From 0ff958171e1399a95d875f9009dfaab1ccb284a4 Mon Sep 17 00:00:00 2001 From: suyuan <175338101@qq.com> Date: Thu, 24 Dec 2020 15:28:44 +0800 Subject: [PATCH] Revert "Revert "Merge branch 'develop'"" This reverts commit f0937d0399e49c1d37cb10e091b5324d9e18914b. --- build.sh | 22 +- config | 3 + config-bpi-r64 | 1 + config-cm520-79f | 9 +- config-espressobin | 9 + config-p2w_r619ac | 9 +- config-r2s | 1 + config-rpi3 | 7 + config-rpi4 | 1 + config-x86_64 | 1 + patches/bbr2.patch | 27 + patches/check-rsync.patch | 14 + patches/luci-occitan.patch | 2 +- .../base-files/files/bin/config_generate | 148 +- .../files/etc/board.d/99-default_network | 1 + .../files/lib/preinit/80_mount_root | 30 - root/package/boot/uboot-envtools/Makefile | 78 - root/package/firmware/ipq-wifi/Makefile | 48 +- root/target/linux/bcm27xx/bcm2708/config-4.14 | 431 - root/target/linux/bcm27xx/bcm2709/config-4.14 | 472 - root/target/linux/bcm27xx/bcm2709/config-4.19 | 568 - root/target/linux/bcm27xx/bcm2710/config-4.14 | 492 - root/target/linux/bcm27xx/bcm2710/config-4.19 | 545 - root/target/linux/bcm27xx/bcm2711/config-4.19 | 667 - root/target/linux/generic/config-4.14 | 5797 - root/target/linux/generic/config-4.19 | 6136 - root/target/linux/generic/config-4.9 | 5324 - root/target/linux/generic/config-5.4 | 6501 - .../generic/hack-4.14/690-mptcp_v0.94.patch | 20725 -- .../hack-4.14/998-ndpi-netfilter.patch | 116 - .../hack-4.14/999-stop-promiscuous-info.patch | 14 - .../generic/hack-4.19/690-mptcp_v0.95.patch | 22998 -- .../generic/hack-4.19/691-mptcp_ecf.patch | 434 - .../hack-4.19/692-tcp_nanqinlang.patch | 1037 - .../hack-4.19/998-ndpi-netfilter.patch | 116 - .../hack-4.19/999-f2fs-ioerrorfix.patch | 25 - .../hack-4.19/999-stop-promiscuous-info.patch | 14 - .../generic/hack-4.9/690-mptcp_v0.93.patch | 20499 -- .../generic/hack-5.4/690-mptcp_trunk.patch | 23662 -- .../generic/hack-5.4/692-tcp_nanqinlang.patch | 1037 - .../generic/hack-5.4/998-ndpi-netfilter.patch | 116 - .../hack-5.4/999-stop-promiscuous-info.patch | 47 - .../ipq40xx/base-files/etc/board.d/01_leds | 90 +- .../ipq40xx/base-files/etc/board.d/02_network | 32 +- .../base-files/etc/board.d/03_gpio_switches | 0 .../etc/hotplug.d/firmware/11-ath10k-caldata | 50 +- .../etc/hotplug.d/net/21_adjust_network | 0 .../ipq40xx/base-files/etc/init.d/bootcount | 0 .../linux/ipq40xx/base-files/etc/inittab | 5 + .../etc/uci-defaults/04_led_migration | 19 + .../lib/preinit/05_set_iface_mac_ipq40xx.sh | 9 +- .../preinit/06_set_preinit_iface_ipq40xx.sh | 4 +- .../ipq40xx/base-files/lib/upgrade/linksys.sh | 122 + .../base-files/lib/upgrade/openmesh.sh | 106 + .../base-files/lib/upgrade/platform.sh | 181 +- .../net/ethernet/qualcomm/essedma/Makefile | 9 - .../net/ethernet/qualcomm/essedma/edma.c | 2177 - .../net/ethernet/qualcomm/essedma/edma.h | 455 - .../net/ethernet/qualcomm/essedma/edma_axi.c | 1359 - .../ethernet/qualcomm/essedma/edma_ethtool.c | 384 - .../net/ethernet/qualcomm/essedma/ess_edma.h | 389 - .../arm/boot/dts/qcom-ipq4019-cm520-79f.dts | 300 - .../arch/arm/boot/dts/qcom-ipq4019-l1000.dts | 20 +- .../arm/boot/dts/qcom-ipq4019-r619ac.dtsi | 6 +- root/target/linux/ipq40xx/image/Makefile | 126 +- .../901-arm-boot-add-dts-files.patch | 17 +- root/target/linux/mediatek/Makefile | 19 - .../linux/mediatek/base-files/etc/inittab | 4 - .../base-files/etc/uci-defaults/99-net-ps | 6 - .../lib/preinit/05_set_preinit_iface | 9 - .../lib/preinit/06_set_rps_sock_flow | 8 - .../base-files/lib/preinit/07_set_iface_mac | 48 - .../base-files/lib/preinit/79_move_config | 19 - .../base-files/lib/preinit/90_init_jffs2 | 7 - .../base-files/lib/upgrade/platform.sh | 85 - root/target/linux/mediatek/modules.mk | 51 - .../mt7623/base-files/etc/board.d/02_network | 36 - .../base-files/lib/preinit/07_set_iface_mac | 47 - .../base-files/lib/preinit/79_move_config | 19 - .../mt7623/base-files/lib/upgrade/platform.sh | 154 - root/target/linux/mediatek/mt7623/config-4.14 | 570 - root/target/linux/mediatek/mt7623/config-5.4 | 561 - .../0229-fix-memory-size-for-bpi-r2.patch | 23 - .../0229-update-gpio-leds-for-bpi-r2.patch | 27 - .../0230-update-pcie-for-bpi-r2.patch | 48 - .../0231-enable-trgmii-on-bpi-r2.patch | 22 - .../0232-merge-mt6625l-wifi-driver.patch | 217327 --------------- .../0233-revert-unexport-vfs_read-write.patch | 35 - .../0234-fix-mtk-wlan_gen2-module.patch | 127 - .../0235-mtk_wdt-remove-debug-printk.patch | 12 - .../0236-mt6625l-rename-wlan.patch | 13 - .../0237-mt7623-add-HNAT-support.patch | 1824 - ...-and-build-script-change-gitignore-m.patch | 747 - .../0006-wifi-adding-driver-folder.patch | 216265 -------------- ...-related-changes-outside-driver-dire.patch | 846 - ...y-Dominik-Koch-nic_rx-patch-from-htt.patch | 78 - .../0009-wifi-activated-wifi-options.patch | 52 - ...ssing-CONFIG_PCI_MSI-needed-for-pcie.patch | 34 - .../0014-dts-set-mac-address-eth0.patch | 34 - ...uild.sh-dts-added-devicetree-Overlay.patch | 40 - ...ields-for-holding-information-about-.patch | 60 - .../0020-net-dsa-add-helper-functions.patch | 86 - ...a-adding-handling-of-second-CPU-Port.patch | 102 - ...a-add-support-for-GMAC2-wired-to-ext.patch | 34 - .../0023-net-dsa-dsa-multi-cpu-mt7530.c.patch | 121 - ...A-when-we-are-turning-on-the-special.patch | 54 - ...5-net-dsa-mt7530-add-linking-to-mdio.patch | 47 - .../0026-net-dsa-changes-to-dts.patch | 81 - ...ek-add-refcount-for-DPI-power-on-off.patch | 171 - ...-move-hardware-register-to-node-data.patch | 101 - ...-adjust-EDGE-to-match-clock-and-data.patch | 62 - ...ek-add-clock-factor-for-different-IC.patch | 68 - ...vert-dpi-driver-to-use-drm_of_find_p.patch | 66 - ...add-dpi-driver-for-mt2701-and-mt7623.patch | 76 - ...-separate-hdmi-phy-to-different-file.patch | 641 - ...-add-support-for-SPDIF-audio-in-HDMI.patch | 32 - ...dd-hdmi-driver-for-MT2701-and-MT7623.patch | 309 - ...mplement-connection-from-BLS-to-DPI0.patch | 58 - ...-a-error-return-value-when-clock-dri.patch | 32 - ...fig-component-output-by-device-node-.patch | 142 - ...dd-a-performance-counter-unit-device.patch | 36 - ...pdate-subsystem-clock-controller-dev.patch | 76 - ...ts-mt7623-add-iommu-smi-device-nodes.patch | 120 - ...-mt7623-add-jpeg-decoder-device-node.patch | 41 - ...dd-display-subsystem-related-device-.patch | 493 - ...fix-boot-up-for-720-and-480-but-1080.patch | 72 - ...sing-different-round-rate-for-mt7623.patch | 103 - .../0046-hdmi-fix-possible_crtcs.patch | 26 - ...0047-hdmi-added-options-to-defconfig.patch | 31 - .../0049-hdmi-added-fbdev-options.patch | 24 - .../patches-4.19/0050-BT-fix-Bluetooth.patch | 69 - ...sable-some-debug-messages-evbug-gpio.patch | 34 - ...add-multiple-routing-tables-for-IPv4.patch | 25 - ...ig-added-options-for-Traffic-Shaping.patch | 33 - .../0061-defconfig-add-nftables.patch | 60 - ...defconfig-add-all-XT-matches-targets.patch | 100 - ...0064-dsa-fix-oops-in-br_vlan_enabled.patch | 34 - .../0066-defconfig-enable-mt76x2.patch | 25 - .../0067-dsa-fix-from-florian.patch | 34 - ...-atheros-wireless-lan-9k-10k-support.patch | 35 - .../0072-defconfig-add-ebtables.patch | 47 - .../0074-add-compiler-gcc8.h.patch | 78 - ...ig-add-mqueue-and-seccomp-for-docker.patch | 37 - .../0227-arm-dts-Add-Unielec-U7623-DTS.patch | 397 - .../0233-revert-unexport-vfs_read-write.patch | 35 - .../0234-fix-mtk-wlan_gen2-module.patch | 127 - .../0235-mtk_wdt-remove-debug-printk.patch | 12 - .../0236-mt6625l-rename-wlan.patch | 13 - .../patches-4.19/0999-wlan-memcpy-fix.patch | 20 - ...cket-corruption-on-bridged-interface.patch | 51 - .../0006-dts-fix-bpi2-console.patch | 10 - .../0100-dts-add-second-gmac.patch | 54 - .../0103-net-support-net-labels.patch | 39 - .../patches-5.4/0110-rtc-mt6397.patch | 249 - .../patches-5.4/0111-mt6323-poweroff.patch | 160 - .../0112-dts-mt6323-add-key-rtc-power.patch | 57 - .../0170-dts-mt7623-add-display.patch | 500 - .../0171-dts-mt7623-add-mali450.patch | 77 - .../patches-5.4/0180-lima-power-on-off.patch | 68 - .../0181-drm-Add-get_possible_crtc.patch | 84 - .../0182-drm-change-possible_crtc.patch | 45 - .../patches-5.4/0183-drm-fix-DRM_INFO.patch | 21 - .../0184-drm-config-component-output.patch | 146 - .../patches-5.4/0185-drm-fix-boot-up.patch | 55 - .../patches-5.4/0190-thermal-add-sensor.patch | 56 - .../mediatek/patches-5.4/0191-thermal.patch | 35 - .../mediatek/patches-5.4/0230-pthread.patch | 14 - .../patches-5.4/0999-lan-to-wan.patch | 49 - root/target/linux/mvebu/config-4.14 | 498 - root/target/linux/mvebu/config-4.19 | 531 - root/target/linux/x86/config-4.19 | 500 - 171 files changed, 785 insertions(+), 570335 deletions(-) create mode 100644 config-espressobin create mode 100644 config-rpi3 create mode 100644 patches/bbr2.patch create mode 100644 patches/check-rsync.patch delete mode 100644 root/package/base-files/files/lib/preinit/80_mount_root delete mode 100644 root/package/boot/uboot-envtools/Makefile delete mode 100644 root/target/linux/bcm27xx/bcm2708/config-4.14 delete mode 100644 root/target/linux/bcm27xx/bcm2709/config-4.14 delete mode 100644 root/target/linux/bcm27xx/bcm2709/config-4.19 delete mode 100644 root/target/linux/bcm27xx/bcm2710/config-4.14 delete mode 100644 root/target/linux/bcm27xx/bcm2710/config-4.19 delete mode 100644 root/target/linux/bcm27xx/bcm2711/config-4.19 delete mode 100644 root/target/linux/generic/config-4.14 delete mode 100644 root/target/linux/generic/config-4.19 delete mode 100644 root/target/linux/generic/config-4.9 delete mode 100644 root/target/linux/generic/config-5.4 delete mode 100644 root/target/linux/generic/hack-4.14/690-mptcp_v0.94.patch delete mode 100644 root/target/linux/generic/hack-4.14/998-ndpi-netfilter.patch delete mode 100644 root/target/linux/generic/hack-4.14/999-stop-promiscuous-info.patch delete mode 100644 root/target/linux/generic/hack-4.19/690-mptcp_v0.95.patch delete mode 100644 root/target/linux/generic/hack-4.19/691-mptcp_ecf.patch delete mode 100644 root/target/linux/generic/hack-4.19/692-tcp_nanqinlang.patch delete mode 100644 root/target/linux/generic/hack-4.19/998-ndpi-netfilter.patch delete mode 100644 root/target/linux/generic/hack-4.19/999-f2fs-ioerrorfix.patch delete mode 100644 root/target/linux/generic/hack-4.19/999-stop-promiscuous-info.patch delete mode 100644 root/target/linux/generic/hack-4.9/690-mptcp_v0.93.patch delete mode 100644 root/target/linux/generic/hack-5.4/690-mptcp_trunk.patch delete mode 100644 root/target/linux/generic/hack-5.4/692-tcp_nanqinlang.patch delete mode 100644 root/target/linux/generic/hack-5.4/998-ndpi-netfilter.patch delete mode 100644 root/target/linux/generic/hack-5.4/999-stop-promiscuous-info.patch mode change 100644 => 100755 root/target/linux/ipq40xx/base-files/etc/board.d/01_leds mode change 100644 => 100755 root/target/linux/ipq40xx/base-files/etc/board.d/03_gpio_switches mode change 100644 => 100755 root/target/linux/ipq40xx/base-files/etc/hotplug.d/net/21_adjust_network mode change 100644 => 100755 root/target/linux/ipq40xx/base-files/etc/init.d/bootcount create mode 100755 root/target/linux/ipq40xx/base-files/etc/inittab create mode 100755 root/target/linux/ipq40xx/base-files/etc/uci-defaults/04_led_migration mode change 100644 => 100755 root/target/linux/ipq40xx/base-files/lib/preinit/05_set_iface_mac_ipq40xx.sh mode change 100644 => 100755 root/target/linux/ipq40xx/base-files/lib/preinit/06_set_preinit_iface_ipq40xx.sh create mode 100755 root/target/linux/ipq40xx/base-files/lib/upgrade/linksys.sh create mode 100755 root/target/linux/ipq40xx/base-files/lib/upgrade/openmesh.sh delete mode 100644 root/target/linux/ipq40xx/files-5.4/drivers/net/ethernet/qualcomm/essedma/Makefile delete mode 100644 root/target/linux/ipq40xx/files-5.4/drivers/net/ethernet/qualcomm/essedma/edma.c delete mode 100644 root/target/linux/ipq40xx/files-5.4/drivers/net/ethernet/qualcomm/essedma/edma.h delete mode 100644 root/target/linux/ipq40xx/files-5.4/drivers/net/ethernet/qualcomm/essedma/edma_axi.c delete mode 100644 root/target/linux/ipq40xx/files-5.4/drivers/net/ethernet/qualcomm/essedma/edma_ethtool.c delete mode 100644 root/target/linux/ipq40xx/files-5.4/drivers/net/ethernet/qualcomm/essedma/ess_edma.h delete mode 100644 root/target/linux/ipq40xx/files/arch/arm/boot/dts/qcom-ipq4019-cm520-79f.dts delete mode 100644 root/target/linux/mediatek/Makefile delete mode 100644 root/target/linux/mediatek/base-files/etc/inittab delete mode 100755 root/target/linux/mediatek/base-files/etc/uci-defaults/99-net-ps delete mode 100644 root/target/linux/mediatek/base-files/lib/preinit/05_set_preinit_iface delete mode 100644 root/target/linux/mediatek/base-files/lib/preinit/06_set_rps_sock_flow delete mode 100644 root/target/linux/mediatek/base-files/lib/preinit/07_set_iface_mac delete mode 100644 root/target/linux/mediatek/base-files/lib/preinit/79_move_config delete mode 100644 root/target/linux/mediatek/base-files/lib/preinit/90_init_jffs2 delete mode 100755 root/target/linux/mediatek/base-files/lib/upgrade/platform.sh delete mode 100644 root/target/linux/mediatek/modules.mk delete mode 100755 root/target/linux/mediatek/mt7623/base-files/etc/board.d/02_network delete mode 100644 root/target/linux/mediatek/mt7623/base-files/lib/preinit/07_set_iface_mac delete mode 100644 root/target/linux/mediatek/mt7623/base-files/lib/preinit/79_move_config delete mode 100755 root/target/linux/mediatek/mt7623/base-files/lib/upgrade/platform.sh delete mode 100644 root/target/linux/mediatek/mt7623/config-4.14 delete mode 100644 root/target/linux/mediatek/mt7623/config-5.4 delete mode 100644 root/target/linux/mediatek/patches-4.14/0229-fix-memory-size-for-bpi-r2.patch delete mode 100644 root/target/linux/mediatek/patches-4.14/0229-update-gpio-leds-for-bpi-r2.patch delete mode 100644 root/target/linux/mediatek/patches-4.14/0230-update-pcie-for-bpi-r2.patch delete mode 100644 root/target/linux/mediatek/patches-4.14/0231-enable-trgmii-on-bpi-r2.patch delete mode 100644 root/target/linux/mediatek/patches-4.14/0232-merge-mt6625l-wifi-driver.patch delete mode 100644 root/target/linux/mediatek/patches-4.14/0233-revert-unexport-vfs_read-write.patch delete mode 100644 root/target/linux/mediatek/patches-4.14/0234-fix-mtk-wlan_gen2-module.patch delete mode 100644 root/target/linux/mediatek/patches-4.14/0235-mtk_wdt-remove-debug-printk.patch delete mode 100644 root/target/linux/mediatek/patches-4.14/0236-mt6625l-rename-wlan.patch delete mode 100644 root/target/linux/mediatek/patches-4.14/0237-mt7623-add-HNAT-support.patch delete mode 100644 root/target/linux/mediatek/patches-4.19/0001-adding-defconfig-and-build-script-change-gitignore-m.patch delete mode 100644 root/target/linux/mediatek/patches-4.19/0006-wifi-adding-driver-folder.patch delete mode 100644 root/target/linux/mediatek/patches-4.19/0007-wifi-adding-wifi-related-changes-outside-driver-dire.patch delete mode 100644 root/target/linux/mediatek/patches-4.19/0008-gcc-gcc8-fixes-by-Dominik-Koch-nic_rx-patch-from-htt.patch delete mode 100644 root/target/linux/mediatek/patches-4.19/0009-wifi-activated-wifi-options.patch delete mode 100644 root/target/linux/mediatek/patches-4.19/0012-defconfig-add-missing-CONFIG_PCI_MSI-needed-for-pcie.patch delete mode 100644 root/target/linux/mediatek/patches-4.19/0014-dts-set-mac-address-eth0.patch delete mode 100644 root/target/linux/mediatek/patches-4.19/0016-build.sh-dts-added-devicetree-Overlay.patch delete mode 100644 root/target/linux/mediatek/patches-4.19/0019-net-dsa-adding-fields-for-holding-information-about-.patch delete mode 100644 root/target/linux/mediatek/patches-4.19/0020-net-dsa-add-helper-functions.patch delete mode 100644 root/target/linux/mediatek/patches-4.19/0021-net-dsa-adding-handling-of-second-CPU-Port.patch delete mode 100644 root/target/linux/mediatek/patches-4.19/0022-net-dsa-add-support-for-GMAC2-wired-to-ext.patch delete mode 100644 root/target/linux/mediatek/patches-4.19/0023-net-dsa-dsa-multi-cpu-mt7530.c.patch delete mode 100644 root/target/linux/mediatek/patches-4.19/0024-net-dsa-tell-GDMA-when-we-are-turning-on-the-special.patch delete mode 100644 root/target/linux/mediatek/patches-4.19/0025-net-dsa-mt7530-add-linking-to-mdio.patch delete mode 100644 root/target/linux/mediatek/patches-4.19/0026-net-dsa-changes-to-dts.patch delete mode 100644 root/target/linux/mediatek/patches-4.19/0027-drm-mediatek-add-refcount-for-DPI-power-on-off.patch delete mode 100644 root/target/linux/mediatek/patches-4.19/0028-drm-mediatek-move-hardware-register-to-node-data.patch delete mode 100644 root/target/linux/mediatek/patches-4.19/0029-drm-mediatek-adjust-EDGE-to-match-clock-and-data.patch delete mode 100644 root/target/linux/mediatek/patches-4.19/0030-drm-mediatek-add-clock-factor-for-different-IC.patch delete mode 100644 root/target/linux/mediatek/patches-4.19/0031-drm-mediatek-convert-dpi-driver-to-use-drm_of_find_p.patch delete mode 100644 root/target/linux/mediatek/patches-4.19/0032-drm-mediatek-add-dpi-driver-for-mt2701-and-mt7623.patch delete mode 100644 root/target/linux/mediatek/patches-4.19/0033-drm-mediatek-separate-hdmi-phy-to-different-file.patch delete mode 100644 root/target/linux/mediatek/patches-4.19/0034-drm-mediatek-add-support-for-SPDIF-audio-in-HDMI.patch delete mode 100644 root/target/linux/mediatek/patches-4.19/0035-drm-mediatek-add-hdmi-driver-for-MT2701-and-MT7623.patch delete mode 100644 root/target/linux/mediatek/patches-4.19/0036-drm-mediatek-implement-connection-from-BLS-to-DPI0.patch delete mode 100644 root/target/linux/mediatek/patches-4.19/0037-drm-mediatek-add-a-error-return-value-when-clock-dri.patch delete mode 100644 root/target/linux/mediatek/patches-4.19/0038-drm-mediatek-config-component-output-by-device-node-.patch delete mode 100644 root/target/linux/mediatek/patches-4.19/0039-arm-dts-mt7623-add-a-performance-counter-unit-device.patch delete mode 100644 root/target/linux/mediatek/patches-4.19/0040-arm-dts-mt7623-update-subsystem-clock-controller-dev.patch delete mode 100644 root/target/linux/mediatek/patches-4.19/0041-arm-dts-mt7623-add-iommu-smi-device-nodes.patch delete mode 100644 root/target/linux/mediatek/patches-4.19/0042-arm-dts-mt7623-add-jpeg-decoder-device-node.patch delete mode 100644 root/target/linux/mediatek/patches-4.19/0043-arm-dts-mt7623-add-display-subsystem-related-device-.patch delete mode 100644 root/target/linux/mediatek/patches-4.19/0044-fix-boot-up-for-720-and-480-but-1080.patch delete mode 100644 root/target/linux/mediatek/patches-4.19/0045-using-different-round-rate-for-mt7623.patch delete mode 100644 root/target/linux/mediatek/patches-4.19/0046-hdmi-fix-possible_crtcs.patch delete mode 100644 root/target/linux/mediatek/patches-4.19/0047-hdmi-added-options-to-defconfig.patch delete mode 100644 root/target/linux/mediatek/patches-4.19/0049-hdmi-added-fbdev-options.patch delete mode 100644 root/target/linux/mediatek/patches-4.19/0050-BT-fix-Bluetooth.patch delete mode 100644 root/target/linux/mediatek/patches-4.19/0053-defconfig-disable-some-debug-messages-evbug-gpio.patch delete mode 100644 root/target/linux/mediatek/patches-4.19/0058-defconfig-add-multiple-routing-tables-for-IPv4.patch delete mode 100644 root/target/linux/mediatek/patches-4.19/0059-defconfig-added-options-for-Traffic-Shaping.patch delete mode 100644 root/target/linux/mediatek/patches-4.19/0061-defconfig-add-nftables.patch delete mode 100644 root/target/linux/mediatek/patches-4.19/0063-defconfig-add-all-XT-matches-targets.patch delete mode 100644 root/target/linux/mediatek/patches-4.19/0064-dsa-fix-oops-in-br_vlan_enabled.patch delete mode 100644 root/target/linux/mediatek/patches-4.19/0066-defconfig-enable-mt76x2.patch delete mode 100644 root/target/linux/mediatek/patches-4.19/0067-dsa-fix-from-florian.patch delete mode 100644 root/target/linux/mediatek/patches-4.19/0068-defconfig-add-atheros-wireless-lan-9k-10k-support.patch delete mode 100644 root/target/linux/mediatek/patches-4.19/0072-defconfig-add-ebtables.patch delete mode 100644 root/target/linux/mediatek/patches-4.19/0074-add-compiler-gcc8.h.patch delete mode 100644 root/target/linux/mediatek/patches-4.19/0076-defconfig-add-mqueue-and-seccomp-for-docker.patch delete mode 100644 root/target/linux/mediatek/patches-4.19/0227-arm-dts-Add-Unielec-U7623-DTS.patch delete mode 100644 root/target/linux/mediatek/patches-4.19/0233-revert-unexport-vfs_read-write.patch delete mode 100644 root/target/linux/mediatek/patches-4.19/0234-fix-mtk-wlan_gen2-module.patch delete mode 100644 root/target/linux/mediatek/patches-4.19/0235-mtk_wdt-remove-debug-printk.patch delete mode 100644 root/target/linux/mediatek/patches-4.19/0236-mt6625l-rename-wlan.patch delete mode 100644 root/target/linux/mediatek/patches-4.19/0999-wlan-memcpy-fix.patch delete mode 100644 root/target/linux/mediatek/patches-5.4/0004-mediatek-fix-packet-corruption-on-bridged-interface.patch delete mode 100644 root/target/linux/mediatek/patches-5.4/0006-dts-fix-bpi2-console.patch delete mode 100644 root/target/linux/mediatek/patches-5.4/0100-dts-add-second-gmac.patch delete mode 100644 root/target/linux/mediatek/patches-5.4/0103-net-support-net-labels.patch delete mode 100644 root/target/linux/mediatek/patches-5.4/0110-rtc-mt6397.patch delete mode 100644 root/target/linux/mediatek/patches-5.4/0111-mt6323-poweroff.patch delete mode 100644 root/target/linux/mediatek/patches-5.4/0112-dts-mt6323-add-key-rtc-power.patch delete mode 100644 root/target/linux/mediatek/patches-5.4/0170-dts-mt7623-add-display.patch delete mode 100644 root/target/linux/mediatek/patches-5.4/0171-dts-mt7623-add-mali450.patch delete mode 100644 root/target/linux/mediatek/patches-5.4/0180-lima-power-on-off.patch delete mode 100644 root/target/linux/mediatek/patches-5.4/0181-drm-Add-get_possible_crtc.patch delete mode 100644 root/target/linux/mediatek/patches-5.4/0182-drm-change-possible_crtc.patch delete mode 100644 root/target/linux/mediatek/patches-5.4/0183-drm-fix-DRM_INFO.patch delete mode 100644 root/target/linux/mediatek/patches-5.4/0184-drm-config-component-output.patch delete mode 100644 root/target/linux/mediatek/patches-5.4/0185-drm-fix-boot-up.patch delete mode 100644 root/target/linux/mediatek/patches-5.4/0190-thermal-add-sensor.patch delete mode 100644 root/target/linux/mediatek/patches-5.4/0191-thermal.patch delete mode 100644 root/target/linux/mediatek/patches-5.4/0230-pthread.patch delete mode 100644 root/target/linux/mediatek/patches-5.4/0999-lan-to-wan.patch delete mode 100644 root/target/linux/mvebu/config-4.14 delete mode 100644 root/target/linux/mvebu/config-4.19 delete mode 100644 root/target/linux/x86/config-4.19 diff --git a/build.sh b/build.sh index feabc560..aada4f31 100755 --- a/build.sh +++ b/build.sh @@ -78,9 +78,9 @@ fi #_get_repo source https://github.com/ysurac/openmptcprouter-source "master" if [ "$OMR_OPENWRT" = "default" ]; then - _get_repo "$OMR_TARGET/source" https://github.com/openwrt/openwrt "a439f1bb478b4b8b4134dbed76266c0032625b6b" - _get_repo feeds/packages https://github.com/openwrt/packages "05769970213a5f9ffb81506b18da288890c05949" - _get_repo feeds/luci https://github.com/openwrt/luci "a805a3178f902fe609d3d4a6c7b6b5b1dad88838" + _get_repo "$OMR_TARGET/source" https://github.com/openwrt/openwrt "bfc433efd4a0c6875a92981d1bd2a5e3e60c61c6" + _get_repo feeds/packages https://github.com/openwrt/packages "85dbb482017faec4d69c21b57a5a0afb8095f48a" + _get_repo feeds/luci https://github.com/openwrt/luci "833e25d24a8cbf8dd587ee4424ef49b3e4e5f210" elif [ "$OMR_OPENWRT" = "master" ]; then _get_repo "$OMR_TARGET/source" https://github.com/openwrt/openwrt "master" _get_repo feeds/packages https://github.com/openwrt/packages "master" @@ -236,6 +236,16 @@ if ! patch -Rf -N -p1 -s --dry-run < ../../patches/nanqinlang.patch; then fi echo "Done" +# Add BBR2 patch, only working on 64bits images for now +if [ "$OMR_TARGET" = "x86_64" ] || [ "$OMR_TARGET" = "bpi-r64" ] || [ "$OMR_TARGET" = "rpi4" ] || [ "$OMR_TARGET" = "espressobin" ] || [ "$OMR_TARGET" = "r2s" ] || [ "$OMR_TARGET" = "rpi3" ]; then + echo "Checking if BBRv2 patch is set or not" + if ! patch -Rf -N -p1 -s --dry-run < ../../patches/bbr2.patch; then + echo "apply..." + patch -N -p1 -s < ../../patches/bbr2.patch + fi + echo "Done" +fi + echo "Checking if smsc75xx patch is set or not" if ! patch -Rf -N -p1 -s --dry-run < ../../patches/smsc75xx.patch; then echo "apply..." @@ -270,6 +280,12 @@ if ! patch -Rf -N -p1 -s --dry-run < ../../patches/download-ipv4.patch; then fi echo "Done" +echo "Remove check rsync" +if [ "$(grep rsync include/prereq-build.mk)" != "" ]; then + patch -N -p1 -s < ../../patches/check-rsync.patch +fi +echo "Done" + if [ -f target/linux/mediatek/patches-5.4/0999-hnat.patch ]; then rm -f target/linux/mediatek/patches-5.4/0999-hnat.patch fi diff --git a/config b/config index 8f3b2bd8..cc029c42 100644 --- a/config +++ b/config @@ -25,6 +25,7 @@ CONFIG_BUSYBOX_CONFIG_FEATURE_USE_TERMIOS=y CONFIG_BUSYBOX_CONFIG_FEATURE_VI_UNDO=y CONFIG_BUSYBOX_CONFIG_FEATURE_VI_UNDO_QUEUE=y CONFIG_BUSYBOX_CONFIG_FEATURE_VI_UNDO_QUEUE_MAX=32 +CONFIG_BUSYBOX_CONFIG_FEATURE_XARGS_SUPPORT_PARALLEL=y CONFIG_BUSYBOX_CONFIG_IOSTAT=y CONFIG_BUSYBOX_CONFIG_LOADKMAP=y CONFIG_BUSYBOX_CONFIG_LSPCI=y @@ -47,10 +48,12 @@ CONFIG_KERNEL_DEBUG_PINCTRL=y CONFIG_KERNEL_DEVTMPFS=y CONFIG_KERNEL_DEVTMPFS_MOUNT=y CONFIG_KERNEL_DIRECT_IO=y +CONFIG_KERNEL_DMA_ACPI=y CONFIG_KERNEL_FANOTIFY=y CONFIG_KERNEL_FHANDLE=y CONFIG_KERNEL_IPC_NS=y # CONFIG_KERNEL_MAGIC_SYSRQ is not set +CONFIG_KERNEL_MMC_SDHCI_ACPI=y CONFIG_KERNEL_NAMESPACES=y CONFIG_KERNEL_NET_NS=y CONFIG_KERNEL_PID_NS=y diff --git a/config-bpi-r64 b/config-bpi-r64 index c2eefeed..74443ce7 100644 --- a/config-bpi-r64 +++ b/config-bpi-r64 @@ -7,3 +7,4 @@ CONFIG_PACKAGE_uboot-mediatek=y CONFIG_PACKAGE_uboot-envtools=y CONFIG_PACKAGE_mt7622-preloader=y CONFIG_KERNEL_ARM64_MODULE_PLTS=y +CONFIG_KERNEL_TCP_CONG_BBR2=y diff --git a/config-cm520-79f b/config-cm520-79f index 0358b260..9622e061 100644 --- a/config-cm520-79f +++ b/config-cm520-79f @@ -1,7 +1,12 @@ CONFIG_TARGET_ipq40xx=y CONFIG_TARGET_ipq40xx_generic=y CONFIG_TARGET_ipq40xx_generic_DEVICE_mobipromo_cm520-79f=y -CONFIG_PACKAGE_kmod-6lowpan=y -# CONFIG_KERNEL_CC_OPTIMIZE_FOR_PERFORMANCE is not set CONFIG_KERNEL_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_PACKAGE_ipq-wifi-mobipromo_cm520-79f=y +CONFIG_DEFAULT_ath10k-firmware-qca4019-ct=y +CONFIG_DEFAULT_kmod-ath10k-ct=y +# CONFIG_KERNEL_CC_OPTIMIZE_FOR_PERFORMANCE is not set +CONFIG_PACKAGE_kmod-ath10k-ct=y +CONFIG_ATH10K-CT_LEDS=y +CONFIG_PACKAGE_ath10k-firmware-qca4019-ct=y CONFIG_KERNEL_ARM_MODULE_PLTS=y diff --git a/config-espressobin b/config-espressobin new file mode 100644 index 00000000..ed5b4188 --- /dev/null +++ b/config-espressobin @@ -0,0 +1,9 @@ +CONFIG_TARGET_mvebu=y +CONFIG_TARGET_mvebu_cortexa53=y +CONFIG_TARGET_mvebu_cortexa53_DEVICE_globalscale_espressobin-v7=y +CONFIG_PACKAGE_kmod-6lowpan=y +CONFIG_PACKAGE_luci-app-advanced-reboot=y +# CONFIG_KERNEL_CC_OPTIMIZE_FOR_PERFORMANCE is not set +CONFIG_KERNEL_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_KERNEL_ARM_MODULE_PLTS=y +CONFIG_KERNEL_TCP_CONG_BBR2=y diff --git a/config-p2w_r619ac b/config-p2w_r619ac index 62a4972f..750ecadb 100644 --- a/config-p2w_r619ac +++ b/config-p2w_r619ac @@ -1,7 +1,12 @@ CONFIG_TARGET_ipq40xx=y CONFIG_TARGET_ipq40xx_generic=y CONFIG_TARGET_ipq40xx_generic_DEVICE_p2w_r619ac-128m=y -CONFIG_PACKAGE_kmod-6lowpan=y +CONFIG_PACKAGE_ipq-wifi-p2w_r619ac=y +CONFIG_DEFAULT_ath10k-firmware-qca4019-ct=y +CONFIG_DEFAULT_kmod-ath10k-ct=y # CONFIG_KERNEL_CC_OPTIMIZE_FOR_PERFORMANCE is not set CONFIG_KERNEL_CC_OPTIMIZE_FOR_SIZE=y -CONFIG_KERNEL_ARM_MODULE_PLTS=y +CONFIG_PACKAGE_kmod-ath10k-ct=y +CONFIG_ATH10K-CT_LEDS=y +CONFIG_PACKAGE_ath10k-firmware-qca4019-ct=y +CONFIG_KERNEL_ARM_MODULE_PLTS=y diff --git a/config-r2s b/config-r2s index af12d580..32b989e7 100644 --- a/config-r2s +++ b/config-r2s @@ -3,3 +3,4 @@ CONFIG_TARGET_rockchip_armv8=y CONFIG_TARGET_rockchip_armv8_DEVICE_friendlyarm_nanopi-r2s=y CONFIG_PACKAGE_kmod-6lowpan=y CONFIG_KERNEL_ARM_MODULE_PLTS=y +CONFIG_KERNEL_TCP_CONG_BBR2=y diff --git a/config-rpi3 b/config-rpi3 new file mode 100644 index 00000000..70db978f --- /dev/null +++ b/config-rpi3 @@ -0,0 +1,7 @@ +CONFIG_TARGET_bcm27xx=y +CONFIG_TARGET_bcm27xx_bcm2710=y +CONFIG_TARGET_bcm27xx_bcm2710_DEVICE_rpi-3=y +CONFIG_PACKAGE_kmod-ath10k-ct=n +CONFIG_PACKAGE_kmod-ath9k=y +CONFIG_KERNEL_ARM_MODULE_PLTS=y +CONFIG_KERNEL_TCP_CONG_BBR2=y diff --git a/config-rpi4 b/config-rpi4 index 673501f4..c2840279 100644 --- a/config-rpi4 +++ b/config-rpi4 @@ -6,3 +6,4 @@ CONFIG_PACKAGE_kmod-ath9k=y CONFIG_PACKAGE_bcm27xx-eeprom=y CONFIG_PACKAGE_bcm27xx-userland=y CONFIG_KERNEL_ARM64_MODULE_PLTS=y +CONFIG_KERNEL_TCP_CONG_BBR2=y diff --git a/config-x86_64 b/config-x86_64 index 25699d13..78b1a42c 100644 --- a/config-x86_64 +++ b/config-x86_64 @@ -9,3 +9,4 @@ CONFIG_PACKAGE_kmod-ath9k=y CONFIG_GRUB_IMAGES=y CONFIG_EFI_IMAGES=y # CONFIG_VMDK_IMAGES is not set +CONFIG_KERNEL_TCP_CONG_BBR2=y diff --git a/patches/bbr2.patch b/patches/bbr2.patch new file mode 100644 index 00000000..b1d89c96 --- /dev/null +++ b/patches/bbr2.patch @@ -0,0 +1,27 @@ +--- a/package/kernel/linux/modules/netsupport.mk 2020-11-22 17:39:14.462349527 +0100 ++++ b/package/kernel/linux/modules/netsupport.mk 2020-11-22 17:41:37.719620332 +0100 +@@ -948,6 +948,24 @@ + + $(eval $(call KernelPackage,tcp-bbr)) + ++define KernelPackage/tcp-bbr2 ++ SUBMENU:=$(NETWORK_SUPPORT_MENU) ++ TITLE:=BBRv2 TCP congestion control ++ KCONFIG:= \ ++ CONFIG_TCP_CONG_ADVANCED=y \ ++ CONFIG_TCP_CONG_BBR2 ++ FILES:=$(LINUX_DIR)/net/ipv4/tcp_bbr2.ko ++ AUTOLOAD:=$(call AutoLoad,74,tcp_bbr2) ++endef ++ ++define KernelPackage/tcp-bbr2/description ++ Kernel module for BBRv2 (Bottleneck Bandwidth and RTT) TCP congestion ++ control. It requires the fq ("Fair Queue") pacing packet scheduler. ++ For kernel 4.13+, TCP internal pacing is implemented as fallback. ++endef ++ ++$(eval $(call KernelPackage,tcp-bbr2)) ++ + define KernelPackage/tcp-nanqinlang + SUBMENU:=$(NETWORK_SUPPORT_MENU) + TITLE:=BBR NANQINLANG TCP congestion control diff --git a/patches/check-rsync.patch b/patches/check-rsync.patch new file mode 100644 index 00000000..d74a4b6a --- /dev/null +++ b/patches/check-rsync.patch @@ -0,0 +1,14 @@ +diff --git a/include/prereq-build.mk b/include/prereq-build.mk +index e7314b253b58..5045fabdfbde 100644 +--- a/include/prereq-build.mk ++++ b/include/prereq-build.mk +@@ -170,9 +170,6 @@ $(eval $(call SetupHostCommand,git,Please install Git (git-core) >= 1.7.12.2, \ + $(eval $(call SetupHostCommand,file,Please install the 'file' package, \ + file --version 2>&1 | grep file)) + +-$(eval $(call SetupHostCommand,rsync,Please install 'rsync', \ +- rsync --version - -do_mount_root() { - mount_root - boot_run_hook preinit_mount_root - [ -e /dev/sda1 ] && mount /dev/sda1 /boot >/dev/null 2>&1 - [ -f /boot/sysupgrade.tgz ] && { - mv /boot/sysupgrade.tgz / - } - [ -e /dev/sda1 ] && umount /boot >/dev/null 2>&1 - [ -f /sysupgrade.tgz ] && { - echo "- config restore -" - cd / - tar xzf sysupgrade.tgz - } -} -[ -n "$(mount | grep ext4 | grep ro)" ] && { - [ -e /dev/mmcblk0p2 ] && { - echo "Checking ext4 FS on mmcblk0p2..." - /usr/sbin/e2fsck -y -f /dev/mmcblk0p2 >/dev/null 2>&1 - } - [ -e /dev/sda2 ] && { - echo "Checking ext4 FS on sda2..." - /usr/sbin/e2fsck -y -f /dev/sda2 >/dev/null 2>&1 - } -} -[ "$INITRAMFS" = "1" ] || boot_hook_add preinit_main do_mount_root diff --git a/root/package/boot/uboot-envtools/Makefile b/root/package/boot/uboot-envtools/Makefile deleted file mode 100644 index 5ea32d88..00000000 --- a/root/package/boot/uboot-envtools/Makefile +++ /dev/null @@ -1,78 +0,0 @@ -# -# Copyright (C) 2006-2014 OpenWrt.org -# -# This is free software, licensed under the GNU General Public License v2. -# See /LICENSE for more information. -# - -include $(TOPDIR)/rules.mk - -PKG_NAME:=uboot-envtools -PKG_DISTNAME:=u-boot -PKG_VERSION:=2020.04 -PKG_RELEASE:=1 - -PKG_SOURCE_PROTO:=git -PKG_SOURCE:=$(PKG_DISTNAME)-$(PKG_VERSION).tar.bz2 -PKG_SOURCE_SUBDIR:=$(PKG_DISTNAME)-$(PKG_VERSION) -PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_DISTNAME)-$(PKG_VERSION) -PKG_SOURCE_URL:=https://git.denx.de/u-boot.git -PKG_SOURCE_VERSION:=36fec02b1f90b92cf51ec531564f9284eae27ab4 -PKG_MIRROR_HASH:=fe732aaf037d9cc3c0909bad8362af366ae964bbdac6913a34081ff4ad565372 - -PKG_BUILD_DEPENDS:=fstools - -PKG_LICENSE:=GPL-2.0 GPL-2.0+ -PKG_LICENSE_FILES:=Licenses/README - -PKG_FLAGS:=nonshared - -PKG_BUILD_PARALLEL:=1 - -include $(INCLUDE_DIR)/package.mk - -define Package/uboot-envtools - SECTION:=utils - CATEGORY:=Utilities - SUBMENU:=Boot Loaders - TITLE:=read/modify U-Boot bootloader environment - URL:=http://www.denx.de/wiki/U-Boot -endef - -define Package/uboot-envtools/description - This package includes tools to read and modify U-Boot bootloader environment. -endef - -define Build/Configure - touch $(PKG_BUILD_DIR)/include/config.h - mkdir -p $(PKG_BUILD_DIR)/include/config - touch $(PKG_BUILD_DIR)/include/config/auto.conf - mkdir -p $(PKG_BUILD_DIR)/include/generated - touch $(PKG_BUILD_DIR)/include/generated/autoconf.h -endef - -MAKE_FLAGS += \ - TARGET_CFLAGS="$(TARGET_CFLAGS)" \ - TARGET_LDFLAGS="$(TARGET_LDFLAGS)" \ - no-dot-config-targets=envtools \ - envtools - -define Package/uboot-envtools/conffiles -/etc/config/ubootenv -/etc/fw_env.config -endef - -define Package/uboot-envtools/install - $(INSTALL_DIR) $(1)/usr/sbin - $(INSTALL_BIN) $(PKG_BUILD_DIR)/tools/env/fw_printenv $(1)/usr/sbin - $(LN) fw_printenv $(1)/usr/sbin/fw_setenv - $(INSTALL_DIR) $(1)/lib - $(INSTALL_DATA) ./files/uboot-envtools.sh $(1)/lib - $(INSTALL_DIR) $(1)/etc/uci-defaults - $(if $(wildcard ./files/$(BOARD)), \ - $(INSTALL_DATA) ./files/$(BOARD) \ - $(1)/etc/uci-defaults/30_uboot-envtools \ - ) -endef - -$(eval $(call BuildPackage,uboot-envtools)) diff --git a/root/package/firmware/ipq-wifi/Makefile b/root/package/firmware/ipq-wifi/Makefile index ec01e76b..20b07c79 100644 --- a/root/package/firmware/ipq-wifi/Makefile +++ b/root/package/firmware/ipq-wifi/Makefile @@ -8,7 +8,7 @@ PKG_FLAGS:=nonshared include $(INCLUDE_DIR)/package.mk define Build/Prepare - mkdir -p $(PKG_BUILD_DIR) + mkdir -p $(PKG_BUILD_DIR) endef define Build/Compile @@ -25,22 +25,29 @@ endef # ALLWIFIBOARDS:= \ - 8dev_habanero-dvk \ - aruba_ap-303 \ - avm_fritzrepeater-1200 \ - buffalo_wtr-m2133hp \ - cellc_rtl30vw \ - dlink_dap2610 \ - engenius_eap2200 \ - engenius_emd1 \ - engenius_emr3500 \ - ezviz_cs-w3-wd1200g-eup \ - glinet_gl-s1300 \ - linksys_ea8300 \ + 8dev_habanero-dvk \ + aruba_ap-303 \ + avm_fritzrepeater-1200 \ + buffalo_wtr-m2133hp \ + cellc_rtl30vw \ + devolo_magic-2-wifi-next \ + dlink_dap2610 \ + edgecore_ecw5410 \ + edgecore_oap100 \ + engenius_eap2200 \ + engenius_emd1 \ + engenius_emr3500 \ + ezviz_cs-w3-wd1200g-eup \ + glinet_gl-s1300 \ + linksys_ea8300 \ + linksys_mr8300-v0 \ + luma_wrtq-329acn \ pangu_l1000 \ - p2w_r619ac \ - mobipromo_cm520-79f \ - qxwlan_e2600ac + p2w_r619ac \ + mobipromo_cm520-79f \ + plasmacloud_pa1200 \ + plasmacloud_pa2200 \ + qxwlan_e2600ac ALLWIFIPACKAGES:=$(foreach BOARD,$(ALLWIFIBOARDS),ipq-wifi-$(BOARD)) @@ -48,7 +55,7 @@ define Package/ipq-wifi-default SUBMENU:=ath10k Board-Specific Overrides SECTION:=firmware CATEGORY:=Firmware - DEPENDS:=@TARGET_ipq40xx + DEPENDS:=@(TARGET_ipq40xx||TARGET_ipq806x) TITLE:=Custom Board endef @@ -106,14 +113,21 @@ $(eval $(call generate-ipq-wifi-package,aruba_ap-303,Aruba AP-303)) $(eval $(call generate-ipq-wifi-package,avm_fritzrepeater-1200,AVM FRITZRepeater 1200)) $(eval $(call generate-ipq-wifi-package,buffalo_wtr-m2133hp,Buffalo WTR-M2133HP)) $(eval $(call generate-ipq-wifi-package,cellc_rtl30vw, Cell C RTL30VW)) +$(eval $(call generate-ipq-wifi-package,devolo_magic-2-wifi-next,devolo Magic 2 WiFi next)) $(eval $(call generate-ipq-wifi-package,dlink_dap2610,D-Link DAP-2610)) +$(eval $(call generate-ipq-wifi-package,edgecore_ecw5410,Edgecore ECW5410)) +$(eval $(call generate-ipq-wifi-package,edgecore_oap100,Edgecore OAP100)) $(eval $(call generate-ipq-wifi-package,engenius_eap2200,EnGenius EAP2200)) $(eval $(call generate-ipq-wifi-package,engenius_emd1,EnGenius EMD1)) $(eval $(call generate-ipq-wifi-package,engenius_emr3500,EnGenius EMR3500)) $(eval $(call generate-ipq-wifi-package,ezviz_cs-w3-wd1200g-eup,EZVIZ CS-W3-WD1200G EUP)) $(eval $(call generate-ipq-wifi-package,glinet_gl-s1300,GL.iNet GL-S1300)) $(eval $(call generate-ipq-wifi-package,linksys_ea8300,Linksys EA8300)) +$(eval $(call generate-ipq-wifi-package,linksys_mr8300-v0,Linksys MR8300)) +$(eval $(call generate-ipq-wifi-package,luma_wrtq-329acn,Luma WRTQ-329ACN)) $(eval $(call generate-ipq-wifi-package,mobipromo_cm520-79f,MobiPromo CM520-79F)) +$(eval $(call generate-ipq-wifi-package,plasmacloud_pa1200,Plasma Cloud PA1200)) +$(eval $(call generate-ipq-wifi-package,plasmacloud_pa2200,Plasma Cloud PA2200)) $(eval $(call generate-ipq-wifi-package,qxwlan_e2600ac,Qxwlan E2600AC)) $(eval $(call generate-ipq-wifi-package,pangu_l1000,PANGU L1000)) $(eval $(call generate-ipq-wifi-package,p2w_r619ac,P&W R619AC)) diff --git a/root/target/linux/bcm27xx/bcm2708/config-4.14 b/root/target/linux/bcm27xx/bcm2708/config-4.14 deleted file mode 100644 index 9af3e766..00000000 --- a/root/target/linux/bcm27xx/bcm2708/config-4.14 +++ /dev/null @@ -1,431 +0,0 @@ -# CONFIG_AIO is not set -CONFIG_ALIGNMENT_TRAP=y -CONFIG_ARCH_BCM=y -CONFIG_ARCH_BCM2835=y -CONFIG_ARCH_CLOCKSOURCE_DATA=y -CONFIG_ARCH_HAS_DEBUG_VIRTUAL=y -CONFIG_ARCH_HAS_ELF_RANDOMIZE=y -CONFIG_ARCH_HAS_GCOV_PROFILE_ALL=y -CONFIG_ARCH_HAS_SET_MEMORY=y -CONFIG_ARCH_HAS_SG_CHAIN=y -CONFIG_ARCH_HAS_STRICT_KERNEL_RWX=y -CONFIG_ARCH_HAS_STRICT_MODULE_RWX=y -CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y -CONFIG_ARCH_HIBERNATION_POSSIBLE=y -CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y -CONFIG_ARCH_MULTIPLATFORM=y -# CONFIG_ARCH_MULTI_CPU_AUTO is not set -CONFIG_ARCH_MULTI_V6=y -CONFIG_ARCH_MULTI_V6_V7=y -CONFIG_ARCH_NR_GPIO=0 -CONFIG_ARCH_OPTIONAL_KERNEL_RWX=y -# CONFIG_ARCH_OPTIONAL_KERNEL_RWX_DEFAULT is not set -# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set -# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set -CONFIG_ARCH_SUPPORTS_ATOMIC_RMW=y -CONFIG_ARCH_SUPPORTS_UPROBES=y -CONFIG_ARCH_SUSPEND_POSSIBLE=y -CONFIG_ARCH_USE_BUILTIN_BSWAP=y -CONFIG_ARCH_USE_CMPXCHG_LOCKREF=y -# CONFIG_ARCH_WANTS_THP_SWAP is not set -CONFIG_ARCH_WANT_GENERAL_HUGETLB=y -CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y -CONFIG_ARM=y -CONFIG_ARM_AMBA=y -CONFIG_ARM_BCM2835_CPUFREQ=y -CONFIG_ARM_CPU_SUSPEND=y -CONFIG_ARM_ERRATA_411920=y -CONFIG_ARM_HAS_SG_CHAIN=y -CONFIG_ARM_L1_CACHE_SHIFT=5 -CONFIG_ARM_PATCH_PHYS_VIRT=y -# CONFIG_ARM_SP805_WATCHDOG is not set -CONFIG_ARM_THUMB=y -CONFIG_ARM_TIMER_SP804=y -CONFIG_ARM_UNWIND=y -CONFIG_AUTO_ZRELADDR=y -# CONFIG_BACKLIGHT_CLASS_DEVICE is not set -CONFIG_BACKLIGHT_LCD_SUPPORT=y -CONFIG_BCM2708_VCMEM=y -# CONFIG_BCM2835_DEVGPIOMEM is not set -CONFIG_BCM2835_FAST_MEMCPY=y -CONFIG_BCM2835_MBOX=y -# CONFIG_BCM2835_SMI is not set -CONFIG_BCM2835_THERMAL=y -CONFIG_BCM2835_TIMER=y -CONFIG_BCM2835_VCHIQ=y -# CONFIG_BCM2835_VCHIQ_SUPPORT_MEMDUMP is not set -CONFIG_BCM2835_WDT=y -CONFIG_BCM_VCIO=y -CONFIG_BCM_VC_SM=y -CONFIG_BCM_VIDEOCORE=y -# CONFIG_BLK_DEV_INITRD is not set -CONFIG_BLK_DEV_LOOP=y -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_COUNT=16 -CONFIG_BLK_DEV_RAM_SIZE=4096 -CONFIG_BLK_DEV_SD=y -CONFIG_BLK_SCSI_REQUEST=y -CONFIG_BRCM_CHAR_DRIVERS=y -CONFIG_BUILD_BIN2C=y -# CONFIG_CACHE_L2X0 is not set -CONFIG_CLKDEV_LOOKUP=y -CONFIG_CLKSRC_MMIO=y -CONFIG_CLONE_BACKWARDS=y -CONFIG_CMA=y -CONFIG_CMA_ALIGNMENT=8 -CONFIG_CMA_AREAS=7 -# CONFIG_CMA_DEBUG is not set -# CONFIG_CMA_DEBUGFS is not set -CONFIG_CMA_SIZE_MBYTES=16 -# CONFIG_CMA_SIZE_SEL_MAX is not set -CONFIG_CMA_SIZE_SEL_MBYTES=y -# CONFIG_CMA_SIZE_SEL_MIN is not set -# CONFIG_CMA_SIZE_SEL_PERCENTAGE is not set -CONFIG_COMMON_CLK=y -CONFIG_CONFIGFS_FS=y -CONFIG_CONSOLE_LOGLEVEL_DEFAULT=7 -CONFIG_CONSOLE_TRANSLATIONS=y -# CONFIG_CPUFREQ_DT is not set -CONFIG_CPU_32v6=y -CONFIG_CPU_32v6K=y -CONFIG_CPU_ABRT_EV6=y -# CONFIG_CPU_BPREDICT_DISABLE is not set -CONFIG_CPU_CACHE_V6=y -CONFIG_CPU_CACHE_VIPT=y -CONFIG_CPU_COPY_V6=y -CONFIG_CPU_CP15=y -CONFIG_CPU_CP15_MMU=y -CONFIG_CPU_FREQ=y -CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y -# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set -CONFIG_CPU_FREQ_GOV_ATTR_SET=y -CONFIG_CPU_FREQ_GOV_COMMON=y -CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y -CONFIG_CPU_FREQ_GOV_ONDEMAND=y -CONFIG_CPU_FREQ_GOV_PERFORMANCE=y -CONFIG_CPU_FREQ_GOV_POWERSAVE=y -CONFIG_CPU_FREQ_GOV_USERSPACE=y -CONFIG_CPU_FREQ_STAT=y -CONFIG_CPU_HAS_ASID=y -# CONFIG_CPU_ICACHE_DISABLE is not set -CONFIG_CPU_IDLE=y -CONFIG_CPU_IDLE_GOV_LADDER=y -CONFIG_CPU_IDLE_GOV_MENU=y -CONFIG_CPU_PABRT_V6=y -CONFIG_CPU_PM=y -# CONFIG_CPU_THERMAL is not set -CONFIG_CPU_THUMB_CAPABLE=y -CONFIG_CPU_TLB_V6=y -CONFIG_CPU_V6K=y -CONFIG_CRC16=y -CONFIG_CRYPTO_CRC32C=y -CONFIG_CRYPTO_HASH=y -CONFIG_CRYPTO_HASH2=y -CONFIG_CRYPTO_RNG2=y -CONFIG_CRYPTO_WORKQUEUE=y -CONFIG_DCACHE_WORD_ACCESS=y -CONFIG_DEBUG_ALIGN_RODATA=y -CONFIG_DEBUG_BUGVERBOSE=y -CONFIG_DEBUG_INFO=y -CONFIG_DEBUG_LL_INCLUDE="mach/debug-macro.S" -# CONFIG_DEBUG_UART_8250 is not set -# CONFIG_DEBUG_USER is not set -CONFIG_DEFAULT_CFQ=y -# CONFIG_DEFAULT_DEADLINE is not set -CONFIG_DEFAULT_IOSCHED="cfq" -CONFIG_DMADEVICES=y -CONFIG_DMA_BCM2708=y -CONFIG_DMA_BCM2835=y -CONFIG_DMA_CMA=y -CONFIG_DMA_ENGINE=y -# CONFIG_DMA_NOOP_OPS is not set -CONFIG_DMA_OF=y -CONFIG_DMA_SHARED_BUFFER=y -CONFIG_DMA_VIRTUAL_CHANNELS=y -# CONFIG_DMA_VIRT_OPS is not set -CONFIG_DNOTIFY=y -# CONFIG_DRM_LIB_RANDOM is not set -# CONFIG_DRM_PANEL_LVDS is not set -# CONFIG_DRM_PANEL_INNOLUX_P079ZCA is not set -# CONFIG_DRM_PANEL_SAMSUNG_S6E3HA2 is not set -# CONFIG_DRM_PANEL_SITRONIX_ST7789V is not set -# CONFIG_DRM_VC4_HDMI_CEC is not set -CONFIG_DTC=y -CONFIG_DUMMY_CONSOLE=y -CONFIG_EDAC_ATOMIC_SCRUB=y -CONFIG_EDAC_SUPPORT=y -CONFIG_ENABLE_MUST_CHECK=y -CONFIG_EXPORTFS=y -CONFIG_EXT4_FS=y -CONFIG_EXT4_FS_POSIX_ACL=y -CONFIG_EXT4_FS_SECURITY=y -# CONFIG_F2FS_CHECK_FS is not set -CONFIG_F2FS_FS=y -# CONFIG_F2FS_FS_SECURITY is not set -CONFIG_F2FS_FS_XATTR=y -CONFIG_F2FS_STAT_FS=y -CONFIG_FB=y -CONFIG_FB_BCM2708=y -CONFIG_FB_CFB_COPYAREA=y -CONFIG_FB_CFB_FILLRECT=y -CONFIG_FB_CFB_IMAGEBLIT=y -CONFIG_FB_CMDLINE=y -# CONFIG_FB_PROVIDE_GET_FB_UNMAPPED_AREA is not set -# CONFIG_FB_RPISENSE is not set -CONFIG_FIQ=y -CONFIG_FIRMWARE_IN_KERNEL=y -CONFIG_FIX_EARLYCON_MEM=y -# CONFIG_FONTS is not set -CONFIG_FONT_8x16=y -CONFIG_FONT_8x8=y -CONFIG_FONT_SUPPORT=y -# CONFIG_FPE_FASTFPE is not set -# CONFIG_FPE_NWFPE is not set -CONFIG_FRAMEBUFFER_CONSOLE=y -# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set -# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set -CONFIG_FREEZER=y -CONFIG_FS_MBCACHE=y -CONFIG_FS_POSIX_ACL=y -CONFIG_FUTEX_PI=y -CONFIG_GENERIC_ALLOCATOR=y -CONFIG_GENERIC_BUG=y -CONFIG_GENERIC_CLOCKEVENTS=y -CONFIG_GENERIC_CPU_AUTOPROBE=y -CONFIG_GENERIC_EARLY_IOREMAP=y -CONFIG_GENERIC_IDLE_POLL_SETUP=y -CONFIG_GENERIC_IO=y -CONFIG_GENERIC_IRQ_SHOW=y -CONFIG_GENERIC_IRQ_SHOW_LEVEL=y -CONFIG_GENERIC_PCI_IOMAP=y -CONFIG_GENERIC_PINCONF=y -CONFIG_GENERIC_PINCTRL_GROUPS=y -CONFIG_GENERIC_PINMUX_FUNCTIONS=y -CONFIG_GENERIC_SCHED_CLOCK=y -CONFIG_GENERIC_SMP_IDLE_THREAD=y -CONFIG_GENERIC_STRNCPY_FROM_USER=y -CONFIG_GENERIC_STRNLEN_USER=y -CONFIG_GPIOLIB=y -CONFIG_GPIOLIB_IRQCHIP=y -# CONFIG_GPIO_BCM_EXP is not set -# CONFIG_GPIO_BCM_VIRT is not set -CONFIG_GPIO_SYSFS=y -# CONFIG_GRO_CELLS is not set -CONFIG_HANDLE_DOMAIN_IRQ=y -CONFIG_HARDIRQS_SW_RESEND=y -CONFIG_HAS_DMA=y -CONFIG_HAS_IOMEM=y -CONFIG_HAS_IOPORT_MAP=y -# CONFIG_HAVE_64BIT_ALIGNED_ACCESS is not set -# CONFIG_HAVE_ARCH_BITREVERSE is not set -CONFIG_HAVE_ARCH_JUMP_LABEL=y -CONFIG_HAVE_ARCH_KGDB=y -CONFIG_HAVE_ARCH_PFN_VALID=y -CONFIG_HAVE_ARCH_TRACEHOOK=y -# CONFIG_HAVE_BOOTMEM_INFO_NODE is not set -CONFIG_HAVE_CC_STACKPROTECTOR=y -CONFIG_HAVE_CLK=y -CONFIG_HAVE_CLK_PREPARE=y -CONFIG_HAVE_CONTEXT_TRACKING=y -CONFIG_HAVE_C_RECORDMCOUNT=y -CONFIG_HAVE_DEBUG_KMEMLEAK=y -CONFIG_HAVE_DMA_API_DEBUG=y -CONFIG_HAVE_DMA_CONTIGUOUS=y -CONFIG_HAVE_DYNAMIC_FTRACE=y -CONFIG_HAVE_DYNAMIC_FTRACE_WITH_REGS=y -CONFIG_HAVE_EBPF_JIT=y -CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y -CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y -CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y -CONFIG_HAVE_FUNCTION_TRACER=y -CONFIG_HAVE_GENERIC_DMA_COHERENT=y -CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y -CONFIG_HAVE_MEMBLOCK=y -CONFIG_HAVE_MOD_ARCH_SPECIFIC=y -CONFIG_HAVE_NET_DSA=y -CONFIG_HAVE_OPROFILE=y -CONFIG_HAVE_OPTPROBES=y -CONFIG_HAVE_PERF_EVENTS=y -CONFIG_HAVE_PERF_REGS=y -CONFIG_HAVE_PERF_USER_STACK_DUMP=y -CONFIG_HAVE_PROC_CPU=y -CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y -CONFIG_HAVE_SYSCALL_TRACEPOINTS=y -CONFIG_HAVE_UID16=y -CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y -CONFIG_HW_CONSOLE=y -CONFIG_HZ_FIXED=0 -CONFIG_IKCONFIG=y -CONFIG_IKCONFIG_PROC=y -CONFIG_INPUT=y -CONFIG_INPUT_MOUSEDEV=y -# CONFIG_INPUT_MOUSEDEV_PSAUX is not set -CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 -CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 -CONFIG_IOMMU_HELPER=y -CONFIG_IOSCHED_CFQ=y -CONFIG_IRQCHIP=y -CONFIG_IRQ_DOMAIN=y -CONFIG_IRQ_FORCED_THREADING=y -CONFIG_IRQ_WORK=y -CONFIG_JBD2=y -CONFIG_KERNEL_GZIP=y -# CONFIG_KERNEL_XZ is not set -# CONFIG_LCD_CLASS_DEVICE is not set -CONFIG_LEDS_GPIO=y -CONFIG_LEDS_TRIGGER_INPUT=y -CONFIG_LIBFDT=y -CONFIG_LOGO=y -CONFIG_LOGO_LINUX_CLUT224=y -# CONFIG_LOGO_LINUX_MONO is not set -# CONFIG_LOGO_LINUX_VGA16 is not set -CONFIG_MAC_PARTITION=y -CONFIG_MAGIC_SYSRQ=y -CONFIG_MAILBOX=y -# CONFIG_MAILBOX_TEST is not set -CONFIG_MAX_RAW_DEVS=256 -# CONFIG_MDIO_BUS is not set -CONFIG_MEMORY_ISOLATION=y -CONFIG_MFD_RPISENSE_CORE=y -CONFIG_MFD_SYSCON=y -CONFIG_MIGHT_HAVE_CACHE_L2X0=y -CONFIG_MIGHT_HAVE_PCI=y -CONFIG_MIGRATION=y -CONFIG_MMC=y -CONFIG_MMC_BCM2835=y -CONFIG_MMC_BCM2835_DMA=y -CONFIG_MMC_BCM2835_MMC=y -CONFIG_MMC_BCM2835_PIO_DMA_BARRIER=2 -CONFIG_MMC_BCM2835_SDHOST=y -CONFIG_MMC_BLOCK=y -CONFIG_MMC_BLOCK_MINORS=32 -CONFIG_MMC_SDHCI=y -CONFIG_MMC_SDHCI_PLTFM=y -CONFIG_MODULES_USE_ELF_REL=y -# CONFIG_MTD is not set -CONFIG_MULTI_IRQ_HANDLER=y -CONFIG_NEED_DMA_MAP_STATE=y -CONFIG_NEED_PER_CPU_KM=y -CONFIG_NLS=y -CONFIG_NLS_ASCII=y -CONFIG_NLS_DEFAULT="utf8" -CONFIG_NO_BOOTMEM=y -CONFIG_NO_HZ=y -CONFIG_NO_HZ_COMMON=y -CONFIG_NO_HZ_IDLE=y -CONFIG_OABI_COMPAT=y -CONFIG_OF=y -CONFIG_OF_ADDRESS=y -CONFIG_OF_CONFIGFS=y -CONFIG_OF_DYNAMIC=y -CONFIG_OF_EARLY_FLATTREE=y -CONFIG_OF_FLATTREE=y -CONFIG_OF_GPIO=y -CONFIG_OF_IRQ=y -CONFIG_OF_NET=y -CONFIG_OF_OVERLAY=y -CONFIG_OF_RESERVED_MEM=y -CONFIG_OF_RESOLVE=y -CONFIG_OLD_SIGACTION=y -CONFIG_OLD_SIGSUSPEND3=y -CONFIG_PAGE_OFFSET=0xC0000000 -# CONFIG_PCI_DOMAINS_GENERIC is not set -# CONFIG_PCI_SYSCALL is not set -CONFIG_PERF_USE_VMALLOC=y -CONFIG_PGTABLE_LEVELS=2 -CONFIG_PINCTRL=y -CONFIG_PINCTRL_BCM2835=y -CONFIG_PM=y -CONFIG_PM_CLK=y -# CONFIG_PM_DEBUG is not set -CONFIG_PM_GENERIC_DOMAINS=y -CONFIG_PM_GENERIC_DOMAINS_OF=y -CONFIG_PM_GENERIC_DOMAINS_SLEEP=y -CONFIG_PM_SLEEP=y -CONFIG_POWER_SUPPLY=y -CONFIG_PRINTK_SAFE_LOG_BUF_SHIFT=13 -CONFIG_PRINTK_TIME=y -CONFIG_PROC_PAGE_MONITOR=y -CONFIG_PWM=y -CONFIG_PWM_BCM2835=y -CONFIG_PWM_SYSFS=y -CONFIG_RASPBERRYPI_FIRMWARE=y -CONFIG_RASPBERRYPI_POWER=y -CONFIG_RATIONAL=y -CONFIG_RAW_DRIVER=y -# CONFIG_RCU_NEED_SEGCBLIST is not set -# CONFIG_RCU_STALL_COMMON is not set -CONFIG_REGMAP=y -CONFIG_REGMAP_MMIO=y -CONFIG_REGULATOR=y -CONFIG_REGULATOR_FIXED_VOLTAGE=y -CONFIG_RWSEM_XCHGADD_ALGORITHM=y -# CONFIG_SCHED_INFO is not set -CONFIG_SCSI=y -# CONFIG_SCSI_LOWLEVEL is not set -# CONFIG_SCSI_PROC_FS is not set -CONFIG_SERIAL_8250_BCM2835AUX=y -# CONFIG_SERIAL_8250_DMA is not set -CONFIG_SERIAL_8250_EXTENDED=y -CONFIG_SERIAL_8250_FSL=y -CONFIG_SERIAL_8250_NR_UARTS=1 -CONFIG_SERIAL_8250_RUNTIME_UARTS=0 -CONFIG_SERIAL_8250_SHARE_IRQ=y -CONFIG_SERIAL_AMBA_PL011=y -CONFIG_SERIAL_AMBA_PL011_CONSOLE=y -CONFIG_SERIAL_OF_PLATFORM=y -CONFIG_SG_POOL=y -# CONFIG_SND_BCM2708_SOC_GOOGLEVOICEHAT_SOUNDCARD is not set -# CONFIG_SND_BCM2708_SOC_RPI_CIRRUS is not set -CONFIG_SND_BCM2708_SOC_ALLO_PIANO_DAC_PLUS=m -CONFIG_SND_BCM2708_SOC_ALLO_BOSS_DAC=m -CONFIG_SND_BCM2708_SOC_ALLO_DIGIONE=m -# CONFIG_SND_BCM2708_SOC_ALLO_KATANA_DAC is not set -# CONFIG_SND_AUDIOINJECTOR_OCTO_SOUNDCARD is not set -CONFIG_SND_SOC_ICS43432=y -CONFIG_SPARSE_IRQ=y -CONFIG_SRCU=y -# CONFIG_STRIP_ASM_SYMS is not set -CONFIG_SUSPEND=y -CONFIG_SUSPEND_FREEZER=y -CONFIG_SWIOTLB=y -CONFIG_SYS_SUPPORTS_APM_EMULATION=y -# CONFIG_TEXTSEARCH is not set -CONFIG_THERMAL=y -CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y -CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=0 -CONFIG_THERMAL_GOV_STEP_WISE=y -CONFIG_THERMAL_OF=y -CONFIG_THIN_ARCHIVES=y -CONFIG_TICK_CPU_ACCOUNTING=y -CONFIG_TIMER_OF=y -CONFIG_TIMER_PROBE=y -CONFIG_TINY_SRCU=y -CONFIG_TMPFS_POSIX_ACL=y -CONFIG_UEVENT_HELPER_PATH="" -# CONFIG_UID16 is not set -CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h" -CONFIG_USB=y -CONFIG_USB_ANNOUNCE_NEW_DEVICES=y -CONFIG_USB_COMMON=y -CONFIG_USB_DWCOTG=y -CONFIG_USB_LAN78XX=y -# CONFIG_USB_EHCI_HCD is not set -CONFIG_USB_NET_DRIVERS=y -CONFIG_USB_NET_SMSC95XX=y -CONFIG_USB_STORAGE=y -CONFIG_USB_SUPPORT=y -CONFIG_USB_UAS=y -CONFIG_USB_USBNET=y -CONFIG_USE_OF=y -CONFIG_VECTORS_BASE=0xffff0000 -CONFIG_VFP=y -CONFIG_VT=y -CONFIG_VT_CONSOLE=y -CONFIG_VT_CONSOLE_SLEEP=y -CONFIG_VT_HW_CONSOLE_BINDING=y -CONFIG_WATCHDOG_CORE=y -CONFIG_XZ_DEC_ARM=y -CONFIG_XZ_DEC_BCJ=y -CONFIG_ZBOOT_ROM_BSS=0x0 -CONFIG_ZBOOT_ROM_TEXT=0x0 diff --git a/root/target/linux/bcm27xx/bcm2709/config-4.14 b/root/target/linux/bcm27xx/bcm2709/config-4.14 deleted file mode 100644 index 083c4b94..00000000 --- a/root/target/linux/bcm27xx/bcm2709/config-4.14 +++ /dev/null @@ -1,472 +0,0 @@ -# CONFIG_AIO is not set -CONFIG_ALIGNMENT_TRAP=y -CONFIG_ARCH_BCM=y -CONFIG_ARCH_BCM2835=y -CONFIG_ARCH_CLOCKSOURCE_DATA=y -CONFIG_ARCH_HAS_DEBUG_VIRTUAL=y -CONFIG_ARCH_HAS_ELF_RANDOMIZE=y -CONFIG_ARCH_HAS_GCOV_PROFILE_ALL=y -CONFIG_ARCH_HAS_SET_MEMORY=y -CONFIG_ARCH_HAS_SG_CHAIN=y -CONFIG_ARCH_HAS_STRICT_KERNEL_RWX=y -CONFIG_ARCH_HAS_STRICT_MODULE_RWX=y -CONFIG_ARCH_HAS_TICK_BROADCAST=y -CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y -CONFIG_ARCH_HIBERNATION_POSSIBLE=y -CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y -CONFIG_ARCH_MMAP_RND_BITS_MAX=15 -CONFIG_ARCH_MULTIPLATFORM=y -# CONFIG_ARCH_MULTI_CPU_AUTO is not set -CONFIG_ARCH_MULTI_V6_V7=y -CONFIG_ARCH_MULTI_V7=y -CONFIG_ARCH_NR_GPIO=0 -CONFIG_ARCH_OPTIONAL_KERNEL_RWX=y -CONFIG_ARCH_OPTIONAL_KERNEL_RWX_DEFAULT=y -# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set -# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set -CONFIG_ARCH_SUPPORTS_ATOMIC_RMW=y -CONFIG_ARCH_SUPPORTS_UPROBES=y -CONFIG_ARCH_SUSPEND_POSSIBLE=y -CONFIG_ARCH_USE_BUILTIN_BSWAP=y -CONFIG_ARCH_USE_CMPXCHG_LOCKREF=y -# CONFIG_ARCH_WANTS_THP_SWAP is not set -CONFIG_ARCH_WANT_GENERAL_HUGETLB=y -CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y -CONFIG_ARM=y -CONFIG_ARM_AMBA=y -CONFIG_ARM_ARCH_TIMER=y -CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y -CONFIG_ARM_BCM2835_CPUFREQ=y -CONFIG_ARM_CPU_SUSPEND=y -CONFIG_ARM_HAS_SG_CHAIN=y -CONFIG_ARM_L1_CACHE_SHIFT=6 -CONFIG_ARM_L1_CACHE_SHIFT_6=y -# CONFIG_ARM_LPAE is not set -CONFIG_ARM_PATCH_IDIV=y -CONFIG_ARM_PATCH_PHYS_VIRT=y -# CONFIG_ARM_SP805_WATCHDOG is not set -CONFIG_ARM_THUMB=y -# CONFIG_ARM_THUMBEE is not set -CONFIG_ARM_TIMER_SP804=y -CONFIG_ARM_UNWIND=y -CONFIG_ARM_VIRT_EXT=y -CONFIG_AUTO_ZRELADDR=y -# CONFIG_BACKLIGHT_CLASS_DEVICE is not set -CONFIG_BACKLIGHT_LCD_SUPPORT=y -CONFIG_BCM2708_VCMEM=y -# CONFIG_BCM2835_DEVGPIOMEM is not set -CONFIG_BCM2835_MBOX=y -# CONFIG_BCM2835_SMI is not set -CONFIG_BCM2835_THERMAL=y -CONFIG_BCM2835_TIMER=y -CONFIG_BCM2835_VCHIQ=y -# CONFIG_BCM2835_VCHIQ_SUPPORT_MEMDUMP is not set -CONFIG_BCM2835_WDT=y -CONFIG_BCM_VCIO=y -CONFIG_BCM_VC_SM=y -CONFIG_BCM_VIDEOCORE=y -# CONFIG_BLK_DEV_INITRD is not set -CONFIG_BLK_DEV_LOOP=y -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_COUNT=16 -CONFIG_BLK_DEV_RAM_SIZE=4096 -CONFIG_BLK_DEV_SD=y -CONFIG_BLK_SCSI_REQUEST=y -CONFIG_BRCM_CHAR_DRIVERS=y -CONFIG_BUILD_BIN2C=y -# CONFIG_CACHE_L2X0 is not set -CONFIG_CLKDEV_LOOKUP=y -CONFIG_CLKSRC_MMIO=y -CONFIG_CLONE_BACKWARDS=y -CONFIG_CMA=y -CONFIG_CMA_ALIGNMENT=8 -CONFIG_CMA_AREAS=7 -# CONFIG_CMA_DEBUG is not set -# CONFIG_CMA_DEBUGFS is not set -CONFIG_CMA_SIZE_MBYTES=16 -# CONFIG_CMA_SIZE_SEL_MAX is not set -CONFIG_CMA_SIZE_SEL_MBYTES=y -# CONFIG_CMA_SIZE_SEL_MIN is not set -# CONFIG_CMA_SIZE_SEL_PERCENTAGE is not set -CONFIG_COMMON_CLK=y -CONFIG_CONFIGFS_FS=y -CONFIG_CONSOLE_LOGLEVEL_DEFAULT=7 -CONFIG_CONSOLE_TRANSLATIONS=y -# CONFIG_CPUFREQ_DT is not set -CONFIG_CPU_32v6K=y -CONFIG_CPU_32v7=y -CONFIG_CPU_ABRT_EV7=y -# CONFIG_CPU_BPREDICT_DISABLE is not set -CONFIG_CPU_CACHE_V7=y -CONFIG_CPU_CACHE_VIPT=y -CONFIG_CPU_COPY_V6=y -CONFIG_CPU_CP15=y -CONFIG_CPU_CP15_MMU=y -CONFIG_CPU_FREQ=y -CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y -# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set -CONFIG_CPU_FREQ_GOV_ATTR_SET=y -CONFIG_CPU_FREQ_GOV_COMMON=y -CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y -CONFIG_CPU_FREQ_GOV_ONDEMAND=y -CONFIG_CPU_FREQ_GOV_PERFORMANCE=y -CONFIG_CPU_FREQ_GOV_POWERSAVE=y -CONFIG_CPU_FREQ_GOV_USERSPACE=y -CONFIG_CPU_FREQ_STAT=y -CONFIG_CPU_HAS_ASID=y -# CONFIG_CPU_HOTPLUG_STATE_CONTROL is not set -# CONFIG_CPU_ICACHE_DISABLE is not set -CONFIG_CPU_IDLE=y -CONFIG_CPU_IDLE_GOV_LADDER=y -CONFIG_CPU_IDLE_GOV_MENU=y -CONFIG_CPU_PABRT_V7=y -CONFIG_CPU_PM=y -CONFIG_CPU_RMAP=y -# CONFIG_CPU_THERMAL is not set -CONFIG_CPU_THUMB_CAPABLE=y -CONFIG_CPU_TLB_V7=y -CONFIG_CPU_V7=y -CONFIG_CRC16=y -CONFIG_CRYPTO_AEAD=y -CONFIG_CRYPTO_AEAD2=y -CONFIG_CRYPTO_CRC32C=y -CONFIG_CRYPTO_HASH=y -CONFIG_CRYPTO_HASH2=y -CONFIG_CRYPTO_MANAGER=y -CONFIG_CRYPTO_MANAGER2=y -CONFIG_CRYPTO_NULL2=y -CONFIG_CRYPTO_RNG2=y -CONFIG_CRYPTO_WORKQUEUE=y -CONFIG_DCACHE_WORD_ACCESS=y -CONFIG_DEBUG_ALIGN_RODATA=y -CONFIG_DEBUG_BUGVERBOSE=y -CONFIG_DEBUG_INFO=y -CONFIG_DEBUG_LL_INCLUDE="mach/debug-macro.S" -# CONFIG_DEBUG_UART_8250 is not set -# CONFIG_DEBUG_USER is not set -CONFIG_DEFAULT_CFQ=y -# CONFIG_DEFAULT_DEADLINE is not set -CONFIG_DEFAULT_IOSCHED="cfq" -CONFIG_DMADEVICES=y -CONFIG_DMA_BCM2708=y -CONFIG_DMA_BCM2835=y -CONFIG_DMA_CMA=y -CONFIG_DMA_ENGINE=y -# CONFIG_DMA_NOOP_OPS is not set -CONFIG_DMA_OF=y -CONFIG_DMA_SHARED_BUFFER=y -CONFIG_DMA_VIRTUAL_CHANNELS=y -# CONFIG_DMA_VIRT_OPS is not set -CONFIG_DNOTIFY=y -# CONFIG_DRM_LIB_RANDOM is not set -CONFIG_DRM_PANEL_LVDS=n -CONFIG_DRM_PANEL_INNOLUX_P079ZCA=n -CONFIG_DRM_PANEL_SAMSUNG_S6E3HA2=n -CONFIG_DRM_PANEL_SITRONIX_ST7789V=n -CONFIG_DRM_VC4_HDMI_CEC=n -CONFIG_DTC=y -CONFIG_DUMMY_CONSOLE=y -CONFIG_EDAC_ATOMIC_SCRUB=y -CONFIG_EDAC_SUPPORT=y -CONFIG_ENABLE_MUST_CHECK=y -CONFIG_EXPORTFS=y -CONFIG_EXT4_FS=y -CONFIG_EXT4_FS_POSIX_ACL=y -CONFIG_EXT4_FS_SECURITY=y -# CONFIG_F2FS_CHECK_FS is not set -CONFIG_F2FS_FS=y -# CONFIG_F2FS_FS_SECURITY is not set -CONFIG_F2FS_FS_XATTR=y -CONFIG_F2FS_STAT_FS=y -CONFIG_FB=y -CONFIG_FB_BCM2708=y -CONFIG_FB_CFB_COPYAREA=y -CONFIG_FB_CFB_FILLRECT=y -CONFIG_FB_CFB_IMAGEBLIT=y -CONFIG_FB_CMDLINE=y -# CONFIG_FB_PROVIDE_GET_FB_UNMAPPED_AREA is not set -# CONFIG_FB_RPISENSE is not set -CONFIG_FIQ=y -CONFIG_FIRMWARE_IN_KERNEL=y -CONFIG_FIX_EARLYCON_MEM=y -# CONFIG_FONTS is not set -CONFIG_FONT_8x16=y -CONFIG_FONT_8x8=y -CONFIG_FONT_SUPPORT=y -# CONFIG_FPE_FASTFPE is not set -# CONFIG_FPE_NWFPE is not set -CONFIG_FRAMEBUFFER_CONSOLE=y -# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set -# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set -CONFIG_FREEZER=y -CONFIG_FS_MBCACHE=y -CONFIG_FS_POSIX_ACL=y -CONFIG_FUTEX_PI=y -CONFIG_GENERIC_ALLOCATOR=y -CONFIG_GENERIC_ARCH_TOPOLOGY=y -CONFIG_GENERIC_BUG=y -CONFIG_GENERIC_CLOCKEVENTS=y -CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y -CONFIG_GENERIC_CPU_AUTOPROBE=y -CONFIG_GENERIC_EARLY_IOREMAP=y -CONFIG_GENERIC_IDLE_POLL_SETUP=y -CONFIG_GENERIC_IO=y -CONFIG_GENERIC_IRQ_SHOW=y -CONFIG_GENERIC_IRQ_SHOW_LEVEL=y -CONFIG_GENERIC_PCI_IOMAP=y -CONFIG_GENERIC_PINCONF=y -CONFIG_GENERIC_PINCTRL_GROUPS=y -CONFIG_GENERIC_PINMUX_FUNCTIONS=y -CONFIG_GENERIC_SCHED_CLOCK=y -CONFIG_GENERIC_SMP_IDLE_THREAD=y -CONFIG_GENERIC_STRNCPY_FROM_USER=y -CONFIG_GENERIC_STRNLEN_USER=y -CONFIG_GPIOLIB=y -CONFIG_GPIOLIB_IRQCHIP=y -CONFIG_GPIO_ARIZONA=y -CONFIG_GPIO_BCM_EXP=y -CONFIG_GPIO_BCM_VIRT=y -CONFIG_GPIO_SYSFS=y -# CONFIG_GRO_CELLS is not set -CONFIG_HANDLE_DOMAIN_IRQ=y -CONFIG_HARDIRQS_SW_RESEND=y -CONFIG_HAS_DMA=y -CONFIG_HAS_IOMEM=y -CONFIG_HAS_IOPORT_MAP=y -# CONFIG_HAVE_64BIT_ALIGNED_ACCESS is not set -CONFIG_HAVE_ARCH_BITREVERSE=y -CONFIG_HAVE_ARCH_JUMP_LABEL=y -CONFIG_HAVE_ARCH_KGDB=y -CONFIG_HAVE_ARCH_PFN_VALID=y -CONFIG_HAVE_ARCH_TRACEHOOK=y -CONFIG_HAVE_ARM_ARCH_TIMER=y -CONFIG_HAVE_ARM_SMCCC=y -# CONFIG_HAVE_BOOTMEM_INFO_NODE is not set -CONFIG_HAVE_CC_STACKPROTECTOR=y -CONFIG_HAVE_CLK=y -CONFIG_HAVE_CLK_PREPARE=y -CONFIG_HAVE_CONTEXT_TRACKING=y -CONFIG_HAVE_C_RECORDMCOUNT=y -CONFIG_HAVE_DEBUG_KMEMLEAK=y -CONFIG_HAVE_DMA_API_DEBUG=y -CONFIG_HAVE_DMA_CONTIGUOUS=y -CONFIG_HAVE_DYNAMIC_FTRACE=y -CONFIG_HAVE_DYNAMIC_FTRACE_WITH_REGS=y -CONFIG_HAVE_EBPF_JIT=y -CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y -CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y -CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y -CONFIG_HAVE_FUNCTION_TRACER=y -CONFIG_HAVE_GENERIC_DMA_COHERENT=y -CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y -CONFIG_HAVE_MEMBLOCK=y -CONFIG_HAVE_MOD_ARCH_SPECIFIC=y -CONFIG_HAVE_NET_DSA=y -CONFIG_HAVE_OPROFILE=y -CONFIG_HAVE_OPTPROBES=y -CONFIG_HAVE_PERF_EVENTS=y -CONFIG_HAVE_PERF_REGS=y -CONFIG_HAVE_PERF_USER_STACK_DUMP=y -CONFIG_HAVE_PROC_CPU=y -CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y -CONFIG_HAVE_SMP=y -CONFIG_HAVE_SYSCALL_TRACEPOINTS=y -CONFIG_HAVE_UID16=y -CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y -CONFIG_HOTPLUG_CPU=y -CONFIG_HW_CONSOLE=y -CONFIG_HZ_FIXED=0 -CONFIG_IKCONFIG=y -CONFIG_IKCONFIG_PROC=y -CONFIG_INPUT=y -CONFIG_INPUT_MOUSEDEV=y -# CONFIG_INPUT_MOUSEDEV_PSAUX is not set -CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 -CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 -CONFIG_IOMMU_HELPER=y -CONFIG_IOSCHED_CFQ=y -CONFIG_IRQCHIP=y -CONFIG_IRQ_DOMAIN=y -CONFIG_IRQ_FORCED_THREADING=y -CONFIG_IRQ_WORK=y -CONFIG_JBD2=y -CONFIG_KERNEL_GZIP=y -# CONFIG_KERNEL_XZ is not set -# CONFIG_LCD_CLASS_DEVICE is not set -CONFIG_LEDS_GPIO=y -CONFIG_LEDS_TRIGGER_INPUT=y -CONFIG_LIBFDT=y -CONFIG_LOCK_SPIN_ON_OWNER=y -CONFIG_LOGO=y -CONFIG_LOGO_LINUX_CLUT224=y -# CONFIG_LOGO_LINUX_MONO is not set -# CONFIG_LOGO_LINUX_VGA16 is not set -CONFIG_MAC_PARTITION=y -CONFIG_MAGIC_SYSRQ=y -CONFIG_MAILBOX=y -# CONFIG_MAILBOX_TEST is not set -CONFIG_MAX_RAW_DEVS=256 -# CONFIG_MDIO_BUS is not set -CONFIG_MEMORY_ISOLATION=y -CONFIG_MFD_ARIZONA=y -CONFIG_MFD_SYSCON=y -# CONFIG_MFD_RPISENSE_CORE is not set -CONFIG_MIGHT_HAVE_CACHE_L2X0=y -CONFIG_MIGHT_HAVE_PCI=y -CONFIG_MIGRATION=y -CONFIG_MMC=y -CONFIG_MMC_BCM2835=y -CONFIG_MMC_BCM2835_DMA=y -CONFIG_MMC_BCM2835_MMC=y -CONFIG_MMC_BCM2835_PIO_DMA_BARRIER=2 -CONFIG_MMC_BCM2835_SDHOST=y -CONFIG_MMC_BLOCK=y -CONFIG_MMC_BLOCK_MINORS=32 -CONFIG_MMC_SDHCI=y -CONFIG_MMC_SDHCI_PLTFM=y -CONFIG_MODULES_USE_ELF_REL=y -# CONFIG_MTD is not set -CONFIG_MULTI_IRQ_HANDLER=y -CONFIG_MUTEX_SPIN_ON_OWNER=y -CONFIG_NEED_DMA_MAP_STATE=y -CONFIG_NEON=y -CONFIG_NET_FLOW_LIMIT=y -CONFIG_NLS=y -CONFIG_NLS_ASCII=y -CONFIG_NLS_DEFAULT="utf8" -CONFIG_NO_BOOTMEM=y -CONFIG_NO_HZ=y -CONFIG_NO_HZ_COMMON=y -CONFIG_NO_HZ_IDLE=y -CONFIG_NR_CPUS=4 -CONFIG_OABI_COMPAT=y -CONFIG_OF=y -CONFIG_OF_ADDRESS=y -CONFIG_OF_CONFIGFS=y -CONFIG_OF_DYNAMIC=y -CONFIG_OF_EARLY_FLATTREE=y -CONFIG_OF_FLATTREE=y -CONFIG_OF_GPIO=y -CONFIG_OF_IRQ=y -CONFIG_OF_NET=y -CONFIG_OF_OVERLAY=y -CONFIG_OF_RESERVED_MEM=y -CONFIG_OF_RESOLVE=y -CONFIG_OLD_SIGACTION=y -CONFIG_OLD_SIGSUSPEND3=y -CONFIG_PADATA=y -CONFIG_PAGE_OFFSET=0x80000000 -# CONFIG_PCI_DOMAINS_GENERIC is not set -# CONFIG_PCI_SYSCALL is not set -CONFIG_PERF_USE_VMALLOC=y -CONFIG_PGTABLE_LEVELS=2 -CONFIG_PINCTRL=y -CONFIG_PINCTRL_BCM2835=y -CONFIG_PM=y -CONFIG_PM_CLK=y -# CONFIG_PM_DEBUG is not set -CONFIG_PM_GENERIC_DOMAINS=y -CONFIG_PM_GENERIC_DOMAINS_OF=y -CONFIG_PM_GENERIC_DOMAINS_SLEEP=y -CONFIG_PM_SLEEP=y -CONFIG_PM_SLEEP_SMP=y -CONFIG_POWER_SUPPLY=y -CONFIG_PRINTK_SAFE_LOG_BUF_SHIFT=13 -CONFIG_PRINTK_TIME=y -CONFIG_PROC_PAGE_MONITOR=y -CONFIG_PWM=y -CONFIG_PWM_BCM2835=y -CONFIG_PWM_SYSFS=y -CONFIG_RASPBERRYPI_FIRMWARE=y -CONFIG_RASPBERRYPI_POWER=y -CONFIG_RATIONAL=y -CONFIG_RAW_DRIVER=y -CONFIG_RCU_NEED_SEGCBLIST=y -CONFIG_RCU_STALL_COMMON=y -CONFIG_REGMAP=y -CONFIG_REGMAP_MMIO=y -CONFIG_REGULATOR=y -CONFIG_REGULATOR_FIXED_VOLTAGE=y -CONFIG_RFS_ACCEL=y -CONFIG_RPS=y -CONFIG_RWSEM_SPIN_ON_OWNER=y -CONFIG_RWSEM_XCHGADD_ALGORITHM=y -# CONFIG_SCHED_INFO is not set -CONFIG_SCSI=y -# CONFIG_SCSI_LOWLEVEL is not set -# CONFIG_SCSI_PROC_FS is not set -CONFIG_SERIAL_8250_BCM2835AUX=y -# CONFIG_SERIAL_8250_DMA is not set -CONFIG_SERIAL_8250_EXTENDED=y -CONFIG_SERIAL_8250_FSL=y -CONFIG_SERIAL_8250_NR_UARTS=1 -CONFIG_SERIAL_8250_RUNTIME_UARTS=0 -CONFIG_SERIAL_8250_SHARE_IRQ=y -CONFIG_SERIAL_AMBA_PL011=y -CONFIG_SERIAL_AMBA_PL011_CONSOLE=y -CONFIG_SERIAL_OF_PLATFORM=y -CONFIG_SG_POOL=y -CONFIG_SMP=y -CONFIG_SMP_ON_UP=y -CONFIG_SND_BCM2708_SOC_GOOGLEVOICEHAT_SOUNDCARD=n -CONFIG_SND_BCM2708_SOC_RPI_CIRRUS=n -CONFIG_SND_AUDIOINJECTOR_OCTO_SOUNDCARD=n -CONFIG_SND_BCM2708_SOC_ALLO_PIANO_DAC_PLUS=n -CONFIG_SND_BCM2708_SOC_ALLO_BOSS_DAC=n -CONFIG_SND_BCM2708_SOC_ALLO_DIGIONE=n -CONFIG_SND_BCM2708_SOC_ALLO_KATANA_DAC=n -# CONFIG_SND_SOC_ICS43432 is not set -CONFIG_SPARSE_IRQ=y -CONFIG_SRCU=y -# CONFIG_STRIP_ASM_SYMS is not set -CONFIG_SUSPEND=y -CONFIG_SUSPEND_FREEZER=y -CONFIG_SWIOTLB=y -CONFIG_SWP_EMULATE=y -CONFIG_SYS_SUPPORTS_APM_EMULATION=y -# CONFIG_TEE is not set -# CONFIG_TEXTSEARCH is not set -CONFIG_THERMAL=y -CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y -CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=0 -CONFIG_THERMAL_GOV_STEP_WISE=y -CONFIG_THERMAL_OF=y -CONFIG_THIN_ARCHIVES=y -# CONFIG_THUMB2_KERNEL is not set -CONFIG_TICK_CPU_ACCOUNTING=y -CONFIG_TIMER_OF=y -CONFIG_TIMER_PROBE=y -CONFIG_TMPFS_POSIX_ACL=y -CONFIG_TREE_RCU=y -CONFIG_TREE_SRCU=y -CONFIG_UEVENT_HELPER_PATH="" -# CONFIG_UID16 is not set -CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h" -CONFIG_USB=y -CONFIG_USB_ANNOUNCE_NEW_DEVICES=y -CONFIG_USB_COMMON=y -CONFIG_USB_DWCOTG=y -# CONFIG_USB_EHCI_HCD is not set -CONFIG_USB_LAN78XX=y -CONFIG_USB_NET_DRIVERS=y -CONFIG_USB_NET_SMSC95XX=y -CONFIG_USB_STORAGE=y -CONFIG_USB_SUPPORT=y -CONFIG_USB_UAS=y -CONFIG_USB_USBNET=y -CONFIG_USE_OF=y -CONFIG_VECTORS_BASE=0xffff0000 -CONFIG_VFP=y -CONFIG_VFPv3=y -CONFIG_VMSPLIT_2G=y -# CONFIG_VMSPLIT_3G is not set -CONFIG_VT=y -CONFIG_VT_CONSOLE=y -CONFIG_VT_CONSOLE_SLEEP=y -CONFIG_VT_HW_CONSOLE_BINDING=y -CONFIG_WATCHDOG_CORE=y -CONFIG_XPS=y -CONFIG_XZ_DEC_ARM=y -CONFIG_XZ_DEC_BCJ=y -CONFIG_ZBOOT_ROM_BSS=0x0 -CONFIG_ZBOOT_ROM_TEXT=0x0 diff --git a/root/target/linux/bcm27xx/bcm2709/config-4.19 b/root/target/linux/bcm27xx/bcm2709/config-4.19 deleted file mode 100644 index 0dacdda4..00000000 --- a/root/target/linux/bcm27xx/bcm2709/config-4.19 +++ /dev/null @@ -1,568 +0,0 @@ -# CONFIG_AIO is not set -CONFIG_ALIGNMENT_TRAP=y -# CONFIG_ARCH_AXXIA is not set -CONFIG_ARCH_BCM=y -CONFIG_ARCH_BCM2835=y -# CONFIG_ARCH_BCM_HR2 is not set -CONFIG_ARCH_CLOCKSOURCE_DATA=y -CONFIG_ARCH_DMA_ADDR_T_64BIT=y -CONFIG_ARCH_HAS_DEBUG_VIRTUAL=y -CONFIG_ARCH_HAS_ELF_RANDOMIZE=y -CONFIG_ARCH_HAS_FORTIFY_SOURCE=y -CONFIG_ARCH_HAS_GCOV_PROFILE_ALL=y -CONFIG_ARCH_HAS_KCOV=y -CONFIG_ARCH_HAS_MEMBARRIER_SYNC_CORE=y -CONFIG_ARCH_HAS_PHYS_TO_DMA=y -CONFIG_ARCH_HAS_PTE_SPECIAL=y -CONFIG_ARCH_HAS_SET_MEMORY=y -CONFIG_ARCH_HAS_SG_CHAIN=y -CONFIG_ARCH_HAS_STRICT_KERNEL_RWX=y -CONFIG_ARCH_HAS_STRICT_MODULE_RWX=y -CONFIG_ARCH_HAS_TICK_BROADCAST=y -CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y -CONFIG_ARCH_HIBERNATION_POSSIBLE=y -CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y -CONFIG_ARCH_MULTIPLATFORM=y -CONFIG_ARCH_MULTI_V6_V7=y -CONFIG_ARCH_MULTI_V7=y -CONFIG_ARCH_NR_GPIO=0 -CONFIG_ARCH_OPTIONAL_KERNEL_RWX=y -CONFIG_ARCH_OPTIONAL_KERNEL_RWX_DEFAULT=y -CONFIG_ARCH_SUPPORTS_ATOMIC_RMW=y -CONFIG_ARCH_SUPPORTS_UPROBES=y -CONFIG_ARCH_SUSPEND_POSSIBLE=y -CONFIG_ARCH_USE_BUILTIN_BSWAP=y -CONFIG_ARCH_USE_CMPXCHG_LOCKREF=y -CONFIG_ARCH_WANT_GENERAL_HUGETLB=y -CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y -CONFIG_ARGON_MEM=y -CONFIG_ARM=y -CONFIG_ARM_AMBA=y -CONFIG_ARM_ARCH_TIMER=y -CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y -CONFIG_ARM_BCM2835_CPUFREQ=y -CONFIG_ARM_CPU_SUSPEND=y -CONFIG_ARM_CRYPTO=y -CONFIG_ARM_ERRATA_643719=y -CONFIG_ARM_GIC=y -CONFIG_ARM_HAS_SG_CHAIN=y -CONFIG_ARM_HEAVY_MB=y -CONFIG_ARM_L1_CACHE_SHIFT=6 -CONFIG_ARM_L1_CACHE_SHIFT_6=y -CONFIG_ARM_LPAE=y -CONFIG_ARM_MODULE_PLTS=y -CONFIG_ARM_PATCH_IDIV=y -CONFIG_ARM_PATCH_PHYS_VIRT=y -# CONFIG_ARM_SCMI_PROTOCOL is not set -# CONFIG_ARM_SP805_WATCHDOG is not set -CONFIG_ARM_THUMB=y -# CONFIG_ARM_THUMBEE is not set -CONFIG_ARM_TIMER_SP804=y -CONFIG_ARM_UNWIND=y -CONFIG_ARM_VIRT_EXT=y -CONFIG_AUTO_ZRELADDR=y -# CONFIG_AX88796B_PHY is not set -# CONFIG_BACKLIGHT_CLASS_DEVICE is not set -CONFIG_BACKLIGHT_LCD_SUPPORT=y -CONFIG_BCM2708_VCMEM=y -CONFIG_BCM2835_DEVGPIOMEM=y -CONFIG_BCM2835_MBOX=y -CONFIG_BCM2835_POWER=y -# CONFIG_BCM2835_SMI is not set -CONFIG_BCM2835_THERMAL=y -CONFIG_BCM2835_TIMER=y -CONFIG_BCM2835_VCHIQ=y -CONFIG_BCM2835_VCHIQ_MMAL=y -CONFIG_BCM2835_WDT=y -CONFIG_BCM7XXX_PHY=y -CONFIG_BCMGENET=y -CONFIG_BCM_NET_PHYLIB=y -CONFIG_BCM_VCIO=y -CONFIG_BCM_VC_SM=y -CONFIG_BCM_VC_SM_CMA=y -CONFIG_BCM_VIDEOCORE=y -CONFIG_BLK_DEBUG_FS=y -CONFIG_BLK_DEV_BSG=y -CONFIG_BLK_DEV_BSGLIB=y -# CONFIG_BLK_DEV_DM is not set -# CONFIG_BLK_DEV_INITRD is not set -CONFIG_BLK_DEV_LOOP=y -# CONFIG_BLK_DEV_MD is not set -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_COUNT=16 -CONFIG_BLK_DEV_RAM_SIZE=4096 -CONFIG_BLK_DEV_SD=y -CONFIG_BLK_MQ_PCI=y -CONFIG_BLK_SCSI_REQUEST=y -CONFIG_BOUNCE=y -CONFIG_BRCMSTB_THERMAL=y -CONFIG_BRCM_CHAR_DRIVERS=y -CONFIG_BROADCOM_PHY=y -CONFIG_BUILD_BIN2C=y -CONFIG_CACHE_L2X0=y -CONFIG_CC_HAS_ASM_GOTO=y -CONFIG_CLKDEV_LOOKUP=y -CONFIG_CLKSRC_MMIO=y -CONFIG_CLONE_BACKWARDS=y -CONFIG_CMA=y -CONFIG_CMA_ALIGNMENT=8 -CONFIG_CMA_AREAS=7 -# CONFIG_CMA_DEBUG is not set -# CONFIG_CMA_DEBUGFS is not set -CONFIG_CMA_SIZE_MBYTES=5 -# CONFIG_CMA_SIZE_SEL_MAX is not set -CONFIG_CMA_SIZE_SEL_MBYTES=y -# CONFIG_CMA_SIZE_SEL_MIN is not set -# CONFIG_CMA_SIZE_SEL_PERCENTAGE is not set -CONFIG_COMMON_CLK=y -CONFIG_CONFIGFS_FS=y -CONFIG_CONSOLE_TRANSLATIONS=y -# CONFIG_CPUFREQ_DT is not set -CONFIG_CPU_32v6K=y -CONFIG_CPU_32v7=y -CONFIG_CPU_ABRT_EV7=y -# CONFIG_CPU_BPREDICT_DISABLE is not set -CONFIG_CPU_CACHE_V7=y -CONFIG_CPU_CACHE_VIPT=y -CONFIG_CPU_COPY_V6=y -CONFIG_CPU_CP15=y -CONFIG_CPU_CP15_MMU=y -CONFIG_CPU_FREQ=y -CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y -# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set -CONFIG_CPU_FREQ_GOV_ATTR_SET=y -CONFIG_CPU_FREQ_GOV_COMMON=y -CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y -CONFIG_CPU_FREQ_GOV_ONDEMAND=y -CONFIG_CPU_FREQ_GOV_PERFORMANCE=y -CONFIG_CPU_FREQ_GOV_POWERSAVE=y -CONFIG_CPU_FREQ_GOV_USERSPACE=y -CONFIG_CPU_FREQ_STAT=y -CONFIG_CPU_HAS_ASID=y -# CONFIG_CPU_HOTPLUG_STATE_CONTROL is not set -# CONFIG_CPU_ICACHE_DISABLE is not set -CONFIG_CPU_IDLE=y -CONFIG_CPU_IDLE_GOV_LADDER=y -CONFIG_CPU_IDLE_GOV_MENU=y -CONFIG_CPU_PABRT_V7=y -CONFIG_CPU_PM=y -CONFIG_CPU_RMAP=y -CONFIG_CPU_SPECTRE=y -# CONFIG_CPU_THERMAL is not set -CONFIG_CPU_THUMB_CAPABLE=y -CONFIG_CPU_TLB_V7=y -CONFIG_CPU_V7=y -CONFIG_CRC16=y -CONFIG_CRYPTO_AEAD=y -CONFIG_CRYPTO_AEAD2=y -CONFIG_CRYPTO_AES_ARM=y -CONFIG_CRYPTO_AES_ARM_BS=y -CONFIG_CRYPTO_AES_ARM_CE=y -CONFIG_CRYPTO_CHACHA20=y -CONFIG_CRYPTO_CHACHA20_NEON=y -CONFIG_CRYPTO_CRC32=y -CONFIG_CRYPTO_CRC32C=y -CONFIG_CRYPTO_CRC32_ARM_CE=y -CONFIG_CRYPTO_CRYPTD=y -CONFIG_CRYPTO_GHASH_ARM_CE=y -CONFIG_CRYPTO_HASH=y -CONFIG_CRYPTO_HASH2=y -CONFIG_CRYPTO_MANAGER=y -CONFIG_CRYPTO_MANAGER2=y -CONFIG_CRYPTO_NULL2=y -CONFIG_CRYPTO_RNG2=y -CONFIG_CRYPTO_SHA1=y -CONFIG_CRYPTO_SHA1_ARM=y -CONFIG_CRYPTO_SHA1_ARM_CE=y -CONFIG_CRYPTO_SHA1_ARM_NEON=y -CONFIG_CRYPTO_SHA256_ARM=y -CONFIG_CRYPTO_SHA2_ARM_CE=y -CONFIG_CRYPTO_SHA512_ARM=y -CONFIG_CRYPTO_SIMD=y -CONFIG_CRYPTO_WORKQUEUE=y -CONFIG_DCACHE_WORD_ACCESS=y -CONFIG_DEBUG_ALIGN_RODATA=y -CONFIG_DEBUG_BUGVERBOSE=y -CONFIG_DEBUG_INFO=y -CONFIG_DEBUG_LL_INCLUDE="mach/debug-macro.S" -# CONFIG_DEBUG_USER is not set -CONFIG_DEFAULT_CFQ=y -# CONFIG_DEFAULT_DEADLINE is not set -CONFIG_DEFAULT_IOSCHED="cfq" -CONFIG_DEFAULT_MPTCP_PM="fullmesh" -CONFIG_DEVMEM=y -CONFIG_DMADEVICES=y -CONFIG_DMA_BCM2708=y -CONFIG_DMA_BCM2835=y -CONFIG_DMA_CMA=y -CONFIG_DMA_ENGINE=y -CONFIG_DMA_OF=y -CONFIG_DMA_SHARED_BUFFER=y -CONFIG_DMA_VIRTUAL_CHANNELS=y -CONFIG_DNOTIFY=y -CONFIG_DTC=y -CONFIG_DUMMY_CONSOLE=y -CONFIG_EDAC_ATOMIC_SCRUB=y -CONFIG_EDAC_SUPPORT=y -CONFIG_ENABLE_MUST_CHECK=y -CONFIG_EXT4_FS=y -CONFIG_EXT4_FS_POSIX_ACL=y -CONFIG_EXT4_FS_SECURITY=y -# CONFIG_F2FS_CHECK_FS is not set -CONFIG_F2FS_FS=y -# CONFIG_F2FS_FS_SECURITY is not set -CONFIG_F2FS_FS_XATTR=y -CONFIG_F2FS_STAT_FS=y -CONFIG_FB=y -CONFIG_FB_BCM2708=y -CONFIG_FB_CFB_COPYAREA=y -CONFIG_FB_CFB_FILLRECT=y -CONFIG_FB_CFB_IMAGEBLIT=y -CONFIG_FB_CMDLINE=y -# CONFIG_FB_RPISENSE is not set -CONFIG_FIQ=y -CONFIG_FIXED_PHY=y -CONFIG_FIX_EARLYCON_MEM=y -# CONFIG_FONTS is not set -CONFIG_FONT_8x16=y -CONFIG_FONT_8x8=y -CONFIG_FONT_SUPPORT=y -# CONFIG_FPE_FASTFPE is not set -# CONFIG_FPE_NWFPE is not set -CONFIG_FRAMEBUFFER_CONSOLE=y -# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set -# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set -CONFIG_FREEZER=y -CONFIG_FS_IOMAP=y -CONFIG_FS_MBCACHE=y -CONFIG_FS_POSIX_ACL=y -CONFIG_GENERIC_ALLOCATOR=y -CONFIG_GENERIC_ARCH_TOPOLOGY=y -CONFIG_GENERIC_BUG=y -CONFIG_GENERIC_CLOCKEVENTS=y -CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y -CONFIG_GENERIC_CPU_AUTOPROBE=y -CONFIG_GENERIC_EARLY_IOREMAP=y -CONFIG_GENERIC_IDLE_POLL_SETUP=y -CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y -CONFIG_GENERIC_IRQ_MIGRATION=y -CONFIG_GENERIC_IRQ_MULTI_HANDLER=y -CONFIG_GENERIC_IRQ_SHOW=y -CONFIG_GENERIC_IRQ_SHOW_LEVEL=y -CONFIG_GENERIC_MSI_IRQ=y -CONFIG_GENERIC_MSI_IRQ_DOMAIN=y -CONFIG_GENERIC_PCI_IOMAP=y -CONFIG_GENERIC_PHY=y -CONFIG_GENERIC_PINCONF=y -CONFIG_GENERIC_PINCTRL_GROUPS=y -CONFIG_GENERIC_PINMUX_FUNCTIONS=y -CONFIG_GENERIC_SCHED_CLOCK=y -CONFIG_GENERIC_SMP_IDLE_THREAD=y -CONFIG_GENERIC_STRNCPY_FROM_USER=y -CONFIG_GENERIC_STRNLEN_USER=y -CONFIG_GENERIC_TIME_VSYSCALL=y -CONFIG_GPIOLIB=y -CONFIG_GPIOLIB_IRQCHIP=y -CONFIG_GPIO_BCM_VIRT=y -CONFIG_GPIO_RASPBERRYPI_EXP=y -CONFIG_GPIO_STMPE=y -CONFIG_GPIO_SYSFS=y -CONFIG_HANDLE_DOMAIN_IRQ=y -CONFIG_HARDEN_BRANCH_PREDICTOR=y -CONFIG_HARDIRQS_SW_RESEND=y -CONFIG_HAS_DMA=y -CONFIG_HAS_IOMEM=y -CONFIG_HAS_IOPORT_MAP=y -CONFIG_HAVE_ARCH_BITREVERSE=y -CONFIG_HAVE_ARCH_JUMP_LABEL=y -CONFIG_HAVE_ARCH_KGDB=y -CONFIG_HAVE_ARCH_PFN_VALID=y -CONFIG_HAVE_ARCH_THREAD_STRUCT_WHITELIST=y -CONFIG_HAVE_ARCH_TRACEHOOK=y -CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE=y -CONFIG_HAVE_ARM_ARCH_TIMER=y -CONFIG_HAVE_ARM_SMCCC=y -CONFIG_HAVE_CLK=y -CONFIG_HAVE_CLK_PREPARE=y -CONFIG_HAVE_CONTEXT_TRACKING=y -CONFIG_HAVE_C_RECORDMCOUNT=y -CONFIG_HAVE_DEBUG_KMEMLEAK=y -CONFIG_HAVE_DMA_CONTIGUOUS=y -CONFIG_HAVE_DYNAMIC_FTRACE=y -CONFIG_HAVE_DYNAMIC_FTRACE_WITH_REGS=y -CONFIG_HAVE_EBPF_JIT=y -CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y -CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y -CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y -CONFIG_HAVE_FUNCTION_TRACER=y -CONFIG_HAVE_GENERIC_DMA_COHERENT=y -CONFIG_HAVE_GENERIC_GUP=y -CONFIG_HAVE_IDE=y -CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y -CONFIG_HAVE_LD_DEAD_CODE_DATA_ELIMINATION=y -CONFIG_HAVE_MEMBLOCK=y -CONFIG_HAVE_MOD_ARCH_SPECIFIC=y -CONFIG_HAVE_NET_DSA=y -CONFIG_HAVE_OPROFILE=y -CONFIG_HAVE_OPTPROBES=y -CONFIG_HAVE_PERF_EVENTS=y -CONFIG_HAVE_PERF_REGS=y -CONFIG_HAVE_PERF_USER_STACK_DUMP=y -CONFIG_HAVE_PROC_CPU=y -CONFIG_HAVE_RCU_TABLE_FREE=y -CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y -CONFIG_HAVE_RSEQ=y -CONFIG_HAVE_SMP=y -CONFIG_HAVE_SYSCALL_TRACEPOINTS=y -CONFIG_HAVE_UID16=y -CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y -CONFIG_HIGHMEM=y -CONFIG_HIGHPTE=y -CONFIG_HOTPLUG_CPU=y -# CONFIG_HUGETLBFS is not set -CONFIG_HW_CONSOLE=y -CONFIG_HW_RANDOM=y -CONFIG_HW_RANDOM_BCM2835=y -CONFIG_HW_RANDOM_IPROC_RNG200=y -CONFIG_HZ_FIXED=0 -CONFIG_I2C=y -# CONFIG_I2C_BCM2708 is not set -CONFIG_I2C_BOARDINFO=y -CONFIG_I2C_COMPAT=y -CONFIG_I2C_HELPER_AUTO=y -CONFIG_IKCONFIG=y -CONFIG_IKCONFIG_PROC=y -CONFIG_INPUT=y -CONFIG_INPUT_MOUSEDEV=y -# CONFIG_INPUT_MOUSEDEV_PSAUX is not set -CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 -CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 -CONFIG_IOSCHED_CFQ=y -CONFIG_IRQCHIP=y -CONFIG_IRQ_DOMAIN=y -CONFIG_IRQ_DOMAIN_HIERARCHY=y -CONFIG_IRQ_FORCED_THREADING=y -CONFIG_IRQ_WORK=y -CONFIG_JBD2=y -CONFIG_KERNEL_GZIP=y -# CONFIG_KERNEL_XZ is not set -# CONFIG_LCD_CLASS_DEVICE is not set -CONFIG_LEDS_GPIO=y -CONFIG_LEDS_TRIGGER_INPUT=y -CONFIG_LIBFDT=y -CONFIG_LOCK_DEBUGGING_SUPPORT=y -CONFIG_LOCK_SPIN_ON_OWNER=y -CONFIG_LOGO=y -CONFIG_LOGO_LINUX_CLUT224=y -# CONFIG_LOGO_LINUX_MONO is not set -# CONFIG_LOGO_LINUX_VGA16 is not set -CONFIG_MAC_PARTITION=y -CONFIG_MAGIC_SYSRQ=y -CONFIG_MAILBOX=y -# CONFIG_MAILBOX_TEST is not set -CONFIG_MAX_RAW_DEVS=256 -CONFIG_MD=y -CONFIG_MDIO_BCM_UNIMAC=y -CONFIG_MDIO_BUS=y -CONFIG_MDIO_DEVICE=y -CONFIG_MEMFD_CREATE=y -CONFIG_MEMORY_ISOLATION=y -CONFIG_MFD_CORE=y -# CONFIG_MFD_RPISENSE_CORE is not set -CONFIG_MFD_STMPE=y -CONFIG_MFD_SYSCON=y -CONFIG_MICROCHIP_PHY=y -CONFIG_MIGHT_HAVE_CACHE_L2X0=y -CONFIG_MIGHT_HAVE_PCI=y -CONFIG_MIGRATION=y -CONFIG_MMC=y -CONFIG_MMC_BCM2835=y -CONFIG_MMC_BCM2835_DMA=y -CONFIG_MMC_BCM2835_MMC=y -CONFIG_MMC_BCM2835_PIO_DMA_BARRIER=2 -CONFIG_MMC_BCM2835_SDHOST=y -CONFIG_MMC_BLOCK=y -CONFIG_MMC_BLOCK_MINORS=32 -CONFIG_MMC_SDHCI=y -CONFIG_MMC_SDHCI_IO_ACCESSORS=y -CONFIG_MMC_SDHCI_IPROC=y -# CONFIG_MMC_SDHCI_PCI is not set -CONFIG_MMC_SDHCI_PLTFM=y -# CONFIG_MMC_TIFM_SD is not set -CONFIG_MODULES_USE_ELF_REL=y -CONFIG_MUTEX_SPIN_ON_OWNER=y -CONFIG_NEED_DMA_MAP_STATE=y -CONFIG_NEON=y -CONFIG_NET_FLOW_LIMIT=y -CONFIG_NLS=y -CONFIG_NLS_ASCII=y -CONFIG_NLS_DEFAULT="utf8" -CONFIG_NO_BOOTMEM=y -CONFIG_NO_HZ=y -CONFIG_NO_HZ_COMMON=y -CONFIG_NO_HZ_IDLE=y -CONFIG_NR_CPUS=4 -CONFIG_NVMEM=y -CONFIG_OABI_COMPAT=y -CONFIG_OF=y -CONFIG_OF_ADDRESS=y -CONFIG_OF_CONFIGFS=y -CONFIG_OF_DYNAMIC=y -CONFIG_OF_EARLY_FLATTREE=y -CONFIG_OF_FLATTREE=y -CONFIG_OF_GPIO=y -CONFIG_OF_IRQ=y -CONFIG_OF_KOBJ=y -CONFIG_OF_MDIO=y -CONFIG_OF_NET=y -CONFIG_OF_OVERLAY=y -CONFIG_OF_RESERVED_MEM=y -CONFIG_OF_RESOLVE=y -CONFIG_OLD_SIGACTION=y -CONFIG_OLD_SIGSUSPEND3=y -CONFIG_OUTER_CACHE=y -CONFIG_OUTER_CACHE_SYNC=y -CONFIG_PADATA=y -CONFIG_PAGE_OFFSET=0xC0000000 -CONFIG_PCI=y -CONFIG_PCIEAER=y -CONFIG_PCIEPORTBUS=y -CONFIG_PCIE_BRCMSTB=y -CONFIG_PCIE_PME=y -CONFIG_PCI_DOMAINS=y -CONFIG_PCI_DOMAINS_GENERIC=y -CONFIG_PCI_MSI=y -CONFIG_PCI_MSI_IRQ_DOMAIN=y -# CONFIG_PCI_V3_SEMI is not set -CONFIG_PERF_USE_VMALLOC=y -CONFIG_PGTABLE_LEVELS=3 -CONFIG_PHYLIB=y -CONFIG_PHYS_ADDR_T_64BIT=y -CONFIG_PINCTRL=y -CONFIG_PINCTRL_BCM2835=y -# 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_PLUGIN_HOSTCC="g++" -CONFIG_PM=y -CONFIG_PM_CLK=y -# CONFIG_PM_DEBUG is not set -CONFIG_PM_GENERIC_DOMAINS=y -CONFIG_PM_GENERIC_DOMAINS_OF=y -CONFIG_PM_GENERIC_DOMAINS_SLEEP=y -CONFIG_PM_SLEEP=y -CONFIG_PM_SLEEP_SMP=y -CONFIG_POWER_RESET=y -CONFIG_POWER_RESET_GPIO=y -CONFIG_POWER_SUPPLY=y -CONFIG_PRINTK_TIME=y -CONFIG_PROC_PAGE_MONITOR=y -CONFIG_PWM=y -CONFIG_PWM_BCM2835=y -# CONFIG_PWM_STMPE is not set -CONFIG_PWM_SYSFS=y -CONFIG_RAS=y -CONFIG_RASPBERRYPI_FIRMWARE=y -CONFIG_RASPBERRYPI_POWER=y -CONFIG_RATIONAL=y -CONFIG_RAW_DRIVER=y -CONFIG_RCU_NEED_SEGCBLIST=y -CONFIG_RCU_STALL_COMMON=y -CONFIG_REFCOUNT_FULL=y -CONFIG_REGMAP=y -CONFIG_REGMAP_MMIO=y -CONFIG_REGULATOR=y -CONFIG_REGULATOR_FIXED_VOLTAGE=y -CONFIG_REGULATOR_GPIO=y -CONFIG_RESET_CONTROLLER=y -CONFIG_RFS_ACCEL=y -# CONFIG_RPIVID_MEM is not set -CONFIG_RPS=y -CONFIG_RWSEM_SPIN_ON_OWNER=y -CONFIG_RWSEM_XCHGADD_ALGORITHM=y -CONFIG_SCSI=y -CONFIG_SCSI_ISCSI_ATTRS=y -CONFIG_SCSI_MQ_DEFAULT=y -# CONFIG_SCSI_PROC_FS is not set -CONFIG_SERIAL_8250_BCM2835AUX=y -# CONFIG_SERIAL_8250_DMA is not set -CONFIG_SERIAL_8250_EXTENDED=y -CONFIG_SERIAL_8250_FSL=y -CONFIG_SERIAL_8250_NR_UARTS=1 -CONFIG_SERIAL_8250_RUNTIME_UARTS=0 -CONFIG_SERIAL_8250_SHARE_IRQ=y -CONFIG_SERIAL_AMBA_PL011=y -CONFIG_SERIAL_AMBA_PL011_CONSOLE=y -CONFIG_SERIAL_DEV_BUS=y -# CONFIG_SERIAL_DEV_CTRL_TTYPORT is not set -CONFIG_SERIAL_OF_PLATFORM=y -CONFIG_SG_POOL=y -CONFIG_SMP=y -CONFIG_SMP_ON_UP=y -CONFIG_SPARSE_IRQ=y -CONFIG_SPI=y -# CONFIG_SPI_BCM2835AUX is not set -CONFIG_SPI_MASTER=y -CONFIG_SPI_MEM=y -CONFIG_SPI_SLAVE=y -# CONFIG_SPI_SLAVE_SYSTEM_CONTROL is not set -# CONFIG_SPI_SLAVE_TIME is not set -CONFIG_SRCU=y -CONFIG_STMPE_I2C=y -CONFIG_STMPE_SPI=y -CONFIG_STREAM_PARSER=y -# CONFIG_STRIP_ASM_SYMS is not set -CONFIG_SUSPEND=y -CONFIG_SUSPEND_FREEZER=y -CONFIG_SWPHY=y -CONFIG_SWP_EMULATE=y -CONFIG_SYS_SUPPORTS_APM_EMULATION=y -CONFIG_SYS_SUPPORTS_HUGETLBFS=y -# CONFIG_TEXTSEARCH is not set -CONFIG_THERMAL=y -CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y -CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=0 -CONFIG_THERMAL_GOV_STEP_WISE=y -CONFIG_THERMAL_OF=y -# CONFIG_THUMB2_KERNEL is not set -CONFIG_TICK_CPU_ACCOUNTING=y -CONFIG_TIMER_OF=y -CONFIG_TIMER_PROBE=y -CONFIG_TMPFS_POSIX_ACL=y -CONFIG_TREE_RCU=y -CONFIG_TREE_SRCU=y -CONFIG_TTY_PRINTK=y -CONFIG_UEVENT_HELPER_PATH="" -# CONFIG_UID16 is not set -CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h" -CONFIG_USB=y -CONFIG_USB_PCI=y -CONFIG_USB_ANNOUNCE_NEW_DEVICES=y -CONFIG_USB_COMMON=y -CONFIG_USB_DWCOTG=y -# CONFIG_USB_EHCI_HCD is not set -CONFIG_USB_LAN78XX=y -CONFIG_USB_NET_DRIVERS=y -CONFIG_USB_NET_SMSC95XX=y -CONFIG_USB_STORAGE=y -CONFIG_USB_SUPPORT=y -CONFIG_USB_UAS=y -CONFIG_USB_USBNET=y -CONFIG_USB_XHCI_HCD=y -CONFIG_USB_XHCI_PCI=y -CONFIG_USB_XHCI_PLATFORM=y -CONFIG_USE_OF=y -CONFIG_VDSO=y -CONFIG_VFP=y -CONFIG_VFPv3=y -CONFIG_VT=y -CONFIG_VT_CONSOLE=y -CONFIG_VT_CONSOLE_SLEEP=y -CONFIG_VT_HW_CONSOLE_BINDING=y -CONFIG_WATCHDOG_CORE=y -CONFIG_XPS=y -CONFIG_XZ_DEC_ARM=y -CONFIG_XZ_DEC_BCJ=y -CONFIG_ZBOOT_ROM_BSS=0 -CONFIG_ZBOOT_ROM_TEXT=0 diff --git a/root/target/linux/bcm27xx/bcm2710/config-4.14 b/root/target/linux/bcm27xx/bcm2710/config-4.14 deleted file mode 100644 index f9efa9fe..00000000 --- a/root/target/linux/bcm27xx/bcm2710/config-4.14 +++ /dev/null @@ -1,492 +0,0 @@ -CONFIG_64BIT=y -# CONFIG_AIO is not set -CONFIG_ARCH_BCM2835=y -CONFIG_ARCH_CLOCKSOURCE_DATA=y -CONFIG_ARCH_DMA_ADDR_T_64BIT=y -CONFIG_ARCH_HAS_CACHE_LINE_SIZE=y -CONFIG_ARCH_HAS_DEBUG_VIRTUAL=y -CONFIG_ARCH_HAS_ELF_RANDOMIZE=y -CONFIG_ARCH_HAS_FORTIFY_SOURCE=y -CONFIG_ARCH_HAS_GCOV_PROFILE_ALL=y -CONFIG_ARCH_HAS_GIGANTIC_PAGE=y -CONFIG_ARCH_HAS_HOLES_MEMORYMODEL=y -CONFIG_ARCH_HAS_KCOV=y -CONFIG_ARCH_HAS_SET_MEMORY=y -CONFIG_ARCH_HAS_SG_CHAIN=y -CONFIG_ARCH_HAS_STRICT_KERNEL_RWX=y -CONFIG_ARCH_HAS_STRICT_MODULE_RWX=y -CONFIG_ARCH_HAS_TICK_BROADCAST=y -CONFIG_ARCH_HIBERNATION_POSSIBLE=y -CONFIG_ARCH_MMAP_RND_BITS=18 -CONFIG_ARCH_MMAP_RND_BITS_MAX=24 -CONFIG_ARCH_MMAP_RND_BITS_MIN=18 -CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN=11 -# CONFIG_ARCH_OPTIONAL_KERNEL_RWX is not set -# CONFIG_ARCH_OPTIONAL_KERNEL_RWX_DEFAULT is not set -CONFIG_ARCH_PHYS_ADDR_T_64BIT=y -CONFIG_ARCH_PROC_KCORE_TEXT=y -CONFIG_ARCH_SELECT_MEMORY_MODEL=y -CONFIG_ARCH_SPARSEMEM_DEFAULT=y -CONFIG_ARCH_SPARSEMEM_ENABLE=y -CONFIG_ARCH_SUPPORTS_ATOMIC_RMW=y -CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y -CONFIG_ARCH_SUPPORTS_MEMORY_FAILURE=y -CONFIG_ARCH_SUPPORTS_NUMA_BALANCING=y -CONFIG_ARCH_SUPPORTS_UPROBES=y -CONFIG_ARCH_SUSPEND_POSSIBLE=y -CONFIG_ARCH_USE_CMPXCHG_LOCKREF=y -# CONFIG_ARCH_WANTS_THP_SWAP is not set -CONFIG_ARCH_WANT_COMPAT_IPC_PARSE_VERSION=y -CONFIG_ARCH_WANT_FRAME_POINTERS=y -CONFIG_ARCH_WANT_HUGE_PMD_SHARE=y -CONFIG_ARM64=y -# CONFIG_ARM64_16K_PAGES is not set -CONFIG_ARM64_4K_PAGES=y -# CONFIG_ARM64_64K_PAGES is not set -CONFIG_ARM64_CONT_SHIFT=4 -# CONFIG_ARM64_CRYPTO is not set -CONFIG_ARM64_ERRATUM_819472=y -CONFIG_ARM64_ERRATUM_824069=y -CONFIG_ARM64_ERRATUM_826319=y -CONFIG_ARM64_ERRATUM_827319=y -CONFIG_ARM64_ERRATUM_832075=y -CONFIG_ARM64_ERRATUM_843419=y -CONFIG_ARM64_ERRATUM_1024718=y -CONFIG_ARM64_HW_AFDBM=y -# CONFIG_ARM64_LSE_ATOMICS is not set -CONFIG_ARM64_MODULE_CMODEL_LARGE=y -CONFIG_ARM64_PAGE_SHIFT=12 -CONFIG_ARM64_PAN=y -# CONFIG_ARM64_PMEM is not set -# CONFIG_ARM64_PTDUMP_CORE is not set -# CONFIG_ARM64_PTDUMP_DEBUGFS is not set -# CONFIG_ARM64_RANDOMIZE_TEXT_OFFSET is not set -# CONFIG_ARM64_SW_TTBR0_PAN is not set -CONFIG_ARM64_UAO=y -CONFIG_ARM64_VA_BITS=39 -CONFIG_ARM64_VA_BITS_39=y -# CONFIG_ARM64_VA_BITS_48 is not set -CONFIG_ARM64_VHE=y -CONFIG_ARM64_SSBD=y -CONFIG_ARM_AMBA=y -CONFIG_ARM_ARCH_TIMER=y -CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y -CONFIG_ARM_ARCH_TIMER_OOL_WORKAROUND=y -CONFIG_ARM_BCM2835_CPUFREQ=y -CONFIG_ARM_GIC=y -CONFIG_ARM_GIC_V3=y -CONFIG_ARM_PSCI_FW=y -# CONFIG_ARM_SP805_WATCHDOG is not set -CONFIG_ARM_TIMER_SP804=y -CONFIG_AUDIT_ARCH_COMPAT_GENERIC=y -# CONFIG_BACKLIGHT_CLASS_DEVICE is not set -CONFIG_BACKLIGHT_LCD_SUPPORT=y -CONFIG_BCM2708_VCMEM=y -# CONFIG_BCM2835_DEVGPIOMEM is not set -CONFIG_BCM2835_MBOX=y -# CONFIG_BCM2835_SMI is not set -CONFIG_BCM2835_THERMAL=y -CONFIG_BCM2835_VCHIQ=y -# CONFIG_BCM2835_VCHIQ_SUPPORT_MEMDUMP is not set -CONFIG_BCM2835_WDT=y -# CONFIG_BCM_FLEXRM_MBOX is not set -# CONFIG_BCM_VCIO is not set -# CONFIG_BCM_VC_SM is not set -CONFIG_BCM_VIDEOCORE=y -# CONFIG_BLK_DEV_INITRD is not set -CONFIG_BLK_DEV_LOOP=y -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_COUNT=16 -CONFIG_BLK_DEV_RAM_SIZE=4096 -CONFIG_BLK_DEV_SD=y -CONFIG_BLK_SCSI_REQUEST=y -CONFIG_BOUNCE=y -CONFIG_BRCM_CHAR_DRIVERS=y -CONFIG_BUILD_BIN2C=y -CONFIG_CAVIUM_ERRATUM_22375=y -CONFIG_CAVIUM_ERRATUM_23154=y -CONFIG_CAVIUM_ERRATUM_27456=y -CONFIG_CLKDEV_LOOKUP=y -CONFIG_CLKSRC_MMIO=y -CONFIG_CLONE_BACKWARDS=y -CONFIG_CMA=y -CONFIG_CMA_ALIGNMENT=8 -CONFIG_CMA_AREAS=7 -# CONFIG_CMA_DEBUG is not set -# CONFIG_CMA_DEBUGFS is not set -CONFIG_CMA_SIZE_MBYTES=16 -# CONFIG_CMA_SIZE_SEL_MAX is not set -CONFIG_CMA_SIZE_SEL_MBYTES=y -# CONFIG_CMA_SIZE_SEL_MIN is not set -# CONFIG_CMA_SIZE_SEL_PERCENTAGE is not set -CONFIG_COMMON_CLK=y -# CONFIG_COMMON_CLK_VERSATILE is not set -CONFIG_COMMON_CLK_XGENE=y -# CONFIG_COMPAT is not set -CONFIG_CONFIGFS_FS=y -CONFIG_CONSOLE_TRANSLATIONS=y -# CONFIG_CPUFREQ_DT is not set -# CONFIG_CPU_BIG_ENDIAN is not set -CONFIG_CPU_FREQ=y -# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set -CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y -CONFIG_CPU_FREQ_GOV_ATTR_SET=y -CONFIG_CPU_FREQ_GOV_COMMON=y -CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y -CONFIG_CPU_FREQ_GOV_ONDEMAND=y -CONFIG_CPU_FREQ_GOV_PERFORMANCE=y -CONFIG_CPU_FREQ_GOV_POWERSAVE=y -CONFIG_CPU_FREQ_GOV_USERSPACE=y -CONFIG_CPU_FREQ_STAT=y -# CONFIG_CPU_HOTPLUG_STATE_CONTROL is not set -CONFIG_CPU_IDLE=y -CONFIG_CPU_IDLE_GOV_LADDER=y -CONFIG_CPU_IDLE_GOV_MENU=y -CONFIG_CPU_PM=y -CONFIG_CPU_RMAP=y -# CONFIG_CPU_THERMAL is not set -CONFIG_CRC16=y -CONFIG_CRYPTO_AEAD=y -CONFIG_CRYPTO_AEAD2=y -CONFIG_CRYPTO_CRC32=y -CONFIG_CRYPTO_CRC32C=y -CONFIG_CRYPTO_HASH=y -CONFIG_CRYPTO_HASH2=y -CONFIG_CRYPTO_MANAGER=y -CONFIG_CRYPTO_MANAGER2=y -CONFIG_CRYPTO_NULL2=y -CONFIG_CRYPTO_RNG2=y -CONFIG_CRYPTO_WORKQUEUE=y -CONFIG_DCACHE_WORD_ACCESS=y -CONFIG_DEBUG_BUGVERBOSE=y -CONFIG_DEBUG_INFO=y -CONFIG_DEFAULT_DUMMY=y -CONFIG_DEFAULT_SCHEDULER=y -CONFIG_DMADEVICES=y -CONFIG_DMA_BCM2708=y -CONFIG_DMA_BCM2835=y -CONFIG_DMA_CMA=y -CONFIG_DMA_ENGINE=y -# CONFIG_DMA_NOOP_OPS is not set -CONFIG_DMA_OF=y -CONFIG_DMA_VIRTUAL_CHANNELS=y -# CONFIG_DMA_VIRT_OPS is not set -CONFIG_DNOTIFY=y -# CONFIG_DRM_LIB_RANDOM is not set -CONFIG_DTC=y -CONFIG_DUMMY_CONSOLE=y -CONFIG_EDAC_SUPPORT=y -CONFIG_ENABLE_MUST_CHECK=y -CONFIG_EXPORTFS=y -CONFIG_EXT4_FS=y -CONFIG_EXT4_FS_POSIX_ACL=y -CONFIG_EXT4_FS_SECURITY=y -# CONFIG_F2FS_CHECK_FS is not set -CONFIG_F2FS_FS=y -# CONFIG_F2FS_FS_SECURITY is not set -CONFIG_F2FS_FS_XATTR=y -CONFIG_F2FS_STAT_FS=y -CONFIG_FB=y -CONFIG_FB_BCM2708=y -CONFIG_FB_CFB_COPYAREA=y -CONFIG_FB_CFB_FILLRECT=y -CONFIG_FB_CFB_IMAGEBLIT=y -CONFIG_FB_CMDLINE=y -# CONFIG_FB_PROVIDE_GET_FB_UNMAPPED_AREA is not set -# CONFIG_FB_RPISENSE is not set -CONFIG_FIRMWARE_IN_KERNEL=y -CONFIG_FIXED_PHY=y -CONFIG_FIX_EARLYCON_MEM=y -# CONFIG_FONTS is not set -CONFIG_FONT_8x16=y -CONFIG_FONT_8x8=y -CONFIG_FONT_SUPPORT=y -CONFIG_FRAMEBUFFER_CONSOLE=y -# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set -# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set -CONFIG_FRAME_POINTER=y -CONFIG_FREEZER=y -CONFIG_FSL_ERRATUM_A008585=y -CONFIG_FS_MBCACHE=y -CONFIG_FS_POSIX_ACL=y -CONFIG_FUTEX_PI=y -CONFIG_GENERIC_ALLOCATOR=y -CONFIG_GENERIC_ARCH_TOPOLOGY=y -CONFIG_GENERIC_BUG=y -CONFIG_GENERIC_BUG_RELATIVE_POINTERS=y -CONFIG_GENERIC_CLOCKEVENTS=y -CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y -CONFIG_GENERIC_CPU_AUTOPROBE=y -CONFIG_GENERIC_CSUM=y -CONFIG_GENERIC_EARLY_IOREMAP=y -CONFIG_GENERIC_IDLE_POLL_SETUP=y -CONFIG_GENERIC_IO=y -CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y -CONFIG_GENERIC_IRQ_MIGRATION=y -CONFIG_GENERIC_IRQ_SHOW=y -CONFIG_GENERIC_IRQ_SHOW_LEVEL=y -CONFIG_GENERIC_PCI_IOMAP=y -CONFIG_GENERIC_PINCONF=y -CONFIG_GENERIC_PINCTRL_GROUPS=y -CONFIG_GENERIC_PINMUX_FUNCTIONS=y -CONFIG_GENERIC_SCHED_CLOCK=y -CONFIG_GENERIC_SMP_IDLE_THREAD=y -CONFIG_GENERIC_STRNCPY_FROM_USER=y -CONFIG_GENERIC_STRNLEN_USER=y -CONFIG_GENERIC_TIME_VSYSCALL=y -CONFIG_GPIOLIB=y -CONFIG_GPIOLIB_IRQCHIP=y -CONFIG_GPIO_BCM_EXP=y -CONFIG_GPIO_BCM_VIRT=y -CONFIG_GPIO_SYSFS=y -# CONFIG_GRO_CELLS is not set -CONFIG_HANDLE_DOMAIN_IRQ=y -CONFIG_HARDIRQS_SW_RESEND=y -CONFIG_HAS_DMA=y -CONFIG_HAS_IOMEM=y -# CONFIG_HAVE_64BIT_ALIGNED_ACCESS is not set -CONFIG_HAVE_ALIGNED_STRUCT_PAGE=y -CONFIG_HAVE_ARCH_AUDITSYSCALL=y -CONFIG_HAVE_ARCH_BITREVERSE=y -CONFIG_HAVE_ARCH_HUGE_VMAP=y -CONFIG_HAVE_ARCH_JUMP_LABEL=y -CONFIG_HAVE_ARCH_KASAN=y -CONFIG_HAVE_ARCH_KGDB=y -CONFIG_HAVE_ARCH_PFN_VALID=y -CONFIG_HAVE_ARCH_SECCOMP_FILTER=y -CONFIG_HAVE_ARCH_TRACEHOOK=y -CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE=y -CONFIG_HAVE_ARCH_VMAP_STACK=y -CONFIG_HAVE_ARM_SMCCC=y -# CONFIG_HAVE_BOOTMEM_INFO_NODE is not set -CONFIG_HAVE_CC_STACKPROTECTOR=y -CONFIG_HAVE_CLK=y -CONFIG_HAVE_CLK_PREPARE=y -CONFIG_HAVE_CMPXCHG_DOUBLE=y -CONFIG_HAVE_CMPXCHG_LOCAL=y -CONFIG_HAVE_CONTEXT_TRACKING=y -CONFIG_HAVE_C_RECORDMCOUNT=y -CONFIG_HAVE_DEBUG_BUGVERBOSE=y -CONFIG_HAVE_DEBUG_KMEMLEAK=y -CONFIG_HAVE_DMA_API_DEBUG=y -CONFIG_HAVE_DMA_CONTIGUOUS=y -CONFIG_HAVE_DYNAMIC_FTRACE=y -CONFIG_HAVE_EBPF_JIT=y -CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y -CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y -CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y -CONFIG_HAVE_FUNCTION_TRACER=y -CONFIG_HAVE_GENERIC_DMA_COHERENT=y -CONFIG_HAVE_GENERIC_GUP=y -CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y -CONFIG_HAVE_MEMBLOCK=y -CONFIG_HAVE_MEMORY_PRESENT=y -CONFIG_HAVE_NET_DSA=y -CONFIG_HAVE_PATA_PLATFORM=y -CONFIG_HAVE_PERF_EVENTS=y -CONFIG_HAVE_PERF_REGS=y -CONFIG_HAVE_PERF_USER_STACK_DUMP=y -CONFIG_HAVE_RCU_TABLE_FREE=y -CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y -CONFIG_HAVE_SYSCALL_TRACEPOINTS=y -CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y -CONFIG_HOLES_IN_ZONE=y -CONFIG_HOTPLUG_CPU=y -# CONFIG_HUGETLBFS is not set -CONFIG_HW_CONSOLE=y -CONFIG_IKCONFIG=y -CONFIG_IKCONFIG_PROC=y -CONFIG_ILLEGAL_POINTER_VALUE=0xdead000000000000 -CONFIG_INPUT=y -CONFIG_INPUT_MOUSEDEV=y -# CONFIG_INPUT_MOUSEDEV_PSAUX is not set -CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 -CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 -CONFIG_IOMMU_HELPER=y -CONFIG_IOSCHED_CFQ=y -CONFIG_IRQCHIP=y -CONFIG_IRQ_DOMAIN=y -CONFIG_IRQ_DOMAIN_HIERARCHY=y -CONFIG_IRQ_FORCED_THREADING=y -CONFIG_IRQ_WORK=y -CONFIG_JBD2=y -# CONFIG_LCD_CLASS_DEVICE is not set -CONFIG_LEDS_GPIO=y -CONFIG_LEDS_TRIGGER_INPUT=y -CONFIG_LIBFDT=y -CONFIG_LOCK_SPIN_ON_OWNER=y -CONFIG_LOGO=y -CONFIG_LOGO_LINUX_CLUT224=y -# CONFIG_LOGO_LINUX_MONO is not set -# CONFIG_LOGO_LINUX_VGA16 is not set -CONFIG_MAC_PARTITION=y -CONFIG_MAGIC_SYSRQ=y -CONFIG_MAILBOX=y -# CONFIG_MAILBOX_TEST is not set -CONFIG_MAX_RAW_DEVS=256 -CONFIG_MDIO_BUS=y -CONFIG_MDIO_DEVICE=y -CONFIG_MEMORY_ISOLATION=y -CONFIG_MFD_SYSCON=y -CONFIG_MICROCHIP_PHY=y -CONFIG_MIGRATION=y -CONFIG_MMC=y -CONFIG_MMC_BCM2835=y -CONFIG_MMC_BCM2835_DMA=y -CONFIG_MMC_BCM2835_MMC=y -CONFIG_MMC_BCM2835_PIO_DMA_BARRIER=2 -CONFIG_MMC_BCM2835_SDHOST=y -CONFIG_MMC_BLOCK=y -CONFIG_MMC_BLOCK_MINORS=32 -CONFIG_MMC_SDHCI=y -CONFIG_MMC_SDHCI_PLTFM=y -CONFIG_MODULES_USE_ELF_RELA=y -# CONFIG_MTD is not set -CONFIG_MUTEX_SPIN_ON_OWNER=y -CONFIG_NEED_DMA_MAP_STATE=y -CONFIG_NEED_SG_DMA_LENGTH=y -CONFIG_NET_FLOW_LIMIT=y -CONFIG_NLS=y -CONFIG_NLS_ASCII=y -CONFIG_NLS_DEFAULT="utf8" -CONFIG_NO_BOOTMEM=y -CONFIG_NO_HZ=y -CONFIG_NO_HZ_COMMON=y -CONFIG_NO_HZ_IDLE=y -CONFIG_NO_IOPORT_MAP=y -CONFIG_NR_CPUS=4 -# CONFIG_NUMA is not set -CONFIG_OF=y -CONFIG_OF_ADDRESS=y -CONFIG_OF_CONFIGFS=y -CONFIG_OF_DYNAMIC=y -CONFIG_OF_EARLY_FLATTREE=y -CONFIG_OF_FLATTREE=y -CONFIG_OF_GPIO=y -CONFIG_OF_MDIO=y -CONFIG_OF_IRQ=y -CONFIG_OF_NET=y -CONFIG_OF_OVERLAY=y -CONFIG_OF_RESERVED_MEM=y -CONFIG_OF_RESOLVE=y -CONFIG_PADATA=y -CONFIG_PARTITION_PERCPU=y -# CONFIG_PCI_DOMAINS is not set -# CONFIG_PCI_DOMAINS_GENERIC is not set -# CONFIG_PCI_SYSCALL is not set -CONFIG_PGTABLE_LEVELS=3 -CONFIG_PHYLIB=y -CONFIG_PHYS_ADDR_T_64BIT=y -# CONFIG_PHY_XGENE is not set -CONFIG_PINCTRL=y -CONFIG_PINCTRL_BCM2835=y -CONFIG_PM=y -CONFIG_PM_CLK=y -# CONFIG_PM_DEBUG is not set -CONFIG_PM_GENERIC_DOMAINS=y -CONFIG_PM_GENERIC_DOMAINS_OF=y -CONFIG_PM_GENERIC_DOMAINS_SLEEP=y -CONFIG_PM_SLEEP=y -CONFIG_PM_SLEEP_SMP=y -CONFIG_POWER_RESET=y -CONFIG_POWER_SUPPLY=y -CONFIG_PRINTK_TIME=y -CONFIG_PROC_PAGE_MONITOR=y -CONFIG_PWM=y -CONFIG_PWM_BCM2835=y -CONFIG_PWM_SYSFS=y -# CONFIG_RANDOMIZE_BASE is not set -CONFIG_RASPBERRYPI_FIRMWARE=y -CONFIG_RASPBERRYPI_POWER=y -CONFIG_RATIONAL=y -CONFIG_RAW_DRIVER=y -CONFIG_RCU_NEED_SEGCBLIST=y -CONFIG_RCU_STALL_COMMON=y -CONFIG_REGMAP=y -CONFIG_REGMAP_MMIO=y -CONFIG_REGULATOR=y -CONFIG_REGULATOR_FIXED_VOLTAGE=y -CONFIG_RFS_ACCEL=y -CONFIG_RPS=y -CONFIG_RWSEM_SPIN_ON_OWNER=y -CONFIG_RWSEM_XCHGADD_ALGORITHM=y -# CONFIG_SCHED_INFO is not set -CONFIG_SCSI=y -# CONFIG_SCSI_LOWLEVEL is not set -# CONFIG_SCSI_PROC_FS is not set -CONFIG_SERIAL_8250_BCM2835AUX=y -# CONFIG_SERIAL_8250_DMA is not set -CONFIG_SERIAL_8250_EXTENDED=y -CONFIG_SERIAL_8250_FSL=y -CONFIG_SERIAL_8250_NR_UARTS=1 -CONFIG_SERIAL_8250_RUNTIME_UARTS=0 -CONFIG_SERIAL_8250_SHARE_IRQ=y -CONFIG_SERIAL_AMBA_PL011=y -CONFIG_SERIAL_AMBA_PL011_CONSOLE=y -CONFIG_SERIAL_OF_PLATFORM=y -CONFIG_SG_POOL=y -CONFIG_SMP=y -CONFIG_SPARSEMEM=y -CONFIG_SPARSEMEM_EXTREME=y -CONFIG_SPARSEMEM_MANUAL=y -CONFIG_SPARSEMEM_VMEMMAP=y -CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y -CONFIG_SPARSE_IRQ=y -CONFIG_SRCU=y -# CONFIG_STRIP_ASM_SYMS is not set -CONFIG_SUSPEND=y -CONFIG_SUSPEND_FREEZER=y -CONFIG_SWIOTLB=y -CONFIG_SWPHY=y -CONFIG_SYSCTL_EXCEPTION_TRACE=y -CONFIG_SYS_SUPPORTS_HUGETLBFS=y -# CONFIG_TEXTSEARCH is not set -CONFIG_THERMAL=y -CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y -CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=0 -CONFIG_THERMAL_GOV_STEP_WISE=y -CONFIG_THERMAL_OF=y -CONFIG_THIN_ARCHIVES=y -CONFIG_THREAD_INFO_IN_TASK=y -CONFIG_TICK_CPU_ACCOUNTING=y -CONFIG_TIMER_OF=y -CONFIG_TIMER_PROBE=y -CONFIG_TMPFS_POSIX_ACL=y -CONFIG_TREE_RCU=y -CONFIG_TREE_SRCU=y -CONFIG_UEVENT_HELPER_PATH="" -CONFIG_USB=y -CONFIG_USB_ANNOUNCE_NEW_DEVICES=y -CONFIG_USB_COMMON=y -CONFIG_USB_DWCOTG=y -CONFIG_USB_LAN78XX=y -# CONFIG_USB_EHCI_HCD is not set -CONFIG_USB_NET_DRIVERS=y -CONFIG_USB_NET_SMSC95XX=y -CONFIG_USB_STORAGE=y -CONFIG_USB_SUPPORT=y -CONFIG_USB_UAS=y -CONFIG_USB_USBNET=y -CONFIG_VMAP_STACK=y -CONFIG_VT=y -CONFIG_VT_CONSOLE=y -CONFIG_VT_CONSOLE_SLEEP=y -CONFIG_VT_HW_CONSOLE_BINDING=y -CONFIG_WATCHDOG_CORE=y -CONFIG_XPS=y -CONFIG_XZ_DEC_ARM=y -CONFIG_XZ_DEC_BCJ=y -CONFIG_MFD_RPISENSE_CORE=n -CONFIG_DRM_PANEL_LVDS=n -CONFIG_DRM_PANEL_INNOLUX_P079ZCA=n -CONFIG_DRM_PANEL_SAMSUNG_S6E3HA2=n -CONFIG_DRM_PANEL_SITRONIX_ST7789V=n -CONFIG_DRM_VC4_HDMI_CEC=n -CONFIG_SND_BCM2708_SOC_GOOGLEVOICEHAT_SOUNDCARD=n -CONFIG_SND_BCM2708_SOC_RPI_CIRRUS=n -CONFIG_SND_AUDIOINJECTOR_OCTO_SOUNDCARD=n -CONFIG_SND_BCM2708_SOC_ALLO_PIANO_DAC_PLUS=n -CONFIG_SND_BCM2708_SOC_ALLO_BOSS_DAC=n -CONFIG_SND_BCM2708_SOC_ALLO_DIGIONE=n -CONFIG_SND_BCM2708_SOC_ALLO_KATANA_DAC=n -CONFIG_SND_SOC_ICS43432=n diff --git a/root/target/linux/bcm27xx/bcm2710/config-4.19 b/root/target/linux/bcm27xx/bcm2710/config-4.19 deleted file mode 100644 index f8592d40..00000000 --- a/root/target/linux/bcm27xx/bcm2710/config-4.19 +++ /dev/null @@ -1,545 +0,0 @@ -CONFIG_64BIT=y -# CONFIG_AIO is not set -CONFIG_ARCH_BCM2835=y -CONFIG_ARCH_CLOCKSOURCE_DATA=y -CONFIG_ARCH_DMA_ADDR_T_64BIT=y -CONFIG_ARCH_HAS_CACHE_LINE_SIZE=y -CONFIG_ARCH_HAS_DEBUG_VIRTUAL=y -CONFIG_ARCH_HAS_ELF_RANDOMIZE=y -CONFIG_ARCH_HAS_FAST_MULTIPLIER=y -CONFIG_ARCH_HAS_FORTIFY_SOURCE=y -CONFIG_ARCH_HAS_GCOV_PROFILE_ALL=y -CONFIG_ARCH_HAS_GIGANTIC_PAGE=y -CONFIG_ARCH_HAS_HOLES_MEMORYMODEL=y -CONFIG_ARCH_HAS_KCOV=y -CONFIG_ARCH_HAS_MEMBARRIER_SYNC_CORE=y -CONFIG_ARCH_HAS_PTE_SPECIAL=y -CONFIG_ARCH_HAS_SET_MEMORY=y -CONFIG_ARCH_HAS_SG_CHAIN=y -CONFIG_ARCH_HAS_STRICT_KERNEL_RWX=y -CONFIG_ARCH_HAS_STRICT_MODULE_RWX=y -CONFIG_ARCH_HAS_SYSCALL_WRAPPER=y -CONFIG_ARCH_HAS_TICK_BROADCAST=y -CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG=y -CONFIG_ARCH_HIBERNATION_POSSIBLE=y -CONFIG_ARCH_INLINE_READ_LOCK=y -CONFIG_ARCH_INLINE_READ_LOCK_BH=y -CONFIG_ARCH_INLINE_READ_LOCK_IRQ=y -CONFIG_ARCH_INLINE_READ_LOCK_IRQSAVE=y -CONFIG_ARCH_INLINE_READ_UNLOCK=y -CONFIG_ARCH_INLINE_READ_UNLOCK_BH=y -CONFIG_ARCH_INLINE_READ_UNLOCK_IRQ=y -CONFIG_ARCH_INLINE_READ_UNLOCK_IRQRESTORE=y -CONFIG_ARCH_INLINE_SPIN_LOCK=y -CONFIG_ARCH_INLINE_SPIN_LOCK_BH=y -CONFIG_ARCH_INLINE_SPIN_LOCK_IRQ=y -CONFIG_ARCH_INLINE_SPIN_LOCK_IRQSAVE=y -CONFIG_ARCH_INLINE_SPIN_TRYLOCK=y -CONFIG_ARCH_INLINE_SPIN_TRYLOCK_BH=y -CONFIG_ARCH_INLINE_SPIN_UNLOCK=y -CONFIG_ARCH_INLINE_SPIN_UNLOCK_BH=y -CONFIG_ARCH_INLINE_SPIN_UNLOCK_IRQ=y -CONFIG_ARCH_INLINE_SPIN_UNLOCK_IRQRESTORE=y -CONFIG_ARCH_INLINE_WRITE_LOCK=y -CONFIG_ARCH_INLINE_WRITE_LOCK_BH=y -CONFIG_ARCH_INLINE_WRITE_LOCK_IRQ=y -CONFIG_ARCH_INLINE_WRITE_LOCK_IRQSAVE=y -CONFIG_ARCH_INLINE_WRITE_UNLOCK=y -CONFIG_ARCH_INLINE_WRITE_UNLOCK_BH=y -CONFIG_ARCH_INLINE_WRITE_UNLOCK_IRQ=y -CONFIG_ARCH_INLINE_WRITE_UNLOCK_IRQRESTORE=y -CONFIG_ARCH_MMAP_RND_BITS=18 -CONFIG_ARCH_MMAP_RND_BITS_MAX=24 -CONFIG_ARCH_MMAP_RND_BITS_MIN=18 -CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN=11 -CONFIG_ARCH_PROC_KCORE_TEXT=y -CONFIG_ARCH_SELECT_MEMORY_MODEL=y -CONFIG_ARCH_SPARSEMEM_DEFAULT=y -CONFIG_ARCH_SPARSEMEM_ENABLE=y -CONFIG_ARCH_SUPPORTS_ATOMIC_RMW=y -CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y -CONFIG_ARCH_SUPPORTS_INT128=y -CONFIG_ARCH_SUPPORTS_MEMORY_FAILURE=y -CONFIG_ARCH_SUPPORTS_NUMA_BALANCING=y -CONFIG_ARCH_SUPPORTS_UPROBES=y -CONFIG_ARCH_SUSPEND_POSSIBLE=y -CONFIG_ARCH_USE_CMPXCHG_LOCKREF=y -CONFIG_ARCH_USE_QUEUED_RWLOCKS=y -CONFIG_ARCH_USE_QUEUED_SPINLOCKS=y -CONFIG_ARCH_WANT_COMPAT_IPC_PARSE_VERSION=y -CONFIG_ARCH_WANT_FRAME_POINTERS=y -CONFIG_ARCH_WANT_HUGE_PMD_SHARE=y -CONFIG_ARM64=y -# CONFIG_ARM64_16K_PAGES is not set -CONFIG_ARM64_4K_PAGES=y -# CONFIG_ARM64_64K_PAGES is not set -CONFIG_ARM64_CONT_SHIFT=4 -# CONFIG_ARM64_CRYPTO is not set -CONFIG_ARM64_ERRATUM_1024718=y -CONFIG_ARM64_ERRATUM_1463225=y -CONFIG_ARM64_ERRATUM_819472=y -CONFIG_ARM64_ERRATUM_824069=y -CONFIG_ARM64_ERRATUM_826319=y -CONFIG_ARM64_ERRATUM_827319=y -CONFIG_ARM64_ERRATUM_832075=y -CONFIG_ARM64_ERRATUM_843419=y -CONFIG_ARM64_HW_AFDBM=y -# CONFIG_ARM64_LSE_ATOMICS is not set -CONFIG_ARM64_MODULE_PLTS=y -CONFIG_ARM64_PAGE_SHIFT=12 -CONFIG_ARM64_PAN=y -CONFIG_ARM64_PA_BITS=48 -CONFIG_ARM64_PA_BITS_48=y -# CONFIG_ARM64_PMEM is not set -# CONFIG_ARM64_PTDUMP_DEBUGFS is not set -# CONFIG_ARM64_RANDOMIZE_TEXT_OFFSET is not set -CONFIG_ARM64_SSBD=y -CONFIG_ARM64_SVE=y -# CONFIG_ARM64_SW_TTBR0_PAN is not set -CONFIG_ARM64_UAO=y -CONFIG_ARM64_VA_BITS=39 -CONFIG_ARM64_VA_BITS_39=y -# CONFIG_ARM64_VA_BITS_48 is not set -CONFIG_ARM64_VHE=y -CONFIG_ARM_AMBA=y -CONFIG_ARM_ARCH_TIMER=y -CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y -CONFIG_ARM_ARCH_TIMER_OOL_WORKAROUND=y -CONFIG_ARM_BCM2835_CPUFREQ=y -CONFIG_ARM_GIC=y -CONFIG_ARM_GIC_V3=y -CONFIG_ARM_GIC_V3_ITS=y -CONFIG_ARM_PSCI_FW=y -# CONFIG_ARM_SCMI_PROTOCOL is not set -# CONFIG_ARM_SP805_WATCHDOG is not set -CONFIG_ARM_TIMER_SP804=y -# CONFIG_AX88796B_PHY is not set -CONFIG_AUDIT_ARCH_COMPAT_GENERIC=y -# CONFIG_BACKLIGHT_CLASS_DEVICE is not set -CONFIG_BACKLIGHT_LCD_SUPPORT=y -CONFIG_BCM2708_VCMEM=y -# CONFIG_BCM2835_DEVGPIOMEM is not set -CONFIG_BCM2835_MBOX=y -CONFIG_BCM2835_POWER=y -# CONFIG_BCM2835_SMI is not set -CONFIG_BCM2835_THERMAL=y -CONFIG_BCM2835_VCHIQ=y -CONFIG_BCM2835_VCHIQ_MMAL=y -CONFIG_BCM2835_WDT=y -# CONFIG_BCM_VCIO is not set -# CONFIG_BCM_VC_SM is not set -CONFIG_BCM_VIDEOCORE=y -# CONFIG_BLK_DEV_INITRD is not set -CONFIG_BLK_DEV_LOOP=y -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_COUNT=16 -CONFIG_BLK_DEV_RAM_SIZE=4096 -CONFIG_BLK_DEV_SD=y -CONFIG_BLK_SCSI_REQUEST=y -CONFIG_BRCM_CHAR_DRIVERS=y -CONFIG_BRCMSTB_THERMAL=y -CONFIG_BUILD_BIN2C=y -CONFIG_CAVIUM_ERRATUM_22375=y -CONFIG_CAVIUM_ERRATUM_23154=y -CONFIG_CAVIUM_ERRATUM_27456=y -CONFIG_CLKDEV_LOOKUP=y -CONFIG_CLKSRC_MMIO=y -CONFIG_CLONE_BACKWARDS=y -CONFIG_CMA=y -CONFIG_CMA_ALIGNMENT=8 -CONFIG_CMA_AREAS=7 -# CONFIG_CMA_DEBUG is not set -# CONFIG_CMA_DEBUGFS is not set -CONFIG_CMA_SIZE_MBYTES=16 -# CONFIG_CMA_SIZE_SEL_MAX is not set -CONFIG_CMA_SIZE_SEL_MBYTES=y -# CONFIG_CMA_SIZE_SEL_MIN is not set -# CONFIG_CMA_SIZE_SEL_PERCENTAGE is not set -CONFIG_COMMON_CLK=y -CONFIG_COMMON_CLK_XGENE=y -# CONFIG_COMPAT is not set -CONFIG_CONFIGFS_FS=y -CONFIG_CONSOLE_TRANSLATIONS=y -# CONFIG_CPUFREQ_DT is not set -# CONFIG_CPU_BIG_ENDIAN is not set -CONFIG_CPU_FREQ=y -CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y -CONFIG_CPU_FREQ_GOV_ATTR_SET=y -CONFIG_CPU_FREQ_GOV_COMMON=y -CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y -CONFIG_CPU_FREQ_GOV_ONDEMAND=y -CONFIG_CPU_FREQ_GOV_PERFORMANCE=y -CONFIG_CPU_FREQ_GOV_POWERSAVE=y -CONFIG_CPU_FREQ_GOV_USERSPACE=y -CONFIG_CPU_FREQ_STAT=y -# CONFIG_CPU_HOTPLUG_STATE_CONTROL is not set -CONFIG_CPU_IDLE=y -CONFIG_CPU_IDLE_GOV_LADDER=y -CONFIG_CPU_IDLE_GOV_MENU=y -CONFIG_CPU_PM=y -CONFIG_CPU_RMAP=y -# CONFIG_CPU_THERMAL is not set -CONFIG_CRC16=y -CONFIG_CRYPTO_AEAD=y -CONFIG_CRYPTO_AEAD2=y -CONFIG_CRYPTO_CRC32=y -CONFIG_CRYPTO_CRC32C=y -CONFIG_CRYPTO_HASH=y -CONFIG_CRYPTO_HASH2=y -CONFIG_CRYPTO_MANAGER=y -CONFIG_CRYPTO_MANAGER2=y -CONFIG_CRYPTO_NULL2=y -CONFIG_CRYPTO_RNG2=y -CONFIG_CRYPTO_WORKQUEUE=y -CONFIG_DCACHE_WORD_ACCESS=y -CONFIG_DEBUG_BUGVERBOSE=y -CONFIG_DEBUG_INFO=y -CONFIG_DEFAULT_MPTCP_PM="fullmesh" -CONFIG_DMADEVICES=y -CONFIG_DMA_BCM2708=y -CONFIG_DMA_BCM2835=y -CONFIG_DMA_CMA=y -CONFIG_DMA_DIRECT_OPS=y -CONFIG_DMA_ENGINE=y -CONFIG_DMA_OF=y -CONFIG_DMA_SHARED_BUFFER=m -CONFIG_DMA_VIRTUAL_CHANNELS=y -CONFIG_DNOTIFY=y -CONFIG_DTC=y -CONFIG_DUMMY_CONSOLE=y -CONFIG_EDAC_SUPPORT=y -CONFIG_ENABLE_MUST_CHECK=y -CONFIG_EXT4_FS=y -CONFIG_EXT4_FS_POSIX_ACL=y -CONFIG_EXT4_FS_SECURITY=y -# CONFIG_F2FS_CHECK_FS is not set -CONFIG_F2FS_FS=y -# CONFIG_F2FS_FS_SECURITY is not set -CONFIG_F2FS_FS_XATTR=y -CONFIG_F2FS_STAT_FS=y -CONFIG_FB=y -CONFIG_FB_BCM2708=y -CONFIG_FB_CFB_COPYAREA=y -CONFIG_FB_CFB_FILLRECT=y -CONFIG_FB_CFB_IMAGEBLIT=y -CONFIG_FB_CMDLINE=y -# CONFIG_FB_RPISENSE is not set -CONFIG_FIXED_PHY=y -CONFIG_FIX_EARLYCON_MEM=y -# CONFIG_FLATMEM_MANUAL is not set -# CONFIG_FONTS is not set -CONFIG_FONT_8x16=y -CONFIG_FONT_8x8=y -CONFIG_FONT_SUPPORT=y -CONFIG_FRAMEBUFFER_CONSOLE=y -# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set -# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set -CONFIG_FRAME_POINTER=y -CONFIG_FREEZER=y -CONFIG_FSL_ERRATUM_A008585=y -CONFIG_FS_IOMAP=y -CONFIG_FS_MBCACHE=y -CONFIG_FS_POSIX_ACL=y -CONFIG_GENERIC_ALLOCATOR=y -CONFIG_GENERIC_ARCH_TOPOLOGY=y -CONFIG_GENERIC_BUG=y -CONFIG_GENERIC_BUG_RELATIVE_POINTERS=y -CONFIG_GENERIC_CLOCKEVENTS=y -CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y -CONFIG_GENERIC_CPU_AUTOPROBE=y -CONFIG_GENERIC_CSUM=y -CONFIG_GENERIC_EARLY_IOREMAP=y -CONFIG_GENERIC_IDLE_POLL_SETUP=y -CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y -CONFIG_GENERIC_IRQ_MIGRATION=y -CONFIG_GENERIC_IRQ_MULTI_HANDLER=y -CONFIG_GENERIC_IRQ_SHOW=y -CONFIG_GENERIC_IRQ_SHOW_LEVEL=y -CONFIG_GENERIC_MSI_IRQ=y -CONFIG_GENERIC_MSI_IRQ_DOMAIN=y -CONFIG_GENERIC_PCI_IOMAP=y -CONFIG_GENERIC_PINCONF=y -CONFIG_GENERIC_PINCTRL_GROUPS=y -CONFIG_GENERIC_PINMUX_FUNCTIONS=y -CONFIG_GENERIC_SCHED_CLOCK=y -CONFIG_GENERIC_SMP_IDLE_THREAD=y -CONFIG_GENERIC_STRNCPY_FROM_USER=y -CONFIG_GENERIC_STRNLEN_USER=y -CONFIG_GENERIC_TIME_VSYSCALL=y -CONFIG_GPIOLIB=y -CONFIG_GPIOLIB_IRQCHIP=y -CONFIG_GPIO_BCM_VIRT=y -CONFIG_GPIO_RASPBERRYPI_EXP=y -CONFIG_GPIO_SYSFS=y -CONFIG_HANDLE_DOMAIN_IRQ=y -CONFIG_HARDEN_BRANCH_PREDICTOR=y -CONFIG_HARDIRQS_SW_RESEND=y -CONFIG_HAS_DMA=y -CONFIG_HAS_IOMEM=y -CONFIG_HAVE_ALIGNED_STRUCT_PAGE=y -CONFIG_HAVE_ARCH_AUDITSYSCALL=y -CONFIG_HAVE_ARCH_BITREVERSE=y -CONFIG_HAVE_ARCH_HUGE_VMAP=y -CONFIG_HAVE_ARCH_JUMP_LABEL=y -CONFIG_HAVE_ARCH_KASAN=y -CONFIG_HAVE_ARCH_KGDB=y -CONFIG_HAVE_ARCH_PFN_VALID=y -CONFIG_HAVE_ARCH_PREL32_RELOCATIONS=y -CONFIG_HAVE_ARCH_SECCOMP_FILTER=y -CONFIG_HAVE_ARCH_THREAD_STRUCT_WHITELIST=y -CONFIG_HAVE_ARCH_TRACEHOOK=y -CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE=y -CONFIG_HAVE_ARCH_VMAP_STACK=y -CONFIG_HAVE_ARM_SMCCC=y -CONFIG_HAVE_CLK=y -CONFIG_HAVE_CLK_PREPARE=y -CONFIG_HAVE_CMPXCHG_DOUBLE=y -CONFIG_HAVE_CMPXCHG_LOCAL=y -CONFIG_HAVE_CONTEXT_TRACKING=y -CONFIG_HAVE_C_RECORDMCOUNT=y -CONFIG_HAVE_DEBUG_BUGVERBOSE=y -CONFIG_HAVE_DEBUG_KMEMLEAK=y -CONFIG_HAVE_DMA_CONTIGUOUS=y -CONFIG_HAVE_DYNAMIC_FTRACE=y -CONFIG_HAVE_EBPF_JIT=y -CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y -CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y -CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y -CONFIG_HAVE_FUNCTION_TRACER=y -CONFIG_HAVE_GENERIC_DMA_COHERENT=y -CONFIG_HAVE_GENERIC_GUP=y -CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y -CONFIG_HAVE_MEMBLOCK=y -CONFIG_HAVE_MEMORY_PRESENT=y -CONFIG_HAVE_MOD_ARCH_SPECIFIC=y -CONFIG_HAVE_NET_DSA=y -CONFIG_HAVE_PATA_PLATFORM=y -CONFIG_HAVE_PERF_EVENTS=y -CONFIG_HAVE_PERF_REGS=y -CONFIG_HAVE_PERF_USER_STACK_DUMP=y -CONFIG_HAVE_RCU_TABLE_FREE=y -CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y -CONFIG_HAVE_RSEQ=y -CONFIG_HAVE_SYSCALL_TRACEPOINTS=y -CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y -CONFIG_HOLES_IN_ZONE=y -CONFIG_HOTPLUG_CPU=y -# CONFIG_HUGETLBFS is not set -CONFIG_HW_CONSOLE=y -CONFIG_IKCONFIG=y -CONFIG_IKCONFIG_PROC=y -CONFIG_ILLEGAL_POINTER_VALUE=0xdead000000000000 -CONFIG_INLINE_READ_LOCK=y -CONFIG_INLINE_READ_LOCK_BH=y -CONFIG_INLINE_READ_LOCK_IRQ=y -CONFIG_INLINE_READ_LOCK_IRQSAVE=y -CONFIG_INLINE_READ_UNLOCK_BH=y -CONFIG_INLINE_READ_UNLOCK_IRQRESTORE=y -CONFIG_INLINE_SPIN_LOCK=y -CONFIG_INLINE_SPIN_LOCK_BH=y -CONFIG_INLINE_SPIN_LOCK_IRQ=y -CONFIG_INLINE_SPIN_LOCK_IRQSAVE=y -CONFIG_INLINE_SPIN_TRYLOCK=y -CONFIG_INLINE_SPIN_TRYLOCK_BH=y -CONFIG_INLINE_SPIN_UNLOCK_BH=y -CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE=y -CONFIG_INLINE_WRITE_LOCK=y -CONFIG_INLINE_WRITE_LOCK_BH=y -CONFIG_INLINE_WRITE_LOCK_IRQ=y -CONFIG_INLINE_WRITE_LOCK_IRQSAVE=y -CONFIG_INLINE_WRITE_UNLOCK_BH=y -CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE=y -CONFIG_INPUT=y -CONFIG_INPUT_MOUSEDEV=y -# CONFIG_INPUT_MOUSEDEV_PSAUX is not set -CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 -CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 -CONFIG_IOSCHED_CFQ=y -CONFIG_IRQCHIP=y -CONFIG_IRQ_DOMAIN=y -CONFIG_IRQ_DOMAIN_HIERARCHY=y -CONFIG_IRQ_FORCED_THREADING=y -CONFIG_IRQ_WORK=y -CONFIG_JBD2=y -# CONFIG_LCD_CLASS_DEVICE is not set -CONFIG_LEDS_GPIO=y -CONFIG_LEDS_TRIGGER_INPUT=y -CONFIG_LIBFDT=y -CONFIG_LOCK_DEBUGGING_SUPPORT=y -CONFIG_LOCK_SPIN_ON_OWNER=y -CONFIG_LOGO=y -CONFIG_LOGO_LINUX_CLUT224=y -# CONFIG_LOGO_LINUX_MONO is not set -# CONFIG_LOGO_LINUX_VGA16 is not set -CONFIG_MAC_PARTITION=y -CONFIG_MAGIC_SYSRQ=y -CONFIG_MAILBOX=y -# CONFIG_MAILBOX_TEST is not set -CONFIG_MAX_RAW_DEVS=256 -CONFIG_MDIO_BUS=y -CONFIG_MDIO_DEVICE=y -CONFIG_MEMFD_CREATE=y -CONFIG_MEMORY_ISOLATION=y -# CONFIG_MFD_RPISENSE_CORE is not set -CONFIG_MFD_SYSCON=y -CONFIG_MICROCHIP_PHY=y -CONFIG_MIGRATION=y -CONFIG_MMC=y -CONFIG_MMC_BCM2835=y -CONFIG_MMC_BCM2835_DMA=y -CONFIG_MMC_BCM2835_MMC=y -CONFIG_MMC_BCM2835_PIO_DMA_BARRIER=2 -CONFIG_MMC_BCM2835_SDHOST=y -CONFIG_MMC_BLOCK=y -CONFIG_MMC_BLOCK_MINORS=32 -CONFIG_MMC_SDHCI=y -CONFIG_MMC_SDHCI_PLTFM=y -CONFIG_MODULES_USE_ELF_RELA=y -# CONFIG_MTD is not set -CONFIG_MUTEX_SPIN_ON_OWNER=y -CONFIG_NEED_DMA_MAP_STATE=y -CONFIG_NEED_SG_DMA_LENGTH=y -CONFIG_NET_FLOW_LIMIT=y -CONFIG_NLS=y -CONFIG_NLS_ASCII=y -CONFIG_NLS_DEFAULT="utf8" -CONFIG_NO_BOOTMEM=y -CONFIG_NO_HZ=y -CONFIG_NO_HZ_COMMON=y -CONFIG_NO_HZ_IDLE=y -CONFIG_NO_IOPORT_MAP=y -CONFIG_NR_CPUS=4 -# CONFIG_NUMA is not set -CONFIG_NVMEM=y -CONFIG_OF=y -CONFIG_OF_ADDRESS=y -CONFIG_OF_CONFIGFS=y -CONFIG_OF_DYNAMIC=y -CONFIG_OF_EARLY_FLATTREE=y -CONFIG_OF_FLATTREE=y -CONFIG_OF_GPIO=y -CONFIG_OF_IRQ=y -CONFIG_OF_KOBJ=y -CONFIG_OF_MDIO=y -CONFIG_OF_NET=y -CONFIG_OF_OVERLAY=y -CONFIG_OF_RESERVED_MEM=y -CONFIG_OF_RESOLVE=y -CONFIG_PADATA=y -CONFIG_PARTITION_PERCPU=y -CONFIG_PGTABLE_LEVELS=3 -CONFIG_PHYLIB=y -CONFIG_PHYS_ADDR_T_64BIT=y -CONFIG_PINCTRL=y -CONFIG_PINCTRL_BCM2835=y -CONFIG_PLUGIN_HOSTCC="g++" -CONFIG_PM=y -CONFIG_PM_CLK=y -# CONFIG_PM_DEBUG is not set -CONFIG_PM_GENERIC_DOMAINS=y -CONFIG_PM_GENERIC_DOMAINS_OF=y -CONFIG_PM_GENERIC_DOMAINS_SLEEP=y -CONFIG_PM_SLEEP=y -CONFIG_PM_SLEEP_SMP=y -CONFIG_POWER_RESET=y -CONFIG_POWER_SUPPLY=y -CONFIG_PRINTK_TIME=y -CONFIG_PROC_PAGE_MONITOR=y -CONFIG_PWM=y -CONFIG_PWM_BCM2835=y -CONFIG_PWM_SYSFS=y -CONFIG_QUEUED_RWLOCKS=y -CONFIG_QUEUED_SPINLOCKS=y -# CONFIG_RANDOMIZE_BASE is not set -CONFIG_RASPBERRYPI_FIRMWARE=y -CONFIG_RASPBERRYPI_POWER=y -CONFIG_RATIONAL=y -CONFIG_RAW_DRIVER=y -CONFIG_RCU_NEED_SEGCBLIST=y -CONFIG_RCU_STALL_COMMON=y -CONFIG_REFCOUNT_FULL=y -CONFIG_REGMAP=y -CONFIG_REGMAP_MMIO=y -CONFIG_REGULATOR=y -CONFIG_REGULATOR_FIXED_VOLTAGE=y -CONFIG_RFS_ACCEL=y -# CONFIG_RPIVID_MEM is not set -CONFIG_RPS=y -CONFIG_RWSEM_SPIN_ON_OWNER=y -CONFIG_RWSEM_XCHGADD_ALGORITHM=y -CONFIG_SCSI=y -# CONFIG_SCSI_LOWLEVEL is not set -# CONFIG_SCSI_PROC_FS is not set -# CONFIG_SENSORS_RASPBERRYPI_HWMON is not set -CONFIG_SERIAL_8250_BCM2835AUX=y -# CONFIG_SERIAL_8250_DMA is not set -CONFIG_SERIAL_8250_EXTENDED=y -CONFIG_SERIAL_8250_FSL=y -CONFIG_SERIAL_8250_NR_UARTS=1 -CONFIG_SERIAL_8250_RUNTIME_UARTS=0 -CONFIG_SERIAL_8250_SHARE_IRQ=y -CONFIG_SERIAL_AMBA_PL011=y -CONFIG_SERIAL_AMBA_PL011_CONSOLE=y -CONFIG_SERIAL_OF_PLATFORM=y -CONFIG_SG_POOL=y -CONFIG_SMP=y -# CONFIG_SND_AUDIOSENSE_PI is not set -# CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUSADC is not set -# CONFIG_SND_BCM2708_SOC_I_SABRE_Q2M is not set -# CONFIG_SND_RPI_SIMPLE_SOUNDCARD is not set -# CONFIG_SND_RPI_WM8804_SOUNDCARD is not set -# CONFIG_SND_SOC_AD193X_SPI is not set -CONFIG_SPARSEMEM=y -CONFIG_SPARSEMEM_EXTREME=y -CONFIG_SPARSEMEM_MANUAL=y -CONFIG_SPARSEMEM_VMEMMAP=y -CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y -CONFIG_SPARSE_IRQ=y -CONFIG_SRCU=y -CONFIG_STREAM_PARSER=y -# CONFIG_STRIP_ASM_SYMS is not set -CONFIG_SUSPEND=y -CONFIG_SUSPEND_FREEZER=y -CONFIG_SWIOTLB=y -CONFIG_SWPHY=y -CONFIG_SYSCTL_EXCEPTION_TRACE=y -CONFIG_SYS_SUPPORTS_HUGETLBFS=y -# CONFIG_TEXTSEARCH is not set -CONFIG_THERMAL=y -CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y -CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=0 -CONFIG_THERMAL_GOV_STEP_WISE=y -CONFIG_THERMAL_OF=y -CONFIG_THREAD_INFO_IN_TASK=y -CONFIG_TICK_CPU_ACCOUNTING=y -CONFIG_TIMER_OF=y -CONFIG_TIMER_PROBE=y -CONFIG_TMPFS_POSIX_ACL=y -# CONFIG_TOUCHSCREEN_RPI_FT5406 is not set -CONFIG_TREE_RCU=y -CONFIG_TREE_SRCU=y -CONFIG_UEVENT_HELPER_PATH="" -CONFIG_UNMAP_KERNEL_AT_EL0=y -CONFIG_USB=y -CONFIG_USB_ANNOUNCE_NEW_DEVICES=y -CONFIG_USB_COMMON=y -CONFIG_USB_DWCOTG=y -# CONFIG_USB_EHCI_HCD is not set -CONFIG_USB_LAN78XX=y -CONFIG_USB_NET_DRIVERS=y -CONFIG_USB_NET_SMSC95XX=y -CONFIG_USB_STORAGE=y -CONFIG_USB_SUPPORT=y -CONFIG_USB_UAS=y -CONFIG_USB_USBNET=y -# CONFIG_VIDEO_CODEC_BCM2835 is not set -CONFIG_VMAP_STACK=y -CONFIG_VT=y -CONFIG_VT_CONSOLE=y -CONFIG_VT_CONSOLE_SLEEP=y -CONFIG_VT_HW_CONSOLE_BINDING=y -CONFIG_WATCHDOG_CORE=y -CONFIG_XPS=y -CONFIG_XZ_DEC_ARM=y -CONFIG_XZ_DEC_BCJ=y -CONFIG_ZONE_DMA32=y diff --git a/root/target/linux/bcm27xx/bcm2711/config-4.19 b/root/target/linux/bcm27xx/bcm2711/config-4.19 deleted file mode 100644 index b1691271..00000000 --- a/root/target/linux/bcm27xx/bcm2711/config-4.19 +++ /dev/null @@ -1,667 +0,0 @@ -CONFIG_64BIT=y -# CONFIG_AIO is not set -CONFIG_ARCH_BCM2835=y -CONFIG_ARCH_CLOCKSOURCE_DATA=y -CONFIG_ARCH_DMA_ADDR_T_64BIT=y -CONFIG_ARCH_HAS_CACHE_LINE_SIZE=y -CONFIG_ARCH_HAS_DEBUG_VIRTUAL=y -CONFIG_ARCH_HAS_ELF_RANDOMIZE=y -CONFIG_ARCH_HAS_FAST_MULTIPLIER=y -CONFIG_ARCH_HAS_FORTIFY_SOURCE=y -CONFIG_ARCH_HAS_GCOV_PROFILE_ALL=y -CONFIG_ARCH_HAS_GIGANTIC_PAGE=y -CONFIG_ARCH_HAS_HOLES_MEMORYMODEL=y -CONFIG_ARCH_HAS_KCOV=y -CONFIG_ARCH_HAS_MEMBARRIER_SYNC_CORE=y -CONFIG_ARCH_HAS_PHYS_TO_DMA=y -CONFIG_ARCH_HAS_PTE_SPECIAL=y -CONFIG_ARCH_HAS_SET_MEMORY=y -CONFIG_ARCH_HAS_SG_CHAIN=y -CONFIG_ARCH_HAS_STRICT_KERNEL_RWX=y -CONFIG_ARCH_HAS_STRICT_MODULE_RWX=y -CONFIG_ARCH_HAS_SYSCALL_WRAPPER=y -CONFIG_ARCH_HAS_TICK_BROADCAST=y -CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG=y -CONFIG_ARCH_HIBERNATION_POSSIBLE=y -CONFIG_ARCH_INLINE_READ_LOCK=y -CONFIG_ARCH_INLINE_READ_LOCK_BH=y -CONFIG_ARCH_INLINE_READ_LOCK_IRQ=y -CONFIG_ARCH_INLINE_READ_LOCK_IRQSAVE=y -CONFIG_ARCH_INLINE_READ_UNLOCK=y -CONFIG_ARCH_INLINE_READ_UNLOCK_BH=y -CONFIG_ARCH_INLINE_READ_UNLOCK_IRQ=y -CONFIG_ARCH_INLINE_READ_UNLOCK_IRQRESTORE=y -CONFIG_ARCH_INLINE_SPIN_LOCK=y -CONFIG_ARCH_INLINE_SPIN_LOCK_BH=y -CONFIG_ARCH_INLINE_SPIN_LOCK_IRQ=y -CONFIG_ARCH_INLINE_SPIN_LOCK_IRQSAVE=y -CONFIG_ARCH_INLINE_SPIN_TRYLOCK=y -CONFIG_ARCH_INLINE_SPIN_TRYLOCK_BH=y -CONFIG_ARCH_INLINE_SPIN_UNLOCK=y -CONFIG_ARCH_INLINE_SPIN_UNLOCK_BH=y -CONFIG_ARCH_INLINE_SPIN_UNLOCK_IRQ=y -CONFIG_ARCH_INLINE_SPIN_UNLOCK_IRQRESTORE=y -CONFIG_ARCH_INLINE_WRITE_LOCK=y -CONFIG_ARCH_INLINE_WRITE_LOCK_BH=y -CONFIG_ARCH_INLINE_WRITE_LOCK_IRQ=y -CONFIG_ARCH_INLINE_WRITE_LOCK_IRQSAVE=y -CONFIG_ARCH_INLINE_WRITE_UNLOCK=y -CONFIG_ARCH_INLINE_WRITE_UNLOCK_BH=y -CONFIG_ARCH_INLINE_WRITE_UNLOCK_IRQ=y -CONFIG_ARCH_INLINE_WRITE_UNLOCK_IRQRESTORE=y -CONFIG_ARCH_MMAP_RND_BITS=18 -CONFIG_ARCH_MMAP_RND_BITS_MAX=24 -CONFIG_ARCH_MMAP_RND_BITS_MIN=18 -CONFIG_ARCH_MMAP_RND_COMPAT_BITS=11 -CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN=11 -CONFIG_ARCH_PROC_KCORE_TEXT=y -CONFIG_ARCH_SELECT_MEMORY_MODEL=y -CONFIG_ARCH_SPARSEMEM_DEFAULT=y -CONFIG_ARCH_SPARSEMEM_ENABLE=y -CONFIG_ARCH_SUPPORTS_ATOMIC_RMW=y -CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y -CONFIG_ARCH_SUPPORTS_INT128=y -CONFIG_ARCH_SUPPORTS_MEMORY_FAILURE=y -CONFIG_ARCH_SUPPORTS_NUMA_BALANCING=y -CONFIG_ARCH_SUPPORTS_UPROBES=y -CONFIG_ARCH_SUSPEND_POSSIBLE=y -CONFIG_ARCH_USE_CMPXCHG_LOCKREF=y -CONFIG_ARCH_USE_QUEUED_RWLOCKS=y -CONFIG_ARCH_USE_QUEUED_SPINLOCKS=y -CONFIG_ARCH_WANT_COMPAT_IPC_PARSE_VERSION=y -CONFIG_ARCH_WANT_FRAME_POINTERS=y -CONFIG_ARCH_WANT_HUGE_PMD_SHARE=y -CONFIG_ARGON_MEM=y -CONFIG_ARM64=y -# CONFIG_ARM64_16K_PAGES is not set -CONFIG_ARM64_4K_PAGES=y -# CONFIG_ARM64_64K_PAGES is not set -CONFIG_ARM64_CONT_SHIFT=4 -CONFIG_ARM64_CRYPTO=y -CONFIG_ARM64_ERRATUM_1024718=y -CONFIG_ARM64_ERRATUM_1463225=y -CONFIG_ARM64_ERRATUM_819472=y -CONFIG_ARM64_ERRATUM_824069=y -CONFIG_ARM64_ERRATUM_826319=y -CONFIG_ARM64_ERRATUM_827319=y -CONFIG_ARM64_ERRATUM_832075=y -CONFIG_ARM64_ERRATUM_843419=y -CONFIG_ARM64_HW_AFDBM=y -# CONFIG_ARM64_LSE_ATOMICS is not set -CONFIG_ARM64_MODULE_PLTS=y -CONFIG_ARM64_PAGE_SHIFT=12 -CONFIG_ARM64_PAN=y -CONFIG_ARM64_PA_BITS=48 -CONFIG_ARM64_PA_BITS_48=y -# CONFIG_ARM64_PMEM is not set -# CONFIG_ARM64_PTDUMP_DEBUGFS is not set -# CONFIG_ARM64_RANDOMIZE_TEXT_OFFSET is not set -CONFIG_ARM64_SSBD=y -CONFIG_ARM64_SVE=y -# CONFIG_ARM64_SW_TTBR0_PAN is not set -CONFIG_ARM64_UAO=y -CONFIG_ARM64_VA_BITS=39 -CONFIG_ARM64_VA_BITS_39=y -# CONFIG_ARM64_VA_BITS_48 is not set -CONFIG_ARM64_VHE=y -CONFIG_ARMV8_DEPRECATED=y -CONFIG_ARM_AMBA=y -CONFIG_ARM_ARCH_TIMER=y -CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y -CONFIG_ARM_ARCH_TIMER_OOL_WORKAROUND=y -CONFIG_ARM_BCM2835_CPUFREQ=y -CONFIG_ARM_CRYPTO=y -CONFIG_ARM_GIC=y -CONFIG_ARM_GIC_V2M=y -CONFIG_ARM_GIC_V3=y -CONFIG_ARM_GIC_V3_ITS=y -CONFIG_ARM_GIC_V3_ITS_PCI=y -CONFIG_ARM_HEAVY_MB=y -CONFIG_ARM_LPAE=y -CONFIG_ARM_PSCI_FW=y -CONFIG_ARM_MODULE_PLTS=y -# CONFIG_ARM_SCMI_PROTOCOL is not set -# CONFIG_ARM_SP805_WATCHDOG is not set -CONFIG_ARM_TIMER_SP804=y -# CONFIG_AX88796B_PHY is not set -CONFIG_AUDIT_ARCH_COMPAT_GENERIC=y -# CONFIG_BACKLIGHT_CLASS_DEVICE is not set -CONFIG_BACKLIGHT_LCD_SUPPORT=y -CONFIG_BCM2708_VCMEM=y -CONFIG_BCM2835_DEVGPIOMEM=y -CONFIG_BCM2835_MBOX=y -CONFIG_BCM2835_POWER=y -# CONFIG_BCM2835_SMI is not set -CONFIG_BCM2835_THERMAL=y -CONFIG_BCM2835_VCHIQ=y -CONFIG_BCM2835_VCHIQ_MMAL=y -CONFIG_BCM2835_WDT=y -CONFIG_BCM7XXX_PHY=y -CONFIG_BCMGENET=y -CONFIG_BCM_NET_PHYLIB=y -CONFIG_BCM_VCIO=y -# CONFIG_BCM_VC_SM is not set -CONFIG_BCM_VC_SM_CMA=y -CONFIG_BCM_VIDEOCORE=y -CONFIG_BLK_DEBUG_FS=y -CONFIG_BLK_DEV_BSG=y -CONFIG_BLK_DEV_BSGLIB=y -# CONFIG_BLK_DEV_DM is not set -# CONFIG_BLK_DEV_INITRD is not set -CONFIG_BLK_DEV_LOOP=y -# CONFIG_BLK_DEV_MD is not set -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_COUNT=16 -CONFIG_BLK_DEV_RAM_SIZE=4096 -CONFIG_BLK_DEV_SD=y -CONFIG_BLK_MQ_PCI=y -CONFIG_BLK_SCSI_REQUEST=y -CONFIG_BLOCK_COMPAT=y -CONFIG_BOUNCE=y -CONFIG_BRCMSTB_THERMAL=y -CONFIG_BRCM_CHAR_DRIVERS=y -CONFIG_BROADCOM_PHY=y -CONFIG_BUILD_BIN2C=y -CONFIG_CACHE_L2X0=y -CONFIG_CAVIUM_ERRATUM_22375=y -CONFIG_CAVIUM_ERRATUM_23154=y -CONFIG_CAVIUM_ERRATUM_27456=y -CONFIG_CC_HAS_ASM_GOTO=y -CONFIG_CLKDEV_LOOKUP=y -CONFIG_CLKSRC_MMIO=y -CONFIG_CLONE_BACKWARDS=y -CONFIG_CMA=y -CONFIG_CMA_ALIGNMENT=8 -CONFIG_CMA_AREAS=7 -# CONFIG_CMA_DEBUG is not set -# CONFIG_CMA_DEBUGFS is not set -CONFIG_CMA_SIZE_MBYTES=5 -# CONFIG_CMA_SIZE_SEL_MAX is not set -CONFIG_CMA_SIZE_SEL_MBYTES=y -# CONFIG_CMA_SIZE_SEL_MIN is not set -# CONFIG_CMA_SIZE_SEL_PERCENTAGE is not set -CONFIG_COMMON_CLK=y -CONFIG_COMMON_CLK_XGENE=y -CONFIG_COMPAT=y -CONFIG_COMPAT_32BIT_TIME=y -CONFIG_COMPAT_BINFMT_ELF=y -CONFIG_COMPAT_NETLINK_MESSAGES=y -CONFIG_COMPAT_OLD_SIGACTION=y -CONFIG_CONFIGFS_FS=y -CONFIG_CONSOLE_TRANSLATIONS=y -CONFIG_CP15_BARRIER_EMULATION=y -# CONFIG_CPUFREQ_DT is not set -# CONFIG_CPU_BIG_ENDIAN is not set -CONFIG_CPU_FREQ=y -CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y -# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set -CONFIG_CPU_FREQ_GOV_ATTR_SET=y -CONFIG_CPU_FREQ_GOV_COMMON=y -CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y -CONFIG_CPU_FREQ_GOV_ONDEMAND=y -CONFIG_CPU_FREQ_GOV_PERFORMANCE=y -CONFIG_CPU_FREQ_GOV_POWERSAVE=y -CONFIG_CPU_FREQ_GOV_USERSPACE=y -CONFIG_CPU_FREQ_STAT=y -# CONFIG_CPU_HOTPLUG_STATE_CONTROL is not set -CONFIG_CPU_IDLE=y -CONFIG_CPU_IDLE_GOV_LADDER=y -CONFIG_CPU_IDLE_GOV_MENU=y -CONFIG_CPU_PM=y -CONFIG_CPU_RMAP=y -# CONFIG_CPU_THERMAL is not set -CONFIG_CRC16=y -CONFIG_CRYPTO_AEAD=y -CONFIG_CRYPTO_AEAD2=y -CONFIG_CRYPTO_AES_ARM64=y -CONFIG_CRYPTO_AES_ARM64_BS=y -CONFIG_CRYPTO_AES_ARM64_CE=y -CONFIG_CRYPTO_AES_ARM64_CE_BLK=y -CONFIG_CRYPTO_AES_ARM64_CE_CCM=y -CONFIG_CRYPTO_AES_ARM64_NEON_BLK=y -CONFIG_CRYPTO_CHACHA20=y -CONFIG_CRYPTO_CHACHA20_NEON=y -CONFIG_CRYPTO_CRC32=y -CONFIG_CRYPTO_CRC32C=y -CONFIG_CRYPTO_CRC32_ARM64_CE=y -CONFIG_CRYPTO_CRYPTD=y -CONFIG_CRYPTO_GF128MUL=y -CONFIG_CRYPTO_GHASH_ARM64_CE=y -CONFIG_CRYPTO_HASH=y -CONFIG_CRYPTO_HASH2=y -CONFIG_CRYPTO_MANAGER=y -CONFIG_CRYPTO_MANAGER2=y -CONFIG_CRYPTO_NULL2=y -CONFIG_CRYPTO_RNG2=y -CONFIG_CRYPTO_SHA1=y -CONFIG_CRYPTO_SHA1_ARM64_CE=y -CONFIG_CRYPTO_SHA256_ARM64=y -CONFIG_CRYPTO_SHA2_ARM64_CE=y -CONFIG_CRYPTO_SHA3=y -CONFIG_CRYPTO_SHA3_ARM64=y -CONFIG_CRYPTO_SHA512_ARM64=y -CONFIG_CRYPTO_SHA512_ARM64_CE=y -CONFIG_CRYPTO_SIMD=y -CONFIG_CRYPTO_SM3=y -CONFIG_CRYPTO_SM3_ARM64_CE=y -CONFIG_CRYPTO_SM4=y -CONFIG_CRYPTO_SM4_ARM64_CE=y -CONFIG_CRYPTO_WORKQUEUE=y -CONFIG_DCACHE_WORD_ACCESS=y -CONFIG_DEBUG_BUGVERBOSE=y -CONFIG_DEBUG_INFO=y -CONFIG_DEFAULT_CFQ=y -# CONFIG_DEFAULT_DEADLINE is not set -CONFIG_DEFAULT_IOSCHED="cfq" -CONFIG_DEFAULT_MPTCP_PM="fullmesh" -CONFIG_DEVMEM=y -CONFIG_DMADEVICES=y -CONFIG_DMA_BCM2708=y -CONFIG_DMA_BCM2835=y -CONFIG_DMA_CMA=y -CONFIG_DMA_DIRECT_OPS=y -CONFIG_DMA_ENGINE=y -CONFIG_DMA_OF=y -CONFIG_DMA_SHARED_BUFFER=y -CONFIG_DMA_VIRTUAL_CHANNELS=y -CONFIG_DNOTIFY=y -CONFIG_DTC=y -CONFIG_DUMMY_CONSOLE=y -CONFIG_EDAC_SUPPORT=y -CONFIG_ENABLE_MUST_CHECK=y -CONFIG_EXT4_FS=y -CONFIG_EXT4_FS_POSIX_ACL=y -CONFIG_EXT4_FS_SECURITY=y -CONFIG_FB=y -CONFIG_FB_BCM2708=y -CONFIG_FB_CFB_COPYAREA=y -CONFIG_FB_CFB_FILLRECT=y -CONFIG_FB_CFB_IMAGEBLIT=y -CONFIG_FB_CMDLINE=y -# CONFIG_FB_RPISENSE is not set -CONFIG_FIXED_PHY=y -CONFIG_FIX_EARLYCON_MEM=y -# CONFIG_FLATMEM_MANUAL is not set -# CONFIG_FONTS is not set -CONFIG_FONT_8x16=y -CONFIG_FONT_8x8=y -CONFIG_FONT_SUPPORT=y -CONFIG_FRAMEBUFFER_CONSOLE=y -# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set -# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set -CONFIG_FRAME_POINTER=y -CONFIG_FREEZER=y -CONFIG_FIXED_PHY=y -CONFIG_FSL_ERRATUM_A008585=y -CONFIG_FS_IOMAP=y -CONFIG_FS_MBCACHE=y -CONFIG_FS_POSIX_ACL=y -CONFIG_GENERIC_ALLOCATOR=y -CONFIG_GENERIC_ARCH_TOPOLOGY=y -CONFIG_GENERIC_BUG=y -CONFIG_GENERIC_BUG_RELATIVE_POINTERS=y -CONFIG_GENERIC_CLOCKEVENTS=y -CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y -CONFIG_GENERIC_CPU_AUTOPROBE=y -CONFIG_GENERIC_CSUM=y -CONFIG_GENERIC_EARLY_IOREMAP=y -CONFIG_GENERIC_IDLE_POLL_SETUP=y -CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y -CONFIG_GENERIC_IRQ_MIGRATION=y -CONFIG_GENERIC_IRQ_MULTI_HANDLER=y -CONFIG_GENERIC_IRQ_SHOW=y -CONFIG_GENERIC_IRQ_SHOW_LEVEL=y -CONFIG_GENERIC_MSI_IRQ=y -CONFIG_GENERIC_MSI_IRQ_DOMAIN=y -CONFIG_GENERIC_PCI_IOMAP=y -CONFIG_GENERIC_PHY=y -CONFIG_GENERIC_PINCONF=y -CONFIG_GENERIC_PINCTRL_GROUPS=y -CONFIG_GENERIC_PINMUX_FUNCTIONS=y -CONFIG_GENERIC_SCHED_CLOCK=y -CONFIG_GENERIC_SMP_IDLE_THREAD=y -CONFIG_GENERIC_STRNCPY_FROM_USER=y -CONFIG_GENERIC_STRNLEN_USER=y -CONFIG_GENERIC_TIME_VSYSCALL=y -CONFIG_GPIOLIB=y -CONFIG_GPIOLIB_IRQCHIP=y -CONFIG_GPIO_BCM_VIRT=y -CONFIG_GPIO_RASPBERRYPI_EXP=y -CONFIG_GPIO_STMPE=y -CONFIG_GPIO_SYSFS=y -CONFIG_HANDLE_DOMAIN_IRQ=y -CONFIG_HARDEN_BRANCH_PREDICTOR=y -CONFIG_HARDIRQS_SW_RESEND=y -CONFIG_HAS_DMA=y -CONFIG_HAS_IOMEM=y -CONFIG_HAS_IOPORT_MAP=y -CONFIG_HAVE_ALIGNED_STRUCT_PAGE=y -CONFIG_HAVE_ARCH_AUDITSYSCALL=y -CONFIG_HAVE_ARCH_BITREVERSE=y -CONFIG_HAVE_ARCH_HUGE_VMAP=y -CONFIG_HAVE_ARCH_JUMP_LABEL=y -CONFIG_HAVE_ARCH_KASAN=y -CONFIG_HAVE_ARCH_KGDB=y -CONFIG_HAVE_ARCH_MMAP_RND_COMPAT_BITS=y -CONFIG_HAVE_ARCH_PFN_VALID=y -CONFIG_HAVE_ARCH_PREL32_RELOCATIONS=y -CONFIG_HAVE_ARCH_SECCOMP_FILTER=y -CONFIG_HAVE_ARCH_THREAD_STRUCT_WHITELIST=y -CONFIG_HAVE_ARCH_TRACEHOOK=y -CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE=y -CONFIG_HAVE_ARCH_VMAP_STACK=y -CONFIG_HAVE_ARM_SMCCC=y -CONFIG_HAVE_CLK=y -CONFIG_HAVE_CLK_PREPARE=y -CONFIG_HAVE_CMPXCHG_DOUBLE=y -CONFIG_HAVE_CMPXCHG_LOCAL=y -CONFIG_HAVE_CONTEXT_TRACKING=y -CONFIG_HAVE_C_RECORDMCOUNT=y -CONFIG_HAVE_DEBUG_BUGVERBOSE=y -CONFIG_HAVE_DEBUG_KMEMLEAK=y -CONFIG_HAVE_DMA_CONTIGUOUS=y -CONFIG_HAVE_DYNAMIC_FTRACE=y -CONFIG_HAVE_EBPF_JIT=y -CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y -CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y -CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y -CONFIG_HAVE_FUNCTION_TRACER=y -CONFIG_HAVE_GENERIC_DMA_COHERENT=y -CONFIG_HAVE_GENERIC_GUP=y -CONFIG_HAVE_IDE=y -CONFIG_HAVE_LD_DEAD_CODE_DATA_ELIMINATION=y -CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y -CONFIG_HAVE_MEMBLOCK=y -CONFIG_HAVE_MEMORY_PRESENT=y -CONFIG_HAVE_MOD_ARCH_SPECIFIC=y -CONFIG_HAVE_NET_DSA=y -CONFIG_HAVE_PATA_PLATFORM=y -CONFIG_HAVE_PERF_EVENTS=y -CONFIG_HAVE_PERF_REGS=y -CONFIG_HAVE_PERF_USER_STACK_DUMP=y -CONFIG_HAVE_RCU_TABLE_FREE=y -CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y -CONFIG_HAVE_RSEQ=y -CONFIG_HAVE_SYSCALL_TRACEPOINTS=y -CONFIG_HAVE_UID16=y -CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y -CONFIG_HIGHMEM=y -CONFIG_HIGHPTE=y -CONFIG_HW_RANDOM=y -CONFIG_HW_RANDOM_BCM2835=y -CONFIG_HW_RANDOM_IPROC_RNG200=y -CONFIG_HOLES_IN_ZONE=y -CONFIG_HOTPLUG_CPU=y -# CONFIG_HUGETLBFS is not set -CONFIG_HW_CONSOLE=y -CONFIG_I2C=y -# CONFIG_I2C_BCM2708 is not set -CONFIG_I2C_BOARDINFO=y -CONFIG_I2C_COMPAT=y -CONFIG_I2C_HELPER_AUTO=y -CONFIG_IKCONFIG=y -CONFIG_IKCONFIG_PROC=y -CONFIG_ILLEGAL_POINTER_VALUE=0xdead000000000000 -CONFIG_INLINE_READ_LOCK=y -CONFIG_INLINE_READ_LOCK_BH=y -CONFIG_INLINE_READ_LOCK_IRQ=y -CONFIG_INLINE_READ_LOCK_IRQSAVE=y -CONFIG_INLINE_READ_UNLOCK_BH=y -CONFIG_INLINE_READ_UNLOCK_IRQRESTORE=y -CONFIG_INLINE_SPIN_LOCK=y -CONFIG_INLINE_SPIN_LOCK_BH=y -CONFIG_INLINE_SPIN_LOCK_IRQ=y -CONFIG_INLINE_SPIN_LOCK_IRQSAVE=y -CONFIG_INLINE_SPIN_TRYLOCK=y -CONFIG_INLINE_SPIN_TRYLOCK_BH=y -CONFIG_INLINE_SPIN_UNLOCK_BH=y -CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE=y -CONFIG_INLINE_WRITE_LOCK=y -CONFIG_INLINE_WRITE_LOCK_BH=y -CONFIG_INLINE_WRITE_LOCK_IRQ=y -CONFIG_INLINE_WRITE_LOCK_IRQSAVE=y -CONFIG_INLINE_WRITE_UNLOCK_BH=y -CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE=y -CONFIG_INPUT=y -CONFIG_INPUT_MOUSEDEV=y -# CONFIG_INPUT_MOUSEDEV_PSAUX is not set -CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 -CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 -CONFIG_IOSCHED_CFQ=y -CONFIG_IRQCHIP=y -CONFIG_IRQ_DOMAIN=y -CONFIG_IRQ_DOMAIN_HIERARCHY=y -CONFIG_IRQ_FORCED_THREADING=y -CONFIG_IRQ_WORK=y -CONFIG_JBD2=y -# CONFIG_LCD_CLASS_DEVICE is not set -CONFIG_LEDS_GPIO=y -CONFIG_LEDS_TRIGGER_INPUT=y -CONFIG_LIBFDT=y -CONFIG_LOCK_DEBUGGING_SUPPORT=y -CONFIG_LOCK_SPIN_ON_OWNER=y -CONFIG_LOGO=y -CONFIG_LOGO_LINUX_CLUT224=y -# CONFIG_LOGO_LINUX_MONO is not set -# CONFIG_LOGO_LINUX_VGA16 is not set -CONFIG_MAC_PARTITION=y -CONFIG_MAGIC_SYSRQ=y -CONFIG_MAILBOX=y -# CONFIG_MAILBOX_TEST is not set -CONFIG_MAX_RAW_DEVS=256 -CONFIG_MD=y -CONFIG_MDIO_BCM_UNIMAC=y -CONFIG_MDIO_BUS=y -CONFIG_MDIO_DEVICE=y -CONFIG_MEMFD_CREATE=y -CONFIG_MEMORY_ISOLATION=y -CONFIG_MFD_CORE=y -# CONFIG_MFD_RPISENSE_CORE is not set -CONFIG_MFD_STMPE=y -CONFIG_MFD_SYSCON=y -CONFIG_MICROCHIP_PHY=y -CONFIG_MIGRATION=y -CONFIG_MMC=y -# CONFIG_MMC_BCM2835 is not set -CONFIG_MMC_BCM2835_DMA=y -CONFIG_MMC_BCM2835_MMC=y -CONFIG_MMC_BCM2835_PIO_DMA_BARRIER=2 -CONFIG_MMC_BCM2835_SDHOST=y -CONFIG_MMC_BLOCK=y -CONFIG_MMC_BLOCK_MINORS=32 -CONFIG_MMC_SDHCI=y -CONFIG_MMC_SDHCI_IO_ACCESSORS=y -CONFIG_MMC_SDHCI_IPROC=y -# CONFIG_MMC_SDHCI_PCI is not set -CONFIG_MMC_SDHCI_PLTFM=y -# CONFIG_MMC_TIFM_SD is not set -CONFIG_MODULES_USE_ELF_RELA=y -CONFIG_MTD_BLOCK2MTD=y -CONFIG_MTD_NAND=y -CONFIG_MTD_NAND_ECC=y -CONFIG_MTD_SPI_NOR=y -CONFIG_MTD_UBI=y -CONFIG_MTD_UBI_BEB_LIMIT=20 -# CONFIG_MTD_UBI_BLOCK is not set -# CONFIG_MTD_UBI_FASTMAP is not set -# CONFIG_MTD_UBI_GLUEBI is not set -CONFIG_MTD_UBI_WL_THRESHOLD=4096 -CONFIG_MUTEX_SPIN_ON_OWNER=y -CONFIG_NEED_DMA_MAP_STATE=y -CONFIG_NEED_SG_DMA_LENGTH=y -CONFIG_NET_FLOW_LIMIT=y -CONFIG_NLS=y -CONFIG_NLS_ASCII=y -CONFIG_NLS_DEFAULT="utf8" -CONFIG_NO_BOOTMEM=y -CONFIG_NO_HZ=y -CONFIG_NO_HZ_COMMON=y -CONFIG_NO_HZ_IDLE=y -CONFIG_NR_CPUS=4 -# CONFIG_NUMA is not set -CONFIG_NVMEM=y -CONFIG_OF=y -CONFIG_OF_ADDRESS=y -CONFIG_OF_CONFIGFS=y -CONFIG_OF_DYNAMIC=y -CONFIG_OF_EARLY_FLATTREE=y -CONFIG_OF_FLATTREE=y -CONFIG_OF_GPIO=y -CONFIG_OF_IRQ=y -CONFIG_OF_KOBJ=y -CONFIG_OF_MDIO=y -CONFIG_OF_NET=y -CONFIG_OF_OVERLAY=y -CONFIG_OF_RESERVED_MEM=y -CONFIG_OF_RESOLVE=y -CONFIG_OLD_SIGSUSPEND3=y -CONFIG_PADATA=y -CONFIG_PARTITION_PERCPU=y -CONFIG_OUTER_CACHE=y -CONFIG_OUTER_CACHE_SYNC=y -CONFIG_PAGE_OFFSET=0xC0000000 -CONFIG_PCI=y -CONFIG_PCIEAER=y -CONFIG_PCIEPORTBUS=y -CONFIG_PCIE_BRCMSTB=y -CONFIG_PCIE_PME=y -CONFIG_PCI_DOMAINS=y -CONFIG_PCI_DOMAINS_GENERIC=y -CONFIG_PCI_MSI=y -CONFIG_PCI_MSI_IRQ_DOMAIN=y -CONFIG_PGTABLE_LEVELS=3 -CONFIG_PHYLIB=y -CONFIG_PHYS_ADDR_T_64BIT=y -CONFIG_PINCTRL=y -CONFIG_PINCTRL_BCM2835=y -CONFIG_PLUGIN_HOSTCC="g++" -CONFIG_PM=y -CONFIG_PM_CLK=y -# CONFIG_PM_DEBUG is not set -CONFIG_PM_GENERIC_DOMAINS=y -CONFIG_PM_GENERIC_DOMAINS_OF=y -CONFIG_PM_GENERIC_DOMAINS_SLEEP=y -CONFIG_PM_SLEEP=y -CONFIG_PM_SLEEP_SMP=y -CONFIG_POWER_RESET=y -CONFIG_POWER_RESET_GPIO=y -CONFIG_POWER_SUPPLY=y -CONFIG_PRINTK_TIME=y -CONFIG_PROC_PAGE_MONITOR=y -CONFIG_PWM=y -CONFIG_PWM_BCM2835=y -# CONFIG_PWM_STMPE is not set -CONFIG_PWM_SYSFS=y -CONFIG_QUEUED_RWLOCKS=y -CONFIG_QUEUED_SPINLOCKS=y -# CONFIG_RANDOMIZE_BASE is not set -CONFIG_RAS=y -CONFIG_RASPBERRYPI_FIRMWARE=y -CONFIG_RASPBERRYPI_POWER=y -CONFIG_RATIONAL=y -CONFIG_RAW_DRIVER=y -CONFIG_RCU_NEED_SEGCBLIST=y -CONFIG_RCU_STALL_COMMON=y -CONFIG_REFCOUNT_FULL=y -CONFIG_REGMAP=y -CONFIG_REGMAP_MMIO=y -CONFIG_REGULATOR=y -CONFIG_REGULATOR_GPIO=y -CONFIG_REGULATOR_FIXED_VOLTAGE=y -CONFIG_RESET_CONTROLLER=y -CONFIG_RFS_ACCEL=y -# CONFIG_RPIVID_MEM is not set -CONFIG_RPS=y -CONFIG_RWSEM_SPIN_ON_OWNER=y -CONFIG_RWSEM_XCHGADD_ALGORITHM=y -CONFIG_SCSI=y -CONFIG_SCSI_ISCSI_ATTRS=y -# CONFIG_SCSI_LOWLEVEL is not set -CONFIG_SCSI_MQ_DEFAULT=y -# CONFIG_SCSI_PROC_FS is not set -CONFIG_SERIAL_8250_BCM2835AUX=y -# CONFIG_SERIAL_8250_DMA is not set -CONFIG_SERIAL_8250_EXTENDED=y -CONFIG_SERIAL_8250_FSL=y -CONFIG_SERIAL_8250_NR_UARTS=1 -CONFIG_SERIAL_8250_RUNTIME_UARTS=0 -CONFIG_SERIAL_8250_SHARE_IRQ=y -CONFIG_SERIAL_AMBA_PL011=y -CONFIG_SERIAL_AMBA_PL011_CONSOLE=y -CONFIG_SERIAL_DEV_BUS=y -# CONFIG_SERIAL_DEV_CTRL_TTYPORT is not set -CONFIG_SERIAL_OF_PLATFORM=y -CONFIG_SETEND_EMULATION=y -CONFIG_SG_POOL=y -CONFIG_SMP=y -CONFIG_SPARSEMEM=y -CONFIG_SPARSEMEM_EXTREME=y -CONFIG_SPARSEMEM_MANUAL=y -CONFIG_SPARSEMEM_VMEMMAP=y -CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y -CONFIG_SPARSE_IRQ=y -CONFIG_SPI=y -# CONFIG_SPI_BCM2835AUX is not set -CONFIG_SPI_MASTER=y -CONFIG_SPI_MEM=y -CONFIG_SPI_SLAVE=y -# CONFIG_SPI_SLAVE_SYSTEM_CONTROL is not set -# CONFIG_SPI_SLAVE_TIME is not set -CONFIG_SRCU=y -CONFIG_STMPE_I2C=y -CONFIG_STMPE_SPI=y -CONFIG_STREAM_PARSER=y -# CONFIG_STRIP_ASM_SYMS is not set -CONFIG_SUSPEND=y -CONFIG_SUSPEND_FREEZER=y -CONFIG_SWIOTLB=y -CONFIG_SWPHY=y -CONFIG_SWP_EMULATION=y -CONFIG_SYSCTL_EXCEPTION_TRACE=y -CONFIG_SYSVIPC_COMPAT=y -CONFIG_SYS_SUPPORTS_HUGETLBFS=y -# CONFIG_TEXTSEARCH is not set -CONFIG_THERMAL=y -CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y -CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=0 -CONFIG_THERMAL_GOV_STEP_WISE=y -CONFIG_THERMAL_OF=y -CONFIG_THREAD_INFO_IN_TASK=y -CONFIG_TICK_CPU_ACCOUNTING=y -CONFIG_TIMER_OF=y -CONFIG_TIMER_PROBE=y -CONFIG_TI_ST=y -CONFIG_TMPFS_POSIX_ACL=y -CONFIG_TREE_RCU=y -CONFIG_TREE_SRCU=y -# CONFIG_UBIFS_FS is not set -CONFIG_UEVENT_HELPER_PATH="" -CONFIG_UNMAP_KERNEL_AT_EL0=y -CONFIG_USB=y -CONFIG_USB_ANNOUNCE_NEW_DEVICES=y -CONFIG_USB_COMMON=y -CONFIG_USB_DWCOTG=y -# CONFIG_USB_EHCI_HCD is not set -CONFIG_USB_LAN78XX=y -CONFIG_USB_NET_DRIVERS=y -CONFIG_USB_NET_SMSC95XX=y -CONFIG_USB_PCI=y -CONFIG_USB_STORAGE=y -CONFIG_USB_SUPPORT=y -CONFIG_USB_UAS=y -CONFIG_USB_USBNET=y -# CONFIG_USB_UHCI_HCD is not set -CONFIG_USB_XHCI_HCD=y -CONFIG_USB_XHCI_PCI=y -CONFIG_USB_XHCI_PLATFORM=y -CONFIG_VMAP_STACK=y -CONFIG_VDSO=y -CONFIG_VT=y -CONFIG_VT_CONSOLE=y -CONFIG_VT_CONSOLE_SLEEP=y -CONFIG_VT_HW_CONSOLE_BINDING=y -CONFIG_WATCHDOG_CORE=y -CONFIG_XPS=y -CONFIG_XZ_DEC_ARM=y -CONFIG_XZ_DEC_BCJ=y -CONFIG_ZONE_DMA32=y diff --git a/root/target/linux/generic/config-4.14 b/root/target/linux/generic/config-4.14 deleted file mode 100644 index 37b428b6..00000000 --- a/root/target/linux/generic/config-4.14 +++ /dev/null @@ -1,5797 +0,0 @@ -# CONFIG_104_QUAD_8 is not set -CONFIG_32BIT=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_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_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_AD5755 is not set -# CONFIG_AD5761 is not set -# CONFIG_AD5764 is not set -# CONFIG_AD5791 is not set -# CONFIG_AD5933 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_AD7298 is not set -# CONFIG_AD7303 is not set -# CONFIG_AD7476 is not set -# CONFIG_AD7606 is not set -# CONFIG_AD7746 is not set -# CONFIG_AD7766 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_AD799X is not set -# CONFIG_AD8366 is not set -# CONFIG_AD8801 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_ADE7753 is not set -# CONFIG_ADE7754 is not set -# CONFIG_ADE7758 is not set -# CONFIG_ADE7759 is not set -# CONFIG_ADE7854 is not set -# CONFIG_ADF4350 is not set -# CONFIG_ADFS_FS is not set -# CONFIG_ADIS16060 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_ADIS16204 is not set -# CONFIG_ADIS16209 is not set -# CONFIG_ADIS16220 is not set -# CONFIG_ADIS16240 is not set -# CONFIG_ADIS16260 is not set -# CONFIG_ADIS16400 is not set -# CONFIG_ADIS16480 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_ADVISE_SYSCALLS=y -# CONFIG_ADXL345_I2C is not set -# CONFIG_ADXL345_SPI 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_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_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_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_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_ALPINE is not set -# CONFIG_ARCH_ARTPEC is not set -# CONFIG_ARCH_ASPEED is not set -# CONFIG_ARCH_AT91 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_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_HAS_DEVMEM_IS_ALLOWED=y -# CONFIG_ARCH_HAS_ILOG2_U32 is not set -# CONFIG_ARCH_HAS_ILOG2_U64 is not set -CONFIG_ARCH_HAS_UBSAN_SANITIZE_ALL=y -# 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_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_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_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_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_PHYS_ADDR_T_64BIT 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_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_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_SHMOBILE_MULTI is not set -# CONFIG_ARCH_SIRF is not set -# CONFIG_ARCH_SOCFPGA is not set -# CONFIG_ARCH_SPRD is not set -# CONFIG_ARCH_STI is not set -# CONFIG_ARCH_STRATIX10 is not set -# CONFIG_ARCH_SUNXI 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_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_WANTS_UBSAN_NO_NULL 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_ARM64_ERRATUM_1024718 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_RELOC_TEST is not set -CONFIG_ARM64_SW_TTBR0_PAN=y -# CONFIG_ARM_APPENDED_DTB is not set -# CONFIG_ARM_ARCH_TIMER 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_CCN 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_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_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_GIC_MAX_NR=1 -# CONFIG_ARM_KERNMEM_PERMS is not set -# CONFIG_ARM_KIRKWOOD_CPUFREQ is not set -# CONFIG_ARM_KPROBES_TEST 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_PTDUMP is not set -# CONFIG_ARM_SBSA_WATCHDOG is not set -# CONFIG_ARM_SCPI_PROTOCOL 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_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_GENERIC 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_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_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_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_GENERIC is not set -# CONFIG_BACKLIGHT_GPIO is not set -# CONFIG_BACKLIGHT_LCD_SUPPORT 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_RPI is not set -# CONFIG_BACKLIGHT_SAHARA is not set -# CONFIG_BACKTRACE_SELF_TEST 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_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_BCM63XX is not set -# CONFIG_BCM63XX_PHY is not set -# CONFIG_BCM7038_WDT is not set -# CONFIG_BCM7XXX_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_FLAT is not set -# CONFIG_BINFMT_MISC is not set -CONFIG_BINFMT_SCRIPT=y -CONFIG_BITREVERSE=y -# CONFIG_BLK_CMDLINE_PARSER is not set -# CONFIG_BLK_CPQ_CISS_DA is not set -# CONFIG_BLK_CPQ_DA 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_HD 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_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_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_BMG160 is not set -# CONFIG_BMI160_I2C is not set -# CONFIG_BMI160_SPI is not set -# CONFIG_BMIPS_GENERIC is not set -# CONFIG_BMP085 is not set -# CONFIG_BMP085_I2C is not set -# CONFIG_BMP085_SPI is not set -# CONFIG_BMP280 is not set -# CONFIG_BNA is not set -# CONFIG_BNX2 is not set -# CONFIG_BNX2X 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_BOOT_PRINTK_DELAY is not set -CONFIG_BOOT_RAW=y -CONFIG_BPF=y -CONFIG_BPF_JIT=y -# CONFIG_BPF_JIT_ALWAYS_ON 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_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_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_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_HCIBTUART is not set -# CONFIG_BT_HCIBTUSB 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_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_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_BUILD_BIN2C is not set -# 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_MCBA_USB 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_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_CB710_CORE is not set -# CONFIG_CC10001_ADC is not set -# CONFIG_CCS811 is not set -CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE=y -# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set -# CONFIG_CC_STACKPROTECTOR is not set -CONFIG_CC_STACKPROTECTOR_NONE=y -# CONFIG_CC_STACKPROTECTOR_REGULAR is not set -# CONFIG_CC_STACKPROTECTOR_STRONG is not set -# CONFIG_CDROM_PKTCDVD is not set -# CONFIG_CEPH_FS is not set -# CONFIG_CEPH_LIB is not set -# CONFIG_CFQ_GROUP_IOSCHED is not set -# CONFIG_CFG80211 is not set -# CONFIG_CFG80211_CERTIFICATION_ONUS is not set -# CONFIG_CGROUPS is not set -# CONFIG_CGROUP_BPF is not set -# CONFIG_CGROUP_DEBUG is not set -# CONFIG_CGROUP_HUGETLB is not set -# CONFIG_CGROUP_NET_CLASSID is not set -# CONFIG_CGROUP_NET_PRIO is not set -# CONFIG_CGROUP_RDMA 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_BQ25890 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_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_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=y -# CONFIG_CIFS_STATS2 is not set -# CONFIG_CIFS_WEAK_PW_HASH is not set -# CONFIG_CIFS_XATTR is not set -# CONFIG_CIO_DAC is not set -# 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_IPROC 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_SI5351 is not set -# CONFIG_COMMON_CLK_SI570 is not set -# CONFIG_COMMON_CLK_VC5 is not set -# CONFIG_COMMON_CLK_VERSATILE 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_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_CPA_DEBUG 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_IDLE is not set -# CONFIG_CPU_IDLE_GOV_MENU is not set -# CONFIG_CPU_IDLE_MULTIPLE_DRIVERS is not set -# CONFIG_CPU_NO_EFFICIENT_FFS is not set -CONFIG_CPU_SW_DOMAIN_PAN=y -# CONFIG_CRAMFS is not set -CONFIG_CRASHLOG=y -# 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_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_AEAD 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_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=y -# CONFIG_CRYPTO_AUTHENC is not set -CONFIG_CRYPTO_BLKCIPHER=y -CONFIG_CRYPTO_BLKCIPHER2=y -# 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_CHACHA20 is not set -# CONFIG_CRYPTO_CHACHA20POLY1305 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_CRCT10DIF is not set -# CONFIG_CRYPTO_CRYPTD is not set -# CONFIG_CRYPTO_CTR is not set -# CONFIG_CRYPTO_CTS is not set -# CONFIG_CRYPTO_DEFLATE is not set -# CONFIG_CRYPTO_DES 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_TDES is not set -# CONFIG_CRYPTO_DEV_CAVIUM_ZIP is not set -# CONFIG_CRYPTO_DEV_CCP 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_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_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_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_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_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_NULL 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_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_SHA256 is not set -# CONFIG_CRYPTO_SHA3 is not set -# CONFIG_CRYPTO_SHA512 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_HASH is not set -# CONFIG_CRYPTO_USER_API_RNG 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_ZLIB is not set -# CONFIG_CS5535_MFGPT is not set -# CONFIG_CS89x0 is not set -# CONFIG_CUSE is not set -# CONFIG_CW1200 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_FORCE_WEAK_PER_CPU is not set -CONFIG_DEBUG_FS=y -# 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_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_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_PREEMPT is not set -# CONFIG_DEBUG_RODATA_TEST is not set -# CONFIG_DEBUG_RT_MUTEXES 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_BCM63XX is not set -# CONFIG_DEBUG_VIRTUAL is not set -# CONFIG_DEBUG_VM 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_CFQ is not set -CONFIG_DEFAULT_DEADLINE=y -CONFIG_DEFAULT_HOSTNAME="(none)" -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_TCP_CONG="cubic" -CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" -# CONFIG_DELL_LAPTOP is not set -# CONFIG_DELL_RBTN 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_DLM is not set -# CONFIG_DM9000 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_ENGINE is not set -# CONFIG_DMA_FENCE_TRACE is not set -# 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_DEBUG is not set -# CONFIG_DM_DELAY 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_VERITY 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_DP83848_PHY is not set -# CONFIG_DP83867_PHY is not set -# CONFIG_DPOT_DAC 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_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_CIRRUS_QEMU is not set -# CONFIG_DRM_DEBUG_MM is not set -# CONFIG_DRM_DEBUG_MM_SELFTEST is not set -# CONFIG_DRM_DP_AUX_CHARDEV 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_FSL_DCU 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_TDA998X is not set -# CONFIG_DRM_I2C_SIL164 is not set -# CONFIG_DRM_I915 is not set -# CONFIG_DRM_LEGACY is not set -# CONFIG_DRM_LIB_RANDOM is not set -# CONFIG_DRM_LOAD_EDID_FIRMWARE is not set -# CONFIG_DRM_LVDS_ENCODER is not set -# CONFIG_DRM_MALI_DISPLAY 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_NXP_PTN3460 is not set -# CONFIG_DRM_OMAP is not set -# CONFIG_DRM_PANEL_INNOLUX_P079ZCA is not set -# CONFIG_DRM_PANEL_JDI_LT070ME05000 is not set -# CONFIG_DRM_PANEL_LG_LG4573 is not set -# CONFIG_DRM_PANEL_LVDS is not set -# CONFIG_DRM_PANEL_PANASONIC_VVX10F034N00 is not set -# CONFIG_DRM_PANEL_RASPBERRYPI_TOUCHSCREEN is not set -# CONFIG_DRM_PANEL_SAMSUNG_LD9040 is not set -# CONFIG_DRM_PANEL_SAMSUNG_S6E3HA2 is not set -# CONFIG_DRM_PANEL_SAMSUNG_S6E8AA0 is not set -# CONFIG_DRM_PANEL_SHARP_LQ101R1SX01 is not set -# CONFIG_DRM_PANEL_SHARP_LS043T1LE01 is not set -# CONFIG_DRM_PANEL_SITRONIX_ST7789V is not set -# CONFIG_DRM_PARADE_PS8622 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_SII902X is not set -# CONFIG_DRM_SIL_SII8620 is not set -# CONFIG_DRM_STI is not set -# CONFIG_DRM_STM is not set -# CONFIG_DRM_SUN4I is not set -# CONFIG_DRM_TILCDC is not set -# CONFIG_DRM_TINYDRM is not set -# CONFIG_DRM_TI_TFP410 is not set -# CONFIG_DRM_TOSHIBA_TC358767 is not set -# CONFIG_DRM_UDL is not set -# CONFIG_DRM_VBOXVIDEO is not set -# CONFIG_DRM_VGEM is not set -# CONFIG_DRM_VIRTIO_GPU is not set -# CONFIG_DRM_VMWGFX is not set -# CONFIG_DS1682 is not set -# CONFIG_DS1803 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_AU8522_V4L is not set -# CONFIG_DVB_CORE is not set -# CONFIG_DVB_DUMMY_FE is not set -# CONFIG_DVB_TUNER_DIB0070 is not set -# CONFIG_DVB_TUNER_DIB0090 is not set -# CONFIG_DWC_XLGMAC 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_DMAC is not set -# CONFIG_DW_DMAC_PCI is not set -# CONFIG_DW_WATCHDOG is not set -# CONFIG_DYNAMIC_DEBUG is not set -# 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_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_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_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_ET131X is not set -CONFIG_ETHERNET=y -# CONFIG_ETHOC is not set -CONFIG_EVENTFD=y -CONFIG_EXPERT=y -CONFIG_EXPORTFS=y -# CONFIG_EXPORTFS_BLOCK_OPS is not set -# CONFIG_EXT2_FS is not set -# CONFIG_EXT2_FS_XATTR is not set -# 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_AXP288 is not set -# CONFIG_EXTCON_GPIO is not set -# CONFIG_EXTCON_INTEL_INT3496 is not set -# CONFIG_EXTCON_MAX3355 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_FAULT_INJECTION is not set -# CONFIG_F2FS_FS is not set -# CONFIG_F2FS_FS_ENCRYPTION is not set -# CONFIG_F2FS_FS_POSIX_ACL is not set -# CONFIG_F2FS_IO_TRACE is not set -# CONFIG_FAIR_GROUP_SCHED is not set -# CONFIG_FANOTIFY 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_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_FILE_LOCKING=y -# 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_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_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_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_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_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_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_USER_HELPER=y -CONFIG_FW_LOADER_USER_HELPER_FALLBACK=y -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_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_PROBE=y -CONFIG_GENERIC_NET_UTILS=y -# CONFIG_GENERIC_PHY is not set -# 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_GOLDFISH is not set -# CONFIG_GOOGLE_FIRMWARE is not set -# CONFIG_GP2AP020A00F is not set -# CONFIG_GPIOLIB 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_ALTERA is not set -# CONFIG_GPIO_AMD8111 is not set -# CONFIG_GPIO_AMDPT is not set -# CONFIG_GPIO_BCM_KONA is not set -# CONFIG_GPIO_BT8XX 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_ICH is not set -# CONFIG_GPIO_IT87 is not set -# CONFIG_GPIO_LYNXPOINT is not set -# CONFIG_GPIO_MAX7300 is not set -# CONFIG_GPIO_MAX7301 is not set -# CONFIG_GPIO_MAX732X 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_PCF857X is not set -# CONFIG_GPIO_PCH 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_SCH is not set -# CONFIG_GPIO_SCH311X is not set -# CONFIG_GPIO_SX150X is not set -# CONFIG_GPIO_SYSCON is not set -# CONFIG_GPIO_SYSFS is not set -# 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_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_HAMACHI is not set -# CONFIG_HAMRADIO is not set -# CONFIG_HAPPYMEAL is not set -CONFIG_HARDEN_BRANCH_PREDICTOR=y -CONFIG_HARDENED_USERCOPY=y -# CONFIG_HARDENED_USERCOPY_PAGESPAN is not set -# CONFIG_HARDLOCKUP_DETECTOR is not set -# CONFIG_HAVE_AOUT is not set -CONFIG_HAVE_ARCH_HARDENED_USERCOPY=y -# CONFIG_HAVE_ARCH_HASH is not set -CONFIG_HAVE_ARCH_MMAP_RND_BITS=y -# CONFIG_HAVE_ARCH_VMAP_STACK is not set -CONFIG_HAVE_ARCH_WITHIN_STACK_FRAMES=y -# CONFIG_HAVE_ARM_ARCH_TIMER is not set -CONFIG_HAVE_EXIT_THREAD=y -CONFIG_HAVE_GCC_PLUGINS=y -CONFIG_HAVE_HARDENED_USERCOPY_ALLOCATOR=y -CONFIG_HAVE_KERNEL_BZIP2=y -CONFIG_HAVE_KERNEL_CAT=y -CONFIG_HAVE_KERNEL_GZIP=y -CONFIG_HAVE_KERNEL_LZ4=y -CONFIG_HAVE_KERNEL_LZMA=y -CONFIG_HAVE_KERNEL_LZO=y -CONFIG_HAVE_KERNEL_XZ=y -CONFIG_HAVE_KPROBES=y -CONFIG_HAVE_KRETPROBES=y -CONFIG_HAVE_NMI=y -# CONFIG_HCALL_STATS is not set -# CONFIG_HDC100X 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_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_CHERRY is not set -# CONFIG_HID_CHICONY is not set -# CONFIG_HID_CMEDIA is not set -# CONFIG_HID_CORSAIR is not set -# CONFIG_HID_CP2112 is not set -# CONFIG_HID_CYPRESS is not set -# CONFIG_HID_DRAGONRISE 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_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_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_MAGICMOUSE is not set -# CONFIG_HID_MAYFLASH 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_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_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_UCLOGIC is not set -# CONFIG_HID_UDRAW_PS3 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_HISI_FEMAC is not set -# CONFIG_HIX5HD2_GMAC 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_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_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_CAVIUM 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_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 is not set -# CONFIG_HW_RANDOM_VIA is not set -# CONFIG_HW_RANDOM_VIRTIO 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=100 -CONFIG_HZ_100=y -# 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_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_MLXCPLD is not set -# CONFIG_I2C_MPC 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_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_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_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_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_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_IFB is not set -# CONFIG_IGB is not set -# CONFIG_IGBVF is not set -# CONFIG_IIO is not set -# CONFIG_IIO_BUFFER_CB is not set -# CONFIG_IIO_CONFIGFS is not set -CONFIG_IIO_CONSUMERS_PER_TRIGGER=2 -# CONFIG_IIO_INTERRUPT_TRIGGER is not set -# CONFIG_IIO_MUX is not set -# CONFIG_IIO_PERIODIC_RTC_TRIGGER 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_IKCONFIG is not set -# CONFIG_IKCONFIG_PROC 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_INET=y -# CONFIG_INET6_AH is not set -# CONFIG_INET6_ESP 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_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_INIT_ENV_ARG_LIMIT=32 -# CONFIG_INLINE_READ_LOCK is not set -# CONFIG_INLINE_READ_LOCK_BH is not set -# CONFIG_INLINE_READ_LOCK_IRQ is not set -# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set -# CONFIG_INLINE_READ_TRYLOCK is not set -CONFIG_INLINE_READ_UNLOCK=y -# CONFIG_INLINE_READ_UNLOCK_BH is not set -CONFIG_INLINE_READ_UNLOCK_IRQ=y -# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set -# CONFIG_INLINE_SPIN_LOCK is not set -# CONFIG_INLINE_SPIN_LOCK_BH is not set -# CONFIG_INLINE_SPIN_LOCK_IRQ is not set -# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set -# CONFIG_INLINE_SPIN_TRYLOCK is not set -# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set -# CONFIG_INLINE_SPIN_UNLOCK_BH is not set -CONFIG_INLINE_SPIN_UNLOCK_IRQ=y -# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set -# CONFIG_INLINE_WRITE_LOCK is not set -# CONFIG_INLINE_WRITE_LOCK_BH is not set -# CONFIG_INLINE_WRITE_LOCK_IRQ is not set -# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set -# CONFIG_INLINE_WRITE_TRYLOCK is not set -CONFIG_INLINE_WRITE_UNLOCK=y -# CONFIG_INLINE_WRITE_UNLOCK_BH is not set -CONFIG_INLINE_WRITE_UNLOCK_IRQ=y -# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set -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_IDEAPAD_SLIDEBAR is not set -# CONFIG_INPUT_IMS_PCU 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_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_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_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_CHTWC is not set -# CONFIG_INTEL_TH is not set -# CONFIG_INTEL_VBTN is not set -# CONFIG_INTEL_XWAY_PHY is not set -# CONFIG_INTERVAL_TREE_TEST 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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_KUSER_HELPERS=y -# CONFIG_KVM_AMD is not set -# CONFIG_KVM_GUEST is not set -# CONFIG_KVM_INTEL 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_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_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_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_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_DAC124S085 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_LM355x is not set -# CONFIG_LEDS_LM3642 is not set -# CONFIG_LEDS_LP3944 is not set -# CONFIG_LEDS_LP3952 is not set -# CONFIG_LEDS_LP5521 is not set -# CONFIG_LEDS_LP5523 is not set -# CONFIG_LEDS_LP5562 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_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_SYSCON is not set -# CONFIG_LEDS_TCA6507 is not set -# CONFIG_LEDS_TLC591XX is not set -CONFIG_LEDS_TRIGGERS=y -# 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 is not set -# CONFIG_LEDS_TRIGGER_IDE_DISK is not set -# 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_TIMER=y -# CONFIG_LEDS_TRIGGER_TRANSIENT 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_LIQUIDIO is not set -# CONFIG_LIQUIDIO_VF is not set -# CONFIG_LIRC_STAGING 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_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_LTC2471 is not set -# CONFIG_LTC2485 is not set -# CONFIG_LTC2497 is not set -# CONFIG_LTC2632 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_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_JAZZ is not set -# CONFIG_MACH_JZ4740 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_MAILBOX 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_MAX1363 is not set -# CONFIG_MAX30100 is not set -# CONFIG_MAX30102 is not set -# CONFIG_MAX44000 is not set -# CONFIG_MAX517 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_MC3230 is not set -# CONFIG_MCB is not set -# CONFIG_MCP320X is not set -# CONFIG_MCP3422 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_DEVICE is not set -# CONFIG_MDIO_HISI_FEMAC is not set -# CONFIG_MDIO_OCTEON is not set -# CONFIG_MDIO_THUNDER 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_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_USB_SUPPORT is not set -# CONFIG_MEGARAID_LEGACY is not set -# CONFIG_MEGARAID_NEWGEN is not set -# CONFIG_MEGARAID_SAS is not set -CONFIG_MEMBARRIER=y -# CONFIG_MEMORY is not set -# CONFIG_MEMORY_FAILURE 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_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_HI6421_PMIC is not set -# CONFIG_MFD_INTEL_QUARK_I2C_GPIO is not set -# CONFIG_MFD_JANZ_CMODIO is not set -# CONFIG_MFD_KEMPLD is not set -# CONFIG_MFD_LM3533 is not set -# CONFIG_MFD_LP3943 is not set -# CONFIG_MFD_LP8788 is not set -# CONFIG_MFD_MAX14577 is not set -# CONFIG_MFD_MAX77620 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_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_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_STMPE 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_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_MICREL_KS8995MA is not set -# CONFIG_MICREL_PHY is not set -# CONFIG_MICROCHIP_KSZ is not set -# CONFIG_MICROCHIP_PHY is not set -# CONFIG_MICROSEMI_PHY is not set -# CONFIG_MIGRATION is not set -CONFIG_MII=y -# 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_GENERIC 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_FILESYSTEMS=y -# 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_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_DEBUG is not set -# CONFIG_MMC_DW 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_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_MSM is not set -# CONFIG_MMC_SDHCI_OF_ARASAN is not set -# CONFIG_MMC_SDHCI_OF_AT91 is not set -# CONFIG_MMC_SDHCI_OF_ESDHC is not set -# CONFIG_MMC_SDHCI_OF_HLWD 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_TEST 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_MODULES=y -# 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_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_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_MSDOS_FS is not set -CONFIG_MSDOS_PARTITION=y -# CONFIG_MSI_BITMAP_SELFTEST is not set -# CONFIG_MSI_LAPTOP 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_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_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_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_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_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_OF=y -# CONFIG_MTD_PHYSMAP_OF_GEMINI is not set -# CONFIG_MTD_PHYSMAP_OF_VERSATILE is not set -# CONFIG_MTD_PLATRAM is not set -# CONFIG_MTD_PMC551 is not set -# CONFIG_MTD_RAM 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_SLRAM is not set -# CONFIG_MTD_SM_COMMON is not set -# CONFIG_MTD_SPINAND_MT29F 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_BRNIMAGE_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_UIMAGE_SPLIT is not set -# CONFIG_MTD_VIRT_CONCAT 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_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_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_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_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_GACT 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_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_BCM_SF2 is not set -# CONFIG_NET_DSA_LOOP 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_QCA8K 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_DSA is not set -# CONFIG_NET_DSA_TAG_EDSA 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_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_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_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_CBQ 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_FIFO=y -# CONFIG_NET_SCH_FQ is not set -CONFIG_NET_SCH_FQ_CODEL=y -# 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_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_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_CAVIUM=y -CONFIG_NET_VENDOR_CHELSIO=y -CONFIG_NET_VENDOR_CIRRUS=y -CONFIG_NET_VENDOR_CISCO=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_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_MYRI=y -CONFIG_NET_VENDOR_NATSEMI=y -CONFIG_NET_VENDOR_NETRONOME=y -CONFIG_NET_VENDOR_NVIDIA=y -CONFIG_NET_VENDOR_OKI=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_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_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_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_RT is not set -# CONFIG_NFT_SET_BITMAP is not set -# CONFIG_NF_CONNTRACK is not set -# CONFIG_NF_CONNTRACK_AMANDA is not set -CONFIG_NF_CONNTRACK_CUSTOM=2 -# 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_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_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_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_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 is not set -# CONFIG_NF_NAT_MASQUERADE_IPV6 is not set -# 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_NETDEV 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_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_NOP_USB_XCEIV is not set -# CONFIG_NORTEL_HERMES is not set -# CONFIG_NOTIFIER_ERROR_INJECTION 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_NVM is not set -# CONFIG_NVMEM is not set -# CONFIG_NVMEM_BCM_OCOTP is not set -# CONFIG_NVMEM_IMX_OCOTP 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_N_GSM is not set -# CONFIG_OABI_COMPAT is not set -# CONFIG_OBS600 is not set -# CONFIG_OCFS2_FS is not set -# CONFIG_OF_OVERLAY is not set -# 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 is not set -# 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_REDIRECT_DIR is not set -# 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_PAGE_EXTENSION is not set -# CONFIG_PAGE_OWNER is not set -# CONFIG_PAGE_POISONING 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_INJECT is not set -# CONFIG_PCIEASPM is not set -# CONFIG_PCIEPORTBUS is not set -# CONFIG_PCIE_ALTERA is not set -# CONFIG_PCIE_ARMADA_8K is not set -# CONFIG_PCIE_DPC is not set -# CONFIG_PCIE_DW_PLAT is not set -# CONFIG_PCIE_ECRC is not set -# CONFIG_PCIE_IPROC is not set -# CONFIG_PCIE_KIRIN is not set -# CONFIG_PCIE_PTM 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_LAYERSCAPE is not set -# CONFIG_PCI_MSI is not set -# CONFIG_PCI_PASID 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_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_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_CPCAP_USB is not set -# CONFIG_PHY_EXYNOS_DP_VIDEO is not set -# CONFIG_PHY_EXYNOS_MIPI_VIDEO 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_SAMSUNG_USB2 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_EXYNOS is not set -# CONFIG_PINCTRL_EXYNOS5440 is not set -# CONFIG_PINCTRL_MCP23S08 is not set -# CONFIG_PINCTRL_MSM8X74 is not set -CONFIG_PINCTRL_SINGLE=y -# CONFIG_PINCTRL_SX150X is not set -CONFIG_PINMUX=y -# CONFIG_PKCS7_MESSAGE_PARSER 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_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_PM_AUTOSLEEP 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_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_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_PREEMPT_NONE=y -# CONFIG_PREEMPT_TRACER is not set -# CONFIG_PREEMPT_VOLUNTARY is not set -CONFIG_PREVENT_FIRMWARE_BUILD=y -CONFIG_PRINTK=y -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=y -CONFIG_PROC_SYSCTL=y -# 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_REPEATEDLY is not set -# CONFIG_PSAMPLE is not set -# CONFIG_PSB6970_PHY is not set -# CONFIG_PSTORE is not set -# CONFIG_PTP_1588_CLOCK 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_PUBLIC_KEY_ALGO_RSA is not set -# CONFIG_PWM 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_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_QSEMI_PHY is not set -# CONFIG_QUEUED_LOCK_STAT 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_RAID_ATTRS is not set -# CONFIG_RALINK is not set -# CONFIG_RANDOM32_SELFTEST 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_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_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_READABLE_ASM is not set -# CONFIG_REALTEK_PHY is not set -# CONFIG_REDWOOD is not set -# CONFIG_REFCOUNT_FULL 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_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_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_MAX8649 is not set -# CONFIG_REGULATOR_MAX8660 is not set -# CONFIG_REGULATOR_MAX8952 is not set -# CONFIG_REGULATOR_MAX8973 is not set -# CONFIG_REGULATOR_MT6311 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_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 is not set -# CONFIG_REISERFS_PROC_INFO is not set -# CONFIG_RELAY is not set -# CONFIG_RELOCATABLE is not set -# CONFIG_REMOTEPROC is not set -# CONFIG_RESET_ATH79 is not set -# CONFIG_RESET_BERLIN is not set -# CONFIG_RESET_CONTROLLER is not set -# CONFIG_RESET_IMX7 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_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_RPR0521 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_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_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_ISL12057 is not set -# CONFIG_RTC_DRV_ISL1208 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_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_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_RV3029C2 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_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_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_INIC162X is not set -# 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_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_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_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_SECCOMP is not set -CONFIG_SECTION_MISMATCH_WARN_ONLY=y -# CONFIG_SECURITY is not set -# CONFIG_SECURITYFS is not set -CONFIG_SECURITY_DMESG_RESTRICT=y -CONFIG_SELECT_MEMORY_MODEL=y -# 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_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_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_BH1770 is not set -# CONFIG_SENSORS_BH1780 is not set -# CONFIG_SENSORS_CORETEMP is not set -# CONFIG_SENSORS_DELL_SMM is not set -# CONFIG_SENSORS_DME1737 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_IR35221 is not set -# CONFIG_SENSORS_ISL29018 is not set -# CONFIG_SENSORS_ISL29028 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_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_MAX1111 is not set -# CONFIG_SENSORS_MAX16064 is not set -# CONFIG_SENSORS_MAX16065 is not set -# CONFIG_SENSORS_MAX1619 is not set -# CONFIG_SENSORS_MAX1668 is not set -# CONFIG_SENSORS_MAX197 is not set -# CONFIG_SENSORS_MAX20751 is not set -# CONFIG_SENSORS_MAX31722 is not set -# CONFIG_SENSORS_MAX31790 is not set -# CONFIG_SENSORS_MAX34440 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_NCT6683 is not set -# CONFIG_SENSORS_NCT6775 is not set -# CONFIG_SENSORS_NCT7802 is not set -# CONFIG_SENSORS_NCT7904 is not set -# CONFIG_SENSORS_NSA320 is not set -# CONFIG_SENSORS_NTC_THERMISTOR 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_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_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_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_XGENE is not set -# CONFIG_SENSORS_ZL6100 is not set -CONFIG_SERIAL_8250=y -# 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_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_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_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_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_IP32 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_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_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_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_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_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_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_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_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_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_AK4104 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_ALC5623 is not set -# CONFIG_SND_SOC_AMD_ACP is not set -# CONFIG_SND_SOC_AU1XAUDIO is not set -# CONFIG_SND_SOC_AU1XPSC 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_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_CS4349 is not set -# CONFIG_SND_SOC_CS53L30 is not set -# CONFIG_SND_SOC_DIO2125 is not set -# CONFIG_SND_SOC_ES7134 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_ESAI 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_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_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_CHT_BSW_MAX98090_TI_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_KBL_RT5663_MAX98927_MACH is not set -# CONFIG_SND_SOC_INTEL_KBL_RT5663_RT5514_MAX98927_MACH 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_SST is not set -# CONFIG_SND_SOC_MAX98504 is not set -# CONFIG_SND_SOC_MAX9860 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_MT8173 is not set -# CONFIG_SND_SOC_NAU8540 is not set -# CONFIG_SND_SOC_NAU8810 is not set -# CONFIG_SND_SOC_NAU8824 is not set -# CONFIG_SND_SOC_PCM1681 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_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_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_SIRF_AUDIO_CODEC is not set -# CONFIG_SND_SOC_SPDIF 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_TAS5086 is not set -# CONFIG_SND_SOC_TAS571X is not set -# CONFIG_SND_SOC_TAS5720 is not set -# CONFIG_SND_SOC_TFA9879 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_TLV320AIC3X is not set -# CONFIG_SND_SOC_TPA6130A2 is not set -# CONFIG_SND_SOC_TS3A227E 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_WM8804_I2C is not set -# CONFIG_SND_SOC_WM8804_SPI is not set -# CONFIG_SND_SOC_WM8903 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_XTFPGA_I2S 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_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_YMFPCI is not set -# CONFIG_SNI_RM 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_SOUND_OSS_CORE 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_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_LM70_LLP is not set -# CONFIG_SPI_LOOPBACK_TEST is not set -# CONFIG_SPI_MASTER is not set -# CONFIG_SPI_MPC52xx is not set -# CONFIG_SPI_MPC52xx_PSC 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_ROCKCHIP is not set -# CONFIG_SPI_S3C64XX is not set -# CONFIG_SPI_SC18IS602 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_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_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_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_SUN4I_GPADC 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_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_SPI_DRIVER is not set -# CONFIG_SWCONFIG_LEDS is not set -# CONFIG_SW_SYNC is not set -# CONFIG_SX9500 is not set -# CONFIG_SXGBE_ETH is not set -# CONFIG_SYNCLINK_CS is not set -# CONFIG_SYNC_FILE is not set -# CONFIG_SYNOPSYS_DWC_ETH_QOS 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_TASK_XACCT is not set -# CONFIG_TC35815 is not set -# CONFIG_TCG_ATMEL is not set -# CONFIG_TCG_CRB 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_BITMAP is not set -# CONFIG_TEST_BPF is not set -# CONFIG_TEST_FIRMWARE is not set -# CONFIG_TEST_HASH is not set -# CONFIG_TEST_HEXDUMP 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_POWER is not set -# CONFIG_TEST_PRINTF is not set -# CONFIG_TEST_RHASHTABLE is not set -# CONFIG_TEST_SORT is not set -# CONFIG_TEST_STATIC_KEYS is not set -# CONFIG_TEST_STRING_HELPERS 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_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_WRITABLE_TRIPS is not set -# CONFIG_THINKPAD_ACPI is not set -CONFIG_THIN_ARCHIVES=y -# CONFIG_THRUSTMASTER_FF 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_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_ADS7950 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_CPTS is not set -# CONFIG_TI_DAC7512 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_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_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_CHIPONE_ICN8318 is not set -# CONFIG_TOUCHSCREEN_COLIBRI_VF50 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_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_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_RM_TS is not set -# CONFIG_TOUCHSCREEN_RPI_FT5406 is not set -# CONFIG_TOUCHSCREEN_ROHM_BU21023 is not set -# CONFIG_TOUCHSCREEN_S3C2410 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_ATMEL 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_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_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_KEYS is not set -# CONFIG_TSL2583 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_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_ENCRYPTION is not set -CONFIG_UBIFS_FS_FORMAT4=y -# CONFIG_UBIFS_FS_SECURITY is not set -# CONFIG_UBSAN is not set -# CONFIG_UCB1400_CORE is not set -# CONFIG_UCSI is not set -# CONFIG_UDF_FS is not set -CONFIG_UDF_NLS=y -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_UNIX=y -CONFIG_UNIX98_PTYS=y -# CONFIG_UNIXWARE_DISKLABEL is not set -# CONFIG_UNIX_DIAG is not set -# CONFIG_UNUSED_SYMBOLS is not set -CONFIG_UNMAP_KERNEL_AT_EL0=y -# CONFIG_UPROBES is not set -# CONFIG_UPROBE_EVENTS is not set -# CONFIG_US5182D is not set -# CONFIG_USB 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_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_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_CHAOSKEY is not set -# CONFIG_USB_CHIPIDEA is not set -# CONFIG_USB_CONFIGFS 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_DWC3 is not set -# CONFIG_USB_DWC3_EXYNOS 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_DYNAMIC_MINORS is not set -# CONFIG_USB_EG20T is not set -# CONFIG_USB_EHCI_ATH79 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_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_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_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_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_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_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_FSM 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_RCAR_PHY is not set -# CONFIG_USB_RENESAS_USBHS is not set -# CONFIG_USB_RIO500 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_HCD is not set -# CONFIG_USB_XHCI_TEGRA 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_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_TEST_DRIVERS is not set -# CONFIG_VCNL4000 is not set -# CONFIG_VDSO 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_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_NET is not set -# CONFIG_VHOST_VSOCK is not set -# CONFIG_VIA_RHINE is not set -# CONFIG_VIA_VELOCITY 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_ADV_DEBUG is not set -# CONFIG_VIDEO_AK881X 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_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_EM28XX is not set -# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set -# CONFIG_VIDEO_GO7007 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_IR_I2C is not set -# CONFIG_VIDEO_IVTV is not set -# CONFIG_VIDEO_KS0127 is not set -# CONFIG_VIDEO_M52790 is not set -# CONFIG_VIDEO_ML86V7667 is not set -# CONFIG_VIDEO_MSP3400 is not set -# CONFIG_VIDEO_MT9M111 is not set -# CONFIG_VIDEO_MT9V011 is not set -# CONFIG_VIDEO_MXB is not set -# CONFIG_VIDEO_NOON010PC30 is not set -# CONFIG_VIDEO_OMAP2_VOUT is not set -# CONFIG_VIDEO_OV2640 is not set -# CONFIG_VIDEO_OV2659 is not set -# CONFIG_VIDEO_OV6650 is not set -# CONFIG_VIDEO_OV7640 is not set -# CONFIG_VIDEO_OV7670 is not set -# CONFIG_VIDEO_PVRUSB2 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_SONY_BTF_MPX is not set -# CONFIG_VIDEO_SR030PC30 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_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_ZORAN is not set -# CONFIG_VIRTIO_BALLOON is not set -# CONFIG_VIRTIO_BLK_SCSI is not set -# CONFIG_VIRTIO_INPUT is not set -# CONFIG_VIRTIO_MMIO 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_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_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_SLAVE_BQ27000 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_DS2431 is not set -# CONFIG_W1_SLAVE_DS2433 is not set -# CONFIG_W1_SLAVE_DS2438 is not set -# CONFIG_W1_SLAVE_DS2760 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_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_PRETIMEOUT_GOV is not set -# CONFIG_WATCHDOG_SYSFS 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_WIMAX_GDM72XX 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_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_WL_MEDIATEK is not set -CONFIG_WL_TI=y -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_DEBUG_STATIC_CPU_HAS is not set -# CONFIG_X86_PKG_TEMP_THERMAL is not set -CONFIG_X86_SYSFB=y -# CONFIG_XEN is not set -CONFIG_XFRM=y -# 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_POSIX_ACL is not set -# CONFIG_XFS_QUOTA is not set -# CONFIG_XFS_RT 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_WATCHDOG is not set -# CONFIG_XILINX_ZYNQMP_DMA is not set -# CONFIG_XILLYBUS 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_ZPA2326 is not set -# CONFIG_ZPOOL is not set -# CONFIG_ZRAM is not set -# CONFIG_ZSMALLOC is not set -# CONFIG_ZX_TDM is not set diff --git a/root/target/linux/generic/config-4.19 b/root/target/linux/generic/config-4.19 deleted file mode 100644 index 44f72f2c..00000000 --- a/root/target/linux/generic/config-4.19 +++ /dev/null @@ -1,6136 +0,0 @@ -# CONFIG_104_QUAD_8 is not set -CONFIG_32BIT=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_AD5791 is not set -# CONFIG_AD5933 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_AD7298 is not set -# CONFIG_AD7303 is not set -# CONFIG_AD7476 is not set -# CONFIG_AD7606 is not set -# CONFIG_AD7746 is not set -# CONFIG_AD7766 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_AD799X is not set -# CONFIG_AD8366 is not set -# CONFIG_AD8801 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_ADE7753 is not set -# CONFIG_ADE7754 is not set -# CONFIG_ADE7758 is not set -# CONFIG_ADE7759 is not set -# CONFIG_ADE7854 is not set -# CONFIG_ADF4350 is not set -# CONFIG_ADFS_FS is not set -# CONFIG_ADIS16060 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_ADIS16204 is not set -# CONFIG_ADIS16209 is not set -# CONFIG_ADIS16220 is not set -# CONFIG_ADIS16240 is not set -# CONFIG_ADIS16260 is not set -# CONFIG_ADIS16400 is not set -# CONFIG_ADIS16480 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_ADVISE_SYSCALLS=y -# CONFIG_ADXL345_I2C is not set -# CONFIG_ADXL345_SPI 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_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_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_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_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_ALPINE is not set -# CONFIG_ARCH_ARTPEC is not set -# CONFIG_ARCH_ASPEED is not set -# CONFIG_ARCH_AT91 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_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_HAS_DEVMEM_IS_ALLOWED=y -# CONFIG_ARCH_HAS_ILOG2_U32 is not set -# CONFIG_ARCH_HAS_ILOG2_U64 is not set -CONFIG_ARCH_HAS_UBSAN_SANITIZE_ALL=y -# 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_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_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_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_PHYS_ADDR_T_64BIT 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_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_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_SHMOBILE_MULTI is not set -# CONFIG_ARCH_SIRF is not set -# CONFIG_ARCH_SOCFPGA 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_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_WANTS_UBSAN_NO_NULL 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_ARGON_MEM is not set -# CONFIG_ARM64_ERRATUM_1024718 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_RAS_EXTN is not set -# CONFIG_ARM64_RELOC_TEST is not set -# CONFIG_ARM_APPENDED_DTB is not set -# CONFIG_ARM_ARCH_TIMER 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_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_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_GIC_MAX_NR=1 -# CONFIG_ARM_KERNMEM_PERMS is not set -# CONFIG_ARM_KIRKWOOD_CPUFREQ is not set -# CONFIG_ARM_KPROBES_TEST 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_PTDUMP 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_SPE_PMU 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_ASIX_PHY 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_GENERIC 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_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_GENERIC is not set -# CONFIG_BACKLIGHT_GPIO is not set -# CONFIG_BACKLIGHT_LCD_SUPPORT 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_RPI is not set -# CONFIG_BACKLIGHT_SAHARA is not set -# CONFIG_BACKTRACE_SELF_TEST 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_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_BCM63XX is not set -# CONFIG_BCM63XX_PHY is not set -# CONFIG_BCM7038_WDT is not set -# CONFIG_BCM7XXX_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_IOLATENCY is not set -# CONFIG_BLK_CMDLINE_PARSER is not set -# CONFIG_BLK_CPQ_CISS_DA is not set -# CONFIG_BLK_CPQ_DA 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_HD 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=y -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_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_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_BMP085 is not set -# CONFIG_BMP085_I2C is not set -# CONFIG_BMP085_SPI is not set -# CONFIG_BMP280 is not set -# CONFIG_BNA is not set -# CONFIG_BNX2 is not set -# CONFIG_BNX2X 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_BOOT_PRINTK_DELAY is not set -CONFIG_BOOT_RAW=y -CONFIG_BPF=y -# CONFIG_BPFILTER is not set -CONFIG_BPF_JIT=y -# CONFIG_BPF_JIT_ALWAYS_ON is not set -CONFIG_BPF_STREAM_PARSER=y -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_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_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_HCIBTUART is not set -# CONFIG_BT_HCIBTUSB is not set -# CONFIG_BT_HCIBTUSB_AUTOSUSPEND 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_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_RFCOMM is not set -CONFIG_BT_RFCOMM_TTY=y -# CONFIG_BT_SELFTEST is not set -# CONFIG_BT_WILINK is not set -CONFIG_BUG=y -# CONFIG_BUG_ON_DATA_CORRUPTION is not set -CONFIG_BUILDTIME_EXTABLE_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_MCBA_USB 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_HAS_SANCOV_TRACE_PC=y -CONFIG_CC_HAS_STACKPROTECTOR_NONE=y -CONFIG_CC_IS_GCC=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_CGROUP_BPF is not set -# CONFIG_CGROUP_DEBUG is not set -# CONFIG_CGROUP_NET_CLASSID is not set -# CONFIG_CGROUP_NET_PRIO is not set -# CONFIG_CGROUP_RDMA is not set -# CONFIG_CHARGER_ADP5061 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_BQ25890 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_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_CHASH_STATS is not set -# CONFIG_CHASH_SELFTEST 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=y -# CONFIG_CIFS_STATS2 is not set -# CONFIG_CIFS_WEAK_PW_HASH is not set -# CONFIG_CIFS_XATTR is not set -# 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_IPROC is not set -# CONFIG_COMMON_CLK_MAX9485 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_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_VERSATILE 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_CONFIG_KVM_AMD_SEV 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_CPA_DEBUG 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_IDLE is not set -# CONFIG_CPU_IDLE_GOV_MENU is not set -# CONFIG_CPU_IDLE_MULTIPLE_DRIVERS is not set -# CONFIG_CPU_ISOLATION is not set -# 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_CRASHLOG=y -# 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_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_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=y -# CONFIG_CRYPTO_AUTHENC is not set -CONFIG_CRYPTO_BLKCIPHER=y -CONFIG_CRYPTO_BLKCIPHER2=y -# 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_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_CRCT10DIF is not set -# CONFIG_CRYPTO_CRYPTD is not set -# CONFIG_CRYPTO_CTR is not set -# CONFIG_CRYPTO_CTS is not set -# CONFIG_CRYPTO_DEFLATE is not set -# CONFIG_CRYPTO_DES 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_TDES is not set -# CONFIG_CRYPTO_DEV_CAVIUM_ZIP is not set -# CONFIG_CRYPTO_DEV_CCP 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_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_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_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_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_NULL 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_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_SHA256 is not set -# CONFIG_CRYPTO_SHA3 is not set -# CONFIG_CRYPTO_SHA512 is not set -# CONFIG_CRYPTO_SM3 is not set -# CONFIG_CRYPTO_SM4 is not set -# CONFIG_CRYPTO_SPECK 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_HASH is not set -# CONFIG_CRYPTO_USER_API_RNG 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_ZLIB is not set -# CONFIG_CRYPTO_ZSTD is not set -# CONFIG_CS5535_MFGPT is not set -# CONFIG_CS89x0 is not set -# CONFIG_CUSE is not set -# CONFIG_CW1200 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_FORCE_WEAK_PER_CPU is not set -CONFIG_DEBUG_FS=y -# 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_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_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_PREEMPT is not set -# CONFIG_DEBUG_RODATA 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_SET_MODULE_RONX 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_BCM63XX is not set -# CONFIG_DEBUG_VIRTUAL is not set -# CONFIG_DEBUG_VM 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_CFQ is not set -CONFIG_DEFAULT_DEADLINE=y -CONFIG_DEFAULT_HOSTNAME="(none)" -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_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_DLM is not set -# CONFIG_DM9000 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_ENGINE is not set -# CONFIG_DMA_FENCE_TRACE is not set -# 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_DEBUG is not set -# CONFIG_DM_DELAY 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_DP83TC811_PHY is not set -# CONFIG_DPOT_DAC is not set -CONFIG_DQL=y -# CONFIG_DRAGONRISE_FF is not set -# CONFIG_DRM is not set -# CONFIG_DRM_I915 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_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_CIRRUS_QEMU is not set -# CONFIG_DRM_DEBUG_MM is not set -# CONFIG_DRM_DEBUG_SELFTEST 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_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_LEGACY is not set -# CONFIG_DRM_LIB_RANDOM is not set -# CONFIG_DRM_LOAD_EDID_FIRMWARE is not set -# CONFIG_DRM_LVDS_ENCODER is not set -# CONFIG_DRM_MALI_DISPLAY 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_NXP_PTN3460 is not set -# CONFIG_DRM_OMAP is not set -# CONFIG_DRM_PANEL_ARM_VERSATILE 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_LG_LG4573 is not set -# CONFIG_DRM_PANEL_LVDS is not set -# CONFIG_DRM_PANEL_ORISETECH_OTM8009A is not set -# CONFIG_DRM_PANEL_PANASONIC_VVX10F034N00 is not set -# CONFIG_DRM_PANEL_RASPBERRYPI_TOUCHSCREEN is not set -# CONFIG_DRM_PANEL_RAYDIUM_RM68200 is not set -# CONFIG_DRM_PANEL_SAMSUNG_LD9040 is not set -# CONFIG_DRM_PANEL_SAMSUNG_S6E3HA2 is not set -# CONFIG_DRM_PANEL_SAMSUNG_S6E63J0X03 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_LS043T1LE01 is not set -# CONFIG_DRM_PANEL_SITRONIX_ST7789V is not set -# CONFIG_DRM_PARADE_PS8622 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_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_TILCDC is not set -# CONFIG_DRM_TINYDRM is not set -# CONFIG_DRM_TI_TFP410 is not set -# CONFIG_DRM_TOSHIBA_TC358767 is not set -# CONFIG_DRM_UDL is not set -# CONFIG_DRM_VBOXVIDEO is not set -# CONFIG_DRM_VIRTIO_GPU is not set -# CONFIG_DRM_VGEM 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_AU8522_V4L is not set -# CONFIG_DVB_CORE is not set -# CONFIG_DVB_DUMMY_FE is not set -# CONFIG_DVB_TUNER_DIB0070 is not set -# CONFIG_DVB_TUNER_DIB0090 is not set -# CONFIG_DWC_XLGMAC 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_WATCHDOG is not set -# CONFIG_DYNAMIC_DEBUG is not set -# 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_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_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_EVENTFD=y -CONFIG_EXPERT=y -CONFIG_EXPORTFS=y -# CONFIG_EXPORTFS_BLOCK_OPS is not set -# CONFIG_EXT2_FS is not set -# CONFIG_EXT2_FS_XATTR is not set -# 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_GPIO is not set -# CONFIG_EXTCON_INTEL_INT3496 is not set -# CONFIG_EXTCON_MAX3355 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_FAULT_INJECTION is not set -# CONFIG_F2FS_FS is not set -# CONFIG_F2FS_FS_ENCRYPTION is not set -# CONFIG_F2FS_FS_POSIX_ACL is not set -# CONFIG_F2FS_IO_TRACE is not set -# CONFIG_FAILOVER is not set -# CONFIG_FAIR_GROUP_SCHED is not set -# CONFIG_FANOTIFY is not set -CONFIG_FAT_DEFAULT_CODEPAGE=437 -CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" -# CONFIG_FAT_DEFAULT_UTF8 is not set -CONFIG_FAT_FS=y -# 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_FOREIGN_ENDIAN is not set -# CONFIG_FB_FLEX 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_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_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_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_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_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_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_USER_HELPER=y -CONFIG_FW_LOADER_USER_HELPER_FALLBACK=y -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_GCC_VERSION=70400 -# 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_PROBE=y -CONFIG_GENERIC_NET_UTILS=y -# CONFIG_GENERIC_PHY is not set -# 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_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_ALTERA is not set -# CONFIG_GPIO_AMD8111 is not set -# CONFIG_GPIO_AMDPT is not set -# CONFIG_GPIO_BCM_KONA is not set -# CONFIG_GPIO_BT8XX 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_HLWD is not set -# CONFIG_GPIO_ICH is not set -# CONFIG_GPIO_IT87 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_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_SCH is not set -# CONFIG_GPIO_SCH311X is not set -# CONFIG_GPIO_SX150X is not set -# CONFIG_GPIO_SYSCON is not set -# CONFIG_GPIO_SYSFS is not set -# 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_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_HAVE_AOUT is not set -CONFIG_HAVE_ARCH_HARDENED_USERCOPY=y -# CONFIG_HAVE_ARCH_HASH is not set -CONFIG_HAVE_ARCH_MMAP_RND_BITS=y -# CONFIG_HAVE_ARCH_VMAP_STACK is not set -CONFIG_HAVE_ARCH_WITHIN_STACK_FRAMES=y -# CONFIG_HAVE_ARM_ARCH_TIMER is not set -CONFIG_HAVE_EXIT_THREAD=y -CONFIG_HAVE_GCC_PLUGINS=y -CONFIG_HAVE_HARDENED_USERCOPY_ALLOCATOR=y -CONFIG_HAVE_KERNEL_BZIP2=y -CONFIG_HAVE_KERNEL_CAT=y -CONFIG_HAVE_KERNEL_GZIP=y -CONFIG_HAVE_KERNEL_LZ4=y -CONFIG_HAVE_KERNEL_LZMA=y -CONFIG_HAVE_KERNEL_LZO=y -CONFIG_HAVE_KERNEL_XZ=y -CONFIG_HAVE_KPROBES=y -CONFIG_HAVE_KRETPROBES=y -CONFIG_HAVE_NMI=y -CONFIG_HAVE_STACKPROTECTOR=y -# CONFIG_HCALL_STATS is not set -# CONFIG_HDC100X 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_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_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_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_MAGICMOUSE is not set -# CONFIG_HID_MAYFLASH 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_UCLOGIC is not set -# CONFIG_HID_UDRAW_PS3 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_FEMAC is not set -# CONFIG_HIX5HD2_GMAC 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_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_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_CAVIUM 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_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 is not set -# CONFIG_HW_RANDOM_VIA is not set -# CONFIG_HW_RANDOM_VIRTIO 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=100 -CONFIG_HZ_100=y -# 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_MLXCPLD is not set -# CONFIG_I2C_MPC 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_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_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_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_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_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_IIO is not set -# CONFIG_IIO_BUFFER_CB 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_IKCONFIG is not set -# CONFIG_IKCONFIG_PROC 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_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_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_INIT_ENV_ARG_LIMIT=32 -# CONFIG_INLINE_READ_LOCK is not set -# CONFIG_INLINE_READ_LOCK_BH is not set -# CONFIG_INLINE_READ_LOCK_IRQ is not set -# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set -# CONFIG_INLINE_READ_TRYLOCK is not set -CONFIG_INLINE_READ_UNLOCK=y -# CONFIG_INLINE_READ_UNLOCK_BH is not set -CONFIG_INLINE_READ_UNLOCK_IRQ=y -# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set -# CONFIG_INLINE_SPIN_LOCK is not set -# CONFIG_INLINE_SPIN_LOCK_BH is not set -# CONFIG_INLINE_SPIN_LOCK_IRQ is not set -# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set -# CONFIG_INLINE_SPIN_TRYLOCK is not set -# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set -# CONFIG_INLINE_SPIN_UNLOCK_BH is not set -CONFIG_INLINE_SPIN_UNLOCK_IRQ=y -# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set -# CONFIG_INLINE_WRITE_LOCK is not set -# CONFIG_INLINE_WRITE_LOCK_BH is not set -# CONFIG_INLINE_WRITE_LOCK_IRQ is not set -# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set -# CONFIG_INLINE_WRITE_TRYLOCK is not set -CONFIG_INLINE_WRITE_UNLOCK=y -# CONFIG_INLINE_WRITE_UNLOCK_BH is not set -CONFIG_INLINE_WRITE_UNLOCK_IRQ=y -# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set -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_INTEL_ATOMISP2_PM 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_IDEAPAD_SLIDEBAR is not set -# CONFIG_INPUT_IMS_PCU 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_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_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_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_INTERVAL_TREE_TEST 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_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_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_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_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_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_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_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_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_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_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_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_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_KUSER_HELPERS=y -# CONFIG_KVM_AMD is not set -# CONFIG_KVM_GUEST is not set -# CONFIG_KVM_INTEL 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_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_APU 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_CR0014114 is not set -# CONFIG_LEDS_DAC124S085 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_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_LP5521 is not set -# CONFIG_LEDS_LP5523 is not set -# CONFIG_LEDS_LP5562 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_SYSCON is not set -# CONFIG_LEDS_TCA6507 is not set -# CONFIG_LEDS_TLC591XX is not set -CONFIG_LEDS_TRIGGERS=y -# CONFIG_LEDS_TRIGGER_ACTIVITY 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 is not set -# CONFIG_LEDS_TRIGGER_IDE_DISK is not set -# 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_TIMER=y -# CONFIG_LEDS_TRIGGER_TRANSIENT 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_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_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_LTC2471 is not set -# CONFIG_LTC2485 is not set -# CONFIG_LTC2497 is not set -# CONFIG_LTC2632 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_JAZZ is not set -# CONFIG_MACH_JZ4740 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_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_MAX1363 is not set -# CONFIG_MAX30100 is not set -# CONFIG_MAX30102 is not set -# CONFIG_MAX44000 is not set -# CONFIG_MAX517 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_MC3230 is not set -# CONFIG_MCB is not set -# CONFIG_MCP320X is not set -# CONFIG_MCP3422 is not set -# CONFIG_MCP4018 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_DEVICE is not set -# CONFIG_MDIO_HISI_FEMAC is not set -# CONFIG_MDIO_MSCC_MIIM is not set -# CONFIG_MDIO_OCTEON is not set -# CONFIG_MDIO_THUNDER 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_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_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_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_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_HI6421_PMIC is not set -# CONFIG_MFD_INTEL_QUARK_I2C_GPIO is not set -# CONFIG_MFD_JANZ_CMODIO is not set -# CONFIG_MFD_KEMPLD is not set -# CONFIG_MFD_LM3533 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_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_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_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_STMPE 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_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_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_T1_PHY is not set -# CONFIG_MICROSEMI_PHY is not set -# CONFIG_MIGRATION is not set -CONFIG_MII=y -# 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_GENERIC 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_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_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_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_MSM is not set -# CONFIG_MMC_SDHCI_OF_ARASAN 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_TEST 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_MODULES=y -# 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_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_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_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_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_ATMEL is not set -# CONFIG_MTD_NAND_AU1550 is not set -# CONFIG_MTD_NAND_BCH is not set -# CONFIG_MTD_NAND_BCM2835_SMI is not set -# CONFIG_MTD_NAND_BF5XX is not set -# CONFIG_MTD_NAND_BRCMNAND 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_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_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_OF=y -# CONFIG_MTD_PHYSMAP_OF_GEMINI is not set -# CONFIG_MTD_PHYSMAP_OF_VERSATILE is not set -# CONFIG_MTD_PLATRAM is not set -# CONFIG_MTD_PMC551 is not set -# CONFIG_MTD_RAM 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_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_BRNIMAGE_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_UIMAGE_SPLIT is not set -# CONFIG_MTD_VIRT_CONCAT is not set -# CONFIG_MTK_MMC 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_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_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_GACT 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_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_BCM_SF2 is not set -# CONFIG_NET_DSA_LEGACY is not set -# CONFIG_NET_DSA_LOOP 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_QCA8K is not set -# CONFIG_NET_DSA_REALTEK_SMI 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_DSA is not set -# CONFIG_NET_DSA_TAG_EDSA is not set -# CONFIG_NET_DSA_VITESSE_VSC73XX 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_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_FIFO=y -# CONFIG_NET_SCH_FQ is not set -CONFIG_NET_SCH_FQ_CODEL=y -# 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_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_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_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_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_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_TPROXY is not set -# CONFIG_NFT_TUNNEL is not set -# CONFIG_NF_CONNTRACK is not set -# CONFIG_NF_CONNTRACK_AMANDA 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_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_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_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_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_NVM is not set -# CONFIG_NVMEM is not set -# CONFIG_NVMEM_BCM_OCOTP is not set -# CONFIG_NVMEM_IMX_OCOTP 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_N_GSM is not set -# CONFIG_OABI_COMPAT is not set -# CONFIG_OBS600 is not set -# CONFIG_OCFS2_FS is not set -# CONFIG_OF_OVERLAY is not set -# 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 is not set -# 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_PAGE_EXTENSION is not set -# CONFIG_PAGE_OWNER is not set -# CONFIG_PAGE_POISONING 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_INJECT is not set -# CONFIG_PCIEASPM is not set -# CONFIG_PCIEPORTBUS is not set -# CONFIG_PCIE_ALTERA is not set -# CONFIG_PCIE_ARMADA_8K is not set -# CONFIG_PCIE_CADENCE_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_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_LAYERSCAPE 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_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_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_CPCAP_USB is not set -# CONFIG_PHY_EXYNOS_DP_VIDEO is not set -# CONFIG_PHY_EXYNOS_MIPI_VIDEO is not set -# CONFIG_PHY_MAPPHONE_MDM6600 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_MCP23S08 is not set -# CONFIG_PINCTRL_MSM8X74 is not set -CONFIG_PINCTRL_SINGLE=y -# CONFIG_PINCTRL_SX150X is not set -CONFIG_PINMUX=y -# CONFIG_PKCS7_MESSAGE_PARSER 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_PLUGIN_HOSTCC="" -# 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_PM_AUTOSLEEP 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_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_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_PREEMPT_NONE=y -# CONFIG_PREEMPT_TRACER is not set -# CONFIG_PREEMPT_VOLUNTARY is not set -# CONFIG_PREEMPTIRQ_EVENTS is not set -# CONFIG_PREEMPTIRQ_DELAY_TEST is not set -CONFIG_PREVENT_FIRMWARE_BUILD=y -CONFIG_PRINTK=y -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=y -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_REPEATEDLY is not set -# CONFIG_PSAMPLE is not set -# CONFIG_PSB6970_PHY is not set -# CONFIG_PSTORE is not set -# CONFIG_PTP_1588_CLOCK 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_PUBLIC_KEY_ALGO_RSA is not set -# CONFIG_PWM 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_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_QSEMI_PHY is not set -# CONFIG_QUEUED_LOCK_STAT 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_RAID_ATTRS is not set -# CONFIG_RALINK is not set -# CONFIG_RANDOM32_SELFTEST 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_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_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_READABLE_ASM is not set -# CONFIG_REALTEK_PHY is not set -# CONFIG_REDWOOD is not set -# CONFIG_REFCOUNT_FULL 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_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_MAX8649 is not set -# CONFIG_REGULATOR_MAX8660 is not set -# CONFIG_REGULATOR_MAX8952 is not set -# CONFIG_REGULATOR_MAX8973 is not set -# CONFIG_REGULATOR_MT6311 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_SY8106A 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 is not set -# 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_CONTROLLER is not set -# CONFIG_RESET_IMX7 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_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_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_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_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_RV3029C2 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_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_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_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_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_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_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_DMESG_RESTRICT=y -CONFIG_SELECT_MEMORY_MODEL=y -# 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_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_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_BH1770 is not set -# CONFIG_SENSORS_BH1780 is not set -# CONFIG_SENSORS_CORETEMP is not set -# CONFIG_SENSORS_DELL_SMM is not set -# CONFIG_SENSORS_DME1737 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_IR35221 is not set -# CONFIG_SENSORS_ISL29018 is not set -# CONFIG_SENSORS_ISL29028 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_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_MAX1111 is not set -# CONFIG_SENSORS_MAX16064 is not set -# CONFIG_SENSORS_MAX16065 is not set -# CONFIG_SENSORS_MAX1619 is not set -# CONFIG_SENSORS_MAX1668 is not set -# CONFIG_SENSORS_MAX197 is not set -# CONFIG_SENSORS_MAX20751 is not set -# CONFIG_SENSORS_MAX31722 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_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_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_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_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_XGENE is not set -# CONFIG_SENSORS_ZL6100 is not set -CONFIG_SERIAL_8250=y -# 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_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_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_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_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_IP32 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_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_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_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_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_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_AD193X_I2C 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_AK4104 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_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_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_CS4349 is not set -# CONFIG_SND_SOC_CS53L30 is not set -# CONFIG_SND_SOC_DIO2125 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_ESAI 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_I_SABRE_CODEC is not set -# CONFIG_SND_SOC_ICS43432 is not set -# CONFIG_SND_SOC_IMG 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_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_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_HASWELL 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_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_MAX9759 is not set -# CONFIG_SND_SOC_MAX98373 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_MT8173 is not set -# CONFIG_SND_SOC_NAU8540 is not set -# CONFIG_SND_SOC_NAU8810 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_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_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_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_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_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_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_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_XTFPGA_I2S 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_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_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_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_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_ROCKCHIP is not set -# CONFIG_SPI_S3C64XX is not set -# CONFIG_SPI_SC18IS602 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_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=y -# 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_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_SPI_DRIVER is not set -# CONFIG_SWCONFIG_LEDS is not set -# CONFIG_SW_SYNC is not set -# CONFIG_SX9500 is not set -# CONFIG_SXGBE_ETH is not set -# CONFIG_SYNCLINK_CS is not set -# CONFIG_SYNC_FILE is not set -# CONFIG_SYNOPSYS_DWC_ETH_QOS 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_TASK_XACCT is not set -# CONFIG_TC35815 is not set -# CONFIG_TCG_ATMEL is not set -# CONFIG_TCG_CRB 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=y -# 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_BPF is not set -# CONFIG_TEST_FIRMWARE 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_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_STATIC_KEYS is not set -# CONFIG_TEST_STRING_HELPERS 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_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_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_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_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_ADS7950 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_CPTS is not set -# CONFIG_TI_DAC082S085 is not set -# CONFIG_TI_DAC5571 is not set -# CONFIG_TI_DAC7512 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_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_I2C is not set -# CONFIG_TOUCHSCREEN_AD7879 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_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_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_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_IIO is not set -# CONFIG_TOUCHSCREEN_TSC2007 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_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_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_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_ENCRYPTION is not set -CONFIG_UBIFS_FS_FORMAT4=y -# CONFIG_UBIFS_FS_SECURITY is not set -# CONFIG_UBIFS_FS_XATTR is not set -# CONFIG_UBSAN is not set -# CONFIG_UCB1400_CORE is not set -# CONFIG_UCSI is not set -# CONFIG_UDF_FS 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_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_UNUSED_SYMBOLS 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_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_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_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_CHAOSKEY is not set -# CONFIG_USB_CHIPIDEA is not set -# CONFIG_USB_CONFIGFS 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_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_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_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_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_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_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_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_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_FSM 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_RCAR_PHY is not set -# CONFIG_USB_RENESAS_USBHS is not set -# CONFIG_USB_RIO500 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_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_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_TEST_DRIVERS is not set -# CONFIG_VBOXGUEST is not set -# CONFIG_VCNL4000 is not set -# CONFIG_VDSO 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_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_NET is not set -# CONFIG_VHOST_VSOCK is not set -# CONFIG_VIA_RHINE is not set -# CONFIG_VIA_VELOCITY 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_ADV_DEBUG is not set -# CONFIG_VIDEO_AK881X 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_EM28XX is not set -# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set -# CONFIG_VIDEO_GO7007 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_I2C is not set -# CONFIG_VIDEO_IR_I2C is not set -# CONFIG_VIDEO_IVTV is not set -# CONFIG_VIDEO_KS0127 is not set -# CONFIG_VIDEO_M52790 is not set -# CONFIG_VIDEO_ML86V7667 is not set -# CONFIG_VIDEO_MSP3400 is not set -# CONFIG_VIDEO_MT9M111 is not set -# CONFIG_VIDEO_MT9T112 is not set -# CONFIG_VIDEO_MT9V011 is not set -# CONFIG_VIDEO_MT9V111 is not set -# CONFIG_VIDEO_MXB is not set -# CONFIG_VIDEO_NOON010PC30 is not set -# CONFIG_VIDEO_OMAP2_VOUT is not set -# CONFIG_VIDEO_OV2640 is not set -# CONFIG_VIDEO_OV2659 is not set -# CONFIG_VIDEO_OV5695 is not set -# CONFIG_VIDEO_OV6650 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_PVRUSB2 is not set -# CONFIG_VIDEO_RJ54N1 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_SONY_BTF_MPX is not set -# CONFIG_VIDEO_SR030PC30 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_ZORAN is not set -# CONFIG_VIRTIO_BALLOON is not set -# CONFIG_VIRTIO_BLK_SCSI is not set -# CONFIG_VIRTIO_INPUT is not set -CONFIG_VIRTIO_MENU=y -# CONFIG_VIRTIO_MMIO 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_VL6180 is not set -CONFIG_VLAN_8021Q=y -# CONFIG_VLAN_8021Q_GVRP is not set -# CONFIG_VLAN_8021Q_MVRP is not set -CONFIG_VMAP_STACK=y -# 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_SLAVE_BQ27000 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_DS2431 is not set -# CONFIG_W1_SLAVE_DS2433 is not set -# CONFIG_W1_SLAVE_DS2438 is not set -# CONFIG_W1_SLAVE_DS2760 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_PRETIMEOUT_GOV is not set -# CONFIG_WATCHDOG_SYSFS 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_WIMAX_GDM72XX 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_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_WL_MEDIATEK is not set -CONFIG_WL_TI=y -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_DEBUG_STATIC_CPU_HAS 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_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_VCU is not set -# CONFIG_XILINX_WATCHDOG is not set -# CONFIG_XILINX_ZYNQMP_DMA 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 -CONFIG_TCP_CONG_LIA=y -CONFIG_TCP_CONG_OLIA=y -CONFIG_TCP_CONG_WVEGAS=y -CONFIG_TCP_CONG_BALIA=y -CONFIG_TCP_CONG_MCTCPDESYNC=y -CONFIG_DEFAULT_TCP_CONG="cubic" -CONFIG_MPTCP=y -# CONFIG_DEFAULT_BALIA is not set -# CONFIG_DEFAULT_LIA is not set -# CONFIG_DEFAULT_OLIA is not set -# CONFIG_DEFAULT_WVEGAS is not set -# CONFIG_DEFAULT_BBR is not set -# CONFIG_DEFAULT_MCTCPDESYNC is not set -CONFIG_DEFAULT_CUBIC=y -CONFIG_DEFAULT_MPTCP_PM="default" -CONFIG_DEFAULT_MPTCP_SCHED="default" -CONFIG_MPTCP_PM_ADVANCED=y -CONFIG_MPTCP_SCHED_ADVANCED=y -CONFIG_MPTCP_FULLMESH=y -CONFIG_MPTCP_NDIFFPORTS=y -CONFIG_MPTCP_BINDER=y -CONFIG_MPTCP_ROUNDROBIN=y -CONFIG_MPTCP_BLEST=y -CONFIG_MPTCP_REDUNDANT=y -CONFIG_MPTCP_NETLINK=y -CONFIG_MPTCP_ECF=y -CONFIG_DEFAULT_FULLMESH=y -CONFIG_DEFAULT_SCHEDULER=y -# CONFIG_DEFAULT_NDIFFPORTS is not set -# CONFIG_DEFAULT_NETLINK is not set -# CONFIG_DEFAULT_BINDER is not set -# CONFIG_DEFAULT_DUMMY is not set -# CONFIG_DEFAULT_ROUNDROBIN is not set -# CONFIG_DEFAULT_BLEST is not set -# CONFIG_DEFAULT_REDUNDANT is not set -CONFIG_NF_CONNTRACK_CUSTOM=2 \ No newline at end of file diff --git a/root/target/linux/generic/config-4.9 b/root/target/linux/generic/config-4.9 deleted file mode 100644 index ceac7fac..00000000 --- a/root/target/linux/generic/config-4.9 +++ /dev/null @@ -1,5324 +0,0 @@ -CONFIG_32BIT=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_ABX500_CORE is not set -# CONFIG_ACCESSIBILITY is not set -# CONFIG_ACENIC is not set -# CONFIG_ACERHDF 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_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_AD5755 is not set -# CONFIG_AD5761 is not set -# CONFIG_AD5764 is not set -# CONFIG_AD5791 is not set -# CONFIG_AD5933 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_AD7298 is not set -# CONFIG_AD7303 is not set -# CONFIG_AD7476 is not set -# CONFIG_AD7606 is not set -# CONFIG_AD7746 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_AD799X is not set -# CONFIG_AD8366 is not set -# CONFIG_AD8801 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_ADE7753 is not set -# CONFIG_ADE7754 is not set -# CONFIG_ADE7758 is not set -# CONFIG_ADE7759 is not set -# CONFIG_ADE7854 is not set -# CONFIG_ADF4350 is not set -# CONFIG_ADFS_FS is not set -# CONFIG_ADIS16060 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_ADIS16204 is not set -# CONFIG_ADIS16209 is not set -# CONFIG_ADIS16220 is not set -# CONFIG_ADIS16240 is not set -# CONFIG_ADIS16260 is not set -# CONFIG_ADIS16400 is not set -# CONFIG_ADIS16480 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_ADVISE_SYSCALLS=y -# 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_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_AL3320A is not set -# CONFIG_ALIM7101_WDT is not set -CONFIG_ALLOW_DEV_COREDUMP=y -# CONFIG_ALTERA_MBOX is not set -# CONFIG_ALTERA_STAPL is not set -# CONFIG_ALTERA_TSE is not set -# CONFIG_ALX 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_PHY is not set -# CONFIG_AMD_XGBE 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_APPLICOM 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_ALPINE is not set -# CONFIG_ARCH_ARTPEC is not set -# CONFIG_ARCH_ASPEED is not set -# CONFIG_ARCH_AT91 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_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_HAS_DEVMEM_IS_ALLOWED=y -# CONFIG_ARCH_HAS_ILOG2_U32 is not set -# CONFIG_ARCH_HAS_ILOG2_U64 is not set -CONFIG_ARCH_HAS_UBSAN_SANITIZE_ALL=y -# 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_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_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_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_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_PHYS_ADDR_T_64BIT 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_REALVIEW is not set -# CONFIG_ARCH_RENESAS is not set -# CONFIG_ARCH_ROCKCHIP is not set -# CONFIG_ARCH_RPC 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_SHMOBILE_MULTI is not set -# CONFIG_ARCH_SIRF is not set -# CONFIG_ARCH_SOCFPGA is not set -# CONFIG_ARCH_SPRD is not set -# CONFIG_ARCH_STI is not set -# CONFIG_ARCH_STRATIX10 is not set -# CONFIG_ARCH_SUNXI is not set -# CONFIG_ARCH_TANGO is not set -# CONFIG_ARCH_TEGRA is not set -# CONFIG_ARCH_THUNDER 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_VT8500 is not set -# CONFIG_ARCH_VULCAN is not set -# CONFIG_ARCH_W90X900 is not set -# CONFIG_ARCH_WANTS_UBSAN_NO_NULL 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_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_ARM_APPENDED_DTB is not set -# CONFIG_ARM_ARCH_TIMER 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_CCN 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_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_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_GIC_MAX_NR=1 -# CONFIG_ARM_KERNMEM_PERMS is not set -# CONFIG_ARM_KIRKWOOD_CPUFREQ is not set -# CONFIG_ARM_KPROBES_TEST 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_PTDUMP is not set -# CONFIG_ARM_SBSA_WATCHDOG is not set -# CONFIG_ARM_SCPI_PROTOCOL 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_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_GENERIC 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_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_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_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_BD6107 is not set -# CONFIG_BACKLIGHT_GENERIC is not set -# CONFIG_BACKLIGHT_GPIO is not set -# CONFIG_BACKLIGHT_LCD_SUPPORT 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_RPI is not set -# CONFIG_BACKLIGHT_SAHARA is not set -# CONFIG_BACKTRACE_SELF_TEST 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_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_MAX17040 is not set -# CONFIG_BATTERY_MAX17042 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_BCM63XX is not set -# CONFIG_BCM63XX_PHY is not set -# CONFIG_BCM7038_WDT is not set -# CONFIG_BCM7XXX_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_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_FLAT is not set -# CONFIG_BINFMT_MISC is not set -CONFIG_BINFMT_SCRIPT=y -CONFIG_BITREVERSE=y -# CONFIG_BLK_CMDLINE_PARSER is not set -# CONFIG_BLK_CPQ_CISS_DA is not set -# CONFIG_BLK_CPQ_DA 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_HD 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_BLOCK=y -# CONFIG_BMA180 is not set -# CONFIG_BMA220 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_BMG160 is not set -# CONFIG_BMI160_I2C is not set -# CONFIG_BMI160_SPI is not set -# CONFIG_BMIPS_GENERIC is not set -# CONFIG_BMP085 is not set -# CONFIG_BMP085_I2C is not set -# CONFIG_BMP085_SPI is not set -# CONFIG_BMP280 is not set -# CONFIG_BNA is not set -# CONFIG_BNX2 is not set -# CONFIG_BNX2X 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_BOOT_PRINTK_DELAY is not set -CONFIG_BOOT_RAW=y -CONFIG_BPF=y -# CONFIG_BPF_JIT 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_NETFILTER is not set -# CONFIG_BRIDGE_NF_EBTABLES is not set -# CONFIG_BRIDGE_VLAN_FILTERING is not set -# 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_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_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_HCIBTUART is not set -# CONFIG_BT_HCIBTUSB 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_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_RFCOMM is not set -CONFIG_BT_RFCOMM_TTY=y -# CONFIG_BT_SELFTEST is not set -CONFIG_BUG=y -CONFIG_BUILDTIME_EXTABLE_SORT=y -# CONFIG_BUILD_BIN2C is not set -# 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_IFI_CANFD is not set -# CONFIG_CAN_M_CAN 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_VCAN 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_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_OCTEON_SOC is not set -# CONFIG_CB710_CORE is not set -# CONFIG_CC10001_ADC is not set -# CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE is not set -CONFIG_CC_OPTIMIZE_FOR_SIZE=y -# CONFIG_CC_STACKPROTECTOR is not set -CONFIG_CC_STACKPROTECTOR_NONE=y -# CONFIG_CC_STACKPROTECTOR_REGULAR is not set -# CONFIG_CC_STACKPROTECTOR_STRONG 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_CGROUP_DEBUG is not set -# CONFIG_CGROUP_NET_PRIO is not set -# CONFIG_CGROUP_NET_CLASSID 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_BQ25890 is not set -# CONFIG_CHARGER_GPIO is not set -# CONFIG_CHARGER_ISP1704 is not set -# CONFIG_CHARGER_LP8727 is not set -# CONFIG_CHARGER_MANAGER is not set -# CONFIG_CHARGER_MAX8903 is not set -# CONFIG_CHARGER_RT9455 is not set -# CONFIG_CHARGER_SMB347 is not set -# CONFIG_CHARGER_TWL4030 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_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=y -# CONFIG_CIFS_STATS2 is not set -# CONFIG_CIFS_WEAK_PW_HASH is not set -# CONFIG_CIFS_XATTR is not set -# CONFIG_CIO_DAC is not set -# CONFIG_CLEANCACHE is not set -# CONFIG_CLKSRC_VERSATILE 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_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_IPROC 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_SI5351 is not set -# CONFIG_COMMON_CLK_SI570 is not set -# CONFIG_COMMON_CLK_XLNX_CLKWZRD is not set -# CONFIG_COMPACTION is not set -# CONFIG_COMPAL_LAPTOP 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_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_CPA_DEBUG 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_IDLE is not set -# CONFIG_CPU_IDLE_GOV_MENU is not set -# CONFIG_CPU_IDLE_MULTIPLE_DRIVERS is not set -# CONFIG_CPU_NO_EFFICIENT_FFS is not set -CONFIG_CPU_SW_DOMAIN_PAN=y -# CONFIG_CRAMFS is not set -CONFIG_CRASHLOG=y -# 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_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_AEAD 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_NI_INTEL 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=y -# CONFIG_CRYPTO_AUTHENC is not set -CONFIG_CRYPTO_BLKCIPHER=y -CONFIG_CRYPTO_BLKCIPHER2=y -# 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_CHACHA20 is not set -# CONFIG_CRYPTO_CHACHA20POLY1305 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_CRCT10DIF is not set -# CONFIG_CRYPTO_CRYPTD is not set -# CONFIG_CRYPTO_CTR is not set -# CONFIG_CRYPTO_CTS is not set -# CONFIG_CRYPTO_DEFLATE is not set -# CONFIG_CRYPTO_DES is not set -# CONFIG_CRYPTO_DEV_ATMEL_AES is not set -# CONFIG_CRYPTO_DEV_ATMEL_SHA is not set -# CONFIG_CRYPTO_DEV_ATMEL_TDES is not set -# CONFIG_CRYPTO_DEV_CCP is not set -# CONFIG_CRYPTO_DEV_FSL_CAAM is not set -# CONFIG_CRYPTO_DEV_HIFN_795X 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_MXS_DCP 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_SAHARA is not set -# CONFIG_CRYPTO_DEV_TALITOS 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_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_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_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_NULL 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_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_SHA256 is not set -# CONFIG_CRYPTO_SHA3 is not set -# CONFIG_CRYPTO_SHA512 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_HASH is not set -# CONFIG_CRYPTO_USER_API_RNG 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_ZLIB is not set -# CONFIG_CS5535_MFGPT is not set -# CONFIG_CS89x0 is not set -# CONFIG_CUSE is not set -# CONFIG_CW1200 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_CYPRESS_FIRMWARE is not set -# CONFIG_DAVICOM_PHY is not set -# CONFIG_DCB is not set -# CONFIG_DDR 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_FORCE_WEAK_PER_CPU is not set -CONFIG_DEBUG_FS=y -# 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_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_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_PREEMPT is not set -# CONFIG_DEBUG_RODATA is not set -# CONFIG_DEBUG_RODATA_TEST is not set -# CONFIG_DEBUG_RT_MUTEXES is not set -# CONFIG_DEBUG_SECTION_MISMATCH is not set -# CONFIG_DEBUG_SEMIHOSTING is not set -# CONFIG_DEBUG_SET_MODULE_RONX 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_BCM63XX is not set -# CONFIG_DEBUG_VM 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_DEADLINE=y -CONFIG_DEFAULT_HOSTNAME="(none)" -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_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" -# CONFIG_DELL_RBTN 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_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_DLM is not set -# CONFIG_DM9000 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_DMASCC is not set -# CONFIG_DMATEST is not set -# CONFIG_DMA_API_DEBUG is not set -# CONFIG_DMA_ENGINE is not set -# CONFIG_DMA_SHARED_BUFFER is not set -# CONFIG_DM_CACHE is not set -# CONFIG_DM_DEBUG is not set -# CONFIG_DM_DELAY is not set -# CONFIG_DM_ERA is not set -# CONFIG_DM_FLAKEY 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_VERITY 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_DP83848_PHY is not set -# CONFIG_DP83867_PHY 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_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_CIRRUS_QEMU is not set -# CONFIG_DRM_DP_AUX_CHARDEV is not set -# CONFIG_DRM_DUMB_VGA_DAC is not set -# CONFIG_DRM_ETNAVIV is not set -# CONFIG_DRM_EXYNOS is not set -# CONFIG_DRM_FBDEV_EMULATION is not set -# CONFIG_DRM_FSL_DCU is not set -# CONFIG_DRM_HDLCD 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_TDA998X is not set -# CONFIG_DRM_I2C_SIL164 is not set -# CONFIG_DRM_LEGACY is not set -# CONFIG_DRM_LOAD_EDID_FIRMWARE is not set -# CONFIG_DRM_MALI_DISPLAY is not set -# CONFIG_DRM_MGAG200 is not set -# CONFIG_DRM_NOUVEAU is not set -# CONFIG_DRM_NXP_PTN3460 is not set -# CONFIG_DRM_OMAP is not set -# CONFIG_DRM_PANEL_JDI_LT070ME05000 is not set -# CONFIG_DRM_PANEL_LG_LG4573 is not set -# CONFIG_DRM_PANEL_PANASONIC_VVX10F034N00 is not set -# CONFIG_DRM_PANEL_RASPBERRYPI_TOUCHSCREEN is not set -# CONFIG_DRM_PANEL_SAMSUNG_LD9040 is not set -# CONFIG_DRM_PANEL_SAMSUNG_S6E8AA0 is not set -# CONFIG_DRM_PANEL_SHARP_LQ101R1SX01 is not set -# CONFIG_DRM_PANEL_SHARP_LS043T1LE01 is not set -# CONFIG_DRM_PARADE_PS8622 is not set -# CONFIG_DRM_QXL is not set -# CONFIG_DRM_RADEON is not set -# CONFIG_DRM_SII902X is not set -# CONFIG_DRM_STI is not set -# CONFIG_DRM_TILCDC is not set -# CONFIG_DRM_TOSHIBA_TC358767 is not set -# CONFIG_DRM_UDL is not set -# CONFIG_DRM_VGEM is not set -# CONFIG_DS1682 is not set -# CONFIG_DS1803 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_AU8522_V4L is not set -# CONFIG_DVB_CORE is not set -# CONFIG_DVB_DUMMY_FE is not set -# CONFIG_DVB_TUNER_DIB0070 is not set -# CONFIG_DVB_TUNER_DIB0090 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_DMAC is not set -# CONFIG_DW_DMAC_PCI is not set -# CONFIG_DW_WATCHDOG is not set -# CONFIG_DYNAMIC_DEBUG is not set -# 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_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_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_ENIC is not set -# CONFIG_EPAPR_PARAVIRT is not set -# CONFIG_EPIC100 is not set -CONFIG_EPOLL=y -# CONFIG_EQUALIZER is not set -# CONFIG_ET131X is not set -CONFIG_ETHERNET=y -# CONFIG_ETHOC is not set -CONFIG_EVENTFD=y -CONFIG_EXPERT=y -# CONFIG_EXPORTFS is not set -# CONFIG_EXPORTFS_BLOCK_OPS is not set -# CONFIG_EXT2_FS is not set -# CONFIG_EXT2_FS_XATTR is not set -# 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_AXP288 is not set -# CONFIG_EXTCON_GPIO is not set -# CONFIG_EXTCON_MAX3355 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_FAULT_INJECTION is not set -# CONFIG_F2FS_FS is not set -# CONFIG_F2FS_FS_ENCRYPTION is not set -# CONFIG_F2FS_FS_POSIX_ACL is not set -# CONFIG_F2FS_IO_TRACE is not set -# CONFIG_FAIR_GROUP_SCHED is not set -# CONFIG_FANOTIFY 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_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_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_FILE_LOCKING=y -# 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_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_FORCEDETH is not set -CONFIG_FORCE_MAX_ZONEORDER=11 -# CONFIG_FPGA is not set -# CONFIG_FRAMEBUFFER_CONSOLE 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_FSL_EDMA is not set -# CONFIG_FSL_MC_BUS is not set -# CONFIG_FSL_PQ_MDIO 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_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_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_FW_CFG_SYSFS is not set -CONFIG_FW_LOADER=y -CONFIG_FW_LOADER_USER_HELPER=y -CONFIG_FW_LOADER_USER_HELPER_FALLBACK=y -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_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_PROBE=y -CONFIG_GENERIC_NET_UTILS=y -# CONFIG_GENERIC_PHY is not set -# 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_GOLDFISH is not set -# CONFIG_GP2AP020A00F is not set -# CONFIG_GPIOLIB 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_ALTERA is not set -# CONFIG_GPIO_AMD8111 is not set -# CONFIG_GPIO_AMDPT is not set -# CONFIG_GPIO_BCM_KONA is not set -# CONFIG_GPIO_BT8XX is not set -# CONFIG_GPIO_CS5535 is not set -# CONFIG_GPIO_DWAPB is not set -# CONFIG_GPIO_EM is not set -# CONFIG_GPIO_F7188X 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_ICH is not set -# CONFIG_GPIO_IT87 is not set -# CONFIG_GPIO_LYNXPOINT is not set -# CONFIG_GPIO_MAX7300 is not set -# CONFIG_GPIO_MAX7301 is not set -# CONFIG_GPIO_MAX732X 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_PCF857X is not set -# CONFIG_GPIO_PCH 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_SCH is not set -# CONFIG_GPIO_SCH311X is not set -# CONFIG_GPIO_SX150X is not set -# CONFIG_GPIO_SYSCON is not set -# CONFIG_GPIO_SYSFS is not set -# 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_WS16C48 is not set -# CONFIG_GPIO_XGENE is not set -# CONFIG_GPIO_XILINX 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_HAMACHI is not set -# CONFIG_HAMRADIO is not set -# CONFIG_HAPPYMEAL is not set -# CONFIG_HARDENED_USERCOPY is not set -# CONFIG_HARDLOCKUP_DETECTOR is not set -# CONFIG_HAVE_AOUT is not set -CONFIG_HAVE_ARCH_HARDENED_USERCOPY=y -# CONFIG_HAVE_ARCH_HASH is not set -CONFIG_HAVE_ARCH_MMAP_RND_BITS=y -# CONFIG_HAVE_ARCH_VMAP_STACK is not set -CONFIG_HAVE_ARCH_WITHIN_STACK_FRAMES=y -# CONFIG_HAVE_ARM_ARCH_TIMER is not set -CONFIG_HAVE_EXIT_THREAD=y -CONFIG_HAVE_GCC_PLUGINS=y -CONFIG_HAVE_HARDENED_USERCOPY_ALLOCATOR=y -CONFIG_HAVE_KERNEL_BZIP2=y -CONFIG_HAVE_KERNEL_CAT=y -CONFIG_HAVE_KERNEL_GZIP=y -CONFIG_HAVE_KERNEL_LZ4=y -CONFIG_HAVE_KERNEL_LZMA=y -CONFIG_HAVE_KERNEL_LZO=y -CONFIG_HAVE_KERNEL_XZ=y -CONFIG_HAVE_KPROBES=y -CONFIG_HAVE_KRETPROBES=y -CONFIG_HAVE_NMI=y -# CONFIG_HCALL_STATS is not set -# CONFIG_HDC100X 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_HDQ_MASTER_OMAP is not set -# CONFIG_HEADERS_CHECK 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_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_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_CHERRY is not set -# CONFIG_HID_CHICONY is not set -# CONFIG_HID_CMEDIA is not set -# CONFIG_HID_CORSAIR is not set -# CONFIG_HID_CP2112 is not set -# CONFIG_HID_CYPRESS is not set -# CONFIG_HID_DRAGONRISE 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_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_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_MAGICMOUSE is not set -# CONFIG_HID_MICROSOFT is not set -# CONFIG_HID_MONTEREY is not set -# CONFIG_HID_MULTITOUCH 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_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_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_UCLOGIC 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_HIP04_ETH is not set -# CONFIG_HIPPI is not set -# CONFIG_HISI_FEMAC is not set -# CONFIG_HIX5HD2_GMAC is not set -# CONFIG_HMC6352 is not set -# CONFIG_HNS 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_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_HTU21 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_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_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_OMAP3_ROM is not set -# CONFIG_HW_RANDOM_PPC4XX is not set -# CONFIG_HW_RANDOM_TIMERIOMEM is not set -# CONFIG_HW_RANDOM_TPM is not set -# CONFIG_HW_RANDOM_VIA is not set -# CONFIG_HW_RANDOM_VIRTIO is not set -# CONFIG_HYPERV is not set -# CONFIG_HYSDN is not set -CONFIG_HZ=100 -CONFIG_HZ_100=y -# 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_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_MPC is not set -# CONFIG_I2C_MUX is not set -# CONFIG_I2C_MUX_GPIO 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_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_RCAR is not set -# CONFIG_I2C_RK3X is not set -# CONFIG_I2C_ROBOTFUZZ_OSIF 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_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_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_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_IFB is not set -# CONFIG_IGB is not set -# CONFIG_IGBVF is not set -# CONFIG_IIO is not set -# CONFIG_IIO_BUFFER_CB is not set -# CONFIG_IIO_CONFIGFS is not set -CONFIG_IIO_CONSUMERS_PER_TRIGGER=2 -# CONFIG_IIO_INTERRUPT_TRIGGER is not set -# CONFIG_IIO_PERIODIC_RTC_TRIGGER 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_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_IKCONFIG is not set -# CONFIG_IKCONFIG_PROC 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_INET=y -# CONFIG_INET6_AH is not set -# CONFIG_INET6_ESP 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_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_INIT_ENV_ARG_LIMIT=32 -# CONFIG_INLINE_READ_LOCK is not set -# CONFIG_INLINE_READ_LOCK_BH is not set -# CONFIG_INLINE_READ_LOCK_IRQ is not set -# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set -# CONFIG_INLINE_READ_TRYLOCK is not set -CONFIG_INLINE_READ_UNLOCK=y -# CONFIG_INLINE_READ_UNLOCK_BH is not set -CONFIG_INLINE_READ_UNLOCK_IRQ=y -# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set -# CONFIG_INLINE_SPIN_LOCK is not set -# CONFIG_INLINE_SPIN_LOCK_BH is not set -# CONFIG_INLINE_SPIN_LOCK_IRQ is not set -# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set -# CONFIG_INLINE_SPIN_TRYLOCK is not set -# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set -# CONFIG_INLINE_SPIN_UNLOCK_BH is not set -CONFIG_INLINE_SPIN_UNLOCK_IRQ=y -# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set -# CONFIG_INLINE_WRITE_LOCK is not set -# CONFIG_INLINE_WRITE_LOCK_BH is not set -# CONFIG_INLINE_WRITE_LOCK_IRQ is not set -# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set -# CONFIG_INLINE_WRITE_TRYLOCK is not set -CONFIG_INLINE_WRITE_UNLOCK=y -# CONFIG_INLINE_WRITE_UNLOCK_BH is not set -CONFIG_INLINE_WRITE_UNLOCK_IRQ=y -# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set -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_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_IDEAPAD_SLIDEBAR is not set -# CONFIG_INPUT_IMS_PCU 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_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_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_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_INTEL_HID_EVENT is not set -# CONFIG_INTEL_IDLE is not set -# CONFIG_INTEL_IDMA64 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_TH is not set -# CONFIG_INTEL_VBTN is not set -# CONFIG_INTEL_XWAY_PHY is not set -# CONFIG_INTERVAL_TREE_TEST 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_IOSCHED_CFQ is not set -CONFIG_IOSCHED_DEADLINE=y -CONFIG_IOSCHED_NOOP=y -CONFIG_IO_STRICT_DEVMEM=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_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_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_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_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_VS is not set -# 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_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_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_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_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_KERNFS=y -# CONFIG_KEXEC is not set -# CONFIG_KEYBOARD_ADC is not set -# CONFIG_KEYBOARD_ADP5588 is not set -# CONFIG_KEYBOARD_ADP5589 is not set -# CONFIG_KEYBOARD_ATKBD is not set -# CONFIG_KEYBOARD_BCM is not set -# CONFIG_KEYBOARD_CAP11XX 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_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_STOWAWAY is not set -# CONFIG_KEYBOARD_SUNKBD is not set -# CONFIG_KEYBOARD_TCA6416 is not set -# CONFIG_KEYBOARD_TCA8418 is not set -# CONFIG_KEYBOARD_TWL4030 is not set -# CONFIG_KEYBOARD_XTKBD is not set -# CONFIG_KEYS 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_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_KUSER_HELPERS=y -# CONFIG_KVM_AMD is not set -# CONFIG_KVM_GUEST is not set -# CONFIG_KVM_INTEL 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_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_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_S6E63M0 is not set -# CONFIG_LCD_TDO24M is not set -# CONFIG_LCD_VGG2432A4 is not set -# CONFIG_LDM_PARTITION is not set -CONFIG_LD_DEAD_CODE_DATA_ELIMINATION=y -# 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_CLASS=y -# CONFIG_LEDS_CLASS_FLASH is not set -# CONFIG_LEDS_DAC124S085 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_LM355x is not set -# CONFIG_LEDS_LM3642 is not set -# CONFIG_LEDS_LP3944 is not set -# CONFIG_LEDS_LP3952 is not set -# CONFIG_LEDS_LP5521 is not set -# CONFIG_LEDS_LP5523 is not set -# CONFIG_LEDS_LP5562 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_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_SYSCON is not set -# CONFIG_LEDS_TCA6507 is not set -# CONFIG_LEDS_TLC591XX is not set -CONFIG_LEDS_TRIGGERS=y -# 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 is not set -# CONFIG_LEDS_TRIGGER_IDE_DISK is not set -# 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_TIMER=y -# CONFIG_LEDS_TRIGGER_TRANSIENT 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_LIQUIDIO is not set -# CONFIG_LIRC_STAGING is not set -# CONFIG_LIS3L02DQ is not set -# CONFIG_LKDTM is not set -CONFIG_LLC=y -# CONFIG_LLC2 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_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_LTC2485 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_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_JAZZ is not set -# CONFIG_MACH_JZ4740 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_MAILBOX is not set -# CONFIG_MANDATORY_FILE_LOCKING is not set -# CONFIG_MANGLE_BOOTARGS is not set -# CONFIG_MARVELL_PHY is not set -# CONFIG_MAX1027 is not set -# CONFIG_MAX1363 is not set -# CONFIG_MAX30100 is not set -# CONFIG_MAX44000 is not set -# CONFIG_MAX517 is not set -# CONFIG_MAX5487 is not set -# CONFIG_MAX5821 is not set -# CONFIG_MAX63XX_WATCHDOG is not set -# CONFIG_MAXIM_THERMOCOUPLE is not set -CONFIG_MAY_USE_DEVLINK=y -# CONFIG_MC3230 is not set -# CONFIG_MCB is not set -# CONFIG_MCP320X is not set -# CONFIG_MCP3422 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_HISI_FEMAC is not set -# CONFIG_MDIO_OCTEON is not set -# CONFIG_MDIO_THUNDER 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_CONTROLLER is not set -# CONFIG_MEDIA_DIGITAL_TV_SUPPORT is not set -# CONFIG_MEDIA_PCI_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_USB_SUPPORT is not set -# CONFIG_MEGARAID_LEGACY is not set -# CONFIG_MEGARAID_NEWGEN is not set -# CONFIG_MEGARAID_SAS is not set -CONFIG_MEMBARRIER=y -# CONFIG_MEMORY is not set -# CONFIG_MEMORY_FAILURE 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_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_CORE 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_HI6421_PMIC is not set -# CONFIG_MFD_JANZ_CMODIO is not set -# CONFIG_MFD_KEMPLD is not set -# CONFIG_MFD_LM3533 is not set -# CONFIG_MFD_LP3943 is not set -# CONFIG_MFD_LP8788 is not set -# CONFIG_MFD_MAX14577 is not set -# CONFIG_MFD_MAX77620 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_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_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_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_STMPE 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_LP873X 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_TPS80031 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_MICREL_KS8995MA is not set -# CONFIG_MICREL_PHY is not set -# CONFIG_MICROCHIP_PHY is not set -# CONFIG_MICROSEMI_PHY is not set -# CONFIG_MIGRATION is not set -CONFIG_MII=y -# 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_GENERIC 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_FILESYSTEMS=y -# 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_MLXSW_CORE 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_CB710 is not set -# CONFIG_MMC_DEBUG is not set -# CONFIG_MMC_DW 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_BCM_KONA is not set -# CONFIG_MMC_SDHCI_F_SDH30 is not set -# CONFIG_MMC_SDHCI_IPROC is not set -# CONFIG_MMC_SDHCI_MSM is not set -# CONFIG_MMC_SDHCI_OF_ARASAN is not set -# CONFIG_MMC_SDHCI_OF_AT91 is not set -# CONFIG_MMC_SDHCI_OF_ESDHC is not set -# CONFIG_MMC_SDHCI_OF_HLWD is not set -# CONFIG_MMC_SDHCI_PXAV2 is not set -# CONFIG_MMC_SDHCI_PXAV3 is not set -# CONFIG_MMC_SDRICOH_CS is not set -# CONFIG_MMC_SPI is not set -# CONFIG_MMC_TEST 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_MODULES=y -# 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_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_MS5611 is not set -# CONFIG_MS5637 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_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_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_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_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_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_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_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_OF=y -# CONFIG_MTD_PHYSMAP_OF_VERSATILE is not set -# CONFIG_MTD_PLATRAM is not set -# CONFIG_MTD_PMC551 is not set -# CONFIG_MTD_RAM 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_SLRAM is not set -# CONFIG_MTD_SM_COMMON is not set -# CONFIG_MTD_SPINAND_MT29F 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_BRNIMAGE_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_UIMAGE_SPLIT 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_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_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_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_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_GACT 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_NAT is not set -# CONFIG_NET_ACT_PEDIT is not set -# CONFIG_NET_ACT_POLICE 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_BCM_SF2 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_QCA8K is not set -# CONFIG_NET_DSA_TAG_DSA is not set -# CONFIG_NET_DSA_TAG_EDSA 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_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_FC is not set -# CONFIG_NET_FOU is not set -# CONFIG_NET_FOU_IP_TUNNELS 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_MPLS_GSO is not set -# CONFIG_NET_NCSI 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_CBQ is not set -# CONFIG_NET_SCH_CHOKE is not set -# CONFIG_NET_SCH_CODEL is not set -# CONFIG_NET_SCH_DRR is not set -# CONFIG_NET_SCH_DSMARK is not set -CONFIG_NET_SCH_FIFO=y -# CONFIG_NET_SCH_FQ is not set -CONFIG_NET_SCH_FQ_CODEL=y -# 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_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_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_ALTEON=y -CONFIG_NET_VENDOR_AMAZON=y -CONFIG_NET_VENDOR_AMD=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_CAVIUM=y -CONFIG_NET_VENDOR_CHELSIO=y -CONFIG_NET_VENDOR_CIRRUS=y -CONFIG_NET_VENDOR_CISCO=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_HISILICON=y -CONFIG_NET_VENDOR_HP=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_MYRI=y -CONFIG_NET_VENDOR_NATSEMI=y -CONFIG_NET_VENDOR_NETRONOME=y -CONFIG_NET_VENDOR_NVIDIA=y -CONFIG_NET_VENDOR_OKI=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_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_NETVF 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_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_DUP_IPV4 is not set -# CONFIG_NFT_DUP_IPV6 is not set -# CONFIG_NF_CONNTRACK is not set -# CONFIG_NF_CONNTRACK_AMANDA 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_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_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_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_LOG_ARP is not set -# CONFIG_NF_LOG_IPV4 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 is not set -# CONFIG_NF_NAT_MASQUERADE_IPV6 is not set -# 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_TABLES is not set -# CONFIG_NF_TABLES_NETDEV is not set -# CONFIG_NI65 is not set -# CONFIG_NI903X_WDT is not set -# CONFIG_NILFS2_FS is not set -# CONFIG_NIU 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_NOP_USB_XCEIV is not set -# CONFIG_NORTEL_HERMES is not set -# CONFIG_NOTIFIER_ERROR_INJECTION 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_NVM is not set -# CONFIG_NVMEM is not set -# CONFIG_NVMEM_IMX_OCOTP 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_N_GSM is not set -# CONFIG_OABI_COMPAT is not set -# CONFIG_OBS600 is not set -# CONFIG_OCFS2_FS is not set -# CONFIG_OF_OVERLAY is not set -# 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_ORANGEFS_FS is not set -# CONFIG_ORION_WATCHDOG is not set -# CONFIG_OSF_PARTITION is not set -CONFIG_OVERLAY_FS=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_PAGE_EXTENSION is not set -# CONFIG_PAGE_OWNER is not set -# CONFIG_PAGE_POISONING 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_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_INJECT is not set -# CONFIG_PCIEASPM is not set -# CONFIG_PCIEPORTBUS is not set -# CONFIG_PCIE_ALTERA is not set -# CONFIG_PCIE_ARMADA_8K is not set -# CONFIG_PCIE_DPC is not set -# CONFIG_PCIE_DW_PLAT is not set -# CONFIG_PCIE_ECRC is not set -# CONFIG_PCIE_IPROC is not set -# CONFIG_PCIE_PTM 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_HERMES 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_LAYERSCAPE is not set -# CONFIG_PCI_MSI is not set -# CONFIG_PCI_PASID 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_SYSCALL=y -# 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_PD6729 is not set -# CONFIG_PDA_POWER is not set -# CONFIG_PDC_ADMA 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_EXYNOS_DP_VIDEO is not set -# CONFIG_PHY_EXYNOS_MIPI_VIDEO 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_SAMSUNG_USB2 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_EXYNOS is not set -# CONFIG_PINCTRL_EXYNOS5440 is not set -# CONFIG_PINCTRL_MSM8X74 is not set -CONFIG_PINCTRL_SINGLE=y -CONFIG_PINMUX=y -# CONFIG_PKCS7_MESSAGE_PARSER 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_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_PM_AUTOSLEEP is not set -# CONFIG_PM_DEVFREQ is not set -# CONFIG_PM_WAKELOCKS is not set -# CONFIG_POSIX_MQUEUE is not set -# 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_LTC2952 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_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_PREEMPT_NONE=y -# CONFIG_PREEMPT_TRACER is not set -# CONFIG_PREEMPT_VOLUNTARY is not set -CONFIG_PREVENT_FIRMWARE_BUILD=y -CONFIG_PRINTK=y -CONFIG_PRINTK_NMI=y -# 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=y -CONFIG_PROC_SYSCTL=y -# 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_REPEATEDLY is not set -# CONFIG_PSB6970_PHY is not set -# CONFIG_PSTORE is not set -# CONFIG_PTP_1588_CLOCK is not set -# CONFIG_PTP_1588_CLOCK_IXP46X is not set -# CONFIG_PTP_1588_CLOCK_PCH is not set -# CONFIG_PUBLIC_KEY_ALGO_RSA is not set -# CONFIG_PWM is not set -# CONFIG_PWM_FSL_FTM is not set -# CONFIG_PWM_PCA9685 is not set -CONFIG_PWRSEQ_EMMC=y -CONFIG_PWRSEQ_SIMPLE=y -# CONFIG_QCA7000 is not set -# CONFIG_QCOM_EMAC 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_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_QSEMI_PHY is not set -# CONFIG_QUEUED_LOCK_STAT 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_RAID_ATTRS is not set -# CONFIG_RALINK is not set -# CONFIG_RANDOM32_SELFTEST 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_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_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_READABLE_ASM is not set -# CONFIG_REALTEK_PHY is not set -# CONFIG_REDWOOD 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_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_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_MAX8649 is not set -# CONFIG_REGULATOR_MAX8660 is not set -# CONFIG_REGULATOR_MAX8952 is not set -# CONFIG_REGULATOR_MAX8973 is not set -# CONFIG_REGULATOR_MT6311 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_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_TPS6524X is not set -# CONFIG_REGULATOR_USERSPACE_CONSUMER 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 is not set -# CONFIG_REISERFS_PROC_INFO is not set -# CONFIG_RELAY is not set -# CONFIG_RELOCATABLE is not set -# CONFIG_RESET_ATH79 is not set -# CONFIG_RESET_BERLIN is not set -# CONFIG_RESET_CONTROLLER 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_ZYNQ 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_ROCKER is not set -# CONFIG_ROMFS_FS is not set -# CONFIG_ROSE is not set -# CONFIG_RPCSEC_GSS_KRB5 is not set -# CONFIG_RPR0521 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_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_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_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_ISL12057 is not set -# CONFIG_RTC_DRV_ISL1208 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_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_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_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_RV3029C2 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_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_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_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_INIC162X is not set -# 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_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_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_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_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_SECCOMP is not set -CONFIG_SECTION_MISMATCH_WARN_ONLY=y -# CONFIG_SECURITY is not set -# CONFIG_SECURITYFS is not set -# CONFIG_SECURITY_DMESG_RESTRICT is not set -CONFIG_SELECT_MEMORY_MODEL=y -# 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_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_ASB100 is not set -# CONFIG_SENSORS_ASC7621 is not set -# CONFIG_SENSORS_ATK0110 is not set -# CONFIG_SENSORS_ATXP1 is not set -# CONFIG_SENSORS_BH1770 is not set -# CONFIG_SENSORS_BH1780 is not set -# CONFIG_SENSORS_CORETEMP is not set -# CONFIG_SENSORS_DELL_SMM is not set -# CONFIG_SENSORS_DME1737 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_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_ISL29018 is not set -# CONFIG_SENSORS_ISL29028 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_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_LTC2990 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_MAX1111 is not set -# CONFIG_SENSORS_MAX16065 is not set -# CONFIG_SENSORS_MAX1619 is not set -# CONFIG_SENSORS_MAX1668 is not set -# CONFIG_SENSORS_MAX197 is not set -# CONFIG_SENSORS_MAX31722 is not set -# CONFIG_SENSORS_MAX31790 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_MCP3021 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_NSA320 is not set -# CONFIG_SENSORS_NTC_THERMISTOR is not set -# CONFIG_SENSORS_PC87360 is not set -# CONFIG_SENSORS_PC87427 is not set -# CONFIG_SENSORS_PCF8591 is not set -# CONFIG_SENSORS_POWR1220 is not set -# CONFIG_SENSORS_PWM_FAN 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_TC74 is not set -# CONFIG_SENSORS_THMC50 is not set -# CONFIG_SENSORS_TMP102 is not set -# CONFIG_SENSORS_TMP103 is not set -# CONFIG_SENSORS_TMP401 is not set -# CONFIG_SENSORS_TMP421 is not set -# CONFIG_SENSORS_TSL2550 is not set -# CONFIG_SENSORS_TSL2563 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_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_XGENE is not set -CONFIG_SERIAL_8250=y -# CONFIG_SERIAL_8250_ACCENT 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_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_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_EARLYCON=y -# CONFIG_SERIAL_EARLYCON_ARM_SEMIHOST 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_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_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_SFI 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_IP32 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_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_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_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_RANDOM is not set -# CONFIG_SLHC is not set -# CONFIG_SLICOSS 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_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_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_AW2 is not set -# CONFIG_SND_AZT2320 is not set -# CONFIG_SND_AZT3328 is not set -# CONFIG_SND_BCD2000 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_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_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_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_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_ADAU7002 is not set -# CONFIG_SND_SOC_AK4104 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_ALC5623 is not set -# CONFIG_SND_SOC_AMD_ACP is not set -# CONFIG_SND_SOC_AU1XAUDIO is not set -# CONFIG_SND_SOC_AU1XPSC 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_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_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_CS4349 is not set -# CONFIG_SND_SOC_CS53L30 is not set -# CONFIG_SND_SOC_ES8328 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_ESAI 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_IMG 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_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_MAX98090_MACH is not set -# CONFIG_SND_SOC_INTEL_BYT_RT5640_MACH is not set -# CONFIG_SND_SOC_INTEL_CHT_BSW_MAX98090_TI_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_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_SST is not set -# CONFIG_SND_SOC_MAX98504 is not set -# CONFIG_SND_SOC_MAX9860 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_MT2701 is not set -# CONFIG_SND_SOC_MT8173 is not set -# CONFIG_SND_SOC_NAU8810 is not set -# CONFIG_SND_SOC_PCM1681 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_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_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_SIRF_AUDIO_CODEC is not set -# CONFIG_SND_SOC_SPDIF 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_TAS5086 is not set -# CONFIG_SND_SOC_TAS571X is not set -# CONFIG_SND_SOC_TAS5720 is not set -# CONFIG_SND_SOC_TFA9879 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_TLV320AIC3X is not set -# CONFIG_SND_SOC_TPA6130A2 is not set -# CONFIG_SND_SOC_TS3A227E is not set -# CONFIG_SND_SOC_WM8510 is not set -# CONFIG_SND_SOC_WM8523 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_WM8804_I2C is not set -# CONFIG_SND_SOC_WM8804_SPI is not set -# CONFIG_SND_SOC_WM8903 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_XTFPGA_I2S is not set -# CONFIG_SND_SONICVIBES is not set -# CONFIG_SND_SPI is not set -# CONFIG_SND_SSCAPE 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_YMFPCI is not set -# CONFIG_SNI_RM 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_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_SOUND_OSS_CORE 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_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_LM70_LLP is not set -# CONFIG_SPI_LOOPBACK_TEST is not set -# CONFIG_SPI_MASTER is not set -# CONFIG_SPI_MPC52xx is not set -# CONFIG_SPI_MPC52xx_PSC 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_ROCKCHIP is not set -# CONFIG_SPI_SC18IS602 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_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 is not set -# 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_SRAM 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_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_MEDIA is not set -CONFIG_STANDALONE=y -# CONFIG_STATIC_KEYS_SELFTEST 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_STRIP_ASM_SYMS=y -# CONFIG_STX104 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_GSS is not set -# CONFIG_SUNXI_SRAM is not set -# CONFIG_SUN_PARTITION 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_SPI_DRIVER is not set -# CONFIG_SWCONFIG_LEDS is not set -# CONFIG_SX9500 is not set -# CONFIG_SXGBE_ETH is not set -# CONFIG_SYNCLINK_CS is not set -# CONFIG_SYNC_FILE is not set -# CONFIG_SYNOPSYS_DWC_ETH_QOS 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_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_TASK_XACCT is not set -# CONFIG_TC35815 is not set -# CONFIG_TCG_ATMEL is not set -# CONFIG_TCG_CRB 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=y -# 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_TEGRA_AHB is not set -# CONFIG_TEGRA_HOST1X is not set -# CONFIG_TEHUTI is not set -# CONFIG_TERANETICS_PHY is not set -# CONFIG_TEST_BITMAP is not set -# CONFIG_TEST_BPF is not set -# CONFIG_TEST_FIRMWARE is not set -# CONFIG_TEST_HASH is not set -# CONFIG_TEST_HEXDUMP is not set -# CONFIG_TEST_KSTRTOX is not set -# CONFIG_TEST_LIST_SORT is not set -# CONFIG_TEST_LKM is not set -# CONFIG_TEST_POWER is not set -# CONFIG_TEST_PRINTF is not set -# CONFIG_TEST_RHASHTABLE is not set -# CONFIG_TEST_STATIC_KEYS is not set -# CONFIG_TEST_STRING_HELPERS is not set -# CONFIG_TEST_UDELAY is not set -# CONFIG_TEST_USER_COPY is not set -# CONFIG_TEST_UUID 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_WRITABLE_TRIPS is not set -# CONFIG_THINKPAD_ACPI is not set -# CONFIG_THRUSTMASTER_FF 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_TINY_RCU=y -# CONFIG_TIPC is not set -# CONFIG_TI_ADC081C is not set -# CONFIG_TI_ADC0832 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_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_CPTS is not set -# CONFIG_TI_DAC7512 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_TLAN is not set -# CONFIG_TMD_HERMES is not set -# CONFIG_TMP006 is not set -CONFIG_TMPFS=y -# 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_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_ADS7846 is not set -# CONFIG_TOUCHSCREEN_AR1021_I2C is not set -# CONFIG_TOUCHSCREEN_ATMEL_MXT is not set -# CONFIG_TOUCHSCREEN_AUO_PIXCIR is not set -# CONFIG_TOUCHSCREEN_BU21013 is not set -# CONFIG_TOUCHSCREEN_CHIPONE_ICN8318 is not set -# CONFIG_TOUCHSCREEN_CY8CTMG110 is not set -# CONFIG_TOUCHSCREEN_CYTTSP4_CORE is not set -# CONFIG_TOUCHSCREEN_CYTTSP_CORE 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_FT6236 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_ILI210X is not set -# CONFIG_TOUCHSCREEN_IMX6UL_TSC is not set -# CONFIG_TOUCHSCREEN_INEXIO is not set -# CONFIG_TOUCHSCREEN_MAX11801 is not set -# CONFIG_TOUCHSCREEN_MCS5000 is not set -# CONFIG_TOUCHSCREEN_MELFAS_MIP4 is not set -# CONFIG_TOUCHSCREEN_MK712 is not set -# CONFIG_TOUCHSCREEN_MMS114 is not set -# CONFIG_TOUCHSCREEN_MTOUCH is not set -# CONFIG_TOUCHSCREEN_PENMOUNT is not set -# CONFIG_TOUCHSCREEN_PIXCIR is not set -# CONFIG_TOUCHSCREEN_RM_TS is not set -# CONFIG_TOUCHSCREEN_ROHM_BU21023 is not set -# CONFIG_TOUCHSCREEN_S3C2410 is not set -# CONFIG_TOUCHSCREEN_SILEAD is not set -# CONFIG_TOUCHSCREEN_SIS_I2C is not set -# CONFIG_TOUCHSCREEN_ST1232 is not set -# CONFIG_TOUCHSCREEN_SUR40 is not set -# CONFIG_TOUCHSCREEN_SURFACE3_SPI is not set -# CONFIG_TOUCHSCREEN_SX8654 is not set -# CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4 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_TSC2004 is not set -# CONFIG_TOUCHSCREEN_TSC2005 is not set -# CONFIG_TOUCHSCREEN_TSC2007 is not set -# CONFIG_TOUCHSCREEN_TSC_SERIO is not set -# CONFIG_TOUCHSCREEN_USB_COMPOSITE 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_WM97XX is not set -# CONFIG_TOUCHSCREEN_ZFORCE 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_ENUM_MAP_FILE 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_KEYS is not set -# CONFIG_TSL2583 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_TYPHOON is not set -# CONFIG_UACCESS_WITH_MEMCPY is not set -# CONFIG_UBIFS_ATIME_SUPPORT is not set -# CONFIG_UBSAN is not set -# CONFIG_UCB1400_CORE is not set -# CONFIG_UCSI is not set -# CONFIG_UDF_FS is not set -CONFIG_UDF_NLS=y -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_UNIX=y -CONFIG_UNIX98_PTYS=y -# CONFIG_UNIXWARE_DISKLABEL is not set -# CONFIG_UNIX_DIAG is not set -# CONFIG_UNUSED_SYMBOLS is not set -# CONFIG_UPROBES is not set -# CONFIG_UPROBE_EVENT is not set -# CONFIG_US5182D is not set -# CONFIG_USB 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_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_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_CHAOSKEY is not set -# CONFIG_USB_CHIPIDEA is not set -# CONFIG_USB_CONFIGFS 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_DWC3 is not set -# CONFIG_USB_DWC3_EXYNOS 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_DYNAMIC_MINORS is not set -# CONFIG_USB_EG20T is not set -# CONFIG_USB_EHCI_ATH79 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_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_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_HWA_HCD is not set -# CONFIG_USB_IDMOUSE 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_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_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_MSM_OTG 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_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_FSM is not set -# CONFIG_USB_OTG_WHITELIST is not set -# CONFIG_USB_OXU210HP_HCD 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_RCAR_PHY is not set -# CONFIG_USB_RENESAS_USBHS is not set -# CONFIG_USB_RIO500 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_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_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_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_HCD 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_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_TEST_DRIVERS is not set -# CONFIG_VCNL4000 is not set -# CONFIG_VDSO 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_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_NET is not set -# CONFIG_VHOST_VSOCK is not set -# CONFIG_VIA_RHINE is not set -# CONFIG_VIA_VELOCITY 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_ADV_DEBUG is not set -# CONFIG_VIDEO_AK881X 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_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_EM28XX is not set -# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set -# CONFIG_VIDEO_GO7007 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_IR_I2C is not set -# CONFIG_VIDEO_IVTV is not set -# CONFIG_VIDEO_KS0127 is not set -# CONFIG_VIDEO_M52790 is not set -# CONFIG_VIDEO_ML86V7667 is not set -# CONFIG_VIDEO_MSP3400 is not set -# CONFIG_VIDEO_MT9M111 is not set -# CONFIG_VIDEO_MT9V011 is not set -# CONFIG_VIDEO_MXB is not set -# CONFIG_VIDEO_NOON010PC30 is not set -# CONFIG_VIDEO_OMAP2_VOUT is not set -# CONFIG_VIDEO_OV2659 is not set -# CONFIG_VIDEO_OV7640 is not set -# CONFIG_VIDEO_OV7670 is not set -# CONFIG_VIDEO_PVRUSB2 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_SONY_BTF_MPX is not set -# CONFIG_VIDEO_SR030PC30 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_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_ZORAN is not set -# CONFIG_VIRTIO_BALLOON is not set -# CONFIG_VIRTIO_INPUT is not set -# CONFIG_VIRTIO_MMIO 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_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_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_SLAVE_BQ27000 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_DS2431 is not set -# CONFIG_W1_SLAVE_DS2433 is not set -# CONFIG_W1_SLAVE_DS2760 is not set -# CONFIG_W1_SLAVE_DS2780 is not set -# CONFIG_W1_SLAVE_DS2781 is not set -# CONFIG_W1_SLAVE_DS28E04 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_WATCHDOG=y -# CONFIG_WATCHDOG_CORE is not set -# CONFIG_WATCHDOG_NOWAYOUT is not set -# CONFIG_WATCHDOG_PRETIMEOUT_GOV is not set -# CONFIG_WATCHDOG_SYSFS 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_WIMAX_GDM72XX is not set -CONFIG_WIRELESS=y -CONFIG_WIRELESS_EXT=y -# 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_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_WL_MEDIATEK is not set -CONFIG_WL_TI=y -CONFIG_WQ_POWER_EFFICIENT_DEFAULT=y -# CONFIG_WQ_WATCHDOG is not set -# CONFIG_X25 is not set -# CONFIG_X509_CERTIFICATE_PARSER is not set -# CONFIG_X86_DEBUG_STATIC_CPU_HAS is not set -# CONFIG_X86_PKG_TEMP_THERMAL is not set -CONFIG_X86_SYSFB=y -# CONFIG_XEN is not set -CONFIG_XFRM=y -# 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_POSIX_ACL is not set -# CONFIG_XFS_QUOTA is not set -# CONFIG_XFS_RT 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_WATCHDOG is not set -# CONFIG_XILINX_ZYNQMP_DMA is not set -# CONFIG_XILLYBUS 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_ZPA2326 is not set -# CONFIG_ZPOOL is not set -# CONFIG_ZRAM is not set -# CONFIG_ZSMALLOC is not set -CONFIG_TCP_CONG_LIA=y -CONFIG_TCP_CONG_OLIA=y -CONFIG_TCP_CONG_WVEGAS=y -CONFIG_TCP_CONG_BALIA=y -CONFIG_DEFAULT_TCP_CONG="olia" -CONFIG_MPTCP=y \ No newline at end of file diff --git a/root/target/linux/generic/config-5.4 b/root/target/linux/generic/config-5.4 deleted file mode 100644 index 3b71ac91..00000000 --- a/root/target/linux/generic/config-5.4 +++ /dev/null @@ -1,6501 +0,0 @@ -# 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_AD5791 is not set -# CONFIG_AD5933 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_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_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_ADIS16480 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_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_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_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_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_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_HAS_DEVMEM_IS_ALLOWED=y -# CONFIG_ARCH_HAS_ILOG2_U32 is not set -# CONFIG_ARCH_HAS_ILOG2_U64 is not set -CONFIG_ARCH_HAS_UBSAN_SANITIZE_ALL=y -# 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_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_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_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_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_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_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_CRYPTO is not set -# CONFIG_ARM64_ERRATUM_1024718 is not set -# CONFIG_ARM64_ERRATUM_1463225 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_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_UAO 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_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_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_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_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_GENERIC 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_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_LCD_SUPPORT 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_RPI is not set -# CONFIG_BACKLIGHT_SAHARA is not set -# CONFIG_BACKTRACE_SELF_TEST 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_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_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_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_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_BOOT_PRINTK_DELAY is not set -CONFIG_BOOT_RAW=y -CONFIG_BPF=y -# CONFIG_BPFILTER is not set -CONFIG_BPF_JIT=y -# CONFIG_BPF_JIT_ALWAYS_ON 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_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_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_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_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_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_J1939 is not set -# CONFIG_CAN_KVASER_PCIEFD is not set -# CONFIG_CAN_MCBA_USB 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_HAS_ASM_INLINE=y -CONFIG_CC_HAS_SANCOV_TRACE_PC=y -CONFIG_CC_HAS_STACKPROTECTOR_NONE=y -CONFIG_CC_HAS_WARN_MAYBE_UNINITIALIZED=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_CGROUP_BPF is not set -# CONFIG_CGROUP_DEBUG is not set -# CONFIG_CGROUP_HUGETLB is not set -# CONFIG_CGROUP_NET_CLASSID is not set -# CONFIG_CGROUP_NET_PRIO is not set -# CONFIG_CGROUP_RDMA is not set -# CONFIG_CHARGER_ADP5061 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_BQ25890 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=y -# CONFIG_CIFS_STATS2 is not set -# CONFIG_CIFS_WEAK_PW_HASH is not set -# CONFIG_CIFS_XATTR is not set -# 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_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_VERSATILE 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_CONFIG_KVM_AMD_SEV 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_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_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_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_CRASHLOG=y -# 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_BLKCIPHER=y -CONFIG_CRYPTO_BLKCIPHER2=y -# 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_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_DEFLATE is not set -# CONFIG_CRYPTO_DES 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_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_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_SHA512 is not set -# CONFIG_CRYPTO_SHA512_ARM is not set -# CONFIG_CRYPTO_SIMD is not set -# CONFIG_CRYPTO_SM3 is not set -# CONFIG_CRYPTO_SM4 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_HASH is not set -# CONFIG_CRYPTO_USER_API_RNG 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_CUSE is not set -# CONFIG_CW1200 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_FORCE_WEAK_PER_CPU is not set -CONFIG_DEBUG_FS=y -# 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_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_BCM63XX is not set -# CONFIG_DEBUG_USER is not set -# CONFIG_DEBUG_VIRTUAL is not set -# CONFIG_DEBUG_VM 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_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_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_DLM is not set -# CONFIG_DM9000 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_DECLARE_COHERENT=y -# CONFIG_DMA_ENGINE is not set -# CONFIG_DMA_FENCE_TRACE is not set -# CONFIG_DMA_JZ4780 is not set -# 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_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_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_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_CIRRUS_QEMU is not set -# CONFIG_DRM_DEBUG_MM is not set -# CONFIG_DRM_DEBUG_SELFTEST 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_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_NXP_PTN3460 is not set -# CONFIG_DRM_OMAP is not set -# CONFIG_DRM_PANEL_ARM_VERSATILE 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_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_PANASONIC_VVX10F034N00 is not set -# CONFIG_DRM_PANEL_RASPBERRYPI_TOUCHSCREEN is not set -# CONFIG_DRM_PANEL_RAYDIUM_RM68200 is not set -# CONFIG_DRM_PANEL_SAMSUNG_LD9040 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_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_SITRONIX_ST7789V is not set -# CONFIG_DRM_PANEL_SONY_ACX565AKM is not set -# CONFIG_DRM_PANEL_TPO_TD043MTEA1 is not set -# CONFIG_DRM_PANEL_TPO_TD028TTEC1 is not set -# CONFIG_DRM_PANEL_TPO_TPG110 is not set -# CONFIG_DRM_PANFROST is not set -# CONFIG_DRM_PARADE_PS8622 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_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_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_TOSHIBA_TC358764 is not set -# CONFIG_DRM_TOSHIBA_TC358767 is not set -# CONFIG_DRM_UDL is not set -# CONFIG_DRM_VBOXVIDEO 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_AU8522_V4L is not set -# CONFIG_DVB_CORE is not set -# CONFIG_DVB_DUMMY_FE is not set -# CONFIG_DVB_TUNER_DIB0070 is not set -# CONFIG_DVB_TUNER_DIB0090 is not set -# CONFIG_DWC_XLGMAC is not set -# CONFIG_DWMAC_DWC_QOS_ETH 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_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_EVENTFD=y -# 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 is not set -# 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_ENCRYPTION is not set -# CONFIG_F2FS_FS_POSIX_ACL is not set -# CONFIG_F2FS_FS_SECURITY is not set -# CONFIG_F2FS_IO_TRACE is not set -# CONFIG_FAILOVER is not set -# CONFIG_FAIR_GROUP_SCHED is not set -# CONFIG_FANOTIFY 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_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_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_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_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_PROBE=y -CONFIG_GENERIC_NET_UTILS=y -# CONFIG_GENERIC_PHY is not set -# 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_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_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_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_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_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_SX150X is not set -# CONFIG_GPIO_SYSCON is not set -# CONFIG_GPIO_SYSFS is not set -# 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_HAVE_AOUT is not set -CONFIG_HAVE_ARCH_HARDENED_USERCOPY=y -# CONFIG_HAVE_ARCH_HASH is not set -CONFIG_HAVE_ARCH_MMAP_RND_BITS=y -# CONFIG_HAVE_ARCH_VMAP_STACK is not set -CONFIG_HAVE_ARCH_WITHIN_STACK_FRAMES=y -# CONFIG_HAVE_ARM_ARCH_TIMER is not set -CONFIG_HAVE_EXIT_THREAD=y -CONFIG_HAVE_GCC_PLUGINS=y -CONFIG_HAVE_HARDENED_USERCOPY_ALLOCATOR=y -CONFIG_HAVE_KERNEL_BZIP2=y -CONFIG_HAVE_KERNEL_CAT=y -CONFIG_HAVE_KERNEL_GZIP=y -CONFIG_HAVE_KERNEL_LZ4=y -CONFIG_HAVE_KERNEL_LZMA=y -CONFIG_HAVE_KERNEL_LZO=y -CONFIG_HAVE_KERNEL_XZ=y -CONFIG_HAVE_KPROBES=y -CONFIG_HAVE_KRETPROBES=y -CONFIG_HAVE_NMI=y -CONFIG_HAVE_STACKPROTECTOR=y -# CONFIG_HCALL_STATS is not set -# CONFIG_HDC100X 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_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_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_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_FEMAC is not set -# CONFIG_HIX5HD2_GMAC 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_CAVIUM 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_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_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_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_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_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_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_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_IKCONFIG is not set -# CONFIG_IKCONFIG_PROC is not set -# CONFIG_IKHEADERS 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_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_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_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_INLINE_READ_LOCK is not set -# CONFIG_INLINE_READ_LOCK_BH is not set -# CONFIG_INLINE_READ_LOCK_IRQ is not set -# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set -# CONFIG_INLINE_READ_TRYLOCK is not set -CONFIG_INLINE_READ_UNLOCK=y -# CONFIG_INLINE_READ_UNLOCK_BH is not set -CONFIG_INLINE_READ_UNLOCK_IRQ=y -# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set -# CONFIG_INLINE_SPIN_LOCK is not set -# CONFIG_INLINE_SPIN_LOCK_BH is not set -# CONFIG_INLINE_SPIN_LOCK_IRQ is not set -# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set -# CONFIG_INLINE_SPIN_TRYLOCK is not set -# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set -# CONFIG_INLINE_SPIN_UNLOCK_BH is not set -CONFIG_INLINE_SPIN_UNLOCK_IRQ=y -# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set -# CONFIG_INLINE_WRITE_LOCK is not set -# CONFIG_INLINE_WRITE_LOCK_BH is not set -# CONFIG_INLINE_WRITE_LOCK_IRQ is not set -# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set -# CONFIG_INLINE_WRITE_TRYLOCK is not set -CONFIG_INLINE_WRITE_UNLOCK=y -# CONFIG_INLINE_WRITE_UNLOCK_BH is not set -CONFIG_INLINE_WRITE_UNLOCK_IRQ=y -# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set -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_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_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_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_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_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_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_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_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_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_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_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_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_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_KUSER_HELPERS=y -# CONFIG_KVM_AMD is not set -# CONFIG_KVM_GUEST is not set -# CONFIG_KVM_INTEL 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_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_CR0014114 is not set -# CONFIG_LEDS_DAC124S085 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_LP5521 is not set -# CONFIG_LEDS_LP5523 is not set -# CONFIG_LEDS_LP5562 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 is not set -# CONFIG_LEDS_TRIGGER_IDE_DISK is not set -# 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_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_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_LTC1660 is not set -# CONFIG_LTC2471 is not set -# CONFIG_LTC2485 is not set -# CONFIG_LTC2497 is not set -# CONFIG_LTC2632 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_JAZZ is not set -# CONFIG_MACH_JZ4740 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_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_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_HISI_FEMAC is not set -# CONFIG_MDIO_MSCC_MIIM is not set -# CONFIG_MDIO_OCTEON is not set -# CONFIG_MDIO_THUNDER 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_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_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_HI6421_PMIC is not set -# CONFIG_MFD_INTEL_QUARK_I2C_GPIO 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_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_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_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_T1_PHY is not set -# CONFIG_MICROSEMI_PHY is not set -# CONFIG_MIGRATION is not set -CONFIG_MII=y -# 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_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_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_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_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_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_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_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_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_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_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_BRNIMAGE_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_UIMAGE_SPLIT is not set -# CONFIG_MTD_VIRT_CONCAT is not set -# CONFIG_MTK_MMC 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_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_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_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_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_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_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_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_QCA 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_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_FIFO=y -# CONFIG_NET_SCH_FQ is not set -CONFIG_NET_SCH_FQ_CODEL=y -# 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_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_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_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_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_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_INJECT is not set -# CONFIG_PCIEASPM is not set -# CONFIG_PCIEPORTBUS is not set -# CONFIG_PCIE_ALTERA is not set -# CONFIG_PCIE_ARMADA_8K is not set -# CONFIG_PCIE_BW is not set -# CONFIG_PCIE_CADENCE_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_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_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_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_SIERRA 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_MAPPHONE_MDM6600 is not set -# CONFIG_PHY_MIXEL_MIPI_DPHY 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_OCELOT is not set -CONFIG_PINCTRL_SINGLE=y -# CONFIG_PINCTRL_STMFX is not set -# CONFIG_PINCTRL_SX150X 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_PLUGIN_HOSTCC="" -# 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_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_PREVENT_FIRMWARE_BUILD=y -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=y -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_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_PTP_1588_CLOCK 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_PUBLIC_KEY_ALGO_RSA is not set -# CONFIG_PVPANIC is not set -# CONFIG_PWM 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_QSEMI_PHY is not set -# CONFIG_QUEUED_LOCK_STAT 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_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_READABLE_ASM is not set -# CONFIG_REALTEK_PHY is not set -# CONFIG_REDWOOD is not set -# CONFIG_REED_SOLOMON_TEST is not set -# CONFIG_REFCOUNT_FULL 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_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_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_MT6311 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_SLG51000 is not set -# CONFIG_REGULATOR_SY8106A is not set -# CONFIG_REGULATOR_SY8824X 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 is not set -# 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_CONTROLLER is not set -# CONFIG_RESET_IMX7 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_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_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_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_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_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_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_DMESG_RESTRICT=y -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_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_BH1770 is not set -# CONFIG_SENSORS_BH1780 is not set -# CONFIG_SENSORS_CORETEMP is not set -# CONFIG_SENSORS_DELL_SMM is not set -# CONFIG_SENSORS_DME1737 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_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_MAX1668 is not set -# CONFIG_SENSORS_MAX197 is not set -# CONFIG_SENSORS_MAX20751 is not set -# CONFIG_SENSORS_MAX31722 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_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_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_XGENE is not set -# CONFIG_SENSORS_ZL6100 is not set -CONFIG_SERIAL_8250=y -# 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_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_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_IP32 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_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_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_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_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_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_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_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_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_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_JZ4725B_CODEC is not set -# CONFIG_SND_SOC_JZ4740_CODEC 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_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_MT8173 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_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_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_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_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_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_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_SX9500 is not set -# CONFIG_SXGBE_ETH is not set -# CONFIG_SYNCLINK_CS is not set -# CONFIG_SYNC_FILE is not set -# CONFIG_SYNOPSYS_DWC_ETH_QOS 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_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_BLACKHOLE_DEV is not set -# CONFIG_TEST_BPF is not set -# CONFIG_TEST_FIRMWARE 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_MEMCAT_P is not set -# CONFIG_TEST_MEMINIT 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_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_TINYDRM_HX8357D is not set -# CONFIG_TINYDRM_ILI9225 is not set -# CONFIG_TINYDRM_ILI9341 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_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_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_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_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_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_FORMAT4=y -# CONFIG_UBIFS_FS_SECURITY is not set -# CONFIG_UBIFS_FS_XATTR 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_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_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_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_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_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_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_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_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_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_FSM 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_RCAR_PHY is not set -# CONFIG_USB_RENESAS_USBHS is not set -# CONFIG_USB_RIO500 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_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_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_TEST_DRIVERS is not set -# CONFIG_VALIDATE_FS_PARSER is not set -# CONFIG_VBOXGUEST is not set -# CONFIG_VCNL4000 is not set -# CONFIG_VCNL4035 is not set -# CONFIG_VDSO 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_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_NET is not set -# CONFIG_VHOST_VSOCK is not set -# CONFIG_VIA_RHINE is not set -# CONFIG_VIA_VELOCITY 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_ADV_DEBUG is not set -# CONFIG_VIDEO_AK881X is not set -# CONFIG_VIDEO_ASPEED 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_EM28XX is not set -# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set -# CONFIG_VIDEO_GO7007 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_I2C is not set -# CONFIG_VIDEO_IR_I2C is not set -# CONFIG_VIDEO_IVTV is not set -# CONFIG_VIDEO_KS0127 is not set -# CONFIG_VIDEO_M52790 is not set -# CONFIG_VIDEO_ML86V7667 is not set -# CONFIG_VIDEO_MSP3400 is not set -# CONFIG_VIDEO_MT9M111 is not set -# CONFIG_VIDEO_MT9T112 is not set -# CONFIG_VIDEO_MT9V011 is not set -# CONFIG_VIDEO_MT9V111 is not set -# CONFIG_VIDEO_MXB is not set -# CONFIG_VIDEO_NOON010PC30 is not set -# CONFIG_VIDEO_OMAP2_VOUT is not set -# CONFIG_VIDEO_OV2640 is not set -# CONFIG_VIDEO_OV2659 is not set -# CONFIG_VIDEO_OV5695 is not set -# CONFIG_VIDEO_OV6650 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_OV9640 is not set -# CONFIG_VIDEO_PVRUSB2 is not set -# CONFIG_VIDEO_RJ54N1 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_SONY_BTF_MPX is not set -# CONFIG_VIDEO_SR030PC30 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_ZORAN is not set -# CONFIG_VIRTIO_BALLOON is not set -# CONFIG_VIRTIO_BLK_SCSI 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_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_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_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_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_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_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_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 -CONFIG_TCP_CONG_LIA=y -CONFIG_TCP_CONG_OLIA=y -CONFIG_TCP_CONG_WVEGAS=y -CONFIG_TCP_CONG_BALIA=y -CONFIG_TCP_CONG_MCTCPDESYNC=y -CONFIG_DEFAULT_TCP_CONG="cubic" -CONFIG_MPTCP=y -# CONFIG_DEFAULT_BALIA is not set -# CONFIG_DEFAULT_LIA is not set -# CONFIG_DEFAULT_OLIA is not set -# CONFIG_DEFAULT_WVEGAS is not set -# CONFIG_DEFAULT_BBR is not set -# CONFIG_DEFAULT_MCTCPDESYNC is not set -CONFIG_DEFAULT_CUBIC=y -CONFIG_DEFAULT_MPTCP_PM="default" -CONFIG_DEFAULT_MPTCP_SCHED="default" -CONFIG_MPTCP_PM_ADVANCED=y -CONFIG_MPTCP_SCHED_ADVANCED=y -CONFIG_MPTCP_FULLMESH=y -CONFIG_MPTCP_NDIFFPORTS=y -CONFIG_MPTCP_BINDER=y -CONFIG_MPTCP_ROUNDROBIN=y -CONFIG_MPTCP_BLEST=y -CONFIG_MPTCP_REDUNDANT=y -CONFIG_MPTCP_NETLINK=y -CONFIG_MPTCP_ECF=y -CONFIG_DEFAULT_FULLMESH=y -CONFIG_DEFAULT_SCHEDULER=y -# CONFIG_DEFAULT_NDIFFPORTS is not set -# CONFIG_DEFAULT_NETLINK is not set -# CONFIG_DEFAULT_BINDER is not set -# CONFIG_DEFAULT_DUMMY is not set -# CONFIG_DEFAULT_ROUNDROBIN is not set -# CONFIG_DEFAULT_BLEST is not set -# CONFIG_DEFAULT_REDUNDANT is not set -CONFIG_NF_CONNTRACK_CUSTOM=2 -CONFIG_CRYPTO_SHA256=y \ No newline at end of file diff --git a/root/target/linux/generic/hack-4.14/690-mptcp_v0.94.patch b/root/target/linux/generic/hack-4.14/690-mptcp_v0.94.patch deleted file mode 100644 index 1df18b04..00000000 --- a/root/target/linux/generic/hack-4.14/690-mptcp_v0.94.patch +++ /dev/null @@ -1,20725 +0,0 @@ -diff -aurN linux-4.14.174/Documentation/networking/ip-sysctl.txt mptcp-mptcp_v0.94/Documentation/networking/ip-sysctl.txt ---- linux-4.14.174/Documentation/networking/ip-sysctl.txt 2020-03-20 10:54:27.000000000 +0100 -+++ mptcp-mptcp_v0.94/Documentation/networking/ip-sysctl.txt 2020-03-23 09:45:33.000000000 +0100 -@@ -734,6 +734,18 @@ - in RFC 5961 (Improving TCP's Robustness to Blind In-Window Attacks) - Default: 100 - -+MPTCP variables: -+ -+mptcp_enabled - INTEGER -+ Enable or disable Multipath TCP for new connections. -+ Possible values are: -+ -+ 0: Multipath TCP is disabled on all TCP-sockets that are newly created. -+ 1: Multipath TCP is enabled by default on all new TCP-sockets. Note that -+ existing sockets in LISTEN-state will still use regular TCP. -+ 2: Enables Multipath TCP only upon the request of the application -+ throught the socket-option MPTCP_ENABLED. -+ - UDP variables: - - udp_l3mdev_accept - BOOLEAN -diff -aurN linux-4.14.174/drivers/infiniband/hw/cxgb4/cm.c mptcp-mptcp_v0.94/drivers/infiniband/hw/cxgb4/cm.c ---- linux-4.14.174/drivers/infiniband/hw/cxgb4/cm.c 2020-03-20 10:54:27.000000000 +0100 -+++ mptcp-mptcp_v0.94/drivers/infiniband/hw/cxgb4/cm.c 2020-03-23 09:45:33.000000000 +0100 -@@ -3757,7 +3757,7 @@ - */ - memset(&tmp_opt, 0, sizeof(tmp_opt)); - tcp_clear_options(&tmp_opt); -- tcp_parse_options(&init_net, skb, &tmp_opt, 0, NULL); -+ tcp_parse_options(&init_net, skb, &tmp_opt, NULL, 0, NULL, NULL); - - req = __skb_push(skb, sizeof(*req)); - memset(req, 0, sizeof(*req)); -diff -aurN linux-4.14.174/include/linux/skbuff.h mptcp-mptcp_v0.94/include/linux/skbuff.h ---- linux-4.14.174/include/linux/skbuff.h 2020-03-20 10:54:27.000000000 +0100 -+++ mptcp-mptcp_v0.94/include/linux/skbuff.h 2020-03-23 09:45:33.000000000 +0100 -@@ -690,7 +690,7 @@ - * want to keep them across layers you have to do a skb_clone() - * first. This is owned by whoever has the skb queued ATM. - */ -- char cb[48] __aligned(8); -+ char cb[80] __aligned(8); - - unsigned long _skb_refdst; - void (*destructor)(struct sk_buff *skb); -diff -aurN linux-4.14.174/include/linux/tcp.h mptcp-mptcp_v0.94/include/linux/tcp.h ---- linux-4.14.174/include/linux/tcp.h 2020-03-20 10:54:27.000000000 +0100 -+++ mptcp-mptcp_v0.94/include/linux/tcp.h 2020-03-23 09:45:33.000000000 +0100 -@@ -58,7 +58,7 @@ - /* TCP Fast Open */ - #define TCP_FASTOPEN_COOKIE_MIN 4 /* Min Fast Open Cookie size in bytes */ - #define TCP_FASTOPEN_COOKIE_MAX 16 /* Max Fast Open Cookie size in bytes */ --#define TCP_FASTOPEN_COOKIE_SIZE 8 /* the size employed by this impl. */ -+#define TCP_FASTOPEN_COOKIE_SIZE 4 /* the size employed by this impl. */ - - /* TCP Fast Open Cookie as stored in memory */ - struct tcp_fastopen_cookie { -@@ -83,6 +83,56 @@ - u32 end_seq; - }; - -+struct tcp_out_options { -+ u16 options; /* bit field of OPTION_* */ -+ u8 ws; /* window scale, 0 to disable */ -+ u8 num_sack_blocks;/* number of SACK blocks to include */ -+ u8 hash_size; /* bytes in hash_location */ -+ u16 mss; /* 0 to disable */ -+ __u8 *hash_location; /* temporary pointer, overloaded */ -+ __u32 tsval, tsecr; /* need to include OPTION_TS */ -+ struct tcp_fastopen_cookie *fastopen_cookie; /* Fast open cookie */ -+#ifdef CONFIG_MPTCP -+ u16 mptcp_options; /* bit field of MPTCP related OPTION_* */ -+ u8 dss_csum:1, /* dss-checksum required? */ -+ add_addr_v4:1, -+ add_addr_v6:1, -+ mptcp_ver:4; -+ -+ union { -+ struct { -+ __u64 sender_key; /* sender's key for mptcp */ -+ __u64 receiver_key; /* receiver's key for mptcp */ -+ } mp_capable; -+ -+ struct { -+ __u64 sender_truncated_mac; -+ __u32 sender_nonce; -+ /* random number of the sender */ -+ __u32 token; /* token for mptcp */ -+ u8 low_prio:1; -+ } mp_join_syns; -+ }; -+ -+ struct { -+ __u64 trunc_mac; -+ struct in_addr addr; -+ u16 port; -+ u8 addr_id; -+ } add_addr4; -+ -+ struct { -+ __u64 trunc_mac; -+ struct in6_addr addr; -+ u16 port; -+ u8 addr_id; -+ } add_addr6; -+ -+ u16 remove_addrs; /* list of address id */ -+ u8 addr_id; /* address id (mp_join or add_address) */ -+#endif /* CONFIG_MPTCP */ -+}; -+ - /*These are used to set the sack_ok field in struct tcp_options_received */ - #define TCP_SACK_SEEN (1 << 0) /*1 = peer is SACK capable, */ - #define TCP_FACK_ENABLED (1 << 1) /*1 = FACK is enabled locally*/ -@@ -106,6 +156,9 @@ - u16 mss_clamp; /* Maximal mss, negotiated at connection setup */ - }; - -+struct mptcp_cb; -+struct mptcp_tcp_sock; -+ - static inline void tcp_clear_options(struct tcp_options_received *rx_opt) - { - rx_opt->tstamp_ok = rx_opt->sack_ok = 0; -@@ -141,6 +194,8 @@ - return (struct tcp_request_sock *)req; - } - -+struct tcp_md5sig_key; -+ - struct tcp_sock { - /* inet_connection_sock has to be the first member of tcp_sock */ - struct inet_connection_sock inet_conn; -@@ -363,6 +418,44 @@ - */ - struct request_sock *fastopen_rsk; - u32 *saved_syn; -+ -+ /* MPTCP/TCP-specific callbacks */ -+ const struct tcp_sock_ops *ops; -+ -+ struct mptcp_cb *mpcb; -+ struct sock *meta_sk; -+ /* We keep these flags even if CONFIG_MPTCP is not checked, because -+ * it allows checking MPTCP capability just by checking the mpc flag, -+ * rather than adding ifdefs everywhere. -+ */ -+ u32 mpc:1, /* Other end is multipath capable */ -+ inside_tk_table:1, /* Is the tcp_sock inside the token-table? */ -+ send_mp_fclose:1, -+ request_mptcp:1, /* Did we send out an MP_CAPABLE? -+ * (this speeds up mptcp_doit() in tcp_recvmsg) -+ */ -+ pf:1, /* Potentially Failed state: when this flag is set, we -+ * stop using the subflow -+ */ -+ mp_killed:1, /* Killed with a tcp_done in mptcp? */ -+ is_master_sk:1, -+ close_it:1, /* Must close socket in mptcp_data_ready? */ -+ closing:1, -+ mptcp_ver:4, -+ mptcp_sched_setsockopt:1, -+ mptcp_pm_setsockopt:1, -+ record_master_info:1, -+ tcp_disconnect:1; -+ struct mptcp_tcp_sock *mptcp; -+#ifdef CONFIG_MPTCP -+#define MPTCP_SCHED_NAME_MAX 16 -+#define MPTCP_PM_NAME_MAX 16 -+ struct hlist_nulls_node tk_table; -+ u32 mptcp_loc_token; -+ u64 mptcp_loc_key; -+ char mptcp_sched_name[MPTCP_SCHED_NAME_MAX]; -+ char mptcp_pm_name[MPTCP_PM_NAME_MAX]; -+#endif /* CONFIG_MPTCP */ - }; - - enum tsq_enum { -@@ -374,6 +467,8 @@ - TCP_MTU_REDUCED_DEFERRED, /* tcp_v{4|6}_err() could not call - * tcp_v{4|6}_mtu_reduced() - */ -+ MPTCP_PATH_MANAGER_DEFERRED, /* MPTCP deferred creation of new subflows */ -+ MPTCP_SUB_DEFERRED, /* A subflow got deferred - process them */ - }; - - enum tsq_flags { -@@ -383,6 +478,8 @@ - TCPF_WRITE_TIMER_DEFERRED = (1UL << TCP_WRITE_TIMER_DEFERRED), - TCPF_DELACK_TIMER_DEFERRED = (1UL << TCP_DELACK_TIMER_DEFERRED), - TCPF_MTU_REDUCED_DEFERRED = (1UL << TCP_MTU_REDUCED_DEFERRED), -+ TCPF_PATH_MANAGER_DEFERRED = (1UL << MPTCP_PATH_MANAGER_DEFERRED), -+ TCPF_SUB_DEFERRED = (1UL << MPTCP_SUB_DEFERRED), - }; - - static inline struct tcp_sock *tcp_sk(const struct sock *sk) -@@ -405,6 +502,7 @@ - #ifdef CONFIG_TCP_MD5SIG - struct tcp_md5sig_key *tw_md5_key; - #endif -+ struct mptcp_tw *mptcp_tw; - }; - - static inline struct tcp_timewait_sock *tcp_twsk(const struct sock *sk) -diff -aurN linux-4.14.174/include/net/inet_common.h mptcp-mptcp_v0.94/include/net/inet_common.h ---- linux-4.14.174/include/net/inet_common.h 2020-03-20 10:54:27.000000000 +0100 -+++ mptcp-mptcp_v0.94/include/net/inet_common.h 2020-03-23 09:45:33.000000000 +0100 -@@ -2,6 +2,8 @@ - #ifndef _INET_COMMON_H - #define _INET_COMMON_H - -+#include -+ - extern const struct proto_ops inet_stream_ops; - extern const struct proto_ops inet_dgram_ops; - -@@ -14,6 +16,8 @@ - struct sockaddr; - struct socket; - -+int inet_create(struct net *net, struct socket *sock, int protocol, int kern); -+int inet6_create(struct net *net, struct socket *sock, int protocol, int kern); - int inet_release(struct socket *sock); - int inet_stream_connect(struct socket *sock, struct sockaddr *uaddr, - int addr_len, int flags); -diff -aurN linux-4.14.174/include/net/inet_connection_sock.h mptcp-mptcp_v0.94/include/net/inet_connection_sock.h ---- linux-4.14.174/include/net/inet_connection_sock.h 2020-03-20 10:54:27.000000000 +0100 -+++ mptcp-mptcp_v0.94/include/net/inet_connection_sock.h 2020-03-23 09:45:33.000000000 +0100 -@@ -30,6 +30,7 @@ - - struct inet_bind_bucket; - struct tcp_congestion_ops; -+struct tcp_options_received; - - /* - * Pointers to address related TCP functions -diff -aurN linux-4.14.174/include/net/inet_sock.h mptcp-mptcp_v0.94/include/net/inet_sock.h ---- linux-4.14.174/include/net/inet_sock.h 2020-03-20 10:54:27.000000000 +0100 -+++ mptcp-mptcp_v0.94/include/net/inet_sock.h 2020-03-23 09:45:33.000000000 +0100 -@@ -90,7 +90,9 @@ - wscale_ok : 1, - ecn_ok : 1, - acked : 1, -- no_srccheck: 1; -+ no_srccheck: 1, -+ mptcp_rqsk : 1, -+ saw_mpc : 1; - u32 ir_mark; - union { - struct ip_options_rcu __rcu *ireq_opt; -diff -aurN linux-4.14.174/include/net/mptcp.h mptcp-mptcp_v0.94/include/net/mptcp.h ---- linux-4.14.174/include/net/mptcp.h 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_v0.94/include/net/mptcp.h 2020-03-23 09:45:33.000000000 +0100 -@@ -0,0 +1,1529 @@ -+/* -+ * MPTCP implementation -+ * -+ * Initial Design & Implementation: -+ * Sébastien Barré -+ * -+ * Current Maintainer & Author: -+ * Christoph Paasch -+ * -+ * Additional authors: -+ * Jaakko Korkeaniemi -+ * Gregory Detal -+ * Fabien Duchêne -+ * Andreas Seelinger -+ * Lavkesh Lahngir -+ * Andreas Ripke -+ * Vlad Dogaru -+ * Octavian Purdila -+ * John Ronan -+ * Catalin Nicutar -+ * Brandon Heller -+ * -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version -+ * 2 of the License, or (at your option) any later version. -+ */ -+ -+#ifndef _MPTCP_H -+#define _MPTCP_H -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+ -+#if defined(__LITTLE_ENDIAN_BITFIELD) -+ #define ntohll(x) be64_to_cpu(x) -+ #define htonll(x) cpu_to_be64(x) -+#elif defined(__BIG_ENDIAN_BITFIELD) -+ #define ntohll(x) (x) -+ #define htonll(x) (x) -+#endif -+ -+struct mptcp_loc4 { -+ u8 loc4_id; -+ u8 low_prio:1; -+ int if_idx; -+ struct in_addr addr; -+}; -+ -+struct mptcp_rem4 { -+ u8 rem4_id; -+ __be16 port; -+ struct in_addr addr; -+}; -+ -+struct mptcp_loc6 { -+ u8 loc6_id; -+ u8 low_prio:1; -+ int if_idx; -+ struct in6_addr addr; -+}; -+ -+struct mptcp_rem6 { -+ u8 rem6_id; -+ __be16 port; -+ struct in6_addr addr; -+}; -+ -+struct mptcp_request_sock { -+ struct tcp_request_sock req; -+ struct hlist_nulls_node hash_entry; -+ -+ union { -+ struct { -+ /* Only on initial subflows */ -+ u64 mptcp_loc_key; -+ u64 mptcp_rem_key; -+ u32 mptcp_loc_token; -+ }; -+ -+ struct { -+ /* Only on additional subflows */ -+ u32 mptcp_rem_nonce; -+ u32 mptcp_loc_nonce; -+ u64 mptcp_hash_tmac; -+ }; -+ }; -+ -+ u8 loc_id; -+ u8 rem_id; /* Address-id in the MP_JOIN */ -+ u8 dss_csum:1, -+ is_sub:1, /* Is this a new subflow? */ -+ low_prio:1, /* Interface set to low-prio? */ -+ rcv_low_prio:1, -+ mptcp_ver:4; -+}; -+ -+struct mptcp_options_received { -+ u16 saw_mpc:1, -+ dss_csum:1, -+ drop_me:1, -+ -+ is_mp_join:1, -+ join_ack:1, -+ -+ saw_low_prio:2, /* 0x1 - low-prio set for this subflow -+ * 0x2 - low-prio set for another subflow -+ */ -+ low_prio:1, -+ -+ saw_add_addr:2, /* Saw at least one add_addr option: -+ * 0x1: IPv4 - 0x2: IPv6 -+ */ -+ more_add_addr:1, /* Saw one more add-addr. */ -+ -+ saw_rem_addr:1, /* Saw at least one rem_addr option */ -+ more_rem_addr:1, /* Saw one more rem-addr. */ -+ -+ mp_fail:1, -+ mp_fclose:1; -+ u8 rem_id; /* Address-id in the MP_JOIN */ -+ u8 prio_addr_id; /* Address-id in the MP_PRIO */ -+ -+ const unsigned char *add_addr_ptr; /* Pointer to add-address option */ -+ const unsigned char *rem_addr_ptr; /* Pointer to rem-address option */ -+ -+ u32 data_ack; -+ u32 data_seq; -+ u16 data_len; -+ -+ u8 mptcp_ver; /* MPTCP version */ -+ -+ /* Key inside the option (from mp_capable or fast_close) */ -+ u64 mptcp_sender_key; -+ u64 mptcp_receiver_key; -+ -+ u32 mptcp_rem_token; /* Remote token */ -+ -+ u32 mptcp_recv_nonce; -+ u64 mptcp_recv_tmac; -+ u8 mptcp_recv_mac[20]; -+}; -+ -+struct mptcp_tcp_sock { -+ struct tcp_sock *next; /* Next subflow socket */ -+ struct hlist_node cb_list; -+ struct mptcp_options_received rx_opt; -+ -+ /* Those three fields record the current mapping */ -+ u64 map_data_seq; -+ u32 map_subseq; -+ u16 map_data_len; -+ u16 slave_sk:1, -+ fully_established:1, -+ establish_increased:1, -+ second_packet:1, -+ attached:1, -+ send_mp_fail:1, -+ include_mpc:1, -+ mapping_present:1, -+ map_data_fin:1, -+ low_prio:1, /* use this socket as backup */ -+ rcv_low_prio:1, /* Peer sent low-prio option to us */ -+ send_mp_prio:1, /* Trigger to send mp_prio on this socket */ -+ pre_established:1; /* State between sending 3rd ACK and -+ * receiving the fourth ack of new subflows. -+ */ -+ -+ /* isn: needed to translate abs to relative subflow seqnums */ -+ u32 snt_isn; -+ u32 rcv_isn; -+ u8 path_index; -+ u8 loc_id; -+ u8 rem_id; -+ -+#define MPTCP_SCHED_SIZE 16 -+ u8 mptcp_sched[MPTCP_SCHED_SIZE] __aligned(8); -+ -+ int init_rcv_wnd; -+ u32 infinite_cutoff_seq; -+ struct delayed_work work; -+ u32 mptcp_loc_nonce; -+ struct tcp_sock *tp; /* Where is my daddy? */ -+ u32 last_end_data_seq; -+ -+ /* MP_JOIN subflow: timer for retransmitting the 3rd ack */ -+ struct timer_list mptcp_ack_timer; -+ -+ /* HMAC of the third ack */ -+ char sender_mac[20]; -+}; -+ -+struct mptcp_tw { -+ struct list_head list; -+ u64 loc_key; -+ u64 rcv_nxt; -+ struct mptcp_cb __rcu *mpcb; -+ u8 meta_tw:1, -+ in_list:1; -+}; -+ -+#define MPTCP_PM_NAME_MAX 16 -+struct mptcp_pm_ops { -+ struct list_head list; -+ -+ /* Signal the creation of a new MPTCP-session. */ -+ void (*new_session)(const struct sock *meta_sk); -+ void (*release_sock)(struct sock *meta_sk); -+ void (*fully_established)(struct sock *meta_sk); -+ void (*new_remote_address)(struct sock *meta_sk); -+ void (*subflow_error)(struct sock *meta_sk, struct sock *sk); -+ int (*get_local_id)(sa_family_t family, union inet_addr *addr, -+ struct net *net, bool *low_prio); -+ void (*addr_signal)(struct sock *sk, unsigned *size, -+ struct tcp_out_options *opts, struct sk_buff *skb); -+ void (*add_raddr)(struct mptcp_cb *mpcb, const union inet_addr *addr, -+ sa_family_t family, __be16 port, u8 id); -+ void (*rem_raddr)(struct mptcp_cb *mpcb, u8 rem_id); -+ void (*init_subsocket_v4)(struct sock *sk, struct in_addr addr); -+ void (*init_subsocket_v6)(struct sock *sk, struct in6_addr addr); -+ void (*delete_subflow)(struct sock *sk); -+ -+ char name[MPTCP_PM_NAME_MAX]; -+ struct module *owner; -+}; -+ -+#define MPTCP_SCHED_NAME_MAX 16 -+struct mptcp_sched_ops { -+ struct list_head list; -+ -+ struct sock * (*get_subflow)(struct sock *meta_sk, -+ struct sk_buff *skb, -+ bool zero_wnd_test); -+ struct sk_buff * (*next_segment)(struct sock *meta_sk, -+ int *reinject, -+ struct sock **subsk, -+ unsigned int *limit); -+ void (*init)(struct sock *sk); -+ void (*release)(struct sock *sk); -+ -+ char name[MPTCP_SCHED_NAME_MAX]; -+ struct module *owner; -+}; -+ -+struct mptcp_cb { -+ /* list of sockets in this multipath connection */ -+ struct tcp_sock *connection_list; -+ /* list of sockets that need a call to release_cb */ -+ struct hlist_head callback_list; -+ -+ /* High-order bits of 64-bit sequence numbers */ -+ u32 snd_high_order[2]; -+ u32 rcv_high_order[2]; -+ -+ u16 send_infinite_mapping:1, -+ in_time_wait:1, -+ list_rcvd:1, /* XXX TO REMOVE */ -+ addr_signal:1, /* Path-manager wants us to call addr_signal */ -+ dss_csum:1, -+ server_side:1, -+ infinite_mapping_rcv:1, -+ infinite_mapping_snd:1, -+ dfin_combined:1, /* Was the DFIN combined with subflow-fin? */ -+ passive_close:1, -+ snd_hiseq_index:1, /* Index in snd_high_order of snd_nxt */ -+ rcv_hiseq_index:1, /* Index in rcv_high_order of rcv_nxt */ -+ tcp_ca_explicit_set:1; /* was meta CC set by app? */ -+ -+ /* socket count in this connection */ -+ u8 cnt_subflows; -+ u8 cnt_established; -+ -+#define MPTCP_SCHED_DATA_SIZE 8 -+ u8 mptcp_sched[MPTCP_SCHED_DATA_SIZE] __aligned(8); -+ struct mptcp_sched_ops *sched_ops; -+ -+ struct sk_buff_head reinject_queue; -+ /* First cache-line boundary is here minus 8 bytes. But from the -+ * reinject-queue only the next and prev pointers are regularly -+ * accessed. Thus, the whole data-path is on a single cache-line. -+ */ -+ -+ u64 csum_cutoff_seq; -+ u64 infinite_rcv_seq; -+ -+ /***** Start of fields, used for connection closure */ -+ spinlock_t tw_lock; -+ unsigned char mptw_state; -+ u8 dfin_path_index; -+ -+ struct list_head tw_list; -+ -+ /***** Start of fields, used for subflow establishment and closure */ -+ atomic_t mpcb_refcnt; -+ -+ /* Mutex needed, because otherwise mptcp_close will complain that the -+ * socket is owned by the user. -+ * E.g., mptcp_sub_close_wq is taking the meta-lock. -+ */ -+ struct mutex mpcb_mutex; -+ -+ /***** Start of fields, used for subflow establishment */ -+ struct sock *meta_sk; -+ -+ /* Master socket, also part of the connection_list, this -+ * socket is the one that the application sees. -+ */ -+ struct sock *master_sk; -+ -+ __u64 mptcp_loc_key; -+ __u64 mptcp_rem_key; -+ __u32 mptcp_loc_token; -+ __u32 mptcp_rem_token; -+ -+#define MPTCP_PM_SIZE 608 -+ u8 mptcp_pm[MPTCP_PM_SIZE] __aligned(8); -+ struct mptcp_pm_ops *pm_ops; -+ -+ u32 path_index_bits; -+ /* Next pi to pick up in case a new path becomes available */ -+ u8 next_path_index; -+ -+ __u8 mptcp_ver; -+ -+ /* Original snd/rcvbuf of the initial subflow. -+ * Used for the new subflows on the server-side to allow correct -+ * autotuning -+ */ -+ int orig_sk_rcvbuf; -+ int orig_sk_sndbuf; -+ u32 orig_window_clamp; -+ -+ struct tcp_info *master_info; -+}; -+ -+#define MPTCP_VERSION_0 0 -+#define MPTCP_VERSION_1 1 -+ -+#define MPTCP_SUB_CAPABLE 0 -+#define MPTCP_SUB_LEN_CAPABLE_SYN 12 -+#define MPTCP_SUB_LEN_CAPABLE_SYN_ALIGN 12 -+#define MPTCP_SUB_LEN_CAPABLE_ACK 20 -+#define MPTCP_SUB_LEN_CAPABLE_ACK_ALIGN 20 -+ -+#define MPTCP_SUB_JOIN 1 -+#define MPTCP_SUB_LEN_JOIN_SYN 12 -+#define MPTCP_SUB_LEN_JOIN_SYN_ALIGN 12 -+#define MPTCP_SUB_LEN_JOIN_SYNACK 16 -+#define MPTCP_SUB_LEN_JOIN_SYNACK_ALIGN 16 -+#define MPTCP_SUB_LEN_JOIN_ACK 24 -+#define MPTCP_SUB_LEN_JOIN_ACK_ALIGN 24 -+ -+#define MPTCP_SUB_DSS 2 -+#define MPTCP_SUB_LEN_DSS 4 -+#define MPTCP_SUB_LEN_DSS_ALIGN 4 -+ -+/* Lengths for seq and ack are the ones without the generic MPTCP-option header, -+ * as they are part of the DSS-option. -+ * To get the total length, just add the different options together. -+ */ -+#define MPTCP_SUB_LEN_SEQ 10 -+#define MPTCP_SUB_LEN_SEQ_CSUM 12 -+#define MPTCP_SUB_LEN_SEQ_ALIGN 12 -+ -+#define MPTCP_SUB_LEN_SEQ_64 14 -+#define MPTCP_SUB_LEN_SEQ_CSUM_64 16 -+#define MPTCP_SUB_LEN_SEQ_64_ALIGN 16 -+ -+#define MPTCP_SUB_LEN_ACK 4 -+#define MPTCP_SUB_LEN_ACK_ALIGN 4 -+ -+#define MPTCP_SUB_LEN_ACK_64 8 -+#define MPTCP_SUB_LEN_ACK_64_ALIGN 8 -+ -+/* This is the "default" option-length we will send out most often. -+ * MPTCP DSS-header -+ * 32-bit data sequence number -+ * 32-bit data ack -+ * -+ * It is necessary to calculate the effective MSS we will be using when -+ * sending data. -+ */ -+#define MPTCP_SUB_LEN_DSM_ALIGN (MPTCP_SUB_LEN_DSS_ALIGN + \ -+ MPTCP_SUB_LEN_SEQ_ALIGN + \ -+ MPTCP_SUB_LEN_ACK_ALIGN) -+ -+#define MPTCP_SUB_ADD_ADDR 3 -+#define MPTCP_SUB_LEN_ADD_ADDR4 8 -+#define MPTCP_SUB_LEN_ADD_ADDR4_VER1 16 -+#define MPTCP_SUB_LEN_ADD_ADDR6 20 -+#define MPTCP_SUB_LEN_ADD_ADDR6_VER1 28 -+#define MPTCP_SUB_LEN_ADD_ADDR4_ALIGN 8 -+#define MPTCP_SUB_LEN_ADD_ADDR4_ALIGN_VER1 16 -+#define MPTCP_SUB_LEN_ADD_ADDR6_ALIGN 20 -+#define MPTCP_SUB_LEN_ADD_ADDR6_ALIGN_VER1 28 -+ -+#define MPTCP_SUB_REMOVE_ADDR 4 -+#define MPTCP_SUB_LEN_REMOVE_ADDR 4 -+ -+#define MPTCP_SUB_PRIO 5 -+#define MPTCP_SUB_LEN_PRIO 3 -+#define MPTCP_SUB_LEN_PRIO_ADDR 4 -+#define MPTCP_SUB_LEN_PRIO_ALIGN 4 -+ -+#define MPTCP_SUB_FAIL 6 -+#define MPTCP_SUB_LEN_FAIL 12 -+#define MPTCP_SUB_LEN_FAIL_ALIGN 12 -+ -+#define MPTCP_SUB_FCLOSE 7 -+#define MPTCP_SUB_LEN_FCLOSE 12 -+#define MPTCP_SUB_LEN_FCLOSE_ALIGN 12 -+ -+ -+#define OPTION_MPTCP (1 << 5) -+ -+/* Max number of fastclose retransmissions */ -+#define MPTCP_FASTCLOSE_RETRIES 3 -+ -+#ifdef CONFIG_MPTCP -+ -+/* Used for checking if the mptcp initialization has been successful */ -+extern bool mptcp_init_failed; -+ -+/* MPTCP options */ -+#define OPTION_TYPE_SYN (1 << 0) -+#define OPTION_TYPE_SYNACK (1 << 1) -+#define OPTION_TYPE_ACK (1 << 2) -+#define OPTION_MP_CAPABLE (1 << 3) -+#define OPTION_DATA_ACK (1 << 4) -+#define OPTION_ADD_ADDR (1 << 5) -+#define OPTION_MP_JOIN (1 << 6) -+#define OPTION_MP_FAIL (1 << 7) -+#define OPTION_MP_FCLOSE (1 << 8) -+#define OPTION_REMOVE_ADDR (1 << 9) -+#define OPTION_MP_PRIO (1 << 10) -+ -+/* MPTCP flags: both TX and RX */ -+#define MPTCPHDR_SEQ 0x01 /* DSS.M option is present */ -+#define MPTCPHDR_FIN 0x02 /* DSS.F option is present */ -+#define MPTCPHDR_SEQ64_INDEX 0x04 /* index of seq in mpcb->snd_high_order */ -+/* MPTCP flags: RX only */ -+#define MPTCPHDR_ACK 0x08 -+#define MPTCPHDR_SEQ64_SET 0x10 /* Did we received a 64-bit seq number? */ -+#define MPTCPHDR_SEQ64_OFO 0x20 /* Is it not in our circular array? */ -+#define MPTCPHDR_DSS_CSUM 0x40 -+/* MPTCP flags: TX only */ -+#define MPTCPHDR_INF 0x08 -+#define MPTCP_REINJECT 0x10 /* Did we reinject this segment? */ -+ -+struct mptcp_option { -+ __u8 kind; -+ __u8 len; -+#if defined(__LITTLE_ENDIAN_BITFIELD) -+ __u8 ver:4, -+ sub:4; -+#elif defined(__BIG_ENDIAN_BITFIELD) -+ __u8 sub:4, -+ ver:4; -+#else -+#error "Adjust your defines" -+#endif -+}; -+ -+struct mp_capable { -+ __u8 kind; -+ __u8 len; -+#if defined(__LITTLE_ENDIAN_BITFIELD) -+ __u8 ver:4, -+ sub:4; -+ __u8 h:1, -+ rsv:5, -+ b:1, -+ a:1; -+#elif defined(__BIG_ENDIAN_BITFIELD) -+ __u8 sub:4, -+ ver:4; -+ __u8 a:1, -+ b:1, -+ rsv:5, -+ h:1; -+#else -+#error "Adjust your defines" -+#endif -+ __u64 sender_key; -+ __u64 receiver_key; -+} __attribute__((__packed__)); -+ -+struct mp_join { -+ __u8 kind; -+ __u8 len; -+#if defined(__LITTLE_ENDIAN_BITFIELD) -+ __u8 b:1, -+ rsv:3, -+ sub:4; -+#elif defined(__BIG_ENDIAN_BITFIELD) -+ __u8 sub:4, -+ rsv:3, -+ b:1; -+#else -+#error "Adjust your defines" -+#endif -+ __u8 addr_id; -+ union { -+ struct { -+ u32 token; -+ u32 nonce; -+ } syn; -+ struct { -+ __u64 mac; -+ u32 nonce; -+ } synack; -+ struct { -+ __u8 mac[20]; -+ } ack; -+ } u; -+} __attribute__((__packed__)); -+ -+struct mp_dss { -+ __u8 kind; -+ __u8 len; -+#if defined(__LITTLE_ENDIAN_BITFIELD) -+ __u16 rsv1:4, -+ sub:4, -+ A:1, -+ a:1, -+ M:1, -+ m:1, -+ F:1, -+ rsv2:3; -+#elif defined(__BIG_ENDIAN_BITFIELD) -+ __u16 sub:4, -+ rsv1:4, -+ rsv2:3, -+ F:1, -+ m:1, -+ M:1, -+ a:1, -+ A:1; -+#else -+#error "Adjust your defines" -+#endif -+}; -+ -+struct mp_add_addr { -+ __u8 kind; -+ __u8 len; -+#if defined(__LITTLE_ENDIAN_BITFIELD) -+ __u8 ipver:4, -+ sub:4; -+#elif defined(__BIG_ENDIAN_BITFIELD) -+ __u8 sub:4, -+ ipver:4; -+#else -+#error "Adjust your defines" -+#endif -+ __u8 addr_id; -+ union { -+ struct { -+ struct in_addr addr; -+ __be16 port; -+ __u8 mac[8]; -+ } v4; -+ struct { -+ struct in6_addr addr; -+ __be16 port; -+ __u8 mac[8]; -+ } v6; -+ } u; -+} __attribute__((__packed__)); -+ -+struct mp_remove_addr { -+ __u8 kind; -+ __u8 len; -+#if defined(__LITTLE_ENDIAN_BITFIELD) -+ __u8 rsv:4, -+ sub:4; -+#elif defined(__BIG_ENDIAN_BITFIELD) -+ __u8 sub:4, -+ rsv:4; -+#else -+#error "Adjust your defines" -+#endif -+ /* list of addr_id */ -+ __u8 addrs_id; -+}; -+ -+struct mp_fail { -+ __u8 kind; -+ __u8 len; -+#if defined(__LITTLE_ENDIAN_BITFIELD) -+ __u16 rsv1:4, -+ sub:4, -+ rsv2:8; -+#elif defined(__BIG_ENDIAN_BITFIELD) -+ __u16 sub:4, -+ rsv1:4, -+ rsv2:8; -+#else -+#error "Adjust your defines" -+#endif -+ __be64 data_seq; -+} __attribute__((__packed__)); -+ -+struct mp_fclose { -+ __u8 kind; -+ __u8 len; -+#if defined(__LITTLE_ENDIAN_BITFIELD) -+ __u16 rsv1:4, -+ sub:4, -+ rsv2:8; -+#elif defined(__BIG_ENDIAN_BITFIELD) -+ __u16 sub:4, -+ rsv1:4, -+ rsv2:8; -+#else -+#error "Adjust your defines" -+#endif -+ __u64 key; -+} __attribute__((__packed__)); -+ -+struct mp_prio { -+ __u8 kind; -+ __u8 len; -+#if defined(__LITTLE_ENDIAN_BITFIELD) -+ __u8 b:1, -+ rsv:3, -+ sub:4; -+#elif defined(__BIG_ENDIAN_BITFIELD) -+ __u8 sub:4, -+ rsv:3, -+ b:1; -+#else -+#error "Adjust your defines" -+#endif -+ __u8 addr_id; -+} __attribute__((__packed__)); -+ -+static inline int mptcp_sub_len_dss(const struct mp_dss *m, const int csum) -+{ -+ return 4 + m->A * (4 + m->a * 4) + m->M * (10 + m->m * 4 + csum * 2); -+} -+ -+#define MPTCP_SYSCTL 1 -+ -+extern int sysctl_mptcp_enabled; -+extern int sysctl_mptcp_version; -+extern int sysctl_mptcp_checksum; -+extern int sysctl_mptcp_debug; -+extern int sysctl_mptcp_syn_retries; -+ -+extern struct workqueue_struct *mptcp_wq; -+ -+#define mptcp_debug(fmt, args...) \ -+ do { \ -+ if (unlikely(sysctl_mptcp_debug)) \ -+ pr_err(fmt, ##args); \ -+ } while (0) -+ -+/* Iterates over all subflows */ -+#define mptcp_for_each_tp(mpcb, tp) \ -+ for ((tp) = (mpcb)->connection_list; (tp); (tp) = (tp)->mptcp->next) -+ -+#define mptcp_for_each_sk(mpcb, sk) \ -+ for ((sk) = (struct sock *)(mpcb)->connection_list; \ -+ sk; \ -+ sk = (struct sock *)tcp_sk(sk)->mptcp->next) -+ -+#define mptcp_for_each_sk_safe(__mpcb, __sk, __temp) \ -+ for (__sk = (struct sock *)(__mpcb)->connection_list, \ -+ __temp = __sk ? (struct sock *)tcp_sk(__sk)->mptcp->next : NULL; \ -+ __sk; \ -+ __sk = __temp, \ -+ __temp = __sk ? (struct sock *)tcp_sk(__sk)->mptcp->next : NULL) -+ -+/* Iterates over all bit set to 1 in a bitset */ -+#define mptcp_for_each_bit_set(b, i) \ -+ for (i = ffs(b) - 1; i >= 0; i = ffs(b >> (i + 1) << (i + 1)) - 1) -+ -+#define mptcp_for_each_bit_unset(b, i) \ -+ mptcp_for_each_bit_set(~b, i) -+ -+#define MPTCP_INC_STATS(net, field) SNMP_INC_STATS((net)->mptcp.mptcp_statistics, field) -+#define MPTCP_INC_STATS_BH(net, field) __SNMP_INC_STATS((net)->mptcp.mptcp_statistics, field) -+ -+enum -+{ -+ MPTCP_MIB_NUM = 0, -+ MPTCP_MIB_MPCAPABLEPASSIVE, /* Received SYN with MP_CAPABLE */ -+ MPTCP_MIB_MPCAPABLEACTIVE, /* Sent SYN with MP_CAPABLE */ -+ MPTCP_MIB_MPCAPABLEACTIVEACK, /* Received SYN/ACK with MP_CAPABLE */ -+ MPTCP_MIB_MPCAPABLEPASSIVEACK, /* Received third ACK with MP_CAPABLE */ -+ MPTCP_MIB_MPCAPABLEPASSIVEFALLBACK,/* Server-side fallback during 3-way handshake */ -+ MPTCP_MIB_MPCAPABLEACTIVEFALLBACK, /* Client-side fallback during 3-way handshake */ -+ MPTCP_MIB_MPCAPABLERETRANSFALLBACK,/* Client-side stopped sending MP_CAPABLE after too many SYN-retransmissions */ -+ MPTCP_MIB_CSUMENABLED, /* Created MPTCP-connection with DSS-checksum enabled */ -+ MPTCP_MIB_RETRANSSEGS, /* Segments retransmitted at the MPTCP-level */ -+ MPTCP_MIB_MPFAILRX, /* Received an MP_FAIL */ -+ MPTCP_MIB_CSUMFAIL, /* Received segment with invalid checksum */ -+ MPTCP_MIB_FASTCLOSERX, /* Recevied a FAST_CLOSE */ -+ MPTCP_MIB_FASTCLOSETX, /* Sent a FAST_CLOSE */ -+ MPTCP_MIB_FBACKSUB, /* Fallback upon ack without data-ack on new subflow */ -+ MPTCP_MIB_FBACKINIT, /* Fallback upon ack without data-ack on initial subflow */ -+ MPTCP_MIB_FBDATASUB, /* Fallback upon data without DSS at the beginning on new subflow */ -+ MPTCP_MIB_FBDATAINIT, /* Fallback upon data without DSS at the beginning on initial subflow */ -+ MPTCP_MIB_REMADDRSUB, /* Remove subflow due to REMOVE_ADDR */ -+ MPTCP_MIB_JOINNOTOKEN, /* Received MP_JOIN but the token was not found */ -+ MPTCP_MIB_JOINFALLBACK, /* Received MP_JOIN on session that has fallen back to reg. TCP */ -+ MPTCP_MIB_JOINSYNTX, /* Sent a SYN + MP_JOIN */ -+ MPTCP_MIB_JOINSYNRX, /* Received a SYN + MP_JOIN */ -+ MPTCP_MIB_JOINSYNACKRX, /* Received a SYN/ACK + MP_JOIN */ -+ MPTCP_MIB_JOINSYNACKMAC, /* HMAC was wrong on SYN/ACK + MP_JOIN */ -+ MPTCP_MIB_JOINACKRX, /* Received an ACK + MP_JOIN */ -+ MPTCP_MIB_JOINACKMAC, /* HMAC was wrong on ACK + MP_JOIN */ -+ MPTCP_MIB_JOINACKFAIL, /* Third ACK on new subflow did not contain an MP_JOIN */ -+ MPTCP_MIB_JOINACKRTO, /* Retransmission timer for third ACK + MP_JOIN timed out */ -+ MPTCP_MIB_JOINACKRXMIT, /* Retransmitted an ACK + MP_JOIN */ -+ MPTCP_MIB_NODSSWINDOW, /* Received too many packets without a DSS-option */ -+ MPTCP_MIB_DSSNOMATCH, /* Received a new mapping that did not match the previous one */ -+ MPTCP_MIB_INFINITEMAPRX, /* Received an infinite mapping */ -+ MPTCP_MIB_DSSTCPMISMATCH, /* DSS-mapping did not map with TCP's sequence numbers */ -+ MPTCP_MIB_DSSTRIMHEAD, /* Trimmed segment at the head (coalescing middlebox) */ -+ MPTCP_MIB_DSSSPLITTAIL, /* Trimmed segment at the tail (coalescing middlebox) */ -+ MPTCP_MIB_PURGEOLD, /* Removed old skb from the rcv-queue due to missing DSS-mapping */ -+ MPTCP_MIB_ADDADDRRX, /* Received an ADD_ADDR */ -+ MPTCP_MIB_ADDADDRTX, /* Sent an ADD_ADDR */ -+ MPTCP_MIB_REMADDRRX, /* Received a REMOVE_ADDR */ -+ MPTCP_MIB_REMADDRTX, /* Sent a REMOVE_ADDR */ -+ __MPTCP_MIB_MAX -+}; -+ -+#define MPTCP_MIB_MAX __MPTCP_MIB_MAX -+struct mptcp_mib { -+ unsigned long mibs[MPTCP_MIB_MAX]; -+}; -+ -+extern struct lock_class_key meta_key; -+extern char *meta_key_name; -+extern struct lock_class_key meta_slock_key; -+extern char *meta_slock_key_name; -+ -+extern siphash_key_t mptcp_secret; -+ -+/* This is needed to ensure that two subsequent key/nonce-generation result in -+ * different keys/nonces if the IPs and ports are the same. -+ */ -+extern u32 mptcp_seed; -+ -+#define MPTCP_HASH_SIZE 1024 -+ -+extern struct hlist_nulls_head tk_hashtable[MPTCP_HASH_SIZE]; -+ -+/* Request-sockets can be hashed in the tk_htb for collision-detection or in -+ * the regular htb for join-connections. We need to define different NULLS -+ * values so that we can correctly detect a request-socket that has been -+ * recycled. See also c25eb3bfb9729. -+ */ -+#define MPTCP_REQSK_NULLS_BASE (1U << 29) -+ -+ -+void mptcp_data_ready(struct sock *sk); -+void mptcp_write_space(struct sock *sk); -+ -+void mptcp_add_meta_ofo_queue(const struct sock *meta_sk, struct sk_buff *skb, -+ struct sock *sk); -+void mptcp_cleanup_rbuf(struct sock *meta_sk, int copied); -+int mptcp_add_sock(struct sock *meta_sk, struct sock *sk, u8 loc_id, u8 rem_id, -+ gfp_t flags); -+void mptcp_del_sock(struct sock *sk); -+void mptcp_update_metasocket(const struct sock *meta_sk); -+void mptcp_reinject_data(struct sock *orig_sk, int clone_it); -+void mptcp_update_sndbuf(const struct tcp_sock *tp); -+void mptcp_send_fin(struct sock *meta_sk); -+void mptcp_send_active_reset(struct sock *meta_sk, gfp_t priority); -+bool mptcp_write_xmit(struct sock *sk, unsigned int mss_now, int nonagle, -+ int push_one, gfp_t gfp); -+void tcp_parse_mptcp_options(const struct sk_buff *skb, -+ struct mptcp_options_received *mopt); -+void mptcp_parse_options(const uint8_t *ptr, int opsize, -+ struct mptcp_options_received *mopt, -+ const struct sk_buff *skb, -+ struct tcp_sock *tp); -+void mptcp_syn_options(const struct sock *sk, struct tcp_out_options *opts, -+ unsigned *remaining); -+void mptcp_synack_options(struct request_sock *req, -+ struct tcp_out_options *opts, -+ unsigned *remaining); -+void mptcp_established_options(struct sock *sk, struct sk_buff *skb, -+ struct tcp_out_options *opts, unsigned *size); -+void mptcp_options_write(__be32 *ptr, struct tcp_sock *tp, -+ const struct tcp_out_options *opts, -+ struct sk_buff *skb); -+void mptcp_close(struct sock *meta_sk, long timeout); -+int mptcp_doit(struct sock *sk); -+int mptcp_create_master_sk(struct sock *meta_sk, __u64 remote_key, -+ __u8 mptcp_ver, u32 window); -+int mptcp_check_req_fastopen(struct sock *child, struct request_sock *req); -+int mptcp_check_req_master(struct sock *sk, struct sock *child, -+ struct request_sock *req, const struct sk_buff *skb, -+ int drop, u32 tsoff); -+struct sock *mptcp_check_req_child(struct sock *meta_sk, -+ struct sock *child, -+ struct request_sock *req, -+ struct sk_buff *skb, -+ const struct mptcp_options_received *mopt); -+u32 __mptcp_select_window(struct sock *sk); -+void mptcp_select_initial_window(int __space, __u32 mss, __u32 *rcv_wnd, -+ __u32 *window_clamp, int wscale_ok, -+ __u8 *rcv_wscale, __u32 init_rcv_wnd, -+ const struct sock *sk); -+unsigned int mptcp_current_mss(struct sock *meta_sk); -+int mptcp_select_size(const struct sock *meta_sk, bool sg, bool first_skb); -+void mptcp_key_sha1(u64 key, u32 *token, u64 *idsn); -+void mptcp_hmac_sha1(const u8 *key_1, const u8 *key_2, u32 *hash_out, -+ int arg_num, ...); -+void mptcp_clean_rtx_infinite(const struct sk_buff *skb, struct sock *sk); -+void mptcp_fin(struct sock *meta_sk); -+void mptcp_meta_retransmit_timer(struct sock *meta_sk); -+void mptcp_sub_retransmit_timer(struct sock *sk); -+int mptcp_write_wakeup(struct sock *meta_sk, int mib); -+void mptcp_sub_close_wq(struct work_struct *work); -+void mptcp_sub_close(struct sock *sk, unsigned long delay); -+struct sock *mptcp_select_ack_sock(const struct sock *meta_sk); -+void mptcp_prepare_for_backlog(struct sock *sk, struct sk_buff *skb); -+int mptcp_backlog_rcv(struct sock *meta_sk, struct sk_buff *skb); -+void mptcp_ack_handler(unsigned long); -+bool mptcp_check_rtt(const struct tcp_sock *tp, int time); -+int mptcp_check_snd_buf(const struct tcp_sock *tp); -+bool mptcp_handle_options(struct sock *sk, const struct tcphdr *th, -+ const struct sk_buff *skb); -+void __init mptcp_init(void); -+void mptcp_destroy_sock(struct sock *sk); -+int mptcp_rcv_synsent_state_process(struct sock *sk, struct sock **skptr, -+ const struct sk_buff *skb, -+ const struct mptcp_options_received *mopt); -+unsigned int mptcp_xmit_size_goal(const struct sock *meta_sk, u32 mss_now, -+ int large_allowed); -+int mptcp_init_tw_sock(struct sock *sk, struct tcp_timewait_sock *tw); -+void mptcp_twsk_destructor(struct tcp_timewait_sock *tw); -+void mptcp_time_wait(struct sock *sk, int state, int timeo); -+void mptcp_disconnect(struct sock *meta_sk); -+bool mptcp_should_expand_sndbuf(const struct sock *sk); -+int mptcp_retransmit_skb(struct sock *meta_sk, struct sk_buff *skb); -+void mptcp_tsq_flags(struct sock *sk); -+void mptcp_tsq_sub_deferred(struct sock *meta_sk); -+struct mp_join *mptcp_find_join(const struct sk_buff *skb); -+void mptcp_hash_remove_bh(struct tcp_sock *meta_tp); -+struct sock *mptcp_hash_find(const struct net *net, const u32 token); -+int mptcp_lookup_join(struct sk_buff *skb, struct inet_timewait_sock *tw); -+int mptcp_do_join_short(struct sk_buff *skb, -+ const struct mptcp_options_received *mopt, -+ struct net *net); -+void mptcp_reqsk_destructor(struct request_sock *req); -+void mptcp_connect_init(struct sock *sk); -+void mptcp_sub_force_close(struct sock *sk); -+int mptcp_sub_len_remove_addr_align(u16 bitfield); -+void mptcp_init_buffer_space(struct sock *sk); -+void mptcp_join_reqsk_init(const struct mptcp_cb *mpcb, -+ const struct request_sock *req, -+ struct sk_buff *skb); -+void mptcp_reqsk_init(struct request_sock *req, const struct sock *sk, -+ const struct sk_buff *skb, bool want_cookie); -+int mptcp_conn_request(struct sock *sk, struct sk_buff *skb); -+void mptcp_enable_sock(struct sock *sk); -+void mptcp_disable_sock(struct sock *sk); -+void mptcp_disable_static_key(void); -+void mptcp_cookies_reqsk_init(struct request_sock *req, -+ struct mptcp_options_received *mopt, -+ struct sk_buff *skb); -+void mptcp_mpcb_put(struct mptcp_cb *mpcb); -+int mptcp_finish_handshake(struct sock *child, struct sk_buff *skb); -+int mptcp_get_info(const struct sock *meta_sk, char __user *optval, int optlen); -+void mptcp_clear_sk(struct sock *sk, int size); -+ -+/* MPTCP-path-manager registration/initialization functions */ -+int mptcp_register_path_manager(struct mptcp_pm_ops *pm); -+void mptcp_unregister_path_manager(struct mptcp_pm_ops *pm); -+void mptcp_init_path_manager(struct mptcp_cb *mpcb); -+void mptcp_cleanup_path_manager(struct mptcp_cb *mpcb); -+void mptcp_fallback_default(struct mptcp_cb *mpcb); -+void mptcp_get_default_path_manager(char *name); -+int mptcp_set_scheduler(struct sock *sk, const char *name); -+int mptcp_set_path_manager(struct sock *sk, const char *name); -+int mptcp_set_default_path_manager(const char *name); -+extern struct mptcp_pm_ops mptcp_pm_default; -+ -+/* MPTCP-scheduler registration/initialization functions */ -+int mptcp_register_scheduler(struct mptcp_sched_ops *sched); -+void mptcp_unregister_scheduler(struct mptcp_sched_ops *sched); -+void mptcp_init_scheduler(struct mptcp_cb *mpcb); -+void mptcp_cleanup_scheduler(struct mptcp_cb *mpcb); -+void mptcp_get_default_scheduler(char *name); -+int mptcp_set_default_scheduler(const char *name); -+bool mptcp_is_available(struct sock *sk, const struct sk_buff *skb, -+ bool zero_wnd_test); -+bool mptcp_is_def_unavailable(struct sock *sk); -+bool subflow_is_active(const struct tcp_sock *tp); -+bool subflow_is_backup(const struct tcp_sock *tp); -+struct sock *get_available_subflow(struct sock *meta_sk, struct sk_buff *skb, -+ bool zero_wnd_test); -+extern struct mptcp_sched_ops mptcp_sched_default; -+ -+/* Initializes function-pointers and MPTCP-flags */ -+static inline void mptcp_init_tcp_sock(struct sock *sk) -+{ -+ if (!mptcp_init_failed && sysctl_mptcp_enabled == MPTCP_SYSCTL) -+ mptcp_enable_sock(sk); -+} -+ -+static inline int mptcp_pi_to_flag(int pi) -+{ -+ return 1 << (pi - 1); -+} -+ -+static inline -+struct mptcp_request_sock *mptcp_rsk(const struct request_sock *req) -+{ -+ return (struct mptcp_request_sock *)req; -+} -+ -+static inline -+struct request_sock *rev_mptcp_rsk(const struct mptcp_request_sock *req) -+{ -+ return (struct request_sock *)req; -+} -+ -+static inline bool mptcp_can_sendpage(struct sock *sk) -+{ -+ struct sock *sk_it; -+ -+ if (tcp_sk(sk)->mpcb->dss_csum) -+ return false; -+ -+ mptcp_for_each_sk(tcp_sk(sk)->mpcb, sk_it) { -+ if (!(sk_it->sk_route_caps & NETIF_F_SG) || -+ !sk_check_csum_caps(sk_it)) -+ return false; -+ } -+ -+ return true; -+} -+ -+static inline void mptcp_push_pending_frames(struct sock *meta_sk) -+{ -+ /* We check packets out and send-head here. TCP only checks the -+ * send-head. But, MPTCP also checks packets_out, as this is an -+ * indication that we might want to do opportunistic reinjection. -+ */ -+ if (tcp_sk(meta_sk)->packets_out || tcp_send_head(meta_sk)) { -+ struct tcp_sock *tp = tcp_sk(meta_sk); -+ -+ /* We don't care about the MSS, because it will be set in -+ * mptcp_write_xmit. -+ */ -+ __tcp_push_pending_frames(meta_sk, 0, tp->nonagle); -+ } -+} -+ -+static inline void mptcp_send_reset(struct sock *sk) -+{ -+ if (tcp_need_reset(sk->sk_state)) -+ tcp_sk(sk)->ops->send_active_reset(sk, GFP_ATOMIC); -+ mptcp_sub_force_close(sk); -+} -+ -+static inline void mptcp_sub_force_close_all(struct mptcp_cb *mpcb, -+ struct sock *except) -+{ -+ struct sock *sk_it, *tmp; -+ -+ mptcp_for_each_sk_safe(mpcb, sk_it, tmp) { -+ if (sk_it != except) -+ mptcp_send_reset(sk_it); -+ } -+} -+ -+static inline bool mptcp_is_data_seq(const struct sk_buff *skb) -+{ -+ return TCP_SKB_CB(skb)->mptcp_flags & MPTCPHDR_SEQ; -+} -+ -+static inline bool mptcp_is_data_fin(const struct sk_buff *skb) -+{ -+ return TCP_SKB_CB(skb)->mptcp_flags & MPTCPHDR_FIN; -+} -+ -+/* Is it a data-fin while in infinite mapping mode? -+ * In infinite mode, a subflow-fin is in fact a data-fin. -+ */ -+static inline bool mptcp_is_data_fin2(const struct sk_buff *skb, -+ const struct tcp_sock *tp) -+{ -+ return mptcp_is_data_fin(skb) || -+ (tp->mpcb->infinite_mapping_rcv && -+ (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN)); -+} -+ -+static inline u8 mptcp_get_64_bit(u64 data_seq, struct mptcp_cb *mpcb) -+{ -+ u64 data_seq_high = (u32)(data_seq >> 32); -+ -+ if (mpcb->rcv_high_order[0] == data_seq_high) -+ return 0; -+ else if (mpcb->rcv_high_order[1] == data_seq_high) -+ return MPTCPHDR_SEQ64_INDEX; -+ else -+ return MPTCPHDR_SEQ64_OFO; -+} -+ -+/* Sets the data_seq and returns pointer to the in-skb field of the data_seq. -+ * If the packet has a 64-bit dseq, the pointer points to the last 32 bits. -+ */ -+static inline __u32 *mptcp_skb_set_data_seq(const struct sk_buff *skb, -+ u32 *data_seq, -+ struct mptcp_cb *mpcb) -+{ -+ __u32 *ptr = (__u32 *)(skb_transport_header(skb) + TCP_SKB_CB(skb)->dss_off); -+ -+ if (TCP_SKB_CB(skb)->mptcp_flags & MPTCPHDR_SEQ64_SET) { -+ u64 data_seq64 = get_unaligned_be64(ptr); -+ -+ if (mpcb) -+ TCP_SKB_CB(skb)->mptcp_flags |= mptcp_get_64_bit(data_seq64, mpcb); -+ -+ *data_seq = (u32)data_seq64; -+ ptr++; -+ } else { -+ *data_seq = get_unaligned_be32(ptr); -+ } -+ -+ return ptr; -+} -+ -+static inline struct sock *mptcp_meta_sk(const struct sock *sk) -+{ -+ return tcp_sk(sk)->meta_sk; -+} -+ -+static inline struct tcp_sock *mptcp_meta_tp(const struct tcp_sock *tp) -+{ -+ return tcp_sk(tp->meta_sk); -+} -+ -+static inline int is_meta_tp(const struct tcp_sock *tp) -+{ -+ return tp->mpcb && mptcp_meta_tp(tp) == tp; -+} -+ -+static inline int is_meta_sk(const struct sock *sk) -+{ -+ return sk->sk_state != TCP_NEW_SYN_RECV && -+ sk->sk_type == SOCK_STREAM && sk->sk_protocol == IPPROTO_TCP && -+ mptcp(tcp_sk(sk)) && mptcp_meta_sk(sk) == sk; -+} -+ -+static inline int is_master_tp(const struct tcp_sock *tp) -+{ -+ return !mptcp(tp) || (!tp->mptcp->slave_sk && !is_meta_tp(tp)); -+} -+ -+static inline void mptcp_init_mp_opt(struct mptcp_options_received *mopt) -+{ -+ mopt->saw_mpc = 0; -+ mopt->dss_csum = 0; -+ mopt->drop_me = 0; -+ -+ mopt->is_mp_join = 0; -+ mopt->join_ack = 0; -+ -+ mopt->saw_low_prio = 0; -+ mopt->low_prio = 0; -+ -+ mopt->saw_add_addr = 0; -+ mopt->more_add_addr = 0; -+ -+ mopt->saw_rem_addr = 0; -+ mopt->more_rem_addr = 0; -+ -+ mopt->mp_fail = 0; -+ mopt->mp_fclose = 0; -+} -+ -+static inline void mptcp_reset_mopt(struct tcp_sock *tp) -+{ -+ struct mptcp_options_received *mopt = &tp->mptcp->rx_opt; -+ -+ mopt->saw_low_prio = 0; -+ mopt->saw_add_addr = 0; -+ mopt->more_add_addr = 0; -+ mopt->saw_rem_addr = 0; -+ mopt->more_rem_addr = 0; -+ mopt->join_ack = 0; -+ mopt->mp_fail = 0; -+ mopt->mp_fclose = 0; -+} -+ -+static inline __be32 mptcp_get_highorder_sndbits(const struct sk_buff *skb, -+ const struct mptcp_cb *mpcb) -+{ -+ return htonl(mpcb->snd_high_order[(TCP_SKB_CB(skb)->mptcp_flags & -+ MPTCPHDR_SEQ64_INDEX) ? 1 : 0]); -+} -+ -+static inline u64 mptcp_get_data_seq_64(const struct mptcp_cb *mpcb, int index, -+ u32 data_seq_32) -+{ -+ return ((u64)mpcb->rcv_high_order[index] << 32) | data_seq_32; -+} -+ -+static inline u64 mptcp_get_rcv_nxt_64(const struct tcp_sock *meta_tp) -+{ -+ struct mptcp_cb *mpcb = meta_tp->mpcb; -+ return mptcp_get_data_seq_64(mpcb, mpcb->rcv_hiseq_index, -+ meta_tp->rcv_nxt); -+} -+ -+static inline void mptcp_check_sndseq_wrap(struct tcp_sock *meta_tp, int inc) -+{ -+ if (unlikely(meta_tp->snd_nxt > meta_tp->snd_nxt + inc)) { -+ struct mptcp_cb *mpcb = meta_tp->mpcb; -+ mpcb->snd_hiseq_index = mpcb->snd_hiseq_index ? 0 : 1; -+ mpcb->snd_high_order[mpcb->snd_hiseq_index] += 2; -+ } -+} -+ -+static inline void mptcp_check_rcvseq_wrap(struct tcp_sock *meta_tp, -+ u32 old_rcv_nxt) -+{ -+ if (unlikely(old_rcv_nxt > meta_tp->rcv_nxt)) { -+ struct mptcp_cb *mpcb = meta_tp->mpcb; -+ mpcb->rcv_high_order[mpcb->rcv_hiseq_index] += 2; -+ mpcb->rcv_hiseq_index = mpcb->rcv_hiseq_index ? 0 : 1; -+ } -+} -+ -+static inline int mptcp_sk_can_send(const struct sock *sk) -+{ -+ return tcp_passive_fastopen(sk) || -+ ((1 << sk->sk_state) & (TCPF_ESTABLISHED | TCPF_CLOSE_WAIT) && -+ !tcp_sk(sk)->mptcp->pre_established); -+} -+ -+static inline int mptcp_sk_can_recv(const struct sock *sk) -+{ -+ return (1 << sk->sk_state) & (TCPF_ESTABLISHED | TCPF_FIN_WAIT1 | TCPF_FIN_WAIT2); -+} -+ -+static inline int mptcp_sk_can_send_ack(const struct sock *sk) -+{ -+ return !((1 << sk->sk_state) & (TCPF_SYN_SENT | TCPF_SYN_RECV | -+ TCPF_CLOSE | TCPF_LISTEN)) && -+ !tcp_sk(sk)->mptcp->pre_established; -+} -+ -+/* Only support GSO if all subflows supports it */ -+static inline bool mptcp_sk_can_gso(const struct sock *meta_sk) -+{ -+ struct sock *sk; -+ -+ if (tcp_sk(meta_sk)->mpcb->dss_csum) -+ return false; -+ -+ mptcp_for_each_sk(tcp_sk(meta_sk)->mpcb, sk) { -+ if (!mptcp_sk_can_send(sk)) -+ continue; -+ if (!sk_can_gso(sk)) -+ return false; -+ } -+ return true; -+} -+ -+static inline bool mptcp_can_sg(const struct sock *meta_sk) -+{ -+ struct sock *sk; -+ -+ if (tcp_sk(meta_sk)->mpcb->dss_csum) -+ return false; -+ -+ mptcp_for_each_sk(tcp_sk(meta_sk)->mpcb, sk) { -+ if (!mptcp_sk_can_send(sk)) -+ continue; -+ if (!(sk->sk_route_caps & NETIF_F_SG)) -+ return false; -+ } -+ return true; -+} -+ -+static inline void mptcp_set_rto(struct sock *sk) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct sock *sk_it; -+ struct inet_connection_sock *micsk = inet_csk(mptcp_meta_sk(sk)); -+ __u32 max_rto = 0; -+ -+ /* We are in recovery-phase on the MPTCP-level. Do not update the -+ * RTO, because this would kill exponential backoff. -+ */ -+ if (micsk->icsk_retransmits) -+ return; -+ -+ mptcp_for_each_sk(tp->mpcb, sk_it) { -+ if ((mptcp_sk_can_send(sk_it) || sk_it->sk_state == TCP_SYN_RECV) && -+ inet_csk(sk_it)->icsk_retransmits == 0 && -+ inet_csk(sk_it)->icsk_backoff == 0 && -+ inet_csk(sk_it)->icsk_rto > max_rto) -+ max_rto = inet_csk(sk_it)->icsk_rto; -+ } -+ if (max_rto) { -+ micsk->icsk_rto = max_rto << 1; -+ -+ /* A successfull rto-measurement - reset backoff counter */ -+ micsk->icsk_backoff = 0; -+ } -+} -+ -+static inline void mptcp_sub_close_passive(struct sock *sk) -+{ -+ struct sock *meta_sk = mptcp_meta_sk(sk); -+ struct tcp_sock *tp = tcp_sk(sk), *meta_tp = tcp_sk(meta_sk); -+ -+ /* Only close, if the app did a send-shutdown (passive close), and we -+ * received the data-ack of the data-fin. -+ */ -+ if (tp->mpcb->passive_close && meta_tp->snd_una == meta_tp->write_seq) -+ mptcp_sub_close(sk, 0); -+} -+ -+static inline bool mptcp_fallback_infinite(struct sock *sk, int flag) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct mptcp_cb *mpcb = tp->mpcb; -+ -+ /* If data has been acknowleged on the meta-level, fully_established -+ * will have been set before and thus we will not fall back to infinite -+ * mapping. -+ */ -+ if (likely(tp->mptcp->fully_established)) -+ return false; -+ -+ if (!(flag & MPTCP_FLAG_DATA_ACKED)) -+ return false; -+ -+ /* Don't fallback twice ;) */ -+ if (mpcb->infinite_mapping_snd) -+ return false; -+ -+ pr_err("%s %#x will fallback - pi %d, src %pI4:%u dst %pI4:%u rcv_nxt %u from %pS\n", -+ __func__, mpcb->mptcp_loc_token, tp->mptcp->path_index, -+ &inet_sk(sk)->inet_saddr, ntohs(inet_sk(sk)->inet_sport), -+ &inet_sk(sk)->inet_daddr, ntohs(inet_sk(sk)->inet_dport), -+ tp->rcv_nxt, __builtin_return_address(0)); -+ if (!is_master_tp(tp)) { -+ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_FBACKSUB); -+ return true; -+ } -+ -+ mpcb->infinite_mapping_snd = 1; -+ mpcb->infinite_mapping_rcv = 1; -+ mpcb->infinite_rcv_seq = mptcp_get_rcv_nxt_64(mptcp_meta_tp(tp)); -+ tp->mptcp->fully_established = 1; -+ -+ mptcp_sub_force_close_all(mpcb, sk); -+ -+ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_FBACKINIT); -+ -+ return false; -+} -+ -+/* Find the first index whose bit in the bit-field == 0 */ -+static inline u8 mptcp_set_new_pathindex(struct mptcp_cb *mpcb) -+{ -+ u8 base = mpcb->next_path_index; -+ int i; -+ -+ /* Start at 1, because 0 is reserved for the meta-sk */ -+ mptcp_for_each_bit_unset(mpcb->path_index_bits >> base, i) { -+ if (i + base < 1) -+ continue; -+ if (i + base >= sizeof(mpcb->path_index_bits) * 8) -+ break; -+ i += base; -+ mpcb->path_index_bits |= (1 << i); -+ mpcb->next_path_index = i + 1; -+ return i; -+ } -+ mptcp_for_each_bit_unset(mpcb->path_index_bits, i) { -+ if (i >= sizeof(mpcb->path_index_bits) * 8) -+ break; -+ if (i < 1) -+ continue; -+ mpcb->path_index_bits |= (1 << i); -+ mpcb->next_path_index = i + 1; -+ return i; -+ } -+ -+ return 0; -+} -+ -+static inline bool mptcp_v6_is_v4_mapped(const struct sock *sk) -+{ -+ return sk->sk_family == AF_INET6 && -+ ipv6_addr_type(&inet6_sk(sk)->saddr) == IPV6_ADDR_MAPPED; -+} -+ -+/* We are in or are becoming to be in infinite mapping mode */ -+static inline bool mptcp_in_infinite_mapping_weak(const struct mptcp_cb *mpcb) -+{ -+ return mpcb->infinite_mapping_rcv || -+ mpcb->infinite_mapping_snd || -+ mpcb->send_infinite_mapping; -+} -+ -+static inline bool mptcp_can_new_subflow(const struct sock *meta_sk) -+{ -+ /* Has been removed from the tk-table. Thus, no new subflows. -+ * -+ * Check for close-state is necessary, because we may have been closed -+ * without passing by mptcp_close(). -+ * -+ * When falling back, no new subflows are allowed either. -+ */ -+ return meta_sk->sk_state != TCP_CLOSE && -+ tcp_sk(meta_sk)->inside_tk_table && -+ !tcp_sk(meta_sk)->mpcb->infinite_mapping_rcv && -+ !tcp_sk(meta_sk)->mpcb->send_infinite_mapping; -+} -+ -+/* TCP and MPTCP mpc flag-depending functions */ -+u16 mptcp_select_window(struct sock *sk); -+void mptcp_init_buffer_space(struct sock *sk); -+void mptcp_tcp_set_rto(struct sock *sk); -+ -+/* TCP and MPTCP flag-depending functions */ -+bool mptcp_prune_ofo_queue(struct sock *sk); -+ -+#else /* CONFIG_MPTCP */ -+#define mptcp_debug(fmt, args...) \ -+ do { \ -+ } while (0) -+ -+/* Without MPTCP, we just do one iteration -+ * over the only socket available. This assumes that -+ * the sk/tp arg is the socket in that case. -+ */ -+#define mptcp_for_each_sk(mpcb, sk) -+#define mptcp_for_each_sk_safe(__mpcb, __sk, __temp) -+ -+#define MPTCP_INC_STATS(net, field) \ -+ do { \ -+ } while(0) -+ -+static inline bool mptcp_is_data_fin(const struct sk_buff *skb) -+{ -+ return false; -+} -+static inline bool mptcp_is_data_seq(const struct sk_buff *skb) -+{ -+ return false; -+} -+static inline struct sock *mptcp_meta_sk(const struct sock *sk) -+{ -+ return NULL; -+} -+static inline struct tcp_sock *mptcp_meta_tp(const struct tcp_sock *tp) -+{ -+ return NULL; -+} -+static inline int is_meta_sk(const struct sock *sk) -+{ -+ return 0; -+} -+static inline int is_master_tp(const struct tcp_sock *tp) -+{ -+ return 0; -+} -+static inline void mptcp_del_sock(const struct sock *sk) {} -+static inline void mptcp_update_metasocket(const struct sock *meta_sk) {} -+static inline void mptcp_reinject_data(struct sock *orig_sk, int clone_it) {} -+static inline void mptcp_update_sndbuf(const struct tcp_sock *tp) {} -+static inline void mptcp_clean_rtx_infinite(const struct sk_buff *skb, -+ const struct sock *sk) {} -+static inline void mptcp_sub_close(struct sock *sk, unsigned long delay) {} -+static inline void mptcp_set_rto(const struct sock *sk) {} -+static inline void mptcp_send_fin(const struct sock *meta_sk) {} -+static inline void mptcp_parse_options(const uint8_t *ptr, const int opsize, -+ struct mptcp_options_received *mopt, -+ const struct sk_buff *skb, -+ const struct tcp_sock *tp) {} -+static inline void mptcp_syn_options(const struct sock *sk, -+ struct tcp_out_options *opts, -+ unsigned *remaining) {} -+static inline void mptcp_synack_options(struct request_sock *req, -+ struct tcp_out_options *opts, -+ unsigned *remaining) {} -+ -+static inline void mptcp_established_options(struct sock *sk, -+ struct sk_buff *skb, -+ struct tcp_out_options *opts, -+ unsigned *size) {} -+static inline void mptcp_options_write(__be32 *ptr, struct tcp_sock *tp, -+ const struct tcp_out_options *opts, -+ struct sk_buff *skb) {} -+static inline void mptcp_close(struct sock *meta_sk, long timeout) {} -+static inline int mptcp_doit(struct sock *sk) -+{ -+ return 0; -+} -+static inline int mptcp_check_req_fastopen(struct sock *child, -+ struct request_sock *req) -+{ -+ return 1; -+} -+static inline int mptcp_check_req_master(const struct sock *sk, -+ const struct sock *child, -+ const struct request_sock *req, -+ const struct sk_buff *skb, -+ int drop, -+ u32 tsoff) -+{ -+ return 1; -+} -+static inline struct sock *mptcp_check_req_child(const struct sock *meta_sk, -+ const struct sock *child, -+ const struct request_sock *req, -+ struct sk_buff *skb, -+ const struct mptcp_options_received *mopt) -+{ -+ return NULL; -+} -+static inline unsigned int mptcp_current_mss(struct sock *meta_sk) -+{ -+ return 0; -+} -+static inline void mptcp_sub_close_passive(struct sock *sk) {} -+static inline bool mptcp_fallback_infinite(const struct sock *sk, int flag) -+{ -+ return false; -+} -+static inline void mptcp_init_mp_opt(const struct mptcp_options_received *mopt) {} -+static inline void mptcp_prepare_for_backlog(struct sock *sk, struct sk_buff *skb) {} -+static inline bool mptcp_check_rtt(const struct tcp_sock *tp, int time) -+{ -+ return false; -+} -+static inline int mptcp_check_snd_buf(const struct tcp_sock *tp) -+{ -+ return 0; -+} -+static inline void mptcp_push_pending_frames(struct sock *meta_sk) {} -+static inline void mptcp_send_reset(const struct sock *sk) {} -+static inline void mptcp_sub_force_close_all(struct mptcp_cb *mpcb, -+ struct sock *except) {} -+static inline bool mptcp_handle_options(struct sock *sk, -+ const struct tcphdr *th, -+ struct sk_buff *skb) -+{ -+ return false; -+} -+static inline void mptcp_reset_mopt(struct tcp_sock *tp) {} -+static inline void __init mptcp_init(void) {} -+static inline bool mptcp_sk_can_gso(const struct sock *sk) -+{ -+ return false; -+} -+static inline bool mptcp_can_sg(const struct sock *meta_sk) -+{ -+ return false; -+} -+static inline unsigned int mptcp_xmit_size_goal(const struct sock *meta_sk, -+ u32 mss_now, int large_allowed) -+{ -+ return 0; -+} -+static inline void mptcp_destroy_sock(struct sock *sk) {} -+static inline int mptcp_rcv_synsent_state_process(struct sock *sk, -+ struct sock **skptr, -+ struct sk_buff *skb, -+ const struct mptcp_options_received *mopt) -+{ -+ return 0; -+} -+static inline bool mptcp_can_sendpage(struct sock *sk) -+{ -+ return false; -+} -+static inline int mptcp_init_tw_sock(struct sock *sk, -+ struct tcp_timewait_sock *tw) -+{ -+ return 0; -+} -+static inline void mptcp_twsk_destructor(struct tcp_timewait_sock *tw) {} -+static inline void mptcp_disconnect(struct sock *meta_sk) {} -+static inline void mptcp_tsq_flags(struct sock *sk) {} -+static inline void mptcp_tsq_sub_deferred(struct sock *meta_sk) {} -+static inline void mptcp_hash_remove_bh(struct tcp_sock *meta_tp) {} -+static inline void mptcp_remove_shortcuts(const struct mptcp_cb *mpcb, -+ const struct sk_buff *skb) {} -+static inline void mptcp_init_tcp_sock(struct sock *sk) {} -+static inline void mptcp_disable_static_key(void) {} -+static inline void mptcp_cookies_reqsk_init(struct request_sock *req, -+ struct mptcp_options_received *mopt, -+ struct sk_buff *skb) {} -+static inline void mptcp_mpcb_put(struct mptcp_cb *mpcb) {} -+static inline void mptcp_fin(struct sock *meta_sk) {} -+static inline bool mptcp_in_infinite_mapping_weak(const struct mptcp_cb *mpcb) -+{ -+ return false; -+} -+static inline bool mptcp_can_new_subflow(const struct sock *meta_sk) -+{ -+ return false; -+} -+ -+#endif /* CONFIG_MPTCP */ -+ -+#endif /* _MPTCP_H */ -diff -aurN linux-4.14.174/include/net/mptcp_v4.h mptcp-mptcp_v0.94/include/net/mptcp_v4.h ---- linux-4.14.174/include/net/mptcp_v4.h 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_v0.94/include/net/mptcp_v4.h 2020-03-23 09:45:33.000000000 +0100 -@@ -0,0 +1,68 @@ -+/* -+ * MPTCP implementation -+ * -+ * Initial Design & Implementation: -+ * Sébastien Barré -+ * -+ * Current Maintainer & Author: -+ * Christoph Paasch -+ * -+ * Additional authors: -+ * Jaakko Korkeaniemi -+ * Gregory Detal -+ * Fabien Duchêne -+ * Andreas Seelinger -+ * Lavkesh Lahngir -+ * Andreas Ripke -+ * Vlad Dogaru -+ * Octavian Purdila -+ * John Ronan -+ * Catalin Nicutar -+ * Brandon Heller -+ * -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version -+ * 2 of the License, or (at your option) any later version. -+ */ -+ -+#ifndef MPTCP_V4_H_ -+#define MPTCP_V4_H_ -+ -+ -+#include -+#include -+#include -+#include -+#include -+ -+extern struct request_sock_ops mptcp_request_sock_ops; -+extern const struct inet_connection_sock_af_ops mptcp_v4_specific; -+extern struct tcp_request_sock_ops mptcp_request_sock_ipv4_ops; -+extern struct tcp_request_sock_ops mptcp_join_request_sock_ipv4_ops; -+ -+#ifdef CONFIG_MPTCP -+ -+int mptcp_v4_do_rcv(struct sock *meta_sk, struct sk_buff *skb); -+struct sock *mptcp_v4_search_req(const __be16 rport, const __be32 raddr, -+ const __be32 laddr, const struct net *net); -+int mptcp_init4_subsockets(struct sock *meta_sk, const struct mptcp_loc4 *loc, -+ struct mptcp_rem4 *rem); -+int mptcp_pm_v4_init(void); -+void mptcp_pm_v4_undo(void); -+u32 mptcp_v4_get_nonce(__be32 saddr, __be32 daddr, __be16 sport, __be16 dport); -+u64 mptcp_v4_get_key(__be32 saddr, __be32 daddr, __be16 sport, __be16 dport, -+ u32 seed); -+ -+#else -+ -+static inline int mptcp_v4_do_rcv(const struct sock *meta_sk, -+ const struct sk_buff *skb) -+{ -+ return 0; -+} -+ -+#endif /* CONFIG_MPTCP */ -+ -+#endif /* MPTCP_V4_H_ */ -diff -aurN linux-4.14.174/include/net/mptcp_v6.h mptcp-mptcp_v0.94/include/net/mptcp_v6.h ---- linux-4.14.174/include/net/mptcp_v6.h 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_v0.94/include/net/mptcp_v6.h 2020-03-23 09:45:33.000000000 +0100 -@@ -0,0 +1,69 @@ -+/* -+ * MPTCP implementation -+ * -+ * Initial Design & Implementation: -+ * Sébastien Barré -+ * -+ * Current Maintainer & Author: -+ * Jaakko Korkeaniemi -+ * -+ * Additional authors: -+ * Jaakko Korkeaniemi -+ * Gregory Detal -+ * Fabien Duchêne -+ * Andreas Seelinger -+ * Lavkesh Lahngir -+ * Andreas Ripke -+ * Vlad Dogaru -+ * Octavian Purdila -+ * John Ronan -+ * Catalin Nicutar -+ * Brandon Heller -+ * -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version -+ * 2 of the License, or (at your option) any later version. -+ */ -+ -+#ifndef _MPTCP_V6_H -+#define _MPTCP_V6_H -+ -+#include -+#include -+ -+#include -+ -+ -+#ifdef CONFIG_MPTCP -+extern const struct inet_connection_sock_af_ops mptcp_v6_mapped; -+extern const struct inet_connection_sock_af_ops mptcp_v6_specific; -+extern struct request_sock_ops mptcp6_request_sock_ops; -+extern struct tcp_request_sock_ops mptcp_request_sock_ipv6_ops; -+extern struct tcp_request_sock_ops mptcp_join_request_sock_ipv6_ops; -+ -+int mptcp_v6_do_rcv(struct sock *meta_sk, struct sk_buff *skb); -+struct sock *mptcp_v6_search_req(const __be16 rport, const struct in6_addr *raddr, -+ const struct in6_addr *laddr, const struct net *net); -+int mptcp_init6_subsockets(struct sock *meta_sk, const struct mptcp_loc6 *loc, -+ struct mptcp_rem6 *rem); -+int mptcp_pm_v6_init(void); -+void mptcp_pm_v6_undo(void); -+__u32 mptcp_v6_get_nonce(const __be32 *saddr, const __be32 *daddr, -+ __be16 sport, __be16 dport); -+u64 mptcp_v6_get_key(const __be32 *saddr, const __be32 *daddr, -+ __be16 sport, __be16 dport, u32 seed); -+ -+#else /* CONFIG_MPTCP */ -+ -+#define mptcp_v6_mapped ipv6_mapped -+ -+static inline int mptcp_v6_do_rcv(struct sock *meta_sk, struct sk_buff *skb) -+{ -+ return 0; -+} -+ -+#endif /* CONFIG_MPTCP */ -+ -+#endif /* _MPTCP_V6_H */ -diff -aurN linux-4.14.174/include/net/net_namespace.h mptcp-mptcp_v0.94/include/net/net_namespace.h ---- linux-4.14.174/include/net/net_namespace.h 2020-03-20 10:54:27.000000000 +0100 -+++ mptcp-mptcp_v0.94/include/net/net_namespace.h 2020-03-23 09:45:33.000000000 +0100 -@@ -18,6 +18,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -101,6 +102,9 @@ - #if IS_ENABLED(CONFIG_IPV6) - struct netns_ipv6 ipv6; - #endif -+#if IS_ENABLED(CONFIG_MPTCP) -+ struct netns_mptcp mptcp; -+#endif - #if IS_ENABLED(CONFIG_IEEE802154_6LOWPAN) - struct netns_ieee802154_lowpan ieee802154_lowpan; - #endif -diff -aurN linux-4.14.174/include/net/netns/mptcp.h mptcp-mptcp_v0.94/include/net/netns/mptcp.h ---- linux-4.14.174/include/net/netns/mptcp.h 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_v0.94/include/net/netns/mptcp.h 2020-03-23 09:45:33.000000000 +0100 -@@ -0,0 +1,52 @@ -+/* -+ * MPTCP implementation - MPTCP namespace -+ * -+ * Initial Design & Implementation: -+ * Sébastien Barré -+ * -+ * Current Maintainer: -+ * Christoph Paasch -+ * -+ * Additional authors: -+ * Jaakko Korkeaniemi -+ * Gregory Detal -+ * Fabien Duchêne -+ * Andreas Seelinger -+ * Lavkesh Lahngir -+ * Andreas Ripke -+ * Vlad Dogaru -+ * Octavian Purdila -+ * John Ronan -+ * Catalin Nicutar -+ * Brandon Heller -+ * -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version -+ * 2 of the License, or (at your option) any later version. -+ */ -+ -+#ifndef __NETNS_MPTCP_H__ -+#define __NETNS_MPTCP_H__ -+ -+#include -+ -+enum { -+ MPTCP_PM_FULLMESH = 0, -+ MPTCP_PM_MAX -+}; -+ -+struct mptcp_mib; -+ -+struct netns_mptcp { -+ DEFINE_SNMP_STAT(struct mptcp_mib, mptcp_statistics); -+ -+#ifdef CONFIG_PROC_FS -+ struct proc_dir_entry *proc_net_mptcp; -+#endif -+ -+ void *path_managers[MPTCP_PM_MAX]; -+}; -+ -+#endif /* __NETNS_MPTCP_H__ */ -diff -aurN linux-4.14.174/include/net/snmp.h mptcp-mptcp_v0.94/include/net/snmp.h ---- linux-4.14.174/include/net/snmp.h 2020-03-20 10:54:27.000000000 +0100 -+++ mptcp-mptcp_v0.94/include/net/snmp.h 2020-03-23 09:45:33.000000000 +0100 -@@ -91,7 +91,6 @@ - atomic_long_t mibs[ICMP6MSG_MIB_MAX]; - }; - -- - /* TCP */ - #define TCP_MIB_MAX __TCP_MIB_MAX - struct tcp_mib { -diff -aurN linux-4.14.174/include/net/sock.h mptcp-mptcp_v0.94/include/net/sock.h ---- linux-4.14.174/include/net/sock.h 2020-03-20 10:54:27.000000000 +0100 -+++ mptcp-mptcp_v0.94/include/net/sock.h 2020-03-23 09:45:33.000000000 +0100 -@@ -786,6 +786,7 @@ - SOCK_FILTER_LOCKED, /* Filter cannot be changed anymore */ - SOCK_SELECT_ERR_QUEUE, /* Wake select on error queue */ - SOCK_RCU_FREE, /* wait rcu grace period in sk_destruct() */ -+ SOCK_MPTCP, /* MPTCP set on this socket */ - }; - - #define SK_FLAGS_TIMESTAMP ((1UL << SOCK_TIMESTAMP) | (1UL << SOCK_TIMESTAMPING_RX_SOFTWARE)) -@@ -1086,6 +1087,7 @@ - void (*unhash)(struct sock *sk); - void (*rehash)(struct sock *sk); - int (*get_port)(struct sock *sk, unsigned short snum); -+ void (*clear_sk)(struct sock *sk, int size); - - /* Keeping track of sockets in use */ - #ifdef CONFIG_PROC_FS -@@ -1510,9 +1512,6 @@ - - static inline void sock_owned_by_me(const struct sock *sk) - { --#ifdef CONFIG_LOCKDEP -- WARN_ON_ONCE(!lockdep_sock_is_held(sk) && debug_locks); --#endif - } - - static inline bool sock_owned_by_user(const struct sock *sk) -diff -aurN linux-4.14.174/include/net/tcp.h mptcp-mptcp_v0.94/include/net/tcp.h ---- linux-4.14.174/include/net/tcp.h 2020-03-20 10:54:27.000000000 +0100 -+++ mptcp-mptcp_v0.94/include/net/tcp.h 2020-03-23 09:45:33.000000000 +0100 -@@ -187,6 +187,7 @@ - #define TCPOPT_SACK 5 /* SACK Block */ - #define TCPOPT_TIMESTAMP 8 /* Better RTT estimations/PAWS */ - #define TCPOPT_MD5SIG 19 /* MD5 Signature (RFC2385) */ -+#define TCPOPT_MPTCP 30 - #define TCPOPT_FASTOPEN 34 /* Fast open (RFC7413) */ - #define TCPOPT_EXP 254 /* Experimental */ - /* Magic number to be after the option value for sharing TCP -@@ -240,6 +241,30 @@ - */ - #define TFO_SERVER_WO_SOCKOPT1 0x400 - -+/* Flags from tcp_input.c for tcp_ack */ -+#define FLAG_DATA 0x01 /* Incoming frame contained data. */ -+#define FLAG_WIN_UPDATE 0x02 /* Incoming ACK was a window update. */ -+#define FLAG_DATA_ACKED 0x04 /* This ACK acknowledged new data. */ -+#define FLAG_RETRANS_DATA_ACKED 0x08 /* "" "" some of which was retransmitted. */ -+#define FLAG_SYN_ACKED 0x10 /* This ACK acknowledged SYN. */ -+#define FLAG_DATA_SACKED 0x20 /* New SACK. */ -+#define FLAG_ECE 0x40 /* ECE in this ACK */ -+#define FLAG_LOST_RETRANS 0x80 /* This ACK marks some retransmission lost */ -+#define FLAG_SLOWPATH 0x100 /* Do not skip RFC checks for window update.*/ -+#define FLAG_ORIG_SACK_ACKED 0x200 /* Never retransmitted data are (s)acked */ -+#define FLAG_SND_UNA_ADVANCED 0x400 /* Snd_una was changed (!= FLAG_DATA_ACKED) */ -+#define FLAG_DSACKING_ACK 0x800 /* SACK blocks contained D-SACK info */ -+#define FLAG_SET_XMIT_TIMER 0x1000 /* Set TLP or RTO timer */ -+#define FLAG_SACK_RENEGING 0x2000 /* snd_una advanced to a sacked seq */ -+#define FLAG_UPDATE_TS_RECENT 0x4000 /* tcp_replace_ts_recent() */ -+#define FLAG_NO_CHALLENGE_ACK 0x8000 /* do not call tcp_send_challenge_ack() */ -+ -+#define MPTCP_FLAG_DATA_ACKED 0x10000 -+ -+#define FLAG_ACKED (FLAG_DATA_ACKED|FLAG_SYN_ACKED) -+#define FLAG_NOT_DUP (FLAG_DATA|FLAG_WIN_UPDATE|FLAG_ACKED) -+#define FLAG_CA_ALERT (FLAG_DATA_SACKED|FLAG_ECE|FLAG_DSACKING_ACK) -+#define FLAG_FORWARD_PROGRESS (FLAG_ACKED|FLAG_DATA_SACKED) - - /* sysctl variables for tcp */ - extern int sysctl_tcp_fastopen; -@@ -341,6 +366,96 @@ - #define TCP_DEC_STATS(net, field) SNMP_DEC_STATS((net)->mib.tcp_statistics, field) - #define TCP_ADD_STATS(net, field, val) SNMP_ADD_STATS((net)->mib.tcp_statistics, field, val) - -+/**** START - Exports needed for MPTCP ****/ -+extern const struct tcp_request_sock_ops tcp_request_sock_ipv4_ops; -+extern const struct tcp_request_sock_ops tcp_request_sock_ipv6_ops; -+ -+struct mptcp_options_received; -+ -+void tcp_cleanup_rbuf(struct sock *sk, int copied); -+void tcp_cwnd_validate(struct sock *sk, bool is_cwnd_limited); -+int tcp_close_state(struct sock *sk); -+void tcp_minshall_update(struct tcp_sock *tp, unsigned int mss_now, -+ const struct sk_buff *skb); -+int tcp_xmit_probe_skb(struct sock *sk, int urgent, int mib); -+void tcp_event_new_data_sent(struct sock *sk, const struct sk_buff *skb); -+int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it, -+ gfp_t gfp_mask); -+unsigned int tcp_mss_split_point(const struct sock *sk, -+ const struct sk_buff *skb, -+ unsigned int mss_now, -+ unsigned int max_segs, -+ int nonagle); -+bool tcp_nagle_test(const struct tcp_sock *tp, const struct sk_buff *skb, -+ unsigned int cur_mss, int nonagle); -+bool tcp_snd_wnd_test(const struct tcp_sock *tp, const struct sk_buff *skb, -+ unsigned int cur_mss); -+unsigned int tcp_cwnd_test(const struct tcp_sock *tp, const struct sk_buff *skb); -+int tcp_init_tso_segs(struct sk_buff *skb, unsigned int mss_now); -+int __pskb_trim_head(struct sk_buff *skb, int len); -+void tcp_queue_skb(struct sock *sk, struct sk_buff *skb); -+void tcp_init_nondata_skb(struct sk_buff *skb, u32 seq, u8 flags); -+void tcp_reset(struct sock *sk); -+bool tcp_may_update_window(const struct tcp_sock *tp, const u32 ack, -+ const u32 ack_seq, const u32 nwin); -+bool tcp_urg_mode(const struct tcp_sock *tp); -+void tcp_ack_probe(struct sock *sk); -+void tcp_rearm_rto(struct sock *sk); -+int tcp_write_timeout(struct sock *sk); -+bool retransmits_timed_out(struct sock *sk, -+ unsigned int boundary, -+ unsigned int timeout); -+void tcp_write_err(struct sock *sk); -+void tcp_adjust_pcount(struct sock *sk, const struct sk_buff *skb, int decr); -+void tcp_set_skb_tso_segs(struct sk_buff *skb, unsigned int mss_now); -+ -+void tcp_v4_reqsk_send_ack(const struct sock *sk, struct sk_buff *skb, -+ struct request_sock *req); -+void tcp_v4_send_reset(const struct sock *sk, struct sk_buff *skb); -+struct sock *tcp_v4_cookie_check(struct sock *sk, struct sk_buff *skb); -+void tcp_v4_reqsk_destructor(struct request_sock *req); -+ -+void tcp_v6_reqsk_send_ack(const struct sock *sk, struct sk_buff *skb, -+ struct request_sock *req); -+void tcp_v6_send_reset(const struct sock *sk, struct sk_buff *skb); -+struct sock *tcp_v6_cookie_check(struct sock *sk, struct sk_buff *skb); -+int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb); -+int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len); -+void tcp_v6_destroy_sock(struct sock *sk); -+void inet6_sk_rx_dst_set(struct sock *sk, const struct sk_buff *skb); -+void tcp_v6_hash(struct sock *sk); -+struct sock *tcp_v6_hnd_req(struct sock *sk,struct sk_buff *skb); -+struct sock *tcp_v6_syn_recv_sock(const struct sock *sk, struct sk_buff *skb, -+ struct request_sock *req, -+ struct dst_entry *dst, -+ struct request_sock *req_unhash, -+ bool *own_req); -+void tcp_v6_reqsk_destructor(struct request_sock *req); -+ -+unsigned int tcp_xmit_size_goal(struct sock *sk, u32 mss_now, -+ int large_allowed); -+u32 tcp_tso_acked(struct sock *sk, struct sk_buff *skb); -+ -+void skb_clone_fraglist(struct sk_buff *skb); -+void copy_skb_header(struct sk_buff *new, const struct sk_buff *old); -+ -+void inet_twsk_free(struct inet_timewait_sock *tw); -+int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb); -+/* These states need RST on ABORT according to RFC793 */ -+static inline bool tcp_need_reset(int state) -+{ -+ return (1 << state) & -+ (TCPF_ESTABLISHED | TCPF_CLOSE_WAIT | TCPF_FIN_WAIT1 | -+ TCPF_FIN_WAIT2 | TCPF_SYN_RECV); -+} -+ -+int __must_check tcp_queue_rcv(struct sock *sk, struct sk_buff *skb, int hdrlen, -+ bool *fragstolen); -+void tcp_ofo_queue(struct sock *sk); -+void tcp_data_queue_ofo(struct sock *sk, struct sk_buff *skb); -+int linear_payload_sz(bool first_skb); -+/**** END - Exports needed for MPTCP ****/ -+ - void tcp_tasklet_init(void); - - void tcp_v4_err(struct sk_buff *skb, u32); -@@ -436,7 +551,9 @@ - int flags, int *addr_len); - void tcp_parse_options(const struct net *net, const struct sk_buff *skb, - struct tcp_options_received *opt_rx, -- int estab, struct tcp_fastopen_cookie *foc); -+ struct mptcp_options_received *mopt_rx, -+ int estab, struct tcp_fastopen_cookie *foc, -+ struct tcp_sock *tp); - const u8 *tcp_parse_md5sig_option(const struct tcphdr *th); - - /* -@@ -445,6 +562,7 @@ - - void tcp_v4_send_check(struct sock *sk, struct sk_buff *skb); - void tcp_v4_mtu_reduced(struct sock *sk); -+void tcp_v6_mtu_reduced(struct sock *sk); - void tcp_req_err(struct sock *sk, u32 seq, bool abort); - int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb); - struct sock *tcp_create_openreq_child(const struct sock *sk, -@@ -533,7 +651,8 @@ - - u32 __cookie_v4_init_sequence(const struct iphdr *iph, const struct tcphdr *th, - u16 *mssp); --__u32 cookie_v4_init_sequence(const struct sk_buff *skb, __u16 *mss); -+__u32 cookie_v4_init_sequence(struct request_sock *req, const struct sock *sk, -+ const struct sk_buff *skb, __u16 *mss); - u64 cookie_init_timestamp(struct request_sock *req); - bool cookie_timestamp_decode(const struct net *net, - struct tcp_options_received *opt); -@@ -547,7 +666,8 @@ - - u32 __cookie_v6_init_sequence(const struct ipv6hdr *iph, - const struct tcphdr *th, u16 *mssp); --__u32 cookie_v6_init_sequence(const struct sk_buff *skb, __u16 *mss); -+__u32 cookie_v6_init_sequence(struct request_sock *req, const struct sock *sk, -+ const struct sk_buff *skb, __u16 *mss); - #endif - /* tcp_output.c */ - -@@ -579,10 +699,17 @@ - void tcp_skb_collapse_tstamp(struct sk_buff *skb, - const struct sk_buff *next_skb); - -+u16 tcp_select_window(struct sock *sk); -+int select_size(const struct sock *sk, bool sg, bool first_skb); -+bool tcp_write_xmit(struct sock *sk, unsigned int mss_now, int nonagle, -+ int push_one, gfp_t gfp); -+ - /* tcp_input.c */ - void tcp_rearm_rto(struct sock *sk); - void tcp_synack_rtt_meas(struct sock *sk, struct request_sock *req); - void tcp_reset(struct sock *sk); -+void tcp_set_rto(struct sock *sk); -+bool tcp_should_expand_sndbuf(const struct sock *sk); - void tcp_skb_mark_lost_uncond_verify(struct tcp_sock *tp, struct sk_buff *skb); - void tcp_fin(struct sock *sk); - -@@ -621,7 +748,7 @@ - } - - /* tcp.c */ --void tcp_get_info(struct sock *, struct tcp_info *); -+void tcp_get_info(struct sock *, struct tcp_info *, bool no_lock); - - /* Read 'sendfile()'-style from a TCP socket */ - int tcp_read_sock(struct sock *sk, read_descriptor_t *desc, -@@ -815,6 +942,12 @@ - */ - ktime_t swtstamp; - }; -+ -+#ifdef CONFIG_MPTCP -+ __u8 mptcp_flags; /* flags for the MPTCP layer */ -+ __u8 dss_off; /* Number of 4-byte words until -+ * seq-number */ -+#endif - __u8 tcp_flags; /* TCP header flags. (tcp[13]) */ - - __u8 sacked; /* State flags for SACK/FACK. */ -@@ -833,6 +966,14 @@ - has_rxtstamp:1, /* SKB has a RX timestamp */ - unused:5; - __u32 ack_seq; /* Sequence number ACK'd */ -+ -+#ifdef CONFIG_MPTCP -+ union { /* For MPTCP outgoing frames */ -+ __u32 path_mask; /* paths that tried to send this skb */ -+ __u32 dss[6]; /* DSS options */ -+ }; -+#endif -+ - union { - struct { - /* There is space for up to 24 bytes */ -@@ -1053,6 +1194,8 @@ - int tcp_set_allowed_congestion_control(char *allowed); - int tcp_set_congestion_control(struct sock *sk, const char *name, bool load, - bool reinit, bool cap_net_admin); -+int __tcp_set_congestion_control(struct sock *sk, const char *name, bool load, -+ bool reinit, bool cap_net_admin); - u32 tcp_slow_start(struct tcp_sock *tp, u32 acked); - void tcp_cong_avoid_ai(struct tcp_sock *tp, u32 w, u32 acked); - -@@ -1335,7 +1478,8 @@ - /* Determine a window scaling and initial window to offer. */ - void tcp_select_initial_window(int __space, __u32 mss, __u32 *rcv_wnd, - __u32 *window_clamp, int wscale_ok, -- __u8 *rcv_wscale, __u32 init_rcv_wnd); -+ __u8 *rcv_wscale, __u32 init_rcv_wnd, -+ const struct sock *sk); - - static inline int tcp_win_from_space(int space) - { -@@ -1346,6 +1490,19 @@ - space - (space>>tcp_adv_win_scale); - } - -+#ifdef CONFIG_MPTCP -+extern struct static_key mptcp_static_key; -+static inline bool mptcp(const struct tcp_sock *tp) -+{ -+ return static_key_false(&mptcp_static_key) && tp->mpc; -+} -+#else -+static inline bool mptcp(const struct tcp_sock *tp) -+{ -+ return 0; -+} -+#endif -+ - /* Note: caller must be prepared to deal with negative returns */ - static inline int tcp_space(const struct sock *sk) - { -@@ -1622,19 +1779,7 @@ - } - - /* write queue abstraction */ --static inline void tcp_write_queue_purge(struct sock *sk) --{ -- struct sk_buff *skb; -- -- tcp_chrono_stop(sk, TCP_CHRONO_BUSY); -- while ((skb = __skb_dequeue(&sk->sk_write_queue)) != NULL) -- sk_wmem_free_skb(sk, skb); -- sk_mem_reclaim(sk); -- tcp_clear_all_retrans_hints(tcp_sk(sk)); -- tcp_init_send_head(sk); -- tcp_sk(sk)->packets_out = 0; -- inet_csk(sk)->icsk_backoff = 0; --} -+void tcp_write_queue_purge(struct sock *sk); - - static inline struct sk_buff *tcp_write_queue_head(const struct sock *sk) - { -@@ -1918,6 +2063,32 @@ - #endif - }; - -+/* TCP/MPTCP-specific functions */ -+struct tcp_sock_ops { -+ u32 (*__select_window)(struct sock *sk); -+ u16 (*select_window)(struct sock *sk); -+ void (*select_initial_window)(int __space, __u32 mss, __u32 *rcv_wnd, -+ __u32 *window_clamp, int wscale_ok, -+ __u8 *rcv_wscale, __u32 init_rcv_wnd, -+ const struct sock *sk); -+ int (*select_size)(const struct sock *sk, bool sg, bool first_skb); -+ void (*init_buffer_space)(struct sock *sk); -+ void (*set_rto)(struct sock *sk); -+ bool (*should_expand_sndbuf)(const struct sock *sk); -+ void (*send_fin)(struct sock *sk); -+ bool (*write_xmit)(struct sock *sk, unsigned int mss_now, int nonagle, -+ int push_one, gfp_t gfp); -+ void (*send_active_reset)(struct sock *sk, gfp_t priority); -+ int (*write_wakeup)(struct sock *sk, int mib); -+ void (*retransmit_timer)(struct sock *sk); -+ void (*time_wait)(struct sock *sk, int state, int timeo); -+ void (*cleanup_rbuf)(struct sock *sk, int copied); -+ void (*cwnd_validate)(struct sock *sk, bool is_cwnd_limited); -+ int (*set_cong_ctrl)(struct sock *sk, const char *name, bool load, -+ bool reinit, bool cap_net_admin); -+}; -+extern const struct tcp_sock_ops tcp_specific; -+ - struct tcp_request_sock_ops { - u16 mss_clamp; - #ifdef CONFIG_TCP_MD5SIG -@@ -1928,12 +2099,13 @@ - const struct sock *sk, - const struct sk_buff *skb); - #endif -- void (*init_req)(struct request_sock *req, -- const struct sock *sk_listener, -- struct sk_buff *skb); -+ int (*init_req)(struct request_sock *req, -+ const struct sock *sk_listener, -+ struct sk_buff *skb, -+ bool want_cookie); - #ifdef CONFIG_SYN_COOKIES -- __u32 (*cookie_init_seq)(const struct sk_buff *skb, -- __u16 *mss); -+ __u32 (*cookie_init_seq)(struct request_sock *req, const struct sock *sk, -+ const struct sk_buff *skb, __u16 *mss); - #endif - struct dst_entry *(*route_req)(const struct sock *sk, struct flowi *fl, - const struct request_sock *req); -@@ -1947,15 +2119,17 @@ - - #ifdef CONFIG_SYN_COOKIES - static inline __u32 cookie_init_sequence(const struct tcp_request_sock_ops *ops, -+ struct request_sock *req, - const struct sock *sk, struct sk_buff *skb, - __u16 *mss) - { - tcp_synq_overflow(sk); - __NET_INC_STATS(sock_net(sk), LINUX_MIB_SYNCOOKIESSENT); -- return ops->cookie_init_seq(skb, mss); -+ return ops->cookie_init_seq(req, sk, skb, mss); - } - #else - static inline __u32 cookie_init_sequence(const struct tcp_request_sock_ops *ops, -+ struct request_sock *req, - const struct sock *sk, struct sk_buff *skb, - __u16 *mss) - { -diff -aurN linux-4.14.174/include/net/tcp_states.h mptcp-mptcp_v0.94/include/net/tcp_states.h ---- linux-4.14.174/include/net/tcp_states.h 2020-03-20 10:54:27.000000000 +0100 -+++ mptcp-mptcp_v0.94/include/net/tcp_states.h 2020-03-23 09:45:33.000000000 +0100 -@@ -26,6 +26,7 @@ - TCP_LISTEN, - TCP_CLOSING, /* Now a valid state */ - TCP_NEW_SYN_RECV, -+ TCP_RST_WAIT, - - TCP_MAX_STATES /* Leave at the end! */ - }; -@@ -47,6 +48,7 @@ - TCPF_LISTEN = (1 << 10), - TCPF_CLOSING = (1 << 11), - TCPF_NEW_SYN_RECV = (1 << 12), -+ TCPF_RST_WAIT = (1 << 13), - }; - - #endif /* _LINUX_TCP_STATES_H */ -diff -aurN linux-4.14.174/include/net/transp_v6.h mptcp-mptcp_v0.94/include/net/transp_v6.h ---- linux-4.14.174/include/net/transp_v6.h 2020-03-20 10:54:27.000000000 +0100 -+++ mptcp-mptcp_v0.94/include/net/transp_v6.h 2020-03-23 09:45:33.000000000 +0100 -@@ -59,6 +59,8 @@ - - /* address family specific functions */ - extern const struct inet_connection_sock_af_ops ipv4_specific; -+extern const struct inet_connection_sock_af_ops ipv6_mapped; -+extern const struct inet_connection_sock_af_ops ipv6_specific; - - void inet6_destroy_sock(struct sock *sk); - -diff -aurN linux-4.14.174/include/uapi/linux/if.h mptcp-mptcp_v0.94/include/uapi/linux/if.h ---- linux-4.14.174/include/uapi/linux/if.h 2020-03-20 10:54:27.000000000 +0100 -+++ mptcp-mptcp_v0.94/include/uapi/linux/if.h 2020-03-23 09:45:33.000000000 +0100 -@@ -132,6 +132,9 @@ - #define IFF_ECHO IFF_ECHO - #endif /* __UAPI_DEF_IF_NET_DEVICE_FLAGS_LOWER_UP_DORMANT_ECHO */ - -+#define IFF_NOMULTIPATH 0x80000 /* Disable for MPTCP */ -+#define IFF_MPBACKUP 0x100000 /* Use as backup path for MPTCP */ -+ - #define IFF_VOLATILE (IFF_LOOPBACK|IFF_POINTOPOINT|IFF_BROADCAST|IFF_ECHO|\ - IFF_MASTER|IFF_SLAVE|IFF_RUNNING|IFF_LOWER_UP|IFF_DORMANT) - -diff -aurN linux-4.14.174/include/uapi/linux/tcp.h mptcp-mptcp_v0.94/include/uapi/linux/tcp.h ---- linux-4.14.174/include/uapi/linux/tcp.h 2020-03-20 10:54:27.000000000 +0100 -+++ mptcp-mptcp_v0.94/include/uapi/linux/tcp.h 2020-03-23 09:45:33.000000000 +0100 -@@ -18,9 +18,15 @@ - #ifndef _UAPI_LINUX_TCP_H - #define _UAPI_LINUX_TCP_H - --#include -+#ifndef __KERNEL__ -+#include -+#endif -+ - #include -+#include -+#include - #include -+#include - - struct tcphdr { - __be16 source; -@@ -120,6 +126,12 @@ - #define TCP_FASTOPEN_CONNECT 30 /* Attempt FastOpen with connect */ - #define TCP_ULP 31 /* Attach a ULP to a TCP connection */ - #define TCP_MD5SIG_EXT 32 /* TCP MD5 Signature with extensions */ -+#define MPTCP_ENABLED 42 -+#define MPTCP_SCHEDULER 43 -+#define MPTCP_PATH_MANAGER 44 -+#define MPTCP_INFO 45 -+ -+#define MPTCP_INFO_FLAG_SAVE_MASTER 0x01 - - struct tcp_repair_opt { - __u32 opt_code; -@@ -242,6 +254,53 @@ - - }; - -+struct mptcp_meta_info { -+ __u8 mptcpi_state; -+ __u8 mptcpi_retransmits; -+ __u8 mptcpi_probes; -+ __u8 mptcpi_backoff; -+ -+ __u32 mptcpi_rto; -+ __u32 mptcpi_unacked; -+ -+ /* Times. */ -+ __u32 mptcpi_last_data_sent; -+ __u32 mptcpi_last_data_recv; -+ __u32 mptcpi_last_ack_recv; -+ -+ __u32 mptcpi_total_retrans; -+ -+ __u64 mptcpi_bytes_acked; /* RFC4898 tcpEStatsAppHCThruOctetsAcked */ -+ __u64 mptcpi_bytes_received; /* RFC4898 tcpEStatsAppHCThruOctetsReceived */ -+}; -+ -+struct mptcp_sub_info { -+ union { -+ struct sockaddr src; -+ struct sockaddr_in src_v4; -+ struct sockaddr_in6 src_v6; -+ }; -+ -+ union { -+ struct sockaddr dst; -+ struct sockaddr_in dst_v4; -+ struct sockaddr_in6 dst_v6; -+ }; -+}; -+ -+struct mptcp_info { -+ __u32 tcp_info_len; /* Length of each struct tcp_info in subflows pointer */ -+ __u32 sub_len; /* Total length of memory pointed to by subflows pointer */ -+ __u32 meta_len; /* Length of memory pointed to by meta_info */ -+ __u32 sub_info_len; /* Length of each struct mptcp_sub_info in subflow_info pointer */ -+ __u32 total_sub_info_len; /* Total length of memory pointed to by subflow_info */ -+ -+ struct mptcp_meta_info *meta_info; -+ struct tcp_info *initial; -+ struct tcp_info *subflows; /* Pointer to array of tcp_info structs */ -+ struct mptcp_sub_info *subflow_info; -+}; -+ - /* for TCP_MD5SIG socket option */ - #define TCP_MD5SIG_MAXKEYLEN 80 - -diff -aurN linux-4.14.174/kernel/rcu/Kconfig.debug mptcp-mptcp_v0.94/kernel/rcu/Kconfig.debug ---- linux-4.14.174/kernel/rcu/Kconfig.debug 2020-03-20 10:54:27.000000000 +0100 -+++ mptcp-mptcp_v0.94/kernel/rcu/Kconfig.debug 2020-03-23 09:45:33.000000000 +0100 -@@ -4,9 +4,6 @@ - - menu "RCU Debugging" - --config PROVE_RCU -- def_bool PROVE_LOCKING -- - config TORTURE_TEST - tristate - default n -diff -aurN linux-4.14.174/net/core/dev.c mptcp-mptcp_v0.94/net/core/dev.c ---- linux-4.14.174/net/core/dev.c 2020-03-20 10:54:27.000000000 +0100 -+++ mptcp-mptcp_v0.94/net/core/dev.c 2020-03-23 09:45:33.000000000 +0100 -@@ -6769,7 +6769,7 @@ - - dev->flags = (flags & (IFF_DEBUG | IFF_NOTRAILERS | IFF_NOARP | - IFF_DYNAMIC | IFF_MULTICAST | IFF_PORTSEL | -- IFF_AUTOMEDIA)) | -+ IFF_AUTOMEDIA | IFF_NOMULTIPATH | IFF_MPBACKUP)) | - (dev->flags & (IFF_UP | IFF_VOLATILE | IFF_PROMISC | - IFF_ALLMULTI)); - -diff -aurN linux-4.14.174/net/core/skbuff.c mptcp-mptcp_v0.94/net/core/skbuff.c ---- linux-4.14.174/net/core/skbuff.c 2020-03-20 10:54:27.000000000 +0100 -+++ mptcp-mptcp_v0.94/net/core/skbuff.c 2020-03-23 09:45:33.000000000 +0100 -@@ -536,7 +536,7 @@ - skb_drop_list(&skb_shinfo(skb)->frag_list); - } - --static void skb_clone_fraglist(struct sk_buff *skb) -+void skb_clone_fraglist(struct sk_buff *skb) - { - struct sk_buff *list; - -@@ -1305,7 +1305,7 @@ - skb->inner_mac_header += off; - } - --static void copy_skb_header(struct sk_buff *new, const struct sk_buff *old) -+void copy_skb_header(struct sk_buff *new, const struct sk_buff *old) - { - __copy_skb_header(new, old); - -diff -aurN linux-4.14.174/net/core/sock.c mptcp-mptcp_v0.94/net/core/sock.c ---- linux-4.14.174/net/core/sock.c 2020-03-20 10:54:27.000000000 +0100 -+++ mptcp-mptcp_v0.94/net/core/sock.c 2020-03-23 09:45:33.000000000 +0100 -@@ -139,6 +139,11 @@ - - #include - -+#ifdef CONFIG_MPTCP -+#include -+#include -+#endif -+ - #include - #include - -@@ -1413,6 +1418,23 @@ - */ - static inline void sock_lock_init(struct sock *sk) - { -+#ifdef CONFIG_MPTCP -+ /* Reclassify the lock-class for subflows */ -+ if (sk->sk_type == SOCK_STREAM && sk->sk_protocol == IPPROTO_TCP) -+ if (mptcp(tcp_sk(sk)) || tcp_sk(sk)->is_master_sk) { -+ sock_lock_init_class_and_name(sk, meta_slock_key_name, -+ &meta_slock_key, -+ meta_key_name, -+ &meta_key); -+ -+ /* We don't yet have the mptcp-point. -+ * Thus we still need inet_sock_destruct -+ */ -+ sk->sk_destruct = inet_sock_destruct; -+ return; -+ } -+#endif -+ - if (sk->sk_kern_sock) - sock_lock_init_class_and_name( - sk, -@@ -1461,8 +1483,12 @@ - sk = kmem_cache_alloc(slab, priority & ~__GFP_ZERO); - if (!sk) - return sk; -- if (priority & __GFP_ZERO) -- sk_prot_clear_nulls(sk, prot->obj_size); -+ if (priority & __GFP_ZERO) { -+ if (prot->clear_sk) -+ prot->clear_sk(sk, prot->obj_size); -+ else -+ sk_prot_clear_nulls(sk, prot->obj_size); -+ } - } else - sk = kmalloc(prot->obj_size, priority); - -@@ -1684,6 +1710,7 @@ - atomic_set(&newsk->sk_zckey, 0); - - sock_reset_flag(newsk, SOCK_DONE); -+ sock_reset_flag(newsk, SOCK_MPTCP); - - /* sk->sk_memcg will be populated at accept() time */ - newsk->sk_memcg = NULL; -diff -aurN linux-4.14.174/net/ipv4/af_inet.c mptcp-mptcp_v0.94/net/ipv4/af_inet.c ---- linux-4.14.174/net/ipv4/af_inet.c 2020-03-20 10:54:27.000000000 +0100 -+++ mptcp-mptcp_v0.94/net/ipv4/af_inet.c 2020-03-23 09:45:33.000000000 +0100 -@@ -104,6 +104,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -149,6 +150,9 @@ - return; - } - -+ if (sock_flag(sk, SOCK_MPTCP)) -+ mptcp_disable_static_key(); -+ - WARN_ON(atomic_read(&sk->sk_rmem_alloc)); - WARN_ON(refcount_read(&sk->sk_wmem_alloc)); - WARN_ON(sk->sk_wmem_queued); -@@ -241,8 +245,7 @@ - * Create an inet socket. - */ - --static int inet_create(struct net *net, struct socket *sock, int protocol, -- int kern) -+int inet_create(struct net *net, struct socket *sock, int protocol, int kern) - { - struct sock *sk; - struct inet_protosw *answer; -@@ -702,6 +705,23 @@ - lock_sock(sk2); - - sock_rps_record_flow(sk2); -+ -+ if (sk2->sk_protocol == IPPROTO_TCP && mptcp(tcp_sk(sk2))) { -+ struct sock *sk_it = sk2; -+ -+ mptcp_for_each_sk(tcp_sk(sk2)->mpcb, sk_it) -+ sock_rps_record_flow(sk_it); -+ -+ if (tcp_sk(sk2)->mpcb->master_sk) { -+ sk_it = tcp_sk(sk2)->mpcb->master_sk; -+ -+ write_lock_bh(&sk_it->sk_callback_lock); -+ sk_it->sk_wq = newsock->wq; -+ sk_it->sk_socket = newsock; -+ write_unlock_bh(&sk_it->sk_callback_lock); -+ } -+ } -+ - WARN_ON(!((1 << sk2->sk_state) & - (TCPF_ESTABLISHED | TCPF_SYN_RECV | - TCPF_CLOSE_WAIT | TCPF_CLOSE))); -@@ -1883,6 +1903,9 @@ - - ip_init(); - -+ /* We must initialize MPTCP before TCP. */ -+ mptcp_init(); -+ - /* Setup TCP slab cache for open requests. */ - tcp_init(); - -diff -aurN linux-4.14.174/net/ipv4/inet_connection_sock.c mptcp-mptcp_v0.94/net/ipv4/inet_connection_sock.c ---- linux-4.14.174/net/ipv4/inet_connection_sock.c 2020-03-20 10:54:27.000000000 +0100 -+++ mptcp-mptcp_v0.94/net/ipv4/inet_connection_sock.c 2020-03-23 09:45:33.000000000 +0100 -@@ -23,6 +23,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -709,7 +710,10 @@ - int max_retries, thresh; - u8 defer_accept; - -- if (sk_state_load(sk_listener) != TCP_LISTEN) -+ if (sk_state_load(sk_listener) != TCP_LISTEN && !is_meta_sk(sk_listener)) -+ goto drop; -+ -+ if (is_meta_sk(sk_listener) && !mptcp_can_new_subflow(sk_listener)) - goto drop; - - max_retries = icsk->icsk_syn_retries ? : net->ipv4.sysctl_tcp_synack_retries; -@@ -803,7 +807,9 @@ - const struct request_sock *req, - const gfp_t priority) - { -- struct sock *newsk = sk_clone_lock(sk, priority); -+ struct sock *newsk; -+ -+ newsk = sk_clone_lock(sk, priority); - - if (newsk) { - struct inet_connection_sock *newicsk = inet_csk(newsk); -@@ -1003,7 +1009,14 @@ - */ - while ((req = reqsk_queue_remove(queue, sk)) != NULL) { - struct sock *child = req->sk; -+ bool mutex_taken = false; -+ struct mptcp_cb *mpcb = tcp_sk(child)->mpcb; - -+ if (is_meta_sk(child)) { -+ WARN_ON(atomic_inc_not_zero(&mpcb->mpcb_refcnt) == 0); -+ mutex_lock(&mpcb->mpcb_mutex); -+ mutex_taken = true; -+ } - local_bh_disable(); - bh_lock_sock(child); - WARN_ON(sock_owned_by_user(child)); -@@ -1013,6 +1026,10 @@ - reqsk_put(req); - bh_unlock_sock(child); - local_bh_enable(); -+ if (mutex_taken) { -+ mutex_unlock(&mpcb->mpcb_mutex); -+ mptcp_mpcb_put(mpcb); -+ } - sock_put(child); - - cond_resched(); -diff -aurN linux-4.14.174/net/ipv4/ip_sockglue.c mptcp-mptcp_v0.94/net/ipv4/ip_sockglue.c ---- linux-4.14.174/net/ipv4/ip_sockglue.c 2020-03-20 10:54:27.000000000 +0100 -+++ mptcp-mptcp_v0.94/net/ipv4/ip_sockglue.c 2020-03-23 09:45:33.000000000 +0100 -@@ -44,6 +44,8 @@ - #endif - #include - -+#include -+ - #include - #include - -@@ -658,7 +660,7 @@ - break; - old = rcu_dereference_protected(inet->inet_opt, - lockdep_sock_is_held(sk)); -- if (inet->is_icsk) { -+ if (inet->is_icsk && !is_meta_sk(sk)) { - struct inet_connection_sock *icsk = inet_csk(sk); - #if IS_ENABLED(CONFIG_IPV6) - if (sk->sk_family == PF_INET || -@@ -752,6 +754,17 @@ - inet->tos = val; - sk->sk_priority = rt_tos2priority(val); - sk_dst_reset(sk); -+ /* Update TOS on mptcp subflow */ -+ if (is_meta_sk(sk)) { -+ struct sock *sk_it; -+ mptcp_for_each_sk(tcp_sk(sk)->mpcb, sk_it) { -+ if (inet_sk(sk_it)->tos != inet_sk(sk)->tos) { -+ inet_sk(sk_it)->tos = inet_sk(sk)->tos; -+ sk_it->sk_priority = sk->sk_priority; -+ sk_dst_reset(sk_it); -+ } -+ } -+ } - } - break; - case IP_TTL: -diff -aurN linux-4.14.174/net/ipv4/Kconfig mptcp-mptcp_v0.94/net/ipv4/Kconfig ---- linux-4.14.174/net/ipv4/Kconfig 2020-03-20 10:54:27.000000000 +0100 -+++ mptcp-mptcp_v0.94/net/ipv4/Kconfig 2020-03-23 09:45:33.000000000 +0100 -@@ -675,6 +675,38 @@ - bufferbloat, policers, or AQM schemes that do not provide a delay - signal. It requires the fq ("Fair Queue") pacing packet scheduler. - -+config TCP_CONG_LIA -+ tristate "MPTCP Linked Increase" -+ depends on MPTCP -+ default n -+ ---help--- -+ MultiPath TCP Linked Increase Congestion Control -+ To enable it, just put 'lia' in tcp_congestion_control -+ -+config TCP_CONG_OLIA -+ tristate "MPTCP Opportunistic Linked Increase" -+ depends on MPTCP -+ default n -+ ---help--- -+ MultiPath TCP Opportunistic Linked Increase Congestion Control -+ To enable it, just put 'olia' in tcp_congestion_control -+ -+config TCP_CONG_WVEGAS -+ tristate "MPTCP WVEGAS CONGESTION CONTROL" -+ depends on MPTCP -+ default n -+ ---help--- -+ wVegas congestion control for MPTCP -+ To enable it, just put 'wvegas' in tcp_congestion_control -+ -+config TCP_CONG_BALIA -+ tristate "MPTCP BALIA CONGESTION CONTROL" -+ depends on MPTCP -+ default n -+ ---help--- -+ Multipath TCP Balanced Linked Adaptation Congestion Control -+ To enable it, just put 'balia' in tcp_congestion_control -+ - choice - prompt "Default TCP congestion control" - default DEFAULT_CUBIC -@@ -712,6 +744,18 @@ - config DEFAULT_BBR - bool "BBR" if TCP_CONG_BBR=y - -+ config DEFAULT_LIA -+ bool "Lia" if TCP_CONG_LIA=y -+ -+ config DEFAULT_OLIA -+ bool "Olia" if TCP_CONG_OLIA=y -+ -+ config DEFAULT_WVEGAS -+ bool "Wvegas" if TCP_CONG_WVEGAS=y -+ -+ config DEFAULT_BALIA -+ bool "Balia" if TCP_CONG_BALIA=y -+ - config DEFAULT_RENO - bool "Reno" - endchoice -@@ -732,6 +776,10 @@ - default "vegas" if DEFAULT_VEGAS - default "westwood" if DEFAULT_WESTWOOD - default "veno" if DEFAULT_VENO -+ default "lia" if DEFAULT_LIA -+ default "olia" if DEFAULT_OLIA -+ default "wvegas" if DEFAULT_WVEGAS -+ default "balia" if DEFAULT_BALIA - default "reno" if DEFAULT_RENO - default "dctcp" if DEFAULT_DCTCP - default "cdg" if DEFAULT_CDG -diff -aurN linux-4.14.174/net/ipv4/syncookies.c mptcp-mptcp_v0.94/net/ipv4/syncookies.c ---- linux-4.14.174/net/ipv4/syncookies.c 2020-03-20 10:54:27.000000000 +0100 -+++ mptcp-mptcp_v0.94/net/ipv4/syncookies.c 2020-03-23 09:45:33.000000000 +0100 -@@ -16,6 +16,8 @@ - #include - #include - #include -+#include -+#include - #include - #include - #include -@@ -179,7 +181,8 @@ - } - EXPORT_SYMBOL_GPL(__cookie_v4_init_sequence); - --__u32 cookie_v4_init_sequence(const struct sk_buff *skb, __u16 *mssp) -+__u32 cookie_v4_init_sequence(struct request_sock *req, const struct sock *sk, -+ const struct sk_buff *skb, __u16 *mssp) - { - const struct iphdr *iph = ip_hdr(skb); - const struct tcphdr *th = tcp_hdr(skb); -@@ -209,9 +212,27 @@ - struct inet_connection_sock *icsk = inet_csk(sk); - struct sock *child; - bool own_req; -+#ifdef CONFIG_MPTCP -+ int ret; -+#endif - - child = icsk->icsk_af_ops->syn_recv_sock(sk, skb, req, dst, - NULL, &own_req); -+ -+#ifdef CONFIG_MPTCP -+ if (!child) -+ goto listen_overflow; -+ -+ ret = mptcp_check_req_master(sk, child, req, skb, 0, tsoff); -+ if (ret < 0) -+ return NULL; -+ -+ if (!ret) -+ return tcp_sk(child)->mpcb->master_sk; -+ -+listen_overflow: -+#endif -+ - if (child) { - refcount_set(&req->rsk_refcnt, 1); - tcp_sk(child)->tsoffset = tsoff; -@@ -289,6 +310,7 @@ - { - struct ip_options *opt = &TCP_SKB_CB(skb)->header.h4.opt; - struct tcp_options_received tcp_opt; -+ struct mptcp_options_received mopt; - struct inet_request_sock *ireq; - struct tcp_request_sock *treq; - struct tcp_sock *tp = tcp_sk(sk); -@@ -318,7 +340,8 @@ - - /* check for timestamp cookie support */ - memset(&tcp_opt, 0, sizeof(tcp_opt)); -- tcp_parse_options(sock_net(sk), skb, &tcp_opt, 0, NULL); -+ mptcp_init_mp_opt(&mopt); -+ tcp_parse_options(sock_net(sk), skb, &tcp_opt, &mopt, 0, NULL, NULL); - - if (tcp_opt.saw_tstamp && tcp_opt.rcv_tsecr) { - tsoff = secure_tcp_ts_off(sock_net(sk), -@@ -331,7 +354,12 @@ - goto out; - - ret = NULL; -- req = inet_reqsk_alloc(&tcp_request_sock_ops, sk, false); /* for safety */ -+#ifdef CONFIG_MPTCP -+ if (mopt.saw_mpc) -+ req = inet_reqsk_alloc(&mptcp_request_sock_ops, sk, false); /* for safety */ -+ else -+#endif -+ req = inet_reqsk_alloc(&tcp_request_sock_ops, sk, false); /* for safety */ - if (!req) - goto out; - -@@ -351,12 +379,17 @@ - ireq->sack_ok = tcp_opt.sack_ok; - ireq->wscale_ok = tcp_opt.wscale_ok; - ireq->tstamp_ok = tcp_opt.saw_tstamp; -+ ireq->mptcp_rqsk = 0; -+ ireq->saw_mpc = 0; - req->ts_recent = tcp_opt.saw_tstamp ? tcp_opt.rcv_tsval : 0; - treq->snt_synack = 0; - treq->tfo_listener = false; - - ireq->ir_iif = inet_request_bound_dev_if(sk, skb); - -+ if (mopt.saw_mpc) -+ mptcp_cookies_reqsk_init(req, &mopt, skb); -+ - /* We throwed the options of the initial SYN away, so we hope - * the ACK carries the same options again (see RFC1122 4.2.3.8) - */ -@@ -390,10 +423,10 @@ - /* Try to redo what tcp_v4_send_synack did. */ - req->rsk_window_clamp = tp->window_clamp ? :dst_metric(&rt->dst, RTAX_WINDOW); - -- tcp_select_initial_window(tcp_full_space(sk), req->mss, -- &req->rsk_rcv_wnd, &req->rsk_window_clamp, -- ireq->wscale_ok, &rcv_wscale, -- dst_metric(&rt->dst, RTAX_INITRWND)); -+ tp->ops->select_initial_window(tcp_full_space(sk), req->mss, -+ &req->rsk_rcv_wnd, &req->rsk_window_clamp, -+ ireq->wscale_ok, &rcv_wscale, -+ dst_metric(&rt->dst, RTAX_INITRWND), sk); - - ireq->rcv_wscale = rcv_wscale; - ireq->ecn_ok = cookie_ecn_ok(&tcp_opt, sock_net(sk), &rt->dst); -diff -aurN linux-4.14.174/net/ipv4/tcp.c mptcp-mptcp_v0.94/net/ipv4/tcp.c ---- linux-4.14.174/net/ipv4/tcp.c 2020-03-20 10:54:27.000000000 +0100 -+++ mptcp-mptcp_v0.94/net/ipv4/tcp.c 2020-03-23 09:45:33.000000000 +0100 -@@ -273,6 +273,7 @@ - - #include - #include -+#include - #include - #include - #include -@@ -402,6 +403,25 @@ - return rate64; - } - -+const struct tcp_sock_ops tcp_specific = { -+ .__select_window = __tcp_select_window, -+ .select_window = tcp_select_window, -+ .select_initial_window = tcp_select_initial_window, -+ .select_size = select_size, -+ .init_buffer_space = tcp_init_buffer_space, -+ .set_rto = tcp_set_rto, -+ .should_expand_sndbuf = tcp_should_expand_sndbuf, -+ .send_fin = tcp_send_fin, -+ .write_xmit = tcp_write_xmit, -+ .send_active_reset = tcp_send_active_reset, -+ .write_wakeup = tcp_write_wakeup, -+ .retransmit_timer = tcp_retransmit_timer, -+ .time_wait = tcp_time_wait, -+ .cleanup_rbuf = tcp_cleanup_rbuf, -+ .cwnd_validate = tcp_cwnd_validate, -+ .set_cong_ctrl = __tcp_set_congestion_control, -+}; -+ - /* Address-family independent initialization for a tcp_sock. - * - * NOTE: A lot of things set to zero explicitly by call to -@@ -452,6 +472,11 @@ - sk->sk_sndbuf = sysctl_tcp_wmem[1]; - sk->sk_rcvbuf = sysctl_tcp_rmem[1]; - -+ tp->ops = &tcp_specific; -+ -+ /* Initialize MPTCP-specific stuff and function-pointers */ -+ mptcp_init_tcp_sock(sk); -+ - sk_sockets_allocated_inc(sk); - } - EXPORT_SYMBOL(tcp_init_sock); -@@ -766,6 +791,7 @@ - int ret; - - sock_rps_record_flow(sk); -+ - /* - * We can't seek on a socket input - */ -@@ -776,6 +802,14 @@ - - lock_sock(sk); - -+#ifdef CONFIG_MPTCP -+ if (mptcp(tcp_sk(sk))) { -+ struct sock *sk_it; -+ mptcp_for_each_sk(tcp_sk(sk)->mpcb, sk_it) -+ sock_rps_record_flow(sk_it); -+ } -+#endif -+ - timeo = sock_rcvtimeo(sk, sock->file->f_flags & O_NONBLOCK); - while (tss.len) { - ret = __tcp_splice_read(sk, &tss); -@@ -879,8 +913,7 @@ - return NULL; - } - --static unsigned int tcp_xmit_size_goal(struct sock *sk, u32 mss_now, -- int large_allowed) -+unsigned int tcp_xmit_size_goal(struct sock *sk, u32 mss_now, int large_allowed) - { - struct tcp_sock *tp = tcp_sk(sk); - u32 new_size_goal, size_goal; -@@ -908,8 +941,13 @@ - { - int mss_now; - -- mss_now = tcp_current_mss(sk); -- *size_goal = tcp_xmit_size_goal(sk, mss_now, !(flags & MSG_OOB)); -+ if (mptcp(tcp_sk(sk))) { -+ mss_now = mptcp_current_mss(sk); -+ *size_goal = mptcp_xmit_size_goal(sk, mss_now, !(flags & MSG_OOB)); -+ } else { -+ mss_now = tcp_current_mss(sk); -+ *size_goal = tcp_xmit_size_goal(sk, mss_now, !(flags & MSG_OOB)); -+ } - - return mss_now; - } -@@ -944,12 +982,33 @@ - * is fully established. - */ - if (((1 << sk->sk_state) & ~(TCPF_ESTABLISHED | TCPF_CLOSE_WAIT)) && -- !tcp_passive_fastopen(sk)) { -+ !tcp_passive_fastopen(mptcp(tp) && tp->mpcb->master_sk ? -+ tp->mpcb->master_sk : sk)) { - err = sk_stream_wait_connect(sk, &timeo); - if (err != 0) - goto out_err; - } - -+ if (mptcp(tp)) { -+ struct sock *sk_it = sk; -+ -+ /* We must check this with socket-lock hold because we iterate -+ * over the subflows. -+ */ -+ if (!mptcp_can_sendpage(sk)) { -+ ssize_t ret; -+ -+ release_sock(sk); -+ ret = sock_no_sendpage(sk->sk_socket, page, offset, -+ size, flags); -+ lock_sock(sk); -+ return ret; -+ } -+ -+ mptcp_for_each_sk(tp->mpcb, sk_it) -+ sock_rps_record_flow(sk_it); -+ } -+ - sk_clear_bit(SOCKWQ_ASYNC_NOSPACE, sk); - - mss_now = tcp_send_mss(sk, &size_goal, flags); -@@ -1067,8 +1126,9 @@ - int tcp_sendpage_locked(struct sock *sk, struct page *page, int offset, - size_t size, int flags) - { -- if (!(sk->sk_route_caps & NETIF_F_SG) || -- !sk_check_csum_caps(sk)) -+ /* If MPTCP is enabled, we check it later after establishment */ -+ if (!mptcp(tcp_sk(sk)) && (!(sk->sk_route_caps & NETIF_F_SG) || -+ !sk_check_csum_caps(sk))) - return sock_no_sendpage_locked(sk, page, offset, size, flags); - - tcp_rate_check_app_limited(sk); /* is sending application-limited? */ -@@ -1100,14 +1160,14 @@ - * This also speeds up tso_fragment(), since it wont fallback - * to tcp_fragment(). - */ --static int linear_payload_sz(bool first_skb) -+int linear_payload_sz(bool first_skb) - { - if (first_skb) - return SKB_WITH_OVERHEAD(2048 - MAX_TCP_HEADER); - return 0; - } - --static int select_size(const struct sock *sk, bool sg, bool first_skb) -+int select_size(const struct sock *sk, bool sg, bool first_skb) - { - const struct tcp_sock *tp = tcp_sk(sk); - int tmp = tp->mss_cache; -@@ -1229,12 +1289,19 @@ - * is fully established. - */ - if (((1 << sk->sk_state) & ~(TCPF_ESTABLISHED | TCPF_CLOSE_WAIT)) && -- !tcp_passive_fastopen(sk)) { -+ !tcp_passive_fastopen(mptcp(tp) && tp->mpcb->master_sk ? -+ tp->mpcb->master_sk : sk)) { - err = sk_stream_wait_connect(sk, &timeo); - if (err != 0) - goto do_error; - } - -+ if (mptcp(tp)) { -+ struct sock *sk_it = sk; -+ mptcp_for_each_sk(tp->mpcb, sk_it) -+ sock_rps_record_flow(sk_it); -+ } -+ - if (unlikely(tp->repair)) { - if (tp->repair_queue == TCP_RECV_QUEUE) { - copied = tcp_send_rcvq(sk, msg, size); -@@ -1270,7 +1337,10 @@ - if (sk->sk_err || (sk->sk_shutdown & SEND_SHUTDOWN)) - goto do_error; - -- sg = !!(sk->sk_route_caps & NETIF_F_SG); -+ if (mptcp(tp)) -+ sg = mptcp_can_sg(sk); -+ else -+ sg = !!(sk->sk_route_caps & NETIF_F_SG); - - while (msg_data_left(msg)) { - int copy = 0; -@@ -1299,7 +1369,7 @@ - } - first_skb = skb_queue_empty(&sk->sk_write_queue); - skb = sk_stream_alloc_skb(sk, -- select_size(sk, sg, first_skb), -+ tp->ops->select_size(sk, sg, first_skb), - sk->sk_allocation, - first_skb); - if (!skb) -@@ -1308,8 +1378,15 @@ - process_backlog = true; - /* - * Check whether we can use HW checksum. -+ * -+ * If dss-csum is enabled, we do not do hw-csum. -+ * In case of non-mptcp we check the -+ * device-capabilities. -+ * In case of mptcp, hw-csum's will be handled -+ * later in mptcp_write_xmit. - */ -- if (sk_check_csum_caps(sk)) -+ if (((mptcp(tp) && !tp->mpcb->dss_csum) || !mptcp(tp)) && -+ (mptcp(tp) || sk_check_csum_caps(sk))) - skb->ip_summed = CHECKSUM_PARTIAL; - - skb_entail(sk, skb); -@@ -1534,7 +1611,7 @@ - * calculation of whether or not we must ACK for the sake of - * a window update. - */ --static void tcp_cleanup_rbuf(struct sock *sk, int copied) -+void tcp_cleanup_rbuf(struct sock *sk, int copied) - { - struct tcp_sock *tp = tcp_sk(sk); - bool time_to_ack = false; -@@ -1577,7 +1654,7 @@ - - /* Optimize, __tcp_select_window() is not cheap. */ - if (2*rcv_window_now <= tp->window_clamp) { -- __u32 new_window = __tcp_select_window(sk); -+ __u32 new_window = tp->ops->__select_window(sk); - - /* Send ACK now, if this read freed lots of space - * in our buffer. Certainly, new_window is new window. -@@ -1693,7 +1770,7 @@ - /* Clean up data we have read: This will do ACK frames. */ - if (copied > 0) { - tcp_recv_skb(sk, seq, &offset); -- tcp_cleanup_rbuf(sk, copied); -+ tp->ops->cleanup_rbuf(sk, copied); - } - return copied; - } -@@ -1793,6 +1870,14 @@ - - lock_sock(sk); - -+#ifdef CONFIG_MPTCP -+ if (mptcp(tp)) { -+ struct sock *sk_it; -+ mptcp_for_each_sk(tp->mpcb, sk_it) -+ sock_rps_record_flow(sk_it); -+ } -+#endif -+ - err = -ENOTCONN; - if (sk->sk_state == TCP_LISTEN) - goto out; -@@ -1913,7 +1998,7 @@ - } - } - -- tcp_cleanup_rbuf(sk, copied); -+ tp->ops->cleanup_rbuf(sk, copied); - - if (copied >= target) { - /* Do not sleep, just process backlog. */ -@@ -2006,7 +2091,7 @@ - tcp_recv_timestamp(msg, sk, &tss); - - /* Clean up data we have read: This will do ACK frames. */ -- tcp_cleanup_rbuf(sk, copied); -+ tp->ops->cleanup_rbuf(sk, copied); - - release_sock(sk); - return copied; -@@ -2084,7 +2169,7 @@ - [TCP_NEW_SYN_RECV] = TCP_CLOSE, /* should not happen ! */ - }; - --static int tcp_close_state(struct sock *sk) -+int tcp_close_state(struct sock *sk) - { - int next = (int)new_state[sk->sk_state]; - int ns = next & TCP_STATE_MASK; -@@ -2114,7 +2199,7 @@ - TCPF_SYN_RECV | TCPF_CLOSE_WAIT)) { - /* Clear out any half completed packets. FIN if needed. */ - if (tcp_close_state(sk)) -- tcp_send_fin(sk); -+ tcp_sk(sk)->ops->send_fin(sk); - } - } - EXPORT_SYMBOL(tcp_shutdown); -@@ -2139,6 +2224,17 @@ - int data_was_unread = 0; - int state; - -+ if (is_meta_sk(sk)) { -+ /* TODO: Currently forcing timeout to 0 because -+ * sk_stream_wait_close will complain during lockdep because -+ * of the mpcb_mutex (circular lock dependency through -+ * inet_csk_listen_stop()). -+ * We should find a way to get rid of the mpcb_mutex. -+ */ -+ mptcp_close(sk, 0); -+ return; -+ } -+ - lock_sock(sk); - sk->sk_shutdown = SHUTDOWN_MASK; - -@@ -2183,7 +2279,7 @@ - /* Unread data was tossed, zap the connection. */ - NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPABORTONCLOSE); - tcp_set_state(sk, TCP_CLOSE); -- tcp_send_active_reset(sk, sk->sk_allocation); -+ tcp_sk(sk)->ops->send_active_reset(sk, sk->sk_allocation); - } else if (sock_flag(sk, SOCK_LINGER) && !sk->sk_lingertime) { - /* Check zero linger _after_ checking for unread data. */ - sk->sk_prot->disconnect(sk, 0); -@@ -2257,7 +2353,7 @@ - struct tcp_sock *tp = tcp_sk(sk); - if (tp->linger2 < 0) { - tcp_set_state(sk, TCP_CLOSE); -- tcp_send_active_reset(sk, GFP_ATOMIC); -+ tp->ops->send_active_reset(sk, GFP_ATOMIC); - __NET_INC_STATS(sock_net(sk), - LINUX_MIB_TCPABORTONLINGER); - } else { -@@ -2267,7 +2363,8 @@ - inet_csk_reset_keepalive_timer(sk, - tmo - TCP_TIMEWAIT_LEN); - } else { -- tcp_time_wait(sk, TCP_FIN_WAIT2, tmo); -+ tcp_sk(sk)->ops->time_wait(sk, TCP_FIN_WAIT2, -+ tmo); - goto out; - } - } -@@ -2276,7 +2373,7 @@ - sk_mem_reclaim(sk); - if (tcp_check_oom(sk, 0)) { - tcp_set_state(sk, TCP_CLOSE); -- tcp_send_active_reset(sk, GFP_ATOMIC); -+ tcp_sk(sk)->ops->send_active_reset(sk, GFP_ATOMIC); - __NET_INC_STATS(sock_net(sk), - LINUX_MIB_TCPABORTONMEMORY); - } else if (!check_net(sock_net(sk))) { -@@ -2305,15 +2402,6 @@ - } - EXPORT_SYMBOL(tcp_close); - --/* These states need RST on ABORT according to RFC793 */ -- --static inline bool tcp_need_reset(int state) --{ -- return (1 << state) & -- (TCPF_ESTABLISHED | TCPF_CLOSE_WAIT | TCPF_FIN_WAIT1 | -- TCPF_FIN_WAIT2 | TCPF_SYN_RECV); --} -- - int tcp_disconnect(struct sock *sk, int flags) - { - struct inet_sock *inet = inet_sk(sk); -@@ -2336,7 +2424,7 @@ - /* The last check adjusts for discrepancy of Linux wrt. RFC - * states - */ -- tcp_send_active_reset(sk, gfp_any()); -+ tp->ops->send_active_reset(sk, gfp_any()); - sk->sk_err = ECONNRESET; - } else if (old_state == TCP_SYN_SENT) - sk->sk_err = ECONNRESET; -@@ -2352,6 +2440,13 @@ - if (!(sk->sk_userlocks & SOCK_BINDADDR_LOCK)) - inet_reset_saddr(sk); - -+ if (is_meta_sk(sk)) { -+ mptcp_disconnect(sk); -+ } else { -+ if (tp->inside_tk_table) -+ mptcp_hash_remove_bh(tp); -+ } -+ - sk->sk_shutdown = 0; - sock_reset_flag(sk, SOCK_DONE); - tp->srtt_us = 0; -@@ -2406,7 +2501,7 @@ - static inline bool tcp_can_repair_sock(const struct sock *sk) - { - return ns_capable(sock_net(sk)->user_ns, CAP_NET_ADMIN) && -- (sk->sk_state != TCP_LISTEN); -+ (sk->sk_state != TCP_LISTEN) && !sock_flag(sk, SOCK_MPTCP); - } - - static int tcp_repair_set_window(struct tcp_sock *tp, char __user *optbuf, int len) -@@ -2543,6 +2638,61 @@ - release_sock(sk); - return err; - } -+#ifdef CONFIG_MPTCP -+ case MPTCP_SCHEDULER: { -+ char name[MPTCP_SCHED_NAME_MAX]; -+ -+ if (optlen < 1) -+ return -EINVAL; -+ -+ /* Cannot be used if MPTCP is not used or we already have -+ * established an MPTCP-connection. -+ */ -+ if (mptcp_init_failed || !sysctl_mptcp_enabled || -+ sk->sk_state != TCP_CLOSE) -+ return -EPERM; -+ -+ val = strncpy_from_user(name, optval, -+ min_t(long, MPTCP_SCHED_NAME_MAX - 1, -+ optlen)); -+ -+ if (val < 0) -+ return -EFAULT; -+ name[val] = 0; -+ -+ lock_sock(sk); -+ err = mptcp_set_scheduler(sk, name); -+ release_sock(sk); -+ return err; -+ } -+ -+ case MPTCP_PATH_MANAGER: { -+ char name[MPTCP_PM_NAME_MAX]; -+ -+ if (optlen < 1) -+ return -EINVAL; -+ -+ /* Cannot be used if MPTCP is not used or we already have -+ * established an MPTCP-connection. -+ */ -+ if (mptcp_init_failed || !sysctl_mptcp_enabled || -+ sk->sk_state != TCP_CLOSE) -+ return -EPERM; -+ -+ val = strncpy_from_user(name, optval, -+ min_t(long, MPTCP_PM_NAME_MAX - 1, -+ optlen)); -+ -+ if (val < 0) -+ return -EFAULT; -+ name[val] = 0; -+ -+ lock_sock(sk); -+ err = mptcp_set_path_manager(sk, name); -+ release_sock(sk); -+ return err; -+ } -+#endif - default: - /* fallthru */ - break; -@@ -2720,6 +2870,12 @@ - break; - - case TCP_DEFER_ACCEPT: -+ /* An established MPTCP-connection (mptcp(tp) only returns true -+ * if the socket is established) should not use DEFER on new -+ * subflows. -+ */ -+ if (mptcp(tp)) -+ break; - /* Translate value in seconds to number of retransmits */ - icsk->icsk_accept_queue.rskq_defer_accept = - secs_to_retrans(val, TCP_TIMEOUT_INIT / HZ, -@@ -2747,7 +2903,7 @@ - (TCPF_ESTABLISHED | TCPF_CLOSE_WAIT) && - inet_csk_ack_scheduled(sk)) { - icsk->icsk_ack.pending |= ICSK_ACK_PUSHED; -- tcp_cleanup_rbuf(sk, 1); -+ tp->ops->cleanup_rbuf(sk, 1); - if (!(val & 1)) - icsk->icsk_ack.pingpong = 1; - } -@@ -2757,7 +2913,7 @@ - #ifdef CONFIG_TCP_MD5SIG - case TCP_MD5SIG: - case TCP_MD5SIG_EXT: -- if ((1 << sk->sk_state) & (TCPF_CLOSE | TCPF_LISTEN)) -+ if ((1 << sk->sk_state) & (TCPF_CLOSE | TCPF_LISTEN) && !sock_flag(sk, SOCK_MPTCP)) - err = tp->af_specific->md5_parse(sk, optname, optval, optlen); - else - err = -EINVAL; -@@ -2808,6 +2964,32 @@ - tp->notsent_lowat = val; - sk->sk_write_space(sk); - break; -+#ifdef CONFIG_MPTCP -+ case MPTCP_ENABLED: -+ if (mptcp_init_failed || !sysctl_mptcp_enabled || -+ sk->sk_state != TCP_CLOSE -+#ifdef CONFIG_TCP_MD5SIG -+ || tp->md5sig_info -+#endif -+ ) { -+ err = -EPERM; -+ break; -+ } -+ -+ if (val) -+ mptcp_enable_sock(sk); -+ else -+ mptcp_disable_sock(sk); -+ break; -+ case MPTCP_INFO: -+ if (mptcp_init_failed || !sysctl_mptcp_enabled) { -+ err = -EPERM; -+ break; -+ } -+ -+ tp->record_master_info = !!(val & MPTCP_INFO_FLAG_SAVE_MASTER); -+ break; -+#endif - default: - err = -ENOPROTOOPT; - break; -@@ -2861,7 +3043,7 @@ - } - - /* Return information about state of tcp endpoint in API format. */ --void tcp_get_info(struct sock *sk, struct tcp_info *info) -+void tcp_get_info(struct sock *sk, struct tcp_info *info, bool no_lock) - { - const struct tcp_sock *tp = tcp_sk(sk); /* iff sk_type == SOCK_STREAM */ - const struct inet_connection_sock *icsk = inet_csk(sk); -@@ -2898,7 +3080,8 @@ - return; - } - -- slow = lock_sock_fast(sk); -+ if (!no_lock) -+ slow = lock_sock_fast(sk); - - info->tcpi_ca_state = icsk->icsk_ca_state; - info->tcpi_retransmits = icsk->icsk_retransmits; -@@ -2967,7 +3150,9 @@ - rate64 = tcp_compute_delivery_rate(tp); - if (rate64) - info->tcpi_delivery_rate = rate64; -- unlock_sock_fast(sk, slow); -+ -+ if (!no_lock) -+ unlock_sock_fast(sk, slow); - } - EXPORT_SYMBOL_GPL(tcp_get_info); - -@@ -3073,7 +3258,7 @@ - if (get_user(len, optlen)) - return -EFAULT; - -- tcp_get_info(sk, &info); -+ tcp_get_info(sk, &info, false); - - len = min_t(unsigned int, len, sizeof(info)); - if (put_user(len, optlen)) -@@ -3235,6 +3420,87 @@ - } - return 0; - } -+#ifdef CONFIG_MPTCP -+ case MPTCP_SCHEDULER: -+ if (get_user(len, optlen)) -+ return -EFAULT; -+ len = min_t(unsigned int, len, MPTCP_SCHED_NAME_MAX); -+ if (put_user(len, optlen)) -+ return -EFAULT; -+ -+ lock_sock(sk); -+ if (mptcp(tcp_sk(sk))) { -+ struct mptcp_cb *mpcb = tcp_sk(mptcp_meta_sk(sk))->mpcb; -+ -+ if (copy_to_user(optval, mpcb->sched_ops->name, len)) { -+ release_sock(sk); -+ return -EFAULT; -+ } -+ } else { -+ if (copy_to_user(optval, tcp_sk(sk)->mptcp_sched_name, -+ len)) { -+ release_sock(sk); -+ return -EFAULT; -+ } -+ } -+ release_sock(sk); -+ return 0; -+ -+ case MPTCP_PATH_MANAGER: -+ if (get_user(len, optlen)) -+ return -EFAULT; -+ len = min_t(unsigned int, len, MPTCP_PM_NAME_MAX); -+ if (put_user(len, optlen)) -+ return -EFAULT; -+ -+ lock_sock(sk); -+ if (mptcp(tcp_sk(sk))) { -+ struct mptcp_cb *mpcb = tcp_sk(mptcp_meta_sk(sk))->mpcb; -+ -+ if (copy_to_user(optval, mpcb->pm_ops->name, len)) { -+ release_sock(sk); -+ return -EFAULT; -+ } -+ } else { -+ if (copy_to_user(optval, tcp_sk(sk)->mptcp_pm_name, -+ len)) { -+ release_sock(sk); -+ return -EFAULT; -+ } -+ } -+ release_sock(sk); -+ return 0; -+ -+ case MPTCP_ENABLED: -+ if (sk->sk_state != TCP_SYN_SENT) -+ val = mptcp(tp) ? 1 : 0; -+ else -+ val = sock_flag(sk, SOCK_MPTCP) ? 1 : 0; -+ break; -+ case MPTCP_INFO: -+ { -+ int ret; -+ -+ if (!mptcp(tp)) -+ return -EINVAL; -+ -+ if (get_user(len, optlen)) -+ return -EFAULT; -+ -+ len = min_t(unsigned int, len, sizeof(struct mptcp_info)); -+ -+ lock_sock(sk); -+ ret = mptcp_get_info(sk, optval, len); -+ release_sock(sk); -+ -+ if (ret) -+ return ret; -+ -+ if (put_user(len, optlen)) -+ return -EFAULT; -+ return 0; -+ } -+#endif - default: - return -ENOPROTOOPT; - } -@@ -3409,7 +3675,9 @@ - if (sk->sk_state == TCP_SYN_SENT || sk->sk_state == TCP_SYN_RECV) - TCP_INC_STATS(sock_net(sk), TCP_MIB_ATTEMPTFAILS); - -+ WARN_ON(sk->sk_state == TCP_CLOSE); - tcp_set_state(sk, TCP_CLOSE); -+ - tcp_clear_xmit_timers(sk); - if (req) - reqsk_fastopen_remove(sk, req, false); -@@ -3425,6 +3693,8 @@ - - int tcp_abort(struct sock *sk, int err) - { -+ struct sock *meta_sk = mptcp(tcp_sk(sk)) ? mptcp_meta_sk(sk) : sk; -+ - if (!sk_fullsock(sk)) { - if (sk->sk_state == TCP_NEW_SYN_RECV) { - struct request_sock *req = inet_reqsk(sk); -@@ -3438,7 +3708,7 @@ - } - - /* Don't race with userspace socket closes such as tcp_close. */ -- lock_sock(sk); -+ lock_sock(meta_sk); - - if (sk->sk_state == TCP_LISTEN) { - tcp_set_state(sk, TCP_CLOSE); -@@ -3447,7 +3717,7 @@ - - /* Don't race with BH socket closes such as inet_csk_listen_stop. */ - local_bh_disable(); -- bh_lock_sock(sk); -+ bh_lock_sock(meta_sk); - - if (!sock_flag(sk, SOCK_DEAD)) { - sk->sk_err = err; -@@ -3455,14 +3725,14 @@ - smp_wmb(); - sk->sk_error_report(sk); - if (tcp_need_reset(sk->sk_state)) -- tcp_send_active_reset(sk, GFP_ATOMIC); -+ tcp_sk(sk)->ops->send_active_reset(sk, GFP_ATOMIC); - tcp_done(sk); - } - -- bh_unlock_sock(sk); -+ bh_unlock_sock(meta_sk); - local_bh_enable(); - tcp_write_queue_purge(sk); -- release_sock(sk); -+ release_sock(meta_sk); - return 0; - } - EXPORT_SYMBOL_GPL(tcp_abort); -diff -aurN linux-4.14.174/net/ipv4/tcp_cong.c mptcp-mptcp_v0.94/net/ipv4/tcp_cong.c ---- linux-4.14.174/net/ipv4/tcp_cong.c 2020-03-20 10:54:27.000000000 +0100 -+++ mptcp-mptcp_v0.94/net/ipv4/tcp_cong.c 2020-03-23 09:45:33.000000000 +0100 -@@ -333,13 +333,19 @@ - return ret; - } - -+int tcp_set_congestion_control(struct sock *sk, const char *name, bool load, -+ bool reinit, bool cap_net_admin) -+{ -+ return tcp_sk(sk)->ops->set_cong_ctrl(sk, name, load, reinit, cap_net_admin); -+} -+ - /* Change congestion control for socket. If load is false, then it is the - * responsibility of the caller to call tcp_init_congestion_control or - * tcp_reinit_congestion_control (if the current congestion control was - * already initialized. - */ --int tcp_set_congestion_control(struct sock *sk, const char *name, bool load, -- bool reinit, bool cap_net_admin) -+int __tcp_set_congestion_control(struct sock *sk, const char *name, bool load, -+ bool reinit, bool cap_net_admin) - { - struct inet_connection_sock *icsk = inet_csk(sk); - const struct tcp_congestion_ops *ca; -diff -aurN linux-4.14.174/net/ipv4/tcp_diag.c mptcp-mptcp_v0.94/net/ipv4/tcp_diag.c ---- linux-4.14.174/net/ipv4/tcp_diag.c 2020-03-20 10:54:27.000000000 +0100 -+++ mptcp-mptcp_v0.94/net/ipv4/tcp_diag.c 2020-03-23 09:45:33.000000000 +0100 -@@ -34,7 +34,7 @@ - r->idiag_wqueue = tp->write_seq - tp->snd_una; - } - if (info) -- tcp_get_info(sk, info); -+ tcp_get_info(sk, info, false); - } - - #ifdef CONFIG_TCP_MD5SIG -diff -aurN linux-4.14.174/net/ipv4/tcp_fastopen.c mptcp-mptcp_v0.94/net/ipv4/tcp_fastopen.c ---- linux-4.14.174/net/ipv4/tcp_fastopen.c 2020-03-20 10:54:27.000000000 +0100 -+++ mptcp-mptcp_v0.94/net/ipv4/tcp_fastopen.c 2020-03-23 09:45:33.000000000 +0100 -@@ -9,6 +9,7 @@ - #include - #include - #include -+#include - - int sysctl_tcp_fastopen __read_mostly = TFO_CLIENT_ENABLE; - -@@ -176,8 +177,9 @@ - { - struct tcp_sock *tp; - struct request_sock_queue *queue = &inet_csk(sk)->icsk_accept_queue; -- struct sock *child; -+ struct sock *child, *meta_sk; - bool own_req; -+ int ret; - - req->num_retrans = 0; - req->num_timeout = 0; -@@ -216,20 +218,31 @@ - - refcount_set(&req->rsk_refcnt, 2); - -+ tp->rcv_nxt = TCP_SKB_CB(skb)->seq + 1; -+ -+ tcp_fastopen_add_skb(child, skb); -+ -+ tcp_rsk(req)->rcv_nxt = tp->rcv_nxt; -+ tp->rcv_wup = tp->rcv_nxt; -+ -+ meta_sk = child; -+ ret = mptcp_check_req_fastopen(meta_sk, req); -+ if (ret < 0) -+ return NULL; -+ -+ if (ret == 0) { -+ child = tcp_sk(meta_sk)->mpcb->master_sk; -+ tp = tcp_sk(child); -+ } -+ - /* Now finish processing the fastopen child socket. */ - inet_csk(child)->icsk_af_ops->rebuild_header(child); - tcp_init_congestion_control(child); - tcp_mtup_init(child); - tcp_init_metrics(child); - tcp_call_bpf(child, BPF_SOCK_OPS_PASSIVE_ESTABLISHED_CB); -- tcp_init_buffer_space(child); -- -- tp->rcv_nxt = TCP_SKB_CB(skb)->seq + 1; -+ tp->ops->init_buffer_space(child); - -- tcp_fastopen_add_skb(child, skb); -- -- tcp_rsk(req)->rcv_nxt = tp->rcv_nxt; -- tp->rcv_wup = tp->rcv_nxt; - /* tcp_conn_request() is sending the SYNACK, - * and queues the child into listener accept queue. - */ -diff -aurN linux-4.14.174/net/ipv4/tcp_input.c mptcp-mptcp_v0.94/net/ipv4/tcp_input.c ---- linux-4.14.174/net/ipv4/tcp_input.c 2020-03-20 10:54:27.000000000 +0100 -+++ mptcp-mptcp_v0.94/net/ipv4/tcp_input.c 2020-03-23 09:45:33.000000000 +0100 -@@ -76,6 +76,9 @@ - #include - #include - #include -+#include -+#include -+#include - - int sysctl_tcp_fack __read_mostly; - int sysctl_tcp_max_reordering __read_mostly = 300; -@@ -96,28 +99,6 @@ - int sysctl_tcp_early_retrans __read_mostly = 3; - int sysctl_tcp_invalid_ratelimit __read_mostly = HZ/2; - --#define FLAG_DATA 0x01 /* Incoming frame contained data. */ --#define FLAG_WIN_UPDATE 0x02 /* Incoming ACK was a window update. */ --#define FLAG_DATA_ACKED 0x04 /* This ACK acknowledged new data. */ --#define FLAG_RETRANS_DATA_ACKED 0x08 /* "" "" some of which was retransmitted. */ --#define FLAG_SYN_ACKED 0x10 /* This ACK acknowledged SYN. */ --#define FLAG_DATA_SACKED 0x20 /* New SACK. */ --#define FLAG_ECE 0x40 /* ECE in this ACK */ --#define FLAG_LOST_RETRANS 0x80 /* This ACK marks some retransmission lost */ --#define FLAG_SLOWPATH 0x100 /* Do not skip RFC checks for window update.*/ --#define FLAG_ORIG_SACK_ACKED 0x200 /* Never retransmitted data are (s)acked */ --#define FLAG_SND_UNA_ADVANCED 0x400 /* Snd_una was changed (!= FLAG_DATA_ACKED) */ --#define FLAG_DSACKING_ACK 0x800 /* SACK blocks contained D-SACK info */ --#define FLAG_SET_XMIT_TIMER 0x1000 /* Set TLP or RTO timer */ --#define FLAG_SACK_RENEGING 0x2000 /* snd_una advanced to a sacked seq */ --#define FLAG_UPDATE_TS_RECENT 0x4000 /* tcp_replace_ts_recent() */ --#define FLAG_NO_CHALLENGE_ACK 0x8000 /* do not call tcp_send_challenge_ack() */ -- --#define FLAG_ACKED (FLAG_DATA_ACKED|FLAG_SYN_ACKED) --#define FLAG_NOT_DUP (FLAG_DATA|FLAG_WIN_UPDATE|FLAG_ACKED) --#define FLAG_CA_ALERT (FLAG_DATA_SACKED|FLAG_ECE|FLAG_DSACKING_ACK) --#define FLAG_FORWARD_PROGRESS (FLAG_ACKED|FLAG_DATA_SACKED) -- - #define TCP_REMNANT (TCP_FLAG_FIN|TCP_FLAG_URG|TCP_FLAG_SYN|TCP_FLAG_PSH) - #define TCP_HP_BITS (~(TCP_RESERVED_BITS|TCP_FLAG_PSH)) - -@@ -329,8 +310,12 @@ - per_mss = roundup_pow_of_two(per_mss) + - SKB_DATA_ALIGN(sizeof(struct sk_buff)); - -- nr_segs = max_t(u32, TCP_INIT_CWND, tp->snd_cwnd); -- nr_segs = max_t(u32, nr_segs, tp->reordering + 1); -+ if (mptcp(tp)) { -+ nr_segs = mptcp_check_snd_buf(tp); -+ } else { -+ nr_segs = max_t(u32, TCP_INIT_CWND, tp->snd_cwnd); -+ nr_segs = max_t(u32, nr_segs, tp->reordering + 1); -+ } - - /* Fast Recovery (RFC 5681 3.2) : - * Cubic needs 1.7 factor, rounded to 2 to include -@@ -339,8 +324,16 @@ - sndmem = ca_ops->sndbuf_expand ? ca_ops->sndbuf_expand(sk) : 2; - sndmem *= nr_segs * per_mss; - -- if (sk->sk_sndbuf < sndmem) -+ /* MPTCP: after this sndmem is the new contribution of the -+ * current subflow to the aggregated sndbuf */ -+ if (sk->sk_sndbuf < sndmem) { -+ int old_sndbuf = sk->sk_sndbuf; - sk->sk_sndbuf = min(sndmem, sysctl_tcp_wmem[2]); -+ /* MPTCP: ok, the subflow sndbuf has grown, reflect -+ * this in the aggregate buffer.*/ -+ if (mptcp(tp) && old_sndbuf != sk->sk_sndbuf) -+ mptcp_update_sndbuf(tp); -+ } - } - - /* 2. Tuning advertised window (window_clamp, rcv_ssthresh) -@@ -389,9 +382,15 @@ - static void tcp_grow_window(struct sock *sk, const struct sk_buff *skb) - { - struct tcp_sock *tp = tcp_sk(sk); -+ struct sock *meta_sk = mptcp(tp) ? mptcp_meta_sk(sk) : sk; -+ struct tcp_sock *meta_tp = tcp_sk(meta_sk); - int room; - -- room = min_t(int, tp->window_clamp, tcp_space(sk)) - tp->rcv_ssthresh; -+ if (is_meta_sk(sk)) -+ return; -+ -+ -+ room = min_t(int, meta_tp->window_clamp, tcp_space(meta_sk)) - meta_tp->rcv_ssthresh; - - /* Check #1 */ - if (room > 0 && !tcp_under_memory_pressure(sk)) { -@@ -401,13 +400,13 @@ - * will fit to rcvbuf in future. - */ - if (tcp_win_from_space(skb->truesize) <= skb->len) -- incr = 2 * tp->advmss; -+ incr = 2 * meta_tp->advmss; - else -- incr = __tcp_grow_window(sk, skb); -+ incr = __tcp_grow_window(meta_sk, skb); - - if (incr) { - incr = max_t(int, incr, 2 * skb->len); -- tp->rcv_ssthresh += min(room, incr); -+ meta_tp->rcv_ssthresh += min(room, incr); - inet_csk(sk)->icsk_ack.quick |= 1; - } - } -@@ -601,7 +600,10 @@ - - tcp_mstamp_refresh(tp); - time = tcp_stamp_us_delta(tp->tcp_mstamp, tp->rcvq_space.time); -- if (time < (tp->rcv_rtt_est.rtt_us >> 3) || tp->rcv_rtt_est.rtt_us == 0) -+ if (mptcp(tp)) { -+ if (mptcp_check_rtt(tp, time)) -+ return; -+ } else if (time < (tp->rcv_rtt_est.rtt_us >> 3) || tp->rcv_rtt_est.rtt_us == 0) - return; - - /* Number of bytes copied to user in last RTT */ -@@ -837,7 +839,7 @@ - /* Calculate rto without backoff. This is the second half of Van Jacobson's - * routine referred to above. - */ --static void tcp_set_rto(struct sock *sk) -+void tcp_set_rto(struct sock *sk) - { - const struct tcp_sock *tp = tcp_sk(sk); - /* Old crap is replaced with new one. 8) -@@ -1428,7 +1430,11 @@ - int len; - int in_sack; - -- if (!sk_can_gso(sk)) -+ /* For MPTCP we cannot shift skb-data and remove one skb from the -+ * send-queue, because this will make us loose the DSS-option (which -+ * is stored in TCP_SKB_CB(skb)->dss) of the skb we are removing. -+ */ -+ if (!sk_can_gso(sk) || mptcp(tp)) - goto fallback; - - /* Normally R but no L won't result in plain S */ -@@ -2983,7 +2989,7 @@ - */ - tcp_update_rtt_min(sk, ca_rtt_us); - tcp_rtt_estimator(sk, seq_rtt_us); -- tcp_set_rto(sk); -+ tp->ops->set_rto(sk); - - /* RFC6298: only reset backoff on valid RTT measurement. */ - inet_csk(sk)->icsk_backoff = 0; -@@ -3051,7 +3057,7 @@ - } - - /* If we get here, the whole TSO packet has not been acked. */ --static u32 tcp_tso_acked(struct sock *sk, struct sk_buff *skb) -+u32 tcp_tso_acked(struct sock *sk, struct sk_buff *skb) - { - struct tcp_sock *tp = tcp_sk(sk); - u32 packets_acked; -@@ -3174,6 +3180,8 @@ - */ - if (likely(!(scb->tcp_flags & TCPHDR_SYN))) { - flag |= FLAG_DATA_ACKED; -+ if (mptcp(tp) && mptcp_is_data_seq(skb)) -+ flag |= MPTCP_FLAG_DATA_ACKED; - } else { - flag |= FLAG_SYN_ACKED; - tp->retrans_stamp = 0; -@@ -3286,7 +3294,7 @@ - return flag; - } - --static void tcp_ack_probe(struct sock *sk) -+void tcp_ack_probe(struct sock *sk) - { - const struct tcp_sock *tp = tcp_sk(sk); - struct inet_connection_sock *icsk = inet_csk(sk); -@@ -3356,9 +3364,8 @@ - /* Check that window update is acceptable. - * The function assumes that snd_una<=ack<=snd_next. - */ --static inline bool tcp_may_update_window(const struct tcp_sock *tp, -- const u32 ack, const u32 ack_seq, -- const u32 nwin) -+bool tcp_may_update_window(const struct tcp_sock *tp, const u32 ack, -+ const u32 ack_seq, const u32 nwin) - { - return after(ack, tp->snd_una) || - after(ack_seq, tp->snd_wl1) || -@@ -3578,7 +3585,7 @@ - } - - /* This routine deals with incoming acks, but not outgoing ones. */ --static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag) -+static int tcp_ack(struct sock *sk, struct sk_buff *skb, int flag) - { - struct inet_connection_sock *icsk = inet_csk(sk); - struct tcp_sock *tp = tcp_sk(sk); -@@ -3685,6 +3692,16 @@ - flag |= tcp_clean_rtx_queue(sk, prior_fackets, prior_snd_una, &acked, - &sack_state); - -+ if (mptcp(tp)) { -+ if (mptcp_fallback_infinite(sk, flag)) { -+ pr_err("%s resetting flow\n", __func__); -+ mptcp_send_reset(sk); -+ goto invalid_ack; -+ } -+ -+ mptcp_clean_rtx_infinite(skb, sk); -+ } -+ - if (tp->tlp_high_seq) - tcp_process_tlp_ack(sk, ack, flag); - /* If needed, reset TLP/RTO timer; RACK may later override this. */ -@@ -3763,8 +3780,10 @@ - */ - void tcp_parse_options(const struct net *net, - const struct sk_buff *skb, -- struct tcp_options_received *opt_rx, int estab, -- struct tcp_fastopen_cookie *foc) -+ struct tcp_options_received *opt_rx, -+ struct mptcp_options_received *mopt, -+ int estab, struct tcp_fastopen_cookie *foc, -+ struct tcp_sock *tp) - { - const unsigned char *ptr; - const struct tcphdr *th = tcp_hdr(skb); -@@ -3848,6 +3867,10 @@ - */ - break; - #endif -+ case TCPOPT_MPTCP: -+ mptcp_parse_options(ptr - 2, opsize, mopt, skb, tp); -+ break; -+ - case TCPOPT_FASTOPEN: - tcp_parse_fastopen_option( - opsize - TCPOLEN_FASTOPEN_BASE, -@@ -3912,7 +3935,9 @@ - return true; - } - -- tcp_parse_options(net, skb, &tp->rx_opt, 1, NULL); -+ tcp_parse_options(net, skb, &tp->rx_opt, -+ mptcp(tp) ? &tp->mptcp->rx_opt : NULL, 1, NULL, tp); -+ - if (tp->rx_opt.saw_tstamp && tp->rx_opt.rcv_tsecr) - tp->rx_opt.rcv_tsecr -= tp->tsoffset; - -@@ -4069,6 +4094,11 @@ - { - struct tcp_sock *tp = tcp_sk(sk); - -+ if (is_meta_sk(sk)) { -+ mptcp_fin(sk); -+ return; -+ } -+ - inet_csk_schedule_ack(sk); - - sk->sk_shutdown |= RCV_SHUTDOWN; -@@ -4079,6 +4109,10 @@ - case TCP_ESTABLISHED: - /* Move to CLOSE_WAIT */ - tcp_set_state(sk, TCP_CLOSE_WAIT); -+ -+ if (mptcp(tp)) -+ mptcp_sub_close_passive(sk); -+ - inet_csk(sk)->icsk_ack.pingpong = 1; - break; - -@@ -4101,9 +4135,16 @@ - tcp_set_state(sk, TCP_CLOSING); - break; - case TCP_FIN_WAIT2: -+ if (mptcp(tp)) { -+ /* The socket will get closed by mptcp_data_ready. -+ * We first have to process all data-sequences. -+ */ -+ tp->close_it = 1; -+ break; -+ } - /* Received a FIN -- send ACK and enter TIME_WAIT. */ - tcp_send_ack(sk); -- tcp_time_wait(sk, TCP_TIME_WAIT, 0); -+ tp->ops->time_wait(sk, TCP_TIME_WAIT, 0); - break; - default: - /* Only TCP_LISTEN and TCP_CLOSE are left, in these -@@ -4125,6 +4166,10 @@ - if (!sock_flag(sk, SOCK_DEAD)) { - sk->sk_state_change(sk); - -+ /* Don't wake up MPTCP-subflows */ -+ if (mptcp(tp)) -+ return; -+ - /* Do not send POLL_HUP for half duplex close. */ - if (sk->sk_shutdown == SHUTDOWN_MASK || - sk->sk_state == TCP_CLOSE) -@@ -4331,6 +4376,9 @@ - - *fragstolen = false; - -+ if (mptcp(tcp_sk(sk)) && !is_meta_sk(sk)) -+ return false; -+ - /* Its possible this segment overlaps with prior segment in queue */ - if (TCP_SKB_CB(from)->seq != TCP_SKB_CB(to)->end_seq) - return false; -@@ -4382,7 +4430,7 @@ - /* This one checks to see if we can put data from the - * out_of_order queue into the receive_queue. - */ --static void tcp_ofo_queue(struct sock *sk) -+void tcp_ofo_queue(struct sock *sk) - { - struct tcp_sock *tp = tcp_sk(sk); - __u32 dsack_high = tp->rcv_nxt; -@@ -4408,7 +4456,14 @@ - if (TCP_SKB_CB(skb)->has_rxtstamp) - skb->tstamp = TCP_SKB_CB(skb)->swtstamp; - -- if (unlikely(!after(TCP_SKB_CB(skb)->end_seq, tp->rcv_nxt))) { -+ /* In case of MPTCP, the segment may be empty if it's a -+ * non-data DATA_FIN. (see beginning of tcp_data_queue) -+ * -+ * But this only holds true for subflows, not for the -+ * meta-socket. -+ */ -+ if (unlikely(!after(TCP_SKB_CB(skb)->end_seq, tp->rcv_nxt) && -+ (is_meta_sk(sk) || !mptcp(tp) || TCP_SKB_CB(skb)->end_seq != TCP_SKB_CB(skb)->seq))) { - SOCK_DEBUG(sk, "ofo packet was already received\n"); - tcp_drop(sk, skb); - continue; -@@ -4443,6 +4498,9 @@ - static int tcp_try_rmem_schedule(struct sock *sk, struct sk_buff *skb, - unsigned int size) - { -+ if (mptcp(tcp_sk(sk))) -+ sk = mptcp_meta_sk(sk); -+ - if (atomic_read(&sk->sk_rmem_alloc) > sk->sk_rcvbuf || - !sk_rmem_schedule(sk, skb, size)) { - -@@ -4457,7 +4515,7 @@ - return 0; - } - --static void tcp_data_queue_ofo(struct sock *sk, struct sk_buff *skb) -+void tcp_data_queue_ofo(struct sock *sk, struct sk_buff *skb) - { - struct tcp_sock *tp = tcp_sk(sk); - struct rb_node **p, *parent; -@@ -4529,7 +4587,8 @@ - continue; - } - if (before(seq, TCP_SKB_CB(skb1)->end_seq)) { -- if (!after(end_seq, TCP_SKB_CB(skb1)->end_seq)) { -+ if (!after(end_seq, TCP_SKB_CB(skb1)->end_seq) && -+ (is_meta_sk(sk) || !mptcp(tp) || end_seq != seq)) { - /* All the bits are present. Drop. */ - NET_INC_STATS(sock_net(sk), - LINUX_MIB_TCPOFOMERGE); -@@ -4576,6 +4635,11 @@ - end_seq); - break; - } -+ /* MPTCP allows non-data data-fin to be in the ofo-queue */ -+ if (mptcp(tp) && !is_meta_sk(sk) && TCP_SKB_CB(skb1)->seq == TCP_SKB_CB(skb1)->end_seq) { -+ skb = skb1; -+ continue; -+ } - rb_erase(&skb1->rbnode, &tp->out_of_order_queue); - tcp_dsack_extend(sk, TCP_SKB_CB(skb1)->seq, - TCP_SKB_CB(skb1)->end_seq); -@@ -4587,7 +4651,7 @@ - tp->ooo_last_skb = skb; - - add_sack: -- if (tcp_is_sack(tp)) -+ if (tcp_is_sack(tp) && seq != end_seq) - tcp_sack_new_ofo_skb(sk, seq, end_seq); - end: - if (skb) { -@@ -4597,8 +4661,8 @@ - } - } - --static int __must_check tcp_queue_rcv(struct sock *sk, struct sk_buff *skb, int hdrlen, -- bool *fragstolen) -+int __must_check tcp_queue_rcv(struct sock *sk, struct sk_buff *skb, int hdrlen, -+ bool *fragstolen) - { - int eaten; - struct sk_buff *tail = skb_peek_tail(&sk->sk_receive_queue); -@@ -4671,10 +4735,14 @@ - bool fragstolen; - int eaten; - -- if (TCP_SKB_CB(skb)->seq == TCP_SKB_CB(skb)->end_seq) { -+ /* If no data is present, but a data_fin is in the options, we still -+ * have to call mptcp_queue_skb later on. */ -+ if (TCP_SKB_CB(skb)->seq == TCP_SKB_CB(skb)->end_seq && -+ !(mptcp(tp) && mptcp_is_data_fin(skb))) { - __kfree_skb(skb); - return; - } -+ - skb_dst_drop(skb); - __skb_pull(skb, tcp_hdr(skb)->doff * 4); - -@@ -4699,7 +4767,7 @@ - - eaten = tcp_queue_rcv(sk, skb, 0, &fragstolen); - tcp_rcv_nxt_update(tp, TCP_SKB_CB(skb)->end_seq); -- if (skb->len) -+ if (skb->len || mptcp_is_data_fin(skb)) - tcp_event_data_recv(sk, skb); - if (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN) - tcp_fin(sk); -@@ -4721,7 +4789,11 @@ - - if (eaten > 0) - kfree_skb_partial(skb, fragstolen); -- if (!sock_flag(sk, SOCK_DEAD)) -+ if (!sock_flag(sk, SOCK_DEAD) || mptcp(tp)) -+ /* MPTCP: we always have to call data_ready, because -+ * we may be about to receive a data-fin, which still -+ * must get queued. -+ */ - sk->sk_data_ready(sk); - return; - } -@@ -5060,7 +5132,7 @@ - return -1; - } - --static bool tcp_should_expand_sndbuf(const struct sock *sk) -+bool tcp_should_expand_sndbuf(const struct sock *sk) - { - const struct tcp_sock *tp = tcp_sk(sk); - -@@ -5095,7 +5167,7 @@ - { - struct tcp_sock *tp = tcp_sk(sk); - -- if (tcp_should_expand_sndbuf(sk)) { -+ if (tp->ops->should_expand_sndbuf(sk)) { - tcp_sndbuf_expand(sk); - tp->snd_cwnd_stamp = tcp_jiffies32; - } -@@ -5109,10 +5181,11 @@ - sock_reset_flag(sk, SOCK_QUEUE_SHRUNK); - /* pairs with tcp_poll() */ - smp_mb(); -- if (sk->sk_socket && -- test_bit(SOCK_NOSPACE, &sk->sk_socket->flags)) { -+ if (mptcp(tcp_sk(sk)) || -+ (sk->sk_socket && -+ test_bit(SOCK_NOSPACE, &sk->sk_socket->flags))) { - tcp_new_space(sk); -- if (!test_bit(SOCK_NOSPACE, &sk->sk_socket->flags)) -+ if (sk->sk_socket && !test_bit(SOCK_NOSPACE, &sk->sk_socket->flags)) - tcp_chrono_stop(sk, TCP_CHRONO_SNDBUF_LIMITED); - } - } -@@ -5135,8 +5208,14 @@ - if (((tp->rcv_nxt - tp->rcv_wup) > inet_csk(sk)->icsk_ack.rcv_mss && - /* ... and right edge of window advances far enough. - * (tcp_recvmsg() will send ACK otherwise). Or... -+ * in the case of mptcp the meta ofo queue may -+ * prevent tcp_recvmsg from being called in time -+ * so no data is available for the application, skip the -+ * receive window check as there is no hope that the application -+ * will do a tcp_recvmsg anytime soon. - */ -- __tcp_select_window(sk) >= tp->rcv_wnd) || -+ (tp->ops->__select_window(sk) >= tp->rcv_wnd || (mptcp(tp) && -+ skb_queue_empty(&mptcp_meta_sk(sk)->sk_receive_queue)))) || - /* We ACK each frame or... */ - tcp_in_quickack_mode(sk) || - /* We have out of order data. */ -@@ -5238,6 +5317,10 @@ - { - struct tcp_sock *tp = tcp_sk(sk); - -+ /* MPTCP urgent data is not yet supported */ -+ if (mptcp(tp)) -+ return; -+ - /* Check if we get a new urgent pointer - normally not. */ - if (th->urg) - tcp_check_urg(sk, th); -@@ -5380,9 +5463,15 @@ - goto discard; - } - -+ /* If valid: post process the received MPTCP options. */ -+ if (mptcp(tp) && mptcp_handle_options(sk, th, skb)) -+ goto discard; -+ - return true; - - discard: -+ if (mptcp(tp)) -+ mptcp_reset_mopt(tp); - tcp_drop(sk, skb); - return false; - } -@@ -5436,6 +5525,10 @@ - - tp->rx_opt.saw_tstamp = 0; - -+ /* MPTCP: force slowpath. */ -+ if (mptcp(tp)) -+ goto slow_path; -+ - /* pred_flags is 0xS?10 << 16 + snd_wnd - * if header_prediction is to be made - * 'S' will always be tp->tcp_header_len >> 2 -@@ -5605,7 +5698,7 @@ - */ - tp->lsndtime = tcp_jiffies32; - -- tcp_init_buffer_space(sk); -+ tp->ops->init_buffer_space(sk); - - if (sock_flag(sk, SOCK_KEEPOPEN)) - inet_csk_reset_keepalive_timer(sk, keepalive_time_when(tp)); -@@ -5620,7 +5713,8 @@ - struct tcp_fastopen_cookie *cookie) - { - struct tcp_sock *tp = tcp_sk(sk); -- struct sk_buff *data = tp->syn_data ? tcp_write_queue_head(sk) : NULL; -+ struct sock *meta_sk = mptcp(tp) ? mptcp_meta_sk(sk) : sk; -+ struct sk_buff *data = tp->syn_data ? tcp_write_queue_head(meta_sk) : NULL; - u16 mss = tp->rx_opt.mss_clamp, try_exp = 0; - bool syn_drop = false; - -@@ -5630,7 +5724,7 @@ - /* Get original SYNACK MSS value if user MSS sets mss_clamp */ - tcp_clear_options(&opt); - opt.user_mss = opt.mss_clamp = 0; -- tcp_parse_options(sock_net(sk), synack, &opt, 0, NULL); -+ tcp_parse_options(sock_net(sk), synack, &opt, NULL, 0, NULL, NULL); - mss = opt.mss_clamp; - } - -@@ -5654,7 +5748,11 @@ - - tcp_fastopen_cache_set(sk, mss, cookie, syn_drop, try_exp); - -- if (data) { /* Retransmit unacked data in SYN */ -+ /* In mptcp case, we do not rely on "retransmit", but instead on -+ * "transmit", because if fastopen data is not acked, the retransmission -+ * becomes the first MPTCP data (see mptcp_rcv_synsent_fastopen). -+ */ -+ if (data && !mptcp(tp)) { /* Retransmit unacked data in SYN */ - tcp_for_write_queue_from(data, sk) { - if (data == tcp_send_head(sk) || - __tcp_retransmit_skb(sk, data, 1)) -@@ -5682,9 +5780,13 @@ - struct tcp_sock *tp = tcp_sk(sk); - struct tcp_fastopen_cookie foc = { .len = -1 }; - int saved_clamp = tp->rx_opt.mss_clamp; -+ struct mptcp_options_received mopt; - bool fastopen_fail; - -- tcp_parse_options(sock_net(sk), skb, &tp->rx_opt, 0, &foc); -+ mptcp_init_mp_opt(&mopt); -+ -+ tcp_parse_options(sock_net(sk), skb, &tp->rx_opt, -+ mptcp(tp) ? &tp->mptcp->rx_opt : &mopt, 0, &foc, tp); - if (tp->rx_opt.saw_tstamp && tp->rx_opt.rcv_tsecr) - tp->rx_opt.rcv_tsecr -= tp->tsoffset; - -@@ -5744,6 +5846,35 @@ - tcp_init_wl(tp, TCP_SKB_CB(skb)->seq); - tcp_ack(sk, skb, FLAG_SLOWPATH); - -+ if (tp->request_mptcp || mptcp(tp)) { -+ int ret; -+ -+ rcu_read_lock(); -+ local_bh_disable(); -+ ret = mptcp_rcv_synsent_state_process(sk, &sk, -+ skb, &mopt); -+ local_bh_enable(); -+ rcu_read_unlock(); -+ -+ /* May have changed if we support MPTCP */ -+ tp = tcp_sk(sk); -+ icsk = inet_csk(sk); -+ -+ if (ret == 1) -+ goto reset_and_undo; -+ if (ret == 2) -+ goto discard; -+ } -+ -+ if (mptcp(tp) && !is_master_tp(tp)) { -+ /* Timer for repeating the ACK until an answer -+ * arrives. Used only when establishing an additional -+ * subflow inside of an MPTCP connection. -+ */ -+ sk_reset_timer(sk, &tp->mptcp->mptcp_ack_timer, -+ jiffies + icsk->icsk_rto); -+ } -+ - /* Ok.. it's good. Set up sequence numbers and - * move to established. - */ -@@ -5770,6 +5901,11 @@ - tp->tcp_header_len = sizeof(struct tcphdr); - } - -+ if (mptcp(tp)) { -+ tp->tcp_header_len += MPTCP_SUB_LEN_DSM_ALIGN; -+ tp->advmss -= MPTCP_SUB_LEN_DSM_ALIGN; -+ } -+ - if (tcp_is_sack(tp) && sysctl_tcp_fack) - tcp_enable_fack(tp); - -@@ -5795,9 +5931,12 @@ - } - if (fastopen_fail) - return -1; -- if (sk->sk_write_pending || -+ /* With MPTCP we cannot send data on the third ack due to the -+ * lack of option-space to combine with an MP_CAPABLE. -+ */ -+ if (!mptcp(tp) && (sk->sk_write_pending || - icsk->icsk_accept_queue.rskq_defer_accept || -- icsk->icsk_ack.pingpong) { -+ icsk->icsk_ack.pingpong)) { - /* Save one ACK. Data will be ready after - * several ticks, if write_pending is set. - * -@@ -5836,6 +5975,7 @@ - tcp_paws_reject(&tp->rx_opt, 0)) - goto discard_and_undo; - -+ /* TODO - check this here for MPTCP */ - if (th->syn) { - /* We see SYN without ACK. It is attempt of - * simultaneous connect with crossed SYNs. -@@ -5852,6 +5992,11 @@ - tp->tcp_header_len = sizeof(struct tcphdr); - } - -+ if (mptcp(tp)) { -+ tp->tcp_header_len += MPTCP_SUB_LEN_DSM_ALIGN; -+ tp->advmss -= MPTCP_SUB_LEN_DSM_ALIGN; -+ } -+ - tp->rcv_nxt = TCP_SKB_CB(skb)->seq + 1; - tp->copied_seq = tp->rcv_nxt; - tp->rcv_wup = TCP_SKB_CB(skb)->seq + 1; -@@ -5910,6 +6055,7 @@ - */ - - int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb) -+ __releases(&sk->sk_lock.slock) - { - struct tcp_sock *tp = tcp_sk(sk); - struct inet_connection_sock *icsk = inet_csk(sk); -@@ -5952,6 +6098,16 @@ - tp->rx_opt.saw_tstamp = 0; - tcp_mstamp_refresh(tp); - queued = tcp_rcv_synsent_state_process(sk, skb, th); -+ if (is_meta_sk(sk)) { -+ sk = tcp_sk(sk)->mpcb->master_sk; -+ tp = tcp_sk(sk); -+ -+ /* Need to call it here, because it will announce new -+ * addresses, which can only be done after the third ack -+ * of the 3-way handshake. -+ */ -+ mptcp_update_metasocket(tp->meta_sk); -+ } - if (queued >= 0) - return queued; - -@@ -6009,7 +6165,7 @@ - - tcp_mtup_init(sk); - tp->copied_seq = tp->rcv_nxt; -- tcp_init_buffer_space(sk); -+ tp->ops->init_buffer_space(sk); - } - smp_mb(); - tcp_set_state(sk, TCP_ESTABLISHED); -@@ -6028,6 +6184,8 @@ - - if (tp->rx_opt.tstamp_ok) - tp->advmss -= TCPOLEN_TSTAMP_ALIGNED; -+ if (mptcp(tp)) -+ tp->advmss -= MPTCP_SUB_LEN_DSM_ALIGN; - - if (req) { - /* Re-arm the timer because data may have been sent out. -@@ -6050,6 +6208,30 @@ - - tcp_initialize_rcv_mss(sk); - tcp_fast_path_on(tp); -+ -+ /* Send an ACK when establishing a new MPTCP subflow, i.e. -+ * using an MP_JOIN subtype. -+ */ -+ if (mptcp(tp)) { -+ if (is_master_tp(tp)) { -+ mptcp_update_metasocket(mptcp_meta_sk(sk)); -+ } else { -+ struct sock *meta_sk = mptcp_meta_sk(sk); -+ -+ tcp_send_ack(sk); -+ -+ /* Update RTO as it might be worse/better */ -+ mptcp_set_rto(sk); -+ -+ /* If the new RTO would fire earlier, pull it in! */ -+ if (tcp_sk(meta_sk)->packets_out && -+ icsk->icsk_timeout > inet_csk(meta_sk)->icsk_rto + jiffies) { -+ tcp_rearm_rto(meta_sk); -+ } -+ -+ mptcp_push_pending_frames(mptcp_meta_sk(sk)); -+ } -+ } - break; - - case TCP_FIN_WAIT1: { -@@ -6097,7 +6279,8 @@ - tmo = tcp_fin_time(sk); - if (tmo > TCP_TIMEWAIT_LEN) { - inet_csk_reset_keepalive_timer(sk, tmo - TCP_TIMEWAIT_LEN); -- } else if (th->fin || sock_owned_by_user(sk)) { -+ } else if (th->fin || mptcp_is_data_fin(skb) || -+ sock_owned_by_user(sk)) { - /* Bad case. We could lose such FIN otherwise. - * It is not a big problem, but it looks confusing - * and not so rare event. We still can lose it now, -@@ -6106,7 +6289,7 @@ - */ - inet_csk_reset_keepalive_timer(sk, tmo); - } else { -- tcp_time_wait(sk, TCP_FIN_WAIT2, tmo); -+ tp->ops->time_wait(sk, TCP_FIN_WAIT2, tmo); - goto discard; - } - break; -@@ -6114,7 +6297,7 @@ - - case TCP_CLOSING: - if (tp->snd_una == tp->write_seq) { -- tcp_time_wait(sk, TCP_TIME_WAIT, 0); -+ tp->ops->time_wait(sk, TCP_TIME_WAIT, 0); - goto discard; - } - break; -@@ -6126,6 +6309,9 @@ - goto discard; - } - break; -+ case TCP_CLOSE: -+ if (tp->mp_killed) -+ goto discard; - } - - /* step 6: check the URG bit */ -@@ -6146,7 +6332,8 @@ - */ - if (sk->sk_shutdown & RCV_SHUTDOWN) { - if (TCP_SKB_CB(skb)->end_seq != TCP_SKB_CB(skb)->seq && -- after(TCP_SKB_CB(skb)->end_seq - th->fin, tp->rcv_nxt)) { -+ after(TCP_SKB_CB(skb)->end_seq - th->fin, tp->rcv_nxt) && -+ !mptcp(tp)) { - NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPABORTONDATA); - tcp_reset(sk); - return 1; -@@ -6243,6 +6430,8 @@ - ireq->wscale_ok = rx_opt->wscale_ok; - ireq->acked = 0; - ireq->ecn_ok = 0; -+ ireq->mptcp_rqsk = 0; -+ ireq->saw_mpc = 0; - ireq->ir_rmt_port = tcp_hdr(skb)->source; - ireq->ir_num = ntohs(tcp_hdr(skb)->dest); - ireq->ir_mark = inet_request_mark(sk, skb); -@@ -6337,12 +6526,17 @@ - /* TW buckets are converted to open requests without - * limitations, they conserve resources and peer is - * evidently real one. -+ * -+ * MPTCP: new subflows cannot be established in a stateless manner. - */ -- if ((net->ipv4.sysctl_tcp_syncookies == 2 || -+ if (((!is_meta_sk(sk) && net->ipv4.sysctl_tcp_syncookies == 2) || - inet_csk_reqsk_queue_is_full(sk)) && !isn) { - want_cookie = tcp_syn_flood_action(sk, skb, rsk_ops->slab_name); - if (!want_cookie) - goto drop; -+ -+ if (is_meta_sk(sk)) -+ goto drop; - } - - if (sk_acceptq_is_full(sk)) { -@@ -6360,8 +6554,8 @@ - tcp_clear_options(&tmp_opt); - tmp_opt.mss_clamp = af_ops->mss_clamp; - tmp_opt.user_mss = tp->rx_opt.user_mss; -- tcp_parse_options(sock_net(sk), skb, &tmp_opt, 0, -- want_cookie ? NULL : &foc); -+ tcp_parse_options(sock_net(sk), skb, &tmp_opt, NULL, 0, -+ want_cookie ? NULL : &foc, NULL); - - if (want_cookie && !tmp_opt.saw_tstamp) - tcp_clear_options(&tmp_opt); -@@ -6373,7 +6567,8 @@ - /* Note: tcp_v6_init_req() might override ir_iif for link locals */ - inet_rsk(req)->ir_iif = inet_request_bound_dev_if(sk, skb); - -- af_ops->init_req(req, sk, skb); -+ if (af_ops->init_req(req, sk, skb, want_cookie)) -+ goto drop_and_free; - - if (security_inet_conn_request(sk, skb, req)) - goto drop_and_free; -@@ -6409,7 +6604,7 @@ - tcp_ecn_create_request(req, skb, sk, dst); - - if (want_cookie) { -- isn = cookie_init_sequence(af_ops, sk, skb, &req->mss); -+ isn = cookie_init_sequence(af_ops, req, sk, skb, &req->mss); - req->cookie_ts = tmp_opt.tstamp_ok; - if (!tmp_opt.tstamp_ok) - inet_rsk(req)->ecn_ok = 0; -@@ -6423,18 +6618,26 @@ - fastopen_sk = tcp_try_fastopen(sk, skb, req, &foc); - } - if (fastopen_sk) { -+ struct sock *meta_sk = fastopen_sk; -+ -+ if (mptcp(tcp_sk(fastopen_sk))) -+ meta_sk = mptcp_meta_sk(fastopen_sk); - af_ops->send_synack(fastopen_sk, dst, &fl, req, - &foc, TCP_SYNACK_FASTOPEN); - /* Add the child socket directly into the accept queue */ -- if (!inet_csk_reqsk_queue_add(sk, req, fastopen_sk)) { -+ if (!inet_csk_reqsk_queue_add(sk, req, meta_sk)) { - reqsk_fastopen_remove(fastopen_sk, req, false); - bh_unlock_sock(fastopen_sk); -+ if (meta_sk != fastopen_sk) -+ bh_unlock_sock(meta_sk); - sock_put(fastopen_sk); - reqsk_put(req); - goto drop; - } - sk->sk_data_ready(sk); - bh_unlock_sock(fastopen_sk); -+ if (meta_sk != fastopen_sk) -+ bh_unlock_sock(meta_sk); - sock_put(fastopen_sk); - } else { - tcp_rsk(req)->tfo_listener = false; -diff -aurN linux-4.14.174/net/ipv4/tcp_ipv4.c mptcp-mptcp_v0.94/net/ipv4/tcp_ipv4.c ---- linux-4.14.174/net/ipv4/tcp_ipv4.c 2020-03-20 10:54:27.000000000 +0100 -+++ mptcp-mptcp_v0.94/net/ipv4/tcp_ipv4.c 2020-03-23 09:45:33.000000000 +0100 -@@ -67,6 +67,8 @@ - #include - #include - #include -+#include -+#include - #include - #include - #include -@@ -372,7 +374,7 @@ - struct inet_sock *inet; - const int type = icmp_hdr(icmp_skb)->type; - const int code = icmp_hdr(icmp_skb)->code; -- struct sock *sk; -+ struct sock *sk, *meta_sk; - struct sk_buff *skb; - struct request_sock *fastopen; - u32 seq, snd_una; -@@ -401,13 +403,19 @@ - (code == ICMP_NET_UNREACH || - code == ICMP_HOST_UNREACH))); - -- bh_lock_sock(sk); -+ tp = tcp_sk(sk); -+ if (mptcp(tp)) -+ meta_sk = mptcp_meta_sk(sk); -+ else -+ meta_sk = sk; -+ -+ bh_lock_sock(meta_sk); - /* If too many ICMPs get dropped on busy - * servers this needs to be solved differently. - * We do take care of PMTU discovery (RFC1191) special case : - * we can receive locally generated ICMP messages while socket is held. - */ -- if (sock_owned_by_user(sk)) { -+ if (sock_owned_by_user(meta_sk)) { - if (!(type == ICMP_DEST_UNREACH && code == ICMP_FRAG_NEEDED)) - __NET_INC_STATS(net, LINUX_MIB_LOCKDROPPEDICMPS); - } -@@ -420,7 +428,6 @@ - } - - icsk = inet_csk(sk); -- tp = tcp_sk(sk); - /* XXX (TFO) - tp->snd_una should be ISN (tcp_create_openreq_child() */ - fastopen = tp->fastopen_rsk; - snd_una = fastopen ? tcp_rsk(fastopen)->snt_isn : tp->snd_una; -@@ -454,11 +461,13 @@ - goto out; - - tp->mtu_info = info; -- if (!sock_owned_by_user(sk)) { -+ if (!sock_owned_by_user(meta_sk)) { - tcp_v4_mtu_reduced(sk); - } else { - if (!test_and_set_bit(TCP_MTU_REDUCED_DEFERRED, &sk->sk_tsq_flags)) - sock_hold(sk); -+ if (mptcp(tp)) -+ mptcp_tsq_flags(sk); - } - goto out; - } -@@ -472,7 +481,7 @@ - !icsk->icsk_backoff || fastopen) - break; - -- if (sock_owned_by_user(sk)) -+ if (sock_owned_by_user(meta_sk)) - break; - - skb = tcp_write_queue_head(sk); -@@ -495,7 +504,7 @@ - } else { - /* RTO revert clocked out retransmission. - * Will retransmit now */ -- tcp_retransmit_timer(sk); -+ tcp_sk(sk)->ops->retransmit_timer(sk); - } - - break; -@@ -515,7 +524,7 @@ - if (fastopen && !fastopen->sk) - break; - -- if (!sock_owned_by_user(sk)) { -+ if (!sock_owned_by_user(meta_sk)) { - sk->sk_err = err; - - sk->sk_error_report(sk); -@@ -544,7 +553,7 @@ - */ - - inet = inet_sk(sk); -- if (!sock_owned_by_user(sk) && inet->recverr) { -+ if (!sock_owned_by_user(meta_sk) && inet->recverr) { - sk->sk_err = err; - sk->sk_error_report(sk); - } else { /* Only an error on timeout */ -@@ -552,7 +561,7 @@ - } - - out: -- bh_unlock_sock(sk); -+ bh_unlock_sock(meta_sk); - sock_put(sk); - } - -@@ -594,7 +603,7 @@ - * Exception: precedence violation. We do not implement it in any case. - */ - --static void tcp_v4_send_reset(const struct sock *sk, struct sk_buff *skb) -+void tcp_v4_send_reset(const struct sock *sk, struct sk_buff *skb) - { - const struct tcphdr *th = tcp_hdr(skb); - struct { -@@ -731,10 +740,10 @@ - */ - - static void tcp_v4_send_ack(const struct sock *sk, -- struct sk_buff *skb, u32 seq, u32 ack, -+ struct sk_buff *skb, u32 seq, u32 ack, u32 data_ack, - u32 win, u32 tsval, u32 tsecr, int oif, - struct tcp_md5sig_key *key, -- int reply_flags, u8 tos) -+ int reply_flags, u8 tos, int mptcp) - { - const struct tcphdr *th = tcp_hdr(skb); - struct { -@@ -743,6 +752,10 @@ - #ifdef CONFIG_TCP_MD5SIG - + (TCPOLEN_MD5SIG_ALIGNED >> 2) - #endif -+#ifdef CONFIG_MPTCP -+ + ((MPTCP_SUB_LEN_DSS >> 2) + -+ (MPTCP_SUB_LEN_ACK >> 2)) -+#endif - ]; - } rep; - struct net *net = sock_net(sk); -@@ -787,6 +800,21 @@ - ip_hdr(skb)->daddr, &rep.th); - } - #endif -+#ifdef CONFIG_MPTCP -+ if (mptcp) { -+ int offset = (tsecr) ? 3 : 0; -+ /* Construction of 32-bit data_ack */ -+ rep.opt[offset++] = htonl((TCPOPT_MPTCP << 24) | -+ ((MPTCP_SUB_LEN_DSS + MPTCP_SUB_LEN_ACK) << 16) | -+ (0x20 << 8) | -+ (0x01)); -+ rep.opt[offset] = htonl(data_ack); -+ -+ arg.iov[0].iov_len += MPTCP_SUB_LEN_DSS + MPTCP_SUB_LEN_ACK; -+ rep.th.doff = arg.iov[0].iov_len / 4; -+ } -+#endif /* CONFIG_MPTCP */ -+ - arg.flags = reply_flags; - arg.csum = csum_tcpudp_nofold(ip_hdr(skb)->daddr, - ip_hdr(skb)->saddr, /* XXX */ -@@ -810,28 +838,36 @@ - { - struct inet_timewait_sock *tw = inet_twsk(sk); - struct tcp_timewait_sock *tcptw = tcp_twsk(sk); -+ u32 data_ack = 0; -+ int mptcp = 0; -+ -+ if (tcptw->mptcp_tw) { -+ data_ack = (u32)tcptw->mptcp_tw->rcv_nxt; -+ mptcp = 1; -+ } - - tcp_v4_send_ack(sk, skb, -- tcptw->tw_snd_nxt, tcptw->tw_rcv_nxt, -+ tcptw->tw_snd_nxt, tcptw->tw_rcv_nxt, data_ack, - tcptw->tw_rcv_wnd >> tw->tw_rcv_wscale, - tcp_time_stamp_raw() + tcptw->tw_ts_offset, - tcptw->tw_ts_recent, - tw->tw_bound_dev_if, - tcp_twsk_md5_key(tcptw), - tw->tw_transparent ? IP_REPLY_ARG_NOSRCCHECK : 0, -- tw->tw_tos -+ tw->tw_tos, mptcp - ); - - inet_twsk_put(tw); - } - --static void tcp_v4_reqsk_send_ack(const struct sock *sk, struct sk_buff *skb, -- struct request_sock *req) -+void tcp_v4_reqsk_send_ack(const struct sock *sk, struct sk_buff *skb, -+ struct request_sock *req) - { - /* sk->sk_state == TCP_LISTEN -> for regular TCP_SYN_RECV - * sk->sk_state == TCP_SYN_RECV -> for Fast Open. - */ -- u32 seq = (sk->sk_state == TCP_LISTEN) ? tcp_rsk(req)->snt_isn + 1 : -+ u32 seq = (sk->sk_state == TCP_LISTEN || is_meta_sk(sk)) ? -+ tcp_rsk(req)->snt_isn + 1 : - tcp_sk(sk)->snd_nxt; - - /* RFC 7323 2.3 -@@ -840,7 +876,7 @@ - * Rcv.Wind.Shift bits: - */ - tcp_v4_send_ack(sk, skb, seq, -- tcp_rsk(req)->rcv_nxt, -+ tcp_rsk(req)->rcv_nxt, 0, - req->rsk_rcv_wnd >> inet_rsk(req)->rcv_wscale, - tcp_time_stamp_raw() + tcp_rsk(req)->ts_off, - req->ts_recent, -@@ -848,7 +884,7 @@ - tcp_md5_do_lookup(sk, (union tcp_md5_addr *)&ip_hdr(skb)->saddr, - AF_INET), - inet_rsk(req)->no_srccheck ? IP_REPLY_ARG_NOSRCCHECK : 0, -- ip_hdr(skb)->tos); -+ ip_hdr(skb)->tos, 0); - } - - /* -@@ -856,11 +892,11 @@ - * This still operates on a request_sock only, not on a big - * socket. - */ --static int tcp_v4_send_synack(const struct sock *sk, struct dst_entry *dst, -- struct flowi *fl, -- struct request_sock *req, -- struct tcp_fastopen_cookie *foc, -- enum tcp_synack_type synack_type) -+int tcp_v4_send_synack(const struct sock *sk, struct dst_entry *dst, -+ struct flowi *fl, -+ struct request_sock *req, -+ struct tcp_fastopen_cookie *foc, -+ enum tcp_synack_type synack_type) - { - const struct inet_request_sock *ireq = inet_rsk(req); - struct flowi4 fl4; -@@ -890,7 +926,7 @@ - /* - * IPv4 request_sock destructor. - */ --static void tcp_v4_reqsk_destructor(struct request_sock *req) -+void tcp_v4_reqsk_destructor(struct request_sock *req) - { - kfree(rcu_dereference_protected(inet_rsk(req)->ireq_opt, 1)); - } -@@ -1263,9 +1299,10 @@ - return false; - } - --static void tcp_v4_init_req(struct request_sock *req, -- const struct sock *sk_listener, -- struct sk_buff *skb) -+static int tcp_v4_init_req(struct request_sock *req, -+ const struct sock *sk_listener, -+ struct sk_buff *skb, -+ bool want_cookie) - { - struct inet_request_sock *ireq = inet_rsk(req); - struct net *net = sock_net(sk_listener); -@@ -1273,6 +1310,8 @@ - sk_rcv_saddr_set(req_to_sk(req), ip_hdr(skb)->daddr); - sk_daddr_set(req_to_sk(req), ip_hdr(skb)->saddr); - RCU_INIT_POINTER(ireq->ireq_opt, tcp_v4_save_options(net, skb)); -+ -+ return 0; - } - - static struct dst_entry *tcp_v4_route_req(const struct sock *sk, -@@ -1292,7 +1331,7 @@ - .syn_ack_timeout = tcp_syn_ack_timeout, - }; - --static const struct tcp_request_sock_ops tcp_request_sock_ipv4_ops = { -+const struct tcp_request_sock_ops tcp_request_sock_ipv4_ops = { - .mss_clamp = TCP_MSS_DEFAULT, - #ifdef CONFIG_TCP_MD5SIG - .req_md5_lookup = tcp_v4_md5_lookup, -@@ -1429,7 +1468,7 @@ - } - EXPORT_SYMBOL(tcp_v4_syn_recv_sock); - --static struct sock *tcp_v4_cookie_check(struct sock *sk, struct sk_buff *skb) -+struct sock *tcp_v4_cookie_check(struct sock *sk, struct sk_buff *skb) - { - #ifdef CONFIG_SYN_COOKIES - const struct tcphdr *th = tcp_hdr(skb); -@@ -1452,6 +1491,9 @@ - { - struct sock *rsk; - -+ if (is_meta_sk(sk)) -+ return mptcp_v4_do_rcv(sk, skb); -+ - if (sk->sk_state == TCP_ESTABLISHED) { /* Fast path */ - struct dst_entry *dst = sk->sk_rx_dst; - -@@ -1603,6 +1645,10 @@ - TCP_SKB_CB(skb)->end_seq = (TCP_SKB_CB(skb)->seq + th->syn + th->fin + - skb->len - th->doff * 4); - TCP_SKB_CB(skb)->ack_seq = ntohl(th->ack_seq); -+#ifdef CONFIG_MPTCP -+ TCP_SKB_CB(skb)->mptcp_flags = 0; -+ TCP_SKB_CB(skb)->dss_off = 0; -+#endif - TCP_SKB_CB(skb)->tcp_flags = tcp_flag_byte(th); - TCP_SKB_CB(skb)->tcp_tw_isn = 0; - TCP_SKB_CB(skb)->ip_dsfield = ipv4_get_dsfield(iph); -@@ -1621,8 +1667,8 @@ - int sdif = inet_sdif(skb); - const struct iphdr *iph; - const struct tcphdr *th; -+ struct sock *sk, *meta_sk = NULL; - bool refcounted; -- struct sock *sk; - int ret; - - if (skb->pkt_type != PACKET_HOST) -@@ -1675,7 +1721,7 @@ - reqsk_put(req); - goto csum_error; - } -- if (unlikely(sk->sk_state != TCP_LISTEN)) { -+ if (unlikely(sk->sk_state != TCP_LISTEN && !is_meta_sk(sk))) { - inet_csk_reqsk_queue_drop_and_put(sk, req); - goto lookup; - } -@@ -1684,6 +1730,36 @@ - */ - sock_hold(sk); - refcounted = true; -+ -+ if (is_meta_sk(sk)) { -+ bh_lock_sock(sk); -+ -+ if (!mptcp_can_new_subflow(sk)) { -+ inet_csk_reqsk_queue_drop_and_put(sk, req); -+ bh_unlock_sock(sk); -+ -+ goto discard_and_relse; -+ } -+ -+ if (sock_owned_by_user(sk)) { -+ mptcp_prepare_for_backlog(sk, skb); -+ if (unlikely(sk_add_backlog(sk, skb, -+ sk->sk_rcvbuf + sk->sk_sndbuf))) { -+ reqsk_put(req); -+ -+ bh_unlock_sock(sk); -+ __NET_INC_STATS(net, LINUX_MIB_TCPBACKLOGDROP); -+ goto discard_and_relse; -+ } -+ -+ reqsk_put(req); -+ bh_unlock_sock(sk); -+ sock_put(sk); -+ -+ return 0; -+ } -+ } -+ - nsk = NULL; - if (!tcp_filter(sk, skb)) { - th = (const struct tcphdr *)skb->data; -@@ -1693,11 +1769,15 @@ - } - if (!nsk) { - reqsk_put(req); -+ if (is_meta_sk(sk)) -+ bh_unlock_sock(sk); - goto discard_and_relse; - } - if (nsk == sk) { - reqsk_put(req); - tcp_v4_restore_cb(skb); -+ if (is_meta_sk(sk)) -+ bh_unlock_sock(sk); - } else if (tcp_child_process(sk, nsk, skb)) { - tcp_v4_send_reset(nsk, skb); - goto discard_and_relse; -@@ -1734,15 +1814,24 @@ - - sk_incoming_cpu_update(sk); - -- bh_lock_sock_nested(sk); -+ if (mptcp(tcp_sk(sk))) { -+ meta_sk = mptcp_meta_sk(sk); -+ -+ bh_lock_sock_nested(meta_sk); -+ if (sock_owned_by_user(meta_sk)) -+ mptcp_prepare_for_backlog(sk, skb); -+ } else { -+ meta_sk = sk; -+ bh_lock_sock_nested(sk); -+ } - tcp_segs_in(tcp_sk(sk), skb); - ret = 0; -- if (!sock_owned_by_user(sk)) { -+ if (!sock_owned_by_user(meta_sk)) { - ret = tcp_v4_do_rcv(sk, skb); -- } else if (tcp_add_backlog(sk, skb)) { -+ } else if (tcp_add_backlog(meta_sk, skb)) { - goto discard_and_relse; - } -- bh_unlock_sock(sk); -+ bh_unlock_sock(meta_sk); - - put_and_return: - if (refcounted) -@@ -1756,6 +1845,19 @@ - - tcp_v4_fill_cb(skb, iph, th); - -+#ifdef CONFIG_MPTCP -+ if (!sk && th->syn && !th->ack) { -+ int ret = mptcp_lookup_join(skb, NULL); -+ -+ if (ret < 0) { -+ tcp_v4_send_reset(NULL, skb); -+ goto discard_it; -+ } else if (ret > 0) { -+ return 0; -+ } -+ } -+#endif -+ - if (tcp_checksum_complete(skb)) { - csum_error: - __TCP_INC_STATS(net, TCP_MIB_CSUMERRORS); -@@ -1804,6 +1906,18 @@ - refcounted = false; - goto process; - } -+#ifdef CONFIG_MPTCP -+ if (th->syn && !th->ack) { -+ int ret = mptcp_lookup_join(skb, inet_twsk(sk)); -+ -+ if (ret < 0) { -+ tcp_v4_send_reset(NULL, skb); -+ goto discard_it; -+ } else if (ret > 0) { -+ return 0; -+ } -+ } -+#endif - /* Fall through to ACK */ - } - case TCP_TW_ACK: -@@ -1872,7 +1986,12 @@ - - tcp_init_sock(sk); - -- icsk->icsk_af_ops = &ipv4_specific; -+#ifdef CONFIG_MPTCP -+ if (sock_flag(sk, SOCK_MPTCP)) -+ icsk->icsk_af_ops = &mptcp_v4_specific; -+ else -+#endif -+ icsk->icsk_af_ops = &ipv4_specific; - - #ifdef CONFIG_TCP_MD5SIG - tcp_sk(sk)->af_specific = &tcp_sock_ipv4_specific; -@@ -1889,6 +2008,11 @@ - - tcp_cleanup_congestion_control(sk); - -+ if (mptcp(tp)) -+ mptcp_destroy_sock(sk); -+ if (tp->inside_tk_table) -+ mptcp_hash_remove_bh(tp); -+ - tcp_cleanup_ulp(sk); - - /* Cleanup up the write buffer. */ -@@ -2437,6 +2561,9 @@ - .compat_getsockopt = compat_tcp_getsockopt, - #endif - .diag_destroy = tcp_abort, -+#ifdef CONFIG_MPTCP -+ .clear_sk = mptcp_clear_sk, -+#endif - }; - EXPORT_SYMBOL(tcp_prot); - -diff -aurN linux-4.14.174/net/ipv4/tcp_minisocks.c mptcp-mptcp_v0.94/net/ipv4/tcp_minisocks.c ---- linux-4.14.174/net/ipv4/tcp_minisocks.c 2020-03-20 10:54:27.000000000 +0100 -+++ mptcp-mptcp_v0.94/net/ipv4/tcp_minisocks.c 2020-03-23 09:45:33.000000000 +0100 -@@ -18,11 +18,13 @@ - * Jorge Cwik, - */ - -+#include - #include - #include - #include - #include - #include -+#include - #include - #include - #include -@@ -95,10 +97,14 @@ - struct tcp_options_received tmp_opt; - struct tcp_timewait_sock *tcptw = tcp_twsk((struct sock *)tw); - bool paws_reject = false; -+ struct mptcp_options_received mopt; - - tmp_opt.saw_tstamp = 0; -- if (th->doff > (sizeof(*th) >> 2) && tcptw->tw_ts_recent_stamp) { -- tcp_parse_options(twsk_net(tw), skb, &tmp_opt, 0, NULL); -+ if (th->doff > (sizeof(*th) >> 2) && -+ (tcptw->tw_ts_recent_stamp || tcptw->mptcp_tw)) { -+ mptcp_init_mp_opt(&mopt); -+ -+ tcp_parse_options(twsk_net(tw), skb, &tmp_opt, &mopt, 0, NULL, NULL); - - if (tmp_opt.saw_tstamp) { - if (tmp_opt.rcv_tsecr) -@@ -107,6 +113,11 @@ - tmp_opt.ts_recent_stamp = tcptw->tw_ts_recent_stamp; - paws_reject = tcp_paws_reject(&tmp_opt, th->rst); - } -+ -+ if (unlikely(mopt.mp_fclose) && tcptw->mptcp_tw) { -+ if (mopt.mptcp_sender_key == tcptw->mptcp_tw->loc_key) -+ return TCP_TW_RST; -+ } - } - - if (tw->tw_substate == TCP_FIN_WAIT2) { -@@ -130,6 +141,16 @@ - if (!th->ack || - !after(TCP_SKB_CB(skb)->end_seq, tcptw->tw_rcv_nxt) || - TCP_SKB_CB(skb)->end_seq == TCP_SKB_CB(skb)->seq) { -+ /* If mptcp_is_data_fin() returns true, we are sure that -+ * mopt has been initialized - otherwise it would not -+ * be a DATA_FIN. -+ */ -+ if (tcptw->mptcp_tw && tcptw->mptcp_tw->meta_tw && -+ mptcp_is_data_fin(skb) && -+ TCP_SKB_CB(skb)->seq == tcptw->tw_rcv_nxt && -+ mopt.data_seq + 1 == (u32)tcptw->mptcp_tw->rcv_nxt) -+ return TCP_TW_ACK; -+ - inet_twsk_put(tw); - return TCP_TW_SUCCESS; - } -@@ -274,6 +295,15 @@ - tcptw->tw_ts_offset = tp->tsoffset; - tcptw->tw_last_oow_ack_time = 0; - -+ if (mptcp(tp)) { -+ if (mptcp_init_tw_sock(sk, tcptw)) { -+ inet_twsk_free(tw); -+ goto exit; -+ } -+ } else { -+ tcptw->mptcp_tw = NULL; -+ } -+ - #if IS_ENABLED(CONFIG_IPV6) - if (tw->tw_family == PF_INET6) { - struct ipv6_pinfo *np = inet6_sk(sk); -@@ -331,15 +361,18 @@ - NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPTIMEWAITOVERFLOW); - } - -+exit: - tcp_update_metrics(sk); - tcp_done(sk); - } - - void tcp_twsk_destructor(struct sock *sk) - { --#ifdef CONFIG_TCP_MD5SIG - struct tcp_timewait_sock *twsk = tcp_twsk(sk); - -+ if (twsk->mptcp_tw) -+ mptcp_twsk_destructor(twsk); -+#ifdef CONFIG_TCP_MD5SIG - if (twsk->tw_md5_key) - kfree_rcu(twsk->tw_md5_key, rcu); - #endif -@@ -378,13 +411,14 @@ - full_space = rcv_wnd * mss; - - /* tcp_full_space because it is guaranteed to be the first packet */ -- tcp_select_initial_window(full_space, -- mss - (ireq->tstamp_ok ? TCPOLEN_TSTAMP_ALIGNED : 0), -+ tp->ops->select_initial_window(tcp_full_space(sk_listener), -+ mss - (ireq->tstamp_ok ? TCPOLEN_TSTAMP_ALIGNED : 0) - -+ (ireq->saw_mpc ? MPTCP_SUB_LEN_DSM_ALIGN : 0), - &req->rsk_rcv_wnd, - &req->rsk_window_clamp, - ireq->wscale_ok, - &rcv_wscale, -- rcv_wnd); -+ rcv_wnd, sk_listener); - ireq->rcv_wscale = rcv_wscale; - } - EXPORT_SYMBOL(tcp_openreq_init_rwin); -@@ -526,6 +560,8 @@ - newtp->rx_opt.ts_recent_stamp = 0; - newtp->tcp_header_len = sizeof(struct tcphdr); - } -+ if (ireq->saw_mpc) -+ newtp->tcp_header_len += MPTCP_SUB_LEN_DSM_ALIGN; - newtp->tsoffset = treq->ts_off; - #ifdef CONFIG_TCP_MD5SIG - newtp->md5sig_info = NULL; /*XXX*/ -@@ -541,6 +577,7 @@ - newtp->syn_data_acked = 0; - newtp->rack.mstamp = 0; - newtp->rack.advanced = 0; -+ newtp->inside_tk_table = 0; - - __TCP_INC_STATS(sock_net(sk), TCP_MIB_PASSIVEOPENS); - } -@@ -564,6 +601,7 @@ - bool fastopen) - { - struct tcp_options_received tmp_opt; -+ struct mptcp_options_received mopt; - struct sock *child; - const struct tcphdr *th = tcp_hdr(skb); - __be32 flg = tcp_flag_word(th) & (TCP_FLAG_RST|TCP_FLAG_SYN|TCP_FLAG_ACK); -@@ -571,8 +609,11 @@ - bool own_req; - - tmp_opt.saw_tstamp = 0; -+ -+ mptcp_init_mp_opt(&mopt); -+ - if (th->doff > (sizeof(struct tcphdr)>>2)) { -- tcp_parse_options(sock_net(sk), skb, &tmp_opt, 0, NULL); -+ tcp_parse_options(sock_net(sk), skb, &tmp_opt, &mopt, 0, NULL, NULL); - - if (tmp_opt.saw_tstamp) { - tmp_opt.ts_recent = req->ts_recent; -@@ -613,7 +654,14 @@ - * - * Reset timer after retransmitting SYNACK, similar to - * the idea of fast retransmit in recovery. -+ * -+ * Fall back to TCP if MP_CAPABLE is not set. - */ -+ -+ if (inet_rsk(req)->saw_mpc && !mopt.saw_mpc) -+ inet_rsk(req)->saw_mpc = false; -+ -+ - if (!tcp_oow_rate_limited(sock_net(sk), skb, - LINUX_MIB_TCPACKSKIPPEDSYNRECV, - &tcp_rsk(req)->last_oow_ack_time) && -@@ -766,6 +814,18 @@ - if (!child) - goto listen_overflow; - -+ if (own_req && !is_meta_sk(sk)) { -+ int ret = mptcp_check_req_master(sk, child, req, skb, 1, 0); -+ if (ret < 0) -+ goto listen_overflow; -+ -+ /* MPTCP-supported */ -+ if (!ret) -+ return tcp_sk(child)->mpcb->master_sk; -+ } else if (own_req) { -+ return mptcp_check_req_child(sk, child, req, skb, &mopt); -+ } -+ - sock_rps_save_rxhash(child, skb); - tcp_synack_rtt_meas(child, req); - return inet_csk_complete_hashdance(sk, child, req, own_req); -@@ -813,12 +873,13 @@ - { - int ret = 0; - int state = child->sk_state; -+ struct sock *meta_sk = mptcp(tcp_sk(child)) ? mptcp_meta_sk(child) : child; - - /* record NAPI ID of child */ - sk_mark_napi_id(child, skb); - - tcp_segs_in(tcp_sk(child), skb); -- if (!sock_owned_by_user(child)) { -+ if (!sock_owned_by_user(meta_sk)) { - ret = tcp_rcv_state_process(child, skb); - /* Wakeup parent, send SIGIO */ - if (state == TCP_SYN_RECV && child->sk_state != state) -@@ -828,10 +889,14 @@ - * in main socket hash table and lock on listening - * socket does not protect us more. - */ -- __sk_add_backlog(child, skb); -+ if (mptcp(tcp_sk(child))) -+ mptcp_prepare_for_backlog(child, skb); -+ __sk_add_backlog(meta_sk, skb); - } - -- bh_unlock_sock(child); -+ if (mptcp(tcp_sk(child))) -+ bh_unlock_sock(child); -+ bh_unlock_sock(meta_sk); - sock_put(child); - return ret; - } -diff -aurN linux-4.14.174/net/ipv4/tcp_output.c mptcp-mptcp_v0.94/net/ipv4/tcp_output.c ---- linux-4.14.174/net/ipv4/tcp_output.c 2020-03-20 10:54:27.000000000 +0100 -+++ mptcp-mptcp_v0.94/net/ipv4/tcp_output.c 2020-03-23 09:45:33.000000000 +0100 -@@ -36,6 +36,12 @@ - - #define pr_fmt(fmt) "TCP: " fmt - -+#include -+#include -+#if IS_ENABLED(CONFIG_IPV6) -+#include -+#endif -+#include - #include - - #include -@@ -62,11 +68,8 @@ - /* By default, RFC2861 behavior. */ - int sysctl_tcp_slow_start_after_idle __read_mostly = 1; - --static bool tcp_write_xmit(struct sock *sk, unsigned int mss_now, int nonagle, -- int push_one, gfp_t gfp); -- - /* Account for new data that has been sent to the network. */ --static void tcp_event_new_data_sent(struct sock *sk, const struct sk_buff *skb) -+void tcp_event_new_data_sent(struct sock *sk, const struct sk_buff *skb) - { - struct inet_connection_sock *icsk = inet_csk(sk); - struct tcp_sock *tp = tcp_sk(sk); -@@ -211,7 +214,7 @@ - void tcp_select_initial_window(int __space, __u32 mss, - __u32 *rcv_wnd, __u32 *window_clamp, - int wscale_ok, __u8 *rcv_wscale, -- __u32 init_rcv_wnd) -+ __u32 init_rcv_wnd, const struct sock *sk) - { - unsigned int space = (__space < 0 ? 0 : __space); - -@@ -265,12 +268,16 @@ - * value can be stuffed directly into th->window for an outgoing - * frame. - */ --static u16 tcp_select_window(struct sock *sk) -+u16 tcp_select_window(struct sock *sk) - { - struct tcp_sock *tp = tcp_sk(sk); - u32 old_win = tp->rcv_wnd; -- u32 cur_win = tcp_receive_window(tp); -- u32 new_win = __tcp_select_window(sk); -+ /* The window must never shrink at the meta-level. At the subflow we -+ * have to allow this. Otherwise we may announce a window too large -+ * for the current meta-level sk_rcvbuf. -+ */ -+ u32 cur_win = tcp_receive_window(mptcp(tp) ? tcp_sk(mptcp_meta_sk(sk)) : tp); -+ u32 new_win = tp->ops->__select_window(sk); - - /* Never shrink the offered window */ - if (new_win < cur_win) { -@@ -286,6 +293,7 @@ - LINUX_MIB_TCPWANTZEROWINDOWADV); - new_win = ALIGN(cur_win, 1 << tp->rx_opt.rcv_wscale); - } -+ - tp->rcv_wnd = new_win; - tp->rcv_wup = tp->rcv_nxt; - -@@ -397,7 +405,7 @@ - /* Constructs common control bits of non-data skb. If SYN/FIN is present, - * auto increment end seqno. - */ --static void tcp_init_nondata_skb(struct sk_buff *skb, u32 seq, u8 flags) -+void tcp_init_nondata_skb(struct sk_buff *skb, u32 seq, u8 flags) - { - skb->ip_summed = CHECKSUM_PARTIAL; - skb->csum = 0; -@@ -413,7 +421,7 @@ - TCP_SKB_CB(skb)->end_seq = seq; - } - --static inline bool tcp_urg_mode(const struct tcp_sock *tp) -+bool tcp_urg_mode(const struct tcp_sock *tp) - { - return tp->snd_una != tp->snd_up; - } -@@ -423,17 +431,7 @@ - #define OPTION_MD5 (1 << 2) - #define OPTION_WSCALE (1 << 3) - #define OPTION_FAST_OPEN_COOKIE (1 << 8) -- --struct tcp_out_options { -- u16 options; /* bit field of OPTION_* */ -- u16 mss; /* 0 to disable */ -- u8 ws; /* window scale, 0 to disable */ -- u8 num_sack_blocks; /* number of SACK blocks to include */ -- u8 hash_size; /* bytes in hash_location */ -- __u8 *hash_location; /* temporary pointer, overloaded */ -- __u32 tsval, tsecr; /* need to include OPTION_TS */ -- struct tcp_fastopen_cookie *fastopen_cookie; /* Fast open cookie */ --}; -+/* Before adding here - take a look at OPTION_MPTCP in include/net/mptcp.h */ - - /* Write previously computed TCP options to the packet. - * -@@ -449,7 +447,7 @@ - * (but it may well be that other scenarios fail similarly). - */ - static void tcp_options_write(__be32 *ptr, struct tcp_sock *tp, -- struct tcp_out_options *opts) -+ struct tcp_out_options *opts, struct sk_buff *skb) - { - u16 options = opts->options; /* mungable copy */ - -@@ -541,6 +539,9 @@ - } - ptr += (len + 3) >> 2; - } -+ -+ if (unlikely(OPTION_MPTCP & opts->options)) -+ mptcp_options_write(ptr, tp, opts, skb); - } - - /* Compute TCP options for SYN packets. This is not the final -@@ -592,6 +593,8 @@ - if (unlikely(!(OPTION_TS & opts->options))) - remaining -= TCPOLEN_SACKPERM_ALIGNED; - } -+ if (tp->request_mptcp || mptcp(tp)) -+ mptcp_syn_options(sk, opts, &remaining); - - if (fastopen && fastopen->cookie.len >= 0) { - u32 need = fastopen->cookie.len; -@@ -668,6 +671,9 @@ - } - } - -+ if (ireq->saw_mpc) -+ mptcp_synack_options(req, opts, &remaining); -+ - return MAX_TCP_OPTION_SPACE - remaining; - } - -@@ -700,6 +706,8 @@ - opts->tsecr = tp->rx_opt.ts_recent; - size += TCPOLEN_TSTAMP_ALIGNED; - } -+ if (mptcp(tp)) -+ mptcp_established_options(sk, skb, opts, &size); - - eff_sacks = tp->rx_opt.num_sacks + tp->rx_opt.dsack; - if (unlikely(eff_sacks)) { -@@ -750,8 +758,8 @@ - tcp_xmit_retransmit_queue(sk); - } - -- tcp_write_xmit(sk, tcp_current_mss(sk), tp->nonagle, -- 0, GFP_ATOMIC); -+ tcp_sk(sk)->ops->write_xmit(sk, tcp_current_mss(sk), -+ tcp_sk(sk)->nonagle, 0, GFP_ATOMIC); - } - } - /* -@@ -767,7 +775,7 @@ - unsigned long flags; - struct list_head *q, *n; - struct tcp_sock *tp; -- struct sock *sk; -+ struct sock *sk, *meta_sk; - - local_irq_save(flags); - list_splice_init(&tsq->head, &list); -@@ -781,14 +789,28 @@ - smp_mb__before_atomic(); - clear_bit(TSQ_QUEUED, &sk->sk_tsq_flags); - -- if (!sk->sk_lock.owned && -+ meta_sk = mptcp(tp) ? mptcp_meta_sk(sk) : sk; -+ -+ if (!meta_sk->sk_lock.owned && - test_bit(TCP_TSQ_DEFERRED, &sk->sk_tsq_flags)) { -- bh_lock_sock(sk); -- if (!sock_owned_by_user(sk)) { -+ bh_lock_sock(meta_sk); -+ if (!sock_owned_by_user(meta_sk)) { - clear_bit(TCP_TSQ_DEFERRED, &sk->sk_tsq_flags); - tcp_tsq_handler(sk); -+ if (mptcp(tp)) -+ tcp_tsq_handler(meta_sk); -+ } else if (mptcp(tp)) { -+ if (sk->sk_state != TCP_CLOSE) -+ mptcp_tsq_flags(sk); -+ } -+ bh_unlock_sock(meta_sk); -+ } else { -+ if (mptcp(tp)) { -+ bh_lock_sock(meta_sk); -+ if (sk->sk_state != TCP_CLOSE) -+ mptcp_tsq_flags(sk); -+ bh_unlock_sock(meta_sk); - } -- bh_unlock_sock(sk); - } - - sk_free(sk); -@@ -798,7 +820,9 @@ - #define TCP_DEFERRED_ALL (TCPF_TSQ_DEFERRED | \ - TCPF_WRITE_TIMER_DEFERRED | \ - TCPF_DELACK_TIMER_DEFERRED | \ -- TCPF_MTU_REDUCED_DEFERRED) -+ TCPF_MTU_REDUCED_DEFERRED | \ -+ TCPF_PATH_MANAGER_DEFERRED |\ -+ TCPF_SUB_DEFERRED) - /** - * tcp_release_cb - tcp release_sock() callback - * @sk: socket -@@ -818,8 +842,11 @@ - nflags = flags & ~TCP_DEFERRED_ALL; - } while (cmpxchg(&sk->sk_tsq_flags, flags, nflags) != flags); - -- if (flags & TCPF_TSQ_DEFERRED) -+ if (flags & TCPF_TSQ_DEFERRED) { - tcp_tsq_handler(sk); -+ if (mptcp(tcp_sk(sk))) -+ tcp_tsq_handler(mptcp_meta_sk(sk)); -+ } - - /* Here begins the tricky part : - * We are called from release_sock() with : -@@ -844,6 +871,13 @@ - inet_csk(sk)->icsk_af_ops->mtu_reduced(sk); - __sock_put(sk); - } -+ if (flags & TCPF_PATH_MANAGER_DEFERRED) { -+ if (tcp_sk(sk)->mpcb->pm_ops->release_sock) -+ tcp_sk(sk)->mpcb->pm_ops->release_sock(sk); -+ __sock_put(sk); -+ } -+ if (flags & TCPF_SUB_DEFERRED) -+ mptcp_tsq_sub_deferred(sk); - } - EXPORT_SYMBOL(tcp_release_cb); - -@@ -1081,10 +1115,10 @@ - } - } - -- tcp_options_write((__be32 *)(th + 1), tp, &opts); -+ tcp_options_write((__be32 *)(th + 1), tp, &opts, skb); - skb_shinfo(skb)->gso_type = sk->sk_gso_type; - if (likely(!(tcb->tcp_flags & TCPHDR_SYN))) { -- th->window = htons(tcp_select_window(sk)); -+ th->window = htons(tp->ops->select_window(sk)); - tcp_ecn_send(sk, skb, th, tcp_header_size); - } else { - /* RFC1323: The window in SYN & SYN/ACK segments -@@ -1141,8 +1175,8 @@ - return err; - } - --static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it, -- gfp_t gfp_mask) -+int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it, -+ gfp_t gfp_mask) - { - return __tcp_transmit_skb(sk, skb, clone_it, gfp_mask, - tcp_sk(sk)->rcv_nxt); -@@ -1153,7 +1187,7 @@ - * NOTE: probe0 timer is not checked, do not forget tcp_push_pending_frames, - * otherwise socket can stall. - */ --static void tcp_queue_skb(struct sock *sk, struct sk_buff *skb) -+void tcp_queue_skb(struct sock *sk, struct sk_buff *skb) - { - struct tcp_sock *tp = tcp_sk(sk); - -@@ -1166,7 +1200,7 @@ - } - - /* Initialize TSO segments for a packet. */ --static void tcp_set_skb_tso_segs(struct sk_buff *skb, unsigned int mss_now) -+void tcp_set_skb_tso_segs(struct sk_buff *skb, unsigned int mss_now) - { - if (skb->len <= mss_now || skb->ip_summed == CHECKSUM_NONE) { - /* Avoid the costly divide in the normal -@@ -1198,7 +1232,7 @@ - /* Pcount in the middle of the write queue got changed, we need to do various - * tweaks to fix counters - */ --static void tcp_adjust_pcount(struct sock *sk, const struct sk_buff *skb, int decr) -+void tcp_adjust_pcount(struct sock *sk, const struct sk_buff *skb, int decr) - { - struct tcp_sock *tp = tcp_sk(sk); - -@@ -1364,7 +1398,7 @@ - /* This is similar to __pskb_pull_tail(). The difference is that pulled - * data is not copied, but immediately discarded. - */ --static int __pskb_trim_head(struct sk_buff *skb, int len) -+int __pskb_trim_head(struct sk_buff *skb, int len) - { - struct skb_shared_info *shinfo; - int i, k, eat; -@@ -1586,6 +1620,7 @@ - - return mss_now; - } -+EXPORT_SYMBOL(tcp_current_mss); - - /* RFC2861, slow part. Adjust cwnd, after it was not full during one rto. - * As additional protections, we do not touch cwnd in retransmission phases, -@@ -1609,7 +1644,7 @@ - tp->snd_cwnd_stamp = tcp_jiffies32; - } - --static void tcp_cwnd_validate(struct sock *sk, bool is_cwnd_limited) -+void tcp_cwnd_validate(struct sock *sk, bool is_cwnd_limited) - { - const struct tcp_congestion_ops *ca_ops = inet_csk(sk)->icsk_ca_ops; - struct tcp_sock *tp = tcp_sk(sk); -@@ -1667,8 +1702,8 @@ - * But we can avoid doing the divide again given we already have - * skb_pcount = skb->len / mss_now - */ --static void tcp_minshall_update(struct tcp_sock *tp, unsigned int mss_now, -- const struct sk_buff *skb) -+void tcp_minshall_update(struct tcp_sock *tp, unsigned int mss_now, -+ const struct sk_buff *skb) - { - if (skb->len < tcp_skb_pcount(skb) * mss_now) - tp->snd_sml = TCP_SKB_CB(skb)->end_seq; -@@ -1726,11 +1761,11 @@ - } - - /* Returns the portion of skb which can be sent right away */ --static unsigned int tcp_mss_split_point(const struct sock *sk, -- const struct sk_buff *skb, -- unsigned int mss_now, -- unsigned int max_segs, -- int nonagle) -+unsigned int tcp_mss_split_point(const struct sock *sk, -+ const struct sk_buff *skb, -+ unsigned int mss_now, -+ unsigned int max_segs, -+ int nonagle) - { - const struct tcp_sock *tp = tcp_sk(sk); - u32 partial, needed, window, max_len; -@@ -1760,13 +1795,14 @@ - /* Can at least one segment of SKB be sent right now, according to the - * congestion window rules? If so, return how many segments are allowed. - */ --static inline unsigned int tcp_cwnd_test(const struct tcp_sock *tp, -- const struct sk_buff *skb) -+unsigned int tcp_cwnd_test(const struct tcp_sock *tp, -+ const struct sk_buff *skb) - { - u32 in_flight, cwnd, halfcwnd; - - /* Don't be strict about the congestion window for the final FIN. */ -- if ((TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN) && -+ if (skb && -+ (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN) && - tcp_skb_pcount(skb) == 1) - return 1; - -@@ -1786,7 +1822,7 @@ - * This must be invoked the first time we consider transmitting - * SKB onto the wire. - */ --static int tcp_init_tso_segs(struct sk_buff *skb, unsigned int mss_now) -+int tcp_init_tso_segs(struct sk_buff *skb, unsigned int mss_now) - { - int tso_segs = tcp_skb_pcount(skb); - -@@ -1801,8 +1837,8 @@ - /* Return true if the Nagle test allows this packet to be - * sent now. - */ --static inline bool tcp_nagle_test(const struct tcp_sock *tp, const struct sk_buff *skb, -- unsigned int cur_mss, int nonagle) -+bool tcp_nagle_test(const struct tcp_sock *tp, const struct sk_buff *skb, -+ unsigned int cur_mss, int nonagle) - { - /* Nagle rule does not apply to frames, which sit in the middle of the - * write_queue (they have no chances to get new data). -@@ -1814,7 +1850,8 @@ - return true; - - /* Don't use the nagle rule for urgent data (or for the final FIN). */ -- if (tcp_urg_mode(tp) || (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN)) -+ if (tcp_urg_mode(tp) || (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN) || -+ mptcp_is_data_fin(skb)) - return true; - - if (!tcp_nagle_check(skb->len < cur_mss, tp, nonagle)) -@@ -1824,9 +1861,8 @@ - } - - /* Does at least the first segment of SKB fit into the send window? */ --static bool tcp_snd_wnd_test(const struct tcp_sock *tp, -- const struct sk_buff *skb, -- unsigned int cur_mss) -+bool tcp_snd_wnd_test(const struct tcp_sock *tp, const struct sk_buff *skb, -+ unsigned int cur_mss) - { - u32 end_seq = TCP_SKB_CB(skb)->end_seq; - -@@ -1983,7 +2019,7 @@ - } - - /* If this packet won't get more data, do not wait. */ -- if (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN) -+ if ((TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN) || mptcp_is_data_fin(skb)) - goto send_now; - - return true; -@@ -2283,6 +2319,23 @@ - tcp_chrono_set(tp, TCP_CHRONO_BUSY); - } - -+void tcp_write_queue_purge(struct sock *sk) -+{ -+ struct sk_buff *skb; -+ -+ if (mptcp(tcp_sk(sk)) && !is_meta_sk(sk) && !tcp_write_queue_empty(sk)) -+ mptcp_reinject_data(sk, 0); -+ -+ tcp_chrono_stop(sk, TCP_CHRONO_BUSY); -+ while ((skb = __skb_dequeue(&sk->sk_write_queue)) != NULL) -+ sk_wmem_free_skb(sk, skb); -+ sk_mem_reclaim(sk); -+ tcp_clear_all_retrans_hints(tcp_sk(sk)); -+ tcp_init_send_head(sk); -+ tcp_sk(sk)->packets_out = 0; -+ inet_csk(sk)->icsk_backoff = 0; -+} -+ - /* This routine writes packets to the network. It advances the - * send_head. This happens as incoming acks open up the remote - * window for us. -@@ -2297,7 +2350,7 @@ - * Returns true, if no segments are in flight and we have queued segments, - * but cannot send anything now because of SWS or another problem. - */ --static bool tcp_write_xmit(struct sock *sk, unsigned int mss_now, int nonagle, -+bool tcp_write_xmit(struct sock *sk, unsigned int mss_now, int nonagle, - int push_one, gfp_t gfp) - { - struct tcp_sock *tp = tcp_sk(sk); -@@ -2311,7 +2364,12 @@ - sent_pkts = 0; - - tcp_mstamp_refresh(tp); -- if (!push_one) { -+ -+ /* pmtu not yet supported with MPTCP. Should be possible, by early -+ * exiting the loop inside tcp_mtu_probe, making sure that only one -+ * single DSS-mapping gets probed. -+ */ -+ if (!push_one && !mptcp(tp)) { - /* Do MTU probing. */ - result = tcp_mtu_probe(sk); - if (!result) { -@@ -2417,7 +2475,8 @@ - if (push_one != 2) - tcp_schedule_loss_probe(sk, false); - is_cwnd_limited |= (tcp_packets_in_flight(tp) >= tp->snd_cwnd); -- tcp_cwnd_validate(sk, is_cwnd_limited); -+ if (tp->ops->cwnd_validate) -+ tp->ops->cwnd_validate(sk, is_cwnd_limited); - return false; - } - return !tp->packets_out && tcp_send_head(sk); -@@ -2502,7 +2561,7 @@ - if (skb) { - if (tcp_snd_wnd_test(tp, skb, mss)) { - pcount = tp->packets_out; -- tcp_write_xmit(sk, mss, TCP_NAGLE_OFF, 2, GFP_ATOMIC); -+ tp->ops->write_xmit(sk, mss, TCP_NAGLE_OFF, 2, GFP_ATOMIC); - if (tp->packets_out > pcount) - goto probe_sent; - goto rearm_timer; -@@ -2569,8 +2628,8 @@ - if (unlikely(sk->sk_state == TCP_CLOSE)) - return; - -- if (tcp_write_xmit(sk, cur_mss, nonagle, 0, -- sk_gfp_mask(sk, GFP_ATOMIC))) -+ if (tcp_sk(sk)->ops->write_xmit(sk, cur_mss, nonagle, 0, -+ sk_gfp_mask(sk, GFP_ATOMIC))) - tcp_check_probe_timer(sk); - } - -@@ -2583,7 +2642,8 @@ - - BUG_ON(!skb || skb->len < mss_now); - -- tcp_write_xmit(sk, mss_now, TCP_NAGLE_PUSH, 1, sk->sk_allocation); -+ tcp_sk(sk)->ops->write_xmit(sk, mss_now, TCP_NAGLE_PUSH, 1, -+ sk->sk_allocation); - } - - /* This function returns the amount that we can raise the -@@ -2816,6 +2876,10 @@ - if (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_SYN) - return; - -+ /* Currently not supported for MPTCP - but it should be possible */ -+ if (mptcp(tp)) -+ return; -+ - tcp_for_write_queue_from_safe(skb, tmp, sk) { - if (!tcp_can_collapse(sk, skb)) - break; -@@ -3273,7 +3337,7 @@ - - /* RFC1323: The window in SYN & SYN/ACK segments is never scaled. */ - th->window = htons(min(req->rsk_rcv_wnd, 65535U)); -- tcp_options_write((__be32 *)(th + 1), NULL, &opts); -+ tcp_options_write((__be32 *)(th + 1), NULL, &opts, skb); - th->doff = (tcp_header_size >> 2); - __TCP_INC_STATS(sock_net(sk), TCP_MIB_OUTSEGS); - -@@ -3354,13 +3418,13 @@ - if (rcv_wnd == 0) - rcv_wnd = dst_metric(dst, RTAX_INITRWND); - -- tcp_select_initial_window(tcp_full_space(sk), -- tp->advmss - (tp->rx_opt.ts_recent_stamp ? tp->tcp_header_len - sizeof(struct tcphdr) : 0), -- &tp->rcv_wnd, -- &tp->window_clamp, -- sock_net(sk)->ipv4.sysctl_tcp_window_scaling, -- &rcv_wscale, -- rcv_wnd); -+ tp->ops->select_initial_window(tcp_full_space(sk), -+ tp->advmss - (tp->rx_opt.ts_recent_stamp ? tp->tcp_header_len - sizeof(struct tcphdr) : 0), -+ &tp->rcv_wnd, -+ &tp->window_clamp, -+ sock_net(sk)->ipv4.sysctl_tcp_window_scaling, -+ &rcv_wscale, -+ rcv_wnd, sk); - - tp->rx_opt.rcv_wscale = rcv_wscale; - tp->rcv_ssthresh = tp->rcv_wnd; -@@ -3385,6 +3449,36 @@ - inet_csk(sk)->icsk_rto = tcp_timeout_init(sk); - inet_csk(sk)->icsk_retransmits = 0; - tcp_clear_retrans(tp); -+ -+#ifdef CONFIG_MPTCP -+ if (sock_flag(sk, SOCK_MPTCP) && mptcp_doit(sk)) { -+ if (is_master_tp(tp)) { -+ tp->request_mptcp = 1; -+ mptcp_connect_init(sk); -+ } else if (tp->mptcp) { -+ struct inet_sock *inet = inet_sk(sk); -+ -+ tp->mptcp->snt_isn = tp->write_seq; -+ tp->mptcp->init_rcv_wnd = tp->rcv_wnd; -+ -+ /* Set nonce for new subflows */ -+ if (sk->sk_family == AF_INET) -+ tp->mptcp->mptcp_loc_nonce = mptcp_v4_get_nonce( -+ inet->inet_saddr, -+ inet->inet_daddr, -+ inet->inet_sport, -+ inet->inet_dport); -+#if IS_ENABLED(CONFIG_IPV6) -+ else -+ tp->mptcp->mptcp_loc_nonce = mptcp_v6_get_nonce( -+ inet6_sk(sk)->saddr.s6_addr32, -+ sk->sk_v6_daddr.s6_addr32, -+ inet->inet_sport, -+ inet->inet_dport); -+#endif -+ } -+ } -+#endif - } - - static void tcp_connect_queue_skb(struct sock *sk, struct sk_buff *skb) -@@ -3645,6 +3739,7 @@ - { - __tcp_send_ack(sk, tcp_sk(sk)->rcv_nxt); - } -+EXPORT_SYMBOL_GPL(tcp_send_ack); - - /* This routine sends a packet with an out of date sequence - * number. It assumes the other end will try to ack it. -@@ -3657,7 +3752,7 @@ - * one is with SEG.SEQ=SND.UNA to deliver urgent pointer, another is - * out-of-date with SND.UNA-1 to probe window. - */ --static int tcp_xmit_probe_skb(struct sock *sk, int urgent, int mib) -+int tcp_xmit_probe_skb(struct sock *sk, int urgent, int mib) - { - struct tcp_sock *tp = tcp_sk(sk); - struct sk_buff *skb; -@@ -3743,7 +3838,7 @@ - unsigned long probe_max; - int err; - -- err = tcp_write_wakeup(sk, LINUX_MIB_TCPWINPROBE); -+ err = tp->ops->write_wakeup(sk, LINUX_MIB_TCPWINPROBE); - - if (tp->packets_out || !tcp_send_head(sk)) { - /* Cancel probe timer, if it is not required. */ -diff -aurN linux-4.14.174/net/ipv4/tcp_timer.c mptcp-mptcp_v0.94/net/ipv4/tcp_timer.c ---- linux-4.14.174/net/ipv4/tcp_timer.c 2020-03-20 10:54:27.000000000 +0100 -+++ mptcp-mptcp_v0.94/net/ipv4/tcp_timer.c 2020-03-23 09:45:33.000000000 +0100 -@@ -20,6 +20,7 @@ - - #include - #include -+#include - #include - - int sysctl_tcp_thin_linear_timeouts __read_mostly; -@@ -31,7 +32,7 @@ - * Returns: Nothing (void) - */ - --static void tcp_write_err(struct sock *sk) -+void tcp_write_err(struct sock *sk) - { - sk->sk_err = sk->sk_err_soft ? : ETIMEDOUT; - sk->sk_error_report(sk); -@@ -87,7 +88,7 @@ - (!tp->snd_wnd && !tp->packets_out)) - do_reset = true; - if (do_reset) -- tcp_send_active_reset(sk, GFP_ATOMIC); -+ tp->ops->send_active_reset(sk, GFP_ATOMIC); - tcp_done(sk); - __NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPABORTONMEMORY); - return 1; -@@ -162,9 +163,9 @@ - * after "boundary" unsuccessful, exponentially backed-off - * retransmissions with an initial RTO of TCP_RTO_MIN. - */ --static bool retransmits_timed_out(struct sock *sk, -- unsigned int boundary, -- unsigned int timeout) -+bool retransmits_timed_out(struct sock *sk, -+ unsigned int boundary, -+ unsigned int timeout) - { - const unsigned int rto_base = TCP_RTO_MIN; - unsigned int linear_backoff_thresh, start_ts; -@@ -173,8 +174,14 @@ - return false; - - start_ts = tcp_sk(sk)->retrans_stamp; -- if (unlikely(!start_ts)) -- start_ts = tcp_skb_timestamp(tcp_write_queue_head(sk)); -+ if (unlikely(!start_ts)) { -+ struct sk_buff *skb = tcp_write_queue_head(sk); -+ -+ if (!skb) -+ return false; -+ -+ start_ts = tcp_skb_timestamp(skb); -+ } - - if (likely(timeout == 0)) { - linear_backoff_thresh = ilog2(TCP_RTO_MAX/rto_base); -@@ -189,7 +196,7 @@ - } - - /* A write timeout has occurred. Process the after effects. */ --static int tcp_write_timeout(struct sock *sk) -+int tcp_write_timeout(struct sock *sk) - { - struct inet_connection_sock *icsk = inet_csk(sk); - struct tcp_sock *tp = tcp_sk(sk); -@@ -209,6 +216,17 @@ - sk_rethink_txhash(sk); - } - retry_until = icsk->icsk_syn_retries ? : net->ipv4.sysctl_tcp_syn_retries; -+ -+#ifdef CONFIG_MPTCP -+ /* Stop retransmitting MP_CAPABLE options in SYN if timed out. */ -+ if (tcp_sk(sk)->request_mptcp && -+ icsk->icsk_retransmits >= sysctl_mptcp_syn_retries) { -+ tcp_sk(sk)->request_mptcp = 0; -+ -+ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_MPCAPABLERETRANSFALLBACK); -+ } -+#endif /* CONFIG_MPTCP */ -+ - expired = icsk->icsk_retransmits >= retry_until; - } else { - if (retransmits_timed_out(sk, net->ipv4.sysctl_tcp_retries1, 0)) { -@@ -304,18 +322,22 @@ - static void tcp_delack_timer(unsigned long data) - { - struct sock *sk = (struct sock *)data; -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct sock *meta_sk = mptcp(tp) ? mptcp_meta_sk(sk) : sk; - -- bh_lock_sock(sk); -- if (!sock_owned_by_user(sk)) { -+ bh_lock_sock(meta_sk); -+ if (!sock_owned_by_user(meta_sk)) { - tcp_delack_timer_handler(sk); - } else { - inet_csk(sk)->icsk_ack.blocked = 1; -- __NET_INC_STATS(sock_net(sk), LINUX_MIB_DELAYEDACKLOCKED); -+ __NET_INC_STATS(sock_net(meta_sk), LINUX_MIB_DELAYEDACKLOCKED); - /* deleguate our work to tcp_release_cb() */ - if (!test_and_set_bit(TCP_DELACK_TIMER_DEFERRED, &sk->sk_tsq_flags)) - sock_hold(sk); -+ if (mptcp(tp)) -+ mptcp_tsq_flags(sk); - } -- bh_unlock_sock(sk); -+ bh_unlock_sock(meta_sk); - sock_put(sk); - } - -@@ -360,6 +382,10 @@ - - if (icsk->icsk_probes_out >= max_probes) { - abort: tcp_write_err(sk); -+ if (is_meta_sk(sk) && -+ mptcp_in_infinite_mapping_weak(tp->mpcb)) { -+ mptcp_sub_force_close_all(tp->mpcb, NULL); -+ } - } else { - /* Only send another probe if we didn't close things up. */ - tcp_send_probe0(sk); -@@ -580,7 +606,7 @@ - break; - case ICSK_TIME_RETRANS: - icsk->icsk_pending = 0; -- tcp_retransmit_timer(sk); -+ tcp_sk(sk)->ops->retransmit_timer(sk); - break; - case ICSK_TIME_PROBE0: - icsk->icsk_pending = 0; -@@ -595,16 +621,19 @@ - static void tcp_write_timer(unsigned long data) - { - struct sock *sk = (struct sock *)data; -+ struct sock *meta_sk = mptcp(tcp_sk(sk)) ? mptcp_meta_sk(sk) : sk; - -- bh_lock_sock(sk); -- if (!sock_owned_by_user(sk)) { -+ bh_lock_sock(meta_sk); -+ if (!sock_owned_by_user(meta_sk)) { - tcp_write_timer_handler(sk); - } else { - /* delegate our work to tcp_release_cb() */ - if (!test_and_set_bit(TCP_WRITE_TIMER_DEFERRED, &sk->sk_tsq_flags)) - sock_hold(sk); -+ if (mptcp(tcp_sk(sk))) -+ mptcp_tsq_flags(sk); - } -- bh_unlock_sock(sk); -+ bh_unlock_sock(meta_sk); - sock_put(sk); - } - -@@ -634,11 +663,12 @@ - struct sock *sk = (struct sock *) data; - struct inet_connection_sock *icsk = inet_csk(sk); - struct tcp_sock *tp = tcp_sk(sk); -+ struct sock *meta_sk = mptcp(tp) ? mptcp_meta_sk(sk) : sk; - u32 elapsed; - - /* Only process if socket is not in use. */ -- bh_lock_sock(sk); -- if (sock_owned_by_user(sk)) { -+ bh_lock_sock(meta_sk); -+ if (sock_owned_by_user(meta_sk)) { - /* Try again later. */ - inet_csk_reset_keepalive_timer (sk, HZ/20); - goto out; -@@ -650,16 +680,31 @@ - } - - tcp_mstamp_refresh(tp); -+ -+ if (tp->send_mp_fclose) { -+ if (icsk->icsk_retransmits >= MPTCP_FASTCLOSE_RETRIES) { -+ tcp_write_err(sk); -+ goto out; -+ } -+ -+ tcp_send_ack(sk); -+ icsk->icsk_retransmits++; -+ -+ icsk->icsk_rto = min(icsk->icsk_rto << 1, TCP_RTO_MAX); -+ elapsed = icsk->icsk_rto; -+ goto resched; -+ } -+ - if (sk->sk_state == TCP_FIN_WAIT2 && sock_flag(sk, SOCK_DEAD)) { - if (tp->linger2 >= 0) { - const int tmo = tcp_fin_time(sk) - TCP_TIMEWAIT_LEN; - - if (tmo > 0) { -- tcp_time_wait(sk, TCP_FIN_WAIT2, tmo); -+ tp->ops->time_wait(sk, TCP_FIN_WAIT2, tmo); - goto out; - } - } -- tcp_send_active_reset(sk, GFP_ATOMIC); -+ tp->ops->send_active_reset(sk, GFP_ATOMIC); - goto death; - } - -@@ -684,11 +729,11 @@ - icsk->icsk_probes_out > 0) || - (icsk->icsk_user_timeout == 0 && - icsk->icsk_probes_out >= keepalive_probes(tp))) { -- tcp_send_active_reset(sk, GFP_ATOMIC); -+ tp->ops->send_active_reset(sk, GFP_ATOMIC); - tcp_write_err(sk); - goto out; - } -- if (tcp_write_wakeup(sk, LINUX_MIB_TCPKEEPALIVE) <= 0) { -+ if (tp->ops->write_wakeup(sk, LINUX_MIB_TCPKEEPALIVE) <= 0) { - icsk->icsk_probes_out++; - elapsed = keepalive_intvl_when(tp); - } else { -@@ -712,7 +757,7 @@ - tcp_done(sk); - - out: -- bh_unlock_sock(sk); -+ bh_unlock_sock(meta_sk); - sock_put(sk); - } - -diff -aurN linux-4.14.174/net/ipv6/addrconf.c mptcp-mptcp_v0.94/net/ipv6/addrconf.c ---- linux-4.14.174/net/ipv6/addrconf.c 2020-03-20 10:54:27.000000000 +0100 -+++ mptcp-mptcp_v0.94/net/ipv6/addrconf.c 2020-03-23 09:45:33.000000000 +0100 -@@ -928,6 +928,7 @@ - - kfree_rcu(ifp, rcu); - } -+EXPORT_SYMBOL(inet6_ifa_finish_destroy); - - static void - ipv6_link_dev_addr(struct inet6_dev *idev, struct inet6_ifaddr *ifp) -diff -aurN linux-4.14.174/net/ipv6/af_inet6.c mptcp-mptcp_v0.94/net/ipv6/af_inet6.c ---- linux-4.14.174/net/ipv6/af_inet6.c 2020-03-20 10:54:27.000000000 +0100 -+++ mptcp-mptcp_v0.94/net/ipv6/af_inet6.c 2020-03-23 09:45:33.000000000 +0100 -@@ -107,8 +107,7 @@ - return (struct ipv6_pinfo *)(((u8 *)sk) + offset); - } - --static int inet6_create(struct net *net, struct socket *sock, int protocol, -- int kern) -+int inet6_create(struct net *net, struct socket *sock, int protocol, int kern) - { - struct inet_sock *inet; - struct ipv6_pinfo *np; -diff -aurN linux-4.14.174/net/ipv6/ipv6_sockglue.c mptcp-mptcp_v0.94/net/ipv6/ipv6_sockglue.c ---- linux-4.14.174/net/ipv6/ipv6_sockglue.c 2020-03-20 10:54:27.000000000 +0100 -+++ mptcp-mptcp_v0.94/net/ipv6/ipv6_sockglue.c 2020-03-23 09:45:33.000000000 +0100 -@@ -48,6 +48,8 @@ - #include - #include - #include -+#include -+#include - #include - #include - #include -@@ -222,7 +224,12 @@ - sock_prot_inuse_add(net, &tcp_prot, 1); - local_bh_enable(); - sk->sk_prot = &tcp_prot; -- icsk->icsk_af_ops = &ipv4_specific; -+#ifdef CONFIG_MPTCP -+ if (sock_flag(sk, SOCK_MPTCP)) -+ icsk->icsk_af_ops = &mptcp_v4_specific; -+ else -+#endif -+ icsk->icsk_af_ops = &ipv4_specific; - sk->sk_socket->ops = &inet_stream_ops; - sk->sk_family = PF_INET; - tcp_sync_mss(sk, icsk->icsk_pmtu_cookie); -diff -aurN linux-4.14.174/net/ipv6/syncookies.c mptcp-mptcp_v0.94/net/ipv6/syncookies.c ---- linux-4.14.174/net/ipv6/syncookies.c 2020-03-20 10:54:27.000000000 +0100 -+++ mptcp-mptcp_v0.94/net/ipv6/syncookies.c 2020-03-23 09:45:33.000000000 +0100 -@@ -20,6 +20,8 @@ - #include - #include - #include -+#include -+#include - #include - - #define COOKIEBITS 24 /* Upper bits store count */ -@@ -111,7 +113,8 @@ - } - EXPORT_SYMBOL_GPL(__cookie_v6_init_sequence); - --__u32 cookie_v6_init_sequence(const struct sk_buff *skb, __u16 *mssp) -+__u32 cookie_v6_init_sequence(struct request_sock *req, const struct sock *sk, -+ const struct sk_buff *skb, __u16 *mssp) - { - const struct ipv6hdr *iph = ipv6_hdr(skb); - const struct tcphdr *th = tcp_hdr(skb); -@@ -133,6 +136,7 @@ - struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb) - { - struct tcp_options_received tcp_opt; -+ struct mptcp_options_received mopt; - struct inet_request_sock *ireq; - struct tcp_request_sock *treq; - struct ipv6_pinfo *np = inet6_sk(sk); -@@ -162,7 +166,8 @@ - - /* check for timestamp cookie support */ - memset(&tcp_opt, 0, sizeof(tcp_opt)); -- tcp_parse_options(sock_net(sk), skb, &tcp_opt, 0, NULL); -+ mptcp_init_mp_opt(&mopt); -+ tcp_parse_options(sock_net(sk), skb, &tcp_opt, &mopt, 0, NULL, NULL); - - if (tcp_opt.saw_tstamp && tcp_opt.rcv_tsecr) { - tsoff = secure_tcpv6_ts_off(sock_net(sk), -@@ -175,14 +180,27 @@ - goto out; - - ret = NULL; -- req = inet_reqsk_alloc(&tcp6_request_sock_ops, sk, false); -+#ifdef CONFIG_MPTCP -+ if (mopt.saw_mpc) -+ req = inet_reqsk_alloc(&mptcp6_request_sock_ops, sk, false); -+ else -+#endif -+ req = inet_reqsk_alloc(&tcp6_request_sock_ops, sk, false); - if (!req) - goto out; - - ireq = inet_rsk(req); -+ ireq->mptcp_rqsk = 0; -+ ireq->saw_mpc = 0; - treq = tcp_rsk(req); - treq->tfo_listener = false; - -+ /* Must be done before anything else, as it initializes -+ * hash_entry of the MPTCP request-sock. -+ */ -+ if (mopt.saw_mpc) -+ mptcp_cookies_reqsk_init(req, &mopt, skb); -+ - if (security_inet_conn_request(sk, skb, req)) - goto out_free; - -@@ -244,10 +262,10 @@ - } - - req->rsk_window_clamp = tp->window_clamp ? :dst_metric(dst, RTAX_WINDOW); -- tcp_select_initial_window(tcp_full_space(sk), req->mss, -- &req->rsk_rcv_wnd, &req->rsk_window_clamp, -- ireq->wscale_ok, &rcv_wscale, -- dst_metric(dst, RTAX_INITRWND)); -+ tp->ops->select_initial_window(tcp_full_space(sk), req->mss, -+ &req->rsk_rcv_wnd, &req->rsk_window_clamp, -+ ireq->wscale_ok, &rcv_wscale, -+ dst_metric(dst, RTAX_INITRWND), sk); - - ireq->rcv_wscale = rcv_wscale; - ireq->ecn_ok = cookie_ecn_ok(&tcp_opt, sock_net(sk), dst); -diff -aurN linux-4.14.174/net/ipv6/tcp_ipv6.c mptcp-mptcp_v0.94/net/ipv6/tcp_ipv6.c ---- linux-4.14.174/net/ipv6/tcp_ipv6.c 2020-03-20 10:54:27.000000000 +0100 -+++ mptcp-mptcp_v0.94/net/ipv6/tcp_ipv6.c 2020-03-23 09:45:33.000000000 +0100 -@@ -61,6 +61,8 @@ - #include - #include - #include -+#include -+#include - #include - - #include -@@ -69,14 +71,6 @@ - #include - #include - --static void tcp_v6_send_reset(const struct sock *sk, struct sk_buff *skb); --static void tcp_v6_reqsk_send_ack(const struct sock *sk, struct sk_buff *skb, -- struct request_sock *req); -- --static int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb); -- --static const struct inet_connection_sock_af_ops ipv6_mapped; --static const struct inet_connection_sock_af_ops ipv6_specific; - #ifdef CONFIG_TCP_MD5SIG - static const struct tcp_sock_af_ops tcp_sock_ipv6_specific; - static const struct tcp_sock_af_ops tcp_sock_ipv6_mapped_specific; -@@ -88,7 +82,7 @@ - } - #endif - --static void inet6_sk_rx_dst_set(struct sock *sk, const struct sk_buff *skb) -+void inet6_sk_rx_dst_set(struct sock *sk, const struct sk_buff *skb) - { - struct dst_entry *dst = skb_dst(skb); - -@@ -115,7 +109,7 @@ - ipv6_hdr(skb)->saddr.s6_addr32); - } - --static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr, -+int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr, - int addr_len) - { - struct sockaddr_in6 *usin = (struct sockaddr_in6 *) uaddr; -@@ -213,7 +207,12 @@ - sin.sin_port = usin->sin6_port; - sin.sin_addr.s_addr = usin->sin6_addr.s6_addr32[3]; - -- icsk->icsk_af_ops = &ipv6_mapped; -+#ifdef CONFIG_MPTCP -+ if (sock_flag(sk, SOCK_MPTCP)) -+ icsk->icsk_af_ops = &mptcp_v6_mapped; -+ else -+#endif -+ icsk->icsk_af_ops = &ipv6_mapped; - sk->sk_backlog_rcv = tcp_v4_do_rcv; - #ifdef CONFIG_TCP_MD5SIG - tp->af_specific = &tcp_sock_ipv6_mapped_specific; -@@ -223,7 +222,12 @@ - - if (err) { - icsk->icsk_ext_hdr_len = exthdrlen; -- icsk->icsk_af_ops = &ipv6_specific; -+#ifdef CONFIG_MPTCP -+ if (sock_flag(sk, SOCK_MPTCP)) -+ icsk->icsk_af_ops = &mptcp_v6_specific; -+ else -+#endif -+ icsk->icsk_af_ops = &ipv6_specific; - sk->sk_backlog_rcv = tcp_v6_do_rcv; - #ifdef CONFIG_TCP_MD5SIG - tp->af_specific = &tcp_sock_ipv6_specific; -@@ -316,7 +320,7 @@ - return err; - } - --static void tcp_v6_mtu_reduced(struct sock *sk) -+void tcp_v6_mtu_reduced(struct sock *sk) - { - struct dst_entry *dst; - -@@ -343,7 +347,7 @@ - struct ipv6_pinfo *np; - struct tcp_sock *tp; - __u32 seq, snd_una; -- struct sock *sk; -+ struct sock *sk, *meta_sk; - bool fatal; - int err; - -@@ -367,8 +371,14 @@ - if (sk->sk_state == TCP_NEW_SYN_RECV) - return tcp_req_err(sk, seq, fatal); - -- bh_lock_sock(sk); -- if (sock_owned_by_user(sk) && type != ICMPV6_PKT_TOOBIG) -+ tp = tcp_sk(sk); -+ if (mptcp(tp)) -+ meta_sk = mptcp_meta_sk(sk); -+ else -+ meta_sk = sk; -+ -+ bh_lock_sock(meta_sk); -+ if (sock_owned_by_user(meta_sk) && type != ICMPV6_PKT_TOOBIG) - __NET_INC_STATS(net, LINUX_MIB_LOCKDROPPEDICMPS); - - if (sk->sk_state == TCP_CLOSE) -@@ -379,7 +389,6 @@ - goto out; - } - -- tp = tcp_sk(sk); - /* XXX (TFO) - tp->snd_una should be ISN (tcp_create_openreq_child() */ - fastopen = tp->fastopen_rsk; - snd_una = fastopen ? tcp_rsk(fastopen)->snt_isn : tp->snd_una; -@@ -413,11 +422,15 @@ - goto out; - - tp->mtu_info = ntohl(info); -- if (!sock_owned_by_user(sk)) -+ if (!sock_owned_by_user(meta_sk)) { - tcp_v6_mtu_reduced(sk); -- else if (!test_and_set_bit(TCP_MTU_REDUCED_DEFERRED, -- &sk->sk_tsq_flags)) -- sock_hold(sk); -+ } else { -+ if (!test_and_set_bit(TCP_MTU_REDUCED_DEFERRED, -+ &sk->sk_tsq_flags)) -+ sock_hold(sk); -+ if (mptcp(tp)) -+ mptcp_tsq_flags(sk); -+ } - goto out; - } - -@@ -432,7 +445,7 @@ - if (fastopen && !fastopen->sk) - break; - -- if (!sock_owned_by_user(sk)) { -+ if (!sock_owned_by_user(meta_sk)) { - sk->sk_err = err; - sk->sk_error_report(sk); /* Wake people up to see the error (see connect in sock.c) */ - -@@ -442,14 +455,14 @@ - goto out; - } - -- if (!sock_owned_by_user(sk) && np->recverr) { -+ if (!sock_owned_by_user(meta_sk) && np->recverr) { - sk->sk_err = err; - sk->sk_error_report(sk); - } else - sk->sk_err_soft = err; - - out: -- bh_unlock_sock(sk); -+ bh_unlock_sock(meta_sk); - sock_put(sk); - } - -@@ -495,8 +508,7 @@ - return err; - } - -- --static void tcp_v6_reqsk_destructor(struct request_sock *req) -+void tcp_v6_reqsk_destructor(struct request_sock *req) - { - kfree(inet_rsk(req)->ipv6_opt); - kfree_skb(inet_rsk(req)->pktopts); -@@ -714,9 +726,10 @@ - return false; - } - --static void tcp_v6_init_req(struct request_sock *req, -- const struct sock *sk_listener, -- struct sk_buff *skb) -+static int tcp_v6_init_req(struct request_sock *req, -+ const struct sock *sk_listener, -+ struct sk_buff *skb, -+ bool want_cookie) - { - bool l3_slave = ipv6_l3mdev_skb(TCP_SKB_CB(skb)->header.h6.flags); - struct inet_request_sock *ireq = inet_rsk(req); -@@ -738,6 +751,8 @@ - refcount_inc(&skb->users); - ireq->pktopts = skb; - } -+ -+ return 0; - } - - static struct dst_entry *tcp_v6_route_req(const struct sock *sk, -@@ -757,7 +772,7 @@ - .syn_ack_timeout = tcp_syn_ack_timeout, - }; - --static const struct tcp_request_sock_ops tcp_request_sock_ipv6_ops = { -+const struct tcp_request_sock_ops tcp_request_sock_ipv6_ops = { - .mss_clamp = IPV6_MIN_MTU - sizeof(struct tcphdr) - - sizeof(struct ipv6hdr), - #ifdef CONFIG_TCP_MD5SIG -@@ -775,9 +790,9 @@ - }; - - static void tcp_v6_send_response(const struct sock *sk, struct sk_buff *skb, u32 seq, -- u32 ack, u32 win, u32 tsval, u32 tsecr, -+ u32 ack, u32 data_ack, u32 win, u32 tsval, u32 tsecr, - int oif, struct tcp_md5sig_key *key, int rst, -- u8 tclass, __be32 label) -+ u8 tclass, __be32 label, int mptcp) - { - const struct tcphdr *th = tcp_hdr(skb); - struct tcphdr *t1; -@@ -795,7 +810,10 @@ - if (key) - tot_len += TCPOLEN_MD5SIG_ALIGNED; - #endif -- -+#ifdef CONFIG_MPTCP -+ if (mptcp) -+ tot_len += MPTCP_SUB_LEN_DSS + MPTCP_SUB_LEN_ACK; -+#endif - buff = alloc_skb(MAX_HEADER + sizeof(struct ipv6hdr) + tot_len, - GFP_ATOMIC); - if (!buff) -@@ -833,6 +851,17 @@ - tcp_v6_md5_hash_hdr((__u8 *)topt, key, - &ipv6_hdr(skb)->saddr, - &ipv6_hdr(skb)->daddr, t1); -+ topt += 4; -+ } -+#endif -+#ifdef CONFIG_MPTCP -+ if (mptcp) { -+ /* Construction of 32-bit data_ack */ -+ *topt++ = htonl((TCPOPT_MPTCP << 24) | -+ ((MPTCP_SUB_LEN_DSS + MPTCP_SUB_LEN_ACK) << 16) | -+ (0x20 << 8) | -+ (0x01)); -+ *topt++ = htonl(data_ack); - } - #endif - -@@ -879,7 +908,7 @@ - kfree_skb(buff); - } - --static void tcp_v6_send_reset(const struct sock *sk, struct sk_buff *skb) -+void tcp_v6_send_reset(const struct sock *sk, struct sk_buff *skb) - { - const struct tcphdr *th = tcp_hdr(skb); - u32 seq = 0, ack_seq = 0; -@@ -942,7 +971,7 @@ - (th->doff << 2); - - oif = sk ? sk->sk_bound_dev_if : 0; -- tcp_v6_send_response(sk, skb, seq, ack_seq, 0, 0, 0, oif, key, 1, 0, 0); -+ tcp_v6_send_response(sk, skb, seq, ack_seq, 0, 0, 0, 0, oif, key, 1, 0, 0, 0); - - #ifdef CONFIG_TCP_MD5SIG - out: -@@ -951,30 +980,37 @@ - } - - static void tcp_v6_send_ack(const struct sock *sk, struct sk_buff *skb, u32 seq, -- u32 ack, u32 win, u32 tsval, u32 tsecr, int oif, -+ u32 ack, u32 data_ack, u32 win, u32 tsval, u32 tsecr, int oif, - struct tcp_md5sig_key *key, u8 tclass, -- __be32 label) -+ __be32 label, int mptcp) - { -- tcp_v6_send_response(sk, skb, seq, ack, win, tsval, tsecr, oif, key, 0, -- tclass, label); -+ tcp_v6_send_response(sk, skb, seq, ack, data_ack, win, tsval, tsecr, oif, -+ key, 0, tclass, label, mptcp); - } - - static void tcp_v6_timewait_ack(struct sock *sk, struct sk_buff *skb) - { - struct inet_timewait_sock *tw = inet_twsk(sk); - struct tcp_timewait_sock *tcptw = tcp_twsk(sk); -+ u32 data_ack = 0; -+ int mptcp = 0; - -+ if (tcptw->mptcp_tw) { -+ data_ack = (u32)tcptw->mptcp_tw->rcv_nxt; -+ mptcp = 1; -+ } - tcp_v6_send_ack(sk, skb, tcptw->tw_snd_nxt, tcptw->tw_rcv_nxt, -+ data_ack, - tcptw->tw_rcv_wnd >> tw->tw_rcv_wscale, - tcp_time_stamp_raw() + tcptw->tw_ts_offset, - tcptw->tw_ts_recent, tw->tw_bound_dev_if, tcp_twsk_md5_key(tcptw), -- tw->tw_tclass, cpu_to_be32(tw->tw_flowlabel)); -+ tw->tw_tclass, cpu_to_be32(tw->tw_flowlabel), mptcp); - - inet_twsk_put(tw); - } - --static void tcp_v6_reqsk_send_ack(const struct sock *sk, struct sk_buff *skb, -- struct request_sock *req) -+void tcp_v6_reqsk_send_ack(const struct sock *sk, struct sk_buff *skb, -+ struct request_sock *req) - { - /* sk->sk_state == TCP_LISTEN -> for regular TCP_SYN_RECV - * sk->sk_state == TCP_SYN_RECV -> for Fast Open. -@@ -984,18 +1020,18 @@ - * exception of segments, MUST be right-shifted by - * Rcv.Wind.Shift bits: - */ -- tcp_v6_send_ack(sk, skb, (sk->sk_state == TCP_LISTEN) ? -+ tcp_v6_send_ack(sk, skb, (sk->sk_state == TCP_LISTEN || is_meta_sk(sk)) ? - tcp_rsk(req)->snt_isn + 1 : tcp_sk(sk)->snd_nxt, -- tcp_rsk(req)->rcv_nxt, -+ tcp_rsk(req)->rcv_nxt, 0, - req->rsk_rcv_wnd >> inet_rsk(req)->rcv_wscale, - tcp_time_stamp_raw() + tcp_rsk(req)->ts_off, - req->ts_recent, sk->sk_bound_dev_if, - tcp_v6_md5_do_lookup(sk, &ipv6_hdr(skb)->saddr), -- 0, 0); -+ 0, 0, 0); - } - - --static struct sock *tcp_v6_cookie_check(struct sock *sk, struct sk_buff *skb) -+struct sock *tcp_v6_cookie_check(struct sock *sk, struct sk_buff *skb) - { - #ifdef CONFIG_SYN_COOKIES - const struct tcphdr *th = tcp_hdr(skb); -@@ -1006,7 +1042,7 @@ - return sk; - } - --static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb) -+int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb) - { - if (skb->protocol == htons(ETH_P_IP)) - return tcp_v4_conn_request(sk, skb); -@@ -1032,11 +1068,11 @@ - sizeof(struct inet6_skb_parm)); - } - --static struct sock *tcp_v6_syn_recv_sock(const struct sock *sk, struct sk_buff *skb, -- struct request_sock *req, -- struct dst_entry *dst, -- struct request_sock *req_unhash, -- bool *own_req) -+struct sock *tcp_v6_syn_recv_sock(const struct sock *sk, struct sk_buff *skb, -+ struct request_sock *req, -+ struct dst_entry *dst, -+ struct request_sock *req_unhash, -+ bool *own_req) - { - struct inet_request_sock *ireq; - struct ipv6_pinfo *newnp; -@@ -1073,7 +1109,15 @@ - - newnp->saddr = newsk->sk_v6_rcv_saddr; - -- inet_csk(newsk)->icsk_af_ops = &ipv6_mapped; -+#ifdef CONFIG_MPTCP -+ /* We must check on the request-socket because the listener -+ * socket's flag may have been changed halfway through. -+ */ -+ if (!inet_rsk(req)->saw_mpc) -+ inet_csk(newsk)->icsk_af_ops = &mptcp_v6_mapped; -+ else -+#endif -+ inet_csk(newsk)->icsk_af_ops = &ipv6_mapped; - newsk->sk_backlog_rcv = tcp_v4_do_rcv; - #ifdef CONFIG_TCP_MD5SIG - newtp->af_specific = &tcp_sock_ipv6_mapped_specific; -@@ -1120,6 +1164,14 @@ - if (!newsk) - goto out_nonewsk; - -+#ifdef CONFIG_MPTCP -+ /* If the meta_sk is v6-mapped we can end up here with the wrong af_ops. -+ * Just make sure that this subflow is v6. -+ */ -+ if (is_meta_sk(sk)) -+ inet_csk(newsk)->icsk_af_ops = &mptcp_v6_specific; -+#endif -+ - /* - * No need to charge this sock to the relevant IPv6 refcnt debug socks - * count here, tcp_create_openreq_child now does this for us, see the -@@ -1248,7 +1300,7 @@ - * This is because we cannot sleep with the original spinlock - * held. - */ --static int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb) -+int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb) - { - struct ipv6_pinfo *np = inet6_sk(sk); - struct tcp_sock *tp; -@@ -1265,6 +1317,9 @@ - if (skb->protocol == htons(ETH_P_IP)) - return tcp_v4_do_rcv(sk, skb); - -+ if (is_meta_sk(sk)) -+ return mptcp_v6_do_rcv(sk, skb); -+ - /* - * socket locking is here for SMP purposes as backlog rcv - * is currently called with bh processing disabled. -@@ -1392,6 +1447,10 @@ - TCP_SKB_CB(skb)->end_seq = (TCP_SKB_CB(skb)->seq + th->syn + th->fin + - skb->len - th->doff*4); - TCP_SKB_CB(skb)->ack_seq = ntohl(th->ack_seq); -+#ifdef CONFIG_MPTCP -+ TCP_SKB_CB(skb)->mptcp_flags = 0; -+ TCP_SKB_CB(skb)->dss_off = 0; -+#endif - TCP_SKB_CB(skb)->tcp_flags = tcp_flag_byte(th); - TCP_SKB_CB(skb)->tcp_tw_isn = 0; - TCP_SKB_CB(skb)->ip_dsfield = ipv6_get_dsfield(hdr); -@@ -1405,8 +1464,8 @@ - int sdif = inet6_sdif(skb); - const struct tcphdr *th; - const struct ipv6hdr *hdr; -+ struct sock *sk, *meta_sk = NULL; - bool refcounted; -- struct sock *sk; - int ret; - struct net *net = dev_net(skb->dev); - -@@ -1459,12 +1518,42 @@ - reqsk_put(req); - goto csum_error; - } -- if (unlikely(sk->sk_state != TCP_LISTEN)) { -+ if (unlikely(sk->sk_state != TCP_LISTEN && !is_meta_sk(sk))) { - inet_csk_reqsk_queue_drop_and_put(sk, req); - goto lookup; - } - sock_hold(sk); - refcounted = true; -+ -+ if (is_meta_sk(sk)) { -+ bh_lock_sock(sk); -+ -+ if (!mptcp_can_new_subflow(sk)) { -+ inet_csk_reqsk_queue_drop_and_put(sk, req); -+ bh_unlock_sock(sk); -+ -+ goto discard_and_relse; -+ } -+ -+ if (sock_owned_by_user(sk)) { -+ mptcp_prepare_for_backlog(sk, skb); -+ if (unlikely(sk_add_backlog(sk, skb, -+ sk->sk_rcvbuf + sk->sk_sndbuf))) { -+ reqsk_put(req); -+ -+ bh_unlock_sock(sk); -+ __NET_INC_STATS(net, LINUX_MIB_TCPBACKLOGDROP); -+ goto discard_and_relse; -+ } -+ -+ reqsk_put(req); -+ bh_unlock_sock(sk); -+ sock_put(sk); -+ -+ return 0; -+ } -+ } -+ - nsk = NULL; - if (!tcp_filter(sk, skb)) { - th = (const struct tcphdr *)skb->data; -@@ -1474,10 +1563,14 @@ - } - if (!nsk) { - reqsk_put(req); -+ if (is_meta_sk(sk)) -+ bh_unlock_sock(sk); - goto discard_and_relse; - } - if (nsk == sk) { - reqsk_put(req); -+ if (is_meta_sk(sk)) -+ bh_unlock_sock(sk); - tcp_v6_restore_cb(skb); - } else if (tcp_child_process(sk, nsk, skb)) { - tcp_v6_send_reset(nsk, skb); -@@ -1487,6 +1580,7 @@ - return 0; - } - } -+ - if (hdr->hop_limit < inet6_sk(sk)->min_hopcount) { - __NET_INC_STATS(net, LINUX_MIB_TCPMINTTLDROP); - goto discard_and_relse; -@@ -1513,15 +1607,25 @@ - - sk_incoming_cpu_update(sk); - -- bh_lock_sock_nested(sk); -+ if (mptcp(tcp_sk(sk))) { -+ meta_sk = mptcp_meta_sk(sk); -+ -+ bh_lock_sock_nested(meta_sk); -+ if (sock_owned_by_user(meta_sk)) -+ mptcp_prepare_for_backlog(sk, skb); -+ } else { -+ meta_sk = sk; -+ bh_lock_sock_nested(sk); -+ } - tcp_segs_in(tcp_sk(sk), skb); - ret = 0; -- if (!sock_owned_by_user(sk)) { -+ if (!sock_owned_by_user(meta_sk)) { - ret = tcp_v6_do_rcv(sk, skb); -- } else if (tcp_add_backlog(sk, skb)) { -+ } else if (tcp_add_backlog(meta_sk, skb)) { - goto discard_and_relse; - } -- bh_unlock_sock(sk); -+ -+ bh_unlock_sock(meta_sk); - - put_and_return: - if (refcounted) -@@ -1534,6 +1638,19 @@ - - tcp_v6_fill_cb(skb, hdr, th); - -+#ifdef CONFIG_MPTCP -+ if (!sk && th->syn && !th->ack) { -+ int ret = mptcp_lookup_join(skb, NULL); -+ -+ if (ret < 0) { -+ tcp_v6_send_reset(NULL, skb); -+ goto discard_it; -+ } else if (ret > 0) { -+ return 0; -+ } -+ } -+#endif -+ - if (tcp_checksum_complete(skb)) { - csum_error: - __TCP_INC_STATS(net, TCP_MIB_CSUMERRORS); -@@ -1586,6 +1703,18 @@ - refcounted = false; - goto process; - } -+#ifdef CONFIG_MPTCP -+ if (th->syn && !th->ack) { -+ int ret = mptcp_lookup_join(skb, inet_twsk(sk)); -+ -+ if (ret < 0) { -+ tcp_v6_send_reset(NULL, skb); -+ goto discard_it; -+ } else if (ret > 0) { -+ return 0; -+ } -+ } -+#endif - /* Fall through to ACK */ - } - case TCP_TW_ACK: -@@ -1639,13 +1768,13 @@ - } - } - --static struct timewait_sock_ops tcp6_timewait_sock_ops = { -+struct timewait_sock_ops tcp6_timewait_sock_ops = { - .twsk_obj_size = sizeof(struct tcp6_timewait_sock), - .twsk_unique = tcp_twsk_unique, - .twsk_destructor = tcp_twsk_destructor, - }; - --static const struct inet_connection_sock_af_ops ipv6_specific = { -+const struct inet_connection_sock_af_ops ipv6_specific = { - .queue_xmit = inet6_csk_xmit, - .send_check = tcp_v6_send_check, - .rebuild_header = inet6_sk_rebuild_header, -@@ -1676,7 +1805,7 @@ - /* - * TCP over IPv4 via INET6 API - */ --static const struct inet_connection_sock_af_ops ipv6_mapped = { -+const struct inet_connection_sock_af_ops ipv6_mapped = { - .queue_xmit = ip_queue_xmit, - .send_check = tcp_v4_send_check, - .rebuild_header = inet_sk_rebuild_header, -@@ -1712,7 +1841,12 @@ - - tcp_init_sock(sk); - -- icsk->icsk_af_ops = &ipv6_specific; -+#ifdef CONFIG_MPTCP -+ if (sock_flag(sk, SOCK_MPTCP)) -+ icsk->icsk_af_ops = &mptcp_v6_specific; -+ else -+#endif -+ icsk->icsk_af_ops = &ipv6_specific; - - #ifdef CONFIG_TCP_MD5SIG - tcp_sk(sk)->af_specific = &tcp_sock_ipv6_specific; -@@ -1721,7 +1855,7 @@ - return 0; - } - --static void tcp_v6_destroy_sock(struct sock *sk) -+void tcp_v6_destroy_sock(struct sock *sk) - { - tcp_v4_destroy_sock(sk); - inet6_destroy_sock(sk); -@@ -1955,6 +2089,9 @@ - .compat_getsockopt = compat_tcp_getsockopt, - #endif - .diag_destroy = tcp_abort, -+#ifdef CONFIG_MPTCP -+ .clear_sk = mptcp_clear_sk, -+#endif - }; - - /* thinking of making this const? Don't. -diff -aurN linux-4.14.174/net/Kconfig mptcp-mptcp_v0.94/net/Kconfig ---- linux-4.14.174/net/Kconfig 2020-03-20 10:54:27.000000000 +0100 -+++ mptcp-mptcp_v0.94/net/Kconfig 2020-03-23 09:45:33.000000000 +0100 -@@ -88,6 +88,7 @@ - source "net/ipv4/Kconfig" - source "net/ipv6/Kconfig" - source "net/netlabel/Kconfig" -+source "net/mptcp/Kconfig" - - endif # if INET - -diff -aurN linux-4.14.174/net/Makefile mptcp-mptcp_v0.94/net/Makefile ---- linux-4.14.174/net/Makefile 2020-03-20 10:54:27.000000000 +0100 -+++ mptcp-mptcp_v0.94/net/Makefile 2020-03-23 09:45:33.000000000 +0100 -@@ -20,6 +20,7 @@ - obj-$(CONFIG_XFRM) += xfrm/ - obj-$(CONFIG_UNIX) += unix/ - obj-$(CONFIG_NET) += ipv6/ -+obj-$(CONFIG_MPTCP) += mptcp/ - obj-$(CONFIG_PACKET) += packet/ - obj-$(CONFIG_NET_KEY) += key/ - obj-$(CONFIG_BRIDGE) += bridge/ -diff -aurN linux-4.14.174/net/mptcp/Kconfig mptcp-mptcp_v0.94/net/mptcp/Kconfig ---- linux-4.14.174/net/mptcp/Kconfig 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_v0.94/net/mptcp/Kconfig 2020-03-23 09:45:33.000000000 +0100 -@@ -0,0 +1,129 @@ -+# -+# MPTCP configuration -+# -+config MPTCP -+ bool "MPTCP protocol" -+ depends on (IPV6=y || IPV6=n) -+ ---help--- -+ This replaces the normal TCP stack with a Multipath TCP stack, -+ able to use several paths at once. -+ -+menuconfig MPTCP_PM_ADVANCED -+ bool "MPTCP: advanced path-manager control" -+ depends on MPTCP=y -+ ---help--- -+ Support for selection of different path-managers. You should choose 'Y' here, -+ because otherwise you will not actively create new MPTCP-subflows. -+ -+if MPTCP_PM_ADVANCED -+ -+config MPTCP_FULLMESH -+ tristate "MPTCP Full-Mesh Path-Manager" -+ depends on MPTCP=y -+ ---help--- -+ This path-management module will create a full-mesh among all IP-addresses. -+ -+config MPTCP_NDIFFPORTS -+ tristate "MPTCP ndiff-ports" -+ depends on MPTCP=y -+ ---help--- -+ This path-management module will create multiple subflows between the same -+ pair of IP-addresses, modifying the source-port. You can set the number -+ of subflows via the mptcp_ndiffports-sysctl. -+ -+config MPTCP_BINDER -+ tristate "MPTCP Binder" -+ depends on (MPTCP=y) -+ ---help--- -+ This path-management module works like ndiffports, and adds the sysctl -+ option to set the gateway (and/or path to) per each additional subflow -+ via Loose Source Routing (IPv4 only). -+ -+choice -+ prompt "Default MPTCP Path-Manager" -+ default DEFAULT_DUMMY -+ help -+ Select the Path-Manager of your choice -+ -+ config DEFAULT_FULLMESH -+ bool "Full mesh" if MPTCP_FULLMESH=y -+ -+ config DEFAULT_NDIFFPORTS -+ bool "ndiff-ports" if MPTCP_NDIFFPORTS=y -+ -+ config DEFAULT_BINDER -+ bool "binder" if MPTCP_BINDER=y -+ -+ config DEFAULT_DUMMY -+ bool "Default" -+ -+endchoice -+ -+endif -+ -+config DEFAULT_MPTCP_PM -+ string -+ default "default" if DEFAULT_DUMMY -+ default "fullmesh" if DEFAULT_FULLMESH -+ default "ndiffports" if DEFAULT_NDIFFPORTS -+ default "binder" if DEFAULT_BINDER -+ default "default" -+ -+menuconfig MPTCP_SCHED_ADVANCED -+ bool "MPTCP: advanced scheduler control" -+ depends on MPTCP=y -+ ---help--- -+ Support for selection of different schedulers. You should choose 'Y' here, -+ if you want to choose a different scheduler than the default one. -+ -+if MPTCP_SCHED_ADVANCED -+ -+config MPTCP_ROUNDROBIN -+ tristate "MPTCP Round-Robin" -+ depends on (MPTCP=y) -+ ---help--- -+ This is a very simple round-robin scheduler. Probably has bad performance -+ but might be interesting for researchers. -+ -+config MPTCP_REDUNDANT -+ tristate "MPTCP Redundant" -+ depends on (MPTCP=y) -+ ---help--- -+ This scheduler sends all packets redundantly over all subflows to decreases -+ latency and jitter on the cost of lower throughput. -+ -+choice -+ prompt "Default MPTCP Scheduler" -+ default DEFAULT_SCHEDULER -+ help -+ Select the Scheduler of your choice -+ -+ config DEFAULT_SCHEDULER -+ bool "Default" -+ ---help--- -+ This is the default scheduler, sending first on the subflow -+ with the lowest RTT. -+ -+ config DEFAULT_ROUNDROBIN -+ bool "Round-Robin" if MPTCP_ROUNDROBIN=y -+ ---help--- -+ This is the round-rob scheduler, sending in a round-robin -+ fashion.. -+ -+ config DEFAULT_REDUNDANT -+ bool "Redundant" if MPTCP_REDUNDANT=y -+ ---help--- -+ This is the redundant scheduler, sending packets redundantly over -+ all the subflows. -+ -+endchoice -+endif -+ -+config DEFAULT_MPTCP_SCHED -+ string -+ depends on (MPTCP=y) -+ default "default" if DEFAULT_SCHEDULER -+ default "roundrobin" if DEFAULT_ROUNDROBIN -+ default "redundant" if DEFAULT_REDUNDANT -+ default "default" -+ -diff -aurN linux-4.14.174/net/mptcp/Makefile mptcp-mptcp_v0.94/net/mptcp/Makefile ---- linux-4.14.174/net/mptcp/Makefile 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_v0.94/net/mptcp/Makefile 2020-03-23 09:45:33.000000000 +0100 -@@ -0,0 +1,22 @@ -+# -+## Makefile for MultiPath TCP support code. -+# -+# -+ -+obj-$(CONFIG_MPTCP) += mptcp.o -+ -+mptcp-y := mptcp_ctrl.o mptcp_ipv4.o mptcp_pm.o \ -+ mptcp_output.o mptcp_input.o mptcp_sched.o -+ -+obj-$(CONFIG_TCP_CONG_LIA) += mptcp_coupled.o -+obj-$(CONFIG_TCP_CONG_OLIA) += mptcp_olia.o -+obj-$(CONFIG_TCP_CONG_WVEGAS) += mptcp_wvegas.o -+obj-$(CONFIG_TCP_CONG_BALIA) += mptcp_balia.o -+obj-$(CONFIG_MPTCP_FULLMESH) += mptcp_fullmesh.o -+obj-$(CONFIG_MPTCP_NDIFFPORTS) += mptcp_ndiffports.o -+obj-$(CONFIG_MPTCP_BINDER) += mptcp_binder.o -+obj-$(CONFIG_MPTCP_ROUNDROBIN) += mptcp_rr.o -+obj-$(CONFIG_MPTCP_REDUNDANT) += mptcp_redundant.o -+ -+mptcp-$(subst m,y,$(CONFIG_IPV6)) += mptcp_ipv6.o -+ -diff -aurN linux-4.14.174/net/mptcp/mptcp_balia.c mptcp-mptcp_v0.94/net/mptcp/mptcp_balia.c ---- linux-4.14.174/net/mptcp/mptcp_balia.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_v0.94/net/mptcp/mptcp_balia.c 2020-03-23 09:45:33.000000000 +0100 -@@ -0,0 +1,268 @@ -+/* -+ * MPTCP implementation - Balia Congestion Control -+ * (Balanced Linked Adaptation Algorithm) -+ * -+ * Analysis, Design and Implementation: -+ * Qiuyu Peng -+ * Anwar Walid -+ * Jaehyun Hwang -+ * Steven H. Low -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version -+ * 2 of the License, or (at your option) any later version. -+ */ -+ -+#include -+#include -+ -+#include -+ -+/* The variable 'rate' (i.e., x_r) will be scaled -+ * e.g., from B/s to KB/s, MB/s, or GB/s -+ * if max_rate > 2^rate_scale_limit -+ */ -+ -+static int rate_scale_limit = 25; -+static int alpha_scale = 10; -+static int scale_num = 5; -+ -+struct mptcp_balia { -+ u64 ai; -+ u64 md; -+ bool forced_update; -+}; -+ -+static inline int mptcp_balia_sk_can_send(const struct sock *sk) -+{ -+ return mptcp_sk_can_send(sk) && tcp_sk(sk)->srtt_us; -+} -+ -+static inline u64 mptcp_get_ai(const struct sock *meta_sk) -+{ -+ return ((struct mptcp_balia *)inet_csk_ca(meta_sk))->ai; -+} -+ -+static inline void mptcp_set_ai(const struct sock *meta_sk, u64 ai) -+{ -+ ((struct mptcp_balia *)inet_csk_ca(meta_sk))->ai = ai; -+} -+ -+static inline u64 mptcp_get_md(const struct sock *meta_sk) -+{ -+ return ((struct mptcp_balia *)inet_csk_ca(meta_sk))->md; -+} -+ -+static inline void mptcp_set_md(const struct sock *meta_sk, u64 md) -+{ -+ ((struct mptcp_balia *)inet_csk_ca(meta_sk))->md = md; -+} -+ -+static inline u64 mptcp_balia_scale(u64 val, int scale) -+{ -+ return (u64) val << scale; -+} -+ -+static inline bool mptcp_get_forced(const struct sock *meta_sk) -+{ -+ return ((struct mptcp_balia *)inet_csk_ca(meta_sk))->forced_update; -+} -+ -+static inline void mptcp_set_forced(const struct sock *meta_sk, bool force) -+{ -+ ((struct mptcp_balia *)inet_csk_ca(meta_sk))->forced_update = force; -+} -+ -+static void mptcp_balia_recalc_ai(const struct sock *sk) -+{ -+ const struct tcp_sock *tp = tcp_sk(sk); -+ const struct mptcp_cb *mpcb = tp->mpcb; -+ const struct sock *sub_sk; -+ u64 max_rate = 0, rate = 0, sum_rate = 0; -+ u64 alpha, ai = tp->snd_cwnd, md = (tp->snd_cwnd >> 1); -+ int num_scale_down = 0; -+ -+ if (!mpcb) -+ return; -+ -+ /* Only one subflow left - fall back to normal reno-behavior */ -+ if (mpcb->cnt_established <= 1) -+ goto exit; -+ -+ /* Find max_rate first */ -+ mptcp_for_each_sk(mpcb, sub_sk) { -+ struct tcp_sock *sub_tp = tcp_sk(sub_sk); -+ u64 tmp; -+ -+ if (!mptcp_balia_sk_can_send(sub_sk)) -+ continue; -+ -+ tmp = div_u64((u64)tp->mss_cache * sub_tp->snd_cwnd -+ * (USEC_PER_SEC << 3), sub_tp->srtt_us); -+ sum_rate += tmp; -+ -+ if (tp == sub_tp) -+ rate = tmp; -+ -+ if (tmp >= max_rate) -+ max_rate = tmp; -+ } -+ -+ /* At least, the current subflow should be able to send */ -+ if (unlikely(!rate)) -+ goto exit; -+ -+ alpha = div64_u64(max_rate, rate); -+ -+ /* Scale down max_rate if it is too high (e.g., >2^25) */ -+ while (max_rate > mptcp_balia_scale(1, rate_scale_limit)) { -+ max_rate >>= scale_num; -+ num_scale_down++; -+ } -+ -+ if (num_scale_down) { -+ sum_rate = 0; -+ mptcp_for_each_sk(mpcb, sub_sk) { -+ struct tcp_sock *sub_tp = tcp_sk(sub_sk); -+ u64 tmp; -+ -+ if (!mptcp_balia_sk_can_send(sub_sk)) -+ continue; -+ -+ tmp = div_u64((u64)tp->mss_cache * sub_tp->snd_cwnd -+ * (USEC_PER_SEC << 3), sub_tp->srtt_us); -+ tmp >>= (scale_num * num_scale_down); -+ -+ sum_rate += tmp; -+ } -+ rate >>= (scale_num * num_scale_down); -+ } -+ -+ /* (sum_rate)^2 * 10 * w_r -+ * ai = ------------------------------------ -+ * (x_r + max_rate) * (4x_r + max_rate) -+ */ -+ sum_rate *= sum_rate; -+ -+ ai = div64_u64(sum_rate * 10, rate + max_rate); -+ ai = div64_u64(ai * tp->snd_cwnd, (rate << 2) + max_rate); -+ -+ if (unlikely(!ai)) -+ ai = tp->snd_cwnd; -+ -+ md = ((tp->snd_cwnd >> 1) * min(mptcp_balia_scale(alpha, alpha_scale), -+ mptcp_balia_scale(3, alpha_scale) >> 1)) -+ >> alpha_scale; -+ -+exit: -+ mptcp_set_ai(sk, ai); -+ mptcp_set_md(sk, md); -+} -+ -+static void mptcp_balia_init(struct sock *sk) -+{ -+ if (mptcp(tcp_sk(sk))) { -+ mptcp_set_forced(sk, 0); -+ mptcp_set_ai(sk, 0); -+ mptcp_set_md(sk, 0); -+ } -+} -+ -+static void mptcp_balia_cwnd_event(struct sock *sk, enum tcp_ca_event event) -+{ -+ if (event == CA_EVENT_COMPLETE_CWR || event == CA_EVENT_LOSS) -+ mptcp_balia_recalc_ai(sk); -+} -+ -+static void mptcp_balia_set_state(struct sock *sk, u8 ca_state) -+{ -+ if (!mptcp(tcp_sk(sk))) -+ return; -+ -+ mptcp_set_forced(sk, 1); -+} -+ -+static void mptcp_balia_cong_avoid(struct sock *sk, u32 ack, u32 acked) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ const struct mptcp_cb *mpcb = tp->mpcb; -+ int snd_cwnd; -+ -+ if (!mptcp(tp)) { -+ tcp_reno_cong_avoid(sk, ack, acked); -+ return; -+ } -+ -+ if (!tcp_is_cwnd_limited(sk)) -+ return; -+ -+ if (tcp_in_slow_start(tp)) { -+ /* In "safe" area, increase. */ -+ tcp_slow_start(tp, acked); -+ mptcp_balia_recalc_ai(sk); -+ return; -+ } -+ -+ if (mptcp_get_forced(mptcp_meta_sk(sk))) { -+ mptcp_balia_recalc_ai(sk); -+ mptcp_set_forced(sk, 0); -+ } -+ -+ if (mpcb->cnt_established > 1) -+ snd_cwnd = (int) mptcp_get_ai(sk); -+ else -+ snd_cwnd = tp->snd_cwnd; -+ -+ if (tp->snd_cwnd_cnt >= snd_cwnd) { -+ if (tp->snd_cwnd < tp->snd_cwnd_clamp) { -+ tp->snd_cwnd++; -+ mptcp_balia_recalc_ai(sk); -+ } -+ -+ tp->snd_cwnd_cnt = 0; -+ } else { -+ tp->snd_cwnd_cnt++; -+ } -+} -+ -+static u32 mptcp_balia_ssthresh(struct sock *sk) -+{ -+ const struct tcp_sock *tp = tcp_sk(sk); -+ const struct mptcp_cb *mpcb = tp->mpcb; -+ -+ if (unlikely(!mptcp(tp) || mpcb->cnt_established <= 1)) -+ return tcp_reno_ssthresh(sk); -+ else -+ return max((u32)(tp->snd_cwnd - mptcp_get_md(sk)), 1U); -+} -+ -+static struct tcp_congestion_ops mptcp_balia = { -+ .init = mptcp_balia_init, -+ .ssthresh = mptcp_balia_ssthresh, -+ .cong_avoid = mptcp_balia_cong_avoid, -+ .undo_cwnd = tcp_reno_undo_cwnd, -+ .cwnd_event = mptcp_balia_cwnd_event, -+ .set_state = mptcp_balia_set_state, -+ .owner = THIS_MODULE, -+ .name = "balia", -+}; -+ -+static int __init mptcp_balia_register(void) -+{ -+ BUILD_BUG_ON(sizeof(struct mptcp_balia) > ICSK_CA_PRIV_SIZE); -+ return tcp_register_congestion_control(&mptcp_balia); -+} -+ -+static void __exit mptcp_balia_unregister(void) -+{ -+ tcp_unregister_congestion_control(&mptcp_balia); -+} -+ -+module_init(mptcp_balia_register); -+module_exit(mptcp_balia_unregister); -+ -+MODULE_AUTHOR("Jaehyun Hwang, Anwar Walid, Qiuyu Peng, Steven H. Low"); -+MODULE_LICENSE("GPL"); -+MODULE_DESCRIPTION("MPTCP BALIA CONGESTION CONTROL ALGORITHM"); -+MODULE_VERSION("0.1"); -diff -aurN linux-4.14.174/net/mptcp/mptcp_binder.c mptcp-mptcp_v0.94/net/mptcp/mptcp_binder.c ---- linux-4.14.174/net/mptcp/mptcp_binder.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_v0.94/net/mptcp/mptcp_binder.c 2020-03-23 09:45:33.000000000 +0100 -@@ -0,0 +1,490 @@ -+#include -+ -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define MPTCP_GW_MAX_LISTS 10 -+#define MPTCP_GW_LIST_MAX_LEN 6 -+#define MPTCP_GW_SYSCTL_MAX_LEN (15 * MPTCP_GW_LIST_MAX_LEN * \ -+ MPTCP_GW_MAX_LISTS) -+ -+struct mptcp_gw_list { -+ struct in_addr list[MPTCP_GW_MAX_LISTS][MPTCP_GW_LIST_MAX_LEN]; -+ u8 len[MPTCP_GW_MAX_LISTS]; -+}; -+ -+struct binder_priv { -+ /* Worker struct for subflow establishment */ -+ struct work_struct subflow_work; -+ -+ struct mptcp_cb *mpcb; -+ -+ /* Prevent multiple sub-sockets concurrently iterating over sockets */ -+ spinlock_t *flow_lock; -+}; -+ -+static struct mptcp_gw_list *mptcp_gws; -+static rwlock_t mptcp_gws_lock; -+ -+static int mptcp_binder_ndiffports __read_mostly = 1; -+ -+static char sysctl_mptcp_binder_gateways[MPTCP_GW_SYSCTL_MAX_LEN] __read_mostly; -+ -+static int mptcp_get_avail_list_ipv4(struct sock *sk) -+{ -+ int i, j, list_taken, opt_ret, opt_len; -+ unsigned char *opt_ptr, *opt_end_ptr, opt[MAX_IPOPTLEN]; -+ -+ for (i = 0; i < MPTCP_GW_MAX_LISTS; ++i) { -+ if (mptcp_gws->len[i] == 0) -+ goto error; -+ -+ mptcp_debug("mptcp_get_avail_list_ipv4: List %i\n", i); -+ list_taken = 0; -+ -+ /* Loop through all sub-sockets in this connection */ -+ mptcp_for_each_sk(tcp_sk(sk)->mpcb, sk) { -+ mptcp_debug("mptcp_get_avail_list_ipv4: Next sock\n"); -+ -+ /* Reset length and options buffer, then retrieve -+ * from socket -+ */ -+ opt_len = MAX_IPOPTLEN; -+ memset(opt, 0, MAX_IPOPTLEN); -+ opt_ret = ip_getsockopt(sk, IPPROTO_IP, -+ IP_OPTIONS, (char __user *)opt, (int __user *)&opt_len); -+ if (opt_ret < 0) { -+ mptcp_debug("%s: MPTCP subsocket getsockopt() IP_OPTIONS failed, error %d\n", -+ __func__, opt_ret); -+ goto error; -+ } -+ -+ /* If socket has no options, it has no stake in this list */ -+ if (opt_len <= 0) -+ continue; -+ -+ /* Iterate options buffer */ -+ for (opt_ptr = &opt[0]; opt_ptr < &opt[opt_len]; opt_ptr++) { -+ if (*opt_ptr == IPOPT_LSRR) { -+ mptcp_debug("mptcp_get_avail_list_ipv4: LSRR options found\n"); -+ goto sock_lsrr; -+ } -+ } -+ continue; -+ -+sock_lsrr: -+ /* Pointer to the 2nd to last address */ -+ opt_end_ptr = opt_ptr+(*(opt_ptr+1))-4; -+ -+ /* Addresses start 3 bytes after type offset */ -+ opt_ptr += 3; -+ j = 0; -+ -+ /* Different length lists cannot be the same */ -+ if ((opt_end_ptr-opt_ptr)/4 != mptcp_gws->len[i]) -+ continue; -+ -+ /* Iterate if we are still inside options list -+ * and sysctl list -+ */ -+ while (opt_ptr < opt_end_ptr && j < mptcp_gws->len[i]) { -+ /* If there is a different address, this list must -+ * not be set on this socket -+ */ -+ if (memcmp(&mptcp_gws->list[i][j], opt_ptr, 4)) -+ break; -+ -+ /* Jump 4 bytes to next address */ -+ opt_ptr += 4; -+ j++; -+ } -+ -+ /* Reached the end without a differing address, lists -+ * are therefore identical. -+ */ -+ if (j == mptcp_gws->len[i]) { -+ mptcp_debug("mptcp_get_avail_list_ipv4: List already used\n"); -+ list_taken = 1; -+ break; -+ } -+ } -+ -+ /* Free list found if not taken by a socket */ -+ if (!list_taken) { -+ mptcp_debug("mptcp_get_avail_list_ipv4: List free\n"); -+ break; -+ } -+ } -+ -+ if (i >= MPTCP_GW_MAX_LISTS) -+ goto error; -+ -+ return i; -+error: -+ return -1; -+} -+ -+/* The list of addresses is parsed each time a new connection is opened, -+ * to make sure it's up to date. In case of error, all the lists are -+ * marked as unavailable and the subflow's fingerprint is set to 0. -+ */ -+static void mptcp_v4_add_lsrr(struct sock *sk, struct in_addr addr) -+{ -+ int i, j, ret; -+ unsigned char opt[MAX_IPOPTLEN] = {0}; -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct binder_priv *fmp = (struct binder_priv *)&tp->mpcb->mptcp_pm[0]; -+ -+ /* Read lock: multiple sockets can read LSRR addresses at the same -+ * time, but writes are done in mutual exclusion. -+ * Spin lock: must search for free list for one socket at a time, or -+ * multiple sockets could take the same list. -+ */ -+ read_lock(&mptcp_gws_lock); -+ spin_lock(fmp->flow_lock); -+ -+ i = mptcp_get_avail_list_ipv4(sk); -+ -+ /* Execution enters here only if a free path is found. -+ */ -+ if (i >= 0) { -+ opt[0] = IPOPT_NOP; -+ opt[1] = IPOPT_LSRR; -+ opt[2] = sizeof(mptcp_gws->list[i][0].s_addr) * -+ (mptcp_gws->len[i] + 1) + 3; -+ opt[3] = IPOPT_MINOFF; -+ for (j = 0; j < mptcp_gws->len[i]; ++j) -+ memcpy(opt + 4 + -+ (j * sizeof(mptcp_gws->list[i][0].s_addr)), -+ &mptcp_gws->list[i][j].s_addr, -+ sizeof(mptcp_gws->list[i][0].s_addr)); -+ /* Final destination must be part of IP_OPTIONS parameter. */ -+ memcpy(opt + 4 + (j * sizeof(addr.s_addr)), &addr.s_addr, -+ sizeof(addr.s_addr)); -+ -+ /* setsockopt must be inside the lock, otherwise another -+ * subflow could fail to see that we have taken a list. -+ */ -+ ret = ip_setsockopt(sk, IPPROTO_IP, IP_OPTIONS, (char __user *)opt, -+ 4 + sizeof(mptcp_gws->list[i][0].s_addr) * (mptcp_gws->len[i] + 1)); -+ -+ if (ret < 0) { -+ mptcp_debug("%s: MPTCP subsock setsockopt() IP_OPTIONS failed, error %d\n", -+ __func__, ret); -+ } -+ } -+ -+ spin_unlock(fmp->flow_lock); -+ read_unlock(&mptcp_gws_lock); -+ -+ return; -+} -+ -+/* Parses gateways string for a list of paths to different -+ * gateways, and stores them for use with the Loose Source Routing (LSRR) -+ * socket option. Each list must have "," separated addresses, and the lists -+ * themselves must be separated by "-". Returns -1 in case one or more of the -+ * addresses is not a valid ipv4/6 address. -+ */ -+static int mptcp_parse_gateway_ipv4(char *gateways) -+{ -+ int i, j, k, ret; -+ char *tmp_string = NULL; -+ struct in_addr tmp_addr; -+ -+ tmp_string = kzalloc(16, GFP_KERNEL); -+ if (tmp_string == NULL) -+ return -ENOMEM; -+ -+ write_lock(&mptcp_gws_lock); -+ -+ memset(mptcp_gws, 0, sizeof(struct mptcp_gw_list)); -+ -+ /* A TMP string is used since inet_pton needs a null terminated string -+ * but we do not want to modify the sysctl for obvious reasons. -+ * i will iterate over the SYSCTL string, j will iterate over the -+ * temporary string where each IP is copied into, k will iterate over -+ * the IPs in each list. -+ */ -+ for (i = j = k = 0; -+ i < MPTCP_GW_SYSCTL_MAX_LEN && k < MPTCP_GW_MAX_LISTS; -+ ++i) { -+ if (gateways[i] == '-' || gateways[i] == ',' || gateways[i] == '\0') { -+ /* If the temp IP is empty and the current list is -+ * empty, we are done. -+ */ -+ if (j == 0 && mptcp_gws->len[k] == 0) -+ break; -+ -+ /* Terminate the temp IP string, then if it is -+ * non-empty parse the IP and copy it. -+ */ -+ tmp_string[j] = '\0'; -+ if (j > 0) { -+ mptcp_debug("mptcp_parse_gateway_list tmp: %s i: %d\n", tmp_string, i); -+ -+ ret = in4_pton(tmp_string, strlen(tmp_string), -+ (u8 *)&tmp_addr.s_addr, '\0', -+ NULL); -+ -+ if (ret) { -+ mptcp_debug("mptcp_parse_gateway_list ret: %d s_addr: %pI4\n", -+ ret, -+ &tmp_addr.s_addr); -+ memcpy(&mptcp_gws->list[k][mptcp_gws->len[k]].s_addr, -+ &tmp_addr.s_addr, -+ sizeof(tmp_addr.s_addr)); -+ mptcp_gws->len[k]++; -+ j = 0; -+ tmp_string[j] = '\0'; -+ /* Since we can't impose a limit to -+ * what the user can input, make sure -+ * there are not too many IPs in the -+ * SYSCTL string. -+ */ -+ if (mptcp_gws->len[k] > MPTCP_GW_LIST_MAX_LEN) { -+ mptcp_debug("mptcp_parse_gateway_list too many members in list %i: max %i\n", -+ k, -+ MPTCP_GW_LIST_MAX_LEN); -+ goto error; -+ } -+ } else { -+ goto error; -+ } -+ } -+ -+ if (gateways[i] == '-' || gateways[i] == '\0') -+ ++k; -+ } else { -+ tmp_string[j] = gateways[i]; -+ ++j; -+ } -+ } -+ -+ /* Number of flows is number of gateway lists plus master flow */ -+ mptcp_binder_ndiffports = k+1; -+ -+ write_unlock(&mptcp_gws_lock); -+ kfree(tmp_string); -+ -+ return 0; -+ -+error: -+ memset(mptcp_gws, 0, sizeof(struct mptcp_gw_list)); -+ memset(gateways, 0, sizeof(char) * MPTCP_GW_SYSCTL_MAX_LEN); -+ write_unlock(&mptcp_gws_lock); -+ kfree(tmp_string); -+ return -1; -+} -+ -+/** -+ * Create all new subflows, by doing calls to mptcp_initX_subsockets -+ * -+ * This function uses a goto next_subflow, to allow releasing the lock between -+ * new subflows and giving other processes a chance to do some work on the -+ * socket and potentially finishing the communication. -+ **/ -+static void create_subflow_worker(struct work_struct *work) -+{ -+ const struct binder_priv *pm_priv = container_of(work, -+ struct binder_priv, -+ subflow_work); -+ struct mptcp_cb *mpcb = pm_priv->mpcb; -+ struct sock *meta_sk = mpcb->meta_sk; -+ int iter = 0; -+ -+next_subflow: -+ if (iter) { -+ release_sock(meta_sk); -+ mutex_unlock(&mpcb->mpcb_mutex); -+ -+ cond_resched(); -+ } -+ mutex_lock(&mpcb->mpcb_mutex); -+ lock_sock_nested(meta_sk, SINGLE_DEPTH_NESTING); -+ -+ if (!mptcp(tcp_sk(meta_sk))) -+ goto exit; -+ -+ iter++; -+ -+ if (sock_flag(meta_sk, SOCK_DEAD)) -+ goto exit; -+ -+ if (mpcb->master_sk && -+ !tcp_sk(mpcb->master_sk)->mptcp->fully_established) -+ goto exit; -+ -+ if (mptcp_binder_ndiffports > iter && -+ mptcp_binder_ndiffports > mpcb->cnt_subflows) { -+ struct mptcp_loc4 loc; -+ struct mptcp_rem4 rem; -+ -+ loc.addr.s_addr = inet_sk(meta_sk)->inet_saddr; -+ loc.loc4_id = 0; -+ loc.low_prio = 0; -+ -+ rem.addr.s_addr = inet_sk(meta_sk)->inet_daddr; -+ rem.port = inet_sk(meta_sk)->inet_dport; -+ rem.rem4_id = 0; /* Default 0 */ -+ -+ mptcp_init4_subsockets(meta_sk, &loc, &rem); -+ -+ goto next_subflow; -+ } -+ -+exit: -+ release_sock(meta_sk); -+ mutex_unlock(&mpcb->mpcb_mutex); -+ mptcp_mpcb_put(mpcb); -+ sock_put(meta_sk); -+} -+ -+static void binder_new_session(const struct sock *meta_sk) -+{ -+ struct mptcp_cb *mpcb = tcp_sk(meta_sk)->mpcb; -+ struct binder_priv *fmp = (struct binder_priv *)&mpcb->mptcp_pm[0]; -+ static DEFINE_SPINLOCK(flow_lock); -+ -+#if IS_ENABLED(CONFIG_IPV6) -+ if (meta_sk->sk_family == AF_INET6 && -+ !mptcp_v6_is_v4_mapped(meta_sk)) { -+ mptcp_fallback_default(mpcb); -+ return; -+ } -+#endif -+ -+ /* Initialize workqueue-struct */ -+ INIT_WORK(&fmp->subflow_work, create_subflow_worker); -+ fmp->mpcb = mpcb; -+ -+ fmp->flow_lock = &flow_lock; -+} -+ -+static void binder_create_subflows(struct sock *meta_sk) -+{ -+ struct mptcp_cb *mpcb = tcp_sk(meta_sk)->mpcb; -+ struct binder_priv *pm_priv = (struct binder_priv *)&mpcb->mptcp_pm[0]; -+ -+ if (mptcp_in_infinite_mapping_weak(mpcb) || -+ mpcb->server_side || sock_flag(meta_sk, SOCK_DEAD)) -+ return; -+ -+ if (!work_pending(&pm_priv->subflow_work)) { -+ sock_hold(meta_sk); -+ atomic_inc(&mpcb->mpcb_refcnt); -+ queue_work(mptcp_wq, &pm_priv->subflow_work); -+ } -+} -+ -+static int binder_get_local_id(sa_family_t family, union inet_addr *addr, -+ struct net *net, bool *low_prio) -+{ -+ return 0; -+} -+ -+/* Callback functions, executed when syctl mptcp.mptcp_gateways is updated. -+ * Inspired from proc_tcp_congestion_control(). -+ */ -+static int proc_mptcp_gateways(struct ctl_table *ctl, int write, -+ void __user *buffer, size_t *lenp, -+ loff_t *ppos) -+{ -+ int ret; -+ struct ctl_table tbl = { -+ .maxlen = MPTCP_GW_SYSCTL_MAX_LEN, -+ }; -+ -+ if (write) { -+ tbl.data = kzalloc(MPTCP_GW_SYSCTL_MAX_LEN, GFP_KERNEL); -+ if (tbl.data == NULL) -+ return -ENOMEM; -+ ret = proc_dostring(&tbl, write, buffer, lenp, ppos); -+ if (ret == 0) { -+ ret = mptcp_parse_gateway_ipv4(tbl.data); -+ memcpy(ctl->data, tbl.data, MPTCP_GW_SYSCTL_MAX_LEN); -+ } -+ kfree(tbl.data); -+ } else { -+ ret = proc_dostring(ctl, write, buffer, lenp, ppos); -+ } -+ -+ -+ return ret; -+} -+ -+static struct mptcp_pm_ops binder __read_mostly = { -+ .new_session = binder_new_session, -+ .fully_established = binder_create_subflows, -+ .get_local_id = binder_get_local_id, -+ .init_subsocket_v4 = mptcp_v4_add_lsrr, -+ .name = "binder", -+ .owner = THIS_MODULE, -+}; -+ -+static struct ctl_table binder_table[] = { -+ { -+ .procname = "mptcp_binder_gateways", -+ .data = &sysctl_mptcp_binder_gateways, -+ .maxlen = sizeof(char) * MPTCP_GW_SYSCTL_MAX_LEN, -+ .mode = 0644, -+ .proc_handler = &proc_mptcp_gateways -+ }, -+ { } -+}; -+ -+static struct ctl_table_header *mptcp_sysctl_binder; -+ -+/* General initialization of MPTCP_PM */ -+static int __init binder_register(void) -+{ -+ mptcp_gws = kzalloc(sizeof(*mptcp_gws), GFP_KERNEL); -+ if (!mptcp_gws) -+ return -ENOMEM; -+ -+ rwlock_init(&mptcp_gws_lock); -+ -+ BUILD_BUG_ON(sizeof(struct binder_priv) > MPTCP_PM_SIZE); -+ -+ mptcp_sysctl_binder = register_net_sysctl(&init_net, "net/mptcp", -+ binder_table); -+ if (!mptcp_sysctl_binder) -+ goto sysctl_fail; -+ -+ if (mptcp_register_path_manager(&binder)) -+ goto pm_failed; -+ -+ return 0; -+ -+pm_failed: -+ unregister_net_sysctl_table(mptcp_sysctl_binder); -+sysctl_fail: -+ kfree(mptcp_gws); -+ -+ return -1; -+} -+ -+static void binder_unregister(void) -+{ -+ mptcp_unregister_path_manager(&binder); -+ unregister_net_sysctl_table(mptcp_sysctl_binder); -+ kfree(mptcp_gws); -+} -+ -+module_init(binder_register); -+module_exit(binder_unregister); -+ -+MODULE_AUTHOR("Luca Boccassi, Duncan Eastoe, Christoph Paasch (ndiffports)"); -+MODULE_LICENSE("GPL"); -+MODULE_DESCRIPTION("BINDER MPTCP"); -+MODULE_VERSION("0.1"); -diff -aurN linux-4.14.174/net/mptcp/mptcp_coupled.c mptcp-mptcp_v0.94/net/mptcp/mptcp_coupled.c ---- linux-4.14.174/net/mptcp/mptcp_coupled.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_v0.94/net/mptcp/mptcp_coupled.c 2020-03-23 09:45:33.000000000 +0100 -@@ -0,0 +1,271 @@ -+/* -+ * MPTCP implementation - Linked Increase congestion control Algorithm (LIA) -+ * -+ * Initial Design & Implementation: -+ * Sébastien Barré -+ * -+ * Current Maintainer & Author: -+ * Christoph Paasch -+ * -+ * Additional authors: -+ * Jaakko Korkeaniemi -+ * Gregory Detal -+ * Fabien Duchêne -+ * Andreas Seelinger -+ * Lavkesh Lahngir -+ * Andreas Ripke -+ * Vlad Dogaru -+ * Octavian Purdila -+ * John Ronan -+ * Catalin Nicutar -+ * Brandon Heller -+ * -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version -+ * 2 of the License, or (at your option) any later version. -+ */ -+#include -+#include -+ -+#include -+ -+/* Scaling is done in the numerator with alpha_scale_num and in the denominator -+ * with alpha_scale_den. -+ * -+ * To downscale, we just need to use alpha_scale. -+ * -+ * We have: alpha_scale = alpha_scale_num / (alpha_scale_den ^ 2) -+ */ -+static int alpha_scale_den = 10; -+static int alpha_scale_num = 32; -+static int alpha_scale = 12; -+ -+struct mptcp_ccc { -+ u64 alpha; -+ bool forced_update; -+}; -+ -+static inline int mptcp_ccc_sk_can_send(const struct sock *sk) -+{ -+ return mptcp_sk_can_send(sk) && tcp_sk(sk)->srtt_us; -+} -+ -+static inline u64 mptcp_get_alpha(const struct sock *meta_sk) -+{ -+ return ((struct mptcp_ccc *)inet_csk_ca(meta_sk))->alpha; -+} -+ -+static inline void mptcp_set_alpha(const struct sock *meta_sk, u64 alpha) -+{ -+ ((struct mptcp_ccc *)inet_csk_ca(meta_sk))->alpha = alpha; -+} -+ -+static inline u64 mptcp_ccc_scale(u32 val, int scale) -+{ -+ return (u64) val << scale; -+} -+ -+static inline bool mptcp_get_forced(const struct sock *meta_sk) -+{ -+ return ((struct mptcp_ccc *)inet_csk_ca(meta_sk))->forced_update; -+} -+ -+static inline void mptcp_set_forced(const struct sock *meta_sk, bool force) -+{ -+ ((struct mptcp_ccc *)inet_csk_ca(meta_sk))->forced_update = force; -+} -+ -+static void mptcp_ccc_recalc_alpha(const struct sock *sk) -+{ -+ const struct mptcp_cb *mpcb = tcp_sk(sk)->mpcb; -+ const struct sock *sub_sk; -+ int best_cwnd = 0, best_rtt = 0, can_send = 0; -+ u64 max_numerator = 0, sum_denominator = 0, alpha = 1; -+ -+ if (!mpcb) -+ return; -+ -+ /* Only one subflow left - fall back to normal reno-behavior -+ * (set alpha to 1) -+ */ -+ if (mpcb->cnt_established <= 1) -+ goto exit; -+ -+ /* Do regular alpha-calculation for multiple subflows */ -+ -+ /* Find the max numerator of the alpha-calculation */ -+ mptcp_for_each_sk(mpcb, sub_sk) { -+ struct tcp_sock *sub_tp = tcp_sk(sub_sk); -+ u64 tmp; -+ -+ if (!mptcp_ccc_sk_can_send(sub_sk)) -+ continue; -+ -+ can_send++; -+ -+ /* We need to look for the path, that provides the max-value. -+ * Integer-overflow is not possible here, because -+ * tmp will be in u64. -+ */ -+ tmp = div64_u64(mptcp_ccc_scale(sub_tp->snd_cwnd, -+ alpha_scale_num), (u64)sub_tp->srtt_us * sub_tp->srtt_us); -+ -+ if (tmp >= max_numerator) { -+ max_numerator = tmp; -+ best_cwnd = sub_tp->snd_cwnd; -+ best_rtt = sub_tp->srtt_us; -+ } -+ } -+ -+ /* No subflow is able to send - we don't care anymore */ -+ if (unlikely(!can_send)) -+ goto exit; -+ -+ /* Calculate the denominator */ -+ mptcp_for_each_sk(mpcb, sub_sk) { -+ struct tcp_sock *sub_tp = tcp_sk(sub_sk); -+ -+ if (!mptcp_ccc_sk_can_send(sub_sk)) -+ continue; -+ -+ sum_denominator += div_u64( -+ mptcp_ccc_scale(sub_tp->snd_cwnd, -+ alpha_scale_den) * best_rtt, -+ sub_tp->srtt_us); -+ } -+ sum_denominator *= sum_denominator; -+ if (unlikely(!sum_denominator)) { -+ pr_err("%s: sum_denominator == 0, cnt_established:%d\n", -+ __func__, mpcb->cnt_established); -+ mptcp_for_each_sk(mpcb, sub_sk) { -+ struct tcp_sock *sub_tp = tcp_sk(sub_sk); -+ pr_err("%s: pi:%d, state:%d\n, rtt:%u, cwnd: %u", -+ __func__, sub_tp->mptcp->path_index, -+ sub_sk->sk_state, sub_tp->srtt_us, -+ sub_tp->snd_cwnd); -+ } -+ } -+ -+ alpha = div64_u64(mptcp_ccc_scale(best_cwnd, alpha_scale_num), sum_denominator); -+ -+ if (unlikely(!alpha)) -+ alpha = 1; -+ -+exit: -+ mptcp_set_alpha(mptcp_meta_sk(sk), alpha); -+} -+ -+static void mptcp_ccc_init(struct sock *sk) -+{ -+ if (mptcp(tcp_sk(sk))) { -+ mptcp_set_forced(mptcp_meta_sk(sk), 0); -+ mptcp_set_alpha(mptcp_meta_sk(sk), 1); -+ } -+ /* If we do not mptcp, behave like reno: return */ -+} -+ -+static void mptcp_ccc_cwnd_event(struct sock *sk, enum tcp_ca_event event) -+{ -+ if (event == CA_EVENT_LOSS) -+ mptcp_ccc_recalc_alpha(sk); -+} -+ -+static void mptcp_ccc_set_state(struct sock *sk, u8 ca_state) -+{ -+ if (!mptcp(tcp_sk(sk))) -+ return; -+ -+ mptcp_set_forced(mptcp_meta_sk(sk), 1); -+} -+ -+static void mptcp_ccc_cong_avoid(struct sock *sk, u32 ack, u32 acked) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ const struct mptcp_cb *mpcb = tp->mpcb; -+ int snd_cwnd; -+ -+ if (!mptcp(tp)) { -+ tcp_reno_cong_avoid(sk, ack, acked); -+ return; -+ } -+ -+ if (!tcp_is_cwnd_limited(sk)) -+ return; -+ -+ if (tcp_in_slow_start(tp)) { -+ /* In "safe" area, increase. */ -+ tcp_slow_start(tp, acked); -+ mptcp_ccc_recalc_alpha(sk); -+ return; -+ } -+ -+ if (mptcp_get_forced(mptcp_meta_sk(sk))) { -+ mptcp_ccc_recalc_alpha(sk); -+ mptcp_set_forced(mptcp_meta_sk(sk), 0); -+ } -+ -+ if (mpcb->cnt_established > 1) { -+ u64 alpha = mptcp_get_alpha(mptcp_meta_sk(sk)); -+ -+ /* This may happen, if at the initialization, the mpcb -+ * was not yet attached to the sock, and thus -+ * initializing alpha failed. -+ */ -+ if (unlikely(!alpha)) -+ alpha = 1; -+ -+ snd_cwnd = (int) div_u64 ((u64) mptcp_ccc_scale(1, alpha_scale), -+ alpha); -+ -+ /* snd_cwnd_cnt >= max (scale * tot_cwnd / alpha, cwnd) -+ * Thus, we select here the max value. -+ */ -+ if (snd_cwnd < tp->snd_cwnd) -+ snd_cwnd = tp->snd_cwnd; -+ } else { -+ snd_cwnd = tp->snd_cwnd; -+ } -+ -+ if (tp->snd_cwnd_cnt >= snd_cwnd) { -+ if (tp->snd_cwnd < tp->snd_cwnd_clamp) { -+ tp->snd_cwnd++; -+ mptcp_ccc_recalc_alpha(sk); -+ } -+ -+ tp->snd_cwnd_cnt = 0; -+ } else { -+ tp->snd_cwnd_cnt++; -+ } -+} -+ -+static struct tcp_congestion_ops mptcp_ccc = { -+ .init = mptcp_ccc_init, -+ .ssthresh = tcp_reno_ssthresh, -+ .cong_avoid = mptcp_ccc_cong_avoid, -+ .undo_cwnd = tcp_reno_undo_cwnd, -+ .cwnd_event = mptcp_ccc_cwnd_event, -+ .set_state = mptcp_ccc_set_state, -+ .owner = THIS_MODULE, -+ .name = "lia", -+}; -+ -+static int __init mptcp_ccc_register(void) -+{ -+ BUILD_BUG_ON(sizeof(struct mptcp_ccc) > ICSK_CA_PRIV_SIZE); -+ return tcp_register_congestion_control(&mptcp_ccc); -+} -+ -+static void __exit mptcp_ccc_unregister(void) -+{ -+ tcp_unregister_congestion_control(&mptcp_ccc); -+} -+ -+module_init(mptcp_ccc_register); -+module_exit(mptcp_ccc_unregister); -+ -+MODULE_AUTHOR("Christoph Paasch, Sébastien Barré"); -+MODULE_LICENSE("GPL"); -+MODULE_DESCRIPTION("MPTCP LINKED INCREASE CONGESTION CONTROL ALGORITHM"); -+MODULE_VERSION("0.1"); -diff -aurN linux-4.14.174/net/mptcp/mptcp_ctrl.c mptcp-mptcp_v0.94/net/mptcp/mptcp_ctrl.c ---- linux-4.14.174/net/mptcp/mptcp_ctrl.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_v0.94/net/mptcp/mptcp_ctrl.c 2020-03-23 09:45:33.000000000 +0100 -@@ -0,0 +1,3038 @@ -+/* -+ * MPTCP implementation - MPTCP-control -+ * -+ * Initial Design & Implementation: -+ * Sébastien Barré -+ * -+ * Current Maintainer & Author: -+ * Christoph Paasch -+ * -+ * Additional authors: -+ * Jaakko Korkeaniemi -+ * Gregory Detal -+ * Fabien Duchêne -+ * Andreas Seelinger -+ * Lavkesh Lahngir -+ * Andreas Ripke -+ * Vlad Dogaru -+ * Octavian Purdila -+ * John Ronan -+ * Catalin Nicutar -+ * Brandon Heller -+ * -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version -+ * 2 of the License, or (at your option) any later version. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#if IS_ENABLED(CONFIG_IPV6) -+#include -+#include -+#endif -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+static struct kmem_cache *mptcp_sock_cache __read_mostly; -+static struct kmem_cache *mptcp_cb_cache __read_mostly; -+static struct kmem_cache *mptcp_tw_cache __read_mostly; -+ -+int sysctl_mptcp_enabled __read_mostly = 1; -+EXPORT_SYMBOL(sysctl_mptcp_enabled); -+int sysctl_mptcp_version __read_mostly = 0; -+static int min_mptcp_version; -+static int max_mptcp_version = 1; -+int sysctl_mptcp_checksum __read_mostly = 1; -+int sysctl_mptcp_debug __read_mostly; -+EXPORT_SYMBOL(sysctl_mptcp_debug); -+int sysctl_mptcp_syn_retries __read_mostly = 3; -+ -+bool mptcp_init_failed __read_mostly; -+ -+struct static_key mptcp_static_key = STATIC_KEY_INIT_FALSE; -+EXPORT_SYMBOL(mptcp_static_key); -+ -+static int proc_mptcp_path_manager(struct ctl_table *ctl, int write, -+ void __user *buffer, size_t *lenp, -+ loff_t *ppos) -+{ -+ char val[MPTCP_PM_NAME_MAX]; -+ struct ctl_table tbl = { -+ .data = val, -+ .maxlen = MPTCP_PM_NAME_MAX, -+ }; -+ int ret; -+ -+ mptcp_get_default_path_manager(val); -+ -+ ret = proc_dostring(&tbl, write, buffer, lenp, ppos); -+ if (write && ret == 0) -+ ret = mptcp_set_default_path_manager(val); -+ return ret; -+} -+ -+static int proc_mptcp_scheduler(struct ctl_table *ctl, int write, -+ void __user *buffer, size_t *lenp, -+ loff_t *ppos) -+{ -+ char val[MPTCP_SCHED_NAME_MAX]; -+ struct ctl_table tbl = { -+ .data = val, -+ .maxlen = MPTCP_SCHED_NAME_MAX, -+ }; -+ int ret; -+ -+ mptcp_get_default_scheduler(val); -+ -+ ret = proc_dostring(&tbl, write, buffer, lenp, ppos); -+ if (write && ret == 0) -+ ret = mptcp_set_default_scheduler(val); -+ return ret; -+} -+ -+static struct ctl_table mptcp_table[] = { -+ { -+ .procname = "mptcp_enabled", -+ .data = &sysctl_mptcp_enabled, -+ .maxlen = sizeof(int), -+ .mode = 0644, -+ .proc_handler = &proc_dointvec -+ }, -+ { -+ .procname = "mptcp_version", -+ .data = &sysctl_mptcp_version, -+ .mode = 0644, -+ .maxlen = sizeof(int), -+ .proc_handler = &proc_dointvec_minmax, -+ .extra1 = &min_mptcp_version, -+ .extra2 = &max_mptcp_version, -+ }, -+ { -+ .procname = "mptcp_checksum", -+ .data = &sysctl_mptcp_checksum, -+ .maxlen = sizeof(int), -+ .mode = 0644, -+ .proc_handler = &proc_dointvec -+ }, -+ { -+ .procname = "mptcp_debug", -+ .data = &sysctl_mptcp_debug, -+ .maxlen = sizeof(int), -+ .mode = 0644, -+ .proc_handler = &proc_dointvec -+ }, -+ { -+ .procname = "mptcp_syn_retries", -+ .data = &sysctl_mptcp_syn_retries, -+ .maxlen = sizeof(int), -+ .mode = 0644, -+ .proc_handler = &proc_dointvec -+ }, -+ { -+ .procname = "mptcp_path_manager", -+ .mode = 0644, -+ .maxlen = MPTCP_PM_NAME_MAX, -+ .proc_handler = proc_mptcp_path_manager, -+ }, -+ { -+ .procname = "mptcp_scheduler", -+ .mode = 0644, -+ .maxlen = MPTCP_SCHED_NAME_MAX, -+ .proc_handler = proc_mptcp_scheduler, -+ }, -+ { } -+}; -+ -+static inline u32 mptcp_hash_tk(u32 token) -+{ -+ return token % MPTCP_HASH_SIZE; -+} -+ -+struct hlist_nulls_head tk_hashtable[MPTCP_HASH_SIZE]; -+EXPORT_SYMBOL(tk_hashtable); -+ -+/* The following hash table is used to avoid collision of token */ -+static struct hlist_nulls_head mptcp_reqsk_tk_htb[MPTCP_HASH_SIZE]; -+ -+/* Lock, protecting the two hash-tables that hold the token. Namely, -+ * mptcp_reqsk_tk_htb and tk_hashtable -+ */ -+static spinlock_t mptcp_tk_hashlock; -+ -+static bool mptcp_reqsk_find_tk(const u32 token) -+{ -+ const u32 hash = mptcp_hash_tk(token); -+ const struct mptcp_request_sock *mtreqsk; -+ const struct hlist_nulls_node *node; -+ -+begin: -+ hlist_nulls_for_each_entry_rcu(mtreqsk, node, -+ &mptcp_reqsk_tk_htb[hash], hash_entry) { -+ if (token == mtreqsk->mptcp_loc_token) -+ return true; -+ } -+ /* A request-socket is destroyed by RCU. So, it might have been recycled -+ * and put into another hash-table list. So, after the lookup we may -+ * end up in a different list. So, we may need to restart. -+ * -+ * See also the comment in __inet_lookup_established. -+ */ -+ if (get_nulls_value(node) != hash) -+ goto begin; -+ return false; -+} -+ -+static void mptcp_reqsk_insert_tk(struct request_sock *reqsk, const u32 token) -+{ -+ u32 hash = mptcp_hash_tk(token); -+ -+ hlist_nulls_add_head_rcu(&mptcp_rsk(reqsk)->hash_entry, -+ &mptcp_reqsk_tk_htb[hash]); -+} -+ -+static void mptcp_reqsk_remove_tk(const struct request_sock *reqsk) -+{ -+ rcu_read_lock(); -+ local_bh_disable(); -+ spin_lock(&mptcp_tk_hashlock); -+ hlist_nulls_del_init_rcu(&mptcp_rsk(reqsk)->hash_entry); -+ spin_unlock(&mptcp_tk_hashlock); -+ local_bh_enable(); -+ rcu_read_unlock(); -+} -+ -+void mptcp_reqsk_destructor(struct request_sock *req) -+{ -+ if (!mptcp_rsk(req)->is_sub) -+ mptcp_reqsk_remove_tk(req); -+} -+ -+static void __mptcp_hash_insert(struct tcp_sock *meta_tp, const u32 token) -+{ -+ u32 hash = mptcp_hash_tk(token); -+ hlist_nulls_add_head_rcu(&meta_tp->tk_table, &tk_hashtable[hash]); -+ meta_tp->inside_tk_table = 1; -+} -+ -+static bool mptcp_find_token(u32 token) -+{ -+ const u32 hash = mptcp_hash_tk(token); -+ const struct tcp_sock *meta_tp; -+ const struct hlist_nulls_node *node; -+ -+begin: -+ hlist_nulls_for_each_entry_rcu(meta_tp, node, &tk_hashtable[hash], tk_table) { -+ if (token == meta_tp->mptcp_loc_token) -+ return true; -+ } -+ /* A TCP-socket is destroyed by RCU. So, it might have been recycled -+ * and put into another hash-table list. So, after the lookup we may -+ * end up in a different list. So, we may need to restart. -+ * -+ * See also the comment in __inet_lookup_established. -+ */ -+ if (get_nulls_value(node) != hash) -+ goto begin; -+ return false; -+} -+ -+static void mptcp_set_key_reqsk(struct request_sock *req, -+ const struct sk_buff *skb, -+ u32 seed) -+{ -+ const struct inet_request_sock *ireq = inet_rsk(req); -+ struct mptcp_request_sock *mtreq = mptcp_rsk(req); -+ -+ if (skb->protocol == htons(ETH_P_IP)) { -+ mtreq->mptcp_loc_key = mptcp_v4_get_key(ip_hdr(skb)->saddr, -+ ip_hdr(skb)->daddr, -+ htons(ireq->ir_num), -+ ireq->ir_rmt_port, -+ seed); -+#if IS_ENABLED(CONFIG_IPV6) -+ } else { -+ mtreq->mptcp_loc_key = mptcp_v6_get_key(ipv6_hdr(skb)->saddr.s6_addr32, -+ ipv6_hdr(skb)->daddr.s6_addr32, -+ htons(ireq->ir_num), -+ ireq->ir_rmt_port, -+ seed); -+#endif -+ } -+ -+ mptcp_key_sha1(mtreq->mptcp_loc_key, &mtreq->mptcp_loc_token, NULL); -+} -+ -+/* New MPTCP-connection request, prepare a new token for the meta-socket that -+ * will be created in mptcp_check_req_master(), and store the received token. -+ */ -+static void mptcp_reqsk_new_mptcp(struct request_sock *req, -+ const struct sock *sk, -+ const struct mptcp_options_received *mopt, -+ const struct sk_buff *skb) -+{ -+ struct mptcp_request_sock *mtreq = mptcp_rsk(req); -+ const struct tcp_sock *tp = tcp_sk(sk); -+ -+ inet_rsk(req)->saw_mpc = 1; -+ -+ /* MPTCP version agreement */ -+ if (mopt->mptcp_ver >= tp->mptcp_ver) -+ mtreq->mptcp_ver = tp->mptcp_ver; -+ else -+ mtreq->mptcp_ver = mopt->mptcp_ver; -+ -+ rcu_read_lock(); -+ local_bh_disable(); -+ spin_lock(&mptcp_tk_hashlock); -+ do { -+ mptcp_set_key_reqsk(req, skb, mptcp_seed++); -+ } while (mptcp_reqsk_find_tk(mtreq->mptcp_loc_token) || -+ mptcp_find_token(mtreq->mptcp_loc_token)); -+ mptcp_reqsk_insert_tk(req, mtreq->mptcp_loc_token); -+ spin_unlock(&mptcp_tk_hashlock); -+ local_bh_enable(); -+ rcu_read_unlock(); -+ mtreq->mptcp_rem_key = mopt->mptcp_sender_key; -+} -+ -+static int mptcp_reqsk_new_cookie(struct request_sock *req, -+ const struct sock *sk, -+ const struct mptcp_options_received *mopt, -+ const struct sk_buff *skb) -+{ -+ struct mptcp_request_sock *mtreq = mptcp_rsk(req); -+ -+ /* MPTCP version agreement */ -+ if (mopt->mptcp_ver >= tcp_sk(sk)->mptcp_ver) -+ mtreq->mptcp_ver = tcp_sk(sk)->mptcp_ver; -+ else -+ mtreq->mptcp_ver = mopt->mptcp_ver; -+ -+ rcu_read_lock(); -+ local_bh_disable(); -+ spin_lock(&mptcp_tk_hashlock); -+ -+ mptcp_set_key_reqsk(req, skb, tcp_rsk(req)->snt_isn); -+ -+ if (mptcp_reqsk_find_tk(mtreq->mptcp_loc_token) || -+ mptcp_find_token(mtreq->mptcp_loc_token)) { -+ spin_unlock(&mptcp_tk_hashlock); -+ local_bh_enable(); -+ rcu_read_unlock(); -+ return false; -+ } -+ -+ inet_rsk(req)->saw_mpc = 1; -+ -+ spin_unlock(&mptcp_tk_hashlock); -+ local_bh_enable(); -+ rcu_read_unlock(); -+ -+ mtreq->mptcp_rem_key = mopt->mptcp_sender_key; -+ -+ return true; -+} -+ -+static void mptcp_set_key_sk(const struct sock *sk) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ const struct inet_sock *isk = inet_sk(sk); -+ -+ if (sk->sk_family == AF_INET) -+ tp->mptcp_loc_key = mptcp_v4_get_key(isk->inet_saddr, -+ isk->inet_daddr, -+ isk->inet_sport, -+ isk->inet_dport, -+ mptcp_seed++); -+#if IS_ENABLED(CONFIG_IPV6) -+ else -+ tp->mptcp_loc_key = mptcp_v6_get_key(inet6_sk(sk)->saddr.s6_addr32, -+ sk->sk_v6_daddr.s6_addr32, -+ isk->inet_sport, -+ isk->inet_dport, -+ mptcp_seed++); -+#endif -+ -+ mptcp_key_sha1(tp->mptcp_loc_key, -+ &tp->mptcp_loc_token, NULL); -+} -+ -+#ifdef HAVE_JUMP_LABEL -+static atomic_t mptcp_needed_deferred; -+static atomic_t mptcp_wanted; -+ -+static void mptcp_clear(struct work_struct *work) -+{ -+ int deferred = atomic_xchg(&mptcp_needed_deferred, 0); -+ int wanted; -+ -+ wanted = atomic_add_return(deferred, &mptcp_wanted); -+ if (wanted > 0) -+ static_key_enable(&mptcp_static_key); -+ else -+ static_key_disable(&mptcp_static_key); -+} -+ -+static DECLARE_WORK(mptcp_work, mptcp_clear); -+#endif -+ -+static void mptcp_enable_static_key_bh(void) -+{ -+#ifdef HAVE_JUMP_LABEL -+ int wanted; -+ -+ while (1) { -+ wanted = atomic_read(&mptcp_wanted); -+ if (wanted <= 0) -+ break; -+ if (atomic_cmpxchg(&mptcp_wanted, wanted, wanted + 1) == wanted) -+ return; -+ } -+ atomic_inc(&mptcp_needed_deferred); -+ schedule_work(&mptcp_work); -+#else -+ static_key_slow_inc(&mptcp_static_key); -+#endif -+} -+ -+static void mptcp_enable_static_key(void) -+{ -+#ifdef HAVE_JUMP_LABEL -+ atomic_inc(&mptcp_wanted); -+ static_key_enable(&mptcp_static_key); -+#else -+ static_key_slow_inc(&mptcp_static_key); -+#endif -+} -+ -+void mptcp_disable_static_key(void) -+{ -+#ifdef HAVE_JUMP_LABEL -+ int wanted; -+ -+ while (1) { -+ wanted = atomic_read(&mptcp_wanted); -+ if (wanted <= 1) -+ break; -+ if (atomic_cmpxchg(&mptcp_wanted, wanted, wanted - 1) == wanted) -+ return; -+ } -+ atomic_dec(&mptcp_needed_deferred); -+ schedule_work(&mptcp_work); -+#else -+ static_key_slow_dec(&mptcp_static_key); -+#endif -+} -+ -+void mptcp_enable_sock(struct sock *sk) -+{ -+ if (!sock_flag(sk, SOCK_MPTCP)) { -+ sock_set_flag(sk, SOCK_MPTCP); -+ tcp_sk(sk)->mptcp_ver = sysctl_mptcp_version; -+ -+ /* Necessary here, because MPTCP can be enabled/disabled through -+ * a setsockopt. -+ */ -+ if (sk->sk_family == AF_INET) -+ inet_csk(sk)->icsk_af_ops = &mptcp_v4_specific; -+#if IS_ENABLED(CONFIG_IPV6) -+ else if (mptcp_v6_is_v4_mapped(sk)) -+ inet_csk(sk)->icsk_af_ops = &mptcp_v6_mapped; -+ else -+ inet_csk(sk)->icsk_af_ops = &mptcp_v6_specific; -+#endif -+ -+ mptcp_enable_static_key(); -+ } -+} -+ -+void mptcp_disable_sock(struct sock *sk) -+{ -+ if (sock_flag(sk, SOCK_MPTCP)) { -+ sock_reset_flag(sk, SOCK_MPTCP); -+ -+ /* Necessary here, because MPTCP can be enabled/disabled through -+ * a setsockopt. -+ */ -+ if (sk->sk_family == AF_INET) -+ inet_csk(sk)->icsk_af_ops = &ipv4_specific; -+#if IS_ENABLED(CONFIG_IPV6) -+ else if (mptcp_v6_is_v4_mapped(sk)) -+ inet_csk(sk)->icsk_af_ops = &ipv6_mapped; -+ else -+ inet_csk(sk)->icsk_af_ops = &ipv6_specific; -+#endif -+ -+ mptcp_disable_static_key(); -+ } -+} -+ -+void mptcp_connect_init(struct sock *sk) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ -+ rcu_read_lock(); -+ local_bh_disable(); -+ spin_lock(&mptcp_tk_hashlock); -+ do { -+ mptcp_set_key_sk(sk); -+ } while (mptcp_reqsk_find_tk(tp->mptcp_loc_token) || -+ mptcp_find_token(tp->mptcp_loc_token)); -+ -+ __mptcp_hash_insert(tp, tp->mptcp_loc_token); -+ spin_unlock(&mptcp_tk_hashlock); -+ local_bh_enable(); -+ rcu_read_unlock(); -+ -+ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_MPCAPABLEACTIVE); -+} -+ -+/** -+ * This function increments the refcount of the mpcb struct. -+ * It is the responsibility of the caller to decrement when releasing -+ * the structure. -+ */ -+struct sock *mptcp_hash_find(const struct net *net, const u32 token) -+{ -+ const u32 hash = mptcp_hash_tk(token); -+ const struct tcp_sock *meta_tp; -+ struct sock *meta_sk = NULL; -+ const struct hlist_nulls_node *node; -+ -+ rcu_read_lock(); -+ local_bh_disable(); -+begin: -+ hlist_nulls_for_each_entry_rcu(meta_tp, node, &tk_hashtable[hash], -+ tk_table) { -+ meta_sk = (struct sock *)meta_tp; -+ if (token == meta_tp->mptcp_loc_token && -+ net_eq(net, sock_net(meta_sk))) { -+ if (unlikely(!refcount_inc_not_zero(&meta_sk->sk_refcnt))) -+ goto out; -+ if (unlikely(token != meta_tp->mptcp_loc_token || -+ !net_eq(net, sock_net(meta_sk)))) { -+ sock_gen_put(meta_sk); -+ goto begin; -+ } -+ goto found; -+ } -+ } -+ /* A TCP-socket is destroyed by RCU. So, it might have been recycled -+ * and put into another hash-table list. So, after the lookup we may -+ * end up in a different list. So, we may need to restart. -+ * -+ * See also the comment in __inet_lookup_established. -+ */ -+ if (get_nulls_value(node) != hash) -+ goto begin; -+out: -+ meta_sk = NULL; -+found: -+ local_bh_enable(); -+ rcu_read_unlock(); -+ return meta_sk; -+} -+ -+void mptcp_hash_remove_bh(struct tcp_sock *meta_tp) -+{ -+ /* remove from the token hashtable */ -+ rcu_read_lock(); -+ local_bh_disable(); -+ spin_lock(&mptcp_tk_hashlock); -+ hlist_nulls_del_init_rcu(&meta_tp->tk_table); -+ meta_tp->inside_tk_table = 0; -+ spin_unlock(&mptcp_tk_hashlock); -+ local_bh_enable(); -+ rcu_read_unlock(); -+} -+ -+struct sock *mptcp_select_ack_sock(const struct sock *meta_sk) -+{ -+ const struct tcp_sock *meta_tp = tcp_sk(meta_sk); -+ struct sock *sk, *rttsk = NULL, *lastsk = NULL; -+ u32 min_time = 0, last_active = 0; -+ -+ mptcp_for_each_sk(meta_tp->mpcb, sk) { -+ struct tcp_sock *tp = tcp_sk(sk); -+ u32 elapsed; -+ -+ if (!mptcp_sk_can_send_ack(sk) || tp->pf) -+ continue; -+ -+ elapsed = keepalive_time_elapsed(tp); -+ -+ /* We take the one with the lowest RTT within a reasonable -+ * (meta-RTO)-timeframe -+ */ -+ if (elapsed < inet_csk(meta_sk)->icsk_rto) { -+ if (!min_time || tp->srtt_us < min_time) { -+ min_time = tp->srtt_us; -+ rttsk = sk; -+ } -+ continue; -+ } -+ -+ /* Otherwise, we just take the most recent active */ -+ if (!rttsk && (!last_active || elapsed < last_active)) { -+ last_active = elapsed; -+ lastsk = sk; -+ } -+ } -+ -+ if (rttsk) -+ return rttsk; -+ -+ return lastsk; -+} -+EXPORT_SYMBOL(mptcp_select_ack_sock); -+ -+static void mptcp_sock_def_error_report(struct sock *sk) -+{ -+ const struct mptcp_cb *mpcb = tcp_sk(sk)->mpcb; -+ struct sock *meta_sk = mptcp_meta_sk(sk); -+ struct tcp_sock *tp = tcp_sk(sk); -+ -+ if (!sock_flag(sk, SOCK_DEAD)) { -+ if (tp->send_mp_fclose && sk->sk_err == ETIMEDOUT) { -+ /* Called by the keep alive timer (tcp_write_timeout), -+ * when the limit of fastclose retransmissions has been -+ * reached. Send a TCP RST to clear the status of any -+ * stateful firewall (typically conntrack) which are -+ * not aware of mptcp and cannot understand the -+ * fastclose option. -+ */ -+ tp->ops->send_active_reset(sk, GFP_ATOMIC); -+ } -+ } -+ -+ if (!tp->tcp_disconnect && mptcp_in_infinite_mapping_weak(mpcb)) { -+ meta_sk->sk_err = sk->sk_err; -+ meta_sk->sk_err_soft = sk->sk_err_soft; -+ -+ if (!sock_flag(meta_sk, SOCK_DEAD)) -+ meta_sk->sk_error_report(meta_sk); -+ -+ WARN(meta_sk->sk_state == TCP_CLOSE, -+ "Meta already closed i_rcv %u i_snd %u send_i %u flags %#lx\n", -+ mpcb->infinite_mapping_rcv, mpcb->infinite_mapping_snd, -+ mpcb->send_infinite_mapping, meta_sk->sk_flags); -+ -+ if (meta_sk->sk_state != TCP_CLOSE) -+ tcp_done(meta_sk); -+ } -+ -+ if (mpcb->pm_ops->subflow_error) -+ mpcb->pm_ops->subflow_error(meta_sk, sk); -+ -+ sk->sk_err = 0; -+ return; -+} -+ -+void mptcp_mpcb_put(struct mptcp_cb *mpcb) -+{ -+ if (atomic_dec_and_test(&mpcb->mpcb_refcnt)) { -+ mptcp_cleanup_path_manager(mpcb); -+ mptcp_cleanup_scheduler(mpcb); -+ kfree(mpcb->master_info); -+ kmem_cache_free(mptcp_cb_cache, mpcb); -+ } -+} -+EXPORT_SYMBOL(mptcp_mpcb_put); -+ -+static void mptcp_mpcb_cleanup(struct mptcp_cb *mpcb) -+{ -+ struct mptcp_tw *mptw; -+ -+ /* The mpcb is disappearing - we can make the final -+ * update to the rcv_nxt of the time-wait-sock and remove -+ * its reference to the mpcb. -+ */ -+ spin_lock_bh(&mpcb->tw_lock); -+ list_for_each_entry_rcu(mptw, &mpcb->tw_list, list) { -+ list_del_rcu(&mptw->list); -+ mptw->in_list = 0; -+ mptcp_mpcb_put(mpcb); -+ rcu_assign_pointer(mptw->mpcb, NULL); -+ } -+ spin_unlock_bh(&mpcb->tw_lock); -+ -+ mptcp_mpcb_put(mpcb); -+} -+ -+static void mptcp_sock_destruct(struct sock *sk) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ -+ if (!is_meta_sk(sk)) { -+ BUG_ON(!hlist_unhashed(&tp->mptcp->cb_list)); -+ -+ kmem_cache_free(mptcp_sock_cache, tp->mptcp); -+ tp->mptcp = NULL; -+ -+ /* Taken when mpcb pointer was set */ -+ sock_put(mptcp_meta_sk(sk)); -+ mptcp_mpcb_put(tp->mpcb); -+ } else { -+ mptcp_debug("%s destroying meta-sk token %#x\n", __func__, -+ tcp_sk(sk)->mpcb->mptcp_loc_token); -+ -+ mptcp_mpcb_cleanup(tp->mpcb); -+ } -+ -+ WARN_ON(!static_key_false(&mptcp_static_key)); -+ -+ /* Must be called here, because this will decrement the jump-label. */ -+ inet_sock_destruct(sk); -+} -+ -+void mptcp_destroy_sock(struct sock *sk) -+{ -+ if (is_meta_sk(sk)) { -+ struct sock *sk_it, *tmpsk; -+ -+ __skb_queue_purge(&tcp_sk(sk)->mpcb->reinject_queue); -+ -+ /* We have to close all remaining subflows. Normally, they -+ * should all be about to get closed. But, if the kernel is -+ * forcing a closure (e.g., tcp_write_err), the subflows might -+ * not have been closed properly (as we are waiting for the -+ * DATA_ACK of the DATA_FIN). -+ */ -+ mptcp_for_each_sk_safe(tcp_sk(sk)->mpcb, sk_it, tmpsk) { -+ /* Already did call tcp_close - waiting for graceful -+ * closure, or if we are retransmitting fast-close on -+ * the subflow. The reset (or timeout) will kill the -+ * subflow.. -+ */ -+ if (tcp_sk(sk_it)->closing || -+ tcp_sk(sk_it)->send_mp_fclose) -+ continue; -+ -+ /* Allow the delayed work first to prevent time-wait state */ -+ if (delayed_work_pending(&tcp_sk(sk_it)->mptcp->work)) -+ continue; -+ -+ mptcp_sub_close(sk_it, 0); -+ } -+ } else { -+ mptcp_del_sock(sk); -+ } -+} -+ -+static void mptcp_set_state(struct sock *sk) -+{ -+ struct sock *meta_sk = mptcp_meta_sk(sk); -+ -+ /* Meta is not yet established - wake up the application */ -+ if ((1 << meta_sk->sk_state) & (TCPF_SYN_SENT | TCPF_SYN_RECV) && -+ sk->sk_state == TCP_ESTABLISHED) { -+ tcp_set_state(meta_sk, TCP_ESTABLISHED); -+ -+ if (!sock_flag(meta_sk, SOCK_DEAD)) { -+ meta_sk->sk_state_change(meta_sk); -+ sk_wake_async(meta_sk, SOCK_WAKE_IO, POLL_OUT); -+ } -+ -+ tcp_sk(meta_sk)->lsndtime = tcp_jiffies32; -+ } -+ -+ if (sk->sk_state == TCP_ESTABLISHED) { -+ tcp_sk(sk)->mptcp->establish_increased = 1; -+ tcp_sk(sk)->mpcb->cnt_established++; -+ } -+ -+ if (sk->sk_state == TCP_CLOSE) { -+ if (!sock_flag(sk, SOCK_DEAD)) -+ mptcp_sub_close(sk, 0); -+ } -+} -+ -+static int mptcp_set_congestion_control(struct sock *meta_sk, const char *name, -+ bool load, bool reinit, bool cap_net_admin) -+{ -+ int err, result = 0; -+ struct sock *sk_it; -+ -+ result = __tcp_set_congestion_control(meta_sk, name, load, reinit, cap_net_admin); -+ -+ tcp_sk(meta_sk)->mpcb->tcp_ca_explicit_set = true; -+ -+ mptcp_for_each_sk(tcp_sk(meta_sk)->mpcb, sk_it) { -+ err = __tcp_set_congestion_control(sk_it, name, load, reinit, cap_net_admin); -+ if (err) -+ result = err; -+ } -+ return result; -+} -+ -+static void mptcp_assign_congestion_control(struct sock *sk) -+{ -+ struct inet_connection_sock *icsk = inet_csk(sk); -+ struct inet_connection_sock *meta_icsk = inet_csk(mptcp_meta_sk(sk)); -+ const struct tcp_congestion_ops *ca = meta_icsk->icsk_ca_ops; -+ -+ /* Congestion control is the same as meta. Thus, it has been -+ * try_module_get'd by tcp_assign_congestion_control. -+ * Congestion control on meta was not explicitly configured by -+ * application, leave default or route based. -+ */ -+ if (icsk->icsk_ca_ops == ca || -+ !tcp_sk(mptcp_meta_sk(sk))->mpcb->tcp_ca_explicit_set) -+ return; -+ -+ /* Use the same congestion control as set on the meta-sk */ -+ if (!try_module_get(ca->owner)) { -+ /* This should never happen. The congestion control is linked -+ * to the meta-socket (through tcp_assign_congestion_control) -+ * who "holds" the refcnt on the module. -+ */ -+ WARN(1, "Could not get the congestion control!"); -+ return; -+ } -+ module_put(icsk->icsk_ca_ops->owner); -+ icsk->icsk_ca_ops = ca; -+ -+ /* Clear out private data before diag gets it and -+ * the ca has not been initialized. -+ */ -+ if (ca->get_info) -+ memset(icsk->icsk_ca_priv, 0, sizeof(icsk->icsk_ca_priv)); -+ -+ return; -+} -+ -+siphash_key_t mptcp_secret __read_mostly; -+u32 mptcp_seed = 0; -+ -+void mptcp_key_sha1(u64 key, u32 *token, u64 *idsn) -+{ -+ u32 workspace[SHA_WORKSPACE_WORDS]; -+ u32 mptcp_hashed_key[SHA_DIGEST_WORDS]; -+ u8 input[64]; -+ int i; -+ -+ memset(workspace, 0, sizeof(workspace)); -+ -+ /* Initialize input with appropriate padding */ -+ memset(&input[9], 0, sizeof(input) - 10); /* -10, because the last byte -+ * is explicitly set too -+ */ -+ memcpy(input, &key, sizeof(key)); /* Copy key to the msg beginning */ -+ input[8] = 0x80; /* Padding: First bit after message = 1 */ -+ input[63] = 0x40; /* Padding: Length of the message = 64 bits */ -+ -+ sha_init(mptcp_hashed_key); -+ sha_transform(mptcp_hashed_key, input, workspace); -+ -+ for (i = 0; i < 5; i++) -+ mptcp_hashed_key[i] = cpu_to_be32(mptcp_hashed_key[i]); -+ -+ if (token) -+ *token = mptcp_hashed_key[0]; -+ if (idsn) -+ *idsn = *((u64 *)&mptcp_hashed_key[3]); -+} -+ -+void mptcp_hmac_sha1(const u8 *key_1, const u8 *key_2, u32 *hash_out, -+ int arg_num, ...) -+{ -+ u32 workspace[SHA_WORKSPACE_WORDS]; -+ u8 input[128]; /* 2 512-bit blocks */ -+ int i; -+ int index; -+ int length; -+ u8 *msg; -+ va_list list; -+ -+ memset(workspace, 0, sizeof(workspace)); -+ -+ /* Generate key xored with ipad */ -+ memset(input, 0x36, 64); -+ for (i = 0; i < 8; i++) -+ input[i] ^= key_1[i]; -+ for (i = 0; i < 8; i++) -+ input[i + 8] ^= key_2[i]; -+ -+ va_start(list, arg_num); -+ index = 64; -+ for (i = 0; i < arg_num; i++) { -+ length = va_arg(list, int); -+ msg = va_arg(list, u8 *); -+ BUG_ON(index + length > 125); /* Message is too long */ -+ memcpy(&input[index], msg, length); -+ index += length; -+ } -+ va_end(list); -+ -+ input[index] = 0x80; /* Padding: First bit after message = 1 */ -+ memset(&input[index + 1], 0, (126 - index)); -+ -+ /* Padding: Length of the message = 512 + message length (bits) */ -+ input[126] = 0x02; -+ input[127] = ((index - 64) * 8); /* Message length (bits) */ -+ -+ sha_init(hash_out); -+ sha_transform(hash_out, input, workspace); -+ memset(workspace, 0, sizeof(workspace)); -+ -+ sha_transform(hash_out, &input[64], workspace); -+ memset(workspace, 0, sizeof(workspace)); -+ -+ for (i = 0; i < 5; i++) -+ hash_out[i] = cpu_to_be32(hash_out[i]); -+ -+ /* Prepare second part of hmac */ -+ memset(input, 0x5C, 64); -+ for (i = 0; i < 8; i++) -+ input[i] ^= key_1[i]; -+ for (i = 0; i < 8; i++) -+ input[i + 8] ^= key_2[i]; -+ -+ memcpy(&input[64], hash_out, 20); -+ input[84] = 0x80; -+ memset(&input[85], 0, 41); -+ -+ /* Padding: Length of the message = 512 + 160 bits */ -+ input[126] = 0x02; -+ input[127] = 0xA0; -+ -+ sha_init(hash_out); -+ sha_transform(hash_out, input, workspace); -+ memset(workspace, 0, sizeof(workspace)); -+ -+ sha_transform(hash_out, &input[64], workspace); -+ -+ for (i = 0; i < 5; i++) -+ hash_out[i] = cpu_to_be32(hash_out[i]); -+} -+EXPORT_SYMBOL(mptcp_hmac_sha1); -+ -+static void mptcp_mpcb_inherit_sockopts(struct sock *meta_sk, struct sock *master_sk) -+{ -+ /* Socket-options handled by sk_clone_lock while creating the meta-sk. -+ * ====== -+ * SO_SNDBUF, SO_SNDBUFFORCE, SO_RCVBUF, SO_RCVBUFFORCE, SO_RCVLOWAT, -+ * SO_RCVTIMEO, SO_SNDTIMEO, SO_ATTACH_FILTER, SO_DETACH_FILTER, -+ * TCP_NODELAY, TCP_CORK -+ * -+ * Socket-options handled in this function here -+ * ====== -+ * TCP_DEFER_ACCEPT -+ * SO_KEEPALIVE -+ * -+ * Socket-options on the todo-list -+ * ====== -+ * SO_BINDTODEVICE - should probably prevent creation of new subsocks -+ * across other devices. - what about the api-draft? -+ * SO_DEBUG -+ * SO_REUSEADDR - probably we don't care about this -+ * SO_DONTROUTE, SO_BROADCAST -+ * SO_OOBINLINE -+ * SO_LINGER -+ * SO_TIMESTAMP* - I don't think this is of concern for a SOCK_STREAM -+ * SO_PASSSEC - I don't think this is of concern for a SOCK_STREAM -+ * SO_RXQ_OVFL -+ * TCP_COOKIE_TRANSACTIONS -+ * TCP_MAXSEG -+ * TCP_THIN_* - Handled by sk_clone_lock, but we need to support this -+ * in mptcp_meta_retransmit_timer. AND we need to check -+ * what is about the subsockets. -+ * TCP_LINGER2 -+ * TCP_WINDOW_CLAMP -+ * TCP_USER_TIMEOUT -+ * TCP_MD5SIG -+ * -+ * Socket-options of no concern for the meta-socket (but for the subsocket) -+ * ====== -+ * SO_PRIORITY -+ * SO_MARK -+ * TCP_CONGESTION -+ * TCP_SYNCNT -+ * TCP_QUICKACK -+ */ -+ -+ /* DEFER_ACCEPT should not be set on the meta, as we want to accept new subflows directly */ -+ inet_csk(meta_sk)->icsk_accept_queue.rskq_defer_accept = 0; -+ -+ /* Keepalives are handled entirely at the MPTCP-layer */ -+ if (sock_flag(meta_sk, SOCK_KEEPOPEN)) { -+ inet_csk_reset_keepalive_timer(meta_sk, -+ keepalive_time_when(tcp_sk(meta_sk))); -+ sock_reset_flag(master_sk, SOCK_KEEPOPEN); -+ inet_csk_delete_keepalive_timer(master_sk); -+ } -+ -+ /* Do not propagate subflow-errors up to the MPTCP-layer */ -+ inet_sk(master_sk)->recverr = 0; -+} -+ -+static void mptcp_sub_inherit_sockopts(const struct sock *meta_sk, struct sock *sub_sk) -+{ -+ /* IP_TOS also goes to the subflow. */ -+ if (inet_sk(sub_sk)->tos != inet_sk(meta_sk)->tos) { -+ inet_sk(sub_sk)->tos = inet_sk(meta_sk)->tos; -+ sub_sk->sk_priority = meta_sk->sk_priority; -+ sk_dst_reset(sub_sk); -+ } -+ -+ /* Inherit SO_REUSEADDR */ -+ sub_sk->sk_reuse = meta_sk->sk_reuse; -+ -+ /* Inherit SO_MARK: can be used for routing or filtering */ -+ sub_sk->sk_mark = meta_sk->sk_mark; -+ -+ /* Inherit snd/rcv-buffer locks */ -+ sub_sk->sk_userlocks = meta_sk->sk_userlocks & ~SOCK_BINDPORT_LOCK; -+ -+ /* Nagle/Cork is forced off on the subflows. It is handled at the meta-layer */ -+ tcp_sk(sub_sk)->nonagle = TCP_NAGLE_OFF|TCP_NAGLE_PUSH; -+ -+ /* Keepalives are handled entirely at the MPTCP-layer */ -+ if (sock_flag(sub_sk, SOCK_KEEPOPEN)) { -+ sock_reset_flag(sub_sk, SOCK_KEEPOPEN); -+ inet_csk_delete_keepalive_timer(sub_sk); -+ } -+ -+ /* Do not propagate subflow-errors up to the MPTCP-layer */ -+ inet_sk(sub_sk)->recverr = 0; -+} -+ -+void mptcp_prepare_for_backlog(struct sock *sk, struct sk_buff *skb) -+{ -+ /* In case of success (in mptcp_backlog_rcv) and error (in kfree_skb) of -+ * sk_add_backlog, we will decrement the sk refcount. -+ */ -+ sock_hold(sk); -+ skb->sk = sk; -+ skb->destructor = sock_efree; -+} -+ -+int mptcp_backlog_rcv(struct sock *meta_sk, struct sk_buff *skb) -+{ -+ /* skb-sk may be NULL if we receive a packet immediatly after the -+ * SYN/ACK + MP_CAPABLE. -+ */ -+ struct sock *sk = skb->sk ? skb->sk : meta_sk; -+ int ret = 0; -+ -+ if (unlikely(!refcount_inc_not_zero(&sk->sk_refcnt))) { -+ kfree_skb(skb); -+ return 0; -+ } -+ -+ /* Decrement sk refcnt when calling the skb destructor. -+ * Refcnt is incremented and skb destructor is set in tcp_v{4,6}_rcv via -+ * mptcp_prepare_for_backlog() here above. -+ */ -+ skb_orphan(skb); -+ -+ if (sk->sk_family == AF_INET) -+ ret = tcp_v4_do_rcv(sk, skb); -+#if IS_ENABLED(CONFIG_IPV6) -+ else -+ ret = tcp_v6_do_rcv(sk, skb); -+#endif -+ -+ sock_put(sk); -+ return ret; -+} -+ -+struct lock_class_key meta_key; -+char *meta_key_name = "sk_lock-AF_INET-MPTCP"; -+struct lock_class_key meta_slock_key; -+char *meta_slock_key_name = "slock-AF_INET-MPTCP"; -+ -+static const struct tcp_sock_ops mptcp_meta_specific = { -+ .__select_window = __mptcp_select_window, -+ .select_window = mptcp_select_window, -+ .select_initial_window = mptcp_select_initial_window, -+ .select_size = mptcp_select_size, -+ .init_buffer_space = mptcp_init_buffer_space, -+ .set_rto = mptcp_tcp_set_rto, -+ .should_expand_sndbuf = mptcp_should_expand_sndbuf, -+ .send_fin = mptcp_send_fin, -+ .write_xmit = mptcp_write_xmit, -+ .send_active_reset = mptcp_send_active_reset, -+ .write_wakeup = mptcp_write_wakeup, -+ .retransmit_timer = mptcp_meta_retransmit_timer, -+ .time_wait = mptcp_time_wait, -+ .cleanup_rbuf = mptcp_cleanup_rbuf, -+ .set_cong_ctrl = mptcp_set_congestion_control, -+}; -+ -+static const struct tcp_sock_ops mptcp_sub_specific = { -+ .__select_window = __mptcp_select_window, -+ .select_window = mptcp_select_window, -+ .select_initial_window = mptcp_select_initial_window, -+ .select_size = mptcp_select_size, -+ .init_buffer_space = mptcp_init_buffer_space, -+ .set_rto = mptcp_tcp_set_rto, -+ .should_expand_sndbuf = mptcp_should_expand_sndbuf, -+ .send_fin = tcp_send_fin, -+ .write_xmit = tcp_write_xmit, -+ .send_active_reset = tcp_send_active_reset, -+ .write_wakeup = tcp_write_wakeup, -+ .retransmit_timer = mptcp_sub_retransmit_timer, -+ .time_wait = tcp_time_wait, -+ .cleanup_rbuf = tcp_cleanup_rbuf, -+ .set_cong_ctrl = __tcp_set_congestion_control, -+}; -+ -+static int mptcp_alloc_mpcb(struct sock *meta_sk, __u64 remote_key, -+ __u8 mptcp_ver, u32 window) -+{ -+ struct mptcp_cb *mpcb; -+ struct sock *master_sk; -+ struct inet_connection_sock *meta_icsk = inet_csk(meta_sk); -+ struct tcp_sock *master_tp, *meta_tp = tcp_sk(meta_sk); -+ u64 snd_idsn, rcv_idsn; -+ -+ dst_release(meta_sk->sk_rx_dst); -+ meta_sk->sk_rx_dst = NULL; -+ /* This flag is set to announce sock_lock_init to -+ * reclassify the lock-class of the master socket. -+ */ -+ meta_tp->is_master_sk = 1; -+ master_sk = sk_clone_lock(meta_sk, GFP_ATOMIC | __GFP_ZERO); -+ meta_tp->is_master_sk = 0; -+ if (!master_sk) -+ goto err_alloc_master; -+ -+ master_tp = tcp_sk(master_sk); -+ master_tp->inside_tk_table = 0; -+ -+ mpcb = kmem_cache_zalloc(mptcp_cb_cache, GFP_ATOMIC); -+ if (!mpcb) -+ goto err_alloc_mpcb; -+ -+ /* Store the mptcp version agreed on initial handshake */ -+ mpcb->mptcp_ver = mptcp_ver; -+ -+ /* Store the keys and generate the peer's token */ -+ mpcb->mptcp_loc_key = meta_tp->mptcp_loc_key; -+ mpcb->mptcp_loc_token = meta_tp->mptcp_loc_token; -+ -+ /* Generate Initial data-sequence-numbers */ -+ mptcp_key_sha1(mpcb->mptcp_loc_key, NULL, &snd_idsn); -+ snd_idsn = ntohll(snd_idsn) + 1; -+ mpcb->snd_high_order[0] = snd_idsn >> 32; -+ mpcb->snd_high_order[1] = mpcb->snd_high_order[0] - 1; -+ -+ mpcb->mptcp_rem_key = remote_key; -+ mptcp_key_sha1(mpcb->mptcp_rem_key, &mpcb->mptcp_rem_token, &rcv_idsn); -+ rcv_idsn = ntohll(rcv_idsn) + 1; -+ mpcb->rcv_high_order[0] = rcv_idsn >> 32; -+ mpcb->rcv_high_order[1] = mpcb->rcv_high_order[0] + 1; -+ -+ mpcb->meta_sk = meta_sk; -+ mpcb->master_sk = master_sk; -+ -+ skb_queue_head_init(&mpcb->reinject_queue); -+ mutex_init(&mpcb->mpcb_mutex); -+ -+ /* Init time-wait stuff */ -+ INIT_LIST_HEAD(&mpcb->tw_list); -+ spin_lock_init(&mpcb->tw_lock); -+ -+ INIT_HLIST_HEAD(&mpcb->callback_list); -+ -+ mpcb->orig_sk_rcvbuf = meta_sk->sk_rcvbuf; -+ mpcb->orig_sk_sndbuf = meta_sk->sk_sndbuf; -+ mpcb->orig_window_clamp = meta_tp->window_clamp; -+ -+ /* The meta is directly linked - set refcnt to 1 */ -+ atomic_set(&mpcb->mpcb_refcnt, 1); -+ -+ if (!meta_tp->inside_tk_table) { -+ /* Adding the meta_tp in the token hashtable - coming from server-side */ -+ rcu_read_lock(); -+ local_bh_disable(); -+ spin_lock(&mptcp_tk_hashlock); -+ -+ /* With lockless listeners, we might process two ACKs at the -+ * same time. With TCP, inet_csk_complete_hashdance takes care -+ * of this. But, for MPTCP this would be too late if we add -+ * this MPTCP-socket in the token table (new subflows might -+ * come in and match on this socket here. -+ * So, we need to check if someone else already added the token -+ * and revert in that case. The other guy won the race... -+ */ -+ if (mptcp_find_token(mpcb->mptcp_loc_token)) { -+ spin_unlock(&mptcp_tk_hashlock); -+ local_bh_enable(); -+ rcu_read_unlock(); -+ -+ goto err_insert_token; -+ } -+ __mptcp_hash_insert(meta_tp, mpcb->mptcp_loc_token); -+ -+ spin_unlock(&mptcp_tk_hashlock); -+ local_bh_enable(); -+ rcu_read_unlock(); -+ } -+ -+#if IS_ENABLED(CONFIG_IPV6) -+ if (meta_icsk->icsk_af_ops == &mptcp_v6_mapped) { -+ struct tcp6_sock *master_tp6 = (struct tcp6_sock *)master_sk; -+ struct ipv6_pinfo *newnp, *np = inet6_sk(meta_sk); -+ -+ inet_sk(master_sk)->pinet6 = &master_tp6->inet6; -+ -+ newnp = inet6_sk(master_sk); -+ memcpy(newnp, np, sizeof(struct ipv6_pinfo)); -+ -+ newnp->ipv6_mc_list = NULL; -+ newnp->ipv6_ac_list = NULL; -+ newnp->ipv6_fl_list = NULL; -+ newnp->pktoptions = NULL; -+ newnp->opt = NULL; -+ -+ newnp->rxopt.all = 0; -+ newnp->repflow = 0; -+ np->rxopt.all = 0; -+ np->repflow = 0; -+ } else if (meta_sk->sk_family == AF_INET6) { -+ struct tcp6_sock *master_tp6 = (struct tcp6_sock *)master_sk; -+ struct ipv6_pinfo *newnp, *np = inet6_sk(meta_sk); -+ struct ipv6_txoptions *opt; -+ -+ inet_sk(master_sk)->pinet6 = &master_tp6->inet6; -+ -+ /* The following heavily inspired from tcp_v6_syn_recv_sock() */ -+ newnp = inet6_sk(master_sk); -+ memcpy(newnp, np, sizeof(struct ipv6_pinfo)); -+ -+ newnp->ipv6_mc_list = NULL; -+ newnp->ipv6_ac_list = NULL; -+ newnp->ipv6_fl_list = NULL; -+ newnp->pktoptions = NULL; -+ newnp->opt = NULL; -+ -+ newnp->rxopt.all = 0; -+ newnp->repflow = 0; -+ np->rxopt.all = 0; -+ np->repflow = 0; -+ -+ opt = rcu_dereference(np->opt); -+ if (opt) { -+ opt = ipv6_dup_options(master_sk, opt); -+ RCU_INIT_POINTER(newnp->opt, opt); -+ } -+ inet_csk(master_sk)->icsk_ext_hdr_len = 0; -+ if (opt) -+ inet_csk(master_sk)->icsk_ext_hdr_len = opt->opt_nflen + -+ opt->opt_flen; -+ } -+#endif -+ -+ meta_tp->mptcp = NULL; -+ -+ meta_tp->write_seq = (u32)snd_idsn; -+ meta_tp->snd_sml = meta_tp->write_seq; -+ meta_tp->snd_una = meta_tp->write_seq; -+ meta_tp->snd_nxt = meta_tp->write_seq; -+ meta_tp->pushed_seq = meta_tp->write_seq; -+ meta_tp->snd_up = meta_tp->write_seq; -+ -+ meta_tp->copied_seq = (u32)rcv_idsn; -+ meta_tp->rcv_nxt = (u32)rcv_idsn; -+ meta_tp->rcv_wup = (u32)rcv_idsn; -+ -+ meta_tp->snd_wl1 = meta_tp->rcv_nxt - 1; -+ meta_tp->snd_wnd = window; -+ meta_tp->retrans_stamp = 0; /* Set in tcp_connect() */ -+ -+ meta_tp->packets_out = 0; -+ meta_icsk->icsk_probes_out = 0; -+ -+ rcu_assign_pointer(inet_sk(meta_sk)->inet_opt, NULL); -+ -+ /* Set mptcp-pointers */ -+ master_tp->mpcb = mpcb; -+ master_tp->meta_sk = meta_sk; -+ meta_tp->mpcb = mpcb; -+ meta_tp->meta_sk = meta_sk; -+ -+ /* Initialize the queues */ -+ master_tp->out_of_order_queue = RB_ROOT; -+ INIT_LIST_HEAD(&master_tp->tsq_node); -+ -+ master_sk->sk_tsq_flags = 0; -+ /* icsk_bind_hash inherited from the meta, but it will be properly set in -+ * mptcp_create_master_sk. Same operation is done in inet_csk_clone_lock. -+ */ -+ inet_csk(master_sk)->icsk_bind_hash = NULL; -+ -+ /* Init the accept_queue structure, we support a queue of 32 pending -+ * connections, it does not need to be huge, since we only store here -+ * pending subflow creations. -+ */ -+ reqsk_queue_alloc(&meta_icsk->icsk_accept_queue); -+ meta_sk->sk_max_ack_backlog = 32; -+ meta_sk->sk_ack_backlog = 0; -+ -+ if (!sock_flag(meta_sk, SOCK_MPTCP)) { -+ mptcp_enable_static_key_bh(); -+ sock_set_flag(meta_sk, SOCK_MPTCP); -+ } -+ -+ /* Redefine function-pointers as the meta-sk is now fully ready */ -+ meta_tp->mpc = 1; -+ meta_tp->ops = &mptcp_meta_specific; -+ -+ meta_sk->sk_backlog_rcv = mptcp_backlog_rcv; -+ meta_sk->sk_destruct = mptcp_sock_destruct; -+ -+ /* Meta-level retransmit timer */ -+ meta_icsk->icsk_rto *= 2; /* Double of initial - rto */ -+ -+ tcp_init_xmit_timers(master_sk); -+ /* Has been set for sending out the SYN */ -+ inet_csk_clear_xmit_timer(meta_sk, ICSK_TIME_RETRANS); -+ -+ mptcp_mpcb_inherit_sockopts(meta_sk, master_sk); -+ -+ mptcp_init_path_manager(mpcb); -+ mptcp_init_scheduler(mpcb); -+ -+ if (!try_module_get(inet_csk(master_sk)->icsk_ca_ops->owner)) -+ tcp_assign_congestion_control(master_sk); -+ -+ master_tp->saved_syn = NULL; -+ -+ mptcp_debug("%s: created mpcb with token %#x\n", -+ __func__, mpcb->mptcp_loc_token); -+ -+ return 0; -+ -+err_insert_token: -+ kmem_cache_free(mptcp_cb_cache, mpcb); -+ -+err_alloc_mpcb: -+ inet_sk(master_sk)->inet_opt = NULL; -+ master_sk->sk_state = TCP_CLOSE; -+ sock_orphan(master_sk); -+ bh_unlock_sock(master_sk); -+ sk_free(master_sk); -+ -+err_alloc_master: -+ return -ENOBUFS; -+} -+ -+int mptcp_add_sock(struct sock *meta_sk, struct sock *sk, u8 loc_id, u8 rem_id, -+ gfp_t flags) -+{ -+ struct mptcp_cb *mpcb = tcp_sk(meta_sk)->mpcb; -+ struct tcp_sock *tp = tcp_sk(sk); -+ -+ tp->mptcp = kmem_cache_zalloc(mptcp_sock_cache, flags); -+ if (!tp->mptcp) -+ return -ENOMEM; -+ -+ tp->mptcp->path_index = mptcp_set_new_pathindex(mpcb); -+ /* No more space for more subflows? */ -+ if (!tp->mptcp->path_index) { -+ kmem_cache_free(mptcp_sock_cache, tp->mptcp); -+ return -EPERM; -+ } -+ -+ INIT_HLIST_NODE(&tp->mptcp->cb_list); -+ -+ tp->mptcp->tp = tp; -+ tp->mpcb = mpcb; -+ tp->meta_sk = meta_sk; -+ -+ if (!sock_flag(sk, SOCK_MPTCP)) { -+ mptcp_enable_static_key_bh(); -+ sock_set_flag(sk, SOCK_MPTCP); -+ } -+ -+ tp->mpc = 1; -+ tp->ops = &mptcp_sub_specific; -+ -+ tp->mptcp->loc_id = loc_id; -+ tp->mptcp->rem_id = rem_id; -+ if (mpcb->sched_ops->init) -+ mpcb->sched_ops->init(sk); -+ -+ /* The corresponding sock_put is in mptcp_sock_destruct(). It cannot be -+ * included in mptcp_del_sock(), because the mpcb must remain alive -+ * until the last subsocket is completely destroyed. -+ */ -+ sock_hold(meta_sk); -+ atomic_inc(&mpcb->mpcb_refcnt); -+ -+ tp->mptcp->next = mpcb->connection_list; -+ mpcb->connection_list = tp; -+ tp->mptcp->attached = 1; -+ -+ mpcb->cnt_subflows++; -+ -+ mptcp_sub_inherit_sockopts(meta_sk, sk); -+ INIT_DELAYED_WORK(&tp->mptcp->work, mptcp_sub_close_wq); -+ -+ /* Properly inherit CC from the meta-socket */ -+ mptcp_assign_congestion_control(sk); -+ -+ /* As we successfully allocated the mptcp_tcp_sock, we have to -+ * change the function-pointers here (for sk_destruct to work correctly) -+ */ -+ sk->sk_error_report = mptcp_sock_def_error_report; -+ sk->sk_data_ready = mptcp_data_ready; -+ sk->sk_write_space = mptcp_write_space; -+ sk->sk_state_change = mptcp_set_state; -+ sk->sk_destruct = mptcp_sock_destruct; -+ -+ if (sk->sk_family == AF_INET) -+ mptcp_debug("%s: token %#x pi %d, src_addr:%pI4:%d dst_addr:%pI4:%d, cnt_subflows now %d\n", -+ __func__ , mpcb->mptcp_loc_token, -+ tp->mptcp->path_index, -+ &((struct inet_sock *)tp)->inet_saddr, -+ ntohs(((struct inet_sock *)tp)->inet_sport), -+ &((struct inet_sock *)tp)->inet_daddr, -+ ntohs(((struct inet_sock *)tp)->inet_dport), -+ mpcb->cnt_subflows); -+#if IS_ENABLED(CONFIG_IPV6) -+ else -+ mptcp_debug("%s: token %#x pi %d, src_addr:%pI6:%d dst_addr:%pI6:%d, cnt_subflows now %d\n", -+ __func__ , mpcb->mptcp_loc_token, -+ tp->mptcp->path_index, &inet6_sk(sk)->saddr, -+ ntohs(((struct inet_sock *)tp)->inet_sport), -+ &sk->sk_v6_daddr, -+ ntohs(((struct inet_sock *)tp)->inet_dport), -+ mpcb->cnt_subflows); -+#endif -+ -+ return 0; -+} -+ -+void mptcp_del_sock(struct sock *sk) -+{ -+ struct tcp_sock *tp = tcp_sk(sk), *tp_prev; -+ struct mptcp_cb *mpcb; -+ -+ if (!tp->mptcp || !tp->mptcp->attached) -+ return; -+ -+ mpcb = tp->mpcb; -+ tp_prev = mpcb->connection_list; -+ -+ if (mpcb->sched_ops->release) -+ mpcb->sched_ops->release(sk); -+ -+ if (mpcb->pm_ops->delete_subflow) -+ mpcb->pm_ops->delete_subflow(sk); -+ -+ mptcp_debug("%s: Removing subsock tok %#x pi:%d state %d is_meta? %d\n", -+ __func__, mpcb->mptcp_loc_token, tp->mptcp->path_index, -+ sk->sk_state, is_meta_sk(sk)); -+ -+ if (tp_prev == tp) { -+ mpcb->connection_list = tp->mptcp->next; -+ } else { -+ for (; tp_prev && tp_prev->mptcp->next; tp_prev = tp_prev->mptcp->next) { -+ if (tp_prev->mptcp->next == tp) { -+ tp_prev->mptcp->next = tp->mptcp->next; -+ break; -+ } -+ } -+ } -+ mpcb->cnt_subflows--; -+ if (tp->mptcp->establish_increased) -+ mpcb->cnt_established--; -+ -+ tp->mptcp->next = NULL; -+ tp->mptcp->attached = 0; -+ mpcb->path_index_bits &= ~(1 << tp->mptcp->path_index); -+ -+ if (!skb_queue_empty(&sk->sk_write_queue)) -+ mptcp_reinject_data(sk, 0); -+ -+ if (is_master_tp(tp)) { -+ struct sock *meta_sk = mptcp_meta_sk(sk); -+ struct tcp_sock *meta_tp = tcp_sk(meta_sk); -+ -+ if (meta_tp->record_master_info && -+ !sock_flag(meta_sk, SOCK_DEAD)) { -+ mpcb->master_info = kmalloc(sizeof(*mpcb->master_info), -+ GFP_ATOMIC); -+ -+ if (mpcb->master_info) -+ tcp_get_info(sk, mpcb->master_info, true); -+ } -+ -+ mpcb->master_sk = NULL; -+ } else if (tp->mptcp->pre_established) { -+ sk_stop_timer(sk, &tp->mptcp->mptcp_ack_timer); -+ } -+} -+ -+/* Updates the MPTCP-session based on path-manager information (e.g., addresses, -+ * low-prio flows,...). -+ */ -+void mptcp_update_metasocket(const struct sock *meta_sk) -+{ -+ if (tcp_sk(meta_sk)->mpcb->pm_ops->new_session) -+ tcp_sk(meta_sk)->mpcb->pm_ops->new_session(meta_sk); -+} -+ -+/* Clean up the receive buffer for full frames taken by the user, -+ * then send an ACK if necessary. COPIED is the number of bytes -+ * tcp_recvmsg has given to the user so far, it speeds up the -+ * calculation of whether or not we must ACK for the sake of -+ * a window update. -+ * (inspired from tcp_cleanup_rbuf()) -+ */ -+void mptcp_cleanup_rbuf(struct sock *meta_sk, int copied) -+{ -+ struct tcp_sock *meta_tp = tcp_sk(meta_sk); -+ struct sock *sk; -+ bool recheck_rcv_window = false; -+ __u32 rcv_window_now = 0; -+ -+ if (copied > 0 && !(meta_sk->sk_shutdown & RCV_SHUTDOWN)) { -+ rcv_window_now = tcp_receive_window(meta_tp); -+ -+ /* Optimize, __mptcp_select_window() is not cheap. */ -+ if (2 * rcv_window_now <= meta_tp->window_clamp) -+ recheck_rcv_window = true; -+ } -+ -+ mptcp_for_each_sk(meta_tp->mpcb, sk) { -+ struct tcp_sock *tp = tcp_sk(sk); -+ const struct inet_connection_sock *icsk = inet_csk(sk); -+ -+ if (!mptcp_sk_can_send_ack(sk)) -+ continue; -+ -+ if (!inet_csk_ack_scheduled(sk)) -+ goto second_part; -+ /* Delayed ACKs frequently hit locked sockets during bulk -+ * receive. -+ */ -+ if (icsk->icsk_ack.blocked || -+ /* Once-per-two-segments ACK was not sent by tcp_input.c */ -+ tp->rcv_nxt - tp->rcv_wup > icsk->icsk_ack.rcv_mss || -+ /* If this read emptied read buffer, we send ACK, if -+ * connection is not bidirectional, user drained -+ * receive buffer and there was a small segment -+ * in queue. -+ */ -+ (copied > 0 && -+ ((icsk->icsk_ack.pending & ICSK_ACK_PUSHED2) || -+ ((icsk->icsk_ack.pending & ICSK_ACK_PUSHED) && -+ !icsk->icsk_ack.pingpong)) && -+ !atomic_read(&meta_sk->sk_rmem_alloc))) { -+ tcp_send_ack(sk); -+ continue; -+ } -+ -+second_part: -+ /* This here is the second part of tcp_cleanup_rbuf */ -+ if (recheck_rcv_window) { -+ __u32 new_window = tp->ops->__select_window(sk); -+ -+ /* Send ACK now, if this read freed lots of space -+ * in our buffer. Certainly, new_window is new window. -+ * We can advertise it now, if it is not less than -+ * current one. -+ * "Lots" means "at least twice" here. -+ */ -+ if (new_window && new_window >= 2 * rcv_window_now) -+ tcp_send_ack(sk); -+ } -+ } -+} -+ -+static int mptcp_sub_send_fin(struct sock *sk) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct sk_buff *skb = tcp_write_queue_tail(sk); -+ int mss_now; -+ -+ /* Optimization, tack on the FIN if we have a queue of -+ * unsent frames. But be careful about outgoing SACKS -+ * and IP options. -+ */ -+ mss_now = tcp_current_mss(sk); -+ -+ if (tcp_send_head(sk) != NULL) { -+ TCP_SKB_CB(skb)->tcp_flags |= TCPHDR_FIN; -+ TCP_SKB_CB(skb)->end_seq++; -+ tp->write_seq++; -+ } else { -+ skb = alloc_skb_fclone(MAX_TCP_HEADER, GFP_ATOMIC); -+ if (!skb) -+ return 1; -+ -+ /* Reserve space for headers and prepare control bits. */ -+ skb_reserve(skb, MAX_TCP_HEADER); -+ /* FIN eats a sequence byte, write_seq advanced by tcp_queue_skb(). */ -+ tcp_init_nondata_skb(skb, tp->write_seq, -+ TCPHDR_ACK | TCPHDR_FIN); -+ tcp_queue_skb(sk, skb); -+ } -+ __tcp_push_pending_frames(sk, mss_now, TCP_NAGLE_OFF); -+ -+ return 0; -+} -+ -+static void mptcp_sub_close_doit(struct sock *sk) -+{ -+ struct sock *meta_sk = mptcp_meta_sk(sk); -+ struct tcp_sock *tp = tcp_sk(sk); -+ -+ if (sock_flag(sk, SOCK_DEAD)) -+ return; -+ -+ if (meta_sk->sk_shutdown == SHUTDOWN_MASK || sk->sk_state == TCP_CLOSE) { -+ tp->closing = 1; -+ tcp_close(sk, 0); -+ } else if (tcp_close_state(sk)) { -+ sk->sk_shutdown |= SEND_SHUTDOWN; -+ tcp_send_fin(sk); -+ } -+} -+ -+void mptcp_sub_close_wq(struct work_struct *work) -+{ -+ struct tcp_sock *tp = container_of(work, struct mptcp_tcp_sock, work.work)->tp; -+ struct sock *sk = (struct sock *)tp; -+ struct mptcp_cb *mpcb = tp->mpcb; -+ struct sock *meta_sk = mptcp_meta_sk(sk); -+ -+ mutex_lock(&mpcb->mpcb_mutex); -+ lock_sock_nested(meta_sk, SINGLE_DEPTH_NESTING); -+ -+ mptcp_sub_close_doit(sk); -+ -+ release_sock(meta_sk); -+ mutex_unlock(&mpcb->mpcb_mutex); -+ mptcp_mpcb_put(mpcb); -+ sock_put(sk); -+} -+ -+void mptcp_sub_close(struct sock *sk, unsigned long delay) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct delayed_work *work = &tcp_sk(sk)->mptcp->work; -+ -+ /* We are already closing - e.g., call from sock_def_error_report upon -+ * tcp_disconnect in tcp_close. -+ */ -+ if (tp->closing) -+ return; -+ -+ /* Work already scheduled ? */ -+ if (work_pending(&work->work)) { -+ /* Work present - who will be first ? */ -+ if (jiffies + delay > work->timer.expires) -+ return; -+ -+ /* Try canceling - if it fails, work will be executed soon */ -+ if (!cancel_delayed_work(work)) -+ return; -+ sock_put(sk); -+ mptcp_mpcb_put(tp->mpcb); -+ } -+ -+ if (!delay) { -+ unsigned char old_state = sk->sk_state; -+ -+ /* We directly send the FIN. Because it may take so a long time, -+ * untile the work-queue will get scheduled... -+ * -+ * If mptcp_sub_send_fin returns 1, it failed and thus we reset -+ * the old state so that tcp_close will finally send the fin -+ * in user-context. -+ */ -+ if (!sk->sk_err && old_state != TCP_CLOSE && -+ tcp_close_state(sk) && mptcp_sub_send_fin(sk)) { -+ if (old_state == TCP_ESTABLISHED) -+ TCP_INC_STATS(sock_net(sk), TCP_MIB_CURRESTAB); -+ sk->sk_state = old_state; -+ } -+ } -+ -+ sock_hold(sk); -+ atomic_inc(&tp->mpcb->mpcb_refcnt); -+ queue_delayed_work(mptcp_wq, work, delay); -+} -+ -+void mptcp_sub_force_close(struct sock *sk) -+{ -+ /* The below tcp_done may have freed the socket, if he is already dead. -+ * Thus, we are not allowed to access it afterwards. That's why -+ * we have to store the dead-state in this local variable. -+ */ -+ int sock_is_dead = sock_flag(sk, SOCK_DEAD); -+ -+ tcp_sk(sk)->mp_killed = 1; -+ -+ if (sk->sk_state != TCP_CLOSE) -+ tcp_done(sk); -+ -+ if (!sock_is_dead) -+ mptcp_sub_close(sk, 0); -+} -+EXPORT_SYMBOL(mptcp_sub_force_close); -+ -+/* Update the mpcb send window, based on the contributions -+ * of each subflow -+ */ -+void mptcp_update_sndbuf(const struct tcp_sock *tp) -+{ -+ struct sock *meta_sk = tp->meta_sk, *sk; -+ int new_sndbuf = 0, old_sndbuf = meta_sk->sk_sndbuf; -+ -+ mptcp_for_each_sk(tp->mpcb, sk) { -+ if (!mptcp_sk_can_send(sk)) -+ continue; -+ -+ new_sndbuf += sk->sk_sndbuf; -+ -+ if (new_sndbuf > sysctl_tcp_wmem[2] || new_sndbuf < 0) { -+ new_sndbuf = sysctl_tcp_wmem[2]; -+ break; -+ } -+ } -+ meta_sk->sk_sndbuf = max(min(new_sndbuf, sysctl_tcp_wmem[2]), meta_sk->sk_sndbuf); -+ -+ /* The subflow's call to sk_write_space in tcp_new_space ends up in -+ * mptcp_write_space. -+ * It has nothing to do with waking up the application. -+ * So, we do it here. -+ */ -+ if (old_sndbuf != meta_sk->sk_sndbuf) -+ meta_sk->sk_write_space(meta_sk); -+} -+ -+/* Similar to: tcp_close */ -+void mptcp_close(struct sock *meta_sk, long timeout) -+{ -+ struct tcp_sock *meta_tp = tcp_sk(meta_sk); -+ struct sock *sk_it, *tmpsk; -+ struct mptcp_cb *mpcb = meta_tp->mpcb; -+ struct sk_buff *skb; -+ int data_was_unread = 0; -+ int state; -+ -+ mptcp_debug("%s: Close of meta_sk with tok %#x\n", -+ __func__, mpcb->mptcp_loc_token); -+ -+ WARN_ON(atomic_inc_not_zero(&mpcb->mpcb_refcnt) == 0); -+ mutex_lock(&mpcb->mpcb_mutex); -+ lock_sock_nested(meta_sk, SINGLE_DEPTH_NESTING); -+ -+ if (meta_tp->inside_tk_table) -+ /* Detach the mpcb from the token hashtable */ -+ mptcp_hash_remove_bh(meta_tp); -+ -+ meta_sk->sk_shutdown = SHUTDOWN_MASK; -+ /* We need to flush the recv. buffs. We do this only on the -+ * descriptor close, not protocol-sourced closes, because the -+ * reader process may not have drained the data yet! -+ */ -+ while ((skb = __skb_dequeue(&meta_sk->sk_receive_queue)) != NULL) { -+ u32 len = TCP_SKB_CB(skb)->end_seq - TCP_SKB_CB(skb)->seq; -+ -+ if (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN) -+ len--; -+ data_was_unread += len; -+ __kfree_skb(skb); -+ } -+ -+ sk_mem_reclaim(meta_sk); -+ -+ /* If socket has been already reset (e.g. in tcp_reset()) - kill it. */ -+ if (meta_sk->sk_state == TCP_CLOSE) { -+ mptcp_for_each_sk_safe(mpcb, sk_it, tmpsk) { -+ if (tcp_sk(sk_it)->send_mp_fclose) -+ continue; -+ mptcp_sub_close(sk_it, 0); -+ } -+ goto adjudge_to_death; -+ } -+ -+ if (data_was_unread) { -+ /* Unread data was tossed, zap the connection. */ -+ NET_INC_STATS(sock_net(meta_sk), LINUX_MIB_TCPABORTONCLOSE); -+ tcp_set_state(meta_sk, TCP_CLOSE); -+ tcp_sk(meta_sk)->ops->send_active_reset(meta_sk, -+ meta_sk->sk_allocation); -+ } else if (sock_flag(meta_sk, SOCK_LINGER) && !meta_sk->sk_lingertime) { -+ /* Check zero linger _after_ checking for unread data. */ -+ meta_sk->sk_prot->disconnect(meta_sk, 0); -+ NET_INC_STATS(sock_net(meta_sk), LINUX_MIB_TCPABORTONDATA); -+ } else if (tcp_close_state(meta_sk)) { -+ mptcp_send_fin(meta_sk); -+ } else if (meta_tp->snd_una == meta_tp->write_seq) { -+ /* The DATA_FIN has been sent and acknowledged -+ * (e.g., by sk_shutdown). Close all the other subflows -+ */ -+ mptcp_for_each_sk_safe(mpcb, sk_it, tmpsk) { -+ unsigned long delay = 0; -+ /* If we are the passive closer, don't trigger -+ * subflow-fin until the subflow has been finned -+ * by the peer. - thus we add a delay -+ */ -+ if (mpcb->passive_close && -+ sk_it->sk_state == TCP_ESTABLISHED) -+ delay = inet_csk(sk_it)->icsk_rto << 3; -+ -+ mptcp_sub_close(sk_it, delay); -+ } -+ } -+ -+ sk_stream_wait_close(meta_sk, timeout); -+ -+adjudge_to_death: -+ state = meta_sk->sk_state; -+ sock_hold(meta_sk); -+ sock_orphan(meta_sk); -+ -+ /* socket will be freed after mptcp_close - we have to prevent -+ * access from the subflows. -+ */ -+ mptcp_for_each_sk(mpcb, sk_it) { -+ /* Similar to sock_orphan, but we don't set it DEAD, because -+ * the callbacks are still set and must be called. -+ */ -+ write_lock_bh(&sk_it->sk_callback_lock); -+ sk_set_socket(sk_it, NULL); -+ sk_it->sk_wq = NULL; -+ write_unlock_bh(&sk_it->sk_callback_lock); -+ } -+ -+ /* It is the last release_sock in its life. It will remove backlog. */ -+ release_sock(meta_sk); -+ -+ /* Now socket is owned by kernel and we acquire BH lock -+ * to finish close. No need to check for user refs. -+ */ -+ local_bh_disable(); -+ bh_lock_sock(meta_sk); -+ WARN_ON(sock_owned_by_user(meta_sk)); -+ -+ percpu_counter_inc(meta_sk->sk_prot->orphan_count); -+ -+ /* Have we already been destroyed by a softirq or backlog? */ -+ if (state != TCP_CLOSE && meta_sk->sk_state == TCP_CLOSE) -+ goto out; -+ -+ /* This is a (useful) BSD violating of the RFC. There is a -+ * problem with TCP as specified in that the other end could -+ * keep a socket open forever with no application left this end. -+ * We use a 3 minute timeout (about the same as BSD) then kill -+ * our end. If they send after that then tough - BUT: long enough -+ * that we won't make the old 4*rto = almost no time - whoops -+ * reset mistake. -+ * -+ * Nope, it was not mistake. It is really desired behaviour -+ * f.e. on http servers, when such sockets are useless, but -+ * consume significant resources. Let's do it with special -+ * linger2 option. --ANK -+ */ -+ -+ if (meta_sk->sk_state == TCP_FIN_WAIT2) { -+ if (meta_tp->linger2 < 0) { -+ tcp_set_state(meta_sk, TCP_CLOSE); -+ meta_tp->ops->send_active_reset(meta_sk, GFP_ATOMIC); -+ __NET_INC_STATS(sock_net(meta_sk), -+ LINUX_MIB_TCPABORTONLINGER); -+ } else { -+ const int tmo = tcp_fin_time(meta_sk); -+ -+ if (tmo > TCP_TIMEWAIT_LEN) { -+ inet_csk_reset_keepalive_timer(meta_sk, -+ tmo - TCP_TIMEWAIT_LEN); -+ } else { -+ meta_tp->ops->time_wait(meta_sk, TCP_FIN_WAIT2, -+ tmo); -+ goto out; -+ } -+ } -+ } -+ if (meta_sk->sk_state != TCP_CLOSE) { -+ sk_mem_reclaim(meta_sk); -+ if (tcp_check_oom(meta_sk, 0)) { -+ if (net_ratelimit()) -+ pr_info("MPTCP: out of memory: force closing socket\n"); -+ tcp_set_state(meta_sk, TCP_CLOSE); -+ meta_tp->ops->send_active_reset(meta_sk, GFP_ATOMIC); -+ __NET_INC_STATS(sock_net(meta_sk), -+ LINUX_MIB_TCPABORTONMEMORY); -+ } -+ } -+ -+ -+ if (meta_sk->sk_state == TCP_CLOSE) -+ inet_csk_destroy_sock(meta_sk); -+ /* Otherwise, socket is reprieved until protocol close. */ -+ -+out: -+ bh_unlock_sock(meta_sk); -+ local_bh_enable(); -+ mutex_unlock(&mpcb->mpcb_mutex); -+ mptcp_mpcb_put(mpcb); -+ sock_put(meta_sk); /* Taken by sock_hold */ -+} -+ -+void mptcp_disconnect(struct sock *meta_sk) -+{ -+ struct tcp_sock *meta_tp = tcp_sk(meta_sk); -+ struct sock *subsk, *tmpsk; -+ -+ __skb_queue_purge(&meta_tp->mpcb->reinject_queue); -+ -+ if (meta_tp->inside_tk_table) -+ mptcp_hash_remove_bh(meta_tp); -+ -+ local_bh_disable(); -+ mptcp_for_each_sk_safe(meta_tp->mpcb, subsk, tmpsk) { -+ if (spin_is_locked(&subsk->sk_lock.slock)) -+ bh_unlock_sock(subsk); -+ -+ tcp_sk(subsk)->tcp_disconnect = 1; -+ -+ meta_sk->sk_prot->disconnect(subsk, O_NONBLOCK); -+ -+ sock_orphan(subsk); -+ -+ percpu_counter_inc(meta_sk->sk_prot->orphan_count); -+ -+ inet_csk_destroy_sock(subsk); -+ } -+ local_bh_enable(); -+ -+ mptcp_mpcb_cleanup(meta_tp->mpcb); -+ meta_tp->meta_sk = NULL; -+ -+ meta_tp->send_mp_fclose = 0; -+ meta_tp->mpc = 0; -+ meta_tp->ops = &tcp_specific; -+#if IS_ENABLED(CONFIG_IPV6) -+ if (meta_sk->sk_family == AF_INET6) -+ meta_sk->sk_backlog_rcv = tcp_v6_do_rcv; -+ else -+ meta_sk->sk_backlog_rcv = tcp_v4_do_rcv; -+#else -+ meta_sk->sk_backlog_rcv = tcp_v4_do_rcv; -+#endif -+ meta_sk->sk_destruct = inet_sock_destruct; -+} -+ -+ -+/* Returns 1 if we should enable MPTCP for that socket. */ -+int mptcp_doit(struct sock *sk) -+{ -+ /* Don't do mptcp over loopback */ -+ if (sk->sk_family == AF_INET && -+ (ipv4_is_loopback(inet_sk(sk)->inet_daddr) || -+ ipv4_is_loopback(inet_sk(sk)->inet_saddr))) -+ return 0; -+#if IS_ENABLED(CONFIG_IPV6) -+ if (sk->sk_family == AF_INET6 && -+ (ipv6_addr_loopback(&sk->sk_v6_daddr) || -+ ipv6_addr_loopback(&inet6_sk(sk)->saddr))) -+ return 0; -+#endif -+ if (mptcp_v6_is_v4_mapped(sk) && -+ ipv4_is_loopback(inet_sk(sk)->inet_saddr)) -+ return 0; -+ -+#ifdef CONFIG_TCP_MD5SIG -+ /* If TCP_MD5SIG is enabled, do not do MPTCP - there is no Option-Space */ -+ if (tcp_sk(sk)->af_specific->md5_lookup(sk, sk)) -+ return 0; -+#endif -+ -+ return 1; -+} -+ -+int mptcp_create_master_sk(struct sock *meta_sk, __u64 remote_key, -+ __u8 mptcp_ver, u32 window) -+{ -+ struct tcp_sock *master_tp; -+ struct sock *master_sk; -+ -+ if (mptcp_alloc_mpcb(meta_sk, remote_key, mptcp_ver, window)) -+ goto err_alloc_mpcb; -+ -+ master_sk = tcp_sk(meta_sk)->mpcb->master_sk; -+ master_tp = tcp_sk(master_sk); -+ -+ if (mptcp_add_sock(meta_sk, master_sk, 0, 0, GFP_ATOMIC)) -+ goto err_add_sock; -+ -+ if (__inet_inherit_port(meta_sk, master_sk) < 0) -+ goto err_add_sock; -+ -+ meta_sk->sk_prot->unhash(meta_sk); -+ inet_ehash_nolisten(master_sk, NULL); -+ -+ master_tp->mptcp->init_rcv_wnd = master_tp->rcv_wnd; -+ -+ return 0; -+ -+err_add_sock: -+ inet_csk_prepare_forced_close(master_sk); -+ tcp_done(master_sk); -+ -+err_alloc_mpcb: -+ return -ENOBUFS; -+} -+ -+static int __mptcp_check_req_master(struct sock *child, -+ struct request_sock *req) -+{ -+ struct tcp_sock *child_tp = tcp_sk(child); -+ struct sock *meta_sk = child; -+ struct mptcp_cb *mpcb; -+ struct mptcp_request_sock *mtreq; -+ -+ /* Never contained an MP_CAPABLE */ -+ if (!inet_rsk(req)->mptcp_rqsk) -+ return 1; -+ -+ if (!inet_rsk(req)->saw_mpc) { -+ /* Fallback to regular TCP, because we saw one SYN without -+ * MP_CAPABLE. In tcp_check_req we continue the regular path. -+ * But, the socket has been added to the reqsk_tk_htb, so we -+ * must still remove it. -+ */ -+ MPTCP_INC_STATS(sock_net(meta_sk), MPTCP_MIB_MPCAPABLEPASSIVEFALLBACK); -+ mptcp_reqsk_remove_tk(req); -+ return 1; -+ } -+ -+ MPTCP_INC_STATS(sock_net(meta_sk), MPTCP_MIB_MPCAPABLEPASSIVEACK); -+ -+ /* Just set this values to pass them to mptcp_alloc_mpcb */ -+ mtreq = mptcp_rsk(req); -+ child_tp->mptcp_loc_key = mtreq->mptcp_loc_key; -+ child_tp->mptcp_loc_token = mtreq->mptcp_loc_token; -+ -+ if (mptcp_create_master_sk(meta_sk, mtreq->mptcp_rem_key, -+ mtreq->mptcp_ver, child_tp->snd_wnd)) { -+ inet_csk_prepare_forced_close(meta_sk); -+ tcp_done(meta_sk); -+ -+ return -ENOBUFS; -+ } -+ -+ child = tcp_sk(child)->mpcb->master_sk; -+ child_tp = tcp_sk(child); -+ mpcb = child_tp->mpcb; -+ -+ child_tp->mptcp->snt_isn = tcp_rsk(req)->snt_isn; -+ child_tp->mptcp->rcv_isn = tcp_rsk(req)->rcv_isn; -+ -+ mpcb->dss_csum = mtreq->dss_csum; -+ mpcb->server_side = 1; -+ -+ /* Needs to be done here additionally, because when accepting a -+ * new connection we pass by __reqsk_free and not reqsk_free. -+ */ -+ mptcp_reqsk_remove_tk(req); -+ -+ /* Hold when creating the meta-sk in tcp_vX_syn_recv_sock. */ -+ sock_put(meta_sk); -+ -+ return 0; -+} -+ -+int mptcp_check_req_fastopen(struct sock *child, struct request_sock *req) -+{ -+ struct sock *meta_sk = child, *master_sk; -+ struct sk_buff *skb; -+ u32 new_mapping; -+ int ret; -+ -+ ret = __mptcp_check_req_master(child, req); -+ if (ret) -+ return ret; -+ -+ master_sk = tcp_sk(meta_sk)->mpcb->master_sk; -+ -+ /* We need to rewind copied_seq as it is set to IDSN + 1 and as we have -+ * pre-MPTCP data in the receive queue. -+ */ -+ tcp_sk(meta_sk)->copied_seq -= tcp_sk(master_sk)->rcv_nxt - -+ tcp_rsk(req)->rcv_isn - 1; -+ -+ /* Map subflow sequence number to data sequence numbers. We need to map -+ * these data to [IDSN - len - 1, IDSN[. -+ */ -+ new_mapping = tcp_sk(meta_sk)->copied_seq - tcp_rsk(req)->rcv_isn - 1; -+ -+ /* There should be only one skb: the SYN + data. */ -+ skb_queue_walk(&meta_sk->sk_receive_queue, skb) { -+ TCP_SKB_CB(skb)->seq += new_mapping; -+ TCP_SKB_CB(skb)->end_seq += new_mapping; -+ } -+ -+ /* With fastopen we change the semantics of the relative subflow -+ * sequence numbers to deal with middleboxes that could add/remove -+ * multiple bytes in the SYN. We chose to start counting at rcv_nxt - 1 -+ * instead of the regular TCP ISN. -+ */ -+ tcp_sk(master_sk)->mptcp->rcv_isn = tcp_sk(master_sk)->rcv_nxt - 1; -+ -+ /* We need to update copied_seq of the master_sk to account for the -+ * already moved data to the meta receive queue. -+ */ -+ tcp_sk(master_sk)->copied_seq = tcp_sk(master_sk)->rcv_nxt; -+ -+ /* Handled by the master_sk */ -+ tcp_sk(meta_sk)->fastopen_rsk = NULL; -+ -+ return 0; -+} -+ -+int mptcp_check_req_master(struct sock *sk, struct sock *child, -+ struct request_sock *req, const struct sk_buff *skb, -+ int drop, u32 tsoff) -+{ -+ struct sock *meta_sk = child; -+ int ret; -+ -+ ret = __mptcp_check_req_master(child, req); -+ if (ret) -+ return ret; -+ child = tcp_sk(child)->mpcb->master_sk; -+ -+ sock_rps_save_rxhash(child, skb); -+ -+ /* drop indicates that we come from tcp_check_req and thus need to -+ * handle the request-socket fully. -+ */ -+ if (drop) { -+ tcp_synack_rtt_meas(child, req); -+ -+ inet_csk_reqsk_queue_drop(sk, req); -+ reqsk_queue_removed(&inet_csk(sk)->icsk_accept_queue, req); -+ if (!inet_csk_reqsk_queue_add(sk, req, meta_sk)) { -+ bh_unlock_sock(meta_sk); -+ /* No sock_put() of the meta needed. The reference has -+ * already been dropped in __mptcp_check_req_master(). -+ */ -+ sock_put(child); -+ return -1; -+ } -+ } else { -+ /* Thus, we come from syn-cookies */ -+ refcount_set(&req->rsk_refcnt, 1); -+ tcp_sk(meta_sk)->tsoffset = tsoff; -+ if (!inet_csk_reqsk_queue_add(sk, req, meta_sk)) { -+ bh_unlock_sock(meta_sk); -+ /* No sock_put() of the meta needed. The reference has -+ * already been dropped in __mptcp_check_req_master(). -+ */ -+ sock_put(child); -+ reqsk_put(req); -+ return -1; -+ } -+ } -+ -+ return 0; -+} -+ -+struct sock *mptcp_check_req_child(struct sock *meta_sk, -+ struct sock *child, -+ struct request_sock *req, -+ struct sk_buff *skb, -+ const struct mptcp_options_received *mopt) -+{ -+ struct tcp_sock *child_tp = tcp_sk(child); -+ struct mptcp_request_sock *mtreq = mptcp_rsk(req); -+ struct mptcp_cb *mpcb = tcp_sk(meta_sk)->mpcb; -+ u8 hash_mac_check[20]; -+ -+ child_tp->out_of_order_queue = RB_ROOT; -+ -+ if (!mopt->join_ack) { -+ MPTCP_INC_STATS(sock_net(meta_sk), MPTCP_MIB_JOINACKFAIL); -+ goto teardown; -+ } -+ -+ mptcp_hmac_sha1((u8 *)&mpcb->mptcp_rem_key, -+ (u8 *)&mpcb->mptcp_loc_key, -+ (u32 *)hash_mac_check, 2, -+ 4, (u8 *)&mtreq->mptcp_rem_nonce, -+ 4, (u8 *)&mtreq->mptcp_loc_nonce); -+ -+ if (memcmp(hash_mac_check, (char *)&mopt->mptcp_recv_mac, 20)) { -+ MPTCP_INC_STATS(sock_net(meta_sk), MPTCP_MIB_JOINACKMAC); -+ goto teardown; -+ } -+ -+ /* Point it to the same struct socket and wq as the meta_sk */ -+ sk_set_socket(child, meta_sk->sk_socket); -+ child->sk_wq = meta_sk->sk_wq; -+ -+ if (mptcp_add_sock(meta_sk, child, mtreq->loc_id, mtreq->rem_id, GFP_ATOMIC)) { -+ /* Has been inherited, but now child_tp->mptcp is NULL */ -+ child_tp->mpc = 0; -+ child_tp->ops = &tcp_specific; -+ -+ /* TODO when we support acking the third ack for new subflows, -+ * we should silently discard this third ack, by returning NULL. -+ * -+ * Maybe, at the retransmission we will have enough memory to -+ * fully add the socket to the meta-sk. -+ */ -+ goto teardown; -+ } -+ -+ /* The child is a clone of the meta socket, we must now reset -+ * some of the fields -+ */ -+ child_tp->mptcp->rcv_low_prio = mtreq->rcv_low_prio; -+ -+ /* We should allow proper increase of the snd/rcv-buffers. Thus, we -+ * use the original values instead of the bloated up ones from the -+ * clone. -+ */ -+ child->sk_sndbuf = mpcb->orig_sk_sndbuf; -+ child->sk_rcvbuf = mpcb->orig_sk_rcvbuf; -+ -+ child_tp->mptcp->slave_sk = 1; -+ child_tp->mptcp->snt_isn = tcp_rsk(req)->snt_isn; -+ child_tp->mptcp->rcv_isn = tcp_rsk(req)->rcv_isn; -+ child_tp->mptcp->init_rcv_wnd = req->rsk_rcv_wnd; -+ -+ child->sk_tsq_flags = 0; -+ -+ sock_rps_save_rxhash(child, skb); -+ tcp_synack_rtt_meas(child, req); -+ -+ /* Subflows do not use the accept queue, as they -+ * are attached immediately to the mpcb. -+ */ -+ inet_csk_reqsk_queue_drop(meta_sk, req); -+ reqsk_queue_removed(&inet_csk(meta_sk)->icsk_accept_queue, req); -+ -+ /* The refcnt is initialized to 2, because regular TCP will put him -+ * in the socket's listener queue. However, we do not have a listener-queue. -+ * So, we need to make sure that this request-sock indeed gets destroyed. -+ */ -+ reqsk_put(req); -+ -+ MPTCP_INC_STATS(sock_net(meta_sk), MPTCP_MIB_JOINACKRX); -+ return child; -+ -+teardown: -+ req->rsk_ops->send_reset(meta_sk, skb); -+ -+ /* Drop this request - sock creation failed. */ -+ inet_csk_reqsk_queue_drop(meta_sk, req); -+ reqsk_queue_removed(&inet_csk(meta_sk)->icsk_accept_queue, req); -+ inet_csk_prepare_forced_close(child); -+ tcp_done(child); -+ return meta_sk; -+} -+ -+int mptcp_init_tw_sock(struct sock *sk, struct tcp_timewait_sock *tw) -+{ -+ struct mptcp_tw *mptw; -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct mptcp_cb *mpcb = tp->mpcb; -+ -+ /* A subsocket in tw can only receive data. So, if we are in -+ * infinite-receive, then we should not reply with a data-ack or act -+ * upon general MPTCP-signaling. We prevent this by simply not creating -+ * the mptcp_tw_sock. -+ */ -+ if (mpcb->infinite_mapping_rcv) { -+ tw->mptcp_tw = NULL; -+ return 0; -+ } -+ -+ /* Alloc MPTCP-tw-sock */ -+ mptw = kmem_cache_alloc(mptcp_tw_cache, GFP_ATOMIC); -+ if (!mptw) { -+ tw->mptcp_tw = NULL; -+ return -ENOBUFS; -+ } -+ -+ atomic_inc(&mpcb->mpcb_refcnt); -+ -+ tw->mptcp_tw = mptw; -+ mptw->loc_key = mpcb->mptcp_loc_key; -+ mptw->meta_tw = mpcb->in_time_wait; -+ mptw->rcv_nxt = mptcp_get_rcv_nxt_64(mptcp_meta_tp(tp)); -+ if (mptw->meta_tw && mpcb->mptw_state != TCP_TIME_WAIT) -+ mptw->rcv_nxt++; -+ rcu_assign_pointer(mptw->mpcb, mpcb); -+ -+ spin_lock_bh(&mpcb->tw_lock); -+ list_add_rcu(&mptw->list, &tp->mpcb->tw_list); -+ mptw->in_list = 1; -+ spin_unlock_bh(&mpcb->tw_lock); -+ -+ return 0; -+} -+ -+void mptcp_twsk_destructor(struct tcp_timewait_sock *tw) -+{ -+ struct mptcp_cb *mpcb; -+ -+ rcu_read_lock(); -+ local_bh_disable(); -+ mpcb = rcu_dereference(tw->mptcp_tw->mpcb); -+ -+ /* If we are still holding a ref to the mpcb, we have to remove ourself -+ * from the list and drop the ref properly. -+ */ -+ if (mpcb && atomic_inc_not_zero(&mpcb->mpcb_refcnt)) { -+ spin_lock(&mpcb->tw_lock); -+ if (tw->mptcp_tw->in_list) { -+ list_del_rcu(&tw->mptcp_tw->list); -+ tw->mptcp_tw->in_list = 0; -+ /* Put, because we added it to the list */ -+ mptcp_mpcb_put(mpcb); -+ } -+ spin_unlock(&mpcb->tw_lock); -+ -+ /* Second time, because we increased it above */ -+ mptcp_mpcb_put(mpcb); -+ } -+ -+ local_bh_enable(); -+ rcu_read_unlock(); -+ -+ kmem_cache_free(mptcp_tw_cache, tw->mptcp_tw); -+} -+ -+/* Updates the rcv_nxt of the time-wait-socks and allows them to ack a -+ * data-fin. -+ */ -+void mptcp_time_wait(struct sock *meta_sk, int state, int timeo) -+{ -+ struct tcp_sock *meta_tp = tcp_sk(meta_sk); -+ struct mptcp_tw *mptw; -+ -+ if (mptcp_in_infinite_mapping_weak(meta_tp->mpcb)) { -+ struct sock *sk_it, *tmp; -+ -+ mptcp_for_each_sk_safe(meta_tp->mpcb, sk_it, tmp) { -+ if (sk_it->sk_state == TCP_CLOSE) -+ continue; -+ -+ tcp_sk(sk_it)->ops->time_wait(sk_it, state, timeo); -+ } -+ } -+ -+ /* Used for sockets that go into tw after the meta -+ * (see mptcp_init_tw_sock()) -+ */ -+ meta_tp->mpcb->in_time_wait = 1; -+ meta_tp->mpcb->mptw_state = state; -+ -+ /* Update the time-wait-sock's information */ -+ rcu_read_lock(); -+ local_bh_disable(); -+ list_for_each_entry_rcu(mptw, &meta_tp->mpcb->tw_list, list) { -+ mptw->meta_tw = 1; -+ mptw->rcv_nxt = mptcp_get_rcv_nxt_64(meta_tp); -+ -+ /* We want to ack a DATA_FIN, but are yet in FIN_WAIT_2 - -+ * pretend as if the DATA_FIN has already reached us, that way -+ * the checks in tcp_timewait_state_process will be good as the -+ * DATA_FIN comes in. -+ */ -+ if (state != TCP_TIME_WAIT) -+ mptw->rcv_nxt++; -+ } -+ local_bh_enable(); -+ rcu_read_unlock(); -+ -+ if (meta_sk->sk_state != TCP_CLOSE) -+ tcp_done(meta_sk); -+} -+ -+void mptcp_tsq_flags(struct sock *sk) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct sock *meta_sk = mptcp_meta_sk(sk); -+ -+ /* It will be handled as a regular deferred-call */ -+ if (is_meta_sk(sk)) -+ return; -+ -+ if (hlist_unhashed(&tp->mptcp->cb_list)) { -+ hlist_add_head(&tp->mptcp->cb_list, &tp->mpcb->callback_list); -+ /* We need to hold it here, as the sock_hold is not assured -+ * by the release_sock as it is done in regular TCP. -+ * -+ * The subsocket may get inet_csk_destroy'd while it is inside -+ * the callback_list. -+ */ -+ sock_hold(sk); -+ } -+ -+ if (!test_and_set_bit(MPTCP_SUB_DEFERRED, &meta_sk->sk_tsq_flags)) -+ sock_hold(meta_sk); -+} -+ -+void mptcp_tsq_sub_deferred(struct sock *meta_sk) -+{ -+ struct tcp_sock *meta_tp = tcp_sk(meta_sk); -+ struct mptcp_tcp_sock *mptcp; -+ struct hlist_node *tmp; -+ -+ __sock_put(meta_sk); -+ hlist_for_each_entry_safe(mptcp, tmp, &meta_tp->mpcb->callback_list, cb_list) { -+ struct tcp_sock *tp = mptcp->tp; -+ struct sock *sk = (struct sock *)tp; -+ -+ hlist_del_init(&mptcp->cb_list); -+ sk->sk_prot->release_cb(sk); -+ /* Final sock_put (cfr. mptcp_tsq_flags) */ -+ sock_put(sk); -+ } -+} -+ -+void mptcp_join_reqsk_init(const struct mptcp_cb *mpcb, -+ const struct request_sock *req, -+ struct sk_buff *skb) -+{ -+ struct mptcp_request_sock *mtreq = mptcp_rsk(req); -+ struct mptcp_options_received mopt; -+ u8 mptcp_hash_mac[20]; -+ -+ mptcp_init_mp_opt(&mopt); -+ tcp_parse_mptcp_options(skb, &mopt); -+ -+ mtreq->is_sub = 1; -+ inet_rsk(req)->mptcp_rqsk = 1; -+ -+ mtreq->mptcp_rem_nonce = mopt.mptcp_recv_nonce; -+ -+ mptcp_hmac_sha1((u8 *)&mpcb->mptcp_loc_key, -+ (u8 *)&mpcb->mptcp_rem_key, -+ (u32 *)mptcp_hash_mac, 2, -+ 4, (u8 *)&mtreq->mptcp_loc_nonce, -+ 4, (u8 *)&mtreq->mptcp_rem_nonce); -+ mtreq->mptcp_hash_tmac = *(u64 *)mptcp_hash_mac; -+ -+ mtreq->rem_id = mopt.rem_id; -+ mtreq->rcv_low_prio = mopt.low_prio; -+ inet_rsk(req)->saw_mpc = 1; -+ -+ MPTCP_INC_STATS(sock_net(mpcb->meta_sk), MPTCP_MIB_JOINSYNRX); -+} -+ -+void mptcp_reqsk_init(struct request_sock *req, const struct sock *sk, -+ const struct sk_buff *skb, bool want_cookie) -+{ -+ struct mptcp_options_received mopt; -+ struct mptcp_request_sock *mtreq = mptcp_rsk(req); -+ -+ mptcp_init_mp_opt(&mopt); -+ tcp_parse_mptcp_options(skb, &mopt); -+ -+ mtreq->dss_csum = mopt.dss_csum; -+ -+ if (want_cookie) { -+ if (!mptcp_reqsk_new_cookie(req, sk, &mopt, skb)) -+ /* No key available - back to regular TCP */ -+ inet_rsk(req)->mptcp_rqsk = 0; -+ return; -+ } -+ -+ mptcp_reqsk_new_mptcp(req, sk, &mopt, skb); -+} -+ -+void mptcp_cookies_reqsk_init(struct request_sock *req, -+ struct mptcp_options_received *mopt, -+ struct sk_buff *skb) -+{ -+ struct mptcp_request_sock *mtreq = mptcp_rsk(req); -+ -+ /* Absolutely need to always initialize this. */ -+ mtreq->hash_entry.pprev = NULL; -+ -+ mtreq->mptcp_rem_key = mopt->mptcp_sender_key; -+ mtreq->mptcp_loc_key = mopt->mptcp_receiver_key; -+ -+ /* Generate the token */ -+ mptcp_key_sha1(mtreq->mptcp_loc_key, &mtreq->mptcp_loc_token, NULL); -+ -+ rcu_read_lock(); -+ local_bh_disable(); -+ spin_lock(&mptcp_tk_hashlock); -+ -+ /* Check, if the key is still free */ -+ if (mptcp_reqsk_find_tk(mtreq->mptcp_loc_token) || -+ mptcp_find_token(mtreq->mptcp_loc_token)) -+ goto out; -+ -+ inet_rsk(req)->saw_mpc = 1; -+ mtreq->is_sub = 0; -+ inet_rsk(req)->mptcp_rqsk = 1; -+ mtreq->dss_csum = mopt->dss_csum; -+ -+out: -+ spin_unlock(&mptcp_tk_hashlock); -+ local_bh_enable(); -+ rcu_read_unlock(); -+} -+ -+int mptcp_conn_request(struct sock *sk, struct sk_buff *skb) -+{ -+ struct mptcp_options_received mopt; -+ -+ mptcp_init_mp_opt(&mopt); -+ tcp_parse_mptcp_options(skb, &mopt); -+ -+ if (mopt.is_mp_join) -+ return mptcp_do_join_short(skb, &mopt, sock_net(sk)); -+ if (mopt.drop_me) -+ goto drop; -+ -+ if (!sock_flag(sk, SOCK_MPTCP)) -+ mopt.saw_mpc = 0; -+ -+ if (skb->protocol == htons(ETH_P_IP)) { -+ if (mopt.saw_mpc) { -+ if (skb_rtable(skb)->rt_flags & -+ (RTCF_BROADCAST | RTCF_MULTICAST)) -+ goto drop; -+ -+ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_MPCAPABLEPASSIVE); -+ return tcp_conn_request(&mptcp_request_sock_ops, -+ &mptcp_request_sock_ipv4_ops, -+ sk, skb); -+ } -+ -+ return tcp_v4_conn_request(sk, skb); -+#if IS_ENABLED(CONFIG_IPV6) -+ } else { -+ if (mopt.saw_mpc) { -+ if (!ipv6_unicast_destination(skb)) -+ goto drop; -+ -+ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_MPCAPABLEPASSIVE); -+ return tcp_conn_request(&mptcp6_request_sock_ops, -+ &mptcp_request_sock_ipv6_ops, -+ sk, skb); -+ } -+ -+ return tcp_v6_conn_request(sk, skb); -+#endif -+ } -+drop: -+ __NET_INC_STATS(sock_net(sk), LINUX_MIB_LISTENDROPS); -+ return 0; -+} -+ -+static void __mptcp_get_info(const struct sock *meta_sk, -+ struct mptcp_meta_info *info) -+{ -+ const struct inet_connection_sock *meta_icsk = inet_csk(meta_sk); -+ const struct tcp_sock *meta_tp = tcp_sk(meta_sk); -+ u32 now = tcp_jiffies32; -+ -+ memset(info, 0, sizeof(*info)); -+ -+ info->mptcpi_state = meta_sk->sk_state; -+ info->mptcpi_retransmits = meta_icsk->icsk_retransmits; -+ info->mptcpi_probes = meta_icsk->icsk_probes_out; -+ info->mptcpi_backoff = meta_icsk->icsk_backoff; -+ -+ info->mptcpi_rto = jiffies_to_usecs(meta_icsk->icsk_rto); -+ -+ info->mptcpi_unacked = meta_tp->packets_out; -+ -+ info->mptcpi_last_data_sent = jiffies_to_msecs(now - meta_tp->lsndtime); -+ info->mptcpi_last_data_recv = jiffies_to_msecs(now - meta_icsk->icsk_ack.lrcvtime); -+ info->mptcpi_last_ack_recv = jiffies_to_msecs(now - meta_tp->rcv_tstamp); -+ -+ info->mptcpi_total_retrans = meta_tp->total_retrans; -+ -+ info->mptcpi_bytes_acked = meta_tp->bytes_acked; -+ info->mptcpi_bytes_received = meta_tp->bytes_received; -+} -+ -+static void mptcp_get_sub_info(struct sock *sk, struct mptcp_sub_info *info) -+{ -+ struct inet_sock *inet = inet_sk(sk); -+ -+ memset(info, 0, sizeof(*info)); -+ -+ if (sk->sk_family == AF_INET) { -+ info->src_v4.sin_family = AF_INET; -+ info->src_v4.sin_port = inet->inet_sport; -+ -+ info->src_v4.sin_addr.s_addr = inet->inet_rcv_saddr; -+ if (!info->src_v4.sin_addr.s_addr) -+ info->src_v4.sin_addr.s_addr = inet->inet_saddr; -+ -+ info->dst_v4.sin_family = AF_INET; -+ info->dst_v4.sin_port = inet->inet_dport; -+ info->dst_v4.sin_addr.s_addr = inet->inet_daddr; -+#if IS_ENABLED(CONFIG_IPV6) -+ } else { -+ struct ipv6_pinfo *np = inet6_sk(sk); -+ -+ info->src_v6.sin6_family = AF_INET6; -+ info->src_v6.sin6_port = inet->inet_sport; -+ -+ if (ipv6_addr_any(&sk->sk_v6_rcv_saddr)) -+ info->src_v6.sin6_addr = np->saddr; -+ else -+ info->src_v6.sin6_addr = sk->sk_v6_rcv_saddr; -+ -+ info->dst_v6.sin6_family = AF_INET6; -+ info->dst_v6.sin6_port = inet->inet_dport; -+ info->dst_v6.sin6_addr = sk->sk_v6_daddr; -+#endif -+ } -+} -+ -+int mptcp_get_info(const struct sock *meta_sk, char __user *optval, int optlen) -+{ -+ const struct tcp_sock *meta_tp = tcp_sk(meta_sk); -+ struct sock *sk; -+ -+ struct mptcp_meta_info meta_info; -+ struct mptcp_info m_info; -+ -+ unsigned int info_len; -+ -+ /* Check again with the lock held */ -+ if (!mptcp(meta_tp)) -+ return -EINVAL; -+ -+ if (copy_from_user(&m_info, optval, optlen)) -+ return -EFAULT; -+ -+ if (m_info.meta_info) { -+ unsigned int len; -+ -+ __mptcp_get_info(meta_sk, &meta_info); -+ -+ /* Need to set this, if user thinks that tcp_info is bigger than ours */ -+ len = min_t(unsigned int, m_info.meta_len, sizeof(meta_info)); -+ m_info.meta_len = len; -+ -+ if (copy_to_user((void __user *)m_info.meta_info, &meta_info, len)) -+ return -EFAULT; -+ } -+ -+ /* Need to set this, if user thinks that tcp_info is bigger than ours */ -+ info_len = min_t(unsigned int, m_info.tcp_info_len, sizeof(struct tcp_info)); -+ m_info.tcp_info_len = info_len; -+ -+ if (m_info.initial) { -+ struct mptcp_cb *mpcb = meta_tp->mpcb; -+ -+ if (mpcb->master_sk) { -+ struct tcp_info info; -+ -+ tcp_get_info(mpcb->master_sk, &info, true); -+ if (copy_to_user((void __user *)m_info.initial, &info, info_len)) -+ return -EFAULT; -+ } else if (meta_tp->record_master_info && mpcb->master_info) { -+ if (copy_to_user((void __user *)m_info.initial, mpcb->master_info, info_len)) -+ return -EFAULT; -+ } else { -+ return meta_tp->record_master_info ? -ENOMEM : -EINVAL; -+ } -+ } -+ -+ if (m_info.subflows) { -+ unsigned int len, sub_len = 0; -+ char __user *ptr; -+ -+ ptr = (char __user *)m_info.subflows; -+ len = m_info.sub_len; -+ -+ mptcp_for_each_sk(meta_tp->mpcb, sk) { -+ struct tcp_info t_info; -+ unsigned int tmp_len; -+ -+ tcp_get_info(sk, &t_info, true); -+ -+ tmp_len = min_t(unsigned int, len, info_len); -+ len -= tmp_len; -+ -+ if (copy_to_user(ptr, &t_info, tmp_len)) -+ return -EFAULT; -+ -+ ptr += tmp_len; -+ sub_len += tmp_len; -+ -+ if (len == 0) -+ break; -+ } -+ -+ m_info.sub_len = sub_len; -+ } -+ -+ if (m_info.subflow_info) { -+ unsigned int len, sub_info_len, total_sub_info_len = 0; -+ char __user *ptr; -+ -+ ptr = (char __user *)m_info.subflow_info; -+ len = m_info.total_sub_info_len; -+ -+ sub_info_len = min_t(unsigned int, m_info.sub_info_len, -+ sizeof(struct mptcp_sub_info)); -+ m_info.sub_info_len = sub_info_len; -+ -+ mptcp_for_each_sk(meta_tp->mpcb, sk) { -+ struct mptcp_sub_info m_sub_info; -+ unsigned int tmp_len; -+ -+ mptcp_get_sub_info(sk, &m_sub_info); -+ -+ tmp_len = min_t(unsigned int, len, sub_info_len); -+ len -= tmp_len; -+ -+ if (copy_to_user(ptr, &m_sub_info, tmp_len)) -+ return -EFAULT; -+ -+ ptr += tmp_len; -+ total_sub_info_len += tmp_len; -+ -+ if (len == 0) -+ break; -+ } -+ -+ m_info.total_sub_info_len = total_sub_info_len; -+ } -+ -+ if (copy_to_user(optval, &m_info, optlen)) -+ return -EFAULT; -+ -+ return 0; -+} -+ -+void mptcp_clear_sk(struct sock *sk, int size) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ -+ /* we do not want to clear tk_table field, because of RCU lookups */ -+ sk_prot_clear_nulls(sk, offsetof(struct tcp_sock, tk_table.next)); -+ -+ size -= offsetof(struct tcp_sock, tk_table.pprev); -+ memset((char *)&tp->tk_table.pprev, 0, size); -+} -+ -+static const struct snmp_mib mptcp_snmp_list[] = { -+ SNMP_MIB_ITEM("MPCapableSYNRX", MPTCP_MIB_MPCAPABLEPASSIVE), -+ SNMP_MIB_ITEM("MPCapableSYNTX", MPTCP_MIB_MPCAPABLEACTIVE), -+ SNMP_MIB_ITEM("MPCapableSYNACKRX", MPTCP_MIB_MPCAPABLEACTIVEACK), -+ SNMP_MIB_ITEM("MPCapableACKRX", MPTCP_MIB_MPCAPABLEPASSIVEACK), -+ SNMP_MIB_ITEM("MPCapableFallbackACK", MPTCP_MIB_MPCAPABLEPASSIVEFALLBACK), -+ SNMP_MIB_ITEM("MPCapableFallbackSYNACK", MPTCP_MIB_MPCAPABLEACTIVEFALLBACK), -+ SNMP_MIB_ITEM("MPCapableRetransFallback", MPTCP_MIB_MPCAPABLERETRANSFALLBACK), -+ SNMP_MIB_ITEM("MPTCPCsumEnabled", MPTCP_MIB_CSUMENABLED), -+ SNMP_MIB_ITEM("MPTCPRetrans", MPTCP_MIB_RETRANSSEGS), -+ SNMP_MIB_ITEM("MPFailRX", MPTCP_MIB_MPFAILRX), -+ SNMP_MIB_ITEM("MPCsumFail", MPTCP_MIB_CSUMFAIL), -+ SNMP_MIB_ITEM("MPFastcloseRX", MPTCP_MIB_FASTCLOSERX), -+ SNMP_MIB_ITEM("MPFastcloseTX", MPTCP_MIB_FASTCLOSETX), -+ SNMP_MIB_ITEM("MPFallbackAckSub", MPTCP_MIB_FBACKSUB), -+ SNMP_MIB_ITEM("MPFallbackAckInit", MPTCP_MIB_FBACKINIT), -+ SNMP_MIB_ITEM("MPFallbackDataSub", MPTCP_MIB_FBDATASUB), -+ SNMP_MIB_ITEM("MPFallbackDataInit", MPTCP_MIB_FBDATAINIT), -+ SNMP_MIB_ITEM("MPRemoveAddrSubDelete", MPTCP_MIB_REMADDRSUB), -+ SNMP_MIB_ITEM("MPJoinNoTokenFound", MPTCP_MIB_JOINNOTOKEN), -+ SNMP_MIB_ITEM("MPJoinAlreadyFallenback", MPTCP_MIB_JOINFALLBACK), -+ SNMP_MIB_ITEM("MPJoinSynTx", MPTCP_MIB_JOINSYNTX), -+ SNMP_MIB_ITEM("MPJoinSynRx", MPTCP_MIB_JOINSYNRX), -+ SNMP_MIB_ITEM("MPJoinSynAckRx", MPTCP_MIB_JOINSYNACKRX), -+ SNMP_MIB_ITEM("MPJoinSynAckHMacFailure", MPTCP_MIB_JOINSYNACKMAC), -+ SNMP_MIB_ITEM("MPJoinAckRx", MPTCP_MIB_JOINACKRX), -+ SNMP_MIB_ITEM("MPJoinAckHMacFailure", MPTCP_MIB_JOINACKMAC), -+ SNMP_MIB_ITEM("MPJoinAckMissing", MPTCP_MIB_JOINACKFAIL), -+ SNMP_MIB_ITEM("MPJoinAckRTO", MPTCP_MIB_JOINACKRTO), -+ SNMP_MIB_ITEM("MPJoinAckRexmit", MPTCP_MIB_JOINACKRXMIT), -+ SNMP_MIB_ITEM("NoDSSInWindow", MPTCP_MIB_NODSSWINDOW), -+ SNMP_MIB_ITEM("DSSNotMatching", MPTCP_MIB_DSSNOMATCH), -+ SNMP_MIB_ITEM("InfiniteMapRx", MPTCP_MIB_INFINITEMAPRX), -+ SNMP_MIB_ITEM("DSSNoMatchTCP", MPTCP_MIB_DSSTCPMISMATCH), -+ SNMP_MIB_ITEM("DSSTrimHead", MPTCP_MIB_DSSTRIMHEAD), -+ SNMP_MIB_ITEM("DSSSplitTail", MPTCP_MIB_DSSSPLITTAIL), -+ SNMP_MIB_ITEM("DSSPurgeOldSubSegs", MPTCP_MIB_PURGEOLD), -+ SNMP_MIB_ITEM("AddAddrRx", MPTCP_MIB_ADDADDRRX), -+ SNMP_MIB_ITEM("AddAddrTx", MPTCP_MIB_ADDADDRTX), -+ SNMP_MIB_ITEM("RemAddrRx", MPTCP_MIB_REMADDRRX), -+ SNMP_MIB_ITEM("RemAddrTx", MPTCP_MIB_REMADDRTX), -+ SNMP_MIB_SENTINEL -+}; -+ -+struct workqueue_struct *mptcp_wq; -+EXPORT_SYMBOL(mptcp_wq); -+ -+/* Output /proc/net/mptcp */ -+static int mptcp_pm_seq_show(struct seq_file *seq, void *v) -+{ -+ struct tcp_sock *meta_tp; -+ const struct net *net = seq->private; -+ int i, n = 0; -+ -+ seq_printf(seq, " sl loc_tok rem_tok v6 local_address remote_address st ns tx_queue rx_queue inode"); -+ seq_putc(seq, '\n'); -+ -+ for (i = 0; i < MPTCP_HASH_SIZE; i++) { -+ struct hlist_nulls_node *node; -+ rcu_read_lock(); -+ local_bh_disable(); -+ hlist_nulls_for_each_entry_rcu(meta_tp, node, -+ &tk_hashtable[i], tk_table) { -+ struct sock *meta_sk = (struct sock *)meta_tp; -+ struct inet_sock *isk = inet_sk(meta_sk); -+ struct mptcp_cb *mpcb = meta_tp->mpcb; -+ -+ if (!mptcp(meta_tp) || !net_eq(net, sock_net(meta_sk))) -+ continue; -+ -+ if (!mpcb) -+ continue; -+ -+ if (capable(CAP_NET_ADMIN)) { -+ seq_printf(seq, "%4d: %04X %04X ", n++, -+ mpcb->mptcp_loc_token, -+ mpcb->mptcp_rem_token); -+ } else { -+ seq_printf(seq, "%4d: %04X %04X ", n++, -1, -1); -+ } -+ if (meta_sk->sk_family == AF_INET || -+ mptcp_v6_is_v4_mapped(meta_sk)) { -+ seq_printf(seq, " 0 %08X:%04X %08X:%04X ", -+ isk->inet_rcv_saddr, -+ ntohs(isk->inet_sport), -+ isk->inet_daddr, -+ ntohs(isk->inet_dport)); -+#if IS_ENABLED(CONFIG_IPV6) -+ } else if (meta_sk->sk_family == AF_INET6) { -+ struct in6_addr *src = &meta_sk->sk_v6_rcv_saddr; -+ struct in6_addr *dst = &meta_sk->sk_v6_daddr; -+ seq_printf(seq, " 1 %08X%08X%08X%08X:%04X %08X%08X%08X%08X:%04X", -+ src->s6_addr32[0], src->s6_addr32[1], -+ src->s6_addr32[2], src->s6_addr32[3], -+ ntohs(isk->inet_sport), -+ dst->s6_addr32[0], dst->s6_addr32[1], -+ dst->s6_addr32[2], dst->s6_addr32[3], -+ ntohs(isk->inet_dport)); -+#endif -+ } -+ seq_printf(seq, " %02X %02X %08X:%08X %lu", -+ meta_sk->sk_state, mpcb->cnt_subflows, -+ meta_tp->write_seq - meta_tp->snd_una, -+ max_t(int, meta_tp->rcv_nxt - -+ meta_tp->copied_seq, 0), -+ sock_i_ino(meta_sk)); -+ seq_putc(seq, '\n'); -+ } -+ -+ local_bh_enable(); -+ rcu_read_unlock(); -+ } -+ -+ return 0; -+} -+ -+static int mptcp_pm_seq_open(struct inode *inode, struct file *file) -+{ -+ return single_open_net(inode, file, mptcp_pm_seq_show); -+} -+ -+static const struct file_operations mptcp_pm_seq_fops = { -+ .owner = THIS_MODULE, -+ .open = mptcp_pm_seq_open, -+ .read = seq_read, -+ .llseek = seq_lseek, -+ .release = single_release_net, -+}; -+ -+static int mptcp_snmp_seq_show(struct seq_file *seq, void *v) -+{ -+ struct net *net = seq->private; -+ int i; -+ -+ for (i = 0; mptcp_snmp_list[i].name != NULL; i++) -+ seq_printf(seq, "%-32s\t%ld\n", mptcp_snmp_list[i].name, -+ snmp_fold_field(net->mptcp.mptcp_statistics, -+ mptcp_snmp_list[i].entry)); -+ -+ return 0; -+} -+ -+static int mptcp_snmp_seq_open(struct inode *inode, struct file *file) -+{ -+ return single_open_net(inode, file, mptcp_snmp_seq_show); -+} -+ -+static const struct file_operations mptcp_snmp_seq_fops = { -+ .owner = THIS_MODULE, -+ .open = mptcp_snmp_seq_open, -+ .read = seq_read, -+ .llseek = seq_lseek, -+ .release = single_release_net, -+}; -+ -+static int mptcp_pm_init_net(struct net *net) -+{ -+ net->mptcp.mptcp_statistics = alloc_percpu(struct mptcp_mib); -+ if (!net->mptcp.mptcp_statistics) -+ goto out_mptcp_mibs; -+ -+#ifdef CONFIG_PROC_FS -+ net->mptcp.proc_net_mptcp = proc_net_mkdir(net, "mptcp_net", net->proc_net); -+ if (!net->mptcp.proc_net_mptcp) -+ goto out_proc_net_mptcp; -+ if (!proc_create("mptcp", S_IRUGO, net->mptcp.proc_net_mptcp, -+ &mptcp_pm_seq_fops)) -+ goto out_mptcp_net_mptcp; -+ if (!proc_create("snmp", S_IRUGO, net->mptcp.proc_net_mptcp, -+ &mptcp_snmp_seq_fops)) -+ goto out_mptcp_net_snmp; -+#endif -+ -+ return 0; -+ -+#ifdef CONFIG_PROC_FS -+out_mptcp_net_snmp: -+ remove_proc_entry("mptcp", net->mptcp.proc_net_mptcp); -+out_mptcp_net_mptcp: -+ remove_proc_subtree("mptcp_net", net->proc_net); -+ net->mptcp.proc_net_mptcp = NULL; -+out_proc_net_mptcp: -+ free_percpu(net->mptcp.mptcp_statistics); -+#endif -+out_mptcp_mibs: -+ return -ENOMEM; -+} -+ -+static void mptcp_pm_exit_net(struct net *net) -+{ -+ remove_proc_entry("snmp", net->mptcp.proc_net_mptcp); -+ remove_proc_entry("mptcp", net->mptcp.proc_net_mptcp); -+ remove_proc_subtree("mptcp_net", net->proc_net); -+ free_percpu(net->mptcp.mptcp_statistics); -+} -+ -+static struct pernet_operations mptcp_pm_proc_ops = { -+ .init = mptcp_pm_init_net, -+ .exit = mptcp_pm_exit_net, -+}; -+ -+/* General initialization of mptcp */ -+void __init mptcp_init(void) -+{ -+ int i; -+ struct ctl_table_header *mptcp_sysctl; -+ -+ mptcp_sock_cache = kmem_cache_create("mptcp_sock", -+ sizeof(struct mptcp_tcp_sock), -+ 0, SLAB_HWCACHE_ALIGN, -+ NULL); -+ if (!mptcp_sock_cache) -+ goto mptcp_sock_cache_failed; -+ -+ mptcp_cb_cache = kmem_cache_create("mptcp_cb", sizeof(struct mptcp_cb), -+ 0, SLAB_TYPESAFE_BY_RCU|SLAB_HWCACHE_ALIGN, -+ NULL); -+ if (!mptcp_cb_cache) -+ goto mptcp_cb_cache_failed; -+ -+ mptcp_tw_cache = kmem_cache_create("mptcp_tw", sizeof(struct mptcp_tw), -+ 0, SLAB_TYPESAFE_BY_RCU|SLAB_HWCACHE_ALIGN, -+ NULL); -+ if (!mptcp_tw_cache) -+ goto mptcp_tw_cache_failed; -+ -+ get_random_bytes(&mptcp_secret, sizeof(mptcp_secret)); -+ -+ mptcp_wq = alloc_workqueue("mptcp_wq", WQ_UNBOUND | WQ_MEM_RECLAIM, 8); -+ if (!mptcp_wq) -+ goto alloc_workqueue_failed; -+ -+ for (i = 0; i < MPTCP_HASH_SIZE; i++) { -+ INIT_HLIST_NULLS_HEAD(&tk_hashtable[i], i); -+ INIT_HLIST_NULLS_HEAD(&mptcp_reqsk_tk_htb[i], i); -+ } -+ -+ spin_lock_init(&mptcp_tk_hashlock); -+ -+ if (register_pernet_subsys(&mptcp_pm_proc_ops)) -+ goto pernet_failed; -+ -+#if IS_ENABLED(CONFIG_IPV6) -+ if (mptcp_pm_v6_init()) -+ goto mptcp_pm_v6_failed; -+#endif -+ if (mptcp_pm_v4_init()) -+ goto mptcp_pm_v4_failed; -+ -+ mptcp_sysctl = register_net_sysctl(&init_net, "net/mptcp", mptcp_table); -+ if (!mptcp_sysctl) -+ goto register_sysctl_failed; -+ -+ if (mptcp_register_path_manager(&mptcp_pm_default)) -+ goto register_pm_failed; -+ -+ if (mptcp_register_scheduler(&mptcp_sched_default)) -+ goto register_sched_failed; -+ -+ pr_info("MPTCP: Stable release v0.94.7"); -+ -+ mptcp_init_failed = false; -+ -+ return; -+ -+register_sched_failed: -+ mptcp_unregister_path_manager(&mptcp_pm_default); -+register_pm_failed: -+ unregister_net_sysctl_table(mptcp_sysctl); -+register_sysctl_failed: -+ mptcp_pm_v4_undo(); -+mptcp_pm_v4_failed: -+#if IS_ENABLED(CONFIG_IPV6) -+ mptcp_pm_v6_undo(); -+mptcp_pm_v6_failed: -+#endif -+ unregister_pernet_subsys(&mptcp_pm_proc_ops); -+pernet_failed: -+ destroy_workqueue(mptcp_wq); -+alloc_workqueue_failed: -+ kmem_cache_destroy(mptcp_tw_cache); -+mptcp_tw_cache_failed: -+ kmem_cache_destroy(mptcp_cb_cache); -+mptcp_cb_cache_failed: -+ kmem_cache_destroy(mptcp_sock_cache); -+mptcp_sock_cache_failed: -+ mptcp_init_failed = true; -+} -diff -aurN linux-4.14.174/net/mptcp/mptcp_fullmesh.c mptcp-mptcp_v0.94/net/mptcp/mptcp_fullmesh.c ---- linux-4.14.174/net/mptcp/mptcp_fullmesh.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_v0.94/net/mptcp/mptcp_fullmesh.c 2020-03-23 09:45:33.000000000 +0100 -@@ -0,0 +1,2016 @@ -+#include -+#include -+ -+#include -+#include -+ -+#if IS_ENABLED(CONFIG_IPV6) -+#include -+#include -+#endif -+ -+enum { -+ MPTCP_EVENT_ADD = 1, -+ MPTCP_EVENT_DEL, -+ MPTCP_EVENT_MOD, -+}; -+ -+#define MPTCP_SUBFLOW_RETRY_DELAY 1000 -+ -+/* Max number of local or remote addresses we can store. -+ * When changing, see the bitfield below in fullmesh_rem4/6. -+ */ -+#define MPTCP_MAX_ADDR 8 -+ -+struct fullmesh_rem4 { -+ u8 rem4_id; -+ u8 bitfield; -+ u8 retry_bitfield; -+ __be16 port; -+ struct in_addr addr; -+}; -+ -+struct fullmesh_rem6 { -+ u8 rem6_id; -+ u8 bitfield; -+ u8 retry_bitfield; -+ __be16 port; -+ struct in6_addr addr; -+}; -+ -+struct mptcp_loc_addr { -+ struct mptcp_loc4 locaddr4[MPTCP_MAX_ADDR]; -+ u8 loc4_bits; -+ u8 next_v4_index; -+ -+ struct mptcp_loc6 locaddr6[MPTCP_MAX_ADDR]; -+ u8 loc6_bits; -+ u8 next_v6_index; -+ struct rcu_head rcu; -+}; -+ -+struct mptcp_addr_event { -+ struct list_head list; -+ unsigned short family; -+ u8 code:7, -+ low_prio:1; -+ int if_idx; -+ union inet_addr addr; -+}; -+ -+struct fullmesh_priv { -+ /* Worker struct for subflow establishment */ -+ struct work_struct subflow_work; -+ /* Delayed worker, when the routing-tables are not yet ready. */ -+ struct delayed_work subflow_retry_work; -+ -+ /* Remote addresses */ -+ struct fullmesh_rem4 remaddr4[MPTCP_MAX_ADDR]; -+ struct fullmesh_rem6 remaddr6[MPTCP_MAX_ADDR]; -+ -+ struct mptcp_cb *mpcb; -+ -+ u16 remove_addrs; /* Addresses to remove */ -+ u8 announced_addrs_v4; /* IPv4 Addresses we did announce */ -+ u8 announced_addrs_v6; /* IPv6 Addresses we did announce */ -+ -+ u8 add_addr; /* Are we sending an add_addr? */ -+ -+ u8 rem4_bits; -+ u8 rem6_bits; -+ -+ /* Are we established the additional subflows for primary pair? */ -+ u8 first_pair:1; -+}; -+ -+struct mptcp_fm_ns { -+ struct mptcp_loc_addr __rcu *local; -+ spinlock_t local_lock; /* Protecting the above pointer */ -+ struct list_head events; -+ struct delayed_work address_worker; -+ -+ struct net *net; -+}; -+ -+static int num_subflows __read_mostly = 1; -+module_param(num_subflows, int, 0644); -+MODULE_PARM_DESC(num_subflows, "choose the number of subflows per pair of IP addresses of MPTCP connection"); -+ -+static int create_on_err __read_mostly; -+module_param(create_on_err, int, 0644); -+MODULE_PARM_DESC(create_on_err, "recreate the subflow upon a timeout"); -+ -+static struct mptcp_pm_ops full_mesh __read_mostly; -+ -+static void full_mesh_create_subflows(struct sock *meta_sk); -+ -+static struct mptcp_fm_ns *fm_get_ns(const struct net *net) -+{ -+ return (struct mptcp_fm_ns *)net->mptcp.path_managers[MPTCP_PM_FULLMESH]; -+} -+ -+static struct fullmesh_priv *fullmesh_get_priv(const struct mptcp_cb *mpcb) -+{ -+ return (struct fullmesh_priv *)&mpcb->mptcp_pm[0]; -+} -+ -+/* Find the first free index in the bitfield */ -+static int __mptcp_find_free_index(u8 bitfield, u8 base) -+{ -+ int i; -+ -+ /* There are anyways no free bits... */ -+ if (bitfield == 0xff) -+ goto exit; -+ -+ i = ffs(~(bitfield >> base)) - 1; -+ if (i < 0) -+ goto exit; -+ -+ /* No free bits when starting at base, try from 0 on */ -+ if (i + base >= sizeof(bitfield) * 8) -+ return __mptcp_find_free_index(bitfield, 0); -+ -+ return i + base; -+exit: -+ return -1; -+} -+ -+static int mptcp_find_free_index(u8 bitfield) -+{ -+ return __mptcp_find_free_index(bitfield, 0); -+} -+ -+static void mptcp_addv4_raddr(struct mptcp_cb *mpcb, -+ const struct in_addr *addr, -+ __be16 port, u8 id) -+{ -+ int i; -+ struct fullmesh_rem4 *rem4; -+ struct fullmesh_priv *fmp = fullmesh_get_priv(mpcb); -+ -+ mptcp_for_each_bit_set(fmp->rem4_bits, i) { -+ rem4 = &fmp->remaddr4[i]; -+ -+ /* Address is already in the list --- continue */ -+ if (rem4->rem4_id == id && -+ rem4->addr.s_addr == addr->s_addr && rem4->port == port) -+ return; -+ -+ /* This may be the case, when the peer is behind a NAT. He is -+ * trying to JOIN, thus sending the JOIN with a certain ID. -+ * However the src_addr of the IP-packet has been changed. We -+ * update the addr in the list, because this is the address as -+ * OUR BOX sees it. -+ */ -+ if (rem4->rem4_id == id && rem4->addr.s_addr != addr->s_addr) { -+ /* update the address */ -+ mptcp_debug("%s: updating old addr:%pI4 to addr %pI4 with id:%d\n", -+ __func__, &rem4->addr.s_addr, -+ &addr->s_addr, id); -+ rem4->addr.s_addr = addr->s_addr; -+ rem4->port = port; -+ mpcb->list_rcvd = 1; -+ return; -+ } -+ } -+ -+ i = mptcp_find_free_index(fmp->rem4_bits); -+ /* Do we have already the maximum number of local/remote addresses? */ -+ if (i < 0) { -+ mptcp_debug("%s: At max num of remote addresses: %d --- not adding address: %pI4\n", -+ __func__, MPTCP_MAX_ADDR, &addr->s_addr); -+ return; -+ } -+ -+ rem4 = &fmp->remaddr4[i]; -+ -+ /* Address is not known yet, store it */ -+ rem4->addr.s_addr = addr->s_addr; -+ rem4->port = port; -+ rem4->bitfield = 0; -+ rem4->retry_bitfield = 0; -+ rem4->rem4_id = id; -+ mpcb->list_rcvd = 1; -+ fmp->rem4_bits |= (1 << i); -+ -+ return; -+} -+ -+static void mptcp_addv6_raddr(struct mptcp_cb *mpcb, -+ const struct in6_addr *addr, -+ __be16 port, u8 id) -+{ -+ int i; -+ struct fullmesh_rem6 *rem6; -+ struct fullmesh_priv *fmp = fullmesh_get_priv(mpcb); -+ -+ mptcp_for_each_bit_set(fmp->rem6_bits, i) { -+ rem6 = &fmp->remaddr6[i]; -+ -+ /* Address is already in the list --- continue */ -+ if (rem6->rem6_id == id && -+ ipv6_addr_equal(&rem6->addr, addr) && rem6->port == port) -+ return; -+ -+ /* This may be the case, when the peer is behind a NAT. He is -+ * trying to JOIN, thus sending the JOIN with a certain ID. -+ * However the src_addr of the IP-packet has been changed. We -+ * update the addr in the list, because this is the address as -+ * OUR BOX sees it. -+ */ -+ if (rem6->rem6_id == id) { -+ /* update the address */ -+ mptcp_debug("%s: updating old addr: %pI6 to addr %pI6 with id:%d\n", -+ __func__, &rem6->addr, addr, id); -+ rem6->addr = *addr; -+ rem6->port = port; -+ mpcb->list_rcvd = 1; -+ return; -+ } -+ } -+ -+ i = mptcp_find_free_index(fmp->rem6_bits); -+ /* Do we have already the maximum number of local/remote addresses? */ -+ if (i < 0) { -+ mptcp_debug("%s: At max num of remote addresses: %d --- not adding address: %pI6\n", -+ __func__, MPTCP_MAX_ADDR, addr); -+ return; -+ } -+ -+ rem6 = &fmp->remaddr6[i]; -+ -+ /* Address is not known yet, store it */ -+ rem6->addr = *addr; -+ rem6->port = port; -+ rem6->bitfield = 0; -+ rem6->retry_bitfield = 0; -+ rem6->rem6_id = id; -+ mpcb->list_rcvd = 1; -+ fmp->rem6_bits |= (1 << i); -+ -+ return; -+} -+ -+static void mptcp_v4_rem_raddress(struct mptcp_cb *mpcb, u8 id) -+{ -+ int i; -+ struct fullmesh_priv *fmp = fullmesh_get_priv(mpcb); -+ -+ mptcp_for_each_bit_set(fmp->rem4_bits, i) { -+ if (fmp->remaddr4[i].rem4_id == id) { -+ /* remove address from bitfield */ -+ fmp->rem4_bits &= ~(1 << i); -+ -+ break; -+ } -+ } -+} -+ -+static void mptcp_v6_rem_raddress(const struct mptcp_cb *mpcb, u8 id) -+{ -+ int i; -+ struct fullmesh_priv *fmp = fullmesh_get_priv(mpcb); -+ -+ mptcp_for_each_bit_set(fmp->rem6_bits, i) { -+ if (fmp->remaddr6[i].rem6_id == id) { -+ /* remove address from bitfield */ -+ fmp->rem6_bits &= ~(1 << i); -+ -+ break; -+ } -+ } -+} -+ -+/* Sets the bitfield of the remote-address field */ -+static void mptcp_v4_set_init_addr_bit(const struct mptcp_cb *mpcb, -+ const struct in_addr *addr, u8 index) -+{ -+ int i; -+ struct fullmesh_priv *fmp = fullmesh_get_priv(mpcb); -+ -+ mptcp_for_each_bit_set(fmp->rem4_bits, i) { -+ if (fmp->remaddr4[i].addr.s_addr == addr->s_addr) { -+ fmp->remaddr4[i].bitfield |= (1 << index); -+ return; -+ } -+ } -+} -+ -+/* Sets the bitfield of the remote-address field */ -+static void mptcp_v6_set_init_addr_bit(struct mptcp_cb *mpcb, -+ const struct in6_addr *addr, u8 index) -+{ -+ int i; -+ struct fullmesh_priv *fmp = fullmesh_get_priv(mpcb); -+ -+ mptcp_for_each_bit_set(fmp->rem6_bits, i) { -+ if (ipv6_addr_equal(&fmp->remaddr6[i].addr, addr)) { -+ fmp->remaddr6[i].bitfield |= (1 << index); -+ return; -+ } -+ } -+} -+ -+static void mptcp_set_init_addr_bit(struct mptcp_cb *mpcb, -+ const union inet_addr *addr, -+ sa_family_t family, u8 id) -+{ -+ if (family == AF_INET) -+ mptcp_v4_set_init_addr_bit(mpcb, &addr->in, id); -+ else -+ mptcp_v6_set_init_addr_bit(mpcb, &addr->in6, id); -+} -+ -+static void mptcp_v4_subflows(struct sock *meta_sk, -+ const struct mptcp_loc4 *loc, -+ struct mptcp_rem4 *rem) -+{ -+ int i; -+ -+ for (i = 1; i < num_subflows; i++) -+ mptcp_init4_subsockets(meta_sk, loc, rem); -+} -+ -+#if IS_ENABLED(CONFIG_IPV6) -+static void mptcp_v6_subflows(struct sock *meta_sk, -+ const struct mptcp_loc6 *loc, -+ struct mptcp_rem6 *rem) -+{ -+ int i; -+ -+ for (i = 1; i < num_subflows; i++) -+ mptcp_init6_subsockets(meta_sk, loc, rem); -+} -+#endif -+ -+static void retry_subflow_worker(struct work_struct *work) -+{ -+ struct delayed_work *delayed_work = container_of(work, -+ struct delayed_work, -+ work); -+ struct fullmesh_priv *fmp = container_of(delayed_work, -+ struct fullmesh_priv, -+ subflow_retry_work); -+ struct mptcp_cb *mpcb = fmp->mpcb; -+ struct sock *meta_sk = mpcb->meta_sk; -+ struct mptcp_loc_addr *mptcp_local; -+ struct mptcp_fm_ns *fm_ns = fm_get_ns(sock_net(meta_sk)); -+ int iter = 0, i; -+ -+ /* We need a local (stable) copy of the address-list. Really, it is not -+ * such a big deal, if the address-list is not 100% up-to-date. -+ */ -+ rcu_read_lock_bh(); -+ mptcp_local = rcu_dereference_bh(fm_ns->local); -+ mptcp_local = kmemdup(mptcp_local, sizeof(*mptcp_local), GFP_ATOMIC); -+ rcu_read_unlock_bh(); -+ -+ if (!mptcp_local) -+ return; -+ -+next_subflow: -+ if (iter) { -+ release_sock(meta_sk); -+ mutex_unlock(&mpcb->mpcb_mutex); -+ -+ cond_resched(); -+ } -+ mutex_lock(&mpcb->mpcb_mutex); -+ lock_sock_nested(meta_sk, SINGLE_DEPTH_NESTING); -+ -+ if (!mptcp(tcp_sk(meta_sk))) -+ goto exit; -+ -+ iter++; -+ -+ if (sock_flag(meta_sk, SOCK_DEAD)) -+ goto exit; -+ -+ mptcp_for_each_bit_set(fmp->rem4_bits, i) { -+ struct fullmesh_rem4 *rem = &fmp->remaddr4[i]; -+ /* Do we need to retry establishing a subflow ? */ -+ if (rem->retry_bitfield) { -+ int i = mptcp_find_free_index(~rem->retry_bitfield); -+ struct mptcp_rem4 rem4; -+ -+ rem->bitfield |= (1 << i); -+ rem->retry_bitfield &= ~(1 << i); -+ -+ rem4.addr = rem->addr; -+ rem4.port = rem->port; -+ rem4.rem4_id = rem->rem4_id; -+ -+ mptcp_init4_subsockets(meta_sk, &mptcp_local->locaddr4[i], &rem4); -+ mptcp_v4_subflows(meta_sk, -+ &mptcp_local->locaddr4[i], -+ &rem4); -+ goto next_subflow; -+ } -+ } -+ -+#if IS_ENABLED(CONFIG_IPV6) -+ mptcp_for_each_bit_set(fmp->rem6_bits, i) { -+ struct fullmesh_rem6 *rem = &fmp->remaddr6[i]; -+ -+ /* Do we need to retry establishing a subflow ? */ -+ if (rem->retry_bitfield) { -+ int i = mptcp_find_free_index(~rem->retry_bitfield); -+ struct mptcp_rem6 rem6; -+ -+ rem->bitfield |= (1 << i); -+ rem->retry_bitfield &= ~(1 << i); -+ -+ rem6.addr = rem->addr; -+ rem6.port = rem->port; -+ rem6.rem6_id = rem->rem6_id; -+ -+ mptcp_init6_subsockets(meta_sk, &mptcp_local->locaddr6[i], &rem6); -+ mptcp_v6_subflows(meta_sk, -+ &mptcp_local->locaddr6[i], -+ &rem6); -+ goto next_subflow; -+ } -+ } -+#endif -+ -+exit: -+ kfree(mptcp_local); -+ release_sock(meta_sk); -+ mutex_unlock(&mpcb->mpcb_mutex); -+ mptcp_mpcb_put(mpcb); -+ sock_put(meta_sk); -+} -+ -+/** -+ * Create all new subflows, by doing calls to mptcp_initX_subsockets -+ * -+ * This function uses a goto next_subflow, to allow releasing the lock between -+ * new subflows and giving other processes a chance to do some work on the -+ * socket and potentially finishing the communication. -+ **/ -+static void create_subflow_worker(struct work_struct *work) -+{ -+ struct fullmesh_priv *fmp = container_of(work, struct fullmesh_priv, -+ subflow_work); -+ struct mptcp_cb *mpcb = fmp->mpcb; -+ struct sock *meta_sk = mpcb->meta_sk; -+ struct mptcp_loc_addr *mptcp_local; -+ const struct mptcp_fm_ns *fm_ns = fm_get_ns(sock_net(meta_sk)); -+ int iter = 0, retry = 0; -+ int i; -+ -+ /* We need a local (stable) copy of the address-list. Really, it is not -+ * such a big deal, if the address-list is not 100% up-to-date. -+ */ -+ rcu_read_lock_bh(); -+ mptcp_local = rcu_dereference_bh(fm_ns->local); -+ mptcp_local = kmemdup(mptcp_local, sizeof(*mptcp_local), GFP_ATOMIC); -+ rcu_read_unlock_bh(); -+ -+ if (!mptcp_local) -+ return; -+ -+next_subflow: -+ if (iter) { -+ release_sock(meta_sk); -+ mutex_unlock(&mpcb->mpcb_mutex); -+ -+ cond_resched(); -+ } -+ mutex_lock(&mpcb->mpcb_mutex); -+ lock_sock_nested(meta_sk, SINGLE_DEPTH_NESTING); -+ -+ if (sock_flag(meta_sk, SOCK_DEAD) || !mptcp(tcp_sk(meta_sk))) -+ goto exit; -+ -+ if (mpcb->master_sk && -+ !tcp_sk(mpcb->master_sk)->mptcp->fully_established) -+ goto exit; -+ -+ /* Create the additional subflows for the first pair */ -+ if (fmp->first_pair == 0 && mpcb->master_sk) { -+ struct mptcp_loc4 loc; -+ struct mptcp_rem4 rem; -+ -+ loc.addr.s_addr = inet_sk(meta_sk)->inet_saddr; -+ loc.loc4_id = 0; -+ loc.low_prio = 0; -+ loc.if_idx = mpcb->master_sk->sk_bound_dev_if; -+ -+ rem.addr.s_addr = inet_sk(meta_sk)->inet_daddr; -+ rem.port = inet_sk(meta_sk)->inet_dport; -+ rem.rem4_id = 0; /* Default 0 */ -+ -+ mptcp_v4_subflows(meta_sk, &loc, &rem); -+ -+ fmp->first_pair = 1; -+ } -+ iter++; -+ -+ mptcp_for_each_bit_set(fmp->rem4_bits, i) { -+ struct fullmesh_rem4 *rem; -+ u8 remaining_bits; -+ -+ rem = &fmp->remaddr4[i]; -+ remaining_bits = ~(rem->bitfield) & mptcp_local->loc4_bits; -+ -+ /* Are there still combinations to handle? */ -+ if (remaining_bits) { -+ int i = mptcp_find_free_index(~remaining_bits); -+ struct mptcp_rem4 rem4; -+ -+ rem->bitfield |= (1 << i); -+ -+ rem4.addr = rem->addr; -+ rem4.port = rem->port; -+ rem4.rem4_id = rem->rem4_id; -+ -+ /* If a route is not yet available then retry once */ -+ if (mptcp_init4_subsockets(meta_sk, &mptcp_local->locaddr4[i], -+ &rem4) == -ENETUNREACH) -+ retry = rem->retry_bitfield |= (1 << i); -+ else -+ mptcp_v4_subflows(meta_sk, -+ &mptcp_local->locaddr4[i], -+ &rem4); -+ goto next_subflow; -+ } -+ } -+ -+#if IS_ENABLED(CONFIG_IPV6) -+ if (fmp->first_pair == 0 && mpcb->master_sk) { -+ struct mptcp_loc6 loc; -+ struct mptcp_rem6 rem; -+ -+ loc.addr = inet6_sk(meta_sk)->saddr; -+ loc.loc6_id = 0; -+ loc.low_prio = 0; -+ loc.if_idx = mpcb->master_sk->sk_bound_dev_if; -+ -+ rem.addr = meta_sk->sk_v6_daddr; -+ rem.port = inet_sk(meta_sk)->inet_dport; -+ rem.rem6_id = 0; /* Default 0 */ -+ -+ mptcp_v6_subflows(meta_sk, &loc, &rem); -+ -+ fmp->first_pair = 1; -+ } -+ mptcp_for_each_bit_set(fmp->rem6_bits, i) { -+ struct fullmesh_rem6 *rem; -+ u8 remaining_bits; -+ -+ rem = &fmp->remaddr6[i]; -+ remaining_bits = ~(rem->bitfield) & mptcp_local->loc6_bits; -+ -+ /* Are there still combinations to handle? */ -+ if (remaining_bits) { -+ int i = mptcp_find_free_index(~remaining_bits); -+ struct mptcp_rem6 rem6; -+ -+ rem->bitfield |= (1 << i); -+ -+ rem6.addr = rem->addr; -+ rem6.port = rem->port; -+ rem6.rem6_id = rem->rem6_id; -+ -+ /* If a route is not yet available then retry once */ -+ if (mptcp_init6_subsockets(meta_sk, &mptcp_local->locaddr6[i], -+ &rem6) == -ENETUNREACH) -+ retry = rem->retry_bitfield |= (1 << i); -+ else -+ mptcp_v6_subflows(meta_sk, -+ &mptcp_local->locaddr6[i], -+ &rem6); -+ goto next_subflow; -+ } -+ } -+#endif -+ -+ if (retry && !delayed_work_pending(&fmp->subflow_retry_work)) { -+ sock_hold(meta_sk); -+ atomic_inc(&mpcb->mpcb_refcnt); -+ queue_delayed_work(mptcp_wq, &fmp->subflow_retry_work, -+ msecs_to_jiffies(MPTCP_SUBFLOW_RETRY_DELAY)); -+ } -+ -+exit: -+ kfree(mptcp_local); -+ release_sock(meta_sk); -+ mutex_unlock(&mpcb->mpcb_mutex); -+ mptcp_mpcb_put(mpcb); -+ sock_put(meta_sk); -+} -+ -+static void announce_remove_addr(u8 addr_id, struct sock *meta_sk) -+{ -+ struct mptcp_cb *mpcb = tcp_sk(meta_sk)->mpcb; -+ struct fullmesh_priv *fmp = fullmesh_get_priv(mpcb); -+ struct sock *sk = mptcp_select_ack_sock(meta_sk); -+ -+ fmp->remove_addrs |= (1 << addr_id); -+ mpcb->addr_signal = 1; -+ -+ if (sk) -+ tcp_send_ack(sk); -+} -+ -+static void update_addr_bitfields(struct sock *meta_sk, -+ const struct mptcp_loc_addr *mptcp_local) -+{ -+ struct mptcp_cb *mpcb = tcp_sk(meta_sk)->mpcb; -+ struct fullmesh_priv *fmp = fullmesh_get_priv(mpcb); -+ int i; -+ -+ /* The bits in announced_addrs_* always match with loc*_bits. So, a -+ * simple & operation unsets the correct bits, because these go from -+ * announced to non-announced -+ */ -+ fmp->announced_addrs_v4 &= mptcp_local->loc4_bits; -+ -+ mptcp_for_each_bit_set(fmp->rem4_bits, i) { -+ fmp->remaddr4[i].bitfield &= mptcp_local->loc4_bits; -+ fmp->remaddr4[i].retry_bitfield &= mptcp_local->loc4_bits; -+ } -+ -+ fmp->announced_addrs_v6 &= mptcp_local->loc6_bits; -+ -+ mptcp_for_each_bit_set(fmp->rem6_bits, i) { -+ fmp->remaddr6[i].bitfield &= mptcp_local->loc6_bits; -+ fmp->remaddr6[i].retry_bitfield &= mptcp_local->loc6_bits; -+ } -+} -+ -+static int mptcp_find_address(const struct mptcp_loc_addr *mptcp_local, -+ sa_family_t family, const union inet_addr *addr, -+ int if_idx) -+{ -+ int i; -+ u8 loc_bits; -+ bool found = false; -+ -+ if (family == AF_INET) -+ loc_bits = mptcp_local->loc4_bits; -+ else -+ loc_bits = mptcp_local->loc6_bits; -+ -+ mptcp_for_each_bit_set(loc_bits, i) { -+ if (family == AF_INET && -+ (!if_idx || mptcp_local->locaddr4[i].if_idx == if_idx) && -+ mptcp_local->locaddr4[i].addr.s_addr == addr->in.s_addr) { -+ found = true; -+ break; -+ } -+ if (family == AF_INET6 && -+ (!if_idx || mptcp_local->locaddr6[i].if_idx == if_idx) && -+ ipv6_addr_equal(&mptcp_local->locaddr6[i].addr, -+ &addr->in6)) { -+ found = true; -+ break; -+ } -+ } -+ -+ if (!found) -+ return -1; -+ -+ return i; -+} -+ -+static int mptcp_find_address_transp(const struct mptcp_loc_addr *mptcp_local, -+ sa_family_t family, int if_idx) -+{ -+ bool found = false; -+ u8 loc_bits; -+ int i; -+ -+ if (family == AF_INET) -+ loc_bits = mptcp_local->loc4_bits; -+ else -+ loc_bits = mptcp_local->loc6_bits; -+ -+ mptcp_for_each_bit_set(loc_bits, i) { -+ if (family == AF_INET && -+ (!if_idx || mptcp_local->locaddr4[i].if_idx == if_idx)) { -+ found = true; -+ break; -+ } -+ if (family == AF_INET6 && -+ (!if_idx || mptcp_local->locaddr6[i].if_idx == if_idx)) { -+ found = true; -+ break; -+ } -+ } -+ -+ if (!found) -+ return -1; -+ -+ return i; -+} -+ -+static void mptcp_address_worker(struct work_struct *work) -+{ -+ const struct delayed_work *delayed_work = container_of(work, -+ struct delayed_work, -+ work); -+ struct mptcp_fm_ns *fm_ns = container_of(delayed_work, -+ struct mptcp_fm_ns, -+ address_worker); -+ struct net *net = fm_ns->net; -+ struct mptcp_addr_event *event = NULL; -+ struct mptcp_loc_addr *mptcp_local, *old; -+ int i, id = -1; /* id is used in the socket-code on a delete-event */ -+ bool success; /* Used to indicate if we succeeded handling the event */ -+ -+next_event: -+ success = false; -+ kfree(event); -+ -+ /* First, let's dequeue an event from our event-list */ -+ rcu_read_lock_bh(); -+ spin_lock(&fm_ns->local_lock); -+ -+ event = list_first_entry_or_null(&fm_ns->events, -+ struct mptcp_addr_event, list); -+ if (!event) { -+ spin_unlock(&fm_ns->local_lock); -+ rcu_read_unlock_bh(); -+ return; -+ } -+ -+ list_del(&event->list); -+ -+ mptcp_local = rcu_dereference_bh(fm_ns->local); -+ -+ if (event->code == MPTCP_EVENT_DEL) { -+ id = mptcp_find_address(mptcp_local, event->family, -+ &event->addr, event->if_idx); -+ -+ /* Not in the list - so we don't care */ -+ if (id < 0) { -+ mptcp_debug("%s could not find id\n", __func__); -+ goto duno; -+ } -+ -+ old = mptcp_local; -+ mptcp_local = kmemdup(mptcp_local, sizeof(*mptcp_local), -+ GFP_ATOMIC); -+ if (!mptcp_local) -+ goto duno; -+ -+ if (event->family == AF_INET) -+ mptcp_local->loc4_bits &= ~(1 << id); -+ else -+ mptcp_local->loc6_bits &= ~(1 << id); -+ -+ rcu_assign_pointer(fm_ns->local, mptcp_local); -+ kfree_rcu(old, rcu); -+ } else { -+ int i = mptcp_find_address(mptcp_local, event->family, -+ &event->addr, event->if_idx); -+ int j = i; -+ -+ if (j < 0) { -+ /* Not in the list, so we have to find an empty slot */ -+ if (event->family == AF_INET) -+ i = __mptcp_find_free_index(mptcp_local->loc4_bits, -+ mptcp_local->next_v4_index); -+ if (event->family == AF_INET6) -+ i = __mptcp_find_free_index(mptcp_local->loc6_bits, -+ mptcp_local->next_v6_index); -+ -+ if (i < 0) { -+ mptcp_debug("%s no more space\n", __func__); -+ goto duno; -+ } -+ -+ /* It might have been a MOD-event. */ -+ event->code = MPTCP_EVENT_ADD; -+ } else { -+ /* Let's check if anything changes */ -+ if (event->family == AF_INET && -+ event->low_prio == mptcp_local->locaddr4[i].low_prio) -+ goto duno; -+ -+ if (event->family == AF_INET6 && -+ event->low_prio == mptcp_local->locaddr6[i].low_prio) -+ goto duno; -+ } -+ -+ old = mptcp_local; -+ mptcp_local = kmemdup(mptcp_local, sizeof(*mptcp_local), -+ GFP_ATOMIC); -+ if (!mptcp_local) -+ goto duno; -+ -+ if (event->family == AF_INET) { -+ mptcp_local->locaddr4[i].addr.s_addr = event->addr.in.s_addr; -+ mptcp_local->locaddr4[i].loc4_id = i + 1; -+ mptcp_local->locaddr4[i].low_prio = event->low_prio; -+ mptcp_local->locaddr4[i].if_idx = event->if_idx; -+ -+ mptcp_debug("%s updated IP %pI4 on ifidx %u prio %u id %u\n", -+ __func__, &event->addr.in.s_addr, -+ event->if_idx, event->low_prio, i + 1); -+ } else { -+ mptcp_local->locaddr6[i].addr = event->addr.in6; -+ mptcp_local->locaddr6[i].loc6_id = i + MPTCP_MAX_ADDR; -+ mptcp_local->locaddr6[i].low_prio = event->low_prio; -+ mptcp_local->locaddr6[i].if_idx = event->if_idx; -+ -+ mptcp_debug("%s updated IP %pI6 on ifidx %u prio %u id %u\n", -+ __func__, &event->addr.in6, -+ event->if_idx, event->low_prio, i + MPTCP_MAX_ADDR); -+ } -+ -+ if (j < 0) { -+ if (event->family == AF_INET) { -+ mptcp_local->loc4_bits |= (1 << i); -+ mptcp_local->next_v4_index = i + 1; -+ } else { -+ mptcp_local->loc6_bits |= (1 << i); -+ mptcp_local->next_v6_index = i + 1; -+ } -+ } -+ -+ rcu_assign_pointer(fm_ns->local, mptcp_local); -+ kfree_rcu(old, rcu); -+ } -+ success = true; -+ -+duno: -+ spin_unlock(&fm_ns->local_lock); -+ rcu_read_unlock_bh(); -+ -+ if (!success) -+ goto next_event; -+ -+ /* Now we iterate over the MPTCP-sockets and apply the event. */ -+ for (i = 0; i < MPTCP_HASH_SIZE; i++) { -+ const struct hlist_nulls_node *node; -+ struct tcp_sock *meta_tp; -+ -+ rcu_read_lock_bh(); -+ hlist_nulls_for_each_entry_rcu(meta_tp, node, &tk_hashtable[i], -+ tk_table) { -+ struct sock *meta_sk = (struct sock *)meta_tp, *sk; -+ bool meta_v4 = meta_sk->sk_family == AF_INET; -+ struct mptcp_cb *mpcb; -+ -+ if (sock_net(meta_sk) != net) -+ continue; -+ -+ if (meta_v4) { -+ /* skip IPv6 events if meta is IPv4 */ -+ if (event->family == AF_INET6) -+ continue; -+ } else if (event->family == AF_INET && meta_sk->sk_ipv6only) { -+ /* skip IPv4 events if IPV6_V6ONLY is set */ -+ continue; -+ } -+ -+ if (unlikely(!refcount_inc_not_zero(&meta_sk->sk_refcnt))) -+ continue; -+ -+ bh_lock_sock(meta_sk); -+ -+ mpcb = meta_tp->mpcb; -+ if (!mpcb) -+ goto next; -+ -+ if (!mptcp(meta_tp) || !is_meta_sk(meta_sk) || -+ mptcp_in_infinite_mapping_weak(mpcb)) -+ goto next; -+ -+ /* May be that the pm has changed in-between */ -+ if (mpcb->pm_ops != &full_mesh) -+ goto next; -+ -+ if (sock_owned_by_user(meta_sk)) { -+ if (!test_and_set_bit(MPTCP_PATH_MANAGER_DEFERRED, -+ &meta_sk->sk_tsq_flags)) -+ sock_hold(meta_sk); -+ -+ goto next; -+ } -+ -+ if (event->code == MPTCP_EVENT_ADD) { -+ struct fullmesh_priv *fmp = fullmesh_get_priv(mpcb); -+ -+ fmp->add_addr++; -+ mpcb->addr_signal = 1; -+ -+ sk = mptcp_select_ack_sock(meta_sk); -+ if (sk) -+ tcp_send_ack(sk); -+ -+ full_mesh_create_subflows(meta_sk); -+ } -+ -+ if (event->code == MPTCP_EVENT_DEL) { -+ struct sock *sk, *tmpsk; -+ struct mptcp_loc_addr *mptcp_local; -+ bool found = false; -+ -+ mptcp_local = rcu_dereference_bh(fm_ns->local); -+ -+ /* In any case, we need to update our bitfields */ -+ if (id >= 0) -+ update_addr_bitfields(meta_sk, mptcp_local); -+ -+ /* Look for the socket and remove him */ -+ mptcp_for_each_sk_safe(mpcb, sk, tmpsk) { -+ if ((event->family == AF_INET6 && -+ (sk->sk_family == AF_INET || -+ mptcp_v6_is_v4_mapped(sk))) || -+ (event->family == AF_INET && -+ (sk->sk_family == AF_INET6 && -+ !mptcp_v6_is_v4_mapped(sk)))) -+ continue; -+ -+ if (event->family == AF_INET && -+ (sk->sk_family == AF_INET || -+ mptcp_v6_is_v4_mapped(sk)) && -+ inet_sk(sk)->inet_saddr != event->addr.in.s_addr) -+ continue; -+ -+ if (event->family == AF_INET6 && -+ sk->sk_family == AF_INET6 && -+ !ipv6_addr_equal(&inet6_sk(sk)->saddr, &event->addr.in6)) -+ continue; -+ -+ /* Reinject, so that pf = 1 and so we -+ * won't select this one as the -+ * ack-sock. -+ */ -+ mptcp_reinject_data(sk, 0); -+ -+ /* We announce the removal of this id */ -+ announce_remove_addr(tcp_sk(sk)->mptcp->loc_id, meta_sk); -+ -+ mptcp_sub_force_close(sk); -+ found = true; -+ } -+ -+ if (found) -+ goto next; -+ -+ /* The id may have been given by the event, -+ * matching on a local address. And it may not -+ * have matched on one of the above sockets, -+ * because the client never created a subflow. -+ * So, we have to finally remove it here. -+ */ -+ if (id >= 0) { -+ u8 loc_id = id -+ + (event->family == AF_INET ? 1 : MPTCP_MAX_ADDR); -+ announce_remove_addr(loc_id, meta_sk); -+ } -+ } -+ -+ if (event->code == MPTCP_EVENT_MOD) { -+ struct sock *sk; -+ -+ mptcp_for_each_sk(mpcb, sk) { -+ struct tcp_sock *tp = tcp_sk(sk); -+ if (event->family == AF_INET && -+ (sk->sk_family == AF_INET || -+ mptcp_v6_is_v4_mapped(sk)) && -+ inet_sk(sk)->inet_saddr == event->addr.in.s_addr) { -+ if (event->low_prio != tp->mptcp->low_prio) { -+ tp->mptcp->send_mp_prio = 1; -+ tp->mptcp->low_prio = event->low_prio; -+ -+ tcp_send_ack(sk); -+ } -+ } -+ -+ if (event->family == AF_INET6 && -+ sk->sk_family == AF_INET6 && -+ !ipv6_addr_equal(&inet6_sk(sk)->saddr, &event->addr.in6)) { -+ if (event->low_prio != tp->mptcp->low_prio) { -+ tp->mptcp->send_mp_prio = 1; -+ tp->mptcp->low_prio = event->low_prio; -+ -+ tcp_send_ack(sk); -+ } -+ } -+ } -+ } -+next: -+ bh_unlock_sock(meta_sk); -+ sock_put(meta_sk); -+ } -+ rcu_read_unlock_bh(); -+ } -+ goto next_event; -+} -+ -+static struct mptcp_addr_event *lookup_similar_event(const struct net *net, -+ const struct mptcp_addr_event *event) -+{ -+ struct mptcp_addr_event *eventq; -+ struct mptcp_fm_ns *fm_ns = fm_get_ns(net); -+ -+ list_for_each_entry(eventq, &fm_ns->events, list) { -+ if (eventq->family != event->family) -+ continue; -+ if (eventq->if_idx != event->if_idx) -+ continue; -+ if (event->family == AF_INET) { -+ if (eventq->addr.in.s_addr == event->addr.in.s_addr) -+ return eventq; -+ } else { -+ if (ipv6_addr_equal(&eventq->addr.in6, &event->addr.in6)) -+ return eventq; -+ } -+ } -+ return NULL; -+} -+ -+/* We already hold the net-namespace MPTCP-lock */ -+static void add_pm_event(struct net *net, const struct mptcp_addr_event *event) -+{ -+ struct mptcp_addr_event *eventq = lookup_similar_event(net, event); -+ struct mptcp_fm_ns *fm_ns = fm_get_ns(net); -+ -+ if (eventq) { -+ switch (event->code) { -+ case MPTCP_EVENT_DEL: -+ mptcp_debug("%s del old_code %u\n", __func__, eventq->code); -+ list_del(&eventq->list); -+ kfree(eventq); -+ break; -+ case MPTCP_EVENT_ADD: -+ mptcp_debug("%s add old_code %u\n", __func__, eventq->code); -+ eventq->low_prio = event->low_prio; -+ eventq->code = MPTCP_EVENT_ADD; -+ return; -+ case MPTCP_EVENT_MOD: -+ mptcp_debug("%s mod old_code %u\n", __func__, eventq->code); -+ eventq->low_prio = event->low_prio; -+ eventq->code = MPTCP_EVENT_MOD; -+ return; -+ } -+ } -+ -+ /* OK, we have to add the new address to the wait queue */ -+ eventq = kmemdup(event, sizeof(struct mptcp_addr_event), GFP_ATOMIC); -+ if (!eventq) -+ return; -+ -+ list_add_tail(&eventq->list, &fm_ns->events); -+ -+ /* Create work-queue */ -+ if (!delayed_work_pending(&fm_ns->address_worker)) -+ queue_delayed_work(mptcp_wq, &fm_ns->address_worker, -+ msecs_to_jiffies(500)); -+} -+ -+static void addr4_event_handler(const struct in_ifaddr *ifa, unsigned long event, -+ struct net *net) -+{ -+ const struct net_device *netdev = ifa->ifa_dev->dev; -+ struct mptcp_fm_ns *fm_ns = fm_get_ns(net); -+ struct mptcp_addr_event mpevent; -+ -+ if (ifa->ifa_scope > RT_SCOPE_LINK || -+ ipv4_is_loopback(ifa->ifa_local)) -+ return; -+ -+ spin_lock_bh(&fm_ns->local_lock); -+ -+ mpevent.family = AF_INET; -+ mpevent.addr.in.s_addr = ifa->ifa_local; -+ mpevent.low_prio = (netdev->flags & IFF_MPBACKUP) ? 1 : 0; -+ mpevent.if_idx = netdev->ifindex; -+ -+ if (event == NETDEV_DOWN || !netif_running(netdev) || -+ (netdev->flags & IFF_NOMULTIPATH) || !(netdev->flags & IFF_UP)) -+ mpevent.code = MPTCP_EVENT_DEL; -+ else if (event == NETDEV_UP) -+ mpevent.code = MPTCP_EVENT_ADD; -+ else if (event == NETDEV_CHANGE) -+ mpevent.code = MPTCP_EVENT_MOD; -+ -+ mptcp_debug("%s created event for %pI4, code %u prio %u idx %u\n", __func__, -+ &ifa->ifa_local, mpevent.code, mpevent.low_prio, mpevent.if_idx); -+ add_pm_event(net, &mpevent); -+ -+ spin_unlock_bh(&fm_ns->local_lock); -+ return; -+} -+ -+/* React on IPv4-addr add/rem-events */ -+static int mptcp_pm_inetaddr_event(struct notifier_block *this, -+ unsigned long event, void *ptr) -+{ -+ const struct in_ifaddr *ifa = (struct in_ifaddr *)ptr; -+ struct net *net = dev_net(ifa->ifa_dev->dev); -+ -+ if (!(event == NETDEV_UP || event == NETDEV_DOWN || -+ event == NETDEV_CHANGE)) -+ return NOTIFY_DONE; -+ -+ addr4_event_handler(ifa, event, net); -+ -+ return NOTIFY_DONE; -+} -+ -+static struct notifier_block mptcp_pm_inetaddr_notifier = { -+ .notifier_call = mptcp_pm_inetaddr_event, -+}; -+ -+#if IS_ENABLED(CONFIG_IPV6) -+ -+/* IPV6-related address/interface watchers */ -+struct mptcp_dad_data { -+ struct timer_list timer; -+ struct inet6_ifaddr *ifa; -+}; -+ -+static void dad_callback(unsigned long arg); -+static int inet6_addr_event(struct notifier_block *this, -+ unsigned long event, void *ptr); -+ -+static bool ipv6_dad_finished(const struct inet6_ifaddr *ifa) -+{ -+ return !(ifa->flags & IFA_F_TENTATIVE) || -+ ifa->state > INET6_IFADDR_STATE_DAD; -+} -+ -+static void dad_init_timer(struct mptcp_dad_data *data, -+ struct inet6_ifaddr *ifa) -+{ -+ data->ifa = ifa; -+ data->timer.data = (unsigned long)data; -+ data->timer.function = dad_callback; -+ if (ifa->idev->cnf.rtr_solicit_delay) -+ data->timer.expires = jiffies + ifa->idev->cnf.rtr_solicit_delay; -+ else -+ data->timer.expires = jiffies + (HZ/10); -+} -+ -+static void dad_callback(unsigned long arg) -+{ -+ struct mptcp_dad_data *data = (struct mptcp_dad_data *)arg; -+ -+ /* DAD failed or IP brought down? */ -+ if (data->ifa->state == INET6_IFADDR_STATE_ERRDAD || -+ data->ifa->state == INET6_IFADDR_STATE_DEAD) -+ goto exit; -+ -+ if (!ipv6_dad_finished(data->ifa)) { -+ dad_init_timer(data, data->ifa); -+ add_timer(&data->timer); -+ return; -+ } -+ -+ inet6_addr_event(NULL, NETDEV_UP, data->ifa); -+ -+exit: -+ in6_ifa_put(data->ifa); -+ kfree(data); -+} -+ -+static inline void dad_setup_timer(struct inet6_ifaddr *ifa) -+{ -+ struct mptcp_dad_data *data; -+ -+ data = kmalloc(sizeof(*data), GFP_ATOMIC); -+ -+ if (!data) -+ return; -+ -+ init_timer(&data->timer); -+ dad_init_timer(data, ifa); -+ add_timer(&data->timer); -+ in6_ifa_hold(ifa); -+} -+ -+static void addr6_event_handler(const struct inet6_ifaddr *ifa, unsigned long event, -+ struct net *net) -+{ -+ const struct net_device *netdev = ifa->idev->dev; -+ int addr_type = ipv6_addr_type(&ifa->addr); -+ struct mptcp_fm_ns *fm_ns = fm_get_ns(net); -+ struct mptcp_addr_event mpevent; -+ -+ if (ifa->scope > RT_SCOPE_LINK || -+ addr_type == IPV6_ADDR_ANY || -+ (addr_type & IPV6_ADDR_LOOPBACK) || -+ (addr_type & IPV6_ADDR_LINKLOCAL)) -+ return; -+ -+ spin_lock_bh(&fm_ns->local_lock); -+ -+ mpevent.family = AF_INET6; -+ mpevent.addr.in6 = ifa->addr; -+ mpevent.low_prio = (netdev->flags & IFF_MPBACKUP) ? 1 : 0; -+ mpevent.if_idx = netdev->ifindex; -+ -+ if (event == NETDEV_DOWN || !netif_running(netdev) || -+ (netdev->flags & IFF_NOMULTIPATH) || !(netdev->flags & IFF_UP)) -+ mpevent.code = MPTCP_EVENT_DEL; -+ else if (event == NETDEV_UP) -+ mpevent.code = MPTCP_EVENT_ADD; -+ else if (event == NETDEV_CHANGE) -+ mpevent.code = MPTCP_EVENT_MOD; -+ -+ mptcp_debug("%s created event for %pI6, code %u prio %u idx %u\n", __func__, -+ &ifa->addr, mpevent.code, mpevent.low_prio, mpevent.if_idx); -+ add_pm_event(net, &mpevent); -+ -+ spin_unlock_bh(&fm_ns->local_lock); -+ return; -+} -+ -+/* React on IPv6-addr add/rem-events */ -+static int inet6_addr_event(struct notifier_block *this, unsigned long event, -+ void *ptr) -+{ -+ struct inet6_ifaddr *ifa6 = (struct inet6_ifaddr *)ptr; -+ struct net *net = dev_net(ifa6->idev->dev); -+ -+ if (!(event == NETDEV_UP || event == NETDEV_DOWN || -+ event == NETDEV_CHANGE)) -+ return NOTIFY_DONE; -+ -+ if (sysctl_mptcp_enabled && !ipv6_dad_finished(ifa6)) -+ dad_setup_timer(ifa6); -+ else -+ addr6_event_handler(ifa6, event, net); -+ -+ return NOTIFY_DONE; -+} -+ -+static struct notifier_block inet6_addr_notifier = { -+ .notifier_call = inet6_addr_event, -+}; -+ -+#endif -+ -+/* React on ifup/down-events */ -+static int netdev_event(struct notifier_block *this, unsigned long event, -+ void *ptr) -+{ -+ const struct net_device *dev = netdev_notifier_info_to_dev(ptr); -+ struct in_device *in_dev; -+#if IS_ENABLED(CONFIG_IPV6) -+ struct inet6_dev *in6_dev; -+#endif -+ -+ if (!(event == NETDEV_UP || event == NETDEV_DOWN || -+ event == NETDEV_CHANGE)) -+ return NOTIFY_DONE; -+ -+ rcu_read_lock(); -+ in_dev = __in_dev_get_rtnl(dev); -+ -+ if (in_dev) { -+ for_ifa(in_dev) { -+ mptcp_pm_inetaddr_event(NULL, event, ifa); -+ } endfor_ifa(in_dev); -+ } -+ -+#if IS_ENABLED(CONFIG_IPV6) -+ in6_dev = __in6_dev_get(dev); -+ -+ if (in6_dev) { -+ struct inet6_ifaddr *ifa6; -+ list_for_each_entry(ifa6, &in6_dev->addr_list, if_list) -+ inet6_addr_event(NULL, event, ifa6); -+ } -+#endif -+ -+ rcu_read_unlock(); -+ return NOTIFY_DONE; -+} -+ -+static struct notifier_block mptcp_pm_netdev_notifier = { -+ .notifier_call = netdev_event, -+}; -+ -+static void full_mesh_add_raddr(struct mptcp_cb *mpcb, -+ const union inet_addr *addr, -+ sa_family_t family, __be16 port, u8 id) -+{ -+ if (family == AF_INET) -+ mptcp_addv4_raddr(mpcb, &addr->in, port, id); -+ else -+ mptcp_addv6_raddr(mpcb, &addr->in6, port, id); -+} -+ -+static void full_mesh_new_session(const struct sock *meta_sk) -+{ -+ struct mptcp_loc_addr *mptcp_local; -+ struct mptcp_cb *mpcb = tcp_sk(meta_sk)->mpcb; -+ struct fullmesh_priv *fmp = fullmesh_get_priv(mpcb); -+ const struct mptcp_fm_ns *fm_ns = fm_get_ns(sock_net(meta_sk)); -+ struct tcp_sock *master_tp = tcp_sk(mpcb->master_sk); -+ int i, index, if_idx = 0; -+ union inet_addr saddr, daddr; -+ sa_family_t family = AF_INET; -+ bool meta_v4 = meta_sk->sk_family == AF_INET; -+ -+ /* Init local variables necessary for the rest */ -+ if (meta_sk->sk_family == AF_INET || mptcp_v6_is_v4_mapped(meta_sk)) { -+ saddr.ip = inet_sk(meta_sk)->inet_saddr; -+ daddr.ip = inet_sk(meta_sk)->inet_daddr; -+ if_idx = mpcb->master_sk->sk_bound_dev_if; -+ family = AF_INET; -+#if IS_ENABLED(CONFIG_IPV6) -+ } else { -+ saddr.in6 = inet6_sk(meta_sk)->saddr; -+ daddr.in6 = meta_sk->sk_v6_daddr; -+ if_idx = mpcb->master_sk->sk_bound_dev_if; -+ family = AF_INET6; -+#endif -+ } -+ -+ if (inet_sk(meta_sk)->transparent) -+ if_idx = inet_sk(meta_sk)->rx_dst_ifindex; -+ -+ rcu_read_lock_bh(); -+ mptcp_local = rcu_dereference(fm_ns->local); -+ -+ if (inet_sk(meta_sk)->transparent) -+ index = mptcp_find_address_transp(mptcp_local, family, if_idx); -+ else -+ index = mptcp_find_address(mptcp_local, family, &saddr, if_idx); -+ if (index < 0) -+ goto fallback; -+ -+ if (family == AF_INET) -+ master_tp->mptcp->low_prio = mptcp_local->locaddr4[index].low_prio; -+ else -+ master_tp->mptcp->low_prio = mptcp_local->locaddr6[index].low_prio; -+ master_tp->mptcp->send_mp_prio = master_tp->mptcp->low_prio; -+ -+ full_mesh_add_raddr(mpcb, &daddr, family, 0, 0); -+ mptcp_set_init_addr_bit(mpcb, &daddr, family, index); -+ -+ /* Initialize workqueue-struct */ -+ INIT_WORK(&fmp->subflow_work, create_subflow_worker); -+ INIT_DELAYED_WORK(&fmp->subflow_retry_work, retry_subflow_worker); -+ fmp->mpcb = mpcb; -+ -+ if (!meta_v4 && meta_sk->sk_ipv6only) -+ goto skip_ipv4; -+ -+ /* Look for the address among the local addresses */ -+ mptcp_for_each_bit_set(mptcp_local->loc4_bits, i) { -+ __be32 ifa_address = mptcp_local->locaddr4[i].addr.s_addr; -+ -+ /* We do not need to announce the initial subflow's address again */ -+ if (family == AF_INET && -+ (!if_idx || mptcp_local->locaddr4[i].if_idx == if_idx) && -+ saddr.ip == ifa_address) -+ continue; -+ -+ fmp->add_addr++; -+ mpcb->addr_signal = 1; -+ } -+ -+skip_ipv4: -+#if IS_ENABLED(CONFIG_IPV6) -+ /* skip IPv6 addresses if meta-socket is IPv4 */ -+ if (meta_v4) -+ goto skip_ipv6; -+ -+ mptcp_for_each_bit_set(mptcp_local->loc6_bits, i) { -+ const struct in6_addr *ifa6 = &mptcp_local->locaddr6[i].addr; -+ -+ /* We do not need to announce the initial subflow's address again */ -+ if (family == AF_INET6 && -+ (!if_idx || mptcp_local->locaddr6[i].if_idx == if_idx) && -+ ipv6_addr_equal(&saddr.in6, ifa6)) -+ continue; -+ -+ fmp->add_addr++; -+ mpcb->addr_signal = 1; -+ } -+ -+skip_ipv6: -+#endif -+ -+ rcu_read_unlock_bh(); -+ -+ if (family == AF_INET) -+ fmp->announced_addrs_v4 |= (1 << index); -+ else -+ fmp->announced_addrs_v6 |= (1 << index); -+ -+ for (i = fmp->add_addr; i && fmp->add_addr; i--) -+ tcp_send_ack(mpcb->master_sk); -+ -+ if (master_tp->mptcp->send_mp_prio) -+ tcp_send_ack(mpcb->master_sk); -+ -+ return; -+ -+fallback: -+ rcu_read_unlock_bh(); -+ mptcp_fallback_default(mpcb); -+ return; -+} -+ -+static void full_mesh_create_subflows(struct sock *meta_sk) -+{ -+ struct mptcp_cb *mpcb = tcp_sk(meta_sk)->mpcb; -+ struct fullmesh_priv *fmp = fullmesh_get_priv(mpcb); -+ -+ if (mptcp_in_infinite_mapping_weak(mpcb) || -+ mpcb->server_side || sock_flag(meta_sk, SOCK_DEAD)) -+ return; -+ -+ if (mpcb->master_sk && -+ !tcp_sk(mpcb->master_sk)->mptcp->fully_established) -+ return; -+ -+ if (!work_pending(&fmp->subflow_work)) { -+ sock_hold(meta_sk); -+ atomic_inc(&mpcb->mpcb_refcnt); -+ queue_work(mptcp_wq, &fmp->subflow_work); -+ } -+} -+ -+static void full_mesh_subflow_error(struct sock *meta_sk, struct sock *sk) -+{ -+ const struct mptcp_cb *mpcb = tcp_sk(meta_sk)->mpcb; -+ -+ if (!create_on_err) -+ return; -+ -+ if (mptcp_in_infinite_mapping_weak(mpcb) || -+ mpcb->server_side || sock_flag(meta_sk, SOCK_DEAD)) -+ return; -+ -+ if (sk->sk_err != ETIMEDOUT) -+ return; -+ -+ full_mesh_create_subflows(meta_sk); -+} -+ -+/* Called upon release_sock, if the socket was owned by the user during -+ * a path-management event. -+ */ -+static void full_mesh_release_sock(struct sock *meta_sk) -+{ -+ struct mptcp_loc_addr *mptcp_local; -+ struct mptcp_cb *mpcb = tcp_sk(meta_sk)->mpcb; -+ struct fullmesh_priv *fmp = fullmesh_get_priv(mpcb); -+ const struct mptcp_fm_ns *fm_ns = fm_get_ns(sock_net(meta_sk)); -+ struct sock *sk, *tmpsk; -+ bool meta_v4 = meta_sk->sk_family == AF_INET; -+ int i; -+ -+ rcu_read_lock_bh(); -+ mptcp_local = rcu_dereference(fm_ns->local); -+ -+ if (!meta_v4 && meta_sk->sk_ipv6only) -+ goto skip_ipv4; -+ -+ /* First, detect modifications or additions */ -+ mptcp_for_each_bit_set(mptcp_local->loc4_bits, i) { -+ struct in_addr ifa = mptcp_local->locaddr4[i].addr; -+ bool found = false; -+ -+ mptcp_for_each_sk(mpcb, sk) { -+ struct tcp_sock *tp = tcp_sk(sk); -+ -+ if (sk->sk_family == AF_INET6 && -+ !mptcp_v6_is_v4_mapped(sk)) -+ continue; -+ -+ if (inet_sk(sk)->inet_saddr != ifa.s_addr) -+ continue; -+ -+ found = true; -+ -+ if (mptcp_local->locaddr4[i].low_prio != tp->mptcp->low_prio) { -+ tp->mptcp->send_mp_prio = 1; -+ tp->mptcp->low_prio = mptcp_local->locaddr4[i].low_prio; -+ -+ tcp_send_ack(sk); -+ } -+ } -+ -+ if (!found) { -+ fmp->add_addr++; -+ mpcb->addr_signal = 1; -+ -+ sk = mptcp_select_ack_sock(meta_sk); -+ if (sk) -+ tcp_send_ack(sk); -+ full_mesh_create_subflows(meta_sk); -+ } -+ } -+ -+skip_ipv4: -+#if IS_ENABLED(CONFIG_IPV6) -+ /* skip IPv6 addresses if meta-socket is IPv4 */ -+ if (meta_v4) -+ goto removal; -+ -+ mptcp_for_each_bit_set(mptcp_local->loc6_bits, i) { -+ struct in6_addr ifa = mptcp_local->locaddr6[i].addr; -+ bool found = false; -+ -+ mptcp_for_each_sk(mpcb, sk) { -+ struct tcp_sock *tp = tcp_sk(sk); -+ -+ if (sk->sk_family == AF_INET || -+ mptcp_v6_is_v4_mapped(sk)) -+ continue; -+ -+ if (!ipv6_addr_equal(&inet6_sk(sk)->saddr, &ifa)) -+ continue; -+ -+ found = true; -+ -+ if (mptcp_local->locaddr6[i].low_prio != tp->mptcp->low_prio) { -+ tp->mptcp->send_mp_prio = 1; -+ tp->mptcp->low_prio = mptcp_local->locaddr6[i].low_prio; -+ -+ tcp_send_ack(sk); -+ } -+ } -+ -+ if (!found) { -+ fmp->add_addr++; -+ mpcb->addr_signal = 1; -+ -+ sk = mptcp_select_ack_sock(meta_sk); -+ if (sk) -+ tcp_send_ack(sk); -+ full_mesh_create_subflows(meta_sk); -+ } -+ } -+ -+removal: -+#endif -+ -+ /* Now, detect address-removals */ -+ mptcp_for_each_sk_safe(mpcb, sk, tmpsk) { -+ bool shall_remove = true; -+ -+ if (sk->sk_family == AF_INET || mptcp_v6_is_v4_mapped(sk)) { -+ mptcp_for_each_bit_set(mptcp_local->loc4_bits, i) { -+ if (inet_sk(sk)->inet_saddr == mptcp_local->locaddr4[i].addr.s_addr) { -+ shall_remove = false; -+ break; -+ } -+ } -+ } else { -+ mptcp_for_each_bit_set(mptcp_local->loc6_bits, i) { -+ if (ipv6_addr_equal(&inet6_sk(sk)->saddr, &mptcp_local->locaddr6[i].addr)) { -+ shall_remove = false; -+ break; -+ } -+ } -+ } -+ -+ if (shall_remove) { -+ /* Reinject, so that pf = 1 and so we -+ * won't select this one as the -+ * ack-sock. -+ */ -+ mptcp_reinject_data(sk, 0); -+ -+ announce_remove_addr(tcp_sk(sk)->mptcp->loc_id, -+ meta_sk); -+ -+ mptcp_sub_force_close(sk); -+ } -+ } -+ -+ /* Just call it optimistically. It actually cannot do any harm */ -+ update_addr_bitfields(meta_sk, mptcp_local); -+ -+ rcu_read_unlock_bh(); -+} -+ -+static int full_mesh_get_local_id(sa_family_t family, union inet_addr *addr, -+ struct net *net, bool *low_prio) -+{ -+ struct mptcp_loc_addr *mptcp_local; -+ const struct mptcp_fm_ns *fm_ns = fm_get_ns(net); -+ int index, id = -1; -+ -+ /* Handle the backup-flows */ -+ rcu_read_lock_bh(); -+ mptcp_local = rcu_dereference(fm_ns->local); -+ -+ index = mptcp_find_address(mptcp_local, family, addr, 0); -+ -+ if (index != -1) { -+ if (family == AF_INET) { -+ id = mptcp_local->locaddr4[index].loc4_id; -+ *low_prio = mptcp_local->locaddr4[index].low_prio; -+ } else { -+ id = mptcp_local->locaddr6[index].loc6_id; -+ *low_prio = mptcp_local->locaddr6[index].low_prio; -+ } -+ } -+ -+ -+ rcu_read_unlock_bh(); -+ -+ return id; -+} -+ -+static void full_mesh_addr_signal(struct sock *sk, unsigned *size, -+ struct tcp_out_options *opts, -+ struct sk_buff *skb) -+{ -+ const struct tcp_sock *tp = tcp_sk(sk); -+ struct mptcp_cb *mpcb = tp->mpcb; -+ struct sock *meta_sk = mpcb->meta_sk; -+ struct fullmesh_priv *fmp = fullmesh_get_priv(mpcb); -+ struct mptcp_loc_addr *mptcp_local; -+ struct mptcp_fm_ns *fm_ns = fm_get_ns(sock_net(sk)); -+ int remove_addr_len; -+ u8 unannouncedv4 = 0, unannouncedv6 = 0; -+ bool meta_v4 = meta_sk->sk_family == AF_INET; -+ -+ mpcb->addr_signal = 0; -+ -+ if (likely(!fmp->add_addr)) -+ goto remove_addr; -+ -+ rcu_read_lock_bh(); -+ mptcp_local = rcu_dereference(fm_ns->local); -+ -+ if (!meta_v4 && meta_sk->sk_ipv6only) -+ goto skip_ipv4; -+ -+ /* IPv4 */ -+ unannouncedv4 = (~fmp->announced_addrs_v4) & mptcp_local->loc4_bits; -+ if (unannouncedv4 && -+ ((mpcb->mptcp_ver == MPTCP_VERSION_0 && -+ MAX_TCP_OPTION_SPACE - *size >= MPTCP_SUB_LEN_ADD_ADDR4_ALIGN) || -+ (mpcb->mptcp_ver >= MPTCP_VERSION_1 && -+ MAX_TCP_OPTION_SPACE - *size >= MPTCP_SUB_LEN_ADD_ADDR4_ALIGN_VER1))) { -+ int ind = mptcp_find_free_index(~unannouncedv4); -+ -+ opts->options |= OPTION_MPTCP; -+ opts->mptcp_options |= OPTION_ADD_ADDR; -+ opts->add_addr4.addr_id = mptcp_local->locaddr4[ind].loc4_id; -+ opts->add_addr4.addr = mptcp_local->locaddr4[ind].addr; -+ opts->add_addr_v4 = 1; -+ if (mpcb->mptcp_ver >= MPTCP_VERSION_1) { -+ u8 mptcp_hash_mac[20]; -+ u8 no_key[8]; -+ -+ *(u64 *)no_key = 0; -+ mptcp_hmac_sha1((u8 *)&mpcb->mptcp_loc_key, -+ (u8 *)no_key, -+ (u32 *)mptcp_hash_mac, 2, -+ 1, (u8 *)&mptcp_local->locaddr4[ind].loc4_id, -+ 4, (u8 *)&opts->add_addr4.addr.s_addr); -+ opts->add_addr4.trunc_mac = *(u64 *)mptcp_hash_mac; -+ } -+ -+ if (skb) { -+ fmp->announced_addrs_v4 |= (1 << ind); -+ fmp->add_addr--; -+ } -+ -+ if (mpcb->mptcp_ver < MPTCP_VERSION_1) -+ *size += MPTCP_SUB_LEN_ADD_ADDR4_ALIGN; -+ if (mpcb->mptcp_ver >= MPTCP_VERSION_1) -+ *size += MPTCP_SUB_LEN_ADD_ADDR4_ALIGN_VER1; -+ -+ goto skip_ipv6; -+ } -+ -+ if (meta_v4) -+ goto skip_ipv6; -+skip_ipv4: -+ /* IPv6 */ -+ unannouncedv6 = (~fmp->announced_addrs_v6) & mptcp_local->loc6_bits; -+ if (unannouncedv6 && -+ ((mpcb->mptcp_ver == MPTCP_VERSION_0 && -+ MAX_TCP_OPTION_SPACE - *size >= MPTCP_SUB_LEN_ADD_ADDR6_ALIGN) || -+ (mpcb->mptcp_ver >= MPTCP_VERSION_1 && -+ MAX_TCP_OPTION_SPACE - *size >= MPTCP_SUB_LEN_ADD_ADDR6_ALIGN_VER1))) { -+ int ind = mptcp_find_free_index(~unannouncedv6); -+ -+ opts->options |= OPTION_MPTCP; -+ opts->mptcp_options |= OPTION_ADD_ADDR; -+ opts->add_addr6.addr_id = mptcp_local->locaddr6[ind].loc6_id; -+ opts->add_addr6.addr = mptcp_local->locaddr6[ind].addr; -+ opts->add_addr_v6 = 1; -+ if (mpcb->mptcp_ver >= MPTCP_VERSION_1) { -+ u8 mptcp_hash_mac[20]; -+ u8 no_key[8]; -+ -+ *(u64 *)no_key = 0; -+ mptcp_hmac_sha1((u8 *)&mpcb->mptcp_loc_key, -+ (u8 *)no_key, -+ (u32 *)mptcp_hash_mac, 2, -+ 1, (u8 *)&mptcp_local->locaddr6[ind].loc6_id, -+ 16, (u8 *)&opts->add_addr6.addr.s6_addr); -+ opts->add_addr6.trunc_mac = *(u64 *)mptcp_hash_mac; -+ } -+ -+ if (skb) { -+ fmp->announced_addrs_v6 |= (1 << ind); -+ fmp->add_addr--; -+ } -+ if (mpcb->mptcp_ver < MPTCP_VERSION_1) -+ *size += MPTCP_SUB_LEN_ADD_ADDR6_ALIGN; -+ if (mpcb->mptcp_ver >= MPTCP_VERSION_1) -+ *size += MPTCP_SUB_LEN_ADD_ADDR6_ALIGN_VER1; -+ } -+ -+skip_ipv6: -+ rcu_read_unlock_bh(); -+ -+ if (!unannouncedv4 && !unannouncedv6 && skb) -+ fmp->add_addr--; -+ -+remove_addr: -+ if (likely(!fmp->remove_addrs)) -+ goto exit; -+ -+ remove_addr_len = mptcp_sub_len_remove_addr_align(fmp->remove_addrs); -+ if (MAX_TCP_OPTION_SPACE - *size < remove_addr_len) -+ goto exit; -+ -+ opts->options |= OPTION_MPTCP; -+ opts->mptcp_options |= OPTION_REMOVE_ADDR; -+ opts->remove_addrs = fmp->remove_addrs; -+ *size += remove_addr_len; -+ if (skb) -+ fmp->remove_addrs = 0; -+ -+exit: -+ mpcb->addr_signal = !!(fmp->add_addr || fmp->remove_addrs); -+} -+ -+static void full_mesh_rem_raddr(struct mptcp_cb *mpcb, u8 rem_id) -+{ -+ mptcp_v4_rem_raddress(mpcb, rem_id); -+ mptcp_v6_rem_raddress(mpcb, rem_id); -+} -+ -+static void full_mesh_delete_subflow(struct sock *sk) -+{ -+ struct fullmesh_priv *fmp = fullmesh_get_priv(tcp_sk(sk)->mpcb); -+ struct mptcp_fm_ns *fm_ns = fm_get_ns(sock_net(sk)); -+ struct mptcp_loc_addr *mptcp_local; -+ int index, i; -+ -+ if (!create_on_err) -+ return; -+ -+ rcu_read_lock_bh(); -+ mptcp_local = rcu_dereference_bh(fm_ns->local); -+ -+ if (sk->sk_family == AF_INET || mptcp_v6_is_v4_mapped(sk)) { -+ union inet_addr saddr; -+ -+ saddr.ip = inet_sk(sk)->inet_saddr; -+ index = mptcp_find_address(mptcp_local, AF_INET, &saddr, -+ sk->sk_bound_dev_if); -+ if (index < 0) -+ goto out; -+ -+ mptcp_for_each_bit_set(fmp->rem4_bits, i) { -+ struct fullmesh_rem4 *rem4 = &fmp->remaddr4[i]; -+ -+ if (rem4->addr.s_addr != sk->sk_daddr) -+ continue; -+ -+ if (rem4->port && rem4->port != inet_sk(sk)->inet_dport) -+ continue; -+ -+ rem4->bitfield &= ~(1 << index); -+ } -+#if IS_ENABLED(CONFIG_IPV6) -+ } else { -+ union inet_addr saddr; -+ -+ saddr.in6 = inet6_sk(sk)->saddr; -+ index = mptcp_find_address(mptcp_local, AF_INET6, &saddr, -+ sk->sk_bound_dev_if); -+ if (index < 0) -+ goto out; -+ -+ mptcp_for_each_bit_set(fmp->rem6_bits, i) { -+ struct fullmesh_rem6 *rem6 = &fmp->remaddr6[i]; -+ -+ if (!ipv6_addr_equal(&rem6->addr, &sk->sk_v6_daddr)) -+ continue; -+ -+ if (rem6->port && rem6->port != inet_sk(sk)->inet_dport) -+ continue; -+ -+ rem6->bitfield &= ~(1 << index); -+ } -+#endif -+ } -+ -+out: -+ rcu_read_unlock_bh(); -+} -+ -+/* Output /proc/net/mptcp_fullmesh */ -+static int mptcp_fm_seq_show(struct seq_file *seq, void *v) -+{ -+ const struct net *net = seq->private; -+ struct mptcp_loc_addr *mptcp_local; -+ const struct mptcp_fm_ns *fm_ns = fm_get_ns(net); -+ int i; -+ -+ seq_printf(seq, "Index, Address-ID, Backup, IP-address, if-idx\n"); -+ -+ rcu_read_lock_bh(); -+ mptcp_local = rcu_dereference(fm_ns->local); -+ -+ seq_printf(seq, "IPv4, next v4-index: %u\n", mptcp_local->next_v4_index); -+ -+ mptcp_for_each_bit_set(mptcp_local->loc4_bits, i) { -+ struct mptcp_loc4 *loc4 = &mptcp_local->locaddr4[i]; -+ -+ seq_printf(seq, "%u, %u, %u, %pI4 %u\n", i, loc4->loc4_id, -+ loc4->low_prio, &loc4->addr, loc4->if_idx); -+ } -+ -+ seq_printf(seq, "IPv6, next v6-index: %u\n", mptcp_local->next_v6_index); -+ -+ mptcp_for_each_bit_set(mptcp_local->loc6_bits, i) { -+ struct mptcp_loc6 *loc6 = &mptcp_local->locaddr6[i]; -+ -+ seq_printf(seq, "%u, %u, %u, %pI6 %u\n", i, loc6->loc6_id, -+ loc6->low_prio, &loc6->addr, loc6->if_idx); -+ } -+ rcu_read_unlock_bh(); -+ -+ return 0; -+} -+ -+static int mptcp_fm_seq_open(struct inode *inode, struct file *file) -+{ -+ return single_open_net(inode, file, mptcp_fm_seq_show); -+} -+ -+static const struct file_operations mptcp_fm_seq_fops = { -+ .owner = THIS_MODULE, -+ .open = mptcp_fm_seq_open, -+ .read = seq_read, -+ .llseek = seq_lseek, -+ .release = single_release_net, -+}; -+ -+static int mptcp_fm_init_net(struct net *net) -+{ -+ struct mptcp_loc_addr *mptcp_local; -+ struct mptcp_fm_ns *fm_ns; -+ int err = 0; -+ -+ fm_ns = kzalloc(sizeof(*fm_ns), GFP_KERNEL); -+ if (!fm_ns) -+ return -ENOBUFS; -+ -+ mptcp_local = kzalloc(sizeof(*mptcp_local), GFP_KERNEL); -+ if (!mptcp_local) { -+ err = -ENOBUFS; -+ goto err_mptcp_local; -+ } -+ -+ if (!proc_create("mptcp_fullmesh", S_IRUGO, net->proc_net, -+ &mptcp_fm_seq_fops)) { -+ err = -ENOMEM; -+ goto err_seq_fops; -+ } -+ -+ mptcp_local->next_v4_index = 1; -+ -+ rcu_assign_pointer(fm_ns->local, mptcp_local); -+ INIT_DELAYED_WORK(&fm_ns->address_worker, mptcp_address_worker); -+ INIT_LIST_HEAD(&fm_ns->events); -+ spin_lock_init(&fm_ns->local_lock); -+ fm_ns->net = net; -+ net->mptcp.path_managers[MPTCP_PM_FULLMESH] = fm_ns; -+ -+ return 0; -+err_seq_fops: -+ kfree(mptcp_local); -+err_mptcp_local: -+ kfree(fm_ns); -+ return err; -+} -+ -+static void mptcp_fm_exit_net(struct net *net) -+{ -+ struct mptcp_addr_event *eventq, *tmp; -+ struct mptcp_fm_ns *fm_ns; -+ struct mptcp_loc_addr *mptcp_local; -+ -+ fm_ns = fm_get_ns(net); -+ cancel_delayed_work_sync(&fm_ns->address_worker); -+ -+ rcu_read_lock_bh(); -+ -+ mptcp_local = rcu_dereference_bh(fm_ns->local); -+ kfree_rcu(mptcp_local, rcu); -+ -+ spin_lock(&fm_ns->local_lock); -+ list_for_each_entry_safe(eventq, tmp, &fm_ns->events, list) { -+ list_del(&eventq->list); -+ kfree(eventq); -+ } -+ spin_unlock(&fm_ns->local_lock); -+ -+ rcu_read_unlock_bh(); -+ -+ remove_proc_entry("mptcp_fullmesh", net->proc_net); -+ -+ kfree(fm_ns); -+} -+ -+static struct pernet_operations full_mesh_net_ops = { -+ .init = mptcp_fm_init_net, -+ .exit = mptcp_fm_exit_net, -+}; -+ -+static struct mptcp_pm_ops full_mesh __read_mostly = { -+ .new_session = full_mesh_new_session, -+ .release_sock = full_mesh_release_sock, -+ .fully_established = full_mesh_create_subflows, -+ .new_remote_address = full_mesh_create_subflows, -+ .subflow_error = full_mesh_subflow_error, -+ .get_local_id = full_mesh_get_local_id, -+ .addr_signal = full_mesh_addr_signal, -+ .add_raddr = full_mesh_add_raddr, -+ .rem_raddr = full_mesh_rem_raddr, -+ .delete_subflow = full_mesh_delete_subflow, -+ .name = "fullmesh", -+ .owner = THIS_MODULE, -+}; -+ -+/* General initialization of MPTCP_PM */ -+static int __init full_mesh_register(void) -+{ -+ int ret; -+ -+ BUILD_BUG_ON(sizeof(struct fullmesh_priv) > MPTCP_PM_SIZE); -+ -+ ret = register_pernet_subsys(&full_mesh_net_ops); -+ if (ret) -+ goto out; -+ -+ ret = register_inetaddr_notifier(&mptcp_pm_inetaddr_notifier); -+ if (ret) -+ goto err_reg_inetaddr; -+ ret = register_netdevice_notifier(&mptcp_pm_netdev_notifier); -+ if (ret) -+ goto err_reg_netdev; -+ -+#if IS_ENABLED(CONFIG_IPV6) -+ ret = register_inet6addr_notifier(&inet6_addr_notifier); -+ if (ret) -+ goto err_reg_inet6addr; -+#endif -+ -+ ret = mptcp_register_path_manager(&full_mesh); -+ if (ret) -+ goto err_reg_pm; -+ -+out: -+ return ret; -+ -+ -+err_reg_pm: -+#if IS_ENABLED(CONFIG_IPV6) -+ unregister_inet6addr_notifier(&inet6_addr_notifier); -+err_reg_inet6addr: -+#endif -+ unregister_netdevice_notifier(&mptcp_pm_netdev_notifier); -+err_reg_netdev: -+ unregister_inetaddr_notifier(&mptcp_pm_inetaddr_notifier); -+err_reg_inetaddr: -+ unregister_pernet_subsys(&full_mesh_net_ops); -+ goto out; -+} -+ -+static void full_mesh_unregister(void) -+{ -+#if IS_ENABLED(CONFIG_IPV6) -+ unregister_inet6addr_notifier(&inet6_addr_notifier); -+#endif -+ unregister_netdevice_notifier(&mptcp_pm_netdev_notifier); -+ unregister_inetaddr_notifier(&mptcp_pm_inetaddr_notifier); -+ unregister_pernet_subsys(&full_mesh_net_ops); -+ mptcp_unregister_path_manager(&full_mesh); -+} -+ -+module_init(full_mesh_register); -+module_exit(full_mesh_unregister); -+ -+MODULE_AUTHOR("Christoph Paasch"); -+MODULE_LICENSE("GPL"); -+MODULE_DESCRIPTION("Full-Mesh MPTCP"); -+MODULE_VERSION("0.88"); -diff -aurN linux-4.14.174/net/mptcp/mptcp_input.c mptcp-mptcp_v0.94/net/mptcp/mptcp_input.c ---- linux-4.14.174/net/mptcp/mptcp_input.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_v0.94/net/mptcp/mptcp_input.c 2020-03-23 09:45:33.000000000 +0100 -@@ -0,0 +1,2475 @@ -+/* -+ * MPTCP implementation - Sending side -+ * -+ * Initial Design & Implementation: -+ * Sébastien Barré -+ * -+ * Current Maintainer & Author: -+ * Christoph Paasch -+ * -+ * Additional authors: -+ * Jaakko Korkeaniemi -+ * Gregory Detal -+ * Fabien Duchêne -+ * Andreas Seelinger -+ * Lavkesh Lahngir -+ * Andreas Ripke -+ * Vlad Dogaru -+ * Octavian Purdila -+ * John Ronan -+ * Catalin Nicutar -+ * Brandon Heller -+ * -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version -+ * 2 of the License, or (at your option) any later version. -+ */ -+ -+#include -+ -+#include -+#include -+#include -+ -+#include -+ -+/* is seq1 < seq2 ? */ -+static inline bool before64(const u64 seq1, const u64 seq2) -+{ -+ return (s64)(seq1 - seq2) < 0; -+} -+ -+/* is seq1 > seq2 ? */ -+#define after64(seq1, seq2) before64(seq2, seq1) -+ -+static inline void mptcp_become_fully_estab(struct sock *sk) -+{ -+ tcp_sk(sk)->mptcp->fully_established = 1; -+ -+ if (is_master_tp(tcp_sk(sk)) && -+ tcp_sk(sk)->mpcb->pm_ops->fully_established) -+ tcp_sk(sk)->mpcb->pm_ops->fully_established(mptcp_meta_sk(sk)); -+} -+ -+/* Similar to tcp_tso_acked without any memory accounting */ -+static inline int mptcp_tso_acked_reinject(const struct sock *meta_sk, -+ struct sk_buff *skb) -+{ -+ const struct tcp_sock *meta_tp = tcp_sk(meta_sk); -+ u32 packets_acked, len, delta_truesize; -+ -+ BUG_ON(!after(TCP_SKB_CB(skb)->end_seq, meta_tp->snd_una)); -+ -+ packets_acked = tcp_skb_pcount(skb); -+ -+ if (skb_unclone(skb, GFP_ATOMIC)) -+ return 0; -+ -+ len = meta_tp->snd_una - TCP_SKB_CB(skb)->seq; -+ delta_truesize = __pskb_trim_head(skb, len); -+ -+ TCP_SKB_CB(skb)->seq += len; -+ skb->ip_summed = CHECKSUM_PARTIAL; -+ -+ if (delta_truesize) -+ skb->truesize -= delta_truesize; -+ -+ /* Any change of skb->len requires recalculation of tso factor. */ -+ if (tcp_skb_pcount(skb) > 1) -+ tcp_set_skb_tso_segs(skb, tcp_skb_mss(skb)); -+ packets_acked -= tcp_skb_pcount(skb); -+ -+ if (packets_acked) { -+ BUG_ON(tcp_skb_pcount(skb) == 0); -+ BUG_ON(!before(TCP_SKB_CB(skb)->seq, TCP_SKB_CB(skb)->end_seq)); -+ } -+ -+ return packets_acked; -+} -+ -+/** -+ * Cleans the meta-socket retransmission queue and the reinject-queue. -+ * @sk must be the metasocket. -+ */ -+static void mptcp_clean_rtx_queue(struct sock *meta_sk, u32 prior_snd_una) -+{ -+ struct sk_buff *skb, *tmp; -+ struct tcp_sock *meta_tp = tcp_sk(meta_sk); -+ struct mptcp_cb *mpcb = meta_tp->mpcb; -+ bool acked = false; -+ u32 acked_pcount; -+ -+ while ((skb = tcp_write_queue_head(meta_sk)) && -+ skb != tcp_send_head(meta_sk)) { -+ bool fully_acked = true; -+ -+ if (before(meta_tp->snd_una, TCP_SKB_CB(skb)->end_seq)) { -+ if (tcp_skb_pcount(skb) == 1 || -+ !after(meta_tp->snd_una, TCP_SKB_CB(skb)->seq)) -+ break; -+ -+ acked_pcount = tcp_tso_acked(meta_sk, skb); -+ if (!acked_pcount) -+ break; -+ -+ fully_acked = false; -+ } else { -+ acked_pcount = tcp_skb_pcount(skb); -+ } -+ -+ acked = true; -+ meta_tp->packets_out -= acked_pcount; -+ meta_tp->retrans_stamp = 0; -+ -+ if (!fully_acked) -+ break; -+ -+ tcp_unlink_write_queue(skb, meta_sk); -+ -+ if (mptcp_is_data_fin(skb)) { -+ struct sock *sk_it, *sk_tmp; -+ -+ /* DATA_FIN has been acknowledged - now we can close -+ * the subflows -+ */ -+ mptcp_for_each_sk_safe(mpcb, sk_it, sk_tmp) { -+ unsigned long delay = 0; -+ -+ /* If we are the passive closer, don't trigger -+ * subflow-fin until the subflow has been finned -+ * by the peer - thus we add a delay. -+ */ -+ if (mpcb->passive_close && -+ sk_it->sk_state == TCP_ESTABLISHED) -+ delay = inet_csk(sk_it)->icsk_rto << 3; -+ -+ mptcp_sub_close(sk_it, delay); -+ } -+ } -+ sk_wmem_free_skb(meta_sk, skb); -+ } -+ /* Remove acknowledged data from the reinject queue */ -+ skb_queue_walk_safe(&mpcb->reinject_queue, skb, tmp) { -+ if (before(meta_tp->snd_una, TCP_SKB_CB(skb)->end_seq)) { -+ if (tcp_skb_pcount(skb) == 1 || -+ !after(meta_tp->snd_una, TCP_SKB_CB(skb)->seq)) -+ break; -+ -+ mptcp_tso_acked_reinject(meta_sk, skb); -+ break; -+ } -+ -+ __skb_unlink(skb, &mpcb->reinject_queue); -+ __kfree_skb(skb); -+ } -+ -+ if (likely(between(meta_tp->snd_up, prior_snd_una, meta_tp->snd_una))) -+ meta_tp->snd_up = meta_tp->snd_una; -+ -+ if (acked) { -+ tcp_rearm_rto(meta_sk); -+ /* Normally this is done in tcp_try_undo_loss - but MPTCP -+ * does not call this function. -+ */ -+ inet_csk(meta_sk)->icsk_retransmits = 0; -+ } -+} -+ -+/* Inspired by tcp_rcv_state_process */ -+static int mptcp_rcv_state_process(struct sock *meta_sk, struct sock *sk, -+ const struct sk_buff *skb, u32 data_seq, -+ u16 data_len) -+{ -+ struct tcp_sock *meta_tp = tcp_sk(meta_sk), *tp = tcp_sk(sk); -+ const struct tcphdr *th = tcp_hdr(skb); -+ -+ /* State-machine handling if FIN has been enqueued and he has -+ * been acked (snd_una == write_seq) - it's important that this -+ * here is after sk_wmem_free_skb because otherwise -+ * sk_forward_alloc is wrong upon inet_csk_destroy_sock() -+ */ -+ switch (meta_sk->sk_state) { -+ case TCP_FIN_WAIT1: { -+ struct dst_entry *dst; -+ int tmo; -+ -+ if (meta_tp->snd_una != meta_tp->write_seq) -+ break; -+ -+ tcp_set_state(meta_sk, TCP_FIN_WAIT2); -+ meta_sk->sk_shutdown |= SEND_SHUTDOWN; -+ -+ dst = __sk_dst_get(sk); -+ if (dst) -+ dst_confirm(dst); -+ -+ if (!sock_flag(meta_sk, SOCK_DEAD)) { -+ /* Wake up lingering close() */ -+ meta_sk->sk_state_change(meta_sk); -+ break; -+ } -+ -+ if (meta_tp->linger2 < 0 || -+ (data_len && -+ after(data_seq + data_len - (mptcp_is_data_fin2(skb, tp) ? 1 : 0), -+ meta_tp->rcv_nxt))) { -+ mptcp_send_active_reset(meta_sk, GFP_ATOMIC); -+ tcp_done(meta_sk); -+ __NET_INC_STATS(sock_net(meta_sk), LINUX_MIB_TCPABORTONDATA); -+ return 1; -+ } -+ -+ tmo = tcp_fin_time(meta_sk); -+ if (tmo > TCP_TIMEWAIT_LEN) { -+ inet_csk_reset_keepalive_timer(meta_sk, tmo - TCP_TIMEWAIT_LEN); -+ } else if (mptcp_is_data_fin2(skb, tp) || sock_owned_by_user(meta_sk)) { -+ /* Bad case. We could lose such FIN otherwise. -+ * It is not a big problem, but it looks confusing -+ * and not so rare event. We still can lose it now, -+ * if it spins in bh_lock_sock(), but it is really -+ * marginal case. -+ */ -+ inet_csk_reset_keepalive_timer(meta_sk, tmo); -+ } else { -+ meta_tp->ops->time_wait(meta_sk, TCP_FIN_WAIT2, tmo); -+ } -+ break; -+ } -+ case TCP_CLOSING: -+ case TCP_LAST_ACK: -+ if (meta_tp->snd_una == meta_tp->write_seq) { -+ tcp_done(meta_sk); -+ return 1; -+ } -+ break; -+ } -+ -+ /* step 7: process the segment text */ -+ switch (meta_sk->sk_state) { -+ case TCP_FIN_WAIT1: -+ case TCP_FIN_WAIT2: -+ /* RFC 793 says to queue data in these states, -+ * RFC 1122 says we MUST send a reset. -+ * BSD 4.4 also does reset. -+ */ -+ if (meta_sk->sk_shutdown & RCV_SHUTDOWN) { -+ if (TCP_SKB_CB(skb)->end_seq != TCP_SKB_CB(skb)->seq && -+ after(TCP_SKB_CB(skb)->end_seq - th->fin, tp->rcv_nxt) && -+ !mptcp_is_data_fin2(skb, tp)) { -+ __NET_INC_STATS(sock_net(meta_sk), LINUX_MIB_TCPABORTONDATA); -+ mptcp_send_active_reset(meta_sk, GFP_ATOMIC); -+ tcp_reset(meta_sk); -+ return 1; -+ } -+ } -+ break; -+ } -+ -+ return 0; -+} -+ -+/** -+ * @return: -+ * i) 1: Everything's fine. -+ * ii) -1: A reset has been sent on the subflow - csum-failure -+ * iii) 0: csum-failure but no reset sent, because it's the last subflow. -+ * Last packet should not be destroyed by the caller because it has -+ * been done here. -+ */ -+static int mptcp_verif_dss_csum(struct sock *sk) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct sk_buff *tmp, *tmp1, *last = NULL; -+ __wsum csum_tcp = 0; /* cumulative checksum of pld + mptcp-header */ -+ int ans = 1, overflowed = 0, offset = 0, dss_csum_added = 0; -+ int iter = 0; -+ u32 next_seq, offset_seq; -+ -+ skb_queue_walk_safe(&sk->sk_receive_queue, tmp, tmp1) { -+ unsigned int csum_len; -+ -+ /* init next seq in first round */ -+ if (!iter) -+ next_seq = TCP_SKB_CB(tmp)->seq; -+ offset_seq = next_seq - TCP_SKB_CB(tmp)->seq; -+ -+ if (before(tp->mptcp->map_subseq + tp->mptcp->map_data_len, TCP_SKB_CB(tmp)->end_seq)) -+ /* Mapping ends in the middle of the packet - -+ * csum only these bytes -+ */ -+ csum_len = tp->mptcp->map_subseq + tp->mptcp->map_data_len - TCP_SKB_CB(tmp)->seq; -+ else -+ csum_len = tmp->len; -+ -+ csum_len -= offset_seq; -+ offset = 0; -+ if (overflowed) { -+ char first_word[4]; -+ first_word[0] = 0; -+ first_word[1] = 0; -+ first_word[2] = 0; -+ first_word[3] = *(tmp->data + offset_seq); -+ csum_tcp = csum_partial(first_word, 4, csum_tcp); -+ offset = 1; -+ csum_len--; -+ overflowed = 0; -+ } -+ -+ csum_tcp = skb_checksum(tmp, offset + offset_seq, csum_len, -+ csum_tcp); -+ -+ /* Was it on an odd-length? Then we have to merge the next byte -+ * correctly (see above) -+ */ -+ if (csum_len != (csum_len & (~1))) -+ overflowed = 1; -+ -+ if (mptcp_is_data_seq(tmp) && !dss_csum_added) { -+ __be32 data_seq = htonl((u32)(tp->mptcp->map_data_seq >> 32)); -+ -+ /* If a 64-bit dss is present, we increase the offset -+ * by 4 bytes, as the high-order 64-bits will be added -+ * in the final csum_partial-call. -+ */ -+ u32 offset = skb_transport_offset(tmp) + -+ TCP_SKB_CB(tmp)->dss_off; -+ if (TCP_SKB_CB(tmp)->mptcp_flags & MPTCPHDR_SEQ64_SET) -+ offset += 4; -+ -+ csum_tcp = skb_checksum(tmp, offset, -+ MPTCP_SUB_LEN_SEQ_CSUM, -+ csum_tcp); -+ -+ csum_tcp = csum_partial(&data_seq, -+ sizeof(data_seq), csum_tcp); -+ -+ dss_csum_added = 1; /* Just do it once */ -+ } -+ last = tmp; -+ iter++; -+ -+ if (!skb_queue_is_last(&sk->sk_receive_queue, tmp) && -+ !before(TCP_SKB_CB(tmp1)->seq, -+ tp->mptcp->map_subseq + tp->mptcp->map_data_len)) -+ break; -+ next_seq = TCP_SKB_CB(tmp)->end_seq; -+ } -+ -+ /* Now, checksum must be 0 */ -+ if (unlikely(csum_fold(csum_tcp))) { -+ pr_err("%s csum is wrong: %#x data_seq %u dss_csum_added %d overflowed %d iterations %d\n", -+ __func__, csum_fold(csum_tcp), TCP_SKB_CB(last)->seq, -+ dss_csum_added, overflowed, iter); -+ -+ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_CSUMFAIL); -+ tp->mptcp->send_mp_fail = 1; -+ -+ /* map_data_seq is the data-seq number of the -+ * mapping we are currently checking -+ */ -+ tp->mpcb->csum_cutoff_seq = tp->mptcp->map_data_seq; -+ -+ if (tp->mpcb->cnt_subflows > 1) { -+ mptcp_send_reset(sk); -+ ans = -1; -+ } else { -+ tp->mpcb->send_infinite_mapping = 1; -+ -+ /* Need to purge the rcv-queue as it's no more valid */ -+ while ((tmp = __skb_dequeue(&sk->sk_receive_queue)) != NULL) { -+ tp->copied_seq = TCP_SKB_CB(tmp)->end_seq; -+ kfree_skb(tmp); -+ } -+ -+ ans = 0; -+ } -+ } -+ -+ return ans; -+} -+ -+static inline void mptcp_prepare_skb(struct sk_buff *skb, -+ const struct sock *sk) -+{ -+ const struct tcp_sock *tp = tcp_sk(sk); -+ struct tcp_skb_cb *tcb = TCP_SKB_CB(skb); -+ u32 inc = 0, end_seq = tcb->end_seq; -+ -+ if (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN) -+ end_seq--; -+ /* If skb is the end of this mapping (end is always at mapping-boundary -+ * thanks to the splitting/trimming), then we need to increase -+ * data-end-seq by 1 if this here is a data-fin. -+ * -+ * We need to do -1 because end_seq includes the subflow-FIN. -+ */ -+ if (tp->mptcp->map_data_fin && -+ end_seq == tp->mptcp->map_subseq + tp->mptcp->map_data_len) { -+ inc = 1; -+ -+ /* We manually set the fin-flag if it is a data-fin. For easy -+ * processing in tcp_recvmsg. -+ */ -+ TCP_SKB_CB(skb)->tcp_flags |= TCPHDR_FIN; -+ } else { -+ /* We may have a subflow-fin with data but without data-fin */ -+ TCP_SKB_CB(skb)->tcp_flags &= ~TCPHDR_FIN; -+ } -+ -+ /* Adapt data-seq's to the packet itself. We kinda transform the -+ * dss-mapping to a per-packet granularity. This is necessary to -+ * correctly handle overlapping mappings coming from different -+ * subflows. Otherwise it would be a complete mess. -+ */ -+ tcb->seq = ((u32)tp->mptcp->map_data_seq) + tcb->seq - tp->mptcp->map_subseq; -+ tcb->end_seq = tcb->seq + skb->len + inc; -+} -+ -+static inline void mptcp_reset_mapping(struct tcp_sock *tp, u32 old_copied_seq) -+{ -+ tp->mptcp->map_data_len = 0; -+ tp->mptcp->map_data_seq = 0; -+ tp->mptcp->map_subseq = 0; -+ tp->mptcp->map_data_fin = 0; -+ tp->mptcp->mapping_present = 0; -+ -+ /* In infinite mapping receiver mode, we have to advance the implied -+ * data-sequence number when we progress the subflow's data. -+ */ -+ if (tp->mpcb->infinite_mapping_rcv) -+ tp->mpcb->infinite_rcv_seq += (tp->copied_seq - old_copied_seq); -+} -+ -+/* The DSS-mapping received on the sk only covers the second half of the skb -+ * (cut at seq). We trim the head from the skb. -+ * Data will be freed upon kfree(). -+ * -+ * Inspired by tcp_trim_head(). -+ */ -+static void mptcp_skb_trim_head(struct sk_buff *skb, struct sock *sk, u32 seq) -+{ -+ int len = seq - TCP_SKB_CB(skb)->seq; -+ u32 new_seq = TCP_SKB_CB(skb)->seq + len; -+ u32 delta_truesize; -+ -+ delta_truesize = __pskb_trim_head(skb, len); -+ -+ TCP_SKB_CB(skb)->seq = new_seq; -+ -+ if (delta_truesize) { -+ skb->truesize -= delta_truesize; -+ atomic_sub(delta_truesize, &sk->sk_rmem_alloc); -+ sk_mem_uncharge(sk, delta_truesize); -+ } -+} -+ -+/* The DSS-mapping received on the sk only covers the first half of the skb -+ * (cut at seq). We create a second skb (@return), and queue it in the rcv-queue -+ * as further packets may resolve the mapping of the second half of data. -+ * -+ * Inspired by tcp_fragment(). -+ */ -+static int mptcp_skb_split_tail(struct sk_buff *skb, struct sock *sk, u32 seq) -+{ -+ struct sk_buff *buff; -+ int nsize; -+ int nlen, len; -+ u8 flags; -+ -+ len = seq - TCP_SKB_CB(skb)->seq; -+ nsize = skb_headlen(skb) - len + tcp_sk(sk)->tcp_header_len; -+ if (nsize < 0) -+ nsize = 0; -+ -+ /* Get a new skb... force flag on. */ -+ buff = alloc_skb(nsize, GFP_ATOMIC); -+ if (buff == NULL) -+ return -ENOMEM; -+ -+ skb_reserve(buff, tcp_sk(sk)->tcp_header_len); -+ skb_reset_transport_header(buff); -+ -+ flags = TCP_SKB_CB(skb)->tcp_flags; -+ TCP_SKB_CB(skb)->tcp_flags = flags & ~(TCPHDR_FIN); -+ TCP_SKB_CB(buff)->tcp_flags = flags; -+ -+ /* We absolutly need to call skb_set_owner_r before refreshing the -+ * truesize of buff, otherwise the moved data will account twice. -+ */ -+ skb_set_owner_r(buff, sk); -+ nlen = skb->len - len - nsize; -+ buff->truesize += nlen; -+ skb->truesize -= nlen; -+ -+ /* Correct the sequence numbers. */ -+ TCP_SKB_CB(buff)->seq = TCP_SKB_CB(skb)->seq + len; -+ TCP_SKB_CB(buff)->end_seq = TCP_SKB_CB(skb)->end_seq; -+ TCP_SKB_CB(skb)->end_seq = TCP_SKB_CB(buff)->seq; -+ -+ skb_split(skb, buff, len); -+ -+ __skb_queue_after(&sk->sk_receive_queue, skb, buff); -+ -+ return 0; -+} -+ -+/* @return: 0 everything is fine. Just continue processing -+ * 1 subflow is broken stop everything -+ * -1 this packet was broken - continue with the next one. -+ */ -+static int mptcp_prevalidate_skb(struct sock *sk, struct sk_buff *skb) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct mptcp_cb *mpcb = tp->mpcb; -+ -+ /* If we are in infinite mode, the subflow-fin is in fact a data-fin. */ -+ if (!skb->len && (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN) && -+ !mptcp_is_data_fin(skb) && !mpcb->infinite_mapping_rcv) { -+ /* Remove a pure subflow-fin from the queue and increase -+ * copied_seq. -+ */ -+ tp->copied_seq = TCP_SKB_CB(skb)->end_seq; -+ __skb_unlink(skb, &sk->sk_receive_queue); -+ __kfree_skb(skb); -+ return -1; -+ } -+ -+ /* If we are not yet fully established and do not know the mapping for -+ * this segment, this path has to fallback to infinite or be torn down. -+ */ -+ if (!tp->mptcp->fully_established && !mptcp_is_data_seq(skb) && -+ !tp->mptcp->mapping_present && !mpcb->infinite_mapping_rcv) { -+ pr_err("%s %#x will fallback - pi %d from %pS, seq %u\n", -+ __func__, mpcb->mptcp_loc_token, -+ tp->mptcp->path_index, __builtin_return_address(0), -+ TCP_SKB_CB(skb)->seq); -+ -+ if (!is_master_tp(tp)) { -+ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_FBDATASUB); -+ mptcp_send_reset(sk); -+ return 1; -+ } -+ -+ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_FBDATAINIT); -+ -+ mpcb->infinite_mapping_snd = 1; -+ mpcb->infinite_mapping_rcv = 1; -+ mpcb->infinite_rcv_seq = mptcp_get_rcv_nxt_64(mptcp_meta_tp(tp)); -+ -+ mptcp_sub_force_close_all(mpcb, sk); -+ -+ /* We do a seamless fallback and should not send a inf.mapping. */ -+ mpcb->send_infinite_mapping = 0; -+ tp->mptcp->fully_established = 1; -+ } -+ -+ /* Receiver-side becomes fully established when a whole rcv-window has -+ * been received without the need to fallback due to the previous -+ * condition. -+ */ -+ if (!tp->mptcp->fully_established) { -+ tp->mptcp->init_rcv_wnd -= skb->len; -+ if (tp->mptcp->init_rcv_wnd < 0) -+ mptcp_become_fully_estab(sk); -+ } -+ -+ return 0; -+} -+ -+static void mptcp_restart_sending(struct sock *meta_sk) -+{ -+ struct tcp_sock *meta_tp = tcp_sk(meta_sk); -+ struct mptcp_cb *mpcb = meta_tp->mpcb; -+ -+ /* We resend everything that has not been acknowledged */ -+ meta_sk->sk_send_head = tcp_write_queue_head(meta_sk); -+ -+ /* We artificially restart the whole send-queue. Thus, -+ * it is as if no packets are in flight -+ */ -+ meta_tp->packets_out = 0; -+ -+ /* If the snd_nxt already wrapped around, we have to -+ * undo the wrapping, as we are restarting from snd_una -+ * on. -+ */ -+ if (meta_tp->snd_nxt < meta_tp->snd_una) { -+ mpcb->snd_high_order[mpcb->snd_hiseq_index] -= 2; -+ mpcb->snd_hiseq_index = mpcb->snd_hiseq_index ? 0 : 1; -+ } -+ meta_tp->snd_nxt = meta_tp->snd_una; -+ -+ /* Trigger a sending on the meta. */ -+ mptcp_push_pending_frames(meta_sk); -+} -+ -+/* @return: 0 everything is fine. Just continue processing -+ * 1 subflow is broken stop everything -+ * -1 this packet was broken - continue with the next one. -+ */ -+static int mptcp_detect_mapping(struct sock *sk, struct sk_buff *skb) -+{ -+ struct tcp_sock *tp = tcp_sk(sk), *meta_tp = mptcp_meta_tp(tp); -+ struct mptcp_cb *mpcb = tp->mpcb; -+ struct tcp_skb_cb *tcb = TCP_SKB_CB(skb); -+ u32 *ptr; -+ u32 data_seq, sub_seq, data_len, tcp_end_seq; -+ bool set_infinite_rcv = false; -+ -+ /* If we are in infinite-mapping-mode, the subflow is guaranteed to be -+ * in-order at the data-level. Thus data-seq-numbers can be inferred -+ * from what is expected at the data-level. -+ */ -+ if (mpcb->infinite_mapping_rcv) { -+ /* copied_seq may be bigger than tcb->seq (e.g., when the peer -+ * retransmits data that actually has already been acknowledged with -+ * newer data, if he did not receive our acks). Thus, we need -+ * to account for this overlap as well. -+ */ -+ tp->mptcp->map_data_seq = mpcb->infinite_rcv_seq - (tp->copied_seq - tcb->seq); -+ tp->mptcp->map_subseq = tcb->seq; -+ tp->mptcp->map_data_len = skb->len; -+ tp->mptcp->map_data_fin = !!(TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN); -+ tp->mptcp->mapping_present = 1; -+ return 0; -+ } -+ -+ /* No mapping here? Exit - it is either already set or still on its way */ -+ if (!mptcp_is_data_seq(skb)) { -+ /* Too many packets without a mapping - this subflow is broken */ -+ if (!tp->mptcp->mapping_present && -+ tp->rcv_nxt - tp->copied_seq > 65536) { -+ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_NODSSWINDOW); -+ mptcp_send_reset(sk); -+ return 1; -+ } -+ -+ return 0; -+ } -+ -+ ptr = mptcp_skb_set_data_seq(skb, &data_seq, mpcb); -+ ptr++; -+ sub_seq = get_unaligned_be32(ptr) + tp->mptcp->rcv_isn; -+ ptr++; -+ data_len = get_unaligned_be16(ptr); -+ -+ /* If it's an empty skb with DATA_FIN, sub_seq must get fixed. -+ * The draft sets it to 0, but we really would like to have the -+ * real value, to have an easy handling afterwards here in this -+ * function. -+ */ -+ if (mptcp_is_data_fin(skb) && skb->len == 0) -+ sub_seq = TCP_SKB_CB(skb)->seq; -+ -+ /* If there is already a mapping - we check if it maps with the current -+ * one. If not - we reset. -+ */ -+ if (tp->mptcp->mapping_present && -+ (data_seq != (u32)tp->mptcp->map_data_seq || -+ sub_seq != tp->mptcp->map_subseq || -+ data_len != tp->mptcp->map_data_len + tp->mptcp->map_data_fin || -+ mptcp_is_data_fin(skb) != tp->mptcp->map_data_fin)) { -+ /* Mapping in packet is different from what we want */ -+ pr_err("%s Mappings do not match!\n", __func__); -+ pr_err("%s dseq %u mdseq %u, sseq %u msseq %u dlen %u mdlen %u dfin %d mdfin %d\n", -+ __func__, data_seq, (u32)tp->mptcp->map_data_seq, -+ sub_seq, tp->mptcp->map_subseq, data_len, -+ tp->mptcp->map_data_len, mptcp_is_data_fin(skb), -+ tp->mptcp->map_data_fin); -+ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_DSSNOMATCH); -+ mptcp_send_reset(sk); -+ return 1; -+ } -+ -+ /* If the previous check was good, the current mapping is valid and we exit. */ -+ if (tp->mptcp->mapping_present) -+ return 0; -+ -+ /* Mapping not yet set on this subflow - we set it here! */ -+ -+ if (!data_len) { -+ mpcb->infinite_mapping_rcv = 1; -+ mpcb->send_infinite_mapping = 1; -+ tp->mptcp->fully_established = 1; -+ /* We need to repeat mp_fail's until the sender felt -+ * back to infinite-mapping - here we stop repeating it. -+ */ -+ tp->mptcp->send_mp_fail = 0; -+ -+ /* We have to fixup data_len - it must be the same as skb->len */ -+ data_len = skb->len + (mptcp_is_data_fin(skb) ? 1 : 0); -+ sub_seq = tcb->seq; -+ -+ mptcp_restart_sending(tp->meta_sk); -+ -+ mptcp_sub_force_close_all(mpcb, sk); -+ -+ /* data_seq and so on are set correctly */ -+ -+ /* At this point, the meta-ofo-queue has to be emptied, -+ * as the following data is guaranteed to be in-order at -+ * the data and subflow-level -+ */ -+ skb_rbtree_purge(&meta_tp->out_of_order_queue); -+ -+ set_infinite_rcv = true; -+ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_INFINITEMAPRX); -+ } -+ -+ /* We are sending mp-fail's and thus are in fallback mode. -+ * Ignore packets which do not announce the fallback and still -+ * want to provide a mapping. -+ */ -+ if (tp->mptcp->send_mp_fail) { -+ tp->copied_seq = TCP_SKB_CB(skb)->end_seq; -+ __skb_unlink(skb, &sk->sk_receive_queue); -+ __kfree_skb(skb); -+ return -1; -+ } -+ -+ /* FIN increased the mapping-length by 1 */ -+ if (mptcp_is_data_fin(skb)) -+ data_len--; -+ -+ /* Subflow-sequences of packet must be -+ * (at least partially) be part of the DSS-mapping's -+ * subflow-sequence-space. -+ * -+ * Basically the mapping is not valid, if either of the -+ * following conditions is true: -+ * -+ * 1. It's not a data_fin and -+ * MPTCP-sub_seq >= TCP-end_seq -+ * -+ * 2. It's a data_fin and TCP-end_seq > TCP-seq and -+ * MPTCP-sub_seq >= TCP-end_seq -+ * -+ * The previous two can be merged into: -+ * TCP-end_seq > TCP-seq and MPTCP-sub_seq >= TCP-end_seq -+ * Because if it's not a data-fin, TCP-end_seq > TCP-seq -+ * -+ * 3. It's a data_fin and skb->len == 0 and -+ * MPTCP-sub_seq > TCP-end_seq -+ * -+ * 4. It's not a data_fin and TCP-end_seq > TCP-seq and -+ * MPTCP-sub_seq + MPTCP-data_len <= TCP-seq -+ */ -+ -+ /* subflow-fin is not part of the mapping - ignore it here ! */ -+ tcp_end_seq = tcb->end_seq; -+ if (tcb->tcp_flags & TCPHDR_FIN) -+ tcp_end_seq--; -+ if ((!before(sub_seq, tcb->end_seq) && after(tcp_end_seq, tcb->seq)) || -+ (mptcp_is_data_fin(skb) && skb->len == 0 && after(sub_seq, tcb->end_seq)) || -+ (!after(sub_seq + data_len, tcb->seq) && after(tcp_end_seq, tcb->seq))) { -+ /* Subflow-sequences of packet is different from what is in the -+ * packet's dss-mapping. The peer is misbehaving - reset -+ */ -+ pr_err("%s Packet's mapping does not map to the DSS sub_seq %u " -+ "end_seq %u, tcp_end_seq %u seq %u dfin %u len %u data_len %u" -+ "copied_seq %u\n", __func__, sub_seq, tcb->end_seq, tcp_end_seq, tcb->seq, mptcp_is_data_fin(skb), -+ skb->len, data_len, tp->copied_seq); -+ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_DSSTCPMISMATCH); -+ mptcp_send_reset(sk); -+ return 1; -+ } -+ -+ /* Does the DSS had 64-bit seqnum's ? */ -+ if (!(tcb->mptcp_flags & MPTCPHDR_SEQ64_SET)) { -+ /* Wrapped around? */ -+ if (unlikely(after(data_seq, meta_tp->rcv_nxt) && data_seq < meta_tp->rcv_nxt)) { -+ tp->mptcp->map_data_seq = mptcp_get_data_seq_64(mpcb, !mpcb->rcv_hiseq_index, data_seq); -+ } else { -+ /* Else, access the default high-order bits */ -+ tp->mptcp->map_data_seq = mptcp_get_data_seq_64(mpcb, mpcb->rcv_hiseq_index, data_seq); -+ } -+ } else { -+ tp->mptcp->map_data_seq = mptcp_get_data_seq_64(mpcb, (tcb->mptcp_flags & MPTCPHDR_SEQ64_INDEX) ? 1 : 0, data_seq); -+ -+ if (unlikely(tcb->mptcp_flags & MPTCPHDR_SEQ64_OFO)) { -+ /* We make sure that the data_seq is invalid. -+ * It will be dropped later. -+ */ -+ tp->mptcp->map_data_seq += 0xFFFFFFFF; -+ tp->mptcp->map_data_seq += 0xFFFFFFFF; -+ } -+ } -+ -+ if (set_infinite_rcv) -+ mpcb->infinite_rcv_seq = tp->mptcp->map_data_seq; -+ -+ tp->mptcp->map_data_len = data_len; -+ tp->mptcp->map_subseq = sub_seq; -+ tp->mptcp->map_data_fin = mptcp_is_data_fin(skb) ? 1 : 0; -+ tp->mptcp->mapping_present = 1; -+ -+ return 0; -+} -+ -+/* Similar to tcp_sequence(...) */ -+static inline bool mptcp_sequence(const struct tcp_sock *meta_tp, -+ u64 data_seq, u64 end_data_seq) -+{ -+ const struct mptcp_cb *mpcb = meta_tp->mpcb; -+ u64 rcv_wup64; -+ -+ /* Wrap-around? */ -+ if (meta_tp->rcv_wup > meta_tp->rcv_nxt) { -+ rcv_wup64 = ((u64)(mpcb->rcv_high_order[mpcb->rcv_hiseq_index] - 1) << 32) | -+ meta_tp->rcv_wup; -+ } else { -+ rcv_wup64 = mptcp_get_data_seq_64(mpcb, mpcb->rcv_hiseq_index, -+ meta_tp->rcv_wup); -+ } -+ -+ return !before64(end_data_seq, rcv_wup64) && -+ !after64(data_seq, mptcp_get_rcv_nxt_64(meta_tp) + tcp_receive_window(meta_tp)); -+} -+ -+/* @return: 0 everything is fine. Just continue processing -+ * -1 this packet was broken - continue with the next one. -+ */ -+static int mptcp_validate_mapping(struct sock *sk, struct sk_buff *skb) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct sk_buff *tmp, *tmp1; -+ u32 tcp_end_seq; -+ -+ if (!tp->mptcp->mapping_present) -+ return 0; -+ -+ /* either, the new skb gave us the mapping and the first segment -+ * in the sub-rcv-queue has to be trimmed ... -+ */ -+ tmp = skb_peek(&sk->sk_receive_queue); -+ if (before(TCP_SKB_CB(tmp)->seq, tp->mptcp->map_subseq) && -+ after(TCP_SKB_CB(tmp)->end_seq, tp->mptcp->map_subseq)) { -+ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_DSSTRIMHEAD); -+ mptcp_skb_trim_head(tmp, sk, tp->mptcp->map_subseq); -+ } -+ -+ /* ... or the new skb (tail) has to be split at the end. */ -+ tcp_end_seq = TCP_SKB_CB(skb)->end_seq; -+ if (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN) -+ tcp_end_seq--; -+ if (after(tcp_end_seq, tp->mptcp->map_subseq + tp->mptcp->map_data_len)) { -+ u32 seq = tp->mptcp->map_subseq + tp->mptcp->map_data_len; -+ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_DSSSPLITTAIL); -+ if (mptcp_skb_split_tail(skb, sk, seq)) { /* Allocation failed */ -+ /* TODO : maybe handle this here better. -+ * We now just force meta-retransmission. -+ */ -+ tp->copied_seq = TCP_SKB_CB(skb)->end_seq; -+ __skb_unlink(skb, &sk->sk_receive_queue); -+ __kfree_skb(skb); -+ return -1; -+ } -+ } -+ -+ /* Now, remove old sk_buff's from the receive-queue. -+ * This may happen if the mapping has been lost for these segments and -+ * the next mapping has already been received. -+ */ -+ if (before(TCP_SKB_CB(skb_peek(&sk->sk_receive_queue))->seq, tp->mptcp->map_subseq)) { -+ skb_queue_walk_safe(&sk->sk_receive_queue, tmp1, tmp) { -+ if (!before(TCP_SKB_CB(tmp1)->seq, tp->mptcp->map_subseq)) -+ break; -+ -+ tp->copied_seq = TCP_SKB_CB(tmp1)->end_seq; -+ __skb_unlink(tmp1, &sk->sk_receive_queue); -+ -+ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_PURGEOLD); -+ /* Impossible that we could free skb here, because his -+ * mapping is known to be valid from previous checks -+ */ -+ __kfree_skb(tmp1); -+ } -+ } -+ -+ return 0; -+} -+ -+/* @return: 0 everything is fine. Just continue processing -+ * 1 subflow is broken stop everything -+ * -1 this mapping has been put in the meta-receive-queue -+ * -2 this mapping has been eaten by the application -+ */ -+static int mptcp_queue_skb(struct sock *sk) -+{ -+ struct tcp_sock *tp = tcp_sk(sk), *meta_tp = mptcp_meta_tp(tp); -+ struct sock *meta_sk = mptcp_meta_sk(sk); -+ struct mptcp_cb *mpcb = tp->mpcb; -+ struct sk_buff *tmp, *tmp1; -+ u64 rcv_nxt64 = mptcp_get_rcv_nxt_64(meta_tp); -+ u32 old_copied_seq = tp->copied_seq; -+ bool data_queued = false; -+ -+ /* Have we not yet received the full mapping? */ -+ if (!tp->mptcp->mapping_present || -+ before(tp->rcv_nxt, tp->mptcp->map_subseq + tp->mptcp->map_data_len)) -+ return 0; -+ -+ /* Is this an overlapping mapping? rcv_nxt >= end_data_seq -+ * OR -+ * This mapping is out of window -+ */ -+ if (!before64(rcv_nxt64, tp->mptcp->map_data_seq + tp->mptcp->map_data_len + tp->mptcp->map_data_fin) || -+ !mptcp_sequence(meta_tp, tp->mptcp->map_data_seq, -+ tp->mptcp->map_data_seq + tp->mptcp->map_data_len + tp->mptcp->map_data_fin)) { -+ skb_queue_walk_safe(&sk->sk_receive_queue, tmp1, tmp) { -+ __skb_unlink(tmp1, &sk->sk_receive_queue); -+ tp->copied_seq = TCP_SKB_CB(tmp1)->end_seq; -+ __kfree_skb(tmp1); -+ -+ if (!skb_queue_empty(&sk->sk_receive_queue) && -+ !before(TCP_SKB_CB(tmp)->seq, -+ tp->mptcp->map_subseq + tp->mptcp->map_data_len)) -+ break; -+ } -+ -+ mptcp_reset_mapping(tp, old_copied_seq); -+ -+ return -1; -+ } -+ -+ /* Record it, because we want to send our data_fin on the same path */ -+ if (tp->mptcp->map_data_fin) { -+ mpcb->dfin_path_index = tp->mptcp->path_index; -+ mpcb->dfin_combined = !!(sk->sk_shutdown & RCV_SHUTDOWN); -+ } -+ -+ /* Verify the checksum */ -+ if (mpcb->dss_csum && !mpcb->infinite_mapping_rcv) { -+ int ret = mptcp_verif_dss_csum(sk); -+ -+ if (ret <= 0) { -+ mptcp_reset_mapping(tp, old_copied_seq); -+ return 1; -+ } -+ } -+ -+ if (before64(rcv_nxt64, tp->mptcp->map_data_seq)) { -+ /* Seg's have to go to the meta-ofo-queue */ -+ skb_queue_walk_safe(&sk->sk_receive_queue, tmp1, tmp) { -+ tp->copied_seq = TCP_SKB_CB(tmp1)->end_seq; -+ mptcp_prepare_skb(tmp1, sk); -+ __skb_unlink(tmp1, &sk->sk_receive_queue); -+ /* MUST be done here, because fragstolen may be true later. -+ * Then, kfree_skb_partial will not account the memory. -+ */ -+ skb_orphan(tmp1); -+ -+ if (!mpcb->in_time_wait) /* In time-wait, do not receive data */ -+ tcp_data_queue_ofo(meta_sk, tmp1); -+ else -+ __kfree_skb(tmp1); -+ -+ if (!skb_queue_empty(&sk->sk_receive_queue) && -+ !before(TCP_SKB_CB(tmp)->seq, -+ tp->mptcp->map_subseq + tp->mptcp->map_data_len)) -+ break; -+ } -+ -+ /* Quick ACK if more 3/4 of the receive window is filled */ -+ if (after64(tp->mptcp->map_data_seq, -+ rcv_nxt64 + 3 * (tcp_receive_window(meta_tp) >> 2))) -+ tcp_enter_quickack_mode(sk, TCP_MAX_QUICKACKS); -+ -+ } else { -+ /* Ready for the meta-rcv-queue */ -+ skb_queue_walk_safe(&sk->sk_receive_queue, tmp1, tmp) { -+ int eaten = 0; -+ bool fragstolen = false; -+ u32 old_rcv_nxt = meta_tp->rcv_nxt; -+ -+ tp->copied_seq = TCP_SKB_CB(tmp1)->end_seq; -+ mptcp_prepare_skb(tmp1, sk); -+ __skb_unlink(tmp1, &sk->sk_receive_queue); -+ /* MUST be done here, because fragstolen may be true. -+ * Then, kfree_skb_partial will not account the memory. -+ */ -+ skb_orphan(tmp1); -+ -+ /* This segment has already been received */ -+ if (!after(TCP_SKB_CB(tmp1)->end_seq, meta_tp->rcv_nxt)) { -+ __kfree_skb(tmp1); -+ goto next; -+ } -+ -+ if (mpcb->in_time_wait) /* In time-wait, do not receive data */ -+ eaten = 1; -+ -+ if (!eaten) -+ eaten = tcp_queue_rcv(meta_sk, tmp1, 0, &fragstolen); -+ -+ meta_tp->rcv_nxt = TCP_SKB_CB(tmp1)->end_seq; -+ -+ if (TCP_SKB_CB(tmp1)->tcp_flags & TCPHDR_FIN) -+ mptcp_fin(meta_sk); -+ -+ /* Check if this fills a gap in the ofo queue */ -+ if (!RB_EMPTY_ROOT(&meta_tp->out_of_order_queue)) -+ tcp_ofo_queue(meta_sk); -+ -+ mptcp_check_rcvseq_wrap(meta_tp, old_rcv_nxt); -+ -+ if (eaten) -+ kfree_skb_partial(tmp1, fragstolen); -+ -+ data_queued = true; -+next: -+ if (!skb_queue_empty(&sk->sk_receive_queue) && -+ !before(TCP_SKB_CB(tmp)->seq, -+ tp->mptcp->map_subseq + tp->mptcp->map_data_len)) -+ break; -+ } -+ } -+ -+ inet_csk(meta_sk)->icsk_ack.lrcvtime = tcp_jiffies32; -+ mptcp_reset_mapping(tp, old_copied_seq); -+ -+ return data_queued ? -1 : -2; -+} -+ -+void mptcp_data_ready(struct sock *sk) -+{ -+ struct sock *meta_sk = mptcp_meta_sk(sk); -+ struct sk_buff *skb, *tmp; -+ int queued = 0; -+ -+ tcp_mstamp_refresh(tcp_sk(meta_sk)); -+ -+ /* restart before the check, because mptcp_fin might have changed the -+ * state. -+ */ -+restart: -+ /* If the meta cannot receive data, there is no point in pushing data. -+ * If we are in time-wait, we may still be waiting for the final FIN. -+ * So, we should proceed with the processing. -+ */ -+ if (!mptcp_sk_can_recv(meta_sk) && !tcp_sk(sk)->mpcb->in_time_wait) { -+ skb_queue_purge(&sk->sk_receive_queue); -+ tcp_sk(sk)->copied_seq = tcp_sk(sk)->rcv_nxt; -+ goto exit; -+ } -+ -+ /* Iterate over all segments, detect their mapping (if we don't have -+ * one yet), validate them and push everything one level higher. -+ */ -+ skb_queue_walk_safe(&sk->sk_receive_queue, skb, tmp) { -+ int ret; -+ /* Pre-validation - e.g., early fallback */ -+ ret = mptcp_prevalidate_skb(sk, skb); -+ if (ret < 0) -+ goto restart; -+ else if (ret > 0) -+ break; -+ -+ /* Set the current mapping */ -+ ret = mptcp_detect_mapping(sk, skb); -+ if (ret < 0) -+ goto restart; -+ else if (ret > 0) -+ break; -+ -+ /* Validation */ -+ if (mptcp_validate_mapping(sk, skb) < 0) -+ goto restart; -+ -+ /* Push a level higher */ -+ ret = mptcp_queue_skb(sk); -+ if (ret < 0) { -+ if (ret == -1) -+ queued = ret; -+ goto restart; -+ } else if (ret == 0) { -+ continue; -+ } else { /* ret == 1 */ -+ break; -+ } -+ } -+ -+exit: -+ if (tcp_sk(sk)->close_it && sk->sk_state == TCP_FIN_WAIT2) { -+ tcp_send_ack(sk); -+ tcp_sk(sk)->ops->time_wait(sk, TCP_TIME_WAIT, 0); -+ } -+ -+ if (queued == -1 && !sock_flag(meta_sk, SOCK_DEAD)) -+ meta_sk->sk_data_ready(meta_sk); -+} -+ -+struct mp_join *mptcp_find_join(const struct sk_buff *skb) -+{ -+ const struct tcphdr *th = tcp_hdr(skb); -+ unsigned char *ptr; -+ int length = (th->doff * 4) - sizeof(struct tcphdr); -+ -+ /* Jump through the options to check whether JOIN is there */ -+ ptr = (unsigned char *)(th + 1); -+ while (length > 0) { -+ int opcode = *ptr++; -+ int opsize; -+ -+ switch (opcode) { -+ case TCPOPT_EOL: -+ return NULL; -+ case TCPOPT_NOP: /* Ref: RFC 793 section 3.1 */ -+ length--; -+ continue; -+ default: -+ opsize = *ptr++; -+ if (opsize < 2) /* "silly options" */ -+ return NULL; -+ if (opsize > length) -+ return NULL; /* don't parse partial options */ -+ if (opcode == TCPOPT_MPTCP && -+ ((struct mptcp_option *)(ptr - 2))->sub == MPTCP_SUB_JOIN) { -+ return (struct mp_join *)(ptr - 2); -+ } -+ ptr += opsize - 2; -+ length -= opsize; -+ } -+ } -+ return NULL; -+} -+ -+int mptcp_lookup_join(struct sk_buff *skb, struct inet_timewait_sock *tw) -+{ -+ const struct mptcp_cb *mpcb; -+ struct sock *meta_sk; -+ u32 token; -+ bool meta_v4; -+ struct mp_join *join_opt = mptcp_find_join(skb); -+ if (!join_opt) -+ return 0; -+ -+ /* MPTCP structures were not initialized, so return error */ -+ if (mptcp_init_failed) -+ return -1; -+ -+ token = join_opt->u.syn.token; -+ meta_sk = mptcp_hash_find(dev_net(skb_dst(skb)->dev), token); -+ if (!meta_sk) { -+ MPTCP_INC_STATS(dev_net(skb_dst(skb)->dev), MPTCP_MIB_JOINNOTOKEN); -+ mptcp_debug("%s:mpcb not found:%x\n", __func__, token); -+ return -1; -+ } -+ -+ meta_v4 = meta_sk->sk_family == AF_INET; -+ if (meta_v4) { -+ if (skb->protocol == htons(ETH_P_IPV6)) { -+ mptcp_debug("SYN+MP_JOIN with IPV6 address on pure IPV4 meta\n"); -+ sock_put(meta_sk); /* Taken by mptcp_hash_find */ -+ return -1; -+ } -+ } else if (skb->protocol == htons(ETH_P_IP) && meta_sk->sk_ipv6only) { -+ mptcp_debug("SYN+MP_JOIN with IPV4 address on IPV6_V6ONLY meta\n"); -+ sock_put(meta_sk); /* Taken by mptcp_hash_find */ -+ return -1; -+ } -+ -+ mpcb = tcp_sk(meta_sk)->mpcb; -+ if (mpcb->infinite_mapping_rcv || mpcb->send_infinite_mapping) { -+ /* We are in fallback-mode on the reception-side - -+ * no new subflows! -+ */ -+ sock_put(meta_sk); /* Taken by mptcp_hash_find */ -+ MPTCP_INC_STATS(sock_net(meta_sk), MPTCP_MIB_JOINFALLBACK); -+ return -1; -+ } -+ -+ /* Coming from time-wait-sock processing in tcp_v4_rcv. -+ * We have to deschedule it before continuing, because otherwise -+ * mptcp_v4_do_rcv will hit again on it inside tcp_v4_hnd_req. -+ */ -+ if (tw) -+ inet_twsk_deschedule_put(tw); -+ -+ /* OK, this is a new syn/join, let's create a new open request and -+ * send syn+ack -+ */ -+ bh_lock_sock_nested(meta_sk); -+ if (sock_owned_by_user(meta_sk)) { -+ if (unlikely(sk_add_backlog(meta_sk, skb, -+ meta_sk->sk_rcvbuf + meta_sk->sk_sndbuf))) { -+ bh_unlock_sock(meta_sk); -+ __NET_INC_STATS(sock_net(meta_sk), -+ LINUX_MIB_TCPBACKLOGDROP); -+ sock_put(meta_sk); /* Taken by mptcp_hash_find */ -+ kfree_skb(skb); -+ return 1; -+ } -+ } else if (skb->protocol == htons(ETH_P_IP)) { -+ tcp_v4_do_rcv(meta_sk, skb); -+#if IS_ENABLED(CONFIG_IPV6) -+ } else { -+ tcp_v6_do_rcv(meta_sk, skb); -+#endif /* CONFIG_IPV6 */ -+ } -+ bh_unlock_sock(meta_sk); -+ sock_put(meta_sk); /* Taken by mptcp_hash_find */ -+ return 1; -+} -+ -+int mptcp_do_join_short(struct sk_buff *skb, -+ const struct mptcp_options_received *mopt, -+ struct net *net) -+{ -+ struct sock *meta_sk; -+ u32 token; -+ bool meta_v4; -+ -+ token = mopt->mptcp_rem_token; -+ meta_sk = mptcp_hash_find(net, token); -+ if (!meta_sk) { -+ MPTCP_INC_STATS(dev_net(skb_dst(skb)->dev), MPTCP_MIB_JOINNOTOKEN); -+ mptcp_debug("%s:mpcb not found:%x\n", __func__, token); -+ return -1; -+ } -+ -+ meta_v4 = meta_sk->sk_family == AF_INET; -+ if (meta_v4) { -+ if (skb->protocol == htons(ETH_P_IPV6)) { -+ mptcp_debug("SYN+MP_JOIN with IPV6 address on pure IPV4 meta\n"); -+ sock_put(meta_sk); /* Taken by mptcp_hash_find */ -+ return -1; -+ } -+ } else if (skb->protocol == htons(ETH_P_IP) && meta_sk->sk_ipv6only) { -+ mptcp_debug("SYN+MP_JOIN with IPV4 address on IPV6_V6ONLY meta\n"); -+ sock_put(meta_sk); /* Taken by mptcp_hash_find */ -+ return -1; -+ } -+ -+ /* OK, this is a new syn/join, let's create a new open request and -+ * send syn+ack -+ */ -+ bh_lock_sock(meta_sk); -+ -+ /* This check is also done in mptcp_vX_do_rcv. But, there we cannot -+ * call tcp_vX_send_reset, because we hold already two socket-locks. -+ * (the listener and the meta from above) -+ * -+ * And the send-reset will try to take yet another one (ip_send_reply). -+ * Thus, we propagate the reset up to tcp_rcv_state_process. -+ */ -+ if (tcp_sk(meta_sk)->mpcb->infinite_mapping_rcv || -+ tcp_sk(meta_sk)->mpcb->send_infinite_mapping || -+ meta_sk->sk_state == TCP_CLOSE || !tcp_sk(meta_sk)->inside_tk_table) { -+ MPTCP_INC_STATS(sock_net(meta_sk), MPTCP_MIB_JOINFALLBACK); -+ bh_unlock_sock(meta_sk); -+ sock_put(meta_sk); /* Taken by mptcp_hash_find */ -+ return -1; -+ } -+ -+ if (sock_owned_by_user(meta_sk)) { -+ if (unlikely(sk_add_backlog(meta_sk, skb, -+ meta_sk->sk_rcvbuf + meta_sk->sk_sndbuf))) -+ __NET_INC_STATS(net, LINUX_MIB_TCPBACKLOGDROP); -+ else -+ /* Must make sure that upper layers won't free the -+ * skb if it is added to the backlog-queue. -+ */ -+ skb_get(skb); -+ } else { -+ /* mptcp_v4_do_rcv tries to free the skb - we prevent this, as -+ * the skb will finally be freed by tcp_v4_do_rcv (where we are -+ * coming from) -+ */ -+ skb_get(skb); -+ if (skb->protocol == htons(ETH_P_IP)) { -+ tcp_v4_do_rcv(meta_sk, skb); -+#if IS_ENABLED(CONFIG_IPV6) -+ } else { /* IPv6 */ -+ tcp_v6_do_rcv(meta_sk, skb); -+#endif /* CONFIG_IPV6 */ -+ } -+ } -+ -+ bh_unlock_sock(meta_sk); -+ sock_put(meta_sk); /* Taken by mptcp_hash_find */ -+ return 0; -+} -+ -+/** -+ * Equivalent of tcp_fin() for MPTCP -+ * Can be called only when the FIN is validly part -+ * of the data seqnum space. Not before when we get holes. -+ */ -+void mptcp_fin(struct sock *meta_sk) -+{ -+ struct sock *sk = NULL, *sk_it; -+ struct tcp_sock *meta_tp = tcp_sk(meta_sk); -+ struct mptcp_cb *mpcb = meta_tp->mpcb; -+ unsigned char state; -+ -+ mptcp_for_each_sk(mpcb, sk_it) { -+ if (tcp_sk(sk_it)->mptcp->path_index == mpcb->dfin_path_index) { -+ sk = sk_it; -+ break; -+ } -+ } -+ -+ if (!sk || sk->sk_state == TCP_CLOSE) -+ sk = mptcp_select_ack_sock(meta_sk); -+ -+ inet_csk_schedule_ack(sk); -+ -+ if (!mpcb->in_time_wait) { -+ meta_sk->sk_shutdown |= RCV_SHUTDOWN; -+ sock_set_flag(meta_sk, SOCK_DONE); -+ state = meta_sk->sk_state; -+ } else { -+ state = mpcb->mptw_state; -+ } -+ -+ switch (state) { -+ case TCP_SYN_RECV: -+ case TCP_ESTABLISHED: -+ /* Move to CLOSE_WAIT */ -+ tcp_set_state(meta_sk, TCP_CLOSE_WAIT); -+ inet_csk(sk)->icsk_ack.pingpong = 1; -+ break; -+ -+ case TCP_CLOSE_WAIT: -+ case TCP_CLOSING: -+ /* Received a retransmission of the FIN, do -+ * nothing. -+ */ -+ break; -+ case TCP_LAST_ACK: -+ /* RFC793: Remain in the LAST-ACK state. */ -+ break; -+ -+ case TCP_FIN_WAIT1: -+ /* This case occurs when a simultaneous close -+ * happens, we must ack the received FIN and -+ * enter the CLOSING state. -+ */ -+ tcp_send_ack(sk); -+ tcp_set_state(meta_sk, TCP_CLOSING); -+ break; -+ case TCP_FIN_WAIT2: -+ /* Received a FIN -- send ACK and enter TIME_WAIT. */ -+ tcp_send_ack(sk); -+ meta_tp->ops->time_wait(meta_sk, TCP_TIME_WAIT, 0); -+ break; -+ default: -+ /* Only TCP_LISTEN and TCP_CLOSE are left, in these -+ * cases we should never reach this piece of code. -+ */ -+ pr_err("%s: Impossible, meta_sk->sk_state=%d\n", __func__, -+ meta_sk->sk_state); -+ break; -+ } -+ -+ /* It _is_ possible, that we have something out-of-order _after_ FIN. -+ * Probably, we should reset in this case. For now drop them. -+ */ -+ skb_rbtree_purge(&meta_tp->out_of_order_queue); -+ sk_mem_reclaim(meta_sk); -+ -+ if (!sock_flag(meta_sk, SOCK_DEAD)) { -+ meta_sk->sk_state_change(meta_sk); -+ -+ /* Do not send POLL_HUP for half duplex close. */ -+ if (meta_sk->sk_shutdown == SHUTDOWN_MASK || -+ meta_sk->sk_state == TCP_CLOSE) -+ sk_wake_async(meta_sk, SOCK_WAKE_WAITD, POLL_HUP); -+ else -+ sk_wake_async(meta_sk, SOCK_WAKE_WAITD, POLL_IN); -+ } -+ -+ return; -+} -+ -+static void mptcp_xmit_retransmit_queue(struct sock *meta_sk) -+{ -+ struct tcp_sock *meta_tp = tcp_sk(meta_sk); -+ struct sk_buff *skb; -+ -+ if (!meta_tp->packets_out) -+ return; -+ -+ tcp_for_write_queue(skb, meta_sk) { -+ if (skb == tcp_send_head(meta_sk)) -+ break; -+ -+ if (mptcp_retransmit_skb(meta_sk, skb)) -+ return; -+ -+ if (skb == tcp_write_queue_head(meta_sk)) -+ inet_csk_reset_xmit_timer(meta_sk, ICSK_TIME_RETRANS, -+ inet_csk(meta_sk)->icsk_rto, -+ TCP_RTO_MAX); -+ } -+} -+ -+static void mptcp_snd_una_update(struct tcp_sock *meta_tp, u32 data_ack) -+{ -+ u32 delta = data_ack - meta_tp->snd_una; -+ -+ sock_owned_by_me((struct sock *)meta_tp); -+ meta_tp->bytes_acked += delta; -+ meta_tp->snd_una = data_ack; -+} -+ -+/* Handle the DATA_ACK */ -+static void mptcp_data_ack(struct sock *sk, const struct sk_buff *skb) -+{ -+ struct sock *meta_sk = mptcp_meta_sk(sk); -+ struct tcp_sock *meta_tp = tcp_sk(meta_sk), *tp = tcp_sk(sk); -+ struct tcp_skb_cb *tcb = TCP_SKB_CB(skb); -+ u32 prior_snd_una = meta_tp->snd_una; -+ int prior_packets; -+ u32 nwin, data_ack, data_seq; -+ u16 data_len = 0; -+ -+ /* A valid packet came in - subflow is operational again */ -+ tp->pf = 0; -+ -+ /* Even if there is no data-ack, we stop retransmitting. -+ * Except if this is a SYN/ACK. Then it is just a retransmission -+ */ -+ if (tp->mptcp->pre_established && !tcp_hdr(skb)->syn) { -+ tp->mptcp->pre_established = 0; -+ sk_stop_timer(sk, &tp->mptcp->mptcp_ack_timer); -+ } -+ -+ /* If we are in infinite mapping mode, rx_opt.data_ack has been -+ * set by mptcp_clean_rtx_infinite. -+ */ -+ if (!(tcb->mptcp_flags & MPTCPHDR_ACK) && !tp->mpcb->infinite_mapping_snd) -+ return; -+ -+ if (unlikely(!tp->mptcp->fully_established) && -+ tp->mptcp->snt_isn + 1 != TCP_SKB_CB(skb)->ack_seq) -+ /* As soon as a subflow-data-ack (not acking syn, thus snt_isn + 1) -+ * includes a data-ack, we are fully established -+ */ -+ mptcp_become_fully_estab(sk); -+ -+ /* After we did the subflow-only processing (stopping timer and marking -+ * subflow as established), check if we can proceed with MPTCP-level -+ * processing. -+ */ -+ if (meta_sk->sk_state == TCP_CLOSE) -+ return; -+ -+ /* Get the data_seq */ -+ if (mptcp_is_data_seq(skb)) { -+ data_seq = tp->mptcp->rx_opt.data_seq; -+ data_len = tp->mptcp->rx_opt.data_len; -+ } else { -+ data_seq = meta_tp->snd_wl1; -+ } -+ -+ data_ack = tp->mptcp->rx_opt.data_ack; -+ -+ /* If the ack is older than previous acks -+ * then we can probably ignore it. -+ */ -+ if (before(data_ack, prior_snd_una)) -+ goto exit; -+ -+ /* If the ack includes data we haven't sent yet, discard -+ * this segment (RFC793 Section 3.9). -+ */ -+ if (after(data_ack, meta_tp->snd_nxt)) -+ goto exit; -+ -+ /*** Now, update the window - inspired by tcp_ack_update_window ***/ -+ nwin = ntohs(tcp_hdr(skb)->window); -+ -+ if (likely(!tcp_hdr(skb)->syn)) -+ nwin <<= tp->rx_opt.snd_wscale; -+ -+ if (tcp_may_update_window(meta_tp, data_ack, data_seq, nwin)) { -+ tcp_update_wl(meta_tp, data_seq); -+ -+ /* Draft v09, Section 3.3.5: -+ * [...] It should only update its local receive window values -+ * when the largest sequence number allowed (i.e. DATA_ACK + -+ * receive window) increases. [...] -+ */ -+ if (meta_tp->snd_wnd != nwin && -+ !before(data_ack + nwin, tcp_wnd_end(meta_tp))) { -+ meta_tp->snd_wnd = nwin; -+ -+ if (nwin > meta_tp->max_window) -+ meta_tp->max_window = nwin; -+ } -+ } -+ /*** Done, update the window ***/ -+ -+ /* We passed data and got it acked, remove any soft error -+ * log. Something worked... -+ */ -+ sk->sk_err_soft = 0; -+ inet_csk(meta_sk)->icsk_probes_out = 0; -+ meta_tp->rcv_tstamp = tcp_jiffies32; -+ prior_packets = meta_tp->packets_out; -+ if (!prior_packets) -+ goto no_queue; -+ -+ mptcp_snd_una_update(meta_tp, data_ack); -+ -+ mptcp_clean_rtx_queue(meta_sk, prior_snd_una); -+ -+ /* We are in loss-state, and something got acked, retransmit the whole -+ * queue now! -+ */ -+ if (inet_csk(meta_sk)->icsk_ca_state == TCP_CA_Loss && -+ after(data_ack, prior_snd_una)) { -+ mptcp_xmit_retransmit_queue(meta_sk); -+ inet_csk(meta_sk)->icsk_ca_state = TCP_CA_Open; -+ } -+ -+ /* Simplified version of tcp_new_space, because the snd-buffer -+ * is handled by all the subflows. -+ */ -+ if (sock_flag(meta_sk, SOCK_QUEUE_SHRUNK)) { -+ sock_reset_flag(meta_sk, SOCK_QUEUE_SHRUNK); -+ if (meta_sk->sk_socket && -+ test_bit(SOCK_NOSPACE, &meta_sk->sk_socket->flags)) -+ meta_sk->sk_write_space(meta_sk); -+ } -+ -+ if (meta_sk->sk_state != TCP_ESTABLISHED && -+ mptcp_rcv_state_process(meta_sk, sk, skb, data_seq, data_len)) -+ return; -+ -+exit: -+ mptcp_push_pending_frames(meta_sk); -+ -+ return; -+ -+no_queue: -+ if (tcp_send_head(meta_sk)) -+ tcp_ack_probe(meta_sk); -+ -+ mptcp_push_pending_frames(meta_sk); -+ -+ return; -+} -+ -+void mptcp_clean_rtx_infinite(const struct sk_buff *skb, struct sock *sk) -+{ -+ struct tcp_sock *tp = tcp_sk(sk), *meta_tp = tcp_sk(mptcp_meta_sk(sk)); -+ -+ if (!tp->mpcb->infinite_mapping_snd) -+ return; -+ -+ /* The difference between both write_seq's represents the offset between -+ * data-sequence and subflow-sequence. As we are infinite, this must -+ * match. -+ * -+ * Thus, from this difference we can infer the meta snd_una. -+ */ -+ tp->mptcp->rx_opt.data_ack = meta_tp->snd_nxt - tp->snd_nxt + -+ tp->snd_una; -+ -+ mptcp_data_ack(sk, skb); -+} -+ -+/**** static functions used by mptcp_parse_options */ -+ -+static void mptcp_send_reset_rem_id(const struct mptcp_cb *mpcb, u8 rem_id) -+{ -+ struct sock *sk_it, *tmpsk; -+ -+ mptcp_for_each_sk_safe(mpcb, sk_it, tmpsk) { -+ if (tcp_sk(sk_it)->mptcp->rem_id == rem_id) { -+ mptcp_reinject_data(sk_it, 0); -+ mptcp_send_reset(sk_it); -+ } -+ } -+} -+ -+static inline bool is_valid_addropt_opsize(u8 mptcp_ver, -+ struct mp_add_addr *mpadd, -+ int opsize) -+{ -+#if IS_ENABLED(CONFIG_IPV6) -+ if (mptcp_ver < MPTCP_VERSION_1 && mpadd->ipver == 6) { -+ return opsize == MPTCP_SUB_LEN_ADD_ADDR6 || -+ opsize == MPTCP_SUB_LEN_ADD_ADDR6 + 2; -+ } -+ if (mptcp_ver >= MPTCP_VERSION_1 && mpadd->ipver == 6) -+ return opsize == MPTCP_SUB_LEN_ADD_ADDR6_VER1 || -+ opsize == MPTCP_SUB_LEN_ADD_ADDR6_VER1 + 2; -+#endif -+ if (mptcp_ver < MPTCP_VERSION_1 && mpadd->ipver == 4) { -+ return opsize == MPTCP_SUB_LEN_ADD_ADDR4 || -+ opsize == MPTCP_SUB_LEN_ADD_ADDR4 + 2; -+ } -+ if (mptcp_ver >= MPTCP_VERSION_1 && mpadd->ipver == 4) { -+ return opsize == MPTCP_SUB_LEN_ADD_ADDR4_VER1 || -+ opsize == MPTCP_SUB_LEN_ADD_ADDR4_VER1 + 2; -+ } -+ return false; -+} -+ -+void mptcp_parse_options(const uint8_t *ptr, int opsize, -+ struct mptcp_options_received *mopt, -+ const struct sk_buff *skb, -+ struct tcp_sock *tp) -+{ -+ const struct mptcp_option *mp_opt = (struct mptcp_option *)ptr; -+ -+ /* If the socket is mp-capable we would have a mopt. */ -+ if (!mopt) -+ return; -+ -+ switch (mp_opt->sub) { -+ case MPTCP_SUB_CAPABLE: -+ { -+ const struct mp_capable *mpcapable = (struct mp_capable *)ptr; -+ -+ if (opsize != MPTCP_SUB_LEN_CAPABLE_SYN && -+ opsize != MPTCP_SUB_LEN_CAPABLE_ACK) { -+ mptcp_debug("%s: mp_capable: bad option size %d\n", -+ __func__, opsize); -+ break; -+ } -+ -+ /* MPTCP-RFC 6824: -+ * "If receiving a message with the 'B' flag set to 1, and this -+ * is not understood, then this SYN MUST be silently ignored; -+ */ -+ if (mpcapable->b) { -+ mopt->drop_me = 1; -+ break; -+ } -+ -+ /* MPTCP-RFC 6824: -+ * "An implementation that only supports this method MUST set -+ * bit "H" to 1, and bits "C" through "G" to 0." -+ */ -+ if (!mpcapable->h) -+ break; -+ -+ mopt->saw_mpc = 1; -+ mopt->dss_csum = sysctl_mptcp_checksum || mpcapable->a; -+ -+ if (opsize >= MPTCP_SUB_LEN_CAPABLE_SYN) -+ mopt->mptcp_sender_key = mpcapable->sender_key; -+ if (opsize == MPTCP_SUB_LEN_CAPABLE_ACK) -+ mopt->mptcp_receiver_key = mpcapable->receiver_key; -+ -+ mopt->mptcp_ver = mpcapable->ver; -+ break; -+ } -+ case MPTCP_SUB_JOIN: -+ { -+ const struct mp_join *mpjoin = (struct mp_join *)ptr; -+ -+ if (opsize != MPTCP_SUB_LEN_JOIN_SYN && -+ opsize != MPTCP_SUB_LEN_JOIN_SYNACK && -+ opsize != MPTCP_SUB_LEN_JOIN_ACK) { -+ mptcp_debug("%s: mp_join: bad option size %d\n", -+ __func__, opsize); -+ break; -+ } -+ -+ /* saw_mpc must be set, because in tcp_check_req we assume that -+ * it is set to support falling back to reg. TCP if a rexmitted -+ * SYN has no MP_CAPABLE or MP_JOIN -+ */ -+ switch (opsize) { -+ case MPTCP_SUB_LEN_JOIN_SYN: -+ mopt->is_mp_join = 1; -+ mopt->saw_mpc = 1; -+ mopt->low_prio = mpjoin->b; -+ mopt->rem_id = mpjoin->addr_id; -+ mopt->mptcp_rem_token = mpjoin->u.syn.token; -+ mopt->mptcp_recv_nonce = mpjoin->u.syn.nonce; -+ break; -+ case MPTCP_SUB_LEN_JOIN_SYNACK: -+ mopt->saw_mpc = 1; -+ mopt->low_prio = mpjoin->b; -+ mopt->rem_id = mpjoin->addr_id; -+ mopt->mptcp_recv_tmac = mpjoin->u.synack.mac; -+ mopt->mptcp_recv_nonce = mpjoin->u.synack.nonce; -+ break; -+ case MPTCP_SUB_LEN_JOIN_ACK: -+ mopt->saw_mpc = 1; -+ mopt->join_ack = 1; -+ memcpy(mopt->mptcp_recv_mac, mpjoin->u.ack.mac, 20); -+ break; -+ } -+ break; -+ } -+ case MPTCP_SUB_DSS: -+ { -+ const struct mp_dss *mdss = (struct mp_dss *)ptr; -+ struct tcp_skb_cb *tcb = TCP_SKB_CB(skb); -+ -+ /* We check opsize for the csum and non-csum case. We do this, -+ * because the draft says that the csum SHOULD be ignored if -+ * it has not been negotiated in the MP_CAPABLE but still is -+ * present in the data. -+ * -+ * It will get ignored later in mptcp_queue_skb. -+ */ -+ if (opsize != mptcp_sub_len_dss(mdss, 0) && -+ opsize != mptcp_sub_len_dss(mdss, 1)) { -+ mptcp_debug("%s: mp_dss: bad option size %d\n", -+ __func__, opsize); -+ break; -+ } -+ -+ ptr += 4; -+ -+ if (mdss->A) { -+ tcb->mptcp_flags |= MPTCPHDR_ACK; -+ -+ if (mdss->a) { -+ mopt->data_ack = (u32) get_unaligned_be64(ptr); -+ ptr += MPTCP_SUB_LEN_ACK_64; -+ } else { -+ mopt->data_ack = get_unaligned_be32(ptr); -+ ptr += MPTCP_SUB_LEN_ACK; -+ } -+ } -+ -+ tcb->dss_off = (ptr - skb_transport_header(skb)); -+ -+ if (mdss->M) { -+ if (mdss->m) { -+ u64 data_seq64 = get_unaligned_be64(ptr); -+ -+ tcb->mptcp_flags |= MPTCPHDR_SEQ64_SET; -+ mopt->data_seq = (u32) data_seq64; -+ -+ ptr += 12; /* 64-bit dseq + subseq */ -+ } else { -+ mopt->data_seq = get_unaligned_be32(ptr); -+ ptr += 8; /* 32-bit dseq + subseq */ -+ } -+ mopt->data_len = get_unaligned_be16(ptr); -+ -+ tcb->mptcp_flags |= MPTCPHDR_SEQ; -+ -+ /* Is a check-sum present? */ -+ if (opsize == mptcp_sub_len_dss(mdss, 1)) -+ tcb->mptcp_flags |= MPTCPHDR_DSS_CSUM; -+ -+ /* DATA_FIN only possible with DSS-mapping */ -+ if (mdss->F) -+ tcb->mptcp_flags |= MPTCPHDR_FIN; -+ } -+ -+ break; -+ } -+ case MPTCP_SUB_ADD_ADDR: -+ { -+ struct mp_add_addr *mpadd = (struct mp_add_addr *)ptr; -+ -+ /* If tcp_sock is not available, MPTCP version can't be -+ * retrieved and ADD_ADDR opsize validation is not possible. -+ */ -+ if (!tp || !tp->mpcb) -+ break; -+ -+ if (!is_valid_addropt_opsize(tp->mpcb->mptcp_ver, -+ mpadd, opsize)) { -+ mptcp_debug("%s: mp_add_addr: bad option size %d\n", -+ __func__, opsize); -+ break; -+ } -+ -+ /* We have to manually parse the options if we got two of them. */ -+ if (mopt->saw_add_addr) { -+ mopt->more_add_addr = 1; -+ break; -+ } -+ mopt->saw_add_addr = 1; -+ mopt->add_addr_ptr = ptr; -+ break; -+ } -+ case MPTCP_SUB_REMOVE_ADDR: -+ if ((opsize - MPTCP_SUB_LEN_REMOVE_ADDR) < 0) { -+ mptcp_debug("%s: mp_remove_addr: bad option size %d\n", -+ __func__, opsize); -+ break; -+ } -+ -+ if (mopt->saw_rem_addr) { -+ mopt->more_rem_addr = 1; -+ break; -+ } -+ mopt->saw_rem_addr = 1; -+ mopt->rem_addr_ptr = ptr; -+ break; -+ case MPTCP_SUB_PRIO: -+ { -+ const struct mp_prio *mpprio = (struct mp_prio *)ptr; -+ -+ if (opsize != MPTCP_SUB_LEN_PRIO && -+ opsize != MPTCP_SUB_LEN_PRIO_ADDR) { -+ mptcp_debug("%s: mp_prio: bad option size %d\n", -+ __func__, opsize); -+ break; -+ } -+ -+ mopt->saw_low_prio = 1; -+ mopt->low_prio = mpprio->b; -+ -+ if (opsize == MPTCP_SUB_LEN_PRIO_ADDR) { -+ mopt->saw_low_prio = 2; -+ mopt->prio_addr_id = mpprio->addr_id; -+ } -+ break; -+ } -+ case MPTCP_SUB_FAIL: -+ if (opsize != MPTCP_SUB_LEN_FAIL) { -+ mptcp_debug("%s: mp_fail: bad option size %d\n", -+ __func__, opsize); -+ break; -+ } -+ mopt->mp_fail = 1; -+ break; -+ case MPTCP_SUB_FCLOSE: -+ if (opsize != MPTCP_SUB_LEN_FCLOSE) { -+ mptcp_debug("%s: mp_fclose: bad option size %d\n", -+ __func__, opsize); -+ break; -+ } -+ -+ mopt->mp_fclose = 1; -+ mopt->mptcp_sender_key = ((struct mp_fclose *)ptr)->key; -+ -+ break; -+ default: -+ mptcp_debug("%s: Received unkown subtype: %d\n", -+ __func__, mp_opt->sub); -+ break; -+ } -+} -+ -+/** Parse only MPTCP options */ -+void tcp_parse_mptcp_options(const struct sk_buff *skb, -+ struct mptcp_options_received *mopt) -+{ -+ const struct tcphdr *th = tcp_hdr(skb); -+ int length = (th->doff * 4) - sizeof(struct tcphdr); -+ const unsigned char *ptr = (const unsigned char *)(th + 1); -+ -+ while (length > 0) { -+ int opcode = *ptr++; -+ int opsize; -+ -+ switch (opcode) { -+ case TCPOPT_EOL: -+ return; -+ case TCPOPT_NOP: /* Ref: RFC 793 section 3.1 */ -+ length--; -+ continue; -+ default: -+ opsize = *ptr++; -+ if (opsize < 2) /* "silly options" */ -+ return; -+ if (opsize > length) -+ return; /* don't parse partial options */ -+ if (opcode == TCPOPT_MPTCP) -+ mptcp_parse_options(ptr - 2, opsize, mopt, skb, NULL); -+ } -+ ptr += opsize - 2; -+ length -= opsize; -+ } -+} -+ -+bool mptcp_check_rtt(const struct tcp_sock *tp, int time) -+{ -+ struct mptcp_cb *mpcb = tp->mpcb; -+ struct sock *sk; -+ u32 rtt_max = 0; -+ -+ /* In MPTCP, we take the max delay across all flows, -+ * in order to take into account meta-reordering buffers. -+ */ -+ mptcp_for_each_sk(mpcb, sk) { -+ if (!mptcp_sk_can_recv(sk)) -+ continue; -+ -+ if (rtt_max < tcp_sk(sk)->rcv_rtt_est.rtt_us) -+ rtt_max = tcp_sk(sk)->rcv_rtt_est.rtt_us; -+ } -+ if (time < (rtt_max >> 3) || !rtt_max) -+ return true; -+ -+ return false; -+} -+ -+static void mptcp_handle_add_addr(const unsigned char *ptr, struct sock *sk) -+{ -+ struct mp_add_addr *mpadd = (struct mp_add_addr *)ptr; -+ struct mptcp_cb *mpcb = tcp_sk(sk)->mpcb; -+ __be16 port = 0; -+ union inet_addr addr; -+ sa_family_t family; -+ -+ if (mpadd->ipver == 4) { -+ char *recv_hmac; -+ u8 hash_mac_check[20]; -+ u8 no_key[8]; -+ int msg_parts = 0; -+ -+ if (mpcb->mptcp_ver < MPTCP_VERSION_1) -+ goto skip_hmac_v4; -+ -+ *(u64 *)no_key = 0; -+ recv_hmac = (char *)mpadd->u.v4.mac; -+ if (mpadd->len == MPTCP_SUB_LEN_ADD_ADDR4_VER1) { -+ recv_hmac -= sizeof(mpadd->u.v4.port); -+ msg_parts = 2; -+ } else if (mpadd->len == MPTCP_SUB_LEN_ADD_ADDR4_VER1 + 2) { -+ msg_parts = 3; -+ } -+ mptcp_hmac_sha1((u8 *)&mpcb->mptcp_rem_key, -+ (u8 *)no_key, -+ (u32 *)hash_mac_check, msg_parts, -+ 1, (u8 *)&mpadd->addr_id, -+ 4, (u8 *)&mpadd->u.v4.addr.s_addr, -+ 2, (u8 *)&mpadd->u.v4.port); -+ if (memcmp(hash_mac_check, recv_hmac, 8) != 0) -+ /* ADD_ADDR2 discarded */ -+ return; -+skip_hmac_v4: -+ if ((mpcb->mptcp_ver == MPTCP_VERSION_0 && -+ mpadd->len == MPTCP_SUB_LEN_ADD_ADDR4 + 2) || -+ (mpcb->mptcp_ver == MPTCP_VERSION_1 && -+ mpadd->len == MPTCP_SUB_LEN_ADD_ADDR4_VER1 + 2)) -+ port = mpadd->u.v4.port; -+ family = AF_INET; -+ addr.in = mpadd->u.v4.addr; -+#if IS_ENABLED(CONFIG_IPV6) -+ } else if (mpadd->ipver == 6) { -+ char *recv_hmac; -+ u8 hash_mac_check[20]; -+ u8 no_key[8]; -+ int msg_parts = 0; -+ -+ if (mpcb->mptcp_ver < MPTCP_VERSION_1) -+ goto skip_hmac_v6; -+ -+ *(u64 *)no_key = 0; -+ recv_hmac = (char *)mpadd->u.v6.mac; -+ if (mpadd->len == MPTCP_SUB_LEN_ADD_ADDR6_VER1) { -+ recv_hmac -= sizeof(mpadd->u.v6.port); -+ msg_parts = 2; -+ } else if (mpadd->len == MPTCP_SUB_LEN_ADD_ADDR6_VER1 + 2) { -+ msg_parts = 3; -+ } -+ mptcp_hmac_sha1((u8 *)&mpcb->mptcp_rem_key, -+ (u8 *)no_key, -+ (u32 *)hash_mac_check, msg_parts, -+ 1, (u8 *)&mpadd->addr_id, -+ 16, (u8 *)&mpadd->u.v6.addr.s6_addr, -+ 2, (u8 *)&mpadd->u.v6.port); -+ if (memcmp(hash_mac_check, recv_hmac, 8) != 0) -+ /* ADD_ADDR2 discarded */ -+ return; -+skip_hmac_v6: -+ if ((mpcb->mptcp_ver == MPTCP_VERSION_0 && -+ mpadd->len == MPTCP_SUB_LEN_ADD_ADDR6 + 2) || -+ (mpcb->mptcp_ver == MPTCP_VERSION_1 && -+ mpadd->len == MPTCP_SUB_LEN_ADD_ADDR6_VER1 + 2)) -+ port = mpadd->u.v6.port; -+ family = AF_INET6; -+ addr.in6 = mpadd->u.v6.addr; -+#endif /* CONFIG_IPV6 */ -+ } else { -+ return; -+ } -+ -+ if (mpcb->pm_ops->add_raddr) -+ mpcb->pm_ops->add_raddr(mpcb, &addr, family, port, mpadd->addr_id); -+ -+ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_ADDADDRRX); -+} -+ -+static void mptcp_handle_rem_addr(const unsigned char *ptr, struct sock *sk) -+{ -+ struct mp_remove_addr *mprem = (struct mp_remove_addr *)ptr; -+ int i; -+ u8 rem_id; -+ struct mptcp_cb *mpcb = tcp_sk(sk)->mpcb; -+ -+ for (i = 0; i <= mprem->len - MPTCP_SUB_LEN_REMOVE_ADDR; i++) { -+ rem_id = (&mprem->addrs_id)[i]; -+ -+ if (mpcb->pm_ops->rem_raddr) -+ mpcb->pm_ops->rem_raddr(mpcb, rem_id); -+ mptcp_send_reset_rem_id(mpcb, rem_id); -+ -+ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_REMADDRSUB); -+ } -+ -+ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_REMADDRRX); -+} -+ -+static void mptcp_parse_addropt(const struct sk_buff *skb, struct sock *sk) -+{ -+ struct tcphdr *th = tcp_hdr(skb); -+ unsigned char *ptr; -+ int length = (th->doff * 4) - sizeof(struct tcphdr); -+ -+ /* Jump through the options to check whether ADD_ADDR is there */ -+ ptr = (unsigned char *)(th + 1); -+ while (length > 0) { -+ int opcode = *ptr++; -+ int opsize; -+ -+ switch (opcode) { -+ case TCPOPT_EOL: -+ return; -+ case TCPOPT_NOP: -+ length--; -+ continue; -+ default: -+ opsize = *ptr++; -+ if (opsize < 2) -+ return; -+ if (opsize > length) -+ return; /* don't parse partial options */ -+ if (opcode == TCPOPT_MPTCP && -+ ((struct mptcp_option *)ptr)->sub == MPTCP_SUB_ADD_ADDR) { -+ u8 mptcp_ver = tcp_sk(sk)->mpcb->mptcp_ver; -+ struct mp_add_addr *mpadd = (struct mp_add_addr *)ptr; -+ -+ if (!is_valid_addropt_opsize(mptcp_ver, mpadd, -+ opsize)) -+ goto cont; -+ -+ mptcp_handle_add_addr(ptr, sk); -+ } -+ if (opcode == TCPOPT_MPTCP && -+ ((struct mptcp_option *)ptr)->sub == MPTCP_SUB_REMOVE_ADDR) { -+ if ((opsize - MPTCP_SUB_LEN_REMOVE_ADDR) < 0) -+ goto cont; -+ -+ mptcp_handle_rem_addr(ptr, sk); -+ } -+cont: -+ ptr += opsize - 2; -+ length -= opsize; -+ } -+ } -+ return; -+} -+ -+static bool mptcp_mp_fastclose_rcvd(struct sock *sk) -+{ -+ struct mptcp_tcp_sock *mptcp = tcp_sk(sk)->mptcp; -+ struct mptcp_cb *mpcb = tcp_sk(sk)->mpcb; -+ -+ if (likely(!mptcp->rx_opt.mp_fclose)) -+ return false; -+ -+ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_FASTCLOSERX); -+ mptcp->rx_opt.mp_fclose = 0; -+ if (mptcp->rx_opt.mptcp_sender_key != mpcb->mptcp_loc_key) -+ return false; -+ -+ mptcp_sub_force_close_all(mpcb, NULL); -+ -+ tcp_reset(mptcp_meta_sk(sk)); -+ -+ return true; -+} -+ -+static void mptcp_mp_fail_rcvd(struct sock *sk, const struct tcphdr *th) -+{ -+ struct mptcp_tcp_sock *mptcp = tcp_sk(sk)->mptcp; -+ struct sock *meta_sk = mptcp_meta_sk(sk); -+ struct mptcp_cb *mpcb = tcp_sk(sk)->mpcb; -+ -+ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_MPFAILRX); -+ mptcp->rx_opt.mp_fail = 0; -+ -+ if (!th->rst && !mpcb->infinite_mapping_snd) { -+ mpcb->send_infinite_mapping = 1; -+ -+ mptcp_restart_sending(meta_sk); -+ -+ mptcp_sub_force_close_all(mpcb, sk); -+ } -+} -+ -+static inline void mptcp_path_array_check(struct sock *meta_sk) -+{ -+ struct mptcp_cb *mpcb = tcp_sk(meta_sk)->mpcb; -+ -+ if (unlikely(mpcb->list_rcvd)) { -+ mpcb->list_rcvd = 0; -+ if (mpcb->pm_ops->new_remote_address) -+ mpcb->pm_ops->new_remote_address(meta_sk); -+ } -+} -+ -+bool mptcp_handle_options(struct sock *sk, const struct tcphdr *th, -+ const struct sk_buff *skb) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct mptcp_options_received *mopt = &tp->mptcp->rx_opt; -+ -+ if (tp->mpcb->infinite_mapping_rcv || tp->mpcb->infinite_mapping_snd) -+ return false; -+ -+ if (mptcp_mp_fastclose_rcvd(sk)) -+ return true; -+ -+ if (sk->sk_state == TCP_RST_WAIT && !th->rst) -+ return true; -+ -+ if (unlikely(mopt->mp_fail)) -+ mptcp_mp_fail_rcvd(sk, th); -+ -+ /* RFC 6824, Section 3.3: -+ * If a checksum is not present when its use has been negotiated, the -+ * receiver MUST close the subflow with a RST as it is considered broken. -+ */ -+ if (mptcp_is_data_seq(skb) && tp->mpcb->dss_csum && -+ !(TCP_SKB_CB(skb)->mptcp_flags & MPTCPHDR_DSS_CSUM)) { -+ mptcp_send_reset(sk); -+ return true; -+ } -+ -+ /* We have to acknowledge retransmissions of the third -+ * ack. -+ */ -+ if (mopt->join_ack) { -+ tcp_send_delayed_ack(sk); -+ mopt->join_ack = 0; -+ } -+ -+ if (mopt->saw_add_addr || mopt->saw_rem_addr) { -+ if (mopt->more_add_addr || mopt->more_rem_addr) { -+ mptcp_parse_addropt(skb, sk); -+ } else { -+ if (mopt->saw_add_addr) -+ mptcp_handle_add_addr(mopt->add_addr_ptr, sk); -+ if (mopt->saw_rem_addr) -+ mptcp_handle_rem_addr(mopt->rem_addr_ptr, sk); -+ } -+ -+ mopt->more_add_addr = 0; -+ mopt->saw_add_addr = 0; -+ mopt->more_rem_addr = 0; -+ mopt->saw_rem_addr = 0; -+ } -+ if (mopt->saw_low_prio) { -+ if (mopt->saw_low_prio == 1) { -+ tp->mptcp->rcv_low_prio = mopt->low_prio; -+ } else { -+ struct sock *sk_it; -+ mptcp_for_each_sk(tp->mpcb, sk_it) { -+ struct mptcp_tcp_sock *mptcp = tcp_sk(sk_it)->mptcp; -+ if (mptcp->rem_id == mopt->prio_addr_id) -+ mptcp->rcv_low_prio = mopt->low_prio; -+ } -+ } -+ mopt->saw_low_prio = 0; -+ } -+ -+ mptcp_data_ack(sk, skb); -+ -+ mptcp_path_array_check(mptcp_meta_sk(sk)); -+ /* Socket may have been mp_killed by a REMOVE_ADDR */ -+ if (tp->mp_killed) -+ return true; -+ -+ return false; -+} -+ -+/* In case of fastopen, some data can already be in the write queue. -+ * We need to update the sequence number of the segments as they -+ * were initially TCP sequence numbers. -+ */ -+static void mptcp_rcv_synsent_fastopen(struct sock *meta_sk) -+{ -+ struct tcp_sock *meta_tp = tcp_sk(meta_sk); -+ struct tcp_sock *master_tp = tcp_sk(meta_tp->mpcb->master_sk); -+ struct sk_buff *skb; -+ u32 new_mapping = meta_tp->write_seq - master_tp->snd_una; -+ -+ /* There should only be one skb in write queue: the data not -+ * acknowledged in the SYN+ACK. In this case, we need to map -+ * this data to data sequence numbers. -+ */ -+ skb_queue_walk(&meta_sk->sk_write_queue, skb) { -+ /* If the server only acknowledges partially the data sent in -+ * the SYN, we need to trim the acknowledged part because -+ * we don't want to retransmit this already received data. -+ * When we reach this point, tcp_ack() has already cleaned up -+ * fully acked segments. However, tcp trims partially acked -+ * segments only when retransmitting. Since MPTCP comes into -+ * play only now, we will fake an initial transmit, and -+ * retransmit_skb() will not be called. The following fragment -+ * comes from __tcp_retransmit_skb(). -+ */ -+ if (before(TCP_SKB_CB(skb)->seq, master_tp->snd_una)) { -+ BUG_ON(before(TCP_SKB_CB(skb)->end_seq, -+ master_tp->snd_una)); -+ /* tcp_trim_head can only returns ENOMEM if skb is -+ * cloned. It is not the case here (see -+ * tcp_send_syn_data). -+ */ -+ BUG_ON(tcp_trim_head(meta_sk, skb, master_tp->snd_una - -+ TCP_SKB_CB(skb)->seq)); -+ } -+ -+ TCP_SKB_CB(skb)->seq += new_mapping; -+ TCP_SKB_CB(skb)->end_seq += new_mapping; -+ } -+ -+ /* We can advance write_seq by the number of bytes unacknowledged -+ * and that were mapped in the previous loop. -+ */ -+ meta_tp->write_seq += master_tp->write_seq - master_tp->snd_una; -+ -+ /* The packets from the master_sk will be entailed to it later -+ * Until that time, its write queue is empty, and -+ * write_seq must align with snd_una -+ */ -+ master_tp->snd_nxt = master_tp->write_seq = master_tp->snd_una; -+ master_tp->packets_out = 0; -+ -+ /* Although these data have been sent already over the subsk, -+ * They have never been sent over the meta_sk, so we rewind -+ * the send_head so that tcp considers it as an initial send -+ * (instead of retransmit). -+ */ -+ meta_sk->sk_send_head = tcp_write_queue_head(meta_sk); -+} -+ -+/* The skptr is needed, because if we become MPTCP-capable, we have to switch -+ * from meta-socket to master-socket. -+ * -+ * @return: 1 - we want to reset this connection -+ * 2 - we want to discard the received syn/ack -+ * 0 - everything is fine - continue -+ */ -+int mptcp_rcv_synsent_state_process(struct sock *sk, struct sock **skptr, -+ const struct sk_buff *skb, -+ const struct mptcp_options_received *mopt) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ -+ if (mptcp(tp)) { -+ u8 hash_mac_check[20]; -+ struct mptcp_cb *mpcb = tp->mpcb; -+ -+ mptcp_hmac_sha1((u8 *)&mpcb->mptcp_rem_key, -+ (u8 *)&mpcb->mptcp_loc_key, -+ (u32 *)hash_mac_check, 2, -+ 4, (u8 *)&tp->mptcp->rx_opt.mptcp_recv_nonce, -+ 4, (u8 *)&tp->mptcp->mptcp_loc_nonce); -+ if (memcmp(hash_mac_check, -+ (char *)&tp->mptcp->rx_opt.mptcp_recv_tmac, 8)) { -+ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_JOINSYNACKMAC); -+ mptcp_sub_force_close(sk); -+ return 1; -+ } -+ -+ /* Set this flag in order to postpone data sending -+ * until the 4th ack arrives. -+ */ -+ tp->mptcp->pre_established = 1; -+ tp->mptcp->rcv_low_prio = tp->mptcp->rx_opt.low_prio; -+ -+ mptcp_hmac_sha1((u8 *)&mpcb->mptcp_loc_key, -+ (u8 *)&mpcb->mptcp_rem_key, -+ (u32 *)&tp->mptcp->sender_mac[0], 2, -+ 4, (u8 *)&tp->mptcp->mptcp_loc_nonce, -+ 4, (u8 *)&tp->mptcp->rx_opt.mptcp_recv_nonce); -+ -+ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_JOINSYNACKRX); -+ } else if (mopt->saw_mpc) { -+ struct sock *meta_sk = sk; -+ -+ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_MPCAPABLEACTIVEACK); -+ if (mopt->mptcp_ver > tcp_sk(sk)->mptcp_ver) -+ /* TODO Consider adding new MPTCP_INC_STATS entry */ -+ goto fallback; -+ -+ if (mptcp_create_master_sk(sk, mopt->mptcp_sender_key, -+ mopt->mptcp_ver, -+ ntohs(tcp_hdr(skb)->window))) -+ return 2; -+ -+ sk = tcp_sk(sk)->mpcb->master_sk; -+ *skptr = sk; -+ tp = tcp_sk(sk); -+ -+ /* If fastopen was used data might be in the send queue. We -+ * need to update their sequence number to MPTCP-level seqno. -+ * Note that it can happen in rare cases that fastopen_req is -+ * NULL and syn_data is 0 but fastopen indeed occurred and -+ * data has been queued in the write queue (but not sent). -+ * Example of such rare cases: connect is non-blocking and -+ * TFO is configured to work without cookies. -+ */ -+ if (!skb_queue_empty(&meta_sk->sk_write_queue)) -+ mptcp_rcv_synsent_fastopen(meta_sk); -+ -+ /* -1, because the SYN consumed 1 byte. In case of TFO, we -+ * start the subflow-sequence number as if the data of the SYN -+ * is not part of any mapping. -+ */ -+ tp->mptcp->snt_isn = tp->snd_una - 1; -+ tp->mpcb->dss_csum = mopt->dss_csum; -+ if (tp->mpcb->dss_csum) -+ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_CSUMENABLED); -+ -+ tp->mptcp->include_mpc = 1; -+ -+ /* Ensure that fastopen is handled at the meta-level. */ -+ tp->fastopen_req = NULL; -+ -+ sk_set_socket(sk, meta_sk->sk_socket); -+ sk->sk_wq = meta_sk->sk_wq; -+ -+ bh_unlock_sock(sk); -+ /* hold in sk_clone_lock due to initialization to 2 */ -+ sock_put(sk); -+ } else { -+ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_MPCAPABLEACTIVEFALLBACK); -+fallback: -+ tp->request_mptcp = 0; -+ -+ if (tp->inside_tk_table) -+ mptcp_hash_remove_bh(tp); -+ } -+ -+ if (mptcp(tp)) -+ tp->mptcp->rcv_isn = TCP_SKB_CB(skb)->seq; -+ -+ return 0; -+} -+ -+/* Similar to tcp_should_expand_sndbuf */ -+bool mptcp_should_expand_sndbuf(const struct sock *sk) -+{ -+ const struct sock *sk_it; -+ const struct sock *meta_sk = mptcp_meta_sk(sk); -+ const struct tcp_sock *meta_tp = tcp_sk(meta_sk); -+ int cnt_backups = 0; -+ int backup_available = 0; -+ -+ /* We circumvent this check in tcp_check_space, because we want to -+ * always call sk_write_space. So, we reproduce the check here. -+ */ -+ if (!meta_sk->sk_socket || -+ !test_bit(SOCK_NOSPACE, &meta_sk->sk_socket->flags)) -+ return false; -+ -+ /* If the user specified a specific send buffer setting, do -+ * not modify it. -+ */ -+ if (meta_sk->sk_userlocks & SOCK_SNDBUF_LOCK) -+ return false; -+ -+ /* If we are under global TCP memory pressure, do not expand. */ -+ if (tcp_under_memory_pressure(meta_sk)) -+ return false; -+ -+ /* If we are under soft global TCP memory pressure, do not expand. */ -+ if (sk_memory_allocated(meta_sk) >= sk_prot_mem_limits(meta_sk, 0)) -+ return false; -+ -+ /* For MPTCP we look for a subsocket that could send data. -+ * If we found one, then we update the send-buffer. -+ */ -+ mptcp_for_each_sk(meta_tp->mpcb, sk_it) { -+ struct tcp_sock *tp_it = tcp_sk(sk_it); -+ -+ if (!mptcp_sk_can_send(sk_it)) -+ continue; -+ -+ /* Backup-flows have to be counted - if there is no other -+ * subflow we take the backup-flow into account. -+ */ -+ if (tp_it->mptcp->rcv_low_prio || tp_it->mptcp->low_prio) -+ cnt_backups++; -+ -+ if (tcp_packets_in_flight(tp_it) < tp_it->snd_cwnd) { -+ if (tp_it->mptcp->rcv_low_prio || tp_it->mptcp->low_prio) { -+ backup_available = 1; -+ continue; -+ } -+ return true; -+ } -+ } -+ -+ /* Backup-flow is available for sending - update send-buffer */ -+ if (meta_tp->mpcb->cnt_established == cnt_backups && backup_available) -+ return true; -+ return false; -+} -+ -+void mptcp_init_buffer_space(struct sock *sk) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct sock *meta_sk = mptcp_meta_sk(sk); -+ struct tcp_sock *meta_tp = tcp_sk(meta_sk); -+ int space; -+ -+ tcp_init_buffer_space(sk); -+ -+ if (is_master_tp(tp)) { -+ meta_tp->rcvq_space.space = meta_tp->rcv_wnd; -+ tcp_mstamp_refresh(meta_tp); -+ meta_tp->rcvq_space.time = meta_tp->tcp_mstamp; -+ meta_tp->rcvq_space.seq = meta_tp->copied_seq; -+ -+ /* If there is only one subflow, we just use regular TCP -+ * autotuning. User-locks are handled already by -+ * tcp_init_buffer_space -+ */ -+ meta_tp->window_clamp = tp->window_clamp; -+ meta_tp->rcv_ssthresh = tp->rcv_ssthresh; -+ meta_sk->sk_rcvbuf = sk->sk_rcvbuf; -+ meta_sk->sk_sndbuf = sk->sk_sndbuf; -+ -+ return; -+ } -+ -+ if (meta_sk->sk_userlocks & SOCK_RCVBUF_LOCK) -+ goto snd_buf; -+ -+ /* Adding a new subflow to the rcv-buffer space. We make a simple -+ * addition, to give some space to allow traffic on the new subflow. -+ * Autotuning will increase it further later on. -+ */ -+ space = min(meta_sk->sk_rcvbuf + sk->sk_rcvbuf, sysctl_tcp_rmem[2]); -+ if (space > meta_sk->sk_rcvbuf) { -+ meta_tp->window_clamp += tp->window_clamp; -+ meta_tp->rcv_ssthresh += tp->rcv_ssthresh; -+ meta_sk->sk_rcvbuf = space; -+ } -+ -+snd_buf: -+ if (meta_sk->sk_userlocks & SOCK_SNDBUF_LOCK) -+ return; -+ -+ /* Adding a new subflow to the send-buffer space. We make a simple -+ * addition, to give some space to allow traffic on the new subflow. -+ * Autotuning will increase it further later on. -+ */ -+ space = min(meta_sk->sk_sndbuf + sk->sk_sndbuf, sysctl_tcp_wmem[2]); -+ if (space > meta_sk->sk_sndbuf) { -+ meta_sk->sk_sndbuf = space; -+ meta_sk->sk_write_space(meta_sk); -+ } -+} -+ -+void mptcp_tcp_set_rto(struct sock *sk) -+{ -+ tcp_set_rto(sk); -+ mptcp_set_rto(sk); -+} -diff -aurN linux-4.14.174/net/mptcp/mptcp_ipv4.c mptcp-mptcp_v0.94/net/mptcp/mptcp_ipv4.c ---- linux-4.14.174/net/mptcp/mptcp_ipv4.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_v0.94/net/mptcp/mptcp_ipv4.c 2020-03-23 09:45:33.000000000 +0100 -@@ -0,0 +1,436 @@ -+/* -+ * MPTCP implementation - IPv4-specific functions -+ * -+ * Initial Design & Implementation: -+ * Sébastien Barré -+ * -+ * Current Maintainer: -+ * Christoph Paasch -+ * -+ * Additional authors: -+ * Jaakko Korkeaniemi -+ * Gregory Detal -+ * Fabien Duchêne -+ * Andreas Seelinger -+ * Lavkesh Lahngir -+ * Andreas Ripke -+ * Vlad Dogaru -+ * Octavian Purdila -+ * John Ronan -+ * Catalin Nicutar -+ * Brandon Heller -+ * -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version -+ * 2 of the License, or (at your option) any later version. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+u32 mptcp_v4_get_nonce(__be32 saddr, __be32 daddr, __be16 sport, __be16 dport) -+{ -+ return siphash_4u32((__force u32)saddr, (__force u32)daddr, -+ (__force u32)sport << 16 | (__force u32)dport, -+ mptcp_seed++, &mptcp_secret); -+} -+ -+u64 mptcp_v4_get_key(__be32 saddr, __be32 daddr, __be16 sport, __be16 dport, -+ u32 seed) -+{ -+ return siphash_2u64((__force u64)saddr << 32 | (__force u64)daddr, -+ (__force u64)seed << 32 | (__force u64)sport << 16 | (__force u64)dport, -+ &mptcp_secret); -+} -+ -+ -+static void mptcp_v4_reqsk_destructor(struct request_sock *req) -+{ -+ mptcp_reqsk_destructor(req); -+ -+ tcp_v4_reqsk_destructor(req); -+} -+ -+static int mptcp_v4_init_req(struct request_sock *req, const struct sock *sk, -+ struct sk_buff *skb, bool want_cookie) -+{ -+ tcp_request_sock_ipv4_ops.init_req(req, sk, skb, want_cookie); -+ -+ mptcp_rsk(req)->hash_entry.pprev = NULL; -+ mptcp_rsk(req)->is_sub = 0; -+ inet_rsk(req)->mptcp_rqsk = 1; -+ -+ /* In case of SYN-cookies, we wait for the isn to be generated - it is -+ * input to the key-generation. -+ */ -+ if (!want_cookie) -+ mptcp_reqsk_init(req, sk, skb, false); -+ -+ return 0; -+} -+ -+#ifdef CONFIG_SYN_COOKIES -+static u32 mptcp_v4_cookie_init_seq(struct request_sock *req, const struct sock *sk, -+ const struct sk_buff *skb, __u16 *mssp) -+{ -+ __u32 isn = cookie_v4_init_sequence(req, sk, skb, mssp); -+ -+ tcp_rsk(req)->snt_isn = isn; -+ -+ mptcp_reqsk_init(req, sk, skb, true); -+ -+ return isn; -+} -+#endif -+ -+static int mptcp_v4_join_init_req(struct request_sock *req, const struct sock *sk, -+ struct sk_buff *skb, bool want_cookie) -+{ -+ struct mptcp_request_sock *mtreq = mptcp_rsk(req); -+ const struct mptcp_cb *mpcb = tcp_sk(sk)->mpcb; -+ union inet_addr addr; -+ int loc_id; -+ bool low_prio = false; -+ -+ /* We need to do this as early as possible. Because, if we fail later -+ * (e.g., get_local_id), then reqsk_free tries to remove the -+ * request-socket from the htb in mptcp_hash_request_remove as pprev -+ * may be different from NULL. -+ */ -+ mtreq->hash_entry.pprev = NULL; -+ -+ tcp_request_sock_ipv4_ops.init_req(req, sk, skb, want_cookie); -+ -+ mtreq->mptcp_loc_nonce = mptcp_v4_get_nonce(ip_hdr(skb)->saddr, -+ ip_hdr(skb)->daddr, -+ tcp_hdr(skb)->source, -+ tcp_hdr(skb)->dest); -+ addr.ip = inet_rsk(req)->ir_loc_addr; -+ loc_id = mpcb->pm_ops->get_local_id(AF_INET, &addr, sock_net(sk), &low_prio); -+ if (loc_id == -1) -+ return -1; -+ mtreq->loc_id = loc_id; -+ mtreq->low_prio = low_prio; -+ -+ mptcp_join_reqsk_init(mpcb, req, skb); -+ -+ return 0; -+} -+ -+/* Similar to tcp_request_sock_ops */ -+struct request_sock_ops mptcp_request_sock_ops __read_mostly = { -+ .family = PF_INET, -+ .obj_size = sizeof(struct mptcp_request_sock), -+ .rtx_syn_ack = tcp_rtx_synack, -+ .send_ack = tcp_v4_reqsk_send_ack, -+ .destructor = mptcp_v4_reqsk_destructor, -+ .send_reset = tcp_v4_send_reset, -+ .syn_ack_timeout = tcp_syn_ack_timeout, -+}; -+ -+/* Similar to: tcp_v4_conn_request */ -+static int mptcp_v4_join_request(struct sock *meta_sk, struct sk_buff *skb) -+{ -+ return tcp_conn_request(&mptcp_request_sock_ops, -+ &mptcp_join_request_sock_ipv4_ops, -+ meta_sk, skb); -+} -+ -+int mptcp_finish_handshake(struct sock *child, struct sk_buff *skb) -+ __releases(&child->sk_lock.slock) -+{ -+ int ret; -+ -+ /* We don't call tcp_child_process here, because we hold -+ * already the meta-sk-lock and are sure that it is not owned -+ * by the user. -+ */ -+ tcp_sk(child)->segs_in += max_t(u16, 1, skb_shinfo(skb)->gso_segs); -+ ret = tcp_rcv_state_process(child, skb); -+ bh_unlock_sock(child); -+ sock_put(child); -+ -+ return ret; -+} -+ -+ -+/* Similar to: tcp_v4_do_rcv -+ * We only process join requests here. (either the SYN or the final ACK) -+ */ -+int mptcp_v4_do_rcv(struct sock *meta_sk, struct sk_buff *skb) -+{ -+ const struct tcphdr *th = tcp_hdr(skb); -+ const struct iphdr *iph = ip_hdr(skb); -+ struct sock *child, *rsk = NULL, *sk; -+ int ret; -+ -+ sk = inet_lookup_established(sock_net(meta_sk), &tcp_hashinfo, -+ iph->saddr, th->source, iph->daddr, -+ th->dest, inet_iif(skb)); -+ -+ if (!sk) -+ goto new_subflow; -+ -+ if (is_meta_sk(sk)) { -+ WARN("%s Did not find a sub-sk - did found the meta!\n", __func__); -+ sock_put(sk); -+ goto discard; -+ } -+ -+ if (sk->sk_state == TCP_TIME_WAIT) { -+ inet_twsk_put(inet_twsk(sk)); -+ goto discard; -+ } -+ -+ if (sk->sk_state == TCP_NEW_SYN_RECV) { -+ struct request_sock *req = inet_reqsk(sk); -+ -+ if (!mptcp_can_new_subflow(meta_sk)) -+ goto reset_and_discard; -+ -+ local_bh_disable(); -+ child = tcp_check_req(meta_sk, skb, req, false); -+ if (!child) { -+ reqsk_put(req); -+ local_bh_enable(); -+ goto discard; -+ } -+ -+ if (child != meta_sk) { -+ ret = mptcp_finish_handshake(child, skb); -+ if (ret) { -+ rsk = child; -+ local_bh_enable(); -+ goto reset_and_discard; -+ } -+ -+ local_bh_enable(); -+ return 0; -+ } -+ -+ /* tcp_check_req failed */ -+ reqsk_put(req); -+ -+ local_bh_enable(); -+ goto discard; -+ } -+ -+ ret = tcp_v4_do_rcv(sk, skb); -+ sock_put(sk); -+ -+ return ret; -+ -+new_subflow: -+ if (!mptcp_can_new_subflow(meta_sk)) -+ goto reset_and_discard; -+ -+ child = tcp_v4_cookie_check(meta_sk, skb); -+ if (!child) -+ goto discard; -+ -+ if (child != meta_sk) { -+ ret = mptcp_finish_handshake(child, skb); -+ if (ret) { -+ rsk = child; -+ goto reset_and_discard; -+ } -+ } -+ -+ if (tcp_hdr(skb)->syn) { -+ local_bh_disable(); -+ mptcp_v4_join_request(meta_sk, skb); -+ local_bh_enable(); -+ } -+ -+discard: -+ kfree_skb(skb); -+ return 0; -+ -+reset_and_discard: -+ tcp_v4_send_reset(rsk, skb); -+ goto discard; -+} -+ -+/* Create a new IPv4 subflow. -+ * -+ * We are in user-context and meta-sock-lock is hold. -+ */ -+int mptcp_init4_subsockets(struct sock *meta_sk, const struct mptcp_loc4 *loc, -+ struct mptcp_rem4 *rem) -+{ -+ struct tcp_sock *tp; -+ struct sock *sk; -+ struct sockaddr_in loc_in, rem_in; -+ struct socket_alloc sock_full; -+ struct socket *sock = (struct socket *)&sock_full; -+ int ret; -+ -+ /** First, create and prepare the new socket */ -+ memcpy(&sock_full, meta_sk->sk_socket, sizeof(sock_full)); -+ sock->state = SS_UNCONNECTED; -+ sock->ops = NULL; -+ -+ ret = inet_create(sock_net(meta_sk), sock, IPPROTO_TCP, 1); -+ if (unlikely(ret < 0)) { -+ net_err_ratelimited("%s inet_create failed ret: %d\n", -+ __func__, ret); -+ return ret; -+ } -+ -+ sk = sock->sk; -+ tp = tcp_sk(sk); -+ -+ /* All subsockets need the MPTCP-lock-class */ -+ lockdep_set_class_and_name(&(sk)->sk_lock.slock, &meta_slock_key, meta_slock_key_name); -+ lockdep_init_map(&(sk)->sk_lock.dep_map, meta_key_name, &meta_key, 0); -+ -+ if (mptcp_add_sock(meta_sk, sk, loc->loc4_id, rem->rem4_id, GFP_KERNEL)) { -+ net_err_ratelimited("%s mptcp_add_sock failed ret: %d\n", -+ __func__, ret); -+ goto error; -+ } -+ -+ tp->mptcp->slave_sk = 1; -+ tp->mptcp->low_prio = loc->low_prio; -+ -+ /* Initializing the timer for an MPTCP subflow */ -+ setup_timer(&tp->mptcp->mptcp_ack_timer, mptcp_ack_handler, (unsigned long)sk); -+ -+ /** Then, connect the socket to the peer */ -+ loc_in.sin_family = AF_INET; -+ rem_in.sin_family = AF_INET; -+ loc_in.sin_port = 0; -+ if (rem->port) -+ rem_in.sin_port = rem->port; -+ else -+ rem_in.sin_port = inet_sk(meta_sk)->inet_dport; -+ loc_in.sin_addr = loc->addr; -+ rem_in.sin_addr = rem->addr; -+ -+ if (loc->if_idx) -+ sk->sk_bound_dev_if = loc->if_idx; -+ -+ ret = kernel_bind(sock, (struct sockaddr *)&loc_in, -+ sizeof(struct sockaddr_in)); -+ if (ret < 0) { -+ net_err_ratelimited("%s: token %#x bind() to %pI4 index %d failed, error %d\n", -+ __func__, tcp_sk(meta_sk)->mpcb->mptcp_loc_token, -+ &loc_in.sin_addr, loc->if_idx, ret); -+ goto error; -+ } -+ -+ mptcp_debug("%s: token %#x pi %d src_addr:%pI4:%d dst_addr:%pI4:%d ifidx: %d\n", -+ __func__, tcp_sk(meta_sk)->mpcb->mptcp_loc_token, -+ tp->mptcp->path_index, &loc_in.sin_addr, -+ ntohs(loc_in.sin_port), &rem_in.sin_addr, -+ ntohs(rem_in.sin_port), loc->if_idx); -+ -+ if (tcp_sk(meta_sk)->mpcb->pm_ops->init_subsocket_v4) -+ tcp_sk(meta_sk)->mpcb->pm_ops->init_subsocket_v4(sk, rem->addr); -+ -+ ret = kernel_connect(sock, (struct sockaddr *)&rem_in, -+ sizeof(struct sockaddr_in), O_NONBLOCK); -+ if (ret < 0 && ret != -EINPROGRESS) { -+ net_err_ratelimited("%s: MPTCP subsocket connect() failed, error %d\n", -+ __func__, ret); -+ goto error; -+ } -+ -+ MPTCP_INC_STATS(sock_net(meta_sk), MPTCP_MIB_JOINSYNTX); -+ -+ sk_set_socket(sk, meta_sk->sk_socket); -+ sk->sk_wq = meta_sk->sk_wq; -+ -+ return 0; -+ -+error: -+ /* May happen if mptcp_add_sock fails first */ -+ if (!mptcp(tp)) { -+ tcp_close(sk, 0); -+ } else { -+ local_bh_disable(); -+ mptcp_sub_force_close(sk); -+ local_bh_enable(); -+ } -+ return ret; -+} -+EXPORT_SYMBOL(mptcp_init4_subsockets); -+ -+const struct inet_connection_sock_af_ops mptcp_v4_specific = { -+ .queue_xmit = ip_queue_xmit, -+ .send_check = tcp_v4_send_check, -+ .rebuild_header = inet_sk_rebuild_header, -+ .sk_rx_dst_set = inet_sk_rx_dst_set, -+ .conn_request = mptcp_conn_request, -+ .syn_recv_sock = tcp_v4_syn_recv_sock, -+ .net_header_len = sizeof(struct iphdr), -+ .setsockopt = ip_setsockopt, -+ .getsockopt = ip_getsockopt, -+ .addr2sockaddr = inet_csk_addr2sockaddr, -+ .sockaddr_len = sizeof(struct sockaddr_in), -+#ifdef CONFIG_COMPAT -+ .compat_setsockopt = compat_ip_setsockopt, -+ .compat_getsockopt = compat_ip_getsockopt, -+#endif -+ .mtu_reduced = tcp_v4_mtu_reduced, -+}; -+ -+struct tcp_request_sock_ops mptcp_request_sock_ipv4_ops; -+struct tcp_request_sock_ops mptcp_join_request_sock_ipv4_ops; -+ -+/* General initialization of IPv4 for MPTCP */ -+int mptcp_pm_v4_init(void) -+{ -+ int ret = 0; -+ struct request_sock_ops *ops = &mptcp_request_sock_ops; -+ -+ mptcp_request_sock_ipv4_ops = tcp_request_sock_ipv4_ops; -+ mptcp_request_sock_ipv4_ops.init_req = mptcp_v4_init_req; -+#ifdef CONFIG_SYN_COOKIES -+ mptcp_request_sock_ipv4_ops.cookie_init_seq = mptcp_v4_cookie_init_seq; -+#endif -+ mptcp_join_request_sock_ipv4_ops = tcp_request_sock_ipv4_ops; -+ mptcp_join_request_sock_ipv4_ops.init_req = mptcp_v4_join_init_req; -+ -+ ops->slab_name = kasprintf(GFP_KERNEL, "request_sock_%s", "MPTCP"); -+ if (ops->slab_name == NULL) { -+ ret = -ENOMEM; -+ goto out; -+ } -+ -+ ops->slab = kmem_cache_create(ops->slab_name, ops->obj_size, 0, -+ SLAB_TYPESAFE_BY_RCU|SLAB_HWCACHE_ALIGN, -+ NULL); -+ -+ if (ops->slab == NULL) { -+ ret = -ENOMEM; -+ goto err_reqsk_create; -+ } -+ -+out: -+ return ret; -+ -+err_reqsk_create: -+ kfree(ops->slab_name); -+ ops->slab_name = NULL; -+ goto out; -+} -+ -+void mptcp_pm_v4_undo(void) -+{ -+ kmem_cache_destroy(mptcp_request_sock_ops.slab); -+ kfree(mptcp_request_sock_ops.slab_name); -+} -diff -aurN linux-4.14.174/net/mptcp/mptcp_ipv6.c mptcp-mptcp_v0.94/net/mptcp/mptcp_ipv6.c ---- linux-4.14.174/net/mptcp/mptcp_ipv6.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_v0.94/net/mptcp/mptcp_ipv6.c 2020-03-23 09:45:33.000000000 +0100 -@@ -0,0 +1,465 @@ -+/* -+ * MPTCP implementation - IPv6-specific functions -+ * -+ * Initial Design & Implementation: -+ * Sébastien Barré -+ * -+ * Current Maintainer: -+ * Jaakko Korkeaniemi -+ * -+ * Additional authors: -+ * Jaakko Korkeaniemi -+ * Gregory Detal -+ * Fabien Duchêne -+ * Andreas Seelinger -+ * Lavkesh Lahngir -+ * Andreas Ripke -+ * Vlad Dogaru -+ * Octavian Purdila -+ * John Ronan -+ * Catalin Nicutar -+ * Brandon Heller -+ * -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version -+ * 2 of the License, or (at your option) any later version. -+ */ -+ -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+__u32 mptcp_v6_get_nonce(const __be32 *saddr, const __be32 *daddr, -+ __be16 sport, __be16 dport) -+{ -+ const struct { -+ struct in6_addr saddr; -+ struct in6_addr daddr; -+ u32 seed; -+ __be16 sport; -+ __be16 dport; -+ } __aligned(SIPHASH_ALIGNMENT) combined = { -+ .saddr = *(struct in6_addr *)saddr, -+ .daddr = *(struct in6_addr *)daddr, -+ .seed = mptcp_seed++, -+ .sport = sport, -+ .dport = dport -+ }; -+ -+ return siphash(&combined, offsetofend(typeof(combined), dport), -+ &mptcp_secret); -+} -+ -+u64 mptcp_v6_get_key(const __be32 *saddr, const __be32 *daddr, -+ __be16 sport, __be16 dport, u32 seed) -+{ -+ const struct { -+ struct in6_addr saddr; -+ struct in6_addr daddr; -+ u32 seed; -+ __be16 sport; -+ __be16 dport; -+ } __aligned(SIPHASH_ALIGNMENT) combined = { -+ .saddr = *(struct in6_addr *)saddr, -+ .daddr = *(struct in6_addr *)daddr, -+ .seed = seed, -+ .sport = sport, -+ .dport = dport -+ }; -+ -+ return siphash(&combined, offsetofend(typeof(combined), dport), -+ &mptcp_secret); -+} -+ -+static void mptcp_v6_reqsk_destructor(struct request_sock *req) -+{ -+ mptcp_reqsk_destructor(req); -+ -+ tcp_v6_reqsk_destructor(req); -+} -+ -+static int mptcp_v6_init_req(struct request_sock *req, const struct sock *sk, -+ struct sk_buff *skb, bool want_cookie) -+{ -+ tcp_request_sock_ipv6_ops.init_req(req, sk, skb, want_cookie); -+ -+ mptcp_rsk(req)->hash_entry.pprev = NULL; -+ mptcp_rsk(req)->is_sub = 0; -+ inet_rsk(req)->mptcp_rqsk = 1; -+ -+ /* In case of SYN-cookies, we wait for the isn to be generated - it is -+ * input to the key-generation. -+ */ -+ if (!want_cookie) -+ mptcp_reqsk_init(req, sk, skb, false); -+ -+ return 0; -+} -+ -+#ifdef CONFIG_SYN_COOKIES -+static u32 mptcp_v6_cookie_init_seq(struct request_sock *req, const struct sock *sk, -+ const struct sk_buff *skb, __u16 *mssp) -+{ -+ __u32 isn = cookie_v6_init_sequence(req, sk, skb, mssp); -+ -+ tcp_rsk(req)->snt_isn = isn; -+ -+ mptcp_reqsk_init(req, sk, skb, true); -+ -+ return isn; -+} -+#endif -+ -+static int mptcp_v6_join_init_req(struct request_sock *req, const struct sock *sk, -+ struct sk_buff *skb, bool want_cookie) -+{ -+ struct mptcp_request_sock *mtreq = mptcp_rsk(req); -+ const struct mptcp_cb *mpcb = tcp_sk(sk)->mpcb; -+ union inet_addr addr; -+ int loc_id; -+ bool low_prio = false; -+ -+ /* We need to do this as early as possible. Because, if we fail later -+ * (e.g., get_local_id), then reqsk_free tries to remove the -+ * request-socket from the htb in mptcp_hash_request_remove as pprev -+ * may be different from NULL. -+ */ -+ mtreq->hash_entry.pprev = NULL; -+ -+ tcp_request_sock_ipv6_ops.init_req(req, sk, skb, want_cookie); -+ -+ mtreq->mptcp_loc_nonce = mptcp_v6_get_nonce(ipv6_hdr(skb)->saddr.s6_addr32, -+ ipv6_hdr(skb)->daddr.s6_addr32, -+ tcp_hdr(skb)->source, -+ tcp_hdr(skb)->dest); -+ addr.in6 = inet_rsk(req)->ir_v6_loc_addr; -+ loc_id = mpcb->pm_ops->get_local_id(AF_INET6, &addr, sock_net(sk), &low_prio); -+ if (loc_id == -1) -+ return -1; -+ mtreq->loc_id = loc_id; -+ mtreq->low_prio = low_prio; -+ -+ mptcp_join_reqsk_init(mpcb, req, skb); -+ -+ return 0; -+} -+ -+/* Similar to tcp6_request_sock_ops */ -+struct request_sock_ops mptcp6_request_sock_ops __read_mostly = { -+ .family = AF_INET6, -+ .obj_size = sizeof(struct mptcp_request_sock), -+ .rtx_syn_ack = tcp_rtx_synack, -+ .send_ack = tcp_v6_reqsk_send_ack, -+ .destructor = mptcp_v6_reqsk_destructor, -+ .send_reset = tcp_v6_send_reset, -+ .syn_ack_timeout = tcp_syn_ack_timeout, -+}; -+ -+static int mptcp_v6_join_request(struct sock *meta_sk, struct sk_buff *skb) -+{ -+ return tcp_conn_request(&mptcp6_request_sock_ops, -+ &mptcp_join_request_sock_ipv6_ops, -+ meta_sk, skb); -+} -+ -+int mptcp_v6_do_rcv(struct sock *meta_sk, struct sk_buff *skb) -+{ -+ const struct tcphdr *th = tcp_hdr(skb); -+ const struct ipv6hdr *ip6h = ipv6_hdr(skb); -+ struct sock *child, *rsk = NULL, *sk; -+ int ret; -+ -+ sk = __inet6_lookup_established(sock_net(meta_sk), -+ &tcp_hashinfo, -+ &ip6h->saddr, th->source, -+ &ip6h->daddr, ntohs(th->dest), -+ tcp_v6_iif(skb), tcp_v6_sdif(skb)); -+ -+ if (!sk) -+ goto new_subflow; -+ -+ if (is_meta_sk(sk)) { -+ WARN("%s Did not find a sub-sk - did found the meta!\n", __func__); -+ sock_put(sk); -+ goto discard; -+ } -+ -+ if (sk->sk_state == TCP_TIME_WAIT) { -+ inet_twsk_put(inet_twsk(sk)); -+ goto discard; -+ } -+ -+ if (sk->sk_state == TCP_NEW_SYN_RECV) { -+ struct request_sock *req = inet_reqsk(sk); -+ -+ if (!mptcp_can_new_subflow(meta_sk)) -+ goto reset_and_discard; -+ -+ local_bh_disable(); -+ child = tcp_check_req(meta_sk, skb, req, false); -+ if (!child) { -+ reqsk_put(req); -+ local_bh_enable(); -+ goto discard; -+ } -+ -+ if (child != meta_sk) { -+ ret = mptcp_finish_handshake(child, skb); -+ if (ret) { -+ rsk = child; -+ local_bh_enable(); -+ goto reset_and_discard; -+ } -+ -+ local_bh_enable(); -+ return 0; -+ } -+ -+ /* tcp_check_req failed */ -+ reqsk_put(req); -+ -+ local_bh_enable(); -+ goto discard; -+ } -+ -+ ret = tcp_v6_do_rcv(sk, skb); -+ sock_put(sk); -+ -+ return ret; -+ -+new_subflow: -+ if (!mptcp_can_new_subflow(meta_sk)) -+ goto reset_and_discard; -+ -+ child = tcp_v6_cookie_check(meta_sk, skb); -+ if (!child) -+ goto discard; -+ -+ if (child != meta_sk) { -+ ret = mptcp_finish_handshake(child, skb); -+ if (ret) { -+ rsk = child; -+ goto reset_and_discard; -+ } -+ } -+ -+ if (tcp_hdr(skb)->syn) { -+ local_bh_disable(); -+ mptcp_v6_join_request(meta_sk, skb); -+ local_bh_enable(); -+ } -+ -+discard: -+ kfree_skb(skb); -+ return 0; -+ -+reset_and_discard: -+ tcp_v6_send_reset(rsk, skb); -+ goto discard; -+} -+ -+/* Create a new IPv6 subflow. -+ * -+ * We are in user-context and meta-sock-lock is hold. -+ */ -+int mptcp_init6_subsockets(struct sock *meta_sk, const struct mptcp_loc6 *loc, -+ struct mptcp_rem6 *rem) -+{ -+ struct tcp_sock *tp; -+ struct sock *sk; -+ struct sockaddr_in6 loc_in, rem_in; -+ struct socket_alloc sock_full; -+ struct socket *sock = (struct socket *)&sock_full; -+ int ret; -+ -+ /** First, create and prepare the new socket */ -+ memcpy(&sock_full, meta_sk->sk_socket, sizeof(sock_full)); -+ sock->state = SS_UNCONNECTED; -+ sock->ops = NULL; -+ -+ ret = inet6_create(sock_net(meta_sk), sock, IPPROTO_TCP, 1); -+ if (unlikely(ret < 0)) { -+ net_err_ratelimited("%s inet6_create failed ret: %d\n", -+ __func__, ret); -+ return ret; -+ } -+ -+ sk = sock->sk; -+ tp = tcp_sk(sk); -+ -+ /* All subsockets need the MPTCP-lock-class */ -+ lockdep_set_class_and_name(&(sk)->sk_lock.slock, &meta_slock_key, meta_slock_key_name); -+ lockdep_init_map(&(sk)->sk_lock.dep_map, meta_key_name, &meta_key, 0); -+ -+ if (mptcp_add_sock(meta_sk, sk, loc->loc6_id, rem->rem6_id, GFP_KERNEL)) { -+ net_err_ratelimited("%s mptcp_add_sock failed ret: %d\n", -+ __func__, ret); -+ goto error; -+ } -+ -+ tp->mptcp->slave_sk = 1; -+ tp->mptcp->low_prio = loc->low_prio; -+ -+ /* Initializing the timer for an MPTCP subflow */ -+ setup_timer(&tp->mptcp->mptcp_ack_timer, mptcp_ack_handler, (unsigned long)sk); -+ -+ /** Then, connect the socket to the peer */ -+ loc_in.sin6_family = AF_INET6; -+ rem_in.sin6_family = AF_INET6; -+ loc_in.sin6_port = 0; -+ if (rem->port) -+ rem_in.sin6_port = rem->port; -+ else -+ rem_in.sin6_port = inet_sk(meta_sk)->inet_dport; -+ loc_in.sin6_addr = loc->addr; -+ rem_in.sin6_addr = rem->addr; -+ -+ if (loc->if_idx) -+ sk->sk_bound_dev_if = loc->if_idx; -+ -+ ret = kernel_bind(sock, (struct sockaddr *)&loc_in, -+ sizeof(struct sockaddr_in6)); -+ if (ret < 0) { -+ net_err_ratelimited("%s: token %#x bind() to %pI6 index %d failed, error %d\n", -+ __func__, tcp_sk(meta_sk)->mpcb->mptcp_loc_token, -+ &loc_in.sin6_addr, loc->if_idx, ret); -+ goto error; -+ } -+ -+ mptcp_debug("%s: token %#x pi %d src_addr:%pI6:%d dst_addr:%pI6:%d ifidx: %u\n", -+ __func__, tcp_sk(meta_sk)->mpcb->mptcp_loc_token, -+ tp->mptcp->path_index, &loc_in.sin6_addr, -+ ntohs(loc_in.sin6_port), &rem_in.sin6_addr, -+ ntohs(rem_in.sin6_port), loc->if_idx); -+ -+ if (tcp_sk(meta_sk)->mpcb->pm_ops->init_subsocket_v6) -+ tcp_sk(meta_sk)->mpcb->pm_ops->init_subsocket_v6(sk, rem->addr); -+ -+ ret = kernel_connect(sock, (struct sockaddr *)&rem_in, -+ sizeof(struct sockaddr_in6), O_NONBLOCK); -+ if (ret < 0 && ret != -EINPROGRESS) { -+ net_err_ratelimited("%s: MPTCP subsocket connect() failed, error %d\n", -+ __func__, ret); -+ goto error; -+ } -+ -+ MPTCP_INC_STATS(sock_net(meta_sk), MPTCP_MIB_JOINSYNTX); -+ -+ sk_set_socket(sk, meta_sk->sk_socket); -+ sk->sk_wq = meta_sk->sk_wq; -+ -+ return 0; -+ -+error: -+ /* May happen if mptcp_add_sock fails first */ -+ if (!mptcp(tp)) { -+ tcp_close(sk, 0); -+ } else { -+ local_bh_disable(); -+ mptcp_sub_force_close(sk); -+ local_bh_enable(); -+ } -+ return ret; -+} -+EXPORT_SYMBOL(mptcp_init6_subsockets); -+ -+const struct inet_connection_sock_af_ops mptcp_v6_specific = { -+ .queue_xmit = inet6_csk_xmit, -+ .send_check = tcp_v6_send_check, -+ .rebuild_header = inet6_sk_rebuild_header, -+ .sk_rx_dst_set = inet6_sk_rx_dst_set, -+ .conn_request = mptcp_conn_request, -+ .syn_recv_sock = tcp_v6_syn_recv_sock, -+ .net_header_len = sizeof(struct ipv6hdr), -+ .net_frag_header_len = sizeof(struct frag_hdr), -+ .setsockopt = ipv6_setsockopt, -+ .getsockopt = ipv6_getsockopt, -+ .addr2sockaddr = inet6_csk_addr2sockaddr, -+ .sockaddr_len = sizeof(struct sockaddr_in6), -+#ifdef CONFIG_COMPAT -+ .compat_setsockopt = compat_ipv6_setsockopt, -+ .compat_getsockopt = compat_ipv6_getsockopt, -+#endif -+ .mtu_reduced = tcp_v6_mtu_reduced, -+}; -+ -+const struct inet_connection_sock_af_ops mptcp_v6_mapped = { -+ .queue_xmit = ip_queue_xmit, -+ .send_check = tcp_v4_send_check, -+ .rebuild_header = inet_sk_rebuild_header, -+ .sk_rx_dst_set = inet_sk_rx_dst_set, -+ .conn_request = mptcp_conn_request, -+ .syn_recv_sock = tcp_v6_syn_recv_sock, -+ .net_header_len = sizeof(struct iphdr), -+ .setsockopt = ipv6_setsockopt, -+ .getsockopt = ipv6_getsockopt, -+ .addr2sockaddr = inet6_csk_addr2sockaddr, -+ .sockaddr_len = sizeof(struct sockaddr_in6), -+#ifdef CONFIG_COMPAT -+ .compat_setsockopt = compat_ipv6_setsockopt, -+ .compat_getsockopt = compat_ipv6_getsockopt, -+#endif -+ .mtu_reduced = tcp_v4_mtu_reduced, -+}; -+ -+struct tcp_request_sock_ops mptcp_request_sock_ipv6_ops; -+struct tcp_request_sock_ops mptcp_join_request_sock_ipv6_ops; -+ -+int mptcp_pm_v6_init(void) -+{ -+ int ret = 0; -+ struct request_sock_ops *ops = &mptcp6_request_sock_ops; -+ -+ mptcp_request_sock_ipv6_ops = tcp_request_sock_ipv6_ops; -+ mptcp_request_sock_ipv6_ops.init_req = mptcp_v6_init_req; -+#ifdef CONFIG_SYN_COOKIES -+ mptcp_request_sock_ipv6_ops.cookie_init_seq = mptcp_v6_cookie_init_seq; -+#endif -+ -+ mptcp_join_request_sock_ipv6_ops = tcp_request_sock_ipv6_ops; -+ mptcp_join_request_sock_ipv6_ops.init_req = mptcp_v6_join_init_req; -+ -+ ops->slab_name = kasprintf(GFP_KERNEL, "request_sock_%s", "MPTCP6"); -+ if (ops->slab_name == NULL) { -+ ret = -ENOMEM; -+ goto out; -+ } -+ -+ ops->slab = kmem_cache_create(ops->slab_name, ops->obj_size, 0, -+ SLAB_TYPESAFE_BY_RCU|SLAB_HWCACHE_ALIGN, -+ NULL); -+ -+ if (ops->slab == NULL) { -+ ret = -ENOMEM; -+ goto err_reqsk_create; -+ } -+ -+out: -+ return ret; -+ -+err_reqsk_create: -+ kfree(ops->slab_name); -+ ops->slab_name = NULL; -+ goto out; -+} -+ -+void mptcp_pm_v6_undo(void) -+{ -+ kmem_cache_destroy(mptcp6_request_sock_ops.slab); -+ kfree(mptcp6_request_sock_ops.slab_name); -+} -diff -aurN linux-4.14.174/net/mptcp/mptcp_ndiffports.c mptcp-mptcp_v0.94/net/mptcp/mptcp_ndiffports.c ---- linux-4.14.174/net/mptcp/mptcp_ndiffports.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_v0.94/net/mptcp/mptcp_ndiffports.c 2020-03-23 09:45:33.000000000 +0100 -@@ -0,0 +1,173 @@ -+#include -+ -+#include -+#include -+ -+#if IS_ENABLED(CONFIG_IPV6) -+#include -+#endif -+ -+struct ndiffports_priv { -+ /* Worker struct for subflow establishment */ -+ struct work_struct subflow_work; -+ -+ struct mptcp_cb *mpcb; -+}; -+ -+static int num_subflows __read_mostly = 2; -+module_param(num_subflows, int, 0644); -+MODULE_PARM_DESC(num_subflows, "choose the number of subflows per MPTCP connection"); -+ -+/** -+ * Create all new subflows, by doing calls to mptcp_initX_subsockets -+ * -+ * This function uses a goto next_subflow, to allow releasing the lock between -+ * new subflows and giving other processes a chance to do some work on the -+ * socket and potentially finishing the communication. -+ **/ -+static void create_subflow_worker(struct work_struct *work) -+{ -+ const struct ndiffports_priv *pm_priv = container_of(work, -+ struct ndiffports_priv, -+ subflow_work); -+ struct mptcp_cb *mpcb = pm_priv->mpcb; -+ struct sock *meta_sk = mpcb->meta_sk; -+ int iter = 0; -+ -+next_subflow: -+ if (iter) { -+ release_sock(meta_sk); -+ mutex_unlock(&mpcb->mpcb_mutex); -+ -+ cond_resched(); -+ } -+ mutex_lock(&mpcb->mpcb_mutex); -+ lock_sock_nested(meta_sk, SINGLE_DEPTH_NESTING); -+ -+ if (!mptcp(tcp_sk(meta_sk))) -+ goto exit; -+ -+ iter++; -+ -+ if (sock_flag(meta_sk, SOCK_DEAD)) -+ goto exit; -+ -+ if (mpcb->master_sk && -+ !tcp_sk(mpcb->master_sk)->mptcp->fully_established) -+ goto exit; -+ -+ if (num_subflows > iter && num_subflows > mpcb->cnt_subflows) { -+ if (meta_sk->sk_family == AF_INET || -+ mptcp_v6_is_v4_mapped(meta_sk)) { -+ struct mptcp_loc4 loc; -+ struct mptcp_rem4 rem; -+ -+ loc.addr.s_addr = inet_sk(meta_sk)->inet_saddr; -+ loc.loc4_id = 0; -+ loc.low_prio = 0; -+ if (mpcb->master_sk) -+ loc.if_idx = mpcb->master_sk->sk_bound_dev_if; -+ else -+ loc.if_idx = 0; -+ -+ rem.addr.s_addr = inet_sk(meta_sk)->inet_daddr; -+ rem.port = inet_sk(meta_sk)->inet_dport; -+ rem.rem4_id = 0; /* Default 0 */ -+ -+ mptcp_init4_subsockets(meta_sk, &loc, &rem); -+ } else { -+#if IS_ENABLED(CONFIG_IPV6) -+ struct mptcp_loc6 loc; -+ struct mptcp_rem6 rem; -+ -+ loc.addr = inet6_sk(meta_sk)->saddr; -+ loc.loc6_id = 0; -+ loc.low_prio = 0; -+ if (mpcb->master_sk) -+ loc.if_idx = mpcb->master_sk->sk_bound_dev_if; -+ else -+ loc.if_idx = 0; -+ -+ rem.addr = meta_sk->sk_v6_daddr; -+ rem.port = inet_sk(meta_sk)->inet_dport; -+ rem.rem6_id = 0; /* Default 0 */ -+ -+ mptcp_init6_subsockets(meta_sk, &loc, &rem); -+#endif -+ } -+ goto next_subflow; -+ } -+ -+exit: -+ release_sock(meta_sk); -+ mutex_unlock(&mpcb->mpcb_mutex); -+ mptcp_mpcb_put(mpcb); -+ sock_put(meta_sk); -+} -+ -+static void ndiffports_new_session(const struct sock *meta_sk) -+{ -+ struct mptcp_cb *mpcb = tcp_sk(meta_sk)->mpcb; -+ struct ndiffports_priv *fmp = (struct ndiffports_priv *)&mpcb->mptcp_pm[0]; -+ -+ /* Initialize workqueue-struct */ -+ INIT_WORK(&fmp->subflow_work, create_subflow_worker); -+ fmp->mpcb = mpcb; -+} -+ -+static void ndiffports_create_subflows(struct sock *meta_sk) -+{ -+ struct mptcp_cb *mpcb = tcp_sk(meta_sk)->mpcb; -+ struct ndiffports_priv *pm_priv = (struct ndiffports_priv *)&mpcb->mptcp_pm[0]; -+ -+ if (mptcp_in_infinite_mapping_weak(mpcb) || -+ mpcb->server_side || sock_flag(meta_sk, SOCK_DEAD)) -+ return; -+ -+ if (!work_pending(&pm_priv->subflow_work)) { -+ sock_hold(meta_sk); -+ atomic_inc(&mpcb->mpcb_refcnt); -+ queue_work(mptcp_wq, &pm_priv->subflow_work); -+ } -+} -+ -+static int ndiffports_get_local_id(sa_family_t family, union inet_addr *addr, -+ struct net *net, bool *low_prio) -+{ -+ return 0; -+} -+ -+static struct mptcp_pm_ops ndiffports __read_mostly = { -+ .new_session = ndiffports_new_session, -+ .fully_established = ndiffports_create_subflows, -+ .get_local_id = ndiffports_get_local_id, -+ .name = "ndiffports", -+ .owner = THIS_MODULE, -+}; -+ -+/* General initialization of MPTCP_PM */ -+static int __init ndiffports_register(void) -+{ -+ BUILD_BUG_ON(sizeof(struct ndiffports_priv) > MPTCP_PM_SIZE); -+ -+ if (mptcp_register_path_manager(&ndiffports)) -+ goto exit; -+ -+ return 0; -+ -+exit: -+ return -1; -+} -+ -+static void ndiffports_unregister(void) -+{ -+ mptcp_unregister_path_manager(&ndiffports); -+} -+ -+module_init(ndiffports_register); -+module_exit(ndiffports_unregister); -+ -+MODULE_AUTHOR("Christoph Paasch"); -+MODULE_LICENSE("GPL"); -+MODULE_DESCRIPTION("NDIFF-PORTS MPTCP"); -+MODULE_VERSION("0.88"); -diff -aurN linux-4.14.174/net/mptcp/mptcp_olia.c mptcp-mptcp_v0.94/net/mptcp/mptcp_olia.c ---- linux-4.14.174/net/mptcp/mptcp_olia.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_v0.94/net/mptcp/mptcp_olia.c 2020-03-23 09:45:33.000000000 +0100 -@@ -0,0 +1,310 @@ -+/* -+ * MPTCP implementation - OPPORTUNISTIC LINKED INCREASES CONGESTION CONTROL: -+ * -+ * Algorithm design: -+ * Ramin Khalili -+ * Nicolas Gast -+ * Jean-Yves Le Boudec -+ * -+ * Implementation: -+ * Ramin Khalili -+ * -+ * Ported to the official MPTCP-kernel: -+ * Christoph Paasch -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version -+ * 2 of the License, or (at your option) any later version. -+ */ -+ -+ -+#include -+#include -+ -+#include -+ -+static int scale = 10; -+ -+struct mptcp_olia { -+ u32 mptcp_loss1; -+ u32 mptcp_loss2; -+ u32 mptcp_loss3; -+ int epsilon_num; -+ u32 epsilon_den; -+ int mptcp_snd_cwnd_cnt; -+}; -+ -+static inline int mptcp_olia_sk_can_send(const struct sock *sk) -+{ -+ return mptcp_sk_can_send(sk) && tcp_sk(sk)->srtt_us; -+} -+ -+static inline u64 mptcp_olia_scale(u64 val, int scale) -+{ -+ return (u64) val << scale; -+} -+ -+/* take care of artificially inflate (see RFC5681) -+ * of cwnd during fast-retransmit phase -+ */ -+static u32 mptcp_get_crt_cwnd(struct sock *sk) -+{ -+ const struct inet_connection_sock *icsk = inet_csk(sk); -+ -+ if (icsk->icsk_ca_state == TCP_CA_Recovery) -+ return tcp_sk(sk)->snd_ssthresh; -+ else -+ return tcp_sk(sk)->snd_cwnd; -+} -+ -+/* return the dominator of the first term of the increasing term */ -+static u64 mptcp_get_rate(const struct mptcp_cb *mpcb , u32 path_rtt) -+{ -+ struct sock *sk; -+ u64 rate = 1; /* We have to avoid a zero-rate because it is used as a divisor */ -+ -+ mptcp_for_each_sk(mpcb, sk) { -+ struct tcp_sock *tp = tcp_sk(sk); -+ u64 scaled_num; -+ u32 tmp_cwnd; -+ -+ if (!mptcp_olia_sk_can_send(sk)) -+ continue; -+ -+ tmp_cwnd = mptcp_get_crt_cwnd(sk); -+ scaled_num = mptcp_olia_scale(tmp_cwnd, scale) * path_rtt; -+ rate += div_u64(scaled_num , tp->srtt_us); -+ } -+ rate *= rate; -+ return rate; -+} -+ -+/* find the maximum cwnd, used to find set M */ -+static u32 mptcp_get_max_cwnd(const struct mptcp_cb *mpcb) -+{ -+ struct sock *sk; -+ u32 best_cwnd = 0; -+ -+ mptcp_for_each_sk(mpcb, sk) { -+ u32 tmp_cwnd; -+ -+ if (!mptcp_olia_sk_can_send(sk)) -+ continue; -+ -+ tmp_cwnd = mptcp_get_crt_cwnd(sk); -+ if (tmp_cwnd > best_cwnd) -+ best_cwnd = tmp_cwnd; -+ } -+ return best_cwnd; -+} -+ -+static void mptcp_get_epsilon(const struct mptcp_cb *mpcb) -+{ -+ struct mptcp_olia *ca; -+ struct tcp_sock *tp; -+ struct sock *sk; -+ u64 tmp_int, tmp_rtt, best_int = 0, best_rtt = 1; -+ u32 max_cwnd, tmp_cwnd; -+ u8 M = 0, B_not_M = 0; -+ -+ /* TODO - integrate this in the following loop - we just want to iterate once */ -+ -+ max_cwnd = mptcp_get_max_cwnd(mpcb); -+ -+ /* find the best path */ -+ mptcp_for_each_sk(mpcb, sk) { -+ tp = tcp_sk(sk); -+ ca = inet_csk_ca(sk); -+ -+ if (!mptcp_olia_sk_can_send(sk)) -+ continue; -+ -+ tmp_rtt = (u64)tp->srtt_us * tp->srtt_us; -+ /* TODO - check here and rename variables */ -+ tmp_int = max(ca->mptcp_loss3 - ca->mptcp_loss2, -+ ca->mptcp_loss2 - ca->mptcp_loss1); -+ -+ if ((u64)tmp_int * best_rtt >= (u64)best_int * tmp_rtt) { -+ best_rtt = tmp_rtt; -+ best_int = tmp_int; -+ } -+ } -+ -+ /* TODO - integrate this here in mptcp_get_max_cwnd and in the previous loop */ -+ /* find the size of M and B_not_M */ -+ mptcp_for_each_sk(mpcb, sk) { -+ tp = tcp_sk(sk); -+ ca = inet_csk_ca(sk); -+ -+ if (!mptcp_olia_sk_can_send(sk)) -+ continue; -+ -+ tmp_cwnd = mptcp_get_crt_cwnd(sk); -+ if (tmp_cwnd == max_cwnd) { -+ M++; -+ } else { -+ tmp_rtt = (u64)tp->srtt_us * tp->srtt_us; -+ tmp_int = max(ca->mptcp_loss3 - ca->mptcp_loss2, -+ ca->mptcp_loss2 - ca->mptcp_loss1); -+ -+ if ((u64)tmp_int * best_rtt == (u64)best_int * tmp_rtt) -+ B_not_M++; -+ } -+ } -+ -+ /* check if the path is in M or B_not_M and set the value of epsilon accordingly */ -+ mptcp_for_each_sk(mpcb, sk) { -+ tp = tcp_sk(sk); -+ ca = inet_csk_ca(sk); -+ -+ if (!mptcp_olia_sk_can_send(sk)) -+ continue; -+ -+ if (B_not_M == 0) { -+ ca->epsilon_num = 0; -+ ca->epsilon_den = 1; -+ } else { -+ tmp_rtt = (u64)tp->srtt_us * tp->srtt_us; -+ tmp_int = max(ca->mptcp_loss3 - ca->mptcp_loss2, -+ ca->mptcp_loss2 - ca->mptcp_loss1); -+ tmp_cwnd = mptcp_get_crt_cwnd(sk); -+ -+ if (tmp_cwnd < max_cwnd && -+ (u64)tmp_int * best_rtt == (u64)best_int * tmp_rtt) { -+ ca->epsilon_num = 1; -+ ca->epsilon_den = mpcb->cnt_established * B_not_M; -+ } else if (tmp_cwnd == max_cwnd) { -+ ca->epsilon_num = -1; -+ ca->epsilon_den = mpcb->cnt_established * M; -+ } else { -+ ca->epsilon_num = 0; -+ ca->epsilon_den = 1; -+ } -+ } -+ } -+} -+ -+/* setting the initial values */ -+static void mptcp_olia_init(struct sock *sk) -+{ -+ const struct tcp_sock *tp = tcp_sk(sk); -+ struct mptcp_olia *ca = inet_csk_ca(sk); -+ -+ if (mptcp(tp)) { -+ ca->mptcp_loss1 = tp->snd_una; -+ ca->mptcp_loss2 = tp->snd_una; -+ ca->mptcp_loss3 = tp->snd_una; -+ ca->mptcp_snd_cwnd_cnt = 0; -+ ca->epsilon_num = 0; -+ ca->epsilon_den = 1; -+ } -+} -+ -+/* updating inter-loss distance and ssthresh */ -+static void mptcp_olia_set_state(struct sock *sk, u8 new_state) -+{ -+ if (!mptcp(tcp_sk(sk))) -+ return; -+ -+ if (new_state == TCP_CA_Loss || -+ new_state == TCP_CA_Recovery || new_state == TCP_CA_CWR) { -+ struct mptcp_olia *ca = inet_csk_ca(sk); -+ -+ if (ca->mptcp_loss3 != ca->mptcp_loss2 && -+ !inet_csk(sk)->icsk_retransmits) { -+ ca->mptcp_loss1 = ca->mptcp_loss2; -+ ca->mptcp_loss2 = ca->mptcp_loss3; -+ } -+ } -+} -+ -+/* main algorithm */ -+static void mptcp_olia_cong_avoid(struct sock *sk, u32 ack, u32 acked) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct mptcp_olia *ca = inet_csk_ca(sk); -+ const struct mptcp_cb *mpcb = tp->mpcb; -+ -+ u64 inc_num, inc_den, rate, cwnd_scaled; -+ -+ if (!mptcp(tp)) { -+ tcp_reno_cong_avoid(sk, ack, acked); -+ return; -+ } -+ -+ ca->mptcp_loss3 = tp->snd_una; -+ -+ if (!tcp_is_cwnd_limited(sk)) -+ return; -+ -+ /* slow start if it is in the safe area */ -+ if (tcp_in_slow_start(tp)) { -+ tcp_slow_start(tp, acked); -+ return; -+ } -+ -+ mptcp_get_epsilon(mpcb); -+ rate = mptcp_get_rate(mpcb, tp->srtt_us); -+ cwnd_scaled = mptcp_olia_scale(tp->snd_cwnd, scale); -+ inc_den = ca->epsilon_den * tp->snd_cwnd * rate ? : 1; -+ -+ /* calculate the increasing term, scaling is used to reduce the rounding effect */ -+ if (ca->epsilon_num == -1) { -+ if (ca->epsilon_den * cwnd_scaled * cwnd_scaled < rate) { -+ inc_num = rate - ca->epsilon_den * -+ cwnd_scaled * cwnd_scaled; -+ ca->mptcp_snd_cwnd_cnt -= div64_u64( -+ mptcp_olia_scale(inc_num , scale) , inc_den); -+ } else { -+ inc_num = ca->epsilon_den * -+ cwnd_scaled * cwnd_scaled - rate; -+ ca->mptcp_snd_cwnd_cnt += div64_u64( -+ mptcp_olia_scale(inc_num , scale) , inc_den); -+ } -+ } else { -+ inc_num = ca->epsilon_num * rate + -+ ca->epsilon_den * cwnd_scaled * cwnd_scaled; -+ ca->mptcp_snd_cwnd_cnt += div64_u64( -+ mptcp_olia_scale(inc_num , scale) , inc_den); -+ } -+ -+ -+ if (ca->mptcp_snd_cwnd_cnt >= (1 << scale) - 1) { -+ if (tp->snd_cwnd < tp->snd_cwnd_clamp) -+ tp->snd_cwnd++; -+ ca->mptcp_snd_cwnd_cnt = 0; -+ } else if (ca->mptcp_snd_cwnd_cnt <= 0 - (1 << scale) + 1) { -+ tp->snd_cwnd = max((int) 1 , (int) tp->snd_cwnd - 1); -+ ca->mptcp_snd_cwnd_cnt = 0; -+ } -+} -+ -+static struct tcp_congestion_ops mptcp_olia = { -+ .init = mptcp_olia_init, -+ .ssthresh = tcp_reno_ssthresh, -+ .cong_avoid = mptcp_olia_cong_avoid, -+ .undo_cwnd = tcp_reno_undo_cwnd, -+ .set_state = mptcp_olia_set_state, -+ .owner = THIS_MODULE, -+ .name = "olia", -+}; -+ -+static int __init mptcp_olia_register(void) -+{ -+ BUILD_BUG_ON(sizeof(struct mptcp_olia) > ICSK_CA_PRIV_SIZE); -+ return tcp_register_congestion_control(&mptcp_olia); -+} -+ -+static void __exit mptcp_olia_unregister(void) -+{ -+ tcp_unregister_congestion_control(&mptcp_olia); -+} -+ -+module_init(mptcp_olia_register); -+module_exit(mptcp_olia_unregister); -+ -+MODULE_AUTHOR("Ramin Khalili, Nicolas Gast, Jean-Yves Le Boudec"); -+MODULE_LICENSE("GPL"); -+MODULE_DESCRIPTION("MPTCP COUPLED CONGESTION CONTROL"); -+MODULE_VERSION("0.1"); -diff -aurN linux-4.14.174/net/mptcp/mptcp_output.c mptcp-mptcp_v0.94/net/mptcp/mptcp_output.c ---- linux-4.14.174/net/mptcp/mptcp_output.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_v0.94/net/mptcp/mptcp_output.c 2020-03-23 09:45:33.000000000 +0100 -@@ -0,0 +1,1824 @@ -+/* -+ * MPTCP implementation - Sending side -+ * -+ * Initial Design & Implementation: -+ * Sébastien Barré -+ * -+ * Current Maintainer & Author: -+ * Christoph Paasch -+ * -+ * Additional authors: -+ * Jaakko Korkeaniemi -+ * Gregory Detal -+ * Fabien Duchêne -+ * Andreas Seelinger -+ * Lavkesh Lahngir -+ * Andreas Ripke -+ * Vlad Dogaru -+ * Octavian Purdila -+ * John Ronan -+ * Catalin Nicutar -+ * Brandon Heller -+ * -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version -+ * 2 of the License, or (at your option) any later version. -+ */ -+ -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+ -+static const int mptcp_dss_len = MPTCP_SUB_LEN_DSS_ALIGN + -+ MPTCP_SUB_LEN_ACK_ALIGN + -+ MPTCP_SUB_LEN_SEQ_ALIGN; -+ -+static inline int mptcp_sub_len_remove_addr(u16 bitfield) -+{ -+ unsigned int c; -+ for (c = 0; bitfield; c++) -+ bitfield &= bitfield - 1; -+ return MPTCP_SUB_LEN_REMOVE_ADDR + c - 1; -+} -+ -+int mptcp_sub_len_remove_addr_align(u16 bitfield) -+{ -+ return ALIGN(mptcp_sub_len_remove_addr(bitfield), 4); -+} -+EXPORT_SYMBOL(mptcp_sub_len_remove_addr_align); -+ -+/* get the data-seq and end-data-seq and store them again in the -+ * tcp_skb_cb -+ */ -+static bool mptcp_reconstruct_mapping(struct sk_buff *skb) -+{ -+ const struct mp_dss *mpdss = (struct mp_dss *)TCP_SKB_CB(skb)->dss; -+ u32 *p32; -+ u16 *p16; -+ -+ if (!mptcp_is_data_seq(skb)) -+ return false; -+ -+ if (!mpdss->M) -+ return false; -+ -+ /* Move the pointer to the data-seq */ -+ p32 = (u32 *)mpdss; -+ p32++; -+ if (mpdss->A) { -+ p32++; -+ if (mpdss->a) -+ p32++; -+ } -+ -+ TCP_SKB_CB(skb)->seq = ntohl(*p32); -+ -+ /* Get the data_len to calculate the end_data_seq */ -+ p32++; -+ p32++; -+ p16 = (u16 *)p32; -+ TCP_SKB_CB(skb)->end_seq = ntohs(*p16) + TCP_SKB_CB(skb)->seq; -+ -+ return true; -+} -+ -+static bool mptcp_is_reinjected(const struct sk_buff *skb) -+{ -+ return TCP_SKB_CB(skb)->mptcp_flags & MPTCP_REINJECT; -+} -+ -+static void mptcp_find_and_set_pathmask(const struct sock *meta_sk, struct sk_buff *skb) -+{ -+ struct sk_buff *skb_it; -+ -+ skb_it = tcp_write_queue_head(meta_sk); -+ -+ tcp_for_write_queue_from(skb_it, meta_sk) { -+ if (skb_it == tcp_send_head(meta_sk)) -+ break; -+ -+ if (TCP_SKB_CB(skb_it)->seq == TCP_SKB_CB(skb)->seq) { -+ TCP_SKB_CB(skb)->path_mask = TCP_SKB_CB(skb_it)->path_mask; -+ break; -+ } -+ } -+} -+ -+/* Reinject data from one TCP subflow to the meta_sk. If sk == NULL, we are -+ * coming from the meta-retransmit-timer -+ */ -+static void __mptcp_reinject_data(struct sk_buff *orig_skb, struct sock *meta_sk, -+ struct sock *sk, int clone_it) -+{ -+ struct sk_buff *skb, *skb1; -+ const struct tcp_sock *meta_tp = tcp_sk(meta_sk); -+ struct mptcp_cb *mpcb = meta_tp->mpcb; -+ u32 seq, end_seq; -+ -+ if (clone_it) { -+ /* pskb_copy is necessary here, because the TCP/IP-headers -+ * will be changed when it's going to be reinjected on another -+ * subflow. -+ */ -+ skb = pskb_copy_for_clone(orig_skb, GFP_ATOMIC); -+ } else { -+ __skb_unlink(orig_skb, &sk->sk_write_queue); -+ sock_set_flag(sk, SOCK_QUEUE_SHRUNK); -+ sk->sk_wmem_queued -= orig_skb->truesize; -+ sk_mem_uncharge(sk, orig_skb->truesize); -+ skb = orig_skb; -+ } -+ if (unlikely(!skb)) -+ return; -+ -+ if (sk && !mptcp_reconstruct_mapping(skb)) { -+ __kfree_skb(skb); -+ return; -+ } -+ -+ skb->sk = meta_sk; -+ -+ /* Reset subflow-specific TCP control-data */ -+ TCP_SKB_CB(skb)->sacked = 0; -+ TCP_SKB_CB(skb)->tcp_flags &= (TCPHDR_ACK | TCPHDR_PSH); -+ -+ /* If it reached already the destination, we don't have to reinject it */ -+ if (!after(TCP_SKB_CB(skb)->end_seq, meta_tp->snd_una)) { -+ __kfree_skb(skb); -+ return; -+ } -+ -+ /* Only reinject segments that are fully covered by the mapping */ -+ if (skb->len + (mptcp_is_data_fin(skb) ? 1 : 0) != -+ TCP_SKB_CB(skb)->end_seq - TCP_SKB_CB(skb)->seq) { -+ u32 seq = TCP_SKB_CB(skb)->seq; -+ u32 end_seq = TCP_SKB_CB(skb)->end_seq; -+ -+ __kfree_skb(skb); -+ -+ /* Ok, now we have to look for the full mapping in the meta -+ * send-queue :S -+ */ -+ tcp_for_write_queue(skb, meta_sk) { -+ /* Not yet at the mapping? */ -+ if (before(TCP_SKB_CB(skb)->seq, seq)) -+ continue; -+ /* We have passed by the mapping */ -+ if (after(TCP_SKB_CB(skb)->end_seq, end_seq)) -+ return; -+ -+ __mptcp_reinject_data(skb, meta_sk, NULL, 1); -+ } -+ return; -+ } -+ -+ /* Segment goes back to the MPTCP-layer. So, we need to zero the -+ * path_mask/dss. -+ */ -+ memset(TCP_SKB_CB(skb)->dss, 0 , mptcp_dss_len); -+ -+ /* We need to find out the path-mask from the meta-write-queue -+ * to properly select a subflow. -+ */ -+ mptcp_find_and_set_pathmask(meta_sk, skb); -+ -+ /* If it's empty, just add */ -+ if (skb_queue_empty(&mpcb->reinject_queue)) { -+ skb_queue_head(&mpcb->reinject_queue, skb); -+ return; -+ } -+ -+ /* Find place to insert skb - or even we can 'drop' it, as the -+ * data is already covered by other skb's in the reinject-queue. -+ * -+ * This is inspired by code from tcp_data_queue. -+ */ -+ -+ skb1 = skb_peek_tail(&mpcb->reinject_queue); -+ seq = TCP_SKB_CB(skb)->seq; -+ while (1) { -+ if (!after(TCP_SKB_CB(skb1)->seq, seq)) -+ break; -+ if (skb_queue_is_first(&mpcb->reinject_queue, skb1)) { -+ skb1 = NULL; -+ break; -+ } -+ skb1 = skb_queue_prev(&mpcb->reinject_queue, skb1); -+ } -+ -+ /* Do skb overlap to previous one? */ -+ end_seq = TCP_SKB_CB(skb)->end_seq; -+ if (skb1 && before(seq, TCP_SKB_CB(skb1)->end_seq)) { -+ if (!after(end_seq, TCP_SKB_CB(skb1)->end_seq)) { -+ /* All the bits are present. Don't reinject */ -+ __kfree_skb(skb); -+ return; -+ } -+ if (seq == TCP_SKB_CB(skb1)->seq) { -+ if (skb_queue_is_first(&mpcb->reinject_queue, skb1)) -+ skb1 = NULL; -+ else -+ skb1 = skb_queue_prev(&mpcb->reinject_queue, skb1); -+ } -+ } -+ if (!skb1) -+ __skb_queue_head(&mpcb->reinject_queue, skb); -+ else -+ __skb_queue_after(&mpcb->reinject_queue, skb1, skb); -+ -+ /* And clean segments covered by new one as whole. */ -+ while (!skb_queue_is_last(&mpcb->reinject_queue, skb)) { -+ skb1 = skb_queue_next(&mpcb->reinject_queue, skb); -+ -+ if (!after(end_seq, TCP_SKB_CB(skb1)->seq)) -+ break; -+ -+ if (before(end_seq, TCP_SKB_CB(skb1)->end_seq)) -+ break; -+ -+ __skb_unlink(skb1, &mpcb->reinject_queue); -+ __kfree_skb(skb1); -+ } -+ return; -+} -+ -+/* Inserts data into the reinject queue */ -+void mptcp_reinject_data(struct sock *sk, int clone_it) -+{ -+ struct sk_buff *skb_it, *tmp; -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct sock *meta_sk = tp->meta_sk; -+ -+ /* It has already been closed - there is really no point in reinjecting */ -+ if (meta_sk->sk_state == TCP_CLOSE) -+ return; -+ -+ skb_queue_walk_safe(&sk->sk_write_queue, skb_it, tmp) { -+ struct tcp_skb_cb *tcb = TCP_SKB_CB(skb_it); -+ /* Subflow syn's and fin's are not reinjected. -+ * -+ * As well as empty subflow-fins with a data-fin. -+ * They are reinjected below (without the subflow-fin-flag) -+ */ -+ if (tcb->tcp_flags & TCPHDR_SYN || -+ (tcb->tcp_flags & TCPHDR_FIN && !mptcp_is_data_fin(skb_it)) || -+ (tcb->tcp_flags & TCPHDR_FIN && mptcp_is_data_fin(skb_it) && !skb_it->len)) -+ continue; -+ -+ if (mptcp_is_reinjected(skb_it)) -+ continue; -+ -+ tcb->mptcp_flags |= MPTCP_REINJECT; -+ __mptcp_reinject_data(skb_it, meta_sk, sk, clone_it); -+ } -+ -+ skb_it = tcp_write_queue_tail(meta_sk); -+ /* If sk has sent the empty data-fin, we have to reinject it too. */ -+ if (skb_it && mptcp_is_data_fin(skb_it) && skb_it->len == 0 && -+ TCP_SKB_CB(skb_it)->path_mask & mptcp_pi_to_flag(tp->mptcp->path_index)) { -+ __mptcp_reinject_data(skb_it, meta_sk, NULL, 1); -+ } -+ -+ tp->pf = 1; -+ -+ mptcp_push_pending_frames(meta_sk); -+} -+EXPORT_SYMBOL(mptcp_reinject_data); -+ -+static void mptcp_combine_dfin(const struct sk_buff *skb, -+ const struct sock *meta_sk, -+ struct sock *subsk) -+{ -+ const struct tcp_sock *meta_tp = tcp_sk(meta_sk); -+ const struct mptcp_cb *mpcb = meta_tp->mpcb; -+ -+ /* In infinite mapping we always try to combine */ -+ if (mpcb->infinite_mapping_snd) -+ goto combine; -+ -+ /* Don't combine, if they didn't combine when closing - otherwise we end -+ * up in TIME_WAIT, even if our app is smart enough to avoid it. -+ */ -+ if (!mptcp_sk_can_recv(meta_sk) && !mpcb->dfin_combined) -+ return; -+ -+ /* Don't combine if there is still outstanding data that remains to be -+ * DATA_ACKed, because otherwise we may never be able to deliver this. -+ */ -+ if (meta_tp->snd_una != TCP_SKB_CB(skb)->seq) -+ return; -+ -+combine: -+ if (tcp_close_state(subsk)) { -+ subsk->sk_shutdown |= SEND_SHUTDOWN; -+ TCP_SKB_CB(skb)->tcp_flags |= TCPHDR_FIN; -+ } -+} -+ -+static int mptcp_write_dss_mapping(const struct tcp_sock *tp, const struct sk_buff *skb, -+ __be32 *ptr) -+{ -+ const struct tcp_skb_cb *tcb = TCP_SKB_CB(skb); -+ __be32 *start = ptr; -+ __u16 data_len; -+ -+ *ptr++ = htonl(tcb->seq); /* data_seq */ -+ -+ /* If it's a non-data DATA_FIN, we set subseq to 0 (draft v7) */ -+ if (mptcp_is_data_fin(skb) && skb->len == 0) -+ *ptr++ = 0; /* subseq */ -+ else -+ *ptr++ = htonl(tp->write_seq - tp->mptcp->snt_isn); /* subseq */ -+ -+ if (tcb->mptcp_flags & MPTCPHDR_INF) -+ data_len = 0; -+ else -+ data_len = tcb->end_seq - tcb->seq; -+ -+ if (tp->mpcb->dss_csum && data_len) { -+ __be16 *p16 = (__be16 *)ptr; -+ __be32 hdseq = mptcp_get_highorder_sndbits(skb, tp->mpcb); -+ __wsum csum; -+ -+ *ptr = htonl(((data_len) << 16) | -+ (TCPOPT_EOL << 8) | -+ (TCPOPT_EOL)); -+ csum = csum_partial(ptr - 2, 12, skb->csum); -+ p16++; -+ *p16++ = csum_fold(csum_partial(&hdseq, sizeof(hdseq), csum)); -+ } else { -+ *ptr++ = htonl(((data_len) << 16) | -+ (TCPOPT_NOP << 8) | -+ (TCPOPT_NOP)); -+ } -+ -+ return ptr - start; -+} -+ -+static int mptcp_write_dss_data_ack(const struct tcp_sock *tp, const struct sk_buff *skb, -+ __be32 *ptr) -+{ -+ struct mp_dss *mdss = (struct mp_dss *)ptr; -+ __be32 *start = ptr; -+ -+ mdss->kind = TCPOPT_MPTCP; -+ mdss->sub = MPTCP_SUB_DSS; -+ mdss->rsv1 = 0; -+ mdss->rsv2 = 0; -+ mdss->F = mptcp_is_data_fin(skb) ? 1 : 0; -+ mdss->m = 0; -+ mdss->M = mptcp_is_data_seq(skb) ? 1 : 0; -+ mdss->a = 0; -+ mdss->A = 1; -+ mdss->len = mptcp_sub_len_dss(mdss, tp->mpcb->dss_csum); -+ ptr++; -+ -+ *ptr++ = htonl(mptcp_meta_tp(tp)->rcv_nxt); -+ -+ return ptr - start; -+} -+ -+/* RFC6824 states that once a particular subflow mapping has been sent -+ * out it must never be changed. However, packets may be split while -+ * they are in the retransmission queue (due to SACK or ACKs) and that -+ * arguably means that we would change the mapping (e.g. it splits it, -+ * our sends out a subset of the initial mapping). -+ * -+ * Furthermore, the skb checksum is not always preserved across splits -+ * (e.g. mptcp_fragment) which would mean that we need to recompute -+ * the DSS checksum in this case. -+ * -+ * To avoid this we save the initial DSS mapping which allows us to -+ * send the same DSS mapping even for fragmented retransmits. -+ */ -+static void mptcp_save_dss_data_seq(const struct tcp_sock *tp, struct sk_buff *skb) -+{ -+ struct tcp_skb_cb *tcb = TCP_SKB_CB(skb); -+ __be32 *ptr = (__be32 *)tcb->dss; -+ -+ tcb->mptcp_flags |= MPTCPHDR_SEQ; -+ -+ ptr += mptcp_write_dss_data_ack(tp, skb, ptr); -+ ptr += mptcp_write_dss_mapping(tp, skb, ptr); -+} -+ -+/* Write the saved DSS mapping to the header */ -+static int mptcp_write_dss_data_seq(const struct tcp_sock *tp, struct sk_buff *skb, -+ __be32 *ptr) -+{ -+ __be32 *start = ptr; -+ -+ memcpy(ptr, TCP_SKB_CB(skb)->dss, mptcp_dss_len); -+ -+ /* update the data_ack */ -+ start[1] = htonl(mptcp_meta_tp(tp)->rcv_nxt); -+ -+ /* dss is in a union with inet_skb_parm and -+ * the IP layer expects zeroed IPCB fields. -+ */ -+ memset(TCP_SKB_CB(skb)->dss, 0 , mptcp_dss_len); -+ -+ return mptcp_dss_len/sizeof(*ptr); -+} -+ -+static bool mptcp_skb_entail(struct sock *sk, struct sk_buff *skb, int reinject) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ const struct sock *meta_sk = mptcp_meta_sk(sk); -+ const struct mptcp_cb *mpcb = tp->mpcb; -+ struct tcp_skb_cb *tcb; -+ struct sk_buff *subskb = NULL; -+ -+ if (!reinject) -+ TCP_SKB_CB(skb)->mptcp_flags |= (mpcb->snd_hiseq_index ? -+ MPTCPHDR_SEQ64_INDEX : 0); -+ -+ subskb = pskb_copy_for_clone(skb, GFP_ATOMIC); -+ if (!subskb) -+ return false; -+ -+ /* At the subflow-level we need to call again tcp_init_tso_segs. We -+ * force this, by setting pcount to 0. It has been set to 1 prior to -+ * the call to mptcp_skb_entail. -+ */ -+ tcp_skb_pcount_set(subskb, 0); -+ -+ TCP_SKB_CB(skb)->path_mask |= mptcp_pi_to_flag(tp->mptcp->path_index); -+ -+ /* Compute checksum, if: -+ * 1. The current route does not support csum offloading but it was -+ * assumed that it does (ip_summed is CHECKSUM_PARTIAL) -+ * 2. We need the DSS-checksum but ended up not pre-computing it -+ * (e.g., in the case of TFO retransmissions). -+ */ -+ if (skb->ip_summed == CHECKSUM_PARTIAL && -+ (!sk_check_csum_caps(sk) || tp->mpcb->dss_csum)) { -+ subskb->csum = skb->csum = skb_checksum(skb, 0, skb->len, 0); -+ subskb->ip_summed = skb->ip_summed = CHECKSUM_NONE; -+ } -+ -+ tcb = TCP_SKB_CB(subskb); -+ -+ if (tp->mpcb->send_infinite_mapping && -+ !tp->mpcb->infinite_mapping_snd && -+ !before(tcb->seq, mptcp_meta_tp(tp)->snd_nxt)) { -+ tp->mptcp->fully_established = 1; -+ tp->mpcb->infinite_mapping_snd = 1; -+ tp->mptcp->infinite_cutoff_seq = tp->write_seq; -+ tcb->mptcp_flags |= MPTCPHDR_INF; -+ } -+ -+ if (mptcp_is_data_fin(subskb)) -+ mptcp_combine_dfin(subskb, meta_sk, sk); -+ -+ mptcp_save_dss_data_seq(tp, subskb); -+ -+ tcb->seq = tp->write_seq; -+ -+ /* Take into account seg len */ -+ tp->write_seq += subskb->len + ((tcb->tcp_flags & TCPHDR_FIN) ? 1 : 0); -+ tcb->end_seq = tp->write_seq; -+ -+ /* If it's a non-payload DATA_FIN (also no subflow-fin), the -+ * segment is not part of the subflow but on a meta-only-level. -+ */ -+ if (!mptcp_is_data_fin(subskb) || tcb->end_seq != tcb->seq) { -+ tcp_add_write_queue_tail(sk, subskb); -+ sk->sk_wmem_queued += subskb->truesize; -+ sk_mem_charge(sk, subskb->truesize); -+ } else { -+ int err; -+ -+ /* Necessary to initialize for tcp_transmit_skb. mss of 1, as -+ * skb->len = 0 will force tso_segs to 1. -+ */ -+ tcp_init_tso_segs(subskb, 1); -+ /* Empty data-fins are sent immediatly on the subflow */ -+ err = tcp_transmit_skb(sk, subskb, 1, GFP_ATOMIC); -+ -+ /* It has not been queued, we can free it now. */ -+ kfree_skb(subskb); -+ -+ if (err) -+ return false; -+ } -+ -+ if (!tp->mptcp->fully_established) { -+ tp->mptcp->second_packet = 1; -+ tp->mptcp->last_end_data_seq = TCP_SKB_CB(skb)->end_seq; -+ } -+ -+ return true; -+} -+ -+/* Fragment an skb and update the mptcp meta-data. Due to reinject, we -+ * might need to undo some operations done by tcp_fragment. -+ */ -+static int mptcp_fragment(struct sock *meta_sk, struct sk_buff *skb, u32 len, -+ gfp_t gfp, int reinject) -+{ -+ int ret, diff, old_factor; -+ struct sk_buff *buff; -+ u8 flags; -+ -+ if (skb_headlen(skb) < len) -+ diff = skb->len - len; -+ else -+ diff = skb->data_len; -+ old_factor = tcp_skb_pcount(skb); -+ -+ /* The mss_now in tcp_fragment is used to set the tso_segs of the skb. -+ * At the MPTCP-level we do not care about the absolute value. All we -+ * care about is that it is set to 1 for accurate packets_out -+ * accounting. -+ */ -+ ret = tcp_fragment(meta_sk, skb, len, UINT_MAX, gfp); -+ if (ret) -+ return ret; -+ -+ buff = skb->next; -+ -+ flags = TCP_SKB_CB(skb)->mptcp_flags; -+ TCP_SKB_CB(skb)->mptcp_flags = flags & ~(MPTCPHDR_FIN); -+ TCP_SKB_CB(buff)->mptcp_flags = flags; -+ TCP_SKB_CB(buff)->path_mask = TCP_SKB_CB(skb)->path_mask; -+ -+ /* If reinject == 1, the buff will be added to the reinject -+ * queue, which is currently not part of memory accounting. So -+ * undo the changes done by tcp_fragment and update the -+ * reinject queue. Also, undo changes to the packet counters. -+ */ -+ if (reinject == 1) { -+ int undo = buff->truesize - diff; -+ meta_sk->sk_wmem_queued -= undo; -+ sk_mem_uncharge(meta_sk, undo); -+ -+ tcp_sk(meta_sk)->mpcb->reinject_queue.qlen++; -+ meta_sk->sk_write_queue.qlen--; -+ -+ if (!before(tcp_sk(meta_sk)->snd_nxt, TCP_SKB_CB(buff)->end_seq)) { -+ undo = old_factor - tcp_skb_pcount(skb) - -+ tcp_skb_pcount(buff); -+ if (undo) -+ tcp_adjust_pcount(meta_sk, skb, -undo); -+ } -+ } -+ -+ return 0; -+} -+ -+/* Inspired by tcp_write_wakeup */ -+int mptcp_write_wakeup(struct sock *meta_sk, int mib) -+{ -+ struct tcp_sock *meta_tp = tcp_sk(meta_sk); -+ struct sk_buff *skb; -+ struct sock *sk_it; -+ int ans = 0; -+ -+ if (meta_sk->sk_state == TCP_CLOSE) -+ return -1; -+ -+ skb = tcp_send_head(meta_sk); -+ if (skb && -+ before(TCP_SKB_CB(skb)->seq, tcp_wnd_end(meta_tp))) { -+ unsigned int mss; -+ unsigned int seg_size = tcp_wnd_end(meta_tp) - TCP_SKB_CB(skb)->seq; -+ struct sock *subsk = meta_tp->mpcb->sched_ops->get_subflow(meta_sk, skb, true); -+ struct tcp_sock *subtp; -+ -+ WARN_ON(TCP_SKB_CB(skb)->sacked); -+ -+ if (!subsk) -+ goto window_probe; -+ subtp = tcp_sk(subsk); -+ mss = tcp_current_mss(subsk); -+ -+ seg_size = min(tcp_wnd_end(meta_tp) - TCP_SKB_CB(skb)->seq, -+ tcp_wnd_end(subtp) - subtp->write_seq); -+ -+ if (before(meta_tp->pushed_seq, TCP_SKB_CB(skb)->end_seq)) -+ meta_tp->pushed_seq = TCP_SKB_CB(skb)->end_seq; -+ -+ /* We are probing the opening of a window -+ * but the window size is != 0 -+ * must have been a result SWS avoidance ( sender ) -+ */ -+ if (seg_size < TCP_SKB_CB(skb)->end_seq - TCP_SKB_CB(skb)->seq || -+ skb->len > mss) { -+ seg_size = min(seg_size, mss); -+ TCP_SKB_CB(skb)->tcp_flags |= TCPHDR_PSH; -+ if (mptcp_fragment(meta_sk, skb, seg_size, -+ GFP_ATOMIC, 0)) -+ return -1; -+ } else if (!tcp_skb_pcount(skb)) { -+ /* see mptcp_write_xmit on why we use UINT_MAX */ -+ tcp_set_skb_tso_segs(skb, UINT_MAX); -+ } -+ -+ TCP_SKB_CB(skb)->tcp_flags |= TCPHDR_PSH; -+ if (!mptcp_skb_entail(subsk, skb, 0)) -+ return -1; -+ -+ mptcp_check_sndseq_wrap(meta_tp, TCP_SKB_CB(skb)->end_seq - -+ TCP_SKB_CB(skb)->seq); -+ tcp_event_new_data_sent(meta_sk, skb); -+ -+ __tcp_push_pending_frames(subsk, mss, TCP_NAGLE_PUSH); -+ skb->skb_mstamp = meta_tp->tcp_mstamp; -+ meta_tp->lsndtime = tcp_jiffies32; -+ -+ return 0; -+ } else { -+window_probe: -+ if (between(meta_tp->snd_up, meta_tp->snd_una + 1, -+ meta_tp->snd_una + 0xFFFF)) { -+ mptcp_for_each_sk(meta_tp->mpcb, sk_it) { -+ if (mptcp_sk_can_send_ack(sk_it)) -+ tcp_xmit_probe_skb(sk_it, 1, mib); -+ } -+ } -+ -+ /* At least one of the tcp_xmit_probe_skb's has to succeed */ -+ mptcp_for_each_sk(meta_tp->mpcb, sk_it) { -+ int ret; -+ -+ if (!mptcp_sk_can_send_ack(sk_it)) -+ continue; -+ -+ ret = tcp_xmit_probe_skb(sk_it, 0, mib); -+ if (unlikely(ret > 0)) -+ ans = ret; -+ } -+ return ans; -+ } -+} -+ -+bool mptcp_write_xmit(struct sock *meta_sk, unsigned int mss_now, int nonagle, -+ int push_one, gfp_t gfp) -+{ -+ struct tcp_sock *meta_tp = tcp_sk(meta_sk), *subtp; -+ struct sock *subsk = NULL; -+ struct mptcp_cb *mpcb = meta_tp->mpcb; -+ struct sk_buff *skb; -+ int reinject = 0; -+ unsigned int sublimit; -+ __u32 path_mask = 0; -+ -+ tcp_mstamp_refresh(meta_tp); -+ -+ if (inet_csk(meta_sk)->icsk_retransmits) { -+ /* If the timer already once fired, retransmit the head of the -+ * queue to unblock us ASAP. -+ */ -+ if (meta_tp->packets_out && !mpcb->infinite_mapping_snd) -+ mptcp_retransmit_skb(meta_sk, tcp_write_queue_head(meta_sk)); -+ } -+ -+ while ((skb = mpcb->sched_ops->next_segment(meta_sk, &reinject, &subsk, -+ &sublimit))) { -+ unsigned int limit; -+ -+ WARN(TCP_SKB_CB(skb)->sacked, "sacked: %u reinject: %u", -+ TCP_SKB_CB(skb)->sacked, reinject); -+ -+ subtp = tcp_sk(subsk); -+ mss_now = tcp_current_mss(subsk); -+ -+ if (reinject == 1) { -+ if (!after(TCP_SKB_CB(skb)->end_seq, meta_tp->snd_una)) { -+ /* Segment already reached the peer, take the next one */ -+ __skb_unlink(skb, &mpcb->reinject_queue); -+ __kfree_skb(skb); -+ continue; -+ } -+ } -+ -+ /* If the segment was cloned (e.g. a meta retransmission), -+ * the header must be expanded/copied so that there is no -+ * corruption of TSO information. -+ */ -+ if (skb_unclone(skb, GFP_ATOMIC)) -+ break; -+ -+ if (unlikely(!tcp_snd_wnd_test(meta_tp, skb, mss_now))) -+ break; -+ -+ /* Force tso_segs to 1 by using UINT_MAX. -+ * We actually don't care about the exact number of segments -+ * emitted on the subflow. We need just to set tso_segs, because -+ * we still need an accurate packets_out count in -+ * tcp_event_new_data_sent. -+ */ -+ tcp_set_skb_tso_segs(skb, UINT_MAX); -+ -+ /* Check for nagle, irregardless of tso_segs. If the segment is -+ * actually larger than mss_now (TSO segment), then -+ * tcp_nagle_check will have partial == false and always trigger -+ * the transmission. -+ * tcp_write_xmit has a TSO-level nagle check which is not -+ * subject to the MPTCP-level. It is based on the properties of -+ * the subflow, not the MPTCP-level. -+ */ -+ if (unlikely(!tcp_nagle_test(meta_tp, skb, mss_now, -+ (tcp_skb_is_last(meta_sk, skb) ? -+ nonagle : TCP_NAGLE_PUSH)))) -+ break; -+ -+ limit = mss_now; -+ /* skb->len > mss_now is the equivalent of tso_segs > 1 in -+ * tcp_write_xmit. Otherwise split-point would return 0. -+ */ -+ if (skb->len > mss_now && !tcp_urg_mode(meta_tp)) -+ /* We limit the size of the skb so that it fits into the -+ * window. Call tcp_mss_split_point to avoid duplicating -+ * code. -+ * We really only care about fitting the skb into the -+ * window. That's why we use UINT_MAX. If the skb does -+ * not fit into the cwnd_quota or the NIC's max-segs -+ * limitation, it will be split by the subflow's -+ * tcp_write_xmit which does the appropriate call to -+ * tcp_mss_split_point. -+ */ -+ limit = tcp_mss_split_point(meta_sk, skb, mss_now, -+ UINT_MAX / mss_now, -+ nonagle); -+ -+ if (sublimit) -+ limit = min(limit, sublimit); -+ -+ if (skb->len > limit && -+ unlikely(mptcp_fragment(meta_sk, skb, limit, gfp, reinject))) -+ break; -+ -+ if (!mptcp_skb_entail(subsk, skb, reinject)) -+ break; -+ /* Nagle is handled at the MPTCP-layer, so -+ * always push on the subflow -+ */ -+ __tcp_push_pending_frames(subsk, mss_now, TCP_NAGLE_PUSH); -+ skb->skb_mstamp = meta_tp->tcp_mstamp; -+ meta_tp->lsndtime = tcp_jiffies32; -+ -+ path_mask |= mptcp_pi_to_flag(subtp->mptcp->path_index); -+ -+ if (!reinject) { -+ mptcp_check_sndseq_wrap(meta_tp, -+ TCP_SKB_CB(skb)->end_seq - -+ TCP_SKB_CB(skb)->seq); -+ tcp_event_new_data_sent(meta_sk, skb); -+ } -+ -+ tcp_minshall_update(meta_tp, mss_now, skb); -+ -+ if (reinject > 0) { -+ __skb_unlink(skb, &mpcb->reinject_queue); -+ kfree_skb(skb); -+ } -+ -+ if (push_one) -+ break; -+ } -+ -+ mptcp_for_each_sk(mpcb, subsk) { -+ subtp = tcp_sk(subsk); -+ -+ if (!(path_mask & mptcp_pi_to_flag(subtp->mptcp->path_index))) -+ continue; -+ -+ /* We have pushed data on this subflow. We ignore the call to -+ * cwnd_validate in tcp_write_xmit as is_cwnd_limited will never -+ * be true (we never push more than what the cwnd can accept). -+ * We need to ensure that we call tcp_cwnd_validate with -+ * is_cwnd_limited set to true if we have filled the cwnd. -+ */ -+ tcp_cwnd_validate(subsk, tcp_packets_in_flight(subtp) >= -+ subtp->snd_cwnd); -+ } -+ -+ return !meta_tp->packets_out && tcp_send_head(meta_sk); -+} -+ -+void mptcp_write_space(struct sock *sk) -+{ -+ mptcp_push_pending_frames(mptcp_meta_sk(sk)); -+} -+ -+u32 __mptcp_select_window(struct sock *sk) -+{ -+ struct inet_connection_sock *icsk = inet_csk(sk); -+ struct tcp_sock *tp = tcp_sk(sk), *meta_tp = mptcp_meta_tp(tp); -+ struct sock *meta_sk = mptcp_meta_sk(sk); -+ int mss, free_space, full_space, window; -+ -+ /* MSS for the peer's data. Previous versions used mss_clamp -+ * here. I don't know if the value based on our guesses -+ * of peer's MSS is better for the performance. It's more correct -+ * but may be worse for the performance because of rcv_mss -+ * fluctuations. --SAW 1998/11/1 -+ */ -+ mss = icsk->icsk_ack.rcv_mss; -+ free_space = tcp_space(meta_sk); -+ full_space = min_t(int, meta_tp->window_clamp, -+ tcp_full_space(meta_sk)); -+ -+ if (mss > full_space) -+ mss = full_space; -+ -+ if (free_space < (full_space >> 1)) { -+ /* If free_space is decreasing due to mostly meta-level -+ * out-of-order packets, don't turn off the quick-ack mode. -+ */ -+ if (meta_tp->rcv_nxt - meta_tp->copied_seq > ((full_space - free_space) >> 1)) -+ icsk->icsk_ack.quick = 0; -+ -+ if (tcp_memory_pressure) -+ /* TODO this has to be adapted when we support different -+ * MSS's among the subflows. -+ */ -+ meta_tp->rcv_ssthresh = min(meta_tp->rcv_ssthresh, -+ 4U * meta_tp->advmss); -+ -+ if (free_space < mss) -+ return 0; -+ } -+ -+ if (free_space > meta_tp->rcv_ssthresh) -+ free_space = meta_tp->rcv_ssthresh; -+ -+ /* Don't do rounding if we are using window scaling, since the -+ * scaled window will not line up with the MSS boundary anyway. -+ */ -+ window = meta_tp->rcv_wnd; -+ if (tp->rx_opt.rcv_wscale) { -+ window = free_space; -+ -+ /* Advertise enough space so that it won't get scaled away. -+ * Import case: prevent zero window announcement if -+ * 1< mss. -+ */ -+ if (((window >> tp->rx_opt.rcv_wscale) << tp-> -+ rx_opt.rcv_wscale) != window) -+ window = (((window >> tp->rx_opt.rcv_wscale) + 1) -+ << tp->rx_opt.rcv_wscale); -+ } else { -+ /* Get the largest window that is a nice multiple of mss. -+ * Window clamp already applied above. -+ * If our current window offering is within 1 mss of the -+ * free space we just keep it. This prevents the divide -+ * and multiply from happening most of the time. -+ * We also don't do any window rounding when the free space -+ * is too small. -+ */ -+ if (window <= free_space - mss || window > free_space) -+ window = (free_space / mss) * mss; -+ else if (mss == full_space && -+ free_space > window + (full_space >> 1)) -+ window = free_space; -+ } -+ -+ return window; -+} -+ -+void mptcp_syn_options(const struct sock *sk, struct tcp_out_options *opts, -+ unsigned *remaining) -+{ -+ const struct tcp_sock *tp = tcp_sk(sk); -+ -+ opts->options |= OPTION_MPTCP; -+ if (is_master_tp(tp)) { -+ opts->mptcp_options |= OPTION_MP_CAPABLE | OPTION_TYPE_SYN; -+ opts->mptcp_ver = tcp_sk(sk)->mptcp_ver; -+ *remaining -= MPTCP_SUB_LEN_CAPABLE_SYN_ALIGN; -+ opts->mp_capable.sender_key = tp->mptcp_loc_key; -+ opts->dss_csum = !!sysctl_mptcp_checksum; -+ } else { -+ const struct mptcp_cb *mpcb = tp->mpcb; -+ -+ opts->mptcp_options |= OPTION_MP_JOIN | OPTION_TYPE_SYN; -+ *remaining -= MPTCP_SUB_LEN_JOIN_SYN_ALIGN; -+ opts->mp_join_syns.token = mpcb->mptcp_rem_token; -+ opts->mp_join_syns.low_prio = tp->mptcp->low_prio; -+ opts->addr_id = tp->mptcp->loc_id; -+ opts->mp_join_syns.sender_nonce = tp->mptcp->mptcp_loc_nonce; -+ } -+} -+ -+void mptcp_synack_options(struct request_sock *req, -+ struct tcp_out_options *opts, unsigned *remaining) -+{ -+ struct mptcp_request_sock *mtreq; -+ mtreq = mptcp_rsk(req); -+ -+ opts->options |= OPTION_MPTCP; -+ /* MPCB not yet set - thus it's a new MPTCP-session */ -+ if (!mtreq->is_sub) { -+ opts->mptcp_options |= OPTION_MP_CAPABLE | OPTION_TYPE_SYNACK; -+ opts->mptcp_ver = mtreq->mptcp_ver; -+ opts->mp_capable.sender_key = mtreq->mptcp_loc_key; -+ opts->dss_csum = !!sysctl_mptcp_checksum || mtreq->dss_csum; -+ *remaining -= MPTCP_SUB_LEN_CAPABLE_SYN_ALIGN; -+ } else { -+ opts->mptcp_options |= OPTION_MP_JOIN | OPTION_TYPE_SYNACK; -+ opts->mp_join_syns.sender_truncated_mac = -+ mtreq->mptcp_hash_tmac; -+ opts->mp_join_syns.sender_nonce = mtreq->mptcp_loc_nonce; -+ opts->mp_join_syns.low_prio = mtreq->low_prio; -+ opts->addr_id = mtreq->loc_id; -+ *remaining -= MPTCP_SUB_LEN_JOIN_SYNACK_ALIGN; -+ } -+} -+ -+void mptcp_established_options(struct sock *sk, struct sk_buff *skb, -+ struct tcp_out_options *opts, unsigned *size) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct mptcp_cb *mpcb = tp->mpcb; -+ const struct tcp_skb_cb *tcb = skb ? TCP_SKB_CB(skb) : NULL; -+ -+ /* We are coming from tcp_current_mss with the meta_sk as an argument. -+ * It does not make sense to check for the options, because when the -+ * segment gets sent, another subflow will be chosen. -+ */ -+ if (!skb && is_meta_sk(sk)) -+ return; -+ -+ if (unlikely(tp->send_mp_fclose)) { -+ opts->options |= OPTION_MPTCP; -+ opts->mptcp_options |= OPTION_MP_FCLOSE; -+ opts->mp_capable.receiver_key = mpcb->mptcp_rem_key; -+ *size += MPTCP_SUB_LEN_FCLOSE_ALIGN; -+ return; -+ } -+ -+ /* 1. If we are the sender of the infinite-mapping, we need the -+ * MPTCPHDR_INF-flag, because a retransmission of the -+ * infinite-announcment still needs the mptcp-option. -+ * -+ * We need infinite_cutoff_seq, because retransmissions from before -+ * the infinite-cutoff-moment still need the MPTCP-signalling to stay -+ * consistent. -+ * -+ * 2. If we are the receiver of the infinite-mapping, we always skip -+ * mptcp-options, because acknowledgments from before the -+ * infinite-mapping point have already been sent out. -+ * -+ * I know, the whole infinite-mapping stuff is ugly... -+ * -+ * TODO: Handle wrapped data-sequence numbers -+ * (even if it's very unlikely) -+ */ -+ if (unlikely(mpcb->infinite_mapping_snd) && -+ ((mpcb->send_infinite_mapping && tcb && -+ mptcp_is_data_seq(skb) && -+ !(tcb->mptcp_flags & MPTCPHDR_INF) && -+ !before(tcb->seq, tp->mptcp->infinite_cutoff_seq)) || -+ !mpcb->send_infinite_mapping)) -+ return; -+ -+ if (unlikely(tp->mptcp->include_mpc)) { -+ opts->options |= OPTION_MPTCP; -+ opts->mptcp_options |= OPTION_MP_CAPABLE | -+ OPTION_TYPE_ACK; -+ *size += MPTCP_SUB_LEN_CAPABLE_ACK_ALIGN; -+ opts->mptcp_ver = mpcb->mptcp_ver; -+ opts->mp_capable.sender_key = mpcb->mptcp_loc_key; -+ opts->mp_capable.receiver_key = mpcb->mptcp_rem_key; -+ opts->dss_csum = mpcb->dss_csum; -+ -+ if (skb) -+ tp->mptcp->include_mpc = 0; -+ } -+ if (unlikely(tp->mptcp->pre_established) && -+ (!skb || !(tcb->tcp_flags & (TCPHDR_FIN | TCPHDR_RST)))) { -+ opts->options |= OPTION_MPTCP; -+ opts->mptcp_options |= OPTION_MP_JOIN | OPTION_TYPE_ACK; -+ *size += MPTCP_SUB_LEN_JOIN_ACK_ALIGN; -+ } -+ -+ if (unlikely(mpcb->addr_signal) && mpcb->pm_ops->addr_signal && -+ mpcb->mptcp_ver >= MPTCP_VERSION_1 && skb && !mptcp_is_data_seq(skb)) { -+ mpcb->pm_ops->addr_signal(sk, size, opts, skb); -+ -+ if (opts->add_addr_v6) -+ /* Skip subsequent options */ -+ return; -+ } -+ -+ if (!tp->mptcp->include_mpc && !tp->mptcp->pre_established) { -+ opts->options |= OPTION_MPTCP; -+ opts->mptcp_options |= OPTION_DATA_ACK; -+ /* If !skb, we come from tcp_current_mss and thus we always -+ * assume that the DSS-option will be set for the data-packet. -+ */ -+ if (skb && !mptcp_is_data_seq(skb)) { -+ *size += MPTCP_SUB_LEN_ACK_ALIGN; -+ } else { -+ /* Doesn't matter, if csum included or not. It will be -+ * either 10 or 12, and thus aligned = 12 -+ */ -+ *size += MPTCP_SUB_LEN_ACK_ALIGN + -+ MPTCP_SUB_LEN_SEQ_ALIGN; -+ } -+ -+ *size += MPTCP_SUB_LEN_DSS_ALIGN; -+ } -+ -+ /* In fallback mp_fail-mode, we have to repeat it until the fallback -+ * has been done by the sender -+ */ -+ if (unlikely(tp->mptcp->send_mp_fail) && skb && -+ MAX_TCP_OPTION_SPACE - *size >= MPTCP_SUB_LEN_FAIL) { -+ opts->options |= OPTION_MPTCP; -+ opts->mptcp_options |= OPTION_MP_FAIL; -+ *size += MPTCP_SUB_LEN_FAIL; -+ } -+ -+ if (unlikely(mpcb->addr_signal) && mpcb->pm_ops->addr_signal && -+ mpcb->mptcp_ver < MPTCP_VERSION_1) -+ mpcb->pm_ops->addr_signal(sk, size, opts, skb); -+ -+ if (unlikely(tp->mptcp->send_mp_prio) && -+ MAX_TCP_OPTION_SPACE - *size >= MPTCP_SUB_LEN_PRIO_ALIGN) { -+ opts->options |= OPTION_MPTCP; -+ opts->mptcp_options |= OPTION_MP_PRIO; -+ if (skb) -+ tp->mptcp->send_mp_prio = 0; -+ *size += MPTCP_SUB_LEN_PRIO_ALIGN; -+ } -+ -+ return; -+} -+ -+u16 mptcp_select_window(struct sock *sk) -+{ -+ u16 new_win = tcp_select_window(sk); -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct tcp_sock *meta_tp = mptcp_meta_tp(tp); -+ -+ meta_tp->rcv_wnd = tp->rcv_wnd; -+ meta_tp->rcv_wup = meta_tp->rcv_nxt; -+ -+ return new_win; -+} -+ -+void mptcp_options_write(__be32 *ptr, struct tcp_sock *tp, -+ const struct tcp_out_options *opts, -+ struct sk_buff *skb) -+{ -+ if (unlikely(OPTION_MP_CAPABLE & opts->mptcp_options)) { -+ struct mp_capable *mpc = (struct mp_capable *)ptr; -+ -+ mpc->kind = TCPOPT_MPTCP; -+ -+ if ((OPTION_TYPE_SYN & opts->mptcp_options) || -+ (OPTION_TYPE_SYNACK & opts->mptcp_options)) { -+ mpc->sender_key = opts->mp_capable.sender_key; -+ mpc->len = MPTCP_SUB_LEN_CAPABLE_SYN; -+ mpc->ver = opts->mptcp_ver; -+ ptr += MPTCP_SUB_LEN_CAPABLE_SYN_ALIGN >> 2; -+ } else if (OPTION_TYPE_ACK & opts->mptcp_options) { -+ mpc->sender_key = opts->mp_capable.sender_key; -+ mpc->receiver_key = opts->mp_capable.receiver_key; -+ mpc->len = MPTCP_SUB_LEN_CAPABLE_ACK; -+ mpc->ver = opts->mptcp_ver; -+ ptr += MPTCP_SUB_LEN_CAPABLE_ACK_ALIGN >> 2; -+ } -+ -+ mpc->sub = MPTCP_SUB_CAPABLE; -+ mpc->a = opts->dss_csum; -+ mpc->b = 0; -+ mpc->rsv = 0; -+ mpc->h = 1; -+ } -+ if (unlikely(OPTION_MP_JOIN & opts->mptcp_options)) { -+ struct mp_join *mpj = (struct mp_join *)ptr; -+ -+ mpj->kind = TCPOPT_MPTCP; -+ mpj->sub = MPTCP_SUB_JOIN; -+ mpj->rsv = 0; -+ -+ if (OPTION_TYPE_SYN & opts->mptcp_options) { -+ mpj->len = MPTCP_SUB_LEN_JOIN_SYN; -+ mpj->u.syn.token = opts->mp_join_syns.token; -+ mpj->u.syn.nonce = opts->mp_join_syns.sender_nonce; -+ mpj->b = opts->mp_join_syns.low_prio; -+ mpj->addr_id = opts->addr_id; -+ ptr += MPTCP_SUB_LEN_JOIN_SYN_ALIGN >> 2; -+ } else if (OPTION_TYPE_SYNACK & opts->mptcp_options) { -+ mpj->len = MPTCP_SUB_LEN_JOIN_SYNACK; -+ mpj->u.synack.mac = -+ opts->mp_join_syns.sender_truncated_mac; -+ mpj->u.synack.nonce = opts->mp_join_syns.sender_nonce; -+ mpj->b = opts->mp_join_syns.low_prio; -+ mpj->addr_id = opts->addr_id; -+ ptr += MPTCP_SUB_LEN_JOIN_SYNACK_ALIGN >> 2; -+ } else if (OPTION_TYPE_ACK & opts->mptcp_options) { -+ mpj->len = MPTCP_SUB_LEN_JOIN_ACK; -+ mpj->addr_id = 0; /* addr_id is rsv (RFC 6824, p. 21) */ -+ memcpy(mpj->u.ack.mac, &tp->mptcp->sender_mac[0], 20); -+ ptr += MPTCP_SUB_LEN_JOIN_ACK_ALIGN >> 2; -+ } -+ } -+ if (unlikely(OPTION_ADD_ADDR & opts->mptcp_options)) { -+ struct mp_add_addr *mpadd = (struct mp_add_addr *)ptr; -+ struct mptcp_cb *mpcb = tp->mpcb; -+ -+ mpadd->kind = TCPOPT_MPTCP; -+ if (opts->add_addr_v4) { -+ mpadd->sub = MPTCP_SUB_ADD_ADDR; -+ mpadd->ipver = 4; -+ mpadd->addr_id = opts->add_addr4.addr_id; -+ mpadd->u.v4.addr = opts->add_addr4.addr; -+ if (mpcb->mptcp_ver < MPTCP_VERSION_1) { -+ mpadd->len = MPTCP_SUB_LEN_ADD_ADDR4; -+ ptr += MPTCP_SUB_LEN_ADD_ADDR4_ALIGN >> 2; -+ } else { -+ memcpy((char *)mpadd->u.v4.mac - 2, -+ (char *)&opts->add_addr4.trunc_mac, 8); -+ mpadd->len = MPTCP_SUB_LEN_ADD_ADDR4_VER1; -+ ptr += MPTCP_SUB_LEN_ADD_ADDR4_ALIGN_VER1 >> 2; -+ } -+ } else if (opts->add_addr_v6) { -+ mpadd->sub = MPTCP_SUB_ADD_ADDR; -+ mpadd->ipver = 6; -+ mpadd->addr_id = opts->add_addr6.addr_id; -+ memcpy(&mpadd->u.v6.addr, &opts->add_addr6.addr, -+ sizeof(mpadd->u.v6.addr)); -+ if (mpcb->mptcp_ver < MPTCP_VERSION_1) { -+ mpadd->len = MPTCP_SUB_LEN_ADD_ADDR6; -+ ptr += MPTCP_SUB_LEN_ADD_ADDR6_ALIGN >> 2; -+ } else { -+ memcpy((char *)mpadd->u.v6.mac - 2, -+ (char *)&opts->add_addr6.trunc_mac, 8); -+ mpadd->len = MPTCP_SUB_LEN_ADD_ADDR6_VER1; -+ ptr += MPTCP_SUB_LEN_ADD_ADDR6_ALIGN_VER1 >> 2; -+ } -+ } -+ -+ MPTCP_INC_STATS(sock_net((struct sock *)tp), MPTCP_MIB_ADDADDRTX); -+ } -+ if (unlikely(OPTION_REMOVE_ADDR & opts->mptcp_options)) { -+ struct mp_remove_addr *mprem = (struct mp_remove_addr *)ptr; -+ u8 *addrs_id; -+ int id, len, len_align; -+ -+ len = mptcp_sub_len_remove_addr(opts->remove_addrs); -+ len_align = mptcp_sub_len_remove_addr_align(opts->remove_addrs); -+ -+ mprem->kind = TCPOPT_MPTCP; -+ mprem->len = len; -+ mprem->sub = MPTCP_SUB_REMOVE_ADDR; -+ mprem->rsv = 0; -+ addrs_id = &mprem->addrs_id; -+ -+ mptcp_for_each_bit_set(opts->remove_addrs, id) -+ *(addrs_id++) = id; -+ -+ /* Fill the rest with NOP's */ -+ if (len_align > len) { -+ int i; -+ for (i = 0; i < len_align - len; i++) -+ *(addrs_id++) = TCPOPT_NOP; -+ } -+ -+ ptr += len_align >> 2; -+ -+ MPTCP_INC_STATS(sock_net((struct sock *)tp), MPTCP_MIB_REMADDRTX); -+ } -+ if (unlikely(OPTION_MP_FAIL & opts->mptcp_options)) { -+ struct mp_fail *mpfail = (struct mp_fail *)ptr; -+ -+ mpfail->kind = TCPOPT_MPTCP; -+ mpfail->len = MPTCP_SUB_LEN_FAIL; -+ mpfail->sub = MPTCP_SUB_FAIL; -+ mpfail->rsv1 = 0; -+ mpfail->rsv2 = 0; -+ mpfail->data_seq = htonll(tp->mpcb->csum_cutoff_seq); -+ -+ ptr += MPTCP_SUB_LEN_FAIL_ALIGN >> 2; -+ } -+ if (unlikely(OPTION_MP_FCLOSE & opts->mptcp_options)) { -+ struct mp_fclose *mpfclose = (struct mp_fclose *)ptr; -+ -+ mpfclose->kind = TCPOPT_MPTCP; -+ mpfclose->len = MPTCP_SUB_LEN_FCLOSE; -+ mpfclose->sub = MPTCP_SUB_FCLOSE; -+ mpfclose->rsv1 = 0; -+ mpfclose->rsv2 = 0; -+ mpfclose->key = opts->mp_capable.receiver_key; -+ -+ ptr += MPTCP_SUB_LEN_FCLOSE_ALIGN >> 2; -+ } -+ -+ if (OPTION_DATA_ACK & opts->mptcp_options) { -+ if (!mptcp_is_data_seq(skb)) -+ ptr += mptcp_write_dss_data_ack(tp, skb, ptr); -+ else -+ ptr += mptcp_write_dss_data_seq(tp, skb, ptr); -+ } -+ if (unlikely(OPTION_MP_PRIO & opts->mptcp_options)) { -+ struct mp_prio *mpprio = (struct mp_prio *)ptr; -+ -+ mpprio->kind = TCPOPT_MPTCP; -+ mpprio->len = MPTCP_SUB_LEN_PRIO; -+ mpprio->sub = MPTCP_SUB_PRIO; -+ mpprio->rsv = 0; -+ mpprio->b = tp->mptcp->low_prio; -+ mpprio->addr_id = TCPOPT_NOP; -+ -+ ptr += MPTCP_SUB_LEN_PRIO_ALIGN >> 2; -+ } -+} -+ -+/* Sends the datafin */ -+void mptcp_send_fin(struct sock *meta_sk) -+{ -+ struct tcp_sock *meta_tp = tcp_sk(meta_sk); -+ struct sk_buff *skb = tcp_write_queue_tail(meta_sk); -+ int mss_now; -+ -+ if ((1 << meta_sk->sk_state) & (TCPF_CLOSE_WAIT | TCPF_LAST_ACK)) -+ meta_tp->mpcb->passive_close = 1; -+ -+ /* Optimization, tack on the FIN if we have a queue of -+ * unsent frames. But be careful about outgoing SACKS -+ * and IP options. -+ */ -+ mss_now = mptcp_current_mss(meta_sk); -+ -+ if (tcp_send_head(meta_sk) != NULL) { -+ TCP_SKB_CB(skb)->mptcp_flags |= MPTCPHDR_FIN; -+ TCP_SKB_CB(skb)->end_seq++; -+ meta_tp->write_seq++; -+ } else { -+ /* Socket is locked, keep trying until memory is available. */ -+ for (;;) { -+ skb = alloc_skb_fclone(MAX_TCP_HEADER, -+ meta_sk->sk_allocation); -+ if (skb) -+ break; -+ yield(); -+ } -+ /* Reserve space for headers and prepare control bits. */ -+ skb_reserve(skb, MAX_TCP_HEADER); -+ -+ tcp_init_nondata_skb(skb, meta_tp->write_seq, TCPHDR_ACK); -+ TCP_SKB_CB(skb)->end_seq++; -+ TCP_SKB_CB(skb)->mptcp_flags |= MPTCPHDR_FIN; -+ tcp_queue_skb(meta_sk, skb); -+ } -+ __tcp_push_pending_frames(meta_sk, mss_now, TCP_NAGLE_OFF); -+} -+ -+void mptcp_send_active_reset(struct sock *meta_sk, gfp_t priority) -+{ -+ struct tcp_sock *meta_tp = tcp_sk(meta_sk); -+ struct mptcp_cb *mpcb = meta_tp->mpcb; -+ struct sock *sk; -+ -+ if (!mpcb->cnt_subflows) -+ return; -+ -+ WARN_ON(meta_tp->send_mp_fclose); -+ -+ /* First - select a socket */ -+ sk = mptcp_select_ack_sock(meta_sk); -+ -+ /* May happen if no subflow is in an appropriate state, OR -+ * we are in infinite mode or about to go there - just send a reset -+ */ -+ if (!sk || mptcp_in_infinite_mapping_weak(mpcb)) { -+ /* tcp_done must be handled with bh disabled */ -+ if (!in_serving_softirq()) -+ local_bh_disable(); -+ -+ mptcp_sub_force_close_all(mpcb, NULL); -+ -+ if (!in_serving_softirq()) -+ local_bh_enable(); -+ return; -+ } -+ -+ tcp_mstamp_refresh(meta_tp); -+ -+ tcp_sk(sk)->send_mp_fclose = 1; -+ /** Reset all other subflows */ -+ -+ /* tcp_done must be handled with bh disabled */ -+ if (!in_serving_softirq()) -+ local_bh_disable(); -+ -+ mptcp_sub_force_close_all(mpcb, sk); -+ -+ tcp_set_state(sk, TCP_RST_WAIT); -+ -+ if (!in_serving_softirq()) -+ local_bh_enable(); -+ -+ tcp_send_ack(sk); -+ tcp_clear_xmit_timers(sk); -+ inet_csk_reset_keepalive_timer(sk, inet_csk(sk)->icsk_rto); -+ -+ meta_tp->send_mp_fclose = 1; -+ inet_csk(sk)->icsk_retransmits = 0; -+ -+ /* Prevent exp backoff reverting on ICMP dest unreachable */ -+ inet_csk(sk)->icsk_backoff = 0; -+ -+ MPTCP_INC_STATS(sock_net(meta_sk), MPTCP_MIB_FASTCLOSETX); -+} -+ -+static void mptcp_ack_retransmit_timer(struct sock *sk) -+{ -+ struct inet_connection_sock *icsk = inet_csk(sk); -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct net *net = sock_net(sk); -+ struct sk_buff *skb; -+ -+ if (inet_csk(sk)->icsk_af_ops->rebuild_header(sk)) -+ goto out; /* Routing failure or similar */ -+ -+ tcp_mstamp_refresh(tp); -+ -+ if (tcp_write_timeout(sk)) { -+ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_JOINACKRTO); -+ tp->mptcp->pre_established = 0; -+ sk_stop_timer(sk, &tp->mptcp->mptcp_ack_timer); -+ tp->ops->send_active_reset(sk, GFP_ATOMIC); -+ goto out; -+ } -+ -+ skb = alloc_skb(MAX_TCP_HEADER, GFP_ATOMIC); -+ if (skb == NULL) { -+ sk_reset_timer(sk, &tp->mptcp->mptcp_ack_timer, -+ jiffies + icsk->icsk_rto); -+ return; -+ } -+ -+ /* Reserve space for headers and prepare control bits */ -+ skb_reserve(skb, MAX_TCP_HEADER); -+ tcp_init_nondata_skb(skb, tp->snd_una, TCPHDR_ACK); -+ -+ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_JOINACKRXMIT); -+ -+ if (tcp_transmit_skb(sk, skb, 0, GFP_ATOMIC) > 0) { -+ /* Retransmission failed because of local congestion, -+ * do not backoff. -+ */ -+ if (!icsk->icsk_retransmits) -+ icsk->icsk_retransmits = 1; -+ sk_reset_timer(sk, &tp->mptcp->mptcp_ack_timer, -+ jiffies + icsk->icsk_rto); -+ return; -+ } -+ -+ if (!tp->retrans_stamp) -+ tp->retrans_stamp = tcp_time_stamp(tp) ? : 1; -+ -+ icsk->icsk_retransmits++; -+ icsk->icsk_rto = min(icsk->icsk_rto << 1, TCP_RTO_MAX); -+ sk_reset_timer(sk, &tp->mptcp->mptcp_ack_timer, -+ jiffies + icsk->icsk_rto); -+ if (retransmits_timed_out(sk, net->ipv4.sysctl_tcp_retries1 + 1, 0)) -+ __sk_dst_reset(sk); -+ -+out:; -+} -+ -+void mptcp_ack_handler(unsigned long data) -+{ -+ struct sock *sk = (struct sock *)data; -+ struct sock *meta_sk = mptcp_meta_sk(sk); -+ -+ bh_lock_sock(meta_sk); -+ if (sock_owned_by_user(meta_sk)) { -+ /* Try again later */ -+ sk_reset_timer(sk, &tcp_sk(sk)->mptcp->mptcp_ack_timer, -+ jiffies + (HZ / 20)); -+ goto out_unlock; -+ } -+ -+ if (sk->sk_state == TCP_CLOSE) -+ goto out_unlock; -+ if (!tcp_sk(sk)->mptcp->pre_established) -+ goto out_unlock; -+ -+ mptcp_ack_retransmit_timer(sk); -+ -+ sk_mem_reclaim(sk); -+ -+out_unlock: -+ bh_unlock_sock(meta_sk); -+ sock_put(sk); -+} -+ -+/* Similar to tcp_retransmit_skb -+ * -+ * The diff is that we handle the retransmission-stats (retrans_stamp) at the -+ * meta-level. -+ */ -+int mptcp_retransmit_skb(struct sock *meta_sk, struct sk_buff *skb) -+{ -+ struct tcp_sock *meta_tp = tcp_sk(meta_sk); -+ struct sock *subsk; -+ unsigned int limit, mss_now; -+ int err = -1; -+ -+ WARN_ON(TCP_SKB_CB(skb)->sacked); -+ -+ /* Do not sent more than we queued. 1/4 is reserved for possible -+ * copying overhead: fragmentation, tunneling, mangling etc. -+ * -+ * This is a meta-retransmission thus we check on the meta-socket. -+ */ -+ if (refcount_read(&meta_sk->sk_wmem_alloc) > -+ min(meta_sk->sk_wmem_queued + (meta_sk->sk_wmem_queued >> 2), meta_sk->sk_sndbuf)) { -+ return -EAGAIN; -+ } -+ -+ /* We need to make sure that the retransmitted segment can be sent on a -+ * subflow right now. If it is too big, it needs to be fragmented. -+ */ -+ subsk = meta_tp->mpcb->sched_ops->get_subflow(meta_sk, skb, false); -+ if (!subsk) { -+ /* We want to increase icsk_retransmits, thus return 0, so that -+ * mptcp_meta_retransmit_timer enters the desired branch. -+ */ -+ err = 0; -+ goto failed; -+ } -+ mss_now = tcp_current_mss(subsk); -+ -+ /* If the segment was cloned (e.g. a meta retransmission), the header -+ * must be expanded/copied so that there is no corruption of TSO -+ * information. -+ */ -+ if (skb_unclone(skb, GFP_ATOMIC)) { -+ err = -ENOMEM; -+ goto failed; -+ } -+ -+ /* Must have been set by mptcp_write_xmit before */ -+ BUG_ON(!tcp_skb_pcount(skb)); -+ -+ limit = mss_now; -+ /* skb->len > mss_now is the equivalent of tso_segs > 1 in -+ * tcp_write_xmit. Otherwise split-point would return 0. -+ */ -+ if (skb->len > mss_now && !tcp_urg_mode(meta_tp)) -+ limit = tcp_mss_split_point(meta_sk, skb, mss_now, -+ UINT_MAX / mss_now, -+ TCP_NAGLE_OFF); -+ -+ limit = min(limit, tcp_wnd_end(meta_tp) - TCP_SKB_CB(skb)->seq); -+ -+ if (skb->len > limit && -+ unlikely(mptcp_fragment(meta_sk, skb, limit, -+ GFP_ATOMIC, 0))) -+ goto failed; -+ -+ if (!mptcp_skb_entail(subsk, skb, -1)) -+ goto failed; -+ -+ /* Update global TCP statistics. */ -+ MPTCP_INC_STATS(sock_net(meta_sk), MPTCP_MIB_RETRANSSEGS); -+ -+ /* Diff to tcp_retransmit_skb */ -+ -+ /* Save stamp of the first retransmit. */ -+ if (!meta_tp->retrans_stamp) { -+ tcp_mstamp_refresh(meta_tp); -+ meta_tp->retrans_stamp = tcp_time_stamp(meta_tp); -+ } -+ -+ __tcp_push_pending_frames(subsk, mss_now, TCP_NAGLE_PUSH); -+ skb->skb_mstamp = meta_tp->tcp_mstamp; -+ meta_tp->lsndtime = tcp_jiffies32; -+ -+ return 0; -+ -+failed: -+ __NET_INC_STATS(sock_net(meta_sk), LINUX_MIB_TCPRETRANSFAIL); -+ return err; -+} -+ -+/* Similar to tcp_retransmit_timer -+ * -+ * The diff is that we have to handle retransmissions of the FAST_CLOSE-message -+ * and that we don't have an srtt estimation at the meta-level. -+ */ -+void mptcp_meta_retransmit_timer(struct sock *meta_sk) -+{ -+ struct tcp_sock *meta_tp = tcp_sk(meta_sk); -+ struct mptcp_cb *mpcb = meta_tp->mpcb; -+ struct inet_connection_sock *meta_icsk = inet_csk(meta_sk); -+ int err; -+ -+ /* In fallback, retransmission is handled at the subflow-level */ -+ if (!meta_tp->packets_out || mpcb->infinite_mapping_snd) -+ return; -+ -+ WARN_ON(tcp_write_queue_empty(meta_sk)); -+ -+ if (!meta_tp->snd_wnd && !sock_flag(meta_sk, SOCK_DEAD) && -+ !((1 << meta_sk->sk_state) & (TCPF_SYN_SENT | TCPF_SYN_RECV))) { -+ /* Receiver dastardly shrinks window. Our retransmits -+ * become zero probes, but we should not timeout this -+ * connection. If the socket is an orphan, time it out, -+ * we cannot allow such beasts to hang infinitely. -+ */ -+ struct inet_sock *meta_inet = inet_sk(meta_sk); -+ if (meta_sk->sk_family == AF_INET) { -+ net_dbg_ratelimited("MPTCP: Peer %pI4:%u/%u unexpectedly shrunk window %u:%u (repaired)\n", -+ &meta_inet->inet_daddr, -+ ntohs(meta_inet->inet_dport), -+ meta_inet->inet_num, meta_tp->snd_una, -+ meta_tp->snd_nxt); -+ } -+#if IS_ENABLED(CONFIG_IPV6) -+ else if (meta_sk->sk_family == AF_INET6) { -+ net_dbg_ratelimited("MPTCP: Peer %pI6:%u/%u unexpectedly shrunk window %u:%u (repaired)\n", -+ &meta_sk->sk_v6_daddr, -+ ntohs(meta_inet->inet_dport), -+ meta_inet->inet_num, meta_tp->snd_una, -+ meta_tp->snd_nxt); -+ } -+#endif -+ if (tcp_jiffies32 - meta_tp->rcv_tstamp > TCP_RTO_MAX) { -+ tcp_write_err(meta_sk); -+ return; -+ } -+ -+ mptcp_retransmit_skb(meta_sk, tcp_write_queue_head(meta_sk)); -+ goto out_reset_timer; -+ } -+ -+ if (tcp_write_timeout(meta_sk)) -+ return; -+ -+ if (meta_icsk->icsk_retransmits == 0) -+ __NET_INC_STATS(sock_net(meta_sk), LINUX_MIB_TCPTIMEOUTS); -+ -+ meta_icsk->icsk_ca_state = TCP_CA_Loss; -+ -+ err = mptcp_retransmit_skb(meta_sk, tcp_write_queue_head(meta_sk)); -+ if (err > 0) { -+ /* Retransmission failed because of local congestion, -+ * do not backoff. -+ */ -+ if (!meta_icsk->icsk_retransmits) -+ meta_icsk->icsk_retransmits = 1; -+ inet_csk_reset_xmit_timer(meta_sk, ICSK_TIME_RETRANS, -+ min(meta_icsk->icsk_rto, TCP_RESOURCE_PROBE_INTERVAL), -+ TCP_RTO_MAX); -+ return; -+ } -+ -+ /* Increase the timeout each time we retransmit. Note that -+ * we do not increase the rtt estimate. rto is initialized -+ * from rtt, but increases here. Jacobson (SIGCOMM 88) suggests -+ * that doubling rto each time is the least we can get away with. -+ * In KA9Q, Karn uses this for the first few times, and then -+ * goes to quadratic. netBSD doubles, but only goes up to *64, -+ * and clamps at 1 to 64 sec afterwards. Note that 120 sec is -+ * defined in the protocol as the maximum possible RTT. I guess -+ * we'll have to use something other than TCP to talk to the -+ * University of Mars. -+ * -+ * PAWS allows us longer timeouts and large windows, so once -+ * implemented ftp to mars will work nicely. We will have to fix -+ * the 120 second clamps though! -+ */ -+ meta_icsk->icsk_backoff++; -+ meta_icsk->icsk_retransmits++; -+ -+out_reset_timer: -+ /* If stream is thin, use linear timeouts. Since 'icsk_backoff' is -+ * used to reset timer, set to 0. Recalculate 'icsk_rto' as this -+ * might be increased if the stream oscillates between thin and thick, -+ * thus the old value might already be too high compared to the value -+ * set by 'tcp_set_rto' in tcp_input.c which resets the rto without -+ * backoff. Limit to TCP_THIN_LINEAR_RETRIES before initiating -+ * exponential backoff behaviour to avoid continue hammering -+ * linear-timeout retransmissions into a black hole -+ */ -+ if (meta_sk->sk_state == TCP_ESTABLISHED && -+ (meta_tp->thin_lto || sysctl_tcp_thin_linear_timeouts) && -+ tcp_stream_is_thin(meta_tp) && -+ meta_icsk->icsk_retransmits <= TCP_THIN_LINEAR_RETRIES) { -+ meta_icsk->icsk_backoff = 0; -+ /* We cannot do the same as in tcp_write_timer because the -+ * srtt is not set here. -+ */ -+ mptcp_set_rto(meta_sk); -+ } else { -+ /* Use normal (exponential) backoff */ -+ meta_icsk->icsk_rto = min(meta_icsk->icsk_rto << 1, TCP_RTO_MAX); -+ } -+ inet_csk_reset_xmit_timer(meta_sk, ICSK_TIME_RETRANS, meta_icsk->icsk_rto, TCP_RTO_MAX); -+ -+ return; -+} -+ -+void mptcp_sub_retransmit_timer(struct sock *sk) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ -+ tcp_retransmit_timer(sk); -+ -+ if (!tp->fastopen_rsk) { -+ mptcp_reinject_data(sk, 1); -+ mptcp_set_rto(sk); -+ } -+} -+ -+/* Modify values to an mptcp-level for the initial window of new subflows */ -+void mptcp_select_initial_window(int __space, __u32 mss, __u32 *rcv_wnd, -+ __u32 *window_clamp, int wscale_ok, -+ __u8 *rcv_wscale, __u32 init_rcv_wnd, -+ const struct sock *sk) -+{ -+ const struct mptcp_cb *mpcb = tcp_sk(sk)->mpcb; -+ -+ *window_clamp = mpcb->orig_window_clamp; -+ __space = tcp_win_from_space(mpcb->orig_sk_rcvbuf); -+ -+ tcp_select_initial_window(__space, mss, rcv_wnd, window_clamp, -+ wscale_ok, rcv_wscale, init_rcv_wnd, sk); -+} -+ -+static inline u64 mptcp_calc_rate(const struct sock *meta_sk, unsigned int mss, -+ unsigned int (*mss_cb)(struct sock *sk)) -+{ -+ struct sock *sk; -+ u64 rate = 0; -+ -+ mptcp_for_each_sk(tcp_sk(meta_sk)->mpcb, sk) { -+ struct tcp_sock *tp = tcp_sk(sk); -+ int this_mss; -+ u64 this_rate; -+ -+ if (!mptcp_sk_can_send(sk)) -+ continue; -+ -+ /* Do not consider subflows without a RTT estimation yet -+ * otherwise this_rate >>> rate. -+ */ -+ if (unlikely(!tp->srtt_us)) -+ continue; -+ -+ this_mss = mss_cb(sk); -+ -+ /* If this_mss is smaller than mss, it means that a segment will -+ * be splitted in two (or more) when pushed on this subflow. If -+ * you consider that mss = 1428 and this_mss = 1420 then two -+ * segments will be generated: a 1420-byte and 8-byte segment. -+ * The latter will introduce a large overhead as for a single -+ * data segment 2 slots will be used in the congestion window. -+ * Therefore reducing by ~2 the potential throughput of this -+ * subflow. Indeed, 1428 will be send while 2840 could have been -+ * sent if mss == 1420 reducing the throughput by 2840 / 1428. -+ * -+ * The following algorithm take into account this overhead -+ * when computing the potential throughput that MPTCP can -+ * achieve when generating mss-byte segments. -+ * -+ * The formulae is the following: -+ * \sum_{\forall sub} ratio * \frac{mss * cwnd_sub}{rtt_sub} -+ * Where ratio is computed as follows: -+ * \frac{mss}{\ceil{mss / mss_sub} * mss_sub} -+ * -+ * ratio gives the reduction factor of the theoretical -+ * throughput a subflow can achieve if MPTCP uses a specific -+ * MSS value. -+ */ -+ this_rate = div64_u64((u64)mss * mss * (USEC_PER_SEC << 3) * -+ max(tp->snd_cwnd, tp->packets_out), -+ (u64)tp->srtt_us * -+ DIV_ROUND_UP(mss, this_mss) * this_mss); -+ rate += this_rate; -+ } -+ -+ return rate; -+} -+ -+static unsigned int __mptcp_current_mss(const struct sock *meta_sk, -+ unsigned int (*mss_cb)(struct sock *sk)) -+{ -+ unsigned int mss = 0; -+ u64 rate = 0; -+ struct sock *sk; -+ -+ mptcp_for_each_sk(tcp_sk(meta_sk)->mpcb, sk) { -+ int this_mss; -+ u64 this_rate; -+ -+ if (!mptcp_sk_can_send(sk)) -+ continue; -+ -+ this_mss = mss_cb(sk); -+ -+ /* Same mss values will produce the same throughput. */ -+ if (this_mss == mss) -+ continue; -+ -+ /* See whether using this mss value can theoretically improve -+ * the performances. -+ */ -+ this_rate = mptcp_calc_rate(meta_sk, this_mss, mss_cb); -+ if (this_rate >= rate) { -+ mss = this_mss; -+ rate = this_rate; -+ } -+ } -+ -+ return mss; -+} -+ -+unsigned int mptcp_current_mss(struct sock *meta_sk) -+{ -+ unsigned int mss = __mptcp_current_mss(meta_sk, tcp_current_mss); -+ -+ /* If no subflow is available, we take a default-mss from the -+ * meta-socket. -+ */ -+ return !mss ? tcp_current_mss(meta_sk) : mss; -+} -+ -+static unsigned int mptcp_select_size_mss(struct sock *sk) -+{ -+ return tcp_sk(sk)->mss_cache; -+} -+ -+int mptcp_select_size(const struct sock *meta_sk, bool sg, bool first_skb) -+{ -+ unsigned int mss = __mptcp_current_mss(meta_sk, mptcp_select_size_mss); -+ -+ if (sg) { -+ if (mptcp_sk_can_gso(meta_sk)) { -+ mss = linear_payload_sz(first_skb); -+ } else { -+ int pgbreak = SKB_MAX_HEAD(MAX_TCP_HEADER); -+ -+ if (mss >= pgbreak && -+ mss <= pgbreak + (MAX_SKB_FRAGS - 1) * PAGE_SIZE) -+ mss = pgbreak; -+ } -+ } -+ -+ return !mss ? tcp_sk(meta_sk)->mss_cache : mss; -+} -+ -+int mptcp_check_snd_buf(const struct tcp_sock *tp) -+{ -+ const struct sock *sk; -+ u32 rtt_max = tp->srtt_us; -+ u64 bw_est; -+ -+ if (!tp->srtt_us) -+ return tp->reordering + 1; -+ -+ mptcp_for_each_sk(tp->mpcb, sk) { -+ if (!mptcp_sk_can_send(sk)) -+ continue; -+ -+ if (rtt_max < tcp_sk(sk)->srtt_us) -+ rtt_max = tcp_sk(sk)->srtt_us; -+ } -+ -+ bw_est = div64_u64(((u64)tp->snd_cwnd * rtt_max) << 16, -+ (u64)tp->srtt_us); -+ -+ return max_t(unsigned int, (u32)(bw_est >> 16), -+ tp->reordering + 1); -+} -+ -+unsigned int mptcp_xmit_size_goal(const struct sock *meta_sk, u32 mss_now, -+ int large_allowed) -+{ -+ struct sock *sk; -+ u32 xmit_size_goal = 0; -+ -+ if (large_allowed && mptcp_sk_can_gso(meta_sk)) { -+ mptcp_for_each_sk(tcp_sk(meta_sk)->mpcb, sk) { -+ int this_size_goal; -+ -+ if (!mptcp_sk_can_send(sk)) -+ continue; -+ -+ this_size_goal = tcp_xmit_size_goal(sk, mss_now, 1); -+ if (this_size_goal > xmit_size_goal) -+ xmit_size_goal = this_size_goal; -+ } -+ } -+ -+ return max(xmit_size_goal, mss_now); -+} -+ -diff -aurN linux-4.14.174/net/mptcp/mptcp_pm.c mptcp-mptcp_v0.94/net/mptcp/mptcp_pm.c ---- linux-4.14.174/net/mptcp/mptcp_pm.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_v0.94/net/mptcp/mptcp_pm.c 2020-03-23 09:45:33.000000000 +0100 -@@ -0,0 +1,226 @@ -+/* -+ * MPTCP implementation - MPTCP-subflow-management -+ * -+ * Initial Design & Implementation: -+ * Sébastien Barré -+ * -+ * Current Maintainer & Author: -+ * Christoph Paasch -+ * -+ * Additional authors: -+ * Jaakko Korkeaniemi -+ * Gregory Detal -+ * Fabien Duchêne -+ * Andreas Seelinger -+ * Lavkesh Lahngir -+ * Andreas Ripke -+ * Vlad Dogaru -+ * Octavian Purdila -+ * John Ronan -+ * Catalin Nicutar -+ * Brandon Heller -+ * -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version -+ * 2 of the License, or (at your option) any later version. -+ */ -+ -+ -+#include -+#include -+ -+static DEFINE_SPINLOCK(mptcp_pm_list_lock); -+static LIST_HEAD(mptcp_pm_list); -+ -+static int mptcp_default_id(sa_family_t family, union inet_addr *addr, -+ struct net *net, bool *low_prio) -+{ -+ return 0; -+} -+ -+struct mptcp_pm_ops mptcp_pm_default = { -+ .get_local_id = mptcp_default_id, /* We do not care */ -+ .name = "default", -+ .owner = THIS_MODULE, -+}; -+ -+static struct mptcp_pm_ops *mptcp_pm_find(const char *name) -+{ -+ struct mptcp_pm_ops *e; -+ -+ list_for_each_entry_rcu(e, &mptcp_pm_list, list) { -+ if (strcmp(e->name, name) == 0) -+ return e; -+ } -+ -+ return NULL; -+} -+ -+int mptcp_register_path_manager(struct mptcp_pm_ops *pm) -+{ -+ int ret = 0; -+ -+ if (!pm->get_local_id) -+ return -EINVAL; -+ -+ spin_lock(&mptcp_pm_list_lock); -+ if (mptcp_pm_find(pm->name)) { -+ pr_notice("%s already registered\n", pm->name); -+ ret = -EEXIST; -+ } else { -+ list_add_tail_rcu(&pm->list, &mptcp_pm_list); -+ pr_info("%s registered\n", pm->name); -+ } -+ spin_unlock(&mptcp_pm_list_lock); -+ -+ return ret; -+} -+EXPORT_SYMBOL_GPL(mptcp_register_path_manager); -+ -+void mptcp_unregister_path_manager(struct mptcp_pm_ops *pm) -+{ -+ spin_lock(&mptcp_pm_list_lock); -+ list_del_rcu(&pm->list); -+ spin_unlock(&mptcp_pm_list_lock); -+ -+ /* Wait for outstanding readers to complete before the -+ * module gets removed entirely. -+ * -+ * A try_module_get() should fail by now as our module is -+ * in "going" state since no refs are held anymore and -+ * module_exit() handler being called. -+ */ -+ synchronize_rcu(); -+} -+EXPORT_SYMBOL_GPL(mptcp_unregister_path_manager); -+ -+void mptcp_get_default_path_manager(char *name) -+{ -+ struct mptcp_pm_ops *pm; -+ -+ BUG_ON(list_empty(&mptcp_pm_list)); -+ -+ rcu_read_lock(); -+ pm = list_entry(mptcp_pm_list.next, struct mptcp_pm_ops, list); -+ strncpy(name, pm->name, MPTCP_PM_NAME_MAX); -+ rcu_read_unlock(); -+} -+ -+int mptcp_set_default_path_manager(const char *name) -+{ -+ struct mptcp_pm_ops *pm; -+ int ret = -ENOENT; -+ -+ spin_lock(&mptcp_pm_list_lock); -+ pm = mptcp_pm_find(name); -+#ifdef CONFIG_MODULES -+ if (!pm && capable(CAP_NET_ADMIN)) { -+ spin_unlock(&mptcp_pm_list_lock); -+ -+ request_module("mptcp_%s", name); -+ spin_lock(&mptcp_pm_list_lock); -+ pm = mptcp_pm_find(name); -+ } -+#endif -+ -+ if (pm) { -+ list_move(&pm->list, &mptcp_pm_list); -+ ret = 0; -+ } else { -+ pr_info("%s is not available\n", name); -+ } -+ spin_unlock(&mptcp_pm_list_lock); -+ -+ return ret; -+} -+ -+static struct mptcp_pm_ops *__mptcp_pm_find_autoload(const char *name) -+{ -+ struct mptcp_pm_ops *pm = mptcp_pm_find(name); -+#ifdef CONFIG_MODULES -+ if (!pm && capable(CAP_NET_ADMIN)) { -+ rcu_read_unlock(); -+ request_module("mptcp_%s", name); -+ rcu_read_lock(); -+ pm = mptcp_pm_find(name); -+ } -+#endif -+ return pm; -+} -+ -+void mptcp_init_path_manager(struct mptcp_cb *mpcb) -+{ -+ struct mptcp_pm_ops *pm; -+ struct sock *meta_sk = mpcb->meta_sk; -+ struct tcp_sock *meta_tp = tcp_sk(meta_sk); -+ -+ rcu_read_lock(); -+ /* if path manager was set using socket option */ -+ if (meta_tp->mptcp_pm_setsockopt) { -+ pm = __mptcp_pm_find_autoload(meta_tp->mptcp_pm_name); -+ if (pm && try_module_get(pm->owner)) { -+ mpcb->pm_ops = pm; -+ goto out; -+ } -+ } -+ -+ list_for_each_entry_rcu(pm, &mptcp_pm_list, list) { -+ if (try_module_get(pm->owner)) { -+ mpcb->pm_ops = pm; -+ break; -+ } -+ } -+out: -+ rcu_read_unlock(); -+} -+ -+/* Change path manager for socket */ -+int mptcp_set_path_manager(struct sock *sk, const char *name) -+{ -+ struct mptcp_pm_ops *pm; -+ int err = 0; -+ -+ rcu_read_lock(); -+ pm = __mptcp_pm_find_autoload(name); -+ -+ if (!pm) { -+ err = -ENOENT; -+ } else if (!ns_capable(sock_net(sk)->user_ns, CAP_NET_ADMIN)) { -+ err = -EPERM; -+ } else { -+ strcpy(tcp_sk(sk)->mptcp_pm_name, name); -+ tcp_sk(sk)->mptcp_pm_setsockopt = 1; -+ } -+ rcu_read_unlock(); -+ -+ return err; -+} -+ -+/* Manage refcounts on socket close. */ -+void mptcp_cleanup_path_manager(struct mptcp_cb *mpcb) -+{ -+ module_put(mpcb->pm_ops->owner); -+} -+ -+/* Fallback to the default path-manager. */ -+void mptcp_fallback_default(struct mptcp_cb *mpcb) -+{ -+ struct mptcp_pm_ops *pm; -+ -+ mptcp_cleanup_path_manager(mpcb); -+ pm = mptcp_pm_find("default"); -+ -+ /* Cannot fail - it's the default module */ -+ try_module_get(pm->owner); -+ mpcb->pm_ops = pm; -+} -+EXPORT_SYMBOL_GPL(mptcp_fallback_default); -+ -+/* Set default value from kernel configuration at bootup */ -+static int __init mptcp_path_manager_default(void) -+{ -+ return mptcp_set_default_path_manager(CONFIG_DEFAULT_MPTCP_PM); -+} -+late_initcall(mptcp_path_manager_default); -diff -aurN linux-4.14.174/net/mptcp/mptcp_redundant.c mptcp-mptcp_v0.94/net/mptcp/mptcp_redundant.c ---- linux-4.14.174/net/mptcp/mptcp_redundant.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_v0.94/net/mptcp/mptcp_redundant.c 2020-03-23 09:45:33.000000000 +0100 -@@ -0,0 +1,301 @@ -+/* -+ * MPTCP Scheduler to reduce latency and jitter. -+ * -+ * This scheduler sends all packets redundantly on all available subflows. -+ * -+ * Initial Design & Implementation: -+ * Tobias Erbshaeusser -+ * Alexander Froemmgen -+ * -+ * Initial corrections & modifications: -+ * Christian Pinedo -+ * Igor Lopez -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version -+ * 2 of the License, or (at your option) any later version. -+ */ -+ -+#include -+#include -+ -+/* Struct to store the data of a single subflow */ -+struct redsched_sock_data { -+ /* The skb or NULL */ -+ struct sk_buff *skb; -+ /* End sequence number of the skb. This number should be checked -+ * to be valid before the skb field is used -+ */ -+ u32 skb_end_seq; -+}; -+ -+/* Struct to store the data of the control block */ -+struct redsched_cb_data { -+ /* The next subflow where a skb should be sent or NULL */ -+ struct tcp_sock *next_subflow; -+}; -+ -+/* Returns the socket data from a given subflow socket */ -+static struct redsched_sock_data *redsched_get_sock_data(struct tcp_sock *tp) -+{ -+ return (struct redsched_sock_data *)&tp->mptcp->mptcp_sched[0]; -+} -+ -+/* Returns the control block data from a given meta socket */ -+static struct redsched_cb_data *redsched_get_cb_data(struct tcp_sock *tp) -+{ -+ return (struct redsched_cb_data *)&tp->mpcb->mptcp_sched[0]; -+} -+ -+static bool redsched_get_active_valid_sks(struct sock *meta_sk) -+{ -+ struct tcp_sock *meta_tp = tcp_sk(meta_sk); -+ struct mptcp_cb *mpcb = meta_tp->mpcb; -+ struct sock *sk; -+ int active_valid_sks = 0; -+ -+ mptcp_for_each_sk(mpcb, sk) { -+ if (subflow_is_active((struct tcp_sock *)sk) && -+ !mptcp_is_def_unavailable(sk)) -+ active_valid_sks++; -+ } -+ -+ return active_valid_sks; -+} -+ -+static bool redsched_use_subflow(struct sock *meta_sk, -+ int active_valid_sks, -+ struct tcp_sock *tp, -+ struct sk_buff *skb) -+{ -+ if (!skb || !mptcp_is_available((struct sock *)tp, skb, false)) -+ return false; -+ -+ if (TCP_SKB_CB(skb)->path_mask != 0) -+ return subflow_is_active(tp); -+ -+ if (TCP_SKB_CB(skb)->path_mask == 0) { -+ if (active_valid_sks == -1) -+ active_valid_sks = redsched_get_active_valid_sks(meta_sk); -+ -+ if (subflow_is_backup(tp) && active_valid_sks > 0) -+ return false; -+ else -+ return true; -+ } -+ -+ return false; -+} -+ -+static struct sock *redundant_get_subflow(struct sock *meta_sk, -+ struct sk_buff *skb, -+ bool zero_wnd_test) -+{ -+ struct tcp_sock *meta_tp = tcp_sk(meta_sk); -+ struct mptcp_cb *mpcb = meta_tp->mpcb; -+ struct redsched_cb_data *cb_data = redsched_get_cb_data(meta_tp); -+ struct tcp_sock *first_tp = cb_data->next_subflow; -+ struct sock *sk; -+ struct tcp_sock *tp; -+ -+ /* Answer data_fin on same subflow */ -+ if (meta_sk->sk_shutdown & RCV_SHUTDOWN && -+ skb && mptcp_is_data_fin(skb)) { -+ mptcp_for_each_sk(mpcb, sk) { -+ if (tcp_sk(sk)->mptcp->path_index == -+ mpcb->dfin_path_index && -+ mptcp_is_available(sk, skb, zero_wnd_test)) -+ return sk; -+ } -+ } -+ -+ if (!first_tp) -+ first_tp = mpcb->connection_list; -+ tp = first_tp; -+ -+ /* still NULL (no subflow in connection_list?) */ -+ if (!first_tp) -+ return NULL; -+ -+ /* Search for any subflow to send it */ -+ do { -+ if (mptcp_is_available((struct sock *)tp, skb, -+ zero_wnd_test)) { -+ cb_data->next_subflow = tp->mptcp->next; -+ return (struct sock *)tp; -+ } -+ -+ tp = tp->mptcp->next; -+ if (!tp) -+ tp = mpcb->connection_list; -+ } while (tp != first_tp); -+ -+ /* No space */ -+ return NULL; -+} -+ -+/* Corrects the stored skb pointers if they are invalid */ -+static void redsched_correct_skb_pointers(struct sock *meta_sk, -+ struct redsched_sock_data *sk_data) -+{ -+ struct tcp_sock *meta_tp = tcp_sk(meta_sk); -+ -+ if (sk_data->skb && !after(sk_data->skb_end_seq, meta_tp->snd_una)) -+ sk_data->skb = NULL; -+} -+ -+/* Returns the next skb from the queue */ -+static struct sk_buff *redundant_next_skb_from_queue(struct sk_buff_head *queue, -+ struct sk_buff *previous, -+ struct sock *meta_sk) -+{ -+ if (skb_queue_empty(queue)) -+ return NULL; -+ -+ if (!previous) -+ return skb_peek(queue); -+ -+ if (skb_queue_is_last(queue, previous)) -+ return NULL; -+ -+ /* sk_data->skb stores the last scheduled packet for this subflow. -+ * If sk_data->skb was scheduled but not sent (e.g., due to nagle), -+ * we have to schedule it again. -+ * -+ * For the redundant scheduler, there are two cases: -+ * 1. sk_data->skb was not sent on another subflow: -+ * we have to schedule it again to ensure that we do not -+ * skip this packet. -+ * 2. sk_data->skb was already sent on another subflow: -+ * with regard to the redundant semantic, we have to -+ * schedule it again. However, we keep it simple and ignore it, -+ * as it was already sent by another subflow. -+ * This might be changed in the future. -+ * -+ * For case 1, send_head is equal previous, as only a single -+ * packet can be skipped. -+ */ -+ if (tcp_send_head(meta_sk) == previous) -+ return tcp_send_head(meta_sk); -+ -+ return skb_queue_next(queue, previous); -+} -+ -+static struct sk_buff *redundant_next_segment(struct sock *meta_sk, -+ int *reinject, -+ struct sock **subsk, -+ unsigned int *limit) -+{ -+ struct tcp_sock *meta_tp = tcp_sk(meta_sk); -+ struct mptcp_cb *mpcb = meta_tp->mpcb; -+ struct redsched_cb_data *cb_data = redsched_get_cb_data(meta_tp); -+ struct tcp_sock *first_tp = cb_data->next_subflow; -+ struct tcp_sock *tp; -+ struct sk_buff *skb; -+ int active_valid_sks = -1; -+ -+ /* As we set it, we have to reset it as well. */ -+ *limit = 0; -+ -+ if (skb_queue_empty(&mpcb->reinject_queue) && -+ skb_queue_empty(&meta_sk->sk_write_queue)) -+ /* Nothing to send */ -+ return NULL; -+ -+ /* First try reinjections */ -+ skb = skb_peek(&mpcb->reinject_queue); -+ if (skb) { -+ *subsk = get_available_subflow(meta_sk, skb, false); -+ if (!*subsk) -+ return NULL; -+ *reinject = 1; -+ return skb; -+ } -+ -+ /* Then try indistinctly redundant and normal skbs */ -+ -+ if (!first_tp) -+ first_tp = mpcb->connection_list; -+ -+ /* still NULL (no subflow in connection_list?) */ -+ if (!first_tp) -+ return NULL; -+ -+ tp = first_tp; -+ -+ *reinject = 0; -+ active_valid_sks = redsched_get_active_valid_sks(meta_sk); -+ do { -+ struct redsched_sock_data *sk_data; -+ -+ /* Correct the skb pointers of the current subflow */ -+ sk_data = redsched_get_sock_data(tp); -+ redsched_correct_skb_pointers(meta_sk, sk_data); -+ -+ skb = redundant_next_skb_from_queue(&meta_sk->sk_write_queue, -+ sk_data->skb, meta_sk); -+ if (skb && redsched_use_subflow(meta_sk, active_valid_sks, tp, -+ skb)) { -+ sk_data->skb = skb; -+ sk_data->skb_end_seq = TCP_SKB_CB(skb)->end_seq; -+ cb_data->next_subflow = tp->mptcp->next; -+ *subsk = (struct sock *)tp; -+ -+ if (TCP_SKB_CB(skb)->path_mask) -+ *reinject = -1; -+ return skb; -+ } -+ -+ tp = tp->mptcp->next; -+ if (!tp) -+ tp = mpcb->connection_list; -+ } while (tp != first_tp); -+ -+ /* Nothing to send */ -+ return NULL; -+} -+ -+static void redundant_release(struct sock *sk) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct redsched_cb_data *cb_data = redsched_get_cb_data(tp); -+ -+ /* Check if the next subflow would be the released one. If yes correct -+ * the pointer -+ */ -+ if (cb_data->next_subflow == tp) -+ cb_data->next_subflow = tp->mptcp->next; -+} -+ -+static struct mptcp_sched_ops mptcp_sched_redundant = { -+ .get_subflow = redundant_get_subflow, -+ .next_segment = redundant_next_segment, -+ .release = redundant_release, -+ .name = "redundant", -+ .owner = THIS_MODULE, -+}; -+ -+static int __init redundant_register(void) -+{ -+ BUILD_BUG_ON(sizeof(struct redsched_sock_data) > MPTCP_SCHED_SIZE); -+ BUILD_BUG_ON(sizeof(struct redsched_cb_data) > MPTCP_SCHED_DATA_SIZE); -+ -+ if (mptcp_register_scheduler(&mptcp_sched_redundant)) -+ return -1; -+ -+ return 0; -+} -+ -+static void redundant_unregister(void) -+{ -+ mptcp_unregister_scheduler(&mptcp_sched_redundant); -+} -+ -+module_init(redundant_register); -+module_exit(redundant_unregister); -+ -+MODULE_AUTHOR("Tobias Erbshaeusser, Alexander Froemmgen"); -+MODULE_LICENSE("GPL"); -+MODULE_DESCRIPTION("REDUNDANT MPTCP"); -+MODULE_VERSION("0.90"); -diff -aurN linux-4.14.174/net/mptcp/mptcp_rr.c mptcp-mptcp_v0.94/net/mptcp/mptcp_rr.c ---- linux-4.14.174/net/mptcp/mptcp_rr.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_v0.94/net/mptcp/mptcp_rr.c 2020-03-23 09:45:33.000000000 +0100 -@@ -0,0 +1,301 @@ -+/* MPTCP Scheduler module selector. Highly inspired by tcp_cong.c */ -+ -+#include -+#include -+ -+static unsigned char num_segments __read_mostly = 1; -+module_param(num_segments, byte, 0644); -+MODULE_PARM_DESC(num_segments, "The number of consecutive segments that are part of a burst"); -+ -+static bool cwnd_limited __read_mostly = 1; -+module_param(cwnd_limited, bool, 0644); -+MODULE_PARM_DESC(cwnd_limited, "if set to 1, the scheduler tries to fill the congestion-window on all subflows"); -+ -+struct rrsched_priv { -+ unsigned char quota; -+}; -+ -+static struct rrsched_priv *rrsched_get_priv(const struct tcp_sock *tp) -+{ -+ return (struct rrsched_priv *)&tp->mptcp->mptcp_sched[0]; -+} -+ -+/* If the sub-socket sk available to send the skb? */ -+static bool mptcp_rr_is_available(const struct sock *sk, const struct sk_buff *skb, -+ bool zero_wnd_test, bool cwnd_test) -+{ -+ const struct tcp_sock *tp = tcp_sk(sk); -+ unsigned int space, in_flight; -+ -+ /* Set of states for which we are allowed to send data */ -+ if (!mptcp_sk_can_send(sk)) -+ return false; -+ -+ /* We do not send data on this subflow unless it is -+ * fully established, i.e. the 4th ack has been received. -+ */ -+ if (tp->mptcp->pre_established) -+ return false; -+ -+ if (tp->pf) -+ return false; -+ -+ if (inet_csk(sk)->icsk_ca_state == TCP_CA_Loss) { -+ /* If SACK is disabled, and we got a loss, TCP does not exit -+ * the loss-state until something above high_seq has been acked. -+ * (see tcp_try_undo_recovery) -+ * -+ * high_seq is the snd_nxt at the moment of the RTO. As soon -+ * as we have an RTO, we won't push data on the subflow. -+ * Thus, snd_una can never go beyond high_seq. -+ */ -+ if (!tcp_is_reno(tp)) -+ return false; -+ else if (tp->snd_una != tp->high_seq) -+ return false; -+ } -+ -+ if (!tp->mptcp->fully_established) { -+ /* Make sure that we send in-order data */ -+ if (skb && tp->mptcp->second_packet && -+ tp->mptcp->last_end_data_seq != TCP_SKB_CB(skb)->seq) -+ return false; -+ } -+ -+ if (!cwnd_test) -+ goto zero_wnd_test; -+ -+ in_flight = tcp_packets_in_flight(tp); -+ /* Not even a single spot in the cwnd */ -+ if (in_flight >= tp->snd_cwnd) -+ return false; -+ -+ /* Now, check if what is queued in the subflow's send-queue -+ * already fills the cwnd. -+ */ -+ space = (tp->snd_cwnd - in_flight) * tp->mss_cache; -+ -+ if (tp->write_seq - tp->snd_nxt > space) -+ return false; -+ -+zero_wnd_test: -+ if (zero_wnd_test && !before(tp->write_seq, tcp_wnd_end(tp))) -+ return false; -+ -+ return true; -+} -+ -+/* Are we not allowed to reinject this skb on tp? */ -+static int mptcp_rr_dont_reinject_skb(const struct tcp_sock *tp, const struct sk_buff *skb) -+{ -+ /* If the skb has already been enqueued in this sk, try to find -+ * another one. -+ */ -+ return skb && -+ /* Has the skb already been enqueued into this subsocket? */ -+ mptcp_pi_to_flag(tp->mptcp->path_index) & TCP_SKB_CB(skb)->path_mask; -+} -+ -+/* We just look for any subflow that is available */ -+static struct sock *rr_get_available_subflow(struct sock *meta_sk, -+ struct sk_buff *skb, -+ bool zero_wnd_test) -+{ -+ const struct mptcp_cb *mpcb = tcp_sk(meta_sk)->mpcb; -+ struct sock *sk, *bestsk = NULL, *backupsk = NULL; -+ -+ /* Answer data_fin on same subflow!!! */ -+ if (meta_sk->sk_shutdown & RCV_SHUTDOWN && -+ skb && mptcp_is_data_fin(skb)) { -+ mptcp_for_each_sk(mpcb, sk) { -+ if (tcp_sk(sk)->mptcp->path_index == mpcb->dfin_path_index && -+ mptcp_rr_is_available(sk, skb, zero_wnd_test, true)) -+ return sk; -+ } -+ } -+ -+ /* First, find the best subflow */ -+ mptcp_for_each_sk(mpcb, sk) { -+ struct tcp_sock *tp = tcp_sk(sk); -+ -+ if (!mptcp_rr_is_available(sk, skb, zero_wnd_test, true)) -+ continue; -+ -+ if (mptcp_rr_dont_reinject_skb(tp, skb)) { -+ backupsk = sk; -+ continue; -+ } -+ -+ bestsk = sk; -+ } -+ -+ if (bestsk) { -+ sk = bestsk; -+ } else if (backupsk) { -+ /* It has been sent on all subflows once - let's give it a -+ * chance again by restarting its pathmask. -+ */ -+ if (skb) -+ TCP_SKB_CB(skb)->path_mask = 0; -+ sk = backupsk; -+ } -+ -+ return sk; -+} -+ -+/* Returns the next segment to be sent from the mptcp meta-queue. -+ * (chooses the reinject queue if any segment is waiting in it, otherwise, -+ * chooses the normal write queue). -+ * Sets *@reinject to 1 if the returned segment comes from the -+ * reinject queue. Sets it to 0 if it is the regular send-head of the meta-sk, -+ * and sets it to -1 if it is a meta-level retransmission to optimize the -+ * receive-buffer. -+ */ -+static struct sk_buff *__mptcp_rr_next_segment(const struct sock *meta_sk, int *reinject) -+{ -+ const struct mptcp_cb *mpcb = tcp_sk(meta_sk)->mpcb; -+ struct sk_buff *skb = NULL; -+ -+ *reinject = 0; -+ -+ /* If we are in fallback-mode, just take from the meta-send-queue */ -+ if (mpcb->infinite_mapping_snd || mpcb->send_infinite_mapping) -+ return tcp_send_head(meta_sk); -+ -+ skb = skb_peek(&mpcb->reinject_queue); -+ -+ if (skb) -+ *reinject = 1; -+ else -+ skb = tcp_send_head(meta_sk); -+ return skb; -+} -+ -+static struct sk_buff *mptcp_rr_next_segment(struct sock *meta_sk, -+ int *reinject, -+ struct sock **subsk, -+ unsigned int *limit) -+{ -+ const struct mptcp_cb *mpcb = tcp_sk(meta_sk)->mpcb; -+ struct sock *sk_it, *choose_sk = NULL; -+ struct sk_buff *skb = __mptcp_rr_next_segment(meta_sk, reinject); -+ unsigned char split = num_segments; -+ unsigned char iter = 0, full_subs = 0; -+ -+ /* As we set it, we have to reset it as well. */ -+ *limit = 0; -+ -+ if (!skb) -+ return NULL; -+ -+ if (*reinject) { -+ *subsk = rr_get_available_subflow(meta_sk, skb, false); -+ if (!*subsk) -+ return NULL; -+ -+ return skb; -+ } -+ -+retry: -+ -+ /* First, we look for a subflow who is currently being used */ -+ mptcp_for_each_sk(mpcb, sk_it) { -+ struct tcp_sock *tp_it = tcp_sk(sk_it); -+ struct rrsched_priv *rsp = rrsched_get_priv(tp_it); -+ -+ if (!mptcp_rr_is_available(sk_it, skb, false, cwnd_limited)) -+ continue; -+ -+ iter++; -+ -+ /* Is this subflow currently being used? */ -+ if (rsp->quota > 0 && rsp->quota < num_segments) { -+ split = num_segments - rsp->quota; -+ choose_sk = sk_it; -+ goto found; -+ } -+ -+ /* Or, it's totally unused */ -+ if (!rsp->quota) { -+ split = num_segments; -+ choose_sk = sk_it; -+ } -+ -+ /* Or, it must then be fully used */ -+ if (rsp->quota >= num_segments) -+ full_subs++; -+ } -+ -+ /* All considered subflows have a full quota, and we considered at -+ * least one. -+ */ -+ if (iter && iter == full_subs) { -+ /* So, we restart this round by setting quota to 0 and retry -+ * to find a subflow. -+ */ -+ mptcp_for_each_sk(mpcb, sk_it) { -+ struct tcp_sock *tp_it = tcp_sk(sk_it); -+ struct rrsched_priv *rsp = rrsched_get_priv(tp_it); -+ -+ if (!mptcp_rr_is_available(sk_it, skb, false, cwnd_limited)) -+ continue; -+ -+ rsp->quota = 0; -+ } -+ -+ goto retry; -+ } -+ -+found: -+ if (choose_sk) { -+ unsigned int mss_now; -+ struct tcp_sock *choose_tp = tcp_sk(choose_sk); -+ struct rrsched_priv *rsp = rrsched_get_priv(choose_tp); -+ -+ if (!mptcp_rr_is_available(choose_sk, skb, false, true)) -+ return NULL; -+ -+ *subsk = choose_sk; -+ mss_now = tcp_current_mss(*subsk); -+ *limit = split * mss_now; -+ -+ if (skb->len > mss_now) -+ rsp->quota += DIV_ROUND_UP(skb->len, mss_now); -+ else -+ rsp->quota++; -+ -+ return skb; -+ } -+ -+ return NULL; -+} -+ -+static struct mptcp_sched_ops mptcp_sched_rr = { -+ .get_subflow = rr_get_available_subflow, -+ .next_segment = mptcp_rr_next_segment, -+ .name = "roundrobin", -+ .owner = THIS_MODULE, -+}; -+ -+static int __init rr_register(void) -+{ -+ BUILD_BUG_ON(sizeof(struct rrsched_priv) > MPTCP_SCHED_SIZE); -+ -+ if (mptcp_register_scheduler(&mptcp_sched_rr)) -+ return -1; -+ -+ return 0; -+} -+ -+static void rr_unregister(void) -+{ -+ mptcp_unregister_scheduler(&mptcp_sched_rr); -+} -+ -+module_init(rr_register); -+module_exit(rr_unregister); -+ -+MODULE_AUTHOR("Christoph Paasch"); -+MODULE_LICENSE("GPL"); -+MODULE_DESCRIPTION("ROUNDROBIN MPTCP"); -+MODULE_VERSION("0.89"); -diff -aurN linux-4.14.174/net/mptcp/mptcp_sched.c mptcp-mptcp_v0.94/net/mptcp/mptcp_sched.c ---- linux-4.14.174/net/mptcp/mptcp_sched.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_v0.94/net/mptcp/mptcp_sched.c 2020-03-23 09:45:33.000000000 +0100 -@@ -0,0 +1,633 @@ -+/* MPTCP Scheduler module selector. Highly inspired by tcp_cong.c */ -+ -+#include -+#include -+ -+static DEFINE_SPINLOCK(mptcp_sched_list_lock); -+static LIST_HEAD(mptcp_sched_list); -+ -+struct defsched_priv { -+ u32 last_rbuf_opti; -+}; -+ -+static struct defsched_priv *defsched_get_priv(const struct tcp_sock *tp) -+{ -+ return (struct defsched_priv *)&tp->mptcp->mptcp_sched[0]; -+} -+ -+bool mptcp_is_def_unavailable(struct sock *sk) -+{ -+ const struct tcp_sock *tp = tcp_sk(sk); -+ -+ /* Set of states for which we are allowed to send data */ -+ if (!mptcp_sk_can_send(sk)) -+ return true; -+ -+ /* We do not send data on this subflow unless it is -+ * fully established, i.e. the 4th ack has been received. -+ */ -+ if (tp->mptcp->pre_established) -+ return true; -+ -+ if (tp->pf) -+ return true; -+ -+ return false; -+} -+EXPORT_SYMBOL_GPL(mptcp_is_def_unavailable); -+ -+static bool mptcp_is_temp_unavailable(struct sock *sk, -+ const struct sk_buff *skb, -+ bool zero_wnd_test) -+{ -+ const struct tcp_sock *tp = tcp_sk(sk); -+ unsigned int mss_now, space, in_flight; -+ -+ if (inet_csk(sk)->icsk_ca_state == TCP_CA_Loss) { -+ /* If SACK is disabled, and we got a loss, TCP does not exit -+ * the loss-state until something above high_seq has been -+ * acked. (see tcp_try_undo_recovery) -+ * -+ * high_seq is the snd_nxt at the moment of the RTO. As soon -+ * as we have an RTO, we won't push data on the subflow. -+ * Thus, snd_una can never go beyond high_seq. -+ */ -+ if (!tcp_is_reno(tp)) -+ return true; -+ else if (tp->snd_una != tp->high_seq) -+ return true; -+ } -+ -+ if (!tp->mptcp->fully_established) { -+ /* Make sure that we send in-order data */ -+ if (skb && tp->mptcp->second_packet && -+ tp->mptcp->last_end_data_seq != TCP_SKB_CB(skb)->seq) -+ return true; -+ } -+ -+ in_flight = tcp_packets_in_flight(tp); -+ /* Not even a single spot in the cwnd */ -+ if (in_flight >= tp->snd_cwnd) -+ return true; -+ -+ /* Now, check if what is queued in the subflow's send-queue -+ * already fills the cwnd. -+ */ -+ space = (tp->snd_cwnd - in_flight) * tp->mss_cache; -+ -+ if (tp->write_seq - tp->snd_nxt > space) -+ return true; -+ -+ if (zero_wnd_test && !before(tp->write_seq, tcp_wnd_end(tp))) -+ return true; -+ -+ mss_now = tcp_current_mss(sk); -+ -+ /* Don't send on this subflow if we bypass the allowed send-window at -+ * the per-subflow level. Similar to tcp_snd_wnd_test, but manually -+ * calculated end_seq (because here at this point end_seq is still at -+ * the meta-level). -+ */ -+ if (skb && zero_wnd_test && -+ after(tp->write_seq + min(skb->len, mss_now), tcp_wnd_end(tp))) -+ return true; -+ -+ return false; -+} -+ -+/* Is the sub-socket sk available to send the skb? */ -+bool mptcp_is_available(struct sock *sk, const struct sk_buff *skb, -+ bool zero_wnd_test) -+{ -+ return !mptcp_is_def_unavailable(sk) && -+ !mptcp_is_temp_unavailable(sk, skb, zero_wnd_test); -+} -+EXPORT_SYMBOL_GPL(mptcp_is_available); -+ -+/* Are we not allowed to reinject this skb on tp? */ -+static int mptcp_dont_reinject_skb(const struct tcp_sock *tp, const struct sk_buff *skb) -+{ -+ /* If the skb has already been enqueued in this sk, try to find -+ * another one. -+ */ -+ return skb && -+ /* Has the skb already been enqueued into this subsocket? */ -+ mptcp_pi_to_flag(tp->mptcp->path_index) & TCP_SKB_CB(skb)->path_mask; -+} -+ -+bool subflow_is_backup(const struct tcp_sock *tp) -+{ -+ return tp->mptcp->rcv_low_prio || tp->mptcp->low_prio; -+} -+EXPORT_SYMBOL_GPL(subflow_is_backup); -+ -+bool subflow_is_active(const struct tcp_sock *tp) -+{ -+ return !tp->mptcp->rcv_low_prio && !tp->mptcp->low_prio; -+} -+EXPORT_SYMBOL_GPL(subflow_is_active); -+ -+/* Generic function to iterate over used and unused subflows and to select the -+ * best one -+ */ -+static struct sock -+*get_subflow_from_selectors(struct mptcp_cb *mpcb, struct sk_buff *skb, -+ bool (*selector)(const struct tcp_sock *), -+ bool zero_wnd_test, bool *force) -+{ -+ struct sock *bestsk = NULL; -+ u32 min_srtt = 0xffffffff; -+ bool found_unused = false; -+ bool found_unused_una = false; -+ struct sock *sk; -+ -+ mptcp_for_each_sk(mpcb, sk) { -+ struct tcp_sock *tp = tcp_sk(sk); -+ bool unused = false; -+ -+ /* First, we choose only the wanted sks */ -+ if (!(*selector)(tp)) -+ continue; -+ -+ if (!mptcp_dont_reinject_skb(tp, skb)) -+ unused = true; -+ else if (found_unused) -+ /* If a unused sk was found previously, we continue - -+ * no need to check used sks anymore. -+ */ -+ continue; -+ -+ if (mptcp_is_def_unavailable(sk)) -+ continue; -+ -+ if (mptcp_is_temp_unavailable(sk, skb, zero_wnd_test)) { -+ if (unused) -+ found_unused_una = true; -+ continue; -+ } -+ -+ if (unused) { -+ if (!found_unused) { -+ /* It's the first time we encounter an unused -+ * sk - thus we reset the bestsk (which might -+ * have been set to a used sk). -+ */ -+ min_srtt = 0xffffffff; -+ bestsk = NULL; -+ } -+ found_unused = true; -+ } -+ -+ if (tp->srtt_us < min_srtt) { -+ min_srtt = tp->srtt_us; -+ bestsk = sk; -+ } -+ } -+ -+ if (bestsk) { -+ /* The force variable is used to mark the returned sk as -+ * previously used or not-used. -+ */ -+ if (found_unused) -+ *force = true; -+ else -+ *force = false; -+ } else { -+ /* The force variable is used to mark if there are temporally -+ * unavailable not-used sks. -+ */ -+ if (found_unused_una) -+ *force = true; -+ else -+ *force = false; -+ } -+ -+ return bestsk; -+} -+ -+/* This is the scheduler. This function decides on which flow to send -+ * a given MSS. If all subflows are found to be busy, NULL is returned -+ * The flow is selected based on the shortest RTT. -+ * If all paths have full cong windows, we simply return NULL. -+ * -+ * Additionally, this function is aware of the backup-subflows. -+ */ -+struct sock *get_available_subflow(struct sock *meta_sk, struct sk_buff *skb, -+ bool zero_wnd_test) -+{ -+ struct mptcp_cb *mpcb = tcp_sk(meta_sk)->mpcb; -+ struct sock *sk; -+ bool looping = false, force; -+ -+ /* if there is only one subflow, bypass the scheduling function */ -+ if (mpcb->cnt_subflows == 1) { -+ sk = (struct sock *)mpcb->connection_list; -+ if (!mptcp_is_available(sk, skb, zero_wnd_test)) -+ sk = NULL; -+ return sk; -+ } -+ -+ /* Answer data_fin on same subflow!!! */ -+ if (meta_sk->sk_shutdown & RCV_SHUTDOWN && -+ skb && mptcp_is_data_fin(skb)) { -+ mptcp_for_each_sk(mpcb, sk) { -+ if (tcp_sk(sk)->mptcp->path_index == mpcb->dfin_path_index && -+ mptcp_is_available(sk, skb, zero_wnd_test)) -+ return sk; -+ } -+ } -+ -+ /* Find the best subflow */ -+restart: -+ sk = get_subflow_from_selectors(mpcb, skb, &subflow_is_active, -+ zero_wnd_test, &force); -+ if (force) -+ /* one unused active sk or one NULL sk when there is at least -+ * one temporally unavailable unused active sk -+ */ -+ return sk; -+ -+ sk = get_subflow_from_selectors(mpcb, skb, &subflow_is_backup, -+ zero_wnd_test, &force); -+ if (!force && skb) { -+ /* one used backup sk or one NULL sk where there is no one -+ * temporally unavailable unused backup sk -+ * -+ * the skb passed through all the available active and backups -+ * sks, so clean the path mask -+ */ -+ TCP_SKB_CB(skb)->path_mask = 0; -+ -+ if (!looping) { -+ looping = true; -+ goto restart; -+ } -+ } -+ return sk; -+} -+EXPORT_SYMBOL_GPL(get_available_subflow); -+ -+static struct sk_buff *mptcp_rcv_buf_optimization(struct sock *sk, int penal) -+{ -+ struct sock *meta_sk; -+ const struct tcp_sock *tp = tcp_sk(sk); -+ struct tcp_sock *tp_it; -+ struct sk_buff *skb_head; -+ struct defsched_priv *dsp = defsched_get_priv(tp); -+ -+ if (tp->mpcb->cnt_subflows == 1) -+ return NULL; -+ -+ meta_sk = mptcp_meta_sk(sk); -+ skb_head = tcp_write_queue_head(meta_sk); -+ -+ if (!skb_head || skb_head == tcp_send_head(meta_sk)) -+ return NULL; -+ -+ /* If penalization is optional (coming from mptcp_next_segment() and -+ * We are not send-buffer-limited we do not penalize. The retransmission -+ * is just an optimization to fix the idle-time due to the delay before -+ * we wake up the application. -+ */ -+ if (!penal && sk_stream_memory_free(meta_sk)) -+ goto retrans; -+ -+ /* Only penalize again after an RTT has elapsed */ -+ if (tcp_jiffies32 - dsp->last_rbuf_opti < usecs_to_jiffies(tp->srtt_us >> 3)) -+ goto retrans; -+ -+ /* Half the cwnd of the slow flows */ -+ mptcp_for_each_tp(tp->mpcb, tp_it) { -+ if (tp_it != tp && -+ TCP_SKB_CB(skb_head)->path_mask & mptcp_pi_to_flag(tp_it->mptcp->path_index)) { -+ if (tp->srtt_us < tp_it->srtt_us && inet_csk((struct sock *)tp_it)->icsk_ca_state == TCP_CA_Open) { -+ u32 prior_cwnd = tp_it->snd_cwnd; -+ -+ tp_it->snd_cwnd = max(tp_it->snd_cwnd >> 1U, 1U); -+ -+ /* If in slow start, do not reduce the ssthresh */ -+ if (prior_cwnd >= tp_it->snd_ssthresh) -+ tp_it->snd_ssthresh = max(tp_it->snd_ssthresh >> 1U, 2U); -+ -+ dsp->last_rbuf_opti = tcp_jiffies32; -+ } -+ } -+ } -+ -+retrans: -+ -+ /* Segment not yet injected into this path? Take it!!! */ -+ if (!(TCP_SKB_CB(skb_head)->path_mask & mptcp_pi_to_flag(tp->mptcp->path_index))) { -+ bool do_retrans = false; -+ mptcp_for_each_tp(tp->mpcb, tp_it) { -+ if (tp_it != tp && -+ TCP_SKB_CB(skb_head)->path_mask & mptcp_pi_to_flag(tp_it->mptcp->path_index)) { -+ if (tp_it->snd_cwnd <= 4) { -+ do_retrans = true; -+ break; -+ } -+ -+ if (4 * tp->srtt_us >= tp_it->srtt_us) { -+ do_retrans = false; -+ break; -+ } else { -+ do_retrans = true; -+ } -+ } -+ } -+ -+ if (do_retrans && mptcp_is_available(sk, skb_head, false)) -+ return skb_head; -+ } -+ return NULL; -+} -+ -+/* Returns the next segment to be sent from the mptcp meta-queue. -+ * (chooses the reinject queue if any segment is waiting in it, otherwise, -+ * chooses the normal write queue). -+ * Sets *@reinject to 1 if the returned segment comes from the -+ * reinject queue. Sets it to 0 if it is the regular send-head of the meta-sk, -+ * and sets it to -1 if it is a meta-level retransmission to optimize the -+ * receive-buffer. -+ */ -+static struct sk_buff *__mptcp_next_segment(struct sock *meta_sk, int *reinject) -+{ -+ const struct mptcp_cb *mpcb = tcp_sk(meta_sk)->mpcb; -+ struct sk_buff *skb = NULL; -+ -+ *reinject = 0; -+ -+ /* If we are in fallback-mode, just take from the meta-send-queue */ -+ if (mpcb->infinite_mapping_snd || mpcb->send_infinite_mapping) -+ return tcp_send_head(meta_sk); -+ -+ skb = skb_peek(&mpcb->reinject_queue); -+ -+ if (skb) { -+ *reinject = 1; -+ } else { -+ skb = tcp_send_head(meta_sk); -+ -+ if (!skb && meta_sk->sk_socket && -+ test_bit(SOCK_NOSPACE, &meta_sk->sk_socket->flags) && -+ sk_stream_wspace(meta_sk) < sk_stream_min_wspace(meta_sk)) { -+ struct sock *subsk = get_available_subflow(meta_sk, NULL, -+ false); -+ if (!subsk) -+ return NULL; -+ -+ skb = mptcp_rcv_buf_optimization(subsk, 0); -+ if (skb) -+ *reinject = -1; -+ } -+ } -+ return skb; -+} -+ -+static struct sk_buff *mptcp_next_segment(struct sock *meta_sk, -+ int *reinject, -+ struct sock **subsk, -+ unsigned int *limit) -+{ -+ struct sk_buff *skb = __mptcp_next_segment(meta_sk, reinject); -+ unsigned int mss_now; -+ struct tcp_sock *subtp; -+ u16 gso_max_segs; -+ u32 max_len, max_segs, window, needed; -+ -+ /* As we set it, we have to reset it as well. */ -+ *limit = 0; -+ -+ if (!skb) -+ return NULL; -+ -+ *subsk = get_available_subflow(meta_sk, skb, false); -+ if (!*subsk) -+ return NULL; -+ -+ subtp = tcp_sk(*subsk); -+ mss_now = tcp_current_mss(*subsk); -+ -+ if (!*reinject && unlikely(!tcp_snd_wnd_test(tcp_sk(meta_sk), skb, mss_now))) { -+ skb = mptcp_rcv_buf_optimization(*subsk, 1); -+ if (skb) -+ *reinject = -1; -+ else -+ return NULL; -+ } -+ -+ /* No splitting required, as we will only send one single segment */ -+ if (skb->len <= mss_now) -+ return skb; -+ -+ /* The following is similar to tcp_mss_split_point, but -+ * we do not care about nagle, because we will anyways -+ * use TCP_NAGLE_PUSH, which overrides this. -+ * -+ * So, we first limit according to the cwnd/gso-size and then according -+ * to the subflow's window. -+ */ -+ -+ gso_max_segs = (*subsk)->sk_gso_max_segs; -+ if (!gso_max_segs) /* No gso supported on the subflow's NIC */ -+ gso_max_segs = 1; -+ max_segs = min_t(unsigned int, tcp_cwnd_test(subtp, skb), gso_max_segs); -+ if (!max_segs) -+ return NULL; -+ -+ max_len = mss_now * max_segs; -+ window = tcp_wnd_end(subtp) - subtp->write_seq; -+ -+ needed = min(skb->len, window); -+ if (max_len <= skb->len) -+ /* Take max_win, which is actually the cwnd/gso-size */ -+ *limit = max_len; -+ else -+ /* Or, take the window */ -+ *limit = needed; -+ -+ return skb; -+} -+ -+static void defsched_init(struct sock *sk) -+{ -+ struct defsched_priv *dsp = defsched_get_priv(tcp_sk(sk)); -+ -+ dsp->last_rbuf_opti = tcp_jiffies32; -+} -+ -+struct mptcp_sched_ops mptcp_sched_default = { -+ .get_subflow = get_available_subflow, -+ .next_segment = mptcp_next_segment, -+ .init = defsched_init, -+ .name = "default", -+ .owner = THIS_MODULE, -+}; -+ -+static struct mptcp_sched_ops *mptcp_sched_find(const char *name) -+{ -+ struct mptcp_sched_ops *e; -+ -+ list_for_each_entry_rcu(e, &mptcp_sched_list, list) { -+ if (strcmp(e->name, name) == 0) -+ return e; -+ } -+ -+ return NULL; -+} -+ -+int mptcp_register_scheduler(struct mptcp_sched_ops *sched) -+{ -+ int ret = 0; -+ -+ if (!sched->get_subflow || !sched->next_segment) -+ return -EINVAL; -+ -+ spin_lock(&mptcp_sched_list_lock); -+ if (mptcp_sched_find(sched->name)) { -+ pr_notice("%s already registered\n", sched->name); -+ ret = -EEXIST; -+ } else { -+ list_add_tail_rcu(&sched->list, &mptcp_sched_list); -+ pr_info("%s registered\n", sched->name); -+ } -+ spin_unlock(&mptcp_sched_list_lock); -+ -+ return ret; -+} -+EXPORT_SYMBOL_GPL(mptcp_register_scheduler); -+ -+void mptcp_unregister_scheduler(struct mptcp_sched_ops *sched) -+{ -+ spin_lock(&mptcp_sched_list_lock); -+ list_del_rcu(&sched->list); -+ spin_unlock(&mptcp_sched_list_lock); -+ -+ /* Wait for outstanding readers to complete before the -+ * module gets removed entirely. -+ * -+ * A try_module_get() should fail by now as our module is -+ * in "going" state since no refs are held anymore and -+ * module_exit() handler being called. -+ */ -+ synchronize_rcu(); -+} -+EXPORT_SYMBOL_GPL(mptcp_unregister_scheduler); -+ -+void mptcp_get_default_scheduler(char *name) -+{ -+ struct mptcp_sched_ops *sched; -+ -+ BUG_ON(list_empty(&mptcp_sched_list)); -+ -+ rcu_read_lock(); -+ sched = list_entry(mptcp_sched_list.next, struct mptcp_sched_ops, list); -+ strncpy(name, sched->name, MPTCP_SCHED_NAME_MAX); -+ rcu_read_unlock(); -+} -+ -+int mptcp_set_default_scheduler(const char *name) -+{ -+ struct mptcp_sched_ops *sched; -+ int ret = -ENOENT; -+ -+ spin_lock(&mptcp_sched_list_lock); -+ sched = mptcp_sched_find(name); -+#ifdef CONFIG_MODULES -+ if (!sched && capable(CAP_NET_ADMIN)) { -+ spin_unlock(&mptcp_sched_list_lock); -+ -+ request_module("mptcp_%s", name); -+ spin_lock(&mptcp_sched_list_lock); -+ sched = mptcp_sched_find(name); -+ } -+#endif -+ -+ if (sched) { -+ list_move(&sched->list, &mptcp_sched_list); -+ ret = 0; -+ } else { -+ pr_info("%s is not available\n", name); -+ } -+ spin_unlock(&mptcp_sched_list_lock); -+ -+ return ret; -+} -+ -+/* Must be called with rcu lock held */ -+static struct mptcp_sched_ops *__mptcp_sched_find_autoload(const char *name) -+{ -+ struct mptcp_sched_ops *sched = mptcp_sched_find(name); -+#ifdef CONFIG_MODULES -+ if (!sched && capable(CAP_NET_ADMIN)) { -+ rcu_read_unlock(); -+ request_module("mptcp_%s", name); -+ rcu_read_lock(); -+ sched = mptcp_sched_find(name); -+ } -+#endif -+ return sched; -+} -+ -+void mptcp_init_scheduler(struct mptcp_cb *mpcb) -+{ -+ struct mptcp_sched_ops *sched; -+ struct sock *meta_sk = mpcb->meta_sk; -+ struct tcp_sock *meta_tp = tcp_sk(meta_sk); -+ -+ rcu_read_lock(); -+ /* if scheduler was set using socket option */ -+ if (meta_tp->mptcp_sched_setsockopt) { -+ sched = __mptcp_sched_find_autoload(meta_tp->mptcp_sched_name); -+ if (sched && try_module_get(sched->owner)) { -+ mpcb->sched_ops = sched; -+ goto out; -+ } -+ } -+ -+ list_for_each_entry_rcu(sched, &mptcp_sched_list, list) { -+ if (try_module_get(sched->owner)) { -+ mpcb->sched_ops = sched; -+ break; -+ } -+ } -+out: -+ rcu_read_unlock(); -+} -+ -+/* Change scheduler for socket */ -+int mptcp_set_scheduler(struct sock *sk, const char *name) -+{ -+ struct mptcp_sched_ops *sched; -+ int err = 0; -+ -+ rcu_read_lock(); -+ sched = __mptcp_sched_find_autoload(name); -+ -+ if (!sched) { -+ err = -ENOENT; -+ } else if (!ns_capable(sock_net(sk)->user_ns, CAP_NET_ADMIN)) { -+ err = -EPERM; -+ } else { -+ strcpy(tcp_sk(sk)->mptcp_sched_name, name); -+ tcp_sk(sk)->mptcp_sched_setsockopt = 1; -+ } -+ rcu_read_unlock(); -+ -+ return err; -+} -+ -+/* Manage refcounts on socket close. */ -+void mptcp_cleanup_scheduler(struct mptcp_cb *mpcb) -+{ -+ module_put(mpcb->sched_ops->owner); -+} -+ -+/* Set default value from kernel configuration at bootup */ -+static int __init mptcp_scheduler_default(void) -+{ -+ BUILD_BUG_ON(sizeof(struct defsched_priv) > MPTCP_SCHED_SIZE); -+ -+ return mptcp_set_default_scheduler(CONFIG_DEFAULT_MPTCP_SCHED); -+} -+late_initcall(mptcp_scheduler_default); -diff -aurN linux-4.14.174/net/mptcp/mptcp_wvegas.c mptcp-mptcp_v0.94/net/mptcp/mptcp_wvegas.c ---- linux-4.14.174/net/mptcp/mptcp_wvegas.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_v0.94/net/mptcp/mptcp_wvegas.c 2020-03-23 09:45:33.000000000 +0100 -@@ -0,0 +1,270 @@ -+/* -+ * MPTCP implementation - WEIGHTED VEGAS -+ * -+ * Algorithm design: -+ * Yu Cao -+ * Mingwei Xu -+ * Xiaoming Fu -+ * -+ * Implementation: -+ * Yu Cao -+ * Enhuan Dong -+ * -+ * Ported to the official MPTCP-kernel: -+ * Christoph Paasch -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version -+ * 2 of the License, or (at your option) any later version. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+static int initial_alpha = 2; -+static int total_alpha = 10; -+static int gamma = 1; -+ -+module_param(initial_alpha, int, 0644); -+MODULE_PARM_DESC(initial_alpha, "initial alpha for all subflows"); -+module_param(total_alpha, int, 0644); -+MODULE_PARM_DESC(total_alpha, "total alpha for all subflows"); -+module_param(gamma, int, 0644); -+MODULE_PARM_DESC(gamma, "limit on increase (scale by 2)"); -+ -+#define MPTCP_WVEGAS_SCALE 16 -+ -+/* wVegas variables */ -+struct wvegas { -+ u32 beg_snd_nxt; /* right edge during last RTT */ -+ u8 doing_wvegas_now;/* if true, do wvegas for this RTT */ -+ -+ u16 cnt_rtt; /* # of RTTs measured within last RTT */ -+ u32 sampled_rtt; /* cumulative RTTs measured within last RTT (in usec) */ -+ u32 base_rtt; /* the min of all wVegas RTT measurements seen (in usec) */ -+ -+ u64 instant_rate; /* cwnd / srtt_us, unit: pkts/us * 2^16 */ -+ u64 weight; /* the ratio of subflow's rate to the total rate, * 2^16 */ -+ int alpha; /* alpha for each subflows */ -+ -+ u32 queue_delay; /* queue delay*/ -+}; -+ -+ -+static inline u64 mptcp_wvegas_scale(u32 val, int scale) -+{ -+ return (u64) val << scale; -+} -+ -+static void wvegas_enable(const struct sock *sk) -+{ -+ const struct tcp_sock *tp = tcp_sk(sk); -+ struct wvegas *wvegas = inet_csk_ca(sk); -+ -+ wvegas->doing_wvegas_now = 1; -+ -+ wvegas->beg_snd_nxt = tp->snd_nxt; -+ -+ wvegas->cnt_rtt = 0; -+ wvegas->sampled_rtt = 0; -+ -+ wvegas->instant_rate = 0; -+ wvegas->alpha = initial_alpha; -+ wvegas->weight = mptcp_wvegas_scale(1, MPTCP_WVEGAS_SCALE); -+ -+ wvegas->queue_delay = 0; -+} -+ -+static inline void wvegas_disable(const struct sock *sk) -+{ -+ struct wvegas *wvegas = inet_csk_ca(sk); -+ -+ wvegas->doing_wvegas_now = 0; -+} -+ -+static void mptcp_wvegas_init(struct sock *sk) -+{ -+ struct wvegas *wvegas = inet_csk_ca(sk); -+ -+ wvegas->base_rtt = 0x7fffffff; -+ wvegas_enable(sk); -+} -+ -+static inline u64 mptcp_wvegas_rate(u32 cwnd, u32 rtt_us) -+{ -+ return div_u64(mptcp_wvegas_scale(cwnd, MPTCP_WVEGAS_SCALE), rtt_us); -+} -+ -+static void mptcp_wvegas_pkts_acked(struct sock *sk, -+ const struct ack_sample *sample) -+{ -+ struct wvegas *wvegas = inet_csk_ca(sk); -+ u32 vrtt; -+ -+ if (sample->rtt_us < 0) -+ return; -+ -+ vrtt = sample->rtt_us + 1; -+ -+ if (vrtt < wvegas->base_rtt) -+ wvegas->base_rtt = vrtt; -+ -+ wvegas->sampled_rtt += vrtt; -+ wvegas->cnt_rtt++; -+} -+ -+static void mptcp_wvegas_state(struct sock *sk, u8 ca_state) -+{ -+ if (ca_state == TCP_CA_Open) -+ wvegas_enable(sk); -+ else -+ wvegas_disable(sk); -+} -+ -+static void mptcp_wvegas_cwnd_event(struct sock *sk, enum tcp_ca_event event) -+{ -+ if (event == CA_EVENT_CWND_RESTART) { -+ mptcp_wvegas_init(sk); -+ } else if (event == CA_EVENT_LOSS) { -+ struct wvegas *wvegas = inet_csk_ca(sk); -+ wvegas->instant_rate = 0; -+ } -+} -+ -+static inline u32 mptcp_wvegas_ssthresh(const struct tcp_sock *tp) -+{ -+ return min(tp->snd_ssthresh, tp->snd_cwnd); -+} -+ -+static u64 mptcp_wvegas_weight(const struct mptcp_cb *mpcb, const struct sock *sk) -+{ -+ u64 total_rate = 0; -+ struct sock *sub_sk; -+ const struct wvegas *wvegas = inet_csk_ca(sk); -+ -+ if (!mpcb) -+ return wvegas->weight; -+ -+ -+ mptcp_for_each_sk(mpcb, sub_sk) { -+ struct wvegas *sub_wvegas = inet_csk_ca(sub_sk); -+ -+ /* sampled_rtt is initialized by 0 */ -+ if (mptcp_sk_can_send(sub_sk) && (sub_wvegas->sampled_rtt > 0)) -+ total_rate += sub_wvegas->instant_rate; -+ } -+ -+ if (total_rate && wvegas->instant_rate) -+ return div64_u64(mptcp_wvegas_scale(wvegas->instant_rate, MPTCP_WVEGAS_SCALE), total_rate); -+ else -+ return wvegas->weight; -+} -+ -+static void mptcp_wvegas_cong_avoid(struct sock *sk, u32 ack, u32 acked) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct wvegas *wvegas = inet_csk_ca(sk); -+ -+ if (!wvegas->doing_wvegas_now) { -+ tcp_reno_cong_avoid(sk, ack, acked); -+ return; -+ } -+ -+ if (after(ack, wvegas->beg_snd_nxt)) { -+ wvegas->beg_snd_nxt = tp->snd_nxt; -+ -+ if (wvegas->cnt_rtt <= 2) { -+ tcp_reno_cong_avoid(sk, ack, acked); -+ } else { -+ u32 rtt, diff, q_delay; -+ u64 target_cwnd; -+ -+ rtt = wvegas->sampled_rtt / wvegas->cnt_rtt; -+ target_cwnd = div_u64(((u64)tp->snd_cwnd * wvegas->base_rtt), rtt); -+ -+ diff = div_u64((u64)tp->snd_cwnd * (rtt - wvegas->base_rtt), rtt); -+ -+ if (diff > gamma && tcp_in_slow_start(tp)) { -+ tp->snd_cwnd = min(tp->snd_cwnd, (u32)target_cwnd+1); -+ tp->snd_ssthresh = mptcp_wvegas_ssthresh(tp); -+ -+ } else if (tcp_in_slow_start(tp)) { -+ tcp_slow_start(tp, acked); -+ } else { -+ if (diff >= wvegas->alpha) { -+ wvegas->instant_rate = mptcp_wvegas_rate(tp->snd_cwnd, rtt); -+ wvegas->weight = mptcp_wvegas_weight(tp->mpcb, sk); -+ wvegas->alpha = max(2U, (u32)((wvegas->weight * total_alpha) >> MPTCP_WVEGAS_SCALE)); -+ } -+ if (diff > wvegas->alpha) { -+ tp->snd_cwnd--; -+ tp->snd_ssthresh = mptcp_wvegas_ssthresh(tp); -+ } else if (diff < wvegas->alpha) { -+ tp->snd_cwnd++; -+ } -+ -+ /* Try to drain link queue if needed*/ -+ q_delay = rtt - wvegas->base_rtt; -+ if ((wvegas->queue_delay == 0) || (wvegas->queue_delay > q_delay)) -+ wvegas->queue_delay = q_delay; -+ -+ if (q_delay >= 2 * wvegas->queue_delay) { -+ u32 backoff_factor = div_u64(mptcp_wvegas_scale(wvegas->base_rtt, MPTCP_WVEGAS_SCALE), 2 * rtt); -+ tp->snd_cwnd = ((u64)tp->snd_cwnd * backoff_factor) >> MPTCP_WVEGAS_SCALE; -+ wvegas->queue_delay = 0; -+ } -+ } -+ -+ if (tp->snd_cwnd < 2) -+ tp->snd_cwnd = 2; -+ else if (tp->snd_cwnd > tp->snd_cwnd_clamp) -+ tp->snd_cwnd = tp->snd_cwnd_clamp; -+ -+ tp->snd_ssthresh = tcp_current_ssthresh(sk); -+ } -+ -+ wvegas->cnt_rtt = 0; -+ wvegas->sampled_rtt = 0; -+ } -+ /* Use normal slow start */ -+ else if (tcp_in_slow_start(tp)) -+ tcp_slow_start(tp, acked); -+} -+ -+ -+static struct tcp_congestion_ops mptcp_wvegas __read_mostly = { -+ .init = mptcp_wvegas_init, -+ .ssthresh = tcp_reno_ssthresh, -+ .cong_avoid = mptcp_wvegas_cong_avoid, -+ .undo_cwnd = tcp_reno_undo_cwnd, -+ .pkts_acked = mptcp_wvegas_pkts_acked, -+ .set_state = mptcp_wvegas_state, -+ .cwnd_event = mptcp_wvegas_cwnd_event, -+ -+ .owner = THIS_MODULE, -+ .name = "wvegas", -+}; -+ -+static int __init mptcp_wvegas_register(void) -+{ -+ BUILD_BUG_ON(sizeof(struct wvegas) > ICSK_CA_PRIV_SIZE); -+ tcp_register_congestion_control(&mptcp_wvegas); -+ return 0; -+} -+ -+static void __exit mptcp_wvegas_unregister(void) -+{ -+ tcp_unregister_congestion_control(&mptcp_wvegas); -+} -+ -+module_init(mptcp_wvegas_register); -+module_exit(mptcp_wvegas_unregister); -+ -+MODULE_AUTHOR("Yu Cao, Enhuan Dong"); -+MODULE_LICENSE("GPL"); -+MODULE_DESCRIPTION("MPTCP wVegas"); -+MODULE_VERSION("0.1"); diff --git a/root/target/linux/generic/hack-4.14/998-ndpi-netfilter.patch b/root/target/linux/generic/hack-4.14/998-ndpi-netfilter.patch deleted file mode 100644 index cd8d61a7..00000000 --- a/root/target/linux/generic/hack-4.14/998-ndpi-netfilter.patch +++ /dev/null @@ -1,116 +0,0 @@ -diff --git a/include/net/netfilter/nf_conntrack_extend.h b/include/net/netfilter/nf_conntrack_extend.h -index 21f887c..59980ec 100644 ---- a/include/net/netfilter/nf_conntrack_extend.h -+++ b/include/net/netfilter/nf_conntrack_extend.h -@@ -28,7 +28,8 @@ enum nf_ct_ext_id { - #if IS_ENABLED(CONFIG_NETFILTER_SYNPROXY) - NF_CT_EXT_SYNPROXY, - #endif -- NF_CT_EXT_NUM, -+ NF_CT_EXT_CUSTOM, -+ NF_CT_EXT_NUM=NF_CT_EXT_CUSTOM+CONFIG_NF_CONNTRACK_CUSTOM, - }; - - #define NF_CT_EXT_HELPER_TYPE struct nf_conn_help -@@ -96,5 +97,6 @@ struct nf_ct_ext_type { - }; - - int nf_ct_extend_register(const struct nf_ct_ext_type *type); -+int nf_ct_extend_custom_register(struct nf_ct_ext_type *type,unsigned long int cid); - void nf_ct_extend_unregister(const struct nf_ct_ext_type *type); - #endif /* _NF_CONNTRACK_EXTEND_H */ -diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig -index 7581e82..30a11eb 100644 ---- a/net/netfilter/Kconfig -+++ b/net/netfilter/Kconfig -@@ -85,6 +85,16 @@ config NF_CONNTRACK_SECMARK - - If unsure, say 'N'. - -+config NF_CONNTRACK_CUSTOM -+ int "Number of custom extend" -+ range 0 8 -+ depends on NETFILTER_ADVANCED -+ default "2" -+ help -+ This parameter specifies how many custom extensions can be registered. -+ -+ The default value is 2. -+ - config NF_CONNTRACK_ZONES - bool 'Connection tracking zones' - depends on NETFILTER_ADVANCED -diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c -index 85f643c..44e2fdd 100644 ---- a/net/netfilter/nf_conntrack_core.c -+++ b/net/netfilter/nf_conntrack_core.c -@@ -1971,7 +1971,7 @@ int nf_conntrack_set_hashsize(const char *val, const struct kernel_param *kp) - static __always_inline unsigned int total_extension_size(void) - { - /* remember to add new extensions below */ -- BUILD_BUG_ON(NF_CT_EXT_NUM > 9); -+ BUILD_BUG_ON(NF_CT_EXT_NUM > 12); - - return sizeof(struct nf_ct_ext) + - sizeof(struct nf_conn_help) -diff --git a/net/netfilter/nf_conntrack_extend.c b/net/netfilter/nf_conntrack_extend.c -index 9fe0ddc..5a9054e 100644 ---- a/net/netfilter/nf_conntrack_extend.c -+++ b/net/netfilter/nf_conntrack_extend.c -@@ -108,11 +108,56 @@ int nf_ct_extend_register(const struct nf_ct_ext_type *type) - } - EXPORT_SYMBOL_GPL(nf_ct_extend_register); - -+static unsigned long int nf_ct_ext_cust_id[CONFIG_NF_CONNTRACK_CUSTOM]; -+static enum nf_ct_ext_id -+nf_ct_extend_get_custom_id(unsigned long int ext_id); -+ -+int nf_ct_extend_custom_register(struct nf_ct_ext_type *type, -+ unsigned long int cid) -+{ -+ int ret; -+ enum nf_ct_ext_id new_id = nf_ct_extend_get_custom_id(cid); -+ if(!new_id) -+ return -EBUSY; -+ type->id = new_id; -+ ret = nf_ct_extend_register(type); -+ if(ret < 0) { -+ mutex_lock(&nf_ct_ext_type_mutex); -+ nf_ct_ext_cust_id[new_id - NF_CT_EXT_CUSTOM] = 0; -+ mutex_unlock(&nf_ct_ext_type_mutex); -+ } -+ return ret; -+} -+EXPORT_SYMBOL_GPL(nf_ct_extend_custom_register); -+ -+static enum nf_ct_ext_id -+nf_ct_extend_get_custom_id(unsigned long int ext_id) -+{ -+ enum nf_ct_ext_id ret = 0; -+ int i; -+ mutex_lock(&nf_ct_ext_type_mutex); -+ for(i = 0; i < CONFIG_NF_CONNTRACK_CUSTOM; i++) { -+ if(!nf_ct_ext_cust_id[i]) { -+ nf_ct_ext_cust_id[i] = ext_id; -+ ret = i+NF_CT_EXT_CUSTOM; -+ break; -+ } -+ if(nf_ct_ext_cust_id[i] == ext_id) { -+ ret = i+NF_CT_EXT_CUSTOM; -+ break; -+ } -+ } -+ mutex_unlock(&nf_ct_ext_type_mutex); -+ return ret; -+} -+ - /* This MUST be called in process context. */ - void nf_ct_extend_unregister(const struct nf_ct_ext_type *type) - { - mutex_lock(&nf_ct_ext_type_mutex); - RCU_INIT_POINTER(nf_ct_ext_types[type->id], NULL); -+ if(type->id >= NF_CT_EXT_CUSTOM && type->id < NF_CT_EXT_NUM) -+ nf_ct_ext_cust_id[type->id-NF_CT_EXT_CUSTOM] = 0; - mutex_unlock(&nf_ct_ext_type_mutex); - synchronize_rcu(); - } diff --git a/root/target/linux/generic/hack-4.14/999-stop-promiscuous-info.patch b/root/target/linux/generic/hack-4.14/999-stop-promiscuous-info.patch deleted file mode 100644 index 2dc06ee6..00000000 --- a/root/target/linux/generic/hack-4.14/999-stop-promiscuous-info.patch +++ /dev/null @@ -1,14 +0,0 @@ ---- a/net/core/dev.c 2018-08-10 10:31:41.199494561 +0200 -+++ b/net/core/dev.c 2018-08-10 10:32:03.635272509 +0200 -@@ -6613,9 +6613,11 @@ - } - } - if (dev->flags != old_flags) { -+ /* - pr_info("device %s %s promiscuous mode\n", - dev->name, - dev->flags & IFF_PROMISC ? "entered" : "left"); -+ */ - if (audit_enabled) { - current_uid_gid(&uid, &gid); - audit_log(current->audit_context, GFP_ATOMIC, diff --git a/root/target/linux/generic/hack-4.19/690-mptcp_v0.95.patch b/root/target/linux/generic/hack-4.19/690-mptcp_v0.95.patch deleted file mode 100644 index cf58d5a6..00000000 --- a/root/target/linux/generic/hack-4.19/690-mptcp_v0.95.patch +++ /dev/null @@ -1,22998 +0,0 @@ -diff -aurN linux-4.19.104/Documentation/networking/ip-sysctl.txt mptcp-mptcp_v0.95/Documentation/networking/ip-sysctl.txt ---- linux-4.19.104/Documentation/networking/ip-sysctl.txt 2020-02-14 22:33:28.000000000 +0100 -+++ mptcp-mptcp_v0.95/Documentation/networking/ip-sysctl.txt 2020-02-17 11:29:55.000000000 +0100 -@@ -763,6 +763,18 @@ - in RFC 5961 (Improving TCP's Robustness to Blind In-Window Attacks) - Default: 100 - -+MPTCP variables: -+ -+mptcp_enabled - INTEGER -+ Enable or disable Multipath TCP for new connections. -+ Possible values are: -+ -+ 0: Multipath TCP is disabled on all TCP-sockets that are newly created. -+ 1: Multipath TCP is enabled by default on all new TCP-sockets. Note that -+ existing sockets in LISTEN-state will still use regular TCP. -+ 2: Enables Multipath TCP only upon the request of the application -+ throught the socket-option MPTCP_ENABLED. -+ - UDP variables: - - udp_l3mdev_accept - BOOLEAN -diff -aurN linux-4.19.104/drivers/infiniband/hw/cxgb4/cm.c mptcp-mptcp_v0.95/drivers/infiniband/hw/cxgb4/cm.c ---- linux-4.19.104/drivers/infiniband/hw/cxgb4/cm.c 2020-02-14 22:33:28.000000000 +0100 -+++ mptcp-mptcp_v0.95/drivers/infiniband/hw/cxgb4/cm.c 2020-02-17 11:29:55.000000000 +0100 -@@ -3782,7 +3782,7 @@ - */ - memset(&tmp_opt, 0, sizeof(tmp_opt)); - tcp_clear_options(&tmp_opt); -- tcp_parse_options(&init_net, skb, &tmp_opt, 0, NULL); -+ tcp_parse_options(&init_net, skb, &tmp_opt, NULL, 0, NULL, NULL); - - req = __skb_push(skb, sizeof(*req)); - memset(req, 0, sizeof(*req)); -diff -aurN linux-4.19.104/include/linux/skbuff.h mptcp-mptcp_v0.95/include/linux/skbuff.h ---- linux-4.19.104/include/linux/skbuff.h 2020-02-14 22:33:28.000000000 +0100 -+++ mptcp-mptcp_v0.95/include/linux/skbuff.h 2020-02-17 11:29:55.000000000 +0100 -@@ -697,7 +697,7 @@ - * want to keep them across layers you have to do a skb_clone() - * first. This is owned by whoever has the skb queued ATM. - */ -- char cb[48] __aligned(8); -+ char cb[80] __aligned(8); - - union { - struct { -diff -aurN linux-4.19.104/include/linux/tcp.h mptcp-mptcp_v0.95/include/linux/tcp.h ---- linux-4.19.104/include/linux/tcp.h 2020-02-14 22:33:28.000000000 +0100 -+++ mptcp-mptcp_v0.95/include/linux/tcp.h 2020-02-17 11:29:55.000000000 +0100 -@@ -58,7 +58,7 @@ - /* TCP Fast Open */ - #define TCP_FASTOPEN_COOKIE_MIN 4 /* Min Fast Open Cookie size in bytes */ - #define TCP_FASTOPEN_COOKIE_MAX 16 /* Max Fast Open Cookie size in bytes */ --#define TCP_FASTOPEN_COOKIE_SIZE 8 /* the size employed by this impl. */ -+#define TCP_FASTOPEN_COOKIE_SIZE 4 /* the size employed by this impl. */ - - /* TCP Fast Open Cookie as stored in memory */ - struct tcp_fastopen_cookie { -@@ -83,6 +83,56 @@ - u32 end_seq; - }; - -+struct tcp_out_options { -+ u16 options; /* bit field of OPTION_* */ -+ u16 mss; /* 0 to disable */ -+ u8 ws; /* window scale, 0 to disable */ -+ u8 num_sack_blocks; /* number of SACK blocks to include */ -+ u8 hash_size; /* bytes in hash_location */ -+ __u8 *hash_location; /* temporary pointer, overloaded */ -+ __u32 tsval, tsecr; /* need to include OPTION_TS */ -+ struct tcp_fastopen_cookie *fastopen_cookie; /* Fast open cookie */ -+#ifdef CONFIG_MPTCP -+ u16 mptcp_options; /* bit field of MPTCP related OPTION_* */ -+ u8 dss_csum:1, /* dss-checksum required? */ -+ add_addr_v4:1, -+ add_addr_v6:1, -+ mptcp_ver:4; -+ -+ union { -+ struct { -+ __u64 sender_key; /* sender's key for mptcp */ -+ __u64 receiver_key; /* receiver's key for mptcp */ -+ } mp_capable; -+ -+ struct { -+ __u64 sender_truncated_mac; -+ __u32 sender_nonce; -+ /* random number of the sender */ -+ __u32 token; /* token for mptcp */ -+ u8 low_prio:1; -+ } mp_join_syns; -+ }; -+ -+ struct { -+ __u64 trunc_mac; -+ struct in_addr addr; -+ u16 port; -+ u8 addr_id; -+ } add_addr4; -+ -+ struct { -+ __u64 trunc_mac; -+ struct in6_addr addr; -+ u16 port; -+ u8 addr_id; -+ } add_addr6; -+ -+ u16 remove_addrs; /* list of address id */ -+ u8 addr_id; /* address id (mp_join or add_address) */ -+#endif /* CONFIG_MPTCP */ -+}; -+ - /*These are used to set the sack_ok field in struct tcp_options_received */ - #define TCP_SACK_SEEN (1 << 0) /*1 = peer is SACK capable, */ - #define TCP_DSACK_SEEN (1 << 2) /*1 = DSACK was received from peer*/ -@@ -106,6 +156,9 @@ - u16 mss_clamp; /* Maximal mss, negotiated at connection setup */ - }; - -+struct mptcp_cb; -+struct mptcp_tcp_sock; -+ - static inline void tcp_clear_options(struct tcp_options_received *rx_opt) - { - rx_opt->tstamp_ok = rx_opt->sack_ok = 0; -@@ -144,6 +197,8 @@ - return (struct tcp_request_sock *)req; - } - -+struct tcp_md5sig_key; -+ - struct tcp_sock { - /* inet_connection_sock has to be the first member of tcp_sock */ - struct inet_connection_sock inet_conn; -@@ -398,6 +453,44 @@ - */ - struct request_sock *fastopen_rsk; - u32 *saved_syn; -+ -+ /* MPTCP/TCP-specific callbacks */ -+ const struct tcp_sock_ops *ops; -+ -+ struct mptcp_cb *mpcb; -+ struct sock *meta_sk; -+ /* We keep these flags even if CONFIG_MPTCP is not checked, because -+ * it allows checking MPTCP capability just by checking the mpc flag, -+ * rather than adding ifdefs everywhere. -+ */ -+ u32 mpc:1, /* Other end is multipath capable */ -+ inside_tk_table:1, /* Is the tcp_sock inside the token-table? */ -+ send_mp_fclose:1, -+ request_mptcp:1, /* Did we send out an MP_CAPABLE? -+ * (this speeds up mptcp_doit() in tcp_recvmsg) -+ */ -+ pf:1, /* Potentially Failed state: when this flag is set, we -+ * stop using the subflow -+ */ -+ mp_killed:1, /* Killed with a tcp_done in mptcp? */ -+ is_master_sk:1, -+ close_it:1, /* Must close socket in mptcp_data_ready? */ -+ closing:1, -+ mptcp_ver:4, -+ mptcp_sched_setsockopt:1, -+ mptcp_pm_setsockopt:1, -+ record_master_info:1, -+ tcp_disconnect:1; -+ struct mptcp_tcp_sock *mptcp; -+#ifdef CONFIG_MPTCP -+#define MPTCP_SCHED_NAME_MAX 16 -+#define MPTCP_PM_NAME_MAX 16 -+ struct hlist_nulls_node tk_table; -+ u32 mptcp_loc_token; -+ u64 mptcp_loc_key; -+ char mptcp_sched_name[MPTCP_SCHED_NAME_MAX]; -+ char mptcp_pm_name[MPTCP_PM_NAME_MAX]; -+#endif /* CONFIG_MPTCP */ - }; - - enum tsq_enum { -@@ -409,6 +502,8 @@ - TCP_MTU_REDUCED_DEFERRED, /* tcp_v{4|6}_err() could not call - * tcp_v{4|6}_mtu_reduced() - */ -+ MPTCP_PATH_MANAGER_DEFERRED, /* MPTCP deferred creation of new subflows */ -+ MPTCP_SUB_DEFERRED, /* A subflow got deferred - process them */ - }; - - enum tsq_flags { -@@ -418,6 +513,8 @@ - TCPF_WRITE_TIMER_DEFERRED = (1UL << TCP_WRITE_TIMER_DEFERRED), - TCPF_DELACK_TIMER_DEFERRED = (1UL << TCP_DELACK_TIMER_DEFERRED), - TCPF_MTU_REDUCED_DEFERRED = (1UL << TCP_MTU_REDUCED_DEFERRED), -+ TCPF_PATH_MANAGER_DEFERRED = (1UL << MPTCP_PATH_MANAGER_DEFERRED), -+ TCPF_SUB_DEFERRED = (1UL << MPTCP_SUB_DEFERRED), - }; - - static inline struct tcp_sock *tcp_sk(const struct sock *sk) -@@ -440,6 +537,7 @@ - #ifdef CONFIG_TCP_MD5SIG - struct tcp_md5sig_key *tw_md5_key; - #endif -+ struct mptcp_tw *mptcp_tw; - }; - - static inline struct tcp_timewait_sock *tcp_twsk(const struct sock *sk) -diff -aurN linux-4.19.104/include/net/inet_common.h mptcp-mptcp_v0.95/include/net/inet_common.h ---- linux-4.19.104/include/net/inet_common.h 2020-02-14 22:33:28.000000000 +0100 -+++ mptcp-mptcp_v0.95/include/net/inet_common.h 2020-02-17 11:29:55.000000000 +0100 -@@ -2,6 +2,8 @@ - #ifndef _INET_COMMON_H - #define _INET_COMMON_H - -+#include -+ - extern const struct proto_ops inet_stream_ops; - extern const struct proto_ops inet_dgram_ops; - -@@ -14,6 +16,8 @@ - struct sockaddr; - struct socket; - -+int inet_create(struct net *net, struct socket *sock, int protocol, int kern); -+int inet6_create(struct net *net, struct socket *sock, int protocol, int kern); - int inet_release(struct socket *sock); - int inet_stream_connect(struct socket *sock, struct sockaddr *uaddr, - int addr_len, int flags); -diff -aurN linux-4.19.104/include/net/inet_connection_sock.h mptcp-mptcp_v0.95/include/net/inet_connection_sock.h ---- linux-4.19.104/include/net/inet_connection_sock.h 2020-02-14 22:33:28.000000000 +0100 -+++ mptcp-mptcp_v0.95/include/net/inet_connection_sock.h 2020-02-17 11:29:55.000000000 +0100 -@@ -29,6 +29,7 @@ - - struct inet_bind_bucket; - struct tcp_congestion_ops; -+struct tcp_options_received; - - /* - * Pointers to address related TCP functions -diff -aurN linux-4.19.104/include/net/inet_sock.h mptcp-mptcp_v0.95/include/net/inet_sock.h ---- linux-4.19.104/include/net/inet_sock.h 2020-02-14 22:33:28.000000000 +0100 -+++ mptcp-mptcp_v0.95/include/net/inet_sock.h 2020-02-17 11:29:55.000000000 +0100 -@@ -83,7 +83,7 @@ - #define ireq_state req.__req_common.skc_state - #define ireq_family req.__req_common.skc_family - -- u16 snd_wscale : 4, -+ u32 snd_wscale : 4, - rcv_wscale : 4, - tstamp_ok : 1, - sack_ok : 1, -@@ -91,6 +91,8 @@ - ecn_ok : 1, - acked : 1, - no_srccheck: 1, -+ mptcp_rqsk : 1, -+ saw_mpc : 1, - smc_ok : 1; - u32 ir_mark; - union { -diff -aurN linux-4.19.104/include/net/mptcp.h mptcp-mptcp_v0.95/include/net/mptcp.h ---- linux-4.19.104/include/net/mptcp.h 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_v0.95/include/net/mptcp.h 2020-02-17 11:29:55.000000000 +0100 -@@ -0,0 +1,1498 @@ -+/* -+ * MPTCP implementation -+ * -+ * Initial Design & Implementation: -+ * Sébastien Barré -+ * -+ * Current Maintainer & Author: -+ * Christoph Paasch -+ * -+ * Additional authors: -+ * Jaakko Korkeaniemi -+ * Gregory Detal -+ * Fabien Duchêne -+ * Andreas Seelinger -+ * Lavkesh Lahngir -+ * Andreas Ripke -+ * Vlad Dogaru -+ * Octavian Purdila -+ * John Ronan -+ * Catalin Nicutar -+ * Brandon Heller -+ * -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version -+ * 2 of the License, or (at your option) any later version. -+ */ -+ -+#ifndef _MPTCP_H -+#define _MPTCP_H -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+ -+#if defined(__LITTLE_ENDIAN_BITFIELD) -+ #define ntohll(x) be64_to_cpu(x) -+ #define htonll(x) cpu_to_be64(x) -+#elif defined(__BIG_ENDIAN_BITFIELD) -+ #define ntohll(x) (x) -+ #define htonll(x) (x) -+#endif -+ -+struct mptcp_loc4 { -+ u8 loc4_id; -+ u8 low_prio:1; -+ int if_idx; -+ struct in_addr addr; -+}; -+ -+struct mptcp_rem4 { -+ u8 rem4_id; -+ __be16 port; -+ struct in_addr addr; -+}; -+ -+struct mptcp_loc6 { -+ u8 loc6_id; -+ u8 low_prio:1; -+ int if_idx; -+ struct in6_addr addr; -+}; -+ -+struct mptcp_rem6 { -+ u8 rem6_id; -+ __be16 port; -+ struct in6_addr addr; -+}; -+ -+struct mptcp_request_sock { -+ struct tcp_request_sock req; -+ struct hlist_nulls_node hash_entry; -+ -+ union { -+ struct { -+ /* Only on initial subflows */ -+ u64 mptcp_loc_key; -+ u64 mptcp_rem_key; -+ u32 mptcp_loc_token; -+ }; -+ -+ struct { -+ /* Only on additional subflows */ -+ u32 mptcp_rem_nonce; -+ u32 mptcp_loc_nonce; -+ u64 mptcp_hash_tmac; -+ }; -+ }; -+ -+ u8 loc_id; -+ u8 rem_id; /* Address-id in the MP_JOIN */ -+ u8 dss_csum:1, -+ is_sub:1, /* Is this a new subflow? */ -+ low_prio:1, /* Interface set to low-prio? */ -+ rcv_low_prio:1, -+ mptcp_ver:4; -+}; -+ -+struct mptcp_options_received { -+ u16 saw_mpc:1, -+ dss_csum:1, -+ drop_me:1, -+ -+ is_mp_join:1, -+ join_ack:1, -+ -+ saw_low_prio:2, /* 0x1 - low-prio set for this subflow -+ * 0x2 - low-prio set for another subflow -+ */ -+ low_prio:1, -+ -+ saw_add_addr:2, /* Saw at least one add_addr option: -+ * 0x1: IPv4 - 0x2: IPv6 -+ */ -+ more_add_addr:1, /* Saw one more add-addr. */ -+ -+ saw_rem_addr:1, /* Saw at least one rem_addr option */ -+ more_rem_addr:1, /* Saw one more rem-addr. */ -+ -+ mp_fail:1, -+ mp_fclose:1; -+ u8 rem_id; /* Address-id in the MP_JOIN */ -+ u8 prio_addr_id; /* Address-id in the MP_PRIO */ -+ -+ const unsigned char *add_addr_ptr; /* Pointer to add-address option */ -+ const unsigned char *rem_addr_ptr; /* Pointer to rem-address option */ -+ -+ u32 data_ack; -+ u32 data_seq; -+ u16 data_len; -+ -+ u8 mptcp_ver; /* MPTCP version */ -+ -+ /* Key inside the option (from mp_capable or fast_close) */ -+ u64 mptcp_sender_key; -+ u64 mptcp_receiver_key; -+ -+ u32 mptcp_rem_token; /* Remote token */ -+ -+ u32 mptcp_recv_nonce; -+ u64 mptcp_recv_tmac; -+ u8 mptcp_recv_mac[20]; -+}; -+ -+struct mptcp_tcp_sock { -+ struct hlist_node node; -+ struct hlist_node cb_list; -+ struct mptcp_options_received rx_opt; -+ -+ /* Those three fields record the current mapping */ -+ u64 map_data_seq; -+ u32 map_subseq; -+ u16 map_data_len; -+ u16 slave_sk:1, -+ fully_established:1, -+ second_packet:1, -+ attached:1, -+ send_mp_fail:1, -+ include_mpc:1, -+ mapping_present:1, -+ map_data_fin:1, -+ low_prio:1, /* use this socket as backup */ -+ rcv_low_prio:1, /* Peer sent low-prio option to us */ -+ send_mp_prio:1, /* Trigger to send mp_prio on this socket */ -+ pre_established:1; /* State between sending 3rd ACK and -+ * receiving the fourth ack of new subflows. -+ */ -+ -+ /* isn: needed to translate abs to relative subflow seqnums */ -+ u32 snt_isn; -+ u32 rcv_isn; -+ u8 path_index; -+ u8 loc_id; -+ u8 rem_id; -+ u8 sk_err; -+ -+#define MPTCP_SCHED_SIZE 16 -+ u8 mptcp_sched[MPTCP_SCHED_SIZE] __aligned(8); -+ -+ int init_rcv_wnd; -+ u32 infinite_cutoff_seq; -+ struct delayed_work work; -+ u32 mptcp_loc_nonce; -+ struct tcp_sock *tp; -+ u32 last_end_data_seq; -+ -+ /* MP_JOIN subflow: timer for retransmitting the 3rd ack */ -+ struct timer_list mptcp_ack_timer; -+ -+ /* HMAC of the third ack */ -+ char sender_mac[20]; -+}; -+ -+struct mptcp_tw { -+ struct list_head list; -+ u64 loc_key; -+ u64 rcv_nxt; -+ struct mptcp_cb __rcu *mpcb; -+ u8 meta_tw:1, -+ in_list:1; -+}; -+ -+#define MPTCP_PM_NAME_MAX 16 -+struct mptcp_pm_ops { -+ struct list_head list; -+ -+ /* Signal the creation of a new MPTCP-session. */ -+ void (*new_session)(const struct sock *meta_sk); -+ void (*release_sock)(struct sock *meta_sk); -+ void (*fully_established)(struct sock *meta_sk); -+ void (*close_session)(struct sock *meta_sk); -+ void (*new_remote_address)(struct sock *meta_sk); -+ int (*get_local_id)(const struct sock *meta_sk, sa_family_t family, -+ union inet_addr *addr, bool *low_prio); -+ void (*addr_signal)(struct sock *sk, unsigned *size, -+ struct tcp_out_options *opts, struct sk_buff *skb); -+ void (*add_raddr)(struct mptcp_cb *mpcb, const union inet_addr *addr, -+ sa_family_t family, __be16 port, u8 id); -+ void (*rem_raddr)(struct mptcp_cb *mpcb, u8 rem_id); -+ void (*init_subsocket_v4)(struct sock *sk, struct in_addr addr); -+ void (*init_subsocket_v6)(struct sock *sk, struct in6_addr addr); -+ void (*established_subflow)(struct sock *sk); -+ void (*delete_subflow)(struct sock *sk); -+ void (*prio_changed)(struct sock *sk, int low_prio); -+ -+ char name[MPTCP_PM_NAME_MAX]; -+ struct module *owner; -+}; -+ -+#define MPTCP_SCHED_NAME_MAX 16 -+struct mptcp_sched_ops { -+ struct list_head list; -+ -+ struct sock * (*get_subflow)(struct sock *meta_sk, -+ struct sk_buff *skb, -+ bool zero_wnd_test); -+ struct sk_buff * (*next_segment)(struct sock *meta_sk, -+ int *reinject, -+ struct sock **subsk, -+ unsigned int *limit); -+ void (*init)(struct sock *sk); -+ void (*release)(struct sock *sk); -+ -+ char name[MPTCP_SCHED_NAME_MAX]; -+ struct module *owner; -+}; -+ -+struct mptcp_cb { -+ /* list of sockets in this multipath connection */ -+ struct hlist_head conn_list; -+ /* list of sockets that need a call to release_cb */ -+ struct hlist_head callback_list; -+ -+ /* Lock used for protecting the different rcu-lists of mptcp_cb */ -+ spinlock_t mpcb_list_lock; -+ -+ /* High-order bits of 64-bit sequence numbers */ -+ u32 snd_high_order[2]; -+ u32 rcv_high_order[2]; -+ -+ u16 send_infinite_mapping:1, -+ in_time_wait:1, -+ list_rcvd:1, /* XXX TO REMOVE */ -+ addr_signal:1, /* Path-manager wants us to call addr_signal */ -+ dss_csum:1, -+ server_side:1, -+ infinite_mapping_rcv:1, -+ infinite_mapping_snd:1, -+ dfin_combined:1, /* Was the DFIN combined with subflow-fin? */ -+ passive_close:1, -+ snd_hiseq_index:1, /* Index in snd_high_order of snd_nxt */ -+ rcv_hiseq_index:1, /* Index in rcv_high_order of rcv_nxt */ -+ tcp_ca_explicit_set:1; /* was meta CC set by app? */ -+ -+#define MPTCP_SCHED_DATA_SIZE 8 -+ u8 mptcp_sched[MPTCP_SCHED_DATA_SIZE] __aligned(8); -+ const struct mptcp_sched_ops *sched_ops; -+ -+ struct sk_buff_head reinject_queue; -+ /* First cache-line boundary is here minus 8 bytes. But from the -+ * reinject-queue only the next and prev pointers are regularly -+ * accessed. Thus, the whole data-path is on a single cache-line. -+ */ -+ -+ u64 csum_cutoff_seq; -+ u64 infinite_rcv_seq; -+ -+ /***** Start of fields, used for connection closure */ -+ unsigned char mptw_state; -+ u8 dfin_path_index; -+ -+ struct list_head tw_list; -+ -+ /***** Start of fields, used for subflow establishment and closure */ -+ refcount_t mpcb_refcnt; -+ -+ /* Mutex needed, because otherwise mptcp_close will complain that the -+ * socket is owned by the user. -+ * E.g., mptcp_sub_close_wq is taking the meta-lock. -+ */ -+ struct mutex mpcb_mutex; -+ -+ /***** Start of fields, used for subflow establishment */ -+ struct sock *meta_sk; -+ -+ /* Master socket, also part of the conn_list, this -+ * socket is the one that the application sees. -+ */ -+ struct sock *master_sk; -+ -+ __u64 mptcp_loc_key; -+ __u64 mptcp_rem_key; -+ __u32 mptcp_loc_token; -+ __u32 mptcp_rem_token; -+ -+#define MPTCP_PM_SIZE 608 -+ u8 mptcp_pm[MPTCP_PM_SIZE] __aligned(8); -+ const struct mptcp_pm_ops *pm_ops; -+ -+ unsigned long path_index_bits; -+ -+ __u8 mptcp_ver; -+ -+ /* Original snd/rcvbuf of the initial subflow. -+ * Used for the new subflows on the server-side to allow correct -+ * autotuning -+ */ -+ int orig_sk_rcvbuf; -+ int orig_sk_sndbuf; -+ u32 orig_window_clamp; -+ -+ struct tcp_info *master_info; -+}; -+ -+#define MPTCP_VERSION_0 0 -+#define MPTCP_VERSION_1 1 -+ -+#define MPTCP_SUB_CAPABLE 0 -+#define MPTCP_SUB_LEN_CAPABLE_SYN 12 -+#define MPTCP_SUB_LEN_CAPABLE_SYN_ALIGN 12 -+#define MPTCP_SUB_LEN_CAPABLE_ACK 20 -+#define MPTCP_SUB_LEN_CAPABLE_ACK_ALIGN 20 -+ -+#define MPTCP_SUB_JOIN 1 -+#define MPTCP_SUB_LEN_JOIN_SYN 12 -+#define MPTCP_SUB_LEN_JOIN_SYN_ALIGN 12 -+#define MPTCP_SUB_LEN_JOIN_SYNACK 16 -+#define MPTCP_SUB_LEN_JOIN_SYNACK_ALIGN 16 -+#define MPTCP_SUB_LEN_JOIN_ACK 24 -+#define MPTCP_SUB_LEN_JOIN_ACK_ALIGN 24 -+ -+#define MPTCP_SUB_DSS 2 -+#define MPTCP_SUB_LEN_DSS 4 -+#define MPTCP_SUB_LEN_DSS_ALIGN 4 -+ -+/* Lengths for seq and ack are the ones without the generic MPTCP-option header, -+ * as they are part of the DSS-option. -+ * To get the total length, just add the different options together. -+ */ -+#define MPTCP_SUB_LEN_SEQ 10 -+#define MPTCP_SUB_LEN_SEQ_CSUM 12 -+#define MPTCP_SUB_LEN_SEQ_ALIGN 12 -+ -+#define MPTCP_SUB_LEN_SEQ_64 14 -+#define MPTCP_SUB_LEN_SEQ_CSUM_64 16 -+#define MPTCP_SUB_LEN_SEQ_64_ALIGN 16 -+ -+#define MPTCP_SUB_LEN_ACK 4 -+#define MPTCP_SUB_LEN_ACK_ALIGN 4 -+ -+#define MPTCP_SUB_LEN_ACK_64 8 -+#define MPTCP_SUB_LEN_ACK_64_ALIGN 8 -+ -+/* This is the "default" option-length we will send out most often. -+ * MPTCP DSS-header -+ * 32-bit data sequence number -+ * 32-bit data ack -+ * -+ * It is necessary to calculate the effective MSS we will be using when -+ * sending data. -+ */ -+#define MPTCP_SUB_LEN_DSM_ALIGN (MPTCP_SUB_LEN_DSS_ALIGN + \ -+ MPTCP_SUB_LEN_SEQ_ALIGN + \ -+ MPTCP_SUB_LEN_ACK_ALIGN) -+ -+#define MPTCP_SUB_ADD_ADDR 3 -+#define MPTCP_SUB_LEN_ADD_ADDR4 8 -+#define MPTCP_SUB_LEN_ADD_ADDR4_VER1 16 -+#define MPTCP_SUB_LEN_ADD_ADDR6 20 -+#define MPTCP_SUB_LEN_ADD_ADDR6_VER1 28 -+#define MPTCP_SUB_LEN_ADD_ADDR4_ALIGN 8 -+#define MPTCP_SUB_LEN_ADD_ADDR4_ALIGN_VER1 16 -+#define MPTCP_SUB_LEN_ADD_ADDR6_ALIGN 20 -+#define MPTCP_SUB_LEN_ADD_ADDR6_ALIGN_VER1 28 -+ -+#define MPTCP_SUB_REMOVE_ADDR 4 -+#define MPTCP_SUB_LEN_REMOVE_ADDR 4 -+ -+#define MPTCP_SUB_PRIO 5 -+#define MPTCP_SUB_LEN_PRIO 3 -+#define MPTCP_SUB_LEN_PRIO_ADDR 4 -+#define MPTCP_SUB_LEN_PRIO_ALIGN 4 -+ -+#define MPTCP_SUB_FAIL 6 -+#define MPTCP_SUB_LEN_FAIL 12 -+#define MPTCP_SUB_LEN_FAIL_ALIGN 12 -+ -+#define MPTCP_SUB_FCLOSE 7 -+#define MPTCP_SUB_LEN_FCLOSE 12 -+#define MPTCP_SUB_LEN_FCLOSE_ALIGN 12 -+ -+ -+#define OPTION_MPTCP (1 << 5) -+ -+/* Max number of fastclose retransmissions */ -+#define MPTCP_FASTCLOSE_RETRIES 3 -+ -+#ifdef CONFIG_MPTCP -+ -+/* Used for checking if the mptcp initialization has been successful */ -+extern bool mptcp_init_failed; -+ -+/* MPTCP options */ -+#define OPTION_TYPE_SYN (1 << 0) -+#define OPTION_TYPE_SYNACK (1 << 1) -+#define OPTION_TYPE_ACK (1 << 2) -+#define OPTION_MP_CAPABLE (1 << 3) -+#define OPTION_DATA_ACK (1 << 4) -+#define OPTION_ADD_ADDR (1 << 5) -+#define OPTION_MP_JOIN (1 << 6) -+#define OPTION_MP_FAIL (1 << 7) -+#define OPTION_MP_FCLOSE (1 << 8) -+#define OPTION_REMOVE_ADDR (1 << 9) -+#define OPTION_MP_PRIO (1 << 10) -+ -+/* MPTCP flags: both TX and RX */ -+#define MPTCPHDR_SEQ 0x01 /* DSS.M option is present */ -+#define MPTCPHDR_FIN 0x02 /* DSS.F option is present */ -+#define MPTCPHDR_SEQ64_INDEX 0x04 /* index of seq in mpcb->snd_high_order */ -+/* MPTCP flags: RX only */ -+#define MPTCPHDR_ACK 0x08 -+#define MPTCPHDR_SEQ64_SET 0x10 /* Did we received a 64-bit seq number? */ -+#define MPTCPHDR_SEQ64_OFO 0x20 /* Is it not in our circular array? */ -+#define MPTCPHDR_DSS_CSUM 0x40 -+/* MPTCP flags: TX only */ -+#define MPTCPHDR_INF 0x08 -+#define MPTCP_REINJECT 0x10 /* Did we reinject this segment? */ -+ -+struct mptcp_option { -+ __u8 kind; -+ __u8 len; -+#if defined(__LITTLE_ENDIAN_BITFIELD) -+ __u8 ver:4, -+ sub:4; -+#elif defined(__BIG_ENDIAN_BITFIELD) -+ __u8 sub:4, -+ ver:4; -+#else -+#error "Adjust your defines" -+#endif -+}; -+ -+struct mp_capable { -+ __u8 kind; -+ __u8 len; -+#if defined(__LITTLE_ENDIAN_BITFIELD) -+ __u8 ver:4, -+ sub:4; -+ __u8 h:1, -+ rsv:5, -+ b:1, -+ a:1; -+#elif defined(__BIG_ENDIAN_BITFIELD) -+ __u8 sub:4, -+ ver:4; -+ __u8 a:1, -+ b:1, -+ rsv:5, -+ h:1; -+#else -+#error "Adjust your defines" -+#endif -+ __u64 sender_key; -+ __u64 receiver_key; -+} __attribute__((__packed__)); -+ -+struct mp_join { -+ __u8 kind; -+ __u8 len; -+#if defined(__LITTLE_ENDIAN_BITFIELD) -+ __u8 b:1, -+ rsv:3, -+ sub:4; -+#elif defined(__BIG_ENDIAN_BITFIELD) -+ __u8 sub:4, -+ rsv:3, -+ b:1; -+#else -+#error "Adjust your defines" -+#endif -+ __u8 addr_id; -+ union { -+ struct { -+ u32 token; -+ u32 nonce; -+ } syn; -+ struct { -+ __u64 mac; -+ u32 nonce; -+ } synack; -+ struct { -+ __u8 mac[20]; -+ } ack; -+ } u; -+} __attribute__((__packed__)); -+ -+struct mp_dss { -+ __u8 kind; -+ __u8 len; -+#if defined(__LITTLE_ENDIAN_BITFIELD) -+ __u16 rsv1:4, -+ sub:4, -+ A:1, -+ a:1, -+ M:1, -+ m:1, -+ F:1, -+ rsv2:3; -+#elif defined(__BIG_ENDIAN_BITFIELD) -+ __u16 sub:4, -+ rsv1:4, -+ rsv2:3, -+ F:1, -+ m:1, -+ M:1, -+ a:1, -+ A:1; -+#else -+#error "Adjust your defines" -+#endif -+}; -+ -+struct mp_add_addr { -+ __u8 kind; -+ __u8 len; -+#if defined(__LITTLE_ENDIAN_BITFIELD) -+ __u8 ipver:4, -+ sub:4; -+#elif defined(__BIG_ENDIAN_BITFIELD) -+ __u8 sub:4, -+ ipver:4; -+#else -+#error "Adjust your defines" -+#endif -+ __u8 addr_id; -+ union { -+ struct { -+ struct in_addr addr; -+ __be16 port; -+ __u8 mac[8]; -+ } v4; -+ struct { -+ struct in6_addr addr; -+ __be16 port; -+ __u8 mac[8]; -+ } v6; -+ } u; -+} __attribute__((__packed__)); -+ -+struct mp_remove_addr { -+ __u8 kind; -+ __u8 len; -+#if defined(__LITTLE_ENDIAN_BITFIELD) -+ __u8 rsv:4, -+ sub:4; -+#elif defined(__BIG_ENDIAN_BITFIELD) -+ __u8 sub:4, -+ rsv:4; -+#else -+#error "Adjust your defines" -+#endif -+ /* list of addr_id */ -+ __u8 addrs_id; -+}; -+ -+struct mp_fail { -+ __u8 kind; -+ __u8 len; -+#if defined(__LITTLE_ENDIAN_BITFIELD) -+ __u16 rsv1:4, -+ sub:4, -+ rsv2:8; -+#elif defined(__BIG_ENDIAN_BITFIELD) -+ __u16 sub:4, -+ rsv1:4, -+ rsv2:8; -+#else -+#error "Adjust your defines" -+#endif -+ __be64 data_seq; -+} __attribute__((__packed__)); -+ -+struct mp_fclose { -+ __u8 kind; -+ __u8 len; -+#if defined(__LITTLE_ENDIAN_BITFIELD) -+ __u16 rsv1:4, -+ sub:4, -+ rsv2:8; -+#elif defined(__BIG_ENDIAN_BITFIELD) -+ __u16 sub:4, -+ rsv1:4, -+ rsv2:8; -+#else -+#error "Adjust your defines" -+#endif -+ __u64 key; -+} __attribute__((__packed__)); -+ -+struct mp_prio { -+ __u8 kind; -+ __u8 len; -+#if defined(__LITTLE_ENDIAN_BITFIELD) -+ __u8 b:1, -+ rsv:3, -+ sub:4; -+#elif defined(__BIG_ENDIAN_BITFIELD) -+ __u8 sub:4, -+ rsv:3, -+ b:1; -+#else -+#error "Adjust your defines" -+#endif -+ __u8 addr_id; -+} __attribute__((__packed__)); -+ -+static inline int mptcp_sub_len_dss(const struct mp_dss *m, const int csum) -+{ -+ return 4 + m->A * (4 + m->a * 4) + m->M * (10 + m->m * 4 + csum * 2); -+} -+ -+#define MPTCP_SYSCTL 1 -+ -+extern int sysctl_mptcp_enabled; -+extern int sysctl_mptcp_version; -+extern int sysctl_mptcp_checksum; -+extern int sysctl_mptcp_debug; -+extern int sysctl_mptcp_syn_retries; -+ -+extern struct workqueue_struct *mptcp_wq; -+ -+#define mptcp_debug(fmt, args...) \ -+ do { \ -+ if (unlikely(sysctl_mptcp_debug)) \ -+ pr_err(fmt, ##args); \ -+ } while (0) -+ -+static inline struct sock *mptcp_to_sock(const struct mptcp_tcp_sock *mptcp) -+{ -+ return (struct sock *)mptcp->tp; -+} -+ -+#define mptcp_for_each_sub(__mpcb, __mptcp) \ -+ hlist_for_each_entry_rcu(__mptcp, &((__mpcb)->conn_list), node) -+ -+/* Must be called with the appropriate lock held */ -+#define mptcp_for_each_sub_safe(__mpcb, __mptcp, __tmp) \ -+ hlist_for_each_entry_safe(__mptcp, __tmp, &((__mpcb)->conn_list), node) -+ -+/* Iterates over all bit set to 1 in a bitset */ -+#define mptcp_for_each_bit_set(b, i) \ -+ for (i = ffs(b) - 1; i >= 0; i = ffs(b >> (i + 1) << (i + 1)) - 1) -+ -+#define mptcp_for_each_bit_unset(b, i) \ -+ mptcp_for_each_bit_set(~b, i) -+ -+#define MPTCP_INC_STATS(net, field) SNMP_INC_STATS((net)->mptcp.mptcp_statistics, field) -+#define MPTCP_INC_STATS_BH(net, field) __SNMP_INC_STATS((net)->mptcp.mptcp_statistics, field) -+ -+enum -+{ -+ MPTCP_MIB_NUM = 0, -+ MPTCP_MIB_MPCAPABLEPASSIVE, /* Received SYN with MP_CAPABLE */ -+ MPTCP_MIB_MPCAPABLEACTIVE, /* Sent SYN with MP_CAPABLE */ -+ MPTCP_MIB_MPCAPABLEACTIVEACK, /* Received SYN/ACK with MP_CAPABLE */ -+ MPTCP_MIB_MPCAPABLEPASSIVEACK, /* Received third ACK with MP_CAPABLE */ -+ MPTCP_MIB_MPCAPABLEPASSIVEFALLBACK,/* Server-side fallback during 3-way handshake */ -+ MPTCP_MIB_MPCAPABLEACTIVEFALLBACK, /* Client-side fallback during 3-way handshake */ -+ MPTCP_MIB_MPCAPABLERETRANSFALLBACK,/* Client-side stopped sending MP_CAPABLE after too many SYN-retransmissions */ -+ MPTCP_MIB_CSUMENABLED, /* Created MPTCP-connection with DSS-checksum enabled */ -+ MPTCP_MIB_RETRANSSEGS, /* Segments retransmitted at the MPTCP-level */ -+ MPTCP_MIB_MPFAILRX, /* Received an MP_FAIL */ -+ MPTCP_MIB_CSUMFAIL, /* Received segment with invalid checksum */ -+ MPTCP_MIB_FASTCLOSERX, /* Recevied a FAST_CLOSE */ -+ MPTCP_MIB_FASTCLOSETX, /* Sent a FAST_CLOSE */ -+ MPTCP_MIB_FBACKSUB, /* Fallback upon ack without data-ack on new subflow */ -+ MPTCP_MIB_FBACKINIT, /* Fallback upon ack without data-ack on initial subflow */ -+ MPTCP_MIB_FBDATASUB, /* Fallback upon data without DSS at the beginning on new subflow */ -+ MPTCP_MIB_FBDATAINIT, /* Fallback upon data without DSS at the beginning on initial subflow */ -+ MPTCP_MIB_REMADDRSUB, /* Remove subflow due to REMOVE_ADDR */ -+ MPTCP_MIB_JOINNOTOKEN, /* Received MP_JOIN but the token was not found */ -+ MPTCP_MIB_JOINFALLBACK, /* Received MP_JOIN on session that has fallen back to reg. TCP */ -+ MPTCP_MIB_JOINSYNTX, /* Sent a SYN + MP_JOIN */ -+ MPTCP_MIB_JOINSYNRX, /* Received a SYN + MP_JOIN */ -+ MPTCP_MIB_JOINSYNACKRX, /* Received a SYN/ACK + MP_JOIN */ -+ MPTCP_MIB_JOINSYNACKMAC, /* HMAC was wrong on SYN/ACK + MP_JOIN */ -+ MPTCP_MIB_JOINACKRX, /* Received an ACK + MP_JOIN */ -+ MPTCP_MIB_JOINACKMAC, /* HMAC was wrong on ACK + MP_JOIN */ -+ MPTCP_MIB_JOINACKFAIL, /* Third ACK on new subflow did not contain an MP_JOIN */ -+ MPTCP_MIB_JOINACKRTO, /* Retransmission timer for third ACK + MP_JOIN timed out */ -+ MPTCP_MIB_JOINACKRXMIT, /* Retransmitted an ACK + MP_JOIN */ -+ MPTCP_MIB_NODSSWINDOW, /* Received too many packets without a DSS-option */ -+ MPTCP_MIB_DSSNOMATCH, /* Received a new mapping that did not match the previous one */ -+ MPTCP_MIB_INFINITEMAPRX, /* Received an infinite mapping */ -+ MPTCP_MIB_DSSTCPMISMATCH, /* DSS-mapping did not map with TCP's sequence numbers */ -+ MPTCP_MIB_DSSTRIMHEAD, /* Trimmed segment at the head (coalescing middlebox) */ -+ MPTCP_MIB_DSSSPLITTAIL, /* Trimmed segment at the tail (coalescing middlebox) */ -+ MPTCP_MIB_PURGEOLD, /* Removed old skb from the rcv-queue due to missing DSS-mapping */ -+ MPTCP_MIB_ADDADDRRX, /* Received an ADD_ADDR */ -+ MPTCP_MIB_ADDADDRTX, /* Sent an ADD_ADDR */ -+ MPTCP_MIB_REMADDRRX, /* Received a REMOVE_ADDR */ -+ MPTCP_MIB_REMADDRTX, /* Sent a REMOVE_ADDR */ -+ __MPTCP_MIB_MAX -+}; -+ -+#define MPTCP_MIB_MAX __MPTCP_MIB_MAX -+struct mptcp_mib { -+ unsigned long mibs[MPTCP_MIB_MAX]; -+}; -+ -+extern struct lock_class_key meta_key; -+extern char *meta_key_name; -+extern struct lock_class_key meta_slock_key; -+extern char *meta_slock_key_name; -+ -+extern siphash_key_t mptcp_secret; -+ -+/* This is needed to ensure that two subsequent key/nonce-generation result in -+ * different keys/nonces if the IPs and ports are the same. -+ */ -+extern u32 mptcp_seed; -+ -+#define MPTCP_HASH_SIZE 1024 -+ -+extern struct hlist_nulls_head tk_hashtable[MPTCP_HASH_SIZE]; -+ -+/* Request-sockets can be hashed in the tk_htb for collision-detection or in -+ * the regular htb for join-connections. We need to define different NULLS -+ * values so that we can correctly detect a request-socket that has been -+ * recycled. See also c25eb3bfb9729. -+ */ -+#define MPTCP_REQSK_NULLS_BASE (1U << 29) -+ -+ -+void mptcp_data_ready(struct sock *sk); -+void mptcp_write_space(struct sock *sk); -+ -+void mptcp_add_meta_ofo_queue(const struct sock *meta_sk, struct sk_buff *skb, -+ struct sock *sk); -+void mptcp_cleanup_rbuf(struct sock *meta_sk, int copied); -+int mptcp_add_sock(struct sock *meta_sk, struct sock *sk, u8 loc_id, u8 rem_id, -+ gfp_t flags); -+void mptcp_del_sock(struct sock *sk); -+void mptcp_update_metasocket(const struct sock *meta_sk); -+void mptcp_reinject_data(struct sock *orig_sk, int clone_it); -+void mptcp_update_sndbuf(const struct tcp_sock *tp); -+void mptcp_send_fin(struct sock *meta_sk); -+void mptcp_send_active_reset(struct sock *meta_sk, gfp_t priority); -+bool mptcp_write_xmit(struct sock *sk, unsigned int mss_now, int nonagle, -+ int push_one, gfp_t gfp); -+void tcp_parse_mptcp_options(const struct sk_buff *skb, -+ struct mptcp_options_received *mopt); -+void mptcp_parse_options(const uint8_t *ptr, int opsize, -+ struct mptcp_options_received *mopt, -+ const struct sk_buff *skb, -+ struct tcp_sock *tp); -+void mptcp_syn_options(const struct sock *sk, struct tcp_out_options *opts, -+ unsigned *remaining); -+void mptcp_synack_options(struct request_sock *req, -+ struct tcp_out_options *opts, -+ unsigned *remaining); -+void mptcp_established_options(struct sock *sk, struct sk_buff *skb, -+ struct tcp_out_options *opts, unsigned *size); -+void mptcp_options_write(__be32 *ptr, struct tcp_sock *tp, -+ const struct tcp_out_options *opts, -+ struct sk_buff *skb); -+void mptcp_close(struct sock *meta_sk, long timeout); -+bool mptcp_doit(struct sock *sk); -+int mptcp_create_master_sk(struct sock *meta_sk, __u64 remote_key, -+ __u8 mptcp_ver, u32 window); -+int mptcp_check_req_fastopen(struct sock *child, struct request_sock *req); -+int mptcp_check_req_master(struct sock *sk, struct sock *child, -+ struct request_sock *req, const struct sk_buff *skb, -+ int drop, u32 tsoff); -+struct sock *mptcp_check_req_child(struct sock *meta_sk, -+ struct sock *child, -+ struct request_sock *req, -+ struct sk_buff *skb, -+ const struct mptcp_options_received *mopt); -+u32 __mptcp_select_window(struct sock *sk); -+void mptcp_select_initial_window(const struct sock *sk, int __space, __u32 mss, -+ __u32 *rcv_wnd, __u32 *window_clamp, -+ int wscale_ok, __u8 *rcv_wscale, -+ __u32 init_rcv_wnd); -+unsigned int mptcp_current_mss(struct sock *meta_sk); -+int mptcp_select_size(const struct sock *meta_sk, bool first_skb, bool zc); -+void mptcp_hmac_sha1(const u8 *key_1, const u8 *key_2, u32 *hash_out, -+ int arg_num, ...); -+void mptcp_clean_rtx_infinite(const struct sk_buff *skb, struct sock *sk); -+void mptcp_fin(struct sock *meta_sk); -+void mptcp_meta_retransmit_timer(struct sock *meta_sk); -+void mptcp_sub_retransmit_timer(struct sock *sk); -+int mptcp_write_wakeup(struct sock *meta_sk, int mib); -+void mptcp_sub_close_wq(struct work_struct *work); -+void mptcp_sub_close(struct sock *sk, unsigned long delay); -+struct sock *mptcp_select_ack_sock(const struct sock *meta_sk); -+void mptcp_prepare_for_backlog(struct sock *sk, struct sk_buff *skb); -+int mptcp_backlog_rcv(struct sock *meta_sk, struct sk_buff *skb); -+void mptcp_ack_handler(struct timer_list *t); -+bool mptcp_check_rtt(const struct tcp_sock *tp, int time); -+int mptcp_check_snd_buf(const struct tcp_sock *tp); -+bool mptcp_handle_options(struct sock *sk, const struct tcphdr *th, -+ const struct sk_buff *skb); -+void __init mptcp_init(void); -+void mptcp_destroy_sock(struct sock *sk); -+int mptcp_rcv_synsent_state_process(struct sock *sk, struct sock **skptr, -+ const struct sk_buff *skb, -+ const struct mptcp_options_received *mopt); -+unsigned int mptcp_xmit_size_goal(const struct sock *meta_sk, u32 mss_now, -+ int large_allowed); -+int mptcp_init_tw_sock(struct sock *sk, struct tcp_timewait_sock *tw); -+void mptcp_twsk_destructor(struct tcp_timewait_sock *tw); -+void mptcp_time_wait(struct sock *sk, int state, int timeo); -+void mptcp_disconnect(struct sock *meta_sk); -+bool mptcp_should_expand_sndbuf(const struct sock *sk); -+int mptcp_retransmit_skb(struct sock *meta_sk, struct sk_buff *skb); -+void mptcp_tsq_flags(struct sock *sk); -+void mptcp_tsq_sub_deferred(struct sock *meta_sk); -+struct mp_join *mptcp_find_join(const struct sk_buff *skb); -+void mptcp_hash_remove_bh(struct tcp_sock *meta_tp); -+struct sock *mptcp_hash_find(const struct net *net, const u32 token); -+int mptcp_lookup_join(struct sk_buff *skb, struct inet_timewait_sock *tw); -+int mptcp_do_join_short(struct sk_buff *skb, -+ const struct mptcp_options_received *mopt, -+ struct net *net); -+void mptcp_reqsk_destructor(struct request_sock *req); -+void mptcp_connect_init(struct sock *sk); -+void mptcp_sub_force_close(struct sock *sk); -+int mptcp_sub_len_remove_addr_align(u16 bitfield); -+void mptcp_join_reqsk_init(const struct mptcp_cb *mpcb, -+ const struct request_sock *req, -+ struct sk_buff *skb); -+void mptcp_reqsk_init(struct request_sock *req, const struct sock *sk, -+ const struct sk_buff *skb, bool want_cookie); -+int mptcp_conn_request(struct sock *sk, struct sk_buff *skb); -+void mptcp_enable_sock(struct sock *sk); -+void mptcp_disable_sock(struct sock *sk); -+void mptcp_disable_static_key(void); -+void mptcp_cookies_reqsk_init(struct request_sock *req, -+ struct mptcp_options_received *mopt, -+ struct sk_buff *skb); -+void mptcp_mpcb_put(struct mptcp_cb *mpcb); -+int mptcp_finish_handshake(struct sock *child, struct sk_buff *skb); -+int mptcp_get_info(const struct sock *meta_sk, char __user *optval, int optlen); -+void mptcp_clear_sk(struct sock *sk, int size); -+ -+/* MPTCP-path-manager registration/initialization functions */ -+int mptcp_register_path_manager(struct mptcp_pm_ops *pm); -+void mptcp_unregister_path_manager(struct mptcp_pm_ops *pm); -+void mptcp_init_path_manager(struct mptcp_cb *mpcb); -+void mptcp_cleanup_path_manager(struct mptcp_cb *mpcb); -+void mptcp_fallback_default(struct mptcp_cb *mpcb); -+void mptcp_get_default_path_manager(char *name); -+int mptcp_set_scheduler(struct sock *sk, const char *name); -+int mptcp_set_path_manager(struct sock *sk, const char *name); -+int mptcp_set_default_path_manager(const char *name); -+extern struct mptcp_pm_ops mptcp_pm_default; -+ -+/* MPTCP-scheduler registration/initialization functions */ -+int mptcp_register_scheduler(struct mptcp_sched_ops *sched); -+void mptcp_unregister_scheduler(struct mptcp_sched_ops *sched); -+void mptcp_init_scheduler(struct mptcp_cb *mpcb); -+void mptcp_cleanup_scheduler(struct mptcp_cb *mpcb); -+void mptcp_get_default_scheduler(char *name); -+int mptcp_set_default_scheduler(const char *name); -+bool mptcp_is_available(struct sock *sk, const struct sk_buff *skb, -+ bool zero_wnd_test); -+bool mptcp_is_def_unavailable(struct sock *sk); -+bool subflow_is_active(const struct tcp_sock *tp); -+bool subflow_is_backup(const struct tcp_sock *tp); -+struct sock *get_available_subflow(struct sock *meta_sk, struct sk_buff *skb, -+ bool zero_wnd_test); -+extern struct mptcp_sched_ops mptcp_sched_default; -+ -+/* Initializes function-pointers and MPTCP-flags */ -+static inline void mptcp_init_tcp_sock(struct sock *sk) -+{ -+ if (!mptcp_init_failed && sysctl_mptcp_enabled == MPTCP_SYSCTL) -+ mptcp_enable_sock(sk); -+} -+ -+static inline int mptcp_pi_to_flag(int pi) -+{ -+ return 1 << (pi - 1); -+} -+ -+static inline -+struct mptcp_request_sock *mptcp_rsk(const struct request_sock *req) -+{ -+ return (struct mptcp_request_sock *)req; -+} -+ -+static inline -+struct request_sock *rev_mptcp_rsk(const struct mptcp_request_sock *req) -+{ -+ return (struct request_sock *)req; -+} -+ -+static inline bool mptcp_can_sendpage(struct sock *sk) -+{ -+ struct mptcp_tcp_sock *mptcp; -+ -+ if (tcp_sk(sk)->mpcb->dss_csum) -+ return false; -+ -+ mptcp_for_each_sub(tcp_sk(sk)->mpcb, mptcp) { -+ struct sock *sk_it = mptcp_to_sock(mptcp); -+ -+ if (!(sk_it->sk_route_caps & NETIF_F_SG)) -+ return false; -+ } -+ -+ return true; -+} -+ -+static inline void mptcp_push_pending_frames(struct sock *meta_sk) -+{ -+ /* We check packets out and send-head here. TCP only checks the -+ * send-head. But, MPTCP also checks packets_out, as this is an -+ * indication that we might want to do opportunistic reinjection. -+ */ -+ if (tcp_sk(meta_sk)->packets_out || tcp_send_head(meta_sk)) { -+ struct tcp_sock *tp = tcp_sk(meta_sk); -+ -+ /* We don't care about the MSS, because it will be set in -+ * mptcp_write_xmit. -+ */ -+ __tcp_push_pending_frames(meta_sk, 0, tp->nonagle); -+ } -+} -+ -+static inline void mptcp_send_reset(struct sock *sk) -+{ -+ if (tcp_need_reset(sk->sk_state)) -+ tcp_sk(sk)->ops->send_active_reset(sk, GFP_ATOMIC); -+ mptcp_sub_force_close(sk); -+} -+ -+static inline void mptcp_sub_force_close_all(struct mptcp_cb *mpcb, -+ struct sock *except) -+{ -+ struct mptcp_tcp_sock *mptcp; -+ struct hlist_node *tmp; -+ -+ mptcp_for_each_sub_safe(mpcb, mptcp, tmp) { -+ struct sock *sk_it = mptcp_to_sock(mptcp); -+ -+ if (sk_it != except) -+ mptcp_send_reset(sk_it); -+ } -+} -+ -+static inline bool mptcp_is_data_seq(const struct sk_buff *skb) -+{ -+ return TCP_SKB_CB(skb)->mptcp_flags & MPTCPHDR_SEQ; -+} -+ -+static inline bool mptcp_is_data_fin(const struct sk_buff *skb) -+{ -+ return TCP_SKB_CB(skb)->mptcp_flags & MPTCPHDR_FIN; -+} -+ -+/* Is it a data-fin while in infinite mapping mode? -+ * In infinite mode, a subflow-fin is in fact a data-fin. -+ */ -+static inline bool mptcp_is_data_fin2(const struct sk_buff *skb, -+ const struct tcp_sock *tp) -+{ -+ return mptcp_is_data_fin(skb) || -+ (tp->mpcb->infinite_mapping_rcv && -+ (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN)); -+} -+ -+static inline u8 mptcp_get_64_bit(u64 data_seq, struct mptcp_cb *mpcb) -+{ -+ u64 data_seq_high = (u32)(data_seq >> 32); -+ -+ if (mpcb->rcv_high_order[0] == data_seq_high) -+ return 0; -+ else if (mpcb->rcv_high_order[1] == data_seq_high) -+ return MPTCPHDR_SEQ64_INDEX; -+ else -+ return MPTCPHDR_SEQ64_OFO; -+} -+ -+/* Sets the data_seq and returns pointer to the in-skb field of the data_seq. -+ * If the packet has a 64-bit dseq, the pointer points to the last 32 bits. -+ */ -+static inline __u32 *mptcp_skb_set_data_seq(const struct sk_buff *skb, -+ u32 *data_seq, -+ struct mptcp_cb *mpcb) -+{ -+ __u32 *ptr = (__u32 *)(skb_transport_header(skb) + TCP_SKB_CB(skb)->dss_off); -+ -+ if (TCP_SKB_CB(skb)->mptcp_flags & MPTCPHDR_SEQ64_SET) { -+ u64 data_seq64 = get_unaligned_be64(ptr); -+ -+ if (mpcb) -+ TCP_SKB_CB(skb)->mptcp_flags |= mptcp_get_64_bit(data_seq64, mpcb); -+ -+ *data_seq = (u32)data_seq64; -+ ptr++; -+ } else { -+ *data_seq = get_unaligned_be32(ptr); -+ } -+ -+ return ptr; -+} -+ -+static inline struct sock *mptcp_meta_sk(const struct sock *sk) -+{ -+ return tcp_sk(sk)->meta_sk; -+} -+ -+static inline struct tcp_sock *mptcp_meta_tp(const struct tcp_sock *tp) -+{ -+ return tcp_sk(tp->meta_sk); -+} -+ -+static inline int is_meta_tp(const struct tcp_sock *tp) -+{ -+ return tp->mpcb && mptcp_meta_tp(tp) == tp; -+} -+ -+static inline int is_meta_sk(const struct sock *sk) -+{ -+ return sk->sk_state != TCP_NEW_SYN_RECV && -+ sk->sk_type == SOCK_STREAM && sk->sk_protocol == IPPROTO_TCP && -+ mptcp(tcp_sk(sk)) && mptcp_meta_sk(sk) == sk; -+} -+ -+static inline int is_master_tp(const struct tcp_sock *tp) -+{ -+ return !mptcp(tp) || (!tp->mptcp->slave_sk && !is_meta_tp(tp)); -+} -+ -+static inline void mptcp_init_mp_opt(struct mptcp_options_received *mopt) -+{ -+ mopt->saw_mpc = 0; -+ mopt->dss_csum = 0; -+ mopt->drop_me = 0; -+ -+ mopt->is_mp_join = 0; -+ mopt->join_ack = 0; -+ -+ mopt->saw_low_prio = 0; -+ mopt->low_prio = 0; -+ -+ mopt->saw_add_addr = 0; -+ mopt->more_add_addr = 0; -+ -+ mopt->saw_rem_addr = 0; -+ mopt->more_rem_addr = 0; -+ -+ mopt->mp_fail = 0; -+ mopt->mp_fclose = 0; -+} -+ -+static inline void mptcp_reset_mopt(struct tcp_sock *tp) -+{ -+ struct mptcp_options_received *mopt = &tp->mptcp->rx_opt; -+ -+ mopt->saw_low_prio = 0; -+ mopt->saw_add_addr = 0; -+ mopt->more_add_addr = 0; -+ mopt->saw_rem_addr = 0; -+ mopt->more_rem_addr = 0; -+ mopt->join_ack = 0; -+ mopt->mp_fail = 0; -+ mopt->mp_fclose = 0; -+} -+ -+static inline __be32 mptcp_get_highorder_sndbits(const struct sk_buff *skb, -+ const struct mptcp_cb *mpcb) -+{ -+ return htonl(mpcb->snd_high_order[(TCP_SKB_CB(skb)->mptcp_flags & -+ MPTCPHDR_SEQ64_INDEX) ? 1 : 0]); -+} -+ -+static inline u64 mptcp_get_data_seq_64(const struct mptcp_cb *mpcb, int index, -+ u32 data_seq_32) -+{ -+ return ((u64)mpcb->rcv_high_order[index] << 32) | data_seq_32; -+} -+ -+static inline u64 mptcp_get_rcv_nxt_64(const struct tcp_sock *meta_tp) -+{ -+ struct mptcp_cb *mpcb = meta_tp->mpcb; -+ return mptcp_get_data_seq_64(mpcb, mpcb->rcv_hiseq_index, -+ meta_tp->rcv_nxt); -+} -+ -+static inline void mptcp_check_sndseq_wrap(struct tcp_sock *meta_tp, int inc) -+{ -+ if (unlikely(meta_tp->snd_nxt > meta_tp->snd_nxt + inc)) { -+ struct mptcp_cb *mpcb = meta_tp->mpcb; -+ mpcb->snd_hiseq_index = mpcb->snd_hiseq_index ? 0 : 1; -+ mpcb->snd_high_order[mpcb->snd_hiseq_index] += 2; -+ } -+} -+ -+static inline void mptcp_check_rcvseq_wrap(struct tcp_sock *meta_tp, -+ u32 old_rcv_nxt) -+{ -+ if (unlikely(old_rcv_nxt > meta_tp->rcv_nxt)) { -+ struct mptcp_cb *mpcb = meta_tp->mpcb; -+ mpcb->rcv_high_order[mpcb->rcv_hiseq_index] += 2; -+ mpcb->rcv_hiseq_index = mpcb->rcv_hiseq_index ? 0 : 1; -+ } -+} -+ -+static inline int mptcp_sk_can_send(const struct sock *sk) -+{ -+ return tcp_passive_fastopen(sk) || -+ ((1 << sk->sk_state) & (TCPF_ESTABLISHED | TCPF_CLOSE_WAIT) && -+ !tcp_sk(sk)->mptcp->pre_established); -+} -+ -+static inline int mptcp_sk_can_recv(const struct sock *sk) -+{ -+ return (1 << sk->sk_state) & (TCPF_ESTABLISHED | TCPF_FIN_WAIT1 | TCPF_FIN_WAIT2); -+} -+ -+static inline int mptcp_sk_can_send_ack(const struct sock *sk) -+{ -+ return !((1 << sk->sk_state) & (TCPF_SYN_SENT | TCPF_SYN_RECV | -+ TCPF_CLOSE | TCPF_LISTEN)) && -+ !tcp_sk(sk)->mptcp->pre_established; -+} -+ -+static inline bool mptcp_can_sg(const struct sock *meta_sk) -+{ -+ struct mptcp_tcp_sock *mptcp; -+ -+ if (tcp_sk(meta_sk)->mpcb->dss_csum) -+ return false; -+ -+ mptcp_for_each_sub(tcp_sk(meta_sk)->mpcb, mptcp) { -+ struct sock *sk = mptcp_to_sock(mptcp); -+ -+ if (!mptcp_sk_can_send(sk)) -+ continue; -+ if (!(sk->sk_route_caps & NETIF_F_SG)) -+ return false; -+ } -+ return true; -+} -+ -+static inline void mptcp_set_rto(struct sock *sk) -+{ -+ struct inet_connection_sock *micsk = inet_csk(mptcp_meta_sk(sk)); -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct mptcp_tcp_sock *mptcp; -+ __u32 max_rto = 0; -+ -+ /* We are in recovery-phase on the MPTCP-level. Do not update the -+ * RTO, because this would kill exponential backoff. -+ */ -+ if (micsk->icsk_retransmits) -+ return; -+ -+ mptcp_for_each_sub(tp->mpcb, mptcp) { -+ struct sock *sk_it = mptcp_to_sock(mptcp); -+ -+ if ((mptcp_sk_can_send(sk_it) || sk_it->sk_state == TCP_SYN_RECV) && -+ inet_csk(sk_it)->icsk_retransmits == 0 && -+ inet_csk(sk_it)->icsk_backoff == 0 && -+ inet_csk(sk_it)->icsk_rto > max_rto) -+ max_rto = inet_csk(sk_it)->icsk_rto; -+ } -+ if (max_rto) { -+ micsk->icsk_rto = max_rto << 1; -+ -+ /* A successfull rto-measurement - reset backoff counter */ -+ micsk->icsk_backoff = 0; -+ } -+} -+ -+static inline void mptcp_sub_close_passive(struct sock *sk) -+{ -+ struct sock *meta_sk = mptcp_meta_sk(sk); -+ struct tcp_sock *tp = tcp_sk(sk), *meta_tp = tcp_sk(meta_sk); -+ -+ /* Only close, if the app did a send-shutdown (passive close), and we -+ * received the data-ack of the data-fin. -+ */ -+ if (tp->mpcb->passive_close && meta_tp->snd_una == meta_tp->write_seq) -+ mptcp_sub_close(sk, 0); -+} -+ -+static inline void mptcp_fallback_close(struct mptcp_cb *mpcb, -+ struct sock *except) -+{ -+ mptcp_sub_force_close_all(mpcb, except); -+ -+ if (mpcb->pm_ops->close_session) -+ mpcb->pm_ops->close_session(mptcp_meta_sk(except)); -+} -+ -+static inline bool mptcp_fallback_infinite(struct sock *sk, int flag) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct mptcp_cb *mpcb = tp->mpcb; -+ -+ /* If data has been acknowleged on the meta-level, fully_established -+ * will have been set before and thus we will not fall back to infinite -+ * mapping. -+ */ -+ if (likely(tp->mptcp->fully_established)) -+ return false; -+ -+ if (!(flag & MPTCP_FLAG_DATA_ACKED)) -+ return false; -+ -+ /* Don't fallback twice ;) */ -+ if (mpcb->infinite_mapping_snd) -+ return false; -+ -+ pr_debug("%s %#x will fallback - pi %d, src %pI4:%u dst %pI4:%u rcv_nxt %u from %pS\n", -+ __func__, mpcb->mptcp_loc_token, tp->mptcp->path_index, -+ &inet_sk(sk)->inet_saddr, ntohs(inet_sk(sk)->inet_sport), -+ &inet_sk(sk)->inet_daddr, ntohs(inet_sk(sk)->inet_dport), -+ tp->rcv_nxt, __builtin_return_address(0)); -+ if (!is_master_tp(tp)) { -+ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_FBACKSUB); -+ return true; -+ } -+ -+ mpcb->infinite_mapping_snd = 1; -+ mpcb->infinite_mapping_rcv = 1; -+ mpcb->infinite_rcv_seq = mptcp_get_rcv_nxt_64(mptcp_meta_tp(tp)); -+ tp->mptcp->fully_established = 1; -+ -+ mptcp_fallback_close(mpcb, sk); -+ -+ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_FBACKINIT); -+ -+ return false; -+} -+ -+static inline bool mptcp_v6_is_v4_mapped(const struct sock *sk) -+{ -+ return sk->sk_family == AF_INET6 && -+ ipv6_addr_type(&inet6_sk(sk)->saddr) == IPV6_ADDR_MAPPED; -+} -+ -+/* We are in or are becoming to be in infinite mapping mode */ -+static inline bool mptcp_in_infinite_mapping_weak(const struct mptcp_cb *mpcb) -+{ -+ return mpcb->infinite_mapping_rcv || -+ mpcb->infinite_mapping_snd || -+ mpcb->send_infinite_mapping; -+} -+ -+static inline bool mptcp_can_new_subflow(const struct sock *meta_sk) -+{ -+ /* Has been removed from the tk-table. Thus, no new subflows. -+ * -+ * Check for close-state is necessary, because we may have been closed -+ * without passing by mptcp_close(). -+ * -+ * When falling back, no new subflows are allowed either. -+ */ -+ return meta_sk->sk_state != TCP_CLOSE && -+ tcp_sk(meta_sk)->inside_tk_table && -+ !tcp_sk(meta_sk)->mpcb->infinite_mapping_rcv && -+ !tcp_sk(meta_sk)->mpcb->send_infinite_mapping; -+} -+ -+static inline int mptcp_subflow_count(const struct mptcp_cb *mpcb) -+{ -+ struct mptcp_tcp_sock *mptcp; -+ int i = 0; -+ -+ mptcp_for_each_sub(mpcb, mptcp) -+ i++; -+ -+ return i; -+} -+ -+/* TCP and MPTCP mpc flag-depending functions */ -+u16 mptcp_select_window(struct sock *sk); -+void mptcp_tcp_set_rto(struct sock *sk); -+ -+/* TCP and MPTCP flag-depending functions */ -+bool mptcp_prune_ofo_queue(struct sock *sk); -+ -+#else /* CONFIG_MPTCP */ -+#define mptcp_debug(fmt, args...) \ -+ do { \ -+ } while (0) -+ -+static inline struct sock *mptcp_to_sock(const struct mptcp_tcp_sock *mptcp) -+{ -+ return NULL; -+} -+ -+#define mptcp_for_each_sub(__mpcb, __mptcp) \ -+ if (0) -+ -+#define MPTCP_INC_STATS(net, field) \ -+ do { \ -+ } while(0) -+ -+static inline bool mptcp_is_data_fin(const struct sk_buff *skb) -+{ -+ return false; -+} -+static inline bool mptcp_is_data_seq(const struct sk_buff *skb) -+{ -+ return false; -+} -+static inline struct sock *mptcp_meta_sk(const struct sock *sk) -+{ -+ return NULL; -+} -+static inline struct tcp_sock *mptcp_meta_tp(const struct tcp_sock *tp) -+{ -+ return NULL; -+} -+static inline int is_meta_sk(const struct sock *sk) -+{ -+ return 0; -+} -+static inline int is_master_tp(const struct tcp_sock *tp) -+{ -+ return 0; -+} -+static inline void mptcp_del_sock(const struct sock *sk) {} -+static inline void mptcp_update_metasocket(const struct sock *meta_sk) {} -+static inline void mptcp_reinject_data(struct sock *orig_sk, int clone_it) {} -+static inline void mptcp_update_sndbuf(const struct tcp_sock *tp) {} -+static inline void mptcp_clean_rtx_infinite(const struct sk_buff *skb, -+ const struct sock *sk) {} -+static inline void mptcp_sub_close(struct sock *sk, unsigned long delay) {} -+static inline void mptcp_set_rto(const struct sock *sk) {} -+static inline void mptcp_send_fin(const struct sock *meta_sk) {} -+static inline void mptcp_parse_options(const uint8_t *ptr, const int opsize, -+ struct mptcp_options_received *mopt, -+ const struct sk_buff *skb, -+ const struct tcp_sock *tp) {} -+static inline void mptcp_syn_options(const struct sock *sk, -+ struct tcp_out_options *opts, -+ unsigned *remaining) {} -+static inline void mptcp_synack_options(struct request_sock *req, -+ struct tcp_out_options *opts, -+ unsigned *remaining) {} -+ -+static inline void mptcp_established_options(struct sock *sk, -+ struct sk_buff *skb, -+ struct tcp_out_options *opts, -+ unsigned *size) {} -+static inline void mptcp_options_write(__be32 *ptr, struct tcp_sock *tp, -+ const struct tcp_out_options *opts, -+ struct sk_buff *skb) {} -+static inline void mptcp_close(struct sock *meta_sk, long timeout) {} -+static inline bool mptcp_doit(struct sock *sk) -+{ -+ return false; -+} -+static inline int mptcp_check_req_fastopen(struct sock *child, -+ struct request_sock *req) -+{ -+ return 1; -+} -+static inline int mptcp_check_req_master(const struct sock *sk, -+ const struct sock *child, -+ const struct request_sock *req, -+ const struct sk_buff *skb, -+ int drop, -+ u32 tsoff) -+{ -+ return 1; -+} -+static inline struct sock *mptcp_check_req_child(const struct sock *meta_sk, -+ const struct sock *child, -+ const struct request_sock *req, -+ struct sk_buff *skb, -+ const struct mptcp_options_received *mopt) -+{ -+ return NULL; -+} -+static inline unsigned int mptcp_current_mss(struct sock *meta_sk) -+{ -+ return 0; -+} -+static inline void mptcp_sub_close_passive(struct sock *sk) {} -+static inline bool mptcp_fallback_infinite(const struct sock *sk, int flag) -+{ -+ return false; -+} -+static inline void mptcp_init_mp_opt(const struct mptcp_options_received *mopt) {} -+static inline void mptcp_prepare_for_backlog(struct sock *sk, struct sk_buff *skb) {} -+static inline bool mptcp_check_rtt(const struct tcp_sock *tp, int time) -+{ -+ return false; -+} -+static inline int mptcp_check_snd_buf(const struct tcp_sock *tp) -+{ -+ return 0; -+} -+static inline void mptcp_push_pending_frames(struct sock *meta_sk) {} -+static inline void mptcp_send_reset(const struct sock *sk) {} -+static inline void mptcp_sub_force_close_all(struct mptcp_cb *mpcb, -+ struct sock *except) {} -+static inline bool mptcp_handle_options(struct sock *sk, -+ const struct tcphdr *th, -+ struct sk_buff *skb) -+{ -+ return false; -+} -+static inline void mptcp_reset_mopt(struct tcp_sock *tp) {} -+static inline void __init mptcp_init(void) {} -+static inline bool mptcp_can_sg(const struct sock *meta_sk) -+{ -+ return false; -+} -+static inline unsigned int mptcp_xmit_size_goal(const struct sock *meta_sk, -+ u32 mss_now, int large_allowed) -+{ -+ return 0; -+} -+static inline void mptcp_destroy_sock(struct sock *sk) {} -+static inline int mptcp_rcv_synsent_state_process(struct sock *sk, -+ struct sock **skptr, -+ struct sk_buff *skb, -+ const struct mptcp_options_received *mopt) -+{ -+ return 0; -+} -+static inline bool mptcp_can_sendpage(struct sock *sk) -+{ -+ return false; -+} -+static inline int mptcp_init_tw_sock(struct sock *sk, -+ struct tcp_timewait_sock *tw) -+{ -+ return 0; -+} -+static inline void mptcp_twsk_destructor(struct tcp_timewait_sock *tw) {} -+static inline void mptcp_disconnect(struct sock *meta_sk) {} -+static inline void mptcp_tsq_flags(struct sock *sk) {} -+static inline void mptcp_tsq_sub_deferred(struct sock *meta_sk) {} -+static inline void mptcp_hash_remove_bh(struct tcp_sock *meta_tp) {} -+static inline void mptcp_remove_shortcuts(const struct mptcp_cb *mpcb, -+ const struct sk_buff *skb) {} -+static inline void mptcp_init_tcp_sock(struct sock *sk) {} -+static inline void mptcp_disable_static_key(void) {} -+static inline void mptcp_cookies_reqsk_init(struct request_sock *req, -+ struct mptcp_options_received *mopt, -+ struct sk_buff *skb) {} -+static inline void mptcp_mpcb_put(struct mptcp_cb *mpcb) {} -+static inline void mptcp_fin(struct sock *meta_sk) {} -+static inline bool mptcp_in_infinite_mapping_weak(const struct mptcp_cb *mpcb) -+{ -+ return false; -+} -+static inline bool mptcp_can_new_subflow(const struct sock *meta_sk) -+{ -+ return false; -+} -+ -+#endif /* CONFIG_MPTCP */ -+ -+#endif /* _MPTCP_H */ -diff -aurN linux-4.19.104/include/net/mptcp_v4.h mptcp-mptcp_v0.95/include/net/mptcp_v4.h ---- linux-4.19.104/include/net/mptcp_v4.h 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_v0.95/include/net/mptcp_v4.h 2020-02-17 11:29:55.000000000 +0100 -@@ -0,0 +1,76 @@ -+/* -+ * MPTCP implementation -+ * -+ * Initial Design & Implementation: -+ * Sébastien Barré -+ * -+ * Current Maintainer & Author: -+ * Christoph Paasch -+ * -+ * Additional authors: -+ * Jaakko Korkeaniemi -+ * Gregory Detal -+ * Fabien Duchêne -+ * Andreas Seelinger -+ * Lavkesh Lahngir -+ * Andreas Ripke -+ * Vlad Dogaru -+ * Octavian Purdila -+ * John Ronan -+ * Catalin Nicutar -+ * Brandon Heller -+ * -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version -+ * 2 of the License, or (at your option) any later version. -+ */ -+ -+#ifndef MPTCP_V4_H_ -+#define MPTCP_V4_H_ -+ -+ -+#include -+#include -+#include -+#include -+#include -+ -+extern struct request_sock_ops mptcp_request_sock_ops; -+extern const struct inet_connection_sock_af_ops mptcp_v4_specific; -+extern struct tcp_request_sock_ops mptcp_request_sock_ipv4_ops; -+extern struct tcp_request_sock_ops mptcp_join_request_sock_ipv4_ops; -+ -+#ifdef CONFIG_MPTCP -+ -+int mptcp_v4_do_rcv(struct sock *meta_sk, struct sk_buff *skb); -+struct sock *mptcp_v4_search_req(const __be16 rport, const __be32 raddr, -+ const __be32 laddr, const struct net *net); -+int __mptcp_init4_subsockets(struct sock *meta_sk, const struct mptcp_loc4 *loc, -+ __be16 sport, struct mptcp_rem4 *rem, -+ struct sock **subsk); -+int mptcp_pm_v4_init(void); -+void mptcp_pm_v4_undo(void); -+u32 mptcp_v4_get_nonce(__be32 saddr, __be32 daddr, __be16 sport, __be16 dport); -+u64 mptcp_v4_get_key(__be32 saddr, __be32 daddr, __be16 sport, __be16 dport, -+ u32 seed); -+ -+static inline int mptcp_init4_subsockets(struct sock *meta_sk, -+ const struct mptcp_loc4 *loc, -+ struct mptcp_rem4 *rem) -+{ -+ return __mptcp_init4_subsockets(meta_sk, loc, 0, rem, NULL); -+} -+ -+#else -+ -+static inline int mptcp_v4_do_rcv(const struct sock *meta_sk, -+ const struct sk_buff *skb) -+{ -+ return 0; -+} -+ -+#endif /* CONFIG_MPTCP */ -+ -+#endif /* MPTCP_V4_H_ */ -diff -aurN linux-4.19.104/include/net/mptcp_v6.h mptcp-mptcp_v0.95/include/net/mptcp_v6.h ---- linux-4.19.104/include/net/mptcp_v6.h 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_v0.95/include/net/mptcp_v6.h 2020-02-17 11:29:55.000000000 +0100 -@@ -0,0 +1,77 @@ -+/* -+ * MPTCP implementation -+ * -+ * Initial Design & Implementation: -+ * Sébastien Barré -+ * -+ * Current Maintainer & Author: -+ * Jaakko Korkeaniemi -+ * -+ * Additional authors: -+ * Jaakko Korkeaniemi -+ * Gregory Detal -+ * Fabien Duchêne -+ * Andreas Seelinger -+ * Lavkesh Lahngir -+ * Andreas Ripke -+ * Vlad Dogaru -+ * Octavian Purdila -+ * John Ronan -+ * Catalin Nicutar -+ * Brandon Heller -+ * -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version -+ * 2 of the License, or (at your option) any later version. -+ */ -+ -+#ifndef _MPTCP_V6_H -+#define _MPTCP_V6_H -+ -+#include -+#include -+ -+#include -+ -+ -+#ifdef CONFIG_MPTCP -+extern const struct inet_connection_sock_af_ops mptcp_v6_mapped; -+extern const struct inet_connection_sock_af_ops mptcp_v6_specific; -+extern struct request_sock_ops mptcp6_request_sock_ops; -+extern struct tcp_request_sock_ops mptcp_request_sock_ipv6_ops; -+extern struct tcp_request_sock_ops mptcp_join_request_sock_ipv6_ops; -+ -+int mptcp_v6_do_rcv(struct sock *meta_sk, struct sk_buff *skb); -+struct sock *mptcp_v6_search_req(const __be16 rport, const struct in6_addr *raddr, -+ const struct in6_addr *laddr, const struct net *net); -+int __mptcp_init6_subsockets(struct sock *meta_sk, const struct mptcp_loc6 *loc, -+ __be16 sport, struct mptcp_rem6 *rem, -+ struct sock **subsk); -+int mptcp_pm_v6_init(void); -+void mptcp_pm_v6_undo(void); -+__u32 mptcp_v6_get_nonce(const __be32 *saddr, const __be32 *daddr, -+ __be16 sport, __be16 dport); -+u64 mptcp_v6_get_key(const __be32 *saddr, const __be32 *daddr, -+ __be16 sport, __be16 dport, u32 seed); -+ -+static inline int mptcp_init6_subsockets(struct sock *meta_sk, -+ const struct mptcp_loc6 *loc, -+ struct mptcp_rem6 *rem) -+{ -+ return __mptcp_init6_subsockets(meta_sk, loc, 0, rem, NULL); -+} -+ -+#else /* CONFIG_MPTCP */ -+ -+#define mptcp_v6_mapped ipv6_mapped -+ -+static inline int mptcp_v6_do_rcv(struct sock *meta_sk, struct sk_buff *skb) -+{ -+ return 0; -+} -+ -+#endif /* CONFIG_MPTCP */ -+ -+#endif /* _MPTCP_V6_H */ -diff -aurN linux-4.19.104/include/net/net_namespace.h mptcp-mptcp_v0.95/include/net/net_namespace.h ---- linux-4.19.104/include/net/net_namespace.h 2020-02-14 22:33:28.000000000 +0100 -+++ mptcp-mptcp_v0.95/include/net/net_namespace.h 2020-02-17 11:29:55.000000000 +0100 -@@ -19,6 +19,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -110,6 +111,9 @@ - #if IS_ENABLED(CONFIG_IPV6) - struct netns_ipv6 ipv6; - #endif -+#if IS_ENABLED(CONFIG_MPTCP) -+ struct netns_mptcp mptcp; -+#endif - #if IS_ENABLED(CONFIG_IEEE802154_6LOWPAN) - struct netns_ieee802154_lowpan ieee802154_lowpan; - #endif -diff -aurN linux-4.19.104/include/net/netns/mptcp.h mptcp-mptcp_v0.95/include/net/netns/mptcp.h ---- linux-4.19.104/include/net/netns/mptcp.h 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_v0.95/include/net/netns/mptcp.h 2020-02-17 11:29:55.000000000 +0100 -@@ -0,0 +1,52 @@ -+/* -+ * MPTCP implementation - MPTCP namespace -+ * -+ * Initial Design & Implementation: -+ * Sébastien Barré -+ * -+ * Current Maintainer: -+ * Christoph Paasch -+ * -+ * Additional authors: -+ * Jaakko Korkeaniemi -+ * Gregory Detal -+ * Fabien Duchêne -+ * Andreas Seelinger -+ * Lavkesh Lahngir -+ * Andreas Ripke -+ * Vlad Dogaru -+ * Octavian Purdila -+ * John Ronan -+ * Catalin Nicutar -+ * Brandon Heller -+ * -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version -+ * 2 of the License, or (at your option) any later version. -+ */ -+ -+#ifndef __NETNS_MPTCP_H__ -+#define __NETNS_MPTCP_H__ -+ -+#include -+ -+enum { -+ MPTCP_PM_FULLMESH = 0, -+ MPTCP_PM_MAX -+}; -+ -+struct mptcp_mib; -+ -+struct netns_mptcp { -+ DEFINE_SNMP_STAT(struct mptcp_mib, mptcp_statistics); -+ -+#ifdef CONFIG_PROC_FS -+ struct proc_dir_entry *proc_net_mptcp; -+#endif -+ -+ void *path_managers[MPTCP_PM_MAX]; -+}; -+ -+#endif /* __NETNS_MPTCP_H__ */ -diff -aurN linux-4.19.104/include/net/snmp.h mptcp-mptcp_v0.95/include/net/snmp.h ---- linux-4.19.104/include/net/snmp.h 2020-02-14 22:33:28.000000000 +0100 -+++ mptcp-mptcp_v0.95/include/net/snmp.h 2020-02-17 11:29:55.000000000 +0100 -@@ -91,7 +91,6 @@ - atomic_long_t mibs[ICMP6MSG_MIB_MAX]; - }; - -- - /* TCP */ - #define TCP_MIB_MAX __TCP_MIB_MAX - struct tcp_mib { -diff -aurN linux-4.19.104/include/net/sock.h mptcp-mptcp_v0.95/include/net/sock.h ---- linux-4.19.104/include/net/sock.h 2020-02-14 22:33:28.000000000 +0100 -+++ mptcp-mptcp_v0.95/include/net/sock.h 2020-02-17 11:29:55.000000000 +0100 -@@ -815,6 +815,7 @@ - SOCK_SELECT_ERR_QUEUE, /* Wake select on error queue */ - SOCK_RCU_FREE, /* wait rcu grace period in sk_destruct() */ - SOCK_TXTIME, -+ SOCK_MPTCP, /* MPTCP set on this socket */ - }; - - #define SK_FLAGS_TIMESTAMP ((1UL << SOCK_TIMESTAMP) | (1UL << SOCK_TIMESTAMPING_RX_SOFTWARE)) -@@ -1118,6 +1119,7 @@ - void (*unhash)(struct sock *sk); - void (*rehash)(struct sock *sk); - int (*get_port)(struct sock *sk, unsigned short snum); -+ void (*clear_sk)(struct sock *sk, int size); - - /* Keeping track of sockets in use */ - #ifdef CONFIG_PROC_FS -diff -aurN linux-4.19.104/include/net/tcp.h mptcp-mptcp_v0.95/include/net/tcp.h ---- linux-4.19.104/include/net/tcp.h 2020-02-14 22:33:28.000000000 +0100 -+++ mptcp-mptcp_v0.95/include/net/tcp.h 2020-02-17 11:29:55.000000000 +0100 -@@ -185,6 +185,7 @@ - #define TCPOPT_SACK 5 /* SACK Block */ - #define TCPOPT_TIMESTAMP 8 /* Better RTT estimations/PAWS */ - #define TCPOPT_MD5SIG 19 /* MD5 Signature (RFC2385) */ -+#define TCPOPT_MPTCP 30 - #define TCPOPT_FASTOPEN 34 /* Fast open (RFC7413) */ - #define TCPOPT_EXP 254 /* Experimental */ - /* Magic number to be after the option value for sharing TCP -@@ -241,6 +242,31 @@ - */ - #define TFO_SERVER_WO_SOCKOPT1 0x400 - -+/* Flags from tcp_input.c for tcp_ack */ -+#define FLAG_DATA 0x01 /* Incoming frame contained data. */ -+#define FLAG_WIN_UPDATE 0x02 /* Incoming ACK was a window update. */ -+#define FLAG_DATA_ACKED 0x04 /* This ACK acknowledged new data. */ -+#define FLAG_RETRANS_DATA_ACKED 0x08 /* "" "" some of which was retransmitted. */ -+#define FLAG_SYN_ACKED 0x10 /* This ACK acknowledged SYN. */ -+#define FLAG_DATA_SACKED 0x20 /* New SACK. */ -+#define FLAG_ECE 0x40 /* ECE in this ACK */ -+#define FLAG_LOST_RETRANS 0x80 /* This ACK marks some retransmission lost */ -+#define FLAG_SLOWPATH 0x100 /* Do not skip RFC checks for window update.*/ -+#define FLAG_ORIG_SACK_ACKED 0x200 /* Never retransmitted data are (s)acked */ -+#define FLAG_SND_UNA_ADVANCED 0x400 /* Snd_una was changed (!= FLAG_DATA_ACKED) */ -+#define FLAG_DSACKING_ACK 0x800 /* SACK blocks contained D-SACK info */ -+#define FLAG_SET_XMIT_TIMER 0x1000 /* Set TLP or RTO timer */ -+#define FLAG_SACK_RENEGING 0x2000 /* snd_una advanced to a sacked seq */ -+#define FLAG_UPDATE_TS_RECENT 0x4000 /* tcp_replace_ts_recent() */ -+#define FLAG_NO_CHALLENGE_ACK 0x8000 /* do not call tcp_send_challenge_ack() */ -+#define FLAG_ACK_MAYBE_DELAYED 0x10000 /* Likely a delayed ACK */ -+ -+#define MPTCP_FLAG_DATA_ACKED 0x20000 -+ -+#define FLAG_ACKED (FLAG_DATA_ACKED|FLAG_SYN_ACKED) -+#define FLAG_NOT_DUP (FLAG_DATA|FLAG_WIN_UPDATE|FLAG_ACKED) -+#define FLAG_CA_ALERT (FLAG_DATA_SACKED|FLAG_ECE|FLAG_DSACKING_ACK) -+#define FLAG_FORWARD_PROGRESS (FLAG_ACKED|FLAG_DATA_SACKED) - - /* sysctl variables for tcp */ - extern int sysctl_tcp_max_orphans; -@@ -313,6 +339,96 @@ - #define TCP_DEC_STATS(net, field) SNMP_DEC_STATS((net)->mib.tcp_statistics, field) - #define TCP_ADD_STATS(net, field, val) SNMP_ADD_STATS((net)->mib.tcp_statistics, field, val) - -+/**** START - Exports needed for MPTCP ****/ -+extern const struct tcp_request_sock_ops tcp_request_sock_ipv4_ops; -+extern const struct tcp_request_sock_ops tcp_request_sock_ipv6_ops; -+ -+struct mptcp_options_received; -+ -+void tcp_cleanup_rbuf(struct sock *sk, int copied); -+void tcp_cwnd_validate(struct sock *sk, bool is_cwnd_limited); -+int tcp_close_state(struct sock *sk); -+void tcp_minshall_update(struct tcp_sock *tp, unsigned int mss_now, -+ const struct sk_buff *skb); -+int tcp_xmit_probe_skb(struct sock *sk, int urgent, int mib); -+void tcp_event_new_data_sent(struct sock *sk, struct sk_buff *skb); -+int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it, -+ gfp_t gfp_mask); -+unsigned int tcp_mss_split_point(const struct sock *sk, -+ const struct sk_buff *skb, -+ unsigned int mss_now, -+ unsigned int max_segs, -+ int nonagle); -+bool tcp_nagle_test(const struct tcp_sock *tp, const struct sk_buff *skb, -+ unsigned int cur_mss, int nonagle); -+bool tcp_snd_wnd_test(const struct tcp_sock *tp, const struct sk_buff *skb, -+ unsigned int cur_mss); -+unsigned int tcp_cwnd_test(const struct tcp_sock *tp, const struct sk_buff *skb); -+int tcp_init_tso_segs(struct sk_buff *skb, unsigned int mss_now); -+int __pskb_trim_head(struct sk_buff *skb, int len); -+void tcp_queue_skb(struct sock *sk, struct sk_buff *skb); -+void tcp_init_nondata_skb(struct sk_buff *skb, u32 seq, u8 flags); -+void tcp_reset(struct sock *sk); -+bool tcp_may_update_window(const struct tcp_sock *tp, const u32 ack, -+ const u32 ack_seq, const u32 nwin); -+bool tcp_urg_mode(const struct tcp_sock *tp); -+void tcp_ack_probe(struct sock *sk); -+void tcp_rearm_rto(struct sock *sk); -+int tcp_write_timeout(struct sock *sk); -+bool retransmits_timed_out(struct sock *sk, -+ unsigned int boundary, -+ unsigned int timeout); -+void tcp_write_err(struct sock *sk); -+void tcp_adjust_pcount(struct sock *sk, const struct sk_buff *skb, int decr); -+void tcp_update_skb_after_send(struct tcp_sock *tp, struct sk_buff *skb); -+void tcp_set_skb_tso_segs(struct sk_buff *skb, unsigned int mss_now); -+ -+void tcp_v4_reqsk_send_ack(const struct sock *sk, struct sk_buff *skb, -+ struct request_sock *req); -+void tcp_v4_send_reset(const struct sock *sk, struct sk_buff *skb); -+struct sock *tcp_v4_cookie_check(struct sock *sk, struct sk_buff *skb); -+void tcp_v4_reqsk_destructor(struct request_sock *req); -+ -+void tcp_v6_reqsk_send_ack(const struct sock *sk, struct sk_buff *skb, -+ struct request_sock *req); -+void tcp_v6_send_reset(const struct sock *sk, struct sk_buff *skb); -+struct sock *tcp_v6_cookie_check(struct sock *sk, struct sk_buff *skb); -+int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb); -+int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len); -+void tcp_v6_destroy_sock(struct sock *sk); -+void inet6_sk_rx_dst_set(struct sock *sk, const struct sk_buff *skb); -+void tcp_v6_hash(struct sock *sk); -+struct sock *tcp_v6_hnd_req(struct sock *sk,struct sk_buff *skb); -+struct sock *tcp_v6_syn_recv_sock(const struct sock *sk, struct sk_buff *skb, -+ struct request_sock *req, -+ struct dst_entry *dst, -+ struct request_sock *req_unhash, -+ bool *own_req); -+void tcp_v6_reqsk_destructor(struct request_sock *req); -+ -+unsigned int tcp_xmit_size_goal(struct sock *sk, u32 mss_now, -+ int large_allowed); -+u32 tcp_tso_acked(struct sock *sk, struct sk_buff *skb); -+ -+void skb_clone_fraglist(struct sk_buff *skb); -+ -+void inet_twsk_free(struct inet_timewait_sock *tw); -+int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb); -+/* These states need RST on ABORT according to RFC793 */ -+static inline bool tcp_need_reset(int state) -+{ -+ return (1 << state) & -+ (TCPF_ESTABLISHED | TCPF_CLOSE_WAIT | TCPF_FIN_WAIT1 | -+ TCPF_FIN_WAIT2 | TCPF_SYN_RECV); -+} -+ -+int __must_check tcp_queue_rcv(struct sock *sk, struct sk_buff *skb, int hdrlen, -+ bool *fragstolen); -+void tcp_ofo_queue(struct sock *sk); -+void tcp_data_queue_ofo(struct sock *sk, struct sk_buff *skb); -+int linear_payload_sz(bool first_skb); -+/**** END - Exports needed for MPTCP ****/ -+ - void tcp_tasklet_init(void); - - void tcp_v4_err(struct sk_buff *skb, u32); -@@ -412,7 +528,9 @@ - struct vm_area_struct *vma); - void tcp_parse_options(const struct net *net, const struct sk_buff *skb, - struct tcp_options_received *opt_rx, -- int estab, struct tcp_fastopen_cookie *foc); -+ struct mptcp_options_received *mopt_rx, -+ int estab, struct tcp_fastopen_cookie *foc, -+ struct tcp_sock *tp); - const u8 *tcp_parse_md5sig_option(const struct tcphdr *th); - - /* -@@ -421,6 +539,7 @@ - - void tcp_v4_send_check(struct sock *sk, struct sk_buff *skb); - void tcp_v4_mtu_reduced(struct sock *sk); -+void tcp_v6_mtu_reduced(struct sock *sk); - void tcp_req_err(struct sock *sk, u32 seq, bool abort); - int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb); - struct sock *tcp_create_openreq_child(const struct sock *sk, -@@ -538,7 +657,8 @@ - - u32 __cookie_v4_init_sequence(const struct iphdr *iph, const struct tcphdr *th, - u16 *mssp); --__u32 cookie_v4_init_sequence(const struct sk_buff *skb, __u16 *mss); -+__u32 cookie_v4_init_sequence(struct request_sock *req, const struct sock *sk, -+ const struct sk_buff *skb, __u16 *mss); - u64 cookie_init_timestamp(struct request_sock *req); - bool cookie_timestamp_decode(const struct net *net, - struct tcp_options_received *opt); -@@ -552,7 +672,8 @@ - - u32 __cookie_v6_init_sequence(const struct ipv6hdr *iph, - const struct tcphdr *th, u16 *mssp); --__u32 cookie_v6_init_sequence(const struct sk_buff *skb, __u16 *mss); -+__u32 cookie_v6_init_sequence(struct request_sock *req, const struct sock *sk, -+ const struct sk_buff *skb, __u16 *mss); - #endif - /* tcp_output.c */ - -@@ -588,10 +709,16 @@ - void tcp_skb_collapse_tstamp(struct sk_buff *skb, - const struct sk_buff *next_skb); - -+u16 tcp_select_window(struct sock *sk); -+bool tcp_write_xmit(struct sock *sk, unsigned int mss_now, int nonagle, -+ int push_one, gfp_t gfp); -+ - /* tcp_input.c */ - void tcp_rearm_rto(struct sock *sk); - void tcp_synack_rtt_meas(struct sock *sk, struct request_sock *req); - void tcp_reset(struct sock *sk); -+void tcp_set_rto(struct sock *sk); -+bool tcp_should_expand_sndbuf(const struct sock *sk); - void tcp_skb_mark_lost_uncond_verify(struct tcp_sock *tp, struct sk_buff *skb); - void tcp_fin(struct sock *sk); - -@@ -635,7 +762,7 @@ - } - - /* tcp.c */ --void tcp_get_info(struct sock *, struct tcp_info *); -+void tcp_get_info(struct sock *, struct tcp_info *, bool no_lock); - - /* Read 'sendfile()'-style from a TCP socket */ - int tcp_read_sock(struct sock *sk, read_descriptor_t *desc, -@@ -823,6 +950,12 @@ - u16 tcp_gso_size; - }; - }; -+ -+#ifdef CONFIG_MPTCP -+ __u8 mptcp_flags; /* flags for the MPTCP layer */ -+ __u8 dss_off; /* Number of 4-byte words until -+ * seq-number */ -+#endif - __u8 tcp_flags; /* TCP header flags. (tcp[13]) */ - - __u8 sacked; /* State flags for SACK. */ -@@ -841,6 +974,14 @@ - has_rxtstamp:1, /* SKB has a RX timestamp */ - unused:5; - __u32 ack_seq; /* Sequence number ACK'd */ -+ -+#ifdef CONFIG_MPTCP -+ union { /* For MPTCP outgoing frames */ -+ __u32 path_mask; /* paths that tried to send this skb */ -+ __u32 dss[6]; /* DSS options */ -+ }; -+#endif -+ - union { - struct { - /* There is space for up to 24 bytes */ -@@ -1067,6 +1208,8 @@ - int tcp_set_allowed_congestion_control(char *allowed); - int tcp_set_congestion_control(struct sock *sk, const char *name, bool load, - bool reinit, bool cap_net_admin); -+int __tcp_set_congestion_control(struct sock *sk, const char *name, bool load, -+ bool reinit, bool cap_net_admin); - u32 tcp_slow_start(struct tcp_sock *tp, u32 acked); - void tcp_cong_avoid_ai(struct tcp_sock *tp, u32 w, u32 acked); - -@@ -1361,6 +1504,19 @@ - space - (space>>tcp_adv_win_scale); - } - -+#ifdef CONFIG_MPTCP -+extern struct static_key mptcp_static_key; -+static inline bool mptcp(const struct tcp_sock *tp) -+{ -+ return static_key_false(&mptcp_static_key) && tp->mpc; -+} -+#else -+static inline bool mptcp(const struct tcp_sock *tp) -+{ -+ return 0; -+} -+#endif -+ - /* Note: caller must be prepared to deal with negative returns */ - static inline int tcp_space(const struct sock *sk) - { -@@ -1893,6 +2049,32 @@ - #endif - }; - -+/* TCP/MPTCP-specific functions */ -+struct tcp_sock_ops { -+ u32 (*__select_window)(struct sock *sk); -+ u16 (*select_window)(struct sock *sk); -+ void (*select_initial_window)(const struct sock *sk, int __space, -+ __u32 mss, __u32 *rcv_wnd, -+ __u32 *window_clamp, int wscale_ok, -+ __u8 *rcv_wscale, __u32 init_rcv_wnd); -+ int (*select_size)(const struct sock *sk, bool first_skb, bool zc); -+ void (*init_buffer_space)(struct sock *sk); -+ void (*set_rto)(struct sock *sk); -+ bool (*should_expand_sndbuf)(const struct sock *sk); -+ void (*send_fin)(struct sock *sk); -+ bool (*write_xmit)(struct sock *sk, unsigned int mss_now, int nonagle, -+ int push_one, gfp_t gfp); -+ void (*send_active_reset)(struct sock *sk, gfp_t priority); -+ int (*write_wakeup)(struct sock *sk, int mib); -+ void (*retransmit_timer)(struct sock *sk); -+ void (*time_wait)(struct sock *sk, int state, int timeo); -+ void (*cleanup_rbuf)(struct sock *sk, int copied); -+ void (*cwnd_validate)(struct sock *sk, bool is_cwnd_limited); -+ int (*set_cong_ctrl)(struct sock *sk, const char *name, bool load, -+ bool reinit, bool cap_net_admin); -+}; -+extern const struct tcp_sock_ops tcp_specific; -+ - struct tcp_request_sock_ops { - u16 mss_clamp; - #ifdef CONFIG_TCP_MD5SIG -@@ -1903,12 +2085,13 @@ - const struct sock *sk, - const struct sk_buff *skb); - #endif -- void (*init_req)(struct request_sock *req, -- const struct sock *sk_listener, -- struct sk_buff *skb); -+ int (*init_req)(struct request_sock *req, -+ const struct sock *sk_listener, -+ struct sk_buff *skb, -+ bool want_cookie); - #ifdef CONFIG_SYN_COOKIES -- __u32 (*cookie_init_seq)(const struct sk_buff *skb, -- __u16 *mss); -+ __u32 (*cookie_init_seq)(struct request_sock *req, const struct sock *sk, -+ const struct sk_buff *skb, __u16 *mss); - #endif - struct dst_entry *(*route_req)(const struct sock *sk, struct flowi *fl, - const struct request_sock *req); -@@ -1922,15 +2105,17 @@ - - #ifdef CONFIG_SYN_COOKIES - static inline __u32 cookie_init_sequence(const struct tcp_request_sock_ops *ops, -+ struct request_sock *req, - const struct sock *sk, struct sk_buff *skb, - __u16 *mss) - { - tcp_synq_overflow(sk); - __NET_INC_STATS(sock_net(sk), LINUX_MIB_SYNCOOKIESSENT); -- return ops->cookie_init_seq(skb, mss); -+ return ops->cookie_init_seq(req, sk, skb, mss); - } - #else - static inline __u32 cookie_init_sequence(const struct tcp_request_sock_ops *ops, -+ struct request_sock *req, - const struct sock *sk, struct sk_buff *skb, - __u16 *mss) - { -diff -aurN linux-4.19.104/include/net/tcp_states.h mptcp-mptcp_v0.95/include/net/tcp_states.h ---- linux-4.19.104/include/net/tcp_states.h 2020-02-14 22:33:28.000000000 +0100 -+++ mptcp-mptcp_v0.95/include/net/tcp_states.h 2020-02-17 11:29:55.000000000 +0100 -@@ -26,6 +26,7 @@ - TCP_LISTEN, - TCP_CLOSING, /* Now a valid state */ - TCP_NEW_SYN_RECV, -+ TCP_RST_WAIT, - - TCP_MAX_STATES /* Leave at the end! */ - }; -@@ -47,6 +48,7 @@ - TCPF_LISTEN = (1 << TCP_LISTEN), - TCPF_CLOSING = (1 << TCP_CLOSING), - TCPF_NEW_SYN_RECV = (1 << TCP_NEW_SYN_RECV), -+ TCPF_RST_WAIT = (1 << TCP_RST_WAIT), - }; - - #endif /* _LINUX_TCP_STATES_H */ -diff -aurN linux-4.19.104/include/net/transp_v6.h mptcp-mptcp_v0.95/include/net/transp_v6.h ---- linux-4.19.104/include/net/transp_v6.h 2020-02-14 22:33:28.000000000 +0100 -+++ mptcp-mptcp_v0.95/include/net/transp_v6.h 2020-02-17 11:29:55.000000000 +0100 -@@ -58,6 +58,8 @@ - - /* address family specific functions */ - extern const struct inet_connection_sock_af_ops ipv4_specific; -+extern const struct inet_connection_sock_af_ops ipv6_mapped; -+extern const struct inet_connection_sock_af_ops ipv6_specific; - - void inet6_destroy_sock(struct sock *sk); - -diff -aurN linux-4.19.104/include/trace/events/tcp.h mptcp-mptcp_v0.95/include/trace/events/tcp.h ---- linux-4.19.104/include/trace/events/tcp.h 2020-02-14 22:33:28.000000000 +0100 -+++ mptcp-mptcp_v0.95/include/trace/events/tcp.h 2020-02-17 11:29:55.000000000 +0100 -@@ -10,6 +10,7 @@ - #include - #include - #include -+#include - #include - - #define TP_STORE_V4MAPPED(__entry, saddr, daddr) \ -@@ -178,6 +179,13 @@ - TP_ARGS(sk) - ); - -+DEFINE_EVENT(tcp_event_sk_skb, mptcp_retransmit, -+ -+ TP_PROTO(const struct sock *sk, const struct sk_buff *skb), -+ -+ TP_ARGS(sk, skb) -+); -+ - TRACE_EVENT(tcp_retransmit_synack, - - TP_PROTO(const struct sock *sk, const struct request_sock *req), -@@ -245,6 +253,7 @@ - __field(__u32, srtt) - __field(__u32, rcv_wnd) - __field(__u64, sock_cookie) -+ __field(__u8, mptcp) - ), - - TP_fast_assign( -@@ -271,13 +280,15 @@ - __entry->ssthresh = tcp_current_ssthresh(sk); - __entry->srtt = tp->srtt_us >> 3; - __entry->sock_cookie = sock_gen_cookie(sk); -+ __entry->mptcp = mptcp(tp) ? tp->mptcp->path_index : 0; - ), - -- TP_printk("src=%pISpc dest=%pISpc mark=%#x data_len=%d snd_nxt=%#x snd_una=%#x snd_cwnd=%u ssthresh=%u snd_wnd=%u srtt=%u rcv_wnd=%u sock_cookie=%llx", -+ TP_printk("src=%pISpc dest=%pISpc mark=%#x data_len=%d snd_nxt=%#x snd_una=%#x snd_cwnd=%u ssthresh=%u snd_wnd=%u srtt=%u rcv_wnd=%u sock_cookie=%llx mptcp=%d", - __entry->saddr, __entry->daddr, __entry->mark, - __entry->data_len, __entry->snd_nxt, __entry->snd_una, - __entry->snd_cwnd, __entry->ssthresh, __entry->snd_wnd, -- __entry->srtt, __entry->rcv_wnd, __entry->sock_cookie) -+ __entry->srtt, __entry->rcv_wnd, __entry->sock_cookie, -+ __entry->mptcp) - ); - - #endif /* _TRACE_TCP_H */ -diff -aurN linux-4.19.104/include/uapi/linux/bpf.h mptcp-mptcp_v0.95/include/uapi/linux/bpf.h ---- linux-4.19.104/include/uapi/linux/bpf.h 2020-02-14 22:33:28.000000000 +0100 -+++ mptcp-mptcp_v0.95/include/uapi/linux/bpf.h 2020-02-17 11:29:55.000000000 +0100 -@@ -2674,6 +2674,7 @@ - BPF_TCP_LISTEN, - BPF_TCP_CLOSING, /* Now a valid state */ - BPF_TCP_NEW_SYN_RECV, -+ BPF_TCP_RST_WAIT, - - BPF_TCP_MAX_STATES /* Leave at the end! */ - }; -diff -aurN linux-4.19.104/include/uapi/linux/if.h mptcp-mptcp_v0.95/include/uapi/linux/if.h ---- linux-4.19.104/include/uapi/linux/if.h 2020-02-14 22:33:28.000000000 +0100 -+++ mptcp-mptcp_v0.95/include/uapi/linux/if.h 2020-02-17 11:29:55.000000000 +0100 -@@ -132,6 +132,9 @@ - #define IFF_ECHO IFF_ECHO - #endif /* __UAPI_DEF_IF_NET_DEVICE_FLAGS_LOWER_UP_DORMANT_ECHO */ - -+#define IFF_NOMULTIPATH 0x80000 /* Disable for MPTCP */ -+#define IFF_MPBACKUP 0x100000 /* Use as backup path for MPTCP */ -+ - #define IFF_VOLATILE (IFF_LOOPBACK|IFF_POINTOPOINT|IFF_BROADCAST|IFF_ECHO|\ - IFF_MASTER|IFF_SLAVE|IFF_RUNNING|IFF_LOWER_UP|IFF_DORMANT) - -diff -aurN linux-4.19.104/include/uapi/linux/mptcp.h mptcp-mptcp_v0.95/include/uapi/linux/mptcp.h ---- linux-4.19.104/include/uapi/linux/mptcp.h 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_v0.95/include/uapi/linux/mptcp.h 2020-02-17 11:29:55.000000000 +0100 -@@ -0,0 +1,149 @@ -+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ -+/* -+ * Netlink API for Multipath TCP -+ * -+ * Author: Gregory Detal -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version -+ * 2 of the License, or (at your option) any later version. -+ */ -+ -+#ifndef _LINUX_MPTCP_H -+#define _LINUX_MPTCP_H -+ -+#define MPTCP_GENL_NAME "mptcp" -+#define MPTCP_GENL_EV_GRP_NAME "mptcp_events" -+#define MPTCP_GENL_CMD_GRP_NAME "mptcp_commands" -+#define MPTCP_GENL_VER 0x1 -+ -+/* -+ * ATTR types defined for MPTCP -+ */ -+enum { -+ MPTCP_ATTR_UNSPEC = 0, -+ -+ MPTCP_ATTR_TOKEN, /* u32 */ -+ MPTCP_ATTR_FAMILY, /* u16 */ -+ MPTCP_ATTR_LOC_ID, /* u8 */ -+ MPTCP_ATTR_REM_ID, /* u8 */ -+ MPTCP_ATTR_SADDR4, /* u32 */ -+ MPTCP_ATTR_SADDR6, /* struct in6_addr */ -+ MPTCP_ATTR_DADDR4, /* u32 */ -+ MPTCP_ATTR_DADDR6, /* struct in6_addr */ -+ MPTCP_ATTR_SPORT, /* u16 */ -+ MPTCP_ATTR_DPORT, /* u16 */ -+ MPTCP_ATTR_BACKUP, /* u8 */ -+ MPTCP_ATTR_ERROR, /* u8 */ -+ MPTCP_ATTR_FLAGS, /* u16 */ -+ MPTCP_ATTR_TIMEOUT, /* u32 */ -+ MPTCP_ATTR_IF_IDX, /* s32 */ -+ -+ __MPTCP_ATTR_AFTER_LAST -+}; -+ -+#define MPTCP_ATTR_MAX (__MPTCP_ATTR_AFTER_LAST - 1) -+ -+/* -+ * Events generated by MPTCP: -+ * - MPTCP_EVENT_CREATED: token, family, saddr4 | saddr6, daddr4 | daddr6, -+ * sport, dport -+ * A new connection has been created. It is the good time to allocate -+ * memory and send ADD_ADDR if needed. Depending on the traffic-patterns -+ * it can take a long time until the MPTCP_EVENT_ESTABLISHED is sent. -+ * -+ * - MPTCP_EVENT_ESTABLISHED: token, family, saddr4 | saddr6, daddr4 | daddr6, -+ * sport, dport -+ * A connection is established (can start new subflows). -+ * -+ * - MPTCP_EVENT_CLOSED: token -+ * A connection has stopped. -+ * -+ * - MPTCP_EVENT_ANNOUNCED: token, rem_id, family, daddr4 | daddr6 [, dport] -+ * A new address has been announced by the peer. -+ * -+ * - MPTCP_EVENT_REMOVED: token, rem_id -+ * An address has been lost by the peer. -+ * -+ * - MPTCP_EVENT_SUB_ESTABLISHED: token, family, saddr4 | saddr6, -+ * daddr4 | daddr6, sport, dport, backup, -+ * if_idx [, error] -+ * A new subflow has been established. 'error' should not be set. -+ * -+ * - MPTCP_EVENT_SUB_CLOSED: token, family, saddr4 | saddr6, daddr4 | daddr6, -+ * sport, dport, backup, if_idx [, error] -+ * A subflow has been closed. An error (copy of sk_err) could be set if an -+ * error has been detected for this subflow. -+ * -+ * - MPTCP_EVENT_SUB_PRIORITY: token, family, saddr4 | saddr6, daddr4 | daddr6, -+ * sport, dport, backup, if_idx [, error] -+ * The priority of a subflow has changed. 'error' should not be set. -+ * -+ * Commands for MPTCP: -+ * - MPTCP_CMD_ANNOUNCE: token, loc_id, family, saddr4 | saddr6 [, sport] -+ * Announce a new address to the peer. -+ * -+ * - MPTCP_CMD_REMOVE: token, loc_id -+ * Announce that an address has been lost to the peer. -+ * -+ * - MPTCP_CMD_SUB_CREATE: token, family, loc_id, rem_id, [saddr4 | saddr6, -+ * daddr4 | daddr6, dport [, sport, backup, if_idx]] -+ * Create a new subflow. -+ * -+ * - MPTCP_CMD_SUB_DESTROY: token, family, saddr4 | saddr6, daddr4 | daddr6, -+ * sport, dport -+ * Close a subflow. -+ * -+ * - MPTCP_CMD_SUB_PRIORITY: token, family, saddr4 | saddr6, daddr4 | daddr6, -+ * sport, dport, backup -+ * Change the priority of a subflow. -+ * -+ * - MPTCP_CMD_SET_FILTER: flags -+ * Set the filter on events. Set MPTCPF_* flags to only receive specific -+ * events. Default is to receive all events. -+ * -+ * - MPTCP_CMD_EXIST: token -+ * Check if this token is linked to an existing socket. -+ */ -+enum { -+ MPTCP_CMD_UNSPEC = 0, -+ -+ MPTCP_EVENT_CREATED, -+ MPTCP_EVENT_ESTABLISHED, -+ MPTCP_EVENT_CLOSED, -+ -+ MPTCP_CMD_ANNOUNCE, -+ MPTCP_CMD_REMOVE, -+ MPTCP_EVENT_ANNOUNCED, -+ MPTCP_EVENT_REMOVED, -+ -+ MPTCP_CMD_SUB_CREATE, -+ MPTCP_CMD_SUB_DESTROY, -+ MPTCP_EVENT_SUB_ESTABLISHED, -+ MPTCP_EVENT_SUB_CLOSED, -+ -+ MPTCP_CMD_SUB_PRIORITY, -+ MPTCP_EVENT_SUB_PRIORITY, -+ -+ MPTCP_CMD_SET_FILTER, -+ -+ MPTCP_CMD_EXIST, -+ -+ __MPTCP_CMD_AFTER_LAST -+}; -+ -+#define MPTCP_CMD_MAX (__MPTCP_CMD_AFTER_LAST - 1) -+ -+enum { -+ MPTCPF_EVENT_CREATED = (1 << 1), -+ MPTCPF_EVENT_ESTABLISHED = (1 << 2), -+ MPTCPF_EVENT_CLOSED = (1 << 3), -+ MPTCPF_EVENT_ANNOUNCED = (1 << 4), -+ MPTCPF_EVENT_REMOVED = (1 << 5), -+ MPTCPF_EVENT_SUB_ESTABLISHED = (1 << 6), -+ MPTCPF_EVENT_SUB_CLOSED = (1 << 7), -+ MPTCPF_EVENT_SUB_PRIORITY = (1 << 8), -+}; -+ -+#endif /* _LINUX_MPTCP_H */ -diff -aurN linux-4.19.104/include/uapi/linux/tcp.h mptcp-mptcp_v0.95/include/uapi/linux/tcp.h ---- linux-4.19.104/include/uapi/linux/tcp.h 2020-02-14 22:33:28.000000000 +0100 -+++ mptcp-mptcp_v0.95/include/uapi/linux/tcp.h 2020-02-17 11:29:55.000000000 +0100 -@@ -18,9 +18,15 @@ - #ifndef _UAPI_LINUX_TCP_H - #define _UAPI_LINUX_TCP_H - --#include -+#ifndef __KERNEL__ -+#include -+#endif -+ - #include -+#include -+#include - #include -+#include - - struct tcphdr { - __be16 source; -@@ -131,6 +137,13 @@ - #define TCP_REPAIR_OFF 0 - #define TCP_REPAIR_OFF_NO_WP -1 /* Turn off without window probes */ - -+#define MPTCP_ENABLED 42 -+#define MPTCP_SCHEDULER 43 -+#define MPTCP_PATH_MANAGER 44 -+#define MPTCP_INFO 45 -+ -+#define MPTCP_INFO_FLAG_SAVE_MASTER 0x01 -+ - struct tcp_repair_opt { - __u32 opt_code; - __u32 opt_val; -@@ -268,6 +281,53 @@ - TCP_NLA_REORD_SEEN, /* reordering events seen */ - }; - -+struct mptcp_meta_info { -+ __u8 mptcpi_state; -+ __u8 mptcpi_retransmits; -+ __u8 mptcpi_probes; -+ __u8 mptcpi_backoff; -+ -+ __u32 mptcpi_rto; -+ __u32 mptcpi_unacked; -+ -+ /* Times. */ -+ __u32 mptcpi_last_data_sent; -+ __u32 mptcpi_last_data_recv; -+ __u32 mptcpi_last_ack_recv; -+ -+ __u32 mptcpi_total_retrans; -+ -+ __u64 mptcpi_bytes_acked; /* RFC4898 tcpEStatsAppHCThruOctetsAcked */ -+ __u64 mptcpi_bytes_received; /* RFC4898 tcpEStatsAppHCThruOctetsReceived */ -+}; -+ -+struct mptcp_sub_info { -+ union { -+ struct sockaddr src; -+ struct sockaddr_in src_v4; -+ struct sockaddr_in6 src_v6; -+ }; -+ -+ union { -+ struct sockaddr dst; -+ struct sockaddr_in dst_v4; -+ struct sockaddr_in6 dst_v6; -+ }; -+}; -+ -+struct mptcp_info { -+ __u32 tcp_info_len; /* Length of each struct tcp_info in subflows pointer */ -+ __u32 sub_len; /* Total length of memory pointed to by subflows pointer */ -+ __u32 meta_len; /* Length of memory pointed to by meta_info */ -+ __u32 sub_info_len; /* Length of each struct mptcp_sub_info in subflow_info pointer */ -+ __u32 total_sub_info_len; /* Total length of memory pointed to by subflow_info */ -+ -+ struct mptcp_meta_info *meta_info; -+ struct tcp_info *initial; -+ struct tcp_info *subflows; /* Pointer to array of tcp_info structs */ -+ struct mptcp_sub_info *subflow_info; -+}; -+ - /* for TCP_MD5SIG socket option */ - #define TCP_MD5SIG_MAXKEYLEN 80 - -diff -aurN linux-4.19.104/net/core/dev.c mptcp-mptcp_v0.95/net/core/dev.c ---- linux-4.19.104/net/core/dev.c 2020-02-14 22:33:28.000000000 +0100 -+++ mptcp-mptcp_v0.95/net/core/dev.c 2020-02-17 11:29:55.000000000 +0100 -@@ -7636,7 +7636,7 @@ - - dev->flags = (flags & (IFF_DEBUG | IFF_NOTRAILERS | IFF_NOARP | - IFF_DYNAMIC | IFF_MULTICAST | IFF_PORTSEL | -- IFF_AUTOMEDIA)) | -+ IFF_AUTOMEDIA | IFF_NOMULTIPATH | IFF_MPBACKUP)) | - (dev->flags & (IFF_UP | IFF_VOLATILE | IFF_PROMISC | - IFF_ALLMULTI)); - -diff -aurN linux-4.19.104/net/core/net-traces.c mptcp-mptcp_v0.95/net/core/net-traces.c ---- linux-4.19.104/net/core/net-traces.c 2020-02-14 22:33:28.000000000 +0100 -+++ mptcp-mptcp_v0.95/net/core/net-traces.c 2020-02-17 11:29:55.000000000 +0100 -@@ -48,3 +48,5 @@ - EXPORT_TRACEPOINT_SYMBOL_GPL(napi_poll); - - EXPORT_TRACEPOINT_SYMBOL_GPL(tcp_send_reset); -+ -+EXPORT_TRACEPOINT_SYMBOL_GPL(mptcp_retransmit); -diff -aurN linux-4.19.104/net/core/skbuff.c mptcp-mptcp_v0.95/net/core/skbuff.c ---- linux-4.19.104/net/core/skbuff.c 2020-02-14 22:33:28.000000000 +0100 -+++ mptcp-mptcp_v0.95/net/core/skbuff.c 2020-02-17 11:29:55.000000000 +0100 -@@ -536,7 +536,7 @@ - skb_drop_list(&skb_shinfo(skb)->frag_list); - } - --static void skb_clone_fraglist(struct sk_buff *skb) -+void skb_clone_fraglist(struct sk_buff *skb) - { - struct sk_buff *list; - -diff -aurN linux-4.19.104/net/core/sock.c mptcp-mptcp_v0.95/net/core/sock.c ---- linux-4.19.104/net/core/sock.c 2020-02-14 22:33:28.000000000 +0100 -+++ mptcp-mptcp_v0.95/net/core/sock.c 2020-02-17 11:29:55.000000000 +0100 -@@ -140,6 +140,11 @@ - - #include - -+#ifdef CONFIG_MPTCP -+#include -+#include -+#endif -+ - #include - #include - -@@ -1412,6 +1417,23 @@ - */ - static inline void sock_lock_init(struct sock *sk) - { -+#ifdef CONFIG_MPTCP -+ /* Reclassify the lock-class for subflows */ -+ if (sk->sk_type == SOCK_STREAM && sk->sk_protocol == IPPROTO_TCP) -+ if (mptcp(tcp_sk(sk)) || tcp_sk(sk)->is_master_sk) { -+ sock_lock_init_class_and_name(sk, meta_slock_key_name, -+ &meta_slock_key, -+ meta_key_name, -+ &meta_key); -+ -+ /* We don't yet have the mptcp-point. -+ * Thus we still need inet_sock_destruct -+ */ -+ sk->sk_destruct = inet_sock_destruct; -+ return; -+ } -+#endif -+ - if (sk->sk_kern_sock) - sock_lock_init_class_and_name( - sk, -@@ -1460,8 +1482,12 @@ - sk = kmem_cache_alloc(slab, priority & ~__GFP_ZERO); - if (!sk) - return sk; -- if (priority & __GFP_ZERO) -- sk_prot_clear_nulls(sk, prot->obj_size); -+ if (priority & __GFP_ZERO) { -+ if (prot->clear_sk) -+ prot->clear_sk(sk, prot->obj_size); -+ else -+ sk_prot_clear_nulls(sk, prot->obj_size); -+ } - } else - sk = kmalloc(prot->obj_size, priority); - -@@ -1689,6 +1715,7 @@ - atomic_set(&newsk->sk_zckey, 0); - - sock_reset_flag(newsk, SOCK_DONE); -+ sock_reset_flag(newsk, SOCK_MPTCP); - mem_cgroup_sk_alloc(newsk); - cgroup_sk_alloc(&newsk->sk_cgrp_data); - -diff -aurN linux-4.19.104/net/ipv4/af_inet.c mptcp-mptcp_v0.95/net/ipv4/af_inet.c ---- linux-4.19.104/net/ipv4/af_inet.c 2020-02-14 22:33:28.000000000 +0100 -+++ mptcp-mptcp_v0.95/net/ipv4/af_inet.c 2020-02-17 11:29:55.000000000 +0100 -@@ -104,6 +104,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -150,6 +151,9 @@ - return; - } - -+ if (sock_flag(sk, SOCK_MPTCP)) -+ mptcp_disable_static_key(); -+ - WARN_ON(atomic_read(&sk->sk_rmem_alloc)); - WARN_ON(refcount_read(&sk->sk_wmem_alloc)); - WARN_ON(sk->sk_wmem_queued); -@@ -244,8 +248,7 @@ - * Create an inet socket. - */ - --static int inet_create(struct net *net, struct socket *sock, int protocol, -- int kern) -+int inet_create(struct net *net, struct socket *sock, int protocol, int kern) - { - struct sock *sk; - struct inet_protosw *answer; -@@ -739,6 +742,24 @@ - lock_sock(sk2); - - sock_rps_record_flow(sk2); -+ -+ if (sk2->sk_protocol == IPPROTO_TCP && mptcp(tcp_sk(sk2))) { -+ struct mptcp_tcp_sock *mptcp; -+ -+ mptcp_for_each_sub(tcp_sk(sk2)->mpcb, mptcp) { -+ sock_rps_record_flow(mptcp_to_sock(mptcp)); -+ } -+ -+ if (tcp_sk(sk2)->mpcb->master_sk) { -+ struct sock *sk_it = tcp_sk(sk2)->mpcb->master_sk; -+ -+ write_lock_bh(&sk_it->sk_callback_lock); -+ sk_it->sk_wq = newsock->wq; -+ sk_it->sk_socket = newsock; -+ write_unlock_bh(&sk_it->sk_callback_lock); -+ } -+ } -+ - WARN_ON(!((1 << sk2->sk_state) & - (TCPF_ESTABLISHED | TCPF_SYN_RECV | - TCPF_CLOSE_WAIT | TCPF_CLOSE))); -@@ -1955,6 +1976,9 @@ - - ip_init(); - -+ /* We must initialize MPTCP before TCP. */ -+ mptcp_init(); -+ - /* Setup TCP slab cache for open requests. */ - tcp_init(); - -diff -aurN linux-4.19.104/net/ipv4/inet_connection_sock.c mptcp-mptcp_v0.95/net/ipv4/inet_connection_sock.c ---- linux-4.19.104/net/ipv4/inet_connection_sock.c 2020-02-14 22:33:28.000000000 +0100 -+++ mptcp-mptcp_v0.95/net/ipv4/inet_connection_sock.c 2020-02-17 11:29:55.000000000 +0100 -@@ -23,6 +23,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -691,7 +692,10 @@ - int max_retries, thresh; - u8 defer_accept; - -- if (inet_sk_state_load(sk_listener) != TCP_LISTEN) -+ if (!is_meta_sk(sk_listener) && inet_sk_state_load(sk_listener) != TCP_LISTEN) -+ goto drop; -+ -+ if (is_meta_sk(sk_listener) && !mptcp_can_new_subflow(sk_listener)) - goto drop; - - max_retries = icsk->icsk_syn_retries ? : net->ipv4.sysctl_tcp_synack_retries; -@@ -784,7 +788,9 @@ - const struct request_sock *req, - const gfp_t priority) - { -- struct sock *newsk = sk_clone_lock(sk, priority); -+ struct sock *newsk; -+ -+ newsk = sk_clone_lock(sk, priority); - - if (newsk) { - struct inet_connection_sock *newicsk = inet_csk(newsk); -@@ -984,7 +990,14 @@ - */ - while ((req = reqsk_queue_remove(queue, sk)) != NULL) { - struct sock *child = req->sk; -+ bool mutex_taken = false; -+ struct mptcp_cb *mpcb = tcp_sk(child)->mpcb; - -+ if (is_meta_sk(child)) { -+ WARN_ON(refcount_inc_not_zero(&mpcb->mpcb_refcnt) == 0); -+ mutex_lock(&mpcb->mpcb_mutex); -+ mutex_taken = true; -+ } - local_bh_disable(); - bh_lock_sock(child); - WARN_ON(sock_owned_by_user(child)); -@@ -994,6 +1007,10 @@ - reqsk_put(req); - bh_unlock_sock(child); - local_bh_enable(); -+ if (mutex_taken) { -+ mutex_unlock(&mpcb->mpcb_mutex); -+ mptcp_mpcb_put(mpcb); -+ } - sock_put(child); - - cond_resched(); -diff -aurN linux-4.19.104/net/ipv4/ip_sockglue.c mptcp-mptcp_v0.95/net/ipv4/ip_sockglue.c ---- linux-4.19.104/net/ipv4/ip_sockglue.c 2020-02-14 22:33:28.000000000 +0100 -+++ mptcp-mptcp_v0.95/net/ipv4/ip_sockglue.c 2020-02-17 11:29:55.000000000 +0100 -@@ -44,6 +44,8 @@ - #endif - #include - -+#include -+ - #include - #include - -@@ -655,7 +657,7 @@ - break; - old = rcu_dereference_protected(inet->inet_opt, - lockdep_sock_is_held(sk)); -- if (inet->is_icsk) { -+ if (inet->is_icsk && !is_meta_sk(sk)) { - struct inet_connection_sock *icsk = inet_csk(sk); - #if IS_ENABLED(CONFIG_IPV6) - if (sk->sk_family == PF_INET || -@@ -749,6 +751,20 @@ - inet->tos = val; - sk->sk_priority = rt_tos2priority(val); - sk_dst_reset(sk); -+ /* Update TOS on mptcp subflow */ -+ if (is_meta_sk(sk)) { -+ struct mptcp_tcp_sock *mptcp; -+ -+ mptcp_for_each_sub(tcp_sk(sk)->mpcb, mptcp) { -+ struct sock *sk_it = mptcp_to_sock(mptcp); -+ -+ if (inet_sk(sk_it)->tos != inet_sk(sk)->tos) { -+ inet_sk(sk_it)->tos = inet_sk(sk)->tos; -+ sk_it->sk_priority = sk->sk_priority; -+ sk_dst_reset(sk_it); -+ } -+ } -+ } - } - break; - case IP_TTL: -diff -aurN linux-4.19.104/net/ipv4/Kconfig mptcp-mptcp_v0.95/net/ipv4/Kconfig ---- linux-4.19.104/net/ipv4/Kconfig 2020-02-14 22:33:28.000000000 +0100 -+++ mptcp-mptcp_v0.95/net/ipv4/Kconfig 2020-02-17 11:29:55.000000000 +0100 -@@ -680,6 +680,51 @@ - bufferbloat, policers, or AQM schemes that do not provide a delay - signal. It requires the fq ("Fair Queue") pacing packet scheduler. - -+config TCP_CONG_LIA -+ tristate "MPTCP Linked Increase" -+ depends on MPTCP -+ default n -+ ---help--- -+ MultiPath TCP Linked Increase Congestion Control -+ To enable it, just put 'lia' in tcp_congestion_control -+ -+config TCP_CONG_OLIA -+ tristate "MPTCP Opportunistic Linked Increase" -+ depends on MPTCP -+ default n -+ ---help--- -+ MultiPath TCP Opportunistic Linked Increase Congestion Control -+ To enable it, just put 'olia' in tcp_congestion_control -+ -+config TCP_CONG_WVEGAS -+ tristate "MPTCP WVEGAS CONGESTION CONTROL" -+ depends on MPTCP -+ default n -+ ---help--- -+ wVegas congestion control for MPTCP -+ To enable it, just put 'wvegas' in tcp_congestion_control -+ -+config TCP_CONG_BALIA -+ tristate "MPTCP BALIA CONGESTION CONTROL" -+ depends on MPTCP -+ default n -+ ---help--- -+ Multipath TCP Balanced Linked Adaptation Congestion Control -+ To enable it, just put 'balia' in tcp_congestion_control -+ -+config TCP_CONG_MCTCPDESYNC -+ tristate "DESYNCHRONIZED MCTCP CONGESTION CONTROL (EXPERIMENTAL)" -+ depends on MPTCP -+ default n -+ ---help--- -+ Desynchronized MultiChannel TCP Congestion Control. This is experimental -+ code that only supports single path and must have set mptcp_ndiffports -+ larger than one. -+ To enable it, just put 'mctcpdesync' in tcp_congestion_control -+ For further details see: -+ http://ieeexplore.ieee.org/abstract/document/6911722/ -+ https://doi.org/10.1016/j.comcom.2015.07.010 -+ - choice - prompt "Default TCP congestion control" - default DEFAULT_CUBIC -@@ -717,6 +762,21 @@ - config DEFAULT_BBR - bool "BBR" if TCP_CONG_BBR=y - -+ config DEFAULT_LIA -+ bool "Lia" if TCP_CONG_LIA=y -+ -+ config DEFAULT_OLIA -+ bool "Olia" if TCP_CONG_OLIA=y -+ -+ config DEFAULT_WVEGAS -+ bool "Wvegas" if TCP_CONG_WVEGAS=y -+ -+ config DEFAULT_BALIA -+ bool "Balia" if TCP_CONG_BALIA=y -+ -+ config DEFAULT_MCTCPDESYNC -+ bool "Mctcpdesync (EXPERIMENTAL)" if TCP_CONG_MCTCPDESYNC=y -+ - config DEFAULT_RENO - bool "Reno" - endchoice -@@ -737,6 +797,10 @@ - default "vegas" if DEFAULT_VEGAS - default "westwood" if DEFAULT_WESTWOOD - default "veno" if DEFAULT_VENO -+ default "lia" if DEFAULT_LIA -+ default "olia" if DEFAULT_OLIA -+ default "wvegas" if DEFAULT_WVEGAS -+ default "balia" if DEFAULT_BALIA - default "reno" if DEFAULT_RENO - default "dctcp" if DEFAULT_DCTCP - default "cdg" if DEFAULT_CDG -diff -aurN linux-4.19.104/net/ipv4/syncookies.c mptcp-mptcp_v0.95/net/ipv4/syncookies.c ---- linux-4.19.104/net/ipv4/syncookies.c 2020-02-14 22:33:28.000000000 +0100 -+++ mptcp-mptcp_v0.95/net/ipv4/syncookies.c 2020-02-17 11:29:55.000000000 +0100 -@@ -16,6 +16,8 @@ - #include - #include - #include -+#include -+#include - #include - #include - #include -@@ -179,7 +181,8 @@ - } - EXPORT_SYMBOL_GPL(__cookie_v4_init_sequence); - --__u32 cookie_v4_init_sequence(const struct sk_buff *skb, __u16 *mssp) -+__u32 cookie_v4_init_sequence(struct request_sock *req, const struct sock *sk, -+ const struct sk_buff *skb, __u16 *mssp) - { - const struct iphdr *iph = ip_hdr(skb); - const struct tcphdr *th = tcp_hdr(skb); -@@ -209,9 +212,27 @@ - struct inet_connection_sock *icsk = inet_csk(sk); - struct sock *child; - bool own_req; -+#ifdef CONFIG_MPTCP -+ int ret; -+#endif - - child = icsk->icsk_af_ops->syn_recv_sock(sk, skb, req, dst, - NULL, &own_req); -+ -+#ifdef CONFIG_MPTCP -+ if (!child) -+ goto listen_overflow; -+ -+ ret = mptcp_check_req_master(sk, child, req, skb, 0, tsoff); -+ if (ret < 0) -+ return NULL; -+ -+ if (!ret) -+ return tcp_sk(child)->mpcb->master_sk; -+ -+listen_overflow: -+#endif -+ - if (child) { - refcount_set(&req->rsk_refcnt, 1); - tcp_sk(child)->tsoffset = tsoff; -@@ -289,6 +310,7 @@ - { - struct ip_options *opt = &TCP_SKB_CB(skb)->header.h4.opt; - struct tcp_options_received tcp_opt; -+ struct mptcp_options_received mopt; - struct inet_request_sock *ireq; - struct tcp_request_sock *treq; - struct tcp_sock *tp = tcp_sk(sk); -@@ -318,7 +340,8 @@ - - /* check for timestamp cookie support */ - memset(&tcp_opt, 0, sizeof(tcp_opt)); -- tcp_parse_options(sock_net(sk), skb, &tcp_opt, 0, NULL); -+ mptcp_init_mp_opt(&mopt); -+ tcp_parse_options(sock_net(sk), skb, &tcp_opt, &mopt, 0, NULL, NULL); - - if (tcp_opt.saw_tstamp && tcp_opt.rcv_tsecr) { - tsoff = secure_tcp_ts_off(sock_net(sk), -@@ -331,7 +354,12 @@ - goto out; - - ret = NULL; -- req = inet_reqsk_alloc(&tcp_request_sock_ops, sk, false); /* for safety */ -+#ifdef CONFIG_MPTCP -+ if (mopt.saw_mpc) -+ req = inet_reqsk_alloc(&mptcp_request_sock_ops, sk, false); /* for safety */ -+ else -+#endif -+ req = inet_reqsk_alloc(&tcp_request_sock_ops, sk, false); /* for safety */ - if (!req) - goto out; - -@@ -351,6 +379,8 @@ - ireq->sack_ok = tcp_opt.sack_ok; - ireq->wscale_ok = tcp_opt.wscale_ok; - ireq->tstamp_ok = tcp_opt.saw_tstamp; -+ ireq->mptcp_rqsk = 0; -+ ireq->saw_mpc = 0; - req->ts_recent = tcp_opt.saw_tstamp ? tcp_opt.rcv_tsval : 0; - treq->snt_synack = 0; - treq->tfo_listener = false; -@@ -359,6 +389,9 @@ - - ireq->ir_iif = inet_request_bound_dev_if(sk, skb); - -+ if (mopt.saw_mpc) -+ mptcp_cookies_reqsk_init(req, &mopt, skb); -+ - /* We throwed the options of the initial SYN away, so we hope - * the ACK carries the same options again (see RFC1122 4.2.3.8) - */ -@@ -392,10 +425,10 @@ - /* Try to redo what tcp_v4_send_synack did. */ - req->rsk_window_clamp = tp->window_clamp ? :dst_metric(&rt->dst, RTAX_WINDOW); - -- tcp_select_initial_window(sk, tcp_full_space(sk), req->mss, -- &req->rsk_rcv_wnd, &req->rsk_window_clamp, -- ireq->wscale_ok, &rcv_wscale, -- dst_metric(&rt->dst, RTAX_INITRWND)); -+ tp->ops->select_initial_window(sk, tcp_full_space(sk), req->mss, -+ &req->rsk_rcv_wnd, &req->rsk_window_clamp, -+ ireq->wscale_ok, &rcv_wscale, -+ dst_metric(&rt->dst, RTAX_INITRWND)); - - ireq->rcv_wscale = rcv_wscale; - ireq->ecn_ok = cookie_ecn_ok(&tcp_opt, sock_net(sk), &rt->dst); -diff -aurN linux-4.19.104/net/ipv4/tcp.c mptcp-mptcp_v0.95/net/ipv4/tcp.c ---- linux-4.19.104/net/ipv4/tcp.c 2020-02-14 22:33:28.000000000 +0100 -+++ mptcp-mptcp_v0.95/net/ipv4/tcp.c 2020-02-17 11:29:55.000000000 +0100 -@@ -274,6 +274,7 @@ - - #include - #include -+#include - #include - #include - #include -@@ -399,6 +400,27 @@ - return rate64; - } - -+static int select_size(const struct sock *sk, bool first_skb, bool zc); -+ -+const struct tcp_sock_ops tcp_specific = { -+ .__select_window = __tcp_select_window, -+ .select_window = tcp_select_window, -+ .select_initial_window = tcp_select_initial_window, -+ .select_size = select_size, -+ .init_buffer_space = tcp_init_buffer_space, -+ .set_rto = tcp_set_rto, -+ .should_expand_sndbuf = tcp_should_expand_sndbuf, -+ .send_fin = tcp_send_fin, -+ .write_xmit = tcp_write_xmit, -+ .send_active_reset = tcp_send_active_reset, -+ .write_wakeup = tcp_write_wakeup, -+ .retransmit_timer = tcp_retransmit_timer, -+ .time_wait = tcp_time_wait, -+ .cleanup_rbuf = tcp_cleanup_rbuf, -+ .cwnd_validate = tcp_cwnd_validate, -+ .set_cong_ctrl = __tcp_set_congestion_control, -+}; -+ - /* Address-family independent initialization for a tcp_sock. - * - * NOTE: A lot of things set to zero explicitly by call to -@@ -452,6 +474,11 @@ - sk->sk_sndbuf = sock_net(sk)->ipv4.sysctl_tcp_wmem[1]; - sk->sk_rcvbuf = sock_net(sk)->ipv4.sysctl_tcp_rmem[1]; - -+ tp->ops = &tcp_specific; -+ -+ /* Initialize MPTCP-specific stuff and function-pointers */ -+ mptcp_init_tcp_sock(sk); -+ - sk_sockets_allocated_inc(sk); - sk->sk_route_forced_caps = NETIF_F_GSO; - } -@@ -466,7 +493,7 @@ - tcp_init_metrics(sk); - tcp_call_bpf(sk, bpf_op, 0, NULL); - tcp_init_congestion_control(sk); -- tcp_init_buffer_space(sk); -+ tcp_sk(sk)->ops->init_buffer_space(sk); - } - - static void tcp_tx_timestamp(struct sock *sk, u16 tsflags) -@@ -786,6 +813,7 @@ - int ret; - - sock_rps_record_flow(sk); -+ - /* - * We can't seek on a socket input - */ -@@ -796,6 +824,16 @@ - - lock_sock(sk); - -+#ifdef CONFIG_MPTCP -+ if (mptcp(tcp_sk(sk))) { -+ struct mptcp_tcp_sock *mptcp; -+ -+ mptcp_for_each_sub(tcp_sk(sk)->mpcb, mptcp) { -+ sock_rps_record_flow(mptcp_to_sock(mptcp)); -+ } -+ } -+#endif -+ - timeo = sock_rcvtimeo(sk, sock->file->f_flags & O_NONBLOCK); - while (tss.len) { - ret = __tcp_splice_read(sk, &tss); -@@ -899,8 +937,7 @@ - return NULL; - } - --static unsigned int tcp_xmit_size_goal(struct sock *sk, u32 mss_now, -- int large_allowed) -+unsigned int tcp_xmit_size_goal(struct sock *sk, u32 mss_now, int large_allowed) - { - struct tcp_sock *tp = tcp_sk(sk); - u32 new_size_goal, size_goal; -@@ -928,8 +965,13 @@ - { - int mss_now; - -- mss_now = tcp_current_mss(sk); -- *size_goal = tcp_xmit_size_goal(sk, mss_now, !(flags & MSG_OOB)); -+ if (mptcp(tcp_sk(sk))) { -+ mss_now = mptcp_current_mss(sk); -+ *size_goal = mptcp_xmit_size_goal(sk, mss_now, !(flags & MSG_OOB)); -+ } else { -+ mss_now = tcp_current_mss(sk); -+ *size_goal = tcp_xmit_size_goal(sk, mss_now, !(flags & MSG_OOB)); -+ } - - return mss_now; - } -@@ -964,12 +1006,34 @@ - * is fully established. - */ - if (((1 << sk->sk_state) & ~(TCPF_ESTABLISHED | TCPF_CLOSE_WAIT)) && -- !tcp_passive_fastopen(sk)) { -+ !tcp_passive_fastopen(mptcp(tp) && tp->mpcb->master_sk ? -+ tp->mpcb->master_sk : sk)) { - err = sk_stream_wait_connect(sk, &timeo); - if (err != 0) - goto out_err; - } - -+ if (mptcp(tp)) { -+ struct mptcp_tcp_sock *mptcp; -+ -+ /* We must check this with socket-lock hold because we iterate -+ * over the subflows. -+ */ -+ if (!mptcp_can_sendpage(sk)) { -+ ssize_t ret; -+ -+ release_sock(sk); -+ ret = sock_no_sendpage(sk->sk_socket, page, offset, -+ size, flags); -+ lock_sock(sk); -+ return ret; -+ } -+ -+ mptcp_for_each_sub(tp->mpcb, mptcp) { -+ sock_rps_record_flow(mptcp_to_sock(mptcp)); -+ } -+ } -+ - sk_clear_bit(SOCKWQ_ASYNC_NOSPACE, sk); - - mss_now = tcp_send_mss(sk, &size_goal, flags); -@@ -1088,7 +1152,8 @@ - int tcp_sendpage_locked(struct sock *sk, struct page *page, int offset, - size_t size, int flags) - { -- if (!(sk->sk_route_caps & NETIF_F_SG)) -+ /* If MPTCP is enabled, we check it later after establishment */ -+ if (!mptcp(tcp_sk(sk)) && !(sk->sk_route_caps & NETIF_F_SG)) - return sock_no_sendpage_locked(sk, page, offset, size, flags); - - tcp_rate_check_app_limited(sk); /* is sending application-limited? */ -@@ -1120,14 +1185,14 @@ - * This also speeds up tso_fragment(), since it wont fallback - * to tcp_fragment(). - */ --static int linear_payload_sz(bool first_skb) -+int linear_payload_sz(bool first_skb) - { - if (first_skb) - return SKB_WITH_OVERHEAD(2048 - MAX_TCP_HEADER); - return 0; - } - --static int select_size(bool first_skb, bool zc) -+static int select_size(const struct sock *sk, bool first_skb, bool zc) - { - if (zc) - return 0; -@@ -1237,12 +1302,21 @@ - * is fully established. - */ - if (((1 << sk->sk_state) & ~(TCPF_ESTABLISHED | TCPF_CLOSE_WAIT)) && -- !tcp_passive_fastopen(sk)) { -+ !tcp_passive_fastopen(mptcp(tp) && tp->mpcb->master_sk ? -+ tp->mpcb->master_sk : sk)) { - err = sk_stream_wait_connect(sk, &timeo); - if (err != 0) - goto do_error; - } - -+ if (mptcp(tp)) { -+ struct mptcp_tcp_sock *mptcp; -+ -+ mptcp_for_each_sub(tp->mpcb, mptcp) { -+ sock_rps_record_flow(mptcp_to_sock(mptcp)); -+ } -+ } -+ - if (unlikely(tp->repair)) { - if (tp->repair_queue == TCP_RECV_QUEUE) { - copied = tcp_send_rcvq(sk, msg, size); -@@ -1298,7 +1372,7 @@ - goto restart; - } - first_skb = tcp_rtx_and_write_queues_empty(sk); -- linear = select_size(first_skb, zc); -+ linear = tp->ops->select_size(sk, first_skb, zc); - skb = sk_stream_alloc_skb(sk, linear, sk->sk_allocation, - first_skb); - if (!skb) -@@ -1536,7 +1610,7 @@ - * calculation of whether or not we must ACK for the sake of - * a window update. - */ --static void tcp_cleanup_rbuf(struct sock *sk, int copied) -+void tcp_cleanup_rbuf(struct sock *sk, int copied) - { - struct tcp_sock *tp = tcp_sk(sk); - bool time_to_ack = false; -@@ -1579,7 +1653,7 @@ - - /* Optimize, __tcp_select_window() is not cheap. */ - if (2*rcv_window_now <= tp->window_clamp) { -- __u32 new_window = __tcp_select_window(sk); -+ __u32 new_window = tp->ops->__select_window(sk); - - /* Send ACK now, if this read freed lots of space - * in our buffer. Certainly, new_window is new window. -@@ -1695,7 +1769,7 @@ - /* Clean up data we have read: This will do ACK frames. */ - if (copied > 0) { - tcp_recv_skb(sk, seq, &offset); -- tcp_cleanup_rbuf(sk, copied); -+ tp->ops->cleanup_rbuf(sk, copied); - } - return copied; - } -@@ -1952,6 +2026,16 @@ - - lock_sock(sk); - -+#ifdef CONFIG_MPTCP -+ if (mptcp(tp)) { -+ struct mptcp_tcp_sock *mptcp; -+ -+ mptcp_for_each_sub(tp->mpcb, mptcp) { -+ sock_rps_record_flow(mptcp_to_sock(mptcp)); -+ } -+ } -+#endif -+ - err = -ENOTCONN; - if (sk->sk_state == TCP_LISTEN) - goto out; -@@ -2070,7 +2154,7 @@ - } - } - -- tcp_cleanup_rbuf(sk, copied); -+ tp->ops->cleanup_rbuf(sk, copied); - - if (copied >= target) { - /* Do not sleep, just process backlog. */ -@@ -2161,7 +2245,7 @@ - */ - - /* Clean up data we have read: This will do ACK frames. */ -- tcp_cleanup_rbuf(sk, copied); -+ tp->ops->cleanup_rbuf(sk, copied); - - release_sock(sk); - -@@ -2273,7 +2357,7 @@ - [TCP_NEW_SYN_RECV] = TCP_CLOSE, /* should not happen ! */ - }; - --static int tcp_close_state(struct sock *sk) -+int tcp_close_state(struct sock *sk) - { - int next = (int)new_state[sk->sk_state]; - int ns = next & TCP_STATE_MASK; -@@ -2303,7 +2387,7 @@ - TCPF_SYN_RECV | TCPF_CLOSE_WAIT)) { - /* Clear out any half completed packets. FIN if needed. */ - if (tcp_close_state(sk)) -- tcp_send_fin(sk); -+ tcp_sk(sk)->ops->send_fin(sk); - } - } - EXPORT_SYMBOL(tcp_shutdown); -@@ -2328,6 +2412,17 @@ - int data_was_unread = 0; - int state; - -+ if (is_meta_sk(sk)) { -+ /* TODO: Currently forcing timeout to 0 because -+ * sk_stream_wait_close will complain during lockdep because -+ * of the mpcb_mutex (circular lock dependency through -+ * inet_csk_listen_stop()). -+ * We should find a way to get rid of the mpcb_mutex. -+ */ -+ mptcp_close(sk, 0); -+ return; -+ } -+ - lock_sock(sk); - sk->sk_shutdown = SHUTDOWN_MASK; - -@@ -2372,7 +2467,7 @@ - /* Unread data was tossed, zap the connection. */ - NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPABORTONCLOSE); - tcp_set_state(sk, TCP_CLOSE); -- tcp_send_active_reset(sk, sk->sk_allocation); -+ tcp_sk(sk)->ops->send_active_reset(sk, sk->sk_allocation); - } else if (sock_flag(sk, SOCK_LINGER) && !sk->sk_lingertime) { - /* Check zero linger _after_ checking for unread data. */ - sk->sk_prot->disconnect(sk, 0); -@@ -2446,7 +2541,7 @@ - struct tcp_sock *tp = tcp_sk(sk); - if (tp->linger2 < 0) { - tcp_set_state(sk, TCP_CLOSE); -- tcp_send_active_reset(sk, GFP_ATOMIC); -+ tp->ops->send_active_reset(sk, GFP_ATOMIC); - __NET_INC_STATS(sock_net(sk), - LINUX_MIB_TCPABORTONLINGER); - } else { -@@ -2456,7 +2551,8 @@ - inet_csk_reset_keepalive_timer(sk, - tmo - TCP_TIMEWAIT_LEN); - } else { -- tcp_time_wait(sk, TCP_FIN_WAIT2, tmo); -+ tcp_sk(sk)->ops->time_wait(sk, TCP_FIN_WAIT2, -+ tmo); - goto out; - } - } -@@ -2465,7 +2561,7 @@ - sk_mem_reclaim(sk); - if (tcp_check_oom(sk, 0)) { - tcp_set_state(sk, TCP_CLOSE); -- tcp_send_active_reset(sk, GFP_ATOMIC); -+ tcp_sk(sk)->ops->send_active_reset(sk, GFP_ATOMIC); - __NET_INC_STATS(sock_net(sk), - LINUX_MIB_TCPABORTONMEMORY); - } else if (!check_net(sock_net(sk))) { -@@ -2494,15 +2590,6 @@ - } - EXPORT_SYMBOL(tcp_close); - --/* These states need RST on ABORT according to RFC793 */ -- --static inline bool tcp_need_reset(int state) --{ -- return (1 << state) & -- (TCPF_ESTABLISHED | TCPF_CLOSE_WAIT | TCPF_FIN_WAIT1 | -- TCPF_FIN_WAIT2 | TCPF_SYN_RECV); --} -- - static void tcp_rtx_queue_purge(struct sock *sk) - { - struct rb_node *p = rb_first(&sk->tcp_rtx_queue); -@@ -2524,6 +2611,10 @@ - { - struct sk_buff *skb; - -+ if (mptcp(tcp_sk(sk)) && !is_meta_sk(sk) && -+ !tcp_rtx_and_write_queues_empty(sk)) -+ mptcp_reinject_data(sk, 0); -+ - tcp_chrono_stop(sk, TCP_CHRONO_BUSY); - while ((skb = __skb_dequeue(&sk->sk_write_queue)) != NULL) { - tcp_skb_tsorted_anchor_cleanup(skb); -@@ -2558,7 +2649,7 @@ - /* The last check adjusts for discrepancy of Linux wrt. RFC - * states - */ -- tcp_send_active_reset(sk, gfp_any()); -+ tp->ops->send_active_reset(sk, gfp_any()); - sk->sk_err = ECONNRESET; - } else if (old_state == TCP_SYN_SENT) - sk->sk_err = ECONNRESET; -@@ -2576,6 +2667,13 @@ - if (!(sk->sk_userlocks & SOCK_BINDADDR_LOCK)) - inet_reset_saddr(sk); - -+ if (is_meta_sk(sk)) { -+ mptcp_disconnect(sk); -+ } else { -+ if (tp->inside_tk_table) -+ mptcp_hash_remove_bh(tp); -+ } -+ - sk->sk_shutdown = 0; - sock_reset_flag(sk, SOCK_DONE); - tp->srtt_us = 0; -@@ -2636,7 +2734,7 @@ - static inline bool tcp_can_repair_sock(const struct sock *sk) - { - return ns_capable(sock_net(sk)->user_ns, CAP_NET_ADMIN) && -- (sk->sk_state != TCP_LISTEN); -+ (sk->sk_state != TCP_LISTEN) && !sock_flag(sk, SOCK_MPTCP); - } - - static int tcp_repair_set_window(struct tcp_sock *tp, char __user *optbuf, int len) -@@ -2782,6 +2880,61 @@ - - return tcp_fastopen_reset_cipher(net, sk, key, sizeof(key)); - } -+#ifdef CONFIG_MPTCP -+ case MPTCP_SCHEDULER: { -+ char name[MPTCP_SCHED_NAME_MAX]; -+ -+ if (optlen < 1) -+ return -EINVAL; -+ -+ /* Cannot be used if MPTCP is not used or we already have -+ * established an MPTCP-connection. -+ */ -+ if (mptcp_init_failed || !sysctl_mptcp_enabled || -+ sk->sk_state != TCP_CLOSE) -+ return -EPERM; -+ -+ val = strncpy_from_user(name, optval, -+ min_t(long, MPTCP_SCHED_NAME_MAX - 1, -+ optlen)); -+ -+ if (val < 0) -+ return -EFAULT; -+ name[val] = 0; -+ -+ lock_sock(sk); -+ err = mptcp_set_scheduler(sk, name); -+ release_sock(sk); -+ return err; -+ } -+ -+ case MPTCP_PATH_MANAGER: { -+ char name[MPTCP_PM_NAME_MAX]; -+ -+ if (optlen < 1) -+ return -EINVAL; -+ -+ /* Cannot be used if MPTCP is not used or we already have -+ * established an MPTCP-connection. -+ */ -+ if (mptcp_init_failed || !sysctl_mptcp_enabled || -+ sk->sk_state != TCP_CLOSE) -+ return -EPERM; -+ -+ val = strncpy_from_user(name, optval, -+ min_t(long, MPTCP_PM_NAME_MAX - 1, -+ optlen)); -+ -+ if (val < 0) -+ return -EFAULT; -+ name[val] = 0; -+ -+ lock_sock(sk); -+ err = mptcp_set_path_manager(sk, name); -+ release_sock(sk); -+ return err; -+ } -+#endif - default: - /* fallthru */ - break; -@@ -2962,6 +3115,12 @@ - break; - - case TCP_DEFER_ACCEPT: -+ /* An established MPTCP-connection (mptcp(tp) only returns true -+ * if the socket is established) should not use DEFER on new -+ * subflows. -+ */ -+ if (mptcp(tp)) -+ break; - /* Translate value in seconds to number of retransmits */ - icsk->icsk_accept_queue.rskq_defer_accept = - secs_to_retrans(val, TCP_TIMEOUT_INIT / HZ, -@@ -2989,7 +3148,7 @@ - (TCPF_ESTABLISHED | TCPF_CLOSE_WAIT) && - inet_csk_ack_scheduled(sk)) { - icsk->icsk_ack.pending |= ICSK_ACK_PUSHED; -- tcp_cleanup_rbuf(sk, 1); -+ tp->ops->cleanup_rbuf(sk, 1); - if (!(val & 1)) - icsk->icsk_ack.pingpong = 1; - } -@@ -2999,7 +3158,7 @@ - #ifdef CONFIG_TCP_MD5SIG - case TCP_MD5SIG: - case TCP_MD5SIG_EXT: -- if ((1 << sk->sk_state) & (TCPF_CLOSE | TCPF_LISTEN)) -+ if ((1 << sk->sk_state) & (TCPF_CLOSE | TCPF_LISTEN) && !sock_flag(sk, SOCK_MPTCP)) - err = tp->af_specific->md5_parse(sk, optname, optval, optlen); - else - err = -EINVAL; -@@ -3058,6 +3217,32 @@ - tp->notsent_lowat = val; - sk->sk_write_space(sk); - break; -+#ifdef CONFIG_MPTCP -+ case MPTCP_ENABLED: -+ if (mptcp_init_failed || !sysctl_mptcp_enabled || -+ sk->sk_state != TCP_CLOSE -+#ifdef CONFIG_TCP_MD5SIG -+ || tp->md5sig_info -+#endif -+ ) { -+ err = -EPERM; -+ break; -+ } -+ -+ if (val) -+ mptcp_enable_sock(sk); -+ else -+ mptcp_disable_sock(sk); -+ break; -+ case MPTCP_INFO: -+ if (mptcp_init_failed || !sysctl_mptcp_enabled) { -+ err = -EPERM; -+ break; -+ } -+ -+ tp->record_master_info = !!(val & MPTCP_INFO_FLAG_SAVE_MASTER); -+ break; -+#endif - case TCP_INQ: - if (val > 1 || val < 0) - err = -EINVAL; -@@ -3117,7 +3302,7 @@ - } - - /* Return information about state of tcp endpoint in API format. */ --void tcp_get_info(struct sock *sk, struct tcp_info *info) -+void tcp_get_info(struct sock *sk, struct tcp_info *info, bool no_lock) - { - const struct tcp_sock *tp = tcp_sk(sk); /* iff sk_type == SOCK_STREAM */ - const struct inet_connection_sock *icsk = inet_csk(sk); -@@ -3154,7 +3339,8 @@ - return; - } - -- slow = lock_sock_fast(sk); -+ if (!no_lock) -+ slow = lock_sock_fast(sk); - - info->tcpi_ca_state = icsk->icsk_ca_state; - info->tcpi_retransmits = icsk->icsk_retransmits; -@@ -3228,7 +3414,9 @@ - info->tcpi_bytes_retrans = tp->bytes_retrans; - info->tcpi_dsack_dups = tp->dsack_dups; - info->tcpi_reord_seen = tp->reord_seen; -- unlock_sock_fast(sk, slow); -+ -+ if (!no_lock) -+ unlock_sock_fast(sk, slow); - } - EXPORT_SYMBOL_GPL(tcp_get_info); - -@@ -3373,7 +3561,7 @@ - if (get_user(len, optlen)) - return -EFAULT; - -- tcp_get_info(sk, &info); -+ tcp_get_info(sk, &info, false); - - len = min_t(unsigned int, len, sizeof(info)); - if (put_user(len, optlen)) -@@ -3564,6 +3752,87 @@ - } - return 0; - } -+#ifdef CONFIG_MPTCP -+ case MPTCP_SCHEDULER: -+ if (get_user(len, optlen)) -+ return -EFAULT; -+ len = min_t(unsigned int, len, MPTCP_SCHED_NAME_MAX); -+ if (put_user(len, optlen)) -+ return -EFAULT; -+ -+ lock_sock(sk); -+ if (mptcp(tcp_sk(sk))) { -+ struct mptcp_cb *mpcb = tcp_sk(mptcp_meta_sk(sk))->mpcb; -+ -+ if (copy_to_user(optval, mpcb->sched_ops->name, len)) { -+ release_sock(sk); -+ return -EFAULT; -+ } -+ } else { -+ if (copy_to_user(optval, tcp_sk(sk)->mptcp_sched_name, -+ len)) { -+ release_sock(sk); -+ return -EFAULT; -+ } -+ } -+ release_sock(sk); -+ return 0; -+ -+ case MPTCP_PATH_MANAGER: -+ if (get_user(len, optlen)) -+ return -EFAULT; -+ len = min_t(unsigned int, len, MPTCP_PM_NAME_MAX); -+ if (put_user(len, optlen)) -+ return -EFAULT; -+ -+ lock_sock(sk); -+ if (mptcp(tcp_sk(sk))) { -+ struct mptcp_cb *mpcb = tcp_sk(mptcp_meta_sk(sk))->mpcb; -+ -+ if (copy_to_user(optval, mpcb->pm_ops->name, len)) { -+ release_sock(sk); -+ return -EFAULT; -+ } -+ } else { -+ if (copy_to_user(optval, tcp_sk(sk)->mptcp_pm_name, -+ len)) { -+ release_sock(sk); -+ return -EFAULT; -+ } -+ } -+ release_sock(sk); -+ return 0; -+ -+ case MPTCP_ENABLED: -+ if (sk->sk_state != TCP_SYN_SENT) -+ val = mptcp(tp) ? 1 : 0; -+ else -+ val = sock_flag(sk, SOCK_MPTCP) ? 1 : 0; -+ break; -+ case MPTCP_INFO: -+ { -+ int ret; -+ -+ if (!mptcp(tp)) -+ return -EINVAL; -+ -+ if (get_user(len, optlen)) -+ return -EFAULT; -+ -+ len = min_t(unsigned int, len, sizeof(struct mptcp_info)); -+ -+ lock_sock(sk); -+ ret = mptcp_get_info(sk, optval, len); -+ release_sock(sk); -+ -+ if (ret) -+ return ret; -+ -+ if (put_user(len, optlen)) -+ return -EFAULT; -+ return 0; -+ } -+#endif - #ifdef CONFIG_MMU - case TCP_ZEROCOPY_RECEIVE: { - struct tcp_zerocopy_receive zc; -@@ -3757,7 +4026,9 @@ - if (sk->sk_state == TCP_SYN_SENT || sk->sk_state == TCP_SYN_RECV) - TCP_INC_STATS(sock_net(sk), TCP_MIB_ATTEMPTFAILS); - -+ WARN_ON(sk->sk_state == TCP_CLOSE); - tcp_set_state(sk, TCP_CLOSE); -+ - tcp_clear_xmit_timers(sk); - if (req) - reqsk_fastopen_remove(sk, req, false); -@@ -3773,6 +4044,8 @@ - - int tcp_abort(struct sock *sk, int err) - { -+ struct sock *meta_sk = mptcp(tcp_sk(sk)) ? mptcp_meta_sk(sk) : sk; -+ - if (!sk_fullsock(sk)) { - if (sk->sk_state == TCP_NEW_SYN_RECV) { - struct request_sock *req = inet_reqsk(sk); -@@ -3786,7 +4059,7 @@ - } - - /* Don't race with userspace socket closes such as tcp_close. */ -- lock_sock(sk); -+ lock_sock(meta_sk); - - if (sk->sk_state == TCP_LISTEN) { - tcp_set_state(sk, TCP_CLOSE); -@@ -3795,7 +4068,7 @@ - - /* Don't race with BH socket closes such as inet_csk_listen_stop. */ - local_bh_disable(); -- bh_lock_sock(sk); -+ bh_lock_sock(meta_sk); - - if (!sock_flag(sk, SOCK_DEAD)) { - sk->sk_err = err; -@@ -3803,14 +4076,14 @@ - smp_wmb(); - sk->sk_error_report(sk); - if (tcp_need_reset(sk->sk_state)) -- tcp_send_active_reset(sk, GFP_ATOMIC); -+ tcp_sk(sk)->ops->send_active_reset(sk, GFP_ATOMIC); - tcp_done(sk); - } - -- bh_unlock_sock(sk); -+ bh_unlock_sock(meta_sk); - local_bh_enable(); - tcp_write_queue_purge(sk); -- release_sock(sk); -+ release_sock(meta_sk); - return 0; - } - EXPORT_SYMBOL_GPL(tcp_abort); -diff -aurN linux-4.19.104/net/ipv4/tcp_cong.c mptcp-mptcp_v0.95/net/ipv4/tcp_cong.c ---- linux-4.19.104/net/ipv4/tcp_cong.c 2020-02-14 22:33:28.000000000 +0100 -+++ mptcp-mptcp_v0.95/net/ipv4/tcp_cong.c 2020-02-17 11:29:55.000000000 +0100 -@@ -327,13 +327,19 @@ - return ret; - } - -+int tcp_set_congestion_control(struct sock *sk, const char *name, bool load, -+ bool reinit, bool cap_net_admin) -+{ -+ return tcp_sk(sk)->ops->set_cong_ctrl(sk, name, load, reinit, cap_net_admin); -+} -+ - /* Change congestion control for socket. If load is false, then it is the - * responsibility of the caller to call tcp_init_congestion_control or - * tcp_reinit_congestion_control (if the current congestion control was - * already initialized. - */ --int tcp_set_congestion_control(struct sock *sk, const char *name, bool load, -- bool reinit, bool cap_net_admin) -+int __tcp_set_congestion_control(struct sock *sk, const char *name, bool load, -+ bool reinit, bool cap_net_admin) - { - struct inet_connection_sock *icsk = inet_csk(sk); - const struct tcp_congestion_ops *ca; -diff -aurN linux-4.19.104/net/ipv4/tcp_diag.c mptcp-mptcp_v0.95/net/ipv4/tcp_diag.c ---- linux-4.19.104/net/ipv4/tcp_diag.c 2020-02-14 22:33:28.000000000 +0100 -+++ mptcp-mptcp_v0.95/net/ipv4/tcp_diag.c 2020-02-17 11:29:55.000000000 +0100 -@@ -34,7 +34,7 @@ - r->idiag_wqueue = tp->write_seq - tp->snd_una; - } - if (info) -- tcp_get_info(sk, info); -+ tcp_get_info(sk, info, false); - } - - #ifdef CONFIG_TCP_MD5SIG -diff -aurN linux-4.19.104/net/ipv4/tcp_fastopen.c mptcp-mptcp_v0.95/net/ipv4/tcp_fastopen.c ---- linux-4.19.104/net/ipv4/tcp_fastopen.c 2020-02-14 22:33:28.000000000 +0100 -+++ mptcp-mptcp_v0.95/net/ipv4/tcp_fastopen.c 2020-02-17 11:29:55.000000000 +0100 -@@ -9,6 +9,7 @@ - #include - #include - #include -+#include - - void tcp_fastopen_init_key_once(struct net *net) - { -@@ -218,8 +219,9 @@ - { - struct tcp_sock *tp; - struct request_sock_queue *queue = &inet_csk(sk)->icsk_accept_queue; -- struct sock *child; -+ struct sock *child, *meta_sk; - bool own_req; -+ int ret; - - req->num_retrans = 0; - req->num_timeout = 0; -@@ -258,15 +260,26 @@ - - refcount_set(&req->rsk_refcnt, 2); - -- /* Now finish processing the fastopen child socket. */ -- tcp_init_transfer(child, BPF_SOCK_OPS_PASSIVE_ESTABLISHED_CB); -- - tp->rcv_nxt = TCP_SKB_CB(skb)->seq + 1; - - tcp_fastopen_add_skb(child, skb); - - tcp_rsk(req)->rcv_nxt = tp->rcv_nxt; - tp->rcv_wup = tp->rcv_nxt; -+ -+ meta_sk = child; -+ ret = mptcp_check_req_fastopen(meta_sk, req); -+ if (ret < 0) -+ return NULL; -+ -+ if (ret == 0) { -+ child = tcp_sk(meta_sk)->mpcb->master_sk; -+ tp = tcp_sk(child); -+ } -+ -+ /* Now finish processing the fastopen child socket. */ -+ tcp_init_transfer(child, BPF_SOCK_OPS_PASSIVE_ESTABLISHED_CB); -+ - /* tcp_conn_request() is sending the SYNACK, - * and queues the child into listener accept queue. - */ -diff -aurN linux-4.19.104/net/ipv4/tcp_input.c mptcp-mptcp_v0.95/net/ipv4/tcp_input.c ---- linux-4.19.104/net/ipv4/tcp_input.c 2020-02-14 22:33:28.000000000 +0100 -+++ mptcp-mptcp_v0.95/net/ipv4/tcp_input.c 2020-02-17 11:29:55.000000000 +0100 -@@ -76,35 +76,15 @@ - #include - #include - #include -+#include -+#include -+#include - #include - #include - #include - - int sysctl_tcp_max_orphans __read_mostly = NR_FILE; - --#define FLAG_DATA 0x01 /* Incoming frame contained data. */ --#define FLAG_WIN_UPDATE 0x02 /* Incoming ACK was a window update. */ --#define FLAG_DATA_ACKED 0x04 /* This ACK acknowledged new data. */ --#define FLAG_RETRANS_DATA_ACKED 0x08 /* "" "" some of which was retransmitted. */ --#define FLAG_SYN_ACKED 0x10 /* This ACK acknowledged SYN. */ --#define FLAG_DATA_SACKED 0x20 /* New SACK. */ --#define FLAG_ECE 0x40 /* ECE in this ACK */ --#define FLAG_LOST_RETRANS 0x80 /* This ACK marks some retransmission lost */ --#define FLAG_SLOWPATH 0x100 /* Do not skip RFC checks for window update.*/ --#define FLAG_ORIG_SACK_ACKED 0x200 /* Never retransmitted data are (s)acked */ --#define FLAG_SND_UNA_ADVANCED 0x400 /* Snd_una was changed (!= FLAG_DATA_ACKED) */ --#define FLAG_DSACKING_ACK 0x800 /* SACK blocks contained D-SACK info */ --#define FLAG_SET_XMIT_TIMER 0x1000 /* Set TLP or RTO timer */ --#define FLAG_SACK_RENEGING 0x2000 /* snd_una advanced to a sacked seq */ --#define FLAG_UPDATE_TS_RECENT 0x4000 /* tcp_replace_ts_recent() */ --#define FLAG_NO_CHALLENGE_ACK 0x8000 /* do not call tcp_send_challenge_ack() */ --#define FLAG_ACK_MAYBE_DELAYED 0x10000 /* Likely a delayed ACK */ -- --#define FLAG_ACKED (FLAG_DATA_ACKED|FLAG_SYN_ACKED) --#define FLAG_NOT_DUP (FLAG_DATA|FLAG_WIN_UPDATE|FLAG_ACKED) --#define FLAG_CA_ALERT (FLAG_DATA_SACKED|FLAG_ECE|FLAG_DSACKING_ACK) --#define FLAG_FORWARD_PROGRESS (FLAG_ACKED|FLAG_DATA_SACKED) -- - #define TCP_REMNANT (TCP_FLAG_FIN|TCP_FLAG_URG|TCP_FLAG_SYN|TCP_FLAG_PSH) - #define TCP_HP_BITS (~(TCP_RESERVED_BITS|TCP_FLAG_PSH)) - -@@ -342,8 +322,12 @@ - per_mss = roundup_pow_of_two(per_mss) + - SKB_DATA_ALIGN(sizeof(struct sk_buff)); - -- nr_segs = max_t(u32, TCP_INIT_CWND, tp->snd_cwnd); -- nr_segs = max_t(u32, nr_segs, tp->reordering + 1); -+ if (mptcp(tp)) { -+ nr_segs = mptcp_check_snd_buf(tp); -+ } else { -+ nr_segs = max_t(u32, TCP_INIT_CWND, tp->snd_cwnd); -+ nr_segs = max_t(u32, nr_segs, tp->reordering + 1); -+ } - - /* Fast Recovery (RFC 5681 3.2) : - * Cubic needs 1.7 factor, rounded to 2 to include -@@ -352,8 +336,16 @@ - sndmem = ca_ops->sndbuf_expand ? ca_ops->sndbuf_expand(sk) : 2; - sndmem *= nr_segs * per_mss; - -- if (sk->sk_sndbuf < sndmem) -+ /* MPTCP: after this sndmem is the new contribution of the -+ * current subflow to the aggregated sndbuf */ -+ if (sk->sk_sndbuf < sndmem) { -+ int old_sndbuf = sk->sk_sndbuf; - sk->sk_sndbuf = min(sndmem, sock_net(sk)->ipv4.sysctl_tcp_wmem[2]); -+ /* MPTCP: ok, the subflow sndbuf has grown, reflect -+ * this in the aggregate buffer.*/ -+ if (mptcp(tp) && old_sndbuf != sk->sk_sndbuf) -+ mptcp_update_sndbuf(tp); -+ } - } - - /* 2. Tuning advertised window (window_clamp, rcv_ssthresh) -@@ -402,9 +394,14 @@ - static void tcp_grow_window(struct sock *sk, const struct sk_buff *skb) - { - struct tcp_sock *tp = tcp_sk(sk); -+ struct sock *meta_sk = mptcp(tp) ? mptcp_meta_sk(sk) : sk; -+ struct tcp_sock *meta_tp = tcp_sk(meta_sk); - int room; - -- room = min_t(int, tp->window_clamp, tcp_space(sk)) - tp->rcv_ssthresh; -+ if (is_meta_sk(sk)) -+ return; -+ -+ room = min_t(int, meta_tp->window_clamp, tcp_space(meta_sk)) - meta_tp->rcv_ssthresh; - - /* Check #1 */ - if (room > 0 && !tcp_under_memory_pressure(sk)) { -@@ -414,13 +411,13 @@ - * will fit to rcvbuf in future. - */ - if (tcp_win_from_space(sk, skb->truesize) <= skb->len) -- incr = 2 * tp->advmss; -+ incr = 2 * meta_tp->advmss; - else -- incr = __tcp_grow_window(sk, skb); -+ incr = __tcp_grow_window(meta_sk, skb); - - if (incr) { - incr = max_t(int, incr, 2 * skb->len); -- tp->rcv_ssthresh += min(room, incr); -+ meta_tp->rcv_ssthresh += min(room, incr); - inet_csk(sk)->icsk_ack.quick |= 1; - } - } -@@ -600,7 +597,10 @@ - - tcp_mstamp_refresh(tp); - time = tcp_stamp_us_delta(tp->tcp_mstamp, tp->rcvq_space.time); -- if (time < (tp->rcv_rtt_est.rtt_us >> 3) || tp->rcv_rtt_est.rtt_us == 0) -+ if (mptcp(tp)) { -+ if (mptcp_check_rtt(tp, time)) -+ return; -+ } else if (time < (tp->rcv_rtt_est.rtt_us >> 3) || tp->rcv_rtt_est.rtt_us == 0) - return; - - /* Number of bytes copied to user in last RTT */ -@@ -819,7 +819,7 @@ - /* Calculate rto without backoff. This is the second half of Van Jacobson's - * routine referred to above. - */ --static void tcp_set_rto(struct sock *sk) -+void tcp_set_rto(struct sock *sk) - { - const struct tcp_sock *tp = tcp_sk(sk); - /* Old crap is replaced with new one. 8) -@@ -1391,6 +1391,13 @@ - int len; - int in_sack; - -+ /* For MPTCP we cannot shift skb-data and remove one skb from the -+ * send-queue, because this will make us loose the DSS-option (which -+ * is stored in TCP_SKB_CB(skb)->dss) of the skb we are removing. -+ */ -+ if (mptcp(tp)) -+ goto fallback; -+ - /* Normally R but no L won't result in plain S */ - if (!dup_sack && - (TCP_SKB_CB(skb)->sacked & (TCPCB_LOST|TCPCB_SACKED_RETRANS)) == TCPCB_SACKED_RETRANS) -@@ -2942,7 +2949,7 @@ - */ - tcp_update_rtt_min(sk, ca_rtt_us, flag); - tcp_rtt_estimator(sk, seq_rtt_us); -- tcp_set_rto(sk); -+ tp->ops->set_rto(sk); - - /* RFC6298: only reset backoff on valid RTT measurement. */ - inet_csk(sk)->icsk_backoff = 0; -@@ -3010,7 +3017,7 @@ - } - - /* If we get here, the whole TSO packet has not been acked. */ --static u32 tcp_tso_acked(struct sock *sk, struct sk_buff *skb) -+u32 tcp_tso_acked(struct sock *sk, struct sk_buff *skb) - { - struct tcp_sock *tp = tcp_sk(sk); - u32 packets_acked; -@@ -3136,6 +3143,8 @@ - */ - if (likely(!(scb->tcp_flags & TCPHDR_SYN))) { - flag |= FLAG_DATA_ACKED; -+ if (mptcp(tp) && mptcp_is_data_seq(skb)) -+ flag |= MPTCP_FLAG_DATA_ACKED; - } else { - flag |= FLAG_SYN_ACKED; - tp->retrans_stamp = 0; -@@ -3255,7 +3264,7 @@ - return flag; - } - --static void tcp_ack_probe(struct sock *sk) -+void tcp_ack_probe(struct sock *sk) - { - struct inet_connection_sock *icsk = inet_csk(sk); - struct sk_buff *head = tcp_send_head(sk); -@@ -3327,9 +3336,8 @@ - /* Check that window update is acceptable. - * The function assumes that snd_una<=ack<=snd_next. - */ --static inline bool tcp_may_update_window(const struct tcp_sock *tp, -- const u32 ack, const u32 ack_seq, -- const u32 nwin) -+bool tcp_may_update_window(const struct tcp_sock *tp, const u32 ack, -+ const u32 ack_seq, const u32 nwin) - { - return after(ack, tp->snd_una) || - after(ack_seq, tp->snd_wl1) || -@@ -3566,7 +3574,7 @@ - } - - /* This routine deals with incoming acks, but not outgoing ones. */ --static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag) -+static int tcp_ack(struct sock *sk, struct sk_buff *skb, int flag) - { - struct inet_connection_sock *icsk = inet_csk(sk); - struct tcp_sock *tp = tcp_sk(sk); -@@ -3679,6 +3687,16 @@ - - tcp_rack_update_reo_wnd(sk, &rs); - -+ if (mptcp(tp)) { -+ if (mptcp_fallback_infinite(sk, flag)) { -+ pr_debug("%s resetting flow\n", __func__); -+ mptcp_send_reset(sk); -+ goto invalid_ack; -+ } -+ -+ mptcp_clean_rtx_infinite(skb, sk); -+ } -+ - if (tp->tlp_high_seq) - tcp_process_tlp_ack(sk, ack, flag); - /* If needed, reset TLP/RTO timer; RACK may later override this. */ -@@ -3778,8 +3796,10 @@ - */ - void tcp_parse_options(const struct net *net, - const struct sk_buff *skb, -- struct tcp_options_received *opt_rx, int estab, -- struct tcp_fastopen_cookie *foc) -+ struct tcp_options_received *opt_rx, -+ struct mptcp_options_received *mopt, -+ int estab, struct tcp_fastopen_cookie *foc, -+ struct tcp_sock *tp) - { - const unsigned char *ptr; - const struct tcphdr *th = tcp_hdr(skb); -@@ -3863,6 +3883,10 @@ - */ - break; - #endif -+ case TCPOPT_MPTCP: -+ mptcp_parse_options(ptr - 2, opsize, mopt, skb, tp); -+ break; -+ - case TCPOPT_FASTOPEN: - tcp_parse_fastopen_option( - opsize - TCPOLEN_FASTOPEN_BASE, -@@ -3930,7 +3954,9 @@ - return true; - } - -- tcp_parse_options(net, skb, &tp->rx_opt, 1, NULL); -+ tcp_parse_options(net, skb, &tp->rx_opt, -+ mptcp(tp) ? &tp->mptcp->rx_opt : NULL, 1, NULL, tp); -+ - if (tp->rx_opt.saw_tstamp && tp->rx_opt.rcv_tsecr) - tp->rx_opt.rcv_tsecr -= tp->tsoffset; - -@@ -4089,6 +4115,11 @@ - { - struct tcp_sock *tp = tcp_sk(sk); - -+ if (is_meta_sk(sk)) { -+ mptcp_fin(sk); -+ return; -+ } -+ - inet_csk_schedule_ack(sk); - - sk->sk_shutdown |= RCV_SHUTDOWN; -@@ -4099,6 +4130,10 @@ - case TCP_ESTABLISHED: - /* Move to CLOSE_WAIT */ - tcp_set_state(sk, TCP_CLOSE_WAIT); -+ -+ if (mptcp(tp)) -+ mptcp_sub_close_passive(sk); -+ - inet_csk(sk)->icsk_ack.pingpong = 1; - break; - -@@ -4121,9 +4156,16 @@ - tcp_set_state(sk, TCP_CLOSING); - break; - case TCP_FIN_WAIT2: -+ if (mptcp(tp)) { -+ /* The socket will get closed by mptcp_data_ready. -+ * We first have to process all data-sequences. -+ */ -+ tp->close_it = 1; -+ break; -+ } - /* Received a FIN -- send ACK and enter TIME_WAIT. */ - tcp_send_ack(sk); -- tcp_time_wait(sk, TCP_TIME_WAIT, 0); -+ tp->ops->time_wait(sk, TCP_TIME_WAIT, 0); - break; - default: - /* Only TCP_LISTEN and TCP_CLOSE are left, in these -@@ -4145,6 +4187,10 @@ - if (!sock_flag(sk, SOCK_DEAD)) { - sk->sk_state_change(sk); - -+ /* Don't wake up MPTCP-subflows */ -+ if (mptcp(tp)) -+ return; -+ - /* Do not send POLL_HUP for half duplex close. */ - if (sk->sk_shutdown == SHUTDOWN_MASK || - sk->sk_state == TCP_CLOSE) -@@ -4347,6 +4393,9 @@ - - *fragstolen = false; - -+ if (mptcp(tcp_sk(sk)) && !is_meta_sk(sk)) -+ return false; -+ - /* Its possible this segment overlaps with prior segment in queue */ - if (TCP_SKB_CB(from)->seq != TCP_SKB_CB(to)->end_seq) - return false; -@@ -4401,7 +4450,7 @@ - /* This one checks to see if we can put data from the - * out_of_order queue into the receive_queue. - */ --static void tcp_ofo_queue(struct sock *sk) -+void tcp_ofo_queue(struct sock *sk) - { - struct tcp_sock *tp = tcp_sk(sk); - __u32 dsack_high = tp->rcv_nxt; -@@ -4424,7 +4473,14 @@ - p = rb_next(p); - rb_erase(&skb->rbnode, &tp->out_of_order_queue); - -- if (unlikely(!after(TCP_SKB_CB(skb)->end_seq, tp->rcv_nxt))) { -+ /* In case of MPTCP, the segment may be empty if it's a -+ * non-data DATA_FIN. (see beginning of tcp_data_queue) -+ * -+ * But this only holds true for subflows, not for the -+ * meta-socket. -+ */ -+ if (unlikely(!after(TCP_SKB_CB(skb)->end_seq, tp->rcv_nxt) && -+ (is_meta_sk(sk) || !mptcp(tp) || TCP_SKB_CB(skb)->end_seq != TCP_SKB_CB(skb)->seq))) { - SOCK_DEBUG(sk, "ofo packet was already received\n"); - tcp_drop(sk, skb); - continue; -@@ -4458,6 +4514,9 @@ - static int tcp_try_rmem_schedule(struct sock *sk, struct sk_buff *skb, - unsigned int size) - { -+ if (mptcp(tcp_sk(sk))) -+ sk = mptcp_meta_sk(sk); -+ - if (atomic_read(&sk->sk_rmem_alloc) > sk->sk_rcvbuf || - !sk_rmem_schedule(sk, skb, size)) { - -@@ -4472,7 +4531,7 @@ - return 0; - } - --static void tcp_data_queue_ofo(struct sock *sk, struct sk_buff *skb) -+void tcp_data_queue_ofo(struct sock *sk, struct sk_buff *skb) - { - struct tcp_sock *tp = tcp_sk(sk); - struct rb_node **p, *parent; -@@ -4540,7 +4599,8 @@ - continue; - } - if (before(seq, TCP_SKB_CB(skb1)->end_seq)) { -- if (!after(end_seq, TCP_SKB_CB(skb1)->end_seq)) { -+ if (!after(end_seq, TCP_SKB_CB(skb1)->end_seq) && -+ (is_meta_sk(sk) || !mptcp(tp) || end_seq != seq)) { - /* All the bits are present. Drop. */ - NET_INC_STATS(sock_net(sk), - LINUX_MIB_TCPOFOMERGE); -@@ -4587,6 +4647,11 @@ - end_seq); - break; - } -+ /* MPTCP allows non-data data-fin to be in the ofo-queue */ -+ if (mptcp(tp) && !is_meta_sk(sk) && TCP_SKB_CB(skb1)->seq == TCP_SKB_CB(skb1)->end_seq) { -+ skb = skb1; -+ continue; -+ } - rb_erase(&skb1->rbnode, &tp->out_of_order_queue); - tcp_dsack_extend(sk, TCP_SKB_CB(skb1)->seq, - TCP_SKB_CB(skb1)->end_seq); -@@ -4598,7 +4663,7 @@ - tp->ooo_last_skb = skb; - - add_sack: -- if (tcp_is_sack(tp)) -+ if (tcp_is_sack(tp) && seq != end_seq) - tcp_sack_new_ofo_skb(sk, seq, end_seq); - end: - if (skb) { -@@ -4608,8 +4673,8 @@ - } - } - --static int __must_check tcp_queue_rcv(struct sock *sk, struct sk_buff *skb, int hdrlen, -- bool *fragstolen) -+int __must_check tcp_queue_rcv(struct sock *sk, struct sk_buff *skb, int hdrlen, -+ bool *fragstolen) - { - int eaten; - struct sk_buff *tail = skb_peek_tail(&sk->sk_receive_queue); -@@ -4683,7 +4748,7 @@ - const struct tcp_sock *tp = tcp_sk(sk); - int avail = tp->rcv_nxt - tp->copied_seq; - -- if (avail < sk->sk_rcvlowat && !sock_flag(sk, SOCK_DONE)) -+ if (avail < sk->sk_rcvlowat && !sock_flag(sk, SOCK_DONE) && !mptcp(tp)) - return; - - sk->sk_data_ready(sk); -@@ -4695,10 +4760,14 @@ - bool fragstolen; - int eaten; - -- if (TCP_SKB_CB(skb)->seq == TCP_SKB_CB(skb)->end_seq) { -+ /* If no data is present, but a data_fin is in the options, we still -+ * have to call mptcp_queue_skb later on. */ -+ if (TCP_SKB_CB(skb)->seq == TCP_SKB_CB(skb)->end_seq && -+ !(mptcp(tp) && mptcp_is_data_fin(skb))) { - __kfree_skb(skb); - return; - } -+ - skb_dst_drop(skb); - __skb_pull(skb, tcp_hdr(skb)->doff * 4); - -@@ -4726,7 +4795,7 @@ - } - - eaten = tcp_queue_rcv(sk, skb, 0, &fragstolen); -- if (skb->len) -+ if (skb->len || mptcp_is_data_fin(skb)) - tcp_event_data_recv(sk, skb); - if (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN) - tcp_fin(sk); -@@ -4748,7 +4817,11 @@ - - if (eaten > 0) - kfree_skb_partial(skb, fragstolen); -- if (!sock_flag(sk, SOCK_DEAD)) -+ if (!sock_flag(sk, SOCK_DEAD) || mptcp(tp)) -+ /* MPTCP: we always have to call data_ready, because -+ * we may be about to receive a data-fin, which still -+ * must get queued. -+ */ - tcp_data_ready(sk); - return; - } -@@ -5096,7 +5169,7 @@ - return -1; - } - --static bool tcp_should_expand_sndbuf(const struct sock *sk) -+bool tcp_should_expand_sndbuf(const struct sock *sk) - { - const struct tcp_sock *tp = tcp_sk(sk); - -@@ -5131,7 +5204,7 @@ - { - struct tcp_sock *tp = tcp_sk(sk); - -- if (tcp_should_expand_sndbuf(sk)) { -+ if (tp->ops->should_expand_sndbuf(sk)) { - tcp_sndbuf_expand(sk); - tp->snd_cwnd_stamp = tcp_jiffies32; - } -@@ -5145,10 +5218,11 @@ - sock_reset_flag(sk, SOCK_QUEUE_SHRUNK); - /* pairs with tcp_poll() */ - smp_mb(); -- if (sk->sk_socket && -- test_bit(SOCK_NOSPACE, &sk->sk_socket->flags)) { -+ if (mptcp(tcp_sk(sk)) || -+ (sk->sk_socket && -+ test_bit(SOCK_NOSPACE, &sk->sk_socket->flags))) { - tcp_new_space(sk); -- if (!test_bit(SOCK_NOSPACE, &sk->sk_socket->flags)) -+ if (sk->sk_socket && !test_bit(SOCK_NOSPACE, &sk->sk_socket->flags)) - tcp_chrono_stop(sk, TCP_CHRONO_SNDBUF_LIMITED); - } - } -@@ -5167,6 +5241,8 @@ - { - struct tcp_sock *tp = tcp_sk(sk); - unsigned long rtt, delay; -+ struct sock *meta_sk = mptcp(tp) ? mptcp_meta_sk(sk) : sk; -+ struct tcp_sock *meta_tp = tcp_sk(meta_sk); - - /* More than one full frame received... */ - if (((tp->rcv_nxt - tp->rcv_wup) > inet_csk(sk)->icsk_ack.rcv_mss && -@@ -5175,8 +5251,8 @@ - * If application uses SO_RCVLOWAT, we want send ack now if - * we have not received enough bytes to satisfy the condition. - */ -- (tp->rcv_nxt - tp->copied_seq < sk->sk_rcvlowat || -- __tcp_select_window(sk) >= tp->rcv_wnd)) || -+ (meta_tp->rcv_nxt - meta_tp->copied_seq < meta_sk->sk_rcvlowat || -+ tp->ops->__select_window(sk) >= tp->rcv_wnd)) || - /* We ACK each frame or... */ - tcp_in_quickack_mode(sk) || - /* Protocol state mandates a one-time immediate ACK */ -@@ -5311,6 +5387,10 @@ - { - struct tcp_sock *tp = tcp_sk(sk); - -+ /* MPTCP urgent data is not yet supported */ -+ if (mptcp(tp)) -+ return; -+ - /* Check if we get a new urgent pointer - normally not. */ - if (th->urg) - tcp_check_urg(sk, th); -@@ -5453,9 +5533,15 @@ - goto discard; - } - -+ /* If valid: post process the received MPTCP options. */ -+ if (mptcp(tp) && mptcp_handle_options(sk, th, skb)) -+ goto discard; -+ - return true; - - discard: -+ if (mptcp(tp)) -+ mptcp_reset_mopt(tp); - tcp_drop(sk, skb); - return false; - } -@@ -5512,6 +5598,10 @@ - - tp->rx_opt.saw_tstamp = 0; - -+ /* MPTCP: force slowpath. */ -+ if (mptcp(tp)) -+ goto slow_path; -+ - /* pred_flags is 0xS?10 << 16 + snd_wnd - * if header_prediction is to be made - * 'S' will always be tp->tcp_header_len >> 2 -@@ -5695,17 +5785,24 @@ - struct tcp_fastopen_cookie *cookie) - { - struct tcp_sock *tp = tcp_sk(sk); -- struct sk_buff *data = tp->syn_data ? tcp_rtx_queue_head(sk) : NULL; -+ struct sk_buff *data = NULL; - u16 mss = tp->rx_opt.mss_clamp, try_exp = 0; - bool syn_drop = false; - -+ if (tp->syn_data) { -+ if (mptcp(tp)) -+ data = tcp_write_queue_head(mptcp_meta_sk(sk)); -+ else -+ data = tcp_rtx_queue_head(sk); -+ } -+ - if (mss == tp->rx_opt.user_mss) { - struct tcp_options_received opt; - - /* Get original SYNACK MSS value if user MSS sets mss_clamp */ - tcp_clear_options(&opt); - opt.user_mss = opt.mss_clamp = 0; -- tcp_parse_options(sock_net(sk), synack, &opt, 0, NULL); -+ tcp_parse_options(sock_net(sk), synack, &opt, NULL, 0, NULL, NULL); - mss = opt.mss_clamp; - } - -@@ -5729,7 +5826,11 @@ - - tcp_fastopen_cache_set(sk, mss, cookie, syn_drop, try_exp); - -- if (data) { /* Retransmit unacked data in SYN */ -+ /* In mptcp case, we do not rely on "retransmit", but instead on -+ * "transmit", because if fastopen data is not acked, the retransmission -+ * becomes the first MPTCP data (see mptcp_rcv_synsent_fastopen). -+ */ -+ if (data && !mptcp(tp)) { /* Retransmit unacked data in SYN */ - skb_rbtree_walk_from(data) { - if (__tcp_retransmit_skb(sk, data, 1)) - break; -@@ -5769,9 +5870,13 @@ - struct tcp_sock *tp = tcp_sk(sk); - struct tcp_fastopen_cookie foc = { .len = -1 }; - int saved_clamp = tp->rx_opt.mss_clamp; -+ struct mptcp_options_received mopt; - bool fastopen_fail; - -- tcp_parse_options(sock_net(sk), skb, &tp->rx_opt, 0, &foc); -+ mptcp_init_mp_opt(&mopt); -+ -+ tcp_parse_options(sock_net(sk), skb, &tp->rx_opt, -+ mptcp(tp) ? &tp->mptcp->rx_opt : &mopt, 0, &foc, tp); - if (tp->rx_opt.saw_tstamp && tp->rx_opt.rcv_tsecr) - tp->rx_opt.rcv_tsecr -= tp->tsoffset; - -@@ -5831,6 +5936,35 @@ - tcp_init_wl(tp, TCP_SKB_CB(skb)->seq); - tcp_ack(sk, skb, FLAG_SLOWPATH); - -+ if (tp->request_mptcp || mptcp(tp)) { -+ int ret; -+ -+ rcu_read_lock(); -+ local_bh_disable(); -+ ret = mptcp_rcv_synsent_state_process(sk, &sk, -+ skb, &mopt); -+ local_bh_enable(); -+ rcu_read_unlock(); -+ -+ /* May have changed if we support MPTCP */ -+ tp = tcp_sk(sk); -+ icsk = inet_csk(sk); -+ -+ if (ret == 1) -+ goto reset_and_undo; -+ if (ret == 2) -+ goto discard; -+ } -+ -+ if (mptcp(tp) && !is_master_tp(tp)) { -+ /* Timer for repeating the ACK until an answer -+ * arrives. Used only when establishing an additional -+ * subflow inside of an MPTCP connection. -+ */ -+ sk_reset_timer(sk, &tp->mptcp->mptcp_ack_timer, -+ jiffies + icsk->icsk_rto); -+ } -+ - /* Ok.. it's good. Set up sequence numbers and - * move to established. - */ -@@ -5857,6 +5991,11 @@ - tp->tcp_header_len = sizeof(struct tcphdr); - } - -+ if (mptcp(tp)) { -+ tp->tcp_header_len += MPTCP_SUB_LEN_DSM_ALIGN; -+ tp->advmss -= MPTCP_SUB_LEN_DSM_ALIGN; -+ } -+ - tcp_sync_mss(sk, icsk->icsk_pmtu_cookie); - tcp_initialize_rcv_mss(sk); - -@@ -5880,9 +6019,12 @@ - } - if (fastopen_fail) - return -1; -- if (sk->sk_write_pending || -+ /* With MPTCP we cannot send data on the third ack due to the -+ * lack of option-space to combine with an MP_CAPABLE. -+ */ -+ if (!mptcp(tp) && (sk->sk_write_pending || - icsk->icsk_accept_queue.rskq_defer_accept || -- icsk->icsk_ack.pingpong) { -+ icsk->icsk_ack.pingpong)) { - /* Save one ACK. Data will be ready after - * several ticks, if write_pending is set. - * -@@ -5921,6 +6063,7 @@ - tcp_paws_reject(&tp->rx_opt, 0)) - goto discard_and_undo; - -+ /* TODO - check this here for MPTCP */ - if (th->syn) { - /* We see SYN without ACK. It is attempt of - * simultaneous connect with crossed SYNs. -@@ -5937,6 +6080,11 @@ - tp->tcp_header_len = sizeof(struct tcphdr); - } - -+ if (mptcp(tp)) { -+ tp->tcp_header_len += MPTCP_SUB_LEN_DSM_ALIGN; -+ tp->advmss -= MPTCP_SUB_LEN_DSM_ALIGN; -+ } -+ - WRITE_ONCE(tp->rcv_nxt, TCP_SKB_CB(skb)->seq + 1); - tp->copied_seq = tp->rcv_nxt; - tp->rcv_wup = TCP_SKB_CB(skb)->seq + 1; -@@ -5995,6 +6143,7 @@ - */ - - int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb) -+ __releases(&sk->sk_lock.slock) - { - struct tcp_sock *tp = tcp_sk(sk); - struct inet_connection_sock *icsk = inet_csk(sk); -@@ -6037,6 +6186,16 @@ - tp->rx_opt.saw_tstamp = 0; - tcp_mstamp_refresh(tp); - queued = tcp_rcv_synsent_state_process(sk, skb, th); -+ if (is_meta_sk(sk)) { -+ sk = tcp_sk(sk)->mpcb->master_sk; -+ tp = tcp_sk(sk); -+ -+ /* Need to call it here, because it will announce new -+ * addresses, which can only be done after the third ack -+ * of the 3-way handshake. -+ */ -+ mptcp_update_metasocket(tp->meta_sk); -+ } - if (queued >= 0) - return queued; - -@@ -6119,6 +6278,8 @@ - - if (tp->rx_opt.tstamp_ok) - tp->advmss -= TCPOLEN_TSTAMP_ALIGNED; -+ if (mptcp(tp)) -+ tp->advmss -= MPTCP_SUB_LEN_DSM_ALIGN; - - if (!inet_csk(sk)->icsk_ca_ops->cong_control) - tcp_update_pacing_rate(sk); -@@ -6128,6 +6289,30 @@ - - tcp_initialize_rcv_mss(sk); - tcp_fast_path_on(tp); -+ -+ /* Send an ACK when establishing a new MPTCP subflow, i.e. -+ * using an MP_JOIN subtype. -+ */ -+ if (mptcp(tp)) { -+ if (is_master_tp(tp)) { -+ mptcp_update_metasocket(mptcp_meta_sk(sk)); -+ } else { -+ struct sock *meta_sk = mptcp_meta_sk(sk); -+ -+ tcp_send_ack(sk); -+ -+ /* Update RTO as it might be worse/better */ -+ mptcp_set_rto(sk); -+ -+ /* If the new RTO would fire earlier, pull it in! */ -+ if (tcp_sk(meta_sk)->packets_out && -+ icsk->icsk_timeout > inet_csk(meta_sk)->icsk_rto + jiffies) { -+ tcp_rearm_rto(meta_sk); -+ } -+ -+ mptcp_push_pending_frames(mptcp_meta_sk(sk)); -+ } -+ } - break; - - case TCP_FIN_WAIT1: { -@@ -6175,7 +6360,8 @@ - tmo = tcp_fin_time(sk); - if (tmo > TCP_TIMEWAIT_LEN) { - inet_csk_reset_keepalive_timer(sk, tmo - TCP_TIMEWAIT_LEN); -- } else if (th->fin || sock_owned_by_user(sk)) { -+ } else if (th->fin || mptcp_is_data_fin(skb) || -+ sock_owned_by_user(sk)) { - /* Bad case. We could lose such FIN otherwise. - * It is not a big problem, but it looks confusing - * and not so rare event. We still can lose it now, -@@ -6184,7 +6370,7 @@ - */ - inet_csk_reset_keepalive_timer(sk, tmo); - } else { -- tcp_time_wait(sk, TCP_FIN_WAIT2, tmo); -+ tp->ops->time_wait(sk, TCP_FIN_WAIT2, tmo); - goto discard; - } - break; -@@ -6192,7 +6378,7 @@ - - case TCP_CLOSING: - if (tp->snd_una == tp->write_seq) { -- tcp_time_wait(sk, TCP_TIME_WAIT, 0); -+ tp->ops->time_wait(sk, TCP_TIME_WAIT, 0); - goto discard; - } - break; -@@ -6204,6 +6390,9 @@ - goto discard; - } - break; -+ case TCP_CLOSE: -+ if (tp->mp_killed) -+ goto discard; - } - - /* step 6: check the URG bit */ -@@ -6225,7 +6414,8 @@ - */ - if (sk->sk_shutdown & RCV_SHUTDOWN) { - if (TCP_SKB_CB(skb)->end_seq != TCP_SKB_CB(skb)->seq && -- after(TCP_SKB_CB(skb)->end_seq - th->fin, tp->rcv_nxt)) { -+ after(TCP_SKB_CB(skb)->end_seq - th->fin, tp->rcv_nxt) && -+ !mptcp(tp)) { - NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPABORTONDATA); - tcp_reset(sk); - return 1; -@@ -6322,6 +6512,8 @@ - ireq->wscale_ok = rx_opt->wscale_ok; - ireq->acked = 0; - ireq->ecn_ok = 0; -+ ireq->mptcp_rqsk = 0; -+ ireq->saw_mpc = 0; - ireq->ir_rmt_port = tcp_hdr(skb)->source; - ireq->ir_num = ntohs(tcp_hdr(skb)->dest); - ireq->ir_mark = inet_request_mark(sk, skb); -@@ -6419,12 +6611,17 @@ - /* TW buckets are converted to open requests without - * limitations, they conserve resources and peer is - * evidently real one. -+ * -+ * MPTCP: new subflows cannot be established in a stateless manner. - */ -- if ((net->ipv4.sysctl_tcp_syncookies == 2 || -+ if (((!is_meta_sk(sk) && net->ipv4.sysctl_tcp_syncookies == 2) || - inet_csk_reqsk_queue_is_full(sk)) && !isn) { - want_cookie = tcp_syn_flood_action(sk, skb, rsk_ops->slab_name); - if (!want_cookie) - goto drop; -+ -+ if (is_meta_sk(sk)) -+ goto drop; - } - - if (sk_acceptq_is_full(sk)) { -@@ -6442,8 +6639,8 @@ - tcp_clear_options(&tmp_opt); - tmp_opt.mss_clamp = af_ops->mss_clamp; - tmp_opt.user_mss = tp->rx_opt.user_mss; -- tcp_parse_options(sock_net(sk), skb, &tmp_opt, 0, -- want_cookie ? NULL : &foc); -+ tcp_parse_options(sock_net(sk), skb, &tmp_opt, NULL, 0, -+ want_cookie ? NULL : &foc, NULL); - - if (want_cookie && !tmp_opt.saw_tstamp) - tcp_clear_options(&tmp_opt); -@@ -6458,7 +6655,8 @@ - /* Note: tcp_v6_init_req() might override ir_iif for link locals */ - inet_rsk(req)->ir_iif = inet_request_bound_dev_if(sk, skb); - -- af_ops->init_req(req, sk, skb); -+ if (af_ops->init_req(req, sk, skb, want_cookie)) -+ goto drop_and_free; - - if (security_inet_conn_request(sk, skb, req)) - goto drop_and_free; -@@ -6494,7 +6692,7 @@ - tcp_ecn_create_request(req, skb, sk, dst); - - if (want_cookie) { -- isn = cookie_init_sequence(af_ops, sk, skb, &req->mss); -+ isn = cookie_init_sequence(af_ops, req, sk, skb, &req->mss); - req->cookie_ts = tmp_opt.tstamp_ok; - if (!tmp_opt.tstamp_ok) - inet_rsk(req)->ecn_ok = 0; -@@ -6509,18 +6707,26 @@ - fastopen_sk = tcp_try_fastopen(sk, skb, req, &foc, dst); - } - if (fastopen_sk) { -+ struct sock *meta_sk = fastopen_sk; -+ -+ if (mptcp(tcp_sk(fastopen_sk))) -+ meta_sk = mptcp_meta_sk(fastopen_sk); - af_ops->send_synack(fastopen_sk, dst, &fl, req, - &foc, TCP_SYNACK_FASTOPEN); - /* Add the child socket directly into the accept queue */ -- if (!inet_csk_reqsk_queue_add(sk, req, fastopen_sk)) { -+ if (!inet_csk_reqsk_queue_add(sk, req, meta_sk)) { - reqsk_fastopen_remove(fastopen_sk, req, false); - bh_unlock_sock(fastopen_sk); -+ if (meta_sk != fastopen_sk) -+ bh_unlock_sock(meta_sk); - sock_put(fastopen_sk); - reqsk_put(req); - goto drop; - } - sk->sk_data_ready(sk); - bh_unlock_sock(fastopen_sk); -+ if (meta_sk != fastopen_sk) -+ bh_unlock_sock(meta_sk); - sock_put(fastopen_sk); - } else { - tcp_rsk(req)->tfo_listener = false; -diff -aurN linux-4.19.104/net/ipv4/tcp_ipv4.c mptcp-mptcp_v0.95/net/ipv4/tcp_ipv4.c ---- linux-4.19.104/net/ipv4/tcp_ipv4.c 2020-02-14 22:33:28.000000000 +0100 -+++ mptcp-mptcp_v0.95/net/ipv4/tcp_ipv4.c 2020-02-17 11:29:55.000000000 +0100 -@@ -67,6 +67,8 @@ - #include - #include - #include -+#include -+#include - #include - #include - #include -@@ -432,7 +434,7 @@ - struct inet_sock *inet; - const int type = icmp_hdr(icmp_skb)->type; - const int code = icmp_hdr(icmp_skb)->code; -- struct sock *sk; -+ struct sock *sk, *meta_sk; - struct sk_buff *skb; - struct request_sock *fastopen; - u32 seq, snd_una; -@@ -461,13 +463,19 @@ - (code == ICMP_NET_UNREACH || - code == ICMP_HOST_UNREACH))); - -- bh_lock_sock(sk); -+ tp = tcp_sk(sk); -+ if (mptcp(tp)) -+ meta_sk = mptcp_meta_sk(sk); -+ else -+ meta_sk = sk; -+ -+ bh_lock_sock(meta_sk); - /* If too many ICMPs get dropped on busy - * servers this needs to be solved differently. - * We do take care of PMTU discovery (RFC1191) special case : - * we can receive locally generated ICMP messages while socket is held. - */ -- if (sock_owned_by_user(sk)) { -+ if (sock_owned_by_user(meta_sk)) { - if (!(type == ICMP_DEST_UNREACH && code == ICMP_FRAG_NEEDED)) - __NET_INC_STATS(net, LINUX_MIB_LOCKDROPPEDICMPS); - } -@@ -480,7 +488,6 @@ - } - - icsk = inet_csk(sk); -- tp = tcp_sk(sk); - /* XXX (TFO) - tp->snd_una should be ISN (tcp_create_openreq_child() */ - fastopen = tp->fastopen_rsk; - snd_una = fastopen ? tcp_rsk(fastopen)->snt_isn : tp->snd_una; -@@ -514,11 +521,13 @@ - goto out; - - tp->mtu_info = info; -- if (!sock_owned_by_user(sk)) { -+ if (!sock_owned_by_user(meta_sk)) { - tcp_v4_mtu_reduced(sk); - } else { - if (!test_and_set_bit(TCP_MTU_REDUCED_DEFERRED, &sk->sk_tsq_flags)) - sock_hold(sk); -+ if (mptcp(tp)) -+ mptcp_tsq_flags(sk); - } - goto out; - } -@@ -532,7 +541,7 @@ - !icsk->icsk_backoff || fastopen) - break; - -- if (sock_owned_by_user(sk)) -+ if (sock_owned_by_user(meta_sk)) - break; - - skb = tcp_rtx_queue_head(sk); -@@ -555,7 +564,7 @@ - } else { - /* RTO revert clocked out retransmission. - * Will retransmit now */ -- tcp_retransmit_timer(sk); -+ tcp_sk(sk)->ops->retransmit_timer(sk); - } - - break; -@@ -575,7 +584,7 @@ - if (fastopen && !fastopen->sk) - break; - -- if (!sock_owned_by_user(sk)) { -+ if (!sock_owned_by_user(meta_sk)) { - sk->sk_err = err; - - sk->sk_error_report(sk); -@@ -604,7 +613,7 @@ - */ - - inet = inet_sk(sk); -- if (!sock_owned_by_user(sk) && inet->recverr) { -+ if (!sock_owned_by_user(meta_sk) && inet->recverr) { - sk->sk_err = err; - sk->sk_error_report(sk); - } else { /* Only an error on timeout */ -@@ -612,7 +621,7 @@ - } - - out: -- bh_unlock_sock(sk); -+ bh_unlock_sock(meta_sk); - sock_put(sk); - } - -@@ -647,7 +656,7 @@ - * Exception: precedence violation. We do not implement it in any case. - */ - --static void tcp_v4_send_reset(const struct sock *sk, struct sk_buff *skb) -+void tcp_v4_send_reset(const struct sock *sk, struct sk_buff *skb) - { - const struct tcphdr *th = tcp_hdr(skb); - struct { -@@ -793,10 +802,10 @@ - */ - - static void tcp_v4_send_ack(const struct sock *sk, -- struct sk_buff *skb, u32 seq, u32 ack, -+ struct sk_buff *skb, u32 seq, u32 ack, u32 data_ack, - u32 win, u32 tsval, u32 tsecr, int oif, - struct tcp_md5sig_key *key, -- int reply_flags, u8 tos) -+ int reply_flags, u8 tos, int mptcp) - { - const struct tcphdr *th = tcp_hdr(skb); - struct { -@@ -805,6 +814,10 @@ - #ifdef CONFIG_TCP_MD5SIG - + (TCPOLEN_MD5SIG_ALIGNED >> 2) - #endif -+#ifdef CONFIG_MPTCP -+ + ((MPTCP_SUB_LEN_DSS >> 2) + -+ (MPTCP_SUB_LEN_ACK >> 2)) -+#endif - ]; - } rep; - struct net *net = sock_net(sk); -@@ -850,6 +863,21 @@ - ip_hdr(skb)->daddr, &rep.th); - } - #endif -+#ifdef CONFIG_MPTCP -+ if (mptcp) { -+ int offset = (tsecr) ? 3 : 0; -+ /* Construction of 32-bit data_ack */ -+ rep.opt[offset++] = htonl((TCPOPT_MPTCP << 24) | -+ ((MPTCP_SUB_LEN_DSS + MPTCP_SUB_LEN_ACK) << 16) | -+ (0x20 << 8) | -+ (0x01)); -+ rep.opt[offset] = htonl(data_ack); -+ -+ arg.iov[0].iov_len += MPTCP_SUB_LEN_DSS + MPTCP_SUB_LEN_ACK; -+ rep.th.doff = arg.iov[0].iov_len / 4; -+ } -+#endif /* CONFIG_MPTCP */ -+ - arg.flags = reply_flags; - arg.csum = csum_tcpudp_nofold(ip_hdr(skb)->daddr, - ip_hdr(skb)->saddr, /* XXX */ -@@ -878,28 +906,36 @@ - { - struct inet_timewait_sock *tw = inet_twsk(sk); - struct tcp_timewait_sock *tcptw = tcp_twsk(sk); -+ u32 data_ack = 0; -+ int mptcp = 0; -+ -+ if (tcptw->mptcp_tw) { -+ data_ack = (u32)tcptw->mptcp_tw->rcv_nxt; -+ mptcp = 1; -+ } - - tcp_v4_send_ack(sk, skb, -- tcptw->tw_snd_nxt, tcptw->tw_rcv_nxt, -+ tcptw->tw_snd_nxt, tcptw->tw_rcv_nxt, data_ack, - tcptw->tw_rcv_wnd >> tw->tw_rcv_wscale, - tcp_time_stamp_raw() + tcptw->tw_ts_offset, - tcptw->tw_ts_recent, - tw->tw_bound_dev_if, - tcp_twsk_md5_key(tcptw), - tw->tw_transparent ? IP_REPLY_ARG_NOSRCCHECK : 0, -- tw->tw_tos -+ tw->tw_tos, mptcp - ); - - inet_twsk_put(tw); - } - --static void tcp_v4_reqsk_send_ack(const struct sock *sk, struct sk_buff *skb, -- struct request_sock *req) -+void tcp_v4_reqsk_send_ack(const struct sock *sk, struct sk_buff *skb, -+ struct request_sock *req) - { - /* sk->sk_state == TCP_LISTEN -> for regular TCP_SYN_RECV - * sk->sk_state == TCP_SYN_RECV -> for Fast Open. - */ -- u32 seq = (sk->sk_state == TCP_LISTEN) ? tcp_rsk(req)->snt_isn + 1 : -+ u32 seq = (sk->sk_state == TCP_LISTEN || is_meta_sk(sk)) ? -+ tcp_rsk(req)->snt_isn + 1 : - tcp_sk(sk)->snd_nxt; - - /* RFC 7323 2.3 -@@ -908,7 +944,7 @@ - * Rcv.Wind.Shift bits: - */ - tcp_v4_send_ack(sk, skb, seq, -- tcp_rsk(req)->rcv_nxt, -+ tcp_rsk(req)->rcv_nxt, 0, - req->rsk_rcv_wnd >> inet_rsk(req)->rcv_wscale, - tcp_time_stamp_raw() + tcp_rsk(req)->ts_off, - req->ts_recent, -@@ -916,7 +952,7 @@ - tcp_md5_do_lookup(sk, (union tcp_md5_addr *)&ip_hdr(skb)->saddr, - AF_INET), - inet_rsk(req)->no_srccheck ? IP_REPLY_ARG_NOSRCCHECK : 0, -- ip_hdr(skb)->tos); -+ ip_hdr(skb)->tos, 0); - } - - /* -@@ -924,11 +960,11 @@ - * This still operates on a request_sock only, not on a big - * socket. - */ --static int tcp_v4_send_synack(const struct sock *sk, struct dst_entry *dst, -- struct flowi *fl, -- struct request_sock *req, -- struct tcp_fastopen_cookie *foc, -- enum tcp_synack_type synack_type) -+int tcp_v4_send_synack(const struct sock *sk, struct dst_entry *dst, -+ struct flowi *fl, -+ struct request_sock *req, -+ struct tcp_fastopen_cookie *foc, -+ enum tcp_synack_type synack_type) - { - const struct inet_request_sock *ireq = inet_rsk(req); - struct flowi4 fl4; -@@ -958,7 +994,7 @@ - /* - * IPv4 request_sock destructor. - */ --static void tcp_v4_reqsk_destructor(struct request_sock *req) -+void tcp_v4_reqsk_destructor(struct request_sock *req) - { - kfree(rcu_dereference_protected(inet_rsk(req)->ireq_opt, 1)); - } -@@ -1331,9 +1367,10 @@ - return false; - } - --static void tcp_v4_init_req(struct request_sock *req, -- const struct sock *sk_listener, -- struct sk_buff *skb) -+static int tcp_v4_init_req(struct request_sock *req, -+ const struct sock *sk_listener, -+ struct sk_buff *skb, -+ bool want_cookie) - { - struct inet_request_sock *ireq = inet_rsk(req); - struct net *net = sock_net(sk_listener); -@@ -1341,6 +1378,8 @@ - sk_rcv_saddr_set(req_to_sk(req), ip_hdr(skb)->daddr); - sk_daddr_set(req_to_sk(req), ip_hdr(skb)->saddr); - RCU_INIT_POINTER(ireq->ireq_opt, tcp_v4_save_options(net, skb)); -+ -+ return 0; - } - - static struct dst_entry *tcp_v4_route_req(const struct sock *sk, -@@ -1360,7 +1399,7 @@ - .syn_ack_timeout = tcp_syn_ack_timeout, - }; - --static const struct tcp_request_sock_ops tcp_request_sock_ipv4_ops = { -+const struct tcp_request_sock_ops tcp_request_sock_ipv4_ops = { - .mss_clamp = TCP_MSS_DEFAULT, - #ifdef CONFIG_TCP_MD5SIG - .req_md5_lookup = tcp_v4_md5_lookup, -@@ -1497,7 +1536,7 @@ - } - EXPORT_SYMBOL(tcp_v4_syn_recv_sock); - --static struct sock *tcp_v4_cookie_check(struct sock *sk, struct sk_buff *skb) -+struct sock *tcp_v4_cookie_check(struct sock *sk, struct sk_buff *skb) - { - #ifdef CONFIG_SYN_COOKIES - const struct tcphdr *th = tcp_hdr(skb); -@@ -1520,6 +1559,9 @@ - { - struct sock *rsk; - -+ if (is_meta_sk(sk)) -+ return mptcp_v4_do_rcv(sk, skb); -+ - if (sk->sk_state == TCP_ESTABLISHED) { /* Fast path */ - struct dst_entry *dst = sk->sk_rx_dst; - -@@ -1671,6 +1713,10 @@ - TCP_SKB_CB(skb)->end_seq = (TCP_SKB_CB(skb)->seq + th->syn + th->fin + - skb->len - th->doff * 4); - TCP_SKB_CB(skb)->ack_seq = ntohl(th->ack_seq); -+#ifdef CONFIG_MPTCP -+ TCP_SKB_CB(skb)->mptcp_flags = 0; -+ TCP_SKB_CB(skb)->dss_off = 0; -+#endif - TCP_SKB_CB(skb)->tcp_flags = tcp_flag_byte(th); - TCP_SKB_CB(skb)->tcp_tw_isn = 0; - TCP_SKB_CB(skb)->ip_dsfield = ipv4_get_dsfield(iph); -@@ -1689,8 +1735,8 @@ - int sdif = inet_sdif(skb); - const struct iphdr *iph; - const struct tcphdr *th; -+ struct sock *sk, *meta_sk = NULL; - bool refcounted; -- struct sock *sk; - int ret; - - if (skb->pkt_type != PACKET_HOST) -@@ -1744,7 +1790,11 @@ - reqsk_put(req); - goto csum_error; - } -- if (unlikely(sk->sk_state != TCP_LISTEN)) { -+ if (unlikely(sk->sk_state != TCP_LISTEN && !is_meta_sk(sk))) { -+ inet_csk_reqsk_queue_drop_and_put(sk, req); -+ goto lookup; -+ } -+ if (unlikely(is_meta_sk(sk) && !mptcp_can_new_subflow(sk))) { - inet_csk_reqsk_queue_drop_and_put(sk, req); - goto lookup; - } -@@ -1753,6 +1803,7 @@ - */ - sock_hold(sk); - refcounted = true; -+ - nsk = NULL; - if (!tcp_filter(sk, skb)) { - th = (const struct tcphdr *)skb->data; -@@ -1813,15 +1864,24 @@ - - sk_incoming_cpu_update(sk); - -- bh_lock_sock_nested(sk); -+ if (mptcp(tcp_sk(sk))) { -+ meta_sk = mptcp_meta_sk(sk); -+ -+ bh_lock_sock_nested(meta_sk); -+ if (sock_owned_by_user(meta_sk)) -+ mptcp_prepare_for_backlog(sk, skb); -+ } else { -+ meta_sk = sk; -+ bh_lock_sock_nested(sk); -+ } - tcp_segs_in(tcp_sk(sk), skb); - ret = 0; -- if (!sock_owned_by_user(sk)) { -+ if (!sock_owned_by_user(meta_sk)) { - ret = tcp_v4_do_rcv(sk, skb); -- } else if (tcp_add_backlog(sk, skb)) { -+ } else if (tcp_add_backlog(meta_sk, skb)) { - goto discard_and_relse; - } -- bh_unlock_sock(sk); -+ bh_unlock_sock(meta_sk); - - put_and_return: - if (refcounted) -@@ -1835,6 +1895,19 @@ - - tcp_v4_fill_cb(skb, iph, th); - -+#ifdef CONFIG_MPTCP -+ if (!sk && th->syn && !th->ack) { -+ int ret = mptcp_lookup_join(skb, NULL); -+ -+ if (ret < 0) { -+ tcp_v4_send_reset(NULL, skb); -+ goto discard_it; -+ } else if (ret > 0) { -+ return 0; -+ } -+ } -+#endif -+ - if (tcp_checksum_complete(skb)) { - csum_error: - __TCP_INC_STATS(net, TCP_MIB_CSUMERRORS); -@@ -1883,6 +1956,18 @@ - refcounted = false; - goto process; - } -+#ifdef CONFIG_MPTCP -+ if (th->syn && !th->ack) { -+ int ret = mptcp_lookup_join(skb, inet_twsk(sk)); -+ -+ if (ret < 0) { -+ tcp_v4_send_reset(NULL, skb); -+ goto discard_it; -+ } else if (ret > 0) { -+ return 0; -+ } -+ } -+#endif - } - /* to ACK */ - /* fall through */ -@@ -1952,7 +2037,12 @@ - - tcp_init_sock(sk); - -- icsk->icsk_af_ops = &ipv4_specific; -+#ifdef CONFIG_MPTCP -+ if (sock_flag(sk, SOCK_MPTCP)) -+ icsk->icsk_af_ops = &mptcp_v4_specific; -+ else -+#endif -+ icsk->icsk_af_ops = &ipv4_specific; - - #ifdef CONFIG_TCP_MD5SIG - tcp_sk(sk)->af_specific = &tcp_sock_ipv4_specific; -@@ -1971,6 +2061,11 @@ - - tcp_cleanup_congestion_control(sk); - -+ if (mptcp(tp)) -+ mptcp_destroy_sock(sk); -+ if (tp->inside_tk_table) -+ mptcp_hash_remove_bh(tp); -+ - tcp_cleanup_ulp(sk); - - /* Cleanup up the write buffer. */ -@@ -2475,6 +2570,11 @@ - .sysctl_rmem_offset = offsetof(struct net, ipv4.sysctl_tcp_rmem), - .max_header = MAX_TCP_HEADER, - .obj_size = sizeof(struct tcp_sock), -+#ifdef CONFIG_MPTCP -+ .useroffset = offsetof(struct tcp_sock, mptcp_sched_name), -+ .usersize = sizeof_field(struct tcp_sock, mptcp_sched_name) + -+ sizeof_field(struct tcp_sock, mptcp_pm_name), -+#endif - .slab_flags = SLAB_TYPESAFE_BY_RCU, - .twsk_prot = &tcp_timewait_sock_ops, - .rsk_prot = &tcp_request_sock_ops, -@@ -2485,6 +2585,9 @@ - .compat_getsockopt = compat_tcp_getsockopt, - #endif - .diag_destroy = tcp_abort, -+#ifdef CONFIG_MPTCP -+ .clear_sk = mptcp_clear_sk, -+#endif - }; - EXPORT_SYMBOL(tcp_prot); - -diff -aurN linux-4.19.104/net/ipv4/tcp_minisocks.c mptcp-mptcp_v0.95/net/ipv4/tcp_minisocks.c ---- linux-4.19.104/net/ipv4/tcp_minisocks.c 2020-02-14 22:33:28.000000000 +0100 -+++ mptcp-mptcp_v0.95/net/ipv4/tcp_minisocks.c 2020-02-17 11:29:55.000000000 +0100 -@@ -18,11 +18,13 @@ - * Jorge Cwik, - */ - -+#include - #include - #include - #include - #include - #include -+#include - #include - #include - #include -@@ -94,10 +96,14 @@ - struct tcp_options_received tmp_opt; - struct tcp_timewait_sock *tcptw = tcp_twsk((struct sock *)tw); - bool paws_reject = false; -+ struct mptcp_options_received mopt; - - tmp_opt.saw_tstamp = 0; -- if (th->doff > (sizeof(*th) >> 2) && tcptw->tw_ts_recent_stamp) { -- tcp_parse_options(twsk_net(tw), skb, &tmp_opt, 0, NULL); -+ if (th->doff > (sizeof(*th) >> 2) && -+ (tcptw->tw_ts_recent_stamp || tcptw->mptcp_tw)) { -+ mptcp_init_mp_opt(&mopt); -+ -+ tcp_parse_options(twsk_net(tw), skb, &tmp_opt, &mopt, 0, NULL, NULL); - - if (tmp_opt.saw_tstamp) { - if (tmp_opt.rcv_tsecr) -@@ -106,6 +112,11 @@ - tmp_opt.ts_recent_stamp = tcptw->tw_ts_recent_stamp; - paws_reject = tcp_paws_reject(&tmp_opt, th->rst); - } -+ -+ if (unlikely(mopt.mp_fclose) && tcptw->mptcp_tw) { -+ if (mopt.mptcp_sender_key == tcptw->mptcp_tw->loc_key) -+ return TCP_TW_RST; -+ } - } - - if (tw->tw_substate == TCP_FIN_WAIT2) { -@@ -129,6 +140,16 @@ - if (!th->ack || - !after(TCP_SKB_CB(skb)->end_seq, tcptw->tw_rcv_nxt) || - TCP_SKB_CB(skb)->end_seq == TCP_SKB_CB(skb)->seq) { -+ /* If mptcp_is_data_fin() returns true, we are sure that -+ * mopt has been initialized - otherwise it would not -+ * be a DATA_FIN. -+ */ -+ if (tcptw->mptcp_tw && tcptw->mptcp_tw->meta_tw && -+ mptcp_is_data_fin(skb) && -+ TCP_SKB_CB(skb)->seq == tcptw->tw_rcv_nxt && -+ mopt.data_seq + 1 == (u32)tcptw->mptcp_tw->rcv_nxt) -+ return TCP_TW_ACK; -+ - inet_twsk_put(tw); - return TCP_TW_SUCCESS; - } -@@ -274,6 +295,15 @@ - tcptw->tw_ts_offset = tp->tsoffset; - tcptw->tw_last_oow_ack_time = 0; - -+ if (mptcp(tp)) { -+ if (mptcp_init_tw_sock(sk, tcptw)) { -+ inet_twsk_free(tw); -+ goto exit; -+ } -+ } else { -+ tcptw->mptcp_tw = NULL; -+ } -+ - #if IS_ENABLED(CONFIG_IPV6) - if (tw->tw_family == PF_INET6) { - struct ipv6_pinfo *np = inet6_sk(sk); -@@ -330,6 +360,7 @@ - NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPTIMEWAITOVERFLOW); - } - -+exit: - tcp_update_metrics(sk); - tcp_done(sk); - } -@@ -337,9 +368,11 @@ - - void tcp_twsk_destructor(struct sock *sk) - { --#ifdef CONFIG_TCP_MD5SIG - struct tcp_timewait_sock *twsk = tcp_twsk(sk); - -+ if (twsk->mptcp_tw) -+ mptcp_twsk_destructor(twsk); -+#ifdef CONFIG_TCP_MD5SIG - if (twsk->tw_md5_key) - kfree_rcu(twsk->tw_md5_key, rcu); - #endif -@@ -378,8 +411,9 @@ - full_space = rcv_wnd * mss; - - /* tcp_full_space because it is guaranteed to be the first packet */ -- tcp_select_initial_window(sk_listener, full_space, -- mss - (ireq->tstamp_ok ? TCPOLEN_TSTAMP_ALIGNED : 0), -+ tp->ops->select_initial_window(sk_listener, full_space, -+ mss - (ireq->tstamp_ok ? TCPOLEN_TSTAMP_ALIGNED : 0) - -+ (ireq->saw_mpc ? MPTCP_SUB_LEN_DSM_ALIGN : 0), - &req->rsk_rcv_wnd, - &req->rsk_window_clamp, - ireq->wscale_ok, -@@ -477,6 +511,8 @@ - newtp->snd_sml = newtp->snd_una = - newtp->snd_nxt = newtp->snd_up = treq->snt_isn + 1; - -+ newtp->out_of_order_queue = RB_ROOT; -+ newsk->tcp_rtx_queue = RB_ROOT; - INIT_LIST_HEAD(&newtp->tsq_node); - INIT_LIST_HEAD(&newtp->tsorted_sent_queue); - -@@ -547,6 +583,8 @@ - newtp->rx_opt.ts_recent_stamp = 0; - newtp->tcp_header_len = sizeof(struct tcphdr); - } -+ if (ireq->saw_mpc) -+ newtp->tcp_header_len += MPTCP_SUB_LEN_DSM_ALIGN; - newtp->tsoffset = treq->ts_off; - #ifdef CONFIG_TCP_MD5SIG - newtp->md5sig_info = NULL; /*XXX*/ -@@ -566,6 +604,7 @@ - newtp->rack.last_delivered = 0; - newtp->rack.reo_wnd_persist = 0; - newtp->rack.dsack_seen = 0; -+ newtp->inside_tk_table = 0; - - __TCP_INC_STATS(sock_net(sk), TCP_MIB_PASSIVEOPENS); - -@@ -589,6 +628,7 @@ - bool fastopen, bool *req_stolen) - { - struct tcp_options_received tmp_opt; -+ struct mptcp_options_received mopt; - struct sock *child; - const struct tcphdr *th = tcp_hdr(skb); - __be32 flg = tcp_flag_word(th) & (TCP_FLAG_RST|TCP_FLAG_SYN|TCP_FLAG_ACK); -@@ -596,8 +636,11 @@ - bool own_req; - - tmp_opt.saw_tstamp = 0; -+ -+ mptcp_init_mp_opt(&mopt); -+ - if (th->doff > (sizeof(struct tcphdr)>>2)) { -- tcp_parse_options(sock_net(sk), skb, &tmp_opt, 0, NULL); -+ tcp_parse_options(sock_net(sk), skb, &tmp_opt, &mopt, 0, NULL, NULL); - - if (tmp_opt.saw_tstamp) { - tmp_opt.ts_recent = req->ts_recent; -@@ -638,7 +681,14 @@ - * - * Reset timer after retransmitting SYNACK, similar to - * the idea of fast retransmit in recovery. -+ * -+ * Fall back to TCP if MP_CAPABLE is not set. - */ -+ -+ if (inet_rsk(req)->saw_mpc && !mopt.saw_mpc) -+ inet_rsk(req)->saw_mpc = false; -+ -+ - if (!tcp_oow_rate_limited(sock_net(sk), skb, - LINUX_MIB_TCPACKSKIPPEDSYNRECV, - &tcp_rsk(req)->last_oow_ack_time) && -@@ -786,17 +836,37 @@ - * ESTABLISHED STATE. If it will be dropped after - * socket is created, wait for troubles. - */ -+ if (is_meta_sk(sk)) -+ bh_lock_sock_nested(sk); - child = inet_csk(sk)->icsk_af_ops->syn_recv_sock(sk, skb, req, NULL, - req, &own_req); - if (!child) - goto listen_overflow; - -+ if (own_req && !is_meta_sk(sk)) { -+ int ret = mptcp_check_req_master(sk, child, req, skb, 1, 0); -+ if (ret < 0) -+ goto listen_overflow; -+ -+ /* MPTCP-supported */ -+ if (!ret) -+ return tcp_sk(child)->mpcb->master_sk; -+ } else if (own_req) { -+ return mptcp_check_req_child(sk, child, req, skb, &mopt); -+ } -+ -+ if (is_meta_sk(sk)) -+ bh_unlock_sock(sk); -+ - sock_rps_save_rxhash(child, skb); - tcp_synack_rtt_meas(child, req); - *req_stolen = !own_req; - return inet_csk_complete_hashdance(sk, child, req, own_req); - - listen_overflow: -+ if (is_meta_sk(sk)) -+ bh_unlock_sock(sk); -+ - if (!sock_net(sk)->ipv4.sysctl_tcp_abort_on_overflow) { - inet_rsk(req)->acked = 1; - return NULL; -@@ -839,12 +909,13 @@ - { - int ret = 0; - int state = child->sk_state; -+ struct sock *meta_sk = mptcp(tcp_sk(child)) ? mptcp_meta_sk(child) : child; - - /* record NAPI ID of child */ - sk_mark_napi_id(child, skb); - - tcp_segs_in(tcp_sk(child), skb); -- if (!sock_owned_by_user(child)) { -+ if (!sock_owned_by_user(meta_sk)) { - ret = tcp_rcv_state_process(child, skb); - /* Wakeup parent, send SIGIO */ - if (state == TCP_SYN_RECV && child->sk_state != state) -@@ -854,10 +925,14 @@ - * in main socket hash table and lock on listening - * socket does not protect us more. - */ -- __sk_add_backlog(child, skb); -+ if (mptcp(tcp_sk(child))) -+ mptcp_prepare_for_backlog(child, skb); -+ __sk_add_backlog(meta_sk, skb); - } - - bh_unlock_sock(child); -+ if (mptcp(tcp_sk(child))) -+ bh_unlock_sock(meta_sk); - sock_put(child); - return ret; - } -diff -aurN linux-4.19.104/net/ipv4/tcp_output.c mptcp-mptcp_v0.95/net/ipv4/tcp_output.c ---- linux-4.19.104/net/ipv4/tcp_output.c 2020-02-14 22:33:28.000000000 +0100 -+++ mptcp-mptcp_v0.95/net/ipv4/tcp_output.c 2020-02-17 11:29:55.000000000 +0100 -@@ -36,6 +36,12 @@ - - #define pr_fmt(fmt) "TCP: " fmt - -+#include -+#include -+#if IS_ENABLED(CONFIG_IPV6) -+#include -+#endif -+#include - #include - - #include -@@ -45,11 +51,8 @@ - - #include - --static bool tcp_write_xmit(struct sock *sk, unsigned int mss_now, int nonagle, -- int push_one, gfp_t gfp); -- - /* Account for new data that has been sent to the network. */ --static void tcp_event_new_data_sent(struct sock *sk, struct sk_buff *skb) -+void tcp_event_new_data_sent(struct sock *sk, struct sk_buff *skb) - { - struct inet_connection_sock *icsk = inet_csk(sk); - struct tcp_sock *tp = tcp_sk(sk); -@@ -242,12 +245,16 @@ - * value can be stuffed directly into th->window for an outgoing - * frame. - */ --static u16 tcp_select_window(struct sock *sk) -+u16 tcp_select_window(struct sock *sk) - { - struct tcp_sock *tp = tcp_sk(sk); - u32 old_win = tp->rcv_wnd; -- u32 cur_win = tcp_receive_window(tp); -- u32 new_win = __tcp_select_window(sk); -+ /* The window must never shrink at the meta-level. At the subflow we -+ * have to allow this. Otherwise we may announce a window too large -+ * for the current meta-level sk_rcvbuf. -+ */ -+ u32 cur_win = tcp_receive_window(mptcp(tp) ? tcp_sk(mptcp_meta_sk(sk)) : tp); -+ u32 new_win = tp->ops->__select_window(sk); - - /* Never shrink the offered window */ - if (new_win < cur_win) { -@@ -263,6 +270,7 @@ - LINUX_MIB_TCPWANTZEROWINDOWADV); - new_win = ALIGN(cur_win, 1 << tp->rx_opt.rcv_wscale); - } -+ - tp->rcv_wnd = new_win; - tp->rcv_wup = tp->rcv_nxt; - -@@ -375,7 +383,7 @@ - /* Constructs common control bits of non-data skb. If SYN/FIN is present, - * auto increment end seqno. - */ --static void tcp_init_nondata_skb(struct sk_buff *skb, u32 seq, u8 flags) -+void tcp_init_nondata_skb(struct sk_buff *skb, u32 seq, u8 flags) - { - skb->ip_summed = CHECKSUM_PARTIAL; - -@@ -390,7 +398,7 @@ - TCP_SKB_CB(skb)->end_seq = seq; - } - --static inline bool tcp_urg_mode(const struct tcp_sock *tp) -+bool tcp_urg_mode(const struct tcp_sock *tp) - { - return tp->snd_una != tp->snd_up; - } -@@ -401,6 +409,7 @@ - #define OPTION_WSCALE (1 << 3) - #define OPTION_FAST_OPEN_COOKIE (1 << 8) - #define OPTION_SMC (1 << 9) -+/* Before adding here - take a look at OPTION_MPTCP in include/net/mptcp.h */ - - static void smc_options_write(__be32 *ptr, u16 *options) - { -@@ -417,17 +426,6 @@ - #endif - } - --struct tcp_out_options { -- u16 options; /* bit field of OPTION_* */ -- u16 mss; /* 0 to disable */ -- u8 ws; /* window scale, 0 to disable */ -- u8 num_sack_blocks; /* number of SACK blocks to include */ -- u8 hash_size; /* bytes in hash_location */ -- __u8 *hash_location; /* temporary pointer, overloaded */ -- __u32 tsval, tsecr; /* need to include OPTION_TS */ -- struct tcp_fastopen_cookie *fastopen_cookie; /* Fast open cookie */ --}; -- - /* Write previously computed TCP options to the packet. - * - * Beware: Something in the Internet is very sensitive to the ordering of -@@ -442,7 +440,7 @@ - * (but it may well be that other scenarios fail similarly). - */ - static void tcp_options_write(__be32 *ptr, struct tcp_sock *tp, -- struct tcp_out_options *opts) -+ struct tcp_out_options *opts, struct sk_buff *skb) - { - u16 options = opts->options; /* mungable copy */ - -@@ -536,6 +534,9 @@ - } - - smc_options_write(ptr, &options); -+ -+ if (unlikely(OPTION_MPTCP & opts->options)) -+ mptcp_options_write(ptr, tp, opts, skb); - } - - static void smc_set_option(const struct tcp_sock *tp, -@@ -621,6 +622,8 @@ - if (unlikely(!(OPTION_TS & opts->options))) - remaining -= TCPOLEN_SACKPERM_ALIGNED; - } -+ if (tp->request_mptcp || mptcp(tp)) -+ mptcp_syn_options(sk, opts, &remaining); - - if (fastopen && fastopen->cookie.len >= 0) { - u32 need = fastopen->cookie.len; -@@ -702,6 +705,9 @@ - - smc_set_option_cond(tcp_sk(sk), ireq, opts, &remaining); - -+ if (ireq->saw_mpc) -+ mptcp_synack_options(req, opts, &remaining); -+ - return MAX_TCP_OPTION_SPACE - remaining; - } - -@@ -735,6 +741,8 @@ - opts->tsecr = tp->rx_opt.ts_recent; - size += TCPOLEN_TSTAMP_ALIGNED; - } -+ if (mptcp(tp)) -+ mptcp_established_options(sk, skb, opts, &size); - - eff_sacks = tp->rx_opt.num_sacks + tp->rx_opt.dsack; - if (unlikely(eff_sacks)) { -@@ -785,19 +793,31 @@ - tcp_xmit_retransmit_queue(sk); - } - -- tcp_write_xmit(sk, tcp_current_mss(sk), tp->nonagle, -- 0, GFP_ATOMIC); -+ tcp_sk(sk)->ops->write_xmit(sk, tcp_current_mss(sk), -+ tcp_sk(sk)->nonagle, 0, GFP_ATOMIC); - } - } - - static void tcp_tsq_handler(struct sock *sk) - { -- bh_lock_sock(sk); -- if (!sock_owned_by_user(sk)) -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct sock *meta_sk = mptcp(tp) ? mptcp_meta_sk(sk) : sk; -+ -+ bh_lock_sock(meta_sk); -+ if (!sock_owned_by_user(meta_sk)) { - tcp_tsq_write(sk); -- else if (!test_and_set_bit(TCP_TSQ_DEFERRED, &sk->sk_tsq_flags)) -- sock_hold(sk); -- bh_unlock_sock(sk); -+ -+ if (mptcp(tp)) -+ tcp_tsq_write(meta_sk); -+ } else { -+ if (!test_and_set_bit(TCP_TSQ_DEFERRED, &meta_sk->sk_tsq_flags)) -+ sock_hold(meta_sk); -+ -+ if ((mptcp(tp)) && (sk->sk_state != TCP_CLOSE)) -+ mptcp_tsq_flags(sk); -+ } -+ -+ bh_unlock_sock(meta_sk); - } - /* - * One tasklet per cpu tries to send more skbs. -@@ -834,7 +854,9 @@ - #define TCP_DEFERRED_ALL (TCPF_TSQ_DEFERRED | \ - TCPF_WRITE_TIMER_DEFERRED | \ - TCPF_DELACK_TIMER_DEFERRED | \ -- TCPF_MTU_REDUCED_DEFERRED) -+ TCPF_MTU_REDUCED_DEFERRED | \ -+ TCPF_PATH_MANAGER_DEFERRED |\ -+ TCPF_SUB_DEFERRED) - /** - * tcp_release_cb - tcp release_sock() callback - * @sk: socket -@@ -857,6 +879,9 @@ - if (flags & TCPF_TSQ_DEFERRED) { - tcp_tsq_write(sk); - __sock_put(sk); -+ -+ if (mptcp(tcp_sk(sk))) -+ tcp_tsq_write(mptcp_meta_sk(sk)); - } - /* Here begins the tricky part : - * We are called from release_sock() with : -@@ -881,6 +906,13 @@ - inet_csk(sk)->icsk_af_ops->mtu_reduced(sk); - __sock_put(sk); - } -+ if (flags & TCPF_PATH_MANAGER_DEFERRED) { -+ if (tcp_sk(sk)->mpcb->pm_ops->release_sock) -+ tcp_sk(sk)->mpcb->pm_ops->release_sock(sk); -+ __sock_put(sk); -+ } -+ if (flags & TCPF_SUB_DEFERRED) -+ mptcp_tsq_sub_deferred(sk); - } - EXPORT_SYMBOL(tcp_release_cb); - -@@ -983,7 +1015,7 @@ - sock_hold(sk); - } - --static void tcp_update_skb_after_send(struct tcp_sock *tp, struct sk_buff *skb) -+void tcp_update_skb_after_send(struct tcp_sock *tp, struct sk_buff *skb) - { - skb->skb_mstamp = tp->tcp_mstamp; - list_move_tail(&skb->tcp_tsorted_anchor, &tp->tsorted_sent_queue); -@@ -1095,10 +1127,10 @@ - } - } - -- tcp_options_write((__be32 *)(th + 1), tp, &opts); -+ tcp_options_write((__be32 *)(th + 1), tp, &opts, skb); - skb_shinfo(skb)->gso_type = sk->sk_gso_type; - if (likely(!(tcb->tcp_flags & TCPHDR_SYN))) { -- th->window = htons(tcp_select_window(sk)); -+ th->window = htons(tp->ops->select_window(sk)); - tcp_ecn_send(sk, skb, th, tcp_header_size); - } else { - /* RFC1323: The window in SYN & SYN/ACK segments -@@ -1156,8 +1188,8 @@ - return err; - } - --static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it, -- gfp_t gfp_mask) -+int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it, -+ gfp_t gfp_mask) - { - return __tcp_transmit_skb(sk, skb, clone_it, gfp_mask, - tcp_sk(sk)->rcv_nxt); -@@ -1168,7 +1200,7 @@ - * NOTE: probe0 timer is not checked, do not forget tcp_push_pending_frames, - * otherwise socket can stall. - */ --static void tcp_queue_skb(struct sock *sk, struct sk_buff *skb) -+void tcp_queue_skb(struct sock *sk, struct sk_buff *skb) - { - struct tcp_sock *tp = tcp_sk(sk); - -@@ -1181,7 +1213,7 @@ - } - - /* Initialize TSO segments for a packet. */ --static void tcp_set_skb_tso_segs(struct sk_buff *skb, unsigned int mss_now) -+void tcp_set_skb_tso_segs(struct sk_buff *skb, unsigned int mss_now) - { - if (skb->len <= mss_now) { - /* Avoid the costly divide in the normal -@@ -1198,7 +1230,7 @@ - /* Pcount in the middle of the write queue got changed, we need to do various - * tweaks to fix counters - */ --static void tcp_adjust_pcount(struct sock *sk, const struct sk_buff *skb, int decr) -+void tcp_adjust_pcount(struct sock *sk, const struct sk_buff *skb, int decr) - { - struct tcp_sock *tp = tcp_sk(sk); - -@@ -1366,7 +1398,7 @@ - /* This is similar to __pskb_pull_tail(). The difference is that pulled - * data is not copied, but immediately discarded. - */ --static int __pskb_trim_head(struct sk_buff *skb, int len) -+int __pskb_trim_head(struct sk_buff *skb, int len) - { - struct skb_shared_info *shinfo; - int i, k, eat; -@@ -1588,6 +1620,7 @@ - - return mss_now; - } -+EXPORT_SYMBOL(tcp_current_mss); - - /* RFC2861, slow part. Adjust cwnd, after it was not full during one rto. - * As additional protections, we do not touch cwnd in retransmission phases, -@@ -1611,7 +1644,7 @@ - tp->snd_cwnd_stamp = tcp_jiffies32; - } - --static void tcp_cwnd_validate(struct sock *sk, bool is_cwnd_limited) -+void tcp_cwnd_validate(struct sock *sk, bool is_cwnd_limited) - { - const struct tcp_congestion_ops *ca_ops = inet_csk(sk)->icsk_ca_ops; - struct tcp_sock *tp = tcp_sk(sk); -@@ -1669,8 +1702,8 @@ - * But we can avoid doing the divide again given we already have - * skb_pcount = skb->len / mss_now - */ --static void tcp_minshall_update(struct tcp_sock *tp, unsigned int mss_now, -- const struct sk_buff *skb) -+void tcp_minshall_update(struct tcp_sock *tp, unsigned int mss_now, -+ const struct sk_buff *skb) - { - if (skb->len < tcp_skb_pcount(skb) * mss_now) - tp->snd_sml = TCP_SKB_CB(skb)->end_seq; -@@ -1729,11 +1762,11 @@ - } - - /* Returns the portion of skb which can be sent right away */ --static unsigned int tcp_mss_split_point(const struct sock *sk, -- const struct sk_buff *skb, -- unsigned int mss_now, -- unsigned int max_segs, -- int nonagle) -+unsigned int tcp_mss_split_point(const struct sock *sk, -+ const struct sk_buff *skb, -+ unsigned int mss_now, -+ unsigned int max_segs, -+ int nonagle) - { - const struct tcp_sock *tp = tcp_sk(sk); - u32 partial, needed, window, max_len; -@@ -1763,13 +1796,14 @@ - /* Can at least one segment of SKB be sent right now, according to the - * congestion window rules? If so, return how many segments are allowed. - */ --static inline unsigned int tcp_cwnd_test(const struct tcp_sock *tp, -- const struct sk_buff *skb) -+unsigned int tcp_cwnd_test(const struct tcp_sock *tp, -+ const struct sk_buff *skb) - { - u32 in_flight, cwnd, halfcwnd; - - /* Don't be strict about the congestion window for the final FIN. */ -- if ((TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN) && -+ if (skb && -+ (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN) && - tcp_skb_pcount(skb) == 1) - return 1; - -@@ -1784,12 +1818,13 @@ - halfcwnd = max(cwnd >> 1, 1U); - return min(halfcwnd, cwnd - in_flight); - } -+EXPORT_SYMBOL(tcp_cwnd_test); - - /* Initialize TSO state of a skb. - * This must be invoked the first time we consider transmitting - * SKB onto the wire. - */ --static int tcp_init_tso_segs(struct sk_buff *skb, unsigned int mss_now) -+int tcp_init_tso_segs(struct sk_buff *skb, unsigned int mss_now) - { - int tso_segs = tcp_skb_pcount(skb); - -@@ -1804,8 +1839,8 @@ - /* Return true if the Nagle test allows this packet to be - * sent now. - */ --static inline bool tcp_nagle_test(const struct tcp_sock *tp, const struct sk_buff *skb, -- unsigned int cur_mss, int nonagle) -+bool tcp_nagle_test(const struct tcp_sock *tp, const struct sk_buff *skb, -+ unsigned int cur_mss, int nonagle) - { - /* Nagle rule does not apply to frames, which sit in the middle of the - * write_queue (they have no chances to get new data). -@@ -1817,7 +1852,8 @@ - return true; - - /* Don't use the nagle rule for urgent data (or for the final FIN). */ -- if (tcp_urg_mode(tp) || (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN)) -+ if (tcp_urg_mode(tp) || (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN) || -+ mptcp_is_data_fin(skb)) - return true; - - if (!tcp_nagle_check(skb->len < cur_mss, tp, nonagle)) -@@ -1827,9 +1863,8 @@ - } - - /* Does at least the first segment of SKB fit into the send window? */ --static bool tcp_snd_wnd_test(const struct tcp_sock *tp, -- const struct sk_buff *skb, -- unsigned int cur_mss) -+bool tcp_snd_wnd_test(const struct tcp_sock *tp, const struct sk_buff *skb, -+ unsigned int cur_mss) - { - u32 end_seq = TCP_SKB_CB(skb)->end_seq; - -@@ -1838,6 +1873,7 @@ - - return !after(end_seq, tcp_wnd_end(tp)); - } -+EXPORT_SYMBOL(tcp_snd_wnd_test); - - /* Trim TSO SKB to LEN bytes, put the remaining data into a new packet - * which is put after SKB on the list. It is very much like -@@ -1990,7 +2026,7 @@ - } - - /* If this packet won't get more data, do not wait. */ -- if (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN) -+ if ((TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN) || mptcp_is_data_fin(skb)) - goto send_now; - - return true; -@@ -2294,7 +2330,7 @@ - * Returns true, if no segments are in flight and we have queued segments, - * but cannot send anything now because of SWS or another problem. - */ --static bool tcp_write_xmit(struct sock *sk, unsigned int mss_now, int nonagle, -+bool tcp_write_xmit(struct sock *sk, unsigned int mss_now, int nonagle, - int push_one, gfp_t gfp) - { - struct tcp_sock *tp = tcp_sk(sk); -@@ -2308,7 +2344,12 @@ - sent_pkts = 0; - - tcp_mstamp_refresh(tp); -- if (!push_one) { -+ -+ /* pmtu not yet supported with MPTCP. Should be possible, by early -+ * exiting the loop inside tcp_mtu_probe, making sure that only one -+ * single DSS-mapping gets probed. -+ */ -+ if (!push_one && !mptcp(tp)) { - /* Do MTU probing. */ - result = tcp_mtu_probe(sk); - if (!result) { -@@ -2413,7 +2454,8 @@ - if (push_one != 2) - tcp_schedule_loss_probe(sk, false); - is_cwnd_limited |= (tcp_packets_in_flight(tp) >= tp->snd_cwnd); -- tcp_cwnd_validate(sk, is_cwnd_limited); -+ if (tp->ops->cwnd_validate) -+ tp->ops->cwnd_validate(sk, is_cwnd_limited); - return false; - } - return !tp->packets_out && !tcp_write_queue_empty(sk); -@@ -2496,7 +2538,7 @@ - skb = tcp_send_head(sk); - if (skb && tcp_snd_wnd_test(tp, skb, mss)) { - pcount = tp->packets_out; -- tcp_write_xmit(sk, mss, TCP_NAGLE_OFF, 2, GFP_ATOMIC); -+ tp->ops->write_xmit(sk, mss, TCP_NAGLE_OFF, 2, GFP_ATOMIC); - if (tp->packets_out > pcount) - goto probe_sent; - goto rearm_timer; -@@ -2560,8 +2602,8 @@ - if (unlikely(sk->sk_state == TCP_CLOSE)) - return; - -- if (tcp_write_xmit(sk, cur_mss, nonagle, 0, -- sk_gfp_mask(sk, GFP_ATOMIC))) -+ if (tcp_sk(sk)->ops->write_xmit(sk, cur_mss, nonagle, 0, -+ sk_gfp_mask(sk, GFP_ATOMIC))) - tcp_check_probe_timer(sk); - } - -@@ -2574,7 +2616,8 @@ - - BUG_ON(!skb || skb->len < mss_now); - -- tcp_write_xmit(sk, mss_now, TCP_NAGLE_PUSH, 1, sk->sk_allocation); -+ tcp_sk(sk)->ops->write_xmit(sk, mss_now, TCP_NAGLE_PUSH, 1, -+ sk->sk_allocation); - } - - /* This function returns the amount that we can raise the -@@ -2796,6 +2839,10 @@ - if (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_SYN) - return; - -+ /* Currently not supported for MPTCP - but it should be possible */ -+ if (mptcp(tp)) -+ return; -+ - skb_rbtree_walk_from_safe(skb, tmp) { - if (!tcp_can_collapse(sk, skb)) - break; -@@ -3266,7 +3313,7 @@ - - /* RFC1323: The window in SYN & SYN/ACK segments is never scaled. */ - th->window = htons(min(req->rsk_rcv_wnd, 65535U)); -- tcp_options_write((__be32 *)(th + 1), NULL, &opts); -+ tcp_options_write((__be32 *)(th + 1), NULL, &opts, skb); - th->doff = (tcp_header_size >> 2); - __TCP_INC_STATS(sock_net(sk), TCP_MIB_OUTSEGS); - -@@ -3347,13 +3394,13 @@ - if (rcv_wnd == 0) - rcv_wnd = dst_metric(dst, RTAX_INITRWND); - -- tcp_select_initial_window(sk, tcp_full_space(sk), -- tp->advmss - (tp->rx_opt.ts_recent_stamp ? tp->tcp_header_len - sizeof(struct tcphdr) : 0), -- &tp->rcv_wnd, -- &tp->window_clamp, -- sock_net(sk)->ipv4.sysctl_tcp_window_scaling, -- &rcv_wscale, -- rcv_wnd); -+ tp->ops->select_initial_window(sk, tcp_full_space(sk), -+ tp->advmss - (tp->rx_opt.ts_recent_stamp ? tp->tcp_header_len - sizeof(struct tcphdr) : 0), -+ &tp->rcv_wnd, -+ &tp->window_clamp, -+ sock_net(sk)->ipv4.sysctl_tcp_window_scaling, -+ &rcv_wscale, -+ rcv_wnd); - - tp->rx_opt.rcv_wscale = rcv_wscale; - tp->rcv_ssthresh = tp->rcv_wnd; -@@ -3378,6 +3425,36 @@ - inet_csk(sk)->icsk_rto = tcp_timeout_init(sk); - inet_csk(sk)->icsk_retransmits = 0; - tcp_clear_retrans(tp); -+ -+#ifdef CONFIG_MPTCP -+ if (sock_flag(sk, SOCK_MPTCP) && mptcp_doit(sk)) { -+ if (is_master_tp(tp)) { -+ tp->request_mptcp = 1; -+ mptcp_connect_init(sk); -+ } else if (tp->mptcp) { -+ struct inet_sock *inet = inet_sk(sk); -+ -+ tp->mptcp->snt_isn = tp->write_seq; -+ tp->mptcp->init_rcv_wnd = tp->rcv_wnd; -+ -+ /* Set nonce for new subflows */ -+ if (sk->sk_family == AF_INET) -+ tp->mptcp->mptcp_loc_nonce = mptcp_v4_get_nonce( -+ inet->inet_saddr, -+ inet->inet_daddr, -+ inet->inet_sport, -+ inet->inet_dport); -+#if IS_ENABLED(CONFIG_IPV6) -+ else -+ tp->mptcp->mptcp_loc_nonce = mptcp_v6_get_nonce( -+ inet6_sk(sk)->saddr.s6_addr32, -+ sk->sk_v6_daddr.s6_addr32, -+ inet->inet_sport, -+ inet->inet_dport); -+#endif -+ } -+ } -+#endif - } - - static void tcp_connect_queue_skb(struct sock *sk, struct sk_buff *skb) -@@ -3640,6 +3717,7 @@ - { - __tcp_send_ack(sk, tcp_sk(sk)->rcv_nxt); - } -+EXPORT_SYMBOL_GPL(tcp_send_ack); - - /* This routine sends a packet with an out of date sequence - * number. It assumes the other end will try to ack it. -@@ -3652,7 +3730,7 @@ - * one is with SEG.SEQ=SND.UNA to deliver urgent pointer, another is - * out-of-date with SND.UNA-1 to probe window. - */ --static int tcp_xmit_probe_skb(struct sock *sk, int urgent, int mib) -+int tcp_xmit_probe_skb(struct sock *sk, int urgent, int mib) - { - struct tcp_sock *tp = tcp_sk(sk); - struct sk_buff *skb; -@@ -3739,7 +3817,7 @@ - unsigned long probe_max; - int err; - -- err = tcp_write_wakeup(sk, LINUX_MIB_TCPWINPROBE); -+ err = tp->ops->write_wakeup(sk, LINUX_MIB_TCPWINPROBE); - - if (tp->packets_out || tcp_write_queue_empty(sk)) { - /* Cancel probe timer, if it is not required. */ -diff -aurN linux-4.19.104/net/ipv4/tcp_timer.c mptcp-mptcp_v0.95/net/ipv4/tcp_timer.c ---- linux-4.19.104/net/ipv4/tcp_timer.c 2020-02-14 22:33:28.000000000 +0100 -+++ mptcp-mptcp_v0.95/net/ipv4/tcp_timer.c 2020-02-17 11:29:55.000000000 +0100 -@@ -20,6 +20,7 @@ - - #include - #include -+#include - #include - - static u32 tcp_retransmit_stamp(const struct sock *sk) -@@ -58,7 +59,7 @@ - * Returns: Nothing (void) - */ - --static void tcp_write_err(struct sock *sk) -+void tcp_write_err(struct sock *sk) - { - sk->sk_err = sk->sk_err_soft ? : ETIMEDOUT; - sk->sk_error_report(sk); -@@ -114,7 +115,7 @@ - (!tp->snd_wnd && !tp->packets_out)) - do_reset = true; - if (do_reset) -- tcp_send_active_reset(sk, GFP_ATOMIC); -+ tp->ops->send_active_reset(sk, GFP_ATOMIC); - tcp_done(sk); - __NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPABORTONMEMORY); - return 1; -@@ -186,9 +187,9 @@ - * after "boundary" unsuccessful, exponentially backed-off - * retransmissions with an initial RTO of TCP_RTO_MIN. - */ --static bool retransmits_timed_out(struct sock *sk, -- unsigned int boundary, -- unsigned int timeout) -+bool retransmits_timed_out(struct sock *sk, -+ unsigned int boundary, -+ unsigned int timeout) - { - const unsigned int rto_base = TCP_RTO_MIN; - unsigned int linear_backoff_thresh, start_ts; -@@ -214,7 +215,7 @@ - } - - /* A write timeout has occurred. Process the after effects. */ --static int tcp_write_timeout(struct sock *sk) -+int tcp_write_timeout(struct sock *sk) - { - struct inet_connection_sock *icsk = inet_csk(sk); - struct tcp_sock *tp = tcp_sk(sk); -@@ -229,6 +230,17 @@ - sk_rethink_txhash(sk); - } - retry_until = icsk->icsk_syn_retries ? : net->ipv4.sysctl_tcp_syn_retries; -+ -+#ifdef CONFIG_MPTCP -+ /* Stop retransmitting MP_CAPABLE options in SYN if timed out. */ -+ if (tcp_sk(sk)->request_mptcp && -+ icsk->icsk_retransmits >= sysctl_mptcp_syn_retries) { -+ tcp_sk(sk)->request_mptcp = 0; -+ -+ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_MPCAPABLERETRANSFALLBACK); -+ } -+#endif /* CONFIG_MPTCP */ -+ - expired = icsk->icsk_retransmits >= retry_until; - } else { - if (retransmits_timed_out(sk, net->ipv4.sysctl_tcp_retries1, 0)) { -@@ -324,18 +336,22 @@ - struct inet_connection_sock *icsk = - from_timer(icsk, t, icsk_delack_timer); - struct sock *sk = &icsk->icsk_inet.sk; -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct sock *meta_sk = mptcp(tp) ? mptcp_meta_sk(sk) : sk; - -- bh_lock_sock(sk); -- if (!sock_owned_by_user(sk)) { -+ bh_lock_sock(meta_sk); -+ if (!sock_owned_by_user(meta_sk)) { - tcp_delack_timer_handler(sk); - } else { - icsk->icsk_ack.blocked = 1; -- __NET_INC_STATS(sock_net(sk), LINUX_MIB_DELAYEDACKLOCKED); -+ __NET_INC_STATS(sock_net(meta_sk), LINUX_MIB_DELAYEDACKLOCKED); - /* deleguate our work to tcp_release_cb() */ - if (!test_and_set_bit(TCP_DELACK_TIMER_DEFERRED, &sk->sk_tsq_flags)) - sock_hold(sk); -+ if (mptcp(tp)) -+ mptcp_tsq_flags(sk); - } -- bh_unlock_sock(sk); -+ bh_unlock_sock(meta_sk); - sock_put(sk); - } - -@@ -380,6 +396,10 @@ - - if (icsk->icsk_probes_out >= max_probes) { - abort: tcp_write_err(sk); -+ if (is_meta_sk(sk) && -+ mptcp_in_infinite_mapping_weak(tp->mpcb)) { -+ mptcp_sub_force_close_all(tp->mpcb, NULL); -+ } - } else { - /* Only send another probe if we didn't close things up. */ - tcp_send_probe0(sk); -@@ -595,7 +615,7 @@ - break; - case ICSK_TIME_RETRANS: - icsk->icsk_pending = 0; -- tcp_retransmit_timer(sk); -+ tcp_sk(sk)->ops->retransmit_timer(sk); - break; - case ICSK_TIME_PROBE0: - icsk->icsk_pending = 0; -@@ -612,16 +632,19 @@ - struct inet_connection_sock *icsk = - from_timer(icsk, t, icsk_retransmit_timer); - struct sock *sk = &icsk->icsk_inet.sk; -+ struct sock *meta_sk = mptcp(tcp_sk(sk)) ? mptcp_meta_sk(sk) : sk; - -- bh_lock_sock(sk); -- if (!sock_owned_by_user(sk)) { -+ bh_lock_sock(meta_sk); -+ if (!sock_owned_by_user(meta_sk)) { - tcp_write_timer_handler(sk); - } else { - /* delegate our work to tcp_release_cb() */ - if (!test_and_set_bit(TCP_WRITE_TIMER_DEFERRED, &sk->sk_tsq_flags)) - sock_hold(sk); -+ if (mptcp(tcp_sk(sk))) -+ mptcp_tsq_flags(sk); - } -- bh_unlock_sock(sk); -+ bh_unlock_sock(meta_sk); - sock_put(sk); - } - -@@ -651,11 +674,12 @@ - struct sock *sk = from_timer(sk, t, sk_timer); - struct inet_connection_sock *icsk = inet_csk(sk); - struct tcp_sock *tp = tcp_sk(sk); -+ struct sock *meta_sk = mptcp(tp) ? mptcp_meta_sk(sk) : sk; - u32 elapsed; - - /* Only process if socket is not in use. */ -- bh_lock_sock(sk); -- if (sock_owned_by_user(sk)) { -+ bh_lock_sock(meta_sk); -+ if (sock_owned_by_user(meta_sk)) { - /* Try again later. */ - inet_csk_reset_keepalive_timer (sk, HZ/20); - goto out; -@@ -667,16 +691,31 @@ - } - - tcp_mstamp_refresh(tp); -+ -+ if (tp->send_mp_fclose) { -+ if (icsk->icsk_retransmits >= MPTCP_FASTCLOSE_RETRIES) { -+ tcp_write_err(sk); -+ goto out; -+ } -+ -+ tcp_send_ack(sk); -+ icsk->icsk_retransmits++; -+ -+ icsk->icsk_rto = min(icsk->icsk_rto << 1, TCP_RTO_MAX); -+ elapsed = icsk->icsk_rto; -+ goto resched; -+ } -+ - if (sk->sk_state == TCP_FIN_WAIT2 && sock_flag(sk, SOCK_DEAD)) { - if (tp->linger2 >= 0) { - const int tmo = tcp_fin_time(sk) - TCP_TIMEWAIT_LEN; - - if (tmo > 0) { -- tcp_time_wait(sk, TCP_FIN_WAIT2, tmo); -+ tp->ops->time_wait(sk, TCP_FIN_WAIT2, tmo); - goto out; - } - } -- tcp_send_active_reset(sk, GFP_ATOMIC); -+ tp->ops->send_active_reset(sk, GFP_ATOMIC); - goto death; - } - -@@ -701,11 +740,11 @@ - icsk->icsk_probes_out > 0) || - (icsk->icsk_user_timeout == 0 && - icsk->icsk_probes_out >= keepalive_probes(tp))) { -- tcp_send_active_reset(sk, GFP_ATOMIC); -+ tp->ops->send_active_reset(sk, GFP_ATOMIC); - tcp_write_err(sk); - goto out; - } -- if (tcp_write_wakeup(sk, LINUX_MIB_TCPKEEPALIVE) <= 0) { -+ if (tp->ops->write_wakeup(sk, LINUX_MIB_TCPKEEPALIVE) <= 0) { - icsk->icsk_probes_out++; - elapsed = keepalive_intvl_when(tp); - } else { -@@ -729,7 +768,7 @@ - tcp_done(sk); - - out: -- bh_unlock_sock(sk); -+ bh_unlock_sock(meta_sk); - sock_put(sk); - } - -diff -aurN linux-4.19.104/net/ipv6/addrconf.c mptcp-mptcp_v0.95/net/ipv6/addrconf.c ---- linux-4.19.104/net/ipv6/addrconf.c 2020-02-14 22:33:28.000000000 +0100 -+++ mptcp-mptcp_v0.95/net/ipv6/addrconf.c 2020-02-17 11:29:55.000000000 +0100 -@@ -917,6 +917,7 @@ - - kfree_rcu(ifp, rcu); - } -+EXPORT_SYMBOL(inet6_ifa_finish_destroy); - - static void - ipv6_link_dev_addr(struct inet6_dev *idev, struct inet6_ifaddr *ifp) -diff -aurN linux-4.19.104/net/ipv6/af_inet6.c mptcp-mptcp_v0.95/net/ipv6/af_inet6.c ---- linux-4.19.104/net/ipv6/af_inet6.c 2020-02-14 22:33:28.000000000 +0100 -+++ mptcp-mptcp_v0.95/net/ipv6/af_inet6.c 2020-02-17 11:29:55.000000000 +0100 -@@ -107,8 +107,7 @@ - return (struct ipv6_pinfo *)(((u8 *)sk) + offset); - } - --static int inet6_create(struct net *net, struct socket *sock, int protocol, -- int kern) -+int inet6_create(struct net *net, struct socket *sock, int protocol, int kern) - { - struct inet_sock *inet; - struct ipv6_pinfo *np; -diff -aurN linux-4.19.104/net/ipv6/ipv6_sockglue.c mptcp-mptcp_v0.95/net/ipv6/ipv6_sockglue.c ---- linux-4.19.104/net/ipv6/ipv6_sockglue.c 2020-02-14 22:33:28.000000000 +0100 -+++ mptcp-mptcp_v0.95/net/ipv6/ipv6_sockglue.c 2020-02-17 11:29:55.000000000 +0100 -@@ -48,6 +48,8 @@ - #include - #include - #include -+#include -+#include - #include - #include - #include -@@ -216,7 +218,12 @@ - sock_prot_inuse_add(net, &tcp_prot, 1); - local_bh_enable(); - sk->sk_prot = &tcp_prot; -- icsk->icsk_af_ops = &ipv4_specific; -+#ifdef CONFIG_MPTCP -+ if (sock_flag(sk, SOCK_MPTCP)) -+ icsk->icsk_af_ops = &mptcp_v4_specific; -+ else -+#endif -+ icsk->icsk_af_ops = &ipv4_specific; - sk->sk_socket->ops = &inet_stream_ops; - sk->sk_family = PF_INET; - tcp_sync_mss(sk, icsk->icsk_pmtu_cookie); -diff -aurN linux-4.19.104/net/ipv6/syncookies.c mptcp-mptcp_v0.95/net/ipv6/syncookies.c ---- linux-4.19.104/net/ipv6/syncookies.c 2020-02-14 22:33:28.000000000 +0100 -+++ mptcp-mptcp_v0.95/net/ipv6/syncookies.c 2020-02-17 11:29:55.000000000 +0100 -@@ -20,6 +20,8 @@ - #include - #include - #include -+#include -+#include - #include - - #define COOKIEBITS 24 /* Upper bits store count */ -@@ -111,7 +113,8 @@ - } - EXPORT_SYMBOL_GPL(__cookie_v6_init_sequence); - --__u32 cookie_v6_init_sequence(const struct sk_buff *skb, __u16 *mssp) -+__u32 cookie_v6_init_sequence(struct request_sock *req, const struct sock *sk, -+ const struct sk_buff *skb, __u16 *mssp) - { - const struct ipv6hdr *iph = ipv6_hdr(skb); - const struct tcphdr *th = tcp_hdr(skb); -@@ -133,6 +136,7 @@ - struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb) - { - struct tcp_options_received tcp_opt; -+ struct mptcp_options_received mopt; - struct inet_request_sock *ireq; - struct tcp_request_sock *treq; - struct ipv6_pinfo *np = inet6_sk(sk); -@@ -162,7 +166,8 @@ - - /* check for timestamp cookie support */ - memset(&tcp_opt, 0, sizeof(tcp_opt)); -- tcp_parse_options(sock_net(sk), skb, &tcp_opt, 0, NULL); -+ mptcp_init_mp_opt(&mopt); -+ tcp_parse_options(sock_net(sk), skb, &tcp_opt, &mopt, 0, NULL, NULL); - - if (tcp_opt.saw_tstamp && tcp_opt.rcv_tsecr) { - tsoff = secure_tcpv6_ts_off(sock_net(sk), -@@ -175,14 +180,27 @@ - goto out; - - ret = NULL; -- req = inet_reqsk_alloc(&tcp6_request_sock_ops, sk, false); -+#ifdef CONFIG_MPTCP -+ if (mopt.saw_mpc) -+ req = inet_reqsk_alloc(&mptcp6_request_sock_ops, sk, false); -+ else -+#endif -+ req = inet_reqsk_alloc(&tcp6_request_sock_ops, sk, false); - if (!req) - goto out; - - ireq = inet_rsk(req); -+ ireq->mptcp_rqsk = 0; -+ ireq->saw_mpc = 0; - treq = tcp_rsk(req); - treq->tfo_listener = false; - -+ /* Must be done before anything else, as it initializes -+ * hash_entry of the MPTCP request-sock. -+ */ -+ if (mopt.saw_mpc) -+ mptcp_cookies_reqsk_init(req, &mopt, skb); -+ - if (security_inet_conn_request(sk, skb, req)) - goto out_free; - -@@ -246,10 +264,10 @@ - } - - req->rsk_window_clamp = tp->window_clamp ? :dst_metric(dst, RTAX_WINDOW); -- tcp_select_initial_window(sk, tcp_full_space(sk), req->mss, -- &req->rsk_rcv_wnd, &req->rsk_window_clamp, -- ireq->wscale_ok, &rcv_wscale, -- dst_metric(dst, RTAX_INITRWND)); -+ tp->ops->select_initial_window(sk, tcp_full_space(sk), req->mss, -+ &req->rsk_rcv_wnd, &req->rsk_window_clamp, -+ ireq->wscale_ok, &rcv_wscale, -+ dst_metric(dst, RTAX_INITRWND)); - - ireq->rcv_wscale = rcv_wscale; - ireq->ecn_ok = cookie_ecn_ok(&tcp_opt, sock_net(sk), dst); -diff -aurN linux-4.19.104/net/ipv6/tcp_ipv6.c mptcp-mptcp_v0.95/net/ipv6/tcp_ipv6.c ---- linux-4.19.104/net/ipv6/tcp_ipv6.c 2020-02-14 22:33:28.000000000 +0100 -+++ mptcp-mptcp_v0.95/net/ipv6/tcp_ipv6.c 2020-02-17 11:29:55.000000000 +0100 -@@ -61,6 +61,8 @@ - #include - #include - #include -+#include -+#include - #include - - #include -@@ -70,15 +72,6 @@ - #include - - #include -- --static void tcp_v6_send_reset(const struct sock *sk, struct sk_buff *skb); --static void tcp_v6_reqsk_send_ack(const struct sock *sk, struct sk_buff *skb, -- struct request_sock *req); -- --static int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb); -- --static const struct inet_connection_sock_af_ops ipv6_mapped; --static const struct inet_connection_sock_af_ops ipv6_specific; - #ifdef CONFIG_TCP_MD5SIG - static const struct tcp_sock_af_ops tcp_sock_ipv6_specific; - static const struct tcp_sock_af_ops tcp_sock_ipv6_mapped_specific; -@@ -90,7 +83,7 @@ - } - #endif - --static void inet6_sk_rx_dst_set(struct sock *sk, const struct sk_buff *skb) -+void inet6_sk_rx_dst_set(struct sock *sk, const struct sk_buff *skb) - { - struct dst_entry *dst = skb_dst(skb); - -@@ -132,7 +125,7 @@ - return BPF_CGROUP_RUN_PROG_INET6_CONNECT(sk, uaddr); - } - --static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr, -+int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr, - int addr_len) - { - struct sockaddr_in6 *usin = (struct sockaddr_in6 *) uaddr; -@@ -229,7 +222,12 @@ - sin.sin_port = usin->sin6_port; - sin.sin_addr.s_addr = usin->sin6_addr.s6_addr32[3]; - -- icsk->icsk_af_ops = &ipv6_mapped; -+#ifdef CONFIG_MPTCP -+ if (sock_flag(sk, SOCK_MPTCP)) -+ icsk->icsk_af_ops = &mptcp_v6_mapped; -+ else -+#endif -+ icsk->icsk_af_ops = &ipv6_mapped; - sk->sk_backlog_rcv = tcp_v4_do_rcv; - #ifdef CONFIG_TCP_MD5SIG - tp->af_specific = &tcp_sock_ipv6_mapped_specific; -@@ -239,7 +237,12 @@ - - if (err) { - icsk->icsk_ext_hdr_len = exthdrlen; -- icsk->icsk_af_ops = &ipv6_specific; -+#ifdef CONFIG_MPTCP -+ if (sock_flag(sk, SOCK_MPTCP)) -+ icsk->icsk_af_ops = &mptcp_v6_specific; -+ else -+#endif -+ icsk->icsk_af_ops = &ipv6_specific; - sk->sk_backlog_rcv = tcp_v6_do_rcv; - #ifdef CONFIG_TCP_MD5SIG - tp->af_specific = &tcp_sock_ipv6_specific; -@@ -332,7 +335,7 @@ - return err; - } - --static void tcp_v6_mtu_reduced(struct sock *sk) -+void tcp_v6_mtu_reduced(struct sock *sk) - { - struct dst_entry *dst; - -@@ -359,7 +362,7 @@ - struct ipv6_pinfo *np; - struct tcp_sock *tp; - __u32 seq, snd_una; -- struct sock *sk; -+ struct sock *sk, *meta_sk; - bool fatal; - int err; - -@@ -383,8 +386,14 @@ - if (sk->sk_state == TCP_NEW_SYN_RECV) - return tcp_req_err(sk, seq, fatal); - -- bh_lock_sock(sk); -- if (sock_owned_by_user(sk) && type != ICMPV6_PKT_TOOBIG) -+ tp = tcp_sk(sk); -+ if (mptcp(tp)) -+ meta_sk = mptcp_meta_sk(sk); -+ else -+ meta_sk = sk; -+ -+ bh_lock_sock(meta_sk); -+ if (sock_owned_by_user(meta_sk) && type != ICMPV6_PKT_TOOBIG) - __NET_INC_STATS(net, LINUX_MIB_LOCKDROPPEDICMPS); - - if (sk->sk_state == TCP_CLOSE) -@@ -395,7 +404,6 @@ - goto out; - } - -- tp = tcp_sk(sk); - /* XXX (TFO) - tp->snd_una should be ISN (tcp_create_openreq_child() */ - fastopen = tp->fastopen_rsk; - snd_una = fastopen ? tcp_rsk(fastopen)->snt_isn : tp->snd_una; -@@ -429,11 +437,15 @@ - goto out; - - tp->mtu_info = ntohl(info); -- if (!sock_owned_by_user(sk)) -+ if (!sock_owned_by_user(meta_sk)) { - tcp_v6_mtu_reduced(sk); -- else if (!test_and_set_bit(TCP_MTU_REDUCED_DEFERRED, -- &sk->sk_tsq_flags)) -- sock_hold(sk); -+ } else { -+ if (!test_and_set_bit(TCP_MTU_REDUCED_DEFERRED, -+ &sk->sk_tsq_flags)) -+ sock_hold(sk); -+ if (mptcp(tp)) -+ mptcp_tsq_flags(sk); -+ } - goto out; - } - -@@ -448,7 +460,7 @@ - if (fastopen && !fastopen->sk) - break; - -- if (!sock_owned_by_user(sk)) { -+ if (!sock_owned_by_user(meta_sk)) { - sk->sk_err = err; - sk->sk_error_report(sk); /* Wake people up to see the error (see connect in sock.c) */ - -@@ -458,14 +470,14 @@ - goto out; - } - -- if (!sock_owned_by_user(sk) && np->recverr) { -+ if (!sock_owned_by_user(meta_sk) && np->recverr) { - sk->sk_err = err; - sk->sk_error_report(sk); - } else - sk->sk_err_soft = err; - - out: -- bh_unlock_sock(sk); -+ bh_unlock_sock(meta_sk); - sock_put(sk); - } - -@@ -511,8 +523,7 @@ - return err; - } - -- --static void tcp_v6_reqsk_destructor(struct request_sock *req) -+void tcp_v6_reqsk_destructor(struct request_sock *req) - { - kfree(inet_rsk(req)->ipv6_opt); - kfree_skb(inet_rsk(req)->pktopts); -@@ -730,9 +741,10 @@ - return false; - } - --static void tcp_v6_init_req(struct request_sock *req, -- const struct sock *sk_listener, -- struct sk_buff *skb) -+static int tcp_v6_init_req(struct request_sock *req, -+ const struct sock *sk_listener, -+ struct sk_buff *skb, -+ bool want_cookie) - { - bool l3_slave = ipv6_l3mdev_skb(TCP_SKB_CB(skb)->header.h6.flags); - struct inet_request_sock *ireq = inet_rsk(req); -@@ -754,6 +766,8 @@ - refcount_inc(&skb->users); - ireq->pktopts = skb; - } -+ -+ return 0; - } - - static struct dst_entry *tcp_v6_route_req(const struct sock *sk, -@@ -773,7 +787,7 @@ - .syn_ack_timeout = tcp_syn_ack_timeout, - }; - --static const struct tcp_request_sock_ops tcp_request_sock_ipv6_ops = { -+const struct tcp_request_sock_ops tcp_request_sock_ipv6_ops = { - .mss_clamp = IPV6_MIN_MTU - sizeof(struct tcphdr) - - sizeof(struct ipv6hdr), - #ifdef CONFIG_TCP_MD5SIG -@@ -791,9 +805,9 @@ - }; - - static void tcp_v6_send_response(const struct sock *sk, struct sk_buff *skb, u32 seq, -- u32 ack, u32 win, u32 tsval, u32 tsecr, -+ u32 ack, u32 data_ack, u32 win, u32 tsval, u32 tsecr, - int oif, struct tcp_md5sig_key *key, int rst, -- u8 tclass, __be32 label) -+ u8 tclass, __be32 label, int mptcp) - { - const struct tcphdr *th = tcp_hdr(skb); - struct tcphdr *t1; -@@ -812,7 +826,10 @@ - if (key) - tot_len += TCPOLEN_MD5SIG_ALIGNED; - #endif -- -+#ifdef CONFIG_MPTCP -+ if (mptcp) -+ tot_len += MPTCP_SUB_LEN_DSS + MPTCP_SUB_LEN_ACK; -+#endif - buff = alloc_skb(MAX_HEADER + sizeof(struct ipv6hdr) + tot_len, - GFP_ATOMIC); - if (!buff) -@@ -850,6 +867,17 @@ - tcp_v6_md5_hash_hdr((__u8 *)topt, key, - &ipv6_hdr(skb)->saddr, - &ipv6_hdr(skb)->daddr, t1); -+ topt += 4; -+ } -+#endif -+#ifdef CONFIG_MPTCP -+ if (mptcp) { -+ /* Construction of 32-bit data_ack */ -+ *topt++ = htonl((TCPOPT_MPTCP << 24) | -+ ((MPTCP_SUB_LEN_DSS + MPTCP_SUB_LEN_ACK) << 16) | -+ (0x20 << 8) | -+ (0x01)); -+ *topt++ = htonl(data_ack); - } - #endif - -@@ -899,7 +927,7 @@ - kfree_skb(buff); - } - --static void tcp_v6_send_reset(const struct sock *sk, struct sk_buff *skb) -+void tcp_v6_send_reset(const struct sock *sk, struct sk_buff *skb) - { - const struct tcphdr *th = tcp_hdr(skb); - u32 seq = 0, ack_seq = 0; -@@ -967,7 +995,7 @@ - trace_tcp_send_reset(sk, skb); - } - -- tcp_v6_send_response(sk, skb, seq, ack_seq, 0, 0, 0, oif, key, 1, 0, 0); -+ tcp_v6_send_response(sk, skb, seq, ack_seq, 0, 0, 0, 0, oif, key, 1, 0, 0, 0); - - #ifdef CONFIG_TCP_MD5SIG - out: -@@ -976,30 +1004,37 @@ - } - - static void tcp_v6_send_ack(const struct sock *sk, struct sk_buff *skb, u32 seq, -- u32 ack, u32 win, u32 tsval, u32 tsecr, int oif, -+ u32 ack, u32 data_ack, u32 win, u32 tsval, u32 tsecr, int oif, - struct tcp_md5sig_key *key, u8 tclass, -- __be32 label) -+ __be32 label, int mptcp) - { -- tcp_v6_send_response(sk, skb, seq, ack, win, tsval, tsecr, oif, key, 0, -- tclass, label); -+ tcp_v6_send_response(sk, skb, seq, ack, data_ack, win, tsval, tsecr, oif, -+ key, 0, tclass, label, mptcp); - } - - static void tcp_v6_timewait_ack(struct sock *sk, struct sk_buff *skb) - { - struct inet_timewait_sock *tw = inet_twsk(sk); - struct tcp_timewait_sock *tcptw = tcp_twsk(sk); -+ u32 data_ack = 0; -+ int mptcp = 0; - -+ if (tcptw->mptcp_tw) { -+ data_ack = (u32)tcptw->mptcp_tw->rcv_nxt; -+ mptcp = 1; -+ } - tcp_v6_send_ack(sk, skb, tcptw->tw_snd_nxt, tcptw->tw_rcv_nxt, -+ data_ack, - tcptw->tw_rcv_wnd >> tw->tw_rcv_wscale, - tcp_time_stamp_raw() + tcptw->tw_ts_offset, - tcptw->tw_ts_recent, tw->tw_bound_dev_if, tcp_twsk_md5_key(tcptw), -- tw->tw_tclass, cpu_to_be32(tw->tw_flowlabel)); -+ tw->tw_tclass, cpu_to_be32(tw->tw_flowlabel), mptcp); - - inet_twsk_put(tw); - } - --static void tcp_v6_reqsk_send_ack(const struct sock *sk, struct sk_buff *skb, -- struct request_sock *req) -+void tcp_v6_reqsk_send_ack(const struct sock *sk, struct sk_buff *skb, -+ struct request_sock *req) - { - /* sk->sk_state == TCP_LISTEN -> for regular TCP_SYN_RECV - * sk->sk_state == TCP_SYN_RECV -> for Fast Open. -@@ -1009,18 +1044,18 @@ - * exception of segments, MUST be right-shifted by - * Rcv.Wind.Shift bits: - */ -- tcp_v6_send_ack(sk, skb, (sk->sk_state == TCP_LISTEN) ? -+ tcp_v6_send_ack(sk, skb, (sk->sk_state == TCP_LISTEN || is_meta_sk(sk)) ? - tcp_rsk(req)->snt_isn + 1 : tcp_sk(sk)->snd_nxt, -- tcp_rsk(req)->rcv_nxt, -+ tcp_rsk(req)->rcv_nxt, 0, - req->rsk_rcv_wnd >> inet_rsk(req)->rcv_wscale, - tcp_time_stamp_raw() + tcp_rsk(req)->ts_off, - req->ts_recent, sk->sk_bound_dev_if, - tcp_v6_md5_do_lookup(sk, &ipv6_hdr(skb)->saddr), -- 0, 0); -+ 0, 0, 0); - } - - --static struct sock *tcp_v6_cookie_check(struct sock *sk, struct sk_buff *skb) -+struct sock *tcp_v6_cookie_check(struct sock *sk, struct sk_buff *skb) - { - #ifdef CONFIG_SYN_COOKIES - const struct tcphdr *th = tcp_hdr(skb); -@@ -1031,7 +1066,7 @@ - return sk; - } - --static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb) -+int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb) - { - if (skb->protocol == htons(ETH_P_IP)) - return tcp_v4_conn_request(sk, skb); -@@ -1057,11 +1092,11 @@ - sizeof(struct inet6_skb_parm)); - } - --static struct sock *tcp_v6_syn_recv_sock(const struct sock *sk, struct sk_buff *skb, -- struct request_sock *req, -- struct dst_entry *dst, -- struct request_sock *req_unhash, -- bool *own_req) -+struct sock *tcp_v6_syn_recv_sock(const struct sock *sk, struct sk_buff *skb, -+ struct request_sock *req, -+ struct dst_entry *dst, -+ struct request_sock *req_unhash, -+ bool *own_req) - { - struct inet_request_sock *ireq; - struct ipv6_pinfo *newnp; -@@ -1098,7 +1133,15 @@ - - newnp->saddr = newsk->sk_v6_rcv_saddr; - -- inet_csk(newsk)->icsk_af_ops = &ipv6_mapped; -+#ifdef CONFIG_MPTCP -+ /* We must check on the request-socket because the listener -+ * socket's flag may have been changed halfway through. -+ */ -+ if (!inet_rsk(req)->saw_mpc) -+ inet_csk(newsk)->icsk_af_ops = &mptcp_v6_mapped; -+ else -+#endif -+ inet_csk(newsk)->icsk_af_ops = &ipv6_mapped; - newsk->sk_backlog_rcv = tcp_v4_do_rcv; - #ifdef CONFIG_TCP_MD5SIG - newtp->af_specific = &tcp_sock_ipv6_mapped_specific; -@@ -1145,6 +1188,14 @@ - if (!newsk) - goto out_nonewsk; - -+#ifdef CONFIG_MPTCP -+ /* If the meta_sk is v6-mapped we can end up here with the wrong af_ops. -+ * Just make sure that this subflow is v6. -+ */ -+ if (is_meta_sk(sk)) -+ inet_csk(newsk)->icsk_af_ops = &mptcp_v6_specific; -+#endif -+ - /* - * No need to charge this sock to the relevant IPv6 refcnt debug socks - * count here, tcp_create_openreq_child now does this for us, see the -@@ -1273,7 +1324,7 @@ - * This is because we cannot sleep with the original spinlock - * held. - */ --static int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb) -+int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb) - { - struct ipv6_pinfo *np = inet6_sk(sk); - struct tcp_sock *tp; -@@ -1290,6 +1341,9 @@ - if (skb->protocol == htons(ETH_P_IP)) - return tcp_v4_do_rcv(sk, skb); - -+ if (is_meta_sk(sk)) -+ return mptcp_v6_do_rcv(sk, skb); -+ - /* - * socket locking is here for SMP purposes as backlog rcv - * is currently called with bh processing disabled. -@@ -1417,6 +1471,10 @@ - TCP_SKB_CB(skb)->end_seq = (TCP_SKB_CB(skb)->seq + th->syn + th->fin + - skb->len - th->doff*4); - TCP_SKB_CB(skb)->ack_seq = ntohl(th->ack_seq); -+#ifdef CONFIG_MPTCP -+ TCP_SKB_CB(skb)->mptcp_flags = 0; -+ TCP_SKB_CB(skb)->dss_off = 0; -+#endif - TCP_SKB_CB(skb)->tcp_flags = tcp_flag_byte(th); - TCP_SKB_CB(skb)->tcp_tw_isn = 0; - TCP_SKB_CB(skb)->ip_dsfield = ipv6_get_dsfield(hdr); -@@ -1430,8 +1488,8 @@ - int sdif = inet6_sdif(skb); - const struct tcphdr *th; - const struct ipv6hdr *hdr; -+ struct sock *sk, *meta_sk = NULL; - bool refcounted; -- struct sock *sk; - int ret; - struct net *net = dev_net(skb->dev); - -@@ -1485,12 +1543,17 @@ - reqsk_put(req); - goto csum_error; - } -- if (unlikely(sk->sk_state != TCP_LISTEN)) { -+ if (unlikely(sk->sk_state != TCP_LISTEN && !is_meta_sk(sk))) { -+ inet_csk_reqsk_queue_drop_and_put(sk, req); -+ goto lookup; -+ } -+ if (unlikely(is_meta_sk(sk) && !mptcp_can_new_subflow(sk))) { - inet_csk_reqsk_queue_drop_and_put(sk, req); - goto lookup; - } - sock_hold(sk); - refcounted = true; -+ - nsk = NULL; - if (!tcp_filter(sk, skb)) { - th = (const struct tcphdr *)skb->data; -@@ -1523,6 +1586,7 @@ - return 0; - } - } -+ - if (hdr->hop_limit < inet6_sk(sk)->min_hopcount) { - __NET_INC_STATS(net, LINUX_MIB_TCPMINTTLDROP); - goto discard_and_relse; -@@ -1549,15 +1613,25 @@ - - sk_incoming_cpu_update(sk); - -- bh_lock_sock_nested(sk); -+ if (mptcp(tcp_sk(sk))) { -+ meta_sk = mptcp_meta_sk(sk); -+ -+ bh_lock_sock_nested(meta_sk); -+ if (sock_owned_by_user(meta_sk)) -+ mptcp_prepare_for_backlog(sk, skb); -+ } else { -+ meta_sk = sk; -+ bh_lock_sock_nested(sk); -+ } - tcp_segs_in(tcp_sk(sk), skb); - ret = 0; -- if (!sock_owned_by_user(sk)) { -+ if (!sock_owned_by_user(meta_sk)) { - ret = tcp_v6_do_rcv(sk, skb); -- } else if (tcp_add_backlog(sk, skb)) { -+ } else if (tcp_add_backlog(meta_sk, skb)) { - goto discard_and_relse; - } -- bh_unlock_sock(sk); -+ -+ bh_unlock_sock(meta_sk); - - put_and_return: - if (refcounted) -@@ -1570,6 +1644,19 @@ - - tcp_v6_fill_cb(skb, hdr, th); - -+#ifdef CONFIG_MPTCP -+ if (!sk && th->syn && !th->ack) { -+ int ret = mptcp_lookup_join(skb, NULL); -+ -+ if (ret < 0) { -+ tcp_v6_send_reset(NULL, skb); -+ goto discard_it; -+ } else if (ret > 0) { -+ return 0; -+ } -+ } -+#endif -+ - if (tcp_checksum_complete(skb)) { - csum_error: - __TCP_INC_STATS(net, TCP_MIB_CSUMERRORS); -@@ -1622,6 +1709,18 @@ - refcounted = false; - goto process; - } -+#ifdef CONFIG_MPTCP -+ if (th->syn && !th->ack) { -+ int ret = mptcp_lookup_join(skb, inet_twsk(sk)); -+ -+ if (ret < 0) { -+ tcp_v6_send_reset(NULL, skb); -+ goto discard_it; -+ } else if (ret > 0) { -+ return 0; -+ } -+ } -+#endif - } - /* to ACK */ - /* fall through */ -@@ -1676,13 +1775,13 @@ - } - } - --static struct timewait_sock_ops tcp6_timewait_sock_ops = { -+struct timewait_sock_ops tcp6_timewait_sock_ops = { - .twsk_obj_size = sizeof(struct tcp6_timewait_sock), - .twsk_unique = tcp_twsk_unique, - .twsk_destructor = tcp_twsk_destructor, - }; - --static const struct inet_connection_sock_af_ops ipv6_specific = { -+const struct inet_connection_sock_af_ops ipv6_specific = { - .queue_xmit = inet6_csk_xmit, - .send_check = tcp_v6_send_check, - .rebuild_header = inet6_sk_rebuild_header, -@@ -1713,7 +1812,7 @@ - /* - * TCP over IPv4 via INET6 API - */ --static const struct inet_connection_sock_af_ops ipv6_mapped = { -+const struct inet_connection_sock_af_ops ipv6_mapped = { - .queue_xmit = ip_queue_xmit, - .send_check = tcp_v4_send_check, - .rebuild_header = inet_sk_rebuild_header, -@@ -1749,7 +1848,12 @@ - - tcp_init_sock(sk); - -- icsk->icsk_af_ops = &ipv6_specific; -+#ifdef CONFIG_MPTCP -+ if (sock_flag(sk, SOCK_MPTCP)) -+ icsk->icsk_af_ops = &mptcp_v6_specific; -+ else -+#endif -+ icsk->icsk_af_ops = &ipv6_specific; - - #ifdef CONFIG_TCP_MD5SIG - tcp_sk(sk)->af_specific = &tcp_sock_ipv6_specific; -@@ -1758,7 +1862,7 @@ - return 0; - } - --static void tcp_v6_destroy_sock(struct sock *sk) -+void tcp_v6_destroy_sock(struct sock *sk) - { - tcp_v4_destroy_sock(sk); - inet6_destroy_sock(sk); -@@ -1981,6 +2085,11 @@ - .sysctl_rmem_offset = offsetof(struct net, ipv4.sysctl_tcp_rmem), - .max_header = MAX_TCP_HEADER, - .obj_size = sizeof(struct tcp6_sock), -+#ifdef CONFIG_MPTCP -+ .useroffset = offsetof(struct tcp_sock, mptcp_sched_name), -+ .usersize = sizeof_field(struct tcp_sock, mptcp_sched_name) + -+ sizeof_field(struct tcp_sock, mptcp_pm_name), -+#endif - .slab_flags = SLAB_TYPESAFE_BY_RCU, - .twsk_prot = &tcp6_timewait_sock_ops, - .rsk_prot = &tcp6_request_sock_ops, -@@ -1991,6 +2100,9 @@ - .compat_getsockopt = compat_tcp_getsockopt, - #endif - .diag_destroy = tcp_abort, -+#ifdef CONFIG_MPTCP -+ .clear_sk = mptcp_clear_sk, -+#endif - }; - - /* thinking of making this const? Don't. -diff -aurN linux-4.19.104/net/Kconfig mptcp-mptcp_v0.95/net/Kconfig ---- linux-4.19.104/net/Kconfig 2020-02-14 22:33:28.000000000 +0100 -+++ mptcp-mptcp_v0.95/net/Kconfig 2020-02-17 11:29:55.000000000 +0100 -@@ -89,6 +89,7 @@ - source "net/ipv4/Kconfig" - source "net/ipv6/Kconfig" - source "net/netlabel/Kconfig" -+source "net/mptcp/Kconfig" - - endif # if INET - -diff -aurN linux-4.19.104/net/Makefile mptcp-mptcp_v0.95/net/Makefile ---- linux-4.19.104/net/Makefile 2020-02-14 22:33:28.000000000 +0100 -+++ mptcp-mptcp_v0.95/net/Makefile 2020-02-17 11:29:55.000000000 +0100 -@@ -20,6 +20,7 @@ - obj-$(CONFIG_XFRM) += xfrm/ - obj-$(CONFIG_UNIX) += unix/ - obj-$(CONFIG_NET) += ipv6/ -+obj-$(CONFIG_MPTCP) += mptcp/ - obj-$(CONFIG_BPFILTER) += bpfilter/ - obj-$(CONFIG_PACKET) += packet/ - obj-$(CONFIG_NET_KEY) += key/ -diff -aurN linux-4.19.104/net/mptcp/Kconfig mptcp-mptcp_v0.95/net/mptcp/Kconfig ---- linux-4.19.104/net/mptcp/Kconfig 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_v0.95/net/mptcp/Kconfig 2020-02-17 11:29:55.000000000 +0100 -@@ -0,0 +1,146 @@ -+# -+# MPTCP configuration -+# -+config MPTCP -+ bool "MPTCP protocol" -+ depends on (IPV6=y || IPV6=n) -+ ---help--- -+ This replaces the normal TCP stack with a Multipath TCP stack, -+ able to use several paths at once. -+ -+menuconfig MPTCP_PM_ADVANCED -+ bool "MPTCP: advanced path-manager control" -+ depends on MPTCP=y -+ ---help--- -+ Support for selection of different path-managers. You should choose 'Y' here, -+ because otherwise you will not actively create new MPTCP-subflows. -+ -+if MPTCP_PM_ADVANCED -+ -+config MPTCP_FULLMESH -+ tristate "MPTCP Full-Mesh Path-Manager" -+ depends on MPTCP=y -+ ---help--- -+ This path-management module will create a full-mesh among all IP-addresses. -+ -+config MPTCP_NDIFFPORTS -+ tristate "MPTCP ndiff-ports" -+ depends on MPTCP=y -+ ---help--- -+ This path-management module will create multiple subflows between the same -+ pair of IP-addresses, modifying the source-port. You can set the number -+ of subflows via the mptcp_ndiffports-sysctl. -+ -+config MPTCP_BINDER -+ tristate "MPTCP Binder" -+ depends on (MPTCP=y) -+ ---help--- -+ This path-management module works like ndiffports, and adds the sysctl -+ option to set the gateway (and/or path to) per each additional subflow -+ via Loose Source Routing (IPv4 only). -+ -+config MPTCP_NETLINK -+ tristate "MPTCP Netlink Path-Manager" -+ depends on MPTCP=y -+ ---help--- -+ This path-management module is controlled over a Netlink interface. A userspace -+ module can therefore control the establishment of new subflows and the policy -+ to apply over those new subflows for every connection. -+ -+choice -+ prompt "Default MPTCP Path-Manager" -+ default DEFAULT -+ help -+ Select the Path-Manager of your choice -+ -+ config DEFAULT_FULLMESH -+ bool "Full mesh" if MPTCP_FULLMESH=y -+ -+ config DEFAULT_NDIFFPORTS -+ bool "ndiff-ports" if MPTCP_NDIFFPORTS=y -+ -+ config DEFAULT_BINDER -+ bool "binder" if MPTCP_BINDER=y -+ -+ config DEFAULT_NETLINK -+ bool "Netlink" if MPTCP_NETLINK=y -+ -+ config DEFAULT_DUMMY -+ bool "Default" -+ -+endchoice -+ -+endif -+ -+config DEFAULT_MPTCP_PM -+ string -+ default "default" if DEFAULT_DUMMY -+ default "fullmesh" if DEFAULT_FULLMESH -+ default "ndiffports" if DEFAULT_NDIFFPORTS -+ default "binder" if DEFAULT_BINDER -+ default "default" -+ -+menuconfig MPTCP_SCHED_ADVANCED -+ bool "MPTCP: advanced scheduler control" -+ depends on MPTCP=y -+ ---help--- -+ Support for selection of different schedulers. You should choose 'Y' here, -+ if you want to choose a different scheduler than the default one. -+ -+if MPTCP_SCHED_ADVANCED -+ -+config MPTCP_BLEST -+ tristate "MPTCP BLEST" -+ depends on MPTCP=y -+ ---help--- -+ This is an experimental BLocking ESTimation-based (BLEST) scheduler. -+ -+config MPTCP_ROUNDROBIN -+ tristate "MPTCP Round-Robin" -+ depends on (MPTCP=y) -+ ---help--- -+ This is a very simple round-robin scheduler. Probably has bad performance -+ but might be interesting for researchers. -+ -+config MPTCP_REDUNDANT -+ tristate "MPTCP Redundant" -+ depends on (MPTCP=y) -+ ---help--- -+ This scheduler sends all packets redundantly over all subflows to decreases -+ latency and jitter on the cost of lower throughput. -+ -+choice -+ prompt "Default MPTCP Scheduler" -+ default DEFAULT -+ help -+ Select the Scheduler of your choice -+ -+ config DEFAULT_SCHEDULER -+ bool "Default" -+ ---help--- -+ This is the default scheduler, sending first on the subflow -+ with the lowest RTT. -+ -+ config DEFAULT_ROUNDROBIN -+ bool "Round-Robin" if MPTCP_ROUNDROBIN=y -+ ---help--- -+ This is the round-rob scheduler, sending in a round-robin -+ fashion.. -+ -+ config DEFAULT_REDUNDANT -+ bool "Redundant" if MPTCP_REDUNDANT=y -+ ---help--- -+ This is the redundant scheduler, sending packets redundantly over -+ all the subflows. -+ -+endchoice -+endif -+ -+config DEFAULT_MPTCP_SCHED -+ string -+ depends on (MPTCP=y) -+ default "default" if DEFAULT_SCHEDULER -+ default "roundrobin" if DEFAULT_ROUNDROBIN -+ default "redundant" if DEFAULT_REDUNDANT -+ default "default" -+ -diff -aurN linux-4.19.104/net/mptcp/Makefile mptcp-mptcp_v0.95/net/mptcp/Makefile ---- linux-4.19.104/net/mptcp/Makefile 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_v0.95/net/mptcp/Makefile 2020-02-17 11:29:55.000000000 +0100 -@@ -0,0 +1,24 @@ -+# -+## Makefile for MultiPath TCP support code. -+# -+# -+ -+obj-$(CONFIG_MPTCP) += mptcp.o -+ -+mptcp-y := mptcp_ctrl.o mptcp_ipv4.o mptcp_pm.o \ -+ mptcp_output.o mptcp_input.o mptcp_sched.o -+ -+obj-$(CONFIG_TCP_CONG_LIA) += mptcp_coupled.o -+obj-$(CONFIG_TCP_CONG_OLIA) += mptcp_olia.o -+obj-$(CONFIG_TCP_CONG_WVEGAS) += mptcp_wvegas.o -+obj-$(CONFIG_TCP_CONG_BALIA) += mptcp_balia.o -+obj-$(CONFIG_TCP_CONG_MCTCPDESYNC) += mctcp_desync.o -+obj-$(CONFIG_MPTCP_FULLMESH) += mptcp_fullmesh.o -+obj-$(CONFIG_MPTCP_NDIFFPORTS) += mptcp_ndiffports.o -+obj-$(CONFIG_MPTCP_BINDER) += mptcp_binder.o -+obj-$(CONFIG_MPTCP_NETLINK) += mptcp_netlink.o -+obj-$(CONFIG_MPTCP_ROUNDROBIN) += mptcp_rr.o -+obj-$(CONFIG_MPTCP_REDUNDANT) += mptcp_redundant.o -+obj-$(CONFIG_MPTCP_BLEST) += mptcp_blest.o -+ -+mptcp-$(subst m,y,$(CONFIG_IPV6)) += mptcp_ipv6.o -diff -aurN linux-4.19.104/net/mptcp/mctcp_desync.c mptcp-mptcp_v0.95/net/mptcp/mctcp_desync.c ---- linux-4.19.104/net/mptcp/mctcp_desync.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_v0.95/net/mptcp/mctcp_desync.c 2020-02-17 11:29:55.000000000 +0100 -@@ -0,0 +1,193 @@ -+/* -+ * Desynchronized Multi-Channel TCP Congestion Control Algorithm -+ * -+ * Implementation based on publications of "DMCTCP:Desynchronized Multi-Channel -+ * TCP for high speed access networks with tiny buffers" in 23rd international -+ * conference of Computer Communication and Networks (ICCCN), 2014, and -+ * "Exploring parallelism and desynchronization of TCP over high speed networks -+ * with tiny buffers" in Journal of Computer Communications Elsevier, 2015. -+ * -+ * http://ieeexplore.ieee.org/abstract/document/6911722/ -+ * https://doi.org/10.1016/j.comcom.2015.07.010 -+ * -+ * This prototype is for research purpose and is currently experimental code -+ * that only support a single path. Future support of multi-channel over -+ * multi-path requires channels grouping. -+ * -+ * Initial Design and Implementation: -+ * Cheng Cui -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the Free -+ * Software Foundation; either version 2 of the License, or (at your option) -+ * any later version. -+ */ -+#include -+#include -+#include -+ -+enum { -+ MASTER_CHANNEL = 1, -+ INI_MIN_CWND = 2, -+}; -+ -+/* private congestion control structure: -+ * off_tstamp: the last backoff timestamp for loss synchronization event -+ * off_subfid: the subflow which was backoff on off_tstamp -+ */ -+struct mctcp_desync { -+ u64 off_tstamp; -+ u8 off_subfid; -+}; -+ -+static inline int mctcp_cc_sk_can_send(const struct sock *sk) -+{ -+ return mptcp_sk_can_send(sk) && tcp_sk(sk)->srtt_us; -+} -+ -+static void mctcp_desync_init(struct sock *sk) -+{ -+ if (mptcp(tcp_sk(sk))) { -+ struct mctcp_desync *ca = inet_csk_ca(mptcp_meta_sk(sk)); -+ ca->off_tstamp = 0; -+ ca->off_subfid = 0; -+ } -+ /* If we do not mptcp, behave like reno: return */ -+} -+ -+static void mctcp_desync_cong_avoid(struct sock *sk, u32 ack, u32 acked) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ -+ if (!mptcp(tp)) { -+ tcp_reno_cong_avoid(sk, ack, acked); -+ return; -+ } else if (!tcp_is_cwnd_limited(sk)) { -+ return; -+ } else { -+ const struct mctcp_desync *ca = inet_csk_ca(mptcp_meta_sk(sk)); -+ const u8 subfid = tp->mptcp->path_index; -+ -+ /* current aggregated cwnd */ -+ u32 agg_cwnd = 0; -+ u32 min_cwnd = 0xffffffff; -+ u8 min_cwnd_subfid = 0; -+ -+ /* In "safe" area, increase */ -+ if (tcp_in_slow_start(tp)) { -+ if (ca->off_subfid) { -+ /* passed initial phase, allow slow start */ -+ tcp_slow_start(tp, acked); -+ } else if (MASTER_CHANNEL == tp->mptcp->path_index) { -+ /* master channel is normal slow start in -+ * initial phase */ -+ tcp_slow_start(tp, acked); -+ } else { -+ /* secondary channels increase slowly until -+ * the initial phase passed -+ */ -+ tp->snd_ssthresh = tp->snd_cwnd = INI_MIN_CWND; -+ } -+ return; -+ } else { -+ /* In dangerous area, increase slowly and linearly. */ -+ const struct mptcp_tcp_sock *mptcp; -+ -+ /* get total cwnd and the subflow that has min cwnd */ -+ mptcp_for_each_sub(tp->mpcb, mptcp) { -+ const struct sock *sub_sk = mptcp_to_sock(mptcp); -+ -+ if (mctcp_cc_sk_can_send(sub_sk)) { -+ const struct tcp_sock *sub_tp = -+ tcp_sk(sub_sk); -+ agg_cwnd += sub_tp->snd_cwnd; -+ if(min_cwnd > sub_tp->snd_cwnd) { -+ min_cwnd = sub_tp->snd_cwnd; -+ min_cwnd_subfid = -+ sub_tp->mptcp->path_index; -+ } -+ } -+ } -+ /* the smallest subflow grows faster than others */ -+ if (subfid == min_cwnd_subfid) { -+ tcp_cong_avoid_ai(tp, min_cwnd, acked); -+ } else { -+ tcp_cong_avoid_ai(tp, agg_cwnd - min_cwnd, -+ acked); -+ } -+ } -+ } -+} -+ -+static u32 mctcp_desync_ssthresh(struct sock *sk) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ -+ if (!mptcp(tp)) { -+ return max(tp->snd_cwnd >> 1U, 2U); -+ } else { -+ struct mctcp_desync *ca = inet_csk_ca(mptcp_meta_sk(sk)); -+ const u8 subfid = tp->mptcp->path_index; -+ const struct mptcp_tcp_sock *mptcp; -+ u32 max_cwnd = 0; -+ u8 max_cwnd_subfid = 0; -+ -+ /* Find the subflow that has the max cwnd. */ -+ mptcp_for_each_sub(tp->mpcb, mptcp) { -+ const struct sock *sub_sk = mptcp_to_sock(mptcp); -+ -+ if (mctcp_cc_sk_can_send(sub_sk)) { -+ const struct tcp_sock *sub_tp = tcp_sk(sub_sk); -+ if (max_cwnd < sub_tp->snd_cwnd) { -+ max_cwnd = sub_tp->snd_cwnd; -+ max_cwnd_subfid = -+ sub_tp->mptcp->path_index; -+ } -+ } -+ } -+ /* Use high resolution clock. */ -+ if (subfid == max_cwnd_subfid) { -+ u64 now = tcp_clock_us(); -+ u32 delta = tcp_stamp_us_delta(now, ca->off_tstamp); -+ -+ if (delta < (tp->srtt_us >> 3)) { -+ /* desynchronize */ -+ return tp->snd_cwnd; -+ } else { -+ ca->off_tstamp = now; -+ ca->off_subfid = subfid; -+ return max(max_cwnd >> 1U, 2U); -+ } -+ } else { -+ return tp->snd_cwnd; -+ } -+ } -+} -+ -+static struct tcp_congestion_ops mctcp_desync = { -+ .init = mctcp_desync_init, -+ .ssthresh = mctcp_desync_ssthresh, -+ .undo_cwnd = tcp_reno_undo_cwnd, -+ .cong_avoid = mctcp_desync_cong_avoid, -+ .owner = THIS_MODULE, -+ .name = "mctcpdesync", -+}; -+ -+static int __init mctcp_desync_register(void) -+{ -+ BUILD_BUG_ON(sizeof(struct mctcp_desync) > ICSK_CA_PRIV_SIZE); -+ return tcp_register_congestion_control(&mctcp_desync); -+} -+ -+static void __exit mctcp_desync_unregister(void) -+{ -+ tcp_unregister_congestion_control(&mctcp_desync); -+} -+ -+module_init(mctcp_desync_register); -+module_exit(mctcp_desync_unregister); -+ -+MODULE_AUTHOR("Cheng Cui"); -+MODULE_LICENSE("GPL"); -+MODULE_DESCRIPTION("MCTCP: DESYNCHRONIZED MULTICHANNEL TCP CONGESTION CONTROL"); -+MODULE_VERSION("1.0"); -diff -aurN linux-4.19.104/net/mptcp/mptcp_balia.c mptcp-mptcp_v0.95/net/mptcp/mptcp_balia.c ---- linux-4.19.104/net/mptcp/mptcp_balia.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_v0.95/net/mptcp/mptcp_balia.c 2020-02-17 11:29:55.000000000 +0100 -@@ -0,0 +1,261 @@ -+/* -+ * MPTCP implementation - Balia Congestion Control -+ * (Balanced Linked Adaptation Algorithm) -+ * -+ * Analysis, Design and Implementation: -+ * Qiuyu Peng -+ * Anwar Walid -+ * Jaehyun Hwang -+ * Steven H. Low -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version -+ * 2 of the License, or (at your option) any later version. -+ */ -+ -+#include -+#include -+ -+#include -+ -+/* The variable 'rate' (i.e., x_r) will be scaled -+ * e.g., from B/s to KB/s, MB/s, or GB/s -+ * if max_rate > 2^rate_scale_limit -+ */ -+ -+static int rate_scale_limit = 25; -+static int alpha_scale = 10; -+static int scale_num = 5; -+ -+struct mptcp_balia { -+ u64 ai; -+ u64 md; -+ bool forced_update; -+}; -+ -+static inline int mptcp_balia_sk_can_send(const struct sock *sk) -+{ -+ return mptcp_sk_can_send(sk) && tcp_sk(sk)->srtt_us; -+} -+ -+static inline u64 mptcp_get_ai(const struct sock *meta_sk) -+{ -+ return ((struct mptcp_balia *)inet_csk_ca(meta_sk))->ai; -+} -+ -+static inline void mptcp_set_ai(const struct sock *meta_sk, u64 ai) -+{ -+ ((struct mptcp_balia *)inet_csk_ca(meta_sk))->ai = ai; -+} -+ -+static inline u64 mptcp_get_md(const struct sock *meta_sk) -+{ -+ return ((struct mptcp_balia *)inet_csk_ca(meta_sk))->md; -+} -+ -+static inline void mptcp_set_md(const struct sock *meta_sk, u64 md) -+{ -+ ((struct mptcp_balia *)inet_csk_ca(meta_sk))->md = md; -+} -+ -+static inline u64 mptcp_balia_scale(u64 val, int scale) -+{ -+ return (u64) val << scale; -+} -+ -+static inline bool mptcp_get_forced(const struct sock *meta_sk) -+{ -+ return ((struct mptcp_balia *)inet_csk_ca(meta_sk))->forced_update; -+} -+ -+static inline void mptcp_set_forced(const struct sock *meta_sk, bool force) -+{ -+ ((struct mptcp_balia *)inet_csk_ca(meta_sk))->forced_update = force; -+} -+ -+static void mptcp_balia_recalc_ai(const struct sock *sk) -+{ -+ const struct tcp_sock *tp = tcp_sk(sk); -+ const struct mptcp_cb *mpcb = tp->mpcb; -+ struct mptcp_tcp_sock *mptcp; -+ u64 max_rate = 0, rate = 0, sum_rate = 0; -+ u64 alpha, ai = tp->snd_cwnd, md = (tp->snd_cwnd >> 1); -+ int num_scale_down = 0; -+ -+ if (!mpcb) -+ return; -+ -+ /* Find max_rate first */ -+ mptcp_for_each_sub(mpcb, mptcp) { -+ const struct sock *sub_sk = mptcp_to_sock(mptcp); -+ struct tcp_sock *sub_tp = tcp_sk(sub_sk); -+ u64 tmp; -+ -+ if (!mptcp_balia_sk_can_send(sub_sk)) -+ continue; -+ -+ tmp = div_u64((u64)tp->mss_cache * sub_tp->snd_cwnd -+ * (USEC_PER_SEC << 3), sub_tp->srtt_us); -+ sum_rate += tmp; -+ -+ if (tp == sub_tp) -+ rate = tmp; -+ -+ if (tmp >= max_rate) -+ max_rate = tmp; -+ } -+ -+ /* At least, the current subflow should be able to send */ -+ if (unlikely(!rate)) -+ goto exit; -+ -+ alpha = div64_u64(max_rate, rate); -+ -+ /* Scale down max_rate if it is too high (e.g., >2^25) */ -+ while (max_rate > mptcp_balia_scale(1, rate_scale_limit)) { -+ max_rate >>= scale_num; -+ num_scale_down++; -+ } -+ -+ if (num_scale_down) { -+ sum_rate = 0; -+ mptcp_for_each_sub(mpcb, mptcp) { -+ const struct sock *sub_sk = mptcp_to_sock(mptcp); -+ struct tcp_sock *sub_tp = tcp_sk(sub_sk); -+ u64 tmp; -+ -+ if (!mptcp_balia_sk_can_send(sub_sk)) -+ continue; -+ -+ tmp = div_u64((u64)tp->mss_cache * sub_tp->snd_cwnd -+ * (USEC_PER_SEC << 3), sub_tp->srtt_us); -+ tmp >>= (scale_num * num_scale_down); -+ -+ sum_rate += tmp; -+ } -+ rate >>= (scale_num * num_scale_down); -+ } -+ -+ /* (sum_rate)^2 * 10 * w_r -+ * ai = ------------------------------------ -+ * (x_r + max_rate) * (4x_r + max_rate) -+ */ -+ sum_rate *= sum_rate; -+ -+ ai = div64_u64(sum_rate * 10, rate + max_rate); -+ ai = div64_u64(ai * tp->snd_cwnd, (rate << 2) + max_rate); -+ -+ if (unlikely(!ai)) -+ ai = tp->snd_cwnd; -+ -+ md = ((tp->snd_cwnd >> 1) * min(mptcp_balia_scale(alpha, alpha_scale), -+ mptcp_balia_scale(3, alpha_scale) >> 1)) -+ >> alpha_scale; -+ -+exit: -+ mptcp_set_ai(sk, ai); -+ mptcp_set_md(sk, md); -+} -+ -+static void mptcp_balia_init(struct sock *sk) -+{ -+ if (mptcp(tcp_sk(sk))) { -+ mptcp_set_forced(sk, 0); -+ mptcp_set_ai(sk, 0); -+ mptcp_set_md(sk, 0); -+ } -+} -+ -+static void mptcp_balia_cwnd_event(struct sock *sk, enum tcp_ca_event event) -+{ -+ if (event == CA_EVENT_COMPLETE_CWR || event == CA_EVENT_LOSS) -+ mptcp_balia_recalc_ai(sk); -+} -+ -+static void mptcp_balia_set_state(struct sock *sk, u8 ca_state) -+{ -+ if (!mptcp(tcp_sk(sk))) -+ return; -+ -+ mptcp_set_forced(sk, 1); -+} -+ -+static void mptcp_balia_cong_avoid(struct sock *sk, u32 ack, u32 acked) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ int snd_cwnd; -+ -+ if (!mptcp(tp)) { -+ tcp_reno_cong_avoid(sk, ack, acked); -+ return; -+ } -+ -+ if (!tcp_is_cwnd_limited(sk)) -+ return; -+ -+ if (tcp_in_slow_start(tp)) { -+ /* In "safe" area, increase. */ -+ tcp_slow_start(tp, acked); -+ mptcp_balia_recalc_ai(sk); -+ return; -+ } -+ -+ if (mptcp_get_forced(mptcp_meta_sk(sk))) { -+ mptcp_balia_recalc_ai(sk); -+ mptcp_set_forced(sk, 0); -+ } -+ -+ snd_cwnd = (int)mptcp_get_ai(sk); -+ -+ if (tp->snd_cwnd_cnt >= snd_cwnd) { -+ if (tp->snd_cwnd < tp->snd_cwnd_clamp) { -+ tp->snd_cwnd++; -+ mptcp_balia_recalc_ai(sk); -+ } -+ -+ tp->snd_cwnd_cnt = 0; -+ } else { -+ tp->snd_cwnd_cnt++; -+ } -+} -+ -+static u32 mptcp_balia_ssthresh(struct sock *sk) -+{ -+ const struct tcp_sock *tp = tcp_sk(sk); -+ -+ if (unlikely(!mptcp(tp))) -+ return tcp_reno_ssthresh(sk); -+ else -+ return max((u32)(tp->snd_cwnd - mptcp_get_md(sk)), 1U); -+} -+ -+static struct tcp_congestion_ops mptcp_balia = { -+ .init = mptcp_balia_init, -+ .ssthresh = mptcp_balia_ssthresh, -+ .cong_avoid = mptcp_balia_cong_avoid, -+ .undo_cwnd = tcp_reno_undo_cwnd, -+ .cwnd_event = mptcp_balia_cwnd_event, -+ .set_state = mptcp_balia_set_state, -+ .owner = THIS_MODULE, -+ .name = "balia", -+}; -+ -+static int __init mptcp_balia_register(void) -+{ -+ BUILD_BUG_ON(sizeof(struct mptcp_balia) > ICSK_CA_PRIV_SIZE); -+ return tcp_register_congestion_control(&mptcp_balia); -+} -+ -+static void __exit mptcp_balia_unregister(void) -+{ -+ tcp_unregister_congestion_control(&mptcp_balia); -+} -+ -+module_init(mptcp_balia_register); -+module_exit(mptcp_balia_unregister); -+ -+MODULE_AUTHOR("Jaehyun Hwang, Anwar Walid, Qiuyu Peng, Steven H. Low"); -+MODULE_LICENSE("GPL"); -+MODULE_DESCRIPTION("MPTCP BALIA CONGESTION CONTROL ALGORITHM"); -+MODULE_VERSION("0.1"); -diff -aurN linux-4.19.104/net/mptcp/mptcp_binder.c mptcp-mptcp_v0.95/net/mptcp/mptcp_binder.c ---- linux-4.19.104/net/mptcp/mptcp_binder.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_v0.95/net/mptcp/mptcp_binder.c 2020-02-17 11:29:55.000000000 +0100 -@@ -0,0 +1,494 @@ -+#include -+ -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define MPTCP_GW_MAX_LISTS 10 -+#define MPTCP_GW_LIST_MAX_LEN 6 -+#define MPTCP_GW_SYSCTL_MAX_LEN (15 * MPTCP_GW_LIST_MAX_LEN * \ -+ MPTCP_GW_MAX_LISTS) -+ -+struct mptcp_gw_list { -+ struct in_addr list[MPTCP_GW_MAX_LISTS][MPTCP_GW_LIST_MAX_LEN]; -+ u8 len[MPTCP_GW_MAX_LISTS]; -+}; -+ -+struct binder_priv { -+ /* Worker struct for subflow establishment */ -+ struct work_struct subflow_work; -+ -+ struct mptcp_cb *mpcb; -+ -+ /* Prevent multiple sub-sockets concurrently iterating over sockets */ -+ spinlock_t *flow_lock; -+}; -+ -+static struct mptcp_gw_list *mptcp_gws; -+static rwlock_t mptcp_gws_lock; -+ -+static int mptcp_binder_ndiffports __read_mostly = 1; -+ -+static char sysctl_mptcp_binder_gateways[MPTCP_GW_SYSCTL_MAX_LEN] __read_mostly; -+ -+static int mptcp_get_avail_list_ipv4(struct sock *sk) -+{ -+ int i, j, list_taken, opt_ret, opt_len; -+ unsigned char *opt_ptr, *opt_end_ptr, opt[MAX_IPOPTLEN]; -+ -+ for (i = 0; i < MPTCP_GW_MAX_LISTS; ++i) { -+ struct mptcp_tcp_sock *mptcp; -+ -+ if (mptcp_gws->len[i] == 0) -+ goto error; -+ -+ mptcp_debug("mptcp_get_avail_list_ipv4: List %i\n", i); -+ list_taken = 0; -+ -+ /* Loop through all sub-sockets in this connection */ -+ mptcp_for_each_sub(tcp_sk(sk)->mpcb, mptcp) { -+ sk = mptcp_to_sock(mptcp); -+ -+ mptcp_debug("mptcp_get_avail_list_ipv4: Next sock\n"); -+ -+ /* Reset length and options buffer, then retrieve -+ * from socket -+ */ -+ opt_len = MAX_IPOPTLEN; -+ memset(opt, 0, MAX_IPOPTLEN); -+ opt_ret = ip_getsockopt(sk, IPPROTO_IP, -+ IP_OPTIONS, (char __user *)opt, (int __user *)&opt_len); -+ if (opt_ret < 0) { -+ mptcp_debug("%s: MPTCP subsocket getsockopt() IP_OPTIONS failed, error %d\n", -+ __func__, opt_ret); -+ goto error; -+ } -+ -+ /* If socket has no options, it has no stake in this list */ -+ if (opt_len <= 0) -+ continue; -+ -+ /* Iterate options buffer */ -+ for (opt_ptr = &opt[0]; opt_ptr < &opt[opt_len]; opt_ptr++) { -+ if (*opt_ptr == IPOPT_LSRR) { -+ mptcp_debug("mptcp_get_avail_list_ipv4: LSRR options found\n"); -+ goto sock_lsrr; -+ } -+ } -+ continue; -+ -+sock_lsrr: -+ /* Pointer to the 2nd to last address */ -+ opt_end_ptr = opt_ptr+(*(opt_ptr+1))-4; -+ -+ /* Addresses start 3 bytes after type offset */ -+ opt_ptr += 3; -+ j = 0; -+ -+ /* Different length lists cannot be the same */ -+ if ((opt_end_ptr-opt_ptr)/4 != mptcp_gws->len[i]) -+ continue; -+ -+ /* Iterate if we are still inside options list -+ * and sysctl list -+ */ -+ while (opt_ptr < opt_end_ptr && j < mptcp_gws->len[i]) { -+ /* If there is a different address, this list must -+ * not be set on this socket -+ */ -+ if (memcmp(&mptcp_gws->list[i][j], opt_ptr, 4)) -+ break; -+ -+ /* Jump 4 bytes to next address */ -+ opt_ptr += 4; -+ j++; -+ } -+ -+ /* Reached the end without a differing address, lists -+ * are therefore identical. -+ */ -+ if (j == mptcp_gws->len[i]) { -+ mptcp_debug("mptcp_get_avail_list_ipv4: List already used\n"); -+ list_taken = 1; -+ break; -+ } -+ } -+ -+ /* Free list found if not taken by a socket */ -+ if (!list_taken) { -+ mptcp_debug("mptcp_get_avail_list_ipv4: List free\n"); -+ break; -+ } -+ } -+ -+ if (i >= MPTCP_GW_MAX_LISTS) -+ goto error; -+ -+ return i; -+error: -+ return -1; -+} -+ -+/* The list of addresses is parsed each time a new connection is opened, -+ * to make sure it's up to date. In case of error, all the lists are -+ * marked as unavailable and the subflow's fingerprint is set to 0. -+ */ -+static void mptcp_v4_add_lsrr(struct sock *sk, struct in_addr addr) -+{ -+ int i, j, ret; -+ unsigned char opt[MAX_IPOPTLEN] = {0}; -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct binder_priv *fmp = (struct binder_priv *)&tp->mpcb->mptcp_pm[0]; -+ -+ /* Read lock: multiple sockets can read LSRR addresses at the same -+ * time, but writes are done in mutual exclusion. -+ * Spin lock: must search for free list for one socket at a time, or -+ * multiple sockets could take the same list. -+ */ -+ read_lock(&mptcp_gws_lock); -+ spin_lock(fmp->flow_lock); -+ -+ i = mptcp_get_avail_list_ipv4(sk); -+ -+ /* Execution enters here only if a free path is found. -+ */ -+ if (i >= 0) { -+ opt[0] = IPOPT_NOP; -+ opt[1] = IPOPT_LSRR; -+ opt[2] = sizeof(mptcp_gws->list[i][0].s_addr) * -+ (mptcp_gws->len[i] + 1) + 3; -+ opt[3] = IPOPT_MINOFF; -+ for (j = 0; j < mptcp_gws->len[i]; ++j) -+ memcpy(opt + 4 + -+ (j * sizeof(mptcp_gws->list[i][0].s_addr)), -+ &mptcp_gws->list[i][j].s_addr, -+ sizeof(mptcp_gws->list[i][0].s_addr)); -+ /* Final destination must be part of IP_OPTIONS parameter. */ -+ memcpy(opt + 4 + (j * sizeof(addr.s_addr)), &addr.s_addr, -+ sizeof(addr.s_addr)); -+ -+ /* setsockopt must be inside the lock, otherwise another -+ * subflow could fail to see that we have taken a list. -+ */ -+ ret = ip_setsockopt(sk, IPPROTO_IP, IP_OPTIONS, (char __user *)opt, -+ 4 + sizeof(mptcp_gws->list[i][0].s_addr) * (mptcp_gws->len[i] + 1)); -+ -+ if (ret < 0) { -+ mptcp_debug("%s: MPTCP subsock setsockopt() IP_OPTIONS failed, error %d\n", -+ __func__, ret); -+ } -+ } -+ -+ spin_unlock(fmp->flow_lock); -+ read_unlock(&mptcp_gws_lock); -+ -+ return; -+} -+ -+/* Parses gateways string for a list of paths to different -+ * gateways, and stores them for use with the Loose Source Routing (LSRR) -+ * socket option. Each list must have "," separated addresses, and the lists -+ * themselves must be separated by "-". Returns -1 in case one or more of the -+ * addresses is not a valid ipv4/6 address. -+ */ -+static int mptcp_parse_gateway_ipv4(char *gateways) -+{ -+ int i, j, k, ret; -+ char *tmp_string = NULL; -+ struct in_addr tmp_addr; -+ -+ tmp_string = kzalloc(16, GFP_KERNEL); -+ if (tmp_string == NULL) -+ return -ENOMEM; -+ -+ write_lock(&mptcp_gws_lock); -+ -+ memset(mptcp_gws, 0, sizeof(struct mptcp_gw_list)); -+ -+ /* A TMP string is used since inet_pton needs a null terminated string -+ * but we do not want to modify the sysctl for obvious reasons. -+ * i will iterate over the SYSCTL string, j will iterate over the -+ * temporary string where each IP is copied into, k will iterate over -+ * the IPs in each list. -+ */ -+ for (i = j = k = 0; -+ i < MPTCP_GW_SYSCTL_MAX_LEN && k < MPTCP_GW_MAX_LISTS; -+ ++i) { -+ if (gateways[i] == '-' || gateways[i] == ',' || gateways[i] == '\0') { -+ /* If the temp IP is empty and the current list is -+ * empty, we are done. -+ */ -+ if (j == 0 && mptcp_gws->len[k] == 0) -+ break; -+ -+ /* Terminate the temp IP string, then if it is -+ * non-empty parse the IP and copy it. -+ */ -+ tmp_string[j] = '\0'; -+ if (j > 0) { -+ mptcp_debug("mptcp_parse_gateway_list tmp: %s i: %d\n", tmp_string, i); -+ -+ ret = in4_pton(tmp_string, strlen(tmp_string), -+ (u8 *)&tmp_addr.s_addr, '\0', -+ NULL); -+ -+ if (ret) { -+ mptcp_debug("mptcp_parse_gateway_list ret: %d s_addr: %pI4\n", -+ ret, -+ &tmp_addr.s_addr); -+ memcpy(&mptcp_gws->list[k][mptcp_gws->len[k]].s_addr, -+ &tmp_addr.s_addr, -+ sizeof(tmp_addr.s_addr)); -+ mptcp_gws->len[k]++; -+ j = 0; -+ tmp_string[j] = '\0'; -+ /* Since we can't impose a limit to -+ * what the user can input, make sure -+ * there are not too many IPs in the -+ * SYSCTL string. -+ */ -+ if (mptcp_gws->len[k] > MPTCP_GW_LIST_MAX_LEN) { -+ mptcp_debug("mptcp_parse_gateway_list too many members in list %i: max %i\n", -+ k, -+ MPTCP_GW_LIST_MAX_LEN); -+ goto error; -+ } -+ } else { -+ goto error; -+ } -+ } -+ -+ if (gateways[i] == '-' || gateways[i] == '\0') -+ ++k; -+ } else { -+ tmp_string[j] = gateways[i]; -+ ++j; -+ } -+ } -+ -+ /* Number of flows is number of gateway lists plus master flow */ -+ mptcp_binder_ndiffports = k+1; -+ -+ write_unlock(&mptcp_gws_lock); -+ kfree(tmp_string); -+ -+ return 0; -+ -+error: -+ memset(mptcp_gws, 0, sizeof(struct mptcp_gw_list)); -+ memset(gateways, 0, sizeof(char) * MPTCP_GW_SYSCTL_MAX_LEN); -+ write_unlock(&mptcp_gws_lock); -+ kfree(tmp_string); -+ return -1; -+} -+ -+/** -+ * Create all new subflows, by doing calls to mptcp_initX_subsockets -+ * -+ * This function uses a goto next_subflow, to allow releasing the lock between -+ * new subflows and giving other processes a chance to do some work on the -+ * socket and potentially finishing the communication. -+ **/ -+static void create_subflow_worker(struct work_struct *work) -+{ -+ const struct binder_priv *pm_priv = container_of(work, -+ struct binder_priv, -+ subflow_work); -+ struct mptcp_cb *mpcb = pm_priv->mpcb; -+ struct sock *meta_sk = mpcb->meta_sk; -+ int iter = 0; -+ -+next_subflow: -+ if (iter) { -+ release_sock(meta_sk); -+ mutex_unlock(&mpcb->mpcb_mutex); -+ -+ cond_resched(); -+ } -+ mutex_lock(&mpcb->mpcb_mutex); -+ lock_sock_nested(meta_sk, SINGLE_DEPTH_NESTING); -+ -+ if (!mptcp(tcp_sk(meta_sk))) -+ goto exit; -+ -+ iter++; -+ -+ if (sock_flag(meta_sk, SOCK_DEAD)) -+ goto exit; -+ -+ if (mpcb->master_sk && -+ !tcp_sk(mpcb->master_sk)->mptcp->fully_established) -+ goto exit; -+ -+ if (mptcp_binder_ndiffports > iter && -+ mptcp_binder_ndiffports > mptcp_subflow_count(mpcb)) { -+ struct mptcp_loc4 loc; -+ struct mptcp_rem4 rem; -+ -+ loc.addr.s_addr = inet_sk(meta_sk)->inet_saddr; -+ loc.loc4_id = 0; -+ loc.low_prio = 0; -+ -+ rem.addr.s_addr = inet_sk(meta_sk)->inet_daddr; -+ rem.port = inet_sk(meta_sk)->inet_dport; -+ rem.rem4_id = 0; /* Default 0 */ -+ -+ mptcp_init4_subsockets(meta_sk, &loc, &rem); -+ -+ goto next_subflow; -+ } -+ -+exit: -+ release_sock(meta_sk); -+ mutex_unlock(&mpcb->mpcb_mutex); -+ mptcp_mpcb_put(mpcb); -+ sock_put(meta_sk); -+} -+ -+static void binder_new_session(const struct sock *meta_sk) -+{ -+ struct mptcp_cb *mpcb = tcp_sk(meta_sk)->mpcb; -+ struct binder_priv *fmp = (struct binder_priv *)&mpcb->mptcp_pm[0]; -+ static DEFINE_SPINLOCK(flow_lock); -+ -+#if IS_ENABLED(CONFIG_IPV6) -+ if (meta_sk->sk_family == AF_INET6 && -+ !mptcp_v6_is_v4_mapped(meta_sk)) { -+ mptcp_fallback_default(mpcb); -+ return; -+ } -+#endif -+ -+ /* Initialize workqueue-struct */ -+ INIT_WORK(&fmp->subflow_work, create_subflow_worker); -+ fmp->mpcb = mpcb; -+ -+ fmp->flow_lock = &flow_lock; -+} -+ -+static void binder_create_subflows(struct sock *meta_sk) -+{ -+ struct mptcp_cb *mpcb = tcp_sk(meta_sk)->mpcb; -+ struct binder_priv *pm_priv = (struct binder_priv *)&mpcb->mptcp_pm[0]; -+ -+ if (mptcp_in_infinite_mapping_weak(mpcb) || -+ mpcb->server_side || sock_flag(meta_sk, SOCK_DEAD)) -+ return; -+ -+ if (!work_pending(&pm_priv->subflow_work)) { -+ sock_hold(meta_sk); -+ refcount_inc(&mpcb->mpcb_refcnt); -+ queue_work(mptcp_wq, &pm_priv->subflow_work); -+ } -+} -+ -+static int binder_get_local_id(const struct sock *meta_sk, sa_family_t family, -+ union inet_addr *addr, bool *low_prio) -+{ -+ return 0; -+} -+ -+/* Callback functions, executed when syctl mptcp.mptcp_gateways is updated. -+ * Inspired from proc_tcp_congestion_control(). -+ */ -+static int proc_mptcp_gateways(struct ctl_table *ctl, int write, -+ void __user *buffer, size_t *lenp, -+ loff_t *ppos) -+{ -+ int ret; -+ struct ctl_table tbl = { -+ .maxlen = MPTCP_GW_SYSCTL_MAX_LEN, -+ }; -+ -+ if (write) { -+ tbl.data = kzalloc(MPTCP_GW_SYSCTL_MAX_LEN, GFP_KERNEL); -+ if (tbl.data == NULL) -+ return -ENOMEM; -+ ret = proc_dostring(&tbl, write, buffer, lenp, ppos); -+ if (ret == 0) { -+ ret = mptcp_parse_gateway_ipv4(tbl.data); -+ memcpy(ctl->data, tbl.data, MPTCP_GW_SYSCTL_MAX_LEN); -+ } -+ kfree(tbl.data); -+ } else { -+ ret = proc_dostring(ctl, write, buffer, lenp, ppos); -+ } -+ -+ -+ return ret; -+} -+ -+static struct mptcp_pm_ops binder __read_mostly = { -+ .new_session = binder_new_session, -+ .fully_established = binder_create_subflows, -+ .get_local_id = binder_get_local_id, -+ .init_subsocket_v4 = mptcp_v4_add_lsrr, -+ .name = "binder", -+ .owner = THIS_MODULE, -+}; -+ -+static struct ctl_table binder_table[] = { -+ { -+ .procname = "mptcp_binder_gateways", -+ .data = &sysctl_mptcp_binder_gateways, -+ .maxlen = sizeof(char) * MPTCP_GW_SYSCTL_MAX_LEN, -+ .mode = 0644, -+ .proc_handler = &proc_mptcp_gateways -+ }, -+ { } -+}; -+ -+static struct ctl_table_header *mptcp_sysctl_binder; -+ -+/* General initialization of MPTCP_PM */ -+static int __init binder_register(void) -+{ -+ mptcp_gws = kzalloc(sizeof(*mptcp_gws), GFP_KERNEL); -+ if (!mptcp_gws) -+ return -ENOMEM; -+ -+ rwlock_init(&mptcp_gws_lock); -+ -+ BUILD_BUG_ON(sizeof(struct binder_priv) > MPTCP_PM_SIZE); -+ -+ mptcp_sysctl_binder = register_net_sysctl(&init_net, "net/mptcp", -+ binder_table); -+ if (!mptcp_sysctl_binder) -+ goto sysctl_fail; -+ -+ if (mptcp_register_path_manager(&binder)) -+ goto pm_failed; -+ -+ return 0; -+ -+pm_failed: -+ unregister_net_sysctl_table(mptcp_sysctl_binder); -+sysctl_fail: -+ kfree(mptcp_gws); -+ -+ return -1; -+} -+ -+static void binder_unregister(void) -+{ -+ mptcp_unregister_path_manager(&binder); -+ unregister_net_sysctl_table(mptcp_sysctl_binder); -+ kfree(mptcp_gws); -+} -+ -+module_init(binder_register); -+module_exit(binder_unregister); -+ -+MODULE_AUTHOR("Luca Boccassi, Duncan Eastoe, Christoph Paasch (ndiffports)"); -+MODULE_LICENSE("GPL"); -+MODULE_DESCRIPTION("BINDER MPTCP"); -+MODULE_VERSION("0.1"); -diff -aurN linux-4.19.104/net/mptcp/mptcp_blest.c mptcp-mptcp_v0.95/net/mptcp/mptcp_blest.c ---- linux-4.19.104/net/mptcp/mptcp_blest.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_v0.95/net/mptcp/mptcp_blest.c 2020-02-17 11:29:55.000000000 +0100 -@@ -0,0 +1,481 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* MPTCP Scheduler to reduce HoL-blocking and spurious retransmissions. -+ * -+ * Algorithm Design: -+ * Simone Ferlin -+ * Ozgu Alay -+ * Olivier Mehani -+ * Roksana Boreli -+ * -+ * Initial Implementation: -+ * Simone Ferlin -+ * -+ * Additional Authors: -+ * Daniel Weber -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version -+ * 2 of the License, or (at your option) any later version. -+ */ -+ -+#include -+#include -+#include -+ -+static unsigned char lambda __read_mostly = 12; -+module_param(lambda, byte, 0644); -+MODULE_PARM_DESC(lambda, "Divided by 10 for scaling factor of fast flow rate estimation"); -+ -+static unsigned char max_lambda __read_mostly = 13; -+module_param(max_lambda, byte, 0644); -+MODULE_PARM_DESC(max_lambda, "Divided by 10 for maximum scaling factor of fast flow rate estimation"); -+ -+static unsigned char min_lambda __read_mostly = 10; -+module_param(min_lambda, byte, 0644); -+MODULE_PARM_DESC(min_lambda, "Divided by 10 for minimum scaling factor of fast flow rate estimation"); -+ -+static unsigned char dyn_lambda_good = 10; /* 1% */ -+module_param(dyn_lambda_good, byte, 0644); -+MODULE_PARM_DESC(dyn_lambda_good, "Decrease of lambda in positive case."); -+ -+static unsigned char dyn_lambda_bad = 40; /* 4% */ -+module_param(dyn_lambda_bad, byte, 0644); -+MODULE_PARM_DESC(dyn_lambda_bad, "Increase of lambda in negative case."); -+ -+struct blestsched_priv { -+ u32 last_rbuf_opti; -+ u32 min_srtt_us; -+ u32 max_srtt_us; -+}; -+ -+struct blestsched_cb { -+ bool retrans_flag; -+ s16 lambda_1000; /* values range from min_lambda * 100 to max_lambda * 100 */ -+ u32 last_lambda_update; -+}; -+ -+static struct blestsched_priv *blestsched_get_priv(const struct tcp_sock *tp) -+{ -+ return (struct blestsched_priv *)&tp->mptcp->mptcp_sched[0]; -+} -+ -+static struct blestsched_cb *blestsched_get_cb(const struct tcp_sock *tp) -+{ -+ return (struct blestsched_cb *)&tp->mpcb->mptcp_sched[0]; -+} -+ -+static void blestsched_update_lambda(struct sock *meta_sk, struct sock *sk) -+{ -+ struct blestsched_cb *blest_cb = blestsched_get_cb(tcp_sk(meta_sk)); -+ struct blestsched_priv *blest_p = blestsched_get_priv(tcp_sk(sk)); -+ -+ if (tcp_jiffies32 - blest_cb->last_lambda_update < usecs_to_jiffies(blest_p->min_srtt_us >> 3)) -+ return; -+ -+ /* if there have been retransmissions of packets of the slow flow -+ * during the slow flows last RTT => increase lambda -+ * otherwise decrease -+ */ -+ if (blest_cb->retrans_flag) { -+ /* need to slow down on the slow flow */ -+ blest_cb->lambda_1000 += dyn_lambda_bad; -+ } else { -+ /* use the slow flow more */ -+ blest_cb->lambda_1000 -= dyn_lambda_good; -+ } -+ blest_cb->retrans_flag = false; -+ -+ /* cap lambda_1000 to its value range */ -+ blest_cb->lambda_1000 = min_t(s16, blest_cb->lambda_1000, max_lambda * 100); -+ blest_cb->lambda_1000 = max_t(s16, blest_cb->lambda_1000, min_lambda * 100); -+ -+ blest_cb->last_lambda_update = tcp_jiffies32; -+} -+ -+/* how many bytes will sk send during the rtt of another, slower flow? */ -+static u32 blestsched_estimate_bytes(struct sock *sk, u32 time_8) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct blestsched_priv *blest_p = blestsched_get_priv(tp); -+ struct blestsched_cb *blest_cb = blestsched_get_cb(mptcp_meta_tp(tp)); -+ u32 avg_rtt, num_rtts, ca_cwnd, packets; -+ -+ avg_rtt = (blest_p->min_srtt_us + blest_p->max_srtt_us) / 2; -+ if (avg_rtt == 0) -+ num_rtts = 1; /* sanity */ -+ else -+ num_rtts = (time_8 / avg_rtt) + 1; /* round up */ -+ -+ /* during num_rtts, how many bytes will be sent on the flow? -+ * assumes for simplification that Reno is applied as congestion-control -+ */ -+ if (tp->snd_ssthresh == TCP_INFINITE_SSTHRESH) { -+ /* we are in initial slow start */ -+ if (num_rtts > 16) -+ num_rtts = 16; /* cap for sanity */ -+ packets = tp->snd_cwnd * ((1 << num_rtts) - 1); /* cwnd + 2*cwnd + 4*cwnd */ -+ } else { -+ ca_cwnd = max(tp->snd_cwnd, tp->snd_ssthresh + 1); /* assume we jump to CA already */ -+ packets = (ca_cwnd + (num_rtts - 1) / 2) * num_rtts; -+ } -+ -+ return div_u64(((u64)packets) * tp->mss_cache * blest_cb->lambda_1000, 1000); -+} -+ -+static u32 blestsched_estimate_linger_time(struct sock *sk) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct blestsched_priv *blest_p = blestsched_get_priv(tp); -+ u32 estimate, slope, inflight, cwnd; -+ -+ inflight = tcp_packets_in_flight(tp) + 1; /* take into account the new one */ -+ cwnd = tp->snd_cwnd; -+ -+ if (inflight >= cwnd) { -+ estimate = blest_p->max_srtt_us; -+ } else { -+ slope = blest_p->max_srtt_us - blest_p->min_srtt_us; -+ if (cwnd == 0) -+ cwnd = 1; /* sanity */ -+ estimate = blest_p->min_srtt_us + (slope * inflight) / cwnd; -+ } -+ -+ return (tp->srtt_us > estimate) ? tp->srtt_us : estimate; -+} -+ -+/* This is the BLEST scheduler. This function decides on which flow to send -+ * a given MSS. If all subflows are found to be busy or the currently best -+ * subflow is estimated to possibly cause HoL-blocking, NULL is returned. -+ */ -+struct sock *blest_get_available_subflow(struct sock *meta_sk, struct sk_buff *skb, -+ bool zero_wnd_test) -+{ -+ struct mptcp_cb *mpcb = tcp_sk(meta_sk)->mpcb; -+ struct sock *bestsk, *minsk = NULL; -+ struct tcp_sock *meta_tp, *besttp; -+ struct mptcp_tcp_sock *mptcp; -+ struct blestsched_priv *blest_p; -+ u32 min_srtt = U32_MAX; -+ -+ /* Answer data_fin on same subflow!!! */ -+ if (meta_sk->sk_shutdown & RCV_SHUTDOWN && -+ skb && mptcp_is_data_fin(skb)) { -+ mptcp_for_each_sub(mpcb, mptcp) { -+ bestsk = mptcp_to_sock(mptcp); -+ -+ if (tcp_sk(bestsk)->mptcp->path_index == mpcb->dfin_path_index && -+ mptcp_is_available(bestsk, skb, zero_wnd_test)) -+ return bestsk; -+ } -+ } -+ -+ /* First, find the overall best subflow */ -+ mptcp_for_each_sub(mpcb, mptcp) { -+ bestsk = mptcp_to_sock(mptcp); -+ besttp = tcp_sk(bestsk); -+ blest_p = blestsched_get_priv(besttp); -+ -+ /* Set of states for which we are allowed to send data */ -+ if (!mptcp_sk_can_send(bestsk)) -+ continue; -+ -+ /* We do not send data on this subflow unless it is -+ * fully established, i.e. the 4th ack has been received. -+ */ -+ if (besttp->mptcp->pre_established) -+ continue; -+ -+ blest_p->min_srtt_us = min(blest_p->min_srtt_us, besttp->srtt_us); -+ blest_p->max_srtt_us = max(blest_p->max_srtt_us, besttp->srtt_us); -+ -+ /* record minimal rtt */ -+ if (besttp->srtt_us < min_srtt) { -+ min_srtt = besttp->srtt_us; -+ minsk = bestsk; -+ } -+ } -+ -+ /* find the current best subflow according to the default scheduler */ -+ bestsk = get_available_subflow(meta_sk, skb, zero_wnd_test); -+ -+ /* if we decided to use a slower flow, we have the option of not using it at all */ -+ if (bestsk && minsk && bestsk != minsk) { -+ u32 slow_linger_time, fast_bytes, slow_inflight_bytes, slow_bytes, avail_space; -+ u32 buffered_bytes = 0; -+ -+ meta_tp = tcp_sk(meta_sk); -+ besttp = tcp_sk(bestsk); -+ -+ blestsched_update_lambda(meta_sk, bestsk); -+ -+ /* if we send this SKB now, it will be acked in besttp->srtt seconds -+ * during this time: how many bytes will we send on the fast flow? -+ */ -+ slow_linger_time = blestsched_estimate_linger_time(bestsk); -+ fast_bytes = blestsched_estimate_bytes(minsk, slow_linger_time); -+ -+ if (skb) -+ buffered_bytes = skb->len; -+ -+ /* is the required space available in the mptcp meta send window? -+ * we assume that all bytes inflight on the slow path will be acked in besttp->srtt seconds -+ * (just like the SKB if it was sent now) -> that means that those inflight bytes will -+ * keep occupying space in the meta window until then -+ */ -+ slow_inflight_bytes = besttp->write_seq - besttp->snd_una; -+ slow_bytes = buffered_bytes + slow_inflight_bytes; // bytes of this SKB plus those in flight already -+ -+ avail_space = (slow_bytes < meta_tp->snd_wnd) ? (meta_tp->snd_wnd - slow_bytes) : 0; -+ -+ if (fast_bytes > avail_space) { -+ /* sending this SKB on the slow flow means -+ * we wouldn't be able to send all the data we'd like to send on the fast flow -+ * so don't do that -+ */ -+ return NULL; -+ } -+ } -+ -+ return bestsk; -+} -+ -+/* copy from mptcp_sched.c: mptcp_rcv_buf_optimization */ -+static struct sk_buff *mptcp_blest_rcv_buf_optimization(struct sock *sk, int penal) -+{ -+ struct sock *meta_sk; -+ const struct tcp_sock *tp = tcp_sk(sk); -+ struct mptcp_tcp_sock *mptcp; -+ struct sk_buff *skb_head; -+ struct blestsched_priv *blest_p = blestsched_get_priv(tp); -+ struct blestsched_cb *blest_cb; -+ -+ meta_sk = mptcp_meta_sk(sk); -+ skb_head = tcp_rtx_queue_head(meta_sk); -+ -+ if (!skb_head) -+ return NULL; -+ -+ /* If penalization is optional (coming from mptcp_next_segment() and -+ * We are not send-buffer-limited we do not penalize. The retransmission -+ * is just an optimization to fix the idle-time due to the delay before -+ * we wake up the application. -+ */ -+ if (!penal && sk_stream_memory_free(meta_sk)) -+ goto retrans; -+ -+ /* Record the occurrence of a retransmission to update the lambda value */ -+ blest_cb = blestsched_get_cb(tcp_sk(meta_sk)); -+ blest_cb->retrans_flag = true; -+ -+ /* Only penalize again after an RTT has elapsed */ -+ if (tcp_jiffies32 - blest_p->last_rbuf_opti < usecs_to_jiffies(tp->srtt_us >> 3)) -+ goto retrans; -+ -+ /* Half the cwnd of the slow flows */ -+ mptcp_for_each_sub(tp->mpcb, mptcp) { -+ struct tcp_sock *tp_it = mptcp->tp; -+ -+ if (tp_it != tp && -+ TCP_SKB_CB(skb_head)->path_mask & mptcp_pi_to_flag(tp_it->mptcp->path_index)) { -+ if (tp->srtt_us < tp_it->srtt_us && inet_csk((struct sock *)tp_it)->icsk_ca_state == TCP_CA_Open) { -+ u32 prior_cwnd = tp_it->snd_cwnd; -+ -+ tp_it->snd_cwnd = max(tp_it->snd_cwnd >> 1U, 1U); -+ -+ /* If in slow start, do not reduce the ssthresh */ -+ if (prior_cwnd >= tp_it->snd_ssthresh) -+ tp_it->snd_ssthresh = max(tp_it->snd_ssthresh >> 1U, 2U); -+ -+ blest_p->last_rbuf_opti = tcp_jiffies32; -+ } -+ } -+ } -+ -+retrans: -+ -+ /* Segment not yet injected into this path? Take it!!! */ -+ if (!(TCP_SKB_CB(skb_head)->path_mask & mptcp_pi_to_flag(tp->mptcp->path_index))) { -+ bool do_retrans = false; -+ mptcp_for_each_sub(tp->mpcb, mptcp) { -+ struct tcp_sock *tp_it = mptcp->tp; -+ -+ if (tp_it != tp && -+ TCP_SKB_CB(skb_head)->path_mask & mptcp_pi_to_flag(tp_it->mptcp->path_index)) { -+ if (tp_it->snd_cwnd <= 4) { -+ do_retrans = true; -+ break; -+ } -+ -+ if (4 * tp->srtt_us >= tp_it->srtt_us) { -+ do_retrans = false; -+ break; -+ } else { -+ do_retrans = true; -+ } -+ } -+ } -+ -+ if (do_retrans && mptcp_is_available(sk, skb_head, false)) { -+ trace_mptcp_retransmit(sk, skb_head); -+ return skb_head; -+ } -+ } -+ return NULL; -+} -+ -+/* copy from mptcp_sched.c: __mptcp_next_segment */ -+/* Returns the next segment to be sent from the mptcp meta-queue. -+ * (chooses the reinject queue if any segment is waiting in it, otherwise, -+ * chooses the normal write queue). -+ * Sets *@reinject to 1 if the returned segment comes from the -+ * reinject queue. Sets it to 0 if it is the regular send-head of the meta-sk, -+ * and sets it to -1 if it is a meta-level retransmission to optimize the -+ * receive-buffer. -+ */ -+static struct sk_buff *__mptcp_blest_next_segment(struct sock *meta_sk, int *reinject) -+{ -+ const struct mptcp_cb *mpcb = tcp_sk(meta_sk)->mpcb; -+ struct sk_buff *skb = NULL; -+ -+ *reinject = 0; -+ -+ /* If we are in fallback-mode, just take from the meta-send-queue */ -+ if (mpcb->infinite_mapping_snd || mpcb->send_infinite_mapping) -+ return tcp_send_head(meta_sk); -+ -+ skb = skb_peek(&mpcb->reinject_queue); -+ -+ if (skb) { -+ *reinject = 1; -+ } else { -+ skb = tcp_send_head(meta_sk); -+ -+ if (!skb && meta_sk->sk_socket && -+ test_bit(SOCK_NOSPACE, &meta_sk->sk_socket->flags) && -+ sk_stream_wspace(meta_sk) < sk_stream_min_wspace(meta_sk)) { -+ struct sock *subsk = blest_get_available_subflow(meta_sk, NULL, -+ false); -+ if (!subsk) -+ return NULL; -+ -+ skb = mptcp_blest_rcv_buf_optimization(subsk, 0); -+ if (skb) -+ *reinject = -1; -+ } -+ } -+ return skb; -+} -+ -+/* copy from mptcp_sched.c: mptcp_next_segment */ -+static struct sk_buff *mptcp_blest_next_segment(struct sock *meta_sk, -+ int *reinject, -+ struct sock **subsk, -+ unsigned int *limit) -+{ -+ struct sk_buff *skb = __mptcp_blest_next_segment(meta_sk, reinject); -+ unsigned int mss_now; -+ struct tcp_sock *subtp; -+ u16 gso_max_segs; -+ u32 max_len, max_segs, window, needed; -+ -+ /* As we set it, we have to reset it as well. */ -+ *limit = 0; -+ -+ if (!skb) -+ return NULL; -+ -+ *subsk = blest_get_available_subflow(meta_sk, skb, false); -+ if (!*subsk) -+ return NULL; -+ -+ subtp = tcp_sk(*subsk); -+ mss_now = tcp_current_mss(*subsk); -+ -+ if (!*reinject && unlikely(!tcp_snd_wnd_test(tcp_sk(meta_sk), skb, mss_now))) { -+ skb = mptcp_blest_rcv_buf_optimization(*subsk, 1); -+ if (skb) -+ *reinject = -1; -+ else -+ return NULL; -+ } -+ -+ /* No splitting required, as we will only send one single segment */ -+ if (skb->len <= mss_now) -+ return skb; -+ -+ /* The following is similar to tcp_mss_split_point, but -+ * we do not care about nagle, because we will anyways -+ * use TCP_NAGLE_PUSH, which overrides this. -+ * -+ * So, we first limit according to the cwnd/gso-size and then according -+ * to the subflow's window. -+ */ -+ -+ gso_max_segs = (*subsk)->sk_gso_max_segs; -+ if (!gso_max_segs) /* No gso supported on the subflow's NIC */ -+ gso_max_segs = 1; -+ max_segs = min_t(unsigned int, tcp_cwnd_test(subtp, skb), gso_max_segs); -+ if (!max_segs) -+ return NULL; -+ -+ max_len = mss_now * max_segs; -+ window = tcp_wnd_end(subtp) - subtp->write_seq; -+ -+ needed = min(skb->len, window); -+ if (max_len <= skb->len) -+ /* Take max_win, which is actually the cwnd/gso-size */ -+ *limit = max_len; -+ else -+ /* Or, take the window */ -+ *limit = needed; -+ -+ return skb; -+} -+ -+static void blestsched_init(struct sock *sk) -+{ -+ struct blestsched_priv *blest_p = blestsched_get_priv(tcp_sk(sk)); -+ struct blestsched_cb *blest_cb = blestsched_get_cb(tcp_sk(mptcp_meta_sk(sk))); -+ -+ blest_p->last_rbuf_opti = tcp_jiffies32; -+ blest_p->min_srtt_us = U32_MAX; -+ blest_p->max_srtt_us = 0; -+ -+ if (!blest_cb->lambda_1000) { -+ blest_cb->lambda_1000 = lambda * 100; -+ blest_cb->last_lambda_update = tcp_jiffies32; -+ } -+} -+ -+static struct mptcp_sched_ops mptcp_sched_blest = { -+ .get_subflow = blest_get_available_subflow, -+ .next_segment = mptcp_blest_next_segment, -+ .init = blestsched_init, -+ .name = "blest", -+ .owner = THIS_MODULE, -+}; -+ -+static int __init blest_register(void) -+{ -+ BUILD_BUG_ON(sizeof(struct blestsched_priv) > MPTCP_SCHED_SIZE); -+ BUILD_BUG_ON(sizeof(struct blestsched_cb) > MPTCP_SCHED_DATA_SIZE); -+ -+ if (mptcp_register_scheduler(&mptcp_sched_blest)) -+ return -1; -+ -+ return 0; -+} -+ -+static void blest_unregister(void) -+{ -+ mptcp_unregister_scheduler(&mptcp_sched_blest); -+} -+ -+module_init(blest_register); -+module_exit(blest_unregister); -+ -+MODULE_AUTHOR("Simone Ferlin, Daniel Weber"); -+MODULE_LICENSE("GPL"); -+MODULE_DESCRIPTION("BLEST scheduler for MPTCP, based on default minimum RTT scheduler"); -+MODULE_VERSION("0.95"); -diff -aurN linux-4.19.104/net/mptcp/mptcp_coupled.c mptcp-mptcp_v0.95/net/mptcp/mptcp_coupled.c ---- linux-4.19.104/net/mptcp/mptcp_coupled.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_v0.95/net/mptcp/mptcp_coupled.c 2020-02-17 11:29:55.000000000 +0100 -@@ -0,0 +1,262 @@ -+/* -+ * MPTCP implementation - Linked Increase congestion control Algorithm (LIA) -+ * -+ * Initial Design & Implementation: -+ * Sébastien Barré -+ * -+ * Current Maintainer & Author: -+ * Christoph Paasch -+ * -+ * Additional authors: -+ * Jaakko Korkeaniemi -+ * Gregory Detal -+ * Fabien Duchêne -+ * Andreas Seelinger -+ * Lavkesh Lahngir -+ * Andreas Ripke -+ * Vlad Dogaru -+ * Octavian Purdila -+ * John Ronan -+ * Catalin Nicutar -+ * Brandon Heller -+ * -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version -+ * 2 of the License, or (at your option) any later version. -+ */ -+#include -+#include -+ -+#include -+ -+/* Scaling is done in the numerator with alpha_scale_num and in the denominator -+ * with alpha_scale_den. -+ * -+ * To downscale, we just need to use alpha_scale. -+ * -+ * We have: alpha_scale = alpha_scale_num / (alpha_scale_den ^ 2) -+ */ -+static int alpha_scale_den = 10; -+static int alpha_scale_num = 32; -+static int alpha_scale = 12; -+ -+struct mptcp_ccc { -+ u64 alpha; -+ bool forced_update; -+}; -+ -+static inline int mptcp_ccc_sk_can_send(const struct sock *sk) -+{ -+ return mptcp_sk_can_send(sk) && tcp_sk(sk)->srtt_us; -+} -+ -+static inline u64 mptcp_get_alpha(const struct sock *meta_sk) -+{ -+ return ((struct mptcp_ccc *)inet_csk_ca(meta_sk))->alpha; -+} -+ -+static inline void mptcp_set_alpha(const struct sock *meta_sk, u64 alpha) -+{ -+ ((struct mptcp_ccc *)inet_csk_ca(meta_sk))->alpha = alpha; -+} -+ -+static inline u64 mptcp_ccc_scale(u32 val, int scale) -+{ -+ return (u64) val << scale; -+} -+ -+static inline bool mptcp_get_forced(const struct sock *meta_sk) -+{ -+ return ((struct mptcp_ccc *)inet_csk_ca(meta_sk))->forced_update; -+} -+ -+static inline void mptcp_set_forced(const struct sock *meta_sk, bool force) -+{ -+ ((struct mptcp_ccc *)inet_csk_ca(meta_sk))->forced_update = force; -+} -+ -+static void mptcp_ccc_recalc_alpha(const struct sock *sk) -+{ -+ const struct mptcp_cb *mpcb = tcp_sk(sk)->mpcb; -+ const struct mptcp_tcp_sock *mptcp; -+ int best_cwnd = 0, best_rtt = 0, can_send = 0; -+ u64 max_numerator = 0, sum_denominator = 0, alpha = 1; -+ -+ if (!mpcb) -+ return; -+ -+ /* Do regular alpha-calculation for multiple subflows */ -+ -+ /* Find the max numerator of the alpha-calculation */ -+ mptcp_for_each_sub(mpcb, mptcp) { -+ const struct sock *sub_sk = mptcp_to_sock(mptcp); -+ struct tcp_sock *sub_tp = tcp_sk(sub_sk); -+ u64 tmp; -+ -+ if (!mptcp_ccc_sk_can_send(sub_sk)) -+ continue; -+ -+ can_send++; -+ -+ /* We need to look for the path, that provides the max-value. -+ * Integer-overflow is not possible here, because -+ * tmp will be in u64. -+ */ -+ tmp = div64_u64(mptcp_ccc_scale(sub_tp->snd_cwnd, -+ alpha_scale_num), (u64)sub_tp->srtt_us * sub_tp->srtt_us); -+ -+ if (tmp >= max_numerator) { -+ max_numerator = tmp; -+ best_cwnd = sub_tp->snd_cwnd; -+ best_rtt = sub_tp->srtt_us; -+ } -+ } -+ -+ /* No subflow is able to send - we don't care anymore */ -+ if (unlikely(!can_send)) -+ goto exit; -+ -+ /* Calculate the denominator */ -+ mptcp_for_each_sub(mpcb, mptcp) { -+ const struct sock *sub_sk = mptcp_to_sock(mptcp); -+ struct tcp_sock *sub_tp = tcp_sk(sub_sk); -+ -+ if (!mptcp_ccc_sk_can_send(sub_sk)) -+ continue; -+ -+ sum_denominator += div_u64( -+ mptcp_ccc_scale(sub_tp->snd_cwnd, -+ alpha_scale_den) * best_rtt, -+ sub_tp->srtt_us); -+ } -+ sum_denominator *= sum_denominator; -+ if (unlikely(!sum_denominator)) { -+ pr_err("%s: sum_denominator == 0\n", __func__); -+ mptcp_for_each_sub(mpcb, mptcp) { -+ const struct sock *sub_sk = mptcp_to_sock(mptcp); -+ struct tcp_sock *sub_tp = tcp_sk(sub_sk); -+ pr_err("%s: pi:%d, state:%d\n, rtt:%u, cwnd: %u", -+ __func__, sub_tp->mptcp->path_index, -+ sub_sk->sk_state, sub_tp->srtt_us, -+ sub_tp->snd_cwnd); -+ } -+ } -+ -+ alpha = div64_u64(mptcp_ccc_scale(best_cwnd, alpha_scale_num), sum_denominator); -+ -+ if (unlikely(!alpha)) -+ alpha = 1; -+ -+exit: -+ mptcp_set_alpha(mptcp_meta_sk(sk), alpha); -+} -+ -+static void mptcp_ccc_init(struct sock *sk) -+{ -+ if (mptcp(tcp_sk(sk))) { -+ mptcp_set_forced(mptcp_meta_sk(sk), 0); -+ mptcp_set_alpha(mptcp_meta_sk(sk), 1); -+ } -+ /* If we do not mptcp, behave like reno: return */ -+} -+ -+static void mptcp_ccc_cwnd_event(struct sock *sk, enum tcp_ca_event event) -+{ -+ if (event == CA_EVENT_LOSS) -+ mptcp_ccc_recalc_alpha(sk); -+} -+ -+static void mptcp_ccc_set_state(struct sock *sk, u8 ca_state) -+{ -+ if (!mptcp(tcp_sk(sk))) -+ return; -+ -+ mptcp_set_forced(mptcp_meta_sk(sk), 1); -+} -+ -+static void mptcp_ccc_cong_avoid(struct sock *sk, u32 ack, u32 acked) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ int snd_cwnd; -+ u64 alpha; -+ -+ if (!mptcp(tp)) { -+ tcp_reno_cong_avoid(sk, ack, acked); -+ return; -+ } -+ -+ if (!tcp_is_cwnd_limited(sk)) -+ return; -+ -+ if (tcp_in_slow_start(tp)) { -+ /* In "safe" area, increase. */ -+ tcp_slow_start(tp, acked); -+ mptcp_ccc_recalc_alpha(sk); -+ return; -+ } -+ -+ if (mptcp_get_forced(mptcp_meta_sk(sk))) { -+ mptcp_ccc_recalc_alpha(sk); -+ mptcp_set_forced(mptcp_meta_sk(sk), 0); -+ } -+ -+ alpha = mptcp_get_alpha(mptcp_meta_sk(sk)); -+ -+ /* This may happen, if at the initialization, the mpcb -+ * was not yet attached to the sock, and thus -+ * initializing alpha failed. -+ */ -+ if (unlikely(!alpha)) -+ alpha = 1; -+ -+ snd_cwnd = (int)div_u64((u64)mptcp_ccc_scale(1, alpha_scale), alpha); -+ -+ /* snd_cwnd_cnt >= max (scale * tot_cwnd / alpha, cwnd) -+ * Thus, we select here the max value. -+ */ -+ if (snd_cwnd < tp->snd_cwnd) -+ snd_cwnd = tp->snd_cwnd; -+ -+ if (tp->snd_cwnd_cnt >= snd_cwnd) { -+ if (tp->snd_cwnd < tp->snd_cwnd_clamp) { -+ tp->snd_cwnd++; -+ mptcp_ccc_recalc_alpha(sk); -+ } -+ -+ tp->snd_cwnd_cnt = 0; -+ } else { -+ tp->snd_cwnd_cnt++; -+ } -+} -+ -+static struct tcp_congestion_ops mptcp_ccc = { -+ .init = mptcp_ccc_init, -+ .ssthresh = tcp_reno_ssthresh, -+ .cong_avoid = mptcp_ccc_cong_avoid, -+ .undo_cwnd = tcp_reno_undo_cwnd, -+ .cwnd_event = mptcp_ccc_cwnd_event, -+ .set_state = mptcp_ccc_set_state, -+ .owner = THIS_MODULE, -+ .name = "lia", -+}; -+ -+static int __init mptcp_ccc_register(void) -+{ -+ BUILD_BUG_ON(sizeof(struct mptcp_ccc) > ICSK_CA_PRIV_SIZE); -+ return tcp_register_congestion_control(&mptcp_ccc); -+} -+ -+static void __exit mptcp_ccc_unregister(void) -+{ -+ tcp_unregister_congestion_control(&mptcp_ccc); -+} -+ -+module_init(mptcp_ccc_register); -+module_exit(mptcp_ccc_unregister); -+ -+MODULE_AUTHOR("Christoph Paasch, Sébastien Barré"); -+MODULE_LICENSE("GPL"); -+MODULE_DESCRIPTION("MPTCP LINKED INCREASE CONGESTION CONTROL ALGORITHM"); -+MODULE_VERSION("0.1"); -diff -aurN linux-4.19.104/net/mptcp/mptcp_ctrl.c mptcp-mptcp_v0.95/net/mptcp/mptcp_ctrl.c ---- linux-4.19.104/net/mptcp/mptcp_ctrl.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_v0.95/net/mptcp/mptcp_ctrl.c 2020-02-17 11:29:55.000000000 +0100 -@@ -0,0 +1,3140 @@ -+/* -+ * MPTCP implementation - MPTCP-control -+ * -+ * Initial Design & Implementation: -+ * Sébastien Barré -+ * -+ * Current Maintainer & Author: -+ * Christoph Paasch -+ * -+ * Additional authors: -+ * Jaakko Korkeaniemi -+ * Gregory Detal -+ * Fabien Duchêne -+ * Andreas Seelinger -+ * Lavkesh Lahngir -+ * Andreas Ripke -+ * Vlad Dogaru -+ * Octavian Purdila -+ * John Ronan -+ * Catalin Nicutar -+ * Brandon Heller -+ * -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version -+ * 2 of the License, or (at your option) any later version. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#if IS_ENABLED(CONFIG_IPV6) -+#include -+#include -+#endif -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+static struct kmem_cache *mptcp_sock_cache __read_mostly; -+static struct kmem_cache *mptcp_cb_cache __read_mostly; -+static struct kmem_cache *mptcp_tw_cache __read_mostly; -+ -+int sysctl_mptcp_enabled __read_mostly = 1; -+int sysctl_mptcp_version __read_mostly = 0; -+static int min_mptcp_version; -+static int max_mptcp_version = 1; -+int sysctl_mptcp_checksum __read_mostly = 1; -+int sysctl_mptcp_debug __read_mostly; -+EXPORT_SYMBOL(sysctl_mptcp_debug); -+int sysctl_mptcp_syn_retries __read_mostly = 3; -+ -+bool mptcp_init_failed __read_mostly; -+ -+struct static_key mptcp_static_key = STATIC_KEY_INIT_FALSE; -+EXPORT_SYMBOL(mptcp_static_key); -+ -+static void mptcp_key_sha1(u64 key, u32 *token, u64 *idsn); -+ -+static int proc_mptcp_path_manager(struct ctl_table *ctl, int write, -+ void __user *buffer, size_t *lenp, -+ loff_t *ppos) -+{ -+ char val[MPTCP_PM_NAME_MAX]; -+ struct ctl_table tbl = { -+ .data = val, -+ .maxlen = MPTCP_PM_NAME_MAX, -+ }; -+ int ret; -+ -+ mptcp_get_default_path_manager(val); -+ -+ ret = proc_dostring(&tbl, write, buffer, lenp, ppos); -+ if (write && ret == 0) -+ ret = mptcp_set_default_path_manager(val); -+ return ret; -+} -+ -+static int proc_mptcp_scheduler(struct ctl_table *ctl, int write, -+ void __user *buffer, size_t *lenp, -+ loff_t *ppos) -+{ -+ char val[MPTCP_SCHED_NAME_MAX]; -+ struct ctl_table tbl = { -+ .data = val, -+ .maxlen = MPTCP_SCHED_NAME_MAX, -+ }; -+ int ret; -+ -+ mptcp_get_default_scheduler(val); -+ -+ ret = proc_dostring(&tbl, write, buffer, lenp, ppos); -+ if (write && ret == 0) -+ ret = mptcp_set_default_scheduler(val); -+ return ret; -+} -+ -+static struct ctl_table mptcp_table[] = { -+ { -+ .procname = "mptcp_enabled", -+ .data = &sysctl_mptcp_enabled, -+ .maxlen = sizeof(int), -+ .mode = 0644, -+ .proc_handler = &proc_dointvec -+ }, -+ { -+ .procname = "mptcp_version", -+ .data = &sysctl_mptcp_version, -+ .mode = 0644, -+ .maxlen = sizeof(int), -+ .proc_handler = &proc_dointvec_minmax, -+ .extra1 = &min_mptcp_version, -+ .extra2 = &max_mptcp_version, -+ }, -+ { -+ .procname = "mptcp_checksum", -+ .data = &sysctl_mptcp_checksum, -+ .maxlen = sizeof(int), -+ .mode = 0644, -+ .proc_handler = &proc_dointvec -+ }, -+ { -+ .procname = "mptcp_debug", -+ .data = &sysctl_mptcp_debug, -+ .maxlen = sizeof(int), -+ .mode = 0644, -+ .proc_handler = &proc_dointvec -+ }, -+ { -+ .procname = "mptcp_syn_retries", -+ .data = &sysctl_mptcp_syn_retries, -+ .maxlen = sizeof(int), -+ .mode = 0644, -+ .proc_handler = &proc_dointvec -+ }, -+ { -+ .procname = "mptcp_path_manager", -+ .mode = 0644, -+ .maxlen = MPTCP_PM_NAME_MAX, -+ .proc_handler = proc_mptcp_path_manager, -+ }, -+ { -+ .procname = "mptcp_scheduler", -+ .mode = 0644, -+ .maxlen = MPTCP_SCHED_NAME_MAX, -+ .proc_handler = proc_mptcp_scheduler, -+ }, -+ { } -+}; -+ -+static inline u32 mptcp_hash_tk(u32 token) -+{ -+ return token % MPTCP_HASH_SIZE; -+} -+ -+struct hlist_nulls_head tk_hashtable[MPTCP_HASH_SIZE]; -+EXPORT_SYMBOL(tk_hashtable); -+ -+/* The following hash table is used to avoid collision of token */ -+static struct hlist_nulls_head mptcp_reqsk_tk_htb[MPTCP_HASH_SIZE]; -+ -+/* Lock, protecting the two hash-tables that hold the token. Namely, -+ * mptcp_reqsk_tk_htb and tk_hashtable -+ */ -+static spinlock_t mptcp_tk_hashlock; -+ -+static bool mptcp_reqsk_find_tk(const u32 token) -+{ -+ const u32 hash = mptcp_hash_tk(token); -+ const struct mptcp_request_sock *mtreqsk; -+ const struct hlist_nulls_node *node; -+ -+begin: -+ hlist_nulls_for_each_entry_rcu(mtreqsk, node, -+ &mptcp_reqsk_tk_htb[hash], hash_entry) { -+ if (token == mtreqsk->mptcp_loc_token) -+ return true; -+ } -+ /* A request-socket is destroyed by RCU. So, it might have been recycled -+ * and put into another hash-table list. So, after the lookup we may -+ * end up in a different list. So, we may need to restart. -+ * -+ * See also the comment in __inet_lookup_established. -+ */ -+ if (get_nulls_value(node) != hash) -+ goto begin; -+ return false; -+} -+ -+static void mptcp_reqsk_insert_tk(struct request_sock *reqsk, const u32 token) -+{ -+ u32 hash = mptcp_hash_tk(token); -+ -+ hlist_nulls_add_head_rcu(&mptcp_rsk(reqsk)->hash_entry, -+ &mptcp_reqsk_tk_htb[hash]); -+} -+ -+static void mptcp_reqsk_remove_tk(const struct request_sock *reqsk) -+{ -+ rcu_read_lock(); -+ local_bh_disable(); -+ spin_lock(&mptcp_tk_hashlock); -+ hlist_nulls_del_init_rcu(&mptcp_rsk(reqsk)->hash_entry); -+ spin_unlock(&mptcp_tk_hashlock); -+ local_bh_enable(); -+ rcu_read_unlock(); -+} -+ -+void mptcp_reqsk_destructor(struct request_sock *req) -+{ -+ if (!mptcp_rsk(req)->is_sub) -+ mptcp_reqsk_remove_tk(req); -+} -+ -+static void __mptcp_hash_insert(struct tcp_sock *meta_tp, const u32 token) -+{ -+ u32 hash = mptcp_hash_tk(token); -+ hlist_nulls_add_head_rcu(&meta_tp->tk_table, &tk_hashtable[hash]); -+ meta_tp->inside_tk_table = 1; -+} -+ -+static bool mptcp_find_token(u32 token) -+{ -+ const u32 hash = mptcp_hash_tk(token); -+ const struct tcp_sock *meta_tp; -+ const struct hlist_nulls_node *node; -+ -+begin: -+ hlist_nulls_for_each_entry_rcu(meta_tp, node, &tk_hashtable[hash], tk_table) { -+ if (token == meta_tp->mptcp_loc_token) -+ return true; -+ } -+ /* A TCP-socket is destroyed by RCU. So, it might have been recycled -+ * and put into another hash-table list. So, after the lookup we may -+ * end up in a different list. So, we may need to restart. -+ * -+ * See also the comment in __inet_lookup_established. -+ */ -+ if (get_nulls_value(node) != hash) -+ goto begin; -+ return false; -+} -+ -+static void mptcp_set_key_reqsk(struct request_sock *req, -+ const struct sk_buff *skb, -+ u32 seed) -+{ -+ const struct inet_request_sock *ireq = inet_rsk(req); -+ struct mptcp_request_sock *mtreq = mptcp_rsk(req); -+ -+ if (skb->protocol == htons(ETH_P_IP)) { -+ mtreq->mptcp_loc_key = mptcp_v4_get_key(ip_hdr(skb)->saddr, -+ ip_hdr(skb)->daddr, -+ htons(ireq->ir_num), -+ ireq->ir_rmt_port, -+ seed); -+#if IS_ENABLED(CONFIG_IPV6) -+ } else { -+ mtreq->mptcp_loc_key = mptcp_v6_get_key(ipv6_hdr(skb)->saddr.s6_addr32, -+ ipv6_hdr(skb)->daddr.s6_addr32, -+ htons(ireq->ir_num), -+ ireq->ir_rmt_port, -+ seed); -+#endif -+ } -+ -+ mptcp_key_sha1(mtreq->mptcp_loc_key, &mtreq->mptcp_loc_token, NULL); -+} -+ -+/* New MPTCP-connection request, prepare a new token for the meta-socket that -+ * will be created in mptcp_check_req_master(), and store the received token. -+ */ -+static void mptcp_reqsk_new_mptcp(struct request_sock *req, -+ const struct sock *sk, -+ const struct mptcp_options_received *mopt, -+ const struct sk_buff *skb) -+{ -+ struct mptcp_request_sock *mtreq = mptcp_rsk(req); -+ const struct tcp_sock *tp = tcp_sk(sk); -+ -+ inet_rsk(req)->saw_mpc = 1; -+ -+ /* MPTCP version agreement */ -+ if (mopt->mptcp_ver >= tp->mptcp_ver) -+ mtreq->mptcp_ver = tp->mptcp_ver; -+ else -+ mtreq->mptcp_ver = mopt->mptcp_ver; -+ -+ rcu_read_lock(); -+ local_bh_disable(); -+ spin_lock(&mptcp_tk_hashlock); -+ do { -+ mptcp_set_key_reqsk(req, skb, mptcp_seed++); -+ } while (mptcp_reqsk_find_tk(mtreq->mptcp_loc_token) || -+ mptcp_find_token(mtreq->mptcp_loc_token)); -+ mptcp_reqsk_insert_tk(req, mtreq->mptcp_loc_token); -+ spin_unlock(&mptcp_tk_hashlock); -+ local_bh_enable(); -+ rcu_read_unlock(); -+ mtreq->mptcp_rem_key = mopt->mptcp_sender_key; -+} -+ -+static int mptcp_reqsk_new_cookie(struct request_sock *req, -+ const struct sock *sk, -+ const struct mptcp_options_received *mopt, -+ const struct sk_buff *skb) -+{ -+ struct mptcp_request_sock *mtreq = mptcp_rsk(req); -+ -+ /* MPTCP version agreement */ -+ if (mopt->mptcp_ver >= tcp_sk(sk)->mptcp_ver) -+ mtreq->mptcp_ver = tcp_sk(sk)->mptcp_ver; -+ else -+ mtreq->mptcp_ver = mopt->mptcp_ver; -+ -+ rcu_read_lock(); -+ local_bh_disable(); -+ spin_lock(&mptcp_tk_hashlock); -+ -+ mptcp_set_key_reqsk(req, skb, tcp_rsk(req)->snt_isn); -+ -+ if (mptcp_reqsk_find_tk(mtreq->mptcp_loc_token) || -+ mptcp_find_token(mtreq->mptcp_loc_token)) { -+ spin_unlock(&mptcp_tk_hashlock); -+ local_bh_enable(); -+ rcu_read_unlock(); -+ return false; -+ } -+ -+ inet_rsk(req)->saw_mpc = 1; -+ -+ spin_unlock(&mptcp_tk_hashlock); -+ local_bh_enable(); -+ rcu_read_unlock(); -+ -+ mtreq->mptcp_rem_key = mopt->mptcp_sender_key; -+ -+ return true; -+} -+ -+static void mptcp_set_key_sk(const struct sock *sk) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ const struct inet_sock *isk = inet_sk(sk); -+ -+ if (sk->sk_family == AF_INET) -+ tp->mptcp_loc_key = mptcp_v4_get_key(isk->inet_saddr, -+ isk->inet_daddr, -+ isk->inet_sport, -+ isk->inet_dport, -+ mptcp_seed++); -+#if IS_ENABLED(CONFIG_IPV6) -+ else -+ tp->mptcp_loc_key = mptcp_v6_get_key(inet6_sk(sk)->saddr.s6_addr32, -+ sk->sk_v6_daddr.s6_addr32, -+ isk->inet_sport, -+ isk->inet_dport, -+ mptcp_seed++); -+#endif -+ -+ mptcp_key_sha1(tp->mptcp_loc_key, -+ &tp->mptcp_loc_token, NULL); -+} -+ -+#ifdef CONFIG_JUMP_LABEL -+static atomic_t mptcp_needed_deferred; -+static atomic_t mptcp_wanted; -+ -+static void mptcp_clear(struct work_struct *work) -+{ -+ int deferred = atomic_xchg(&mptcp_needed_deferred, 0); -+ int wanted; -+ -+ wanted = atomic_add_return(deferred, &mptcp_wanted); -+ if (wanted > 0) -+ static_key_enable(&mptcp_static_key); -+ else -+ static_key_disable(&mptcp_static_key); -+} -+ -+static DECLARE_WORK(mptcp_work, mptcp_clear); -+#endif -+ -+static void mptcp_enable_static_key_bh(void) -+{ -+#ifdef CONFIG_JUMP_LABEL -+ int wanted; -+ -+ while (1) { -+ wanted = atomic_read(&mptcp_wanted); -+ if (wanted <= 0) -+ break; -+ if (atomic_cmpxchg(&mptcp_wanted, wanted, wanted + 1) == wanted) -+ return; -+ } -+ atomic_inc(&mptcp_needed_deferred); -+ schedule_work(&mptcp_work); -+#else -+ static_key_slow_inc(&mptcp_static_key); -+#endif -+} -+ -+static void mptcp_enable_static_key(void) -+{ -+#ifdef CONFIG_JUMP_LABEL -+ atomic_inc(&mptcp_wanted); -+ static_key_enable(&mptcp_static_key); -+#else -+ static_key_slow_inc(&mptcp_static_key); -+#endif -+} -+ -+void mptcp_disable_static_key(void) -+{ -+#ifdef CONFIG_JUMP_LABEL -+ int wanted; -+ -+ while (1) { -+ wanted = atomic_read(&mptcp_wanted); -+ if (wanted <= 1) -+ break; -+ if (atomic_cmpxchg(&mptcp_wanted, wanted, wanted - 1) == wanted) -+ return; -+ } -+ atomic_dec(&mptcp_needed_deferred); -+ schedule_work(&mptcp_work); -+#else -+ static_key_slow_dec(&mptcp_static_key); -+#endif -+} -+ -+void mptcp_enable_sock(struct sock *sk) -+{ -+ if (!sock_flag(sk, SOCK_MPTCP)) { -+ sock_set_flag(sk, SOCK_MPTCP); -+ tcp_sk(sk)->mptcp_ver = sysctl_mptcp_version; -+ -+ /* Necessary here, because MPTCP can be enabled/disabled through -+ * a setsockopt. -+ */ -+ if (sk->sk_family == AF_INET) -+ inet_csk(sk)->icsk_af_ops = &mptcp_v4_specific; -+#if IS_ENABLED(CONFIG_IPV6) -+ else if (mptcp_v6_is_v4_mapped(sk)) -+ inet_csk(sk)->icsk_af_ops = &mptcp_v6_mapped; -+ else -+ inet_csk(sk)->icsk_af_ops = &mptcp_v6_specific; -+#endif -+ -+ mptcp_enable_static_key(); -+ } -+} -+ -+void mptcp_disable_sock(struct sock *sk) -+{ -+ if (sock_flag(sk, SOCK_MPTCP)) { -+ sock_reset_flag(sk, SOCK_MPTCP); -+ -+ /* Necessary here, because MPTCP can be enabled/disabled through -+ * a setsockopt. -+ */ -+ if (sk->sk_family == AF_INET) -+ inet_csk(sk)->icsk_af_ops = &ipv4_specific; -+#if IS_ENABLED(CONFIG_IPV6) -+ else if (mptcp_v6_is_v4_mapped(sk)) -+ inet_csk(sk)->icsk_af_ops = &ipv6_mapped; -+ else -+ inet_csk(sk)->icsk_af_ops = &ipv6_specific; -+#endif -+ -+ mptcp_disable_static_key(); -+ } -+} -+ -+void mptcp_connect_init(struct sock *sk) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ -+ rcu_read_lock(); -+ local_bh_disable(); -+ spin_lock(&mptcp_tk_hashlock); -+ do { -+ mptcp_set_key_sk(sk); -+ } while (mptcp_reqsk_find_tk(tp->mptcp_loc_token) || -+ mptcp_find_token(tp->mptcp_loc_token)); -+ -+ __mptcp_hash_insert(tp, tp->mptcp_loc_token); -+ spin_unlock(&mptcp_tk_hashlock); -+ local_bh_enable(); -+ rcu_read_unlock(); -+ -+ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_MPCAPABLEACTIVE); -+} -+ -+/** -+ * This function increments the refcount of the mpcb struct. -+ * It is the responsibility of the caller to decrement when releasing -+ * the structure. -+ */ -+struct sock *mptcp_hash_find(const struct net *net, const u32 token) -+{ -+ const u32 hash = mptcp_hash_tk(token); -+ const struct tcp_sock *meta_tp; -+ struct sock *meta_sk = NULL; -+ const struct hlist_nulls_node *node; -+ -+ rcu_read_lock(); -+ local_bh_disable(); -+begin: -+ hlist_nulls_for_each_entry_rcu(meta_tp, node, &tk_hashtable[hash], -+ tk_table) { -+ meta_sk = (struct sock *)meta_tp; -+ if (token == meta_tp->mptcp_loc_token && -+ net_eq(net, sock_net(meta_sk))) { -+ if (unlikely(!refcount_inc_not_zero(&meta_sk->sk_refcnt))) -+ goto out; -+ if (unlikely(token != meta_tp->mptcp_loc_token || -+ !net_eq(net, sock_net(meta_sk)))) { -+ sock_gen_put(meta_sk); -+ goto begin; -+ } -+ goto found; -+ } -+ } -+ /* A TCP-socket is destroyed by RCU. So, it might have been recycled -+ * and put into another hash-table list. So, after the lookup we may -+ * end up in a different list. So, we may need to restart. -+ * -+ * See also the comment in __inet_lookup_established. -+ */ -+ if (get_nulls_value(node) != hash) -+ goto begin; -+out: -+ meta_sk = NULL; -+found: -+ local_bh_enable(); -+ rcu_read_unlock(); -+ return meta_sk; -+} -+EXPORT_SYMBOL_GPL(mptcp_hash_find); -+ -+void mptcp_hash_remove_bh(struct tcp_sock *meta_tp) -+{ -+ /* remove from the token hashtable */ -+ rcu_read_lock(); -+ local_bh_disable(); -+ spin_lock(&mptcp_tk_hashlock); -+ hlist_nulls_del_init_rcu(&meta_tp->tk_table); -+ meta_tp->inside_tk_table = 0; -+ spin_unlock(&mptcp_tk_hashlock); -+ local_bh_enable(); -+ rcu_read_unlock(); -+} -+ -+struct sock *mptcp_select_ack_sock(const struct sock *meta_sk) -+{ -+ const struct tcp_sock *meta_tp = tcp_sk(meta_sk); -+ struct sock *rttsk = NULL, *lastsk = NULL; -+ u32 min_time = 0, last_active = 0; -+ struct mptcp_tcp_sock *mptcp; -+ -+ mptcp_for_each_sub(meta_tp->mpcb, mptcp) { -+ struct sock *sk = mptcp_to_sock(mptcp); -+ struct tcp_sock *tp = tcp_sk(sk); -+ u32 elapsed; -+ -+ if (!mptcp_sk_can_send_ack(sk) || tp->pf) -+ continue; -+ -+ elapsed = keepalive_time_elapsed(tp); -+ -+ /* We take the one with the lowest RTT within a reasonable -+ * (meta-RTO)-timeframe -+ */ -+ if (elapsed < inet_csk(meta_sk)->icsk_rto) { -+ if (!min_time || tp->srtt_us < min_time) { -+ min_time = tp->srtt_us; -+ rttsk = sk; -+ } -+ continue; -+ } -+ -+ /* Otherwise, we just take the most recent active */ -+ if (!rttsk && (!last_active || elapsed < last_active)) { -+ last_active = elapsed; -+ lastsk = sk; -+ } -+ } -+ -+ if (rttsk) -+ return rttsk; -+ -+ return lastsk; -+} -+EXPORT_SYMBOL(mptcp_select_ack_sock); -+ -+static void mptcp_sock_def_error_report(struct sock *sk) -+{ -+ const struct mptcp_cb *mpcb = tcp_sk(sk)->mpcb; -+ struct tcp_sock *tp = tcp_sk(sk); -+ -+ if (!sock_flag(sk, SOCK_DEAD)) { -+ if (tp->send_mp_fclose && sk->sk_err == ETIMEDOUT) { -+ /* Called by the keep alive timer (tcp_write_timeout), -+ * when the limit of fastclose retransmissions has been -+ * reached. Send a TCP RST to clear the status of any -+ * stateful firewall (typically conntrack) which are -+ * not aware of mptcp and cannot understand the -+ * fastclose option. -+ */ -+ tp->ops->send_active_reset(sk, GFP_ATOMIC); -+ } -+ } -+ -+ /* record this info that can be used by PM after the sf close */ -+ tp->mptcp->sk_err = sk->sk_err; -+ -+ if (!tp->tcp_disconnect && mptcp_in_infinite_mapping_weak(mpcb)) { -+ struct sock *meta_sk = mptcp_meta_sk(sk); -+ -+ meta_sk->sk_err = sk->sk_err; -+ meta_sk->sk_err_soft = sk->sk_err_soft; -+ -+ if (!sock_flag(meta_sk, SOCK_DEAD)) -+ meta_sk->sk_error_report(meta_sk); -+ -+ WARN(meta_sk->sk_state == TCP_CLOSE, -+ "Meta already closed i_rcv %u i_snd %u send_i %u flags %#lx\n", -+ mpcb->infinite_mapping_rcv, mpcb->infinite_mapping_snd, -+ mpcb->send_infinite_mapping, meta_sk->sk_flags); -+ -+ if (meta_sk->sk_state != TCP_CLOSE) -+ tcp_done(meta_sk); -+ } -+ -+ sk->sk_err = 0; -+ return; -+} -+ -+void mptcp_mpcb_put(struct mptcp_cb *mpcb) -+{ -+ if (refcount_dec_and_test(&mpcb->mpcb_refcnt)) { -+ mptcp_cleanup_path_manager(mpcb); -+ mptcp_cleanup_scheduler(mpcb); -+ kfree(mpcb->master_info); -+ kmem_cache_free(mptcp_cb_cache, mpcb); -+ } -+} -+EXPORT_SYMBOL(mptcp_mpcb_put); -+ -+static void mptcp_mpcb_cleanup(struct mptcp_cb *mpcb) -+{ -+ struct mptcp_tw *mptw; -+ -+ /* The mpcb is disappearing - we can make the final -+ * update to the rcv_nxt of the time-wait-sock and remove -+ * its reference to the mpcb. -+ */ -+ spin_lock_bh(&mpcb->mpcb_list_lock); -+ list_for_each_entry_rcu(mptw, &mpcb->tw_list, list) { -+ list_del_rcu(&mptw->list); -+ mptw->in_list = 0; -+ mptcp_mpcb_put(mpcb); -+ rcu_assign_pointer(mptw->mpcb, NULL); -+ } -+ spin_unlock_bh(&mpcb->mpcb_list_lock); -+ -+ mptcp_mpcb_put(mpcb); -+} -+ -+static void mptcp_sock_destruct(struct sock *sk) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ -+ if (!is_meta_sk(sk)) { -+ BUG_ON(!hlist_unhashed(&tp->mptcp->cb_list)); -+ -+ kmem_cache_free(mptcp_sock_cache, tp->mptcp); -+ tp->mptcp = NULL; -+ -+ /* Taken when mpcb pointer was set */ -+ sock_put(mptcp_meta_sk(sk)); -+ mptcp_mpcb_put(tp->mpcb); -+ } else { -+ mptcp_debug("%s destroying meta-sk token %#x\n", __func__, -+ tcp_sk(sk)->mpcb->mptcp_loc_token); -+ -+ mptcp_mpcb_cleanup(tp->mpcb); -+ } -+ -+ WARN_ON(!static_key_false(&mptcp_static_key)); -+ -+ /* Must be called here, because this will decrement the jump-label. */ -+ inet_sock_destruct(sk); -+} -+ -+void mptcp_destroy_sock(struct sock *sk) -+{ -+ if (is_meta_sk(sk)) { -+ struct mptcp_tcp_sock *mptcp; -+ struct hlist_node *tmp; -+ -+ __skb_queue_purge(&tcp_sk(sk)->mpcb->reinject_queue); -+ -+ /* We have to close all remaining subflows. Normally, they -+ * should all be about to get closed. But, if the kernel is -+ * forcing a closure (e.g., tcp_write_err), the subflows might -+ * not have been closed properly (as we are waiting for the -+ * DATA_ACK of the DATA_FIN). -+ */ -+ mptcp_for_each_sub_safe(tcp_sk(sk)->mpcb, mptcp, tmp) { -+ struct sock *sk_it = mptcp_to_sock(mptcp); -+ -+ /* Already did call tcp_close - waiting for graceful -+ * closure, or if we are retransmitting fast-close on -+ * the subflow. The reset (or timeout) will kill the -+ * subflow.. -+ */ -+ if (tcp_sk(sk_it)->closing || -+ tcp_sk(sk_it)->send_mp_fclose) -+ continue; -+ -+ /* Allow the delayed work first to prevent time-wait state */ -+ if (delayed_work_pending(&tcp_sk(sk_it)->mptcp->work)) -+ continue; -+ -+ mptcp_sub_close(sk_it, 0); -+ } -+ } else { -+ mptcp_del_sock(sk); -+ } -+} -+ -+static void mptcp_set_state(struct sock *sk) -+{ -+ struct sock *meta_sk = mptcp_meta_sk(sk); -+ -+ /* Meta is not yet established - wake up the application */ -+ if ((1 << meta_sk->sk_state) & (TCPF_SYN_SENT | TCPF_SYN_RECV) && -+ sk->sk_state == TCP_ESTABLISHED) { -+ tcp_set_state(meta_sk, TCP_ESTABLISHED); -+ -+ if (!sock_flag(meta_sk, SOCK_DEAD)) { -+ meta_sk->sk_state_change(meta_sk); -+ sk_wake_async(meta_sk, SOCK_WAKE_IO, POLL_OUT); -+ } -+ -+ tcp_sk(meta_sk)->lsndtime = tcp_jiffies32; -+ } -+ -+ if (sk->sk_state == TCP_CLOSE) { -+ if (!sock_flag(sk, SOCK_DEAD)) -+ mptcp_sub_close(sk, 0); -+ } -+} -+ -+static int mptcp_set_congestion_control(struct sock *meta_sk, const char *name, -+ bool load, bool reinit, bool cap_net_admin) -+{ -+ struct mptcp_tcp_sock *mptcp; -+ int err, result = 0; -+ -+ result = __tcp_set_congestion_control(meta_sk, name, load, reinit, cap_net_admin); -+ -+ tcp_sk(meta_sk)->mpcb->tcp_ca_explicit_set = true; -+ -+ mptcp_for_each_sub(tcp_sk(meta_sk)->mpcb, mptcp) { -+ struct sock *sk_it = mptcp_to_sock(mptcp); -+ -+ err = __tcp_set_congestion_control(sk_it, name, load, reinit, cap_net_admin); -+ if (err) -+ result = err; -+ } -+ return result; -+} -+ -+static void mptcp_assign_congestion_control(struct sock *sk) -+{ -+ struct inet_connection_sock *icsk = inet_csk(sk); -+ struct inet_connection_sock *meta_icsk = inet_csk(mptcp_meta_sk(sk)); -+ const struct tcp_congestion_ops *ca = meta_icsk->icsk_ca_ops; -+ -+ /* Congestion control is the same as meta. Thus, it has been -+ * try_module_get'd by tcp_assign_congestion_control. -+ * Congestion control on meta was not explicitly configured by -+ * application, leave default or route based. -+ */ -+ if (icsk->icsk_ca_ops == ca || -+ !tcp_sk(mptcp_meta_sk(sk))->mpcb->tcp_ca_explicit_set) -+ return; -+ -+ /* Use the same congestion control as set on the meta-sk */ -+ if (!try_module_get(ca->owner)) { -+ /* This should never happen. The congestion control is linked -+ * to the meta-socket (through tcp_assign_congestion_control) -+ * who "holds" the refcnt on the module. -+ */ -+ WARN(1, "Could not get the congestion control!"); -+ return; -+ } -+ module_put(icsk->icsk_ca_ops->owner); -+ icsk->icsk_ca_ops = ca; -+ -+ /* Clear out private data before diag gets it and -+ * the ca has not been initialized. -+ */ -+ if (ca->get_info) -+ memset(icsk->icsk_ca_priv, 0, sizeof(icsk->icsk_ca_priv)); -+ -+ return; -+} -+ -+siphash_key_t mptcp_secret __read_mostly; -+u32 mptcp_seed = 0; -+ -+static void mptcp_key_sha1(u64 key, u32 *token, u64 *idsn) -+{ -+ u32 workspace[SHA_WORKSPACE_WORDS]; -+ u32 mptcp_hashed_key[SHA_DIGEST_WORDS]; -+ u8 input[64]; -+ int i; -+ -+ memset(workspace, 0, sizeof(workspace)); -+ -+ /* Initialize input with appropriate padding */ -+ memset(&input[9], 0, sizeof(input) - 10); /* -10, because the last byte -+ * is explicitly set too -+ */ -+ memcpy(input, &key, sizeof(key)); /* Copy key to the msg beginning */ -+ input[8] = 0x80; /* Padding: First bit after message = 1 */ -+ input[63] = 0x40; /* Padding: Length of the message = 64 bits */ -+ -+ sha_init(mptcp_hashed_key); -+ sha_transform(mptcp_hashed_key, input, workspace); -+ -+ for (i = 0; i < 5; i++) -+ mptcp_hashed_key[i] = (__force u32)cpu_to_be32(mptcp_hashed_key[i]); -+ -+ if (token) -+ *token = mptcp_hashed_key[0]; -+ if (idsn) -+ *idsn = ntohll(*((__be64 *)&mptcp_hashed_key[3])); -+} -+ -+void mptcp_hmac_sha1(const u8 *key_1, const u8 *key_2, u32 *hash_out, -+ int arg_num, ...) -+{ -+ u32 workspace[SHA_WORKSPACE_WORDS]; -+ u8 input[128]; /* 2 512-bit blocks */ -+ int i; -+ int index; -+ int length; -+ u8 *msg; -+ va_list list; -+ -+ memset(workspace, 0, sizeof(workspace)); -+ -+ /* Generate key xored with ipad */ -+ memset(input, 0x36, 64); -+ for (i = 0; i < 8; i++) -+ input[i] ^= key_1[i]; -+ for (i = 0; i < 8; i++) -+ input[i + 8] ^= key_2[i]; -+ -+ va_start(list, arg_num); -+ index = 64; -+ for (i = 0; i < arg_num; i++) { -+ length = va_arg(list, int); -+ msg = va_arg(list, u8 *); -+ BUG_ON(index + length > 125); /* Message is too long */ -+ memcpy(&input[index], msg, length); -+ index += length; -+ } -+ va_end(list); -+ -+ input[index] = 0x80; /* Padding: First bit after message = 1 */ -+ memset(&input[index + 1], 0, (126 - index)); -+ -+ /* Padding: Length of the message = 512 + message length (bits) */ -+ input[126] = 0x02; -+ input[127] = ((index - 64) * 8); /* Message length (bits) */ -+ -+ sha_init(hash_out); -+ sha_transform(hash_out, input, workspace); -+ memset(workspace, 0, sizeof(workspace)); -+ -+ sha_transform(hash_out, &input[64], workspace); -+ memset(workspace, 0, sizeof(workspace)); -+ -+ for (i = 0; i < 5; i++) -+ hash_out[i] = (__force u32)cpu_to_be32(hash_out[i]); -+ -+ /* Prepare second part of hmac */ -+ memset(input, 0x5C, 64); -+ for (i = 0; i < 8; i++) -+ input[i] ^= key_1[i]; -+ for (i = 0; i < 8; i++) -+ input[i + 8] ^= key_2[i]; -+ -+ memcpy(&input[64], hash_out, 20); -+ input[84] = 0x80; -+ memset(&input[85], 0, 41); -+ -+ /* Padding: Length of the message = 512 + 160 bits */ -+ input[126] = 0x02; -+ input[127] = 0xA0; -+ -+ sha_init(hash_out); -+ sha_transform(hash_out, input, workspace); -+ memset(workspace, 0, sizeof(workspace)); -+ -+ sha_transform(hash_out, &input[64], workspace); -+ -+ for (i = 0; i < 5; i++) -+ hash_out[i] = (__force u32)cpu_to_be32(hash_out[i]); -+} -+EXPORT_SYMBOL(mptcp_hmac_sha1); -+ -+static void mptcp_mpcb_inherit_sockopts(struct sock *meta_sk, struct sock *master_sk) -+{ -+ /* Socket-options handled by sk_clone_lock while creating the meta-sk. -+ * ====== -+ * SO_SNDBUF, SO_SNDBUFFORCE, SO_RCVBUF, SO_RCVBUFFORCE, SO_RCVLOWAT, -+ * SO_RCVTIMEO, SO_SNDTIMEO, SO_ATTACH_FILTER, SO_DETACH_FILTER, -+ * TCP_NODELAY, TCP_CORK -+ * -+ * Socket-options handled in this function here -+ * ====== -+ * TCP_DEFER_ACCEPT -+ * SO_KEEPALIVE -+ * -+ * Socket-options on the todo-list -+ * ====== -+ * SO_BINDTODEVICE - should probably prevent creation of new subsocks -+ * across other devices. - what about the api-draft? -+ * SO_DEBUG -+ * SO_REUSEADDR - probably we don't care about this -+ * SO_DONTROUTE, SO_BROADCAST -+ * SO_OOBINLINE -+ * SO_LINGER -+ * SO_TIMESTAMP* - I don't think this is of concern for a SOCK_STREAM -+ * SO_PASSSEC - I don't think this is of concern for a SOCK_STREAM -+ * SO_RXQ_OVFL -+ * TCP_COOKIE_TRANSACTIONS -+ * TCP_MAXSEG -+ * TCP_THIN_* - Handled by sk_clone_lock, but we need to support this -+ * in mptcp_meta_retransmit_timer. AND we need to check -+ * what is about the subsockets. -+ * TCP_LINGER2 -+ * TCP_WINDOW_CLAMP -+ * TCP_USER_TIMEOUT -+ * TCP_MD5SIG -+ * -+ * Socket-options of no concern for the meta-socket (but for the subsocket) -+ * ====== -+ * SO_PRIORITY -+ * SO_MARK -+ * TCP_CONGESTION -+ * TCP_SYNCNT -+ * TCP_QUICKACK -+ */ -+ -+ /* DEFER_ACCEPT should not be set on the meta, as we want to accept new subflows directly */ -+ inet_csk(meta_sk)->icsk_accept_queue.rskq_defer_accept = 0; -+ -+ /* Keepalives are handled entirely at the MPTCP-layer */ -+ if (sock_flag(meta_sk, SOCK_KEEPOPEN)) { -+ inet_csk_reset_keepalive_timer(meta_sk, -+ keepalive_time_when(tcp_sk(meta_sk))); -+ sock_reset_flag(master_sk, SOCK_KEEPOPEN); -+ inet_csk_delete_keepalive_timer(master_sk); -+ } -+ -+ /* Do not propagate subflow-errors up to the MPTCP-layer */ -+ inet_sk(master_sk)->recverr = 0; -+} -+ -+/* Called without holding lock on meta_sk */ -+static void mptcp_sub_inherit_sockopts(const struct sock *meta_sk, struct sock *sub_sk) -+{ -+ __u8 meta_tos; -+ -+ /* IP_TOS also goes to the subflow. */ -+ meta_tos = READ_ONCE(inet_sk(meta_sk)->tos); -+ if (inet_sk(sub_sk)->tos != meta_tos) { -+ inet_sk(sub_sk)->tos = meta_tos; -+ sub_sk->sk_priority = meta_sk->sk_priority; -+ sk_dst_reset(sub_sk); -+ } -+ -+ /* Inherit SO_REUSEADDR */ -+ sub_sk->sk_reuse = meta_sk->sk_reuse; -+ -+ /* Inherit SO_MARK: can be used for routing or filtering */ -+ sub_sk->sk_mark = meta_sk->sk_mark; -+ -+ /* Inherit snd/rcv-buffer locks */ -+ sub_sk->sk_userlocks = meta_sk->sk_userlocks & ~SOCK_BINDPORT_LOCK; -+ -+ /* Nagle/Cork is forced off on the subflows. It is handled at the meta-layer */ -+ tcp_sk(sub_sk)->nonagle = TCP_NAGLE_OFF|TCP_NAGLE_PUSH; -+ -+ /* Keepalives are handled entirely at the MPTCP-layer */ -+ if (sock_flag(sub_sk, SOCK_KEEPOPEN)) { -+ sock_reset_flag(sub_sk, SOCK_KEEPOPEN); -+ inet_csk_delete_keepalive_timer(sub_sk); -+ } -+ -+ /* Do not propagate subflow-errors up to the MPTCP-layer */ -+ inet_sk(sub_sk)->recverr = 0; -+} -+ -+void mptcp_prepare_for_backlog(struct sock *sk, struct sk_buff *skb) -+{ -+ /* In case of success (in mptcp_backlog_rcv) and error (in kfree_skb) of -+ * sk_add_backlog, we will decrement the sk refcount. -+ */ -+ sock_hold(sk); -+ skb->sk = sk; -+ skb->destructor = sock_efree; -+} -+ -+int mptcp_backlog_rcv(struct sock *meta_sk, struct sk_buff *skb) -+{ -+ /* skb-sk may be NULL if we receive a packet immediatly after the -+ * SYN/ACK + MP_CAPABLE. -+ */ -+ struct sock *sk = skb->sk ? skb->sk : meta_sk; -+ int ret = 0; -+ -+ if (unlikely(!refcount_inc_not_zero(&sk->sk_refcnt))) { -+ kfree_skb(skb); -+ return 0; -+ } -+ -+ /* Decrement sk refcnt when calling the skb destructor. -+ * Refcnt is incremented and skb destructor is set in tcp_v{4,6}_rcv via -+ * mptcp_prepare_for_backlog() here above. -+ */ -+ skb_orphan(skb); -+ -+ if (sk->sk_family == AF_INET) -+ ret = tcp_v4_do_rcv(sk, skb); -+#if IS_ENABLED(CONFIG_IPV6) -+ else -+ ret = tcp_v6_do_rcv(sk, skb); -+#endif -+ -+ sock_put(sk); -+ return ret; -+} -+ -+static void mptcp_init_buffer_space(struct sock *sk) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct sock *meta_sk = mptcp_meta_sk(sk); -+ struct tcp_sock *meta_tp = tcp_sk(meta_sk); -+ int space; -+ -+ tcp_init_buffer_space(sk); -+ -+ if (is_master_tp(tp)) { -+ meta_tp->rcvq_space.space = meta_tp->rcv_wnd; -+ tcp_mstamp_refresh(meta_tp); -+ meta_tp->rcvq_space.time = meta_tp->tcp_mstamp; -+ meta_tp->rcvq_space.seq = meta_tp->copied_seq; -+ -+ /* If there is only one subflow, we just use regular TCP -+ * autotuning. User-locks are handled already by -+ * tcp_init_buffer_space -+ */ -+ meta_tp->window_clamp = tp->window_clamp; -+ meta_tp->rcv_ssthresh = tp->rcv_ssthresh; -+ meta_sk->sk_rcvbuf = sk->sk_rcvbuf; -+ meta_sk->sk_sndbuf = sk->sk_sndbuf; -+ -+ return; -+ } -+ -+ if (meta_sk->sk_userlocks & SOCK_RCVBUF_LOCK) -+ goto snd_buf; -+ -+ /* Adding a new subflow to the rcv-buffer space. We make a simple -+ * addition, to give some space to allow traffic on the new subflow. -+ * Autotuning will increase it further later on. -+ */ -+ space = min(meta_sk->sk_rcvbuf + sk->sk_rcvbuf, -+ sock_net(meta_sk)->ipv4.sysctl_tcp_rmem[2]); -+ if (space > meta_sk->sk_rcvbuf) { -+ meta_tp->window_clamp += tp->window_clamp; -+ meta_tp->rcv_ssthresh += tp->rcv_ssthresh; -+ meta_sk->sk_rcvbuf = space; -+ } -+ -+snd_buf: -+ if (meta_sk->sk_userlocks & SOCK_SNDBUF_LOCK) -+ return; -+ -+ /* Adding a new subflow to the send-buffer space. We make a simple -+ * addition, to give some space to allow traffic on the new subflow. -+ * Autotuning will increase it further later on. -+ */ -+ space = min(meta_sk->sk_sndbuf + sk->sk_sndbuf, -+ sock_net(meta_sk)->ipv4.sysctl_tcp_wmem[2]); -+ if (space > meta_sk->sk_sndbuf) { -+ meta_sk->sk_sndbuf = space; -+ meta_sk->sk_write_space(meta_sk); -+ } -+} -+ -+struct lock_class_key meta_key; -+char *meta_key_name = "sk_lock-AF_INET-MPTCP"; -+struct lock_class_key meta_slock_key; -+char *meta_slock_key_name = "slock-AF_INET-MPTCP"; -+ -+static const struct tcp_sock_ops mptcp_meta_specific = { -+ .__select_window = __mptcp_select_window, -+ .select_window = mptcp_select_window, -+ .select_initial_window = mptcp_select_initial_window, -+ .select_size = mptcp_select_size, -+ .init_buffer_space = mptcp_init_buffer_space, -+ .set_rto = mptcp_tcp_set_rto, -+ .should_expand_sndbuf = mptcp_should_expand_sndbuf, -+ .send_fin = mptcp_send_fin, -+ .write_xmit = mptcp_write_xmit, -+ .send_active_reset = mptcp_send_active_reset, -+ .write_wakeup = mptcp_write_wakeup, -+ .retransmit_timer = mptcp_meta_retransmit_timer, -+ .time_wait = mptcp_time_wait, -+ .cleanup_rbuf = mptcp_cleanup_rbuf, -+ .set_cong_ctrl = mptcp_set_congestion_control, -+}; -+ -+static const struct tcp_sock_ops mptcp_sub_specific = { -+ .__select_window = __mptcp_select_window, -+ .select_window = mptcp_select_window, -+ .select_initial_window = mptcp_select_initial_window, -+ .select_size = mptcp_select_size, -+ .init_buffer_space = mptcp_init_buffer_space, -+ .set_rto = mptcp_tcp_set_rto, -+ .should_expand_sndbuf = mptcp_should_expand_sndbuf, -+ .send_fin = tcp_send_fin, -+ .write_xmit = tcp_write_xmit, -+ .send_active_reset = tcp_send_active_reset, -+ .write_wakeup = tcp_write_wakeup, -+ .retransmit_timer = mptcp_sub_retransmit_timer, -+ .time_wait = tcp_time_wait, -+ .cleanup_rbuf = tcp_cleanup_rbuf, -+ .set_cong_ctrl = __tcp_set_congestion_control, -+}; -+ -+static int mptcp_alloc_mpcb(struct sock *meta_sk, __u64 remote_key, -+ __u8 mptcp_ver, u32 window) -+{ -+ struct mptcp_cb *mpcb; -+ struct sock *master_sk; -+ struct inet_connection_sock *meta_icsk = inet_csk(meta_sk); -+ struct tcp_sock *master_tp, *meta_tp = tcp_sk(meta_sk); -+ u64 snd_idsn, rcv_idsn; -+ -+ dst_release(meta_sk->sk_rx_dst); -+ meta_sk->sk_rx_dst = NULL; -+ /* This flag is set to announce sock_lock_init to -+ * reclassify the lock-class of the master socket. -+ */ -+ meta_tp->is_master_sk = 1; -+ master_sk = sk_clone_lock(meta_sk, GFP_ATOMIC | __GFP_ZERO); -+ meta_tp->is_master_sk = 0; -+ if (!master_sk) -+ goto err_alloc_master; -+ -+ master_tp = tcp_sk(master_sk); -+ master_tp->inside_tk_table = 0; -+ -+ mpcb = kmem_cache_zalloc(mptcp_cb_cache, GFP_ATOMIC); -+ if (!mpcb) -+ goto err_alloc_mpcb; -+ -+ /* Store the mptcp version agreed on initial handshake */ -+ mpcb->mptcp_ver = mptcp_ver; -+ -+ /* Store the keys and generate the peer's token */ -+ mpcb->mptcp_loc_key = meta_tp->mptcp_loc_key; -+ mpcb->mptcp_loc_token = meta_tp->mptcp_loc_token; -+ -+ /* Generate Initial data-sequence-numbers */ -+ mptcp_key_sha1(mpcb->mptcp_loc_key, NULL, &snd_idsn); -+ snd_idsn++; -+ mpcb->snd_high_order[0] = snd_idsn >> 32; -+ mpcb->snd_high_order[1] = mpcb->snd_high_order[0] - 1; -+ -+ mpcb->mptcp_rem_key = remote_key; -+ mptcp_key_sha1(mpcb->mptcp_rem_key, &mpcb->mptcp_rem_token, &rcv_idsn); -+ rcv_idsn++; -+ mpcb->rcv_high_order[0] = rcv_idsn >> 32; -+ mpcb->rcv_high_order[1] = mpcb->rcv_high_order[0] + 1; -+ -+ mpcb->meta_sk = meta_sk; -+ mpcb->master_sk = master_sk; -+ -+ skb_queue_head_init(&mpcb->reinject_queue); -+ mutex_init(&mpcb->mpcb_mutex); -+ -+ /* Init time-wait stuff */ -+ INIT_LIST_HEAD(&mpcb->tw_list); -+ -+ INIT_HLIST_HEAD(&mpcb->callback_list); -+ INIT_HLIST_HEAD(&mpcb->conn_list); -+ spin_lock_init(&mpcb->mpcb_list_lock); -+ -+ mpcb->orig_sk_rcvbuf = meta_sk->sk_rcvbuf; -+ mpcb->orig_sk_sndbuf = meta_sk->sk_sndbuf; -+ mpcb->orig_window_clamp = meta_tp->window_clamp; -+ -+ /* The meta is directly linked - set refcnt to 1 */ -+ refcount_set(&mpcb->mpcb_refcnt, 1); -+ -+ if (!meta_tp->inside_tk_table) { -+ /* Adding the meta_tp in the token hashtable - coming from server-side */ -+ rcu_read_lock(); -+ local_bh_disable(); -+ spin_lock(&mptcp_tk_hashlock); -+ -+ /* With lockless listeners, we might process two ACKs at the -+ * same time. With TCP, inet_csk_complete_hashdance takes care -+ * of this. But, for MPTCP this would be too late if we add -+ * this MPTCP-socket in the token table (new subflows might -+ * come in and match on this socket here. -+ * So, we need to check if someone else already added the token -+ * and revert in that case. The other guy won the race... -+ */ -+ if (mptcp_find_token(mpcb->mptcp_loc_token)) { -+ spin_unlock(&mptcp_tk_hashlock); -+ local_bh_enable(); -+ rcu_read_unlock(); -+ -+ goto err_insert_token; -+ } -+ __mptcp_hash_insert(meta_tp, mpcb->mptcp_loc_token); -+ -+ spin_unlock(&mptcp_tk_hashlock); -+ local_bh_enable(); -+ rcu_read_unlock(); -+ } -+ -+#if IS_ENABLED(CONFIG_IPV6) -+ if (meta_icsk->icsk_af_ops == &mptcp_v6_mapped) { -+ struct tcp6_sock *master_tp6 = (struct tcp6_sock *)master_sk; -+ struct ipv6_pinfo *newnp, *np = inet6_sk(meta_sk); -+ -+ inet_sk(master_sk)->pinet6 = &master_tp6->inet6; -+ -+ newnp = inet6_sk(master_sk); -+ memcpy(newnp, np, sizeof(struct ipv6_pinfo)); -+ -+ newnp->ipv6_mc_list = NULL; -+ newnp->ipv6_ac_list = NULL; -+ newnp->ipv6_fl_list = NULL; -+ newnp->pktoptions = NULL; -+ newnp->opt = NULL; -+ -+ newnp->rxopt.all = 0; -+ newnp->repflow = 0; -+ np->rxopt.all = 0; -+ np->repflow = 0; -+ } else if (meta_sk->sk_family == AF_INET6) { -+ struct tcp6_sock *master_tp6 = (struct tcp6_sock *)master_sk; -+ struct ipv6_pinfo *newnp, *np = inet6_sk(meta_sk); -+ struct ipv6_txoptions *opt; -+ -+ inet_sk(master_sk)->pinet6 = &master_tp6->inet6; -+ -+ /* The following heavily inspired from tcp_v6_syn_recv_sock() */ -+ newnp = inet6_sk(master_sk); -+ memcpy(newnp, np, sizeof(struct ipv6_pinfo)); -+ -+ newnp->ipv6_mc_list = NULL; -+ newnp->ipv6_ac_list = NULL; -+ newnp->ipv6_fl_list = NULL; -+ newnp->pktoptions = NULL; -+ newnp->opt = NULL; -+ -+ newnp->rxopt.all = 0; -+ newnp->repflow = 0; -+ np->rxopt.all = 0; -+ np->repflow = 0; -+ -+ opt = rcu_dereference(np->opt); -+ if (opt) { -+ opt = ipv6_dup_options(master_sk, opt); -+ RCU_INIT_POINTER(newnp->opt, opt); -+ } -+ inet_csk(master_sk)->icsk_ext_hdr_len = 0; -+ if (opt) -+ inet_csk(master_sk)->icsk_ext_hdr_len = opt->opt_nflen + -+ opt->opt_flen; -+ } -+#endif -+ -+ meta_tp->mptcp = NULL; -+ -+ meta_tp->write_seq = (u32)snd_idsn; -+ meta_tp->snd_sml = meta_tp->write_seq; -+ meta_tp->snd_una = meta_tp->write_seq; -+ meta_tp->snd_nxt = meta_tp->write_seq; -+ meta_tp->pushed_seq = meta_tp->write_seq; -+ meta_tp->snd_up = meta_tp->write_seq; -+ -+ meta_tp->copied_seq = (u32)rcv_idsn; -+ meta_tp->rcv_nxt = (u32)rcv_idsn; -+ meta_tp->rcv_wup = (u32)rcv_idsn; -+ -+ meta_tp->snd_wl1 = meta_tp->rcv_nxt - 1; -+ meta_tp->snd_wnd = window; -+ meta_tp->retrans_stamp = 0; /* Set in tcp_connect() */ -+ -+ meta_tp->packets_out = 0; -+ meta_icsk->icsk_probes_out = 0; -+ -+ rcu_assign_pointer(inet_sk(meta_sk)->inet_opt, NULL); -+ -+ /* Set mptcp-pointers */ -+ master_tp->mpcb = mpcb; -+ master_tp->meta_sk = meta_sk; -+ meta_tp->mpcb = mpcb; -+ meta_tp->meta_sk = meta_sk; -+ -+ /* Initialize the queues */ -+ master_tp->out_of_order_queue = RB_ROOT; -+ master_sk->tcp_rtx_queue = RB_ROOT; -+ INIT_LIST_HEAD(&master_tp->tsq_node); -+ INIT_LIST_HEAD(&master_tp->tsorted_sent_queue); -+ -+ master_sk->sk_tsq_flags = 0; -+ /* icsk_bind_hash inherited from the meta, but it will be properly set in -+ * mptcp_create_master_sk. Same operation is done in inet_csk_clone_lock. -+ */ -+ inet_csk(master_sk)->icsk_bind_hash = NULL; -+ -+ /* Init the accept_queue structure, we support a queue of 32 pending -+ * connections, it does not need to be huge, since we only store here -+ * pending subflow creations. -+ */ -+ reqsk_queue_alloc(&meta_icsk->icsk_accept_queue); -+ meta_sk->sk_max_ack_backlog = 32; -+ meta_sk->sk_ack_backlog = 0; -+ -+ if (!sock_flag(meta_sk, SOCK_MPTCP)) { -+ mptcp_enable_static_key_bh(); -+ sock_set_flag(meta_sk, SOCK_MPTCP); -+ } -+ -+ /* Redefine function-pointers as the meta-sk is now fully ready */ -+ meta_tp->mpc = 1; -+ meta_tp->ops = &mptcp_meta_specific; -+ -+ meta_sk->sk_backlog_rcv = mptcp_backlog_rcv; -+ meta_sk->sk_destruct = mptcp_sock_destruct; -+ -+ /* Meta-level retransmit timer */ -+ meta_icsk->icsk_rto *= 2; /* Double of initial - rto */ -+ -+ tcp_init_xmit_timers(master_sk); -+ /* Has been set for sending out the SYN */ -+ inet_csk_clear_xmit_timer(meta_sk, ICSK_TIME_RETRANS); -+ -+ mptcp_mpcb_inherit_sockopts(meta_sk, master_sk); -+ -+ mptcp_init_path_manager(mpcb); -+ mptcp_init_scheduler(mpcb); -+ -+ if (!try_module_get(inet_csk(master_sk)->icsk_ca_ops->owner)) -+ tcp_assign_congestion_control(master_sk); -+ -+ master_tp->saved_syn = NULL; -+ -+ mptcp_debug("%s: created mpcb with token %#x\n", -+ __func__, mpcb->mptcp_loc_token); -+ -+ return 0; -+ -+err_insert_token: -+ kmem_cache_free(mptcp_cb_cache, mpcb); -+ -+err_alloc_mpcb: -+ inet_sk(master_sk)->inet_opt = NULL; -+ master_sk->sk_state = TCP_CLOSE; -+ sock_orphan(master_sk); -+ bh_unlock_sock(master_sk); -+ sk_free(master_sk); -+ -+err_alloc_master: -+ return -ENOBUFS; -+} -+ -+/* Called without holding lock on mpcb */ -+static u8 mptcp_set_new_pathindex(struct mptcp_cb *mpcb) -+{ -+ int i; -+ -+ /* Start at 1, because 0 is reserved for the meta-sk */ -+ for (i = 1; i < sizeof(mpcb->path_index_bits) * 8; i++) { -+ if (!test_and_set_bit(i, &mpcb->path_index_bits)) -+ break; -+ } -+ -+ if (i == sizeof(mpcb->path_index_bits) * 8) -+ return 0; -+ return i; -+} -+ -+/* May be called without holding the meta-level lock */ -+int mptcp_add_sock(struct sock *meta_sk, struct sock *sk, u8 loc_id, u8 rem_id, -+ gfp_t flags) -+{ -+ struct mptcp_cb *mpcb = tcp_sk(meta_sk)->mpcb; -+ struct tcp_sock *tp = tcp_sk(sk); -+ -+ tp->mptcp = kmem_cache_zalloc(mptcp_sock_cache, flags); -+ if (!tp->mptcp) -+ return -ENOMEM; -+ -+ tp->mptcp->path_index = mptcp_set_new_pathindex(mpcb); -+ /* No more space for more subflows? */ -+ if (!tp->mptcp->path_index) { -+ kmem_cache_free(mptcp_sock_cache, tp->mptcp); -+ return -EPERM; -+ } -+ -+ INIT_HLIST_NODE(&tp->mptcp->cb_list); -+ -+ tp->mptcp->tp = tp; -+ tp->mpcb = mpcb; -+ tp->meta_sk = meta_sk; -+ -+ if (!sock_flag(sk, SOCK_MPTCP)) { -+ mptcp_enable_static_key_bh(); -+ sock_set_flag(sk, SOCK_MPTCP); -+ } -+ -+ tp->mpc = 1; -+ tp->ops = &mptcp_sub_specific; -+ -+ tp->mptcp->loc_id = loc_id; -+ tp->mptcp->rem_id = rem_id; -+ if (mpcb->sched_ops->init) -+ mpcb->sched_ops->init(sk); -+ -+ /* The corresponding sock_put is in mptcp_sock_destruct(). It cannot be -+ * included in mptcp_del_sock(), because the mpcb must remain alive -+ * until the last subsocket is completely destroyed. -+ */ -+ sock_hold(meta_sk); -+ refcount_inc(&mpcb->mpcb_refcnt); -+ -+ spin_lock_bh(&mpcb->mpcb_list_lock); -+ hlist_add_head_rcu(&tp->mptcp->node, &mpcb->conn_list); -+ spin_unlock_bh(&mpcb->mpcb_list_lock); -+ -+ tp->mptcp->attached = 1; -+ -+ mptcp_sub_inherit_sockopts(meta_sk, sk); -+ INIT_DELAYED_WORK(&tp->mptcp->work, mptcp_sub_close_wq); -+ -+ /* Properly inherit CC from the meta-socket */ -+ mptcp_assign_congestion_control(sk); -+ -+ /* As we successfully allocated the mptcp_tcp_sock, we have to -+ * change the function-pointers here (for sk_destruct to work correctly) -+ */ -+ sk->sk_error_report = mptcp_sock_def_error_report; -+ sk->sk_data_ready = mptcp_data_ready; -+ sk->sk_write_space = mptcp_write_space; -+ sk->sk_state_change = mptcp_set_state; -+ sk->sk_destruct = mptcp_sock_destruct; -+ -+ if (sk->sk_family == AF_INET) -+ mptcp_debug("%s: token %#x pi %d, src_addr:%pI4:%d dst_addr:%pI4:%d\n", -+ __func__ , mpcb->mptcp_loc_token, -+ tp->mptcp->path_index, -+ &((struct inet_sock *)tp)->inet_saddr, -+ ntohs(((struct inet_sock *)tp)->inet_sport), -+ &((struct inet_sock *)tp)->inet_daddr, -+ ntohs(((struct inet_sock *)tp)->inet_dport)); -+#if IS_ENABLED(CONFIG_IPV6) -+ else -+ mptcp_debug("%s: token %#x pi %d, src_addr:%pI6:%d dst_addr:%pI6:%d\n", -+ __func__ , mpcb->mptcp_loc_token, -+ tp->mptcp->path_index, &inet6_sk(sk)->saddr, -+ ntohs(((struct inet_sock *)tp)->inet_sport), -+ &sk->sk_v6_daddr, -+ ntohs(((struct inet_sock *)tp)->inet_dport)); -+#endif -+ -+ return 0; -+} -+ -+void mptcp_del_sock(struct sock *sk) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct mptcp_cb *mpcb; -+ -+ if (!tp->mptcp || !tp->mptcp->attached) -+ return; -+ -+ mpcb = tp->mpcb; -+ -+ if (mpcb->sched_ops->release) -+ mpcb->sched_ops->release(sk); -+ -+ if (mpcb->pm_ops->delete_subflow) -+ mpcb->pm_ops->delete_subflow(sk); -+ -+ mptcp_debug("%s: Removing subsock tok %#x pi:%d state %d is_meta? %d\n", -+ __func__, mpcb->mptcp_loc_token, tp->mptcp->path_index, -+ sk->sk_state, is_meta_sk(sk)); -+ -+ spin_lock_bh(&mpcb->mpcb_list_lock); -+ hlist_del_init_rcu(&tp->mptcp->node); -+ spin_unlock_bh(&mpcb->mpcb_list_lock); -+ -+ tp->mptcp->attached = 0; -+ mpcb->path_index_bits &= ~(1 << tp->mptcp->path_index); -+ -+ if (!tcp_write_queue_empty(sk) || !tcp_rtx_queue_empty(sk)) -+ mptcp_reinject_data(sk, 0); -+ -+ if (is_master_tp(tp)) { -+ struct sock *meta_sk = mptcp_meta_sk(sk); -+ struct tcp_sock *meta_tp = tcp_sk(meta_sk); -+ -+ if (meta_tp->record_master_info && -+ !sock_flag(meta_sk, SOCK_DEAD)) { -+ mpcb->master_info = kmalloc(sizeof(*mpcb->master_info), -+ GFP_ATOMIC); -+ -+ if (mpcb->master_info) -+ tcp_get_info(sk, mpcb->master_info, true); -+ } -+ -+ mpcb->master_sk = NULL; -+ } else if (tp->mptcp->pre_established) { -+ sk_stop_timer(sk, &tp->mptcp->mptcp_ack_timer); -+ } -+} -+ -+/* Updates the MPTCP-session based on path-manager information (e.g., addresses, -+ * low-prio flows,...). -+ */ -+void mptcp_update_metasocket(const struct sock *meta_sk) -+{ -+ if (tcp_sk(meta_sk)->mpcb->pm_ops->new_session) -+ tcp_sk(meta_sk)->mpcb->pm_ops->new_session(meta_sk); -+} -+ -+/* Clean up the receive buffer for full frames taken by the user, -+ * then send an ACK if necessary. COPIED is the number of bytes -+ * tcp_recvmsg has given to the user so far, it speeds up the -+ * calculation of whether or not we must ACK for the sake of -+ * a window update. -+ * (inspired from tcp_cleanup_rbuf()) -+ */ -+void mptcp_cleanup_rbuf(struct sock *meta_sk, int copied) -+{ -+ struct tcp_sock *meta_tp = tcp_sk(meta_sk); -+ bool recheck_rcv_window = false; -+ struct mptcp_tcp_sock *mptcp; -+ __u32 rcv_window_now = 0; -+ -+ if (copied > 0 && !(meta_sk->sk_shutdown & RCV_SHUTDOWN)) { -+ rcv_window_now = tcp_receive_window(meta_tp); -+ -+ /* Optimize, __mptcp_select_window() is not cheap. */ -+ if (2 * rcv_window_now <= meta_tp->window_clamp) -+ recheck_rcv_window = true; -+ } -+ -+ mptcp_for_each_sub(meta_tp->mpcb, mptcp) { -+ struct sock *sk = mptcp_to_sock(mptcp); -+ struct tcp_sock *tp = tcp_sk(sk); -+ const struct inet_connection_sock *icsk = inet_csk(sk); -+ -+ if (!mptcp_sk_can_send_ack(sk)) -+ continue; -+ -+ if (!inet_csk_ack_scheduled(sk)) -+ goto second_part; -+ /* Delayed ACKs frequently hit locked sockets during bulk -+ * receive. -+ */ -+ if (icsk->icsk_ack.blocked || -+ /* Once-per-two-segments ACK was not sent by tcp_input.c */ -+ tp->rcv_nxt - tp->rcv_wup > icsk->icsk_ack.rcv_mss || -+ /* If this read emptied read buffer, we send ACK, if -+ * connection is not bidirectional, user drained -+ * receive buffer and there was a small segment -+ * in queue. -+ */ -+ (copied > 0 && -+ ((icsk->icsk_ack.pending & ICSK_ACK_PUSHED2) || -+ ((icsk->icsk_ack.pending & ICSK_ACK_PUSHED) && -+ !icsk->icsk_ack.pingpong)) && -+ !atomic_read(&meta_sk->sk_rmem_alloc))) { -+ tcp_send_ack(sk); -+ continue; -+ } -+ -+second_part: -+ /* This here is the second part of tcp_cleanup_rbuf */ -+ if (recheck_rcv_window) { -+ __u32 new_window = tp->ops->__select_window(sk); -+ -+ /* Send ACK now, if this read freed lots of space -+ * in our buffer. Certainly, new_window is new window. -+ * We can advertise it now, if it is not less than -+ * current one. -+ * "Lots" means "at least twice" here. -+ */ -+ if (new_window && new_window >= 2 * rcv_window_now) -+ tcp_send_ack(sk); -+ } -+ } -+} -+ -+static int mptcp_sub_send_fin(struct sock *sk) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct sk_buff *skb = tcp_write_queue_tail(sk); -+ int mss_now; -+ -+ /* Optimization, tack on the FIN if we have a queue of -+ * unsent frames. But be careful about outgoing SACKS -+ * and IP options. -+ */ -+ mss_now = tcp_current_mss(sk); -+ -+ if (tcp_send_head(sk) != NULL) { -+ TCP_SKB_CB(skb)->tcp_flags |= TCPHDR_FIN; -+ TCP_SKB_CB(skb)->end_seq++; -+ tp->write_seq++; -+ } else { -+ skb = alloc_skb_fclone(MAX_TCP_HEADER, GFP_ATOMIC); -+ if (!skb) -+ return 1; -+ -+ INIT_LIST_HEAD(&skb->tcp_tsorted_anchor); -+ skb_reserve(skb, MAX_TCP_HEADER); -+ /* FIN eats a sequence byte, write_seq advanced by tcp_queue_skb(). */ -+ tcp_init_nondata_skb(skb, tp->write_seq, -+ TCPHDR_ACK | TCPHDR_FIN); -+ tcp_queue_skb(sk, skb); -+ } -+ __tcp_push_pending_frames(sk, mss_now, TCP_NAGLE_OFF); -+ -+ return 0; -+} -+ -+static void mptcp_sub_close_doit(struct sock *sk) -+{ -+ struct sock *meta_sk = mptcp_meta_sk(sk); -+ struct tcp_sock *tp = tcp_sk(sk); -+ -+ if (sock_flag(sk, SOCK_DEAD)) -+ return; -+ -+ if (meta_sk->sk_shutdown == SHUTDOWN_MASK || sk->sk_state == TCP_CLOSE) { -+ tp->closing = 1; -+ tcp_close(sk, 0); -+ } else if (tcp_close_state(sk)) { -+ sk->sk_shutdown |= SEND_SHUTDOWN; -+ tcp_send_fin(sk); -+ } -+} -+ -+void mptcp_sub_close_wq(struct work_struct *work) -+{ -+ struct tcp_sock *tp = container_of(work, struct mptcp_tcp_sock, work.work)->tp; -+ struct sock *sk = (struct sock *)tp; -+ struct mptcp_cb *mpcb = tp->mpcb; -+ struct sock *meta_sk = mptcp_meta_sk(sk); -+ -+ mutex_lock(&mpcb->mpcb_mutex); -+ lock_sock_nested(meta_sk, SINGLE_DEPTH_NESTING); -+ -+ mptcp_sub_close_doit(sk); -+ -+ release_sock(meta_sk); -+ mutex_unlock(&mpcb->mpcb_mutex); -+ mptcp_mpcb_put(mpcb); -+ sock_put(sk); -+} -+ -+void mptcp_sub_close(struct sock *sk, unsigned long delay) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct delayed_work *work = &tcp_sk(sk)->mptcp->work; -+ -+ /* We are already closing - e.g., call from sock_def_error_report upon -+ * tcp_disconnect in tcp_close. -+ */ -+ if (tp->closing) -+ return; -+ -+ /* Work already scheduled ? */ -+ if (work_pending(&work->work)) { -+ /* Work present - who will be first ? */ -+ if (jiffies + delay > work->timer.expires) -+ return; -+ -+ /* Try canceling - if it fails, work will be executed soon */ -+ if (!cancel_delayed_work(work)) -+ return; -+ sock_put(sk); -+ mptcp_mpcb_put(tp->mpcb); -+ } -+ -+ if (!delay) { -+ unsigned char old_state = sk->sk_state; -+ -+ /* We directly send the FIN. Because it may take so a long time, -+ * untile the work-queue will get scheduled... -+ * -+ * If mptcp_sub_send_fin returns 1, it failed and thus we reset -+ * the old state so that tcp_close will finally send the fin -+ * in user-context. -+ */ -+ if (!sk->sk_err && old_state != TCP_CLOSE && -+ tcp_close_state(sk) && mptcp_sub_send_fin(sk)) { -+ if (old_state == TCP_ESTABLISHED) -+ TCP_INC_STATS(sock_net(sk), TCP_MIB_CURRESTAB); -+ sk->sk_state = old_state; -+ } -+ } -+ -+ sock_hold(sk); -+ refcount_inc(&tp->mpcb->mpcb_refcnt); -+ queue_delayed_work(mptcp_wq, work, delay); -+} -+ -+void mptcp_sub_force_close(struct sock *sk) -+{ -+ /* The below tcp_done may have freed the socket, if he is already dead. -+ * Thus, we are not allowed to access it afterwards. That's why -+ * we have to store the dead-state in this local variable. -+ */ -+ int sock_is_dead = sock_flag(sk, SOCK_DEAD); -+ -+ tcp_sk(sk)->mp_killed = 1; -+ -+ if (sk->sk_state != TCP_CLOSE) -+ tcp_done(sk); -+ -+ if (!sock_is_dead) -+ mptcp_sub_close(sk, 0); -+} -+EXPORT_SYMBOL(mptcp_sub_force_close); -+ -+/* Update the mpcb send window, based on the contributions -+ * of each subflow -+ */ -+void mptcp_update_sndbuf(const struct tcp_sock *tp) -+{ -+ struct sock *meta_sk = tp->meta_sk; -+ int new_sndbuf = 0, old_sndbuf = meta_sk->sk_sndbuf; -+ struct mptcp_tcp_sock *mptcp; -+ -+ mptcp_for_each_sub(tp->mpcb, mptcp) { -+ struct sock *sk = mptcp_to_sock(mptcp); -+ -+ if (!mptcp_sk_can_send(sk)) -+ continue; -+ -+ new_sndbuf += sk->sk_sndbuf; -+ -+ if (new_sndbuf > sock_net(meta_sk)->ipv4.sysctl_tcp_wmem[2] || -+ new_sndbuf < 0) { -+ new_sndbuf = sock_net(meta_sk)->ipv4.sysctl_tcp_wmem[2]; -+ break; -+ } -+ } -+ meta_sk->sk_sndbuf = max(min(new_sndbuf, -+ sock_net(meta_sk)->ipv4.sysctl_tcp_wmem[2]), -+ meta_sk->sk_sndbuf); -+ -+ /* The subflow's call to sk_write_space in tcp_new_space ends up in -+ * mptcp_write_space. -+ * It has nothing to do with waking up the application. -+ * So, we do it here. -+ */ -+ if (old_sndbuf != meta_sk->sk_sndbuf) -+ meta_sk->sk_write_space(meta_sk); -+} -+ -+/* Similar to: tcp_close */ -+void mptcp_close(struct sock *meta_sk, long timeout) -+{ -+ struct tcp_sock *meta_tp = tcp_sk(meta_sk); -+ struct mptcp_cb *mpcb = meta_tp->mpcb; -+ struct mptcp_tcp_sock *mptcp; -+ struct sk_buff *skb; -+ int data_was_unread = 0; -+ int state; -+ -+ mptcp_debug("%s: Close of meta_sk with tok %#x\n", -+ __func__, mpcb->mptcp_loc_token); -+ -+ WARN_ON(refcount_inc_not_zero(&mpcb->mpcb_refcnt) == 0); -+ mutex_lock(&mpcb->mpcb_mutex); -+ lock_sock_nested(meta_sk, SINGLE_DEPTH_NESTING); -+ -+ if (meta_tp->inside_tk_table) -+ /* Detach the mpcb from the token hashtable */ -+ mptcp_hash_remove_bh(meta_tp); -+ -+ meta_sk->sk_shutdown = SHUTDOWN_MASK; -+ /* We need to flush the recv. buffs. We do this only on the -+ * descriptor close, not protocol-sourced closes, because the -+ * reader process may not have drained the data yet! -+ */ -+ while ((skb = __skb_dequeue(&meta_sk->sk_receive_queue)) != NULL) { -+ u32 len = TCP_SKB_CB(skb)->end_seq - TCP_SKB_CB(skb)->seq; -+ -+ if (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN) -+ len--; -+ data_was_unread += len; -+ __kfree_skb(skb); -+ } -+ -+ sk_mem_reclaim(meta_sk); -+ -+ /* If socket has been already reset (e.g. in tcp_reset()) - kill it. */ -+ if (meta_sk->sk_state == TCP_CLOSE) { -+ struct mptcp_tcp_sock *mptcp; -+ struct hlist_node *tmp; -+ -+ mptcp_for_each_sub_safe(mpcb, mptcp, tmp) { -+ struct sock *sk_it = mptcp_to_sock(mptcp); -+ -+ if (tcp_sk(sk_it)->send_mp_fclose) -+ continue; -+ mptcp_sub_close(sk_it, 0); -+ } -+ goto adjudge_to_death; -+ } -+ -+ if (data_was_unread) { -+ /* Unread data was tossed, zap the connection. */ -+ NET_INC_STATS(sock_net(meta_sk), LINUX_MIB_TCPABORTONCLOSE); -+ tcp_set_state(meta_sk, TCP_CLOSE); -+ tcp_sk(meta_sk)->ops->send_active_reset(meta_sk, -+ meta_sk->sk_allocation); -+ } else if (sock_flag(meta_sk, SOCK_LINGER) && !meta_sk->sk_lingertime) { -+ /* Check zero linger _after_ checking for unread data. */ -+ meta_sk->sk_prot->disconnect(meta_sk, 0); -+ NET_INC_STATS(sock_net(meta_sk), LINUX_MIB_TCPABORTONDATA); -+ } else if (tcp_close_state(meta_sk)) { -+ mptcp_send_fin(meta_sk); -+ } else if (meta_tp->snd_una == meta_tp->write_seq) { -+ struct mptcp_tcp_sock *mptcp; -+ struct hlist_node *tmp; -+ -+ /* The DATA_FIN has been sent and acknowledged -+ * (e.g., by sk_shutdown). Close all the other subflows -+ */ -+ mptcp_for_each_sub_safe(mpcb, mptcp, tmp) { -+ struct sock *sk_it = mptcp_to_sock(mptcp); -+ unsigned long delay = 0; -+ /* If we are the passive closer, don't trigger -+ * subflow-fin until the subflow has been finned -+ * by the peer. - thus we add a delay -+ */ -+ if (mpcb->passive_close && -+ sk_it->sk_state == TCP_ESTABLISHED) -+ delay = inet_csk(sk_it)->icsk_rto << 3; -+ -+ mptcp_sub_close(sk_it, delay); -+ } -+ } -+ -+ sk_stream_wait_close(meta_sk, timeout); -+ -+adjudge_to_death: -+ state = meta_sk->sk_state; -+ sock_hold(meta_sk); -+ sock_orphan(meta_sk); -+ -+ /* socket will be freed after mptcp_close - we have to prevent -+ * access from the subflows. -+ */ -+ mptcp_for_each_sub(mpcb, mptcp) { -+ struct sock *sk_it = mptcp_to_sock(mptcp); -+ -+ /* Similar to sock_orphan, but we don't set it DEAD, because -+ * the callbacks are still set and must be called. -+ */ -+ write_lock_bh(&sk_it->sk_callback_lock); -+ sk_set_socket(sk_it, NULL); -+ sk_it->sk_wq = NULL; -+ write_unlock_bh(&sk_it->sk_callback_lock); -+ } -+ -+ if (mpcb->pm_ops->close_session) -+ mpcb->pm_ops->close_session(meta_sk); -+ -+ /* It is the last release_sock in its life. It will remove backlog. */ -+ release_sock(meta_sk); -+ -+ /* Now socket is owned by kernel and we acquire BH lock -+ * to finish close. No need to check for user refs. -+ */ -+ local_bh_disable(); -+ bh_lock_sock(meta_sk); -+ WARN_ON(sock_owned_by_user(meta_sk)); -+ -+ percpu_counter_inc(meta_sk->sk_prot->orphan_count); -+ -+ /* Have we already been destroyed by a softirq or backlog? */ -+ if (state != TCP_CLOSE && meta_sk->sk_state == TCP_CLOSE) -+ goto out; -+ -+ /* This is a (useful) BSD violating of the RFC. There is a -+ * problem with TCP as specified in that the other end could -+ * keep a socket open forever with no application left this end. -+ * We use a 3 minute timeout (about the same as BSD) then kill -+ * our end. If they send after that then tough - BUT: long enough -+ * that we won't make the old 4*rto = almost no time - whoops -+ * reset mistake. -+ * -+ * Nope, it was not mistake. It is really desired behaviour -+ * f.e. on http servers, when such sockets are useless, but -+ * consume significant resources. Let's do it with special -+ * linger2 option. --ANK -+ */ -+ -+ if (meta_sk->sk_state == TCP_FIN_WAIT2) { -+ if (meta_tp->linger2 < 0) { -+ tcp_set_state(meta_sk, TCP_CLOSE); -+ meta_tp->ops->send_active_reset(meta_sk, GFP_ATOMIC); -+ __NET_INC_STATS(sock_net(meta_sk), -+ LINUX_MIB_TCPABORTONLINGER); -+ } else { -+ const int tmo = tcp_fin_time(meta_sk); -+ -+ if (tmo > TCP_TIMEWAIT_LEN) { -+ inet_csk_reset_keepalive_timer(meta_sk, -+ tmo - TCP_TIMEWAIT_LEN); -+ } else { -+ meta_tp->ops->time_wait(meta_sk, TCP_FIN_WAIT2, -+ tmo); -+ goto out; -+ } -+ } -+ } -+ if (meta_sk->sk_state != TCP_CLOSE) { -+ sk_mem_reclaim(meta_sk); -+ if (tcp_check_oom(meta_sk, 0)) { -+ if (net_ratelimit()) -+ pr_info("MPTCP: out of memory: force closing socket\n"); -+ tcp_set_state(meta_sk, TCP_CLOSE); -+ meta_tp->ops->send_active_reset(meta_sk, GFP_ATOMIC); -+ __NET_INC_STATS(sock_net(meta_sk), -+ LINUX_MIB_TCPABORTONMEMORY); -+ } -+ } -+ -+ -+ if (meta_sk->sk_state == TCP_CLOSE) -+ inet_csk_destroy_sock(meta_sk); -+ /* Otherwise, socket is reprieved until protocol close. */ -+ -+out: -+ bh_unlock_sock(meta_sk); -+ local_bh_enable(); -+ mutex_unlock(&mpcb->mpcb_mutex); -+ mptcp_mpcb_put(mpcb); -+ sock_put(meta_sk); /* Taken by sock_hold */ -+} -+ -+void mptcp_disconnect(struct sock *meta_sk) -+{ -+ struct tcp_sock *meta_tp = tcp_sk(meta_sk); -+ struct mptcp_tcp_sock *mptcp; -+ struct hlist_node *tmp; -+ -+ __skb_queue_purge(&meta_tp->mpcb->reinject_queue); -+ -+ if (meta_tp->inside_tk_table) -+ mptcp_hash_remove_bh(meta_tp); -+ -+ local_bh_disable(); -+ mptcp_for_each_sub_safe(meta_tp->mpcb, mptcp, tmp) { -+ struct sock *subsk = mptcp_to_sock(mptcp); -+ -+ if (spin_is_locked(&subsk->sk_lock.slock)) -+ bh_unlock_sock(subsk); -+ -+ tcp_sk(subsk)->tcp_disconnect = 1; -+ -+ meta_sk->sk_prot->disconnect(subsk, O_NONBLOCK); -+ -+ sock_orphan(subsk); -+ -+ percpu_counter_inc(meta_sk->sk_prot->orphan_count); -+ -+ inet_csk_destroy_sock(subsk); -+ } -+ local_bh_enable(); -+ -+ mptcp_mpcb_cleanup(meta_tp->mpcb); -+ meta_tp->meta_sk = NULL; -+ -+ meta_tp->send_mp_fclose = 0; -+ meta_tp->mpc = 0; -+ meta_tp->ops = &tcp_specific; -+#if IS_ENABLED(CONFIG_IPV6) -+ if (meta_sk->sk_family == AF_INET6) -+ meta_sk->sk_backlog_rcv = tcp_v6_do_rcv; -+ else -+ meta_sk->sk_backlog_rcv = tcp_v4_do_rcv; -+#else -+ meta_sk->sk_backlog_rcv = tcp_v4_do_rcv; -+#endif -+ meta_sk->sk_destruct = inet_sock_destruct; -+} -+ -+ -+/* Returns True if we should enable MPTCP for that socket. */ -+bool mptcp_doit(struct sock *sk) -+{ -+ const struct dst_entry *dst = __sk_dst_get(sk); -+ -+ /* Don't do mptcp over loopback */ -+ if (sk->sk_family == AF_INET && -+ (ipv4_is_loopback(inet_sk(sk)->inet_daddr) || -+ ipv4_is_loopback(inet_sk(sk)->inet_saddr))) -+ return false; -+#if IS_ENABLED(CONFIG_IPV6) -+ if (sk->sk_family == AF_INET6 && -+ (ipv6_addr_loopback(&sk->sk_v6_daddr) || -+ ipv6_addr_loopback(&inet6_sk(sk)->saddr))) -+ return false; -+#endif -+ if (mptcp_v6_is_v4_mapped(sk) && -+ ipv4_is_loopback(inet_sk(sk)->inet_saddr)) -+ return false; -+ -+#ifdef CONFIG_TCP_MD5SIG -+ /* If TCP_MD5SIG is enabled, do not do MPTCP - there is no Option-Space */ -+ if (tcp_sk(sk)->af_specific->md5_lookup(sk, sk)) -+ return false; -+#endif -+ -+ if (dst->dev && (dst->dev->flags & IFF_NOMULTIPATH)) -+ return false; -+ -+ return true; -+} -+ -+int mptcp_create_master_sk(struct sock *meta_sk, __u64 remote_key, -+ __u8 mptcp_ver, u32 window) -+{ -+ struct tcp_sock *master_tp; -+ struct sock *master_sk; -+ -+ if (mptcp_alloc_mpcb(meta_sk, remote_key, mptcp_ver, window)) -+ goto err_alloc_mpcb; -+ -+ master_sk = tcp_sk(meta_sk)->mpcb->master_sk; -+ master_tp = tcp_sk(master_sk); -+ -+ if (mptcp_add_sock(meta_sk, master_sk, 0, 0, GFP_ATOMIC)) -+ goto err_add_sock; -+ -+ if (__inet_inherit_port(meta_sk, master_sk) < 0) -+ goto err_add_sock; -+ -+ meta_sk->sk_prot->unhash(meta_sk); -+ inet_ehash_nolisten(master_sk, NULL); -+ -+ master_tp->mptcp->init_rcv_wnd = master_tp->rcv_wnd; -+ -+ return 0; -+ -+err_add_sock: -+ inet_csk_prepare_forced_close(master_sk); -+ tcp_done(master_sk); -+ -+err_alloc_mpcb: -+ return -ENOBUFS; -+} -+ -+static int __mptcp_check_req_master(struct sock *child, -+ struct request_sock *req) -+{ -+ struct tcp_sock *child_tp = tcp_sk(child); -+ struct sock *meta_sk = child; -+ struct mptcp_cb *mpcb; -+ struct mptcp_request_sock *mtreq; -+ -+ /* Never contained an MP_CAPABLE */ -+ if (!inet_rsk(req)->mptcp_rqsk) -+ return 1; -+ -+ if (!inet_rsk(req)->saw_mpc) { -+ /* Fallback to regular TCP, because we saw one SYN without -+ * MP_CAPABLE. In tcp_check_req we continue the regular path. -+ * But, the socket has been added to the reqsk_tk_htb, so we -+ * must still remove it. -+ */ -+ MPTCP_INC_STATS(sock_net(meta_sk), MPTCP_MIB_MPCAPABLEPASSIVEFALLBACK); -+ mptcp_reqsk_remove_tk(req); -+ return 1; -+ } -+ -+ MPTCP_INC_STATS(sock_net(meta_sk), MPTCP_MIB_MPCAPABLEPASSIVEACK); -+ -+ /* Just set this values to pass them to mptcp_alloc_mpcb */ -+ mtreq = mptcp_rsk(req); -+ child_tp->mptcp_loc_key = mtreq->mptcp_loc_key; -+ child_tp->mptcp_loc_token = mtreq->mptcp_loc_token; -+ -+ if (mptcp_create_master_sk(meta_sk, mtreq->mptcp_rem_key, -+ mtreq->mptcp_ver, child_tp->snd_wnd)) { -+ inet_csk_prepare_forced_close(meta_sk); -+ tcp_done(meta_sk); -+ -+ return -ENOBUFS; -+ } -+ -+ child = tcp_sk(child)->mpcb->master_sk; -+ child_tp = tcp_sk(child); -+ mpcb = child_tp->mpcb; -+ -+ child_tp->mptcp->snt_isn = tcp_rsk(req)->snt_isn; -+ child_tp->mptcp->rcv_isn = tcp_rsk(req)->rcv_isn; -+ -+ mpcb->dss_csum = mtreq->dss_csum; -+ mpcb->server_side = 1; -+ -+ /* Needs to be done here additionally, because when accepting a -+ * new connection we pass by __reqsk_free and not reqsk_free. -+ */ -+ mptcp_reqsk_remove_tk(req); -+ -+ /* Hold when creating the meta-sk in tcp_vX_syn_recv_sock. */ -+ sock_put(meta_sk); -+ -+ return 0; -+} -+ -+int mptcp_check_req_fastopen(struct sock *child, struct request_sock *req) -+{ -+ struct sock *meta_sk = child, *master_sk; -+ struct sk_buff *skb; -+ u32 new_mapping; -+ int ret; -+ -+ ret = __mptcp_check_req_master(child, req); -+ if (ret) -+ return ret; -+ -+ master_sk = tcp_sk(meta_sk)->mpcb->master_sk; -+ -+ /* We need to rewind copied_seq as it is set to IDSN + 1 and as we have -+ * pre-MPTCP data in the receive queue. -+ */ -+ tcp_sk(meta_sk)->copied_seq -= tcp_sk(master_sk)->rcv_nxt - -+ tcp_rsk(req)->rcv_isn - 1; -+ -+ /* Map subflow sequence number to data sequence numbers. We need to map -+ * these data to [IDSN - len - 1, IDSN[. -+ */ -+ new_mapping = tcp_sk(meta_sk)->copied_seq - tcp_rsk(req)->rcv_isn - 1; -+ -+ /* There should be only one skb: the SYN + data. */ -+ skb_queue_walk(&meta_sk->sk_receive_queue, skb) { -+ TCP_SKB_CB(skb)->seq += new_mapping; -+ TCP_SKB_CB(skb)->end_seq += new_mapping; -+ } -+ -+ /* With fastopen we change the semantics of the relative subflow -+ * sequence numbers to deal with middleboxes that could add/remove -+ * multiple bytes in the SYN. We chose to start counting at rcv_nxt - 1 -+ * instead of the regular TCP ISN. -+ */ -+ tcp_sk(master_sk)->mptcp->rcv_isn = tcp_sk(master_sk)->rcv_nxt - 1; -+ -+ /* We need to update copied_seq of the master_sk to account for the -+ * already moved data to the meta receive queue. -+ */ -+ tcp_sk(master_sk)->copied_seq = tcp_sk(master_sk)->rcv_nxt; -+ -+ /* Handled by the master_sk */ -+ tcp_sk(meta_sk)->fastopen_rsk = NULL; -+ -+ return 0; -+} -+ -+int mptcp_check_req_master(struct sock *sk, struct sock *child, -+ struct request_sock *req, const struct sk_buff *skb, -+ int drop, u32 tsoff) -+{ -+ struct sock *meta_sk = child; -+ int ret; -+ -+ ret = __mptcp_check_req_master(child, req); -+ if (ret) -+ return ret; -+ child = tcp_sk(child)->mpcb->master_sk; -+ -+ sock_rps_save_rxhash(child, skb); -+ -+ /* drop indicates that we come from tcp_check_req and thus need to -+ * handle the request-socket fully. -+ */ -+ if (drop) { -+ tcp_synack_rtt_meas(child, req); -+ -+ inet_csk_reqsk_queue_drop(sk, req); -+ reqsk_queue_removed(&inet_csk(sk)->icsk_accept_queue, req); -+ if (!inet_csk_reqsk_queue_add(sk, req, meta_sk)) { -+ bh_unlock_sock(meta_sk); -+ /* No sock_put() of the meta needed. The reference has -+ * already been dropped in __mptcp_check_req_master(). -+ */ -+ sock_put(child); -+ return -1; -+ } -+ } else { -+ /* Thus, we come from syn-cookies */ -+ refcount_set(&req->rsk_refcnt, 1); -+ tcp_sk(meta_sk)->tsoffset = tsoff; -+ if (!inet_csk_reqsk_queue_add(sk, req, meta_sk)) { -+ bh_unlock_sock(meta_sk); -+ /* No sock_put() of the meta needed. The reference has -+ * already been dropped in __mptcp_check_req_master(). -+ */ -+ sock_put(child); -+ reqsk_put(req); -+ return -1; -+ } -+ } -+ -+ return 0; -+} -+ -+/* May be called without holding the meta-level lock */ -+struct sock *mptcp_check_req_child(struct sock *meta_sk, -+ struct sock *child, -+ struct request_sock *req, -+ struct sk_buff *skb, -+ const struct mptcp_options_received *mopt) -+{ -+ const struct mptcp_cb *mpcb = tcp_sk(meta_sk)->mpcb; -+ struct mptcp_request_sock *mtreq = mptcp_rsk(req); -+ struct tcp_sock *child_tp = tcp_sk(child); -+ u8 hash_mac_check[20]; -+ -+ if (!mopt->join_ack) { -+ MPTCP_INC_STATS(sock_net(meta_sk), MPTCP_MIB_JOINACKFAIL); -+ goto teardown; -+ } -+ -+ mptcp_hmac_sha1((u8 *)&mpcb->mptcp_rem_key, -+ (u8 *)&mpcb->mptcp_loc_key, -+ (u32 *)hash_mac_check, 2, -+ 4, (u8 *)&mtreq->mptcp_rem_nonce, -+ 4, (u8 *)&mtreq->mptcp_loc_nonce); -+ -+ if (memcmp(hash_mac_check, (char *)&mopt->mptcp_recv_mac, 20)) { -+ MPTCP_INC_STATS(sock_net(meta_sk), MPTCP_MIB_JOINACKMAC); -+ goto teardown; -+ } -+ -+ /* Point it to the same struct socket and wq as the meta_sk */ -+ sk_set_socket(child, meta_sk->sk_socket); -+ child->sk_wq = meta_sk->sk_wq; -+ -+ if (mptcp_add_sock(meta_sk, child, mtreq->loc_id, mtreq->rem_id, GFP_ATOMIC)) { -+ /* Has been inherited, but now child_tp->mptcp is NULL */ -+ child_tp->mpc = 0; -+ child_tp->ops = &tcp_specific; -+ -+ /* TODO when we support acking the third ack for new subflows, -+ * we should silently discard this third ack, by returning NULL. -+ * -+ * Maybe, at the retransmission we will have enough memory to -+ * fully add the socket to the meta-sk. -+ */ -+ goto teardown; -+ } -+ -+ /* The child is a clone of the meta socket, we must now reset -+ * some of the fields -+ */ -+ child_tp->mptcp->rcv_low_prio = mtreq->rcv_low_prio; -+ -+ /* We should allow proper increase of the snd/rcv-buffers. Thus, we -+ * use the original values instead of the bloated up ones from the -+ * clone. -+ */ -+ child->sk_sndbuf = mpcb->orig_sk_sndbuf; -+ child->sk_rcvbuf = mpcb->orig_sk_rcvbuf; -+ -+ child_tp->mptcp->slave_sk = 1; -+ child_tp->mptcp->snt_isn = tcp_rsk(req)->snt_isn; -+ child_tp->mptcp->rcv_isn = tcp_rsk(req)->rcv_isn; -+ child_tp->mptcp->init_rcv_wnd = req->rsk_rcv_wnd; -+ -+ child->sk_tsq_flags = 0; -+ -+ sock_rps_save_rxhash(child, skb); -+ tcp_synack_rtt_meas(child, req); -+ -+ if (mpcb->pm_ops->established_subflow) -+ mpcb->pm_ops->established_subflow(child); -+ -+ /* Subflows do not use the accept queue, as they -+ * are attached immediately to the mpcb. -+ */ -+ inet_csk_reqsk_queue_drop(meta_sk, req); -+ reqsk_queue_removed(&inet_csk(meta_sk)->icsk_accept_queue, req); -+ -+ /* The refcnt is initialized to 2, because regular TCP will put him -+ * in the socket's listener queue. However, we do not have a listener-queue. -+ * So, we need to make sure that this request-sock indeed gets destroyed. -+ */ -+ reqsk_put(req); -+ -+ MPTCP_INC_STATS(sock_net(meta_sk), MPTCP_MIB_JOINACKRX); -+ return child; -+ -+teardown: -+ req->rsk_ops->send_reset(meta_sk, skb); -+ -+ /* Drop this request - sock creation failed. */ -+ inet_csk_reqsk_queue_drop(meta_sk, req); -+ reqsk_queue_removed(&inet_csk(meta_sk)->icsk_accept_queue, req); -+ inet_csk_prepare_forced_close(child); -+ tcp_done(child); -+ bh_unlock_sock(meta_sk); -+ return meta_sk; -+} -+ -+int mptcp_init_tw_sock(struct sock *sk, struct tcp_timewait_sock *tw) -+{ -+ struct mptcp_tw *mptw; -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct mptcp_cb *mpcb = tp->mpcb; -+ -+ /* A subsocket in tw can only receive data. So, if we are in -+ * infinite-receive, then we should not reply with a data-ack or act -+ * upon general MPTCP-signaling. We prevent this by simply not creating -+ * the mptcp_tw_sock. -+ */ -+ if (mpcb->infinite_mapping_rcv) { -+ tw->mptcp_tw = NULL; -+ return 0; -+ } -+ -+ /* Alloc MPTCP-tw-sock */ -+ mptw = kmem_cache_alloc(mptcp_tw_cache, GFP_ATOMIC); -+ if (!mptw) { -+ tw->mptcp_tw = NULL; -+ return -ENOBUFS; -+ } -+ -+ refcount_inc(&mpcb->mpcb_refcnt); -+ -+ tw->mptcp_tw = mptw; -+ mptw->loc_key = mpcb->mptcp_loc_key; -+ mptw->meta_tw = mpcb->in_time_wait; -+ mptw->rcv_nxt = mptcp_get_rcv_nxt_64(mptcp_meta_tp(tp)); -+ if (mptw->meta_tw && mpcb->mptw_state != TCP_TIME_WAIT) -+ mptw->rcv_nxt++; -+ rcu_assign_pointer(mptw->mpcb, mpcb); -+ -+ spin_lock_bh(&mpcb->mpcb_list_lock); -+ list_add_rcu(&mptw->list, &tp->mpcb->tw_list); -+ mptw->in_list = 1; -+ spin_unlock_bh(&mpcb->mpcb_list_lock); -+ -+ return 0; -+} -+ -+void mptcp_twsk_destructor(struct tcp_timewait_sock *tw) -+{ -+ struct mptcp_cb *mpcb; -+ -+ rcu_read_lock(); -+ local_bh_disable(); -+ mpcb = rcu_dereference(tw->mptcp_tw->mpcb); -+ -+ /* If we are still holding a ref to the mpcb, we have to remove ourself -+ * from the list and drop the ref properly. -+ */ -+ if (mpcb && refcount_inc_not_zero(&mpcb->mpcb_refcnt)) { -+ spin_lock(&mpcb->mpcb_list_lock); -+ if (tw->mptcp_tw->in_list) { -+ list_del_rcu(&tw->mptcp_tw->list); -+ tw->mptcp_tw->in_list = 0; -+ /* Put, because we added it to the list */ -+ mptcp_mpcb_put(mpcb); -+ } -+ spin_unlock(&mpcb->mpcb_list_lock); -+ -+ /* Second time, because we increased it above */ -+ mptcp_mpcb_put(mpcb); -+ } -+ -+ local_bh_enable(); -+ rcu_read_unlock(); -+ -+ kmem_cache_free(mptcp_tw_cache, tw->mptcp_tw); -+} -+ -+/* Updates the rcv_nxt of the time-wait-socks and allows them to ack a -+ * data-fin. -+ */ -+void mptcp_time_wait(struct sock *meta_sk, int state, int timeo) -+{ -+ struct tcp_sock *meta_tp = tcp_sk(meta_sk); -+ struct mptcp_tw *mptw; -+ -+ if (mptcp_in_infinite_mapping_weak(meta_tp->mpcb)) { -+ struct mptcp_tcp_sock *mptcp; -+ struct hlist_node *tmp; -+ -+ mptcp_for_each_sub_safe(meta_tp->mpcb, mptcp, tmp) { -+ struct sock *sk_it = mptcp_to_sock(mptcp); -+ -+ if (sk_it->sk_state == TCP_CLOSE) -+ continue; -+ -+ tcp_sk(sk_it)->ops->time_wait(sk_it, state, timeo); -+ } -+ } -+ -+ /* Used for sockets that go into tw after the meta -+ * (see mptcp_init_tw_sock()) -+ */ -+ meta_tp->mpcb->in_time_wait = 1; -+ meta_tp->mpcb->mptw_state = state; -+ -+ /* Update the time-wait-sock's information */ -+ rcu_read_lock(); -+ local_bh_disable(); -+ list_for_each_entry_rcu(mptw, &meta_tp->mpcb->tw_list, list) { -+ mptw->meta_tw = 1; -+ mptw->rcv_nxt = mptcp_get_rcv_nxt_64(meta_tp); -+ -+ /* We want to ack a DATA_FIN, but are yet in FIN_WAIT_2 - -+ * pretend as if the DATA_FIN has already reached us, that way -+ * the checks in tcp_timewait_state_process will be good as the -+ * DATA_FIN comes in. -+ */ -+ if (state != TCP_TIME_WAIT) -+ mptw->rcv_nxt++; -+ } -+ local_bh_enable(); -+ rcu_read_unlock(); -+ -+ if (meta_sk->sk_state != TCP_CLOSE) -+ tcp_done(meta_sk); -+} -+ -+void mptcp_tsq_flags(struct sock *sk) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct sock *meta_sk = mptcp_meta_sk(sk); -+ -+ /* It will be handled as a regular deferred-call */ -+ if (is_meta_sk(sk)) -+ return; -+ -+ if (hlist_unhashed(&tp->mptcp->cb_list)) { -+ hlist_add_head(&tp->mptcp->cb_list, &tp->mpcb->callback_list); -+ /* We need to hold it here, as the sock_hold is not assured -+ * by the release_sock as it is done in regular TCP. -+ * -+ * The subsocket may get inet_csk_destroy'd while it is inside -+ * the callback_list. -+ */ -+ sock_hold(sk); -+ } -+ -+ if (!test_and_set_bit(MPTCP_SUB_DEFERRED, &meta_sk->sk_tsq_flags)) -+ sock_hold(meta_sk); -+} -+ -+void mptcp_tsq_sub_deferred(struct sock *meta_sk) -+{ -+ struct tcp_sock *meta_tp = tcp_sk(meta_sk); -+ struct mptcp_tcp_sock *mptcp; -+ struct hlist_node *tmp; -+ -+ __sock_put(meta_sk); -+ hlist_for_each_entry_safe(mptcp, tmp, &meta_tp->mpcb->callback_list, cb_list) { -+ struct tcp_sock *tp = mptcp->tp; -+ struct sock *sk = (struct sock *)tp; -+ -+ hlist_del_init(&mptcp->cb_list); -+ sk->sk_prot->release_cb(sk); -+ /* Final sock_put (cfr. mptcp_tsq_flags) */ -+ sock_put(sk); -+ } -+} -+ -+/* May be called without holding the meta-level lock */ -+void mptcp_join_reqsk_init(const struct mptcp_cb *mpcb, -+ const struct request_sock *req, -+ struct sk_buff *skb) -+{ -+ struct mptcp_request_sock *mtreq = mptcp_rsk(req); -+ struct mptcp_options_received mopt; -+ u8 mptcp_hash_mac[20]; -+ -+ mptcp_init_mp_opt(&mopt); -+ tcp_parse_mptcp_options(skb, &mopt); -+ -+ mtreq->is_sub = 1; -+ inet_rsk(req)->mptcp_rqsk = 1; -+ -+ mtreq->mptcp_rem_nonce = mopt.mptcp_recv_nonce; -+ -+ mptcp_hmac_sha1((u8 *)&mpcb->mptcp_loc_key, -+ (u8 *)&mpcb->mptcp_rem_key, -+ (u32 *)mptcp_hash_mac, 2, -+ 4, (u8 *)&mtreq->mptcp_loc_nonce, -+ 4, (u8 *)&mtreq->mptcp_rem_nonce); -+ mtreq->mptcp_hash_tmac = *(u64 *)mptcp_hash_mac; -+ -+ mtreq->rem_id = mopt.rem_id; -+ mtreq->rcv_low_prio = mopt.low_prio; -+ inet_rsk(req)->saw_mpc = 1; -+ -+ MPTCP_INC_STATS(sock_net(mpcb->meta_sk), MPTCP_MIB_JOINSYNRX); -+} -+ -+void mptcp_reqsk_init(struct request_sock *req, const struct sock *sk, -+ const struct sk_buff *skb, bool want_cookie) -+{ -+ struct mptcp_options_received mopt; -+ struct mptcp_request_sock *mtreq = mptcp_rsk(req); -+ -+ mptcp_init_mp_opt(&mopt); -+ tcp_parse_mptcp_options(skb, &mopt); -+ -+ mtreq->dss_csum = mopt.dss_csum; -+ -+ if (want_cookie) { -+ if (!mptcp_reqsk_new_cookie(req, sk, &mopt, skb)) -+ /* No key available - back to regular TCP */ -+ inet_rsk(req)->mptcp_rqsk = 0; -+ return; -+ } -+ -+ mptcp_reqsk_new_mptcp(req, sk, &mopt, skb); -+} -+ -+void mptcp_cookies_reqsk_init(struct request_sock *req, -+ struct mptcp_options_received *mopt, -+ struct sk_buff *skb) -+{ -+ struct mptcp_request_sock *mtreq = mptcp_rsk(req); -+ -+ /* Absolutely need to always initialize this. */ -+ mtreq->hash_entry.pprev = NULL; -+ -+ mtreq->mptcp_rem_key = mopt->mptcp_sender_key; -+ mtreq->mptcp_loc_key = mopt->mptcp_receiver_key; -+ -+ /* Generate the token */ -+ mptcp_key_sha1(mtreq->mptcp_loc_key, &mtreq->mptcp_loc_token, NULL); -+ -+ rcu_read_lock(); -+ local_bh_disable(); -+ spin_lock(&mptcp_tk_hashlock); -+ -+ /* Check, if the key is still free */ -+ if (mptcp_reqsk_find_tk(mtreq->mptcp_loc_token) || -+ mptcp_find_token(mtreq->mptcp_loc_token)) -+ goto out; -+ -+ inet_rsk(req)->saw_mpc = 1; -+ mtreq->is_sub = 0; -+ inet_rsk(req)->mptcp_rqsk = 1; -+ mtreq->dss_csum = mopt->dss_csum; -+ -+out: -+ spin_unlock(&mptcp_tk_hashlock); -+ local_bh_enable(); -+ rcu_read_unlock(); -+} -+ -+int mptcp_conn_request(struct sock *sk, struct sk_buff *skb) -+{ -+ struct mptcp_options_received mopt; -+ -+ mptcp_init_mp_opt(&mopt); -+ tcp_parse_mptcp_options(skb, &mopt); -+ -+ if (mopt.is_mp_join) -+ return mptcp_do_join_short(skb, &mopt, sock_net(sk)); -+ if (mopt.drop_me) -+ goto drop; -+ -+ if (!sock_flag(sk, SOCK_MPTCP)) -+ mopt.saw_mpc = 0; -+ -+ if (skb->protocol == htons(ETH_P_IP)) { -+ if (mopt.saw_mpc) { -+ if (skb_rtable(skb)->rt_flags & -+ (RTCF_BROADCAST | RTCF_MULTICAST)) -+ goto drop; -+ -+ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_MPCAPABLEPASSIVE); -+ return tcp_conn_request(&mptcp_request_sock_ops, -+ &mptcp_request_sock_ipv4_ops, -+ sk, skb); -+ } -+ -+ return tcp_v4_conn_request(sk, skb); -+#if IS_ENABLED(CONFIG_IPV6) -+ } else { -+ if (mopt.saw_mpc) { -+ if (!ipv6_unicast_destination(skb)) -+ goto drop; -+ -+ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_MPCAPABLEPASSIVE); -+ return tcp_conn_request(&mptcp6_request_sock_ops, -+ &mptcp_request_sock_ipv6_ops, -+ sk, skb); -+ } -+ -+ return tcp_v6_conn_request(sk, skb); -+#endif -+ } -+drop: -+ __NET_INC_STATS(sock_net(sk), LINUX_MIB_LISTENDROPS); -+ return 0; -+} -+ -+int mptcp_finish_handshake(struct sock *child, struct sk_buff *skb) -+ __releases(&child->sk_lock.slock) -+{ -+ int ret; -+ -+ /* We don't call tcp_child_process here, because we hold -+ * already the meta-sk-lock and are sure that it is not owned -+ * by the user. -+ */ -+ tcp_sk(child)->segs_in += max_t(u16, 1, skb_shinfo(skb)->gso_segs); -+ ret = tcp_rcv_state_process(child, skb); -+ bh_unlock_sock(child); -+ sock_put(child); -+ -+ return ret; -+} -+ -+static void __mptcp_get_info(const struct sock *meta_sk, -+ struct mptcp_meta_info *info) -+{ -+ const struct inet_connection_sock *meta_icsk = inet_csk(meta_sk); -+ const struct tcp_sock *meta_tp = tcp_sk(meta_sk); -+ u32 now = tcp_jiffies32; -+ -+ memset(info, 0, sizeof(*info)); -+ -+ info->mptcpi_state = meta_sk->sk_state; -+ info->mptcpi_retransmits = meta_icsk->icsk_retransmits; -+ info->mptcpi_probes = meta_icsk->icsk_probes_out; -+ info->mptcpi_backoff = meta_icsk->icsk_backoff; -+ -+ info->mptcpi_rto = jiffies_to_usecs(meta_icsk->icsk_rto); -+ -+ info->mptcpi_unacked = meta_tp->packets_out; -+ -+ info->mptcpi_last_data_sent = jiffies_to_msecs(now - meta_tp->lsndtime); -+ info->mptcpi_last_data_recv = jiffies_to_msecs(now - meta_icsk->icsk_ack.lrcvtime); -+ info->mptcpi_last_ack_recv = jiffies_to_msecs(now - meta_tp->rcv_tstamp); -+ -+ info->mptcpi_total_retrans = meta_tp->total_retrans; -+ -+ info->mptcpi_bytes_acked = meta_tp->bytes_acked; -+ info->mptcpi_bytes_received = meta_tp->bytes_received; -+} -+ -+static void mptcp_get_sub_info(struct sock *sk, struct mptcp_sub_info *info) -+{ -+ struct inet_sock *inet = inet_sk(sk); -+ -+ memset(info, 0, sizeof(*info)); -+ -+ if (sk->sk_family == AF_INET) { -+ info->src_v4.sin_family = AF_INET; -+ info->src_v4.sin_port = inet->inet_sport; -+ -+ info->src_v4.sin_addr.s_addr = inet->inet_rcv_saddr; -+ if (!info->src_v4.sin_addr.s_addr) -+ info->src_v4.sin_addr.s_addr = inet->inet_saddr; -+ -+ info->dst_v4.sin_family = AF_INET; -+ info->dst_v4.sin_port = inet->inet_dport; -+ info->dst_v4.sin_addr.s_addr = inet->inet_daddr; -+#if IS_ENABLED(CONFIG_IPV6) -+ } else { -+ struct ipv6_pinfo *np = inet6_sk(sk); -+ -+ info->src_v6.sin6_family = AF_INET6; -+ info->src_v6.sin6_port = inet->inet_sport; -+ -+ if (ipv6_addr_any(&sk->sk_v6_rcv_saddr)) -+ info->src_v6.sin6_addr = np->saddr; -+ else -+ info->src_v6.sin6_addr = sk->sk_v6_rcv_saddr; -+ -+ info->dst_v6.sin6_family = AF_INET6; -+ info->dst_v6.sin6_port = inet->inet_dport; -+ info->dst_v6.sin6_addr = sk->sk_v6_daddr; -+#endif -+ } -+} -+ -+int mptcp_get_info(const struct sock *meta_sk, char __user *optval, int optlen) -+{ -+ const struct tcp_sock *meta_tp = tcp_sk(meta_sk); -+ -+ struct mptcp_meta_info meta_info; -+ struct mptcp_info m_info; -+ -+ unsigned int info_len; -+ -+ /* Check again with the lock held */ -+ if (!mptcp(meta_tp)) -+ return -EINVAL; -+ -+ if (copy_from_user(&m_info, optval, optlen)) -+ return -EFAULT; -+ -+ if (m_info.meta_info) { -+ unsigned int len; -+ -+ __mptcp_get_info(meta_sk, &meta_info); -+ -+ /* Need to set this, if user thinks that tcp_info is bigger than ours */ -+ len = min_t(unsigned int, m_info.meta_len, sizeof(meta_info)); -+ m_info.meta_len = len; -+ -+ if (copy_to_user((void __user *)m_info.meta_info, &meta_info, len)) -+ return -EFAULT; -+ } -+ -+ /* Need to set this, if user thinks that tcp_info is bigger than ours */ -+ info_len = min_t(unsigned int, m_info.tcp_info_len, sizeof(struct tcp_info)); -+ m_info.tcp_info_len = info_len; -+ -+ if (m_info.initial) { -+ struct mptcp_cb *mpcb = meta_tp->mpcb; -+ -+ if (mpcb->master_sk) { -+ struct tcp_info info; -+ -+ tcp_get_info(mpcb->master_sk, &info, true); -+ if (copy_to_user((void __user *)m_info.initial, &info, info_len)) -+ return -EFAULT; -+ } else if (meta_tp->record_master_info && mpcb->master_info) { -+ if (copy_to_user((void __user *)m_info.initial, mpcb->master_info, info_len)) -+ return -EFAULT; -+ } else { -+ return meta_tp->record_master_info ? -ENOMEM : -EINVAL; -+ } -+ } -+ -+ if (m_info.subflows) { -+ unsigned int len, sub_len = 0; -+ struct mptcp_tcp_sock *mptcp; -+ char __user *ptr; -+ -+ ptr = (char __user *)m_info.subflows; -+ len = m_info.sub_len; -+ -+ mptcp_for_each_sub(meta_tp->mpcb, mptcp) { -+ struct tcp_info t_info; -+ unsigned int tmp_len; -+ -+ tcp_get_info(mptcp_to_sock(mptcp), &t_info, true); -+ -+ tmp_len = min_t(unsigned int, len, info_len); -+ len -= tmp_len; -+ -+ if (copy_to_user(ptr, &t_info, tmp_len)) -+ return -EFAULT; -+ -+ ptr += tmp_len; -+ sub_len += tmp_len; -+ -+ if (len == 0) -+ break; -+ } -+ -+ m_info.sub_len = sub_len; -+ } -+ -+ if (m_info.subflow_info) { -+ unsigned int len, sub_info_len, total_sub_info_len = 0; -+ struct mptcp_tcp_sock *mptcp; -+ char __user *ptr; -+ -+ ptr = (char __user *)m_info.subflow_info; -+ len = m_info.total_sub_info_len; -+ -+ sub_info_len = min_t(unsigned int, m_info.sub_info_len, -+ sizeof(struct mptcp_sub_info)); -+ m_info.sub_info_len = sub_info_len; -+ -+ mptcp_for_each_sub(meta_tp->mpcb, mptcp) { -+ struct mptcp_sub_info m_sub_info; -+ unsigned int tmp_len; -+ -+ mptcp_get_sub_info(mptcp_to_sock(mptcp), &m_sub_info); -+ -+ tmp_len = min_t(unsigned int, len, sub_info_len); -+ len -= tmp_len; -+ -+ if (copy_to_user(ptr, &m_sub_info, tmp_len)) -+ return -EFAULT; -+ -+ ptr += tmp_len; -+ total_sub_info_len += tmp_len; -+ -+ if (len == 0) -+ break; -+ } -+ -+ m_info.total_sub_info_len = total_sub_info_len; -+ } -+ -+ if (copy_to_user(optval, &m_info, optlen)) -+ return -EFAULT; -+ -+ return 0; -+} -+ -+void mptcp_clear_sk(struct sock *sk, int size) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ -+ /* we do not want to clear tk_table field, because of RCU lookups */ -+ sk_prot_clear_nulls(sk, offsetof(struct tcp_sock, tk_table.next)); -+ -+ size -= offsetof(struct tcp_sock, tk_table.pprev); -+ memset((char *)&tp->tk_table.pprev, 0, size); -+} -+ -+static const struct snmp_mib mptcp_snmp_list[] = { -+ SNMP_MIB_ITEM("MPCapableSYNRX", MPTCP_MIB_MPCAPABLEPASSIVE), -+ SNMP_MIB_ITEM("MPCapableSYNTX", MPTCP_MIB_MPCAPABLEACTIVE), -+ SNMP_MIB_ITEM("MPCapableSYNACKRX", MPTCP_MIB_MPCAPABLEACTIVEACK), -+ SNMP_MIB_ITEM("MPCapableACKRX", MPTCP_MIB_MPCAPABLEPASSIVEACK), -+ SNMP_MIB_ITEM("MPCapableFallbackACK", MPTCP_MIB_MPCAPABLEPASSIVEFALLBACK), -+ SNMP_MIB_ITEM("MPCapableFallbackSYNACK", MPTCP_MIB_MPCAPABLEACTIVEFALLBACK), -+ SNMP_MIB_ITEM("MPCapableRetransFallback", MPTCP_MIB_MPCAPABLERETRANSFALLBACK), -+ SNMP_MIB_ITEM("MPTCPCsumEnabled", MPTCP_MIB_CSUMENABLED), -+ SNMP_MIB_ITEM("MPTCPRetrans", MPTCP_MIB_RETRANSSEGS), -+ SNMP_MIB_ITEM("MPFailRX", MPTCP_MIB_MPFAILRX), -+ SNMP_MIB_ITEM("MPCsumFail", MPTCP_MIB_CSUMFAIL), -+ SNMP_MIB_ITEM("MPFastcloseRX", MPTCP_MIB_FASTCLOSERX), -+ SNMP_MIB_ITEM("MPFastcloseTX", MPTCP_MIB_FASTCLOSETX), -+ SNMP_MIB_ITEM("MPFallbackAckSub", MPTCP_MIB_FBACKSUB), -+ SNMP_MIB_ITEM("MPFallbackAckInit", MPTCP_MIB_FBACKINIT), -+ SNMP_MIB_ITEM("MPFallbackDataSub", MPTCP_MIB_FBDATASUB), -+ SNMP_MIB_ITEM("MPFallbackDataInit", MPTCP_MIB_FBDATAINIT), -+ SNMP_MIB_ITEM("MPRemoveAddrSubDelete", MPTCP_MIB_REMADDRSUB), -+ SNMP_MIB_ITEM("MPJoinNoTokenFound", MPTCP_MIB_JOINNOTOKEN), -+ SNMP_MIB_ITEM("MPJoinAlreadyFallenback", MPTCP_MIB_JOINFALLBACK), -+ SNMP_MIB_ITEM("MPJoinSynTx", MPTCP_MIB_JOINSYNTX), -+ SNMP_MIB_ITEM("MPJoinSynRx", MPTCP_MIB_JOINSYNRX), -+ SNMP_MIB_ITEM("MPJoinSynAckRx", MPTCP_MIB_JOINSYNACKRX), -+ SNMP_MIB_ITEM("MPJoinSynAckHMacFailure", MPTCP_MIB_JOINSYNACKMAC), -+ SNMP_MIB_ITEM("MPJoinAckRx", MPTCP_MIB_JOINACKRX), -+ SNMP_MIB_ITEM("MPJoinAckHMacFailure", MPTCP_MIB_JOINACKMAC), -+ SNMP_MIB_ITEM("MPJoinAckMissing", MPTCP_MIB_JOINACKFAIL), -+ SNMP_MIB_ITEM("MPJoinAckRTO", MPTCP_MIB_JOINACKRTO), -+ SNMP_MIB_ITEM("MPJoinAckRexmit", MPTCP_MIB_JOINACKRXMIT), -+ SNMP_MIB_ITEM("NoDSSInWindow", MPTCP_MIB_NODSSWINDOW), -+ SNMP_MIB_ITEM("DSSNotMatching", MPTCP_MIB_DSSNOMATCH), -+ SNMP_MIB_ITEM("InfiniteMapRx", MPTCP_MIB_INFINITEMAPRX), -+ SNMP_MIB_ITEM("DSSNoMatchTCP", MPTCP_MIB_DSSTCPMISMATCH), -+ SNMP_MIB_ITEM("DSSTrimHead", MPTCP_MIB_DSSTRIMHEAD), -+ SNMP_MIB_ITEM("DSSSplitTail", MPTCP_MIB_DSSSPLITTAIL), -+ SNMP_MIB_ITEM("DSSPurgeOldSubSegs", MPTCP_MIB_PURGEOLD), -+ SNMP_MIB_ITEM("AddAddrRx", MPTCP_MIB_ADDADDRRX), -+ SNMP_MIB_ITEM("AddAddrTx", MPTCP_MIB_ADDADDRTX), -+ SNMP_MIB_ITEM("RemAddrRx", MPTCP_MIB_REMADDRRX), -+ SNMP_MIB_ITEM("RemAddrTx", MPTCP_MIB_REMADDRTX), -+ SNMP_MIB_SENTINEL -+}; -+ -+struct workqueue_struct *mptcp_wq; -+EXPORT_SYMBOL(mptcp_wq); -+ -+/* Output /proc/net/mptcp */ -+static int mptcp_pm_seq_show(struct seq_file *seq, void *v) -+{ -+ struct tcp_sock *meta_tp; -+ const struct net *net = seq->private; -+ int i, n = 0; -+ -+ seq_printf(seq, " sl loc_tok rem_tok v6 local_address remote_address st ns tx_queue rx_queue inode"); -+ seq_putc(seq, '\n'); -+ -+ for (i = 0; i < MPTCP_HASH_SIZE; i++) { -+ struct hlist_nulls_node *node; -+ rcu_read_lock(); -+ local_bh_disable(); -+ hlist_nulls_for_each_entry_rcu(meta_tp, node, -+ &tk_hashtable[i], tk_table) { -+ struct sock *meta_sk = (struct sock *)meta_tp; -+ struct inet_sock *isk = inet_sk(meta_sk); -+ struct mptcp_cb *mpcb = meta_tp->mpcb; -+ -+ if (!mptcp(meta_tp) || !net_eq(net, sock_net(meta_sk))) -+ continue; -+ -+ if (!mpcb) -+ continue; -+ -+ if (capable(CAP_NET_ADMIN)) { -+ seq_printf(seq, "%4d: %04X %04X ", n++, -+ mpcb->mptcp_loc_token, -+ mpcb->mptcp_rem_token); -+ } else { -+ seq_printf(seq, "%4d: %04X %04X ", n++, -1, -1); -+ } -+ if (meta_sk->sk_family == AF_INET || -+ mptcp_v6_is_v4_mapped(meta_sk)) { -+ seq_printf(seq, " 0 %08X:%04X %08X:%04X ", -+ isk->inet_rcv_saddr, -+ ntohs(isk->inet_sport), -+ isk->inet_daddr, -+ ntohs(isk->inet_dport)); -+#if IS_ENABLED(CONFIG_IPV6) -+ } else if (meta_sk->sk_family == AF_INET6) { -+ struct in6_addr *src = &meta_sk->sk_v6_rcv_saddr; -+ struct in6_addr *dst = &meta_sk->sk_v6_daddr; -+ seq_printf(seq, " 1 %08X%08X%08X%08X:%04X %08X%08X%08X%08X:%04X", -+ src->s6_addr32[0], src->s6_addr32[1], -+ src->s6_addr32[2], src->s6_addr32[3], -+ ntohs(isk->inet_sport), -+ dst->s6_addr32[0], dst->s6_addr32[1], -+ dst->s6_addr32[2], dst->s6_addr32[3], -+ ntohs(isk->inet_dport)); -+#endif -+ } -+ -+ seq_printf(seq, " %02X %02X %08X:%08X %lu", -+ meta_sk->sk_state, mptcp_subflow_count(mpcb), -+ meta_tp->write_seq - meta_tp->snd_una, -+ max_t(int, meta_tp->rcv_nxt - -+ meta_tp->copied_seq, 0), -+ sock_i_ino(meta_sk)); -+ seq_putc(seq, '\n'); -+ } -+ -+ local_bh_enable(); -+ rcu_read_unlock(); -+ } -+ -+ return 0; -+} -+ -+static int mptcp_snmp_seq_show(struct seq_file *seq, void *v) -+{ -+ struct net *net = seq->private; -+ int i; -+ -+ for (i = 0; mptcp_snmp_list[i].name != NULL; i++) -+ seq_printf(seq, "%-32s\t%ld\n", mptcp_snmp_list[i].name, -+ snmp_fold_field(net->mptcp.mptcp_statistics, -+ mptcp_snmp_list[i].entry)); -+ -+ return 0; -+} -+ -+static int mptcp_pm_init_net(struct net *net) -+{ -+ net->mptcp.mptcp_statistics = alloc_percpu(struct mptcp_mib); -+ if (!net->mptcp.mptcp_statistics) -+ goto out_mptcp_mibs; -+ -+#ifdef CONFIG_PROC_FS -+ net->mptcp.proc_net_mptcp = proc_net_mkdir(net, "mptcp_net", net->proc_net); -+ if (!net->mptcp.proc_net_mptcp) -+ goto out_proc_net_mptcp; -+ if (!proc_create_net_single("mptcp", S_IRUGO, net->mptcp.proc_net_mptcp, -+ mptcp_pm_seq_show, NULL)) -+ goto out_mptcp_net_mptcp; -+ if (!proc_create_net_single("snmp", S_IRUGO, net->mptcp.proc_net_mptcp, -+ mptcp_snmp_seq_show, NULL)) -+ goto out_mptcp_net_snmp; -+#endif -+ -+ return 0; -+ -+#ifdef CONFIG_PROC_FS -+out_mptcp_net_snmp: -+ remove_proc_entry("mptcp", net->mptcp.proc_net_mptcp); -+out_mptcp_net_mptcp: -+ remove_proc_subtree("mptcp_net", net->proc_net); -+ net->mptcp.proc_net_mptcp = NULL; -+out_proc_net_mptcp: -+ free_percpu(net->mptcp.mptcp_statistics); -+#endif -+out_mptcp_mibs: -+ return -ENOMEM; -+} -+ -+static void mptcp_pm_exit_net(struct net *net) -+{ -+ remove_proc_entry("snmp", net->mptcp.proc_net_mptcp); -+ remove_proc_entry("mptcp", net->mptcp.proc_net_mptcp); -+ remove_proc_subtree("mptcp_net", net->proc_net); -+ free_percpu(net->mptcp.mptcp_statistics); -+} -+ -+static struct pernet_operations mptcp_pm_proc_ops = { -+ .init = mptcp_pm_init_net, -+ .exit = mptcp_pm_exit_net, -+}; -+ -+/* General initialization of mptcp */ -+void __init mptcp_init(void) -+{ -+ int i; -+ struct ctl_table_header *mptcp_sysctl; -+ -+ mptcp_sock_cache = kmem_cache_create("mptcp_sock", -+ sizeof(struct mptcp_tcp_sock), -+ 0, SLAB_HWCACHE_ALIGN, -+ NULL); -+ if (!mptcp_sock_cache) -+ goto mptcp_sock_cache_failed; -+ -+ mptcp_cb_cache = kmem_cache_create("mptcp_cb", sizeof(struct mptcp_cb), -+ 0, SLAB_TYPESAFE_BY_RCU|SLAB_HWCACHE_ALIGN, -+ NULL); -+ if (!mptcp_cb_cache) -+ goto mptcp_cb_cache_failed; -+ -+ mptcp_tw_cache = kmem_cache_create("mptcp_tw", sizeof(struct mptcp_tw), -+ 0, SLAB_TYPESAFE_BY_RCU|SLAB_HWCACHE_ALIGN, -+ NULL); -+ if (!mptcp_tw_cache) -+ goto mptcp_tw_cache_failed; -+ -+ get_random_bytes(&mptcp_secret, sizeof(mptcp_secret)); -+ -+ mptcp_wq = alloc_workqueue("mptcp_wq", WQ_UNBOUND | WQ_MEM_RECLAIM, 8); -+ if (!mptcp_wq) -+ goto alloc_workqueue_failed; -+ -+ for (i = 0; i < MPTCP_HASH_SIZE; i++) { -+ INIT_HLIST_NULLS_HEAD(&tk_hashtable[i], i); -+ INIT_HLIST_NULLS_HEAD(&mptcp_reqsk_tk_htb[i], i); -+ } -+ -+ spin_lock_init(&mptcp_tk_hashlock); -+ -+ if (register_pernet_subsys(&mptcp_pm_proc_ops)) -+ goto pernet_failed; -+ -+#if IS_ENABLED(CONFIG_IPV6) -+ if (mptcp_pm_v6_init()) -+ goto mptcp_pm_v6_failed; -+#endif -+ if (mptcp_pm_v4_init()) -+ goto mptcp_pm_v4_failed; -+ -+ mptcp_sysctl = register_net_sysctl(&init_net, "net/mptcp", mptcp_table); -+ if (!mptcp_sysctl) -+ goto register_sysctl_failed; -+ -+ if (mptcp_register_path_manager(&mptcp_pm_default)) -+ goto register_pm_failed; -+ -+ if (mptcp_register_scheduler(&mptcp_sched_default)) -+ goto register_sched_failed; -+ -+ pr_info("MPTCP: Stable release v0.95"); -+ -+ mptcp_init_failed = false; -+ -+ return; -+ -+register_sched_failed: -+ mptcp_unregister_path_manager(&mptcp_pm_default); -+register_pm_failed: -+ unregister_net_sysctl_table(mptcp_sysctl); -+register_sysctl_failed: -+ mptcp_pm_v4_undo(); -+mptcp_pm_v4_failed: -+#if IS_ENABLED(CONFIG_IPV6) -+ mptcp_pm_v6_undo(); -+mptcp_pm_v6_failed: -+#endif -+ unregister_pernet_subsys(&mptcp_pm_proc_ops); -+pernet_failed: -+ destroy_workqueue(mptcp_wq); -+alloc_workqueue_failed: -+ kmem_cache_destroy(mptcp_tw_cache); -+mptcp_tw_cache_failed: -+ kmem_cache_destroy(mptcp_cb_cache); -+mptcp_cb_cache_failed: -+ kmem_cache_destroy(mptcp_sock_cache); -+mptcp_sock_cache_failed: -+ mptcp_init_failed = true; -+} -diff -aurN linux-4.19.104/net/mptcp/mptcp_fullmesh.c mptcp-mptcp_v0.95/net/mptcp/mptcp_fullmesh.c ---- linux-4.19.104/net/mptcp/mptcp_fullmesh.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_v0.95/net/mptcp/mptcp_fullmesh.c 2020-02-17 11:29:55.000000000 +0100 -@@ -0,0 +1,1941 @@ -+#include -+#include -+ -+#include -+#include -+ -+#if IS_ENABLED(CONFIG_IPV6) -+#include -+#include -+#endif -+ -+enum { -+ MPTCP_EVENT_ADD = 1, -+ MPTCP_EVENT_DEL, -+ MPTCP_EVENT_MOD, -+}; -+ -+#define MPTCP_SUBFLOW_RETRY_DELAY 1000 -+ -+/* Max number of local or remote addresses we can store. -+ * When changing, see the bitfield below in fullmesh_rem4/6. -+ */ -+#define MPTCP_MAX_ADDR 8 -+ -+struct fullmesh_rem4 { -+ u8 rem4_id; -+ u8 bitfield; -+ u8 retry_bitfield; -+ __be16 port; -+ struct in_addr addr; -+}; -+ -+struct fullmesh_rem6 { -+ u8 rem6_id; -+ u8 bitfield; -+ u8 retry_bitfield; -+ __be16 port; -+ struct in6_addr addr; -+}; -+ -+struct mptcp_loc_addr { -+ struct mptcp_loc4 locaddr4[MPTCP_MAX_ADDR]; -+ u8 loc4_bits; -+ u8 next_v4_index; -+ -+ struct mptcp_loc6 locaddr6[MPTCP_MAX_ADDR]; -+ u8 loc6_bits; -+ u8 next_v6_index; -+ struct rcu_head rcu; -+}; -+ -+struct mptcp_addr_event { -+ struct list_head list; -+ unsigned short family; -+ u8 code:7, -+ low_prio:1; -+ int if_idx; -+ union inet_addr addr; -+}; -+ -+struct fullmesh_priv { -+ /* Worker struct for subflow establishment */ -+ struct work_struct subflow_work; -+ /* Delayed worker, when the routing-tables are not yet ready. */ -+ struct delayed_work subflow_retry_work; -+ -+ /* Remote addresses */ -+ struct fullmesh_rem4 remaddr4[MPTCP_MAX_ADDR]; -+ struct fullmesh_rem6 remaddr6[MPTCP_MAX_ADDR]; -+ -+ struct mptcp_cb *mpcb; -+ -+ u16 remove_addrs; /* Addresses to remove */ -+ u8 announced_addrs_v4; /* IPv4 Addresses we did announce */ -+ u8 announced_addrs_v6; /* IPv6 Addresses we did announce */ -+ -+ u8 add_addr; /* Are we sending an add_addr? */ -+ -+ u8 rem4_bits; -+ u8 rem6_bits; -+ -+ /* Have we established the additional subflows for primary pair? */ -+ u8 first_pair:1; -+}; -+ -+struct mptcp_fm_ns { -+ struct mptcp_loc_addr __rcu *local; -+ spinlock_t local_lock; /* Protecting the above pointer */ -+ struct list_head events; -+ struct delayed_work address_worker; -+ -+ struct net *net; -+}; -+ -+static int num_subflows __read_mostly = 1; -+module_param(num_subflows, int, 0644); -+MODULE_PARM_DESC(num_subflows, "choose the number of subflows per pair of IP addresses of MPTCP connection"); -+ -+static int create_on_err __read_mostly; -+module_param(create_on_err, int, 0644); -+MODULE_PARM_DESC(create_on_err, "recreate the subflow upon a timeout"); -+ -+static struct mptcp_pm_ops full_mesh __read_mostly; -+ -+static void full_mesh_create_subflows(struct sock *meta_sk); -+ -+static struct mptcp_fm_ns *fm_get_ns(const struct net *net) -+{ -+ return (struct mptcp_fm_ns *)net->mptcp.path_managers[MPTCP_PM_FULLMESH]; -+} -+ -+static struct fullmesh_priv *fullmesh_get_priv(const struct mptcp_cb *mpcb) -+{ -+ return (struct fullmesh_priv *)&mpcb->mptcp_pm[0]; -+} -+ -+/* Find the first free index in the bitfield */ -+static int __mptcp_find_free_index(u8 bitfield, u8 base) -+{ -+ int i; -+ -+ /* There are anyways no free bits... */ -+ if (bitfield == 0xff) -+ goto exit; -+ -+ i = ffs(~(bitfield >> base)) - 1; -+ if (i < 0) -+ goto exit; -+ -+ /* No free bits when starting at base, try from 0 on */ -+ if (i + base >= sizeof(bitfield) * 8) -+ return __mptcp_find_free_index(bitfield, 0); -+ -+ return i + base; -+exit: -+ return -1; -+} -+ -+static int mptcp_find_free_index(u8 bitfield) -+{ -+ return __mptcp_find_free_index(bitfield, 0); -+} -+ -+static void mptcp_addv4_raddr(struct mptcp_cb *mpcb, -+ const struct in_addr *addr, -+ __be16 port, u8 id) -+{ -+ int i; -+ struct fullmesh_rem4 *rem4; -+ struct fullmesh_priv *fmp = fullmesh_get_priv(mpcb); -+ -+ mptcp_for_each_bit_set(fmp->rem4_bits, i) { -+ rem4 = &fmp->remaddr4[i]; -+ -+ /* Address is already in the list --- continue */ -+ if (rem4->rem4_id == id && -+ rem4->addr.s_addr == addr->s_addr && rem4->port == port) -+ return; -+ -+ /* This may be the case, when the peer is behind a NAT. He is -+ * trying to JOIN, thus sending the JOIN with a certain ID. -+ * However the src_addr of the IP-packet has been changed. We -+ * update the addr in the list, because this is the address as -+ * OUR BOX sees it. -+ */ -+ if (rem4->rem4_id == id && rem4->addr.s_addr != addr->s_addr) { -+ /* update the address */ -+ mptcp_debug("%s: updating old addr:%pI4 to addr %pI4 with id:%d\n", -+ __func__, &rem4->addr.s_addr, -+ &addr->s_addr, id); -+ rem4->addr.s_addr = addr->s_addr; -+ rem4->port = port; -+ mpcb->list_rcvd = 1; -+ return; -+ } -+ } -+ -+ i = mptcp_find_free_index(fmp->rem4_bits); -+ /* Do we have already the maximum number of local/remote addresses? */ -+ if (i < 0) { -+ mptcp_debug("%s: At max num of remote addresses: %d --- not adding address: %pI4\n", -+ __func__, MPTCP_MAX_ADDR, &addr->s_addr); -+ return; -+ } -+ -+ rem4 = &fmp->remaddr4[i]; -+ -+ /* Address is not known yet, store it */ -+ rem4->addr.s_addr = addr->s_addr; -+ rem4->port = port; -+ rem4->bitfield = 0; -+ rem4->retry_bitfield = 0; -+ rem4->rem4_id = id; -+ mpcb->list_rcvd = 1; -+ fmp->rem4_bits |= (1 << i); -+ -+ return; -+} -+ -+static void mptcp_addv6_raddr(struct mptcp_cb *mpcb, -+ const struct in6_addr *addr, -+ __be16 port, u8 id) -+{ -+ int i; -+ struct fullmesh_rem6 *rem6; -+ struct fullmesh_priv *fmp = fullmesh_get_priv(mpcb); -+ -+ mptcp_for_each_bit_set(fmp->rem6_bits, i) { -+ rem6 = &fmp->remaddr6[i]; -+ -+ /* Address is already in the list --- continue */ -+ if (rem6->rem6_id == id && -+ ipv6_addr_equal(&rem6->addr, addr) && rem6->port == port) -+ return; -+ -+ /* This may be the case, when the peer is behind a NAT. He is -+ * trying to JOIN, thus sending the JOIN with a certain ID. -+ * However the src_addr of the IP-packet has been changed. We -+ * update the addr in the list, because this is the address as -+ * OUR BOX sees it. -+ */ -+ if (rem6->rem6_id == id) { -+ /* update the address */ -+ mptcp_debug("%s: updating old addr: %pI6 to addr %pI6 with id:%d\n", -+ __func__, &rem6->addr, addr, id); -+ rem6->addr = *addr; -+ rem6->port = port; -+ mpcb->list_rcvd = 1; -+ return; -+ } -+ } -+ -+ i = mptcp_find_free_index(fmp->rem6_bits); -+ /* Do we have already the maximum number of local/remote addresses? */ -+ if (i < 0) { -+ mptcp_debug("%s: At max num of remote addresses: %d --- not adding address: %pI6\n", -+ __func__, MPTCP_MAX_ADDR, addr); -+ return; -+ } -+ -+ rem6 = &fmp->remaddr6[i]; -+ -+ /* Address is not known yet, store it */ -+ rem6->addr = *addr; -+ rem6->port = port; -+ rem6->bitfield = 0; -+ rem6->retry_bitfield = 0; -+ rem6->rem6_id = id; -+ mpcb->list_rcvd = 1; -+ fmp->rem6_bits |= (1 << i); -+ -+ return; -+} -+ -+static void mptcp_v4_rem_raddress(struct mptcp_cb *mpcb, u8 id) -+{ -+ int i; -+ struct fullmesh_priv *fmp = fullmesh_get_priv(mpcb); -+ -+ mptcp_for_each_bit_set(fmp->rem4_bits, i) { -+ if (fmp->remaddr4[i].rem4_id == id) { -+ /* remove address from bitfield */ -+ fmp->rem4_bits &= ~(1 << i); -+ -+ break; -+ } -+ } -+} -+ -+static void mptcp_v6_rem_raddress(const struct mptcp_cb *mpcb, u8 id) -+{ -+ int i; -+ struct fullmesh_priv *fmp = fullmesh_get_priv(mpcb); -+ -+ mptcp_for_each_bit_set(fmp->rem6_bits, i) { -+ if (fmp->remaddr6[i].rem6_id == id) { -+ /* remove address from bitfield */ -+ fmp->rem6_bits &= ~(1 << i); -+ -+ break; -+ } -+ } -+} -+ -+/* Sets the bitfield of the remote-address field */ -+static void mptcp_v4_set_init_addr_bit(const struct mptcp_cb *mpcb, -+ const struct in_addr *addr, u8 index) -+{ -+ int i; -+ struct fullmesh_priv *fmp = fullmesh_get_priv(mpcb); -+ -+ mptcp_for_each_bit_set(fmp->rem4_bits, i) { -+ if (fmp->remaddr4[i].addr.s_addr == addr->s_addr) { -+ fmp->remaddr4[i].bitfield |= (1 << index); -+ return; -+ } -+ } -+} -+ -+/* Sets the bitfield of the remote-address field */ -+static void mptcp_v6_set_init_addr_bit(struct mptcp_cb *mpcb, -+ const struct in6_addr *addr, u8 index) -+{ -+ int i; -+ struct fullmesh_priv *fmp = fullmesh_get_priv(mpcb); -+ -+ mptcp_for_each_bit_set(fmp->rem6_bits, i) { -+ if (ipv6_addr_equal(&fmp->remaddr6[i].addr, addr)) { -+ fmp->remaddr6[i].bitfield |= (1 << index); -+ return; -+ } -+ } -+} -+ -+static void mptcp_set_init_addr_bit(struct mptcp_cb *mpcb, -+ const union inet_addr *addr, -+ sa_family_t family, u8 id) -+{ -+ if (family == AF_INET) -+ mptcp_v4_set_init_addr_bit(mpcb, &addr->in, id); -+ else -+ mptcp_v6_set_init_addr_bit(mpcb, &addr->in6, id); -+} -+ -+static void mptcp_v4_subflows(struct sock *meta_sk, -+ const struct mptcp_loc4 *loc, -+ struct mptcp_rem4 *rem) -+{ -+ int i; -+ -+ for (i = 1; i < num_subflows; i++) -+ mptcp_init4_subsockets(meta_sk, loc, rem); -+} -+ -+#if IS_ENABLED(CONFIG_IPV6) -+static void mptcp_v6_subflows(struct sock *meta_sk, -+ const struct mptcp_loc6 *loc, -+ struct mptcp_rem6 *rem) -+{ -+ int i; -+ -+ for (i = 1; i < num_subflows; i++) -+ mptcp_init6_subsockets(meta_sk, loc, rem); -+} -+#endif -+ -+static void retry_subflow_worker(struct work_struct *work) -+{ -+ struct delayed_work *delayed_work = container_of(work, -+ struct delayed_work, -+ work); -+ struct fullmesh_priv *fmp = container_of(delayed_work, -+ struct fullmesh_priv, -+ subflow_retry_work); -+ struct mptcp_cb *mpcb = fmp->mpcb; -+ struct sock *meta_sk = mpcb->meta_sk; -+ struct mptcp_loc_addr *mptcp_local; -+ struct mptcp_fm_ns *fm_ns = fm_get_ns(sock_net(meta_sk)); -+ int iter = 0, i; -+ -+ /* We need a local (stable) copy of the address-list. Really, it is not -+ * such a big deal, if the address-list is not 100% up-to-date. -+ */ -+ rcu_read_lock_bh(); -+ mptcp_local = rcu_dereference_bh(fm_ns->local); -+ mptcp_local = kmemdup(mptcp_local, sizeof(*mptcp_local), GFP_ATOMIC); -+ rcu_read_unlock_bh(); -+ -+ if (!mptcp_local) -+ return; -+ -+next_subflow: -+ if (iter) { -+ release_sock(meta_sk); -+ mutex_unlock(&mpcb->mpcb_mutex); -+ -+ cond_resched(); -+ } -+ mutex_lock(&mpcb->mpcb_mutex); -+ lock_sock_nested(meta_sk, SINGLE_DEPTH_NESTING); -+ -+ if (!mptcp(tcp_sk(meta_sk))) -+ goto exit; -+ -+ iter++; -+ -+ if (sock_flag(meta_sk, SOCK_DEAD)) -+ goto exit; -+ -+ mptcp_for_each_bit_set(fmp->rem4_bits, i) { -+ struct fullmesh_rem4 *rem = &fmp->remaddr4[i]; -+ /* Do we need to retry establishing a subflow ? */ -+ if (rem->retry_bitfield) { -+ int i = mptcp_find_free_index(~rem->retry_bitfield); -+ struct mptcp_rem4 rem4; -+ -+ rem->bitfield |= (1 << i); -+ rem->retry_bitfield &= ~(1 << i); -+ -+ rem4.addr = rem->addr; -+ rem4.port = rem->port; -+ rem4.rem4_id = rem->rem4_id; -+ -+ mptcp_init4_subsockets(meta_sk, &mptcp_local->locaddr4[i], &rem4); -+ mptcp_v4_subflows(meta_sk, -+ &mptcp_local->locaddr4[i], -+ &rem4); -+ goto next_subflow; -+ } -+ } -+ -+#if IS_ENABLED(CONFIG_IPV6) -+ mptcp_for_each_bit_set(fmp->rem6_bits, i) { -+ struct fullmesh_rem6 *rem = &fmp->remaddr6[i]; -+ -+ /* Do we need to retry establishing a subflow ? */ -+ if (rem->retry_bitfield) { -+ int i = mptcp_find_free_index(~rem->retry_bitfield); -+ struct mptcp_rem6 rem6; -+ -+ rem->bitfield |= (1 << i); -+ rem->retry_bitfield &= ~(1 << i); -+ -+ rem6.addr = rem->addr; -+ rem6.port = rem->port; -+ rem6.rem6_id = rem->rem6_id; -+ -+ mptcp_init6_subsockets(meta_sk, &mptcp_local->locaddr6[i], &rem6); -+ mptcp_v6_subflows(meta_sk, -+ &mptcp_local->locaddr6[i], -+ &rem6); -+ goto next_subflow; -+ } -+ } -+#endif -+ -+exit: -+ kfree(mptcp_local); -+ release_sock(meta_sk); -+ mutex_unlock(&mpcb->mpcb_mutex); -+ mptcp_mpcb_put(mpcb); -+ sock_put(meta_sk); -+} -+ -+/** -+ * Create all new subflows, by doing calls to mptcp_initX_subsockets -+ * -+ * This function uses a goto next_subflow, to allow releasing the lock between -+ * new subflows and giving other processes a chance to do some work on the -+ * socket and potentially finishing the communication. -+ **/ -+static void create_subflow_worker(struct work_struct *work) -+{ -+ struct fullmesh_priv *fmp = container_of(work, struct fullmesh_priv, -+ subflow_work); -+ struct mptcp_cb *mpcb = fmp->mpcb; -+ struct sock *meta_sk = mpcb->meta_sk; -+ struct mptcp_loc_addr *mptcp_local; -+ const struct mptcp_fm_ns *fm_ns = fm_get_ns(sock_net(meta_sk)); -+ int iter = 0, retry = 0; -+ int i; -+ -+ /* We need a local (stable) copy of the address-list. Really, it is not -+ * such a big deal, if the address-list is not 100% up-to-date. -+ */ -+ rcu_read_lock_bh(); -+ mptcp_local = rcu_dereference_bh(fm_ns->local); -+ mptcp_local = kmemdup(mptcp_local, sizeof(*mptcp_local), GFP_ATOMIC); -+ rcu_read_unlock_bh(); -+ -+ if (!mptcp_local) -+ return; -+ -+next_subflow: -+ if (iter) { -+ release_sock(meta_sk); -+ mutex_unlock(&mpcb->mpcb_mutex); -+ -+ cond_resched(); -+ } -+ mutex_lock(&mpcb->mpcb_mutex); -+ lock_sock_nested(meta_sk, SINGLE_DEPTH_NESTING); -+ -+ if (sock_flag(meta_sk, SOCK_DEAD) || !mptcp(tcp_sk(meta_sk))) -+ goto exit; -+ -+ if (mpcb->master_sk && -+ !tcp_sk(mpcb->master_sk)->mptcp->fully_established) -+ goto exit; -+ -+ /* Create the additional subflows for the first pair */ -+ if (fmp->first_pair == 0 && mpcb->master_sk) { -+ struct mptcp_loc4 loc; -+ struct mptcp_rem4 rem; -+ -+ loc.addr.s_addr = inet_sk(meta_sk)->inet_saddr; -+ loc.loc4_id = 0; -+ loc.low_prio = 0; -+ loc.if_idx = mpcb->master_sk->sk_bound_dev_if; -+ -+ rem.addr.s_addr = inet_sk(meta_sk)->inet_daddr; -+ rem.port = inet_sk(meta_sk)->inet_dport; -+ rem.rem4_id = 0; /* Default 0 */ -+ -+ mptcp_v4_subflows(meta_sk, &loc, &rem); -+ -+ fmp->first_pair = 1; -+ } -+ iter++; -+ -+ mptcp_for_each_bit_set(fmp->rem4_bits, i) { -+ struct fullmesh_rem4 *rem; -+ u8 remaining_bits; -+ -+ rem = &fmp->remaddr4[i]; -+ remaining_bits = ~(rem->bitfield) & mptcp_local->loc4_bits; -+ -+ /* Are there still combinations to handle? */ -+ if (remaining_bits) { -+ int i = mptcp_find_free_index(~remaining_bits); -+ struct mptcp_rem4 rem4; -+ -+ rem->bitfield |= (1 << i); -+ -+ rem4.addr = rem->addr; -+ rem4.port = rem->port; -+ rem4.rem4_id = rem->rem4_id; -+ -+ /* If a route is not yet available then retry once */ -+ if (mptcp_init4_subsockets(meta_sk, &mptcp_local->locaddr4[i], -+ &rem4) == -ENETUNREACH) -+ retry = rem->retry_bitfield |= (1 << i); -+ else -+ mptcp_v4_subflows(meta_sk, -+ &mptcp_local->locaddr4[i], -+ &rem4); -+ goto next_subflow; -+ } -+ } -+ -+#if IS_ENABLED(CONFIG_IPV6) -+ if (fmp->first_pair == 0 && mpcb->master_sk) { -+ struct mptcp_loc6 loc; -+ struct mptcp_rem6 rem; -+ -+ loc.addr = inet6_sk(meta_sk)->saddr; -+ loc.loc6_id = 0; -+ loc.low_prio = 0; -+ loc.if_idx = mpcb->master_sk->sk_bound_dev_if; -+ -+ rem.addr = meta_sk->sk_v6_daddr; -+ rem.port = inet_sk(meta_sk)->inet_dport; -+ rem.rem6_id = 0; /* Default 0 */ -+ -+ mptcp_v6_subflows(meta_sk, &loc, &rem); -+ -+ fmp->first_pair = 1; -+ } -+ mptcp_for_each_bit_set(fmp->rem6_bits, i) { -+ struct fullmesh_rem6 *rem; -+ u8 remaining_bits; -+ -+ rem = &fmp->remaddr6[i]; -+ remaining_bits = ~(rem->bitfield) & mptcp_local->loc6_bits; -+ -+ /* Are there still combinations to handle? */ -+ if (remaining_bits) { -+ int i = mptcp_find_free_index(~remaining_bits); -+ struct mptcp_rem6 rem6; -+ -+ rem->bitfield |= (1 << i); -+ -+ rem6.addr = rem->addr; -+ rem6.port = rem->port; -+ rem6.rem6_id = rem->rem6_id; -+ -+ /* If a route is not yet available then retry once */ -+ if (mptcp_init6_subsockets(meta_sk, &mptcp_local->locaddr6[i], -+ &rem6) == -ENETUNREACH) -+ retry = rem->retry_bitfield |= (1 << i); -+ else -+ mptcp_v6_subflows(meta_sk, -+ &mptcp_local->locaddr6[i], -+ &rem6); -+ goto next_subflow; -+ } -+ } -+#endif -+ -+ if (retry && !delayed_work_pending(&fmp->subflow_retry_work)) { -+ sock_hold(meta_sk); -+ refcount_inc(&mpcb->mpcb_refcnt); -+ queue_delayed_work(mptcp_wq, &fmp->subflow_retry_work, -+ msecs_to_jiffies(MPTCP_SUBFLOW_RETRY_DELAY)); -+ } -+ -+exit: -+ kfree(mptcp_local); -+ release_sock(meta_sk); -+ mutex_unlock(&mpcb->mpcb_mutex); -+ mptcp_mpcb_put(mpcb); -+ sock_put(meta_sk); -+} -+ -+static void announce_remove_addr(u8 addr_id, struct sock *meta_sk) -+{ -+ struct mptcp_cb *mpcb = tcp_sk(meta_sk)->mpcb; -+ struct fullmesh_priv *fmp = fullmesh_get_priv(mpcb); -+ struct sock *sk = mptcp_select_ack_sock(meta_sk); -+ -+ fmp->remove_addrs |= (1 << addr_id); -+ mpcb->addr_signal = 1; -+ -+ if (sk) -+ tcp_send_ack(sk); -+} -+ -+static void update_addr_bitfields(struct sock *meta_sk, -+ const struct mptcp_loc_addr *mptcp_local) -+{ -+ struct mptcp_cb *mpcb = tcp_sk(meta_sk)->mpcb; -+ struct fullmesh_priv *fmp = fullmesh_get_priv(mpcb); -+ int i; -+ -+ /* The bits in announced_addrs_* always match with loc*_bits. So, a -+ * simple & operation unsets the correct bits, because these go from -+ * announced to non-announced -+ */ -+ fmp->announced_addrs_v4 &= mptcp_local->loc4_bits; -+ -+ mptcp_for_each_bit_set(fmp->rem4_bits, i) { -+ fmp->remaddr4[i].bitfield &= mptcp_local->loc4_bits; -+ fmp->remaddr4[i].retry_bitfield &= mptcp_local->loc4_bits; -+ } -+ -+ fmp->announced_addrs_v6 &= mptcp_local->loc6_bits; -+ -+ mptcp_for_each_bit_set(fmp->rem6_bits, i) { -+ fmp->remaddr6[i].bitfield &= mptcp_local->loc6_bits; -+ fmp->remaddr6[i].retry_bitfield &= mptcp_local->loc6_bits; -+ } -+} -+ -+static int mptcp_find_address(const struct mptcp_loc_addr *mptcp_local, -+ sa_family_t family, const union inet_addr *addr, -+ int if_idx) -+{ -+ int i; -+ u8 loc_bits; -+ bool found = false; -+ -+ if (family == AF_INET) -+ loc_bits = mptcp_local->loc4_bits; -+ else -+ loc_bits = mptcp_local->loc6_bits; -+ -+ mptcp_for_each_bit_set(loc_bits, i) { -+ if (family == AF_INET && -+ (!if_idx || mptcp_local->locaddr4[i].if_idx == if_idx) && -+ mptcp_local->locaddr4[i].addr.s_addr == addr->in.s_addr) { -+ found = true; -+ break; -+ } -+ if (family == AF_INET6 && -+ (!if_idx || mptcp_local->locaddr6[i].if_idx == if_idx) && -+ ipv6_addr_equal(&mptcp_local->locaddr6[i].addr, -+ &addr->in6)) { -+ found = true; -+ break; -+ } -+ } -+ -+ if (!found) -+ return -1; -+ -+ return i; -+} -+ -+static int mptcp_find_address_transp(const struct mptcp_loc_addr *mptcp_local, -+ sa_family_t family, int if_idx) -+{ -+ bool found = false; -+ u8 loc_bits; -+ int i; -+ -+ if (family == AF_INET) -+ loc_bits = mptcp_local->loc4_bits; -+ else -+ loc_bits = mptcp_local->loc6_bits; -+ -+ mptcp_for_each_bit_set(loc_bits, i) { -+ if (family == AF_INET && -+ (!if_idx || mptcp_local->locaddr4[i].if_idx == if_idx)) { -+ found = true; -+ break; -+ } -+ if (family == AF_INET6 && -+ (!if_idx || mptcp_local->locaddr6[i].if_idx == if_idx)) { -+ found = true; -+ break; -+ } -+ } -+ -+ if (!found) -+ return -1; -+ -+ return i; -+} -+ -+static void mptcp_address_worker(struct work_struct *work) -+{ -+ const struct delayed_work *delayed_work = container_of(work, -+ struct delayed_work, -+ work); -+ struct mptcp_fm_ns *fm_ns = container_of(delayed_work, -+ struct mptcp_fm_ns, -+ address_worker); -+ struct net *net = fm_ns->net; -+ struct mptcp_addr_event *event = NULL; -+ struct mptcp_loc_addr *mptcp_local, *old; -+ int i, id = -1; /* id is used in the socket-code on a delete-event */ -+ bool success; /* Used to indicate if we succeeded handling the event */ -+ -+next_event: -+ success = false; -+ kfree(event); -+ -+ /* First, let's dequeue an event from our event-list */ -+ rcu_read_lock_bh(); -+ spin_lock(&fm_ns->local_lock); -+ -+ event = list_first_entry_or_null(&fm_ns->events, -+ struct mptcp_addr_event, list); -+ if (!event) { -+ spin_unlock(&fm_ns->local_lock); -+ rcu_read_unlock_bh(); -+ return; -+ } -+ -+ list_del(&event->list); -+ -+ mptcp_local = rcu_dereference_bh(fm_ns->local); -+ -+ if (event->code == MPTCP_EVENT_DEL) { -+ id = mptcp_find_address(mptcp_local, event->family, -+ &event->addr, event->if_idx); -+ -+ /* Not in the list - so we don't care */ -+ if (id < 0) { -+ mptcp_debug("%s could not find id\n", __func__); -+ goto duno; -+ } -+ -+ old = mptcp_local; -+ mptcp_local = kmemdup(mptcp_local, sizeof(*mptcp_local), -+ GFP_ATOMIC); -+ if (!mptcp_local) -+ goto duno; -+ -+ if (event->family == AF_INET) -+ mptcp_local->loc4_bits &= ~(1 << id); -+ else -+ mptcp_local->loc6_bits &= ~(1 << id); -+ -+ rcu_assign_pointer(fm_ns->local, mptcp_local); -+ kfree_rcu(old, rcu); -+ } else { -+ int i = mptcp_find_address(mptcp_local, event->family, -+ &event->addr, event->if_idx); -+ int j = i; -+ -+ if (j < 0) { -+ /* Not in the list, so we have to find an empty slot */ -+ if (event->family == AF_INET) -+ i = __mptcp_find_free_index(mptcp_local->loc4_bits, -+ mptcp_local->next_v4_index); -+ if (event->family == AF_INET6) -+ i = __mptcp_find_free_index(mptcp_local->loc6_bits, -+ mptcp_local->next_v6_index); -+ -+ if (i < 0) { -+ mptcp_debug("%s no more space\n", __func__); -+ goto duno; -+ } -+ -+ /* It might have been a MOD-event. */ -+ event->code = MPTCP_EVENT_ADD; -+ } else { -+ /* Let's check if anything changes */ -+ if (event->family == AF_INET && -+ event->low_prio == mptcp_local->locaddr4[i].low_prio) -+ goto duno; -+ -+ if (event->family == AF_INET6 && -+ event->low_prio == mptcp_local->locaddr6[i].low_prio) -+ goto duno; -+ } -+ -+ old = mptcp_local; -+ mptcp_local = kmemdup(mptcp_local, sizeof(*mptcp_local), -+ GFP_ATOMIC); -+ if (!mptcp_local) -+ goto duno; -+ -+ if (event->family == AF_INET) { -+ mptcp_local->locaddr4[i].addr.s_addr = event->addr.in.s_addr; -+ mptcp_local->locaddr4[i].loc4_id = i + 1; -+ mptcp_local->locaddr4[i].low_prio = event->low_prio; -+ mptcp_local->locaddr4[i].if_idx = event->if_idx; -+ -+ mptcp_debug("%s updated IP %pI4 on ifidx %u prio %u id %u\n", -+ __func__, &event->addr.in.s_addr, -+ event->if_idx, event->low_prio, i + 1); -+ } else { -+ mptcp_local->locaddr6[i].addr = event->addr.in6; -+ mptcp_local->locaddr6[i].loc6_id = i + MPTCP_MAX_ADDR; -+ mptcp_local->locaddr6[i].low_prio = event->low_prio; -+ mptcp_local->locaddr6[i].if_idx = event->if_idx; -+ -+ mptcp_debug("%s updated IP %pI6 on ifidx %u prio %u id %u\n", -+ __func__, &event->addr.in6, -+ event->if_idx, event->low_prio, i + MPTCP_MAX_ADDR); -+ } -+ -+ if (j < 0) { -+ if (event->family == AF_INET) { -+ mptcp_local->loc4_bits |= (1 << i); -+ mptcp_local->next_v4_index = i + 1; -+ } else { -+ mptcp_local->loc6_bits |= (1 << i); -+ mptcp_local->next_v6_index = i + 1; -+ } -+ } -+ -+ rcu_assign_pointer(fm_ns->local, mptcp_local); -+ kfree_rcu(old, rcu); -+ } -+ success = true; -+ -+duno: -+ spin_unlock(&fm_ns->local_lock); -+ rcu_read_unlock_bh(); -+ -+ if (!success) -+ goto next_event; -+ -+ /* Now we iterate over the MPTCP-sockets and apply the event. */ -+ for (i = 0; i < MPTCP_HASH_SIZE; i++) { -+ const struct hlist_nulls_node *node; -+ struct tcp_sock *meta_tp; -+ -+ rcu_read_lock_bh(); -+ hlist_nulls_for_each_entry_rcu(meta_tp, node, &tk_hashtable[i], -+ tk_table) { -+ struct sock *meta_sk = (struct sock *)meta_tp, *sk; -+ bool meta_v4 = meta_sk->sk_family == AF_INET; -+ struct mptcp_cb *mpcb; -+ -+ if (sock_net(meta_sk) != net) -+ continue; -+ -+ if (meta_v4) { -+ /* skip IPv6 events if meta is IPv4 */ -+ if (event->family == AF_INET6) -+ continue; -+ } else if (event->family == AF_INET && meta_sk->sk_ipv6only) { -+ /* skip IPv4 events if IPV6_V6ONLY is set */ -+ continue; -+ } -+ -+ if (unlikely(!refcount_inc_not_zero(&meta_sk->sk_refcnt))) -+ continue; -+ -+ bh_lock_sock(meta_sk); -+ -+ mpcb = meta_tp->mpcb; -+ if (!mpcb) -+ goto next; -+ -+ if (!mptcp(meta_tp) || !is_meta_sk(meta_sk) || -+ mptcp_in_infinite_mapping_weak(mpcb)) -+ goto next; -+ -+ /* May be that the pm has changed in-between */ -+ if (mpcb->pm_ops != &full_mesh) -+ goto next; -+ -+ if (sock_owned_by_user(meta_sk)) { -+ if (!test_and_set_bit(MPTCP_PATH_MANAGER_DEFERRED, -+ &meta_sk->sk_tsq_flags)) -+ sock_hold(meta_sk); -+ -+ goto next; -+ } -+ -+ if (event->code == MPTCP_EVENT_ADD) { -+ struct fullmesh_priv *fmp = fullmesh_get_priv(mpcb); -+ -+ fmp->add_addr++; -+ mpcb->addr_signal = 1; -+ -+ sk = mptcp_select_ack_sock(meta_sk); -+ if (sk) -+ tcp_send_ack(sk); -+ -+ full_mesh_create_subflows(meta_sk); -+ } -+ -+ if (event->code == MPTCP_EVENT_DEL) { -+ struct mptcp_tcp_sock *mptcp; -+ struct mptcp_loc_addr *mptcp_local; -+ struct hlist_node *tmp; -+ bool found = false; -+ -+ mptcp_local = rcu_dereference_bh(fm_ns->local); -+ -+ /* In any case, we need to update our bitfields */ -+ if (id >= 0) -+ update_addr_bitfields(meta_sk, mptcp_local); -+ -+ /* Look for the socket and remove him */ -+ mptcp_for_each_sub_safe(mpcb, mptcp, tmp) { -+ struct sock *sk = mptcp_to_sock(mptcp); -+ -+ if ((event->family == AF_INET6 && -+ (sk->sk_family == AF_INET || -+ mptcp_v6_is_v4_mapped(sk))) || -+ (event->family == AF_INET && -+ (sk->sk_family == AF_INET6 && -+ !mptcp_v6_is_v4_mapped(sk)))) -+ continue; -+ -+ if (event->family == AF_INET && -+ (sk->sk_family == AF_INET || -+ mptcp_v6_is_v4_mapped(sk)) && -+ inet_sk(sk)->inet_saddr != event->addr.in.s_addr) -+ continue; -+ -+ if (event->family == AF_INET6 && -+ sk->sk_family == AF_INET6 && -+ !ipv6_addr_equal(&inet6_sk(sk)->saddr, &event->addr.in6)) -+ continue; -+ -+ /* Reinject, so that pf = 1 and so we -+ * won't select this one as the -+ * ack-sock. -+ */ -+ mptcp_reinject_data(sk, 0); -+ -+ /* We announce the removal of this id */ -+ announce_remove_addr(tcp_sk(sk)->mptcp->loc_id, meta_sk); -+ -+ mptcp_sub_force_close(sk); -+ found = true; -+ } -+ -+ if (found) -+ goto next; -+ -+ /* The id may have been given by the event, -+ * matching on a local address. And it may not -+ * have matched on one of the above sockets, -+ * because the client never created a subflow. -+ * So, we have to finally remove it here. -+ */ -+ if (id >= 0) { -+ u8 loc_id = id -+ + (event->family == AF_INET ? 1 : MPTCP_MAX_ADDR); -+ announce_remove_addr(loc_id, meta_sk); -+ } -+ } -+ -+ if (event->code == MPTCP_EVENT_MOD) { -+ struct mptcp_tcp_sock *mptcp; -+ -+ mptcp_for_each_sub(mpcb, mptcp) { -+ struct sock *sk = mptcp_to_sock(mptcp); -+ struct tcp_sock *tp = tcp_sk(sk); -+ if (event->family == AF_INET && -+ (sk->sk_family == AF_INET || -+ mptcp_v6_is_v4_mapped(sk)) && -+ inet_sk(sk)->inet_saddr == event->addr.in.s_addr) { -+ if (event->low_prio != tp->mptcp->low_prio) { -+ tp->mptcp->send_mp_prio = 1; -+ tp->mptcp->low_prio = event->low_prio; -+ -+ tcp_send_ack(sk); -+ } -+ } -+ -+ if (event->family == AF_INET6 && -+ sk->sk_family == AF_INET6 && -+ !ipv6_addr_equal(&inet6_sk(sk)->saddr, &event->addr.in6)) { -+ if (event->low_prio != tp->mptcp->low_prio) { -+ tp->mptcp->send_mp_prio = 1; -+ tp->mptcp->low_prio = event->low_prio; -+ -+ tcp_send_ack(sk); -+ } -+ } -+ } -+ } -+next: -+ bh_unlock_sock(meta_sk); -+ sock_put(meta_sk); -+ } -+ rcu_read_unlock_bh(); -+ } -+ goto next_event; -+} -+ -+static struct mptcp_addr_event *lookup_similar_event(const struct net *net, -+ const struct mptcp_addr_event *event) -+{ -+ struct mptcp_addr_event *eventq; -+ struct mptcp_fm_ns *fm_ns = fm_get_ns(net); -+ -+ list_for_each_entry(eventq, &fm_ns->events, list) { -+ if (eventq->family != event->family) -+ continue; -+ if (eventq->if_idx != event->if_idx) -+ continue; -+ if (event->family == AF_INET) { -+ if (eventq->addr.in.s_addr == event->addr.in.s_addr) -+ return eventq; -+ } else { -+ if (ipv6_addr_equal(&eventq->addr.in6, &event->addr.in6)) -+ return eventq; -+ } -+ } -+ return NULL; -+} -+ -+/* We already hold the net-namespace MPTCP-lock */ -+static void add_pm_event(struct net *net, const struct mptcp_addr_event *event) -+{ -+ struct mptcp_addr_event *eventq = lookup_similar_event(net, event); -+ struct mptcp_fm_ns *fm_ns = fm_get_ns(net); -+ -+ if (eventq) { -+ switch (event->code) { -+ case MPTCP_EVENT_DEL: -+ mptcp_debug("%s del old_code %u\n", __func__, eventq->code); -+ list_del(&eventq->list); -+ kfree(eventq); -+ break; -+ case MPTCP_EVENT_ADD: -+ mptcp_debug("%s add old_code %u\n", __func__, eventq->code); -+ eventq->low_prio = event->low_prio; -+ eventq->code = MPTCP_EVENT_ADD; -+ return; -+ case MPTCP_EVENT_MOD: -+ mptcp_debug("%s mod old_code %u\n", __func__, eventq->code); -+ eventq->low_prio = event->low_prio; -+ eventq->code = MPTCP_EVENT_MOD; -+ return; -+ } -+ } -+ -+ /* OK, we have to add the new address to the wait queue */ -+ eventq = kmemdup(event, sizeof(struct mptcp_addr_event), GFP_ATOMIC); -+ if (!eventq) -+ return; -+ -+ list_add_tail(&eventq->list, &fm_ns->events); -+ -+ /* Create work-queue */ -+ if (!delayed_work_pending(&fm_ns->address_worker)) -+ queue_delayed_work(mptcp_wq, &fm_ns->address_worker, -+ msecs_to_jiffies(500)); -+} -+ -+static void addr4_event_handler(const struct in_ifaddr *ifa, unsigned long event, -+ struct net *net) -+{ -+ const struct net_device *netdev = ifa->ifa_dev->dev; -+ struct mptcp_fm_ns *fm_ns = fm_get_ns(net); -+ struct mptcp_addr_event mpevent; -+ -+ if (ifa->ifa_scope > RT_SCOPE_LINK || -+ ipv4_is_loopback(ifa->ifa_local)) -+ return; -+ -+ spin_lock_bh(&fm_ns->local_lock); -+ -+ mpevent.family = AF_INET; -+ mpevent.addr.in.s_addr = ifa->ifa_local; -+ mpevent.low_prio = (netdev->flags & IFF_MPBACKUP) ? 1 : 0; -+ mpevent.if_idx = netdev->ifindex; -+ -+ if (event == NETDEV_DOWN || !netif_running(netdev) || -+ (netdev->flags & IFF_NOMULTIPATH) || !(netdev->flags & IFF_UP)) -+ mpevent.code = MPTCP_EVENT_DEL; -+ else if (event == NETDEV_UP) -+ mpevent.code = MPTCP_EVENT_ADD; -+ else if (event == NETDEV_CHANGE) -+ mpevent.code = MPTCP_EVENT_MOD; -+ -+ mptcp_debug("%s created event for %pI4, code %u prio %u idx %u\n", __func__, -+ &ifa->ifa_local, mpevent.code, mpevent.low_prio, mpevent.if_idx); -+ add_pm_event(net, &mpevent); -+ -+ spin_unlock_bh(&fm_ns->local_lock); -+ return; -+} -+ -+/* React on IPv4-addr add/rem-events */ -+static int mptcp_pm_inetaddr_event(struct notifier_block *this, -+ unsigned long event, void *ptr) -+{ -+ const struct in_ifaddr *ifa = (struct in_ifaddr *)ptr; -+ struct net *net = dev_net(ifa->ifa_dev->dev); -+ -+ if (!(event == NETDEV_UP || event == NETDEV_DOWN || -+ event == NETDEV_CHANGE)) -+ return NOTIFY_DONE; -+ -+ addr4_event_handler(ifa, event, net); -+ -+ return NOTIFY_DONE; -+} -+ -+static struct notifier_block mptcp_pm_inetaddr_notifier = { -+ .notifier_call = mptcp_pm_inetaddr_event, -+}; -+ -+#if IS_ENABLED(CONFIG_IPV6) -+ -+static int inet6_addr_event(struct notifier_block *this, unsigned long event, -+ void *ptr); -+ -+static void addr6_event_handler(const struct inet6_ifaddr *ifa, unsigned long event, -+ struct net *net) -+{ -+ const struct net_device *netdev = ifa->idev->dev; -+ int addr_type = ipv6_addr_type(&ifa->addr); -+ struct mptcp_fm_ns *fm_ns = fm_get_ns(net); -+ struct mptcp_addr_event mpevent; -+ -+ if (ifa->scope > RT_SCOPE_LINK || -+ addr_type == IPV6_ADDR_ANY || -+ (addr_type & IPV6_ADDR_LOOPBACK) || -+ (addr_type & IPV6_ADDR_LINKLOCAL)) -+ return; -+ -+ spin_lock_bh(&fm_ns->local_lock); -+ -+ mpevent.family = AF_INET6; -+ mpevent.addr.in6 = ifa->addr; -+ mpevent.low_prio = (netdev->flags & IFF_MPBACKUP) ? 1 : 0; -+ mpevent.if_idx = netdev->ifindex; -+ -+ if (event == NETDEV_DOWN || !netif_running(netdev) || -+ (netdev->flags & IFF_NOMULTIPATH) || !(netdev->flags & IFF_UP)) -+ mpevent.code = MPTCP_EVENT_DEL; -+ else if (event == NETDEV_UP) -+ mpevent.code = MPTCP_EVENT_ADD; -+ else if (event == NETDEV_CHANGE) -+ mpevent.code = MPTCP_EVENT_MOD; -+ -+ mptcp_debug("%s created event for %pI6, code %u prio %u idx %u\n", __func__, -+ &ifa->addr, mpevent.code, mpevent.low_prio, mpevent.if_idx); -+ add_pm_event(net, &mpevent); -+ -+ spin_unlock_bh(&fm_ns->local_lock); -+ return; -+} -+ -+/* React on IPv6-addr add/rem-events */ -+static int inet6_addr_event(struct notifier_block *this, unsigned long event, -+ void *ptr) -+{ -+ struct inet6_ifaddr *ifa6 = (struct inet6_ifaddr *)ptr; -+ struct net *net = dev_net(ifa6->idev->dev); -+ -+ if (!(event == NETDEV_UP || event == NETDEV_DOWN || -+ event == NETDEV_CHANGE)) -+ return NOTIFY_DONE; -+ -+ addr6_event_handler(ifa6, event, net); -+ -+ return NOTIFY_DONE; -+} -+ -+static struct notifier_block inet6_addr_notifier = { -+ .notifier_call = inet6_addr_event, -+}; -+ -+#endif -+ -+/* React on ifup/down-events */ -+static int netdev_event(struct notifier_block *this, unsigned long event, -+ void *ptr) -+{ -+ const struct net_device *dev = netdev_notifier_info_to_dev(ptr); -+ struct in_device *in_dev; -+#if IS_ENABLED(CONFIG_IPV6) -+ struct inet6_dev *in6_dev; -+#endif -+ -+ if (!(event == NETDEV_UP || event == NETDEV_DOWN || -+ event == NETDEV_CHANGE)) -+ return NOTIFY_DONE; -+ -+ rcu_read_lock(); -+ in_dev = __in_dev_get_rtnl(dev); -+ -+ if (in_dev) { -+ for_ifa(in_dev) { -+ mptcp_pm_inetaddr_event(NULL, event, ifa); -+ } endfor_ifa(in_dev); -+ } -+ -+#if IS_ENABLED(CONFIG_IPV6) -+ in6_dev = __in6_dev_get(dev); -+ -+ if (in6_dev) { -+ struct inet6_ifaddr *ifa6; -+ list_for_each_entry(ifa6, &in6_dev->addr_list, if_list) -+ inet6_addr_event(NULL, event, ifa6); -+ } -+#endif -+ -+ rcu_read_unlock(); -+ return NOTIFY_DONE; -+} -+ -+static struct notifier_block mptcp_pm_netdev_notifier = { -+ .notifier_call = netdev_event, -+}; -+ -+static void full_mesh_add_raddr(struct mptcp_cb *mpcb, -+ const union inet_addr *addr, -+ sa_family_t family, __be16 port, u8 id) -+{ -+ if (family == AF_INET) -+ mptcp_addv4_raddr(mpcb, &addr->in, port, id); -+ else -+ mptcp_addv6_raddr(mpcb, &addr->in6, port, id); -+} -+ -+static void full_mesh_new_session(const struct sock *meta_sk) -+{ -+ struct mptcp_loc_addr *mptcp_local; -+ struct mptcp_cb *mpcb = tcp_sk(meta_sk)->mpcb; -+ struct fullmesh_priv *fmp = fullmesh_get_priv(mpcb); -+ const struct mptcp_fm_ns *fm_ns = fm_get_ns(sock_net(meta_sk)); -+ struct tcp_sock *master_tp = tcp_sk(mpcb->master_sk); -+ int i, index, if_idx = 0; -+ union inet_addr saddr, daddr; -+ sa_family_t family = AF_INET; -+ bool meta_v4 = meta_sk->sk_family == AF_INET; -+ -+ /* Init local variables necessary for the rest */ -+ if (meta_sk->sk_family == AF_INET || mptcp_v6_is_v4_mapped(meta_sk)) { -+ saddr.ip = inet_sk(meta_sk)->inet_saddr; -+ daddr.ip = inet_sk(meta_sk)->inet_daddr; -+ if_idx = mpcb->master_sk->sk_bound_dev_if; -+ family = AF_INET; -+#if IS_ENABLED(CONFIG_IPV6) -+ } else { -+ saddr.in6 = inet6_sk(meta_sk)->saddr; -+ daddr.in6 = meta_sk->sk_v6_daddr; -+ if_idx = mpcb->master_sk->sk_bound_dev_if; -+ family = AF_INET6; -+#endif -+ } -+ -+ if (inet_sk(meta_sk)->transparent) -+ if_idx = inet_sk(meta_sk)->rx_dst_ifindex; -+ -+ rcu_read_lock_bh(); -+ mptcp_local = rcu_dereference(fm_ns->local); -+ -+ if (inet_sk(meta_sk)->transparent) -+ index = mptcp_find_address_transp(mptcp_local, family, if_idx); -+ else -+ index = mptcp_find_address(mptcp_local, family, &saddr, if_idx); -+ if (index < 0) -+ goto fallback; -+ -+ if (family == AF_INET) -+ master_tp->mptcp->low_prio = mptcp_local->locaddr4[index].low_prio; -+ else -+ master_tp->mptcp->low_prio = mptcp_local->locaddr6[index].low_prio; -+ master_tp->mptcp->send_mp_prio = master_tp->mptcp->low_prio; -+ -+ full_mesh_add_raddr(mpcb, &daddr, family, 0, 0); -+ mptcp_set_init_addr_bit(mpcb, &daddr, family, index); -+ -+ /* Initialize workqueue-struct */ -+ INIT_WORK(&fmp->subflow_work, create_subflow_worker); -+ INIT_DELAYED_WORK(&fmp->subflow_retry_work, retry_subflow_worker); -+ fmp->mpcb = mpcb; -+ -+ if (!meta_v4 && meta_sk->sk_ipv6only) -+ goto skip_ipv4; -+ -+ /* Look for the address among the local addresses */ -+ mptcp_for_each_bit_set(mptcp_local->loc4_bits, i) { -+ __be32 ifa_address = mptcp_local->locaddr4[i].addr.s_addr; -+ -+ /* We do not need to announce the initial subflow's address again */ -+ if (family == AF_INET && -+ (!if_idx || mptcp_local->locaddr4[i].if_idx == if_idx) && -+ saddr.ip == ifa_address) -+ continue; -+ -+ fmp->add_addr++; -+ mpcb->addr_signal = 1; -+ } -+ -+skip_ipv4: -+#if IS_ENABLED(CONFIG_IPV6) -+ /* skip IPv6 addresses if meta-socket is IPv4 */ -+ if (meta_v4) -+ goto skip_ipv6; -+ -+ mptcp_for_each_bit_set(mptcp_local->loc6_bits, i) { -+ const struct in6_addr *ifa6 = &mptcp_local->locaddr6[i].addr; -+ -+ /* We do not need to announce the initial subflow's address again */ -+ if (family == AF_INET6 && -+ (!if_idx || mptcp_local->locaddr6[i].if_idx == if_idx) && -+ ipv6_addr_equal(&saddr.in6, ifa6)) -+ continue; -+ -+ fmp->add_addr++; -+ mpcb->addr_signal = 1; -+ } -+ -+skip_ipv6: -+#endif -+ -+ rcu_read_unlock_bh(); -+ -+ if (family == AF_INET) -+ fmp->announced_addrs_v4 |= (1 << index); -+ else -+ fmp->announced_addrs_v6 |= (1 << index); -+ -+ for (i = fmp->add_addr; i && fmp->add_addr; i--) -+ tcp_send_ack(mpcb->master_sk); -+ -+ if (master_tp->mptcp->send_mp_prio) -+ tcp_send_ack(mpcb->master_sk); -+ -+ return; -+ -+fallback: -+ rcu_read_unlock_bh(); -+ mptcp_fallback_default(mpcb); -+ return; -+} -+ -+static void full_mesh_create_subflows(struct sock *meta_sk) -+{ -+ struct mptcp_cb *mpcb = tcp_sk(meta_sk)->mpcb; -+ struct fullmesh_priv *fmp = fullmesh_get_priv(mpcb); -+ -+ if (mptcp_in_infinite_mapping_weak(mpcb) || -+ mpcb->server_side || sock_flag(meta_sk, SOCK_DEAD)) -+ return; -+ -+ if (mpcb->master_sk && -+ !tcp_sk(mpcb->master_sk)->mptcp->fully_established) -+ return; -+ -+ if (!work_pending(&fmp->subflow_work)) { -+ sock_hold(meta_sk); -+ refcount_inc(&mpcb->mpcb_refcnt); -+ queue_work(mptcp_wq, &fmp->subflow_work); -+ } -+} -+ -+/* Called upon release_sock, if the socket was owned by the user during -+ * a path-management event. -+ */ -+static void full_mesh_release_sock(struct sock *meta_sk) -+{ -+ struct mptcp_loc_addr *mptcp_local; -+ struct mptcp_cb *mpcb = tcp_sk(meta_sk)->mpcb; -+ struct fullmesh_priv *fmp = fullmesh_get_priv(mpcb); -+ const struct mptcp_fm_ns *fm_ns = fm_get_ns(sock_net(meta_sk)); -+ bool meta_v4 = meta_sk->sk_family == AF_INET; -+ struct mptcp_tcp_sock *mptcp; -+ struct hlist_node *tmp; -+ int i; -+ -+ rcu_read_lock_bh(); -+ mptcp_local = rcu_dereference(fm_ns->local); -+ -+ if (!meta_v4 && meta_sk->sk_ipv6only) -+ goto skip_ipv4; -+ -+ /* First, detect modifications or additions */ -+ mptcp_for_each_bit_set(mptcp_local->loc4_bits, i) { -+ struct in_addr ifa = mptcp_local->locaddr4[i].addr; -+ bool found = false; -+ -+ mptcp_for_each_sub(mpcb, mptcp) { -+ struct sock *sk = mptcp_to_sock(mptcp); -+ struct tcp_sock *tp = tcp_sk(sk); -+ -+ if (sk->sk_family == AF_INET6 && -+ !mptcp_v6_is_v4_mapped(sk)) -+ continue; -+ -+ if (inet_sk(sk)->inet_saddr != ifa.s_addr) -+ continue; -+ -+ found = true; -+ -+ if (mptcp_local->locaddr4[i].low_prio != tp->mptcp->low_prio) { -+ tp->mptcp->send_mp_prio = 1; -+ tp->mptcp->low_prio = mptcp_local->locaddr4[i].low_prio; -+ -+ tcp_send_ack(sk); -+ } -+ } -+ -+ if (!found) { -+ struct sock *sk; -+ -+ fmp->add_addr++; -+ mpcb->addr_signal = 1; -+ -+ sk = mptcp_select_ack_sock(meta_sk); -+ if (sk) -+ tcp_send_ack(sk); -+ full_mesh_create_subflows(meta_sk); -+ } -+ } -+ -+skip_ipv4: -+#if IS_ENABLED(CONFIG_IPV6) -+ /* skip IPv6 addresses if meta-socket is IPv4 */ -+ if (meta_v4) -+ goto removal; -+ -+ mptcp_for_each_bit_set(mptcp_local->loc6_bits, i) { -+ struct in6_addr ifa = mptcp_local->locaddr6[i].addr; -+ bool found = false; -+ -+ mptcp_for_each_sub(mpcb, mptcp) { -+ struct sock *sk = mptcp_to_sock(mptcp); -+ struct tcp_sock *tp = tcp_sk(sk); -+ -+ if (sk->sk_family == AF_INET || -+ mptcp_v6_is_v4_mapped(sk)) -+ continue; -+ -+ if (!ipv6_addr_equal(&inet6_sk(sk)->saddr, &ifa)) -+ continue; -+ -+ found = true; -+ -+ if (mptcp_local->locaddr6[i].low_prio != tp->mptcp->low_prio) { -+ tp->mptcp->send_mp_prio = 1; -+ tp->mptcp->low_prio = mptcp_local->locaddr6[i].low_prio; -+ -+ tcp_send_ack(sk); -+ } -+ } -+ -+ if (!found) { -+ struct sock *sk; -+ -+ fmp->add_addr++; -+ mpcb->addr_signal = 1; -+ -+ sk = mptcp_select_ack_sock(meta_sk); -+ if (sk) -+ tcp_send_ack(sk); -+ full_mesh_create_subflows(meta_sk); -+ } -+ } -+ -+removal: -+#endif -+ -+ /* Now, detect address-removals */ -+ mptcp_for_each_sub_safe(mpcb, mptcp, tmp) { -+ struct sock *sk = mptcp_to_sock(mptcp); -+ bool shall_remove = true; -+ -+ if (sk->sk_family == AF_INET || mptcp_v6_is_v4_mapped(sk)) { -+ mptcp_for_each_bit_set(mptcp_local->loc4_bits, i) { -+ if (inet_sk(sk)->inet_saddr == mptcp_local->locaddr4[i].addr.s_addr) { -+ shall_remove = false; -+ break; -+ } -+ } -+ } else { -+ mptcp_for_each_bit_set(mptcp_local->loc6_bits, i) { -+ if (ipv6_addr_equal(&inet6_sk(sk)->saddr, &mptcp_local->locaddr6[i].addr)) { -+ shall_remove = false; -+ break; -+ } -+ } -+ } -+ -+ if (shall_remove) { -+ /* Reinject, so that pf = 1 and so we -+ * won't select this one as the -+ * ack-sock. -+ */ -+ mptcp_reinject_data(sk, 0); -+ -+ announce_remove_addr(tcp_sk(sk)->mptcp->loc_id, -+ meta_sk); -+ -+ mptcp_sub_force_close(sk); -+ } -+ } -+ -+ /* Just call it optimistically. It actually cannot do any harm */ -+ update_addr_bitfields(meta_sk, mptcp_local); -+ -+ rcu_read_unlock_bh(); -+} -+ -+static int full_mesh_get_local_id(const struct sock *meta_sk, -+ sa_family_t family, union inet_addr *addr, -+ bool *low_prio) -+{ -+ struct mptcp_loc_addr *mptcp_local; -+ const struct mptcp_fm_ns *fm_ns = fm_get_ns(sock_net(meta_sk)); -+ int index, id = -1; -+ -+ /* Handle the backup-flows */ -+ rcu_read_lock_bh(); -+ mptcp_local = rcu_dereference(fm_ns->local); -+ -+ index = mptcp_find_address(mptcp_local, family, addr, 0); -+ -+ if (index != -1) { -+ if (family == AF_INET) { -+ id = mptcp_local->locaddr4[index].loc4_id; -+ *low_prio = mptcp_local->locaddr4[index].low_prio; -+ } else { -+ id = mptcp_local->locaddr6[index].loc6_id; -+ *low_prio = mptcp_local->locaddr6[index].low_prio; -+ } -+ } -+ -+ -+ rcu_read_unlock_bh(); -+ -+ return id; -+} -+ -+static void full_mesh_addr_signal(struct sock *sk, unsigned *size, -+ struct tcp_out_options *opts, -+ struct sk_buff *skb) -+{ -+ const struct tcp_sock *tp = tcp_sk(sk); -+ struct mptcp_cb *mpcb = tp->mpcb; -+ struct sock *meta_sk = mpcb->meta_sk; -+ struct fullmesh_priv *fmp = fullmesh_get_priv(mpcb); -+ struct mptcp_loc_addr *mptcp_local; -+ struct mptcp_fm_ns *fm_ns = fm_get_ns(sock_net(sk)); -+ int remove_addr_len; -+ u8 unannouncedv4 = 0, unannouncedv6 = 0; -+ bool meta_v4 = meta_sk->sk_family == AF_INET; -+ -+ mpcb->addr_signal = 0; -+ -+ if (likely(!fmp->add_addr)) -+ goto remove_addr; -+ -+ rcu_read_lock_bh(); -+ mptcp_local = rcu_dereference(fm_ns->local); -+ -+ if (!meta_v4 && meta_sk->sk_ipv6only) -+ goto skip_ipv4; -+ -+ /* IPv4 */ -+ unannouncedv4 = (~fmp->announced_addrs_v4) & mptcp_local->loc4_bits; -+ if (unannouncedv4 && -+ ((mpcb->mptcp_ver == MPTCP_VERSION_0 && -+ MAX_TCP_OPTION_SPACE - *size >= MPTCP_SUB_LEN_ADD_ADDR4_ALIGN) || -+ (mpcb->mptcp_ver >= MPTCP_VERSION_1 && -+ MAX_TCP_OPTION_SPACE - *size >= MPTCP_SUB_LEN_ADD_ADDR4_ALIGN_VER1))) { -+ int ind = mptcp_find_free_index(~unannouncedv4); -+ -+ opts->options |= OPTION_MPTCP; -+ opts->mptcp_options |= OPTION_ADD_ADDR; -+ opts->add_addr4.addr_id = mptcp_local->locaddr4[ind].loc4_id; -+ opts->add_addr4.addr = mptcp_local->locaddr4[ind].addr; -+ opts->add_addr_v4 = 1; -+ if (mpcb->mptcp_ver >= MPTCP_VERSION_1) { -+ u8 mptcp_hash_mac[20]; -+ u8 no_key[8]; -+ -+ *(u64 *)no_key = 0; -+ mptcp_hmac_sha1((u8 *)&mpcb->mptcp_loc_key, -+ (u8 *)no_key, -+ (u32 *)mptcp_hash_mac, 2, -+ 1, (u8 *)&mptcp_local->locaddr4[ind].loc4_id, -+ 4, (u8 *)&opts->add_addr4.addr.s_addr); -+ opts->add_addr4.trunc_mac = *(u64 *)mptcp_hash_mac; -+ } -+ -+ if (skb) { -+ fmp->announced_addrs_v4 |= (1 << ind); -+ fmp->add_addr--; -+ } -+ -+ if (mpcb->mptcp_ver < MPTCP_VERSION_1) -+ *size += MPTCP_SUB_LEN_ADD_ADDR4_ALIGN; -+ if (mpcb->mptcp_ver >= MPTCP_VERSION_1) -+ *size += MPTCP_SUB_LEN_ADD_ADDR4_ALIGN_VER1; -+ -+ goto skip_ipv6; -+ } -+ -+ if (meta_v4) -+ goto skip_ipv6; -+skip_ipv4: -+ /* IPv6 */ -+ unannouncedv6 = (~fmp->announced_addrs_v6) & mptcp_local->loc6_bits; -+ if (unannouncedv6 && -+ ((mpcb->mptcp_ver == MPTCP_VERSION_0 && -+ MAX_TCP_OPTION_SPACE - *size >= MPTCP_SUB_LEN_ADD_ADDR6_ALIGN) || -+ (mpcb->mptcp_ver >= MPTCP_VERSION_1 && -+ MAX_TCP_OPTION_SPACE - *size >= MPTCP_SUB_LEN_ADD_ADDR6_ALIGN_VER1))) { -+ int ind = mptcp_find_free_index(~unannouncedv6); -+ -+ opts->options |= OPTION_MPTCP; -+ opts->mptcp_options |= OPTION_ADD_ADDR; -+ opts->add_addr6.addr_id = mptcp_local->locaddr6[ind].loc6_id; -+ opts->add_addr6.addr = mptcp_local->locaddr6[ind].addr; -+ opts->add_addr_v6 = 1; -+ if (mpcb->mptcp_ver >= MPTCP_VERSION_1) { -+ u8 mptcp_hash_mac[20]; -+ u8 no_key[8]; -+ -+ *(u64 *)no_key = 0; -+ mptcp_hmac_sha1((u8 *)&mpcb->mptcp_loc_key, -+ (u8 *)no_key, -+ (u32 *)mptcp_hash_mac, 2, -+ 1, (u8 *)&mptcp_local->locaddr6[ind].loc6_id, -+ 16, (u8 *)&opts->add_addr6.addr.s6_addr); -+ opts->add_addr6.trunc_mac = *(u64 *)mptcp_hash_mac; -+ } -+ -+ if (skb) { -+ fmp->announced_addrs_v6 |= (1 << ind); -+ fmp->add_addr--; -+ } -+ if (mpcb->mptcp_ver < MPTCP_VERSION_1) -+ *size += MPTCP_SUB_LEN_ADD_ADDR6_ALIGN; -+ if (mpcb->mptcp_ver >= MPTCP_VERSION_1) -+ *size += MPTCP_SUB_LEN_ADD_ADDR6_ALIGN_VER1; -+ } -+ -+skip_ipv6: -+ rcu_read_unlock_bh(); -+ -+ if (!unannouncedv4 && !unannouncedv6 && skb) -+ fmp->add_addr--; -+ -+remove_addr: -+ if (likely(!fmp->remove_addrs)) -+ goto exit; -+ -+ remove_addr_len = mptcp_sub_len_remove_addr_align(fmp->remove_addrs); -+ if (MAX_TCP_OPTION_SPACE - *size < remove_addr_len) -+ goto exit; -+ -+ opts->options |= OPTION_MPTCP; -+ opts->mptcp_options |= OPTION_REMOVE_ADDR; -+ opts->remove_addrs = fmp->remove_addrs; -+ *size += remove_addr_len; -+ if (skb) -+ fmp->remove_addrs = 0; -+ -+exit: -+ mpcb->addr_signal = !!(fmp->add_addr || fmp->remove_addrs); -+} -+ -+static void full_mesh_rem_raddr(struct mptcp_cb *mpcb, u8 rem_id) -+{ -+ mptcp_v4_rem_raddress(mpcb, rem_id); -+ mptcp_v6_rem_raddress(mpcb, rem_id); -+} -+ -+static void full_mesh_delete_subflow(struct sock *sk) -+{ -+ struct fullmesh_priv *fmp = fullmesh_get_priv(tcp_sk(sk)->mpcb); -+ struct mptcp_fm_ns *fm_ns = fm_get_ns(sock_net(sk)); -+ struct sock *meta_sk = mptcp_meta_sk(sk); -+ struct mptcp_loc_addr *mptcp_local; -+ int index, i; -+ -+ if (!create_on_err) -+ return; -+ -+ if (!mptcp_can_new_subflow(meta_sk)) -+ return; -+ -+ rcu_read_lock_bh(); -+ mptcp_local = rcu_dereference_bh(fm_ns->local); -+ -+ if (sk->sk_family == AF_INET || mptcp_v6_is_v4_mapped(sk)) { -+ union inet_addr saddr; -+ -+ saddr.ip = inet_sk(sk)->inet_saddr; -+ index = mptcp_find_address(mptcp_local, AF_INET, &saddr, -+ sk->sk_bound_dev_if); -+ if (index < 0) -+ goto out; -+ -+ mptcp_for_each_bit_set(fmp->rem4_bits, i) { -+ struct fullmesh_rem4 *rem4 = &fmp->remaddr4[i]; -+ -+ if (rem4->addr.s_addr != sk->sk_daddr) -+ continue; -+ -+ if (rem4->port && rem4->port != inet_sk(sk)->inet_dport) -+ continue; -+ -+ rem4->bitfield &= ~(1 << index); -+ } -+#if IS_ENABLED(CONFIG_IPV6) -+ } else { -+ union inet_addr saddr; -+ -+ saddr.in6 = inet6_sk(sk)->saddr; -+ index = mptcp_find_address(mptcp_local, AF_INET6, &saddr, -+ sk->sk_bound_dev_if); -+ if (index < 0) -+ goto out; -+ -+ mptcp_for_each_bit_set(fmp->rem6_bits, i) { -+ struct fullmesh_rem6 *rem6 = &fmp->remaddr6[i]; -+ -+ if (!ipv6_addr_equal(&rem6->addr, &sk->sk_v6_daddr)) -+ continue; -+ -+ if (rem6->port && rem6->port != inet_sk(sk)->inet_dport) -+ continue; -+ -+ rem6->bitfield &= ~(1 << index); -+ } -+#endif -+ } -+ -+out: -+ rcu_read_unlock_bh(); -+ -+ /* re-schedule the creation of failed subflows */ -+ if (tcp_sk(sk)->mptcp->sk_err == ETIMEDOUT || sk->sk_err == ETIMEDOUT) -+ full_mesh_create_subflows(meta_sk); -+} -+ -+/* Output /proc/net/mptcp_fullmesh */ -+static int mptcp_fm_seq_show(struct seq_file *seq, void *v) -+{ -+ const struct net *net = seq->private; -+ struct mptcp_loc_addr *mptcp_local; -+ const struct mptcp_fm_ns *fm_ns = fm_get_ns(net); -+ int i; -+ -+ seq_printf(seq, "Index, Address-ID, Backup, IP-address, if-idx\n"); -+ -+ rcu_read_lock_bh(); -+ mptcp_local = rcu_dereference(fm_ns->local); -+ -+ seq_printf(seq, "IPv4, next v4-index: %u\n", mptcp_local->next_v4_index); -+ -+ mptcp_for_each_bit_set(mptcp_local->loc4_bits, i) { -+ struct mptcp_loc4 *loc4 = &mptcp_local->locaddr4[i]; -+ -+ seq_printf(seq, "%u, %u, %u, %pI4 %u\n", i, loc4->loc4_id, -+ loc4->low_prio, &loc4->addr, loc4->if_idx); -+ } -+ -+ seq_printf(seq, "IPv6, next v6-index: %u\n", mptcp_local->next_v6_index); -+ -+ mptcp_for_each_bit_set(mptcp_local->loc6_bits, i) { -+ struct mptcp_loc6 *loc6 = &mptcp_local->locaddr6[i]; -+ -+ seq_printf(seq, "%u, %u, %u, %pI6 %u\n", i, loc6->loc6_id, -+ loc6->low_prio, &loc6->addr, loc6->if_idx); -+ } -+ rcu_read_unlock_bh(); -+ -+ return 0; -+} -+ -+static int mptcp_fm_init_net(struct net *net) -+{ -+ struct mptcp_loc_addr *mptcp_local; -+ struct mptcp_fm_ns *fm_ns; -+ int err = 0; -+ -+ fm_ns = kzalloc(sizeof(*fm_ns), GFP_KERNEL); -+ if (!fm_ns) -+ return -ENOBUFS; -+ -+ mptcp_local = kzalloc(sizeof(*mptcp_local), GFP_KERNEL); -+ if (!mptcp_local) { -+ err = -ENOBUFS; -+ goto err_mptcp_local; -+ } -+ -+ if (!proc_create_net_single("mptcp_fullmesh", S_IRUGO, net->proc_net, -+ mptcp_fm_seq_show, NULL)) { -+ err = -ENOMEM; -+ goto err_seq_fops; -+ } -+ -+ mptcp_local->next_v4_index = 1; -+ -+ rcu_assign_pointer(fm_ns->local, mptcp_local); -+ INIT_DELAYED_WORK(&fm_ns->address_worker, mptcp_address_worker); -+ INIT_LIST_HEAD(&fm_ns->events); -+ spin_lock_init(&fm_ns->local_lock); -+ fm_ns->net = net; -+ net->mptcp.path_managers[MPTCP_PM_FULLMESH] = fm_ns; -+ -+ return 0; -+err_seq_fops: -+ kfree(mptcp_local); -+err_mptcp_local: -+ kfree(fm_ns); -+ return err; -+} -+ -+static void mptcp_fm_exit_net(struct net *net) -+{ -+ struct mptcp_addr_event *eventq, *tmp; -+ struct mptcp_fm_ns *fm_ns; -+ struct mptcp_loc_addr *mptcp_local; -+ -+ fm_ns = fm_get_ns(net); -+ cancel_delayed_work_sync(&fm_ns->address_worker); -+ -+ rcu_read_lock_bh(); -+ -+ mptcp_local = rcu_dereference_bh(fm_ns->local); -+ kfree_rcu(mptcp_local, rcu); -+ -+ spin_lock(&fm_ns->local_lock); -+ list_for_each_entry_safe(eventq, tmp, &fm_ns->events, list) { -+ list_del(&eventq->list); -+ kfree(eventq); -+ } -+ spin_unlock(&fm_ns->local_lock); -+ -+ rcu_read_unlock_bh(); -+ -+ remove_proc_entry("mptcp_fullmesh", net->proc_net); -+ -+ kfree(fm_ns); -+} -+ -+static struct pernet_operations full_mesh_net_ops = { -+ .init = mptcp_fm_init_net, -+ .exit = mptcp_fm_exit_net, -+}; -+ -+static struct mptcp_pm_ops full_mesh __read_mostly = { -+ .new_session = full_mesh_new_session, -+ .release_sock = full_mesh_release_sock, -+ .fully_established = full_mesh_create_subflows, -+ .new_remote_address = full_mesh_create_subflows, -+ .get_local_id = full_mesh_get_local_id, -+ .addr_signal = full_mesh_addr_signal, -+ .add_raddr = full_mesh_add_raddr, -+ .rem_raddr = full_mesh_rem_raddr, -+ .delete_subflow = full_mesh_delete_subflow, -+ .name = "fullmesh", -+ .owner = THIS_MODULE, -+}; -+ -+/* General initialization of MPTCP_PM */ -+static int __init full_mesh_register(void) -+{ -+ int ret; -+ -+ BUILD_BUG_ON(sizeof(struct fullmesh_priv) > MPTCP_PM_SIZE); -+ -+ ret = register_pernet_subsys(&full_mesh_net_ops); -+ if (ret) -+ goto out; -+ -+ ret = register_inetaddr_notifier(&mptcp_pm_inetaddr_notifier); -+ if (ret) -+ goto err_reg_inetaddr; -+ ret = register_netdevice_notifier(&mptcp_pm_netdev_notifier); -+ if (ret) -+ goto err_reg_netdev; -+ -+#if IS_ENABLED(CONFIG_IPV6) -+ ret = register_inet6addr_notifier(&inet6_addr_notifier); -+ if (ret) -+ goto err_reg_inet6addr; -+#endif -+ -+ ret = mptcp_register_path_manager(&full_mesh); -+ if (ret) -+ goto err_reg_pm; -+ -+out: -+ return ret; -+ -+ -+err_reg_pm: -+#if IS_ENABLED(CONFIG_IPV6) -+ unregister_inet6addr_notifier(&inet6_addr_notifier); -+err_reg_inet6addr: -+#endif -+ unregister_netdevice_notifier(&mptcp_pm_netdev_notifier); -+err_reg_netdev: -+ unregister_inetaddr_notifier(&mptcp_pm_inetaddr_notifier); -+err_reg_inetaddr: -+ unregister_pernet_subsys(&full_mesh_net_ops); -+ goto out; -+} -+ -+static void full_mesh_unregister(void) -+{ -+#if IS_ENABLED(CONFIG_IPV6) -+ unregister_inet6addr_notifier(&inet6_addr_notifier); -+#endif -+ unregister_netdevice_notifier(&mptcp_pm_netdev_notifier); -+ unregister_inetaddr_notifier(&mptcp_pm_inetaddr_notifier); -+ unregister_pernet_subsys(&full_mesh_net_ops); -+ mptcp_unregister_path_manager(&full_mesh); -+} -+ -+module_init(full_mesh_register); -+module_exit(full_mesh_unregister); -+ -+MODULE_AUTHOR("Christoph Paasch"); -+MODULE_LICENSE("GPL"); -+MODULE_DESCRIPTION("Full-Mesh MPTCP"); -+MODULE_VERSION("0.88"); -diff -aurN linux-4.19.104/net/mptcp/mptcp_input.c mptcp-mptcp_v0.95/net/mptcp/mptcp_input.c ---- linux-4.19.104/net/mptcp/mptcp_input.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_v0.95/net/mptcp/mptcp_input.c 2020-02-17 11:29:55.000000000 +0100 -@@ -0,0 +1,2431 @@ -+/* -+ * MPTCP implementation - Sending side -+ * -+ * Initial Design & Implementation: -+ * Sébastien Barré -+ * -+ * Current Maintainer & Author: -+ * Christoph Paasch -+ * -+ * Additional authors: -+ * Jaakko Korkeaniemi -+ * Gregory Detal -+ * Fabien Duchêne -+ * Andreas Seelinger -+ * Lavkesh Lahngir -+ * Andreas Ripke -+ * Vlad Dogaru -+ * Octavian Purdila -+ * John Ronan -+ * Catalin Nicutar -+ * Brandon Heller -+ * -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version -+ * 2 of the License, or (at your option) any later version. -+ */ -+ -+#include -+ -+#include -+#include -+#include -+ -+#include -+ -+/* is seq1 < seq2 ? */ -+static inline bool before64(const u64 seq1, const u64 seq2) -+{ -+ return (s64)(seq1 - seq2) < 0; -+} -+ -+/* is seq1 > seq2 ? */ -+#define after64(seq1, seq2) before64(seq2, seq1) -+ -+static inline void mptcp_become_fully_estab(struct sock *sk) -+{ -+ tcp_sk(sk)->mptcp->fully_established = 1; -+ -+ if (is_master_tp(tcp_sk(sk)) && -+ tcp_sk(sk)->mpcb->pm_ops->fully_established) -+ tcp_sk(sk)->mpcb->pm_ops->fully_established(mptcp_meta_sk(sk)); -+} -+ -+/* Similar to tcp_tso_acked without any memory accounting */ -+static inline int mptcp_tso_acked_reinject(const struct sock *meta_sk, -+ struct sk_buff *skb) -+{ -+ const struct tcp_sock *meta_tp = tcp_sk(meta_sk); -+ u32 packets_acked, len, delta_truesize; -+ -+ BUG_ON(!after(TCP_SKB_CB(skb)->end_seq, meta_tp->snd_una)); -+ -+ packets_acked = tcp_skb_pcount(skb); -+ -+ if (skb_unclone(skb, GFP_ATOMIC)) -+ return 0; -+ -+ len = meta_tp->snd_una - TCP_SKB_CB(skb)->seq; -+ delta_truesize = __pskb_trim_head(skb, len); -+ -+ TCP_SKB_CB(skb)->seq += len; -+ skb->ip_summed = CHECKSUM_PARTIAL; -+ -+ if (delta_truesize) -+ skb->truesize -= delta_truesize; -+ -+ /* Any change of skb->len requires recalculation of tso factor. */ -+ if (tcp_skb_pcount(skb) > 1) -+ tcp_set_skb_tso_segs(skb, tcp_skb_mss(skb)); -+ packets_acked -= tcp_skb_pcount(skb); -+ -+ if (packets_acked) { -+ BUG_ON(tcp_skb_pcount(skb) == 0); -+ BUG_ON(!before(TCP_SKB_CB(skb)->seq, TCP_SKB_CB(skb)->end_seq)); -+ } -+ -+ return packets_acked; -+} -+ -+/* Cleans the meta-socket retransmission queue and the reinject-queue. */ -+static void mptcp_clean_rtx_queue(struct sock *meta_sk, u32 prior_snd_una) -+{ -+ struct sk_buff *skb, *tmp, *next; -+ struct tcp_sock *meta_tp = tcp_sk(meta_sk); -+ struct mptcp_cb *mpcb = meta_tp->mpcb; -+ bool acked = false; -+ u32 acked_pcount; -+ -+ for (skb = skb_rb_first(&meta_sk->tcp_rtx_queue); skb; skb = next) { -+ bool fully_acked = true; -+ -+ if (before(meta_tp->snd_una, TCP_SKB_CB(skb)->end_seq)) { -+ if (tcp_skb_pcount(skb) == 1 || -+ !after(meta_tp->snd_una, TCP_SKB_CB(skb)->seq)) -+ break; -+ -+ acked_pcount = tcp_tso_acked(meta_sk, skb); -+ if (!acked_pcount) -+ break; -+ -+ fully_acked = false; -+ } else { -+ acked_pcount = tcp_skb_pcount(skb); -+ } -+ -+ acked = true; -+ meta_tp->packets_out -= acked_pcount; -+ meta_tp->retrans_stamp = 0; -+ -+ if (!fully_acked) -+ break; -+ -+ next = skb_rb_next(skb); -+ -+ if (mptcp_is_data_fin(skb)) { -+ struct mptcp_tcp_sock *mptcp; -+ struct hlist_node *tmp; -+ -+ /* DATA_FIN has been acknowledged - now we can close -+ * the subflows -+ */ -+ mptcp_for_each_sub_safe(mpcb, mptcp, tmp) { -+ struct sock *sk_it = mptcp_to_sock(mptcp); -+ unsigned long delay = 0; -+ -+ /* If we are the passive closer, don't trigger -+ * subflow-fin until the subflow has been finned -+ * by the peer - thus we add a delay. -+ */ -+ if (mpcb->passive_close && -+ sk_it->sk_state == TCP_ESTABLISHED) -+ delay = inet_csk(sk_it)->icsk_rto << 3; -+ -+ mptcp_sub_close(sk_it, delay); -+ } -+ } -+ tcp_rtx_queue_unlink_and_free(skb, meta_sk); -+ } -+ /* Remove acknowledged data from the reinject queue */ -+ skb_queue_walk_safe(&mpcb->reinject_queue, skb, tmp) { -+ if (before(meta_tp->snd_una, TCP_SKB_CB(skb)->end_seq)) { -+ if (tcp_skb_pcount(skb) == 1 || -+ !after(meta_tp->snd_una, TCP_SKB_CB(skb)->seq)) -+ break; -+ -+ mptcp_tso_acked_reinject(meta_sk, skb); -+ break; -+ } -+ -+ __skb_unlink(skb, &mpcb->reinject_queue); -+ __kfree_skb(skb); -+ } -+ -+ if (likely(between(meta_tp->snd_up, prior_snd_una, meta_tp->snd_una))) -+ meta_tp->snd_up = meta_tp->snd_una; -+ -+ if (acked) { -+ tcp_rearm_rto(meta_sk); -+ /* Normally this is done in tcp_try_undo_loss - but MPTCP -+ * does not call this function. -+ */ -+ inet_csk(meta_sk)->icsk_retransmits = 0; -+ } -+} -+ -+/* Inspired by tcp_rcv_state_process */ -+static int mptcp_rcv_state_process(struct sock *meta_sk, struct sock *sk, -+ const struct sk_buff *skb, u32 data_seq, -+ u16 data_len) -+{ -+ struct tcp_sock *meta_tp = tcp_sk(meta_sk), *tp = tcp_sk(sk); -+ const struct tcphdr *th = tcp_hdr(skb); -+ -+ /* State-machine handling if FIN has been enqueued and he has -+ * been acked (snd_una == write_seq) - it's important that this -+ * here is after sk_wmem_free_skb because otherwise -+ * sk_forward_alloc is wrong upon inet_csk_destroy_sock() -+ */ -+ switch (meta_sk->sk_state) { -+ case TCP_FIN_WAIT1: { -+ struct dst_entry *dst; -+ int tmo; -+ -+ if (meta_tp->snd_una != meta_tp->write_seq) -+ break; -+ -+ tcp_set_state(meta_sk, TCP_FIN_WAIT2); -+ meta_sk->sk_shutdown |= SEND_SHUTDOWN; -+ -+ dst = __sk_dst_get(sk); -+ if (dst) -+ dst_confirm(dst); -+ -+ if (!sock_flag(meta_sk, SOCK_DEAD)) { -+ /* Wake up lingering close() */ -+ meta_sk->sk_state_change(meta_sk); -+ break; -+ } -+ -+ if (meta_tp->linger2 < 0 || -+ (data_len && -+ after(data_seq + data_len - (mptcp_is_data_fin2(skb, tp) ? 1 : 0), -+ meta_tp->rcv_nxt))) { -+ mptcp_send_active_reset(meta_sk, GFP_ATOMIC); -+ tcp_done(meta_sk); -+ __NET_INC_STATS(sock_net(meta_sk), LINUX_MIB_TCPABORTONDATA); -+ return 1; -+ } -+ -+ tmo = tcp_fin_time(meta_sk); -+ if (tmo > TCP_TIMEWAIT_LEN) { -+ inet_csk_reset_keepalive_timer(meta_sk, tmo - TCP_TIMEWAIT_LEN); -+ } else if (mptcp_is_data_fin2(skb, tp) || sock_owned_by_user(meta_sk)) { -+ /* Bad case. We could lose such FIN otherwise. -+ * It is not a big problem, but it looks confusing -+ * and not so rare event. We still can lose it now, -+ * if it spins in bh_lock_sock(), but it is really -+ * marginal case. -+ */ -+ inet_csk_reset_keepalive_timer(meta_sk, tmo); -+ } else { -+ meta_tp->ops->time_wait(meta_sk, TCP_FIN_WAIT2, tmo); -+ } -+ break; -+ } -+ case TCP_CLOSING: -+ case TCP_LAST_ACK: -+ if (meta_tp->snd_una == meta_tp->write_seq) { -+ tcp_done(meta_sk); -+ return 1; -+ } -+ break; -+ } -+ -+ /* step 7: process the segment text */ -+ switch (meta_sk->sk_state) { -+ case TCP_FIN_WAIT1: -+ case TCP_FIN_WAIT2: -+ /* RFC 793 says to queue data in these states, -+ * RFC 1122 says we MUST send a reset. -+ * BSD 4.4 also does reset. -+ */ -+ if (meta_sk->sk_shutdown & RCV_SHUTDOWN) { -+ if (TCP_SKB_CB(skb)->end_seq != TCP_SKB_CB(skb)->seq && -+ after(TCP_SKB_CB(skb)->end_seq - th->fin, tp->rcv_nxt) && -+ !mptcp_is_data_fin2(skb, tp)) { -+ __NET_INC_STATS(sock_net(meta_sk), LINUX_MIB_TCPABORTONDATA); -+ mptcp_send_active_reset(meta_sk, GFP_ATOMIC); -+ tcp_reset(meta_sk); -+ return 1; -+ } -+ } -+ break; -+ } -+ -+ return 0; -+} -+ -+/** -+ * @return: -+ * i) 1: Everything's fine. -+ * ii) -1: A reset has been sent on the subflow - csum-failure -+ * iii) 0: csum-failure but no reset sent, because it's the last subflow. -+ * Last packet should not be destroyed by the caller because it has -+ * been done here. -+ */ -+static int mptcp_verif_dss_csum(struct sock *sk) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct sk_buff *tmp, *tmp1, *last = NULL; -+ __wsum csum_tcp = 0; /* cumulative checksum of pld + mptcp-header */ -+ int ans = 1, overflowed = 0, offset = 0, dss_csum_added = 0; -+ int iter = 0; -+ u32 next_seq, offset_seq; -+ -+ skb_queue_walk_safe(&sk->sk_receive_queue, tmp, tmp1) { -+ unsigned int csum_len; -+ -+ /* init next seq in first round */ -+ if (!iter) -+ next_seq = TCP_SKB_CB(tmp)->seq; -+ offset_seq = next_seq - TCP_SKB_CB(tmp)->seq; -+ -+ if (before(tp->mptcp->map_subseq + tp->mptcp->map_data_len, TCP_SKB_CB(tmp)->end_seq)) -+ /* Mapping ends in the middle of the packet - -+ * csum only these bytes -+ */ -+ csum_len = tp->mptcp->map_subseq + tp->mptcp->map_data_len - TCP_SKB_CB(tmp)->seq; -+ else -+ csum_len = tmp->len; -+ -+ csum_len -= offset_seq; -+ offset = 0; -+ if (overflowed) { -+ char first_word[4]; -+ first_word[0] = 0; -+ first_word[1] = 0; -+ first_word[2] = 0; -+ first_word[3] = *(tmp->data + offset_seq); -+ csum_tcp = csum_partial(first_word, 4, csum_tcp); -+ offset = 1; -+ csum_len--; -+ overflowed = 0; -+ } -+ -+ csum_tcp = skb_checksum(tmp, offset + offset_seq, csum_len, -+ csum_tcp); -+ -+ /* Was it on an odd-length? Then we have to merge the next byte -+ * correctly (see above) -+ */ -+ if (csum_len != (csum_len & (~1))) -+ overflowed = 1; -+ -+ if (mptcp_is_data_seq(tmp) && !dss_csum_added) { -+ __be32 data_seq = htonl((u32)(tp->mptcp->map_data_seq >> 32)); -+ -+ /* If a 64-bit dss is present, we increase the offset -+ * by 4 bytes, as the high-order 64-bits will be added -+ * in the final csum_partial-call. -+ */ -+ u32 offset = skb_transport_offset(tmp) + -+ TCP_SKB_CB(tmp)->dss_off; -+ if (TCP_SKB_CB(tmp)->mptcp_flags & MPTCPHDR_SEQ64_SET) -+ offset += 4; -+ -+ csum_tcp = skb_checksum(tmp, offset, -+ MPTCP_SUB_LEN_SEQ_CSUM, -+ csum_tcp); -+ -+ csum_tcp = csum_partial(&data_seq, -+ sizeof(data_seq), csum_tcp); -+ -+ dss_csum_added = 1; /* Just do it once */ -+ } -+ last = tmp; -+ iter++; -+ -+ if (!skb_queue_is_last(&sk->sk_receive_queue, tmp) && -+ !before(TCP_SKB_CB(tmp1)->seq, -+ tp->mptcp->map_subseq + tp->mptcp->map_data_len)) -+ break; -+ next_seq = TCP_SKB_CB(tmp)->end_seq; -+ } -+ -+ /* Now, checksum must be 0 */ -+ if (unlikely(csum_fold(csum_tcp))) { -+ struct mptcp_tcp_sock *mptcp; -+ struct sock *sk_it = NULL; -+ -+ pr_debug("%s csum is wrong: %#x tcp-seq %u dss_csum_added %d overflowed %d iterations %d\n", -+ __func__, csum_fold(csum_tcp), TCP_SKB_CB(last)->seq, -+ dss_csum_added, overflowed, iter); -+ -+ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_CSUMFAIL); -+ tp->mptcp->send_mp_fail = 1; -+ -+ /* map_data_seq is the data-seq number of the -+ * mapping we are currently checking -+ */ -+ tp->mpcb->csum_cutoff_seq = tp->mptcp->map_data_seq; -+ -+ /* Search for another subflow that is fully established */ -+ mptcp_for_each_sub(tp->mpcb, mptcp) { -+ sk_it = mptcp_to_sock(mptcp); -+ -+ if (sk_it != sk && -+ tcp_sk(sk_it)->mptcp->fully_established) -+ break; -+ -+ sk_it = NULL; -+ } -+ -+ if (sk_it) { -+ mptcp_send_reset(sk); -+ ans = -1; -+ } else { -+ tp->mpcb->send_infinite_mapping = 1; -+ -+ /* Need to purge the rcv-queue as it's no more valid */ -+ while ((tmp = __skb_dequeue(&sk->sk_receive_queue)) != NULL) { -+ tp->copied_seq = TCP_SKB_CB(tmp)->end_seq; -+ kfree_skb(tmp); -+ } -+ -+ mptcp_fallback_close(tp->mpcb, sk); -+ -+ ans = 0; -+ } -+ } -+ -+ return ans; -+} -+ -+static inline void mptcp_prepare_skb(struct sk_buff *skb, -+ const struct sock *sk) -+{ -+ const struct tcp_sock *tp = tcp_sk(sk); -+ struct tcp_skb_cb *tcb = TCP_SKB_CB(skb); -+ u32 inc = 0, end_seq = tcb->end_seq; -+ -+ if (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN) -+ end_seq--; -+ /* If skb is the end of this mapping (end is always at mapping-boundary -+ * thanks to the splitting/trimming), then we need to increase -+ * data-end-seq by 1 if this here is a data-fin. -+ * -+ * We need to do -1 because end_seq includes the subflow-FIN. -+ */ -+ if (tp->mptcp->map_data_fin && -+ end_seq == tp->mptcp->map_subseq + tp->mptcp->map_data_len) { -+ inc = 1; -+ -+ /* We manually set the fin-flag if it is a data-fin. For easy -+ * processing in tcp_recvmsg. -+ */ -+ TCP_SKB_CB(skb)->tcp_flags |= TCPHDR_FIN; -+ } else { -+ /* We may have a subflow-fin with data but without data-fin */ -+ TCP_SKB_CB(skb)->tcp_flags &= ~TCPHDR_FIN; -+ } -+ -+ /* Adapt data-seq's to the packet itself. We kinda transform the -+ * dss-mapping to a per-packet granularity. This is necessary to -+ * correctly handle overlapping mappings coming from different -+ * subflows. Otherwise it would be a complete mess. -+ */ -+ tcb->seq = ((u32)tp->mptcp->map_data_seq) + tcb->seq - tp->mptcp->map_subseq; -+ tcb->end_seq = tcb->seq + skb->len + inc; -+} -+ -+static inline void mptcp_reset_mapping(struct tcp_sock *tp, u32 old_copied_seq) -+{ -+ tp->mptcp->map_data_len = 0; -+ tp->mptcp->map_data_seq = 0; -+ tp->mptcp->map_subseq = 0; -+ tp->mptcp->map_data_fin = 0; -+ tp->mptcp->mapping_present = 0; -+ -+ /* In infinite mapping receiver mode, we have to advance the implied -+ * data-sequence number when we progress the subflow's data. -+ */ -+ if (tp->mpcb->infinite_mapping_rcv) -+ tp->mpcb->infinite_rcv_seq += (tp->copied_seq - old_copied_seq); -+} -+ -+/* The DSS-mapping received on the sk only covers the second half of the skb -+ * (cut at seq). We trim the head from the skb. -+ * Data will be freed upon kfree(). -+ * -+ * Inspired by tcp_trim_head(). -+ */ -+static void mptcp_skb_trim_head(struct sk_buff *skb, struct sock *sk, u32 seq) -+{ -+ int len = seq - TCP_SKB_CB(skb)->seq; -+ u32 new_seq = TCP_SKB_CB(skb)->seq + len; -+ u32 delta_truesize; -+ -+ delta_truesize = __pskb_trim_head(skb, len); -+ -+ TCP_SKB_CB(skb)->seq = new_seq; -+ -+ if (delta_truesize) { -+ skb->truesize -= delta_truesize; -+ atomic_sub(delta_truesize, &sk->sk_rmem_alloc); -+ sk_mem_uncharge(sk, delta_truesize); -+ } -+} -+ -+/* The DSS-mapping received on the sk only covers the first half of the skb -+ * (cut at seq). We create a second skb (@return), and queue it in the rcv-queue -+ * as further packets may resolve the mapping of the second half of data. -+ * -+ * Inspired by tcp_fragment(). -+ */ -+static int mptcp_skb_split_tail(struct sk_buff *skb, struct sock *sk, u32 seq) -+{ -+ struct sk_buff *buff; -+ int nsize; -+ int nlen, len; -+ u8 flags; -+ -+ len = seq - TCP_SKB_CB(skb)->seq; -+ nsize = skb_headlen(skb) - len + tcp_sk(sk)->tcp_header_len; -+ if (nsize < 0) -+ nsize = 0; -+ -+ /* Get a new skb... force flag on. */ -+ buff = alloc_skb(nsize, GFP_ATOMIC); -+ if (buff == NULL) -+ return -ENOMEM; -+ -+ skb_reserve(buff, tcp_sk(sk)->tcp_header_len); -+ skb_reset_transport_header(buff); -+ -+ flags = TCP_SKB_CB(skb)->tcp_flags; -+ TCP_SKB_CB(skb)->tcp_flags = flags & ~(TCPHDR_FIN); -+ TCP_SKB_CB(buff)->tcp_flags = flags; -+ -+ /* We absolutly need to call skb_set_owner_r before refreshing the -+ * truesize of buff, otherwise the moved data will account twice. -+ */ -+ skb_set_owner_r(buff, sk); -+ nlen = skb->len - len - nsize; -+ buff->truesize += nlen; -+ skb->truesize -= nlen; -+ -+ /* Correct the sequence numbers. */ -+ TCP_SKB_CB(buff)->seq = TCP_SKB_CB(skb)->seq + len; -+ TCP_SKB_CB(buff)->end_seq = TCP_SKB_CB(skb)->end_seq; -+ TCP_SKB_CB(skb)->end_seq = TCP_SKB_CB(buff)->seq; -+ -+ skb_split(skb, buff, len); -+ -+ __skb_queue_after(&sk->sk_receive_queue, skb, buff); -+ -+ return 0; -+} -+ -+/* @return: 0 everything is fine. Just continue processing -+ * 1 subflow is broken stop everything -+ * -1 this packet was broken - continue with the next one. -+ */ -+static int mptcp_prevalidate_skb(struct sock *sk, struct sk_buff *skb) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct mptcp_cb *mpcb = tp->mpcb; -+ -+ /* If we are in infinite mode, the subflow-fin is in fact a data-fin. */ -+ if (!skb->len && (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN) && -+ !mptcp_is_data_fin(skb) && !mpcb->infinite_mapping_rcv) { -+ /* Remove a pure subflow-fin from the queue and increase -+ * copied_seq. -+ */ -+ tp->copied_seq = TCP_SKB_CB(skb)->end_seq; -+ __skb_unlink(skb, &sk->sk_receive_queue); -+ __kfree_skb(skb); -+ return -1; -+ } -+ -+ /* If we are not yet fully established and do not know the mapping for -+ * this segment, this path has to fallback to infinite or be torn down. -+ */ -+ if (!tp->mptcp->fully_established && !mptcp_is_data_seq(skb) && -+ !tp->mptcp->mapping_present && !mpcb->infinite_mapping_rcv) { -+ pr_debug("%s %#x will fallback - pi %d from %pS, seq %u\n", -+ __func__, mpcb->mptcp_loc_token, -+ tp->mptcp->path_index, __builtin_return_address(0), -+ TCP_SKB_CB(skb)->seq); -+ -+ if (!is_master_tp(tp)) { -+ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_FBDATASUB); -+ mptcp_send_reset(sk); -+ return 1; -+ } -+ -+ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_FBDATAINIT); -+ -+ mpcb->infinite_mapping_snd = 1; -+ mpcb->infinite_mapping_rcv = 1; -+ mpcb->infinite_rcv_seq = mptcp_get_rcv_nxt_64(mptcp_meta_tp(tp)); -+ -+ mptcp_fallback_close(mpcb, sk); -+ -+ /* We do a seamless fallback and should not send a inf.mapping. */ -+ mpcb->send_infinite_mapping = 0; -+ tp->mptcp->fully_established = 1; -+ } -+ -+ /* Receiver-side becomes fully established when a whole rcv-window has -+ * been received without the need to fallback due to the previous -+ * condition. -+ */ -+ if (!tp->mptcp->fully_established) { -+ tp->mptcp->init_rcv_wnd -= skb->len; -+ if (tp->mptcp->init_rcv_wnd < 0) -+ mptcp_become_fully_estab(sk); -+ } -+ -+ return 0; -+} -+ -+static void mptcp_restart_sending(struct sock *meta_sk) -+{ -+ struct tcp_sock *meta_tp = tcp_sk(meta_sk); -+ struct mptcp_cb *mpcb = meta_tp->mpcb; -+ struct sk_buff *wq_head, *skb, *tmp; -+ -+ skb = tcp_rtx_queue_head(meta_sk); -+ -+ /* We resend everything that has not been acknowledged, thus we need -+ * to move it from the rtx-tree to the write-queue. -+ */ -+ wq_head = tcp_write_queue_head(meta_sk); -+ -+ skb_rbtree_walk_from_safe(skb, tmp) { -+ list_del(&skb->tcp_tsorted_anchor); -+ tcp_rtx_queue_unlink(skb, meta_sk); -+ INIT_LIST_HEAD(&skb->tcp_tsorted_anchor); -+ -+ if (wq_head) -+ __skb_queue_before(&meta_sk->sk_write_queue, wq_head, skb); -+ else -+ tcp_add_write_queue_tail(meta_sk, skb); -+ } -+ -+ /* We artificially restart the whole send-queue. Thus, -+ * it is as if no packets are in flight -+ */ -+ meta_tp->packets_out = 0; -+ -+ /* If the snd_nxt already wrapped around, we have to -+ * undo the wrapping, as we are restarting from snd_una -+ * on. -+ */ -+ if (meta_tp->snd_nxt < meta_tp->snd_una) { -+ mpcb->snd_high_order[mpcb->snd_hiseq_index] -= 2; -+ mpcb->snd_hiseq_index = mpcb->snd_hiseq_index ? 0 : 1; -+ } -+ meta_tp->snd_nxt = meta_tp->snd_una; -+ -+ /* Trigger a sending on the meta. */ -+ mptcp_push_pending_frames(meta_sk); -+} -+ -+/* @return: 0 everything is fine. Just continue processing -+ * 1 subflow is broken stop everything -+ * -1 this packet was broken - continue with the next one. -+ */ -+static int mptcp_detect_mapping(struct sock *sk, struct sk_buff *skb) -+{ -+ struct tcp_sock *tp = tcp_sk(sk), *meta_tp = mptcp_meta_tp(tp); -+ struct mptcp_cb *mpcb = tp->mpcb; -+ struct tcp_skb_cb *tcb = TCP_SKB_CB(skb); -+ u32 *ptr; -+ u32 data_seq, sub_seq, data_len, tcp_end_seq; -+ bool set_infinite_rcv = false; -+ -+ /* If we are in infinite-mapping-mode, the subflow is guaranteed to be -+ * in-order at the data-level. Thus data-seq-numbers can be inferred -+ * from what is expected at the data-level. -+ */ -+ if (mpcb->infinite_mapping_rcv) { -+ /* copied_seq may be bigger than tcb->seq (e.g., when the peer -+ * retransmits data that actually has already been acknowledged with -+ * newer data, if he did not receive our acks). Thus, we need -+ * to account for this overlap as well. -+ */ -+ tp->mptcp->map_data_seq = mpcb->infinite_rcv_seq - (tp->copied_seq - tcb->seq); -+ tp->mptcp->map_subseq = tcb->seq; -+ tp->mptcp->map_data_len = skb->len; -+ tp->mptcp->map_data_fin = !!(TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN); -+ tp->mptcp->mapping_present = 1; -+ return 0; -+ } -+ -+ /* No mapping here? Exit - it is either already set or still on its way */ -+ if (!mptcp_is_data_seq(skb)) { -+ /* Too many packets without a mapping - this subflow is broken */ -+ if (!tp->mptcp->mapping_present && -+ tp->rcv_nxt - tp->copied_seq > 65536) { -+ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_NODSSWINDOW); -+ mptcp_send_reset(sk); -+ return 1; -+ } -+ -+ return 0; -+ } -+ -+ ptr = mptcp_skb_set_data_seq(skb, &data_seq, mpcb); -+ ptr++; -+ sub_seq = get_unaligned_be32(ptr) + tp->mptcp->rcv_isn; -+ ptr++; -+ data_len = get_unaligned_be16(ptr); -+ -+ /* If it's an empty skb with DATA_FIN, sub_seq must get fixed. -+ * The draft sets it to 0, but we really would like to have the -+ * real value, to have an easy handling afterwards here in this -+ * function. -+ */ -+ if (mptcp_is_data_fin(skb) && skb->len == 0) -+ sub_seq = TCP_SKB_CB(skb)->seq; -+ -+ /* If there is already a mapping - we check if it maps with the current -+ * one. If not - we reset. -+ */ -+ if (tp->mptcp->mapping_present && -+ (data_seq != (u32)tp->mptcp->map_data_seq || -+ sub_seq != tp->mptcp->map_subseq || -+ data_len != tp->mptcp->map_data_len + tp->mptcp->map_data_fin || -+ mptcp_is_data_fin(skb) != tp->mptcp->map_data_fin)) { -+ /* Mapping in packet is different from what we want */ -+ pr_debug("%s Mappings do not match!\n", __func__); -+ pr_debug("%s dseq %u mdseq %u, sseq %u msseq %u dlen %u mdlen %u dfin %d mdfin %d\n", -+ __func__, data_seq, (u32)tp->mptcp->map_data_seq, -+ sub_seq, tp->mptcp->map_subseq, data_len, -+ tp->mptcp->map_data_len, mptcp_is_data_fin(skb), -+ tp->mptcp->map_data_fin); -+ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_DSSNOMATCH); -+ mptcp_send_reset(sk); -+ return 1; -+ } -+ -+ /* If the previous check was good, the current mapping is valid and we exit. */ -+ if (tp->mptcp->mapping_present) -+ return 0; -+ -+ /* Mapping not yet set on this subflow - we set it here! */ -+ -+ if (!data_len) { -+ mpcb->infinite_mapping_rcv = 1; -+ mpcb->send_infinite_mapping = 1; -+ tp->mptcp->fully_established = 1; -+ /* We need to repeat mp_fail's until the sender felt -+ * back to infinite-mapping - here we stop repeating it. -+ */ -+ tp->mptcp->send_mp_fail = 0; -+ -+ /* We have to fixup data_len - it must be the same as skb->len */ -+ data_len = skb->len + (mptcp_is_data_fin(skb) ? 1 : 0); -+ sub_seq = tcb->seq; -+ -+ mptcp_restart_sending(tp->meta_sk); -+ -+ mptcp_fallback_close(mpcb, sk); -+ -+ /* data_seq and so on are set correctly */ -+ -+ /* At this point, the meta-ofo-queue has to be emptied, -+ * as the following data is guaranteed to be in-order at -+ * the data and subflow-level -+ */ -+ skb_rbtree_purge(&meta_tp->out_of_order_queue); -+ -+ set_infinite_rcv = true; -+ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_INFINITEMAPRX); -+ } -+ -+ /* We are sending mp-fail's and thus are in fallback mode. -+ * Ignore packets which do not announce the fallback and still -+ * want to provide a mapping. -+ */ -+ if (tp->mptcp->send_mp_fail) { -+ tp->copied_seq = TCP_SKB_CB(skb)->end_seq; -+ __skb_unlink(skb, &sk->sk_receive_queue); -+ __kfree_skb(skb); -+ return -1; -+ } -+ -+ /* FIN increased the mapping-length by 1 */ -+ if (mptcp_is_data_fin(skb)) -+ data_len--; -+ -+ /* Subflow-sequences of packet must be -+ * (at least partially) be part of the DSS-mapping's -+ * subflow-sequence-space. -+ * -+ * Basically the mapping is not valid, if either of the -+ * following conditions is true: -+ * -+ * 1. It's not a data_fin and -+ * MPTCP-sub_seq >= TCP-end_seq -+ * -+ * 2. It's a data_fin and TCP-end_seq > TCP-seq and -+ * MPTCP-sub_seq >= TCP-end_seq -+ * -+ * The previous two can be merged into: -+ * TCP-end_seq > TCP-seq and MPTCP-sub_seq >= TCP-end_seq -+ * Because if it's not a data-fin, TCP-end_seq > TCP-seq -+ * -+ * 3. It's a data_fin and skb->len == 0 and -+ * MPTCP-sub_seq > TCP-end_seq -+ * -+ * 4. It's not a data_fin and TCP-end_seq > TCP-seq and -+ * MPTCP-sub_seq + MPTCP-data_len <= TCP-seq -+ */ -+ -+ /* subflow-fin is not part of the mapping - ignore it here ! */ -+ tcp_end_seq = tcb->end_seq; -+ if (tcb->tcp_flags & TCPHDR_FIN) -+ tcp_end_seq--; -+ if ((!before(sub_seq, tcb->end_seq) && after(tcp_end_seq, tcb->seq)) || -+ (mptcp_is_data_fin(skb) && skb->len == 0 && after(sub_seq, tcb->end_seq)) || -+ (!after(sub_seq + data_len, tcb->seq) && after(tcp_end_seq, tcb->seq))) { -+ /* Subflow-sequences of packet is different from what is in the -+ * packet's dss-mapping. The peer is misbehaving - reset -+ */ -+ pr_debug("%s Packet's mapping does not map to the DSS sub_seq %u end_seq %u, tcp_end_seq %u seq %u dfin %u len %u data_len %u copied_seq %u\n", -+ __func__, sub_seq, tcb->end_seq, tcp_end_seq, -+ tcb->seq, mptcp_is_data_fin(skb), -+ skb->len, data_len, tp->copied_seq); -+ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_DSSTCPMISMATCH); -+ mptcp_send_reset(sk); -+ return 1; -+ } -+ -+ /* Does the DSS had 64-bit seqnum's ? */ -+ if (!(tcb->mptcp_flags & MPTCPHDR_SEQ64_SET)) { -+ /* Wrapped around? */ -+ if (unlikely(after(data_seq, meta_tp->rcv_nxt) && data_seq < meta_tp->rcv_nxt)) { -+ tp->mptcp->map_data_seq = mptcp_get_data_seq_64(mpcb, !mpcb->rcv_hiseq_index, data_seq); -+ } else { -+ /* Else, access the default high-order bits */ -+ tp->mptcp->map_data_seq = mptcp_get_data_seq_64(mpcb, mpcb->rcv_hiseq_index, data_seq); -+ } -+ } else { -+ tp->mptcp->map_data_seq = mptcp_get_data_seq_64(mpcb, (tcb->mptcp_flags & MPTCPHDR_SEQ64_INDEX) ? 1 : 0, data_seq); -+ -+ if (unlikely(tcb->mptcp_flags & MPTCPHDR_SEQ64_OFO)) { -+ /* We make sure that the data_seq is invalid. -+ * It will be dropped later. -+ */ -+ tp->mptcp->map_data_seq += 0xFFFFFFFF; -+ tp->mptcp->map_data_seq += 0xFFFFFFFF; -+ } -+ } -+ -+ if (set_infinite_rcv) -+ mpcb->infinite_rcv_seq = tp->mptcp->map_data_seq; -+ -+ tp->mptcp->map_data_len = data_len; -+ tp->mptcp->map_subseq = sub_seq; -+ tp->mptcp->map_data_fin = mptcp_is_data_fin(skb) ? 1 : 0; -+ tp->mptcp->mapping_present = 1; -+ -+ return 0; -+} -+ -+/* Similar to tcp_sequence(...) */ -+static inline bool mptcp_sequence(const struct tcp_sock *meta_tp, -+ u64 data_seq, u64 end_data_seq) -+{ -+ const struct mptcp_cb *mpcb = meta_tp->mpcb; -+ u64 rcv_wup64; -+ -+ /* Wrap-around? */ -+ if (meta_tp->rcv_wup > meta_tp->rcv_nxt) { -+ rcv_wup64 = ((u64)(mpcb->rcv_high_order[mpcb->rcv_hiseq_index] - 1) << 32) | -+ meta_tp->rcv_wup; -+ } else { -+ rcv_wup64 = mptcp_get_data_seq_64(mpcb, mpcb->rcv_hiseq_index, -+ meta_tp->rcv_wup); -+ } -+ -+ return !before64(end_data_seq, rcv_wup64) && -+ !after64(data_seq, mptcp_get_rcv_nxt_64(meta_tp) + tcp_receive_window(meta_tp)); -+} -+ -+/* @return: 0 everything is fine. Just continue processing -+ * -1 this packet was broken - continue with the next one. -+ */ -+static int mptcp_validate_mapping(struct sock *sk, struct sk_buff *skb) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct sk_buff *tmp, *tmp1; -+ u32 tcp_end_seq; -+ -+ if (!tp->mptcp->mapping_present) -+ return 0; -+ -+ /* either, the new skb gave us the mapping and the first segment -+ * in the sub-rcv-queue has to be trimmed ... -+ */ -+ tmp = skb_peek(&sk->sk_receive_queue); -+ if (before(TCP_SKB_CB(tmp)->seq, tp->mptcp->map_subseq) && -+ after(TCP_SKB_CB(tmp)->end_seq, tp->mptcp->map_subseq)) { -+ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_DSSTRIMHEAD); -+ mptcp_skb_trim_head(tmp, sk, tp->mptcp->map_subseq); -+ } -+ -+ /* ... or the new skb (tail) has to be split at the end. */ -+ tcp_end_seq = TCP_SKB_CB(skb)->end_seq; -+ if (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN) -+ tcp_end_seq--; -+ if (after(tcp_end_seq, tp->mptcp->map_subseq + tp->mptcp->map_data_len)) { -+ u32 seq = tp->mptcp->map_subseq + tp->mptcp->map_data_len; -+ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_DSSSPLITTAIL); -+ if (mptcp_skb_split_tail(skb, sk, seq)) { /* Allocation failed */ -+ /* TODO : maybe handle this here better. -+ * We now just force meta-retransmission. -+ */ -+ tp->copied_seq = TCP_SKB_CB(skb)->end_seq; -+ __skb_unlink(skb, &sk->sk_receive_queue); -+ __kfree_skb(skb); -+ return -1; -+ } -+ } -+ -+ /* Now, remove old sk_buff's from the receive-queue. -+ * This may happen if the mapping has been lost for these segments and -+ * the next mapping has already been received. -+ */ -+ if (before(TCP_SKB_CB(skb_peek(&sk->sk_receive_queue))->seq, tp->mptcp->map_subseq)) { -+ skb_queue_walk_safe(&sk->sk_receive_queue, tmp1, tmp) { -+ if (!before(TCP_SKB_CB(tmp1)->seq, tp->mptcp->map_subseq)) -+ break; -+ -+ tp->copied_seq = TCP_SKB_CB(tmp1)->end_seq; -+ __skb_unlink(tmp1, &sk->sk_receive_queue); -+ -+ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_PURGEOLD); -+ /* Impossible that we could free skb here, because his -+ * mapping is known to be valid from previous checks -+ */ -+ __kfree_skb(tmp1); -+ } -+ } -+ -+ return 0; -+} -+ -+/* @return: 0 everything is fine. Just continue processing -+ * 1 subflow is broken stop everything -+ * -1 this mapping has been put in the meta-receive-queue -+ * -2 this mapping has been eaten by the application -+ */ -+static int mptcp_queue_skb(struct sock *sk) -+{ -+ struct tcp_sock *tp = tcp_sk(sk), *meta_tp = mptcp_meta_tp(tp); -+ struct sock *meta_sk = mptcp_meta_sk(sk); -+ struct mptcp_cb *mpcb = tp->mpcb; -+ struct sk_buff *tmp, *tmp1; -+ u64 rcv_nxt64 = mptcp_get_rcv_nxt_64(meta_tp); -+ u32 old_copied_seq = tp->copied_seq; -+ bool data_queued = false; -+ -+ /* Have we not yet received the full mapping? */ -+ if (!tp->mptcp->mapping_present || -+ before(tp->rcv_nxt, tp->mptcp->map_subseq + tp->mptcp->map_data_len)) -+ return 0; -+ -+ /* Is this an overlapping mapping? rcv_nxt >= end_data_seq -+ * OR -+ * This mapping is out of window -+ */ -+ if (!before64(rcv_nxt64, tp->mptcp->map_data_seq + tp->mptcp->map_data_len + tp->mptcp->map_data_fin) || -+ !mptcp_sequence(meta_tp, tp->mptcp->map_data_seq, -+ tp->mptcp->map_data_seq + tp->mptcp->map_data_len + tp->mptcp->map_data_fin)) { -+ skb_queue_walk_safe(&sk->sk_receive_queue, tmp1, tmp) { -+ __skb_unlink(tmp1, &sk->sk_receive_queue); -+ tp->copied_seq = TCP_SKB_CB(tmp1)->end_seq; -+ __kfree_skb(tmp1); -+ -+ if (!skb_queue_empty(&sk->sk_receive_queue) && -+ !before(TCP_SKB_CB(tmp)->seq, -+ tp->mptcp->map_subseq + tp->mptcp->map_data_len)) -+ break; -+ } -+ -+ mptcp_reset_mapping(tp, old_copied_seq); -+ -+ return -1; -+ } -+ -+ /* Record it, because we want to send our data_fin on the same path */ -+ if (tp->mptcp->map_data_fin) { -+ mpcb->dfin_path_index = tp->mptcp->path_index; -+ mpcb->dfin_combined = !!(sk->sk_shutdown & RCV_SHUTDOWN); -+ } -+ -+ /* Verify the checksum */ -+ if (mpcb->dss_csum && !mpcb->infinite_mapping_rcv) { -+ int ret = mptcp_verif_dss_csum(sk); -+ -+ if (ret <= 0) { -+ mptcp_reset_mapping(tp, old_copied_seq); -+ return 1; -+ } -+ } -+ -+ if (before64(rcv_nxt64, tp->mptcp->map_data_seq)) { -+ /* Seg's have to go to the meta-ofo-queue */ -+ skb_queue_walk_safe(&sk->sk_receive_queue, tmp1, tmp) { -+ tp->copied_seq = TCP_SKB_CB(tmp1)->end_seq; -+ mptcp_prepare_skb(tmp1, sk); -+ __skb_unlink(tmp1, &sk->sk_receive_queue); -+ /* MUST be done here, because fragstolen may be true later. -+ * Then, kfree_skb_partial will not account the memory. -+ */ -+ skb_orphan(tmp1); -+ -+ if (!mpcb->in_time_wait) /* In time-wait, do not receive data */ -+ tcp_data_queue_ofo(meta_sk, tmp1); -+ else -+ __kfree_skb(tmp1); -+ -+ if (!skb_queue_empty(&sk->sk_receive_queue) && -+ !before(TCP_SKB_CB(tmp)->seq, -+ tp->mptcp->map_subseq + tp->mptcp->map_data_len)) -+ break; -+ } -+ -+ /* Quick ACK if more 3/4 of the receive window is filled */ -+ if (after64(tp->mptcp->map_data_seq, -+ rcv_nxt64 + 3 * (tcp_receive_window(meta_tp) >> 2))) -+ tcp_enter_quickack_mode(sk, TCP_MAX_QUICKACKS); -+ -+ } else { -+ /* Ready for the meta-rcv-queue */ -+ skb_queue_walk_safe(&sk->sk_receive_queue, tmp1, tmp) { -+ int eaten = 0; -+ bool fragstolen = false; -+ u32 old_rcv_nxt = meta_tp->rcv_nxt; -+ -+ tp->copied_seq = TCP_SKB_CB(tmp1)->end_seq; -+ mptcp_prepare_skb(tmp1, sk); -+ __skb_unlink(tmp1, &sk->sk_receive_queue); -+ /* MUST be done here, because fragstolen may be true. -+ * Then, kfree_skb_partial will not account the memory. -+ */ -+ skb_orphan(tmp1); -+ -+ /* This segment has already been received */ -+ if (!after(TCP_SKB_CB(tmp1)->end_seq, meta_tp->rcv_nxt)) { -+ __kfree_skb(tmp1); -+ goto next; -+ } -+ -+ if (mpcb->in_time_wait) /* In time-wait, do not receive data */ -+ eaten = 1; -+ -+ if (!eaten) -+ eaten = tcp_queue_rcv(meta_sk, tmp1, 0, &fragstolen); -+ -+ meta_tp->rcv_nxt = TCP_SKB_CB(tmp1)->end_seq; -+ -+ if (TCP_SKB_CB(tmp1)->tcp_flags & TCPHDR_FIN) -+ mptcp_fin(meta_sk); -+ -+ /* Check if this fills a gap in the ofo queue */ -+ if (!RB_EMPTY_ROOT(&meta_tp->out_of_order_queue)) -+ tcp_ofo_queue(meta_sk); -+ -+ mptcp_check_rcvseq_wrap(meta_tp, old_rcv_nxt); -+ -+ if (eaten) -+ kfree_skb_partial(tmp1, fragstolen); -+ -+ data_queued = true; -+next: -+ if (!skb_queue_empty(&sk->sk_receive_queue) && -+ !before(TCP_SKB_CB(tmp)->seq, -+ tp->mptcp->map_subseq + tp->mptcp->map_data_len)) -+ break; -+ } -+ } -+ -+ inet_csk(meta_sk)->icsk_ack.lrcvtime = tcp_jiffies32; -+ mptcp_reset_mapping(tp, old_copied_seq); -+ -+ return data_queued ? -1 : -2; -+} -+ -+void mptcp_data_ready(struct sock *sk) -+{ -+ struct sock *meta_sk = mptcp_meta_sk(sk); -+ struct sk_buff *skb, *tmp; -+ int queued = 0; -+ -+ tcp_mstamp_refresh(tcp_sk(meta_sk)); -+ -+ /* restart before the check, because mptcp_fin might have changed the -+ * state. -+ */ -+restart: -+ /* If the meta cannot receive data, there is no point in pushing data. -+ * If we are in time-wait, we may still be waiting for the final FIN. -+ * So, we should proceed with the processing. -+ */ -+ if (!mptcp_sk_can_recv(meta_sk) && !tcp_sk(sk)->mpcb->in_time_wait) { -+ skb_queue_purge(&sk->sk_receive_queue); -+ tcp_sk(sk)->copied_seq = tcp_sk(sk)->rcv_nxt; -+ goto exit; -+ } -+ -+ /* Iterate over all segments, detect their mapping (if we don't have -+ * one yet), validate them and push everything one level higher. -+ */ -+ skb_queue_walk_safe(&sk->sk_receive_queue, skb, tmp) { -+ int ret; -+ /* Pre-validation - e.g., early fallback */ -+ ret = mptcp_prevalidate_skb(sk, skb); -+ if (ret < 0) -+ goto restart; -+ else if (ret > 0) -+ break; -+ -+ /* Set the current mapping */ -+ ret = mptcp_detect_mapping(sk, skb); -+ if (ret < 0) -+ goto restart; -+ else if (ret > 0) -+ break; -+ -+ /* Validation */ -+ if (mptcp_validate_mapping(sk, skb) < 0) -+ goto restart; -+ -+ /* Push a level higher */ -+ ret = mptcp_queue_skb(sk); -+ if (ret < 0) { -+ if (ret == -1) -+ queued = ret; -+ goto restart; -+ } else if (ret == 0) { -+ continue; -+ } else { /* ret == 1 */ -+ break; -+ } -+ } -+ -+exit: -+ if (tcp_sk(sk)->close_it && sk->sk_state == TCP_FIN_WAIT2) { -+ tcp_send_ack(sk); -+ tcp_sk(sk)->ops->time_wait(sk, TCP_TIME_WAIT, 0); -+ } -+ -+ if (queued == -1 && !sock_flag(meta_sk, SOCK_DEAD)) -+ meta_sk->sk_data_ready(meta_sk); -+} -+ -+struct mp_join *mptcp_find_join(const struct sk_buff *skb) -+{ -+ const struct tcphdr *th = tcp_hdr(skb); -+ unsigned char *ptr; -+ int length = (th->doff * 4) - sizeof(struct tcphdr); -+ -+ /* Jump through the options to check whether JOIN is there */ -+ ptr = (unsigned char *)(th + 1); -+ while (length > 0) { -+ int opcode = *ptr++; -+ int opsize; -+ -+ switch (opcode) { -+ case TCPOPT_EOL: -+ return NULL; -+ case TCPOPT_NOP: /* Ref: RFC 793 section 3.1 */ -+ length--; -+ continue; -+ default: -+ opsize = *ptr++; -+ if (opsize < 2) /* "silly options" */ -+ return NULL; -+ if (opsize > length) -+ return NULL; /* don't parse partial options */ -+ if (opcode == TCPOPT_MPTCP && -+ ((struct mptcp_option *)(ptr - 2))->sub == MPTCP_SUB_JOIN) { -+ return (struct mp_join *)(ptr - 2); -+ } -+ ptr += opsize - 2; -+ length -= opsize; -+ } -+ } -+ return NULL; -+} -+ -+int mptcp_lookup_join(struct sk_buff *skb, struct inet_timewait_sock *tw) -+{ -+ struct sock *meta_sk; -+ u32 token; -+ bool meta_v4; -+ struct mp_join *join_opt = mptcp_find_join(skb); -+ if (!join_opt) -+ return 0; -+ -+ /* MPTCP structures were not initialized, so return error */ -+ if (mptcp_init_failed) -+ return -1; -+ -+ token = join_opt->u.syn.token; -+ meta_sk = mptcp_hash_find(dev_net(skb_dst(skb)->dev), token); -+ if (!meta_sk) { -+ MPTCP_INC_STATS(dev_net(skb_dst(skb)->dev), MPTCP_MIB_JOINNOTOKEN); -+ mptcp_debug("%s:mpcb not found:%x\n", __func__, token); -+ return -1; -+ } -+ -+ meta_v4 = meta_sk->sk_family == AF_INET; -+ if (meta_v4) { -+ if (skb->protocol == htons(ETH_P_IPV6)) { -+ mptcp_debug("SYN+MP_JOIN with IPV6 address on pure IPV4 meta\n"); -+ sock_put(meta_sk); /* Taken by mptcp_hash_find */ -+ return -1; -+ } -+ } else if (skb->protocol == htons(ETH_P_IP) && meta_sk->sk_ipv6only) { -+ mptcp_debug("SYN+MP_JOIN with IPV4 address on IPV6_V6ONLY meta\n"); -+ sock_put(meta_sk); /* Taken by mptcp_hash_find */ -+ return -1; -+ } -+ -+ /* Coming from time-wait-sock processing in tcp_v4_rcv. -+ * We have to deschedule it before continuing, because otherwise -+ * mptcp_v4_do_rcv will hit again on it inside tcp_v4_hnd_req. -+ */ -+ if (tw) -+ inet_twsk_deschedule_put(tw); -+ -+ /* OK, this is a new syn/join, let's create a new open request and -+ * send syn+ack -+ */ -+ if (skb->protocol == htons(ETH_P_IP)) { -+ tcp_v4_do_rcv(meta_sk, skb); -+#if IS_ENABLED(CONFIG_IPV6) -+ } else { -+ tcp_v6_do_rcv(meta_sk, skb); -+#endif /* CONFIG_IPV6 */ -+ } -+ sock_put(meta_sk); /* Taken by mptcp_hash_find */ -+ return 1; -+} -+ -+int mptcp_do_join_short(struct sk_buff *skb, -+ const struct mptcp_options_received *mopt, -+ struct net *net) -+{ -+ struct sock *meta_sk; -+ u32 token; -+ bool meta_v4; -+ -+ token = mopt->mptcp_rem_token; -+ meta_sk = mptcp_hash_find(net, token); -+ if (!meta_sk) { -+ MPTCP_INC_STATS(dev_net(skb_dst(skb)->dev), MPTCP_MIB_JOINNOTOKEN); -+ mptcp_debug("%s:mpcb not found:%x\n", __func__, token); -+ return -1; -+ } -+ -+ meta_v4 = meta_sk->sk_family == AF_INET; -+ if (meta_v4) { -+ if (skb->protocol == htons(ETH_P_IPV6)) { -+ mptcp_debug("SYN+MP_JOIN with IPV6 address on pure IPV4 meta\n"); -+ sock_put(meta_sk); /* Taken by mptcp_hash_find */ -+ return -1; -+ } -+ } else if (skb->protocol == htons(ETH_P_IP) && meta_sk->sk_ipv6only) { -+ mptcp_debug("SYN+MP_JOIN with IPV4 address on IPV6_V6ONLY meta\n"); -+ sock_put(meta_sk); /* Taken by mptcp_hash_find */ -+ return -1; -+ } -+ -+ /* OK, this is a new syn/join, let's create a new open request and -+ * send syn+ack -+ */ -+ -+ /* mptcp_v4_do_rcv tries to free the skb - we prevent this, as -+ * the skb will finally be freed by tcp_v4_do_rcv (where we are -+ * coming from) -+ */ -+ skb_get(skb); -+ if (skb->protocol == htons(ETH_P_IP)) { -+ tcp_v4_do_rcv(meta_sk, skb); -+#if IS_ENABLED(CONFIG_IPV6) -+ } else { /* IPv6 */ -+ tcp_v6_do_rcv(meta_sk, skb); -+#endif /* CONFIG_IPV6 */ -+ } -+ -+ sock_put(meta_sk); /* Taken by mptcp_hash_find */ -+ return 0; -+} -+ -+/** -+ * Equivalent of tcp_fin() for MPTCP -+ * Can be called only when the FIN is validly part -+ * of the data seqnum space. Not before when we get holes. -+ */ -+void mptcp_fin(struct sock *meta_sk) -+{ -+ struct sock *sk = NULL; -+ struct tcp_sock *meta_tp = tcp_sk(meta_sk); -+ struct mptcp_cb *mpcb = meta_tp->mpcb; -+ struct mptcp_tcp_sock *mptcp; -+ unsigned char state; -+ -+ mptcp_for_each_sub(mpcb, mptcp) { -+ struct sock *sk_it = mptcp_to_sock(mptcp); -+ -+ if (tcp_sk(sk_it)->mptcp->path_index == mpcb->dfin_path_index) { -+ sk = sk_it; -+ break; -+ } -+ } -+ -+ if (!sk || sk->sk_state == TCP_CLOSE) -+ sk = mptcp_select_ack_sock(meta_sk); -+ -+ inet_csk_schedule_ack(sk); -+ -+ if (!mpcb->in_time_wait) { -+ meta_sk->sk_shutdown |= RCV_SHUTDOWN; -+ sock_set_flag(meta_sk, SOCK_DONE); -+ state = meta_sk->sk_state; -+ } else { -+ state = mpcb->mptw_state; -+ } -+ -+ switch (state) { -+ case TCP_SYN_RECV: -+ case TCP_ESTABLISHED: -+ /* Move to CLOSE_WAIT */ -+ tcp_set_state(meta_sk, TCP_CLOSE_WAIT); -+ inet_csk(sk)->icsk_ack.pingpong = 1; -+ break; -+ -+ case TCP_CLOSE_WAIT: -+ case TCP_CLOSING: -+ /* Received a retransmission of the FIN, do -+ * nothing. -+ */ -+ break; -+ case TCP_LAST_ACK: -+ /* RFC793: Remain in the LAST-ACK state. */ -+ break; -+ -+ case TCP_FIN_WAIT1: -+ /* This case occurs when a simultaneous close -+ * happens, we must ack the received FIN and -+ * enter the CLOSING state. -+ */ -+ tcp_send_ack(sk); -+ tcp_set_state(meta_sk, TCP_CLOSING); -+ break; -+ case TCP_FIN_WAIT2: -+ /* Received a FIN -- send ACK and enter TIME_WAIT. */ -+ tcp_send_ack(sk); -+ meta_tp->ops->time_wait(meta_sk, TCP_TIME_WAIT, 0); -+ break; -+ default: -+ /* Only TCP_LISTEN and TCP_CLOSE are left, in these -+ * cases we should never reach this piece of code. -+ */ -+ pr_err("%s: Impossible, meta_sk->sk_state=%d\n", __func__, -+ meta_sk->sk_state); -+ break; -+ } -+ -+ /* It _is_ possible, that we have something out-of-order _after_ FIN. -+ * Probably, we should reset in this case. For now drop them. -+ */ -+ skb_rbtree_purge(&meta_tp->out_of_order_queue); -+ sk_mem_reclaim(meta_sk); -+ -+ if (!sock_flag(meta_sk, SOCK_DEAD)) { -+ meta_sk->sk_state_change(meta_sk); -+ -+ /* Do not send POLL_HUP for half duplex close. */ -+ if (meta_sk->sk_shutdown == SHUTDOWN_MASK || -+ meta_sk->sk_state == TCP_CLOSE) -+ sk_wake_async(meta_sk, SOCK_WAKE_WAITD, POLL_HUP); -+ else -+ sk_wake_async(meta_sk, SOCK_WAKE_WAITD, POLL_IN); -+ } -+ -+ return; -+} -+ -+/* Similar to tcp_xmit_retransmit_queue */ -+static void mptcp_xmit_retransmit_queue(struct sock *meta_sk) -+{ -+ struct tcp_sock *meta_tp = tcp_sk(meta_sk); -+ struct sk_buff *skb, *rtx_head; -+ -+ if (!meta_tp->packets_out) -+ return; -+ -+ skb = rtx_head = tcp_rtx_queue_head(meta_sk); -+ skb_rbtree_walk_from(skb) { -+ if (mptcp_retransmit_skb(meta_sk, skb)) -+ return; -+ -+ if (skb == rtx_head) -+ inet_csk_reset_xmit_timer(meta_sk, ICSK_TIME_RETRANS, -+ inet_csk(meta_sk)->icsk_rto, -+ TCP_RTO_MAX); -+ } -+} -+ -+static void mptcp_snd_una_update(struct tcp_sock *meta_tp, u32 data_ack) -+{ -+ u32 delta = data_ack - meta_tp->snd_una; -+ -+ sock_owned_by_me((struct sock *)meta_tp); -+ meta_tp->bytes_acked += delta; -+ meta_tp->snd_una = data_ack; -+} -+ -+/* Handle the DATA_ACK */ -+static void mptcp_data_ack(struct sock *sk, const struct sk_buff *skb) -+{ -+ struct sock *meta_sk = mptcp_meta_sk(sk); -+ struct tcp_sock *meta_tp = tcp_sk(meta_sk), *tp = tcp_sk(sk); -+ struct tcp_skb_cb *tcb = TCP_SKB_CB(skb); -+ u32 prior_snd_una = meta_tp->snd_una; -+ int prior_packets; -+ u32 nwin, data_ack, data_seq; -+ u16 data_len = 0; -+ -+ /* A valid packet came in - subflow is operational again */ -+ tp->pf = 0; -+ -+ /* Even if there is no data-ack, we stop retransmitting. -+ * Except if this is a SYN/ACK. Then it is just a retransmission -+ */ -+ if (tp->mptcp->pre_established && !tcp_hdr(skb)->syn) { -+ tp->mptcp->pre_established = 0; -+ sk_stop_timer(sk, &tp->mptcp->mptcp_ack_timer); -+ -+ if (meta_tp->mpcb->pm_ops->established_subflow) -+ meta_tp->mpcb->pm_ops->established_subflow(sk); -+ } -+ -+ /* If we are in infinite mapping mode, rx_opt.data_ack has been -+ * set by mptcp_clean_rtx_infinite. -+ */ -+ if (!(tcb->mptcp_flags & MPTCPHDR_ACK) && !tp->mpcb->infinite_mapping_snd) -+ return; -+ -+ if (unlikely(!tp->mptcp->fully_established) && -+ tp->mptcp->snt_isn + 1 != TCP_SKB_CB(skb)->ack_seq) -+ /* As soon as a subflow-data-ack (not acking syn, thus snt_isn + 1) -+ * includes a data-ack, we are fully established -+ */ -+ mptcp_become_fully_estab(sk); -+ -+ /* After we did the subflow-only processing (stopping timer and marking -+ * subflow as established), check if we can proceed with MPTCP-level -+ * processing. -+ */ -+ if (meta_sk->sk_state == TCP_CLOSE) -+ return; -+ -+ /* Get the data_seq */ -+ if (mptcp_is_data_seq(skb)) { -+ data_seq = tp->mptcp->rx_opt.data_seq; -+ data_len = tp->mptcp->rx_opt.data_len; -+ } else { -+ data_seq = meta_tp->snd_wl1; -+ } -+ -+ data_ack = tp->mptcp->rx_opt.data_ack; -+ -+ /* If the ack is older than previous acks -+ * then we can probably ignore it. -+ */ -+ if (before(data_ack, prior_snd_una)) -+ goto exit; -+ -+ /* If the ack includes data we haven't sent yet, discard -+ * this segment (RFC793 Section 3.9). -+ */ -+ if (after(data_ack, meta_tp->snd_nxt)) -+ goto exit; -+ -+ /*** Now, update the window - inspired by tcp_ack_update_window ***/ -+ nwin = ntohs(tcp_hdr(skb)->window); -+ -+ if (likely(!tcp_hdr(skb)->syn)) -+ nwin <<= tp->rx_opt.snd_wscale; -+ -+ if (tcp_may_update_window(meta_tp, data_ack, data_seq, nwin)) { -+ tcp_update_wl(meta_tp, data_seq); -+ -+ /* Draft v09, Section 3.3.5: -+ * [...] It should only update its local receive window values -+ * when the largest sequence number allowed (i.e. DATA_ACK + -+ * receive window) increases. [...] -+ */ -+ if (meta_tp->snd_wnd != nwin && -+ !before(data_ack + nwin, tcp_wnd_end(meta_tp))) { -+ meta_tp->snd_wnd = nwin; -+ -+ if (nwin > meta_tp->max_window) -+ meta_tp->max_window = nwin; -+ } -+ } -+ /*** Done, update the window ***/ -+ -+ /* We passed data and got it acked, remove any soft error -+ * log. Something worked... -+ */ -+ sk->sk_err_soft = 0; -+ inet_csk(meta_sk)->icsk_probes_out = 0; -+ meta_tp->rcv_tstamp = tcp_jiffies32; -+ prior_packets = meta_tp->packets_out; -+ if (!prior_packets) -+ goto no_queue; -+ -+ mptcp_snd_una_update(meta_tp, data_ack); -+ -+ mptcp_clean_rtx_queue(meta_sk, prior_snd_una); -+ -+ /* We are in loss-state, and something got acked, retransmit the whole -+ * queue now! -+ */ -+ if (inet_csk(meta_sk)->icsk_ca_state == TCP_CA_Loss && -+ after(data_ack, prior_snd_una)) { -+ mptcp_xmit_retransmit_queue(meta_sk); -+ inet_csk(meta_sk)->icsk_ca_state = TCP_CA_Open; -+ } -+ -+ /* Simplified version of tcp_new_space, because the snd-buffer -+ * is handled by all the subflows. -+ */ -+ if (sock_flag(meta_sk, SOCK_QUEUE_SHRUNK)) { -+ sock_reset_flag(meta_sk, SOCK_QUEUE_SHRUNK); -+ if (meta_sk->sk_socket && -+ test_bit(SOCK_NOSPACE, &meta_sk->sk_socket->flags)) -+ meta_sk->sk_write_space(meta_sk); -+ } -+ -+ if (meta_sk->sk_state != TCP_ESTABLISHED && -+ mptcp_rcv_state_process(meta_sk, sk, skb, data_seq, data_len)) -+ return; -+ -+exit: -+ mptcp_push_pending_frames(meta_sk); -+ -+ return; -+ -+no_queue: -+ if (tcp_send_head(meta_sk)) -+ tcp_ack_probe(meta_sk); -+ -+ mptcp_push_pending_frames(meta_sk); -+ -+ return; -+} -+ -+void mptcp_clean_rtx_infinite(const struct sk_buff *skb, struct sock *sk) -+{ -+ struct tcp_sock *tp = tcp_sk(sk), *meta_tp = tcp_sk(mptcp_meta_sk(sk)); -+ -+ if (!tp->mpcb->infinite_mapping_snd) -+ return; -+ -+ /* The difference between both write_seq's represents the offset between -+ * data-sequence and subflow-sequence. As we are infinite, this must -+ * match. -+ * -+ * Thus, from this difference we can infer the meta snd_una. -+ */ -+ tp->mptcp->rx_opt.data_ack = meta_tp->snd_nxt - tp->snd_nxt + -+ tp->snd_una; -+ -+ mptcp_data_ack(sk, skb); -+} -+ -+/**** static functions used by mptcp_parse_options */ -+ -+static void mptcp_send_reset_rem_id(const struct mptcp_cb *mpcb, u8 rem_id) -+{ -+ struct mptcp_tcp_sock *mptcp; -+ struct hlist_node *tmp; -+ -+ mptcp_for_each_sub_safe(mpcb, mptcp, tmp) { -+ struct sock *sk_it = mptcp_to_sock(mptcp); -+ -+ if (tcp_sk(sk_it)->mptcp->rem_id == rem_id) { -+ mptcp_reinject_data(sk_it, 0); -+ mptcp_send_reset(sk_it); -+ } -+ } -+} -+ -+static inline bool is_valid_addropt_opsize(u8 mptcp_ver, -+ struct mp_add_addr *mpadd, -+ int opsize) -+{ -+#if IS_ENABLED(CONFIG_IPV6) -+ if (mptcp_ver < MPTCP_VERSION_1 && mpadd->ipver == 6) { -+ return opsize == MPTCP_SUB_LEN_ADD_ADDR6 || -+ opsize == MPTCP_SUB_LEN_ADD_ADDR6 + 2; -+ } -+ if (mptcp_ver >= MPTCP_VERSION_1 && mpadd->ipver == 6) -+ return opsize == MPTCP_SUB_LEN_ADD_ADDR6_VER1 || -+ opsize == MPTCP_SUB_LEN_ADD_ADDR6_VER1 + 2; -+#endif -+ if (mptcp_ver < MPTCP_VERSION_1 && mpadd->ipver == 4) { -+ return opsize == MPTCP_SUB_LEN_ADD_ADDR4 || -+ opsize == MPTCP_SUB_LEN_ADD_ADDR4 + 2; -+ } -+ if (mptcp_ver >= MPTCP_VERSION_1 && mpadd->ipver == 4) { -+ return opsize == MPTCP_SUB_LEN_ADD_ADDR4_VER1 || -+ opsize == MPTCP_SUB_LEN_ADD_ADDR4_VER1 + 2; -+ } -+ return false; -+} -+ -+void mptcp_parse_options(const uint8_t *ptr, int opsize, -+ struct mptcp_options_received *mopt, -+ const struct sk_buff *skb, -+ struct tcp_sock *tp) -+{ -+ const struct mptcp_option *mp_opt = (struct mptcp_option *)ptr; -+ -+ /* If the socket is mp-capable we would have a mopt. */ -+ if (!mopt) -+ return; -+ -+ switch (mp_opt->sub) { -+ case MPTCP_SUB_CAPABLE: -+ { -+ const struct mp_capable *mpcapable = (struct mp_capable *)ptr; -+ -+ if (opsize != MPTCP_SUB_LEN_CAPABLE_SYN && -+ opsize != MPTCP_SUB_LEN_CAPABLE_ACK) { -+ mptcp_debug("%s: mp_capable: bad option size %d\n", -+ __func__, opsize); -+ break; -+ } -+ -+ /* MPTCP-RFC 6824: -+ * "If receiving a message with the 'B' flag set to 1, and this -+ * is not understood, then this SYN MUST be silently ignored; -+ */ -+ if (mpcapable->b) { -+ mopt->drop_me = 1; -+ break; -+ } -+ -+ /* MPTCP-RFC 6824: -+ * "An implementation that only supports this method MUST set -+ * bit "H" to 1, and bits "C" through "G" to 0." -+ */ -+ if (!mpcapable->h) -+ break; -+ -+ mopt->saw_mpc = 1; -+ mopt->dss_csum = sysctl_mptcp_checksum || mpcapable->a; -+ -+ if (opsize >= MPTCP_SUB_LEN_CAPABLE_SYN) -+ mopt->mptcp_sender_key = mpcapable->sender_key; -+ if (opsize == MPTCP_SUB_LEN_CAPABLE_ACK) -+ mopt->mptcp_receiver_key = mpcapable->receiver_key; -+ -+ mopt->mptcp_ver = mpcapable->ver; -+ break; -+ } -+ case MPTCP_SUB_JOIN: -+ { -+ const struct mp_join *mpjoin = (struct mp_join *)ptr; -+ -+ if (opsize != MPTCP_SUB_LEN_JOIN_SYN && -+ opsize != MPTCP_SUB_LEN_JOIN_SYNACK && -+ opsize != MPTCP_SUB_LEN_JOIN_ACK) { -+ mptcp_debug("%s: mp_join: bad option size %d\n", -+ __func__, opsize); -+ break; -+ } -+ -+ /* saw_mpc must be set, because in tcp_check_req we assume that -+ * it is set to support falling back to reg. TCP if a rexmitted -+ * SYN has no MP_CAPABLE or MP_JOIN -+ */ -+ switch (opsize) { -+ case MPTCP_SUB_LEN_JOIN_SYN: -+ mopt->is_mp_join = 1; -+ mopt->saw_mpc = 1; -+ mopt->low_prio = mpjoin->b; -+ mopt->rem_id = mpjoin->addr_id; -+ mopt->mptcp_rem_token = mpjoin->u.syn.token; -+ mopt->mptcp_recv_nonce = mpjoin->u.syn.nonce; -+ break; -+ case MPTCP_SUB_LEN_JOIN_SYNACK: -+ mopt->saw_mpc = 1; -+ mopt->low_prio = mpjoin->b; -+ mopt->rem_id = mpjoin->addr_id; -+ mopt->mptcp_recv_tmac = mpjoin->u.synack.mac; -+ mopt->mptcp_recv_nonce = mpjoin->u.synack.nonce; -+ break; -+ case MPTCP_SUB_LEN_JOIN_ACK: -+ mopt->saw_mpc = 1; -+ mopt->join_ack = 1; -+ memcpy(mopt->mptcp_recv_mac, mpjoin->u.ack.mac, 20); -+ break; -+ } -+ break; -+ } -+ case MPTCP_SUB_DSS: -+ { -+ const struct mp_dss *mdss = (struct mp_dss *)ptr; -+ struct tcp_skb_cb *tcb = TCP_SKB_CB(skb); -+ -+ /* We check opsize for the csum and non-csum case. We do this, -+ * because the draft says that the csum SHOULD be ignored if -+ * it has not been negotiated in the MP_CAPABLE but still is -+ * present in the data. -+ * -+ * It will get ignored later in mptcp_queue_skb. -+ */ -+ if (opsize != mptcp_sub_len_dss(mdss, 0) && -+ opsize != mptcp_sub_len_dss(mdss, 1)) { -+ mptcp_debug("%s: mp_dss: bad option size %d\n", -+ __func__, opsize); -+ break; -+ } -+ -+ ptr += 4; -+ -+ if (mdss->A) { -+ tcb->mptcp_flags |= MPTCPHDR_ACK; -+ -+ if (mdss->a) { -+ mopt->data_ack = (u32) get_unaligned_be64(ptr); -+ ptr += MPTCP_SUB_LEN_ACK_64; -+ } else { -+ mopt->data_ack = get_unaligned_be32(ptr); -+ ptr += MPTCP_SUB_LEN_ACK; -+ } -+ } -+ -+ tcb->dss_off = (ptr - skb_transport_header(skb)); -+ -+ if (mdss->M) { -+ if (mdss->m) { -+ u64 data_seq64 = get_unaligned_be64(ptr); -+ -+ tcb->mptcp_flags |= MPTCPHDR_SEQ64_SET; -+ mopt->data_seq = (u32) data_seq64; -+ -+ ptr += 12; /* 64-bit dseq + subseq */ -+ } else { -+ mopt->data_seq = get_unaligned_be32(ptr); -+ ptr += 8; /* 32-bit dseq + subseq */ -+ } -+ mopt->data_len = get_unaligned_be16(ptr); -+ -+ tcb->mptcp_flags |= MPTCPHDR_SEQ; -+ -+ /* Is a check-sum present? */ -+ if (opsize == mptcp_sub_len_dss(mdss, 1)) -+ tcb->mptcp_flags |= MPTCPHDR_DSS_CSUM; -+ -+ /* DATA_FIN only possible with DSS-mapping */ -+ if (mdss->F) -+ tcb->mptcp_flags |= MPTCPHDR_FIN; -+ } -+ -+ break; -+ } -+ case MPTCP_SUB_ADD_ADDR: -+ { -+ struct mp_add_addr *mpadd = (struct mp_add_addr *)ptr; -+ -+ /* If tcp_sock is not available, MPTCP version can't be -+ * retrieved and ADD_ADDR opsize validation is not possible. -+ */ -+ if (!tp || !tp->mpcb) -+ break; -+ -+ if (!is_valid_addropt_opsize(tp->mpcb->mptcp_ver, -+ mpadd, opsize)) { -+ mptcp_debug("%s: mp_add_addr: bad option size %d\n", -+ __func__, opsize); -+ break; -+ } -+ -+ /* We have to manually parse the options if we got two of them. */ -+ if (mopt->saw_add_addr) { -+ mopt->more_add_addr = 1; -+ break; -+ } -+ mopt->saw_add_addr = 1; -+ mopt->add_addr_ptr = ptr; -+ break; -+ } -+ case MPTCP_SUB_REMOVE_ADDR: -+ if ((opsize - MPTCP_SUB_LEN_REMOVE_ADDR) < 0) { -+ mptcp_debug("%s: mp_remove_addr: bad option size %d\n", -+ __func__, opsize); -+ break; -+ } -+ -+ if (mopt->saw_rem_addr) { -+ mopt->more_rem_addr = 1; -+ break; -+ } -+ mopt->saw_rem_addr = 1; -+ mopt->rem_addr_ptr = ptr; -+ break; -+ case MPTCP_SUB_PRIO: -+ { -+ const struct mp_prio *mpprio = (struct mp_prio *)ptr; -+ -+ if (opsize != MPTCP_SUB_LEN_PRIO && -+ opsize != MPTCP_SUB_LEN_PRIO_ADDR) { -+ mptcp_debug("%s: mp_prio: bad option size %d\n", -+ __func__, opsize); -+ break; -+ } -+ -+ mopt->saw_low_prio = 1; -+ mopt->low_prio = mpprio->b; -+ -+ if (opsize == MPTCP_SUB_LEN_PRIO_ADDR) { -+ mopt->saw_low_prio = 2; -+ mopt->prio_addr_id = mpprio->addr_id; -+ } -+ break; -+ } -+ case MPTCP_SUB_FAIL: -+ if (opsize != MPTCP_SUB_LEN_FAIL) { -+ mptcp_debug("%s: mp_fail: bad option size %d\n", -+ __func__, opsize); -+ break; -+ } -+ mopt->mp_fail = 1; -+ break; -+ case MPTCP_SUB_FCLOSE: -+ if (opsize != MPTCP_SUB_LEN_FCLOSE) { -+ mptcp_debug("%s: mp_fclose: bad option size %d\n", -+ __func__, opsize); -+ break; -+ } -+ -+ mopt->mp_fclose = 1; -+ mopt->mptcp_sender_key = ((struct mp_fclose *)ptr)->key; -+ -+ break; -+ default: -+ mptcp_debug("%s: Received unkown subtype: %d\n", -+ __func__, mp_opt->sub); -+ break; -+ } -+} -+ -+/** Parse only MPTCP options */ -+void tcp_parse_mptcp_options(const struct sk_buff *skb, -+ struct mptcp_options_received *mopt) -+{ -+ const struct tcphdr *th = tcp_hdr(skb); -+ int length = (th->doff * 4) - sizeof(struct tcphdr); -+ const unsigned char *ptr = (const unsigned char *)(th + 1); -+ -+ while (length > 0) { -+ int opcode = *ptr++; -+ int opsize; -+ -+ switch (opcode) { -+ case TCPOPT_EOL: -+ return; -+ case TCPOPT_NOP: /* Ref: RFC 793 section 3.1 */ -+ length--; -+ continue; -+ default: -+ opsize = *ptr++; -+ if (opsize < 2) /* "silly options" */ -+ return; -+ if (opsize > length) -+ return; /* don't parse partial options */ -+ if (opcode == TCPOPT_MPTCP) -+ mptcp_parse_options(ptr - 2, opsize, mopt, skb, NULL); -+ } -+ ptr += opsize - 2; -+ length -= opsize; -+ } -+} -+ -+bool mptcp_check_rtt(const struct tcp_sock *tp, int time) -+{ -+ struct mptcp_cb *mpcb = tp->mpcb; -+ struct mptcp_tcp_sock *mptcp; -+ u32 rtt_max = 0; -+ -+ /* In MPTCP, we take the max delay across all flows, -+ * in order to take into account meta-reordering buffers. -+ */ -+ mptcp_for_each_sub(mpcb, mptcp) { -+ struct sock *sk = mptcp_to_sock(mptcp); -+ -+ if (!mptcp_sk_can_recv(sk)) -+ continue; -+ -+ if (rtt_max < tcp_sk(sk)->rcv_rtt_est.rtt_us) -+ rtt_max = tcp_sk(sk)->rcv_rtt_est.rtt_us; -+ } -+ if (time < (rtt_max >> 3) || !rtt_max) -+ return true; -+ -+ return false; -+} -+ -+static void mptcp_handle_add_addr(const unsigned char *ptr, struct sock *sk) -+{ -+ struct mp_add_addr *mpadd = (struct mp_add_addr *)ptr; -+ struct mptcp_cb *mpcb = tcp_sk(sk)->mpcb; -+ __be16 port = 0; -+ union inet_addr addr; -+ sa_family_t family; -+ -+ if (mpadd->ipver == 4) { -+ char *recv_hmac; -+ u8 hash_mac_check[20]; -+ u8 no_key[8]; -+ int msg_parts = 0; -+ -+ if (mpcb->mptcp_ver < MPTCP_VERSION_1) -+ goto skip_hmac_v4; -+ -+ *(u64 *)no_key = 0; -+ recv_hmac = (char *)mpadd->u.v4.mac; -+ if (mpadd->len == MPTCP_SUB_LEN_ADD_ADDR4_VER1) { -+ recv_hmac -= sizeof(mpadd->u.v4.port); -+ msg_parts = 2; -+ } else if (mpadd->len == MPTCP_SUB_LEN_ADD_ADDR4_VER1 + 2) { -+ msg_parts = 3; -+ } -+ mptcp_hmac_sha1((u8 *)&mpcb->mptcp_rem_key, -+ (u8 *)no_key, -+ (u32 *)hash_mac_check, msg_parts, -+ 1, (u8 *)&mpadd->addr_id, -+ 4, (u8 *)&mpadd->u.v4.addr.s_addr, -+ 2, (u8 *)&mpadd->u.v4.port); -+ if (memcmp(hash_mac_check, recv_hmac, 8) != 0) -+ /* ADD_ADDR2 discarded */ -+ return; -+skip_hmac_v4: -+ if ((mpcb->mptcp_ver == MPTCP_VERSION_0 && -+ mpadd->len == MPTCP_SUB_LEN_ADD_ADDR4 + 2) || -+ (mpcb->mptcp_ver == MPTCP_VERSION_1 && -+ mpadd->len == MPTCP_SUB_LEN_ADD_ADDR4_VER1 + 2)) -+ port = mpadd->u.v4.port; -+ family = AF_INET; -+ addr.in = mpadd->u.v4.addr; -+#if IS_ENABLED(CONFIG_IPV6) -+ } else if (mpadd->ipver == 6) { -+ char *recv_hmac; -+ u8 hash_mac_check[20]; -+ u8 no_key[8]; -+ int msg_parts = 0; -+ -+ if (mpcb->mptcp_ver < MPTCP_VERSION_1) -+ goto skip_hmac_v6; -+ -+ *(u64 *)no_key = 0; -+ recv_hmac = (char *)mpadd->u.v6.mac; -+ if (mpadd->len == MPTCP_SUB_LEN_ADD_ADDR6_VER1) { -+ recv_hmac -= sizeof(mpadd->u.v6.port); -+ msg_parts = 2; -+ } else if (mpadd->len == MPTCP_SUB_LEN_ADD_ADDR6_VER1 + 2) { -+ msg_parts = 3; -+ } -+ mptcp_hmac_sha1((u8 *)&mpcb->mptcp_rem_key, -+ (u8 *)no_key, -+ (u32 *)hash_mac_check, msg_parts, -+ 1, (u8 *)&mpadd->addr_id, -+ 16, (u8 *)&mpadd->u.v6.addr.s6_addr, -+ 2, (u8 *)&mpadd->u.v6.port); -+ if (memcmp(hash_mac_check, recv_hmac, 8) != 0) -+ /* ADD_ADDR2 discarded */ -+ return; -+skip_hmac_v6: -+ if ((mpcb->mptcp_ver == MPTCP_VERSION_0 && -+ mpadd->len == MPTCP_SUB_LEN_ADD_ADDR6 + 2) || -+ (mpcb->mptcp_ver == MPTCP_VERSION_1 && -+ mpadd->len == MPTCP_SUB_LEN_ADD_ADDR6_VER1 + 2)) -+ port = mpadd->u.v6.port; -+ family = AF_INET6; -+ addr.in6 = mpadd->u.v6.addr; -+#endif /* CONFIG_IPV6 */ -+ } else { -+ return; -+ } -+ -+ if (mpcb->pm_ops->add_raddr) -+ mpcb->pm_ops->add_raddr(mpcb, &addr, family, port, mpadd->addr_id); -+ -+ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_ADDADDRRX); -+} -+ -+static void mptcp_handle_rem_addr(const unsigned char *ptr, struct sock *sk) -+{ -+ struct mp_remove_addr *mprem = (struct mp_remove_addr *)ptr; -+ int i; -+ u8 rem_id; -+ struct mptcp_cb *mpcb = tcp_sk(sk)->mpcb; -+ -+ for (i = 0; i <= mprem->len - MPTCP_SUB_LEN_REMOVE_ADDR; i++) { -+ rem_id = (&mprem->addrs_id)[i]; -+ -+ if (mpcb->pm_ops->rem_raddr) -+ mpcb->pm_ops->rem_raddr(mpcb, rem_id); -+ mptcp_send_reset_rem_id(mpcb, rem_id); -+ -+ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_REMADDRSUB); -+ } -+ -+ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_REMADDRRX); -+} -+ -+static void mptcp_parse_addropt(const struct sk_buff *skb, struct sock *sk) -+{ -+ struct tcphdr *th = tcp_hdr(skb); -+ unsigned char *ptr; -+ int length = (th->doff * 4) - sizeof(struct tcphdr); -+ -+ /* Jump through the options to check whether ADD_ADDR is there */ -+ ptr = (unsigned char *)(th + 1); -+ while (length > 0) { -+ int opcode = *ptr++; -+ int opsize; -+ -+ switch (opcode) { -+ case TCPOPT_EOL: -+ return; -+ case TCPOPT_NOP: -+ length--; -+ continue; -+ default: -+ opsize = *ptr++; -+ if (opsize < 2) -+ return; -+ if (opsize > length) -+ return; /* don't parse partial options */ -+ if (opcode == TCPOPT_MPTCP && -+ ((struct mptcp_option *)ptr)->sub == MPTCP_SUB_ADD_ADDR) { -+ u8 mptcp_ver = tcp_sk(sk)->mpcb->mptcp_ver; -+ struct mp_add_addr *mpadd = (struct mp_add_addr *)ptr; -+ -+ if (!is_valid_addropt_opsize(mptcp_ver, mpadd, -+ opsize)) -+ goto cont; -+ -+ mptcp_handle_add_addr(ptr, sk); -+ } -+ if (opcode == TCPOPT_MPTCP && -+ ((struct mptcp_option *)ptr)->sub == MPTCP_SUB_REMOVE_ADDR) { -+ if ((opsize - MPTCP_SUB_LEN_REMOVE_ADDR) < 0) -+ goto cont; -+ -+ mptcp_handle_rem_addr(ptr, sk); -+ } -+cont: -+ ptr += opsize - 2; -+ length -= opsize; -+ } -+ } -+ return; -+} -+ -+static bool mptcp_mp_fastclose_rcvd(struct sock *sk) -+{ -+ struct mptcp_tcp_sock *mptcp = tcp_sk(sk)->mptcp; -+ struct mptcp_cb *mpcb = tcp_sk(sk)->mpcb; -+ -+ if (likely(!mptcp->rx_opt.mp_fclose)) -+ return false; -+ -+ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_FASTCLOSERX); -+ mptcp->rx_opt.mp_fclose = 0; -+ if (mptcp->rx_opt.mptcp_sender_key != mpcb->mptcp_loc_key) -+ return false; -+ -+ mptcp_sub_force_close_all(mpcb, NULL); -+ -+ tcp_reset(mptcp_meta_sk(sk)); -+ -+ return true; -+} -+ -+static void mptcp_mp_fail_rcvd(struct sock *sk, const struct tcphdr *th) -+{ -+ struct mptcp_tcp_sock *mptcp = tcp_sk(sk)->mptcp; -+ struct sock *meta_sk = mptcp_meta_sk(sk); -+ struct mptcp_cb *mpcb = tcp_sk(sk)->mpcb; -+ -+ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_MPFAILRX); -+ mptcp->rx_opt.mp_fail = 0; -+ -+ if (!th->rst && !mpcb->infinite_mapping_snd) { -+ mpcb->send_infinite_mapping = 1; -+ -+ mptcp_restart_sending(meta_sk); -+ -+ mptcp_fallback_close(mpcb, sk); -+ } -+} -+ -+static inline void mptcp_path_array_check(struct sock *meta_sk) -+{ -+ struct mptcp_cb *mpcb = tcp_sk(meta_sk)->mpcb; -+ -+ if (unlikely(mpcb->list_rcvd)) { -+ mpcb->list_rcvd = 0; -+ if (mpcb->pm_ops->new_remote_address) -+ mpcb->pm_ops->new_remote_address(meta_sk); -+ } -+} -+ -+bool mptcp_handle_options(struct sock *sk, const struct tcphdr *th, -+ const struct sk_buff *skb) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct mptcp_options_received *mopt = &tp->mptcp->rx_opt; -+ struct mptcp_cb *mpcb = tp->mpcb; -+ -+ if (tp->mpcb->infinite_mapping_rcv || tp->mpcb->infinite_mapping_snd) -+ return false; -+ -+ if (mptcp_mp_fastclose_rcvd(sk)) -+ return true; -+ -+ if (sk->sk_state == TCP_RST_WAIT && !th->rst) -+ return true; -+ -+ if (unlikely(mopt->mp_fail)) -+ mptcp_mp_fail_rcvd(sk, th); -+ -+ /* RFC 6824, Section 3.3: -+ * If a checksum is not present when its use has been negotiated, the -+ * receiver MUST close the subflow with a RST as it is considered broken. -+ */ -+ if (mptcp_is_data_seq(skb) && tp->mpcb->dss_csum && -+ !(TCP_SKB_CB(skb)->mptcp_flags & MPTCPHDR_DSS_CSUM)) { -+ mptcp_send_reset(sk); -+ return true; -+ } -+ -+ /* We have to acknowledge retransmissions of the third -+ * ack. -+ */ -+ if (mopt->join_ack) { -+ tcp_send_delayed_ack(sk); -+ mopt->join_ack = 0; -+ } -+ -+ if (mopt->saw_add_addr || mopt->saw_rem_addr) { -+ if (mopt->more_add_addr || mopt->more_rem_addr) { -+ mptcp_parse_addropt(skb, sk); -+ } else { -+ if (mopt->saw_add_addr) -+ mptcp_handle_add_addr(mopt->add_addr_ptr, sk); -+ if (mopt->saw_rem_addr) -+ mptcp_handle_rem_addr(mopt->rem_addr_ptr, sk); -+ } -+ -+ mopt->more_add_addr = 0; -+ mopt->saw_add_addr = 0; -+ mopt->more_rem_addr = 0; -+ mopt->saw_rem_addr = 0; -+ } -+ if (mopt->saw_low_prio) { -+ if (mopt->saw_low_prio == 1) { -+ tp->mptcp->rcv_low_prio = mopt->low_prio; -+ if (mpcb->pm_ops->prio_changed) -+ mpcb->pm_ops->prio_changed(sk, mopt->low_prio); -+ } else { -+ struct mptcp_tcp_sock *mptcp; -+ -+ mptcp_for_each_sub(tp->mpcb, mptcp) { -+ if (mptcp->rem_id == mopt->prio_addr_id) { -+ mptcp->rcv_low_prio = mopt->low_prio; -+ if (mpcb->pm_ops->prio_changed) -+ mpcb->pm_ops->prio_changed(sk, -+ mopt->low_prio); -+ } -+ } -+ } -+ mopt->saw_low_prio = 0; -+ } -+ -+ mptcp_data_ack(sk, skb); -+ -+ mptcp_path_array_check(mptcp_meta_sk(sk)); -+ /* Socket may have been mp_killed by a REMOVE_ADDR */ -+ if (tp->mp_killed) -+ return true; -+ -+ return false; -+} -+ -+static void _mptcp_rcv_synsent_fastopen(struct sock *meta_sk, -+ struct sk_buff *skb, bool rtx_queue) -+{ -+ struct tcp_sock *meta_tp = tcp_sk(meta_sk); -+ struct tcp_sock *master_tp = tcp_sk(meta_tp->mpcb->master_sk); -+ u32 new_mapping = meta_tp->write_seq - master_tp->snd_una; -+ -+ /* If the server only acknowledges partially the data sent in -+ * the SYN, we need to trim the acknowledged part because -+ * we don't want to retransmit this already received data. -+ * When we reach this point, tcp_ack() has already cleaned up -+ * fully acked segments. However, tcp trims partially acked -+ * segments only when retransmitting. Since MPTCP comes into -+ * play only now, we will fake an initial transmit, and -+ * retransmit_skb() will not be called. The following fragment -+ * comes from __tcp_retransmit_skb(). -+ */ -+ if (before(TCP_SKB_CB(skb)->seq, master_tp->snd_una)) { -+ BUG_ON(before(TCP_SKB_CB(skb)->end_seq, -+ master_tp->snd_una)); -+ /* tcp_trim_head can only returns ENOMEM if skb is -+ * cloned. It is not the case here (see -+ * tcp_send_syn_data). -+ */ -+ BUG_ON(tcp_trim_head(meta_sk, skb, master_tp->snd_una - -+ TCP_SKB_CB(skb)->seq)); -+ } -+ -+ TCP_SKB_CB(skb)->seq += new_mapping; -+ TCP_SKB_CB(skb)->end_seq += new_mapping; -+ -+ list_del(&skb->tcp_tsorted_anchor); -+ -+ if (rtx_queue) -+ tcp_rtx_queue_unlink(skb, meta_sk); -+ else -+ tcp_unlink_write_queue(skb, meta_sk); -+ -+ INIT_LIST_HEAD(&skb->tcp_tsorted_anchor); -+ -+ tcp_add_write_queue_tail(meta_sk, skb); -+} -+ -+/* In case of fastopen, some data can already be in the write queue. -+ * We need to update the sequence number of the segments as they -+ * were initially TCP sequence numbers. -+ */ -+static void mptcp_rcv_synsent_fastopen(struct sock *meta_sk) -+{ -+ struct tcp_sock *meta_tp = tcp_sk(meta_sk); -+ struct tcp_sock *master_tp = tcp_sk(meta_tp->mpcb->master_sk); -+ struct sk_buff *skb_write_head, *skb_rtx_head, *tmp; -+ -+ skb_write_head = tcp_write_queue_head(meta_sk); -+ skb_rtx_head = tcp_rtx_queue_head(meta_sk); -+ -+ if (!(skb_write_head || skb_rtx_head)) -+ return; -+ -+ /* There should only be one skb in {write, rtx} queue: the data not -+ * acknowledged in the SYN+ACK. In this case, we need to map -+ * this data to data sequence numbers. -+ */ -+ -+ WARN_ON(skb_write_head && skb_rtx_head); -+ -+ if (skb_write_head) { -+ skb_queue_walk_from_safe(&meta_sk->sk_write_queue, -+ skb_write_head, tmp) { -+ _mptcp_rcv_synsent_fastopen(meta_sk, skb_write_head, -+ false); -+ } -+ } -+ -+ if (skb_rtx_head) { -+ skb_rbtree_walk_from_safe(skb_rtx_head, tmp) { -+ _mptcp_rcv_synsent_fastopen(meta_sk, skb_rtx_head, -+ true); -+ } -+ } -+ -+ /* We can advance write_seq by the number of bytes unacknowledged -+ * and that were mapped in the previous loop. -+ */ -+ meta_tp->write_seq += master_tp->write_seq - master_tp->snd_una; -+ -+ /* The packets from the master_sk will be entailed to it later -+ * Until that time, its write queue is empty, and -+ * write_seq must align with snd_una -+ */ -+ master_tp->snd_nxt = master_tp->write_seq = master_tp->snd_una; -+ master_tp->packets_out = 0; -+} -+ -+/* The skptr is needed, because if we become MPTCP-capable, we have to switch -+ * from meta-socket to master-socket. -+ * -+ * @return: 1 - we want to reset this connection -+ * 2 - we want to discard the received syn/ack -+ * 0 - everything is fine - continue -+ */ -+int mptcp_rcv_synsent_state_process(struct sock *sk, struct sock **skptr, -+ const struct sk_buff *skb, -+ const struct mptcp_options_received *mopt) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ -+ if (mptcp(tp)) { -+ u8 hash_mac_check[20]; -+ struct mptcp_cb *mpcb = tp->mpcb; -+ -+ mptcp_hmac_sha1((u8 *)&mpcb->mptcp_rem_key, -+ (u8 *)&mpcb->mptcp_loc_key, -+ (u32 *)hash_mac_check, 2, -+ 4, (u8 *)&tp->mptcp->rx_opt.mptcp_recv_nonce, -+ 4, (u8 *)&tp->mptcp->mptcp_loc_nonce); -+ if (memcmp(hash_mac_check, -+ (char *)&tp->mptcp->rx_opt.mptcp_recv_tmac, 8)) { -+ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_JOINSYNACKMAC); -+ mptcp_sub_force_close(sk); -+ return 1; -+ } -+ -+ /* Set this flag in order to postpone data sending -+ * until the 4th ack arrives. -+ */ -+ tp->mptcp->pre_established = 1; -+ tp->mptcp->rcv_low_prio = tp->mptcp->rx_opt.low_prio; -+ -+ mptcp_hmac_sha1((u8 *)&mpcb->mptcp_loc_key, -+ (u8 *)&mpcb->mptcp_rem_key, -+ (u32 *)&tp->mptcp->sender_mac[0], 2, -+ 4, (u8 *)&tp->mptcp->mptcp_loc_nonce, -+ 4, (u8 *)&tp->mptcp->rx_opt.mptcp_recv_nonce); -+ -+ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_JOINSYNACKRX); -+ } else if (mopt->saw_mpc) { -+ struct sock *meta_sk = sk; -+ -+ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_MPCAPABLEACTIVEACK); -+ if (mopt->mptcp_ver > tcp_sk(sk)->mptcp_ver) -+ /* TODO Consider adding new MPTCP_INC_STATS entry */ -+ goto fallback; -+ -+ if (mptcp_create_master_sk(sk, mopt->mptcp_sender_key, -+ mopt->mptcp_ver, -+ ntohs(tcp_hdr(skb)->window))) -+ return 2; -+ -+ sk = tcp_sk(sk)->mpcb->master_sk; -+ *skptr = sk; -+ tp = tcp_sk(sk); -+ -+ /* If fastopen was used data might be in the send queue. We -+ * need to update their sequence number to MPTCP-level seqno. -+ * Note that it can happen in rare cases that fastopen_req is -+ * NULL and syn_data is 0 but fastopen indeed occurred and -+ * data has been queued in the write queue (but not sent). -+ * Example of such rare cases: connect is non-blocking and -+ * TFO is configured to work without cookies. -+ */ -+ mptcp_rcv_synsent_fastopen(meta_sk); -+ -+ /* -1, because the SYN consumed 1 byte. In case of TFO, we -+ * start the subflow-sequence number as if the data of the SYN -+ * is not part of any mapping. -+ */ -+ tp->mptcp->snt_isn = tp->snd_una - 1; -+ tp->mpcb->dss_csum = mopt->dss_csum; -+ if (tp->mpcb->dss_csum) -+ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_CSUMENABLED); -+ -+ tp->mptcp->include_mpc = 1; -+ -+ /* Ensure that fastopen is handled at the meta-level. */ -+ tp->fastopen_req = NULL; -+ -+ sk_set_socket(sk, meta_sk->sk_socket); -+ sk->sk_wq = meta_sk->sk_wq; -+ -+ bh_unlock_sock(sk); -+ /* hold in sk_clone_lock due to initialization to 2 */ -+ sock_put(sk); -+ } else { -+ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_MPCAPABLEACTIVEFALLBACK); -+fallback: -+ tp->request_mptcp = 0; -+ -+ if (tp->inside_tk_table) -+ mptcp_hash_remove_bh(tp); -+ } -+ -+ if (mptcp(tp)) -+ tp->mptcp->rcv_isn = TCP_SKB_CB(skb)->seq; -+ -+ return 0; -+} -+ -+/* Similar to tcp_should_expand_sndbuf */ -+bool mptcp_should_expand_sndbuf(const struct sock *sk) -+{ -+ const struct sock *meta_sk = mptcp_meta_sk(sk); -+ const struct tcp_sock *meta_tp = tcp_sk(meta_sk); -+ const struct mptcp_tcp_sock *mptcp; -+ -+ /* We circumvent this check in tcp_check_space, because we want to -+ * always call sk_write_space. So, we reproduce the check here. -+ */ -+ if (!meta_sk->sk_socket || -+ !test_bit(SOCK_NOSPACE, &meta_sk->sk_socket->flags)) -+ return false; -+ -+ /* If the user specified a specific send buffer setting, do -+ * not modify it. -+ */ -+ if (meta_sk->sk_userlocks & SOCK_SNDBUF_LOCK) -+ return false; -+ -+ /* If we are under global TCP memory pressure, do not expand. */ -+ if (tcp_under_memory_pressure(meta_sk)) -+ return false; -+ -+ /* If we are under soft global TCP memory pressure, do not expand. */ -+ if (sk_memory_allocated(meta_sk) >= sk_prot_mem_limits(meta_sk, 0)) -+ return false; -+ -+ /* For MPTCP we look for a subsocket that could send data. -+ * If we found one, then we update the send-buffer. -+ */ -+ mptcp_for_each_sub(meta_tp->mpcb, mptcp) { -+ const struct sock *sk_it = mptcp_to_sock(mptcp); -+ const struct tcp_sock *tp_it = tcp_sk(sk_it); -+ -+ if (!mptcp_sk_can_send(sk_it)) -+ continue; -+ -+ if (tcp_packets_in_flight(tp_it) < tp_it->snd_cwnd) -+ return true; -+ } -+ -+ return false; -+} -+ -+void mptcp_tcp_set_rto(struct sock *sk) -+{ -+ tcp_set_rto(sk); -+ mptcp_set_rto(sk); -+} -diff -aurN linux-4.19.104/net/mptcp/mptcp_ipv4.c mptcp-mptcp_v0.95/net/mptcp/mptcp_ipv4.c ---- linux-4.19.104/net/mptcp/mptcp_ipv4.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_v0.95/net/mptcp/mptcp_ipv4.c 2020-02-17 11:29:55.000000000 +0100 -@@ -0,0 +1,427 @@ -+/* -+ * MPTCP implementation - IPv4-specific functions -+ * -+ * Initial Design & Implementation: -+ * Sébastien Barré -+ * -+ * Current Maintainer: -+ * Christoph Paasch -+ * -+ * Additional authors: -+ * Jaakko Korkeaniemi -+ * Gregory Detal -+ * Fabien Duchêne -+ * Andreas Seelinger -+ * Lavkesh Lahngir -+ * Andreas Ripke -+ * Vlad Dogaru -+ * Octavian Purdila -+ * John Ronan -+ * Catalin Nicutar -+ * Brandon Heller -+ * -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version -+ * 2 of the License, or (at your option) any later version. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+u32 mptcp_v4_get_nonce(__be32 saddr, __be32 daddr, __be16 sport, __be16 dport) -+{ -+ return siphash_4u32((__force u32)saddr, (__force u32)daddr, -+ (__force u32)sport << 16 | (__force u32)dport, -+ mptcp_seed++, &mptcp_secret); -+} -+ -+u64 mptcp_v4_get_key(__be32 saddr, __be32 daddr, __be16 sport, __be16 dport, -+ u32 seed) -+{ -+ return siphash_2u64((__force u64)saddr << 32 | (__force u64)daddr, -+ (__force u64)seed << 32 | (__force u64)sport << 16 | (__force u64)dport, -+ &mptcp_secret); -+} -+ -+ -+static void mptcp_v4_reqsk_destructor(struct request_sock *req) -+{ -+ mptcp_reqsk_destructor(req); -+ -+ tcp_v4_reqsk_destructor(req); -+} -+ -+static int mptcp_v4_init_req(struct request_sock *req, const struct sock *sk, -+ struct sk_buff *skb, bool want_cookie) -+{ -+ tcp_request_sock_ipv4_ops.init_req(req, sk, skb, want_cookie); -+ -+ mptcp_rsk(req)->hash_entry.pprev = NULL; -+ mptcp_rsk(req)->is_sub = 0; -+ inet_rsk(req)->mptcp_rqsk = 1; -+ -+ /* In case of SYN-cookies, we wait for the isn to be generated - it is -+ * input to the key-generation. -+ */ -+ if (!want_cookie) -+ mptcp_reqsk_init(req, sk, skb, false); -+ -+ return 0; -+} -+ -+#ifdef CONFIG_SYN_COOKIES -+static u32 mptcp_v4_cookie_init_seq(struct request_sock *req, const struct sock *sk, -+ const struct sk_buff *skb, __u16 *mssp) -+{ -+ __u32 isn = cookie_v4_init_sequence(req, sk, skb, mssp); -+ -+ tcp_rsk(req)->snt_isn = isn; -+ -+ mptcp_reqsk_init(req, sk, skb, true); -+ -+ return isn; -+} -+#endif -+ -+/* May be called without holding the meta-level lock */ -+static int mptcp_v4_join_init_req(struct request_sock *req, const struct sock *meta_sk, -+ struct sk_buff *skb, bool want_cookie) -+{ -+ struct mptcp_request_sock *mtreq = mptcp_rsk(req); -+ const struct mptcp_cb *mpcb = tcp_sk(meta_sk)->mpcb; -+ union inet_addr addr; -+ int loc_id; -+ bool low_prio = false; -+ -+ /* We need to do this as early as possible. Because, if we fail later -+ * (e.g., get_local_id), then reqsk_free tries to remove the -+ * request-socket from the htb in mptcp_hash_request_remove as pprev -+ * may be different from NULL. -+ */ -+ mtreq->hash_entry.pprev = NULL; -+ -+ tcp_request_sock_ipv4_ops.init_req(req, meta_sk, skb, want_cookie); -+ -+ mtreq->mptcp_loc_nonce = mptcp_v4_get_nonce(ip_hdr(skb)->saddr, -+ ip_hdr(skb)->daddr, -+ tcp_hdr(skb)->source, -+ tcp_hdr(skb)->dest); -+ addr.ip = inet_rsk(req)->ir_loc_addr; -+ loc_id = mpcb->pm_ops->get_local_id(meta_sk, AF_INET, &addr, &low_prio); -+ if (loc_id == -1) -+ return -1; -+ mtreq->loc_id = loc_id; -+ mtreq->low_prio = low_prio; -+ -+ mptcp_join_reqsk_init(mpcb, req, skb); -+ -+ return 0; -+} -+ -+/* Similar to tcp_request_sock_ops */ -+struct request_sock_ops mptcp_request_sock_ops __read_mostly = { -+ .family = PF_INET, -+ .obj_size = sizeof(struct mptcp_request_sock), -+ .rtx_syn_ack = tcp_rtx_synack, -+ .send_ack = tcp_v4_reqsk_send_ack, -+ .destructor = mptcp_v4_reqsk_destructor, -+ .send_reset = tcp_v4_send_reset, -+ .syn_ack_timeout = tcp_syn_ack_timeout, -+}; -+ -+/* Similar to: tcp_v4_conn_request -+ * May be called without holding the meta-level lock -+ */ -+static int mptcp_v4_join_request(struct sock *meta_sk, struct sk_buff *skb) -+{ -+ return tcp_conn_request(&mptcp_request_sock_ops, -+ &mptcp_join_request_sock_ipv4_ops, -+ meta_sk, skb); -+} -+ -+/* Similar to: tcp_v4_do_rcv -+ * We only process join requests here. (either the SYN or the final ACK) -+ */ -+int mptcp_v4_do_rcv(struct sock *meta_sk, struct sk_buff *skb) -+{ -+ const struct tcphdr *th = tcp_hdr(skb); -+ const struct iphdr *iph = ip_hdr(skb); -+ struct sock *child, *rsk = NULL, *sk; -+ int ret; -+ -+ sk = inet_lookup_established(sock_net(meta_sk), &tcp_hashinfo, -+ iph->saddr, th->source, iph->daddr, -+ th->dest, inet_iif(skb)); -+ -+ if (!sk) -+ goto new_subflow; -+ -+ if (is_meta_sk(sk)) { -+ WARN("%s Did not find a sub-sk - did found the meta!\n", __func__); -+ sock_put(sk); -+ goto discard; -+ } -+ -+ if (sk->sk_state == TCP_TIME_WAIT) { -+ inet_twsk_put(inet_twsk(sk)); -+ goto discard; -+ } -+ -+ if (sk->sk_state == TCP_NEW_SYN_RECV) { -+ struct request_sock *req = inet_reqsk(sk); -+ bool req_stolen; -+ -+ if (!mptcp_can_new_subflow(meta_sk)) -+ goto reset_and_discard; -+ -+ local_bh_disable(); -+ child = tcp_check_req(meta_sk, skb, req, false, &req_stolen); -+ if (!child) { -+ reqsk_put(req); -+ local_bh_enable(); -+ goto discard; -+ } -+ -+ if (child != meta_sk) { -+ ret = mptcp_finish_handshake(child, skb); -+ if (ret) { -+ rsk = child; -+ local_bh_enable(); -+ goto reset_and_discard; -+ } -+ -+ local_bh_enable(); -+ return 0; -+ } -+ -+ /* tcp_check_req failed */ -+ reqsk_put(req); -+ -+ local_bh_enable(); -+ goto discard; -+ } -+ -+ ret = tcp_v4_do_rcv(sk, skb); -+ sock_put(sk); -+ -+ return ret; -+ -+new_subflow: -+ if (!mptcp_can_new_subflow(meta_sk)) -+ goto reset_and_discard; -+ -+ child = tcp_v4_cookie_check(meta_sk, skb); -+ if (!child) -+ goto discard; -+ -+ if (child != meta_sk) { -+ ret = mptcp_finish_handshake(child, skb); -+ if (ret) { -+ rsk = child; -+ goto reset_and_discard; -+ } -+ } -+ -+ if (tcp_hdr(skb)->syn) { -+ local_bh_disable(); -+ mptcp_v4_join_request(meta_sk, skb); -+ local_bh_enable(); -+ } -+ -+discard: -+ kfree_skb(skb); -+ return 0; -+ -+reset_and_discard: -+ tcp_v4_send_reset(rsk, skb); -+ goto discard; -+} -+ -+/* Create a new IPv4 subflow. -+ * -+ * We are in user-context and meta-sock-lock is hold. -+ */ -+int __mptcp_init4_subsockets(struct sock *meta_sk, const struct mptcp_loc4 *loc, -+ __be16 sport, struct mptcp_rem4 *rem, -+ struct sock **subsk) -+{ -+ struct tcp_sock *tp; -+ struct sock *sk; -+ struct sockaddr_in loc_in, rem_in; -+ struct socket_alloc sock_full; -+ struct socket *sock = (struct socket *)&sock_full; -+ int ret; -+ -+ /** First, create and prepare the new socket */ -+ memcpy(&sock_full, meta_sk->sk_socket, sizeof(sock_full)); -+ sock->state = SS_UNCONNECTED; -+ sock->ops = NULL; -+ -+ ret = inet_create(sock_net(meta_sk), sock, IPPROTO_TCP, 1); -+ if (unlikely(ret < 0)) { -+ net_err_ratelimited("%s inet_create failed ret: %d\n", -+ __func__, ret); -+ return ret; -+ } -+ -+ sk = sock->sk; -+ tp = tcp_sk(sk); -+ -+ /* All subsockets need the MPTCP-lock-class */ -+ lockdep_set_class_and_name(&(sk)->sk_lock.slock, &meta_slock_key, meta_slock_key_name); -+ lockdep_init_map(&(sk)->sk_lock.dep_map, meta_key_name, &meta_key, 0); -+ -+ ret = mptcp_add_sock(meta_sk, sk, loc->loc4_id, rem->rem4_id, GFP_KERNEL); -+ if (ret) { -+ net_err_ratelimited("%s mptcp_add_sock failed ret: %d\n", -+ __func__, ret); -+ goto error; -+ } -+ -+ tp->mptcp->slave_sk = 1; -+ tp->mptcp->low_prio = loc->low_prio; -+ -+ /* Initializing the timer for an MPTCP subflow */ -+ timer_setup(&tp->mptcp->mptcp_ack_timer, mptcp_ack_handler, 0); -+ -+ /** Then, connect the socket to the peer */ -+ loc_in.sin_family = AF_INET; -+ rem_in.sin_family = AF_INET; -+ loc_in.sin_port = sport; -+ if (rem->port) -+ rem_in.sin_port = rem->port; -+ else -+ rem_in.sin_port = inet_sk(meta_sk)->inet_dport; -+ loc_in.sin_addr = loc->addr; -+ rem_in.sin_addr = rem->addr; -+ -+ if (loc->if_idx) -+ sk->sk_bound_dev_if = loc->if_idx; -+ -+ ret = kernel_bind(sock, (struct sockaddr *)&loc_in, -+ sizeof(struct sockaddr_in)); -+ if (ret < 0) { -+ net_err_ratelimited("%s: token %#x bind() to %pI4 index %d failed, error %d\n", -+ __func__, tcp_sk(meta_sk)->mpcb->mptcp_loc_token, -+ &loc_in.sin_addr, loc->if_idx, ret); -+ goto error; -+ } -+ -+ mptcp_debug("%s: token %#x pi %d src_addr:%pI4:%d dst_addr:%pI4:%d ifidx: %d\n", -+ __func__, tcp_sk(meta_sk)->mpcb->mptcp_loc_token, -+ tp->mptcp->path_index, &loc_in.sin_addr, -+ ntohs(loc_in.sin_port), &rem_in.sin_addr, -+ ntohs(rem_in.sin_port), loc->if_idx); -+ -+ if (tcp_sk(meta_sk)->mpcb->pm_ops->init_subsocket_v4) -+ tcp_sk(meta_sk)->mpcb->pm_ops->init_subsocket_v4(sk, rem->addr); -+ -+ ret = kernel_connect(sock, (struct sockaddr *)&rem_in, -+ sizeof(struct sockaddr_in), O_NONBLOCK); -+ if (ret < 0 && ret != -EINPROGRESS) { -+ net_err_ratelimited("%s: MPTCP subsocket connect() failed, error %d\n", -+ __func__, ret); -+ goto error; -+ } -+ -+ MPTCP_INC_STATS(sock_net(meta_sk), MPTCP_MIB_JOINSYNTX); -+ -+ sk_set_socket(sk, meta_sk->sk_socket); -+ sk->sk_wq = meta_sk->sk_wq; -+ -+ if (subsk) -+ *subsk = sk; -+ -+ return 0; -+ -+error: -+ /* May happen if mptcp_add_sock fails first */ -+ if (!mptcp(tp)) { -+ tcp_close(sk, 0); -+ } else { -+ local_bh_disable(); -+ mptcp_sub_force_close(sk); -+ local_bh_enable(); -+ } -+ return ret; -+} -+EXPORT_SYMBOL(__mptcp_init4_subsockets); -+ -+const struct inet_connection_sock_af_ops mptcp_v4_specific = { -+ .queue_xmit = ip_queue_xmit, -+ .send_check = tcp_v4_send_check, -+ .rebuild_header = inet_sk_rebuild_header, -+ .sk_rx_dst_set = inet_sk_rx_dst_set, -+ .conn_request = mptcp_conn_request, -+ .syn_recv_sock = tcp_v4_syn_recv_sock, -+ .net_header_len = sizeof(struct iphdr), -+ .setsockopt = ip_setsockopt, -+ .getsockopt = ip_getsockopt, -+ .addr2sockaddr = inet_csk_addr2sockaddr, -+ .sockaddr_len = sizeof(struct sockaddr_in), -+#ifdef CONFIG_COMPAT -+ .compat_setsockopt = compat_ip_setsockopt, -+ .compat_getsockopt = compat_ip_getsockopt, -+#endif -+ .mtu_reduced = tcp_v4_mtu_reduced, -+}; -+ -+struct tcp_request_sock_ops mptcp_request_sock_ipv4_ops; -+struct tcp_request_sock_ops mptcp_join_request_sock_ipv4_ops; -+ -+/* General initialization of IPv4 for MPTCP */ -+int mptcp_pm_v4_init(void) -+{ -+ int ret = 0; -+ struct request_sock_ops *ops = &mptcp_request_sock_ops; -+ -+ mptcp_request_sock_ipv4_ops = tcp_request_sock_ipv4_ops; -+ mptcp_request_sock_ipv4_ops.init_req = mptcp_v4_init_req; -+#ifdef CONFIG_SYN_COOKIES -+ mptcp_request_sock_ipv4_ops.cookie_init_seq = mptcp_v4_cookie_init_seq; -+#endif -+ mptcp_join_request_sock_ipv4_ops = tcp_request_sock_ipv4_ops; -+ mptcp_join_request_sock_ipv4_ops.init_req = mptcp_v4_join_init_req; -+ -+ ops->slab_name = kasprintf(GFP_KERNEL, "request_sock_%s", "MPTCP"); -+ if (ops->slab_name == NULL) { -+ ret = -ENOMEM; -+ goto out; -+ } -+ -+ ops->slab = kmem_cache_create(ops->slab_name, ops->obj_size, 0, -+ SLAB_TYPESAFE_BY_RCU|SLAB_HWCACHE_ALIGN, -+ NULL); -+ -+ if (ops->slab == NULL) { -+ ret = -ENOMEM; -+ goto err_reqsk_create; -+ } -+ -+out: -+ return ret; -+ -+err_reqsk_create: -+ kfree(ops->slab_name); -+ ops->slab_name = NULL; -+ goto out; -+} -+ -+void mptcp_pm_v4_undo(void) -+{ -+ kmem_cache_destroy(mptcp_request_sock_ops.slab); -+ kfree(mptcp_request_sock_ops.slab_name); -+} -diff -aurN linux-4.19.104/net/mptcp/mptcp_ipv6.c mptcp-mptcp_v0.95/net/mptcp/mptcp_ipv6.c ---- linux-4.19.104/net/mptcp/mptcp_ipv6.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_v0.95/net/mptcp/mptcp_ipv6.c 2020-02-17 11:29:55.000000000 +0100 -@@ -0,0 +1,475 @@ -+/* -+ * MPTCP implementation - IPv6-specific functions -+ * -+ * Initial Design & Implementation: -+ * Sébastien Barré -+ * -+ * Current Maintainer: -+ * Jaakko Korkeaniemi -+ * -+ * Additional authors: -+ * Jaakko Korkeaniemi -+ * Gregory Detal -+ * Fabien Duchêne -+ * Andreas Seelinger -+ * Lavkesh Lahngir -+ * Andreas Ripke -+ * Vlad Dogaru -+ * Octavian Purdila -+ * John Ronan -+ * Catalin Nicutar -+ * Brandon Heller -+ * -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version -+ * 2 of the License, or (at your option) any later version. -+ */ -+ -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+__u32 mptcp_v6_get_nonce(const __be32 *saddr, const __be32 *daddr, -+ __be16 sport, __be16 dport) -+{ -+ const struct { -+ struct in6_addr saddr; -+ struct in6_addr daddr; -+ u32 seed; -+ __be16 sport; -+ __be16 dport; -+ } __aligned(SIPHASH_ALIGNMENT) combined = { -+ .saddr = *(struct in6_addr *)saddr, -+ .daddr = *(struct in6_addr *)daddr, -+ .seed = mptcp_seed++, -+ .sport = sport, -+ .dport = dport -+ }; -+ -+ return siphash(&combined, offsetofend(typeof(combined), dport), -+ &mptcp_secret); -+} -+ -+u64 mptcp_v6_get_key(const __be32 *saddr, const __be32 *daddr, -+ __be16 sport, __be16 dport, u32 seed) -+{ -+ const struct { -+ struct in6_addr saddr; -+ struct in6_addr daddr; -+ u32 seed; -+ __be16 sport; -+ __be16 dport; -+ } __aligned(SIPHASH_ALIGNMENT) combined = { -+ .saddr = *(struct in6_addr *)saddr, -+ .daddr = *(struct in6_addr *)daddr, -+ .seed = seed, -+ .sport = sport, -+ .dport = dport -+ }; -+ -+ return siphash(&combined, offsetofend(typeof(combined), dport), -+ &mptcp_secret); -+} -+ -+static void mptcp_v6_reqsk_destructor(struct request_sock *req) -+{ -+ mptcp_reqsk_destructor(req); -+ -+ tcp_v6_reqsk_destructor(req); -+} -+ -+static int mptcp_v6_init_req(struct request_sock *req, const struct sock *sk, -+ struct sk_buff *skb, bool want_cookie) -+{ -+ tcp_request_sock_ipv6_ops.init_req(req, sk, skb, want_cookie); -+ -+ mptcp_rsk(req)->hash_entry.pprev = NULL; -+ mptcp_rsk(req)->is_sub = 0; -+ inet_rsk(req)->mptcp_rqsk = 1; -+ -+ /* In case of SYN-cookies, we wait for the isn to be generated - it is -+ * input to the key-generation. -+ */ -+ if (!want_cookie) -+ mptcp_reqsk_init(req, sk, skb, false); -+ -+ return 0; -+} -+ -+#ifdef CONFIG_SYN_COOKIES -+static u32 mptcp_v6_cookie_init_seq(struct request_sock *req, const struct sock *sk, -+ const struct sk_buff *skb, __u16 *mssp) -+{ -+ __u32 isn = cookie_v6_init_sequence(req, sk, skb, mssp); -+ -+ tcp_rsk(req)->snt_isn = isn; -+ -+ mptcp_reqsk_init(req, sk, skb, true); -+ -+ return isn; -+} -+#endif -+ -+/* May be called without holding the meta-level lock */ -+static int mptcp_v6_join_init_req(struct request_sock *req, const struct sock *meta_sk, -+ struct sk_buff *skb, bool want_cookie) -+{ -+ struct mptcp_request_sock *mtreq = mptcp_rsk(req); -+ const struct mptcp_cb *mpcb = tcp_sk(meta_sk)->mpcb; -+ union inet_addr addr; -+ int loc_id; -+ bool low_prio = false; -+ -+ /* We need to do this as early as possible. Because, if we fail later -+ * (e.g., get_local_id), then reqsk_free tries to remove the -+ * request-socket from the htb in mptcp_hash_request_remove as pprev -+ * may be different from NULL. -+ */ -+ mtreq->hash_entry.pprev = NULL; -+ -+ tcp_request_sock_ipv6_ops.init_req(req, meta_sk, skb, want_cookie); -+ -+ mtreq->mptcp_loc_nonce = mptcp_v6_get_nonce(ipv6_hdr(skb)->saddr.s6_addr32, -+ ipv6_hdr(skb)->daddr.s6_addr32, -+ tcp_hdr(skb)->source, -+ tcp_hdr(skb)->dest); -+ addr.in6 = inet_rsk(req)->ir_v6_loc_addr; -+ loc_id = mpcb->pm_ops->get_local_id(meta_sk, AF_INET6, &addr, &low_prio); -+ if (loc_id == -1) -+ return -1; -+ mtreq->loc_id = loc_id; -+ mtreq->low_prio = low_prio; -+ -+ mptcp_join_reqsk_init(mpcb, req, skb); -+ -+ return 0; -+} -+ -+/* Similar to tcp6_request_sock_ops */ -+struct request_sock_ops mptcp6_request_sock_ops __read_mostly = { -+ .family = AF_INET6, -+ .obj_size = sizeof(struct mptcp_request_sock), -+ .rtx_syn_ack = tcp_rtx_synack, -+ .send_ack = tcp_v6_reqsk_send_ack, -+ .destructor = mptcp_v6_reqsk_destructor, -+ .send_reset = tcp_v6_send_reset, -+ .syn_ack_timeout = tcp_syn_ack_timeout, -+}; -+ -+/* Similar to: tcp_v6_conn_request -+ * May be called without holding the meta-level lock -+ */ -+static int mptcp_v6_join_request(struct sock *meta_sk, struct sk_buff *skb) -+{ -+ return tcp_conn_request(&mptcp6_request_sock_ops, -+ &mptcp_join_request_sock_ipv6_ops, -+ meta_sk, skb); -+} -+ -+int mptcp_v6_do_rcv(struct sock *meta_sk, struct sk_buff *skb) -+{ -+ const struct tcphdr *th = tcp_hdr(skb); -+ const struct ipv6hdr *ip6h = ipv6_hdr(skb); -+ struct sock *child, *rsk = NULL, *sk; -+ int ret; -+ -+ sk = __inet6_lookup_established(sock_net(meta_sk), -+ &tcp_hashinfo, -+ &ip6h->saddr, th->source, -+ &ip6h->daddr, ntohs(th->dest), -+ tcp_v6_iif(skb), tcp_v6_sdif(skb)); -+ -+ if (!sk) -+ goto new_subflow; -+ -+ if (is_meta_sk(sk)) { -+ WARN("%s Did not find a sub-sk - did found the meta!\n", __func__); -+ sock_put(sk); -+ goto discard; -+ } -+ -+ if (sk->sk_state == TCP_TIME_WAIT) { -+ inet_twsk_put(inet_twsk(sk)); -+ goto discard; -+ } -+ -+ if (sk->sk_state == TCP_NEW_SYN_RECV) { -+ struct request_sock *req = inet_reqsk(sk); -+ bool req_stolen; -+ -+ if (!mptcp_can_new_subflow(meta_sk)) -+ goto reset_and_discard; -+ -+ local_bh_disable(); -+ child = tcp_check_req(meta_sk, skb, req, false, &req_stolen); -+ if (!child) { -+ reqsk_put(req); -+ local_bh_enable(); -+ goto discard; -+ } -+ -+ if (child != meta_sk) { -+ ret = mptcp_finish_handshake(child, skb); -+ if (ret) { -+ rsk = child; -+ local_bh_enable(); -+ goto reset_and_discard; -+ } -+ -+ local_bh_enable(); -+ return 0; -+ } -+ -+ /* tcp_check_req failed */ -+ reqsk_put(req); -+ -+ local_bh_enable(); -+ goto discard; -+ } -+ -+ ret = tcp_v6_do_rcv(sk, skb); -+ sock_put(sk); -+ -+ return ret; -+ -+new_subflow: -+ if (!mptcp_can_new_subflow(meta_sk)) -+ goto reset_and_discard; -+ -+ child = tcp_v6_cookie_check(meta_sk, skb); -+ if (!child) -+ goto discard; -+ -+ if (child != meta_sk) { -+ ret = mptcp_finish_handshake(child, skb); -+ if (ret) { -+ rsk = child; -+ goto reset_and_discard; -+ } -+ } -+ -+ if (tcp_hdr(skb)->syn) { -+ local_bh_disable(); -+ mptcp_v6_join_request(meta_sk, skb); -+ local_bh_enable(); -+ } -+ -+discard: -+ kfree_skb(skb); -+ return 0; -+ -+reset_and_discard: -+ tcp_v6_send_reset(rsk, skb); -+ goto discard; -+} -+ -+/* Create a new IPv6 subflow. -+ * -+ * We are in user-context and meta-sock-lock is hold. -+ */ -+int __mptcp_init6_subsockets(struct sock *meta_sk, const struct mptcp_loc6 *loc, -+ __be16 sport, struct mptcp_rem6 *rem, -+ struct sock **subsk) -+{ -+ struct tcp_sock *tp; -+ struct sock *sk; -+ struct sockaddr_in6 loc_in, rem_in; -+ struct socket_alloc sock_full; -+ struct socket *sock = (struct socket *)&sock_full; -+ int ret; -+ -+ /** First, create and prepare the new socket */ -+ memcpy(&sock_full, meta_sk->sk_socket, sizeof(sock_full)); -+ sock->state = SS_UNCONNECTED; -+ sock->ops = NULL; -+ -+ ret = inet6_create(sock_net(meta_sk), sock, IPPROTO_TCP, 1); -+ if (unlikely(ret < 0)) { -+ net_err_ratelimited("%s inet6_create failed ret: %d\n", -+ __func__, ret); -+ return ret; -+ } -+ -+ sk = sock->sk; -+ tp = tcp_sk(sk); -+ -+ /* All subsockets need the MPTCP-lock-class */ -+ lockdep_set_class_and_name(&(sk)->sk_lock.slock, &meta_slock_key, meta_slock_key_name); -+ lockdep_init_map(&(sk)->sk_lock.dep_map, meta_key_name, &meta_key, 0); -+ -+ ret = mptcp_add_sock(meta_sk, sk, loc->loc6_id, rem->rem6_id, GFP_KERNEL); -+ if (ret) { -+ net_err_ratelimited("%s mptcp_add_sock failed ret: %d\n", -+ __func__, ret); -+ goto error; -+ } -+ -+ tp->mptcp->slave_sk = 1; -+ tp->mptcp->low_prio = loc->low_prio; -+ -+ /* Initializing the timer for an MPTCP subflow */ -+ timer_setup(&tp->mptcp->mptcp_ack_timer, mptcp_ack_handler, 0); -+ -+ /** Then, connect the socket to the peer */ -+ loc_in.sin6_family = AF_INET6; -+ rem_in.sin6_family = AF_INET6; -+ loc_in.sin6_port = sport; -+ if (rem->port) -+ rem_in.sin6_port = rem->port; -+ else -+ rem_in.sin6_port = inet_sk(meta_sk)->inet_dport; -+ loc_in.sin6_addr = loc->addr; -+ rem_in.sin6_addr = rem->addr; -+ -+ if (loc->if_idx) -+ sk->sk_bound_dev_if = loc->if_idx; -+ -+ ret = kernel_bind(sock, (struct sockaddr *)&loc_in, -+ sizeof(struct sockaddr_in6)); -+ if (ret < 0) { -+ net_err_ratelimited("%s: token %#x bind() to %pI6 index %d failed, error %d\n", -+ __func__, tcp_sk(meta_sk)->mpcb->mptcp_loc_token, -+ &loc_in.sin6_addr, loc->if_idx, ret); -+ goto error; -+ } -+ -+ mptcp_debug("%s: token %#x pi %d src_addr:%pI6:%d dst_addr:%pI6:%d ifidx: %u\n", -+ __func__, tcp_sk(meta_sk)->mpcb->mptcp_loc_token, -+ tp->mptcp->path_index, &loc_in.sin6_addr, -+ ntohs(loc_in.sin6_port), &rem_in.sin6_addr, -+ ntohs(rem_in.sin6_port), loc->if_idx); -+ -+ if (tcp_sk(meta_sk)->mpcb->pm_ops->init_subsocket_v6) -+ tcp_sk(meta_sk)->mpcb->pm_ops->init_subsocket_v6(sk, rem->addr); -+ -+ ret = kernel_connect(sock, (struct sockaddr *)&rem_in, -+ sizeof(struct sockaddr_in6), O_NONBLOCK); -+ if (ret < 0 && ret != -EINPROGRESS) { -+ net_err_ratelimited("%s: MPTCP subsocket connect() failed, error %d\n", -+ __func__, ret); -+ goto error; -+ } -+ -+ MPTCP_INC_STATS(sock_net(meta_sk), MPTCP_MIB_JOINSYNTX); -+ -+ sk_set_socket(sk, meta_sk->sk_socket); -+ sk->sk_wq = meta_sk->sk_wq; -+ -+ if (subsk) -+ *subsk = sk; -+ -+ return 0; -+ -+error: -+ /* May happen if mptcp_add_sock fails first */ -+ if (!mptcp(tp)) { -+ tcp_close(sk, 0); -+ } else { -+ local_bh_disable(); -+ mptcp_sub_force_close(sk); -+ local_bh_enable(); -+ } -+ return ret; -+} -+EXPORT_SYMBOL(__mptcp_init6_subsockets); -+ -+const struct inet_connection_sock_af_ops mptcp_v6_specific = { -+ .queue_xmit = inet6_csk_xmit, -+ .send_check = tcp_v6_send_check, -+ .rebuild_header = inet6_sk_rebuild_header, -+ .sk_rx_dst_set = inet6_sk_rx_dst_set, -+ .conn_request = mptcp_conn_request, -+ .syn_recv_sock = tcp_v6_syn_recv_sock, -+ .net_header_len = sizeof(struct ipv6hdr), -+ .net_frag_header_len = sizeof(struct frag_hdr), -+ .setsockopt = ipv6_setsockopt, -+ .getsockopt = ipv6_getsockopt, -+ .addr2sockaddr = inet6_csk_addr2sockaddr, -+ .sockaddr_len = sizeof(struct sockaddr_in6), -+#ifdef CONFIG_COMPAT -+ .compat_setsockopt = compat_ipv6_setsockopt, -+ .compat_getsockopt = compat_ipv6_getsockopt, -+#endif -+ .mtu_reduced = tcp_v6_mtu_reduced, -+}; -+ -+const struct inet_connection_sock_af_ops mptcp_v6_mapped = { -+ .queue_xmit = ip_queue_xmit, -+ .send_check = tcp_v4_send_check, -+ .rebuild_header = inet_sk_rebuild_header, -+ .sk_rx_dst_set = inet_sk_rx_dst_set, -+ .conn_request = mptcp_conn_request, -+ .syn_recv_sock = tcp_v6_syn_recv_sock, -+ .net_header_len = sizeof(struct iphdr), -+ .setsockopt = ipv6_setsockopt, -+ .getsockopt = ipv6_getsockopt, -+ .addr2sockaddr = inet6_csk_addr2sockaddr, -+ .sockaddr_len = sizeof(struct sockaddr_in6), -+#ifdef CONFIG_COMPAT -+ .compat_setsockopt = compat_ipv6_setsockopt, -+ .compat_getsockopt = compat_ipv6_getsockopt, -+#endif -+ .mtu_reduced = tcp_v4_mtu_reduced, -+}; -+ -+struct tcp_request_sock_ops mptcp_request_sock_ipv6_ops; -+struct tcp_request_sock_ops mptcp_join_request_sock_ipv6_ops; -+ -+int mptcp_pm_v6_init(void) -+{ -+ int ret = 0; -+ struct request_sock_ops *ops = &mptcp6_request_sock_ops; -+ -+ mptcp_request_sock_ipv6_ops = tcp_request_sock_ipv6_ops; -+ mptcp_request_sock_ipv6_ops.init_req = mptcp_v6_init_req; -+#ifdef CONFIG_SYN_COOKIES -+ mptcp_request_sock_ipv6_ops.cookie_init_seq = mptcp_v6_cookie_init_seq; -+#endif -+ -+ mptcp_join_request_sock_ipv6_ops = tcp_request_sock_ipv6_ops; -+ mptcp_join_request_sock_ipv6_ops.init_req = mptcp_v6_join_init_req; -+ -+ ops->slab_name = kasprintf(GFP_KERNEL, "request_sock_%s", "MPTCP6"); -+ if (ops->slab_name == NULL) { -+ ret = -ENOMEM; -+ goto out; -+ } -+ -+ ops->slab = kmem_cache_create(ops->slab_name, ops->obj_size, 0, -+ SLAB_TYPESAFE_BY_RCU|SLAB_HWCACHE_ALIGN, -+ NULL); -+ -+ if (ops->slab == NULL) { -+ ret = -ENOMEM; -+ goto err_reqsk_create; -+ } -+ -+out: -+ return ret; -+ -+err_reqsk_create: -+ kfree(ops->slab_name); -+ ops->slab_name = NULL; -+ goto out; -+} -+ -+void mptcp_pm_v6_undo(void) -+{ -+ kmem_cache_destroy(mptcp6_request_sock_ops.slab); -+ kfree(mptcp6_request_sock_ops.slab_name); -+} -diff -aurN linux-4.19.104/net/mptcp/mptcp_ndiffports.c mptcp-mptcp_v0.95/net/mptcp/mptcp_ndiffports.c ---- linux-4.19.104/net/mptcp/mptcp_ndiffports.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_v0.95/net/mptcp/mptcp_ndiffports.c 2020-02-17 11:29:55.000000000 +0100 -@@ -0,0 +1,174 @@ -+#include -+ -+#include -+#include -+ -+#if IS_ENABLED(CONFIG_IPV6) -+#include -+#endif -+ -+struct ndiffports_priv { -+ /* Worker struct for subflow establishment */ -+ struct work_struct subflow_work; -+ -+ struct mptcp_cb *mpcb; -+}; -+ -+static int num_subflows __read_mostly = 2; -+module_param(num_subflows, int, 0644); -+MODULE_PARM_DESC(num_subflows, "choose the number of subflows per MPTCP connection"); -+ -+/** -+ * Create all new subflows, by doing calls to mptcp_initX_subsockets -+ * -+ * This function uses a goto next_subflow, to allow releasing the lock between -+ * new subflows and giving other processes a chance to do some work on the -+ * socket and potentially finishing the communication. -+ **/ -+static void create_subflow_worker(struct work_struct *work) -+{ -+ const struct ndiffports_priv *pm_priv = container_of(work, -+ struct ndiffports_priv, -+ subflow_work); -+ struct mptcp_cb *mpcb = pm_priv->mpcb; -+ struct sock *meta_sk = mpcb->meta_sk; -+ int iter = 0; -+ -+next_subflow: -+ if (iter) { -+ release_sock(meta_sk); -+ mutex_unlock(&mpcb->mpcb_mutex); -+ -+ cond_resched(); -+ } -+ mutex_lock(&mpcb->mpcb_mutex); -+ lock_sock_nested(meta_sk, SINGLE_DEPTH_NESTING); -+ -+ if (!mptcp(tcp_sk(meta_sk))) -+ goto exit; -+ -+ iter++; -+ -+ if (sock_flag(meta_sk, SOCK_DEAD)) -+ goto exit; -+ -+ if (mpcb->master_sk && -+ !tcp_sk(mpcb->master_sk)->mptcp->fully_established) -+ goto exit; -+ -+ if (num_subflows > iter && num_subflows > mptcp_subflow_count(mpcb)) { -+ if (meta_sk->sk_family == AF_INET || -+ mptcp_v6_is_v4_mapped(meta_sk)) { -+ struct mptcp_loc4 loc; -+ struct mptcp_rem4 rem; -+ -+ loc.addr.s_addr = inet_sk(meta_sk)->inet_saddr; -+ loc.loc4_id = 0; -+ loc.low_prio = 0; -+ if (mpcb->master_sk) -+ loc.if_idx = mpcb->master_sk->sk_bound_dev_if; -+ else -+ loc.if_idx = 0; -+ -+ rem.addr.s_addr = inet_sk(meta_sk)->inet_daddr; -+ rem.port = inet_sk(meta_sk)->inet_dport; -+ rem.rem4_id = 0; /* Default 0 */ -+ -+ mptcp_init4_subsockets(meta_sk, &loc, &rem); -+ } else { -+#if IS_ENABLED(CONFIG_IPV6) -+ struct mptcp_loc6 loc; -+ struct mptcp_rem6 rem; -+ -+ loc.addr = inet6_sk(meta_sk)->saddr; -+ loc.loc6_id = 0; -+ loc.low_prio = 0; -+ if (mpcb->master_sk) -+ loc.if_idx = mpcb->master_sk->sk_bound_dev_if; -+ else -+ loc.if_idx = 0; -+ -+ rem.addr = meta_sk->sk_v6_daddr; -+ rem.port = inet_sk(meta_sk)->inet_dport; -+ rem.rem6_id = 0; /* Default 0 */ -+ -+ mptcp_init6_subsockets(meta_sk, &loc, &rem); -+#endif -+ } -+ goto next_subflow; -+ } -+ -+exit: -+ release_sock(meta_sk); -+ mutex_unlock(&mpcb->mpcb_mutex); -+ mptcp_mpcb_put(mpcb); -+ sock_put(meta_sk); -+} -+ -+static void ndiffports_new_session(const struct sock *meta_sk) -+{ -+ struct mptcp_cb *mpcb = tcp_sk(meta_sk)->mpcb; -+ struct ndiffports_priv *fmp = (struct ndiffports_priv *)&mpcb->mptcp_pm[0]; -+ -+ /* Initialize workqueue-struct */ -+ INIT_WORK(&fmp->subflow_work, create_subflow_worker); -+ fmp->mpcb = mpcb; -+} -+ -+static void ndiffports_create_subflows(struct sock *meta_sk) -+{ -+ struct mptcp_cb *mpcb = tcp_sk(meta_sk)->mpcb; -+ struct ndiffports_priv *pm_priv = (struct ndiffports_priv *)&mpcb->mptcp_pm[0]; -+ -+ if (mptcp_in_infinite_mapping_weak(mpcb) || -+ mpcb->server_side || sock_flag(meta_sk, SOCK_DEAD)) -+ return; -+ -+ if (!work_pending(&pm_priv->subflow_work)) { -+ sock_hold(meta_sk); -+ refcount_inc(&mpcb->mpcb_refcnt); -+ queue_work(mptcp_wq, &pm_priv->subflow_work); -+ } -+} -+ -+static int ndiffports_get_local_id(const struct sock *meta_sk, -+ sa_family_t family, union inet_addr *addr, -+ bool *low_prio) -+{ -+ return 0; -+} -+ -+static struct mptcp_pm_ops ndiffports __read_mostly = { -+ .new_session = ndiffports_new_session, -+ .fully_established = ndiffports_create_subflows, -+ .get_local_id = ndiffports_get_local_id, -+ .name = "ndiffports", -+ .owner = THIS_MODULE, -+}; -+ -+/* General initialization of MPTCP_PM */ -+static int __init ndiffports_register(void) -+{ -+ BUILD_BUG_ON(sizeof(struct ndiffports_priv) > MPTCP_PM_SIZE); -+ -+ if (mptcp_register_path_manager(&ndiffports)) -+ goto exit; -+ -+ return 0; -+ -+exit: -+ return -1; -+} -+ -+static void ndiffports_unregister(void) -+{ -+ mptcp_unregister_path_manager(&ndiffports); -+} -+ -+module_init(ndiffports_register); -+module_exit(ndiffports_unregister); -+ -+MODULE_AUTHOR("Christoph Paasch"); -+MODULE_LICENSE("GPL"); -+MODULE_DESCRIPTION("NDIFF-PORTS MPTCP"); -+MODULE_VERSION("0.88"); -diff -aurN linux-4.19.104/net/mptcp/mptcp_netlink.c mptcp-mptcp_v0.95/net/mptcp/mptcp_netlink.c ---- linux-4.19.104/net/mptcp/mptcp_netlink.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_v0.95/net/mptcp/mptcp_netlink.c 2020-02-17 11:29:55.000000000 +0100 -@@ -0,0 +1,1277 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* MPTCP implementation - Netlink Path Manager -+ * -+ * Analysis, Design and Implementation: -+ * - Gregory Detal -+ * - Sébastien Barré -+ * - Matthieu Baerts -+ * - Pau Espin Pedrol -+ * - Detlev Casanova -+ * - David Verbeiren -+ * - Frank Vanbever -+ * - Antoine Maes -+ * - Tim Froidcoeur -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version -+ * 2 of the License, or (at your option) any later version. -+ */ -+ -+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt -+#include -+#include -+#include -+#include -+#include -+#if IS_ENABLED(CONFIG_IPV6) -+#include -+#endif -+ -+#define MPTCP_MAX_ADDR 8 -+ -+struct mptcp_nl_priv { -+ /* Unfortunately we need to store this to generate MP_JOINs in case -+ * of the peer generating a subflow (see get_local_id). -+ */ -+ u8 loc4_bits; -+ u8 announced4; -+ struct mptcp_loc4 locaddr4[MPTCP_MAX_ADDR]; -+ -+#if IS_ENABLED(CONFIG_IPV6) -+ u8 loc6_bits; -+ u8 announced6; -+ struct mptcp_loc6 locaddr6[MPTCP_MAX_ADDR]; -+#endif -+ -+ u16 remove_addrs; -+ -+ bool is_closed; -+}; -+ -+static struct genl_family mptcp_genl_family; -+ -+#define MPTCP_GENL_EV_GRP_OFFSET 0 -+#define MPTCP_GENL_CMD_GRP_OFFSET 1 -+ -+static const struct genl_multicast_group mptcp_mcgrps[] = { -+ [MPTCP_GENL_EV_GRP_OFFSET] = { .name = MPTCP_GENL_EV_GRP_NAME, }, -+ [MPTCP_GENL_CMD_GRP_OFFSET] = { .name = MPTCP_GENL_CMD_GRP_NAME, }, -+}; -+ -+static const struct nla_policy mptcp_nl_genl_policy[MPTCP_ATTR_MAX + 1] = { -+ [MPTCP_ATTR_TOKEN] = { .type = NLA_U32, }, -+ [MPTCP_ATTR_FAMILY] = { .type = NLA_U16, }, -+ [MPTCP_ATTR_LOC_ID] = { .type = NLA_U8, }, -+ [MPTCP_ATTR_REM_ID] = { .type = NLA_U8, }, -+ [MPTCP_ATTR_SADDR4] = { .type = NLA_U32, }, -+ [MPTCP_ATTR_SADDR6] = { .type = NLA_BINARY, -+ .len = sizeof(struct in6_addr), }, -+ [MPTCP_ATTR_DADDR4] = { .type = NLA_U32, }, -+ [MPTCP_ATTR_DADDR6] = { .type = NLA_BINARY, -+ .len = sizeof(struct in6_addr), }, -+ [MPTCP_ATTR_SPORT] = { .type = NLA_U16, }, -+ [MPTCP_ATTR_DPORT] = { .type = NLA_U16, }, -+ [MPTCP_ATTR_BACKUP] = { .type = NLA_U8, }, -+ [MPTCP_ATTR_TIMEOUT] = { .type = NLA_U32, }, -+ [MPTCP_ATTR_IF_IDX] = { .type = NLA_S32, }, -+}; -+ -+/* Defines the userspace PM filter on events. Set events are ignored. */ -+static u16 mptcp_nl_event_filter; -+ -+static inline struct mptcp_nl_priv * -+mptcp_nl_priv(const struct sock *meta_sk) -+{ -+ return (struct mptcp_nl_priv *)&tcp_sk(meta_sk)->mpcb->mptcp_pm[0]; -+} -+ -+static inline bool -+mptcp_nl_must_notify(u16 event, const struct sock *meta_sk) -+{ -+ struct mptcp_nl_priv *priv = mptcp_nl_priv(meta_sk); -+ -+ /* close_session() can be called before other events because it is -+ * also called when doing a fallback to TCP. We don't want to send -+ * events to the user-space after having sent the CLOSED event. -+ */ -+ if (priv->is_closed) -+ return false; -+ -+ if (event == MPTCPF_EVENT_CLOSED) -+ priv->is_closed = true; -+ -+ if (mptcp_nl_event_filter & event) -+ return false; -+ -+ if (!genl_has_listeners(&mptcp_genl_family, sock_net(meta_sk), 0)) -+ return false; -+ -+ return true; -+} -+ -+/* Find the first free index in the bitfield starting from 0 */ -+static int -+mptcp_nl_find_free_index(u8 bitfield) -+{ -+ int i; -+ -+ /* There are anyways no free bits... */ -+ if (bitfield == 0xff) -+ return -1; -+ -+ i = ffs(~bitfield) - 1; -+ if (i < 0) -+ return -1; -+ -+ return i; -+} -+ -+static inline int -+mptcp_nl_put_subsk(struct sk_buff *msg, struct sock *sk) -+{ -+ struct inet_sock *isk = inet_sk(sk); -+ struct sock *meta_sk = mptcp_meta_sk(sk); -+ u8 backup; -+ u8 sk_err; -+ -+ if (nla_put_u16(msg, MPTCP_ATTR_FAMILY, sk->sk_family)) -+ goto nla_put_failure; -+ -+ if (nla_put_u8(msg, MPTCP_ATTR_LOC_ID, tcp_sk(sk)->mptcp->loc_id)) -+ goto nla_put_failure; -+ -+ if (nla_put_u8(msg, MPTCP_ATTR_REM_ID, tcp_sk(sk)->mptcp->rem_id)) -+ goto nla_put_failure; -+ -+ switch (sk->sk_family) { -+ case AF_INET: -+ if (nla_put_u32(msg, MPTCP_ATTR_SADDR4, isk->inet_saddr)) -+ goto nla_put_failure; -+ -+ if (nla_put_u32(msg, MPTCP_ATTR_DADDR4, isk->inet_daddr)) -+ goto nla_put_failure; -+ break; -+#if IS_ENABLED(CONFIG_IPV6) -+ case AF_INET6: { -+ struct ipv6_pinfo *np = inet6_sk(sk); -+ -+ if (nla_put(msg, MPTCP_ATTR_SADDR6, sizeof(np->saddr), -+ &np->saddr)) -+ goto nla_put_failure; -+ -+ if (nla_put(msg, MPTCP_ATTR_DADDR6, sizeof(sk->sk_v6_daddr), -+ &sk->sk_v6_daddr)) -+ goto nla_put_failure; -+ break; -+ } -+#endif -+ default: -+ goto nla_put_failure; -+ } -+ -+ if (nla_put_u16(msg, MPTCP_ATTR_SPORT, ntohs(isk->inet_sport))) -+ goto nla_put_failure; -+ -+ if (nla_put_u16(msg, MPTCP_ATTR_DPORT, ntohs(isk->inet_dport))) -+ goto nla_put_failure; -+ -+ backup = !!(tcp_sk(sk)->mptcp->rcv_low_prio || -+ tcp_sk(sk)->mptcp->low_prio); -+ -+ if (nla_put_u8(msg, MPTCP_ATTR_BACKUP, backup)) -+ goto nla_put_failure; -+ -+ if (nla_put_s32(msg, MPTCP_ATTR_IF_IDX, sk->sk_bound_dev_if)) -+ goto nla_put_failure; -+ -+ sk_err = sk->sk_err ? : tcp_sk(sk)->mptcp->sk_err; -+ if (unlikely(sk_err != 0) && meta_sk->sk_state == TCP_ESTABLISHED && -+ nla_put_u8(msg, MPTCP_ATTR_ERROR, sk_err)) -+ goto nla_put_failure; -+ -+ return 0; -+ -+nla_put_failure: -+ return -1; -+} -+ -+static inline struct sk_buff * -+mptcp_nl_mcast_prepare(struct mptcp_cb *mpcb, struct sock *sk, int cmd, -+ void **hdr) -+{ -+ struct sk_buff *msg; -+ -+ /* possible optimisation: use the needed size */ -+ msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC); -+ if (!msg) -+ return NULL; -+ -+ *hdr = genlmsg_put(msg, 0, 0, &mptcp_genl_family, 0, cmd); -+ if (!*hdr) -+ goto free_msg; -+ -+ if (nla_put_u32(msg, MPTCP_ATTR_TOKEN, mpcb->mptcp_loc_token)) -+ goto nla_put_failure; -+ -+ if (sk && mptcp_nl_put_subsk(msg, sk)) -+ goto nla_put_failure; -+ -+ return msg; -+ -+nla_put_failure: -+ genlmsg_cancel(msg, *hdr); -+free_msg: -+ nlmsg_free(msg); -+ return NULL; -+} -+ -+static inline int -+mptcp_nl_mcast_send(struct mptcp_cb *mpcb, struct sk_buff *msg, void *hdr) -+{ -+ int ret; -+ struct sock *meta_sk = mpcb->meta_sk; -+ -+ genlmsg_end(msg, hdr); -+ -+ ret = genlmsg_multicast_netns(&mptcp_genl_family, sock_net(meta_sk), -+ msg, 0, MPTCP_GENL_EV_GRP_OFFSET, -+ GFP_ATOMIC); -+ if (ret && ret != -ESRCH) -+ pr_err("%s: genlmsg_multicast failed with %d\n", __func__, ret); -+ return ret; -+} -+ -+static inline void -+mptcp_nl_mcast(struct mptcp_cb *mpcb, struct sock *sk, int cmd) -+{ -+ void *hdr; -+ struct sk_buff *msg; -+ -+ msg = mptcp_nl_mcast_prepare(mpcb, sk, cmd, &hdr); -+ if (msg) -+ mptcp_nl_mcast_send(mpcb, msg, hdr); -+ else -+ pr_warn("%s: unable to prepare multicast message\n", __func__); -+} -+ -+static inline void -+mptcp_nl_mcast_fail(struct sk_buff *msg, void *hdr) -+{ -+ genlmsg_cancel(msg, hdr); -+ nlmsg_free(msg); -+} -+ -+static void -+mptcp_nl_new(const struct sock *meta_sk, bool established) -+{ -+ struct mptcp_cb *mpcb = tcp_sk(meta_sk)->mpcb; -+ -+ mptcp_nl_mcast(mpcb, mpcb->master_sk, -+ established ? MPTCP_EVENT_ESTABLISHED -+ : MPTCP_EVENT_CREATED); -+} -+ -+static void -+mptcp_nl_pm_new_session(const struct sock *meta_sk) -+{ -+ if (!mptcp_nl_must_notify(MPTCPF_EVENT_CREATED, meta_sk)) -+ return; -+ -+ mptcp_nl_new(meta_sk, false); -+} -+ -+static inline int -+mptcp_nl_loc_id_to_index_lookup(struct sock *meta_sk, sa_family_t family, -+ u8 addr_id) -+{ -+ struct mptcp_nl_priv *priv = mptcp_nl_priv(meta_sk); -+ int i; -+ -+ switch (family) { -+ case AF_INET: -+ mptcp_for_each_bit_set(priv->loc4_bits, i) { -+ if (priv->locaddr4[i].loc4_id == addr_id) -+ return i; -+ } -+ break; -+#if IS_ENABLED(CONFIG_IPV6) -+ case AF_INET6: -+ mptcp_for_each_bit_set(priv->loc6_bits, i) { -+ if (priv->locaddr6[i].loc6_id == addr_id) -+ return i; -+ } -+ break; -+#endif -+ } -+ return -1; -+} -+ -+static inline void -+mptcp_nl_sk_setup_locaddr(struct sock *meta_sk, struct sock *sk) -+{ -+ struct mptcp_nl_priv *priv = mptcp_nl_priv(meta_sk); -+ bool backup = !!(tcp_sk(sk)->mptcp->rcv_low_prio || -+ tcp_sk(sk)->mptcp->low_prio); -+ sa_family_t family = mptcp_v6_is_v4_mapped(sk) ? AF_INET -+ : sk->sk_family; -+ u8 addr_id = tcp_sk(sk)->mptcp->loc_id; -+ int idx = mptcp_nl_loc_id_to_index_lookup(meta_sk, family, -+ addr_id); -+ -+ /* Same as in mptcp_fullmesh.c: exception for transparent sockets */ -+ int if_idx = inet_sk(sk)->transparent ? inet_sk(sk)->rx_dst_ifindex : -+ sk->sk_bound_dev_if; -+ -+ switch (family) { -+ case AF_INET: { -+ struct inet_sock *isk = inet_sk(sk); -+ -+ if (idx == -1) -+ idx = mptcp_nl_find_free_index(priv->loc4_bits); -+ if (idx == -1) { -+ pr_warn("No free index for sk loc_id v4\n"); -+ return; -+ } -+ priv->locaddr4[idx].addr.s_addr = isk->inet_saddr; -+ priv->locaddr4[idx].loc4_id = addr_id; -+ priv->locaddr4[idx].low_prio = backup; -+ priv->locaddr4[idx].if_idx = if_idx; -+ priv->loc4_bits |= 1 << idx; -+ priv->announced4 |= 1 << idx; -+ break; -+ } -+#if IS_ENABLED(CONFIG_IPV6) -+ case AF_INET6: { -+ struct ipv6_pinfo *np = inet6_sk(sk); -+ -+ if (idx == -1) -+ idx = mptcp_nl_find_free_index(priv->loc6_bits); -+ if (idx == -1) { -+ pr_warn("No free index for sk loc_id v6\n"); -+ return; -+ } -+ priv->locaddr6[idx].addr = np->saddr; -+ priv->locaddr6[idx].loc6_id = addr_id; -+ priv->locaddr6[idx].low_prio = backup; -+ priv->locaddr6[idx].if_idx = if_idx; -+ priv->loc6_bits |= 1 << idx; -+ priv->announced6 |= 1 << idx; -+ break; -+ } -+#endif -+ } -+} -+ -+static void -+mptcp_nl_pm_fully_established(struct sock *meta_sk) -+{ -+ mptcp_nl_sk_setup_locaddr(meta_sk, tcp_sk(meta_sk)->mpcb->master_sk); -+ -+ if (!mptcp_nl_must_notify(MPTCPF_EVENT_ESTABLISHED, meta_sk)) -+ return; -+ -+ mptcp_nl_new(meta_sk, true); -+} -+ -+static void -+mptcp_nl_pm_close_session(struct sock *meta_sk) -+{ -+ if (!mptcp_nl_must_notify(MPTCPF_EVENT_CLOSED, meta_sk)) -+ return; -+ -+ mptcp_nl_mcast(tcp_sk(meta_sk)->mpcb, NULL, MPTCP_EVENT_CLOSED); -+} -+ -+static void -+mptcp_nl_pm_established_subflow(struct sock *sk) -+{ -+ struct sock *meta_sk = mptcp_meta_sk(sk); -+ -+ mptcp_nl_sk_setup_locaddr(meta_sk, sk); -+ -+ if (!mptcp_nl_must_notify(MPTCPF_EVENT_SUB_ESTABLISHED, meta_sk)) -+ return; -+ -+ mptcp_nl_mcast(tcp_sk(meta_sk)->mpcb, sk, MPTCP_EVENT_SUB_ESTABLISHED); -+} -+ -+static void -+mptcp_nl_pm_delete_subflow(struct sock *sk) -+{ -+ struct sock *meta_sk = mptcp_meta_sk(sk); -+ -+ if (!mptcp_nl_must_notify(MPTCPF_EVENT_SUB_CLOSED, meta_sk)) -+ return; -+ -+ mptcp_nl_mcast(tcp_sk(meta_sk)->mpcb, sk, MPTCP_EVENT_SUB_CLOSED); -+} -+ -+static void -+mptcp_nl_pm_add_raddr(struct mptcp_cb *mpcb, const union inet_addr *addr, -+ sa_family_t family, __be16 port, u8 id) -+{ -+ struct sk_buff *msg; -+ void *hdr; -+ -+ if (!mptcp_nl_must_notify(MPTCPF_EVENT_ANNOUNCED, mpcb->meta_sk)) -+ return; -+ -+ msg = mptcp_nl_mcast_prepare(mpcb, NULL, MPTCP_EVENT_ANNOUNCED, &hdr); -+ if (!msg) -+ return; -+ -+ if (nla_put_u8(msg, MPTCP_ATTR_REM_ID, id)) -+ goto nla_put_failure; -+ -+ if (nla_put_u16(msg, MPTCP_ATTR_FAMILY, family)) -+ goto nla_put_failure; -+ -+ switch (family) { -+ case AF_INET: -+ if (nla_put_u32(msg, MPTCP_ATTR_DADDR4, addr->ip)) -+ goto nla_put_failure; -+ break; -+#if IS_ENABLED(CONFIG_IPV6) -+ case AF_INET6: -+ if (nla_put(msg, MPTCP_ATTR_DADDR6, sizeof(addr->ip6), -+ &addr->ip6)) -+ goto nla_put_failure; -+ break; -+#endif -+ default: -+ goto nla_put_failure; -+ } -+ -+ if (nla_put_u16(msg, MPTCP_ATTR_DPORT, ntohs(port))) -+ goto nla_put_failure; -+ -+ mptcp_nl_mcast_send(mpcb, msg, hdr); -+ -+ return; -+ -+nla_put_failure: -+ mptcp_nl_mcast_fail(msg, hdr); -+} -+ -+static void -+mptcp_nl_pm_rem_raddr(struct mptcp_cb *mpcb, u8 id) -+{ -+ struct sk_buff *msg; -+ void *hdr; -+ -+ if (!mptcp_nl_must_notify(MPTCPF_EVENT_REMOVED, mpcb->meta_sk)) -+ return; -+ -+ msg = mptcp_nl_mcast_prepare(mpcb, NULL, MPTCP_EVENT_REMOVED, &hdr); -+ -+ if (!msg) -+ return; -+ -+ if (nla_put_u8(msg, MPTCP_ATTR_REM_ID, id)) -+ goto nla_put_failure; -+ -+ mptcp_nl_mcast_send(mpcb, msg, hdr); -+ -+ return; -+ -+nla_put_failure: -+ mptcp_nl_mcast_fail(msg, hdr); -+} -+ -+static int -+mptcp_nl_pm_get_local_id(const struct sock *meta_sk, sa_family_t family, -+ union inet_addr *addr, bool *low_prio) -+{ -+ struct mptcp_nl_priv *priv = mptcp_nl_priv(meta_sk); -+ int i, id = 0; -+ -+ switch (family) { -+ case AF_INET: -+ mptcp_for_each_bit_set(priv->loc4_bits, i) { -+ if (addr->in.s_addr == priv->locaddr4[i].addr.s_addr) { -+ id = priv->locaddr4[i].loc4_id; -+ *low_prio = priv->locaddr4[i].low_prio; -+ goto out; -+ } -+ } -+ break; -+#if IS_ENABLED(CONFIG_IPV6) -+ case AF_INET6: -+ mptcp_for_each_bit_set(priv->loc6_bits, i) { -+ if (ipv6_addr_equal(&addr->in6, -+ &priv->locaddr6[i].addr)) { -+ id = priv->locaddr6[i].loc6_id; -+ *low_prio = priv->locaddr6[i].low_prio; -+ goto out; -+ } -+ } -+ break; -+#endif -+ } -+ return -1; -+ -+out: -+ return id; -+} -+ -+static void -+mptcp_nl_pm_addr_signal(struct sock *sk, unsigned *size, -+ struct tcp_out_options *opts, struct sk_buff *skb) -+{ -+ struct mptcp_nl_priv *priv = mptcp_nl_priv(sk); -+ struct mptcp_cb *mpcb = tcp_sk(sk)->mpcb; -+ u8 unannounced; -+ int remove_addr_len; -+ -+ unannounced = (~priv->announced4) & priv->loc4_bits; -+ if (unannounced && -+ MAX_TCP_OPTION_SPACE - *size >= MPTCP_SUB_LEN_ADD_ADDR4_ALIGN) { -+ int i = mptcp_nl_find_free_index(~unannounced); -+ -+ opts->options |= OPTION_MPTCP; -+ opts->mptcp_options |= OPTION_ADD_ADDR; -+ opts->add_addr4.addr_id = priv->locaddr4[i].loc4_id; -+ opts->add_addr4.addr = priv->locaddr4[i].addr; -+ opts->add_addr_v4 = 1; -+ -+ if (skb) -+ priv->announced4 |= (1 << i); -+ *size += MPTCP_SUB_LEN_ADD_ADDR4_ALIGN; -+ } -+ -+#if IS_ENABLED(CONFIG_IPV6) -+ unannounced = (~priv->announced6) & priv->loc6_bits; -+ if (unannounced && -+ MAX_TCP_OPTION_SPACE - *size >= MPTCP_SUB_LEN_ADD_ADDR6_ALIGN) { -+ int i = mptcp_nl_find_free_index(~unannounced); -+ -+ opts->options |= OPTION_MPTCP; -+ opts->mptcp_options |= OPTION_ADD_ADDR; -+ opts->add_addr6.addr_id = priv->locaddr6[i].loc6_id; -+ opts->add_addr6.addr = priv->locaddr6[i].addr; -+ opts->add_addr_v6 = 1; -+ -+ if (skb) -+ priv->announced6 |= (1 << i); -+ *size += MPTCP_SUB_LEN_ADD_ADDR6_ALIGN; -+ } -+#endif -+ -+ if (likely(!priv->remove_addrs)) -+ goto exit; -+ -+ remove_addr_len = mptcp_sub_len_remove_addr_align(priv->remove_addrs); -+ if (MAX_TCP_OPTION_SPACE - *size < remove_addr_len) -+ goto exit; -+ -+ opts->options |= OPTION_MPTCP; -+ opts->mptcp_options |= OPTION_REMOVE_ADDR; -+ opts->remove_addrs = priv->remove_addrs; -+ -+ if (skb) -+ priv->remove_addrs = 0; -+ *size += remove_addr_len; -+ -+exit: -+ mpcb->addr_signal = !!((~priv->announced4) & priv->loc4_bits || -+#if IS_ENABLED(CONFIG_IPV6) -+ (~priv->announced6) & priv->loc6_bits || -+#endif -+ priv->remove_addrs); -+} -+ -+static void -+mptcp_nl_pm_prio_changed(struct sock *sk, int low_prio) -+{ -+ struct sock *meta_sk = mptcp_meta_sk(sk); -+ -+ if (!mptcp_nl_must_notify(MPTCPF_EVENT_SUB_PRIORITY, meta_sk)) -+ return; -+ -+ mptcp_nl_mcast(tcp_sk(meta_sk)->mpcb, sk, MPTCP_EVENT_SUB_PRIORITY); -+} -+ -+static int -+mptcp_nl_genl_announce(struct sk_buff *skb, struct genl_info *info) -+{ -+ struct sock *meta_sk, *subsk; -+ struct mptcp_cb *mpcb; -+ struct mptcp_nl_priv *priv; -+ u32 token; -+ u8 addr_id, backup = 0; -+ u16 family; -+ int i, ret = 0; -+ union inet_addr saddr; -+ int if_idx = 0; -+ bool useless; /* unused out parameter "low_prio" */ -+ -+ if (!info->attrs[MPTCP_ATTR_TOKEN] || !info->attrs[MPTCP_ATTR_FAMILY] || -+ !info->attrs[MPTCP_ATTR_LOC_ID]) -+ return -EINVAL; -+ -+ token = nla_get_u32(info->attrs[MPTCP_ATTR_TOKEN]); -+ meta_sk = mptcp_hash_find(genl_info_net(info), token); -+ if (!meta_sk) -+ return -EINVAL; -+ -+ mpcb = tcp_sk(meta_sk)->mpcb; -+ priv = mptcp_nl_priv(meta_sk); -+ family = nla_get_u16(info->attrs[MPTCP_ATTR_FAMILY]); -+ addr_id = nla_get_u8(info->attrs[MPTCP_ATTR_LOC_ID]); -+ -+ if (info->attrs[MPTCP_ATTR_BACKUP]) -+ backup = nla_get_u8(info->attrs[MPTCP_ATTR_BACKUP]); -+ -+ if (info->attrs[MPTCP_ATTR_IF_IDX]) -+ if_idx = nla_get_s32(info->attrs[MPTCP_ATTR_IF_IDX]); -+ -+ mutex_lock(&mpcb->mpcb_mutex); -+ lock_sock_nested(meta_sk, SINGLE_DEPTH_NESTING); -+ -+ switch (family) { -+ case AF_INET: -+ if (!info->attrs[MPTCP_ATTR_SADDR4]) { -+ ret = -EINVAL; -+ goto exit; -+ } -+ -+ saddr.in.s_addr = nla_get_u32(info->attrs[MPTCP_ATTR_SADDR4]); -+ i = mptcp_nl_pm_get_local_id(meta_sk, family, -+ &saddr, &useless); -+ if (i < 0) { -+ i = mptcp_nl_find_free_index(priv->loc4_bits); -+ if (i < 0) { -+ ret = -ENOBUFS; -+ goto exit; -+ } -+ } else if (i != addr_id) { -+ ret = -EINVAL; -+ goto exit; -+ } -+ -+ priv->locaddr4[i].addr.s_addr = saddr.in.s_addr; -+ priv->locaddr4[i].loc4_id = addr_id; -+ priv->locaddr4[i].low_prio = !!backup; -+ priv->locaddr4[i].if_idx = if_idx; -+ priv->loc4_bits |= 1 << i; -+ priv->announced4 &= ~(1 << i); -+ break; -+#if IS_ENABLED(CONFIG_IPV6) -+ case AF_INET6: -+ if (!info->attrs[MPTCP_ATTR_SADDR6]) { -+ ret = -EINVAL; -+ goto exit; -+ } -+ -+ saddr.in6 = *(struct in6_addr *) -+ nla_data(info->attrs[MPTCP_ATTR_SADDR6]); -+ i = mptcp_nl_pm_get_local_id(meta_sk, family, &saddr, &useless); -+ if (i < 0) { -+ i = mptcp_nl_find_free_index(priv->loc6_bits); -+ if (i < 0) { -+ ret = -ENOBUFS; -+ goto exit; -+ } -+ } else if (i != addr_id) { -+ ret = -EINVAL; -+ goto exit; -+ } -+ -+ priv->locaddr6[i].addr = saddr.in6; -+ priv->locaddr6[i].loc6_id = addr_id; -+ priv->locaddr6[i].low_prio = !!backup; -+ priv->locaddr6[i].if_idx = if_idx; -+ priv->loc6_bits |= 1 << i; -+ priv->announced6 &= ~(1 << i); -+ break; -+#endif -+ default: -+ ret = -EINVAL; -+ goto exit; -+ } -+ -+ mpcb->addr_signal = 1; -+ -+ rcu_read_lock_bh(); -+ subsk = mptcp_select_ack_sock(meta_sk); -+ if (subsk) -+ tcp_send_ack(subsk); -+ rcu_read_unlock_bh(); -+ -+exit: -+ release_sock(meta_sk); -+ mutex_unlock(&mpcb->mpcb_mutex); -+ sock_put(meta_sk); -+ return ret; -+} -+ -+static int -+mptcp_nl_genl_remove(struct sk_buff *skb, struct genl_info *info) -+{ -+ struct sock *meta_sk, *subsk; -+ struct mptcp_cb *mpcb; -+ struct mptcp_nl_priv *priv; -+ u32 token; -+ u8 addr_id; -+ int i; -+ int retcode; -+ bool found = false; -+ -+ if (!info->attrs[MPTCP_ATTR_TOKEN] || !info->attrs[MPTCP_ATTR_LOC_ID]) -+ return -EINVAL; -+ -+ token = nla_get_u32(info->attrs[MPTCP_ATTR_TOKEN]); -+ meta_sk = mptcp_hash_find(genl_info_net(info), token); -+ if (!meta_sk) -+ return -EINVAL; -+ -+ mpcb = tcp_sk(meta_sk)->mpcb; -+ priv = mptcp_nl_priv(meta_sk); -+ addr_id = nla_get_u8(info->attrs[MPTCP_ATTR_LOC_ID]); -+ -+ mutex_lock(&mpcb->mpcb_mutex); -+ lock_sock_nested(meta_sk, SINGLE_DEPTH_NESTING); -+ -+ mptcp_for_each_bit_set(priv->loc4_bits, i) { -+ if (priv->locaddr4[i].loc4_id == addr_id) { -+ priv->loc4_bits &= ~(1 << i); -+ found = true; -+ break; -+ } -+ } -+ -+#if IS_ENABLED(CONFIG_IPV6) -+ if (!found) { -+ mptcp_for_each_bit_set(priv->loc6_bits, i) { -+ if (priv->locaddr6[i].loc6_id == addr_id) { -+ priv->loc6_bits &= ~(1 << i); -+ found = true; -+ break; -+ } -+ } -+ } -+#endif -+ -+ if (found) { -+ priv->remove_addrs |= 1 << addr_id; -+ mpcb->addr_signal = 1; -+ -+ rcu_read_lock_bh(); -+ subsk = mptcp_select_ack_sock(meta_sk); -+ if (subsk) -+ tcp_send_ack(subsk); -+ rcu_read_unlock_bh(); -+ retcode = 0; -+ } else { -+ retcode = -EINVAL; -+ } -+ -+ release_sock(meta_sk); -+ mutex_unlock(&mpcb->mpcb_mutex); -+ sock_put(meta_sk); -+ return retcode; -+} -+ -+static int -+mptcp_nl_genl_create(struct sk_buff *skb, struct genl_info *info) -+{ -+ struct sock *meta_sk, *subsk = NULL; -+ struct mptcp_cb *mpcb; -+ struct mptcp_nl_priv *priv; -+ u32 token; -+ u16 family, sport; -+ u8 loc_id, rem_id, backup = 0; -+ int i, ret = 0; -+ int if_idx; -+ -+ if (!info->attrs[MPTCP_ATTR_TOKEN] || !info->attrs[MPTCP_ATTR_FAMILY] || -+ !info->attrs[MPTCP_ATTR_LOC_ID] || !info->attrs[MPTCP_ATTR_REM_ID]) -+ return -EINVAL; -+ -+ token = nla_get_u32(info->attrs[MPTCP_ATTR_TOKEN]); -+ meta_sk = mptcp_hash_find(genl_info_net(info), token); -+ if (!meta_sk) -+ /* We use a more specific value than EINVAL here so that -+ * userspace can handle this specific case easily. This is -+ * useful to check the case in which userspace tries to create a -+ * subflow for a connection which was already destroyed recently -+ * in kernelspace, but userspace didn't have time to realize -+ * about it because there is a gap of time between kernel -+ * destroying the connection and userspace receiving the event -+ * through Netlink. It can easily happen for short life-time -+ * conns. -+ */ -+ return -EBADR; -+ -+ mpcb = tcp_sk(meta_sk)->mpcb; -+ -+ mutex_lock(&mpcb->mpcb_mutex); -+ lock_sock_nested(meta_sk, SINGLE_DEPTH_NESTING); -+ -+ if (sock_flag(meta_sk, SOCK_DEAD)) { -+ /* Same as for the EBADR case. In this case, though, we know for -+ * sure the conn owner of the subflow existed at some point (no -+ * invalid token possibility) -+ */ -+ ret = -EOWNERDEAD; -+ goto unlock; -+ } -+ -+ if (!mptcp_can_new_subflow(meta_sk)) { -+ /* Same as for the EBADR and EOWNERDEAD case but here, the MPTCP -+ * session has just been stopped, it is no longer possible to -+ * create new subflows. -+ */ -+ ret = -ENOTCONN; -+ goto unlock; -+ } -+ -+ if (mpcb->master_sk && -+ !tcp_sk(mpcb->master_sk)->mptcp->fully_established) { -+ /* First condition is not only in there for safely purposes, it -+ * can also be triggered in the same scenario as in EBADR and -+ * EOWNERDEAD -+ */ -+ ret = -EAGAIN; -+ goto unlock; -+ } -+ -+ priv = mptcp_nl_priv(meta_sk); -+ -+ family = nla_get_u16(info->attrs[MPTCP_ATTR_FAMILY]); -+ loc_id = nla_get_u8(info->attrs[MPTCP_ATTR_LOC_ID]); -+ rem_id = nla_get_u8(info->attrs[MPTCP_ATTR_REM_ID]); -+ -+ sport = info->attrs[MPTCP_ATTR_SPORT] -+ ? htons(nla_get_u16(info->attrs[MPTCP_ATTR_SPORT])) : 0; -+ backup = info->attrs[MPTCP_ATTR_BACKUP] -+ ? nla_get_u8(info->attrs[MPTCP_ATTR_BACKUP]) : 0; -+ if_idx = info->attrs[MPTCP_ATTR_IF_IDX] -+ ? nla_get_s32(info->attrs[MPTCP_ATTR_IF_IDX]) : 0; -+ -+ switch (family) { -+ case AF_INET: { -+ struct mptcp_rem4 rem = { -+ .rem4_id = rem_id, -+ }; -+ struct mptcp_loc4 loc = { -+ .loc4_id = loc_id, -+ }; -+ -+ if (!info->attrs[MPTCP_ATTR_DADDR4] || -+ !info->attrs[MPTCP_ATTR_DPORT]) { -+ goto create_failed; -+ } else { -+ rem.addr.s_addr = -+ nla_get_u32(info->attrs[MPTCP_ATTR_DADDR4]); -+ rem.port = -+ ntohs(nla_get_u16(info->attrs[MPTCP_ATTR_DPORT])); -+ } -+ -+ if (!info->attrs[MPTCP_ATTR_SADDR4]) { -+ bool found = false; -+ -+ mptcp_for_each_bit_set(priv->loc4_bits, i) { -+ if (priv->locaddr4[i].loc4_id == loc_id) { -+ loc.addr = priv->locaddr4[i].addr; -+ loc.low_prio = -+ priv->locaddr4[i].low_prio; -+ loc.if_idx = -+ priv->locaddr4[i].if_idx; -+ found = true; -+ break; -+ } -+ } -+ -+ if (!found) -+ goto create_failed; -+ } else { -+ loc.addr.s_addr = -+ nla_get_u32(info->attrs[MPTCP_ATTR_SADDR4]); -+ loc.low_prio = backup; -+ loc.if_idx = if_idx; -+ } -+ -+ ret = __mptcp_init4_subsockets(meta_sk, &loc, sport, &rem, -+ &subsk); -+ if (ret < 0) -+ goto unlock; -+ break; -+ } -+#if IS_ENABLED(CONFIG_IPV6) -+ case AF_INET6: { -+ struct mptcp_rem6 rem = { -+ .rem6_id = rem_id, -+ }; -+ struct mptcp_loc6 loc = { -+ .loc6_id = loc_id, -+ }; -+ -+ if (!info->attrs[MPTCP_ATTR_DADDR6] || -+ !info->attrs[MPTCP_ATTR_DPORT]) { -+ goto create_failed; -+ } else { -+ rem.addr = *(struct in6_addr *) -+ nla_data(info->attrs[MPTCP_ATTR_DADDR6]); -+ rem.port = -+ ntohs(nla_get_u16(info->attrs[MPTCP_ATTR_DPORT])); -+ } -+ -+ if (!info->attrs[MPTCP_ATTR_SADDR6]) { -+ bool found = false; -+ -+ mptcp_for_each_bit_set(priv->loc6_bits, i) { -+ if (priv->locaddr6[i].loc6_id == loc_id) { -+ loc.addr = priv->locaddr6[i].addr; -+ loc.low_prio = -+ priv->locaddr6[i].low_prio; -+ loc.if_idx = -+ priv->locaddr6[i].if_idx; -+ -+ found = true; -+ break; -+ } -+ } -+ -+ if (!found) -+ goto create_failed; -+ } else { -+ loc.addr = *(struct in6_addr *) -+ nla_data(info->attrs[MPTCP_ATTR_SADDR6]); -+ loc.low_prio = backup; -+ loc.if_idx = if_idx; -+ } -+ -+ ret = __mptcp_init6_subsockets(meta_sk, &loc, sport, &rem, -+ &subsk); -+ if (ret < 0) -+ goto unlock; -+ break; -+ } -+#endif -+ default: -+ goto create_failed; -+ } -+ -+unlock: -+ release_sock(meta_sk); -+ mutex_unlock(&mpcb->mpcb_mutex); -+ sock_put(meta_sk); -+ return ret; -+ -+create_failed: -+ ret = -EINVAL; -+ goto unlock; -+} -+ -+static struct sock * -+mptcp_nl_subsk_lookup(struct mptcp_cb *mpcb, struct nlattr **attrs) -+{ -+ struct sock *sk; -+ struct mptcp_tcp_sock *mptcp; -+ struct hlist_node *tmp; -+ u16 family; -+ __be16 sport, dport; -+ -+ if (!attrs[MPTCP_ATTR_FAMILY] || !attrs[MPTCP_ATTR_SPORT] || -+ !attrs[MPTCP_ATTR_DPORT]) -+ goto exit; -+ -+ family = nla_get_u16(attrs[MPTCP_ATTR_FAMILY]); -+ sport = htons(nla_get_u16(attrs[MPTCP_ATTR_SPORT])); -+ dport = htons(nla_get_u16(attrs[MPTCP_ATTR_DPORT])); -+ -+ switch (family) { -+ case AF_INET: { -+ __be32 saddr, daddr; -+ -+ if (!attrs[MPTCP_ATTR_SADDR4] || !attrs[MPTCP_ATTR_DADDR4]) -+ break; -+ -+ saddr = nla_get_u32(attrs[MPTCP_ATTR_SADDR4]); -+ daddr = nla_get_u32(attrs[MPTCP_ATTR_DADDR4]); -+ -+ mptcp_for_each_sub_safe(mpcb, mptcp, tmp) { -+ struct sock *subsk = mptcp_to_sock(mptcp); -+ struct inet_sock *isk = inet_sk(subsk); -+ -+ if (subsk->sk_family != AF_INET) -+ continue; -+ -+ if (isk->inet_saddr == saddr && -+ isk->inet_daddr == daddr && -+ isk->inet_sport == sport && -+ isk->inet_dport == dport) { -+ sk = subsk; -+ goto found; -+ } -+ } -+ break; -+ } -+#if IS_ENABLED(CONFIG_IPV6) -+ case AF_INET6: { -+ struct in6_addr saddr, daddr; -+ -+ if (!attrs[MPTCP_ATTR_SADDR6] || !attrs[MPTCP_ATTR_DADDR6]) -+ break; -+ -+ saddr = *(struct in6_addr *)nla_data(attrs[MPTCP_ATTR_SADDR6]); -+ daddr = *(struct in6_addr *)nla_data(attrs[MPTCP_ATTR_DADDR6]); -+ -+ mptcp_for_each_sub_safe(mpcb, mptcp, tmp) { -+ struct sock *subsk = mptcp_to_sock(mptcp); -+ struct inet_sock *isk = inet_sk(subsk); -+ struct ipv6_pinfo *np; -+ -+ if (subsk->sk_family != AF_INET6) -+ continue; -+ -+ np = inet6_sk(subsk); -+ if (ipv6_addr_equal(&saddr, &np->saddr) && -+ ipv6_addr_equal(&daddr, &subsk->sk_v6_daddr) && -+ isk->inet_sport == sport && -+ isk->inet_dport == dport) { -+ sk = subsk; -+ goto found; -+ } -+ } -+ break; -+ } -+#endif -+ } -+ -+exit: -+ sk = NULL; -+found: -+ return sk; -+} -+ -+static int -+mptcp_nl_genl_destroy(struct sk_buff *skb, struct genl_info *info) -+{ -+ struct sock *meta_sk, *subsk; -+ struct mptcp_cb *mpcb; -+ int ret = 0; -+ u32 token; -+ -+ if (!info->attrs[MPTCP_ATTR_TOKEN]) -+ return -EINVAL; -+ -+ token = nla_get_u32(info->attrs[MPTCP_ATTR_TOKEN]); -+ -+ meta_sk = mptcp_hash_find(genl_info_net(info), token); -+ if (!meta_sk) -+ return -EINVAL; -+ -+ mpcb = tcp_sk(meta_sk)->mpcb; -+ -+ mutex_lock(&mpcb->mpcb_mutex); -+ lock_sock_nested(meta_sk, SINGLE_DEPTH_NESTING); -+ -+ subsk = mptcp_nl_subsk_lookup(mpcb, info->attrs); -+ if (subsk) { -+ local_bh_disable(); -+ mptcp_reinject_data(subsk, 0); -+ mptcp_send_reset(subsk); -+ local_bh_enable(); -+ } else { -+ ret = -EINVAL; -+ } -+ -+ release_sock(meta_sk); -+ mutex_unlock(&mpcb->mpcb_mutex); -+ sock_put(meta_sk); -+ return ret; -+} -+ -+static int -+mptcp_nl_genl_conn_exists(struct sk_buff *skb, struct genl_info *info) -+{ -+ struct sock *meta_sk; -+ u32 token; -+ -+ if (!info->attrs[MPTCP_ATTR_TOKEN]) -+ return -EINVAL; -+ -+ token = nla_get_u32(info->attrs[MPTCP_ATTR_TOKEN]); -+ -+ meta_sk = mptcp_hash_find(genl_info_net(info), token); -+ if (!meta_sk) -+ return -ENOTCONN; -+ -+ sock_put(meta_sk); -+ return 0; -+} -+ -+static int -+mptcp_nl_genl_priority(struct sk_buff *skb, struct genl_info *info) -+{ -+ struct sock *meta_sk, *subsk; -+ struct mptcp_cb *mpcb; -+ int ret = 0; -+ u32 token; -+ u8 backup = 0; -+ -+ if (!info->attrs[MPTCP_ATTR_TOKEN]) -+ return -EINVAL; -+ -+ token = nla_get_u32(info->attrs[MPTCP_ATTR_TOKEN]); -+ if (info->attrs[MPTCP_ATTR_BACKUP]) -+ backup = nla_get_u8(info->attrs[MPTCP_ATTR_BACKUP]); -+ -+ meta_sk = mptcp_hash_find(genl_info_net(info), token); -+ if (!meta_sk) -+ return -EINVAL; -+ -+ mpcb = tcp_sk(meta_sk)->mpcb; -+ -+ mutex_lock(&mpcb->mpcb_mutex); -+ lock_sock_nested(meta_sk, SINGLE_DEPTH_NESTING); -+ -+ subsk = mptcp_nl_subsk_lookup(mpcb, info->attrs); -+ if (subsk) { -+ tcp_sk(subsk)->mptcp->send_mp_prio = 1; -+ tcp_sk(subsk)->mptcp->low_prio = !!backup; -+ -+ local_bh_disable(); -+ if (mptcp_sk_can_send_ack(subsk)) -+ tcp_send_ack(subsk); -+ else -+ ret = -ENOTCONN; -+ local_bh_enable(); -+ } else { -+ ret = -EINVAL; -+ } -+ -+ release_sock(meta_sk); -+ mutex_unlock(&mpcb->mpcb_mutex); -+ sock_put(meta_sk); -+ return ret; -+} -+ -+static int -+mptcp_nl_genl_set_filter(struct sk_buff *skb, struct genl_info *info) -+{ -+ u16 flags; -+ -+ if (!info->attrs[MPTCP_ATTR_FLAGS]) -+ return -EINVAL; -+ -+ flags = nla_get_u16(info->attrs[MPTCP_ATTR_FLAGS]); -+ -+ /* Only want to receive events that correspond to these flags */ -+ mptcp_nl_event_filter = ~flags; -+ -+ return 0; -+} -+ -+static struct genl_ops mptcp_genl_ops[] = { -+ { -+ .cmd = MPTCP_CMD_ANNOUNCE, -+ .doit = mptcp_nl_genl_announce, -+ .policy = mptcp_nl_genl_policy, -+ .flags = GENL_ADMIN_PERM, -+ }, -+ { -+ .cmd = MPTCP_CMD_REMOVE, -+ .doit = mptcp_nl_genl_remove, -+ .policy = mptcp_nl_genl_policy, -+ .flags = GENL_ADMIN_PERM, -+ }, -+ { -+ .cmd = MPTCP_CMD_SUB_CREATE, -+ .doit = mptcp_nl_genl_create, -+ .policy = mptcp_nl_genl_policy, -+ .flags = GENL_ADMIN_PERM, -+ }, -+ { -+ .cmd = MPTCP_CMD_SUB_DESTROY, -+ .doit = mptcp_nl_genl_destroy, -+ .policy = mptcp_nl_genl_policy, -+ .flags = GENL_ADMIN_PERM, -+ }, -+ { -+ .cmd = MPTCP_CMD_SUB_PRIORITY, -+ .doit = mptcp_nl_genl_priority, -+ .policy = mptcp_nl_genl_policy, -+ .flags = GENL_ADMIN_PERM, -+ }, -+ { -+ .cmd = MPTCP_CMD_SET_FILTER, -+ .doit = mptcp_nl_genl_set_filter, -+ .policy = mptcp_nl_genl_policy, -+ .flags = GENL_ADMIN_PERM, -+ }, -+ { -+ .cmd = MPTCP_CMD_EXIST, -+ .doit = mptcp_nl_genl_conn_exists, -+ .policy = mptcp_nl_genl_policy, -+ .flags = GENL_ADMIN_PERM, -+ }, -+}; -+ -+static struct mptcp_pm_ops mptcp_nl_pm_ops = { -+ .new_session = mptcp_nl_pm_new_session, -+ .close_session = mptcp_nl_pm_close_session, -+ .fully_established = mptcp_nl_pm_fully_established, -+ .established_subflow = mptcp_nl_pm_established_subflow, -+ .delete_subflow = mptcp_nl_pm_delete_subflow, -+ .add_raddr = mptcp_nl_pm_add_raddr, -+ .rem_raddr = mptcp_nl_pm_rem_raddr, -+ .get_local_id = mptcp_nl_pm_get_local_id, -+ .addr_signal = mptcp_nl_pm_addr_signal, -+ .prio_changed = mptcp_nl_pm_prio_changed, -+ .name = "netlink", -+ .owner = THIS_MODULE, -+}; -+ -+static struct genl_family mptcp_genl_family = { -+ .hdrsize = 0, -+ .name = MPTCP_GENL_NAME, -+ .version = MPTCP_GENL_VER, -+ .maxattr = MPTCP_ATTR_MAX, -+ .netnsok = true, -+ .module = THIS_MODULE, -+ .ops = mptcp_genl_ops, -+ .n_ops = ARRAY_SIZE(mptcp_genl_ops), -+ .mcgrps = mptcp_mcgrps, -+ .n_mcgrps = ARRAY_SIZE(mptcp_mcgrps), -+}; -+ -+static int __init -+mptcp_nl_init(void) -+{ -+ int ret; -+ -+ BUILD_BUG_ON(sizeof(struct mptcp_nl_priv) > MPTCP_PM_SIZE); -+ -+ ret = genl_register_family(&mptcp_genl_family); -+ if (ret) -+ goto out_genl; -+ -+ ret = mptcp_register_path_manager(&mptcp_nl_pm_ops); -+ if (ret) -+ goto out_pm; -+ -+ return 0; -+out_pm: -+ genl_unregister_family(&mptcp_genl_family); -+out_genl: -+ return ret; -+} -+ -+static void __exit -+mptcp_nl_exit(void) -+{ -+ mptcp_unregister_path_manager(&mptcp_nl_pm_ops); -+ genl_unregister_family(&mptcp_genl_family); -+} -+ -+module_init(mptcp_nl_init); -+module_exit(mptcp_nl_exit); -+ -+MODULE_AUTHOR("Gregory Detal "); -+MODULE_LICENSE("GPL"); -+MODULE_DESCRIPTION("MPTCP netlink-based path manager"); -+MODULE_ALIAS_GENL_FAMILY(MPTCP_GENL_NAME); -diff -aurN linux-4.19.104/net/mptcp/mptcp_olia.c mptcp-mptcp_v0.95/net/mptcp/mptcp_olia.c ---- linux-4.19.104/net/mptcp/mptcp_olia.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_v0.95/net/mptcp/mptcp_olia.c 2020-02-17 11:29:55.000000000 +0100 -@@ -0,0 +1,318 @@ -+/* -+ * MPTCP implementation - OPPORTUNISTIC LINKED INCREASES CONGESTION CONTROL: -+ * -+ * Algorithm design: -+ * Ramin Khalili -+ * Nicolas Gast -+ * Jean-Yves Le Boudec -+ * -+ * Implementation: -+ * Ramin Khalili -+ * -+ * Ported to the official MPTCP-kernel: -+ * Christoph Paasch -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version -+ * 2 of the License, or (at your option) any later version. -+ */ -+ -+ -+#include -+#include -+ -+#include -+ -+static int scale = 10; -+ -+struct mptcp_olia { -+ u32 mptcp_loss1; -+ u32 mptcp_loss2; -+ u32 mptcp_loss3; -+ int epsilon_num; -+ u32 epsilon_den; -+ int mptcp_snd_cwnd_cnt; -+}; -+ -+static inline int mptcp_olia_sk_can_send(const struct sock *sk) -+{ -+ return mptcp_sk_can_send(sk) && tcp_sk(sk)->srtt_us; -+} -+ -+static inline u64 mptcp_olia_scale(u64 val, int scale) -+{ -+ return (u64) val << scale; -+} -+ -+/* take care of artificially inflate (see RFC5681) -+ * of cwnd during fast-retransmit phase -+ */ -+static u32 mptcp_get_crt_cwnd(struct sock *sk) -+{ -+ const struct inet_connection_sock *icsk = inet_csk(sk); -+ -+ if (icsk->icsk_ca_state == TCP_CA_Recovery) -+ return tcp_sk(sk)->snd_ssthresh; -+ else -+ return tcp_sk(sk)->snd_cwnd; -+} -+ -+/* return the dominator of the first term of the increasing term */ -+static u64 mptcp_get_rate(const struct mptcp_cb *mpcb , u32 path_rtt) -+{ -+ struct mptcp_tcp_sock *mptcp; -+ u64 rate = 1; /* We have to avoid a zero-rate because it is used as a divisor */ -+ -+ mptcp_for_each_sub(mpcb, mptcp) { -+ struct sock *sk = mptcp_to_sock(mptcp); -+ struct tcp_sock *tp = tcp_sk(sk); -+ u64 scaled_num; -+ u32 tmp_cwnd; -+ -+ if (!mptcp_olia_sk_can_send(sk)) -+ continue; -+ -+ tmp_cwnd = mptcp_get_crt_cwnd(sk); -+ scaled_num = mptcp_olia_scale(tmp_cwnd, scale) * path_rtt; -+ rate += div_u64(scaled_num , tp->srtt_us); -+ } -+ rate *= rate; -+ return rate; -+} -+ -+/* find the maximum cwnd, used to find set M */ -+static u32 mptcp_get_max_cwnd(const struct mptcp_cb *mpcb) -+{ -+ struct mptcp_tcp_sock *mptcp; -+ u32 best_cwnd = 0; -+ -+ mptcp_for_each_sub(mpcb, mptcp) { -+ struct sock *sk = mptcp_to_sock(mptcp); -+ u32 tmp_cwnd; -+ -+ if (!mptcp_olia_sk_can_send(sk)) -+ continue; -+ -+ tmp_cwnd = mptcp_get_crt_cwnd(sk); -+ if (tmp_cwnd > best_cwnd) -+ best_cwnd = tmp_cwnd; -+ } -+ return best_cwnd; -+} -+ -+static void mptcp_get_epsilon(const struct mptcp_cb *mpcb) -+{ -+ struct mptcp_tcp_sock *mptcp; -+ struct mptcp_olia *ca; -+ struct tcp_sock *tp; -+ struct sock *sk; -+ u64 tmp_int, tmp_rtt, best_int = 0, best_rtt = 1; -+ u32 max_cwnd, tmp_cwnd, established_cnt = 0; -+ u8 M = 0, B_not_M = 0; -+ -+ /* TODO - integrate this in the following loop - we just want to iterate once */ -+ -+ max_cwnd = mptcp_get_max_cwnd(mpcb); -+ -+ /* find the best path */ -+ mptcp_for_each_sub(mpcb, mptcp) { -+ sk = mptcp_to_sock(mptcp); -+ tp = tcp_sk(sk); -+ ca = inet_csk_ca(sk); -+ -+ if (!mptcp_olia_sk_can_send(sk)) -+ continue; -+ -+ established_cnt++; -+ -+ tmp_rtt = (u64)tp->srtt_us * tp->srtt_us; -+ /* TODO - check here and rename variables */ -+ tmp_int = max(ca->mptcp_loss3 - ca->mptcp_loss2, -+ ca->mptcp_loss2 - ca->mptcp_loss1); -+ -+ if ((u64)tmp_int * best_rtt >= (u64)best_int * tmp_rtt) { -+ best_rtt = tmp_rtt; -+ best_int = tmp_int; -+ } -+ } -+ -+ /* TODO - integrate this here in mptcp_get_max_cwnd and in the previous loop */ -+ /* find the size of M and B_not_M */ -+ mptcp_for_each_sub(mpcb, mptcp) { -+ sk = mptcp_to_sock(mptcp); -+ tp = tcp_sk(sk); -+ ca = inet_csk_ca(sk); -+ -+ if (!mptcp_olia_sk_can_send(sk)) -+ continue; -+ -+ tmp_cwnd = mptcp_get_crt_cwnd(sk); -+ if (tmp_cwnd == max_cwnd) { -+ M++; -+ } else { -+ tmp_rtt = (u64)tp->srtt_us * tp->srtt_us; -+ tmp_int = max(ca->mptcp_loss3 - ca->mptcp_loss2, -+ ca->mptcp_loss2 - ca->mptcp_loss1); -+ -+ if ((u64)tmp_int * best_rtt == (u64)best_int * tmp_rtt) -+ B_not_M++; -+ } -+ } -+ -+ /* check if the path is in M or B_not_M and set the value of epsilon accordingly */ -+ mptcp_for_each_sub(mpcb, mptcp) { -+ sk = mptcp_to_sock(mptcp); -+ tp = tcp_sk(sk); -+ ca = inet_csk_ca(sk); -+ -+ if (!mptcp_olia_sk_can_send(sk)) -+ continue; -+ -+ if (B_not_M == 0) { -+ ca->epsilon_num = 0; -+ ca->epsilon_den = 1; -+ } else { -+ tmp_rtt = (u64)tp->srtt_us * tp->srtt_us; -+ tmp_int = max(ca->mptcp_loss3 - ca->mptcp_loss2, -+ ca->mptcp_loss2 - ca->mptcp_loss1); -+ tmp_cwnd = mptcp_get_crt_cwnd(sk); -+ -+ if (tmp_cwnd < max_cwnd && -+ (u64)tmp_int * best_rtt == (u64)best_int * tmp_rtt) { -+ ca->epsilon_num = 1; -+ ca->epsilon_den = established_cnt * B_not_M; -+ } else if (tmp_cwnd == max_cwnd) { -+ ca->epsilon_num = -1; -+ ca->epsilon_den = established_cnt * M; -+ } else { -+ ca->epsilon_num = 0; -+ ca->epsilon_den = 1; -+ } -+ } -+ } -+} -+ -+/* setting the initial values */ -+static void mptcp_olia_init(struct sock *sk) -+{ -+ const struct tcp_sock *tp = tcp_sk(sk); -+ struct mptcp_olia *ca = inet_csk_ca(sk); -+ -+ if (mptcp(tp)) { -+ ca->mptcp_loss1 = tp->snd_una; -+ ca->mptcp_loss2 = tp->snd_una; -+ ca->mptcp_loss3 = tp->snd_una; -+ ca->mptcp_snd_cwnd_cnt = 0; -+ ca->epsilon_num = 0; -+ ca->epsilon_den = 1; -+ } -+} -+ -+/* updating inter-loss distance and ssthresh */ -+static void mptcp_olia_set_state(struct sock *sk, u8 new_state) -+{ -+ if (!mptcp(tcp_sk(sk))) -+ return; -+ -+ if (new_state == TCP_CA_Loss || -+ new_state == TCP_CA_Recovery || new_state == TCP_CA_CWR) { -+ struct mptcp_olia *ca = inet_csk_ca(sk); -+ -+ if (ca->mptcp_loss3 != ca->mptcp_loss2 && -+ !inet_csk(sk)->icsk_retransmits) { -+ ca->mptcp_loss1 = ca->mptcp_loss2; -+ ca->mptcp_loss2 = ca->mptcp_loss3; -+ } -+ } -+} -+ -+/* main algorithm */ -+static void mptcp_olia_cong_avoid(struct sock *sk, u32 ack, u32 acked) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct mptcp_olia *ca = inet_csk_ca(sk); -+ const struct mptcp_cb *mpcb = tp->mpcb; -+ -+ u64 inc_num, inc_den, rate, cwnd_scaled; -+ -+ if (!mptcp(tp)) { -+ tcp_reno_cong_avoid(sk, ack, acked); -+ return; -+ } -+ -+ ca->mptcp_loss3 = tp->snd_una; -+ -+ if (!tcp_is_cwnd_limited(sk)) -+ return; -+ -+ /* slow start if it is in the safe area */ -+ if (tcp_in_slow_start(tp)) { -+ tcp_slow_start(tp, acked); -+ return; -+ } -+ -+ mptcp_get_epsilon(mpcb); -+ rate = mptcp_get_rate(mpcb, tp->srtt_us); -+ cwnd_scaled = mptcp_olia_scale(tp->snd_cwnd, scale); -+ inc_den = ca->epsilon_den * tp->snd_cwnd * rate ? : 1; -+ -+ /* calculate the increasing term, scaling is used to reduce the rounding effect */ -+ if (ca->epsilon_num == -1) { -+ if (ca->epsilon_den * cwnd_scaled * cwnd_scaled < rate) { -+ inc_num = rate - ca->epsilon_den * -+ cwnd_scaled * cwnd_scaled; -+ ca->mptcp_snd_cwnd_cnt -= div64_u64( -+ mptcp_olia_scale(inc_num , scale) , inc_den); -+ } else { -+ inc_num = ca->epsilon_den * -+ cwnd_scaled * cwnd_scaled - rate; -+ ca->mptcp_snd_cwnd_cnt += div64_u64( -+ mptcp_olia_scale(inc_num , scale) , inc_den); -+ } -+ } else { -+ inc_num = ca->epsilon_num * rate + -+ ca->epsilon_den * cwnd_scaled * cwnd_scaled; -+ ca->mptcp_snd_cwnd_cnt += div64_u64( -+ mptcp_olia_scale(inc_num , scale) , inc_den); -+ } -+ -+ -+ if (ca->mptcp_snd_cwnd_cnt >= (1 << scale) - 1) { -+ if (tp->snd_cwnd < tp->snd_cwnd_clamp) -+ tp->snd_cwnd++; -+ ca->mptcp_snd_cwnd_cnt = 0; -+ } else if (ca->mptcp_snd_cwnd_cnt <= 0 - (1 << scale) + 1) { -+ tp->snd_cwnd = max((int) 1 , (int) tp->snd_cwnd - 1); -+ ca->mptcp_snd_cwnd_cnt = 0; -+ } -+} -+ -+static struct tcp_congestion_ops mptcp_olia = { -+ .init = mptcp_olia_init, -+ .ssthresh = tcp_reno_ssthresh, -+ .cong_avoid = mptcp_olia_cong_avoid, -+ .undo_cwnd = tcp_reno_undo_cwnd, -+ .set_state = mptcp_olia_set_state, -+ .owner = THIS_MODULE, -+ .name = "olia", -+}; -+ -+static int __init mptcp_olia_register(void) -+{ -+ BUILD_BUG_ON(sizeof(struct mptcp_olia) > ICSK_CA_PRIV_SIZE); -+ return tcp_register_congestion_control(&mptcp_olia); -+} -+ -+static void __exit mptcp_olia_unregister(void) -+{ -+ tcp_unregister_congestion_control(&mptcp_olia); -+} -+ -+module_init(mptcp_olia_register); -+module_exit(mptcp_olia_unregister); -+ -+MODULE_AUTHOR("Ramin Khalili, Nicolas Gast, Jean-Yves Le Boudec"); -+MODULE_LICENSE("GPL"); -+MODULE_DESCRIPTION("MPTCP COUPLED CONGESTION CONTROL"); -+MODULE_VERSION("0.1"); -diff -aurN linux-4.19.104/net/mptcp/mptcp_output.c mptcp-mptcp_v0.95/net/mptcp/mptcp_output.c ---- linux-4.19.104/net/mptcp/mptcp_output.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_v0.95/net/mptcp/mptcp_output.c 2020-02-17 11:29:55.000000000 +0100 -@@ -0,0 +1,1929 @@ -+/* -+ * MPTCP implementation - Sending side -+ * -+ * Initial Design & Implementation: -+ * Sébastien Barré -+ * -+ * Current Maintainer & Author: -+ * Christoph Paasch -+ * -+ * Additional authors: -+ * Jaakko Korkeaniemi -+ * Gregory Detal -+ * Fabien Duchêne -+ * Andreas Seelinger -+ * Lavkesh Lahngir -+ * Andreas Ripke -+ * Vlad Dogaru -+ * Octavian Purdila -+ * John Ronan -+ * Catalin Nicutar -+ * Brandon Heller -+ * -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version -+ * 2 of the License, or (at your option) any later version. -+ */ -+ -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+ -+static const int mptcp_dss_len = MPTCP_SUB_LEN_DSS_ALIGN + -+ MPTCP_SUB_LEN_ACK_ALIGN + -+ MPTCP_SUB_LEN_SEQ_ALIGN; -+ -+static inline int mptcp_sub_len_remove_addr(u16 bitfield) -+{ -+ unsigned int c; -+ for (c = 0; bitfield; c++) -+ bitfield &= bitfield - 1; -+ return MPTCP_SUB_LEN_REMOVE_ADDR + c - 1; -+} -+ -+int mptcp_sub_len_remove_addr_align(u16 bitfield) -+{ -+ return ALIGN(mptcp_sub_len_remove_addr(bitfield), 4); -+} -+EXPORT_SYMBOL(mptcp_sub_len_remove_addr_align); -+ -+/* get the data-seq and end-data-seq and store them again in the -+ * tcp_skb_cb -+ */ -+static bool mptcp_reconstruct_mapping(struct sk_buff *skb) -+{ -+ const struct mp_dss *mpdss = (struct mp_dss *)TCP_SKB_CB(skb)->dss; -+ __be32 *p32; -+ __be16 *p16; -+ -+ if (!mptcp_is_data_seq(skb)) -+ return false; -+ -+ if (!mpdss->M) -+ return false; -+ -+ /* Move the pointer to the data-seq */ -+ p32 = (__be32 *)mpdss; -+ p32++; -+ if (mpdss->A) { -+ p32++; -+ if (mpdss->a) -+ p32++; -+ } -+ -+ TCP_SKB_CB(skb)->seq = ntohl(*p32); -+ -+ /* Get the data_len to calculate the end_data_seq */ -+ p32++; -+ p32++; -+ p16 = (__be16 *)p32; -+ TCP_SKB_CB(skb)->end_seq = ntohs(*p16) + TCP_SKB_CB(skb)->seq; -+ -+ return true; -+} -+ -+static bool mptcp_is_reinjected(const struct sk_buff *skb) -+{ -+ return TCP_SKB_CB(skb)->mptcp_flags & MPTCP_REINJECT; -+} -+ -+static void mptcp_find_and_set_pathmask(struct sock *meta_sk, struct sk_buff *skb) -+{ -+ struct rb_node **p = &meta_sk->tcp_rtx_queue.rb_node; -+ struct rb_node *parent; -+ struct sk_buff *skb_it; -+ -+ while (*p) { -+ parent = *p; -+ skb_it = rb_to_skb(parent); -+ if (before(TCP_SKB_CB(skb)->seq, TCP_SKB_CB(skb_it)->seq)) { -+ p = &parent->rb_left; -+ continue; -+ } -+ if (after(TCP_SKB_CB(skb)->seq, TCP_SKB_CB(skb_it)->seq)) { -+ p = &parent->rb_right; -+ continue; -+ } -+ -+ TCP_SKB_CB(skb)->path_mask = TCP_SKB_CB(skb_it)->path_mask; -+ break; -+ } -+} -+ -+/* Reinject data from one TCP subflow to the meta_sk. If sk == NULL, we are -+ * coming from the meta-retransmit-timer -+ */ -+static void __mptcp_reinject_data(struct sk_buff *orig_skb, struct sock *meta_sk, -+ struct sock *sk, int clone_it, -+ enum tcp_queue tcp_queue) -+{ -+ struct sk_buff *skb, *skb1; -+ const struct tcp_sock *meta_tp = tcp_sk(meta_sk); -+ struct mptcp_cb *mpcb = meta_tp->mpcb; -+ u32 seq, end_seq; -+ -+ if (clone_it) { -+ /* pskb_copy is necessary here, because the TCP/IP-headers -+ * will be changed when it's going to be reinjected on another -+ * subflow. -+ */ -+ tcp_skb_tsorted_save(orig_skb) { -+ skb = pskb_copy_for_clone(orig_skb, GFP_ATOMIC); -+ } tcp_skb_tsorted_restore(orig_skb); -+ } else { -+ if (tcp_queue == TCP_FRAG_IN_WRITE_QUEUE) { -+ __skb_unlink(orig_skb, &sk->sk_write_queue); -+ } else { -+ list_del(&orig_skb->tcp_tsorted_anchor); -+ tcp_rtx_queue_unlink(orig_skb, sk); -+ INIT_LIST_HEAD(&orig_skb->tcp_tsorted_anchor); -+ } -+ sock_set_flag(sk, SOCK_QUEUE_SHRUNK); -+ sk->sk_wmem_queued -= orig_skb->truesize; -+ sk_mem_uncharge(sk, orig_skb->truesize); -+ skb = orig_skb; -+ } -+ if (unlikely(!skb)) -+ return; -+ -+ /* Make sure that this list is clean */ -+ tcp_skb_tsorted_anchor_cleanup(skb); -+ -+ if (sk && !mptcp_reconstruct_mapping(skb)) { -+ __kfree_skb(skb); -+ return; -+ } -+ -+ skb->sk = meta_sk; -+ -+ /* Reset subflow-specific TCP control-data */ -+ TCP_SKB_CB(skb)->sacked = 0; -+ TCP_SKB_CB(skb)->tcp_flags &= (TCPHDR_ACK | TCPHDR_PSH); -+ -+ /* If it reached already the destination, we don't have to reinject it */ -+ if (!after(TCP_SKB_CB(skb)->end_seq, meta_tp->snd_una)) { -+ __kfree_skb(skb); -+ return; -+ } -+ -+ /* Only reinject segments that are fully covered by the mapping */ -+ if (skb->len + (mptcp_is_data_fin(skb) ? 1 : 0) != -+ TCP_SKB_CB(skb)->end_seq - TCP_SKB_CB(skb)->seq) { -+ struct rb_node *parent, **p = &meta_sk->tcp_rtx_queue.rb_node; -+ u32 end_seq = TCP_SKB_CB(skb)->end_seq; -+ u32 seq = TCP_SKB_CB(skb)->seq; -+ -+ __kfree_skb(skb); -+ -+ /* Ok, now we have to look for the full mapping in the meta -+ * send-queue :S -+ */ -+ -+ /* First, find the first skb that covers us */ -+ while (*p) { -+ parent = *p; -+ skb = rb_to_skb(parent); -+ -+ /* Not yet at the mapping? */ -+ if (!after(end_seq, TCP_SKB_CB(skb)->seq)) { -+ p = &parent->rb_left; -+ continue; -+ } -+ -+ if (!before(seq, TCP_SKB_CB(skb)->end_seq)) { -+ p = &parent->rb_right; -+ continue; -+ } -+ -+ break; -+ } -+ -+ if (*p) { -+ /* We found it, now let's reinject everything */ -+ skb = rb_to_skb(*p); -+ -+ skb_rbtree_walk_from(skb) { -+ if (after(TCP_SKB_CB(skb)->end_seq, end_seq)) -+ return; -+ __mptcp_reinject_data(skb, meta_sk, NULL, 1, -+ TCP_FRAG_IN_RTX_QUEUE); -+ } -+ } -+ return; -+ } -+ -+ /* Segment goes back to the MPTCP-layer. So, we need to zero the -+ * path_mask/dss. -+ */ -+ memset(TCP_SKB_CB(skb)->dss, 0 , mptcp_dss_len); -+ -+ /* We need to find out the path-mask from the meta-write-queue -+ * to properly select a subflow. -+ */ -+ mptcp_find_and_set_pathmask(meta_sk, skb); -+ -+ /* If it's empty, just add */ -+ if (skb_queue_empty(&mpcb->reinject_queue)) { -+ skb_queue_head(&mpcb->reinject_queue, skb); -+ return; -+ } -+ -+ /* Find place to insert skb - or even we can 'drop' it, as the -+ * data is already covered by other skb's in the reinject-queue. -+ * -+ * This is inspired by code from tcp_data_queue. -+ */ -+ -+ skb1 = skb_peek_tail(&mpcb->reinject_queue); -+ seq = TCP_SKB_CB(skb)->seq; -+ while (1) { -+ if (!after(TCP_SKB_CB(skb1)->seq, seq)) -+ break; -+ if (skb_queue_is_first(&mpcb->reinject_queue, skb1)) { -+ skb1 = NULL; -+ break; -+ } -+ skb1 = skb_queue_prev(&mpcb->reinject_queue, skb1); -+ } -+ -+ /* Do skb overlap to previous one? */ -+ end_seq = TCP_SKB_CB(skb)->end_seq; -+ if (skb1 && before(seq, TCP_SKB_CB(skb1)->end_seq)) { -+ if (!after(end_seq, TCP_SKB_CB(skb1)->end_seq)) { -+ /* All the bits are present. Don't reinject */ -+ __kfree_skb(skb); -+ return; -+ } -+ if (seq == TCP_SKB_CB(skb1)->seq) { -+ if (skb_queue_is_first(&mpcb->reinject_queue, skb1)) -+ skb1 = NULL; -+ else -+ skb1 = skb_queue_prev(&mpcb->reinject_queue, skb1); -+ } -+ } -+ if (!skb1) -+ __skb_queue_head(&mpcb->reinject_queue, skb); -+ else -+ __skb_queue_after(&mpcb->reinject_queue, skb1, skb); -+ -+ /* And clean segments covered by new one as whole. */ -+ while (!skb_queue_is_last(&mpcb->reinject_queue, skb)) { -+ skb1 = skb_queue_next(&mpcb->reinject_queue, skb); -+ -+ if (!after(end_seq, TCP_SKB_CB(skb1)->seq)) -+ break; -+ -+ if (before(end_seq, TCP_SKB_CB(skb1)->end_seq)) -+ break; -+ -+ __skb_unlink(skb1, &mpcb->reinject_queue); -+ __kfree_skb(skb1); -+ } -+ return; -+} -+ -+/* Inserts data into the reinject queue */ -+void mptcp_reinject_data(struct sock *sk, int clone_it) -+{ -+ struct sock *meta_sk = mptcp_meta_sk(sk); -+ struct sk_buff *skb_it, *tmp; -+ enum tcp_queue tcp_queue; -+ -+ /* It has already been closed - there is really no point in reinjecting */ -+ if (meta_sk->sk_state == TCP_CLOSE) -+ return; -+ -+ skb_queue_walk_safe(&sk->sk_write_queue, skb_it, tmp) { -+ struct tcp_skb_cb *tcb = TCP_SKB_CB(skb_it); -+ /* Subflow syn's and fin's are not reinjected. -+ * -+ * As well as empty subflow-fins with a data-fin. -+ * They are reinjected below (without the subflow-fin-flag) -+ */ -+ if (tcb->tcp_flags & TCPHDR_SYN || -+ (tcb->tcp_flags & TCPHDR_FIN && !mptcp_is_data_fin(skb_it)) || -+ (tcb->tcp_flags & TCPHDR_FIN && mptcp_is_data_fin(skb_it) && !skb_it->len)) -+ continue; -+ -+ if (mptcp_is_reinjected(skb_it)) -+ continue; -+ -+ tcb->mptcp_flags |= MPTCP_REINJECT; -+ __mptcp_reinject_data(skb_it, meta_sk, sk, clone_it, -+ TCP_FRAG_IN_WRITE_QUEUE); -+ } -+ -+ skb_it = tcp_rtx_queue_head(sk); -+ skb_rbtree_walk_from_safe(skb_it, tmp) { -+ struct tcp_skb_cb *tcb = TCP_SKB_CB(skb_it); -+ -+ /* Subflow syn's and fin's are not reinjected. -+ * -+ * As well as empty subflow-fins with a data-fin. -+ * They are reinjected below (without the subflow-fin-flag) -+ */ -+ if (tcb->tcp_flags & TCPHDR_SYN || -+ (tcb->tcp_flags & TCPHDR_FIN && !mptcp_is_data_fin(skb_it)) || -+ (tcb->tcp_flags & TCPHDR_FIN && mptcp_is_data_fin(skb_it) && !skb_it->len)) -+ continue; -+ -+ if (mptcp_is_reinjected(skb_it)) -+ continue; -+ -+ tcb->mptcp_flags |= MPTCP_REINJECT; -+ __mptcp_reinject_data(skb_it, meta_sk, sk, clone_it, -+ TCP_FRAG_IN_RTX_QUEUE); -+ } -+ -+ skb_it = tcp_write_queue_tail(meta_sk); -+ tcp_queue = TCP_FRAG_IN_WRITE_QUEUE; -+ -+ if (!skb_it) { -+ skb_it = skb_rb_last(&meta_sk->tcp_rtx_queue); -+ tcp_queue = TCP_FRAG_IN_RTX_QUEUE; -+ } -+ -+ /* If sk has sent the empty data-fin, we have to reinject it too. */ -+ if (skb_it && mptcp_is_data_fin(skb_it) && skb_it->len == 0 && -+ TCP_SKB_CB(skb_it)->path_mask & mptcp_pi_to_flag(tcp_sk(sk)->mptcp->path_index)) { -+ __mptcp_reinject_data(skb_it, meta_sk, NULL, 1, tcp_queue); -+ } -+ -+ tcp_sk(sk)->pf = 1; -+ -+ mptcp_push_pending_frames(meta_sk); -+} -+EXPORT_SYMBOL(mptcp_reinject_data); -+ -+static void mptcp_combine_dfin(const struct sk_buff *skb, -+ const struct sock *meta_sk, -+ struct sock *subsk) -+{ -+ const struct tcp_sock *meta_tp = tcp_sk(meta_sk); -+ const struct mptcp_cb *mpcb = meta_tp->mpcb; -+ -+ /* In infinite mapping we always try to combine */ -+ if (mpcb->infinite_mapping_snd) -+ goto combine; -+ -+ /* Don't combine, if they didn't combine when closing - otherwise we end -+ * up in TIME_WAIT, even if our app is smart enough to avoid it. -+ */ -+ if (!mptcp_sk_can_recv(meta_sk) && !mpcb->dfin_combined) -+ return; -+ -+ /* Don't combine if there is still outstanding data that remains to be -+ * DATA_ACKed, because otherwise we may never be able to deliver this. -+ */ -+ if (meta_tp->snd_una != TCP_SKB_CB(skb)->seq) -+ return; -+ -+combine: -+ if (tcp_close_state(subsk)) { -+ subsk->sk_shutdown |= SEND_SHUTDOWN; -+ TCP_SKB_CB(skb)->tcp_flags |= TCPHDR_FIN; -+ } -+} -+ -+static int mptcp_write_dss_mapping(const struct tcp_sock *tp, const struct sk_buff *skb, -+ __be32 *ptr) -+{ -+ const struct tcp_skb_cb *tcb = TCP_SKB_CB(skb); -+ __be32 *start = ptr; -+ __u16 data_len; -+ -+ *ptr++ = htonl(tcb->seq); /* data_seq */ -+ -+ /* If it's a non-data DATA_FIN, we set subseq to 0 (draft v7) */ -+ if (mptcp_is_data_fin(skb) && skb->len == 0) -+ *ptr++ = 0; /* subseq */ -+ else -+ *ptr++ = htonl(tp->write_seq - tp->mptcp->snt_isn); /* subseq */ -+ -+ if (tcb->mptcp_flags & MPTCPHDR_INF) -+ data_len = 0; -+ else -+ data_len = tcb->end_seq - tcb->seq; -+ -+ if (tp->mpcb->dss_csum && data_len) { -+ __sum16 *p16 = (__sum16 *)ptr; -+ __be32 hdseq = mptcp_get_highorder_sndbits(skb, tp->mpcb); -+ __wsum csum; -+ -+ *ptr = htonl(((data_len) << 16) | -+ (TCPOPT_EOL << 8) | -+ (TCPOPT_EOL)); -+ csum = csum_partial(ptr - 2, 12, skb->csum); -+ p16++; -+ *p16++ = csum_fold(csum_partial(&hdseq, sizeof(hdseq), csum)); -+ } else { -+ *ptr++ = htonl(((data_len) << 16) | -+ (TCPOPT_NOP << 8) | -+ (TCPOPT_NOP)); -+ } -+ -+ return ptr - start; -+} -+ -+static int mptcp_write_dss_data_ack(const struct tcp_sock *tp, const struct sk_buff *skb, -+ __be32 *ptr) -+{ -+ struct mp_dss *mdss = (struct mp_dss *)ptr; -+ __be32 *start = ptr; -+ -+ mdss->kind = TCPOPT_MPTCP; -+ mdss->sub = MPTCP_SUB_DSS; -+ mdss->rsv1 = 0; -+ mdss->rsv2 = 0; -+ mdss->F = mptcp_is_data_fin(skb) ? 1 : 0; -+ mdss->m = 0; -+ mdss->M = mptcp_is_data_seq(skb) ? 1 : 0; -+ mdss->a = 0; -+ mdss->A = 1; -+ mdss->len = mptcp_sub_len_dss(mdss, tp->mpcb->dss_csum); -+ ptr++; -+ -+ *ptr++ = htonl(mptcp_meta_tp(tp)->rcv_nxt); -+ -+ return ptr - start; -+} -+ -+/* RFC6824 states that once a particular subflow mapping has been sent -+ * out it must never be changed. However, packets may be split while -+ * they are in the retransmission queue (due to SACK or ACKs) and that -+ * arguably means that we would change the mapping (e.g. it splits it, -+ * our sends out a subset of the initial mapping). -+ * -+ * Furthermore, the skb checksum is not always preserved across splits -+ * (e.g. mptcp_fragment) which would mean that we need to recompute -+ * the DSS checksum in this case. -+ * -+ * To avoid this we save the initial DSS mapping which allows us to -+ * send the same DSS mapping even for fragmented retransmits. -+ */ -+static void mptcp_save_dss_data_seq(const struct tcp_sock *tp, struct sk_buff *skb) -+{ -+ struct tcp_skb_cb *tcb = TCP_SKB_CB(skb); -+ __be32 *ptr = (__be32 *)tcb->dss; -+ -+ tcb->mptcp_flags |= MPTCPHDR_SEQ; -+ -+ ptr += mptcp_write_dss_data_ack(tp, skb, ptr); -+ ptr += mptcp_write_dss_mapping(tp, skb, ptr); -+} -+ -+/* Write the saved DSS mapping to the header */ -+static int mptcp_write_dss_data_seq(const struct tcp_sock *tp, struct sk_buff *skb, -+ __be32 *ptr) -+{ -+ __be32 *start = ptr; -+ -+ memcpy(ptr, TCP_SKB_CB(skb)->dss, mptcp_dss_len); -+ -+ /* update the data_ack */ -+ start[1] = htonl(mptcp_meta_tp(tp)->rcv_nxt); -+ -+ /* dss is in a union with inet_skb_parm and -+ * the IP layer expects zeroed IPCB fields. -+ */ -+ memset(TCP_SKB_CB(skb)->dss, 0 , mptcp_dss_len); -+ -+ return mptcp_dss_len/sizeof(*ptr); -+} -+ -+static bool mptcp_skb_entail(struct sock *sk, struct sk_buff *skb, int reinject) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ const struct sock *meta_sk = mptcp_meta_sk(sk); -+ const struct mptcp_cb *mpcb = tp->mpcb; -+ struct tcp_skb_cb *tcb; -+ struct sk_buff *subskb = NULL; -+ -+ if (!reinject) -+ TCP_SKB_CB(skb)->mptcp_flags |= (mpcb->snd_hiseq_index ? -+ MPTCPHDR_SEQ64_INDEX : 0); -+ -+ tcp_skb_tsorted_save(skb) { -+ subskb = pskb_copy_for_clone(skb, GFP_ATOMIC); -+ } tcp_skb_tsorted_restore(skb); -+ if (!subskb) -+ return false; -+ -+ /* At the subflow-level we need to call again tcp_init_tso_segs. We -+ * force this, by setting pcount to 0. It has been set to 1 prior to -+ * the call to mptcp_skb_entail. -+ */ -+ tcp_skb_pcount_set(subskb, 0); -+ -+ TCP_SKB_CB(skb)->path_mask |= mptcp_pi_to_flag(tp->mptcp->path_index); -+ -+ /* Compute checksum */ -+ if (tp->mpcb->dss_csum) -+ subskb->csum = skb->csum = skb_checksum(skb, 0, skb->len, 0); -+ -+ tcb = TCP_SKB_CB(subskb); -+ -+ if (tp->mpcb->send_infinite_mapping && -+ !tp->mpcb->infinite_mapping_snd && -+ !before(tcb->seq, mptcp_meta_tp(tp)->snd_nxt)) { -+ tp->mptcp->fully_established = 1; -+ tp->mpcb->infinite_mapping_snd = 1; -+ tp->mptcp->infinite_cutoff_seq = tp->write_seq; -+ tcb->mptcp_flags |= MPTCPHDR_INF; -+ } -+ -+ if (mptcp_is_data_fin(subskb)) -+ mptcp_combine_dfin(subskb, meta_sk, sk); -+ -+ mptcp_save_dss_data_seq(tp, subskb); -+ -+ tcb->seq = tp->write_seq; -+ -+ /* Take into account seg len */ -+ tp->write_seq += subskb->len + ((tcb->tcp_flags & TCPHDR_FIN) ? 1 : 0); -+ tcb->end_seq = tp->write_seq; -+ -+ /* If it's a non-payload DATA_FIN (also no subflow-fin), the -+ * segment is not part of the subflow but on a meta-only-level. -+ */ -+ if (!mptcp_is_data_fin(subskb) || tcb->end_seq != tcb->seq) { -+ /* Make sure that this list is clean */ -+ INIT_LIST_HEAD(&subskb->tcp_tsorted_anchor); -+ -+ tcp_add_write_queue_tail(sk, subskb); -+ sk->sk_wmem_queued += subskb->truesize; -+ sk_mem_charge(sk, subskb->truesize); -+ } else { -+ /* Necessary to initialize for tcp_transmit_skb. mss of 1, as -+ * skb->len = 0 will force tso_segs to 1. -+ */ -+ tcp_init_tso_segs(subskb, 1); -+ -+ /* Empty data-fins are sent immediatly on the subflow */ -+ if (tcp_transmit_skb(sk, subskb, 0, GFP_ATOMIC)) -+ return false; -+ } -+ -+ if (!tp->mptcp->fully_established) { -+ tp->mptcp->second_packet = 1; -+ tp->mptcp->last_end_data_seq = TCP_SKB_CB(skb)->end_seq; -+ } -+ -+ return true; -+} -+ -+/* Fragment an skb and update the mptcp meta-data. Due to reinject, we -+ * might need to undo some operations done by tcp_fragment. -+ * -+ * Be careful, the skb may come from 3 different places: -+ * - The send-queue (tcp_queue == TCP_FRAG_IN_WRITE_QUEUE) -+ * - The retransmit-queue (tcp_queue == TCP_FRAG_IN_RTX_QUEUE) -+ * - The reinject-queue (reinject == -1) -+ */ -+static int mptcp_fragment(struct sock *meta_sk, enum tcp_queue tcp_queue, -+ struct sk_buff *skb, u32 len, -+ gfp_t gfp, int reinject) -+{ -+ int ret, diff, old_factor; -+ struct sk_buff *buff; -+ u8 flags; -+ -+ if (skb_headlen(skb) < len) -+ diff = skb->len - len; -+ else -+ diff = skb->data_len; -+ old_factor = tcp_skb_pcount(skb); -+ -+ /* The mss_now in tcp_fragment is used to set the tso_segs of the skb. -+ * At the MPTCP-level we do not care about the absolute value. All we -+ * care about is that it is set to 1 for accurate packets_out -+ * accounting. -+ */ -+ ret = tcp_fragment(meta_sk, tcp_queue, skb, len, UINT_MAX, gfp); -+ if (ret) -+ return ret; -+ -+ if (tcp_queue == TCP_FRAG_IN_WRITE_QUEUE) -+ buff = skb->next; -+ else -+ buff = skb_rb_next(skb); -+ -+ flags = TCP_SKB_CB(skb)->mptcp_flags; -+ TCP_SKB_CB(skb)->mptcp_flags = flags & ~(MPTCPHDR_FIN); -+ TCP_SKB_CB(buff)->mptcp_flags = flags; -+ TCP_SKB_CB(buff)->path_mask = TCP_SKB_CB(skb)->path_mask; -+ -+ /* If reinject == 1, the buff will be added to the reinject -+ * queue, which is currently not part of memory accounting. So -+ * undo the changes done by tcp_fragment and update the -+ * reinject queue. Also, undo changes to the packet counters. -+ */ -+ if (reinject == 1) { -+ int undo = buff->truesize - diff; -+ meta_sk->sk_wmem_queued -= undo; -+ sk_mem_uncharge(meta_sk, undo); -+ -+ tcp_sk(meta_sk)->mpcb->reinject_queue.qlen++; -+ if (tcp_queue == TCP_FRAG_IN_WRITE_QUEUE) -+ meta_sk->sk_write_queue.qlen--; -+ -+ if (!before(tcp_sk(meta_sk)->snd_nxt, TCP_SKB_CB(buff)->end_seq)) { -+ undo = old_factor - tcp_skb_pcount(skb) - -+ tcp_skb_pcount(buff); -+ if (undo) -+ tcp_adjust_pcount(meta_sk, skb, -undo); -+ } -+ -+ /* tcp_fragment's call to sk_stream_alloc_skb initializes the -+ * tcp_tsorted_anchor. We need to revert this as it clashes -+ * with the refdst pointer. -+ */ -+ tcp_skb_tsorted_anchor_cleanup(buff); -+ } -+ -+ return 0; -+} -+ -+/* Inspired by tcp_write_wakeup */ -+int mptcp_write_wakeup(struct sock *meta_sk, int mib) -+{ -+ struct tcp_sock *meta_tp = tcp_sk(meta_sk); -+ struct sk_buff *skb; -+ int ans = 0; -+ -+ if (meta_sk->sk_state == TCP_CLOSE) -+ return -1; -+ -+ skb = tcp_send_head(meta_sk); -+ if (skb && -+ before(TCP_SKB_CB(skb)->seq, tcp_wnd_end(meta_tp))) { -+ unsigned int mss; -+ unsigned int seg_size = tcp_wnd_end(meta_tp) - TCP_SKB_CB(skb)->seq; -+ struct sock *subsk = meta_tp->mpcb->sched_ops->get_subflow(meta_sk, skb, true); -+ struct tcp_sock *subtp; -+ -+ WARN_ON(TCP_SKB_CB(skb)->sacked); -+ -+ if (!subsk) -+ goto window_probe; -+ subtp = tcp_sk(subsk); -+ mss = tcp_current_mss(subsk); -+ -+ seg_size = min(tcp_wnd_end(meta_tp) - TCP_SKB_CB(skb)->seq, -+ tcp_wnd_end(subtp) - subtp->write_seq); -+ -+ if (before(meta_tp->pushed_seq, TCP_SKB_CB(skb)->end_seq)) -+ meta_tp->pushed_seq = TCP_SKB_CB(skb)->end_seq; -+ -+ /* We are probing the opening of a window -+ * but the window size is != 0 -+ * must have been a result SWS avoidance ( sender ) -+ */ -+ if (seg_size < TCP_SKB_CB(skb)->end_seq - TCP_SKB_CB(skb)->seq || -+ skb->len > mss) { -+ seg_size = min(seg_size, mss); -+ TCP_SKB_CB(skb)->tcp_flags |= TCPHDR_PSH; -+ if (mptcp_fragment(meta_sk, TCP_FRAG_IN_WRITE_QUEUE, -+ skb, seg_size, GFP_ATOMIC, 0)) -+ return -1; -+ } else if (!tcp_skb_pcount(skb)) { -+ /* see mptcp_write_xmit on why we use UINT_MAX */ -+ tcp_set_skb_tso_segs(skb, UINT_MAX); -+ } -+ -+ TCP_SKB_CB(skb)->tcp_flags |= TCPHDR_PSH; -+ if (!mptcp_skb_entail(subsk, skb, 0)) -+ return -1; -+ -+ mptcp_check_sndseq_wrap(meta_tp, TCP_SKB_CB(skb)->end_seq - -+ TCP_SKB_CB(skb)->seq); -+ tcp_event_new_data_sent(meta_sk, skb); -+ -+ __tcp_push_pending_frames(subsk, mss, TCP_NAGLE_PUSH); -+ tcp_update_skb_after_send(meta_tp, skb); -+ meta_tp->lsndtime = tcp_jiffies32; -+ -+ return 0; -+ } else { -+ struct mptcp_tcp_sock *mptcp; -+ -+window_probe: -+ if (between(meta_tp->snd_up, meta_tp->snd_una + 1, -+ meta_tp->snd_una + 0xFFFF)) { -+ mptcp_for_each_sub(meta_tp->mpcb, mptcp) { -+ struct sock *sk_it = mptcp_to_sock(mptcp); -+ -+ if (mptcp_sk_can_send_ack(sk_it)) -+ tcp_xmit_probe_skb(sk_it, 1, mib); -+ } -+ } -+ -+ /* At least one of the tcp_xmit_probe_skb's has to succeed */ -+ mptcp_for_each_sub(meta_tp->mpcb, mptcp) { -+ struct sock *sk_it = mptcp_to_sock(mptcp); -+ int ret; -+ -+ if (!mptcp_sk_can_send_ack(sk_it)) -+ continue; -+ -+ ret = tcp_xmit_probe_skb(sk_it, 0, mib); -+ if (unlikely(ret > 0)) -+ ans = ret; -+ } -+ return ans; -+ } -+} -+ -+bool mptcp_write_xmit(struct sock *meta_sk, unsigned int mss_now, int nonagle, -+ int push_one, gfp_t gfp) -+{ -+ struct tcp_sock *meta_tp = tcp_sk(meta_sk), *subtp; -+ struct mptcp_tcp_sock *mptcp; -+ struct sock *subsk = NULL; -+ struct mptcp_cb *mpcb = meta_tp->mpcb; -+ struct sk_buff *skb; -+ int reinject = 0; -+ unsigned int sublimit; -+ __u32 path_mask = 0; -+ -+ tcp_mstamp_refresh(meta_tp); -+ -+ if (inet_csk(meta_sk)->icsk_retransmits) { -+ /* If the timer already once fired, retransmit the head of the -+ * queue to unblock us ASAP. -+ */ -+ if (meta_tp->packets_out && !mpcb->infinite_mapping_snd) -+ mptcp_retransmit_skb(meta_sk, tcp_rtx_queue_head(meta_sk)); -+ } -+ -+ while ((skb = mpcb->sched_ops->next_segment(meta_sk, &reinject, &subsk, -+ &sublimit))) { -+ enum tcp_queue tcp_queue = TCP_FRAG_IN_WRITE_QUEUE; -+ unsigned int limit; -+ -+ WARN(TCP_SKB_CB(skb)->sacked, "sacked: %u reinject: %u", -+ TCP_SKB_CB(skb)->sacked, reinject); -+ -+ subtp = tcp_sk(subsk); -+ mss_now = tcp_current_mss(subsk); -+ -+ if (reinject == 1) { -+ if (!after(TCP_SKB_CB(skb)->end_seq, meta_tp->snd_una)) { -+ /* Segment already reached the peer, take the next one */ -+ __skb_unlink(skb, &mpcb->reinject_queue); -+ __kfree_skb(skb); -+ continue; -+ } -+ } else if (reinject == -1) { -+ tcp_queue = TCP_FRAG_IN_RTX_QUEUE; -+ } -+ -+ /* If the segment was cloned (e.g. a meta retransmission), -+ * the header must be expanded/copied so that there is no -+ * corruption of TSO information. -+ */ -+ if (skb_unclone(skb, GFP_ATOMIC)) -+ break; -+ -+ if (unlikely(!tcp_snd_wnd_test(meta_tp, skb, mss_now))) -+ break; -+ -+ /* Force tso_segs to 1 by using UINT_MAX. -+ * We actually don't care about the exact number of segments -+ * emitted on the subflow. We need just to set tso_segs, because -+ * we still need an accurate packets_out count in -+ * tcp_event_new_data_sent. -+ */ -+ tcp_set_skb_tso_segs(skb, UINT_MAX); -+ -+ /* Check for nagle, irregardless of tso_segs. If the segment is -+ * actually larger than mss_now (TSO segment), then -+ * tcp_nagle_check will have partial == false and always trigger -+ * the transmission. -+ * tcp_write_xmit has a TSO-level nagle check which is not -+ * subject to the MPTCP-level. It is based on the properties of -+ * the subflow, not the MPTCP-level. -+ * When the segment is a reinjection or redundant scheduled -+ * segment, nagle check at meta-level may prevent -+ * sending. This could hurt with certain schedulers, as they -+ * to reinjection to recover from a window-stall or reduce latency. -+ * Therefore, Nagle check should be disabled in that case. -+ */ -+ if (!reinject && -+ unlikely(!tcp_nagle_test(meta_tp, skb, mss_now, -+ (tcp_skb_is_last(meta_sk, skb) ? -+ nonagle : TCP_NAGLE_PUSH)))) -+ break; -+ -+ limit = mss_now; -+ /* skb->len > mss_now is the equivalent of tso_segs > 1 in -+ * tcp_write_xmit. Otherwise split-point would return 0. -+ */ -+ if (skb->len > mss_now && !tcp_urg_mode(meta_tp)) -+ /* We limit the size of the skb so that it fits into the -+ * window. Call tcp_mss_split_point to avoid duplicating -+ * code. -+ * We really only care about fitting the skb into the -+ * window. That's why we use UINT_MAX. If the skb does -+ * not fit into the cwnd_quota or the NIC's max-segs -+ * limitation, it will be split by the subflow's -+ * tcp_write_xmit which does the appropriate call to -+ * tcp_mss_split_point. -+ */ -+ limit = tcp_mss_split_point(meta_sk, skb, mss_now, -+ UINT_MAX / mss_now, -+ nonagle); -+ -+ if (sublimit) -+ limit = min(limit, sublimit); -+ -+ if (skb->len > limit && -+ unlikely(mptcp_fragment(meta_sk, tcp_queue, -+ skb, limit, gfp, reinject))) -+ break; -+ -+ if (!mptcp_skb_entail(subsk, skb, reinject)) -+ break; -+ /* Nagle is handled at the MPTCP-layer, so -+ * always push on the subflow -+ */ -+ __tcp_push_pending_frames(subsk, mss_now, TCP_NAGLE_PUSH); -+ if (reinject <= 0) -+ tcp_update_skb_after_send(meta_tp, skb); -+ meta_tp->lsndtime = tcp_jiffies32; -+ -+ path_mask |= mptcp_pi_to_flag(subtp->mptcp->path_index); -+ -+ if (!reinject) { -+ mptcp_check_sndseq_wrap(meta_tp, -+ TCP_SKB_CB(skb)->end_seq - -+ TCP_SKB_CB(skb)->seq); -+ tcp_event_new_data_sent(meta_sk, skb); -+ } -+ -+ tcp_minshall_update(meta_tp, mss_now, skb); -+ -+ if (reinject > 0) { -+ __skb_unlink(skb, &mpcb->reinject_queue); -+ kfree_skb(skb); -+ } -+ -+ if (push_one) -+ break; -+ } -+ -+ mptcp_for_each_sub(mpcb, mptcp) { -+ subsk = mptcp_to_sock(mptcp); -+ subtp = tcp_sk(subsk); -+ -+ if (!(path_mask & mptcp_pi_to_flag(subtp->mptcp->path_index))) -+ continue; -+ -+ /* We have pushed data on this subflow. We ignore the call to -+ * cwnd_validate in tcp_write_xmit as is_cwnd_limited will never -+ * be true (we never push more than what the cwnd can accept). -+ * We need to ensure that we call tcp_cwnd_validate with -+ * is_cwnd_limited set to true if we have filled the cwnd. -+ */ -+ tcp_cwnd_validate(subsk, tcp_packets_in_flight(subtp) >= -+ subtp->snd_cwnd); -+ } -+ -+ return !meta_tp->packets_out && tcp_send_head(meta_sk); -+} -+ -+void mptcp_write_space(struct sock *sk) -+{ -+ mptcp_push_pending_frames(mptcp_meta_sk(sk)); -+} -+ -+u32 __mptcp_select_window(struct sock *sk) -+{ -+ struct inet_connection_sock *icsk = inet_csk(sk); -+ struct tcp_sock *tp = tcp_sk(sk), *meta_tp = mptcp_meta_tp(tp); -+ struct sock *meta_sk = mptcp_meta_sk(sk); -+ int mss, free_space, full_space, window; -+ -+ /* MSS for the peer's data. Previous versions used mss_clamp -+ * here. I don't know if the value based on our guesses -+ * of peer's MSS is better for the performance. It's more correct -+ * but may be worse for the performance because of rcv_mss -+ * fluctuations. --SAW 1998/11/1 -+ */ -+ mss = icsk->icsk_ack.rcv_mss; -+ free_space = tcp_space(meta_sk); -+ full_space = min_t(int, meta_tp->window_clamp, -+ tcp_full_space(meta_sk)); -+ -+ if (mss > full_space) -+ mss = full_space; -+ -+ if (free_space < (full_space >> 1)) { -+ /* If free_space is decreasing due to mostly meta-level -+ * out-of-order packets, don't turn off the quick-ack mode. -+ */ -+ if (meta_tp->rcv_nxt - meta_tp->copied_seq > ((full_space - free_space) >> 1)) -+ icsk->icsk_ack.quick = 0; -+ -+ if (tcp_memory_pressure) -+ /* TODO this has to be adapted when we support different -+ * MSS's among the subflows. -+ */ -+ meta_tp->rcv_ssthresh = min(meta_tp->rcv_ssthresh, -+ 4U * meta_tp->advmss); -+ -+ if (free_space < mss) -+ return 0; -+ } -+ -+ if (free_space > meta_tp->rcv_ssthresh) -+ free_space = meta_tp->rcv_ssthresh; -+ -+ /* Don't do rounding if we are using window scaling, since the -+ * scaled window will not line up with the MSS boundary anyway. -+ */ -+ window = meta_tp->rcv_wnd; -+ if (tp->rx_opt.rcv_wscale) { -+ window = free_space; -+ -+ /* Advertise enough space so that it won't get scaled away. -+ * Import case: prevent zero window announcement if -+ * 1< mss. -+ */ -+ if (((window >> tp->rx_opt.rcv_wscale) << tp-> -+ rx_opt.rcv_wscale) != window) -+ window = (((window >> tp->rx_opt.rcv_wscale) + 1) -+ << tp->rx_opt.rcv_wscale); -+ } else { -+ /* Get the largest window that is a nice multiple of mss. -+ * Window clamp already applied above. -+ * If our current window offering is within 1 mss of the -+ * free space we just keep it. This prevents the divide -+ * and multiply from happening most of the time. -+ * We also don't do any window rounding when the free space -+ * is too small. -+ */ -+ if (window <= free_space - mss || window > free_space) -+ window = (free_space / mss) * mss; -+ else if (mss == full_space && -+ free_space > window + (full_space >> 1)) -+ window = free_space; -+ } -+ -+ return window; -+} -+ -+void mptcp_syn_options(const struct sock *sk, struct tcp_out_options *opts, -+ unsigned *remaining) -+{ -+ const struct tcp_sock *tp = tcp_sk(sk); -+ -+ opts->options |= OPTION_MPTCP; -+ if (is_master_tp(tp)) { -+ opts->mptcp_options |= OPTION_MP_CAPABLE | OPTION_TYPE_SYN; -+ opts->mptcp_ver = tcp_sk(sk)->mptcp_ver; -+ *remaining -= MPTCP_SUB_LEN_CAPABLE_SYN_ALIGN; -+ opts->mp_capable.sender_key = tp->mptcp_loc_key; -+ opts->dss_csum = !!sysctl_mptcp_checksum; -+ } else { -+ const struct mptcp_cb *mpcb = tp->mpcb; -+ -+ opts->mptcp_options |= OPTION_MP_JOIN | OPTION_TYPE_SYN; -+ *remaining -= MPTCP_SUB_LEN_JOIN_SYN_ALIGN; -+ opts->mp_join_syns.token = mpcb->mptcp_rem_token; -+ opts->mp_join_syns.low_prio = tp->mptcp->low_prio; -+ opts->addr_id = tp->mptcp->loc_id; -+ opts->mp_join_syns.sender_nonce = tp->mptcp->mptcp_loc_nonce; -+ } -+} -+ -+void mptcp_synack_options(struct request_sock *req, -+ struct tcp_out_options *opts, unsigned *remaining) -+{ -+ struct mptcp_request_sock *mtreq; -+ mtreq = mptcp_rsk(req); -+ -+ opts->options |= OPTION_MPTCP; -+ /* MPCB not yet set - thus it's a new MPTCP-session */ -+ if (!mtreq->is_sub) { -+ opts->mptcp_options |= OPTION_MP_CAPABLE | OPTION_TYPE_SYNACK; -+ opts->mptcp_ver = mtreq->mptcp_ver; -+ opts->mp_capable.sender_key = mtreq->mptcp_loc_key; -+ opts->dss_csum = !!sysctl_mptcp_checksum || mtreq->dss_csum; -+ *remaining -= MPTCP_SUB_LEN_CAPABLE_SYN_ALIGN; -+ } else { -+ opts->mptcp_options |= OPTION_MP_JOIN | OPTION_TYPE_SYNACK; -+ opts->mp_join_syns.sender_truncated_mac = -+ mtreq->mptcp_hash_tmac; -+ opts->mp_join_syns.sender_nonce = mtreq->mptcp_loc_nonce; -+ opts->mp_join_syns.low_prio = mtreq->low_prio; -+ opts->addr_id = mtreq->loc_id; -+ *remaining -= MPTCP_SUB_LEN_JOIN_SYNACK_ALIGN; -+ } -+} -+ -+void mptcp_established_options(struct sock *sk, struct sk_buff *skb, -+ struct tcp_out_options *opts, unsigned *size) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct mptcp_cb *mpcb = tp->mpcb; -+ const struct tcp_skb_cb *tcb = skb ? TCP_SKB_CB(skb) : NULL; -+ -+ /* We are coming from tcp_current_mss with the meta_sk as an argument. -+ * It does not make sense to check for the options, because when the -+ * segment gets sent, another subflow will be chosen. -+ */ -+ if (!skb && is_meta_sk(sk)) -+ return; -+ -+ if (unlikely(tp->send_mp_fclose)) { -+ opts->options |= OPTION_MPTCP; -+ opts->mptcp_options |= OPTION_MP_FCLOSE; -+ opts->mp_capable.receiver_key = mpcb->mptcp_rem_key; -+ *size += MPTCP_SUB_LEN_FCLOSE_ALIGN; -+ return; -+ } -+ -+ /* 1. If we are the sender of the infinite-mapping, we need the -+ * MPTCPHDR_INF-flag, because a retransmission of the -+ * infinite-announcment still needs the mptcp-option. -+ * -+ * We need infinite_cutoff_seq, because retransmissions from before -+ * the infinite-cutoff-moment still need the MPTCP-signalling to stay -+ * consistent. -+ * -+ * 2. If we are the receiver of the infinite-mapping, we always skip -+ * mptcp-options, because acknowledgments from before the -+ * infinite-mapping point have already been sent out. -+ * -+ * I know, the whole infinite-mapping stuff is ugly... -+ * -+ * TODO: Handle wrapped data-sequence numbers -+ * (even if it's very unlikely) -+ */ -+ if (unlikely(mpcb->infinite_mapping_snd) && -+ ((mpcb->send_infinite_mapping && tcb && -+ mptcp_is_data_seq(skb) && -+ !(tcb->mptcp_flags & MPTCPHDR_INF) && -+ !before(tcb->seq, tp->mptcp->infinite_cutoff_seq)) || -+ !mpcb->send_infinite_mapping)) -+ return; -+ -+ if (unlikely(tp->mptcp->include_mpc)) { -+ opts->options |= OPTION_MPTCP; -+ opts->mptcp_options |= OPTION_MP_CAPABLE | -+ OPTION_TYPE_ACK; -+ *size += MPTCP_SUB_LEN_CAPABLE_ACK_ALIGN; -+ opts->mptcp_ver = mpcb->mptcp_ver; -+ opts->mp_capable.sender_key = mpcb->mptcp_loc_key; -+ opts->mp_capable.receiver_key = mpcb->mptcp_rem_key; -+ opts->dss_csum = mpcb->dss_csum; -+ -+ if (skb) -+ tp->mptcp->include_mpc = 0; -+ } -+ if (unlikely(tp->mptcp->pre_established) && -+ (!skb || !(tcb->tcp_flags & (TCPHDR_FIN | TCPHDR_RST)))) { -+ opts->options |= OPTION_MPTCP; -+ opts->mptcp_options |= OPTION_MP_JOIN | OPTION_TYPE_ACK; -+ *size += MPTCP_SUB_LEN_JOIN_ACK_ALIGN; -+ } -+ -+ if (unlikely(mpcb->addr_signal) && mpcb->pm_ops->addr_signal && -+ mpcb->mptcp_ver >= MPTCP_VERSION_1 && skb && !mptcp_is_data_seq(skb)) { -+ mpcb->pm_ops->addr_signal(sk, size, opts, skb); -+ -+ if (opts->add_addr_v6) -+ /* Skip subsequent options */ -+ return; -+ } -+ -+ if (!tp->mptcp->include_mpc && !tp->mptcp->pre_established) { -+ opts->options |= OPTION_MPTCP; -+ opts->mptcp_options |= OPTION_DATA_ACK; -+ /* If !skb, we come from tcp_current_mss and thus we always -+ * assume that the DSS-option will be set for the data-packet. -+ */ -+ if (skb && !mptcp_is_data_seq(skb)) { -+ *size += MPTCP_SUB_LEN_ACK_ALIGN; -+ } else { -+ /* Doesn't matter, if csum included or not. It will be -+ * either 10 or 12, and thus aligned = 12 -+ */ -+ *size += MPTCP_SUB_LEN_ACK_ALIGN + -+ MPTCP_SUB_LEN_SEQ_ALIGN; -+ } -+ -+ *size += MPTCP_SUB_LEN_DSS_ALIGN; -+ } -+ -+ /* In fallback mp_fail-mode, we have to repeat it until the fallback -+ * has been done by the sender -+ */ -+ if (unlikely(tp->mptcp->send_mp_fail) && skb && -+ MAX_TCP_OPTION_SPACE - *size >= MPTCP_SUB_LEN_FAIL) { -+ opts->options |= OPTION_MPTCP; -+ opts->mptcp_options |= OPTION_MP_FAIL; -+ *size += MPTCP_SUB_LEN_FAIL; -+ } -+ -+ if (unlikely(mpcb->addr_signal) && mpcb->pm_ops->addr_signal && -+ mpcb->mptcp_ver < MPTCP_VERSION_1) -+ mpcb->pm_ops->addr_signal(sk, size, opts, skb); -+ -+ if (unlikely(tp->mptcp->send_mp_prio) && -+ MAX_TCP_OPTION_SPACE - *size >= MPTCP_SUB_LEN_PRIO_ALIGN) { -+ opts->options |= OPTION_MPTCP; -+ opts->mptcp_options |= OPTION_MP_PRIO; -+ if (skb) -+ tp->mptcp->send_mp_prio = 0; -+ *size += MPTCP_SUB_LEN_PRIO_ALIGN; -+ } -+ -+ return; -+} -+ -+u16 mptcp_select_window(struct sock *sk) -+{ -+ u16 new_win = tcp_select_window(sk); -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct tcp_sock *meta_tp = mptcp_meta_tp(tp); -+ -+ meta_tp->rcv_wnd = tp->rcv_wnd; -+ meta_tp->rcv_wup = meta_tp->rcv_nxt; -+ -+ return new_win; -+} -+ -+void mptcp_options_write(__be32 *ptr, struct tcp_sock *tp, -+ const struct tcp_out_options *opts, -+ struct sk_buff *skb) -+{ -+ if (unlikely(OPTION_MP_CAPABLE & opts->mptcp_options)) { -+ struct mp_capable *mpc = (struct mp_capable *)ptr; -+ -+ mpc->kind = TCPOPT_MPTCP; -+ -+ if ((OPTION_TYPE_SYN & opts->mptcp_options) || -+ (OPTION_TYPE_SYNACK & opts->mptcp_options)) { -+ mpc->sender_key = opts->mp_capable.sender_key; -+ mpc->len = MPTCP_SUB_LEN_CAPABLE_SYN; -+ mpc->ver = opts->mptcp_ver; -+ ptr += MPTCP_SUB_LEN_CAPABLE_SYN_ALIGN >> 2; -+ } else if (OPTION_TYPE_ACK & opts->mptcp_options) { -+ mpc->sender_key = opts->mp_capable.sender_key; -+ mpc->receiver_key = opts->mp_capable.receiver_key; -+ mpc->len = MPTCP_SUB_LEN_CAPABLE_ACK; -+ mpc->ver = opts->mptcp_ver; -+ ptr += MPTCP_SUB_LEN_CAPABLE_ACK_ALIGN >> 2; -+ } -+ -+ mpc->sub = MPTCP_SUB_CAPABLE; -+ mpc->a = opts->dss_csum; -+ mpc->b = 0; -+ mpc->rsv = 0; -+ mpc->h = 1; -+ } -+ if (unlikely(OPTION_MP_JOIN & opts->mptcp_options)) { -+ struct mp_join *mpj = (struct mp_join *)ptr; -+ -+ mpj->kind = TCPOPT_MPTCP; -+ mpj->sub = MPTCP_SUB_JOIN; -+ mpj->rsv = 0; -+ -+ if (OPTION_TYPE_SYN & opts->mptcp_options) { -+ mpj->len = MPTCP_SUB_LEN_JOIN_SYN; -+ mpj->u.syn.token = opts->mp_join_syns.token; -+ mpj->u.syn.nonce = opts->mp_join_syns.sender_nonce; -+ mpj->b = opts->mp_join_syns.low_prio; -+ mpj->addr_id = opts->addr_id; -+ ptr += MPTCP_SUB_LEN_JOIN_SYN_ALIGN >> 2; -+ } else if (OPTION_TYPE_SYNACK & opts->mptcp_options) { -+ mpj->len = MPTCP_SUB_LEN_JOIN_SYNACK; -+ mpj->u.synack.mac = -+ opts->mp_join_syns.sender_truncated_mac; -+ mpj->u.synack.nonce = opts->mp_join_syns.sender_nonce; -+ mpj->b = opts->mp_join_syns.low_prio; -+ mpj->addr_id = opts->addr_id; -+ ptr += MPTCP_SUB_LEN_JOIN_SYNACK_ALIGN >> 2; -+ } else if (OPTION_TYPE_ACK & opts->mptcp_options) { -+ mpj->len = MPTCP_SUB_LEN_JOIN_ACK; -+ mpj->addr_id = 0; /* addr_id is rsv (RFC 6824, p. 21) */ -+ memcpy(mpj->u.ack.mac, &tp->mptcp->sender_mac[0], 20); -+ ptr += MPTCP_SUB_LEN_JOIN_ACK_ALIGN >> 2; -+ } -+ } -+ if (unlikely(OPTION_ADD_ADDR & opts->mptcp_options)) { -+ struct mp_add_addr *mpadd = (struct mp_add_addr *)ptr; -+ struct mptcp_cb *mpcb = tp->mpcb; -+ -+ mpadd->kind = TCPOPT_MPTCP; -+ if (opts->add_addr_v4) { -+ mpadd->sub = MPTCP_SUB_ADD_ADDR; -+ mpadd->ipver = 4; -+ mpadd->addr_id = opts->add_addr4.addr_id; -+ mpadd->u.v4.addr = opts->add_addr4.addr; -+ if (mpcb->mptcp_ver < MPTCP_VERSION_1) { -+ mpadd->len = MPTCP_SUB_LEN_ADD_ADDR4; -+ ptr += MPTCP_SUB_LEN_ADD_ADDR4_ALIGN >> 2; -+ } else { -+ memcpy((char *)mpadd->u.v4.mac - 2, -+ (char *)&opts->add_addr4.trunc_mac, 8); -+ mpadd->len = MPTCP_SUB_LEN_ADD_ADDR4_VER1; -+ ptr += MPTCP_SUB_LEN_ADD_ADDR4_ALIGN_VER1 >> 2; -+ } -+ } else if (opts->add_addr_v6) { -+ mpadd->sub = MPTCP_SUB_ADD_ADDR; -+ mpadd->ipver = 6; -+ mpadd->addr_id = opts->add_addr6.addr_id; -+ memcpy(&mpadd->u.v6.addr, &opts->add_addr6.addr, -+ sizeof(mpadd->u.v6.addr)); -+ if (mpcb->mptcp_ver < MPTCP_VERSION_1) { -+ mpadd->len = MPTCP_SUB_LEN_ADD_ADDR6; -+ ptr += MPTCP_SUB_LEN_ADD_ADDR6_ALIGN >> 2; -+ } else { -+ memcpy((char *)mpadd->u.v6.mac - 2, -+ (char *)&opts->add_addr6.trunc_mac, 8); -+ mpadd->len = MPTCP_SUB_LEN_ADD_ADDR6_VER1; -+ ptr += MPTCP_SUB_LEN_ADD_ADDR6_ALIGN_VER1 >> 2; -+ } -+ } -+ -+ MPTCP_INC_STATS(sock_net((struct sock *)tp), MPTCP_MIB_ADDADDRTX); -+ } -+ if (unlikely(OPTION_REMOVE_ADDR & opts->mptcp_options)) { -+ struct mp_remove_addr *mprem = (struct mp_remove_addr *)ptr; -+ u8 *addrs_id; -+ int id, len, len_align; -+ -+ len = mptcp_sub_len_remove_addr(opts->remove_addrs); -+ len_align = mptcp_sub_len_remove_addr_align(opts->remove_addrs); -+ -+ mprem->kind = TCPOPT_MPTCP; -+ mprem->len = len; -+ mprem->sub = MPTCP_SUB_REMOVE_ADDR; -+ mprem->rsv = 0; -+ addrs_id = &mprem->addrs_id; -+ -+ mptcp_for_each_bit_set(opts->remove_addrs, id) -+ *(addrs_id++) = id; -+ -+ /* Fill the rest with NOP's */ -+ if (len_align > len) { -+ int i; -+ for (i = 0; i < len_align - len; i++) -+ *(addrs_id++) = TCPOPT_NOP; -+ } -+ -+ ptr += len_align >> 2; -+ -+ MPTCP_INC_STATS(sock_net((struct sock *)tp), MPTCP_MIB_REMADDRTX); -+ } -+ if (unlikely(OPTION_MP_FAIL & opts->mptcp_options)) { -+ struct mp_fail *mpfail = (struct mp_fail *)ptr; -+ -+ mpfail->kind = TCPOPT_MPTCP; -+ mpfail->len = MPTCP_SUB_LEN_FAIL; -+ mpfail->sub = MPTCP_SUB_FAIL; -+ mpfail->rsv1 = 0; -+ mpfail->rsv2 = 0; -+ mpfail->data_seq = htonll(tp->mpcb->csum_cutoff_seq); -+ -+ ptr += MPTCP_SUB_LEN_FAIL_ALIGN >> 2; -+ } -+ if (unlikely(OPTION_MP_FCLOSE & opts->mptcp_options)) { -+ struct mp_fclose *mpfclose = (struct mp_fclose *)ptr; -+ -+ mpfclose->kind = TCPOPT_MPTCP; -+ mpfclose->len = MPTCP_SUB_LEN_FCLOSE; -+ mpfclose->sub = MPTCP_SUB_FCLOSE; -+ mpfclose->rsv1 = 0; -+ mpfclose->rsv2 = 0; -+ mpfclose->key = opts->mp_capable.receiver_key; -+ -+ ptr += MPTCP_SUB_LEN_FCLOSE_ALIGN >> 2; -+ } -+ -+ if (OPTION_DATA_ACK & opts->mptcp_options) { -+ if (!mptcp_is_data_seq(skb)) -+ ptr += mptcp_write_dss_data_ack(tp, skb, ptr); -+ else -+ ptr += mptcp_write_dss_data_seq(tp, skb, ptr); -+ } -+ if (unlikely(OPTION_MP_PRIO & opts->mptcp_options)) { -+ struct mp_prio *mpprio = (struct mp_prio *)ptr; -+ -+ mpprio->kind = TCPOPT_MPTCP; -+ mpprio->len = MPTCP_SUB_LEN_PRIO; -+ mpprio->sub = MPTCP_SUB_PRIO; -+ mpprio->rsv = 0; -+ mpprio->b = tp->mptcp->low_prio; -+ mpprio->addr_id = TCPOPT_NOP; -+ -+ ptr += MPTCP_SUB_LEN_PRIO_ALIGN >> 2; -+ } -+} -+ -+/* Sends the datafin */ -+void mptcp_send_fin(struct sock *meta_sk) -+{ -+ struct sk_buff *skb, *tskb = tcp_write_queue_tail(meta_sk); -+ struct tcp_sock *meta_tp = tcp_sk(meta_sk); -+ int mss_now; -+ -+ if ((1 << meta_sk->sk_state) & (TCPF_CLOSE_WAIT | TCPF_LAST_ACK)) -+ meta_tp->mpcb->passive_close = 1; -+ -+ /* Optimization, tack on the FIN if we have a queue of -+ * unsent frames. But be careful about outgoing SACKS -+ * and IP options. -+ */ -+ mss_now = mptcp_current_mss(meta_sk); -+ -+ if (tskb) { -+ TCP_SKB_CB(tskb)->mptcp_flags |= MPTCPHDR_FIN; -+ TCP_SKB_CB(tskb)->end_seq++; -+ meta_tp->write_seq++; -+ } else { -+ /* Socket is locked, keep trying until memory is available. */ -+ for (;;) { -+ skb = alloc_skb_fclone(MAX_TCP_HEADER, -+ meta_sk->sk_allocation); -+ if (skb) -+ break; -+ yield(); -+ } -+ /* Reserve space for headers and prepare control bits. */ -+ INIT_LIST_HEAD(&skb->tcp_tsorted_anchor); -+ skb_reserve(skb, MAX_TCP_HEADER); -+ -+ tcp_init_nondata_skb(skb, meta_tp->write_seq, TCPHDR_ACK); -+ TCP_SKB_CB(skb)->end_seq++; -+ TCP_SKB_CB(skb)->mptcp_flags |= MPTCPHDR_FIN; -+ tcp_queue_skb(meta_sk, skb); -+ } -+ __tcp_push_pending_frames(meta_sk, mss_now, TCP_NAGLE_OFF); -+} -+ -+void mptcp_send_active_reset(struct sock *meta_sk, gfp_t priority) -+{ -+ struct tcp_sock *meta_tp = tcp_sk(meta_sk); -+ struct mptcp_cb *mpcb = meta_tp->mpcb; -+ struct sock *sk; -+ -+ if (hlist_empty(&mpcb->conn_list)) -+ return; -+ -+ WARN_ON(meta_tp->send_mp_fclose); -+ -+ /* First - select a socket */ -+ sk = mptcp_select_ack_sock(meta_sk); -+ -+ /* May happen if no subflow is in an appropriate state, OR -+ * we are in infinite mode or about to go there - just send a reset -+ */ -+ if (!sk || mptcp_in_infinite_mapping_weak(mpcb)) { -+ /* tcp_done must be handled with bh disabled */ -+ if (!in_serving_softirq()) -+ local_bh_disable(); -+ -+ mptcp_sub_force_close_all(mpcb, NULL); -+ -+ if (!in_serving_softirq()) -+ local_bh_enable(); -+ return; -+ } -+ -+ tcp_mstamp_refresh(meta_tp); -+ -+ tcp_sk(sk)->send_mp_fclose = 1; -+ /** Reset all other subflows */ -+ -+ /* tcp_done must be handled with bh disabled */ -+ if (!in_serving_softirq()) -+ local_bh_disable(); -+ -+ mptcp_sub_force_close_all(mpcb, sk); -+ -+ tcp_set_state(sk, TCP_RST_WAIT); -+ -+ if (!in_serving_softirq()) -+ local_bh_enable(); -+ -+ tcp_send_ack(sk); -+ tcp_clear_xmit_timers(sk); -+ inet_csk_reset_keepalive_timer(sk, inet_csk(sk)->icsk_rto); -+ -+ meta_tp->send_mp_fclose = 1; -+ inet_csk(sk)->icsk_retransmits = 0; -+ -+ /* Prevent exp backoff reverting on ICMP dest unreachable */ -+ inet_csk(sk)->icsk_backoff = 0; -+ -+ MPTCP_INC_STATS(sock_net(meta_sk), MPTCP_MIB_FASTCLOSETX); -+} -+ -+static void mptcp_ack_retransmit_timer(struct sock *sk) -+{ -+ struct inet_connection_sock *icsk = inet_csk(sk); -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct net *net = sock_net(sk); -+ struct sk_buff *skb; -+ -+ if (inet_csk(sk)->icsk_af_ops->rebuild_header(sk)) -+ goto out; /* Routing failure or similar */ -+ -+ tcp_mstamp_refresh(tp); -+ -+ if (tcp_write_timeout(sk)) { -+ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_JOINACKRTO); -+ tp->mptcp->pre_established = 0; -+ sk_stop_timer(sk, &tp->mptcp->mptcp_ack_timer); -+ tp->ops->send_active_reset(sk, GFP_ATOMIC); -+ goto out; -+ } -+ -+ skb = alloc_skb(MAX_TCP_HEADER, GFP_ATOMIC); -+ if (skb == NULL) { -+ sk_reset_timer(sk, &tp->mptcp->mptcp_ack_timer, -+ jiffies + icsk->icsk_rto); -+ return; -+ } -+ -+ /* Reserve space for headers and prepare control bits */ -+ skb_reserve(skb, MAX_TCP_HEADER); -+ tcp_init_nondata_skb(skb, tp->snd_una, TCPHDR_ACK); -+ -+ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_JOINACKRXMIT); -+ -+ if (tcp_transmit_skb(sk, skb, 0, GFP_ATOMIC) > 0) { -+ /* Retransmission failed because of local congestion, -+ * do not backoff. -+ */ -+ if (!icsk->icsk_retransmits) -+ icsk->icsk_retransmits = 1; -+ sk_reset_timer(sk, &tp->mptcp->mptcp_ack_timer, -+ jiffies + icsk->icsk_rto); -+ return; -+ } -+ -+ if (!tp->retrans_stamp) -+ tp->retrans_stamp = tcp_time_stamp(tp) ? : 1; -+ -+ icsk->icsk_retransmits++; -+ icsk->icsk_rto = min(icsk->icsk_rto << 1, TCP_RTO_MAX); -+ sk_reset_timer(sk, &tp->mptcp->mptcp_ack_timer, -+ jiffies + icsk->icsk_rto); -+ if (retransmits_timed_out(sk, net->ipv4.sysctl_tcp_retries1 + 1, 0)) -+ __sk_dst_reset(sk); -+ -+out:; -+} -+ -+void mptcp_ack_handler(struct timer_list *t) -+{ -+ struct mptcp_tcp_sock *mptcp = from_timer(mptcp, t, mptcp_ack_timer); -+ struct sock *sk = (struct sock *)mptcp->tp; -+ struct sock *meta_sk = mptcp_meta_sk(sk); -+ -+ bh_lock_sock(meta_sk); -+ if (sock_owned_by_user(meta_sk)) { -+ /* Try again later */ -+ sk_reset_timer(sk, &tcp_sk(sk)->mptcp->mptcp_ack_timer, -+ jiffies + (HZ / 20)); -+ goto out_unlock; -+ } -+ -+ if (sk->sk_state == TCP_CLOSE) -+ goto out_unlock; -+ if (!tcp_sk(sk)->mptcp->pre_established) -+ goto out_unlock; -+ -+ mptcp_ack_retransmit_timer(sk); -+ -+ sk_mem_reclaim(sk); -+ -+out_unlock: -+ bh_unlock_sock(meta_sk); -+ sock_put(sk); -+} -+ -+/* Similar to tcp_retransmit_skb -+ * -+ * The diff is that we handle the retransmission-stats (retrans_stamp) at the -+ * meta-level. -+ */ -+int mptcp_retransmit_skb(struct sock *meta_sk, struct sk_buff *skb) -+{ -+ struct tcp_sock *meta_tp = tcp_sk(meta_sk); -+ struct sock *subsk; -+ unsigned int limit, mss_now; -+ int err = -1; -+ -+ WARN_ON(TCP_SKB_CB(skb)->sacked); -+ -+ /* Do not sent more than we queued. 1/4 is reserved for possible -+ * copying overhead: fragmentation, tunneling, mangling etc. -+ * -+ * This is a meta-retransmission thus we check on the meta-socket. -+ */ -+ if (refcount_read(&meta_sk->sk_wmem_alloc) > -+ min(meta_sk->sk_wmem_queued + (meta_sk->sk_wmem_queued >> 2), meta_sk->sk_sndbuf)) { -+ return -EAGAIN; -+ } -+ -+ /* We need to make sure that the retransmitted segment can be sent on a -+ * subflow right now. If it is too big, it needs to be fragmented. -+ */ -+ subsk = meta_tp->mpcb->sched_ops->get_subflow(meta_sk, skb, false); -+ if (!subsk) { -+ /* We want to increase icsk_retransmits, thus return 0, so that -+ * mptcp_meta_retransmit_timer enters the desired branch. -+ */ -+ err = 0; -+ goto failed; -+ } -+ mss_now = tcp_current_mss(subsk); -+ -+ /* If the segment was cloned (e.g. a meta retransmission), the header -+ * must be expanded/copied so that there is no corruption of TSO -+ * information. -+ */ -+ if (skb_unclone(skb, GFP_ATOMIC)) { -+ err = -ENOMEM; -+ goto failed; -+ } -+ -+ /* Must have been set by mptcp_write_xmit before */ -+ BUG_ON(!tcp_skb_pcount(skb)); -+ -+ limit = mss_now; -+ /* skb->len > mss_now is the equivalent of tso_segs > 1 in -+ * tcp_write_xmit. Otherwise split-point would return 0. -+ */ -+ if (skb->len > mss_now && !tcp_urg_mode(meta_tp)) -+ limit = tcp_mss_split_point(meta_sk, skb, mss_now, -+ UINT_MAX / mss_now, -+ TCP_NAGLE_OFF); -+ -+ limit = min(limit, tcp_wnd_end(meta_tp) - TCP_SKB_CB(skb)->seq); -+ -+ if (skb->len > limit && -+ unlikely(mptcp_fragment(meta_sk, TCP_FRAG_IN_RTX_QUEUE, skb, -+ limit, GFP_ATOMIC, 0))) -+ goto failed; -+ -+ if (!mptcp_skb_entail(subsk, skb, -1)) -+ goto failed; -+ -+ /* Update global TCP statistics. */ -+ MPTCP_INC_STATS(sock_net(meta_sk), MPTCP_MIB_RETRANSSEGS); -+ -+ /* Diff to tcp_retransmit_skb */ -+ -+ /* Save stamp of the first retransmit. */ -+ if (!meta_tp->retrans_stamp) { -+ tcp_mstamp_refresh(meta_tp); -+ meta_tp->retrans_stamp = tcp_time_stamp(meta_tp); -+ } -+ -+ __tcp_push_pending_frames(subsk, mss_now, TCP_NAGLE_PUSH); -+ tcp_update_skb_after_send(meta_tp, skb); -+ meta_tp->lsndtime = tcp_jiffies32; -+ -+ return 0; -+ -+failed: -+ __NET_INC_STATS(sock_net(meta_sk), LINUX_MIB_TCPRETRANSFAIL); -+ return err; -+} -+ -+/* Similar to tcp_retransmit_timer -+ * -+ * The diff is that we have to handle retransmissions of the FAST_CLOSE-message -+ * and that we don't have an srtt estimation at the meta-level. -+ */ -+void mptcp_meta_retransmit_timer(struct sock *meta_sk) -+{ -+ struct tcp_sock *meta_tp = tcp_sk(meta_sk); -+ struct mptcp_cb *mpcb = meta_tp->mpcb; -+ struct inet_connection_sock *meta_icsk = inet_csk(meta_sk); -+ int err; -+ -+ /* In fallback, retransmission is handled at the subflow-level */ -+ if (!meta_tp->packets_out || mpcb->infinite_mapping_snd) -+ return; -+ -+ WARN_ON(tcp_rtx_queue_empty(meta_sk)); -+ -+ if (!meta_tp->snd_wnd && !sock_flag(meta_sk, SOCK_DEAD) && -+ !((1 << meta_sk->sk_state) & (TCPF_SYN_SENT | TCPF_SYN_RECV))) { -+ /* Receiver dastardly shrinks window. Our retransmits -+ * become zero probes, but we should not timeout this -+ * connection. If the socket is an orphan, time it out, -+ * we cannot allow such beasts to hang infinitely. -+ */ -+ struct inet_sock *meta_inet = inet_sk(meta_sk); -+ if (meta_sk->sk_family == AF_INET) { -+ net_dbg_ratelimited("MPTCP: Peer %pI4:%u/%u unexpectedly shrunk window %u:%u (repaired)\n", -+ &meta_inet->inet_daddr, -+ ntohs(meta_inet->inet_dport), -+ meta_inet->inet_num, meta_tp->snd_una, -+ meta_tp->snd_nxt); -+ } -+#if IS_ENABLED(CONFIG_IPV6) -+ else if (meta_sk->sk_family == AF_INET6) { -+ net_dbg_ratelimited("MPTCP: Peer %pI6:%u/%u unexpectedly shrunk window %u:%u (repaired)\n", -+ &meta_sk->sk_v6_daddr, -+ ntohs(meta_inet->inet_dport), -+ meta_inet->inet_num, meta_tp->snd_una, -+ meta_tp->snd_nxt); -+ } -+#endif -+ if (tcp_jiffies32 - meta_tp->rcv_tstamp > TCP_RTO_MAX) { -+ tcp_write_err(meta_sk); -+ return; -+ } -+ -+ mptcp_retransmit_skb(meta_sk, tcp_rtx_queue_head(meta_sk)); -+ goto out_reset_timer; -+ } -+ -+ if (tcp_write_timeout(meta_sk)) -+ return; -+ -+ if (meta_icsk->icsk_retransmits == 0) -+ __NET_INC_STATS(sock_net(meta_sk), LINUX_MIB_TCPTIMEOUTS); -+ -+ meta_icsk->icsk_ca_state = TCP_CA_Loss; -+ -+ err = mptcp_retransmit_skb(meta_sk, tcp_rtx_queue_head(meta_sk)); -+ if (err > 0) { -+ /* Retransmission failed because of local congestion, -+ * do not backoff. -+ */ -+ if (!meta_icsk->icsk_retransmits) -+ meta_icsk->icsk_retransmits = 1; -+ inet_csk_reset_xmit_timer(meta_sk, ICSK_TIME_RETRANS, -+ min(meta_icsk->icsk_rto, TCP_RESOURCE_PROBE_INTERVAL), -+ TCP_RTO_MAX); -+ return; -+ } -+ -+ /* Increase the timeout each time we retransmit. Note that -+ * we do not increase the rtt estimate. rto is initialized -+ * from rtt, but increases here. Jacobson (SIGCOMM 88) suggests -+ * that doubling rto each time is the least we can get away with. -+ * In KA9Q, Karn uses this for the first few times, and then -+ * goes to quadratic. netBSD doubles, but only goes up to *64, -+ * and clamps at 1 to 64 sec afterwards. Note that 120 sec is -+ * defined in the protocol as the maximum possible RTT. I guess -+ * we'll have to use something other than TCP to talk to the -+ * University of Mars. -+ * -+ * PAWS allows us longer timeouts and large windows, so once -+ * implemented ftp to mars will work nicely. We will have to fix -+ * the 120 second clamps though! -+ */ -+ meta_icsk->icsk_backoff++; -+ meta_icsk->icsk_retransmits++; -+ -+out_reset_timer: -+ /* If stream is thin, use linear timeouts. Since 'icsk_backoff' is -+ * used to reset timer, set to 0. Recalculate 'icsk_rto' as this -+ * might be increased if the stream oscillates between thin and thick, -+ * thus the old value might already be too high compared to the value -+ * set by 'tcp_set_rto' in tcp_input.c which resets the rto without -+ * backoff. Limit to TCP_THIN_LINEAR_RETRIES before initiating -+ * exponential backoff behaviour to avoid continue hammering -+ * linear-timeout retransmissions into a black hole -+ */ -+ if (meta_sk->sk_state == TCP_ESTABLISHED && -+ (meta_tp->thin_lto || sock_net(meta_sk)->ipv4.sysctl_tcp_thin_linear_timeouts) && -+ tcp_stream_is_thin(meta_tp) && -+ meta_icsk->icsk_retransmits <= TCP_THIN_LINEAR_RETRIES) { -+ meta_icsk->icsk_backoff = 0; -+ /* We cannot do the same as in tcp_write_timer because the -+ * srtt is not set here. -+ */ -+ mptcp_set_rto(meta_sk); -+ } else { -+ /* Use normal (exponential) backoff */ -+ meta_icsk->icsk_rto = min(meta_icsk->icsk_rto << 1, TCP_RTO_MAX); -+ } -+ inet_csk_reset_xmit_timer(meta_sk, ICSK_TIME_RETRANS, meta_icsk->icsk_rto, TCP_RTO_MAX); -+ -+ return; -+} -+ -+void mptcp_sub_retransmit_timer(struct sock *sk) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ -+ tcp_retransmit_timer(sk); -+ -+ if (!tp->fastopen_rsk) { -+ mptcp_reinject_data(sk, 1); -+ mptcp_set_rto(sk); -+ } -+} -+ -+/* Modify values to an mptcp-level for the initial window of new subflows */ -+void mptcp_select_initial_window(const struct sock *sk, int __space, __u32 mss, -+ __u32 *rcv_wnd, __u32 *window_clamp, -+ int wscale_ok, __u8 *rcv_wscale, -+ __u32 init_rcv_wnd) -+{ -+ const struct mptcp_cb *mpcb = tcp_sk(sk)->mpcb; -+ -+ *window_clamp = mpcb->orig_window_clamp; -+ __space = tcp_win_from_space(sk, mpcb->orig_sk_rcvbuf); -+ -+ tcp_select_initial_window(sk, __space, mss, rcv_wnd, window_clamp, -+ wscale_ok, rcv_wscale, init_rcv_wnd); -+} -+ -+static inline u64 mptcp_calc_rate(const struct sock *meta_sk, unsigned int mss, -+ unsigned int (*mss_cb)(struct sock *sk)) -+{ -+ struct mptcp_tcp_sock *mptcp; -+ u64 rate = 0; -+ -+ mptcp_for_each_sub(tcp_sk(meta_sk)->mpcb, mptcp) { -+ struct sock *sk = mptcp_to_sock(mptcp); -+ struct tcp_sock *tp = tcp_sk(sk); -+ int this_mss; -+ u64 this_rate; -+ -+ if (!mptcp_sk_can_send(sk)) -+ continue; -+ -+ /* Do not consider subflows without a RTT estimation yet -+ * otherwise this_rate >>> rate. -+ */ -+ if (unlikely(!tp->srtt_us)) -+ continue; -+ -+ this_mss = mss_cb(sk); -+ -+ /* If this_mss is smaller than mss, it means that a segment will -+ * be splitted in two (or more) when pushed on this subflow. If -+ * you consider that mss = 1428 and this_mss = 1420 then two -+ * segments will be generated: a 1420-byte and 8-byte segment. -+ * The latter will introduce a large overhead as for a single -+ * data segment 2 slots will be used in the congestion window. -+ * Therefore reducing by ~2 the potential throughput of this -+ * subflow. Indeed, 1428 will be send while 2840 could have been -+ * sent if mss == 1420 reducing the throughput by 2840 / 1428. -+ * -+ * The following algorithm take into account this overhead -+ * when computing the potential throughput that MPTCP can -+ * achieve when generating mss-byte segments. -+ * -+ * The formulae is the following: -+ * \sum_{\forall sub} ratio * \frac{mss * cwnd_sub}{rtt_sub} -+ * Where ratio is computed as follows: -+ * \frac{mss}{\ceil{mss / mss_sub} * mss_sub} -+ * -+ * ratio gives the reduction factor of the theoretical -+ * throughput a subflow can achieve if MPTCP uses a specific -+ * MSS value. -+ */ -+ this_rate = div64_u64((u64)mss * mss * (USEC_PER_SEC << 3) * -+ max(tp->snd_cwnd, tp->packets_out), -+ (u64)tp->srtt_us * -+ DIV_ROUND_UP(mss, this_mss) * this_mss); -+ rate += this_rate; -+ } -+ -+ return rate; -+} -+ -+static unsigned int __mptcp_current_mss(const struct sock *meta_sk, -+ unsigned int (*mss_cb)(struct sock *sk)) -+{ -+ struct mptcp_tcp_sock *mptcp; -+ unsigned int mss = 0; -+ u64 rate = 0; -+ -+ mptcp_for_each_sub(tcp_sk(meta_sk)->mpcb, mptcp) { -+ struct sock *sk = mptcp_to_sock(mptcp); -+ int this_mss; -+ u64 this_rate; -+ -+ if (!mptcp_sk_can_send(sk)) -+ continue; -+ -+ this_mss = mss_cb(sk); -+ -+ /* Same mss values will produce the same throughput. */ -+ if (this_mss == mss) -+ continue; -+ -+ /* See whether using this mss value can theoretically improve -+ * the performances. -+ */ -+ this_rate = mptcp_calc_rate(meta_sk, this_mss, mss_cb); -+ if (this_rate >= rate) { -+ mss = this_mss; -+ rate = this_rate; -+ } -+ } -+ -+ return mss; -+} -+ -+unsigned int mptcp_current_mss(struct sock *meta_sk) -+{ -+ unsigned int mss = __mptcp_current_mss(meta_sk, tcp_current_mss); -+ -+ /* If no subflow is available, we take a default-mss from the -+ * meta-socket. -+ */ -+ return !mss ? tcp_current_mss(meta_sk) : mss; -+} -+ -+static unsigned int mptcp_select_size_mss(struct sock *sk) -+{ -+ return tcp_sk(sk)->mss_cache; -+} -+ -+int mptcp_select_size(const struct sock *meta_sk, bool first_skb, bool zc) -+{ -+ unsigned int mss = __mptcp_current_mss(meta_sk, mptcp_select_size_mss); -+ -+ if (mptcp_can_sg(meta_sk)) { -+ if (zc) -+ return 0; -+ -+ if (!tcp_sk(meta_sk)->mpcb->dss_csum) { -+ mss = linear_payload_sz(first_skb); -+ } else { -+ int pgbreak = SKB_MAX_HEAD(MAX_TCP_HEADER); -+ -+ if (mss >= pgbreak && -+ mss <= pgbreak + (MAX_SKB_FRAGS - 1) * PAGE_SIZE) -+ mss = pgbreak; -+ } -+ } -+ -+ return !mss ? tcp_sk(meta_sk)->mss_cache : mss; -+} -+ -+int mptcp_check_snd_buf(const struct tcp_sock *tp) -+{ -+ const struct mptcp_tcp_sock *mptcp; -+ u32 rtt_max = tp->srtt_us; -+ u64 bw_est; -+ -+ if (!tp->srtt_us) -+ return tp->reordering + 1; -+ -+ mptcp_for_each_sub(tp->mpcb, mptcp) { -+ const struct sock *sk = mptcp_to_sock(mptcp); -+ -+ if (!mptcp_sk_can_send(sk)) -+ continue; -+ -+ if (rtt_max < tcp_sk(sk)->srtt_us) -+ rtt_max = tcp_sk(sk)->srtt_us; -+ } -+ -+ bw_est = div64_u64(((u64)tp->snd_cwnd * rtt_max) << 16, -+ (u64)tp->srtt_us); -+ -+ return max_t(unsigned int, (u32)(bw_est >> 16), -+ tp->reordering + 1); -+} -+ -+unsigned int mptcp_xmit_size_goal(const struct sock *meta_sk, u32 mss_now, -+ int large_allowed) -+{ -+ u32 xmit_size_goal = 0; -+ -+ if (large_allowed && !tcp_sk(meta_sk)->mpcb->dss_csum) { -+ struct mptcp_tcp_sock *mptcp; -+ -+ mptcp_for_each_sub(tcp_sk(meta_sk)->mpcb, mptcp) { -+ struct sock *sk = mptcp_to_sock(mptcp); -+ int this_size_goal; -+ -+ if (!mptcp_sk_can_send(sk)) -+ continue; -+ -+ this_size_goal = tcp_xmit_size_goal(sk, mss_now, 1); -+ if (this_size_goal > xmit_size_goal) -+ xmit_size_goal = this_size_goal; -+ } -+ } -+ -+ return max(xmit_size_goal, mss_now); -+} -+ -diff -aurN linux-4.19.104/net/mptcp/mptcp_pm.c mptcp-mptcp_v0.95/net/mptcp/mptcp_pm.c ---- linux-4.19.104/net/mptcp/mptcp_pm.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_v0.95/net/mptcp/mptcp_pm.c 2020-02-17 11:29:55.000000000 +0100 -@@ -0,0 +1,226 @@ -+/* -+ * MPTCP implementation - MPTCP-subflow-management -+ * -+ * Initial Design & Implementation: -+ * Sébastien Barré -+ * -+ * Current Maintainer & Author: -+ * Christoph Paasch -+ * -+ * Additional authors: -+ * Jaakko Korkeaniemi -+ * Gregory Detal -+ * Fabien Duchêne -+ * Andreas Seelinger -+ * Lavkesh Lahngir -+ * Andreas Ripke -+ * Vlad Dogaru -+ * Octavian Purdila -+ * John Ronan -+ * Catalin Nicutar -+ * Brandon Heller -+ * -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version -+ * 2 of the License, or (at your option) any later version. -+ */ -+ -+ -+#include -+#include -+ -+static DEFINE_SPINLOCK(mptcp_pm_list_lock); -+static LIST_HEAD(mptcp_pm_list); -+ -+static int mptcp_default_id(const struct sock *meta_sk, sa_family_t family, -+ union inet_addr *addr, bool *low_prio) -+{ -+ return 0; -+} -+ -+struct mptcp_pm_ops mptcp_pm_default = { -+ .get_local_id = mptcp_default_id, /* We do not care */ -+ .name = "default", -+ .owner = THIS_MODULE, -+}; -+ -+static struct mptcp_pm_ops *mptcp_pm_find(const char *name) -+{ -+ struct mptcp_pm_ops *e; -+ -+ list_for_each_entry_rcu(e, &mptcp_pm_list, list) { -+ if (strcmp(e->name, name) == 0) -+ return e; -+ } -+ -+ return NULL; -+} -+ -+int mptcp_register_path_manager(struct mptcp_pm_ops *pm) -+{ -+ int ret = 0; -+ -+ if (!pm->get_local_id) -+ return -EINVAL; -+ -+ spin_lock(&mptcp_pm_list_lock); -+ if (mptcp_pm_find(pm->name)) { -+ pr_notice("%s already registered\n", pm->name); -+ ret = -EEXIST; -+ } else { -+ list_add_tail_rcu(&pm->list, &mptcp_pm_list); -+ pr_info("%s registered\n", pm->name); -+ } -+ spin_unlock(&mptcp_pm_list_lock); -+ -+ return ret; -+} -+EXPORT_SYMBOL_GPL(mptcp_register_path_manager); -+ -+void mptcp_unregister_path_manager(struct mptcp_pm_ops *pm) -+{ -+ spin_lock(&mptcp_pm_list_lock); -+ list_del_rcu(&pm->list); -+ spin_unlock(&mptcp_pm_list_lock); -+ -+ /* Wait for outstanding readers to complete before the -+ * module gets removed entirely. -+ * -+ * A try_module_get() should fail by now as our module is -+ * in "going" state since no refs are held anymore and -+ * module_exit() handler being called. -+ */ -+ synchronize_rcu(); -+} -+EXPORT_SYMBOL_GPL(mptcp_unregister_path_manager); -+ -+void mptcp_get_default_path_manager(char *name) -+{ -+ struct mptcp_pm_ops *pm; -+ -+ BUG_ON(list_empty(&mptcp_pm_list)); -+ -+ rcu_read_lock(); -+ pm = list_entry(mptcp_pm_list.next, struct mptcp_pm_ops, list); -+ strncpy(name, pm->name, MPTCP_PM_NAME_MAX); -+ rcu_read_unlock(); -+} -+ -+int mptcp_set_default_path_manager(const char *name) -+{ -+ struct mptcp_pm_ops *pm; -+ int ret = -ENOENT; -+ -+ spin_lock(&mptcp_pm_list_lock); -+ pm = mptcp_pm_find(name); -+#ifdef CONFIG_MODULES -+ if (!pm && capable(CAP_NET_ADMIN)) { -+ spin_unlock(&mptcp_pm_list_lock); -+ -+ request_module("mptcp_%s", name); -+ spin_lock(&mptcp_pm_list_lock); -+ pm = mptcp_pm_find(name); -+ } -+#endif -+ -+ if (pm) { -+ list_move(&pm->list, &mptcp_pm_list); -+ ret = 0; -+ } else { -+ pr_info("%s is not available\n", name); -+ } -+ spin_unlock(&mptcp_pm_list_lock); -+ -+ return ret; -+} -+ -+static struct mptcp_pm_ops *__mptcp_pm_find_autoload(const char *name) -+{ -+ struct mptcp_pm_ops *pm = mptcp_pm_find(name); -+#ifdef CONFIG_MODULES -+ if (!pm && capable(CAP_NET_ADMIN)) { -+ rcu_read_unlock(); -+ request_module("mptcp_%s", name); -+ rcu_read_lock(); -+ pm = mptcp_pm_find(name); -+ } -+#endif -+ return pm; -+} -+ -+void mptcp_init_path_manager(struct mptcp_cb *mpcb) -+{ -+ struct mptcp_pm_ops *pm; -+ struct sock *meta_sk = mpcb->meta_sk; -+ struct tcp_sock *meta_tp = tcp_sk(meta_sk); -+ -+ rcu_read_lock(); -+ /* if path manager was set using socket option */ -+ if (meta_tp->mptcp_pm_setsockopt) { -+ pm = __mptcp_pm_find_autoload(meta_tp->mptcp_pm_name); -+ if (pm && try_module_get(pm->owner)) { -+ mpcb->pm_ops = pm; -+ goto out; -+ } -+ } -+ -+ list_for_each_entry_rcu(pm, &mptcp_pm_list, list) { -+ if (try_module_get(pm->owner)) { -+ mpcb->pm_ops = pm; -+ break; -+ } -+ } -+out: -+ rcu_read_unlock(); -+} -+ -+/* Change path manager for socket */ -+int mptcp_set_path_manager(struct sock *sk, const char *name) -+{ -+ struct mptcp_pm_ops *pm; -+ int err = 0; -+ -+ rcu_read_lock(); -+ pm = __mptcp_pm_find_autoload(name); -+ -+ if (!pm) { -+ err = -ENOENT; -+ } else if (!ns_capable(sock_net(sk)->user_ns, CAP_NET_ADMIN)) { -+ err = -EPERM; -+ } else { -+ strcpy(tcp_sk(sk)->mptcp_pm_name, name); -+ tcp_sk(sk)->mptcp_pm_setsockopt = 1; -+ } -+ rcu_read_unlock(); -+ -+ return err; -+} -+ -+/* Manage refcounts on socket close. */ -+void mptcp_cleanup_path_manager(struct mptcp_cb *mpcb) -+{ -+ module_put(mpcb->pm_ops->owner); -+} -+ -+/* Fallback to the default path-manager. */ -+void mptcp_fallback_default(struct mptcp_cb *mpcb) -+{ -+ struct mptcp_pm_ops *pm; -+ -+ mptcp_cleanup_path_manager(mpcb); -+ pm = mptcp_pm_find("default"); -+ -+ /* Cannot fail - it's the default module */ -+ try_module_get(pm->owner); -+ mpcb->pm_ops = pm; -+} -+EXPORT_SYMBOL_GPL(mptcp_fallback_default); -+ -+/* Set default value from kernel configuration at bootup */ -+static int __init mptcp_path_manager_default(void) -+{ -+ return mptcp_set_default_path_manager(CONFIG_DEFAULT_MPTCP_PM); -+} -+late_initcall(mptcp_path_manager_default); -diff -aurN linux-4.19.104/net/mptcp/mptcp_redundant.c mptcp-mptcp_v0.95/net/mptcp/mptcp_redundant.c ---- linux-4.19.104/net/mptcp/mptcp_redundant.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_v0.95/net/mptcp/mptcp_redundant.c 2020-02-17 11:29:55.000000000 +0100 -@@ -0,0 +1,389 @@ -+/* -+ * MPTCP Scheduler to reduce latency and jitter. -+ * -+ * This scheduler sends all packets redundantly on all available subflows. -+ * -+ * Initial Design & Implementation: -+ * Tobias Erbshaeusser -+ * Alexander Froemmgen -+ * -+ * Initial corrections & modifications: -+ * Christian Pinedo -+ * Igor Lopez -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version -+ * 2 of the License, or (at your option) any later version. -+ */ -+ -+#include -+#include -+ -+/* Struct to store the data of a single subflow */ -+struct redsched_priv { -+ /* The skb or NULL */ -+ struct sk_buff *skb; -+ /* End sequence number of the skb. This number should be checked -+ * to be valid before the skb field is used -+ */ -+ u32 skb_end_seq; -+}; -+ -+/* Struct to store the data of the control block */ -+struct redsched_cb { -+ /* The next subflow where a skb should be sent or NULL */ -+ struct tcp_sock *next_subflow; -+}; -+ -+/* Returns the socket data from a given subflow socket */ -+static struct redsched_priv *redsched_get_priv(struct tcp_sock *tp) -+{ -+ return (struct redsched_priv *)&tp->mptcp->mptcp_sched[0]; -+} -+ -+/* Returns the control block data from a given meta socket */ -+static struct redsched_cb *redsched_get_cb(struct tcp_sock *tp) -+{ -+ return (struct redsched_cb *)&tp->mpcb->mptcp_sched[0]; -+} -+ -+static bool redsched_get_active_valid_sks(struct sock *meta_sk) -+{ -+ struct tcp_sock *meta_tp = tcp_sk(meta_sk); -+ struct mptcp_cb *mpcb = meta_tp->mpcb; -+ struct mptcp_tcp_sock *mptcp; -+ int active_valid_sks = 0; -+ -+ mptcp_for_each_sub(mpcb, mptcp) { -+ struct sock *sk = mptcp_to_sock(mptcp); -+ -+ if (subflow_is_active((struct tcp_sock *)sk) && -+ !mptcp_is_def_unavailable(sk)) -+ active_valid_sks++; -+ } -+ -+ return active_valid_sks; -+} -+ -+static bool redsched_use_subflow(struct sock *meta_sk, -+ int active_valid_sks, -+ struct tcp_sock *tp, -+ struct sk_buff *skb) -+{ -+ if (!skb || !mptcp_is_available((struct sock *)tp, skb, false)) -+ return false; -+ -+ if (TCP_SKB_CB(skb)->path_mask != 0) -+ return subflow_is_active(tp); -+ -+ if (TCP_SKB_CB(skb)->path_mask == 0) { -+ if (active_valid_sks == -1) -+ active_valid_sks = redsched_get_active_valid_sks(meta_sk); -+ -+ if (subflow_is_backup(tp) && active_valid_sks > 0) -+ return false; -+ else -+ return true; -+ } -+ -+ return false; -+} -+ -+#define mptcp_entry_next_rcu(__mptcp) \ -+ hlist_entry_safe(rcu_dereference_raw(hlist_next_rcu( \ -+ &(__mptcp)->node)), struct mptcp_tcp_sock, node) -+ -+static void redsched_update_next_subflow(struct tcp_sock *tp, -+ struct redsched_cb *red_cb) -+{ -+ struct mptcp_tcp_sock *mptcp = mptcp_entry_next_rcu(tp->mptcp); -+ -+ if (mptcp) -+ red_cb->next_subflow = mptcp->tp; -+ else -+ red_cb->next_subflow = NULL; -+} -+ -+static struct sock *red_get_available_subflow(struct sock *meta_sk, -+ struct sk_buff *skb, -+ bool zero_wnd_test) -+{ -+ struct tcp_sock *meta_tp = tcp_sk(meta_sk); -+ struct mptcp_cb *mpcb = meta_tp->mpcb; -+ struct redsched_cb *red_cb = redsched_get_cb(meta_tp); -+ struct tcp_sock *first_tp = red_cb->next_subflow, *tp; -+ struct mptcp_tcp_sock *mptcp; -+ int found = 0; -+ -+ /* Answer data_fin on same subflow */ -+ if (meta_sk->sk_shutdown & RCV_SHUTDOWN && -+ skb && mptcp_is_data_fin(skb)) { -+ mptcp_for_each_sub(mpcb, mptcp) { -+ struct sock *sk = mptcp_to_sock(mptcp); -+ -+ if (tcp_sk(sk)->mptcp->path_index == -+ mpcb->dfin_path_index && -+ mptcp_is_available(sk, skb, zero_wnd_test)) -+ return sk; -+ } -+ } -+ -+ if (!first_tp && !hlist_empty(&mpcb->conn_list)) { -+ first_tp = hlist_entry_safe(rcu_dereference_raw(hlist_first_rcu(&mpcb->conn_list)), -+ struct mptcp_tcp_sock, node)->tp; -+ } -+ tp = first_tp; -+ -+ /* still NULL (no subflow in conn_list?) */ -+ if (!first_tp) -+ return NULL; -+ -+ /* Search for a subflow to send it. -+ * -+ * We want to pick a subflow that is after 'first_tp' in the list of subflows. -+ * Thus, the first mptcp_for_each_sub()-loop tries to walk the list up -+ * to the subflow 'tp' and then checks whether any one of the remaining -+ * ones is eligible to send. -+ * The second mptcp_for_each-sub()-loop is then iterating from the -+ * beginning of the list up to 'first_tp'. -+ */ -+ mptcp_for_each_sub(mpcb, mptcp) { -+ /* We go up to the subflow 'tp' and start from there */ -+ if (tp == mptcp->tp) -+ found = 1; -+ -+ if (!found) -+ continue; -+ tp = mptcp->tp; -+ -+ if (mptcp_is_available((struct sock *)tp, skb, -+ zero_wnd_test)) { -+ redsched_update_next_subflow(tp, red_cb); -+ return (struct sock *)tp; -+ } -+ } -+ -+ mptcp_for_each_sub(mpcb, mptcp) { -+ tp = mptcp->tp; -+ -+ if (tp == first_tp) -+ break; -+ -+ if (mptcp_is_available((struct sock *)tp, skb, -+ zero_wnd_test)) { -+ redsched_update_next_subflow(tp, red_cb); -+ return (struct sock *)tp; -+ } -+ } -+ -+ /* No space */ -+ return NULL; -+} -+ -+/* Corrects the stored skb pointers if they are invalid */ -+static void redsched_correct_skb_pointers(struct sock *meta_sk, -+ struct redsched_priv *red_p) -+{ -+ struct tcp_sock *meta_tp = tcp_sk(meta_sk); -+ -+ if (red_p->skb && !after(red_p->skb_end_seq, meta_tp->snd_una)) -+ red_p->skb = NULL; -+} -+ -+/* Returns the next skb from the queue */ -+static struct sk_buff *redsched_next_skb_from_queue(struct sk_buff_head *queue, -+ struct sk_buff *previous, -+ struct sock *meta_sk) -+{ -+ struct sk_buff *skb; -+ -+ if (!previous) -+ return skb_peek(queue); -+ -+ /* sk_data->skb stores the last scheduled packet for this subflow. -+ * If sk_data->skb was scheduled but not sent (e.g., due to nagle), -+ * we have to schedule it again. -+ * -+ * For the redundant scheduler, there are two cases: -+ * 1. sk_data->skb was not sent on another subflow: -+ * we have to schedule it again to ensure that we do not -+ * skip this packet. -+ * 2. sk_data->skb was already sent on another subflow: -+ * with regard to the redundant semantic, we have to -+ * schedule it again. However, we keep it simple and ignore it, -+ * as it was already sent by another subflow. -+ * This might be changed in the future. -+ * -+ * For case 1, send_head is equal previous, as only a single -+ * packet can be skipped. -+ */ -+ if (tcp_send_head(meta_sk) == previous) -+ return tcp_send_head(meta_sk); -+ -+ skb = skb_rb_next(previous); -+ if (skb) -+ return skb; -+ -+ return tcp_send_head(meta_sk); -+} -+ -+static struct sk_buff *mptcp_red_next_segment(struct sock *meta_sk, -+ int *reinject, -+ struct sock **subsk, -+ unsigned int *limit) -+{ -+ struct tcp_sock *meta_tp = tcp_sk(meta_sk); -+ struct mptcp_cb *mpcb = meta_tp->mpcb; -+ struct redsched_cb *red_cb = redsched_get_cb(meta_tp); -+ struct tcp_sock *first_tp = red_cb->next_subflow, *tp; -+ struct mptcp_tcp_sock *mptcp; -+ int active_valid_sks = -1; -+ struct sk_buff *skb; -+ int found = 0; -+ -+ /* As we set it, we have to reset it as well. */ -+ *limit = 0; -+ -+ if (skb_queue_empty(&mpcb->reinject_queue) && -+ skb_queue_empty(&meta_sk->sk_write_queue)) -+ /* Nothing to send */ -+ return NULL; -+ -+ /* First try reinjections */ -+ skb = skb_peek(&mpcb->reinject_queue); -+ if (skb) { -+ *subsk = get_available_subflow(meta_sk, skb, false); -+ if (!*subsk) -+ return NULL; -+ *reinject = 1; -+ return skb; -+ } -+ -+ /* Then try indistinctly redundant and normal skbs */ -+ -+ if (!first_tp && !hlist_empty(&mpcb->conn_list)) { -+ first_tp = hlist_entry_safe(rcu_dereference_raw(hlist_first_rcu(&mpcb->conn_list)), -+ struct mptcp_tcp_sock, node)->tp; -+ } -+ -+ /* still NULL (no subflow in conn_list?) */ -+ if (!first_tp) -+ return NULL; -+ -+ tp = first_tp; -+ -+ *reinject = 0; -+ active_valid_sks = redsched_get_active_valid_sks(meta_sk); -+ -+ /* We want to pick a subflow that is after 'first_tp' in the list of subflows. -+ * Thus, the first mptcp_for_each_sub()-loop tries to walk the list up -+ * to the subflow 'tp' and then checks whether any one of the remaining -+ * ones can send a segment. -+ * The second mptcp_for_each-sub()-loop is then iterating from the -+ * beginning of the list up to 'first_tp'. -+ */ -+ mptcp_for_each_sub(mpcb, mptcp) { -+ struct redsched_priv *red_p; -+ -+ if (tp == mptcp->tp) -+ found = 1; -+ -+ if (!found) -+ continue; -+ -+ tp = mptcp->tp; -+ -+ /* Correct the skb pointers of the current subflow */ -+ red_p = redsched_get_priv(tp); -+ redsched_correct_skb_pointers(meta_sk, red_p); -+ -+ skb = redsched_next_skb_from_queue(&meta_sk->sk_write_queue, -+ red_p->skb, meta_sk); -+ if (skb && redsched_use_subflow(meta_sk, active_valid_sks, tp, -+ skb)) { -+ red_p->skb = skb; -+ red_p->skb_end_seq = TCP_SKB_CB(skb)->end_seq; -+ redsched_update_next_subflow(tp, red_cb); -+ *subsk = (struct sock *)tp; -+ -+ if (TCP_SKB_CB(skb)->path_mask) -+ *reinject = -1; -+ return skb; -+ } -+ } -+ -+ mptcp_for_each_sub(mpcb, mptcp) { -+ struct redsched_priv *red_p; -+ -+ tp = mptcp->tp; -+ -+ if (tp == first_tp) -+ break; -+ -+ /* Correct the skb pointers of the current subflow */ -+ red_p = redsched_get_priv(tp); -+ redsched_correct_skb_pointers(meta_sk, red_p); -+ -+ skb = redsched_next_skb_from_queue(&meta_sk->sk_write_queue, -+ red_p->skb, meta_sk); -+ if (skb && redsched_use_subflow(meta_sk, active_valid_sks, tp, -+ skb)) { -+ red_p->skb = skb; -+ red_p->skb_end_seq = TCP_SKB_CB(skb)->end_seq; -+ redsched_update_next_subflow(tp, red_cb); -+ *subsk = (struct sock *)tp; -+ -+ if (TCP_SKB_CB(skb)->path_mask) -+ *reinject = -1; -+ return skb; -+ } -+ } -+ -+ /* Nothing to send */ -+ return NULL; -+} -+ -+static void redsched_release(struct sock *sk) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct redsched_cb *red_cb = redsched_get_cb(tp); -+ -+ /* Check if the next subflow would be the released one. If yes correct -+ * the pointer -+ */ -+ if (red_cb->next_subflow == tp) -+ redsched_update_next_subflow(tp, red_cb); -+} -+ -+static struct mptcp_sched_ops mptcp_sched_red = { -+ .get_subflow = red_get_available_subflow, -+ .next_segment = mptcp_red_next_segment, -+ .release = redsched_release, -+ .name = "redundant", -+ .owner = THIS_MODULE, -+}; -+ -+static int __init red_register(void) -+{ -+ BUILD_BUG_ON(sizeof(struct redsched_priv) > MPTCP_SCHED_SIZE); -+ BUILD_BUG_ON(sizeof(struct redsched_cb) > MPTCP_SCHED_DATA_SIZE); -+ -+ if (mptcp_register_scheduler(&mptcp_sched_red)) -+ return -1; -+ -+ return 0; -+} -+ -+static void red_unregister(void) -+{ -+ mptcp_unregister_scheduler(&mptcp_sched_red); -+} -+ -+module_init(red_register); -+module_exit(red_unregister); -+ -+MODULE_AUTHOR("Tobias Erbshaeusser, Alexander Froemmgen"); -+MODULE_LICENSE("GPL"); -+MODULE_DESCRIPTION("REDUNDANT MPTCP"); -+MODULE_VERSION("0.90"); -diff -aurN linux-4.19.104/net/mptcp/mptcp_rr.c mptcp-mptcp_v0.95/net/mptcp/mptcp_rr.c ---- linux-4.19.104/net/mptcp/mptcp_rr.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_v0.95/net/mptcp/mptcp_rr.c 2020-02-17 11:29:55.000000000 +0100 -@@ -0,0 +1,309 @@ -+/* MPTCP Scheduler module selector. Highly inspired by tcp_cong.c */ -+ -+#include -+#include -+ -+static unsigned char num_segments __read_mostly = 1; -+module_param(num_segments, byte, 0644); -+MODULE_PARM_DESC(num_segments, "The number of consecutive segments that are part of a burst"); -+ -+static bool cwnd_limited __read_mostly = 1; -+module_param(cwnd_limited, bool, 0644); -+MODULE_PARM_DESC(cwnd_limited, "if set to 1, the scheduler tries to fill the congestion-window on all subflows"); -+ -+struct rrsched_priv { -+ unsigned char quota; -+}; -+ -+static struct rrsched_priv *rrsched_get_priv(const struct tcp_sock *tp) -+{ -+ return (struct rrsched_priv *)&tp->mptcp->mptcp_sched[0]; -+} -+ -+/* If the sub-socket sk available to send the skb? */ -+static bool mptcp_rr_is_available(const struct sock *sk, const struct sk_buff *skb, -+ bool zero_wnd_test, bool cwnd_test) -+{ -+ const struct tcp_sock *tp = tcp_sk(sk); -+ unsigned int space, in_flight; -+ -+ /* Set of states for which we are allowed to send data */ -+ if (!mptcp_sk_can_send(sk)) -+ return false; -+ -+ /* We do not send data on this subflow unless it is -+ * fully established, i.e. the 4th ack has been received. -+ */ -+ if (tp->mptcp->pre_established) -+ return false; -+ -+ if (tp->pf) -+ return false; -+ -+ if (inet_csk(sk)->icsk_ca_state == TCP_CA_Loss) { -+ /* If SACK is disabled, and we got a loss, TCP does not exit -+ * the loss-state until something above high_seq has been acked. -+ * (see tcp_try_undo_recovery) -+ * -+ * high_seq is the snd_nxt at the moment of the RTO. As soon -+ * as we have an RTO, we won't push data on the subflow. -+ * Thus, snd_una can never go beyond high_seq. -+ */ -+ if (!tcp_is_reno(tp)) -+ return false; -+ else if (tp->snd_una != tp->high_seq) -+ return false; -+ } -+ -+ if (!tp->mptcp->fully_established) { -+ /* Make sure that we send in-order data */ -+ if (skb && tp->mptcp->second_packet && -+ tp->mptcp->last_end_data_seq != TCP_SKB_CB(skb)->seq) -+ return false; -+ } -+ -+ if (!cwnd_test) -+ goto zero_wnd_test; -+ -+ in_flight = tcp_packets_in_flight(tp); -+ /* Not even a single spot in the cwnd */ -+ if (in_flight >= tp->snd_cwnd) -+ return false; -+ -+ /* Now, check if what is queued in the subflow's send-queue -+ * already fills the cwnd. -+ */ -+ space = (tp->snd_cwnd - in_flight) * tp->mss_cache; -+ -+ if (tp->write_seq - tp->snd_nxt > space) -+ return false; -+ -+zero_wnd_test: -+ if (zero_wnd_test && !before(tp->write_seq, tcp_wnd_end(tp))) -+ return false; -+ -+ return true; -+} -+ -+/* Are we not allowed to reinject this skb on tp? */ -+static int mptcp_rr_dont_reinject_skb(const struct tcp_sock *tp, const struct sk_buff *skb) -+{ -+ /* If the skb has already been enqueued in this sk, try to find -+ * another one. -+ */ -+ return skb && -+ /* Has the skb already been enqueued into this subsocket? */ -+ mptcp_pi_to_flag(tp->mptcp->path_index) & TCP_SKB_CB(skb)->path_mask; -+} -+ -+/* We just look for any subflow that is available */ -+static struct sock *rr_get_available_subflow(struct sock *meta_sk, -+ struct sk_buff *skb, -+ bool zero_wnd_test) -+{ -+ const struct mptcp_cb *mpcb = tcp_sk(meta_sk)->mpcb; -+ struct sock *sk = NULL, *bestsk = NULL, *backupsk = NULL; -+ struct mptcp_tcp_sock *mptcp; -+ -+ /* Answer data_fin on same subflow!!! */ -+ if (meta_sk->sk_shutdown & RCV_SHUTDOWN && -+ skb && mptcp_is_data_fin(skb)) { -+ mptcp_for_each_sub(mpcb, mptcp) { -+ sk = mptcp_to_sock(mptcp); -+ if (tcp_sk(sk)->mptcp->path_index == mpcb->dfin_path_index && -+ mptcp_rr_is_available(sk, skb, zero_wnd_test, true)) -+ return sk; -+ } -+ } -+ -+ /* First, find the best subflow */ -+ mptcp_for_each_sub(mpcb, mptcp) { -+ struct tcp_sock *tp; -+ -+ sk = mptcp_to_sock(mptcp); -+ tp = tcp_sk(sk); -+ -+ if (!mptcp_rr_is_available(sk, skb, zero_wnd_test, true)) -+ continue; -+ -+ if (mptcp_rr_dont_reinject_skb(tp, skb)) { -+ backupsk = sk; -+ continue; -+ } -+ -+ bestsk = sk; -+ } -+ -+ if (bestsk) { -+ sk = bestsk; -+ } else if (backupsk) { -+ /* It has been sent on all subflows once - let's give it a -+ * chance again by restarting its pathmask. -+ */ -+ if (skb) -+ TCP_SKB_CB(skb)->path_mask = 0; -+ sk = backupsk; -+ } -+ -+ return sk; -+} -+ -+/* Returns the next segment to be sent from the mptcp meta-queue. -+ * (chooses the reinject queue if any segment is waiting in it, otherwise, -+ * chooses the normal write queue). -+ * Sets *@reinject to 1 if the returned segment comes from the -+ * reinject queue. Sets it to 0 if it is the regular send-head of the meta-sk, -+ * and sets it to -1 if it is a meta-level retransmission to optimize the -+ * receive-buffer. -+ */ -+static struct sk_buff *__mptcp_rr_next_segment(const struct sock *meta_sk, int *reinject) -+{ -+ const struct mptcp_cb *mpcb = tcp_sk(meta_sk)->mpcb; -+ struct sk_buff *skb = NULL; -+ -+ *reinject = 0; -+ -+ /* If we are in fallback-mode, just take from the meta-send-queue */ -+ if (mpcb->infinite_mapping_snd || mpcb->send_infinite_mapping) -+ return tcp_send_head(meta_sk); -+ -+ skb = skb_peek(&mpcb->reinject_queue); -+ -+ if (skb) -+ *reinject = 1; -+ else -+ skb = tcp_send_head(meta_sk); -+ return skb; -+} -+ -+static struct sk_buff *mptcp_rr_next_segment(struct sock *meta_sk, -+ int *reinject, -+ struct sock **subsk, -+ unsigned int *limit) -+{ -+ const struct mptcp_cb *mpcb = tcp_sk(meta_sk)->mpcb; -+ struct sock *choose_sk = NULL; -+ struct mptcp_tcp_sock *mptcp; -+ struct sk_buff *skb = __mptcp_rr_next_segment(meta_sk, reinject); -+ unsigned char split = num_segments; -+ unsigned char iter = 0, full_subs = 0; -+ -+ /* As we set it, we have to reset it as well. */ -+ *limit = 0; -+ -+ if (!skb) -+ return NULL; -+ -+ if (*reinject) { -+ *subsk = rr_get_available_subflow(meta_sk, skb, false); -+ if (!*subsk) -+ return NULL; -+ -+ return skb; -+ } -+ -+retry: -+ -+ /* First, we look for a subflow who is currently being used */ -+ mptcp_for_each_sub(mpcb, mptcp) { -+ struct sock *sk_it = mptcp_to_sock(mptcp); -+ struct tcp_sock *tp_it = tcp_sk(sk_it); -+ struct rrsched_priv *rr_p = rrsched_get_priv(tp_it); -+ -+ if (!mptcp_rr_is_available(sk_it, skb, false, cwnd_limited)) -+ continue; -+ -+ iter++; -+ -+ /* Is this subflow currently being used? */ -+ if (rr_p->quota > 0 && rr_p->quota < num_segments) { -+ split = num_segments - rr_p->quota; -+ choose_sk = sk_it; -+ goto found; -+ } -+ -+ /* Or, it's totally unused */ -+ if (!rr_p->quota) { -+ split = num_segments; -+ choose_sk = sk_it; -+ } -+ -+ /* Or, it must then be fully used */ -+ if (rr_p->quota >= num_segments) -+ full_subs++; -+ } -+ -+ /* All considered subflows have a full quota, and we considered at -+ * least one. -+ */ -+ if (iter && iter == full_subs) { -+ /* So, we restart this round by setting quota to 0 and retry -+ * to find a subflow. -+ */ -+ mptcp_for_each_sub(mpcb, mptcp) { -+ struct sock *sk_it = mptcp_to_sock(mptcp); -+ struct tcp_sock *tp_it = tcp_sk(sk_it); -+ struct rrsched_priv *rr_p = rrsched_get_priv(tp_it); -+ -+ if (!mptcp_rr_is_available(sk_it, skb, false, cwnd_limited)) -+ continue; -+ -+ rr_p->quota = 0; -+ } -+ -+ goto retry; -+ } -+ -+found: -+ if (choose_sk) { -+ unsigned int mss_now; -+ struct tcp_sock *choose_tp = tcp_sk(choose_sk); -+ struct rrsched_priv *rr_p = rrsched_get_priv(choose_tp); -+ -+ if (!mptcp_rr_is_available(choose_sk, skb, false, true)) -+ return NULL; -+ -+ *subsk = choose_sk; -+ mss_now = tcp_current_mss(*subsk); -+ *limit = split * mss_now; -+ -+ if (skb->len > mss_now) -+ rr_p->quota += DIV_ROUND_UP(skb->len, mss_now); -+ else -+ rr_p->quota++; -+ -+ return skb; -+ } -+ -+ return NULL; -+} -+ -+static struct mptcp_sched_ops mptcp_sched_rr = { -+ .get_subflow = rr_get_available_subflow, -+ .next_segment = mptcp_rr_next_segment, -+ .name = "roundrobin", -+ .owner = THIS_MODULE, -+}; -+ -+static int __init rr_register(void) -+{ -+ BUILD_BUG_ON(sizeof(struct rrsched_priv) > MPTCP_SCHED_SIZE); -+ -+ if (mptcp_register_scheduler(&mptcp_sched_rr)) -+ return -1; -+ -+ return 0; -+} -+ -+static void rr_unregister(void) -+{ -+ mptcp_unregister_scheduler(&mptcp_sched_rr); -+} -+ -+module_init(rr_register); -+module_exit(rr_unregister); -+ -+MODULE_AUTHOR("Christoph Paasch"); -+MODULE_LICENSE("GPL"); -+MODULE_DESCRIPTION("ROUNDROBIN MPTCP"); -+MODULE_VERSION("0.89"); -diff -aurN linux-4.19.104/net/mptcp/mptcp_sched.c mptcp-mptcp_v0.95/net/mptcp/mptcp_sched.c ---- linux-4.19.104/net/mptcp/mptcp_sched.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_v0.95/net/mptcp/mptcp_sched.c 2020-02-17 11:29:55.000000000 +0100 -@@ -0,0 +1,634 @@ -+/* MPTCP Scheduler module selector. Highly inspired by tcp_cong.c */ -+ -+#include -+#include -+#include -+ -+static DEFINE_SPINLOCK(mptcp_sched_list_lock); -+static LIST_HEAD(mptcp_sched_list); -+ -+struct defsched_priv { -+ u32 last_rbuf_opti; -+}; -+ -+static struct defsched_priv *defsched_get_priv(const struct tcp_sock *tp) -+{ -+ return (struct defsched_priv *)&tp->mptcp->mptcp_sched[0]; -+} -+ -+bool mptcp_is_def_unavailable(struct sock *sk) -+{ -+ const struct tcp_sock *tp = tcp_sk(sk); -+ -+ /* Set of states for which we are allowed to send data */ -+ if (!mptcp_sk_can_send(sk)) -+ return true; -+ -+ /* We do not send data on this subflow unless it is -+ * fully established, i.e. the 4th ack has been received. -+ */ -+ if (tp->mptcp->pre_established) -+ return true; -+ -+ if (tp->pf) -+ return true; -+ -+ return false; -+} -+EXPORT_SYMBOL_GPL(mptcp_is_def_unavailable); -+ -+static bool mptcp_is_temp_unavailable(struct sock *sk, -+ const struct sk_buff *skb, -+ bool zero_wnd_test) -+{ -+ const struct tcp_sock *tp = tcp_sk(sk); -+ unsigned int mss_now, space, in_flight; -+ -+ if (inet_csk(sk)->icsk_ca_state == TCP_CA_Loss) { -+ /* If SACK is disabled, and we got a loss, TCP does not exit -+ * the loss-state until something above high_seq has been -+ * acked. (see tcp_try_undo_recovery) -+ * -+ * high_seq is the snd_nxt at the moment of the RTO. As soon -+ * as we have an RTO, we won't push data on the subflow. -+ * Thus, snd_una can never go beyond high_seq. -+ */ -+ if (!tcp_is_reno(tp)) -+ return true; -+ else if (tp->snd_una != tp->high_seq) -+ return true; -+ } -+ -+ if (!tp->mptcp->fully_established) { -+ /* Make sure that we send in-order data */ -+ if (skb && tp->mptcp->second_packet && -+ tp->mptcp->last_end_data_seq != TCP_SKB_CB(skb)->seq) -+ return true; -+ } -+ -+ in_flight = tcp_packets_in_flight(tp); -+ /* Not even a single spot in the cwnd */ -+ if (in_flight >= tp->snd_cwnd) -+ return true; -+ -+ /* Now, check if what is queued in the subflow's send-queue -+ * already fills the cwnd. -+ */ -+ space = (tp->snd_cwnd - in_flight) * tp->mss_cache; -+ -+ if (tp->write_seq - tp->snd_nxt > space) -+ return true; -+ -+ if (zero_wnd_test && !before(tp->write_seq, tcp_wnd_end(tp))) -+ return true; -+ -+ mss_now = tcp_current_mss(sk); -+ -+ /* Don't send on this subflow if we bypass the allowed send-window at -+ * the per-subflow level. Similar to tcp_snd_wnd_test, but manually -+ * calculated end_seq (because here at this point end_seq is still at -+ * the meta-level). -+ */ -+ if (skb && zero_wnd_test && -+ after(tp->write_seq + min(skb->len, mss_now), tcp_wnd_end(tp))) -+ return true; -+ -+ return false; -+} -+ -+/* Is the sub-socket sk available to send the skb? */ -+bool mptcp_is_available(struct sock *sk, const struct sk_buff *skb, -+ bool zero_wnd_test) -+{ -+ return !mptcp_is_def_unavailable(sk) && -+ !mptcp_is_temp_unavailable(sk, skb, zero_wnd_test); -+} -+EXPORT_SYMBOL_GPL(mptcp_is_available); -+ -+/* Are we not allowed to reinject this skb on tp? */ -+static int mptcp_dont_reinject_skb(const struct tcp_sock *tp, const struct sk_buff *skb) -+{ -+ /* If the skb has already been enqueued in this sk, try to find -+ * another one. -+ */ -+ return skb && -+ /* Has the skb already been enqueued into this subsocket? */ -+ mptcp_pi_to_flag(tp->mptcp->path_index) & TCP_SKB_CB(skb)->path_mask; -+} -+ -+bool subflow_is_backup(const struct tcp_sock *tp) -+{ -+ return tp->mptcp->rcv_low_prio || tp->mptcp->low_prio; -+} -+EXPORT_SYMBOL_GPL(subflow_is_backup); -+ -+bool subflow_is_active(const struct tcp_sock *tp) -+{ -+ return !tp->mptcp->rcv_low_prio && !tp->mptcp->low_prio; -+} -+EXPORT_SYMBOL_GPL(subflow_is_active); -+ -+/* Generic function to iterate over used and unused subflows and to select the -+ * best one -+ */ -+static struct sock -+*get_subflow_from_selectors(struct mptcp_cb *mpcb, struct sk_buff *skb, -+ bool (*selector)(const struct tcp_sock *), -+ bool zero_wnd_test, bool *force) -+{ -+ struct sock *bestsk = NULL; -+ u32 min_srtt = 0xffffffff; -+ bool found_unused = false; -+ bool found_unused_una = false; -+ struct mptcp_tcp_sock *mptcp; -+ -+ mptcp_for_each_sub(mpcb, mptcp) { -+ struct sock *sk = mptcp_to_sock(mptcp); -+ struct tcp_sock *tp = tcp_sk(sk); -+ bool unused = false; -+ -+ /* First, we choose only the wanted sks */ -+ if (!(*selector)(tp)) -+ continue; -+ -+ if (!mptcp_dont_reinject_skb(tp, skb)) -+ unused = true; -+ else if (found_unused) -+ /* If a unused sk was found previously, we continue - -+ * no need to check used sks anymore. -+ */ -+ continue; -+ -+ if (mptcp_is_def_unavailable(sk)) -+ continue; -+ -+ if (mptcp_is_temp_unavailable(sk, skb, zero_wnd_test)) { -+ if (unused) -+ found_unused_una = true; -+ continue; -+ } -+ -+ if (unused) { -+ if (!found_unused) { -+ /* It's the first time we encounter an unused -+ * sk - thus we reset the bestsk (which might -+ * have been set to a used sk). -+ */ -+ min_srtt = 0xffffffff; -+ bestsk = NULL; -+ } -+ found_unused = true; -+ } -+ -+ if (tp->srtt_us < min_srtt) { -+ min_srtt = tp->srtt_us; -+ bestsk = sk; -+ } -+ } -+ -+ if (bestsk) { -+ /* The force variable is used to mark the returned sk as -+ * previously used or not-used. -+ */ -+ if (found_unused) -+ *force = true; -+ else -+ *force = false; -+ } else { -+ /* The force variable is used to mark if there are temporally -+ * unavailable not-used sks. -+ */ -+ if (found_unused_una) -+ *force = true; -+ else -+ *force = false; -+ } -+ -+ return bestsk; -+} -+ -+/* This is the scheduler. This function decides on which flow to send -+ * a given MSS. If all subflows are found to be busy, NULL is returned -+ * The flow is selected based on the shortest RTT. -+ * If all paths have full cong windows, we simply return NULL. -+ * -+ * Additionally, this function is aware of the backup-subflows. -+ */ -+struct sock *get_available_subflow(struct sock *meta_sk, struct sk_buff *skb, -+ bool zero_wnd_test) -+{ -+ struct mptcp_cb *mpcb = tcp_sk(meta_sk)->mpcb; -+ struct sock *sk; -+ bool looping = false, force; -+ -+ /* Answer data_fin on same subflow!!! */ -+ if (meta_sk->sk_shutdown & RCV_SHUTDOWN && -+ skb && mptcp_is_data_fin(skb)) { -+ struct mptcp_tcp_sock *mptcp; -+ -+ mptcp_for_each_sub(mpcb, mptcp) { -+ sk = mptcp_to_sock(mptcp); -+ -+ if (tcp_sk(sk)->mptcp->path_index == mpcb->dfin_path_index && -+ mptcp_is_available(sk, skb, zero_wnd_test)) -+ return sk; -+ } -+ } -+ -+ /* Find the best subflow */ -+restart: -+ sk = get_subflow_from_selectors(mpcb, skb, &subflow_is_active, -+ zero_wnd_test, &force); -+ if (force) -+ /* one unused active sk or one NULL sk when there is at least -+ * one temporally unavailable unused active sk -+ */ -+ return sk; -+ -+ sk = get_subflow_from_selectors(mpcb, skb, &subflow_is_backup, -+ zero_wnd_test, &force); -+ if (!force && skb) { -+ /* one used backup sk or one NULL sk where there is no one -+ * temporally unavailable unused backup sk -+ * -+ * the skb passed through all the available active and backups -+ * sks, so clean the path mask -+ */ -+ TCP_SKB_CB(skb)->path_mask = 0; -+ -+ if (!looping) { -+ looping = true; -+ goto restart; -+ } -+ } -+ return sk; -+} -+EXPORT_SYMBOL_GPL(get_available_subflow); -+ -+static struct sk_buff *mptcp_rcv_buf_optimization(struct sock *sk, int penal) -+{ -+ struct sock *meta_sk; -+ const struct tcp_sock *tp = tcp_sk(sk); -+ struct mptcp_tcp_sock *mptcp; -+ struct sk_buff *skb_head; -+ struct defsched_priv *def_p = defsched_get_priv(tp); -+ -+ meta_sk = mptcp_meta_sk(sk); -+ skb_head = tcp_rtx_queue_head(meta_sk); -+ -+ if (!skb_head) -+ return NULL; -+ -+ /* If penalization is optional (coming from mptcp_next_segment() and -+ * We are not send-buffer-limited we do not penalize. The retransmission -+ * is just an optimization to fix the idle-time due to the delay before -+ * we wake up the application. -+ */ -+ if (!penal && sk_stream_memory_free(meta_sk)) -+ goto retrans; -+ -+ /* Only penalize again after an RTT has elapsed */ -+ if (tcp_jiffies32 - def_p->last_rbuf_opti < usecs_to_jiffies(tp->srtt_us >> 3)) -+ goto retrans; -+ -+ /* Half the cwnd of the slow flows */ -+ mptcp_for_each_sub(tp->mpcb, mptcp) { -+ struct tcp_sock *tp_it = mptcp->tp; -+ -+ if (tp_it != tp && -+ TCP_SKB_CB(skb_head)->path_mask & mptcp_pi_to_flag(tp_it->mptcp->path_index)) { -+ if (tp->srtt_us < tp_it->srtt_us && inet_csk((struct sock *)tp_it)->icsk_ca_state == TCP_CA_Open) { -+ u32 prior_cwnd = tp_it->snd_cwnd; -+ -+ tp_it->snd_cwnd = max(tp_it->snd_cwnd >> 1U, 1U); -+ -+ /* If in slow start, do not reduce the ssthresh */ -+ if (prior_cwnd >= tp_it->snd_ssthresh) -+ tp_it->snd_ssthresh = max(tp_it->snd_ssthresh >> 1U, 2U); -+ -+ def_p->last_rbuf_opti = tcp_jiffies32; -+ } -+ } -+ } -+ -+retrans: -+ -+ /* Segment not yet injected into this path? Take it!!! */ -+ if (!(TCP_SKB_CB(skb_head)->path_mask & mptcp_pi_to_flag(tp->mptcp->path_index))) { -+ bool do_retrans = false; -+ mptcp_for_each_sub(tp->mpcb, mptcp) { -+ struct tcp_sock *tp_it = mptcp->tp; -+ -+ if (tp_it != tp && -+ TCP_SKB_CB(skb_head)->path_mask & mptcp_pi_to_flag(tp_it->mptcp->path_index)) { -+ if (tp_it->snd_cwnd <= 4) { -+ do_retrans = true; -+ break; -+ } -+ -+ if (4 * tp->srtt_us >= tp_it->srtt_us) { -+ do_retrans = false; -+ break; -+ } else { -+ do_retrans = true; -+ } -+ } -+ } -+ -+ if (do_retrans && mptcp_is_available(sk, skb_head, false)) { -+ trace_mptcp_retransmit(sk, skb_head); -+ return skb_head; -+ } -+ } -+ return NULL; -+} -+ -+/* Returns the next segment to be sent from the mptcp meta-queue. -+ * (chooses the reinject queue if any segment is waiting in it, otherwise, -+ * chooses the normal write queue). -+ * Sets *@reinject to 1 if the returned segment comes from the -+ * reinject queue. Sets it to 0 if it is the regular send-head of the meta-sk, -+ * and sets it to -1 if it is a meta-level retransmission to optimize the -+ * receive-buffer. -+ */ -+static struct sk_buff *__mptcp_next_segment(struct sock *meta_sk, int *reinject) -+{ -+ const struct mptcp_cb *mpcb = tcp_sk(meta_sk)->mpcb; -+ struct sk_buff *skb = NULL; -+ -+ *reinject = 0; -+ -+ /* If we are in fallback-mode, just take from the meta-send-queue */ -+ if (mpcb->infinite_mapping_snd || mpcb->send_infinite_mapping) -+ return tcp_send_head(meta_sk); -+ -+ skb = skb_peek(&mpcb->reinject_queue); -+ -+ if (skb) { -+ *reinject = 1; -+ } else { -+ skb = tcp_send_head(meta_sk); -+ -+ if (!skb && meta_sk->sk_socket && -+ test_bit(SOCK_NOSPACE, &meta_sk->sk_socket->flags) && -+ sk_stream_wspace(meta_sk) < sk_stream_min_wspace(meta_sk)) { -+ struct sock *subsk = get_available_subflow(meta_sk, NULL, -+ false); -+ if (!subsk) -+ return NULL; -+ -+ skb = mptcp_rcv_buf_optimization(subsk, 0); -+ if (skb) -+ *reinject = -1; -+ } -+ } -+ return skb; -+} -+ -+static struct sk_buff *mptcp_next_segment(struct sock *meta_sk, -+ int *reinject, -+ struct sock **subsk, -+ unsigned int *limit) -+{ -+ struct sk_buff *skb = __mptcp_next_segment(meta_sk, reinject); -+ unsigned int mss_now; -+ struct tcp_sock *subtp; -+ u16 gso_max_segs; -+ u32 max_len, max_segs, window, needed; -+ -+ /* As we set it, we have to reset it as well. */ -+ *limit = 0; -+ -+ if (!skb) -+ return NULL; -+ -+ *subsk = get_available_subflow(meta_sk, skb, false); -+ if (!*subsk) -+ return NULL; -+ -+ subtp = tcp_sk(*subsk); -+ mss_now = tcp_current_mss(*subsk); -+ -+ if (!*reinject && unlikely(!tcp_snd_wnd_test(tcp_sk(meta_sk), skb, mss_now))) { -+ skb = mptcp_rcv_buf_optimization(*subsk, 1); -+ if (skb) -+ *reinject = -1; -+ else -+ return NULL; -+ } -+ -+ /* No splitting required, as we will only send one single segment */ -+ if (skb->len <= mss_now) -+ return skb; -+ -+ /* The following is similar to tcp_mss_split_point, but -+ * we do not care about nagle, because we will anyways -+ * use TCP_NAGLE_PUSH, which overrides this. -+ * -+ * So, we first limit according to the cwnd/gso-size and then according -+ * to the subflow's window. -+ */ -+ -+ gso_max_segs = (*subsk)->sk_gso_max_segs; -+ if (!gso_max_segs) /* No gso supported on the subflow's NIC */ -+ gso_max_segs = 1; -+ max_segs = min_t(unsigned int, tcp_cwnd_test(subtp, skb), gso_max_segs); -+ if (!max_segs) -+ return NULL; -+ -+ max_len = mss_now * max_segs; -+ window = tcp_wnd_end(subtp) - subtp->write_seq; -+ -+ needed = min(skb->len, window); -+ if (max_len <= skb->len) -+ /* Take max_win, which is actually the cwnd/gso-size */ -+ *limit = max_len; -+ else -+ /* Or, take the window */ -+ *limit = needed; -+ -+ return skb; -+} -+ -+static void defsched_init(struct sock *sk) -+{ -+ struct defsched_priv *def_p = defsched_get_priv(tcp_sk(sk)); -+ -+ def_p->last_rbuf_opti = tcp_jiffies32; -+} -+ -+struct mptcp_sched_ops mptcp_sched_default = { -+ .get_subflow = get_available_subflow, -+ .next_segment = mptcp_next_segment, -+ .init = defsched_init, -+ .name = "default", -+ .owner = THIS_MODULE, -+}; -+ -+static struct mptcp_sched_ops *mptcp_sched_find(const char *name) -+{ -+ struct mptcp_sched_ops *e; -+ -+ list_for_each_entry_rcu(e, &mptcp_sched_list, list) { -+ if (strcmp(e->name, name) == 0) -+ return e; -+ } -+ -+ return NULL; -+} -+ -+int mptcp_register_scheduler(struct mptcp_sched_ops *sched) -+{ -+ int ret = 0; -+ -+ if (!sched->get_subflow || !sched->next_segment) -+ return -EINVAL; -+ -+ spin_lock(&mptcp_sched_list_lock); -+ if (mptcp_sched_find(sched->name)) { -+ pr_notice("%s already registered\n", sched->name); -+ ret = -EEXIST; -+ } else { -+ list_add_tail_rcu(&sched->list, &mptcp_sched_list); -+ pr_info("%s registered\n", sched->name); -+ } -+ spin_unlock(&mptcp_sched_list_lock); -+ -+ return ret; -+} -+EXPORT_SYMBOL_GPL(mptcp_register_scheduler); -+ -+void mptcp_unregister_scheduler(struct mptcp_sched_ops *sched) -+{ -+ spin_lock(&mptcp_sched_list_lock); -+ list_del_rcu(&sched->list); -+ spin_unlock(&mptcp_sched_list_lock); -+ -+ /* Wait for outstanding readers to complete before the -+ * module gets removed entirely. -+ * -+ * A try_module_get() should fail by now as our module is -+ * in "going" state since no refs are held anymore and -+ * module_exit() handler being called. -+ */ -+ synchronize_rcu(); -+} -+EXPORT_SYMBOL_GPL(mptcp_unregister_scheduler); -+ -+void mptcp_get_default_scheduler(char *name) -+{ -+ struct mptcp_sched_ops *sched; -+ -+ BUG_ON(list_empty(&mptcp_sched_list)); -+ -+ rcu_read_lock(); -+ sched = list_entry(mptcp_sched_list.next, struct mptcp_sched_ops, list); -+ strncpy(name, sched->name, MPTCP_SCHED_NAME_MAX); -+ rcu_read_unlock(); -+} -+ -+int mptcp_set_default_scheduler(const char *name) -+{ -+ struct mptcp_sched_ops *sched; -+ int ret = -ENOENT; -+ -+ spin_lock(&mptcp_sched_list_lock); -+ sched = mptcp_sched_find(name); -+#ifdef CONFIG_MODULES -+ if (!sched && capable(CAP_NET_ADMIN)) { -+ spin_unlock(&mptcp_sched_list_lock); -+ -+ request_module("mptcp_%s", name); -+ spin_lock(&mptcp_sched_list_lock); -+ sched = mptcp_sched_find(name); -+ } -+#endif -+ -+ if (sched) { -+ list_move(&sched->list, &mptcp_sched_list); -+ ret = 0; -+ } else { -+ pr_info("%s is not available\n", name); -+ } -+ spin_unlock(&mptcp_sched_list_lock); -+ -+ return ret; -+} -+ -+/* Must be called with rcu lock held */ -+static struct mptcp_sched_ops *__mptcp_sched_find_autoload(const char *name) -+{ -+ struct mptcp_sched_ops *sched = mptcp_sched_find(name); -+#ifdef CONFIG_MODULES -+ if (!sched && capable(CAP_NET_ADMIN)) { -+ rcu_read_unlock(); -+ request_module("mptcp_%s", name); -+ rcu_read_lock(); -+ sched = mptcp_sched_find(name); -+ } -+#endif -+ return sched; -+} -+ -+void mptcp_init_scheduler(struct mptcp_cb *mpcb) -+{ -+ struct mptcp_sched_ops *sched; -+ struct sock *meta_sk = mpcb->meta_sk; -+ struct tcp_sock *meta_tp = tcp_sk(meta_sk); -+ -+ rcu_read_lock(); -+ /* if scheduler was set using socket option */ -+ if (meta_tp->mptcp_sched_setsockopt) { -+ sched = __mptcp_sched_find_autoload(meta_tp->mptcp_sched_name); -+ if (sched && try_module_get(sched->owner)) { -+ mpcb->sched_ops = sched; -+ goto out; -+ } -+ } -+ -+ list_for_each_entry_rcu(sched, &mptcp_sched_list, list) { -+ if (try_module_get(sched->owner)) { -+ mpcb->sched_ops = sched; -+ break; -+ } -+ } -+out: -+ rcu_read_unlock(); -+} -+ -+/* Change scheduler for socket */ -+int mptcp_set_scheduler(struct sock *sk, const char *name) -+{ -+ struct mptcp_sched_ops *sched; -+ int err = 0; -+ -+ rcu_read_lock(); -+ sched = __mptcp_sched_find_autoload(name); -+ -+ if (!sched) { -+ err = -ENOENT; -+ } else if (!ns_capable(sock_net(sk)->user_ns, CAP_NET_ADMIN)) { -+ err = -EPERM; -+ } else { -+ strcpy(tcp_sk(sk)->mptcp_sched_name, name); -+ tcp_sk(sk)->mptcp_sched_setsockopt = 1; -+ } -+ rcu_read_unlock(); -+ -+ return err; -+} -+ -+/* Manage refcounts on socket close. */ -+void mptcp_cleanup_scheduler(struct mptcp_cb *mpcb) -+{ -+ module_put(mpcb->sched_ops->owner); -+} -+ -+/* Set default value from kernel configuration at bootup */ -+static int __init mptcp_scheduler_default(void) -+{ -+ BUILD_BUG_ON(sizeof(struct defsched_priv) > MPTCP_SCHED_SIZE); -+ -+ return mptcp_set_default_scheduler(CONFIG_DEFAULT_MPTCP_SCHED); -+} -+late_initcall(mptcp_scheduler_default); -diff -aurN linux-4.19.104/net/mptcp/mptcp_wvegas.c mptcp-mptcp_v0.95/net/mptcp/mptcp_wvegas.c ---- linux-4.19.104/net/mptcp/mptcp_wvegas.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_v0.95/net/mptcp/mptcp_wvegas.c 2020-02-17 11:29:55.000000000 +0100 -@@ -0,0 +1,271 @@ -+/* -+ * MPTCP implementation - WEIGHTED VEGAS -+ * -+ * Algorithm design: -+ * Yu Cao -+ * Mingwei Xu -+ * Xiaoming Fu -+ * -+ * Implementation: -+ * Yu Cao -+ * Enhuan Dong -+ * -+ * Ported to the official MPTCP-kernel: -+ * Christoph Paasch -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version -+ * 2 of the License, or (at your option) any later version. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+static int initial_alpha = 2; -+static int total_alpha = 10; -+static int gamma = 1; -+ -+module_param(initial_alpha, int, 0644); -+MODULE_PARM_DESC(initial_alpha, "initial alpha for all subflows"); -+module_param(total_alpha, int, 0644); -+MODULE_PARM_DESC(total_alpha, "total alpha for all subflows"); -+module_param(gamma, int, 0644); -+MODULE_PARM_DESC(gamma, "limit on increase (scale by 2)"); -+ -+#define MPTCP_WVEGAS_SCALE 16 -+ -+/* wVegas variables */ -+struct wvegas { -+ u32 beg_snd_nxt; /* right edge during last RTT */ -+ u8 doing_wvegas_now;/* if true, do wvegas for this RTT */ -+ -+ u16 cnt_rtt; /* # of RTTs measured within last RTT */ -+ u32 sampled_rtt; /* cumulative RTTs measured within last RTT (in usec) */ -+ u32 base_rtt; /* the min of all wVegas RTT measurements seen (in usec) */ -+ -+ u64 instant_rate; /* cwnd / srtt_us, unit: pkts/us * 2^16 */ -+ u64 weight; /* the ratio of subflow's rate to the total rate, * 2^16 */ -+ int alpha; /* alpha for each subflows */ -+ -+ u32 queue_delay; /* queue delay*/ -+}; -+ -+ -+static inline u64 mptcp_wvegas_scale(u32 val, int scale) -+{ -+ return (u64) val << scale; -+} -+ -+static void wvegas_enable(const struct sock *sk) -+{ -+ const struct tcp_sock *tp = tcp_sk(sk); -+ struct wvegas *wvegas = inet_csk_ca(sk); -+ -+ wvegas->doing_wvegas_now = 1; -+ -+ wvegas->beg_snd_nxt = tp->snd_nxt; -+ -+ wvegas->cnt_rtt = 0; -+ wvegas->sampled_rtt = 0; -+ -+ wvegas->instant_rate = 0; -+ wvegas->alpha = initial_alpha; -+ wvegas->weight = mptcp_wvegas_scale(1, MPTCP_WVEGAS_SCALE); -+ -+ wvegas->queue_delay = 0; -+} -+ -+static inline void wvegas_disable(const struct sock *sk) -+{ -+ struct wvegas *wvegas = inet_csk_ca(sk); -+ -+ wvegas->doing_wvegas_now = 0; -+} -+ -+static void mptcp_wvegas_init(struct sock *sk) -+{ -+ struct wvegas *wvegas = inet_csk_ca(sk); -+ -+ wvegas->base_rtt = 0x7fffffff; -+ wvegas_enable(sk); -+} -+ -+static inline u64 mptcp_wvegas_rate(u32 cwnd, u32 rtt_us) -+{ -+ return div_u64(mptcp_wvegas_scale(cwnd, MPTCP_WVEGAS_SCALE), rtt_us); -+} -+ -+static void mptcp_wvegas_pkts_acked(struct sock *sk, -+ const struct ack_sample *sample) -+{ -+ struct wvegas *wvegas = inet_csk_ca(sk); -+ u32 vrtt; -+ -+ if (sample->rtt_us < 0) -+ return; -+ -+ vrtt = sample->rtt_us + 1; -+ -+ if (vrtt < wvegas->base_rtt) -+ wvegas->base_rtt = vrtt; -+ -+ wvegas->sampled_rtt += vrtt; -+ wvegas->cnt_rtt++; -+} -+ -+static void mptcp_wvegas_state(struct sock *sk, u8 ca_state) -+{ -+ if (ca_state == TCP_CA_Open) -+ wvegas_enable(sk); -+ else -+ wvegas_disable(sk); -+} -+ -+static void mptcp_wvegas_cwnd_event(struct sock *sk, enum tcp_ca_event event) -+{ -+ if (event == CA_EVENT_CWND_RESTART) { -+ mptcp_wvegas_init(sk); -+ } else if (event == CA_EVENT_LOSS) { -+ struct wvegas *wvegas = inet_csk_ca(sk); -+ wvegas->instant_rate = 0; -+ } -+} -+ -+static inline u32 mptcp_wvegas_ssthresh(const struct tcp_sock *tp) -+{ -+ return min(tp->snd_ssthresh, tp->snd_cwnd); -+} -+ -+static u64 mptcp_wvegas_weight(const struct mptcp_cb *mpcb, const struct sock *sk) -+{ -+ u64 total_rate = 0; -+ const struct wvegas *wvegas = inet_csk_ca(sk); -+ struct mptcp_tcp_sock *mptcp; -+ -+ if (!mpcb) -+ return wvegas->weight; -+ -+ -+ mptcp_for_each_sub(mpcb, mptcp) { -+ struct sock *sub_sk = mptcp_to_sock(mptcp); -+ struct wvegas *sub_wvegas = inet_csk_ca(sub_sk); -+ -+ /* sampled_rtt is initialized by 0 */ -+ if (mptcp_sk_can_send(sub_sk) && (sub_wvegas->sampled_rtt > 0)) -+ total_rate += sub_wvegas->instant_rate; -+ } -+ -+ if (total_rate && wvegas->instant_rate) -+ return div64_u64(mptcp_wvegas_scale(wvegas->instant_rate, MPTCP_WVEGAS_SCALE), total_rate); -+ else -+ return wvegas->weight; -+} -+ -+static void mptcp_wvegas_cong_avoid(struct sock *sk, u32 ack, u32 acked) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct wvegas *wvegas = inet_csk_ca(sk); -+ -+ if (!wvegas->doing_wvegas_now) { -+ tcp_reno_cong_avoid(sk, ack, acked); -+ return; -+ } -+ -+ if (after(ack, wvegas->beg_snd_nxt)) { -+ wvegas->beg_snd_nxt = tp->snd_nxt; -+ -+ if (wvegas->cnt_rtt <= 2) { -+ tcp_reno_cong_avoid(sk, ack, acked); -+ } else { -+ u32 rtt, diff, q_delay; -+ u64 target_cwnd; -+ -+ rtt = wvegas->sampled_rtt / wvegas->cnt_rtt; -+ target_cwnd = div_u64(((u64)tp->snd_cwnd * wvegas->base_rtt), rtt); -+ -+ diff = div_u64((u64)tp->snd_cwnd * (rtt - wvegas->base_rtt), rtt); -+ -+ if (diff > gamma && tcp_in_slow_start(tp)) { -+ tp->snd_cwnd = min(tp->snd_cwnd, (u32)target_cwnd+1); -+ tp->snd_ssthresh = mptcp_wvegas_ssthresh(tp); -+ -+ } else if (tcp_in_slow_start(tp)) { -+ tcp_slow_start(tp, acked); -+ } else { -+ if (diff >= wvegas->alpha) { -+ wvegas->instant_rate = mptcp_wvegas_rate(tp->snd_cwnd, rtt); -+ wvegas->weight = mptcp_wvegas_weight(tp->mpcb, sk); -+ wvegas->alpha = max(2U, (u32)((wvegas->weight * total_alpha) >> MPTCP_WVEGAS_SCALE)); -+ } -+ if (diff > wvegas->alpha) { -+ tp->snd_cwnd--; -+ tp->snd_ssthresh = mptcp_wvegas_ssthresh(tp); -+ } else if (diff < wvegas->alpha) { -+ tp->snd_cwnd++; -+ } -+ -+ /* Try to drain link queue if needed*/ -+ q_delay = rtt - wvegas->base_rtt; -+ if ((wvegas->queue_delay == 0) || (wvegas->queue_delay > q_delay)) -+ wvegas->queue_delay = q_delay; -+ -+ if (q_delay >= 2 * wvegas->queue_delay) { -+ u32 backoff_factor = div_u64(mptcp_wvegas_scale(wvegas->base_rtt, MPTCP_WVEGAS_SCALE), 2 * rtt); -+ tp->snd_cwnd = ((u64)tp->snd_cwnd * backoff_factor) >> MPTCP_WVEGAS_SCALE; -+ wvegas->queue_delay = 0; -+ } -+ } -+ -+ if (tp->snd_cwnd < 2) -+ tp->snd_cwnd = 2; -+ else if (tp->snd_cwnd > tp->snd_cwnd_clamp) -+ tp->snd_cwnd = tp->snd_cwnd_clamp; -+ -+ tp->snd_ssthresh = tcp_current_ssthresh(sk); -+ } -+ -+ wvegas->cnt_rtt = 0; -+ wvegas->sampled_rtt = 0; -+ } -+ /* Use normal slow start */ -+ else if (tcp_in_slow_start(tp)) -+ tcp_slow_start(tp, acked); -+} -+ -+ -+static struct tcp_congestion_ops mptcp_wvegas __read_mostly = { -+ .init = mptcp_wvegas_init, -+ .ssthresh = tcp_reno_ssthresh, -+ .cong_avoid = mptcp_wvegas_cong_avoid, -+ .undo_cwnd = tcp_reno_undo_cwnd, -+ .pkts_acked = mptcp_wvegas_pkts_acked, -+ .set_state = mptcp_wvegas_state, -+ .cwnd_event = mptcp_wvegas_cwnd_event, -+ -+ .owner = THIS_MODULE, -+ .name = "wvegas", -+}; -+ -+static int __init mptcp_wvegas_register(void) -+{ -+ BUILD_BUG_ON(sizeof(struct wvegas) > ICSK_CA_PRIV_SIZE); -+ tcp_register_congestion_control(&mptcp_wvegas); -+ return 0; -+} -+ -+static void __exit mptcp_wvegas_unregister(void) -+{ -+ tcp_unregister_congestion_control(&mptcp_wvegas); -+} -+ -+module_init(mptcp_wvegas_register); -+module_exit(mptcp_wvegas_unregister); -+ -+MODULE_AUTHOR("Yu Cao, Enhuan Dong"); -+MODULE_LICENSE("GPL"); -+MODULE_DESCRIPTION("MPTCP wVegas"); -+MODULE_VERSION("0.1"); -diff -aurN linux-4.19.104/tools/include/uapi/linux/bpf.h mptcp-mptcp_v0.95/tools/include/uapi/linux/bpf.h ---- linux-4.19.104/tools/include/uapi/linux/bpf.h 2020-02-14 22:33:28.000000000 +0100 -+++ mptcp-mptcp_v0.95/tools/include/uapi/linux/bpf.h 2020-02-17 11:29:55.000000000 +0100 -@@ -2672,6 +2672,7 @@ - BPF_TCP_LISTEN, - BPF_TCP_CLOSING, /* Now a valid state */ - BPF_TCP_NEW_SYN_RECV, -+ BPF_TCP_RST_WAIT, - - BPF_TCP_MAX_STATES /* Leave at the end! */ - }; diff --git a/root/target/linux/generic/hack-4.19/691-mptcp_ecf.patch b/root/target/linux/generic/hack-4.19/691-mptcp_ecf.patch deleted file mode 100644 index d9cf6251..00000000 --- a/root/target/linux/generic/hack-4.19/691-mptcp_ecf.patch +++ /dev/null @@ -1,434 +0,0 @@ -From 35f41229b58cb8c2611207827aa4f658b82db67e Mon Sep 17 00:00:00 2001 -From: Daniel Weber -Date: Mon, 5 Aug 2019 14:02:30 +0200 -Subject: [PATCH] mptcp: Earliest Completion First (ECF) Scheduler - -This scheduler works much like the default MPTCP scheduler. It always -prefers the subflow with the smallest round-trip-time that is available. - -Signed-off-by: Daniel Weber ---- - net/mptcp/Kconfig | 6 + - net/mptcp/Makefile | 1 + - net/mptcp/mptcp_ecf.c | 384 ++++++++++++++++++++++++++++++++++++++++++ - 3 files changed, 391 insertions(+) - create mode 100644 net/mptcp/mptcp_ecf.c - -diff --git a/net/mptcp/Kconfig b/net/mptcp/Kconfig -index d22b7b47860f..dd1f859f1070 100644 ---- a/net/mptcp/Kconfig -+++ b/net/mptcp/Kconfig -@@ -109,6 +109,12 @@ config MPTCP_REDUNDANT - This scheduler sends all packets redundantly over all subflows to decreases - latency and jitter on the cost of lower throughput. - -+config MPTCP_ECF -+ tristate "MPTCP ECF" -+ depends on (MPTCP=y) -+ ---help--- -+ This is an experimental Earliest Completion First (ECF) scheduler. -+ - choice - prompt "Default MPTCP Scheduler" - default DEFAULT -diff --git a/net/mptcp/Makefile b/net/mptcp/Makefile -index 82a2d4d945ae..369248a2f68e 100644 ---- a/net/mptcp/Makefile -+++ b/net/mptcp/Makefile -@@ -20,5 +20,6 @@ obj-$(CONFIG_MPTCP_NETLINK) += mptcp_netlink.o - obj-$(CONFIG_MPTCP_ROUNDROBIN) += mptcp_rr.o - obj-$(CONFIG_MPTCP_REDUNDANT) += mptcp_redundant.o - obj-$(CONFIG_MPTCP_BLEST) += mptcp_blest.o -+obj-$(CONFIG_MPTCP_ECF) += mptcp_ecf.o - - mptcp-$(subst m,y,$(CONFIG_IPV6)) += mptcp_ipv6.o -diff --git a/net/mptcp/mptcp_ecf.c b/net/mptcp/mptcp_ecf.c -new file mode 100644 -index 000000000000..d61f4d2ad375 ---- /dev/null -+++ b/net/mptcp/mptcp_ecf.c -@@ -0,0 +1,384 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* MPTCP ECF Scheduler -+ * -+ * Algorithm Design: -+ * Yeon-sup Lim -+ * Don Towsley -+ * Erich M. Nahum -+ * Richard J. Gibbens -+ * -+ * Initial Implementation: -+ * Yeon-sup Lim -+ * -+ * Additional Authors: -+ * Daniel Weber -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version -+ * 2 of the License, or (at your option) any later version. -+ */ -+ -+#include -+#include -+#include -+ -+static unsigned int r_beta __read_mostly = 4; /* beta = 1/r_beta = 0.25 */ -+module_param(r_beta, int, 0644); -+MODULE_PARM_DESC(r_beta, "beta for ECF"); -+ -+struct ecfsched_priv { -+ u32 last_rbuf_opti; -+}; -+ -+struct ecfsched_cb { -+ u32 switching_margin; /* this is "waiting" in algorithm description */ -+}; -+ -+static struct ecfsched_priv *ecfsched_get_priv(const struct tcp_sock *tp) -+{ -+ return (struct ecfsched_priv *)&tp->mptcp->mptcp_sched[0]; -+} -+ -+static struct ecfsched_cb *ecfsched_get_cb(const struct tcp_sock *tp) -+{ -+ return (struct ecfsched_cb *)&tp->mpcb->mptcp_sched[0]; -+} -+ -+/* This is the ECF scheduler. This function decides on which flow to send -+ * a given MSS. If all subflows are found to be busy or the currently best -+ * subflow is estimated to be slower than waiting for minsk, NULL is returned. -+ */ -+static struct sock *ecf_get_available_subflow(struct sock *meta_sk, -+ struct sk_buff *skb, -+ bool zero_wnd_test) -+{ -+ struct mptcp_cb *mpcb = tcp_sk(meta_sk)->mpcb; -+ struct sock *bestsk, *minsk = NULL; -+ struct tcp_sock *besttp; -+ struct mptcp_tcp_sock *mptcp; -+ struct ecfsched_cb *ecf_cb = ecfsched_get_cb(tcp_sk(meta_sk)); -+ u32 min_srtt = U32_MAX; -+ u32 sub_sndbuf = 0; -+ u32 sub_packets_out = 0; -+ -+ /* Answer data_fin on same subflow!!! */ -+ if (meta_sk->sk_shutdown & RCV_SHUTDOWN && -+ skb && mptcp_is_data_fin(skb)) { -+ mptcp_for_each_sub(mpcb, mptcp) { -+ bestsk = mptcp_to_sock(mptcp); -+ -+ if (tcp_sk(bestsk)->mptcp->path_index == mpcb->dfin_path_index && -+ mptcp_is_available(bestsk, skb, zero_wnd_test)) -+ return bestsk; -+ } -+ } -+ -+ /* First, find the overall best (fastest) subflow */ -+ mptcp_for_each_sub(mpcb, mptcp) { -+ bestsk = mptcp_to_sock(mptcp); -+ besttp = tcp_sk(bestsk); -+ -+ /* Set of states for which we are allowed to send data */ -+ if (!mptcp_sk_can_send(bestsk)) -+ continue; -+ -+ /* We do not send data on this subflow unless it is -+ * fully established, i.e. the 4th ack has been received. -+ */ -+ if (besttp->mptcp->pre_established) -+ continue; -+ -+ sub_sndbuf += bestsk->sk_wmem_queued; -+ sub_packets_out += besttp->packets_out; -+ -+ /* record minimal rtt */ -+ if (besttp->srtt_us < min_srtt) { -+ min_srtt = besttp->srtt_us; -+ minsk = bestsk; -+ } -+ } -+ -+ /* find the current best subflow according to the default scheduler */ -+ bestsk = get_available_subflow(meta_sk, skb, zero_wnd_test); -+ -+ /* if we decided to use a slower flow, we have the option of not using it at all */ -+ if (bestsk && minsk && bestsk != minsk) { -+ u32 mss = tcp_current_mss(bestsk); /* assuming equal MSS */ -+ u32 sndbuf_meta = meta_sk->sk_wmem_queued; -+ u32 sndbuf_minus = sub_sndbuf; -+ u32 sndbuf = 0; -+ -+ u32 cwnd_f = tcp_sk(minsk)->snd_cwnd; -+ u32 srtt_f = tcp_sk(minsk)->srtt_us >> 3; -+ u32 rttvar_f = tcp_sk(minsk)->rttvar_us >> 1; -+ -+ u32 cwnd_s = tcp_sk(bestsk)->snd_cwnd; -+ u32 srtt_s = tcp_sk(bestsk)->srtt_us >> 3; -+ u32 rttvar_s = tcp_sk(bestsk)->rttvar_us >> 1; -+ -+ u32 delta = max(rttvar_f, rttvar_s); -+ -+ u32 x_f; -+ u64 lhs, rhs; /* to avoid overflow, using u64 */ -+ -+ if (tcp_sk(meta_sk)->packets_out > sub_packets_out) -+ sndbuf_minus += (tcp_sk(meta_sk)->packets_out - sub_packets_out) * mss; -+ -+ if (sndbuf_meta > sndbuf_minus) -+ sndbuf = sndbuf_meta - sndbuf_minus; -+ -+ /* we have something to send. -+ * at least one time tx over fastest subflow is required -+ */ -+ x_f = sndbuf > cwnd_f * mss ? sndbuf : cwnd_f * mss; -+ lhs = srtt_f * (x_f + cwnd_f * mss); -+ rhs = cwnd_f * mss * (srtt_s + delta); -+ -+ if (r_beta * lhs < r_beta * rhs + ecf_cb->switching_margin * rhs) { -+ u32 x_s = sndbuf > cwnd_s * mss ? sndbuf : cwnd_s * mss; -+ u64 lhs_s = srtt_s * x_s; -+ u64 rhs_s = cwnd_s * mss * (2 * srtt_f + delta); -+ -+ if (lhs_s >= rhs_s) { -+ /* too slower than fastest */ -+ ecf_cb->switching_margin = 1; -+ return NULL; -+ } -+ } else { -+ /* use slower one */ -+ ecf_cb->switching_margin = 0; -+ } -+ } -+ -+ return bestsk; -+} -+ -+/* copy from mptcp_sched.c: mptcp_rcv_buf_optimization */ -+static struct sk_buff *mptcp_ecf_rcv_buf_optimization(struct sock *sk, int penal) -+{ -+ struct sock *meta_sk; -+ const struct tcp_sock *tp = tcp_sk(sk); -+ struct mptcp_tcp_sock *mptcp; -+ struct sk_buff *skb_head; -+ struct ecfsched_priv *ecf_p = ecfsched_get_priv(tp); -+ -+ meta_sk = mptcp_meta_sk(sk); -+ skb_head = tcp_rtx_queue_head(meta_sk); -+ -+ if (!skb_head) -+ return NULL; -+ -+ /* If penalization is optional (coming from mptcp_next_segment() and -+ * We are not send-buffer-limited we do not penalize. The retransmission -+ * is just an optimization to fix the idle-time due to the delay before -+ * we wake up the application. -+ */ -+ if (!penal && sk_stream_memory_free(meta_sk)) -+ goto retrans; -+ -+ /* Only penalize again after an RTT has elapsed */ -+ if (tcp_jiffies32 - ecf_p->last_rbuf_opti < usecs_to_jiffies(tp->srtt_us >> 3)) -+ goto retrans; -+ -+ /* Half the cwnd of the slow flows */ -+ mptcp_for_each_sub(tp->mpcb, mptcp) { -+ struct tcp_sock *tp_it = mptcp->tp; -+ -+ if (tp_it != tp && -+ TCP_SKB_CB(skb_head)->path_mask & mptcp_pi_to_flag(tp_it->mptcp->path_index)) { -+ if (tp->srtt_us < tp_it->srtt_us && inet_csk((struct sock *)tp_it)->icsk_ca_state == TCP_CA_Open) { -+ u32 prior_cwnd = tp_it->snd_cwnd; -+ -+ tp_it->snd_cwnd = max(tp_it->snd_cwnd >> 1U, 1U); -+ -+ /* If in slow start, do not reduce the ssthresh */ -+ if (prior_cwnd >= tp_it->snd_ssthresh) -+ tp_it->snd_ssthresh = max(tp_it->snd_ssthresh >> 1U, 2U); -+ -+ ecf_p->last_rbuf_opti = tcp_jiffies32; -+ } -+ } -+ } -+ -+retrans: -+ -+ /* Segment not yet injected into this path? Take it!!! */ -+ if (!(TCP_SKB_CB(skb_head)->path_mask & mptcp_pi_to_flag(tp->mptcp->path_index))) { -+ bool do_retrans = false; -+ mptcp_for_each_sub(tp->mpcb, mptcp) { -+ struct tcp_sock *tp_it = mptcp->tp; -+ -+ if (tp_it != tp && -+ TCP_SKB_CB(skb_head)->path_mask & mptcp_pi_to_flag(tp_it->mptcp->path_index)) { -+ if (tp_it->snd_cwnd <= 4) { -+ do_retrans = true; -+ break; -+ } -+ -+ if (4 * tp->srtt_us >= tp_it->srtt_us) { -+ do_retrans = false; -+ break; -+ } else { -+ do_retrans = true; -+ } -+ } -+ } -+ -+ if (do_retrans && mptcp_is_available(sk, skb_head, false)) { -+ trace_mptcp_retransmit(sk, skb_head); -+ return skb_head; -+ } -+ } -+ return NULL; -+} -+ -+/* copy from mptcp_sched.c: __mptcp_next_segment */ -+/* Returns the next segment to be sent from the mptcp meta-queue. -+ * (chooses the reinject queue if any segment is waiting in it, otherwise, -+ * chooses the normal write queue). -+ * Sets *@reinject to 1 if the returned segment comes from the -+ * reinject queue. Sets it to 0 if it is the regular send-head of the meta-sk, -+ * and sets it to -1 if it is a meta-level retransmission to optimize the -+ * receive-buffer. -+ */ -+static struct sk_buff *__mptcp_ecf_next_segment(struct sock *meta_sk, int *reinject) -+{ -+ const struct mptcp_cb *mpcb = tcp_sk(meta_sk)->mpcb; -+ struct sk_buff *skb = NULL; -+ -+ *reinject = 0; -+ -+ /* If we are in fallback-mode, just take from the meta-send-queue */ -+ if (mpcb->infinite_mapping_snd || mpcb->send_infinite_mapping) -+ return tcp_send_head(meta_sk); -+ -+ skb = skb_peek(&mpcb->reinject_queue); -+ -+ if (skb) { -+ *reinject = 1; -+ } else { -+ skb = tcp_send_head(meta_sk); -+ -+ if (!skb && meta_sk->sk_socket && -+ test_bit(SOCK_NOSPACE, &meta_sk->sk_socket->flags) && -+ sk_stream_wspace(meta_sk) < sk_stream_min_wspace(meta_sk)) { -+ struct sock *subsk = ecf_get_available_subflow(meta_sk, NULL, -+ false); -+ if (!subsk) -+ return NULL; -+ -+ skb = mptcp_ecf_rcv_buf_optimization(subsk, 0); -+ if (skb) -+ *reinject = -1; -+ } -+ } -+ return skb; -+} -+ -+/* copy from mptcp_sched.c: mptcp_next_segment */ -+static struct sk_buff *mptcp_ecf_next_segment(struct sock *meta_sk, -+ int *reinject, -+ struct sock **subsk, -+ unsigned int *limit) -+{ -+ struct sk_buff *skb = __mptcp_ecf_next_segment(meta_sk, reinject); -+ unsigned int mss_now; -+ struct tcp_sock *subtp; -+ u16 gso_max_segs; -+ u32 max_len, max_segs, window, needed; -+ -+ /* As we set it, we have to reset it as well. */ -+ *limit = 0; -+ -+ if (!skb) -+ return NULL; -+ -+ *subsk = ecf_get_available_subflow(meta_sk, skb, false); -+ if (!*subsk) -+ return NULL; -+ -+ subtp = tcp_sk(*subsk); -+ mss_now = tcp_current_mss(*subsk); -+ -+ if (!*reinject && unlikely(!tcp_snd_wnd_test(tcp_sk(meta_sk), skb, mss_now))) { -+ skb = mptcp_ecf_rcv_buf_optimization(*subsk, 1); -+ if (skb) -+ *reinject = -1; -+ else -+ return NULL; -+ } -+ -+ /* No splitting required, as we will only send one single segment */ -+ if (skb->len <= mss_now) -+ return skb; -+ -+ /* The following is similar to tcp_mss_split_point, but -+ * we do not care about nagle, because we will anyways -+ * use TCP_NAGLE_PUSH, which overrides this. -+ * -+ * So, we first limit according to the cwnd/gso-size and then according -+ * to the subflow's window. -+ */ -+ -+ gso_max_segs = (*subsk)->sk_gso_max_segs; -+ if (!gso_max_segs) /* No gso supported on the subflow's NIC */ -+ gso_max_segs = 1; -+ max_segs = min_t(unsigned int, tcp_cwnd_test(subtp, skb), gso_max_segs); -+ if (!max_segs) -+ return NULL; -+ -+ max_len = mss_now * max_segs; -+ window = tcp_wnd_end(subtp) - subtp->write_seq; -+ -+ needed = min(skb->len, window); -+ if (max_len <= skb->len) -+ /* Take max_win, which is actually the cwnd/gso-size */ -+ *limit = max_len; -+ else -+ /* Or, take the window */ -+ *limit = needed; -+ -+ return skb; -+} -+ -+static void ecfsched_init(struct sock *sk) -+{ -+ struct ecfsched_priv *ecf_p = ecfsched_get_priv(tcp_sk(sk)); -+ struct ecfsched_cb *ecf_cb = ecfsched_get_cb(tcp_sk(mptcp_meta_sk(sk))); -+ -+ ecf_p->last_rbuf_opti = tcp_jiffies32; -+ ecf_cb->switching_margin = 0; -+} -+ -+struct mptcp_sched_ops mptcp_sched_ecf = { -+ .get_subflow = ecf_get_available_subflow, -+ .next_segment = mptcp_ecf_next_segment, -+ .init = ecfsched_init, -+ .name = "ecf", -+ .owner = THIS_MODULE, -+}; -+ -+static int __init ecf_register(void) -+{ -+ BUILD_BUG_ON(sizeof(struct ecfsched_priv) > MPTCP_SCHED_SIZE); -+ BUILD_BUG_ON(sizeof(struct ecfsched_cb) > MPTCP_SCHED_DATA_SIZE); -+ -+ if (mptcp_register_scheduler(&mptcp_sched_ecf)) -+ return -1; -+ -+ return 0; -+} -+ -+static void ecf_unregister(void) -+{ -+ mptcp_unregister_scheduler(&mptcp_sched_ecf); -+} -+ -+module_init(ecf_register); -+module_exit(ecf_unregister); -+ -+MODULE_AUTHOR("Yeon-sup Lim, Daniel Weber"); -+MODULE_LICENSE("GPL"); -+MODULE_DESCRIPTION("ECF (Earliest Completion First) scheduler for MPTCP, based on default minimum RTT scheduler"); -+MODULE_VERSION("0.95"); diff --git a/root/target/linux/generic/hack-4.19/692-tcp_nanqinlang.patch b/root/target/linux/generic/hack-4.19/692-tcp_nanqinlang.patch deleted file mode 100644 index 56051ae7..00000000 --- a/root/target/linux/generic/hack-4.19/692-tcp_nanqinlang.patch +++ /dev/null @@ -1,1037 +0,0 @@ ---- a/net/ipv4/Makefile.anc 2019-11-23 23:01:47.069966970 +0100 -+++ b/net/ipv4/Makefile 2019-11-23 23:03:01.416428035 +0100 -@@ -48,6 +48,7 @@ - obj-$(CONFIG_INET_UDP_DIAG) += udp_diag.o - obj-$(CONFIG_INET_RAW_DIAG) += raw_diag.o - obj-$(CONFIG_TCP_CONG_BBR) += tcp_bbr.o -+obj-$(CONFIG_TCP_CONG_NANQINLANG) += tcp_nanqinlang.o - obj-$(CONFIG_TCP_CONG_BIC) += tcp_bic.o - obj-$(CONFIG_TCP_CONG_CDG) += tcp_cdg.o - obj-$(CONFIG_TCP_CONG_CUBIC) += tcp_cubic.o ---- a/net/ipv4/Kconfig.anc 2019-11-23 23:01:52.649851417 +0100 -+++ b/net/ipv4/Kconfig 2019-11-23 23:04:21.974762180 +0100 -@@ -681,6 +681,21 @@ - bufferbloat, policers, or AQM schemes that do not provide a delay - signal. It requires the fq ("Fair Queue") pacing packet scheduler. - -+config TCP_CONG_NANQINLANG -+ tristate "NANGINLANG TCP" -+ default n -+ ---help--- -+ -+ BBR (Bottleneck Bandwidth and RTT) TCP congestion control aims to -+ maximize network utilization and minimize queues. It builds an explicit -+ model of the the bottleneck delivery rate and path round-trip -+ propagation delay. It tolerates packet loss and delay unrelated to -+ congestion. It can operate over LAN, WAN, cellular, wifi, or cable -+ modem links. It can coexist with flows that use loss-based congestion -+ control, and can operate with shallow buffers, deep buffers, -+ bufferbloat, policers, or AQM schemes that do not provide a delay -+ signal. It requires the fq ("Fair Queue") pacing packet scheduler. -+ - config TCP_CONG_LIA - tristate "MPTCP Linked Increase" - depends on MPTCP -@@ -763,6 +778,9 @@ - config DEFAULT_BBR - bool "BBR" if TCP_CONG_BBR=y - -+ config DEFAULT_NANQINLANG -+ bool "BBR" if TCP_CONG_NANQINLANG=y -+ - config DEFAULT_LIA - bool "Lia" if TCP_CONG_LIA=y - -@@ -806,6 +824,7 @@ - default "dctcp" if DEFAULT_DCTCP - default "cdg" if DEFAULT_CDG - default "bbr" if DEFAULT_BBR -+ default "nanqinlang" if DEFAULT_NANQINLANG - default "cubic" - - config TCP_MD5SIG ---- /dev/null 2019-11-25 21:13:36.728349757 +0100 -+++ b/net/ipv4/tcp_nanqinlang.c 2019-11-25 21:10:00.392068414 +0100 -@@ -0,0 +1,982 @@ -+/* Bottleneck Bandwidth and RTT (BBR) congestion control -+ * -+ * BBR congestion control computes the sending rate based on the delivery -+ * rate (throughput) estimated from ACKs. In a nutshell: -+ * -+ * On each ACK, update our model of the network path: -+ * bottleneck_bandwidth = windowed_max(delivered / elapsed, 10 round trips) -+ * min_rtt = windowed_min(rtt, 10 seconds) -+ * pacing_rate = pacing_gain * bottleneck_bandwidth -+ * cwnd = max(cwnd_gain * bottleneck_bandwidth * min_rtt, 4) -+ * -+ * The core algorithm does not react directly to packet losses or delays, -+ * although BBR may adjust the size of next send per ACK when loss is -+ * observed, or adjust the sending rate if it estimates there is a -+ * traffic policer, in order to keep the drop rate reasonable. -+ * -+ * Here is a state transition diagram for BBR: -+ * -+ * | -+ * V -+ * +---> STARTUP ----+ -+ * | | | -+ * | V | -+ * | DRAIN ----+ -+ * | | | -+ * | V | -+ * +---> PROBE_BW ----+ -+ * | ^ | | -+ * | | | | -+ * | +----+ | -+ * | | -+ * +---- PROBE_RTT <--+ -+ * -+ * A BBR flow starts in STARTUP, and ramps up its sending rate quickly. -+ * When it estimates the pipe is full, it enters DRAIN to drain the queue. -+ * In steady state a BBR flow only uses PROBE_BW and PROBE_RTT. -+ * A long-lived BBR flow spends the vast majority of its time remaining -+ * (repeatedly) in PROBE_BW, fully probing and utilizing the pipe's bandwidth -+ * in a fair manner, with a small, bounded queue. *If* a flow has been -+ * continuously sending for the entire min_rtt window, and hasn't seen an RTT -+ * sample that matches or decreases its min_rtt estimate for 10 seconds, then -+ * it briefly enters PROBE_RTT to cut inflight to a minimum value to re-probe -+ * the path's two-way propagation delay (min_rtt). When exiting PROBE_RTT, if -+ * we estimated that we reached the full bw of the pipe then we enter PROBE_BW; -+ * otherwise we enter STARTUP to try to fill the pipe. -+ * -+ * BBR is described in detail in: -+ * "BBR: Congestion-Based Congestion Control", -+ * Neal Cardwell, Yuchung Cheng, C. Stephen Gunn, Soheil Hassas Yeganeh, -+ * Van Jacobson. ACM Queue, Vol. 14 No. 5, September-October 2016. -+ * -+ * There is a public e-mail list for discussing BBR development and testing: -+ * https://groups.google.com/forum/#!forum/bbr-dev -+ * -+ * NOTE: BBR might be used with the fq qdisc ("man tc-fq") with pacing enabled, -+ * otherwise TCP stack falls back to an internal pacing using one high -+ * resolution timer per TCP socket and may use more resources. -+ */ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+/* Scale factor for rate in pkt/uSec unit to avoid truncation in bandwidth -+ * estimation. The rate unit ~= (1500 bytes / 1 usec / 2^24) ~= 715 bps. -+ * This handles bandwidths from 0.06pps (715bps) to 256Mpps (3Tbps) in a u32. -+ * Since the minimum window is >=4 packets, the lower bound isn't -+ * an issue. The upper bound isn't an issue with existing technologies. -+ */ -+#define BW_SCALE 24 -+#define BW_UNIT (1 << BW_SCALE) -+ -+#define BBR_SCALE 8 /* scaling factor for fractions in BBR (e.g. gains) */ -+#define BBR_UNIT (1 << BBR_SCALE) -+ -+/* BBR has the following modes for deciding how fast to send: */ -+enum bbr_mode { -+ BBR_STARTUP, /* ramp up sending rate rapidly to fill pipe */ -+ BBR_DRAIN, /* drain any queue created during startup */ -+ BBR_PROBE_BW, /* discover, share bw: pace around estimated bw */ -+ BBR_PROBE_RTT, /* cut inflight to min to probe min_rtt */ -+}; -+ -+/* BBR congestion control block */ -+struct bbr { -+ u32 min_rtt_us; /* min RTT in min_rtt_win_sec window */ -+ u32 min_rtt_stamp; /* timestamp of min_rtt_us */ -+ u32 probe_rtt_done_stamp; /* end time for BBR_PROBE_RTT mode */ -+ struct minmax bw; /* Max recent delivery rate in pkts/uS << 24 */ -+ u32 rtt_cnt; /* count of packet-timed rounds elapsed */ -+ u32 next_rtt_delivered; /* scb->tx.delivered at end of round */ -+ u64 cycle_mstamp; /* time of this cycle phase start */ -+ u32 mode:3, /* current bbr_mode in state machine */ -+ prev_ca_state:3, /* CA state on previous ACK */ -+ packet_conservation:1, /* use packet conservation? */ -+ round_start:1, /* start of packet-timed tx->ack round? */ -+ idle_restart:1, /* restarting after idle? */ -+ probe_rtt_round_done:1, /* a BBR_PROBE_RTT round at 4 pkts? */ -+ unused:13, -+ lt_is_sampling:1, /* taking long-term ("LT") samples now? */ -+ lt_rtt_cnt:7, /* round trips in long-term interval */ -+ lt_use_bw:1; /* use lt_bw as our bw estimate? */ -+ u32 lt_bw; /* LT est delivery rate in pkts/uS << 24 */ -+ u32 lt_last_delivered; /* LT intvl start: tp->delivered */ -+ u32 lt_last_stamp; /* LT intvl start: tp->delivered_mstamp */ -+ u32 lt_last_lost; /* LT intvl start: tp->lost */ -+ u32 pacing_gain:10, /* current gain for setting pacing rate */ -+ cwnd_gain:10, /* current gain for setting cwnd */ -+ full_bw_reached:1, /* reached full bw in Startup? */ -+ full_bw_cnt:2, /* number of rounds without large bw gains */ -+ cycle_idx:3, /* current index in pacing_gain cycle array */ -+ has_seen_rtt:1, /* have we seen an RTT sample yet? */ -+ unused_b:5; -+ u32 prior_cwnd; /* prior cwnd upon entering loss recovery */ -+ u32 full_bw; /* recent bw, to estimate if pipe is full */ -+}; -+ -+#define CYCLE_LEN 8 /* number of phases in a pacing gain cycle */ -+ -+/* Window length of bw filter (in rounds): */ -+static const int bbr_bw_rtts = CYCLE_LEN + 2; -+/* Window length of min_rtt filter (in sec): */ -+static const u32 bbr_min_rtt_win_sec = 10; -+/* Minimum time (in ms) spent at bbr_cwnd_min_target in BBR_PROBE_RTT mode: */ -+static const u32 bbr_probe_rtt_mode_ms = 100; -+/* Skip TSO below the following bandwidth (bits/sec): */ -+static const int bbr_min_tso_rate = 1200000; -+ -+/* We use a high_gain value of 2/ln(2) because it's the smallest pacing gain -+ * that will allow a smoothly increasing pacing rate that will double each RTT -+ * and send the same number of packets per RTT that an un-paced, slow-starting -+ * Reno or CUBIC flow would: -+ */ -+static const int bbr_high_gain = BBR_UNIT * 3000 / 1000 + 1; -+/* The pacing gain of 1/high_gain in BBR_DRAIN is calculated to typically drain -+ * the queue created in BBR_STARTUP in a single round: -+ */ -+static const int bbr_drain_gain = BBR_UNIT * 1000 / 3000; -+/* The gain for deriving steady-state cwnd tolerates delayed/stretched ACKs: */ -+static const int bbr_cwnd_gain = BBR_UNIT * 2; -+/* The pacing_gain values for the PROBE_BW gain cycle, to discover/share bw: */ -+static const int bbr_pacing_gain[] = { -+ BBR_UNIT * 6 / 4, /* probe for more available bw */ -+ BBR_UNIT * 3 / 4, /* drain queue and/or yield bw to other flows */ -+ BBR_UNIT * 5 / 4, BBR_UNIT * 5 / 4, BBR_UNIT * 5 / 4, /* cruise at 1.0*bw to utilize pipe, */ -+ BBR_UNIT * 6 / 4, BBR_UNIT * 6 / 4, BBR_UNIT * 6 / 4 /* without creating excess queue... */ -+}; -+/* Randomize the starting gain cycling phase over N phases: */ -+static const u32 bbr_cycle_rand = 7; -+ -+/* Try to keep at least this many packets in flight, if things go smoothly. For -+ * smooth functioning, a sliding window protocol ACKing every other packet -+ * needs at least 4 packets in flight: -+ */ -+static const u32 bbr_cwnd_min_target = 4; -+ -+/* To estimate if BBR_STARTUP mode (i.e. high_gain) has filled pipe... */ -+/* If bw has increased significantly (1.25x), there may be more bw available: */ -+static const u32 bbr_full_bw_thresh = BBR_UNIT * 5 / 4; -+/* But after 3 rounds w/o significant bw growth, estimate pipe is full: */ -+static const u32 bbr_full_bw_cnt = 3; -+ -+/* "long-term" ("LT") bandwidth estimator parameters... */ -+/* The minimum number of rounds in an LT bw sampling interval: */ -+static const u32 bbr_lt_intvl_min_rtts = 4; -+/* If lost/delivered ratio > 20%, interval is "lossy" and we may be policed: */ -+static const u32 bbr_lt_loss_thresh = 50; -+/* If 2 intervals have a bw ratio <= 1/8, their bw is "consistent": */ -+static const u32 bbr_lt_bw_ratio = BBR_UNIT / 4; -+/* If 2 intervals have a bw diff <= 4 Kbit/sec their bw is "consistent": */ -+static const u32 bbr_lt_bw_diff = 4000 / 8; -+/* If we estimate we're policed, use lt_bw for this many round trips: */ -+static const u32 bbr_lt_bw_max_rtts = 48; -+ -+static void bbr_check_probe_rtt_done(struct sock *sk); -+ -+/* Do we estimate that STARTUP filled the pipe? */ -+static bool bbr_full_bw_reached(const struct sock *sk) -+{ -+ const struct bbr *bbr = inet_csk_ca(sk); -+ -+ return bbr->full_bw_reached; -+} -+ -+/* Return the windowed max recent bandwidth sample, in pkts/uS << BW_SCALE. */ -+static u32 bbr_max_bw(const struct sock *sk) -+{ -+ struct bbr *bbr = inet_csk_ca(sk); -+ -+ return minmax_get(&bbr->bw); -+} -+ -+/* Return the estimated bandwidth of the path, in pkts/uS << BW_SCALE. */ -+static u32 bbr_bw(const struct sock *sk) -+{ -+ struct bbr *bbr = inet_csk_ca(sk); -+ -+ return bbr->lt_use_bw ? bbr->lt_bw : bbr_max_bw(sk); -+} -+ -+/* Return rate in bytes per second, optionally with a gain. -+ * The order here is chosen carefully to avoid overflow of u64. This should -+ * work for input rates of up to 2.9Tbit/sec and gain of 2.89x. -+ */ -+static u64 bbr_rate_bytes_per_sec(struct sock *sk, u64 rate, int gain) -+{ -+ unsigned int mss = tcp_sk(sk)->mss_cache; -+ -+ if (!tcp_needs_internal_pacing(sk)) -+ mss = tcp_mss_to_mtu(sk, mss); -+ rate *= mss; -+ rate *= gain; -+ rate >>= BBR_SCALE; -+ rate *= USEC_PER_SEC; -+ return rate >> BW_SCALE; -+} -+ -+/* Convert a BBR bw and gain factor to a pacing rate in bytes per second. */ -+static u32 bbr_bw_to_pacing_rate(struct sock *sk, u32 bw, int gain) -+{ -+ u64 rate = bw; -+ -+ rate = bbr_rate_bytes_per_sec(sk, rate, gain); -+ rate = min_t(u64, rate, sk->sk_max_pacing_rate); -+ return rate; -+} -+ -+/* Initialize pacing rate to: high_gain * init_cwnd / RTT. */ -+static void bbr_init_pacing_rate_from_rtt(struct sock *sk) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct bbr *bbr = inet_csk_ca(sk); -+ u64 bw; -+ u32 rtt_us; -+ -+ if (tp->srtt_us) { /* any RTT sample yet? */ -+ rtt_us = max(tp->srtt_us >> 3, 1U); -+ bbr->has_seen_rtt = 1; -+ } else { /* no RTT sample yet */ -+ rtt_us = USEC_PER_MSEC; /* use nominal default RTT */ -+ } -+ bw = (u64)tp->snd_cwnd * BW_UNIT; -+ do_div(bw, rtt_us); -+ sk->sk_pacing_rate = bbr_bw_to_pacing_rate(sk, bw, bbr_high_gain); -+} -+ -+/* Pace using current bw estimate and a gain factor. In order to help drive the -+ * network toward lower queues while maintaining high utilization and low -+ * latency, the average pacing rate aims to be slightly (~1%) lower than the -+ * estimated bandwidth. This is an important aspect of the design. In this -+ * implementation this slightly lower pacing rate is achieved implicitly by not -+ * including link-layer headers in the packet size used for the pacing rate. -+ */ -+static void bbr_set_pacing_rate(struct sock *sk, u32 bw, int gain) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct bbr *bbr = inet_csk_ca(sk); -+ u32 rate = bbr_bw_to_pacing_rate(sk, bw, gain); -+ -+ if (unlikely(!bbr->has_seen_rtt && tp->srtt_us)) -+ bbr_init_pacing_rate_from_rtt(sk); -+ if (bbr_full_bw_reached(sk) || rate > sk->sk_pacing_rate) -+ sk->sk_pacing_rate = rate; -+} -+ -+/* override sysctl_tcp_min_tso_segs */ -+static u32 bbr_min_tso_segs(struct sock *sk) -+{ -+ return sk->sk_pacing_rate < (bbr_min_tso_rate >> 3) ? 1 : 2; -+} -+ -+static u32 bbr_tso_segs_goal(struct sock *sk) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ u32 segs, bytes; -+ -+ /* Sort of tcp_tso_autosize() but ignoring -+ * driver provided sk_gso_max_size. -+ */ -+ bytes = min_t(u32, sk->sk_pacing_rate >> sk->sk_pacing_shift, -+ GSO_MAX_SIZE - 1 - MAX_TCP_HEADER); -+ segs = max_t(u32, bytes / tp->mss_cache, bbr_min_tso_segs(sk)); -+ -+ return min(segs, 0x7FU); -+} -+ -+/* Save "last known good" cwnd so we can restore it after losses or PROBE_RTT */ -+static void bbr_save_cwnd(struct sock *sk) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct bbr *bbr = inet_csk_ca(sk); -+ -+ if (bbr->prev_ca_state < TCP_CA_Recovery && bbr->mode != BBR_PROBE_RTT) -+ bbr->prior_cwnd = tp->snd_cwnd; /* this cwnd is good enough */ -+ else /* loss recovery or BBR_PROBE_RTT have temporarily cut cwnd */ -+ bbr->prior_cwnd = max(bbr->prior_cwnd, tp->snd_cwnd); -+} -+ -+static void bbr_cwnd_event(struct sock *sk, enum tcp_ca_event event) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct bbr *bbr = inet_csk_ca(sk); -+ -+ if (event == CA_EVENT_TX_START && tp->app_limited) { -+ bbr->idle_restart = 1; -+ /* Avoid pointless buffer overflows: pace at est. bw if we don't -+ * need more speed (we're restarting from idle and app-limited). -+ */ -+ if (bbr->mode == BBR_PROBE_BW) -+ bbr_set_pacing_rate(sk, bbr_bw(sk), BBR_UNIT); -+ else if (bbr->mode == BBR_PROBE_RTT) -+ bbr_check_probe_rtt_done(sk); -+ } -+} -+ -+/* Find target cwnd. Right-size the cwnd based on min RTT and the -+ * estimated bottleneck bandwidth: -+ * -+ * cwnd = bw * min_rtt * gain = BDP * gain -+ * -+ * The key factor, gain, controls the amount of queue. While a small gain -+ * builds a smaller queue, it becomes more vulnerable to noise in RTT -+ * measurements (e.g., delayed ACKs or other ACK compression effects). This -+ * noise may cause BBR to under-estimate the rate. -+ * -+ * To achieve full performance in high-speed paths, we budget enough cwnd to -+ * fit full-sized skbs in-flight on both end hosts to fully utilize the path: -+ * - one skb in sending host Qdisc, -+ * - one skb in sending host TSO/GSO engine -+ * - one skb being received by receiver host LRO/GRO/delayed-ACK engine -+ * Don't worry, at low rates (bbr_min_tso_rate) this won't bloat cwnd because -+ * in such cases tso_segs_goal is 1. The minimum cwnd is 4 packets, -+ * which allows 2 outstanding 2-packet sequences, to try to keep pipe -+ * full even with ACK-every-other-packet delayed ACKs. -+ */ -+static u32 bbr_target_cwnd(struct sock *sk, u32 bw, int gain) -+{ -+ struct bbr *bbr = inet_csk_ca(sk); -+ u32 cwnd; -+ u64 w; -+ -+ /* If we've never had a valid RTT sample, cap cwnd at the initial -+ * default. This should only happen when the connection is not using TCP -+ * timestamps and has retransmitted all of the SYN/SYNACK/data packets -+ * ACKed so far. In this case, an RTO can cut cwnd to 1, in which -+ * case we need to slow-start up toward something safe: TCP_INIT_CWND. -+ */ -+ if (unlikely(bbr->min_rtt_us == ~0U)) /* no valid RTT samples yet? */ -+ return TCP_INIT_CWND; /* be safe: cap at default initial cwnd*/ -+ -+ w = (u64)bw * bbr->min_rtt_us; -+ -+ /* Apply a gain to the given value, then remove the BW_SCALE shift. */ -+ cwnd = (((w * gain) >> BBR_SCALE) + BW_UNIT - 1) / BW_UNIT; -+ -+ /* Allow enough full-sized skbs in flight to utilize end systems. */ -+ cwnd += 3 * bbr_tso_segs_goal(sk); -+ -+ /* Reduce delayed ACKs by rounding up cwnd to the next even number. */ -+ cwnd = (cwnd + 1) & ~1U; -+ -+ /* Ensure gain cycling gets inflight above BDP even for small BDPs. */ -+ if (bbr->mode == BBR_PROBE_BW && gain > BBR_UNIT) -+ cwnd += 2; -+ -+ return cwnd; -+} -+ -+/* An optimization in BBR to reduce losses: On the first round of recovery, we -+ * follow the packet conservation principle: send P packets per P packets acked. -+ * After that, we slow-start and send at most 2*P packets per P packets acked. -+ * After recovery finishes, or upon undo, we restore the cwnd we had when -+ * recovery started (capped by the target cwnd based on estimated BDP). -+ * -+ * TODO(ycheng/ncardwell): implement a rate-based approach. -+ */ -+static bool bbr_set_cwnd_to_recover_or_restore( -+ struct sock *sk, const struct rate_sample *rs, u32 acked, u32 *new_cwnd) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct bbr *bbr = inet_csk_ca(sk); -+ u8 prev_state = bbr->prev_ca_state, state = inet_csk(sk)->icsk_ca_state; -+ u32 cwnd = tp->snd_cwnd; -+ -+ /* An ACK for P pkts should release at most 2*P packets. We do this -+ * in two steps. First, here we deduct the number of lost packets. -+ * Then, in bbr_set_cwnd() we slow start up toward the target cwnd. -+ */ -+ if (rs->losses > 0) -+ cwnd = max_t(s32, cwnd - rs->losses, 1); -+ -+ if (state == TCP_CA_Recovery && prev_state != TCP_CA_Recovery) { -+ /* Starting 1st round of Recovery, so do packet conservation. */ -+ bbr->packet_conservation = 1; -+ bbr->next_rtt_delivered = tp->delivered; /* start round now */ -+ /* Cut unused cwnd from app behavior, TSQ, or TSO deferral: */ -+ cwnd = tcp_packets_in_flight(tp) + acked; -+ } else if (prev_state >= TCP_CA_Recovery && state < TCP_CA_Recovery) { -+ /* Exiting loss recovery; restore cwnd saved before recovery. */ -+ cwnd = max(cwnd, bbr->prior_cwnd); -+ bbr->packet_conservation = 0; -+ } -+ bbr->prev_ca_state = state; -+ -+ if (bbr->packet_conservation) { -+ *new_cwnd = max(cwnd, tcp_packets_in_flight(tp) + acked); -+ return true; /* yes, using packet conservation */ -+ } -+ *new_cwnd = cwnd; -+ return false; -+} -+ -+/* Slow-start up toward target cwnd (if bw estimate is growing, or packet loss -+ * has drawn us down below target), or snap down to target if we're above it. -+ */ -+static void bbr_set_cwnd(struct sock *sk, const struct rate_sample *rs, -+ u32 acked, u32 bw, int gain) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct bbr *bbr = inet_csk_ca(sk); -+ u32 cwnd = tp->snd_cwnd, target_cwnd = 0; -+ -+ if (!acked) -+ goto done; /* no packet fully ACKed; just apply caps */ -+ -+ if (bbr_set_cwnd_to_recover_or_restore(sk, rs, acked, &cwnd)) -+ goto done; -+ -+ /* If we're below target cwnd, slow start cwnd toward target cwnd. */ -+ target_cwnd = bbr_target_cwnd(sk, bw, gain); -+ if (bbr_full_bw_reached(sk)) /* only cut cwnd if we filled the pipe */ -+ cwnd = min(cwnd + acked, target_cwnd); -+ else if (cwnd < target_cwnd || tp->delivered < TCP_INIT_CWND) -+ cwnd = cwnd + acked; -+ cwnd = max(cwnd, bbr_cwnd_min_target); -+ -+done: -+ tp->snd_cwnd = min(cwnd, tp->snd_cwnd_clamp); /* apply global cap */ -+ if (bbr->mode == BBR_PROBE_RTT) /* drain queue, refresh min_rtt */ -+ tp->snd_cwnd = min(tp->snd_cwnd, bbr_cwnd_min_target); -+} -+ -+/* End cycle phase if it's time and/or we hit the phase's in-flight target. */ -+static bool bbr_is_next_cycle_phase(struct sock *sk, -+ const struct rate_sample *rs) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct bbr *bbr = inet_csk_ca(sk); -+ bool is_full_length = -+ tcp_stamp_us_delta(tp->delivered_mstamp, bbr->cycle_mstamp) > -+ bbr->min_rtt_us; -+ u32 inflight, bw; -+ -+ /* The pacing_gain of 1.0 paces at the estimated bw to try to fully -+ * use the pipe without increasing the queue. -+ */ -+ if (bbr->pacing_gain == BBR_UNIT) -+ return is_full_length; /* just use wall clock time */ -+ -+ inflight = rs->prior_in_flight; /* what was in-flight before ACK? */ -+ bw = bbr_max_bw(sk); -+ -+ /* A pacing_gain > 1.0 probes for bw by trying to raise inflight to at -+ * least pacing_gain*BDP; this may take more than min_rtt if min_rtt is -+ * small (e.g. on a LAN). We do not persist if packets are lost, since -+ * a path with small buffers may not hold that much. -+ */ -+ if (bbr->pacing_gain > BBR_UNIT) -+ return is_full_length && -+ (rs->losses || /* perhaps pacing_gain*BDP won't fit */ -+ inflight >= bbr_target_cwnd(sk, bw, bbr->pacing_gain)); -+ -+ /* A pacing_gain < 1.0 tries to drain extra queue we added if bw -+ * probing didn't find more bw. If inflight falls to match BDP then we -+ * estimate queue is drained; persisting would underutilize the pipe. -+ */ -+ return is_full_length || -+ inflight <= bbr_target_cwnd(sk, bw, BBR_UNIT); -+} -+ -+static void bbr_advance_cycle_phase(struct sock *sk) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct bbr *bbr = inet_csk_ca(sk); -+ -+ bbr->cycle_idx = (bbr->cycle_idx + 1) & (CYCLE_LEN - 1); -+ bbr->cycle_mstamp = tp->delivered_mstamp; -+ bbr->pacing_gain = bbr->lt_use_bw ? BBR_UNIT : -+ bbr_pacing_gain[bbr->cycle_idx]; -+} -+ -+/* Gain cycling: cycle pacing gain to converge to fair share of available bw. */ -+static void bbr_update_cycle_phase(struct sock *sk, -+ const struct rate_sample *rs) -+{ -+ struct bbr *bbr = inet_csk_ca(sk); -+ -+ if (bbr->mode == BBR_PROBE_BW && bbr_is_next_cycle_phase(sk, rs)) -+ bbr_advance_cycle_phase(sk); -+} -+ -+static void bbr_reset_startup_mode(struct sock *sk) -+{ -+ struct bbr *bbr = inet_csk_ca(sk); -+ -+ bbr->mode = BBR_STARTUP; -+ bbr->pacing_gain = bbr_high_gain; -+ bbr->cwnd_gain = bbr_high_gain; -+} -+ -+static void bbr_reset_probe_bw_mode(struct sock *sk) -+{ -+ struct bbr *bbr = inet_csk_ca(sk); -+ -+ bbr->mode = BBR_PROBE_BW; -+ bbr->pacing_gain = BBR_UNIT; -+ bbr->cwnd_gain = bbr_cwnd_gain; -+ bbr->cycle_idx = CYCLE_LEN - 1 - prandom_u32_max(bbr_cycle_rand); -+ bbr_advance_cycle_phase(sk); /* flip to next phase of gain cycle */ -+} -+ -+static void bbr_reset_mode(struct sock *sk) -+{ -+ if (!bbr_full_bw_reached(sk)) -+ bbr_reset_startup_mode(sk); -+ else -+ bbr_reset_probe_bw_mode(sk); -+} -+ -+/* Start a new long-term sampling interval. */ -+static void bbr_reset_lt_bw_sampling_interval(struct sock *sk) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct bbr *bbr = inet_csk_ca(sk); -+ -+ bbr->lt_last_stamp = div_u64(tp->delivered_mstamp, USEC_PER_MSEC); -+ bbr->lt_last_delivered = tp->delivered; -+ bbr->lt_last_lost = tp->lost; -+ bbr->lt_rtt_cnt = 0; -+} -+ -+/* Completely reset long-term bandwidth sampling. */ -+static void bbr_reset_lt_bw_sampling(struct sock *sk) -+{ -+ struct bbr *bbr = inet_csk_ca(sk); -+ -+ bbr->lt_bw = 0; -+ bbr->lt_use_bw = 0; -+ bbr->lt_is_sampling = false; -+ bbr_reset_lt_bw_sampling_interval(sk); -+} -+ -+/* Long-term bw sampling interval is done. Estimate whether we're policed. */ -+static void bbr_lt_bw_interval_done(struct sock *sk, u32 bw) -+{ -+ struct bbr *bbr = inet_csk_ca(sk); -+ u32 diff; -+ -+ if (bbr->lt_bw) { /* do we have bw from a previous interval? */ -+ /* Is new bw close to the lt_bw from the previous interval? */ -+ diff = abs(bw - bbr->lt_bw); -+ if ((diff * BBR_UNIT <= bbr_lt_bw_ratio * bbr->lt_bw) || -+ (bbr_rate_bytes_per_sec(sk, diff, BBR_UNIT) <= -+ bbr_lt_bw_diff)) { -+ /* All criteria are met; estimate we're policed. */ -+ bbr->lt_bw = (bw + bbr->lt_bw) >> 1; /* avg 2 intvls */ -+ bbr->lt_use_bw = 1; -+ bbr->pacing_gain = BBR_UNIT; /* try to avoid drops */ -+ bbr->lt_rtt_cnt = 0; -+ return; -+ } -+ } -+ bbr->lt_bw = bw; -+ bbr_reset_lt_bw_sampling_interval(sk); -+} -+ -+/* Token-bucket traffic policers are common (see "An Internet-Wide Analysis of -+ * Traffic Policing", SIGCOMM 2016). BBR detects token-bucket policers and -+ * explicitly models their policed rate, to reduce unnecessary losses. We -+ * estimate that we're policed if we see 2 consecutive sampling intervals with -+ * consistent throughput and high packet loss. If we think we're being policed, -+ * set lt_bw to the "long-term" average delivery rate from those 2 intervals. -+ */ -+static void bbr_lt_bw_sampling(struct sock *sk, const struct rate_sample *rs) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct bbr *bbr = inet_csk_ca(sk); -+ u32 lost, delivered; -+ u64 bw; -+ u32 t; -+ -+ if (bbr->lt_use_bw) { /* already using long-term rate, lt_bw? */ -+ if (bbr->mode == BBR_PROBE_BW && bbr->round_start && -+ ++bbr->lt_rtt_cnt >= bbr_lt_bw_max_rtts) { -+ bbr_reset_lt_bw_sampling(sk); /* stop using lt_bw */ -+ bbr_reset_probe_bw_mode(sk); /* restart gain cycling */ -+ } -+ return; -+ } -+ -+ /* Wait for the first loss before sampling, to let the policer exhaust -+ * its tokens and estimate the steady-state rate allowed by the policer. -+ * Starting samples earlier includes bursts that over-estimate the bw. -+ */ -+ if (!bbr->lt_is_sampling) { -+ if (!rs->losses) -+ return; -+ bbr_reset_lt_bw_sampling_interval(sk); -+ bbr->lt_is_sampling = true; -+ } -+ -+ /* To avoid underestimates, reset sampling if we run out of data. */ -+ if (rs->is_app_limited) { -+ bbr_reset_lt_bw_sampling(sk); -+ return; -+ } -+ -+ if (bbr->round_start) -+ bbr->lt_rtt_cnt++; /* count round trips in this interval */ -+ if (bbr->lt_rtt_cnt < bbr_lt_intvl_min_rtts) -+ return; /* sampling interval needs to be longer */ -+ if (bbr->lt_rtt_cnt > 4 * bbr_lt_intvl_min_rtts) { -+ bbr_reset_lt_bw_sampling(sk); /* interval is too long */ -+ return; -+ } -+ -+ /* End sampling interval when a packet is lost, so we estimate the -+ * policer tokens were exhausted. Stopping the sampling before the -+ * tokens are exhausted under-estimates the policed rate. -+ */ -+ if (!rs->losses) -+ return; -+ -+ /* Calculate packets lost and delivered in sampling interval. */ -+ lost = tp->lost - bbr->lt_last_lost; -+ delivered = tp->delivered - bbr->lt_last_delivered; -+ /* Is loss rate (lost/delivered) >= lt_loss_thresh? If not, wait. */ -+ if (!delivered || (lost << BBR_SCALE) < bbr_lt_loss_thresh * delivered) -+ return; -+ -+ /* Find average delivery rate in this sampling interval. */ -+ t = div_u64(tp->delivered_mstamp, USEC_PER_MSEC) - bbr->lt_last_stamp; -+ if ((s32)t < 1) -+ return; /* interval is less than one ms, so wait */ -+ /* Check if can multiply without overflow */ -+ if (t >= ~0U / USEC_PER_MSEC) { -+ bbr_reset_lt_bw_sampling(sk); /* interval too long; reset */ -+ return; -+ } -+ t *= USEC_PER_MSEC; -+ bw = (u64)delivered * BW_UNIT; -+ do_div(bw, t); -+ bbr_lt_bw_interval_done(sk, bw); -+} -+ -+/* Estimate the bandwidth based on how fast packets are delivered */ -+static void bbr_update_bw(struct sock *sk, const struct rate_sample *rs) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct bbr *bbr = inet_csk_ca(sk); -+ u64 bw; -+ -+ bbr->round_start = 0; -+ if (rs->delivered < 0 || rs->interval_us <= 0) -+ return; /* Not a valid observation */ -+ -+ /* See if we've reached the next RTT */ -+ if (!before(rs->prior_delivered, bbr->next_rtt_delivered)) { -+ bbr->next_rtt_delivered = tp->delivered; -+ bbr->rtt_cnt++; -+ bbr->round_start = 1; -+ bbr->packet_conservation = 0; -+ } -+ -+ bbr_lt_bw_sampling(sk, rs); -+ -+ /* Divide delivered by the interval to find a (lower bound) bottleneck -+ * bandwidth sample. Delivered is in packets and interval_us in uS and -+ * ratio will be <<1 for most connections. So delivered is first scaled. -+ */ -+ bw = (u64)rs->delivered * BW_UNIT; -+ do_div(bw, rs->interval_us); -+ -+ /* If this sample is application-limited, it is likely to have a very -+ * low delivered count that represents application behavior rather than -+ * the available network rate. Such a sample could drag down estimated -+ * bw, causing needless slow-down. Thus, to continue to send at the -+ * last measured network rate, we filter out app-limited samples unless -+ * they describe the path bw at least as well as our bw model. -+ * -+ * So the goal during app-limited phase is to proceed with the best -+ * network rate no matter how long. We automatically leave this -+ * phase when app writes faster than the network can deliver :) -+ */ -+ if (!rs->is_app_limited || bw >= bbr_max_bw(sk)) { -+ /* Incorporate new sample into our max bw filter. */ -+ minmax_running_max(&bbr->bw, bbr_bw_rtts, bbr->rtt_cnt, bw); -+ } -+} -+ -+/* Estimate when the pipe is full, using the change in delivery rate: BBR -+ * estimates that STARTUP filled the pipe if the estimated bw hasn't changed by -+ * at least bbr_full_bw_thresh (25%) after bbr_full_bw_cnt (3) non-app-limited -+ * rounds. Why 3 rounds: 1: rwin autotuning grows the rwin, 2: we fill the -+ * higher rwin, 3: we get higher delivery rate samples. Or transient -+ * cross-traffic or radio noise can go away. CUBIC Hystart shares a similar -+ * design goal, but uses delay and inter-ACK spacing instead of bandwidth. -+ */ -+static void bbr_check_full_bw_reached(struct sock *sk, -+ const struct rate_sample *rs) -+{ -+ struct bbr *bbr = inet_csk_ca(sk); -+ u32 bw_thresh; -+ -+ if (bbr_full_bw_reached(sk) || !bbr->round_start || rs->is_app_limited) -+ return; -+ -+ bw_thresh = (u64)bbr->full_bw * bbr_full_bw_thresh >> BBR_SCALE; -+ if (bbr_max_bw(sk) >= bw_thresh) { -+ bbr->full_bw = bbr_max_bw(sk); -+ bbr->full_bw_cnt = 0; -+ return; -+ } -+ ++bbr->full_bw_cnt; -+ bbr->full_bw_reached = bbr->full_bw_cnt >= bbr_full_bw_cnt; -+} -+ -+/* If pipe is probably full, drain the queue and then enter steady-state. */ -+static void bbr_check_drain(struct sock *sk, const struct rate_sample *rs) -+{ -+ struct bbr *bbr = inet_csk_ca(sk); -+ -+ if (bbr->mode == BBR_STARTUP && bbr_full_bw_reached(sk)) { -+ bbr->mode = BBR_DRAIN; /* drain queue we created */ -+ bbr->pacing_gain = bbr_drain_gain; /* pace slow to drain */ -+ bbr->cwnd_gain = bbr_high_gain; /* maintain cwnd */ -+ tcp_sk(sk)->snd_ssthresh = -+ bbr_target_cwnd(sk, bbr_max_bw(sk), BBR_UNIT); -+ } /* fall through to check if in-flight is already small: */ -+ if (bbr->mode == BBR_DRAIN && -+ tcp_packets_in_flight(tcp_sk(sk)) <= -+ bbr_target_cwnd(sk, bbr_max_bw(sk), BBR_UNIT)) -+ bbr_reset_probe_bw_mode(sk); /* we estimate queue is drained */ -+} -+ -+static void bbr_check_probe_rtt_done(struct sock *sk) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct bbr *bbr = inet_csk_ca(sk); -+ -+ if (!(bbr->probe_rtt_done_stamp && -+ after(tcp_jiffies32, bbr->probe_rtt_done_stamp))) -+ return; -+ -+ bbr->min_rtt_stamp = tcp_jiffies32; /* wait a while until PROBE_RTT */ -+ tp->snd_cwnd = max(tp->snd_cwnd, bbr->prior_cwnd); -+ bbr_reset_mode(sk); -+} -+ -+/* The goal of PROBE_RTT mode is to have BBR flows cooperatively and -+ * periodically drain the bottleneck queue, to converge to measure the true -+ * min_rtt (unloaded propagation delay). This allows the flows to keep queues -+ * small (reducing queuing delay and packet loss) and achieve fairness among -+ * BBR flows. -+ * -+ * The min_rtt filter window is 10 seconds. When the min_rtt estimate expires, -+ * we enter PROBE_RTT mode and cap the cwnd at bbr_cwnd_min_target=4 packets. -+ * After at least bbr_probe_rtt_mode_ms=200ms and at least one packet-timed -+ * round trip elapsed with that flight size <= 4, we leave PROBE_RTT mode and -+ * re-enter the previous mode. BBR uses 200ms to approximately bound the -+ * performance penalty of PROBE_RTT's cwnd capping to roughly 2% (200ms/10s). -+ * -+ * Note that flows need only pay 2% if they are busy sending over the last 10 -+ * seconds. Interactive applications (e.g., Web, RPCs, video chunks) often have -+ * natural silences or low-rate periods within 10 seconds where the rate is low -+ * enough for long enough to drain its queue in the bottleneck. We pick up -+ * these min RTT measurements opportunistically with our min_rtt filter. :-) -+ */ -+static void bbr_update_min_rtt(struct sock *sk, const struct rate_sample *rs) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct bbr *bbr = inet_csk_ca(sk); -+ bool filter_expired; -+ -+ /* Track min RTT seen in the min_rtt_win_sec filter window: */ -+ filter_expired = after(tcp_jiffies32, -+ bbr->min_rtt_stamp + bbr_min_rtt_win_sec * HZ); -+ if (rs->rtt_us >= 0 && -+ (rs->rtt_us <= bbr->min_rtt_us || -+ (filter_expired && !rs->is_ack_delayed))) { -+ bbr->min_rtt_us = rs->rtt_us; -+ bbr->min_rtt_stamp = tcp_jiffies32; -+ } -+ -+ if (bbr_probe_rtt_mode_ms > 0 && filter_expired && -+ !bbr->idle_restart && bbr->mode != BBR_PROBE_RTT) { -+ bbr->mode = BBR_PROBE_RTT; /* dip, drain queue */ -+ bbr->pacing_gain = BBR_UNIT; -+ bbr->cwnd_gain = BBR_UNIT; -+ bbr_save_cwnd(sk); /* note cwnd so we can restore it */ -+ bbr->probe_rtt_done_stamp = 0; -+ } -+ -+ if (bbr->mode == BBR_PROBE_RTT) { -+ /* Ignore low rate samples during this mode. */ -+ tp->app_limited = -+ (tp->delivered + tcp_packets_in_flight(tp)) ? : 1; -+ /* Maintain min packets in flight for max(200 ms, 1 round). */ -+ if (!bbr->probe_rtt_done_stamp && -+ tcp_packets_in_flight(tp) <= bbr_cwnd_min_target) { -+ bbr->probe_rtt_done_stamp = tcp_jiffies32 + -+ msecs_to_jiffies(bbr_probe_rtt_mode_ms); -+ bbr->probe_rtt_round_done = 0; -+ bbr->next_rtt_delivered = tp->delivered; -+ } else if (bbr->probe_rtt_done_stamp) { -+ if (bbr->round_start) -+ bbr->probe_rtt_round_done = 1; -+ if (bbr->probe_rtt_round_done) -+ bbr_check_probe_rtt_done(sk); -+ } -+ } -+ /* Restart after idle ends only once we process a new S/ACK for data */ -+ if (rs->delivered > 0) -+ bbr->idle_restart = 0; -+} -+ -+static void bbr_update_model(struct sock *sk, const struct rate_sample *rs) -+{ -+ bbr_update_bw(sk, rs); -+ bbr_update_cycle_phase(sk, rs); -+ bbr_check_full_bw_reached(sk, rs); -+ bbr_check_drain(sk, rs); -+ bbr_update_min_rtt(sk, rs); -+} -+ -+static void bbr_main(struct sock *sk, const struct rate_sample *rs) -+{ -+ struct bbr *bbr = inet_csk_ca(sk); -+ u32 bw; -+ -+ bbr_update_model(sk, rs); -+ -+ bw = bbr_bw(sk); -+ bbr_set_pacing_rate(sk, bw, bbr->pacing_gain); -+ bbr_set_cwnd(sk, rs, rs->acked_sacked, bw, bbr->cwnd_gain); -+} -+ -+static void bbr_init(struct sock *sk) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct bbr *bbr = inet_csk_ca(sk); -+ -+ bbr->prior_cwnd = 0; -+ tp->snd_ssthresh = TCP_INFINITE_SSTHRESH; -+ bbr->rtt_cnt = 0; -+ bbr->next_rtt_delivered = 0; -+ bbr->prev_ca_state = TCP_CA_Open; -+ bbr->packet_conservation = 0; -+ -+ bbr->probe_rtt_done_stamp = 0; -+ bbr->probe_rtt_round_done = 0; -+ bbr->min_rtt_us = tcp_min_rtt(tp); -+ bbr->min_rtt_stamp = tcp_jiffies32; -+ -+ minmax_reset(&bbr->bw, bbr->rtt_cnt, 0); /* init max bw to 0 */ -+ -+ bbr->has_seen_rtt = 0; -+ bbr_init_pacing_rate_from_rtt(sk); -+ -+ bbr->round_start = 0; -+ bbr->idle_restart = 0; -+ bbr->full_bw_reached = 0; -+ bbr->full_bw = 0; -+ bbr->full_bw_cnt = 0; -+ bbr->cycle_mstamp = 0; -+ bbr->cycle_idx = 0; -+ bbr_reset_lt_bw_sampling(sk); -+ bbr_reset_startup_mode(sk); -+ -+ cmpxchg(&sk->sk_pacing_status, SK_PACING_NONE, SK_PACING_NEEDED); -+} -+ -+static u32 bbr_sndbuf_expand(struct sock *sk) -+{ -+ /* Provision 3 * cwnd since BBR may slow-start even during recovery. */ -+ return 3; -+} -+ -+/* In theory BBR does not need to undo the cwnd since it does not -+ * always reduce cwnd on losses (see bbr_main()). Keep it for now. -+ */ -+static u32 bbr_undo_cwnd(struct sock *sk) -+{ -+ struct bbr *bbr = inet_csk_ca(sk); -+ -+ bbr->full_bw = 0; /* spurious slow-down; reset full pipe detection */ -+ bbr->full_bw_cnt = 0; -+ bbr_reset_lt_bw_sampling(sk); -+ return tcp_sk(sk)->snd_cwnd; -+} -+ -+/* Entering loss recovery, so save cwnd for when we exit or undo recovery. */ -+static u32 bbr_ssthresh(struct sock *sk) -+{ -+ bbr_save_cwnd(sk); -+ return tcp_sk(sk)->snd_ssthresh; -+} -+ -+static size_t bbr_get_info(struct sock *sk, u32 ext, int *attr, -+ union tcp_cc_info *info) -+{ -+ if (ext & (1 << (INET_DIAG_BBRINFO - 1)) || -+ ext & (1 << (INET_DIAG_VEGASINFO - 1))) { -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct bbr *bbr = inet_csk_ca(sk); -+ u64 bw = bbr_bw(sk); -+ -+ bw = bw * tp->mss_cache * USEC_PER_SEC >> BW_SCALE; -+ memset(&info->bbr, 0, sizeof(info->bbr)); -+ info->bbr.bbr_bw_lo = (u32)bw; -+ info->bbr.bbr_bw_hi = (u32)(bw >> 32); -+ info->bbr.bbr_min_rtt = bbr->min_rtt_us; -+ info->bbr.bbr_pacing_gain = bbr->pacing_gain; -+ info->bbr.bbr_cwnd_gain = bbr->cwnd_gain; -+ *attr = INET_DIAG_BBRINFO; -+ return sizeof(info->bbr); -+ } -+ return 0; -+} -+ -+static void bbr_set_state(struct sock *sk, u8 new_state) -+{ -+ struct bbr *bbr = inet_csk_ca(sk); -+ -+ if (new_state == TCP_CA_Loss) { -+ struct rate_sample rs = { .losses = 1 }; -+ -+ bbr->prev_ca_state = TCP_CA_Loss; -+ bbr->full_bw = 0; -+ bbr->round_start = 1; /* treat RTO like end of a round */ -+ bbr_lt_bw_sampling(sk, &rs); -+ } -+} -+ -+static struct tcp_congestion_ops tcp_bbr_cong_ops __read_mostly = { -+ .flags = TCP_CONG_NON_RESTRICTED, -+ .name = "nanqinlang", -+ .owner = THIS_MODULE, -+ .init = bbr_init, -+ .cong_control = bbr_main, -+ .sndbuf_expand = bbr_sndbuf_expand, -+ .undo_cwnd = bbr_undo_cwnd, -+ .cwnd_event = bbr_cwnd_event, -+ .ssthresh = bbr_ssthresh, -+ .min_tso_segs = bbr_min_tso_segs, -+ .get_info = bbr_get_info, -+ .set_state = bbr_set_state, -+}; -+ -+static int __init bbr_register(void) -+{ -+ BUILD_BUG_ON(sizeof(struct bbr) > ICSK_CA_PRIV_SIZE); -+ return tcp_register_congestion_control(&tcp_bbr_cong_ops); -+} -+ -+static void __exit bbr_unregister(void) -+{ -+ tcp_unregister_congestion_control(&tcp_bbr_cong_ops); -+} -+ -+module_init(bbr_register); -+module_exit(bbr_unregister); -+ -+MODULE_AUTHOR("Van Jacobson "); -+MODULE_AUTHOR("Neal Cardwell "); -+MODULE_AUTHOR("Yuchung Cheng "); -+MODULE_AUTHOR("Soheil Hassas Yeganeh "); -+MODULE_LICENSE("Dual BSD/GPL"); -+MODULE_DESCRIPTION("TCP BBR (Bottleneck Bandwidth and RTT)"); -+MODULE_AUTHOR("Nanqinlang "); diff --git a/root/target/linux/generic/hack-4.19/998-ndpi-netfilter.patch b/root/target/linux/generic/hack-4.19/998-ndpi-netfilter.patch deleted file mode 100644 index cd8d61a7..00000000 --- a/root/target/linux/generic/hack-4.19/998-ndpi-netfilter.patch +++ /dev/null @@ -1,116 +0,0 @@ -diff --git a/include/net/netfilter/nf_conntrack_extend.h b/include/net/netfilter/nf_conntrack_extend.h -index 21f887c..59980ec 100644 ---- a/include/net/netfilter/nf_conntrack_extend.h -+++ b/include/net/netfilter/nf_conntrack_extend.h -@@ -28,7 +28,8 @@ enum nf_ct_ext_id { - #if IS_ENABLED(CONFIG_NETFILTER_SYNPROXY) - NF_CT_EXT_SYNPROXY, - #endif -- NF_CT_EXT_NUM, -+ NF_CT_EXT_CUSTOM, -+ NF_CT_EXT_NUM=NF_CT_EXT_CUSTOM+CONFIG_NF_CONNTRACK_CUSTOM, - }; - - #define NF_CT_EXT_HELPER_TYPE struct nf_conn_help -@@ -96,5 +97,6 @@ struct nf_ct_ext_type { - }; - - int nf_ct_extend_register(const struct nf_ct_ext_type *type); -+int nf_ct_extend_custom_register(struct nf_ct_ext_type *type,unsigned long int cid); - void nf_ct_extend_unregister(const struct nf_ct_ext_type *type); - #endif /* _NF_CONNTRACK_EXTEND_H */ -diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig -index 7581e82..30a11eb 100644 ---- a/net/netfilter/Kconfig -+++ b/net/netfilter/Kconfig -@@ -85,6 +85,16 @@ config NF_CONNTRACK_SECMARK - - If unsure, say 'N'. - -+config NF_CONNTRACK_CUSTOM -+ int "Number of custom extend" -+ range 0 8 -+ depends on NETFILTER_ADVANCED -+ default "2" -+ help -+ This parameter specifies how many custom extensions can be registered. -+ -+ The default value is 2. -+ - config NF_CONNTRACK_ZONES - bool 'Connection tracking zones' - depends on NETFILTER_ADVANCED -diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c -index 85f643c..44e2fdd 100644 ---- a/net/netfilter/nf_conntrack_core.c -+++ b/net/netfilter/nf_conntrack_core.c -@@ -1971,7 +1971,7 @@ int nf_conntrack_set_hashsize(const char *val, const struct kernel_param *kp) - static __always_inline unsigned int total_extension_size(void) - { - /* remember to add new extensions below */ -- BUILD_BUG_ON(NF_CT_EXT_NUM > 9); -+ BUILD_BUG_ON(NF_CT_EXT_NUM > 12); - - return sizeof(struct nf_ct_ext) + - sizeof(struct nf_conn_help) -diff --git a/net/netfilter/nf_conntrack_extend.c b/net/netfilter/nf_conntrack_extend.c -index 9fe0ddc..5a9054e 100644 ---- a/net/netfilter/nf_conntrack_extend.c -+++ b/net/netfilter/nf_conntrack_extend.c -@@ -108,11 +108,56 @@ int nf_ct_extend_register(const struct nf_ct_ext_type *type) - } - EXPORT_SYMBOL_GPL(nf_ct_extend_register); - -+static unsigned long int nf_ct_ext_cust_id[CONFIG_NF_CONNTRACK_CUSTOM]; -+static enum nf_ct_ext_id -+nf_ct_extend_get_custom_id(unsigned long int ext_id); -+ -+int nf_ct_extend_custom_register(struct nf_ct_ext_type *type, -+ unsigned long int cid) -+{ -+ int ret; -+ enum nf_ct_ext_id new_id = nf_ct_extend_get_custom_id(cid); -+ if(!new_id) -+ return -EBUSY; -+ type->id = new_id; -+ ret = nf_ct_extend_register(type); -+ if(ret < 0) { -+ mutex_lock(&nf_ct_ext_type_mutex); -+ nf_ct_ext_cust_id[new_id - NF_CT_EXT_CUSTOM] = 0; -+ mutex_unlock(&nf_ct_ext_type_mutex); -+ } -+ return ret; -+} -+EXPORT_SYMBOL_GPL(nf_ct_extend_custom_register); -+ -+static enum nf_ct_ext_id -+nf_ct_extend_get_custom_id(unsigned long int ext_id) -+{ -+ enum nf_ct_ext_id ret = 0; -+ int i; -+ mutex_lock(&nf_ct_ext_type_mutex); -+ for(i = 0; i < CONFIG_NF_CONNTRACK_CUSTOM; i++) { -+ if(!nf_ct_ext_cust_id[i]) { -+ nf_ct_ext_cust_id[i] = ext_id; -+ ret = i+NF_CT_EXT_CUSTOM; -+ break; -+ } -+ if(nf_ct_ext_cust_id[i] == ext_id) { -+ ret = i+NF_CT_EXT_CUSTOM; -+ break; -+ } -+ } -+ mutex_unlock(&nf_ct_ext_type_mutex); -+ return ret; -+} -+ - /* This MUST be called in process context. */ - void nf_ct_extend_unregister(const struct nf_ct_ext_type *type) - { - mutex_lock(&nf_ct_ext_type_mutex); - RCU_INIT_POINTER(nf_ct_ext_types[type->id], NULL); -+ if(type->id >= NF_CT_EXT_CUSTOM && type->id < NF_CT_EXT_NUM) -+ nf_ct_ext_cust_id[type->id-NF_CT_EXT_CUSTOM] = 0; - mutex_unlock(&nf_ct_ext_type_mutex); - synchronize_rcu(); - } diff --git a/root/target/linux/generic/hack-4.19/999-f2fs-ioerrorfix.patch b/root/target/linux/generic/hack-4.19/999-f2fs-ioerrorfix.patch deleted file mode 100644 index ebc43131..00000000 --- a/root/target/linux/generic/hack-4.19/999-f2fs-ioerrorfix.patch +++ /dev/null @@ -1,25 +0,0 @@ ---- - fs/f2fs/checkpoint.c | 6 ++++++ - 1 file changed, 6 insertions(+) - -diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c -index a7ad1b1e5750..90e1bab86269 100644 ---- a/fs/f2fs/checkpoint.c -+++ b/fs/f2fs/checkpoint.c -@@ -674,6 +674,12 @@ int f2fs_recover_orphan_inodes(struct f2fs_sb_info *sbi) - if (!is_set_ckpt_flags(sbi, CP_ORPHAN_PRESENT_FLAG)) - return 0; - -+ if (bdev_read_only(sbi->sb->s_bdev)) { -+ f2fs_msg(sbi->sb, KERN_INFO, "write access " -+ "unavailable, skipping orphan cleanup"); -+ return 0; -+ } -+ - if (s_flags & SB_RDONLY) { - f2fs_msg(sbi->sb, KERN_INFO, "orphan cleanup on readonly fs"); - sbi->sb->s_flags &= ~SB_RDONLY; --- -2.18.0.rc1 - - \ No newline at end of file diff --git a/root/target/linux/generic/hack-4.19/999-stop-promiscuous-info.patch b/root/target/linux/generic/hack-4.19/999-stop-promiscuous-info.patch deleted file mode 100644 index 2dc06ee6..00000000 --- a/root/target/linux/generic/hack-4.19/999-stop-promiscuous-info.patch +++ /dev/null @@ -1,14 +0,0 @@ ---- a/net/core/dev.c 2018-08-10 10:31:41.199494561 +0200 -+++ b/net/core/dev.c 2018-08-10 10:32:03.635272509 +0200 -@@ -6613,9 +6613,11 @@ - } - } - if (dev->flags != old_flags) { -+ /* - pr_info("device %s %s promiscuous mode\n", - dev->name, - dev->flags & IFF_PROMISC ? "entered" : "left"); -+ */ - if (audit_enabled) { - current_uid_gid(&uid, &gid); - audit_log(current->audit_context, GFP_ATOMIC, diff --git a/root/target/linux/generic/hack-4.9/690-mptcp_v0.93.patch b/root/target/linux/generic/hack-4.9/690-mptcp_v0.93.patch deleted file mode 100644 index 2ee5998d..00000000 --- a/root/target/linux/generic/hack-4.9/690-mptcp_v0.93.patch +++ /dev/null @@ -1,20499 +0,0 @@ -diff -aurN linux-4.9.162/Documentation/networking/ip-sysctl.txt mptcp-mptcp_v0.93/Documentation/networking/ip-sysctl.txt ---- linux-4.9.162/Documentation/networking/ip-sysctl.txt 2019-03-05 17:57:07.000000000 +0100 -+++ mptcp-mptcp_v0.93/Documentation/networking/ip-sysctl.txt 2019-03-14 14:02:32.000000000 +0100 -@@ -732,6 +732,18 @@ - in RFC 5961 (Improving TCP's Robustness to Blind In-Window Attacks) - Default: 100 - -+MPTCP variables: -+ -+mptcp_enabled - INTEGER -+ Enable or disable Multipath TCP for new connections. -+ Possible values are: -+ -+ 0: Multipath TCP is disabled on all TCP-sockets that are newly created. -+ 1: Multipath TCP is enabled by default on all new TCP-sockets. Note that -+ existing sockets in LISTEN-state will still use regular TCP. -+ 2: Enables Multipath TCP only upon the request of the application -+ throught the socket-option MPTCP_ENABLED. -+ - UDP variables: - - udp_mem - vector of 3 INTEGERs: min, pressure, max -diff -aurN linux-4.9.162/drivers/infiniband/hw/cxgb4/cm.c mptcp-mptcp_v0.93/drivers/infiniband/hw/cxgb4/cm.c ---- linux-4.9.162/drivers/infiniband/hw/cxgb4/cm.c 2019-03-05 17:57:07.000000000 +0100 -+++ mptcp-mptcp_v0.93/drivers/infiniband/hw/cxgb4/cm.c 2019-03-14 14:02:32.000000000 +0100 -@@ -3736,7 +3736,7 @@ - */ - memset(&tmp_opt, 0, sizeof(tmp_opt)); - tcp_clear_options(&tmp_opt); -- tcp_parse_options(skb, &tmp_opt, 0, NULL); -+ tcp_parse_options(skb, &tmp_opt, NULL, 0, NULL, NULL); - - req = (struct cpl_pass_accept_req *)__skb_push(skb, sizeof(*req)); - memset(req, 0, sizeof(*req)); -diff -aurN linux-4.9.162/include/linux/skbuff.h mptcp-mptcp_v0.93/include/linux/skbuff.h ---- linux-4.9.162/include/linux/skbuff.h 2019-03-05 17:57:07.000000000 +0100 -+++ mptcp-mptcp_v0.93/include/linux/skbuff.h 2019-03-14 14:02:32.000000000 +0100 -@@ -659,7 +659,7 @@ - * want to keep them across layers you have to do a skb_clone() - * first. This is owned by whoever has the skb queued ATM. - */ -- char cb[48] __aligned(8); -+ char cb[80] __aligned(8); - - unsigned long _skb_refdst; - void (*destructor)(struct sk_buff *skb); -diff -aurN linux-4.9.162/include/linux/tcp.h mptcp-mptcp_v0.93/include/linux/tcp.h ---- linux-4.9.162/include/linux/tcp.h 2019-03-05 17:57:07.000000000 +0100 -+++ mptcp-mptcp_v0.93/include/linux/tcp.h 2019-03-14 14:02:32.000000000 +0100 -@@ -58,7 +58,7 @@ - /* TCP Fast Open */ - #define TCP_FASTOPEN_COOKIE_MIN 4 /* Min Fast Open Cookie size in bytes */ - #define TCP_FASTOPEN_COOKIE_MAX 16 /* Max Fast Open Cookie size in bytes */ --#define TCP_FASTOPEN_COOKIE_SIZE 8 /* the size employed by this impl. */ -+#define TCP_FASTOPEN_COOKIE_SIZE 4 /* the size employed by this impl. */ - - /* TCP Fast Open Cookie as stored in memory */ - struct tcp_fastopen_cookie { -@@ -83,6 +83,56 @@ - u32 end_seq; - }; - -+struct tcp_out_options { -+ u16 options; /* bit field of OPTION_* */ -+ u8 ws; /* window scale, 0 to disable */ -+ u8 num_sack_blocks;/* number of SACK blocks to include */ -+ u8 hash_size; /* bytes in hash_location */ -+ u16 mss; /* 0 to disable */ -+ __u8 *hash_location; /* temporary pointer, overloaded */ -+ __u32 tsval, tsecr; /* need to include OPTION_TS */ -+ struct tcp_fastopen_cookie *fastopen_cookie; /* Fast open cookie */ -+#ifdef CONFIG_MPTCP -+ u16 mptcp_options; /* bit field of MPTCP related OPTION_* */ -+ u8 dss_csum:1, /* dss-checksum required? */ -+ add_addr_v4:1, -+ add_addr_v6:1, -+ mptcp_ver:4; -+ -+ union { -+ struct { -+ __u64 sender_key; /* sender's key for mptcp */ -+ __u64 receiver_key; /* receiver's key for mptcp */ -+ } mp_capable; -+ -+ struct { -+ __u64 sender_truncated_mac; -+ __u32 sender_nonce; -+ /* random number of the sender */ -+ __u32 token; /* token for mptcp */ -+ u8 low_prio:1; -+ } mp_join_syns; -+ }; -+ -+ struct { -+ __u64 trunc_mac; -+ struct in_addr addr; -+ u16 port; -+ u8 addr_id; -+ } add_addr4; -+ -+ struct { -+ __u64 trunc_mac; -+ struct in6_addr addr; -+ u16 port; -+ u8 addr_id; -+ } add_addr6; -+ -+ u16 remove_addrs; /* list of address id */ -+ u8 addr_id; /* address id (mp_join or add_address) */ -+#endif /* CONFIG_MPTCP */ -+}; -+ - /*These are used to set the sack_ok field in struct tcp_options_received */ - #define TCP_SACK_SEEN (1 << 0) /*1 = peer is SACK capable, */ - #define TCP_FACK_ENABLED (1 << 1) /*1 = FACK is enabled locally*/ -@@ -106,6 +156,9 @@ - u16 mss_clamp; /* Maximal mss, negotiated at connection setup */ - }; - -+struct mptcp_cb; -+struct mptcp_tcp_sock; -+ - static inline void tcp_clear_options(struct tcp_options_received *rx_opt) - { - rx_opt->tstamp_ok = rx_opt->sack_ok = 0; -@@ -140,6 +193,8 @@ - return (struct tcp_request_sock *)req; - } - -+struct tcp_md5sig_key; -+ - struct tcp_sock { - /* inet_connection_sock has to be the first member of tcp_sock */ - struct inet_connection_sock inet_conn; -@@ -366,6 +421,44 @@ - */ - struct request_sock *fastopen_rsk; - u32 *saved_syn; -+ -+ /* MPTCP/TCP-specific callbacks */ -+ const struct tcp_sock_ops *ops; -+ -+ struct mptcp_cb *mpcb; -+ struct sock *meta_sk; -+ /* We keep these flags even if CONFIG_MPTCP is not checked, because -+ * it allows checking MPTCP capability just by checking the mpc flag, -+ * rather than adding ifdefs everywhere. -+ */ -+ u32 mpc:1, /* Other end is multipath capable */ -+ inside_tk_table:1, /* Is the tcp_sock inside the token-table? */ -+ send_mp_fclose:1, -+ request_mptcp:1, /* Did we send out an MP_CAPABLE? -+ * (this speeds up mptcp_doit() in tcp_recvmsg) -+ */ -+ pf:1, /* Potentially Failed state: when this flag is set, we -+ * stop using the subflow -+ */ -+ mp_killed:1, /* Killed with a tcp_done in mptcp? */ -+ was_meta_sk:1, /* This was a meta sk (in case of reuse) */ -+ is_master_sk:1, -+ close_it:1, /* Must close socket in mptcp_data_ready? */ -+ closing:1, -+ mptcp_ver:4, -+ mptcp_sched_setsockopt:1, -+ mptcp_pm_setsockopt:1, -+ record_master_info:1; -+ struct mptcp_tcp_sock *mptcp; -+#ifdef CONFIG_MPTCP -+#define MPTCP_SCHED_NAME_MAX 16 -+#define MPTCP_PM_NAME_MAX 16 -+ struct hlist_nulls_node tk_table; -+ u32 mptcp_loc_token; -+ u64 mptcp_loc_key; -+ char mptcp_sched_name[MPTCP_SCHED_NAME_MAX]; -+ char mptcp_pm_name[MPTCP_PM_NAME_MAX]; -+#endif /* CONFIG_MPTCP */ - }; - - enum tsq_flags { -@@ -377,6 +470,8 @@ - TCP_MTU_REDUCED_DEFERRED, /* tcp_v{4|6}_err() could not call - * tcp_v{4|6}_mtu_reduced() - */ -+ MPTCP_PATH_MANAGER_DEFERRED, /* MPTCP deferred creation of new subflows */ -+ MPTCP_SUB_DEFERRED, /* A subflow got deferred - process them */ - }; - - static inline struct tcp_sock *tcp_sk(const struct sock *sk) -@@ -399,6 +494,7 @@ - #ifdef CONFIG_TCP_MD5SIG - struct tcp_md5sig_key *tw_md5_key; - #endif -+ struct mptcp_tw *mptcp_tw; - }; - - static inline struct tcp_timewait_sock *tcp_twsk(const struct sock *sk) -diff -aurN linux-4.9.162/include/net/inet_common.h mptcp-mptcp_v0.93/include/net/inet_common.h ---- linux-4.9.162/include/net/inet_common.h 2019-03-05 17:57:07.000000000 +0100 -+++ mptcp-mptcp_v0.93/include/net/inet_common.h 2019-03-14 14:02:32.000000000 +0100 -@@ -1,6 +1,8 @@ - #ifndef _INET_COMMON_H - #define _INET_COMMON_H - -+#include -+ - extern const struct proto_ops inet_stream_ops; - extern const struct proto_ops inet_dgram_ops; - -@@ -13,6 +15,8 @@ - struct sockaddr; - struct socket; - -+int inet_create(struct net *net, struct socket *sock, int protocol, int kern); -+int inet6_create(struct net *net, struct socket *sock, int protocol, int kern); - int inet_release(struct socket *sock); - int inet_stream_connect(struct socket *sock, struct sockaddr *uaddr, - int addr_len, int flags); -diff -aurN linux-4.9.162/include/net/inet_connection_sock.h mptcp-mptcp_v0.93/include/net/inet_connection_sock.h ---- linux-4.9.162/include/net/inet_connection_sock.h 2019-03-05 17:57:07.000000000 +0100 -+++ mptcp-mptcp_v0.93/include/net/inet_connection_sock.h 2019-03-14 14:02:32.000000000 +0100 -@@ -30,6 +30,7 @@ - - struct inet_bind_bucket; - struct tcp_congestion_ops; -+struct tcp_options_received; - - /* - * Pointers to address related TCP functions -diff -aurN linux-4.9.162/include/net/inet_sock.h mptcp-mptcp_v0.93/include/net/inet_sock.h ---- linux-4.9.162/include/net/inet_sock.h 2019-03-05 17:57:07.000000000 +0100 -+++ mptcp-mptcp_v0.93/include/net/inet_sock.h 2019-03-14 14:02:32.000000000 +0100 -@@ -92,7 +92,9 @@ - wscale_ok : 1, - ecn_ok : 1, - acked : 1, -- no_srccheck: 1; -+ no_srccheck: 1, -+ mptcp_rqsk : 1, -+ saw_mpc : 1; - kmemcheck_bitfield_end(flags); - u32 ir_mark; - union { -diff -aurN linux-4.9.162/include/net/mptcp.h mptcp-mptcp_v0.93/include/net/mptcp.h ---- linux-4.9.162/include/net/mptcp.h 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_v0.93/include/net/mptcp.h 2019-03-14 14:02:32.000000000 +0100 -@@ -0,0 +1,1509 @@ -+/* -+ * MPTCP implementation -+ * -+ * Initial Design & Implementation: -+ * Sébastien Barré -+ * -+ * Current Maintainer & Author: -+ * Christoph Paasch -+ * -+ * Additional authors: -+ * Jaakko Korkeaniemi -+ * Gregory Detal -+ * Fabien Duchêne -+ * Andreas Seelinger -+ * Lavkesh Lahngir -+ * Andreas Ripke -+ * Vlad Dogaru -+ * Octavian Purdila -+ * John Ronan -+ * Catalin Nicutar -+ * Brandon Heller -+ * -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version -+ * 2 of the License, or (at your option) any later version. -+ */ -+ -+#ifndef _MPTCP_H -+#define _MPTCP_H -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+ -+#if defined(__LITTLE_ENDIAN_BITFIELD) -+ #define ntohll(x) be64_to_cpu(x) -+ #define htonll(x) cpu_to_be64(x) -+#elif defined(__BIG_ENDIAN_BITFIELD) -+ #define ntohll(x) (x) -+ #define htonll(x) (x) -+#endif -+ -+struct mptcp_loc4 { -+ u8 loc4_id; -+ u8 low_prio:1; -+ int if_idx; -+ struct in_addr addr; -+}; -+ -+struct mptcp_rem4 { -+ u8 rem4_id; -+ __be16 port; -+ struct in_addr addr; -+}; -+ -+struct mptcp_loc6 { -+ u8 loc6_id; -+ u8 low_prio:1; -+ int if_idx; -+ struct in6_addr addr; -+}; -+ -+struct mptcp_rem6 { -+ u8 rem6_id; -+ __be16 port; -+ struct in6_addr addr; -+}; -+ -+struct mptcp_request_sock { -+ struct tcp_request_sock req; -+ struct hlist_nulls_node hash_entry; -+ -+ union { -+ struct { -+ /* Only on initial subflows */ -+ u64 mptcp_loc_key; -+ u64 mptcp_rem_key; -+ u32 mptcp_loc_token; -+ }; -+ -+ struct { -+ /* Only on additional subflows */ -+ u32 mptcp_rem_nonce; -+ u32 mptcp_loc_nonce; -+ u64 mptcp_hash_tmac; -+ }; -+ }; -+ -+ u8 loc_id; -+ u8 rem_id; /* Address-id in the MP_JOIN */ -+ u8 dss_csum:1, -+ is_sub:1, /* Is this a new subflow? */ -+ low_prio:1, /* Interface set to low-prio? */ -+ rcv_low_prio:1, -+ mptcp_ver:4; -+}; -+ -+struct mptcp_options_received { -+ u16 saw_mpc:1, -+ dss_csum:1, -+ drop_me:1, -+ -+ is_mp_join:1, -+ join_ack:1, -+ -+ saw_low_prio:2, /* 0x1 - low-prio set for this subflow -+ * 0x2 - low-prio set for another subflow -+ */ -+ low_prio:1, -+ -+ saw_add_addr:2, /* Saw at least one add_addr option: -+ * 0x1: IPv4 - 0x2: IPv6 -+ */ -+ more_add_addr:1, /* Saw one more add-addr. */ -+ -+ saw_rem_addr:1, /* Saw at least one rem_addr option */ -+ more_rem_addr:1, /* Saw one more rem-addr. */ -+ -+ mp_fail:1, -+ mp_fclose:1; -+ u8 rem_id; /* Address-id in the MP_JOIN */ -+ u8 prio_addr_id; /* Address-id in the MP_PRIO */ -+ -+ const unsigned char *add_addr_ptr; /* Pointer to add-address option */ -+ const unsigned char *rem_addr_ptr; /* Pointer to rem-address option */ -+ -+ u32 data_ack; -+ u32 data_seq; -+ u16 data_len; -+ -+ u8 mptcp_ver; /* MPTCP version */ -+ -+ /* Key inside the option (from mp_capable or fast_close) */ -+ u64 mptcp_sender_key; -+ u64 mptcp_receiver_key; -+ -+ u32 mptcp_rem_token; /* Remote token */ -+ -+ u32 mptcp_recv_nonce; -+ u64 mptcp_recv_tmac; -+ u8 mptcp_recv_mac[20]; -+}; -+ -+struct mptcp_tcp_sock { -+ struct tcp_sock *next; /* Next subflow socket */ -+ struct hlist_node cb_list; -+ struct mptcp_options_received rx_opt; -+ -+ /* Those three fields record the current mapping */ -+ u64 map_data_seq; -+ u32 map_subseq; -+ u16 map_data_len; -+ u16 slave_sk:1, -+ fully_established:1, -+ establish_increased:1, -+ second_packet:1, -+ attached:1, -+ send_mp_fail:1, -+ include_mpc:1, -+ mapping_present:1, -+ map_data_fin:1, -+ low_prio:1, /* use this socket as backup */ -+ rcv_low_prio:1, /* Peer sent low-prio option to us */ -+ send_mp_prio:1, /* Trigger to send mp_prio on this socket */ -+ pre_established:1; /* State between sending 3rd ACK and -+ * receiving the fourth ack of new subflows. -+ */ -+ -+ /* isn: needed to translate abs to relative subflow seqnums */ -+ u32 snt_isn; -+ u32 rcv_isn; -+ u8 path_index; -+ u8 loc_id; -+ u8 rem_id; -+ -+#define MPTCP_SCHED_SIZE 16 -+ u8 mptcp_sched[MPTCP_SCHED_SIZE] __aligned(8); -+ -+ int init_rcv_wnd; -+ u32 infinite_cutoff_seq; -+ struct delayed_work work; -+ u32 mptcp_loc_nonce; -+ struct tcp_sock *tp; /* Where is my daddy? */ -+ u32 last_end_data_seq; -+ -+ /* MP_JOIN subflow: timer for retransmitting the 3rd ack */ -+ struct timer_list mptcp_ack_timer; -+ -+ /* HMAC of the third ack */ -+ char sender_mac[20]; -+}; -+ -+struct mptcp_tw { -+ struct list_head list; -+ u64 loc_key; -+ u64 rcv_nxt; -+ struct mptcp_cb __rcu *mpcb; -+ u8 meta_tw:1, -+ in_list:1; -+}; -+ -+#define MPTCP_PM_NAME_MAX 16 -+struct mptcp_pm_ops { -+ struct list_head list; -+ -+ /* Signal the creation of a new MPTCP-session. */ -+ void (*new_session)(const struct sock *meta_sk); -+ void (*release_sock)(struct sock *meta_sk); -+ void (*fully_established)(struct sock *meta_sk); -+ void (*new_remote_address)(struct sock *meta_sk); -+ void (*subflow_error)(struct sock *meta_sk, struct sock *sk); -+ int (*get_local_id)(sa_family_t family, union inet_addr *addr, -+ struct net *net, bool *low_prio); -+ void (*addr_signal)(struct sock *sk, unsigned *size, -+ struct tcp_out_options *opts, struct sk_buff *skb); -+ void (*add_raddr)(struct mptcp_cb *mpcb, const union inet_addr *addr, -+ sa_family_t family, __be16 port, u8 id); -+ void (*rem_raddr)(struct mptcp_cb *mpcb, u8 rem_id); -+ void (*init_subsocket_v4)(struct sock *sk, struct in_addr addr); -+ void (*init_subsocket_v6)(struct sock *sk, struct in6_addr addr); -+ void (*delete_subflow)(struct sock *sk); -+ -+ char name[MPTCP_PM_NAME_MAX]; -+ struct module *owner; -+}; -+ -+#define MPTCP_SCHED_NAME_MAX 16 -+struct mptcp_sched_ops { -+ struct list_head list; -+ -+ struct sock * (*get_subflow)(struct sock *meta_sk, -+ struct sk_buff *skb, -+ bool zero_wnd_test); -+ struct sk_buff * (*next_segment)(struct sock *meta_sk, -+ int *reinject, -+ struct sock **subsk, -+ unsigned int *limit); -+ void (*init)(struct sock *sk); -+ void (*release)(struct sock *sk); -+ -+ char name[MPTCP_SCHED_NAME_MAX]; -+ struct module *owner; -+}; -+ -+struct mptcp_cb { -+ /* list of sockets in this multipath connection */ -+ struct tcp_sock *connection_list; -+ /* list of sockets that need a call to release_cb */ -+ struct hlist_head callback_list; -+ -+ /* High-order bits of 64-bit sequence numbers */ -+ u32 snd_high_order[2]; -+ u32 rcv_high_order[2]; -+ -+ u16 send_infinite_mapping:1, -+ in_time_wait:1, -+ list_rcvd:1, /* XXX TO REMOVE */ -+ addr_signal:1, /* Path-manager wants us to call addr_signal */ -+ dss_csum:1, -+ server_side:1, -+ infinite_mapping_rcv:1, -+ infinite_mapping_snd:1, -+ dfin_combined:1, /* Was the DFIN combined with subflow-fin? */ -+ passive_close:1, -+ snd_hiseq_index:1, /* Index in snd_high_order of snd_nxt */ -+ rcv_hiseq_index:1; /* Index in rcv_high_order of rcv_nxt */ -+ -+ /* socket count in this connection */ -+ u8 cnt_subflows; -+ u8 cnt_established; -+ -+#define MPTCP_SCHED_DATA_SIZE 8 -+ u8 mptcp_sched[MPTCP_SCHED_DATA_SIZE] __aligned(8); -+ struct mptcp_sched_ops *sched_ops; -+ -+ struct sk_buff_head reinject_queue; -+ /* First cache-line boundary is here minus 8 bytes. But from the -+ * reinject-queue only the next and prev pointers are regularly -+ * accessed. Thus, the whole data-path is on a single cache-line. -+ */ -+ -+ u64 csum_cutoff_seq; -+ u64 infinite_rcv_seq; -+ -+ /***** Start of fields, used for connection closure */ -+ spinlock_t tw_lock; -+ unsigned char mptw_state; -+ u8 dfin_path_index; -+ -+ struct list_head tw_list; -+ -+ /***** Start of fields, used for subflow establishment and closure */ -+ atomic_t mpcb_refcnt; -+ -+ /* Mutex needed, because otherwise mptcp_close will complain that the -+ * socket is owned by the user. -+ * E.g., mptcp_sub_close_wq is taking the meta-lock. -+ */ -+ struct mutex mpcb_mutex; -+ -+ /***** Start of fields, used for subflow establishment */ -+ struct sock *meta_sk; -+ -+ /* Master socket, also part of the connection_list, this -+ * socket is the one that the application sees. -+ */ -+ struct sock *master_sk; -+ -+ __u64 mptcp_loc_key; -+ __u64 mptcp_rem_key; -+ __u32 mptcp_loc_token; -+ __u32 mptcp_rem_token; -+ -+#define MPTCP_PM_SIZE 608 -+ u8 mptcp_pm[MPTCP_PM_SIZE] __aligned(8); -+ struct mptcp_pm_ops *pm_ops; -+ -+ u32 path_index_bits; -+ /* Next pi to pick up in case a new path becomes available */ -+ u8 next_path_index; -+ -+ __u8 mptcp_ver; -+ -+ /* Original snd/rcvbuf of the initial subflow. -+ * Used for the new subflows on the server-side to allow correct -+ * autotuning -+ */ -+ int orig_sk_rcvbuf; -+ int orig_sk_sndbuf; -+ u32 orig_window_clamp; -+ -+ struct tcp_info *master_info; -+}; -+ -+#define MPTCP_VERSION_0 0 -+#define MPTCP_VERSION_1 1 -+ -+#define MPTCP_SUB_CAPABLE 0 -+#define MPTCP_SUB_LEN_CAPABLE_SYN 12 -+#define MPTCP_SUB_LEN_CAPABLE_SYN_ALIGN 12 -+#define MPTCP_SUB_LEN_CAPABLE_ACK 20 -+#define MPTCP_SUB_LEN_CAPABLE_ACK_ALIGN 20 -+ -+#define MPTCP_SUB_JOIN 1 -+#define MPTCP_SUB_LEN_JOIN_SYN 12 -+#define MPTCP_SUB_LEN_JOIN_SYN_ALIGN 12 -+#define MPTCP_SUB_LEN_JOIN_SYNACK 16 -+#define MPTCP_SUB_LEN_JOIN_SYNACK_ALIGN 16 -+#define MPTCP_SUB_LEN_JOIN_ACK 24 -+#define MPTCP_SUB_LEN_JOIN_ACK_ALIGN 24 -+ -+#define MPTCP_SUB_DSS 2 -+#define MPTCP_SUB_LEN_DSS 4 -+#define MPTCP_SUB_LEN_DSS_ALIGN 4 -+ -+/* Lengths for seq and ack are the ones without the generic MPTCP-option header, -+ * as they are part of the DSS-option. -+ * To get the total length, just add the different options together. -+ */ -+#define MPTCP_SUB_LEN_SEQ 10 -+#define MPTCP_SUB_LEN_SEQ_CSUM 12 -+#define MPTCP_SUB_LEN_SEQ_ALIGN 12 -+ -+#define MPTCP_SUB_LEN_SEQ_64 14 -+#define MPTCP_SUB_LEN_SEQ_CSUM_64 16 -+#define MPTCP_SUB_LEN_SEQ_64_ALIGN 16 -+ -+#define MPTCP_SUB_LEN_ACK 4 -+#define MPTCP_SUB_LEN_ACK_ALIGN 4 -+ -+#define MPTCP_SUB_LEN_ACK_64 8 -+#define MPTCP_SUB_LEN_ACK_64_ALIGN 8 -+ -+/* This is the "default" option-length we will send out most often. -+ * MPTCP DSS-header -+ * 32-bit data sequence number -+ * 32-bit data ack -+ * -+ * It is necessary to calculate the effective MSS we will be using when -+ * sending data. -+ */ -+#define MPTCP_SUB_LEN_DSM_ALIGN (MPTCP_SUB_LEN_DSS_ALIGN + \ -+ MPTCP_SUB_LEN_SEQ_ALIGN + \ -+ MPTCP_SUB_LEN_ACK_ALIGN) -+ -+#define MPTCP_SUB_ADD_ADDR 3 -+#define MPTCP_SUB_LEN_ADD_ADDR4 8 -+#define MPTCP_SUB_LEN_ADD_ADDR4_VER1 16 -+#define MPTCP_SUB_LEN_ADD_ADDR6 20 -+#define MPTCP_SUB_LEN_ADD_ADDR6_VER1 28 -+#define MPTCP_SUB_LEN_ADD_ADDR4_ALIGN 8 -+#define MPTCP_SUB_LEN_ADD_ADDR4_ALIGN_VER1 16 -+#define MPTCP_SUB_LEN_ADD_ADDR6_ALIGN 20 -+#define MPTCP_SUB_LEN_ADD_ADDR6_ALIGN_VER1 28 -+ -+#define MPTCP_SUB_REMOVE_ADDR 4 -+#define MPTCP_SUB_LEN_REMOVE_ADDR 4 -+ -+#define MPTCP_SUB_PRIO 5 -+#define MPTCP_SUB_LEN_PRIO 3 -+#define MPTCP_SUB_LEN_PRIO_ADDR 4 -+#define MPTCP_SUB_LEN_PRIO_ALIGN 4 -+ -+#define MPTCP_SUB_FAIL 6 -+#define MPTCP_SUB_LEN_FAIL 12 -+#define MPTCP_SUB_LEN_FAIL_ALIGN 12 -+ -+#define MPTCP_SUB_FCLOSE 7 -+#define MPTCP_SUB_LEN_FCLOSE 12 -+#define MPTCP_SUB_LEN_FCLOSE_ALIGN 12 -+ -+ -+#define OPTION_MPTCP (1 << 5) -+ -+/* Max number of fastclose retransmissions */ -+#define MPTCP_FASTCLOSE_RETRIES 3 -+ -+#ifdef CONFIG_MPTCP -+ -+/* Used for checking if the mptcp initialization has been successful */ -+extern bool mptcp_init_failed; -+ -+/* MPTCP options */ -+#define OPTION_TYPE_SYN (1 << 0) -+#define OPTION_TYPE_SYNACK (1 << 1) -+#define OPTION_TYPE_ACK (1 << 2) -+#define OPTION_MP_CAPABLE (1 << 3) -+#define OPTION_DATA_ACK (1 << 4) -+#define OPTION_ADD_ADDR (1 << 5) -+#define OPTION_MP_JOIN (1 << 6) -+#define OPTION_MP_FAIL (1 << 7) -+#define OPTION_MP_FCLOSE (1 << 8) -+#define OPTION_REMOVE_ADDR (1 << 9) -+#define OPTION_MP_PRIO (1 << 10) -+ -+/* MPTCP flags: both TX and RX */ -+#define MPTCPHDR_SEQ 0x01 /* DSS.M option is present */ -+#define MPTCPHDR_FIN 0x02 /* DSS.F option is present */ -+#define MPTCPHDR_SEQ64_INDEX 0x04 /* index of seq in mpcb->snd_high_order */ -+/* MPTCP flags: RX only */ -+#define MPTCPHDR_ACK 0x08 -+#define MPTCPHDR_SEQ64_SET 0x10 /* Did we received a 64-bit seq number? */ -+#define MPTCPHDR_SEQ64_OFO 0x20 /* Is it not in our circular array? */ -+#define MPTCPHDR_DSS_CSUM 0x40 -+/* MPTCP flags: TX only */ -+#define MPTCPHDR_INF 0x08 -+#define MPTCP_REINJECT 0x10 /* Did we reinject this segment? */ -+ -+struct mptcp_option { -+ __u8 kind; -+ __u8 len; -+#if defined(__LITTLE_ENDIAN_BITFIELD) -+ __u8 ver:4, -+ sub:4; -+#elif defined(__BIG_ENDIAN_BITFIELD) -+ __u8 sub:4, -+ ver:4; -+#else -+#error "Adjust your defines" -+#endif -+}; -+ -+struct mp_capable { -+ __u8 kind; -+ __u8 len; -+#if defined(__LITTLE_ENDIAN_BITFIELD) -+ __u8 ver:4, -+ sub:4; -+ __u8 h:1, -+ rsv:5, -+ b:1, -+ a:1; -+#elif defined(__BIG_ENDIAN_BITFIELD) -+ __u8 sub:4, -+ ver:4; -+ __u8 a:1, -+ b:1, -+ rsv:5, -+ h:1; -+#else -+#error "Adjust your defines" -+#endif -+ __u64 sender_key; -+ __u64 receiver_key; -+} __attribute__((__packed__)); -+ -+struct mp_join { -+ __u8 kind; -+ __u8 len; -+#if defined(__LITTLE_ENDIAN_BITFIELD) -+ __u8 b:1, -+ rsv:3, -+ sub:4; -+#elif defined(__BIG_ENDIAN_BITFIELD) -+ __u8 sub:4, -+ rsv:3, -+ b:1; -+#else -+#error "Adjust your defines" -+#endif -+ __u8 addr_id; -+ union { -+ struct { -+ u32 token; -+ u32 nonce; -+ } syn; -+ struct { -+ __u64 mac; -+ u32 nonce; -+ } synack; -+ struct { -+ __u8 mac[20]; -+ } ack; -+ } u; -+} __attribute__((__packed__)); -+ -+struct mp_dss { -+ __u8 kind; -+ __u8 len; -+#if defined(__LITTLE_ENDIAN_BITFIELD) -+ __u16 rsv1:4, -+ sub:4, -+ A:1, -+ a:1, -+ M:1, -+ m:1, -+ F:1, -+ rsv2:3; -+#elif defined(__BIG_ENDIAN_BITFIELD) -+ __u16 sub:4, -+ rsv1:4, -+ rsv2:3, -+ F:1, -+ m:1, -+ M:1, -+ a:1, -+ A:1; -+#else -+#error "Adjust your defines" -+#endif -+}; -+ -+struct mp_add_addr { -+ __u8 kind; -+ __u8 len; -+#if defined(__LITTLE_ENDIAN_BITFIELD) -+ __u8 ipver:4, -+ sub:4; -+#elif defined(__BIG_ENDIAN_BITFIELD) -+ __u8 sub:4, -+ ipver:4; -+#else -+#error "Adjust your defines" -+#endif -+ __u8 addr_id; -+ union { -+ struct { -+ struct in_addr addr; -+ __be16 port; -+ __u8 mac[8]; -+ } v4; -+ struct { -+ struct in6_addr addr; -+ __be16 port; -+ __u8 mac[8]; -+ } v6; -+ } u; -+} __attribute__((__packed__)); -+ -+struct mp_remove_addr { -+ __u8 kind; -+ __u8 len; -+#if defined(__LITTLE_ENDIAN_BITFIELD) -+ __u8 rsv:4, -+ sub:4; -+#elif defined(__BIG_ENDIAN_BITFIELD) -+ __u8 sub:4, -+ rsv:4; -+#else -+#error "Adjust your defines" -+#endif -+ /* list of addr_id */ -+ __u8 addrs_id; -+}; -+ -+struct mp_fail { -+ __u8 kind; -+ __u8 len; -+#if defined(__LITTLE_ENDIAN_BITFIELD) -+ __u16 rsv1:4, -+ sub:4, -+ rsv2:8; -+#elif defined(__BIG_ENDIAN_BITFIELD) -+ __u16 sub:4, -+ rsv1:4, -+ rsv2:8; -+#else -+#error "Adjust your defines" -+#endif -+ __be64 data_seq; -+} __attribute__((__packed__)); -+ -+struct mp_fclose { -+ __u8 kind; -+ __u8 len; -+#if defined(__LITTLE_ENDIAN_BITFIELD) -+ __u16 rsv1:4, -+ sub:4, -+ rsv2:8; -+#elif defined(__BIG_ENDIAN_BITFIELD) -+ __u16 sub:4, -+ rsv1:4, -+ rsv2:8; -+#else -+#error "Adjust your defines" -+#endif -+ __u64 key; -+} __attribute__((__packed__)); -+ -+struct mp_prio { -+ __u8 kind; -+ __u8 len; -+#if defined(__LITTLE_ENDIAN_BITFIELD) -+ __u8 b:1, -+ rsv:3, -+ sub:4; -+#elif defined(__BIG_ENDIAN_BITFIELD) -+ __u8 sub:4, -+ rsv:3, -+ b:1; -+#else -+#error "Adjust your defines" -+#endif -+ __u8 addr_id; -+} __attribute__((__packed__)); -+ -+static inline int mptcp_sub_len_dss(const struct mp_dss *m, const int csum) -+{ -+ return 4 + m->A * (4 + m->a * 4) + m->M * (10 + m->m * 4 + csum * 2); -+} -+ -+#define MPTCP_SYSCTL 1 -+ -+extern int sysctl_mptcp_enabled; -+extern int sysctl_mptcp_version; -+extern int sysctl_mptcp_checksum; -+extern int sysctl_mptcp_debug; -+extern int sysctl_mptcp_syn_retries; -+ -+extern struct workqueue_struct *mptcp_wq; -+ -+#define mptcp_debug(fmt, args...) \ -+ do { \ -+ if (unlikely(sysctl_mptcp_debug)) \ -+ pr_err(__FILE__ ": " fmt, ##args); \ -+ } while (0) -+ -+/* Iterates over all subflows */ -+#define mptcp_for_each_tp(mpcb, tp) \ -+ for ((tp) = (mpcb)->connection_list; (tp); (tp) = (tp)->mptcp->next) -+ -+#define mptcp_for_each_sk(mpcb, sk) \ -+ for ((sk) = (struct sock *)(mpcb)->connection_list; \ -+ sk; \ -+ sk = (struct sock *)tcp_sk(sk)->mptcp->next) -+ -+#define mptcp_for_each_sk_safe(__mpcb, __sk, __temp) \ -+ for (__sk = (struct sock *)(__mpcb)->connection_list, \ -+ __temp = __sk ? (struct sock *)tcp_sk(__sk)->mptcp->next : NULL; \ -+ __sk; \ -+ __sk = __temp, \ -+ __temp = __sk ? (struct sock *)tcp_sk(__sk)->mptcp->next : NULL) -+ -+/* Iterates over all bit set to 1 in a bitset */ -+#define mptcp_for_each_bit_set(b, i) \ -+ for (i = ffs(b) - 1; i >= 0; i = ffs(b >> (i + 1) << (i + 1)) - 1) -+ -+#define mptcp_for_each_bit_unset(b, i) \ -+ mptcp_for_each_bit_set(~b, i) -+ -+#define MPTCP_INC_STATS(net, field) SNMP_INC_STATS((net)->mptcp.mptcp_statistics, field) -+#define MPTCP_INC_STATS_BH(net, field) __SNMP_INC_STATS((net)->mptcp.mptcp_statistics, field) -+ -+enum -+{ -+ MPTCP_MIB_NUM = 0, -+ MPTCP_MIB_MPCAPABLEPASSIVE, /* Received SYN with MP_CAPABLE */ -+ MPTCP_MIB_MPCAPABLEACTIVE, /* Sent SYN with MP_CAPABLE */ -+ MPTCP_MIB_MPCAPABLEACTIVEACK, /* Received SYN/ACK with MP_CAPABLE */ -+ MPTCP_MIB_MPCAPABLEPASSIVEACK, /* Received third ACK with MP_CAPABLE */ -+ MPTCP_MIB_MPCAPABLEPASSIVEFALLBACK,/* Server-side fallback during 3-way handshake */ -+ MPTCP_MIB_MPCAPABLEACTIVEFALLBACK, /* Client-side fallback during 3-way handshake */ -+ MPTCP_MIB_MPCAPABLERETRANSFALLBACK,/* Client-side stopped sending MP_CAPABLE after too many SYN-retransmissions */ -+ MPTCP_MIB_CSUMENABLED, /* Created MPTCP-connection with DSS-checksum enabled */ -+ MPTCP_MIB_RETRANSSEGS, /* Segments retransmitted at the MPTCP-level */ -+ MPTCP_MIB_MPFAILRX, /* Received an MP_FAIL */ -+ MPTCP_MIB_CSUMFAIL, /* Received segment with invalid checksum */ -+ MPTCP_MIB_FASTCLOSERX, /* Recevied a FAST_CLOSE */ -+ MPTCP_MIB_FASTCLOSETX, /* Sent a FAST_CLOSE */ -+ MPTCP_MIB_FBACKSUB, /* Fallback upon ack without data-ack on new subflow */ -+ MPTCP_MIB_FBACKINIT, /* Fallback upon ack without data-ack on initial subflow */ -+ MPTCP_MIB_FBDATASUB, /* Fallback upon data without DSS at the beginning on new subflow */ -+ MPTCP_MIB_FBDATAINIT, /* Fallback upon data without DSS at the beginning on initial subflow */ -+ MPTCP_MIB_REMADDRSUB, /* Remove subflow due to REMOVE_ADDR */ -+ MPTCP_MIB_JOINNOTOKEN, /* Received MP_JOIN but the token was not found */ -+ MPTCP_MIB_JOINFALLBACK, /* Received MP_JOIN on session that has fallen back to reg. TCP */ -+ MPTCP_MIB_JOINSYNTX, /* Sent a SYN + MP_JOIN */ -+ MPTCP_MIB_JOINSYNRX, /* Received a SYN + MP_JOIN */ -+ MPTCP_MIB_JOINSYNACKRX, /* Received a SYN/ACK + MP_JOIN */ -+ MPTCP_MIB_JOINSYNACKMAC, /* HMAC was wrong on SYN/ACK + MP_JOIN */ -+ MPTCP_MIB_JOINACKRX, /* Received an ACK + MP_JOIN */ -+ MPTCP_MIB_JOINACKMAC, /* HMAC was wrong on ACK + MP_JOIN */ -+ MPTCP_MIB_JOINACKFAIL, /* Third ACK on new subflow did not contain an MP_JOIN */ -+ MPTCP_MIB_JOINACKRTO, /* Retransmission timer for third ACK + MP_JOIN timed out */ -+ MPTCP_MIB_JOINACKRXMIT, /* Retransmitted an ACK + MP_JOIN */ -+ MPTCP_MIB_NODSSWINDOW, /* Received too many packets without a DSS-option */ -+ MPTCP_MIB_DSSNOMATCH, /* Received a new mapping that did not match the previous one */ -+ MPTCP_MIB_INFINITEMAPRX, /* Received an infinite mapping */ -+ MPTCP_MIB_DSSTCPMISMATCH, /* DSS-mapping did not map with TCP's sequence numbers */ -+ MPTCP_MIB_DSSTRIMHEAD, /* Trimmed segment at the head (coalescing middlebox) */ -+ MPTCP_MIB_DSSSPLITTAIL, /* Trimmed segment at the tail (coalescing middlebox) */ -+ MPTCP_MIB_PURGEOLD, /* Removed old skb from the rcv-queue due to missing DSS-mapping */ -+ MPTCP_MIB_ADDADDRRX, /* Received an ADD_ADDR */ -+ MPTCP_MIB_ADDADDRTX, /* Sent an ADD_ADDR */ -+ MPTCP_MIB_REMADDRRX, /* Received a REMOVE_ADDR */ -+ MPTCP_MIB_REMADDRTX, /* Sent a REMOVE_ADDR */ -+ __MPTCP_MIB_MAX -+}; -+ -+#define MPTCP_MIB_MAX __MPTCP_MIB_MAX -+struct mptcp_mib { -+ unsigned long mibs[MPTCP_MIB_MAX]; -+}; -+ -+extern struct lock_class_key meta_key; -+extern char *meta_key_name; -+extern struct lock_class_key meta_slock_key; -+extern char *meta_slock_key_name; -+ -+extern u32 mptcp_secret[MD5_MESSAGE_BYTES / 4]; -+ -+/* This is needed to ensure that two subsequent key/nonce-generation result in -+ * different keys/nonces if the IPs and ports are the same. -+ */ -+extern u32 mptcp_seed; -+ -+#define MPTCP_HASH_SIZE 1024 -+ -+extern struct hlist_nulls_head tk_hashtable[MPTCP_HASH_SIZE]; -+ -+/* Request-sockets can be hashed in the tk_htb for collision-detection or in -+ * the regular htb for join-connections. We need to define different NULLS -+ * values so that we can correctly detect a request-socket that has been -+ * recycled. See also c25eb3bfb9729. -+ */ -+#define MPTCP_REQSK_NULLS_BASE (1U << 29) -+ -+ -+void mptcp_data_ready(struct sock *sk); -+void mptcp_write_space(struct sock *sk); -+ -+void mptcp_add_meta_ofo_queue(const struct sock *meta_sk, struct sk_buff *skb, -+ struct sock *sk); -+void mptcp_cleanup_rbuf(struct sock *meta_sk, int copied); -+int mptcp_add_sock(struct sock *meta_sk, struct sock *sk, u8 loc_id, u8 rem_id, -+ gfp_t flags); -+void mptcp_del_sock(struct sock *sk); -+void mptcp_update_metasocket(const struct sock *meta_sk); -+void mptcp_reinject_data(struct sock *orig_sk, int clone_it); -+void mptcp_update_sndbuf(const struct tcp_sock *tp); -+void mptcp_send_fin(struct sock *meta_sk); -+void mptcp_send_active_reset(struct sock *meta_sk, gfp_t priority); -+bool mptcp_write_xmit(struct sock *sk, unsigned int mss_now, int nonagle, -+ int push_one, gfp_t gfp); -+void tcp_parse_mptcp_options(const struct sk_buff *skb, -+ struct mptcp_options_received *mopt); -+void mptcp_parse_options(const uint8_t *ptr, int opsize, -+ struct mptcp_options_received *mopt, -+ const struct sk_buff *skb, -+ struct tcp_sock *tp); -+void mptcp_syn_options(const struct sock *sk, struct tcp_out_options *opts, -+ unsigned *remaining); -+void mptcp_synack_options(struct request_sock *req, -+ struct tcp_out_options *opts, -+ unsigned *remaining); -+void mptcp_established_options(struct sock *sk, struct sk_buff *skb, -+ struct tcp_out_options *opts, unsigned *size); -+void mptcp_options_write(__be32 *ptr, struct tcp_sock *tp, -+ const struct tcp_out_options *opts, -+ struct sk_buff *skb); -+void mptcp_close(struct sock *meta_sk, long timeout); -+int mptcp_doit(struct sock *sk); -+int mptcp_create_master_sk(struct sock *meta_sk, __u64 remote_key, -+ __u8 mptcp_ver, u32 window); -+int mptcp_check_req_fastopen(struct sock *child, struct request_sock *req); -+int mptcp_check_req_master(struct sock *sk, struct sock *child, -+ struct request_sock *req, const struct sk_buff *skb, -+ int drop); -+struct sock *mptcp_check_req_child(struct sock *meta_sk, -+ struct sock *child, -+ struct request_sock *req, -+ struct sk_buff *skb, -+ const struct mptcp_options_received *mopt); -+u32 __mptcp_select_window(struct sock *sk); -+void mptcp_select_initial_window(int __space, __u32 mss, __u32 *rcv_wnd, -+ __u32 *window_clamp, int wscale_ok, -+ __u8 *rcv_wscale, __u32 init_rcv_wnd, -+ const struct sock *sk); -+unsigned int mptcp_current_mss(struct sock *meta_sk); -+int mptcp_select_size(const struct sock *meta_sk, bool sg, bool first_skb); -+void mptcp_key_sha1(u64 key, u32 *token, u64 *idsn); -+void mptcp_hmac_sha1(const u8 *key_1, const u8 *key_2, u32 *hash_out, -+ int arg_num, ...); -+void mptcp_clean_rtx_infinite(const struct sk_buff *skb, struct sock *sk); -+void mptcp_fin(struct sock *meta_sk); -+void mptcp_meta_retransmit_timer(struct sock *meta_sk); -+void mptcp_sub_retransmit_timer(struct sock *sk); -+int mptcp_write_wakeup(struct sock *meta_sk, int mib); -+void mptcp_sub_close_wq(struct work_struct *work); -+void mptcp_sub_close(struct sock *sk, unsigned long delay); -+struct sock *mptcp_select_ack_sock(const struct sock *meta_sk); -+void mptcp_prepare_for_backlog(struct sock *sk, struct sk_buff *skb); -+int mptcp_backlog_rcv(struct sock *meta_sk, struct sk_buff *skb); -+void mptcp_ack_handler(unsigned long); -+bool mptcp_check_rtt(const struct tcp_sock *tp, int time); -+int mptcp_check_snd_buf(const struct tcp_sock *tp); -+bool mptcp_handle_options(struct sock *sk, const struct tcphdr *th, -+ const struct sk_buff *skb); -+void __init mptcp_init(void); -+void mptcp_destroy_sock(struct sock *sk); -+int mptcp_rcv_synsent_state_process(struct sock *sk, struct sock **skptr, -+ const struct sk_buff *skb, -+ const struct mptcp_options_received *mopt); -+unsigned int mptcp_xmit_size_goal(const struct sock *meta_sk, u32 mss_now, -+ int large_allowed); -+int mptcp_init_tw_sock(struct sock *sk, struct tcp_timewait_sock *tw); -+void mptcp_twsk_destructor(struct tcp_timewait_sock *tw); -+void mptcp_time_wait(struct sock *sk, int state, int timeo); -+void mptcp_disconnect(struct sock *meta_sk); -+bool mptcp_should_expand_sndbuf(const struct sock *sk); -+int mptcp_retransmit_skb(struct sock *meta_sk, struct sk_buff *skb); -+void mptcp_tsq_flags(struct sock *sk); -+void mptcp_tsq_sub_deferred(struct sock *meta_sk); -+struct mp_join *mptcp_find_join(const struct sk_buff *skb); -+void mptcp_hash_remove_bh(struct tcp_sock *meta_tp); -+struct sock *mptcp_hash_find(const struct net *net, const u32 token); -+int mptcp_lookup_join(struct sk_buff *skb, struct inet_timewait_sock *tw); -+int mptcp_do_join_short(struct sk_buff *skb, -+ const struct mptcp_options_received *mopt, -+ struct net *net); -+void mptcp_reqsk_destructor(struct request_sock *req); -+void mptcp_connect_init(struct sock *sk); -+void mptcp_sub_force_close(struct sock *sk); -+int mptcp_sub_len_remove_addr_align(u16 bitfield); -+void mptcp_init_buffer_space(struct sock *sk); -+void mptcp_join_reqsk_init(const struct mptcp_cb *mpcb, -+ const struct request_sock *req, -+ struct sk_buff *skb); -+void mptcp_reqsk_init(struct request_sock *req, const struct sock *sk, -+ const struct sk_buff *skb, bool want_cookie); -+int mptcp_conn_request(struct sock *sk, struct sk_buff *skb); -+void mptcp_enable_sock(struct sock *sk); -+void mptcp_disable_sock(struct sock *sk); -+void mptcp_disable_static_key(void); -+void mptcp_cookies_reqsk_init(struct request_sock *req, -+ struct mptcp_options_received *mopt, -+ struct sk_buff *skb); -+void mptcp_sock_destruct(struct sock *sk); -+int mptcp_finish_handshake(struct sock *child, struct sk_buff *skb); -+int mptcp_get_info(const struct sock *meta_sk, char __user *optval, int optlen); -+void mptcp_clear_sk(struct sock *sk, int size); -+ -+/* MPTCP-path-manager registration/initialization functions */ -+int mptcp_register_path_manager(struct mptcp_pm_ops *pm); -+void mptcp_unregister_path_manager(struct mptcp_pm_ops *pm); -+void mptcp_init_path_manager(struct mptcp_cb *mpcb); -+void mptcp_cleanup_path_manager(struct mptcp_cb *mpcb); -+void mptcp_fallback_default(struct mptcp_cb *mpcb); -+void mptcp_get_default_path_manager(char *name); -+int mptcp_set_scheduler(struct sock *sk, const char *name); -+int mptcp_set_path_manager(struct sock *sk, const char *name); -+int mptcp_set_default_path_manager(const char *name); -+extern struct mptcp_pm_ops mptcp_pm_default; -+ -+/* MPTCP-scheduler registration/initialization functions */ -+int mptcp_register_scheduler(struct mptcp_sched_ops *sched); -+void mptcp_unregister_scheduler(struct mptcp_sched_ops *sched); -+void mptcp_init_scheduler(struct mptcp_cb *mpcb); -+void mptcp_cleanup_scheduler(struct mptcp_cb *mpcb); -+void mptcp_get_default_scheduler(char *name); -+int mptcp_set_default_scheduler(const char *name); -+bool mptcp_is_available(struct sock *sk, const struct sk_buff *skb, -+ bool zero_wnd_test); -+bool mptcp_is_def_unavailable(struct sock *sk); -+bool subflow_is_active(const struct tcp_sock *tp); -+bool subflow_is_backup(const struct tcp_sock *tp); -+struct sock *get_available_subflow(struct sock *meta_sk, struct sk_buff *skb, -+ bool zero_wnd_test); -+extern struct mptcp_sched_ops mptcp_sched_default; -+ -+/* Initializes function-pointers and MPTCP-flags */ -+static inline void mptcp_init_tcp_sock(struct sock *sk) -+{ -+ if (!mptcp_init_failed && sysctl_mptcp_enabled == MPTCP_SYSCTL) -+ mptcp_enable_sock(sk); -+} -+ -+static inline int mptcp_pi_to_flag(int pi) -+{ -+ return 1 << (pi - 1); -+} -+ -+static inline -+struct mptcp_request_sock *mptcp_rsk(const struct request_sock *req) -+{ -+ return (struct mptcp_request_sock *)req; -+} -+ -+static inline -+struct request_sock *rev_mptcp_rsk(const struct mptcp_request_sock *req) -+{ -+ return (struct request_sock *)req; -+} -+ -+static inline bool mptcp_can_sendpage(struct sock *sk) -+{ -+ struct sock *sk_it; -+ -+ if (tcp_sk(sk)->mpcb->dss_csum) -+ return false; -+ -+ mptcp_for_each_sk(tcp_sk(sk)->mpcb, sk_it) { -+ if (!(sk_it->sk_route_caps & NETIF_F_SG) || -+ !sk_check_csum_caps(sk_it)) -+ return false; -+ } -+ -+ return true; -+} -+ -+static inline void mptcp_push_pending_frames(struct sock *meta_sk) -+{ -+ /* We check packets out and send-head here. TCP only checks the -+ * send-head. But, MPTCP also checks packets_out, as this is an -+ * indication that we might want to do opportunistic reinjection. -+ */ -+ if (tcp_sk(meta_sk)->packets_out || tcp_send_head(meta_sk)) { -+ struct tcp_sock *tp = tcp_sk(meta_sk); -+ -+ /* We don't care about the MSS, because it will be set in -+ * mptcp_write_xmit. -+ */ -+ __tcp_push_pending_frames(meta_sk, 0, tp->nonagle); -+ } -+} -+ -+static inline void mptcp_send_reset(struct sock *sk) -+{ -+ if (tcp_need_reset(sk->sk_state)) -+ tcp_sk(sk)->ops->send_active_reset(sk, GFP_ATOMIC); -+ mptcp_sub_force_close(sk); -+} -+ -+static inline void mptcp_sub_force_close_all(struct mptcp_cb *mpcb, -+ struct sock *except) -+{ -+ struct sock *sk_it, *tmp; -+ -+ mptcp_for_each_sk_safe(mpcb, sk_it, tmp) { -+ if (sk_it != except) -+ mptcp_send_reset(sk_it); -+ } -+} -+ -+static inline bool mptcp_is_data_seq(const struct sk_buff *skb) -+{ -+ return TCP_SKB_CB(skb)->mptcp_flags & MPTCPHDR_SEQ; -+} -+ -+static inline bool mptcp_is_data_fin(const struct sk_buff *skb) -+{ -+ return TCP_SKB_CB(skb)->mptcp_flags & MPTCPHDR_FIN; -+} -+ -+/* Is it a data-fin while in infinite mapping mode? -+ * In infinite mode, a subflow-fin is in fact a data-fin. -+ */ -+static inline bool mptcp_is_data_fin2(const struct sk_buff *skb, -+ const struct tcp_sock *tp) -+{ -+ return mptcp_is_data_fin(skb) || -+ (tp->mpcb->infinite_mapping_rcv && -+ (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN)); -+} -+ -+static inline u8 mptcp_get_64_bit(u64 data_seq, struct mptcp_cb *mpcb) -+{ -+ u64 data_seq_high = (u32)(data_seq >> 32); -+ -+ if (mpcb->rcv_high_order[0] == data_seq_high) -+ return 0; -+ else if (mpcb->rcv_high_order[1] == data_seq_high) -+ return MPTCPHDR_SEQ64_INDEX; -+ else -+ return MPTCPHDR_SEQ64_OFO; -+} -+ -+/* Sets the data_seq and returns pointer to the in-skb field of the data_seq. -+ * If the packet has a 64-bit dseq, the pointer points to the last 32 bits. -+ */ -+static inline __u32 *mptcp_skb_set_data_seq(const struct sk_buff *skb, -+ u32 *data_seq, -+ struct mptcp_cb *mpcb) -+{ -+ __u32 *ptr = (__u32 *)(skb_transport_header(skb) + TCP_SKB_CB(skb)->dss_off); -+ -+ if (TCP_SKB_CB(skb)->mptcp_flags & MPTCPHDR_SEQ64_SET) { -+ u64 data_seq64 = get_unaligned_be64(ptr); -+ -+ if (mpcb) -+ TCP_SKB_CB(skb)->mptcp_flags |= mptcp_get_64_bit(data_seq64, mpcb); -+ -+ *data_seq = (u32)data_seq64; -+ ptr++; -+ } else { -+ *data_seq = get_unaligned_be32(ptr); -+ } -+ -+ return ptr; -+} -+ -+static inline struct sock *mptcp_meta_sk(const struct sock *sk) -+{ -+ return tcp_sk(sk)->meta_sk; -+} -+ -+static inline struct tcp_sock *mptcp_meta_tp(const struct tcp_sock *tp) -+{ -+ return tcp_sk(tp->meta_sk); -+} -+ -+static inline int is_meta_tp(const struct tcp_sock *tp) -+{ -+ return tp->mpcb && mptcp_meta_tp(tp) == tp; -+} -+ -+static inline int is_meta_sk(const struct sock *sk) -+{ -+ return sk->sk_state != TCP_NEW_SYN_RECV && -+ sk->sk_type == SOCK_STREAM && sk->sk_protocol == IPPROTO_TCP && -+ mptcp(tcp_sk(sk)) && mptcp_meta_sk(sk) == sk; -+} -+ -+static inline int is_master_tp(const struct tcp_sock *tp) -+{ -+ return !mptcp(tp) || (!tp->mptcp->slave_sk && !is_meta_tp(tp)); -+} -+ -+static inline void mptcp_init_mp_opt(struct mptcp_options_received *mopt) -+{ -+ mopt->saw_mpc = 0; -+ mopt->dss_csum = 0; -+ mopt->drop_me = 0; -+ -+ mopt->is_mp_join = 0; -+ mopt->join_ack = 0; -+ -+ mopt->saw_low_prio = 0; -+ mopt->low_prio = 0; -+ -+ mopt->saw_add_addr = 0; -+ mopt->more_add_addr = 0; -+ -+ mopt->saw_rem_addr = 0; -+ mopt->more_rem_addr = 0; -+ -+ mopt->mp_fail = 0; -+ mopt->mp_fclose = 0; -+} -+ -+static inline void mptcp_reset_mopt(struct tcp_sock *tp) -+{ -+ struct mptcp_options_received *mopt = &tp->mptcp->rx_opt; -+ -+ mopt->saw_low_prio = 0; -+ mopt->saw_add_addr = 0; -+ mopt->more_add_addr = 0; -+ mopt->saw_rem_addr = 0; -+ mopt->more_rem_addr = 0; -+ mopt->join_ack = 0; -+ mopt->mp_fail = 0; -+ mopt->mp_fclose = 0; -+} -+ -+static inline __be32 mptcp_get_highorder_sndbits(const struct sk_buff *skb, -+ const struct mptcp_cb *mpcb) -+{ -+ return htonl(mpcb->snd_high_order[(TCP_SKB_CB(skb)->mptcp_flags & -+ MPTCPHDR_SEQ64_INDEX) ? 1 : 0]); -+} -+ -+static inline u64 mptcp_get_data_seq_64(const struct mptcp_cb *mpcb, int index, -+ u32 data_seq_32) -+{ -+ return ((u64)mpcb->rcv_high_order[index] << 32) | data_seq_32; -+} -+ -+static inline u64 mptcp_get_rcv_nxt_64(const struct tcp_sock *meta_tp) -+{ -+ struct mptcp_cb *mpcb = meta_tp->mpcb; -+ return mptcp_get_data_seq_64(mpcb, mpcb->rcv_hiseq_index, -+ meta_tp->rcv_nxt); -+} -+ -+static inline void mptcp_check_sndseq_wrap(struct tcp_sock *meta_tp, int inc) -+{ -+ if (unlikely(meta_tp->snd_nxt > meta_tp->snd_nxt + inc)) { -+ struct mptcp_cb *mpcb = meta_tp->mpcb; -+ mpcb->snd_hiseq_index = mpcb->snd_hiseq_index ? 0 : 1; -+ mpcb->snd_high_order[mpcb->snd_hiseq_index] += 2; -+ } -+} -+ -+static inline void mptcp_check_rcvseq_wrap(struct tcp_sock *meta_tp, -+ u32 old_rcv_nxt) -+{ -+ if (unlikely(old_rcv_nxt > meta_tp->rcv_nxt)) { -+ struct mptcp_cb *mpcb = meta_tp->mpcb; -+ mpcb->rcv_high_order[mpcb->rcv_hiseq_index] += 2; -+ mpcb->rcv_hiseq_index = mpcb->rcv_hiseq_index ? 0 : 1; -+ } -+} -+ -+static inline int mptcp_sk_can_send(const struct sock *sk) -+{ -+ return tcp_passive_fastopen(sk) || -+ ((1 << sk->sk_state) & (TCPF_ESTABLISHED | TCPF_CLOSE_WAIT) && -+ !tcp_sk(sk)->mptcp->pre_established); -+} -+ -+static inline int mptcp_sk_can_recv(const struct sock *sk) -+{ -+ return (1 << sk->sk_state) & (TCPF_ESTABLISHED | TCPF_FIN_WAIT1 | TCPF_FIN_WAIT2); -+} -+ -+static inline int mptcp_sk_can_send_ack(const struct sock *sk) -+{ -+ return !((1 << sk->sk_state) & (TCPF_SYN_SENT | TCPF_SYN_RECV | -+ TCPF_CLOSE | TCPF_LISTEN)) && -+ !tcp_sk(sk)->mptcp->pre_established; -+} -+ -+/* Only support GSO if all subflows supports it */ -+static inline bool mptcp_sk_can_gso(const struct sock *meta_sk) -+{ -+ struct sock *sk; -+ -+ if (tcp_sk(meta_sk)->mpcb->dss_csum) -+ return false; -+ -+ mptcp_for_each_sk(tcp_sk(meta_sk)->mpcb, sk) { -+ if (!mptcp_sk_can_send(sk)) -+ continue; -+ if (!sk_can_gso(sk)) -+ return false; -+ } -+ return true; -+} -+ -+static inline bool mptcp_can_sg(const struct sock *meta_sk) -+{ -+ struct sock *sk; -+ -+ if (tcp_sk(meta_sk)->mpcb->dss_csum) -+ return false; -+ -+ mptcp_for_each_sk(tcp_sk(meta_sk)->mpcb, sk) { -+ if (!mptcp_sk_can_send(sk)) -+ continue; -+ if (!(sk->sk_route_caps & NETIF_F_SG)) -+ return false; -+ } -+ return true; -+} -+ -+static inline void mptcp_set_rto(struct sock *sk) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct sock *sk_it; -+ struct inet_connection_sock *micsk = inet_csk(mptcp_meta_sk(sk)); -+ __u32 max_rto = 0; -+ -+ /* We are in recovery-phase on the MPTCP-level. Do not update the -+ * RTO, because this would kill exponential backoff. -+ */ -+ if (micsk->icsk_retransmits) -+ return; -+ -+ mptcp_for_each_sk(tp->mpcb, sk_it) { -+ if ((mptcp_sk_can_send(sk_it) || sk_it->sk_state == TCP_SYN_RECV) && -+ inet_csk(sk_it)->icsk_retransmits == 0 && -+ inet_csk(sk_it)->icsk_rto > max_rto) -+ max_rto = inet_csk(sk_it)->icsk_rto; -+ } -+ if (max_rto) { -+ micsk->icsk_rto = max_rto << 1; -+ -+ /* A successfull rto-measurement - reset backoff counter */ -+ micsk->icsk_backoff = 0; -+ } -+} -+ -+static inline void mptcp_sub_close_passive(struct sock *sk) -+{ -+ struct sock *meta_sk = mptcp_meta_sk(sk); -+ struct tcp_sock *tp = tcp_sk(sk), *meta_tp = tcp_sk(meta_sk); -+ -+ /* Only close, if the app did a send-shutdown (passive close), and we -+ * received the data-ack of the data-fin. -+ */ -+ if (tp->mpcb->passive_close && meta_tp->snd_una == meta_tp->write_seq) -+ mptcp_sub_close(sk, 0); -+} -+ -+static inline bool mptcp_fallback_infinite(struct sock *sk, int flag) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct mptcp_cb *mpcb = tp->mpcb; -+ -+ /* If data has been acknowleged on the meta-level, fully_established -+ * will have been set before and thus we will not fall back to infinite -+ * mapping. -+ */ -+ if (likely(tp->mptcp->fully_established)) -+ return false; -+ -+ if (!(flag & MPTCP_FLAG_DATA_ACKED)) -+ return false; -+ -+ /* Don't fallback twice ;) */ -+ if (mpcb->infinite_mapping_snd) -+ return false; -+ -+ pr_err("%s %#x will fallback - pi %d, src %pI4:%u dst %pI4:%u rcv_nxt %u from %pS\n", -+ __func__, mpcb->mptcp_loc_token, tp->mptcp->path_index, -+ &inet_sk(sk)->inet_saddr, ntohs(inet_sk(sk)->inet_sport), -+ &inet_sk(sk)->inet_daddr, ntohs(inet_sk(sk)->inet_dport), -+ tp->rcv_nxt, __builtin_return_address(0)); -+ if (!is_master_tp(tp)) { -+ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_FBACKSUB); -+ return true; -+ } -+ -+ mpcb->infinite_mapping_snd = 1; -+ mpcb->infinite_mapping_rcv = 1; -+ mpcb->infinite_rcv_seq = mptcp_get_rcv_nxt_64(mptcp_meta_tp(tp)); -+ tp->mptcp->fully_established = 1; -+ -+ mptcp_sub_force_close_all(mpcb, sk); -+ -+ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_FBACKINIT); -+ -+ return false; -+} -+ -+/* Find the first index whose bit in the bit-field == 0 */ -+static inline u8 mptcp_set_new_pathindex(struct mptcp_cb *mpcb) -+{ -+ u8 base = mpcb->next_path_index; -+ int i; -+ -+ /* Start at 1, because 0 is reserved for the meta-sk */ -+ mptcp_for_each_bit_unset(mpcb->path_index_bits >> base, i) { -+ if (i + base < 1) -+ continue; -+ if (i + base >= sizeof(mpcb->path_index_bits) * 8) -+ break; -+ i += base; -+ mpcb->path_index_bits |= (1 << i); -+ mpcb->next_path_index = i + 1; -+ return i; -+ } -+ mptcp_for_each_bit_unset(mpcb->path_index_bits, i) { -+ if (i >= sizeof(mpcb->path_index_bits) * 8) -+ break; -+ if (i < 1) -+ continue; -+ mpcb->path_index_bits |= (1 << i); -+ mpcb->next_path_index = i + 1; -+ return i; -+ } -+ -+ return 0; -+} -+ -+static inline bool mptcp_v6_is_v4_mapped(const struct sock *sk) -+{ -+ return sk->sk_family == AF_INET6 && -+ ipv6_addr_type(&inet6_sk(sk)->saddr) == IPV6_ADDR_MAPPED; -+} -+ -+static inline bool mptcp_can_new_subflow(const struct sock *meta_sk) -+{ -+ /* Has been removed from the tk-table. Thus, no new subflows. -+ * -+ * Check for close-state is necessary, because we may have been closed -+ * without passing by mptcp_close(). -+ * -+ * When falling back, no new subflows are allowed either. -+ */ -+ return meta_sk->sk_state != TCP_CLOSE && -+ tcp_sk(meta_sk)->inside_tk_table && -+ !tcp_sk(meta_sk)->mpcb->infinite_mapping_rcv && -+ !tcp_sk(meta_sk)->mpcb->send_infinite_mapping; -+} -+ -+/* TCP and MPTCP mpc flag-depending functions */ -+u16 mptcp_select_window(struct sock *sk); -+void mptcp_init_buffer_space(struct sock *sk); -+void mptcp_tcp_set_rto(struct sock *sk); -+ -+/* TCP and MPTCP flag-depending functions */ -+bool mptcp_prune_ofo_queue(struct sock *sk); -+ -+#else /* CONFIG_MPTCP */ -+#define mptcp_debug(fmt, args...) \ -+ do { \ -+ } while (0) -+ -+/* Without MPTCP, we just do one iteration -+ * over the only socket available. This assumes that -+ * the sk/tp arg is the socket in that case. -+ */ -+#define mptcp_for_each_sk(mpcb, sk) -+#define mptcp_for_each_sk_safe(__mpcb, __sk, __temp) -+ -+#define MPTCP_INC_STATS(net, field) \ -+ do { \ -+ } while(0) -+ -+static inline bool mptcp_is_data_fin(const struct sk_buff *skb) -+{ -+ return false; -+} -+static inline bool mptcp_is_data_seq(const struct sk_buff *skb) -+{ -+ return false; -+} -+static inline struct sock *mptcp_meta_sk(const struct sock *sk) -+{ -+ return NULL; -+} -+static inline struct tcp_sock *mptcp_meta_tp(const struct tcp_sock *tp) -+{ -+ return NULL; -+} -+static inline int is_meta_sk(const struct sock *sk) -+{ -+ return 0; -+} -+static inline int is_master_tp(const struct tcp_sock *tp) -+{ -+ return 0; -+} -+static inline void mptcp_del_sock(const struct sock *sk) {} -+static inline void mptcp_update_metasocket(const struct sock *meta_sk) {} -+static inline void mptcp_reinject_data(struct sock *orig_sk, int clone_it) {} -+static inline void mptcp_update_sndbuf(const struct tcp_sock *tp) {} -+static inline void mptcp_clean_rtx_infinite(const struct sk_buff *skb, -+ const struct sock *sk) {} -+static inline void mptcp_sub_close(struct sock *sk, unsigned long delay) {} -+static inline void mptcp_set_rto(const struct sock *sk) {} -+static inline void mptcp_send_fin(const struct sock *meta_sk) {} -+static inline void mptcp_parse_options(const uint8_t *ptr, const int opsize, -+ struct mptcp_options_received *mopt, -+ const struct sk_buff *skb, -+ const struct tcp_sock *tp) {} -+static inline void mptcp_syn_options(const struct sock *sk, -+ struct tcp_out_options *opts, -+ unsigned *remaining) {} -+static inline void mptcp_synack_options(struct request_sock *req, -+ struct tcp_out_options *opts, -+ unsigned *remaining) {} -+ -+static inline void mptcp_established_options(struct sock *sk, -+ struct sk_buff *skb, -+ struct tcp_out_options *opts, -+ unsigned *size) {} -+static inline void mptcp_options_write(__be32 *ptr, struct tcp_sock *tp, -+ const struct tcp_out_options *opts, -+ struct sk_buff *skb) {} -+static inline void mptcp_close(struct sock *meta_sk, long timeout) {} -+static inline int mptcp_doit(struct sock *sk) -+{ -+ return 0; -+} -+static inline int mptcp_check_req_fastopen(struct sock *child, -+ struct request_sock *req) -+{ -+ return 1; -+} -+static inline int mptcp_check_req_master(const struct sock *sk, -+ const struct sock *child, -+ const struct request_sock *req, -+ const struct sk_buff *skb, -+ int drop) -+{ -+ return 1; -+} -+static inline struct sock *mptcp_check_req_child(const struct sock *meta_sk, -+ const struct sock *child, -+ const struct request_sock *req, -+ struct sk_buff *skb, -+ const struct mptcp_options_received *mopt) -+{ -+ return NULL; -+} -+static inline unsigned int mptcp_current_mss(struct sock *meta_sk) -+{ -+ return 0; -+} -+static inline void mptcp_sub_close_passive(struct sock *sk) {} -+static inline bool mptcp_fallback_infinite(const struct sock *sk, int flag) -+{ -+ return false; -+} -+static inline void mptcp_init_mp_opt(const struct mptcp_options_received *mopt) {} -+static inline void mptcp_prepare_for_backlog(struct sock *sk, struct sk_buff *skb) {} -+static inline bool mptcp_check_rtt(const struct tcp_sock *tp, int time) -+{ -+ return false; -+} -+static inline int mptcp_check_snd_buf(const struct tcp_sock *tp) -+{ -+ return 0; -+} -+static inline void mptcp_send_reset(const struct sock *sk) {} -+static inline bool mptcp_handle_options(struct sock *sk, -+ const struct tcphdr *th, -+ struct sk_buff *skb) -+{ -+ return false; -+} -+static inline void mptcp_reset_mopt(struct tcp_sock *tp) {} -+static inline void __init mptcp_init(void) {} -+static inline bool mptcp_sk_can_gso(const struct sock *sk) -+{ -+ return false; -+} -+static inline bool mptcp_can_sg(const struct sock *meta_sk) -+{ -+ return false; -+} -+static inline unsigned int mptcp_xmit_size_goal(const struct sock *meta_sk, -+ u32 mss_now, int large_allowed) -+{ -+ return 0; -+} -+static inline void mptcp_destroy_sock(struct sock *sk) {} -+static inline int mptcp_rcv_synsent_state_process(struct sock *sk, -+ struct sock **skptr, -+ struct sk_buff *skb, -+ const struct mptcp_options_received *mopt) -+{ -+ return 0; -+} -+static inline bool mptcp_can_sendpage(struct sock *sk) -+{ -+ return false; -+} -+static inline int mptcp_init_tw_sock(struct sock *sk, -+ struct tcp_timewait_sock *tw) -+{ -+ return 0; -+} -+static inline void mptcp_twsk_destructor(struct tcp_timewait_sock *tw) {} -+static inline void mptcp_disconnect(struct sock *meta_sk) {} -+static inline void mptcp_tsq_flags(struct sock *sk) {} -+static inline void mptcp_tsq_sub_deferred(struct sock *meta_sk) {} -+static inline void mptcp_hash_remove_bh(struct tcp_sock *meta_tp) {} -+static inline void mptcp_remove_shortcuts(const struct mptcp_cb *mpcb, -+ const struct sk_buff *skb) {} -+static inline void mptcp_init_tcp_sock(struct sock *sk) {} -+static inline void mptcp_disable_static_key(void) {} -+static inline void mptcp_cookies_reqsk_init(struct request_sock *req, -+ struct mptcp_options_received *mopt, -+ struct sk_buff *skb) {} -+static inline void mptcp_fin(struct sock *meta_sk) {} -+static inline bool mptcp_can_new_subflow(const struct sock *meta_sk) -+{ -+ return false; -+} -+ -+#endif /* CONFIG_MPTCP */ -+ -+#endif /* _MPTCP_H */ -diff -aurN linux-4.9.162/include/net/mptcp_v4.h mptcp-mptcp_v0.93/include/net/mptcp_v4.h ---- linux-4.9.162/include/net/mptcp_v4.h 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_v0.93/include/net/mptcp_v4.h 2019-03-14 14:02:32.000000000 +0100 -@@ -0,0 +1,68 @@ -+/* -+ * MPTCP implementation -+ * -+ * Initial Design & Implementation: -+ * Sébastien Barré -+ * -+ * Current Maintainer & Author: -+ * Christoph Paasch -+ * -+ * Additional authors: -+ * Jaakko Korkeaniemi -+ * Gregory Detal -+ * Fabien Duchêne -+ * Andreas Seelinger -+ * Lavkesh Lahngir -+ * Andreas Ripke -+ * Vlad Dogaru -+ * Octavian Purdila -+ * John Ronan -+ * Catalin Nicutar -+ * Brandon Heller -+ * -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version -+ * 2 of the License, or (at your option) any later version. -+ */ -+ -+#ifndef MPTCP_V4_H_ -+#define MPTCP_V4_H_ -+ -+ -+#include -+#include -+#include -+#include -+#include -+ -+extern struct request_sock_ops mptcp_request_sock_ops; -+extern const struct inet_connection_sock_af_ops mptcp_v4_specific; -+extern struct tcp_request_sock_ops mptcp_request_sock_ipv4_ops; -+extern struct tcp_request_sock_ops mptcp_join_request_sock_ipv4_ops; -+ -+#ifdef CONFIG_MPTCP -+ -+int mptcp_v4_do_rcv(struct sock *meta_sk, struct sk_buff *skb); -+struct sock *mptcp_v4_search_req(const __be16 rport, const __be32 raddr, -+ const __be32 laddr, const struct net *net); -+int mptcp_init4_subsockets(struct sock *meta_sk, const struct mptcp_loc4 *loc, -+ struct mptcp_rem4 *rem); -+int mptcp_pm_v4_init(void); -+void mptcp_pm_v4_undo(void); -+u32 mptcp_v4_get_nonce(__be32 saddr, __be32 daddr, __be16 sport, __be16 dport); -+u64 mptcp_v4_get_key(__be32 saddr, __be32 daddr, __be16 sport, __be16 dport, -+ u32 seed); -+ -+#else -+ -+static inline int mptcp_v4_do_rcv(const struct sock *meta_sk, -+ const struct sk_buff *skb) -+{ -+ return 0; -+} -+ -+#endif /* CONFIG_MPTCP */ -+ -+#endif /* MPTCP_V4_H_ */ -diff -aurN linux-4.9.162/include/net/mptcp_v6.h mptcp-mptcp_v0.93/include/net/mptcp_v6.h ---- linux-4.9.162/include/net/mptcp_v6.h 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_v0.93/include/net/mptcp_v6.h 2019-03-14 14:02:32.000000000 +0100 -@@ -0,0 +1,69 @@ -+/* -+ * MPTCP implementation -+ * -+ * Initial Design & Implementation: -+ * Sébastien Barré -+ * -+ * Current Maintainer & Author: -+ * Jaakko Korkeaniemi -+ * -+ * Additional authors: -+ * Jaakko Korkeaniemi -+ * Gregory Detal -+ * Fabien Duchêne -+ * Andreas Seelinger -+ * Lavkesh Lahngir -+ * Andreas Ripke -+ * Vlad Dogaru -+ * Octavian Purdila -+ * John Ronan -+ * Catalin Nicutar -+ * Brandon Heller -+ * -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version -+ * 2 of the License, or (at your option) any later version. -+ */ -+ -+#ifndef _MPTCP_V6_H -+#define _MPTCP_V6_H -+ -+#include -+#include -+ -+#include -+ -+ -+#ifdef CONFIG_MPTCP -+extern const struct inet_connection_sock_af_ops mptcp_v6_mapped; -+extern const struct inet_connection_sock_af_ops mptcp_v6_specific; -+extern struct request_sock_ops mptcp6_request_sock_ops; -+extern struct tcp_request_sock_ops mptcp_request_sock_ipv6_ops; -+extern struct tcp_request_sock_ops mptcp_join_request_sock_ipv6_ops; -+ -+int mptcp_v6_do_rcv(struct sock *meta_sk, struct sk_buff *skb); -+struct sock *mptcp_v6_search_req(const __be16 rport, const struct in6_addr *raddr, -+ const struct in6_addr *laddr, const struct net *net); -+int mptcp_init6_subsockets(struct sock *meta_sk, const struct mptcp_loc6 *loc, -+ struct mptcp_rem6 *rem); -+int mptcp_pm_v6_init(void); -+void mptcp_pm_v6_undo(void); -+__u32 mptcp_v6_get_nonce(const __be32 *saddr, const __be32 *daddr, -+ __be16 sport, __be16 dport); -+u64 mptcp_v6_get_key(const __be32 *saddr, const __be32 *daddr, -+ __be16 sport, __be16 dport, u32 seed); -+ -+#else /* CONFIG_MPTCP */ -+ -+#define mptcp_v6_mapped ipv6_mapped -+ -+static inline int mptcp_v6_do_rcv(struct sock *meta_sk, struct sk_buff *skb) -+{ -+ return 0; -+} -+ -+#endif /* CONFIG_MPTCP */ -+ -+#endif /* _MPTCP_V6_H */ -diff -aurN linux-4.9.162/include/net/net_namespace.h mptcp-mptcp_v0.93/include/net/net_namespace.h ---- linux-4.9.162/include/net/net_namespace.h 2019-03-05 17:57:07.000000000 +0100 -+++ mptcp-mptcp_v0.93/include/net/net_namespace.h 2019-03-14 14:02:32.000000000 +0100 -@@ -16,6 +16,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -96,6 +97,9 @@ - #if IS_ENABLED(CONFIG_IPV6) - struct netns_ipv6 ipv6; - #endif -+#if IS_ENABLED(CONFIG_MPTCP) -+ struct netns_mptcp mptcp; -+#endif - #if IS_ENABLED(CONFIG_IEEE802154_6LOWPAN) - struct netns_ieee802154_lowpan ieee802154_lowpan; - #endif -diff -aurN linux-4.9.162/include/net/netns/mptcp.h mptcp-mptcp_v0.93/include/net/netns/mptcp.h ---- linux-4.9.162/include/net/netns/mptcp.h 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_v0.93/include/net/netns/mptcp.h 2019-03-14 14:02:32.000000000 +0100 -@@ -0,0 +1,52 @@ -+/* -+ * MPTCP implementation - MPTCP namespace -+ * -+ * Initial Design & Implementation: -+ * Sébastien Barré -+ * -+ * Current Maintainer: -+ * Christoph Paasch -+ * -+ * Additional authors: -+ * Jaakko Korkeaniemi -+ * Gregory Detal -+ * Fabien Duchêne -+ * Andreas Seelinger -+ * Lavkesh Lahngir -+ * Andreas Ripke -+ * Vlad Dogaru -+ * Octavian Purdila -+ * John Ronan -+ * Catalin Nicutar -+ * Brandon Heller -+ * -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version -+ * 2 of the License, or (at your option) any later version. -+ */ -+ -+#ifndef __NETNS_MPTCP_H__ -+#define __NETNS_MPTCP_H__ -+ -+#include -+ -+enum { -+ MPTCP_PM_FULLMESH = 0, -+ MPTCP_PM_MAX -+}; -+ -+struct mptcp_mib; -+ -+struct netns_mptcp { -+ DEFINE_SNMP_STAT(struct mptcp_mib, mptcp_statistics); -+ -+#ifdef CONFIG_PROC_FS -+ struct proc_dir_entry *proc_net_mptcp; -+#endif -+ -+ void *path_managers[MPTCP_PM_MAX]; -+}; -+ -+#endif /* __NETNS_MPTCP_H__ */ -diff -aurN linux-4.9.162/include/net/snmp.h mptcp-mptcp_v0.93/include/net/snmp.h ---- linux-4.9.162/include/net/snmp.h 2019-03-05 17:57:07.000000000 +0100 -+++ mptcp-mptcp_v0.93/include/net/snmp.h 2019-03-14 14:02:32.000000000 +0100 -@@ -91,7 +91,6 @@ - atomic_long_t mibs[ICMP6MSG_MIB_MAX]; - }; - -- - /* TCP */ - #define TCP_MIB_MAX __TCP_MIB_MAX - struct tcp_mib { -diff -aurN linux-4.9.162/include/net/sock.h mptcp-mptcp_v0.93/include/net/sock.h ---- linux-4.9.162/include/net/sock.h 2019-03-05 17:57:07.000000000 +0100 -+++ mptcp-mptcp_v0.93/include/net/sock.h 2019-03-14 14:02:32.000000000 +0100 -@@ -743,6 +743,7 @@ - SOCK_FILTER_LOCKED, /* Filter cannot be changed anymore */ - SOCK_SELECT_ERR_QUEUE, /* Wake select on error queue */ - SOCK_RCU_FREE, /* wait rcu grace period in sk_destruct() */ -+ SOCK_MPTCP, /* MPTCP set on this socket */ - }; - - #define SK_FLAGS_TIMESTAMP ((1UL << SOCK_TIMESTAMP) | (1UL << SOCK_TIMESTAMPING_RX_SOFTWARE)) -@@ -948,6 +949,16 @@ - - int sk_wait_data(struct sock *sk, long *timeo, const struct sk_buff *skb); - -+/* START - needed for MPTCP */ -+struct sock *sk_prot_alloc(struct proto *prot, gfp_t priority, int family); -+void sock_lock_init(struct sock *sk); -+ -+extern struct lock_class_key af_callback_keys[AF_MAX]; -+extern char *const af_family_clock_key_strings[AF_MAX+1]; -+ -+#define SK_FLAGS_TIMESTAMP ((1UL << SOCK_TIMESTAMP) | (1UL << SOCK_TIMESTAMPING_RX_SOFTWARE)) -+/* END - needed for MPTCP */ -+ - struct request_sock_ops; - struct timewait_sock_ops; - struct inet_hashinfo; -@@ -1022,6 +1033,7 @@ - void (*unhash)(struct sock *sk); - void (*rehash)(struct sock *sk); - int (*get_port)(struct sock *sk, unsigned short snum); -+ void (*clear_sk)(struct sock *sk, int size); - - /* Keeping track of sockets in use */ - #ifdef CONFIG_PROC_FS -diff -aurN linux-4.9.162/include/net/tcp.h mptcp-mptcp_v0.93/include/net/tcp.h ---- linux-4.9.162/include/net/tcp.h 2019-03-05 17:57:07.000000000 +0100 -+++ mptcp-mptcp_v0.93/include/net/tcp.h 2019-03-14 14:02:32.000000000 +0100 -@@ -178,6 +178,7 @@ - #define TCPOPT_SACK 5 /* SACK Block */ - #define TCPOPT_TIMESTAMP 8 /* Better RTT estimations/PAWS */ - #define TCPOPT_MD5SIG 19 /* MD5 Signature (RFC2385) */ -+#define TCPOPT_MPTCP 30 - #define TCPOPT_FASTOPEN 34 /* Fast open (RFC7413) */ - #define TCPOPT_EXP 254 /* Experimental */ - /* Magic number to be after the option value for sharing TCP -@@ -231,6 +232,30 @@ - */ - #define TFO_SERVER_WO_SOCKOPT1 0x400 - -+/* Flags from tcp_input.c for tcp_ack */ -+#define FLAG_DATA 0x01 /* Incoming frame contained data. */ -+#define FLAG_WIN_UPDATE 0x02 /* Incoming ACK was a window update. */ -+#define FLAG_DATA_ACKED 0x04 /* This ACK acknowledged new data. */ -+#define FLAG_RETRANS_DATA_ACKED 0x08 /* "" "" some of which was retransmitted. */ -+#define FLAG_SYN_ACKED 0x10 /* This ACK acknowledged SYN. */ -+#define FLAG_DATA_SACKED 0x20 /* New SACK. */ -+#define FLAG_ECE 0x40 /* ECE in this ACK */ -+#define FLAG_LOST_RETRANS 0x80 /* This ACK marks some retransmission lost */ -+#define FLAG_SLOWPATH 0x100 /* Do not skip RFC checks for window update.*/ -+#define FLAG_ORIG_SACK_ACKED 0x200 /* Never retransmitted data are (s)acked */ -+#define FLAG_SND_UNA_ADVANCED 0x400 /* Snd_una was changed (!= FLAG_DATA_ACKED) */ -+#define FLAG_DSACKING_ACK 0x800 /* SACK blocks contained D-SACK info */ -+#define FLAG_SACK_RENEGING 0x2000 /* snd_una advanced to a sacked seq */ -+#define FLAG_UPDATE_TS_RECENT 0x4000 /* tcp_replace_ts_recent() */ -+#define FLAG_NO_CHALLENGE_ACK 0x8000 /* do not call tcp_send_challenge_ack() */ -+ -+#define MPTCP_FLAG_DATA_ACKED 0x10000 -+ -+#define FLAG_ACKED (FLAG_DATA_ACKED|FLAG_SYN_ACKED) -+#define FLAG_NOT_DUP (FLAG_DATA|FLAG_WIN_UPDATE|FLAG_ACKED) -+#define FLAG_CA_ALERT (FLAG_DATA_SACKED|FLAG_ECE) -+#define FLAG_FORWARD_PROGRESS (FLAG_ACKED|FLAG_DATA_SACKED) -+ - extern struct inet_timewait_death_row tcp_death_row; - - /* sysctl variables for tcp */ -@@ -335,6 +360,97 @@ - #define TCP_DEC_STATS(net, field) SNMP_DEC_STATS((net)->mib.tcp_statistics, field) - #define TCP_ADD_STATS(net, field, val) SNMP_ADD_STATS((net)->mib.tcp_statistics, field, val) - -+/**** START - Exports needed for MPTCP ****/ -+extern const struct tcp_request_sock_ops tcp_request_sock_ipv4_ops; -+extern const struct tcp_request_sock_ops tcp_request_sock_ipv6_ops; -+ -+struct mptcp_options_received; -+ -+void tcp_cleanup_rbuf(struct sock *sk, int copied); -+void tcp_cwnd_validate(struct sock *sk, bool is_cwnd_limited); -+int tcp_close_state(struct sock *sk); -+void tcp_minshall_update(struct tcp_sock *tp, unsigned int mss_now, -+ const struct sk_buff *skb); -+int tcp_xmit_probe_skb(struct sock *sk, int urgent, int mib); -+void tcp_event_new_data_sent(struct sock *sk, const struct sk_buff *skb); -+int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it, -+ gfp_t gfp_mask); -+unsigned int tcp_mss_split_point(const struct sock *sk, -+ const struct sk_buff *skb, -+ unsigned int mss_now, -+ unsigned int max_segs, -+ int nonagle); -+bool tcp_nagle_test(const struct tcp_sock *tp, const struct sk_buff *skb, -+ unsigned int cur_mss, int nonagle); -+bool tcp_snd_wnd_test(const struct tcp_sock *tp, const struct sk_buff *skb, -+ unsigned int cur_mss); -+unsigned int tcp_cwnd_test(const struct tcp_sock *tp, const struct sk_buff *skb); -+int tcp_init_tso_segs(struct sk_buff *skb, unsigned int mss_now); -+int __pskb_trim_head(struct sk_buff *skb, int len); -+void tcp_queue_skb(struct sock *sk, struct sk_buff *skb); -+void tcp_init_nondata_skb(struct sk_buff *skb, u32 seq, u8 flags); -+void tcp_reset(struct sock *sk); -+bool tcp_may_update_window(const struct tcp_sock *tp, const u32 ack, -+ const u32 ack_seq, const u32 nwin); -+bool tcp_urg_mode(const struct tcp_sock *tp); -+void tcp_ack_probe(struct sock *sk); -+void tcp_rearm_rto(struct sock *sk); -+int tcp_write_timeout(struct sock *sk); -+bool retransmits_timed_out(struct sock *sk, unsigned int boundary, -+ unsigned int timeout, bool syn_set); -+void tcp_write_err(struct sock *sk); -+void tcp_adjust_pcount(struct sock *sk, const struct sk_buff *skb, int decr); -+void tcp_set_skb_tso_segs(struct sk_buff *skb, unsigned int mss_now); -+ -+void tcp_v4_reqsk_send_ack(const struct sock *sk, struct sk_buff *skb, -+ struct request_sock *req); -+void tcp_v4_send_reset(const struct sock *sk, struct sk_buff *skb); -+struct sock *tcp_v4_cookie_check(struct sock *sk, struct sk_buff *skb); -+void tcp_v4_reqsk_destructor(struct request_sock *req); -+ -+void tcp_v6_reqsk_send_ack(const struct sock *sk, struct sk_buff *skb, -+ struct request_sock *req); -+void tcp_v6_send_reset(const struct sock *sk, struct sk_buff *skb); -+struct sock *tcp_v6_cookie_check(struct sock *sk, struct sk_buff *skb); -+int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb); -+int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len); -+void tcp_v6_destroy_sock(struct sock *sk); -+void inet6_sk_rx_dst_set(struct sock *sk, const struct sk_buff *skb); -+void tcp_v6_hash(struct sock *sk); -+struct sock *tcp_v6_hnd_req(struct sock *sk,struct sk_buff *skb); -+struct sock *tcp_v6_syn_recv_sock(const struct sock *sk, struct sk_buff *skb, -+ struct request_sock *req, -+ struct dst_entry *dst, -+ struct request_sock *req_unhash, -+ bool *own_req); -+void tcp_v6_reqsk_destructor(struct request_sock *req); -+ -+unsigned int tcp_xmit_size_goal(struct sock *sk, u32 mss_now, -+ int large_allowed); -+u32 tcp_tso_acked(struct sock *sk, struct sk_buff *skb); -+ -+void skb_clone_fraglist(struct sk_buff *skb); -+void copy_skb_header(struct sk_buff *new, const struct sk_buff *old); -+ -+void inet_twsk_free(struct inet_timewait_sock *tw); -+int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb); -+/* These states need RST on ABORT according to RFC793 */ -+static inline bool tcp_need_reset(int state) -+{ -+ return (1 << state) & -+ (TCPF_ESTABLISHED | TCPF_CLOSE_WAIT | TCPF_FIN_WAIT1 | -+ TCPF_FIN_WAIT2 | TCPF_SYN_RECV); -+} -+ -+int __must_check tcp_queue_rcv(struct sock *sk, struct sk_buff *skb, int hdrlen, -+ bool *fragstolen); -+bool tcp_try_coalesce(struct sock *sk, struct sk_buff *to, -+ struct sk_buff *from, bool *fragstolen); -+void tcp_ofo_queue(struct sock *sk); -+void tcp_data_queue_ofo(struct sock *sk, struct sk_buff *skb); -+int linear_payload_sz(bool first_skb); -+/**** END - Exports needed for MPTCP ****/ -+ - void tcp_tasklet_init(void); - - void tcp_v4_err(struct sk_buff *skb, u32); -@@ -428,7 +544,9 @@ - int flags, int *addr_len); - void tcp_parse_options(const struct sk_buff *skb, - struct tcp_options_received *opt_rx, -- int estab, struct tcp_fastopen_cookie *foc); -+ struct mptcp_options_received *mopt_rx, -+ int estab, struct tcp_fastopen_cookie *foc, -+ struct tcp_sock *tp); - const u8 *tcp_parse_md5sig_option(const struct tcphdr *th); - - /* -@@ -437,6 +555,7 @@ - - void tcp_v4_send_check(struct sock *sk, struct sk_buff *skb); - void tcp_v4_mtu_reduced(struct sock *sk); -+void tcp_v6_mtu_reduced(struct sock *sk); - void tcp_req_err(struct sock *sk, u32 seq, bool abort); - int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb); - struct sock *tcp_create_openreq_child(const struct sock *sk, -@@ -517,7 +636,8 @@ - - u32 __cookie_v4_init_sequence(const struct iphdr *iph, const struct tcphdr *th, - u16 *mssp); --__u32 cookie_v4_init_sequence(const struct sk_buff *skb, __u16 *mss); -+__u32 cookie_v4_init_sequence(struct request_sock *req, const struct sock *sk, -+ const struct sk_buff *skb, __u16 *mss); - __u32 cookie_init_timestamp(struct request_sock *req); - bool cookie_timestamp_decode(struct tcp_options_received *opt); - bool cookie_ecn_ok(const struct tcp_options_received *opt, -@@ -530,7 +650,8 @@ - - u32 __cookie_v6_init_sequence(const struct ipv6hdr *iph, - const struct tcphdr *th, u16 *mssp); --__u32 cookie_v6_init_sequence(const struct sk_buff *skb, __u16 *mss); -+__u32 cookie_v6_init_sequence(struct request_sock *req, const struct sock *sk, -+ const struct sk_buff *skb, __u16 *mss); - #endif - /* tcp_output.c */ - -@@ -562,11 +683,18 @@ - void tcp_skb_collapse_tstamp(struct sk_buff *skb, - const struct sk_buff *next_skb); - -+u16 tcp_select_window(struct sock *sk); -+int select_size(const struct sock *sk, bool sg, bool first_skb); -+bool tcp_write_xmit(struct sock *sk, unsigned int mss_now, int nonagle, -+ int push_one, gfp_t gfp); -+ - /* tcp_input.c */ - void tcp_resume_early_retransmit(struct sock *sk); - void tcp_rearm_rto(struct sock *sk); - void tcp_synack_rtt_meas(struct sock *sk, struct request_sock *req); - void tcp_reset(struct sock *sk); -+void tcp_set_rto(struct sock *sk); -+bool tcp_should_expand_sndbuf(const struct sock *sk); - void tcp_skb_mark_lost_uncond_verify(struct tcp_sock *tp, struct sk_buff *skb); - void tcp_fin(struct sock *sk); - -@@ -748,6 +876,12 @@ - u16 tcp_gso_size; - }; - }; -+ -+#ifdef CONFIG_MPTCP -+ __u8 mptcp_flags; /* flags for the MPTCP layer */ -+ __u8 dss_off; /* Number of 4-byte words until -+ * seq-number */ -+#endif - __u8 tcp_flags; /* TCP header flags. (tcp[13]) */ - - __u8 sacked; /* State flags for SACK/FACK. */ -@@ -765,6 +899,14 @@ - eor:1, /* Is skb MSG_EOR marked? */ - unused:6; - __u32 ack_seq; /* Sequence number ACK'd */ -+ -+#ifdef CONFIG_MPTCP -+ union { /* For MPTCP outgoing frames */ -+ __u32 path_mask; /* paths that tried to send this skb */ -+ __u32 dss[6]; /* DSS options */ -+ }; -+#endif -+ - union { - struct { - /* There is space for up to 24 bytes */ -@@ -1261,7 +1403,8 @@ - /* Determine a window scaling and initial window to offer. */ - void tcp_select_initial_window(int __space, __u32 mss, __u32 *rcv_wnd, - __u32 *window_clamp, int wscale_ok, -- __u8 *rcv_wscale, __u32 init_rcv_wnd); -+ __u8 *rcv_wscale, __u32 init_rcv_wnd, -+ const struct sock *sk); - - static inline int tcp_win_from_space(int space) - { -@@ -1272,6 +1415,19 @@ - space - (space>>tcp_adv_win_scale); - } - -+#ifdef CONFIG_MPTCP -+extern struct static_key mptcp_static_key; -+static inline bool mptcp(const struct tcp_sock *tp) -+{ -+ return static_key_false(&mptcp_static_key) && tp->mpc; -+} -+#else -+static inline bool mptcp(const struct tcp_sock *tp) -+{ -+ return 0; -+} -+#endif -+ - /* Note: caller must be prepared to deal with negative returns */ - static inline int tcp_space(const struct sock *sk) - { -@@ -1791,6 +1947,30 @@ - #endif - }; - -+/* TCP/MPTCP-specific functions */ -+struct tcp_sock_ops { -+ u32 (*__select_window)(struct sock *sk); -+ u16 (*select_window)(struct sock *sk); -+ void (*select_initial_window)(int __space, __u32 mss, __u32 *rcv_wnd, -+ __u32 *window_clamp, int wscale_ok, -+ __u8 *rcv_wscale, __u32 init_rcv_wnd, -+ const struct sock *sk); -+ int (*select_size)(const struct sock *sk, bool sg, bool first_skb); -+ void (*init_buffer_space)(struct sock *sk); -+ void (*set_rto)(struct sock *sk); -+ bool (*should_expand_sndbuf)(const struct sock *sk); -+ void (*send_fin)(struct sock *sk); -+ bool (*write_xmit)(struct sock *sk, unsigned int mss_now, int nonagle, -+ int push_one, gfp_t gfp); -+ void (*send_active_reset)(struct sock *sk, gfp_t priority); -+ int (*write_wakeup)(struct sock *sk, int mib); -+ void (*retransmit_timer)(struct sock *sk); -+ void (*time_wait)(struct sock *sk, int state, int timeo); -+ void (*cleanup_rbuf)(struct sock *sk, int copied); -+ void (*cwnd_validate)(struct sock *sk, bool is_cwnd_limited); -+}; -+extern const struct tcp_sock_ops tcp_specific; -+ - struct tcp_request_sock_ops { - u16 mss_clamp; - #ifdef CONFIG_TCP_MD5SIG -@@ -1801,12 +1981,13 @@ - const struct sock *sk, - const struct sk_buff *skb); - #endif -- void (*init_req)(struct request_sock *req, -- const struct sock *sk_listener, -- struct sk_buff *skb); -+ int (*init_req)(struct request_sock *req, -+ const struct sock *sk_listener, -+ struct sk_buff *skb, -+ bool want_cookie); - #ifdef CONFIG_SYN_COOKIES -- __u32 (*cookie_init_seq)(const struct sk_buff *skb, -- __u16 *mss); -+ __u32 (*cookie_init_seq)(struct request_sock *req, const struct sock *sk, -+ const struct sk_buff *skb, __u16 *mss); - #endif - struct dst_entry *(*route_req)(const struct sock *sk, struct flowi *fl, - const struct request_sock *req, -@@ -1820,15 +2001,17 @@ - - #ifdef CONFIG_SYN_COOKIES - static inline __u32 cookie_init_sequence(const struct tcp_request_sock_ops *ops, -+ struct request_sock *req, - const struct sock *sk, struct sk_buff *skb, - __u16 *mss) - { - tcp_synq_overflow(sk); - __NET_INC_STATS(sock_net(sk), LINUX_MIB_SYNCOOKIESSENT); -- return ops->cookie_init_seq(skb, mss); -+ return ops->cookie_init_seq(req, sk, skb, mss); - } - #else - static inline __u32 cookie_init_sequence(const struct tcp_request_sock_ops *ops, -+ struct request_sock *req, - const struct sock *sk, struct sk_buff *skb, - __u16 *mss) - { -diff -aurN linux-4.9.162/include/net/tcp_states.h mptcp-mptcp_v0.93/include/net/tcp_states.h ---- linux-4.9.162/include/net/tcp_states.h 2019-03-05 17:57:07.000000000 +0100 -+++ mptcp-mptcp_v0.93/include/net/tcp_states.h 2019-03-14 14:02:32.000000000 +0100 -@@ -26,6 +26,7 @@ - TCP_LISTEN, - TCP_CLOSING, /* Now a valid state */ - TCP_NEW_SYN_RECV, -+ TCP_RST_WAIT, - - TCP_MAX_STATES /* Leave at the end! */ - }; -@@ -47,6 +48,7 @@ - TCPF_LISTEN = (1 << 10), - TCPF_CLOSING = (1 << 11), - TCPF_NEW_SYN_RECV = (1 << 12), -+ TCPF_RST_WAIT = (1 << 13), - }; - - #endif /* _LINUX_TCP_STATES_H */ -diff -aurN linux-4.9.162/include/net/transp_v6.h mptcp-mptcp_v0.93/include/net/transp_v6.h ---- linux-4.9.162/include/net/transp_v6.h 2019-03-05 17:57:07.000000000 +0100 -+++ mptcp-mptcp_v0.93/include/net/transp_v6.h 2019-03-14 14:02:32.000000000 +0100 -@@ -51,6 +51,8 @@ - - /* address family specific functions */ - extern const struct inet_connection_sock_af_ops ipv4_specific; -+extern const struct inet_connection_sock_af_ops ipv6_mapped; -+extern const struct inet_connection_sock_af_ops ipv6_specific; - - void inet6_destroy_sock(struct sock *sk); - -diff -aurN linux-4.9.162/include/uapi/linux/if.h mptcp-mptcp_v0.93/include/uapi/linux/if.h ---- linux-4.9.162/include/uapi/linux/if.h 2019-03-05 17:57:07.000000000 +0100 -+++ mptcp-mptcp_v0.93/include/uapi/linux/if.h 2019-03-14 14:02:32.000000000 +0100 -@@ -127,6 +127,9 @@ - #define IFF_ECHO IFF_ECHO - #endif /* __UAPI_DEF_IF_NET_DEVICE_FLAGS_LOWER_UP_DORMANT_ECHO */ - -+#define IFF_NOMULTIPATH 0x80000 /* Disable for MPTCP */ -+#define IFF_MPBACKUP 0x100000 /* Use as backup path for MPTCP */ -+ - #define IFF_VOLATILE (IFF_LOOPBACK|IFF_POINTOPOINT|IFF_BROADCAST|IFF_ECHO|\ - IFF_MASTER|IFF_SLAVE|IFF_RUNNING|IFF_LOWER_UP|IFF_DORMANT) - -diff -aurN linux-4.9.162/include/uapi/linux/tcp.h mptcp-mptcp_v0.93/include/uapi/linux/tcp.h ---- linux-4.9.162/include/uapi/linux/tcp.h 2019-03-05 17:57:07.000000000 +0100 -+++ mptcp-mptcp_v0.93/include/uapi/linux/tcp.h 2019-03-14 14:02:32.000000000 +0100 -@@ -17,9 +17,15 @@ - #ifndef _UAPI_LINUX_TCP_H - #define _UAPI_LINUX_TCP_H - --#include -+#ifndef __KERNEL__ -+#include -+#endif -+ - #include -+#include -+#include - #include -+#include - - struct tcphdr { - __be16 source; -@@ -116,6 +122,12 @@ - #define TCP_SAVE_SYN 27 /* Record SYN headers for new connections */ - #define TCP_SAVED_SYN 28 /* Get SYN headers recorded for connection */ - #define TCP_REPAIR_WINDOW 29 /* Get/set window parameters */ -+#define MPTCP_ENABLED 42 -+#define MPTCP_SCHEDULER 43 -+#define MPTCP_PATH_MANAGER 44 -+#define MPTCP_INFO 45 -+ -+#define MPTCP_INFO_FLAG_SAVE_MASTER 0x01 - - struct tcp_repair_opt { - __u32 opt_code; -@@ -216,6 +228,53 @@ - __u64 tcpi_delivery_rate; - }; - -+struct mptcp_meta_info { -+ __u8 mptcpi_state; -+ __u8 mptcpi_retransmits; -+ __u8 mptcpi_probes; -+ __u8 mptcpi_backoff; -+ -+ __u32 mptcpi_rto; -+ __u32 mptcpi_unacked; -+ -+ /* Times. */ -+ __u32 mptcpi_last_data_sent; -+ __u32 mptcpi_last_data_recv; -+ __u32 mptcpi_last_ack_recv; -+ -+ __u32 mptcpi_total_retrans; -+ -+ __u64 mptcpi_bytes_acked; /* RFC4898 tcpEStatsAppHCThruOctetsAcked */ -+ __u64 mptcpi_bytes_received; /* RFC4898 tcpEStatsAppHCThruOctetsReceived */ -+}; -+ -+struct mptcp_sub_info { -+ union { -+ struct sockaddr src; -+ struct sockaddr_in src_v4; -+ struct sockaddr_in6 src_v6; -+ }; -+ -+ union { -+ struct sockaddr dst; -+ struct sockaddr_in dst_v4; -+ struct sockaddr_in6 dst_v6; -+ }; -+}; -+ -+struct mptcp_info { -+ __u32 tcp_info_len; /* Length of each struct tcp_info in subflows pointer */ -+ __u32 sub_len; /* Total length of memory pointed to by subflows pointer */ -+ __u32 meta_len; /* Length of memory pointed to by meta_info */ -+ __u32 sub_info_len; /* Length of each struct mptcp_sub_info in subflow_info pointer */ -+ __u32 total_sub_info_len; /* Total length of memory pointed to by subflow_info */ -+ -+ struct mptcp_meta_info *meta_info; -+ struct tcp_info *initial; -+ struct tcp_info *subflows; /* Pointer to array of tcp_info structs */ -+ struct mptcp_sub_info *subflow_info; -+}; -+ - /* for TCP_MD5SIG socket option */ - #define TCP_MD5SIG_MAXKEYLEN 80 - -diff -aurN linux-4.9.162/net/core/dev.c mptcp-mptcp_v0.93/net/core/dev.c ---- linux-4.9.162/net/core/dev.c 2019-03-05 17:57:07.000000000 +0100 -+++ mptcp-mptcp_v0.93/net/core/dev.c 2019-03-14 14:02:32.000000000 +0100 -@@ -6478,7 +6478,7 @@ - - dev->flags = (flags & (IFF_DEBUG | IFF_NOTRAILERS | IFF_NOARP | - IFF_DYNAMIC | IFF_MULTICAST | IFF_PORTSEL | -- IFF_AUTOMEDIA)) | -+ IFF_AUTOMEDIA | IFF_NOMULTIPATH | IFF_MPBACKUP)) | - (dev->flags & (IFF_UP | IFF_VOLATILE | IFF_PROMISC | - IFF_ALLMULTI)); - -diff -aurN linux-4.9.162/net/core/skbuff.c mptcp-mptcp_v0.93/net/core/skbuff.c ---- linux-4.9.162/net/core/skbuff.c 2019-03-05 17:57:07.000000000 +0100 -+++ mptcp-mptcp_v0.93/net/core/skbuff.c 2019-03-14 14:02:32.000000000 +0100 -@@ -566,7 +566,7 @@ - skb_drop_list(&skb_shinfo(skb)->frag_list); - } - --static void skb_clone_fraglist(struct sk_buff *skb) -+void skb_clone_fraglist(struct sk_buff *skb) - { - struct sk_buff *list; - -@@ -1062,7 +1062,7 @@ - skb->inner_mac_header += off; - } - --static void copy_skb_header(struct sk_buff *new, const struct sk_buff *old) -+void copy_skb_header(struct sk_buff *new, const struct sk_buff *old) - { - __copy_skb_header(new, old); - -diff -aurN linux-4.9.162/net/core/sock.c mptcp-mptcp_v0.93/net/core/sock.c ---- linux-4.9.162/net/core/sock.c 2019-03-05 17:57:07.000000000 +0100 -+++ mptcp-mptcp_v0.93/net/core/sock.c 2019-03-14 14:02:32.000000000 +0100 -@@ -138,6 +138,11 @@ - - #include - -+#ifdef CONFIG_MPTCP -+#include -+#include -+#endif -+ - #include - #include - -@@ -238,7 +243,7 @@ - "slock-AF_NFC" , "slock-AF_VSOCK" ,"slock-AF_KCM" , - "slock-AF_QIPCRTR", "slock-AF_MAX" - }; --static const char *const af_family_clock_key_strings[AF_MAX+1] = { -+char *const af_family_clock_key_strings[AF_MAX+1] = { - "clock-AF_UNSPEC", "clock-AF_UNIX" , "clock-AF_INET" , - "clock-AF_AX25" , "clock-AF_IPX" , "clock-AF_APPLETALK", - "clock-AF_NETROM", "clock-AF_BRIDGE" , "clock-AF_ATMPVC" , -@@ -260,7 +265,7 @@ - * sk_callback_lock locking rules are per-address-family, - * so split the lock classes by using a per-AF key: - */ --static struct lock_class_key af_callback_keys[AF_MAX]; -+struct lock_class_key af_callback_keys[AF_MAX]; - - /* Take into consideration the size of the struct sk_buff overhead in the - * determination of these values, since that is non-constant across -@@ -1284,8 +1289,25 @@ - * - * (We also register the sk_lock with the lock validator.) - */ --static inline void sock_lock_init(struct sock *sk) -+void sock_lock_init(struct sock *sk) - { -+#ifdef CONFIG_MPTCP -+ /* Reclassify the lock-class for subflows */ -+ if (sk->sk_type == SOCK_STREAM && sk->sk_protocol == IPPROTO_TCP) -+ if (mptcp(tcp_sk(sk)) || tcp_sk(sk)->is_master_sk) { -+ sock_lock_init_class_and_name(sk, meta_slock_key_name, -+ &meta_slock_key, -+ meta_key_name, -+ &meta_key); -+ -+ /* We don't yet have the mptcp-point. -+ * Thus we still need inet_sock_destruct -+ */ -+ sk->sk_destruct = inet_sock_destruct; -+ return; -+ } -+#endif -+ - sock_lock_init_class_and_name(sk, - af_family_slock_key_strings[sk->sk_family], - af_family_slock_keys + sk->sk_family, -@@ -1314,7 +1336,7 @@ - #endif - } - --static struct sock *sk_prot_alloc(struct proto *prot, gfp_t priority, -+struct sock *sk_prot_alloc(struct proto *prot, gfp_t priority, - int family) - { - struct sock *sk; -@@ -1325,8 +1347,12 @@ - sk = kmem_cache_alloc(slab, priority & ~__GFP_ZERO); - if (!sk) - return sk; -- if (priority & __GFP_ZERO) -- sk_prot_clear_nulls(sk, prot->obj_size); -+ if (priority & __GFP_ZERO) { -+ if (prot->clear_sk) -+ prot->clear_sk(sk, prot->obj_size); -+ else -+ sk_prot_clear_nulls(sk, prot->obj_size); -+ } - } else - sk = kmalloc(prot->obj_size, priority); - -@@ -1527,6 +1553,7 @@ - newsk->sk_userlocks = sk->sk_userlocks & ~SOCK_BINDPORT_LOCK; - - sock_reset_flag(newsk, SOCK_DONE); -+ sock_reset_flag(newsk, SOCK_MPTCP); - cgroup_sk_alloc(&newsk->sk_cgrp_data); - skb_queue_head_init(&newsk->sk_error_queue); - -diff -aurN linux-4.9.162/net/ipv4/af_inet.c mptcp-mptcp_v0.93/net/ipv4/af_inet.c ---- linux-4.9.162/net/ipv4/af_inet.c 2019-03-05 17:57:07.000000000 +0100 -+++ mptcp-mptcp_v0.93/net/ipv4/af_inet.c 2019-03-14 14:02:32.000000000 +0100 -@@ -104,6 +104,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -149,6 +150,9 @@ - return; - } - -+ if (sock_flag(sk, SOCK_MPTCP)) -+ mptcp_disable_static_key(); -+ - WARN_ON(atomic_read(&sk->sk_rmem_alloc)); - WARN_ON(atomic_read(&sk->sk_wmem_alloc)); - WARN_ON(sk->sk_wmem_queued); -@@ -241,8 +245,7 @@ - * Create an inet socket. - */ - --static int inet_create(struct net *net, struct socket *sock, int protocol, -- int kern) -+int inet_create(struct net *net, struct socket *sock, int protocol, int kern) - { - struct sock *sk; - struct inet_protosw *answer; -@@ -674,6 +677,23 @@ - lock_sock(sk2); - - sock_rps_record_flow(sk2); -+ -+ if (sk2->sk_protocol == IPPROTO_TCP && mptcp(tcp_sk(sk2))) { -+ struct sock *sk_it = sk2; -+ -+ mptcp_for_each_sk(tcp_sk(sk2)->mpcb, sk_it) -+ sock_rps_record_flow(sk_it); -+ -+ if (tcp_sk(sk2)->mpcb->master_sk) { -+ sk_it = tcp_sk(sk2)->mpcb->master_sk; -+ -+ write_lock_bh(&sk_it->sk_callback_lock); -+ sk_it->sk_wq = newsock->wq; -+ sk_it->sk_socket = newsock; -+ write_unlock_bh(&sk_it->sk_callback_lock); -+ } -+ } -+ - WARN_ON(!((1 << sk2->sk_state) & - (TCPF_ESTABLISHED | TCPF_SYN_RECV | - TCPF_CLOSE_WAIT | TCPF_CLOSE))); -@@ -1831,6 +1851,9 @@ - - ip_init(); - -+ /* We must initialize MPTCP before TCP. */ -+ mptcp_init(); -+ - tcp_v4_init(); - - /* Setup TCP slab cache for open requests. */ -diff -aurN linux-4.9.162/net/ipv4/inet_connection_sock.c mptcp-mptcp_v0.93/net/ipv4/inet_connection_sock.c ---- linux-4.9.162/net/ipv4/inet_connection_sock.c 2019-03-05 17:57:07.000000000 +0100 -+++ mptcp-mptcp_v0.93/net/ipv4/inet_connection_sock.c 2019-03-14 14:02:32.000000000 +0100 -@@ -23,6 +23,7 @@ - #include - #include - #include -+#include - #include - #include - -@@ -557,7 +558,10 @@ - int max_retries, thresh; - u8 defer_accept; - -- if (sk_state_load(sk_listener) != TCP_LISTEN) -+ if (sk_state_load(sk_listener) != TCP_LISTEN && !is_meta_sk(sk_listener)) -+ goto drop; -+ -+ if (is_meta_sk(sk_listener) && !mptcp_can_new_subflow(sk_listener)) - goto drop; - - max_retries = icsk->icsk_syn_retries ? : net->ipv4.sysctl_tcp_synack_retries; -@@ -651,7 +655,9 @@ - const struct request_sock *req, - const gfp_t priority) - { -- struct sock *newsk = sk_clone_lock(sk, priority); -+ struct sock *newsk; -+ -+ newsk = sk_clone_lock(sk, priority); - - if (newsk) { - struct inet_connection_sock *newicsk = inet_csk(newsk); -@@ -854,7 +860,12 @@ - */ - while ((req = reqsk_queue_remove(queue, sk)) != NULL) { - struct sock *child = req->sk; -+ bool mutex_taken = false; - -+ if (is_meta_sk(child)) { -+ mutex_lock(&tcp_sk(child)->mpcb->mpcb_mutex); -+ mutex_taken = true; -+ } - local_bh_disable(); - bh_lock_sock(child); - WARN_ON(sock_owned_by_user(child)); -@@ -863,6 +874,8 @@ - inet_child_forget(sk, req, child); - bh_unlock_sock(child); - local_bh_enable(); -+ if (mutex_taken) -+ mutex_unlock(&tcp_sk(child)->mpcb->mpcb_mutex); - sock_put(child); - - cond_resched(); -diff -aurN linux-4.9.162/net/ipv4/ip_sockglue.c mptcp-mptcp_v0.93/net/ipv4/ip_sockglue.c ---- linux-4.9.162/net/ipv4/ip_sockglue.c 2019-03-05 17:57:07.000000000 +0100 -+++ mptcp-mptcp_v0.93/net/ipv4/ip_sockglue.c 2019-03-14 14:02:32.000000000 +0100 -@@ -43,6 +43,8 @@ - #endif - #include - -+#include -+ - #include - #include - -@@ -734,6 +736,17 @@ - inet->tos = val; - sk->sk_priority = rt_tos2priority(val); - sk_dst_reset(sk); -+ /* Update TOS on mptcp subflow */ -+ if (is_meta_sk(sk)) { -+ struct sock *sk_it; -+ mptcp_for_each_sk(tcp_sk(sk)->mpcb, sk_it) { -+ if (inet_sk(sk_it)->tos != inet_sk(sk)->tos) { -+ inet_sk(sk_it)->tos = inet_sk(sk)->tos; -+ sk_it->sk_priority = sk->sk_priority; -+ sk_dst_reset(sk_it); -+ } -+ } -+ } - } - break; - case IP_TTL: -diff -aurN linux-4.9.162/net/ipv4/Kconfig mptcp-mptcp_v0.93/net/ipv4/Kconfig ---- linux-4.9.162/net/ipv4/Kconfig 2019-03-05 17:57:07.000000000 +0100 -+++ mptcp-mptcp_v0.93/net/ipv4/Kconfig 2019-03-14 14:02:32.000000000 +0100 -@@ -655,6 +655,38 @@ - bufferbloat, policers, or AQM schemes that do not provide a delay - signal. It requires the fq ("Fair Queue") pacing packet scheduler. - -+config TCP_CONG_LIA -+ tristate "MPTCP Linked Increase" -+ depends on MPTCP -+ default n -+ ---help--- -+ MultiPath TCP Linked Increase Congestion Control -+ To enable it, just put 'lia' in tcp_congestion_control -+ -+config TCP_CONG_OLIA -+ tristate "MPTCP Opportunistic Linked Increase" -+ depends on MPTCP -+ default n -+ ---help--- -+ MultiPath TCP Opportunistic Linked Increase Congestion Control -+ To enable it, just put 'olia' in tcp_congestion_control -+ -+config TCP_CONG_WVEGAS -+ tristate "MPTCP WVEGAS CONGESTION CONTROL" -+ depends on MPTCP -+ default n -+ ---help--- -+ wVegas congestion control for MPTCP -+ To enable it, just put 'wvegas' in tcp_congestion_control -+ -+config TCP_CONG_BALIA -+ tristate "MPTCP BALIA CONGESTION CONTROL" -+ depends on MPTCP -+ default n -+ ---help--- -+ Multipath TCP Balanced Linked Adaptation Congestion Control -+ To enable it, just put 'balia' in tcp_congestion_control -+ - choice - prompt "Default TCP congestion control" - default DEFAULT_CUBIC -@@ -692,6 +724,18 @@ - config DEFAULT_BBR - bool "BBR" if TCP_CONG_BBR=y - -+ config DEFAULT_LIA -+ bool "Lia" if TCP_CONG_LIA=y -+ -+ config DEFAULT_OLIA -+ bool "Olia" if TCP_CONG_OLIA=y -+ -+ config DEFAULT_WVEGAS -+ bool "Wvegas" if TCP_CONG_WVEGAS=y -+ -+ config DEFAULT_BALIA -+ bool "Balia" if TCP_CONG_BALIA=y -+ - config DEFAULT_RENO - bool "Reno" - endchoice -@@ -712,6 +756,10 @@ - default "vegas" if DEFAULT_VEGAS - default "westwood" if DEFAULT_WESTWOOD - default "veno" if DEFAULT_VENO -+ default "lia" if DEFAULT_LIA -+ default "olia" if DEFAULT_OLIA -+ default "wvegas" if DEFAULT_WVEGAS -+ default "balia" if DEFAULT_BALIA - default "reno" if DEFAULT_RENO - default "dctcp" if DEFAULT_DCTCP - default "cdg" if DEFAULT_CDG -diff -aurN linux-4.9.162/net/ipv4/syncookies.c mptcp-mptcp_v0.93/net/ipv4/syncookies.c ---- linux-4.9.162/net/ipv4/syncookies.c 2019-03-05 17:57:07.000000000 +0100 -+++ mptcp-mptcp_v0.93/net/ipv4/syncookies.c 2019-03-14 14:02:32.000000000 +0100 -@@ -16,6 +16,8 @@ - #include - #include - #include -+#include -+#include - #include - #include - -@@ -189,7 +191,8 @@ - } - EXPORT_SYMBOL_GPL(__cookie_v4_init_sequence); - --__u32 cookie_v4_init_sequence(const struct sk_buff *skb, __u16 *mssp) -+__u32 cookie_v4_init_sequence(struct request_sock *req, const struct sock *sk, -+ const struct sk_buff *skb, __u16 *mssp) - { - const struct iphdr *iph = ip_hdr(skb); - const struct tcphdr *th = tcp_hdr(skb); -@@ -219,9 +222,27 @@ - struct inet_connection_sock *icsk = inet_csk(sk); - struct sock *child; - bool own_req; -+#ifdef CONFIG_MPTCP -+ int ret; -+#endif - - child = icsk->icsk_af_ops->syn_recv_sock(sk, skb, req, dst, - NULL, &own_req); -+ -+#ifdef CONFIG_MPTCP -+ if (!child) -+ goto listen_overflow; -+ -+ ret = mptcp_check_req_master(sk, child, req, skb, 0); -+ if (ret < 0) -+ return NULL; -+ -+ if (!ret) -+ return tcp_sk(child)->mpcb->master_sk; -+ -+listen_overflow: -+#endif -+ - if (child) { - atomic_set(&req->rsk_refcnt, 1); - sock_rps_save_rxhash(child, skb); -@@ -292,6 +313,7 @@ - { - struct ip_options *opt = &TCP_SKB_CB(skb)->header.h4.opt; - struct tcp_options_received tcp_opt; -+ struct mptcp_options_received mopt; - struct inet_request_sock *ireq; - struct tcp_request_sock *treq; - struct tcp_sock *tp = tcp_sk(sk); -@@ -320,13 +342,19 @@ - - /* check for timestamp cookie support */ - memset(&tcp_opt, 0, sizeof(tcp_opt)); -- tcp_parse_options(skb, &tcp_opt, 0, NULL); -+ mptcp_init_mp_opt(&mopt); -+ tcp_parse_options(skb, &tcp_opt, &mopt, 0, NULL, NULL); - - if (!cookie_timestamp_decode(&tcp_opt)) - goto out; - - ret = NULL; -- req = inet_reqsk_alloc(&tcp_request_sock_ops, sk, false); /* for safety */ -+#ifdef CONFIG_MPTCP -+ if (mopt.saw_mpc) -+ req = inet_reqsk_alloc(&mptcp_request_sock_ops, sk, false); /* for safety */ -+ else -+#endif -+ req = inet_reqsk_alloc(&tcp_request_sock_ops, sk, false); /* for safety */ - if (!req) - goto out; - -@@ -345,12 +373,17 @@ - ireq->sack_ok = tcp_opt.sack_ok; - ireq->wscale_ok = tcp_opt.wscale_ok; - ireq->tstamp_ok = tcp_opt.saw_tstamp; -+ ireq->mptcp_rqsk = 0; -+ ireq->saw_mpc = 0; - req->ts_recent = tcp_opt.saw_tstamp ? tcp_opt.rcv_tsval : 0; - treq->snt_synack.v64 = 0; - treq->tfo_listener = false; - - ireq->ir_iif = inet_request_bound_dev_if(sk, skb); - -+ if (mopt.saw_mpc) -+ mptcp_cookies_reqsk_init(req, &mopt, skb); -+ - /* We throwed the options of the initial SYN away, so we hope - * the ACK carries the same options again (see RFC1122 4.2.3.8) - */ -@@ -384,10 +417,10 @@ - /* Try to redo what tcp_v4_send_synack did. */ - req->rsk_window_clamp = tp->window_clamp ? :dst_metric(&rt->dst, RTAX_WINDOW); - -- tcp_select_initial_window(tcp_full_space(sk), req->mss, -- &req->rsk_rcv_wnd, &req->rsk_window_clamp, -- ireq->wscale_ok, &rcv_wscale, -- dst_metric(&rt->dst, RTAX_INITRWND)); -+ tp->ops->select_initial_window(tcp_full_space(sk), req->mss, -+ &req->rsk_rcv_wnd, &req->rsk_window_clamp, -+ ireq->wscale_ok, &rcv_wscale, -+ dst_metric(&rt->dst, RTAX_INITRWND), sk); - - ireq->rcv_wscale = rcv_wscale; - ireq->ecn_ok = cookie_ecn_ok(&tcp_opt, sock_net(sk), &rt->dst); -diff -aurN linux-4.9.162/net/ipv4/tcp.c mptcp-mptcp_v0.93/net/ipv4/tcp.c ---- linux-4.9.162/net/ipv4/tcp.c 2019-03-05 17:57:07.000000000 +0100 -+++ mptcp-mptcp_v0.93/net/ipv4/tcp.c 2019-03-14 14:02:32.000000000 +0100 -@@ -272,6 +272,7 @@ - - #include - #include -+#include - #include - #include - #include -@@ -370,6 +371,24 @@ - return period; - } - -+const struct tcp_sock_ops tcp_specific = { -+ .__select_window = __tcp_select_window, -+ .select_window = tcp_select_window, -+ .select_initial_window = tcp_select_initial_window, -+ .select_size = select_size, -+ .init_buffer_space = tcp_init_buffer_space, -+ .set_rto = tcp_set_rto, -+ .should_expand_sndbuf = tcp_should_expand_sndbuf, -+ .send_fin = tcp_send_fin, -+ .write_xmit = tcp_write_xmit, -+ .send_active_reset = tcp_send_active_reset, -+ .write_wakeup = tcp_write_wakeup, -+ .retransmit_timer = tcp_retransmit_timer, -+ .time_wait = tcp_time_wait, -+ .cleanup_rbuf = tcp_cleanup_rbuf, -+ .cwnd_validate = tcp_cwnd_validate, -+}; -+ - /* Address-family independent initialization for a tcp_sock. - * - * NOTE: A lot of things set to zero explicitly by call to -@@ -423,6 +442,11 @@ - sk->sk_sndbuf = sysctl_tcp_wmem[1]; - sk->sk_rcvbuf = sysctl_tcp_rmem[1]; - -+ tp->ops = &tcp_specific; -+ -+ /* Initialize MPTCP-specific stuff and function-pointers */ -+ mptcp_init_tcp_sock(sk); -+ - local_bh_disable(); - sk_sockets_allocated_inc(sk); - local_bh_enable(); -@@ -733,6 +757,7 @@ - int ret; - - sock_rps_record_flow(sk); -+ - /* - * We can't seek on a socket input - */ -@@ -743,6 +768,14 @@ - - lock_sock(sk); - -+#ifdef CONFIG_MPTCP -+ if (mptcp(tcp_sk(sk))) { -+ struct sock *sk_it; -+ mptcp_for_each_sk(tcp_sk(sk)->mpcb, sk_it) -+ sock_rps_record_flow(sk_it); -+ } -+#endif -+ - timeo = sock_rcvtimeo(sk, sock->file->f_flags & O_NONBLOCK); - while (tss.len) { - ret = __tcp_splice_read(sk, &tss); -@@ -846,8 +879,7 @@ - return NULL; - } - --static unsigned int tcp_xmit_size_goal(struct sock *sk, u32 mss_now, -- int large_allowed) -+unsigned int tcp_xmit_size_goal(struct sock *sk, u32 mss_now, int large_allowed) - { - struct tcp_sock *tp = tcp_sk(sk); - u32 new_size_goal, size_goal; -@@ -875,8 +907,13 @@ - { - int mss_now; - -- mss_now = tcp_current_mss(sk); -- *size_goal = tcp_xmit_size_goal(sk, mss_now, !(flags & MSG_OOB)); -+ if (mptcp(tcp_sk(sk))) { -+ mss_now = mptcp_current_mss(sk); -+ *size_goal = mptcp_xmit_size_goal(sk, mss_now, !(flags & MSG_OOB)); -+ } else { -+ mss_now = tcp_current_mss(sk); -+ *size_goal = tcp_xmit_size_goal(sk, mss_now, !(flags & MSG_OOB)); -+ } - - return mss_now; - } -@@ -895,12 +932,33 @@ - * is fully established. - */ - if (((1 << sk->sk_state) & ~(TCPF_ESTABLISHED | TCPF_CLOSE_WAIT)) && -- !tcp_passive_fastopen(sk)) { -+ !tcp_passive_fastopen(mptcp(tp) && tp->mpcb->master_sk ? -+ tp->mpcb->master_sk : sk)) { - err = sk_stream_wait_connect(sk, &timeo); - if (err != 0) - goto out_err; - } - -+ if (mptcp(tp)) { -+ struct sock *sk_it = sk; -+ -+ /* We must check this with socket-lock hold because we iterate -+ * over the subflows. -+ */ -+ if (!mptcp_can_sendpage(sk)) { -+ ssize_t ret; -+ -+ release_sock(sk); -+ ret = sock_no_sendpage(sk->sk_socket, page, offset, -+ size, flags); -+ lock_sock(sk); -+ return ret; -+ } -+ -+ mptcp_for_each_sk(tp->mpcb, sk_it) -+ sock_rps_record_flow(sk_it); -+ } -+ - sk_clear_bit(SOCKWQ_ASYNC_NOSPACE, sk); - - mss_now = tcp_send_mss(sk, &size_goal, flags); -@@ -1015,8 +1073,9 @@ - { - ssize_t res; - -- if (!(sk->sk_route_caps & NETIF_F_SG) || -- !sk_check_csum_caps(sk)) -+ /* If MPTCP is enabled, we check it later after establishment */ -+ if (!mptcp(tcp_sk(sk)) && (!(sk->sk_route_caps & NETIF_F_SG) || -+ !sk_check_csum_caps(sk))) - return sock_no_sendpage(sk->sk_socket, page, offset, size, - flags); - -@@ -1040,14 +1099,14 @@ - * This also speeds up tso_fragment(), since it wont fallback - * to tcp_fragment(). - */ --static int linear_payload_sz(bool first_skb) -+int linear_payload_sz(bool first_skb) - { - if (first_skb) - return SKB_WITH_OVERHEAD(2048 - MAX_TCP_HEADER); - return 0; - } - --static int select_size(const struct sock *sk, bool sg, bool first_skb) -+int select_size(const struct sock *sk, bool sg, bool first_skb) - { - const struct tcp_sock *tp = tcp_sk(sk); - int tmp = tp->mss_cache; -@@ -1135,12 +1194,19 @@ - * is fully established. - */ - if (((1 << sk->sk_state) & ~(TCPF_ESTABLISHED | TCPF_CLOSE_WAIT)) && -- !tcp_passive_fastopen(sk)) { -+ !tcp_passive_fastopen(mptcp(tp) && tp->mpcb->master_sk ? -+ tp->mpcb->master_sk : sk)) { - err = sk_stream_wait_connect(sk, &timeo); - if (err != 0) - goto do_error; - } - -+ if (mptcp(tp)) { -+ struct sock *sk_it = sk; -+ mptcp_for_each_sk(tp->mpcb, sk_it) -+ sock_rps_record_flow(sk_it); -+ } -+ - if (unlikely(tp->repair)) { - if (tp->repair_queue == TCP_RECV_QUEUE) { - copied = tcp_send_rcvq(sk, msg, size); -@@ -1176,7 +1242,10 @@ - if (sk->sk_err || (sk->sk_shutdown & SEND_SHUTDOWN)) - goto do_error; - -- sg = !!(sk->sk_route_caps & NETIF_F_SG); -+ if (mptcp(tp)) -+ sg = mptcp_can_sg(sk); -+ else -+ sg = !!(sk->sk_route_caps & NETIF_F_SG); - - while (msg_data_left(msg)) { - int copy = 0; -@@ -1205,7 +1274,7 @@ - } - first_skb = skb_queue_empty(&sk->sk_write_queue); - skb = sk_stream_alloc_skb(sk, -- select_size(sk, sg, first_skb), -+ tp->ops->select_size(sk, sg, first_skb), - sk->sk_allocation, - first_skb); - if (!skb) -@@ -1214,8 +1283,15 @@ - process_backlog = true; - /* - * Check whether we can use HW checksum. -+ * -+ * If dss-csum is enabled, we do not do hw-csum. -+ * In case of non-mptcp we check the -+ * device-capabilities. -+ * In case of mptcp, hw-csum's will be handled -+ * later in mptcp_write_xmit. - */ -- if (sk_check_csum_caps(sk)) -+ if (((mptcp(tp) && !tp->mpcb->dss_csum) || !mptcp(tp)) && -+ (mptcp(tp) || sk_check_csum_caps(sk))) - skb->ip_summed = CHECKSUM_PARTIAL; - - skb_entail(sk, skb); -@@ -1424,7 +1500,7 @@ - * calculation of whether or not we must ACK for the sake of - * a window update. - */ --static void tcp_cleanup_rbuf(struct sock *sk, int copied) -+void tcp_cleanup_rbuf(struct sock *sk, int copied) - { - struct tcp_sock *tp = tcp_sk(sk); - bool time_to_ack = false; -@@ -1467,7 +1543,7 @@ - - /* Optimize, __tcp_select_window() is not cheap. */ - if (2*rcv_window_now <= tp->window_clamp) { -- __u32 new_window = __tcp_select_window(sk); -+ __u32 new_window = tp->ops->__select_window(sk); - - /* Send ACK now, if this read freed lots of space - * in our buffer. Certainly, new_window is new window. -@@ -1597,7 +1673,7 @@ - /* Clean up data we have read: This will do ACK frames. */ - if (copied > 0) { - tcp_recv_skb(sk, seq, &offset); -- tcp_cleanup_rbuf(sk, copied); -+ tp->ops->cleanup_rbuf(sk, copied); - } - return copied; - } -@@ -1641,6 +1717,14 @@ - - lock_sock(sk); - -+#ifdef CONFIG_MPTCP -+ if (mptcp(tp)) { -+ struct sock *sk_it; -+ mptcp_for_each_sk(tp->mpcb, sk_it) -+ sock_rps_record_flow(sk_it); -+ } -+#endif -+ - err = -ENOTCONN; - if (sk->sk_state == TCP_LISTEN) - goto out; -@@ -1761,7 +1845,7 @@ - } - } - -- tcp_cleanup_rbuf(sk, copied); -+ tp->ops->cleanup_rbuf(sk, copied); - - if (!sysctl_tcp_low_latency && tp->ucopy.task == user_recv) { - /* Install new reader */ -@@ -1936,7 +2020,7 @@ - */ - - /* Clean up data we have read: This will do ACK frames. */ -- tcp_cleanup_rbuf(sk, copied); -+ tp->ops->cleanup_rbuf(sk, copied); - - release_sock(sk); - return copied; -@@ -2014,7 +2098,7 @@ - [TCP_NEW_SYN_RECV] = TCP_CLOSE, /* should not happen ! */ - }; - --static int tcp_close_state(struct sock *sk) -+int tcp_close_state(struct sock *sk) - { - int next = (int)new_state[sk->sk_state]; - int ns = next & TCP_STATE_MASK; -@@ -2044,7 +2128,7 @@ - TCPF_SYN_RECV | TCPF_CLOSE_WAIT)) { - /* Clear out any half completed packets. FIN if needed. */ - if (tcp_close_state(sk)) -- tcp_send_fin(sk); -+ tcp_sk(sk)->ops->send_fin(sk); - } - } - EXPORT_SYMBOL(tcp_shutdown); -@@ -2069,6 +2153,17 @@ - int data_was_unread = 0; - int state; - -+ if (is_meta_sk(sk)) { -+ /* TODO: Currently forcing timeout to 0 because -+ * sk_stream_wait_close will complain during lockdep because -+ * of the mpcb_mutex (circular lock dependency through -+ * inet_csk_listen_stop()). -+ * We should find a way to get rid of the mpcb_mutex. -+ */ -+ mptcp_close(sk, 0); -+ return; -+ } -+ - lock_sock(sk); - sk->sk_shutdown = SHUTDOWN_MASK; - -@@ -2113,7 +2208,7 @@ - /* Unread data was tossed, zap the connection. */ - NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPABORTONCLOSE); - tcp_set_state(sk, TCP_CLOSE); -- tcp_send_active_reset(sk, sk->sk_allocation); -+ tcp_sk(sk)->ops->send_active_reset(sk, sk->sk_allocation); - } else if (sock_flag(sk, SOCK_LINGER) && !sk->sk_lingertime) { - /* Check zero linger _after_ checking for unread data. */ - sk->sk_prot->disconnect(sk, 0); -@@ -2193,7 +2288,7 @@ - struct tcp_sock *tp = tcp_sk(sk); - if (tp->linger2 < 0) { - tcp_set_state(sk, TCP_CLOSE); -- tcp_send_active_reset(sk, GFP_ATOMIC); -+ tp->ops->send_active_reset(sk, GFP_ATOMIC); - __NET_INC_STATS(sock_net(sk), - LINUX_MIB_TCPABORTONLINGER); - } else { -@@ -2203,7 +2298,8 @@ - inet_csk_reset_keepalive_timer(sk, - tmo - TCP_TIMEWAIT_LEN); - } else { -- tcp_time_wait(sk, TCP_FIN_WAIT2, tmo); -+ tcp_sk(sk)->ops->time_wait(sk, TCP_FIN_WAIT2, -+ tmo); - goto out; - } - } -@@ -2212,7 +2308,7 @@ - sk_mem_reclaim(sk); - if (tcp_check_oom(sk, 0)) { - tcp_set_state(sk, TCP_CLOSE); -- tcp_send_active_reset(sk, GFP_ATOMIC); -+ tcp_sk(sk)->ops->send_active_reset(sk, GFP_ATOMIC); - __NET_INC_STATS(sock_net(sk), - LINUX_MIB_TCPABORTONMEMORY); - } else if (!check_net(sock_net(sk))) { -@@ -2240,15 +2336,6 @@ - } - EXPORT_SYMBOL(tcp_close); - --/* These states need RST on ABORT according to RFC793 */ -- --static inline bool tcp_need_reset(int state) --{ -- return (1 << state) & -- (TCPF_ESTABLISHED | TCPF_CLOSE_WAIT | TCPF_FIN_WAIT1 | -- TCPF_FIN_WAIT2 | TCPF_SYN_RECV); --} -- - int tcp_disconnect(struct sock *sk, int flags) - { - struct inet_sock *inet = inet_sk(sk); -@@ -2271,7 +2358,7 @@ - /* The last check adjusts for discrepancy of Linux wrt. RFC - * states - */ -- tcp_send_active_reset(sk, gfp_any()); -+ tp->ops->send_active_reset(sk, gfp_any()); - sk->sk_err = ECONNRESET; - } else if (old_state == TCP_SYN_SENT) - sk->sk_err = ECONNRESET; -@@ -2286,6 +2373,13 @@ - if (!(sk->sk_userlocks & SOCK_BINDADDR_LOCK)) - inet_reset_saddr(sk); - -+ if (is_meta_sk(sk)) { -+ mptcp_disconnect(sk); -+ } else { -+ if (tp->inside_tk_table) -+ mptcp_hash_remove_bh(tp); -+ } -+ - sk->sk_shutdown = 0; - sock_reset_flag(sk, SOCK_DONE); - tp->srtt_us = 0; -@@ -2329,7 +2423,8 @@ - static inline bool tcp_can_repair_sock(const struct sock *sk) - { - return ns_capable(sock_net(sk)->user_ns, CAP_NET_ADMIN) && -- ((1 << sk->sk_state) & (TCPF_CLOSE | TCPF_ESTABLISHED)); -+ ((1 << sk->sk_state) & (TCPF_CLOSE | TCPF_ESTABLISHED)) && -+ !sock_flag(sk, SOCK_MPTCP); - } - - static int tcp_repair_set_window(struct tcp_sock *tp, char __user *optbuf, int len) -@@ -2444,6 +2539,61 @@ - release_sock(sk); - return err; - } -+#ifdef CONFIG_MPTCP -+ case MPTCP_SCHEDULER: { -+ char name[MPTCP_SCHED_NAME_MAX]; -+ -+ if (optlen < 1) -+ return -EINVAL; -+ -+ /* Cannot be used if MPTCP is not used or we already have -+ * established an MPTCP-connection. -+ */ -+ if (mptcp_init_failed || !sysctl_mptcp_enabled || -+ sk->sk_state != TCP_CLOSE) -+ return -EPERM; -+ -+ val = strncpy_from_user(name, optval, -+ min_t(long, MPTCP_SCHED_NAME_MAX - 1, -+ optlen)); -+ -+ if (val < 0) -+ return -EFAULT; -+ name[val] = 0; -+ -+ lock_sock(sk); -+ err = mptcp_set_scheduler(sk, name); -+ release_sock(sk); -+ return err; -+ } -+ -+ case MPTCP_PATH_MANAGER: { -+ char name[MPTCP_PM_NAME_MAX]; -+ -+ if (optlen < 1) -+ return -EINVAL; -+ -+ /* Cannot be used if MPTCP is not used or we already have -+ * established an MPTCP-connection. -+ */ -+ if (mptcp_init_failed || !sysctl_mptcp_enabled || -+ sk->sk_state != TCP_CLOSE) -+ return -EPERM; -+ -+ val = strncpy_from_user(name, optval, -+ min_t(long, MPTCP_PM_NAME_MAX - 1, -+ optlen)); -+ -+ if (val < 0) -+ return -EFAULT; -+ name[val] = 0; -+ -+ lock_sock(sk); -+ err = mptcp_set_path_manager(sk, name); -+ release_sock(sk); -+ return err; -+ } -+#endif - default: - /* fallthru */ - break; -@@ -2625,6 +2775,12 @@ - break; - - case TCP_DEFER_ACCEPT: -+ /* An established MPTCP-connection (mptcp(tp) only returns true -+ * if the socket is established) should not use DEFER on new -+ * subflows. -+ */ -+ if (mptcp(tp)) -+ break; - /* Translate value in seconds to number of retransmits */ - icsk->icsk_accept_queue.rskq_defer_accept = - secs_to_retrans(val, TCP_TIMEOUT_INIT / HZ, -@@ -2652,7 +2808,7 @@ - (TCPF_ESTABLISHED | TCPF_CLOSE_WAIT) && - inet_csk_ack_scheduled(sk)) { - icsk->icsk_ack.pending |= ICSK_ACK_PUSHED; -- tcp_cleanup_rbuf(sk, 1); -+ tp->ops->cleanup_rbuf(sk, 1); - if (!(val & 1)) - icsk->icsk_ack.pingpong = 1; - } -@@ -2661,7 +2817,7 @@ - - #ifdef CONFIG_TCP_MD5SIG - case TCP_MD5SIG: -- if ((1 << sk->sk_state) & (TCPF_CLOSE | TCPF_LISTEN)) -+ if ((1 << sk->sk_state) & (TCPF_CLOSE | TCPF_LISTEN) && !sock_flag(sk, SOCK_MPTCP)) - err = tp->af_specific->md5_parse(sk, optval, optlen); - else - err = -EINVAL; -@@ -2700,6 +2856,32 @@ - tp->notsent_lowat = val; - sk->sk_write_space(sk); - break; -+#ifdef CONFIG_MPTCP -+ case MPTCP_ENABLED: -+ if (mptcp_init_failed || !sysctl_mptcp_enabled || -+ sk->sk_state != TCP_CLOSE -+#ifdef CONFIG_TCP_MD5SIG -+ || tp->md5sig_info -+#endif -+ ) { -+ err = -EPERM; -+ break; -+ } -+ -+ if (val) -+ mptcp_enable_sock(sk); -+ else -+ mptcp_disable_sock(sk); -+ break; -+ case MPTCP_INFO: -+ if (mptcp_init_failed || !sysctl_mptcp_enabled) { -+ err = -EPERM; -+ break; -+ } -+ -+ tp->record_master_info = !!(val & MPTCP_INFO_FLAG_SAVE_MASTER); -+ break; -+#endif - default: - err = -ENOPROTOOPT; - break; -@@ -3042,6 +3224,75 @@ - } - return 0; - } -+#ifdef CONFIG_MPTCP -+ case MPTCP_SCHEDULER: -+ if (get_user(len, optlen)) -+ return -EFAULT; -+ len = min_t(unsigned int, len, MPTCP_SCHED_NAME_MAX); -+ if (put_user(len, optlen)) -+ return -EFAULT; -+ -+ if (mptcp(tcp_sk(sk))) { -+ struct mptcp_cb *mpcb = tcp_sk(mptcp_meta_sk(sk))->mpcb; -+ -+ if (copy_to_user(optval, mpcb->sched_ops->name, len)) -+ return -EFAULT; -+ } else { -+ if (copy_to_user(optval, tcp_sk(sk)->mptcp_sched_name, -+ len)) -+ return -EFAULT; -+ } -+ return 0; -+ -+ case MPTCP_PATH_MANAGER: -+ if (get_user(len, optlen)) -+ return -EFAULT; -+ len = min_t(unsigned int, len, MPTCP_PM_NAME_MAX); -+ if (put_user(len, optlen)) -+ return -EFAULT; -+ -+ if (mptcp(tcp_sk(sk))) { -+ struct mptcp_cb *mpcb = tcp_sk(mptcp_meta_sk(sk))->mpcb; -+ -+ if (copy_to_user(optval, mpcb->pm_ops->name, len)) -+ return -EFAULT; -+ } else { -+ if (copy_to_user(optval, tcp_sk(sk)->mptcp_pm_name, -+ len)) -+ return -EFAULT; -+ } -+ return 0; -+ -+ case MPTCP_ENABLED: -+ if (sk->sk_state != TCP_SYN_SENT) -+ val = mptcp(tp) ? 1 : 0; -+ else -+ val = sock_flag(sk, SOCK_MPTCP) ? 1 : 0; -+ break; -+ case MPTCP_INFO: -+ { -+ int ret; -+ -+ if (!mptcp(tp)) -+ return -EINVAL; -+ -+ if (get_user(len, optlen)) -+ return -EFAULT; -+ -+ len = min_t(unsigned int, len, sizeof(struct mptcp_info)); -+ -+ lock_sock(sk); -+ ret = mptcp_get_info(sk, optval, len); -+ release_sock(sk); -+ -+ if (ret) -+ return ret; -+ -+ if (put_user(len, optlen)) -+ return -EFAULT; -+ return 0; -+ } -+#endif - default: - return -ENOPROTOOPT; - } -@@ -3216,7 +3467,9 @@ - if (sk->sk_state == TCP_SYN_SENT || sk->sk_state == TCP_SYN_RECV) - TCP_INC_STATS(sock_net(sk), TCP_MIB_ATTEMPTFAILS); - -+ WARN_ON(sk->sk_state == TCP_CLOSE); - tcp_set_state(sk, TCP_CLOSE); -+ - tcp_clear_xmit_timers(sk); - if (req) - reqsk_fastopen_remove(sk, req, false); -@@ -3232,6 +3485,8 @@ - - int tcp_abort(struct sock *sk, int err) - { -+ struct sock *meta_sk = mptcp(tcp_sk(sk)) ? mptcp_meta_sk(sk) : sk; -+ - if (!sk_fullsock(sk)) { - if (sk->sk_state == TCP_NEW_SYN_RECV) { - struct request_sock *req = inet_reqsk(sk); -@@ -3245,7 +3500,7 @@ - } - - /* Don't race with userspace socket closes such as tcp_close. */ -- lock_sock(sk); -+ lock_sock(meta_sk); - - if (sk->sk_state == TCP_LISTEN) { - tcp_set_state(sk, TCP_CLOSE); -@@ -3254,7 +3509,7 @@ - - /* Don't race with BH socket closes such as inet_csk_listen_stop. */ - local_bh_disable(); -- bh_lock_sock(sk); -+ bh_lock_sock(meta_sk); - - if (!sock_flag(sk, SOCK_DEAD)) { - sk->sk_err = err; -@@ -3262,13 +3517,13 @@ - smp_wmb(); - sk->sk_error_report(sk); - if (tcp_need_reset(sk->sk_state)) -- tcp_send_active_reset(sk, GFP_ATOMIC); -+ tcp_sk(sk)->ops->send_active_reset(sk, GFP_ATOMIC); - tcp_done(sk); - } - -- bh_unlock_sock(sk); -+ bh_unlock_sock(meta_sk); - local_bh_enable(); -- release_sock(sk); -+ release_sock(meta_sk); - return 0; - } - EXPORT_SYMBOL_GPL(tcp_abort); -diff -aurN linux-4.9.162/net/ipv4/tcp_fastopen.c mptcp-mptcp_v0.93/net/ipv4/tcp_fastopen.c ---- linux-4.9.162/net/ipv4/tcp_fastopen.c 2019-03-05 17:57:07.000000000 +0100 -+++ mptcp-mptcp_v0.93/net/ipv4/tcp_fastopen.c 2019-03-14 14:02:32.000000000 +0100 -@@ -8,6 +8,7 @@ - #include - #include - #include -+#include - - int sysctl_tcp_fastopen __read_mostly = TFO_CLIENT_ENABLE; - -@@ -176,8 +177,9 @@ - { - struct tcp_sock *tp; - struct request_sock_queue *queue = &inet_csk(sk)->icsk_accept_queue; -- struct sock *child; -+ struct sock *child, *meta_sk; - bool own_req; -+ int ret; - - req->num_retrans = 0; - req->num_timeout = 0; -@@ -216,19 +218,30 @@ - - atomic_set(&req->rsk_refcnt, 2); - -- /* Now finish processing the fastopen child socket. */ -- inet_csk(child)->icsk_af_ops->rebuild_header(child); -- tcp_init_congestion_control(child); -- tcp_mtup_init(child); -- tcp_init_metrics(child); -- tcp_init_buffer_space(child); -- - tp->rcv_nxt = TCP_SKB_CB(skb)->seq + 1; - - tcp_fastopen_add_skb(child, skb); - - tcp_rsk(req)->rcv_nxt = tp->rcv_nxt; - tp->rcv_wup = tp->rcv_nxt; -+ -+ meta_sk = child; -+ ret = mptcp_check_req_fastopen(meta_sk, req); -+ if (ret < 0) -+ return NULL; -+ -+ if (ret == 0) { -+ child = tcp_sk(meta_sk)->mpcb->master_sk; -+ tp = tcp_sk(child); -+ } -+ -+ /* Now finish processing the fastopen child socket. */ -+ inet_csk(child)->icsk_af_ops->rebuild_header(child); -+ tcp_init_congestion_control(child); -+ tcp_mtup_init(child); -+ tcp_init_metrics(child); -+ tp->ops->init_buffer_space(child); -+ - /* tcp_conn_request() is sending the SYNACK, - * and queues the child into listener accept queue. - */ -diff -aurN linux-4.9.162/net/ipv4/tcp_input.c mptcp-mptcp_v0.93/net/ipv4/tcp_input.c ---- linux-4.9.162/net/ipv4/tcp_input.c 2019-03-05 17:57:07.000000000 +0100 -+++ mptcp-mptcp_v0.93/net/ipv4/tcp_input.c 2019-03-14 14:02:32.000000000 +0100 -@@ -75,6 +75,9 @@ - #include - #include - #include -+#include -+#include -+#include - - int sysctl_tcp_timestamps __read_mostly = 1; - int sysctl_tcp_window_scaling __read_mostly = 1; -@@ -101,27 +104,6 @@ - int sysctl_tcp_early_retrans __read_mostly = 3; - int sysctl_tcp_invalid_ratelimit __read_mostly = HZ/2; - --#define FLAG_DATA 0x01 /* Incoming frame contained data. */ --#define FLAG_WIN_UPDATE 0x02 /* Incoming ACK was a window update. */ --#define FLAG_DATA_ACKED 0x04 /* This ACK acknowledged new data. */ --#define FLAG_RETRANS_DATA_ACKED 0x08 /* "" "" some of which was retransmitted. */ --#define FLAG_SYN_ACKED 0x10 /* This ACK acknowledged SYN. */ --#define FLAG_DATA_SACKED 0x20 /* New SACK. */ --#define FLAG_ECE 0x40 /* ECE in this ACK */ --#define FLAG_LOST_RETRANS 0x80 /* This ACK marks some retransmission lost */ --#define FLAG_SLOWPATH 0x100 /* Do not skip RFC checks for window update.*/ --#define FLAG_ORIG_SACK_ACKED 0x200 /* Never retransmitted data are (s)acked */ --#define FLAG_SND_UNA_ADVANCED 0x400 /* Snd_una was changed (!= FLAG_DATA_ACKED) */ --#define FLAG_DSACKING_ACK 0x800 /* SACK blocks contained D-SACK info */ --#define FLAG_SACK_RENEGING 0x2000 /* snd_una advanced to a sacked seq */ --#define FLAG_UPDATE_TS_RECENT 0x4000 /* tcp_replace_ts_recent() */ --#define FLAG_NO_CHALLENGE_ACK 0x8000 /* do not call tcp_send_challenge_ack() */ -- --#define FLAG_ACKED (FLAG_DATA_ACKED|FLAG_SYN_ACKED) --#define FLAG_NOT_DUP (FLAG_DATA|FLAG_WIN_UPDATE|FLAG_ACKED) --#define FLAG_CA_ALERT (FLAG_DATA_SACKED|FLAG_ECE) --#define FLAG_FORWARD_PROGRESS (FLAG_ACKED|FLAG_DATA_SACKED) -- - #define TCP_REMNANT (TCP_FLAG_FIN|TCP_FLAG_URG|TCP_FLAG_SYN|TCP_FLAG_PSH) - #define TCP_HP_BITS (~(TCP_RESERVED_BITS|TCP_FLAG_PSH)) - -@@ -329,8 +311,12 @@ - per_mss = roundup_pow_of_two(per_mss) + - SKB_DATA_ALIGN(sizeof(struct sk_buff)); - -- nr_segs = max_t(u32, TCP_INIT_CWND, tp->snd_cwnd); -- nr_segs = max_t(u32, nr_segs, tp->reordering + 1); -+ if (mptcp(tp)) { -+ nr_segs = mptcp_check_snd_buf(tp); -+ } else { -+ nr_segs = max_t(u32, TCP_INIT_CWND, tp->snd_cwnd); -+ nr_segs = max_t(u32, nr_segs, tp->reordering + 1); -+ } - - /* Fast Recovery (RFC 5681 3.2) : - * Cubic needs 1.7 factor, rounded to 2 to include -@@ -339,8 +325,16 @@ - sndmem = ca_ops->sndbuf_expand ? ca_ops->sndbuf_expand(sk) : 2; - sndmem *= nr_segs * per_mss; - -- if (sk->sk_sndbuf < sndmem) -+ /* MPTCP: after this sndmem is the new contribution of the -+ * current subflow to the aggregated sndbuf */ -+ if (sk->sk_sndbuf < sndmem) { -+ int old_sndbuf = sk->sk_sndbuf; - sk->sk_sndbuf = min(sndmem, sysctl_tcp_wmem[2]); -+ /* MPTCP: ok, the subflow sndbuf has grown, reflect -+ * this in the aggregate buffer.*/ -+ if (mptcp(tp) && old_sndbuf != sk->sk_sndbuf) -+ mptcp_update_sndbuf(tp); -+ } - } - - /* 2. Tuning advertised window (window_clamp, rcv_ssthresh) -@@ -389,10 +383,15 @@ - static void tcp_grow_window(struct sock *sk, const struct sk_buff *skb) - { - struct tcp_sock *tp = tcp_sk(sk); -+ struct sock *meta_sk = mptcp(tp) ? mptcp_meta_sk(sk) : sk; -+ struct tcp_sock *meta_tp = tcp_sk(meta_sk); -+ -+ if (is_meta_sk(sk)) -+ return; - - /* Check #1 */ -- if (tp->rcv_ssthresh < tp->window_clamp && -- (int)tp->rcv_ssthresh < tcp_space(sk) && -+ if (meta_tp->rcv_ssthresh < meta_tp->window_clamp && -+ (int)meta_tp->rcv_ssthresh < tcp_space(meta_sk) && - !tcp_under_memory_pressure(sk)) { - int incr; - -@@ -400,14 +399,14 @@ - * will fit to rcvbuf in future. - */ - if (tcp_win_from_space(skb->truesize) <= skb->len) -- incr = 2 * tp->advmss; -+ incr = 2 * meta_tp->advmss; - else -- incr = __tcp_grow_window(sk, skb); -+ incr = __tcp_grow_window(meta_sk, skb); - - if (incr) { - incr = max_t(int, incr, 2 * skb->len); -- tp->rcv_ssthresh = min(tp->rcv_ssthresh + incr, -- tp->window_clamp); -+ meta_tp->rcv_ssthresh = min(meta_tp->rcv_ssthresh + incr, -+ meta_tp->window_clamp); - inet_csk(sk)->icsk_ack.quick |= 1; - } - } -@@ -590,7 +589,10 @@ - int time; - - time = tcp_time_stamp - tp->rcvq_space.time; -- if (time < (tp->rcv_rtt_est.rtt >> 3) || tp->rcv_rtt_est.rtt == 0) -+ if (mptcp(tp)) { -+ if (mptcp_check_rtt(tp, time)) -+ return; -+ } else if (time < (tp->rcv_rtt_est.rtt >> 3) || tp->rcv_rtt_est.rtt == 0) - return; - - /* Number of bytes copied to user in last RTT */ -@@ -826,7 +828,7 @@ - /* Calculate rto without backoff. This is the second half of Van Jacobson's - * routine referred to above. - */ --static void tcp_set_rto(struct sock *sk) -+void tcp_set_rto(struct sock *sk) - { - const struct tcp_sock *tp = tcp_sk(sk); - /* Old crap is replaced with new one. 8) -@@ -1402,7 +1404,11 @@ - int len; - int in_sack; - -- if (!sk_can_gso(sk)) -+ /* For MPTCP we cannot shift skb-data and remove one skb from the -+ * send-queue, because this will make us loose the DSS-option (which -+ * is stored in TCP_SKB_CB(skb)->dss) of the skb we are removing. -+ */ -+ if (!sk_can_gso(sk) || mptcp(tp)) - goto fallback; - - /* Normally R but no L won't result in plain S */ -@@ -2990,7 +2996,7 @@ - */ - tcp_update_rtt_min(sk, ca_rtt_us); - tcp_rtt_estimator(sk, seq_rtt_us); -- tcp_set_rto(sk); -+ tp->ops->set_rto(sk); - - /* RFC6298: only reset backoff on valid RTT measurement. */ - inet_csk(sk)->icsk_backoff = 0; -@@ -3075,7 +3081,7 @@ - } - - /* If we get here, the whole TSO packet has not been acked. */ --static u32 tcp_tso_acked(struct sock *sk, struct sk_buff *skb) -+u32 tcp_tso_acked(struct sock *sk, struct sk_buff *skb) - { - struct tcp_sock *tp = tcp_sk(sk); - u32 packets_acked; -@@ -3198,6 +3204,8 @@ - */ - if (likely(!(scb->tcp_flags & TCPHDR_SYN))) { - flag |= FLAG_DATA_ACKED; -+ if (mptcp(tp) && mptcp_is_data_seq(skb)) -+ flag |= MPTCP_FLAG_DATA_ACKED; - } else { - flag |= FLAG_SYN_ACKED; - tp->retrans_stamp = 0; -@@ -3308,7 +3316,7 @@ - return flag; - } - --static void tcp_ack_probe(struct sock *sk) -+void tcp_ack_probe(struct sock *sk) - { - const struct tcp_sock *tp = tcp_sk(sk); - struct inet_connection_sock *icsk = inet_csk(sk); -@@ -3378,9 +3386,8 @@ - /* Check that window update is acceptable. - * The function assumes that snd_una<=ack<=snd_next. - */ --static inline bool tcp_may_update_window(const struct tcp_sock *tp, -- const u32 ack, const u32 ack_seq, -- const u32 nwin) -+bool tcp_may_update_window(const struct tcp_sock *tp, const u32 ack, -+ const u32 ack_seq, const u32 nwin) - { - return after(ack, tp->snd_una) || - after(ack_seq, tp->snd_wl1) || -@@ -3604,7 +3611,7 @@ - } - - /* This routine deals with incoming acks, but not outgoing ones. */ --static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag) -+static int tcp_ack(struct sock *sk, struct sk_buff *skb, int flag) - { - struct inet_connection_sock *icsk = inet_csk(sk); - struct tcp_sock *tp = tcp_sk(sk); -@@ -3718,6 +3725,16 @@ - flag |= tcp_clean_rtx_queue(sk, prior_fackets, prior_snd_una, &acked, - &sack_state, &now); - -+ if (mptcp(tp)) { -+ if (mptcp_fallback_infinite(sk, flag)) { -+ pr_err("%s resetting flow\n", __func__); -+ mptcp_send_reset(sk); -+ goto invalid_ack; -+ } -+ -+ mptcp_clean_rtx_infinite(skb, sk); -+ } -+ - if (tcp_ack_is_dubious(sk, flag)) { - is_dupack = !(flag & (FLAG_SND_UNA_ADVANCED | FLAG_NOT_DUP)); - tcp_fastretrans_alert(sk, acked, is_dupack, &flag, &rexmit); -@@ -3796,8 +3813,10 @@ - * the fast version below fails. - */ - void tcp_parse_options(const struct sk_buff *skb, -- struct tcp_options_received *opt_rx, int estab, -- struct tcp_fastopen_cookie *foc) -+ struct tcp_options_received *opt_rx, -+ struct mptcp_options_received *mopt, -+ int estab, struct tcp_fastopen_cookie *foc, -+ struct tcp_sock *tp) - { - const unsigned char *ptr; - const struct tcphdr *th = tcp_hdr(skb); -@@ -3880,6 +3899,10 @@ - */ - break; - #endif -+ case TCPOPT_MPTCP: -+ mptcp_parse_options(ptr - 2, opsize, mopt, skb, tp); -+ break; -+ - case TCPOPT_FASTOPEN: - tcp_parse_fastopen_option( - opsize - TCPOLEN_FASTOPEN_BASE, -@@ -3942,8 +3965,8 @@ - if (tcp_parse_aligned_timestamp(tp, th)) - return true; - } -- -- tcp_parse_options(skb, &tp->rx_opt, 1, NULL); -+ tcp_parse_options(skb, &tp->rx_opt, -+ mptcp(tp) ? &tp->mptcp->rx_opt : NULL, 1, NULL, tp); - if (tp->rx_opt.saw_tstamp && tp->rx_opt.rcv_tsecr) - tp->rx_opt.rcv_tsecr -= tp->tsoffset; - -@@ -4099,6 +4122,11 @@ - { - struct tcp_sock *tp = tcp_sk(sk); - -+ if (is_meta_sk(sk)) { -+ mptcp_fin(sk); -+ return; -+ } -+ - inet_csk_schedule_ack(sk); - - sk->sk_shutdown |= RCV_SHUTDOWN; -@@ -4109,6 +4137,10 @@ - case TCP_ESTABLISHED: - /* Move to CLOSE_WAIT */ - tcp_set_state(sk, TCP_CLOSE_WAIT); -+ -+ if (mptcp(tp)) -+ mptcp_sub_close_passive(sk); -+ - inet_csk(sk)->icsk_ack.pingpong = 1; - break; - -@@ -4131,9 +4163,16 @@ - tcp_set_state(sk, TCP_CLOSING); - break; - case TCP_FIN_WAIT2: -+ if (mptcp(tp)) { -+ /* The socket will get closed by mptcp_data_ready. -+ * We first have to process all data-sequences. -+ */ -+ tp->close_it = 1; -+ break; -+ } - /* Received a FIN -- send ACK and enter TIME_WAIT. */ - tcp_send_ack(sk); -- tcp_time_wait(sk, TCP_TIME_WAIT, 0); -+ tp->ops->time_wait(sk, TCP_TIME_WAIT, 0); - break; - default: - /* Only TCP_LISTEN and TCP_CLOSE are left, in these -@@ -4155,6 +4194,10 @@ - if (!sock_flag(sk, SOCK_DEAD)) { - sk->sk_state_change(sk); - -+ /* Don't wake up MPTCP-subflows */ -+ if (mptcp(tp)) -+ return; -+ - /* Do not send POLL_HUP for half duplex close. */ - if (sk->sk_shutdown == SHUTDOWN_MASK || - sk->sk_state == TCP_CLOSE) -@@ -4345,15 +4388,16 @@ - * Better try to coalesce them right now to avoid future collapses. - * Returns true if caller should free @from instead of queueing it - */ --static bool tcp_try_coalesce(struct sock *sk, -- struct sk_buff *to, -- struct sk_buff *from, -- bool *fragstolen) -+bool tcp_try_coalesce(struct sock *sk, struct sk_buff *to, struct sk_buff *from, -+ bool *fragstolen) - { - int delta; - - *fragstolen = false; - -+ if (mptcp(tcp_sk(sk)) && !is_meta_sk(sk)) -+ return false; -+ - /* Its possible this segment overlaps with prior segment in queue */ - if (TCP_SKB_CB(from)->seq != TCP_SKB_CB(to)->end_seq) - return false; -@@ -4396,7 +4440,7 @@ - /* This one checks to see if we can put data from the - * out_of_order queue into the receive_queue. - */ --static void tcp_ofo_queue(struct sock *sk) -+void tcp_ofo_queue(struct sock *sk) - { - struct tcp_sock *tp = tcp_sk(sk); - __u32 dsack_high = tp->rcv_nxt; -@@ -4419,7 +4463,14 @@ - p = rb_next(p); - rb_erase(&skb->rbnode, &tp->out_of_order_queue); - -- if (unlikely(!after(TCP_SKB_CB(skb)->end_seq, tp->rcv_nxt))) { -+ /* In case of MPTCP, the segment may be empty if it's a -+ * non-data DATA_FIN. (see beginning of tcp_data_queue) -+ * -+ * But this only holds true for subflows, not for the -+ * meta-socket. -+ */ -+ if (unlikely(!after(TCP_SKB_CB(skb)->end_seq, tp->rcv_nxt) && -+ (is_meta_sk(sk) || !mptcp(tp) || TCP_SKB_CB(skb)->end_seq != TCP_SKB_CB(skb)->seq))) { - SOCK_DEBUG(sk, "ofo packet was already received\n"); - tcp_drop(sk, skb); - continue; -@@ -4453,6 +4504,9 @@ - static int tcp_try_rmem_schedule(struct sock *sk, struct sk_buff *skb, - unsigned int size) - { -+ if (mptcp(tcp_sk(sk))) -+ sk = mptcp_meta_sk(sk); -+ - if (atomic_read(&sk->sk_rmem_alloc) > sk->sk_rcvbuf || - !sk_rmem_schedule(sk, skb, size)) { - -@@ -4467,7 +4521,7 @@ - return 0; - } - --static void tcp_data_queue_ofo(struct sock *sk, struct sk_buff *skb) -+void tcp_data_queue_ofo(struct sock *sk, struct sk_buff *skb) - { - struct tcp_sock *tp = tcp_sk(sk); - struct rb_node **p, *parent; -@@ -4535,7 +4589,8 @@ - continue; - } - if (before(seq, TCP_SKB_CB(skb1)->end_seq)) { -- if (!after(end_seq, TCP_SKB_CB(skb1)->end_seq)) { -+ if (!after(end_seq, TCP_SKB_CB(skb1)->end_seq) && -+ (is_meta_sk(sk) || !mptcp(tp) || end_seq != seq)) { - /* All the bits are present. Drop. */ - NET_INC_STATS(sock_net(sk), - LINUX_MIB_TCPOFOMERGE); -@@ -4582,6 +4637,11 @@ - end_seq); - break; - } -+ /* MPTCP allows non-data data-fin to be in the ofo-queue */ -+ if (mptcp(tp) && !is_meta_sk(sk) && TCP_SKB_CB(skb1)->seq == TCP_SKB_CB(skb1)->end_seq) { -+ skb = skb1; -+ continue; -+ } - rb_erase(&skb1->rbnode, &tp->out_of_order_queue); - tcp_dsack_extend(sk, TCP_SKB_CB(skb1)->seq, - TCP_SKB_CB(skb1)->end_seq); -@@ -4593,7 +4653,7 @@ - tp->ooo_last_skb = skb; - - add_sack: -- if (tcp_is_sack(tp)) -+ if (tcp_is_sack(tp) && seq != end_seq) - tcp_sack_new_ofo_skb(sk, seq, end_seq); - end: - if (skb) { -@@ -4602,8 +4662,8 @@ - } - } - --static int __must_check tcp_queue_rcv(struct sock *sk, struct sk_buff *skb, int hdrlen, -- bool *fragstolen) -+int __must_check tcp_queue_rcv(struct sock *sk, struct sk_buff *skb, int hdrlen, -+ bool *fragstolen) - { - int eaten; - struct sk_buff *tail = skb_peek_tail(&sk->sk_receive_queue); -@@ -4675,10 +4735,14 @@ - bool fragstolen = false; - int eaten = -1; - -- if (TCP_SKB_CB(skb)->seq == TCP_SKB_CB(skb)->end_seq) { -+ /* If no data is present, but a data_fin is in the options, we still -+ * have to call mptcp_queue_skb later on. */ -+ if (TCP_SKB_CB(skb)->seq == TCP_SKB_CB(skb)->end_seq && -+ !(mptcp(tp) && mptcp_is_data_fin(skb))) { - __kfree_skb(skb); - return; - } -+ - skb_dst_drop(skb); - __skb_pull(skb, tcp_hdr(skb)->doff * 4); - -@@ -4722,7 +4786,7 @@ - eaten = tcp_queue_rcv(sk, skb, 0, &fragstolen); - } - tcp_rcv_nxt_update(tp, TCP_SKB_CB(skb)->end_seq); -- if (skb->len) -+ if (skb->len || mptcp_is_data_fin(skb)) - tcp_event_data_recv(sk, skb); - if (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN) - tcp_fin(sk); -@@ -4744,7 +4808,11 @@ - - if (eaten > 0) - kfree_skb_partial(skb, fragstolen); -- if (!sock_flag(sk, SOCK_DEAD)) -+ if (!sock_flag(sk, SOCK_DEAD) || mptcp(tp)) -+ /* MPTCP: we always have to call data_ready, because -+ * we may be about to receive a data-fin, which still -+ * must get queued. -+ */ - sk->sk_data_ready(sk); - return; - } -@@ -5083,7 +5151,29 @@ - return -1; - } - --static bool tcp_should_expand_sndbuf(const struct sock *sk) -+/* RFC2861, slow part. Adjust cwnd, after it was not full during one rto. -+ * As additional protections, we do not touch cwnd in retransmission phases, -+ * and if application hit its sndbuf limit recently. -+ */ -+void tcp_cwnd_application_limited(struct sock *sk) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ -+ if (inet_csk(sk)->icsk_ca_state == TCP_CA_Open && -+ sk->sk_socket && !test_bit(SOCK_NOSPACE, &sk->sk_socket->flags)) { -+ /* Limited by application or receiver window. */ -+ u32 init_win = tcp_init_cwnd(tp, __sk_dst_get(sk)); -+ u32 win_used = max(tp->snd_cwnd_used, init_win); -+ if (win_used < tp->snd_cwnd) { -+ tp->snd_ssthresh = tcp_current_ssthresh(sk); -+ tp->snd_cwnd = (tp->snd_cwnd + win_used) >> 1; -+ } -+ tp->snd_cwnd_used = 0; -+ } -+ tp->snd_cwnd_stamp = tcp_time_stamp; -+} -+ -+bool tcp_should_expand_sndbuf(const struct sock *sk) - { - const struct tcp_sock *tp = tcp_sk(sk); - -@@ -5118,7 +5208,7 @@ - { - struct tcp_sock *tp = tcp_sk(sk); - -- if (tcp_should_expand_sndbuf(sk)) { -+ if (tp->ops->should_expand_sndbuf(sk)) { - tcp_sndbuf_expand(sk); - tp->snd_cwnd_stamp = tcp_time_stamp; - } -@@ -5132,8 +5222,9 @@ - sock_reset_flag(sk, SOCK_QUEUE_SHRUNK); - /* pairs with tcp_poll() */ - smp_mb(); -- if (sk->sk_socket && -- test_bit(SOCK_NOSPACE, &sk->sk_socket->flags)) -+ if (mptcp(tcp_sk(sk)) || -+ (sk->sk_socket && -+ test_bit(SOCK_NOSPACE, &sk->sk_socket->flags))) - tcp_new_space(sk); - } - } -@@ -5156,7 +5247,7 @@ - /* ... and right edge of window advances far enough. - * (tcp_recvmsg() will send ACK otherwise). Or... - */ -- __tcp_select_window(sk) >= tp->rcv_wnd) || -+ tp->ops->__select_window(sk) >= tp->rcv_wnd) || - /* We ACK each frame or... */ - tcp_in_quickack_mode(sk) || - /* We have out of order data. */ -@@ -5258,6 +5349,10 @@ - { - struct tcp_sock *tp = tcp_sk(sk); - -+ /* MPTCP urgent data is not yet supported */ -+ if (mptcp(tp)) -+ return; -+ - /* Check if we get a new urgent pointer - normally not. */ - if (th->urg) - tcp_check_urg(sk, th); -@@ -5389,9 +5484,15 @@ - goto discard; - } - -+ /* If valid: post process the received MPTCP options. */ -+ if (mptcp(tp) && mptcp_handle_options(sk, th, skb)) -+ goto discard; -+ - return true; - - discard: -+ if (mptcp(tp)) -+ mptcp_reset_mopt(tp); - tcp_drop(sk, skb); - return false; - } -@@ -5443,6 +5544,10 @@ - - tp->rx_opt.saw_tstamp = 0; - -+ /* MPTCP: force slowpath. */ -+ if (mptcp(tp)) -+ goto slow_path; -+ - /* pred_flags is 0xS?10 << 16 + snd_wnd - * if header_prediction is to be made - * 'S' will always be tp->tcp_header_len >> 2 -@@ -5640,7 +5745,7 @@ - */ - tp->lsndtime = tcp_time_stamp; - -- tcp_init_buffer_space(sk); -+ tp->ops->init_buffer_space(sk); - - if (sock_flag(sk, SOCK_KEEPOPEN)) - inet_csk_reset_keepalive_timer(sk, keepalive_time_when(tp)); -@@ -5656,7 +5761,8 @@ - struct tcp_fastopen_cookie *cookie) - { - struct tcp_sock *tp = tcp_sk(sk); -- struct sk_buff *data = tp->syn_data ? tcp_write_queue_head(sk) : NULL; -+ struct sock *meta_sk = mptcp(tp) ? mptcp_meta_sk(sk) : sk; -+ struct sk_buff *data = tp->syn_data ? tcp_write_queue_head(meta_sk) : NULL; - u16 mss = tp->rx_opt.mss_clamp, try_exp = 0; - bool syn_drop = false; - -@@ -5666,7 +5772,7 @@ - /* Get original SYNACK MSS value if user MSS sets mss_clamp */ - tcp_clear_options(&opt); - opt.user_mss = opt.mss_clamp = 0; -- tcp_parse_options(synack, &opt, 0, NULL); -+ tcp_parse_options(synack, &opt, NULL, 0, NULL, NULL); - mss = opt.mss_clamp; - } - -@@ -5690,7 +5796,11 @@ - - tcp_fastopen_cache_set(sk, mss, cookie, syn_drop, try_exp); - -- if (data) { /* Retransmit unacked data in SYN */ -+ /* In mptcp case, we do not rely on "retransmit", but instead on -+ * "transmit", because if fastopen data is not acked, the retransmission -+ * becomes the first MPTCP data (see mptcp_rcv_synsent_fastopen). -+ */ -+ if (data && !mptcp(tp)) { /* Retransmit unacked data in SYN */ - tcp_for_write_queue_from(data, sk) { - if (data == tcp_send_head(sk) || - __tcp_retransmit_skb(sk, data, 1)) -@@ -5718,9 +5828,13 @@ - struct tcp_sock *tp = tcp_sk(sk); - struct tcp_fastopen_cookie foc = { .len = -1 }; - int saved_clamp = tp->rx_opt.mss_clamp; -+ struct mptcp_options_received mopt; - bool fastopen_fail; - -- tcp_parse_options(skb, &tp->rx_opt, 0, &foc); -+ mptcp_init_mp_opt(&mopt); -+ -+ tcp_parse_options(skb, &tp->rx_opt, -+ mptcp(tp) ? &tp->mptcp->rx_opt : &mopt, 0, &foc, tp); - if (tp->rx_opt.saw_tstamp && tp->rx_opt.rcv_tsecr) - tp->rx_opt.rcv_tsecr -= tp->tsoffset; - -@@ -5780,6 +5894,35 @@ - tcp_init_wl(tp, TCP_SKB_CB(skb)->seq); - tcp_ack(sk, skb, FLAG_SLOWPATH); - -+ if (tp->request_mptcp || mptcp(tp)) { -+ int ret; -+ -+ rcu_read_lock(); -+ local_bh_disable(); -+ ret = mptcp_rcv_synsent_state_process(sk, &sk, -+ skb, &mopt); -+ local_bh_enable(); -+ rcu_read_unlock(); -+ -+ /* May have changed if we support MPTCP */ -+ tp = tcp_sk(sk); -+ icsk = inet_csk(sk); -+ -+ if (ret == 1) -+ goto reset_and_undo; -+ if (ret == 2) -+ goto discard; -+ } -+ -+ if (mptcp(tp) && !is_master_tp(tp)) { -+ /* Timer for repeating the ACK until an answer -+ * arrives. Used only when establishing an additional -+ * subflow inside of an MPTCP connection. -+ */ -+ sk_reset_timer(sk, &tp->mptcp->mptcp_ack_timer, -+ jiffies + icsk->icsk_rto); -+ } -+ - /* Ok.. it's good. Set up sequence numbers and - * move to established. - */ -@@ -5806,6 +5949,11 @@ - tp->tcp_header_len = sizeof(struct tcphdr); - } - -+ if (mptcp(tp)) { -+ tp->tcp_header_len += MPTCP_SUB_LEN_DSM_ALIGN; -+ tp->advmss -= MPTCP_SUB_LEN_DSM_ALIGN; -+ } -+ - if (tcp_is_sack(tp) && sysctl_tcp_fack) - tcp_enable_fack(tp); - -@@ -5831,9 +5979,12 @@ - } - if (fastopen_fail) - return -1; -- if (sk->sk_write_pending || -+ /* With MPTCP we cannot send data on the third ack due to the -+ * lack of option-space to combine with an MP_CAPABLE. -+ */ -+ if (!mptcp(tp) && (sk->sk_write_pending || - icsk->icsk_accept_queue.rskq_defer_accept || -- icsk->icsk_ack.pingpong) { -+ icsk->icsk_ack.pingpong)) { - /* Save one ACK. Data will be ready after - * several ticks, if write_pending is set. - * -@@ -5872,6 +6023,7 @@ - tcp_paws_reject(&tp->rx_opt, 0)) - goto discard_and_undo; - -+ /* TODO - check this here for MPTCP */ - if (th->syn) { - /* We see SYN without ACK. It is attempt of - * simultaneous connect with crossed SYNs. -@@ -5888,6 +6040,11 @@ - tp->tcp_header_len = sizeof(struct tcphdr); - } - -+ if (mptcp(tp)) { -+ tp->tcp_header_len += MPTCP_SUB_LEN_DSM_ALIGN; -+ tp->advmss -= MPTCP_SUB_LEN_DSM_ALIGN; -+ } -+ - tp->rcv_nxt = TCP_SKB_CB(skb)->seq + 1; - tp->copied_seq = tp->rcv_nxt; - tp->rcv_wup = TCP_SKB_CB(skb)->seq + 1; -@@ -5946,6 +6103,7 @@ - */ - - int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb) -+ __releases(&sk->sk_lock.slock) - { - struct tcp_sock *tp = tcp_sk(sk); - struct inet_connection_sock *icsk = inet_csk(sk); -@@ -5987,6 +6145,16 @@ - case TCP_SYN_SENT: - tp->rx_opt.saw_tstamp = 0; - queued = tcp_rcv_synsent_state_process(sk, skb, th); -+ if (is_meta_sk(sk)) { -+ sk = tcp_sk(sk)->mpcb->master_sk; -+ tp = tcp_sk(sk); -+ -+ /* Need to call it here, because it will announce new -+ * addresses, which can only be done after the third ack -+ * of the 3-way handshake. -+ */ -+ mptcp_update_metasocket(tp->meta_sk); -+ } - if (queued >= 0) - return queued; - -@@ -6042,7 +6210,7 @@ - - tcp_mtup_init(sk); - tp->copied_seq = tp->rcv_nxt; -- tcp_init_buffer_space(sk); -+ tp->ops->init_buffer_space(sk); - } - smp_mb(); - tcp_set_state(sk, TCP_ESTABLISHED); -@@ -6061,6 +6229,8 @@ - - if (tp->rx_opt.tstamp_ok) - tp->advmss -= TCPOLEN_TSTAMP_ALIGNED; -+ if (mptcp(tp)) -+ tp->advmss -= MPTCP_SUB_LEN_DSM_ALIGN; - - if (req) { - /* Re-arm the timer because data may have been sent out. -@@ -6083,6 +6253,30 @@ - - tcp_initialize_rcv_mss(sk); - tcp_fast_path_on(tp); -+ -+ /* Send an ACK when establishing a new MPTCP subflow, i.e. -+ * using an MP_JOIN subtype. -+ */ -+ if (mptcp(tp)) { -+ if (is_master_tp(tp)) { -+ mptcp_update_metasocket(mptcp_meta_sk(sk)); -+ } else { -+ struct sock *meta_sk = mptcp_meta_sk(sk); -+ -+ tcp_send_ack(sk); -+ -+ /* Update RTO as it might be worse/better */ -+ mptcp_set_rto(sk); -+ -+ /* If the new RTO would fire earlier, pull it in! */ -+ if (tcp_sk(meta_sk)->packets_out && -+ icsk->icsk_timeout > inet_csk(meta_sk)->icsk_rto + jiffies) { -+ tcp_rearm_rto(meta_sk); -+ } -+ -+ mptcp_push_pending_frames(mptcp_meta_sk(sk)); -+ } -+ } - break; - - case TCP_FIN_WAIT1: { -@@ -6126,7 +6320,8 @@ - tmo = tcp_fin_time(sk); - if (tmo > TCP_TIMEWAIT_LEN) { - inet_csk_reset_keepalive_timer(sk, tmo - TCP_TIMEWAIT_LEN); -- } else if (th->fin || sock_owned_by_user(sk)) { -+ } else if (th->fin || mptcp_is_data_fin(skb) || -+ sock_owned_by_user(sk)) { - /* Bad case. We could lose such FIN otherwise. - * It is not a big problem, but it looks confusing - * and not so rare event. We still can lose it now, -@@ -6135,7 +6330,7 @@ - */ - inet_csk_reset_keepalive_timer(sk, tmo); - } else { -- tcp_time_wait(sk, TCP_FIN_WAIT2, tmo); -+ tp->ops->time_wait(sk, TCP_FIN_WAIT2, tmo); - goto discard; - } - break; -@@ -6143,7 +6338,7 @@ - - case TCP_CLOSING: - if (tp->snd_una == tp->write_seq) { -- tcp_time_wait(sk, TCP_TIME_WAIT, 0); -+ tp->ops->time_wait(sk, TCP_TIME_WAIT, 0); - goto discard; - } - break; -@@ -6155,6 +6350,9 @@ - goto discard; - } - break; -+ case TCP_CLOSE: -+ if (tp->mp_killed) -+ goto discard; - } - - /* step 6: check the URG bit */ -@@ -6175,7 +6373,8 @@ - */ - if (sk->sk_shutdown & RCV_SHUTDOWN) { - if (TCP_SKB_CB(skb)->end_seq != TCP_SKB_CB(skb)->seq && -- after(TCP_SKB_CB(skb)->end_seq - th->fin, tp->rcv_nxt)) { -+ after(TCP_SKB_CB(skb)->end_seq - th->fin, tp->rcv_nxt) && -+ !mptcp(tp)) { - NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPABORTONDATA); - tcp_reset(sk); - return 1; -@@ -6271,6 +6470,8 @@ - ireq->wscale_ok = rx_opt->wscale_ok; - ireq->acked = 0; - ireq->ecn_ok = 0; -+ ireq->mptcp_rqsk = 0; -+ ireq->saw_mpc = 0; - ireq->ir_rmt_port = tcp_hdr(skb)->source; - ireq->ir_num = ntohs(tcp_hdr(skb)->dest); - ireq->ir_mark = inet_request_mark(sk, skb); -@@ -6366,12 +6567,17 @@ - /* TW buckets are converted to open requests without - * limitations, they conserve resources and peer is - * evidently real one. -+ * -+ * MPTCP: new subflows cannot be established in a stateless manner. - */ -- if ((net->ipv4.sysctl_tcp_syncookies == 2 || -+ if (((!is_meta_sk(sk) && net->ipv4.sysctl_tcp_syncookies == 2) || - inet_csk_reqsk_queue_is_full(sk)) && !isn) { - want_cookie = tcp_syn_flood_action(sk, skb, rsk_ops->slab_name); - if (!want_cookie) - goto drop; -+ -+ if (is_meta_sk(sk)) -+ goto drop; - } - - -@@ -6394,7 +6600,7 @@ - tcp_clear_options(&tmp_opt); - tmp_opt.mss_clamp = af_ops->mss_clamp; - tmp_opt.user_mss = tp->rx_opt.user_mss; -- tcp_parse_options(skb, &tmp_opt, 0, want_cookie ? NULL : &foc); -+ tcp_parse_options(skb, &tmp_opt, NULL, 0, want_cookie ? NULL : &foc, NULL); - - if (want_cookie && !tmp_opt.saw_tstamp) - tcp_clear_options(&tmp_opt); -@@ -6406,7 +6612,8 @@ - /* Note: tcp_v6_init_req() might override ir_iif for link locals */ - inet_rsk(req)->ir_iif = inet_request_bound_dev_if(sk, skb); - -- af_ops->init_req(req, sk, skb); -+ if (af_ops->init_req(req, sk, skb, want_cookie)) -+ goto drop_and_free; - - if (security_inet_conn_request(sk, skb, req)) - goto drop_and_free; -@@ -6462,7 +6669,7 @@ - tcp_ecn_create_request(req, skb, sk, dst); - - if (want_cookie) { -- isn = cookie_init_sequence(af_ops, sk, skb, &req->mss); -+ isn = cookie_init_sequence(af_ops, req, sk, skb, &req->mss); - req->cookie_ts = tmp_opt.tstamp_ok; - if (!tmp_opt.tstamp_ok) - inet_rsk(req)->ecn_ok = 0; -@@ -6476,12 +6683,18 @@ - fastopen_sk = tcp_try_fastopen(sk, skb, req, &foc, dst); - } - if (fastopen_sk) { -+ struct sock *meta_sk = fastopen_sk; -+ -+ if (mptcp(tcp_sk(fastopen_sk))) -+ meta_sk = mptcp_meta_sk(fastopen_sk); - af_ops->send_synack(fastopen_sk, dst, &fl, req, - &foc, TCP_SYNACK_FASTOPEN); - /* Add the child socket directly into the accept queue */ -- inet_csk_reqsk_queue_add(sk, req, fastopen_sk); -+ inet_csk_reqsk_queue_add(sk, req, meta_sk); - sk->sk_data_ready(sk); - bh_unlock_sock(fastopen_sk); -+ if (meta_sk != fastopen_sk) -+ bh_unlock_sock(meta_sk); - sock_put(fastopen_sk); - } else { - tcp_rsk(req)->tfo_listener = false; -diff -aurN linux-4.9.162/net/ipv4/tcp_ipv4.c mptcp-mptcp_v0.93/net/ipv4/tcp_ipv4.c ---- linux-4.9.162/net/ipv4/tcp_ipv4.c 2019-03-05 17:57:07.000000000 +0100 -+++ mptcp-mptcp_v0.93/net/ipv4/tcp_ipv4.c 2019-03-14 14:02:32.000000000 +0100 -@@ -67,6 +67,8 @@ - #include - #include - #include -+#include -+#include - #include - #include - #include -@@ -362,7 +364,7 @@ - struct inet_sock *inet; - const int type = icmp_hdr(icmp_skb)->type; - const int code = icmp_hdr(icmp_skb)->code; -- struct sock *sk; -+ struct sock *sk, *meta_sk; - struct sk_buff *skb; - struct request_sock *fastopen; - __u32 seq, snd_una; -@@ -390,13 +392,19 @@ - (code == ICMP_NET_UNREACH || - code == ICMP_HOST_UNREACH))); - -- bh_lock_sock(sk); -+ tp = tcp_sk(sk); -+ if (mptcp(tp)) -+ meta_sk = mptcp_meta_sk(sk); -+ else -+ meta_sk = sk; -+ -+ bh_lock_sock(meta_sk); - /* If too many ICMPs get dropped on busy - * servers this needs to be solved differently. - * We do take care of PMTU discovery (RFC1191) special case : - * we can receive locally generated ICMP messages while socket is held. - */ -- if (sock_owned_by_user(sk)) { -+ if (sock_owned_by_user(meta_sk)) { - if (!(type == ICMP_DEST_UNREACH && code == ICMP_FRAG_NEEDED)) - __NET_INC_STATS(net, LINUX_MIB_LOCKDROPPEDICMPS); - } -@@ -409,7 +417,6 @@ - } - - icsk = inet_csk(sk); -- tp = tcp_sk(sk); - /* XXX (TFO) - tp->snd_una should be ISN (tcp_create_openreq_child() */ - fastopen = tp->fastopen_rsk; - snd_una = fastopen ? tcp_rsk(fastopen)->snt_isn : tp->snd_una; -@@ -443,11 +450,13 @@ - goto out; - - tp->mtu_info = info; -- if (!sock_owned_by_user(sk)) { -+ if (!sock_owned_by_user(meta_sk)) { - tcp_v4_mtu_reduced(sk); - } else { - if (!test_and_set_bit(TCP_MTU_REDUCED_DEFERRED, &tp->tsq_flags)) - sock_hold(sk); -+ if (mptcp(tp)) -+ mptcp_tsq_flags(sk); - } - goto out; - } -@@ -461,7 +470,7 @@ - !icsk->icsk_backoff || fastopen) - break; - -- if (sock_owned_by_user(sk)) -+ if (sock_owned_by_user(meta_sk)) - break; - - skb = tcp_write_queue_head(sk); -@@ -483,7 +492,7 @@ - } else { - /* RTO revert clocked out retransmission. - * Will retransmit now */ -- tcp_retransmit_timer(sk); -+ tcp_sk(sk)->ops->retransmit_timer(sk); - } - - break; -@@ -503,7 +512,7 @@ - if (fastopen && !fastopen->sk) - break; - -- if (!sock_owned_by_user(sk)) { -+ if (!sock_owned_by_user(meta_sk)) { - sk->sk_err = err; - - sk->sk_error_report(sk); -@@ -532,7 +541,7 @@ - */ - - inet = inet_sk(sk); -- if (!sock_owned_by_user(sk) && inet->recverr) { -+ if (!sock_owned_by_user(meta_sk) && inet->recverr) { - sk->sk_err = err; - sk->sk_error_report(sk); - } else { /* Only an error on timeout */ -@@ -540,7 +549,7 @@ - } - - out: -- bh_unlock_sock(sk); -+ bh_unlock_sock(meta_sk); - sock_put(sk); - } - -@@ -582,7 +591,7 @@ - * Exception: precedence violation. We do not implement it in any case. - */ - --static void tcp_v4_send_reset(const struct sock *sk, struct sk_buff *skb) -+void tcp_v4_send_reset(const struct sock *sk, struct sk_buff *skb) - { - const struct tcphdr *th = tcp_hdr(skb); - struct { -@@ -717,10 +726,10 @@ - */ - - static void tcp_v4_send_ack(struct net *net, -- struct sk_buff *skb, u32 seq, u32 ack, -+ struct sk_buff *skb, u32 seq, u32 ack, u32 data_ack, - u32 win, u32 tsval, u32 tsecr, int oif, - struct tcp_md5sig_key *key, -- int reply_flags, u8 tos) -+ int reply_flags, u8 tos, int mptcp) - { - const struct tcphdr *th = tcp_hdr(skb); - struct { -@@ -729,6 +738,10 @@ - #ifdef CONFIG_TCP_MD5SIG - + (TCPOLEN_MD5SIG_ALIGNED >> 2) - #endif -+#ifdef CONFIG_MPTCP -+ + ((MPTCP_SUB_LEN_DSS >> 2) + -+ (MPTCP_SUB_LEN_ACK >> 2)) -+#endif - ]; - } rep; - struct ip_reply_arg arg; -@@ -772,6 +785,21 @@ - ip_hdr(skb)->daddr, &rep.th); - } - #endif -+#ifdef CONFIG_MPTCP -+ if (mptcp) { -+ int offset = (tsecr) ? 3 : 0; -+ /* Construction of 32-bit data_ack */ -+ rep.opt[offset++] = htonl((TCPOPT_MPTCP << 24) | -+ ((MPTCP_SUB_LEN_DSS + MPTCP_SUB_LEN_ACK) << 16) | -+ (0x20 << 8) | -+ (0x01)); -+ rep.opt[offset] = htonl(data_ack); -+ -+ arg.iov[0].iov_len += MPTCP_SUB_LEN_DSS + MPTCP_SUB_LEN_ACK; -+ rep.th.doff = arg.iov[0].iov_len / 4; -+ } -+#endif /* CONFIG_MPTCP */ -+ - arg.flags = reply_flags; - arg.csum = csum_tcpudp_nofold(ip_hdr(skb)->daddr, - ip_hdr(skb)->saddr, /* XXX */ -@@ -794,28 +822,36 @@ - { - struct inet_timewait_sock *tw = inet_twsk(sk); - struct tcp_timewait_sock *tcptw = tcp_twsk(sk); -+ u32 data_ack = 0; -+ int mptcp = 0; -+ -+ if (tcptw->mptcp_tw) { -+ data_ack = (u32)tcptw->mptcp_tw->rcv_nxt; -+ mptcp = 1; -+ } - - tcp_v4_send_ack(sock_net(sk), skb, -- tcptw->tw_snd_nxt, tcptw->tw_rcv_nxt, -+ tcptw->tw_snd_nxt, tcptw->tw_rcv_nxt, data_ack, - tcptw->tw_rcv_wnd >> tw->tw_rcv_wscale, - tcp_time_stamp + tcptw->tw_ts_offset, - tcptw->tw_ts_recent, - tw->tw_bound_dev_if, - tcp_twsk_md5_key(tcptw), - tw->tw_transparent ? IP_REPLY_ARG_NOSRCCHECK : 0, -- tw->tw_tos -+ tw->tw_tos, mptcp - ); - - inet_twsk_put(tw); - } - --static void tcp_v4_reqsk_send_ack(const struct sock *sk, struct sk_buff *skb, -- struct request_sock *req) -+void tcp_v4_reqsk_send_ack(const struct sock *sk, struct sk_buff *skb, -+ struct request_sock *req) - { - /* sk->sk_state == TCP_LISTEN -> for regular TCP_SYN_RECV - * sk->sk_state == TCP_SYN_RECV -> for Fast Open. - */ -- u32 seq = (sk->sk_state == TCP_LISTEN) ? tcp_rsk(req)->snt_isn + 1 : -+ u32 seq = (sk->sk_state == TCP_LISTEN || is_meta_sk(sk)) ? -+ tcp_rsk(req)->snt_isn + 1 : - tcp_sk(sk)->snd_nxt; - - /* RFC 7323 2.3 -@@ -824,7 +860,7 @@ - * Rcv.Wind.Shift bits: - */ - tcp_v4_send_ack(sock_net(sk), skb, seq, -- tcp_rsk(req)->rcv_nxt, -+ tcp_rsk(req)->rcv_nxt, 0, - req->rsk_rcv_wnd >> inet_rsk(req)->rcv_wscale, - tcp_time_stamp, - req->ts_recent, -@@ -832,7 +868,7 @@ - tcp_md5_do_lookup(sk, (union tcp_md5_addr *)&ip_hdr(skb)->saddr, - AF_INET), - inet_rsk(req)->no_srccheck ? IP_REPLY_ARG_NOSRCCHECK : 0, -- ip_hdr(skb)->tos); -+ ip_hdr(skb)->tos, 0); - } - - /* -@@ -840,11 +876,11 @@ - * This still operates on a request_sock only, not on a big - * socket. - */ --static int tcp_v4_send_synack(const struct sock *sk, struct dst_entry *dst, -- struct flowi *fl, -- struct request_sock *req, -- struct tcp_fastopen_cookie *foc, -- enum tcp_synack_type synack_type) -+int tcp_v4_send_synack(const struct sock *sk, struct dst_entry *dst, -+ struct flowi *fl, -+ struct request_sock *req, -+ struct tcp_fastopen_cookie *foc, -+ enum tcp_synack_type synack_type) - { - const struct inet_request_sock *ireq = inet_rsk(req); - struct flowi4 fl4; -@@ -874,7 +910,7 @@ - /* - * IPv4 request_sock destructor. - */ --static void tcp_v4_reqsk_destructor(struct request_sock *req) -+void tcp_v4_reqsk_destructor(struct request_sock *req) - { - kfree(rcu_dereference_protected(inet_rsk(req)->ireq_opt, 1)); - } -@@ -1194,15 +1230,18 @@ - return false; - } - --static void tcp_v4_init_req(struct request_sock *req, -- const struct sock *sk_listener, -- struct sk_buff *skb) -+static int tcp_v4_init_req(struct request_sock *req, -+ const struct sock *sk_listener, -+ struct sk_buff *skb, -+ bool want_cookie) - { - struct inet_request_sock *ireq = inet_rsk(req); - - sk_rcv_saddr_set(req_to_sk(req), ip_hdr(skb)->daddr); - sk_daddr_set(req_to_sk(req), ip_hdr(skb)->saddr); - RCU_INIT_POINTER(ireq->ireq_opt, tcp_v4_save_options(skb)); -+ -+ return 0; - } - - static struct dst_entry *tcp_v4_route_req(const struct sock *sk, -@@ -1232,7 +1271,7 @@ - .syn_ack_timeout = tcp_syn_ack_timeout, - }; - --static const struct tcp_request_sock_ops tcp_request_sock_ipv4_ops = { -+const struct tcp_request_sock_ops tcp_request_sock_ipv4_ops = { - .mss_clamp = TCP_MSS_DEFAULT, - #ifdef CONFIG_TCP_MD5SIG - .req_md5_lookup = tcp_v4_md5_lookup, -@@ -1371,7 +1410,7 @@ - } - EXPORT_SYMBOL(tcp_v4_syn_recv_sock); - --static struct sock *tcp_v4_cookie_check(struct sock *sk, struct sk_buff *skb) -+struct sock *tcp_v4_cookie_check(struct sock *sk, struct sk_buff *skb) - { - #ifdef CONFIG_SYN_COOKIES - const struct tcphdr *th = tcp_hdr(skb); -@@ -1394,6 +1433,9 @@ - { - struct sock *rsk; - -+ if (is_meta_sk(sk)) -+ return mptcp_v4_do_rcv(sk, skb); -+ - if (sk->sk_state == TCP_ESTABLISHED) { /* Fast path */ - struct dst_entry *dst = sk->sk_rx_dst; - -@@ -1537,7 +1579,7 @@ - } else if (skb_queue_len(&tp->ucopy.prequeue) == 1) { - wake_up_interruptible_sync_poll(sk_sleep(sk), - POLLIN | POLLRDNORM | POLLRDBAND); -- if (!inet_csk_ack_scheduled(sk)) -+ if (!inet_csk_ack_scheduled(sk) && !mptcp(tp)) - inet_csk_reset_xmit_timer(sk, ICSK_TIME_DACK, - (3 * tcp_rto_min(sk)) / 4, - TCP_RTO_MAX); -@@ -1598,8 +1640,8 @@ - struct net *net = dev_net(skb->dev); - const struct iphdr *iph; - const struct tcphdr *th; -+ struct sock *sk, *meta_sk = NULL; - bool refcounted; -- struct sock *sk; - int ret; - - if (skb->pkt_type != PACKET_HOST) -@@ -1639,6 +1681,10 @@ - TCP_SKB_CB(skb)->end_seq = (TCP_SKB_CB(skb)->seq + th->syn + th->fin + - skb->len - th->doff * 4); - TCP_SKB_CB(skb)->ack_seq = ntohl(th->ack_seq); -+#ifdef CONFIG_MPTCP -+ TCP_SKB_CB(skb)->mptcp_flags = 0; -+ TCP_SKB_CB(skb)->dss_off = 0; -+#endif - TCP_SKB_CB(skb)->tcp_flags = tcp_flag_byte(th); - TCP_SKB_CB(skb)->tcp_tw_isn = 0; - TCP_SKB_CB(skb)->ip_dsfield = ipv4_get_dsfield(iph); -@@ -1668,7 +1714,7 @@ - reqsk_put(req); - goto csum_error; - } -- if (unlikely(sk->sk_state != TCP_LISTEN)) { -+ if (unlikely(sk->sk_state != TCP_LISTEN && !is_meta_sk(sk))) { - inet_csk_reqsk_queue_drop_and_put(sk, req); - goto lookup; - } -@@ -1677,13 +1723,47 @@ - */ - sock_hold(sk); - refcounted = true; -+ -+ if (is_meta_sk(sk)) { -+ bh_lock_sock(sk); -+ -+ if (!mptcp_can_new_subflow(sk)) { -+ inet_csk_reqsk_queue_drop_and_put(sk, req); -+ bh_unlock_sock(sk); -+ -+ goto discard_and_relse; -+ } -+ -+ if (sock_owned_by_user(sk)) { -+ mptcp_prepare_for_backlog(sk, skb); -+ if (unlikely(sk_add_backlog(sk, skb, -+ sk->sk_rcvbuf + sk->sk_sndbuf))) { -+ reqsk_put(req); -+ -+ bh_unlock_sock(sk); -+ __NET_INC_STATS(net, LINUX_MIB_TCPBACKLOGDROP); -+ goto discard_and_relse; -+ } -+ -+ reqsk_put(req); -+ bh_unlock_sock(sk); -+ sock_put(sk); -+ -+ return 0; -+ } -+ } -+ - nsk = tcp_check_req(sk, skb, req, false); - if (!nsk) { - reqsk_put(req); -+ if (is_meta_sk(sk)) -+ bh_unlock_sock(sk); - goto discard_and_relse; - } - if (nsk == sk) { - reqsk_put(req); -+ if (is_meta_sk(sk)) -+ bh_unlock_sock(sk); - } else if (tcp_child_process(sk, nsk, skb)) { - tcp_v4_send_reset(nsk, skb); - goto discard_and_relse; -@@ -1719,16 +1799,25 @@ - - sk_incoming_cpu_update(sk); - -- bh_lock_sock_nested(sk); -+ if (mptcp(tcp_sk(sk))) { -+ meta_sk = mptcp_meta_sk(sk); -+ -+ bh_lock_sock_nested(meta_sk); -+ if (sock_owned_by_user(meta_sk)) -+ mptcp_prepare_for_backlog(sk, skb); -+ } else { -+ meta_sk = sk; -+ bh_lock_sock_nested(sk); -+ } - tcp_segs_in(tcp_sk(sk), skb); - ret = 0; -- if (!sock_owned_by_user(sk)) { -- if (!tcp_prequeue(sk, skb)) -+ if (!sock_owned_by_user(meta_sk)) { -+ if (!tcp_prequeue(meta_sk, skb)) - ret = tcp_v4_do_rcv(sk, skb); -- } else if (tcp_add_backlog(sk, skb)) { -+ } else if (tcp_add_backlog(meta_sk, skb)) { - goto discard_and_relse; - } -- bh_unlock_sock(sk); -+ bh_unlock_sock(meta_sk); - - put_and_return: - if (refcounted) -@@ -1740,6 +1829,19 @@ - if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb)) - goto discard_it; - -+#ifdef CONFIG_MPTCP -+ if (!sk && th->syn && !th->ack) { -+ int ret = mptcp_lookup_join(skb, NULL); -+ -+ if (ret < 0) { -+ tcp_v4_send_reset(NULL, skb); -+ goto discard_it; -+ } else if (ret > 0) { -+ return 0; -+ } -+ } -+#endif -+ - if (tcp_checksum_complete(skb)) { - csum_error: - __TCP_INC_STATS(net, TCP_MIB_CSUMERRORS); -@@ -1784,6 +1886,18 @@ - refcounted = false; - goto process; - } -+#ifdef CONFIG_MPTCP -+ if (th->syn && !th->ack) { -+ int ret = mptcp_lookup_join(skb, inet_twsk(sk)); -+ -+ if (ret < 0) { -+ tcp_v4_send_reset(NULL, skb); -+ goto discard_it; -+ } else if (ret > 0) { -+ return 0; -+ } -+ } -+#endif - /* Fall through to ACK */ - } - case TCP_TW_ACK: -@@ -1853,7 +1967,12 @@ - - tcp_init_sock(sk); - -- icsk->icsk_af_ops = &ipv4_specific; -+#ifdef CONFIG_MPTCP -+ if (sock_flag(sk, SOCK_MPTCP)) -+ icsk->icsk_af_ops = &mptcp_v4_specific; -+ else -+#endif -+ icsk->icsk_af_ops = &ipv4_specific; - - #ifdef CONFIG_TCP_MD5SIG - tcp_sk(sk)->af_specific = &tcp_sock_ipv4_specific; -@@ -1870,6 +1989,11 @@ - - tcp_cleanup_congestion_control(sk); - -+ if (mptcp(tp)) -+ mptcp_destroy_sock(sk); -+ if (tp->inside_tk_table) -+ mptcp_hash_remove_bh(tp); -+ - /* Cleanup up the write buffer. */ - tcp_write_queue_purge(sk); - -@@ -2415,6 +2539,9 @@ - .compat_getsockopt = compat_tcp_getsockopt, - #endif - .diag_destroy = tcp_abort, -+#ifdef CONFIG_MPTCP -+ .clear_sk = mptcp_clear_sk, -+#endif - }; - EXPORT_SYMBOL(tcp_prot); - -diff -aurN linux-4.9.162/net/ipv4/tcp_minisocks.c mptcp-mptcp_v0.93/net/ipv4/tcp_minisocks.c ---- linux-4.9.162/net/ipv4/tcp_minisocks.c 2019-03-05 17:57:07.000000000 +0100 -+++ mptcp-mptcp_v0.93/net/ipv4/tcp_minisocks.c 2019-03-14 14:02:32.000000000 +0100 -@@ -18,11 +18,13 @@ - * Jorge Cwik, - */ - -+#include - #include - #include - #include - #include - #include -+#include - #include - #include - #include -@@ -100,10 +102,14 @@ - struct tcp_options_received tmp_opt; - struct tcp_timewait_sock *tcptw = tcp_twsk((struct sock *)tw); - bool paws_reject = false; -+ struct mptcp_options_received mopt; - - tmp_opt.saw_tstamp = 0; -- if (th->doff > (sizeof(*th) >> 2) && tcptw->tw_ts_recent_stamp) { -- tcp_parse_options(skb, &tmp_opt, 0, NULL); -+ if (th->doff > (sizeof(*th) >> 2) && -+ (tcptw->tw_ts_recent_stamp || tcptw->mptcp_tw)) { -+ mptcp_init_mp_opt(&mopt); -+ -+ tcp_parse_options(skb, &tmp_opt, &mopt, 0, NULL, NULL); - - if (tmp_opt.saw_tstamp) { - tmp_opt.rcv_tsecr -= tcptw->tw_ts_offset; -@@ -111,6 +117,11 @@ - tmp_opt.ts_recent_stamp = tcptw->tw_ts_recent_stamp; - paws_reject = tcp_paws_reject(&tmp_opt, th->rst); - } -+ -+ if (unlikely(mopt.mp_fclose) && tcptw->mptcp_tw) { -+ if (mopt.mptcp_sender_key == tcptw->mptcp_tw->loc_key) -+ return TCP_TW_RST; -+ } - } - - if (tw->tw_substate == TCP_FIN_WAIT2) { -@@ -134,6 +145,16 @@ - if (!th->ack || - !after(TCP_SKB_CB(skb)->end_seq, tcptw->tw_rcv_nxt) || - TCP_SKB_CB(skb)->end_seq == TCP_SKB_CB(skb)->seq) { -+ /* If mptcp_is_data_fin() returns true, we are sure that -+ * mopt has been initialized - otherwise it would not -+ * be a DATA_FIN. -+ */ -+ if (tcptw->mptcp_tw && tcptw->mptcp_tw->meta_tw && -+ mptcp_is_data_fin(skb) && -+ TCP_SKB_CB(skb)->seq == tcptw->tw_rcv_nxt && -+ mopt.data_seq + 1 == (u32)tcptw->mptcp_tw->rcv_nxt) -+ return TCP_TW_ACK; -+ - inet_twsk_put(tw); - return TCP_TW_SUCCESS; - } -@@ -286,6 +307,15 @@ - tcptw->tw_ts_offset = tp->tsoffset; - tcptw->tw_last_oow_ack_time = 0; - -+ if (mptcp(tp)) { -+ if (mptcp_init_tw_sock(sk, tcptw)) { -+ inet_twsk_free(tw); -+ goto exit; -+ } -+ } else { -+ tcptw->mptcp_tw = NULL; -+ } -+ - #if IS_ENABLED(CONFIG_IPV6) - if (tw->tw_family == PF_INET6) { - struct ipv6_pinfo *np = inet6_sk(sk); -@@ -347,15 +377,18 @@ - NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPTIMEWAITOVERFLOW); - } - -+exit: - tcp_update_metrics(sk); - tcp_done(sk); - } - - void tcp_twsk_destructor(struct sock *sk) - { --#ifdef CONFIG_TCP_MD5SIG - struct tcp_timewait_sock *twsk = tcp_twsk(sk); - -+ if (twsk->mptcp_tw) -+ mptcp_twsk_destructor(twsk); -+#ifdef CONFIG_TCP_MD5SIG - if (twsk->tw_md5_key) - kfree_rcu(twsk->tw_md5_key, rcu); - #endif -@@ -390,13 +423,14 @@ - req->rsk_window_clamp = full_space; - - /* tcp_full_space because it is guaranteed to be the first packet */ -- tcp_select_initial_window(full_space, -- mss - (ireq->tstamp_ok ? TCPOLEN_TSTAMP_ALIGNED : 0), -+ tp->ops->select_initial_window(tcp_full_space(sk_listener), -+ mss - (ireq->tstamp_ok ? TCPOLEN_TSTAMP_ALIGNED : 0) - -+ (ireq->saw_mpc ? MPTCP_SUB_LEN_DSM_ALIGN : 0), - &req->rsk_rcv_wnd, - &req->rsk_window_clamp, - ireq->wscale_ok, - &rcv_wscale, -- dst_metric(dst, RTAX_INITRWND)); -+ dst_metric(dst, RTAX_INITRWND), sk_listener); - ireq->rcv_wscale = rcv_wscale; - } - EXPORT_SYMBOL(tcp_openreq_init_rwin); -@@ -540,6 +574,8 @@ - newtp->rx_opt.ts_recent_stamp = 0; - newtp->tcp_header_len = sizeof(struct tcphdr); - } -+ if (ireq->saw_mpc) -+ newtp->tcp_header_len += MPTCP_SUB_LEN_DSM_ALIGN; - newtp->tsoffset = 0; - #ifdef CONFIG_TCP_MD5SIG - newtp->md5sig_info = NULL; /*XXX*/ -@@ -578,6 +614,7 @@ - bool fastopen) - { - struct tcp_options_received tmp_opt; -+ struct mptcp_options_received mopt; - struct sock *child; - const struct tcphdr *th = tcp_hdr(skb); - __be32 flg = tcp_flag_word(th) & (TCP_FLAG_RST|TCP_FLAG_SYN|TCP_FLAG_ACK); -@@ -585,8 +622,11 @@ - bool own_req; - - tmp_opt.saw_tstamp = 0; -+ -+ mptcp_init_mp_opt(&mopt); -+ - if (th->doff > (sizeof(struct tcphdr)>>2)) { -- tcp_parse_options(skb, &tmp_opt, 0, NULL); -+ tcp_parse_options(skb, &tmp_opt, &mopt, 0, NULL, NULL); - - if (tmp_opt.saw_tstamp) { - tmp_opt.ts_recent = req->ts_recent; -@@ -625,7 +665,14 @@ - * - * Reset timer after retransmitting SYNACK, similar to - * the idea of fast retransmit in recovery. -+ * -+ * Fall back to TCP if MP_CAPABLE is not set. - */ -+ -+ if (inet_rsk(req)->saw_mpc && !mopt.saw_mpc) -+ inet_rsk(req)->saw_mpc = false; -+ -+ - if (!tcp_oow_rate_limited(sock_net(sk), skb, - LINUX_MIB_TCPACKSKIPPEDSYNRECV, - &tcp_rsk(req)->last_oow_ack_time) && -@@ -778,6 +825,18 @@ - if (!child) - goto listen_overflow; - -+ if (own_req && !is_meta_sk(sk)) { -+ int ret = mptcp_check_req_master(sk, child, req, skb, 1); -+ if (ret < 0) -+ goto listen_overflow; -+ -+ /* MPTCP-supported */ -+ if (!ret) -+ return tcp_sk(child)->mpcb->master_sk; -+ } else if (own_req) { -+ return mptcp_check_req_child(sk, child, req, skb, &mopt); -+ } -+ - sock_rps_save_rxhash(child, skb); - tcp_synack_rtt_meas(child, req); - return inet_csk_complete_hashdance(sk, child, req, own_req); -@@ -825,9 +884,10 @@ - { - int ret = 0; - int state = child->sk_state; -+ struct sock *meta_sk = mptcp(tcp_sk(child)) ? mptcp_meta_sk(child) : child; - - tcp_segs_in(tcp_sk(child), skb); -- if (!sock_owned_by_user(child)) { -+ if (!sock_owned_by_user(meta_sk)) { - ret = tcp_rcv_state_process(child, skb); - /* Wakeup parent, send SIGIO */ - if (state == TCP_SYN_RECV && child->sk_state != state) -@@ -837,10 +897,14 @@ - * in main socket hash table and lock on listening - * socket does not protect us more. - */ -- __sk_add_backlog(child, skb); -+ if (mptcp(tcp_sk(child))) -+ mptcp_prepare_for_backlog(child, skb); -+ __sk_add_backlog(meta_sk, skb); - } - -- bh_unlock_sock(child); -+ if (mptcp(tcp_sk(child))) -+ bh_unlock_sock(child); -+ bh_unlock_sock(meta_sk); - sock_put(child); - return ret; - } -diff -aurN linux-4.9.162/net/ipv4/tcp_output.c mptcp-mptcp_v0.93/net/ipv4/tcp_output.c ---- linux-4.9.162/net/ipv4/tcp_output.c 2019-03-05 17:57:07.000000000 +0100 -+++ mptcp-mptcp_v0.93/net/ipv4/tcp_output.c 2019-03-14 14:02:32.000000000 +0100 -@@ -36,6 +36,12 @@ - - #define pr_fmt(fmt) "TCP: " fmt - -+#include -+#include -+#if IS_ENABLED(CONFIG_IPV6) -+#include -+#endif -+#include - #include - - #include -@@ -62,11 +68,8 @@ - /* By default, RFC2861 behavior. */ - int sysctl_tcp_slow_start_after_idle __read_mostly = 1; - --static bool tcp_write_xmit(struct sock *sk, unsigned int mss_now, int nonagle, -- int push_one, gfp_t gfp); -- - /* Account for new data that has been sent to the network. */ --static void tcp_event_new_data_sent(struct sock *sk, const struct sk_buff *skb) -+void tcp_event_new_data_sent(struct sock *sk, const struct sk_buff *skb) - { - struct inet_connection_sock *icsk = inet_csk(sk); - struct tcp_sock *tp = tcp_sk(sk); -@@ -210,7 +213,7 @@ - void tcp_select_initial_window(int __space, __u32 mss, - __u32 *rcv_wnd, __u32 *window_clamp, - int wscale_ok, __u8 *rcv_wscale, -- __u32 init_rcv_wnd) -+ __u32 init_rcv_wnd, const struct sock *sk) - { - unsigned int space = (__space < 0 ? 0 : __space); - -@@ -266,12 +269,16 @@ - * value can be stuffed directly into th->window for an outgoing - * frame. - */ --static u16 tcp_select_window(struct sock *sk) -+u16 tcp_select_window(struct sock *sk) - { - struct tcp_sock *tp = tcp_sk(sk); - u32 old_win = tp->rcv_wnd; -- u32 cur_win = tcp_receive_window(tp); -- u32 new_win = __tcp_select_window(sk); -+ /* The window must never shrink at the meta-level. At the subflow we -+ * have to allow this. Otherwise we may announce a window too large -+ * for the current meta-level sk_rcvbuf. -+ */ -+ u32 cur_win = tcp_receive_window(mptcp(tp) ? tcp_sk(mptcp_meta_sk(sk)) : tp); -+ u32 new_win = tp->ops->__select_window(sk); - - /* Never shrink the offered window */ - if (new_win < cur_win) { -@@ -287,6 +294,7 @@ - LINUX_MIB_TCPWANTZEROWINDOWADV); - new_win = ALIGN(cur_win, 1 << tp->rx_opt.rcv_wscale); - } -+ - tp->rcv_wnd = new_win; - tp->rcv_wup = tp->rcv_nxt; - -@@ -396,7 +404,7 @@ - /* Constructs common control bits of non-data skb. If SYN/FIN is present, - * auto increment end seqno. - */ --static void tcp_init_nondata_skb(struct sk_buff *skb, u32 seq, u8 flags) -+void tcp_init_nondata_skb(struct sk_buff *skb, u32 seq, u8 flags) - { - skb->ip_summed = CHECKSUM_PARTIAL; - skb->csum = 0; -@@ -412,7 +420,7 @@ - TCP_SKB_CB(skb)->end_seq = seq; - } - --static inline bool tcp_urg_mode(const struct tcp_sock *tp) -+bool tcp_urg_mode(const struct tcp_sock *tp) - { - return tp->snd_una != tp->snd_up; - } -@@ -422,17 +430,7 @@ - #define OPTION_MD5 (1 << 2) - #define OPTION_WSCALE (1 << 3) - #define OPTION_FAST_OPEN_COOKIE (1 << 8) -- --struct tcp_out_options { -- u16 options; /* bit field of OPTION_* */ -- u16 mss; /* 0 to disable */ -- u8 ws; /* window scale, 0 to disable */ -- u8 num_sack_blocks; /* number of SACK blocks to include */ -- u8 hash_size; /* bytes in hash_location */ -- __u8 *hash_location; /* temporary pointer, overloaded */ -- __u32 tsval, tsecr; /* need to include OPTION_TS */ -- struct tcp_fastopen_cookie *fastopen_cookie; /* Fast open cookie */ --}; -+/* Before adding here - take a look at OPTION_MPTCP in include/net/mptcp.h */ - - /* Write previously computed TCP options to the packet. - * -@@ -448,7 +446,7 @@ - * (but it may well be that other scenarios fail similarly). - */ - static void tcp_options_write(__be32 *ptr, struct tcp_sock *tp, -- struct tcp_out_options *opts) -+ struct tcp_out_options *opts, struct sk_buff *skb) - { - u16 options = opts->options; /* mungable copy */ - -@@ -540,6 +538,9 @@ - } - ptr += (len + 3) >> 2; - } -+ -+ if (unlikely(OPTION_MPTCP & opts->options)) -+ mptcp_options_write(ptr, tp, opts, skb); - } - - /* Compute TCP options for SYN packets. This is not the final -@@ -591,6 +592,8 @@ - if (unlikely(!(OPTION_TS & opts->options))) - remaining -= TCPOLEN_SACKPERM_ALIGNED; - } -+ if (tp->request_mptcp || mptcp(tp)) -+ mptcp_syn_options(sk, opts, &remaining); - - if (fastopen && fastopen->cookie.len >= 0) { - u32 need = fastopen->cookie.len; -@@ -667,6 +670,9 @@ - } - } - -+ if (ireq->saw_mpc) -+ mptcp_synack_options(req, opts, &remaining); -+ - return MAX_TCP_OPTION_SPACE - remaining; - } - -@@ -699,16 +705,22 @@ - opts->tsecr = tp->rx_opt.ts_recent; - size += TCPOLEN_TSTAMP_ALIGNED; - } -+ if (mptcp(tp)) -+ mptcp_established_options(sk, skb, opts, &size); - - eff_sacks = tp->rx_opt.num_sacks + tp->rx_opt.dsack; - if (unlikely(eff_sacks)) { -- const unsigned int remaining = MAX_TCP_OPTION_SPACE - size; -- opts->num_sack_blocks = -- min_t(unsigned int, eff_sacks, -- (remaining - TCPOLEN_SACK_BASE_ALIGNED) / -- TCPOLEN_SACK_PERBLOCK); -- size += TCPOLEN_SACK_BASE_ALIGNED + -- opts->num_sack_blocks * TCPOLEN_SACK_PERBLOCK; -+ const unsigned remaining = MAX_TCP_OPTION_SPACE - size; -+ if (remaining < TCPOLEN_SACK_BASE_ALIGNED) -+ opts->num_sack_blocks = 0; -+ else -+ opts->num_sack_blocks = -+ min_t(unsigned int, eff_sacks, -+ (remaining - TCPOLEN_SACK_BASE_ALIGNED) / -+ TCPOLEN_SACK_PERBLOCK); -+ if (opts->num_sack_blocks) -+ size += TCPOLEN_SACK_BASE_ALIGNED + -+ opts->num_sack_blocks * TCPOLEN_SACK_PERBLOCK; - } - - return size; -@@ -746,8 +758,8 @@ - tp->snd_cwnd > tcp_packets_in_flight(tp)) - tcp_xmit_retransmit_queue(sk); - -- tcp_write_xmit(sk, tcp_current_mss(sk), tp->nonagle, -- 0, GFP_ATOMIC); -+ tcp_sk(sk)->ops->write_xmit(sk, tcp_current_mss(sk), -+ tcp_sk(sk)->nonagle, 0, GFP_ATOMIC); - } - } - /* -@@ -763,7 +775,7 @@ - unsigned long flags; - struct list_head *q, *n; - struct tcp_sock *tp; -- struct sock *sk; -+ struct sock *sk, *meta_sk; - - local_irq_save(flags); - list_splice_init(&tsq->head, &list); -@@ -774,15 +786,25 @@ - list_del(&tp->tsq_node); - - sk = (struct sock *)tp; -- bh_lock_sock(sk); -+ meta_sk = mptcp(tp) ? mptcp_meta_sk(sk) : sk; -+ bh_lock_sock(meta_sk); - -- if (!sock_owned_by_user(sk)) { -+ if (!sock_owned_by_user(meta_sk)) { - tcp_tsq_handler(sk); -+ if (mptcp(tp)) -+ tcp_tsq_handler(meta_sk); - } else { -+ if (mptcp(tp) && sk->sk_state == TCP_CLOSE) -+ goto exit; -+ - /* defer the work to tcp_release_cb() */ - set_bit(TCP_TSQ_DEFERRED, &tp->tsq_flags); -+ -+ if (mptcp(tp)) -+ mptcp_tsq_flags(sk); - } -- bh_unlock_sock(sk); -+exit: -+ bh_unlock_sock(meta_sk); - - clear_bit(TSQ_QUEUED, &tp->tsq_flags); - sk_free(sk); -@@ -792,7 +814,10 @@ - #define TCP_DEFERRED_ALL ((1UL << TCP_TSQ_DEFERRED) | \ - (1UL << TCP_WRITE_TIMER_DEFERRED) | \ - (1UL << TCP_DELACK_TIMER_DEFERRED) | \ -- (1UL << TCP_MTU_REDUCED_DEFERRED)) -+ (1UL << TCP_MTU_REDUCED_DEFERRED) | \ -+ (1UL << MPTCP_PATH_MANAGER_DEFERRED) |\ -+ (1UL << MPTCP_SUB_DEFERRED)) -+ - /** - * tcp_release_cb - tcp release_sock() callback - * @sk: socket -@@ -839,6 +864,13 @@ - inet_csk(sk)->icsk_af_ops->mtu_reduced(sk); - __sock_put(sk); - } -+ if (flags & (1UL << MPTCP_PATH_MANAGER_DEFERRED)) { -+ if (tcp_sk(sk)->mpcb->pm_ops->release_sock) -+ tcp_sk(sk)->mpcb->pm_ops->release_sock(sk); -+ __sock_put(sk); -+ } -+ if (flags & (1UL << MPTCP_SUB_DEFERRED)) -+ mptcp_tsq_sub_deferred(sk); - } - EXPORT_SYMBOL(tcp_release_cb); - -@@ -992,10 +1024,10 @@ - } - } - -- tcp_options_write((__be32 *)(th + 1), tp, &opts); -+ tcp_options_write((__be32 *)(th + 1), tp, &opts, skb); - skb_shinfo(skb)->gso_type = sk->sk_gso_type; - if (likely(!(tcb->tcp_flags & TCPHDR_SYN))) { -- th->window = htons(tcp_select_window(sk)); -+ th->window = htons(tp->ops->select_window(sk)); - tcp_ecn_send(sk, skb, th, tcp_header_size); - } else { - /* RFC1323: The window in SYN & SYN/ACK segments -@@ -1051,8 +1083,8 @@ - return err; - } - --static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it, -- gfp_t gfp_mask) -+int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it, -+ gfp_t gfp_mask) - { - return __tcp_transmit_skb(sk, skb, clone_it, gfp_mask, - tcp_sk(sk)->rcv_nxt); -@@ -1063,7 +1095,7 @@ - * NOTE: probe0 timer is not checked, do not forget tcp_push_pending_frames, - * otherwise socket can stall. - */ --static void tcp_queue_skb(struct sock *sk, struct sk_buff *skb) -+void tcp_queue_skb(struct sock *sk, struct sk_buff *skb) - { - struct tcp_sock *tp = tcp_sk(sk); - -@@ -1076,7 +1108,7 @@ - } - - /* Initialize TSO segments for a packet. */ --static void tcp_set_skb_tso_segs(struct sk_buff *skb, unsigned int mss_now) -+void tcp_set_skb_tso_segs(struct sk_buff *skb, unsigned int mss_now) - { - if (skb->len <= mss_now || skb->ip_summed == CHECKSUM_NONE) { - /* Avoid the costly divide in the normal -@@ -1108,7 +1140,7 @@ - /* Pcount in the middle of the write queue got changed, we need to do various - * tweaks to fix counters - */ --static void tcp_adjust_pcount(struct sock *sk, const struct sk_buff *skb, int decr) -+void tcp_adjust_pcount(struct sock *sk, const struct sk_buff *skb, int decr) - { - struct tcp_sock *tp = tcp_sk(sk); - -@@ -1261,7 +1293,7 @@ - * eventually). The difference is that pulled data not copied, but - * immediately discarded. - */ --static int __pskb_trim_head(struct sk_buff *skb, int len) -+int __pskb_trim_head(struct sk_buff *skb, int len) - { - struct skb_shared_info *shinfo; - int i, k, eat; -@@ -1485,6 +1517,7 @@ - - return mss_now; - } -+EXPORT_SYMBOL(tcp_current_mss); - - /* RFC2861, slow part. Adjust cwnd, after it was not full during one rto. - * As additional protections, we do not touch cwnd in retransmission phases, -@@ -1508,7 +1541,7 @@ - tp->snd_cwnd_stamp = tcp_time_stamp; - } - --static void tcp_cwnd_validate(struct sock *sk, bool is_cwnd_limited) -+void tcp_cwnd_validate(struct sock *sk, bool is_cwnd_limited) - { - struct tcp_sock *tp = tcp_sk(sk); - -@@ -1552,8 +1585,8 @@ - * But we can avoid doing the divide again given we already have - * skb_pcount = skb->len / mss_now - */ --static void tcp_minshall_update(struct tcp_sock *tp, unsigned int mss_now, -- const struct sk_buff *skb) -+void tcp_minshall_update(struct tcp_sock *tp, unsigned int mss_now, -+ const struct sk_buff *skb) - { - if (skb->len < tcp_skb_pcount(skb) * mss_now) - tp->snd_sml = TCP_SKB_CB(skb)->end_seq; -@@ -1611,11 +1644,11 @@ - } - - /* Returns the portion of skb which can be sent right away */ --static unsigned int tcp_mss_split_point(const struct sock *sk, -- const struct sk_buff *skb, -- unsigned int mss_now, -- unsigned int max_segs, -- int nonagle) -+unsigned int tcp_mss_split_point(const struct sock *sk, -+ const struct sk_buff *skb, -+ unsigned int mss_now, -+ unsigned int max_segs, -+ int nonagle) - { - const struct tcp_sock *tp = tcp_sk(sk); - u32 partial, needed, window, max_len; -@@ -1645,13 +1678,14 @@ - /* Can at least one segment of SKB be sent right now, according to the - * congestion window rules? If so, return how many segments are allowed. - */ --static inline unsigned int tcp_cwnd_test(const struct tcp_sock *tp, -- const struct sk_buff *skb) -+unsigned int tcp_cwnd_test(const struct tcp_sock *tp, -+ const struct sk_buff *skb) - { - u32 in_flight, cwnd, halfcwnd; - - /* Don't be strict about the congestion window for the final FIN. */ -- if ((TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN) && -+ if (skb && -+ (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN) && - tcp_skb_pcount(skb) == 1) - return 1; - -@@ -1671,7 +1705,7 @@ - * This must be invoked the first time we consider transmitting - * SKB onto the wire. - */ --static int tcp_init_tso_segs(struct sk_buff *skb, unsigned int mss_now) -+int tcp_init_tso_segs(struct sk_buff *skb, unsigned int mss_now) - { - int tso_segs = tcp_skb_pcount(skb); - -@@ -1686,8 +1720,8 @@ - /* Return true if the Nagle test allows this packet to be - * sent now. - */ --static inline bool tcp_nagle_test(const struct tcp_sock *tp, const struct sk_buff *skb, -- unsigned int cur_mss, int nonagle) -+bool tcp_nagle_test(const struct tcp_sock *tp, const struct sk_buff *skb, -+ unsigned int cur_mss, int nonagle) - { - /* Nagle rule does not apply to frames, which sit in the middle of the - * write_queue (they have no chances to get new data). -@@ -1699,7 +1733,8 @@ - return true; - - /* Don't use the nagle rule for urgent data (or for the final FIN). */ -- if (tcp_urg_mode(tp) || (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN)) -+ if (tcp_urg_mode(tp) || (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN) || -+ mptcp_is_data_fin(skb)) - return true; - - if (!tcp_nagle_check(skb->len < cur_mss, tp, nonagle)) -@@ -1709,9 +1744,8 @@ - } - - /* Does at least the first segment of SKB fit into the send window? */ --static bool tcp_snd_wnd_test(const struct tcp_sock *tp, -- const struct sk_buff *skb, -- unsigned int cur_mss) -+bool tcp_snd_wnd_test(const struct tcp_sock *tp, const struct sk_buff *skb, -+ unsigned int cur_mss) - { - u32 end_seq = TCP_SKB_CB(skb)->end_seq; - -@@ -1827,7 +1861,7 @@ - struct sk_buff *head; - int win_divisor; - -- if (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN) -+ if ((TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN) || mptcp_is_data_fin(skb)) - goto send_now; - - if (icsk->icsk_ca_state >= TCP_CA_Recovery) -@@ -2143,7 +2177,7 @@ - * Returns true, if no segments are in flight and we have queued segments, - * but cannot send anything now because of SWS or another problem. - */ --static bool tcp_write_xmit(struct sock *sk, unsigned int mss_now, int nonagle, -+bool tcp_write_xmit(struct sock *sk, unsigned int mss_now, int nonagle, - int push_one, gfp_t gfp) - { - struct tcp_sock *tp = tcp_sk(sk); -@@ -2156,7 +2190,11 @@ - - sent_pkts = 0; - -- if (!push_one) { -+ /* pmtu not yet supported with MPTCP. Should be possible, by early -+ * exiting the loop inside tcp_mtu_probe, making sure that only one -+ * single DSS-mapping gets probed. -+ */ -+ if (!push_one && !mptcp(tp)) { - /* Do MTU probing. */ - result = tcp_mtu_probe(sk); - if (!result) { -@@ -2242,7 +2280,8 @@ - if (push_one != 2) - tcp_schedule_loss_probe(sk); - is_cwnd_limited |= (tcp_packets_in_flight(tp) >= tp->snd_cwnd); -- tcp_cwnd_validate(sk, is_cwnd_limited); -+ if (tp->ops->cwnd_validate) -+ tp->ops->cwnd_validate(sk, is_cwnd_limited); - return false; - } - return !tp->packets_out && tcp_send_head(sk); -@@ -2336,7 +2375,7 @@ - if (skb) { - if (tcp_snd_wnd_test(tp, skb, mss)) { - pcount = tp->packets_out; -- tcp_write_xmit(sk, mss, TCP_NAGLE_OFF, 2, GFP_ATOMIC); -+ tp->ops->write_xmit(sk, mss, TCP_NAGLE_OFF, 2, GFP_ATOMIC); - if (tp->packets_out > pcount) - goto probe_sent; - goto rearm_timer; -@@ -2403,8 +2442,8 @@ - if (unlikely(sk->sk_state == TCP_CLOSE)) - return; - -- if (tcp_write_xmit(sk, cur_mss, nonagle, 0, -- sk_gfp_mask(sk, GFP_ATOMIC))) -+ if (tcp_sk(sk)->ops->write_xmit(sk, cur_mss, nonagle, 0, -+ sk_gfp_mask(sk, GFP_ATOMIC))) - tcp_check_probe_timer(sk); - } - -@@ -2417,7 +2456,8 @@ - - BUG_ON(!skb || skb->len < mss_now); - -- tcp_write_xmit(sk, mss_now, TCP_NAGLE_PUSH, 1, sk->sk_allocation); -+ tcp_sk(sk)->ops->write_xmit(sk, mss_now, TCP_NAGLE_PUSH, 1, -+ sk->sk_allocation); - } - - /* This function returns the amount that we can raise the -@@ -2650,6 +2690,10 @@ - if (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_SYN) - return; - -+ /* Currently not supported for MPTCP - but it should be possible */ -+ if (mptcp(tp)) -+ return; -+ - tcp_for_write_queue_from_safe(skb, tmp, sk) { - if (!tcp_can_collapse(sk, skb)) - break; -@@ -3162,7 +3206,7 @@ - - /* RFC1323: The window in SYN & SYN/ACK segments is never scaled. */ - th->window = htons(min(req->rsk_rcv_wnd, 65535U)); -- tcp_options_write((__be32 *)(th + 1), NULL, &opts); -+ tcp_options_write((__be32 *)(th + 1), NULL, &opts, skb); - th->doff = (tcp_header_size >> 2); - __TCP_INC_STATS(sock_net(sk), TCP_MIB_OUTSEGS); - -@@ -3239,13 +3283,13 @@ - (tp->window_clamp > tcp_full_space(sk) || tp->window_clamp == 0)) - tp->window_clamp = tcp_full_space(sk); - -- tcp_select_initial_window(tcp_full_space(sk), -- tp->advmss - (tp->rx_opt.ts_recent_stamp ? tp->tcp_header_len - sizeof(struct tcphdr) : 0), -- &tp->rcv_wnd, -- &tp->window_clamp, -- sysctl_tcp_window_scaling, -- &rcv_wscale, -- dst_metric(dst, RTAX_INITRWND)); -+ tp->ops->select_initial_window(tcp_full_space(sk), -+ tp->advmss - (tp->rx_opt.ts_recent_stamp ? tp->tcp_header_len - sizeof(struct tcphdr) : 0), -+ &tp->rcv_wnd, -+ &tp->window_clamp, -+ sysctl_tcp_window_scaling, -+ &rcv_wscale, -+ dst_metric(dst, RTAX_INITRWND), sk); - - tp->rx_opt.rcv_wscale = rcv_wscale; - tp->rcv_ssthresh = tp->rcv_wnd; -@@ -3270,6 +3314,36 @@ - inet_csk(sk)->icsk_rto = TCP_TIMEOUT_INIT; - inet_csk(sk)->icsk_retransmits = 0; - tcp_clear_retrans(tp); -+ -+#ifdef CONFIG_MPTCP -+ if (sock_flag(sk, SOCK_MPTCP) && mptcp_doit(sk)) { -+ if (is_master_tp(tp)) { -+ tp->request_mptcp = 1; -+ mptcp_connect_init(sk); -+ } else if (tp->mptcp) { -+ struct inet_sock *inet = inet_sk(sk); -+ -+ tp->mptcp->snt_isn = tp->write_seq; -+ tp->mptcp->init_rcv_wnd = tp->rcv_wnd; -+ -+ /* Set nonce for new subflows */ -+ if (sk->sk_family == AF_INET) -+ tp->mptcp->mptcp_loc_nonce = mptcp_v4_get_nonce( -+ inet->inet_saddr, -+ inet->inet_daddr, -+ inet->inet_sport, -+ inet->inet_dport); -+#if IS_ENABLED(CONFIG_IPV6) -+ else -+ tp->mptcp->mptcp_loc_nonce = mptcp_v6_get_nonce( -+ inet6_sk(sk)->saddr.s6_addr32, -+ sk->sk_v6_daddr.s6_addr32, -+ inet->inet_sport, -+ inet->inet_dport); -+#endif -+ } -+ } -+#endif - } - - static void tcp_connect_queue_skb(struct sock *sk, struct sk_buff *skb) -@@ -3540,6 +3614,7 @@ - { - __tcp_send_ack(sk, tcp_sk(sk)->rcv_nxt); - } -+EXPORT_SYMBOL_GPL(tcp_send_ack); - - /* This routine sends a packet with an out of date sequence - * number. It assumes the other end will try to ack it. -@@ -3552,7 +3627,7 @@ - * one is with SEG.SEQ=SND.UNA to deliver urgent pointer, another is - * out-of-date with SND.UNA-1 to probe window. - */ --static int tcp_xmit_probe_skb(struct sock *sk, int urgent, int mib) -+int tcp_xmit_probe_skb(struct sock *sk, int urgent, int mib) - { - struct tcp_sock *tp = tcp_sk(sk); - struct sk_buff *skb; -@@ -3637,7 +3712,7 @@ - unsigned long probe_max; - int err; - -- err = tcp_write_wakeup(sk, LINUX_MIB_TCPWINPROBE); -+ err = tp->ops->write_wakeup(sk, LINUX_MIB_TCPWINPROBE); - - if (tp->packets_out || !tcp_send_head(sk)) { - /* Cancel probe timer, if it is not required. */ -diff -aurN linux-4.9.162/net/ipv4/tcp_timer.c mptcp-mptcp_v0.93/net/ipv4/tcp_timer.c ---- linux-4.9.162/net/ipv4/tcp_timer.c 2019-03-05 17:57:07.000000000 +0100 -+++ mptcp-mptcp_v0.93/net/ipv4/tcp_timer.c 2019-03-14 14:02:32.000000000 +0100 -@@ -20,6 +20,7 @@ - - #include - #include -+#include - #include - - int sysctl_tcp_thin_linear_timeouts __read_mostly; -@@ -31,7 +32,7 @@ - * Returns: Nothing (void) - */ - --static void tcp_write_err(struct sock *sk) -+void tcp_write_err(struct sock *sk) - { - sk->sk_err = sk->sk_err_soft ? : ETIMEDOUT; - sk->sk_error_report(sk); -@@ -86,7 +87,7 @@ - (!tp->snd_wnd && !tp->packets_out)) - do_reset = true; - if (do_reset) -- tcp_send_active_reset(sk, GFP_ATOMIC); -+ tp->ops->send_active_reset(sk, GFP_ATOMIC); - tcp_done(sk); - __NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPABORTONMEMORY); - return 1; -@@ -163,10 +164,8 @@ - * syn_set flag is set. - * - */ --static bool retransmits_timed_out(struct sock *sk, -- unsigned int boundary, -- unsigned int timeout, -- bool syn_set) -+bool retransmits_timed_out(struct sock *sk, unsigned int boundary, -+ unsigned int timeout, bool syn_set) - { - unsigned int linear_backoff_thresh, start_ts; - unsigned int rto_base = syn_set ? TCP_TIMEOUT_INIT : TCP_RTO_MIN; -@@ -191,7 +190,7 @@ - } - - /* A write timeout has occurred. Process the after effects. */ --static int tcp_write_timeout(struct sock *sk) -+int tcp_write_timeout(struct sock *sk) - { - struct inet_connection_sock *icsk = inet_csk(sk); - struct tcp_sock *tp = tcp_sk(sk); -@@ -212,6 +211,16 @@ - } - retry_until = icsk->icsk_syn_retries ? : net->ipv4.sysctl_tcp_syn_retries; - syn_set = true; -+ -+#ifdef CONFIG_MPTCP -+ /* Stop retransmitting MP_CAPABLE options in SYN if timed out. */ -+ if (tcp_sk(sk)->request_mptcp && -+ icsk->icsk_retransmits >= sysctl_mptcp_syn_retries) { -+ tcp_sk(sk)->request_mptcp = 0; -+ -+ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_MPCAPABLERETRANSFALLBACK); -+ } -+#endif /* CONFIG_MPTCP */ - } else { - if (retransmits_timed_out(sk, net->ipv4.sysctl_tcp_retries1, 0, 0)) { - /* Some middle-boxes may black-hole Fast Open _after_ -@@ -318,18 +327,22 @@ - static void tcp_delack_timer(unsigned long data) - { - struct sock *sk = (struct sock *)data; -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct sock *meta_sk = mptcp(tp) ? mptcp_meta_sk(sk) : sk; - -- bh_lock_sock(sk); -- if (!sock_owned_by_user(sk)) { -+ bh_lock_sock(meta_sk); -+ if (!sock_owned_by_user(meta_sk)) { - tcp_delack_timer_handler(sk); - } else { - inet_csk(sk)->icsk_ack.blocked = 1; -- __NET_INC_STATS(sock_net(sk), LINUX_MIB_DELAYEDACKLOCKED); -+ __NET_INC_STATS(sock_net(meta_sk), LINUX_MIB_DELAYEDACKLOCKED); - /* deleguate our work to tcp_release_cb() */ - if (!test_and_set_bit(TCP_DELACK_TIMER_DEFERRED, &tcp_sk(sk)->tsq_flags)) - sock_hold(sk); -+ if (mptcp(tp)) -+ mptcp_tsq_flags(sk); - } -- bh_unlock_sock(sk); -+ bh_unlock_sock(meta_sk); - sock_put(sk); - } - -@@ -588,7 +601,7 @@ - break; - case ICSK_TIME_RETRANS: - icsk->icsk_pending = 0; -- tcp_retransmit_timer(sk); -+ tcp_sk(sk)->ops->retransmit_timer(sk); - break; - case ICSK_TIME_PROBE0: - icsk->icsk_pending = 0; -@@ -603,16 +616,19 @@ - static void tcp_write_timer(unsigned long data) - { - struct sock *sk = (struct sock *)data; -+ struct sock *meta_sk = mptcp(tcp_sk(sk)) ? mptcp_meta_sk(sk) : sk; - -- bh_lock_sock(sk); -- if (!sock_owned_by_user(sk)) { -+ bh_lock_sock(meta_sk); -+ if (!sock_owned_by_user(meta_sk)) { - tcp_write_timer_handler(sk); - } else { - /* delegate our work to tcp_release_cb() */ - if (!test_and_set_bit(TCP_WRITE_TIMER_DEFERRED, &tcp_sk(sk)->tsq_flags)) - sock_hold(sk); -+ if (mptcp(tcp_sk(sk))) -+ mptcp_tsq_flags(sk); - } -- bh_unlock_sock(sk); -+ bh_unlock_sock(meta_sk); - sock_put(sk); - } - -@@ -641,11 +657,12 @@ - struct sock *sk = (struct sock *) data; - struct inet_connection_sock *icsk = inet_csk(sk); - struct tcp_sock *tp = tcp_sk(sk); -+ struct sock *meta_sk = mptcp(tp) ? mptcp_meta_sk(sk) : sk; - u32 elapsed; - - /* Only process if socket is not in use. */ -- bh_lock_sock(sk); -- if (sock_owned_by_user(sk)) { -+ bh_lock_sock(meta_sk); -+ if (sock_owned_by_user(meta_sk)) { - /* Try again later. */ - inet_csk_reset_keepalive_timer (sk, HZ/20); - goto out; -@@ -656,16 +673,40 @@ - goto out; - } - -+ if (tp->send_mp_fclose) { -+ /* MUST do this before tcp_write_timeout, because retrans_stamp -+ * may have been set to 0 in another part while we are -+ * retransmitting MP_FASTCLOSE. Then, we would crash, because -+ * retransmits_timed_out accesses the meta-write-queue. -+ * -+ * We make sure that the timestamp is != 0. -+ */ -+ if (!tp->retrans_stamp) -+ tp->retrans_stamp = tcp_time_stamp ? : 1; -+ -+ if (icsk->icsk_retransmits >= MPTCP_FASTCLOSE_RETRIES) { -+ tcp_write_err(sk); -+ goto out; -+ } -+ -+ tcp_send_ack(sk); -+ icsk->icsk_retransmits++; -+ -+ icsk->icsk_rto = min(icsk->icsk_rto << 1, TCP_RTO_MAX); -+ elapsed = icsk->icsk_rto; -+ goto resched; -+ } -+ - if (sk->sk_state == TCP_FIN_WAIT2 && sock_flag(sk, SOCK_DEAD)) { - if (tp->linger2 >= 0) { - const int tmo = tcp_fin_time(sk) - TCP_TIMEWAIT_LEN; - - if (tmo > 0) { -- tcp_time_wait(sk, TCP_FIN_WAIT2, tmo); -+ tp->ops->time_wait(sk, TCP_FIN_WAIT2, tmo); - goto out; - } - } -- tcp_send_active_reset(sk, GFP_ATOMIC); -+ tp->ops->send_active_reset(sk, GFP_ATOMIC); - goto death; - } - -@@ -690,11 +731,11 @@ - icsk->icsk_probes_out > 0) || - (icsk->icsk_user_timeout == 0 && - icsk->icsk_probes_out >= keepalive_probes(tp))) { -- tcp_send_active_reset(sk, GFP_ATOMIC); -+ tp->ops->send_active_reset(sk, GFP_ATOMIC); - tcp_write_err(sk); - goto out; - } -- if (tcp_write_wakeup(sk, LINUX_MIB_TCPKEEPALIVE) <= 0) { -+ if (tp->ops->write_wakeup(sk, LINUX_MIB_TCPKEEPALIVE) <= 0) { - icsk->icsk_probes_out++; - elapsed = keepalive_intvl_when(tp); - } else { -@@ -718,7 +759,7 @@ - tcp_done(sk); - - out: -- bh_unlock_sock(sk); -+ bh_unlock_sock(meta_sk); - sock_put(sk); - } - -diff -aurN linux-4.9.162/net/ipv6/addrconf.c mptcp-mptcp_v0.93/net/ipv6/addrconf.c ---- linux-4.9.162/net/ipv6/addrconf.c 2019-03-05 17:57:07.000000000 +0100 -+++ mptcp-mptcp_v0.93/net/ipv6/addrconf.c 2019-03-14 14:02:32.000000000 +0100 -@@ -898,6 +898,7 @@ - - kfree_rcu(ifp, rcu); - } -+EXPORT_SYMBOL(inet6_ifa_finish_destroy); - - static void - ipv6_link_dev_addr(struct inet6_dev *idev, struct inet6_ifaddr *ifp) -diff -aurN linux-4.9.162/net/ipv6/af_inet6.c mptcp-mptcp_v0.93/net/ipv6/af_inet6.c ---- linux-4.9.162/net/ipv6/af_inet6.c 2019-03-05 17:57:07.000000000 +0100 -+++ mptcp-mptcp_v0.93/net/ipv6/af_inet6.c 2019-03-14 14:02:32.000000000 +0100 -@@ -106,8 +106,7 @@ - return (struct ipv6_pinfo *)(((u8 *)sk) + offset); - } - --static int inet6_create(struct net *net, struct socket *sock, int protocol, -- int kern) -+int inet6_create(struct net *net, struct socket *sock, int protocol, int kern) - { - struct inet_sock *inet; - struct ipv6_pinfo *np; -diff -aurN linux-4.9.162/net/ipv6/ipv6_sockglue.c mptcp-mptcp_v0.93/net/ipv6/ipv6_sockglue.c ---- linux-4.9.162/net/ipv6/ipv6_sockglue.c 2019-03-05 17:57:07.000000000 +0100 -+++ mptcp-mptcp_v0.93/net/ipv6/ipv6_sockglue.c 2019-03-14 14:02:32.000000000 +0100 -@@ -48,6 +48,8 @@ - #include - #include - #include -+#include -+#include - #include - #include - #include -@@ -215,7 +217,12 @@ - sock_prot_inuse_add(net, &tcp_prot, 1); - local_bh_enable(); - sk->sk_prot = &tcp_prot; -- icsk->icsk_af_ops = &ipv4_specific; -+#ifdef CONFIG_MPTCP -+ if (sock_flag(sk, SOCK_MPTCP)) -+ icsk->icsk_af_ops = &mptcp_v4_specific; -+ else -+#endif -+ icsk->icsk_af_ops = &ipv4_specific; - sk->sk_socket->ops = &inet_stream_ops; - sk->sk_family = PF_INET; - tcp_sync_mss(sk, icsk->icsk_pmtu_cookie); -@@ -241,7 +248,12 @@ - pktopt = xchg(&np->pktoptions, NULL); - kfree_skb(pktopt); - -- sk->sk_destruct = inet_sock_destruct; -+#ifdef CONFIG_MPTCP -+ if (is_meta_sk(sk)) -+ sk->sk_destruct = mptcp_sock_destruct; -+ else -+#endif -+ sk->sk_destruct = inet_sock_destruct; - /* - * ... and add it to the refcnt debug socks count - * in the new family. -acme -diff -aurN linux-4.9.162/net/ipv6/syncookies.c mptcp-mptcp_v0.93/net/ipv6/syncookies.c ---- linux-4.9.162/net/ipv6/syncookies.c 2019-03-05 17:57:07.000000000 +0100 -+++ mptcp-mptcp_v0.93/net/ipv6/syncookies.c 2019-03-14 14:02:32.000000000 +0100 -@@ -19,6 +19,8 @@ - #include - #include - #include -+#include -+#include - #include - - #define COOKIEBITS 24 /* Upper bits store count */ -@@ -113,7 +115,8 @@ - } - EXPORT_SYMBOL_GPL(__cookie_v6_init_sequence); - --__u32 cookie_v6_init_sequence(const struct sk_buff *skb, __u16 *mssp) -+__u32 cookie_v6_init_sequence(struct request_sock *req, const struct sock *sk, -+ const struct sk_buff *skb, __u16 *mssp) - { - const struct ipv6hdr *iph = ipv6_hdr(skb); - const struct tcphdr *th = tcp_hdr(skb); -@@ -135,6 +138,7 @@ - struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb) - { - struct tcp_options_received tcp_opt; -+ struct mptcp_options_received mopt; - struct inet_request_sock *ireq; - struct tcp_request_sock *treq; - struct ipv6_pinfo *np = inet6_sk(sk); -@@ -163,20 +167,34 @@ - - /* check for timestamp cookie support */ - memset(&tcp_opt, 0, sizeof(tcp_opt)); -- tcp_parse_options(skb, &tcp_opt, 0, NULL); -+ mptcp_init_mp_opt(&mopt); -+ tcp_parse_options(skb, &tcp_opt, &mopt, 0, NULL, NULL); - - if (!cookie_timestamp_decode(&tcp_opt)) - goto out; - - ret = NULL; -- req = inet_reqsk_alloc(&tcp6_request_sock_ops, sk, false); -+#ifdef CONFIG_MPTCP -+ if (mopt.saw_mpc) -+ req = inet_reqsk_alloc(&mptcp6_request_sock_ops, sk, false); -+ else -+#endif -+ req = inet_reqsk_alloc(&tcp6_request_sock_ops, sk, false); - if (!req) - goto out; - - ireq = inet_rsk(req); -+ ireq->mptcp_rqsk = 0; -+ ireq->saw_mpc = 0; - treq = tcp_rsk(req); - treq->tfo_listener = false; - -+ /* Must be done before anything else, as it initializes -+ * hash_entry of the MPTCP request-sock. -+ */ -+ if (mopt.saw_mpc) -+ mptcp_cookies_reqsk_init(req, &mopt, skb); -+ - if (security_inet_conn_request(sk, skb, req)) - goto out_free; - -@@ -236,10 +254,10 @@ - } - - req->rsk_window_clamp = tp->window_clamp ? :dst_metric(dst, RTAX_WINDOW); -- tcp_select_initial_window(tcp_full_space(sk), req->mss, -- &req->rsk_rcv_wnd, &req->rsk_window_clamp, -- ireq->wscale_ok, &rcv_wscale, -- dst_metric(dst, RTAX_INITRWND)); -+ tp->ops->select_initial_window(tcp_full_space(sk), req->mss, -+ &req->rsk_rcv_wnd, &req->rsk_window_clamp, -+ ireq->wscale_ok, &rcv_wscale, -+ dst_metric(dst, RTAX_INITRWND), sk); - - ireq->rcv_wscale = rcv_wscale; - ireq->ecn_ok = cookie_ecn_ok(&tcp_opt, sock_net(sk), dst); -diff -aurN linux-4.9.162/net/ipv6/tcp_ipv6.c mptcp-mptcp_v0.93/net/ipv6/tcp_ipv6.c ---- linux-4.9.162/net/ipv6/tcp_ipv6.c 2019-03-05 17:57:07.000000000 +0100 -+++ mptcp-mptcp_v0.93/net/ipv6/tcp_ipv6.c 2019-03-14 14:02:32.000000000 +0100 -@@ -61,6 +61,8 @@ - #include - #include - #include -+#include -+#include - #include - - #include -@@ -69,14 +71,6 @@ - #include - #include - --static void tcp_v6_send_reset(const struct sock *sk, struct sk_buff *skb); --static void tcp_v6_reqsk_send_ack(const struct sock *sk, struct sk_buff *skb, -- struct request_sock *req); -- --static int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb); -- --static const struct inet_connection_sock_af_ops ipv6_mapped; --static const struct inet_connection_sock_af_ops ipv6_specific; - #ifdef CONFIG_TCP_MD5SIG - static const struct tcp_sock_af_ops tcp_sock_ipv6_specific; - static const struct tcp_sock_af_ops tcp_sock_ipv6_mapped_specific; -@@ -88,7 +82,7 @@ - } - #endif - --static void inet6_sk_rx_dst_set(struct sock *sk, const struct sk_buff *skb) -+void inet6_sk_rx_dst_set(struct sock *sk, const struct sk_buff *skb) - { - struct dst_entry *dst = skb_dst(skb); - -@@ -109,7 +103,7 @@ - tcp_hdr(skb)->source); - } - --static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr, -+int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr, - int addr_len) - { - struct sockaddr_in6 *usin = (struct sockaddr_in6 *) uaddr; -@@ -206,7 +200,12 @@ - sin.sin_port = usin->sin6_port; - sin.sin_addr.s_addr = usin->sin6_addr.s6_addr32[3]; - -- icsk->icsk_af_ops = &ipv6_mapped; -+#ifdef CONFIG_MPTCP -+ if (sock_flag(sk, SOCK_MPTCP)) -+ icsk->icsk_af_ops = &mptcp_v6_mapped; -+ else -+#endif -+ icsk->icsk_af_ops = &ipv6_mapped; - sk->sk_backlog_rcv = tcp_v4_do_rcv; - #ifdef CONFIG_TCP_MD5SIG - tp->af_specific = &tcp_sock_ipv6_mapped_specific; -@@ -216,7 +215,12 @@ - - if (err) { - icsk->icsk_ext_hdr_len = exthdrlen; -- icsk->icsk_af_ops = &ipv6_specific; -+#ifdef CONFIG_MPTCP -+ if (sock_flag(sk, SOCK_MPTCP)) -+ icsk->icsk_af_ops = &mptcp_v6_specific; -+ else -+#endif -+ icsk->icsk_af_ops = &ipv6_specific; - sk->sk_backlog_rcv = tcp_v6_do_rcv; - #ifdef CONFIG_TCP_MD5SIG - tp->af_specific = &tcp_sock_ipv6_specific; -@@ -304,7 +308,7 @@ - return err; - } - --static void tcp_v6_mtu_reduced(struct sock *sk) -+void tcp_v6_mtu_reduced(struct sock *sk) - { - struct dst_entry *dst; - -@@ -331,7 +335,7 @@ - struct ipv6_pinfo *np; - struct tcp_sock *tp; - __u32 seq, snd_una; -- struct sock *sk; -+ struct sock *sk, *meta_sk; - bool fatal; - int err; - -@@ -355,8 +359,14 @@ - if (sk->sk_state == TCP_NEW_SYN_RECV) - return tcp_req_err(sk, seq, fatal); - -- bh_lock_sock(sk); -- if (sock_owned_by_user(sk) && type != ICMPV6_PKT_TOOBIG) -+ tp = tcp_sk(sk); -+ if (mptcp(tp)) -+ meta_sk = mptcp_meta_sk(sk); -+ else -+ meta_sk = sk; -+ -+ bh_lock_sock(meta_sk); -+ if (sock_owned_by_user(meta_sk) && type != ICMPV6_PKT_TOOBIG) - __NET_INC_STATS(net, LINUX_MIB_LOCKDROPPEDICMPS); - - if (sk->sk_state == TCP_CLOSE) -@@ -367,7 +377,6 @@ - goto out; - } - -- tp = tcp_sk(sk); - /* XXX (TFO) - tp->snd_una should be ISN (tcp_create_openreq_child() */ - fastopen = tp->fastopen_rsk; - snd_una = fastopen ? tcp_rsk(fastopen)->snt_isn : tp->snd_una; -@@ -401,11 +410,15 @@ - goto out; - - tp->mtu_info = ntohl(info); -- if (!sock_owned_by_user(sk)) -+ if (!sock_owned_by_user(meta_sk)) - tcp_v6_mtu_reduced(sk); -- else if (!test_and_set_bit(TCP_MTU_REDUCED_DEFERRED, -+ else { -+ if (!test_and_set_bit(TCP_MTU_REDUCED_DEFERRED, - &tp->tsq_flags)) -- sock_hold(sk); -+ sock_hold(sk); -+ if (mptcp(tp)) -+ mptcp_tsq_flags(sk); -+ } - goto out; - } - -@@ -420,7 +433,7 @@ - if (fastopen && !fastopen->sk) - break; - -- if (!sock_owned_by_user(sk)) { -+ if (!sock_owned_by_user(meta_sk)) { - sk->sk_err = err; - sk->sk_error_report(sk); /* Wake people up to see the error (see connect in sock.c) */ - -@@ -430,14 +443,14 @@ - goto out; - } - -- if (!sock_owned_by_user(sk) && np->recverr) { -+ if (!sock_owned_by_user(meta_sk) && np->recverr) { - sk->sk_err = err; - sk->sk_error_report(sk); - } else - sk->sk_err_soft = err; - - out: -- bh_unlock_sock(sk); -+ bh_unlock_sock(meta_sk); - sock_put(sk); - } - -@@ -483,8 +496,7 @@ - return err; - } - -- --static void tcp_v6_reqsk_destructor(struct request_sock *req) -+void tcp_v6_reqsk_destructor(struct request_sock *req) - { - kfree(inet_rsk(req)->ipv6_opt); - kfree_skb(inet_rsk(req)->pktopts); -@@ -689,9 +701,10 @@ - return false; - } - --static void tcp_v6_init_req(struct request_sock *req, -- const struct sock *sk_listener, -- struct sk_buff *skb) -+static int tcp_v6_init_req(struct request_sock *req, -+ const struct sock *sk_listener, -+ struct sk_buff *skb, -+ bool want_cookie) - { - struct inet_request_sock *ireq = inet_rsk(req); - const struct ipv6_pinfo *np = inet6_sk(sk_listener); -@@ -712,6 +725,8 @@ - atomic_inc(&skb->users); - ireq->pktopts = skb; - } -+ -+ return 0; - } - - static struct dst_entry *tcp_v6_route_req(const struct sock *sk, -@@ -734,7 +749,7 @@ - .syn_ack_timeout = tcp_syn_ack_timeout, - }; - --static const struct tcp_request_sock_ops tcp_request_sock_ipv6_ops = { -+const struct tcp_request_sock_ops tcp_request_sock_ipv6_ops = { - .mss_clamp = IPV6_MIN_MTU - sizeof(struct tcphdr) - - sizeof(struct ipv6hdr), - #ifdef CONFIG_TCP_MD5SIG -@@ -751,9 +766,9 @@ - }; - - static void tcp_v6_send_response(const struct sock *sk, struct sk_buff *skb, u32 seq, -- u32 ack, u32 win, u32 tsval, u32 tsecr, -+ u32 ack, u32 data_ack, u32 win, u32 tsval, u32 tsecr, - int oif, struct tcp_md5sig_key *key, int rst, -- u8 tclass, __be32 label) -+ u8 tclass, __be32 label, int mptcp) - { - const struct tcphdr *th = tcp_hdr(skb); - struct tcphdr *t1; -@@ -771,7 +786,10 @@ - if (key) - tot_len += TCPOLEN_MD5SIG_ALIGNED; - #endif -- -+#ifdef CONFIG_MPTCP -+ if (mptcp) -+ tot_len += MPTCP_SUB_LEN_DSS + MPTCP_SUB_LEN_ACK; -+#endif - buff = alloc_skb(MAX_HEADER + sizeof(struct ipv6hdr) + tot_len, - GFP_ATOMIC); - if (!buff) -@@ -809,6 +827,17 @@ - tcp_v6_md5_hash_hdr((__u8 *)topt, key, - &ipv6_hdr(skb)->saddr, - &ipv6_hdr(skb)->daddr, t1); -+ topt += 4; -+ } -+#endif -+#ifdef CONFIG_MPTCP -+ if (mptcp) { -+ /* Construction of 32-bit data_ack */ -+ *topt++ = htonl((TCPOPT_MPTCP << 24) | -+ ((MPTCP_SUB_LEN_DSS + MPTCP_SUB_LEN_ACK) << 16) | -+ (0x20 << 8) | -+ (0x01)); -+ *topt++ = htonl(data_ack); - } - #endif - -@@ -854,7 +883,7 @@ - kfree_skb(buff); - } - --static void tcp_v6_send_reset(const struct sock *sk, struct sk_buff *skb) -+void tcp_v6_send_reset(const struct sock *sk, struct sk_buff *skb) - { - const struct tcphdr *th = tcp_hdr(skb); - u32 seq = 0, ack_seq = 0; -@@ -915,7 +944,7 @@ - (th->doff << 2); - - oif = sk ? sk->sk_bound_dev_if : 0; -- tcp_v6_send_response(sk, skb, seq, ack_seq, 0, 0, 0, oif, key, 1, 0, 0); -+ tcp_v6_send_response(sk, skb, seq, ack_seq, 0, 0, 0, 0, oif, key, 1, 0, 0, 0); - - #ifdef CONFIG_TCP_MD5SIG - out: -@@ -924,30 +953,37 @@ - } - - static void tcp_v6_send_ack(const struct sock *sk, struct sk_buff *skb, u32 seq, -- u32 ack, u32 win, u32 tsval, u32 tsecr, int oif, -+ u32 ack, u32 data_ack, u32 win, u32 tsval, u32 tsecr, int oif, - struct tcp_md5sig_key *key, u8 tclass, -- __be32 label) -+ __be32 label, int mptcp) - { -- tcp_v6_send_response(sk, skb, seq, ack, win, tsval, tsecr, oif, key, 0, -- tclass, label); -+ tcp_v6_send_response(sk, skb, seq, ack, data_ack, win, tsval, tsecr, oif, -+ key, 0, tclass, label, mptcp); - } - - static void tcp_v6_timewait_ack(struct sock *sk, struct sk_buff *skb) - { - struct inet_timewait_sock *tw = inet_twsk(sk); - struct tcp_timewait_sock *tcptw = tcp_twsk(sk); -+ u32 data_ack = 0; -+ int mptcp = 0; - -+ if (tcptw->mptcp_tw) { -+ data_ack = (u32)tcptw->mptcp_tw->rcv_nxt; -+ mptcp = 1; -+ } - tcp_v6_send_ack(sk, skb, tcptw->tw_snd_nxt, tcptw->tw_rcv_nxt, -+ data_ack, - tcptw->tw_rcv_wnd >> tw->tw_rcv_wscale, - tcp_time_stamp + tcptw->tw_ts_offset, - tcptw->tw_ts_recent, tw->tw_bound_dev_if, tcp_twsk_md5_key(tcptw), -- tw->tw_tclass, cpu_to_be32(tw->tw_flowlabel)); -+ tw->tw_tclass, cpu_to_be32(tw->tw_flowlabel), mptcp); - - inet_twsk_put(tw); - } - --static void tcp_v6_reqsk_send_ack(const struct sock *sk, struct sk_buff *skb, -- struct request_sock *req) -+void tcp_v6_reqsk_send_ack(const struct sock *sk, struct sk_buff *skb, -+ struct request_sock *req) - { - /* sk->sk_state == TCP_LISTEN -> for regular TCP_SYN_RECV - * sk->sk_state == TCP_SYN_RECV -> for Fast Open. -@@ -957,17 +993,17 @@ - * exception of segments, MUST be right-shifted by - * Rcv.Wind.Shift bits: - */ -- tcp_v6_send_ack(sk, skb, (sk->sk_state == TCP_LISTEN) ? -+ tcp_v6_send_ack(sk, skb, (sk->sk_state == TCP_LISTEN || is_meta_sk(sk)) ? - tcp_rsk(req)->snt_isn + 1 : tcp_sk(sk)->snd_nxt, -- tcp_rsk(req)->rcv_nxt, -+ tcp_rsk(req)->rcv_nxt, 0, - req->rsk_rcv_wnd >> inet_rsk(req)->rcv_wscale, - tcp_time_stamp, req->ts_recent, sk->sk_bound_dev_if, - tcp_v6_md5_do_lookup(sk, &ipv6_hdr(skb)->saddr), -- 0, 0); -+ 0, 0, 0); - } - - --static struct sock *tcp_v6_cookie_check(struct sock *sk, struct sk_buff *skb) -+struct sock *tcp_v6_cookie_check(struct sock *sk, struct sk_buff *skb) - { - #ifdef CONFIG_SYN_COOKIES - const struct tcphdr *th = tcp_hdr(skb); -@@ -978,7 +1014,7 @@ - return sk; - } - --static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb) -+int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb) - { - if (skb->protocol == htons(ETH_P_IP)) - return tcp_v4_conn_request(sk, skb); -@@ -1004,11 +1040,11 @@ - sizeof(struct inet6_skb_parm)); - } - --static struct sock *tcp_v6_syn_recv_sock(const struct sock *sk, struct sk_buff *skb, -- struct request_sock *req, -- struct dst_entry *dst, -- struct request_sock *req_unhash, -- bool *own_req) -+struct sock *tcp_v6_syn_recv_sock(const struct sock *sk, struct sk_buff *skb, -+ struct request_sock *req, -+ struct dst_entry *dst, -+ struct request_sock *req_unhash, -+ bool *own_req) - { - struct inet_request_sock *ireq; - struct ipv6_pinfo *newnp; -@@ -1045,7 +1081,15 @@ - - newnp->saddr = newsk->sk_v6_rcv_saddr; - -- inet_csk(newsk)->icsk_af_ops = &ipv6_mapped; -+#ifdef CONFIG_MPTCP -+ /* We must check on the request-socket because the listener -+ * socket's flag may have been changed halfway through. -+ */ -+ if (!inet_rsk(req)->saw_mpc) -+ inet_csk(newsk)->icsk_af_ops = &mptcp_v6_mapped; -+ else -+#endif -+ inet_csk(newsk)->icsk_af_ops = &ipv6_mapped; - newsk->sk_backlog_rcv = tcp_v4_do_rcv; - #ifdef CONFIG_TCP_MD5SIG - newtp->af_specific = &tcp_sock_ipv6_mapped_specific; -@@ -1092,6 +1136,14 @@ - if (!newsk) - goto out_nonewsk; - -+#ifdef CONFIG_MPTCP -+ /* If the meta_sk is v6-mapped we can end up here with the wrong af_ops. -+ * Just make sure that this subflow is v6. -+ */ -+ if (is_meta_sk(sk)) -+ inet_csk(newsk)->icsk_af_ops = &mptcp_v6_specific; -+#endif -+ - /* - * No need to charge this sock to the relevant IPv6 refcnt debug socks - * count here, tcp_create_openreq_child now does this for us, see the -@@ -1223,7 +1275,7 @@ - * This is because we cannot sleep with the original spinlock - * held. - */ --static int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb) -+int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb) - { - struct ipv6_pinfo *np = inet6_sk(sk); - struct tcp_sock *tp; -@@ -1240,6 +1292,9 @@ - if (skb->protocol == htons(ETH_P_IP)) - return tcp_v4_do_rcv(sk, skb); - -+ if (is_meta_sk(sk)) -+ return mptcp_v6_do_rcv(sk, skb); -+ - if (tcp_filter(sk, skb)) - goto discard; - -@@ -1372,6 +1427,10 @@ - TCP_SKB_CB(skb)->end_seq = (TCP_SKB_CB(skb)->seq + th->syn + th->fin + - skb->len - th->doff*4); - TCP_SKB_CB(skb)->ack_seq = ntohl(th->ack_seq); -+#ifdef CONFIG_MPTCP -+ TCP_SKB_CB(skb)->mptcp_flags = 0; -+ TCP_SKB_CB(skb)->dss_off = 0; -+#endif - TCP_SKB_CB(skb)->tcp_flags = tcp_flag_byte(th); - TCP_SKB_CB(skb)->tcp_tw_isn = 0; - TCP_SKB_CB(skb)->ip_dsfield = ipv6_get_dsfield(hdr); -@@ -1382,8 +1441,8 @@ - { - const struct tcphdr *th; - const struct ipv6hdr *hdr; -+ struct sock *sk, *meta_sk = NULL; - bool refcounted; -- struct sock *sk; - int ret; - struct net *net = dev_net(skb->dev); - -@@ -1437,19 +1496,53 @@ - reqsk_put(req); - goto csum_error; - } -- if (unlikely(sk->sk_state != TCP_LISTEN)) { -+ if (unlikely(sk->sk_state != TCP_LISTEN && !is_meta_sk(sk))) { - inet_csk_reqsk_queue_drop_and_put(sk, req); - goto lookup; - } - sock_hold(sk); - refcounted = true; -+ -+ if (is_meta_sk(sk)) { -+ bh_lock_sock(sk); -+ -+ if (!mptcp_can_new_subflow(sk)) { -+ inet_csk_reqsk_queue_drop_and_put(sk, req); -+ bh_unlock_sock(sk); -+ -+ goto discard_and_relse; -+ } -+ -+ if (sock_owned_by_user(sk)) { -+ mptcp_prepare_for_backlog(sk, skb); -+ if (unlikely(sk_add_backlog(sk, skb, -+ sk->sk_rcvbuf + sk->sk_sndbuf))) { -+ reqsk_put(req); -+ -+ bh_unlock_sock(sk); -+ __NET_INC_STATS(net, LINUX_MIB_TCPBACKLOGDROP); -+ goto discard_and_relse; -+ } -+ -+ reqsk_put(req); -+ bh_unlock_sock(sk); -+ sock_put(sk); -+ -+ return 0; -+ } -+ } -+ - nsk = tcp_check_req(sk, skb, req, false); - if (!nsk) { - reqsk_put(req); -+ if (is_meta_sk(sk)) -+ bh_unlock_sock(sk); - goto discard_and_relse; - } - if (nsk == sk) { - reqsk_put(req); -+ if (is_meta_sk(sk)) -+ bh_unlock_sock(sk); - tcp_v6_restore_cb(skb); - } else if (tcp_child_process(sk, nsk, skb)) { - tcp_v6_send_reset(nsk, skb); -@@ -1459,6 +1552,7 @@ - return 0; - } - } -+ - if (hdr->hop_limit < inet6_sk(sk)->min_hopcount) { - __NET_INC_STATS(net, LINUX_MIB_TCPMINTTLDROP); - goto discard_and_relse; -@@ -1486,16 +1580,26 @@ - - sk_incoming_cpu_update(sk); - -- bh_lock_sock_nested(sk); -+ if (mptcp(tcp_sk(sk))) { -+ meta_sk = mptcp_meta_sk(sk); -+ -+ bh_lock_sock_nested(meta_sk); -+ if (sock_owned_by_user(meta_sk)) -+ mptcp_prepare_for_backlog(sk, skb); -+ } else { -+ meta_sk = sk; -+ bh_lock_sock_nested(sk); -+ } - tcp_segs_in(tcp_sk(sk), skb); - ret = 0; -- if (!sock_owned_by_user(sk)) { -- if (!tcp_prequeue(sk, skb)) -+ if (!sock_owned_by_user(meta_sk)) { -+ if (!tcp_prequeue(meta_sk, skb)) - ret = tcp_v6_do_rcv(sk, skb); -- } else if (tcp_add_backlog(sk, skb)) { -+ } else if (tcp_add_backlog(meta_sk, skb)) { - goto discard_and_relse; - } -- bh_unlock_sock(sk); -+ -+ bh_unlock_sock(meta_sk); - - put_and_return: - if (refcounted) -@@ -1508,6 +1612,19 @@ - - tcp_v6_fill_cb(skb, hdr, th); - -+#ifdef CONFIG_MPTCP -+ if (!sk && th->syn && !th->ack) { -+ int ret = mptcp_lookup_join(skb, NULL); -+ -+ if (ret < 0) { -+ tcp_v6_send_reset(NULL, skb); -+ goto discard_it; -+ } else if (ret > 0) { -+ return 0; -+ } -+ } -+#endif -+ - if (tcp_checksum_complete(skb)) { - csum_error: - __TCP_INC_STATS(net, TCP_MIB_CSUMERRORS); -@@ -1558,6 +1675,18 @@ - refcounted = false; - goto process; - } -+#ifdef CONFIG_MPTCP -+ if (th->syn && !th->ack) { -+ int ret = mptcp_lookup_join(skb, inet_twsk(sk)); -+ -+ if (ret < 0) { -+ tcp_v6_send_reset(NULL, skb); -+ goto discard_it; -+ } else if (ret > 0) { -+ return 0; -+ } -+ } -+#endif - /* Fall through to ACK */ - } - case TCP_TW_ACK: -@@ -1612,13 +1741,13 @@ - } - } - --static struct timewait_sock_ops tcp6_timewait_sock_ops = { -+struct timewait_sock_ops tcp6_timewait_sock_ops = { - .twsk_obj_size = sizeof(struct tcp6_timewait_sock), - .twsk_unique = tcp_twsk_unique, - .twsk_destructor = tcp_twsk_destructor, - }; - --static const struct inet_connection_sock_af_ops ipv6_specific = { -+const struct inet_connection_sock_af_ops ipv6_specific = { - .queue_xmit = inet6_csk_xmit, - .send_check = tcp_v6_send_check, - .rebuild_header = inet6_sk_rebuild_header, -@@ -1650,7 +1779,7 @@ - /* - * TCP over IPv4 via INET6 API - */ --static const struct inet_connection_sock_af_ops ipv6_mapped = { -+const struct inet_connection_sock_af_ops ipv6_mapped = { - .queue_xmit = ip_queue_xmit, - .send_check = tcp_v4_send_check, - .rebuild_header = inet_sk_rebuild_header, -@@ -1687,7 +1816,12 @@ - - tcp_init_sock(sk); - -- icsk->icsk_af_ops = &ipv6_specific; -+#ifdef CONFIG_MPTCP -+ if (sock_flag(sk, SOCK_MPTCP)) -+ icsk->icsk_af_ops = &mptcp_v6_specific; -+ else -+#endif -+ icsk->icsk_af_ops = &ipv6_specific; - - #ifdef CONFIG_TCP_MD5SIG - tcp_sk(sk)->af_specific = &tcp_sock_ipv6_specific; -@@ -1696,7 +1830,7 @@ - return 0; - } - --static void tcp_v6_destroy_sock(struct sock *sk) -+void tcp_v6_destroy_sock(struct sock *sk) - { - tcp_v4_destroy_sock(sk); - inet6_destroy_sock(sk); -@@ -1928,6 +2062,9 @@ - .compat_getsockopt = compat_tcp_getsockopt, - #endif - .diag_destroy = tcp_abort, -+#ifdef CONFIG_MPTCP -+ .clear_sk = mptcp_clear_sk, -+#endif - }; - - static const struct inet6_protocol tcpv6_protocol = { -diff -aurN linux-4.9.162/net/Kconfig mptcp-mptcp_v0.93/net/Kconfig ---- linux-4.9.162/net/Kconfig 2019-03-05 17:57:07.000000000 +0100 -+++ mptcp-mptcp_v0.93/net/Kconfig 2019-03-14 14:02:32.000000000 +0100 -@@ -86,6 +86,7 @@ - source "net/ipv4/Kconfig" - source "net/ipv6/Kconfig" - source "net/netlabel/Kconfig" -+source "net/mptcp/Kconfig" - - endif # if INET - -diff -aurN linux-4.9.162/net/Makefile mptcp-mptcp_v0.93/net/Makefile ---- linux-4.9.162/net/Makefile 2019-03-05 17:57:07.000000000 +0100 -+++ mptcp-mptcp_v0.93/net/Makefile 2019-03-14 14:02:32.000000000 +0100 -@@ -18,6 +18,7 @@ - obj-$(CONFIG_XFRM) += xfrm/ - obj-$(CONFIG_UNIX) += unix/ - obj-$(CONFIG_NET) += ipv6/ -+obj-$(CONFIG_MPTCP) += mptcp/ - obj-$(CONFIG_PACKET) += packet/ - obj-$(CONFIG_NET_KEY) += key/ - obj-$(CONFIG_BRIDGE) += bridge/ -diff -aurN linux-4.9.162/net/mptcp/Kconfig mptcp-mptcp_v0.93/net/mptcp/Kconfig ---- linux-4.9.162/net/mptcp/Kconfig 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_v0.93/net/mptcp/Kconfig 2019-03-14 14:02:32.000000000 +0100 -@@ -0,0 +1,129 @@ -+# -+# MPTCP configuration -+# -+config MPTCP -+ bool "MPTCP protocol" -+ depends on (IPV6=y || IPV6=n) -+ ---help--- -+ This replaces the normal TCP stack with a Multipath TCP stack, -+ able to use several paths at once. -+ -+menuconfig MPTCP_PM_ADVANCED -+ bool "MPTCP: advanced path-manager control" -+ depends on MPTCP=y -+ ---help--- -+ Support for selection of different path-managers. You should choose 'Y' here, -+ because otherwise you will not actively create new MPTCP-subflows. -+ -+if MPTCP_PM_ADVANCED -+ -+config MPTCP_FULLMESH -+ tristate "MPTCP Full-Mesh Path-Manager" -+ depends on MPTCP=y -+ ---help--- -+ This path-management module will create a full-mesh among all IP-addresses. -+ -+config MPTCP_NDIFFPORTS -+ tristate "MPTCP ndiff-ports" -+ depends on MPTCP=y -+ ---help--- -+ This path-management module will create multiple subflows between the same -+ pair of IP-addresses, modifying the source-port. You can set the number -+ of subflows via the mptcp_ndiffports-sysctl. -+ -+config MPTCP_BINDER -+ tristate "MPTCP Binder" -+ depends on (MPTCP=y) -+ ---help--- -+ This path-management module works like ndiffports, and adds the sysctl -+ option to set the gateway (and/or path to) per each additional subflow -+ via Loose Source Routing (IPv4 only). -+ -+choice -+ prompt "Default MPTCP Path-Manager" -+ default DEFAULT -+ help -+ Select the Path-Manager of your choice -+ -+ config DEFAULT_FULLMESH -+ bool "Full mesh" if MPTCP_FULLMESH=y -+ -+ config DEFAULT_NDIFFPORTS -+ bool "ndiff-ports" if MPTCP_NDIFFPORTS=y -+ -+ config DEFAULT_BINDER -+ bool "binder" if MPTCP_BINDER=y -+ -+ config DEFAULT_DUMMY -+ bool "Default" -+ -+endchoice -+ -+endif -+ -+config DEFAULT_MPTCP_PM -+ string -+ default "default" if DEFAULT_DUMMY -+ default "fullmesh" if DEFAULT_FULLMESH -+ default "ndiffports" if DEFAULT_NDIFFPORTS -+ default "binder" if DEFAULT_BINDER -+ default "default" -+ -+menuconfig MPTCP_SCHED_ADVANCED -+ bool "MPTCP: advanced scheduler control" -+ depends on MPTCP=y -+ ---help--- -+ Support for selection of different schedulers. You should choose 'Y' here, -+ if you want to choose a different scheduler than the default one. -+ -+if MPTCP_SCHED_ADVANCED -+ -+config MPTCP_ROUNDROBIN -+ tristate "MPTCP Round-Robin" -+ depends on (MPTCP=y) -+ ---help--- -+ This is a very simple round-robin scheduler. Probably has bad performance -+ but might be interesting for researchers. -+ -+config MPTCP_REDUNDANT -+ tristate "MPTCP Redundant" -+ depends on (MPTCP=y) -+ ---help--- -+ This scheduler sends all packets redundantly over all subflows to decreases -+ latency and jitter on the cost of lower throughput. -+ -+choice -+ prompt "Default MPTCP Scheduler" -+ default DEFAULT -+ help -+ Select the Scheduler of your choice -+ -+ config DEFAULT_SCHEDULER -+ bool "Default" -+ ---help--- -+ This is the default scheduler, sending first on the subflow -+ with the lowest RTT. -+ -+ config DEFAULT_ROUNDROBIN -+ bool "Round-Robin" if MPTCP_ROUNDROBIN=y -+ ---help--- -+ This is the round-rob scheduler, sending in a round-robin -+ fashion.. -+ -+ config DEFAULT_REDUNDANT -+ bool "Redundant" if MPTCP_REDUNDANT=y -+ ---help--- -+ This is the redundant scheduler, sending packets redundantly over -+ all the subflows. -+ -+endchoice -+endif -+ -+config DEFAULT_MPTCP_SCHED -+ string -+ depends on (MPTCP=y) -+ default "default" if DEFAULT_SCHEDULER -+ default "roundrobin" if DEFAULT_ROUNDROBIN -+ default "redundant" if DEFAULT_REDUNDANT -+ default "default" -+ -diff -aurN linux-4.9.162/net/mptcp/Makefile mptcp-mptcp_v0.93/net/mptcp/Makefile ---- linux-4.9.162/net/mptcp/Makefile 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_v0.93/net/mptcp/Makefile 2019-03-14 14:02:32.000000000 +0100 -@@ -0,0 +1,22 @@ -+# -+## Makefile for MultiPath TCP support code. -+# -+# -+ -+obj-$(CONFIG_MPTCP) += mptcp.o -+ -+mptcp-y := mptcp_ctrl.o mptcp_ipv4.o mptcp_pm.o \ -+ mptcp_output.o mptcp_input.o mptcp_sched.o -+ -+obj-$(CONFIG_TCP_CONG_LIA) += mptcp_coupled.o -+obj-$(CONFIG_TCP_CONG_OLIA) += mptcp_olia.o -+obj-$(CONFIG_TCP_CONG_WVEGAS) += mptcp_wvegas.o -+obj-$(CONFIG_TCP_CONG_BALIA) += mptcp_balia.o -+obj-$(CONFIG_MPTCP_FULLMESH) += mptcp_fullmesh.o -+obj-$(CONFIG_MPTCP_NDIFFPORTS) += mptcp_ndiffports.o -+obj-$(CONFIG_MPTCP_BINDER) += mptcp_binder.o -+obj-$(CONFIG_MPTCP_ROUNDROBIN) += mptcp_rr.o -+obj-$(CONFIG_MPTCP_REDUNDANT) += mptcp_redundant.o -+ -+mptcp-$(subst m,y,$(CONFIG_IPV6)) += mptcp_ipv6.o -+ -diff -aurN linux-4.9.162/net/mptcp/mptcp_balia.c mptcp-mptcp_v0.93/net/mptcp/mptcp_balia.c ---- linux-4.9.162/net/mptcp/mptcp_balia.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_v0.93/net/mptcp/mptcp_balia.c 2019-03-14 14:02:32.000000000 +0100 -@@ -0,0 +1,267 @@ -+/* -+ * MPTCP implementation - Balia Congestion Control -+ * (Balanced Linked Adaptation Algorithm) -+ * -+ * Analysis, Design and Implementation: -+ * Qiuyu Peng -+ * Anwar Walid -+ * Jaehyun Hwang -+ * Steven H. Low -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version -+ * 2 of the License, or (at your option) any later version. -+ */ -+ -+#include -+#include -+ -+#include -+ -+/* The variable 'rate' (i.e., x_r) will be scaled -+ * e.g., from B/s to KB/s, MB/s, or GB/s -+ * if max_rate > 2^rate_scale_limit -+ */ -+ -+static int rate_scale_limit = 25; -+static int alpha_scale = 10; -+static int scale_num = 5; -+ -+struct mptcp_balia { -+ u64 ai; -+ u64 md; -+ bool forced_update; -+}; -+ -+static inline int mptcp_balia_sk_can_send(const struct sock *sk) -+{ -+ return mptcp_sk_can_send(sk) && tcp_sk(sk)->srtt_us; -+} -+ -+static inline u64 mptcp_get_ai(const struct sock *meta_sk) -+{ -+ return ((struct mptcp_balia *)inet_csk_ca(meta_sk))->ai; -+} -+ -+static inline void mptcp_set_ai(const struct sock *meta_sk, u64 ai) -+{ -+ ((struct mptcp_balia *)inet_csk_ca(meta_sk))->ai = ai; -+} -+ -+static inline u64 mptcp_get_md(const struct sock *meta_sk) -+{ -+ return ((struct mptcp_balia *)inet_csk_ca(meta_sk))->md; -+} -+ -+static inline void mptcp_set_md(const struct sock *meta_sk, u64 md) -+{ -+ ((struct mptcp_balia *)inet_csk_ca(meta_sk))->md = md; -+} -+ -+static inline u64 mptcp_balia_scale(u64 val, int scale) -+{ -+ return (u64) val << scale; -+} -+ -+static inline bool mptcp_get_forced(const struct sock *meta_sk) -+{ -+ return ((struct mptcp_balia *)inet_csk_ca(meta_sk))->forced_update; -+} -+ -+static inline void mptcp_set_forced(const struct sock *meta_sk, bool force) -+{ -+ ((struct mptcp_balia *)inet_csk_ca(meta_sk))->forced_update = force; -+} -+ -+static void mptcp_balia_recalc_ai(const struct sock *sk) -+{ -+ const struct tcp_sock *tp = tcp_sk(sk); -+ const struct mptcp_cb *mpcb = tp->mpcb; -+ const struct sock *sub_sk; -+ u64 max_rate = 0, rate = 0, sum_rate = 0; -+ u64 alpha, ai = tp->snd_cwnd, md = (tp->snd_cwnd >> 1); -+ int num_scale_down = 0; -+ -+ if (!mpcb) -+ return; -+ -+ /* Only one subflow left - fall back to normal reno-behavior */ -+ if (mpcb->cnt_established <= 1) -+ goto exit; -+ -+ /* Find max_rate first */ -+ mptcp_for_each_sk(mpcb, sub_sk) { -+ struct tcp_sock *sub_tp = tcp_sk(sub_sk); -+ u64 tmp; -+ -+ if (!mptcp_balia_sk_can_send(sub_sk)) -+ continue; -+ -+ tmp = div_u64((u64)tp->mss_cache * sub_tp->snd_cwnd -+ * (USEC_PER_SEC << 3), sub_tp->srtt_us); -+ sum_rate += tmp; -+ -+ if (tp == sub_tp) -+ rate = tmp; -+ -+ if (tmp >= max_rate) -+ max_rate = tmp; -+ } -+ -+ /* At least, the current subflow should be able to send */ -+ if (unlikely(!rate)) -+ goto exit; -+ -+ alpha = div64_u64(max_rate, rate); -+ -+ /* Scale down max_rate if it is too high (e.g., >2^25) */ -+ while (max_rate > mptcp_balia_scale(1, rate_scale_limit)) { -+ max_rate >>= scale_num; -+ num_scale_down++; -+ } -+ -+ if (num_scale_down) { -+ sum_rate = 0; -+ mptcp_for_each_sk(mpcb, sub_sk) { -+ struct tcp_sock *sub_tp = tcp_sk(sub_sk); -+ u64 tmp; -+ -+ if (!mptcp_balia_sk_can_send(sub_sk)) -+ continue; -+ -+ tmp = div_u64((u64)tp->mss_cache * sub_tp->snd_cwnd -+ * (USEC_PER_SEC << 3), sub_tp->srtt_us); -+ tmp >>= (scale_num * num_scale_down); -+ -+ sum_rate += tmp; -+ } -+ rate >>= (scale_num * num_scale_down); -+ } -+ -+ /* (sum_rate)^2 * 10 * w_r -+ * ai = ------------------------------------ -+ * (x_r + max_rate) * (4x_r + max_rate) -+ */ -+ sum_rate *= sum_rate; -+ -+ ai = div64_u64(sum_rate * 10, rate + max_rate); -+ ai = div64_u64(ai * tp->snd_cwnd, (rate << 2) + max_rate); -+ -+ if (unlikely(!ai)) -+ ai = tp->snd_cwnd; -+ -+ md = ((tp->snd_cwnd >> 1) * min(mptcp_balia_scale(alpha, alpha_scale), -+ mptcp_balia_scale(3, alpha_scale) >> 1)) -+ >> alpha_scale; -+ -+exit: -+ mptcp_set_ai(sk, ai); -+ mptcp_set_md(sk, md); -+} -+ -+static void mptcp_balia_init(struct sock *sk) -+{ -+ if (mptcp(tcp_sk(sk))) { -+ mptcp_set_forced(sk, 0); -+ mptcp_set_ai(sk, 0); -+ mptcp_set_md(sk, 0); -+ } -+} -+ -+static void mptcp_balia_cwnd_event(struct sock *sk, enum tcp_ca_event event) -+{ -+ if (event == CA_EVENT_COMPLETE_CWR || event == CA_EVENT_LOSS) -+ mptcp_balia_recalc_ai(sk); -+} -+ -+static void mptcp_balia_set_state(struct sock *sk, u8 ca_state) -+{ -+ if (!mptcp(tcp_sk(sk))) -+ return; -+ -+ mptcp_set_forced(sk, 1); -+} -+ -+static void mptcp_balia_cong_avoid(struct sock *sk, u32 ack, u32 acked) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ const struct mptcp_cb *mpcb = tp->mpcb; -+ int snd_cwnd; -+ -+ if (!mptcp(tp)) { -+ tcp_reno_cong_avoid(sk, ack, acked); -+ return; -+ } -+ -+ if (!tcp_is_cwnd_limited(sk)) -+ return; -+ -+ if (tcp_in_slow_start(tp)) { -+ /* In "safe" area, increase. */ -+ tcp_slow_start(tp, acked); -+ mptcp_balia_recalc_ai(sk); -+ return; -+ } -+ -+ if (mptcp_get_forced(mptcp_meta_sk(sk))) { -+ mptcp_balia_recalc_ai(sk); -+ mptcp_set_forced(sk, 0); -+ } -+ -+ if (mpcb->cnt_established > 1) -+ snd_cwnd = (int) mptcp_get_ai(sk); -+ else -+ snd_cwnd = tp->snd_cwnd; -+ -+ if (tp->snd_cwnd_cnt >= snd_cwnd) { -+ if (tp->snd_cwnd < tp->snd_cwnd_clamp) { -+ tp->snd_cwnd++; -+ mptcp_balia_recalc_ai(sk); -+ } -+ -+ tp->snd_cwnd_cnt = 0; -+ } else { -+ tp->snd_cwnd_cnt++; -+ } -+} -+ -+static u32 mptcp_balia_ssthresh(struct sock *sk) -+{ -+ const struct tcp_sock *tp = tcp_sk(sk); -+ const struct mptcp_cb *mpcb = tp->mpcb; -+ -+ if (unlikely(!mptcp(tp) || mpcb->cnt_established <= 1)) -+ return tcp_reno_ssthresh(sk); -+ else -+ return max((u32)(tp->snd_cwnd - mptcp_get_md(sk)), 1U); -+} -+ -+static struct tcp_congestion_ops mptcp_balia = { -+ .init = mptcp_balia_init, -+ .ssthresh = mptcp_balia_ssthresh, -+ .cong_avoid = mptcp_balia_cong_avoid, -+ .cwnd_event = mptcp_balia_cwnd_event, -+ .set_state = mptcp_balia_set_state, -+ .owner = THIS_MODULE, -+ .name = "balia", -+}; -+ -+static int __init mptcp_balia_register(void) -+{ -+ BUILD_BUG_ON(sizeof(struct mptcp_balia) > ICSK_CA_PRIV_SIZE); -+ return tcp_register_congestion_control(&mptcp_balia); -+} -+ -+static void __exit mptcp_balia_unregister(void) -+{ -+ tcp_unregister_congestion_control(&mptcp_balia); -+} -+ -+module_init(mptcp_balia_register); -+module_exit(mptcp_balia_unregister); -+ -+MODULE_AUTHOR("Jaehyun Hwang, Anwar Walid, Qiuyu Peng, Steven H. Low"); -+MODULE_LICENSE("GPL"); -+MODULE_DESCRIPTION("MPTCP BALIA CONGESTION CONTROL ALGORITHM"); -+MODULE_VERSION("0.1"); -diff -aurN linux-4.9.162/net/mptcp/mptcp_binder.c mptcp-mptcp_v0.93/net/mptcp/mptcp_binder.c ---- linux-4.9.162/net/mptcp/mptcp_binder.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_v0.93/net/mptcp/mptcp_binder.c 2019-03-14 14:02:32.000000000 +0100 -@@ -0,0 +1,486 @@ -+#include -+ -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define MPTCP_GW_MAX_LISTS 10 -+#define MPTCP_GW_LIST_MAX_LEN 6 -+#define MPTCP_GW_SYSCTL_MAX_LEN (15 * MPTCP_GW_LIST_MAX_LEN * \ -+ MPTCP_GW_MAX_LISTS) -+ -+struct mptcp_gw_list { -+ struct in_addr list[MPTCP_GW_MAX_LISTS][MPTCP_GW_LIST_MAX_LEN]; -+ u8 len[MPTCP_GW_MAX_LISTS]; -+}; -+ -+struct binder_priv { -+ /* Worker struct for subflow establishment */ -+ struct work_struct subflow_work; -+ -+ struct mptcp_cb *mpcb; -+ -+ /* Prevent multiple sub-sockets concurrently iterating over sockets */ -+ spinlock_t *flow_lock; -+}; -+ -+static struct mptcp_gw_list *mptcp_gws; -+static rwlock_t mptcp_gws_lock; -+ -+static int mptcp_binder_ndiffports __read_mostly = 1; -+ -+static char sysctl_mptcp_binder_gateways[MPTCP_GW_SYSCTL_MAX_LEN] __read_mostly; -+ -+static int mptcp_get_avail_list_ipv4(struct sock *sk) -+{ -+ int i, j, list_taken, opt_ret, opt_len; -+ unsigned char *opt_ptr, *opt_end_ptr, opt[MAX_IPOPTLEN]; -+ -+ for (i = 0; i < MPTCP_GW_MAX_LISTS; ++i) { -+ if (mptcp_gws->len[i] == 0) -+ goto error; -+ -+ mptcp_debug("mptcp_get_avail_list_ipv4: List %i\n", i); -+ list_taken = 0; -+ -+ /* Loop through all sub-sockets in this connection */ -+ mptcp_for_each_sk(tcp_sk(sk)->mpcb, sk) { -+ mptcp_debug("mptcp_get_avail_list_ipv4: Next sock\n"); -+ -+ /* Reset length and options buffer, then retrieve -+ * from socket -+ */ -+ opt_len = MAX_IPOPTLEN; -+ memset(opt, 0, MAX_IPOPTLEN); -+ opt_ret = ip_getsockopt(sk, IPPROTO_IP, -+ IP_OPTIONS, (char __user *)opt, (int __user *)&opt_len); -+ if (opt_ret < 0) { -+ mptcp_debug("%s: MPTCP subsocket getsockopt() IP_OPTIONS failed, error %d\n", -+ __func__, opt_ret); -+ goto error; -+ } -+ -+ /* If socket has no options, it has no stake in this list */ -+ if (opt_len <= 0) -+ continue; -+ -+ /* Iterate options buffer */ -+ for (opt_ptr = &opt[0]; opt_ptr < &opt[opt_len]; opt_ptr++) { -+ if (*opt_ptr == IPOPT_LSRR) { -+ mptcp_debug("mptcp_get_avail_list_ipv4: LSRR options found\n"); -+ goto sock_lsrr; -+ } -+ } -+ continue; -+ -+sock_lsrr: -+ /* Pointer to the 2nd to last address */ -+ opt_end_ptr = opt_ptr+(*(opt_ptr+1))-4; -+ -+ /* Addresses start 3 bytes after type offset */ -+ opt_ptr += 3; -+ j = 0; -+ -+ /* Different length lists cannot be the same */ -+ if ((opt_end_ptr-opt_ptr)/4 != mptcp_gws->len[i]) -+ continue; -+ -+ /* Iterate if we are still inside options list -+ * and sysctl list -+ */ -+ while (opt_ptr < opt_end_ptr && j < mptcp_gws->len[i]) { -+ /* If there is a different address, this list must -+ * not be set on this socket -+ */ -+ if (memcmp(&mptcp_gws->list[i][j], opt_ptr, 4)) -+ break; -+ -+ /* Jump 4 bytes to next address */ -+ opt_ptr += 4; -+ j++; -+ } -+ -+ /* Reached the end without a differing address, lists -+ * are therefore identical. -+ */ -+ if (j == mptcp_gws->len[i]) { -+ mptcp_debug("mptcp_get_avail_list_ipv4: List already used\n"); -+ list_taken = 1; -+ break; -+ } -+ } -+ -+ /* Free list found if not taken by a socket */ -+ if (!list_taken) { -+ mptcp_debug("mptcp_get_avail_list_ipv4: List free\n"); -+ break; -+ } -+ } -+ -+ if (i >= MPTCP_GW_MAX_LISTS) -+ goto error; -+ -+ return i; -+error: -+ return -1; -+} -+ -+/* The list of addresses is parsed each time a new connection is opened, -+ * to make sure it's up to date. In case of error, all the lists are -+ * marked as unavailable and the subflow's fingerprint is set to 0. -+ */ -+static void mptcp_v4_add_lsrr(struct sock *sk, struct in_addr addr) -+{ -+ int i, j, ret; -+ unsigned char opt[MAX_IPOPTLEN] = {0}; -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct binder_priv *fmp = (struct binder_priv *)&tp->mpcb->mptcp_pm[0]; -+ -+ /* Read lock: multiple sockets can read LSRR addresses at the same -+ * time, but writes are done in mutual exclusion. -+ * Spin lock: must search for free list for one socket at a time, or -+ * multiple sockets could take the same list. -+ */ -+ read_lock(&mptcp_gws_lock); -+ spin_lock(fmp->flow_lock); -+ -+ i = mptcp_get_avail_list_ipv4(sk); -+ -+ /* Execution enters here only if a free path is found. -+ */ -+ if (i >= 0) { -+ opt[0] = IPOPT_NOP; -+ opt[1] = IPOPT_LSRR; -+ opt[2] = sizeof(mptcp_gws->list[i][0].s_addr) * -+ (mptcp_gws->len[i] + 1) + 3; -+ opt[3] = IPOPT_MINOFF; -+ for (j = 0; j < mptcp_gws->len[i]; ++j) -+ memcpy(opt + 4 + -+ (j * sizeof(mptcp_gws->list[i][0].s_addr)), -+ &mptcp_gws->list[i][j].s_addr, -+ sizeof(mptcp_gws->list[i][0].s_addr)); -+ /* Final destination must be part of IP_OPTIONS parameter. */ -+ memcpy(opt + 4 + (j * sizeof(addr.s_addr)), &addr.s_addr, -+ sizeof(addr.s_addr)); -+ -+ /* setsockopt must be inside the lock, otherwise another -+ * subflow could fail to see that we have taken a list. -+ */ -+ ret = ip_setsockopt(sk, IPPROTO_IP, IP_OPTIONS, (char __user *)opt, -+ 4 + sizeof(mptcp_gws->list[i][0].s_addr) * (mptcp_gws->len[i] + 1)); -+ -+ if (ret < 0) { -+ mptcp_debug("%s: MPTCP subsock setsockopt() IP_OPTIONS failed, error %d\n", -+ __func__, ret); -+ } -+ } -+ -+ spin_unlock(fmp->flow_lock); -+ read_unlock(&mptcp_gws_lock); -+ -+ return; -+} -+ -+/* Parses gateways string for a list of paths to different -+ * gateways, and stores them for use with the Loose Source Routing (LSRR) -+ * socket option. Each list must have "," separated addresses, and the lists -+ * themselves must be separated by "-". Returns -1 in case one or more of the -+ * addresses is not a valid ipv4/6 address. -+ */ -+static int mptcp_parse_gateway_ipv4(char *gateways) -+{ -+ int i, j, k, ret; -+ char *tmp_string = NULL; -+ struct in_addr tmp_addr; -+ -+ tmp_string = kzalloc(16, GFP_KERNEL); -+ if (tmp_string == NULL) -+ return -ENOMEM; -+ -+ write_lock(&mptcp_gws_lock); -+ -+ memset(mptcp_gws, 0, sizeof(struct mptcp_gw_list)); -+ -+ /* A TMP string is used since inet_pton needs a null terminated string -+ * but we do not want to modify the sysctl for obvious reasons. -+ * i will iterate over the SYSCTL string, j will iterate over the -+ * temporary string where each IP is copied into, k will iterate over -+ * the IPs in each list. -+ */ -+ for (i = j = k = 0; -+ i < MPTCP_GW_SYSCTL_MAX_LEN && k < MPTCP_GW_MAX_LISTS; -+ ++i) { -+ if (gateways[i] == '-' || gateways[i] == ',' || gateways[i] == '\0') { -+ /* If the temp IP is empty and the current list is -+ * empty, we are done. -+ */ -+ if (j == 0 && mptcp_gws->len[k] == 0) -+ break; -+ -+ /* Terminate the temp IP string, then if it is -+ * non-empty parse the IP and copy it. -+ */ -+ tmp_string[j] = '\0'; -+ if (j > 0) { -+ mptcp_debug("mptcp_parse_gateway_list tmp: %s i: %d\n", tmp_string, i); -+ -+ ret = in4_pton(tmp_string, strlen(tmp_string), -+ (u8 *)&tmp_addr.s_addr, '\0', -+ NULL); -+ -+ if (ret) { -+ mptcp_debug("mptcp_parse_gateway_list ret: %d s_addr: %pI4\n", -+ ret, -+ &tmp_addr.s_addr); -+ memcpy(&mptcp_gws->list[k][mptcp_gws->len[k]].s_addr, -+ &tmp_addr.s_addr, -+ sizeof(tmp_addr.s_addr)); -+ mptcp_gws->len[k]++; -+ j = 0; -+ tmp_string[j] = '\0'; -+ /* Since we can't impose a limit to -+ * what the user can input, make sure -+ * there are not too many IPs in the -+ * SYSCTL string. -+ */ -+ if (mptcp_gws->len[k] > MPTCP_GW_LIST_MAX_LEN) { -+ mptcp_debug("mptcp_parse_gateway_list too many members in list %i: max %i\n", -+ k, -+ MPTCP_GW_LIST_MAX_LEN); -+ goto error; -+ } -+ } else { -+ goto error; -+ } -+ } -+ -+ if (gateways[i] == '-' || gateways[i] == '\0') -+ ++k; -+ } else { -+ tmp_string[j] = gateways[i]; -+ ++j; -+ } -+ } -+ -+ /* Number of flows is number of gateway lists plus master flow */ -+ mptcp_binder_ndiffports = k+1; -+ -+ write_unlock(&mptcp_gws_lock); -+ kfree(tmp_string); -+ -+ return 0; -+ -+error: -+ memset(mptcp_gws, 0, sizeof(struct mptcp_gw_list)); -+ memset(gateways, 0, sizeof(char) * MPTCP_GW_SYSCTL_MAX_LEN); -+ write_unlock(&mptcp_gws_lock); -+ kfree(tmp_string); -+ return -1; -+} -+ -+/** -+ * Create all new subflows, by doing calls to mptcp_initX_subsockets -+ * -+ * This function uses a goto next_subflow, to allow releasing the lock between -+ * new subflows and giving other processes a chance to do some work on the -+ * socket and potentially finishing the communication. -+ **/ -+static void create_subflow_worker(struct work_struct *work) -+{ -+ const struct binder_priv *pm_priv = container_of(work, -+ struct binder_priv, -+ subflow_work); -+ struct mptcp_cb *mpcb = pm_priv->mpcb; -+ struct sock *meta_sk = mpcb->meta_sk; -+ int iter = 0; -+ -+next_subflow: -+ if (iter) { -+ release_sock(meta_sk); -+ mutex_unlock(&mpcb->mpcb_mutex); -+ -+ cond_resched(); -+ } -+ mutex_lock(&mpcb->mpcb_mutex); -+ lock_sock_nested(meta_sk, SINGLE_DEPTH_NESTING); -+ -+ iter++; -+ -+ if (sock_flag(meta_sk, SOCK_DEAD)) -+ goto exit; -+ -+ if (mpcb->master_sk && -+ !tcp_sk(mpcb->master_sk)->mptcp->fully_established) -+ goto exit; -+ -+ if (mptcp_binder_ndiffports > iter && -+ mptcp_binder_ndiffports > mpcb->cnt_subflows) { -+ struct mptcp_loc4 loc; -+ struct mptcp_rem4 rem; -+ -+ loc.addr.s_addr = inet_sk(meta_sk)->inet_saddr; -+ loc.loc4_id = 0; -+ loc.low_prio = 0; -+ -+ rem.addr.s_addr = inet_sk(meta_sk)->inet_daddr; -+ rem.port = inet_sk(meta_sk)->inet_dport; -+ rem.rem4_id = 0; /* Default 0 */ -+ -+ mptcp_init4_subsockets(meta_sk, &loc, &rem); -+ -+ goto next_subflow; -+ } -+ -+exit: -+ release_sock(meta_sk); -+ mutex_unlock(&mpcb->mpcb_mutex); -+ sock_put(meta_sk); -+} -+ -+static void binder_new_session(const struct sock *meta_sk) -+{ -+ struct mptcp_cb *mpcb = tcp_sk(meta_sk)->mpcb; -+ struct binder_priv *fmp = (struct binder_priv *)&mpcb->mptcp_pm[0]; -+ static DEFINE_SPINLOCK(flow_lock); -+ -+#if IS_ENABLED(CONFIG_IPV6) -+ if (meta_sk->sk_family == AF_INET6 && -+ !mptcp_v6_is_v4_mapped(meta_sk)) { -+ mptcp_fallback_default(mpcb); -+ return; -+ } -+#endif -+ -+ /* Initialize workqueue-struct */ -+ INIT_WORK(&fmp->subflow_work, create_subflow_worker); -+ fmp->mpcb = mpcb; -+ -+ fmp->flow_lock = &flow_lock; -+} -+ -+static void binder_create_subflows(struct sock *meta_sk) -+{ -+ struct mptcp_cb *mpcb = tcp_sk(meta_sk)->mpcb; -+ struct binder_priv *pm_priv = (struct binder_priv *)&mpcb->mptcp_pm[0]; -+ -+ if (mpcb->infinite_mapping_snd || mpcb->infinite_mapping_rcv || -+ mpcb->send_infinite_mapping || -+ mpcb->server_side || sock_flag(meta_sk, SOCK_DEAD)) -+ return; -+ -+ if (!work_pending(&pm_priv->subflow_work)) { -+ sock_hold(meta_sk); -+ queue_work(mptcp_wq, &pm_priv->subflow_work); -+ } -+} -+ -+static int binder_get_local_id(sa_family_t family, union inet_addr *addr, -+ struct net *net, bool *low_prio) -+{ -+ return 0; -+} -+ -+/* Callback functions, executed when syctl mptcp.mptcp_gateways is updated. -+ * Inspired from proc_tcp_congestion_control(). -+ */ -+static int proc_mptcp_gateways(struct ctl_table *ctl, int write, -+ void __user *buffer, size_t *lenp, -+ loff_t *ppos) -+{ -+ int ret; -+ struct ctl_table tbl = { -+ .maxlen = MPTCP_GW_SYSCTL_MAX_LEN, -+ }; -+ -+ if (write) { -+ tbl.data = kzalloc(MPTCP_GW_SYSCTL_MAX_LEN, GFP_KERNEL); -+ if (tbl.data == NULL) -+ return -ENOMEM; -+ ret = proc_dostring(&tbl, write, buffer, lenp, ppos); -+ if (ret == 0) { -+ ret = mptcp_parse_gateway_ipv4(tbl.data); -+ memcpy(ctl->data, tbl.data, MPTCP_GW_SYSCTL_MAX_LEN); -+ } -+ kfree(tbl.data); -+ } else { -+ ret = proc_dostring(ctl, write, buffer, lenp, ppos); -+ } -+ -+ -+ return ret; -+} -+ -+static struct mptcp_pm_ops binder __read_mostly = { -+ .new_session = binder_new_session, -+ .fully_established = binder_create_subflows, -+ .get_local_id = binder_get_local_id, -+ .init_subsocket_v4 = mptcp_v4_add_lsrr, -+ .name = "binder", -+ .owner = THIS_MODULE, -+}; -+ -+static struct ctl_table binder_table[] = { -+ { -+ .procname = "mptcp_binder_gateways", -+ .data = &sysctl_mptcp_binder_gateways, -+ .maxlen = sizeof(char) * MPTCP_GW_SYSCTL_MAX_LEN, -+ .mode = 0644, -+ .proc_handler = &proc_mptcp_gateways -+ }, -+ { } -+}; -+ -+static struct ctl_table_header *mptcp_sysctl_binder; -+ -+/* General initialization of MPTCP_PM */ -+static int __init binder_register(void) -+{ -+ mptcp_gws = kzalloc(sizeof(*mptcp_gws), GFP_KERNEL); -+ if (!mptcp_gws) -+ return -ENOMEM; -+ -+ rwlock_init(&mptcp_gws_lock); -+ -+ BUILD_BUG_ON(sizeof(struct binder_priv) > MPTCP_PM_SIZE); -+ -+ mptcp_sysctl_binder = register_net_sysctl(&init_net, "net/mptcp", -+ binder_table); -+ if (!mptcp_sysctl_binder) -+ goto sysctl_fail; -+ -+ if (mptcp_register_path_manager(&binder)) -+ goto pm_failed; -+ -+ return 0; -+ -+pm_failed: -+ unregister_net_sysctl_table(mptcp_sysctl_binder); -+sysctl_fail: -+ kfree(mptcp_gws); -+ -+ return -1; -+} -+ -+static void binder_unregister(void) -+{ -+ mptcp_unregister_path_manager(&binder); -+ unregister_net_sysctl_table(mptcp_sysctl_binder); -+ kfree(mptcp_gws); -+} -+ -+module_init(binder_register); -+module_exit(binder_unregister); -+ -+MODULE_AUTHOR("Luca Boccassi, Duncan Eastoe, Christoph Paasch (ndiffports)"); -+MODULE_LICENSE("GPL"); -+MODULE_DESCRIPTION("BINDER MPTCP"); -+MODULE_VERSION("0.1"); -diff -aurN linux-4.9.162/net/mptcp/mptcp_coupled.c mptcp-mptcp_v0.93/net/mptcp/mptcp_coupled.c ---- linux-4.9.162/net/mptcp/mptcp_coupled.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_v0.93/net/mptcp/mptcp_coupled.c 2019-03-14 14:02:32.000000000 +0100 -@@ -0,0 +1,270 @@ -+/* -+ * MPTCP implementation - Linked Increase congestion control Algorithm (LIA) -+ * -+ * Initial Design & Implementation: -+ * Sébastien Barré -+ * -+ * Current Maintainer & Author: -+ * Christoph Paasch -+ * -+ * Additional authors: -+ * Jaakko Korkeaniemi -+ * Gregory Detal -+ * Fabien Duchêne -+ * Andreas Seelinger -+ * Lavkesh Lahngir -+ * Andreas Ripke -+ * Vlad Dogaru -+ * Octavian Purdila -+ * John Ronan -+ * Catalin Nicutar -+ * Brandon Heller -+ * -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version -+ * 2 of the License, or (at your option) any later version. -+ */ -+#include -+#include -+ -+#include -+ -+/* Scaling is done in the numerator with alpha_scale_num and in the denominator -+ * with alpha_scale_den. -+ * -+ * To downscale, we just need to use alpha_scale. -+ * -+ * We have: alpha_scale = alpha_scale_num / (alpha_scale_den ^ 2) -+ */ -+static int alpha_scale_den = 10; -+static int alpha_scale_num = 32; -+static int alpha_scale = 12; -+ -+struct mptcp_ccc { -+ u64 alpha; -+ bool forced_update; -+}; -+ -+static inline int mptcp_ccc_sk_can_send(const struct sock *sk) -+{ -+ return mptcp_sk_can_send(sk) && tcp_sk(sk)->srtt_us; -+} -+ -+static inline u64 mptcp_get_alpha(const struct sock *meta_sk) -+{ -+ return ((struct mptcp_ccc *)inet_csk_ca(meta_sk))->alpha; -+} -+ -+static inline void mptcp_set_alpha(const struct sock *meta_sk, u64 alpha) -+{ -+ ((struct mptcp_ccc *)inet_csk_ca(meta_sk))->alpha = alpha; -+} -+ -+static inline u64 mptcp_ccc_scale(u32 val, int scale) -+{ -+ return (u64) val << scale; -+} -+ -+static inline bool mptcp_get_forced(const struct sock *meta_sk) -+{ -+ return ((struct mptcp_ccc *)inet_csk_ca(meta_sk))->forced_update; -+} -+ -+static inline void mptcp_set_forced(const struct sock *meta_sk, bool force) -+{ -+ ((struct mptcp_ccc *)inet_csk_ca(meta_sk))->forced_update = force; -+} -+ -+static void mptcp_ccc_recalc_alpha(const struct sock *sk) -+{ -+ const struct mptcp_cb *mpcb = tcp_sk(sk)->mpcb; -+ const struct sock *sub_sk; -+ int best_cwnd = 0, best_rtt = 0, can_send = 0; -+ u64 max_numerator = 0, sum_denominator = 0, alpha = 1; -+ -+ if (!mpcb) -+ return; -+ -+ /* Only one subflow left - fall back to normal reno-behavior -+ * (set alpha to 1) -+ */ -+ if (mpcb->cnt_established <= 1) -+ goto exit; -+ -+ /* Do regular alpha-calculation for multiple subflows */ -+ -+ /* Find the max numerator of the alpha-calculation */ -+ mptcp_for_each_sk(mpcb, sub_sk) { -+ struct tcp_sock *sub_tp = tcp_sk(sub_sk); -+ u64 tmp; -+ -+ if (!mptcp_ccc_sk_can_send(sub_sk)) -+ continue; -+ -+ can_send++; -+ -+ /* We need to look for the path, that provides the max-value. -+ * Integer-overflow is not possible here, because -+ * tmp will be in u64. -+ */ -+ tmp = div64_u64(mptcp_ccc_scale(sub_tp->snd_cwnd, -+ alpha_scale_num), (u64)sub_tp->srtt_us * sub_tp->srtt_us); -+ -+ if (tmp >= max_numerator) { -+ max_numerator = tmp; -+ best_cwnd = sub_tp->snd_cwnd; -+ best_rtt = sub_tp->srtt_us; -+ } -+ } -+ -+ /* No subflow is able to send - we don't care anymore */ -+ if (unlikely(!can_send)) -+ goto exit; -+ -+ /* Calculate the denominator */ -+ mptcp_for_each_sk(mpcb, sub_sk) { -+ struct tcp_sock *sub_tp = tcp_sk(sub_sk); -+ -+ if (!mptcp_ccc_sk_can_send(sub_sk)) -+ continue; -+ -+ sum_denominator += div_u64( -+ mptcp_ccc_scale(sub_tp->snd_cwnd, -+ alpha_scale_den) * best_rtt, -+ sub_tp->srtt_us); -+ } -+ sum_denominator *= sum_denominator; -+ if (unlikely(!sum_denominator)) { -+ pr_err("%s: sum_denominator == 0, cnt_established:%d\n", -+ __func__, mpcb->cnt_established); -+ mptcp_for_each_sk(mpcb, sub_sk) { -+ struct tcp_sock *sub_tp = tcp_sk(sub_sk); -+ pr_err("%s: pi:%d, state:%d\n, rtt:%u, cwnd: %u", -+ __func__, sub_tp->mptcp->path_index, -+ sub_sk->sk_state, sub_tp->srtt_us, -+ sub_tp->snd_cwnd); -+ } -+ } -+ -+ alpha = div64_u64(mptcp_ccc_scale(best_cwnd, alpha_scale_num), sum_denominator); -+ -+ if (unlikely(!alpha)) -+ alpha = 1; -+ -+exit: -+ mptcp_set_alpha(mptcp_meta_sk(sk), alpha); -+} -+ -+static void mptcp_ccc_init(struct sock *sk) -+{ -+ if (mptcp(tcp_sk(sk))) { -+ mptcp_set_forced(mptcp_meta_sk(sk), 0); -+ mptcp_set_alpha(mptcp_meta_sk(sk), 1); -+ } -+ /* If we do not mptcp, behave like reno: return */ -+} -+ -+static void mptcp_ccc_cwnd_event(struct sock *sk, enum tcp_ca_event event) -+{ -+ if (event == CA_EVENT_LOSS) -+ mptcp_ccc_recalc_alpha(sk); -+} -+ -+static void mptcp_ccc_set_state(struct sock *sk, u8 ca_state) -+{ -+ if (!mptcp(tcp_sk(sk))) -+ return; -+ -+ mptcp_set_forced(mptcp_meta_sk(sk), 1); -+} -+ -+static void mptcp_ccc_cong_avoid(struct sock *sk, u32 ack, u32 acked) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ const struct mptcp_cb *mpcb = tp->mpcb; -+ int snd_cwnd; -+ -+ if (!mptcp(tp)) { -+ tcp_reno_cong_avoid(sk, ack, acked); -+ return; -+ } -+ -+ if (!tcp_is_cwnd_limited(sk)) -+ return; -+ -+ if (tcp_in_slow_start(tp)) { -+ /* In "safe" area, increase. */ -+ tcp_slow_start(tp, acked); -+ mptcp_ccc_recalc_alpha(sk); -+ return; -+ } -+ -+ if (mptcp_get_forced(mptcp_meta_sk(sk))) { -+ mptcp_ccc_recalc_alpha(sk); -+ mptcp_set_forced(mptcp_meta_sk(sk), 0); -+ } -+ -+ if (mpcb->cnt_established > 1) { -+ u64 alpha = mptcp_get_alpha(mptcp_meta_sk(sk)); -+ -+ /* This may happen, if at the initialization, the mpcb -+ * was not yet attached to the sock, and thus -+ * initializing alpha failed. -+ */ -+ if (unlikely(!alpha)) -+ alpha = 1; -+ -+ snd_cwnd = (int) div_u64 ((u64) mptcp_ccc_scale(1, alpha_scale), -+ alpha); -+ -+ /* snd_cwnd_cnt >= max (scale * tot_cwnd / alpha, cwnd) -+ * Thus, we select here the max value. -+ */ -+ if (snd_cwnd < tp->snd_cwnd) -+ snd_cwnd = tp->snd_cwnd; -+ } else { -+ snd_cwnd = tp->snd_cwnd; -+ } -+ -+ if (tp->snd_cwnd_cnt >= snd_cwnd) { -+ if (tp->snd_cwnd < tp->snd_cwnd_clamp) { -+ tp->snd_cwnd++; -+ mptcp_ccc_recalc_alpha(sk); -+ } -+ -+ tp->snd_cwnd_cnt = 0; -+ } else { -+ tp->snd_cwnd_cnt++; -+ } -+} -+ -+static struct tcp_congestion_ops mptcp_ccc = { -+ .init = mptcp_ccc_init, -+ .ssthresh = tcp_reno_ssthresh, -+ .cong_avoid = mptcp_ccc_cong_avoid, -+ .cwnd_event = mptcp_ccc_cwnd_event, -+ .set_state = mptcp_ccc_set_state, -+ .owner = THIS_MODULE, -+ .name = "lia", -+}; -+ -+static int __init mptcp_ccc_register(void) -+{ -+ BUILD_BUG_ON(sizeof(struct mptcp_ccc) > ICSK_CA_PRIV_SIZE); -+ return tcp_register_congestion_control(&mptcp_ccc); -+} -+ -+static void __exit mptcp_ccc_unregister(void) -+{ -+ tcp_unregister_congestion_control(&mptcp_ccc); -+} -+ -+module_init(mptcp_ccc_register); -+module_exit(mptcp_ccc_unregister); -+ -+MODULE_AUTHOR("Christoph Paasch, Sébastien Barré"); -+MODULE_LICENSE("GPL"); -+MODULE_DESCRIPTION("MPTCP LINKED INCREASE CONGESTION CONTROL ALGORITHM"); -+MODULE_VERSION("0.1"); -diff -aurN linux-4.9.162/net/mptcp/mptcp_ctrl.c mptcp-mptcp_v0.93/net/mptcp/mptcp_ctrl.c ---- linux-4.9.162/net/mptcp/mptcp_ctrl.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_v0.93/net/mptcp/mptcp_ctrl.c 2019-03-14 14:02:32.000000000 +0100 -@@ -0,0 +1,2971 @@ -+/* -+ * MPTCP implementation - MPTCP-control -+ * -+ * Initial Design & Implementation: -+ * Sébastien Barré -+ * -+ * Current Maintainer & Author: -+ * Christoph Paasch -+ * -+ * Additional authors: -+ * Jaakko Korkeaniemi -+ * Gregory Detal -+ * Fabien Duchêne -+ * Andreas Seelinger -+ * Lavkesh Lahngir -+ * Andreas Ripke -+ * Vlad Dogaru -+ * Octavian Purdila -+ * John Ronan -+ * Catalin Nicutar -+ * Brandon Heller -+ * -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version -+ * 2 of the License, or (at your option) any later version. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#if IS_ENABLED(CONFIG_IPV6) -+#include -+#include -+#endif -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+static struct kmem_cache *mptcp_sock_cache __read_mostly; -+static struct kmem_cache *mptcp_cb_cache __read_mostly; -+static struct kmem_cache *mptcp_tw_cache __read_mostly; -+ -+int sysctl_mptcp_enabled __read_mostly = 1; -+EXPORT_SYMBOL(sysctl_mptcp_enabled); -+int sysctl_mptcp_version __read_mostly = 0; -+static int min_mptcp_version; -+static int max_mptcp_version = 1; -+int sysctl_mptcp_checksum __read_mostly = 1; -+int sysctl_mptcp_debug __read_mostly; -+EXPORT_SYMBOL(sysctl_mptcp_debug); -+int sysctl_mptcp_syn_retries __read_mostly = 3; -+ -+bool mptcp_init_failed __read_mostly; -+ -+struct static_key mptcp_static_key = STATIC_KEY_INIT_FALSE; -+EXPORT_SYMBOL(mptcp_static_key); -+ -+static int proc_mptcp_path_manager(struct ctl_table *ctl, int write, -+ void __user *buffer, size_t *lenp, -+ loff_t *ppos) -+{ -+ char val[MPTCP_PM_NAME_MAX]; -+ struct ctl_table tbl = { -+ .data = val, -+ .maxlen = MPTCP_PM_NAME_MAX, -+ }; -+ int ret; -+ -+ mptcp_get_default_path_manager(val); -+ -+ ret = proc_dostring(&tbl, write, buffer, lenp, ppos); -+ if (write && ret == 0) -+ ret = mptcp_set_default_path_manager(val); -+ return ret; -+} -+ -+static int proc_mptcp_scheduler(struct ctl_table *ctl, int write, -+ void __user *buffer, size_t *lenp, -+ loff_t *ppos) -+{ -+ char val[MPTCP_SCHED_NAME_MAX]; -+ struct ctl_table tbl = { -+ .data = val, -+ .maxlen = MPTCP_SCHED_NAME_MAX, -+ }; -+ int ret; -+ -+ mptcp_get_default_scheduler(val); -+ -+ ret = proc_dostring(&tbl, write, buffer, lenp, ppos); -+ if (write && ret == 0) -+ ret = mptcp_set_default_scheduler(val); -+ return ret; -+} -+ -+static struct ctl_table mptcp_table[] = { -+ { -+ .procname = "mptcp_enabled", -+ .data = &sysctl_mptcp_enabled, -+ .maxlen = sizeof(int), -+ .mode = 0644, -+ .proc_handler = &proc_dointvec -+ }, -+ { -+ .procname = "mptcp_version", -+ .data = &sysctl_mptcp_version, -+ .mode = 0644, -+ .maxlen = sizeof(int), -+ .proc_handler = &proc_dointvec_minmax, -+ .extra1 = &min_mptcp_version, -+ .extra2 = &max_mptcp_version, -+ }, -+ { -+ .procname = "mptcp_checksum", -+ .data = &sysctl_mptcp_checksum, -+ .maxlen = sizeof(int), -+ .mode = 0644, -+ .proc_handler = &proc_dointvec -+ }, -+ { -+ .procname = "mptcp_debug", -+ .data = &sysctl_mptcp_debug, -+ .maxlen = sizeof(int), -+ .mode = 0644, -+ .proc_handler = &proc_dointvec -+ }, -+ { -+ .procname = "mptcp_syn_retries", -+ .data = &sysctl_mptcp_syn_retries, -+ .maxlen = sizeof(int), -+ .mode = 0644, -+ .proc_handler = &proc_dointvec -+ }, -+ { -+ .procname = "mptcp_path_manager", -+ .mode = 0644, -+ .maxlen = MPTCP_PM_NAME_MAX, -+ .proc_handler = proc_mptcp_path_manager, -+ }, -+ { -+ .procname = "mptcp_scheduler", -+ .mode = 0644, -+ .maxlen = MPTCP_SCHED_NAME_MAX, -+ .proc_handler = proc_mptcp_scheduler, -+ }, -+ { } -+}; -+ -+static inline u32 mptcp_hash_tk(u32 token) -+{ -+ return token % MPTCP_HASH_SIZE; -+} -+ -+struct hlist_nulls_head tk_hashtable[MPTCP_HASH_SIZE]; -+EXPORT_SYMBOL(tk_hashtable); -+ -+/* The following hash table is used to avoid collision of token */ -+static struct hlist_nulls_head mptcp_reqsk_tk_htb[MPTCP_HASH_SIZE]; -+ -+/* Lock, protecting the two hash-tables that hold the token. Namely, -+ * mptcp_reqsk_tk_htb and tk_hashtable -+ */ -+static spinlock_t mptcp_tk_hashlock; -+ -+static bool mptcp_reqsk_find_tk(const u32 token) -+{ -+ const u32 hash = mptcp_hash_tk(token); -+ const struct mptcp_request_sock *mtreqsk; -+ const struct hlist_nulls_node *node; -+ -+begin: -+ hlist_nulls_for_each_entry_rcu(mtreqsk, node, -+ &mptcp_reqsk_tk_htb[hash], hash_entry) { -+ if (token == mtreqsk->mptcp_loc_token) -+ return true; -+ } -+ /* A request-socket is destroyed by RCU. So, it might have been recycled -+ * and put into another hash-table list. So, after the lookup we may -+ * end up in a different list. So, we may need to restart. -+ * -+ * See also the comment in __inet_lookup_established. -+ */ -+ if (get_nulls_value(node) != hash) -+ goto begin; -+ return false; -+} -+ -+static void mptcp_reqsk_insert_tk(struct request_sock *reqsk, const u32 token) -+{ -+ u32 hash = mptcp_hash_tk(token); -+ -+ hlist_nulls_add_head_rcu(&mptcp_rsk(reqsk)->hash_entry, -+ &mptcp_reqsk_tk_htb[hash]); -+} -+ -+static void mptcp_reqsk_remove_tk(const struct request_sock *reqsk) -+{ -+ rcu_read_lock(); -+ local_bh_disable(); -+ spin_lock(&mptcp_tk_hashlock); -+ hlist_nulls_del_init_rcu(&mptcp_rsk(reqsk)->hash_entry); -+ spin_unlock(&mptcp_tk_hashlock); -+ local_bh_enable(); -+ rcu_read_unlock(); -+} -+ -+void mptcp_reqsk_destructor(struct request_sock *req) -+{ -+ if (!mptcp_rsk(req)->is_sub) -+ mptcp_reqsk_remove_tk(req); -+} -+ -+static void __mptcp_hash_insert(struct tcp_sock *meta_tp, const u32 token) -+{ -+ u32 hash = mptcp_hash_tk(token); -+ hlist_nulls_add_head_rcu(&meta_tp->tk_table, &tk_hashtable[hash]); -+ meta_tp->inside_tk_table = 1; -+} -+ -+static bool mptcp_find_token(u32 token) -+{ -+ const u32 hash = mptcp_hash_tk(token); -+ const struct tcp_sock *meta_tp; -+ const struct hlist_nulls_node *node; -+ -+begin: -+ hlist_nulls_for_each_entry_rcu(meta_tp, node, &tk_hashtable[hash], tk_table) { -+ if (token == meta_tp->mptcp_loc_token) -+ return true; -+ } -+ /* A TCP-socket is destroyed by RCU. So, it might have been recycled -+ * and put into another hash-table list. So, after the lookup we may -+ * end up in a different list. So, we may need to restart. -+ * -+ * See also the comment in __inet_lookup_established. -+ */ -+ if (get_nulls_value(node) != hash) -+ goto begin; -+ return false; -+} -+ -+static void mptcp_set_key_reqsk(struct request_sock *req, -+ const struct sk_buff *skb, -+ u32 seed) -+{ -+ const struct inet_request_sock *ireq = inet_rsk(req); -+ struct mptcp_request_sock *mtreq = mptcp_rsk(req); -+ -+ if (skb->protocol == htons(ETH_P_IP)) { -+ mtreq->mptcp_loc_key = mptcp_v4_get_key(ip_hdr(skb)->saddr, -+ ip_hdr(skb)->daddr, -+ htons(ireq->ir_num), -+ ireq->ir_rmt_port, -+ seed); -+#if IS_ENABLED(CONFIG_IPV6) -+ } else { -+ mtreq->mptcp_loc_key = mptcp_v6_get_key(ipv6_hdr(skb)->saddr.s6_addr32, -+ ipv6_hdr(skb)->daddr.s6_addr32, -+ htons(ireq->ir_num), -+ ireq->ir_rmt_port, -+ seed); -+#endif -+ } -+ -+ mptcp_key_sha1(mtreq->mptcp_loc_key, &mtreq->mptcp_loc_token, NULL); -+} -+ -+/* New MPTCP-connection request, prepare a new token for the meta-socket that -+ * will be created in mptcp_check_req_master(), and store the received token. -+ */ -+static void mptcp_reqsk_new_mptcp(struct request_sock *req, -+ const struct sock *sk, -+ const struct mptcp_options_received *mopt, -+ const struct sk_buff *skb) -+{ -+ struct mptcp_request_sock *mtreq = mptcp_rsk(req); -+ const struct tcp_sock *tp = tcp_sk(sk); -+ -+ inet_rsk(req)->saw_mpc = 1; -+ -+ /* MPTCP version agreement */ -+ if (mopt->mptcp_ver >= tp->mptcp_ver) -+ mtreq->mptcp_ver = tp->mptcp_ver; -+ else -+ mtreq->mptcp_ver = mopt->mptcp_ver; -+ -+ rcu_read_lock(); -+ local_bh_disable(); -+ spin_lock(&mptcp_tk_hashlock); -+ do { -+ mptcp_set_key_reqsk(req, skb, mptcp_seed++); -+ } while (mptcp_reqsk_find_tk(mtreq->mptcp_loc_token) || -+ mptcp_find_token(mtreq->mptcp_loc_token)); -+ mptcp_reqsk_insert_tk(req, mtreq->mptcp_loc_token); -+ spin_unlock(&mptcp_tk_hashlock); -+ local_bh_enable(); -+ rcu_read_unlock(); -+ mtreq->mptcp_rem_key = mopt->mptcp_sender_key; -+} -+ -+static int mptcp_reqsk_new_cookie(struct request_sock *req, -+ const struct sock *sk, -+ const struct mptcp_options_received *mopt, -+ const struct sk_buff *skb) -+{ -+ struct mptcp_request_sock *mtreq = mptcp_rsk(req); -+ -+ /* MPTCP version agreement */ -+ if (mopt->mptcp_ver >= tcp_sk(sk)->mptcp_ver) -+ mtreq->mptcp_ver = tcp_sk(sk)->mptcp_ver; -+ else -+ mtreq->mptcp_ver = mopt->mptcp_ver; -+ -+ rcu_read_lock(); -+ local_bh_disable(); -+ spin_lock(&mptcp_tk_hashlock); -+ -+ mptcp_set_key_reqsk(req, skb, tcp_rsk(req)->snt_isn); -+ -+ if (mptcp_reqsk_find_tk(mtreq->mptcp_loc_token) || -+ mptcp_find_token(mtreq->mptcp_loc_token)) { -+ spin_unlock(&mptcp_tk_hashlock); -+ local_bh_enable(); -+ rcu_read_unlock(); -+ return false; -+ } -+ -+ inet_rsk(req)->saw_mpc = 1; -+ -+ spin_unlock(&mptcp_tk_hashlock); -+ local_bh_enable(); -+ rcu_read_unlock(); -+ -+ mtreq->mptcp_rem_key = mopt->mptcp_sender_key; -+ -+ return true; -+} -+ -+static void mptcp_set_key_sk(const struct sock *sk) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ const struct inet_sock *isk = inet_sk(sk); -+ -+ if (sk->sk_family == AF_INET) -+ tp->mptcp_loc_key = mptcp_v4_get_key(isk->inet_saddr, -+ isk->inet_daddr, -+ isk->inet_sport, -+ isk->inet_dport, -+ mptcp_seed++); -+#if IS_ENABLED(CONFIG_IPV6) -+ else -+ tp->mptcp_loc_key = mptcp_v6_get_key(inet6_sk(sk)->saddr.s6_addr32, -+ sk->sk_v6_daddr.s6_addr32, -+ isk->inet_sport, -+ isk->inet_dport, -+ mptcp_seed++); -+#endif -+ -+ mptcp_key_sha1(tp->mptcp_loc_key, -+ &tp->mptcp_loc_token, NULL); -+} -+ -+#ifdef HAVE_JUMP_LABEL -+static atomic_t mptcp_needed_deferred; -+static atomic_t mptcp_wanted; -+ -+static void mptcp_clear(struct work_struct *work) -+{ -+ int deferred = atomic_xchg(&mptcp_needed_deferred, 0); -+ int wanted; -+ -+ wanted = atomic_add_return(deferred, &mptcp_wanted); -+ if (wanted > 0) -+ static_key_enable(&mptcp_static_key); -+ else -+ static_key_disable(&mptcp_static_key); -+} -+ -+static DECLARE_WORK(mptcp_work, mptcp_clear); -+#endif -+ -+static void mptcp_enable_static_key_bh(void) -+{ -+#ifdef HAVE_JUMP_LABEL -+ int wanted; -+ -+ while (1) { -+ wanted = atomic_read(&mptcp_wanted); -+ if (wanted <= 0) -+ break; -+ if (atomic_cmpxchg(&mptcp_wanted, wanted, wanted + 1) == wanted) -+ return; -+ } -+ atomic_inc(&mptcp_needed_deferred); -+ schedule_work(&mptcp_work); -+#else -+ static_key_slow_inc(&mptcp_static_key); -+#endif -+} -+ -+static void mptcp_enable_static_key(void) -+{ -+#ifdef HAVE_JUMP_LABEL -+ atomic_inc(&mptcp_wanted); -+ static_key_enable(&mptcp_static_key); -+#else -+ static_key_slow_inc(&mptcp_static_key); -+#endif -+} -+ -+void mptcp_disable_static_key(void) -+{ -+#ifdef HAVE_JUMP_LABEL -+ int wanted; -+ -+ while (1) { -+ wanted = atomic_read(&mptcp_wanted); -+ if (wanted <= 1) -+ break; -+ if (atomic_cmpxchg(&mptcp_wanted, wanted, wanted - 1) == wanted) -+ return; -+ } -+ atomic_dec(&mptcp_needed_deferred); -+ schedule_work(&mptcp_work); -+#else -+ static_key_slow_dec(&mptcp_static_key); -+#endif -+} -+ -+void mptcp_enable_sock(struct sock *sk) -+{ -+ if (!sock_flag(sk, SOCK_MPTCP)) { -+ sock_set_flag(sk, SOCK_MPTCP); -+ tcp_sk(sk)->mptcp_ver = sysctl_mptcp_version; -+ -+ /* Necessary here, because MPTCP can be enabled/disabled through -+ * a setsockopt. -+ */ -+ if (sk->sk_family == AF_INET) -+ inet_csk(sk)->icsk_af_ops = &mptcp_v4_specific; -+#if IS_ENABLED(CONFIG_IPV6) -+ else if (mptcp_v6_is_v4_mapped(sk)) -+ inet_csk(sk)->icsk_af_ops = &mptcp_v6_mapped; -+ else -+ inet_csk(sk)->icsk_af_ops = &mptcp_v6_specific; -+#endif -+ -+ mptcp_enable_static_key(); -+ } -+} -+ -+void mptcp_disable_sock(struct sock *sk) -+{ -+ if (sock_flag(sk, SOCK_MPTCP)) { -+ sock_reset_flag(sk, SOCK_MPTCP); -+ -+ /* Necessary here, because MPTCP can be enabled/disabled through -+ * a setsockopt. -+ */ -+ if (sk->sk_family == AF_INET) -+ inet_csk(sk)->icsk_af_ops = &ipv4_specific; -+#if IS_ENABLED(CONFIG_IPV6) -+ else if (mptcp_v6_is_v4_mapped(sk)) -+ inet_csk(sk)->icsk_af_ops = &ipv6_mapped; -+ else -+ inet_csk(sk)->icsk_af_ops = &ipv6_specific; -+#endif -+ -+ mptcp_disable_static_key(); -+ } -+} -+ -+void mptcp_connect_init(struct sock *sk) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ -+ rcu_read_lock(); -+ local_bh_disable(); -+ spin_lock(&mptcp_tk_hashlock); -+ do { -+ mptcp_set_key_sk(sk); -+ } while (mptcp_reqsk_find_tk(tp->mptcp_loc_token) || -+ mptcp_find_token(tp->mptcp_loc_token)); -+ -+ __mptcp_hash_insert(tp, tp->mptcp_loc_token); -+ spin_unlock(&mptcp_tk_hashlock); -+ local_bh_enable(); -+ rcu_read_unlock(); -+ -+ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_MPCAPABLEACTIVE); -+} -+ -+/** -+ * This function increments the refcount of the mpcb struct. -+ * It is the responsibility of the caller to decrement when releasing -+ * the structure. -+ */ -+struct sock *mptcp_hash_find(const struct net *net, const u32 token) -+{ -+ const u32 hash = mptcp_hash_tk(token); -+ const struct tcp_sock *meta_tp; -+ struct sock *meta_sk = NULL; -+ const struct hlist_nulls_node *node; -+ -+ rcu_read_lock(); -+ local_bh_disable(); -+begin: -+ hlist_nulls_for_each_entry_rcu(meta_tp, node, &tk_hashtable[hash], -+ tk_table) { -+ meta_sk = (struct sock *)meta_tp; -+ if (token == meta_tp->mptcp_loc_token && -+ net_eq(net, sock_net(meta_sk))) { -+ if (unlikely(!atomic_inc_not_zero(&meta_sk->sk_refcnt))) -+ goto out; -+ if (unlikely(token != meta_tp->mptcp_loc_token || -+ !net_eq(net, sock_net(meta_sk)))) { -+ sock_gen_put(meta_sk); -+ goto begin; -+ } -+ goto found; -+ } -+ } -+ /* A TCP-socket is destroyed by RCU. So, it might have been recycled -+ * and put into another hash-table list. So, after the lookup we may -+ * end up in a different list. So, we may need to restart. -+ * -+ * See also the comment in __inet_lookup_established. -+ */ -+ if (get_nulls_value(node) != hash) -+ goto begin; -+out: -+ meta_sk = NULL; -+found: -+ local_bh_enable(); -+ rcu_read_unlock(); -+ return meta_sk; -+} -+ -+void mptcp_hash_remove_bh(struct tcp_sock *meta_tp) -+{ -+ /* remove from the token hashtable */ -+ rcu_read_lock(); -+ local_bh_disable(); -+ spin_lock(&mptcp_tk_hashlock); -+ hlist_nulls_del_init_rcu(&meta_tp->tk_table); -+ meta_tp->inside_tk_table = 0; -+ spin_unlock(&mptcp_tk_hashlock); -+ local_bh_enable(); -+ rcu_read_unlock(); -+} -+ -+struct sock *mptcp_select_ack_sock(const struct sock *meta_sk) -+{ -+ const struct tcp_sock *meta_tp = tcp_sk(meta_sk); -+ struct sock *sk, *rttsk = NULL, *lastsk = NULL; -+ u32 min_time = 0, last_active = 0; -+ -+ mptcp_for_each_sk(meta_tp->mpcb, sk) { -+ struct tcp_sock *tp = tcp_sk(sk); -+ u32 elapsed; -+ -+ if (!mptcp_sk_can_send_ack(sk) || tp->pf) -+ continue; -+ -+ elapsed = keepalive_time_elapsed(tp); -+ -+ /* We take the one with the lowest RTT within a reasonable -+ * (meta-RTO)-timeframe -+ */ -+ if (elapsed < inet_csk(meta_sk)->icsk_rto) { -+ if (!min_time || tp->srtt_us < min_time) { -+ min_time = tp->srtt_us; -+ rttsk = sk; -+ } -+ continue; -+ } -+ -+ /* Otherwise, we just take the most recent active */ -+ if (!rttsk && (!last_active || elapsed < last_active)) { -+ last_active = elapsed; -+ lastsk = sk; -+ } -+ } -+ -+ if (rttsk) -+ return rttsk; -+ -+ return lastsk; -+} -+EXPORT_SYMBOL(mptcp_select_ack_sock); -+ -+static void mptcp_sock_def_error_report(struct sock *sk) -+{ -+ const struct mptcp_cb *mpcb = tcp_sk(sk)->mpcb; -+ struct sock *meta_sk = mptcp_meta_sk(sk); -+ struct tcp_sock *tp = tcp_sk(sk); -+ -+ if (!sock_flag(sk, SOCK_DEAD)) { -+ if (tp->send_mp_fclose && sk->sk_err == ETIMEDOUT) { -+ /* Called by the keep alive timer (tcp_write_timeout), -+ * when the limit of fastclose retransmissions has been -+ * reached. Send a TCP RST to clear the status of any -+ * stateful firewall (typically conntrack) which are -+ * not aware of mptcp and cannot understand the -+ * fastclose option. -+ */ -+ tp->ops->send_active_reset(sk, GFP_ATOMIC); -+ } -+ } -+ -+ if (mpcb->infinite_mapping_rcv || mpcb->infinite_mapping_snd || -+ mpcb->send_infinite_mapping) { -+ -+ meta_sk->sk_err = sk->sk_err; -+ meta_sk->sk_err_soft = sk->sk_err_soft; -+ -+ if (!sock_flag(meta_sk, SOCK_DEAD)) -+ meta_sk->sk_error_report(meta_sk); -+ -+ WARN(meta_sk->sk_state == TCP_CLOSE, -+ "Meta already closed i_rcv %u i_snd %u send_i %u flags %#lx\n", -+ mpcb->infinite_mapping_rcv, mpcb->infinite_mapping_snd, -+ mpcb->send_infinite_mapping, meta_sk->sk_flags); -+ -+ if (meta_sk->sk_state != TCP_CLOSE) -+ tcp_done(meta_sk); -+ } -+ -+ if (mpcb->pm_ops->subflow_error) -+ mpcb->pm_ops->subflow_error(meta_sk, sk); -+ -+ sk->sk_err = 0; -+ return; -+} -+ -+static void mptcp_mpcb_put(struct mptcp_cb *mpcb) -+{ -+ if (atomic_dec_and_test(&mpcb->mpcb_refcnt)) { -+ mptcp_cleanup_path_manager(mpcb); -+ mptcp_cleanup_scheduler(mpcb); -+ kfree(mpcb->master_info); -+ kmem_cache_free(mptcp_cb_cache, mpcb); -+ } -+} -+ -+void mptcp_sock_destruct(struct sock *sk) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ -+ if (!is_meta_sk(sk) && !tp->was_meta_sk) { -+ BUG_ON(!hlist_unhashed(&tp->mptcp->cb_list)); -+ -+ kmem_cache_free(mptcp_sock_cache, tp->mptcp); -+ tp->mptcp = NULL; -+ -+ /* Taken when mpcb pointer was set */ -+ sock_put(mptcp_meta_sk(sk)); -+ mptcp_mpcb_put(tp->mpcb); -+ } else { -+ struct mptcp_cb *mpcb = tp->mpcb; -+ struct mptcp_tw *mptw; -+ -+ /* The mpcb is disappearing - we can make the final -+ * update to the rcv_nxt of the time-wait-sock and remove -+ * its reference to the mpcb. -+ */ -+ spin_lock_bh(&mpcb->tw_lock); -+ list_for_each_entry_rcu(mptw, &mpcb->tw_list, list) { -+ list_del_rcu(&mptw->list); -+ mptw->in_list = 0; -+ mptcp_mpcb_put(mpcb); -+ rcu_assign_pointer(mptw->mpcb, NULL); -+ } -+ spin_unlock_bh(&mpcb->tw_lock); -+ -+ mptcp_mpcb_put(mpcb); -+ -+ mptcp_debug("%s destroying meta-sk\n", __func__); -+ } -+ -+ WARN_ON(!static_key_false(&mptcp_static_key)); -+ -+ /* Must be called here, because this will decrement the jump-label. */ -+ inet_sock_destruct(sk); -+} -+ -+void mptcp_destroy_sock(struct sock *sk) -+{ -+ if (is_meta_sk(sk)) { -+ struct sock *sk_it, *tmpsk; -+ -+ __skb_queue_purge(&tcp_sk(sk)->mpcb->reinject_queue); -+ -+ /* We have to close all remaining subflows. Normally, they -+ * should all be about to get closed. But, if the kernel is -+ * forcing a closure (e.g., tcp_write_err), the subflows might -+ * not have been closed properly (as we are waiting for the -+ * DATA_ACK of the DATA_FIN). -+ */ -+ mptcp_for_each_sk_safe(tcp_sk(sk)->mpcb, sk_it, tmpsk) { -+ /* Already did call tcp_close - waiting for graceful -+ * closure, or if we are retransmitting fast-close on -+ * the subflow. The reset (or timeout) will kill the -+ * subflow.. -+ */ -+ if (tcp_sk(sk_it)->closing || -+ tcp_sk(sk_it)->send_mp_fclose) -+ continue; -+ -+ /* Allow the delayed work first to prevent time-wait state */ -+ if (delayed_work_pending(&tcp_sk(sk_it)->mptcp->work)) -+ continue; -+ -+ mptcp_sub_close(sk_it, 0); -+ } -+ } else { -+ mptcp_del_sock(sk); -+ } -+} -+ -+static void mptcp_set_state(struct sock *sk) -+{ -+ struct sock *meta_sk = mptcp_meta_sk(sk); -+ -+ /* Meta is not yet established - wake up the application */ -+ if ((1 << meta_sk->sk_state) & (TCPF_SYN_SENT | TCPF_SYN_RECV) && -+ sk->sk_state == TCP_ESTABLISHED) { -+ tcp_set_state(meta_sk, TCP_ESTABLISHED); -+ -+ if (!sock_flag(meta_sk, SOCK_DEAD)) { -+ meta_sk->sk_state_change(meta_sk); -+ sk_wake_async(meta_sk, SOCK_WAKE_IO, POLL_OUT); -+ } -+ -+ tcp_sk(meta_sk)->lsndtime = tcp_time_stamp; -+ } -+ -+ if (sk->sk_state == TCP_ESTABLISHED) { -+ tcp_sk(sk)->mptcp->establish_increased = 1; -+ tcp_sk(sk)->mpcb->cnt_established++; -+ } -+ -+ if (sk->sk_state == TCP_CLOSE) { -+ if (!sock_flag(sk, SOCK_DEAD)) -+ mptcp_sub_close(sk, 0); -+ } -+} -+ -+static void mptcp_assign_congestion_control(struct sock *sk) -+{ -+ struct inet_connection_sock *icsk = inet_csk(sk); -+ struct inet_connection_sock *meta_icsk = inet_csk(mptcp_meta_sk(sk)); -+ const struct tcp_congestion_ops *ca = meta_icsk->icsk_ca_ops; -+ -+ /* Congestion control is the same as meta. Thus, it has been -+ * try_module_get'd by tcp_assign_congestion_control. -+ */ -+ if (icsk->icsk_ca_ops == ca) -+ return; -+ -+ /* Use the same congestion control as set on the meta-sk */ -+ if (!try_module_get(ca->owner)) { -+ /* This should never happen. The congestion control is linked -+ * to the meta-socket (through tcp_assign_congestion_control) -+ * who "holds" the refcnt on the module. -+ */ -+ WARN(1, "Could not get the congestion control!"); -+ return; -+ } -+ icsk->icsk_ca_ops = ca; -+ -+ /* Clear out private data before diag gets it and -+ * the ca has not been initialized. -+ */ -+ if (ca->get_info) -+ memset(icsk->icsk_ca_priv, 0, sizeof(icsk->icsk_ca_priv)); -+ -+ return; -+} -+ -+u32 mptcp_secret[MD5_MESSAGE_BYTES / 4] ____cacheline_aligned; -+u32 mptcp_seed = 0; -+ -+void mptcp_key_sha1(u64 key, u32 *token, u64 *idsn) -+{ -+ u32 workspace[SHA_WORKSPACE_WORDS]; -+ u32 mptcp_hashed_key[SHA_DIGEST_WORDS]; -+ u8 input[64]; -+ int i; -+ -+ memset(workspace, 0, sizeof(workspace)); -+ -+ /* Initialize input with appropriate padding */ -+ memset(&input[9], 0, sizeof(input) - 10); /* -10, because the last byte -+ * is explicitly set too -+ */ -+ memcpy(input, &key, sizeof(key)); /* Copy key to the msg beginning */ -+ input[8] = 0x80; /* Padding: First bit after message = 1 */ -+ input[63] = 0x40; /* Padding: Length of the message = 64 bits */ -+ -+ sha_init(mptcp_hashed_key); -+ sha_transform(mptcp_hashed_key, input, workspace); -+ -+ for (i = 0; i < 5; i++) -+ mptcp_hashed_key[i] = cpu_to_be32(mptcp_hashed_key[i]); -+ -+ if (token) -+ *token = mptcp_hashed_key[0]; -+ if (idsn) -+ *idsn = *((u64 *)&mptcp_hashed_key[3]); -+} -+ -+void mptcp_hmac_sha1(const u8 *key_1, const u8 *key_2, u32 *hash_out, -+ int arg_num, ...) -+{ -+ u32 workspace[SHA_WORKSPACE_WORDS]; -+ u8 input[128]; /* 2 512-bit blocks */ -+ int i; -+ int index; -+ int length; -+ u8 *msg; -+ va_list list; -+ -+ memset(workspace, 0, sizeof(workspace)); -+ -+ /* Generate key xored with ipad */ -+ memset(input, 0x36, 64); -+ for (i = 0; i < 8; i++) -+ input[i] ^= key_1[i]; -+ for (i = 0; i < 8; i++) -+ input[i + 8] ^= key_2[i]; -+ -+ va_start(list, arg_num); -+ index = 64; -+ for (i = 0; i < arg_num; i++) { -+ length = va_arg(list, int); -+ msg = va_arg(list, u8 *); -+ BUG_ON(index + length > 125); /* Message is too long */ -+ memcpy(&input[index], msg, length); -+ index += length; -+ } -+ va_end(list); -+ -+ input[index] = 0x80; /* Padding: First bit after message = 1 */ -+ memset(&input[index + 1], 0, (126 - index)); -+ -+ /* Padding: Length of the message = 512 + message length (bits) */ -+ input[126] = 0x02; -+ input[127] = ((index - 64) * 8); /* Message length (bits) */ -+ -+ sha_init(hash_out); -+ sha_transform(hash_out, input, workspace); -+ memset(workspace, 0, sizeof(workspace)); -+ -+ sha_transform(hash_out, &input[64], workspace); -+ memset(workspace, 0, sizeof(workspace)); -+ -+ for (i = 0; i < 5; i++) -+ hash_out[i] = cpu_to_be32(hash_out[i]); -+ -+ /* Prepare second part of hmac */ -+ memset(input, 0x5C, 64); -+ for (i = 0; i < 8; i++) -+ input[i] ^= key_1[i]; -+ for (i = 0; i < 8; i++) -+ input[i + 8] ^= key_2[i]; -+ -+ memcpy(&input[64], hash_out, 20); -+ input[84] = 0x80; -+ memset(&input[85], 0, 41); -+ -+ /* Padding: Length of the message = 512 + 160 bits */ -+ input[126] = 0x02; -+ input[127] = 0xA0; -+ -+ sha_init(hash_out); -+ sha_transform(hash_out, input, workspace); -+ memset(workspace, 0, sizeof(workspace)); -+ -+ sha_transform(hash_out, &input[64], workspace); -+ -+ for (i = 0; i < 5; i++) -+ hash_out[i] = cpu_to_be32(hash_out[i]); -+} -+EXPORT_SYMBOL(mptcp_hmac_sha1); -+ -+static void mptcp_mpcb_inherit_sockopts(struct sock *meta_sk, struct sock *master_sk) -+{ -+ /* Socket-options handled by sk_clone_lock while creating the meta-sk. -+ * ====== -+ * SO_SNDBUF, SO_SNDBUFFORCE, SO_RCVBUF, SO_RCVBUFFORCE, SO_RCVLOWAT, -+ * SO_RCVTIMEO, SO_SNDTIMEO, SO_ATTACH_FILTER, SO_DETACH_FILTER, -+ * TCP_NODELAY, TCP_CORK -+ * -+ * Socket-options handled in this function here -+ * ====== -+ * TCP_DEFER_ACCEPT -+ * SO_KEEPALIVE -+ * -+ * Socket-options on the todo-list -+ * ====== -+ * SO_BINDTODEVICE - should probably prevent creation of new subsocks -+ * across other devices. - what about the api-draft? -+ * SO_DEBUG -+ * SO_REUSEADDR - probably we don't care about this -+ * SO_DONTROUTE, SO_BROADCAST -+ * SO_OOBINLINE -+ * SO_LINGER -+ * SO_TIMESTAMP* - I don't think this is of concern for a SOCK_STREAM -+ * SO_PASSSEC - I don't think this is of concern for a SOCK_STREAM -+ * SO_RXQ_OVFL -+ * TCP_COOKIE_TRANSACTIONS -+ * TCP_MAXSEG -+ * TCP_THIN_* - Handled by sk_clone_lock, but we need to support this -+ * in mptcp_meta_retransmit_timer. AND we need to check -+ * what is about the subsockets. -+ * TCP_LINGER2 -+ * TCP_WINDOW_CLAMP -+ * TCP_USER_TIMEOUT -+ * TCP_MD5SIG -+ * -+ * Socket-options of no concern for the meta-socket (but for the subsocket) -+ * ====== -+ * SO_PRIORITY -+ * SO_MARK -+ * TCP_CONGESTION -+ * TCP_SYNCNT -+ * TCP_QUICKACK -+ */ -+ -+ /* DEFER_ACCEPT should not be set on the meta, as we want to accept new subflows directly */ -+ inet_csk(meta_sk)->icsk_accept_queue.rskq_defer_accept = 0; -+ -+ /* Keepalives are handled entirely at the MPTCP-layer */ -+ if (sock_flag(meta_sk, SOCK_KEEPOPEN)) { -+ inet_csk_reset_keepalive_timer(meta_sk, -+ keepalive_time_when(tcp_sk(meta_sk))); -+ sock_reset_flag(master_sk, SOCK_KEEPOPEN); -+ inet_csk_delete_keepalive_timer(master_sk); -+ } -+ -+ /* Do not propagate subflow-errors up to the MPTCP-layer */ -+ inet_sk(master_sk)->recverr = 0; -+} -+ -+static void mptcp_sub_inherit_sockopts(const struct sock *meta_sk, struct sock *sub_sk) -+{ -+ /* IP_TOS also goes to the subflow. */ -+ if (inet_sk(sub_sk)->tos != inet_sk(meta_sk)->tos) { -+ inet_sk(sub_sk)->tos = inet_sk(meta_sk)->tos; -+ sub_sk->sk_priority = meta_sk->sk_priority; -+ sk_dst_reset(sub_sk); -+ } -+ -+ /* Inherit SO_REUSEADDR */ -+ sub_sk->sk_reuse = meta_sk->sk_reuse; -+ -+ /* Inherit SO_MARK: can be used for routing or filtering */ -+ sub_sk->sk_mark = meta_sk->sk_mark; -+ -+ /* Inherit snd/rcv-buffer locks */ -+ sub_sk->sk_userlocks = meta_sk->sk_userlocks & ~SOCK_BINDPORT_LOCK; -+ -+ /* Nagle/Cork is forced off on the subflows. It is handled at the meta-layer */ -+ tcp_sk(sub_sk)->nonagle = TCP_NAGLE_OFF|TCP_NAGLE_PUSH; -+ -+ /* Keepalives are handled entirely at the MPTCP-layer */ -+ if (sock_flag(sub_sk, SOCK_KEEPOPEN)) { -+ sock_reset_flag(sub_sk, SOCK_KEEPOPEN); -+ inet_csk_delete_keepalive_timer(sub_sk); -+ } -+ -+ /* Do not propagate subflow-errors up to the MPTCP-layer */ -+ inet_sk(sub_sk)->recverr = 0; -+} -+ -+void mptcp_prepare_for_backlog(struct sock *sk, struct sk_buff *skb) -+{ -+ /* In case of success (in mptcp_backlog_rcv) and error (in kfree_skb) of -+ * sk_add_backlog, we will decrement the sk refcount. -+ */ -+ sock_hold(sk); -+ skb->sk = sk; -+ skb->destructor = sock_efree; -+} -+ -+int mptcp_backlog_rcv(struct sock *meta_sk, struct sk_buff *skb) -+{ -+ /* skb-sk may be NULL if we receive a packet immediatly after the -+ * SYN/ACK + MP_CAPABLE. -+ */ -+ struct sock *sk = skb->sk ? skb->sk : meta_sk; -+ int ret = 0; -+ -+ if (unlikely(!atomic_inc_not_zero(&sk->sk_refcnt))) { -+ kfree_skb(skb); -+ return 0; -+ } -+ -+ /* Decrement sk refcnt when calling the skb destructor. -+ * Refcnt is incremented and skb destructor is set in tcp_v{4,6}_rcv via -+ * mptcp_prepare_for_backlog() here above. -+ */ -+ skb_orphan(skb); -+ -+ if (sk->sk_family == AF_INET) -+ ret = tcp_v4_do_rcv(sk, skb); -+#if IS_ENABLED(CONFIG_IPV6) -+ else -+ ret = tcp_v6_do_rcv(sk, skb); -+#endif -+ -+ sock_put(sk); -+ return ret; -+} -+ -+struct lock_class_key meta_key; -+char *meta_key_name = "sk_lock-AF_INET-MPTCP"; -+struct lock_class_key meta_slock_key; -+char *meta_slock_key_name = "slock-AF_INET-MPTCP"; -+ -+static const struct tcp_sock_ops mptcp_meta_specific = { -+ .__select_window = __mptcp_select_window, -+ .select_window = mptcp_select_window, -+ .select_initial_window = mptcp_select_initial_window, -+ .select_size = mptcp_select_size, -+ .init_buffer_space = mptcp_init_buffer_space, -+ .set_rto = mptcp_tcp_set_rto, -+ .should_expand_sndbuf = mptcp_should_expand_sndbuf, -+ .send_fin = mptcp_send_fin, -+ .write_xmit = mptcp_write_xmit, -+ .send_active_reset = mptcp_send_active_reset, -+ .write_wakeup = mptcp_write_wakeup, -+ .retransmit_timer = mptcp_meta_retransmit_timer, -+ .time_wait = mptcp_time_wait, -+ .cleanup_rbuf = mptcp_cleanup_rbuf, -+}; -+ -+static const struct tcp_sock_ops mptcp_sub_specific = { -+ .__select_window = __mptcp_select_window, -+ .select_window = mptcp_select_window, -+ .select_initial_window = mptcp_select_initial_window, -+ .select_size = mptcp_select_size, -+ .init_buffer_space = mptcp_init_buffer_space, -+ .set_rto = mptcp_tcp_set_rto, -+ .should_expand_sndbuf = mptcp_should_expand_sndbuf, -+ .send_fin = tcp_send_fin, -+ .write_xmit = tcp_write_xmit, -+ .send_active_reset = tcp_send_active_reset, -+ .write_wakeup = tcp_write_wakeup, -+ .retransmit_timer = mptcp_sub_retransmit_timer, -+ .time_wait = tcp_time_wait, -+ .cleanup_rbuf = tcp_cleanup_rbuf, -+}; -+ -+static int mptcp_alloc_mpcb(struct sock *meta_sk, __u64 remote_key, -+ __u8 mptcp_ver, u32 window) -+{ -+ struct mptcp_cb *mpcb; -+ struct sock *master_sk; -+ struct inet_connection_sock *meta_icsk = inet_csk(meta_sk); -+ struct tcp_sock *master_tp, *meta_tp = tcp_sk(meta_sk); -+ u64 snd_idsn, rcv_idsn; -+ -+ dst_release(meta_sk->sk_rx_dst); -+ meta_sk->sk_rx_dst = NULL; -+ /* This flag is set to announce sock_lock_init to -+ * reclassify the lock-class of the master socket. -+ */ -+ meta_tp->is_master_sk = 1; -+ master_sk = sk_clone_lock(meta_sk, GFP_ATOMIC | __GFP_ZERO); -+ meta_tp->is_master_sk = 0; -+ if (!master_sk) -+ goto err_alloc_master; -+ -+ master_tp = tcp_sk(master_sk); -+ -+ mpcb = kmem_cache_zalloc(mptcp_cb_cache, GFP_ATOMIC); -+ if (!mpcb) -+ goto err_alloc_mpcb; -+ -+ /* Store the mptcp version agreed on initial handshake */ -+ mpcb->mptcp_ver = mptcp_ver; -+ -+ /* Store the keys and generate the peer's token */ -+ mpcb->mptcp_loc_key = meta_tp->mptcp_loc_key; -+ mpcb->mptcp_loc_token = meta_tp->mptcp_loc_token; -+ -+ /* Generate Initial data-sequence-numbers */ -+ mptcp_key_sha1(mpcb->mptcp_loc_key, NULL, &snd_idsn); -+ snd_idsn = ntohll(snd_idsn) + 1; -+ mpcb->snd_high_order[0] = snd_idsn >> 32; -+ mpcb->snd_high_order[1] = mpcb->snd_high_order[0] - 1; -+ -+ mpcb->mptcp_rem_key = remote_key; -+ mptcp_key_sha1(mpcb->mptcp_rem_key, &mpcb->mptcp_rem_token, &rcv_idsn); -+ rcv_idsn = ntohll(rcv_idsn) + 1; -+ mpcb->rcv_high_order[0] = rcv_idsn >> 32; -+ mpcb->rcv_high_order[1] = mpcb->rcv_high_order[0] + 1; -+ -+ mpcb->meta_sk = meta_sk; -+ mpcb->master_sk = master_sk; -+ -+ skb_queue_head_init(&mpcb->reinject_queue); -+ mutex_init(&mpcb->mpcb_mutex); -+ -+ /* Init time-wait stuff */ -+ INIT_LIST_HEAD(&mpcb->tw_list); -+ spin_lock_init(&mpcb->tw_lock); -+ -+ INIT_HLIST_HEAD(&mpcb->callback_list); -+ -+ mpcb->orig_sk_rcvbuf = meta_sk->sk_rcvbuf; -+ mpcb->orig_sk_sndbuf = meta_sk->sk_sndbuf; -+ mpcb->orig_window_clamp = meta_tp->window_clamp; -+ -+ /* The meta is directly linked - set refcnt to 1 */ -+ atomic_set(&mpcb->mpcb_refcnt, 1); -+ -+ if (!meta_tp->inside_tk_table) { -+ /* Adding the meta_tp in the token hashtable - coming from server-side */ -+ rcu_read_lock(); -+ local_bh_disable(); -+ spin_lock(&mptcp_tk_hashlock); -+ -+ /* With lockless listeners, we might process two ACKs at the -+ * same time. With TCP, inet_csk_complete_hashdance takes care -+ * of this. But, for MPTCP this would be too late if we add -+ * this MPTCP-socket in the token table (new subflows might -+ * come in and match on this socket here. -+ * So, we need to check if someone else already added the token -+ * and revert in that case. The other guy won the race... -+ */ -+ if (mptcp_find_token(mpcb->mptcp_loc_token)) { -+ spin_unlock(&mptcp_tk_hashlock); -+ local_bh_enable(); -+ rcu_read_unlock(); -+ -+ goto err_insert_token; -+ } -+ __mptcp_hash_insert(meta_tp, mpcb->mptcp_loc_token); -+ -+ spin_unlock(&mptcp_tk_hashlock); -+ local_bh_enable(); -+ rcu_read_unlock(); -+ } -+ master_tp->inside_tk_table = 0; -+ -+#if IS_ENABLED(CONFIG_IPV6) -+ if (meta_icsk->icsk_af_ops == &mptcp_v6_mapped) { -+ struct tcp6_sock *master_tp6 = (struct tcp6_sock *)master_sk; -+ struct ipv6_pinfo *newnp, *np = inet6_sk(meta_sk); -+ -+ inet_sk(master_sk)->pinet6 = &master_tp6->inet6; -+ -+ newnp = inet6_sk(master_sk); -+ memcpy(newnp, np, sizeof(struct ipv6_pinfo)); -+ -+ newnp->ipv6_mc_list = NULL; -+ newnp->ipv6_ac_list = NULL; -+ newnp->ipv6_fl_list = NULL; -+ newnp->pktoptions = NULL; -+ newnp->opt = NULL; -+ -+ newnp->rxopt.all = 0; -+ newnp->repflow = 0; -+ np->rxopt.all = 0; -+ np->repflow = 0; -+ } else if (meta_sk->sk_family == AF_INET6) { -+ struct tcp6_sock *master_tp6 = (struct tcp6_sock *)master_sk; -+ struct ipv6_pinfo *newnp, *np = inet6_sk(meta_sk); -+ struct ipv6_txoptions *opt; -+ -+ inet_sk(master_sk)->pinet6 = &master_tp6->inet6; -+ -+ /* The following heavily inspired from tcp_v6_syn_recv_sock() */ -+ newnp = inet6_sk(master_sk); -+ memcpy(newnp, np, sizeof(struct ipv6_pinfo)); -+ -+ newnp->ipv6_mc_list = NULL; -+ newnp->ipv6_ac_list = NULL; -+ newnp->ipv6_fl_list = NULL; -+ newnp->pktoptions = NULL; -+ newnp->opt = NULL; -+ -+ newnp->rxopt.all = 0; -+ newnp->repflow = 0; -+ np->rxopt.all = 0; -+ np->repflow = 0; -+ -+ opt = rcu_dereference(np->opt); -+ if (opt) { -+ opt = ipv6_dup_options(master_sk, opt); -+ RCU_INIT_POINTER(newnp->opt, opt); -+ } -+ inet_csk(master_sk)->icsk_ext_hdr_len = 0; -+ if (opt) -+ inet_csk(master_sk)->icsk_ext_hdr_len = opt->opt_nflen + -+ opt->opt_flen; -+ } -+#endif -+ -+ meta_tp->mptcp = NULL; -+ -+ meta_tp->write_seq = (u32)snd_idsn; -+ meta_tp->snd_sml = meta_tp->write_seq; -+ meta_tp->snd_una = meta_tp->write_seq; -+ meta_tp->snd_nxt = meta_tp->write_seq; -+ meta_tp->pushed_seq = meta_tp->write_seq; -+ meta_tp->snd_up = meta_tp->write_seq; -+ -+ meta_tp->copied_seq = (u32)rcv_idsn; -+ meta_tp->rcv_nxt = (u32)rcv_idsn; -+ meta_tp->rcv_wup = (u32)rcv_idsn; -+ -+ meta_tp->snd_wl1 = meta_tp->rcv_nxt - 1; -+ meta_tp->snd_wnd = window; -+ meta_tp->retrans_stamp = 0; /* Set in tcp_connect() */ -+ -+ meta_tp->packets_out = 0; -+ meta_icsk->icsk_probes_out = 0; -+ -+ /* Set mptcp-pointers */ -+ master_tp->mpcb = mpcb; -+ master_tp->meta_sk = meta_sk; -+ meta_tp->mpcb = mpcb; -+ meta_tp->meta_sk = meta_sk; -+ -+ meta_tp->was_meta_sk = 0; -+ -+ /* Initialize the queues */ -+ master_tp->out_of_order_queue = RB_ROOT; -+ tcp_prequeue_init(master_tp); -+ INIT_LIST_HEAD(&master_tp->tsq_node); -+ -+ master_tp->tsq_flags = 0; -+ /* icsk_bind_hash inherited from the meta, but it will be properly set in -+ * mptcp_create_master_sk. Same operation is done in inet_csk_clone_lock. -+ */ -+ inet_csk(master_sk)->icsk_bind_hash = NULL; -+ -+ /* Init the accept_queue structure, we support a queue of 32 pending -+ * connections, it does not need to be huge, since we only store here -+ * pending subflow creations. -+ */ -+ reqsk_queue_alloc(&meta_icsk->icsk_accept_queue); -+ meta_sk->sk_max_ack_backlog = 32; -+ meta_sk->sk_ack_backlog = 0; -+ -+ if (!sock_flag(meta_sk, SOCK_MPTCP)) { -+ mptcp_enable_static_key_bh(); -+ sock_set_flag(meta_sk, SOCK_MPTCP); -+ } -+ -+ /* Redefine function-pointers as the meta-sk is now fully ready */ -+ meta_tp->mpc = 1; -+ meta_tp->ops = &mptcp_meta_specific; -+ -+ meta_sk->sk_backlog_rcv = mptcp_backlog_rcv; -+ meta_sk->sk_destruct = mptcp_sock_destruct; -+ -+ /* Meta-level retransmit timer */ -+ meta_icsk->icsk_rto *= 2; /* Double of initial - rto */ -+ -+ tcp_init_xmit_timers(master_sk); -+ /* Has been set for sending out the SYN */ -+ inet_csk_clear_xmit_timer(meta_sk, ICSK_TIME_RETRANS); -+ -+ mptcp_mpcb_inherit_sockopts(meta_sk, master_sk); -+ -+ mptcp_init_path_manager(mpcb); -+ mptcp_init_scheduler(mpcb); -+ -+ if (!try_module_get(inet_csk(master_sk)->icsk_ca_ops->owner)) -+ tcp_assign_congestion_control(master_sk); -+ -+ master_tp->saved_syn = NULL; -+ -+ mptcp_debug("%s: created mpcb with token %#x\n", -+ __func__, mpcb->mptcp_loc_token); -+ -+ return 0; -+ -+err_insert_token: -+ kmem_cache_free(mptcp_cb_cache, mpcb); -+ -+err_alloc_mpcb: -+ inet_sk(master_sk)->inet_opt = NULL; -+ master_sk->sk_state = TCP_CLOSE; -+ sock_orphan(master_sk); -+ bh_unlock_sock(master_sk); -+ sk_free(master_sk); -+ -+err_alloc_master: -+ return -ENOBUFS; -+} -+ -+int mptcp_add_sock(struct sock *meta_sk, struct sock *sk, u8 loc_id, u8 rem_id, -+ gfp_t flags) -+{ -+ struct mptcp_cb *mpcb = tcp_sk(meta_sk)->mpcb; -+ struct tcp_sock *tp = tcp_sk(sk); -+ -+ tp->mptcp = kmem_cache_zalloc(mptcp_sock_cache, flags); -+ if (!tp->mptcp) -+ return -ENOMEM; -+ -+ tp->mptcp->path_index = mptcp_set_new_pathindex(mpcb); -+ /* No more space for more subflows? */ -+ if (!tp->mptcp->path_index) { -+ kmem_cache_free(mptcp_sock_cache, tp->mptcp); -+ return -EPERM; -+ } -+ -+ INIT_HLIST_NODE(&tp->mptcp->cb_list); -+ -+ tp->mptcp->tp = tp; -+ tp->mpcb = mpcb; -+ tp->meta_sk = meta_sk; -+ -+ if (!sock_flag(sk, SOCK_MPTCP)) { -+ mptcp_enable_static_key_bh(); -+ sock_set_flag(sk, SOCK_MPTCP); -+ } -+ -+ tp->mpc = 1; -+ tp->ops = &mptcp_sub_specific; -+ -+ tp->mptcp->loc_id = loc_id; -+ tp->mptcp->rem_id = rem_id; -+ if (mpcb->sched_ops->init) -+ mpcb->sched_ops->init(sk); -+ -+ /* The corresponding sock_put is in mptcp_sock_destruct(). It cannot be -+ * included in mptcp_del_sock(), because the mpcb must remain alive -+ * until the last subsocket is completely destroyed. -+ */ -+ sock_hold(meta_sk); -+ atomic_inc(&mpcb->mpcb_refcnt); -+ -+ tp->mptcp->next = mpcb->connection_list; -+ mpcb->connection_list = tp; -+ tp->mptcp->attached = 1; -+ -+ mpcb->cnt_subflows++; -+ atomic_add(atomic_read(&((struct sock *)tp)->sk_rmem_alloc), -+ &meta_sk->sk_rmem_alloc); -+ -+ mptcp_sub_inherit_sockopts(meta_sk, sk); -+ INIT_DELAYED_WORK(&tp->mptcp->work, mptcp_sub_close_wq); -+ -+ /* Properly inherit CC from the meta-socket */ -+ mptcp_assign_congestion_control(sk); -+ -+ /* As we successfully allocated the mptcp_tcp_sock, we have to -+ * change the function-pointers here (for sk_destruct to work correctly) -+ */ -+ sk->sk_error_report = mptcp_sock_def_error_report; -+ sk->sk_data_ready = mptcp_data_ready; -+ sk->sk_write_space = mptcp_write_space; -+ sk->sk_state_change = mptcp_set_state; -+ sk->sk_destruct = mptcp_sock_destruct; -+ -+ if (sk->sk_family == AF_INET) -+ mptcp_debug("%s: token %#x pi %d, src_addr:%pI4:%d dst_addr:%pI4:%d, cnt_subflows now %d\n", -+ __func__ , mpcb->mptcp_loc_token, -+ tp->mptcp->path_index, -+ &((struct inet_sock *)tp)->inet_saddr, -+ ntohs(((struct inet_sock *)tp)->inet_sport), -+ &((struct inet_sock *)tp)->inet_daddr, -+ ntohs(((struct inet_sock *)tp)->inet_dport), -+ mpcb->cnt_subflows); -+#if IS_ENABLED(CONFIG_IPV6) -+ else -+ mptcp_debug("%s: token %#x pi %d, src_addr:%pI6:%d dst_addr:%pI6:%d, cnt_subflows now %d\n", -+ __func__ , mpcb->mptcp_loc_token, -+ tp->mptcp->path_index, &inet6_sk(sk)->saddr, -+ ntohs(((struct inet_sock *)tp)->inet_sport), -+ &sk->sk_v6_daddr, -+ ntohs(((struct inet_sock *)tp)->inet_dport), -+ mpcb->cnt_subflows); -+#endif -+ -+ return 0; -+} -+ -+void mptcp_del_sock(struct sock *sk) -+{ -+ struct tcp_sock *tp = tcp_sk(sk), *tp_prev; -+ struct mptcp_cb *mpcb; -+ -+ if (!tp->mptcp || !tp->mptcp->attached) -+ return; -+ -+ mpcb = tp->mpcb; -+ tp_prev = mpcb->connection_list; -+ -+ if (mpcb->sched_ops->release) -+ mpcb->sched_ops->release(sk); -+ -+ if (mpcb->pm_ops->delete_subflow) -+ mpcb->pm_ops->delete_subflow(sk); -+ -+ mptcp_debug("%s: Removing subsock tok %#x pi:%d state %d is_meta? %d\n", -+ __func__, mpcb->mptcp_loc_token, tp->mptcp->path_index, -+ sk->sk_state, is_meta_sk(sk)); -+ -+ if (tp_prev == tp) { -+ mpcb->connection_list = tp->mptcp->next; -+ } else { -+ for (; tp_prev && tp_prev->mptcp->next; tp_prev = tp_prev->mptcp->next) { -+ if (tp_prev->mptcp->next == tp) { -+ tp_prev->mptcp->next = tp->mptcp->next; -+ break; -+ } -+ } -+ } -+ mpcb->cnt_subflows--; -+ if (tp->mptcp->establish_increased) -+ mpcb->cnt_established--; -+ -+ tp->mptcp->next = NULL; -+ tp->mptcp->attached = 0; -+ mpcb->path_index_bits &= ~(1 << tp->mptcp->path_index); -+ -+ if (!skb_queue_empty(&sk->sk_write_queue)) -+ mptcp_reinject_data(sk, 0); -+ -+ if (is_master_tp(tp)) { -+ struct sock *meta_sk = mptcp_meta_sk(sk); -+ struct tcp_sock *meta_tp = tcp_sk(meta_sk); -+ -+ if (meta_tp->record_master_info && -+ !sock_flag(meta_sk, SOCK_DEAD)) { -+ mpcb->master_info = kmalloc(sizeof(*mpcb->master_info), -+ GFP_ATOMIC); -+ -+ if (mpcb->master_info) -+ tcp_get_info(sk, mpcb->master_info); -+ } -+ -+ mpcb->master_sk = NULL; -+ } else if (tp->mptcp->pre_established) { -+ sk_stop_timer(sk, &tp->mptcp->mptcp_ack_timer); -+ } -+ -+ rcu_assign_pointer(inet_sk(sk)->inet_opt, NULL); -+} -+ -+/* Updates the MPTCP-session based on path-manager information (e.g., addresses, -+ * low-prio flows,...). -+ */ -+void mptcp_update_metasocket(const struct sock *meta_sk) -+{ -+ if (tcp_sk(meta_sk)->mpcb->pm_ops->new_session) -+ tcp_sk(meta_sk)->mpcb->pm_ops->new_session(meta_sk); -+} -+ -+/* Clean up the receive buffer for full frames taken by the user, -+ * then send an ACK if necessary. COPIED is the number of bytes -+ * tcp_recvmsg has given to the user so far, it speeds up the -+ * calculation of whether or not we must ACK for the sake of -+ * a window update. -+ * (inspired from tcp_cleanup_rbuf()) -+ */ -+void mptcp_cleanup_rbuf(struct sock *meta_sk, int copied) -+{ -+ struct tcp_sock *meta_tp = tcp_sk(meta_sk); -+ struct sock *sk; -+ bool recheck_rcv_window = false; -+ __u32 rcv_window_now = 0; -+ -+ if (copied > 0 && !(meta_sk->sk_shutdown & RCV_SHUTDOWN)) { -+ rcv_window_now = tcp_receive_window(meta_tp); -+ -+ /* Optimize, __mptcp_select_window() is not cheap. */ -+ if (2 * rcv_window_now <= meta_tp->window_clamp) -+ recheck_rcv_window = true; -+ } -+ -+ mptcp_for_each_sk(meta_tp->mpcb, sk) { -+ struct tcp_sock *tp = tcp_sk(sk); -+ const struct inet_connection_sock *icsk = inet_csk(sk); -+ -+ if (!mptcp_sk_can_send_ack(sk)) -+ continue; -+ -+ if (!inet_csk_ack_scheduled(sk)) -+ goto second_part; -+ /* Delayed ACKs frequently hit locked sockets during bulk -+ * receive. -+ */ -+ if (icsk->icsk_ack.blocked || -+ /* Once-per-two-segments ACK was not sent by tcp_input.c */ -+ tp->rcv_nxt - tp->rcv_wup > icsk->icsk_ack.rcv_mss || -+ /* If this read emptied read buffer, we send ACK, if -+ * connection is not bidirectional, user drained -+ * receive buffer and there was a small segment -+ * in queue. -+ */ -+ (copied > 0 && -+ ((icsk->icsk_ack.pending & ICSK_ACK_PUSHED2) || -+ ((icsk->icsk_ack.pending & ICSK_ACK_PUSHED) && -+ !icsk->icsk_ack.pingpong)) && -+ !atomic_read(&meta_sk->sk_rmem_alloc))) { -+ tcp_send_ack(sk); -+ continue; -+ } -+ -+second_part: -+ /* This here is the second part of tcp_cleanup_rbuf */ -+ if (recheck_rcv_window) { -+ __u32 new_window = tp->ops->__select_window(sk); -+ -+ /* Send ACK now, if this read freed lots of space -+ * in our buffer. Certainly, new_window is new window. -+ * We can advertise it now, if it is not less than -+ * current one. -+ * "Lots" means "at least twice" here. -+ */ -+ if (new_window && new_window >= 2 * rcv_window_now) -+ tcp_send_ack(sk); -+ } -+ } -+} -+ -+static int mptcp_sub_send_fin(struct sock *sk) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct sk_buff *skb = tcp_write_queue_tail(sk); -+ int mss_now; -+ -+ /* Optimization, tack on the FIN if we have a queue of -+ * unsent frames. But be careful about outgoing SACKS -+ * and IP options. -+ */ -+ mss_now = tcp_current_mss(sk); -+ -+ if (tcp_send_head(sk) != NULL) { -+ TCP_SKB_CB(skb)->tcp_flags |= TCPHDR_FIN; -+ TCP_SKB_CB(skb)->end_seq++; -+ tp->write_seq++; -+ } else { -+ skb = alloc_skb_fclone(MAX_TCP_HEADER, GFP_ATOMIC); -+ if (!skb) -+ return 1; -+ -+ /* Reserve space for headers and prepare control bits. */ -+ skb_reserve(skb, MAX_TCP_HEADER); -+ /* FIN eats a sequence byte, write_seq advanced by tcp_queue_skb(). */ -+ tcp_init_nondata_skb(skb, tp->write_seq, -+ TCPHDR_ACK | TCPHDR_FIN); -+ tcp_queue_skb(sk, skb); -+ } -+ __tcp_push_pending_frames(sk, mss_now, TCP_NAGLE_OFF); -+ -+ return 0; -+} -+ -+static void mptcp_sub_close_doit(struct sock *sk) -+{ -+ struct sock *meta_sk = mptcp_meta_sk(sk); -+ struct tcp_sock *tp = tcp_sk(sk); -+ -+ if (sock_flag(sk, SOCK_DEAD)) -+ return; -+ -+ if (meta_sk->sk_shutdown == SHUTDOWN_MASK || sk->sk_state == TCP_CLOSE) { -+ tp->closing = 1; -+ tcp_close(sk, 0); -+ } else if (tcp_close_state(sk)) { -+ sk->sk_shutdown |= SEND_SHUTDOWN; -+ tcp_send_fin(sk); -+ } -+} -+ -+void mptcp_sub_close_wq(struct work_struct *work) -+{ -+ struct tcp_sock *tp = container_of(work, struct mptcp_tcp_sock, work.work)->tp; -+ struct sock *sk = (struct sock *)tp; -+ struct sock *meta_sk = mptcp_meta_sk(sk); -+ -+ mutex_lock(&tp->mpcb->mpcb_mutex); -+ lock_sock_nested(meta_sk, SINGLE_DEPTH_NESTING); -+ -+ mptcp_sub_close_doit(sk); -+ -+ release_sock(meta_sk); -+ mutex_unlock(&tp->mpcb->mpcb_mutex); -+ sock_put(sk); -+} -+ -+void mptcp_sub_close(struct sock *sk, unsigned long delay) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct delayed_work *work = &tcp_sk(sk)->mptcp->work; -+ -+ /* We are already closing - e.g., call from sock_def_error_report upon -+ * tcp_disconnect in tcp_close. -+ */ -+ if (tp->closing) -+ return; -+ -+ /* Work already scheduled ? */ -+ if (work_pending(&work->work)) { -+ /* Work present - who will be first ? */ -+ if (jiffies + delay > work->timer.expires) -+ return; -+ -+ /* Try canceling - if it fails, work will be executed soon */ -+ if (!cancel_delayed_work(work)) -+ return; -+ sock_put(sk); -+ } -+ -+ if (!delay) { -+ unsigned char old_state = sk->sk_state; -+ -+ /* We directly send the FIN. Because it may take so a long time, -+ * untile the work-queue will get scheduled... -+ * -+ * If mptcp_sub_send_fin returns 1, it failed and thus we reset -+ * the old state so that tcp_close will finally send the fin -+ * in user-context. -+ */ -+ if (!sk->sk_err && old_state != TCP_CLOSE && -+ tcp_close_state(sk) && mptcp_sub_send_fin(sk)) { -+ if (old_state == TCP_ESTABLISHED) -+ TCP_INC_STATS(sock_net(sk), TCP_MIB_CURRESTAB); -+ sk->sk_state = old_state; -+ } -+ } -+ -+ sock_hold(sk); -+ queue_delayed_work(mptcp_wq, work, delay); -+} -+ -+void mptcp_sub_force_close(struct sock *sk) -+{ -+ /* The below tcp_done may have freed the socket, if he is already dead. -+ * Thus, we are not allowed to access it afterwards. That's why -+ * we have to store the dead-state in this local variable. -+ */ -+ int sock_is_dead = sock_flag(sk, SOCK_DEAD); -+ -+ tcp_sk(sk)->mp_killed = 1; -+ -+ if (sk->sk_state != TCP_CLOSE) -+ tcp_done(sk); -+ -+ if (!sock_is_dead) -+ mptcp_sub_close(sk, 0); -+} -+EXPORT_SYMBOL(mptcp_sub_force_close); -+ -+/* Update the mpcb send window, based on the contributions -+ * of each subflow -+ */ -+void mptcp_update_sndbuf(const struct tcp_sock *tp) -+{ -+ struct sock *meta_sk = tp->meta_sk, *sk; -+ int new_sndbuf = 0, old_sndbuf = meta_sk->sk_sndbuf; -+ -+ mptcp_for_each_sk(tp->mpcb, sk) { -+ if (!mptcp_sk_can_send(sk)) -+ continue; -+ -+ new_sndbuf += sk->sk_sndbuf; -+ -+ if (new_sndbuf > sysctl_tcp_wmem[2] || new_sndbuf < 0) { -+ new_sndbuf = sysctl_tcp_wmem[2]; -+ break; -+ } -+ } -+ meta_sk->sk_sndbuf = max(min(new_sndbuf, sysctl_tcp_wmem[2]), meta_sk->sk_sndbuf); -+ -+ /* The subflow's call to sk_write_space in tcp_new_space ends up in -+ * mptcp_write_space. -+ * It has nothing to do with waking up the application. -+ * So, we do it here. -+ */ -+ if (old_sndbuf != meta_sk->sk_sndbuf) -+ meta_sk->sk_write_space(meta_sk); -+} -+ -+/* Similar to: tcp_close */ -+void mptcp_close(struct sock *meta_sk, long timeout) -+{ -+ struct tcp_sock *meta_tp = tcp_sk(meta_sk); -+ struct sock *sk_it, *tmpsk; -+ struct mptcp_cb *mpcb = meta_tp->mpcb; -+ struct sk_buff *skb; -+ int data_was_unread = 0; -+ int state; -+ -+ mptcp_debug("%s: Close of meta_sk with tok %#x\n", -+ __func__, mpcb->mptcp_loc_token); -+ -+ mutex_lock(&mpcb->mpcb_mutex); -+ lock_sock_nested(meta_sk, SINGLE_DEPTH_NESTING); -+ -+ if (meta_tp->inside_tk_table) -+ /* Detach the mpcb from the token hashtable */ -+ mptcp_hash_remove_bh(meta_tp); -+ -+ meta_sk->sk_shutdown = SHUTDOWN_MASK; -+ /* We need to flush the recv. buffs. We do this only on the -+ * descriptor close, not protocol-sourced closes, because the -+ * reader process may not have drained the data yet! -+ */ -+ while ((skb = __skb_dequeue(&meta_sk->sk_receive_queue)) != NULL) { -+ u32 len = TCP_SKB_CB(skb)->end_seq - TCP_SKB_CB(skb)->seq; -+ -+ if (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN) -+ len--; -+ data_was_unread += len; -+ __kfree_skb(skb); -+ } -+ -+ sk_mem_reclaim(meta_sk); -+ -+ /* If socket has been already reset (e.g. in tcp_reset()) - kill it. */ -+ if (meta_sk->sk_state == TCP_CLOSE) { -+ mptcp_for_each_sk_safe(mpcb, sk_it, tmpsk) { -+ if (tcp_sk(sk_it)->send_mp_fclose) -+ continue; -+ mptcp_sub_close(sk_it, 0); -+ } -+ goto adjudge_to_death; -+ } -+ -+ if (data_was_unread) { -+ /* Unread data was tossed, zap the connection. */ -+ NET_INC_STATS(sock_net(meta_sk), LINUX_MIB_TCPABORTONCLOSE); -+ tcp_set_state(meta_sk, TCP_CLOSE); -+ tcp_sk(meta_sk)->ops->send_active_reset(meta_sk, -+ meta_sk->sk_allocation); -+ } else if (sock_flag(meta_sk, SOCK_LINGER) && !meta_sk->sk_lingertime) { -+ /* Check zero linger _after_ checking for unread data. */ -+ meta_sk->sk_prot->disconnect(meta_sk, 0); -+ NET_INC_STATS(sock_net(meta_sk), LINUX_MIB_TCPABORTONDATA); -+ } else if (tcp_close_state(meta_sk)) { -+ mptcp_send_fin(meta_sk); -+ } else if (meta_tp->snd_una == meta_tp->write_seq) { -+ /* The DATA_FIN has been sent and acknowledged -+ * (e.g., by sk_shutdown). Close all the other subflows -+ */ -+ mptcp_for_each_sk_safe(mpcb, sk_it, tmpsk) { -+ unsigned long delay = 0; -+ /* If we are the passive closer, don't trigger -+ * subflow-fin until the subflow has been finned -+ * by the peer. - thus we add a delay -+ */ -+ if (mpcb->passive_close && -+ sk_it->sk_state == TCP_ESTABLISHED) -+ delay = inet_csk(sk_it)->icsk_rto << 3; -+ -+ mptcp_sub_close(sk_it, delay); -+ } -+ } -+ -+ sk_stream_wait_close(meta_sk, timeout); -+ -+adjudge_to_death: -+ state = meta_sk->sk_state; -+ sock_hold(meta_sk); -+ sock_orphan(meta_sk); -+ -+ /* socket will be freed after mptcp_close - we have to prevent -+ * access from the subflows. -+ */ -+ mptcp_for_each_sk(mpcb, sk_it) { -+ /* Similar to sock_orphan, but we don't set it DEAD, because -+ * the callbacks are still set and must be called. -+ */ -+ write_lock_bh(&sk_it->sk_callback_lock); -+ sk_set_socket(sk_it, NULL); -+ sk_it->sk_wq = NULL; -+ write_unlock_bh(&sk_it->sk_callback_lock); -+ } -+ -+ /* It is the last release_sock in its life. It will remove backlog. */ -+ release_sock(meta_sk); -+ -+ /* Now socket is owned by kernel and we acquire BH lock -+ * to finish close. No need to check for user refs. -+ */ -+ local_bh_disable(); -+ bh_lock_sock(meta_sk); -+ WARN_ON(sock_owned_by_user(meta_sk)); -+ -+ percpu_counter_inc(meta_sk->sk_prot->orphan_count); -+ -+ /* Have we already been destroyed by a softirq or backlog? */ -+ if (state != TCP_CLOSE && meta_sk->sk_state == TCP_CLOSE) -+ goto out; -+ -+ /* This is a (useful) BSD violating of the RFC. There is a -+ * problem with TCP as specified in that the other end could -+ * keep a socket open forever with no application left this end. -+ * We use a 3 minute timeout (about the same as BSD) then kill -+ * our end. If they send after that then tough - BUT: long enough -+ * that we won't make the old 4*rto = almost no time - whoops -+ * reset mistake. -+ * -+ * Nope, it was not mistake. It is really desired behaviour -+ * f.e. on http servers, when such sockets are useless, but -+ * consume significant resources. Let's do it with special -+ * linger2 option. --ANK -+ */ -+ -+ if (meta_sk->sk_state == TCP_FIN_WAIT2) { -+ if (meta_tp->linger2 < 0) { -+ tcp_set_state(meta_sk, TCP_CLOSE); -+ meta_tp->ops->send_active_reset(meta_sk, GFP_ATOMIC); -+ __NET_INC_STATS(sock_net(meta_sk), -+ LINUX_MIB_TCPABORTONLINGER); -+ } else { -+ const int tmo = tcp_fin_time(meta_sk); -+ -+ if (tmo > TCP_TIMEWAIT_LEN) { -+ inet_csk_reset_keepalive_timer(meta_sk, -+ tmo - TCP_TIMEWAIT_LEN); -+ } else { -+ meta_tp->ops->time_wait(meta_sk, TCP_FIN_WAIT2, -+ tmo); -+ goto out; -+ } -+ } -+ } -+ if (meta_sk->sk_state != TCP_CLOSE) { -+ sk_mem_reclaim(meta_sk); -+ if (tcp_check_oom(meta_sk, 0)) { -+ if (net_ratelimit()) -+ pr_info("MPTCP: out of memory: force closing socket\n"); -+ tcp_set_state(meta_sk, TCP_CLOSE); -+ meta_tp->ops->send_active_reset(meta_sk, GFP_ATOMIC); -+ __NET_INC_STATS(sock_net(meta_sk), -+ LINUX_MIB_TCPABORTONMEMORY); -+ } -+ } -+ -+ -+ if (meta_sk->sk_state == TCP_CLOSE) -+ inet_csk_destroy_sock(meta_sk); -+ /* Otherwise, socket is reprieved until protocol close. */ -+ -+out: -+ bh_unlock_sock(meta_sk); -+ local_bh_enable(); -+ mutex_unlock(&mpcb->mpcb_mutex); -+ sock_put(meta_sk); /* Taken by sock_hold */ -+} -+ -+void mptcp_disconnect(struct sock *meta_sk) -+{ -+ struct tcp_sock *meta_tp = tcp_sk(meta_sk); -+ struct sock *subsk, *tmpsk; -+ -+ __skb_queue_purge(&meta_tp->mpcb->reinject_queue); -+ -+ if (meta_tp->inside_tk_table) -+ mptcp_hash_remove_bh(meta_tp); -+ -+ local_bh_disable(); -+ mptcp_for_each_sk_safe(meta_tp->mpcb, subsk, tmpsk) { -+ if (spin_is_locked(&subsk->sk_lock.slock)) -+ bh_unlock_sock(subsk); -+ -+ meta_sk->sk_prot->disconnect(subsk, O_NONBLOCK); -+ -+ sock_orphan(subsk); -+ -+ percpu_counter_inc(meta_sk->sk_prot->orphan_count); -+ -+ inet_csk_destroy_sock(subsk); -+ } -+ local_bh_enable(); -+ -+ meta_tp->was_meta_sk = 1; -+ meta_tp->mpc = 0; -+ meta_tp->ops = &tcp_specific; -+} -+ -+ -+/* Returns 1 if we should enable MPTCP for that socket. */ -+int mptcp_doit(struct sock *sk) -+{ -+ /* Don't do mptcp over loopback */ -+ if (sk->sk_family == AF_INET && -+ (ipv4_is_loopback(inet_sk(sk)->inet_daddr) || -+ ipv4_is_loopback(inet_sk(sk)->inet_saddr))) -+ return 0; -+#if IS_ENABLED(CONFIG_IPV6) -+ if (sk->sk_family == AF_INET6 && -+ (ipv6_addr_loopback(&sk->sk_v6_daddr) || -+ ipv6_addr_loopback(&inet6_sk(sk)->saddr))) -+ return 0; -+#endif -+ if (mptcp_v6_is_v4_mapped(sk) && -+ ipv4_is_loopback(inet_sk(sk)->inet_saddr)) -+ return 0; -+ -+#ifdef CONFIG_TCP_MD5SIG -+ /* If TCP_MD5SIG is enabled, do not do MPTCP - there is no Option-Space */ -+ if (tcp_sk(sk)->af_specific->md5_lookup(sk, sk)) -+ return 0; -+#endif -+ -+ return 1; -+} -+ -+int mptcp_create_master_sk(struct sock *meta_sk, __u64 remote_key, -+ __u8 mptcp_ver, u32 window) -+{ -+ struct tcp_sock *master_tp; -+ struct sock *master_sk; -+ -+ if (mptcp_alloc_mpcb(meta_sk, remote_key, mptcp_ver, window)) -+ goto err_alloc_mpcb; -+ -+ master_sk = tcp_sk(meta_sk)->mpcb->master_sk; -+ master_tp = tcp_sk(master_sk); -+ -+ if (mptcp_add_sock(meta_sk, master_sk, 0, 0, GFP_ATOMIC)) -+ goto err_add_sock; -+ -+ if (__inet_inherit_port(meta_sk, master_sk) < 0) -+ goto err_add_sock; -+ -+ meta_sk->sk_prot->unhash(meta_sk); -+ inet_ehash_nolisten(master_sk, NULL); -+ -+ master_tp->mptcp->init_rcv_wnd = master_tp->rcv_wnd; -+ -+ return 0; -+ -+err_add_sock: -+ inet_csk_prepare_forced_close(master_sk); -+ tcp_done(master_sk); -+ -+err_alloc_mpcb: -+ return -ENOBUFS; -+} -+ -+static int __mptcp_check_req_master(struct sock *child, -+ struct request_sock *req) -+{ -+ struct tcp_sock *child_tp = tcp_sk(child); -+ struct sock *meta_sk = child; -+ struct mptcp_cb *mpcb; -+ struct mptcp_request_sock *mtreq; -+ -+ /* Never contained an MP_CAPABLE */ -+ if (!inet_rsk(req)->mptcp_rqsk) -+ return 1; -+ -+ if (!inet_rsk(req)->saw_mpc) { -+ /* Fallback to regular TCP, because we saw one SYN without -+ * MP_CAPABLE. In tcp_check_req we continue the regular path. -+ * But, the socket has been added to the reqsk_tk_htb, so we -+ * must still remove it. -+ */ -+ MPTCP_INC_STATS(sock_net(meta_sk), MPTCP_MIB_MPCAPABLEPASSIVEFALLBACK); -+ mptcp_reqsk_remove_tk(req); -+ return 1; -+ } -+ -+ MPTCP_INC_STATS(sock_net(meta_sk), MPTCP_MIB_MPCAPABLEPASSIVEACK); -+ -+ /* Just set this values to pass them to mptcp_alloc_mpcb */ -+ mtreq = mptcp_rsk(req); -+ child_tp->mptcp_loc_key = mtreq->mptcp_loc_key; -+ child_tp->mptcp_loc_token = mtreq->mptcp_loc_token; -+ -+ if (mptcp_create_master_sk(meta_sk, mtreq->mptcp_rem_key, -+ mtreq->mptcp_ver, child_tp->snd_wnd)) { -+ inet_csk_prepare_forced_close(meta_sk); -+ tcp_done(meta_sk); -+ -+ return -ENOBUFS; -+ } -+ -+ child = tcp_sk(child)->mpcb->master_sk; -+ child_tp = tcp_sk(child); -+ mpcb = child_tp->mpcb; -+ -+ child_tp->mptcp->snt_isn = tcp_rsk(req)->snt_isn; -+ child_tp->mptcp->rcv_isn = tcp_rsk(req)->rcv_isn; -+ -+ mpcb->dss_csum = mtreq->dss_csum; -+ mpcb->server_side = 1; -+ -+ /* Needs to be done here additionally, because when accepting a -+ * new connection we pass by __reqsk_free and not reqsk_free. -+ */ -+ mptcp_reqsk_remove_tk(req); -+ -+ /* Hold when creating the meta-sk in tcp_vX_syn_recv_sock. */ -+ sock_put(meta_sk); -+ -+ return 0; -+} -+ -+int mptcp_check_req_fastopen(struct sock *child, struct request_sock *req) -+{ -+ struct sock *meta_sk = child, *master_sk; -+ struct sk_buff *skb; -+ u32 new_mapping; -+ int ret; -+ -+ ret = __mptcp_check_req_master(child, req); -+ if (ret) -+ return ret; -+ -+ master_sk = tcp_sk(meta_sk)->mpcb->master_sk; -+ -+ /* We need to rewind copied_seq as it is set to IDSN + 1 and as we have -+ * pre-MPTCP data in the receive queue. -+ */ -+ tcp_sk(meta_sk)->copied_seq -= tcp_sk(master_sk)->rcv_nxt - -+ tcp_rsk(req)->rcv_isn - 1; -+ -+ /* Map subflow sequence number to data sequence numbers. We need to map -+ * these data to [IDSN - len - 1, IDSN[. -+ */ -+ new_mapping = tcp_sk(meta_sk)->copied_seq - tcp_rsk(req)->rcv_isn - 1; -+ -+ /* There should be only one skb: the SYN + data. */ -+ skb_queue_walk(&meta_sk->sk_receive_queue, skb) { -+ TCP_SKB_CB(skb)->seq += new_mapping; -+ TCP_SKB_CB(skb)->end_seq += new_mapping; -+ } -+ -+ /* With fastopen we change the semantics of the relative subflow -+ * sequence numbers to deal with middleboxes that could add/remove -+ * multiple bytes in the SYN. We chose to start counting at rcv_nxt - 1 -+ * instead of the regular TCP ISN. -+ */ -+ tcp_sk(master_sk)->mptcp->rcv_isn = tcp_sk(master_sk)->rcv_nxt - 1; -+ -+ /* We need to update copied_seq of the master_sk to account for the -+ * already moved data to the meta receive queue. -+ */ -+ tcp_sk(master_sk)->copied_seq = tcp_sk(master_sk)->rcv_nxt; -+ -+ /* Handled by the master_sk */ -+ tcp_sk(meta_sk)->fastopen_rsk = NULL; -+ -+ return 0; -+} -+ -+int mptcp_check_req_master(struct sock *sk, struct sock *child, -+ struct request_sock *req, const struct sk_buff *skb, -+ int drop) -+{ -+ struct sock *meta_sk = child; -+ int ret; -+ -+ ret = __mptcp_check_req_master(child, req); -+ if (ret) -+ return ret; -+ child = tcp_sk(child)->mpcb->master_sk; -+ -+ sock_rps_save_rxhash(child, skb); -+ -+ /* drop indicates that we come from tcp_check_req and thus need to -+ * handle the request-socket fully. -+ */ -+ if (drop) { -+ tcp_synack_rtt_meas(child, req); -+ inet_csk_complete_hashdance(sk, meta_sk, req, true); -+ } else { -+ /* Thus, we come from syn-cookies */ -+ atomic_set(&req->rsk_refcnt, 1); -+ if (!inet_csk_reqsk_queue_add(sk, req, meta_sk)) { -+ bh_unlock_sock(meta_sk); -+ sock_put(meta_sk); -+ return -1; -+ } -+ } -+ -+ return 0; -+} -+ -+struct sock *mptcp_check_req_child(struct sock *meta_sk, -+ struct sock *child, -+ struct request_sock *req, -+ struct sk_buff *skb, -+ const struct mptcp_options_received *mopt) -+{ -+ struct tcp_sock *child_tp = tcp_sk(child); -+ struct mptcp_request_sock *mtreq = mptcp_rsk(req); -+ struct mptcp_cb *mpcb = tcp_sk(meta_sk)->mpcb; -+ u8 hash_mac_check[20]; -+ -+ child_tp->out_of_order_queue = RB_ROOT; -+ child_tp->inside_tk_table = 0; -+ -+ if (!mopt->join_ack) { -+ MPTCP_INC_STATS(sock_net(meta_sk), MPTCP_MIB_JOINACKFAIL); -+ goto teardown; -+ } -+ -+ mptcp_hmac_sha1((u8 *)&mpcb->mptcp_rem_key, -+ (u8 *)&mpcb->mptcp_loc_key, -+ (u32 *)hash_mac_check, 2, -+ 4, (u8 *)&mtreq->mptcp_rem_nonce, -+ 4, (u8 *)&mtreq->mptcp_loc_nonce); -+ -+ if (memcmp(hash_mac_check, (char *)&mopt->mptcp_recv_mac, 20)) { -+ MPTCP_INC_STATS(sock_net(meta_sk), MPTCP_MIB_JOINACKMAC); -+ goto teardown; -+ } -+ -+ /* Point it to the same struct socket and wq as the meta_sk */ -+ sk_set_socket(child, meta_sk->sk_socket); -+ child->sk_wq = meta_sk->sk_wq; -+ -+ if (mptcp_add_sock(meta_sk, child, mtreq->loc_id, mtreq->rem_id, GFP_ATOMIC)) { -+ /* Has been inherited, but now child_tp->mptcp is NULL */ -+ child_tp->mpc = 0; -+ child_tp->ops = &tcp_specific; -+ -+ /* TODO when we support acking the third ack for new subflows, -+ * we should silently discard this third ack, by returning NULL. -+ * -+ * Maybe, at the retransmission we will have enough memory to -+ * fully add the socket to the meta-sk. -+ */ -+ goto teardown; -+ } -+ -+ /* The child is a clone of the meta socket, we must now reset -+ * some of the fields -+ */ -+ child_tp->mptcp->rcv_low_prio = mtreq->rcv_low_prio; -+ -+ /* We should allow proper increase of the snd/rcv-buffers. Thus, we -+ * use the original values instead of the bloated up ones from the -+ * clone. -+ */ -+ child->sk_sndbuf = mpcb->orig_sk_sndbuf; -+ child->sk_rcvbuf = mpcb->orig_sk_rcvbuf; -+ -+ child_tp->mptcp->slave_sk = 1; -+ child_tp->mptcp->snt_isn = tcp_rsk(req)->snt_isn; -+ child_tp->mptcp->rcv_isn = tcp_rsk(req)->rcv_isn; -+ child_tp->mptcp->init_rcv_wnd = req->rsk_rcv_wnd; -+ -+ child_tp->tsq_flags = 0; -+ -+ sock_rps_save_rxhash(child, skb); -+ tcp_synack_rtt_meas(child, req); -+ -+ /* Subflows do not use the accept queue, as they -+ * are attached immediately to the mpcb. -+ */ -+ inet_csk_reqsk_queue_drop(meta_sk, req); -+ reqsk_queue_removed(&inet_csk(meta_sk)->icsk_accept_queue, req); -+ -+ /* The refcnt is initialized to 2, because regular TCP will put him -+ * in the socket's listener queue. However, we do not have a listener-queue. -+ * So, we need to make sure that this request-sock indeed gets destroyed. -+ */ -+ reqsk_put(req); -+ -+ MPTCP_INC_STATS(sock_net(meta_sk), MPTCP_MIB_JOINACKRX); -+ return child; -+ -+teardown: -+ req->rsk_ops->send_reset(meta_sk, skb); -+ -+ /* Drop this request - sock creation failed. */ -+ inet_csk_reqsk_queue_drop(meta_sk, req); -+ reqsk_queue_removed(&inet_csk(meta_sk)->icsk_accept_queue, req); -+ inet_csk_prepare_forced_close(child); -+ tcp_done(child); -+ return meta_sk; -+} -+ -+int mptcp_init_tw_sock(struct sock *sk, struct tcp_timewait_sock *tw) -+{ -+ struct mptcp_tw *mptw; -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct mptcp_cb *mpcb = tp->mpcb; -+ -+ /* A subsocket in tw can only receive data. So, if we are in -+ * infinite-receive, then we should not reply with a data-ack or act -+ * upon general MPTCP-signaling. We prevent this by simply not creating -+ * the mptcp_tw_sock. -+ */ -+ if (mpcb->infinite_mapping_rcv) { -+ tw->mptcp_tw = NULL; -+ return 0; -+ } -+ -+ /* Alloc MPTCP-tw-sock */ -+ mptw = kmem_cache_alloc(mptcp_tw_cache, GFP_ATOMIC); -+ if (!mptw) { -+ tw->mptcp_tw = NULL; -+ return -ENOBUFS; -+ } -+ -+ atomic_inc(&mpcb->mpcb_refcnt); -+ -+ tw->mptcp_tw = mptw; -+ mptw->loc_key = mpcb->mptcp_loc_key; -+ mptw->meta_tw = mpcb->in_time_wait; -+ mptw->rcv_nxt = mptcp_get_rcv_nxt_64(mptcp_meta_tp(tp)); -+ if (mptw->meta_tw && mpcb->mptw_state != TCP_TIME_WAIT) -+ mptw->rcv_nxt++; -+ rcu_assign_pointer(mptw->mpcb, mpcb); -+ -+ spin_lock_bh(&mpcb->tw_lock); -+ list_add_rcu(&mptw->list, &tp->mpcb->tw_list); -+ mptw->in_list = 1; -+ spin_unlock_bh(&mpcb->tw_lock); -+ -+ return 0; -+} -+ -+void mptcp_twsk_destructor(struct tcp_timewait_sock *tw) -+{ -+ struct mptcp_cb *mpcb; -+ -+ rcu_read_lock(); -+ local_bh_disable(); -+ mpcb = rcu_dereference(tw->mptcp_tw->mpcb); -+ -+ /* If we are still holding a ref to the mpcb, we have to remove ourself -+ * from the list and drop the ref properly. -+ */ -+ if (mpcb && atomic_inc_not_zero(&mpcb->mpcb_refcnt)) { -+ spin_lock(&mpcb->tw_lock); -+ if (tw->mptcp_tw->in_list) { -+ list_del_rcu(&tw->mptcp_tw->list); -+ tw->mptcp_tw->in_list = 0; -+ } -+ spin_unlock(&mpcb->tw_lock); -+ -+ /* Twice, because we increased it above */ -+ mptcp_mpcb_put(mpcb); -+ mptcp_mpcb_put(mpcb); -+ } -+ -+ local_bh_enable(); -+ rcu_read_unlock(); -+ -+ kmem_cache_free(mptcp_tw_cache, tw->mptcp_tw); -+} -+ -+/* Updates the rcv_nxt of the time-wait-socks and allows them to ack a -+ * data-fin. -+ */ -+void mptcp_time_wait(struct sock *meta_sk, int state, int timeo) -+{ -+ struct tcp_sock *meta_tp = tcp_sk(meta_sk); -+ struct mptcp_tw *mptw; -+ -+ /* Used for sockets that go into tw after the meta -+ * (see mptcp_init_tw_sock()) -+ */ -+ meta_tp->mpcb->in_time_wait = 1; -+ meta_tp->mpcb->mptw_state = state; -+ -+ /* Update the time-wait-sock's information */ -+ rcu_read_lock(); -+ local_bh_disable(); -+ list_for_each_entry_rcu(mptw, &meta_tp->mpcb->tw_list, list) { -+ mptw->meta_tw = 1; -+ mptw->rcv_nxt = mptcp_get_rcv_nxt_64(meta_tp); -+ -+ /* We want to ack a DATA_FIN, but are yet in FIN_WAIT_2 - -+ * pretend as if the DATA_FIN has already reached us, that way -+ * the checks in tcp_timewait_state_process will be good as the -+ * DATA_FIN comes in. -+ */ -+ if (state != TCP_TIME_WAIT) -+ mptw->rcv_nxt++; -+ } -+ local_bh_enable(); -+ rcu_read_unlock(); -+ -+ if (meta_sk->sk_state != TCP_CLOSE) -+ tcp_done(meta_sk); -+} -+ -+void mptcp_tsq_flags(struct sock *sk) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct sock *meta_sk = mptcp_meta_sk(sk); -+ -+ /* It will be handled as a regular deferred-call */ -+ if (is_meta_sk(sk)) -+ return; -+ -+ if (hlist_unhashed(&tp->mptcp->cb_list)) { -+ hlist_add_head(&tp->mptcp->cb_list, &tp->mpcb->callback_list); -+ /* We need to hold it here, as the sock_hold is not assured -+ * by the release_sock as it is done in regular TCP. -+ * -+ * The subsocket may get inet_csk_destroy'd while it is inside -+ * the callback_list. -+ */ -+ sock_hold(sk); -+ } -+ -+ if (!test_and_set_bit(MPTCP_SUB_DEFERRED, &tcp_sk(meta_sk)->tsq_flags)) -+ sock_hold(meta_sk); -+} -+ -+void mptcp_tsq_sub_deferred(struct sock *meta_sk) -+{ -+ struct tcp_sock *meta_tp = tcp_sk(meta_sk); -+ struct mptcp_tcp_sock *mptcp; -+ struct hlist_node *tmp; -+ -+ BUG_ON(!is_meta_sk(meta_sk) && !meta_tp->was_meta_sk); -+ -+ __sock_put(meta_sk); -+ hlist_for_each_entry_safe(mptcp, tmp, &meta_tp->mpcb->callback_list, cb_list) { -+ struct tcp_sock *tp = mptcp->tp; -+ struct sock *sk = (struct sock *)tp; -+ -+ hlist_del_init(&mptcp->cb_list); -+ sk->sk_prot->release_cb(sk); -+ /* Final sock_put (cfr. mptcp_tsq_flags */ -+ sock_put(sk); -+ } -+} -+ -+void mptcp_join_reqsk_init(const struct mptcp_cb *mpcb, -+ const struct request_sock *req, -+ struct sk_buff *skb) -+{ -+ struct mptcp_request_sock *mtreq = mptcp_rsk(req); -+ struct mptcp_options_received mopt; -+ u8 mptcp_hash_mac[20]; -+ -+ mptcp_init_mp_opt(&mopt); -+ tcp_parse_mptcp_options(skb, &mopt); -+ -+ mtreq->is_sub = 1; -+ inet_rsk(req)->mptcp_rqsk = 1; -+ -+ mtreq->mptcp_rem_nonce = mopt.mptcp_recv_nonce; -+ -+ mptcp_hmac_sha1((u8 *)&mpcb->mptcp_loc_key, -+ (u8 *)&mpcb->mptcp_rem_key, -+ (u32 *)mptcp_hash_mac, 2, -+ 4, (u8 *)&mtreq->mptcp_loc_nonce, -+ 4, (u8 *)&mtreq->mptcp_rem_nonce); -+ mtreq->mptcp_hash_tmac = *(u64 *)mptcp_hash_mac; -+ -+ mtreq->rem_id = mopt.rem_id; -+ mtreq->rcv_low_prio = mopt.low_prio; -+ inet_rsk(req)->saw_mpc = 1; -+ -+ MPTCP_INC_STATS(sock_net(mpcb->meta_sk), MPTCP_MIB_JOINSYNRX); -+} -+ -+void mptcp_reqsk_init(struct request_sock *req, const struct sock *sk, -+ const struct sk_buff *skb, bool want_cookie) -+{ -+ struct mptcp_options_received mopt; -+ struct mptcp_request_sock *mtreq = mptcp_rsk(req); -+ -+ mptcp_init_mp_opt(&mopt); -+ tcp_parse_mptcp_options(skb, &mopt); -+ -+ mtreq->dss_csum = mopt.dss_csum; -+ -+ if (want_cookie) { -+ if (!mptcp_reqsk_new_cookie(req, sk, &mopt, skb)) -+ /* No key available - back to regular TCP */ -+ inet_rsk(req)->mptcp_rqsk = 0; -+ return; -+ } -+ -+ mptcp_reqsk_new_mptcp(req, sk, &mopt, skb); -+} -+ -+void mptcp_cookies_reqsk_init(struct request_sock *req, -+ struct mptcp_options_received *mopt, -+ struct sk_buff *skb) -+{ -+ struct mptcp_request_sock *mtreq = mptcp_rsk(req); -+ -+ /* Absolutely need to always initialize this. */ -+ mtreq->hash_entry.pprev = NULL; -+ -+ mtreq->mptcp_rem_key = mopt->mptcp_sender_key; -+ mtreq->mptcp_loc_key = mopt->mptcp_receiver_key; -+ -+ /* Generate the token */ -+ mptcp_key_sha1(mtreq->mptcp_loc_key, &mtreq->mptcp_loc_token, NULL); -+ -+ rcu_read_lock(); -+ local_bh_disable(); -+ spin_lock(&mptcp_tk_hashlock); -+ -+ /* Check, if the key is still free */ -+ if (mptcp_reqsk_find_tk(mtreq->mptcp_loc_token) || -+ mptcp_find_token(mtreq->mptcp_loc_token)) -+ goto out; -+ -+ inet_rsk(req)->saw_mpc = 1; -+ mtreq->is_sub = 0; -+ inet_rsk(req)->mptcp_rqsk = 1; -+ mtreq->dss_csum = mopt->dss_csum; -+ -+out: -+ spin_unlock(&mptcp_tk_hashlock); -+ local_bh_enable(); -+ rcu_read_unlock(); -+} -+ -+int mptcp_conn_request(struct sock *sk, struct sk_buff *skb) -+{ -+ struct mptcp_options_received mopt; -+ -+ mptcp_init_mp_opt(&mopt); -+ tcp_parse_mptcp_options(skb, &mopt); -+ -+ if (mopt.is_mp_join) -+ return mptcp_do_join_short(skb, &mopt, sock_net(sk)); -+ if (mopt.drop_me) -+ goto drop; -+ -+ if (!sock_flag(sk, SOCK_MPTCP)) -+ mopt.saw_mpc = 0; -+ -+ if (skb->protocol == htons(ETH_P_IP)) { -+ if (mopt.saw_mpc) { -+ if (skb_rtable(skb)->rt_flags & -+ (RTCF_BROADCAST | RTCF_MULTICAST)) -+ goto drop; -+ -+ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_MPCAPABLEPASSIVE); -+ return tcp_conn_request(&mptcp_request_sock_ops, -+ &mptcp_request_sock_ipv4_ops, -+ sk, skb); -+ } -+ -+ return tcp_v4_conn_request(sk, skb); -+#if IS_ENABLED(CONFIG_IPV6) -+ } else { -+ if (mopt.saw_mpc) { -+ if (!ipv6_unicast_destination(skb)) -+ goto drop; -+ -+ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_MPCAPABLEPASSIVE); -+ return tcp_conn_request(&mptcp6_request_sock_ops, -+ &mptcp_request_sock_ipv6_ops, -+ sk, skb); -+ } -+ -+ return tcp_v6_conn_request(sk, skb); -+#endif -+ } -+drop: -+ __NET_INC_STATS(sock_net(sk), LINUX_MIB_LISTENDROPS); -+ return 0; -+} -+ -+static void __mptcp_get_info(const struct sock *meta_sk, -+ struct mptcp_meta_info *info) -+{ -+ const struct inet_connection_sock *meta_icsk = inet_csk(meta_sk); -+ const struct tcp_sock *meta_tp = tcp_sk(meta_sk); -+ u32 now = tcp_time_stamp; -+ unsigned int start; -+ -+ memset(info, 0, sizeof(*info)); -+ -+ info->mptcpi_state = meta_sk->sk_state; -+ info->mptcpi_retransmits = meta_icsk->icsk_retransmits; -+ info->mptcpi_probes = meta_icsk->icsk_probes_out; -+ info->mptcpi_backoff = meta_icsk->icsk_backoff; -+ -+ info->mptcpi_rto = jiffies_to_usecs(meta_icsk->icsk_rto); -+ -+ info->mptcpi_unacked = meta_tp->packets_out; -+ -+ info->mptcpi_last_data_sent = jiffies_to_msecs(now - meta_tp->lsndtime); -+ info->mptcpi_last_data_recv = jiffies_to_msecs(now - meta_icsk->icsk_ack.lrcvtime); -+ info->mptcpi_last_ack_recv = jiffies_to_msecs(now - meta_tp->rcv_tstamp); -+ -+ info->mptcpi_total_retrans = meta_tp->total_retrans; -+ -+ do { -+ start = u64_stats_fetch_begin_irq(&meta_tp->syncp); -+ info->mptcpi_bytes_acked = meta_tp->bytes_acked; -+ info->mptcpi_bytes_received = meta_tp->bytes_received; -+ } while (u64_stats_fetch_retry_irq(&meta_tp->syncp, start)); -+} -+ -+static void mptcp_get_sub_info(struct sock *sk, struct mptcp_sub_info *info) -+{ -+ struct inet_sock *inet = inet_sk(sk); -+ -+ memset(info, 0, sizeof(*info)); -+ -+ if (sk->sk_family == AF_INET) { -+ info->src_v4.sin_family = AF_INET; -+ info->src_v4.sin_port = inet->inet_sport; -+ -+ info->src_v4.sin_addr.s_addr = inet->inet_rcv_saddr; -+ if (!info->src_v4.sin_addr.s_addr) -+ info->src_v4.sin_addr.s_addr = inet->inet_saddr; -+ -+ info->dst_v4.sin_family = AF_INET; -+ info->dst_v4.sin_port = inet->inet_dport; -+ info->dst_v4.sin_addr.s_addr = inet->inet_daddr; -+#if IS_ENABLED(CONFIG_IPV6) -+ } else { -+ struct ipv6_pinfo *np = inet6_sk(sk); -+ -+ info->src_v6.sin6_family = AF_INET6; -+ info->src_v6.sin6_port = inet->inet_sport; -+ -+ if (ipv6_addr_any(&sk->sk_v6_rcv_saddr)) -+ info->src_v6.sin6_addr = np->saddr; -+ else -+ info->src_v6.sin6_addr = sk->sk_v6_rcv_saddr; -+ -+ info->dst_v6.sin6_family = AF_INET6; -+ info->dst_v6.sin6_port = inet->inet_dport; -+ info->dst_v6.sin6_addr = sk->sk_v6_daddr; -+#endif -+ } -+} -+ -+int mptcp_get_info(const struct sock *meta_sk, char __user *optval, int optlen) -+{ -+ const struct tcp_sock *meta_tp = tcp_sk(meta_sk); -+ struct sock *sk; -+ -+ struct mptcp_meta_info meta_info; -+ struct mptcp_info m_info; -+ -+ unsigned int info_len; -+ -+ if (copy_from_user(&m_info, optval, optlen)) -+ return -EFAULT; -+ -+ if (m_info.meta_info) { -+ unsigned int len; -+ -+ __mptcp_get_info(meta_sk, &meta_info); -+ -+ /* Need to set this, if user thinks that tcp_info is bigger than ours */ -+ len = min_t(unsigned int, m_info.meta_len, sizeof(meta_info)); -+ m_info.meta_len = len; -+ -+ if (copy_to_user((void __user *)m_info.meta_info, &meta_info, len)) -+ return -EFAULT; -+ } -+ -+ /* Need to set this, if user thinks that tcp_info is bigger than ours */ -+ info_len = min_t(unsigned int, m_info.tcp_info_len, sizeof(struct tcp_info)); -+ m_info.tcp_info_len = info_len; -+ -+ if (m_info.initial) { -+ struct mptcp_cb *mpcb = meta_tp->mpcb; -+ -+ if (mpcb->master_sk) { -+ struct tcp_info info; -+ -+ tcp_get_info(mpcb->master_sk, &info); -+ if (copy_to_user((void __user *)m_info.initial, &info, info_len)) -+ return -EFAULT; -+ } else if (meta_tp->record_master_info && mpcb->master_info) { -+ if (copy_to_user((void __user *)m_info.initial, mpcb->master_info, info_len)) -+ return -EFAULT; -+ } else { -+ return meta_tp->record_master_info ? -ENOMEM : -EINVAL; -+ } -+ } -+ -+ if (m_info.subflows) { -+ unsigned int len, sub_len = 0; -+ char __user *ptr; -+ -+ ptr = (char __user *)m_info.subflows; -+ len = m_info.sub_len; -+ -+ mptcp_for_each_sk(meta_tp->mpcb, sk) { -+ struct tcp_info t_info; -+ unsigned int tmp_len; -+ -+ tcp_get_info(sk, &t_info); -+ -+ tmp_len = min_t(unsigned int, len, info_len); -+ len -= tmp_len; -+ -+ if (copy_to_user(ptr, &t_info, tmp_len)) -+ return -EFAULT; -+ -+ ptr += tmp_len; -+ sub_len += tmp_len; -+ -+ if (len == 0) -+ break; -+ } -+ -+ m_info.sub_len = sub_len; -+ } -+ -+ if (m_info.subflow_info) { -+ unsigned int len, sub_info_len, total_sub_info_len = 0; -+ char __user *ptr; -+ -+ ptr = (char __user *)m_info.subflow_info; -+ len = m_info.total_sub_info_len; -+ -+ sub_info_len = min_t(unsigned int, m_info.sub_info_len, -+ sizeof(struct mptcp_sub_info)); -+ m_info.sub_info_len = sub_info_len; -+ -+ mptcp_for_each_sk(meta_tp->mpcb, sk) { -+ struct mptcp_sub_info m_sub_info; -+ unsigned int tmp_len; -+ -+ mptcp_get_sub_info(sk, &m_sub_info); -+ -+ tmp_len = min_t(unsigned int, len, sub_info_len); -+ len -= tmp_len; -+ -+ if (copy_to_user(ptr, &m_sub_info, tmp_len)) -+ return -EFAULT; -+ -+ ptr += tmp_len; -+ total_sub_info_len += tmp_len; -+ -+ if (len == 0) -+ break; -+ } -+ -+ m_info.total_sub_info_len = total_sub_info_len; -+ } -+ -+ if (copy_to_user(optval, &m_info, optlen)) -+ return -EFAULT; -+ -+ return 0; -+} -+ -+void mptcp_clear_sk(struct sock *sk, int size) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ -+ /* we do not want to clear tk_table field, because of RCU lookups */ -+ sk_prot_clear_nulls(sk, offsetof(struct tcp_sock, tk_table.next)); -+ -+ size -= offsetof(struct tcp_sock, tk_table.pprev); -+ memset((char *)&tp->tk_table.pprev, 0, size); -+} -+ -+static const struct snmp_mib mptcp_snmp_list[] = { -+ SNMP_MIB_ITEM("MPCapableSYNRX", MPTCP_MIB_MPCAPABLEPASSIVE), -+ SNMP_MIB_ITEM("MPCapableSYNTX", MPTCP_MIB_MPCAPABLEACTIVE), -+ SNMP_MIB_ITEM("MPCapableSYNACKRX", MPTCP_MIB_MPCAPABLEACTIVEACK), -+ SNMP_MIB_ITEM("MPCapableACKRX", MPTCP_MIB_MPCAPABLEPASSIVEACK), -+ SNMP_MIB_ITEM("MPCapableFallbackACK", MPTCP_MIB_MPCAPABLEPASSIVEFALLBACK), -+ SNMP_MIB_ITEM("MPCapableFallbackSYNACK", MPTCP_MIB_MPCAPABLEACTIVEFALLBACK), -+ SNMP_MIB_ITEM("MPCapableRetransFallback", MPTCP_MIB_MPCAPABLERETRANSFALLBACK), -+ SNMP_MIB_ITEM("MPTCPCsumEnabled", MPTCP_MIB_CSUMENABLED), -+ SNMP_MIB_ITEM("MPTCPRetrans", MPTCP_MIB_RETRANSSEGS), -+ SNMP_MIB_ITEM("MPFailRX", MPTCP_MIB_MPFAILRX), -+ SNMP_MIB_ITEM("MPCsumFail", MPTCP_MIB_CSUMFAIL), -+ SNMP_MIB_ITEM("MPFastcloseRX", MPTCP_MIB_FASTCLOSERX), -+ SNMP_MIB_ITEM("MPFastcloseTX", MPTCP_MIB_FASTCLOSETX), -+ SNMP_MIB_ITEM("MPFallbackAckSub", MPTCP_MIB_FBACKSUB), -+ SNMP_MIB_ITEM("MPFallbackAckInit", MPTCP_MIB_FBACKINIT), -+ SNMP_MIB_ITEM("MPFallbackDataSub", MPTCP_MIB_FBDATASUB), -+ SNMP_MIB_ITEM("MPFallbackDataInit", MPTCP_MIB_FBDATAINIT), -+ SNMP_MIB_ITEM("MPRemoveAddrSubDelete", MPTCP_MIB_REMADDRSUB), -+ SNMP_MIB_ITEM("MPJoinNoTokenFound", MPTCP_MIB_JOINNOTOKEN), -+ SNMP_MIB_ITEM("MPJoinAlreadyFallenback", MPTCP_MIB_JOINFALLBACK), -+ SNMP_MIB_ITEM("MPJoinSynTx", MPTCP_MIB_JOINSYNTX), -+ SNMP_MIB_ITEM("MPJoinSynRx", MPTCP_MIB_JOINSYNRX), -+ SNMP_MIB_ITEM("MPJoinSynAckRx", MPTCP_MIB_JOINSYNACKRX), -+ SNMP_MIB_ITEM("MPJoinSynAckHMacFailure", MPTCP_MIB_JOINSYNACKMAC), -+ SNMP_MIB_ITEM("MPJoinAckRx", MPTCP_MIB_JOINACKRX), -+ SNMP_MIB_ITEM("MPJoinAckHMacFailure", MPTCP_MIB_JOINACKMAC), -+ SNMP_MIB_ITEM("MPJoinAckMissing", MPTCP_MIB_JOINACKFAIL), -+ SNMP_MIB_ITEM("MPJoinAckRTO", MPTCP_MIB_JOINACKRTO), -+ SNMP_MIB_ITEM("MPJoinAckRexmit", MPTCP_MIB_JOINACKRXMIT), -+ SNMP_MIB_ITEM("NoDSSInWindow", MPTCP_MIB_NODSSWINDOW), -+ SNMP_MIB_ITEM("DSSNotMatching", MPTCP_MIB_DSSNOMATCH), -+ SNMP_MIB_ITEM("InfiniteMapRx", MPTCP_MIB_INFINITEMAPRX), -+ SNMP_MIB_ITEM("DSSNoMatchTCP", MPTCP_MIB_DSSTCPMISMATCH), -+ SNMP_MIB_ITEM("DSSTrimHead", MPTCP_MIB_DSSTRIMHEAD), -+ SNMP_MIB_ITEM("DSSSplitTail", MPTCP_MIB_DSSSPLITTAIL), -+ SNMP_MIB_ITEM("DSSPurgeOldSubSegs", MPTCP_MIB_PURGEOLD), -+ SNMP_MIB_ITEM("AddAddrRx", MPTCP_MIB_ADDADDRRX), -+ SNMP_MIB_ITEM("AddAddrTx", MPTCP_MIB_ADDADDRTX), -+ SNMP_MIB_ITEM("RemAddrRx", MPTCP_MIB_REMADDRRX), -+ SNMP_MIB_ITEM("RemAddrTx", MPTCP_MIB_REMADDRTX), -+ SNMP_MIB_SENTINEL -+}; -+ -+struct workqueue_struct *mptcp_wq; -+EXPORT_SYMBOL(mptcp_wq); -+ -+/* Output /proc/net/mptcp */ -+static int mptcp_pm_seq_show(struct seq_file *seq, void *v) -+{ -+ struct tcp_sock *meta_tp; -+ const struct net *net = seq->private; -+ int i, n = 0; -+ -+ seq_printf(seq, " sl loc_tok rem_tok v6 local_address remote_address st ns tx_queue rx_queue inode"); -+ seq_putc(seq, '\n'); -+ -+ for (i = 0; i < MPTCP_HASH_SIZE; i++) { -+ struct hlist_nulls_node *node; -+ rcu_read_lock(); -+ local_bh_disable(); -+ hlist_nulls_for_each_entry_rcu(meta_tp, node, -+ &tk_hashtable[i], tk_table) { -+ struct sock *meta_sk = (struct sock *)meta_tp; -+ struct inet_sock *isk = inet_sk(meta_sk); -+ struct mptcp_cb *mpcb = meta_tp->mpcb; -+ -+ if (!mptcp(meta_tp) || !net_eq(net, sock_net(meta_sk))) -+ continue; -+ -+ if (!mpcb) -+ continue; -+ -+ if (capable(CAP_NET_ADMIN)) { -+ seq_printf(seq, "%4d: %04X %04X ", n++, -+ mpcb->mptcp_loc_token, -+ mpcb->mptcp_rem_token); -+ } else { -+ seq_printf(seq, "%4d: %04X %04X ", n++, -1, -1); -+ } -+ if (meta_sk->sk_family == AF_INET || -+ mptcp_v6_is_v4_mapped(meta_sk)) { -+ seq_printf(seq, " 0 %08X:%04X %08X:%04X ", -+ isk->inet_rcv_saddr, -+ ntohs(isk->inet_sport), -+ isk->inet_daddr, -+ ntohs(isk->inet_dport)); -+#if IS_ENABLED(CONFIG_IPV6) -+ } else if (meta_sk->sk_family == AF_INET6) { -+ struct in6_addr *src = &meta_sk->sk_v6_rcv_saddr; -+ struct in6_addr *dst = &meta_sk->sk_v6_daddr; -+ seq_printf(seq, " 1 %08X%08X%08X%08X:%04X %08X%08X%08X%08X:%04X", -+ src->s6_addr32[0], src->s6_addr32[1], -+ src->s6_addr32[2], src->s6_addr32[3], -+ ntohs(isk->inet_sport), -+ dst->s6_addr32[0], dst->s6_addr32[1], -+ dst->s6_addr32[2], dst->s6_addr32[3], -+ ntohs(isk->inet_dport)); -+#endif -+ } -+ seq_printf(seq, " %02X %02X %08X:%08X %lu", -+ meta_sk->sk_state, mpcb->cnt_subflows, -+ meta_tp->write_seq - meta_tp->snd_una, -+ max_t(int, meta_tp->rcv_nxt - -+ meta_tp->copied_seq, 0), -+ sock_i_ino(meta_sk)); -+ seq_putc(seq, '\n'); -+ } -+ -+ local_bh_enable(); -+ rcu_read_unlock(); -+ } -+ -+ return 0; -+} -+ -+static int mptcp_pm_seq_open(struct inode *inode, struct file *file) -+{ -+ return single_open_net(inode, file, mptcp_pm_seq_show); -+} -+ -+static const struct file_operations mptcp_pm_seq_fops = { -+ .owner = THIS_MODULE, -+ .open = mptcp_pm_seq_open, -+ .read = seq_read, -+ .llseek = seq_lseek, -+ .release = single_release_net, -+}; -+ -+static int mptcp_snmp_seq_show(struct seq_file *seq, void *v) -+{ -+ struct net *net = seq->private; -+ int i; -+ -+ for (i = 0; mptcp_snmp_list[i].name != NULL; i++) -+ seq_printf(seq, "%-32s\t%ld\n", mptcp_snmp_list[i].name, -+ snmp_fold_field(net->mptcp.mptcp_statistics, -+ mptcp_snmp_list[i].entry)); -+ -+ return 0; -+} -+ -+static int mptcp_snmp_seq_open(struct inode *inode, struct file *file) -+{ -+ return single_open_net(inode, file, mptcp_snmp_seq_show); -+} -+ -+static const struct file_operations mptcp_snmp_seq_fops = { -+ .owner = THIS_MODULE, -+ .open = mptcp_snmp_seq_open, -+ .read = seq_read, -+ .llseek = seq_lseek, -+ .release = single_release_net, -+}; -+ -+static int mptcp_pm_init_net(struct net *net) -+{ -+ net->mptcp.mptcp_statistics = alloc_percpu(struct mptcp_mib); -+ if (!net->mptcp.mptcp_statistics) -+ goto out_mptcp_mibs; -+ -+#ifdef CONFIG_PROC_FS -+ net->mptcp.proc_net_mptcp = proc_net_mkdir(net, "mptcp_net", net->proc_net); -+ if (!net->mptcp.proc_net_mptcp) -+ goto out_proc_net_mptcp; -+ if (!proc_create("mptcp", S_IRUGO, net->mptcp.proc_net_mptcp, -+ &mptcp_pm_seq_fops)) -+ goto out_mptcp_net_mptcp; -+ if (!proc_create("snmp", S_IRUGO, net->mptcp.proc_net_mptcp, -+ &mptcp_snmp_seq_fops)) -+ goto out_mptcp_net_snmp; -+#endif -+ -+ return 0; -+ -+#ifdef CONFIG_PROC_FS -+out_mptcp_net_snmp: -+ remove_proc_entry("mptcp", net->mptcp.proc_net_mptcp); -+out_mptcp_net_mptcp: -+ remove_proc_subtree("mptcp_net", net->proc_net); -+ net->mptcp.proc_net_mptcp = NULL; -+out_proc_net_mptcp: -+ free_percpu(net->mptcp.mptcp_statistics); -+#endif -+out_mptcp_mibs: -+ return -ENOMEM; -+} -+ -+static void mptcp_pm_exit_net(struct net *net) -+{ -+ remove_proc_entry("snmp", net->mptcp.proc_net_mptcp); -+ remove_proc_entry("mptcp", net->mptcp.proc_net_mptcp); -+ remove_proc_subtree("mptcp_net", net->proc_net); -+ free_percpu(net->mptcp.mptcp_statistics); -+} -+ -+static struct pernet_operations mptcp_pm_proc_ops = { -+ .init = mptcp_pm_init_net, -+ .exit = mptcp_pm_exit_net, -+}; -+ -+/* General initialization of mptcp */ -+void __init mptcp_init(void) -+{ -+ int i; -+ struct ctl_table_header *mptcp_sysctl; -+ -+ mptcp_sock_cache = kmem_cache_create("mptcp_sock", -+ sizeof(struct mptcp_tcp_sock), -+ 0, SLAB_HWCACHE_ALIGN, -+ NULL); -+ if (!mptcp_sock_cache) -+ goto mptcp_sock_cache_failed; -+ -+ mptcp_cb_cache = kmem_cache_create("mptcp_cb", sizeof(struct mptcp_cb), -+ 0, SLAB_DESTROY_BY_RCU|SLAB_HWCACHE_ALIGN, -+ NULL); -+ if (!mptcp_cb_cache) -+ goto mptcp_cb_cache_failed; -+ -+ mptcp_tw_cache = kmem_cache_create("mptcp_tw", sizeof(struct mptcp_tw), -+ 0, SLAB_DESTROY_BY_RCU|SLAB_HWCACHE_ALIGN, -+ NULL); -+ if (!mptcp_tw_cache) -+ goto mptcp_tw_cache_failed; -+ -+ get_random_bytes(mptcp_secret, sizeof(mptcp_secret)); -+ -+ mptcp_wq = alloc_workqueue("mptcp_wq", WQ_UNBOUND | WQ_MEM_RECLAIM, 8); -+ if (!mptcp_wq) -+ goto alloc_workqueue_failed; -+ -+ for (i = 0; i < MPTCP_HASH_SIZE; i++) { -+ INIT_HLIST_NULLS_HEAD(&tk_hashtable[i], i); -+ INIT_HLIST_NULLS_HEAD(&mptcp_reqsk_tk_htb[i], i); -+ } -+ -+ spin_lock_init(&mptcp_tk_hashlock); -+ -+ if (register_pernet_subsys(&mptcp_pm_proc_ops)) -+ goto pernet_failed; -+ -+#if IS_ENABLED(CONFIG_IPV6) -+ if (mptcp_pm_v6_init()) -+ goto mptcp_pm_v6_failed; -+#endif -+ if (mptcp_pm_v4_init()) -+ goto mptcp_pm_v4_failed; -+ -+ mptcp_sysctl = register_net_sysctl(&init_net, "net/mptcp", mptcp_table); -+ if (!mptcp_sysctl) -+ goto register_sysctl_failed; -+ -+ if (mptcp_register_path_manager(&mptcp_pm_default)) -+ goto register_pm_failed; -+ -+ if (mptcp_register_scheduler(&mptcp_sched_default)) -+ goto register_sched_failed; -+ -+ pr_info("MPTCP: Stable release v0.93.4"); -+ -+ mptcp_init_failed = false; -+ -+ return; -+ -+register_sched_failed: -+ mptcp_unregister_path_manager(&mptcp_pm_default); -+register_pm_failed: -+ unregister_net_sysctl_table(mptcp_sysctl); -+register_sysctl_failed: -+ mptcp_pm_v4_undo(); -+mptcp_pm_v4_failed: -+#if IS_ENABLED(CONFIG_IPV6) -+ mptcp_pm_v6_undo(); -+mptcp_pm_v6_failed: -+#endif -+ unregister_pernet_subsys(&mptcp_pm_proc_ops); -+pernet_failed: -+ destroy_workqueue(mptcp_wq); -+alloc_workqueue_failed: -+ kmem_cache_destroy(mptcp_tw_cache); -+mptcp_tw_cache_failed: -+ kmem_cache_destroy(mptcp_cb_cache); -+mptcp_cb_cache_failed: -+ kmem_cache_destroy(mptcp_sock_cache); -+mptcp_sock_cache_failed: -+ mptcp_init_failed = true; -+} -diff -aurN linux-4.9.162/net/mptcp/mptcp_fullmesh.c mptcp-mptcp_v0.93/net/mptcp/mptcp_fullmesh.c ---- linux-4.9.162/net/mptcp/mptcp_fullmesh.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_v0.93/net/mptcp/mptcp_fullmesh.c 2019-03-14 14:02:32.000000000 +0100 -@@ -0,0 +1,2013 @@ -+#include -+#include -+ -+#include -+#include -+ -+#if IS_ENABLED(CONFIG_IPV6) -+#include -+#include -+#endif -+ -+enum { -+ MPTCP_EVENT_ADD = 1, -+ MPTCP_EVENT_DEL, -+ MPTCP_EVENT_MOD, -+}; -+ -+#define MPTCP_SUBFLOW_RETRY_DELAY 1000 -+ -+/* Max number of local or remote addresses we can store. -+ * When changing, see the bitfield below in fullmesh_rem4/6. -+ */ -+#define MPTCP_MAX_ADDR 8 -+ -+struct fullmesh_rem4 { -+ u8 rem4_id; -+ u8 bitfield; -+ u8 retry_bitfield; -+ __be16 port; -+ struct in_addr addr; -+}; -+ -+struct fullmesh_rem6 { -+ u8 rem6_id; -+ u8 bitfield; -+ u8 retry_bitfield; -+ __be16 port; -+ struct in6_addr addr; -+}; -+ -+struct mptcp_loc_addr { -+ struct mptcp_loc4 locaddr4[MPTCP_MAX_ADDR]; -+ u8 loc4_bits; -+ u8 next_v4_index; -+ -+ struct mptcp_loc6 locaddr6[MPTCP_MAX_ADDR]; -+ u8 loc6_bits; -+ u8 next_v6_index; -+ struct rcu_head rcu; -+}; -+ -+struct mptcp_addr_event { -+ struct list_head list; -+ unsigned short family; -+ u8 code:7, -+ low_prio:1; -+ int if_idx; -+ union inet_addr addr; -+}; -+ -+struct fullmesh_priv { -+ /* Worker struct for subflow establishment */ -+ struct work_struct subflow_work; -+ /* Delayed worker, when the routing-tables are not yet ready. */ -+ struct delayed_work subflow_retry_work; -+ -+ /* Remote addresses */ -+ struct fullmesh_rem4 remaddr4[MPTCP_MAX_ADDR]; -+ struct fullmesh_rem6 remaddr6[MPTCP_MAX_ADDR]; -+ -+ struct mptcp_cb *mpcb; -+ -+ u16 remove_addrs; /* Addresses to remove */ -+ u8 announced_addrs_v4; /* IPv4 Addresses we did announce */ -+ u8 announced_addrs_v6; /* IPv6 Addresses we did announce */ -+ -+ u8 add_addr; /* Are we sending an add_addr? */ -+ -+ u8 rem4_bits; -+ u8 rem6_bits; -+ -+ /* Are we established the additional subflows for primary pair? */ -+ u8 first_pair:1; -+}; -+ -+struct mptcp_fm_ns { -+ struct mptcp_loc_addr __rcu *local; -+ spinlock_t local_lock; /* Protecting the above pointer */ -+ struct list_head events; -+ struct delayed_work address_worker; -+ -+ struct net *net; -+}; -+ -+static int num_subflows __read_mostly = 1; -+module_param(num_subflows, int, 0644); -+MODULE_PARM_DESC(num_subflows, "choose the number of subflows per pair of IP addresses of MPTCP connection"); -+ -+static int create_on_err __read_mostly; -+module_param(create_on_err, int, 0644); -+MODULE_PARM_DESC(create_on_err, "recreate the subflow upon a timeout"); -+ -+static struct mptcp_pm_ops full_mesh __read_mostly; -+ -+static void full_mesh_create_subflows(struct sock *meta_sk); -+ -+static struct mptcp_fm_ns *fm_get_ns(const struct net *net) -+{ -+ return (struct mptcp_fm_ns *)net->mptcp.path_managers[MPTCP_PM_FULLMESH]; -+} -+ -+static struct fullmesh_priv *fullmesh_get_priv(const struct mptcp_cb *mpcb) -+{ -+ return (struct fullmesh_priv *)&mpcb->mptcp_pm[0]; -+} -+ -+/* Find the first free index in the bitfield */ -+static int __mptcp_find_free_index(u8 bitfield, u8 base) -+{ -+ int i; -+ -+ /* There are anyways no free bits... */ -+ if (bitfield == 0xff) -+ goto exit; -+ -+ i = ffs(~(bitfield >> base)) - 1; -+ if (i < 0) -+ goto exit; -+ -+ /* No free bits when starting at base, try from 0 on */ -+ if (i + base >= sizeof(bitfield) * 8) -+ return __mptcp_find_free_index(bitfield, 0); -+ -+ return i + base; -+exit: -+ return -1; -+} -+ -+static int mptcp_find_free_index(u8 bitfield) -+{ -+ return __mptcp_find_free_index(bitfield, 0); -+} -+ -+static void mptcp_addv4_raddr(struct mptcp_cb *mpcb, -+ const struct in_addr *addr, -+ __be16 port, u8 id) -+{ -+ int i; -+ struct fullmesh_rem4 *rem4; -+ struct fullmesh_priv *fmp = fullmesh_get_priv(mpcb); -+ -+ mptcp_for_each_bit_set(fmp->rem4_bits, i) { -+ rem4 = &fmp->remaddr4[i]; -+ -+ /* Address is already in the list --- continue */ -+ if (rem4->rem4_id == id && -+ rem4->addr.s_addr == addr->s_addr && rem4->port == port) -+ return; -+ -+ /* This may be the case, when the peer is behind a NAT. He is -+ * trying to JOIN, thus sending the JOIN with a certain ID. -+ * However the src_addr of the IP-packet has been changed. We -+ * update the addr in the list, because this is the address as -+ * OUR BOX sees it. -+ */ -+ if (rem4->rem4_id == id && rem4->addr.s_addr != addr->s_addr) { -+ /* update the address */ -+ mptcp_debug("%s: updating old addr:%pI4 to addr %pI4 with id:%d\n", -+ __func__, &rem4->addr.s_addr, -+ &addr->s_addr, id); -+ rem4->addr.s_addr = addr->s_addr; -+ rem4->port = port; -+ mpcb->list_rcvd = 1; -+ return; -+ } -+ } -+ -+ i = mptcp_find_free_index(fmp->rem4_bits); -+ /* Do we have already the maximum number of local/remote addresses? */ -+ if (i < 0) { -+ mptcp_debug("%s: At max num of remote addresses: %d --- not adding address: %pI4\n", -+ __func__, MPTCP_MAX_ADDR, &addr->s_addr); -+ return; -+ } -+ -+ rem4 = &fmp->remaddr4[i]; -+ -+ /* Address is not known yet, store it */ -+ rem4->addr.s_addr = addr->s_addr; -+ rem4->port = port; -+ rem4->bitfield = 0; -+ rem4->retry_bitfield = 0; -+ rem4->rem4_id = id; -+ mpcb->list_rcvd = 1; -+ fmp->rem4_bits |= (1 << i); -+ -+ return; -+} -+ -+static void mptcp_addv6_raddr(struct mptcp_cb *mpcb, -+ const struct in6_addr *addr, -+ __be16 port, u8 id) -+{ -+ int i; -+ struct fullmesh_rem6 *rem6; -+ struct fullmesh_priv *fmp = fullmesh_get_priv(mpcb); -+ -+ mptcp_for_each_bit_set(fmp->rem6_bits, i) { -+ rem6 = &fmp->remaddr6[i]; -+ -+ /* Address is already in the list --- continue */ -+ if (rem6->rem6_id == id && -+ ipv6_addr_equal(&rem6->addr, addr) && rem6->port == port) -+ return; -+ -+ /* This may be the case, when the peer is behind a NAT. He is -+ * trying to JOIN, thus sending the JOIN with a certain ID. -+ * However the src_addr of the IP-packet has been changed. We -+ * update the addr in the list, because this is the address as -+ * OUR BOX sees it. -+ */ -+ if (rem6->rem6_id == id) { -+ /* update the address */ -+ mptcp_debug("%s: updating old addr: %pI6 to addr %pI6 with id:%d\n", -+ __func__, &rem6->addr, addr, id); -+ rem6->addr = *addr; -+ rem6->port = port; -+ mpcb->list_rcvd = 1; -+ return; -+ } -+ } -+ -+ i = mptcp_find_free_index(fmp->rem6_bits); -+ /* Do we have already the maximum number of local/remote addresses? */ -+ if (i < 0) { -+ mptcp_debug("%s: At max num of remote addresses: %d --- not adding address: %pI6\n", -+ __func__, MPTCP_MAX_ADDR, addr); -+ return; -+ } -+ -+ rem6 = &fmp->remaddr6[i]; -+ -+ /* Address is not known yet, store it */ -+ rem6->addr = *addr; -+ rem6->port = port; -+ rem6->bitfield = 0; -+ rem6->retry_bitfield = 0; -+ rem6->rem6_id = id; -+ mpcb->list_rcvd = 1; -+ fmp->rem6_bits |= (1 << i); -+ -+ return; -+} -+ -+static void mptcp_v4_rem_raddress(struct mptcp_cb *mpcb, u8 id) -+{ -+ int i; -+ struct fullmesh_priv *fmp = fullmesh_get_priv(mpcb); -+ -+ mptcp_for_each_bit_set(fmp->rem4_bits, i) { -+ if (fmp->remaddr4[i].rem4_id == id) { -+ /* remove address from bitfield */ -+ fmp->rem4_bits &= ~(1 << i); -+ -+ break; -+ } -+ } -+} -+ -+static void mptcp_v6_rem_raddress(const struct mptcp_cb *mpcb, u8 id) -+{ -+ int i; -+ struct fullmesh_priv *fmp = fullmesh_get_priv(mpcb); -+ -+ mptcp_for_each_bit_set(fmp->rem6_bits, i) { -+ if (fmp->remaddr6[i].rem6_id == id) { -+ /* remove address from bitfield */ -+ fmp->rem6_bits &= ~(1 << i); -+ -+ break; -+ } -+ } -+} -+ -+/* Sets the bitfield of the remote-address field */ -+static void mptcp_v4_set_init_addr_bit(const struct mptcp_cb *mpcb, -+ const struct in_addr *addr, u8 index) -+{ -+ int i; -+ struct fullmesh_priv *fmp = fullmesh_get_priv(mpcb); -+ -+ mptcp_for_each_bit_set(fmp->rem4_bits, i) { -+ if (fmp->remaddr4[i].addr.s_addr == addr->s_addr) { -+ fmp->remaddr4[i].bitfield |= (1 << index); -+ return; -+ } -+ } -+} -+ -+/* Sets the bitfield of the remote-address field */ -+static void mptcp_v6_set_init_addr_bit(struct mptcp_cb *mpcb, -+ const struct in6_addr *addr, u8 index) -+{ -+ int i; -+ struct fullmesh_priv *fmp = fullmesh_get_priv(mpcb); -+ -+ mptcp_for_each_bit_set(fmp->rem6_bits, i) { -+ if (ipv6_addr_equal(&fmp->remaddr6[i].addr, addr)) { -+ fmp->remaddr6[i].bitfield |= (1 << index); -+ return; -+ } -+ } -+} -+ -+static void mptcp_set_init_addr_bit(struct mptcp_cb *mpcb, -+ const union inet_addr *addr, -+ sa_family_t family, u8 id) -+{ -+ if (family == AF_INET) -+ mptcp_v4_set_init_addr_bit(mpcb, &addr->in, id); -+ else -+ mptcp_v6_set_init_addr_bit(mpcb, &addr->in6, id); -+} -+ -+static void mptcp_v4_subflows(struct sock *meta_sk, -+ const struct mptcp_loc4 *loc, -+ struct mptcp_rem4 *rem) -+{ -+ int i; -+ -+ for (i = 1; i < num_subflows; i++) -+ mptcp_init4_subsockets(meta_sk, loc, rem); -+} -+ -+#if IS_ENABLED(CONFIG_IPV6) -+static void mptcp_v6_subflows(struct sock *meta_sk, -+ const struct mptcp_loc6 *loc, -+ struct mptcp_rem6 *rem) -+{ -+ int i; -+ -+ for (i = 1; i < num_subflows; i++) -+ mptcp_init6_subsockets(meta_sk, loc, rem); -+} -+#endif -+ -+static void retry_subflow_worker(struct work_struct *work) -+{ -+ struct delayed_work *delayed_work = container_of(work, -+ struct delayed_work, -+ work); -+ struct fullmesh_priv *fmp = container_of(delayed_work, -+ struct fullmesh_priv, -+ subflow_retry_work); -+ struct mptcp_cb *mpcb = fmp->mpcb; -+ struct sock *meta_sk = mpcb->meta_sk; -+ struct mptcp_loc_addr *mptcp_local; -+ struct mptcp_fm_ns *fm_ns = fm_get_ns(sock_net(meta_sk)); -+ int iter = 0, i; -+ -+ /* We need a local (stable) copy of the address-list. Really, it is not -+ * such a big deal, if the address-list is not 100% up-to-date. -+ */ -+ rcu_read_lock_bh(); -+ mptcp_local = rcu_dereference_bh(fm_ns->local); -+ mptcp_local = kmemdup(mptcp_local, sizeof(*mptcp_local), GFP_ATOMIC); -+ rcu_read_unlock_bh(); -+ -+ if (!mptcp_local) -+ return; -+ -+next_subflow: -+ if (iter) { -+ release_sock(meta_sk); -+ mutex_unlock(&mpcb->mpcb_mutex); -+ -+ cond_resched(); -+ } -+ mutex_lock(&mpcb->mpcb_mutex); -+ lock_sock_nested(meta_sk, SINGLE_DEPTH_NESTING); -+ -+ iter++; -+ -+ if (sock_flag(meta_sk, SOCK_DEAD)) -+ goto exit; -+ -+ mptcp_for_each_bit_set(fmp->rem4_bits, i) { -+ struct fullmesh_rem4 *rem = &fmp->remaddr4[i]; -+ /* Do we need to retry establishing a subflow ? */ -+ if (rem->retry_bitfield) { -+ int i = mptcp_find_free_index(~rem->retry_bitfield); -+ struct mptcp_rem4 rem4; -+ -+ rem->bitfield |= (1 << i); -+ rem->retry_bitfield &= ~(1 << i); -+ -+ rem4.addr = rem->addr; -+ rem4.port = rem->port; -+ rem4.rem4_id = rem->rem4_id; -+ -+ mptcp_init4_subsockets(meta_sk, &mptcp_local->locaddr4[i], &rem4); -+ mptcp_v4_subflows(meta_sk, -+ &mptcp_local->locaddr4[i], -+ &rem4); -+ goto next_subflow; -+ } -+ } -+ -+#if IS_ENABLED(CONFIG_IPV6) -+ mptcp_for_each_bit_set(fmp->rem6_bits, i) { -+ struct fullmesh_rem6 *rem = &fmp->remaddr6[i]; -+ -+ /* Do we need to retry establishing a subflow ? */ -+ if (rem->retry_bitfield) { -+ int i = mptcp_find_free_index(~rem->retry_bitfield); -+ struct mptcp_rem6 rem6; -+ -+ rem->bitfield |= (1 << i); -+ rem->retry_bitfield &= ~(1 << i); -+ -+ rem6.addr = rem->addr; -+ rem6.port = rem->port; -+ rem6.rem6_id = rem->rem6_id; -+ -+ mptcp_init6_subsockets(meta_sk, &mptcp_local->locaddr6[i], &rem6); -+ mptcp_v6_subflows(meta_sk, -+ &mptcp_local->locaddr6[i], -+ &rem6); -+ goto next_subflow; -+ } -+ } -+#endif -+ -+exit: -+ kfree(mptcp_local); -+ release_sock(meta_sk); -+ mutex_unlock(&mpcb->mpcb_mutex); -+ sock_put(meta_sk); -+} -+ -+/** -+ * Create all new subflows, by doing calls to mptcp_initX_subsockets -+ * -+ * This function uses a goto next_subflow, to allow releasing the lock between -+ * new subflows and giving other processes a chance to do some work on the -+ * socket and potentially finishing the communication. -+ **/ -+static void create_subflow_worker(struct work_struct *work) -+{ -+ struct fullmesh_priv *fmp = container_of(work, struct fullmesh_priv, -+ subflow_work); -+ struct mptcp_cb *mpcb = fmp->mpcb; -+ struct sock *meta_sk = mpcb->meta_sk; -+ struct mptcp_loc_addr *mptcp_local; -+ const struct mptcp_fm_ns *fm_ns = fm_get_ns(sock_net(meta_sk)); -+ int iter = 0, retry = 0; -+ int i; -+ -+ /* We need a local (stable) copy of the address-list. Really, it is not -+ * such a big deal, if the address-list is not 100% up-to-date. -+ */ -+ rcu_read_lock_bh(); -+ mptcp_local = rcu_dereference_bh(fm_ns->local); -+ mptcp_local = kmemdup(mptcp_local, sizeof(*mptcp_local), GFP_ATOMIC); -+ rcu_read_unlock_bh(); -+ -+ if (!mptcp_local) -+ return; -+ -+next_subflow: -+ if (iter) { -+ release_sock(meta_sk); -+ mutex_unlock(&mpcb->mpcb_mutex); -+ -+ cond_resched(); -+ } -+ mutex_lock(&mpcb->mpcb_mutex); -+ lock_sock_nested(meta_sk, SINGLE_DEPTH_NESTING); -+ -+ if (sock_flag(meta_sk, SOCK_DEAD)) -+ goto exit; -+ -+ if (mpcb->master_sk && -+ !tcp_sk(mpcb->master_sk)->mptcp->fully_established) -+ goto exit; -+ -+ /* Create the additional subflows for the first pair */ -+ if (fmp->first_pair == 0 && mpcb->master_sk) { -+ struct mptcp_loc4 loc; -+ struct mptcp_rem4 rem; -+ -+ loc.addr.s_addr = inet_sk(meta_sk)->inet_saddr; -+ loc.loc4_id = 0; -+ loc.low_prio = 0; -+ loc.if_idx = mpcb->master_sk->sk_bound_dev_if; -+ -+ rem.addr.s_addr = inet_sk(meta_sk)->inet_daddr; -+ rem.port = inet_sk(meta_sk)->inet_dport; -+ rem.rem4_id = 0; /* Default 0 */ -+ -+ mptcp_v4_subflows(meta_sk, &loc, &rem); -+ -+ fmp->first_pair = 1; -+ } -+ iter++; -+ -+ mptcp_for_each_bit_set(fmp->rem4_bits, i) { -+ struct fullmesh_rem4 *rem; -+ u8 remaining_bits; -+ -+ rem = &fmp->remaddr4[i]; -+ remaining_bits = ~(rem->bitfield) & mptcp_local->loc4_bits; -+ -+ /* Are there still combinations to handle? */ -+ if (remaining_bits) { -+ int i = mptcp_find_free_index(~remaining_bits); -+ struct mptcp_rem4 rem4; -+ -+ rem->bitfield |= (1 << i); -+ -+ rem4.addr = rem->addr; -+ rem4.port = rem->port; -+ rem4.rem4_id = rem->rem4_id; -+ -+ /* If a route is not yet available then retry once */ -+ if (mptcp_init4_subsockets(meta_sk, &mptcp_local->locaddr4[i], -+ &rem4) == -ENETUNREACH) -+ retry = rem->retry_bitfield |= (1 << i); -+ else -+ mptcp_v4_subflows(meta_sk, -+ &mptcp_local->locaddr4[i], -+ &rem4); -+ goto next_subflow; -+ } -+ } -+ -+#if IS_ENABLED(CONFIG_IPV6) -+ if (fmp->first_pair == 0 && mpcb->master_sk) { -+ struct mptcp_loc6 loc; -+ struct mptcp_rem6 rem; -+ -+ loc.addr = inet6_sk(meta_sk)->saddr; -+ loc.loc6_id = 0; -+ loc.low_prio = 0; -+ loc.if_idx = mpcb->master_sk->sk_bound_dev_if; -+ -+ rem.addr = meta_sk->sk_v6_daddr; -+ rem.port = inet_sk(meta_sk)->inet_dport; -+ rem.rem6_id = 0; /* Default 0 */ -+ -+ mptcp_v6_subflows(meta_sk, &loc, &rem); -+ -+ fmp->first_pair = 1; -+ } -+ mptcp_for_each_bit_set(fmp->rem6_bits, i) { -+ struct fullmesh_rem6 *rem; -+ u8 remaining_bits; -+ -+ rem = &fmp->remaddr6[i]; -+ remaining_bits = ~(rem->bitfield) & mptcp_local->loc6_bits; -+ -+ /* Are there still combinations to handle? */ -+ if (remaining_bits) { -+ int i = mptcp_find_free_index(~remaining_bits); -+ struct mptcp_rem6 rem6; -+ -+ rem->bitfield |= (1 << i); -+ -+ rem6.addr = rem->addr; -+ rem6.port = rem->port; -+ rem6.rem6_id = rem->rem6_id; -+ -+ /* If a route is not yet available then retry once */ -+ if (mptcp_init6_subsockets(meta_sk, &mptcp_local->locaddr6[i], -+ &rem6) == -ENETUNREACH) -+ retry = rem->retry_bitfield |= (1 << i); -+ else -+ mptcp_v6_subflows(meta_sk, -+ &mptcp_local->locaddr6[i], -+ &rem6); -+ goto next_subflow; -+ } -+ } -+#endif -+ -+ if (retry && !delayed_work_pending(&fmp->subflow_retry_work)) { -+ sock_hold(meta_sk); -+ queue_delayed_work(mptcp_wq, &fmp->subflow_retry_work, -+ msecs_to_jiffies(MPTCP_SUBFLOW_RETRY_DELAY)); -+ } -+ -+exit: -+ kfree(mptcp_local); -+ release_sock(meta_sk); -+ mutex_unlock(&mpcb->mpcb_mutex); -+ sock_put(meta_sk); -+} -+ -+static void announce_remove_addr(u8 addr_id, struct sock *meta_sk) -+{ -+ struct mptcp_cb *mpcb = tcp_sk(meta_sk)->mpcb; -+ struct fullmesh_priv *fmp = fullmesh_get_priv(mpcb); -+ struct sock *sk = mptcp_select_ack_sock(meta_sk); -+ -+ fmp->remove_addrs |= (1 << addr_id); -+ mpcb->addr_signal = 1; -+ -+ if (sk) -+ tcp_send_ack(sk); -+} -+ -+static void update_addr_bitfields(struct sock *meta_sk, -+ const struct mptcp_loc_addr *mptcp_local) -+{ -+ struct mptcp_cb *mpcb = tcp_sk(meta_sk)->mpcb; -+ struct fullmesh_priv *fmp = fullmesh_get_priv(mpcb); -+ int i; -+ -+ /* The bits in announced_addrs_* always match with loc*_bits. So, a -+ * simple & operation unsets the correct bits, because these go from -+ * announced to non-announced -+ */ -+ fmp->announced_addrs_v4 &= mptcp_local->loc4_bits; -+ -+ mptcp_for_each_bit_set(fmp->rem4_bits, i) { -+ fmp->remaddr4[i].bitfield &= mptcp_local->loc4_bits; -+ fmp->remaddr4[i].retry_bitfield &= mptcp_local->loc4_bits; -+ } -+ -+ fmp->announced_addrs_v6 &= mptcp_local->loc6_bits; -+ -+ mptcp_for_each_bit_set(fmp->rem6_bits, i) { -+ fmp->remaddr6[i].bitfield &= mptcp_local->loc6_bits; -+ fmp->remaddr6[i].retry_bitfield &= mptcp_local->loc6_bits; -+ } -+} -+ -+static int mptcp_find_address(const struct mptcp_loc_addr *mptcp_local, -+ sa_family_t family, const union inet_addr *addr, -+ int if_idx) -+{ -+ int i; -+ u8 loc_bits; -+ bool found = false; -+ -+ if (family == AF_INET) -+ loc_bits = mptcp_local->loc4_bits; -+ else -+ loc_bits = mptcp_local->loc6_bits; -+ -+ mptcp_for_each_bit_set(loc_bits, i) { -+ if (family == AF_INET && -+ (!if_idx || mptcp_local->locaddr4[i].if_idx == if_idx) && -+ mptcp_local->locaddr4[i].addr.s_addr == addr->in.s_addr) { -+ found = true; -+ break; -+ } -+ if (family == AF_INET6 && -+ (!if_idx || mptcp_local->locaddr6[i].if_idx == if_idx) && -+ ipv6_addr_equal(&mptcp_local->locaddr6[i].addr, -+ &addr->in6)) { -+ found = true; -+ break; -+ } -+ } -+ -+ if (!found) -+ return -1; -+ -+ return i; -+} -+ -+static int mptcp_find_address_transp(const struct mptcp_loc_addr *mptcp_local, -+ sa_family_t family, int if_idx) -+{ -+ bool found = false; -+ u8 loc_bits; -+ int i; -+ -+ if (family == AF_INET) -+ loc_bits = mptcp_local->loc4_bits; -+ else -+ loc_bits = mptcp_local->loc6_bits; -+ -+ mptcp_for_each_bit_set(loc_bits, i) { -+ if (family == AF_INET && -+ (!if_idx || mptcp_local->locaddr4[i].if_idx == if_idx)) { -+ found = true; -+ break; -+ } -+ if (family == AF_INET6 && -+ (!if_idx || mptcp_local->locaddr6[i].if_idx == if_idx)) { -+ found = true; -+ break; -+ } -+ } -+ -+ if (!found) -+ return -1; -+ -+ return i; -+} -+ -+static void mptcp_address_worker(struct work_struct *work) -+{ -+ const struct delayed_work *delayed_work = container_of(work, -+ struct delayed_work, -+ work); -+ struct mptcp_fm_ns *fm_ns = container_of(delayed_work, -+ struct mptcp_fm_ns, -+ address_worker); -+ struct net *net = fm_ns->net; -+ struct mptcp_addr_event *event = NULL; -+ struct mptcp_loc_addr *mptcp_local, *old; -+ int i, id = -1; /* id is used in the socket-code on a delete-event */ -+ bool success; /* Used to indicate if we succeeded handling the event */ -+ -+next_event: -+ success = false; -+ kfree(event); -+ -+ /* First, let's dequeue an event from our event-list */ -+ rcu_read_lock_bh(); -+ spin_lock(&fm_ns->local_lock); -+ -+ event = list_first_entry_or_null(&fm_ns->events, -+ struct mptcp_addr_event, list); -+ if (!event) { -+ spin_unlock(&fm_ns->local_lock); -+ rcu_read_unlock_bh(); -+ return; -+ } -+ -+ list_del(&event->list); -+ -+ mptcp_local = rcu_dereference_bh(fm_ns->local); -+ -+ if (event->code == MPTCP_EVENT_DEL) { -+ id = mptcp_find_address(mptcp_local, event->family, -+ &event->addr, event->if_idx); -+ -+ /* Not in the list - so we don't care */ -+ if (id < 0) { -+ mptcp_debug("%s could not find id\n", __func__); -+ goto duno; -+ } -+ -+ old = mptcp_local; -+ mptcp_local = kmemdup(mptcp_local, sizeof(*mptcp_local), -+ GFP_ATOMIC); -+ if (!mptcp_local) -+ goto duno; -+ -+ if (event->family == AF_INET) -+ mptcp_local->loc4_bits &= ~(1 << id); -+ else -+ mptcp_local->loc6_bits &= ~(1 << id); -+ -+ rcu_assign_pointer(fm_ns->local, mptcp_local); -+ kfree_rcu(old, rcu); -+ } else { -+ int i = mptcp_find_address(mptcp_local, event->family, -+ &event->addr, event->if_idx); -+ int j = i; -+ -+ if (j < 0) { -+ /* Not in the list, so we have to find an empty slot */ -+ if (event->family == AF_INET) -+ i = __mptcp_find_free_index(mptcp_local->loc4_bits, -+ mptcp_local->next_v4_index); -+ if (event->family == AF_INET6) -+ i = __mptcp_find_free_index(mptcp_local->loc6_bits, -+ mptcp_local->next_v6_index); -+ -+ if (i < 0) { -+ mptcp_debug("%s no more space\n", __func__); -+ goto duno; -+ } -+ -+ /* It might have been a MOD-event. */ -+ event->code = MPTCP_EVENT_ADD; -+ } else { -+ /* Let's check if anything changes */ -+ if (event->family == AF_INET && -+ event->low_prio == mptcp_local->locaddr4[i].low_prio) -+ goto duno; -+ -+ if (event->family == AF_INET6 && -+ event->low_prio == mptcp_local->locaddr6[i].low_prio) -+ goto duno; -+ } -+ -+ old = mptcp_local; -+ mptcp_local = kmemdup(mptcp_local, sizeof(*mptcp_local), -+ GFP_ATOMIC); -+ if (!mptcp_local) -+ goto duno; -+ -+ if (event->family == AF_INET) { -+ mptcp_local->locaddr4[i].addr.s_addr = event->addr.in.s_addr; -+ mptcp_local->locaddr4[i].loc4_id = i + 1; -+ mptcp_local->locaddr4[i].low_prio = event->low_prio; -+ mptcp_local->locaddr4[i].if_idx = event->if_idx; -+ -+ mptcp_debug("%s updated IP %pI4 on ifidx %u prio %u id %u\n", -+ __func__, &event->addr.in.s_addr, -+ event->if_idx, event->low_prio, i + 1); -+ } else { -+ mptcp_local->locaddr6[i].addr = event->addr.in6; -+ mptcp_local->locaddr6[i].loc6_id = i + MPTCP_MAX_ADDR; -+ mptcp_local->locaddr6[i].low_prio = event->low_prio; -+ mptcp_local->locaddr6[i].if_idx = event->if_idx; -+ -+ mptcp_debug("%s updated IP %pI6 on ifidx %u prio %u id %u\n", -+ __func__, &event->addr.in6, -+ event->if_idx, event->low_prio, i + MPTCP_MAX_ADDR); -+ } -+ -+ if (j < 0) { -+ if (event->family == AF_INET) { -+ mptcp_local->loc4_bits |= (1 << i); -+ mptcp_local->next_v4_index = i + 1; -+ } else { -+ mptcp_local->loc6_bits |= (1 << i); -+ mptcp_local->next_v6_index = i + 1; -+ } -+ } -+ -+ rcu_assign_pointer(fm_ns->local, mptcp_local); -+ kfree_rcu(old, rcu); -+ } -+ success = true; -+ -+duno: -+ spin_unlock(&fm_ns->local_lock); -+ rcu_read_unlock_bh(); -+ -+ if (!success) -+ goto next_event; -+ -+ /* Now we iterate over the MPTCP-sockets and apply the event. */ -+ for (i = 0; i < MPTCP_HASH_SIZE; i++) { -+ const struct hlist_nulls_node *node; -+ struct tcp_sock *meta_tp; -+ -+ rcu_read_lock_bh(); -+ hlist_nulls_for_each_entry_rcu(meta_tp, node, &tk_hashtable[i], -+ tk_table) { -+ struct sock *meta_sk = (struct sock *)meta_tp, *sk; -+ bool meta_v4 = meta_sk->sk_family == AF_INET; -+ struct mptcp_cb *mpcb; -+ -+ if (sock_net(meta_sk) != net) -+ continue; -+ -+ if (meta_v4) { -+ /* skip IPv6 events if meta is IPv4 */ -+ if (event->family == AF_INET6) -+ continue; -+ } else if (event->family == AF_INET && meta_sk->sk_ipv6only) { -+ /* skip IPv4 events if IPV6_V6ONLY is set */ -+ continue; -+ } -+ -+ if (unlikely(!atomic_inc_not_zero(&meta_sk->sk_refcnt))) -+ continue; -+ -+ bh_lock_sock(meta_sk); -+ -+ mpcb = meta_tp->mpcb; -+ if (!mpcb) -+ goto next; -+ -+ if (!mptcp(meta_tp) || !is_meta_sk(meta_sk) || -+ mpcb->infinite_mapping_snd || -+ mpcb->infinite_mapping_rcv || -+ mpcb->send_infinite_mapping) -+ goto next; -+ -+ /* May be that the pm has changed in-between */ -+ if (mpcb->pm_ops != &full_mesh) -+ goto next; -+ -+ if (sock_owned_by_user(meta_sk)) { -+ if (!test_and_set_bit(MPTCP_PATH_MANAGER_DEFERRED, -+ &meta_tp->tsq_flags)) -+ sock_hold(meta_sk); -+ -+ goto next; -+ } -+ -+ if (event->code == MPTCP_EVENT_ADD) { -+ struct fullmesh_priv *fmp = fullmesh_get_priv(mpcb); -+ -+ fmp->add_addr++; -+ mpcb->addr_signal = 1; -+ -+ sk = mptcp_select_ack_sock(meta_sk); -+ if (sk) -+ tcp_send_ack(sk); -+ -+ full_mesh_create_subflows(meta_sk); -+ } -+ -+ if (event->code == MPTCP_EVENT_DEL) { -+ struct sock *sk, *tmpsk; -+ struct mptcp_loc_addr *mptcp_local; -+ bool found = false; -+ -+ mptcp_local = rcu_dereference_bh(fm_ns->local); -+ -+ /* In any case, we need to update our bitfields */ -+ if (id >= 0) -+ update_addr_bitfields(meta_sk, mptcp_local); -+ -+ /* Look for the socket and remove him */ -+ mptcp_for_each_sk_safe(mpcb, sk, tmpsk) { -+ if ((event->family == AF_INET6 && -+ (sk->sk_family == AF_INET || -+ mptcp_v6_is_v4_mapped(sk))) || -+ (event->family == AF_INET && -+ (sk->sk_family == AF_INET6 && -+ !mptcp_v6_is_v4_mapped(sk)))) -+ continue; -+ -+ if (event->family == AF_INET && -+ (sk->sk_family == AF_INET || -+ mptcp_v6_is_v4_mapped(sk)) && -+ inet_sk(sk)->inet_saddr != event->addr.in.s_addr) -+ continue; -+ -+ if (event->family == AF_INET6 && -+ sk->sk_family == AF_INET6 && -+ !ipv6_addr_equal(&inet6_sk(sk)->saddr, &event->addr.in6)) -+ continue; -+ -+ /* Reinject, so that pf = 1 and so we -+ * won't select this one as the -+ * ack-sock. -+ */ -+ mptcp_reinject_data(sk, 0); -+ -+ /* We announce the removal of this id */ -+ announce_remove_addr(tcp_sk(sk)->mptcp->loc_id, meta_sk); -+ -+ mptcp_sub_force_close(sk); -+ found = true; -+ } -+ -+ if (found) -+ goto next; -+ -+ /* The id may have been given by the event, -+ * matching on a local address. And it may not -+ * have matched on one of the above sockets, -+ * because the client never created a subflow. -+ * So, we have to finally remove it here. -+ */ -+ if (id >= 0) { -+ u8 loc_id = id -+ + (event->family == AF_INET ? 1 : MPTCP_MAX_ADDR); -+ announce_remove_addr(loc_id, meta_sk); -+ } -+ } -+ -+ if (event->code == MPTCP_EVENT_MOD) { -+ struct sock *sk; -+ -+ mptcp_for_each_sk(mpcb, sk) { -+ struct tcp_sock *tp = tcp_sk(sk); -+ if (event->family == AF_INET && -+ (sk->sk_family == AF_INET || -+ mptcp_v6_is_v4_mapped(sk)) && -+ inet_sk(sk)->inet_saddr == event->addr.in.s_addr) { -+ if (event->low_prio != tp->mptcp->low_prio) { -+ tp->mptcp->send_mp_prio = 1; -+ tp->mptcp->low_prio = event->low_prio; -+ -+ tcp_send_ack(sk); -+ } -+ } -+ -+ if (event->family == AF_INET6 && -+ sk->sk_family == AF_INET6 && -+ !ipv6_addr_equal(&inet6_sk(sk)->saddr, &event->addr.in6)) { -+ if (event->low_prio != tp->mptcp->low_prio) { -+ tp->mptcp->send_mp_prio = 1; -+ tp->mptcp->low_prio = event->low_prio; -+ -+ tcp_send_ack(sk); -+ } -+ } -+ } -+ } -+next: -+ bh_unlock_sock(meta_sk); -+ sock_put(meta_sk); -+ } -+ rcu_read_unlock_bh(); -+ } -+ goto next_event; -+} -+ -+static struct mptcp_addr_event *lookup_similar_event(const struct net *net, -+ const struct mptcp_addr_event *event) -+{ -+ struct mptcp_addr_event *eventq; -+ struct mptcp_fm_ns *fm_ns = fm_get_ns(net); -+ -+ list_for_each_entry(eventq, &fm_ns->events, list) { -+ if (eventq->family != event->family) -+ continue; -+ if (eventq->if_idx != event->if_idx) -+ continue; -+ if (event->family == AF_INET) { -+ if (eventq->addr.in.s_addr == event->addr.in.s_addr) -+ return eventq; -+ } else { -+ if (ipv6_addr_equal(&eventq->addr.in6, &event->addr.in6)) -+ return eventq; -+ } -+ } -+ return NULL; -+} -+ -+/* We already hold the net-namespace MPTCP-lock */ -+static void add_pm_event(struct net *net, const struct mptcp_addr_event *event) -+{ -+ struct mptcp_addr_event *eventq = lookup_similar_event(net, event); -+ struct mptcp_fm_ns *fm_ns = fm_get_ns(net); -+ -+ if (eventq) { -+ switch (event->code) { -+ case MPTCP_EVENT_DEL: -+ mptcp_debug("%s del old_code %u\n", __func__, eventq->code); -+ list_del(&eventq->list); -+ kfree(eventq); -+ break; -+ case MPTCP_EVENT_ADD: -+ mptcp_debug("%s add old_code %u\n", __func__, eventq->code); -+ eventq->low_prio = event->low_prio; -+ eventq->code = MPTCP_EVENT_ADD; -+ return; -+ case MPTCP_EVENT_MOD: -+ mptcp_debug("%s mod old_code %u\n", __func__, eventq->code); -+ eventq->low_prio = event->low_prio; -+ eventq->code = MPTCP_EVENT_MOD; -+ return; -+ } -+ } -+ -+ /* OK, we have to add the new address to the wait queue */ -+ eventq = kmemdup(event, sizeof(struct mptcp_addr_event), GFP_ATOMIC); -+ if (!eventq) -+ return; -+ -+ list_add_tail(&eventq->list, &fm_ns->events); -+ -+ /* Create work-queue */ -+ if (!delayed_work_pending(&fm_ns->address_worker)) -+ queue_delayed_work(mptcp_wq, &fm_ns->address_worker, -+ msecs_to_jiffies(500)); -+} -+ -+static void addr4_event_handler(const struct in_ifaddr *ifa, unsigned long event, -+ struct net *net) -+{ -+ const struct net_device *netdev = ifa->ifa_dev->dev; -+ struct mptcp_fm_ns *fm_ns = fm_get_ns(net); -+ struct mptcp_addr_event mpevent; -+ -+ if (ifa->ifa_scope > RT_SCOPE_LINK || -+ ipv4_is_loopback(ifa->ifa_local)) -+ return; -+ -+ spin_lock_bh(&fm_ns->local_lock); -+ -+ mpevent.family = AF_INET; -+ mpevent.addr.in.s_addr = ifa->ifa_local; -+ mpevent.low_prio = (netdev->flags & IFF_MPBACKUP) ? 1 : 0; -+ mpevent.if_idx = netdev->ifindex; -+ -+ if (event == NETDEV_DOWN || !netif_running(netdev) || -+ (netdev->flags & IFF_NOMULTIPATH) || !(netdev->flags & IFF_UP)) -+ mpevent.code = MPTCP_EVENT_DEL; -+ else if (event == NETDEV_UP) -+ mpevent.code = MPTCP_EVENT_ADD; -+ else if (event == NETDEV_CHANGE) -+ mpevent.code = MPTCP_EVENT_MOD; -+ -+ mptcp_debug("%s created event for %pI4, code %u prio %u idx %u\n", __func__, -+ &ifa->ifa_local, mpevent.code, mpevent.low_prio, mpevent.if_idx); -+ add_pm_event(net, &mpevent); -+ -+ spin_unlock_bh(&fm_ns->local_lock); -+ return; -+} -+ -+/* React on IPv4-addr add/rem-events */ -+static int mptcp_pm_inetaddr_event(struct notifier_block *this, -+ unsigned long event, void *ptr) -+{ -+ const struct in_ifaddr *ifa = (struct in_ifaddr *)ptr; -+ struct net *net = dev_net(ifa->ifa_dev->dev); -+ -+ if (!(event == NETDEV_UP || event == NETDEV_DOWN || -+ event == NETDEV_CHANGE)) -+ return NOTIFY_DONE; -+ -+ addr4_event_handler(ifa, event, net); -+ -+ return NOTIFY_DONE; -+} -+ -+static struct notifier_block mptcp_pm_inetaddr_notifier = { -+ .notifier_call = mptcp_pm_inetaddr_event, -+}; -+ -+#if IS_ENABLED(CONFIG_IPV6) -+ -+/* IPV6-related address/interface watchers */ -+struct mptcp_dad_data { -+ struct timer_list timer; -+ struct inet6_ifaddr *ifa; -+}; -+ -+static void dad_callback(unsigned long arg); -+static int inet6_addr_event(struct notifier_block *this, -+ unsigned long event, void *ptr); -+ -+static bool ipv6_dad_finished(const struct inet6_ifaddr *ifa) -+{ -+ return !(ifa->flags & IFA_F_TENTATIVE) || -+ ifa->state > INET6_IFADDR_STATE_DAD; -+} -+ -+static void dad_init_timer(struct mptcp_dad_data *data, -+ struct inet6_ifaddr *ifa) -+{ -+ data->ifa = ifa; -+ data->timer.data = (unsigned long)data; -+ data->timer.function = dad_callback; -+ if (ifa->idev->cnf.rtr_solicit_delay) -+ data->timer.expires = jiffies + ifa->idev->cnf.rtr_solicit_delay; -+ else -+ data->timer.expires = jiffies + (HZ/10); -+} -+ -+static void dad_callback(unsigned long arg) -+{ -+ struct mptcp_dad_data *data = (struct mptcp_dad_data *)arg; -+ -+ /* DAD failed or IP brought down? */ -+ if (data->ifa->state == INET6_IFADDR_STATE_ERRDAD || -+ data->ifa->state == INET6_IFADDR_STATE_DEAD) -+ goto exit; -+ -+ if (!ipv6_dad_finished(data->ifa)) { -+ dad_init_timer(data, data->ifa); -+ add_timer(&data->timer); -+ return; -+ } -+ -+ inet6_addr_event(NULL, NETDEV_UP, data->ifa); -+ -+exit: -+ in6_ifa_put(data->ifa); -+ kfree(data); -+} -+ -+static inline void dad_setup_timer(struct inet6_ifaddr *ifa) -+{ -+ struct mptcp_dad_data *data; -+ -+ data = kmalloc(sizeof(*data), GFP_ATOMIC); -+ -+ if (!data) -+ return; -+ -+ init_timer(&data->timer); -+ dad_init_timer(data, ifa); -+ add_timer(&data->timer); -+ in6_ifa_hold(ifa); -+} -+ -+static void addr6_event_handler(const struct inet6_ifaddr *ifa, unsigned long event, -+ struct net *net) -+{ -+ const struct net_device *netdev = ifa->idev->dev; -+ int addr_type = ipv6_addr_type(&ifa->addr); -+ struct mptcp_fm_ns *fm_ns = fm_get_ns(net); -+ struct mptcp_addr_event mpevent; -+ -+ if (ifa->scope > RT_SCOPE_LINK || -+ addr_type == IPV6_ADDR_ANY || -+ (addr_type & IPV6_ADDR_LOOPBACK) || -+ (addr_type & IPV6_ADDR_LINKLOCAL)) -+ return; -+ -+ spin_lock_bh(&fm_ns->local_lock); -+ -+ mpevent.family = AF_INET6; -+ mpevent.addr.in6 = ifa->addr; -+ mpevent.low_prio = (netdev->flags & IFF_MPBACKUP) ? 1 : 0; -+ mpevent.if_idx = netdev->ifindex; -+ -+ if (event == NETDEV_DOWN || !netif_running(netdev) || -+ (netdev->flags & IFF_NOMULTIPATH) || !(netdev->flags & IFF_UP)) -+ mpevent.code = MPTCP_EVENT_DEL; -+ else if (event == NETDEV_UP) -+ mpevent.code = MPTCP_EVENT_ADD; -+ else if (event == NETDEV_CHANGE) -+ mpevent.code = MPTCP_EVENT_MOD; -+ -+ mptcp_debug("%s created event for %pI6, code %u prio %u idx %u\n", __func__, -+ &ifa->addr, mpevent.code, mpevent.low_prio, mpevent.if_idx); -+ add_pm_event(net, &mpevent); -+ -+ spin_unlock_bh(&fm_ns->local_lock); -+ return; -+} -+ -+/* React on IPv6-addr add/rem-events */ -+static int inet6_addr_event(struct notifier_block *this, unsigned long event, -+ void *ptr) -+{ -+ struct inet6_ifaddr *ifa6 = (struct inet6_ifaddr *)ptr; -+ struct net *net = dev_net(ifa6->idev->dev); -+ -+ if (!(event == NETDEV_UP || event == NETDEV_DOWN || -+ event == NETDEV_CHANGE)) -+ return NOTIFY_DONE; -+ -+ if (sysctl_mptcp_enabled && !ipv6_dad_finished(ifa6)) -+ dad_setup_timer(ifa6); -+ else -+ addr6_event_handler(ifa6, event, net); -+ -+ return NOTIFY_DONE; -+} -+ -+static struct notifier_block inet6_addr_notifier = { -+ .notifier_call = inet6_addr_event, -+}; -+ -+#endif -+ -+/* React on ifup/down-events */ -+static int netdev_event(struct notifier_block *this, unsigned long event, -+ void *ptr) -+{ -+ const struct net_device *dev = netdev_notifier_info_to_dev(ptr); -+ struct in_device *in_dev; -+#if IS_ENABLED(CONFIG_IPV6) -+ struct inet6_dev *in6_dev; -+#endif -+ -+ if (!(event == NETDEV_UP || event == NETDEV_DOWN || -+ event == NETDEV_CHANGE)) -+ return NOTIFY_DONE; -+ -+ rcu_read_lock(); -+ in_dev = __in_dev_get_rtnl(dev); -+ -+ if (in_dev) { -+ for_ifa(in_dev) { -+ mptcp_pm_inetaddr_event(NULL, event, ifa); -+ } endfor_ifa(in_dev); -+ } -+ -+#if IS_ENABLED(CONFIG_IPV6) -+ in6_dev = __in6_dev_get(dev); -+ -+ if (in6_dev) { -+ struct inet6_ifaddr *ifa6; -+ list_for_each_entry(ifa6, &in6_dev->addr_list, if_list) -+ inet6_addr_event(NULL, event, ifa6); -+ } -+#endif -+ -+ rcu_read_unlock(); -+ return NOTIFY_DONE; -+} -+ -+static struct notifier_block mptcp_pm_netdev_notifier = { -+ .notifier_call = netdev_event, -+}; -+ -+static void full_mesh_add_raddr(struct mptcp_cb *mpcb, -+ const union inet_addr *addr, -+ sa_family_t family, __be16 port, u8 id) -+{ -+ if (family == AF_INET) -+ mptcp_addv4_raddr(mpcb, &addr->in, port, id); -+ else -+ mptcp_addv6_raddr(mpcb, &addr->in6, port, id); -+} -+ -+static void full_mesh_new_session(const struct sock *meta_sk) -+{ -+ struct mptcp_loc_addr *mptcp_local; -+ struct mptcp_cb *mpcb = tcp_sk(meta_sk)->mpcb; -+ struct fullmesh_priv *fmp = fullmesh_get_priv(mpcb); -+ const struct mptcp_fm_ns *fm_ns = fm_get_ns(sock_net(meta_sk)); -+ struct tcp_sock *master_tp = tcp_sk(mpcb->master_sk); -+ int i, index, if_idx = 0; -+ union inet_addr saddr, daddr; -+ sa_family_t family = AF_INET; -+ bool meta_v4 = meta_sk->sk_family == AF_INET; -+ -+ /* Init local variables necessary for the rest */ -+ if (meta_sk->sk_family == AF_INET || mptcp_v6_is_v4_mapped(meta_sk)) { -+ saddr.ip = inet_sk(meta_sk)->inet_saddr; -+ daddr.ip = inet_sk(meta_sk)->inet_daddr; -+ if_idx = mpcb->master_sk->sk_bound_dev_if; -+ family = AF_INET; -+#if IS_ENABLED(CONFIG_IPV6) -+ } else { -+ saddr.in6 = inet6_sk(meta_sk)->saddr; -+ daddr.in6 = meta_sk->sk_v6_daddr; -+ if_idx = mpcb->master_sk->sk_bound_dev_if; -+ family = AF_INET6; -+#endif -+ } -+ -+ if (inet_sk(meta_sk)->transparent) -+ if_idx = inet_sk(meta_sk)->rx_dst_ifindex; -+ -+ rcu_read_lock_bh(); -+ mptcp_local = rcu_dereference(fm_ns->local); -+ -+ if (inet_sk(meta_sk)->transparent) -+ index = mptcp_find_address_transp(mptcp_local, family, if_idx); -+ else -+ index = mptcp_find_address(mptcp_local, family, &saddr, if_idx); -+ if (index < 0) -+ goto fallback; -+ -+ if (family == AF_INET) -+ master_tp->mptcp->low_prio = mptcp_local->locaddr4[index].low_prio; -+ else -+ master_tp->mptcp->low_prio = mptcp_local->locaddr6[index].low_prio; -+ master_tp->mptcp->send_mp_prio = master_tp->mptcp->low_prio; -+ -+ full_mesh_add_raddr(mpcb, &daddr, family, 0, 0); -+ mptcp_set_init_addr_bit(mpcb, &daddr, family, index); -+ -+ /* Initialize workqueue-struct */ -+ INIT_WORK(&fmp->subflow_work, create_subflow_worker); -+ INIT_DELAYED_WORK(&fmp->subflow_retry_work, retry_subflow_worker); -+ fmp->mpcb = mpcb; -+ -+ if (!meta_v4 && meta_sk->sk_ipv6only) -+ goto skip_ipv4; -+ -+ /* Look for the address among the local addresses */ -+ mptcp_for_each_bit_set(mptcp_local->loc4_bits, i) { -+ __be32 ifa_address = mptcp_local->locaddr4[i].addr.s_addr; -+ -+ /* We do not need to announce the initial subflow's address again */ -+ if (family == AF_INET && -+ (!if_idx || mptcp_local->locaddr4[i].if_idx == if_idx) && -+ saddr.ip == ifa_address) -+ continue; -+ -+ fmp->add_addr++; -+ mpcb->addr_signal = 1; -+ } -+ -+skip_ipv4: -+#if IS_ENABLED(CONFIG_IPV6) -+ /* skip IPv6 addresses if meta-socket is IPv4 */ -+ if (meta_v4) -+ goto skip_ipv6; -+ -+ mptcp_for_each_bit_set(mptcp_local->loc6_bits, i) { -+ const struct in6_addr *ifa6 = &mptcp_local->locaddr6[i].addr; -+ -+ /* We do not need to announce the initial subflow's address again */ -+ if (family == AF_INET6 && -+ (!if_idx || mptcp_local->locaddr6[i].if_idx == if_idx) && -+ ipv6_addr_equal(&saddr.in6, ifa6)) -+ continue; -+ -+ fmp->add_addr++; -+ mpcb->addr_signal = 1; -+ } -+ -+skip_ipv6: -+#endif -+ -+ rcu_read_unlock_bh(); -+ -+ if (family == AF_INET) -+ fmp->announced_addrs_v4 |= (1 << index); -+ else -+ fmp->announced_addrs_v6 |= (1 << index); -+ -+ for (i = fmp->add_addr; i && fmp->add_addr; i--) -+ tcp_send_ack(mpcb->master_sk); -+ -+ if (master_tp->mptcp->send_mp_prio) -+ tcp_send_ack(mpcb->master_sk); -+ -+ return; -+ -+fallback: -+ rcu_read_unlock_bh(); -+ mptcp_fallback_default(mpcb); -+ return; -+} -+ -+static void full_mesh_create_subflows(struct sock *meta_sk) -+{ -+ const struct mptcp_cb *mpcb = tcp_sk(meta_sk)->mpcb; -+ struct fullmesh_priv *fmp = fullmesh_get_priv(mpcb); -+ -+ if (mpcb->infinite_mapping_snd || mpcb->infinite_mapping_rcv || -+ mpcb->send_infinite_mapping || -+ mpcb->server_side || sock_flag(meta_sk, SOCK_DEAD)) -+ return; -+ -+ if (mpcb->master_sk && -+ !tcp_sk(mpcb->master_sk)->mptcp->fully_established) -+ return; -+ -+ if (!work_pending(&fmp->subflow_work)) { -+ sock_hold(meta_sk); -+ queue_work(mptcp_wq, &fmp->subflow_work); -+ } -+} -+ -+static void full_mesh_subflow_error(struct sock *meta_sk, struct sock *sk) -+{ -+ const struct mptcp_cb *mpcb = tcp_sk(meta_sk)->mpcb; -+ -+ if (!create_on_err) -+ return; -+ -+ if (mpcb->infinite_mapping_snd || mpcb->infinite_mapping_rcv || -+ mpcb->send_infinite_mapping || -+ mpcb->server_side || sock_flag(meta_sk, SOCK_DEAD)) -+ return; -+ -+ if (sk->sk_err != ETIMEDOUT) -+ return; -+ -+ full_mesh_create_subflows(meta_sk); -+} -+ -+/* Called upon release_sock, if the socket was owned by the user during -+ * a path-management event. -+ */ -+static void full_mesh_release_sock(struct sock *meta_sk) -+{ -+ struct mptcp_loc_addr *mptcp_local; -+ struct mptcp_cb *mpcb = tcp_sk(meta_sk)->mpcb; -+ struct fullmesh_priv *fmp = fullmesh_get_priv(mpcb); -+ const struct mptcp_fm_ns *fm_ns = fm_get_ns(sock_net(meta_sk)); -+ struct sock *sk, *tmpsk; -+ bool meta_v4 = meta_sk->sk_family == AF_INET; -+ int i; -+ -+ rcu_read_lock_bh(); -+ mptcp_local = rcu_dereference(fm_ns->local); -+ -+ if (!meta_v4 && meta_sk->sk_ipv6only) -+ goto skip_ipv4; -+ -+ /* First, detect modifications or additions */ -+ mptcp_for_each_bit_set(mptcp_local->loc4_bits, i) { -+ struct in_addr ifa = mptcp_local->locaddr4[i].addr; -+ bool found = false; -+ -+ mptcp_for_each_sk(mpcb, sk) { -+ struct tcp_sock *tp = tcp_sk(sk); -+ -+ if (sk->sk_family == AF_INET6 && -+ !mptcp_v6_is_v4_mapped(sk)) -+ continue; -+ -+ if (inet_sk(sk)->inet_saddr != ifa.s_addr) -+ continue; -+ -+ found = true; -+ -+ if (mptcp_local->locaddr4[i].low_prio != tp->mptcp->low_prio) { -+ tp->mptcp->send_mp_prio = 1; -+ tp->mptcp->low_prio = mptcp_local->locaddr4[i].low_prio; -+ -+ tcp_send_ack(sk); -+ } -+ } -+ -+ if (!found) { -+ fmp->add_addr++; -+ mpcb->addr_signal = 1; -+ -+ sk = mptcp_select_ack_sock(meta_sk); -+ if (sk) -+ tcp_send_ack(sk); -+ full_mesh_create_subflows(meta_sk); -+ } -+ } -+ -+skip_ipv4: -+#if IS_ENABLED(CONFIG_IPV6) -+ /* skip IPv6 addresses if meta-socket is IPv4 */ -+ if (meta_v4) -+ goto removal; -+ -+ mptcp_for_each_bit_set(mptcp_local->loc6_bits, i) { -+ struct in6_addr ifa = mptcp_local->locaddr6[i].addr; -+ bool found = false; -+ -+ mptcp_for_each_sk(mpcb, sk) { -+ struct tcp_sock *tp = tcp_sk(sk); -+ -+ if (sk->sk_family == AF_INET || -+ mptcp_v6_is_v4_mapped(sk)) -+ continue; -+ -+ if (!ipv6_addr_equal(&inet6_sk(sk)->saddr, &ifa)) -+ continue; -+ -+ found = true; -+ -+ if (mptcp_local->locaddr6[i].low_prio != tp->mptcp->low_prio) { -+ tp->mptcp->send_mp_prio = 1; -+ tp->mptcp->low_prio = mptcp_local->locaddr6[i].low_prio; -+ -+ tcp_send_ack(sk); -+ } -+ } -+ -+ if (!found) { -+ fmp->add_addr++; -+ mpcb->addr_signal = 1; -+ -+ sk = mptcp_select_ack_sock(meta_sk); -+ if (sk) -+ tcp_send_ack(sk); -+ full_mesh_create_subflows(meta_sk); -+ } -+ } -+ -+removal: -+#endif -+ -+ /* Now, detect address-removals */ -+ mptcp_for_each_sk_safe(mpcb, sk, tmpsk) { -+ bool shall_remove = true; -+ -+ if (sk->sk_family == AF_INET || mptcp_v6_is_v4_mapped(sk)) { -+ mptcp_for_each_bit_set(mptcp_local->loc4_bits, i) { -+ if (inet_sk(sk)->inet_saddr == mptcp_local->locaddr4[i].addr.s_addr) { -+ shall_remove = false; -+ break; -+ } -+ } -+ } else { -+ mptcp_for_each_bit_set(mptcp_local->loc6_bits, i) { -+ if (ipv6_addr_equal(&inet6_sk(sk)->saddr, &mptcp_local->locaddr6[i].addr)) { -+ shall_remove = false; -+ break; -+ } -+ } -+ } -+ -+ if (shall_remove) { -+ /* Reinject, so that pf = 1 and so we -+ * won't select this one as the -+ * ack-sock. -+ */ -+ mptcp_reinject_data(sk, 0); -+ -+ announce_remove_addr(tcp_sk(sk)->mptcp->loc_id, -+ meta_sk); -+ -+ mptcp_sub_force_close(sk); -+ } -+ } -+ -+ /* Just call it optimistically. It actually cannot do any harm */ -+ update_addr_bitfields(meta_sk, mptcp_local); -+ -+ rcu_read_unlock_bh(); -+} -+ -+static int full_mesh_get_local_id(sa_family_t family, union inet_addr *addr, -+ struct net *net, bool *low_prio) -+{ -+ struct mptcp_loc_addr *mptcp_local; -+ const struct mptcp_fm_ns *fm_ns = fm_get_ns(net); -+ int index, id = -1; -+ -+ /* Handle the backup-flows */ -+ rcu_read_lock_bh(); -+ mptcp_local = rcu_dereference(fm_ns->local); -+ -+ index = mptcp_find_address(mptcp_local, family, addr, 0); -+ -+ if (index != -1) { -+ if (family == AF_INET) { -+ id = mptcp_local->locaddr4[index].loc4_id; -+ *low_prio = mptcp_local->locaddr4[index].low_prio; -+ } else { -+ id = mptcp_local->locaddr6[index].loc6_id; -+ *low_prio = mptcp_local->locaddr6[index].low_prio; -+ } -+ } -+ -+ -+ rcu_read_unlock_bh(); -+ -+ return id; -+} -+ -+static void full_mesh_addr_signal(struct sock *sk, unsigned *size, -+ struct tcp_out_options *opts, -+ struct sk_buff *skb) -+{ -+ const struct tcp_sock *tp = tcp_sk(sk); -+ struct mptcp_cb *mpcb = tp->mpcb; -+ struct sock *meta_sk = mpcb->meta_sk; -+ struct fullmesh_priv *fmp = fullmesh_get_priv(mpcb); -+ struct mptcp_loc_addr *mptcp_local; -+ struct mptcp_fm_ns *fm_ns = fm_get_ns(sock_net(sk)); -+ int remove_addr_len; -+ u8 unannouncedv4 = 0, unannouncedv6 = 0; -+ bool meta_v4 = meta_sk->sk_family == AF_INET; -+ -+ mpcb->addr_signal = 0; -+ -+ if (likely(!fmp->add_addr)) -+ goto remove_addr; -+ -+ rcu_read_lock_bh(); -+ mptcp_local = rcu_dereference(fm_ns->local); -+ -+ if (!meta_v4 && meta_sk->sk_ipv6only) -+ goto skip_ipv4; -+ -+ /* IPv4 */ -+ unannouncedv4 = (~fmp->announced_addrs_v4) & mptcp_local->loc4_bits; -+ if (unannouncedv4 && -+ ((mpcb->mptcp_ver == MPTCP_VERSION_0 && -+ MAX_TCP_OPTION_SPACE - *size >= MPTCP_SUB_LEN_ADD_ADDR4_ALIGN) || -+ (mpcb->mptcp_ver >= MPTCP_VERSION_1 && -+ MAX_TCP_OPTION_SPACE - *size >= MPTCP_SUB_LEN_ADD_ADDR4_ALIGN_VER1))) { -+ int ind = mptcp_find_free_index(~unannouncedv4); -+ -+ opts->options |= OPTION_MPTCP; -+ opts->mptcp_options |= OPTION_ADD_ADDR; -+ opts->add_addr4.addr_id = mptcp_local->locaddr4[ind].loc4_id; -+ opts->add_addr4.addr = mptcp_local->locaddr4[ind].addr; -+ opts->add_addr_v4 = 1; -+ if (mpcb->mptcp_ver >= MPTCP_VERSION_1) { -+ u8 mptcp_hash_mac[20]; -+ u8 no_key[8]; -+ -+ *(u64 *)no_key = 0; -+ mptcp_hmac_sha1((u8 *)&mpcb->mptcp_loc_key, -+ (u8 *)no_key, -+ (u32 *)mptcp_hash_mac, 2, -+ 1, (u8 *)&mptcp_local->locaddr4[ind].loc4_id, -+ 4, (u8 *)&opts->add_addr4.addr.s_addr); -+ opts->add_addr4.trunc_mac = *(u64 *)mptcp_hash_mac; -+ } -+ -+ if (skb) { -+ fmp->announced_addrs_v4 |= (1 << ind); -+ fmp->add_addr--; -+ } -+ -+ if (mpcb->mptcp_ver < MPTCP_VERSION_1) -+ *size += MPTCP_SUB_LEN_ADD_ADDR4_ALIGN; -+ if (mpcb->mptcp_ver >= MPTCP_VERSION_1) -+ *size += MPTCP_SUB_LEN_ADD_ADDR4_ALIGN_VER1; -+ -+ goto skip_ipv6; -+ } -+ -+ if (meta_v4) -+ goto skip_ipv6; -+skip_ipv4: -+ /* IPv6 */ -+ unannouncedv6 = (~fmp->announced_addrs_v6) & mptcp_local->loc6_bits; -+ if (unannouncedv6 && -+ ((mpcb->mptcp_ver == MPTCP_VERSION_0 && -+ MAX_TCP_OPTION_SPACE - *size >= MPTCP_SUB_LEN_ADD_ADDR6_ALIGN) || -+ (mpcb->mptcp_ver >= MPTCP_VERSION_1 && -+ MAX_TCP_OPTION_SPACE - *size >= MPTCP_SUB_LEN_ADD_ADDR6_ALIGN_VER1))) { -+ int ind = mptcp_find_free_index(~unannouncedv6); -+ -+ opts->options |= OPTION_MPTCP; -+ opts->mptcp_options |= OPTION_ADD_ADDR; -+ opts->add_addr6.addr_id = mptcp_local->locaddr6[ind].loc6_id; -+ opts->add_addr6.addr = mptcp_local->locaddr6[ind].addr; -+ opts->add_addr_v6 = 1; -+ if (mpcb->mptcp_ver >= MPTCP_VERSION_1) { -+ u8 mptcp_hash_mac[20]; -+ u8 no_key[8]; -+ -+ *(u64 *)no_key = 0; -+ mptcp_hmac_sha1((u8 *)&mpcb->mptcp_loc_key, -+ (u8 *)no_key, -+ (u32 *)mptcp_hash_mac, 2, -+ 1, (u8 *)&mptcp_local->locaddr6[ind].loc6_id, -+ 16, (u8 *)&opts->add_addr6.addr.s6_addr); -+ opts->add_addr6.trunc_mac = *(u64 *)mptcp_hash_mac; -+ } -+ -+ if (skb) { -+ fmp->announced_addrs_v6 |= (1 << ind); -+ fmp->add_addr--; -+ } -+ if (mpcb->mptcp_ver < MPTCP_VERSION_1) -+ *size += MPTCP_SUB_LEN_ADD_ADDR6_ALIGN; -+ if (mpcb->mptcp_ver >= MPTCP_VERSION_1) -+ *size += MPTCP_SUB_LEN_ADD_ADDR6_ALIGN_VER1; -+ } -+ -+skip_ipv6: -+ rcu_read_unlock_bh(); -+ -+ if (!unannouncedv4 && !unannouncedv6 && skb) -+ fmp->add_addr--; -+ -+remove_addr: -+ if (likely(!fmp->remove_addrs)) -+ goto exit; -+ -+ remove_addr_len = mptcp_sub_len_remove_addr_align(fmp->remove_addrs); -+ if (MAX_TCP_OPTION_SPACE - *size < remove_addr_len) -+ goto exit; -+ -+ opts->options |= OPTION_MPTCP; -+ opts->mptcp_options |= OPTION_REMOVE_ADDR; -+ opts->remove_addrs = fmp->remove_addrs; -+ *size += remove_addr_len; -+ if (skb) -+ fmp->remove_addrs = 0; -+ -+exit: -+ mpcb->addr_signal = !!(fmp->add_addr || fmp->remove_addrs); -+} -+ -+static void full_mesh_rem_raddr(struct mptcp_cb *mpcb, u8 rem_id) -+{ -+ mptcp_v4_rem_raddress(mpcb, rem_id); -+ mptcp_v6_rem_raddress(mpcb, rem_id); -+} -+ -+static void full_mesh_delete_subflow(struct sock *sk) -+{ -+ struct fullmesh_priv *fmp = fullmesh_get_priv(tcp_sk(sk)->mpcb); -+ struct mptcp_fm_ns *fm_ns = fm_get_ns(sock_net(sk)); -+ struct mptcp_loc_addr *mptcp_local; -+ int index, i; -+ -+ if (!create_on_err) -+ return; -+ -+ rcu_read_lock_bh(); -+ mptcp_local = rcu_dereference_bh(fm_ns->local); -+ -+ if (sk->sk_family == AF_INET || mptcp_v6_is_v4_mapped(sk)) { -+ union inet_addr saddr; -+ -+ saddr.ip = inet_sk(sk)->inet_saddr; -+ index = mptcp_find_address(mptcp_local, AF_INET, &saddr, -+ sk->sk_bound_dev_if); -+ if (index < 0) -+ goto out; -+ -+ mptcp_for_each_bit_set(fmp->rem4_bits, i) { -+ struct fullmesh_rem4 *rem4 = &fmp->remaddr4[i]; -+ -+ if (rem4->addr.s_addr != sk->sk_daddr) -+ continue; -+ -+ if (rem4->port && rem4->port != inet_sk(sk)->inet_dport) -+ continue; -+ -+ rem4->bitfield &= ~(1 << index); -+ } -+#if IS_ENABLED(CONFIG_IPV6) -+ } else { -+ union inet_addr saddr; -+ -+ saddr.in6 = inet6_sk(sk)->saddr; -+ index = mptcp_find_address(mptcp_local, AF_INET6, &saddr, -+ sk->sk_bound_dev_if); -+ if (index < 0) -+ goto out; -+ -+ mptcp_for_each_bit_set(fmp->rem6_bits, i) { -+ struct fullmesh_rem6 *rem6 = &fmp->remaddr6[i]; -+ -+ if (!ipv6_addr_equal(&rem6->addr, &sk->sk_v6_daddr)) -+ continue; -+ -+ if (rem6->port && rem6->port != inet_sk(sk)->inet_dport) -+ continue; -+ -+ rem6->bitfield &= ~(1 << index); -+ } -+#endif -+ } -+ -+out: -+ rcu_read_unlock_bh(); -+} -+ -+/* Output /proc/net/mptcp_fullmesh */ -+static int mptcp_fm_seq_show(struct seq_file *seq, void *v) -+{ -+ const struct net *net = seq->private; -+ struct mptcp_loc_addr *mptcp_local; -+ const struct mptcp_fm_ns *fm_ns = fm_get_ns(net); -+ int i; -+ -+ seq_printf(seq, "Index, Address-ID, Backup, IP-address, if-idx\n"); -+ -+ rcu_read_lock_bh(); -+ mptcp_local = rcu_dereference(fm_ns->local); -+ -+ seq_printf(seq, "IPv4, next v4-index: %u\n", mptcp_local->next_v4_index); -+ -+ mptcp_for_each_bit_set(mptcp_local->loc4_bits, i) { -+ struct mptcp_loc4 *loc4 = &mptcp_local->locaddr4[i]; -+ -+ seq_printf(seq, "%u, %u, %u, %pI4 %u\n", i, loc4->loc4_id, -+ loc4->low_prio, &loc4->addr, loc4->if_idx); -+ } -+ -+ seq_printf(seq, "IPv6, next v6-index: %u\n", mptcp_local->next_v6_index); -+ -+ mptcp_for_each_bit_set(mptcp_local->loc6_bits, i) { -+ struct mptcp_loc6 *loc6 = &mptcp_local->locaddr6[i]; -+ -+ seq_printf(seq, "%u, %u, %u, %pI6 %u\n", i, loc6->loc6_id, -+ loc6->low_prio, &loc6->addr, loc6->if_idx); -+ } -+ rcu_read_unlock_bh(); -+ -+ return 0; -+} -+ -+static int mptcp_fm_seq_open(struct inode *inode, struct file *file) -+{ -+ return single_open_net(inode, file, mptcp_fm_seq_show); -+} -+ -+static const struct file_operations mptcp_fm_seq_fops = { -+ .owner = THIS_MODULE, -+ .open = mptcp_fm_seq_open, -+ .read = seq_read, -+ .llseek = seq_lseek, -+ .release = single_release_net, -+}; -+ -+static int mptcp_fm_init_net(struct net *net) -+{ -+ struct mptcp_loc_addr *mptcp_local; -+ struct mptcp_fm_ns *fm_ns; -+ int err = 0; -+ -+ fm_ns = kzalloc(sizeof(*fm_ns), GFP_KERNEL); -+ if (!fm_ns) -+ return -ENOBUFS; -+ -+ mptcp_local = kzalloc(sizeof(*mptcp_local), GFP_KERNEL); -+ if (!mptcp_local) { -+ err = -ENOBUFS; -+ goto err_mptcp_local; -+ } -+ -+ if (!proc_create("mptcp_fullmesh", S_IRUGO, net->proc_net, -+ &mptcp_fm_seq_fops)) { -+ err = -ENOMEM; -+ goto err_seq_fops; -+ } -+ -+ mptcp_local->next_v4_index = 1; -+ -+ rcu_assign_pointer(fm_ns->local, mptcp_local); -+ INIT_DELAYED_WORK(&fm_ns->address_worker, mptcp_address_worker); -+ INIT_LIST_HEAD(&fm_ns->events); -+ spin_lock_init(&fm_ns->local_lock); -+ fm_ns->net = net; -+ net->mptcp.path_managers[MPTCP_PM_FULLMESH] = fm_ns; -+ -+ return 0; -+err_seq_fops: -+ kfree(mptcp_local); -+err_mptcp_local: -+ kfree(fm_ns); -+ return err; -+} -+ -+static void mptcp_fm_exit_net(struct net *net) -+{ -+ struct mptcp_addr_event *eventq, *tmp; -+ struct mptcp_fm_ns *fm_ns; -+ struct mptcp_loc_addr *mptcp_local; -+ -+ fm_ns = fm_get_ns(net); -+ cancel_delayed_work_sync(&fm_ns->address_worker); -+ -+ rcu_read_lock_bh(); -+ -+ mptcp_local = rcu_dereference_bh(fm_ns->local); -+ kfree_rcu(mptcp_local, rcu); -+ -+ spin_lock(&fm_ns->local_lock); -+ list_for_each_entry_safe(eventq, tmp, &fm_ns->events, list) { -+ list_del(&eventq->list); -+ kfree(eventq); -+ } -+ spin_unlock(&fm_ns->local_lock); -+ -+ rcu_read_unlock_bh(); -+ -+ remove_proc_entry("mptcp_fullmesh", net->proc_net); -+ -+ kfree(fm_ns); -+} -+ -+static struct pernet_operations full_mesh_net_ops = { -+ .init = mptcp_fm_init_net, -+ .exit = mptcp_fm_exit_net, -+}; -+ -+static struct mptcp_pm_ops full_mesh __read_mostly = { -+ .new_session = full_mesh_new_session, -+ .release_sock = full_mesh_release_sock, -+ .fully_established = full_mesh_create_subflows, -+ .new_remote_address = full_mesh_create_subflows, -+ .subflow_error = full_mesh_subflow_error, -+ .get_local_id = full_mesh_get_local_id, -+ .addr_signal = full_mesh_addr_signal, -+ .add_raddr = full_mesh_add_raddr, -+ .rem_raddr = full_mesh_rem_raddr, -+ .delete_subflow = full_mesh_delete_subflow, -+ .name = "fullmesh", -+ .owner = THIS_MODULE, -+}; -+ -+/* General initialization of MPTCP_PM */ -+static int __init full_mesh_register(void) -+{ -+ int ret; -+ -+ BUILD_BUG_ON(sizeof(struct fullmesh_priv) > MPTCP_PM_SIZE); -+ -+ ret = register_pernet_subsys(&full_mesh_net_ops); -+ if (ret) -+ goto out; -+ -+ ret = register_inetaddr_notifier(&mptcp_pm_inetaddr_notifier); -+ if (ret) -+ goto err_reg_inetaddr; -+ ret = register_netdevice_notifier(&mptcp_pm_netdev_notifier); -+ if (ret) -+ goto err_reg_netdev; -+ -+#if IS_ENABLED(CONFIG_IPV6) -+ ret = register_inet6addr_notifier(&inet6_addr_notifier); -+ if (ret) -+ goto err_reg_inet6addr; -+#endif -+ -+ ret = mptcp_register_path_manager(&full_mesh); -+ if (ret) -+ goto err_reg_pm; -+ -+out: -+ return ret; -+ -+ -+err_reg_pm: -+#if IS_ENABLED(CONFIG_IPV6) -+ unregister_inet6addr_notifier(&inet6_addr_notifier); -+err_reg_inet6addr: -+#endif -+ unregister_netdevice_notifier(&mptcp_pm_netdev_notifier); -+err_reg_netdev: -+ unregister_inetaddr_notifier(&mptcp_pm_inetaddr_notifier); -+err_reg_inetaddr: -+ unregister_pernet_subsys(&full_mesh_net_ops); -+ goto out; -+} -+ -+static void full_mesh_unregister(void) -+{ -+#if IS_ENABLED(CONFIG_IPV6) -+ unregister_inet6addr_notifier(&inet6_addr_notifier); -+#endif -+ unregister_netdevice_notifier(&mptcp_pm_netdev_notifier); -+ unregister_inetaddr_notifier(&mptcp_pm_inetaddr_notifier); -+ unregister_pernet_subsys(&full_mesh_net_ops); -+ mptcp_unregister_path_manager(&full_mesh); -+} -+ -+module_init(full_mesh_register); -+module_exit(full_mesh_unregister); -+ -+MODULE_AUTHOR("Christoph Paasch"); -+MODULE_LICENSE("GPL"); -+MODULE_DESCRIPTION("Full-Mesh MPTCP"); -+MODULE_VERSION("0.88"); -diff -aurN linux-4.9.162/net/mptcp/mptcp_input.c mptcp-mptcp_v0.93/net/mptcp/mptcp_input.c ---- linux-4.9.162/net/mptcp/mptcp_input.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_v0.93/net/mptcp/mptcp_input.c 2019-03-14 14:02:32.000000000 +0100 -@@ -0,0 +1,2501 @@ -+/* -+ * MPTCP implementation - Sending side -+ * -+ * Initial Design & Implementation: -+ * Sébastien Barré -+ * -+ * Current Maintainer & Author: -+ * Christoph Paasch -+ * -+ * Additional authors: -+ * Jaakko Korkeaniemi -+ * Gregory Detal -+ * Fabien Duchêne -+ * Andreas Seelinger -+ * Lavkesh Lahngir -+ * Andreas Ripke -+ * Vlad Dogaru -+ * Octavian Purdila -+ * John Ronan -+ * Catalin Nicutar -+ * Brandon Heller -+ * -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version -+ * 2 of the License, or (at your option) any later version. -+ */ -+ -+#include -+ -+#include -+#include -+#include -+ -+#include -+ -+/* is seq1 < seq2 ? */ -+static inline bool before64(const u64 seq1, const u64 seq2) -+{ -+ return (s64)(seq1 - seq2) < 0; -+} -+ -+/* is seq1 > seq2 ? */ -+#define after64(seq1, seq2) before64(seq2, seq1) -+ -+static inline void mptcp_become_fully_estab(struct sock *sk) -+{ -+ tcp_sk(sk)->mptcp->fully_established = 1; -+ -+ if (is_master_tp(tcp_sk(sk)) && -+ tcp_sk(sk)->mpcb->pm_ops->fully_established) -+ tcp_sk(sk)->mpcb->pm_ops->fully_established(mptcp_meta_sk(sk)); -+} -+ -+/* Similar to tcp_tso_acked without any memory accounting */ -+static inline int mptcp_tso_acked_reinject(const struct sock *meta_sk, -+ struct sk_buff *skb) -+{ -+ const struct tcp_sock *meta_tp = tcp_sk(meta_sk); -+ u32 packets_acked, len, delta_truesize; -+ -+ BUG_ON(!after(TCP_SKB_CB(skb)->end_seq, meta_tp->snd_una)); -+ -+ packets_acked = tcp_skb_pcount(skb); -+ -+ if (skb_unclone(skb, GFP_ATOMIC)) -+ return 0; -+ -+ len = meta_tp->snd_una - TCP_SKB_CB(skb)->seq; -+ delta_truesize = __pskb_trim_head(skb, len); -+ -+ TCP_SKB_CB(skb)->seq += len; -+ skb->ip_summed = CHECKSUM_PARTIAL; -+ if (delta_truesize) -+ skb->truesize -= delta_truesize; -+ -+ /* Any change of skb->len requires recalculation of tso factor. */ -+ if (tcp_skb_pcount(skb) > 1) -+ tcp_set_skb_tso_segs(skb, tcp_skb_mss(skb)); -+ packets_acked -= tcp_skb_pcount(skb); -+ -+ if (packets_acked) { -+ BUG_ON(tcp_skb_pcount(skb) == 0); -+ BUG_ON(!before(TCP_SKB_CB(skb)->seq, TCP_SKB_CB(skb)->end_seq)); -+ } -+ -+ return packets_acked; -+} -+ -+/** -+ * Cleans the meta-socket retransmission queue and the reinject-queue. -+ * @sk must be the metasocket. -+ */ -+static void mptcp_clean_rtx_queue(struct sock *meta_sk, u32 prior_snd_una) -+{ -+ struct sk_buff *skb, *tmp; -+ struct tcp_sock *meta_tp = tcp_sk(meta_sk); -+ struct mptcp_cb *mpcb = meta_tp->mpcb; -+ bool acked = false; -+ u32 acked_pcount; -+ -+ while ((skb = tcp_write_queue_head(meta_sk)) && -+ skb != tcp_send_head(meta_sk)) { -+ bool fully_acked = true; -+ -+ if (before(meta_tp->snd_una, TCP_SKB_CB(skb)->end_seq)) { -+ if (tcp_skb_pcount(skb) == 1 || -+ !after(meta_tp->snd_una, TCP_SKB_CB(skb)->seq)) -+ break; -+ -+ acked_pcount = tcp_tso_acked(meta_sk, skb); -+ if (!acked_pcount) -+ break; -+ -+ fully_acked = false; -+ } else { -+ acked_pcount = tcp_skb_pcount(skb); -+ } -+ -+ acked = true; -+ meta_tp->packets_out -= acked_pcount; -+ meta_tp->retrans_stamp = 0; -+ -+ if (!fully_acked) -+ break; -+ -+ tcp_unlink_write_queue(skb, meta_sk); -+ -+ if (mptcp_is_data_fin(skb)) { -+ struct sock *sk_it, *sk_tmp; -+ -+ /* DATA_FIN has been acknowledged - now we can close -+ * the subflows -+ */ -+ mptcp_for_each_sk_safe(mpcb, sk_it, sk_tmp) { -+ unsigned long delay = 0; -+ -+ /* If we are the passive closer, don't trigger -+ * subflow-fin until the subflow has been finned -+ * by the peer - thus we add a delay. -+ */ -+ if (mpcb->passive_close && -+ sk_it->sk_state == TCP_ESTABLISHED) -+ delay = inet_csk(sk_it)->icsk_rto << 3; -+ -+ mptcp_sub_close(sk_it, delay); -+ } -+ } -+ sk_wmem_free_skb(meta_sk, skb); -+ } -+ /* Remove acknowledged data from the reinject queue */ -+ skb_queue_walk_safe(&mpcb->reinject_queue, skb, tmp) { -+ if (before(meta_tp->snd_una, TCP_SKB_CB(skb)->end_seq)) { -+ if (tcp_skb_pcount(skb) == 1 || -+ !after(meta_tp->snd_una, TCP_SKB_CB(skb)->seq)) -+ break; -+ -+ mptcp_tso_acked_reinject(meta_sk, skb); -+ break; -+ } -+ -+ __skb_unlink(skb, &mpcb->reinject_queue); -+ __kfree_skb(skb); -+ } -+ -+ if (likely(between(meta_tp->snd_up, prior_snd_una, meta_tp->snd_una))) -+ meta_tp->snd_up = meta_tp->snd_una; -+ -+ if (acked) { -+ tcp_rearm_rto(meta_sk); -+ /* Normally this is done in tcp_try_undo_loss - but MPTCP -+ * does not call this function. -+ */ -+ inet_csk(meta_sk)->icsk_retransmits = 0; -+ } -+} -+ -+/* Inspired by tcp_rcv_state_process */ -+static int mptcp_rcv_state_process(struct sock *meta_sk, struct sock *sk, -+ const struct sk_buff *skb, u32 data_seq, -+ u16 data_len) -+{ -+ struct tcp_sock *meta_tp = tcp_sk(meta_sk), *tp = tcp_sk(sk); -+ const struct tcphdr *th = tcp_hdr(skb); -+ -+ /* State-machine handling if FIN has been enqueued and he has -+ * been acked (snd_una == write_seq) - it's important that this -+ * here is after sk_wmem_free_skb because otherwise -+ * sk_forward_alloc is wrong upon inet_csk_destroy_sock() -+ */ -+ switch (meta_sk->sk_state) { -+ case TCP_FIN_WAIT1: { -+ struct dst_entry *dst; -+ int tmo; -+ -+ if (meta_tp->snd_una != meta_tp->write_seq) -+ break; -+ -+ tcp_set_state(meta_sk, TCP_FIN_WAIT2); -+ meta_sk->sk_shutdown |= SEND_SHUTDOWN; -+ -+ dst = __sk_dst_get(sk); -+ if (dst) -+ dst_confirm(dst); -+ -+ if (!sock_flag(meta_sk, SOCK_DEAD)) { -+ /* Wake up lingering close() */ -+ meta_sk->sk_state_change(meta_sk); -+ break; -+ } -+ -+ if (meta_tp->linger2 < 0 || -+ (data_len && -+ after(data_seq + data_len - (mptcp_is_data_fin2(skb, tp) ? 1 : 0), -+ meta_tp->rcv_nxt))) { -+ mptcp_send_active_reset(meta_sk, GFP_ATOMIC); -+ tcp_done(meta_sk); -+ __NET_INC_STATS(sock_net(meta_sk), LINUX_MIB_TCPABORTONDATA); -+ return 1; -+ } -+ -+ tmo = tcp_fin_time(meta_sk); -+ if (tmo > TCP_TIMEWAIT_LEN) { -+ inet_csk_reset_keepalive_timer(meta_sk, tmo - TCP_TIMEWAIT_LEN); -+ } else if (mptcp_is_data_fin2(skb, tp) || sock_owned_by_user(meta_sk)) { -+ /* Bad case. We could lose such FIN otherwise. -+ * It is not a big problem, but it looks confusing -+ * and not so rare event. We still can lose it now, -+ * if it spins in bh_lock_sock(), but it is really -+ * marginal case. -+ */ -+ inet_csk_reset_keepalive_timer(meta_sk, tmo); -+ } else { -+ meta_tp->ops->time_wait(meta_sk, TCP_FIN_WAIT2, tmo); -+ } -+ break; -+ } -+ case TCP_CLOSING: -+ case TCP_LAST_ACK: -+ if (meta_tp->snd_una == meta_tp->write_seq) { -+ tcp_done(meta_sk); -+ return 1; -+ } -+ break; -+ } -+ -+ /* step 7: process the segment text */ -+ switch (meta_sk->sk_state) { -+ case TCP_FIN_WAIT1: -+ case TCP_FIN_WAIT2: -+ /* RFC 793 says to queue data in these states, -+ * RFC 1122 says we MUST send a reset. -+ * BSD 4.4 also does reset. -+ */ -+ if (meta_sk->sk_shutdown & RCV_SHUTDOWN) { -+ if (TCP_SKB_CB(skb)->end_seq != TCP_SKB_CB(skb)->seq && -+ after(TCP_SKB_CB(skb)->end_seq - th->fin, tp->rcv_nxt) && -+ !mptcp_is_data_fin2(skb, tp)) { -+ __NET_INC_STATS(sock_net(meta_sk), LINUX_MIB_TCPABORTONDATA); -+ mptcp_send_active_reset(meta_sk, GFP_ATOMIC); -+ tcp_reset(meta_sk); -+ return 1; -+ } -+ } -+ break; -+ } -+ -+ return 0; -+} -+ -+/** -+ * @return: -+ * i) 1: Everything's fine. -+ * ii) -1: A reset has been sent on the subflow - csum-failure -+ * iii) 0: csum-failure but no reset sent, because it's the last subflow. -+ * Last packet should not be destroyed by the caller because it has -+ * been done here. -+ */ -+static int mptcp_verif_dss_csum(struct sock *sk) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct sk_buff *tmp, *tmp1, *last = NULL; -+ __wsum csum_tcp = 0; /* cumulative checksum of pld + mptcp-header */ -+ int ans = 1, overflowed = 0, offset = 0, dss_csum_added = 0; -+ int iter = 0; -+ u32 next_seq, offset_seq; -+ -+ skb_queue_walk_safe(&sk->sk_receive_queue, tmp, tmp1) { -+ unsigned int csum_len; -+ -+ /* init next seq in first round */ -+ if (!iter) -+ next_seq = TCP_SKB_CB(tmp)->seq; -+ offset_seq = next_seq - TCP_SKB_CB(tmp)->seq; -+ -+ if (before(tp->mptcp->map_subseq + tp->mptcp->map_data_len, TCP_SKB_CB(tmp)->end_seq)) -+ /* Mapping ends in the middle of the packet - -+ * csum only these bytes -+ */ -+ csum_len = tp->mptcp->map_subseq + tp->mptcp->map_data_len - TCP_SKB_CB(tmp)->seq; -+ else -+ csum_len = tmp->len; -+ -+ csum_len -= offset_seq; -+ offset = 0; -+ if (overflowed) { -+ char first_word[4]; -+ first_word[0] = 0; -+ first_word[1] = 0; -+ first_word[2] = 0; -+ first_word[3] = *(tmp->data + offset_seq); -+ csum_tcp = csum_partial(first_word, 4, csum_tcp); -+ offset = 1; -+ csum_len--; -+ overflowed = 0; -+ } -+ -+ csum_tcp = skb_checksum(tmp, offset + offset_seq, csum_len, -+ csum_tcp); -+ -+ /* Was it on an odd-length? Then we have to merge the next byte -+ * correctly (see above) -+ */ -+ if (csum_len != (csum_len & (~1))) -+ overflowed = 1; -+ -+ if (mptcp_is_data_seq(tmp) && !dss_csum_added) { -+ __be32 data_seq = htonl((u32)(tp->mptcp->map_data_seq >> 32)); -+ -+ /* If a 64-bit dss is present, we increase the offset -+ * by 4 bytes, as the high-order 64-bits will be added -+ * in the final csum_partial-call. -+ */ -+ u32 offset = skb_transport_offset(tmp) + -+ TCP_SKB_CB(tmp)->dss_off; -+ if (TCP_SKB_CB(tmp)->mptcp_flags & MPTCPHDR_SEQ64_SET) -+ offset += 4; -+ -+ csum_tcp = skb_checksum(tmp, offset, -+ MPTCP_SUB_LEN_SEQ_CSUM, -+ csum_tcp); -+ -+ csum_tcp = csum_partial(&data_seq, -+ sizeof(data_seq), csum_tcp); -+ -+ dss_csum_added = 1; /* Just do it once */ -+ } -+ last = tmp; -+ iter++; -+ -+ if (!skb_queue_is_last(&sk->sk_receive_queue, tmp) && -+ !before(TCP_SKB_CB(tmp1)->seq, -+ tp->mptcp->map_subseq + tp->mptcp->map_data_len)) -+ break; -+ next_seq = TCP_SKB_CB(tmp)->end_seq; -+ } -+ -+ /* Now, checksum must be 0 */ -+ if (unlikely(csum_fold(csum_tcp))) { -+ pr_err("%s csum is wrong: %#x data_seq %u dss_csum_added %d overflowed %d iterations %d\n", -+ __func__, csum_fold(csum_tcp), TCP_SKB_CB(last)->seq, -+ dss_csum_added, overflowed, iter); -+ -+ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_CSUMFAIL); -+ tp->mptcp->send_mp_fail = 1; -+ -+ /* map_data_seq is the data-seq number of the -+ * mapping we are currently checking -+ */ -+ tp->mpcb->csum_cutoff_seq = tp->mptcp->map_data_seq; -+ -+ if (tp->mpcb->cnt_subflows > 1) { -+ mptcp_send_reset(sk); -+ ans = -1; -+ } else { -+ tp->mpcb->send_infinite_mapping = 1; -+ -+ /* Need to purge the rcv-queue as it's no more valid */ -+ while ((tmp = __skb_dequeue(&sk->sk_receive_queue)) != NULL) { -+ tp->copied_seq = TCP_SKB_CB(tmp)->end_seq; -+ kfree_skb(tmp); -+ } -+ -+ ans = 0; -+ } -+ } -+ -+ return ans; -+} -+ -+static inline void mptcp_prepare_skb(struct sk_buff *skb, -+ const struct sock *sk) -+{ -+ const struct tcp_sock *tp = tcp_sk(sk); -+ struct tcp_skb_cb *tcb = TCP_SKB_CB(skb); -+ u32 inc = 0, end_seq = tcb->end_seq; -+ -+ if (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN) -+ end_seq--; -+ /* If skb is the end of this mapping (end is always at mapping-boundary -+ * thanks to the splitting/trimming), then we need to increase -+ * data-end-seq by 1 if this here is a data-fin. -+ * -+ * We need to do -1 because end_seq includes the subflow-FIN. -+ */ -+ if (tp->mptcp->map_data_fin && -+ end_seq == tp->mptcp->map_subseq + tp->mptcp->map_data_len) { -+ inc = 1; -+ -+ /* We manually set the fin-flag if it is a data-fin. For easy -+ * processing in tcp_recvmsg. -+ */ -+ TCP_SKB_CB(skb)->tcp_flags |= TCPHDR_FIN; -+ } else { -+ /* We may have a subflow-fin with data but without data-fin */ -+ TCP_SKB_CB(skb)->tcp_flags &= ~TCPHDR_FIN; -+ } -+ -+ /* Adapt data-seq's to the packet itself. We kinda transform the -+ * dss-mapping to a per-packet granularity. This is necessary to -+ * correctly handle overlapping mappings coming from different -+ * subflows. Otherwise it would be a complete mess. -+ */ -+ tcb->seq = ((u32)tp->mptcp->map_data_seq) + tcb->seq - tp->mptcp->map_subseq; -+ tcb->end_seq = tcb->seq + skb->len + inc; -+} -+ -+/** -+ * @return: 1 if the segment has been eaten and can be suppressed, -+ * otherwise 0. -+ */ -+static inline int mptcp_direct_copy(const struct sk_buff *skb, -+ struct sock *meta_sk) -+{ -+ struct tcp_sock *meta_tp = tcp_sk(meta_sk); -+ int chunk = min_t(unsigned int, skb->len, meta_tp->ucopy.len); -+ int eaten = 0; -+ -+ __set_current_state(TASK_RUNNING); -+ -+ if (!skb_copy_datagram_msg(skb, 0, meta_tp->ucopy.msg, chunk)) { -+ meta_tp->ucopy.len -= chunk; -+ meta_tp->copied_seq += chunk; -+ eaten = (chunk == skb->len); -+ tcp_rcv_space_adjust(meta_sk); -+ } -+ return eaten; -+} -+ -+static inline void mptcp_reset_mapping(struct tcp_sock *tp, u32 old_copied_seq) -+{ -+ tp->mptcp->map_data_len = 0; -+ tp->mptcp->map_data_seq = 0; -+ tp->mptcp->map_subseq = 0; -+ tp->mptcp->map_data_fin = 0; -+ tp->mptcp->mapping_present = 0; -+ -+ /* In infinite mapping receiver mode, we have to advance the implied -+ * data-sequence number when we progress the subflow's data. -+ */ -+ if (tp->mpcb->infinite_mapping_rcv) -+ tp->mpcb->infinite_rcv_seq += (tp->copied_seq - old_copied_seq); -+} -+ -+/* The DSS-mapping received on the sk only covers the second half of the skb -+ * (cut at seq). We trim the head from the skb. -+ * Data will be freed upon kfree(). -+ * -+ * Inspired by tcp_trim_head(). -+ */ -+static void mptcp_skb_trim_head(struct sk_buff *skb, struct sock *sk, u32 seq) -+{ -+ int len = seq - TCP_SKB_CB(skb)->seq; -+ u32 new_seq = TCP_SKB_CB(skb)->seq + len; -+ u32 delta_truesize; -+ -+ delta_truesize = __pskb_trim_head(skb, len); -+ -+ TCP_SKB_CB(skb)->seq = new_seq; -+ -+ if (delta_truesize) { -+ skb->truesize -= delta_truesize; -+ atomic_sub(delta_truesize, &sk->sk_rmem_alloc); -+ sk_mem_uncharge(sk, delta_truesize); -+ } -+} -+ -+/* The DSS-mapping received on the sk only covers the first half of the skb -+ * (cut at seq). We create a second skb (@return), and queue it in the rcv-queue -+ * as further packets may resolve the mapping of the second half of data. -+ * -+ * Inspired by tcp_fragment(). -+ */ -+static int mptcp_skb_split_tail(struct sk_buff *skb, struct sock *sk, u32 seq) -+{ -+ struct sk_buff *buff; -+ int nsize; -+ int nlen, len; -+ u8 flags; -+ -+ len = seq - TCP_SKB_CB(skb)->seq; -+ nsize = skb_headlen(skb) - len + tcp_sk(sk)->tcp_header_len; -+ if (nsize < 0) -+ nsize = 0; -+ -+ /* Get a new skb... force flag on. */ -+ buff = alloc_skb(nsize, GFP_ATOMIC); -+ if (buff == NULL) -+ return -ENOMEM; -+ -+ skb_reserve(buff, tcp_sk(sk)->tcp_header_len); -+ skb_reset_transport_header(buff); -+ -+ flags = TCP_SKB_CB(skb)->tcp_flags; -+ TCP_SKB_CB(skb)->tcp_flags = flags & ~(TCPHDR_FIN); -+ TCP_SKB_CB(buff)->tcp_flags = flags; -+ -+ /* We absolutly need to call skb_set_owner_r before refreshing the -+ * truesize of buff, otherwise the moved data will account twice. -+ */ -+ skb_set_owner_r(buff, sk); -+ nlen = skb->len - len - nsize; -+ buff->truesize += nlen; -+ skb->truesize -= nlen; -+ -+ /* Correct the sequence numbers. */ -+ TCP_SKB_CB(buff)->seq = TCP_SKB_CB(skb)->seq + len; -+ TCP_SKB_CB(buff)->end_seq = TCP_SKB_CB(skb)->end_seq; -+ TCP_SKB_CB(skb)->end_seq = TCP_SKB_CB(buff)->seq; -+ -+ skb_split(skb, buff, len); -+ -+ __skb_queue_after(&sk->sk_receive_queue, skb, buff); -+ -+ return 0; -+} -+ -+/* @return: 0 everything is fine. Just continue processing -+ * 1 subflow is broken stop everything -+ * -1 this packet was broken - continue with the next one. -+ */ -+static int mptcp_prevalidate_skb(struct sock *sk, struct sk_buff *skb) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct mptcp_cb *mpcb = tp->mpcb; -+ -+ /* If we are in infinite mode, the subflow-fin is in fact a data-fin. */ -+ if (!skb->len && (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN) && -+ !mptcp_is_data_fin(skb) && !mpcb->infinite_mapping_rcv) { -+ /* Remove a pure subflow-fin from the queue and increase -+ * copied_seq. -+ */ -+ tp->copied_seq = TCP_SKB_CB(skb)->end_seq; -+ __skb_unlink(skb, &sk->sk_receive_queue); -+ __kfree_skb(skb); -+ return -1; -+ } -+ -+ /* If we are not yet fully established and do not know the mapping for -+ * this segment, this path has to fallback to infinite or be torn down. -+ */ -+ if (!tp->mptcp->fully_established && !mptcp_is_data_seq(skb) && -+ !tp->mptcp->mapping_present && !mpcb->infinite_mapping_rcv) { -+ pr_err("%s %#x will fallback - pi %d from %pS, seq %u\n", -+ __func__, mpcb->mptcp_loc_token, -+ tp->mptcp->path_index, __builtin_return_address(0), -+ TCP_SKB_CB(skb)->seq); -+ -+ if (!is_master_tp(tp)) { -+ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_FBDATASUB); -+ mptcp_send_reset(sk); -+ return 1; -+ } -+ -+ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_FBDATAINIT); -+ -+ mpcb->infinite_mapping_snd = 1; -+ mpcb->infinite_mapping_rcv = 1; -+ mpcb->infinite_rcv_seq = mptcp_get_rcv_nxt_64(mptcp_meta_tp(tp)); -+ -+ mptcp_sub_force_close_all(mpcb, sk); -+ -+ /* We do a seamless fallback and should not send a inf.mapping. */ -+ mpcb->send_infinite_mapping = 0; -+ tp->mptcp->fully_established = 1; -+ } -+ -+ /* Receiver-side becomes fully established when a whole rcv-window has -+ * been received without the need to fallback due to the previous -+ * condition. -+ */ -+ if (!tp->mptcp->fully_established) { -+ tp->mptcp->init_rcv_wnd -= skb->len; -+ if (tp->mptcp->init_rcv_wnd < 0) -+ mptcp_become_fully_estab(sk); -+ } -+ -+ return 0; -+} -+ -+static void mptcp_restart_sending(struct sock *meta_sk) -+{ -+ struct tcp_sock *meta_tp = tcp_sk(meta_sk); -+ struct mptcp_cb *mpcb = meta_tp->mpcb; -+ -+ /* We resend everything that has not been acknowledged */ -+ meta_sk->sk_send_head = tcp_write_queue_head(meta_sk); -+ -+ /* We artificially restart the whole send-queue. Thus, -+ * it is as if no packets are in flight -+ */ -+ meta_tp->packets_out = 0; -+ -+ /* If the snd_nxt already wrapped around, we have to -+ * undo the wrapping, as we are restarting from snd_una -+ * on. -+ */ -+ if (meta_tp->snd_nxt < meta_tp->snd_una) { -+ mpcb->snd_high_order[mpcb->snd_hiseq_index] -= 2; -+ mpcb->snd_hiseq_index = mpcb->snd_hiseq_index ? 0 : 1; -+ } -+ meta_tp->snd_nxt = meta_tp->snd_una; -+ -+ /* Trigger a sending on the meta. */ -+ mptcp_push_pending_frames(meta_sk); -+} -+ -+/* @return: 0 everything is fine. Just continue processing -+ * 1 subflow is broken stop everything -+ * -1 this packet was broken - continue with the next one. -+ */ -+static int mptcp_detect_mapping(struct sock *sk, struct sk_buff *skb) -+{ -+ struct tcp_sock *tp = tcp_sk(sk), *meta_tp = mptcp_meta_tp(tp); -+ struct mptcp_cb *mpcb = tp->mpcb; -+ struct tcp_skb_cb *tcb = TCP_SKB_CB(skb); -+ u32 *ptr; -+ u32 data_seq, sub_seq, data_len, tcp_end_seq; -+ bool set_infinite_rcv = false; -+ -+ /* If we are in infinite-mapping-mode, the subflow is guaranteed to be -+ * in-order at the data-level. Thus data-seq-numbers can be inferred -+ * from what is expected at the data-level. -+ */ -+ if (mpcb->infinite_mapping_rcv) { -+ /* copied_seq may be bigger than tcb->seq (e.g., when the peer -+ * retransmits data that actually has already been acknowledged with -+ * newer data, if he did not receive our acks). Thus, we need -+ * to account for this overlap as well. -+ */ -+ tp->mptcp->map_data_seq = mpcb->infinite_rcv_seq - (tp->copied_seq - tcb->seq); -+ tp->mptcp->map_subseq = tcb->seq; -+ tp->mptcp->map_data_len = skb->len; -+ tp->mptcp->map_data_fin = !!(TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN); -+ tp->mptcp->mapping_present = 1; -+ return 0; -+ } -+ -+ /* No mapping here? Exit - it is either already set or still on its way */ -+ if (!mptcp_is_data_seq(skb)) { -+ /* Too many packets without a mapping - this subflow is broken */ -+ if (!tp->mptcp->mapping_present && -+ tp->rcv_nxt - tp->copied_seq > 65536) { -+ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_NODSSWINDOW); -+ mptcp_send_reset(sk); -+ return 1; -+ } -+ -+ return 0; -+ } -+ -+ ptr = mptcp_skb_set_data_seq(skb, &data_seq, mpcb); -+ ptr++; -+ sub_seq = get_unaligned_be32(ptr) + tp->mptcp->rcv_isn; -+ ptr++; -+ data_len = get_unaligned_be16(ptr); -+ -+ /* If it's an empty skb with DATA_FIN, sub_seq must get fixed. -+ * The draft sets it to 0, but we really would like to have the -+ * real value, to have an easy handling afterwards here in this -+ * function. -+ */ -+ if (mptcp_is_data_fin(skb) && skb->len == 0) -+ sub_seq = TCP_SKB_CB(skb)->seq; -+ -+ /* If there is already a mapping - we check if it maps with the current -+ * one. If not - we reset. -+ */ -+ if (tp->mptcp->mapping_present && -+ (data_seq != (u32)tp->mptcp->map_data_seq || -+ sub_seq != tp->mptcp->map_subseq || -+ data_len != tp->mptcp->map_data_len + tp->mptcp->map_data_fin || -+ mptcp_is_data_fin(skb) != tp->mptcp->map_data_fin)) { -+ /* Mapping in packet is different from what we want */ -+ pr_err("%s Mappings do not match!\n", __func__); -+ pr_err("%s dseq %u mdseq %u, sseq %u msseq %u dlen %u mdlen %u dfin %d mdfin %d\n", -+ __func__, data_seq, (u32)tp->mptcp->map_data_seq, -+ sub_seq, tp->mptcp->map_subseq, data_len, -+ tp->mptcp->map_data_len, mptcp_is_data_fin(skb), -+ tp->mptcp->map_data_fin); -+ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_DSSNOMATCH); -+ mptcp_send_reset(sk); -+ return 1; -+ } -+ -+ /* If the previous check was good, the current mapping is valid and we exit. */ -+ if (tp->mptcp->mapping_present) -+ return 0; -+ -+ /* Mapping not yet set on this subflow - we set it here! */ -+ -+ if (!data_len) { -+ mpcb->infinite_mapping_rcv = 1; -+ mpcb->send_infinite_mapping = 1; -+ tp->mptcp->fully_established = 1; -+ /* We need to repeat mp_fail's until the sender felt -+ * back to infinite-mapping - here we stop repeating it. -+ */ -+ tp->mptcp->send_mp_fail = 0; -+ -+ /* We have to fixup data_len - it must be the same as skb->len */ -+ data_len = skb->len + (mptcp_is_data_fin(skb) ? 1 : 0); -+ sub_seq = tcb->seq; -+ -+ mptcp_restart_sending(tp->meta_sk); -+ -+ mptcp_sub_force_close_all(mpcb, sk); -+ -+ /* data_seq and so on are set correctly */ -+ -+ /* At this point, the meta-ofo-queue has to be emptied, -+ * as the following data is guaranteed to be in-order at -+ * the data and subflow-level -+ */ -+ skb_rbtree_purge(&meta_tp->out_of_order_queue); -+ -+ set_infinite_rcv = true; -+ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_INFINITEMAPRX); -+ } -+ -+ /* We are sending mp-fail's and thus are in fallback mode. -+ * Ignore packets which do not announce the fallback and still -+ * want to provide a mapping. -+ */ -+ if (tp->mptcp->send_mp_fail) { -+ tp->copied_seq = TCP_SKB_CB(skb)->end_seq; -+ __skb_unlink(skb, &sk->sk_receive_queue); -+ __kfree_skb(skb); -+ return -1; -+ } -+ -+ /* FIN increased the mapping-length by 1 */ -+ if (mptcp_is_data_fin(skb)) -+ data_len--; -+ -+ /* Subflow-sequences of packet must be -+ * (at least partially) be part of the DSS-mapping's -+ * subflow-sequence-space. -+ * -+ * Basically the mapping is not valid, if either of the -+ * following conditions is true: -+ * -+ * 1. It's not a data_fin and -+ * MPTCP-sub_seq >= TCP-end_seq -+ * -+ * 2. It's a data_fin and TCP-end_seq > TCP-seq and -+ * MPTCP-sub_seq >= TCP-end_seq -+ * -+ * The previous two can be merged into: -+ * TCP-end_seq > TCP-seq and MPTCP-sub_seq >= TCP-end_seq -+ * Because if it's not a data-fin, TCP-end_seq > TCP-seq -+ * -+ * 3. It's a data_fin and skb->len == 0 and -+ * MPTCP-sub_seq > TCP-end_seq -+ * -+ * 4. It's not a data_fin and TCP-end_seq > TCP-seq and -+ * MPTCP-sub_seq + MPTCP-data_len <= TCP-seq -+ */ -+ -+ /* subflow-fin is not part of the mapping - ignore it here ! */ -+ tcp_end_seq = tcb->end_seq; -+ if (tcb->tcp_flags & TCPHDR_FIN) -+ tcp_end_seq--; -+ if ((!before(sub_seq, tcb->end_seq) && after(tcp_end_seq, tcb->seq)) || -+ (mptcp_is_data_fin(skb) && skb->len == 0 && after(sub_seq, tcb->end_seq)) || -+ (!after(sub_seq + data_len, tcb->seq) && after(tcp_end_seq, tcb->seq))) { -+ /* Subflow-sequences of packet is different from what is in the -+ * packet's dss-mapping. The peer is misbehaving - reset -+ */ -+ pr_err("%s Packet's mapping does not map to the DSS sub_seq %u " -+ "end_seq %u, tcp_end_seq %u seq %u dfin %u len %u data_len %u" -+ "copied_seq %u\n", __func__, sub_seq, tcb->end_seq, tcp_end_seq, tcb->seq, mptcp_is_data_fin(skb), -+ skb->len, data_len, tp->copied_seq); -+ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_DSSTCPMISMATCH); -+ mptcp_send_reset(sk); -+ return 1; -+ } -+ -+ /* Does the DSS had 64-bit seqnum's ? */ -+ if (!(tcb->mptcp_flags & MPTCPHDR_SEQ64_SET)) { -+ /* Wrapped around? */ -+ if (unlikely(after(data_seq, meta_tp->rcv_nxt) && data_seq < meta_tp->rcv_nxt)) { -+ tp->mptcp->map_data_seq = mptcp_get_data_seq_64(mpcb, !mpcb->rcv_hiseq_index, data_seq); -+ } else { -+ /* Else, access the default high-order bits */ -+ tp->mptcp->map_data_seq = mptcp_get_data_seq_64(mpcb, mpcb->rcv_hiseq_index, data_seq); -+ } -+ } else { -+ tp->mptcp->map_data_seq = mptcp_get_data_seq_64(mpcb, (tcb->mptcp_flags & MPTCPHDR_SEQ64_INDEX) ? 1 : 0, data_seq); -+ -+ if (unlikely(tcb->mptcp_flags & MPTCPHDR_SEQ64_OFO)) { -+ /* We make sure that the data_seq is invalid. -+ * It will be dropped later. -+ */ -+ tp->mptcp->map_data_seq += 0xFFFFFFFF; -+ tp->mptcp->map_data_seq += 0xFFFFFFFF; -+ } -+ } -+ -+ if (set_infinite_rcv) -+ mpcb->infinite_rcv_seq = tp->mptcp->map_data_seq; -+ -+ tp->mptcp->map_data_len = data_len; -+ tp->mptcp->map_subseq = sub_seq; -+ tp->mptcp->map_data_fin = mptcp_is_data_fin(skb) ? 1 : 0; -+ tp->mptcp->mapping_present = 1; -+ -+ return 0; -+} -+ -+/* Similar to tcp_sequence(...) */ -+static inline bool mptcp_sequence(const struct tcp_sock *meta_tp, -+ u64 data_seq, u64 end_data_seq) -+{ -+ const struct mptcp_cb *mpcb = meta_tp->mpcb; -+ u64 rcv_wup64; -+ -+ /* Wrap-around? */ -+ if (meta_tp->rcv_wup > meta_tp->rcv_nxt) { -+ rcv_wup64 = ((u64)(mpcb->rcv_high_order[mpcb->rcv_hiseq_index] - 1) << 32) | -+ meta_tp->rcv_wup; -+ } else { -+ rcv_wup64 = mptcp_get_data_seq_64(mpcb, mpcb->rcv_hiseq_index, -+ meta_tp->rcv_wup); -+ } -+ -+ return !before64(end_data_seq, rcv_wup64) && -+ !after64(data_seq, mptcp_get_rcv_nxt_64(meta_tp) + tcp_receive_window(meta_tp)); -+} -+ -+/* @return: 0 everything is fine. Just continue processing -+ * -1 this packet was broken - continue with the next one. -+ */ -+static int mptcp_validate_mapping(struct sock *sk, struct sk_buff *skb) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct sk_buff *tmp, *tmp1; -+ u32 tcp_end_seq; -+ -+ if (!tp->mptcp->mapping_present) -+ return 0; -+ -+ /* either, the new skb gave us the mapping and the first segment -+ * in the sub-rcv-queue has to be trimmed ... -+ */ -+ tmp = skb_peek(&sk->sk_receive_queue); -+ if (before(TCP_SKB_CB(tmp)->seq, tp->mptcp->map_subseq) && -+ after(TCP_SKB_CB(tmp)->end_seq, tp->mptcp->map_subseq)) { -+ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_DSSTRIMHEAD); -+ mptcp_skb_trim_head(tmp, sk, tp->mptcp->map_subseq); -+ } -+ -+ /* ... or the new skb (tail) has to be split at the end. */ -+ tcp_end_seq = TCP_SKB_CB(skb)->end_seq; -+ if (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN) -+ tcp_end_seq--; -+ if (after(tcp_end_seq, tp->mptcp->map_subseq + tp->mptcp->map_data_len)) { -+ u32 seq = tp->mptcp->map_subseq + tp->mptcp->map_data_len; -+ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_DSSSPLITTAIL); -+ if (mptcp_skb_split_tail(skb, sk, seq)) { /* Allocation failed */ -+ /* TODO : maybe handle this here better. -+ * We now just force meta-retransmission. -+ */ -+ tp->copied_seq = TCP_SKB_CB(skb)->end_seq; -+ __skb_unlink(skb, &sk->sk_receive_queue); -+ __kfree_skb(skb); -+ return -1; -+ } -+ } -+ -+ /* Now, remove old sk_buff's from the receive-queue. -+ * This may happen if the mapping has been lost for these segments and -+ * the next mapping has already been received. -+ */ -+ if (before(TCP_SKB_CB(skb_peek(&sk->sk_receive_queue))->seq, tp->mptcp->map_subseq)) { -+ skb_queue_walk_safe(&sk->sk_receive_queue, tmp1, tmp) { -+ if (!before(TCP_SKB_CB(tmp1)->seq, tp->mptcp->map_subseq)) -+ break; -+ -+ tp->copied_seq = TCP_SKB_CB(tmp1)->end_seq; -+ __skb_unlink(tmp1, &sk->sk_receive_queue); -+ -+ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_PURGEOLD); -+ /* Impossible that we could free skb here, because his -+ * mapping is known to be valid from previous checks -+ */ -+ __kfree_skb(tmp1); -+ } -+ } -+ -+ return 0; -+} -+ -+/* @return: 0 everything is fine. Just continue processing -+ * 1 subflow is broken stop everything -+ * -1 this mapping has been put in the meta-receive-queue -+ * -2 this mapping has been eaten by the application -+ */ -+static int mptcp_queue_skb(struct sock *sk) -+{ -+ struct tcp_sock *tp = tcp_sk(sk), *meta_tp = mptcp_meta_tp(tp); -+ struct sock *meta_sk = mptcp_meta_sk(sk); -+ struct mptcp_cb *mpcb = tp->mpcb; -+ struct sk_buff *tmp, *tmp1; -+ u64 rcv_nxt64 = mptcp_get_rcv_nxt_64(meta_tp); -+ u32 old_copied_seq = tp->copied_seq; -+ bool data_queued = false; -+ -+ /* Have we not yet received the full mapping? */ -+ if (!tp->mptcp->mapping_present || -+ before(tp->rcv_nxt, tp->mptcp->map_subseq + tp->mptcp->map_data_len)) -+ return 0; -+ -+ /* Is this an overlapping mapping? rcv_nxt >= end_data_seq -+ * OR -+ * This mapping is out of window -+ */ -+ if (!before64(rcv_nxt64, tp->mptcp->map_data_seq + tp->mptcp->map_data_len + tp->mptcp->map_data_fin) || -+ !mptcp_sequence(meta_tp, tp->mptcp->map_data_seq, -+ tp->mptcp->map_data_seq + tp->mptcp->map_data_len + tp->mptcp->map_data_fin)) { -+ skb_queue_walk_safe(&sk->sk_receive_queue, tmp1, tmp) { -+ __skb_unlink(tmp1, &sk->sk_receive_queue); -+ tp->copied_seq = TCP_SKB_CB(tmp1)->end_seq; -+ __kfree_skb(tmp1); -+ -+ if (!skb_queue_empty(&sk->sk_receive_queue) && -+ !before(TCP_SKB_CB(tmp)->seq, -+ tp->mptcp->map_subseq + tp->mptcp->map_data_len)) -+ break; -+ } -+ -+ mptcp_reset_mapping(tp, old_copied_seq); -+ -+ return -1; -+ } -+ -+ /* Record it, because we want to send our data_fin on the same path */ -+ if (tp->mptcp->map_data_fin) { -+ mpcb->dfin_path_index = tp->mptcp->path_index; -+ mpcb->dfin_combined = !!(sk->sk_shutdown & RCV_SHUTDOWN); -+ } -+ -+ /* Verify the checksum */ -+ if (mpcb->dss_csum && !mpcb->infinite_mapping_rcv) { -+ int ret = mptcp_verif_dss_csum(sk); -+ -+ if (ret <= 0) { -+ mptcp_reset_mapping(tp, old_copied_seq); -+ return 1; -+ } -+ } -+ -+ if (before64(rcv_nxt64, tp->mptcp->map_data_seq)) { -+ /* Seg's have to go to the meta-ofo-queue */ -+ skb_queue_walk_safe(&sk->sk_receive_queue, tmp1, tmp) { -+ tp->copied_seq = TCP_SKB_CB(tmp1)->end_seq; -+ mptcp_prepare_skb(tmp1, sk); -+ __skb_unlink(tmp1, &sk->sk_receive_queue); -+ /* MUST be done here, because fragstolen may be true later. -+ * Then, kfree_skb_partial will not account the memory. -+ */ -+ skb_orphan(tmp1); -+ -+ if (!mpcb->in_time_wait) /* In time-wait, do not receive data */ -+ tcp_data_queue_ofo(meta_sk, tmp1); -+ else -+ __kfree_skb(tmp1); -+ -+ if (!skb_queue_empty(&sk->sk_receive_queue) && -+ !before(TCP_SKB_CB(tmp)->seq, -+ tp->mptcp->map_subseq + tp->mptcp->map_data_len)) -+ break; -+ } -+ -+ /* Quick ACK if more 3/4 of the receive window is filled */ -+ if (after64(tp->mptcp->map_data_seq, -+ rcv_nxt64 + 3 * (tcp_receive_window(meta_tp) >> 2))) -+ tcp_enter_quickack_mode(sk, TCP_MAX_QUICKACKS); -+ -+ } else { -+ /* Ready for the meta-rcv-queue */ -+ skb_queue_walk_safe(&sk->sk_receive_queue, tmp1, tmp) { -+ int eaten = 0; -+ bool fragstolen = false; -+ u32 old_rcv_nxt = meta_tp->rcv_nxt; -+ -+ tp->copied_seq = TCP_SKB_CB(tmp1)->end_seq; -+ mptcp_prepare_skb(tmp1, sk); -+ __skb_unlink(tmp1, &sk->sk_receive_queue); -+ /* MUST be done here, because fragstolen may be true. -+ * Then, kfree_skb_partial will not account the memory. -+ */ -+ skb_orphan(tmp1); -+ -+ /* This segment has already been received */ -+ if (!after(TCP_SKB_CB(tmp1)->end_seq, meta_tp->rcv_nxt)) { -+ __kfree_skb(tmp1); -+ goto next; -+ } -+ -+ /* Is direct copy possible ? */ -+ if (TCP_SKB_CB(tmp1)->seq == meta_tp->rcv_nxt && -+ meta_tp->ucopy.task == current && -+ meta_tp->copied_seq == meta_tp->rcv_nxt && -+ meta_tp->ucopy.len && sock_owned_by_user(meta_sk)) -+ eaten = mptcp_direct_copy(tmp1, meta_sk); -+ -+ if (mpcb->in_time_wait) /* In time-wait, do not receive data */ -+ eaten = 1; -+ -+ if (!eaten) -+ eaten = tcp_queue_rcv(meta_sk, tmp1, 0, &fragstolen); -+ -+ meta_tp->rcv_nxt = TCP_SKB_CB(tmp1)->end_seq; -+ -+ if (TCP_SKB_CB(tmp1)->tcp_flags & TCPHDR_FIN) -+ mptcp_fin(meta_sk); -+ -+ /* Check if this fills a gap in the ofo queue */ -+ if (!RB_EMPTY_ROOT(&meta_tp->out_of_order_queue)) -+ tcp_ofo_queue(meta_sk); -+ -+ mptcp_check_rcvseq_wrap(meta_tp, old_rcv_nxt); -+ -+ if (eaten) -+ kfree_skb_partial(tmp1, fragstolen); -+ -+ data_queued = true; -+next: -+ if (!skb_queue_empty(&sk->sk_receive_queue) && -+ !before(TCP_SKB_CB(tmp)->seq, -+ tp->mptcp->map_subseq + tp->mptcp->map_data_len)) -+ break; -+ } -+ } -+ -+ inet_csk(meta_sk)->icsk_ack.lrcvtime = tcp_time_stamp; -+ mptcp_reset_mapping(tp, old_copied_seq); -+ -+ return data_queued ? -1 : -2; -+} -+ -+void mptcp_data_ready(struct sock *sk) -+{ -+ struct sock *meta_sk = mptcp_meta_sk(sk); -+ struct sk_buff *skb, *tmp; -+ int queued = 0; -+ -+ /* restart before the check, because mptcp_fin might have changed the -+ * state. -+ */ -+restart: -+ /* If the meta cannot receive data, there is no point in pushing data. -+ * If we are in time-wait, we may still be waiting for the final FIN. -+ * So, we should proceed with the processing. -+ */ -+ if (!mptcp_sk_can_recv(meta_sk) && !tcp_sk(sk)->mpcb->in_time_wait) { -+ skb_queue_purge(&sk->sk_receive_queue); -+ tcp_sk(sk)->copied_seq = tcp_sk(sk)->rcv_nxt; -+ goto exit; -+ } -+ -+ /* Iterate over all segments, detect their mapping (if we don't have -+ * one yet), validate them and push everything one level higher. -+ */ -+ skb_queue_walk_safe(&sk->sk_receive_queue, skb, tmp) { -+ int ret; -+ /* Pre-validation - e.g., early fallback */ -+ ret = mptcp_prevalidate_skb(sk, skb); -+ if (ret < 0) -+ goto restart; -+ else if (ret > 0) -+ break; -+ -+ /* Set the current mapping */ -+ ret = mptcp_detect_mapping(sk, skb); -+ if (ret < 0) -+ goto restart; -+ else if (ret > 0) -+ break; -+ -+ /* Validation */ -+ if (mptcp_validate_mapping(sk, skb) < 0) -+ goto restart; -+ -+ /* Push a level higher */ -+ ret = mptcp_queue_skb(sk); -+ if (ret < 0) { -+ if (ret == -1) -+ queued = ret; -+ goto restart; -+ } else if (ret == 0) { -+ continue; -+ } else { /* ret == 1 */ -+ break; -+ } -+ } -+ -+exit: -+ if (tcp_sk(sk)->close_it && sk->sk_state == TCP_FIN_WAIT2) { -+ tcp_send_ack(sk); -+ tcp_sk(sk)->ops->time_wait(sk, TCP_TIME_WAIT, 0); -+ } -+ -+ if (queued == -1 && !sock_flag(meta_sk, SOCK_DEAD)) -+ meta_sk->sk_data_ready(meta_sk); -+} -+ -+struct mp_join *mptcp_find_join(const struct sk_buff *skb) -+{ -+ const struct tcphdr *th = tcp_hdr(skb); -+ unsigned char *ptr; -+ int length = (th->doff * 4) - sizeof(struct tcphdr); -+ -+ /* Jump through the options to check whether JOIN is there */ -+ ptr = (unsigned char *)(th + 1); -+ while (length > 0) { -+ int opcode = *ptr++; -+ int opsize; -+ -+ switch (opcode) { -+ case TCPOPT_EOL: -+ return NULL; -+ case TCPOPT_NOP: /* Ref: RFC 793 section 3.1 */ -+ length--; -+ continue; -+ default: -+ opsize = *ptr++; -+ if (opsize < 2) /* "silly options" */ -+ return NULL; -+ if (opsize > length) -+ return NULL; /* don't parse partial options */ -+ if (opcode == TCPOPT_MPTCP && -+ ((struct mptcp_option *)(ptr - 2))->sub == MPTCP_SUB_JOIN) { -+ return (struct mp_join *)(ptr - 2); -+ } -+ ptr += opsize - 2; -+ length -= opsize; -+ } -+ } -+ return NULL; -+} -+ -+int mptcp_lookup_join(struct sk_buff *skb, struct inet_timewait_sock *tw) -+{ -+ const struct mptcp_cb *mpcb; -+ struct sock *meta_sk; -+ u32 token; -+ bool meta_v4; -+ struct mp_join *join_opt = mptcp_find_join(skb); -+ if (!join_opt) -+ return 0; -+ -+ /* MPTCP structures were not initialized, so return error */ -+ if (mptcp_init_failed) -+ return -1; -+ -+ token = join_opt->u.syn.token; -+ meta_sk = mptcp_hash_find(dev_net(skb_dst(skb)->dev), token); -+ if (!meta_sk) { -+ MPTCP_INC_STATS(dev_net(skb_dst(skb)->dev), MPTCP_MIB_JOINNOTOKEN); -+ mptcp_debug("%s:mpcb not found:%x\n", __func__, token); -+ return -1; -+ } -+ -+ meta_v4 = meta_sk->sk_family == AF_INET; -+ if (meta_v4) { -+ if (skb->protocol == htons(ETH_P_IPV6)) { -+ mptcp_debug("SYN+MP_JOIN with IPV6 address on pure IPV4 meta\n"); -+ sock_put(meta_sk); /* Taken by mptcp_hash_find */ -+ return -1; -+ } -+ } else if (skb->protocol == htons(ETH_P_IP) && meta_sk->sk_ipv6only) { -+ mptcp_debug("SYN+MP_JOIN with IPV4 address on IPV6_V6ONLY meta\n"); -+ sock_put(meta_sk); /* Taken by mptcp_hash_find */ -+ return -1; -+ } -+ -+ mpcb = tcp_sk(meta_sk)->mpcb; -+ if (mpcb->infinite_mapping_rcv || mpcb->send_infinite_mapping) { -+ /* We are in fallback-mode on the reception-side - -+ * no new subflows! -+ */ -+ sock_put(meta_sk); /* Taken by mptcp_hash_find */ -+ MPTCP_INC_STATS(sock_net(meta_sk), MPTCP_MIB_JOINFALLBACK); -+ return -1; -+ } -+ -+ /* Coming from time-wait-sock processing in tcp_v4_rcv. -+ * We have to deschedule it before continuing, because otherwise -+ * mptcp_v4_do_rcv will hit again on it inside tcp_v4_hnd_req. -+ */ -+ if (tw) -+ inet_twsk_deschedule_put(tw); -+ -+ /* OK, this is a new syn/join, let's create a new open request and -+ * send syn+ack -+ */ -+ bh_lock_sock_nested(meta_sk); -+ if (sock_owned_by_user(meta_sk)) { -+ if (unlikely(sk_add_backlog(meta_sk, skb, -+ meta_sk->sk_rcvbuf + meta_sk->sk_sndbuf))) { -+ bh_unlock_sock(meta_sk); -+ __NET_INC_STATS(sock_net(meta_sk), -+ LINUX_MIB_TCPBACKLOGDROP); -+ sock_put(meta_sk); /* Taken by mptcp_hash_find */ -+ kfree_skb(skb); -+ return 1; -+ } -+ } else if (skb->protocol == htons(ETH_P_IP)) { -+ tcp_v4_do_rcv(meta_sk, skb); -+#if IS_ENABLED(CONFIG_IPV6) -+ } else { -+ tcp_v6_do_rcv(meta_sk, skb); -+#endif /* CONFIG_IPV6 */ -+ } -+ bh_unlock_sock(meta_sk); -+ sock_put(meta_sk); /* Taken by mptcp_hash_find */ -+ return 1; -+} -+ -+int mptcp_do_join_short(struct sk_buff *skb, -+ const struct mptcp_options_received *mopt, -+ struct net *net) -+{ -+ struct sock *meta_sk; -+ u32 token; -+ bool meta_v4; -+ -+ token = mopt->mptcp_rem_token; -+ meta_sk = mptcp_hash_find(net, token); -+ if (!meta_sk) { -+ MPTCP_INC_STATS(dev_net(skb_dst(skb)->dev), MPTCP_MIB_JOINNOTOKEN); -+ mptcp_debug("%s:mpcb not found:%x\n", __func__, token); -+ return -1; -+ } -+ -+ meta_v4 = meta_sk->sk_family == AF_INET; -+ if (meta_v4) { -+ if (skb->protocol == htons(ETH_P_IPV6)) { -+ mptcp_debug("SYN+MP_JOIN with IPV6 address on pure IPV4 meta\n"); -+ sock_put(meta_sk); /* Taken by mptcp_hash_find */ -+ return -1; -+ } -+ } else if (skb->protocol == htons(ETH_P_IP) && meta_sk->sk_ipv6only) { -+ mptcp_debug("SYN+MP_JOIN with IPV4 address on IPV6_V6ONLY meta\n"); -+ sock_put(meta_sk); /* Taken by mptcp_hash_find */ -+ return -1; -+ } -+ -+ /* OK, this is a new syn/join, let's create a new open request and -+ * send syn+ack -+ */ -+ bh_lock_sock(meta_sk); -+ -+ /* This check is also done in mptcp_vX_do_rcv. But, there we cannot -+ * call tcp_vX_send_reset, because we hold already two socket-locks. -+ * (the listener and the meta from above) -+ * -+ * And the send-reset will try to take yet another one (ip_send_reply). -+ * Thus, we propagate the reset up to tcp_rcv_state_process. -+ */ -+ if (tcp_sk(meta_sk)->mpcb->infinite_mapping_rcv || -+ tcp_sk(meta_sk)->mpcb->send_infinite_mapping || -+ meta_sk->sk_state == TCP_CLOSE || !tcp_sk(meta_sk)->inside_tk_table) { -+ MPTCP_INC_STATS(sock_net(meta_sk), MPTCP_MIB_JOINFALLBACK); -+ bh_unlock_sock(meta_sk); -+ sock_put(meta_sk); /* Taken by mptcp_hash_find */ -+ return -1; -+ } -+ -+ if (sock_owned_by_user(meta_sk)) { -+ if (unlikely(sk_add_backlog(meta_sk, skb, -+ meta_sk->sk_rcvbuf + meta_sk->sk_sndbuf))) -+ __NET_INC_STATS(net, LINUX_MIB_TCPBACKLOGDROP); -+ else -+ /* Must make sure that upper layers won't free the -+ * skb if it is added to the backlog-queue. -+ */ -+ skb_get(skb); -+ } else { -+ /* mptcp_v4_do_rcv tries to free the skb - we prevent this, as -+ * the skb will finally be freed by tcp_v4_do_rcv (where we are -+ * coming from) -+ */ -+ skb_get(skb); -+ if (skb->protocol == htons(ETH_P_IP)) { -+ tcp_v4_do_rcv(meta_sk, skb); -+#if IS_ENABLED(CONFIG_IPV6) -+ } else { /* IPv6 */ -+ tcp_v6_do_rcv(meta_sk, skb); -+#endif /* CONFIG_IPV6 */ -+ } -+ } -+ -+ bh_unlock_sock(meta_sk); -+ sock_put(meta_sk); /* Taken by mptcp_hash_find */ -+ return 0; -+} -+ -+/** -+ * Equivalent of tcp_fin() for MPTCP -+ * Can be called only when the FIN is validly part -+ * of the data seqnum space. Not before when we get holes. -+ */ -+void mptcp_fin(struct sock *meta_sk) -+{ -+ struct sock *sk = NULL, *sk_it; -+ struct tcp_sock *meta_tp = tcp_sk(meta_sk); -+ struct mptcp_cb *mpcb = meta_tp->mpcb; -+ unsigned char state; -+ -+ mptcp_for_each_sk(mpcb, sk_it) { -+ if (tcp_sk(sk_it)->mptcp->path_index == mpcb->dfin_path_index) { -+ sk = sk_it; -+ break; -+ } -+ } -+ -+ if (!sk || sk->sk_state == TCP_CLOSE) -+ sk = mptcp_select_ack_sock(meta_sk); -+ -+ inet_csk_schedule_ack(sk); -+ -+ if (!mpcb->in_time_wait) { -+ meta_sk->sk_shutdown |= RCV_SHUTDOWN; -+ sock_set_flag(meta_sk, SOCK_DONE); -+ state = meta_sk->sk_state; -+ } else { -+ state = mpcb->mptw_state; -+ } -+ -+ switch (state) { -+ case TCP_SYN_RECV: -+ case TCP_ESTABLISHED: -+ /* Move to CLOSE_WAIT */ -+ tcp_set_state(meta_sk, TCP_CLOSE_WAIT); -+ inet_csk(sk)->icsk_ack.pingpong = 1; -+ break; -+ -+ case TCP_CLOSE_WAIT: -+ case TCP_CLOSING: -+ /* Received a retransmission of the FIN, do -+ * nothing. -+ */ -+ break; -+ case TCP_LAST_ACK: -+ /* RFC793: Remain in the LAST-ACK state. */ -+ break; -+ -+ case TCP_FIN_WAIT1: -+ /* This case occurs when a simultaneous close -+ * happens, we must ack the received FIN and -+ * enter the CLOSING state. -+ */ -+ tcp_send_ack(sk); -+ tcp_set_state(meta_sk, TCP_CLOSING); -+ break; -+ case TCP_FIN_WAIT2: -+ /* Received a FIN -- send ACK and enter TIME_WAIT. */ -+ tcp_send_ack(sk); -+ meta_tp->ops->time_wait(meta_sk, TCP_TIME_WAIT, 0); -+ break; -+ default: -+ /* Only TCP_LISTEN and TCP_CLOSE are left, in these -+ * cases we should never reach this piece of code. -+ */ -+ pr_err("%s: Impossible, meta_sk->sk_state=%d\n", __func__, -+ meta_sk->sk_state); -+ break; -+ } -+ -+ /* It _is_ possible, that we have something out-of-order _after_ FIN. -+ * Probably, we should reset in this case. For now drop them. -+ */ -+ skb_rbtree_purge(&meta_tp->out_of_order_queue); -+ sk_mem_reclaim(meta_sk); -+ -+ if (!sock_flag(meta_sk, SOCK_DEAD)) { -+ meta_sk->sk_state_change(meta_sk); -+ -+ /* Do not send POLL_HUP for half duplex close. */ -+ if (meta_sk->sk_shutdown == SHUTDOWN_MASK || -+ meta_sk->sk_state == TCP_CLOSE) -+ sk_wake_async(meta_sk, SOCK_WAKE_WAITD, POLL_HUP); -+ else -+ sk_wake_async(meta_sk, SOCK_WAKE_WAITD, POLL_IN); -+ } -+ -+ return; -+} -+ -+static void mptcp_xmit_retransmit_queue(struct sock *meta_sk) -+{ -+ struct tcp_sock *meta_tp = tcp_sk(meta_sk); -+ struct sk_buff *skb; -+ -+ if (!meta_tp->packets_out) -+ return; -+ -+ tcp_for_write_queue(skb, meta_sk) { -+ if (skb == tcp_send_head(meta_sk)) -+ break; -+ -+ if (mptcp_retransmit_skb(meta_sk, skb)) -+ return; -+ -+ if (skb == tcp_write_queue_head(meta_sk)) -+ inet_csk_reset_xmit_timer(meta_sk, ICSK_TIME_RETRANS, -+ inet_csk(meta_sk)->icsk_rto, -+ TCP_RTO_MAX); -+ } -+} -+ -+static void mptcp_snd_una_update(struct tcp_sock *meta_tp, u32 data_ack) -+{ -+ u32 delta = data_ack - meta_tp->snd_una; -+ -+ u64_stats_update_begin(&meta_tp->syncp); -+ meta_tp->bytes_acked += delta; -+ u64_stats_update_end(&meta_tp->syncp); -+ meta_tp->snd_una = data_ack; -+} -+ -+/* Handle the DATA_ACK */ -+static void mptcp_data_ack(struct sock *sk, const struct sk_buff *skb) -+{ -+ struct sock *meta_sk = mptcp_meta_sk(sk); -+ struct tcp_sock *meta_tp = tcp_sk(meta_sk), *tp = tcp_sk(sk); -+ struct tcp_skb_cb *tcb = TCP_SKB_CB(skb); -+ u32 prior_snd_una = meta_tp->snd_una; -+ int prior_packets; -+ u32 nwin, data_ack, data_seq; -+ u16 data_len = 0; -+ -+ /* A valid packet came in - subflow is operational again */ -+ tp->pf = 0; -+ -+ /* Even if there is no data-ack, we stop retransmitting. -+ * Except if this is a SYN/ACK. Then it is just a retransmission -+ */ -+ if (tp->mptcp->pre_established && !tcp_hdr(skb)->syn) { -+ tp->mptcp->pre_established = 0; -+ sk_stop_timer(sk, &tp->mptcp->mptcp_ack_timer); -+ } -+ -+ /* If we are in infinite mapping mode, rx_opt.data_ack has been -+ * set by mptcp_clean_rtx_infinite. -+ */ -+ if (!(tcb->mptcp_flags & MPTCPHDR_ACK) && !tp->mpcb->infinite_mapping_snd) -+ return; -+ -+ if (unlikely(!tp->mptcp->fully_established) && -+ tp->mptcp->snt_isn + 1 != TCP_SKB_CB(skb)->ack_seq) -+ /* As soon as a subflow-data-ack (not acking syn, thus snt_isn + 1) -+ * includes a data-ack, we are fully established -+ */ -+ mptcp_become_fully_estab(sk); -+ -+ /* After we did the subflow-only processing (stopping timer and marking -+ * subflow as established), check if we can proceed with MPTCP-level -+ * processing. -+ */ -+ if (meta_sk->sk_state == TCP_CLOSE) -+ return; -+ -+ /* Get the data_seq */ -+ if (mptcp_is_data_seq(skb)) { -+ data_seq = tp->mptcp->rx_opt.data_seq; -+ data_len = tp->mptcp->rx_opt.data_len; -+ } else { -+ data_seq = meta_tp->snd_wl1; -+ } -+ -+ data_ack = tp->mptcp->rx_opt.data_ack; -+ -+ /* If the ack is older than previous acks -+ * then we can probably ignore it. -+ */ -+ if (before(data_ack, prior_snd_una)) -+ goto exit; -+ -+ /* If the ack includes data we haven't sent yet, discard -+ * this segment (RFC793 Section 3.9). -+ */ -+ if (after(data_ack, meta_tp->snd_nxt)) -+ goto exit; -+ -+ /*** Now, update the window - inspired by tcp_ack_update_window ***/ -+ nwin = ntohs(tcp_hdr(skb)->window); -+ -+ if (likely(!tcp_hdr(skb)->syn)) -+ nwin <<= tp->rx_opt.snd_wscale; -+ -+ if (tcp_may_update_window(meta_tp, data_ack, data_seq, nwin)) { -+ tcp_update_wl(meta_tp, data_seq); -+ -+ /* Draft v09, Section 3.3.5: -+ * [...] It should only update its local receive window values -+ * when the largest sequence number allowed (i.e. DATA_ACK + -+ * receive window) increases. [...] -+ */ -+ if (meta_tp->snd_wnd != nwin && -+ !before(data_ack + nwin, tcp_wnd_end(meta_tp))) { -+ meta_tp->snd_wnd = nwin; -+ -+ if (nwin > meta_tp->max_window) -+ meta_tp->max_window = nwin; -+ } -+ } -+ /*** Done, update the window ***/ -+ -+ /* We passed data and got it acked, remove any soft error -+ * log. Something worked... -+ */ -+ sk->sk_err_soft = 0; -+ inet_csk(meta_sk)->icsk_probes_out = 0; -+ meta_tp->rcv_tstamp = tcp_time_stamp; -+ prior_packets = meta_tp->packets_out; -+ if (!prior_packets) -+ goto no_queue; -+ -+ mptcp_snd_una_update(meta_tp, data_ack); -+ -+ mptcp_clean_rtx_queue(meta_sk, prior_snd_una); -+ -+ /* We are in loss-state, and something got acked, retransmit the whole -+ * queue now! -+ */ -+ if (inet_csk(meta_sk)->icsk_ca_state == TCP_CA_Loss && -+ after(data_ack, prior_snd_una)) { -+ mptcp_xmit_retransmit_queue(meta_sk); -+ inet_csk(meta_sk)->icsk_ca_state = TCP_CA_Open; -+ } -+ -+ /* Simplified version of tcp_new_space, because the snd-buffer -+ * is handled by all the subflows. -+ */ -+ if (sock_flag(meta_sk, SOCK_QUEUE_SHRUNK)) { -+ sock_reset_flag(meta_sk, SOCK_QUEUE_SHRUNK); -+ if (meta_sk->sk_socket && -+ test_bit(SOCK_NOSPACE, &meta_sk->sk_socket->flags)) -+ meta_sk->sk_write_space(meta_sk); -+ } -+ -+ if (meta_sk->sk_state != TCP_ESTABLISHED && -+ mptcp_rcv_state_process(meta_sk, sk, skb, data_seq, data_len)) -+ return; -+ -+exit: -+ mptcp_push_pending_frames(meta_sk); -+ -+ return; -+ -+no_queue: -+ if (tcp_send_head(meta_sk)) -+ tcp_ack_probe(meta_sk); -+ -+ mptcp_push_pending_frames(meta_sk); -+ -+ return; -+} -+ -+void mptcp_clean_rtx_infinite(const struct sk_buff *skb, struct sock *sk) -+{ -+ struct tcp_sock *tp = tcp_sk(sk), *meta_tp = tcp_sk(mptcp_meta_sk(sk)); -+ -+ if (!tp->mpcb->infinite_mapping_snd) -+ return; -+ -+ /* The difference between both write_seq's represents the offset between -+ * data-sequence and subflow-sequence. As we are infinite, this must -+ * match. -+ * -+ * Thus, from this difference we can infer the meta snd_una. -+ */ -+ tp->mptcp->rx_opt.data_ack = meta_tp->snd_nxt - tp->snd_nxt + -+ tp->snd_una; -+ -+ mptcp_data_ack(sk, skb); -+} -+ -+/**** static functions used by mptcp_parse_options */ -+ -+static void mptcp_send_reset_rem_id(const struct mptcp_cb *mpcb, u8 rem_id) -+{ -+ struct sock *sk_it, *tmpsk; -+ -+ mptcp_for_each_sk_safe(mpcb, sk_it, tmpsk) { -+ if (tcp_sk(sk_it)->mptcp->rem_id == rem_id) { -+ mptcp_reinject_data(sk_it, 0); -+ mptcp_send_reset(sk_it); -+ } -+ } -+} -+ -+static inline bool is_valid_addropt_opsize(u8 mptcp_ver, -+ struct mp_add_addr *mpadd, -+ int opsize) -+{ -+#if IS_ENABLED(CONFIG_IPV6) -+ if (mptcp_ver < MPTCP_VERSION_1 && mpadd->ipver == 6) { -+ return opsize == MPTCP_SUB_LEN_ADD_ADDR6 || -+ opsize == MPTCP_SUB_LEN_ADD_ADDR6 + 2; -+ } -+ if (mptcp_ver >= MPTCP_VERSION_1 && mpadd->ipver == 6) -+ return opsize == MPTCP_SUB_LEN_ADD_ADDR6_VER1 || -+ opsize == MPTCP_SUB_LEN_ADD_ADDR6_VER1 + 2; -+#endif -+ if (mptcp_ver < MPTCP_VERSION_1 && mpadd->ipver == 4) { -+ return opsize == MPTCP_SUB_LEN_ADD_ADDR4 || -+ opsize == MPTCP_SUB_LEN_ADD_ADDR4 + 2; -+ } -+ if (mptcp_ver >= MPTCP_VERSION_1 && mpadd->ipver == 4) { -+ return opsize == MPTCP_SUB_LEN_ADD_ADDR4_VER1 || -+ opsize == MPTCP_SUB_LEN_ADD_ADDR4_VER1 + 2; -+ } -+ return false; -+} -+ -+void mptcp_parse_options(const uint8_t *ptr, int opsize, -+ struct mptcp_options_received *mopt, -+ const struct sk_buff *skb, -+ struct tcp_sock *tp) -+{ -+ const struct mptcp_option *mp_opt = (struct mptcp_option *)ptr; -+ -+ /* If the socket is mp-capable we would have a mopt. */ -+ if (!mopt) -+ return; -+ -+ switch (mp_opt->sub) { -+ case MPTCP_SUB_CAPABLE: -+ { -+ const struct mp_capable *mpcapable = (struct mp_capable *)ptr; -+ -+ if (opsize != MPTCP_SUB_LEN_CAPABLE_SYN && -+ opsize != MPTCP_SUB_LEN_CAPABLE_ACK) { -+ mptcp_debug("%s: mp_capable: bad option size %d\n", -+ __func__, opsize); -+ break; -+ } -+ -+ /* MPTCP-RFC 6824: -+ * "If receiving a message with the 'B' flag set to 1, and this -+ * is not understood, then this SYN MUST be silently ignored; -+ */ -+ if (mpcapable->b) { -+ mopt->drop_me = 1; -+ break; -+ } -+ -+ /* MPTCP-RFC 6824: -+ * "An implementation that only supports this method MUST set -+ * bit "H" to 1, and bits "C" through "G" to 0." -+ */ -+ if (!mpcapable->h) -+ break; -+ -+ mopt->saw_mpc = 1; -+ mopt->dss_csum = sysctl_mptcp_checksum || mpcapable->a; -+ -+ if (opsize >= MPTCP_SUB_LEN_CAPABLE_SYN) -+ mopt->mptcp_sender_key = mpcapable->sender_key; -+ if (opsize == MPTCP_SUB_LEN_CAPABLE_ACK) -+ mopt->mptcp_receiver_key = mpcapable->receiver_key; -+ -+ mopt->mptcp_ver = mpcapable->ver; -+ break; -+ } -+ case MPTCP_SUB_JOIN: -+ { -+ const struct mp_join *mpjoin = (struct mp_join *)ptr; -+ -+ if (opsize != MPTCP_SUB_LEN_JOIN_SYN && -+ opsize != MPTCP_SUB_LEN_JOIN_SYNACK && -+ opsize != MPTCP_SUB_LEN_JOIN_ACK) { -+ mptcp_debug("%s: mp_join: bad option size %d\n", -+ __func__, opsize); -+ break; -+ } -+ -+ /* saw_mpc must be set, because in tcp_check_req we assume that -+ * it is set to support falling back to reg. TCP if a rexmitted -+ * SYN has no MP_CAPABLE or MP_JOIN -+ */ -+ switch (opsize) { -+ case MPTCP_SUB_LEN_JOIN_SYN: -+ mopt->is_mp_join = 1; -+ mopt->saw_mpc = 1; -+ mopt->low_prio = mpjoin->b; -+ mopt->rem_id = mpjoin->addr_id; -+ mopt->mptcp_rem_token = mpjoin->u.syn.token; -+ mopt->mptcp_recv_nonce = mpjoin->u.syn.nonce; -+ break; -+ case MPTCP_SUB_LEN_JOIN_SYNACK: -+ mopt->saw_mpc = 1; -+ mopt->low_prio = mpjoin->b; -+ mopt->rem_id = mpjoin->addr_id; -+ mopt->mptcp_recv_tmac = mpjoin->u.synack.mac; -+ mopt->mptcp_recv_nonce = mpjoin->u.synack.nonce; -+ break; -+ case MPTCP_SUB_LEN_JOIN_ACK: -+ mopt->saw_mpc = 1; -+ mopt->join_ack = 1; -+ memcpy(mopt->mptcp_recv_mac, mpjoin->u.ack.mac, 20); -+ break; -+ } -+ break; -+ } -+ case MPTCP_SUB_DSS: -+ { -+ const struct mp_dss *mdss = (struct mp_dss *)ptr; -+ struct tcp_skb_cb *tcb = TCP_SKB_CB(skb); -+ -+ /* We check opsize for the csum and non-csum case. We do this, -+ * because the draft says that the csum SHOULD be ignored if -+ * it has not been negotiated in the MP_CAPABLE but still is -+ * present in the data. -+ * -+ * It will get ignored later in mptcp_queue_skb. -+ */ -+ if (opsize != mptcp_sub_len_dss(mdss, 0) && -+ opsize != mptcp_sub_len_dss(mdss, 1)) { -+ mptcp_debug("%s: mp_dss: bad option size %d\n", -+ __func__, opsize); -+ break; -+ } -+ -+ ptr += 4; -+ -+ if (mdss->A) { -+ tcb->mptcp_flags |= MPTCPHDR_ACK; -+ -+ if (mdss->a) { -+ mopt->data_ack = (u32) get_unaligned_be64(ptr); -+ ptr += MPTCP_SUB_LEN_ACK_64; -+ } else { -+ mopt->data_ack = get_unaligned_be32(ptr); -+ ptr += MPTCP_SUB_LEN_ACK; -+ } -+ } -+ -+ tcb->dss_off = (ptr - skb_transport_header(skb)); -+ -+ if (mdss->M) { -+ if (mdss->m) { -+ u64 data_seq64 = get_unaligned_be64(ptr); -+ -+ tcb->mptcp_flags |= MPTCPHDR_SEQ64_SET; -+ mopt->data_seq = (u32) data_seq64; -+ -+ ptr += 12; /* 64-bit dseq + subseq */ -+ } else { -+ mopt->data_seq = get_unaligned_be32(ptr); -+ ptr += 8; /* 32-bit dseq + subseq */ -+ } -+ mopt->data_len = get_unaligned_be16(ptr); -+ -+ tcb->mptcp_flags |= MPTCPHDR_SEQ; -+ -+ /* Is a check-sum present? */ -+ if (opsize == mptcp_sub_len_dss(mdss, 1)) -+ tcb->mptcp_flags |= MPTCPHDR_DSS_CSUM; -+ -+ /* DATA_FIN only possible with DSS-mapping */ -+ if (mdss->F) -+ tcb->mptcp_flags |= MPTCPHDR_FIN; -+ } -+ -+ break; -+ } -+ case MPTCP_SUB_ADD_ADDR: -+ { -+ struct mp_add_addr *mpadd = (struct mp_add_addr *)ptr; -+ -+ /* If tcp_sock is not available, MPTCP version can't be -+ * retrieved and ADD_ADDR opsize validation is not possible. -+ */ -+ if (!tp || !tp->mpcb) -+ break; -+ -+ if (!is_valid_addropt_opsize(tp->mpcb->mptcp_ver, -+ mpadd, opsize)) { -+ mptcp_debug("%s: mp_add_addr: bad option size %d\n", -+ __func__, opsize); -+ break; -+ } -+ -+ /* We have to manually parse the options if we got two of them. */ -+ if (mopt->saw_add_addr) { -+ mopt->more_add_addr = 1; -+ break; -+ } -+ mopt->saw_add_addr = 1; -+ mopt->add_addr_ptr = ptr; -+ break; -+ } -+ case MPTCP_SUB_REMOVE_ADDR: -+ if ((opsize - MPTCP_SUB_LEN_REMOVE_ADDR) < 0) { -+ mptcp_debug("%s: mp_remove_addr: bad option size %d\n", -+ __func__, opsize); -+ break; -+ } -+ -+ if (mopt->saw_rem_addr) { -+ mopt->more_rem_addr = 1; -+ break; -+ } -+ mopt->saw_rem_addr = 1; -+ mopt->rem_addr_ptr = ptr; -+ break; -+ case MPTCP_SUB_PRIO: -+ { -+ const struct mp_prio *mpprio = (struct mp_prio *)ptr; -+ -+ if (opsize != MPTCP_SUB_LEN_PRIO && -+ opsize != MPTCP_SUB_LEN_PRIO_ADDR) { -+ mptcp_debug("%s: mp_prio: bad option size %d\n", -+ __func__, opsize); -+ break; -+ } -+ -+ mopt->saw_low_prio = 1; -+ mopt->low_prio = mpprio->b; -+ -+ if (opsize == MPTCP_SUB_LEN_PRIO_ADDR) { -+ mopt->saw_low_prio = 2; -+ mopt->prio_addr_id = mpprio->addr_id; -+ } -+ break; -+ } -+ case MPTCP_SUB_FAIL: -+ if (opsize != MPTCP_SUB_LEN_FAIL) { -+ mptcp_debug("%s: mp_fail: bad option size %d\n", -+ __func__, opsize); -+ break; -+ } -+ mopt->mp_fail = 1; -+ break; -+ case MPTCP_SUB_FCLOSE: -+ if (opsize != MPTCP_SUB_LEN_FCLOSE) { -+ mptcp_debug("%s: mp_fclose: bad option size %d\n", -+ __func__, opsize); -+ break; -+ } -+ -+ mopt->mp_fclose = 1; -+ mopt->mptcp_sender_key = ((struct mp_fclose *)ptr)->key; -+ -+ break; -+ default: -+ mptcp_debug("%s: Received unkown subtype: %d\n", -+ __func__, mp_opt->sub); -+ break; -+ } -+} -+ -+/** Parse only MPTCP options */ -+void tcp_parse_mptcp_options(const struct sk_buff *skb, -+ struct mptcp_options_received *mopt) -+{ -+ const struct tcphdr *th = tcp_hdr(skb); -+ int length = (th->doff * 4) - sizeof(struct tcphdr); -+ const unsigned char *ptr = (const unsigned char *)(th + 1); -+ -+ while (length > 0) { -+ int opcode = *ptr++; -+ int opsize; -+ -+ switch (opcode) { -+ case TCPOPT_EOL: -+ return; -+ case TCPOPT_NOP: /* Ref: RFC 793 section 3.1 */ -+ length--; -+ continue; -+ default: -+ opsize = *ptr++; -+ if (opsize < 2) /* "silly options" */ -+ return; -+ if (opsize > length) -+ return; /* don't parse partial options */ -+ if (opcode == TCPOPT_MPTCP) -+ mptcp_parse_options(ptr - 2, opsize, mopt, skb, NULL); -+ } -+ ptr += opsize - 2; -+ length -= opsize; -+ } -+} -+ -+bool mptcp_check_rtt(const struct tcp_sock *tp, int time) -+{ -+ struct mptcp_cb *mpcb = tp->mpcb; -+ struct sock *sk; -+ u32 rtt_max = 0; -+ -+ /* In MPTCP, we take the max delay across all flows, -+ * in order to take into account meta-reordering buffers. -+ */ -+ mptcp_for_each_sk(mpcb, sk) { -+ if (!mptcp_sk_can_recv(sk)) -+ continue; -+ -+ if (rtt_max < tcp_sk(sk)->rcv_rtt_est.rtt) -+ rtt_max = tcp_sk(sk)->rcv_rtt_est.rtt; -+ } -+ if (time < (rtt_max >> 3) || !rtt_max) -+ return true; -+ -+ return false; -+} -+ -+static void mptcp_handle_add_addr(const unsigned char *ptr, struct sock *sk) -+{ -+ struct mp_add_addr *mpadd = (struct mp_add_addr *)ptr; -+ struct mptcp_cb *mpcb = tcp_sk(sk)->mpcb; -+ __be16 port = 0; -+ union inet_addr addr; -+ sa_family_t family; -+ -+ if (mpadd->ipver == 4) { -+ char *recv_hmac; -+ u8 hash_mac_check[20]; -+ u8 no_key[8]; -+ int msg_parts = 0; -+ -+ if (mpcb->mptcp_ver < MPTCP_VERSION_1) -+ goto skip_hmac_v4; -+ -+ *(u64 *)no_key = 0; -+ recv_hmac = (char *)mpadd->u.v4.mac; -+ if (mpadd->len == MPTCP_SUB_LEN_ADD_ADDR4_VER1) { -+ recv_hmac -= sizeof(mpadd->u.v4.port); -+ msg_parts = 2; -+ } else if (mpadd->len == MPTCP_SUB_LEN_ADD_ADDR4_VER1 + 2) { -+ msg_parts = 3; -+ } -+ mptcp_hmac_sha1((u8 *)&mpcb->mptcp_rem_key, -+ (u8 *)no_key, -+ (u32 *)hash_mac_check, msg_parts, -+ 1, (u8 *)&mpadd->addr_id, -+ 4, (u8 *)&mpadd->u.v4.addr.s_addr, -+ 2, (u8 *)&mpadd->u.v4.port); -+ if (memcmp(hash_mac_check, recv_hmac, 8) != 0) -+ /* ADD_ADDR2 discarded */ -+ return; -+skip_hmac_v4: -+ if ((mpcb->mptcp_ver == MPTCP_VERSION_0 && -+ mpadd->len == MPTCP_SUB_LEN_ADD_ADDR4 + 2) || -+ (mpcb->mptcp_ver == MPTCP_VERSION_1 && -+ mpadd->len == MPTCP_SUB_LEN_ADD_ADDR4_VER1 + 2)) -+ port = mpadd->u.v4.port; -+ family = AF_INET; -+ addr.in = mpadd->u.v4.addr; -+#if IS_ENABLED(CONFIG_IPV6) -+ } else if (mpadd->ipver == 6) { -+ char *recv_hmac; -+ u8 hash_mac_check[20]; -+ u8 no_key[8]; -+ int msg_parts = 0; -+ -+ if (mpcb->mptcp_ver < MPTCP_VERSION_1) -+ goto skip_hmac_v6; -+ -+ *(u64 *)no_key = 0; -+ recv_hmac = (char *)mpadd->u.v6.mac; -+ if (mpadd->len == MPTCP_SUB_LEN_ADD_ADDR6_VER1) { -+ recv_hmac -= sizeof(mpadd->u.v6.port); -+ msg_parts = 2; -+ } else if (mpadd->len == MPTCP_SUB_LEN_ADD_ADDR6_VER1 + 2) { -+ msg_parts = 3; -+ } -+ mptcp_hmac_sha1((u8 *)&mpcb->mptcp_rem_key, -+ (u8 *)no_key, -+ (u32 *)hash_mac_check, msg_parts, -+ 1, (u8 *)&mpadd->addr_id, -+ 16, (u8 *)&mpadd->u.v6.addr.s6_addr, -+ 2, (u8 *)&mpadd->u.v6.port); -+ if (memcmp(hash_mac_check, recv_hmac, 8) != 0) -+ /* ADD_ADDR2 discarded */ -+ return; -+skip_hmac_v6: -+ if ((mpcb->mptcp_ver == MPTCP_VERSION_0 && -+ mpadd->len == MPTCP_SUB_LEN_ADD_ADDR6 + 2) || -+ (mpcb->mptcp_ver == MPTCP_VERSION_1 && -+ mpadd->len == MPTCP_SUB_LEN_ADD_ADDR6_VER1 + 2)) -+ port = mpadd->u.v6.port; -+ family = AF_INET6; -+ addr.in6 = mpadd->u.v6.addr; -+#endif /* CONFIG_IPV6 */ -+ } else { -+ return; -+ } -+ -+ if (mpcb->pm_ops->add_raddr) -+ mpcb->pm_ops->add_raddr(mpcb, &addr, family, port, mpadd->addr_id); -+ -+ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_ADDADDRRX); -+} -+ -+static void mptcp_handle_rem_addr(const unsigned char *ptr, struct sock *sk) -+{ -+ struct mp_remove_addr *mprem = (struct mp_remove_addr *)ptr; -+ int i; -+ u8 rem_id; -+ struct mptcp_cb *mpcb = tcp_sk(sk)->mpcb; -+ -+ for (i = 0; i <= mprem->len - MPTCP_SUB_LEN_REMOVE_ADDR; i++) { -+ rem_id = (&mprem->addrs_id)[i]; -+ -+ if (mpcb->pm_ops->rem_raddr) -+ mpcb->pm_ops->rem_raddr(mpcb, rem_id); -+ mptcp_send_reset_rem_id(mpcb, rem_id); -+ -+ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_REMADDRSUB); -+ } -+ -+ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_REMADDRRX); -+} -+ -+static void mptcp_parse_addropt(const struct sk_buff *skb, struct sock *sk) -+{ -+ struct tcphdr *th = tcp_hdr(skb); -+ unsigned char *ptr; -+ int length = (th->doff * 4) - sizeof(struct tcphdr); -+ -+ /* Jump through the options to check whether ADD_ADDR is there */ -+ ptr = (unsigned char *)(th + 1); -+ while (length > 0) { -+ int opcode = *ptr++; -+ int opsize; -+ -+ switch (opcode) { -+ case TCPOPT_EOL: -+ return; -+ case TCPOPT_NOP: -+ length--; -+ continue; -+ default: -+ opsize = *ptr++; -+ if (opsize < 2) -+ return; -+ if (opsize > length) -+ return; /* don't parse partial options */ -+ if (opcode == TCPOPT_MPTCP && -+ ((struct mptcp_option *)ptr)->sub == MPTCP_SUB_ADD_ADDR) { -+ u8 mptcp_ver = tcp_sk(sk)->mpcb->mptcp_ver; -+ struct mp_add_addr *mpadd = (struct mp_add_addr *)ptr; -+ -+ if (!is_valid_addropt_opsize(mptcp_ver, mpadd, -+ opsize)) -+ goto cont; -+ -+ mptcp_handle_add_addr(ptr, sk); -+ } -+ if (opcode == TCPOPT_MPTCP && -+ ((struct mptcp_option *)ptr)->sub == MPTCP_SUB_REMOVE_ADDR) { -+ if ((opsize - MPTCP_SUB_LEN_REMOVE_ADDR) < 0) -+ goto cont; -+ -+ mptcp_handle_rem_addr(ptr, sk); -+ } -+cont: -+ ptr += opsize - 2; -+ length -= opsize; -+ } -+ } -+ return; -+} -+ -+static bool mptcp_mp_fastclose_rcvd(struct sock *sk) -+{ -+ struct mptcp_tcp_sock *mptcp = tcp_sk(sk)->mptcp; -+ struct mptcp_cb *mpcb = tcp_sk(sk)->mpcb; -+ -+ if (likely(!mptcp->rx_opt.mp_fclose)) -+ return false; -+ -+ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_FASTCLOSERX); -+ mptcp->rx_opt.mp_fclose = 0; -+ if (mptcp->rx_opt.mptcp_sender_key != mpcb->mptcp_loc_key) -+ return false; -+ -+ mptcp_sub_force_close_all(mpcb, NULL); -+ -+ tcp_reset(mptcp_meta_sk(sk)); -+ -+ return true; -+} -+ -+static void mptcp_mp_fail_rcvd(struct sock *sk, const struct tcphdr *th) -+{ -+ struct mptcp_tcp_sock *mptcp = tcp_sk(sk)->mptcp; -+ struct sock *meta_sk = mptcp_meta_sk(sk); -+ struct mptcp_cb *mpcb = tcp_sk(sk)->mpcb; -+ -+ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_MPFAILRX); -+ mptcp->rx_opt.mp_fail = 0; -+ -+ if (!th->rst && !mpcb->infinite_mapping_snd) { -+ mpcb->send_infinite_mapping = 1; -+ -+ mptcp_restart_sending(meta_sk); -+ -+ mptcp_sub_force_close_all(mpcb, sk); -+ } -+} -+ -+static inline void mptcp_path_array_check(struct sock *meta_sk) -+{ -+ struct mptcp_cb *mpcb = tcp_sk(meta_sk)->mpcb; -+ -+ if (unlikely(mpcb->list_rcvd)) { -+ mpcb->list_rcvd = 0; -+ if (mpcb->pm_ops->new_remote_address) -+ mpcb->pm_ops->new_remote_address(meta_sk); -+ } -+} -+ -+bool mptcp_handle_options(struct sock *sk, const struct tcphdr *th, -+ const struct sk_buff *skb) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct mptcp_options_received *mopt = &tp->mptcp->rx_opt; -+ -+ if (tp->mpcb->infinite_mapping_rcv || tp->mpcb->infinite_mapping_snd) -+ return false; -+ -+ if (mptcp_mp_fastclose_rcvd(sk)) -+ return true; -+ -+ if (sk->sk_state == TCP_RST_WAIT && !th->rst) -+ return true; -+ -+ if (unlikely(mopt->mp_fail)) -+ mptcp_mp_fail_rcvd(sk, th); -+ -+ /* RFC 6824, Section 3.3: -+ * If a checksum is not present when its use has been negotiated, the -+ * receiver MUST close the subflow with a RST as it is considered broken. -+ */ -+ if (mptcp_is_data_seq(skb) && tp->mpcb->dss_csum && -+ !(TCP_SKB_CB(skb)->mptcp_flags & MPTCPHDR_DSS_CSUM)) { -+ mptcp_send_reset(sk); -+ return true; -+ } -+ -+ /* We have to acknowledge retransmissions of the third -+ * ack. -+ */ -+ if (mopt->join_ack) { -+ tcp_send_delayed_ack(sk); -+ mopt->join_ack = 0; -+ } -+ -+ if (mopt->saw_add_addr || mopt->saw_rem_addr) { -+ if (mopt->more_add_addr || mopt->more_rem_addr) { -+ mptcp_parse_addropt(skb, sk); -+ } else { -+ if (mopt->saw_add_addr) -+ mptcp_handle_add_addr(mopt->add_addr_ptr, sk); -+ if (mopt->saw_rem_addr) -+ mptcp_handle_rem_addr(mopt->rem_addr_ptr, sk); -+ } -+ -+ mopt->more_add_addr = 0; -+ mopt->saw_add_addr = 0; -+ mopt->more_rem_addr = 0; -+ mopt->saw_rem_addr = 0; -+ } -+ if (mopt->saw_low_prio) { -+ if (mopt->saw_low_prio == 1) { -+ tp->mptcp->rcv_low_prio = mopt->low_prio; -+ } else { -+ struct sock *sk_it; -+ mptcp_for_each_sk(tp->mpcb, sk_it) { -+ struct mptcp_tcp_sock *mptcp = tcp_sk(sk_it)->mptcp; -+ if (mptcp->rem_id == mopt->prio_addr_id) -+ mptcp->rcv_low_prio = mopt->low_prio; -+ } -+ } -+ mopt->saw_low_prio = 0; -+ } -+ -+ mptcp_data_ack(sk, skb); -+ -+ mptcp_path_array_check(mptcp_meta_sk(sk)); -+ /* Socket may have been mp_killed by a REMOVE_ADDR */ -+ if (tp->mp_killed) -+ return true; -+ -+ return false; -+} -+ -+/* In case of fastopen, some data can already be in the write queue. -+ * We need to update the sequence number of the segments as they -+ * were initially TCP sequence numbers. -+ */ -+static void mptcp_rcv_synsent_fastopen(struct sock *meta_sk) -+{ -+ struct tcp_sock *meta_tp = tcp_sk(meta_sk); -+ struct tcp_sock *master_tp = tcp_sk(meta_tp->mpcb->master_sk); -+ struct sk_buff *skb; -+ u32 new_mapping = meta_tp->write_seq - master_tp->snd_una; -+ -+ /* There should only be one skb in write queue: the data not -+ * acknowledged in the SYN+ACK. In this case, we need to map -+ * this data to data sequence numbers. -+ */ -+ skb_queue_walk(&meta_sk->sk_write_queue, skb) { -+ /* If the server only acknowledges partially the data sent in -+ * the SYN, we need to trim the acknowledged part because -+ * we don't want to retransmit this already received data. -+ * When we reach this point, tcp_ack() has already cleaned up -+ * fully acked segments. However, tcp trims partially acked -+ * segments only when retransmitting. Since MPTCP comes into -+ * play only now, we will fake an initial transmit, and -+ * retransmit_skb() will not be called. The following fragment -+ * comes from __tcp_retransmit_skb(). -+ */ -+ if (before(TCP_SKB_CB(skb)->seq, master_tp->snd_una)) { -+ BUG_ON(before(TCP_SKB_CB(skb)->end_seq, -+ master_tp->snd_una)); -+ /* tcp_trim_head can only returns ENOMEM if skb is -+ * cloned. It is not the case here (see -+ * tcp_send_syn_data). -+ */ -+ BUG_ON(tcp_trim_head(meta_sk, skb, master_tp->snd_una - -+ TCP_SKB_CB(skb)->seq)); -+ } -+ -+ TCP_SKB_CB(skb)->seq += new_mapping; -+ TCP_SKB_CB(skb)->end_seq += new_mapping; -+ } -+ -+ /* We can advance write_seq by the number of bytes unacknowledged -+ * and that were mapped in the previous loop. -+ */ -+ meta_tp->write_seq += master_tp->write_seq - master_tp->snd_una; -+ -+ /* The packets from the master_sk will be entailed to it later -+ * Until that time, its write queue is empty, and -+ * write_seq must align with snd_una -+ */ -+ master_tp->snd_nxt = master_tp->write_seq = master_tp->snd_una; -+ master_tp->packets_out = 0; -+ -+ /* Although these data have been sent already over the subsk, -+ * They have never been sent over the meta_sk, so we rewind -+ * the send_head so that tcp considers it as an initial send -+ * (instead of retransmit). -+ */ -+ meta_sk->sk_send_head = tcp_write_queue_head(meta_sk); -+} -+ -+/* The skptr is needed, because if we become MPTCP-capable, we have to switch -+ * from meta-socket to master-socket. -+ * -+ * @return: 1 - we want to reset this connection -+ * 2 - we want to discard the received syn/ack -+ * 0 - everything is fine - continue -+ */ -+int mptcp_rcv_synsent_state_process(struct sock *sk, struct sock **skptr, -+ const struct sk_buff *skb, -+ const struct mptcp_options_received *mopt) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ -+ if (mptcp(tp)) { -+ u8 hash_mac_check[20]; -+ struct mptcp_cb *mpcb = tp->mpcb; -+ -+ mptcp_hmac_sha1((u8 *)&mpcb->mptcp_rem_key, -+ (u8 *)&mpcb->mptcp_loc_key, -+ (u32 *)hash_mac_check, 2, -+ 4, (u8 *)&tp->mptcp->rx_opt.mptcp_recv_nonce, -+ 4, (u8 *)&tp->mptcp->mptcp_loc_nonce); -+ if (memcmp(hash_mac_check, -+ (char *)&tp->mptcp->rx_opt.mptcp_recv_tmac, 8)) { -+ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_JOINSYNACKMAC); -+ mptcp_sub_force_close(sk); -+ return 1; -+ } -+ -+ /* Set this flag in order to postpone data sending -+ * until the 4th ack arrives. -+ */ -+ tp->mptcp->pre_established = 1; -+ tp->mptcp->rcv_low_prio = tp->mptcp->rx_opt.low_prio; -+ -+ mptcp_hmac_sha1((u8 *)&mpcb->mptcp_loc_key, -+ (u8 *)&mpcb->mptcp_rem_key, -+ (u32 *)&tp->mptcp->sender_mac[0], 2, -+ 4, (u8 *)&tp->mptcp->mptcp_loc_nonce, -+ 4, (u8 *)&tp->mptcp->rx_opt.mptcp_recv_nonce); -+ -+ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_JOINSYNACKRX); -+ } else if (mopt->saw_mpc) { -+ struct sock *meta_sk = sk; -+ -+ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_MPCAPABLEACTIVEACK); -+ if (mopt->mptcp_ver > tcp_sk(sk)->mptcp_ver) -+ /* TODO Consider adding new MPTCP_INC_STATS entry */ -+ goto fallback; -+ -+ if (mptcp_create_master_sk(sk, mopt->mptcp_sender_key, -+ mopt->mptcp_ver, -+ ntohs(tcp_hdr(skb)->window))) -+ return 2; -+ -+ sk = tcp_sk(sk)->mpcb->master_sk; -+ *skptr = sk; -+ tp = tcp_sk(sk); -+ -+ /* If fastopen was used data might be in the send queue. We -+ * need to update their sequence number to MPTCP-level seqno. -+ * Note that it can happen in rare cases that fastopen_req is -+ * NULL and syn_data is 0 but fastopen indeed occurred and -+ * data has been queued in the write queue (but not sent). -+ * Example of such rare cases: connect is non-blocking and -+ * TFO is configured to work without cookies. -+ */ -+ if (!skb_queue_empty(&meta_sk->sk_write_queue)) -+ mptcp_rcv_synsent_fastopen(meta_sk); -+ -+ /* -1, because the SYN consumed 1 byte. In case of TFO, we -+ * start the subflow-sequence number as if the data of the SYN -+ * is not part of any mapping. -+ */ -+ tp->mptcp->snt_isn = tp->snd_una - 1; -+ tp->mpcb->dss_csum = mopt->dss_csum; -+ if (tp->mpcb->dss_csum) -+ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_CSUMENABLED); -+ -+ tp->mptcp->include_mpc = 1; -+ -+ /* Ensure that fastopen is handled at the meta-level. */ -+ tp->fastopen_req = NULL; -+ -+ sk_set_socket(sk, meta_sk->sk_socket); -+ sk->sk_wq = meta_sk->sk_wq; -+ -+ bh_unlock_sock(sk); -+ /* hold in sk_clone_lock due to initialization to 2 */ -+ sock_put(sk); -+ } else { -+ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_MPCAPABLEACTIVEFALLBACK); -+fallback: -+ tp->request_mptcp = 0; -+ -+ if (tp->inside_tk_table) -+ mptcp_hash_remove_bh(tp); -+ } -+ -+ if (mptcp(tp)) -+ tp->mptcp->rcv_isn = TCP_SKB_CB(skb)->seq; -+ -+ return 0; -+} -+ -+/* Similar to tcp_should_expand_sndbuf */ -+bool mptcp_should_expand_sndbuf(const struct sock *sk) -+{ -+ const struct sock *sk_it; -+ const struct sock *meta_sk = mptcp_meta_sk(sk); -+ const struct tcp_sock *meta_tp = tcp_sk(meta_sk); -+ int cnt_backups = 0; -+ int backup_available = 0; -+ -+ /* We circumvent this check in tcp_check_space, because we want to -+ * always call sk_write_space. So, we reproduce the check here. -+ */ -+ if (!meta_sk->sk_socket || -+ !test_bit(SOCK_NOSPACE, &meta_sk->sk_socket->flags)) -+ return false; -+ -+ /* If the user specified a specific send buffer setting, do -+ * not modify it. -+ */ -+ if (meta_sk->sk_userlocks & SOCK_SNDBUF_LOCK) -+ return false; -+ -+ /* If we are under global TCP memory pressure, do not expand. */ -+ if (tcp_under_memory_pressure(meta_sk)) -+ return false; -+ -+ /* If we are under soft global TCP memory pressure, do not expand. */ -+ if (sk_memory_allocated(meta_sk) >= sk_prot_mem_limits(meta_sk, 0)) -+ return false; -+ -+ /* For MPTCP we look for a subsocket that could send data. -+ * If we found one, then we update the send-buffer. -+ */ -+ mptcp_for_each_sk(meta_tp->mpcb, sk_it) { -+ struct tcp_sock *tp_it = tcp_sk(sk_it); -+ -+ if (!mptcp_sk_can_send(sk_it)) -+ continue; -+ -+ /* Backup-flows have to be counted - if there is no other -+ * subflow we take the backup-flow into account. -+ */ -+ if (tp_it->mptcp->rcv_low_prio || tp_it->mptcp->low_prio) -+ cnt_backups++; -+ -+ if (tcp_packets_in_flight(tp_it) < tp_it->snd_cwnd) { -+ if (tp_it->mptcp->rcv_low_prio || tp_it->mptcp->low_prio) { -+ backup_available = 1; -+ continue; -+ } -+ return true; -+ } -+ } -+ -+ /* Backup-flow is available for sending - update send-buffer */ -+ if (meta_tp->mpcb->cnt_established == cnt_backups && backup_available) -+ return true; -+ return false; -+} -+ -+void mptcp_init_buffer_space(struct sock *sk) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct sock *meta_sk = mptcp_meta_sk(sk); -+ struct tcp_sock *meta_tp = tcp_sk(meta_sk); -+ int space; -+ -+ tcp_init_buffer_space(sk); -+ -+ if (is_master_tp(tp)) { -+ meta_tp->rcvq_space.space = meta_tp->rcv_wnd; -+ meta_tp->rcvq_space.time = tcp_time_stamp; -+ meta_tp->rcvq_space.seq = meta_tp->copied_seq; -+ -+ /* If there is only one subflow, we just use regular TCP -+ * autotuning. User-locks are handled already by -+ * tcp_init_buffer_space -+ */ -+ meta_tp->window_clamp = tp->window_clamp; -+ meta_tp->rcv_ssthresh = tp->rcv_ssthresh; -+ meta_sk->sk_rcvbuf = sk->sk_rcvbuf; -+ meta_sk->sk_sndbuf = sk->sk_sndbuf; -+ -+ return; -+ } -+ -+ if (meta_sk->sk_userlocks & SOCK_RCVBUF_LOCK) -+ goto snd_buf; -+ -+ /* Adding a new subflow to the rcv-buffer space. We make a simple -+ * addition, to give some space to allow traffic on the new subflow. -+ * Autotuning will increase it further later on. -+ */ -+ space = min(meta_sk->sk_rcvbuf + sk->sk_rcvbuf, sysctl_tcp_rmem[2]); -+ if (space > meta_sk->sk_rcvbuf) { -+ meta_tp->window_clamp += tp->window_clamp; -+ meta_tp->rcv_ssthresh += tp->rcv_ssthresh; -+ meta_sk->sk_rcvbuf = space; -+ } -+ -+snd_buf: -+ if (meta_sk->sk_userlocks & SOCK_SNDBUF_LOCK) -+ return; -+ -+ /* Adding a new subflow to the send-buffer space. We make a simple -+ * addition, to give some space to allow traffic on the new subflow. -+ * Autotuning will increase it further later on. -+ */ -+ space = min(meta_sk->sk_sndbuf + sk->sk_sndbuf, sysctl_tcp_wmem[2]); -+ if (space > meta_sk->sk_sndbuf) { -+ meta_sk->sk_sndbuf = space; -+ meta_sk->sk_write_space(meta_sk); -+ } -+} -+ -+void mptcp_tcp_set_rto(struct sock *sk) -+{ -+ tcp_set_rto(sk); -+ mptcp_set_rto(sk); -+} -diff -aurN linux-4.9.162/net/mptcp/mptcp_ipv4.c mptcp-mptcp_v0.93/net/mptcp/mptcp_ipv4.c ---- linux-4.9.162/net/mptcp/mptcp_ipv4.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_v0.93/net/mptcp/mptcp_ipv4.c 2019-03-14 14:02:32.000000000 +0100 -@@ -0,0 +1,446 @@ -+/* -+ * MPTCP implementation - IPv4-specific functions -+ * -+ * Initial Design & Implementation: -+ * Sébastien Barré -+ * -+ * Current Maintainer: -+ * Christoph Paasch -+ * -+ * Additional authors: -+ * Jaakko Korkeaniemi -+ * Gregory Detal -+ * Fabien Duchêne -+ * Andreas Seelinger -+ * Lavkesh Lahngir -+ * Andreas Ripke -+ * Vlad Dogaru -+ * Octavian Purdila -+ * John Ronan -+ * Catalin Nicutar -+ * Brandon Heller -+ * -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version -+ * 2 of the License, or (at your option) any later version. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+u32 mptcp_v4_get_nonce(__be32 saddr, __be32 daddr, __be16 sport, __be16 dport) -+{ -+ u32 hash[MD5_DIGEST_WORDS]; -+ -+ hash[0] = (__force u32)saddr; -+ hash[1] = (__force u32)daddr; -+ hash[2] = ((__force u16)sport << 16) + (__force u16)dport; -+ hash[3] = mptcp_seed++; -+ -+ md5_transform(hash, mptcp_secret); -+ -+ return hash[0]; -+} -+ -+u64 mptcp_v4_get_key(__be32 saddr, __be32 daddr, __be16 sport, __be16 dport, -+ u32 seed) -+{ -+ u32 hash[MD5_DIGEST_WORDS]; -+ -+ hash[0] = (__force u32)saddr; -+ hash[1] = (__force u32)daddr; -+ hash[2] = ((__force u16)sport << 16) + (__force u16)dport; -+ hash[3] = seed; -+ -+ md5_transform(hash, mptcp_secret); -+ -+ return *((u64 *)hash); -+} -+ -+ -+static void mptcp_v4_reqsk_destructor(struct request_sock *req) -+{ -+ mptcp_reqsk_destructor(req); -+ -+ tcp_v4_reqsk_destructor(req); -+} -+ -+static int mptcp_v4_init_req(struct request_sock *req, const struct sock *sk, -+ struct sk_buff *skb, bool want_cookie) -+{ -+ tcp_request_sock_ipv4_ops.init_req(req, sk, skb, want_cookie); -+ -+ mptcp_rsk(req)->hash_entry.pprev = NULL; -+ mptcp_rsk(req)->is_sub = 0; -+ inet_rsk(req)->mptcp_rqsk = 1; -+ -+ /* In case of SYN-cookies, we wait for the isn to be generated - it is -+ * input to the key-generation. -+ */ -+ if (!want_cookie) -+ mptcp_reqsk_init(req, sk, skb, false); -+ -+ return 0; -+} -+ -+#ifdef CONFIG_SYN_COOKIES -+static u32 mptcp_v4_cookie_init_seq(struct request_sock *req, const struct sock *sk, -+ const struct sk_buff *skb, __u16 *mssp) -+{ -+ __u32 isn = cookie_v4_init_sequence(req, sk, skb, mssp); -+ -+ tcp_rsk(req)->snt_isn = isn; -+ -+ mptcp_reqsk_init(req, sk, skb, true); -+ -+ return isn; -+} -+#endif -+ -+static int mptcp_v4_join_init_req(struct request_sock *req, const struct sock *sk, -+ struct sk_buff *skb, bool want_cookie) -+{ -+ struct mptcp_request_sock *mtreq = mptcp_rsk(req); -+ const struct mptcp_cb *mpcb = tcp_sk(sk)->mpcb; -+ union inet_addr addr; -+ int loc_id; -+ bool low_prio = false; -+ -+ /* We need to do this as early as possible. Because, if we fail later -+ * (e.g., get_local_id), then reqsk_free tries to remove the -+ * request-socket from the htb in mptcp_hash_request_remove as pprev -+ * may be different from NULL. -+ */ -+ mtreq->hash_entry.pprev = NULL; -+ -+ tcp_request_sock_ipv4_ops.init_req(req, sk, skb, want_cookie); -+ -+ mtreq->mptcp_loc_nonce = mptcp_v4_get_nonce(ip_hdr(skb)->saddr, -+ ip_hdr(skb)->daddr, -+ tcp_hdr(skb)->source, -+ tcp_hdr(skb)->dest); -+ addr.ip = inet_rsk(req)->ir_loc_addr; -+ loc_id = mpcb->pm_ops->get_local_id(AF_INET, &addr, sock_net(sk), &low_prio); -+ if (loc_id == -1) -+ return -1; -+ mtreq->loc_id = loc_id; -+ mtreq->low_prio = low_prio; -+ -+ mptcp_join_reqsk_init(mpcb, req, skb); -+ -+ return 0; -+} -+ -+/* Similar to tcp_request_sock_ops */ -+struct request_sock_ops mptcp_request_sock_ops __read_mostly = { -+ .family = PF_INET, -+ .obj_size = sizeof(struct mptcp_request_sock), -+ .rtx_syn_ack = tcp_rtx_synack, -+ .send_ack = tcp_v4_reqsk_send_ack, -+ .destructor = mptcp_v4_reqsk_destructor, -+ .send_reset = tcp_v4_send_reset, -+ .syn_ack_timeout = tcp_syn_ack_timeout, -+}; -+ -+/* Similar to: tcp_v4_conn_request */ -+static int mptcp_v4_join_request(struct sock *meta_sk, struct sk_buff *skb) -+{ -+ return tcp_conn_request(&mptcp_request_sock_ops, -+ &mptcp_join_request_sock_ipv4_ops, -+ meta_sk, skb); -+} -+ -+int mptcp_finish_handshake(struct sock *child, struct sk_buff *skb) -+ __releases(&child->sk_lock.slock) -+{ -+ int ret; -+ -+ /* We don't call tcp_child_process here, because we hold -+ * already the meta-sk-lock and are sure that it is not owned -+ * by the user. -+ */ -+ tcp_sk(child)->segs_in += max_t(u16, 1, skb_shinfo(skb)->gso_segs); -+ ret = tcp_rcv_state_process(child, skb); -+ bh_unlock_sock(child); -+ sock_put(child); -+ -+ return ret; -+} -+ -+ -+/* Similar to: tcp_v4_do_rcv -+ * We only process join requests here. (either the SYN or the final ACK) -+ */ -+int mptcp_v4_do_rcv(struct sock *meta_sk, struct sk_buff *skb) -+{ -+ const struct tcphdr *th = tcp_hdr(skb); -+ const struct iphdr *iph = ip_hdr(skb); -+ struct sock *child, *rsk = NULL, *sk; -+ int ret; -+ -+ sk = inet_lookup_established(sock_net(meta_sk), &tcp_hashinfo, -+ iph->saddr, th->source, iph->daddr, -+ th->dest, inet_iif(skb)); -+ -+ if (!sk) -+ goto new_subflow; -+ -+ if (is_meta_sk(sk)) { -+ WARN("%s Did not find a sub-sk - did found the meta!\n", __func__); -+ sock_put(sk); -+ goto discard; -+ } -+ -+ if (sk->sk_state == TCP_TIME_WAIT) { -+ inet_twsk_put(inet_twsk(sk)); -+ goto discard; -+ } -+ -+ if (sk->sk_state == TCP_NEW_SYN_RECV) { -+ struct request_sock *req = inet_reqsk(sk); -+ -+ if (!mptcp_can_new_subflow(meta_sk)) -+ goto reset_and_discard; -+ -+ local_bh_disable(); -+ child = tcp_check_req(meta_sk, skb, req, false); -+ if (!child) { -+ reqsk_put(req); -+ local_bh_enable(); -+ goto discard; -+ } -+ -+ if (child != meta_sk) { -+ ret = mptcp_finish_handshake(child, skb); -+ if (ret) { -+ rsk = child; -+ local_bh_enable(); -+ goto reset_and_discard; -+ } -+ -+ local_bh_enable(); -+ return 0; -+ } -+ -+ /* tcp_check_req failed */ -+ reqsk_put(req); -+ -+ local_bh_enable(); -+ goto discard; -+ } -+ -+ ret = tcp_v4_do_rcv(sk, skb); -+ sock_put(sk); -+ -+ return ret; -+ -+new_subflow: -+ if (!mptcp_can_new_subflow(meta_sk)) -+ goto reset_and_discard; -+ -+ child = tcp_v4_cookie_check(meta_sk, skb); -+ if (!child) -+ goto discard; -+ -+ if (child != meta_sk) { -+ ret = mptcp_finish_handshake(child, skb); -+ if (ret) { -+ rsk = child; -+ goto reset_and_discard; -+ } -+ } -+ -+ if (tcp_hdr(skb)->syn) { -+ local_bh_disable(); -+ mptcp_v4_join_request(meta_sk, skb); -+ local_bh_enable(); -+ } -+ -+discard: -+ kfree_skb(skb); -+ return 0; -+ -+reset_and_discard: -+ tcp_v4_send_reset(rsk, skb); -+ goto discard; -+} -+ -+/* Create a new IPv4 subflow. -+ * -+ * We are in user-context and meta-sock-lock is hold. -+ */ -+int mptcp_init4_subsockets(struct sock *meta_sk, const struct mptcp_loc4 *loc, -+ struct mptcp_rem4 *rem) -+{ -+ struct tcp_sock *tp; -+ struct sock *sk; -+ struct sockaddr_in loc_in, rem_in; -+ struct socket_alloc sock_full; -+ struct socket *sock = (struct socket *)&sock_full; -+ int ret; -+ -+ /** First, create and prepare the new socket */ -+ memcpy(&sock_full, meta_sk->sk_socket, sizeof(sock_full)); -+ sock->state = SS_UNCONNECTED; -+ sock->ops = NULL; -+ -+ ret = inet_create(sock_net(meta_sk), sock, IPPROTO_TCP, 1); -+ if (unlikely(ret < 0)) { -+ mptcp_debug("%s inet_create failed ret: %d\n", __func__, ret); -+ return ret; -+ } -+ -+ sk = sock->sk; -+ tp = tcp_sk(sk); -+ -+ /* All subsockets need the MPTCP-lock-class */ -+ lockdep_set_class_and_name(&(sk)->sk_lock.slock, &meta_slock_key, meta_slock_key_name); -+ lockdep_init_map(&(sk)->sk_lock.dep_map, meta_key_name, &meta_key, 0); -+ -+ if (mptcp_add_sock(meta_sk, sk, loc->loc4_id, rem->rem4_id, GFP_KERNEL)) -+ goto error; -+ -+ tp->mptcp->slave_sk = 1; -+ tp->mptcp->low_prio = loc->low_prio; -+ -+ /* Initializing the timer for an MPTCP subflow */ -+ setup_timer(&tp->mptcp->mptcp_ack_timer, mptcp_ack_handler, (unsigned long)sk); -+ -+ /** Then, connect the socket to the peer */ -+ loc_in.sin_family = AF_INET; -+ rem_in.sin_family = AF_INET; -+ loc_in.sin_port = 0; -+ if (rem->port) -+ rem_in.sin_port = rem->port; -+ else -+ rem_in.sin_port = inet_sk(meta_sk)->inet_dport; -+ loc_in.sin_addr = loc->addr; -+ rem_in.sin_addr = rem->addr; -+ -+ if (loc->if_idx) -+ sk->sk_bound_dev_if = loc->if_idx; -+ -+ ret = kernel_bind(sock, (struct sockaddr *)&loc_in, -+ sizeof(struct sockaddr_in)); -+ if (ret < 0) { -+ mptcp_debug("%s: MPTCP subsocket bind() failed, error %d\n", -+ __func__, ret); -+ goto error; -+ } -+ -+ mptcp_debug("%s: token %#x pi %d src_addr:%pI4:%d dst_addr:%pI4:%d ifidx: %d\n", -+ __func__, tcp_sk(meta_sk)->mpcb->mptcp_loc_token, -+ tp->mptcp->path_index, &loc_in.sin_addr, -+ ntohs(loc_in.sin_port), &rem_in.sin_addr, -+ ntohs(rem_in.sin_port), loc->if_idx); -+ -+ if (tcp_sk(meta_sk)->mpcb->pm_ops->init_subsocket_v4) -+ tcp_sk(meta_sk)->mpcb->pm_ops->init_subsocket_v4(sk, rem->addr); -+ -+ ret = kernel_connect(sock, (struct sockaddr *)&rem_in, -+ sizeof(struct sockaddr_in), O_NONBLOCK); -+ if (ret < 0 && ret != -EINPROGRESS) { -+ mptcp_debug("%s: MPTCP subsocket connect() failed, error %d\n", -+ __func__, ret); -+ goto error; -+ } -+ -+ MPTCP_INC_STATS(sock_net(meta_sk), MPTCP_MIB_JOINSYNTX); -+ -+ sk_set_socket(sk, meta_sk->sk_socket); -+ sk->sk_wq = meta_sk->sk_wq; -+ -+ return 0; -+ -+error: -+ /* May happen if mptcp_add_sock fails first */ -+ if (!mptcp(tp)) { -+ tcp_close(sk, 0); -+ } else { -+ local_bh_disable(); -+ mptcp_sub_force_close(sk); -+ local_bh_enable(); -+ } -+ return ret; -+} -+EXPORT_SYMBOL(mptcp_init4_subsockets); -+ -+const struct inet_connection_sock_af_ops mptcp_v4_specific = { -+ .queue_xmit = ip_queue_xmit, -+ .send_check = tcp_v4_send_check, -+ .rebuild_header = inet_sk_rebuild_header, -+ .sk_rx_dst_set = inet_sk_rx_dst_set, -+ .conn_request = mptcp_conn_request, -+ .syn_recv_sock = tcp_v4_syn_recv_sock, -+ .net_header_len = sizeof(struct iphdr), -+ .setsockopt = ip_setsockopt, -+ .getsockopt = ip_getsockopt, -+ .addr2sockaddr = inet_csk_addr2sockaddr, -+ .sockaddr_len = sizeof(struct sockaddr_in), -+ .bind_conflict = inet_csk_bind_conflict, -+#ifdef CONFIG_COMPAT -+ .compat_setsockopt = compat_ip_setsockopt, -+ .compat_getsockopt = compat_ip_getsockopt, -+#endif -+ .mtu_reduced = tcp_v4_mtu_reduced, -+}; -+ -+struct tcp_request_sock_ops mptcp_request_sock_ipv4_ops; -+struct tcp_request_sock_ops mptcp_join_request_sock_ipv4_ops; -+ -+/* General initialization of IPv4 for MPTCP */ -+int mptcp_pm_v4_init(void) -+{ -+ int ret = 0; -+ struct request_sock_ops *ops = &mptcp_request_sock_ops; -+ -+ mptcp_request_sock_ipv4_ops = tcp_request_sock_ipv4_ops; -+ mptcp_request_sock_ipv4_ops.init_req = mptcp_v4_init_req; -+#ifdef CONFIG_SYN_COOKIES -+ mptcp_request_sock_ipv4_ops.cookie_init_seq = mptcp_v4_cookie_init_seq; -+#endif -+ mptcp_join_request_sock_ipv4_ops = tcp_request_sock_ipv4_ops; -+ mptcp_join_request_sock_ipv4_ops.init_req = mptcp_v4_join_init_req; -+ -+ ops->slab_name = kasprintf(GFP_KERNEL, "request_sock_%s", "MPTCP"); -+ if (ops->slab_name == NULL) { -+ ret = -ENOMEM; -+ goto out; -+ } -+ -+ ops->slab = kmem_cache_create(ops->slab_name, ops->obj_size, 0, -+ SLAB_DESTROY_BY_RCU|SLAB_HWCACHE_ALIGN, -+ NULL); -+ -+ if (ops->slab == NULL) { -+ ret = -ENOMEM; -+ goto err_reqsk_create; -+ } -+ -+out: -+ return ret; -+ -+err_reqsk_create: -+ kfree(ops->slab_name); -+ ops->slab_name = NULL; -+ goto out; -+} -+ -+void mptcp_pm_v4_undo(void) -+{ -+ kmem_cache_destroy(mptcp_request_sock_ops.slab); -+ kfree(mptcp_request_sock_ops.slab_name); -+} -diff -aurN linux-4.9.162/net/mptcp/mptcp_ipv6.c mptcp-mptcp_v0.93/net/mptcp/mptcp_ipv6.c ---- linux-4.9.162/net/mptcp/mptcp_ipv6.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_v0.93/net/mptcp/mptcp_ipv6.c 2019-03-14 14:02:32.000000000 +0100 -@@ -0,0 +1,462 @@ -+/* -+ * MPTCP implementation - IPv6-specific functions -+ * -+ * Initial Design & Implementation: -+ * Sébastien Barré -+ * -+ * Current Maintainer: -+ * Jaakko Korkeaniemi -+ * -+ * Additional authors: -+ * Jaakko Korkeaniemi -+ * Gregory Detal -+ * Fabien Duchêne -+ * Andreas Seelinger -+ * Lavkesh Lahngir -+ * Andreas Ripke -+ * Vlad Dogaru -+ * Octavian Purdila -+ * John Ronan -+ * Catalin Nicutar -+ * Brandon Heller -+ * -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version -+ * 2 of the License, or (at your option) any later version. -+ */ -+ -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+__u32 mptcp_v6_get_nonce(const __be32 *saddr, const __be32 *daddr, -+ __be16 sport, __be16 dport) -+{ -+ u32 secret[MD5_MESSAGE_BYTES / 4]; -+ u32 hash[MD5_DIGEST_WORDS]; -+ u32 i; -+ -+ memcpy(hash, saddr, 16); -+ for (i = 0; i < 4; i++) -+ secret[i] = mptcp_secret[i] + (__force u32)daddr[i]; -+ secret[4] = mptcp_secret[4] + -+ (((__force u16)sport << 16) + (__force u16)dport); -+ secret[5] = mptcp_seed++; -+ for (i = 6; i < MD5_MESSAGE_BYTES / 4; i++) -+ secret[i] = mptcp_secret[i]; -+ -+ md5_transform(hash, secret); -+ -+ return hash[0]; -+} -+ -+u64 mptcp_v6_get_key(const __be32 *saddr, const __be32 *daddr, -+ __be16 sport, __be16 dport, u32 seed) -+{ -+ u32 secret[MD5_MESSAGE_BYTES / 4]; -+ u32 hash[MD5_DIGEST_WORDS]; -+ u32 i; -+ -+ memcpy(hash, saddr, 16); -+ for (i = 0; i < 4; i++) -+ secret[i] = mptcp_secret[i] + (__force u32)daddr[i]; -+ secret[4] = mptcp_secret[4] + -+ (((__force u16)sport << 16) + (__force u16)dport); -+ secret[5] = seed; -+ for (i = 6; i < MD5_MESSAGE_BYTES / 4; i++) -+ secret[i] = mptcp_secret[i]; -+ -+ md5_transform(hash, secret); -+ -+ return *((u64 *)hash); -+} -+ -+static void mptcp_v6_reqsk_destructor(struct request_sock *req) -+{ -+ mptcp_reqsk_destructor(req); -+ -+ tcp_v6_reqsk_destructor(req); -+} -+ -+static int mptcp_v6_init_req(struct request_sock *req, const struct sock *sk, -+ struct sk_buff *skb, bool want_cookie) -+{ -+ tcp_request_sock_ipv6_ops.init_req(req, sk, skb, want_cookie); -+ -+ mptcp_rsk(req)->hash_entry.pprev = NULL; -+ mptcp_rsk(req)->is_sub = 0; -+ inet_rsk(req)->mptcp_rqsk = 1; -+ -+ /* In case of SYN-cookies, we wait for the isn to be generated - it is -+ * input to the key-generation. -+ */ -+ if (!want_cookie) -+ mptcp_reqsk_init(req, sk, skb, false); -+ -+ return 0; -+} -+ -+#ifdef CONFIG_SYN_COOKIES -+static u32 mptcp_v6_cookie_init_seq(struct request_sock *req, const struct sock *sk, -+ const struct sk_buff *skb, __u16 *mssp) -+{ -+ __u32 isn = cookie_v6_init_sequence(req, sk, skb, mssp); -+ -+ tcp_rsk(req)->snt_isn = isn; -+ -+ mptcp_reqsk_init(req, sk, skb, true); -+ -+ return isn; -+} -+#endif -+ -+static int mptcp_v6_join_init_req(struct request_sock *req, const struct sock *sk, -+ struct sk_buff *skb, bool want_cookie) -+{ -+ struct mptcp_request_sock *mtreq = mptcp_rsk(req); -+ const struct mptcp_cb *mpcb = tcp_sk(sk)->mpcb; -+ union inet_addr addr; -+ int loc_id; -+ bool low_prio = false; -+ -+ /* We need to do this as early as possible. Because, if we fail later -+ * (e.g., get_local_id), then reqsk_free tries to remove the -+ * request-socket from the htb in mptcp_hash_request_remove as pprev -+ * may be different from NULL. -+ */ -+ mtreq->hash_entry.pprev = NULL; -+ -+ tcp_request_sock_ipv6_ops.init_req(req, sk, skb, want_cookie); -+ -+ mtreq->mptcp_loc_nonce = mptcp_v6_get_nonce(ipv6_hdr(skb)->saddr.s6_addr32, -+ ipv6_hdr(skb)->daddr.s6_addr32, -+ tcp_hdr(skb)->source, -+ tcp_hdr(skb)->dest); -+ addr.in6 = inet_rsk(req)->ir_v6_loc_addr; -+ loc_id = mpcb->pm_ops->get_local_id(AF_INET6, &addr, sock_net(sk), &low_prio); -+ if (loc_id == -1) -+ return -1; -+ mtreq->loc_id = loc_id; -+ mtreq->low_prio = low_prio; -+ -+ mptcp_join_reqsk_init(mpcb, req, skb); -+ -+ return 0; -+} -+ -+/* Similar to tcp6_request_sock_ops */ -+struct request_sock_ops mptcp6_request_sock_ops __read_mostly = { -+ .family = AF_INET6, -+ .obj_size = sizeof(struct mptcp_request_sock), -+ .rtx_syn_ack = tcp_rtx_synack, -+ .send_ack = tcp_v6_reqsk_send_ack, -+ .destructor = mptcp_v6_reqsk_destructor, -+ .send_reset = tcp_v6_send_reset, -+ .syn_ack_timeout = tcp_syn_ack_timeout, -+}; -+ -+static int mptcp_v6_join_request(struct sock *meta_sk, struct sk_buff *skb) -+{ -+ return tcp_conn_request(&mptcp6_request_sock_ops, -+ &mptcp_join_request_sock_ipv6_ops, -+ meta_sk, skb); -+} -+ -+int mptcp_v6_do_rcv(struct sock *meta_sk, struct sk_buff *skb) -+{ -+ const struct tcphdr *th = tcp_hdr(skb); -+ const struct ipv6hdr *ip6h = ipv6_hdr(skb); -+ struct sock *child, *rsk = NULL, *sk; -+ int ret; -+ -+ sk = __inet6_lookup_established(sock_net(meta_sk), -+ &tcp_hashinfo, -+ &ip6h->saddr, th->source, -+ &ip6h->daddr, ntohs(th->dest), -+ tcp_v6_iif(skb)); -+ -+ if (!sk) -+ goto new_subflow; -+ -+ if (is_meta_sk(sk)) { -+ WARN("%s Did not find a sub-sk - did found the meta!\n", __func__); -+ sock_put(sk); -+ goto discard; -+ } -+ -+ if (sk->sk_state == TCP_TIME_WAIT) { -+ inet_twsk_put(inet_twsk(sk)); -+ goto discard; -+ } -+ -+ if (sk->sk_state == TCP_NEW_SYN_RECV) { -+ struct request_sock *req = inet_reqsk(sk); -+ -+ if (!mptcp_can_new_subflow(meta_sk)) -+ goto reset_and_discard; -+ -+ local_bh_disable(); -+ child = tcp_check_req(meta_sk, skb, req, false); -+ if (!child) { -+ reqsk_put(req); -+ local_bh_enable(); -+ goto discard; -+ } -+ -+ if (child != meta_sk) { -+ ret = mptcp_finish_handshake(child, skb); -+ if (ret) { -+ rsk = child; -+ local_bh_enable(); -+ goto reset_and_discard; -+ } -+ -+ local_bh_enable(); -+ return 0; -+ } -+ -+ /* tcp_check_req failed */ -+ reqsk_put(req); -+ -+ local_bh_enable(); -+ goto discard; -+ } -+ -+ ret = tcp_v6_do_rcv(sk, skb); -+ sock_put(sk); -+ -+ return ret; -+ -+new_subflow: -+ if (!mptcp_can_new_subflow(meta_sk)) -+ goto reset_and_discard; -+ -+ child = tcp_v6_cookie_check(meta_sk, skb); -+ if (!child) -+ goto discard; -+ -+ if (child != meta_sk) { -+ ret = mptcp_finish_handshake(child, skb); -+ if (ret) { -+ rsk = child; -+ goto reset_and_discard; -+ } -+ } -+ -+ if (tcp_hdr(skb)->syn) { -+ local_bh_disable(); -+ mptcp_v6_join_request(meta_sk, skb); -+ local_bh_enable(); -+ } -+ -+discard: -+ kfree_skb(skb); -+ return 0; -+ -+reset_and_discard: -+ tcp_v6_send_reset(rsk, skb); -+ goto discard; -+} -+ -+/* Create a new IPv6 subflow. -+ * -+ * We are in user-context and meta-sock-lock is hold. -+ */ -+int mptcp_init6_subsockets(struct sock *meta_sk, const struct mptcp_loc6 *loc, -+ struct mptcp_rem6 *rem) -+{ -+ struct tcp_sock *tp; -+ struct sock *sk; -+ struct sockaddr_in6 loc_in, rem_in; -+ struct socket_alloc sock_full; -+ struct socket *sock = (struct socket *)&sock_full; -+ int ret; -+ -+ /** First, create and prepare the new socket */ -+ memcpy(&sock_full, meta_sk->sk_socket, sizeof(sock_full)); -+ sock->state = SS_UNCONNECTED; -+ sock->ops = NULL; -+ -+ ret = inet6_create(sock_net(meta_sk), sock, IPPROTO_TCP, 1); -+ if (unlikely(ret < 0)) { -+ mptcp_debug("%s inet6_create failed ret: %d\n", __func__, ret); -+ return ret; -+ } -+ -+ sk = sock->sk; -+ tp = tcp_sk(sk); -+ -+ /* All subsockets need the MPTCP-lock-class */ -+ lockdep_set_class_and_name(&(sk)->sk_lock.slock, &meta_slock_key, meta_slock_key_name); -+ lockdep_init_map(&(sk)->sk_lock.dep_map, meta_key_name, &meta_key, 0); -+ -+ if (mptcp_add_sock(meta_sk, sk, loc->loc6_id, rem->rem6_id, GFP_KERNEL)) -+ goto error; -+ -+ tp->mptcp->slave_sk = 1; -+ tp->mptcp->low_prio = loc->low_prio; -+ -+ /* Initializing the timer for an MPTCP subflow */ -+ setup_timer(&tp->mptcp->mptcp_ack_timer, mptcp_ack_handler, (unsigned long)sk); -+ -+ /** Then, connect the socket to the peer */ -+ loc_in.sin6_family = AF_INET6; -+ rem_in.sin6_family = AF_INET6; -+ loc_in.sin6_port = 0; -+ if (rem->port) -+ rem_in.sin6_port = rem->port; -+ else -+ rem_in.sin6_port = inet_sk(meta_sk)->inet_dport; -+ loc_in.sin6_addr = loc->addr; -+ rem_in.sin6_addr = rem->addr; -+ -+ if (loc->if_idx) -+ sk->sk_bound_dev_if = loc->if_idx; -+ -+ ret = kernel_bind(sock, (struct sockaddr *)&loc_in, -+ sizeof(struct sockaddr_in6)); -+ if (ret < 0) { -+ mptcp_debug("%s: MPTCP subsocket bind()failed, error %d\n", -+ __func__, ret); -+ goto error; -+ } -+ -+ mptcp_debug("%s: token %#x pi %d src_addr:%pI6:%d dst_addr:%pI6:%d ifidx: %u\n", -+ __func__, tcp_sk(meta_sk)->mpcb->mptcp_loc_token, -+ tp->mptcp->path_index, &loc_in.sin6_addr, -+ ntohs(loc_in.sin6_port), &rem_in.sin6_addr, -+ ntohs(rem_in.sin6_port), loc->if_idx); -+ -+ if (tcp_sk(meta_sk)->mpcb->pm_ops->init_subsocket_v6) -+ tcp_sk(meta_sk)->mpcb->pm_ops->init_subsocket_v6(sk, rem->addr); -+ -+ ret = kernel_connect(sock, (struct sockaddr *)&rem_in, -+ sizeof(struct sockaddr_in6), O_NONBLOCK); -+ if (ret < 0 && ret != -EINPROGRESS) { -+ mptcp_debug("%s: MPTCP subsocket connect() failed, error %d\n", -+ __func__, ret); -+ goto error; -+ } -+ -+ MPTCP_INC_STATS(sock_net(meta_sk), MPTCP_MIB_JOINSYNTX); -+ -+ sk_set_socket(sk, meta_sk->sk_socket); -+ sk->sk_wq = meta_sk->sk_wq; -+ -+ return 0; -+ -+error: -+ /* May happen if mptcp_add_sock fails first */ -+ if (!mptcp(tp)) { -+ tcp_close(sk, 0); -+ } else { -+ local_bh_disable(); -+ mptcp_sub_force_close(sk); -+ local_bh_enable(); -+ } -+ return ret; -+} -+EXPORT_SYMBOL(mptcp_init6_subsockets); -+ -+const struct inet_connection_sock_af_ops mptcp_v6_specific = { -+ .queue_xmit = inet6_csk_xmit, -+ .send_check = tcp_v6_send_check, -+ .rebuild_header = inet6_sk_rebuild_header, -+ .sk_rx_dst_set = inet6_sk_rx_dst_set, -+ .conn_request = mptcp_conn_request, -+ .syn_recv_sock = tcp_v6_syn_recv_sock, -+ .net_header_len = sizeof(struct ipv6hdr), -+ .net_frag_header_len = sizeof(struct frag_hdr), -+ .setsockopt = ipv6_setsockopt, -+ .getsockopt = ipv6_getsockopt, -+ .addr2sockaddr = inet6_csk_addr2sockaddr, -+ .sockaddr_len = sizeof(struct sockaddr_in6), -+ .bind_conflict = inet6_csk_bind_conflict, -+#ifdef CONFIG_COMPAT -+ .compat_setsockopt = compat_ipv6_setsockopt, -+ .compat_getsockopt = compat_ipv6_getsockopt, -+#endif -+ .mtu_reduced = tcp_v6_mtu_reduced, -+}; -+ -+const struct inet_connection_sock_af_ops mptcp_v6_mapped = { -+ .queue_xmit = ip_queue_xmit, -+ .send_check = tcp_v4_send_check, -+ .rebuild_header = inet_sk_rebuild_header, -+ .sk_rx_dst_set = inet_sk_rx_dst_set, -+ .conn_request = mptcp_conn_request, -+ .syn_recv_sock = tcp_v6_syn_recv_sock, -+ .net_header_len = sizeof(struct iphdr), -+ .setsockopt = ipv6_setsockopt, -+ .getsockopt = ipv6_getsockopt, -+ .addr2sockaddr = inet6_csk_addr2sockaddr, -+ .sockaddr_len = sizeof(struct sockaddr_in6), -+ .bind_conflict = inet6_csk_bind_conflict, -+#ifdef CONFIG_COMPAT -+ .compat_setsockopt = compat_ipv6_setsockopt, -+ .compat_getsockopt = compat_ipv6_getsockopt, -+#endif -+ .mtu_reduced = tcp_v4_mtu_reduced, -+}; -+ -+struct tcp_request_sock_ops mptcp_request_sock_ipv6_ops; -+struct tcp_request_sock_ops mptcp_join_request_sock_ipv6_ops; -+ -+int mptcp_pm_v6_init(void) -+{ -+ int ret = 0; -+ struct request_sock_ops *ops = &mptcp6_request_sock_ops; -+ -+ mptcp_request_sock_ipv6_ops = tcp_request_sock_ipv6_ops; -+ mptcp_request_sock_ipv6_ops.init_req = mptcp_v6_init_req; -+#ifdef CONFIG_SYN_COOKIES -+ mptcp_request_sock_ipv6_ops.cookie_init_seq = mptcp_v6_cookie_init_seq; -+#endif -+ -+ mptcp_join_request_sock_ipv6_ops = tcp_request_sock_ipv6_ops; -+ mptcp_join_request_sock_ipv6_ops.init_req = mptcp_v6_join_init_req; -+ -+ ops->slab_name = kasprintf(GFP_KERNEL, "request_sock_%s", "MPTCP6"); -+ if (ops->slab_name == NULL) { -+ ret = -ENOMEM; -+ goto out; -+ } -+ -+ ops->slab = kmem_cache_create(ops->slab_name, ops->obj_size, 0, -+ SLAB_DESTROY_BY_RCU|SLAB_HWCACHE_ALIGN, -+ NULL); -+ -+ if (ops->slab == NULL) { -+ ret = -ENOMEM; -+ goto err_reqsk_create; -+ } -+ -+out: -+ return ret; -+ -+err_reqsk_create: -+ kfree(ops->slab_name); -+ ops->slab_name = NULL; -+ goto out; -+} -+ -+void mptcp_pm_v6_undo(void) -+{ -+ kmem_cache_destroy(mptcp6_request_sock_ops.slab); -+ kfree(mptcp6_request_sock_ops.slab_name); -+} -diff -aurN linux-4.9.162/net/mptcp/mptcp_ndiffports.c mptcp-mptcp_v0.93/net/mptcp/mptcp_ndiffports.c ---- linux-4.9.162/net/mptcp/mptcp_ndiffports.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_v0.93/net/mptcp/mptcp_ndiffports.c 2019-03-14 14:02:32.000000000 +0100 -@@ -0,0 +1,169 @@ -+#include -+ -+#include -+#include -+ -+#if IS_ENABLED(CONFIG_IPV6) -+#include -+#endif -+ -+struct ndiffports_priv { -+ /* Worker struct for subflow establishment */ -+ struct work_struct subflow_work; -+ -+ struct mptcp_cb *mpcb; -+}; -+ -+static int num_subflows __read_mostly = 2; -+module_param(num_subflows, int, 0644); -+MODULE_PARM_DESC(num_subflows, "choose the number of subflows per MPTCP connection"); -+ -+/** -+ * Create all new subflows, by doing calls to mptcp_initX_subsockets -+ * -+ * This function uses a goto next_subflow, to allow releasing the lock between -+ * new subflows and giving other processes a chance to do some work on the -+ * socket and potentially finishing the communication. -+ **/ -+static void create_subflow_worker(struct work_struct *work) -+{ -+ const struct ndiffports_priv *pm_priv = container_of(work, -+ struct ndiffports_priv, -+ subflow_work); -+ struct mptcp_cb *mpcb = pm_priv->mpcb; -+ struct sock *meta_sk = mpcb->meta_sk; -+ int iter = 0; -+ -+next_subflow: -+ if (iter) { -+ release_sock(meta_sk); -+ mutex_unlock(&mpcb->mpcb_mutex); -+ -+ cond_resched(); -+ } -+ mutex_lock(&mpcb->mpcb_mutex); -+ lock_sock_nested(meta_sk, SINGLE_DEPTH_NESTING); -+ -+ iter++; -+ -+ if (sock_flag(meta_sk, SOCK_DEAD)) -+ goto exit; -+ -+ if (mpcb->master_sk && -+ !tcp_sk(mpcb->master_sk)->mptcp->fully_established) -+ goto exit; -+ -+ if (num_subflows > iter && num_subflows > mpcb->cnt_subflows) { -+ if (meta_sk->sk_family == AF_INET || -+ mptcp_v6_is_v4_mapped(meta_sk)) { -+ struct mptcp_loc4 loc; -+ struct mptcp_rem4 rem; -+ -+ loc.addr.s_addr = inet_sk(meta_sk)->inet_saddr; -+ loc.loc4_id = 0; -+ loc.low_prio = 0; -+ if (mpcb->master_sk) -+ loc.if_idx = mpcb->master_sk->sk_bound_dev_if; -+ else -+ loc.if_idx = 0; -+ -+ rem.addr.s_addr = inet_sk(meta_sk)->inet_daddr; -+ rem.port = inet_sk(meta_sk)->inet_dport; -+ rem.rem4_id = 0; /* Default 0 */ -+ -+ mptcp_init4_subsockets(meta_sk, &loc, &rem); -+ } else { -+#if IS_ENABLED(CONFIG_IPV6) -+ struct mptcp_loc6 loc; -+ struct mptcp_rem6 rem; -+ -+ loc.addr = inet6_sk(meta_sk)->saddr; -+ loc.loc6_id = 0; -+ loc.low_prio = 0; -+ if (mpcb->master_sk) -+ loc.if_idx = mpcb->master_sk->sk_bound_dev_if; -+ else -+ loc.if_idx = 0; -+ -+ rem.addr = meta_sk->sk_v6_daddr; -+ rem.port = inet_sk(meta_sk)->inet_dport; -+ rem.rem6_id = 0; /* Default 0 */ -+ -+ mptcp_init6_subsockets(meta_sk, &loc, &rem); -+#endif -+ } -+ goto next_subflow; -+ } -+ -+exit: -+ release_sock(meta_sk); -+ mutex_unlock(&mpcb->mpcb_mutex); -+ sock_put(meta_sk); -+} -+ -+static void ndiffports_new_session(const struct sock *meta_sk) -+{ -+ struct mptcp_cb *mpcb = tcp_sk(meta_sk)->mpcb; -+ struct ndiffports_priv *fmp = (struct ndiffports_priv *)&mpcb->mptcp_pm[0]; -+ -+ /* Initialize workqueue-struct */ -+ INIT_WORK(&fmp->subflow_work, create_subflow_worker); -+ fmp->mpcb = mpcb; -+} -+ -+static void ndiffports_create_subflows(struct sock *meta_sk) -+{ -+ const struct mptcp_cb *mpcb = tcp_sk(meta_sk)->mpcb; -+ struct ndiffports_priv *pm_priv = (struct ndiffports_priv *)&mpcb->mptcp_pm[0]; -+ -+ if (mpcb->infinite_mapping_snd || mpcb->infinite_mapping_rcv || -+ mpcb->send_infinite_mapping || -+ mpcb->server_side || sock_flag(meta_sk, SOCK_DEAD)) -+ return; -+ -+ if (!work_pending(&pm_priv->subflow_work)) { -+ sock_hold(meta_sk); -+ queue_work(mptcp_wq, &pm_priv->subflow_work); -+ } -+} -+ -+static int ndiffports_get_local_id(sa_family_t family, union inet_addr *addr, -+ struct net *net, bool *low_prio) -+{ -+ return 0; -+} -+ -+static struct mptcp_pm_ops ndiffports __read_mostly = { -+ .new_session = ndiffports_new_session, -+ .fully_established = ndiffports_create_subflows, -+ .get_local_id = ndiffports_get_local_id, -+ .name = "ndiffports", -+ .owner = THIS_MODULE, -+}; -+ -+/* General initialization of MPTCP_PM */ -+static int __init ndiffports_register(void) -+{ -+ BUILD_BUG_ON(sizeof(struct ndiffports_priv) > MPTCP_PM_SIZE); -+ -+ if (mptcp_register_path_manager(&ndiffports)) -+ goto exit; -+ -+ return 0; -+ -+exit: -+ return -1; -+} -+ -+static void ndiffports_unregister(void) -+{ -+ mptcp_unregister_path_manager(&ndiffports); -+} -+ -+module_init(ndiffports_register); -+module_exit(ndiffports_unregister); -+ -+MODULE_AUTHOR("Christoph Paasch"); -+MODULE_LICENSE("GPL"); -+MODULE_DESCRIPTION("NDIFF-PORTS MPTCP"); -+MODULE_VERSION("0.88"); -diff -aurN linux-4.9.162/net/mptcp/mptcp_olia.c mptcp-mptcp_v0.93/net/mptcp/mptcp_olia.c ---- linux-4.9.162/net/mptcp/mptcp_olia.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_v0.93/net/mptcp/mptcp_olia.c 2019-03-14 14:02:32.000000000 +0100 -@@ -0,0 +1,309 @@ -+/* -+ * MPTCP implementation - OPPORTUNISTIC LINKED INCREASES CONGESTION CONTROL: -+ * -+ * Algorithm design: -+ * Ramin Khalili -+ * Nicolas Gast -+ * Jean-Yves Le Boudec -+ * -+ * Implementation: -+ * Ramin Khalili -+ * -+ * Ported to the official MPTCP-kernel: -+ * Christoph Paasch -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version -+ * 2 of the License, or (at your option) any later version. -+ */ -+ -+ -+#include -+#include -+ -+#include -+ -+static int scale = 10; -+ -+struct mptcp_olia { -+ u32 mptcp_loss1; -+ u32 mptcp_loss2; -+ u32 mptcp_loss3; -+ int epsilon_num; -+ u32 epsilon_den; -+ int mptcp_snd_cwnd_cnt; -+}; -+ -+static inline int mptcp_olia_sk_can_send(const struct sock *sk) -+{ -+ return mptcp_sk_can_send(sk) && tcp_sk(sk)->srtt_us; -+} -+ -+static inline u64 mptcp_olia_scale(u64 val, int scale) -+{ -+ return (u64) val << scale; -+} -+ -+/* take care of artificially inflate (see RFC5681) -+ * of cwnd during fast-retransmit phase -+ */ -+static u32 mptcp_get_crt_cwnd(struct sock *sk) -+{ -+ const struct inet_connection_sock *icsk = inet_csk(sk); -+ -+ if (icsk->icsk_ca_state == TCP_CA_Recovery) -+ return tcp_sk(sk)->snd_ssthresh; -+ else -+ return tcp_sk(sk)->snd_cwnd; -+} -+ -+/* return the dominator of the first term of the increasing term */ -+static u64 mptcp_get_rate(const struct mptcp_cb *mpcb , u32 path_rtt) -+{ -+ struct sock *sk; -+ u64 rate = 1; /* We have to avoid a zero-rate because it is used as a divisor */ -+ -+ mptcp_for_each_sk(mpcb, sk) { -+ struct tcp_sock *tp = tcp_sk(sk); -+ u64 scaled_num; -+ u32 tmp_cwnd; -+ -+ if (!mptcp_olia_sk_can_send(sk)) -+ continue; -+ -+ tmp_cwnd = mptcp_get_crt_cwnd(sk); -+ scaled_num = mptcp_olia_scale(tmp_cwnd, scale) * path_rtt; -+ rate += div_u64(scaled_num , tp->srtt_us); -+ } -+ rate *= rate; -+ return rate; -+} -+ -+/* find the maximum cwnd, used to find set M */ -+static u32 mptcp_get_max_cwnd(const struct mptcp_cb *mpcb) -+{ -+ struct sock *sk; -+ u32 best_cwnd = 0; -+ -+ mptcp_for_each_sk(mpcb, sk) { -+ u32 tmp_cwnd; -+ -+ if (!mptcp_olia_sk_can_send(sk)) -+ continue; -+ -+ tmp_cwnd = mptcp_get_crt_cwnd(sk); -+ if (tmp_cwnd > best_cwnd) -+ best_cwnd = tmp_cwnd; -+ } -+ return best_cwnd; -+} -+ -+static void mptcp_get_epsilon(const struct mptcp_cb *mpcb) -+{ -+ struct mptcp_olia *ca; -+ struct tcp_sock *tp; -+ struct sock *sk; -+ u64 tmp_int, tmp_rtt, best_int = 0, best_rtt = 1; -+ u32 max_cwnd, tmp_cwnd; -+ u8 M = 0, B_not_M = 0; -+ -+ /* TODO - integrate this in the following loop - we just want to iterate once */ -+ -+ max_cwnd = mptcp_get_max_cwnd(mpcb); -+ -+ /* find the best path */ -+ mptcp_for_each_sk(mpcb, sk) { -+ tp = tcp_sk(sk); -+ ca = inet_csk_ca(sk); -+ -+ if (!mptcp_olia_sk_can_send(sk)) -+ continue; -+ -+ tmp_rtt = (u64)tp->srtt_us * tp->srtt_us; -+ /* TODO - check here and rename variables */ -+ tmp_int = max(ca->mptcp_loss3 - ca->mptcp_loss2, -+ ca->mptcp_loss2 - ca->mptcp_loss1); -+ -+ if ((u64)tmp_int * best_rtt >= (u64)best_int * tmp_rtt) { -+ best_rtt = tmp_rtt; -+ best_int = tmp_int; -+ } -+ } -+ -+ /* TODO - integrate this here in mptcp_get_max_cwnd and in the previous loop */ -+ /* find the size of M and B_not_M */ -+ mptcp_for_each_sk(mpcb, sk) { -+ tp = tcp_sk(sk); -+ ca = inet_csk_ca(sk); -+ -+ if (!mptcp_olia_sk_can_send(sk)) -+ continue; -+ -+ tmp_cwnd = mptcp_get_crt_cwnd(sk); -+ if (tmp_cwnd == max_cwnd) { -+ M++; -+ } else { -+ tmp_rtt = (u64)tp->srtt_us * tp->srtt_us; -+ tmp_int = max(ca->mptcp_loss3 - ca->mptcp_loss2, -+ ca->mptcp_loss2 - ca->mptcp_loss1); -+ -+ if ((u64)tmp_int * best_rtt == (u64)best_int * tmp_rtt) -+ B_not_M++; -+ } -+ } -+ -+ /* check if the path is in M or B_not_M and set the value of epsilon accordingly */ -+ mptcp_for_each_sk(mpcb, sk) { -+ tp = tcp_sk(sk); -+ ca = inet_csk_ca(sk); -+ -+ if (!mptcp_olia_sk_can_send(sk)) -+ continue; -+ -+ if (B_not_M == 0) { -+ ca->epsilon_num = 0; -+ ca->epsilon_den = 1; -+ } else { -+ tmp_rtt = (u64)tp->srtt_us * tp->srtt_us; -+ tmp_int = max(ca->mptcp_loss3 - ca->mptcp_loss2, -+ ca->mptcp_loss2 - ca->mptcp_loss1); -+ tmp_cwnd = mptcp_get_crt_cwnd(sk); -+ -+ if (tmp_cwnd < max_cwnd && -+ (u64)tmp_int * best_rtt == (u64)best_int * tmp_rtt) { -+ ca->epsilon_num = 1; -+ ca->epsilon_den = mpcb->cnt_established * B_not_M; -+ } else if (tmp_cwnd == max_cwnd) { -+ ca->epsilon_num = -1; -+ ca->epsilon_den = mpcb->cnt_established * M; -+ } else { -+ ca->epsilon_num = 0; -+ ca->epsilon_den = 1; -+ } -+ } -+ } -+} -+ -+/* setting the initial values */ -+static void mptcp_olia_init(struct sock *sk) -+{ -+ const struct tcp_sock *tp = tcp_sk(sk); -+ struct mptcp_olia *ca = inet_csk_ca(sk); -+ -+ if (mptcp(tp)) { -+ ca->mptcp_loss1 = tp->snd_una; -+ ca->mptcp_loss2 = tp->snd_una; -+ ca->mptcp_loss3 = tp->snd_una; -+ ca->mptcp_snd_cwnd_cnt = 0; -+ ca->epsilon_num = 0; -+ ca->epsilon_den = 1; -+ } -+} -+ -+/* updating inter-loss distance and ssthresh */ -+static void mptcp_olia_set_state(struct sock *sk, u8 new_state) -+{ -+ if (!mptcp(tcp_sk(sk))) -+ return; -+ -+ if (new_state == TCP_CA_Loss || -+ new_state == TCP_CA_Recovery || new_state == TCP_CA_CWR) { -+ struct mptcp_olia *ca = inet_csk_ca(sk); -+ -+ if (ca->mptcp_loss3 != ca->mptcp_loss2 && -+ !inet_csk(sk)->icsk_retransmits) { -+ ca->mptcp_loss1 = ca->mptcp_loss2; -+ ca->mptcp_loss2 = ca->mptcp_loss3; -+ } -+ } -+} -+ -+/* main algorithm */ -+static void mptcp_olia_cong_avoid(struct sock *sk, u32 ack, u32 acked) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct mptcp_olia *ca = inet_csk_ca(sk); -+ const struct mptcp_cb *mpcb = tp->mpcb; -+ -+ u64 inc_num, inc_den, rate, cwnd_scaled; -+ -+ if (!mptcp(tp)) { -+ tcp_reno_cong_avoid(sk, ack, acked); -+ return; -+ } -+ -+ ca->mptcp_loss3 = tp->snd_una; -+ -+ if (!tcp_is_cwnd_limited(sk)) -+ return; -+ -+ /* slow start if it is in the safe area */ -+ if (tcp_in_slow_start(tp)) { -+ tcp_slow_start(tp, acked); -+ return; -+ } -+ -+ mptcp_get_epsilon(mpcb); -+ rate = mptcp_get_rate(mpcb, tp->srtt_us); -+ cwnd_scaled = mptcp_olia_scale(tp->snd_cwnd, scale); -+ inc_den = ca->epsilon_den * tp->snd_cwnd * rate ? : 1; -+ -+ /* calculate the increasing term, scaling is used to reduce the rounding effect */ -+ if (ca->epsilon_num == -1) { -+ if (ca->epsilon_den * cwnd_scaled * cwnd_scaled < rate) { -+ inc_num = rate - ca->epsilon_den * -+ cwnd_scaled * cwnd_scaled; -+ ca->mptcp_snd_cwnd_cnt -= div64_u64( -+ mptcp_olia_scale(inc_num , scale) , inc_den); -+ } else { -+ inc_num = ca->epsilon_den * -+ cwnd_scaled * cwnd_scaled - rate; -+ ca->mptcp_snd_cwnd_cnt += div64_u64( -+ mptcp_olia_scale(inc_num , scale) , inc_den); -+ } -+ } else { -+ inc_num = ca->epsilon_num * rate + -+ ca->epsilon_den * cwnd_scaled * cwnd_scaled; -+ ca->mptcp_snd_cwnd_cnt += div64_u64( -+ mptcp_olia_scale(inc_num , scale) , inc_den); -+ } -+ -+ -+ if (ca->mptcp_snd_cwnd_cnt >= (1 << scale) - 1) { -+ if (tp->snd_cwnd < tp->snd_cwnd_clamp) -+ tp->snd_cwnd++; -+ ca->mptcp_snd_cwnd_cnt = 0; -+ } else if (ca->mptcp_snd_cwnd_cnt <= 0 - (1 << scale) + 1) { -+ tp->snd_cwnd = max((int) 1 , (int) tp->snd_cwnd - 1); -+ ca->mptcp_snd_cwnd_cnt = 0; -+ } -+} -+ -+static struct tcp_congestion_ops mptcp_olia = { -+ .init = mptcp_olia_init, -+ .ssthresh = tcp_reno_ssthresh, -+ .cong_avoid = mptcp_olia_cong_avoid, -+ .set_state = mptcp_olia_set_state, -+ .owner = THIS_MODULE, -+ .name = "olia", -+}; -+ -+static int __init mptcp_olia_register(void) -+{ -+ BUILD_BUG_ON(sizeof(struct mptcp_olia) > ICSK_CA_PRIV_SIZE); -+ return tcp_register_congestion_control(&mptcp_olia); -+} -+ -+static void __exit mptcp_olia_unregister(void) -+{ -+ tcp_unregister_congestion_control(&mptcp_olia); -+} -+ -+module_init(mptcp_olia_register); -+module_exit(mptcp_olia_unregister); -+ -+MODULE_AUTHOR("Ramin Khalili, Nicolas Gast, Jean-Yves Le Boudec"); -+MODULE_LICENSE("GPL"); -+MODULE_DESCRIPTION("MPTCP COUPLED CONGESTION CONTROL"); -+MODULE_VERSION("0.1"); -diff -aurN linux-4.9.162/net/mptcp/mptcp_output.c mptcp-mptcp_v0.93/net/mptcp/mptcp_output.c ---- linux-4.9.162/net/mptcp/mptcp_output.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_v0.93/net/mptcp/mptcp_output.c 2019-03-14 14:02:32.000000000 +0100 -@@ -0,0 +1,1818 @@ -+/* -+ * MPTCP implementation - Sending side -+ * -+ * Initial Design & Implementation: -+ * Sébastien Barré -+ * -+ * Current Maintainer & Author: -+ * Christoph Paasch -+ * -+ * Additional authors: -+ * Jaakko Korkeaniemi -+ * Gregory Detal -+ * Fabien Duchêne -+ * Andreas Seelinger -+ * Lavkesh Lahngir -+ * Andreas Ripke -+ * Vlad Dogaru -+ * Octavian Purdila -+ * John Ronan -+ * Catalin Nicutar -+ * Brandon Heller -+ * -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version -+ * 2 of the License, or (at your option) any later version. -+ */ -+ -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+ -+static const int mptcp_dss_len = MPTCP_SUB_LEN_DSS_ALIGN + -+ MPTCP_SUB_LEN_ACK_ALIGN + -+ MPTCP_SUB_LEN_SEQ_ALIGN; -+ -+static inline int mptcp_sub_len_remove_addr(u16 bitfield) -+{ -+ unsigned int c; -+ for (c = 0; bitfield; c++) -+ bitfield &= bitfield - 1; -+ return MPTCP_SUB_LEN_REMOVE_ADDR + c - 1; -+} -+ -+int mptcp_sub_len_remove_addr_align(u16 bitfield) -+{ -+ return ALIGN(mptcp_sub_len_remove_addr(bitfield), 4); -+} -+EXPORT_SYMBOL(mptcp_sub_len_remove_addr_align); -+ -+/* get the data-seq and end-data-seq and store them again in the -+ * tcp_skb_cb -+ */ -+static bool mptcp_reconstruct_mapping(struct sk_buff *skb) -+{ -+ const struct mp_dss *mpdss = (struct mp_dss *)TCP_SKB_CB(skb)->dss; -+ u32 *p32; -+ u16 *p16; -+ -+ if (!mptcp_is_data_seq(skb)) -+ return false; -+ -+ if (!mpdss->M) -+ return false; -+ -+ /* Move the pointer to the data-seq */ -+ p32 = (u32 *)mpdss; -+ p32++; -+ if (mpdss->A) { -+ p32++; -+ if (mpdss->a) -+ p32++; -+ } -+ -+ TCP_SKB_CB(skb)->seq = ntohl(*p32); -+ -+ /* Get the data_len to calculate the end_data_seq */ -+ p32++; -+ p32++; -+ p16 = (u16 *)p32; -+ TCP_SKB_CB(skb)->end_seq = ntohs(*p16) + TCP_SKB_CB(skb)->seq; -+ -+ return true; -+} -+ -+static bool mptcp_is_reinjected(const struct sk_buff *skb) -+{ -+ return TCP_SKB_CB(skb)->mptcp_flags & MPTCP_REINJECT; -+} -+ -+static void mptcp_find_and_set_pathmask(const struct sock *meta_sk, struct sk_buff *skb) -+{ -+ struct sk_buff *skb_it; -+ -+ skb_it = tcp_write_queue_head(meta_sk); -+ -+ tcp_for_write_queue_from(skb_it, meta_sk) { -+ if (skb_it == tcp_send_head(meta_sk)) -+ break; -+ -+ if (TCP_SKB_CB(skb_it)->seq == TCP_SKB_CB(skb)->seq) { -+ TCP_SKB_CB(skb)->path_mask = TCP_SKB_CB(skb_it)->path_mask; -+ break; -+ } -+ } -+} -+ -+/* Reinject data from one TCP subflow to the meta_sk. If sk == NULL, we are -+ * coming from the meta-retransmit-timer -+ */ -+static void __mptcp_reinject_data(struct sk_buff *orig_skb, struct sock *meta_sk, -+ struct sock *sk, int clone_it) -+{ -+ struct sk_buff *skb, *skb1; -+ const struct tcp_sock *meta_tp = tcp_sk(meta_sk); -+ struct mptcp_cb *mpcb = meta_tp->mpcb; -+ u32 seq, end_seq; -+ -+ if (clone_it) { -+ /* pskb_copy is necessary here, because the TCP/IP-headers -+ * will be changed when it's going to be reinjected on another -+ * subflow. -+ */ -+ skb = pskb_copy_for_clone(orig_skb, GFP_ATOMIC); -+ } else { -+ __skb_unlink(orig_skb, &sk->sk_write_queue); -+ sock_set_flag(sk, SOCK_QUEUE_SHRUNK); -+ sk->sk_wmem_queued -= orig_skb->truesize; -+ sk_mem_uncharge(sk, orig_skb->truesize); -+ skb = orig_skb; -+ } -+ if (unlikely(!skb)) -+ return; -+ -+ if (sk && !mptcp_reconstruct_mapping(skb)) { -+ __kfree_skb(skb); -+ return; -+ } -+ -+ skb->sk = meta_sk; -+ -+ /* Reset subflow-specific TCP control-data */ -+ TCP_SKB_CB(skb)->sacked = 0; -+ TCP_SKB_CB(skb)->tcp_flags &= (TCPHDR_ACK | TCPHDR_PSH); -+ -+ /* If it reached already the destination, we don't have to reinject it */ -+ if (!after(TCP_SKB_CB(skb)->end_seq, meta_tp->snd_una)) { -+ __kfree_skb(skb); -+ return; -+ } -+ -+ /* Only reinject segments that are fully covered by the mapping */ -+ if (skb->len + (mptcp_is_data_fin(skb) ? 1 : 0) != -+ TCP_SKB_CB(skb)->end_seq - TCP_SKB_CB(skb)->seq) { -+ u32 seq = TCP_SKB_CB(skb)->seq; -+ u32 end_seq = TCP_SKB_CB(skb)->end_seq; -+ -+ __kfree_skb(skb); -+ -+ /* Ok, now we have to look for the full mapping in the meta -+ * send-queue :S -+ */ -+ tcp_for_write_queue(skb, meta_sk) { -+ /* Not yet at the mapping? */ -+ if (before(TCP_SKB_CB(skb)->seq, seq)) -+ continue; -+ /* We have passed by the mapping */ -+ if (after(TCP_SKB_CB(skb)->end_seq, end_seq)) -+ return; -+ -+ __mptcp_reinject_data(skb, meta_sk, NULL, 1); -+ } -+ return; -+ } -+ -+ /* Segment goes back to the MPTCP-layer. So, we need to zero the -+ * path_mask/dss. -+ */ -+ memset(TCP_SKB_CB(skb)->dss, 0 , mptcp_dss_len); -+ -+ /* We need to find out the path-mask from the meta-write-queue -+ * to properly select a subflow. -+ */ -+ mptcp_find_and_set_pathmask(meta_sk, skb); -+ -+ /* If it's empty, just add */ -+ if (skb_queue_empty(&mpcb->reinject_queue)) { -+ skb_queue_head(&mpcb->reinject_queue, skb); -+ return; -+ } -+ -+ /* Find place to insert skb - or even we can 'drop' it, as the -+ * data is already covered by other skb's in the reinject-queue. -+ * -+ * This is inspired by code from tcp_data_queue. -+ */ -+ -+ skb1 = skb_peek_tail(&mpcb->reinject_queue); -+ seq = TCP_SKB_CB(skb)->seq; -+ while (1) { -+ if (!after(TCP_SKB_CB(skb1)->seq, seq)) -+ break; -+ if (skb_queue_is_first(&mpcb->reinject_queue, skb1)) { -+ skb1 = NULL; -+ break; -+ } -+ skb1 = skb_queue_prev(&mpcb->reinject_queue, skb1); -+ } -+ -+ /* Do skb overlap to previous one? */ -+ end_seq = TCP_SKB_CB(skb)->end_seq; -+ if (skb1 && before(seq, TCP_SKB_CB(skb1)->end_seq)) { -+ if (!after(end_seq, TCP_SKB_CB(skb1)->end_seq)) { -+ /* All the bits are present. Don't reinject */ -+ __kfree_skb(skb); -+ return; -+ } -+ if (seq == TCP_SKB_CB(skb1)->seq) { -+ if (skb_queue_is_first(&mpcb->reinject_queue, skb1)) -+ skb1 = NULL; -+ else -+ skb1 = skb_queue_prev(&mpcb->reinject_queue, skb1); -+ } -+ } -+ if (!skb1) -+ __skb_queue_head(&mpcb->reinject_queue, skb); -+ else -+ __skb_queue_after(&mpcb->reinject_queue, skb1, skb); -+ -+ /* And clean segments covered by new one as whole. */ -+ while (!skb_queue_is_last(&mpcb->reinject_queue, skb)) { -+ skb1 = skb_queue_next(&mpcb->reinject_queue, skb); -+ -+ if (!after(end_seq, TCP_SKB_CB(skb1)->seq)) -+ break; -+ -+ if (before(end_seq, TCP_SKB_CB(skb1)->end_seq)) -+ break; -+ -+ __skb_unlink(skb1, &mpcb->reinject_queue); -+ __kfree_skb(skb1); -+ } -+ return; -+} -+ -+/* Inserts data into the reinject queue */ -+void mptcp_reinject_data(struct sock *sk, int clone_it) -+{ -+ struct sk_buff *skb_it, *tmp; -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct sock *meta_sk = tp->meta_sk; -+ -+ /* It has already been closed - there is really no point in reinjecting */ -+ if (meta_sk->sk_state == TCP_CLOSE) -+ return; -+ -+ skb_queue_walk_safe(&sk->sk_write_queue, skb_it, tmp) { -+ struct tcp_skb_cb *tcb = TCP_SKB_CB(skb_it); -+ /* Subflow syn's and fin's are not reinjected. -+ * -+ * As well as empty subflow-fins with a data-fin. -+ * They are reinjected below (without the subflow-fin-flag) -+ */ -+ if (tcb->tcp_flags & TCPHDR_SYN || -+ (tcb->tcp_flags & TCPHDR_FIN && !mptcp_is_data_fin(skb_it)) || -+ (tcb->tcp_flags & TCPHDR_FIN && mptcp_is_data_fin(skb_it) && !skb_it->len)) -+ continue; -+ -+ if (mptcp_is_reinjected(skb_it)) -+ continue; -+ -+ tcb->mptcp_flags |= MPTCP_REINJECT; -+ __mptcp_reinject_data(skb_it, meta_sk, sk, clone_it); -+ } -+ -+ skb_it = tcp_write_queue_tail(meta_sk); -+ /* If sk has sent the empty data-fin, we have to reinject it too. */ -+ if (skb_it && mptcp_is_data_fin(skb_it) && skb_it->len == 0 && -+ TCP_SKB_CB(skb_it)->path_mask & mptcp_pi_to_flag(tp->mptcp->path_index)) { -+ __mptcp_reinject_data(skb_it, meta_sk, NULL, 1); -+ } -+ -+ tp->pf = 1; -+ -+ mptcp_push_pending_frames(meta_sk); -+} -+EXPORT_SYMBOL(mptcp_reinject_data); -+ -+static void mptcp_combine_dfin(const struct sk_buff *skb, -+ const struct sock *meta_sk, -+ struct sock *subsk) -+{ -+ const struct tcp_sock *meta_tp = tcp_sk(meta_sk); -+ const struct mptcp_cb *mpcb = meta_tp->mpcb; -+ -+ /* In infinite mapping we always try to combine */ -+ if (mpcb->infinite_mapping_snd) -+ goto combine; -+ -+ /* Don't combine, if they didn't combine when closing - otherwise we end -+ * up in TIME_WAIT, even if our app is smart enough to avoid it. -+ */ -+ if (!mptcp_sk_can_recv(meta_sk) && !mpcb->dfin_combined) -+ return; -+ -+ /* Don't combine if there is still outstanding data that remains to be -+ * DATA_ACKed, because otherwise we may never be able to deliver this. -+ */ -+ if (meta_tp->snd_una != TCP_SKB_CB(skb)->seq) -+ return; -+ -+combine: -+ if (tcp_close_state(subsk)) { -+ subsk->sk_shutdown |= SEND_SHUTDOWN; -+ TCP_SKB_CB(skb)->tcp_flags |= TCPHDR_FIN; -+ } -+} -+ -+static int mptcp_write_dss_mapping(const struct tcp_sock *tp, const struct sk_buff *skb, -+ __be32 *ptr) -+{ -+ const struct tcp_skb_cb *tcb = TCP_SKB_CB(skb); -+ __be32 *start = ptr; -+ __u16 data_len; -+ -+ *ptr++ = htonl(tcb->seq); /* data_seq */ -+ -+ /* If it's a non-data DATA_FIN, we set subseq to 0 (draft v7) */ -+ if (mptcp_is_data_fin(skb) && skb->len == 0) -+ *ptr++ = 0; /* subseq */ -+ else -+ *ptr++ = htonl(tp->write_seq - tp->mptcp->snt_isn); /* subseq */ -+ -+ if (tcb->mptcp_flags & MPTCPHDR_INF) -+ data_len = 0; -+ else -+ data_len = tcb->end_seq - tcb->seq; -+ -+ if (tp->mpcb->dss_csum && data_len) { -+ __be16 *p16 = (__be16 *)ptr; -+ __be32 hdseq = mptcp_get_highorder_sndbits(skb, tp->mpcb); -+ __wsum csum; -+ -+ *ptr = htonl(((data_len) << 16) | -+ (TCPOPT_EOL << 8) | -+ (TCPOPT_EOL)); -+ csum = csum_partial(ptr - 2, 12, skb->csum); -+ p16++; -+ *p16++ = csum_fold(csum_partial(&hdseq, sizeof(hdseq), csum)); -+ } else { -+ *ptr++ = htonl(((data_len) << 16) | -+ (TCPOPT_NOP << 8) | -+ (TCPOPT_NOP)); -+ } -+ -+ return ptr - start; -+} -+ -+static int mptcp_write_dss_data_ack(const struct tcp_sock *tp, const struct sk_buff *skb, -+ __be32 *ptr) -+{ -+ struct mp_dss *mdss = (struct mp_dss *)ptr; -+ __be32 *start = ptr; -+ -+ mdss->kind = TCPOPT_MPTCP; -+ mdss->sub = MPTCP_SUB_DSS; -+ mdss->rsv1 = 0; -+ mdss->rsv2 = 0; -+ mdss->F = mptcp_is_data_fin(skb) ? 1 : 0; -+ mdss->m = 0; -+ mdss->M = mptcp_is_data_seq(skb) ? 1 : 0; -+ mdss->a = 0; -+ mdss->A = 1; -+ mdss->len = mptcp_sub_len_dss(mdss, tp->mpcb->dss_csum); -+ ptr++; -+ -+ *ptr++ = htonl(mptcp_meta_tp(tp)->rcv_nxt); -+ -+ return ptr - start; -+} -+ -+/* RFC6824 states that once a particular subflow mapping has been sent -+ * out it must never be changed. However, packets may be split while -+ * they are in the retransmission queue (due to SACK or ACKs) and that -+ * arguably means that we would change the mapping (e.g. it splits it, -+ * our sends out a subset of the initial mapping). -+ * -+ * Furthermore, the skb checksum is not always preserved across splits -+ * (e.g. mptcp_fragment) which would mean that we need to recompute -+ * the DSS checksum in this case. -+ * -+ * To avoid this we save the initial DSS mapping which allows us to -+ * send the same DSS mapping even for fragmented retransmits. -+ */ -+static void mptcp_save_dss_data_seq(const struct tcp_sock *tp, struct sk_buff *skb) -+{ -+ struct tcp_skb_cb *tcb = TCP_SKB_CB(skb); -+ __be32 *ptr = (__be32 *)tcb->dss; -+ -+ tcb->mptcp_flags |= MPTCPHDR_SEQ; -+ -+ ptr += mptcp_write_dss_data_ack(tp, skb, ptr); -+ ptr += mptcp_write_dss_mapping(tp, skb, ptr); -+} -+ -+/* Write the saved DSS mapping to the header */ -+static int mptcp_write_dss_data_seq(const struct tcp_sock *tp, struct sk_buff *skb, -+ __be32 *ptr) -+{ -+ __be32 *start = ptr; -+ -+ memcpy(ptr, TCP_SKB_CB(skb)->dss, mptcp_dss_len); -+ -+ /* update the data_ack */ -+ start[1] = htonl(mptcp_meta_tp(tp)->rcv_nxt); -+ -+ /* dss is in a union with inet_skb_parm and -+ * the IP layer expects zeroed IPCB fields. -+ */ -+ memset(TCP_SKB_CB(skb)->dss, 0 , mptcp_dss_len); -+ -+ return mptcp_dss_len/sizeof(*ptr); -+} -+ -+static bool mptcp_skb_entail(struct sock *sk, struct sk_buff *skb, int reinject) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ const struct sock *meta_sk = mptcp_meta_sk(sk); -+ const struct mptcp_cb *mpcb = tp->mpcb; -+ struct tcp_skb_cb *tcb; -+ struct sk_buff *subskb = NULL; -+ -+ if (!reinject) -+ TCP_SKB_CB(skb)->mptcp_flags |= (mpcb->snd_hiseq_index ? -+ MPTCPHDR_SEQ64_INDEX : 0); -+ -+ subskb = pskb_copy_for_clone(skb, GFP_ATOMIC); -+ if (!subskb) -+ return false; -+ -+ /* At the subflow-level we need to call again tcp_init_tso_segs. We -+ * force this, by setting pcount to 0. It has been set to 1 prior to -+ * the call to mptcp_skb_entail. -+ */ -+ tcp_skb_pcount_set(subskb, 0); -+ -+ TCP_SKB_CB(skb)->path_mask |= mptcp_pi_to_flag(tp->mptcp->path_index); -+ -+ /* Compute checksum, if: -+ * 1. The current route does not support csum offloading but it was -+ * assumed that it does (ip_summed is CHECKSUM_PARTIAL) -+ * 2. We need the DSS-checksum but ended up not pre-computing it -+ * (e.g., in the case of TFO retransmissions). -+ */ -+ if (skb->ip_summed == CHECKSUM_PARTIAL && -+ (!sk_check_csum_caps(sk) || tp->mpcb->dss_csum)) { -+ subskb->csum = skb->csum = skb_checksum(skb, 0, skb->len, 0); -+ subskb->ip_summed = skb->ip_summed = CHECKSUM_NONE; -+ } -+ -+ tcb = TCP_SKB_CB(subskb); -+ -+ if (tp->mpcb->send_infinite_mapping && -+ !tp->mpcb->infinite_mapping_snd && -+ !before(tcb->seq, mptcp_meta_tp(tp)->snd_nxt)) { -+ tp->mptcp->fully_established = 1; -+ tp->mpcb->infinite_mapping_snd = 1; -+ tp->mptcp->infinite_cutoff_seq = tp->write_seq; -+ tcb->mptcp_flags |= MPTCPHDR_INF; -+ } -+ -+ if (mptcp_is_data_fin(subskb)) -+ mptcp_combine_dfin(subskb, meta_sk, sk); -+ -+ mptcp_save_dss_data_seq(tp, subskb); -+ -+ tcb->seq = tp->write_seq; -+ -+ /* Take into account seg len */ -+ tp->write_seq += subskb->len + ((tcb->tcp_flags & TCPHDR_FIN) ? 1 : 0); -+ tcb->end_seq = tp->write_seq; -+ -+ /* If it's a non-payload DATA_FIN (also no subflow-fin), the -+ * segment is not part of the subflow but on a meta-only-level. -+ */ -+ if (!mptcp_is_data_fin(subskb) || tcb->end_seq != tcb->seq) { -+ tcp_add_write_queue_tail(sk, subskb); -+ sk->sk_wmem_queued += subskb->truesize; -+ sk_mem_charge(sk, subskb->truesize); -+ } else { -+ int err; -+ -+ /* Necessary to initialize for tcp_transmit_skb. mss of 1, as -+ * skb->len = 0 will force tso_segs to 1. -+ */ -+ tcp_init_tso_segs(subskb, 1); -+ /* Empty data-fins are sent immediatly on the subflow */ -+ err = tcp_transmit_skb(sk, subskb, 1, GFP_ATOMIC); -+ -+ /* It has not been queued, we can free it now. */ -+ kfree_skb(subskb); -+ -+ if (err) -+ return false; -+ } -+ -+ if (!tp->mptcp->fully_established) { -+ tp->mptcp->second_packet = 1; -+ tp->mptcp->last_end_data_seq = TCP_SKB_CB(skb)->end_seq; -+ } -+ -+ return true; -+} -+ -+/* Fragment an skb and update the mptcp meta-data. Due to reinject, we -+ * might need to undo some operations done by tcp_fragment. -+ */ -+static int mptcp_fragment(struct sock *meta_sk, struct sk_buff *skb, u32 len, -+ gfp_t gfp, int reinject) -+{ -+ int ret, diff, old_factor; -+ struct sk_buff *buff; -+ u8 flags; -+ -+ if (skb_headlen(skb) < len) -+ diff = skb->len - len; -+ else -+ diff = skb->data_len; -+ old_factor = tcp_skb_pcount(skb); -+ -+ /* The mss_now in tcp_fragment is used to set the tso_segs of the skb. -+ * At the MPTCP-level we do not care about the absolute value. All we -+ * care about is that it is set to 1 for accurate packets_out -+ * accounting. -+ */ -+ ret = tcp_fragment(meta_sk, skb, len, UINT_MAX, gfp); -+ if (ret) -+ return ret; -+ -+ buff = skb->next; -+ -+ flags = TCP_SKB_CB(skb)->mptcp_flags; -+ TCP_SKB_CB(skb)->mptcp_flags = flags & ~(MPTCPHDR_FIN); -+ TCP_SKB_CB(buff)->mptcp_flags = flags; -+ TCP_SKB_CB(buff)->path_mask = TCP_SKB_CB(skb)->path_mask; -+ -+ /* If reinject == 1, the buff will be added to the reinject -+ * queue, which is currently not part of memory accounting. So -+ * undo the changes done by tcp_fragment and update the -+ * reinject queue. Also, undo changes to the packet counters. -+ */ -+ if (reinject == 1) { -+ int undo = buff->truesize - diff; -+ meta_sk->sk_wmem_queued -= undo; -+ sk_mem_uncharge(meta_sk, undo); -+ -+ tcp_sk(meta_sk)->mpcb->reinject_queue.qlen++; -+ meta_sk->sk_write_queue.qlen--; -+ -+ if (!before(tcp_sk(meta_sk)->snd_nxt, TCP_SKB_CB(buff)->end_seq)) { -+ undo = old_factor - tcp_skb_pcount(skb) - -+ tcp_skb_pcount(buff); -+ if (undo) -+ tcp_adjust_pcount(meta_sk, skb, -undo); -+ } -+ } -+ -+ return 0; -+} -+ -+/* Inspired by tcp_write_wakeup */ -+int mptcp_write_wakeup(struct sock *meta_sk, int mib) -+{ -+ struct tcp_sock *meta_tp = tcp_sk(meta_sk); -+ struct sk_buff *skb; -+ struct sock *sk_it; -+ int ans = 0; -+ -+ if (meta_sk->sk_state == TCP_CLOSE) -+ return -1; -+ -+ skb = tcp_send_head(meta_sk); -+ if (skb && -+ before(TCP_SKB_CB(skb)->seq, tcp_wnd_end(meta_tp))) { -+ unsigned int mss; -+ unsigned int seg_size = tcp_wnd_end(meta_tp) - TCP_SKB_CB(skb)->seq; -+ struct sock *subsk = meta_tp->mpcb->sched_ops->get_subflow(meta_sk, skb, true); -+ struct tcp_sock *subtp; -+ -+ WARN_ON(TCP_SKB_CB(skb)->sacked); -+ -+ if (!subsk) -+ goto window_probe; -+ subtp = tcp_sk(subsk); -+ mss = tcp_current_mss(subsk); -+ -+ seg_size = min(tcp_wnd_end(meta_tp) - TCP_SKB_CB(skb)->seq, -+ tcp_wnd_end(subtp) - subtp->write_seq); -+ -+ if (before(meta_tp->pushed_seq, TCP_SKB_CB(skb)->end_seq)) -+ meta_tp->pushed_seq = TCP_SKB_CB(skb)->end_seq; -+ -+ /* We are probing the opening of a window -+ * but the window size is != 0 -+ * must have been a result SWS avoidance ( sender ) -+ */ -+ if (seg_size < TCP_SKB_CB(skb)->end_seq - TCP_SKB_CB(skb)->seq || -+ skb->len > mss) { -+ seg_size = min(seg_size, mss); -+ TCP_SKB_CB(skb)->tcp_flags |= TCPHDR_PSH; -+ if (mptcp_fragment(meta_sk, skb, seg_size, -+ GFP_ATOMIC, 0)) -+ return -1; -+ } else if (!tcp_skb_pcount(skb)) { -+ /* see mptcp_write_xmit on why we use UINT_MAX */ -+ tcp_set_skb_tso_segs(skb, UINT_MAX); -+ } -+ -+ TCP_SKB_CB(skb)->tcp_flags |= TCPHDR_PSH; -+ if (!mptcp_skb_entail(subsk, skb, 0)) -+ return -1; -+ skb_mstamp_get(&skb->skb_mstamp); -+ -+ mptcp_check_sndseq_wrap(meta_tp, TCP_SKB_CB(skb)->end_seq - -+ TCP_SKB_CB(skb)->seq); -+ tcp_event_new_data_sent(meta_sk, skb); -+ -+ __tcp_push_pending_frames(subsk, mss, TCP_NAGLE_PUSH); -+ meta_tp->lsndtime = tcp_time_stamp; -+ -+ return 0; -+ } else { -+window_probe: -+ if (between(meta_tp->snd_up, meta_tp->snd_una + 1, -+ meta_tp->snd_una + 0xFFFF)) { -+ mptcp_for_each_sk(meta_tp->mpcb, sk_it) { -+ if (mptcp_sk_can_send_ack(sk_it)) -+ tcp_xmit_probe_skb(sk_it, 1, mib); -+ } -+ } -+ -+ /* At least one of the tcp_xmit_probe_skb's has to succeed */ -+ mptcp_for_each_sk(meta_tp->mpcb, sk_it) { -+ int ret; -+ -+ if (!mptcp_sk_can_send_ack(sk_it)) -+ continue; -+ -+ ret = tcp_xmit_probe_skb(sk_it, 0, mib); -+ if (unlikely(ret > 0)) -+ ans = ret; -+ } -+ return ans; -+ } -+} -+ -+bool mptcp_write_xmit(struct sock *meta_sk, unsigned int mss_now, int nonagle, -+ int push_one, gfp_t gfp) -+{ -+ struct tcp_sock *meta_tp = tcp_sk(meta_sk), *subtp; -+ struct sock *subsk = NULL; -+ struct mptcp_cb *mpcb = meta_tp->mpcb; -+ struct sk_buff *skb; -+ int reinject = 0; -+ unsigned int sublimit; -+ __u32 path_mask = 0; -+ -+ if (inet_csk(meta_sk)->icsk_retransmits) { -+ /* If the timer already once fired, retransmit the head of the -+ * queue to unblock us ASAP. -+ */ -+ if (meta_tp->packets_out && !mpcb->infinite_mapping_snd) -+ mptcp_retransmit_skb(meta_sk, tcp_write_queue_head(meta_sk)); -+ } -+ -+ while ((skb = mpcb->sched_ops->next_segment(meta_sk, &reinject, &subsk, -+ &sublimit))) { -+ unsigned int limit; -+ -+ WARN(TCP_SKB_CB(skb)->sacked, "sacked: %u reinject: %u", -+ TCP_SKB_CB(skb)->sacked, reinject); -+ -+ subtp = tcp_sk(subsk); -+ mss_now = tcp_current_mss(subsk); -+ -+ if (reinject == 1) { -+ if (!after(TCP_SKB_CB(skb)->end_seq, meta_tp->snd_una)) { -+ /* Segment already reached the peer, take the next one */ -+ __skb_unlink(skb, &mpcb->reinject_queue); -+ __kfree_skb(skb); -+ continue; -+ } -+ } -+ -+ /* If the segment was cloned (e.g. a meta retransmission), -+ * the header must be expanded/copied so that there is no -+ * corruption of TSO information. -+ */ -+ if (skb_unclone(skb, GFP_ATOMIC)) -+ break; -+ -+ if (unlikely(!tcp_snd_wnd_test(meta_tp, skb, mss_now))) -+ break; -+ -+ /* Force tso_segs to 1 by using UINT_MAX. -+ * We actually don't care about the exact number of segments -+ * emitted on the subflow. We need just to set tso_segs, because -+ * we still need an accurate packets_out count in -+ * tcp_event_new_data_sent. -+ */ -+ tcp_set_skb_tso_segs(skb, UINT_MAX); -+ -+ /* Check for nagle, irregardless of tso_segs. If the segment is -+ * actually larger than mss_now (TSO segment), then -+ * tcp_nagle_check will have partial == false and always trigger -+ * the transmission. -+ * tcp_write_xmit has a TSO-level nagle check which is not -+ * subject to the MPTCP-level. It is based on the properties of -+ * the subflow, not the MPTCP-level. -+ */ -+ if (unlikely(!tcp_nagle_test(meta_tp, skb, mss_now, -+ (tcp_skb_is_last(meta_sk, skb) ? -+ nonagle : TCP_NAGLE_PUSH)))) -+ break; -+ -+ limit = mss_now; -+ /* skb->len > mss_now is the equivalent of tso_segs > 1 in -+ * tcp_write_xmit. Otherwise split-point would return 0. -+ */ -+ if (skb->len > mss_now && !tcp_urg_mode(meta_tp)) -+ /* We limit the size of the skb so that it fits into the -+ * window. Call tcp_mss_split_point to avoid duplicating -+ * code. -+ * We really only care about fitting the skb into the -+ * window. That's why we use UINT_MAX. If the skb does -+ * not fit into the cwnd_quota or the NIC's max-segs -+ * limitation, it will be split by the subflow's -+ * tcp_write_xmit which does the appropriate call to -+ * tcp_mss_split_point. -+ */ -+ limit = tcp_mss_split_point(meta_sk, skb, mss_now, -+ UINT_MAX / mss_now, -+ nonagle); -+ -+ if (sublimit) -+ limit = min(limit, sublimit); -+ -+ if (skb->len > limit && -+ unlikely(mptcp_fragment(meta_sk, skb, limit, gfp, reinject))) -+ break; -+ -+ if (!mptcp_skb_entail(subsk, skb, reinject)) -+ break; -+ /* Nagle is handled at the MPTCP-layer, so -+ * always push on the subflow -+ */ -+ __tcp_push_pending_frames(subsk, mss_now, TCP_NAGLE_PUSH); -+ meta_tp->lsndtime = tcp_time_stamp; -+ -+ path_mask |= mptcp_pi_to_flag(subtp->mptcp->path_index); -+ skb_mstamp_get(&skb->skb_mstamp); -+ -+ if (!reinject) { -+ mptcp_check_sndseq_wrap(meta_tp, -+ TCP_SKB_CB(skb)->end_seq - -+ TCP_SKB_CB(skb)->seq); -+ tcp_event_new_data_sent(meta_sk, skb); -+ } -+ -+ tcp_minshall_update(meta_tp, mss_now, skb); -+ -+ if (reinject > 0) { -+ __skb_unlink(skb, &mpcb->reinject_queue); -+ kfree_skb(skb); -+ } -+ -+ if (push_one) -+ break; -+ } -+ -+ mptcp_for_each_sk(mpcb, subsk) { -+ subtp = tcp_sk(subsk); -+ -+ if (!(path_mask & mptcp_pi_to_flag(subtp->mptcp->path_index))) -+ continue; -+ -+ /* We have pushed data on this subflow. We ignore the call to -+ * cwnd_validate in tcp_write_xmit as is_cwnd_limited will never -+ * be true (we never push more than what the cwnd can accept). -+ * We need to ensure that we call tcp_cwnd_validate with -+ * is_cwnd_limited set to true if we have filled the cwnd. -+ */ -+ tcp_cwnd_validate(subsk, tcp_packets_in_flight(subtp) >= -+ subtp->snd_cwnd); -+ } -+ -+ return !meta_tp->packets_out && tcp_send_head(meta_sk); -+} -+ -+void mptcp_write_space(struct sock *sk) -+{ -+ mptcp_push_pending_frames(mptcp_meta_sk(sk)); -+} -+ -+u32 __mptcp_select_window(struct sock *sk) -+{ -+ struct inet_connection_sock *icsk = inet_csk(sk); -+ struct tcp_sock *tp = tcp_sk(sk), *meta_tp = mptcp_meta_tp(tp); -+ struct sock *meta_sk = mptcp_meta_sk(sk); -+ int mss, free_space, full_space, window; -+ -+ /* MSS for the peer's data. Previous versions used mss_clamp -+ * here. I don't know if the value based on our guesses -+ * of peer's MSS is better for the performance. It's more correct -+ * but may be worse for the performance because of rcv_mss -+ * fluctuations. --SAW 1998/11/1 -+ */ -+ mss = icsk->icsk_ack.rcv_mss; -+ free_space = tcp_space(meta_sk); -+ full_space = min_t(int, meta_tp->window_clamp, -+ tcp_full_space(meta_sk)); -+ -+ if (mss > full_space) -+ mss = full_space; -+ -+ if (free_space < (full_space >> 1)) { -+ /* If free_space is decreasing due to mostly meta-level -+ * out-of-order packets, don't turn off the quick-ack mode. -+ */ -+ if (meta_tp->rcv_nxt - meta_tp->copied_seq > ((full_space - free_space) >> 1)) -+ icsk->icsk_ack.quick = 0; -+ -+ if (tcp_memory_pressure) -+ /* TODO this has to be adapted when we support different -+ * MSS's among the subflows. -+ */ -+ meta_tp->rcv_ssthresh = min(meta_tp->rcv_ssthresh, -+ 4U * meta_tp->advmss); -+ -+ if (free_space < mss) -+ return 0; -+ } -+ -+ if (free_space > meta_tp->rcv_ssthresh) -+ free_space = meta_tp->rcv_ssthresh; -+ -+ /* Don't do rounding if we are using window scaling, since the -+ * scaled window will not line up with the MSS boundary anyway. -+ */ -+ window = meta_tp->rcv_wnd; -+ if (tp->rx_opt.rcv_wscale) { -+ window = free_space; -+ -+ /* Advertise enough space so that it won't get scaled away. -+ * Import case: prevent zero window announcement if -+ * 1< mss. -+ */ -+ if (((window >> tp->rx_opt.rcv_wscale) << tp-> -+ rx_opt.rcv_wscale) != window) -+ window = (((window >> tp->rx_opt.rcv_wscale) + 1) -+ << tp->rx_opt.rcv_wscale); -+ } else { -+ /* Get the largest window that is a nice multiple of mss. -+ * Window clamp already applied above. -+ * If our current window offering is within 1 mss of the -+ * free space we just keep it. This prevents the divide -+ * and multiply from happening most of the time. -+ * We also don't do any window rounding when the free space -+ * is too small. -+ */ -+ if (window <= free_space - mss || window > free_space) -+ window = (free_space / mss) * mss; -+ else if (mss == full_space && -+ free_space > window + (full_space >> 1)) -+ window = free_space; -+ } -+ -+ return window; -+} -+ -+void mptcp_syn_options(const struct sock *sk, struct tcp_out_options *opts, -+ unsigned *remaining) -+{ -+ const struct tcp_sock *tp = tcp_sk(sk); -+ -+ opts->options |= OPTION_MPTCP; -+ if (is_master_tp(tp)) { -+ opts->mptcp_options |= OPTION_MP_CAPABLE | OPTION_TYPE_SYN; -+ opts->mptcp_ver = tcp_sk(sk)->mptcp_ver; -+ *remaining -= MPTCP_SUB_LEN_CAPABLE_SYN_ALIGN; -+ opts->mp_capable.sender_key = tp->mptcp_loc_key; -+ opts->dss_csum = !!sysctl_mptcp_checksum; -+ } else { -+ const struct mptcp_cb *mpcb = tp->mpcb; -+ -+ opts->mptcp_options |= OPTION_MP_JOIN | OPTION_TYPE_SYN; -+ *remaining -= MPTCP_SUB_LEN_JOIN_SYN_ALIGN; -+ opts->mp_join_syns.token = mpcb->mptcp_rem_token; -+ opts->mp_join_syns.low_prio = tp->mptcp->low_prio; -+ opts->addr_id = tp->mptcp->loc_id; -+ opts->mp_join_syns.sender_nonce = tp->mptcp->mptcp_loc_nonce; -+ } -+} -+ -+void mptcp_synack_options(struct request_sock *req, -+ struct tcp_out_options *opts, unsigned *remaining) -+{ -+ struct mptcp_request_sock *mtreq; -+ mtreq = mptcp_rsk(req); -+ -+ opts->options |= OPTION_MPTCP; -+ /* MPCB not yet set - thus it's a new MPTCP-session */ -+ if (!mtreq->is_sub) { -+ opts->mptcp_options |= OPTION_MP_CAPABLE | OPTION_TYPE_SYNACK; -+ opts->mptcp_ver = mtreq->mptcp_ver; -+ opts->mp_capable.sender_key = mtreq->mptcp_loc_key; -+ opts->dss_csum = !!sysctl_mptcp_checksum || mtreq->dss_csum; -+ *remaining -= MPTCP_SUB_LEN_CAPABLE_SYN_ALIGN; -+ } else { -+ opts->mptcp_options |= OPTION_MP_JOIN | OPTION_TYPE_SYNACK; -+ opts->mp_join_syns.sender_truncated_mac = -+ mtreq->mptcp_hash_tmac; -+ opts->mp_join_syns.sender_nonce = mtreq->mptcp_loc_nonce; -+ opts->mp_join_syns.low_prio = mtreq->low_prio; -+ opts->addr_id = mtreq->loc_id; -+ *remaining -= MPTCP_SUB_LEN_JOIN_SYNACK_ALIGN; -+ } -+} -+ -+void mptcp_established_options(struct sock *sk, struct sk_buff *skb, -+ struct tcp_out_options *opts, unsigned *size) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct mptcp_cb *mpcb = tp->mpcb; -+ const struct tcp_skb_cb *tcb = skb ? TCP_SKB_CB(skb) : NULL; -+ -+ /* We are coming from tcp_current_mss with the meta_sk as an argument. -+ * It does not make sense to check for the options, because when the -+ * segment gets sent, another subflow will be chosen. -+ */ -+ if (!skb && is_meta_sk(sk)) -+ return; -+ -+ if (unlikely(tp->send_mp_fclose)) { -+ opts->options |= OPTION_MPTCP; -+ opts->mptcp_options |= OPTION_MP_FCLOSE; -+ opts->mp_capable.receiver_key = mpcb->mptcp_rem_key; -+ *size += MPTCP_SUB_LEN_FCLOSE_ALIGN; -+ return; -+ } -+ -+ /* 1. If we are the sender of the infinite-mapping, we need the -+ * MPTCPHDR_INF-flag, because a retransmission of the -+ * infinite-announcment still needs the mptcp-option. -+ * -+ * We need infinite_cutoff_seq, because retransmissions from before -+ * the infinite-cutoff-moment still need the MPTCP-signalling to stay -+ * consistent. -+ * -+ * 2. If we are the receiver of the infinite-mapping, we always skip -+ * mptcp-options, because acknowledgments from before the -+ * infinite-mapping point have already been sent out. -+ * -+ * I know, the whole infinite-mapping stuff is ugly... -+ * -+ * TODO: Handle wrapped data-sequence numbers -+ * (even if it's very unlikely) -+ */ -+ if (unlikely(mpcb->infinite_mapping_snd) && -+ ((mpcb->send_infinite_mapping && tcb && -+ mptcp_is_data_seq(skb) && -+ !(tcb->mptcp_flags & MPTCPHDR_INF) && -+ !before(tcb->seq, tp->mptcp->infinite_cutoff_seq)) || -+ !mpcb->send_infinite_mapping)) -+ return; -+ -+ if (unlikely(tp->mptcp->include_mpc)) { -+ opts->options |= OPTION_MPTCP; -+ opts->mptcp_options |= OPTION_MP_CAPABLE | -+ OPTION_TYPE_ACK; -+ *size += MPTCP_SUB_LEN_CAPABLE_ACK_ALIGN; -+ opts->mptcp_ver = mpcb->mptcp_ver; -+ opts->mp_capable.sender_key = mpcb->mptcp_loc_key; -+ opts->mp_capable.receiver_key = mpcb->mptcp_rem_key; -+ opts->dss_csum = mpcb->dss_csum; -+ -+ if (skb) -+ tp->mptcp->include_mpc = 0; -+ } -+ if (unlikely(tp->mptcp->pre_established) && -+ (!skb || !(tcb->tcp_flags & (TCPHDR_FIN | TCPHDR_RST)))) { -+ opts->options |= OPTION_MPTCP; -+ opts->mptcp_options |= OPTION_MP_JOIN | OPTION_TYPE_ACK; -+ *size += MPTCP_SUB_LEN_JOIN_ACK_ALIGN; -+ } -+ -+ if (unlikely(mpcb->addr_signal) && mpcb->pm_ops->addr_signal && -+ mpcb->mptcp_ver >= MPTCP_VERSION_1 && skb && !mptcp_is_data_seq(skb)) { -+ mpcb->pm_ops->addr_signal(sk, size, opts, skb); -+ -+ if (opts->add_addr_v6) -+ /* Skip subsequent options */ -+ return; -+ } -+ -+ if (!tp->mptcp->include_mpc && !tp->mptcp->pre_established) { -+ opts->options |= OPTION_MPTCP; -+ opts->mptcp_options |= OPTION_DATA_ACK; -+ /* If !skb, we come from tcp_current_mss and thus we always -+ * assume that the DSS-option will be set for the data-packet. -+ */ -+ if (skb && !mptcp_is_data_seq(skb)) { -+ *size += MPTCP_SUB_LEN_ACK_ALIGN; -+ } else { -+ /* Doesn't matter, if csum included or not. It will be -+ * either 10 or 12, and thus aligned = 12 -+ */ -+ *size += MPTCP_SUB_LEN_ACK_ALIGN + -+ MPTCP_SUB_LEN_SEQ_ALIGN; -+ } -+ -+ *size += MPTCP_SUB_LEN_DSS_ALIGN; -+ } -+ -+ /* In fallback mp_fail-mode, we have to repeat it until the fallback -+ * has been done by the sender -+ */ -+ if (unlikely(tp->mptcp->send_mp_fail) && skb && -+ MAX_TCP_OPTION_SPACE - *size >= MPTCP_SUB_LEN_FAIL) { -+ opts->options |= OPTION_MPTCP; -+ opts->mptcp_options |= OPTION_MP_FAIL; -+ *size += MPTCP_SUB_LEN_FAIL; -+ } -+ -+ if (unlikely(mpcb->addr_signal) && mpcb->pm_ops->addr_signal && -+ mpcb->mptcp_ver < MPTCP_VERSION_1) -+ mpcb->pm_ops->addr_signal(sk, size, opts, skb); -+ -+ if (unlikely(tp->mptcp->send_mp_prio) && -+ MAX_TCP_OPTION_SPACE - *size >= MPTCP_SUB_LEN_PRIO_ALIGN) { -+ opts->options |= OPTION_MPTCP; -+ opts->mptcp_options |= OPTION_MP_PRIO; -+ if (skb) -+ tp->mptcp->send_mp_prio = 0; -+ *size += MPTCP_SUB_LEN_PRIO_ALIGN; -+ } -+ -+ return; -+} -+ -+u16 mptcp_select_window(struct sock *sk) -+{ -+ u16 new_win = tcp_select_window(sk); -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct tcp_sock *meta_tp = mptcp_meta_tp(tp); -+ -+ meta_tp->rcv_wnd = tp->rcv_wnd; -+ meta_tp->rcv_wup = meta_tp->rcv_nxt; -+ -+ return new_win; -+} -+ -+void mptcp_options_write(__be32 *ptr, struct tcp_sock *tp, -+ const struct tcp_out_options *opts, -+ struct sk_buff *skb) -+{ -+ if (unlikely(OPTION_MP_CAPABLE & opts->mptcp_options)) { -+ struct mp_capable *mpc = (struct mp_capable *)ptr; -+ -+ mpc->kind = TCPOPT_MPTCP; -+ -+ if ((OPTION_TYPE_SYN & opts->mptcp_options) || -+ (OPTION_TYPE_SYNACK & opts->mptcp_options)) { -+ mpc->sender_key = opts->mp_capable.sender_key; -+ mpc->len = MPTCP_SUB_LEN_CAPABLE_SYN; -+ mpc->ver = opts->mptcp_ver; -+ ptr += MPTCP_SUB_LEN_CAPABLE_SYN_ALIGN >> 2; -+ } else if (OPTION_TYPE_ACK & opts->mptcp_options) { -+ mpc->sender_key = opts->mp_capable.sender_key; -+ mpc->receiver_key = opts->mp_capable.receiver_key; -+ mpc->len = MPTCP_SUB_LEN_CAPABLE_ACK; -+ mpc->ver = opts->mptcp_ver; -+ ptr += MPTCP_SUB_LEN_CAPABLE_ACK_ALIGN >> 2; -+ } -+ -+ mpc->sub = MPTCP_SUB_CAPABLE; -+ mpc->a = opts->dss_csum; -+ mpc->b = 0; -+ mpc->rsv = 0; -+ mpc->h = 1; -+ } -+ if (unlikely(OPTION_MP_JOIN & opts->mptcp_options)) { -+ struct mp_join *mpj = (struct mp_join *)ptr; -+ -+ mpj->kind = TCPOPT_MPTCP; -+ mpj->sub = MPTCP_SUB_JOIN; -+ mpj->rsv = 0; -+ -+ if (OPTION_TYPE_SYN & opts->mptcp_options) { -+ mpj->len = MPTCP_SUB_LEN_JOIN_SYN; -+ mpj->u.syn.token = opts->mp_join_syns.token; -+ mpj->u.syn.nonce = opts->mp_join_syns.sender_nonce; -+ mpj->b = opts->mp_join_syns.low_prio; -+ mpj->addr_id = opts->addr_id; -+ ptr += MPTCP_SUB_LEN_JOIN_SYN_ALIGN >> 2; -+ } else if (OPTION_TYPE_SYNACK & opts->mptcp_options) { -+ mpj->len = MPTCP_SUB_LEN_JOIN_SYNACK; -+ mpj->u.synack.mac = -+ opts->mp_join_syns.sender_truncated_mac; -+ mpj->u.synack.nonce = opts->mp_join_syns.sender_nonce; -+ mpj->b = opts->mp_join_syns.low_prio; -+ mpj->addr_id = opts->addr_id; -+ ptr += MPTCP_SUB_LEN_JOIN_SYNACK_ALIGN >> 2; -+ } else if (OPTION_TYPE_ACK & opts->mptcp_options) { -+ mpj->len = MPTCP_SUB_LEN_JOIN_ACK; -+ mpj->addr_id = 0; /* addr_id is rsv (RFC 6824, p. 21) */ -+ memcpy(mpj->u.ack.mac, &tp->mptcp->sender_mac[0], 20); -+ ptr += MPTCP_SUB_LEN_JOIN_ACK_ALIGN >> 2; -+ } -+ } -+ if (unlikely(OPTION_ADD_ADDR & opts->mptcp_options)) { -+ struct mp_add_addr *mpadd = (struct mp_add_addr *)ptr; -+ struct mptcp_cb *mpcb = tp->mpcb; -+ -+ mpadd->kind = TCPOPT_MPTCP; -+ if (opts->add_addr_v4) { -+ mpadd->sub = MPTCP_SUB_ADD_ADDR; -+ mpadd->ipver = 4; -+ mpadd->addr_id = opts->add_addr4.addr_id; -+ mpadd->u.v4.addr = opts->add_addr4.addr; -+ if (mpcb->mptcp_ver < MPTCP_VERSION_1) { -+ mpadd->len = MPTCP_SUB_LEN_ADD_ADDR4; -+ ptr += MPTCP_SUB_LEN_ADD_ADDR4_ALIGN >> 2; -+ } else { -+ memcpy((char *)mpadd->u.v4.mac - 2, -+ (char *)&opts->add_addr4.trunc_mac, 8); -+ mpadd->len = MPTCP_SUB_LEN_ADD_ADDR4_VER1; -+ ptr += MPTCP_SUB_LEN_ADD_ADDR4_ALIGN_VER1 >> 2; -+ } -+ } else if (opts->add_addr_v6) { -+ mpadd->sub = MPTCP_SUB_ADD_ADDR; -+ mpadd->ipver = 6; -+ mpadd->addr_id = opts->add_addr6.addr_id; -+ memcpy(&mpadd->u.v6.addr, &opts->add_addr6.addr, -+ sizeof(mpadd->u.v6.addr)); -+ if (mpcb->mptcp_ver < MPTCP_VERSION_1) { -+ mpadd->len = MPTCP_SUB_LEN_ADD_ADDR6; -+ ptr += MPTCP_SUB_LEN_ADD_ADDR6_ALIGN >> 2; -+ } else { -+ memcpy((char *)mpadd->u.v6.mac - 2, -+ (char *)&opts->add_addr6.trunc_mac, 8); -+ mpadd->len = MPTCP_SUB_LEN_ADD_ADDR6_VER1; -+ ptr += MPTCP_SUB_LEN_ADD_ADDR6_ALIGN_VER1 >> 2; -+ } -+ } -+ -+ MPTCP_INC_STATS(sock_net((struct sock *)tp), MPTCP_MIB_ADDADDRTX); -+ } -+ if (unlikely(OPTION_REMOVE_ADDR & opts->mptcp_options)) { -+ struct mp_remove_addr *mprem = (struct mp_remove_addr *)ptr; -+ u8 *addrs_id; -+ int id, len, len_align; -+ -+ len = mptcp_sub_len_remove_addr(opts->remove_addrs); -+ len_align = mptcp_sub_len_remove_addr_align(opts->remove_addrs); -+ -+ mprem->kind = TCPOPT_MPTCP; -+ mprem->len = len; -+ mprem->sub = MPTCP_SUB_REMOVE_ADDR; -+ mprem->rsv = 0; -+ addrs_id = &mprem->addrs_id; -+ -+ mptcp_for_each_bit_set(opts->remove_addrs, id) -+ *(addrs_id++) = id; -+ -+ /* Fill the rest with NOP's */ -+ if (len_align > len) { -+ int i; -+ for (i = 0; i < len_align - len; i++) -+ *(addrs_id++) = TCPOPT_NOP; -+ } -+ -+ ptr += len_align >> 2; -+ -+ MPTCP_INC_STATS(sock_net((struct sock *)tp), MPTCP_MIB_REMADDRTX); -+ } -+ if (unlikely(OPTION_MP_FAIL & opts->mptcp_options)) { -+ struct mp_fail *mpfail = (struct mp_fail *)ptr; -+ -+ mpfail->kind = TCPOPT_MPTCP; -+ mpfail->len = MPTCP_SUB_LEN_FAIL; -+ mpfail->sub = MPTCP_SUB_FAIL; -+ mpfail->rsv1 = 0; -+ mpfail->rsv2 = 0; -+ mpfail->data_seq = htonll(tp->mpcb->csum_cutoff_seq); -+ -+ ptr += MPTCP_SUB_LEN_FAIL_ALIGN >> 2; -+ } -+ if (unlikely(OPTION_MP_FCLOSE & opts->mptcp_options)) { -+ struct mp_fclose *mpfclose = (struct mp_fclose *)ptr; -+ -+ mpfclose->kind = TCPOPT_MPTCP; -+ mpfclose->len = MPTCP_SUB_LEN_FCLOSE; -+ mpfclose->sub = MPTCP_SUB_FCLOSE; -+ mpfclose->rsv1 = 0; -+ mpfclose->rsv2 = 0; -+ mpfclose->key = opts->mp_capable.receiver_key; -+ -+ ptr += MPTCP_SUB_LEN_FCLOSE_ALIGN >> 2; -+ } -+ -+ if (OPTION_DATA_ACK & opts->mptcp_options) { -+ if (!mptcp_is_data_seq(skb)) -+ ptr += mptcp_write_dss_data_ack(tp, skb, ptr); -+ else -+ ptr += mptcp_write_dss_data_seq(tp, skb, ptr); -+ } -+ if (unlikely(OPTION_MP_PRIO & opts->mptcp_options)) { -+ struct mp_prio *mpprio = (struct mp_prio *)ptr; -+ -+ mpprio->kind = TCPOPT_MPTCP; -+ mpprio->len = MPTCP_SUB_LEN_PRIO; -+ mpprio->sub = MPTCP_SUB_PRIO; -+ mpprio->rsv = 0; -+ mpprio->b = tp->mptcp->low_prio; -+ mpprio->addr_id = TCPOPT_NOP; -+ -+ ptr += MPTCP_SUB_LEN_PRIO_ALIGN >> 2; -+ } -+} -+ -+/* Sends the datafin */ -+void mptcp_send_fin(struct sock *meta_sk) -+{ -+ struct tcp_sock *meta_tp = tcp_sk(meta_sk); -+ struct sk_buff *skb = tcp_write_queue_tail(meta_sk); -+ int mss_now; -+ -+ if ((1 << meta_sk->sk_state) & (TCPF_CLOSE_WAIT | TCPF_LAST_ACK)) -+ meta_tp->mpcb->passive_close = 1; -+ -+ /* Optimization, tack on the FIN if we have a queue of -+ * unsent frames. But be careful about outgoing SACKS -+ * and IP options. -+ */ -+ mss_now = mptcp_current_mss(meta_sk); -+ -+ if (tcp_send_head(meta_sk) != NULL) { -+ TCP_SKB_CB(skb)->mptcp_flags |= MPTCPHDR_FIN; -+ TCP_SKB_CB(skb)->end_seq++; -+ meta_tp->write_seq++; -+ } else { -+ /* Socket is locked, keep trying until memory is available. */ -+ for (;;) { -+ skb = alloc_skb_fclone(MAX_TCP_HEADER, -+ meta_sk->sk_allocation); -+ if (skb) -+ break; -+ yield(); -+ } -+ /* Reserve space for headers and prepare control bits. */ -+ skb_reserve(skb, MAX_TCP_HEADER); -+ -+ tcp_init_nondata_skb(skb, meta_tp->write_seq, TCPHDR_ACK); -+ TCP_SKB_CB(skb)->end_seq++; -+ TCP_SKB_CB(skb)->mptcp_flags |= MPTCPHDR_FIN; -+ tcp_queue_skb(meta_sk, skb); -+ } -+ __tcp_push_pending_frames(meta_sk, mss_now, TCP_NAGLE_OFF); -+} -+ -+void mptcp_send_active_reset(struct sock *meta_sk, gfp_t priority) -+{ -+ struct tcp_sock *meta_tp = tcp_sk(meta_sk); -+ struct mptcp_cb *mpcb = meta_tp->mpcb; -+ struct sock *sk; -+ -+ if (!mpcb->cnt_subflows) -+ return; -+ -+ WARN_ON(meta_tp->send_mp_fclose); -+ -+ /* First - select a socket */ -+ sk = mptcp_select_ack_sock(meta_sk); -+ -+ /* May happen if no subflow is in an appropriate state, OR -+ * we are in infinite mode or about to go there - just send a reset -+ */ -+ if (!sk || mpcb->infinite_mapping_snd || mpcb->send_infinite_mapping || -+ mpcb->infinite_mapping_rcv) { -+ -+ /* tcp_done must be handled with bh disabled */ -+ if (!in_serving_softirq()) -+ local_bh_disable(); -+ -+ mptcp_sub_force_close_all(mpcb, NULL); -+ -+ if (!in_serving_softirq()) -+ local_bh_enable(); -+ return; -+ } -+ -+ -+ tcp_sk(sk)->send_mp_fclose = 1; -+ /** Reset all other subflows */ -+ -+ /* tcp_done must be handled with bh disabled */ -+ if (!in_serving_softirq()) -+ local_bh_disable(); -+ -+ mptcp_sub_force_close_all(mpcb, sk); -+ -+ tcp_set_state(sk, TCP_RST_WAIT); -+ -+ if (!in_serving_softirq()) -+ local_bh_enable(); -+ -+ tcp_send_ack(sk); -+ tcp_clear_xmit_timers(sk); -+ inet_csk_reset_keepalive_timer(sk, inet_csk(sk)->icsk_rto); -+ -+ meta_tp->send_mp_fclose = 1; -+ inet_csk(sk)->icsk_retransmits = 0; -+ -+ /* Prevent exp backoff reverting on ICMP dest unreachable */ -+ inet_csk(sk)->icsk_backoff = 0; -+ -+ MPTCP_INC_STATS(sock_net(meta_sk), MPTCP_MIB_FASTCLOSETX); -+} -+ -+static void mptcp_ack_retransmit_timer(struct sock *sk) -+{ -+ struct inet_connection_sock *icsk = inet_csk(sk); -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct net *net = sock_net(sk); -+ struct sk_buff *skb; -+ -+ if (inet_csk(sk)->icsk_af_ops->rebuild_header(sk)) -+ goto out; /* Routing failure or similar */ -+ -+ if (!tp->retrans_stamp) -+ tp->retrans_stamp = tcp_time_stamp ? : 1; -+ -+ if (tcp_write_timeout(sk)) { -+ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_JOINACKRTO); -+ tp->mptcp->pre_established = 0; -+ sk_stop_timer(sk, &tp->mptcp->mptcp_ack_timer); -+ tp->ops->send_active_reset(sk, GFP_ATOMIC); -+ goto out; -+ } -+ -+ skb = alloc_skb(MAX_TCP_HEADER, GFP_ATOMIC); -+ if (skb == NULL) { -+ sk_reset_timer(sk, &tp->mptcp->mptcp_ack_timer, -+ jiffies + icsk->icsk_rto); -+ return; -+ } -+ -+ /* Reserve space for headers and prepare control bits */ -+ skb_reserve(skb, MAX_TCP_HEADER); -+ tcp_init_nondata_skb(skb, tp->snd_una, TCPHDR_ACK); -+ -+ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_JOINACKRXMIT); -+ -+ if (tcp_transmit_skb(sk, skb, 0, GFP_ATOMIC) > 0) { -+ /* Retransmission failed because of local congestion, -+ * do not backoff. -+ */ -+ if (!icsk->icsk_retransmits) -+ icsk->icsk_retransmits = 1; -+ sk_reset_timer(sk, &tp->mptcp->mptcp_ack_timer, -+ jiffies + icsk->icsk_rto); -+ return; -+ } -+ -+ -+ icsk->icsk_retransmits++; -+ icsk->icsk_rto = min(icsk->icsk_rto << 1, TCP_RTO_MAX); -+ sk_reset_timer(sk, &tp->mptcp->mptcp_ack_timer, -+ jiffies + icsk->icsk_rto); -+ if (retransmits_timed_out(sk, net->ipv4.sysctl_tcp_retries1 + 1, 0, 0)) -+ __sk_dst_reset(sk); -+ -+out:; -+} -+ -+void mptcp_ack_handler(unsigned long data) -+{ -+ struct sock *sk = (struct sock *)data; -+ struct sock *meta_sk = mptcp_meta_sk(sk); -+ -+ bh_lock_sock(meta_sk); -+ if (sock_owned_by_user(meta_sk)) { -+ /* Try again later */ -+ sk_reset_timer(sk, &tcp_sk(sk)->mptcp->mptcp_ack_timer, -+ jiffies + (HZ / 20)); -+ goto out_unlock; -+ } -+ -+ if (sk->sk_state == TCP_CLOSE) -+ goto out_unlock; -+ if (!tcp_sk(sk)->mptcp->pre_established) -+ goto out_unlock; -+ -+ mptcp_ack_retransmit_timer(sk); -+ -+ sk_mem_reclaim(sk); -+ -+out_unlock: -+ bh_unlock_sock(meta_sk); -+ sock_put(sk); -+} -+ -+/* Similar to tcp_retransmit_skb -+ * -+ * The diff is that we handle the retransmission-stats (retrans_stamp) at the -+ * meta-level. -+ */ -+int mptcp_retransmit_skb(struct sock *meta_sk, struct sk_buff *skb) -+{ -+ struct tcp_sock *meta_tp = tcp_sk(meta_sk); -+ struct sock *subsk; -+ unsigned int limit, mss_now; -+ int err = -1; -+ -+ WARN_ON(TCP_SKB_CB(skb)->sacked); -+ -+ /* Do not sent more than we queued. 1/4 is reserved for possible -+ * copying overhead: fragmentation, tunneling, mangling etc. -+ * -+ * This is a meta-retransmission thus we check on the meta-socket. -+ */ -+ if (atomic_read(&meta_sk->sk_wmem_alloc) > -+ min(meta_sk->sk_wmem_queued + (meta_sk->sk_wmem_queued >> 2), meta_sk->sk_sndbuf)) { -+ return -EAGAIN; -+ } -+ -+ /* We need to make sure that the retransmitted segment can be sent on a -+ * subflow right now. If it is too big, it needs to be fragmented. -+ */ -+ subsk = meta_tp->mpcb->sched_ops->get_subflow(meta_sk, skb, false); -+ if (!subsk) { -+ /* We want to increase icsk_retransmits, thus return 0, so that -+ * mptcp_meta_retransmit_timer enters the desired branch. -+ */ -+ err = 0; -+ goto failed; -+ } -+ mss_now = tcp_current_mss(subsk); -+ -+ /* If the segment was cloned (e.g. a meta retransmission), the header -+ * must be expanded/copied so that there is no corruption of TSO -+ * information. -+ */ -+ if (skb_unclone(skb, GFP_ATOMIC)) { -+ err = -ENOMEM; -+ goto failed; -+ } -+ -+ /* Must have been set by mptcp_write_xmit before */ -+ BUG_ON(!tcp_skb_pcount(skb)); -+ -+ limit = mss_now; -+ /* skb->len > mss_now is the equivalent of tso_segs > 1 in -+ * tcp_write_xmit. Otherwise split-point would return 0. -+ */ -+ if (skb->len > mss_now && !tcp_urg_mode(meta_tp)) -+ limit = tcp_mss_split_point(meta_sk, skb, mss_now, -+ UINT_MAX / mss_now, -+ TCP_NAGLE_OFF); -+ -+ if (skb->len > limit && -+ unlikely(mptcp_fragment(meta_sk, skb, limit, -+ GFP_ATOMIC, 0))) -+ goto failed; -+ -+ if (!mptcp_skb_entail(subsk, skb, -1)) -+ goto failed; -+ skb_mstamp_get(&skb->skb_mstamp); -+ -+ /* Update global TCP statistics. */ -+ MPTCP_INC_STATS(sock_net(meta_sk), MPTCP_MIB_RETRANSSEGS); -+ -+ /* Diff to tcp_retransmit_skb */ -+ -+ /* Save stamp of the first retransmit. */ -+ if (!meta_tp->retrans_stamp) -+ meta_tp->retrans_stamp = tcp_skb_timestamp(skb); -+ -+ __tcp_push_pending_frames(subsk, mss_now, TCP_NAGLE_PUSH); -+ meta_tp->lsndtime = tcp_time_stamp; -+ -+ return 0; -+ -+failed: -+ __NET_INC_STATS(sock_net(meta_sk), LINUX_MIB_TCPRETRANSFAIL); -+ return err; -+} -+ -+/* Similar to tcp_retransmit_timer -+ * -+ * The diff is that we have to handle retransmissions of the FAST_CLOSE-message -+ * and that we don't have an srtt estimation at the meta-level. -+ */ -+void mptcp_meta_retransmit_timer(struct sock *meta_sk) -+{ -+ struct tcp_sock *meta_tp = tcp_sk(meta_sk); -+ struct mptcp_cb *mpcb = meta_tp->mpcb; -+ struct inet_connection_sock *meta_icsk = inet_csk(meta_sk); -+ int err; -+ -+ /* In fallback, retransmission is handled at the subflow-level */ -+ if (!meta_tp->packets_out || mpcb->infinite_mapping_snd) -+ return; -+ -+ WARN_ON(tcp_write_queue_empty(meta_sk)); -+ -+ if (!meta_tp->snd_wnd && !sock_flag(meta_sk, SOCK_DEAD) && -+ !((1 << meta_sk->sk_state) & (TCPF_SYN_SENT | TCPF_SYN_RECV))) { -+ /* Receiver dastardly shrinks window. Our retransmits -+ * become zero probes, but we should not timeout this -+ * connection. If the socket is an orphan, time it out, -+ * we cannot allow such beasts to hang infinitely. -+ */ -+ struct inet_sock *meta_inet = inet_sk(meta_sk); -+ if (meta_sk->sk_family == AF_INET) { -+ net_dbg_ratelimited("MPTCP: Peer %pI4:%u/%u unexpectedly shrunk window %u:%u (repaired)\n", -+ &meta_inet->inet_daddr, -+ ntohs(meta_inet->inet_dport), -+ meta_inet->inet_num, meta_tp->snd_una, -+ meta_tp->snd_nxt); -+ } -+#if IS_ENABLED(CONFIG_IPV6) -+ else if (meta_sk->sk_family == AF_INET6) { -+ net_dbg_ratelimited("MPTCP: Peer %pI6:%u/%u unexpectedly shrunk window %u:%u (repaired)\n", -+ &meta_sk->sk_v6_daddr, -+ ntohs(meta_inet->inet_dport), -+ meta_inet->inet_num, meta_tp->snd_una, -+ meta_tp->snd_nxt); -+ } -+#endif -+ if (tcp_time_stamp - meta_tp->rcv_tstamp > TCP_RTO_MAX) { -+ tcp_write_err(meta_sk); -+ return; -+ } -+ -+ mptcp_retransmit_skb(meta_sk, tcp_write_queue_head(meta_sk)); -+ goto out_reset_timer; -+ } -+ -+ if (tcp_write_timeout(meta_sk)) -+ return; -+ -+ if (meta_icsk->icsk_retransmits == 0) -+ __NET_INC_STATS(sock_net(meta_sk), LINUX_MIB_TCPTIMEOUTS); -+ -+ meta_icsk->icsk_ca_state = TCP_CA_Loss; -+ -+ err = mptcp_retransmit_skb(meta_sk, tcp_write_queue_head(meta_sk)); -+ if (err > 0) { -+ /* Retransmission failed because of local congestion, -+ * do not backoff. -+ */ -+ if (!meta_icsk->icsk_retransmits) -+ meta_icsk->icsk_retransmits = 1; -+ inet_csk_reset_xmit_timer(meta_sk, ICSK_TIME_RETRANS, -+ min(meta_icsk->icsk_rto, TCP_RESOURCE_PROBE_INTERVAL), -+ TCP_RTO_MAX); -+ return; -+ } -+ -+ /* Increase the timeout each time we retransmit. Note that -+ * we do not increase the rtt estimate. rto is initialized -+ * from rtt, but increases here. Jacobson (SIGCOMM 88) suggests -+ * that doubling rto each time is the least we can get away with. -+ * In KA9Q, Karn uses this for the first few times, and then -+ * goes to quadratic. netBSD doubles, but only goes up to *64, -+ * and clamps at 1 to 64 sec afterwards. Note that 120 sec is -+ * defined in the protocol as the maximum possible RTT. I guess -+ * we'll have to use something other than TCP to talk to the -+ * University of Mars. -+ * -+ * PAWS allows us longer timeouts and large windows, so once -+ * implemented ftp to mars will work nicely. We will have to fix -+ * the 120 second clamps though! -+ */ -+ meta_icsk->icsk_backoff++; -+ meta_icsk->icsk_retransmits++; -+ -+out_reset_timer: -+ /* If stream is thin, use linear timeouts. Since 'icsk_backoff' is -+ * used to reset timer, set to 0. Recalculate 'icsk_rto' as this -+ * might be increased if the stream oscillates between thin and thick, -+ * thus the old value might already be too high compared to the value -+ * set by 'tcp_set_rto' in tcp_input.c which resets the rto without -+ * backoff. Limit to TCP_THIN_LINEAR_RETRIES before initiating -+ * exponential backoff behaviour to avoid continue hammering -+ * linear-timeout retransmissions into a black hole -+ */ -+ if (meta_sk->sk_state == TCP_ESTABLISHED && -+ (meta_tp->thin_lto || sysctl_tcp_thin_linear_timeouts) && -+ tcp_stream_is_thin(meta_tp) && -+ meta_icsk->icsk_retransmits <= TCP_THIN_LINEAR_RETRIES) { -+ meta_icsk->icsk_backoff = 0; -+ /* We cannot do the same as in tcp_write_timer because the -+ * srtt is not set here. -+ */ -+ mptcp_set_rto(meta_sk); -+ } else { -+ /* Use normal (exponential) backoff */ -+ meta_icsk->icsk_rto = min(meta_icsk->icsk_rto << 1, TCP_RTO_MAX); -+ } -+ inet_csk_reset_xmit_timer(meta_sk, ICSK_TIME_RETRANS, meta_icsk->icsk_rto, TCP_RTO_MAX); -+ -+ return; -+} -+ -+void mptcp_sub_retransmit_timer(struct sock *sk) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ -+ tcp_retransmit_timer(sk); -+ -+ if (!tp->fastopen_rsk) { -+ mptcp_reinject_data(sk, 1); -+ mptcp_set_rto(sk); -+ } -+} -+ -+/* Modify values to an mptcp-level for the initial window of new subflows */ -+void mptcp_select_initial_window(int __space, __u32 mss, __u32 *rcv_wnd, -+ __u32 *window_clamp, int wscale_ok, -+ __u8 *rcv_wscale, __u32 init_rcv_wnd, -+ const struct sock *sk) -+{ -+ const struct mptcp_cb *mpcb = tcp_sk(sk)->mpcb; -+ -+ *window_clamp = mpcb->orig_window_clamp; -+ __space = tcp_win_from_space(mpcb->orig_sk_rcvbuf); -+ -+ tcp_select_initial_window(__space, mss, rcv_wnd, window_clamp, -+ wscale_ok, rcv_wscale, init_rcv_wnd, sk); -+} -+ -+static inline u64 mptcp_calc_rate(const struct sock *meta_sk, unsigned int mss, -+ unsigned int (*mss_cb)(struct sock *sk)) -+{ -+ struct sock *sk; -+ u64 rate = 0; -+ -+ mptcp_for_each_sk(tcp_sk(meta_sk)->mpcb, sk) { -+ struct tcp_sock *tp = tcp_sk(sk); -+ int this_mss; -+ u64 this_rate; -+ -+ if (!mptcp_sk_can_send(sk)) -+ continue; -+ -+ /* Do not consider subflows without a RTT estimation yet -+ * otherwise this_rate >>> rate. -+ */ -+ if (unlikely(!tp->srtt_us)) -+ continue; -+ -+ this_mss = mss_cb(sk); -+ -+ /* If this_mss is smaller than mss, it means that a segment will -+ * be splitted in two (or more) when pushed on this subflow. If -+ * you consider that mss = 1428 and this_mss = 1420 then two -+ * segments will be generated: a 1420-byte and 8-byte segment. -+ * The latter will introduce a large overhead as for a single -+ * data segment 2 slots will be used in the congestion window. -+ * Therefore reducing by ~2 the potential throughput of this -+ * subflow. Indeed, 1428 will be send while 2840 could have been -+ * sent if mss == 1420 reducing the throughput by 2840 / 1428. -+ * -+ * The following algorithm take into account this overhead -+ * when computing the potential throughput that MPTCP can -+ * achieve when generating mss-byte segments. -+ * -+ * The formulae is the following: -+ * \sum_{\forall sub} ratio * \frac{mss * cwnd_sub}{rtt_sub} -+ * Where ratio is computed as follows: -+ * \frac{mss}{\ceil{mss / mss_sub} * mss_sub} -+ * -+ * ratio gives the reduction factor of the theoretical -+ * throughput a subflow can achieve if MPTCP uses a specific -+ * MSS value. -+ */ -+ this_rate = div64_u64((u64)mss * mss * (USEC_PER_SEC << 3) * -+ max(tp->snd_cwnd, tp->packets_out), -+ (u64)tp->srtt_us * -+ DIV_ROUND_UP(mss, this_mss) * this_mss); -+ rate += this_rate; -+ } -+ -+ return rate; -+} -+ -+static unsigned int __mptcp_current_mss(const struct sock *meta_sk, -+ unsigned int (*mss_cb)(struct sock *sk)) -+{ -+ unsigned int mss = 0; -+ u64 rate = 0; -+ struct sock *sk; -+ -+ mptcp_for_each_sk(tcp_sk(meta_sk)->mpcb, sk) { -+ int this_mss; -+ u64 this_rate; -+ -+ if (!mptcp_sk_can_send(sk)) -+ continue; -+ -+ this_mss = mss_cb(sk); -+ -+ /* Same mss values will produce the same throughput. */ -+ if (this_mss == mss) -+ continue; -+ -+ /* See whether using this mss value can theoretically improve -+ * the performances. -+ */ -+ this_rate = mptcp_calc_rate(meta_sk, this_mss, mss_cb); -+ if (this_rate >= rate) { -+ mss = this_mss; -+ rate = this_rate; -+ } -+ } -+ -+ return mss; -+} -+ -+unsigned int mptcp_current_mss(struct sock *meta_sk) -+{ -+ unsigned int mss = __mptcp_current_mss(meta_sk, tcp_current_mss); -+ -+ /* If no subflow is available, we take a default-mss from the -+ * meta-socket. -+ */ -+ return !mss ? tcp_current_mss(meta_sk) : mss; -+} -+ -+static unsigned int mptcp_select_size_mss(struct sock *sk) -+{ -+ return tcp_sk(sk)->mss_cache; -+} -+ -+int mptcp_select_size(const struct sock *meta_sk, bool sg, bool first_skb) -+{ -+ unsigned int mss = __mptcp_current_mss(meta_sk, mptcp_select_size_mss); -+ -+ if (sg) { -+ if (mptcp_sk_can_gso(meta_sk)) { -+ mss = linear_payload_sz(first_skb); -+ } else { -+ int pgbreak = SKB_MAX_HEAD(MAX_TCP_HEADER); -+ -+ if (mss >= pgbreak && -+ mss <= pgbreak + (MAX_SKB_FRAGS - 1) * PAGE_SIZE) -+ mss = pgbreak; -+ } -+ } -+ -+ return !mss ? tcp_sk(meta_sk)->mss_cache : mss; -+} -+ -+int mptcp_check_snd_buf(const struct tcp_sock *tp) -+{ -+ const struct sock *sk; -+ u32 rtt_max = tp->srtt_us; -+ u64 bw_est; -+ -+ if (!tp->srtt_us) -+ return tp->reordering + 1; -+ -+ mptcp_for_each_sk(tp->mpcb, sk) { -+ if (!mptcp_sk_can_send(sk)) -+ continue; -+ -+ if (rtt_max < tcp_sk(sk)->srtt_us) -+ rtt_max = tcp_sk(sk)->srtt_us; -+ } -+ -+ bw_est = div64_u64(((u64)tp->snd_cwnd * rtt_max) << 16, -+ (u64)tp->srtt_us); -+ -+ return max_t(unsigned int, (u32)(bw_est >> 16), -+ tp->reordering + 1); -+} -+ -+unsigned int mptcp_xmit_size_goal(const struct sock *meta_sk, u32 mss_now, -+ int large_allowed) -+{ -+ struct sock *sk; -+ u32 xmit_size_goal = 0; -+ -+ if (large_allowed && mptcp_sk_can_gso(meta_sk)) { -+ mptcp_for_each_sk(tcp_sk(meta_sk)->mpcb, sk) { -+ int this_size_goal; -+ -+ if (!mptcp_sk_can_send(sk)) -+ continue; -+ -+ this_size_goal = tcp_xmit_size_goal(sk, mss_now, 1); -+ if (this_size_goal > xmit_size_goal) -+ xmit_size_goal = this_size_goal; -+ } -+ } -+ -+ return max(xmit_size_goal, mss_now); -+} -+ -diff -aurN linux-4.9.162/net/mptcp/mptcp_pm.c mptcp-mptcp_v0.93/net/mptcp/mptcp_pm.c ---- linux-4.9.162/net/mptcp/mptcp_pm.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_v0.93/net/mptcp/mptcp_pm.c 2019-03-14 14:02:32.000000000 +0100 -@@ -0,0 +1,226 @@ -+/* -+ * MPTCP implementation - MPTCP-subflow-management -+ * -+ * Initial Design & Implementation: -+ * Sébastien Barré -+ * -+ * Current Maintainer & Author: -+ * Christoph Paasch -+ * -+ * Additional authors: -+ * Jaakko Korkeaniemi -+ * Gregory Detal -+ * Fabien Duchêne -+ * Andreas Seelinger -+ * Lavkesh Lahngir -+ * Andreas Ripke -+ * Vlad Dogaru -+ * Octavian Purdila -+ * John Ronan -+ * Catalin Nicutar -+ * Brandon Heller -+ * -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version -+ * 2 of the License, or (at your option) any later version. -+ */ -+ -+ -+#include -+#include -+ -+static DEFINE_SPINLOCK(mptcp_pm_list_lock); -+static LIST_HEAD(mptcp_pm_list); -+ -+static int mptcp_default_id(sa_family_t family, union inet_addr *addr, -+ struct net *net, bool *low_prio) -+{ -+ return 0; -+} -+ -+struct mptcp_pm_ops mptcp_pm_default = { -+ .get_local_id = mptcp_default_id, /* We do not care */ -+ .name = "default", -+ .owner = THIS_MODULE, -+}; -+ -+static struct mptcp_pm_ops *mptcp_pm_find(const char *name) -+{ -+ struct mptcp_pm_ops *e; -+ -+ list_for_each_entry_rcu(e, &mptcp_pm_list, list) { -+ if (strcmp(e->name, name) == 0) -+ return e; -+ } -+ -+ return NULL; -+} -+ -+int mptcp_register_path_manager(struct mptcp_pm_ops *pm) -+{ -+ int ret = 0; -+ -+ if (!pm->get_local_id) -+ return -EINVAL; -+ -+ spin_lock(&mptcp_pm_list_lock); -+ if (mptcp_pm_find(pm->name)) { -+ pr_notice("%s already registered\n", pm->name); -+ ret = -EEXIST; -+ } else { -+ list_add_tail_rcu(&pm->list, &mptcp_pm_list); -+ pr_info("%s registered\n", pm->name); -+ } -+ spin_unlock(&mptcp_pm_list_lock); -+ -+ return ret; -+} -+EXPORT_SYMBOL_GPL(mptcp_register_path_manager); -+ -+void mptcp_unregister_path_manager(struct mptcp_pm_ops *pm) -+{ -+ spin_lock(&mptcp_pm_list_lock); -+ list_del_rcu(&pm->list); -+ spin_unlock(&mptcp_pm_list_lock); -+ -+ /* Wait for outstanding readers to complete before the -+ * module gets removed entirely. -+ * -+ * A try_module_get() should fail by now as our module is -+ * in "going" state since no refs are held anymore and -+ * module_exit() handler being called. -+ */ -+ synchronize_rcu(); -+} -+EXPORT_SYMBOL_GPL(mptcp_unregister_path_manager); -+ -+void mptcp_get_default_path_manager(char *name) -+{ -+ struct mptcp_pm_ops *pm; -+ -+ BUG_ON(list_empty(&mptcp_pm_list)); -+ -+ rcu_read_lock(); -+ pm = list_entry(mptcp_pm_list.next, struct mptcp_pm_ops, list); -+ strncpy(name, pm->name, MPTCP_PM_NAME_MAX); -+ rcu_read_unlock(); -+} -+ -+int mptcp_set_default_path_manager(const char *name) -+{ -+ struct mptcp_pm_ops *pm; -+ int ret = -ENOENT; -+ -+ spin_lock(&mptcp_pm_list_lock); -+ pm = mptcp_pm_find(name); -+#ifdef CONFIG_MODULES -+ if (!pm && capable(CAP_NET_ADMIN)) { -+ spin_unlock(&mptcp_pm_list_lock); -+ -+ request_module("mptcp_%s", name); -+ spin_lock(&mptcp_pm_list_lock); -+ pm = mptcp_pm_find(name); -+ } -+#endif -+ -+ if (pm) { -+ list_move(&pm->list, &mptcp_pm_list); -+ ret = 0; -+ } else { -+ pr_info("%s is not available\n", name); -+ } -+ spin_unlock(&mptcp_pm_list_lock); -+ -+ return ret; -+} -+ -+static struct mptcp_pm_ops *__mptcp_pm_find_autoload(const char *name) -+{ -+ struct mptcp_pm_ops *pm = mptcp_pm_find(name); -+#ifdef CONFIG_MODULES -+ if (!pm && capable(CAP_NET_ADMIN)) { -+ rcu_read_unlock(); -+ request_module("mptcp_%s", name); -+ rcu_read_lock(); -+ pm = mptcp_pm_find(name); -+ } -+#endif -+ return pm; -+} -+ -+void mptcp_init_path_manager(struct mptcp_cb *mpcb) -+{ -+ struct mptcp_pm_ops *pm; -+ struct sock *meta_sk = mpcb->meta_sk; -+ struct tcp_sock *meta_tp = tcp_sk(meta_sk); -+ -+ rcu_read_lock(); -+ /* if path manager was set using socket option */ -+ if (meta_tp->mptcp_pm_setsockopt) { -+ pm = __mptcp_pm_find_autoload(meta_tp->mptcp_pm_name); -+ if (pm && try_module_get(pm->owner)) { -+ mpcb->pm_ops = pm; -+ goto out; -+ } -+ } -+ -+ list_for_each_entry_rcu(pm, &mptcp_pm_list, list) { -+ if (try_module_get(pm->owner)) { -+ mpcb->pm_ops = pm; -+ break; -+ } -+ } -+out: -+ rcu_read_unlock(); -+} -+ -+/* Change path manager for socket */ -+int mptcp_set_path_manager(struct sock *sk, const char *name) -+{ -+ struct mptcp_pm_ops *pm; -+ int err = 0; -+ -+ rcu_read_lock(); -+ pm = __mptcp_pm_find_autoload(name); -+ -+ if (!pm) { -+ err = -ENOENT; -+ } else if (!ns_capable(sock_net(sk)->user_ns, CAP_NET_ADMIN)) { -+ err = -EPERM; -+ } else { -+ strcpy(tcp_sk(sk)->mptcp_pm_name, name); -+ tcp_sk(sk)->mptcp_pm_setsockopt = 1; -+ } -+ rcu_read_unlock(); -+ -+ return err; -+} -+ -+/* Manage refcounts on socket close. */ -+void mptcp_cleanup_path_manager(struct mptcp_cb *mpcb) -+{ -+ module_put(mpcb->pm_ops->owner); -+} -+ -+/* Fallback to the default path-manager. */ -+void mptcp_fallback_default(struct mptcp_cb *mpcb) -+{ -+ struct mptcp_pm_ops *pm; -+ -+ mptcp_cleanup_path_manager(mpcb); -+ pm = mptcp_pm_find("default"); -+ -+ /* Cannot fail - it's the default module */ -+ try_module_get(pm->owner); -+ mpcb->pm_ops = pm; -+} -+EXPORT_SYMBOL_GPL(mptcp_fallback_default); -+ -+/* Set default value from kernel configuration at bootup */ -+static int __init mptcp_path_manager_default(void) -+{ -+ return mptcp_set_default_path_manager(CONFIG_DEFAULT_MPTCP_PM); -+} -+late_initcall(mptcp_path_manager_default); -diff -aurN linux-4.9.162/net/mptcp/mptcp_redundant.c mptcp-mptcp_v0.93/net/mptcp/mptcp_redundant.c ---- linux-4.9.162/net/mptcp/mptcp_redundant.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_v0.93/net/mptcp/mptcp_redundant.c 2019-03-14 14:02:32.000000000 +0100 -@@ -0,0 +1,301 @@ -+/* -+ * MPTCP Scheduler to reduce latency and jitter. -+ * -+ * This scheduler sends all packets redundantly on all available subflows. -+ * -+ * Initial Design & Implementation: -+ * Tobias Erbshaeusser -+ * Alexander Froemmgen -+ * -+ * Initial corrections & modifications: -+ * Christian Pinedo -+ * Igor Lopez -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version -+ * 2 of the License, or (at your option) any later version. -+ */ -+ -+#include -+#include -+ -+/* Struct to store the data of a single subflow */ -+struct redsched_sock_data { -+ /* The skb or NULL */ -+ struct sk_buff *skb; -+ /* End sequence number of the skb. This number should be checked -+ * to be valid before the skb field is used -+ */ -+ u32 skb_end_seq; -+}; -+ -+/* Struct to store the data of the control block */ -+struct redsched_cb_data { -+ /* The next subflow where a skb should be sent or NULL */ -+ struct tcp_sock *next_subflow; -+}; -+ -+/* Returns the socket data from a given subflow socket */ -+static struct redsched_sock_data *redsched_get_sock_data(struct tcp_sock *tp) -+{ -+ return (struct redsched_sock_data *)&tp->mptcp->mptcp_sched[0]; -+} -+ -+/* Returns the control block data from a given meta socket */ -+static struct redsched_cb_data *redsched_get_cb_data(struct tcp_sock *tp) -+{ -+ return (struct redsched_cb_data *)&tp->mpcb->mptcp_sched[0]; -+} -+ -+static bool redsched_get_active_valid_sks(struct sock *meta_sk) -+{ -+ struct tcp_sock *meta_tp = tcp_sk(meta_sk); -+ struct mptcp_cb *mpcb = meta_tp->mpcb; -+ struct sock *sk; -+ int active_valid_sks = 0; -+ -+ mptcp_for_each_sk(mpcb, sk) { -+ if (subflow_is_active((struct tcp_sock *)sk) && -+ !mptcp_is_def_unavailable(sk)) -+ active_valid_sks++; -+ } -+ -+ return active_valid_sks; -+} -+ -+static bool redsched_use_subflow(struct sock *meta_sk, -+ int active_valid_sks, -+ struct tcp_sock *tp, -+ struct sk_buff *skb) -+{ -+ if (!skb || !mptcp_is_available((struct sock *)tp, skb, false)) -+ return false; -+ -+ if (TCP_SKB_CB(skb)->path_mask != 0) -+ return subflow_is_active(tp); -+ -+ if (TCP_SKB_CB(skb)->path_mask == 0) { -+ if (active_valid_sks == -1) -+ active_valid_sks = redsched_get_active_valid_sks(meta_sk); -+ -+ if (subflow_is_backup(tp) && active_valid_sks > 0) -+ return false; -+ else -+ return true; -+ } -+ -+ return false; -+} -+ -+static struct sock *redundant_get_subflow(struct sock *meta_sk, -+ struct sk_buff *skb, -+ bool zero_wnd_test) -+{ -+ struct tcp_sock *meta_tp = tcp_sk(meta_sk); -+ struct mptcp_cb *mpcb = meta_tp->mpcb; -+ struct redsched_cb_data *cb_data = redsched_get_cb_data(meta_tp); -+ struct tcp_sock *first_tp = cb_data->next_subflow; -+ struct sock *sk; -+ struct tcp_sock *tp; -+ -+ /* Answer data_fin on same subflow */ -+ if (meta_sk->sk_shutdown & RCV_SHUTDOWN && -+ skb && mptcp_is_data_fin(skb)) { -+ mptcp_for_each_sk(mpcb, sk) { -+ if (tcp_sk(sk)->mptcp->path_index == -+ mpcb->dfin_path_index && -+ mptcp_is_available(sk, skb, zero_wnd_test)) -+ return sk; -+ } -+ } -+ -+ if (!first_tp) -+ first_tp = mpcb->connection_list; -+ tp = first_tp; -+ -+ /* still NULL (no subflow in connection_list?) */ -+ if (!first_tp) -+ return NULL; -+ -+ /* Search for any subflow to send it */ -+ do { -+ if (mptcp_is_available((struct sock *)tp, skb, -+ zero_wnd_test)) { -+ cb_data->next_subflow = tp->mptcp->next; -+ return (struct sock *)tp; -+ } -+ -+ tp = tp->mptcp->next; -+ if (!tp) -+ tp = mpcb->connection_list; -+ } while (tp != first_tp); -+ -+ /* No space */ -+ return NULL; -+} -+ -+/* Corrects the stored skb pointers if they are invalid */ -+static void redsched_correct_skb_pointers(struct sock *meta_sk, -+ struct redsched_sock_data *sk_data) -+{ -+ struct tcp_sock *meta_tp = tcp_sk(meta_sk); -+ -+ if (sk_data->skb && !after(sk_data->skb_end_seq, meta_tp->snd_una)) -+ sk_data->skb = NULL; -+} -+ -+/* Returns the next skb from the queue */ -+static struct sk_buff *redundant_next_skb_from_queue(struct sk_buff_head *queue, -+ struct sk_buff *previous, -+ struct sock *meta_sk) -+{ -+ if (skb_queue_empty(queue)) -+ return NULL; -+ -+ if (!previous) -+ return skb_peek(queue); -+ -+ if (skb_queue_is_last(queue, previous)) -+ return NULL; -+ -+ /* sk_data->skb stores the last scheduled packet for this subflow. -+ * If sk_data->skb was scheduled but not sent (e.g., due to nagle), -+ * we have to schedule it again. -+ * -+ * For the redundant scheduler, there are two cases: -+ * 1. sk_data->skb was not sent on another subflow: -+ * we have to schedule it again to ensure that we do not -+ * skip this packet. -+ * 2. sk_data->skb was already sent on another subflow: -+ * with regard to the redundant semantic, we have to -+ * schedule it again. However, we keep it simple and ignore it, -+ * as it was already sent by another subflow. -+ * This might be changed in the future. -+ * -+ * For case 1, send_head is equal previous, as only a single -+ * packet can be skipped. -+ */ -+ if (tcp_send_head(meta_sk) == previous) -+ return tcp_send_head(meta_sk); -+ -+ return skb_queue_next(queue, previous); -+} -+ -+static struct sk_buff *redundant_next_segment(struct sock *meta_sk, -+ int *reinject, -+ struct sock **subsk, -+ unsigned int *limit) -+{ -+ struct tcp_sock *meta_tp = tcp_sk(meta_sk); -+ struct mptcp_cb *mpcb = meta_tp->mpcb; -+ struct redsched_cb_data *cb_data = redsched_get_cb_data(meta_tp); -+ struct tcp_sock *first_tp = cb_data->next_subflow; -+ struct tcp_sock *tp; -+ struct sk_buff *skb; -+ int active_valid_sks = -1; -+ -+ /* As we set it, we have to reset it as well. */ -+ *limit = 0; -+ -+ if (skb_queue_empty(&mpcb->reinject_queue) && -+ skb_queue_empty(&meta_sk->sk_write_queue)) -+ /* Nothing to send */ -+ return NULL; -+ -+ /* First try reinjections */ -+ skb = skb_peek(&mpcb->reinject_queue); -+ if (skb) { -+ *subsk = get_available_subflow(meta_sk, skb, false); -+ if (!*subsk) -+ return NULL; -+ *reinject = 1; -+ return skb; -+ } -+ -+ /* Then try indistinctly redundant and normal skbs */ -+ -+ if (!first_tp) -+ first_tp = mpcb->connection_list; -+ -+ /* still NULL (no subflow in connection_list?) */ -+ if (!first_tp) -+ return NULL; -+ -+ tp = first_tp; -+ -+ *reinject = 0; -+ active_valid_sks = redsched_get_active_valid_sks(meta_sk); -+ do { -+ struct redsched_sock_data *sk_data; -+ -+ /* Correct the skb pointers of the current subflow */ -+ sk_data = redsched_get_sock_data(tp); -+ redsched_correct_skb_pointers(meta_sk, sk_data); -+ -+ skb = redundant_next_skb_from_queue(&meta_sk->sk_write_queue, -+ sk_data->skb, meta_sk); -+ if (skb && redsched_use_subflow(meta_sk, active_valid_sks, tp, -+ skb)) { -+ sk_data->skb = skb; -+ sk_data->skb_end_seq = TCP_SKB_CB(skb)->end_seq; -+ cb_data->next_subflow = tp->mptcp->next; -+ *subsk = (struct sock *)tp; -+ -+ if (TCP_SKB_CB(skb)->path_mask) -+ *reinject = -1; -+ return skb; -+ } -+ -+ tp = tp->mptcp->next; -+ if (!tp) -+ tp = mpcb->connection_list; -+ } while (tp != first_tp); -+ -+ /* Nothing to send */ -+ return NULL; -+} -+ -+static void redundant_release(struct sock *sk) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct redsched_cb_data *cb_data = redsched_get_cb_data(tp); -+ -+ /* Check if the next subflow would be the released one. If yes correct -+ * the pointer -+ */ -+ if (cb_data->next_subflow == tp) -+ cb_data->next_subflow = tp->mptcp->next; -+} -+ -+static struct mptcp_sched_ops mptcp_sched_redundant = { -+ .get_subflow = redundant_get_subflow, -+ .next_segment = redundant_next_segment, -+ .release = redundant_release, -+ .name = "redundant", -+ .owner = THIS_MODULE, -+}; -+ -+static int __init redundant_register(void) -+{ -+ BUILD_BUG_ON(sizeof(struct redsched_sock_data) > MPTCP_SCHED_SIZE); -+ BUILD_BUG_ON(sizeof(struct redsched_cb_data) > MPTCP_SCHED_DATA_SIZE); -+ -+ if (mptcp_register_scheduler(&mptcp_sched_redundant)) -+ return -1; -+ -+ return 0; -+} -+ -+static void redundant_unregister(void) -+{ -+ mptcp_unregister_scheduler(&mptcp_sched_redundant); -+} -+ -+module_init(redundant_register); -+module_exit(redundant_unregister); -+ -+MODULE_AUTHOR("Tobias Erbshaeusser, Alexander Froemmgen"); -+MODULE_LICENSE("GPL"); -+MODULE_DESCRIPTION("REDUNDANT MPTCP"); -+MODULE_VERSION("0.90"); -diff -aurN linux-4.9.162/net/mptcp/mptcp_rr.c mptcp-mptcp_v0.93/net/mptcp/mptcp_rr.c ---- linux-4.9.162/net/mptcp/mptcp_rr.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_v0.93/net/mptcp/mptcp_rr.c 2019-03-14 14:02:32.000000000 +0100 -@@ -0,0 +1,301 @@ -+/* MPTCP Scheduler module selector. Highly inspired by tcp_cong.c */ -+ -+#include -+#include -+ -+static unsigned char num_segments __read_mostly = 1; -+module_param(num_segments, byte, 0644); -+MODULE_PARM_DESC(num_segments, "The number of consecutive segments that are part of a burst"); -+ -+static bool cwnd_limited __read_mostly = 1; -+module_param(cwnd_limited, bool, 0644); -+MODULE_PARM_DESC(cwnd_limited, "if set to 1, the scheduler tries to fill the congestion-window on all subflows"); -+ -+struct rrsched_priv { -+ unsigned char quota; -+}; -+ -+static struct rrsched_priv *rrsched_get_priv(const struct tcp_sock *tp) -+{ -+ return (struct rrsched_priv *)&tp->mptcp->mptcp_sched[0]; -+} -+ -+/* If the sub-socket sk available to send the skb? */ -+static bool mptcp_rr_is_available(const struct sock *sk, const struct sk_buff *skb, -+ bool zero_wnd_test, bool cwnd_test) -+{ -+ const struct tcp_sock *tp = tcp_sk(sk); -+ unsigned int space, in_flight; -+ -+ /* Set of states for which we are allowed to send data */ -+ if (!mptcp_sk_can_send(sk)) -+ return false; -+ -+ /* We do not send data on this subflow unless it is -+ * fully established, i.e. the 4th ack has been received. -+ */ -+ if (tp->mptcp->pre_established) -+ return false; -+ -+ if (tp->pf) -+ return false; -+ -+ if (inet_csk(sk)->icsk_ca_state == TCP_CA_Loss) { -+ /* If SACK is disabled, and we got a loss, TCP does not exit -+ * the loss-state until something above high_seq has been acked. -+ * (see tcp_try_undo_recovery) -+ * -+ * high_seq is the snd_nxt at the moment of the RTO. As soon -+ * as we have an RTO, we won't push data on the subflow. -+ * Thus, snd_una can never go beyond high_seq. -+ */ -+ if (!tcp_is_reno(tp)) -+ return false; -+ else if (tp->snd_una != tp->high_seq) -+ return false; -+ } -+ -+ if (!tp->mptcp->fully_established) { -+ /* Make sure that we send in-order data */ -+ if (skb && tp->mptcp->second_packet && -+ tp->mptcp->last_end_data_seq != TCP_SKB_CB(skb)->seq) -+ return false; -+ } -+ -+ if (!cwnd_test) -+ goto zero_wnd_test; -+ -+ in_flight = tcp_packets_in_flight(tp); -+ /* Not even a single spot in the cwnd */ -+ if (in_flight >= tp->snd_cwnd) -+ return false; -+ -+ /* Now, check if what is queued in the subflow's send-queue -+ * already fills the cwnd. -+ */ -+ space = (tp->snd_cwnd - in_flight) * tp->mss_cache; -+ -+ if (tp->write_seq - tp->snd_nxt > space) -+ return false; -+ -+zero_wnd_test: -+ if (zero_wnd_test && !before(tp->write_seq, tcp_wnd_end(tp))) -+ return false; -+ -+ return true; -+} -+ -+/* Are we not allowed to reinject this skb on tp? */ -+static int mptcp_rr_dont_reinject_skb(const struct tcp_sock *tp, const struct sk_buff *skb) -+{ -+ /* If the skb has already been enqueued in this sk, try to find -+ * another one. -+ */ -+ return skb && -+ /* Has the skb already been enqueued into this subsocket? */ -+ mptcp_pi_to_flag(tp->mptcp->path_index) & TCP_SKB_CB(skb)->path_mask; -+} -+ -+/* We just look for any subflow that is available */ -+static struct sock *rr_get_available_subflow(struct sock *meta_sk, -+ struct sk_buff *skb, -+ bool zero_wnd_test) -+{ -+ const struct mptcp_cb *mpcb = tcp_sk(meta_sk)->mpcb; -+ struct sock *sk, *bestsk = NULL, *backupsk = NULL; -+ -+ /* Answer data_fin on same subflow!!! */ -+ if (meta_sk->sk_shutdown & RCV_SHUTDOWN && -+ skb && mptcp_is_data_fin(skb)) { -+ mptcp_for_each_sk(mpcb, sk) { -+ if (tcp_sk(sk)->mptcp->path_index == mpcb->dfin_path_index && -+ mptcp_rr_is_available(sk, skb, zero_wnd_test, true)) -+ return sk; -+ } -+ } -+ -+ /* First, find the best subflow */ -+ mptcp_for_each_sk(mpcb, sk) { -+ struct tcp_sock *tp = tcp_sk(sk); -+ -+ if (!mptcp_rr_is_available(sk, skb, zero_wnd_test, true)) -+ continue; -+ -+ if (mptcp_rr_dont_reinject_skb(tp, skb)) { -+ backupsk = sk; -+ continue; -+ } -+ -+ bestsk = sk; -+ } -+ -+ if (bestsk) { -+ sk = bestsk; -+ } else if (backupsk) { -+ /* It has been sent on all subflows once - let's give it a -+ * chance again by restarting its pathmask. -+ */ -+ if (skb) -+ TCP_SKB_CB(skb)->path_mask = 0; -+ sk = backupsk; -+ } -+ -+ return sk; -+} -+ -+/* Returns the next segment to be sent from the mptcp meta-queue. -+ * (chooses the reinject queue if any segment is waiting in it, otherwise, -+ * chooses the normal write queue). -+ * Sets *@reinject to 1 if the returned segment comes from the -+ * reinject queue. Sets it to 0 if it is the regular send-head of the meta-sk, -+ * and sets it to -1 if it is a meta-level retransmission to optimize the -+ * receive-buffer. -+ */ -+static struct sk_buff *__mptcp_rr_next_segment(const struct sock *meta_sk, int *reinject) -+{ -+ const struct mptcp_cb *mpcb = tcp_sk(meta_sk)->mpcb; -+ struct sk_buff *skb = NULL; -+ -+ *reinject = 0; -+ -+ /* If we are in fallback-mode, just take from the meta-send-queue */ -+ if (mpcb->infinite_mapping_snd || mpcb->send_infinite_mapping) -+ return tcp_send_head(meta_sk); -+ -+ skb = skb_peek(&mpcb->reinject_queue); -+ -+ if (skb) -+ *reinject = 1; -+ else -+ skb = tcp_send_head(meta_sk); -+ return skb; -+} -+ -+static struct sk_buff *mptcp_rr_next_segment(struct sock *meta_sk, -+ int *reinject, -+ struct sock **subsk, -+ unsigned int *limit) -+{ -+ const struct mptcp_cb *mpcb = tcp_sk(meta_sk)->mpcb; -+ struct sock *sk_it, *choose_sk = NULL; -+ struct sk_buff *skb = __mptcp_rr_next_segment(meta_sk, reinject); -+ unsigned char split = num_segments; -+ unsigned char iter = 0, full_subs = 0; -+ -+ /* As we set it, we have to reset it as well. */ -+ *limit = 0; -+ -+ if (!skb) -+ return NULL; -+ -+ if (*reinject) { -+ *subsk = rr_get_available_subflow(meta_sk, skb, false); -+ if (!*subsk) -+ return NULL; -+ -+ return skb; -+ } -+ -+retry: -+ -+ /* First, we look for a subflow who is currently being used */ -+ mptcp_for_each_sk(mpcb, sk_it) { -+ struct tcp_sock *tp_it = tcp_sk(sk_it); -+ struct rrsched_priv *rsp = rrsched_get_priv(tp_it); -+ -+ if (!mptcp_rr_is_available(sk_it, skb, false, cwnd_limited)) -+ continue; -+ -+ iter++; -+ -+ /* Is this subflow currently being used? */ -+ if (rsp->quota > 0 && rsp->quota < num_segments) { -+ split = num_segments - rsp->quota; -+ choose_sk = sk_it; -+ goto found; -+ } -+ -+ /* Or, it's totally unused */ -+ if (!rsp->quota) { -+ split = num_segments; -+ choose_sk = sk_it; -+ } -+ -+ /* Or, it must then be fully used */ -+ if (rsp->quota >= num_segments) -+ full_subs++; -+ } -+ -+ /* All considered subflows have a full quota, and we considered at -+ * least one. -+ */ -+ if (iter && iter == full_subs) { -+ /* So, we restart this round by setting quota to 0 and retry -+ * to find a subflow. -+ */ -+ mptcp_for_each_sk(mpcb, sk_it) { -+ struct tcp_sock *tp_it = tcp_sk(sk_it); -+ struct rrsched_priv *rsp = rrsched_get_priv(tp_it); -+ -+ if (!mptcp_rr_is_available(sk_it, skb, false, cwnd_limited)) -+ continue; -+ -+ rsp->quota = 0; -+ } -+ -+ goto retry; -+ } -+ -+found: -+ if (choose_sk) { -+ unsigned int mss_now; -+ struct tcp_sock *choose_tp = tcp_sk(choose_sk); -+ struct rrsched_priv *rsp = rrsched_get_priv(choose_tp); -+ -+ if (!mptcp_rr_is_available(choose_sk, skb, false, true)) -+ return NULL; -+ -+ *subsk = choose_sk; -+ mss_now = tcp_current_mss(*subsk); -+ *limit = split * mss_now; -+ -+ if (skb->len > mss_now) -+ rsp->quota += DIV_ROUND_UP(skb->len, mss_now); -+ else -+ rsp->quota++; -+ -+ return skb; -+ } -+ -+ return NULL; -+} -+ -+static struct mptcp_sched_ops mptcp_sched_rr = { -+ .get_subflow = rr_get_available_subflow, -+ .next_segment = mptcp_rr_next_segment, -+ .name = "roundrobin", -+ .owner = THIS_MODULE, -+}; -+ -+static int __init rr_register(void) -+{ -+ BUILD_BUG_ON(sizeof(struct rrsched_priv) > MPTCP_SCHED_SIZE); -+ -+ if (mptcp_register_scheduler(&mptcp_sched_rr)) -+ return -1; -+ -+ return 0; -+} -+ -+static void rr_unregister(void) -+{ -+ mptcp_unregister_scheduler(&mptcp_sched_rr); -+} -+ -+module_init(rr_register); -+module_exit(rr_unregister); -+ -+MODULE_AUTHOR("Christoph Paasch"); -+MODULE_LICENSE("GPL"); -+MODULE_DESCRIPTION("ROUNDROBIN MPTCP"); -+MODULE_VERSION("0.89"); -diff -aurN linux-4.9.162/net/mptcp/mptcp_sched.c mptcp-mptcp_v0.93/net/mptcp/mptcp_sched.c ---- linux-4.9.162/net/mptcp/mptcp_sched.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_v0.93/net/mptcp/mptcp_sched.c 2019-03-14 14:02:32.000000000 +0100 -@@ -0,0 +1,634 @@ -+/* MPTCP Scheduler module selector. Highly inspired by tcp_cong.c */ -+ -+#include -+#include -+ -+static DEFINE_SPINLOCK(mptcp_sched_list_lock); -+static LIST_HEAD(mptcp_sched_list); -+ -+struct defsched_priv { -+ u32 last_rbuf_opti; -+}; -+ -+static struct defsched_priv *defsched_get_priv(const struct tcp_sock *tp) -+{ -+ return (struct defsched_priv *)&tp->mptcp->mptcp_sched[0]; -+} -+ -+bool mptcp_is_def_unavailable(struct sock *sk) -+{ -+ const struct tcp_sock *tp = tcp_sk(sk); -+ -+ /* Set of states for which we are allowed to send data */ -+ if (!mptcp_sk_can_send(sk)) -+ return true; -+ -+ /* We do not send data on this subflow unless it is -+ * fully established, i.e. the 4th ack has been received. -+ */ -+ if (tp->mptcp->pre_established) -+ return true; -+ -+ if (tp->pf) -+ return true; -+ -+ return false; -+} -+EXPORT_SYMBOL_GPL(mptcp_is_def_unavailable); -+ -+static bool mptcp_is_temp_unavailable(struct sock *sk, -+ const struct sk_buff *skb, -+ bool zero_wnd_test) -+{ -+ const struct tcp_sock *tp = tcp_sk(sk); -+ unsigned int mss_now, space, in_flight; -+ -+ if (inet_csk(sk)->icsk_ca_state == TCP_CA_Loss) { -+ /* If SACK is disabled, and we got a loss, TCP does not exit -+ * the loss-state until something above high_seq has been -+ * acked. (see tcp_try_undo_recovery) -+ * -+ * high_seq is the snd_nxt at the moment of the RTO. As soon -+ * as we have an RTO, we won't push data on the subflow. -+ * Thus, snd_una can never go beyond high_seq. -+ */ -+ if (!tcp_is_reno(tp)) -+ return true; -+ else if (tp->snd_una != tp->high_seq) -+ return true; -+ } -+ -+ if (!tp->mptcp->fully_established) { -+ /* Make sure that we send in-order data */ -+ if (skb && tp->mptcp->second_packet && -+ tp->mptcp->last_end_data_seq != TCP_SKB_CB(skb)->seq) -+ return true; -+ } -+ -+ in_flight = tcp_packets_in_flight(tp); -+ /* Not even a single spot in the cwnd */ -+ if (in_flight >= tp->snd_cwnd) -+ return true; -+ -+ /* Now, check if what is queued in the subflow's send-queue -+ * already fills the cwnd. -+ */ -+ space = (tp->snd_cwnd - in_flight) * tp->mss_cache; -+ -+ if (tp->write_seq - tp->snd_nxt > space) -+ return true; -+ -+ if (zero_wnd_test && !before(tp->write_seq, tcp_wnd_end(tp))) -+ return true; -+ -+ mss_now = tcp_current_mss(sk); -+ -+ /* Don't send on this subflow if we bypass the allowed send-window at -+ * the per-subflow level. Similar to tcp_snd_wnd_test, but manually -+ * calculated end_seq (because here at this point end_seq is still at -+ * the meta-level). -+ */ -+ if (skb && !zero_wnd_test && -+ after(tp->write_seq + min(skb->len, mss_now), tcp_wnd_end(tp))) -+ return true; -+ -+ return false; -+} -+ -+/* Is the sub-socket sk available to send the skb? */ -+bool mptcp_is_available(struct sock *sk, const struct sk_buff *skb, -+ bool zero_wnd_test) -+{ -+ return !mptcp_is_def_unavailable(sk) && -+ !mptcp_is_temp_unavailable(sk, skb, zero_wnd_test); -+} -+EXPORT_SYMBOL_GPL(mptcp_is_available); -+ -+/* Are we not allowed to reinject this skb on tp? */ -+static int mptcp_dont_reinject_skb(const struct tcp_sock *tp, const struct sk_buff *skb) -+{ -+ /* If the skb has already been enqueued in this sk, try to find -+ * another one. -+ */ -+ return skb && -+ /* Has the skb already been enqueued into this subsocket? */ -+ mptcp_pi_to_flag(tp->mptcp->path_index) & TCP_SKB_CB(skb)->path_mask; -+} -+ -+bool subflow_is_backup(const struct tcp_sock *tp) -+{ -+ return tp->mptcp->rcv_low_prio || tp->mptcp->low_prio; -+} -+EXPORT_SYMBOL_GPL(subflow_is_backup); -+ -+bool subflow_is_active(const struct tcp_sock *tp) -+{ -+ return !tp->mptcp->rcv_low_prio && !tp->mptcp->low_prio; -+} -+EXPORT_SYMBOL_GPL(subflow_is_active); -+ -+/* Generic function to iterate over used and unused subflows and to select the -+ * best one -+ */ -+static struct sock -+*get_subflow_from_selectors(struct mptcp_cb *mpcb, struct sk_buff *skb, -+ bool (*selector)(const struct tcp_sock *), -+ bool zero_wnd_test, bool *force) -+{ -+ struct sock *bestsk = NULL; -+ u32 min_srtt = 0xffffffff; -+ bool found_unused = false; -+ bool found_unused_una = false; -+ struct sock *sk; -+ -+ mptcp_for_each_sk(mpcb, sk) { -+ struct tcp_sock *tp = tcp_sk(sk); -+ bool unused = false; -+ -+ /* First, we choose only the wanted sks */ -+ if (!(*selector)(tp)) -+ continue; -+ -+ if (!mptcp_dont_reinject_skb(tp, skb)) -+ unused = true; -+ else if (found_unused) -+ /* If a unused sk was found previously, we continue - -+ * no need to check used sks anymore. -+ */ -+ continue; -+ -+ if (mptcp_is_def_unavailable(sk)) -+ continue; -+ -+ if (mptcp_is_temp_unavailable(sk, skb, zero_wnd_test)) { -+ if (unused) -+ found_unused_una = true; -+ continue; -+ } -+ -+ if (unused) { -+ if (!found_unused) { -+ /* It's the first time we encounter an unused -+ * sk - thus we reset the bestsk (which might -+ * have been set to a used sk). -+ */ -+ min_srtt = 0xffffffff; -+ bestsk = NULL; -+ } -+ found_unused = true; -+ } -+ -+ if (tp->srtt_us < min_srtt) { -+ min_srtt = tp->srtt_us; -+ bestsk = sk; -+ } -+ } -+ -+ if (bestsk) { -+ /* The force variable is used to mark the returned sk as -+ * previously used or not-used. -+ */ -+ if (found_unused) -+ *force = true; -+ else -+ *force = false; -+ } else { -+ /* The force variable is used to mark if there are temporally -+ * unavailable not-used sks. -+ */ -+ if (found_unused_una) -+ *force = true; -+ else -+ *force = false; -+ } -+ -+ return bestsk; -+} -+ -+/* This is the scheduler. This function decides on which flow to send -+ * a given MSS. If all subflows are found to be busy, NULL is returned -+ * The flow is selected based on the shortest RTT. -+ * If all paths have full cong windows, we simply return NULL. -+ * -+ * Additionally, this function is aware of the backup-subflows. -+ */ -+struct sock *get_available_subflow(struct sock *meta_sk, struct sk_buff *skb, -+ bool zero_wnd_test) -+{ -+ struct mptcp_cb *mpcb = tcp_sk(meta_sk)->mpcb; -+ struct sock *sk; -+ bool looping = false, force; -+ -+ /* if there is only one subflow, bypass the scheduling function */ -+ if (mpcb->cnt_subflows == 1) { -+ sk = (struct sock *)mpcb->connection_list; -+ if (!mptcp_is_available(sk, skb, zero_wnd_test)) -+ sk = NULL; -+ return sk; -+ } -+ -+ /* Answer data_fin on same subflow!!! */ -+ if (meta_sk->sk_shutdown & RCV_SHUTDOWN && -+ skb && mptcp_is_data_fin(skb)) { -+ mptcp_for_each_sk(mpcb, sk) { -+ if (tcp_sk(sk)->mptcp->path_index == mpcb->dfin_path_index && -+ mptcp_is_available(sk, skb, zero_wnd_test)) -+ return sk; -+ } -+ } -+ -+ /* Find the best subflow */ -+restart: -+ sk = get_subflow_from_selectors(mpcb, skb, &subflow_is_active, -+ zero_wnd_test, &force); -+ if (force) -+ /* one unused active sk or one NULL sk when there is at least -+ * one temporally unavailable unused active sk -+ */ -+ return sk; -+ -+ sk = get_subflow_from_selectors(mpcb, skb, &subflow_is_backup, -+ zero_wnd_test, &force); -+ if (!force && skb) { -+ /* one used backup sk or one NULL sk where there is no one -+ * temporally unavailable unused backup sk -+ * -+ * the skb passed through all the available active and backups -+ * sks, so clean the path mask -+ */ -+ TCP_SKB_CB(skb)->path_mask = 0; -+ -+ if (!looping) { -+ looping = true; -+ goto restart; -+ } -+ } -+ return sk; -+} -+EXPORT_SYMBOL_GPL(get_available_subflow); -+ -+static struct sk_buff *mptcp_rcv_buf_optimization(struct sock *sk, int penal) -+{ -+ struct sock *meta_sk; -+ const struct tcp_sock *tp = tcp_sk(sk); -+ struct tcp_sock *tp_it; -+ struct sk_buff *skb_head; -+ struct defsched_priv *dsp = defsched_get_priv(tp); -+ -+ if (tp->mpcb->cnt_subflows == 1) -+ return NULL; -+ -+ meta_sk = mptcp_meta_sk(sk); -+ skb_head = tcp_write_queue_head(meta_sk); -+ -+ if (!skb_head || skb_head == tcp_send_head(meta_sk)) -+ return NULL; -+ -+ /* If penalization is optional (coming from mptcp_next_segment() and -+ * We are not send-buffer-limited we do not penalize. The retransmission -+ * is just an optimization to fix the idle-time due to the delay before -+ * we wake up the application. -+ */ -+ if (!penal && sk_stream_memory_free(meta_sk)) -+ goto retrans; -+ -+ /* Only penalize again after an RTT has elapsed */ -+ if (tcp_time_stamp - dsp->last_rbuf_opti < usecs_to_jiffies(tp->srtt_us >> 3)) -+ goto retrans; -+ -+ /* Half the cwnd of the slow flow */ -+ mptcp_for_each_tp(tp->mpcb, tp_it) { -+ if (tp_it != tp && -+ TCP_SKB_CB(skb_head)->path_mask & mptcp_pi_to_flag(tp_it->mptcp->path_index)) { -+ if (tp->srtt_us < tp_it->srtt_us && inet_csk((struct sock *)tp_it)->icsk_ca_state == TCP_CA_Open) { -+ u32 prior_cwnd = tp_it->snd_cwnd; -+ -+ tp_it->snd_cwnd = max(tp_it->snd_cwnd >> 1U, 1U); -+ -+ /* If in slow start, do not reduce the ssthresh */ -+ if (prior_cwnd >= tp_it->snd_ssthresh) -+ tp_it->snd_ssthresh = max(tp_it->snd_ssthresh >> 1U, 2U); -+ -+ dsp->last_rbuf_opti = tcp_time_stamp; -+ } -+ break; -+ } -+ } -+ -+retrans: -+ -+ /* Segment not yet injected into this path? Take it!!! */ -+ if (!(TCP_SKB_CB(skb_head)->path_mask & mptcp_pi_to_flag(tp->mptcp->path_index))) { -+ bool do_retrans = false; -+ mptcp_for_each_tp(tp->mpcb, tp_it) { -+ if (tp_it != tp && -+ TCP_SKB_CB(skb_head)->path_mask & mptcp_pi_to_flag(tp_it->mptcp->path_index)) { -+ if (tp_it->snd_cwnd <= 4) { -+ do_retrans = true; -+ break; -+ } -+ -+ if (4 * tp->srtt_us >= tp_it->srtt_us) { -+ do_retrans = false; -+ break; -+ } else { -+ do_retrans = true; -+ } -+ } -+ } -+ -+ if (do_retrans && mptcp_is_available(sk, skb_head, false)) -+ return skb_head; -+ } -+ return NULL; -+} -+ -+/* Returns the next segment to be sent from the mptcp meta-queue. -+ * (chooses the reinject queue if any segment is waiting in it, otherwise, -+ * chooses the normal write queue). -+ * Sets *@reinject to 1 if the returned segment comes from the -+ * reinject queue. Sets it to 0 if it is the regular send-head of the meta-sk, -+ * and sets it to -1 if it is a meta-level retransmission to optimize the -+ * receive-buffer. -+ */ -+static struct sk_buff *__mptcp_next_segment(struct sock *meta_sk, int *reinject) -+{ -+ const struct mptcp_cb *mpcb = tcp_sk(meta_sk)->mpcb; -+ struct sk_buff *skb = NULL; -+ -+ *reinject = 0; -+ -+ /* If we are in fallback-mode, just take from the meta-send-queue */ -+ if (mpcb->infinite_mapping_snd || mpcb->send_infinite_mapping) -+ return tcp_send_head(meta_sk); -+ -+ skb = skb_peek(&mpcb->reinject_queue); -+ -+ if (skb) { -+ *reinject = 1; -+ } else { -+ skb = tcp_send_head(meta_sk); -+ -+ if (!skb && meta_sk->sk_socket && -+ test_bit(SOCK_NOSPACE, &meta_sk->sk_socket->flags) && -+ sk_stream_wspace(meta_sk) < sk_stream_min_wspace(meta_sk)) { -+ struct sock *subsk = get_available_subflow(meta_sk, NULL, -+ false); -+ if (!subsk) -+ return NULL; -+ -+ skb = mptcp_rcv_buf_optimization(subsk, 0); -+ if (skb) -+ *reinject = -1; -+ } -+ } -+ return skb; -+} -+ -+static struct sk_buff *mptcp_next_segment(struct sock *meta_sk, -+ int *reinject, -+ struct sock **subsk, -+ unsigned int *limit) -+{ -+ struct sk_buff *skb = __mptcp_next_segment(meta_sk, reinject); -+ unsigned int mss_now; -+ struct tcp_sock *subtp; -+ u16 gso_max_segs; -+ u32 max_len, max_segs, window, needed; -+ -+ /* As we set it, we have to reset it as well. */ -+ *limit = 0; -+ -+ if (!skb) -+ return NULL; -+ -+ *subsk = get_available_subflow(meta_sk, skb, false); -+ if (!*subsk) -+ return NULL; -+ -+ subtp = tcp_sk(*subsk); -+ mss_now = tcp_current_mss(*subsk); -+ -+ if (!*reinject && unlikely(!tcp_snd_wnd_test(tcp_sk(meta_sk), skb, mss_now))) { -+ skb = mptcp_rcv_buf_optimization(*subsk, 1); -+ if (skb) -+ *reinject = -1; -+ else -+ return NULL; -+ } -+ -+ /* No splitting required, as we will only send one single segment */ -+ if (skb->len <= mss_now) -+ return skb; -+ -+ /* The following is similar to tcp_mss_split_point, but -+ * we do not care about nagle, because we will anyways -+ * use TCP_NAGLE_PUSH, which overrides this. -+ * -+ * So, we first limit according to the cwnd/gso-size and then according -+ * to the subflow's window. -+ */ -+ -+ gso_max_segs = (*subsk)->sk_gso_max_segs; -+ if (!gso_max_segs) /* No gso supported on the subflow's NIC */ -+ gso_max_segs = 1; -+ max_segs = min_t(unsigned int, tcp_cwnd_test(subtp, skb), gso_max_segs); -+ if (!max_segs) -+ return NULL; -+ -+ max_len = mss_now * max_segs; -+ window = tcp_wnd_end(subtp) - subtp->write_seq; -+ -+ needed = min(skb->len, window); -+ if (max_len <= skb->len) -+ /* Take max_win, which is actually the cwnd/gso-size */ -+ *limit = max_len; -+ else -+ /* Or, take the window */ -+ *limit = needed; -+ -+ return skb; -+} -+ -+static void defsched_init(struct sock *sk) -+{ -+ struct defsched_priv *dsp = defsched_get_priv(tcp_sk(sk)); -+ -+ dsp->last_rbuf_opti = tcp_time_stamp; -+} -+ -+struct mptcp_sched_ops mptcp_sched_default = { -+ .get_subflow = get_available_subflow, -+ .next_segment = mptcp_next_segment, -+ .init = defsched_init, -+ .name = "default", -+ .owner = THIS_MODULE, -+}; -+ -+static struct mptcp_sched_ops *mptcp_sched_find(const char *name) -+{ -+ struct mptcp_sched_ops *e; -+ -+ list_for_each_entry_rcu(e, &mptcp_sched_list, list) { -+ if (strcmp(e->name, name) == 0) -+ return e; -+ } -+ -+ return NULL; -+} -+ -+int mptcp_register_scheduler(struct mptcp_sched_ops *sched) -+{ -+ int ret = 0; -+ -+ if (!sched->get_subflow || !sched->next_segment) -+ return -EINVAL; -+ -+ spin_lock(&mptcp_sched_list_lock); -+ if (mptcp_sched_find(sched->name)) { -+ pr_notice("%s already registered\n", sched->name); -+ ret = -EEXIST; -+ } else { -+ list_add_tail_rcu(&sched->list, &mptcp_sched_list); -+ pr_info("%s registered\n", sched->name); -+ } -+ spin_unlock(&mptcp_sched_list_lock); -+ -+ return ret; -+} -+EXPORT_SYMBOL_GPL(mptcp_register_scheduler); -+ -+void mptcp_unregister_scheduler(struct mptcp_sched_ops *sched) -+{ -+ spin_lock(&mptcp_sched_list_lock); -+ list_del_rcu(&sched->list); -+ spin_unlock(&mptcp_sched_list_lock); -+ -+ /* Wait for outstanding readers to complete before the -+ * module gets removed entirely. -+ * -+ * A try_module_get() should fail by now as our module is -+ * in "going" state since no refs are held anymore and -+ * module_exit() handler being called. -+ */ -+ synchronize_rcu(); -+} -+EXPORT_SYMBOL_GPL(mptcp_unregister_scheduler); -+ -+void mptcp_get_default_scheduler(char *name) -+{ -+ struct mptcp_sched_ops *sched; -+ -+ BUG_ON(list_empty(&mptcp_sched_list)); -+ -+ rcu_read_lock(); -+ sched = list_entry(mptcp_sched_list.next, struct mptcp_sched_ops, list); -+ strncpy(name, sched->name, MPTCP_SCHED_NAME_MAX); -+ rcu_read_unlock(); -+} -+ -+int mptcp_set_default_scheduler(const char *name) -+{ -+ struct mptcp_sched_ops *sched; -+ int ret = -ENOENT; -+ -+ spin_lock(&mptcp_sched_list_lock); -+ sched = mptcp_sched_find(name); -+#ifdef CONFIG_MODULES -+ if (!sched && capable(CAP_NET_ADMIN)) { -+ spin_unlock(&mptcp_sched_list_lock); -+ -+ request_module("mptcp_%s", name); -+ spin_lock(&mptcp_sched_list_lock); -+ sched = mptcp_sched_find(name); -+ } -+#endif -+ -+ if (sched) { -+ list_move(&sched->list, &mptcp_sched_list); -+ ret = 0; -+ } else { -+ pr_info("%s is not available\n", name); -+ } -+ spin_unlock(&mptcp_sched_list_lock); -+ -+ return ret; -+} -+ -+/* Must be called with rcu lock held */ -+static struct mptcp_sched_ops *__mptcp_sched_find_autoload(const char *name) -+{ -+ struct mptcp_sched_ops *sched = mptcp_sched_find(name); -+#ifdef CONFIG_MODULES -+ if (!sched && capable(CAP_NET_ADMIN)) { -+ rcu_read_unlock(); -+ request_module("mptcp_%s", name); -+ rcu_read_lock(); -+ sched = mptcp_sched_find(name); -+ } -+#endif -+ return sched; -+} -+ -+void mptcp_init_scheduler(struct mptcp_cb *mpcb) -+{ -+ struct mptcp_sched_ops *sched; -+ struct sock *meta_sk = mpcb->meta_sk; -+ struct tcp_sock *meta_tp = tcp_sk(meta_sk); -+ -+ rcu_read_lock(); -+ /* if scheduler was set using socket option */ -+ if (meta_tp->mptcp_sched_setsockopt) { -+ sched = __mptcp_sched_find_autoload(meta_tp->mptcp_sched_name); -+ if (sched && try_module_get(sched->owner)) { -+ mpcb->sched_ops = sched; -+ goto out; -+ } -+ } -+ -+ list_for_each_entry_rcu(sched, &mptcp_sched_list, list) { -+ if (try_module_get(sched->owner)) { -+ mpcb->sched_ops = sched; -+ break; -+ } -+ } -+out: -+ rcu_read_unlock(); -+} -+ -+/* Change scheduler for socket */ -+int mptcp_set_scheduler(struct sock *sk, const char *name) -+{ -+ struct mptcp_sched_ops *sched; -+ int err = 0; -+ -+ rcu_read_lock(); -+ sched = __mptcp_sched_find_autoload(name); -+ -+ if (!sched) { -+ err = -ENOENT; -+ } else if (!ns_capable(sock_net(sk)->user_ns, CAP_NET_ADMIN)) { -+ err = -EPERM; -+ } else { -+ strcpy(tcp_sk(sk)->mptcp_sched_name, name); -+ tcp_sk(sk)->mptcp_sched_setsockopt = 1; -+ } -+ rcu_read_unlock(); -+ -+ return err; -+} -+ -+/* Manage refcounts on socket close. */ -+void mptcp_cleanup_scheduler(struct mptcp_cb *mpcb) -+{ -+ module_put(mpcb->sched_ops->owner); -+} -+ -+/* Set default value from kernel configuration at bootup */ -+static int __init mptcp_scheduler_default(void) -+{ -+ BUILD_BUG_ON(sizeof(struct defsched_priv) > MPTCP_SCHED_SIZE); -+ -+ return mptcp_set_default_scheduler(CONFIG_DEFAULT_MPTCP_SCHED); -+} -+late_initcall(mptcp_scheduler_default); -diff -aurN linux-4.9.162/net/mptcp/mptcp_wvegas.c mptcp-mptcp_v0.93/net/mptcp/mptcp_wvegas.c ---- linux-4.9.162/net/mptcp/mptcp_wvegas.c 1970-01-01 01:00:00.000000000 +0100 -+++ mptcp-mptcp_v0.93/net/mptcp/mptcp_wvegas.c 2019-03-14 14:02:32.000000000 +0100 -@@ -0,0 +1,269 @@ -+/* -+ * MPTCP implementation - WEIGHTED VEGAS -+ * -+ * Algorithm design: -+ * Yu Cao -+ * Mingwei Xu -+ * Xiaoming Fu -+ * -+ * Implementation: -+ * Yu Cao -+ * Enhuan Dong -+ * -+ * Ported to the official MPTCP-kernel: -+ * Christoph Paasch -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version -+ * 2 of the License, or (at your option) any later version. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+static int initial_alpha = 2; -+static int total_alpha = 10; -+static int gamma = 1; -+ -+module_param(initial_alpha, int, 0644); -+MODULE_PARM_DESC(initial_alpha, "initial alpha for all subflows"); -+module_param(total_alpha, int, 0644); -+MODULE_PARM_DESC(total_alpha, "total alpha for all subflows"); -+module_param(gamma, int, 0644); -+MODULE_PARM_DESC(gamma, "limit on increase (scale by 2)"); -+ -+#define MPTCP_WVEGAS_SCALE 16 -+ -+/* wVegas variables */ -+struct wvegas { -+ u32 beg_snd_nxt; /* right edge during last RTT */ -+ u8 doing_wvegas_now;/* if true, do wvegas for this RTT */ -+ -+ u16 cnt_rtt; /* # of RTTs measured within last RTT */ -+ u32 sampled_rtt; /* cumulative RTTs measured within last RTT (in usec) */ -+ u32 base_rtt; /* the min of all wVegas RTT measurements seen (in usec) */ -+ -+ u64 instant_rate; /* cwnd / srtt_us, unit: pkts/us * 2^16 */ -+ u64 weight; /* the ratio of subflow's rate to the total rate, * 2^16 */ -+ int alpha; /* alpha for each subflows */ -+ -+ u32 queue_delay; /* queue delay*/ -+}; -+ -+ -+static inline u64 mptcp_wvegas_scale(u32 val, int scale) -+{ -+ return (u64) val << scale; -+} -+ -+static void wvegas_enable(const struct sock *sk) -+{ -+ const struct tcp_sock *tp = tcp_sk(sk); -+ struct wvegas *wvegas = inet_csk_ca(sk); -+ -+ wvegas->doing_wvegas_now = 1; -+ -+ wvegas->beg_snd_nxt = tp->snd_nxt; -+ -+ wvegas->cnt_rtt = 0; -+ wvegas->sampled_rtt = 0; -+ -+ wvegas->instant_rate = 0; -+ wvegas->alpha = initial_alpha; -+ wvegas->weight = mptcp_wvegas_scale(1, MPTCP_WVEGAS_SCALE); -+ -+ wvegas->queue_delay = 0; -+} -+ -+static inline void wvegas_disable(const struct sock *sk) -+{ -+ struct wvegas *wvegas = inet_csk_ca(sk); -+ -+ wvegas->doing_wvegas_now = 0; -+} -+ -+static void mptcp_wvegas_init(struct sock *sk) -+{ -+ struct wvegas *wvegas = inet_csk_ca(sk); -+ -+ wvegas->base_rtt = 0x7fffffff; -+ wvegas_enable(sk); -+} -+ -+static inline u64 mptcp_wvegas_rate(u32 cwnd, u32 rtt_us) -+{ -+ return div_u64(mptcp_wvegas_scale(cwnd, MPTCP_WVEGAS_SCALE), rtt_us); -+} -+ -+static void mptcp_wvegas_pkts_acked(struct sock *sk, -+ const struct ack_sample *sample) -+{ -+ struct wvegas *wvegas = inet_csk_ca(sk); -+ u32 vrtt; -+ -+ if (sample->rtt_us < 0) -+ return; -+ -+ vrtt = sample->rtt_us + 1; -+ -+ if (vrtt < wvegas->base_rtt) -+ wvegas->base_rtt = vrtt; -+ -+ wvegas->sampled_rtt += vrtt; -+ wvegas->cnt_rtt++; -+} -+ -+static void mptcp_wvegas_state(struct sock *sk, u8 ca_state) -+{ -+ if (ca_state == TCP_CA_Open) -+ wvegas_enable(sk); -+ else -+ wvegas_disable(sk); -+} -+ -+static void mptcp_wvegas_cwnd_event(struct sock *sk, enum tcp_ca_event event) -+{ -+ if (event == CA_EVENT_CWND_RESTART) { -+ mptcp_wvegas_init(sk); -+ } else if (event == CA_EVENT_LOSS) { -+ struct wvegas *wvegas = inet_csk_ca(sk); -+ wvegas->instant_rate = 0; -+ } -+} -+ -+static inline u32 mptcp_wvegas_ssthresh(const struct tcp_sock *tp) -+{ -+ return min(tp->snd_ssthresh, tp->snd_cwnd); -+} -+ -+static u64 mptcp_wvegas_weight(const struct mptcp_cb *mpcb, const struct sock *sk) -+{ -+ u64 total_rate = 0; -+ struct sock *sub_sk; -+ const struct wvegas *wvegas = inet_csk_ca(sk); -+ -+ if (!mpcb) -+ return wvegas->weight; -+ -+ -+ mptcp_for_each_sk(mpcb, sub_sk) { -+ struct wvegas *sub_wvegas = inet_csk_ca(sub_sk); -+ -+ /* sampled_rtt is initialized by 0 */ -+ if (mptcp_sk_can_send(sub_sk) && (sub_wvegas->sampled_rtt > 0)) -+ total_rate += sub_wvegas->instant_rate; -+ } -+ -+ if (total_rate && wvegas->instant_rate) -+ return div64_u64(mptcp_wvegas_scale(wvegas->instant_rate, MPTCP_WVEGAS_SCALE), total_rate); -+ else -+ return wvegas->weight; -+} -+ -+static void mptcp_wvegas_cong_avoid(struct sock *sk, u32 ack, u32 acked) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct wvegas *wvegas = inet_csk_ca(sk); -+ -+ if (!wvegas->doing_wvegas_now) { -+ tcp_reno_cong_avoid(sk, ack, acked); -+ return; -+ } -+ -+ if (after(ack, wvegas->beg_snd_nxt)) { -+ wvegas->beg_snd_nxt = tp->snd_nxt; -+ -+ if (wvegas->cnt_rtt <= 2) { -+ tcp_reno_cong_avoid(sk, ack, acked); -+ } else { -+ u32 rtt, diff, q_delay; -+ u64 target_cwnd; -+ -+ rtt = wvegas->sampled_rtt / wvegas->cnt_rtt; -+ target_cwnd = div_u64(((u64)tp->snd_cwnd * wvegas->base_rtt), rtt); -+ -+ diff = div_u64((u64)tp->snd_cwnd * (rtt - wvegas->base_rtt), rtt); -+ -+ if (diff > gamma && tcp_in_slow_start(tp)) { -+ tp->snd_cwnd = min(tp->snd_cwnd, (u32)target_cwnd+1); -+ tp->snd_ssthresh = mptcp_wvegas_ssthresh(tp); -+ -+ } else if (tcp_in_slow_start(tp)) { -+ tcp_slow_start(tp, acked); -+ } else { -+ if (diff >= wvegas->alpha) { -+ wvegas->instant_rate = mptcp_wvegas_rate(tp->snd_cwnd, rtt); -+ wvegas->weight = mptcp_wvegas_weight(tp->mpcb, sk); -+ wvegas->alpha = max(2U, (u32)((wvegas->weight * total_alpha) >> MPTCP_WVEGAS_SCALE)); -+ } -+ if (diff > wvegas->alpha) { -+ tp->snd_cwnd--; -+ tp->snd_ssthresh = mptcp_wvegas_ssthresh(tp); -+ } else if (diff < wvegas->alpha) { -+ tp->snd_cwnd++; -+ } -+ -+ /* Try to drain link queue if needed*/ -+ q_delay = rtt - wvegas->base_rtt; -+ if ((wvegas->queue_delay == 0) || (wvegas->queue_delay > q_delay)) -+ wvegas->queue_delay = q_delay; -+ -+ if (q_delay >= 2 * wvegas->queue_delay) { -+ u32 backoff_factor = div_u64(mptcp_wvegas_scale(wvegas->base_rtt, MPTCP_WVEGAS_SCALE), 2 * rtt); -+ tp->snd_cwnd = ((u64)tp->snd_cwnd * backoff_factor) >> MPTCP_WVEGAS_SCALE; -+ wvegas->queue_delay = 0; -+ } -+ } -+ -+ if (tp->snd_cwnd < 2) -+ tp->snd_cwnd = 2; -+ else if (tp->snd_cwnd > tp->snd_cwnd_clamp) -+ tp->snd_cwnd = tp->snd_cwnd_clamp; -+ -+ tp->snd_ssthresh = tcp_current_ssthresh(sk); -+ } -+ -+ wvegas->cnt_rtt = 0; -+ wvegas->sampled_rtt = 0; -+ } -+ /* Use normal slow start */ -+ else if (tcp_in_slow_start(tp)) -+ tcp_slow_start(tp, acked); -+} -+ -+ -+static struct tcp_congestion_ops mptcp_wvegas __read_mostly = { -+ .init = mptcp_wvegas_init, -+ .ssthresh = tcp_reno_ssthresh, -+ .cong_avoid = mptcp_wvegas_cong_avoid, -+ .pkts_acked = mptcp_wvegas_pkts_acked, -+ .set_state = mptcp_wvegas_state, -+ .cwnd_event = mptcp_wvegas_cwnd_event, -+ -+ .owner = THIS_MODULE, -+ .name = "wvegas", -+}; -+ -+static int __init mptcp_wvegas_register(void) -+{ -+ BUILD_BUG_ON(sizeof(struct wvegas) > ICSK_CA_PRIV_SIZE); -+ tcp_register_congestion_control(&mptcp_wvegas); -+ return 0; -+} -+ -+static void __exit mptcp_wvegas_unregister(void) -+{ -+ tcp_unregister_congestion_control(&mptcp_wvegas); -+} -+ -+module_init(mptcp_wvegas_register); -+module_exit(mptcp_wvegas_unregister); -+ -+MODULE_AUTHOR("Yu Cao, Enhuan Dong"); -+MODULE_LICENSE("GPL"); -+MODULE_DESCRIPTION("MPTCP wVegas"); -+MODULE_VERSION("0.1"); diff --git a/root/target/linux/generic/hack-5.4/690-mptcp_trunk.patch b/root/target/linux/generic/hack-5.4/690-mptcp_trunk.patch deleted file mode 100644 index dfb008e1..00000000 --- a/root/target/linux/generic/hack-5.4/690-mptcp_trunk.patch +++ /dev/null @@ -1,23662 +0,0 @@ -diff -aurN linux-5.4.64/Documentation/admin-guide/kernel-parameters.txt linux-5.4.64.mptcp/Documentation/admin-guide/kernel-parameters.txt ---- linux-5.4.64/Documentation/admin-guide/kernel-parameters.txt 2020-09-09 19:12:37.000000000 +0200 -+++ linux-5.4.64.mptcp/Documentation/admin-guide/kernel-parameters.txt 2020-09-10 19:25:10.375223065 +0200 -@@ -2734,6 +2734,10 @@ - allocations which rules out almost all kernel - allocations. Use with caution! - -+ mptcp_htable_entries= -+ [KNL,NET] Set number of hash buckets for MPTCP token -+ hashtables. -+ - MTD_Partition= [MTD] - Format: ,,, - -diff -aurN linux-5.4.64/Documentation/networking/ip-sysctl.txt linux-5.4.64.mptcp/Documentation/networking/ip-sysctl.txt ---- linux-5.4.64/Documentation/networking/ip-sysctl.txt 2020-09-09 19:12:37.000000000 +0200 -+++ linux-5.4.64.mptcp/Documentation/networking/ip-sysctl.txt 2020-09-10 19:25:10.375223065 +0200 -@@ -818,6 +818,18 @@ - - Default: 0 (disabled) - -+MPTCP variables: -+ -+mptcp_enabled - INTEGER -+ Enable or disable Multipath TCP for new connections. -+ Possible values are: -+ -+ 0: Multipath TCP is disabled on all TCP-sockets that are newly created. -+ 1: Multipath TCP is enabled by default on all new TCP-sockets. Note that -+ existing sockets in LISTEN-state will still use regular TCP. -+ 2: Enables Multipath TCP only upon the request of the application -+ throught the socket-option MPTCP_ENABLED. -+ - UDP variables: - - udp_l3mdev_accept - BOOLEAN -diff -aurN linux-5.4.64/drivers/infiniband/hw/cxgb4/cm.c linux-5.4.64.mptcp/drivers/infiniband/hw/cxgb4/cm.c ---- linux-5.4.64/drivers/infiniband/hw/cxgb4/cm.c 2020-09-09 19:12:37.000000000 +0200 -+++ linux-5.4.64.mptcp/drivers/infiniband/hw/cxgb4/cm.c 2020-09-10 19:25:10.439222000 +0200 -@@ -3949,7 +3949,7 @@ - */ - memset(&tmp_opt, 0, sizeof(tmp_opt)); - tcp_clear_options(&tmp_opt); -- tcp_parse_options(&init_net, skb, &tmp_opt, 0, NULL); -+ tcp_parse_options(&init_net, skb, &tmp_opt, NULL, 0, NULL, NULL); - - req = __skb_push(skb, sizeof(*req)); - memset(req, 0, sizeof(*req)); -diff -aurN linux-5.4.64/include/linux/skbuff.h linux-5.4.64.mptcp/include/linux/skbuff.h ---- linux-5.4.64/include/linux/skbuff.h 2020-09-09 19:12:37.000000000 +0200 -+++ linux-5.4.64.mptcp/include/linux/skbuff.h 2020-09-10 19:25:10.439222000 +0200 -@@ -717,7 +717,7 @@ - * want to keep them across layers you have to do a skb_clone() - * first. This is owned by whoever has the skb queued ATM. - */ -- char cb[48] __aligned(8); -+ char cb[80] __aligned(8); - - union { - struct { -diff -aurN linux-5.4.64/include/linux/tcp.h linux-5.4.64.mptcp/include/linux/tcp.h ---- linux-5.4.64/include/linux/tcp.h 2020-09-09 19:12:37.000000000 +0200 -+++ linux-5.4.64.mptcp/include/linux/tcp.h 2020-09-10 19:25:10.499221003 +0200 -@@ -54,7 +54,7 @@ - /* TCP Fast Open */ - #define TCP_FASTOPEN_COOKIE_MIN 4 /* Min Fast Open Cookie size in bytes */ - #define TCP_FASTOPEN_COOKIE_MAX 16 /* Max Fast Open Cookie size in bytes */ --#define TCP_FASTOPEN_COOKIE_SIZE 8 /* the size employed by this impl. */ -+#define TCP_FASTOPEN_COOKIE_SIZE 4 /* the size employed by this impl. */ - - /* TCP Fast Open Cookie as stored in memory */ - struct tcp_fastopen_cookie { -@@ -74,6 +74,56 @@ - u32 end_seq; - }; - -+struct tcp_out_options { -+ u16 options; /* bit field of OPTION_* */ -+ u16 mss; /* 0 to disable */ -+ u8 ws; /* window scale, 0 to disable */ -+ u8 num_sack_blocks; /* number of SACK blocks to include */ -+ u8 hash_size; /* bytes in hash_location */ -+ __u8 *hash_location; /* temporary pointer, overloaded */ -+ __u32 tsval, tsecr; /* need to include OPTION_TS */ -+ struct tcp_fastopen_cookie *fastopen_cookie; /* Fast open cookie */ -+#ifdef CONFIG_MPTCP -+ u16 mptcp_options; /* bit field of MPTCP related OPTION_* */ -+ u8 dss_csum:1, /* dss-checksum required? */ -+ add_addr_v4:1, -+ add_addr_v6:1, -+ mptcp_ver:4; -+ -+ union { -+ struct { -+ __u64 sender_key; /* sender's key for mptcp */ -+ __u64 receiver_key; /* receiver's key for mptcp */ -+ } mp_capable; -+ -+ struct { -+ __u64 sender_truncated_mac; -+ __u32 sender_nonce; -+ /* random number of the sender */ -+ __u32 token; /* token for mptcp */ -+ u8 low_prio:1; -+ } mp_join_syns; -+ }; -+ -+ struct { -+ __u64 trunc_mac; -+ struct in_addr addr; -+ u16 port; -+ u8 addr_id; -+ } add_addr4; -+ -+ struct { -+ __u64 trunc_mac; -+ struct in6_addr addr; -+ u16 port; -+ u8 addr_id; -+ } add_addr6; -+ -+ u16 remove_addrs; /* list of address id */ -+ u8 addr_id; /* address id (mp_join or add_address) */ -+#endif /* CONFIG_MPTCP */ -+}; -+ - /*These are used to set the sack_ok field in struct tcp_options_received */ - #define TCP_SACK_SEEN (1 << 0) /*1 = peer is SACK capable, */ - #define TCP_DSACK_SEEN (1 << 2) /*1 = DSACK was received from peer*/ -@@ -97,6 +147,9 @@ - u16 mss_clamp; /* Maximal mss, negotiated at connection setup */ - }; - -+struct mptcp_cb; -+struct mptcp_tcp_sock; -+ - static inline void tcp_clear_options(struct tcp_options_received *rx_opt) - { - rx_opt->tstamp_ok = rx_opt->sack_ok = 0; -@@ -135,6 +188,8 @@ - return (struct tcp_request_sock *)req; - } - -+struct tcp_md5sig_key; -+ - struct tcp_sock { - /* inet_connection_sock has to be the first member of tcp_sock */ - struct inet_connection_sock inet_conn; -@@ -397,6 +452,44 @@ - */ - struct request_sock __rcu *fastopen_rsk; - u32 *saved_syn; -+ -+ /* MPTCP/TCP-specific callbacks */ -+ const struct tcp_sock_ops *ops; -+ -+ struct mptcp_cb *mpcb; -+ struct sock *meta_sk; -+ /* We keep these flags even if CONFIG_MPTCP is not checked, because -+ * it allows checking MPTCP capability just by checking the mpc flag, -+ * rather than adding ifdefs everywhere. -+ */ -+ u32 mpc:1, /* Other end is multipath capable */ -+ inside_tk_table:1, /* Is the tcp_sock inside the token-table? */ -+ send_mp_fclose:1, -+ request_mptcp:1, /* Did we send out an MP_CAPABLE? -+ * (this speeds up mptcp_doit() in tcp_recvmsg) -+ */ -+ pf:1, /* Potentially Failed state: when this flag is set, we -+ * stop using the subflow -+ */ -+ mp_killed:1, /* Killed with a tcp_done in mptcp? */ -+ is_master_sk:1, -+ close_it:1, /* Must close socket in mptcp_data_ready? */ -+ closing:1, -+ mptcp_ver:4, -+ mptcp_sched_setsockopt:1, -+ mptcp_pm_setsockopt:1, -+ record_master_info:1, -+ tcp_disconnect:1; -+ struct mptcp_tcp_sock *mptcp; -+#ifdef CONFIG_MPTCP -+#define MPTCP_SCHED_NAME_MAX 16 -+#define MPTCP_PM_NAME_MAX 16 -+ struct hlist_nulls_node tk_table; -+ u32 mptcp_loc_token; -+ u64 mptcp_loc_key; -+ char mptcp_sched_name[MPTCP_SCHED_NAME_MAX]; -+ char mptcp_pm_name[MPTCP_PM_NAME_MAX]; -+#endif /* CONFIG_MPTCP */ - }; - - enum tsq_enum { -@@ -408,6 +501,8 @@ - TCP_MTU_REDUCED_DEFERRED, /* tcp_v{4|6}_err() could not call - * tcp_v{4|6}_mtu_reduced() - */ -+ MPTCP_PATH_MANAGER_DEFERRED, /* MPTCP deferred creation of new subflows */ -+ MPTCP_SUB_DEFERRED, /* A subflow got deferred - process them */ - }; - - enum tsq_flags { -@@ -417,6 +512,8 @@ - TCPF_WRITE_TIMER_DEFERRED = (1UL << TCP_WRITE_TIMER_DEFERRED), - TCPF_DELACK_TIMER_DEFERRED = (1UL << TCP_DELACK_TIMER_DEFERRED), - TCPF_MTU_REDUCED_DEFERRED = (1UL << TCP_MTU_REDUCED_DEFERRED), -+ TCPF_PATH_MANAGER_DEFERRED = (1UL << MPTCP_PATH_MANAGER_DEFERRED), -+ TCPF_SUB_DEFERRED = (1UL << MPTCP_SUB_DEFERRED), - }; - - static inline struct tcp_sock *tcp_sk(const struct sock *sk) -@@ -440,6 +537,7 @@ - #ifdef CONFIG_TCP_MD5SIG - struct tcp_md5sig_key *tw_md5_key; - #endif -+ struct mptcp_tw *mptcp_tw; - }; - - static inline struct tcp_timewait_sock *tcp_twsk(const struct sock *sk) -diff -aurN linux-5.4.64/include/net/inet_common.h linux-5.4.64.mptcp/include/net/inet_common.h ---- linux-5.4.64/include/net/inet_common.h 2020-09-09 19:12:37.000000000 +0200 -+++ linux-5.4.64.mptcp/include/net/inet_common.h 2020-09-10 19:25:10.499221003 +0200 -@@ -2,6 +2,7 @@ - #ifndef _INET_COMMON_H - #define _INET_COMMON_H - -+#include - #include - - extern const struct proto_ops inet_stream_ops; -@@ -16,6 +17,8 @@ - struct sockaddr; - struct socket; - -+int inet_create(struct net *net, struct socket *sock, int protocol, int kern); -+int inet6_create(struct net *net, struct socket *sock, int protocol, int kern); - int inet_release(struct socket *sock); - int inet_stream_connect(struct socket *sock, struct sockaddr *uaddr, - int addr_len, int flags); -diff -aurN linux-5.4.64/include/net/inet_connection_sock.h linux-5.4.64.mptcp/include/net/inet_connection_sock.h ---- linux-5.4.64/include/net/inet_connection_sock.h 2020-09-09 19:12:37.000000000 +0200 -+++ linux-5.4.64.mptcp/include/net/inet_connection_sock.h 2020-09-10 19:25:10.499221003 +0200 -@@ -25,6 +25,7 @@ - - struct inet_bind_bucket; - struct tcp_congestion_ops; -+struct tcp_options_received; - - /* - * Pointers to address related TCP functions -diff -aurN linux-5.4.64/include/net/inet_sock.h linux-5.4.64.mptcp/include/net/inet_sock.h ---- linux-5.4.64/include/net/inet_sock.h 2020-09-09 19:12:37.000000000 +0200 -+++ linux-5.4.64.mptcp/include/net/inet_sock.h 2020-09-10 19:25:10.499221003 +0200 -@@ -79,7 +79,7 @@ - #define ireq_state req.__req_common.skc_state - #define ireq_family req.__req_common.skc_family - -- u16 snd_wscale : 4, -+ u32 snd_wscale : 4, - rcv_wscale : 4, - tstamp_ok : 1, - sack_ok : 1, -@@ -87,6 +87,8 @@ - ecn_ok : 1, - acked : 1, - no_srccheck: 1, -+ mptcp_rqsk : 1, -+ saw_mpc : 1, - smc_ok : 1; - u32 ir_mark; - union { -diff -aurN linux-5.4.64/include/net/mptcp.h linux-5.4.64.mptcp/include/net/mptcp.h ---- linux-5.4.64/include/net/mptcp.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-5.4.64.mptcp/include/net/mptcp.h 2020-09-10 19:25:10.499221003 +0200 -@@ -0,0 +1,1571 @@ -+/* -+ * MPTCP implementation -+ * -+ * Initial Design & Implementation: -+ * Sébastien Barré -+ * -+ * Current Maintainer & Author: -+ * Christoph Paasch -+ * -+ * Additional authors: -+ * Jaakko Korkeaniemi -+ * Gregory Detal -+ * Fabien Duchêne -+ * Andreas Seelinger -+ * Lavkesh Lahngir -+ * Andreas Ripke -+ * Vlad Dogaru -+ * Octavian Purdila -+ * John Ronan -+ * Catalin Nicutar -+ * Brandon Heller -+ * -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version -+ * 2 of the License, or (at your option) any later version. -+ */ -+ -+#ifndef _MPTCP_H -+#define _MPTCP_H -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+ -+#if defined(__LITTLE_ENDIAN_BITFIELD) -+ #define ntohll(x) be64_to_cpu(x) -+ #define htonll(x) cpu_to_be64(x) -+#elif defined(__BIG_ENDIAN_BITFIELD) -+ #define ntohll(x) (x) -+ #define htonll(x) (x) -+#endif -+ -+struct mptcp_loc4 { -+ u8 loc4_id; -+ u8 low_prio:1; -+ int if_idx; -+ struct in_addr addr; -+}; -+ -+struct mptcp_rem4 { -+ u8 rem4_id; -+ __be16 port; -+ struct in_addr addr; -+}; -+ -+struct mptcp_loc6 { -+ u8 loc6_id; -+ u8 low_prio:1; -+ int if_idx; -+ struct in6_addr addr; -+}; -+ -+struct mptcp_rem6 { -+ u8 rem6_id; -+ __be16 port; -+ struct in6_addr addr; -+}; -+ -+struct mptcp_request_sock { -+ struct tcp_request_sock req; -+ struct hlist_nulls_node hash_entry; -+ -+ union { -+ struct { -+ /* Only on initial subflows */ -+ u64 mptcp_loc_key; -+ u64 mptcp_rem_key; -+ u32 mptcp_loc_token; -+ }; -+ -+ struct { -+ /* Only on additional subflows */ -+ u32 mptcp_rem_nonce; -+ u32 mptcp_loc_nonce; -+ u64 mptcp_hash_tmac; -+ }; -+ }; -+ -+ u8 loc_id; -+ u8 rem_id; /* Address-id in the MP_JOIN */ -+ u16 dss_csum:1, -+ rem_key_set:1, -+ is_sub:1, /* Is this a new subflow? */ -+ low_prio:1, /* Interface set to low-prio? */ -+ rcv_low_prio:1, -+ mptcp_ver:4; -+}; -+ -+struct mptcp_options_received { -+ u16 saw_mpc:1, -+ dss_csum:1, -+ drop_me:1, -+ -+ is_mp_join:1, -+ join_ack:1, -+ -+ saw_low_prio:2, /* 0x1 - low-prio set for this subflow -+ * 0x2 - low-prio set for another subflow -+ */ -+ low_prio:1, -+ -+ saw_add_addr:2, /* Saw at least one add_addr option: -+ * 0x1: IPv4 - 0x2: IPv6 -+ */ -+ more_add_addr:1, /* Saw one more add-addr. */ -+ -+ saw_rem_addr:1, /* Saw at least one rem_addr option */ -+ more_rem_addr:1, /* Saw one more rem-addr. */ -+ -+ mp_fail:1, -+ mp_fclose:1; -+ u8 rem_id; /* Address-id in the MP_JOIN */ -+ u8 prio_addr_id; /* Address-id in the MP_PRIO */ -+ -+ const unsigned char *add_addr_ptr; /* Pointer to add-address option */ -+ const unsigned char *rem_addr_ptr; /* Pointer to rem-address option */ -+ -+ u32 data_ack; -+ u32 data_seq; -+ u16 data_len; -+ -+ u8 mptcp_ver; /* MPTCP version */ -+ -+ /* Key inside the option (from mp_capable or fast_close) */ -+ u64 mptcp_sender_key; -+ u64 mptcp_receiver_key; -+ -+ u32 mptcp_rem_token; /* Remote token */ -+ -+ u32 mptcp_recv_nonce; -+ u64 mptcp_recv_tmac; -+ u8 mptcp_recv_mac[20]; -+}; -+ -+struct mptcp_tcp_sock { -+ struct hlist_node node; -+ struct hlist_node cb_list; -+ struct mptcp_options_received rx_opt; -+ -+ /* Those three fields record the current mapping */ -+ u64 map_data_seq; -+ u32 map_subseq; -+ u16 map_data_len; -+ u16 slave_sk:1, -+ fully_established:1, -+ second_packet:1, -+ attached:1, -+ send_mp_fail:1, -+ include_mpc:1, -+ mapping_present:1, -+ map_data_fin:1, -+ low_prio:1, /* use this socket as backup */ -+ rcv_low_prio:1, /* Peer sent low-prio option to us */ -+ send_mp_prio:1, /* Trigger to send mp_prio on this socket */ -+ pre_established:1; /* State between sending 3rd ACK and -+ * receiving the fourth ack of new subflows. -+ */ -+ -+ /* isn: needed to translate abs to relative subflow seqnums */ -+ u32 snt_isn; -+ u32 rcv_isn; -+ u8 path_index; -+ u8 loc_id; -+ u8 rem_id; -+ u8 sk_err; -+ -+#define MPTCP_SCHED_SIZE 16 -+ u8 mptcp_sched[MPTCP_SCHED_SIZE] __aligned(8); -+ -+ int init_rcv_wnd; -+ u32 infinite_cutoff_seq; -+ struct delayed_work work; -+ u32 mptcp_loc_nonce; -+ struct tcp_sock *tp; -+ u32 last_end_data_seq; -+ -+ /* MP_JOIN subflow: timer for retransmitting the 3rd ack */ -+ struct timer_list mptcp_ack_timer; -+ -+ /* HMAC of the third ack */ -+ char sender_mac[SHA256_DIGEST_SIZE]; -+}; -+ -+struct mptcp_tw { -+ struct list_head list; -+ u64 loc_key; -+ u64 rcv_nxt; -+ struct mptcp_cb __rcu *mpcb; -+ u8 meta_tw:1, -+ in_list:1; -+}; -+ -+#define MPTCP_PM_NAME_MAX 16 -+struct mptcp_pm_ops { -+ struct list_head list; -+ -+ /* Signal the creation of a new MPTCP-session. */ -+ void (*new_session)(const struct sock *meta_sk); -+ void (*release_sock)(struct sock *meta_sk); -+ void (*fully_established)(struct sock *meta_sk); -+ void (*close_session)(struct sock *meta_sk); -+ void (*new_remote_address)(struct sock *meta_sk); -+ int (*get_local_id)(const struct sock *meta_sk, sa_family_t family, -+ union inet_addr *addr, bool *low_prio); -+ void (*addr_signal)(struct sock *sk, unsigned *size, -+ struct tcp_out_options *opts, struct sk_buff *skb); -+ void (*add_raddr)(struct mptcp_cb *mpcb, const union inet_addr *addr, -+ sa_family_t family, __be16 port, u8 id); -+ void (*rem_raddr)(struct mptcp_cb *mpcb, u8 rem_id); -+ void (*init_subsocket_v4)(struct sock *sk, struct in_addr addr); -+ void (*init_subsocket_v6)(struct sock *sk, struct in6_addr addr); -+ void (*established_subflow)(struct sock *sk); -+ void (*delete_subflow)(struct sock *sk); -+ void (*prio_changed)(struct sock *sk, int low_prio); -+ -+ char name[MPTCP_PM_NAME_MAX]; -+ struct module *owner; -+}; -+ -+struct mptcp_sched_ops { -+ struct list_head list; -+ -+ struct sock * (*get_subflow)(struct sock *meta_sk, -+ struct sk_buff *skb, -+ bool zero_wnd_test); -+ struct sk_buff * (*next_segment)(struct sock *meta_sk, -+ int *reinject, -+ struct sock **subsk, -+ unsigned int *limit); -+ void (*init)(struct sock *sk); -+ void (*release)(struct sock *sk); -+ -+ char name[MPTCP_SCHED_NAME_MAX]; -+ struct module *owner; -+}; -+ -+struct mptcp_cb { -+ /* list of sockets in this multipath connection */ -+ struct hlist_head conn_list; -+ /* list of sockets that need a call to release_cb */ -+ struct hlist_head callback_list; -+ -+ /* Lock used for protecting the different rcu-lists of mptcp_cb */ -+ spinlock_t mpcb_list_lock; -+ -+ /* High-order bits of 64-bit sequence numbers */ -+ u32 snd_high_order[2]; -+ u32 rcv_high_order[2]; -+ -+ u16 send_infinite_mapping:1, -+ send_mptcpv1_mpcapable:1, -+ rem_key_set:1, -+ in_time_wait:1, -+ list_rcvd:1, /* XXX TO REMOVE */ -+ addr_signal:1, /* Path-manager wants us to call addr_signal */ -+ dss_csum:1, -+ server_side:1, -+ infinite_mapping_rcv:1, -+ infinite_mapping_snd:1, -+ dfin_combined:1, /* Was the DFIN combined with subflow-fin? */ -+ passive_close:1, -+ snd_hiseq_index:1, /* Index in snd_high_order of snd_nxt */ -+ rcv_hiseq_index:1, /* Index in rcv_high_order of rcv_nxt */ -+ tcp_ca_explicit_set:1; /* was meta CC set by app? */ -+ -+#define MPTCP_SCHED_DATA_SIZE 8 -+ u8 mptcp_sched[MPTCP_SCHED_DATA_SIZE] __aligned(8); -+ const struct mptcp_sched_ops *sched_ops; -+ -+ struct sk_buff_head reinject_queue; -+ /* First cache-line boundary is here minus 8 bytes. But from the -+ * reinject-queue only the next and prev pointers are regularly -+ * accessed. Thus, the whole data-path is on a single cache-line. -+ */ -+ -+ u64 csum_cutoff_seq; -+ u64 infinite_rcv_seq; -+ -+ /***** Start of fields, used for connection closure */ -+ unsigned char mptw_state; -+ u8 dfin_path_index; -+ -+ struct list_head tw_list; -+ -+ /***** Start of fields, used for subflow establishment and closure */ -+ refcount_t mpcb_refcnt; -+ -+ /* Mutex needed, because otherwise mptcp_close will complain that the -+ * socket is owned by the user. -+ * E.g., mptcp_sub_close_wq is taking the meta-lock. -+ */ -+ struct mutex mpcb_mutex; -+ -+ /***** Start of fields, used for subflow establishment */ -+ struct sock *meta_sk; -+ -+ /* Master socket, also part of the conn_list, this -+ * socket is the one that the application sees. -+ */ -+ struct sock *master_sk; -+ -+ __u64 mptcp_loc_key; -+ __u64 mptcp_rem_key; -+ __u32 mptcp_loc_token; -+ __u32 mptcp_rem_token; -+ -+#define MPTCP_PM_SIZE 608 -+ u8 mptcp_pm[MPTCP_PM_SIZE] __aligned(8); -+ const struct mptcp_pm_ops *pm_ops; -+ -+ unsigned long path_index_bits; -+ -+ __u8 mptcp_ver; -+ -+ /* Original snd/rcvbuf of the initial subflow. -+ * Used for the new subflows on the server-side to allow correct -+ * autotuning -+ */ -+ int orig_sk_rcvbuf; -+ int orig_sk_sndbuf; -+ u32 orig_window_clamp; -+ -+ struct tcp_info *master_info; -+}; -+ -+#define MPTCP_VERSION_0 0 -+#define MPTCP_VERSION_1 1 -+ -+#define MPTCP_SUB_CAPABLE 0 -+#define MPTCP_SUB_LEN_CAPABLE_SYN 12 -+#define MPTCP_SUB_LEN_CAPABLE_SYN_ALIGN 12 -+#define MPTCP_SUB_LEN_CAPABLE_ACK 20 -+#define MPTCP_SUB_LEN_CAPABLE_ACK_ALIGN 20 -+ -+#define MPTCPV1_SUB_LEN_CAPABLE_SYN 4 -+#define MPTCPV1_SUB_LEN_CAPABLE_SYN_ALIGN 4 -+#define MPTCPV1_SUB_LEN_CAPABLE_SYNACK 12 -+#define MPTCPV1_SUB_LEN_CAPABLE_SYNACK_ALIGN 12 -+#define MPTCPV1_SUB_LEN_CAPABLE_ACK 20 -+#define MPTCPV1_SUB_LEN_CAPABLE_ACK_ALIGN 20 -+#define MPTCPV1_SUB_LEN_CAPABLE_DATA 22 -+#define MPTCPV1_SUB_LEN_CAPABLE_DATA_CSUM 22 -+#define MPTCPV1_SUB_LEN_CAPABLE_DATA_ALIGN 24 -+ -+#define MPTCP_SUB_JOIN 1 -+#define MPTCP_SUB_LEN_JOIN_SYN 12 -+#define MPTCP_SUB_LEN_JOIN_SYN_ALIGN 12 -+#define MPTCP_SUB_LEN_JOIN_SYNACK 16 -+#define MPTCP_SUB_LEN_JOIN_SYNACK_ALIGN 16 -+#define MPTCP_SUB_LEN_JOIN_ACK 24 -+#define MPTCP_SUB_LEN_JOIN_ACK_ALIGN 24 -+ -+#define MPTCP_SUB_DSS 2 -+#define MPTCP_SUB_LEN_DSS 4 -+#define MPTCP_SUB_LEN_DSS_ALIGN 4 -+ -+/* Lengths for seq and ack are the ones without the generic MPTCP-option header, -+ * as they are part of the DSS-option. -+ * To get the total length, just add the different options together. -+ */ -+#define MPTCP_SUB_LEN_SEQ 10 -+#define MPTCP_SUB_LEN_SEQ_CSUM 12 -+#define MPTCP_SUB_LEN_SEQ_ALIGN 12 -+ -+#define MPTCP_SUB_LEN_SEQ_64 14 -+#define MPTCP_SUB_LEN_SEQ_CSUM_64 16 -+#define MPTCP_SUB_LEN_SEQ_64_ALIGN 16 -+ -+#define MPTCP_SUB_LEN_ACK 4 -+#define MPTCP_SUB_LEN_ACK_ALIGN 4 -+ -+#define MPTCP_SUB_LEN_ACK_64 8 -+#define MPTCP_SUB_LEN_ACK_64_ALIGN 8 -+ -+/* This is the "default" option-length we will send out most often. -+ * MPTCP DSS-header -+ * 32-bit data sequence number -+ * 32-bit data ack -+ * -+ * It is necessary to calculate the effective MSS we will be using when -+ * sending data. -+ */ -+#define MPTCP_SUB_LEN_DSM_ALIGN (MPTCP_SUB_LEN_DSS_ALIGN + \ -+ MPTCP_SUB_LEN_SEQ_ALIGN + \ -+ MPTCP_SUB_LEN_ACK_ALIGN) -+ -+#define MPTCP_SUB_ADD_ADDR 3 -+#define MPTCP_SUB_LEN_ADD_ADDR4 8 -+#define MPTCP_SUB_LEN_ADD_ADDR4_VER1 16 -+#define MPTCP_SUB_LEN_ADD_ADDR6 20 -+#define MPTCP_SUB_LEN_ADD_ADDR6_VER1 28 -+#define MPTCP_SUB_LEN_ADD_ADDR4_ALIGN 8 -+#define MPTCP_SUB_LEN_ADD_ADDR4_ALIGN_VER1 16 -+#define MPTCP_SUB_LEN_ADD_ADDR6_ALIGN 20 -+#define MPTCP_SUB_LEN_ADD_ADDR6_ALIGN_VER1 28 -+ -+#define MPTCP_SUB_REMOVE_ADDR 4 -+#define MPTCP_SUB_LEN_REMOVE_ADDR 4 -+ -+#define MPTCP_SUB_PRIO 5 -+#define MPTCP_SUB_LEN_PRIO 3 -+#define MPTCP_SUB_LEN_PRIO_ADDR 4 -+#define MPTCP_SUB_LEN_PRIO_ALIGN 4 -+ -+#define MPTCP_SUB_FAIL 6 -+#define MPTCP_SUB_LEN_FAIL 12 -+#define MPTCP_SUB_LEN_FAIL_ALIGN 12 -+ -+#define MPTCP_SUB_FCLOSE 7 -+#define MPTCP_SUB_LEN_FCLOSE 12 -+#define MPTCP_SUB_LEN_FCLOSE_ALIGN 12 -+ -+ -+#define OPTION_MPTCP (1 << 5) -+ -+/* Max number of fastclose retransmissions */ -+#define MPTCP_FASTCLOSE_RETRIES 3 -+ -+#ifdef CONFIG_MPTCP -+ -+/* Used for checking if the mptcp initialization has been successful */ -+extern bool mptcp_init_failed; -+ -+/* MPTCP options */ -+#define OPTION_TYPE_SYN (1 << 0) -+#define OPTION_TYPE_SYNACK (1 << 1) -+#define OPTION_TYPE_ACK (1 << 2) -+#define OPTION_MP_CAPABLE (1 << 3) -+#define OPTION_DATA_ACK (1 << 4) -+#define OPTION_ADD_ADDR (1 << 5) -+#define OPTION_MP_JOIN (1 << 6) -+#define OPTION_MP_FAIL (1 << 7) -+#define OPTION_MP_FCLOSE (1 << 8) -+#define OPTION_REMOVE_ADDR (1 << 9) -+#define OPTION_MP_PRIO (1 << 10) -+ -+/* MPTCP flags: both TX and RX */ -+#define MPTCPHDR_SEQ 0x01 /* DSS.M option is present */ -+#define MPTCPHDR_FIN 0x02 /* DSS.F option is present */ -+#define MPTCPHDR_SEQ64_INDEX 0x04 /* index of seq in mpcb->snd_high_order */ -+#define MPTCPHDR_MPC_DATA 0x08 -+/* MPTCP flags: RX only */ -+#define MPTCPHDR_ACK 0x10 -+#define MPTCPHDR_SEQ64_SET 0x20 /* Did we received a 64-bit seq number? */ -+#define MPTCPHDR_SEQ64_OFO 0x40 /* Is it not in our circular array? */ -+#define MPTCPHDR_DSS_CSUM 0x80 -+/* MPTCP flags: TX only */ -+#define MPTCPHDR_INF 0x10 -+#define MPTCP_REINJECT 0x20 /* Did we reinject this segment? */ -+ -+struct mptcp_option { -+ __u8 kind; -+ __u8 len; -+#if defined(__LITTLE_ENDIAN_BITFIELD) -+ __u8 ver:4, -+ sub:4; -+#elif defined(__BIG_ENDIAN_BITFIELD) -+ __u8 sub:4, -+ ver:4; -+#else -+#error "Adjust your defines" -+#endif -+}; -+ -+struct mp_capable { -+ __u8 kind; -+ __u8 len; -+#if defined(__LITTLE_ENDIAN_BITFIELD) -+ __u8 ver:4, -+ sub:4; -+ __u8 h:1, -+ rsv:5, -+ b:1, -+ a:1; -+#elif defined(__BIG_ENDIAN_BITFIELD) -+ __u8 sub:4, -+ ver:4; -+ __u8 a:1, -+ b:1, -+ rsv:5, -+ h:1; -+#else -+#error "Adjust your defines" -+#endif -+ __u64 sender_key; -+ __u64 receiver_key; -+} __attribute__((__packed__)); -+ -+struct mp_join { -+ __u8 kind; -+ __u8 len; -+#if defined(__LITTLE_ENDIAN_BITFIELD) -+ __u8 b:1, -+ rsv:3, -+ sub:4; -+#elif defined(__BIG_ENDIAN_BITFIELD) -+ __u8 sub:4, -+ rsv:3, -+ b:1; -+#else -+#error "Adjust your defines" -+#endif -+ __u8 addr_id; -+ union { -+ struct { -+ u32 token; -+ u32 nonce; -+ } syn; -+ struct { -+ __u64 mac; -+ u32 nonce; -+ } synack; -+ struct { -+ __u8 mac[20]; -+ } ack; -+ } u; -+} __attribute__((__packed__)); -+ -+struct mp_dss { -+ __u8 kind; -+ __u8 len; -+#if defined(__LITTLE_ENDIAN_BITFIELD) -+ __u16 rsv1:4, -+ sub:4, -+ A:1, -+ a:1, -+ M:1, -+ m:1, -+ F:1, -+ rsv2:3; -+#elif defined(__BIG_ENDIAN_BITFIELD) -+ __u16 sub:4, -+ rsv1:4, -+ rsv2:3, -+ F:1, -+ m:1, -+ M:1, -+ a:1, -+ A:1; -+#else -+#error "Adjust your defines" -+#endif -+}; -+ -+struct mp_add_addr { -+ __u8 kind; -+ __u8 len; -+#if defined(__LITTLE_ENDIAN_BITFIELD) -+ union { -+ struct { -+ __u8 ipver:4, -+ sub:4; -+ } v0; -+ struct { -+ __u8 echo:1, -+ rsv:3, -+ sub:4; -+ } v1; -+ } u_bit; -+#elif defined(__BIG_ENDIAN_BITFIELD) -+ union { -+ struct { -+ __u8 sub:4, -+ ipver:4; -+ } v0; -+ struct { -+ __u8 sub:4, -+ rsv:3, -+ echo:1; -+ } v1; -+ } u_bit; -+#else -+#error "Adjust your defines" -+#endif -+ __u8 addr_id; -+ union { -+ struct { -+ struct in_addr addr; -+ __be16 port; -+ __u8 mac[8]; -+ } v4; -+ struct { -+ struct in6_addr addr; -+ __be16 port; -+ __u8 mac[8]; -+ } v6; -+ } u; -+} __attribute__((__packed__)); -+ -+struct mp_remove_addr { -+ __u8 kind; -+ __u8 len; -+#if defined(__LITTLE_ENDIAN_BITFIELD) -+ __u8 rsv:4, -+ sub:4; -+#elif defined(__BIG_ENDIAN_BITFIELD) -+ __u8 sub:4, -+ rsv:4; -+#else -+#error "Adjust your defines" -+#endif -+ /* list of addr_id */ -+ __u8 addrs_id; -+}; -+ -+struct mp_fail { -+ __u8 kind; -+ __u8 len; -+#if defined(__LITTLE_ENDIAN_BITFIELD) -+ __u16 rsv1:4, -+ sub:4, -+ rsv2:8; -+#elif defined(__BIG_ENDIAN_BITFIELD) -+ __u16 sub:4, -+ rsv1:4, -+ rsv2:8; -+#else -+#error "Adjust your defines" -+#endif -+ __be64 data_seq; -+} __attribute__((__packed__)); -+ -+struct mp_fclose { -+ __u8 kind; -+ __u8 len; -+#if defined(__LITTLE_ENDIAN_BITFIELD) -+ __u16 rsv1:4, -+ sub:4, -+ rsv2:8; -+#elif defined(__BIG_ENDIAN_BITFIELD) -+ __u16 sub:4, -+ rsv1:4, -+ rsv2:8; -+#else -+#error "Adjust your defines" -+#endif -+ __u64 key; -+} __attribute__((__packed__)); -+ -+struct mp_prio { -+ __u8 kind; -+ __u8 len; -+#if defined(__LITTLE_ENDIAN_BITFIELD) -+ __u8 b:1, -+ rsv:3, -+ sub:4; -+#elif defined(__BIG_ENDIAN_BITFIELD) -+ __u8 sub:4, -+ rsv:3, -+ b:1; -+#else -+#error "Adjust your defines" -+#endif -+ __u8 addr_id; -+} __attribute__((__packed__)); -+ -+struct mptcp_hashtable { -+ struct hlist_nulls_head *hashtable; -+ unsigned int mask; -+}; -+ -+static inline int mptcp_sub_len_dss(const struct mp_dss *m, const int csum) -+{ -+ return 4 + m->A * (4 + m->a * 4) + m->M * (10 + m->m * 4 + csum * 2); -+} -+ -+#define MPTCP_ENABLE 0x01 -+#define MPTCP_SOCKOPT 0x02 -+#define MPTCP_CLIENT_DISABLE 0x04 -+#define MPTCP_SERVER_DISABLE 0x08 -+ -+extern int sysctl_mptcp_enabled; -+extern int sysctl_mptcp_version; -+extern int sysctl_mptcp_checksum; -+extern int sysctl_mptcp_debug; -+extern int sysctl_mptcp_syn_retries; -+ -+extern struct workqueue_struct *mptcp_wq; -+ -+#define mptcp_debug(fmt, args...) \ -+ do { \ -+ if (unlikely(sysctl_mptcp_debug)) \ -+ pr_err(fmt, ##args); \ -+ } while (0) -+ -+static inline struct sock *mptcp_to_sock(const struct mptcp_tcp_sock *mptcp) -+{ -+ return (struct sock *)mptcp->tp; -+} -+ -+#define mptcp_for_each_sub(__mpcb, __mptcp) \ -+ hlist_for_each_entry_rcu(__mptcp, &((__mpcb)->conn_list), node) -+ -+/* Must be called with the appropriate lock held */ -+#define mptcp_for_each_sub_safe(__mpcb, __mptcp, __tmp) \ -+ hlist_for_each_entry_safe(__mptcp, __tmp, &((__mpcb)->conn_list), node) -+ -+/* Iterates over all bit set to 1 in a bitset */ -+#define mptcp_for_each_bit_set(b, i) \ -+ for (i = ffs(b) - 1; i >= 0; i = ffs(b >> (i + 1) << (i + 1)) - 1) -+ -+#define mptcp_for_each_bit_unset(b, i) \ -+ mptcp_for_each_bit_set(~b, i) -+ -+#define MPTCP_INC_STATS(net, field) SNMP_INC_STATS((net)->mptcp.mptcp_statistics, field) -+#define MPTCP_DEC_STATS(net, field) SNMP_DEC_STATS((net)->mptcp.mptcp_statistics, field) -+#define MPTCP_INC_STATS_BH(net, field) __SNMP_INC_STATS((net)->mptcp.mptcp_statistics, field) -+ -+enum -+{ -+ MPTCP_MIB_NUM = 0, -+ MPTCP_MIB_MPCAPABLEPASSIVE, /* Received SYN with MP_CAPABLE */ -+ MPTCP_MIB_MPCAPABLEACTIVE, /* Sent SYN with MP_CAPABLE */ -+ MPTCP_MIB_MPCAPABLEACTIVEACK, /* Received SYN/ACK with MP_CAPABLE */ -+ MPTCP_MIB_MPCAPABLEPASSIVEACK, /* Received third ACK with MP_CAPABLE */ -+ MPTCP_MIB_MPCAPABLEPASSIVEFALLBACK,/* Server-side fallback during 3-way handshake */ -+ MPTCP_MIB_MPCAPABLEACTIVEFALLBACK, /* Client-side fallback during 3-way handshake */ -+ MPTCP_MIB_MPCAPABLERETRANSFALLBACK,/* Client-side stopped sending MP_CAPABLE after too many SYN-retransmissions */ -+ MPTCP_MIB_CSUMENABLED, /* Created MPTCP-connection with DSS-checksum enabled */ -+ MPTCP_MIB_RETRANSSEGS, /* Segments retransmitted at the MPTCP-level */ -+ MPTCP_MIB_MPFAILRX, /* Received an MP_FAIL */ -+ MPTCP_MIB_CSUMFAIL, /* Received segment with invalid checksum */ -+ MPTCP_MIB_FASTCLOSERX, /* Recevied a FAST_CLOSE */ -+ MPTCP_MIB_FASTCLOSETX, /* Sent a FAST_CLOSE */ -+ MPTCP_MIB_FBACKSUB, /* Fallback upon ack without data-ack on new subflow */ -+ MPTCP_MIB_FBACKINIT, /* Fallback upon ack without data-ack on initial subflow */ -+ MPTCP_MIB_FBDATASUB, /* Fallback upon data without DSS at the beginning on new subflow */ -+ MPTCP_MIB_FBDATAINIT, /* Fallback upon data without DSS at the beginning on initial subflow */ -+ MPTCP_MIB_REMADDRSUB, /* Remove subflow due to REMOVE_ADDR */ -+ MPTCP_MIB_JOINNOTOKEN, /* Received MP_JOIN but the token was not found */ -+ MPTCP_MIB_JOINFALLBACK, /* Received MP_JOIN on session that has fallen back to reg. TCP */ -+ MPTCP_MIB_JOINSYNTX, /* Sent a SYN + MP_JOIN */ -+ MPTCP_MIB_JOINSYNRX, /* Received a SYN + MP_JOIN */ -+ MPTCP_MIB_JOINSYNACKRX, /* Received a SYN/ACK + MP_JOIN */ -+ MPTCP_MIB_JOINSYNACKMAC, /* HMAC was wrong on SYN/ACK + MP_JOIN */ -+ MPTCP_MIB_JOINACKRX, /* Received an ACK + MP_JOIN */ -+ MPTCP_MIB_JOINACKMAC, /* HMAC was wrong on ACK + MP_JOIN */ -+ MPTCP_MIB_JOINACKFAIL, /* Third ACK on new subflow did not contain an MP_JOIN */ -+ MPTCP_MIB_JOINACKRTO, /* Retransmission timer for third ACK + MP_JOIN timed out */ -+ MPTCP_MIB_JOINACKRXMIT, /* Retransmitted an ACK + MP_JOIN */ -+ MPTCP_MIB_NODSSWINDOW, /* Received too many packets without a DSS-option */ -+ MPTCP_MIB_DSSNOMATCH, /* Received a new mapping that did not match the previous one */ -+ MPTCP_MIB_INFINITEMAPRX, /* Received an infinite mapping */ -+ MPTCP_MIB_DSSTCPMISMATCH, /* DSS-mapping did not map with TCP's sequence numbers */ -+ MPTCP_MIB_DSSTRIMHEAD, /* Trimmed segment at the head (coalescing middlebox) */ -+ MPTCP_MIB_DSSSPLITTAIL, /* Trimmed segment at the tail (coalescing middlebox) */ -+ MPTCP_MIB_PURGEOLD, /* Removed old skb from the rcv-queue due to missing DSS-mapping */ -+ MPTCP_MIB_ADDADDRRX, /* Received an ADD_ADDR */ -+ MPTCP_MIB_ADDADDRTX, /* Sent an ADD_ADDR */ -+ MPTCP_MIB_REMADDRRX, /* Received a REMOVE_ADDR */ -+ MPTCP_MIB_REMADDRTX, /* Sent a REMOVE_ADDR */ -+ MPTCP_MIB_JOINALTERNATEPORT, /* Established a subflow on a different destination port-number */ -+ MPTCP_MIB_CURRESTAB, /* Current established MPTCP connections */ -+ __MPTCP_MIB_MAX -+}; -+ -+#define MPTCP_MIB_MAX __MPTCP_MIB_MAX -+struct mptcp_mib { -+ unsigned long mibs[MPTCP_MIB_MAX]; -+}; -+ -+extern struct lock_class_key meta_key; -+extern char *meta_key_name; -+extern struct lock_class_key meta_slock_key; -+extern char *meta_slock_key_name; -+ -+extern siphash_key_t mptcp_secret; -+ -+/* This is needed to ensure that two subsequent key/nonce-generation result in -+ * different keys/nonces if the IPs and ports are the same. -+ */ -+extern u32 mptcp_seed; -+ -+extern struct mptcp_hashtable mptcp_tk_htable; -+ -+/* Request-sockets can be hashed in the tk_htb for collision-detection or in -+ * the regular htb for join-connections. We need to define different NULLS -+ * values so that we can correctly detect a request-socket that has been -+ * recycled. See also c25eb3bfb9729. -+ */ -+#define MPTCP_REQSK_NULLS_BASE (1U << 29) -+ -+ -+void mptcp_data_ready(struct sock *sk); -+void mptcp_write_space(struct sock *sk); -+ -+void mptcp_add_meta_ofo_queue(const struct sock *meta_sk, struct sk_buff *skb, -+ struct sock *sk); -+void mptcp_cleanup_rbuf(struct sock *meta_sk, int copied); -+int mptcp_add_sock(struct sock *meta_sk, struct sock *sk, u8 loc_id, u8 rem_id, -+ gfp_t flags); -+void mptcp_del_sock(struct sock *sk); -+void mptcp_update_metasocket(const struct sock *meta_sk); -+void mptcp_reinject_data(struct sock *orig_sk, int clone_it); -+void mptcp_update_sndbuf(const struct tcp_sock *tp); -+void mptcp_send_fin(struct sock *meta_sk); -+void mptcp_send_active_reset(struct sock *meta_sk, gfp_t priority); -+bool mptcp_write_xmit(struct sock *sk, unsigned int mss_now, int nonagle, -+ int push_one, gfp_t gfp); -+void tcp_parse_mptcp_options(const struct sk_buff *skb, -+ struct mptcp_options_received *mopt); -+void mptcp_parse_options(const uint8_t *ptr, int opsize, -+ struct mptcp_options_received *mopt, -+ const struct sk_buff *skb, -+ struct tcp_sock *tp); -+void mptcp_syn_options(const struct sock *sk, struct tcp_out_options *opts, -+ unsigned *remaining); -+void mptcp_synack_options(struct request_sock *req, -+ struct tcp_out_options *opts, -+ unsigned *remaining); -+void mptcp_established_options(struct sock *sk, struct sk_buff *skb, -+ struct tcp_out_options *opts, unsigned *size); -+void mptcp_options_write(__be32 *ptr, struct tcp_sock *tp, -+ const struct tcp_out_options *opts, -+ struct sk_buff *skb); -+void mptcp_close(struct sock *meta_sk, long timeout); -+bool mptcp_doit(struct sock *sk); -+int mptcp_create_master_sk(struct sock *meta_sk, __u64 remote_key, -+ int rem_key_set, __u8 mptcp_ver, u32 window); -+int mptcp_check_req_fastopen(struct sock *child, struct request_sock *req); -+int mptcp_check_req_master(struct sock *sk, struct sock *child, -+ struct request_sock *req, const struct sk_buff *skb, -+ const struct mptcp_options_received *mopt, -+ int drop, u32 tsoff); -+struct sock *mptcp_check_req_child(struct sock *meta_sk, -+ struct sock *child, -+ struct request_sock *req, -+ struct sk_buff *skb, -+ const struct mptcp_options_received *mopt); -+u32 __mptcp_select_window(struct sock *sk); -+void mptcp_select_initial_window(const struct sock *sk, int __space, __u32 mss, -+ __u32 *rcv_wnd, __u32 *window_clamp, -+ int wscale_ok, __u8 *rcv_wscale, -+ __u32 init_rcv_wnd); -+unsigned int mptcp_current_mss(struct sock *meta_sk); -+void mptcp_hmac(u8 ver, const u8 *key_1, const u8 *key_2, u8 *hash_out, -+ int arg_num, ...); -+void mptcp_clean_rtx_infinite(const struct sk_buff *skb, struct sock *sk); -+void mptcp_fin(struct sock *meta_sk); -+void mptcp_meta_retransmit_timer(struct sock *meta_sk); -+void mptcp_sub_retransmit_timer(struct sock *sk); -+int mptcp_write_wakeup(struct sock *meta_sk, int mib); -+void mptcp_sub_close_wq(struct work_struct *work); -+void mptcp_sub_close(struct sock *sk, unsigned long delay); -+struct sock *mptcp_select_ack_sock(const struct sock *meta_sk); -+void mptcp_prepare_for_backlog(struct sock *sk, struct sk_buff *skb); -+void mptcp_initialize_recv_vars(struct tcp_sock *meta_tp, struct mptcp_cb *mpcb, -+ __u64 remote_key); -+int mptcp_backlog_rcv(struct sock *meta_sk, struct sk_buff *skb); -+void mptcp_ack_handler(struct timer_list *t); -+bool mptcp_check_rtt(const struct tcp_sock *tp, int time); -+int mptcp_check_snd_buf(const struct tcp_sock *tp); -+bool mptcp_handle_options(struct sock *sk, const struct tcphdr *th, -+ const struct sk_buff *skb); -+void __init mptcp_init(void); -+void mptcp_destroy_sock(struct sock *sk); -+int mptcp_rcv_synsent_state_process(struct sock *sk, struct sock **skptr, -+ const struct sk_buff *skb, -+ const struct mptcp_options_received *mopt); -+unsigned int mptcp_xmit_size_goal(const struct sock *meta_sk, u32 mss_now, -+ int large_allowed); -+int mptcp_init_tw_sock(struct sock *sk, struct tcp_timewait_sock *tw); -+void mptcp_twsk_destructor(struct tcp_timewait_sock *tw); -+void mptcp_time_wait(struct sock *sk, int state, int timeo); -+void mptcp_disconnect(struct sock *meta_sk); -+bool mptcp_should_expand_sndbuf(const struct sock *sk); -+int mptcp_retransmit_skb(struct sock *meta_sk, struct sk_buff *skb); -+void mptcp_tsq_flags(struct sock *sk); -+void mptcp_tsq_sub_deferred(struct sock *meta_sk); -+struct mp_join *mptcp_find_join(const struct sk_buff *skb); -+void mptcp_hash_remove_bh(struct tcp_sock *meta_tp); -+struct sock *mptcp_hash_find(const struct net *net, const u32 token); -+int mptcp_lookup_join(struct sk_buff *skb, struct inet_timewait_sock *tw); -+int mptcp_do_join_short(struct sk_buff *skb, -+ const struct mptcp_options_received *mopt, -+ struct net *net); -+void mptcp_reqsk_destructor(struct request_sock *req); -+void mptcp_connect_init(struct sock *sk); -+void mptcp_sub_force_close(struct sock *sk); -+int mptcp_sub_len_remove_addr_align(u16 bitfield); -+void mptcp_join_reqsk_init(const struct mptcp_cb *mpcb, -+ const struct request_sock *req, -+ struct sk_buff *skb); -+void mptcp_reqsk_init(struct request_sock *req, const struct sock *sk, -+ const struct sk_buff *skb, bool want_cookie); -+int mptcp_conn_request(struct sock *sk, struct sk_buff *skb); -+void mptcp_enable_sock(struct sock *sk); -+void mptcp_disable_sock(struct sock *sk); -+void mptcp_disable_static_key(void); -+void mptcp_cookies_reqsk_init(struct request_sock *req, -+ struct mptcp_options_received *mopt, -+ struct sk_buff *skb); -+void mptcp_mpcb_put(struct mptcp_cb *mpcb); -+int mptcp_finish_handshake(struct sock *child, struct sk_buff *skb); -+int mptcp_get_info(const struct sock *meta_sk, char __user *optval, int optlen); -+void mptcp_clear_sk(struct sock *sk, int size); -+ -+/* MPTCP-path-manager registration/initialization functions */ -+int mptcp_register_path_manager(struct mptcp_pm_ops *pm); -+void mptcp_unregister_path_manager(struct mptcp_pm_ops *pm); -+void mptcp_init_path_manager(struct mptcp_cb *mpcb); -+void mptcp_cleanup_path_manager(struct mptcp_cb *mpcb); -+void mptcp_fallback_default(struct mptcp_cb *mpcb); -+void mptcp_get_default_path_manager(char *name); -+int mptcp_set_scheduler(struct sock *sk, const char *name); -+int mptcp_set_path_manager(struct sock *sk, const char *name); -+int mptcp_set_default_path_manager(const char *name); -+extern struct mptcp_pm_ops mptcp_pm_default; -+ -+/* MPTCP-scheduler registration/initialization functions */ -+int mptcp_register_scheduler(struct mptcp_sched_ops *sched); -+void mptcp_unregister_scheduler(struct mptcp_sched_ops *sched); -+void mptcp_init_scheduler(struct mptcp_cb *mpcb); -+void mptcp_cleanup_scheduler(struct mptcp_cb *mpcb); -+void mptcp_get_default_scheduler(char *name); -+int mptcp_set_default_scheduler(const char *name); -+bool mptcp_is_available(struct sock *sk, const struct sk_buff *skb, -+ bool zero_wnd_test); -+bool mptcp_is_def_unavailable(struct sock *sk); -+bool subflow_is_active(const struct tcp_sock *tp); -+bool subflow_is_backup(const struct tcp_sock *tp); -+struct sock *get_available_subflow(struct sock *meta_sk, struct sk_buff *skb, -+ bool zero_wnd_test); -+struct sk_buff *mptcp_next_segment(struct sock *meta_sk, -+ int *reinject, -+ struct sock **subsk, -+ unsigned int *limit); -+extern struct mptcp_sched_ops mptcp_sched_default; -+ -+/* Initializes function-pointers and MPTCP-flags */ -+static inline void mptcp_init_tcp_sock(struct sock *sk) -+{ -+ if (!mptcp_init_failed && sysctl_mptcp_enabled == MPTCP_ENABLE) -+ mptcp_enable_sock(sk); -+} -+ -+static inline void mptcp_init_listen(struct sock *sk) -+{ -+ if (!mptcp_init_failed && -+ sk->sk_type == SOCK_STREAM && sk->sk_protocol == IPPROTO_TCP && -+ sysctl_mptcp_enabled & MPTCP_ENABLE && -+ !(sysctl_mptcp_enabled & MPTCP_SERVER_DISABLE)) -+ mptcp_enable_sock(sk); -+} -+ -+static inline void mptcp_init_connect(struct sock *sk) -+{ -+ if (!mptcp_init_failed && -+ sk->sk_type == SOCK_STREAM && sk->sk_protocol == IPPROTO_TCP && -+ sysctl_mptcp_enabled & MPTCP_ENABLE && -+ !(sysctl_mptcp_enabled & MPTCP_CLIENT_DISABLE)) -+ mptcp_enable_sock(sk); -+} -+ -+static inline int mptcp_pi_to_flag(int pi) -+{ -+ return 1 << (pi - 1); -+} -+ -+static inline -+struct mptcp_request_sock *mptcp_rsk(const struct request_sock *req) -+{ -+ return (struct mptcp_request_sock *)req; -+} -+ -+static inline -+struct request_sock *rev_mptcp_rsk(const struct mptcp_request_sock *req) -+{ -+ return (struct request_sock *)req; -+} -+ -+static inline bool mptcp_can_sendpage(struct sock *sk) -+{ -+ struct mptcp_tcp_sock *mptcp; -+ -+ if (tcp_sk(sk)->mpcb->dss_csum) -+ return false; -+ -+ mptcp_for_each_sub(tcp_sk(sk)->mpcb, mptcp) { -+ struct sock *sk_it = mptcp_to_sock(mptcp); -+ -+ if (!(sk_it->sk_route_caps & NETIF_F_SG)) -+ return false; -+ } -+ -+ return true; -+} -+ -+static inline void mptcp_push_pending_frames(struct sock *meta_sk) -+{ -+ /* We check packets out and send-head here. TCP only checks the -+ * send-head. But, MPTCP also checks packets_out, as this is an -+ * indication that we might want to do opportunistic reinjection. -+ */ -+ if (tcp_sk(meta_sk)->packets_out || tcp_send_head(meta_sk)) { -+ struct tcp_sock *tp = tcp_sk(meta_sk); -+ -+ /* We don't care about the MSS, because it will be set in -+ * mptcp_write_xmit. -+ */ -+ __tcp_push_pending_frames(meta_sk, 0, tp->nonagle); -+ } -+} -+ -+static inline void mptcp_send_reset(struct sock *sk) -+{ -+ if (tcp_need_reset(sk->sk_state)) -+ tcp_sk(sk)->ops->send_active_reset(sk, GFP_ATOMIC); -+ mptcp_sub_force_close(sk); -+} -+ -+static inline void mptcp_sub_force_close_all(struct mptcp_cb *mpcb, -+ struct sock *except) -+{ -+ struct mptcp_tcp_sock *mptcp; -+ struct hlist_node *tmp; -+ -+ mptcp_for_each_sub_safe(mpcb, mptcp, tmp) { -+ struct sock *sk_it = mptcp_to_sock(mptcp); -+ -+ if (sk_it != except) -+ mptcp_send_reset(sk_it); -+ } -+} -+ -+static inline bool mptcp_is_data_mpcapable(const struct sk_buff *skb) -+{ -+ return TCP_SKB_CB(skb)->mptcp_flags & MPTCPHDR_MPC_DATA; -+} -+ -+static inline bool mptcp_is_data_seq(const struct sk_buff *skb) -+{ -+ return TCP_SKB_CB(skb)->mptcp_flags & MPTCPHDR_SEQ; -+} -+ -+static inline bool mptcp_is_data_fin(const struct sk_buff *skb) -+{ -+ return TCP_SKB_CB(skb)->mptcp_flags & MPTCPHDR_FIN; -+} -+ -+/* Is it a data-fin while in infinite mapping mode? -+ * In infinite mode, a subflow-fin is in fact a data-fin. -+ */ -+static inline bool mptcp_is_data_fin2(const struct sk_buff *skb, -+ const struct tcp_sock *tp) -+{ -+ return mptcp_is_data_fin(skb) || -+ (tp->mpcb->infinite_mapping_rcv && -+ (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN)); -+} -+ -+static inline u8 mptcp_get_64_bit(u64 data_seq, struct mptcp_cb *mpcb) -+{ -+ u64 data_seq_high = (u32)(data_seq >> 32); -+ -+ if (mpcb->rcv_high_order[0] == data_seq_high) -+ return 0; -+ else if (mpcb->rcv_high_order[1] == data_seq_high) -+ return MPTCPHDR_SEQ64_INDEX; -+ else -+ return MPTCPHDR_SEQ64_OFO; -+} -+ -+/* Sets the data_seq and returns pointer to the in-skb field of the data_seq. -+ * If the packet has a 64-bit dseq, the pointer points to the last 32 bits. -+ */ -+static inline __u32 *mptcp_skb_set_data_seq(const struct sk_buff *skb, -+ u32 *data_seq, -+ struct mptcp_cb *mpcb) -+{ -+ __u32 *ptr = (__u32 *)(skb_transport_header(skb) + TCP_SKB_CB(skb)->dss_off); -+ -+ if (TCP_SKB_CB(skb)->mptcp_flags & MPTCPHDR_SEQ64_SET) { -+ u64 data_seq64 = get_unaligned_be64(ptr); -+ -+ if (mpcb) -+ TCP_SKB_CB(skb)->mptcp_flags |= mptcp_get_64_bit(data_seq64, mpcb); -+ -+ *data_seq = (u32)data_seq64; -+ ptr++; -+ } else { -+ *data_seq = get_unaligned_be32(ptr); -+ } -+ -+ return ptr; -+} -+ -+static inline struct sock *mptcp_meta_sk(const struct sock *sk) -+{ -+ return tcp_sk(sk)->meta_sk; -+} -+ -+static inline struct tcp_sock *mptcp_meta_tp(const struct tcp_sock *tp) -+{ -+ return tcp_sk(tp->meta_sk); -+} -+ -+static inline int is_meta_tp(const struct tcp_sock *tp) -+{ -+ return tp->mpcb && mptcp_meta_tp(tp) == tp; -+} -+ -+static inline int is_meta_sk(const struct sock *sk) -+{ -+ return sk->sk_state != TCP_NEW_SYN_RECV && -+ sk->sk_type == SOCK_STREAM && sk->sk_protocol == IPPROTO_TCP && -+ mptcp(tcp_sk(sk)) && mptcp_meta_sk(sk) == sk; -+} -+ -+static inline int is_master_tp(const struct tcp_sock *tp) -+{ -+ return !mptcp(tp) || (!tp->mptcp->slave_sk && !is_meta_tp(tp)); -+} -+ -+static inline void mptcp_init_mp_opt(struct mptcp_options_received *mopt) -+{ -+ mopt->saw_mpc = 0; -+ mopt->dss_csum = 0; -+ mopt->drop_me = 0; -+ -+ mopt->is_mp_join = 0; -+ mopt->join_ack = 0; -+ -+ mopt->saw_low_prio = 0; -+ mopt->low_prio = 0; -+ -+ mopt->saw_add_addr = 0; -+ mopt->more_add_addr = 0; -+ -+ mopt->saw_rem_addr = 0; -+ mopt->more_rem_addr = 0; -+ -+ mopt->mp_fail = 0; -+ mopt->mp_fclose = 0; -+} -+ -+static inline void mptcp_reset_mopt(struct tcp_sock *tp) -+{ -+ struct mptcp_options_received *mopt = &tp->mptcp->rx_opt; -+ -+ mopt->saw_low_prio = 0; -+ mopt->saw_add_addr = 0; -+ mopt->more_add_addr = 0; -+ mopt->saw_rem_addr = 0; -+ mopt->more_rem_addr = 0; -+ mopt->join_ack = 0; -+ mopt->mp_fail = 0; -+ mopt->mp_fclose = 0; -+} -+ -+static inline __be32 mptcp_get_highorder_sndbits(const struct sk_buff *skb, -+ const struct mptcp_cb *mpcb) -+{ -+ return htonl(mpcb->snd_high_order[(TCP_SKB_CB(skb)->mptcp_flags & -+ MPTCPHDR_SEQ64_INDEX) ? 1 : 0]); -+} -+ -+static inline u64 mptcp_get_data_seq_64(const struct mptcp_cb *mpcb, int index, -+ u32 data_seq_32) -+{ -+ return ((u64)mpcb->rcv_high_order[index] << 32) | data_seq_32; -+} -+ -+static inline u64 mptcp_get_rcv_nxt_64(const struct tcp_sock *meta_tp) -+{ -+ struct mptcp_cb *mpcb = meta_tp->mpcb; -+ return mptcp_get_data_seq_64(mpcb, mpcb->rcv_hiseq_index, -+ meta_tp->rcv_nxt); -+} -+ -+static inline void mptcp_check_sndseq_wrap(struct tcp_sock *meta_tp, int inc) -+{ -+ if (unlikely(meta_tp->snd_nxt > meta_tp->snd_nxt + inc)) { -+ struct mptcp_cb *mpcb = meta_tp->mpcb; -+ mpcb->snd_hiseq_index = mpcb->snd_hiseq_index ? 0 : 1; -+ mpcb->snd_high_order[mpcb->snd_hiseq_index] += 2; -+ } -+} -+ -+static inline void mptcp_check_rcvseq_wrap(struct tcp_sock *meta_tp, -+ u32 old_rcv_nxt) -+{ -+ if (unlikely(old_rcv_nxt > meta_tp->rcv_nxt)) { -+ struct mptcp_cb *mpcb = meta_tp->mpcb; -+ mpcb->rcv_high_order[mpcb->rcv_hiseq_index] += 2; -+ mpcb->rcv_hiseq_index = mpcb->rcv_hiseq_index ? 0 : 1; -+ } -+} -+ -+static inline int mptcp_sk_can_send(const struct sock *sk) -+{ -+ return tcp_passive_fastopen(sk) || -+ ((1 << sk->sk_state) & (TCPF_ESTABLISHED | TCPF_CLOSE_WAIT) && -+ !tcp_sk(sk)->mptcp->pre_established); -+} -+ -+static inline int mptcp_sk_can_recv(const struct sock *sk) -+{ -+ return (1 << sk->sk_state) & (TCPF_ESTABLISHED | TCPF_FIN_WAIT1 | TCPF_FIN_WAIT2); -+} -+ -+static inline int mptcp_sk_can_send_ack(const struct sock *sk) -+{ -+ return !((1 << sk->sk_state) & (TCPF_SYN_SENT | TCPF_SYN_RECV | -+ TCPF_CLOSE | TCPF_LISTEN)) && -+ !tcp_sk(sk)->mptcp->pre_established; -+} -+ -+static inline bool mptcp_can_sg(const struct sock *meta_sk) -+{ -+ struct mptcp_tcp_sock *mptcp; -+ -+ if (tcp_sk(meta_sk)->mpcb->dss_csum) -+ return false; -+ -+ mptcp_for_each_sub(tcp_sk(meta_sk)->mpcb, mptcp) { -+ struct sock *sk = mptcp_to_sock(mptcp); -+ -+ if (!mptcp_sk_can_send(sk)) -+ continue; -+ if (!(sk->sk_route_caps & NETIF_F_SG)) -+ return false; -+ } -+ return true; -+} -+ -+static inline void mptcp_set_rto(struct sock *sk) -+{ -+ struct inet_connection_sock *micsk = inet_csk(mptcp_meta_sk(sk)); -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct mptcp_tcp_sock *mptcp; -+ __u32 max_rto = 0; -+ -+ /* We are in recovery-phase on the MPTCP-level. Do not update the -+ * RTO, because this would kill exponential backoff. -+ */ -+ if (micsk->icsk_retransmits) -+ return; -+ -+ mptcp_for_each_sub(tp->mpcb, mptcp) { -+ struct sock *sk_it = mptcp_to_sock(mptcp); -+ -+ if ((mptcp_sk_can_send(sk_it) || sk_it->sk_state == TCP_SYN_RECV) && -+ inet_csk(sk_it)->icsk_retransmits == 0 && -+ inet_csk(sk_it)->icsk_backoff == 0 && -+ inet_csk(sk_it)->icsk_rto > max_rto) -+ max_rto = inet_csk(sk_it)->icsk_rto; -+ } -+ if (max_rto) { -+ micsk->icsk_rto = max_rto << 1; -+ -+ /* A successfull rto-measurement - reset backoff counter */ -+ micsk->icsk_backoff = 0; -+ } -+} -+ -+static inline void mptcp_sub_close_passive(struct sock *sk) -+{ -+ struct sock *meta_sk = mptcp_meta_sk(sk); -+ struct tcp_sock *tp = tcp_sk(sk), *meta_tp = tcp_sk(meta_sk); -+ -+ /* Only close, if the app did a send-shutdown (passive close), and we -+ * received the data-ack of the data-fin. -+ */ -+ if (tp->mpcb->passive_close && meta_tp->snd_una == meta_tp->write_seq) -+ mptcp_sub_close(sk, 0); -+} -+ -+static inline void mptcp_fallback_close(struct mptcp_cb *mpcb, -+ struct sock *except) -+{ -+ mptcp_sub_force_close_all(mpcb, except); -+ -+ if (mpcb->pm_ops->close_session) -+ mpcb->pm_ops->close_session(mptcp_meta_sk(except)); -+} -+ -+static inline bool mptcp_fallback_infinite(struct sock *sk, int flag) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct mptcp_cb *mpcb = tp->mpcb; -+ -+ /* If data has been acknowleged on the meta-level, fully_established -+ * will have been set before and thus we will not fall back to infinite -+ * mapping. -+ */ -+ if (likely(tp->mptcp->fully_established)) -+ return false; -+ -+ if (!(flag & MPTCP_FLAG_DATA_ACKED)) -+ return false; -+ -+ /* Don't fallback twice ;) */ -+ if (mpcb->infinite_mapping_snd) -+ return false; -+ -+ pr_debug("%s %#x will fallback - pi %d, src %pI4:%u dst %pI4:%u rcv_nxt %u from %pS\n", -+ __func__, mpcb->mptcp_loc_token, tp->mptcp->path_index, -+ &inet_sk(sk)->inet_saddr, ntohs(inet_sk(sk)->inet_sport), -+ &inet_sk(sk)->inet_daddr, ntohs(inet_sk(sk)->inet_dport), -+ tp->rcv_nxt, __builtin_return_address(0)); -+ if (!is_master_tp(tp)) { -+ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_FBACKSUB); -+ return true; -+ } -+ -+ mpcb->infinite_mapping_snd = 1; -+ mpcb->infinite_mapping_rcv = 1; -+ mpcb->infinite_rcv_seq = mptcp_get_rcv_nxt_64(mptcp_meta_tp(tp)); -+ tp->mptcp->fully_established = 1; -+ -+ mptcp_fallback_close(mpcb, sk); -+ -+ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_FBACKINIT); -+ -+ return false; -+} -+ -+static inline bool mptcp_v6_is_v4_mapped(const struct sock *sk) -+{ -+ return sk->sk_family == AF_INET6 && -+ ipv6_addr_type(&inet6_sk(sk)->saddr) == IPV6_ADDR_MAPPED; -+} -+ -+/* We are in or are becoming to be in infinite mapping mode */ -+static inline bool mptcp_in_infinite_mapping_weak(const struct mptcp_cb *mpcb) -+{ -+ return mpcb->infinite_mapping_rcv || -+ mpcb->infinite_mapping_snd || -+ mpcb->send_infinite_mapping; -+} -+ -+static inline bool mptcp_can_new_subflow(const struct sock *meta_sk) -+{ -+ /* Has been removed from the tk-table. Thus, no new subflows. -+ * -+ * Check for close-state is necessary, because we may have been closed -+ * without passing by mptcp_close(). -+ * -+ * When falling back, no new subflows are allowed either. -+ */ -+ return meta_sk->sk_state != TCP_CLOSE && -+ tcp_sk(meta_sk)->inside_tk_table && -+ !tcp_sk(meta_sk)->mpcb->infinite_mapping_rcv && -+ !tcp_sk(meta_sk)->mpcb->send_infinite_mapping; -+} -+ -+static inline int mptcp_subflow_count(const struct mptcp_cb *mpcb) -+{ -+ struct mptcp_tcp_sock *mptcp; -+ int i = 0; -+ -+ mptcp_for_each_sub(mpcb, mptcp) -+ i++; -+ -+ return i; -+} -+ -+/* TCP and MPTCP mpc flag-depending functions */ -+u16 mptcp_select_window(struct sock *sk); -+void mptcp_tcp_set_rto(struct sock *sk); -+ -+/* TCP and MPTCP flag-depending functions */ -+bool mptcp_prune_ofo_queue(struct sock *sk); -+ -+#else /* CONFIG_MPTCP */ -+#define mptcp_debug(fmt, args...) \ -+ do { \ -+ } while (0) -+ -+static inline struct sock *mptcp_to_sock(const struct mptcp_tcp_sock *mptcp) -+{ -+ return NULL; -+} -+ -+#define mptcp_for_each_sub(__mpcb, __mptcp) \ -+ if (0) -+ -+#define MPTCP_INC_STATS(net, field) \ -+ do { \ -+ } while(0) -+ -+static inline bool mptcp_is_data_fin(const struct sk_buff *skb) -+{ -+ return false; -+} -+static inline bool mptcp_is_data_seq(const struct sk_buff *skb) -+{ -+ return false; -+} -+static inline struct sock *mptcp_meta_sk(const struct sock *sk) -+{ -+ return NULL; -+} -+static inline struct tcp_sock *mptcp_meta_tp(const struct tcp_sock *tp) -+{ -+ return NULL; -+} -+static inline int is_meta_sk(const struct sock *sk) -+{ -+ return 0; -+} -+static inline int is_master_tp(const struct tcp_sock *tp) -+{ -+ return 0; -+} -+static inline void mptcp_del_sock(const struct sock *sk) {} -+static inline void mptcp_update_metasocket(const struct sock *meta_sk) {} -+static inline void mptcp_reinject_data(struct sock *orig_sk, int clone_it) {} -+static inline void mptcp_update_sndbuf(const struct tcp_sock *tp) {} -+static inline void mptcp_clean_rtx_infinite(const struct sk_buff *skb, -+ const struct sock *sk) {} -+static inline void mptcp_sub_close(struct sock *sk, unsigned long delay) {} -+static inline void mptcp_set_rto(const struct sock *sk) {} -+static inline void mptcp_send_fin(const struct sock *meta_sk) {} -+static inline void mptcp_parse_options(const uint8_t *ptr, const int opsize, -+ struct mptcp_options_received *mopt, -+ const struct sk_buff *skb, -+ const struct tcp_sock *tp) {} -+static inline void mptcp_syn_options(const struct sock *sk, -+ struct tcp_out_options *opts, -+ unsigned *remaining) {} -+static inline void mptcp_synack_options(struct request_sock *req, -+ struct tcp_out_options *opts, -+ unsigned *remaining) {} -+ -+static inline void mptcp_established_options(struct sock *sk, -+ struct sk_buff *skb, -+ struct tcp_out_options *opts, -+ unsigned *size) {} -+static inline void mptcp_options_write(__be32 *ptr, struct tcp_sock *tp, -+ const struct tcp_out_options *opts, -+ struct sk_buff *skb) {} -+static inline void mptcp_close(struct sock *meta_sk, long timeout) {} -+static inline bool mptcp_doit(struct sock *sk) -+{ -+ return false; -+} -+static inline int mptcp_check_req_fastopen(struct sock *child, -+ struct request_sock *req) -+{ -+ return 1; -+} -+static inline int mptcp_check_req_master(const struct sock *sk, -+ const struct sock *child, -+ const struct request_sock *req, -+ const struct sk_buff *skb, -+ const struct mptcp_options_received *mopt, -+ int drop, -+ u32 tsoff) -+{ -+ return 1; -+} -+static inline struct sock *mptcp_check_req_child(const struct sock *meta_sk, -+ const struct sock *child, -+ const struct request_sock *req, -+ struct sk_buff *skb, -+ const struct mptcp_options_received *mopt) -+{ -+ return NULL; -+} -+static inline unsigned int mptcp_current_mss(struct sock *meta_sk) -+{ -+ return 0; -+} -+static inline void mptcp_sub_close_passive(struct sock *sk) {} -+static inline bool mptcp_fallback_infinite(const struct sock *sk, int flag) -+{ -+ return false; -+} -+static inline void mptcp_init_mp_opt(const struct mptcp_options_received *mopt) {} -+static inline void mptcp_prepare_for_backlog(struct sock *sk, struct sk_buff *skb) {} -+static inline bool mptcp_check_rtt(const struct tcp_sock *tp, int time) -+{ -+ return false; -+} -+static inline int mptcp_check_snd_buf(const struct tcp_sock *tp) -+{ -+ return 0; -+} -+static inline void mptcp_push_pending_frames(struct sock *meta_sk) {} -+static inline void mptcp_send_reset(const struct sock *sk) {} -+static inline void mptcp_sub_force_close_all(struct mptcp_cb *mpcb, -+ struct sock *except) {} -+static inline bool mptcp_handle_options(struct sock *sk, -+ const struct tcphdr *th, -+ struct sk_buff *skb) -+{ -+ return false; -+} -+static inline void mptcp_reset_mopt(struct tcp_sock *tp) {} -+static inline void __init mptcp_init(void) {} -+static inline bool mptcp_can_sg(const struct sock *meta_sk) -+{ -+ return false; -+} -+static inline unsigned int mptcp_xmit_size_goal(const struct sock *meta_sk, -+ u32 mss_now, int large_allowed) -+{ -+ return 0; -+} -+static inline void mptcp_destroy_sock(struct sock *sk) {} -+static inline int mptcp_rcv_synsent_state_process(struct sock *sk, -+ struct sock **skptr, -+ struct sk_buff *skb, -+ const struct mptcp_options_received *mopt) -+{ -+ return 0; -+} -+static inline bool mptcp_can_sendpage(struct sock *sk) -+{ -+ return false; -+} -+static inline int mptcp_init_tw_sock(struct sock *sk, -+ struct tcp_timewait_sock *tw) -+{ -+ return 0; -+} -+static inline void mptcp_twsk_destructor(struct tcp_timewait_sock *tw) {} -+static inline void mptcp_disconnect(struct sock *meta_sk) {} -+static inline void mptcp_tsq_flags(struct sock *sk) {} -+static inline void mptcp_tsq_sub_deferred(struct sock *meta_sk) {} -+static inline void mptcp_hash_remove_bh(struct tcp_sock *meta_tp) {} -+static inline void mptcp_remove_shortcuts(const struct mptcp_cb *mpcb, -+ const struct sk_buff *skb) {} -+static inline void mptcp_init_tcp_sock(struct sock *sk) {} -+static inline void mptcp_init_listen(struct sock *sk) {} -+static inline void mptcp_init_connect(struct sock *sk) {} -+static inline void mptcp_disable_static_key(void) {} -+static inline void mptcp_cookies_reqsk_init(struct request_sock *req, -+ struct mptcp_options_received *mopt, -+ struct sk_buff *skb) {} -+static inline void mptcp_mpcb_put(struct mptcp_cb *mpcb) {} -+static inline void mptcp_fin(struct sock *meta_sk) {} -+static inline bool mptcp_in_infinite_mapping_weak(const struct mptcp_cb *mpcb) -+{ -+ return false; -+} -+static inline bool mptcp_can_new_subflow(const struct sock *meta_sk) -+{ -+ return false; -+} -+ -+#endif /* CONFIG_MPTCP */ -+ -+#endif /* _MPTCP_H */ -diff -aurN linux-5.4.64/include/net/mptcp_v4.h linux-5.4.64.mptcp/include/net/mptcp_v4.h ---- linux-5.4.64/include/net/mptcp_v4.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-5.4.64.mptcp/include/net/mptcp_v4.h 2020-09-10 19:25:10.499221003 +0200 -@@ -0,0 +1,76 @@ -+/* -+ * MPTCP implementation -+ * -+ * Initial Design & Implementation: -+ * Sébastien Barré -+ * -+ * Current Maintainer & Author: -+ * Christoph Paasch -+ * -+ * Additional authors: -+ * Jaakko Korkeaniemi -+ * Gregory Detal -+ * Fabien Duchêne -+ * Andreas Seelinger -+ * Lavkesh Lahngir -+ * Andreas Ripke -+ * Vlad Dogaru -+ * Octavian Purdila -+ * John Ronan -+ * Catalin Nicutar -+ * Brandon Heller -+ * -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version -+ * 2 of the License, or (at your option) any later version. -+ */ -+ -+#ifndef MPTCP_V4_H_ -+#define MPTCP_V4_H_ -+ -+ -+#include -+#include -+#include -+#include -+#include -+ -+extern struct request_sock_ops mptcp_request_sock_ops; -+extern const struct inet_connection_sock_af_ops mptcp_v4_specific; -+extern struct tcp_request_sock_ops mptcp_request_sock_ipv4_ops; -+extern struct tcp_request_sock_ops mptcp_join_request_sock_ipv4_ops; -+ -+#ifdef CONFIG_MPTCP -+ -+int mptcp_v4_do_rcv(struct sock *meta_sk, struct sk_buff *skb); -+struct sock *mptcp_v4_search_req(const __be16 rport, const __be32 raddr, -+ const __be32 laddr, const struct net *net); -+int __mptcp_init4_subsockets(struct sock *meta_sk, const struct mptcp_loc4 *loc, -+ __be16 sport, struct mptcp_rem4 *rem, -+ struct sock **subsk); -+int mptcp_pm_v4_init(void); -+void mptcp_pm_v4_undo(void); -+u32 mptcp_v4_get_nonce(__be32 saddr, __be32 daddr, __be16 sport, __be16 dport); -+u64 mptcp_v4_get_key(__be32 saddr, __be32 daddr, __be16 sport, __be16 dport, -+ u32 seed); -+ -+static inline int mptcp_init4_subsockets(struct sock *meta_sk, -+ const struct mptcp_loc4 *loc, -+ struct mptcp_rem4 *rem) -+{ -+ return __mptcp_init4_subsockets(meta_sk, loc, 0, rem, NULL); -+} -+ -+#else -+ -+static inline int mptcp_v4_do_rcv(const struct sock *meta_sk, -+ const struct sk_buff *skb) -+{ -+ return 0; -+} -+ -+#endif /* CONFIG_MPTCP */ -+ -+#endif /* MPTCP_V4_H_ */ -diff -aurN linux-5.4.64/include/net/mptcp_v6.h linux-5.4.64.mptcp/include/net/mptcp_v6.h ---- linux-5.4.64/include/net/mptcp_v6.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-5.4.64.mptcp/include/net/mptcp_v6.h 2020-09-10 19:25:10.499221003 +0200 -@@ -0,0 +1,77 @@ -+/* -+ * MPTCP implementation -+ * -+ * Initial Design & Implementation: -+ * Sébastien Barré -+ * -+ * Current Maintainer & Author: -+ * Jaakko Korkeaniemi -+ * -+ * Additional authors: -+ * Jaakko Korkeaniemi -+ * Gregory Detal -+ * Fabien Duchêne -+ * Andreas Seelinger -+ * Lavkesh Lahngir -+ * Andreas Ripke -+ * Vlad Dogaru -+ * Octavian Purdila -+ * John Ronan -+ * Catalin Nicutar -+ * Brandon Heller -+ * -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version -+ * 2 of the License, or (at your option) any later version. -+ */ -+ -+#ifndef _MPTCP_V6_H -+#define _MPTCP_V6_H -+ -+#include -+#include -+ -+#include -+ -+ -+#ifdef CONFIG_MPTCP -+extern const struct inet_connection_sock_af_ops mptcp_v6_mapped; -+extern const struct inet_connection_sock_af_ops mptcp_v6_specific; -+extern struct request_sock_ops mptcp6_request_sock_ops; -+extern struct tcp_request_sock_ops mptcp_request_sock_ipv6_ops; -+extern struct tcp_request_sock_ops mptcp_join_request_sock_ipv6_ops; -+ -+int mptcp_v6_do_rcv(struct sock *meta_sk, struct sk_buff *skb); -+struct sock *mptcp_v6_search_req(const __be16 rport, const struct in6_addr *raddr, -+ const struct in6_addr *laddr, const struct net *net); -+int __mptcp_init6_subsockets(struct sock *meta_sk, const struct mptcp_loc6 *loc, -+ __be16 sport, struct mptcp_rem6 *rem, -+ struct sock **subsk); -+int mptcp_pm_v6_init(void); -+void mptcp_pm_v6_undo(void); -+__u32 mptcp_v6_get_nonce(const __be32 *saddr, const __be32 *daddr, -+ __be16 sport, __be16 dport); -+u64 mptcp_v6_get_key(const __be32 *saddr, const __be32 *daddr, -+ __be16 sport, __be16 dport, u32 seed); -+ -+static inline int mptcp_init6_subsockets(struct sock *meta_sk, -+ const struct mptcp_loc6 *loc, -+ struct mptcp_rem6 *rem) -+{ -+ return __mptcp_init6_subsockets(meta_sk, loc, 0, rem, NULL); -+} -+ -+#else /* CONFIG_MPTCP */ -+ -+#define mptcp_v6_mapped ipv6_mapped -+ -+static inline int mptcp_v6_do_rcv(struct sock *meta_sk, struct sk_buff *skb) -+{ -+ return 0; -+} -+ -+#endif /* CONFIG_MPTCP */ -+ -+#endif /* _MPTCP_V6_H */ -diff -aurN linux-5.4.64/include/net/net_namespace.h linux-5.4.64.mptcp/include/net/net_namespace.h ---- linux-5.4.64/include/net/net_namespace.h 2020-09-09 19:12:37.000000000 +0200 -+++ linux-5.4.64.mptcp/include/net/net_namespace.h 2020-09-10 19:25:10.499221003 +0200 -@@ -19,6 +19,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -123,6 +124,9 @@ - #if IS_ENABLED(CONFIG_IPV6) - struct netns_ipv6 ipv6; - #endif -+#if IS_ENABLED(CONFIG_MPTCP) -+ struct netns_mptcp mptcp; -+#endif - #if IS_ENABLED(CONFIG_IEEE802154_6LOWPAN) - struct netns_ieee802154_lowpan ieee802154_lowpan; - #endif -diff -aurN linux-5.4.64/include/net/netns/mptcp.h linux-5.4.64.mptcp/include/net/netns/mptcp.h ---- linux-5.4.64/include/net/netns/mptcp.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-5.4.64.mptcp/include/net/netns/mptcp.h 2020-09-10 19:25:10.499221003 +0200 -@@ -0,0 +1,52 @@ -+/* -+ * MPTCP implementation - MPTCP namespace -+ * -+ * Initial Design & Implementation: -+ * Sébastien Barré -+ * -+ * Current Maintainer: -+ * Christoph Paasch -+ * -+ * Additional authors: -+ * Jaakko Korkeaniemi -+ * Gregory Detal -+ * Fabien Duchêne -+ * Andreas Seelinger -+ * Lavkesh Lahngir -+ * Andreas Ripke -+ * Vlad Dogaru -+ * Octavian Purdila -+ * John Ronan -+ * Catalin Nicutar -+ * Brandon Heller -+ * -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version -+ * 2 of the License, or (at your option) any later version. -+ */ -+ -+#ifndef __NETNS_MPTCP_H__ -+#define __NETNS_MPTCP_H__ -+ -+#include -+ -+enum { -+ MPTCP_PM_FULLMESH = 0, -+ MPTCP_PM_MAX -+}; -+ -+struct mptcp_mib; -+ -+struct netns_mptcp { -+ DEFINE_SNMP_STAT(struct mptcp_mib, mptcp_statistics); -+ -+#ifdef CONFIG_PROC_FS -+ struct proc_dir_entry *proc_net_mptcp; -+#endif -+ -+ void *path_managers[MPTCP_PM_MAX]; -+}; -+ -+#endif /* __NETNS_MPTCP_H__ */ -diff -aurN linux-5.4.64/include/net/snmp.h linux-5.4.64.mptcp/include/net/snmp.h ---- linux-5.4.64/include/net/snmp.h 2020-09-09 19:12:37.000000000 +0200 -+++ linux-5.4.64.mptcp/include/net/snmp.h 2020-09-10 19:25:10.499221003 +0200 -@@ -86,7 +86,6 @@ - atomic_long_t mibs[ICMP6MSG_MIB_MAX]; - }; - -- - /* TCP */ - #define TCP_MIB_MAX __TCP_MIB_MAX - struct tcp_mib { -diff -aurN linux-5.4.64/include/net/sock.h linux-5.4.64.mptcp/include/net/sock.h ---- linux-5.4.64/include/net/sock.h 2020-09-09 19:12:37.000000000 +0200 -+++ linux-5.4.64.mptcp/include/net/sock.h 2020-09-10 19:25:10.499221003 +0200 -@@ -819,6 +819,7 @@ - SOCK_TXTIME, - SOCK_XDP, /* XDP is attached */ - SOCK_TSTAMP_NEW, /* Indicates 64 bit timestamps always */ -+ SOCK_MPTCP, /* MPTCP set on this socket */ - }; - - #define SK_FLAGS_TIMESTAMP ((1UL << SOCK_TIMESTAMP) | (1UL << SOCK_TIMESTAMPING_RX_SOFTWARE)) -@@ -1131,6 +1132,7 @@ - void (*unhash)(struct sock *sk); - void (*rehash)(struct sock *sk); - int (*get_port)(struct sock *sk, unsigned short snum); -+ void (*clear_sk)(struct sock *sk, int size); - - /* Keeping track of sockets in use */ - #ifdef CONFIG_PROC_FS -diff -aurN linux-5.4.64/include/net/tcp.h linux-5.4.64.mptcp/include/net/tcp.h ---- linux-5.4.64/include/net/tcp.h 2020-09-09 19:12:37.000000000 +0200 -+++ linux-5.4.64.mptcp/include/net/tcp.h 2020-09-10 19:25:10.499221003 +0200 -@@ -182,6 +182,7 @@ - #define TCPOPT_SACK 5 /* SACK Block */ - #define TCPOPT_TIMESTAMP 8 /* Better RTT estimations/PAWS */ - #define TCPOPT_MD5SIG 19 /* MD5 Signature (RFC2385) */ -+#define TCPOPT_MPTCP 30 - #define TCPOPT_FASTOPEN 34 /* Fast open (RFC7413) */ - #define TCPOPT_EXP 254 /* Experimental */ - /* Magic number to be after the option value for sharing TCP -@@ -238,6 +239,31 @@ - */ - #define TFO_SERVER_WO_SOCKOPT1 0x400 - -+/* Flags from tcp_input.c for tcp_ack */ -+#define FLAG_DATA 0x01 /* Incoming frame contained data. */ -+#define FLAG_WIN_UPDATE 0x02 /* Incoming ACK was a window update. */ -+#define FLAG_DATA_ACKED 0x04 /* This ACK acknowledged new data. */ -+#define FLAG_RETRANS_DATA_ACKED 0x08 /* "" "" some of which was retransmitted. */ -+#define FLAG_SYN_ACKED 0x10 /* This ACK acknowledged SYN. */ -+#define FLAG_DATA_SACKED 0x20 /* New SACK. */ -+#define FLAG_ECE 0x40 /* ECE in this ACK */ -+#define FLAG_LOST_RETRANS 0x80 /* This ACK marks some retransmission lost */ -+#define FLAG_SLOWPATH 0x100 /* Do not skip RFC checks for window update.*/ -+#define FLAG_ORIG_SACK_ACKED 0x200 /* Never retransmitted data are (s)acked */ -+#define FLAG_SND_UNA_ADVANCED 0x400 /* Snd_una was changed (!= FLAG_DATA_ACKED) */ -+#define FLAG_DSACKING_ACK 0x800 /* SACK blocks contained D-SACK info */ -+#define FLAG_SET_XMIT_TIMER 0x1000 /* Set TLP or RTO timer */ -+#define FLAG_SACK_RENEGING 0x2000 /* snd_una advanced to a sacked seq */ -+#define FLAG_UPDATE_TS_RECENT 0x4000 /* tcp_replace_ts_recent() */ -+#define FLAG_NO_CHALLENGE_ACK 0x8000 /* do not call tcp_send_challenge_ack() */ -+#define FLAG_ACK_MAYBE_DELAYED 0x10000 /* Likely a delayed ACK */ -+ -+#define MPTCP_FLAG_DATA_ACKED 0x20000 -+ -+#define FLAG_ACKED (FLAG_DATA_ACKED|FLAG_SYN_ACKED) -+#define FLAG_NOT_DUP (FLAG_DATA|FLAG_WIN_UPDATE|FLAG_ACKED) -+#define FLAG_CA_ALERT (FLAG_DATA_SACKED|FLAG_ECE|FLAG_DSACKING_ACK) -+#define FLAG_FORWARD_PROGRESS (FLAG_ACKED|FLAG_DATA_SACKED) - - /* sysctl variables for tcp */ - extern int sysctl_tcp_max_orphans; -@@ -310,6 +336,97 @@ - #define TCP_DEC_STATS(net, field) SNMP_DEC_STATS((net)->mib.tcp_statistics, field) - #define TCP_ADD_STATS(net, field, val) SNMP_ADD_STATS((net)->mib.tcp_statistics, field, val) - -+/**** START - Exports needed for MPTCP ****/ -+extern const struct tcp_request_sock_ops tcp_request_sock_ipv4_ops; -+extern const struct tcp_request_sock_ops tcp_request_sock_ipv6_ops; -+ -+struct mptcp_options_received; -+ -+void tcp_cleanup_rbuf(struct sock *sk, int copied); -+int tcp_close_state(struct sock *sk); -+void tcp_minshall_update(struct tcp_sock *tp, unsigned int mss_now, -+ const struct sk_buff *skb); -+int tcp_xmit_probe_skb(struct sock *sk, int urgent, int mib); -+void tcp_event_new_data_sent(struct sock *sk, struct sk_buff *skb); -+int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it, -+ gfp_t gfp_mask); -+unsigned int tcp_mss_split_point(const struct sock *sk, -+ const struct sk_buff *skb, -+ unsigned int mss_now, -+ unsigned int max_segs, -+ int nonagle); -+bool tcp_nagle_test(const struct tcp_sock *tp, const struct sk_buff *skb, -+ unsigned int cur_mss, int nonagle); -+bool tcp_snd_wnd_test(const struct tcp_sock *tp, const struct sk_buff *skb, -+ unsigned int cur_mss); -+unsigned int tcp_cwnd_test(const struct tcp_sock *tp, const struct sk_buff *skb); -+int tcp_init_tso_segs(struct sk_buff *skb, unsigned int mss_now); -+int __pskb_trim_head(struct sk_buff *skb, int len); -+void tcp_queue_skb(struct sock *sk, struct sk_buff *skb); -+void tcp_init_nondata_skb(struct sk_buff *skb, u32 seq, u8 flags); -+void tcp_reset(struct sock *sk); -+bool tcp_may_update_window(const struct tcp_sock *tp, const u32 ack, -+ const u32 ack_seq, const u32 nwin); -+bool tcp_urg_mode(const struct tcp_sock *tp); -+void tcp_ack_probe(struct sock *sk); -+void tcp_rearm_rto(struct sock *sk); -+int tcp_write_timeout(struct sock *sk); -+bool retransmits_timed_out(struct sock *sk, -+ unsigned int boundary, -+ unsigned int timeout); -+void tcp_write_err(struct sock *sk); -+void tcp_adjust_pcount(struct sock *sk, const struct sk_buff *skb, int decr); -+void tcp_update_skb_after_send(struct sock *sk, struct sk_buff *skb, -+ u64 prior_wstamp); -+void tcp_set_skb_tso_segs(struct sk_buff *skb, unsigned int mss_now); -+ -+void tcp_v4_reqsk_send_ack(const struct sock *sk, struct sk_buff *skb, -+ struct request_sock *req); -+void tcp_v4_send_reset(const struct sock *sk, struct sk_buff *skb); -+struct sock *tcp_v4_cookie_check(struct sock *sk, struct sk_buff *skb); -+void tcp_v4_reqsk_destructor(struct request_sock *req); -+ -+void tcp_v6_reqsk_send_ack(const struct sock *sk, struct sk_buff *skb, -+ struct request_sock *req); -+void tcp_v6_send_reset(const struct sock *sk, struct sk_buff *skb); -+struct sock *tcp_v6_cookie_check(struct sock *sk, struct sk_buff *skb); -+int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb); -+int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len); -+void tcp_v6_destroy_sock(struct sock *sk); -+void inet6_sk_rx_dst_set(struct sock *sk, const struct sk_buff *skb); -+void tcp_v6_hash(struct sock *sk); -+struct sock *tcp_v6_hnd_req(struct sock *sk,struct sk_buff *skb); -+struct sock *tcp_v6_syn_recv_sock(const struct sock *sk, struct sk_buff *skb, -+ struct request_sock *req, -+ struct dst_entry *dst, -+ struct request_sock *req_unhash, -+ bool *own_req); -+void tcp_v6_reqsk_destructor(struct request_sock *req); -+ -+unsigned int tcp_xmit_size_goal(struct sock *sk, u32 mss_now, -+ int large_allowed); -+u32 tcp_tso_acked(struct sock *sk, struct sk_buff *skb); -+void tcp_ack_tstamp(struct sock *sk, struct sk_buff *skb, u32 prior_snd_una); -+ -+void skb_clone_fraglist(struct sk_buff *skb); -+ -+void inet_twsk_free(struct inet_timewait_sock *tw); -+int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb); -+/* These states need RST on ABORT according to RFC793 */ -+static inline bool tcp_need_reset(int state) -+{ -+ return (1 << state) & -+ (TCPF_ESTABLISHED | TCPF_CLOSE_WAIT | TCPF_FIN_WAIT1 | -+ TCPF_FIN_WAIT2 | TCPF_SYN_RECV); -+} -+ -+int __must_check tcp_queue_rcv(struct sock *sk, struct sk_buff *skb, -+ bool *fragstolen); -+void tcp_ofo_queue(struct sock *sk); -+void tcp_data_queue_ofo(struct sock *sk, struct sk_buff *skb); -+int linear_payload_sz(bool first_skb); -+/**** END - Exports needed for MPTCP ****/ -+ - void tcp_tasklet_init(void); - - int tcp_v4_err(struct sk_buff *skb, u32); -@@ -411,7 +528,9 @@ - #endif - void tcp_parse_options(const struct net *net, const struct sk_buff *skb, - struct tcp_options_received *opt_rx, -- int estab, struct tcp_fastopen_cookie *foc); -+ struct mptcp_options_received *mopt_rx, -+ int estab, struct tcp_fastopen_cookie *foc, -+ struct tcp_sock *tp); - const u8 *tcp_parse_md5sig_option(const struct tcphdr *th); - - /* -@@ -430,6 +549,7 @@ - - void tcp_v4_send_check(struct sock *sk, struct sk_buff *skb); - void tcp_v4_mtu_reduced(struct sock *sk); -+void tcp_v6_mtu_reduced(struct sock *sk); - void tcp_req_err(struct sock *sk, u32 seq, bool abort); - int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb); - struct sock *tcp_create_openreq_child(const struct sock *sk, -@@ -453,6 +573,7 @@ - struct request_sock *req, - struct tcp_fastopen_cookie *foc, - enum tcp_synack_type synack_type); -+void tcp_reset_vars(struct sock *sk); - int tcp_disconnect(struct sock *sk, int flags); - - void tcp_finish_connect(struct sock *sk, struct sk_buff *skb); -@@ -462,6 +583,7 @@ - /* From syncookies.c */ - struct sock *tcp_get_cookie_sock(struct sock *sk, struct sk_buff *skb, - struct request_sock *req, -+ const struct mptcp_options_received *mopt, - struct dst_entry *dst, u32 tsoff); - int __cookie_v4_check(const struct iphdr *iph, const struct tcphdr *th, - u32 cookie); -@@ -547,7 +669,8 @@ - - u32 __cookie_v4_init_sequence(const struct iphdr *iph, const struct tcphdr *th, - u16 *mssp); --__u32 cookie_v4_init_sequence(const struct sk_buff *skb, __u16 *mss); -+__u32 cookie_v4_init_sequence(struct request_sock *req, const struct sock *sk, -+ const struct sk_buff *skb, __u16 *mss); - u64 cookie_init_timestamp(struct request_sock *req); - bool cookie_timestamp_decode(const struct net *net, - struct tcp_options_received *opt); -@@ -561,7 +684,8 @@ - - u32 __cookie_v6_init_sequence(const struct ipv6hdr *iph, - const struct tcphdr *th, u16 *mssp); --__u32 cookie_v6_init_sequence(const struct sk_buff *skb, __u16 *mss); -+__u32 cookie_v6_init_sequence(struct request_sock *req, const struct sock *sk, -+ const struct sk_buff *skb, __u16 *mss); - #endif - /* tcp_output.c */ - -@@ -597,10 +721,16 @@ - void tcp_skb_collapse_tstamp(struct sk_buff *skb, - const struct sk_buff *next_skb); - -+u16 tcp_select_window(struct sock *sk); -+bool tcp_write_xmit(struct sock *sk, unsigned int mss_now, int nonagle, -+ int push_one, gfp_t gfp); -+ - /* tcp_input.c */ - void tcp_rearm_rto(struct sock *sk); - void tcp_synack_rtt_meas(struct sock *sk, struct request_sock *req); - void tcp_reset(struct sock *sk); -+void tcp_set_rto(struct sock *sk); -+bool tcp_should_expand_sndbuf(const struct sock *sk); - void tcp_skb_mark_lost_uncond_verify(struct tcp_sock *tp, struct sk_buff *skb); - void tcp_fin(struct sock *sk); - -@@ -644,7 +774,7 @@ - } - - /* tcp.c */ --void tcp_get_info(struct sock *, struct tcp_info *); -+void tcp_get_info(struct sock *, struct tcp_info *, bool no_lock); - - /* Read 'sendfile()'-style from a TCP socket */ - int tcp_read_sock(struct sock *sk, read_descriptor_t *desc, -@@ -828,6 +958,12 @@ - u16 tcp_gso_size; - }; - }; -+ -+#ifdef CONFIG_MPTCP -+ __u8 mptcp_flags; /* flags for the MPTCP layer */ -+ __u8 dss_off; /* Number of 4-byte words until -+ * seq-number */ -+#endif - __u8 tcp_flags; /* TCP header flags. (tcp[13]) */ - - __u8 sacked; /* State flags for SACK. */ -@@ -846,6 +982,14 @@ - has_rxtstamp:1, /* SKB has a RX timestamp */ - unused:5; - __u32 ack_seq; /* Sequence number ACK'd */ -+ -+#ifdef CONFIG_MPTCP -+ union { /* For MPTCP outgoing frames */ -+ __u32 path_mask; /* paths that tried to send this skb */ -+ __u32 dss[6]; /* DSS options */ -+ }; -+#endif -+ - union { - struct { - /* There is space for up to 24 bytes */ -@@ -1087,6 +1231,8 @@ - int tcp_set_allowed_congestion_control(char *allowed); - int tcp_set_congestion_control(struct sock *sk, const char *name, bool load, - bool reinit, bool cap_net_admin); -+int __tcp_set_congestion_control(struct sock *sk, const char *name, bool load, -+ bool reinit, bool cap_net_admin); - u32 tcp_slow_start(struct tcp_sock *tp, u32 acked); - void tcp_cong_avoid_ai(struct tcp_sock *tp, u32 w, u32 acked); - -@@ -1388,6 +1534,19 @@ - space - (space>>tcp_adv_win_scale); - } - -+#ifdef CONFIG_MPTCP -+extern struct static_key mptcp_static_key; -+static inline bool mptcp(const struct tcp_sock *tp) -+{ -+ return static_key_false(&mptcp_static_key) && tp->mpc; -+} -+#else -+static inline bool mptcp(const struct tcp_sock *tp) -+{ -+ return 0; -+} -+#endif -+ - /* Note: caller must be prepared to deal with negative returns */ - static inline int tcp_space(const struct sock *sk) - { -@@ -1975,6 +2134,30 @@ - #endif - }; - -+/* TCP/MPTCP-specific functions */ -+struct tcp_sock_ops { -+ u32 (*__select_window)(struct sock *sk); -+ u16 (*select_window)(struct sock *sk); -+ void (*select_initial_window)(const struct sock *sk, int __space, -+ __u32 mss, __u32 *rcv_wnd, -+ __u32 *window_clamp, int wscale_ok, -+ __u8 *rcv_wscale, __u32 init_rcv_wnd); -+ void (*init_buffer_space)(struct sock *sk); -+ void (*set_rto)(struct sock *sk); -+ bool (*should_expand_sndbuf)(const struct sock *sk); -+ void (*send_fin)(struct sock *sk); -+ bool (*write_xmit)(struct sock *sk, unsigned int mss_now, int nonagle, -+ int push_one, gfp_t gfp); -+ void (*send_active_reset)(struct sock *sk, gfp_t priority); -+ int (*write_wakeup)(struct sock *sk, int mib); -+ void (*retransmit_timer)(struct sock *sk); -+ void (*time_wait)(struct sock *sk, int state, int timeo); -+ void (*cleanup_rbuf)(struct sock *sk, int copied); -+ int (*set_cong_ctrl)(struct sock *sk, const char *name, bool load, -+ bool reinit, bool cap_net_admin); -+}; -+extern const struct tcp_sock_ops tcp_specific; -+ - struct tcp_request_sock_ops { - u16 mss_clamp; - #ifdef CONFIG_TCP_MD5SIG -@@ -1985,12 +2168,13 @@ - const struct sock *sk, - const struct sk_buff *skb); - #endif -- void (*init_req)(struct request_sock *req, -- const struct sock *sk_listener, -- struct sk_buff *skb); -+ int (*init_req)(struct request_sock *req, -+ const struct sock *sk_listener, -+ struct sk_buff *skb, -+ bool want_cookie); - #ifdef CONFIG_SYN_COOKIES -- __u32 (*cookie_init_seq)(const struct sk_buff *skb, -- __u16 *mss); -+ __u32 (*cookie_init_seq)(struct request_sock *req, const struct sock *sk, -+ const struct sk_buff *skb, __u16 *mss); - #endif - struct dst_entry *(*route_req)(const struct sock *sk, struct flowi *fl, - const struct request_sock *req); -@@ -2004,15 +2188,17 @@ - - #ifdef CONFIG_SYN_COOKIES - static inline __u32 cookie_init_sequence(const struct tcp_request_sock_ops *ops, -+ struct request_sock *req, - const struct sock *sk, struct sk_buff *skb, - __u16 *mss) - { - tcp_synq_overflow(sk); - __NET_INC_STATS(sock_net(sk), LINUX_MIB_SYNCOOKIESSENT); -- return ops->cookie_init_seq(skb, mss); -+ return ops->cookie_init_seq(req, sk, skb, mss); - } - #else - static inline __u32 cookie_init_sequence(const struct tcp_request_sock_ops *ops, -+ struct request_sock *req, - const struct sock *sk, struct sk_buff *skb, - __u16 *mss) - { -diff -aurN linux-5.4.64/include/net/tcp_states.h linux-5.4.64.mptcp/include/net/tcp_states.h ---- linux-5.4.64/include/net/tcp_states.h 2020-09-09 19:12:37.000000000 +0200 -+++ linux-5.4.64.mptcp/include/net/tcp_states.h 2020-09-10 19:25:10.499221003 +0200 -@@ -22,6 +22,7 @@ - TCP_LISTEN, - TCP_CLOSING, /* Now a valid state */ - TCP_NEW_SYN_RECV, -+ TCP_RST_WAIT, - - TCP_MAX_STATES /* Leave at the end! */ - }; -@@ -43,6 +44,7 @@ - TCPF_LISTEN = (1 << TCP_LISTEN), - TCPF_CLOSING = (1 << TCP_CLOSING), - TCPF_NEW_SYN_RECV = (1 << TCP_NEW_SYN_RECV), -+ TCPF_RST_WAIT = (1 << TCP_RST_WAIT), - }; - - #endif /* _LINUX_TCP_STATES_H */ -diff -aurN linux-5.4.64/include/net/transp_v6.h linux-5.4.64.mptcp/include/net/transp_v6.h ---- linux-5.4.64/include/net/transp_v6.h 2020-09-09 19:12:37.000000000 +0200 -+++ linux-5.4.64.mptcp/include/net/transp_v6.h 2020-09-10 19:25:10.499221003 +0200 -@@ -58,6 +58,8 @@ - - /* address family specific functions */ - extern const struct inet_connection_sock_af_ops ipv4_specific; -+extern const struct inet_connection_sock_af_ops ipv6_mapped; -+extern const struct inet_connection_sock_af_ops ipv6_specific; - - void inet6_destroy_sock(struct sock *sk); - -diff -aurN linux-5.4.64/include/trace/events/tcp.h linux-5.4.64.mptcp/include/trace/events/tcp.h ---- linux-5.4.64/include/trace/events/tcp.h 2020-09-09 19:12:37.000000000 +0200 -+++ linux-5.4.64.mptcp/include/trace/events/tcp.h 2020-09-10 19:25:10.499221003 +0200 -@@ -10,6 +10,7 @@ - #include - #include - #include -+#include - #include - - #define TP_STORE_V4MAPPED(__entry, saddr, daddr) \ -@@ -181,6 +182,13 @@ - TP_ARGS(sk) - ); - -+DEFINE_EVENT(tcp_event_sk_skb, mptcp_retransmit, -+ -+ TP_PROTO(const struct sock *sk, const struct sk_buff *skb), -+ -+ TP_ARGS(sk, skb) -+); -+ - TRACE_EVENT(tcp_retransmit_synack, - - TP_PROTO(const struct sock *sk, const struct request_sock *req), -@@ -248,6 +256,7 @@ - __field(__u32, srtt) - __field(__u32, rcv_wnd) - __field(__u64, sock_cookie) -+ __field(__u8, mptcp) - ), - - TP_fast_assign( -@@ -274,13 +283,15 @@ - __entry->ssthresh = tcp_current_ssthresh(sk); - __entry->srtt = tp->srtt_us >> 3; - __entry->sock_cookie = sock_gen_cookie(sk); -+ __entry->mptcp = mptcp(tp) ? tp->mptcp->path_index : 0; - ), - -- TP_printk("src=%pISpc dest=%pISpc mark=%#x data_len=%d snd_nxt=%#x snd_una=%#x snd_cwnd=%u ssthresh=%u snd_wnd=%u srtt=%u rcv_wnd=%u sock_cookie=%llx", -+ TP_printk("src=%pISpc dest=%pISpc mark=%#x data_len=%d snd_nxt=%#x snd_una=%#x snd_cwnd=%u ssthresh=%u snd_wnd=%u srtt=%u rcv_wnd=%u sock_cookie=%llx mptcp=%d", - __entry->saddr, __entry->daddr, __entry->mark, - __entry->data_len, __entry->snd_nxt, __entry->snd_una, - __entry->snd_cwnd, __entry->ssthresh, __entry->snd_wnd, -- __entry->srtt, __entry->rcv_wnd, __entry->sock_cookie) -+ __entry->srtt, __entry->rcv_wnd, __entry->sock_cookie, -+ __entry->mptcp) - ); - - #endif /* _TRACE_TCP_H */ -diff -aurN linux-5.4.64/include/uapi/linux/bpf.h linux-5.4.64.mptcp/include/uapi/linux/bpf.h ---- linux-5.4.64/include/uapi/linux/bpf.h 2020-09-09 19:12:37.000000000 +0200 -+++ linux-5.4.64.mptcp/include/uapi/linux/bpf.h 2020-09-10 19:25:10.499221003 +0200 -@@ -3438,6 +3438,7 @@ - BPF_TCP_LISTEN, - BPF_TCP_CLOSING, /* Now a valid state */ - BPF_TCP_NEW_SYN_RECV, -+ BPF_TCP_RST_WAIT, - - BPF_TCP_MAX_STATES /* Leave at the end! */ - }; -diff -aurN linux-5.4.64/include/uapi/linux/if.h linux-5.4.64.mptcp/include/uapi/linux/if.h ---- linux-5.4.64/include/uapi/linux/if.h 2020-09-09 19:12:37.000000000 +0200 -+++ linux-5.4.64.mptcp/include/uapi/linux/if.h 2020-09-10 19:25:10.499221003 +0200 -@@ -132,6 +132,9 @@ - #define IFF_ECHO IFF_ECHO - #endif /* __UAPI_DEF_IF_NET_DEVICE_FLAGS_LOWER_UP_DORMANT_ECHO */ - -+#define IFF_NOMULTIPATH 0x80000 /* Disable for MPTCP */ -+#define IFF_MPBACKUP 0x100000 /* Use as backup path for MPTCP */ -+ - #define IFF_VOLATILE (IFF_LOOPBACK|IFF_POINTOPOINT|IFF_BROADCAST|IFF_ECHO|\ - IFF_MASTER|IFF_SLAVE|IFF_RUNNING|IFF_LOWER_UP|IFF_DORMANT) - -diff -aurN linux-5.4.64/include/uapi/linux/in.h linux-5.4.64.mptcp/include/uapi/linux/in.h ---- linux-5.4.64/include/uapi/linux/in.h 2020-09-09 19:12:37.000000000 +0200 -+++ linux-5.4.64.mptcp/include/uapi/linux/in.h 2020-09-10 19:25:10.499221003 +0200 -@@ -76,6 +76,8 @@ - #define IPPROTO_MPLS IPPROTO_MPLS - IPPROTO_RAW = 255, /* Raw IP packets */ - #define IPPROTO_RAW IPPROTO_RAW -+ IPPROTO_MPTCP = 262, /* Multipath TCP connection */ -+#define IPPROTO_MPTCP IPPROTO_MPTCP - IPPROTO_MAX - }; - #endif -diff -aurN linux-5.4.64/include/uapi/linux/mptcp.h linux-5.4.64.mptcp/include/uapi/linux/mptcp.h ---- linux-5.4.64/include/uapi/linux/mptcp.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-5.4.64.mptcp/include/uapi/linux/mptcp.h 2020-09-10 19:25:10.499221003 +0200 -@@ -0,0 +1,149 @@ -+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ -+/* -+ * Netlink API for Multipath TCP -+ * -+ * Author: Gregory Detal -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version -+ * 2 of the License, or (at your option) any later version. -+ */ -+ -+#ifndef _LINUX_MPTCP_H -+#define _LINUX_MPTCP_H -+ -+#define MPTCP_GENL_NAME "mptcp" -+#define MPTCP_GENL_EV_GRP_NAME "mptcp_events" -+#define MPTCP_GENL_CMD_GRP_NAME "mptcp_commands" -+#define MPTCP_GENL_VER 0x1 -+ -+/* -+ * ATTR types defined for MPTCP -+ */ -+enum { -+ MPTCP_ATTR_UNSPEC = 0, -+ -+ MPTCP_ATTR_TOKEN, /* u32 */ -+ MPTCP_ATTR_FAMILY, /* u16 */ -+ MPTCP_ATTR_LOC_ID, /* u8 */ -+ MPTCP_ATTR_REM_ID, /* u8 */ -+ MPTCP_ATTR_SADDR4, /* u32 */ -+ MPTCP_ATTR_SADDR6, /* struct in6_addr */ -+ MPTCP_ATTR_DADDR4, /* u32 */ -+ MPTCP_ATTR_DADDR6, /* struct in6_addr */ -+ MPTCP_ATTR_SPORT, /* u16 */ -+ MPTCP_ATTR_DPORT, /* u16 */ -+ MPTCP_ATTR_BACKUP, /* u8 */ -+ MPTCP_ATTR_ERROR, /* u8 */ -+ MPTCP_ATTR_FLAGS, /* u16 */ -+ MPTCP_ATTR_TIMEOUT, /* u32 */ -+ MPTCP_ATTR_IF_IDX, /* s32 */ -+ -+ __MPTCP_ATTR_AFTER_LAST -+}; -+ -+#define MPTCP_ATTR_MAX (__MPTCP_ATTR_AFTER_LAST - 1) -+ -+/* -+ * Events generated by MPTCP: -+ * - MPTCP_EVENT_CREATED: token, family, saddr4 | saddr6, daddr4 | daddr6, -+ * sport, dport -+ * A new connection has been created. It is the good time to allocate -+ * memory and send ADD_ADDR if needed. Depending on the traffic-patterns -+ * it can take a long time until the MPTCP_EVENT_ESTABLISHED is sent. -+ * -+ * - MPTCP_EVENT_ESTABLISHED: token, family, saddr4 | saddr6, daddr4 | daddr6, -+ * sport, dport -+ * A connection is established (can start new subflows). -+ * -+ * - MPTCP_EVENT_CLOSED: token -+ * A connection has stopped. -+ * -+ * - MPTCP_EVENT_ANNOUNCED: token, rem_id, family, daddr4 | daddr6 [, dport] -+ * A new address has been announced by the peer. -+ * -+ * - MPTCP_EVENT_REMOVED: token, rem_id -+ * An address has been lost by the peer. -+ * -+ * - MPTCP_EVENT_SUB_ESTABLISHED: token, family, saddr4 | saddr6, -+ * daddr4 | daddr6, sport, dport, backup, -+ * if_idx [, error] -+ * A new subflow has been established. 'error' should not be set. -+ * -+ * - MPTCP_EVENT_SUB_CLOSED: token, family, saddr4 | saddr6, daddr4 | daddr6, -+ * sport, dport, backup, if_idx [, error] -+ * A subflow has been closed. An error (copy of sk_err) could be set if an -+ * error has been detected for this subflow. -+ * -+ * - MPTCP_EVENT_SUB_PRIORITY: token, family, saddr4 | saddr6, daddr4 | daddr6, -+ * sport, dport, backup, if_idx [, error] -+ * The priority of a subflow has changed. 'error' should not be set. -+ * -+ * Commands for MPTCP: -+ * - MPTCP_CMD_ANNOUNCE: token, loc_id, family, saddr4 | saddr6 [, sport] -+ * Announce a new address to the peer. -+ * -+ * - MPTCP_CMD_REMOVE: token, loc_id -+ * Announce that an address has been lost to the peer. -+ * -+ * - MPTCP_CMD_SUB_CREATE: token, family, loc_id, rem_id, [saddr4 | saddr6, -+ * daddr4 | daddr6, dport [, sport, backup, if_idx]] -+ * Create a new subflow. -+ * -+ * - MPTCP_CMD_SUB_DESTROY: token, family, saddr4 | saddr6, daddr4 | daddr6, -+ * sport, dport -+ * Close a subflow. -+ * -+ * - MPTCP_CMD_SUB_PRIORITY: token, family, saddr4 | saddr6, daddr4 | daddr6, -+ * sport, dport, backup -+ * Change the priority of a subflow. -+ * -+ * - MPTCP_CMD_SET_FILTER: flags -+ * Set the filter on events. Set MPTCPF_* flags to only receive specific -+ * events. Default is to receive all events. -+ * -+ * - MPTCP_CMD_EXIST: token -+ * Check if this token is linked to an existing socket. -+ */ -+enum { -+ MPTCP_CMD_UNSPEC = 0, -+ -+ MPTCP_EVENT_CREATED, -+ MPTCP_EVENT_ESTABLISHED, -+ MPTCP_EVENT_CLOSED, -+ -+ MPTCP_CMD_ANNOUNCE, -+ MPTCP_CMD_REMOVE, -+ MPTCP_EVENT_ANNOUNCED, -+ MPTCP_EVENT_REMOVED, -+ -+ MPTCP_CMD_SUB_CREATE, -+ MPTCP_CMD_SUB_DESTROY, -+ MPTCP_EVENT_SUB_ESTABLISHED, -+ MPTCP_EVENT_SUB_CLOSED, -+ -+ MPTCP_CMD_SUB_PRIORITY, -+ MPTCP_EVENT_SUB_PRIORITY, -+ -+ MPTCP_CMD_SET_FILTER, -+ -+ MPTCP_CMD_EXIST, -+ -+ __MPTCP_CMD_AFTER_LAST -+}; -+ -+#define MPTCP_CMD_MAX (__MPTCP_CMD_AFTER_LAST - 1) -+ -+enum { -+ MPTCPF_EVENT_CREATED = (1 << 1), -+ MPTCPF_EVENT_ESTABLISHED = (1 << 2), -+ MPTCPF_EVENT_CLOSED = (1 << 3), -+ MPTCPF_EVENT_ANNOUNCED = (1 << 4), -+ MPTCPF_EVENT_REMOVED = (1 << 5), -+ MPTCPF_EVENT_SUB_ESTABLISHED = (1 << 6), -+ MPTCPF_EVENT_SUB_CLOSED = (1 << 7), -+ MPTCPF_EVENT_SUB_PRIORITY = (1 << 8), -+}; -+ -+#endif /* _LINUX_MPTCP_H */ -diff -aurN linux-5.4.64/include/uapi/linux/tcp.h linux-5.4.64.mptcp/include/uapi/linux/tcp.h ---- linux-5.4.64/include/uapi/linux/tcp.h 2020-09-09 19:12:37.000000000 +0200 -+++ linux-5.4.64.mptcp/include/uapi/linux/tcp.h 2020-09-10 19:25:10.499221003 +0200 -@@ -18,9 +18,15 @@ - #ifndef _UAPI_LINUX_TCP_H - #define _UAPI_LINUX_TCP_H - --#include -+#ifndef __KERNEL__ -+#include -+#endif -+ - #include -+#include -+#include - #include -+#include - - struct tcphdr { - __be16 source; -@@ -134,6 +140,13 @@ - #define TCP_REPAIR_OFF 0 - #define TCP_REPAIR_OFF_NO_WP -1 /* Turn off without window probes */ - -+#define MPTCP_ENABLED 42 -+#define MPTCP_SCHEDULER 43 -+#define MPTCP_PATH_MANAGER 44 -+#define MPTCP_INFO 45 -+ -+#define MPTCP_INFO_FLAG_SAVE_MASTER 0x01 -+ - struct tcp_repair_opt { - __u32 opt_code; - __u32 opt_val; -@@ -305,6 +318,53 @@ - TCP_NLA_SRTT, /* smoothed RTT in usecs */ - }; - -+struct mptcp_meta_info { -+ __u8 mptcpi_state; -+ __u8 mptcpi_retransmits; -+ __u8 mptcpi_probes; -+ __u8 mptcpi_backoff; -+ -+ __u32 mptcpi_rto; -+ __u32 mptcpi_unacked; -+ -+ /* Times. */ -+ __u32 mptcpi_last_data_sent; -+ __u32 mptcpi_last_data_recv; -+ __u32 mptcpi_last_ack_recv; -+ -+ __u32 mptcpi_total_retrans; -+ -+ __u64 mptcpi_bytes_acked; /* RFC4898 tcpEStatsAppHCThruOctetsAcked */ -+ __u64 mptcpi_bytes_received; /* RFC4898 tcpEStatsAppHCThruOctetsReceived */ -+}; -+ -+struct mptcp_sub_info { -+ union { -+ struct sockaddr src; -+ struct sockaddr_in src_v4; -+ struct sockaddr_in6 src_v6; -+ }; -+ -+ union { -+ struct sockaddr dst; -+ struct sockaddr_in dst_v4; -+ struct sockaddr_in6 dst_v6; -+ }; -+}; -+ -+struct mptcp_info { -+ __u32 tcp_info_len; /* Length of each struct tcp_info in subflows pointer */ -+ __u32 sub_len; /* Total length of memory pointed to by subflows pointer */ -+ __u32 meta_len; /* Length of memory pointed to by meta_info */ -+ __u32 sub_info_len; /* Length of each struct mptcp_sub_info in subflow_info pointer */ -+ __u32 total_sub_info_len; /* Total length of memory pointed to by subflow_info */ -+ -+ struct mptcp_meta_info *meta_info; -+ struct tcp_info *initial; -+ struct tcp_info *subflows; /* Pointer to array of tcp_info structs */ -+ struct mptcp_sub_info *subflow_info; -+}; -+ - /* for TCP_MD5SIG socket option */ - #define TCP_MD5SIG_MAXKEYLEN 80 - -diff -aurN linux-5.4.64/net/core/dev.c linux-5.4.64.mptcp/net/core/dev.c ---- linux-5.4.64/net/core/dev.c 2020-09-09 19:12:37.000000000 +0200 -+++ linux-5.4.64.mptcp/net/core/dev.c 2020-09-10 19:25:10.503220935 +0200 -@@ -7851,7 +7851,7 @@ - - dev->flags = (flags & (IFF_DEBUG | IFF_NOTRAILERS | IFF_NOARP | - IFF_DYNAMIC | IFF_MULTICAST | IFF_PORTSEL | -- IFF_AUTOMEDIA)) | -+ IFF_AUTOMEDIA | IFF_NOMULTIPATH | IFF_MPBACKUP)) | - (dev->flags & (IFF_UP | IFF_VOLATILE | IFF_PROMISC | - IFF_ALLMULTI)); - -diff -aurN linux-5.4.64/net/core/net-traces.c linux-5.4.64.mptcp/net/core/net-traces.c ---- linux-5.4.64/net/core/net-traces.c 2020-09-09 19:12:37.000000000 +0200 -+++ linux-5.4.64.mptcp/net/core/net-traces.c 2020-09-10 19:25:10.503220935 +0200 -@@ -60,3 +60,5 @@ - EXPORT_TRACEPOINT_SYMBOL_GPL(napi_poll); - - EXPORT_TRACEPOINT_SYMBOL_GPL(tcp_send_reset); -+ -+EXPORT_TRACEPOINT_SYMBOL_GPL(mptcp_retransmit); -diff -aurN linux-5.4.64/net/core/skbuff.c linux-5.4.64.mptcp/net/core/skbuff.c ---- linux-5.4.64/net/core/skbuff.c 2020-09-09 19:12:37.000000000 +0200 -+++ linux-5.4.64.mptcp/net/core/skbuff.c 2020-09-10 19:25:10.503220935 +0200 -@@ -573,7 +573,7 @@ - skb_drop_list(&skb_shinfo(skb)->frag_list); - } - --static void skb_clone_fraglist(struct sk_buff *skb) -+void skb_clone_fraglist(struct sk_buff *skb) - { - struct sk_buff *list; - -diff -aurN linux-5.4.64/net/core/sock.c linux-5.4.64.mptcp/net/core/sock.c ---- linux-5.4.64/net/core/sock.c 2020-09-09 19:12:37.000000000 +0200 -+++ linux-5.4.64.mptcp/net/core/sock.c 2020-09-10 19:26:53.689504155 +0200 -@@ -135,6 +135,11 @@ - - #include - -+#ifdef CONFIG_MPTCP -+#include -+#include -+#endif -+ - #include - #include - -@@ -1551,6 +1556,23 @@ - */ - static inline void sock_lock_init(struct sock *sk) - { -+#ifdef CONFIG_MPTCP -+ /* Reclassify the lock-class for subflows */ -+ if (sk->sk_type == SOCK_STREAM && sk->sk_protocol == IPPROTO_TCP) -+ if (mptcp(tcp_sk(sk)) || tcp_sk(sk)->is_master_sk) { -+ sock_lock_init_class_and_name(sk, meta_slock_key_name, -+ &meta_slock_key, -+ meta_key_name, -+ &meta_key); -+ -+ /* We don't yet have the mptcp-point. -+ * Thus we still need inet_sock_destruct -+ */ -+ sk->sk_destruct = inet_sock_destruct; -+ return; -+ } -+#endif -+ - if (sk->sk_kern_sock) - sock_lock_init_class_and_name( - sk, -@@ -1599,8 +1621,12 @@ - sk = kmem_cache_alloc(slab, priority & ~__GFP_ZERO); - if (!sk) - return sk; -- if (want_init_on_alloc(priority)) -- sk_prot_clear_nulls(sk, prot->obj_size); -+ if (want_init_on_alloc(priority)) { -+ if (prot->clear_sk) -+ prot->clear_sk(sk, prot->obj_size); -+ else -+ sk_prot_clear_nulls(sk, prot->obj_size); -+ } - } else - sk = kmalloc(prot->obj_size, priority); - -@@ -1832,7 +1858,7 @@ - newsk->sk_userlocks = sk->sk_userlocks & ~SOCK_BINDPORT_LOCK; - atomic_set(&newsk->sk_zckey, 0); - -- sock_reset_flag(newsk, SOCK_DONE); -+ sock_reset_flag(newsk, SOCK_MPTCP); - - /* sk->sk_memcg will be populated at accept() time */ - newsk->sk_memcg = NULL; -diff -aurN linux-5.4.64/net/ipv4/af_inet.c linux-5.4.64.mptcp/net/ipv4/af_inet.c ---- linux-5.4.64/net/ipv4/af_inet.c 2020-09-09 19:12:37.000000000 +0200 -+++ linux-5.4.64.mptcp/net/ipv4/af_inet.c 2020-09-10 19:25:10.503220935 +0200 -@@ -100,6 +100,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -150,6 +151,9 @@ - return; - } - -+ if (sock_flag(sk, SOCK_MPTCP)) -+ mptcp_disable_static_key(); -+ - WARN_ON(atomic_read(&sk->sk_rmem_alloc)); - WARN_ON(refcount_read(&sk->sk_wmem_alloc)); - WARN_ON(sk->sk_wmem_queued); -@@ -227,6 +231,8 @@ - tcp_fastopen_init_key_once(sock_net(sk)); - } - -+ mptcp_init_listen(sk); -+ - err = inet_csk_listen_start(sk, backlog); - if (err) - goto out; -@@ -244,8 +250,7 @@ - * Create an inet socket. - */ - --static int inet_create(struct net *net, struct socket *sock, int protocol, -- int kern) -+int inet_create(struct net *net, struct socket *sock, int protocol, int kern) - { - struct sock *sk; - struct inet_protosw *answer; -@@ -739,6 +744,24 @@ - lock_sock(sk2); - - sock_rps_record_flow(sk2); -+ -+ if (sk2->sk_protocol == IPPROTO_TCP && mptcp(tcp_sk(sk2))) { -+ struct mptcp_tcp_sock *mptcp; -+ -+ mptcp_for_each_sub(tcp_sk(sk2)->mpcb, mptcp) { -+ sock_rps_record_flow(mptcp_to_sock(mptcp)); -+ } -+ -+ if (tcp_sk(sk2)->mpcb->master_sk) { -+ struct sock *sk_it = tcp_sk(sk2)->mpcb->master_sk; -+ -+ write_lock_bh(&sk_it->sk_callback_lock); -+ rcu_assign_pointer(sk_it->sk_wq, &newsock->wq); -+ sk_it->sk_socket = newsock; -+ write_unlock_bh(&sk_it->sk_callback_lock); -+ } -+ } -+ - WARN_ON(!((1 << sk2->sk_state) & - (TCPF_ESTABLISHED | TCPF_SYN_RECV | - TCPF_CLOSE_WAIT | TCPF_CLOSE))); -@@ -1974,6 +1997,9 @@ - - ip_init(); - -+ /* We must initialize MPTCP before TCP. */ -+ mptcp_init(); -+ - /* Setup TCP slab cache for open requests. */ - tcp_init(); - -diff -aurN linux-5.4.64/net/ipv4/inet_connection_sock.c linux-5.4.64.mptcp/net/ipv4/inet_connection_sock.c ---- linux-5.4.64/net/ipv4/inet_connection_sock.c 2020-09-09 19:12:37.000000000 +0200 -+++ linux-5.4.64.mptcp/net/ipv4/inet_connection_sock.c 2020-09-10 19:25:10.503220935 +0200 -@@ -19,6 +19,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -727,7 +728,10 @@ - int max_retries, thresh; - u8 defer_accept; - -- if (inet_sk_state_load(sk_listener) != TCP_LISTEN) -+ if (!is_meta_sk(sk_listener) && inet_sk_state_load(sk_listener) != TCP_LISTEN) -+ goto drop; -+ -+ if (is_meta_sk(sk_listener) && !mptcp_can_new_subflow(sk_listener)) - goto drop; - - max_retries = icsk->icsk_syn_retries ? : net->ipv4.sysctl_tcp_synack_retries; -@@ -816,7 +820,9 @@ - const struct request_sock *req, - const gfp_t priority) - { -- struct sock *newsk = sk_clone_lock(sk, priority); -+ struct sock *newsk; -+ -+ newsk = sk_clone_lock(sk, priority); - - if (newsk) { - struct inet_connection_sock *newicsk = inet_csk(newsk); -@@ -1015,7 +1021,14 @@ - */ - while ((req = reqsk_queue_remove(queue, sk)) != NULL) { - struct sock *child = req->sk; -+ bool mutex_taken = false; -+ struct mptcp_cb *mpcb = tcp_sk(child)->mpcb; - -+ if (is_meta_sk(child)) { -+ WARN_ON(refcount_inc_not_zero(&mpcb->mpcb_refcnt) == 0); -+ mutex_lock(&mpcb->mpcb_mutex); -+ mutex_taken = true; -+ } - local_bh_disable(); - bh_lock_sock(child); - WARN_ON(sock_owned_by_user(child)); -@@ -1025,6 +1038,10 @@ - reqsk_put(req); - bh_unlock_sock(child); - local_bh_enable(); -+ if (mutex_taken) { -+ mutex_unlock(&mpcb->mpcb_mutex); -+ mptcp_mpcb_put(mpcb); -+ } - sock_put(child); - - cond_resched(); -diff -aurN linux-5.4.64/net/ipv4/ip_sockglue.c linux-5.4.64.mptcp/net/ipv4/ip_sockglue.c ---- linux-5.4.64/net/ipv4/ip_sockglue.c 2020-09-09 19:12:37.000000000 +0200 -+++ linux-5.4.64.mptcp/net/ipv4/ip_sockglue.c 2020-09-10 19:25:10.503220935 +0200 -@@ -44,6 +44,8 @@ - #endif - #include - -+#include -+ - #include - #include - -@@ -657,7 +659,7 @@ - break; - old = rcu_dereference_protected(inet->inet_opt, - lockdep_sock_is_held(sk)); -- if (inet->is_icsk) { -+ if (inet->is_icsk && !is_meta_sk(sk)) { - struct inet_connection_sock *icsk = inet_csk(sk); - #if IS_ENABLED(CONFIG_IPV6) - if (sk->sk_family == PF_INET || -@@ -751,6 +753,20 @@ - inet->tos = val; - sk->sk_priority = rt_tos2priority(val); - sk_dst_reset(sk); -+ /* Update TOS on mptcp subflow */ -+ if (is_meta_sk(sk)) { -+ struct mptcp_tcp_sock *mptcp; -+ -+ mptcp_for_each_sub(tcp_sk(sk)->mpcb, mptcp) { -+ struct sock *sk_it = mptcp_to_sock(mptcp); -+ -+ if (inet_sk(sk_it)->tos != inet_sk(sk)->tos) { -+ inet_sk(sk_it)->tos = inet_sk(sk)->tos; -+ sk_it->sk_priority = sk->sk_priority; -+ sk_dst_reset(sk_it); -+ } -+ } -+ } - } - break; - case IP_TTL: -diff -aurN linux-5.4.64/net/ipv4/Kconfig linux-5.4.64.mptcp/net/ipv4/Kconfig ---- linux-5.4.64/net/ipv4/Kconfig 2020-09-09 19:12:37.000000000 +0200 -+++ linux-5.4.64.mptcp/net/ipv4/Kconfig 2020-09-10 19:25:10.503220935 +0200 -@@ -655,6 +655,51 @@ - bufferbloat, policers, or AQM schemes that do not provide a delay - signal. It requires the fq ("Fair Queue") pacing packet scheduler. - -+config TCP_CONG_LIA -+ tristate "MPTCP Linked Increase" -+ depends on MPTCP -+ default n -+ ---help--- -+ MultiPath TCP Linked Increase Congestion Control -+ To enable it, just put 'lia' in tcp_congestion_control -+ -+config TCP_CONG_OLIA -+ tristate "MPTCP Opportunistic Linked Increase" -+ depends on MPTCP -+ default n -+ ---help--- -+ MultiPath TCP Opportunistic Linked Increase Congestion Control -+ To enable it, just put 'olia' in tcp_congestion_control -+ -+config TCP_CONG_WVEGAS -+ tristate "MPTCP WVEGAS CONGESTION CONTROL" -+ depends on MPTCP -+ default n -+ ---help--- -+ wVegas congestion control for MPTCP -+ To enable it, just put 'wvegas' in tcp_congestion_control -+ -+config TCP_CONG_BALIA -+ tristate "MPTCP BALIA CONGESTION CONTROL" -+ depends on MPTCP -+ default n -+ ---help--- -+ Multipath TCP Balanced Linked Adaptation Congestion Control -+ To enable it, just put 'balia' in tcp_congestion_control -+ -+config TCP_CONG_MCTCPDESYNC -+ tristate "DESYNCHRONIZED MCTCP CONGESTION CONTROL (EXPERIMENTAL)" -+ depends on MPTCP -+ default n -+ ---help--- -+ Desynchronized MultiChannel TCP Congestion Control. This is experimental -+ code that only supports single path and must have set mptcp_ndiffports -+ larger than one. -+ To enable it, just put 'mctcpdesync' in tcp_congestion_control -+ For further details see: -+ http://ieeexplore.ieee.org/abstract/document/6911722/ -+ https://doi.org/10.1016/j.comcom.2015.07.010 -+ - choice - prompt "Default TCP congestion control" - default DEFAULT_CUBIC -@@ -692,6 +737,21 @@ - config DEFAULT_BBR - bool "BBR" if TCP_CONG_BBR=y - -+ config DEFAULT_LIA -+ bool "Lia" if TCP_CONG_LIA=y -+ -+ config DEFAULT_OLIA -+ bool "Olia" if TCP_CONG_OLIA=y -+ -+ config DEFAULT_WVEGAS -+ bool "Wvegas" if TCP_CONG_WVEGAS=y -+ -+ config DEFAULT_BALIA -+ bool "Balia" if TCP_CONG_BALIA=y -+ -+ config DEFAULT_MCTCPDESYNC -+ bool "Mctcpdesync (EXPERIMENTAL)" if TCP_CONG_MCTCPDESYNC=y -+ - config DEFAULT_RENO - bool "Reno" - endchoice -@@ -712,6 +772,10 @@ - default "vegas" if DEFAULT_VEGAS - default "westwood" if DEFAULT_WESTWOOD - default "veno" if DEFAULT_VENO -+ default "lia" if DEFAULT_LIA -+ default "olia" if DEFAULT_OLIA -+ default "wvegas" if DEFAULT_WVEGAS -+ default "balia" if DEFAULT_BALIA - default "reno" if DEFAULT_RENO - default "dctcp" if DEFAULT_DCTCP - default "cdg" if DEFAULT_CDG -diff -aurN linux-5.4.64/net/ipv4/syncookies.c linux-5.4.64.mptcp/net/ipv4/syncookies.c ---- linux-5.4.64/net/ipv4/syncookies.c 2020-09-09 19:12:37.000000000 +0200 -+++ linux-5.4.64.mptcp/net/ipv4/syncookies.c 2020-09-10 19:25:10.503220935 +0200 -@@ -12,6 +12,8 @@ - #include - #include - #include -+#include -+#include - #include - #include - #include -@@ -175,7 +177,8 @@ - } - EXPORT_SYMBOL_GPL(__cookie_v4_init_sequence); - --__u32 cookie_v4_init_sequence(const struct sk_buff *skb, __u16 *mssp) -+__u32 cookie_v4_init_sequence(struct request_sock *req, const struct sock *sk, -+ const struct sk_buff *skb, __u16 *mssp) - { - const struct iphdr *iph = ip_hdr(skb); - const struct tcphdr *th = tcp_hdr(skb); -@@ -200,14 +203,33 @@ - - struct sock *tcp_get_cookie_sock(struct sock *sk, struct sk_buff *skb, - struct request_sock *req, -+ const struct mptcp_options_received *mopt, - struct dst_entry *dst, u32 tsoff) - { - struct inet_connection_sock *icsk = inet_csk(sk); - struct sock *child; - bool own_req; -+#ifdef CONFIG_MPTCP -+ int ret; -+#endif - - child = icsk->icsk_af_ops->syn_recv_sock(sk, skb, req, dst, - NULL, &own_req); -+ -+#ifdef CONFIG_MPTCP -+ if (!child) -+ goto listen_overflow; -+ -+ ret = mptcp_check_req_master(sk, child, req, skb, mopt, 0, tsoff); -+ if (ret < 0) -+ return NULL; -+ -+ if (!ret) -+ return tcp_sk(child)->mpcb->master_sk; -+ -+listen_overflow: -+#endif -+ - if (child) { - refcount_set(&req->rsk_refcnt, 1); - tcp_sk(child)->tsoffset = tsoff; -@@ -284,6 +306,7 @@ - { - struct ip_options *opt = &TCP_SKB_CB(skb)->header.h4.opt; - struct tcp_options_received tcp_opt; -+ struct mptcp_options_received mopt; - struct inet_request_sock *ireq; - struct tcp_request_sock *treq; - struct tcp_sock *tp = tcp_sk(sk); -@@ -313,7 +336,8 @@ - - /* check for timestamp cookie support */ - memset(&tcp_opt, 0, sizeof(tcp_opt)); -- tcp_parse_options(sock_net(sk), skb, &tcp_opt, 0, NULL); -+ mptcp_init_mp_opt(&mopt); -+ tcp_parse_options(sock_net(sk), skb, &tcp_opt, &mopt, 0, NULL, NULL); - - if (tcp_opt.saw_tstamp && tcp_opt.rcv_tsecr) { - tsoff = secure_tcp_ts_off(sock_net(sk), -@@ -326,7 +350,12 @@ - goto out; - - ret = NULL; -- req = inet_reqsk_alloc(&tcp_request_sock_ops, sk, false); /* for safety */ -+#ifdef CONFIG_MPTCP -+ if (mopt.saw_mpc) -+ req = inet_reqsk_alloc(&mptcp_request_sock_ops, sk, false); /* for safety */ -+ else -+#endif -+ req = inet_reqsk_alloc(&tcp_request_sock_ops, sk, false); /* for safety */ - if (!req) - goto out; - -@@ -346,6 +375,8 @@ - ireq->sack_ok = tcp_opt.sack_ok; - ireq->wscale_ok = tcp_opt.wscale_ok; - ireq->tstamp_ok = tcp_opt.saw_tstamp; -+ ireq->mptcp_rqsk = 0; -+ ireq->saw_mpc = 0; - req->ts_recent = tcp_opt.saw_tstamp ? tcp_opt.rcv_tsval : 0; - treq->snt_synack = 0; - treq->tfo_listener = false; -@@ -354,6 +385,9 @@ - - ireq->ir_iif = inet_request_bound_dev_if(sk, skb); - -+ if (mopt.saw_mpc) -+ mptcp_cookies_reqsk_init(req, &mopt, skb); -+ - /* We throwed the options of the initial SYN away, so we hope - * the ACK carries the same options again (see RFC1122 4.2.3.8) - */ -@@ -387,15 +421,15 @@ - /* Try to redo what tcp_v4_send_synack did. */ - req->rsk_window_clamp = tp->window_clamp ? :dst_metric(&rt->dst, RTAX_WINDOW); - -- tcp_select_initial_window(sk, tcp_full_space(sk), req->mss, -- &req->rsk_rcv_wnd, &req->rsk_window_clamp, -- ireq->wscale_ok, &rcv_wscale, -- dst_metric(&rt->dst, RTAX_INITRWND)); -+ tp->ops->select_initial_window(sk, tcp_full_space(sk), req->mss, -+ &req->rsk_rcv_wnd, &req->rsk_window_clamp, -+ ireq->wscale_ok, &rcv_wscale, -+ dst_metric(&rt->dst, RTAX_INITRWND)); - - ireq->rcv_wscale = rcv_wscale; - ireq->ecn_ok = cookie_ecn_ok(&tcp_opt, sock_net(sk), &rt->dst); - -- ret = tcp_get_cookie_sock(sk, skb, req, &rt->dst, tsoff); -+ ret = tcp_get_cookie_sock(sk, skb, req, &mopt, &rt->dst, tsoff); - /* ip_queue_xmit() depends on our flow being setup - * Normal sockets get it right from inet_csk_route_child_sock() - */ -diff -aurN linux-5.4.64/net/ipv4/tcp.c linux-5.4.64.mptcp/net/ipv4/tcp.c ---- linux-5.4.64/net/ipv4/tcp.c 2020-09-09 19:12:37.000000000 +0200 -+++ linux-5.4.64.mptcp/net/ipv4/tcp.c 2020-09-10 19:44:12.204220735 +0200 -@@ -270,6 +270,7 @@ - - #include - #include -+#include - #include - #include - #include -@@ -400,6 +401,23 @@ - return rate64; - } - -+const struct tcp_sock_ops tcp_specific = { -+ .__select_window = __tcp_select_window, -+ .select_window = tcp_select_window, -+ .select_initial_window = tcp_select_initial_window, -+ .init_buffer_space = tcp_init_buffer_space, -+ .set_rto = tcp_set_rto, -+ .should_expand_sndbuf = tcp_should_expand_sndbuf, -+ .send_fin = tcp_send_fin, -+ .write_xmit = tcp_write_xmit, -+ .send_active_reset = tcp_send_active_reset, -+ .write_wakeup = tcp_write_wakeup, -+ .retransmit_timer = tcp_retransmit_timer, -+ .time_wait = tcp_time_wait, -+ .cleanup_rbuf = tcp_cleanup_rbuf, -+ .set_cong_ctrl = __tcp_set_congestion_control, -+}; -+ - /* Address-family independent initialization for a tcp_sock. - * - * NOTE: A lot of things set to zero explicitly by call to -@@ -453,6 +471,11 @@ - WRITE_ONCE(sk->sk_sndbuf, sock_net(sk)->ipv4.sysctl_tcp_wmem[1]); - WRITE_ONCE(sk->sk_rcvbuf, sock_net(sk)->ipv4.sysctl_tcp_rmem[1]); - -+ tp->ops = &tcp_specific; -+ -+ /* Initialize MPTCP-specific stuff and function-pointers */ -+ mptcp_init_tcp_sock(sk); -+ - sk_sockets_allocated_inc(sk); - sk->sk_route_forced_caps = NETIF_F_GSO; - } -@@ -785,6 +808,7 @@ - int ret; - - sock_rps_record_flow(sk); -+ - /* - * We can't seek on a socket input - */ -@@ -795,6 +819,16 @@ - - lock_sock(sk); - -+#ifdef CONFIG_MPTCP -+ if (mptcp(tcp_sk(sk))) { -+ struct mptcp_tcp_sock *mptcp; -+ -+ mptcp_for_each_sub(tcp_sk(sk)->mpcb, mptcp) { -+ sock_rps_record_flow(mptcp_to_sock(mptcp)); -+ } -+ } -+#endif -+ - timeo = sock_rcvtimeo(sk, sock->file->f_flags & O_NONBLOCK); - while (tss.len) { - ret = __tcp_splice_read(sk, &tss); -@@ -910,8 +944,7 @@ - return NULL; - } - --static unsigned int tcp_xmit_size_goal(struct sock *sk, u32 mss_now, -- int large_allowed) -+unsigned int tcp_xmit_size_goal(struct sock *sk, u32 mss_now, int large_allowed) - { - struct tcp_sock *tp = tcp_sk(sk); - u32 new_size_goal, size_goal; -@@ -939,8 +972,13 @@ - { - int mss_now; - -- mss_now = tcp_current_mss(sk); -- *size_goal = tcp_xmit_size_goal(sk, mss_now, !(flags & MSG_OOB)); -+ if (mptcp(tcp_sk(sk))) { -+ mss_now = mptcp_current_mss(sk); -+ *size_goal = mptcp_xmit_size_goal(sk, mss_now, !(flags & MSG_OOB)); -+ } else { -+ mss_now = tcp_current_mss(sk); -+ *size_goal = tcp_xmit_size_goal(sk, mss_now, !(flags & MSG_OOB)); -+ } - - return mss_now; - } -@@ -979,12 +1017,34 @@ - * is fully established. - */ - if (((1 << sk->sk_state) & ~(TCPF_ESTABLISHED | TCPF_CLOSE_WAIT)) && -- !tcp_passive_fastopen(sk)) { -+ !tcp_passive_fastopen(mptcp(tp) && tp->mpcb->master_sk ? -+ tp->mpcb->master_sk : sk)) { - err = sk_stream_wait_connect(sk, &timeo); - if (err != 0) - goto out_err; - } - -+ if (mptcp(tp)) { -+ struct mptcp_tcp_sock *mptcp; -+ -+ /* We must check this with socket-lock hold because we iterate -+ * over the subflows. -+ */ -+ if (!mptcp_can_sendpage(sk)) { -+ ssize_t ret; -+ -+ release_sock(sk); -+ ret = sock_no_sendpage(sk->sk_socket, page, offset, -+ size, flags); -+ lock_sock(sk); -+ return ret; -+ } -+ -+ mptcp_for_each_sub(tp->mpcb, mptcp) { -+ sock_rps_record_flow(mptcp_to_sock(mptcp)); -+ } -+ } -+ - sk_clear_bit(SOCKWQ_ASYNC_NOSPACE, sk); - - mss_now = tcp_send_mss(sk, &size_goal, flags); -@@ -1106,7 +1166,8 @@ - int tcp_sendpage_locked(struct sock *sk, struct page *page, int offset, - size_t size, int flags) - { -- if (!(sk->sk_route_caps & NETIF_F_SG)) -+ /* If MPTCP is enabled, we check it later after establishment */ -+ if (!mptcp(tcp_sk(sk)) && !(sk->sk_route_caps & NETIF_F_SG)) - return sock_no_sendpage_locked(sk, page, offset, size, flags); - - tcp_rate_check_app_limited(sk); /* is sending application-limited? */ -@@ -1228,12 +1289,21 @@ - * is fully established. - */ - if (((1 << sk->sk_state) & ~(TCPF_ESTABLISHED | TCPF_CLOSE_WAIT)) && -- !tcp_passive_fastopen(sk)) { -+ !tcp_passive_fastopen(mptcp(tp) && tp->mpcb->master_sk ? -+ tp->mpcb->master_sk : sk)) { - err = sk_stream_wait_connect(sk, &timeo); - if (err != 0) - goto do_error; - } - -+ if (mptcp(tp)) { -+ struct mptcp_tcp_sock *mptcp; -+ -+ mptcp_for_each_sub(tp->mpcb, mptcp) { -+ sock_rps_record_flow(mptcp_to_sock(mptcp)); -+ } -+ } -+ - if (unlikely(tp->repair)) { - if (tp->repair_queue == TCP_RECV_QUEUE) { - copied = tcp_send_rcvq(sk, msg, size); -@@ -1526,7 +1596,7 @@ - * calculation of whether or not we must ACK for the sake of - * a window update. - */ --static void tcp_cleanup_rbuf(struct sock *sk, int copied) -+void tcp_cleanup_rbuf(struct sock *sk, int copied) - { - struct tcp_sock *tp = tcp_sk(sk); - bool time_to_ack = false; -@@ -1569,7 +1639,7 @@ - - /* Optimize, __tcp_select_window() is not cheap. */ - if (2*rcv_window_now <= tp->window_clamp) { -- __u32 new_window = __tcp_select_window(sk); -+ __u32 new_window = tp->ops->__select_window(sk); - - /* Send ACK now, if this read freed lots of space - * in our buffer. Certainly, new_window is new window. -@@ -1685,7 +1755,7 @@ - /* Clean up data we have read: This will do ACK frames. */ - if (copied > 0) { - tcp_recv_skb(sk, seq, &offset); -- tcp_cleanup_rbuf(sk, copied); -+ tp->ops->cleanup_rbuf(sk, copied); - } - return copied; - } -@@ -1976,6 +2046,16 @@ - - lock_sock(sk); - -+#ifdef CONFIG_MPTCP -+ if (mptcp(tp)) { -+ struct mptcp_tcp_sock *mptcp; -+ -+ mptcp_for_each_sub(tp->mpcb, mptcp) { -+ sock_rps_record_flow(mptcp_to_sock(mptcp)); -+ } -+ } -+#endif -+ - err = -ENOTCONN; - if (sk->sk_state == TCP_LISTEN) - goto out; -@@ -2094,7 +2174,7 @@ - } - } - -- tcp_cleanup_rbuf(sk, copied); -+ tp->ops->cleanup_rbuf(sk, copied); - - if (copied >= target) { - /* Do not sleep, just process backlog. */ -@@ -2186,7 +2266,7 @@ - */ - - /* Clean up data we have read: This will do ACK frames. */ -- tcp_cleanup_rbuf(sk, copied); -+ tp->ops->cleanup_rbuf(sk, copied); - - release_sock(sk); - -@@ -2245,8 +2325,11 @@ - - switch (state) { - case TCP_ESTABLISHED: -- if (oldstate != TCP_ESTABLISHED) -+ if (oldstate != TCP_ESTABLISHED) { - TCP_INC_STATS(sock_net(sk), TCP_MIB_CURRESTAB); -+ if (is_meta_sk(sk)) -+ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_CURRESTAB); -+ } - break; - - case TCP_CLOSE: -@@ -2259,8 +2342,11 @@ - inet_put_port(sk); - /* fall through */ - default: -- if (oldstate == TCP_ESTABLISHED) -+ if (oldstate == TCP_ESTABLISHED) { - TCP_DEC_STATS(sock_net(sk), TCP_MIB_CURRESTAB); -+ if (is_meta_sk(sk)) -+ MPTCP_DEC_STATS(sock_net(sk), MPTCP_MIB_CURRESTAB); -+ } - } - - /* Change state AFTER socket is unhashed to avoid closed -@@ -2294,7 +2380,7 @@ - [TCP_NEW_SYN_RECV] = TCP_CLOSE, /* should not happen ! */ - }; - --static int tcp_close_state(struct sock *sk) -+int tcp_close_state(struct sock *sk) - { - int next = (int)new_state[sk->sk_state]; - int ns = next & TCP_STATE_MASK; -@@ -2324,7 +2410,7 @@ - TCPF_SYN_RECV | TCPF_CLOSE_WAIT)) { - /* Clear out any half completed packets. FIN if needed. */ - if (tcp_close_state(sk)) -- tcp_send_fin(sk); -+ tcp_sk(sk)->ops->send_fin(sk); - } - } - EXPORT_SYMBOL(tcp_shutdown); -@@ -2349,6 +2435,17 @@ - int data_was_unread = 0; - int state; - -+ if (is_meta_sk(sk)) { -+ /* TODO: Currently forcing timeout to 0 because -+ * sk_stream_wait_close will complain during lockdep because -+ * of the mpcb_mutex (circular lock dependency through -+ * inet_csk_listen_stop()). -+ * We should find a way to get rid of the mpcb_mutex. -+ */ -+ mptcp_close(sk, 0); -+ return; -+ } -+ - lock_sock(sk); - sk->sk_shutdown = SHUTDOWN_MASK; - -@@ -2393,7 +2490,7 @@ - /* Unread data was tossed, zap the connection. */ - NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPABORTONCLOSE); - tcp_set_state(sk, TCP_CLOSE); -- tcp_send_active_reset(sk, sk->sk_allocation); -+ tcp_sk(sk)->ops->send_active_reset(sk, sk->sk_allocation); - } else if (sock_flag(sk, SOCK_LINGER) && !sk->sk_lingertime) { - /* Check zero linger _after_ checking for unread data. */ - sk->sk_prot->disconnect(sk, 0); -@@ -2467,7 +2564,7 @@ - struct tcp_sock *tp = tcp_sk(sk); - if (tp->linger2 < 0) { - tcp_set_state(sk, TCP_CLOSE); -- tcp_send_active_reset(sk, GFP_ATOMIC); -+ tp->ops->send_active_reset(sk, GFP_ATOMIC); - __NET_INC_STATS(sock_net(sk), - LINUX_MIB_TCPABORTONLINGER); - } else { -@@ -2477,7 +2574,8 @@ - inet_csk_reset_keepalive_timer(sk, - tmo - TCP_TIMEWAIT_LEN); - } else { -- tcp_time_wait(sk, TCP_FIN_WAIT2, tmo); -+ tcp_sk(sk)->ops->time_wait(sk, TCP_FIN_WAIT2, -+ tmo); - goto out; - } - } -@@ -2486,7 +2584,7 @@ - sk_mem_reclaim(sk); - if (tcp_check_oom(sk, 0)) { - tcp_set_state(sk, TCP_CLOSE); -- tcp_send_active_reset(sk, GFP_ATOMIC); -+ tcp_sk(sk)->ops->send_active_reset(sk, GFP_ATOMIC); - __NET_INC_STATS(sock_net(sk), - LINUX_MIB_TCPABORTONMEMORY); - } else if (!check_net(sock_net(sk))) { -@@ -2518,15 +2616,6 @@ - } - EXPORT_SYMBOL(tcp_close); - --/* These states need RST on ABORT according to RFC793 */ -- --static inline bool tcp_need_reset(int state) --{ -- return (1 << state) & -- (TCPF_ESTABLISHED | TCPF_CLOSE_WAIT | TCPF_FIN_WAIT1 | -- TCPF_FIN_WAIT2 | TCPF_SYN_RECV); --} -- - static void tcp_rtx_queue_purge(struct sock *sk) - { - struct rb_node *p = rb_first(&sk->tcp_rtx_queue); -@@ -2548,6 +2637,10 @@ - { - struct sk_buff *skb; - -+ if (mptcp(tcp_sk(sk)) && !is_meta_sk(sk) && -+ !tcp_rtx_and_write_queues_empty(sk)) -+ mptcp_reinject_data(sk, 0); -+ - tcp_chrono_stop(sk, TCP_CHRONO_BUSY); - while ((skb = __skb_dequeue(&sk->sk_write_queue)) != NULL) { - tcp_skb_tsorted_anchor_cleanup(skb); -@@ -2566,6 +2659,35 @@ - inet_csk(sk)->icsk_backoff = 0; - } - -+void tcp_reset_vars(struct sock *sk) -+{ -+ struct inet_connection_sock *icsk = inet_csk(sk); -+ struct tcp_sock *tp = tcp_sk(sk); -+ -+ tp->srtt_us = 0; -+ tp->mdev_us = jiffies_to_usecs(TCP_TIMEOUT_INIT); -+ tp->rcv_rtt_last_tsecr = 0; -+ icsk->icsk_rto = TCP_TIMEOUT_INIT; -+ tp->snd_ssthresh = TCP_INFINITE_SSTHRESH; -+ tp->snd_cwnd = TCP_INIT_CWND; -+ tp->snd_cwnd_cnt = 0; -+ tp->delivered = 0; -+ tp->delivered_ce = 0; -+ tp->is_sack_reneg = 0; -+ tcp_clear_retrans(tp); -+ tp->bytes_sent = 0; -+ tp->bytes_acked = 0; -+ tp->bytes_received = 0; -+ tp->bytes_retrans = 0; -+ tp->total_retrans = 0; -+ tp->segs_in = 0; -+ tp->segs_out = 0; -+ tp->data_segs_in = 0; -+ tp->data_segs_out = 0; -+ /* There's a bubble in the pipe until at least the first ACK. */ -+ tp->app_limited = ~0U; -+} -+ - int tcp_disconnect(struct sock *sk, int flags) - { - struct inet_sock *inet = inet_sk(sk); -@@ -2588,7 +2710,7 @@ - /* The last check adjusts for discrepancy of Linux wrt. RFC - * states - */ -- tcp_send_active_reset(sk, gfp_any()); -+ tp->ops->send_active_reset(sk, gfp_any()); - sk->sk_err = ECONNRESET; - } else if (old_state == TCP_SYN_SENT) - sk->sk_err = ECONNRESET; -@@ -2610,11 +2732,15 @@ - if (!(sk->sk_userlocks & SOCK_BINDADDR_LOCK)) - inet_reset_saddr(sk); - -+ if (is_meta_sk(sk)) { -+ mptcp_disconnect(sk); -+ } else { -+ if (tp->inside_tk_table) -+ mptcp_hash_remove_bh(tp); -+ } -+ - sk->sk_shutdown = 0; - sock_reset_flag(sk, SOCK_DONE); -- tp->srtt_us = 0; -- tp->mdev_us = jiffies_to_usecs(TCP_TIMEOUT_INIT); -- tp->rcv_rtt_last_tsecr = 0; - - seq = tp->write_seq + tp->max_window + 2; - if (!seq) -@@ -2624,20 +2750,14 @@ - icsk->icsk_backoff = 0; - tp->snd_cwnd = 2; - icsk->icsk_probes_out = 0; -- icsk->icsk_rto = TCP_TIMEOUT_INIT; -- tp->snd_ssthresh = TCP_INFINITE_SSTHRESH; -- tp->snd_cwnd = TCP_INIT_CWND; -- tp->snd_cwnd_cnt = 0; - tp->window_clamp = 0; -- tp->delivered = 0; -- tp->delivered_ce = 0; -+ -+ tcp_reset_vars(sk); -+ - if (icsk->icsk_ca_ops->release) - icsk->icsk_ca_ops->release(sk); - memset(icsk->icsk_ca_priv, 0, sizeof(icsk->icsk_ca_priv)); - tcp_set_ca_state(sk, TCP_CA_Open); -- tp->is_sack_reneg = 0; -- tcp_clear_retrans(tp); -- tp->total_retrans = 0; - inet_csk_delack_init(sk); - /* Initialize rcv_mss to TCP_MIN_MSS to avoid division by 0 - * issue in __tcp_select_window() -@@ -2649,14 +2769,6 @@ - sk->sk_rx_dst = NULL; - tcp_saved_syn_free(tp); - tp->compressed_ack = 0; -- tp->segs_in = 0; -- tp->segs_out = 0; -- tp->bytes_sent = 0; -- tp->bytes_acked = 0; -- tp->bytes_received = 0; -- tp->bytes_retrans = 0; -- tp->data_segs_in = 0; -- tp->data_segs_out = 0; - tp->duplicate_sack[0].start_seq = 0; - tp->duplicate_sack[0].end_seq = 0; - tp->dsack_dups = 0; -@@ -2665,8 +2777,6 @@ - tp->sacked_out = 0; - tp->tlp_high_seq = 0; - tp->last_oow_ack_time = 0; -- /* There's a bubble in the pipe until at least the first ACK. */ -- tp->app_limited = ~0U; - tp->rack.mstamp = 0; - tp->rack.advanced = 0; - tp->rack.reo_wnd_steps = 1; -@@ -2700,7 +2810,7 @@ - static inline bool tcp_can_repair_sock(const struct sock *sk) - { - return ns_capable(sock_net(sk)->user_ns, CAP_NET_ADMIN) && -- (sk->sk_state != TCP_LISTEN); -+ (sk->sk_state != TCP_LISTEN) && !sock_flag(sk, SOCK_MPTCP); - } - - static int tcp_repair_set_window(struct tcp_sock *tp, char __user *optbuf, int len) -@@ -2869,6 +2979,61 @@ - - return tcp_fastopen_reset_cipher(net, sk, key, backup_key); - } -+#ifdef CONFIG_MPTCP -+ case MPTCP_SCHEDULER: { -+ char name[MPTCP_SCHED_NAME_MAX]; -+ -+ if (optlen < 1) -+ return -EINVAL; -+ -+ /* Cannot be used if MPTCP is not used or we already have -+ * established an MPTCP-connection. -+ */ -+ if (mptcp_init_failed || !sysctl_mptcp_enabled || -+ sk->sk_state != TCP_CLOSE) -+ return -EPERM; -+ -+ val = strncpy_from_user(name, optval, -+ min_t(long, MPTCP_SCHED_NAME_MAX - 1, -+ optlen)); -+ -+ if (val < 0) -+ return -EFAULT; -+ name[val] = 0; -+ -+ lock_sock(sk); -+ err = mptcp_set_scheduler(sk, name); -+ release_sock(sk); -+ return err; -+ } -+ -+ case MPTCP_PATH_MANAGER: { -+ char name[MPTCP_PM_NAME_MAX]; -+ -+ if (optlen < 1) -+ return -EINVAL; -+ -+ /* Cannot be used if MPTCP is not used or we already have -+ * established an MPTCP-connection. -+ */ -+ if (mptcp_init_failed || !sysctl_mptcp_enabled || -+ sk->sk_state != TCP_CLOSE) -+ return -EPERM; -+ -+ val = strncpy_from_user(name, optval, -+ min_t(long, MPTCP_PM_NAME_MAX - 1, -+ optlen)); -+ -+ if (val < 0) -+ return -EFAULT; -+ name[val] = 0; -+ -+ lock_sock(sk); -+ err = mptcp_set_path_manager(sk, name); -+ release_sock(sk); -+ return err; -+ } -+#endif - default: - /* fallthru */ - break; -@@ -3051,6 +3216,12 @@ - break; - - case TCP_DEFER_ACCEPT: -+ /* An established MPTCP-connection (mptcp(tp) only returns true -+ * if the socket is established) should not use DEFER on new -+ * subflows. -+ */ -+ if (mptcp(tp)) -+ break; - /* Translate value in seconds to number of retransmits */ - icsk->icsk_accept_queue.rskq_defer_accept = - secs_to_retrans(val, TCP_TIMEOUT_INIT / HZ, -@@ -3078,7 +3249,7 @@ - (TCPF_ESTABLISHED | TCPF_CLOSE_WAIT) && - inet_csk_ack_scheduled(sk)) { - icsk->icsk_ack.pending |= ICSK_ACK_PUSHED; -- tcp_cleanup_rbuf(sk, 1); -+ tp->ops->cleanup_rbuf(sk, 1); - if (!(val & 1)) - inet_csk_enter_pingpong_mode(sk); - } -@@ -3144,6 +3315,32 @@ - tp->notsent_lowat = val; - sk->sk_write_space(sk); - break; -+#ifdef CONFIG_MPTCP -+ case MPTCP_ENABLED: -+ if (mptcp_init_failed || !sysctl_mptcp_enabled || -+ sk->sk_state != TCP_CLOSE -+#ifdef CONFIG_TCP_MD5SIG -+ || tp->md5sig_info -+#endif -+ ) { -+ err = -EPERM; -+ break; -+ } -+ -+ if (val) -+ mptcp_enable_sock(sk); -+ else -+ mptcp_disable_sock(sk); -+ break; -+ case MPTCP_INFO: -+ if (mptcp_init_failed || !sysctl_mptcp_enabled) { -+ err = -EPERM; -+ break; -+ } -+ -+ tp->record_master_info = !!(val & MPTCP_INFO_FLAG_SAVE_MASTER); -+ break; -+#endif - case TCP_INQ: - if (val > 1 || val < 0) - err = -EINVAL; -@@ -3208,7 +3405,7 @@ - } - - /* Return information about state of tcp endpoint in API format. */ --void tcp_get_info(struct sock *sk, struct tcp_info *info) -+void tcp_get_info(struct sock *sk, struct tcp_info *info, bool no_lock) - { - const struct tcp_sock *tp = tcp_sk(sk); /* iff sk_type == SOCK_STREAM */ - const struct inet_connection_sock *icsk = inet_csk(sk); -@@ -3245,7 +3442,8 @@ - return; - } - -- slow = lock_sock_fast(sk); -+ if (!no_lock) -+ slow = lock_sock_fast(sk); - - info->tcpi_ca_state = icsk->icsk_ca_state; - info->tcpi_retransmits = icsk->icsk_retransmits; -@@ -3321,7 +3519,9 @@ - info->tcpi_reord_seen = tp->reord_seen; - info->tcpi_rcv_ooopack = tp->rcv_ooopack; - info->tcpi_snd_wnd = tp->snd_wnd; -- unlock_sock_fast(sk, slow); -+ -+ if (!no_lock) -+ unlock_sock_fast(sk, slow); - } - EXPORT_SYMBOL_GPL(tcp_get_info); - -@@ -3468,7 +3668,7 @@ - if (get_user(len, optlen)) - return -EFAULT; - -- tcp_get_info(sk, &info); -+ tcp_get_info(sk, &info, false); - - len = min_t(unsigned int, len, sizeof(info)); - if (put_user(len, optlen)) -@@ -3657,6 +3857,87 @@ - } - return 0; - } -+#ifdef CONFIG_MPTCP -+ case MPTCP_SCHEDULER: -+ if (get_user(len, optlen)) -+ return -EFAULT; -+ len = min_t(unsigned int, len, MPTCP_SCHED_NAME_MAX); -+ if (put_user(len, optlen)) -+ return -EFAULT; -+ -+ lock_sock(sk); -+ if (mptcp(tcp_sk(sk))) { -+ struct mptcp_cb *mpcb = tcp_sk(mptcp_meta_sk(sk))->mpcb; -+ -+ if (copy_to_user(optval, mpcb->sched_ops->name, len)) { -+ release_sock(sk); -+ return -EFAULT; -+ } -+ } else { -+ if (copy_to_user(optval, tcp_sk(sk)->mptcp_sched_name, -+ len)) { -+ release_sock(sk); -+ return -EFAULT; -+ } -+ } -+ release_sock(sk); -+ return 0; -+ -+ case MPTCP_PATH_MANAGER: -+ if (get_user(len, optlen)) -+ return -EFAULT; -+ len = min_t(unsigned int, len, MPTCP_PM_NAME_MAX); -+ if (put_user(len, optlen)) -+ return -EFAULT; -+ -+ lock_sock(sk); -+ if (mptcp(tcp_sk(sk))) { -+ struct mptcp_cb *mpcb = tcp_sk(mptcp_meta_sk(sk))->mpcb; -+ -+ if (copy_to_user(optval, mpcb->pm_ops->name, len)) { -+ release_sock(sk); -+ return -EFAULT; -+ } -+ } else { -+ if (copy_to_user(optval, tcp_sk(sk)->mptcp_pm_name, -+ len)) { -+ release_sock(sk); -+ return -EFAULT; -+ } -+ } -+ release_sock(sk); -+ return 0; -+ -+ case MPTCP_ENABLED: -+ if (sk->sk_state != TCP_SYN_SENT) -+ val = mptcp(tp) ? 1 : 0; -+ else -+ val = sock_flag(sk, SOCK_MPTCP) ? 1 : 0; -+ break; -+ case MPTCP_INFO: -+ { -+ int ret; -+ -+ if (!mptcp(tp)) -+ return -EINVAL; -+ -+ if (get_user(len, optlen)) -+ return -EFAULT; -+ -+ len = min_t(unsigned int, len, sizeof(struct mptcp_info)); -+ -+ lock_sock(sk); -+ ret = mptcp_get_info(sk, optval, len); -+ release_sock(sk); -+ -+ if (ret) -+ return ret; -+ -+ if (put_user(len, optlen)) -+ return -EFAULT; -+ return 0; -+ } -+#endif - #ifdef CONFIG_MMU - case TCP_ZEROCOPY_RECEIVE: { - struct tcp_zerocopy_receive zc; -@@ -3862,7 +4143,9 @@ - if (sk->sk_state == TCP_SYN_SENT || sk->sk_state == TCP_SYN_RECV) - TCP_INC_STATS(sock_net(sk), TCP_MIB_ATTEMPTFAILS); - -+ WARN_ON(sk->sk_state == TCP_CLOSE); - tcp_set_state(sk, TCP_CLOSE); -+ - tcp_clear_xmit_timers(sk); - if (req) - reqsk_fastopen_remove(sk, req, false); -@@ -3878,6 +4161,8 @@ - - int tcp_abort(struct sock *sk, int err) - { -+ struct sock *meta_sk = mptcp(tcp_sk(sk)) ? mptcp_meta_sk(sk) : sk; -+ - if (!sk_fullsock(sk)) { - if (sk->sk_state == TCP_NEW_SYN_RECV) { - struct request_sock *req = inet_reqsk(sk); -@@ -3891,7 +4176,7 @@ - } - - /* Don't race with userspace socket closes such as tcp_close. */ -- lock_sock(sk); -+ lock_sock(meta_sk); - - if (sk->sk_state == TCP_LISTEN) { - tcp_set_state(sk, TCP_CLOSE); -@@ -3900,7 +4185,7 @@ - - /* Don't race with BH socket closes such as inet_csk_listen_stop. */ - local_bh_disable(); -- bh_lock_sock(sk); -+ bh_lock_sock(meta_sk); - - if (!sock_flag(sk, SOCK_DEAD)) { - sk->sk_err = err; -@@ -3908,14 +4193,14 @@ - smp_wmb(); - sk->sk_error_report(sk); - if (tcp_need_reset(sk->sk_state)) -- tcp_send_active_reset(sk, GFP_ATOMIC); -+ tcp_sk(sk)->ops->send_active_reset(sk, GFP_ATOMIC); - tcp_done(sk); - } - -- bh_unlock_sock(sk); -+ bh_unlock_sock(meta_sk); - local_bh_enable(); - tcp_write_queue_purge(sk); -- release_sock(sk); -+ release_sock(meta_sk); - return 0; - } - EXPORT_SYMBOL_GPL(tcp_abort); -diff -aurN linux-5.4.64/net/ipv4/tcp_cong.c linux-5.4.64.mptcp/net/ipv4/tcp_cong.c ---- linux-5.4.64/net/ipv4/tcp_cong.c 2020-09-09 19:12:37.000000000 +0200 -+++ linux-5.4.64.mptcp/net/ipv4/tcp_cong.c 2020-09-10 19:25:10.503220935 +0200 -@@ -328,13 +328,19 @@ - return ret; - } - -+int tcp_set_congestion_control(struct sock *sk, const char *name, bool load, -+ bool reinit, bool cap_net_admin) -+{ -+ return tcp_sk(sk)->ops->set_cong_ctrl(sk, name, load, reinit, cap_net_admin); -+} -+ - /* Change congestion control for socket. If load is false, then it is the - * responsibility of the caller to call tcp_init_congestion_control or - * tcp_reinit_congestion_control (if the current congestion control was - * already initialized. - */ --int tcp_set_congestion_control(struct sock *sk, const char *name, bool load, -- bool reinit, bool cap_net_admin) -+int __tcp_set_congestion_control(struct sock *sk, const char *name, bool load, -+ bool reinit, bool cap_net_admin) - { - struct inet_connection_sock *icsk = inet_csk(sk); - const struct tcp_congestion_ops *ca; -diff -aurN linux-5.4.64/net/ipv4/tcp_diag.c linux-5.4.64.mptcp/net/ipv4/tcp_diag.c ---- linux-5.4.64/net/ipv4/tcp_diag.c 2020-09-09 19:12:37.000000000 +0200 -+++ linux-5.4.64.mptcp/net/ipv4/tcp_diag.c 2020-09-10 19:25:10.503220935 +0200 -@@ -31,7 +31,7 @@ - r->idiag_wqueue = READ_ONCE(tp->write_seq) - tp->snd_una; - } - if (info) -- tcp_get_info(sk, info); -+ tcp_get_info(sk, info, false); - } - - #ifdef CONFIG_TCP_MD5SIG -diff -aurN linux-5.4.64/net/ipv4/tcp_fastopen.c linux-5.4.64.mptcp/net/ipv4/tcp_fastopen.c ---- linux-5.4.64/net/ipv4/tcp_fastopen.c 2020-09-09 19:12:37.000000000 +0200 -+++ linux-5.4.64.mptcp/net/ipv4/tcp_fastopen.c 2020-09-10 19:25:10.503220935 +0200 -@@ -9,6 +9,7 @@ - #include - #include - #include -+#include - - void tcp_fastopen_init_key_once(struct net *net) - { -@@ -136,8 +137,6 @@ - const siphash_key_t *key, - struct tcp_fastopen_cookie *foc) - { -- BUILD_BUG_ON(TCP_FASTOPEN_COOKIE_SIZE != sizeof(u64)); -- - if (req->rsk_ops->family == AF_INET) { - const struct iphdr *iph = ip_hdr(syn); - -@@ -258,8 +257,9 @@ - { - struct tcp_sock *tp; - struct request_sock_queue *queue = &inet_csk(sk)->icsk_accept_queue; -- struct sock *child; -+ struct sock *child, *meta_sk; - bool own_req; -+ int ret; - - child = inet_csk(sk)->icsk_af_ops->syn_recv_sock(sk, skb, req, NULL, - NULL, &own_req); -@@ -294,15 +294,26 @@ - - refcount_set(&req->rsk_refcnt, 2); - -- /* Now finish processing the fastopen child socket. */ -- tcp_init_transfer(child, BPF_SOCK_OPS_PASSIVE_ESTABLISHED_CB); -- - tp->rcv_nxt = TCP_SKB_CB(skb)->seq + 1; - - tcp_fastopen_add_skb(child, skb); - - tcp_rsk(req)->rcv_nxt = tp->rcv_nxt; - tp->rcv_wup = tp->rcv_nxt; -+ -+ meta_sk = child; -+ ret = mptcp_check_req_fastopen(meta_sk, req); -+ if (ret < 0) -+ return NULL; -+ -+ if (ret == 0) { -+ child = tcp_sk(meta_sk)->mpcb->master_sk; -+ tp = tcp_sk(child); -+ } -+ -+ /* Now finish processing the fastopen child socket. */ -+ tcp_init_transfer(child, BPF_SOCK_OPS_PASSIVE_ESTABLISHED_CB); -+ - /* tcp_conn_request() is sending the SYNACK, - * and queues the child into listener accept queue. - */ -diff -aurN linux-5.4.64/net/ipv4/tcp_input.c linux-5.4.64.mptcp/net/ipv4/tcp_input.c ---- linux-5.4.64/net/ipv4/tcp_input.c 2020-09-09 19:12:37.000000000 +0200 -+++ linux-5.4.64.mptcp/net/ipv4/tcp_input.c 2020-09-10 19:32:43.267687285 +0200 -@@ -76,35 +76,15 @@ - #include - #include - #include -+#include -+#include -+#include - #include - #include - #include - - int sysctl_tcp_max_orphans __read_mostly = NR_FILE; - --#define FLAG_DATA 0x01 /* Incoming frame contained data. */ --#define FLAG_WIN_UPDATE 0x02 /* Incoming ACK was a window update. */ --#define FLAG_DATA_ACKED 0x04 /* This ACK acknowledged new data. */ --#define FLAG_RETRANS_DATA_ACKED 0x08 /* "" "" some of which was retransmitted. */ --#define FLAG_SYN_ACKED 0x10 /* This ACK acknowledged SYN. */ --#define FLAG_DATA_SACKED 0x20 /* New SACK. */ --#define FLAG_ECE 0x40 /* ECE in this ACK */ --#define FLAG_LOST_RETRANS 0x80 /* This ACK marks some retransmission lost */ --#define FLAG_SLOWPATH 0x100 /* Do not skip RFC checks for window update.*/ --#define FLAG_ORIG_SACK_ACKED 0x200 /* Never retransmitted data are (s)acked */ --#define FLAG_SND_UNA_ADVANCED 0x400 /* Snd_una was changed (!= FLAG_DATA_ACKED) */ --#define FLAG_DSACKING_ACK 0x800 /* SACK blocks contained D-SACK info */ --#define FLAG_SET_XMIT_TIMER 0x1000 /* Set TLP or RTO timer */ --#define FLAG_SACK_RENEGING 0x2000 /* snd_una advanced to a sacked seq */ --#define FLAG_UPDATE_TS_RECENT 0x4000 /* tcp_replace_ts_recent() */ --#define FLAG_NO_CHALLENGE_ACK 0x8000 /* do not call tcp_send_challenge_ack() */ --#define FLAG_ACK_MAYBE_DELAYED 0x10000 /* Likely a delayed ACK */ -- --#define FLAG_ACKED (FLAG_DATA_ACKED|FLAG_SYN_ACKED) --#define FLAG_NOT_DUP (FLAG_DATA|FLAG_WIN_UPDATE|FLAG_ACKED) --#define FLAG_CA_ALERT (FLAG_DATA_SACKED|FLAG_ECE|FLAG_DSACKING_ACK) --#define FLAG_FORWARD_PROGRESS (FLAG_ACKED|FLAG_DATA_SACKED) -- - #define TCP_REMNANT (TCP_FLAG_FIN|TCP_FLAG_URG|TCP_FLAG_SYN|TCP_FLAG_PSH) - #define TCP_HP_BITS (~(TCP_RESERVED_BITS|TCP_FLAG_PSH)) - -@@ -349,8 +329,12 @@ - per_mss = roundup_pow_of_two(per_mss) + - SKB_DATA_ALIGN(sizeof(struct sk_buff)); - -- nr_segs = max_t(u32, TCP_INIT_CWND, tp->snd_cwnd); -- nr_segs = max_t(u32, nr_segs, tp->reordering + 1); -+ if (mptcp(tp)) { -+ nr_segs = mptcp_check_snd_buf(tp); -+ } else { -+ nr_segs = max_t(u32, TCP_INIT_CWND, tp->snd_cwnd); -+ nr_segs = max_t(u32, nr_segs, tp->reordering + 1); -+ } - - /* Fast Recovery (RFC 5681 3.2) : - * Cubic needs 1.7 factor, rounded to 2 to include -@@ -359,9 +343,17 @@ - sndmem = ca_ops->sndbuf_expand ? ca_ops->sndbuf_expand(sk) : 2; - sndmem *= nr_segs * per_mss; - -- if (sk->sk_sndbuf < sndmem) -+ /* MPTCP: after this sndmem is the new contribution of the -+ * current subflow to the aggregated sndbuf */ -+ if (sk->sk_sndbuf < sndmem) { -+ int old_sndbuf = sk->sk_sndbuf; - WRITE_ONCE(sk->sk_sndbuf, - min(sndmem, sock_net(sk)->ipv4.sysctl_tcp_wmem[2])); -+ /* MPTCP: ok, the subflow sndbuf has grown, reflect -+ * this in the aggregate buffer.*/ -+ if (mptcp(tp) && old_sndbuf != sk->sk_sndbuf) -+ mptcp_update_sndbuf(tp); -+ } - } - - /* 2. Tuning advertised window (window_clamp, rcv_ssthresh) -@@ -410,9 +402,14 @@ - static void tcp_grow_window(struct sock *sk, const struct sk_buff *skb) - { - struct tcp_sock *tp = tcp_sk(sk); -+ struct sock *meta_sk = mptcp(tp) ? mptcp_meta_sk(sk) : sk; -+ struct tcp_sock *meta_tp = tcp_sk(meta_sk); - int room; - -- room = min_t(int, tp->window_clamp, tcp_space(sk)) - tp->rcv_ssthresh; -+ if (is_meta_sk(sk)) -+ return; -+ -+ room = min_t(int, meta_tp->window_clamp, tcp_space(meta_sk)) - meta_tp->rcv_ssthresh; - - /* Check #1 */ - if (room > 0 && !tcp_under_memory_pressure(sk)) { -@@ -422,13 +419,13 @@ - * will fit to rcvbuf in future. - */ - if (tcp_win_from_space(sk, skb->truesize) <= skb->len) -- incr = 2 * tp->advmss; -+ incr = 2 * meta_tp->advmss; - else -- incr = __tcp_grow_window(sk, skb); -+ incr = __tcp_grow_window(meta_sk, skb); - - if (incr) { - incr = max_t(int, incr, 2 * skb->len); -- tp->rcv_ssthresh += min(room, incr); -+ meta_tp->rcv_ssthresh += min(room, incr); - inet_csk(sk)->icsk_ack.quick |= 1; - } - } -@@ -611,7 +608,10 @@ - - tcp_mstamp_refresh(tp); - time = tcp_stamp_us_delta(tp->tcp_mstamp, tp->rcvq_space.time); -- if (time < (tp->rcv_rtt_est.rtt_us >> 3) || tp->rcv_rtt_est.rtt_us == 0) -+ if (mptcp(tp)) { -+ if (mptcp_check_rtt(tp, time)) -+ return; -+ } else if (time < (tp->rcv_rtt_est.rtt_us >> 3) || tp->rcv_rtt_est.rtt_us == 0) - return; - - /* Number of bytes copied to user in last RTT */ -@@ -834,7 +834,7 @@ - /* Calculate rto without backoff. This is the second half of Van Jacobson's - * routine referred to above. - */ --static void tcp_set_rto(struct sock *sk) -+void tcp_set_rto(struct sock *sk) - { - const struct tcp_sock *tp = tcp_sk(sk); - /* Old crap is replaced with new one. 8) -@@ -1406,6 +1406,13 @@ - int len; - int in_sack; - -+ /* For MPTCP we cannot shift skb-data and remove one skb from the -+ * send-queue, because this will make us loose the DSS-option (which -+ * is stored in TCP_SKB_CB(skb)->dss) of the skb we are removing. -+ */ -+ if (mptcp(tp)) -+ goto fallback; -+ - /* Normally R but no L won't result in plain S */ - if (!dup_sack && - (TCP_SKB_CB(skb)->sacked & (TCPCB_LOST|TCPCB_SACKED_RETRANS)) == TCPCB_SACKED_RETRANS) -@@ -2960,7 +2967,7 @@ - */ - tcp_update_rtt_min(sk, ca_rtt_us, flag); - tcp_rtt_estimator(sk, seq_rtt_us); -- tcp_set_rto(sk); -+ tp->ops->set_rto(sk); - - /* RFC6298: only reset backoff on valid RTT measurement. */ - inet_csk(sk)->icsk_backoff = 0; -@@ -3028,7 +3035,7 @@ - } - - /* If we get here, the whole TSO packet has not been acked. */ --static u32 tcp_tso_acked(struct sock *sk, struct sk_buff *skb) -+u32 tcp_tso_acked(struct sock *sk, struct sk_buff *skb) - { - struct tcp_sock *tp = tcp_sk(sk); - u32 packets_acked; -@@ -3048,8 +3055,7 @@ - return packets_acked; - } - --static void tcp_ack_tstamp(struct sock *sk, struct sk_buff *skb, -- u32 prior_snd_una) -+void tcp_ack_tstamp(struct sock *sk, struct sk_buff *skb, u32 prior_snd_una) - { - const struct skb_shared_info *shinfo; - -@@ -3154,6 +3160,8 @@ - */ - if (likely(!(scb->tcp_flags & TCPHDR_SYN))) { - flag |= FLAG_DATA_ACKED; -+ if (mptcp(tp) && mptcp_is_data_seq(skb)) -+ flag |= MPTCP_FLAG_DATA_ACKED; - } else { - flag |= FLAG_SYN_ACKED; - tp->retrans_stamp = 0; -@@ -3274,7 +3282,7 @@ - return flag; - } - --static void tcp_ack_probe(struct sock *sk) -+void tcp_ack_probe(struct sock *sk) - { - struct inet_connection_sock *icsk = inet_csk(sk); - struct sk_buff *head = tcp_send_head(sk); -@@ -3346,9 +3354,8 @@ - /* Check that window update is acceptable. - * The function assumes that snd_una<=ack<=snd_next. - */ --static inline bool tcp_may_update_window(const struct tcp_sock *tp, -- const u32 ack, const u32 ack_seq, -- const u32 nwin) -+bool tcp_may_update_window(const struct tcp_sock *tp, const u32 ack, -+ const u32 ack_seq, const u32 nwin) - { - return after(ack, tp->snd_una) || - after(ack_seq, tp->snd_wl1) || -@@ -3586,7 +3593,7 @@ - } - - /* This routine deals with incoming acks, but not outgoing ones. */ --static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag) -+static int tcp_ack(struct sock *sk, struct sk_buff *skb, int flag) - { - struct inet_connection_sock *icsk = inet_csk(sk); - struct tcp_sock *tp = tcp_sk(sk); -@@ -3709,6 +3716,16 @@ - - tcp_rack_update_reo_wnd(sk, &rs); - -+ if (mptcp(tp)) { -+ if (mptcp_fallback_infinite(sk, flag)) { -+ pr_debug("%s resetting flow\n", __func__); -+ mptcp_send_reset(sk); -+ return -1; -+ } -+ -+ mptcp_clean_rtx_infinite(skb, sk); -+ } -+ - if (tp->tlp_high_seq) - tcp_process_tlp_ack(sk, ack, flag); - /* If needed, reset TLP/RTO timer; RACK may later override this. */ -@@ -3851,8 +3868,10 @@ - */ - void tcp_parse_options(const struct net *net, - const struct sk_buff *skb, -- struct tcp_options_received *opt_rx, int estab, -- struct tcp_fastopen_cookie *foc) -+ struct tcp_options_received *opt_rx, -+ struct mptcp_options_received *mopt, -+ int estab, struct tcp_fastopen_cookie *foc, -+ struct tcp_sock *tp) - { - const unsigned char *ptr; - const struct tcphdr *th = tcp_hdr(skb); -@@ -3938,6 +3957,10 @@ - */ - break; - #endif -+ case TCPOPT_MPTCP: -+ mptcp_parse_options(ptr - 2, opsize, mopt, skb, tp); -+ break; -+ - case TCPOPT_FASTOPEN: - tcp_parse_fastopen_option( - opsize - TCPOLEN_FASTOPEN_BASE, -@@ -4005,7 +4028,9 @@ - return true; - } - -- tcp_parse_options(net, skb, &tp->rx_opt, 1, NULL); -+ tcp_parse_options(net, skb, &tp->rx_opt, -+ mptcp(tp) ? &tp->mptcp->rx_opt : NULL, 1, NULL, tp); -+ - if (tp->rx_opt.saw_tstamp && tp->rx_opt.rcv_tsecr) - tp->rx_opt.rcv_tsecr -= tp->tsoffset; - -@@ -4164,6 +4189,11 @@ - { - struct tcp_sock *tp = tcp_sk(sk); - -+ if (is_meta_sk(sk)) { -+ mptcp_fin(sk); -+ return; -+ } -+ - inet_csk_schedule_ack(sk); - - sk->sk_shutdown |= RCV_SHUTDOWN; -@@ -4174,6 +4204,10 @@ - case TCP_ESTABLISHED: - /* Move to CLOSE_WAIT */ - tcp_set_state(sk, TCP_CLOSE_WAIT); -+ -+ if (mptcp(tp)) -+ mptcp_sub_close_passive(sk); -+ - inet_csk_enter_pingpong_mode(sk); - break; - -@@ -4196,9 +4230,16 @@ - tcp_set_state(sk, TCP_CLOSING); - break; - case TCP_FIN_WAIT2: -+ if (mptcp(tp)) { -+ /* The socket will get closed by mptcp_data_ready. -+ * We first have to process all data-sequences. -+ */ -+ tp->close_it = 1; -+ break; -+ } - /* Received a FIN -- send ACK and enter TIME_WAIT. */ - tcp_send_ack(sk); -- tcp_time_wait(sk, TCP_TIME_WAIT, 0); -+ tp->ops->time_wait(sk, TCP_TIME_WAIT, 0); - break; - default: - /* Only TCP_LISTEN and TCP_CLOSE are left, in these -@@ -4220,6 +4261,10 @@ - if (!sock_flag(sk, SOCK_DEAD)) { - sk->sk_state_change(sk); - -+ /* Don't wake up MPTCP-subflows */ -+ if (mptcp(tp)) -+ return; -+ - /* Do not send POLL_HUP for half duplex close. */ - if (sk->sk_shutdown == SHUTDOWN_MASK || - sk->sk_state == TCP_CLOSE) -@@ -4434,6 +4479,9 @@ - - *fragstolen = false; - -+ if (mptcp(tcp_sk(sk)) && !is_meta_sk(sk)) -+ return false; -+ - /* Its possible this segment overlaps with prior segment in queue */ - if (TCP_SKB_CB(from)->seq != TCP_SKB_CB(to)->end_seq) - return false; -@@ -4488,7 +4536,7 @@ - /* This one checks to see if we can put data from the - * out_of_order queue into the receive_queue. - */ --static void tcp_ofo_queue(struct sock *sk) -+void tcp_ofo_queue(struct sock *sk) - { - struct tcp_sock *tp = tcp_sk(sk); - __u32 dsack_high = tp->rcv_nxt; -@@ -4511,7 +4559,14 @@ - p = rb_next(p); - rb_erase(&skb->rbnode, &tp->out_of_order_queue); - -- if (unlikely(!after(TCP_SKB_CB(skb)->end_seq, tp->rcv_nxt))) { -+ /* In case of MPTCP, the segment may be empty if it's a -+ * non-data DATA_FIN. (see beginning of tcp_data_queue) -+ * -+ * But this only holds true for subflows, not for the -+ * meta-socket. -+ */ -+ if (unlikely(!after(TCP_SKB_CB(skb)->end_seq, tp->rcv_nxt) && -+ (is_meta_sk(sk) || !mptcp(tp) || TCP_SKB_CB(skb)->end_seq != TCP_SKB_CB(skb)->seq))) { - tcp_drop(sk, skb); - continue; - } -@@ -4541,6 +4596,9 @@ - static int tcp_try_rmem_schedule(struct sock *sk, struct sk_buff *skb, - unsigned int size) - { -+ if (mptcp(tcp_sk(sk))) -+ sk = mptcp_meta_sk(sk); -+ - if (atomic_read(&sk->sk_rmem_alloc) > sk->sk_rcvbuf || - !sk_rmem_schedule(sk, skb, size)) { - -@@ -4555,7 +4613,7 @@ - return 0; - } - --static void tcp_data_queue_ofo(struct sock *sk, struct sk_buff *skb) -+void tcp_data_queue_ofo(struct sock *sk, struct sk_buff *skb) - { - struct tcp_sock *tp = tcp_sk(sk); - struct rb_node **p, *parent; -@@ -4627,7 +4685,8 @@ - continue; - } - if (before(seq, TCP_SKB_CB(skb1)->end_seq)) { -- if (!after(end_seq, TCP_SKB_CB(skb1)->end_seq)) { -+ if (!after(end_seq, TCP_SKB_CB(skb1)->end_seq) && -+ (is_meta_sk(sk) || !mptcp(tp) || end_seq != seq)) { - /* All the bits are present. Drop. */ - NET_INC_STATS(sock_net(sk), - LINUX_MIB_TCPOFOMERGE); -@@ -4674,6 +4733,11 @@ - end_seq); - break; - } -+ /* MPTCP allows non-data data-fin to be in the ofo-queue */ -+ if (mptcp(tp) && !is_meta_sk(sk) && TCP_SKB_CB(skb1)->seq == TCP_SKB_CB(skb1)->end_seq) { -+ skb = skb1; -+ continue; -+ } - rb_erase(&skb1->rbnode, &tp->out_of_order_queue); - tcp_dsack_extend(sk, TCP_SKB_CB(skb1)->seq, - TCP_SKB_CB(skb1)->end_seq); -@@ -4685,7 +4749,7 @@ - tp->ooo_last_skb = skb; - - add_sack: -- if (tcp_is_sack(tp)) -+ if (tcp_is_sack(tp) && seq != end_seq) - tcp_sack_new_ofo_skb(sk, seq, end_seq); - end: - if (skb) { -@@ -4699,8 +4763,8 @@ - } - } - --static int __must_check tcp_queue_rcv(struct sock *sk, struct sk_buff *skb, -- bool *fragstolen) -+int __must_check tcp_queue_rcv(struct sock *sk, struct sk_buff *skb, -+ bool *fragstolen) - { - int eaten; - struct sk_buff *tail = skb_peek_tail(&sk->sk_receive_queue); -@@ -4774,7 +4838,7 @@ - int avail = tp->rcv_nxt - tp->copied_seq; - - if (avail < sk->sk_rcvlowat && !tcp_rmem_pressure(sk) && -- !sock_flag(sk, SOCK_DONE)) -+ !sock_flag(sk, SOCK_DONE) && !mptcp(tp)) - return; - - sk->sk_data_ready(sk); -@@ -4786,10 +4850,14 @@ - bool fragstolen; - int eaten; - -- if (TCP_SKB_CB(skb)->seq == TCP_SKB_CB(skb)->end_seq) { -+ /* If no data is present, but a data_fin is in the options, we still -+ * have to call mptcp_queue_skb later on. */ -+ if (TCP_SKB_CB(skb)->seq == TCP_SKB_CB(skb)->end_seq && -+ !(mptcp(tp) && mptcp_is_data_fin(skb))) { - __kfree_skb(skb); - return; - } -+ - skb_dst_drop(skb); - __skb_pull(skb, tcp_hdr(skb)->doff * 4); - -@@ -4816,7 +4884,7 @@ - } - - eaten = tcp_queue_rcv(sk, skb, &fragstolen); -- if (skb->len) -+ if (skb->len || mptcp_is_data_fin(skb)) - tcp_event_data_recv(sk, skb); - if (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN) - tcp_fin(sk); -@@ -4838,7 +4906,11 @@ - - if (eaten > 0) - kfree_skb_partial(skb, fragstolen); -- if (!sock_flag(sk, SOCK_DEAD)) -+ if (!sock_flag(sk, SOCK_DEAD) || mptcp(tp)) -+ /* MPTCP: we always have to call data_ready, because -+ * we may be about to receive a data-fin, which still -+ * must get queued. -+ */ - tcp_data_ready(sk); - return; - } -@@ -5181,7 +5253,7 @@ - return -1; - } - --static bool tcp_should_expand_sndbuf(const struct sock *sk) -+bool tcp_should_expand_sndbuf(const struct sock *sk) - { - const struct tcp_sock *tp = tcp_sk(sk); - -@@ -5216,7 +5288,7 @@ - { - struct tcp_sock *tp = tcp_sk(sk); - -- if (tcp_should_expand_sndbuf(sk)) { -+ if (tp->ops->should_expand_sndbuf(sk)) { - tcp_sndbuf_expand(sk); - tp->snd_cwnd_stamp = tcp_jiffies32; - } -@@ -5230,10 +5302,11 @@ - sock_reset_flag(sk, SOCK_QUEUE_SHRUNK); - /* pairs with tcp_poll() */ - smp_mb(); -- if (sk->sk_socket && -- test_bit(SOCK_NOSPACE, &sk->sk_socket->flags)) { -+ if (mptcp(tcp_sk(sk)) || -+ (sk->sk_socket && -+ test_bit(SOCK_NOSPACE, &sk->sk_socket->flags))) { - tcp_new_space(sk); -- if (!test_bit(SOCK_NOSPACE, &sk->sk_socket->flags)) -+ if (sk->sk_socket && !test_bit(SOCK_NOSPACE, &sk->sk_socket->flags)) - tcp_chrono_stop(sk, TCP_CHRONO_SNDBUF_LIMITED); - } - } -@@ -5252,6 +5325,8 @@ - { - struct tcp_sock *tp = tcp_sk(sk); - unsigned long rtt, delay; -+ struct sock *meta_sk = mptcp(tp) ? mptcp_meta_sk(sk) : sk; -+ struct tcp_sock *meta_tp = tcp_sk(meta_sk); - - /* More than one full frame received... */ - if (((tp->rcv_nxt - tp->rcv_wup) > inet_csk(sk)->icsk_ack.rcv_mss && -@@ -5260,8 +5335,8 @@ - * If application uses SO_RCVLOWAT, we want send ack now if - * we have not received enough bytes to satisfy the condition. - */ -- (tp->rcv_nxt - tp->copied_seq < sk->sk_rcvlowat || -- __tcp_select_window(sk) >= tp->rcv_wnd)) || -+ (meta_tp->rcv_nxt - meta_tp->copied_seq < meta_sk->sk_rcvlowat || -+ tp->ops->__select_window(sk) >= tp->rcv_wnd)) || - /* We ACK each frame or... */ - tcp_in_quickack_mode(sk) || - /* Protocol state mandates a one-time immediate ACK */ -@@ -5396,6 +5471,10 @@ - { - struct tcp_sock *tp = tcp_sk(sk); - -+ /* MPTCP urgent data is not yet supported */ -+ if (mptcp(tp)) -+ return; -+ - /* Check if we get a new urgent pointer - normally not. */ - if (th->urg) - tcp_check_urg(sk, th); -@@ -5538,9 +5617,15 @@ - goto discard; - } - -+ /* If valid: post process the received MPTCP options. */ -+ if (mptcp(tp) && mptcp_handle_options(sk, th, skb)) -+ goto discard; -+ - return true; - - discard: -+ if (mptcp(tp)) -+ mptcp_reset_mopt(tp); - tcp_drop(sk, skb); - return false; - } -@@ -5597,6 +5682,10 @@ - - tp->rx_opt.saw_tstamp = 0; - -+ /* MPTCP: force slowpath. */ -+ if (mptcp(tp)) -+ goto slow_path; -+ - /* pred_flags is 0xS?10 << 16 + snd_wnd - * if header_prediction is to be made - * 'S' will always be tp->tcp_header_len >> 2 -@@ -5769,7 +5858,7 @@ - - tcp_call_bpf(sk, bpf_op, 0, NULL); - tcp_init_congestion_control(sk); -- tcp_init_buffer_space(sk); -+ tcp_sk(sk)->ops->init_buffer_space(sk); - } - - void tcp_finish_connect(struct sock *sk, struct sk_buff *skb) -@@ -5806,17 +5895,24 @@ - struct tcp_fastopen_cookie *cookie) - { - struct tcp_sock *tp = tcp_sk(sk); -- struct sk_buff *data = tp->syn_data ? tcp_rtx_queue_head(sk) : NULL; -+ struct sk_buff *data = NULL; - u16 mss = tp->rx_opt.mss_clamp, try_exp = 0; - bool syn_drop = false; - -+ if (tp->syn_data) { -+ if (mptcp(tp)) -+ data = tcp_write_queue_head(mptcp_meta_sk(sk)); -+ else -+ data = tcp_rtx_queue_head(sk); -+ } -+ - if (mss == tp->rx_opt.user_mss) { - struct tcp_options_received opt; - - /* Get original SYNACK MSS value if user MSS sets mss_clamp */ - tcp_clear_options(&opt); - opt.user_mss = opt.mss_clamp = 0; -- tcp_parse_options(sock_net(sk), synack, &opt, 0, NULL); -+ tcp_parse_options(sock_net(sk), synack, &opt, NULL, 0, NULL, NULL); - mss = opt.mss_clamp; - } - -@@ -5840,7 +5936,11 @@ - - tcp_fastopen_cache_set(sk, mss, cookie, syn_drop, try_exp); - -- if (data) { /* Retransmit unacked data in SYN */ -+ /* In mptcp case, we do not rely on "retransmit", but instead on -+ * "transmit", because if fastopen data is not acked, the retransmission -+ * becomes the first MPTCP data (see mptcp_rcv_synsent_fastopen). -+ */ -+ if (data && !mptcp(tp)) { /* Retransmit unacked data in SYN */ - skb_rbtree_walk_from(data) { - if (__tcp_retransmit_skb(sk, data, 1)) - break; -@@ -5895,9 +5995,13 @@ - struct tcp_sock *tp = tcp_sk(sk); - struct tcp_fastopen_cookie foc = { .len = -1 }; - int saved_clamp = tp->rx_opt.mss_clamp; -+ struct mptcp_options_received mopt; - bool fastopen_fail; - -- tcp_parse_options(sock_net(sk), skb, &tp->rx_opt, 0, &foc); -+ mptcp_init_mp_opt(&mopt); -+ -+ tcp_parse_options(sock_net(sk), skb, &tp->rx_opt, -+ mptcp(tp) ? &tp->mptcp->rx_opt : &mopt, 0, &foc, tp); - if (tp->rx_opt.saw_tstamp && tp->rx_opt.rcv_tsecr) - tp->rx_opt.rcv_tsecr -= tp->tsoffset; - -@@ -5958,6 +6062,35 @@ - tcp_try_undo_spurious_syn(sk); - tcp_ack(sk, skb, FLAG_SLOWPATH); - -+ if (tp->request_mptcp || mptcp(tp)) { -+ int ret; -+ -+ rcu_read_lock(); -+ local_bh_disable(); -+ ret = mptcp_rcv_synsent_state_process(sk, &sk, -+ skb, &mopt); -+ local_bh_enable(); -+ rcu_read_unlock(); -+ -+ /* May have changed if we support MPTCP */ -+ tp = tcp_sk(sk); -+ icsk = inet_csk(sk); -+ -+ if (ret == 1) -+ goto reset_and_undo; -+ if (ret == 2) -+ goto discard; -+ } -+ -+ if (mptcp(tp) && !is_master_tp(tp)) { -+ /* Timer for repeating the ACK until an answer -+ * arrives. Used only when establishing an additional -+ * subflow inside of an MPTCP connection. -+ */ -+ sk_reset_timer(sk, &tp->mptcp->mptcp_ack_timer, -+ jiffies + icsk->icsk_rto); -+ } -+ - /* Ok.. it's good. Set up sequence numbers and - * move to established. - */ -@@ -5984,6 +6117,11 @@ - tp->tcp_header_len = sizeof(struct tcphdr); - } - -+ if (mptcp(tp)) { -+ tp->tcp_header_len += MPTCP_SUB_LEN_DSM_ALIGN; -+ tp->advmss -= MPTCP_SUB_LEN_DSM_ALIGN; -+ } -+ - tcp_sync_mss(sk, icsk->icsk_pmtu_cookie); - tcp_initialize_rcv_mss(sk); - -@@ -6007,9 +6145,12 @@ - } - if (fastopen_fail) - return -1; -- if (sk->sk_write_pending || -+ /* With MPTCP we cannot send data on the third ack due to the -+ * lack of option-space to combine with an MP_CAPABLE. -+ */ -+ if (!mptcp(tp) && (sk->sk_write_pending || - icsk->icsk_accept_queue.rskq_defer_accept || -- inet_csk_in_pingpong_mode(sk)) { -+ inet_csk_in_pingpong_mode(sk))) { - /* Save one ACK. Data will be ready after - * several ticks, if write_pending is set. - * -@@ -6048,6 +6189,7 @@ - tcp_paws_reject(&tp->rx_opt, 0)) - goto discard_and_undo; - -+ /* TODO - check this here for MPTCP */ - if (th->syn) { - /* We see SYN without ACK. It is attempt of - * simultaneous connect with crossed SYNs. -@@ -6064,6 +6206,11 @@ - tp->tcp_header_len = sizeof(struct tcphdr); - } - -+ if (mptcp(tp)) { -+ tp->tcp_header_len += MPTCP_SUB_LEN_DSM_ALIGN; -+ tp->advmss -= MPTCP_SUB_LEN_DSM_ALIGN; -+ } -+ - WRITE_ONCE(tp->rcv_nxt, TCP_SKB_CB(skb)->seq + 1); - WRITE_ONCE(tp->copied_seq, tp->rcv_nxt); - tp->rcv_wup = TCP_SKB_CB(skb)->seq + 1; -@@ -6154,6 +6301,7 @@ - */ - - int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb) -+ __releases(&sk->sk_lock.slock) - { - struct tcp_sock *tp = tcp_sk(sk); - struct inet_connection_sock *icsk = inet_csk(sk); -@@ -6196,6 +6344,16 @@ - tp->rx_opt.saw_tstamp = 0; - tcp_mstamp_refresh(tp); - queued = tcp_rcv_synsent_state_process(sk, skb, th); -+ if (is_meta_sk(sk)) { -+ sk = tcp_sk(sk)->mpcb->master_sk; -+ tp = tcp_sk(sk); -+ -+ /* Need to call it here, because it will announce new -+ * addresses, which can only be done after the third ack -+ * of the 3-way handshake. -+ */ -+ mptcp_update_metasocket(tp->meta_sk); -+ } - if (queued >= 0) - return queued; - -@@ -6268,6 +6426,8 @@ - - if (tp->rx_opt.tstamp_ok) - tp->advmss -= TCPOLEN_TSTAMP_ALIGNED; -+ if (mptcp(tp)) -+ tp->advmss -= MPTCP_SUB_LEN_DSM_ALIGN; - - if (!inet_csk(sk)->icsk_ca_ops->cong_control) - tcp_update_pacing_rate(sk); -@@ -6277,6 +6437,30 @@ - - tcp_initialize_rcv_mss(sk); - tcp_fast_path_on(tp); -+ -+ /* Send an ACK when establishing a new MPTCP subflow, i.e. -+ * using an MP_JOIN subtype. -+ */ -+ if (mptcp(tp)) { -+ if (is_master_tp(tp)) { -+ mptcp_update_metasocket(mptcp_meta_sk(sk)); -+ } else { -+ struct sock *meta_sk = mptcp_meta_sk(sk); -+ -+ tcp_send_ack(sk); -+ -+ /* Update RTO as it might be worse/better */ -+ mptcp_set_rto(sk); -+ -+ /* If the new RTO would fire earlier, pull it in! */ -+ if (tcp_sk(meta_sk)->packets_out && -+ icsk->icsk_timeout > inet_csk(meta_sk)->icsk_rto + jiffies) { -+ tcp_rearm_rto(meta_sk); -+ } -+ -+ mptcp_push_pending_frames(mptcp_meta_sk(sk)); -+ } -+ } - break; - - case TCP_FIN_WAIT1: { -@@ -6317,7 +6501,8 @@ - tmo = tcp_fin_time(sk); - if (tmo > TCP_TIMEWAIT_LEN) { - inet_csk_reset_keepalive_timer(sk, tmo - TCP_TIMEWAIT_LEN); -- } else if (th->fin || sock_owned_by_user(sk)) { -+ } else if (th->fin || mptcp_is_data_fin(skb) || -+ sock_owned_by_user(sk)) { - /* Bad case. We could lose such FIN otherwise. - * It is not a big problem, but it looks confusing - * and not so rare event. We still can lose it now, -@@ -6326,7 +6511,7 @@ - */ - inet_csk_reset_keepalive_timer(sk, tmo); - } else { -- tcp_time_wait(sk, TCP_FIN_WAIT2, tmo); -+ tp->ops->time_wait(sk, TCP_FIN_WAIT2, tmo); - goto discard; - } - break; -@@ -6334,7 +6519,7 @@ - - case TCP_CLOSING: - if (tp->snd_una == tp->write_seq) { -- tcp_time_wait(sk, TCP_TIME_WAIT, 0); -+ tp->ops->time_wait(sk, TCP_TIME_WAIT, 0); - goto discard; - } - break; -@@ -6346,6 +6531,9 @@ - goto discard; - } - break; -+ case TCP_CLOSE: -+ if (tp->mp_killed) -+ goto discard; - } - - /* step 6: check the URG bit */ -@@ -6367,7 +6555,8 @@ - */ - if (sk->sk_shutdown & RCV_SHUTDOWN) { - if (TCP_SKB_CB(skb)->end_seq != TCP_SKB_CB(skb)->seq && -- after(TCP_SKB_CB(skb)->end_seq - th->fin, tp->rcv_nxt)) { -+ after(TCP_SKB_CB(skb)->end_seq - th->fin, tp->rcv_nxt) && -+ !mptcp(tp)) { - NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPABORTONDATA); - tcp_reset(sk); - return 1; -@@ -6469,6 +6658,8 @@ - ireq->wscale_ok = rx_opt->wscale_ok; - ireq->acked = 0; - ireq->ecn_ok = 0; -+ ireq->mptcp_rqsk = 0; -+ ireq->saw_mpc = 0; - ireq->ir_rmt_port = tcp_hdr(skb)->source; - ireq->ir_num = ntohs(tcp_hdr(skb)->dest); - ireq->ir_mark = inet_request_mark(sk, skb); -@@ -6594,12 +6785,17 @@ - /* TW buckets are converted to open requests without - * limitations, they conserve resources and peer is - * evidently real one. -+ * -+ * MPTCP: new subflows cannot be established in a stateless manner. - */ -- if ((net->ipv4.sysctl_tcp_syncookies == 2 || -+ if (((!is_meta_sk(sk) && net->ipv4.sysctl_tcp_syncookies == 2) || - inet_csk_reqsk_queue_is_full(sk)) && !isn) { - want_cookie = tcp_syn_flood_action(sk, rsk_ops->slab_name); - if (!want_cookie) - goto drop; -+ -+ if (is_meta_sk(sk)) -+ goto drop; - } - - if (sk_acceptq_is_full(sk)) { -@@ -6617,8 +6813,8 @@ - tcp_clear_options(&tmp_opt); - tmp_opt.mss_clamp = af_ops->mss_clamp; - tmp_opt.user_mss = tp->rx_opt.user_mss; -- tcp_parse_options(sock_net(sk), skb, &tmp_opt, 0, -- want_cookie ? NULL : &foc); -+ tcp_parse_options(sock_net(sk), skb, &tmp_opt, NULL, 0, -+ want_cookie ? NULL : &foc, NULL); - - if (want_cookie && !tmp_opt.saw_tstamp) - tcp_clear_options(&tmp_opt); -@@ -6633,7 +6829,8 @@ - /* Note: tcp_v6_init_req() might override ir_iif for link locals */ - inet_rsk(req)->ir_iif = inet_request_bound_dev_if(sk, skb); - -- af_ops->init_req(req, sk, skb); -+ if (af_ops->init_req(req, sk, skb, want_cookie)) -+ goto drop_and_free; - - if (security_inet_conn_request(sk, skb, req)) - goto drop_and_free; -@@ -6669,7 +6866,7 @@ - tcp_ecn_create_request(req, skb, sk, dst); - - if (want_cookie) { -- isn = cookie_init_sequence(af_ops, sk, skb, &req->mss); -+ isn = cookie_init_sequence(af_ops, req, sk, skb, &req->mss); - req->cookie_ts = tmp_opt.tstamp_ok; - if (!tmp_opt.tstamp_ok) - inet_rsk(req)->ecn_ok = 0; -@@ -6684,17 +6881,25 @@ - fastopen_sk = tcp_try_fastopen(sk, skb, req, &foc, dst); - } - if (fastopen_sk) { -+ struct sock *meta_sk = fastopen_sk; -+ -+ if (mptcp(tcp_sk(fastopen_sk))) -+ meta_sk = mptcp_meta_sk(fastopen_sk); - af_ops->send_synack(fastopen_sk, dst, &fl, req, - &foc, TCP_SYNACK_FASTOPEN); - /* Add the child socket directly into the accept queue */ -- if (!inet_csk_reqsk_queue_add(sk, req, fastopen_sk)) { -+ if (!inet_csk_reqsk_queue_add(sk, req, meta_sk)) { - reqsk_fastopen_remove(fastopen_sk, req, false); - bh_unlock_sock(fastopen_sk); -+ if (meta_sk != fastopen_sk) -+ bh_unlock_sock(meta_sk); - sock_put(fastopen_sk); - goto drop_and_free; - } - sk->sk_data_ready(sk); - bh_unlock_sock(fastopen_sk); -+ if (meta_sk != fastopen_sk) -+ bh_unlock_sock(meta_sk); - sock_put(fastopen_sk); - } else { - tcp_rsk(req)->tfo_listener = false; -diff -aurN linux-5.4.64/net/ipv4/tcp_ipv4.c linux-5.4.64.mptcp/net/ipv4/tcp_ipv4.c ---- linux-5.4.64/net/ipv4/tcp_ipv4.c 2020-09-09 19:12:37.000000000 +0200 -+++ linux-5.4.64.mptcp/net/ipv4/tcp_ipv4.c 2020-09-10 19:25:10.503220935 +0200 -@@ -62,6 +62,8 @@ - #include - #include - #include -+#include -+#include - #include - #include - #include -@@ -209,6 +211,8 @@ - struct ip_options_rcu *inet_opt; - struct inet_timewait_death_row *tcp_death_row = &sock_net(sk)->ipv4.tcp_death_row; - -+ mptcp_init_connect(sk); -+ - if (addr_len < sizeof(struct sockaddr_in)) - return -EINVAL; - -@@ -430,7 +434,7 @@ - struct inet_sock *inet; - const int type = icmp_hdr(icmp_skb)->type; - const int code = icmp_hdr(icmp_skb)->code; -- struct sock *sk; -+ struct sock *sk, *meta_sk; - struct sk_buff *skb; - struct request_sock *fastopen; - u32 seq, snd_una; -@@ -460,13 +464,19 @@ - return 0; - } - -- bh_lock_sock(sk); -+ tp = tcp_sk(sk); -+ if (mptcp(tp)) -+ meta_sk = mptcp_meta_sk(sk); -+ else -+ meta_sk = sk; -+ -+ bh_lock_sock(meta_sk); - /* If too many ICMPs get dropped on busy - * servers this needs to be solved differently. - * We do take care of PMTU discovery (RFC1191) special case : - * we can receive locally generated ICMP messages while socket is held. - */ -- if (sock_owned_by_user(sk)) { -+ if (sock_owned_by_user(meta_sk)) { - if (!(type == ICMP_DEST_UNREACH && code == ICMP_FRAG_NEEDED)) - __NET_INC_STATS(net, LINUX_MIB_LOCKDROPPEDICMPS); - } -@@ -479,7 +489,6 @@ - } - - icsk = inet_csk(sk); -- tp = tcp_sk(sk); - /* XXX (TFO) - tp->snd_una should be ISN (tcp_create_openreq_child() */ - fastopen = rcu_dereference(tp->fastopen_rsk); - snd_una = fastopen ? tcp_rsk(fastopen)->snt_isn : tp->snd_una; -@@ -513,11 +522,13 @@ - goto out; - - tp->mtu_info = info; -- if (!sock_owned_by_user(sk)) { -+ if (!sock_owned_by_user(meta_sk)) { - tcp_v4_mtu_reduced(sk); - } else { - if (!test_and_set_bit(TCP_MTU_REDUCED_DEFERRED, &sk->sk_tsq_flags)) - sock_hold(sk); -+ if (mptcp(tp)) -+ mptcp_tsq_flags(sk); - } - goto out; - } -@@ -531,7 +542,7 @@ - !icsk->icsk_backoff || fastopen) - break; - -- if (sock_owned_by_user(sk)) -+ if (sock_owned_by_user(meta_sk)) - break; - - skb = tcp_rtx_queue_head(sk); -@@ -555,7 +566,7 @@ - } else { - /* RTO revert clocked out retransmission. - * Will retransmit now */ -- tcp_retransmit_timer(sk); -+ tcp_sk(sk)->ops->retransmit_timer(sk); - } - - break; -@@ -575,7 +586,7 @@ - if (fastopen && !fastopen->sk) - break; - -- if (!sock_owned_by_user(sk)) { -+ if (!sock_owned_by_user(meta_sk)) { - sk->sk_err = err; - - sk->sk_error_report(sk); -@@ -604,7 +615,7 @@ - */ - - inet = inet_sk(sk); -- if (!sock_owned_by_user(sk) && inet->recverr) { -+ if (!sock_owned_by_user(meta_sk) && inet->recverr) { - sk->sk_err = err; - sk->sk_error_report(sk); - } else { /* Only an error on timeout */ -@@ -612,7 +623,7 @@ - } - - out: -- bh_unlock_sock(sk); -+ bh_unlock_sock(meta_sk); - sock_put(sk); - return 0; - } -@@ -648,7 +659,7 @@ - * Exception: precedence violation. We do not implement it in any case. - */ - --static void tcp_v4_send_reset(const struct sock *sk, struct sk_buff *skb) -+void tcp_v4_send_reset(const struct sock *sk, struct sk_buff *skb) - { - const struct tcphdr *th = tcp_hdr(skb); - struct { -@@ -800,10 +811,10 @@ - */ - - static void tcp_v4_send_ack(const struct sock *sk, -- struct sk_buff *skb, u32 seq, u32 ack, -+ struct sk_buff *skb, u32 seq, u32 ack, u32 data_ack, - u32 win, u32 tsval, u32 tsecr, int oif, - struct tcp_md5sig_key *key, -- int reply_flags, u8 tos) -+ int reply_flags, u8 tos, int mptcp) - { - const struct tcphdr *th = tcp_hdr(skb); - struct { -@@ -812,6 +823,10 @@ - #ifdef CONFIG_TCP_MD5SIG - + (TCPOLEN_MD5SIG_ALIGNED >> 2) - #endif -+#ifdef CONFIG_MPTCP -+ + ((MPTCP_SUB_LEN_DSS >> 2) + -+ (MPTCP_SUB_LEN_ACK >> 2)) -+#endif - ]; - } rep; - struct net *net = sock_net(sk); -@@ -858,6 +873,21 @@ - ip_hdr(skb)->daddr, &rep.th); - } - #endif -+#ifdef CONFIG_MPTCP -+ if (mptcp) { -+ int offset = (tsecr) ? 3 : 0; -+ /* Construction of 32-bit data_ack */ -+ rep.opt[offset++] = htonl((TCPOPT_MPTCP << 24) | -+ ((MPTCP_SUB_LEN_DSS + MPTCP_SUB_LEN_ACK) << 16) | -+ (0x20 << 8) | -+ (0x01)); -+ rep.opt[offset] = htonl(data_ack); -+ -+ arg.iov[0].iov_len += MPTCP_SUB_LEN_DSS + MPTCP_SUB_LEN_ACK; -+ rep.th.doff = arg.iov[0].iov_len / 4; -+ } -+#endif /* CONFIG_MPTCP */ -+ - arg.flags = reply_flags; - arg.csum = csum_tcpudp_nofold(ip_hdr(skb)->daddr, - ip_hdr(skb)->saddr, /* XXX */ -@@ -889,28 +919,36 @@ - { - struct inet_timewait_sock *tw = inet_twsk(sk); - struct tcp_timewait_sock *tcptw = tcp_twsk(sk); -+ u32 data_ack = 0; -+ int mptcp = 0; -+ -+ if (tcptw->mptcp_tw) { -+ data_ack = (u32)tcptw->mptcp_tw->rcv_nxt; -+ mptcp = 1; -+ } - - tcp_v4_send_ack(sk, skb, -- tcptw->tw_snd_nxt, tcptw->tw_rcv_nxt, -+ tcptw->tw_snd_nxt, tcptw->tw_rcv_nxt, data_ack, - tcptw->tw_rcv_wnd >> tw->tw_rcv_wscale, - tcp_time_stamp_raw() + tcptw->tw_ts_offset, - tcptw->tw_ts_recent, - tw->tw_bound_dev_if, - tcp_twsk_md5_key(tcptw), - tw->tw_transparent ? IP_REPLY_ARG_NOSRCCHECK : 0, -- tw->tw_tos -+ tw->tw_tos, mptcp - ); - - inet_twsk_put(tw); - } - --static void tcp_v4_reqsk_send_ack(const struct sock *sk, struct sk_buff *skb, -- struct request_sock *req) -+void tcp_v4_reqsk_send_ack(const struct sock *sk, struct sk_buff *skb, -+ struct request_sock *req) - { - /* sk->sk_state == TCP_LISTEN -> for regular TCP_SYN_RECV - * sk->sk_state == TCP_SYN_RECV -> for Fast Open. - */ -- u32 seq = (sk->sk_state == TCP_LISTEN) ? tcp_rsk(req)->snt_isn + 1 : -+ u32 seq = (sk->sk_state == TCP_LISTEN || is_meta_sk(sk)) ? -+ tcp_rsk(req)->snt_isn + 1 : - tcp_sk(sk)->snd_nxt; - - /* RFC 7323 2.3 -@@ -919,7 +957,7 @@ - * Rcv.Wind.Shift bits: - */ - tcp_v4_send_ack(sk, skb, seq, -- tcp_rsk(req)->rcv_nxt, -+ tcp_rsk(req)->rcv_nxt, 0, - req->rsk_rcv_wnd >> inet_rsk(req)->rcv_wscale, - tcp_time_stamp_raw() + tcp_rsk(req)->ts_off, - req->ts_recent, -@@ -927,7 +965,7 @@ - tcp_md5_do_lookup(sk, (union tcp_md5_addr *)&ip_hdr(skb)->saddr, - AF_INET), - inet_rsk(req)->no_srccheck ? IP_REPLY_ARG_NOSRCCHECK : 0, -- ip_hdr(skb)->tos); -+ ip_hdr(skb)->tos, 0); - } - - /* -@@ -935,11 +973,11 @@ - * This still operates on a request_sock only, not on a big - * socket. - */ --static int tcp_v4_send_synack(const struct sock *sk, struct dst_entry *dst, -- struct flowi *fl, -- struct request_sock *req, -- struct tcp_fastopen_cookie *foc, -- enum tcp_synack_type synack_type) -+int tcp_v4_send_synack(const struct sock *sk, struct dst_entry *dst, -+ struct flowi *fl, -+ struct request_sock *req, -+ struct tcp_fastopen_cookie *foc, -+ enum tcp_synack_type synack_type) - { - const struct inet_request_sock *ireq = inet_rsk(req); - struct flowi4 fl4; -@@ -969,7 +1007,7 @@ - /* - * IPv4 request_sock destructor. - */ --static void tcp_v4_reqsk_destructor(struct request_sock *req) -+void tcp_v4_reqsk_destructor(struct request_sock *req) - { - kfree(rcu_dereference_protected(inet_rsk(req)->ireq_opt, 1)); - } -@@ -1354,9 +1392,10 @@ - return false; - } - --static void tcp_v4_init_req(struct request_sock *req, -- const struct sock *sk_listener, -- struct sk_buff *skb) -+static int tcp_v4_init_req(struct request_sock *req, -+ const struct sock *sk_listener, -+ struct sk_buff *skb, -+ bool want_cookie) - { - struct inet_request_sock *ireq = inet_rsk(req); - struct net *net = sock_net(sk_listener); -@@ -1364,6 +1403,8 @@ - sk_rcv_saddr_set(req_to_sk(req), ip_hdr(skb)->daddr); - sk_daddr_set(req_to_sk(req), ip_hdr(skb)->saddr); - RCU_INIT_POINTER(ireq->ireq_opt, tcp_v4_save_options(net, skb)); -+ -+ return 0; - } - - static struct dst_entry *tcp_v4_route_req(const struct sock *sk, -@@ -1383,7 +1424,7 @@ - .syn_ack_timeout = tcp_syn_ack_timeout, - }; - --static const struct tcp_request_sock_ops tcp_request_sock_ipv4_ops = { -+const struct tcp_request_sock_ops tcp_request_sock_ipv4_ops = { - .mss_clamp = TCP_MSS_DEFAULT, - #ifdef CONFIG_TCP_MD5SIG - .req_md5_lookup = tcp_v4_md5_lookup, -@@ -1520,7 +1561,7 @@ - } - EXPORT_SYMBOL(tcp_v4_syn_recv_sock); - --static struct sock *tcp_v4_cookie_check(struct sock *sk, struct sk_buff *skb) -+struct sock *tcp_v4_cookie_check(struct sock *sk, struct sk_buff *skb) - { - #ifdef CONFIG_SYN_COOKIES - const struct tcphdr *th = tcp_hdr(skb); -@@ -1558,6 +1599,9 @@ - { - struct sock *rsk; - -+ if (is_meta_sk(sk)) -+ return mptcp_v4_do_rcv(sk, skb); -+ - if (sk->sk_state == TCP_ESTABLISHED) { /* Fast path */ - struct dst_entry *dst = sk->sk_rx_dst; - -@@ -1802,6 +1846,10 @@ - TCP_SKB_CB(skb)->end_seq = (TCP_SKB_CB(skb)->seq + th->syn + th->fin + - skb->len - th->doff * 4); - TCP_SKB_CB(skb)->ack_seq = ntohl(th->ack_seq); -+#ifdef CONFIG_MPTCP -+ TCP_SKB_CB(skb)->mptcp_flags = 0; -+ TCP_SKB_CB(skb)->dss_off = 0; -+#endif - TCP_SKB_CB(skb)->tcp_flags = tcp_flag_byte(th); - TCP_SKB_CB(skb)->tcp_tw_isn = 0; - TCP_SKB_CB(skb)->ip_dsfield = ipv4_get_dsfield(iph); -@@ -1821,8 +1869,8 @@ - int sdif = inet_sdif(skb); - const struct iphdr *iph; - const struct tcphdr *th; -+ struct sock *sk, *meta_sk = NULL; - bool refcounted; -- struct sock *sk; - int ret; - - if (skb->pkt_type != PACKET_HOST) -@@ -1876,7 +1924,11 @@ - reqsk_put(req); - goto csum_error; - } -- if (unlikely(sk->sk_state != TCP_LISTEN)) { -+ if (unlikely(sk->sk_state != TCP_LISTEN && !is_meta_sk(sk))) { -+ inet_csk_reqsk_queue_drop_and_put(sk, req); -+ goto lookup; -+ } -+ if (unlikely(is_meta_sk(sk) && !mptcp_can_new_subflow(sk))) { - inet_csk_reqsk_queue_drop_and_put(sk, req); - goto lookup; - } -@@ -1885,6 +1937,7 @@ - */ - sock_hold(sk); - refcounted = true; -+ - nsk = NULL; - if (!tcp_filter(sk, skb)) { - th = (const struct tcphdr *)skb->data; -@@ -1945,19 +1998,28 @@ - - sk_incoming_cpu_update(sk); - -- bh_lock_sock_nested(sk); -+ if (mptcp(tcp_sk(sk))) { -+ meta_sk = mptcp_meta_sk(sk); -+ -+ bh_lock_sock_nested(meta_sk); -+ if (sock_owned_by_user(meta_sk)) -+ mptcp_prepare_for_backlog(sk, skb); -+ } else { -+ meta_sk = sk; -+ bh_lock_sock_nested(sk); -+ } - tcp_segs_in(tcp_sk(sk), skb); - ret = 0; -- if (!sock_owned_by_user(sk)) { -+ if (!sock_owned_by_user(meta_sk)) { - skb_to_free = sk->sk_rx_skb_cache; - sk->sk_rx_skb_cache = NULL; - ret = tcp_v4_do_rcv(sk, skb); - } else { -- if (tcp_add_backlog(sk, skb)) -+ if (tcp_add_backlog(meta_sk, skb)) - goto discard_and_relse; - skb_to_free = NULL; - } -- bh_unlock_sock(sk); -+ bh_unlock_sock(meta_sk); - if (skb_to_free) - __kfree_skb(skb_to_free); - -@@ -1973,6 +2035,19 @@ - - tcp_v4_fill_cb(skb, iph, th); - -+#ifdef CONFIG_MPTCP -+ if (!sk && th->syn && !th->ack) { -+ int ret = mptcp_lookup_join(skb, NULL); -+ -+ if (ret < 0) { -+ tcp_v4_send_reset(NULL, skb); -+ goto discard_it; -+ } else if (ret > 0) { -+ return 0; -+ } -+ } -+#endif -+ - if (tcp_checksum_complete(skb)) { - csum_error: - __TCP_INC_STATS(net, TCP_MIB_CSUMERRORS); -@@ -2021,6 +2096,18 @@ - refcounted = false; - goto process; - } -+#ifdef CONFIG_MPTCP -+ if (th->syn && !th->ack) { -+ int ret = mptcp_lookup_join(skb, inet_twsk(sk)); -+ -+ if (ret < 0) { -+ tcp_v4_send_reset(NULL, skb); -+ goto discard_it; -+ } else if (ret > 0) { -+ return 0; -+ } -+ } -+#endif - } - /* to ACK */ - /* fall through */ -@@ -2090,7 +2177,12 @@ - - tcp_init_sock(sk); - -- icsk->icsk_af_ops = &ipv4_specific; -+#ifdef CONFIG_MPTCP -+ if (sock_flag(sk, SOCK_MPTCP)) -+ icsk->icsk_af_ops = &mptcp_v4_specific; -+ else -+#endif -+ icsk->icsk_af_ops = &ipv4_specific; - - #ifdef CONFIG_TCP_MD5SIG - tcp_sk(sk)->af_specific = &tcp_sock_ipv4_specific; -@@ -2109,6 +2201,11 @@ - - tcp_cleanup_congestion_control(sk); - -+ if (mptcp(tp)) -+ mptcp_destroy_sock(sk); -+ if (tp->inside_tk_table) -+ mptcp_hash_remove_bh(tp); -+ - tcp_cleanup_ulp(sk); - - /* Cleanup up the write buffer. */ -@@ -2613,6 +2710,11 @@ - .sysctl_rmem_offset = offsetof(struct net, ipv4.sysctl_tcp_rmem), - .max_header = MAX_TCP_HEADER, - .obj_size = sizeof(struct tcp_sock), -+#ifdef CONFIG_MPTCP -+ .useroffset = offsetof(struct tcp_sock, mptcp_sched_name), -+ .usersize = sizeof_field(struct tcp_sock, mptcp_sched_name) + -+ sizeof_field(struct tcp_sock, mptcp_pm_name), -+#endif - .slab_flags = SLAB_TYPESAFE_BY_RCU, - .twsk_prot = &tcp_timewait_sock_ops, - .rsk_prot = &tcp_request_sock_ops, -@@ -2623,6 +2725,9 @@ - .compat_getsockopt = compat_tcp_getsockopt, - #endif - .diag_destroy = tcp_abort, -+#ifdef CONFIG_MPTCP -+ .clear_sk = mptcp_clear_sk, -+#endif - }; - EXPORT_SYMBOL(tcp_prot); - -diff -aurN linux-5.4.64/net/ipv4/tcp_minisocks.c linux-5.4.64.mptcp/net/ipv4/tcp_minisocks.c ---- linux-5.4.64/net/ipv4/tcp_minisocks.c 2020-09-09 19:12:37.000000000 +0200 -+++ linux-5.4.64.mptcp/net/ipv4/tcp_minisocks.c 2020-09-10 19:25:10.503220935 +0200 -@@ -19,11 +19,13 @@ - * Jorge Cwik, - */ - -+#include - #include - #include - #include - #include - #include -+#include - #include - #include - #include -@@ -95,10 +97,14 @@ - struct tcp_options_received tmp_opt; - struct tcp_timewait_sock *tcptw = tcp_twsk((struct sock *)tw); - bool paws_reject = false; -+ struct mptcp_options_received mopt; - - tmp_opt.saw_tstamp = 0; -- if (th->doff > (sizeof(*th) >> 2) && tcptw->tw_ts_recent_stamp) { -- tcp_parse_options(twsk_net(tw), skb, &tmp_opt, 0, NULL); -+ if (th->doff > (sizeof(*th) >> 2) && -+ (tcptw->tw_ts_recent_stamp || tcptw->mptcp_tw)) { -+ mptcp_init_mp_opt(&mopt); -+ -+ tcp_parse_options(twsk_net(tw), skb, &tmp_opt, &mopt, 0, NULL, NULL); - - if (tmp_opt.saw_tstamp) { - if (tmp_opt.rcv_tsecr) -@@ -107,6 +113,11 @@ - tmp_opt.ts_recent_stamp = tcptw->tw_ts_recent_stamp; - paws_reject = tcp_paws_reject(&tmp_opt, th->rst); - } -+ -+ if (unlikely(mopt.mp_fclose) && tcptw->mptcp_tw) { -+ if (mopt.mptcp_sender_key == tcptw->mptcp_tw->loc_key) -+ return TCP_TW_RST; -+ } - } - - if (tw->tw_substate == TCP_FIN_WAIT2) { -@@ -130,6 +141,16 @@ - if (!th->ack || - !after(TCP_SKB_CB(skb)->end_seq, tcptw->tw_rcv_nxt) || - TCP_SKB_CB(skb)->end_seq == TCP_SKB_CB(skb)->seq) { -+ /* If mptcp_is_data_fin() returns true, we are sure that -+ * mopt has been initialized - otherwise it would not -+ * be a DATA_FIN. -+ */ -+ if (tcptw->mptcp_tw && tcptw->mptcp_tw->meta_tw && -+ mptcp_is_data_fin(skb) && -+ TCP_SKB_CB(skb)->seq == tcptw->tw_rcv_nxt && -+ mopt.data_seq + 1 == (u32)tcptw->mptcp_tw->rcv_nxt) -+ return TCP_TW_ACK; -+ - inet_twsk_put(tw); - return TCP_TW_SUCCESS; - } -@@ -275,6 +296,16 @@ - tcptw->tw_ts_recent_stamp = tp->rx_opt.ts_recent_stamp; - tcptw->tw_ts_offset = tp->tsoffset; - tcptw->tw_last_oow_ack_time = 0; -+ -+ if (mptcp(tp)) { -+ if (mptcp_init_tw_sock(sk, tcptw)) { -+ inet_twsk_free(tw); -+ goto exit; -+ } -+ } else { -+ tcptw->mptcp_tw = NULL; -+ } -+ - tcptw->tw_tx_delay = tp->tcp_tx_delay; - #if IS_ENABLED(CONFIG_IPV6) - if (tw->tw_family == PF_INET6) { -@@ -336,6 +367,7 @@ - NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPTIMEWAITOVERFLOW); - } - -+exit: - tcp_update_metrics(sk); - tcp_done(sk); - } -@@ -343,6 +375,10 @@ - - void tcp_twsk_destructor(struct sock *sk) - { -+ struct tcp_timewait_sock *twsk = tcp_twsk(sk); -+ -+ if (twsk->mptcp_tw) -+ mptcp_twsk_destructor(twsk); - #ifdef CONFIG_TCP_MD5SIG - if (static_branch_unlikely(&tcp_md5_needed)) { - struct tcp_timewait_sock *twsk = tcp_twsk(sk); -@@ -386,8 +422,9 @@ - full_space = rcv_wnd * mss; - - /* tcp_full_space because it is guaranteed to be the first packet */ -- tcp_select_initial_window(sk_listener, full_space, -- mss - (ireq->tstamp_ok ? TCPOLEN_TSTAMP_ALIGNED : 0), -+ tp->ops->select_initial_window(sk_listener, full_space, -+ mss - (ireq->tstamp_ok ? TCPOLEN_TSTAMP_ALIGNED : 0) - -+ (ireq->saw_mpc ? MPTCP_SUB_LEN_DSM_ALIGN : 0), - &req->rsk_rcv_wnd, - &req->rsk_window_clamp, - ireq->wscale_ok, -@@ -487,6 +524,8 @@ - WRITE_ONCE(newtp->snd_nxt, seq); - newtp->snd_up = seq; - -+ newtp->out_of_order_queue = RB_ROOT; -+ newsk->tcp_rtx_queue = RB_ROOT; - INIT_LIST_HEAD(&newtp->tsq_node); - INIT_LIST_HEAD(&newtp->tsorted_sent_queue); - -@@ -530,6 +569,8 @@ - newtp->rx_opt.ts_recent_stamp = 0; - newtp->tcp_header_len = sizeof(struct tcphdr); - } -+ if (ireq->saw_mpc) -+ newtp->tcp_header_len += MPTCP_SUB_LEN_DSM_ALIGN; - if (req->num_timeout) { - newtp->undo_marker = treq->snt_isn; - newtp->retrans_stamp = div_u64(treq->snt_synack, -@@ -547,6 +588,7 @@ - tcp_ecn_openreq_child(newtp, req); - newtp->fastopen_req = NULL; - RCU_INIT_POINTER(newtp->fastopen_rsk, NULL); -+ newtp->inside_tk_table = 0; - - __TCP_INC_STATS(sock_net(sk), TCP_MIB_PASSIVEOPENS); - -@@ -570,15 +612,20 @@ - bool fastopen, bool *req_stolen) - { - struct tcp_options_received tmp_opt; -+ struct mptcp_options_received mopt; - struct sock *child; - const struct tcphdr *th = tcp_hdr(skb); - __be32 flg = tcp_flag_word(th) & (TCP_FLAG_RST|TCP_FLAG_SYN|TCP_FLAG_ACK); - bool paws_reject = false; - bool own_req; -+ bool meta_locked = false; - - tmp_opt.saw_tstamp = 0; -+ -+ mptcp_init_mp_opt(&mopt); -+ - if (th->doff > (sizeof(struct tcphdr)>>2)) { -- tcp_parse_options(sock_net(sk), skb, &tmp_opt, 0, NULL); -+ tcp_parse_options(sock_net(sk), skb, &tmp_opt, &mopt, 0, NULL, NULL); - - if (tmp_opt.saw_tstamp) { - tmp_opt.ts_recent = req->ts_recent; -@@ -619,7 +666,14 @@ - * - * Reset timer after retransmitting SYNACK, similar to - * the idea of fast retransmit in recovery. -+ * -+ * Fall back to TCP if MP_CAPABLE is not set. - */ -+ -+ if (inet_rsk(req)->saw_mpc && !mopt.saw_mpc) -+ inet_rsk(req)->saw_mpc = false; -+ -+ - if (!tcp_oow_rate_limited(sock_net(sk), skb, - LINUX_MIB_TCPACKSKIPPEDSYNRECV, - &tcp_rsk(req)->last_oow_ack_time) && -@@ -767,17 +821,40 @@ - * ESTABLISHED STATE. If it will be dropped after - * socket is created, wait for troubles. - */ -+ if (is_meta_sk(sk)) { -+ bh_lock_sock_nested(sk); -+ meta_locked = true; -+ } - child = inet_csk(sk)->icsk_af_ops->syn_recv_sock(sk, skb, req, NULL, - req, &own_req); - if (!child) - goto listen_overflow; - -+ if (own_req && !is_meta_sk(sk)) { -+ int ret = mptcp_check_req_master(sk, child, req, skb, &mopt, 1, 0); -+ if (ret < 0) -+ goto listen_overflow; -+ -+ /* MPTCP-supported */ -+ if (!ret) -+ return tcp_sk(child)->mpcb->master_sk; -+ } else if (own_req) { -+ return mptcp_check_req_child(sk, child, req, skb, &mopt); -+ } -+ -+ if (meta_locked) -+ bh_unlock_sock(sk); -+ - sock_rps_save_rxhash(child, skb); - tcp_synack_rtt_meas(child, req); - *req_stolen = !own_req; -+ - return inet_csk_complete_hashdance(sk, child, req, own_req); - - listen_overflow: -+ if (meta_locked) -+ bh_unlock_sock(sk); -+ - if (!sock_net(sk)->ipv4.sysctl_tcp_abort_on_overflow) { - inet_rsk(req)->acked = 1; - return NULL; -@@ -820,12 +897,13 @@ - { - int ret = 0; - int state = child->sk_state; -+ struct sock *meta_sk = mptcp(tcp_sk(child)) ? mptcp_meta_sk(child) : child; - - /* record NAPI ID of child */ - sk_mark_napi_id(child, skb); - - tcp_segs_in(tcp_sk(child), skb); -- if (!sock_owned_by_user(child)) { -+ if (!sock_owned_by_user(meta_sk)) { - ret = tcp_rcv_state_process(child, skb); - /* Wakeup parent, send SIGIO */ - if (state == TCP_SYN_RECV && child->sk_state != state) -@@ -835,10 +913,14 @@ - * in main socket hash table and lock on listening - * socket does not protect us more. - */ -- __sk_add_backlog(child, skb); -+ if (mptcp(tcp_sk(child))) -+ mptcp_prepare_for_backlog(child, skb); -+ __sk_add_backlog(meta_sk, skb); - } - - bh_unlock_sock(child); -+ if (mptcp(tcp_sk(child))) -+ bh_unlock_sock(meta_sk); - sock_put(child); - return ret; - } -diff -aurN linux-5.4.64/net/ipv4/tcp_output.c linux-5.4.64.mptcp/net/ipv4/tcp_output.c ---- linux-5.4.64/net/ipv4/tcp_output.c 2020-09-09 19:12:37.000000000 +0200 -+++ linux-5.4.64.mptcp/net/ipv4/tcp_output.c 2020-09-10 19:34:56.261474044 +0200 -@@ -37,6 +37,12 @@ - - #define pr_fmt(fmt) "TCP: " fmt - -+#include -+#include -+#if IS_ENABLED(CONFIG_IPV6) -+#include -+#endif -+#include - #include - - #include -@@ -57,11 +63,8 @@ - tp->tcp_mstamp = div_u64(val, NSEC_PER_USEC); - } - --static bool tcp_write_xmit(struct sock *sk, unsigned int mss_now, int nonagle, -- int push_one, gfp_t gfp); -- - /* Account for new data that has been sent to the network. */ --static void tcp_event_new_data_sent(struct sock *sk, struct sk_buff *skb) -+void tcp_event_new_data_sent(struct sock *sk, struct sk_buff *skb) - { - struct inet_connection_sock *icsk = inet_csk(sk); - struct tcp_sock *tp = tcp_sk(sk); -@@ -255,12 +258,16 @@ - * value can be stuffed directly into th->window for an outgoing - * frame. - */ --static u16 tcp_select_window(struct sock *sk) -+u16 tcp_select_window(struct sock *sk) - { - struct tcp_sock *tp = tcp_sk(sk); - u32 old_win = tp->rcv_wnd; -- u32 cur_win = tcp_receive_window(tp); -- u32 new_win = __tcp_select_window(sk); -+ /* The window must never shrink at the meta-level. At the subflow we -+ * have to allow this. Otherwise we may announce a window too large -+ * for the current meta-level sk_rcvbuf. -+ */ -+ u32 cur_win = tcp_receive_window(mptcp(tp) ? tcp_sk(mptcp_meta_sk(sk)) : tp); -+ u32 new_win = tp->ops->__select_window(sk); - - /* Never shrink the offered window */ - if (new_win < cur_win) { -@@ -276,6 +283,7 @@ - LINUX_MIB_TCPWANTZEROWINDOWADV); - new_win = ALIGN(cur_win, 1 << tp->rx_opt.rcv_wscale); - } -+ - tp->rcv_wnd = new_win; - tp->rcv_wup = tp->rcv_nxt; - -@@ -388,7 +396,7 @@ - /* Constructs common control bits of non-data skb. If SYN/FIN is present, - * auto increment end seqno. - */ --static void tcp_init_nondata_skb(struct sk_buff *skb, u32 seq, u8 flags) -+void tcp_init_nondata_skb(struct sk_buff *skb, u32 seq, u8 flags) - { - skb->ip_summed = CHECKSUM_PARTIAL; - -@@ -403,7 +411,7 @@ - TCP_SKB_CB(skb)->end_seq = seq; - } - --static inline bool tcp_urg_mode(const struct tcp_sock *tp) -+bool tcp_urg_mode(const struct tcp_sock *tp) - { - return tp->snd_una != tp->snd_up; - } -@@ -414,6 +422,7 @@ - #define OPTION_WSCALE (1 << 3) - #define OPTION_FAST_OPEN_COOKIE (1 << 8) - #define OPTION_SMC (1 << 9) -+/* Before adding here - take a look at OPTION_MPTCP in include/net/mptcp.h */ - - static void smc_options_write(__be32 *ptr, u16 *options) - { -@@ -430,17 +439,6 @@ - #endif - } - --struct tcp_out_options { -- u16 options; /* bit field of OPTION_* */ -- u16 mss; /* 0 to disable */ -- u8 ws; /* window scale, 0 to disable */ -- u8 num_sack_blocks; /* number of SACK blocks to include */ -- u8 hash_size; /* bytes in hash_location */ -- __u8 *hash_location; /* temporary pointer, overloaded */ -- __u32 tsval, tsecr; /* need to include OPTION_TS */ -- struct tcp_fastopen_cookie *fastopen_cookie; /* Fast open cookie */ --}; -- - /* Write previously computed TCP options to the packet. - * - * Beware: Something in the Internet is very sensitive to the ordering of -@@ -455,7 +453,7 @@ - * (but it may well be that other scenarios fail similarly). - */ - static void tcp_options_write(__be32 *ptr, struct tcp_sock *tp, -- struct tcp_out_options *opts) -+ struct tcp_out_options *opts, struct sk_buff *skb) - { - u16 options = opts->options; /* mungable copy */ - -@@ -549,6 +547,9 @@ - } - - smc_options_write(ptr, &options); -+ -+ if (unlikely(OPTION_MPTCP & opts->options)) -+ mptcp_options_write(ptr, tp, opts, skb); - } - - static void smc_set_option(const struct tcp_sock *tp, -@@ -635,6 +636,8 @@ - if (unlikely(!(OPTION_TS & opts->options))) - remaining -= TCPOLEN_SACKPERM_ALIGNED; - } -+ if (tp->request_mptcp || mptcp(tp)) -+ mptcp_syn_options(sk, opts, &remaining); - - if (fastopen && fastopen->cookie.len >= 0) { - u32 need = fastopen->cookie.len; -@@ -718,6 +721,9 @@ - - smc_set_option_cond(tcp_sk(sk), ireq, opts, &remaining); - -+ if (ireq->saw_mpc) -+ mptcp_synack_options(req, opts, &remaining); -+ - return MAX_TCP_OPTION_SPACE - remaining; - } - -@@ -752,14 +758,19 @@ - opts->tsecr = tp->rx_opt.ts_recent; - size += TCPOLEN_TSTAMP_ALIGNED; - } -+ if (mptcp(tp)) -+ mptcp_established_options(sk, skb, opts, &size); - - eff_sacks = tp->rx_opt.num_sacks + tp->rx_opt.dsack; - if (unlikely(eff_sacks)) { - const unsigned int remaining = MAX_TCP_OPTION_SPACE - size; -- opts->num_sack_blocks = -- min_t(unsigned int, eff_sacks, -- (remaining - TCPOLEN_SACK_BASE_ALIGNED) / -- TCPOLEN_SACK_PERBLOCK); -+ if (remaining < TCPOLEN_SACK_BASE_ALIGNED) -+ opts->num_sack_blocks = 0; -+ else -+ opts->num_sack_blocks = -+ min_t(unsigned int, eff_sacks, -+ (remaining - TCPOLEN_SACK_BASE_ALIGNED) / -+ TCPOLEN_SACK_PERBLOCK); - if (likely(opts->num_sack_blocks)) - size += TCPOLEN_SACK_BASE_ALIGNED + - opts->num_sack_blocks * TCPOLEN_SACK_PERBLOCK; -@@ -802,19 +813,31 @@ - tcp_xmit_retransmit_queue(sk); - } - -- tcp_write_xmit(sk, tcp_current_mss(sk), tp->nonagle, -- 0, GFP_ATOMIC); -+ tcp_sk(sk)->ops->write_xmit(sk, tcp_current_mss(sk), -+ tcp_sk(sk)->nonagle, 0, GFP_ATOMIC); - } - } - - static void tcp_tsq_handler(struct sock *sk) - { -- bh_lock_sock(sk); -- if (!sock_owned_by_user(sk)) -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct sock *meta_sk = mptcp(tp) ? mptcp_meta_sk(sk) : sk; -+ -+ bh_lock_sock(meta_sk); -+ if (!sock_owned_by_user(meta_sk)) { - tcp_tsq_write(sk); -- else if (!test_and_set_bit(TCP_TSQ_DEFERRED, &sk->sk_tsq_flags)) -- sock_hold(sk); -- bh_unlock_sock(sk); -+ -+ if (mptcp(tp)) -+ tcp_tsq_write(meta_sk); -+ } else { -+ if (!test_and_set_bit(TCP_TSQ_DEFERRED, &sk->sk_tsq_flags)) -+ sock_hold(sk); -+ -+ if ((mptcp(tp)) && (sk->sk_state != TCP_CLOSE)) -+ mptcp_tsq_flags(sk); -+ } -+ -+ bh_unlock_sock(meta_sk); - } - /* - * One tasklet per cpu tries to send more skbs. -@@ -851,7 +874,9 @@ - #define TCP_DEFERRED_ALL (TCPF_TSQ_DEFERRED | \ - TCPF_WRITE_TIMER_DEFERRED | \ - TCPF_DELACK_TIMER_DEFERRED | \ -- TCPF_MTU_REDUCED_DEFERRED) -+ TCPF_MTU_REDUCED_DEFERRED | \ -+ TCPF_PATH_MANAGER_DEFERRED |\ -+ TCPF_SUB_DEFERRED) - /** - * tcp_release_cb - tcp release_sock() callback - * @sk: socket -@@ -874,6 +899,9 @@ - if (flags & TCPF_TSQ_DEFERRED) { - tcp_tsq_write(sk); - __sock_put(sk); -+ -+ if (mptcp(tcp_sk(sk))) -+ tcp_tsq_write(mptcp_meta_sk(sk)); - } - /* Here begins the tricky part : - * We are called from release_sock() with : -@@ -898,6 +926,13 @@ - inet_csk(sk)->icsk_af_ops->mtu_reduced(sk); - __sock_put(sk); - } -+ if (flags & TCPF_PATH_MANAGER_DEFERRED) { -+ if (tcp_sk(sk)->mpcb->pm_ops->release_sock) -+ tcp_sk(sk)->mpcb->pm_ops->release_sock(sk); -+ __sock_put(sk); -+ } -+ if (flags & TCPF_SUB_DEFERRED) -+ mptcp_tsq_sub_deferred(sk); - } - EXPORT_SYMBOL(tcp_release_cb); - -@@ -981,8 +1016,8 @@ - return HRTIMER_NORESTART; - } - --static void tcp_update_skb_after_send(struct sock *sk, struct sk_buff *skb, -- u64 prior_wstamp) -+void tcp_update_skb_after_send(struct sock *sk, struct sk_buff *skb, -+ u64 prior_wstamp) - { - struct tcp_sock *tp = tcp_sk(sk); - -@@ -1128,10 +1163,10 @@ - } - } - -- tcp_options_write((__be32 *)(th + 1), tp, &opts); -+ tcp_options_write((__be32 *)(th + 1), tp, &opts, skb); - skb_shinfo(skb)->gso_type = sk->sk_gso_type; - if (likely(!(tcb->tcp_flags & TCPHDR_SYN))) { -- th->window = htons(tcp_select_window(sk)); -+ th->window = htons(tp->ops->select_window(sk)); - tcp_ecn_send(sk, skb, th, tcp_header_size); - } else { - /* RFC1323: The window in SYN & SYN/ACK segments -@@ -1189,8 +1224,8 @@ - return err; - } - --static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it, -- gfp_t gfp_mask) -+int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it, -+ gfp_t gfp_mask) - { - return __tcp_transmit_skb(sk, skb, clone_it, gfp_mask, - tcp_sk(sk)->rcv_nxt); -@@ -1201,7 +1236,7 @@ - * NOTE: probe0 timer is not checked, do not forget tcp_push_pending_frames, - * otherwise socket can stall. - */ --static void tcp_queue_skb(struct sock *sk, struct sk_buff *skb) -+void tcp_queue_skb(struct sock *sk, struct sk_buff *skb) - { - struct tcp_sock *tp = tcp_sk(sk); - -@@ -1214,7 +1249,7 @@ - } - - /* Initialize TSO segments for a packet. */ --static void tcp_set_skb_tso_segs(struct sk_buff *skb, unsigned int mss_now) -+void tcp_set_skb_tso_segs(struct sk_buff *skb, unsigned int mss_now) - { - if (skb->len <= mss_now) { - /* Avoid the costly divide in the normal -@@ -1231,7 +1266,7 @@ - /* Pcount in the middle of the write queue got changed, we need to do various - * tweaks to fix counters - */ --static void tcp_adjust_pcount(struct sock *sk, const struct sk_buff *skb, int decr) -+void tcp_adjust_pcount(struct sock *sk, const struct sk_buff *skb, int decr) - { - struct tcp_sock *tp = tcp_sk(sk); - -@@ -1400,7 +1435,7 @@ - /* This is similar to __pskb_pull_tail(). The difference is that pulled - * data is not copied, but immediately discarded. - */ --static int __pskb_trim_head(struct sk_buff *skb, int len) -+int __pskb_trim_head(struct sk_buff *skb, int len) - { - struct skb_shared_info *shinfo; - int i, k, eat; -@@ -1622,6 +1657,7 @@ - - return mss_now; - } -+EXPORT_SYMBOL(tcp_current_mss); - - /* RFC2861, slow part. Adjust cwnd, after it was not full during one rto. - * As additional protections, we do not touch cwnd in retransmission phases, -@@ -1703,8 +1739,8 @@ - * But we can avoid doing the divide again given we already have - * skb_pcount = skb->len / mss_now - */ --static void tcp_minshall_update(struct tcp_sock *tp, unsigned int mss_now, -- const struct sk_buff *skb) -+void tcp_minshall_update(struct tcp_sock *tp, unsigned int mss_now, -+ const struct sk_buff *skb) - { - if (skb->len < tcp_skb_pcount(skb) * mss_now) - tp->snd_sml = TCP_SKB_CB(skb)->end_seq; -@@ -1764,11 +1800,11 @@ - } - - /* Returns the portion of skb which can be sent right away */ --static unsigned int tcp_mss_split_point(const struct sock *sk, -- const struct sk_buff *skb, -- unsigned int mss_now, -- unsigned int max_segs, -- int nonagle) -+unsigned int tcp_mss_split_point(const struct sock *sk, -+ const struct sk_buff *skb, -+ unsigned int mss_now, -+ unsigned int max_segs, -+ int nonagle) - { - const struct tcp_sock *tp = tcp_sk(sk); - u32 partial, needed, window, max_len; -@@ -1798,13 +1834,14 @@ - /* Can at least one segment of SKB be sent right now, according to the - * congestion window rules? If so, return how many segments are allowed. - */ --static inline unsigned int tcp_cwnd_test(const struct tcp_sock *tp, -- const struct sk_buff *skb) -+unsigned int tcp_cwnd_test(const struct tcp_sock *tp, -+ const struct sk_buff *skb) - { - u32 in_flight, cwnd, halfcwnd; - - /* Don't be strict about the congestion window for the final FIN. */ -- if ((TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN) && -+ if (skb && -+ (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN) && - tcp_skb_pcount(skb) == 1) - return 1; - -@@ -1819,12 +1856,13 @@ - halfcwnd = max(cwnd >> 1, 1U); - return min(halfcwnd, cwnd - in_flight); - } -+EXPORT_SYMBOL(tcp_cwnd_test); - - /* Initialize TSO state of a skb. - * This must be invoked the first time we consider transmitting - * SKB onto the wire. - */ --static int tcp_init_tso_segs(struct sk_buff *skb, unsigned int mss_now) -+int tcp_init_tso_segs(struct sk_buff *skb, unsigned int mss_now) - { - int tso_segs = tcp_skb_pcount(skb); - -@@ -1839,8 +1877,8 @@ - /* Return true if the Nagle test allows this packet to be - * sent now. - */ --static inline bool tcp_nagle_test(const struct tcp_sock *tp, const struct sk_buff *skb, -- unsigned int cur_mss, int nonagle) -+bool tcp_nagle_test(const struct tcp_sock *tp, const struct sk_buff *skb, -+ unsigned int cur_mss, int nonagle) - { - /* Nagle rule does not apply to frames, which sit in the middle of the - * write_queue (they have no chances to get new data). -@@ -1852,7 +1890,8 @@ - return true; - - /* Don't use the nagle rule for urgent data (or for the final FIN). */ -- if (tcp_urg_mode(tp) || (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN)) -+ if (tcp_urg_mode(tp) || (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN) || -+ mptcp_is_data_fin(skb)) - return true; - - if (!tcp_nagle_check(skb->len < cur_mss, tp, nonagle)) -@@ -1862,9 +1901,8 @@ - } - - /* Does at least the first segment of SKB fit into the send window? */ --static bool tcp_snd_wnd_test(const struct tcp_sock *tp, -- const struct sk_buff *skb, -- unsigned int cur_mss) -+bool tcp_snd_wnd_test(const struct tcp_sock *tp, const struct sk_buff *skb, -+ unsigned int cur_mss) - { - u32 end_seq = TCP_SKB_CB(skb)->end_seq; - -@@ -1873,6 +1911,7 @@ - - return !after(end_seq, tcp_wnd_end(tp)); - } -+EXPORT_SYMBOL(tcp_snd_wnd_test); - - /* Trim TSO SKB to LEN bytes, put the remaining data into a new packet - * which is put after SKB on the list. It is very much like -@@ -2031,7 +2070,8 @@ - - /* If this packet won't get more data, do not wait. */ - if ((TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN) || -- TCP_SKB_CB(skb)->eor) -+ TCP_SKB_CB(skb)->eor || -+ mptcp_is_data_fin(skb)) - goto send_now; - - return true; -@@ -2364,7 +2404,7 @@ - * Returns true, if no segments are in flight and we have queued segments, - * but cannot send anything now because of SWS or another problem. - */ --static bool tcp_write_xmit(struct sock *sk, unsigned int mss_now, int nonagle, -+bool tcp_write_xmit(struct sock *sk, unsigned int mss_now, int nonagle, - int push_one, gfp_t gfp) - { - struct tcp_sock *tp = tcp_sk(sk); -@@ -2378,7 +2418,12 @@ - sent_pkts = 0; - - tcp_mstamp_refresh(tp); -- if (!push_one) { -+ -+ /* pmtu not yet supported with MPTCP. Should be possible, by early -+ * exiting the loop inside tcp_mtu_probe, making sure that only one -+ * single DSS-mapping gets probed. -+ */ -+ if (!push_one && !mptcp(tp)) { - /* Do MTU probing. */ - result = tcp_mtu_probe(sk); - if (!result) { -@@ -2572,7 +2617,7 @@ - skb = tcp_send_head(sk); - if (skb && tcp_snd_wnd_test(tp, skb, mss)) { - pcount = tp->packets_out; -- tcp_write_xmit(sk, mss, TCP_NAGLE_OFF, 2, GFP_ATOMIC); -+ tp->ops->write_xmit(sk, mss, TCP_NAGLE_OFF, 2, GFP_ATOMIC); - if (tp->packets_out > pcount) - goto probe_sent; - goto rearm_timer; -@@ -2634,8 +2679,8 @@ - if (unlikely(sk->sk_state == TCP_CLOSE)) - return; - -- if (tcp_write_xmit(sk, cur_mss, nonagle, 0, -- sk_gfp_mask(sk, GFP_ATOMIC))) -+ if (tcp_sk(sk)->ops->write_xmit(sk, cur_mss, nonagle, 0, -+ sk_gfp_mask(sk, GFP_ATOMIC))) - tcp_check_probe_timer(sk); - } - -@@ -2648,7 +2693,8 @@ - - BUG_ON(!skb || skb->len < mss_now); - -- tcp_write_xmit(sk, mss_now, TCP_NAGLE_PUSH, 1, sk->sk_allocation); -+ tcp_sk(sk)->ops->write_xmit(sk, mss_now, TCP_NAGLE_PUSH, 1, -+ sk->sk_allocation); - } - - /* This function returns the amount that we can raise the -@@ -2870,6 +2916,10 @@ - if (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_SYN) - return; - -+ /* Currently not supported for MPTCP - but it should be possible */ -+ if (mptcp(tp)) -+ return; -+ - skb_rbtree_walk_from_safe(skb, tmp) { - if (!tcp_can_collapse(sk, skb)) - break; -@@ -3351,7 +3401,7 @@ - - /* RFC1323: The window in SYN & SYN/ACK segments is never scaled. */ - th->window = htons(min(req->rsk_rcv_wnd, 65535U)); -- tcp_options_write((__be32 *)(th + 1), NULL, &opts); -+ tcp_options_write((__be32 *)(th + 1), NULL, &opts, skb); - th->doff = (tcp_header_size >> 2); - __TCP_INC_STATS(sock_net(sk), TCP_MIB_OUTSEGS); - -@@ -3433,13 +3483,13 @@ - if (rcv_wnd == 0) - rcv_wnd = dst_metric(dst, RTAX_INITRWND); - -- tcp_select_initial_window(sk, tcp_full_space(sk), -- tp->advmss - (tp->rx_opt.ts_recent_stamp ? tp->tcp_header_len - sizeof(struct tcphdr) : 0), -- &tp->rcv_wnd, -- &tp->window_clamp, -- sock_net(sk)->ipv4.sysctl_tcp_window_scaling, -- &rcv_wscale, -- rcv_wnd); -+ tp->ops->select_initial_window(sk, tcp_full_space(sk), -+ tp->advmss - (tp->rx_opt.ts_recent_stamp ? tp->tcp_header_len - sizeof(struct tcphdr) : 0), -+ &tp->rcv_wnd, -+ &tp->window_clamp, -+ sock_net(sk)->ipv4.sysctl_tcp_window_scaling, -+ &rcv_wscale, -+ rcv_wnd); - - tp->rx_opt.rcv_wscale = rcv_wscale; - tp->rcv_ssthresh = tp->rcv_wnd; -@@ -3464,6 +3514,36 @@ - inet_csk(sk)->icsk_rto = tcp_timeout_init(sk); - inet_csk(sk)->icsk_retransmits = 0; - tcp_clear_retrans(tp); -+ -+#ifdef CONFIG_MPTCP -+ if (sock_flag(sk, SOCK_MPTCP) && mptcp_doit(sk)) { -+ if (is_master_tp(tp)) { -+ tp->request_mptcp = 1; -+ mptcp_connect_init(sk); -+ } else if (tp->mptcp) { -+ struct inet_sock *inet = inet_sk(sk); -+ -+ tp->mptcp->snt_isn = tp->write_seq; -+ tp->mptcp->init_rcv_wnd = tp->rcv_wnd; -+ -+ /* Set nonce for new subflows */ -+ if (sk->sk_family == AF_INET) -+ tp->mptcp->mptcp_loc_nonce = mptcp_v4_get_nonce( -+ inet->inet_saddr, -+ inet->inet_daddr, -+ inet->inet_sport, -+ inet->inet_dport); -+#if IS_ENABLED(CONFIG_IPV6) -+ else -+ tp->mptcp->mptcp_loc_nonce = mptcp_v6_get_nonce( -+ inet6_sk(sk)->saddr.s6_addr32, -+ sk->sk_v6_daddr.s6_addr32, -+ inet->inet_sport, -+ inet->inet_dport); -+#endif -+ } -+ } -+#endif - } - - static void tcp_connect_queue_skb(struct sock *sk, struct sk_buff *skb) -@@ -3727,6 +3807,7 @@ - { - __tcp_send_ack(sk, tcp_sk(sk)->rcv_nxt); - } -+EXPORT_SYMBOL_GPL(tcp_send_ack); - - /* This routine sends a packet with an out of date sequence - * number. It assumes the other end will try to ack it. -@@ -3739,7 +3820,7 @@ - * one is with SEG.SEQ=SND.UNA to deliver urgent pointer, another is - * out-of-date with SND.UNA-1 to probe window. - */ --static int tcp_xmit_probe_skb(struct sock *sk, int urgent, int mib) -+int tcp_xmit_probe_skb(struct sock *sk, int urgent, int mib) - { - struct tcp_sock *tp = tcp_sk(sk); - struct sk_buff *skb; -@@ -3826,7 +3907,7 @@ - unsigned long timeout; - int err; - -- err = tcp_write_wakeup(sk, LINUX_MIB_TCPWINPROBE); -+ err = tp->ops->write_wakeup(sk, LINUX_MIB_TCPWINPROBE); - - if (tp->packets_out || tcp_write_queue_empty(sk)) { - /* Cancel probe timer, if it is not required. */ -diff -aurN linux-5.4.64/net/ipv4/tcp_timer.c linux-5.4.64.mptcp/net/ipv4/tcp_timer.c ---- linux-5.4.64/net/ipv4/tcp_timer.c 2020-09-09 19:12:37.000000000 +0200 -+++ linux-5.4.64.mptcp/net/ipv4/tcp_timer.c 2020-09-10 19:25:10.507220869 +0200 -@@ -21,6 +21,7 @@ - - #include - #include -+#include - #include - - static u32 tcp_clamp_rto_to_user_timeout(const struct sock *sk) -@@ -47,7 +48,7 @@ - * Returns: Nothing (void) - */ - --static void tcp_write_err(struct sock *sk) -+void tcp_write_err(struct sock *sk) - { - sk->sk_err = sk->sk_err_soft ? : ETIMEDOUT; - sk->sk_error_report(sk); -@@ -103,7 +104,7 @@ - (!tp->snd_wnd && !tp->packets_out)) - do_reset = true; - if (do_reset) -- tcp_send_active_reset(sk, GFP_ATOMIC); -+ tp->ops->send_active_reset(sk, GFP_ATOMIC); - tcp_done(sk); - __NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPABORTONMEMORY); - return 1; -@@ -188,9 +189,9 @@ - * after "boundary" unsuccessful, exponentially backed-off - * retransmissions with an initial RTO of TCP_RTO_MIN. - */ --static bool retransmits_timed_out(struct sock *sk, -- unsigned int boundary, -- unsigned int timeout) -+bool retransmits_timed_out(struct sock *sk, -+ unsigned int boundary, -+ unsigned int timeout) - { - unsigned int start_ts; - -@@ -210,7 +211,7 @@ - } - - /* A write timeout has occurred. Process the after effects. */ --static int tcp_write_timeout(struct sock *sk) -+int tcp_write_timeout(struct sock *sk) - { - struct inet_connection_sock *icsk = inet_csk(sk); - struct tcp_sock *tp = tcp_sk(sk); -@@ -225,6 +226,17 @@ - sk_rethink_txhash(sk); - } - retry_until = icsk->icsk_syn_retries ? : net->ipv4.sysctl_tcp_syn_retries; -+ -+#ifdef CONFIG_MPTCP -+ /* Stop retransmitting MP_CAPABLE options in SYN if timed out. */ -+ if (tcp_sk(sk)->request_mptcp && -+ icsk->icsk_retransmits >= sysctl_mptcp_syn_retries) { -+ tcp_sk(sk)->request_mptcp = 0; -+ -+ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_MPCAPABLERETRANSFALLBACK); -+ } -+#endif /* CONFIG_MPTCP */ -+ - expired = icsk->icsk_retransmits >= retry_until; - } else { - if (retransmits_timed_out(sk, net->ipv4.sysctl_tcp_retries1, 0)) { -@@ -320,18 +332,22 @@ - struct inet_connection_sock *icsk = - from_timer(icsk, t, icsk_delack_timer); - struct sock *sk = &icsk->icsk_inet.sk; -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct sock *meta_sk = mptcp(tp) ? mptcp_meta_sk(sk) : sk; - -- bh_lock_sock(sk); -- if (!sock_owned_by_user(sk)) { -+ bh_lock_sock(meta_sk); -+ if (!sock_owned_by_user(meta_sk)) { - tcp_delack_timer_handler(sk); - } else { - icsk->icsk_ack.blocked = 1; -- __NET_INC_STATS(sock_net(sk), LINUX_MIB_DELAYEDACKLOCKED); -+ __NET_INC_STATS(sock_net(meta_sk), LINUX_MIB_DELAYEDACKLOCKED); - /* deleguate our work to tcp_release_cb() */ - if (!test_and_set_bit(TCP_DELACK_TIMER_DEFERRED, &sk->sk_tsq_flags)) - sock_hold(sk); -+ if (mptcp(tp)) -+ mptcp_tsq_flags(sk); - } -- bh_unlock_sock(sk); -+ bh_unlock_sock(meta_sk); - sock_put(sk); - } - -@@ -375,7 +391,12 @@ - } - - if (icsk->icsk_probes_out >= max_probes) { --abort: tcp_write_err(sk); -+abort: -+ tcp_write_err(sk); -+ if (is_meta_sk(sk) && -+ mptcp_in_infinite_mapping_weak(tp->mpcb)) { -+ mptcp_sub_force_close_all(tp->mpcb, NULL); -+ } - } else { - /* Only send another probe if we didn't close things up. */ - tcp_send_probe0(sk); -@@ -596,7 +617,7 @@ - break; - case ICSK_TIME_RETRANS: - icsk->icsk_pending = 0; -- tcp_retransmit_timer(sk); -+ tcp_sk(sk)->ops->retransmit_timer(sk); - break; - case ICSK_TIME_PROBE0: - icsk->icsk_pending = 0; -@@ -613,16 +634,19 @@ - struct inet_connection_sock *icsk = - from_timer(icsk, t, icsk_retransmit_timer); - struct sock *sk = &icsk->icsk_inet.sk; -+ struct sock *meta_sk = mptcp(tcp_sk(sk)) ? mptcp_meta_sk(sk) : sk; - -- bh_lock_sock(sk); -- if (!sock_owned_by_user(sk)) { -+ bh_lock_sock(meta_sk); -+ if (!sock_owned_by_user(meta_sk)) { - tcp_write_timer_handler(sk); - } else { - /* delegate our work to tcp_release_cb() */ - if (!test_and_set_bit(TCP_WRITE_TIMER_DEFERRED, &sk->sk_tsq_flags)) - sock_hold(sk); -+ if (mptcp(tcp_sk(sk))) -+ mptcp_tsq_flags(sk); - } -- bh_unlock_sock(sk); -+ bh_unlock_sock(meta_sk); - sock_put(sk); - } - -@@ -652,11 +676,12 @@ - struct sock *sk = from_timer(sk, t, sk_timer); - struct inet_connection_sock *icsk = inet_csk(sk); - struct tcp_sock *tp = tcp_sk(sk); -+ struct sock *meta_sk = mptcp(tp) ? mptcp_meta_sk(sk) : sk; - u32 elapsed; - - /* Only process if socket is not in use. */ -- bh_lock_sock(sk); -- if (sock_owned_by_user(sk)) { -+ bh_lock_sock(meta_sk); -+ if (sock_owned_by_user(meta_sk)) { - /* Try again later. */ - inet_csk_reset_keepalive_timer (sk, HZ/20); - goto out; -@@ -668,16 +693,31 @@ - } - - tcp_mstamp_refresh(tp); -+ -+ if (tp->send_mp_fclose) { -+ if (icsk->icsk_retransmits >= MPTCP_FASTCLOSE_RETRIES) { -+ tcp_write_err(sk); -+ goto out; -+ } -+ -+ tcp_send_ack(sk); -+ icsk->icsk_retransmits++; -+ -+ icsk->icsk_rto = min(icsk->icsk_rto << 1, TCP_RTO_MAX); -+ elapsed = icsk->icsk_rto; -+ goto resched; -+ } -+ - if (sk->sk_state == TCP_FIN_WAIT2 && sock_flag(sk, SOCK_DEAD)) { - if (tp->linger2 >= 0) { - const int tmo = tcp_fin_time(sk) - TCP_TIMEWAIT_LEN; - - if (tmo > 0) { -- tcp_time_wait(sk, TCP_FIN_WAIT2, tmo); -+ tp->ops->time_wait(sk, TCP_FIN_WAIT2, tmo); - goto out; - } - } -- tcp_send_active_reset(sk, GFP_ATOMIC); -+ tp->ops->send_active_reset(sk, GFP_ATOMIC); - goto death; - } - -@@ -702,11 +742,11 @@ - icsk->icsk_probes_out > 0) || - (icsk->icsk_user_timeout == 0 && - icsk->icsk_probes_out >= keepalive_probes(tp))) { -- tcp_send_active_reset(sk, GFP_ATOMIC); -+ tp->ops->send_active_reset(sk, GFP_ATOMIC); - tcp_write_err(sk); - goto out; - } -- if (tcp_write_wakeup(sk, LINUX_MIB_TCPKEEPALIVE) <= 0) { -+ if (tp->ops->write_wakeup(sk, LINUX_MIB_TCPKEEPALIVE) <= 0) { - icsk->icsk_probes_out++; - elapsed = keepalive_intvl_when(tp); - } else { -@@ -730,7 +770,7 @@ - tcp_done(sk); - - out: -- bh_unlock_sock(sk); -+ bh_unlock_sock(meta_sk); - sock_put(sk); - } - -diff -aurN linux-5.4.64/net/ipv6/addrconf.c linux-5.4.64.mptcp/net/ipv6/addrconf.c ---- linux-5.4.64/net/ipv6/addrconf.c 2020-09-09 19:12:37.000000000 +0200 -+++ linux-5.4.64.mptcp/net/ipv6/addrconf.c 2020-09-10 19:25:10.507220869 +0200 -@@ -967,6 +967,7 @@ - - kfree_rcu(ifp, rcu); - } -+EXPORT_SYMBOL(inet6_ifa_finish_destroy); - - static void - ipv6_link_dev_addr(struct inet6_dev *idev, struct inet6_ifaddr *ifp) -diff -aurN linux-5.4.64/net/ipv6/af_inet6.c linux-5.4.64.mptcp/net/ipv6/af_inet6.c ---- linux-5.4.64/net/ipv6/af_inet6.c 2020-09-09 19:12:37.000000000 +0200 -+++ linux-5.4.64.mptcp/net/ipv6/af_inet6.c 2020-09-10 19:25:10.507220869 +0200 -@@ -104,8 +104,7 @@ - return (struct ipv6_pinfo *)(((u8 *)sk) + offset); - } - --static int inet6_create(struct net *net, struct socket *sock, int protocol, -- int kern) -+int inet6_create(struct net *net, struct socket *sock, int protocol, int kern) - { - struct inet_sock *inet; - struct ipv6_pinfo *np; -diff -aurN linux-5.4.64/net/ipv6/ipv6_sockglue.c linux-5.4.64.mptcp/net/ipv6/ipv6_sockglue.c ---- linux-5.4.64/net/ipv6/ipv6_sockglue.c 2020-09-09 19:12:37.000000000 +0200 -+++ linux-5.4.64.mptcp/net/ipv6/ipv6_sockglue.c 2020-09-10 19:25:10.507220869 +0200 -@@ -44,6 +44,8 @@ - #include - #include - #include -+#include -+#include - #include - #include - #include -@@ -221,7 +223,12 @@ - sock_prot_inuse_add(net, &tcp_prot, 1); - local_bh_enable(); - sk->sk_prot = &tcp_prot; -- icsk->icsk_af_ops = &ipv4_specific; -+#ifdef CONFIG_MPTCP -+ if (sock_flag(sk, SOCK_MPTCP)) -+ icsk->icsk_af_ops = &mptcp_v4_specific; -+ else -+#endif -+ icsk->icsk_af_ops = &ipv4_specific; - sk->sk_socket->ops = &inet_stream_ops; - sk->sk_family = PF_INET; - tcp_sync_mss(sk, icsk->icsk_pmtu_cookie); -diff -aurN linux-5.4.64/net/ipv6/syncookies.c linux-5.4.64.mptcp/net/ipv6/syncookies.c ---- linux-5.4.64/net/ipv6/syncookies.c 2020-09-09 19:12:37.000000000 +0200 -+++ linux-5.4.64.mptcp/net/ipv6/syncookies.c 2020-09-10 19:25:10.507220869 +0200 -@@ -15,6 +15,8 @@ - #include - #include - #include -+#include -+#include - #include - - #define COOKIEBITS 24 /* Upper bits store count */ -@@ -106,7 +108,8 @@ - } - EXPORT_SYMBOL_GPL(__cookie_v6_init_sequence); - --__u32 cookie_v6_init_sequence(const struct sk_buff *skb, __u16 *mssp) -+__u32 cookie_v6_init_sequence(struct request_sock *req, const struct sock *sk, -+ const struct sk_buff *skb, __u16 *mssp) - { - const struct ipv6hdr *iph = ipv6_hdr(skb); - const struct tcphdr *th = tcp_hdr(skb); -@@ -128,6 +131,7 @@ - struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb) - { - struct tcp_options_received tcp_opt; -+ struct mptcp_options_received mopt; - struct inet_request_sock *ireq; - struct tcp_request_sock *treq; - struct ipv6_pinfo *np = inet6_sk(sk); -@@ -157,7 +161,8 @@ - - /* check for timestamp cookie support */ - memset(&tcp_opt, 0, sizeof(tcp_opt)); -- tcp_parse_options(sock_net(sk), skb, &tcp_opt, 0, NULL); -+ mptcp_init_mp_opt(&mopt); -+ tcp_parse_options(sock_net(sk), skb, &tcp_opt, &mopt, 0, NULL, NULL); - - if (tcp_opt.saw_tstamp && tcp_opt.rcv_tsecr) { - tsoff = secure_tcpv6_ts_off(sock_net(sk), -@@ -170,14 +175,27 @@ - goto out; - - ret = NULL; -- req = inet_reqsk_alloc(&tcp6_request_sock_ops, sk, false); -+#ifdef CONFIG_MPTCP -+ if (mopt.saw_mpc) -+ req = inet_reqsk_alloc(&mptcp6_request_sock_ops, sk, false); -+ else -+#endif -+ req = inet_reqsk_alloc(&tcp6_request_sock_ops, sk, false); - if (!req) - goto out; - - ireq = inet_rsk(req); -+ ireq->mptcp_rqsk = 0; -+ ireq->saw_mpc = 0; - treq = tcp_rsk(req); - treq->tfo_listener = false; - -+ /* Must be done before anything else, as it initializes -+ * hash_entry of the MPTCP request-sock. -+ */ -+ if (mopt.saw_mpc) -+ mptcp_cookies_reqsk_init(req, &mopt, skb); -+ - if (security_inet_conn_request(sk, skb, req)) - goto out_free; - -@@ -241,15 +259,15 @@ - } - - req->rsk_window_clamp = tp->window_clamp ? :dst_metric(dst, RTAX_WINDOW); -- tcp_select_initial_window(sk, tcp_full_space(sk), req->mss, -- &req->rsk_rcv_wnd, &req->rsk_window_clamp, -- ireq->wscale_ok, &rcv_wscale, -- dst_metric(dst, RTAX_INITRWND)); -+ tp->ops->select_initial_window(sk, tcp_full_space(sk), req->mss, -+ &req->rsk_rcv_wnd, &req->rsk_window_clamp, -+ ireq->wscale_ok, &rcv_wscale, -+ dst_metric(dst, RTAX_INITRWND)); - - ireq->rcv_wscale = rcv_wscale; - ireq->ecn_ok = cookie_ecn_ok(&tcp_opt, sock_net(sk), dst); - -- ret = tcp_get_cookie_sock(sk, skb, req, dst, tsoff); -+ ret = tcp_get_cookie_sock(sk, skb, req, &mopt, dst, tsoff); - out: - return ret; - out_free: -diff -aurN linux-5.4.64/net/ipv6/tcp_ipv6.c linux-5.4.64.mptcp/net/ipv6/tcp_ipv6.c ---- linux-5.4.64/net/ipv6/tcp_ipv6.c 2020-09-09 19:12:37.000000000 +0200 -+++ linux-5.4.64.mptcp/net/ipv6/tcp_ipv6.c 2020-09-10 19:25:10.507220869 +0200 -@@ -58,6 +58,8 @@ - #include - #include - #include -+#include -+#include - #include - - #include -@@ -67,15 +69,6 @@ - #include - - #include -- --static void tcp_v6_send_reset(const struct sock *sk, struct sk_buff *skb); --static void tcp_v6_reqsk_send_ack(const struct sock *sk, struct sk_buff *skb, -- struct request_sock *req); -- --static int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb); -- --static const struct inet_connection_sock_af_ops ipv6_mapped; --static const struct inet_connection_sock_af_ops ipv6_specific; - #ifdef CONFIG_TCP_MD5SIG - static const struct tcp_sock_af_ops tcp_sock_ipv6_specific; - static const struct tcp_sock_af_ops tcp_sock_ipv6_mapped_specific; -@@ -99,7 +92,7 @@ - return (struct ipv6_pinfo *)(((u8 *)sk) + offset); - } - --static void inet6_sk_rx_dst_set(struct sock *sk, const struct sk_buff *skb) -+void inet6_sk_rx_dst_set(struct sock *sk, const struct sk_buff *skb) - { - struct dst_entry *dst = skb_dst(skb); - -@@ -141,7 +134,7 @@ - return BPF_CGROUP_RUN_PROG_INET6_CONNECT(sk, uaddr); - } - --static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr, -+int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr, - int addr_len) - { - struct sockaddr_in6 *usin = (struct sockaddr_in6 *) uaddr; -@@ -157,6 +150,8 @@ - int err; - struct inet_timewait_death_row *tcp_death_row = &sock_net(sk)->ipv4.tcp_death_row; - -+ mptcp_init_connect(sk); -+ - if (addr_len < SIN6_LEN_RFC2133) - return -EINVAL; - -@@ -236,7 +231,12 @@ - sin.sin_port = usin->sin6_port; - sin.sin_addr.s_addr = usin->sin6_addr.s6_addr32[3]; - -- icsk->icsk_af_ops = &ipv6_mapped; -+#ifdef CONFIG_MPTCP -+ if (sock_flag(sk, SOCK_MPTCP)) -+ icsk->icsk_af_ops = &mptcp_v6_mapped; -+ else -+#endif -+ icsk->icsk_af_ops = &ipv6_mapped; - sk->sk_backlog_rcv = tcp_v4_do_rcv; - #ifdef CONFIG_TCP_MD5SIG - tp->af_specific = &tcp_sock_ipv6_mapped_specific; -@@ -246,7 +246,12 @@ - - if (err) { - icsk->icsk_ext_hdr_len = exthdrlen; -- icsk->icsk_af_ops = &ipv6_specific; -+#ifdef CONFIG_MPTCP -+ if (sock_flag(sk, SOCK_MPTCP)) -+ icsk->icsk_af_ops = &mptcp_v6_specific; -+ else -+#endif -+ icsk->icsk_af_ops = &ipv6_specific; - sk->sk_backlog_rcv = tcp_v6_do_rcv; - #ifdef CONFIG_TCP_MD5SIG - tp->af_specific = &tcp_sock_ipv6_specific; -@@ -340,7 +345,7 @@ - return err; - } - --static void tcp_v6_mtu_reduced(struct sock *sk) -+void tcp_v6_mtu_reduced(struct sock *sk) - { - struct dst_entry *dst; - -@@ -367,7 +372,7 @@ - struct ipv6_pinfo *np; - struct tcp_sock *tp; - __u32 seq, snd_una; -- struct sock *sk; -+ struct sock *sk, *meta_sk; - bool fatal; - int err; - -@@ -393,8 +398,14 @@ - return 0; - } - -- bh_lock_sock(sk); -- if (sock_owned_by_user(sk) && type != ICMPV6_PKT_TOOBIG) -+ tp = tcp_sk(sk); -+ if (mptcp(tp)) -+ meta_sk = mptcp_meta_sk(sk); -+ else -+ meta_sk = sk; -+ -+ bh_lock_sock(meta_sk); -+ if (sock_owned_by_user(meta_sk) && type != ICMPV6_PKT_TOOBIG) - __NET_INC_STATS(net, LINUX_MIB_LOCKDROPPEDICMPS); - - if (sk->sk_state == TCP_CLOSE) -@@ -405,7 +416,6 @@ - goto out; - } - -- tp = tcp_sk(sk); - /* XXX (TFO) - tp->snd_una should be ISN (tcp_create_openreq_child() */ - fastopen = rcu_dereference(tp->fastopen_rsk); - snd_una = fastopen ? tcp_rsk(fastopen)->snt_isn : tp->snd_una; -@@ -439,11 +449,15 @@ - goto out; - - tp->mtu_info = ntohl(info); -- if (!sock_owned_by_user(sk)) -+ if (!sock_owned_by_user(meta_sk)) { - tcp_v6_mtu_reduced(sk); -- else if (!test_and_set_bit(TCP_MTU_REDUCED_DEFERRED, -- &sk->sk_tsq_flags)) -- sock_hold(sk); -+ } else { -+ if (!test_and_set_bit(TCP_MTU_REDUCED_DEFERRED, -+ &sk->sk_tsq_flags)) -+ sock_hold(sk); -+ if (mptcp(tp)) -+ mptcp_tsq_flags(sk); -+ } - goto out; - } - -@@ -458,7 +472,7 @@ - if (fastopen && !fastopen->sk) - break; - -- if (!sock_owned_by_user(sk)) { -+ if (!sock_owned_by_user(meta_sk)) { - sk->sk_err = err; - sk->sk_error_report(sk); /* Wake people up to see the error (see connect in sock.c) */ - -@@ -468,14 +482,14 @@ - goto out; - } - -- if (!sock_owned_by_user(sk) && np->recverr) { -+ if (!sock_owned_by_user(meta_sk) && np->recverr) { - sk->sk_err = err; - sk->sk_error_report(sk); - } else - sk->sk_err_soft = err; - - out: -- bh_unlock_sock(sk); -+ bh_unlock_sock(meta_sk); - sock_put(sk); - return 0; - } -@@ -523,8 +537,7 @@ - return err; - } - -- --static void tcp_v6_reqsk_destructor(struct request_sock *req) -+void tcp_v6_reqsk_destructor(struct request_sock *req) - { - kfree(inet_rsk(req)->ipv6_opt); - kfree_skb(inet_rsk(req)->pktopts); -@@ -742,9 +755,10 @@ - return false; - } - --static void tcp_v6_init_req(struct request_sock *req, -- const struct sock *sk_listener, -- struct sk_buff *skb) -+static int tcp_v6_init_req(struct request_sock *req, -+ const struct sock *sk_listener, -+ struct sk_buff *skb, -+ bool want_cookie) - { - bool l3_slave = ipv6_l3mdev_skb(TCP_SKB_CB(skb)->header.h6.flags); - struct inet_request_sock *ireq = inet_rsk(req); -@@ -766,6 +780,8 @@ - refcount_inc(&skb->users); - ireq->pktopts = skb; - } -+ -+ return 0; - } - - static struct dst_entry *tcp_v6_route_req(const struct sock *sk, -@@ -785,7 +801,7 @@ - .syn_ack_timeout = tcp_syn_ack_timeout, - }; - --static const struct tcp_request_sock_ops tcp_request_sock_ipv6_ops = { -+const struct tcp_request_sock_ops tcp_request_sock_ipv6_ops = { - .mss_clamp = IPV6_MIN_MTU - sizeof(struct tcphdr) - - sizeof(struct ipv6hdr), - #ifdef CONFIG_TCP_MD5SIG -@@ -803,9 +819,9 @@ - }; - - static void tcp_v6_send_response(const struct sock *sk, struct sk_buff *skb, u32 seq, -- u32 ack, u32 win, u32 tsval, u32 tsecr, -+ u32 ack, u32 data_ack, u32 win, u32 tsval, u32 tsecr, - int oif, struct tcp_md5sig_key *key, int rst, -- u8 tclass, __be32 label, u32 priority) -+ u8 tclass, __be32 label, u32 priority, int mptcp) - { - const struct tcphdr *th = tcp_hdr(skb); - struct tcphdr *t1; -@@ -824,7 +840,10 @@ - if (key) - tot_len += TCPOLEN_MD5SIG_ALIGNED; - #endif -- -+#ifdef CONFIG_MPTCP -+ if (mptcp) -+ tot_len += MPTCP_SUB_LEN_DSS + MPTCP_SUB_LEN_ACK; -+#endif - buff = alloc_skb(MAX_HEADER + sizeof(struct ipv6hdr) + tot_len, - GFP_ATOMIC); - if (!buff) -@@ -862,6 +881,17 @@ - tcp_v6_md5_hash_hdr((__u8 *)topt, key, - &ipv6_hdr(skb)->saddr, - &ipv6_hdr(skb)->daddr, t1); -+ topt += 4; -+ } -+#endif -+#ifdef CONFIG_MPTCP -+ if (mptcp) { -+ /* Construction of 32-bit data_ack */ -+ *topt++ = htonl((TCPOPT_MPTCP << 24) | -+ ((MPTCP_SUB_LEN_DSS + MPTCP_SUB_LEN_ACK) << 16) | -+ (0x20 << 8) | -+ (0x01)); -+ *topt++ = htonl(data_ack); - } - #endif - -@@ -920,7 +950,7 @@ - kfree_skb(buff); - } - --static void tcp_v6_send_reset(const struct sock *sk, struct sk_buff *skb) -+void tcp_v6_send_reset(const struct sock *sk, struct sk_buff *skb) - { - const struct tcphdr *th = tcp_hdr(skb); - struct ipv6hdr *ipv6h = ipv6_hdr(skb); -@@ -1005,8 +1035,8 @@ - label = ip6_flowlabel(ipv6h); - } - -- tcp_v6_send_response(sk, skb, seq, ack_seq, 0, 0, 0, oif, key, 1, 0, -- label, priority); -+ tcp_v6_send_response(sk, skb, seq, ack_seq, 0, 0, 0, 0, oif, key, 1, 0, -+ label, priority, 0); - - #ifdef CONFIG_TCP_MD5SIG - out: -@@ -1015,30 +1045,37 @@ - } - - static void tcp_v6_send_ack(const struct sock *sk, struct sk_buff *skb, u32 seq, -- u32 ack, u32 win, u32 tsval, u32 tsecr, int oif, -+ u32 ack, u32 data_ack, u32 win, u32 tsval, u32 tsecr, int oif, - struct tcp_md5sig_key *key, u8 tclass, -- __be32 label, u32 priority) -+ __be32 label, u32 priority, int mptcp) - { -- tcp_v6_send_response(sk, skb, seq, ack, win, tsval, tsecr, oif, key, 0, -- tclass, label, priority); -+ tcp_v6_send_response(sk, skb, seq, ack, data_ack, win, tsval, tsecr, oif, -+ key, 0, tclass, label, priority, mptcp); - } - - static void tcp_v6_timewait_ack(struct sock *sk, struct sk_buff *skb) - { - struct inet_timewait_sock *tw = inet_twsk(sk); - struct tcp_timewait_sock *tcptw = tcp_twsk(sk); -+ u32 data_ack = 0; -+ int mptcp = 0; - -+ if (tcptw->mptcp_tw) { -+ data_ack = (u32)tcptw->mptcp_tw->rcv_nxt; -+ mptcp = 1; -+ } - tcp_v6_send_ack(sk, skb, tcptw->tw_snd_nxt, tcptw->tw_rcv_nxt, -+ data_ack, - tcptw->tw_rcv_wnd >> tw->tw_rcv_wscale, - tcp_time_stamp_raw() + tcptw->tw_ts_offset, - tcptw->tw_ts_recent, tw->tw_bound_dev_if, tcp_twsk_md5_key(tcptw), -- tw->tw_tclass, cpu_to_be32(tw->tw_flowlabel), tw->tw_priority); -+ tw->tw_tclass, cpu_to_be32(tw->tw_flowlabel), tw->tw_priority, mptcp); - - inet_twsk_put(tw); - } - --static void tcp_v6_reqsk_send_ack(const struct sock *sk, struct sk_buff *skb, -- struct request_sock *req) -+void tcp_v6_reqsk_send_ack(const struct sock *sk, struct sk_buff *skb, -+ struct request_sock *req) - { - /* sk->sk_state == TCP_LISTEN -> for regular TCP_SYN_RECV - * sk->sk_state == TCP_SYN_RECV -> for Fast Open. -@@ -1048,18 +1085,18 @@ - * exception of segments, MUST be right-shifted by - * Rcv.Wind.Shift bits: - */ -- tcp_v6_send_ack(sk, skb, (sk->sk_state == TCP_LISTEN) ? -+ tcp_v6_send_ack(sk, skb, (sk->sk_state == TCP_LISTEN || is_meta_sk(sk)) ? - tcp_rsk(req)->snt_isn + 1 : tcp_sk(sk)->snd_nxt, -- tcp_rsk(req)->rcv_nxt, -+ tcp_rsk(req)->rcv_nxt, 0, - req->rsk_rcv_wnd >> inet_rsk(req)->rcv_wscale, - tcp_time_stamp_raw() + tcp_rsk(req)->ts_off, - req->ts_recent, sk->sk_bound_dev_if, - tcp_v6_md5_do_lookup(sk, &ipv6_hdr(skb)->saddr), -- 0, 0, sk->sk_priority); -+ 0, 0, sk->sk_priority, 0); - } - - --static struct sock *tcp_v6_cookie_check(struct sock *sk, struct sk_buff *skb) -+struct sock *tcp_v6_cookie_check(struct sock *sk, struct sk_buff *skb) - { - #ifdef CONFIG_SYN_COOKIES - const struct tcphdr *th = tcp_hdr(skb); -@@ -1085,7 +1122,7 @@ - return mss; - } - --static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb) -+int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb) - { - if (skb->protocol == htons(ETH_P_IP)) - return tcp_v4_conn_request(sk, skb); -@@ -1111,11 +1148,11 @@ - sizeof(struct inet6_skb_parm)); - } - --static struct sock *tcp_v6_syn_recv_sock(const struct sock *sk, struct sk_buff *skb, -- struct request_sock *req, -- struct dst_entry *dst, -- struct request_sock *req_unhash, -- bool *own_req) -+struct sock *tcp_v6_syn_recv_sock(const struct sock *sk, struct sk_buff *skb, -+ struct request_sock *req, -+ struct dst_entry *dst, -+ struct request_sock *req_unhash, -+ bool *own_req) - { - struct inet_request_sock *ireq; - struct ipv6_pinfo *newnp; -@@ -1150,7 +1187,15 @@ - - newnp->saddr = newsk->sk_v6_rcv_saddr; - -- inet_csk(newsk)->icsk_af_ops = &ipv6_mapped; -+#ifdef CONFIG_MPTCP -+ /* We must check on the request-socket because the listener -+ * socket's flag may have been changed halfway through. -+ */ -+ if (!inet_rsk(req)->saw_mpc) -+ inet_csk(newsk)->icsk_af_ops = &mptcp_v6_mapped; -+ else -+#endif -+ inet_csk(newsk)->icsk_af_ops = &ipv6_mapped; - newsk->sk_backlog_rcv = tcp_v4_do_rcv; - #ifdef CONFIG_TCP_MD5SIG - newtp->af_specific = &tcp_sock_ipv6_mapped_specific; -@@ -1197,6 +1242,14 @@ - if (!newsk) - goto out_nonewsk; - -+#ifdef CONFIG_MPTCP -+ /* If the meta_sk is v6-mapped we can end up here with the wrong af_ops. -+ * Just make sure that this subflow is v6. -+ */ -+ if (is_meta_sk(sk)) -+ inet_csk(newsk)->icsk_af_ops = &mptcp_v6_specific; -+#endif -+ - /* - * No need to charge this sock to the relevant IPv6 refcnt debug socks - * count here, tcp_create_openreq_child now does this for us, see the -@@ -1324,7 +1377,7 @@ - * This is because we cannot sleep with the original spinlock - * held. - */ --static int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb) -+int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb) - { - struct ipv6_pinfo *np = tcp_inet6_sk(sk); - struct sk_buff *opt_skb = NULL; -@@ -1341,6 +1394,9 @@ - if (skb->protocol == htons(ETH_P_IP)) - return tcp_v4_do_rcv(sk, skb); - -+ if (is_meta_sk(sk)) -+ return mptcp_v6_do_rcv(sk, skb); -+ - /* - * socket locking is here for SMP purposes as backlog rcv - * is currently called with bh processing disabled. -@@ -1468,6 +1524,10 @@ - TCP_SKB_CB(skb)->end_seq = (TCP_SKB_CB(skb)->seq + th->syn + th->fin + - skb->len - th->doff*4); - TCP_SKB_CB(skb)->ack_seq = ntohl(th->ack_seq); -+#ifdef CONFIG_MPTCP -+ TCP_SKB_CB(skb)->mptcp_flags = 0; -+ TCP_SKB_CB(skb)->dss_off = 0; -+#endif - TCP_SKB_CB(skb)->tcp_flags = tcp_flag_byte(th); - TCP_SKB_CB(skb)->tcp_tw_isn = 0; - TCP_SKB_CB(skb)->ip_dsfield = ipv6_get_dsfield(hdr); -@@ -1482,8 +1542,8 @@ - int sdif = inet6_sdif(skb); - const struct tcphdr *th; - const struct ipv6hdr *hdr; -+ struct sock *sk, *meta_sk = NULL; - bool refcounted; -- struct sock *sk; - int ret; - struct net *net = dev_net(skb->dev); - -@@ -1537,12 +1597,17 @@ - reqsk_put(req); - goto csum_error; - } -- if (unlikely(sk->sk_state != TCP_LISTEN)) { -+ if (unlikely(sk->sk_state != TCP_LISTEN && !is_meta_sk(sk))) { -+ inet_csk_reqsk_queue_drop_and_put(sk, req); -+ goto lookup; -+ } -+ if (unlikely(is_meta_sk(sk) && !mptcp_can_new_subflow(sk))) { - inet_csk_reqsk_queue_drop_and_put(sk, req); - goto lookup; - } - sock_hold(sk); - refcounted = true; -+ - nsk = NULL; - if (!tcp_filter(sk, skb)) { - th = (const struct tcphdr *)skb->data; -@@ -1601,19 +1666,28 @@ - - sk_incoming_cpu_update(sk); - -- bh_lock_sock_nested(sk); -+ if (mptcp(tcp_sk(sk))) { -+ meta_sk = mptcp_meta_sk(sk); -+ -+ bh_lock_sock_nested(meta_sk); -+ if (sock_owned_by_user(meta_sk)) -+ mptcp_prepare_for_backlog(sk, skb); -+ } else { -+ meta_sk = sk; -+ bh_lock_sock_nested(sk); -+ } - tcp_segs_in(tcp_sk(sk), skb); - ret = 0; -- if (!sock_owned_by_user(sk)) { -+ if (!sock_owned_by_user(meta_sk)) { - skb_to_free = sk->sk_rx_skb_cache; - sk->sk_rx_skb_cache = NULL; - ret = tcp_v6_do_rcv(sk, skb); - } else { -- if (tcp_add_backlog(sk, skb)) -+ if (tcp_add_backlog(meta_sk, skb)) - goto discard_and_relse; - skb_to_free = NULL; - } -- bh_unlock_sock(sk); -+ bh_unlock_sock(meta_sk); - if (skb_to_free) - __kfree_skb(skb_to_free); - put_and_return: -@@ -1627,6 +1701,19 @@ - - tcp_v6_fill_cb(skb, hdr, th); - -+#ifdef CONFIG_MPTCP -+ if (!sk && th->syn && !th->ack) { -+ int ret = mptcp_lookup_join(skb, NULL); -+ -+ if (ret < 0) { -+ tcp_v6_send_reset(NULL, skb); -+ goto discard_it; -+ } else if (ret > 0) { -+ return 0; -+ } -+ } -+#endif -+ - if (tcp_checksum_complete(skb)) { - csum_error: - __TCP_INC_STATS(net, TCP_MIB_CSUMERRORS); -@@ -1679,6 +1766,18 @@ - refcounted = false; - goto process; - } -+#ifdef CONFIG_MPTCP -+ if (th->syn && !th->ack) { -+ int ret = mptcp_lookup_join(skb, inet_twsk(sk)); -+ -+ if (ret < 0) { -+ tcp_v6_send_reset(NULL, skb); -+ goto discard_it; -+ } else if (ret > 0) { -+ return 0; -+ } -+ } -+#endif - } - /* to ACK */ - /* fall through */ -@@ -1733,13 +1832,13 @@ - } - } - --static struct timewait_sock_ops tcp6_timewait_sock_ops = { -+struct timewait_sock_ops tcp6_timewait_sock_ops = { - .twsk_obj_size = sizeof(struct tcp6_timewait_sock), - .twsk_unique = tcp_twsk_unique, - .twsk_destructor = tcp_twsk_destructor, - }; - --static const struct inet_connection_sock_af_ops ipv6_specific = { -+const struct inet_connection_sock_af_ops ipv6_specific = { - .queue_xmit = inet6_csk_xmit, - .send_check = tcp_v6_send_check, - .rebuild_header = inet6_sk_rebuild_header, -@@ -1770,7 +1869,7 @@ - /* - * TCP over IPv4 via INET6 API - */ --static const struct inet_connection_sock_af_ops ipv6_mapped = { -+const struct inet_connection_sock_af_ops ipv6_mapped = { - .queue_xmit = ip_queue_xmit, - .send_check = tcp_v4_send_check, - .rebuild_header = inet_sk_rebuild_header, -@@ -1806,7 +1905,12 @@ - - tcp_init_sock(sk); - -- icsk->icsk_af_ops = &ipv6_specific; -+#ifdef CONFIG_MPTCP -+ if (sock_flag(sk, SOCK_MPTCP)) -+ icsk->icsk_af_ops = &mptcp_v6_specific; -+ else -+#endif -+ icsk->icsk_af_ops = &ipv6_specific; - - #ifdef CONFIG_TCP_MD5SIG - tcp_sk(sk)->af_specific = &tcp_sock_ipv6_specific; -@@ -1815,7 +1919,7 @@ - return 0; - } - --static void tcp_v6_destroy_sock(struct sock *sk) -+void tcp_v6_destroy_sock(struct sock *sk) - { - tcp_v4_destroy_sock(sk); - inet6_destroy_sock(sk); -@@ -2038,6 +2142,11 @@ - .sysctl_rmem_offset = offsetof(struct net, ipv4.sysctl_tcp_rmem), - .max_header = MAX_TCP_HEADER, - .obj_size = sizeof(struct tcp6_sock), -+#ifdef CONFIG_MPTCP -+ .useroffset = offsetof(struct tcp_sock, mptcp_sched_name), -+ .usersize = sizeof_field(struct tcp_sock, mptcp_sched_name) + -+ sizeof_field(struct tcp_sock, mptcp_pm_name), -+#endif - .slab_flags = SLAB_TYPESAFE_BY_RCU, - .twsk_prot = &tcp6_timewait_sock_ops, - .rsk_prot = &tcp6_request_sock_ops, -@@ -2048,6 +2157,9 @@ - .compat_getsockopt = compat_tcp_getsockopt, - #endif - .diag_destroy = tcp_abort, -+#ifdef CONFIG_MPTCP -+ .clear_sk = mptcp_clear_sk, -+#endif - }; - - /* thinking of making this const? Don't. -diff -aurN linux-5.4.64/net/Kconfig linux-5.4.64.mptcp/net/Kconfig ---- linux-5.4.64/net/Kconfig 2020-09-09 19:12:37.000000000 +0200 -+++ linux-5.4.64.mptcp/net/Kconfig 2020-09-10 19:25:10.507220869 +0200 -@@ -94,6 +94,7 @@ - source "net/ipv4/Kconfig" - source "net/ipv6/Kconfig" - source "net/netlabel/Kconfig" -+source "net/mptcp/Kconfig" - - endif # if INET - -diff -aurN linux-5.4.64/net/Makefile linux-5.4.64.mptcp/net/Makefile ---- linux-5.4.64/net/Makefile 2020-09-09 19:12:37.000000000 +0200 -+++ linux-5.4.64.mptcp/net/Makefile 2020-09-10 19:25:10.507220869 +0200 -@@ -20,6 +20,7 @@ - obj-$(CONFIG_XFRM) += xfrm/ - obj-$(CONFIG_UNIX_SCM) += unix/ - obj-$(CONFIG_NET) += ipv6/ -+obj-$(CONFIG_MPTCP) += mptcp/ - obj-$(CONFIG_BPFILTER) += bpfilter/ - obj-$(CONFIG_PACKET) += packet/ - obj-$(CONFIG_NET_KEY) += key/ -diff -aurN linux-5.4.64/net/mptcp/Kconfig linux-5.4.64.mptcp/net/mptcp/Kconfig ---- linux-5.4.64/net/mptcp/Kconfig 1970-01-01 01:00:00.000000000 +0100 -+++ linux-5.4.64.mptcp/net/mptcp/Kconfig 2020-09-10 19:25:10.507220869 +0200 -@@ -0,0 +1,154 @@ -+# -+# MPTCP configuration -+# -+config MPTCP -+ bool "MPTCP protocol" -+ depends on (IPV6=y || IPV6=n) -+ select CRYPTO_LIB_SHA256 -+ select CRYPTO -+ ---help--- -+ This replaces the normal TCP stack with a Multipath TCP stack, -+ able to use several paths at once. -+ -+menuconfig MPTCP_PM_ADVANCED -+ bool "MPTCP: advanced path-manager control" -+ depends on MPTCP=y -+ ---help--- -+ Support for selection of different path-managers. You should choose 'Y' here, -+ because otherwise you will not actively create new MPTCP-subflows. -+ -+if MPTCP_PM_ADVANCED -+ -+config MPTCP_FULLMESH -+ tristate "MPTCP Full-Mesh Path-Manager" -+ depends on MPTCP=y -+ ---help--- -+ This path-management module will create a full-mesh among all IP-addresses. -+ -+config MPTCP_NDIFFPORTS -+ tristate "MPTCP ndiff-ports" -+ depends on MPTCP=y -+ ---help--- -+ This path-management module will create multiple subflows between the same -+ pair of IP-addresses, modifying the source-port. You can set the number -+ of subflows via the mptcp_ndiffports-sysctl. -+ -+config MPTCP_BINDER -+ tristate "MPTCP Binder" -+ depends on (MPTCP=y) -+ ---help--- -+ This path-management module works like ndiffports, and adds the sysctl -+ option to set the gateway (and/or path to) per each additional subflow -+ via Loose Source Routing (IPv4 only). -+ -+config MPTCP_NETLINK -+ tristate "MPTCP Netlink Path-Manager" -+ depends on MPTCP=y -+ ---help--- -+ This path-management module is controlled over a Netlink interface. A userspace -+ module can therefore control the establishment of new subflows and the policy -+ to apply over those new subflows for every connection. -+ -+choice -+ prompt "Default MPTCP Path-Manager" -+ default DEFAULT_DUMMY -+ help -+ Select the Path-Manager of your choice -+ -+ config DEFAULT_FULLMESH -+ bool "Full mesh" if MPTCP_FULLMESH=y -+ -+ config DEFAULT_NDIFFPORTS -+ bool "ndiff-ports" if MPTCP_NDIFFPORTS=y -+ -+ config DEFAULT_BINDER -+ bool "binder" if MPTCP_BINDER=y -+ -+ config DEFAULT_NETLINK -+ bool "Netlink" if MPTCP_NETLINK=y -+ -+ config DEFAULT_DUMMY -+ bool "Default" -+ -+endchoice -+ -+endif -+ -+config DEFAULT_MPTCP_PM -+ string -+ default "default" if DEFAULT_DUMMY -+ default "fullmesh" if DEFAULT_FULLMESH -+ default "ndiffports" if DEFAULT_NDIFFPORTS -+ default "binder" if DEFAULT_BINDER -+ default "default" -+ -+menuconfig MPTCP_SCHED_ADVANCED -+ bool "MPTCP: advanced scheduler control" -+ depends on MPTCP=y -+ ---help--- -+ Support for selection of different schedulers. You should choose 'Y' here, -+ if you want to choose a different scheduler than the default one. -+ -+if MPTCP_SCHED_ADVANCED -+ -+config MPTCP_BLEST -+ tristate "MPTCP BLEST" -+ depends on MPTCP=y -+ ---help--- -+ This is an experimental BLocking ESTimation-based (BLEST) scheduler. -+ -+config MPTCP_ROUNDROBIN -+ tristate "MPTCP Round-Robin" -+ depends on (MPTCP=y) -+ ---help--- -+ This is a very simple round-robin scheduler. Probably has bad performance -+ but might be interesting for researchers. -+ -+config MPTCP_REDUNDANT -+ tristate "MPTCP Redundant" -+ depends on (MPTCP=y) -+ ---help--- -+ This scheduler sends all packets redundantly over all subflows to decreases -+ latency and jitter on the cost of lower throughput. -+ -+config MPTCP_ECF -+ tristate "MPTCP ECF" -+ depends on (MPTCP=y) -+ ---help--- -+ This is an experimental Earliest Completion First (ECF) scheduler. -+ -+choice -+ prompt "Default MPTCP Scheduler" -+ default DEFAULT_SCHEDULER -+ help -+ Select the Scheduler of your choice -+ -+ config DEFAULT_SCHEDULER -+ bool "Default" -+ ---help--- -+ This is the default scheduler, sending first on the subflow -+ with the lowest RTT. -+ -+ config DEFAULT_ROUNDROBIN -+ bool "Round-Robin" if MPTCP_ROUNDROBIN=y -+ ---help--- -+ This is the round-rob scheduler, sending in a round-robin -+ fashion.. -+ -+ config DEFAULT_REDUNDANT -+ bool "Redundant" if MPTCP_REDUNDANT=y -+ ---help--- -+ This is the redundant scheduler, sending packets redundantly over -+ all the subflows. -+ -+endchoice -+endif -+ -+config DEFAULT_MPTCP_SCHED -+ string -+ depends on (MPTCP=y) -+ default "default" if DEFAULT_SCHEDULER -+ default "roundrobin" if DEFAULT_ROUNDROBIN -+ default "redundant" if DEFAULT_REDUNDANT -+ default "default" -+ -diff -aurN linux-5.4.64/net/mptcp/Makefile linux-5.4.64.mptcp/net/mptcp/Makefile ---- linux-5.4.64/net/mptcp/Makefile 1970-01-01 01:00:00.000000000 +0100 -+++ linux-5.4.64.mptcp/net/mptcp/Makefile 2020-09-10 19:25:10.507220869 +0200 -@@ -0,0 +1,25 @@ -+# -+## Makefile for MultiPath TCP support code. -+# -+# -+ -+obj-$(CONFIG_MPTCP) += mptcp.o -+ -+mptcp-y := mptcp_ctrl.o mptcp_ipv4.o mptcp_pm.o \ -+ mptcp_output.o mptcp_input.o mptcp_sched.o -+ -+obj-$(CONFIG_TCP_CONG_LIA) += mptcp_coupled.o -+obj-$(CONFIG_TCP_CONG_OLIA) += mptcp_olia.o -+obj-$(CONFIG_TCP_CONG_WVEGAS) += mptcp_wvegas.o -+obj-$(CONFIG_TCP_CONG_BALIA) += mptcp_balia.o -+obj-$(CONFIG_TCP_CONG_MCTCPDESYNC) += mctcp_desync.o -+obj-$(CONFIG_MPTCP_FULLMESH) += mptcp_fullmesh.o -+obj-$(CONFIG_MPTCP_NDIFFPORTS) += mptcp_ndiffports.o -+obj-$(CONFIG_MPTCP_BINDER) += mptcp_binder.o -+obj-$(CONFIG_MPTCP_NETLINK) += mptcp_netlink.o -+obj-$(CONFIG_MPTCP_ROUNDROBIN) += mptcp_rr.o -+obj-$(CONFIG_MPTCP_REDUNDANT) += mptcp_redundant.o -+obj-$(CONFIG_MPTCP_BLEST) += mptcp_blest.o -+obj-$(CONFIG_MPTCP_ECF) += mptcp_ecf.o -+ -+mptcp-$(subst m,y,$(CONFIG_IPV6)) += mptcp_ipv6.o -diff -aurN linux-5.4.64/net/mptcp/mctcp_desync.c linux-5.4.64.mptcp/net/mptcp/mctcp_desync.c ---- linux-5.4.64/net/mptcp/mctcp_desync.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-5.4.64.mptcp/net/mptcp/mctcp_desync.c 2020-09-10 19:25:10.507220869 +0200 -@@ -0,0 +1,193 @@ -+/* -+ * Desynchronized Multi-Channel TCP Congestion Control Algorithm -+ * -+ * Implementation based on publications of "DMCTCP:Desynchronized Multi-Channel -+ * TCP for high speed access networks with tiny buffers" in 23rd international -+ * conference of Computer Communication and Networks (ICCCN), 2014, and -+ * "Exploring parallelism and desynchronization of TCP over high speed networks -+ * with tiny buffers" in Journal of Computer Communications Elsevier, 2015. -+ * -+ * http://ieeexplore.ieee.org/abstract/document/6911722/ -+ * https://doi.org/10.1016/j.comcom.2015.07.010 -+ * -+ * This prototype is for research purpose and is currently experimental code -+ * that only support a single path. Future support of multi-channel over -+ * multi-path requires channels grouping. -+ * -+ * Initial Design and Implementation: -+ * Cheng Cui -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the Free -+ * Software Foundation; either version 2 of the License, or (at your option) -+ * any later version. -+ */ -+#include -+#include -+#include -+ -+enum { -+ MASTER_CHANNEL = 1, -+ INI_MIN_CWND = 2, -+}; -+ -+/* private congestion control structure: -+ * off_tstamp: the last backoff timestamp for loss synchronization event -+ * off_subfid: the subflow which was backoff on off_tstamp -+ */ -+struct mctcp_desync { -+ u64 off_tstamp; -+ u8 off_subfid; -+}; -+ -+static inline int mctcp_cc_sk_can_send(const struct sock *sk) -+{ -+ return mptcp_sk_can_send(sk) && tcp_sk(sk)->srtt_us; -+} -+ -+static void mctcp_desync_init(struct sock *sk) -+{ -+ if (mptcp(tcp_sk(sk))) { -+ struct mctcp_desync *ca = inet_csk_ca(mptcp_meta_sk(sk)); -+ ca->off_tstamp = 0; -+ ca->off_subfid = 0; -+ } -+ /* If we do not mptcp, behave like reno: return */ -+} -+ -+static void mctcp_desync_cong_avoid(struct sock *sk, u32 ack, u32 acked) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ -+ if (!mptcp(tp)) { -+ tcp_reno_cong_avoid(sk, ack, acked); -+ return; -+ } else if (!tcp_is_cwnd_limited(sk)) { -+ return; -+ } else { -+ const struct mctcp_desync *ca = inet_csk_ca(mptcp_meta_sk(sk)); -+ const u8 subfid = tp->mptcp->path_index; -+ -+ /* current aggregated cwnd */ -+ u32 agg_cwnd = 0; -+ u32 min_cwnd = 0xffffffff; -+ u8 min_cwnd_subfid = 0; -+ -+ /* In "safe" area, increase */ -+ if (tcp_in_slow_start(tp)) { -+ if (ca->off_subfid) { -+ /* passed initial phase, allow slow start */ -+ tcp_slow_start(tp, acked); -+ } else if (MASTER_CHANNEL == tp->mptcp->path_index) { -+ /* master channel is normal slow start in -+ * initial phase */ -+ tcp_slow_start(tp, acked); -+ } else { -+ /* secondary channels increase slowly until -+ * the initial phase passed -+ */ -+ tp->snd_ssthresh = tp->snd_cwnd = INI_MIN_CWND; -+ } -+ return; -+ } else { -+ /* In dangerous area, increase slowly and linearly. */ -+ const struct mptcp_tcp_sock *mptcp; -+ -+ /* get total cwnd and the subflow that has min cwnd */ -+ mptcp_for_each_sub(tp->mpcb, mptcp) { -+ const struct sock *sub_sk = mptcp_to_sock(mptcp); -+ -+ if (mctcp_cc_sk_can_send(sub_sk)) { -+ const struct tcp_sock *sub_tp = -+ tcp_sk(sub_sk); -+ agg_cwnd += sub_tp->snd_cwnd; -+ if(min_cwnd > sub_tp->snd_cwnd) { -+ min_cwnd = sub_tp->snd_cwnd; -+ min_cwnd_subfid = -+ sub_tp->mptcp->path_index; -+ } -+ } -+ } -+ /* the smallest subflow grows faster than others */ -+ if (subfid == min_cwnd_subfid) { -+ tcp_cong_avoid_ai(tp, min_cwnd, acked); -+ } else { -+ tcp_cong_avoid_ai(tp, agg_cwnd - min_cwnd, -+ acked); -+ } -+ } -+ } -+} -+ -+static u32 mctcp_desync_ssthresh(struct sock *sk) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ -+ if (!mptcp(tp)) { -+ return max(tp->snd_cwnd >> 1U, 2U); -+ } else { -+ struct mctcp_desync *ca = inet_csk_ca(mptcp_meta_sk(sk)); -+ const u8 subfid = tp->mptcp->path_index; -+ const struct mptcp_tcp_sock *mptcp; -+ u32 max_cwnd = 0; -+ u8 max_cwnd_subfid = 0; -+ -+ /* Find the subflow that has the max cwnd. */ -+ mptcp_for_each_sub(tp->mpcb, mptcp) { -+ const struct sock *sub_sk = mptcp_to_sock(mptcp); -+ -+ if (mctcp_cc_sk_can_send(sub_sk)) { -+ const struct tcp_sock *sub_tp = tcp_sk(sub_sk); -+ if (max_cwnd < sub_tp->snd_cwnd) { -+ max_cwnd = sub_tp->snd_cwnd; -+ max_cwnd_subfid = -+ sub_tp->mptcp->path_index; -+ } -+ } -+ } -+ /* Use high resolution clock. */ -+ if (subfid == max_cwnd_subfid) { -+ u64 now = tcp_clock_us(); -+ u32 delta = tcp_stamp_us_delta(now, ca->off_tstamp); -+ -+ if (delta < (tp->srtt_us >> 3)) { -+ /* desynchronize */ -+ return tp->snd_cwnd; -+ } else { -+ ca->off_tstamp = now; -+ ca->off_subfid = subfid; -+ return max(max_cwnd >> 1U, 2U); -+ } -+ } else { -+ return tp->snd_cwnd; -+ } -+ } -+} -+ -+static struct tcp_congestion_ops mctcp_desync = { -+ .init = mctcp_desync_init, -+ .ssthresh = mctcp_desync_ssthresh, -+ .undo_cwnd = tcp_reno_undo_cwnd, -+ .cong_avoid = mctcp_desync_cong_avoid, -+ .owner = THIS_MODULE, -+ .name = "mctcpdesync", -+}; -+ -+static int __init mctcp_desync_register(void) -+{ -+ BUILD_BUG_ON(sizeof(struct mctcp_desync) > ICSK_CA_PRIV_SIZE); -+ return tcp_register_congestion_control(&mctcp_desync); -+} -+ -+static void __exit mctcp_desync_unregister(void) -+{ -+ tcp_unregister_congestion_control(&mctcp_desync); -+} -+ -+module_init(mctcp_desync_register); -+module_exit(mctcp_desync_unregister); -+ -+MODULE_AUTHOR("Cheng Cui"); -+MODULE_LICENSE("GPL"); -+MODULE_DESCRIPTION("MCTCP: DESYNCHRONIZED MULTICHANNEL TCP CONGESTION CONTROL"); -+MODULE_VERSION("1.0"); -diff -aurN linux-5.4.64/net/mptcp/mptcp_balia.c linux-5.4.64.mptcp/net/mptcp/mptcp_balia.c ---- linux-5.4.64/net/mptcp/mptcp_balia.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-5.4.64.mptcp/net/mptcp/mptcp_balia.c 2020-09-10 19:25:10.507220869 +0200 -@@ -0,0 +1,261 @@ -+/* -+ * MPTCP implementation - Balia Congestion Control -+ * (Balanced Linked Adaptation Algorithm) -+ * -+ * Analysis, Design and Implementation: -+ * Qiuyu Peng -+ * Anwar Walid -+ * Jaehyun Hwang -+ * Steven H. Low -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version -+ * 2 of the License, or (at your option) any later version. -+ */ -+ -+#include -+#include -+ -+#include -+ -+/* The variable 'rate' (i.e., x_r) will be scaled -+ * e.g., from B/s to KB/s, MB/s, or GB/s -+ * if max_rate > 2^rate_scale_limit -+ */ -+ -+static int rate_scale_limit = 25; -+static int alpha_scale = 10; -+static int scale_num = 5; -+ -+struct mptcp_balia { -+ u64 ai; -+ u64 md; -+ bool forced_update; -+}; -+ -+static inline int mptcp_balia_sk_can_send(const struct sock *sk) -+{ -+ return mptcp_sk_can_send(sk) && tcp_sk(sk)->srtt_us; -+} -+ -+static inline u64 mptcp_get_ai(const struct sock *meta_sk) -+{ -+ return ((struct mptcp_balia *)inet_csk_ca(meta_sk))->ai; -+} -+ -+static inline void mptcp_set_ai(const struct sock *meta_sk, u64 ai) -+{ -+ ((struct mptcp_balia *)inet_csk_ca(meta_sk))->ai = ai; -+} -+ -+static inline u64 mptcp_get_md(const struct sock *meta_sk) -+{ -+ return ((struct mptcp_balia *)inet_csk_ca(meta_sk))->md; -+} -+ -+static inline void mptcp_set_md(const struct sock *meta_sk, u64 md) -+{ -+ ((struct mptcp_balia *)inet_csk_ca(meta_sk))->md = md; -+} -+ -+static inline u64 mptcp_balia_scale(u64 val, int scale) -+{ -+ return (u64) val << scale; -+} -+ -+static inline bool mptcp_get_forced(const struct sock *meta_sk) -+{ -+ return ((struct mptcp_balia *)inet_csk_ca(meta_sk))->forced_update; -+} -+ -+static inline void mptcp_set_forced(const struct sock *meta_sk, bool force) -+{ -+ ((struct mptcp_balia *)inet_csk_ca(meta_sk))->forced_update = force; -+} -+ -+static void mptcp_balia_recalc_ai(const struct sock *sk) -+{ -+ const struct tcp_sock *tp = tcp_sk(sk); -+ const struct mptcp_cb *mpcb = tp->mpcb; -+ struct mptcp_tcp_sock *mptcp; -+ u64 max_rate = 0, rate = 0, sum_rate = 0; -+ u64 alpha, ai = tp->snd_cwnd, md = (tp->snd_cwnd >> 1); -+ int num_scale_down = 0; -+ -+ if (!mpcb) -+ return; -+ -+ /* Find max_rate first */ -+ mptcp_for_each_sub(mpcb, mptcp) { -+ const struct sock *sub_sk = mptcp_to_sock(mptcp); -+ struct tcp_sock *sub_tp = tcp_sk(sub_sk); -+ u64 tmp; -+ -+ if (!mptcp_balia_sk_can_send(sub_sk)) -+ continue; -+ -+ tmp = div_u64((u64)tp->mss_cache * sub_tp->snd_cwnd -+ * (USEC_PER_SEC << 3), sub_tp->srtt_us); -+ sum_rate += tmp; -+ -+ if (tp == sub_tp) -+ rate = tmp; -+ -+ if (tmp >= max_rate) -+ max_rate = tmp; -+ } -+ -+ /* At least, the current subflow should be able to send */ -+ if (unlikely(!rate)) -+ goto exit; -+ -+ alpha = div64_u64(max_rate, rate); -+ -+ /* Scale down max_rate if it is too high (e.g., >2^25) */ -+ while (max_rate > mptcp_balia_scale(1, rate_scale_limit)) { -+ max_rate >>= scale_num; -+ num_scale_down++; -+ } -+ -+ if (num_scale_down) { -+ sum_rate = 0; -+ mptcp_for_each_sub(mpcb, mptcp) { -+ const struct sock *sub_sk = mptcp_to_sock(mptcp); -+ struct tcp_sock *sub_tp = tcp_sk(sub_sk); -+ u64 tmp; -+ -+ if (!mptcp_balia_sk_can_send(sub_sk)) -+ continue; -+ -+ tmp = div_u64((u64)tp->mss_cache * sub_tp->snd_cwnd -+ * (USEC_PER_SEC << 3), sub_tp->srtt_us); -+ tmp >>= (scale_num * num_scale_down); -+ -+ sum_rate += tmp; -+ } -+ rate >>= (scale_num * num_scale_down); -+ } -+ -+ /* (sum_rate)^2 * 10 * w_r -+ * ai = ------------------------------------ -+ * (x_r + max_rate) * (4x_r + max_rate) -+ */ -+ sum_rate *= sum_rate; -+ -+ ai = div64_u64(sum_rate * 10, rate + max_rate); -+ ai = div64_u64(ai * tp->snd_cwnd, (rate << 2) + max_rate); -+ -+ if (unlikely(!ai)) -+ ai = tp->snd_cwnd; -+ -+ md = ((tp->snd_cwnd >> 1) * min(mptcp_balia_scale(alpha, alpha_scale), -+ mptcp_balia_scale(3, alpha_scale) >> 1)) -+ >> alpha_scale; -+ -+exit: -+ mptcp_set_ai(sk, ai); -+ mptcp_set_md(sk, md); -+} -+ -+static void mptcp_balia_init(struct sock *sk) -+{ -+ if (mptcp(tcp_sk(sk))) { -+ mptcp_set_forced(sk, 0); -+ mptcp_set_ai(sk, 0); -+ mptcp_set_md(sk, 0); -+ } -+} -+ -+static void mptcp_balia_cwnd_event(struct sock *sk, enum tcp_ca_event event) -+{ -+ if (event == CA_EVENT_COMPLETE_CWR || event == CA_EVENT_LOSS) -+ mptcp_balia_recalc_ai(sk); -+} -+ -+static void mptcp_balia_set_state(struct sock *sk, u8 ca_state) -+{ -+ if (!mptcp(tcp_sk(sk))) -+ return; -+ -+ mptcp_set_forced(sk, 1); -+} -+ -+static void mptcp_balia_cong_avoid(struct sock *sk, u32 ack, u32 acked) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ int snd_cwnd; -+ -+ if (!mptcp(tp)) { -+ tcp_reno_cong_avoid(sk, ack, acked); -+ return; -+ } -+ -+ if (!tcp_is_cwnd_limited(sk)) -+ return; -+ -+ if (tcp_in_slow_start(tp)) { -+ /* In "safe" area, increase. */ -+ tcp_slow_start(tp, acked); -+ mptcp_balia_recalc_ai(sk); -+ return; -+ } -+ -+ if (mptcp_get_forced(mptcp_meta_sk(sk))) { -+ mptcp_balia_recalc_ai(sk); -+ mptcp_set_forced(sk, 0); -+ } -+ -+ snd_cwnd = (int)mptcp_get_ai(sk); -+ -+ if (tp->snd_cwnd_cnt >= snd_cwnd) { -+ if (tp->snd_cwnd < tp->snd_cwnd_clamp) { -+ tp->snd_cwnd++; -+ mptcp_balia_recalc_ai(sk); -+ } -+ -+ tp->snd_cwnd_cnt = 0; -+ } else { -+ tp->snd_cwnd_cnt++; -+ } -+} -+ -+static u32 mptcp_balia_ssthresh(struct sock *sk) -+{ -+ const struct tcp_sock *tp = tcp_sk(sk); -+ -+ if (unlikely(!mptcp(tp))) -+ return tcp_reno_ssthresh(sk); -+ else -+ return max((u32)(tp->snd_cwnd - mptcp_get_md(sk)), 1U); -+} -+ -+static struct tcp_congestion_ops mptcp_balia = { -+ .init = mptcp_balia_init, -+ .ssthresh = mptcp_balia_ssthresh, -+ .cong_avoid = mptcp_balia_cong_avoid, -+ .undo_cwnd = tcp_reno_undo_cwnd, -+ .cwnd_event = mptcp_balia_cwnd_event, -+ .set_state = mptcp_balia_set_state, -+ .owner = THIS_MODULE, -+ .name = "balia", -+}; -+ -+static int __init mptcp_balia_register(void) -+{ -+ BUILD_BUG_ON(sizeof(struct mptcp_balia) > ICSK_CA_PRIV_SIZE); -+ return tcp_register_congestion_control(&mptcp_balia); -+} -+ -+static void __exit mptcp_balia_unregister(void) -+{ -+ tcp_unregister_congestion_control(&mptcp_balia); -+} -+ -+module_init(mptcp_balia_register); -+module_exit(mptcp_balia_unregister); -+ -+MODULE_AUTHOR("Jaehyun Hwang, Anwar Walid, Qiuyu Peng, Steven H. Low"); -+MODULE_LICENSE("GPL"); -+MODULE_DESCRIPTION("MPTCP BALIA CONGESTION CONTROL ALGORITHM"); -+MODULE_VERSION("0.1"); -diff -aurN linux-5.4.64/net/mptcp/mptcp_binder.c linux-5.4.64.mptcp/net/mptcp/mptcp_binder.c ---- linux-5.4.64/net/mptcp/mptcp_binder.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-5.4.64.mptcp/net/mptcp/mptcp_binder.c 2020-09-10 19:25:10.507220869 +0200 -@@ -0,0 +1,494 @@ -+#include -+ -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define MPTCP_GW_MAX_LISTS 10 -+#define MPTCP_GW_LIST_MAX_LEN 6 -+#define MPTCP_GW_SYSCTL_MAX_LEN (15 * MPTCP_GW_LIST_MAX_LEN * \ -+ MPTCP_GW_MAX_LISTS) -+ -+struct mptcp_gw_list { -+ struct in_addr list[MPTCP_GW_MAX_LISTS][MPTCP_GW_LIST_MAX_LEN]; -+ u8 len[MPTCP_GW_MAX_LISTS]; -+}; -+ -+struct binder_priv { -+ /* Worker struct for subflow establishment */ -+ struct work_struct subflow_work; -+ -+ struct mptcp_cb *mpcb; -+ -+ /* Prevent multiple sub-sockets concurrently iterating over sockets */ -+ spinlock_t *flow_lock; -+}; -+ -+static struct mptcp_gw_list *mptcp_gws; -+static rwlock_t mptcp_gws_lock; -+ -+static int mptcp_binder_ndiffports __read_mostly = 1; -+ -+static char sysctl_mptcp_binder_gateways[MPTCP_GW_SYSCTL_MAX_LEN] __read_mostly; -+ -+static int mptcp_get_avail_list_ipv4(struct sock *sk) -+{ -+ int i, j, list_taken, opt_ret, opt_len; -+ unsigned char *opt_ptr, *opt_end_ptr, opt[MAX_IPOPTLEN]; -+ -+ for (i = 0; i < MPTCP_GW_MAX_LISTS; ++i) { -+ struct mptcp_tcp_sock *mptcp; -+ -+ if (mptcp_gws->len[i] == 0) -+ goto error; -+ -+ mptcp_debug("mptcp_get_avail_list_ipv4: List %i\n", i); -+ list_taken = 0; -+ -+ /* Loop through all sub-sockets in this connection */ -+ mptcp_for_each_sub(tcp_sk(sk)->mpcb, mptcp) { -+ sk = mptcp_to_sock(mptcp); -+ -+ mptcp_debug("mptcp_get_avail_list_ipv4: Next sock\n"); -+ -+ /* Reset length and options buffer, then retrieve -+ * from socket -+ */ -+ opt_len = MAX_IPOPTLEN; -+ memset(opt, 0, MAX_IPOPTLEN); -+ opt_ret = ip_getsockopt(sk, IPPROTO_IP, -+ IP_OPTIONS, (char __user *)opt, (int __user *)&opt_len); -+ if (opt_ret < 0) { -+ mptcp_debug("%s: MPTCP subsocket getsockopt() IP_OPTIONS failed, error %d\n", -+ __func__, opt_ret); -+ goto error; -+ } -+ -+ /* If socket has no options, it has no stake in this list */ -+ if (opt_len <= 0) -+ continue; -+ -+ /* Iterate options buffer */ -+ for (opt_ptr = &opt[0]; opt_ptr < &opt[opt_len]; opt_ptr++) { -+ if (*opt_ptr == IPOPT_LSRR) { -+ mptcp_debug("mptcp_get_avail_list_ipv4: LSRR options found\n"); -+ goto sock_lsrr; -+ } -+ } -+ continue; -+ -+sock_lsrr: -+ /* Pointer to the 2nd to last address */ -+ opt_end_ptr = opt_ptr+(*(opt_ptr+1))-4; -+ -+ /* Addresses start 3 bytes after type offset */ -+ opt_ptr += 3; -+ j = 0; -+ -+ /* Different length lists cannot be the same */ -+ if ((opt_end_ptr-opt_ptr)/4 != mptcp_gws->len[i]) -+ continue; -+ -+ /* Iterate if we are still inside options list -+ * and sysctl list -+ */ -+ while (opt_ptr < opt_end_ptr && j < mptcp_gws->len[i]) { -+ /* If there is a different address, this list must -+ * not be set on this socket -+ */ -+ if (memcmp(&mptcp_gws->list[i][j], opt_ptr, 4)) -+ break; -+ -+ /* Jump 4 bytes to next address */ -+ opt_ptr += 4; -+ j++; -+ } -+ -+ /* Reached the end without a differing address, lists -+ * are therefore identical. -+ */ -+ if (j == mptcp_gws->len[i]) { -+ mptcp_debug("mptcp_get_avail_list_ipv4: List already used\n"); -+ list_taken = 1; -+ break; -+ } -+ } -+ -+ /* Free list found if not taken by a socket */ -+ if (!list_taken) { -+ mptcp_debug("mptcp_get_avail_list_ipv4: List free\n"); -+ break; -+ } -+ } -+ -+ if (i >= MPTCP_GW_MAX_LISTS) -+ goto error; -+ -+ return i; -+error: -+ return -1; -+} -+ -+/* The list of addresses is parsed each time a new connection is opened, -+ * to make sure it's up to date. In case of error, all the lists are -+ * marked as unavailable and the subflow's fingerprint is set to 0. -+ */ -+static void mptcp_v4_add_lsrr(struct sock *sk, struct in_addr addr) -+{ -+ int i, j, ret; -+ unsigned char opt[MAX_IPOPTLEN] = {0}; -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct binder_priv *fmp = (struct binder_priv *)&tp->mpcb->mptcp_pm[0]; -+ -+ /* Read lock: multiple sockets can read LSRR addresses at the same -+ * time, but writes are done in mutual exclusion. -+ * Spin lock: must search for free list for one socket at a time, or -+ * multiple sockets could take the same list. -+ */ -+ read_lock(&mptcp_gws_lock); -+ spin_lock(fmp->flow_lock); -+ -+ i = mptcp_get_avail_list_ipv4(sk); -+ -+ /* Execution enters here only if a free path is found. -+ */ -+ if (i >= 0) { -+ opt[0] = IPOPT_NOP; -+ opt[1] = IPOPT_LSRR; -+ opt[2] = sizeof(mptcp_gws->list[i][0].s_addr) * -+ (mptcp_gws->len[i] + 1) + 3; -+ opt[3] = IPOPT_MINOFF; -+ for (j = 0; j < mptcp_gws->len[i]; ++j) -+ memcpy(opt + 4 + -+ (j * sizeof(mptcp_gws->list[i][0].s_addr)), -+ &mptcp_gws->list[i][j].s_addr, -+ sizeof(mptcp_gws->list[i][0].s_addr)); -+ /* Final destination must be part of IP_OPTIONS parameter. */ -+ memcpy(opt + 4 + (j * sizeof(addr.s_addr)), &addr.s_addr, -+ sizeof(addr.s_addr)); -+ -+ /* setsockopt must be inside the lock, otherwise another -+ * subflow could fail to see that we have taken a list. -+ */ -+ ret = ip_setsockopt(sk, IPPROTO_IP, IP_OPTIONS, (char __user *)opt, -+ 4 + sizeof(mptcp_gws->list[i][0].s_addr) * (mptcp_gws->len[i] + 1)); -+ -+ if (ret < 0) { -+ mptcp_debug("%s: MPTCP subsock setsockopt() IP_OPTIONS failed, error %d\n", -+ __func__, ret); -+ } -+ } -+ -+ spin_unlock(fmp->flow_lock); -+ read_unlock(&mptcp_gws_lock); -+ -+ return; -+} -+ -+/* Parses gateways string for a list of paths to different -+ * gateways, and stores them for use with the Loose Source Routing (LSRR) -+ * socket option. Each list must have "," separated addresses, and the lists -+ * themselves must be separated by "-". Returns -1 in case one or more of the -+ * addresses is not a valid ipv4/6 address. -+ */ -+static int mptcp_parse_gateway_ipv4(char *gateways) -+{ -+ int i, j, k, ret; -+ char *tmp_string = NULL; -+ struct in_addr tmp_addr; -+ -+ tmp_string = kzalloc(16, GFP_KERNEL); -+ if (tmp_string == NULL) -+ return -ENOMEM; -+ -+ write_lock(&mptcp_gws_lock); -+ -+ memset(mptcp_gws, 0, sizeof(struct mptcp_gw_list)); -+ -+ /* A TMP string is used since inet_pton needs a null terminated string -+ * but we do not want to modify the sysctl for obvious reasons. -+ * i will iterate over the SYSCTL string, j will iterate over the -+ * temporary string where each IP is copied into, k will iterate over -+ * the IPs in each list. -+ */ -+ for (i = j = k = 0; -+ i < MPTCP_GW_SYSCTL_MAX_LEN && k < MPTCP_GW_MAX_LISTS; -+ ++i) { -+ if (gateways[i] == '-' || gateways[i] == ',' || gateways[i] == '\0') { -+ /* If the temp IP is empty and the current list is -+ * empty, we are done. -+ */ -+ if (j == 0 && mptcp_gws->len[k] == 0) -+ break; -+ -+ /* Terminate the temp IP string, then if it is -+ * non-empty parse the IP and copy it. -+ */ -+ tmp_string[j] = '\0'; -+ if (j > 0) { -+ mptcp_debug("mptcp_parse_gateway_list tmp: %s i: %d\n", tmp_string, i); -+ -+ ret = in4_pton(tmp_string, strlen(tmp_string), -+ (u8 *)&tmp_addr.s_addr, '\0', -+ NULL); -+ -+ if (ret) { -+ mptcp_debug("mptcp_parse_gateway_list ret: %d s_addr: %pI4\n", -+ ret, -+ &tmp_addr.s_addr); -+ memcpy(&mptcp_gws->list[k][mptcp_gws->len[k]].s_addr, -+ &tmp_addr.s_addr, -+ sizeof(tmp_addr.s_addr)); -+ mptcp_gws->len[k]++; -+ j = 0; -+ tmp_string[j] = '\0'; -+ /* Since we can't impose a limit to -+ * what the user can input, make sure -+ * there are not too many IPs in the -+ * SYSCTL string. -+ */ -+ if (mptcp_gws->len[k] > MPTCP_GW_LIST_MAX_LEN) { -+ mptcp_debug("mptcp_parse_gateway_list too many members in list %i: max %i\n", -+ k, -+ MPTCP_GW_LIST_MAX_LEN); -+ goto error; -+ } -+ } else { -+ goto error; -+ } -+ } -+ -+ if (gateways[i] == '-' || gateways[i] == '\0') -+ ++k; -+ } else { -+ tmp_string[j] = gateways[i]; -+ ++j; -+ } -+ } -+ -+ /* Number of flows is number of gateway lists plus master flow */ -+ mptcp_binder_ndiffports = k+1; -+ -+ write_unlock(&mptcp_gws_lock); -+ kfree(tmp_string); -+ -+ return 0; -+ -+error: -+ memset(mptcp_gws, 0, sizeof(struct mptcp_gw_list)); -+ memset(gateways, 0, sizeof(char) * MPTCP_GW_SYSCTL_MAX_LEN); -+ write_unlock(&mptcp_gws_lock); -+ kfree(tmp_string); -+ return -1; -+} -+ -+/** -+ * Create all new subflows, by doing calls to mptcp_initX_subsockets -+ * -+ * This function uses a goto next_subflow, to allow releasing the lock between -+ * new subflows and giving other processes a chance to do some work on the -+ * socket and potentially finishing the communication. -+ **/ -+static void create_subflow_worker(struct work_struct *work) -+{ -+ const struct binder_priv *pm_priv = container_of(work, -+ struct binder_priv, -+ subflow_work); -+ struct mptcp_cb *mpcb = pm_priv->mpcb; -+ struct sock *meta_sk = mpcb->meta_sk; -+ int iter = 0; -+ -+next_subflow: -+ if (iter) { -+ release_sock(meta_sk); -+ mutex_unlock(&mpcb->mpcb_mutex); -+ -+ cond_resched(); -+ } -+ mutex_lock(&mpcb->mpcb_mutex); -+ lock_sock_nested(meta_sk, SINGLE_DEPTH_NESTING); -+ -+ if (!mptcp(tcp_sk(meta_sk))) -+ goto exit; -+ -+ iter++; -+ -+ if (sock_flag(meta_sk, SOCK_DEAD)) -+ goto exit; -+ -+ if (mpcb->master_sk && -+ !tcp_sk(mpcb->master_sk)->mptcp->fully_established) -+ goto exit; -+ -+ if (mptcp_binder_ndiffports > iter && -+ mptcp_binder_ndiffports > mptcp_subflow_count(mpcb)) { -+ struct mptcp_loc4 loc; -+ struct mptcp_rem4 rem; -+ -+ loc.addr.s_addr = inet_sk(meta_sk)->inet_saddr; -+ loc.loc4_id = 0; -+ loc.low_prio = 0; -+ -+ rem.addr.s_addr = inet_sk(meta_sk)->inet_daddr; -+ rem.port = inet_sk(meta_sk)->inet_dport; -+ rem.rem4_id = 0; /* Default 0 */ -+ -+ mptcp_init4_subsockets(meta_sk, &loc, &rem); -+ -+ goto next_subflow; -+ } -+ -+exit: -+ release_sock(meta_sk); -+ mutex_unlock(&mpcb->mpcb_mutex); -+ mptcp_mpcb_put(mpcb); -+ sock_put(meta_sk); -+} -+ -+static void binder_new_session(const struct sock *meta_sk) -+{ -+ struct mptcp_cb *mpcb = tcp_sk(meta_sk)->mpcb; -+ struct binder_priv *fmp = (struct binder_priv *)&mpcb->mptcp_pm[0]; -+ static DEFINE_SPINLOCK(flow_lock); -+ -+#if IS_ENABLED(CONFIG_IPV6) -+ if (meta_sk->sk_family == AF_INET6 && -+ !mptcp_v6_is_v4_mapped(meta_sk)) { -+ mptcp_fallback_default(mpcb); -+ return; -+ } -+#endif -+ -+ /* Initialize workqueue-struct */ -+ INIT_WORK(&fmp->subflow_work, create_subflow_worker); -+ fmp->mpcb = mpcb; -+ -+ fmp->flow_lock = &flow_lock; -+} -+ -+static void binder_create_subflows(struct sock *meta_sk) -+{ -+ struct mptcp_cb *mpcb = tcp_sk(meta_sk)->mpcb; -+ struct binder_priv *pm_priv = (struct binder_priv *)&mpcb->mptcp_pm[0]; -+ -+ if (mptcp_in_infinite_mapping_weak(mpcb) || -+ mpcb->server_side || sock_flag(meta_sk, SOCK_DEAD)) -+ return; -+ -+ if (!work_pending(&pm_priv->subflow_work)) { -+ sock_hold(meta_sk); -+ refcount_inc(&mpcb->mpcb_refcnt); -+ queue_work(mptcp_wq, &pm_priv->subflow_work); -+ } -+} -+ -+static int binder_get_local_id(const struct sock *meta_sk, sa_family_t family, -+ union inet_addr *addr, bool *low_prio) -+{ -+ return 0; -+} -+ -+/* Callback functions, executed when syctl mptcp.mptcp_gateways is updated. -+ * Inspired from proc_tcp_congestion_control(). -+ */ -+static int proc_mptcp_gateways(struct ctl_table *ctl, int write, -+ void __user *buffer, size_t *lenp, -+ loff_t *ppos) -+{ -+ int ret; -+ struct ctl_table tbl = { -+ .maxlen = MPTCP_GW_SYSCTL_MAX_LEN, -+ }; -+ -+ if (write) { -+ tbl.data = kzalloc(MPTCP_GW_SYSCTL_MAX_LEN, GFP_KERNEL); -+ if (tbl.data == NULL) -+ return -ENOMEM; -+ ret = proc_dostring(&tbl, write, buffer, lenp, ppos); -+ if (ret == 0) { -+ ret = mptcp_parse_gateway_ipv4(tbl.data); -+ memcpy(ctl->data, tbl.data, MPTCP_GW_SYSCTL_MAX_LEN); -+ } -+ kfree(tbl.data); -+ } else { -+ ret = proc_dostring(ctl, write, buffer, lenp, ppos); -+ } -+ -+ -+ return ret; -+} -+ -+static struct mptcp_pm_ops binder __read_mostly = { -+ .new_session = binder_new_session, -+ .fully_established = binder_create_subflows, -+ .get_local_id = binder_get_local_id, -+ .init_subsocket_v4 = mptcp_v4_add_lsrr, -+ .name = "binder", -+ .owner = THIS_MODULE, -+}; -+ -+static struct ctl_table binder_table[] = { -+ { -+ .procname = "mptcp_binder_gateways", -+ .data = &sysctl_mptcp_binder_gateways, -+ .maxlen = sizeof(char) * MPTCP_GW_SYSCTL_MAX_LEN, -+ .mode = 0644, -+ .proc_handler = &proc_mptcp_gateways -+ }, -+ { } -+}; -+ -+static struct ctl_table_header *mptcp_sysctl_binder; -+ -+/* General initialization of MPTCP_PM */ -+static int __init binder_register(void) -+{ -+ mptcp_gws = kzalloc(sizeof(*mptcp_gws), GFP_KERNEL); -+ if (!mptcp_gws) -+ return -ENOMEM; -+ -+ rwlock_init(&mptcp_gws_lock); -+ -+ BUILD_BUG_ON(sizeof(struct binder_priv) > MPTCP_PM_SIZE); -+ -+ mptcp_sysctl_binder = register_net_sysctl(&init_net, "net/mptcp", -+ binder_table); -+ if (!mptcp_sysctl_binder) -+ goto sysctl_fail; -+ -+ if (mptcp_register_path_manager(&binder)) -+ goto pm_failed; -+ -+ return 0; -+ -+pm_failed: -+ unregister_net_sysctl_table(mptcp_sysctl_binder); -+sysctl_fail: -+ kfree(mptcp_gws); -+ -+ return -1; -+} -+ -+static void binder_unregister(void) -+{ -+ mptcp_unregister_path_manager(&binder); -+ unregister_net_sysctl_table(mptcp_sysctl_binder); -+ kfree(mptcp_gws); -+} -+ -+module_init(binder_register); -+module_exit(binder_unregister); -+ -+MODULE_AUTHOR("Luca Boccassi, Duncan Eastoe, Christoph Paasch (ndiffports)"); -+MODULE_LICENSE("GPL"); -+MODULE_DESCRIPTION("BINDER MPTCP"); -+MODULE_VERSION("0.1"); -diff -aurN linux-5.4.64/net/mptcp/mptcp_blest.c linux-5.4.64.mptcp/net/mptcp/mptcp_blest.c ---- linux-5.4.64/net/mptcp/mptcp_blest.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-5.4.64.mptcp/net/mptcp/mptcp_blest.c 2020-09-10 19:25:10.507220869 +0200 -@@ -0,0 +1,285 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* MPTCP Scheduler to reduce HoL-blocking and spurious retransmissions. -+ * -+ * Algorithm Design: -+ * Simone Ferlin -+ * Ozgu Alay -+ * Olivier Mehani -+ * Roksana Boreli -+ * -+ * Initial Implementation: -+ * Simone Ferlin -+ * -+ * Additional Authors: -+ * Daniel Weber -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version -+ * 2 of the License, or (at your option) any later version. -+ */ -+ -+#include -+#include -+ -+static unsigned char lambda __read_mostly = 12; -+module_param(lambda, byte, 0644); -+MODULE_PARM_DESC(lambda, "Divided by 10 for scaling factor of fast flow rate estimation"); -+ -+static unsigned char max_lambda __read_mostly = 13; -+module_param(max_lambda, byte, 0644); -+MODULE_PARM_DESC(max_lambda, "Divided by 10 for maximum scaling factor of fast flow rate estimation"); -+ -+static unsigned char min_lambda __read_mostly = 10; -+module_param(min_lambda, byte, 0644); -+MODULE_PARM_DESC(min_lambda, "Divided by 10 for minimum scaling factor of fast flow rate estimation"); -+ -+static unsigned char dyn_lambda_good = 10; /* 1% */ -+module_param(dyn_lambda_good, byte, 0644); -+MODULE_PARM_DESC(dyn_lambda_good, "Decrease of lambda in positive case."); -+ -+static unsigned char dyn_lambda_bad = 40; /* 4% */ -+module_param(dyn_lambda_bad, byte, 0644); -+MODULE_PARM_DESC(dyn_lambda_bad, "Increase of lambda in negative case."); -+ -+struct blestsched_priv { -+ u32 last_rbuf_opti; -+ u32 min_srtt_us; -+ u32 max_srtt_us; -+}; -+ -+struct blestsched_cb { -+ s16 lambda_1000; /* values range from min_lambda * 100 to max_lambda * 100 */ -+ u32 last_lambda_update; -+}; -+ -+static struct blestsched_priv *blestsched_get_priv(const struct tcp_sock *tp) -+{ -+ return (struct blestsched_priv *)&tp->mptcp->mptcp_sched[0]; -+} -+ -+static struct blestsched_cb *blestsched_get_cb(const struct tcp_sock *tp) -+{ -+ return (struct blestsched_cb *)&tp->mpcb->mptcp_sched[0]; -+} -+ -+static void blestsched_update_lambda(struct sock *meta_sk, struct sock *sk) -+{ -+ struct blestsched_cb *blest_cb = blestsched_get_cb(tcp_sk(meta_sk)); -+ struct blestsched_priv *blest_p = blestsched_get_priv(tcp_sk(sk)); -+ -+ if (tcp_jiffies32 - blest_cb->last_lambda_update < usecs_to_jiffies(blest_p->min_srtt_us >> 3)) -+ return; -+ -+ /* if there have been retransmissions of packets of the slow flow -+ * during the slow flows last RTT => increase lambda -+ * otherwise decrease -+ */ -+ if (tcp_sk(meta_sk)->retrans_stamp) { -+ /* need to slow down on the slow flow */ -+ blest_cb->lambda_1000 += dyn_lambda_bad; -+ } else { -+ /* use the slow flow more */ -+ blest_cb->lambda_1000 -= dyn_lambda_good; -+ } -+ -+ /* cap lambda_1000 to its value range */ -+ blest_cb->lambda_1000 = min_t(s16, blest_cb->lambda_1000, max_lambda * 100); -+ blest_cb->lambda_1000 = max_t(s16, blest_cb->lambda_1000, min_lambda * 100); -+ -+ blest_cb->last_lambda_update = tcp_jiffies32; -+} -+ -+/* how many bytes will sk send during the rtt of another, slower flow? */ -+static u32 blestsched_estimate_bytes(struct sock *sk, u32 time_8) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct blestsched_priv *blest_p = blestsched_get_priv(tp); -+ struct blestsched_cb *blest_cb = blestsched_get_cb(mptcp_meta_tp(tp)); -+ u32 avg_rtt, num_rtts, ca_cwnd, packets; -+ -+ avg_rtt = (blest_p->min_srtt_us + blest_p->max_srtt_us) / 2; -+ if (avg_rtt == 0) -+ num_rtts = 1; /* sanity */ -+ else -+ num_rtts = (time_8 / avg_rtt) + 1; /* round up */ -+ -+ /* during num_rtts, how many bytes will be sent on the flow? -+ * assumes for simplification that Reno is applied as congestion-control -+ */ -+ if (tp->snd_ssthresh == TCP_INFINITE_SSTHRESH) { -+ /* we are in initial slow start */ -+ if (num_rtts > 16) -+ num_rtts = 16; /* cap for sanity */ -+ packets = tp->snd_cwnd * ((1 << num_rtts) - 1); /* cwnd + 2*cwnd + 4*cwnd */ -+ } else { -+ ca_cwnd = max(tp->snd_cwnd, tp->snd_ssthresh + 1); /* assume we jump to CA already */ -+ packets = (ca_cwnd + (num_rtts - 1) / 2) * num_rtts; -+ } -+ -+ return div_u64(((u64)packets) * tp->mss_cache * blest_cb->lambda_1000, 1000); -+} -+ -+static u32 blestsched_estimate_linger_time(struct sock *sk) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct blestsched_priv *blest_p = blestsched_get_priv(tp); -+ u32 estimate, slope, inflight, cwnd; -+ -+ inflight = tcp_packets_in_flight(tp) + 1; /* take into account the new one */ -+ cwnd = tp->snd_cwnd; -+ -+ if (inflight >= cwnd) { -+ estimate = blest_p->max_srtt_us; -+ } else { -+ slope = blest_p->max_srtt_us - blest_p->min_srtt_us; -+ if (cwnd == 0) -+ cwnd = 1; /* sanity */ -+ estimate = blest_p->min_srtt_us + (slope * inflight) / cwnd; -+ } -+ -+ return (tp->srtt_us > estimate) ? tp->srtt_us : estimate; -+} -+ -+/* This is the BLEST scheduler. This function decides on which flow to send -+ * a given MSS. If all subflows are found to be busy or the currently best -+ * subflow is estimated to possibly cause HoL-blocking, NULL is returned. -+ */ -+struct sock *blest_get_available_subflow(struct sock *meta_sk, struct sk_buff *skb, -+ bool zero_wnd_test) -+{ -+ struct mptcp_cb *mpcb = tcp_sk(meta_sk)->mpcb; -+ struct sock *bestsk, *minsk = NULL; -+ struct tcp_sock *meta_tp, *besttp; -+ struct mptcp_tcp_sock *mptcp; -+ struct blestsched_priv *blest_p; -+ u32 min_srtt = U32_MAX; -+ -+ /* Answer data_fin on same subflow!!! */ -+ if (meta_sk->sk_shutdown & RCV_SHUTDOWN && -+ skb && mptcp_is_data_fin(skb)) { -+ mptcp_for_each_sub(mpcb, mptcp) { -+ bestsk = mptcp_to_sock(mptcp); -+ -+ if (tcp_sk(bestsk)->mptcp->path_index == mpcb->dfin_path_index && -+ mptcp_is_available(bestsk, skb, zero_wnd_test)) -+ return bestsk; -+ } -+ } -+ -+ /* First, find the overall best subflow */ -+ mptcp_for_each_sub(mpcb, mptcp) { -+ bestsk = mptcp_to_sock(mptcp); -+ besttp = tcp_sk(bestsk); -+ blest_p = blestsched_get_priv(besttp); -+ -+ /* Set of states for which we are allowed to send data */ -+ if (!mptcp_sk_can_send(bestsk)) -+ continue; -+ -+ /* We do not send data on this subflow unless it is -+ * fully established, i.e. the 4th ack has been received. -+ */ -+ if (besttp->mptcp->pre_established) -+ continue; -+ -+ blest_p->min_srtt_us = min(blest_p->min_srtt_us, besttp->srtt_us); -+ blest_p->max_srtt_us = max(blest_p->max_srtt_us, besttp->srtt_us); -+ -+ /* record minimal rtt */ -+ if (besttp->srtt_us < min_srtt) { -+ min_srtt = besttp->srtt_us; -+ minsk = bestsk; -+ } -+ } -+ -+ /* find the current best subflow according to the default scheduler */ -+ bestsk = get_available_subflow(meta_sk, skb, zero_wnd_test); -+ -+ /* if we decided to use a slower flow, we have the option of not using it at all */ -+ if (bestsk && minsk && bestsk != minsk) { -+ u32 slow_linger_time, fast_bytes, slow_inflight_bytes, slow_bytes, avail_space; -+ u32 buffered_bytes = 0; -+ -+ meta_tp = tcp_sk(meta_sk); -+ besttp = tcp_sk(bestsk); -+ -+ blestsched_update_lambda(meta_sk, bestsk); -+ -+ /* if we send this SKB now, it will be acked in besttp->srtt seconds -+ * during this time: how many bytes will we send on the fast flow? -+ */ -+ slow_linger_time = blestsched_estimate_linger_time(bestsk); -+ fast_bytes = blestsched_estimate_bytes(minsk, slow_linger_time); -+ -+ if (skb) -+ buffered_bytes = skb->len; -+ -+ /* is the required space available in the mptcp meta send window? -+ * we assume that all bytes inflight on the slow path will be acked in besttp->srtt seconds -+ * (just like the SKB if it was sent now) -> that means that those inflight bytes will -+ * keep occupying space in the meta window until then -+ */ -+ slow_inflight_bytes = besttp->write_seq - besttp->snd_una; -+ slow_bytes = buffered_bytes + slow_inflight_bytes; // bytes of this SKB plus those in flight already -+ -+ avail_space = (slow_bytes < meta_tp->snd_wnd) ? (meta_tp->snd_wnd - slow_bytes) : 0; -+ -+ if (fast_bytes > avail_space) { -+ /* sending this SKB on the slow flow means -+ * we wouldn't be able to send all the data we'd like to send on the fast flow -+ * so don't do that -+ */ -+ return NULL; -+ } -+ } -+ -+ return bestsk; -+} -+ -+static void blestsched_init(struct sock *sk) -+{ -+ struct blestsched_priv *blest_p = blestsched_get_priv(tcp_sk(sk)); -+ struct blestsched_cb *blest_cb = blestsched_get_cb(tcp_sk(mptcp_meta_sk(sk))); -+ -+ blest_p->last_rbuf_opti = tcp_jiffies32; -+ blest_p->min_srtt_us = U32_MAX; -+ blest_p->max_srtt_us = 0; -+ -+ if (!blest_cb->lambda_1000) { -+ blest_cb->lambda_1000 = lambda * 100; -+ blest_cb->last_lambda_update = tcp_jiffies32; -+ } -+} -+ -+static struct mptcp_sched_ops mptcp_sched_blest = { -+ .get_subflow = blest_get_available_subflow, -+ .next_segment = mptcp_next_segment, -+ .init = blestsched_init, -+ .name = "blest", -+ .owner = THIS_MODULE, -+}; -+ -+static int __init blest_register(void) -+{ -+ BUILD_BUG_ON(sizeof(struct blestsched_priv) > MPTCP_SCHED_SIZE); -+ BUILD_BUG_ON(sizeof(struct blestsched_cb) > MPTCP_SCHED_DATA_SIZE); -+ -+ if (mptcp_register_scheduler(&mptcp_sched_blest)) -+ return -1; -+ -+ return 0; -+} -+ -+static void blest_unregister(void) -+{ -+ mptcp_unregister_scheduler(&mptcp_sched_blest); -+} -+ -+module_init(blest_register); -+module_exit(blest_unregister); -+ -+MODULE_AUTHOR("Simone Ferlin, Daniel Weber"); -+MODULE_LICENSE("GPL"); -+MODULE_DESCRIPTION("BLEST scheduler for MPTCP, based on default minimum RTT scheduler"); -+MODULE_VERSION("0.95"); -diff -aurN linux-5.4.64/net/mptcp/mptcp_coupled.c linux-5.4.64.mptcp/net/mptcp/mptcp_coupled.c ---- linux-5.4.64/net/mptcp/mptcp_coupled.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-5.4.64.mptcp/net/mptcp/mptcp_coupled.c 2020-09-10 19:25:10.507220869 +0200 -@@ -0,0 +1,262 @@ -+/* -+ * MPTCP implementation - Linked Increase congestion control Algorithm (LIA) -+ * -+ * Initial Design & Implementation: -+ * Sébastien Barré -+ * -+ * Current Maintainer & Author: -+ * Christoph Paasch -+ * -+ * Additional authors: -+ * Jaakko Korkeaniemi -+ * Gregory Detal -+ * Fabien Duchêne -+ * Andreas Seelinger -+ * Lavkesh Lahngir -+ * Andreas Ripke -+ * Vlad Dogaru -+ * Octavian Purdila -+ * John Ronan -+ * Catalin Nicutar -+ * Brandon Heller -+ * -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version -+ * 2 of the License, or (at your option) any later version. -+ */ -+#include -+#include -+ -+#include -+ -+/* Scaling is done in the numerator with alpha_scale_num and in the denominator -+ * with alpha_scale_den. -+ * -+ * To downscale, we just need to use alpha_scale. -+ * -+ * We have: alpha_scale = alpha_scale_num / (alpha_scale_den ^ 2) -+ */ -+static int alpha_scale_den = 10; -+static int alpha_scale_num = 32; -+static int alpha_scale = 12; -+ -+struct mptcp_ccc { -+ u64 alpha; -+ bool forced_update; -+}; -+ -+static inline int mptcp_ccc_sk_can_send(const struct sock *sk) -+{ -+ return mptcp_sk_can_send(sk) && tcp_sk(sk)->srtt_us; -+} -+ -+static inline u64 mptcp_get_alpha(const struct sock *meta_sk) -+{ -+ return ((struct mptcp_ccc *)inet_csk_ca(meta_sk))->alpha; -+} -+ -+static inline void mptcp_set_alpha(const struct sock *meta_sk, u64 alpha) -+{ -+ ((struct mptcp_ccc *)inet_csk_ca(meta_sk))->alpha = alpha; -+} -+ -+static inline u64 mptcp_ccc_scale(u32 val, int scale) -+{ -+ return (u64) val << scale; -+} -+ -+static inline bool mptcp_get_forced(const struct sock *meta_sk) -+{ -+ return ((struct mptcp_ccc *)inet_csk_ca(meta_sk))->forced_update; -+} -+ -+static inline void mptcp_set_forced(const struct sock *meta_sk, bool force) -+{ -+ ((struct mptcp_ccc *)inet_csk_ca(meta_sk))->forced_update = force; -+} -+ -+static void mptcp_ccc_recalc_alpha(const struct sock *sk) -+{ -+ const struct mptcp_cb *mpcb = tcp_sk(sk)->mpcb; -+ const struct mptcp_tcp_sock *mptcp; -+ int best_cwnd = 0, best_rtt = 0, can_send = 0; -+ u64 max_numerator = 0, sum_denominator = 0, alpha = 1; -+ -+ if (!mpcb) -+ return; -+ -+ /* Do regular alpha-calculation for multiple subflows */ -+ -+ /* Find the max numerator of the alpha-calculation */ -+ mptcp_for_each_sub(mpcb, mptcp) { -+ const struct sock *sub_sk = mptcp_to_sock(mptcp); -+ struct tcp_sock *sub_tp = tcp_sk(sub_sk); -+ u64 tmp; -+ -+ if (!mptcp_ccc_sk_can_send(sub_sk)) -+ continue; -+ -+ can_send++; -+ -+ /* We need to look for the path, that provides the max-value. -+ * Integer-overflow is not possible here, because -+ * tmp will be in u64. -+ */ -+ tmp = div64_u64(mptcp_ccc_scale(sub_tp->snd_cwnd, -+ alpha_scale_num), (u64)sub_tp->srtt_us * sub_tp->srtt_us); -+ -+ if (tmp >= max_numerator) { -+ max_numerator = tmp; -+ best_cwnd = sub_tp->snd_cwnd; -+ best_rtt = sub_tp->srtt_us; -+ } -+ } -+ -+ /* No subflow is able to send - we don't care anymore */ -+ if (unlikely(!can_send)) -+ goto exit; -+ -+ /* Calculate the denominator */ -+ mptcp_for_each_sub(mpcb, mptcp) { -+ const struct sock *sub_sk = mptcp_to_sock(mptcp); -+ struct tcp_sock *sub_tp = tcp_sk(sub_sk); -+ -+ if (!mptcp_ccc_sk_can_send(sub_sk)) -+ continue; -+ -+ sum_denominator += div_u64( -+ mptcp_ccc_scale(sub_tp->snd_cwnd, -+ alpha_scale_den) * best_rtt, -+ sub_tp->srtt_us); -+ } -+ sum_denominator *= sum_denominator; -+ if (unlikely(!sum_denominator)) { -+ pr_err("%s: sum_denominator == 0\n", __func__); -+ mptcp_for_each_sub(mpcb, mptcp) { -+ const struct sock *sub_sk = mptcp_to_sock(mptcp); -+ struct tcp_sock *sub_tp = tcp_sk(sub_sk); -+ pr_err("%s: pi:%d, state:%d\n, rtt:%u, cwnd: %u", -+ __func__, sub_tp->mptcp->path_index, -+ sub_sk->sk_state, sub_tp->srtt_us, -+ sub_tp->snd_cwnd); -+ } -+ } -+ -+ alpha = div64_u64(mptcp_ccc_scale(best_cwnd, alpha_scale_num), sum_denominator); -+ -+ if (unlikely(!alpha)) -+ alpha = 1; -+ -+exit: -+ mptcp_set_alpha(mptcp_meta_sk(sk), alpha); -+} -+ -+static void mptcp_ccc_init(struct sock *sk) -+{ -+ if (mptcp(tcp_sk(sk))) { -+ mptcp_set_forced(mptcp_meta_sk(sk), 0); -+ mptcp_set_alpha(mptcp_meta_sk(sk), 1); -+ } -+ /* If we do not mptcp, behave like reno: return */ -+} -+ -+static void mptcp_ccc_cwnd_event(struct sock *sk, enum tcp_ca_event event) -+{ -+ if (event == CA_EVENT_LOSS) -+ mptcp_ccc_recalc_alpha(sk); -+} -+ -+static void mptcp_ccc_set_state(struct sock *sk, u8 ca_state) -+{ -+ if (!mptcp(tcp_sk(sk))) -+ return; -+ -+ mptcp_set_forced(mptcp_meta_sk(sk), 1); -+} -+ -+static void mptcp_ccc_cong_avoid(struct sock *sk, u32 ack, u32 acked) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ int snd_cwnd; -+ u64 alpha; -+ -+ if (!mptcp(tp)) { -+ tcp_reno_cong_avoid(sk, ack, acked); -+ return; -+ } -+ -+ if (!tcp_is_cwnd_limited(sk)) -+ return; -+ -+ if (tcp_in_slow_start(tp)) { -+ /* In "safe" area, increase. */ -+ tcp_slow_start(tp, acked); -+ mptcp_ccc_recalc_alpha(sk); -+ return; -+ } -+ -+ if (mptcp_get_forced(mptcp_meta_sk(sk))) { -+ mptcp_ccc_recalc_alpha(sk); -+ mptcp_set_forced(mptcp_meta_sk(sk), 0); -+ } -+ -+ alpha = mptcp_get_alpha(mptcp_meta_sk(sk)); -+ -+ /* This may happen, if at the initialization, the mpcb -+ * was not yet attached to the sock, and thus -+ * initializing alpha failed. -+ */ -+ if (unlikely(!alpha)) -+ alpha = 1; -+ -+ snd_cwnd = (int)div_u64((u64)mptcp_ccc_scale(1, alpha_scale), alpha); -+ -+ /* snd_cwnd_cnt >= max (scale * tot_cwnd / alpha, cwnd) -+ * Thus, we select here the max value. -+ */ -+ if (snd_cwnd < tp->snd_cwnd) -+ snd_cwnd = tp->snd_cwnd; -+ -+ if (tp->snd_cwnd_cnt >= snd_cwnd) { -+ if (tp->snd_cwnd < tp->snd_cwnd_clamp) { -+ tp->snd_cwnd++; -+ mptcp_ccc_recalc_alpha(sk); -+ } -+ -+ tp->snd_cwnd_cnt = 0; -+ } else { -+ tp->snd_cwnd_cnt++; -+ } -+} -+ -+static struct tcp_congestion_ops mptcp_ccc = { -+ .init = mptcp_ccc_init, -+ .ssthresh = tcp_reno_ssthresh, -+ .cong_avoid = mptcp_ccc_cong_avoid, -+ .undo_cwnd = tcp_reno_undo_cwnd, -+ .cwnd_event = mptcp_ccc_cwnd_event, -+ .set_state = mptcp_ccc_set_state, -+ .owner = THIS_MODULE, -+ .name = "lia", -+}; -+ -+static int __init mptcp_ccc_register(void) -+{ -+ BUILD_BUG_ON(sizeof(struct mptcp_ccc) > ICSK_CA_PRIV_SIZE); -+ return tcp_register_congestion_control(&mptcp_ccc); -+} -+ -+static void __exit mptcp_ccc_unregister(void) -+{ -+ tcp_unregister_congestion_control(&mptcp_ccc); -+} -+ -+module_init(mptcp_ccc_register); -+module_exit(mptcp_ccc_unregister); -+ -+MODULE_AUTHOR("Christoph Paasch, Sébastien Barré"); -+MODULE_LICENSE("GPL"); -+MODULE_DESCRIPTION("MPTCP LINKED INCREASE CONGESTION CONTROL ALGORITHM"); -+MODULE_VERSION("0.1"); -diff -aurN linux-5.4.64/net/mptcp/mptcp_ctrl.c linux-5.4.64.mptcp/net/mptcp/mptcp_ctrl.c ---- linux-5.4.64/net/mptcp/mptcp_ctrl.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-5.4.64.mptcp/net/mptcp/mptcp_ctrl.c 2020-09-10 19:25:10.507220869 +0200 -@@ -0,0 +1,3309 @@ -+/* -+ * MPTCP implementation - MPTCP-control -+ * -+ * Initial Design & Implementation: -+ * Sébastien Barré -+ * -+ * Current Maintainer & Author: -+ * Christoph Paasch -+ * -+ * Additional authors: -+ * Jaakko Korkeaniemi -+ * Gregory Detal -+ * Fabien Duchêne -+ * Andreas Seelinger -+ * Lavkesh Lahngir -+ * Andreas Ripke -+ * Vlad Dogaru -+ * Octavian Purdila -+ * John Ronan -+ * Catalin Nicutar -+ * Brandon Heller -+ * -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version -+ * 2 of the License, or (at your option) any later version. -+ */ -+ -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#if IS_ENABLED(CONFIG_IPV6) -+#include -+#include -+#endif -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+static struct kmem_cache *mptcp_sock_cache __read_mostly; -+static struct kmem_cache *mptcp_cb_cache __read_mostly; -+static struct kmem_cache *mptcp_tw_cache __read_mostly; -+ -+int sysctl_mptcp_enabled __read_mostly = 1; -+int sysctl_mptcp_version __read_mostly = 0; -+static int min_mptcp_version; -+static int max_mptcp_version = 1; -+int sysctl_mptcp_checksum __read_mostly = 1; -+int sysctl_mptcp_debug __read_mostly; -+EXPORT_SYMBOL(sysctl_mptcp_debug); -+int sysctl_mptcp_syn_retries __read_mostly = 3; -+ -+bool mptcp_init_failed __read_mostly; -+ -+struct static_key mptcp_static_key = STATIC_KEY_INIT_FALSE; -+EXPORT_SYMBOL(mptcp_static_key); -+ -+static void mptcp_key_hash(u8 version, u64 key, u32 *token, u64 *idsn); -+ -+static int proc_mptcp_path_manager(struct ctl_table *ctl, int write, -+ void __user *buffer, size_t *lenp, -+ loff_t *ppos) -+{ -+ char val[MPTCP_PM_NAME_MAX]; -+ struct ctl_table tbl = { -+ .data = val, -+ .maxlen = MPTCP_PM_NAME_MAX, -+ }; -+ int ret; -+ -+ mptcp_get_default_path_manager(val); -+ -+ ret = proc_dostring(&tbl, write, buffer, lenp, ppos); -+ if (write && ret == 0) -+ ret = mptcp_set_default_path_manager(val); -+ return ret; -+} -+ -+static int proc_mptcp_scheduler(struct ctl_table *ctl, int write, -+ void __user *buffer, size_t *lenp, -+ loff_t *ppos) -+{ -+ char val[MPTCP_SCHED_NAME_MAX]; -+ struct ctl_table tbl = { -+ .data = val, -+ .maxlen = MPTCP_SCHED_NAME_MAX, -+ }; -+ int ret; -+ -+ mptcp_get_default_scheduler(val); -+ -+ ret = proc_dostring(&tbl, write, buffer, lenp, ppos); -+ if (write && ret == 0) -+ ret = mptcp_set_default_scheduler(val); -+ return ret; -+} -+ -+static struct ctl_table mptcp_table[] = { -+ { -+ .procname = "mptcp_enabled", -+ .data = &sysctl_mptcp_enabled, -+ .maxlen = sizeof(int), -+ .mode = 0644, -+ .proc_handler = &proc_dointvec -+ }, -+ { -+ .procname = "mptcp_version", -+ .data = &sysctl_mptcp_version, -+ .mode = 0644, -+ .maxlen = sizeof(int), -+ .proc_handler = &proc_dointvec_minmax, -+ .extra1 = &min_mptcp_version, -+ .extra2 = &max_mptcp_version, -+ }, -+ { -+ .procname = "mptcp_checksum", -+ .data = &sysctl_mptcp_checksum, -+ .maxlen = sizeof(int), -+ .mode = 0644, -+ .proc_handler = &proc_dointvec -+ }, -+ { -+ .procname = "mptcp_debug", -+ .data = &sysctl_mptcp_debug, -+ .maxlen = sizeof(int), -+ .mode = 0644, -+ .proc_handler = &proc_dointvec -+ }, -+ { -+ .procname = "mptcp_syn_retries", -+ .data = &sysctl_mptcp_syn_retries, -+ .maxlen = sizeof(int), -+ .mode = 0644, -+ .proc_handler = &proc_dointvec -+ }, -+ { -+ .procname = "mptcp_path_manager", -+ .mode = 0644, -+ .maxlen = MPTCP_PM_NAME_MAX, -+ .proc_handler = proc_mptcp_path_manager, -+ }, -+ { -+ .procname = "mptcp_scheduler", -+ .mode = 0644, -+ .maxlen = MPTCP_SCHED_NAME_MAX, -+ .proc_handler = proc_mptcp_scheduler, -+ }, -+ { } -+}; -+ -+static inline u32 mptcp_hash_tk(u32 token, struct mptcp_hashtable *htable) -+{ -+ return token & htable->mask; -+} -+ -+struct mptcp_hashtable mptcp_tk_htable; -+EXPORT_SYMBOL(mptcp_tk_htable); -+ -+/* The following hash table is used to avoid collision of token */ -+static struct mptcp_hashtable mptcp_reqsk_tk_htb; -+ -+/* Lock, protecting the two hash-tables that hold the token. Namely, -+ * mptcp_reqsk_tk_htb and tk_hashtable -+ */ -+static spinlock_t mptcp_tk_hashlock; -+ -+static bool mptcp_reqsk_find_tk(const u32 token) -+{ -+ const u32 hash = mptcp_hash_tk(token, &mptcp_reqsk_tk_htb); -+ const struct mptcp_request_sock *mtreqsk; -+ const struct hlist_nulls_node *node; -+ -+begin: -+ hlist_nulls_for_each_entry_rcu(mtreqsk, node, -+ &mptcp_reqsk_tk_htb.hashtable[hash], -+ hash_entry) { -+ if (token == mtreqsk->mptcp_loc_token) -+ return true; -+ } -+ /* A request-socket is destroyed by RCU. So, it might have been recycled -+ * and put into another hash-table list. So, after the lookup we may -+ * end up in a different list. So, we may need to restart. -+ * -+ * See also the comment in __inet_lookup_established. -+ */ -+ if (get_nulls_value(node) != hash) -+ goto begin; -+ return false; -+} -+ -+static void mptcp_reqsk_insert_tk(struct request_sock *reqsk, const u32 token) -+{ -+ u32 hash = mptcp_hash_tk(token, &mptcp_reqsk_tk_htb); -+ -+ hlist_nulls_add_head_rcu(&mptcp_rsk(reqsk)->hash_entry, -+ &mptcp_reqsk_tk_htb.hashtable[hash]); -+} -+ -+static void mptcp_reqsk_remove_tk(const struct request_sock *reqsk) -+{ -+ rcu_read_lock(); -+ local_bh_disable(); -+ spin_lock(&mptcp_tk_hashlock); -+ hlist_nulls_del_init_rcu(&mptcp_rsk(reqsk)->hash_entry); -+ spin_unlock(&mptcp_tk_hashlock); -+ local_bh_enable(); -+ rcu_read_unlock(); -+} -+ -+void mptcp_reqsk_destructor(struct request_sock *req) -+{ -+ if (!mptcp_rsk(req)->is_sub) -+ mptcp_reqsk_remove_tk(req); -+} -+ -+static void __mptcp_hash_insert(struct tcp_sock *meta_tp, const u32 token) -+{ -+ u32 hash = mptcp_hash_tk(token, &mptcp_tk_htable); -+ -+ hlist_nulls_add_head_rcu(&meta_tp->tk_table, -+ &mptcp_tk_htable.hashtable[hash]); -+ meta_tp->inside_tk_table = 1; -+} -+ -+static bool mptcp_find_token(u32 token) -+{ -+ const u32 hash = mptcp_hash_tk(token, &mptcp_tk_htable); -+ const struct tcp_sock *meta_tp; -+ const struct hlist_nulls_node *node; -+ -+begin: -+ hlist_nulls_for_each_entry_rcu(meta_tp, node, -+ &mptcp_tk_htable.hashtable[hash], -+ tk_table) { -+ if (token == meta_tp->mptcp_loc_token) -+ return true; -+ } -+ /* A TCP-socket is destroyed by RCU. So, it might have been recycled -+ * and put into another hash-table list. So, after the lookup we may -+ * end up in a different list. So, we may need to restart. -+ * -+ * See also the comment in __inet_lookup_established. -+ */ -+ if (get_nulls_value(node) != hash) -+ goto begin; -+ return false; -+} -+ -+static void mptcp_set_key_reqsk(struct request_sock *req, -+ const struct sk_buff *skb, -+ u32 seed) -+{ -+ const struct inet_request_sock *ireq = inet_rsk(req); -+ struct mptcp_request_sock *mtreq = mptcp_rsk(req); -+ -+ if (skb->protocol == htons(ETH_P_IP)) { -+ mtreq->mptcp_loc_key = mptcp_v4_get_key(ip_hdr(skb)->saddr, -+ ip_hdr(skb)->daddr, -+ htons(ireq->ir_num), -+ ireq->ir_rmt_port, -+ seed); -+#if IS_ENABLED(CONFIG_IPV6) -+ } else { -+ mtreq->mptcp_loc_key = mptcp_v6_get_key(ipv6_hdr(skb)->saddr.s6_addr32, -+ ipv6_hdr(skb)->daddr.s6_addr32, -+ htons(ireq->ir_num), -+ ireq->ir_rmt_port, -+ seed); -+#endif -+ } -+ -+ mptcp_key_hash(mtreq->mptcp_ver, mtreq->mptcp_loc_key, &mtreq->mptcp_loc_token, NULL); -+} -+ -+/* New MPTCP-connection request, prepare a new token for the meta-socket that -+ * will be created in mptcp_check_req_master(), and store the received token. -+ */ -+static void mptcp_reqsk_new_mptcp(struct request_sock *req, -+ const struct sock *sk, -+ const struct mptcp_options_received *mopt, -+ const struct sk_buff *skb) -+{ -+ struct mptcp_request_sock *mtreq = mptcp_rsk(req); -+ const struct tcp_sock *tp = tcp_sk(sk); -+ -+ inet_rsk(req)->saw_mpc = 1; -+ -+ /* MPTCP version agreement */ -+ if (mopt->mptcp_ver >= tp->mptcp_ver) -+ mtreq->mptcp_ver = tp->mptcp_ver; -+ else -+ mtreq->mptcp_ver = mopt->mptcp_ver; -+ -+ rcu_read_lock(); -+ local_bh_disable(); -+ spin_lock(&mptcp_tk_hashlock); -+ do { -+ mptcp_set_key_reqsk(req, skb, mptcp_seed++); -+ } while (mptcp_reqsk_find_tk(mtreq->mptcp_loc_token) || -+ mptcp_find_token(mtreq->mptcp_loc_token)); -+ mptcp_reqsk_insert_tk(req, mtreq->mptcp_loc_token); -+ spin_unlock(&mptcp_tk_hashlock); -+ local_bh_enable(); -+ rcu_read_unlock(); -+ -+ if (mtreq->mptcp_ver == MPTCP_VERSION_0) { -+ mtreq->mptcp_rem_key = mopt->mptcp_sender_key; -+ mtreq->rem_key_set = 1; -+ } -+} -+ -+static int mptcp_reqsk_new_cookie(struct request_sock *req, -+ const struct sock *sk, -+ const struct mptcp_options_received *mopt, -+ const struct sk_buff *skb) -+{ -+ struct mptcp_request_sock *mtreq = mptcp_rsk(req); -+ -+ /* MPTCP version agreement */ -+ if (mopt->mptcp_ver >= tcp_sk(sk)->mptcp_ver) -+ mtreq->mptcp_ver = tcp_sk(sk)->mptcp_ver; -+ else -+ mtreq->mptcp_ver = mopt->mptcp_ver; -+ -+ rcu_read_lock(); -+ local_bh_disable(); -+ spin_lock(&mptcp_tk_hashlock); -+ -+ mptcp_set_key_reqsk(req, skb, tcp_rsk(req)->snt_isn); -+ -+ if (mptcp_reqsk_find_tk(mtreq->mptcp_loc_token) || -+ mptcp_find_token(mtreq->mptcp_loc_token)) { -+ spin_unlock(&mptcp_tk_hashlock); -+ local_bh_enable(); -+ rcu_read_unlock(); -+ return false; -+ } -+ -+ inet_rsk(req)->saw_mpc = 1; -+ -+ spin_unlock(&mptcp_tk_hashlock); -+ local_bh_enable(); -+ rcu_read_unlock(); -+ -+ if (mtreq->mptcp_ver == MPTCP_VERSION_0) { -+ mtreq->mptcp_rem_key = mopt->mptcp_sender_key; -+ mtreq->rem_key_set = 1; -+ } -+ -+ return true; -+} -+ -+static void mptcp_set_key_sk(const struct sock *sk) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ const struct inet_sock *isk = inet_sk(sk); -+ -+ if (sk->sk_family == AF_INET) -+ tp->mptcp_loc_key = mptcp_v4_get_key(isk->inet_saddr, -+ isk->inet_daddr, -+ isk->inet_sport, -+ isk->inet_dport, -+ mptcp_seed++); -+#if IS_ENABLED(CONFIG_IPV6) -+ else -+ tp->mptcp_loc_key = mptcp_v6_get_key(inet6_sk(sk)->saddr.s6_addr32, -+ sk->sk_v6_daddr.s6_addr32, -+ isk->inet_sport, -+ isk->inet_dport, -+ mptcp_seed++); -+#endif -+ -+ mptcp_key_hash(tp->mptcp_ver, tp->mptcp_loc_key, &tp->mptcp_loc_token, NULL); -+} -+ -+#ifdef CONFIG_JUMP_LABEL -+static atomic_t mptcp_needed_deferred; -+static atomic_t mptcp_wanted; -+ -+static void mptcp_clear(struct work_struct *work) -+{ -+ int deferred = atomic_xchg(&mptcp_needed_deferred, 0); -+ int wanted; -+ -+ wanted = atomic_add_return(deferred, &mptcp_wanted); -+ if (wanted > 0) -+ static_key_enable(&mptcp_static_key); -+ else -+ static_key_disable(&mptcp_static_key); -+} -+ -+static DECLARE_WORK(mptcp_work, mptcp_clear); -+#endif -+ -+static void mptcp_enable_static_key_bh(void) -+{ -+#ifdef CONFIG_JUMP_LABEL -+ int wanted; -+ -+ while (1) { -+ wanted = atomic_read(&mptcp_wanted); -+ if (wanted <= 0) -+ break; -+ if (atomic_cmpxchg(&mptcp_wanted, wanted, wanted + 1) == wanted) -+ return; -+ } -+ atomic_inc(&mptcp_needed_deferred); -+ schedule_work(&mptcp_work); -+#else -+ static_key_slow_inc(&mptcp_static_key); -+#endif -+} -+ -+static void mptcp_enable_static_key(void) -+{ -+#ifdef CONFIG_JUMP_LABEL -+ atomic_inc(&mptcp_wanted); -+ static_key_enable(&mptcp_static_key); -+#else -+ static_key_slow_inc(&mptcp_static_key); -+#endif -+} -+ -+void mptcp_disable_static_key(void) -+{ -+#ifdef CONFIG_JUMP_LABEL -+ int wanted; -+ -+ while (1) { -+ wanted = atomic_read(&mptcp_wanted); -+ if (wanted <= 1) -+ break; -+ if (atomic_cmpxchg(&mptcp_wanted, wanted, wanted - 1) == wanted) -+ return; -+ } -+ atomic_dec(&mptcp_needed_deferred); -+ schedule_work(&mptcp_work); -+#else -+ static_key_slow_dec(&mptcp_static_key); -+#endif -+} -+ -+void mptcp_enable_sock(struct sock *sk) -+{ -+ if (!sock_flag(sk, SOCK_MPTCP)) { -+ sock_set_flag(sk, SOCK_MPTCP); -+ tcp_sk(sk)->mptcp_ver = sysctl_mptcp_version; -+ -+ /* Necessary here, because MPTCP can be enabled/disabled through -+ * a setsockopt. -+ */ -+ if (sk->sk_family == AF_INET) -+ inet_csk(sk)->icsk_af_ops = &mptcp_v4_specific; -+#if IS_ENABLED(CONFIG_IPV6) -+ else if (mptcp_v6_is_v4_mapped(sk)) -+ inet_csk(sk)->icsk_af_ops = &mptcp_v6_mapped; -+ else -+ inet_csk(sk)->icsk_af_ops = &mptcp_v6_specific; -+#endif -+ -+ mptcp_enable_static_key(); -+ } -+} -+ -+void mptcp_disable_sock(struct sock *sk) -+{ -+ if (sock_flag(sk, SOCK_MPTCP)) { -+ sock_reset_flag(sk, SOCK_MPTCP); -+ -+ /* Necessary here, because MPTCP can be enabled/disabled through -+ * a setsockopt. -+ */ -+ if (sk->sk_family == AF_INET) -+ inet_csk(sk)->icsk_af_ops = &ipv4_specific; -+#if IS_ENABLED(CONFIG_IPV6) -+ else if (mptcp_v6_is_v4_mapped(sk)) -+ inet_csk(sk)->icsk_af_ops = &ipv6_mapped; -+ else -+ inet_csk(sk)->icsk_af_ops = &ipv6_specific; -+#endif -+ -+ mptcp_disable_static_key(); -+ } -+} -+ -+void mptcp_connect_init(struct sock *sk) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ -+ rcu_read_lock(); -+ local_bh_disable(); -+ spin_lock(&mptcp_tk_hashlock); -+ do { -+ mptcp_set_key_sk(sk); -+ } while (mptcp_reqsk_find_tk(tp->mptcp_loc_token) || -+ mptcp_find_token(tp->mptcp_loc_token)); -+ -+ __mptcp_hash_insert(tp, tp->mptcp_loc_token); -+ spin_unlock(&mptcp_tk_hashlock); -+ local_bh_enable(); -+ rcu_read_unlock(); -+ -+ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_MPCAPABLEACTIVE); -+} -+ -+/** -+ * This function increments the refcount of the mpcb struct. -+ * It is the responsibility of the caller to decrement when releasing -+ * the structure. -+ */ -+struct sock *mptcp_hash_find(const struct net *net, const u32 token) -+{ -+ const u32 hash = mptcp_hash_tk(token, &mptcp_tk_htable); -+ const struct tcp_sock *meta_tp; -+ struct sock *meta_sk = NULL; -+ const struct hlist_nulls_node *node; -+ -+ rcu_read_lock(); -+ local_bh_disable(); -+begin: -+ hlist_nulls_for_each_entry_rcu(meta_tp, node, -+ &mptcp_tk_htable.hashtable[hash], -+ tk_table) { -+ meta_sk = (struct sock *)meta_tp; -+ if (token == meta_tp->mptcp_loc_token && -+ net_eq(net, sock_net(meta_sk))) { -+ if (unlikely(!refcount_inc_not_zero(&meta_sk->sk_refcnt))) -+ goto out; -+ if (unlikely(token != meta_tp->mptcp_loc_token || -+ !net_eq(net, sock_net(meta_sk)))) { -+ sock_gen_put(meta_sk); -+ goto begin; -+ } -+ goto found; -+ } -+ } -+ /* A TCP-socket is destroyed by RCU. So, it might have been recycled -+ * and put into another hash-table list. So, after the lookup we may -+ * end up in a different list. So, we may need to restart. -+ * -+ * See also the comment in __inet_lookup_established. -+ */ -+ if (get_nulls_value(node) != hash) -+ goto begin; -+out: -+ meta_sk = NULL; -+found: -+ local_bh_enable(); -+ rcu_read_unlock(); -+ return meta_sk; -+} -+EXPORT_SYMBOL_GPL(mptcp_hash_find); -+ -+void mptcp_hash_remove_bh(struct tcp_sock *meta_tp) -+{ -+ /* remove from the token hashtable */ -+ rcu_read_lock(); -+ local_bh_disable(); -+ spin_lock(&mptcp_tk_hashlock); -+ hlist_nulls_del_init_rcu(&meta_tp->tk_table); -+ meta_tp->inside_tk_table = 0; -+ spin_unlock(&mptcp_tk_hashlock); -+ local_bh_enable(); -+ rcu_read_unlock(); -+} -+ -+struct sock *mptcp_select_ack_sock(const struct sock *meta_sk) -+{ -+ const struct tcp_sock *meta_tp = tcp_sk(meta_sk); -+ struct sock *rttsk = NULL, *lastsk = NULL; -+ u32 min_time = 0, last_active = 0; -+ struct mptcp_tcp_sock *mptcp; -+ -+ mptcp_for_each_sub(meta_tp->mpcb, mptcp) { -+ struct sock *sk = mptcp_to_sock(mptcp); -+ struct tcp_sock *tp = tcp_sk(sk); -+ u32 elapsed; -+ -+ if (!mptcp_sk_can_send_ack(sk) || tp->pf) -+ continue; -+ -+ elapsed = keepalive_time_elapsed(tp); -+ -+ /* We take the one with the lowest RTT within a reasonable -+ * (meta-RTO)-timeframe -+ */ -+ if (elapsed < inet_csk(meta_sk)->icsk_rto) { -+ if (!min_time || tp->srtt_us < min_time) { -+ min_time = tp->srtt_us; -+ rttsk = sk; -+ } -+ continue; -+ } -+ -+ /* Otherwise, we just take the most recent active */ -+ if (!rttsk && (!last_active || elapsed < last_active)) { -+ last_active = elapsed; -+ lastsk = sk; -+ } -+ } -+ -+ if (rttsk) -+ return rttsk; -+ -+ return lastsk; -+} -+EXPORT_SYMBOL(mptcp_select_ack_sock); -+ -+static void mptcp_sock_def_error_report(struct sock *sk) -+{ -+ const struct mptcp_cb *mpcb = tcp_sk(sk)->mpcb; -+ struct tcp_sock *tp = tcp_sk(sk); -+ -+ if (!sock_flag(sk, SOCK_DEAD)) { -+ if (tp->send_mp_fclose && sk->sk_err == ETIMEDOUT) { -+ /* Called by the keep alive timer (tcp_write_timeout), -+ * when the limit of fastclose retransmissions has been -+ * reached. Send a TCP RST to clear the status of any -+ * stateful firewall (typically conntrack) which are -+ * not aware of mptcp and cannot understand the -+ * fastclose option. -+ */ -+ tp->ops->send_active_reset(sk, GFP_ATOMIC); -+ } -+ } -+ -+ /* record this info that can be used by PM after the sf close */ -+ tp->mptcp->sk_err = sk->sk_err; -+ -+ if (!tp->tcp_disconnect && mptcp_in_infinite_mapping_weak(mpcb)) { -+ struct sock *meta_sk = mptcp_meta_sk(sk); -+ -+ meta_sk->sk_err = sk->sk_err; -+ meta_sk->sk_err_soft = sk->sk_err_soft; -+ -+ if (!sock_flag(meta_sk, SOCK_DEAD)) -+ meta_sk->sk_error_report(meta_sk); -+ -+ WARN(meta_sk->sk_state == TCP_CLOSE, -+ "Meta already closed i_rcv %u i_snd %u send_i %u flags %#lx\n", -+ mpcb->infinite_mapping_rcv, mpcb->infinite_mapping_snd, -+ mpcb->send_infinite_mapping, meta_sk->sk_flags); -+ -+ if (meta_sk->sk_state != TCP_CLOSE) -+ tcp_done(meta_sk); -+ } -+ -+ sk->sk_err = 0; -+ return; -+} -+ -+void mptcp_mpcb_put(struct mptcp_cb *mpcb) -+{ -+ if (refcount_dec_and_test(&mpcb->mpcb_refcnt)) { -+ mptcp_cleanup_path_manager(mpcb); -+ mptcp_cleanup_scheduler(mpcb); -+ kfree(mpcb->master_info); -+ kmem_cache_free(mptcp_cb_cache, mpcb); -+ } -+} -+EXPORT_SYMBOL(mptcp_mpcb_put); -+ -+static void mptcp_mpcb_cleanup(struct mptcp_cb *mpcb) -+{ -+ struct mptcp_tw *mptw; -+ -+ /* The mpcb is disappearing - we can make the final -+ * update to the rcv_nxt of the time-wait-sock and remove -+ * its reference to the mpcb. -+ */ -+ spin_lock_bh(&mpcb->mpcb_list_lock); -+ list_for_each_entry_rcu(mptw, &mpcb->tw_list, list) { -+ list_del_rcu(&mptw->list); -+ mptw->in_list = 0; -+ mptcp_mpcb_put(mpcb); -+ rcu_assign_pointer(mptw->mpcb, NULL); -+ } -+ spin_unlock_bh(&mpcb->mpcb_list_lock); -+ -+ mptcp_mpcb_put(mpcb); -+} -+ -+static void mptcp_sock_destruct(struct sock *sk) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ -+ if (!is_meta_sk(sk)) { -+ BUG_ON(!hlist_unhashed(&tp->mptcp->cb_list)); -+ -+ kmem_cache_free(mptcp_sock_cache, tp->mptcp); -+ tp->mptcp = NULL; -+ -+ /* Taken when mpcb pointer was set */ -+ sock_put(mptcp_meta_sk(sk)); -+ mptcp_mpcb_put(tp->mpcb); -+ } else { -+ mptcp_debug("%s destroying meta-sk token %#x\n", __func__, -+ tcp_sk(sk)->mpcb->mptcp_loc_token); -+ -+ mptcp_mpcb_cleanup(tp->mpcb); -+ } -+ -+ WARN_ON(!static_key_false(&mptcp_static_key)); -+ -+ /* Must be called here, because this will decrement the jump-label. */ -+ inet_sock_destruct(sk); -+} -+ -+void mptcp_destroy_sock(struct sock *sk) -+{ -+ if (is_meta_sk(sk)) { -+ struct mptcp_tcp_sock *mptcp; -+ struct hlist_node *tmp; -+ -+ __skb_queue_purge(&tcp_sk(sk)->mpcb->reinject_queue); -+ -+ /* We have to close all remaining subflows. Normally, they -+ * should all be about to get closed. But, if the kernel is -+ * forcing a closure (e.g., tcp_write_err), the subflows might -+ * not have been closed properly (as we are waiting for the -+ * DATA_ACK of the DATA_FIN). -+ */ -+ mptcp_for_each_sub_safe(tcp_sk(sk)->mpcb, mptcp, tmp) { -+ struct sock *sk_it = mptcp_to_sock(mptcp); -+ -+ /* Already did call tcp_close - waiting for graceful -+ * closure, or if we are retransmitting fast-close on -+ * the subflow. The reset (or timeout) will kill the -+ * subflow.. -+ */ -+ if (tcp_sk(sk_it)->closing || -+ tcp_sk(sk_it)->send_mp_fclose) -+ continue; -+ -+ /* Allow the delayed work first to prevent time-wait state */ -+ if (delayed_work_pending(&tcp_sk(sk_it)->mptcp->work)) -+ continue; -+ -+ mptcp_sub_close(sk_it, 0); -+ } -+ } else { -+ mptcp_del_sock(sk); -+ } -+} -+ -+static void mptcp_set_state(struct sock *sk) -+{ -+ struct sock *meta_sk = mptcp_meta_sk(sk); -+ -+ /* Meta is not yet established - wake up the application */ -+ if ((1 << meta_sk->sk_state) & (TCPF_SYN_SENT | TCPF_SYN_RECV) && -+ sk->sk_state == TCP_ESTABLISHED) { -+ tcp_set_state(meta_sk, TCP_ESTABLISHED); -+ -+ if (!sock_flag(meta_sk, SOCK_DEAD)) { -+ meta_sk->sk_state_change(meta_sk); -+ sk_wake_async(meta_sk, SOCK_WAKE_IO, POLL_OUT); -+ } -+ -+ tcp_sk(meta_sk)->lsndtime = tcp_jiffies32; -+ } -+ -+ if (sk->sk_state == TCP_CLOSE) { -+ if (!sock_flag(sk, SOCK_DEAD)) -+ mptcp_sub_close(sk, 0); -+ } -+} -+ -+static int mptcp_set_congestion_control(struct sock *meta_sk, const char *name, -+ bool load, bool reinit, bool cap_net_admin) -+{ -+ struct mptcp_tcp_sock *mptcp; -+ int err, result = 0; -+ -+ result = __tcp_set_congestion_control(meta_sk, name, load, reinit, cap_net_admin); -+ -+ tcp_sk(meta_sk)->mpcb->tcp_ca_explicit_set = true; -+ -+ mptcp_for_each_sub(tcp_sk(meta_sk)->mpcb, mptcp) { -+ struct sock *sk_it = mptcp_to_sock(mptcp); -+ -+ err = __tcp_set_congestion_control(sk_it, name, load, reinit, cap_net_admin); -+ if (err) -+ result = err; -+ } -+ return result; -+} -+ -+static void mptcp_assign_congestion_control(struct sock *sk) -+{ -+ struct inet_connection_sock *icsk = inet_csk(sk); -+ struct inet_connection_sock *meta_icsk = inet_csk(mptcp_meta_sk(sk)); -+ const struct tcp_congestion_ops *ca = meta_icsk->icsk_ca_ops; -+ -+ /* Congestion control is the same as meta. Thus, it has been -+ * try_module_get'd by tcp_assign_congestion_control. -+ * Congestion control on meta was not explicitly configured by -+ * application, leave default or route based. -+ */ -+ if (icsk->icsk_ca_ops == ca || -+ !tcp_sk(mptcp_meta_sk(sk))->mpcb->tcp_ca_explicit_set) -+ return; -+ -+ /* Use the same congestion control as set on the meta-sk */ -+ if (!try_module_get(ca->owner)) { -+ /* This should never happen. The congestion control is linked -+ * to the meta-socket (through tcp_assign_congestion_control) -+ * who "holds" the refcnt on the module. -+ */ -+ WARN(1, "Could not get the congestion control!"); -+ return; -+ } -+ module_put(icsk->icsk_ca_ops->owner); -+ icsk->icsk_ca_ops = ca; -+ -+ /* Clear out private data before diag gets it and -+ * the ca has not been initialized. -+ */ -+ if (ca->get_info) -+ memset(icsk->icsk_ca_priv, 0, sizeof(icsk->icsk_ca_priv)); -+ -+ return; -+} -+ -+siphash_key_t mptcp_secret __read_mostly; -+u32 mptcp_seed = 0; -+ -+#define SHA256_DIGEST_WORDS (SHA256_DIGEST_SIZE / 4) -+ -+static void mptcp_key_sha256(const u64 key, u32 *token, u64 *idsn) -+{ -+ u32 mptcp_hashed_key[SHA256_DIGEST_WORDS]; -+ struct sha256_state state; -+ -+ sha256_init(&state); -+ sha256_update(&state, (const u8 *)&key, sizeof(key)); -+ sha256_final(&state, (u8 *)mptcp_hashed_key); -+ -+ if (token) -+ *token = mptcp_hashed_key[0]; -+ if (idsn) -+ *idsn = ntohll(*((__be64 *)&mptcp_hashed_key[6])); -+} -+ -+static void mptcp_hmac_sha256(const u8 *key_1, const u8 *key_2, u8 *hash_out, -+ int arg_num, va_list list) -+{ -+ u8 input[SHA256_BLOCK_SIZE + SHA256_DIGEST_SIZE]; -+ struct sha256_state state; -+ int index, msg_length; -+ int length = 0; -+ u8 *msg; -+ int i; -+ -+ /* Generate key xored with ipad */ -+ memset(input, 0x36, SHA256_BLOCK_SIZE); -+ for (i = 0; i < 8; i++) -+ input[i] ^= key_1[i]; -+ for (i = 0; i < 8; i++) -+ input[i + 8] ^= key_2[i]; -+ -+ index = SHA256_BLOCK_SIZE; -+ msg_length = 0; -+ for (i = 0; i < arg_num; i++) { -+ length = va_arg(list, int); -+ msg = va_arg(list, u8 *); -+ BUG_ON(index + length >= sizeof(input)); /* Message is too long */ -+ memcpy(&input[index], msg, length); -+ index += length; -+ msg_length += length; -+ } -+ -+ sha256_init(&state); -+ sha256_update(&state, input, SHA256_BLOCK_SIZE + msg_length); -+ sha256_final(&state, &input[SHA256_BLOCK_SIZE]); -+ -+ /* Prepare second part of hmac */ -+ memset(input, 0x5C, SHA256_BLOCK_SIZE); -+ for (i = 0; i < 8; i++) -+ input[i] ^= key_1[i]; -+ for (i = 0; i < 8; i++) -+ input[i + 8] ^= key_2[i]; -+ -+ sha256_init(&state); -+ sha256_update(&state, input, sizeof(input)); -+ sha256_final(&state, hash_out); -+} -+ -+static void mptcp_key_sha1(u64 key, u32 *token, u64 *idsn) -+{ -+ u32 workspace[SHA_WORKSPACE_WORDS]; -+ u32 mptcp_hashed_key[SHA_DIGEST_WORDS]; -+ u8 input[64]; -+ int i; -+ -+ memset(workspace, 0, sizeof(workspace)); -+ -+ /* Initialize input with appropriate padding */ -+ memset(&input[9], 0, sizeof(input) - 10); /* -10, because the last byte -+ * is explicitly set too -+ */ -+ memcpy(input, &key, sizeof(key)); /* Copy key to the msg beginning */ -+ input[8] = 0x80; /* Padding: First bit after message = 1 */ -+ input[63] = 0x40; /* Padding: Length of the message = 64 bits */ -+ -+ sha_init(mptcp_hashed_key); -+ sha_transform(mptcp_hashed_key, input, workspace); -+ -+ for (i = 0; i < 5; i++) -+ mptcp_hashed_key[i] = (__force u32)cpu_to_be32(mptcp_hashed_key[i]); -+ -+ if (token) -+ *token = mptcp_hashed_key[0]; -+ if (idsn) -+ *idsn = ntohll(*((__be64 *)&mptcp_hashed_key[3])); -+} -+ -+static void mptcp_key_hash(u8 version, u64 key, u32 *token, u64 *idsn) -+{ -+ if (version == MPTCP_VERSION_0) -+ mptcp_key_sha1(key, token, idsn); -+ else if (version >= MPTCP_VERSION_1) -+ mptcp_key_sha256(key, token, idsn); -+} -+ -+static void mptcp_hmac_sha1(const u8 *key_1, const u8 *key_2, u32 *hash_out, -+ int arg_num, va_list list) -+{ -+ u32 workspace[SHA_WORKSPACE_WORDS]; -+ u8 input[128]; /* 2 512-bit blocks */ -+ int i; -+ int index; -+ int length; -+ u8 *msg; -+ -+ memset(workspace, 0, sizeof(workspace)); -+ -+ /* Generate key xored with ipad */ -+ memset(input, 0x36, 64); -+ for (i = 0; i < 8; i++) -+ input[i] ^= key_1[i]; -+ for (i = 0; i < 8; i++) -+ input[i + 8] ^= key_2[i]; -+ -+ index = 64; -+ for (i = 0; i < arg_num; i++) { -+ length = va_arg(list, int); -+ msg = va_arg(list, u8 *); -+ BUG_ON(index + length > 125); /* Message is too long */ -+ memcpy(&input[index], msg, length); -+ index += length; -+ } -+ -+ input[index] = 0x80; /* Padding: First bit after message = 1 */ -+ memset(&input[index + 1], 0, (126 - index)); -+ -+ /* Padding: Length of the message = 512 + message length (bits) */ -+ input[126] = 0x02; -+ input[127] = ((index - 64) * 8); /* Message length (bits) */ -+ -+ sha_init(hash_out); -+ sha_transform(hash_out, input, workspace); -+ memset(workspace, 0, sizeof(workspace)); -+ -+ sha_transform(hash_out, &input[64], workspace); -+ memset(workspace, 0, sizeof(workspace)); -+ -+ for (i = 0; i < 5; i++) -+ hash_out[i] = (__force u32)cpu_to_be32(hash_out[i]); -+ -+ /* Prepare second part of hmac */ -+ memset(input, 0x5C, 64); -+ for (i = 0; i < 8; i++) -+ input[i] ^= key_1[i]; -+ for (i = 0; i < 8; i++) -+ input[i + 8] ^= key_2[i]; -+ -+ memcpy(&input[64], hash_out, 20); -+ input[84] = 0x80; -+ memset(&input[85], 0, 41); -+ -+ /* Padding: Length of the message = 512 + 160 bits */ -+ input[126] = 0x02; -+ input[127] = 0xA0; -+ -+ sha_init(hash_out); -+ sha_transform(hash_out, input, workspace); -+ memset(workspace, 0, sizeof(workspace)); -+ -+ sha_transform(hash_out, &input[64], workspace); -+ -+ for (i = 0; i < 5; i++) -+ hash_out[i] = (__force u32)cpu_to_be32(hash_out[i]); -+} -+ -+void mptcp_hmac(u8 ver, const u8 *key_1, const u8 *key_2, u8 *hash_out, -+ int arg_num, ...) -+{ -+ va_list args; -+ -+ va_start(args, arg_num); -+ if (ver == MPTCP_VERSION_0) -+ mptcp_hmac_sha1(key_1, key_2, (u32 *)hash_out, arg_num, args); -+ else if (ver >= MPTCP_VERSION_1) -+ mptcp_hmac_sha256(key_1, key_2, hash_out, arg_num, args); -+ va_end(args); -+} -+EXPORT_SYMBOL(mptcp_hmac); -+ -+static void mptcp_mpcb_inherit_sockopts(struct sock *meta_sk, struct sock *master_sk) -+{ -+ /* Socket-options handled by sk_clone_lock while creating the meta-sk. -+ * ====== -+ * SO_SNDBUF, SO_SNDBUFFORCE, SO_RCVBUF, SO_RCVBUFFORCE, SO_RCVLOWAT, -+ * SO_RCVTIMEO, SO_SNDTIMEO, SO_ATTACH_FILTER, SO_DETACH_FILTER, -+ * TCP_NODELAY, TCP_CORK -+ * -+ * Socket-options handled in this function here -+ * ====== -+ * TCP_DEFER_ACCEPT -+ * SO_KEEPALIVE -+ * -+ * Socket-options on the todo-list -+ * ====== -+ * SO_BINDTODEVICE - should probably prevent creation of new subsocks -+ * across other devices. - what about the api-draft? -+ * SO_DEBUG -+ * SO_REUSEADDR - probably we don't care about this -+ * SO_DONTROUTE, SO_BROADCAST -+ * SO_OOBINLINE -+ * SO_LINGER -+ * SO_TIMESTAMP* - I don't think this is of concern for a SOCK_STREAM -+ * SO_PASSSEC - I don't think this is of concern for a SOCK_STREAM -+ * SO_RXQ_OVFL -+ * TCP_COOKIE_TRANSACTIONS -+ * TCP_MAXSEG -+ * TCP_THIN_* - Handled by sk_clone_lock, but we need to support this -+ * in mptcp_meta_retransmit_timer. AND we need to check -+ * what is about the subsockets. -+ * TCP_LINGER2 -+ * TCP_WINDOW_CLAMP -+ * TCP_USER_TIMEOUT -+ * TCP_MD5SIG -+ * -+ * Socket-options of no concern for the meta-socket (but for the subsocket) -+ * ====== -+ * SO_PRIORITY -+ * SO_MARK -+ * TCP_CONGESTION -+ * TCP_SYNCNT -+ * TCP_QUICKACK -+ */ -+ -+ /* DEFER_ACCEPT should not be set on the meta, as we want to accept new subflows directly */ -+ inet_csk(meta_sk)->icsk_accept_queue.rskq_defer_accept = 0; -+ -+ /* Keepalives are handled entirely at the MPTCP-layer */ -+ if (sock_flag(meta_sk, SOCK_KEEPOPEN)) { -+ inet_csk_reset_keepalive_timer(meta_sk, -+ keepalive_time_when(tcp_sk(meta_sk))); -+ sock_reset_flag(master_sk, SOCK_KEEPOPEN); -+ inet_csk_delete_keepalive_timer(master_sk); -+ } -+ -+ /* Do not propagate subflow-errors up to the MPTCP-layer */ -+ inet_sk(master_sk)->recverr = 0; -+} -+ -+/* Called without holding lock on meta_sk */ -+static void mptcp_sub_inherit_sockopts(const struct sock *meta_sk, struct sock *sub_sk) -+{ -+ __u8 meta_tos; -+ -+ /* IP_TOS also goes to the subflow. */ -+ meta_tos = READ_ONCE(inet_sk(meta_sk)->tos); -+ if (inet_sk(sub_sk)->tos != meta_tos) { -+ inet_sk(sub_sk)->tos = meta_tos; -+ sub_sk->sk_priority = meta_sk->sk_priority; -+ sk_dst_reset(sub_sk); -+ } -+ -+ /* Inherit SO_REUSEADDR */ -+ sub_sk->sk_reuse = meta_sk->sk_reuse; -+ -+ /* Inherit SO_MARK: can be used for routing or filtering */ -+ sub_sk->sk_mark = meta_sk->sk_mark; -+ -+ /* Inherit snd/rcv-buffer locks */ -+ sub_sk->sk_userlocks = meta_sk->sk_userlocks & ~SOCK_BINDPORT_LOCK; -+ -+ /* Nagle/Cork is forced off on the subflows. It is handled at the meta-layer */ -+ tcp_sk(sub_sk)->nonagle = TCP_NAGLE_OFF|TCP_NAGLE_PUSH; -+ -+ /* Keepalives are handled entirely at the MPTCP-layer */ -+ if (sock_flag(sub_sk, SOCK_KEEPOPEN)) { -+ sock_reset_flag(sub_sk, SOCK_KEEPOPEN); -+ inet_csk_delete_keepalive_timer(sub_sk); -+ } -+ -+ /* Do not propagate subflow-errors up to the MPTCP-layer */ -+ inet_sk(sub_sk)->recverr = 0; -+} -+ -+void mptcp_prepare_for_backlog(struct sock *sk, struct sk_buff *skb) -+{ -+ /* In case of success (in mptcp_backlog_rcv) and error (in kfree_skb) of -+ * sk_add_backlog, we will decrement the sk refcount. -+ */ -+ sock_hold(sk); -+ skb->sk = sk; -+ skb->destructor = sock_efree; -+} -+ -+int mptcp_backlog_rcv(struct sock *meta_sk, struct sk_buff *skb) -+{ -+ /* skb-sk may be NULL if we receive a packet immediatly after the -+ * SYN/ACK + MP_CAPABLE. -+ */ -+ struct sock *sk = skb->sk ? skb->sk : meta_sk; -+ int ret = 0; -+ -+ if (unlikely(!refcount_inc_not_zero(&sk->sk_refcnt))) { -+ kfree_skb(skb); -+ return 0; -+ } -+ -+ /* Decrement sk refcnt when calling the skb destructor. -+ * Refcnt is incremented and skb destructor is set in tcp_v{4,6}_rcv via -+ * mptcp_prepare_for_backlog() here above. -+ */ -+ skb_orphan(skb); -+ -+ if (sk->sk_family == AF_INET) -+ ret = tcp_v4_do_rcv(sk, skb); -+#if IS_ENABLED(CONFIG_IPV6) -+ else -+ ret = tcp_v6_do_rcv(sk, skb); -+#endif -+ -+ sock_put(sk); -+ return ret; -+} -+ -+static void mptcp_init_buffer_space(struct sock *sk) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct sock *meta_sk = mptcp_meta_sk(sk); -+ struct tcp_sock *meta_tp = tcp_sk(meta_sk); -+ int space; -+ -+ tcp_init_buffer_space(sk); -+ -+ if (is_master_tp(tp)) { -+ meta_tp->rcvq_space.space = meta_tp->rcv_wnd; -+ tcp_mstamp_refresh(meta_tp); -+ meta_tp->rcvq_space.time = meta_tp->tcp_mstamp; -+ meta_tp->rcvq_space.seq = meta_tp->copied_seq; -+ -+ /* If there is only one subflow, we just use regular TCP -+ * autotuning. User-locks are handled already by -+ * tcp_init_buffer_space -+ */ -+ meta_tp->window_clamp = tp->window_clamp; -+ meta_tp->rcv_ssthresh = tp->rcv_ssthresh; -+ meta_sk->sk_rcvbuf = sk->sk_rcvbuf; -+ meta_sk->sk_sndbuf = sk->sk_sndbuf; -+ -+ return; -+ } -+ -+ if (meta_sk->sk_userlocks & SOCK_RCVBUF_LOCK) -+ goto snd_buf; -+ -+ /* Adding a new subflow to the rcv-buffer space. We make a simple -+ * addition, to give some space to allow traffic on the new subflow. -+ * Autotuning will increase it further later on. -+ */ -+ space = min(meta_sk->sk_rcvbuf + sk->sk_rcvbuf, -+ sock_net(meta_sk)->ipv4.sysctl_tcp_rmem[2]); -+ if (space > meta_sk->sk_rcvbuf) { -+ meta_tp->window_clamp += tp->window_clamp; -+ meta_tp->rcv_ssthresh += tp->rcv_ssthresh; -+ meta_sk->sk_rcvbuf = space; -+ } -+ -+snd_buf: -+ if (meta_sk->sk_userlocks & SOCK_SNDBUF_LOCK) -+ return; -+ -+ /* Adding a new subflow to the send-buffer space. We make a simple -+ * addition, to give some space to allow traffic on the new subflow. -+ * Autotuning will increase it further later on. -+ */ -+ space = min(meta_sk->sk_sndbuf + sk->sk_sndbuf, -+ sock_net(meta_sk)->ipv4.sysctl_tcp_wmem[2]); -+ if (space > meta_sk->sk_sndbuf) { -+ meta_sk->sk_sndbuf = space; -+ meta_sk->sk_write_space(meta_sk); -+ } -+} -+ -+struct lock_class_key meta_key; -+char *meta_key_name = "sk_lock-AF_INET-MPTCP"; -+struct lock_class_key meta_slock_key; -+char *meta_slock_key_name = "slock-AF_INET-MPTCP"; -+ -+static const struct tcp_sock_ops mptcp_meta_specific = { -+ .__select_window = __mptcp_select_window, -+ .select_window = mptcp_select_window, -+ .select_initial_window = mptcp_select_initial_window, -+ .init_buffer_space = mptcp_init_buffer_space, -+ .set_rto = mptcp_tcp_set_rto, -+ .should_expand_sndbuf = mptcp_should_expand_sndbuf, -+ .send_fin = mptcp_send_fin, -+ .write_xmit = mptcp_write_xmit, -+ .send_active_reset = mptcp_send_active_reset, -+ .write_wakeup = mptcp_write_wakeup, -+ .retransmit_timer = mptcp_meta_retransmit_timer, -+ .time_wait = mptcp_time_wait, -+ .cleanup_rbuf = mptcp_cleanup_rbuf, -+ .set_cong_ctrl = mptcp_set_congestion_control, -+}; -+ -+static const struct tcp_sock_ops mptcp_sub_specific = { -+ .__select_window = __mptcp_select_window, -+ .select_window = mptcp_select_window, -+ .select_initial_window = mptcp_select_initial_window, -+ .init_buffer_space = mptcp_init_buffer_space, -+ .set_rto = mptcp_tcp_set_rto, -+ .should_expand_sndbuf = mptcp_should_expand_sndbuf, -+ .send_fin = tcp_send_fin, -+ .write_xmit = tcp_write_xmit, -+ .send_active_reset = tcp_send_active_reset, -+ .write_wakeup = tcp_write_wakeup, -+ .retransmit_timer = mptcp_sub_retransmit_timer, -+ .time_wait = tcp_time_wait, -+ .cleanup_rbuf = tcp_cleanup_rbuf, -+ .set_cong_ctrl = __tcp_set_congestion_control, -+}; -+ -+void mptcp_initialize_recv_vars(struct tcp_sock *meta_tp, struct mptcp_cb *mpcb, -+ __u64 remote_key) -+{ -+ u64 idsn; -+ -+ mpcb->mptcp_rem_key = remote_key; -+ mpcb->rem_key_set = 1; -+ mptcp_key_hash(mpcb->mptcp_ver, mpcb->mptcp_rem_key, &mpcb->mptcp_rem_token, &idsn); -+ -+ idsn++; -+ mpcb->rcv_high_order[0] = idsn >> 32; -+ mpcb->rcv_high_order[1] = mpcb->rcv_high_order[0] + 1; -+ meta_tp->copied_seq = (u32)idsn; -+ meta_tp->rcv_nxt = (u32)idsn; -+ meta_tp->rcv_wup = (u32)idsn; -+ -+ meta_tp->snd_wl1 = meta_tp->rcv_nxt - 1; -+} -+ -+static int mptcp_alloc_mpcb(struct sock *meta_sk, __u64 remote_key, -+ int rem_key_set, __u8 mptcp_ver, u32 window) -+{ -+ struct mptcp_cb *mpcb; -+ struct sock *master_sk; -+ struct inet_connection_sock *meta_icsk = inet_csk(meta_sk); -+ struct tcp_sock *master_tp, *meta_tp = tcp_sk(meta_sk); -+ u64 snd_idsn; -+ -+ dst_release(meta_sk->sk_rx_dst); -+ meta_sk->sk_rx_dst = NULL; -+ /* This flag is set to announce sock_lock_init to -+ * reclassify the lock-class of the master socket. -+ */ -+ meta_tp->is_master_sk = 1; -+ master_sk = sk_clone_lock(meta_sk, GFP_ATOMIC | __GFP_ZERO); -+ meta_tp->is_master_sk = 0; -+ if (!master_sk) -+ goto err_alloc_master; -+ -+ /* Same as in inet_csk_clone_lock - need to init to 0 */ -+ memset(&inet_csk(master_sk)->icsk_accept_queue, 0, -+ sizeof(inet_csk(master_sk)->icsk_accept_queue)); -+ -+ master_tp = tcp_sk(master_sk); -+ master_tp->inside_tk_table = 0; -+ -+ mpcb = kmem_cache_zalloc(mptcp_cb_cache, GFP_ATOMIC); -+ if (!mpcb) -+ goto err_alloc_mpcb; -+ -+ /* Store the mptcp version agreed on initial handshake */ -+ mpcb->mptcp_ver = mptcp_ver; -+ -+ /* Store the keys and generate the peer's token */ -+ mpcb->mptcp_loc_key = meta_tp->mptcp_loc_key; -+ mpcb->mptcp_loc_token = meta_tp->mptcp_loc_token; -+ -+ /* Generate Initial data-sequence-numbers */ -+ mptcp_key_hash(mpcb->mptcp_ver, mpcb->mptcp_loc_key, NULL, &snd_idsn); -+ snd_idsn++; -+ mpcb->snd_high_order[0] = snd_idsn >> 32; -+ mpcb->snd_high_order[1] = mpcb->snd_high_order[0] - 1; -+ -+ mpcb->meta_sk = meta_sk; -+ mpcb->master_sk = master_sk; -+ -+ skb_queue_head_init(&mpcb->reinject_queue); -+ mutex_init(&mpcb->mpcb_mutex); -+ -+ /* Init time-wait stuff */ -+ INIT_LIST_HEAD(&mpcb->tw_list); -+ -+ INIT_HLIST_HEAD(&mpcb->callback_list); -+ INIT_HLIST_HEAD(&mpcb->conn_list); -+ spin_lock_init(&mpcb->mpcb_list_lock); -+ -+ mpcb->orig_sk_rcvbuf = meta_sk->sk_rcvbuf; -+ mpcb->orig_sk_sndbuf = meta_sk->sk_sndbuf; -+ mpcb->orig_window_clamp = meta_tp->window_clamp; -+ -+ /* The meta is directly linked - set refcnt to 1 */ -+ refcount_set(&mpcb->mpcb_refcnt, 1); -+ -+ if (!meta_tp->inside_tk_table) { -+ /* Adding the meta_tp in the token hashtable - coming from server-side */ -+ rcu_read_lock(); -+ local_bh_disable(); -+ spin_lock(&mptcp_tk_hashlock); -+ -+ /* With lockless listeners, we might process two ACKs at the -+ * same time. With TCP, inet_csk_complete_hashdance takes care -+ * of this. But, for MPTCP this would be too late if we add -+ * this MPTCP-socket in the token table (new subflows might -+ * come in and match on this socket here. -+ * So, we need to check if someone else already added the token -+ * and revert in that case. The other guy won the race... -+ */ -+ if (mptcp_find_token(mpcb->mptcp_loc_token)) { -+ spin_unlock(&mptcp_tk_hashlock); -+ local_bh_enable(); -+ rcu_read_unlock(); -+ -+ goto err_insert_token; -+ } -+ __mptcp_hash_insert(meta_tp, mpcb->mptcp_loc_token); -+ -+ spin_unlock(&mptcp_tk_hashlock); -+ local_bh_enable(); -+ rcu_read_unlock(); -+ } -+ -+#if IS_ENABLED(CONFIG_IPV6) -+ if (meta_icsk->icsk_af_ops == &mptcp_v6_mapped) { -+ struct tcp6_sock *master_tp6 = (struct tcp6_sock *)master_sk; -+ struct ipv6_pinfo *newnp, *np = inet6_sk(meta_sk); -+ -+ inet_sk(master_sk)->pinet6 = &master_tp6->inet6; -+ -+ newnp = inet6_sk(master_sk); -+ memcpy(newnp, np, sizeof(struct ipv6_pinfo)); -+ -+ newnp->ipv6_mc_list = NULL; -+ newnp->ipv6_ac_list = NULL; -+ newnp->ipv6_fl_list = NULL; -+ newnp->pktoptions = NULL; -+ newnp->opt = NULL; -+ -+ newnp->rxopt.all = 0; -+ newnp->repflow = 0; -+ np->rxopt.all = 0; -+ np->repflow = 0; -+ } else if (meta_sk->sk_family == AF_INET6) { -+ struct tcp6_sock *master_tp6 = (struct tcp6_sock *)master_sk; -+ struct ipv6_pinfo *newnp, *np = inet6_sk(meta_sk); -+ struct ipv6_txoptions *opt; -+ -+ inet_sk(master_sk)->pinet6 = &master_tp6->inet6; -+ -+ /* The following heavily inspired from tcp_v6_syn_recv_sock() */ -+ newnp = inet6_sk(master_sk); -+ memcpy(newnp, np, sizeof(struct ipv6_pinfo)); -+ -+ newnp->ipv6_mc_list = NULL; -+ newnp->ipv6_ac_list = NULL; -+ newnp->ipv6_fl_list = NULL; -+ newnp->pktoptions = NULL; -+ newnp->opt = NULL; -+ -+ newnp->rxopt.all = 0; -+ newnp->repflow = 0; -+ np->rxopt.all = 0; -+ np->repflow = 0; -+ -+ opt = rcu_dereference(np->opt); -+ if (opt) { -+ opt = ipv6_dup_options(master_sk, opt); -+ RCU_INIT_POINTER(newnp->opt, opt); -+ } -+ inet_csk(master_sk)->icsk_ext_hdr_len = 0; -+ if (opt) -+ inet_csk(master_sk)->icsk_ext_hdr_len = opt->opt_nflen + -+ opt->opt_flen; -+ } -+#endif -+ -+ meta_tp->mptcp = NULL; -+ -+ meta_tp->write_seq = (u32)snd_idsn; -+ meta_tp->snd_sml = meta_tp->write_seq; -+ meta_tp->snd_una = meta_tp->write_seq; -+ meta_tp->snd_nxt = meta_tp->write_seq; -+ meta_tp->pushed_seq = meta_tp->write_seq; -+ meta_tp->snd_up = meta_tp->write_seq; -+ -+ if (rem_key_set) -+ mptcp_initialize_recv_vars(meta_tp, mpcb, remote_key); -+ -+ meta_tp->snd_wnd = window; -+ meta_tp->retrans_stamp = 0; /* Set in tcp_connect() */ -+ -+ meta_tp->packets_out = 0; -+ meta_icsk->icsk_probes_out = 0; -+ -+ rcu_assign_pointer(inet_sk(meta_sk)->inet_opt, NULL); -+ -+ /* Set mptcp-pointers */ -+ master_tp->mpcb = mpcb; -+ master_tp->meta_sk = meta_sk; -+ meta_tp->mpcb = mpcb; -+ meta_tp->meta_sk = meta_sk; -+ -+ /* Initialize the queues */ -+ master_tp->out_of_order_queue = RB_ROOT; -+ master_sk->tcp_rtx_queue = RB_ROOT; -+ INIT_LIST_HEAD(&master_tp->tsq_node); -+ INIT_LIST_HEAD(&master_tp->tsorted_sent_queue); -+ -+ master_sk->sk_tsq_flags = 0; -+ /* icsk_bind_hash inherited from the meta, but it will be properly set in -+ * mptcp_create_master_sk. Same operation is done in inet_csk_clone_lock. -+ */ -+ inet_csk(master_sk)->icsk_bind_hash = NULL; -+ -+ /* Init the accept_queue structure, we support a queue of 32 pending -+ * connections, it does not need to be huge, since we only store here -+ * pending subflow creations. -+ */ -+ reqsk_queue_alloc(&meta_icsk->icsk_accept_queue); -+ meta_sk->sk_max_ack_backlog = 32; -+ meta_sk->sk_ack_backlog = 0; -+ -+ if (!sock_flag(meta_sk, SOCK_MPTCP)) { -+ mptcp_enable_static_key_bh(); -+ sock_set_flag(meta_sk, SOCK_MPTCP); -+ } -+ -+ /* Redefine function-pointers as the meta-sk is now fully ready */ -+ meta_tp->mpc = 1; -+ meta_tp->ops = &mptcp_meta_specific; -+ -+ meta_sk->sk_backlog_rcv = mptcp_backlog_rcv; -+ meta_sk->sk_destruct = mptcp_sock_destruct; -+ -+ /* Meta-level retransmit timer */ -+ meta_icsk->icsk_rto *= 2; /* Double of initial - rto */ -+ -+ tcp_init_xmit_timers(master_sk); -+ /* Has been set for sending out the SYN */ -+ inet_csk_clear_xmit_timer(meta_sk, ICSK_TIME_RETRANS); -+ -+ mptcp_mpcb_inherit_sockopts(meta_sk, master_sk); -+ -+ mptcp_init_path_manager(mpcb); -+ mptcp_init_scheduler(mpcb); -+ -+ if (!try_module_get(inet_csk(master_sk)->icsk_ca_ops->owner)) -+ tcp_assign_congestion_control(master_sk); -+ -+ master_tp->saved_syn = NULL; -+ -+ mptcp_debug("%s: created mpcb with token %#x\n", -+ __func__, mpcb->mptcp_loc_token); -+ -+ return 0; -+ -+err_insert_token: -+ kmem_cache_free(mptcp_cb_cache, mpcb); -+ -+err_alloc_mpcb: -+ inet_sk(master_sk)->inet_opt = NULL; -+ master_sk->sk_state = TCP_CLOSE; -+ sock_orphan(master_sk); -+ bh_unlock_sock(master_sk); -+ sk_free(master_sk); -+ -+err_alloc_master: -+ return -ENOBUFS; -+} -+ -+/* Called without holding lock on mpcb */ -+static u8 mptcp_set_new_pathindex(struct mptcp_cb *mpcb) -+{ -+ int i; -+ -+ /* Start at 1, because 0 is reserved for the meta-sk */ -+ for (i = 1; i < sizeof(mpcb->path_index_bits) * 8; i++) { -+ if (!test_and_set_bit(i, &mpcb->path_index_bits)) -+ break; -+ } -+ -+ if (i == sizeof(mpcb->path_index_bits) * 8) -+ return 0; -+ return i; -+} -+ -+/* May be called without holding the meta-level lock */ -+int mptcp_add_sock(struct sock *meta_sk, struct sock *sk, u8 loc_id, u8 rem_id, -+ gfp_t flags) -+{ -+ struct mptcp_cb *mpcb = tcp_sk(meta_sk)->mpcb; -+ struct tcp_sock *tp = tcp_sk(sk); -+ -+ tp->mptcp = kmem_cache_zalloc(mptcp_sock_cache, flags); -+ if (!tp->mptcp) -+ return -ENOMEM; -+ -+ tp->mptcp->path_index = mptcp_set_new_pathindex(mpcb); -+ /* No more space for more subflows? */ -+ if (!tp->mptcp->path_index) { -+ kmem_cache_free(mptcp_sock_cache, tp->mptcp); -+ return -EPERM; -+ } -+ -+ INIT_HLIST_NODE(&tp->mptcp->cb_list); -+ -+ tp->mptcp->tp = tp; -+ tp->mpcb = mpcb; -+ tp->meta_sk = meta_sk; -+ -+ if (!sock_flag(sk, SOCK_MPTCP)) { -+ mptcp_enable_static_key_bh(); -+ sock_set_flag(sk, SOCK_MPTCP); -+ } -+ -+ tp->mpc = 1; -+ tp->ops = &mptcp_sub_specific; -+ -+ tp->mptcp->loc_id = loc_id; -+ tp->mptcp->rem_id = rem_id; -+ if (mpcb->sched_ops->init) -+ mpcb->sched_ops->init(sk); -+ -+ /* The corresponding sock_put is in mptcp_sock_destruct(). It cannot be -+ * included in mptcp_del_sock(), because the mpcb must remain alive -+ * until the last subsocket is completely destroyed. -+ */ -+ sock_hold(meta_sk); -+ refcount_inc(&mpcb->mpcb_refcnt); -+ -+ spin_lock_bh(&mpcb->mpcb_list_lock); -+ hlist_add_head_rcu(&tp->mptcp->node, &mpcb->conn_list); -+ spin_unlock_bh(&mpcb->mpcb_list_lock); -+ -+ tp->mptcp->attached = 1; -+ -+ mptcp_sub_inherit_sockopts(meta_sk, sk); -+ INIT_DELAYED_WORK(&tp->mptcp->work, mptcp_sub_close_wq); -+ -+ /* Properly inherit CC from the meta-socket */ -+ mptcp_assign_congestion_control(sk); -+ -+ /* As we successfully allocated the mptcp_tcp_sock, we have to -+ * change the function-pointers here (for sk_destruct to work correctly) -+ */ -+ sk->sk_error_report = mptcp_sock_def_error_report; -+ sk->sk_data_ready = mptcp_data_ready; -+ sk->sk_write_space = mptcp_write_space; -+ sk->sk_state_change = mptcp_set_state; -+ sk->sk_destruct = mptcp_sock_destruct; -+ -+ if (sk->sk_family == AF_INET) -+ mptcp_debug("%s: token %#x pi %d, src_addr:%pI4:%d dst_addr:%pI4:%d\n", -+ __func__ , mpcb->mptcp_loc_token, -+ tp->mptcp->path_index, -+ &((struct inet_sock *)tp)->inet_saddr, -+ ntohs(((struct inet_sock *)tp)->inet_sport), -+ &((struct inet_sock *)tp)->inet_daddr, -+ ntohs(((struct inet_sock *)tp)->inet_dport)); -+#if IS_ENABLED(CONFIG_IPV6) -+ else -+ mptcp_debug("%s: token %#x pi %d, src_addr:%pI6:%d dst_addr:%pI6:%d\n", -+ __func__ , mpcb->mptcp_loc_token, -+ tp->mptcp->path_index, &inet6_sk(sk)->saddr, -+ ntohs(((struct inet_sock *)tp)->inet_sport), -+ &sk->sk_v6_daddr, -+ ntohs(((struct inet_sock *)tp)->inet_dport)); -+#endif -+ -+ return 0; -+} -+ -+void mptcp_del_sock(struct sock *sk) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct mptcp_cb *mpcb; -+ -+ if (!tp->mptcp || !tp->mptcp->attached) -+ return; -+ -+ mpcb = tp->mpcb; -+ -+ if (mpcb->sched_ops->release) -+ mpcb->sched_ops->release(sk); -+ -+ if (mpcb->pm_ops->delete_subflow) -+ mpcb->pm_ops->delete_subflow(sk); -+ -+ mptcp_debug("%s: Removing subsock tok %#x pi:%d state %d is_meta? %d\n", -+ __func__, mpcb->mptcp_loc_token, tp->mptcp->path_index, -+ sk->sk_state, is_meta_sk(sk)); -+ -+ spin_lock_bh(&mpcb->mpcb_list_lock); -+ hlist_del_init_rcu(&tp->mptcp->node); -+ spin_unlock_bh(&mpcb->mpcb_list_lock); -+ -+ tp->mptcp->attached = 0; -+ mpcb->path_index_bits &= ~(1 << tp->mptcp->path_index); -+ -+ if (!tcp_write_queue_empty(sk) || !tcp_rtx_queue_empty(sk)) -+ mptcp_reinject_data(sk, 0); -+ -+ if (is_master_tp(tp)) { -+ struct sock *meta_sk = mptcp_meta_sk(sk); -+ struct tcp_sock *meta_tp = tcp_sk(meta_sk); -+ -+ if (meta_tp->record_master_info && -+ !sock_flag(meta_sk, SOCK_DEAD)) { -+ mpcb->master_info = kmalloc(sizeof(*mpcb->master_info), -+ GFP_ATOMIC); -+ -+ if (mpcb->master_info) -+ tcp_get_info(sk, mpcb->master_info, true); -+ } -+ -+ mpcb->master_sk = NULL; -+ } else if (tp->mptcp->pre_established) { -+ sk_stop_timer(sk, &tp->mptcp->mptcp_ack_timer); -+ } -+} -+ -+/* Updates the MPTCP-session based on path-manager information (e.g., addresses, -+ * low-prio flows,...). -+ */ -+void mptcp_update_metasocket(const struct sock *meta_sk) -+{ -+ if (tcp_sk(meta_sk)->mpcb->pm_ops->new_session) -+ tcp_sk(meta_sk)->mpcb->pm_ops->new_session(meta_sk); -+} -+ -+/* Clean up the receive buffer for full frames taken by the user, -+ * then send an ACK if necessary. COPIED is the number of bytes -+ * tcp_recvmsg has given to the user so far, it speeds up the -+ * calculation of whether or not we must ACK for the sake of -+ * a window update. -+ * (inspired from tcp_cleanup_rbuf()) -+ */ -+void mptcp_cleanup_rbuf(struct sock *meta_sk, int copied) -+{ -+ struct tcp_sock *meta_tp = tcp_sk(meta_sk); -+ bool recheck_rcv_window = false; -+ struct mptcp_tcp_sock *mptcp; -+ __u32 rcv_window_now = 0; -+ -+ if (copied > 0 && !(meta_sk->sk_shutdown & RCV_SHUTDOWN)) { -+ rcv_window_now = tcp_receive_window(meta_tp); -+ -+ /* Optimize, __mptcp_select_window() is not cheap. */ -+ if (2 * rcv_window_now <= meta_tp->window_clamp) -+ recheck_rcv_window = true; -+ } -+ -+ mptcp_for_each_sub(meta_tp->mpcb, mptcp) { -+ struct sock *sk = mptcp_to_sock(mptcp); -+ struct tcp_sock *tp = tcp_sk(sk); -+ const struct inet_connection_sock *icsk = inet_csk(sk); -+ -+ if (!mptcp_sk_can_send_ack(sk)) -+ continue; -+ -+ if (!inet_csk_ack_scheduled(sk)) -+ goto second_part; -+ /* Delayed ACKs frequently hit locked sockets during bulk -+ * receive. -+ */ -+ if (icsk->icsk_ack.blocked || -+ /* Once-per-two-segments ACK was not sent by tcp_input.c */ -+ tp->rcv_nxt - tp->rcv_wup > icsk->icsk_ack.rcv_mss || -+ /* If this read emptied read buffer, we send ACK, if -+ * connection is not bidirectional, user drained -+ * receive buffer and there was a small segment -+ * in queue. -+ */ -+ (copied > 0 && -+ ((icsk->icsk_ack.pending & ICSK_ACK_PUSHED2) || -+ ((icsk->icsk_ack.pending & ICSK_ACK_PUSHED) && -+ !icsk->icsk_ack.pingpong)) && -+ !atomic_read(&meta_sk->sk_rmem_alloc))) { -+ tcp_send_ack(sk); -+ continue; -+ } -+ -+second_part: -+ /* This here is the second part of tcp_cleanup_rbuf */ -+ if (recheck_rcv_window) { -+ __u32 new_window = tp->ops->__select_window(sk); -+ -+ /* Send ACK now, if this read freed lots of space -+ * in our buffer. Certainly, new_window is new window. -+ * We can advertise it now, if it is not less than -+ * current one. -+ * "Lots" means "at least twice" here. -+ */ -+ if (new_window && new_window >= 2 * rcv_window_now) -+ tcp_send_ack(sk); -+ } -+ } -+} -+ -+static int mptcp_sub_send_fin(struct sock *sk) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct sk_buff *skb = tcp_write_queue_tail(sk); -+ int mss_now; -+ -+ /* Optimization, tack on the FIN if we have a queue of -+ * unsent frames. But be careful about outgoing SACKS -+ * and IP options. -+ */ -+ mss_now = tcp_current_mss(sk); -+ -+ if (tcp_send_head(sk) != NULL) { -+ TCP_SKB_CB(skb)->tcp_flags |= TCPHDR_FIN; -+ TCP_SKB_CB(skb)->end_seq++; -+ tp->write_seq++; -+ } else { -+ skb = alloc_skb_fclone(MAX_TCP_HEADER, GFP_ATOMIC); -+ if (!skb) -+ return 1; -+ -+ INIT_LIST_HEAD(&skb->tcp_tsorted_anchor); -+ skb_reserve(skb, MAX_TCP_HEADER); -+ /* FIN eats a sequence byte, write_seq advanced by tcp_queue_skb(). */ -+ tcp_init_nondata_skb(skb, tp->write_seq, -+ TCPHDR_ACK | TCPHDR_FIN); -+ tcp_queue_skb(sk, skb); -+ } -+ __tcp_push_pending_frames(sk, mss_now, TCP_NAGLE_OFF); -+ -+ return 0; -+} -+ -+static void mptcp_sub_close_doit(struct sock *sk) -+{ -+ struct sock *meta_sk = mptcp_meta_sk(sk); -+ struct tcp_sock *tp = tcp_sk(sk); -+ -+ if (sock_flag(sk, SOCK_DEAD)) -+ return; -+ -+ if (meta_sk->sk_shutdown == SHUTDOWN_MASK || sk->sk_state == TCP_CLOSE) { -+ tp->closing = 1; -+ tcp_close(sk, 0); -+ } else if (tcp_close_state(sk)) { -+ sk->sk_shutdown |= SEND_SHUTDOWN; -+ tcp_send_fin(sk); -+ } -+} -+ -+void mptcp_sub_close_wq(struct work_struct *work) -+{ -+ struct tcp_sock *tp = container_of(work, struct mptcp_tcp_sock, work.work)->tp; -+ struct sock *sk = (struct sock *)tp; -+ struct mptcp_cb *mpcb = tp->mpcb; -+ struct sock *meta_sk = mptcp_meta_sk(sk); -+ -+ mutex_lock(&mpcb->mpcb_mutex); -+ lock_sock_nested(meta_sk, SINGLE_DEPTH_NESTING); -+ -+ mptcp_sub_close_doit(sk); -+ -+ release_sock(meta_sk); -+ mutex_unlock(&mpcb->mpcb_mutex); -+ mptcp_mpcb_put(mpcb); -+ sock_put(sk); -+} -+ -+void mptcp_sub_close(struct sock *sk, unsigned long delay) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct delayed_work *work = &tcp_sk(sk)->mptcp->work; -+ -+ /* We are already closing - e.g., call from sock_def_error_report upon -+ * tcp_disconnect in tcp_close. -+ */ -+ if (tp->closing) -+ return; -+ -+ /* Work already scheduled ? */ -+ if (work_pending(&work->work)) { -+ /* Work present - who will be first ? */ -+ if (jiffies + delay > work->timer.expires) -+ return; -+ -+ /* Try canceling - if it fails, work will be executed soon */ -+ if (!cancel_delayed_work(work)) -+ return; -+ sock_put(sk); -+ mptcp_mpcb_put(tp->mpcb); -+ } -+ -+ if (!delay) { -+ unsigned char old_state = sk->sk_state; -+ -+ /* We directly send the FIN. Because it may take so a long time, -+ * untile the work-queue will get scheduled... -+ * -+ * If mptcp_sub_send_fin returns 1, it failed and thus we reset -+ * the old state so that tcp_close will finally send the fin -+ * in user-context. -+ */ -+ if (!sk->sk_err && old_state != TCP_CLOSE && -+ tcp_close_state(sk) && mptcp_sub_send_fin(sk)) { -+ if (old_state == TCP_ESTABLISHED) -+ TCP_INC_STATS(sock_net(sk), TCP_MIB_CURRESTAB); -+ sk->sk_state = old_state; -+ } -+ } -+ -+ sock_hold(sk); -+ refcount_inc(&tp->mpcb->mpcb_refcnt); -+ queue_delayed_work(mptcp_wq, work, delay); -+} -+ -+void mptcp_sub_force_close(struct sock *sk) -+{ -+ /* The below tcp_done may have freed the socket, if he is already dead. -+ * Thus, we are not allowed to access it afterwards. That's why -+ * we have to store the dead-state in this local variable. -+ */ -+ int sock_is_dead = sock_flag(sk, SOCK_DEAD); -+ -+ tcp_sk(sk)->mp_killed = 1; -+ -+ if (sk->sk_state != TCP_CLOSE) -+ tcp_done(sk); -+ -+ if (!sock_is_dead) -+ mptcp_sub_close(sk, 0); -+} -+EXPORT_SYMBOL(mptcp_sub_force_close); -+ -+/* Update the mpcb send window, based on the contributions -+ * of each subflow -+ */ -+void mptcp_update_sndbuf(const struct tcp_sock *tp) -+{ -+ struct sock *meta_sk = tp->meta_sk; -+ int new_sndbuf = 0, old_sndbuf = meta_sk->sk_sndbuf; -+ struct mptcp_tcp_sock *mptcp; -+ -+ mptcp_for_each_sub(tp->mpcb, mptcp) { -+ struct sock *sk = mptcp_to_sock(mptcp); -+ -+ if (!mptcp_sk_can_send(sk)) -+ continue; -+ -+ new_sndbuf += sk->sk_sndbuf; -+ -+ if (new_sndbuf > sock_net(meta_sk)->ipv4.sysctl_tcp_wmem[2] || -+ new_sndbuf < 0) { -+ new_sndbuf = sock_net(meta_sk)->ipv4.sysctl_tcp_wmem[2]; -+ break; -+ } -+ } -+ meta_sk->sk_sndbuf = max(min(new_sndbuf, -+ sock_net(meta_sk)->ipv4.sysctl_tcp_wmem[2]), -+ meta_sk->sk_sndbuf); -+ -+ /* The subflow's call to sk_write_space in tcp_new_space ends up in -+ * mptcp_write_space. -+ * It has nothing to do with waking up the application. -+ * So, we do it here. -+ */ -+ if (old_sndbuf != meta_sk->sk_sndbuf) -+ meta_sk->sk_write_space(meta_sk); -+} -+ -+/* Similar to: tcp_close */ -+void mptcp_close(struct sock *meta_sk, long timeout) -+{ -+ struct tcp_sock *meta_tp = tcp_sk(meta_sk); -+ struct mptcp_cb *mpcb = meta_tp->mpcb; -+ struct mptcp_tcp_sock *mptcp; -+ struct sk_buff *skb; -+ int data_was_unread = 0; -+ int state; -+ -+ mptcp_debug("%s: Close of meta_sk with tok %#x\n", -+ __func__, mpcb->mptcp_loc_token); -+ -+ WARN_ON(refcount_inc_not_zero(&mpcb->mpcb_refcnt) == 0); -+ mutex_lock(&mpcb->mpcb_mutex); -+ lock_sock_nested(meta_sk, SINGLE_DEPTH_NESTING); -+ -+ if (meta_tp->inside_tk_table) -+ /* Detach the mpcb from the token hashtable */ -+ mptcp_hash_remove_bh(meta_tp); -+ -+ meta_sk->sk_shutdown = SHUTDOWN_MASK; -+ /* We need to flush the recv. buffs. We do this only on the -+ * descriptor close, not protocol-sourced closes, because the -+ * reader process may not have drained the data yet! -+ */ -+ while ((skb = __skb_dequeue(&meta_sk->sk_receive_queue)) != NULL) { -+ u32 len = TCP_SKB_CB(skb)->end_seq - TCP_SKB_CB(skb)->seq; -+ -+ if (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN) -+ len--; -+ data_was_unread += len; -+ __kfree_skb(skb); -+ } -+ -+ sk_mem_reclaim(meta_sk); -+ -+ /* If socket has been already reset (e.g. in tcp_reset()) - kill it. */ -+ if (meta_sk->sk_state == TCP_CLOSE) { -+ struct mptcp_tcp_sock *mptcp; -+ struct hlist_node *tmp; -+ -+ mptcp_for_each_sub_safe(mpcb, mptcp, tmp) { -+ struct sock *sk_it = mptcp_to_sock(mptcp); -+ -+ if (tcp_sk(sk_it)->send_mp_fclose) -+ continue; -+ mptcp_sub_close(sk_it, 0); -+ } -+ goto adjudge_to_death; -+ } -+ -+ if (data_was_unread) { -+ /* Unread data was tossed, zap the connection. */ -+ NET_INC_STATS(sock_net(meta_sk), LINUX_MIB_TCPABORTONCLOSE); -+ tcp_set_state(meta_sk, TCP_CLOSE); -+ tcp_sk(meta_sk)->ops->send_active_reset(meta_sk, -+ meta_sk->sk_allocation); -+ } else if (sock_flag(meta_sk, SOCK_LINGER) && !meta_sk->sk_lingertime) { -+ /* Check zero linger _after_ checking for unread data. */ -+ meta_sk->sk_prot->disconnect(meta_sk, 0); -+ NET_INC_STATS(sock_net(meta_sk), LINUX_MIB_TCPABORTONDATA); -+ } else if (tcp_close_state(meta_sk)) { -+ mptcp_send_fin(meta_sk); -+ } else if (meta_tp->snd_una == meta_tp->write_seq) { -+ struct mptcp_tcp_sock *mptcp; -+ struct hlist_node *tmp; -+ -+ /* The DATA_FIN has been sent and acknowledged -+ * (e.g., by sk_shutdown). Close all the other subflows -+ */ -+ mptcp_for_each_sub_safe(mpcb, mptcp, tmp) { -+ struct sock *sk_it = mptcp_to_sock(mptcp); -+ unsigned long delay = 0; -+ /* If we are the passive closer, don't trigger -+ * subflow-fin until the subflow has been finned -+ * by the peer. - thus we add a delay -+ */ -+ if (mpcb->passive_close && -+ sk_it->sk_state == TCP_ESTABLISHED) -+ delay = inet_csk(sk_it)->icsk_rto << 3; -+ -+ mptcp_sub_close(sk_it, delay); -+ } -+ } -+ -+ sk_stream_wait_close(meta_sk, timeout); -+ -+adjudge_to_death: -+ state = meta_sk->sk_state; -+ sock_hold(meta_sk); -+ sock_orphan(meta_sk); -+ -+ /* socket will be freed after mptcp_close - we have to prevent -+ * access from the subflows. -+ */ -+ mptcp_for_each_sub(mpcb, mptcp) { -+ struct sock *sk_it = mptcp_to_sock(mptcp); -+ -+ /* Similar to sock_orphan, but we don't set it DEAD, because -+ * the callbacks are still set and must be called. -+ */ -+ write_lock_bh(&sk_it->sk_callback_lock); -+ sk_set_socket(sk_it, NULL); -+ sk_it->sk_wq = NULL; -+ write_unlock_bh(&sk_it->sk_callback_lock); -+ } -+ -+ if (mpcb->pm_ops->close_session) -+ mpcb->pm_ops->close_session(meta_sk); -+ -+ /* It is the last release_sock in its life. It will remove backlog. */ -+ release_sock(meta_sk); -+ -+ /* Now socket is owned by kernel and we acquire BH lock -+ * to finish close. No need to check for user refs. -+ */ -+ local_bh_disable(); -+ bh_lock_sock(meta_sk); -+ WARN_ON(sock_owned_by_user(meta_sk)); -+ -+ percpu_counter_inc(meta_sk->sk_prot->orphan_count); -+ -+ /* Have we already been destroyed by a softirq or backlog? */ -+ if (state != TCP_CLOSE && meta_sk->sk_state == TCP_CLOSE) -+ goto out; -+ -+ /* This is a (useful) BSD violating of the RFC. There is a -+ * problem with TCP as specified in that the other end could -+ * keep a socket open forever with no application left this end. -+ * We use a 3 minute timeout (about the same as BSD) then kill -+ * our end. If they send after that then tough - BUT: long enough -+ * that we won't make the old 4*rto = almost no time - whoops -+ * reset mistake. -+ * -+ * Nope, it was not mistake. It is really desired behaviour -+ * f.e. on http servers, when such sockets are useless, but -+ * consume significant resources. Let's do it with special -+ * linger2 option. --ANK -+ */ -+ -+ if (meta_sk->sk_state == TCP_FIN_WAIT2) { -+ if (meta_tp->linger2 < 0) { -+ tcp_set_state(meta_sk, TCP_CLOSE); -+ meta_tp->ops->send_active_reset(meta_sk, GFP_ATOMIC); -+ __NET_INC_STATS(sock_net(meta_sk), -+ LINUX_MIB_TCPABORTONLINGER); -+ } else { -+ const int tmo = tcp_fin_time(meta_sk); -+ -+ if (tmo > TCP_TIMEWAIT_LEN) { -+ inet_csk_reset_keepalive_timer(meta_sk, -+ tmo - TCP_TIMEWAIT_LEN); -+ } else { -+ meta_tp->ops->time_wait(meta_sk, TCP_FIN_WAIT2, -+ tmo); -+ goto out; -+ } -+ } -+ } -+ if (meta_sk->sk_state != TCP_CLOSE) { -+ sk_mem_reclaim(meta_sk); -+ if (tcp_check_oom(meta_sk, 0)) { -+ if (net_ratelimit()) -+ pr_info("MPTCP: out of memory: force closing socket\n"); -+ tcp_set_state(meta_sk, TCP_CLOSE); -+ meta_tp->ops->send_active_reset(meta_sk, GFP_ATOMIC); -+ __NET_INC_STATS(sock_net(meta_sk), -+ LINUX_MIB_TCPABORTONMEMORY); -+ } -+ } -+ -+ -+ if (meta_sk->sk_state == TCP_CLOSE) -+ inet_csk_destroy_sock(meta_sk); -+ /* Otherwise, socket is reprieved until protocol close. */ -+ -+out: -+ bh_unlock_sock(meta_sk); -+ local_bh_enable(); -+ mutex_unlock(&mpcb->mpcb_mutex); -+ mptcp_mpcb_put(mpcb); -+ sock_put(meta_sk); /* Taken by sock_hold */ -+} -+ -+void mptcp_disconnect(struct sock *meta_sk) -+{ -+ struct tcp_sock *meta_tp = tcp_sk(meta_sk); -+ struct mptcp_tcp_sock *mptcp; -+ struct hlist_node *tmp; -+ -+ __skb_queue_purge(&meta_tp->mpcb->reinject_queue); -+ -+ if (meta_tp->inside_tk_table) -+ mptcp_hash_remove_bh(meta_tp); -+ -+ local_bh_disable(); -+ mptcp_for_each_sub_safe(meta_tp->mpcb, mptcp, tmp) { -+ struct sock *subsk = mptcp_to_sock(mptcp); -+ -+ if (spin_is_locked(&subsk->sk_lock.slock)) -+ bh_unlock_sock(subsk); -+ -+ tcp_sk(subsk)->tcp_disconnect = 1; -+ -+ meta_sk->sk_prot->disconnect(subsk, O_NONBLOCK); -+ -+ sock_orphan(subsk); -+ -+ percpu_counter_inc(meta_sk->sk_prot->orphan_count); -+ -+ inet_csk_destroy_sock(subsk); -+ } -+ local_bh_enable(); -+ -+ mptcp_mpcb_cleanup(meta_tp->mpcb); -+ meta_tp->meta_sk = NULL; -+ -+ meta_tp->send_mp_fclose = 0; -+ meta_tp->mpc = 0; -+ meta_tp->ops = &tcp_specific; -+#if IS_ENABLED(CONFIG_IPV6) -+ if (meta_sk->sk_family == AF_INET6) -+ meta_sk->sk_backlog_rcv = tcp_v6_do_rcv; -+ else -+ meta_sk->sk_backlog_rcv = tcp_v4_do_rcv; -+#else -+ meta_sk->sk_backlog_rcv = tcp_v4_do_rcv; -+#endif -+ meta_sk->sk_destruct = inet_sock_destruct; -+} -+ -+ -+/* Returns True if we should enable MPTCP for that socket. */ -+bool mptcp_doit(struct sock *sk) -+{ -+ const struct dst_entry *dst = __sk_dst_get(sk); -+ -+ /* Don't do mptcp over loopback */ -+ if (sk->sk_family == AF_INET && -+ (ipv4_is_loopback(inet_sk(sk)->inet_daddr) || -+ ipv4_is_loopback(inet_sk(sk)->inet_saddr))) -+ return false; -+#if IS_ENABLED(CONFIG_IPV6) -+ if (sk->sk_family == AF_INET6 && -+ (ipv6_addr_loopback(&sk->sk_v6_daddr) || -+ ipv6_addr_loopback(&inet6_sk(sk)->saddr))) -+ return false; -+#endif -+ if (mptcp_v6_is_v4_mapped(sk) && -+ ipv4_is_loopback(inet_sk(sk)->inet_saddr)) -+ return false; -+ -+#ifdef CONFIG_TCP_MD5SIG -+ /* If TCP_MD5SIG is enabled, do not do MPTCP - there is no Option-Space */ -+ if (tcp_sk(sk)->af_specific->md5_lookup(sk, sk)) -+ return false; -+#endif -+ -+ if (dst->dev && (dst->dev->flags & IFF_NOMULTIPATH)) -+ return false; -+ -+ return true; -+} -+ -+int mptcp_create_master_sk(struct sock *meta_sk, __u64 remote_key, -+ int rem_key_set, __u8 mptcp_ver, u32 window) -+{ -+ struct tcp_sock *master_tp; -+ struct sock *master_sk; -+ -+ if (mptcp_alloc_mpcb(meta_sk, remote_key, rem_key_set, mptcp_ver, window)) -+ goto err_alloc_mpcb; -+ -+ master_sk = tcp_sk(meta_sk)->mpcb->master_sk; -+ master_tp = tcp_sk(master_sk); -+ -+ if (mptcp_add_sock(meta_sk, master_sk, 0, 0, GFP_ATOMIC)) -+ goto err_add_sock; -+ -+ if (__inet_inherit_port(meta_sk, master_sk) < 0) -+ goto err_add_sock; -+ -+ meta_sk->sk_prot->unhash(meta_sk); -+ inet_ehash_nolisten(master_sk, NULL); -+ -+ master_tp->mptcp->init_rcv_wnd = master_tp->rcv_wnd; -+ -+ return 0; -+ -+err_add_sock: -+ inet_csk_prepare_forced_close(master_sk); -+ tcp_done(master_sk); -+ -+err_alloc_mpcb: -+ return -ENOBUFS; -+} -+ -+static int __mptcp_check_req_master(struct sock *child, -+ const struct mptcp_options_received *mopt, -+ struct request_sock *req) -+{ -+ struct tcp_sock *child_tp = tcp_sk(child); -+ struct sock *meta_sk = child; -+ struct mptcp_cb *mpcb; -+ struct mptcp_request_sock *mtreq; -+ -+ /* Never contained an MP_CAPABLE */ -+ if (!inet_rsk(req)->mptcp_rqsk) -+ return 1; -+ -+ mtreq = mptcp_rsk(req); -+ -+ if (!inet_rsk(req)->saw_mpc) { -+ /* Fallback to regular TCP, because we saw one SYN without -+ * MP_CAPABLE. In tcp_check_req we continue the regular path. -+ * But, the socket has been added to the reqsk_tk_htb, so we -+ * must still remove it. -+ */ -+ MPTCP_INC_STATS(sock_net(meta_sk), MPTCP_MIB_MPCAPABLEPASSIVEFALLBACK); -+ mptcp_reqsk_remove_tk(req); -+ return 1; -+ } -+ -+ /* mopt can be NULL when coming from FAST-OPEN */ -+ if (mopt && mopt->saw_mpc && mtreq->mptcp_ver == MPTCP_VERSION_1) { -+ mtreq->mptcp_rem_key = mopt->mptcp_sender_key; -+ mtreq->rem_key_set = 1; -+ } -+ -+ MPTCP_INC_STATS(sock_net(meta_sk), MPTCP_MIB_MPCAPABLEPASSIVEACK); -+ -+ /* Just set this values to pass them to mptcp_alloc_mpcb */ -+ child_tp->mptcp_loc_key = mtreq->mptcp_loc_key; -+ child_tp->mptcp_loc_token = mtreq->mptcp_loc_token; -+ -+ if (mptcp_create_master_sk(meta_sk, mtreq->mptcp_rem_key, -+ mtreq->rem_key_set, mtreq->mptcp_ver, -+ child_tp->snd_wnd)) { -+ inet_csk_prepare_forced_close(meta_sk); -+ tcp_done(meta_sk); -+ -+ return -ENOBUFS; -+ } -+ -+ child = tcp_sk(child)->mpcb->master_sk; -+ child_tp = tcp_sk(child); -+ mpcb = child_tp->mpcb; -+ -+ child_tp->mptcp->snt_isn = tcp_rsk(req)->snt_isn; -+ child_tp->mptcp->rcv_isn = tcp_rsk(req)->rcv_isn; -+ -+ mpcb->dss_csum = mtreq->dss_csum; -+ mpcb->server_side = 1; -+ -+ /* Needs to be done here additionally, because when accepting a -+ * new connection we pass by __reqsk_free and not reqsk_free. -+ */ -+ mptcp_reqsk_remove_tk(req); -+ -+ /* Hold when creating the meta-sk in tcp_vX_syn_recv_sock. */ -+ sock_put(meta_sk); -+ -+ return 0; -+} -+ -+int mptcp_check_req_fastopen(struct sock *child, struct request_sock *req) -+{ -+ struct sock *meta_sk = child, *master_sk; -+ struct sk_buff *skb; -+ u32 new_mapping; -+ int ret; -+ -+ ret = __mptcp_check_req_master(child, NULL, req); -+ if (ret) -+ return ret; -+ -+ master_sk = tcp_sk(meta_sk)->mpcb->master_sk; -+ -+ /* We need to rewind copied_seq as it is set to IDSN + 1 and as we have -+ * pre-MPTCP data in the receive queue. -+ */ -+ tcp_sk(meta_sk)->copied_seq -= tcp_sk(master_sk)->rcv_nxt - -+ tcp_rsk(req)->rcv_isn - 1; -+ -+ /* Map subflow sequence number to data sequence numbers. We need to map -+ * these data to [IDSN - len - 1, IDSN[. -+ */ -+ new_mapping = tcp_sk(meta_sk)->copied_seq - tcp_rsk(req)->rcv_isn - 1; -+ -+ /* There should be only one skb: the SYN + data. */ -+ skb_queue_walk(&meta_sk->sk_receive_queue, skb) { -+ TCP_SKB_CB(skb)->seq += new_mapping; -+ TCP_SKB_CB(skb)->end_seq += new_mapping; -+ } -+ -+ /* With fastopen we change the semantics of the relative subflow -+ * sequence numbers to deal with middleboxes that could add/remove -+ * multiple bytes in the SYN. We chose to start counting at rcv_nxt - 1 -+ * instead of the regular TCP ISN. -+ */ -+ tcp_sk(master_sk)->mptcp->rcv_isn = tcp_sk(master_sk)->rcv_nxt - 1; -+ -+ /* We need to update copied_seq of the master_sk to account for the -+ * already moved data to the meta receive queue. -+ */ -+ tcp_sk(master_sk)->copied_seq = tcp_sk(master_sk)->rcv_nxt; -+ -+ /* Handled by the master_sk */ -+ tcp_sk(meta_sk)->fastopen_rsk = NULL; -+ -+ return 0; -+} -+ -+int mptcp_check_req_master(struct sock *sk, struct sock *child, -+ struct request_sock *req, const struct sk_buff *skb, -+ const struct mptcp_options_received *mopt, -+ int drop, u32 tsoff) -+{ -+ struct sock *meta_sk = child; -+ int ret; -+ -+ ret = __mptcp_check_req_master(child, mopt, req); -+ if (ret) -+ return ret; -+ child = tcp_sk(child)->mpcb->master_sk; -+ -+ sock_rps_save_rxhash(child, skb); -+ -+ /* drop indicates that we come from tcp_check_req and thus need to -+ * handle the request-socket fully. -+ */ -+ if (drop) { -+ tcp_synack_rtt_meas(child, req); -+ -+ inet_csk_reqsk_queue_drop(sk, req); -+ reqsk_queue_removed(&inet_csk(sk)->icsk_accept_queue, req); -+ if (!inet_csk_reqsk_queue_add(sk, req, meta_sk)) { -+ bh_unlock_sock(meta_sk); -+ /* No sock_put() of the meta needed. The reference has -+ * already been dropped in __mptcp_check_req_master(). -+ */ -+ sock_put(child); -+ return -1; -+ } -+ } else { -+ /* Thus, we come from syn-cookies */ -+ refcount_set(&req->rsk_refcnt, 1); -+ tcp_sk(meta_sk)->tsoffset = tsoff; -+ if (!inet_csk_reqsk_queue_add(sk, req, meta_sk)) { -+ bh_unlock_sock(meta_sk); -+ /* No sock_put() of the meta needed. The reference has -+ * already been dropped in __mptcp_check_req_master(). -+ */ -+ sock_put(child); -+ reqsk_put(req); -+ return -1; -+ } -+ } -+ -+ return 0; -+} -+ -+/* May be called without holding the meta-level lock */ -+struct sock *mptcp_check_req_child(struct sock *meta_sk, -+ struct sock *child, -+ struct request_sock *req, -+ struct sk_buff *skb, -+ const struct mptcp_options_received *mopt) -+{ -+ const struct mptcp_cb *mpcb = tcp_sk(meta_sk)->mpcb; -+ struct mptcp_request_sock *mtreq = mptcp_rsk(req); -+ struct tcp_sock *child_tp = tcp_sk(child); -+ u8 hash_mac_check[SHA256_DIGEST_SIZE]; -+ -+ if (!mopt->join_ack) { -+ MPTCP_INC_STATS(sock_net(meta_sk), MPTCP_MIB_JOINACKFAIL); -+ goto teardown; -+ } -+ -+ mptcp_hmac(mpcb->mptcp_ver, (u8 *)&mpcb->mptcp_rem_key, -+ (u8 *)&mpcb->mptcp_loc_key, hash_mac_check, 2, -+ 4, (u8 *)&mtreq->mptcp_rem_nonce, -+ 4, (u8 *)&mtreq->mptcp_loc_nonce); -+ -+ if (memcmp(hash_mac_check, (char *)&mopt->mptcp_recv_mac, 20)) { -+ MPTCP_INC_STATS(sock_net(meta_sk), MPTCP_MIB_JOINACKMAC); -+ goto teardown; -+ } -+ -+ /* Point it to the same struct socket and wq as the meta_sk */ -+ sk_set_socket(child, meta_sk->sk_socket); -+ child->sk_wq = meta_sk->sk_wq; -+ -+ if (mptcp_add_sock(meta_sk, child, mtreq->loc_id, mtreq->rem_id, GFP_ATOMIC)) { -+ /* Has been inherited, but now child_tp->mptcp is NULL */ -+ child_tp->mpc = 0; -+ child_tp->ops = &tcp_specific; -+ -+ /* TODO when we support acking the third ack for new subflows, -+ * we should silently discard this third ack, by returning NULL. -+ * -+ * Maybe, at the retransmission we will have enough memory to -+ * fully add the socket to the meta-sk. -+ */ -+ goto teardown; -+ } -+ -+ /* The child is a clone of the meta socket, we must now reset -+ * some of the fields -+ */ -+ child_tp->mptcp->rcv_low_prio = mtreq->rcv_low_prio; -+ -+ /* We should allow proper increase of the snd/rcv-buffers. Thus, we -+ * use the original values instead of the bloated up ones from the -+ * clone. -+ */ -+ child->sk_sndbuf = mpcb->orig_sk_sndbuf; -+ child->sk_rcvbuf = mpcb->orig_sk_rcvbuf; -+ -+ child_tp->mptcp->slave_sk = 1; -+ child_tp->mptcp->snt_isn = tcp_rsk(req)->snt_isn; -+ child_tp->mptcp->rcv_isn = tcp_rsk(req)->rcv_isn; -+ child_tp->mptcp->init_rcv_wnd = req->rsk_rcv_wnd; -+ -+ child->sk_tsq_flags = 0; -+ -+ child_tp->packets_out = 0; -+ -+ tcp_reset_vars(child); -+ -+ sock_rps_save_rxhash(child, skb); -+ tcp_synack_rtt_meas(child, req); -+ -+ if (mpcb->pm_ops->established_subflow) -+ mpcb->pm_ops->established_subflow(child); -+ -+ /* Subflows do not use the accept queue, as they -+ * are attached immediately to the mpcb. -+ */ -+ inet_csk_reqsk_queue_drop(meta_sk, req); -+ reqsk_queue_removed(&inet_csk(meta_sk)->icsk_accept_queue, req); -+ -+ /* The refcnt is initialized to 2, because regular TCP will put him -+ * in the socket's listener queue. However, we do not have a listener-queue. -+ * So, we need to make sure that this request-sock indeed gets destroyed. -+ */ -+ reqsk_put(req); -+ -+ MPTCP_INC_STATS(sock_net(meta_sk), MPTCP_MIB_JOINACKRX); -+ -+ if (inet_sk(child)->inet_sport != inet_sk(meta_sk)->inet_sport) -+ MPTCP_INC_STATS(sock_net(meta_sk), MPTCP_MIB_JOINALTERNATEPORT); -+ -+ return child; -+ -+teardown: -+ req->rsk_ops->send_reset(meta_sk, skb); -+ -+ /* Drop this request - sock creation failed. */ -+ inet_csk_reqsk_queue_drop(meta_sk, req); -+ reqsk_queue_removed(&inet_csk(meta_sk)->icsk_accept_queue, req); -+ inet_csk_prepare_forced_close(child); -+ tcp_done(child); -+ bh_unlock_sock(meta_sk); -+ return meta_sk; -+} -+ -+int mptcp_init_tw_sock(struct sock *sk, struct tcp_timewait_sock *tw) -+{ -+ struct mptcp_tw *mptw; -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct mptcp_cb *mpcb = tp->mpcb; -+ -+ /* A subsocket in tw can only receive data. So, if we are in -+ * infinite-receive, then we should not reply with a data-ack or act -+ * upon general MPTCP-signaling. We prevent this by simply not creating -+ * the mptcp_tw_sock. -+ */ -+ if (mpcb->infinite_mapping_rcv) { -+ tw->mptcp_tw = NULL; -+ return 0; -+ } -+ -+ /* Alloc MPTCP-tw-sock */ -+ mptw = kmem_cache_alloc(mptcp_tw_cache, GFP_ATOMIC); -+ if (!mptw) { -+ tw->mptcp_tw = NULL; -+ return -ENOBUFS; -+ } -+ -+ refcount_inc(&mpcb->mpcb_refcnt); -+ -+ tw->mptcp_tw = mptw; -+ mptw->loc_key = mpcb->mptcp_loc_key; -+ mptw->meta_tw = mpcb->in_time_wait; -+ mptw->rcv_nxt = mptcp_get_rcv_nxt_64(mptcp_meta_tp(tp)); -+ if (mptw->meta_tw && mpcb->mptw_state != TCP_TIME_WAIT) -+ mptw->rcv_nxt++; -+ rcu_assign_pointer(mptw->mpcb, mpcb); -+ -+ spin_lock_bh(&mpcb->mpcb_list_lock); -+ list_add_rcu(&mptw->list, &tp->mpcb->tw_list); -+ mptw->in_list = 1; -+ spin_unlock_bh(&mpcb->mpcb_list_lock); -+ -+ return 0; -+} -+ -+void mptcp_twsk_destructor(struct tcp_timewait_sock *tw) -+{ -+ struct mptcp_cb *mpcb; -+ -+ rcu_read_lock(); -+ local_bh_disable(); -+ mpcb = rcu_dereference(tw->mptcp_tw->mpcb); -+ -+ /* If we are still holding a ref to the mpcb, we have to remove ourself -+ * from the list and drop the ref properly. -+ */ -+ if (mpcb && refcount_inc_not_zero(&mpcb->mpcb_refcnt)) { -+ spin_lock(&mpcb->mpcb_list_lock); -+ if (tw->mptcp_tw->in_list) { -+ list_del_rcu(&tw->mptcp_tw->list); -+ tw->mptcp_tw->in_list = 0; -+ /* Put, because we added it to the list */ -+ mptcp_mpcb_put(mpcb); -+ } -+ spin_unlock(&mpcb->mpcb_list_lock); -+ -+ /* Second time, because we increased it above */ -+ mptcp_mpcb_put(mpcb); -+ } -+ -+ local_bh_enable(); -+ rcu_read_unlock(); -+ -+ kmem_cache_free(mptcp_tw_cache, tw->mptcp_tw); -+} -+ -+/* Updates the rcv_nxt of the time-wait-socks and allows them to ack a -+ * data-fin. -+ */ -+void mptcp_time_wait(struct sock *meta_sk, int state, int timeo) -+{ -+ struct tcp_sock *meta_tp = tcp_sk(meta_sk); -+ struct mptcp_tw *mptw; -+ -+ if (mptcp_in_infinite_mapping_weak(meta_tp->mpcb)) { -+ struct mptcp_tcp_sock *mptcp; -+ struct hlist_node *tmp; -+ -+ mptcp_for_each_sub_safe(meta_tp->mpcb, mptcp, tmp) { -+ struct sock *sk_it = mptcp_to_sock(mptcp); -+ -+ if (sk_it->sk_state == TCP_CLOSE) -+ continue; -+ -+ tcp_sk(sk_it)->ops->time_wait(sk_it, state, timeo); -+ } -+ } -+ -+ /* Used for sockets that go into tw after the meta -+ * (see mptcp_init_tw_sock()) -+ */ -+ meta_tp->mpcb->in_time_wait = 1; -+ meta_tp->mpcb->mptw_state = state; -+ -+ /* Update the time-wait-sock's information */ -+ rcu_read_lock(); -+ local_bh_disable(); -+ list_for_each_entry_rcu(mptw, &meta_tp->mpcb->tw_list, list) { -+ mptw->meta_tw = 1; -+ mptw->rcv_nxt = mptcp_get_rcv_nxt_64(meta_tp); -+ -+ /* We want to ack a DATA_FIN, but are yet in FIN_WAIT_2 - -+ * pretend as if the DATA_FIN has already reached us, that way -+ * the checks in tcp_timewait_state_process will be good as the -+ * DATA_FIN comes in. -+ */ -+ if (state != TCP_TIME_WAIT) -+ mptw->rcv_nxt++; -+ } -+ local_bh_enable(); -+ rcu_read_unlock(); -+ -+ if (meta_sk->sk_state != TCP_CLOSE) -+ tcp_done(meta_sk); -+} -+ -+void mptcp_tsq_flags(struct sock *sk) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct sock *meta_sk = mptcp_meta_sk(sk); -+ -+ /* It will be handled as a regular deferred-call */ -+ if (is_meta_sk(sk)) -+ return; -+ -+ if (hlist_unhashed(&tp->mptcp->cb_list)) { -+ hlist_add_head(&tp->mptcp->cb_list, &tp->mpcb->callback_list); -+ /* We need to hold it here, as the sock_hold is not assured -+ * by the release_sock as it is done in regular TCP. -+ * -+ * The subsocket may get inet_csk_destroy'd while it is inside -+ * the callback_list. -+ */ -+ sock_hold(sk); -+ } -+ -+ if (!test_and_set_bit(MPTCP_SUB_DEFERRED, &meta_sk->sk_tsq_flags)) -+ sock_hold(meta_sk); -+} -+ -+void mptcp_tsq_sub_deferred(struct sock *meta_sk) -+{ -+ struct tcp_sock *meta_tp = tcp_sk(meta_sk); -+ struct mptcp_tcp_sock *mptcp; -+ struct hlist_node *tmp; -+ -+ __sock_put(meta_sk); -+ hlist_for_each_entry_safe(mptcp, tmp, &meta_tp->mpcb->callback_list, cb_list) { -+ struct tcp_sock *tp = mptcp->tp; -+ struct sock *sk = (struct sock *)tp; -+ -+ hlist_del_init(&mptcp->cb_list); -+ sk->sk_prot->release_cb(sk); -+ /* Final sock_put (cfr. mptcp_tsq_flags) */ -+ sock_put(sk); -+ } -+} -+ -+/* May be called without holding the meta-level lock */ -+void mptcp_join_reqsk_init(const struct mptcp_cb *mpcb, -+ const struct request_sock *req, -+ struct sk_buff *skb) -+{ -+ struct mptcp_request_sock *mtreq = mptcp_rsk(req); -+ u8 mptcp_hash_mac[SHA256_DIGEST_SIZE]; -+ struct mptcp_options_received mopt; -+ -+ mptcp_init_mp_opt(&mopt); -+ tcp_parse_mptcp_options(skb, &mopt); -+ -+ mtreq->is_sub = 1; -+ inet_rsk(req)->mptcp_rqsk = 1; -+ -+ mtreq->mptcp_rem_nonce = mopt.mptcp_recv_nonce; -+ -+ mptcp_hmac(mpcb->mptcp_ver, (u8 *)&mpcb->mptcp_loc_key, -+ (u8 *)&mpcb->mptcp_rem_key, mptcp_hash_mac, 2, -+ 4, (u8 *)&mtreq->mptcp_loc_nonce, -+ 4, (u8 *)&mtreq->mptcp_rem_nonce); -+ mtreq->mptcp_hash_tmac = *(u64 *)mptcp_hash_mac; -+ -+ mtreq->rem_id = mopt.rem_id; -+ mtreq->rcv_low_prio = mopt.low_prio; -+ inet_rsk(req)->saw_mpc = 1; -+ -+ MPTCP_INC_STATS(sock_net(mpcb->meta_sk), MPTCP_MIB_JOINSYNRX); -+} -+ -+void mptcp_reqsk_init(struct request_sock *req, const struct sock *sk, -+ const struct sk_buff *skb, bool want_cookie) -+{ -+ struct mptcp_options_received mopt; -+ struct mptcp_request_sock *mtreq = mptcp_rsk(req); -+ -+ mptcp_init_mp_opt(&mopt); -+ tcp_parse_mptcp_options(skb, &mopt); -+ -+ mtreq->dss_csum = mopt.dss_csum; -+ -+ if (want_cookie) { -+ if (!mptcp_reqsk_new_cookie(req, sk, &mopt, skb)) -+ /* No key available - back to regular TCP */ -+ inet_rsk(req)->mptcp_rqsk = 0; -+ return; -+ } -+ -+ mptcp_reqsk_new_mptcp(req, sk, &mopt, skb); -+} -+ -+void mptcp_cookies_reqsk_init(struct request_sock *req, -+ struct mptcp_options_received *mopt, -+ struct sk_buff *skb) -+{ -+ struct mptcp_request_sock *mtreq = mptcp_rsk(req); -+ -+ /* Absolutely need to always initialize this. */ -+ mtreq->hash_entry.pprev = NULL; -+ -+ mtreq->mptcp_ver = mopt->mptcp_ver; -+ mtreq->mptcp_rem_key = mopt->mptcp_sender_key; -+ mtreq->mptcp_loc_key = mopt->mptcp_receiver_key; -+ mtreq->rem_key_set = 1; -+ -+ /* Generate the token */ -+ mptcp_key_hash(mtreq->mptcp_ver, mtreq->mptcp_loc_key, &mtreq->mptcp_loc_token, NULL); -+ -+ rcu_read_lock(); -+ local_bh_disable(); -+ spin_lock(&mptcp_tk_hashlock); -+ -+ /* Check, if the key is still free */ -+ if (mptcp_reqsk_find_tk(mtreq->mptcp_loc_token) || -+ mptcp_find_token(mtreq->mptcp_loc_token)) -+ goto out; -+ -+ inet_rsk(req)->saw_mpc = 1; -+ mtreq->is_sub = 0; -+ inet_rsk(req)->mptcp_rqsk = 1; -+ mtreq->dss_csum = mopt->dss_csum; -+ -+out: -+ spin_unlock(&mptcp_tk_hashlock); -+ local_bh_enable(); -+ rcu_read_unlock(); -+} -+ -+int mptcp_conn_request(struct sock *sk, struct sk_buff *skb) -+{ -+ struct mptcp_options_received mopt; -+ -+ mptcp_init_mp_opt(&mopt); -+ tcp_parse_mptcp_options(skb, &mopt); -+ -+ if (mopt.is_mp_join) -+ return mptcp_do_join_short(skb, &mopt, sock_net(sk)); -+ if (mopt.drop_me) -+ goto drop; -+ -+ if (!sock_flag(sk, SOCK_MPTCP)) -+ mopt.saw_mpc = 0; -+ -+ if (skb->protocol == htons(ETH_P_IP)) { -+ if (mopt.saw_mpc) { -+ if (skb_rtable(skb)->rt_flags & -+ (RTCF_BROADCAST | RTCF_MULTICAST)) -+ goto drop; -+ -+ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_MPCAPABLEPASSIVE); -+ return tcp_conn_request(&mptcp_request_sock_ops, -+ &mptcp_request_sock_ipv4_ops, -+ sk, skb); -+ } -+ -+ return tcp_v4_conn_request(sk, skb); -+#if IS_ENABLED(CONFIG_IPV6) -+ } else { -+ if (mopt.saw_mpc) { -+ if (!ipv6_unicast_destination(skb)) -+ goto drop; -+ -+ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_MPCAPABLEPASSIVE); -+ return tcp_conn_request(&mptcp6_request_sock_ops, -+ &mptcp_request_sock_ipv6_ops, -+ sk, skb); -+ } -+ -+ return tcp_v6_conn_request(sk, skb); -+#endif -+ } -+drop: -+ __NET_INC_STATS(sock_net(sk), LINUX_MIB_LISTENDROPS); -+ return 0; -+} -+ -+int mptcp_finish_handshake(struct sock *child, struct sk_buff *skb) -+ __releases(&child->sk_lock.slock) -+{ -+ int ret; -+ -+ /* We don't call tcp_child_process here, because we hold -+ * already the meta-sk-lock and are sure that it is not owned -+ * by the user. -+ */ -+ tcp_sk(child)->segs_in += max_t(u16, 1, skb_shinfo(skb)->gso_segs); -+ ret = tcp_rcv_state_process(child, skb); -+ bh_unlock_sock(child); -+ sock_put(child); -+ -+ return ret; -+} -+ -+static void __mptcp_get_info(const struct sock *meta_sk, -+ struct mptcp_meta_info *info) -+{ -+ const struct inet_connection_sock *meta_icsk = inet_csk(meta_sk); -+ const struct tcp_sock *meta_tp = tcp_sk(meta_sk); -+ u32 now = tcp_jiffies32; -+ -+ memset(info, 0, sizeof(*info)); -+ -+ info->mptcpi_state = meta_sk->sk_state; -+ info->mptcpi_retransmits = meta_icsk->icsk_retransmits; -+ info->mptcpi_probes = meta_icsk->icsk_probes_out; -+ info->mptcpi_backoff = meta_icsk->icsk_backoff; -+ -+ info->mptcpi_rto = jiffies_to_usecs(meta_icsk->icsk_rto); -+ -+ info->mptcpi_unacked = meta_tp->packets_out; -+ -+ info->mptcpi_last_data_sent = jiffies_to_msecs(now - meta_tp->lsndtime); -+ info->mptcpi_last_data_recv = jiffies_to_msecs(now - meta_icsk->icsk_ack.lrcvtime); -+ info->mptcpi_last_ack_recv = jiffies_to_msecs(now - meta_tp->rcv_tstamp); -+ -+ info->mptcpi_total_retrans = meta_tp->total_retrans; -+ -+ info->mptcpi_bytes_acked = meta_tp->bytes_acked; -+ info->mptcpi_bytes_received = meta_tp->bytes_received; -+} -+ -+static void mptcp_get_sub_info(struct sock *sk, struct mptcp_sub_info *info) -+{ -+ struct inet_sock *inet = inet_sk(sk); -+ -+ memset(info, 0, sizeof(*info)); -+ -+ if (sk->sk_family == AF_INET) { -+ info->src_v4.sin_family = AF_INET; -+ info->src_v4.sin_port = inet->inet_sport; -+ -+ info->src_v4.sin_addr.s_addr = inet->inet_rcv_saddr; -+ if (!info->src_v4.sin_addr.s_addr) -+ info->src_v4.sin_addr.s_addr = inet->inet_saddr; -+ -+ info->dst_v4.sin_family = AF_INET; -+ info->dst_v4.sin_port = inet->inet_dport; -+ info->dst_v4.sin_addr.s_addr = inet->inet_daddr; -+#if IS_ENABLED(CONFIG_IPV6) -+ } else { -+ struct ipv6_pinfo *np = inet6_sk(sk); -+ -+ info->src_v6.sin6_family = AF_INET6; -+ info->src_v6.sin6_port = inet->inet_sport; -+ -+ if (ipv6_addr_any(&sk->sk_v6_rcv_saddr)) -+ info->src_v6.sin6_addr = np->saddr; -+ else -+ info->src_v6.sin6_addr = sk->sk_v6_rcv_saddr; -+ -+ info->dst_v6.sin6_family = AF_INET6; -+ info->dst_v6.sin6_port = inet->inet_dport; -+ info->dst_v6.sin6_addr = sk->sk_v6_daddr; -+#endif -+ } -+} -+ -+int mptcp_get_info(const struct sock *meta_sk, char __user *optval, int optlen) -+{ -+ const struct tcp_sock *meta_tp = tcp_sk(meta_sk); -+ -+ struct mptcp_meta_info meta_info; -+ struct mptcp_info m_info; -+ -+ unsigned int info_len; -+ -+ /* Check again with the lock held */ -+ if (!mptcp(meta_tp)) -+ return -EINVAL; -+ -+ if (copy_from_user(&m_info, optval, optlen)) -+ return -EFAULT; -+ -+ if (m_info.meta_info) { -+ unsigned int len; -+ -+ __mptcp_get_info(meta_sk, &meta_info); -+ -+ /* Need to set this, if user thinks that tcp_info is bigger than ours */ -+ len = min_t(unsigned int, m_info.meta_len, sizeof(meta_info)); -+ m_info.meta_len = len; -+ -+ if (copy_to_user((void __user *)m_info.meta_info, &meta_info, len)) -+ return -EFAULT; -+ } -+ -+ /* Need to set this, if user thinks that tcp_info is bigger than ours */ -+ info_len = min_t(unsigned int, m_info.tcp_info_len, sizeof(struct tcp_info)); -+ m_info.tcp_info_len = info_len; -+ -+ if (m_info.initial) { -+ struct mptcp_cb *mpcb = meta_tp->mpcb; -+ -+ if (mpcb->master_sk) { -+ struct tcp_info info; -+ -+ tcp_get_info(mpcb->master_sk, &info, true); -+ if (copy_to_user((void __user *)m_info.initial, &info, info_len)) -+ return -EFAULT; -+ } else if (meta_tp->record_master_info && mpcb->master_info) { -+ if (copy_to_user((void __user *)m_info.initial, mpcb->master_info, info_len)) -+ return -EFAULT; -+ } else { -+ return meta_tp->record_master_info ? -ENOMEM : -EINVAL; -+ } -+ } -+ -+ if (m_info.subflows) { -+ unsigned int len, sub_len = 0; -+ struct mptcp_tcp_sock *mptcp; -+ char __user *ptr; -+ -+ ptr = (char __user *)m_info.subflows; -+ len = m_info.sub_len; -+ -+ mptcp_for_each_sub(meta_tp->mpcb, mptcp) { -+ struct tcp_info t_info; -+ unsigned int tmp_len; -+ -+ tcp_get_info(mptcp_to_sock(mptcp), &t_info, true); -+ -+ tmp_len = min_t(unsigned int, len, info_len); -+ len -= tmp_len; -+ -+ if (copy_to_user(ptr, &t_info, tmp_len)) -+ return -EFAULT; -+ -+ ptr += tmp_len; -+ sub_len += tmp_len; -+ -+ if (len == 0) -+ break; -+ } -+ -+ m_info.sub_len = sub_len; -+ } -+ -+ if (m_info.subflow_info) { -+ unsigned int len, sub_info_len, total_sub_info_len = 0; -+ struct mptcp_tcp_sock *mptcp; -+ char __user *ptr; -+ -+ ptr = (char __user *)m_info.subflow_info; -+ len = m_info.total_sub_info_len; -+ -+ sub_info_len = min_t(unsigned int, m_info.sub_info_len, -+ sizeof(struct mptcp_sub_info)); -+ m_info.sub_info_len = sub_info_len; -+ -+ mptcp_for_each_sub(meta_tp->mpcb, mptcp) { -+ struct mptcp_sub_info m_sub_info; -+ unsigned int tmp_len; -+ -+ mptcp_get_sub_info(mptcp_to_sock(mptcp), &m_sub_info); -+ -+ tmp_len = min_t(unsigned int, len, sub_info_len); -+ len -= tmp_len; -+ -+ if (copy_to_user(ptr, &m_sub_info, tmp_len)) -+ return -EFAULT; -+ -+ ptr += tmp_len; -+ total_sub_info_len += tmp_len; -+ -+ if (len == 0) -+ break; -+ } -+ -+ m_info.total_sub_info_len = total_sub_info_len; -+ } -+ -+ if (copy_to_user(optval, &m_info, optlen)) -+ return -EFAULT; -+ -+ return 0; -+} -+ -+void mptcp_clear_sk(struct sock *sk, int size) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ -+ /* we do not want to clear tk_table field, because of RCU lookups */ -+ sk_prot_clear_nulls(sk, offsetof(struct tcp_sock, tk_table.next)); -+ -+ size -= offsetof(struct tcp_sock, tk_table.pprev); -+ memset((char *)&tp->tk_table.pprev, 0, size); -+} -+ -+static const struct snmp_mib mptcp_snmp_list[] = { -+ SNMP_MIB_ITEM("MPCapableSYNRX", MPTCP_MIB_MPCAPABLEPASSIVE), -+ SNMP_MIB_ITEM("MPCapableSYNTX", MPTCP_MIB_MPCAPABLEACTIVE), -+ SNMP_MIB_ITEM("MPCapableSYNACKRX", MPTCP_MIB_MPCAPABLEACTIVEACK), -+ SNMP_MIB_ITEM("MPCapableACKRX", MPTCP_MIB_MPCAPABLEPASSIVEACK), -+ SNMP_MIB_ITEM("MPCapableFallbackACK", MPTCP_MIB_MPCAPABLEPASSIVEFALLBACK), -+ SNMP_MIB_ITEM("MPCapableFallbackSYNACK", MPTCP_MIB_MPCAPABLEACTIVEFALLBACK), -+ SNMP_MIB_ITEM("MPCapableRetransFallback", MPTCP_MIB_MPCAPABLERETRANSFALLBACK), -+ SNMP_MIB_ITEM("MPTCPCsumEnabled", MPTCP_MIB_CSUMENABLED), -+ SNMP_MIB_ITEM("MPTCPRetrans", MPTCP_MIB_RETRANSSEGS), -+ SNMP_MIB_ITEM("MPFailRX", MPTCP_MIB_MPFAILRX), -+ SNMP_MIB_ITEM("MPCsumFail", MPTCP_MIB_CSUMFAIL), -+ SNMP_MIB_ITEM("MPFastcloseRX", MPTCP_MIB_FASTCLOSERX), -+ SNMP_MIB_ITEM("MPFastcloseTX", MPTCP_MIB_FASTCLOSETX), -+ SNMP_MIB_ITEM("MPFallbackAckSub", MPTCP_MIB_FBACKSUB), -+ SNMP_MIB_ITEM("MPFallbackAckInit", MPTCP_MIB_FBACKINIT), -+ SNMP_MIB_ITEM("MPFallbackDataSub", MPTCP_MIB_FBDATASUB), -+ SNMP_MIB_ITEM("MPFallbackDataInit", MPTCP_MIB_FBDATAINIT), -+ SNMP_MIB_ITEM("MPRemoveAddrSubDelete", MPTCP_MIB_REMADDRSUB), -+ SNMP_MIB_ITEM("MPJoinNoTokenFound", MPTCP_MIB_JOINNOTOKEN), -+ SNMP_MIB_ITEM("MPJoinAlreadyFallenback", MPTCP_MIB_JOINFALLBACK), -+ SNMP_MIB_ITEM("MPJoinSynTx", MPTCP_MIB_JOINSYNTX), -+ SNMP_MIB_ITEM("MPJoinSynRx", MPTCP_MIB_JOINSYNRX), -+ SNMP_MIB_ITEM("MPJoinSynAckRx", MPTCP_MIB_JOINSYNACKRX), -+ SNMP_MIB_ITEM("MPJoinSynAckHMacFailure", MPTCP_MIB_JOINSYNACKMAC), -+ SNMP_MIB_ITEM("MPJoinAckRx", MPTCP_MIB_JOINACKRX), -+ SNMP_MIB_ITEM("MPJoinAckHMacFailure", MPTCP_MIB_JOINACKMAC), -+ SNMP_MIB_ITEM("MPJoinAckMissing", MPTCP_MIB_JOINACKFAIL), -+ SNMP_MIB_ITEM("MPJoinAckRTO", MPTCP_MIB_JOINACKRTO), -+ SNMP_MIB_ITEM("MPJoinAckRexmit", MPTCP_MIB_JOINACKRXMIT), -+ SNMP_MIB_ITEM("NoDSSInWindow", MPTCP_MIB_NODSSWINDOW), -+ SNMP_MIB_ITEM("DSSNotMatching", MPTCP_MIB_DSSNOMATCH), -+ SNMP_MIB_ITEM("InfiniteMapRx", MPTCP_MIB_INFINITEMAPRX), -+ SNMP_MIB_ITEM("DSSNoMatchTCP", MPTCP_MIB_DSSTCPMISMATCH), -+ SNMP_MIB_ITEM("DSSTrimHead", MPTCP_MIB_DSSTRIMHEAD), -+ SNMP_MIB_ITEM("DSSSplitTail", MPTCP_MIB_DSSSPLITTAIL), -+ SNMP_MIB_ITEM("DSSPurgeOldSubSegs", MPTCP_MIB_PURGEOLD), -+ SNMP_MIB_ITEM("AddAddrRx", MPTCP_MIB_ADDADDRRX), -+ SNMP_MIB_ITEM("AddAddrTx", MPTCP_MIB_ADDADDRTX), -+ SNMP_MIB_ITEM("RemAddrRx", MPTCP_MIB_REMADDRRX), -+ SNMP_MIB_ITEM("RemAddrTx", MPTCP_MIB_REMADDRTX), -+ SNMP_MIB_ITEM("MPJoinAlternatePort", MPTCP_MIB_JOINALTERNATEPORT), -+ SNMP_MIB_ITEM("MPCurrEstab", MPTCP_MIB_CURRESTAB), -+ SNMP_MIB_SENTINEL -+}; -+ -+struct workqueue_struct *mptcp_wq; -+EXPORT_SYMBOL(mptcp_wq); -+ -+/* Output /proc/net/mptcp */ -+static int mptcp_pm_seq_show(struct seq_file *seq, void *v) -+{ -+ struct tcp_sock *meta_tp; -+ const struct net *net = seq->private; -+ unsigned int i, n = 0; -+ -+ seq_printf(seq, " sl loc_tok rem_tok v6 local_address remote_address st ns tx_queue rx_queue inode"); -+ seq_putc(seq, '\n'); -+ -+ for (i = 0; i <= mptcp_tk_htable.mask; i++) { -+ struct hlist_nulls_node *node; -+ rcu_read_lock(); -+ local_bh_disable(); -+ hlist_nulls_for_each_entry_rcu(meta_tp, node, -+ &mptcp_tk_htable.hashtable[i], -+ tk_table) { -+ struct sock *meta_sk = (struct sock *)meta_tp; -+ struct inet_sock *isk = inet_sk(meta_sk); -+ struct mptcp_cb *mpcb = meta_tp->mpcb; -+ -+ if (!mptcp(meta_tp) || !net_eq(net, sock_net(meta_sk))) -+ continue; -+ -+ if (!mpcb) -+ continue; -+ -+ if (capable(CAP_NET_ADMIN)) { -+ seq_printf(seq, "%4d: %04X %04X ", n++, -+ mpcb->mptcp_loc_token, -+ mpcb->mptcp_rem_token); -+ } else { -+ seq_printf(seq, "%4d: %04X %04X ", n++, -1, -1); -+ } -+ if (meta_sk->sk_family == AF_INET || -+ mptcp_v6_is_v4_mapped(meta_sk)) { -+ seq_printf(seq, " 0 %08X:%04X %08X:%04X ", -+ isk->inet_rcv_saddr, -+ ntohs(isk->inet_sport), -+ isk->inet_daddr, -+ ntohs(isk->inet_dport)); -+#if IS_ENABLED(CONFIG_IPV6) -+ } else if (meta_sk->sk_family == AF_INET6) { -+ struct in6_addr *src = &meta_sk->sk_v6_rcv_saddr; -+ struct in6_addr *dst = &meta_sk->sk_v6_daddr; -+ seq_printf(seq, " 1 %08X%08X%08X%08X:%04X %08X%08X%08X%08X:%04X", -+ src->s6_addr32[0], src->s6_addr32[1], -+ src->s6_addr32[2], src->s6_addr32[3], -+ ntohs(isk->inet_sport), -+ dst->s6_addr32[0], dst->s6_addr32[1], -+ dst->s6_addr32[2], dst->s6_addr32[3], -+ ntohs(isk->inet_dport)); -+#endif -+ } -+ -+ seq_printf(seq, " %02X %02X %08X:%08X %lu", -+ meta_sk->sk_state, mptcp_subflow_count(mpcb), -+ meta_tp->write_seq - meta_tp->snd_una, -+ max_t(int, meta_tp->rcv_nxt - -+ meta_tp->copied_seq, 0), -+ sock_i_ino(meta_sk)); -+ seq_putc(seq, '\n'); -+ } -+ -+ local_bh_enable(); -+ rcu_read_unlock(); -+ } -+ -+ return 0; -+} -+ -+static int mptcp_snmp_seq_show(struct seq_file *seq, void *v) -+{ -+ struct net *net = seq->private; -+ int i; -+ -+ for (i = 0; mptcp_snmp_list[i].name != NULL; i++) -+ seq_printf(seq, "%-32s\t%ld\n", mptcp_snmp_list[i].name, -+ snmp_fold_field(net->mptcp.mptcp_statistics, -+ mptcp_snmp_list[i].entry)); -+ -+ return 0; -+} -+ -+static int mptcp_pm_init_net(struct net *net) -+{ -+ net->mptcp.mptcp_statistics = alloc_percpu(struct mptcp_mib); -+ if (!net->mptcp.mptcp_statistics) -+ goto out_mptcp_mibs; -+ -+#ifdef CONFIG_PROC_FS -+ net->mptcp.proc_net_mptcp = proc_net_mkdir(net, "mptcp_net", net->proc_net); -+ if (!net->mptcp.proc_net_mptcp) -+ goto out_proc_net_mptcp; -+ if (!proc_create_net_single("mptcp", S_IRUGO, net->mptcp.proc_net_mptcp, -+ mptcp_pm_seq_show, NULL)) -+ goto out_mptcp_net_mptcp; -+ if (!proc_create_net_single("snmp", S_IRUGO, net->mptcp.proc_net_mptcp, -+ mptcp_snmp_seq_show, NULL)) -+ goto out_mptcp_net_snmp; -+#endif -+ -+ return 0; -+ -+#ifdef CONFIG_PROC_FS -+out_mptcp_net_snmp: -+ remove_proc_entry("mptcp", net->mptcp.proc_net_mptcp); -+out_mptcp_net_mptcp: -+ remove_proc_subtree("mptcp_net", net->proc_net); -+ net->mptcp.proc_net_mptcp = NULL; -+out_proc_net_mptcp: -+ free_percpu(net->mptcp.mptcp_statistics); -+#endif -+out_mptcp_mibs: -+ return -ENOMEM; -+} -+ -+static void mptcp_pm_exit_net(struct net *net) -+{ -+ remove_proc_entry("snmp", net->mptcp.proc_net_mptcp); -+ remove_proc_entry("mptcp", net->mptcp.proc_net_mptcp); -+ remove_proc_subtree("mptcp_net", net->proc_net); -+ free_percpu(net->mptcp.mptcp_statistics); -+} -+ -+static struct pernet_operations mptcp_pm_proc_ops = { -+ .init = mptcp_pm_init_net, -+ .exit = mptcp_pm_exit_net, -+}; -+ -+static unsigned long mptcp_htable_entries __initdata; -+ -+static int __init set_mptcp_htable_entries(char *str) -+{ -+ ssize_t ret; -+ -+ if (!str) -+ return 0; -+ -+ ret = kstrtoul(str, 0, &mptcp_htable_entries); -+ if (ret) -+ return 0; -+ -+ return 1; -+} -+__setup("mptcp_htable_entries=", set_mptcp_htable_entries); -+ -+/* General initialization of mptcp */ -+void __init mptcp_init(void) -+{ -+ unsigned int i; -+ struct ctl_table_header *mptcp_sysctl; -+ -+ mptcp_sock_cache = kmem_cache_create("mptcp_sock", -+ sizeof(struct mptcp_tcp_sock), -+ 0, SLAB_HWCACHE_ALIGN, -+ NULL); -+ if (!mptcp_sock_cache) -+ goto mptcp_sock_cache_failed; -+ -+ mptcp_cb_cache = kmem_cache_create("mptcp_cb", sizeof(struct mptcp_cb), -+ 0, SLAB_TYPESAFE_BY_RCU|SLAB_HWCACHE_ALIGN, -+ NULL); -+ if (!mptcp_cb_cache) -+ goto mptcp_cb_cache_failed; -+ -+ mptcp_tw_cache = kmem_cache_create("mptcp_tw", sizeof(struct mptcp_tw), -+ 0, SLAB_TYPESAFE_BY_RCU|SLAB_HWCACHE_ALIGN, -+ NULL); -+ if (!mptcp_tw_cache) -+ goto mptcp_tw_cache_failed; -+ -+ get_random_bytes(&mptcp_secret, sizeof(mptcp_secret)); -+ -+ mptcp_wq = alloc_workqueue("mptcp_wq", WQ_UNBOUND | WQ_MEM_RECLAIM, 8); -+ if (!mptcp_wq) -+ goto alloc_workqueue_failed; -+ -+ mptcp_tk_htable.hashtable = -+ alloc_large_system_hash("MPTCP tokens", -+ sizeof(mptcp_tk_htable.hashtable[0]), -+ mptcp_htable_entries, -+ 18, /* one slot per 256KB of memory */ -+ 0, -+ NULL, -+ &mptcp_tk_htable.mask, -+ 1024, -+ mptcp_htable_entries ? 0 : 1024 * 1024); -+ -+ for (i = 0; i <= mptcp_tk_htable.mask; i++) -+ INIT_HLIST_NULLS_HEAD(&mptcp_tk_htable.hashtable[i], i); -+ -+ mptcp_reqsk_tk_htb.hashtable = -+ alloc_large_system_hash("MPTCP request tokens", -+ sizeof(mptcp_reqsk_tk_htb.hashtable[0]), -+ mptcp_htable_entries, -+ 18, /* one slot per 256KB of memory */ -+ 0, -+ NULL, -+ &mptcp_reqsk_tk_htb.mask, -+ 1024, -+ mptcp_htable_entries ? 0 : 1024 * 1024); -+ -+ for (i = 0; i <= mptcp_reqsk_tk_htb.mask; i++) -+ INIT_HLIST_NULLS_HEAD(&mptcp_reqsk_tk_htb.hashtable[i], i); -+ -+ -+ spin_lock_init(&mptcp_tk_hashlock); -+ -+ if (register_pernet_subsys(&mptcp_pm_proc_ops)) -+ goto pernet_failed; -+ -+#if IS_ENABLED(CONFIG_IPV6) -+ if (mptcp_pm_v6_init()) -+ goto mptcp_pm_v6_failed; -+#endif -+ if (mptcp_pm_v4_init()) -+ goto mptcp_pm_v4_failed; -+ -+ mptcp_sysctl = register_net_sysctl(&init_net, "net/mptcp", mptcp_table); -+ if (!mptcp_sysctl) -+ goto register_sysctl_failed; -+ -+ if (mptcp_register_path_manager(&mptcp_pm_default)) -+ goto register_pm_failed; -+ -+ if (mptcp_register_scheduler(&mptcp_sched_default)) -+ goto register_sched_failed; -+ -+ pr_info("MPTCP: Unstable branch"); -+ -+ mptcp_init_failed = false; -+ -+ return; -+ -+register_sched_failed: -+ mptcp_unregister_path_manager(&mptcp_pm_default); -+register_pm_failed: -+ unregister_net_sysctl_table(mptcp_sysctl); -+register_sysctl_failed: -+ mptcp_pm_v4_undo(); -+mptcp_pm_v4_failed: -+#if IS_ENABLED(CONFIG_IPV6) -+ mptcp_pm_v6_undo(); -+mptcp_pm_v6_failed: -+#endif -+ unregister_pernet_subsys(&mptcp_pm_proc_ops); -+pernet_failed: -+ destroy_workqueue(mptcp_wq); -+alloc_workqueue_failed: -+ kmem_cache_destroy(mptcp_tw_cache); -+mptcp_tw_cache_failed: -+ kmem_cache_destroy(mptcp_cb_cache); -+mptcp_cb_cache_failed: -+ kmem_cache_destroy(mptcp_sock_cache); -+mptcp_sock_cache_failed: -+ mptcp_init_failed = true; -+} -diff -aurN linux-5.4.64/net/mptcp/mptcp_ecf.c linux-5.4.64.mptcp/net/mptcp/mptcp_ecf.c ---- linux-5.4.64/net/mptcp/mptcp_ecf.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-5.4.64.mptcp/net/mptcp/mptcp_ecf.c 2020-09-10 19:25:10.507220869 +0200 -@@ -0,0 +1,195 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* MPTCP ECF Scheduler -+ * -+ * Algorithm Design: -+ * Yeon-sup Lim -+ * Don Towsley -+ * Erich M. Nahum -+ * Richard J. Gibbens -+ * -+ * Initial Implementation: -+ * Yeon-sup Lim -+ * -+ * Additional Authors: -+ * Daniel Weber -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version -+ * 2 of the License, or (at your option) any later version. -+ */ -+ -+#include -+#include -+ -+static unsigned int mptcp_ecf_r_beta __read_mostly = 4; /* beta = 1/r_beta = 0.25 */ -+module_param(mptcp_ecf_r_beta, int, 0644); -+MODULE_PARM_DESC(mptcp_ecf_r_beta, "beta for ECF"); -+ -+struct ecfsched_priv { -+ u32 last_rbuf_opti; -+}; -+ -+struct ecfsched_cb { -+ u32 switching_margin; /* this is "waiting" in algorithm description */ -+}; -+ -+static struct ecfsched_priv *ecfsched_get_priv(const struct tcp_sock *tp) -+{ -+ return (struct ecfsched_priv *)&tp->mptcp->mptcp_sched[0]; -+} -+ -+static struct ecfsched_cb *ecfsched_get_cb(const struct tcp_sock *tp) -+{ -+ return (struct ecfsched_cb *)&tp->mpcb->mptcp_sched[0]; -+} -+ -+/* This is the ECF scheduler. This function decides on which flow to send -+ * a given MSS. If all subflows are found to be busy or the currently best -+ * subflow is estimated to be slower than waiting for minsk, NULL is returned. -+ */ -+static struct sock *ecf_get_available_subflow(struct sock *meta_sk, -+ struct sk_buff *skb, -+ bool zero_wnd_test) -+{ -+ struct mptcp_cb *mpcb = tcp_sk(meta_sk)->mpcb; -+ struct sock *bestsk, *minsk = NULL; -+ struct tcp_sock *besttp; -+ struct mptcp_tcp_sock *mptcp; -+ struct ecfsched_cb *ecf_cb = ecfsched_get_cb(tcp_sk(meta_sk)); -+ u32 min_srtt = U32_MAX; -+ u32 sub_sndbuf = 0; -+ u32 sub_packets_out = 0; -+ -+ /* Answer data_fin on same subflow!!! */ -+ if (meta_sk->sk_shutdown & RCV_SHUTDOWN && -+ skb && mptcp_is_data_fin(skb)) { -+ mptcp_for_each_sub(mpcb, mptcp) { -+ bestsk = mptcp_to_sock(mptcp); -+ -+ if (tcp_sk(bestsk)->mptcp->path_index == mpcb->dfin_path_index && -+ mptcp_is_available(bestsk, skb, zero_wnd_test)) -+ return bestsk; -+ } -+ } -+ -+ /* First, find the overall best (fastest) subflow */ -+ mptcp_for_each_sub(mpcb, mptcp) { -+ bestsk = mptcp_to_sock(mptcp); -+ besttp = tcp_sk(bestsk); -+ -+ /* Set of states for which we are allowed to send data */ -+ if (!mptcp_sk_can_send(bestsk)) -+ continue; -+ -+ /* We do not send data on this subflow unless it is -+ * fully established, i.e. the 4th ack has been received. -+ */ -+ if (besttp->mptcp->pre_established) -+ continue; -+ -+ sub_sndbuf += bestsk->sk_wmem_queued; -+ sub_packets_out += besttp->packets_out; -+ -+ /* record minimal rtt */ -+ if (besttp->srtt_us < min_srtt) { -+ min_srtt = besttp->srtt_us; -+ minsk = bestsk; -+ } -+ } -+ -+ /* find the current best subflow according to the default scheduler */ -+ bestsk = get_available_subflow(meta_sk, skb, zero_wnd_test); -+ -+ /* if we decided to use a slower flow, we have the option of not using it at all */ -+ if (bestsk && minsk && bestsk != minsk) { -+ u32 mss = tcp_current_mss(bestsk); /* assuming equal MSS */ -+ u32 sndbuf_meta = meta_sk->sk_wmem_queued; -+ u32 sndbuf_minus = sub_sndbuf; -+ u32 sndbuf = 0; -+ -+ u32 cwnd_f = tcp_sk(minsk)->snd_cwnd; -+ u32 srtt_f = tcp_sk(minsk)->srtt_us >> 3; -+ u32 rttvar_f = tcp_sk(minsk)->rttvar_us >> 1; -+ -+ u32 cwnd_s = tcp_sk(bestsk)->snd_cwnd; -+ u32 srtt_s = tcp_sk(bestsk)->srtt_us >> 3; -+ u32 rttvar_s = tcp_sk(bestsk)->rttvar_us >> 1; -+ -+ u32 delta = max(rttvar_f, rttvar_s); -+ -+ u32 x_f; -+ u64 lhs, rhs; /* to avoid overflow, using u64 */ -+ -+ if (tcp_sk(meta_sk)->packets_out > sub_packets_out) -+ sndbuf_minus += (tcp_sk(meta_sk)->packets_out - sub_packets_out) * mss; -+ -+ if (sndbuf_meta > sndbuf_minus) -+ sndbuf = sndbuf_meta - sndbuf_minus; -+ -+ /* we have something to send. -+ * at least one time tx over fastest subflow is required -+ */ -+ x_f = sndbuf > cwnd_f * mss ? sndbuf : cwnd_f * mss; -+ lhs = srtt_f * (x_f + cwnd_f * mss); -+ rhs = cwnd_f * mss * (srtt_s + delta); -+ -+ if (mptcp_ecf_r_beta * lhs < mptcp_ecf_r_beta * rhs + ecf_cb->switching_margin * rhs) { -+ u32 x_s = sndbuf > cwnd_s * mss ? sndbuf : cwnd_s * mss; -+ u64 lhs_s = srtt_s * x_s; -+ u64 rhs_s = cwnd_s * mss * (2 * srtt_f + delta); -+ -+ if (lhs_s >= rhs_s) { -+ /* too slower than fastest */ -+ ecf_cb->switching_margin = 1; -+ return NULL; -+ } -+ } else { -+ /* use slower one */ -+ ecf_cb->switching_margin = 0; -+ } -+ } -+ -+ return bestsk; -+} -+ -+static void ecfsched_init(struct sock *sk) -+{ -+ struct ecfsched_priv *ecf_p = ecfsched_get_priv(tcp_sk(sk)); -+ struct ecfsched_cb *ecf_cb = ecfsched_get_cb(tcp_sk(mptcp_meta_sk(sk))); -+ -+ ecf_p->last_rbuf_opti = tcp_jiffies32; -+ ecf_cb->switching_margin = 0; -+} -+ -+struct mptcp_sched_ops mptcp_sched_ecf = { -+ .get_subflow = ecf_get_available_subflow, -+ .next_segment = mptcp_next_segment, -+ .init = ecfsched_init, -+ .name = "ecf", -+ .owner = THIS_MODULE, -+}; -+ -+static int __init ecf_register(void) -+{ -+ BUILD_BUG_ON(sizeof(struct ecfsched_priv) > MPTCP_SCHED_SIZE); -+ BUILD_BUG_ON(sizeof(struct ecfsched_cb) > MPTCP_SCHED_DATA_SIZE); -+ -+ if (mptcp_register_scheduler(&mptcp_sched_ecf)) -+ return -1; -+ -+ return 0; -+} -+ -+static void ecf_unregister(void) -+{ -+ mptcp_unregister_scheduler(&mptcp_sched_ecf); -+} -+ -+module_init(ecf_register); -+module_exit(ecf_unregister); -+ -+MODULE_AUTHOR("Yeon-sup Lim, Daniel Weber"); -+MODULE_LICENSE("GPL"); -+MODULE_DESCRIPTION("ECF (Earliest Completion First) scheduler for MPTCP, based on default minimum RTT scheduler"); -+MODULE_VERSION("0.95"); -diff -aurN linux-5.4.64/net/mptcp/mptcp_fullmesh.c linux-5.4.64.mptcp/net/mptcp/mptcp_fullmesh.c ---- linux-5.4.64/net/mptcp/mptcp_fullmesh.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-5.4.64.mptcp/net/mptcp/mptcp_fullmesh.c 2020-09-10 19:25:10.507220869 +0200 -@@ -0,0 +1,1938 @@ -+#include -+#include -+ -+#include -+#include -+ -+#if IS_ENABLED(CONFIG_IPV6) -+#include -+#include -+#endif -+ -+enum { -+ MPTCP_EVENT_ADD = 1, -+ MPTCP_EVENT_DEL, -+ MPTCP_EVENT_MOD, -+}; -+ -+#define MPTCP_SUBFLOW_RETRY_DELAY 1000 -+ -+/* Max number of local or remote addresses we can store. -+ * When changing, see the bitfield below in fullmesh_rem4/6. -+ */ -+#define MPTCP_MAX_ADDR 8 -+ -+struct fullmesh_rem4 { -+ u8 rem4_id; -+ u8 bitfield; -+ u8 retry_bitfield; -+ __be16 port; -+ struct in_addr addr; -+}; -+ -+struct fullmesh_rem6 { -+ u8 rem6_id; -+ u8 bitfield; -+ u8 retry_bitfield; -+ __be16 port; -+ struct in6_addr addr; -+}; -+ -+struct mptcp_loc_addr { -+ struct mptcp_loc4 locaddr4[MPTCP_MAX_ADDR]; -+ u8 loc4_bits; -+ u8 next_v4_index; -+ -+ struct mptcp_loc6 locaddr6[MPTCP_MAX_ADDR]; -+ u8 loc6_bits; -+ u8 next_v6_index; -+ struct rcu_head rcu; -+}; -+ -+struct mptcp_addr_event { -+ struct list_head list; -+ unsigned short family; -+ u8 code:7, -+ low_prio:1; -+ int if_idx; -+ union inet_addr addr; -+}; -+ -+struct fullmesh_priv { -+ /* Worker struct for subflow establishment */ -+ struct work_struct subflow_work; -+ /* Delayed worker, when the routing-tables are not yet ready. */ -+ struct delayed_work subflow_retry_work; -+ -+ /* Remote addresses */ -+ struct fullmesh_rem4 remaddr4[MPTCP_MAX_ADDR]; -+ struct fullmesh_rem6 remaddr6[MPTCP_MAX_ADDR]; -+ -+ struct mptcp_cb *mpcb; -+ -+ u16 remove_addrs; /* Addresses to remove */ -+ u8 announced_addrs_v4; /* IPv4 Addresses we did announce */ -+ u8 announced_addrs_v6; /* IPv6 Addresses we did announce */ -+ -+ u8 add_addr; /* Are we sending an add_addr? */ -+ -+ u8 rem4_bits; -+ u8 rem6_bits; -+ -+ /* Have we established the additional subflows for primary pair? */ -+ u8 first_pair:1; -+}; -+ -+struct mptcp_fm_ns { -+ struct mptcp_loc_addr __rcu *local; -+ spinlock_t local_lock; /* Protecting the above pointer */ -+ struct list_head events; -+ struct delayed_work address_worker; -+ -+ struct net *net; -+}; -+ -+static int num_subflows __read_mostly = 1; -+module_param(num_subflows, int, 0644); -+MODULE_PARM_DESC(num_subflows, "choose the number of subflows per pair of IP addresses of MPTCP connection"); -+ -+static int create_on_err __read_mostly; -+module_param(create_on_err, int, 0644); -+MODULE_PARM_DESC(create_on_err, "recreate the subflow upon a timeout"); -+ -+static struct mptcp_pm_ops full_mesh __read_mostly; -+ -+static void full_mesh_create_subflows(struct sock *meta_sk); -+ -+static struct mptcp_fm_ns *fm_get_ns(const struct net *net) -+{ -+ return (struct mptcp_fm_ns *)net->mptcp.path_managers[MPTCP_PM_FULLMESH]; -+} -+ -+static struct fullmesh_priv *fullmesh_get_priv(const struct mptcp_cb *mpcb) -+{ -+ return (struct fullmesh_priv *)&mpcb->mptcp_pm[0]; -+} -+ -+/* Find the first free index in the bitfield */ -+static int __mptcp_find_free_index(u8 bitfield, u8 base) -+{ -+ int i; -+ -+ /* There are anyways no free bits... */ -+ if (bitfield == 0xff) -+ goto exit; -+ -+ i = ffs(~(bitfield >> base)) - 1; -+ if (i < 0) -+ goto exit; -+ -+ /* No free bits when starting at base, try from 0 on */ -+ if (i + base >= sizeof(bitfield) * 8) -+ return __mptcp_find_free_index(bitfield, 0); -+ -+ return i + base; -+exit: -+ return -1; -+} -+ -+static int mptcp_find_free_index(u8 bitfield) -+{ -+ return __mptcp_find_free_index(bitfield, 0); -+} -+ -+static void mptcp_addv4_raddr(struct mptcp_cb *mpcb, -+ const struct in_addr *addr, -+ __be16 port, u8 id) -+{ -+ int i; -+ struct fullmesh_rem4 *rem4; -+ struct fullmesh_priv *fmp = fullmesh_get_priv(mpcb); -+ -+ mptcp_for_each_bit_set(fmp->rem4_bits, i) { -+ rem4 = &fmp->remaddr4[i]; -+ -+ /* Address is already in the list --- continue */ -+ if (rem4->rem4_id == id && -+ rem4->addr.s_addr == addr->s_addr && rem4->port == port) -+ return; -+ -+ /* This may be the case, when the peer is behind a NAT. He is -+ * trying to JOIN, thus sending the JOIN with a certain ID. -+ * However the src_addr of the IP-packet has been changed. We -+ * update the addr in the list, because this is the address as -+ * OUR BOX sees it. -+ */ -+ if (rem4->rem4_id == id && rem4->addr.s_addr != addr->s_addr) { -+ /* update the address */ -+ mptcp_debug("%s: updating old addr:%pI4 to addr %pI4 with id:%d\n", -+ __func__, &rem4->addr.s_addr, -+ &addr->s_addr, id); -+ rem4->addr.s_addr = addr->s_addr; -+ rem4->port = port; -+ mpcb->list_rcvd = 1; -+ return; -+ } -+ } -+ -+ i = mptcp_find_free_index(fmp->rem4_bits); -+ /* Do we have already the maximum number of local/remote addresses? */ -+ if (i < 0) { -+ mptcp_debug("%s: At max num of remote addresses: %d --- not adding address: %pI4\n", -+ __func__, MPTCP_MAX_ADDR, &addr->s_addr); -+ return; -+ } -+ -+ rem4 = &fmp->remaddr4[i]; -+ -+ /* Address is not known yet, store it */ -+ rem4->addr.s_addr = addr->s_addr; -+ rem4->port = port; -+ rem4->bitfield = 0; -+ rem4->retry_bitfield = 0; -+ rem4->rem4_id = id; -+ mpcb->list_rcvd = 1; -+ fmp->rem4_bits |= (1 << i); -+ -+ return; -+} -+ -+static void mptcp_addv6_raddr(struct mptcp_cb *mpcb, -+ const struct in6_addr *addr, -+ __be16 port, u8 id) -+{ -+ int i; -+ struct fullmesh_rem6 *rem6; -+ struct fullmesh_priv *fmp = fullmesh_get_priv(mpcb); -+ -+ mptcp_for_each_bit_set(fmp->rem6_bits, i) { -+ rem6 = &fmp->remaddr6[i]; -+ -+ /* Address is already in the list --- continue */ -+ if (rem6->rem6_id == id && -+ ipv6_addr_equal(&rem6->addr, addr) && rem6->port == port) -+ return; -+ -+ /* This may be the case, when the peer is behind a NAT. He is -+ * trying to JOIN, thus sending the JOIN with a certain ID. -+ * However the src_addr of the IP-packet has been changed. We -+ * update the addr in the list, because this is the address as -+ * OUR BOX sees it. -+ */ -+ if (rem6->rem6_id == id) { -+ /* update the address */ -+ mptcp_debug("%s: updating old addr: %pI6 to addr %pI6 with id:%d\n", -+ __func__, &rem6->addr, addr, id); -+ rem6->addr = *addr; -+ rem6->port = port; -+ mpcb->list_rcvd = 1; -+ return; -+ } -+ } -+ -+ i = mptcp_find_free_index(fmp->rem6_bits); -+ /* Do we have already the maximum number of local/remote addresses? */ -+ if (i < 0) { -+ mptcp_debug("%s: At max num of remote addresses: %d --- not adding address: %pI6\n", -+ __func__, MPTCP_MAX_ADDR, addr); -+ return; -+ } -+ -+ rem6 = &fmp->remaddr6[i]; -+ -+ /* Address is not known yet, store it */ -+ rem6->addr = *addr; -+ rem6->port = port; -+ rem6->bitfield = 0; -+ rem6->retry_bitfield = 0; -+ rem6->rem6_id = id; -+ mpcb->list_rcvd = 1; -+ fmp->rem6_bits |= (1 << i); -+ -+ return; -+} -+ -+static void mptcp_v4_rem_raddress(struct mptcp_cb *mpcb, u8 id) -+{ -+ int i; -+ struct fullmesh_priv *fmp = fullmesh_get_priv(mpcb); -+ -+ mptcp_for_each_bit_set(fmp->rem4_bits, i) { -+ if (fmp->remaddr4[i].rem4_id == id) { -+ /* remove address from bitfield */ -+ fmp->rem4_bits &= ~(1 << i); -+ -+ break; -+ } -+ } -+} -+ -+static void mptcp_v6_rem_raddress(const struct mptcp_cb *mpcb, u8 id) -+{ -+ int i; -+ struct fullmesh_priv *fmp = fullmesh_get_priv(mpcb); -+ -+ mptcp_for_each_bit_set(fmp->rem6_bits, i) { -+ if (fmp->remaddr6[i].rem6_id == id) { -+ /* remove address from bitfield */ -+ fmp->rem6_bits &= ~(1 << i); -+ -+ break; -+ } -+ } -+} -+ -+/* Sets the bitfield of the remote-address field */ -+static void mptcp_v4_set_init_addr_bit(const struct mptcp_cb *mpcb, -+ const struct in_addr *addr, u8 index) -+{ -+ int i; -+ struct fullmesh_priv *fmp = fullmesh_get_priv(mpcb); -+ -+ mptcp_for_each_bit_set(fmp->rem4_bits, i) { -+ if (fmp->remaddr4[i].addr.s_addr == addr->s_addr) { -+ fmp->remaddr4[i].bitfield |= (1 << index); -+ return; -+ } -+ } -+} -+ -+/* Sets the bitfield of the remote-address field */ -+static void mptcp_v6_set_init_addr_bit(struct mptcp_cb *mpcb, -+ const struct in6_addr *addr, u8 index) -+{ -+ int i; -+ struct fullmesh_priv *fmp = fullmesh_get_priv(mpcb); -+ -+ mptcp_for_each_bit_set(fmp->rem6_bits, i) { -+ if (ipv6_addr_equal(&fmp->remaddr6[i].addr, addr)) { -+ fmp->remaddr6[i].bitfield |= (1 << index); -+ return; -+ } -+ } -+} -+ -+static void mptcp_set_init_addr_bit(struct mptcp_cb *mpcb, -+ const union inet_addr *addr, -+ sa_family_t family, u8 id) -+{ -+ if (family == AF_INET) -+ mptcp_v4_set_init_addr_bit(mpcb, &addr->in, id); -+ else -+ mptcp_v6_set_init_addr_bit(mpcb, &addr->in6, id); -+} -+ -+static void mptcp_v4_subflows(struct sock *meta_sk, -+ const struct mptcp_loc4 *loc, -+ struct mptcp_rem4 *rem) -+{ -+ int i; -+ -+ for (i = 1; i < num_subflows; i++) -+ mptcp_init4_subsockets(meta_sk, loc, rem); -+} -+ -+#if IS_ENABLED(CONFIG_IPV6) -+static void mptcp_v6_subflows(struct sock *meta_sk, -+ const struct mptcp_loc6 *loc, -+ struct mptcp_rem6 *rem) -+{ -+ int i; -+ -+ for (i = 1; i < num_subflows; i++) -+ mptcp_init6_subsockets(meta_sk, loc, rem); -+} -+#endif -+ -+static void retry_subflow_worker(struct work_struct *work) -+{ -+ struct delayed_work *delayed_work = container_of(work, -+ struct delayed_work, -+ work); -+ struct fullmesh_priv *fmp = container_of(delayed_work, -+ struct fullmesh_priv, -+ subflow_retry_work); -+ struct mptcp_cb *mpcb = fmp->mpcb; -+ struct sock *meta_sk = mpcb->meta_sk; -+ struct mptcp_loc_addr *mptcp_local; -+ struct mptcp_fm_ns *fm_ns = fm_get_ns(sock_net(meta_sk)); -+ int iter = 0, i; -+ -+ /* We need a local (stable) copy of the address-list. Really, it is not -+ * such a big deal, if the address-list is not 100% up-to-date. -+ */ -+ rcu_read_lock_bh(); -+ mptcp_local = rcu_dereference_bh(fm_ns->local); -+ mptcp_local = kmemdup(mptcp_local, sizeof(*mptcp_local), GFP_ATOMIC); -+ rcu_read_unlock_bh(); -+ -+ if (!mptcp_local) -+ return; -+ -+next_subflow: -+ if (iter) { -+ release_sock(meta_sk); -+ mutex_unlock(&mpcb->mpcb_mutex); -+ -+ cond_resched(); -+ } -+ mutex_lock(&mpcb->mpcb_mutex); -+ lock_sock_nested(meta_sk, SINGLE_DEPTH_NESTING); -+ -+ if (!mptcp(tcp_sk(meta_sk))) -+ goto exit; -+ -+ iter++; -+ -+ if (sock_flag(meta_sk, SOCK_DEAD)) -+ goto exit; -+ -+ mptcp_for_each_bit_set(fmp->rem4_bits, i) { -+ struct fullmesh_rem4 *rem = &fmp->remaddr4[i]; -+ /* Do we need to retry establishing a subflow ? */ -+ if (rem->retry_bitfield) { -+ int i = mptcp_find_free_index(~rem->retry_bitfield); -+ struct mptcp_rem4 rem4; -+ -+ rem->bitfield |= (1 << i); -+ rem->retry_bitfield &= ~(1 << i); -+ -+ rem4.addr = rem->addr; -+ rem4.port = rem->port; -+ rem4.rem4_id = rem->rem4_id; -+ -+ mptcp_init4_subsockets(meta_sk, &mptcp_local->locaddr4[i], &rem4); -+ mptcp_v4_subflows(meta_sk, -+ &mptcp_local->locaddr4[i], -+ &rem4); -+ goto next_subflow; -+ } -+ } -+ -+#if IS_ENABLED(CONFIG_IPV6) -+ mptcp_for_each_bit_set(fmp->rem6_bits, i) { -+ struct fullmesh_rem6 *rem = &fmp->remaddr6[i]; -+ -+ /* Do we need to retry establishing a subflow ? */ -+ if (rem->retry_bitfield) { -+ int i = mptcp_find_free_index(~rem->retry_bitfield); -+ struct mptcp_rem6 rem6; -+ -+ rem->bitfield |= (1 << i); -+ rem->retry_bitfield &= ~(1 << i); -+ -+ rem6.addr = rem->addr; -+ rem6.port = rem->port; -+ rem6.rem6_id = rem->rem6_id; -+ -+ mptcp_init6_subsockets(meta_sk, &mptcp_local->locaddr6[i], &rem6); -+ mptcp_v6_subflows(meta_sk, -+ &mptcp_local->locaddr6[i], -+ &rem6); -+ goto next_subflow; -+ } -+ } -+#endif -+ -+exit: -+ kfree(mptcp_local); -+ release_sock(meta_sk); -+ mutex_unlock(&mpcb->mpcb_mutex); -+ mptcp_mpcb_put(mpcb); -+ sock_put(meta_sk); -+} -+ -+/** -+ * Create all new subflows, by doing calls to mptcp_initX_subsockets -+ * -+ * This function uses a goto next_subflow, to allow releasing the lock between -+ * new subflows and giving other processes a chance to do some work on the -+ * socket and potentially finishing the communication. -+ **/ -+static void create_subflow_worker(struct work_struct *work) -+{ -+ struct fullmesh_priv *fmp = container_of(work, struct fullmesh_priv, -+ subflow_work); -+ struct mptcp_cb *mpcb = fmp->mpcb; -+ struct sock *meta_sk = mpcb->meta_sk; -+ struct mptcp_loc_addr *mptcp_local; -+ const struct mptcp_fm_ns *fm_ns = fm_get_ns(sock_net(meta_sk)); -+ int iter = 0, retry = 0; -+ int i; -+ -+ /* We need a local (stable) copy of the address-list. Really, it is not -+ * such a big deal, if the address-list is not 100% up-to-date. -+ */ -+ rcu_read_lock_bh(); -+ mptcp_local = rcu_dereference_bh(fm_ns->local); -+ mptcp_local = kmemdup(mptcp_local, sizeof(*mptcp_local), GFP_ATOMIC); -+ rcu_read_unlock_bh(); -+ -+ if (!mptcp_local) -+ return; -+ -+next_subflow: -+ if (iter) { -+ release_sock(meta_sk); -+ mutex_unlock(&mpcb->mpcb_mutex); -+ -+ cond_resched(); -+ } -+ mutex_lock(&mpcb->mpcb_mutex); -+ lock_sock_nested(meta_sk, SINGLE_DEPTH_NESTING); -+ -+ if (sock_flag(meta_sk, SOCK_DEAD) || !mptcp(tcp_sk(meta_sk))) -+ goto exit; -+ -+ if (mpcb->master_sk && -+ !tcp_sk(mpcb->master_sk)->mptcp->fully_established) -+ goto exit; -+ -+ /* Create the additional subflows for the first pair */ -+ if (fmp->first_pair == 0 && mpcb->master_sk) { -+ struct mptcp_loc4 loc; -+ struct mptcp_rem4 rem; -+ -+ loc.addr.s_addr = inet_sk(meta_sk)->inet_saddr; -+ loc.loc4_id = 0; -+ loc.low_prio = 0; -+ loc.if_idx = mpcb->master_sk->sk_bound_dev_if; -+ -+ rem.addr.s_addr = inet_sk(meta_sk)->inet_daddr; -+ rem.port = inet_sk(meta_sk)->inet_dport; -+ rem.rem4_id = 0; /* Default 0 */ -+ -+ mptcp_v4_subflows(meta_sk, &loc, &rem); -+ -+ fmp->first_pair = 1; -+ } -+ iter++; -+ -+ mptcp_for_each_bit_set(fmp->rem4_bits, i) { -+ struct fullmesh_rem4 *rem; -+ u8 remaining_bits; -+ -+ rem = &fmp->remaddr4[i]; -+ remaining_bits = ~(rem->bitfield) & mptcp_local->loc4_bits; -+ -+ /* Are there still combinations to handle? */ -+ if (remaining_bits) { -+ int i = mptcp_find_free_index(~remaining_bits); -+ struct mptcp_rem4 rem4; -+ -+ rem->bitfield |= (1 << i); -+ -+ rem4.addr = rem->addr; -+ rem4.port = rem->port; -+ rem4.rem4_id = rem->rem4_id; -+ -+ /* If a route is not yet available then retry once */ -+ if (mptcp_init4_subsockets(meta_sk, &mptcp_local->locaddr4[i], -+ &rem4) == -ENETUNREACH) -+ retry = rem->retry_bitfield |= (1 << i); -+ else -+ mptcp_v4_subflows(meta_sk, -+ &mptcp_local->locaddr4[i], -+ &rem4); -+ goto next_subflow; -+ } -+ } -+ -+#if IS_ENABLED(CONFIG_IPV6) -+ if (fmp->first_pair == 0 && mpcb->master_sk) { -+ struct mptcp_loc6 loc; -+ struct mptcp_rem6 rem; -+ -+ loc.addr = inet6_sk(meta_sk)->saddr; -+ loc.loc6_id = 0; -+ loc.low_prio = 0; -+ loc.if_idx = mpcb->master_sk->sk_bound_dev_if; -+ -+ rem.addr = meta_sk->sk_v6_daddr; -+ rem.port = inet_sk(meta_sk)->inet_dport; -+ rem.rem6_id = 0; /* Default 0 */ -+ -+ mptcp_v6_subflows(meta_sk, &loc, &rem); -+ -+ fmp->first_pair = 1; -+ } -+ mptcp_for_each_bit_set(fmp->rem6_bits, i) { -+ struct fullmesh_rem6 *rem; -+ u8 remaining_bits; -+ -+ rem = &fmp->remaddr6[i]; -+ remaining_bits = ~(rem->bitfield) & mptcp_local->loc6_bits; -+ -+ /* Are there still combinations to handle? */ -+ if (remaining_bits) { -+ int i = mptcp_find_free_index(~remaining_bits); -+ struct mptcp_rem6 rem6; -+ -+ rem->bitfield |= (1 << i); -+ -+ rem6.addr = rem->addr; -+ rem6.port = rem->port; -+ rem6.rem6_id = rem->rem6_id; -+ -+ /* If a route is not yet available then retry once */ -+ if (mptcp_init6_subsockets(meta_sk, &mptcp_local->locaddr6[i], -+ &rem6) == -ENETUNREACH) -+ retry = rem->retry_bitfield |= (1 << i); -+ else -+ mptcp_v6_subflows(meta_sk, -+ &mptcp_local->locaddr6[i], -+ &rem6); -+ goto next_subflow; -+ } -+ } -+#endif -+ -+ if (retry && !delayed_work_pending(&fmp->subflow_retry_work)) { -+ sock_hold(meta_sk); -+ refcount_inc(&mpcb->mpcb_refcnt); -+ queue_delayed_work(mptcp_wq, &fmp->subflow_retry_work, -+ msecs_to_jiffies(MPTCP_SUBFLOW_RETRY_DELAY)); -+ } -+ -+exit: -+ kfree(mptcp_local); -+ release_sock(meta_sk); -+ mutex_unlock(&mpcb->mpcb_mutex); -+ mptcp_mpcb_put(mpcb); -+ sock_put(meta_sk); -+} -+ -+static void announce_remove_addr(u8 addr_id, struct sock *meta_sk) -+{ -+ struct mptcp_cb *mpcb = tcp_sk(meta_sk)->mpcb; -+ struct fullmesh_priv *fmp = fullmesh_get_priv(mpcb); -+ struct sock *sk = mptcp_select_ack_sock(meta_sk); -+ -+ fmp->remove_addrs |= (1 << addr_id); -+ mpcb->addr_signal = 1; -+ -+ if (sk) -+ tcp_send_ack(sk); -+} -+ -+static void update_addr_bitfields(struct sock *meta_sk, -+ const struct mptcp_loc_addr *mptcp_local) -+{ -+ struct mptcp_cb *mpcb = tcp_sk(meta_sk)->mpcb; -+ struct fullmesh_priv *fmp = fullmesh_get_priv(mpcb); -+ int i; -+ -+ /* The bits in announced_addrs_* always match with loc*_bits. So, a -+ * simple & operation unsets the correct bits, because these go from -+ * announced to non-announced -+ */ -+ fmp->announced_addrs_v4 &= mptcp_local->loc4_bits; -+ -+ mptcp_for_each_bit_set(fmp->rem4_bits, i) { -+ fmp->remaddr4[i].bitfield &= mptcp_local->loc4_bits; -+ fmp->remaddr4[i].retry_bitfield &= mptcp_local->loc4_bits; -+ } -+ -+ fmp->announced_addrs_v6 &= mptcp_local->loc6_bits; -+ -+ mptcp_for_each_bit_set(fmp->rem6_bits, i) { -+ fmp->remaddr6[i].bitfield &= mptcp_local->loc6_bits; -+ fmp->remaddr6[i].retry_bitfield &= mptcp_local->loc6_bits; -+ } -+} -+ -+static int mptcp_find_address(const struct mptcp_loc_addr *mptcp_local, -+ sa_family_t family, const union inet_addr *addr, -+ int if_idx) -+{ -+ int i; -+ u8 loc_bits; -+ bool found = false; -+ -+ if (family == AF_INET) -+ loc_bits = mptcp_local->loc4_bits; -+ else -+ loc_bits = mptcp_local->loc6_bits; -+ -+ mptcp_for_each_bit_set(loc_bits, i) { -+ if (family == AF_INET && -+ (!if_idx || mptcp_local->locaddr4[i].if_idx == if_idx) && -+ mptcp_local->locaddr4[i].addr.s_addr == addr->in.s_addr) { -+ found = true; -+ break; -+ } -+ if (family == AF_INET6 && -+ (!if_idx || mptcp_local->locaddr6[i].if_idx == if_idx) && -+ ipv6_addr_equal(&mptcp_local->locaddr6[i].addr, -+ &addr->in6)) { -+ found = true; -+ break; -+ } -+ } -+ -+ if (!found) -+ return -1; -+ -+ return i; -+} -+ -+static int mptcp_find_address_transp(const struct mptcp_loc_addr *mptcp_local, -+ sa_family_t family, int if_idx) -+{ -+ bool found = false; -+ u8 loc_bits; -+ int i; -+ -+ if (family == AF_INET) -+ loc_bits = mptcp_local->loc4_bits; -+ else -+ loc_bits = mptcp_local->loc6_bits; -+ -+ mptcp_for_each_bit_set(loc_bits, i) { -+ if (family == AF_INET && -+ (!if_idx || mptcp_local->locaddr4[i].if_idx == if_idx)) { -+ found = true; -+ break; -+ } -+ if (family == AF_INET6 && -+ (!if_idx || mptcp_local->locaddr6[i].if_idx == if_idx)) { -+ found = true; -+ break; -+ } -+ } -+ -+ if (!found) -+ return -1; -+ -+ return i; -+} -+ -+static void mptcp_address_worker(struct work_struct *work) -+{ -+ const struct delayed_work *delayed_work = container_of(work, -+ struct delayed_work, -+ work); -+ struct mptcp_fm_ns *fm_ns = container_of(delayed_work, -+ struct mptcp_fm_ns, -+ address_worker); -+ struct net *net = fm_ns->net; -+ struct mptcp_addr_event *event = NULL; -+ struct mptcp_loc_addr *mptcp_local, *old; -+ int i, id = -1; /* id is used in the socket-code on a delete-event */ -+ bool success; /* Used to indicate if we succeeded handling the event */ -+ -+next_event: -+ success = false; -+ kfree(event); -+ -+ /* First, let's dequeue an event from our event-list */ -+ rcu_read_lock_bh(); -+ spin_lock(&fm_ns->local_lock); -+ -+ event = list_first_entry_or_null(&fm_ns->events, -+ struct mptcp_addr_event, list); -+ if (!event) { -+ spin_unlock(&fm_ns->local_lock); -+ rcu_read_unlock_bh(); -+ return; -+ } -+ -+ list_del(&event->list); -+ -+ mptcp_local = rcu_dereference_bh(fm_ns->local); -+ -+ if (event->code == MPTCP_EVENT_DEL) { -+ id = mptcp_find_address(mptcp_local, event->family, -+ &event->addr, event->if_idx); -+ -+ /* Not in the list - so we don't care */ -+ if (id < 0) { -+ mptcp_debug("%s could not find id\n", __func__); -+ goto duno; -+ } -+ -+ old = mptcp_local; -+ mptcp_local = kmemdup(mptcp_local, sizeof(*mptcp_local), -+ GFP_ATOMIC); -+ if (!mptcp_local) -+ goto duno; -+ -+ if (event->family == AF_INET) -+ mptcp_local->loc4_bits &= ~(1 << id); -+ else -+ mptcp_local->loc6_bits &= ~(1 << id); -+ -+ rcu_assign_pointer(fm_ns->local, mptcp_local); -+ kfree_rcu(old, rcu); -+ } else { -+ int i = mptcp_find_address(mptcp_local, event->family, -+ &event->addr, event->if_idx); -+ int j = i; -+ -+ if (j < 0) { -+ /* Not in the list, so we have to find an empty slot */ -+ if (event->family == AF_INET) -+ i = __mptcp_find_free_index(mptcp_local->loc4_bits, -+ mptcp_local->next_v4_index); -+ if (event->family == AF_INET6) -+ i = __mptcp_find_free_index(mptcp_local->loc6_bits, -+ mptcp_local->next_v6_index); -+ -+ if (i < 0) { -+ mptcp_debug("%s no more space\n", __func__); -+ goto duno; -+ } -+ -+ /* It might have been a MOD-event. */ -+ event->code = MPTCP_EVENT_ADD; -+ } else { -+ /* Let's check if anything changes */ -+ if (event->family == AF_INET && -+ event->low_prio == mptcp_local->locaddr4[i].low_prio) -+ goto duno; -+ -+ if (event->family == AF_INET6 && -+ event->low_prio == mptcp_local->locaddr6[i].low_prio) -+ goto duno; -+ } -+ -+ old = mptcp_local; -+ mptcp_local = kmemdup(mptcp_local, sizeof(*mptcp_local), -+ GFP_ATOMIC); -+ if (!mptcp_local) -+ goto duno; -+ -+ if (event->family == AF_INET) { -+ mptcp_local->locaddr4[i].addr.s_addr = event->addr.in.s_addr; -+ mptcp_local->locaddr4[i].loc4_id = i + 1; -+ mptcp_local->locaddr4[i].low_prio = event->low_prio; -+ mptcp_local->locaddr4[i].if_idx = event->if_idx; -+ -+ mptcp_debug("%s updated IP %pI4 on ifidx %u prio %u id %u\n", -+ __func__, &event->addr.in.s_addr, -+ event->if_idx, event->low_prio, i + 1); -+ } else { -+ mptcp_local->locaddr6[i].addr = event->addr.in6; -+ mptcp_local->locaddr6[i].loc6_id = i + MPTCP_MAX_ADDR; -+ mptcp_local->locaddr6[i].low_prio = event->low_prio; -+ mptcp_local->locaddr6[i].if_idx = event->if_idx; -+ -+ mptcp_debug("%s updated IP %pI6 on ifidx %u prio %u id %u\n", -+ __func__, &event->addr.in6, -+ event->if_idx, event->low_prio, i + MPTCP_MAX_ADDR); -+ } -+ -+ if (j < 0) { -+ if (event->family == AF_INET) { -+ mptcp_local->loc4_bits |= (1 << i); -+ mptcp_local->next_v4_index = i + 1; -+ } else { -+ mptcp_local->loc6_bits |= (1 << i); -+ mptcp_local->next_v6_index = i + 1; -+ } -+ } -+ -+ rcu_assign_pointer(fm_ns->local, mptcp_local); -+ kfree_rcu(old, rcu); -+ } -+ success = true; -+ -+duno: -+ spin_unlock(&fm_ns->local_lock); -+ rcu_read_unlock_bh(); -+ -+ if (!success) -+ goto next_event; -+ -+ /* Now we iterate over the MPTCP-sockets and apply the event. */ -+ for (i = 0; i <= mptcp_tk_htable.mask; i++) { -+ const struct hlist_nulls_node *node; -+ struct tcp_sock *meta_tp; -+ -+ rcu_read_lock_bh(); -+ hlist_nulls_for_each_entry_rcu(meta_tp, node, -+ &mptcp_tk_htable.hashtable[i], -+ tk_table) { -+ struct sock *meta_sk = (struct sock *)meta_tp, *sk; -+ bool meta_v4 = meta_sk->sk_family == AF_INET; -+ struct mptcp_cb *mpcb; -+ -+ if (sock_net(meta_sk) != net) -+ continue; -+ -+ if (meta_v4) { -+ /* skip IPv6 events if meta is IPv4 */ -+ if (event->family == AF_INET6) -+ continue; -+ } else if (event->family == AF_INET && meta_sk->sk_ipv6only) { -+ /* skip IPv4 events if IPV6_V6ONLY is set */ -+ continue; -+ } -+ -+ if (unlikely(!refcount_inc_not_zero(&meta_sk->sk_refcnt))) -+ continue; -+ -+ bh_lock_sock(meta_sk); -+ -+ mpcb = meta_tp->mpcb; -+ if (!mpcb) -+ goto next; -+ -+ if (!mptcp(meta_tp) || !is_meta_sk(meta_sk) || -+ mptcp_in_infinite_mapping_weak(mpcb)) -+ goto next; -+ -+ /* May be that the pm has changed in-between */ -+ if (mpcb->pm_ops != &full_mesh) -+ goto next; -+ -+ if (sock_owned_by_user(meta_sk)) { -+ if (!test_and_set_bit(MPTCP_PATH_MANAGER_DEFERRED, -+ &meta_sk->sk_tsq_flags)) -+ sock_hold(meta_sk); -+ -+ goto next; -+ } -+ -+ if (event->code == MPTCP_EVENT_ADD) { -+ struct fullmesh_priv *fmp = fullmesh_get_priv(mpcb); -+ -+ fmp->add_addr++; -+ mpcb->addr_signal = 1; -+ -+ sk = mptcp_select_ack_sock(meta_sk); -+ if (sk) -+ tcp_send_ack(sk); -+ -+ full_mesh_create_subflows(meta_sk); -+ } -+ -+ if (event->code == MPTCP_EVENT_DEL) { -+ struct mptcp_tcp_sock *mptcp; -+ struct mptcp_loc_addr *mptcp_local; -+ struct hlist_node *tmp; -+ bool found = false; -+ -+ mptcp_local = rcu_dereference_bh(fm_ns->local); -+ -+ /* In any case, we need to update our bitfields */ -+ if (id >= 0) -+ update_addr_bitfields(meta_sk, mptcp_local); -+ -+ /* Look for the socket and remove him */ -+ mptcp_for_each_sub_safe(mpcb, mptcp, tmp) { -+ struct sock *sk = mptcp_to_sock(mptcp); -+ -+ if ((event->family == AF_INET6 && -+ (sk->sk_family == AF_INET || -+ mptcp_v6_is_v4_mapped(sk))) || -+ (event->family == AF_INET && -+ (sk->sk_family == AF_INET6 && -+ !mptcp_v6_is_v4_mapped(sk)))) -+ continue; -+ -+ if (event->family == AF_INET && -+ (sk->sk_family == AF_INET || -+ mptcp_v6_is_v4_mapped(sk)) && -+ inet_sk(sk)->inet_saddr != event->addr.in.s_addr) -+ continue; -+ -+ if (event->family == AF_INET6 && -+ sk->sk_family == AF_INET6 && -+ !ipv6_addr_equal(&inet6_sk(sk)->saddr, &event->addr.in6)) -+ continue; -+ -+ /* Reinject, so that pf = 1 and so we -+ * won't select this one as the -+ * ack-sock. -+ */ -+ mptcp_reinject_data(sk, 0); -+ -+ /* We announce the removal of this id */ -+ announce_remove_addr(tcp_sk(sk)->mptcp->loc_id, meta_sk); -+ -+ mptcp_sub_force_close(sk); -+ found = true; -+ } -+ -+ if (found) -+ goto next; -+ -+ /* The id may have been given by the event, -+ * matching on a local address. And it may not -+ * have matched on one of the above sockets, -+ * because the client never created a subflow. -+ * So, we have to finally remove it here. -+ */ -+ if (id >= 0) { -+ u8 loc_id = id -+ + (event->family == AF_INET ? 1 : MPTCP_MAX_ADDR); -+ announce_remove_addr(loc_id, meta_sk); -+ } -+ } -+ -+ if (event->code == MPTCP_EVENT_MOD) { -+ struct mptcp_tcp_sock *mptcp; -+ -+ mptcp_for_each_sub(mpcb, mptcp) { -+ struct sock *sk = mptcp_to_sock(mptcp); -+ struct tcp_sock *tp = tcp_sk(sk); -+ if (event->family == AF_INET && -+ (sk->sk_family == AF_INET || -+ mptcp_v6_is_v4_mapped(sk)) && -+ inet_sk(sk)->inet_saddr == event->addr.in.s_addr) { -+ if (event->low_prio != tp->mptcp->low_prio) { -+ tp->mptcp->send_mp_prio = 1; -+ tp->mptcp->low_prio = event->low_prio; -+ -+ tcp_send_ack(sk); -+ } -+ } -+ -+ if (event->family == AF_INET6 && -+ sk->sk_family == AF_INET6 && -+ !ipv6_addr_equal(&inet6_sk(sk)->saddr, &event->addr.in6)) { -+ if (event->low_prio != tp->mptcp->low_prio) { -+ tp->mptcp->send_mp_prio = 1; -+ tp->mptcp->low_prio = event->low_prio; -+ -+ tcp_send_ack(sk); -+ } -+ } -+ } -+ } -+next: -+ bh_unlock_sock(meta_sk); -+ sock_put(meta_sk); -+ } -+ rcu_read_unlock_bh(); -+ } -+ goto next_event; -+} -+ -+static struct mptcp_addr_event *lookup_similar_event(const struct net *net, -+ const struct mptcp_addr_event *event) -+{ -+ struct mptcp_addr_event *eventq; -+ struct mptcp_fm_ns *fm_ns = fm_get_ns(net); -+ -+ list_for_each_entry(eventq, &fm_ns->events, list) { -+ if (eventq->family != event->family) -+ continue; -+ if (eventq->if_idx != event->if_idx) -+ continue; -+ if (event->family == AF_INET) { -+ if (eventq->addr.in.s_addr == event->addr.in.s_addr) -+ return eventq; -+ } else { -+ if (ipv6_addr_equal(&eventq->addr.in6, &event->addr.in6)) -+ return eventq; -+ } -+ } -+ return NULL; -+} -+ -+/* We already hold the net-namespace MPTCP-lock */ -+static void add_pm_event(struct net *net, const struct mptcp_addr_event *event) -+{ -+ struct mptcp_addr_event *eventq = lookup_similar_event(net, event); -+ struct mptcp_fm_ns *fm_ns = fm_get_ns(net); -+ -+ if (eventq) { -+ switch (event->code) { -+ case MPTCP_EVENT_DEL: -+ mptcp_debug("%s del old_code %u\n", __func__, eventq->code); -+ list_del(&eventq->list); -+ kfree(eventq); -+ break; -+ case MPTCP_EVENT_ADD: -+ mptcp_debug("%s add old_code %u\n", __func__, eventq->code); -+ eventq->low_prio = event->low_prio; -+ eventq->code = MPTCP_EVENT_ADD; -+ return; -+ case MPTCP_EVENT_MOD: -+ mptcp_debug("%s mod old_code %u\n", __func__, eventq->code); -+ eventq->low_prio = event->low_prio; -+ eventq->code = MPTCP_EVENT_MOD; -+ return; -+ } -+ } -+ -+ /* OK, we have to add the new address to the wait queue */ -+ eventq = kmemdup(event, sizeof(struct mptcp_addr_event), GFP_ATOMIC); -+ if (!eventq) -+ return; -+ -+ list_add_tail(&eventq->list, &fm_ns->events); -+ -+ /* Create work-queue */ -+ if (!delayed_work_pending(&fm_ns->address_worker)) -+ queue_delayed_work(mptcp_wq, &fm_ns->address_worker, -+ msecs_to_jiffies(500)); -+} -+ -+static void addr4_event_handler(const struct in_ifaddr *ifa, unsigned long event, -+ struct net *net) -+{ -+ const struct net_device *netdev = ifa->ifa_dev->dev; -+ struct mptcp_fm_ns *fm_ns = fm_get_ns(net); -+ struct mptcp_addr_event mpevent; -+ -+ if (ifa->ifa_scope > RT_SCOPE_LINK || -+ ipv4_is_loopback(ifa->ifa_local)) -+ return; -+ -+ spin_lock_bh(&fm_ns->local_lock); -+ -+ mpevent.family = AF_INET; -+ mpevent.addr.in.s_addr = ifa->ifa_local; -+ mpevent.low_prio = (netdev->flags & IFF_MPBACKUP) ? 1 : 0; -+ mpevent.if_idx = netdev->ifindex; -+ -+ if (event == NETDEV_DOWN || !netif_running(netdev) || -+ (netdev->flags & IFF_NOMULTIPATH) || !(netdev->flags & IFF_UP)) -+ mpevent.code = MPTCP_EVENT_DEL; -+ else if (event == NETDEV_UP) -+ mpevent.code = MPTCP_EVENT_ADD; -+ else if (event == NETDEV_CHANGE) -+ mpevent.code = MPTCP_EVENT_MOD; -+ -+ mptcp_debug("%s created event for %pI4, code %u prio %u idx %u\n", __func__, -+ &ifa->ifa_local, mpevent.code, mpevent.low_prio, mpevent.if_idx); -+ add_pm_event(net, &mpevent); -+ -+ spin_unlock_bh(&fm_ns->local_lock); -+ return; -+} -+ -+/* React on IPv4-addr add/rem-events */ -+static int mptcp_pm_inetaddr_event(struct notifier_block *this, -+ unsigned long event, void *ptr) -+{ -+ const struct in_ifaddr *ifa = (struct in_ifaddr *)ptr; -+ struct net *net = dev_net(ifa->ifa_dev->dev); -+ -+ if (!(event == NETDEV_UP || event == NETDEV_DOWN || -+ event == NETDEV_CHANGE)) -+ return NOTIFY_DONE; -+ -+ addr4_event_handler(ifa, event, net); -+ -+ return NOTIFY_DONE; -+} -+ -+static struct notifier_block mptcp_pm_inetaddr_notifier = { -+ .notifier_call = mptcp_pm_inetaddr_event, -+}; -+ -+#if IS_ENABLED(CONFIG_IPV6) -+ -+static int inet6_addr_event(struct notifier_block *this, unsigned long event, -+ void *ptr); -+ -+static void addr6_event_handler(const struct inet6_ifaddr *ifa, unsigned long event, -+ struct net *net) -+{ -+ const struct net_device *netdev = ifa->idev->dev; -+ int addr_type = ipv6_addr_type(&ifa->addr); -+ struct mptcp_fm_ns *fm_ns = fm_get_ns(net); -+ struct mptcp_addr_event mpevent; -+ -+ if (ifa->scope > RT_SCOPE_LINK || -+ addr_type == IPV6_ADDR_ANY || -+ (addr_type & IPV6_ADDR_LOOPBACK) || -+ (addr_type & IPV6_ADDR_LINKLOCAL)) -+ return; -+ -+ spin_lock_bh(&fm_ns->local_lock); -+ -+ mpevent.family = AF_INET6; -+ mpevent.addr.in6 = ifa->addr; -+ mpevent.low_prio = (netdev->flags & IFF_MPBACKUP) ? 1 : 0; -+ mpevent.if_idx = netdev->ifindex; -+ -+ if (event == NETDEV_DOWN || !netif_running(netdev) || -+ (netdev->flags & IFF_NOMULTIPATH) || !(netdev->flags & IFF_UP)) -+ mpevent.code = MPTCP_EVENT_DEL; -+ else if (event == NETDEV_UP) -+ mpevent.code = MPTCP_EVENT_ADD; -+ else if (event == NETDEV_CHANGE) -+ mpevent.code = MPTCP_EVENT_MOD; -+ -+ mptcp_debug("%s created event for %pI6, code %u prio %u idx %u\n", __func__, -+ &ifa->addr, mpevent.code, mpevent.low_prio, mpevent.if_idx); -+ add_pm_event(net, &mpevent); -+ -+ spin_unlock_bh(&fm_ns->local_lock); -+ return; -+} -+ -+/* React on IPv6-addr add/rem-events */ -+static int inet6_addr_event(struct notifier_block *this, unsigned long event, -+ void *ptr) -+{ -+ struct inet6_ifaddr *ifa6 = (struct inet6_ifaddr *)ptr; -+ struct net *net = dev_net(ifa6->idev->dev); -+ -+ if (!(event == NETDEV_UP || event == NETDEV_DOWN || -+ event == NETDEV_CHANGE)) -+ return NOTIFY_DONE; -+ -+ addr6_event_handler(ifa6, event, net); -+ -+ return NOTIFY_DONE; -+} -+ -+static struct notifier_block inet6_addr_notifier = { -+ .notifier_call = inet6_addr_event, -+}; -+ -+#endif -+ -+/* React on ifup/down-events */ -+static int netdev_event(struct notifier_block *this, unsigned long event, -+ void *ptr) -+{ -+ const struct net_device *dev = netdev_notifier_info_to_dev(ptr); -+ struct in_device *in_dev; -+#if IS_ENABLED(CONFIG_IPV6) -+ struct inet6_dev *in6_dev; -+#endif -+ -+ if (!(event == NETDEV_UP || event == NETDEV_DOWN || -+ event == NETDEV_CHANGE)) -+ return NOTIFY_DONE; -+ -+ rcu_read_lock(); -+ in_dev = __in_dev_get_rtnl(dev); -+ -+ if (in_dev) { -+ struct in_ifaddr *ifa; -+ -+ in_dev_for_each_ifa_rcu(ifa, in_dev) { -+ mptcp_pm_inetaddr_event(NULL, event, ifa); -+ } -+ } -+ -+#if IS_ENABLED(CONFIG_IPV6) -+ in6_dev = __in6_dev_get(dev); -+ -+ if (in6_dev) { -+ struct inet6_ifaddr *ifa6; -+ list_for_each_entry(ifa6, &in6_dev->addr_list, if_list) -+ inet6_addr_event(NULL, event, ifa6); -+ } -+#endif -+ -+ rcu_read_unlock(); -+ return NOTIFY_DONE; -+} -+ -+static struct notifier_block mptcp_pm_netdev_notifier = { -+ .notifier_call = netdev_event, -+}; -+ -+static void full_mesh_add_raddr(struct mptcp_cb *mpcb, -+ const union inet_addr *addr, -+ sa_family_t family, __be16 port, u8 id) -+{ -+ if (family == AF_INET) -+ mptcp_addv4_raddr(mpcb, &addr->in, port, id); -+ else -+ mptcp_addv6_raddr(mpcb, &addr->in6, port, id); -+} -+ -+static void full_mesh_new_session(const struct sock *meta_sk) -+{ -+ struct mptcp_loc_addr *mptcp_local; -+ struct mptcp_cb *mpcb = tcp_sk(meta_sk)->mpcb; -+ struct fullmesh_priv *fmp = fullmesh_get_priv(mpcb); -+ const struct mptcp_fm_ns *fm_ns = fm_get_ns(sock_net(meta_sk)); -+ struct tcp_sock *master_tp = tcp_sk(mpcb->master_sk); -+ int i, index, if_idx = 0; -+ union inet_addr saddr, daddr; -+ sa_family_t family = AF_INET; -+ bool meta_v4 = meta_sk->sk_family == AF_INET; -+ -+ /* Init local variables necessary for the rest */ -+ if (meta_sk->sk_family == AF_INET || mptcp_v6_is_v4_mapped(meta_sk)) { -+ saddr.ip = inet_sk(meta_sk)->inet_saddr; -+ daddr.ip = inet_sk(meta_sk)->inet_daddr; -+ if_idx = mpcb->master_sk->sk_bound_dev_if; -+ family = AF_INET; -+#if IS_ENABLED(CONFIG_IPV6) -+ } else { -+ saddr.in6 = inet6_sk(meta_sk)->saddr; -+ daddr.in6 = meta_sk->sk_v6_daddr; -+ if_idx = mpcb->master_sk->sk_bound_dev_if; -+ family = AF_INET6; -+#endif -+ } -+ -+ if (inet_sk(meta_sk)->transparent) -+ if_idx = inet_sk(meta_sk)->rx_dst_ifindex; -+ -+ rcu_read_lock_bh(); -+ mptcp_local = rcu_dereference(fm_ns->local); -+ -+ if (inet_sk(meta_sk)->transparent) -+ index = mptcp_find_address_transp(mptcp_local, family, if_idx); -+ else -+ index = mptcp_find_address(mptcp_local, family, &saddr, if_idx); -+ if (index < 0) -+ goto fallback; -+ -+ if (family == AF_INET) -+ master_tp->mptcp->low_prio = mptcp_local->locaddr4[index].low_prio; -+ else -+ master_tp->mptcp->low_prio = mptcp_local->locaddr6[index].low_prio; -+ master_tp->mptcp->send_mp_prio = master_tp->mptcp->low_prio; -+ -+ full_mesh_add_raddr(mpcb, &daddr, family, 0, 0); -+ mptcp_set_init_addr_bit(mpcb, &daddr, family, index); -+ -+ /* Initialize workqueue-struct */ -+ INIT_WORK(&fmp->subflow_work, create_subflow_worker); -+ INIT_DELAYED_WORK(&fmp->subflow_retry_work, retry_subflow_worker); -+ fmp->mpcb = mpcb; -+ -+ if (!meta_v4 && meta_sk->sk_ipv6only) -+ goto skip_ipv4; -+ -+ /* Look for the address among the local addresses */ -+ mptcp_for_each_bit_set(mptcp_local->loc4_bits, i) { -+ __be32 ifa_address = mptcp_local->locaddr4[i].addr.s_addr; -+ -+ /* We do not need to announce the initial subflow's address again */ -+ if (family == AF_INET && -+ (!if_idx || mptcp_local->locaddr4[i].if_idx == if_idx) && -+ saddr.ip == ifa_address) -+ continue; -+ -+ fmp->add_addr++; -+ mpcb->addr_signal = 1; -+ } -+ -+skip_ipv4: -+#if IS_ENABLED(CONFIG_IPV6) -+ /* skip IPv6 addresses if meta-socket is IPv4 */ -+ if (meta_v4) -+ goto skip_ipv6; -+ -+ mptcp_for_each_bit_set(mptcp_local->loc6_bits, i) { -+ const struct in6_addr *ifa6 = &mptcp_local->locaddr6[i].addr; -+ -+ /* We do not need to announce the initial subflow's address again */ -+ if (family == AF_INET6 && -+ (!if_idx || mptcp_local->locaddr6[i].if_idx == if_idx) && -+ ipv6_addr_equal(&saddr.in6, ifa6)) -+ continue; -+ -+ fmp->add_addr++; -+ mpcb->addr_signal = 1; -+ } -+ -+skip_ipv6: -+#endif -+ -+ rcu_read_unlock_bh(); -+ -+ if (family == AF_INET) -+ fmp->announced_addrs_v4 |= (1 << index); -+ else -+ fmp->announced_addrs_v6 |= (1 << index); -+ -+ for (i = fmp->add_addr; i && fmp->add_addr; i--) -+ tcp_send_ack(mpcb->master_sk); -+ -+ if (master_tp->mptcp->send_mp_prio) -+ tcp_send_ack(mpcb->master_sk); -+ -+ return; -+ -+fallback: -+ rcu_read_unlock_bh(); -+ mptcp_fallback_default(mpcb); -+ return; -+} -+ -+static void full_mesh_create_subflows(struct sock *meta_sk) -+{ -+ struct mptcp_cb *mpcb = tcp_sk(meta_sk)->mpcb; -+ struct fullmesh_priv *fmp = fullmesh_get_priv(mpcb); -+ -+ if (mptcp_in_infinite_mapping_weak(mpcb) || -+ mpcb->server_side || sock_flag(meta_sk, SOCK_DEAD)) -+ return; -+ -+ if (mpcb->master_sk && -+ !tcp_sk(mpcb->master_sk)->mptcp->fully_established) -+ return; -+ -+ if (!work_pending(&fmp->subflow_work)) { -+ sock_hold(meta_sk); -+ refcount_inc(&mpcb->mpcb_refcnt); -+ queue_work(mptcp_wq, &fmp->subflow_work); -+ } -+} -+ -+/* Called upon release_sock, if the socket was owned by the user during -+ * a path-management event. -+ */ -+static void full_mesh_release_sock(struct sock *meta_sk) -+{ -+ struct mptcp_loc_addr *mptcp_local; -+ struct mptcp_cb *mpcb = tcp_sk(meta_sk)->mpcb; -+ struct fullmesh_priv *fmp = fullmesh_get_priv(mpcb); -+ const struct mptcp_fm_ns *fm_ns = fm_get_ns(sock_net(meta_sk)); -+ bool meta_v4 = meta_sk->sk_family == AF_INET; -+ struct mptcp_tcp_sock *mptcp; -+ struct hlist_node *tmp; -+ int i; -+ -+ rcu_read_lock_bh(); -+ mptcp_local = rcu_dereference(fm_ns->local); -+ -+ if (!meta_v4 && meta_sk->sk_ipv6only) -+ goto skip_ipv4; -+ -+ /* First, detect modifications or additions */ -+ mptcp_for_each_bit_set(mptcp_local->loc4_bits, i) { -+ struct in_addr ifa = mptcp_local->locaddr4[i].addr; -+ bool found = false; -+ -+ mptcp_for_each_sub(mpcb, mptcp) { -+ struct sock *sk = mptcp_to_sock(mptcp); -+ struct tcp_sock *tp = tcp_sk(sk); -+ -+ if (sk->sk_family == AF_INET6 && -+ !mptcp_v6_is_v4_mapped(sk)) -+ continue; -+ -+ if (inet_sk(sk)->inet_saddr != ifa.s_addr) -+ continue; -+ -+ found = true; -+ -+ if (mptcp_local->locaddr4[i].low_prio != tp->mptcp->low_prio) { -+ tp->mptcp->send_mp_prio = 1; -+ tp->mptcp->low_prio = mptcp_local->locaddr4[i].low_prio; -+ -+ tcp_send_ack(sk); -+ } -+ } -+ -+ if (!found) { -+ struct sock *sk; -+ -+ fmp->add_addr++; -+ mpcb->addr_signal = 1; -+ -+ sk = mptcp_select_ack_sock(meta_sk); -+ if (sk) -+ tcp_send_ack(sk); -+ full_mesh_create_subflows(meta_sk); -+ } -+ } -+ -+skip_ipv4: -+#if IS_ENABLED(CONFIG_IPV6) -+ /* skip IPv6 addresses if meta-socket is IPv4 */ -+ if (meta_v4) -+ goto removal; -+ -+ mptcp_for_each_bit_set(mptcp_local->loc6_bits, i) { -+ struct in6_addr ifa = mptcp_local->locaddr6[i].addr; -+ bool found = false; -+ -+ mptcp_for_each_sub(mpcb, mptcp) { -+ struct sock *sk = mptcp_to_sock(mptcp); -+ struct tcp_sock *tp = tcp_sk(sk); -+ -+ if (sk->sk_family == AF_INET || -+ mptcp_v6_is_v4_mapped(sk)) -+ continue; -+ -+ if (!ipv6_addr_equal(&inet6_sk(sk)->saddr, &ifa)) -+ continue; -+ -+ found = true; -+ -+ if (mptcp_local->locaddr6[i].low_prio != tp->mptcp->low_prio) { -+ tp->mptcp->send_mp_prio = 1; -+ tp->mptcp->low_prio = mptcp_local->locaddr6[i].low_prio; -+ -+ tcp_send_ack(sk); -+ } -+ } -+ -+ if (!found) { -+ struct sock *sk; -+ -+ fmp->add_addr++; -+ mpcb->addr_signal = 1; -+ -+ sk = mptcp_select_ack_sock(meta_sk); -+ if (sk) -+ tcp_send_ack(sk); -+ full_mesh_create_subflows(meta_sk); -+ } -+ } -+ -+removal: -+#endif -+ -+ /* Now, detect address-removals */ -+ mptcp_for_each_sub_safe(mpcb, mptcp, tmp) { -+ struct sock *sk = mptcp_to_sock(mptcp); -+ bool shall_remove = true; -+ -+ if (sk->sk_family == AF_INET || mptcp_v6_is_v4_mapped(sk)) { -+ mptcp_for_each_bit_set(mptcp_local->loc4_bits, i) { -+ if (inet_sk(sk)->inet_saddr == mptcp_local->locaddr4[i].addr.s_addr) { -+ shall_remove = false; -+ break; -+ } -+ } -+ } else { -+ mptcp_for_each_bit_set(mptcp_local->loc6_bits, i) { -+ if (ipv6_addr_equal(&inet6_sk(sk)->saddr, &mptcp_local->locaddr6[i].addr)) { -+ shall_remove = false; -+ break; -+ } -+ } -+ } -+ -+ if (shall_remove) { -+ /* Reinject, so that pf = 1 and so we -+ * won't select this one as the -+ * ack-sock. -+ */ -+ mptcp_reinject_data(sk, 0); -+ -+ announce_remove_addr(tcp_sk(sk)->mptcp->loc_id, -+ meta_sk); -+ -+ mptcp_sub_force_close(sk); -+ } -+ } -+ -+ /* Just call it optimistically. It actually cannot do any harm */ -+ update_addr_bitfields(meta_sk, mptcp_local); -+ -+ rcu_read_unlock_bh(); -+} -+ -+static int full_mesh_get_local_id(const struct sock *meta_sk, -+ sa_family_t family, union inet_addr *addr, -+ bool *low_prio) -+{ -+ struct mptcp_loc_addr *mptcp_local; -+ const struct mptcp_fm_ns *fm_ns = fm_get_ns(sock_net(meta_sk)); -+ int index, id = -1; -+ -+ /* Handle the backup-flows */ -+ rcu_read_lock_bh(); -+ mptcp_local = rcu_dereference(fm_ns->local); -+ -+ index = mptcp_find_address(mptcp_local, family, addr, 0); -+ -+ if (index != -1) { -+ if (family == AF_INET) { -+ id = mptcp_local->locaddr4[index].loc4_id; -+ *low_prio = mptcp_local->locaddr4[index].low_prio; -+ } else { -+ id = mptcp_local->locaddr6[index].loc6_id; -+ *low_prio = mptcp_local->locaddr6[index].low_prio; -+ } -+ } -+ -+ -+ rcu_read_unlock_bh(); -+ -+ return id; -+} -+ -+static void full_mesh_addr_signal(struct sock *sk, unsigned *size, -+ struct tcp_out_options *opts, -+ struct sk_buff *skb) -+{ -+ const struct tcp_sock *tp = tcp_sk(sk); -+ struct mptcp_cb *mpcb = tp->mpcb; -+ struct sock *meta_sk = mpcb->meta_sk; -+ struct fullmesh_priv *fmp = fullmesh_get_priv(mpcb); -+ struct mptcp_loc_addr *mptcp_local; -+ struct mptcp_fm_ns *fm_ns = fm_get_ns(sock_net(sk)); -+ int remove_addr_len; -+ u8 unannouncedv4 = 0, unannouncedv6 = 0; -+ bool meta_v4 = meta_sk->sk_family == AF_INET; -+ -+ mpcb->addr_signal = 0; -+ -+ if (likely(!fmp->add_addr)) -+ goto remove_addr; -+ -+ rcu_read_lock_bh(); -+ mptcp_local = rcu_dereference(fm_ns->local); -+ -+ if (!meta_v4 && meta_sk->sk_ipv6only) -+ goto skip_ipv4; -+ -+ /* IPv4 */ -+ unannouncedv4 = (~fmp->announced_addrs_v4) & mptcp_local->loc4_bits; -+ if (unannouncedv4 && -+ ((mpcb->mptcp_ver == MPTCP_VERSION_0 && -+ MAX_TCP_OPTION_SPACE - *size >= MPTCP_SUB_LEN_ADD_ADDR4_ALIGN) || -+ (mpcb->mptcp_ver >= MPTCP_VERSION_1 && -+ MAX_TCP_OPTION_SPACE - *size >= MPTCP_SUB_LEN_ADD_ADDR4_ALIGN_VER1))) { -+ int ind = mptcp_find_free_index(~unannouncedv4); -+ -+ opts->options |= OPTION_MPTCP; -+ opts->mptcp_options |= OPTION_ADD_ADDR; -+ opts->add_addr4.addr_id = mptcp_local->locaddr4[ind].loc4_id; -+ opts->add_addr4.addr = mptcp_local->locaddr4[ind].addr; -+ opts->add_addr_v4 = 1; -+ if (mpcb->mptcp_ver >= MPTCP_VERSION_1) { -+ u8 mptcp_hash_mac[SHA256_DIGEST_SIZE]; -+ -+ mptcp_hmac(mpcb->mptcp_ver, (u8 *)&mpcb->mptcp_loc_key, -+ (u8 *)&mpcb->mptcp_rem_key, mptcp_hash_mac, 2, -+ 1, (u8 *)&mptcp_local->locaddr4[ind].loc4_id, -+ 4, (u8 *)&opts->add_addr4.addr.s_addr); -+ opts->add_addr4.trunc_mac = *(u64 *)&mptcp_hash_mac[SHA256_DIGEST_SIZE - sizeof(u64)]; -+ } -+ -+ if (skb) { -+ fmp->announced_addrs_v4 |= (1 << ind); -+ fmp->add_addr--; -+ } -+ -+ if (mpcb->mptcp_ver < MPTCP_VERSION_1) -+ *size += MPTCP_SUB_LEN_ADD_ADDR4_ALIGN; -+ if (mpcb->mptcp_ver >= MPTCP_VERSION_1) -+ *size += MPTCP_SUB_LEN_ADD_ADDR4_ALIGN_VER1; -+ -+ goto skip_ipv6; -+ } -+ -+ if (meta_v4) -+ goto skip_ipv6; -+skip_ipv4: -+ /* IPv6 */ -+ unannouncedv6 = (~fmp->announced_addrs_v6) & mptcp_local->loc6_bits; -+ if (unannouncedv6 && -+ ((mpcb->mptcp_ver == MPTCP_VERSION_0 && -+ MAX_TCP_OPTION_SPACE - *size >= MPTCP_SUB_LEN_ADD_ADDR6_ALIGN) || -+ (mpcb->mptcp_ver >= MPTCP_VERSION_1 && -+ MAX_TCP_OPTION_SPACE - *size >= MPTCP_SUB_LEN_ADD_ADDR6_ALIGN_VER1))) { -+ int ind = mptcp_find_free_index(~unannouncedv6); -+ -+ opts->options |= OPTION_MPTCP; -+ opts->mptcp_options |= OPTION_ADD_ADDR; -+ opts->add_addr6.addr_id = mptcp_local->locaddr6[ind].loc6_id; -+ opts->add_addr6.addr = mptcp_local->locaddr6[ind].addr; -+ opts->add_addr_v6 = 1; -+ if (mpcb->mptcp_ver >= MPTCP_VERSION_1) { -+ u8 mptcp_hash_mac[SHA256_DIGEST_SIZE]; -+ -+ mptcp_hmac(mpcb->mptcp_ver, (u8 *)&mpcb->mptcp_loc_key, -+ (u8 *)&mpcb->mptcp_rem_key, mptcp_hash_mac, 2, -+ 1, (u8 *)&mptcp_local->locaddr6[ind].loc6_id, -+ 16, (u8 *)&opts->add_addr6.addr.s6_addr); -+ opts->add_addr6.trunc_mac = *(u64 *)&mptcp_hash_mac[SHA256_DIGEST_SIZE - sizeof(u64)]; -+ } -+ -+ if (skb) { -+ fmp->announced_addrs_v6 |= (1 << ind); -+ fmp->add_addr--; -+ } -+ if (mpcb->mptcp_ver < MPTCP_VERSION_1) -+ *size += MPTCP_SUB_LEN_ADD_ADDR6_ALIGN; -+ if (mpcb->mptcp_ver >= MPTCP_VERSION_1) -+ *size += MPTCP_SUB_LEN_ADD_ADDR6_ALIGN_VER1; -+ } -+ -+skip_ipv6: -+ rcu_read_unlock_bh(); -+ -+ if (!unannouncedv4 && !unannouncedv6 && skb) -+ fmp->add_addr--; -+ -+remove_addr: -+ if (likely(!fmp->remove_addrs)) -+ goto exit; -+ -+ remove_addr_len = mptcp_sub_len_remove_addr_align(fmp->remove_addrs); -+ if (MAX_TCP_OPTION_SPACE - *size < remove_addr_len) -+ goto exit; -+ -+ opts->options |= OPTION_MPTCP; -+ opts->mptcp_options |= OPTION_REMOVE_ADDR; -+ opts->remove_addrs = fmp->remove_addrs; -+ *size += remove_addr_len; -+ if (skb) -+ fmp->remove_addrs = 0; -+ -+exit: -+ mpcb->addr_signal = !!(fmp->add_addr || fmp->remove_addrs); -+} -+ -+static void full_mesh_rem_raddr(struct mptcp_cb *mpcb, u8 rem_id) -+{ -+ mptcp_v4_rem_raddress(mpcb, rem_id); -+ mptcp_v6_rem_raddress(mpcb, rem_id); -+} -+ -+static void full_mesh_delete_subflow(struct sock *sk) -+{ -+ struct fullmesh_priv *fmp = fullmesh_get_priv(tcp_sk(sk)->mpcb); -+ struct mptcp_fm_ns *fm_ns = fm_get_ns(sock_net(sk)); -+ struct sock *meta_sk = mptcp_meta_sk(sk); -+ struct mptcp_loc_addr *mptcp_local; -+ int index, i; -+ -+ if (!create_on_err) -+ return; -+ -+ if (!mptcp_can_new_subflow(meta_sk)) -+ return; -+ -+ rcu_read_lock_bh(); -+ mptcp_local = rcu_dereference_bh(fm_ns->local); -+ -+ if (sk->sk_family == AF_INET || mptcp_v6_is_v4_mapped(sk)) { -+ union inet_addr saddr; -+ -+ saddr.ip = inet_sk(sk)->inet_saddr; -+ index = mptcp_find_address(mptcp_local, AF_INET, &saddr, -+ sk->sk_bound_dev_if); -+ if (index < 0) -+ goto out; -+ -+ mptcp_for_each_bit_set(fmp->rem4_bits, i) { -+ struct fullmesh_rem4 *rem4 = &fmp->remaddr4[i]; -+ -+ if (rem4->addr.s_addr != sk->sk_daddr) -+ continue; -+ -+ if (rem4->port && rem4->port != inet_sk(sk)->inet_dport) -+ continue; -+ -+ rem4->bitfield &= ~(1 << index); -+ } -+#if IS_ENABLED(CONFIG_IPV6) -+ } else { -+ union inet_addr saddr; -+ -+ saddr.in6 = inet6_sk(sk)->saddr; -+ index = mptcp_find_address(mptcp_local, AF_INET6, &saddr, -+ sk->sk_bound_dev_if); -+ if (index < 0) -+ goto out; -+ -+ mptcp_for_each_bit_set(fmp->rem6_bits, i) { -+ struct fullmesh_rem6 *rem6 = &fmp->remaddr6[i]; -+ -+ if (!ipv6_addr_equal(&rem6->addr, &sk->sk_v6_daddr)) -+ continue; -+ -+ if (rem6->port && rem6->port != inet_sk(sk)->inet_dport) -+ continue; -+ -+ rem6->bitfield &= ~(1 << index); -+ } -+#endif -+ } -+ -+out: -+ rcu_read_unlock_bh(); -+ -+ /* re-schedule the creation of failed subflows */ -+ if (tcp_sk(sk)->mptcp->sk_err == ETIMEDOUT || sk->sk_err == ETIMEDOUT) -+ full_mesh_create_subflows(meta_sk); -+} -+ -+/* Output /proc/net/mptcp_fullmesh */ -+static int mptcp_fm_seq_show(struct seq_file *seq, void *v) -+{ -+ const struct net *net = seq->private; -+ struct mptcp_loc_addr *mptcp_local; -+ const struct mptcp_fm_ns *fm_ns = fm_get_ns(net); -+ int i; -+ -+ seq_printf(seq, "Index, Address-ID, Backup, IP-address, if-idx\n"); -+ -+ rcu_read_lock_bh(); -+ mptcp_local = rcu_dereference(fm_ns->local); -+ -+ seq_printf(seq, "IPv4, next v4-index: %u\n", mptcp_local->next_v4_index); -+ -+ mptcp_for_each_bit_set(mptcp_local->loc4_bits, i) { -+ struct mptcp_loc4 *loc4 = &mptcp_local->locaddr4[i]; -+ -+ seq_printf(seq, "%u, %u, %u, %pI4, %u\n", i, loc4->loc4_id, -+ loc4->low_prio, &loc4->addr, loc4->if_idx); -+ } -+ -+ seq_printf(seq, "IPv6, next v6-index: %u\n", mptcp_local->next_v6_index); -+ -+ mptcp_for_each_bit_set(mptcp_local->loc6_bits, i) { -+ struct mptcp_loc6 *loc6 = &mptcp_local->locaddr6[i]; -+ -+ seq_printf(seq, "%u, %u, %u, %pI6, %u\n", i, loc6->loc6_id, -+ loc6->low_prio, &loc6->addr, loc6->if_idx); -+ } -+ rcu_read_unlock_bh(); -+ -+ return 0; -+} -+ -+static int mptcp_fm_init_net(struct net *net) -+{ -+ struct mptcp_loc_addr *mptcp_local; -+ struct mptcp_fm_ns *fm_ns; -+ int err = 0; -+ -+ fm_ns = kzalloc(sizeof(*fm_ns), GFP_KERNEL); -+ if (!fm_ns) -+ return -ENOBUFS; -+ -+ mptcp_local = kzalloc(sizeof(*mptcp_local), GFP_KERNEL); -+ if (!mptcp_local) { -+ err = -ENOBUFS; -+ goto err_mptcp_local; -+ } -+ -+ if (!proc_create_net_single("mptcp_fullmesh", S_IRUGO, net->proc_net, -+ mptcp_fm_seq_show, NULL)) { -+ err = -ENOMEM; -+ goto err_seq_fops; -+ } -+ -+ mptcp_local->next_v4_index = 1; -+ -+ rcu_assign_pointer(fm_ns->local, mptcp_local); -+ INIT_DELAYED_WORK(&fm_ns->address_worker, mptcp_address_worker); -+ INIT_LIST_HEAD(&fm_ns->events); -+ spin_lock_init(&fm_ns->local_lock); -+ fm_ns->net = net; -+ net->mptcp.path_managers[MPTCP_PM_FULLMESH] = fm_ns; -+ -+ return 0; -+err_seq_fops: -+ kfree(mptcp_local); -+err_mptcp_local: -+ kfree(fm_ns); -+ return err; -+} -+ -+static void mptcp_fm_exit_net(struct net *net) -+{ -+ struct mptcp_addr_event *eventq, *tmp; -+ struct mptcp_fm_ns *fm_ns; -+ struct mptcp_loc_addr *mptcp_local; -+ -+ fm_ns = fm_get_ns(net); -+ cancel_delayed_work_sync(&fm_ns->address_worker); -+ -+ rcu_read_lock_bh(); -+ -+ mptcp_local = rcu_dereference_bh(fm_ns->local); -+ kfree_rcu(mptcp_local, rcu); -+ -+ spin_lock(&fm_ns->local_lock); -+ list_for_each_entry_safe(eventq, tmp, &fm_ns->events, list) { -+ list_del(&eventq->list); -+ kfree(eventq); -+ } -+ spin_unlock(&fm_ns->local_lock); -+ -+ rcu_read_unlock_bh(); -+ -+ remove_proc_entry("mptcp_fullmesh", net->proc_net); -+ -+ kfree(fm_ns); -+} -+ -+static struct pernet_operations full_mesh_net_ops = { -+ .init = mptcp_fm_init_net, -+ .exit = mptcp_fm_exit_net, -+}; -+ -+static struct mptcp_pm_ops full_mesh __read_mostly = { -+ .new_session = full_mesh_new_session, -+ .release_sock = full_mesh_release_sock, -+ .fully_established = full_mesh_create_subflows, -+ .new_remote_address = full_mesh_create_subflows, -+ .get_local_id = full_mesh_get_local_id, -+ .addr_signal = full_mesh_addr_signal, -+ .add_raddr = full_mesh_add_raddr, -+ .rem_raddr = full_mesh_rem_raddr, -+ .delete_subflow = full_mesh_delete_subflow, -+ .name = "fullmesh", -+ .owner = THIS_MODULE, -+}; -+ -+/* General initialization of MPTCP_PM */ -+static int __init full_mesh_register(void) -+{ -+ int ret; -+ -+ BUILD_BUG_ON(sizeof(struct fullmesh_priv) > MPTCP_PM_SIZE); -+ -+ ret = register_pernet_subsys(&full_mesh_net_ops); -+ if (ret) -+ goto out; -+ -+ ret = register_inetaddr_notifier(&mptcp_pm_inetaddr_notifier); -+ if (ret) -+ goto err_reg_inetaddr; -+ ret = register_netdevice_notifier(&mptcp_pm_netdev_notifier); -+ if (ret) -+ goto err_reg_netdev; -+ -+#if IS_ENABLED(CONFIG_IPV6) -+ ret = register_inet6addr_notifier(&inet6_addr_notifier); -+ if (ret) -+ goto err_reg_inet6addr; -+#endif -+ -+ ret = mptcp_register_path_manager(&full_mesh); -+ if (ret) -+ goto err_reg_pm; -+ -+out: -+ return ret; -+ -+ -+err_reg_pm: -+#if IS_ENABLED(CONFIG_IPV6) -+ unregister_inet6addr_notifier(&inet6_addr_notifier); -+err_reg_inet6addr: -+#endif -+ unregister_netdevice_notifier(&mptcp_pm_netdev_notifier); -+err_reg_netdev: -+ unregister_inetaddr_notifier(&mptcp_pm_inetaddr_notifier); -+err_reg_inetaddr: -+ unregister_pernet_subsys(&full_mesh_net_ops); -+ goto out; -+} -+ -+static void full_mesh_unregister(void) -+{ -+#if IS_ENABLED(CONFIG_IPV6) -+ unregister_inet6addr_notifier(&inet6_addr_notifier); -+#endif -+ unregister_netdevice_notifier(&mptcp_pm_netdev_notifier); -+ unregister_inetaddr_notifier(&mptcp_pm_inetaddr_notifier); -+ unregister_pernet_subsys(&full_mesh_net_ops); -+ mptcp_unregister_path_manager(&full_mesh); -+} -+ -+module_init(full_mesh_register); -+module_exit(full_mesh_unregister); -+ -+MODULE_AUTHOR("Christoph Paasch"); -+MODULE_LICENSE("GPL"); -+MODULE_DESCRIPTION("Full-Mesh MPTCP"); -+MODULE_VERSION("0.88"); -diff -aurN linux-5.4.64/net/mptcp/mptcp_input.c linux-5.4.64.mptcp/net/mptcp/mptcp_input.c ---- linux-5.4.64/net/mptcp/mptcp_input.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-5.4.64.mptcp/net/mptcp/mptcp_input.c 2020-09-10 19:25:10.507220869 +0200 -@@ -0,0 +1,2531 @@ -+/* -+ * MPTCP implementation - Sending side -+ * -+ * Initial Design & Implementation: -+ * Sébastien Barré -+ * -+ * Current Maintainer & Author: -+ * Christoph Paasch -+ * -+ * Additional authors: -+ * Jaakko Korkeaniemi -+ * Gregory Detal -+ * Fabien Duchêne -+ * Andreas Seelinger -+ * Lavkesh Lahngir -+ * Andreas Ripke -+ * Vlad Dogaru -+ * Octavian Purdila -+ * John Ronan -+ * Catalin Nicutar -+ * Brandon Heller -+ * -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version -+ * 2 of the License, or (at your option) any later version. -+ */ -+ -+#include -+ -+#include -+#include -+#include -+ -+#include -+ -+/* is seq1 < seq2 ? */ -+static inline bool before64(const u64 seq1, const u64 seq2) -+{ -+ return (s64)(seq1 - seq2) < 0; -+} -+ -+/* is seq1 > seq2 ? */ -+#define after64(seq1, seq2) before64(seq2, seq1) -+ -+static inline void mptcp_become_fully_estab(struct sock *sk) -+{ -+ tcp_sk(sk)->mptcp->fully_established = 1; -+ -+ if (is_master_tp(tcp_sk(sk)) && -+ tcp_sk(sk)->mpcb->pm_ops->fully_established) -+ tcp_sk(sk)->mpcb->pm_ops->fully_established(mptcp_meta_sk(sk)); -+} -+ -+/* Similar to tcp_tso_acked without any memory accounting */ -+static inline int mptcp_tso_acked_reinject(const struct sock *meta_sk, -+ struct sk_buff *skb) -+{ -+ const struct tcp_sock *meta_tp = tcp_sk(meta_sk); -+ u32 packets_acked, len, delta_truesize; -+ -+ BUG_ON(!after(TCP_SKB_CB(skb)->end_seq, meta_tp->snd_una)); -+ -+ packets_acked = tcp_skb_pcount(skb); -+ -+ if (skb_unclone(skb, GFP_ATOMIC)) -+ return 0; -+ -+ len = meta_tp->snd_una - TCP_SKB_CB(skb)->seq; -+ delta_truesize = __pskb_trim_head(skb, len); -+ -+ TCP_SKB_CB(skb)->seq += len; -+ skb->ip_summed = CHECKSUM_PARTIAL; -+ -+ if (delta_truesize) -+ skb->truesize -= delta_truesize; -+ -+ /* Any change of skb->len requires recalculation of tso factor. */ -+ if (tcp_skb_pcount(skb) > 1) -+ tcp_set_skb_tso_segs(skb, tcp_skb_mss(skb)); -+ packets_acked -= tcp_skb_pcount(skb); -+ -+ if (packets_acked) { -+ BUG_ON(tcp_skb_pcount(skb) == 0); -+ BUG_ON(!before(TCP_SKB_CB(skb)->seq, TCP_SKB_CB(skb)->end_seq)); -+ } -+ -+ return packets_acked; -+} -+ -+/* Cleans the meta-socket retransmission queue and the reinject-queue. */ -+static void mptcp_clean_rtx_queue(struct sock *meta_sk, u32 prior_snd_una) -+{ -+ struct sk_buff *skb, *tmp, *next; -+ struct tcp_sock *meta_tp = tcp_sk(meta_sk); -+ struct mptcp_cb *mpcb = meta_tp->mpcb; -+ bool fully_acked = true; -+ bool acked = false; -+ u32 acked_pcount; -+ -+ for (skb = skb_rb_first(&meta_sk->tcp_rtx_queue); skb; skb = next) { -+ struct tcp_skb_cb *scb = TCP_SKB_CB(skb); -+ -+ tcp_ack_tstamp(meta_sk, skb, prior_snd_una); -+ -+ if (after(scb->end_seq, meta_tp->snd_una)) { -+ if (tcp_skb_pcount(skb) == 1 || -+ !after(meta_tp->snd_una, scb->seq)) -+ break; -+ -+ acked_pcount = tcp_tso_acked(meta_sk, skb); -+ if (!acked_pcount) -+ break; -+ fully_acked = false; -+ } else { -+ acked_pcount = tcp_skb_pcount(skb); -+ } -+ -+ acked = true; -+ meta_tp->packets_out -= acked_pcount; -+ meta_tp->retrans_stamp = 0; -+ -+ if (!fully_acked) -+ break; -+ -+ next = skb_rb_next(skb); -+ -+ if (mptcp_is_data_fin(skb)) { -+ struct mptcp_tcp_sock *mptcp; -+ struct hlist_node *tmp; -+ -+ /* DATA_FIN has been acknowledged - now we can close -+ * the subflows -+ */ -+ mptcp_for_each_sub_safe(mpcb, mptcp, tmp) { -+ struct sock *sk_it = mptcp_to_sock(mptcp); -+ unsigned long delay = 0; -+ -+ /* If we are the passive closer, don't trigger -+ * subflow-fin until the subflow has been finned -+ * by the peer - thus we add a delay. -+ */ -+ if (mpcb->passive_close && -+ sk_it->sk_state == TCP_ESTABLISHED) -+ delay = inet_csk(sk_it)->icsk_rto << 3; -+ -+ mptcp_sub_close(sk_it, delay); -+ } -+ } -+ tcp_rtx_queue_unlink_and_free(skb, meta_sk); -+ } -+ /* Remove acknowledged data from the reinject queue */ -+ skb_queue_walk_safe(&mpcb->reinject_queue, skb, tmp) { -+ if (before(meta_tp->snd_una, TCP_SKB_CB(skb)->end_seq)) { -+ if (tcp_skb_pcount(skb) == 1 || -+ !after(meta_tp->snd_una, TCP_SKB_CB(skb)->seq)) -+ break; -+ -+ mptcp_tso_acked_reinject(meta_sk, skb); -+ break; -+ } -+ -+ __skb_unlink(skb, &mpcb->reinject_queue); -+ __kfree_skb(skb); -+ } -+ -+ if (likely(between(meta_tp->snd_up, prior_snd_una, meta_tp->snd_una))) -+ meta_tp->snd_up = meta_tp->snd_una; -+ -+ if (acked) { -+ tcp_rearm_rto(meta_sk); -+ /* Normally this is done in tcp_try_undo_loss - but MPTCP -+ * does not call this function. -+ */ -+ inet_csk(meta_sk)->icsk_retransmits = 0; -+ } -+} -+ -+/* Inspired by tcp_rcv_state_process */ -+/* Returns 0 if processing the packet can continue -+ * -1 if connection was closed with an active reset -+ * 1 if connection was closed and processing should stop. -+ */ -+static int mptcp_rcv_state_process(struct sock *meta_sk, struct sock *sk, -+ const struct sk_buff *skb, u32 data_seq, -+ u16 data_len) -+{ -+ struct tcp_sock *meta_tp = tcp_sk(meta_sk), *tp = tcp_sk(sk); -+ const struct tcphdr *th = tcp_hdr(skb); -+ -+ /* State-machine handling if FIN has been enqueued and he has -+ * been acked (snd_una == write_seq) - it's important that this -+ * here is after sk_wmem_free_skb because otherwise -+ * sk_forward_alloc is wrong upon inet_csk_destroy_sock() -+ */ -+ switch (meta_sk->sk_state) { -+ case TCP_FIN_WAIT1: { -+ struct dst_entry *dst; -+ int tmo; -+ -+ if (meta_tp->snd_una != meta_tp->write_seq) -+ break; -+ -+ tcp_set_state(meta_sk, TCP_FIN_WAIT2); -+ meta_sk->sk_shutdown |= SEND_SHUTDOWN; -+ -+ dst = __sk_dst_get(sk); -+ if (dst) -+ dst_confirm(dst); -+ -+ if (!sock_flag(meta_sk, SOCK_DEAD)) { -+ /* Wake up lingering close() */ -+ meta_sk->sk_state_change(meta_sk); -+ break; -+ } -+ -+ if (meta_tp->linger2 < 0 || -+ (data_len && -+ after(data_seq + data_len - (mptcp_is_data_fin2(skb, tp) ? 1 : 0), -+ meta_tp->rcv_nxt))) { -+ mptcp_send_active_reset(meta_sk, GFP_ATOMIC); -+ tcp_done(meta_sk); -+ __NET_INC_STATS(sock_net(meta_sk), LINUX_MIB_TCPABORTONDATA); -+ return -1; -+ } -+ -+ tmo = tcp_fin_time(meta_sk); -+ if (tmo > TCP_TIMEWAIT_LEN) { -+ inet_csk_reset_keepalive_timer(meta_sk, tmo - TCP_TIMEWAIT_LEN); -+ } else if (mptcp_is_data_fin2(skb, tp) || sock_owned_by_user(meta_sk)) { -+ /* Bad case. We could lose such FIN otherwise. -+ * It is not a big problem, but it looks confusing -+ * and not so rare event. We still can lose it now, -+ * if it spins in bh_lock_sock(), but it is really -+ * marginal case. -+ */ -+ inet_csk_reset_keepalive_timer(meta_sk, tmo); -+ } else { -+ meta_tp->ops->time_wait(meta_sk, TCP_FIN_WAIT2, tmo); -+ } -+ break; -+ } -+ case TCP_CLOSING: -+ case TCP_LAST_ACK: -+ if (meta_tp->snd_una == meta_tp->write_seq) { -+ tcp_done(meta_sk); -+ return 1; -+ } -+ break; -+ } -+ -+ /* step 7: process the segment text */ -+ switch (meta_sk->sk_state) { -+ case TCP_FIN_WAIT1: -+ case TCP_FIN_WAIT2: -+ /* RFC 793 says to queue data in these states, -+ * RFC 1122 says we MUST send a reset. -+ * BSD 4.4 also does reset. -+ */ -+ if (meta_sk->sk_shutdown & RCV_SHUTDOWN) { -+ if (TCP_SKB_CB(skb)->end_seq != TCP_SKB_CB(skb)->seq && -+ after(TCP_SKB_CB(skb)->end_seq - th->fin, tp->rcv_nxt) && -+ !mptcp_is_data_fin2(skb, tp)) { -+ __NET_INC_STATS(sock_net(meta_sk), LINUX_MIB_TCPABORTONDATA); -+ mptcp_send_active_reset(meta_sk, GFP_ATOMIC); -+ tcp_reset(meta_sk); -+ return -1; -+ } -+ } -+ break; -+ } -+ -+ return 0; -+} -+ -+/** -+ * @return: -+ * i) 1: Everything's fine. -+ * ii) -1: A reset has been sent on the subflow - csum-failure -+ * iii) 0: csum-failure but no reset sent, because it's the last subflow. -+ * Last packet should not be destroyed by the caller because it has -+ * been done here. -+ */ -+static int mptcp_verif_dss_csum(struct sock *sk) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct sk_buff *tmp, *tmp1, *last = NULL; -+ __wsum csum_tcp = 0; /* cumulative checksum of pld + mptcp-header */ -+ int ans = 1, overflowed = 0, offset = 0, dss_csum_added = 0; -+ int iter = 0; -+ u32 next_seq, offset_seq; -+ -+ skb_queue_walk_safe(&sk->sk_receive_queue, tmp, tmp1) { -+ unsigned int csum_len; -+ -+ /* init next seq in first round */ -+ if (!iter) -+ next_seq = TCP_SKB_CB(tmp)->seq; -+ offset_seq = next_seq - TCP_SKB_CB(tmp)->seq; -+ -+ if (before(tp->mptcp->map_subseq + tp->mptcp->map_data_len, TCP_SKB_CB(tmp)->end_seq)) -+ /* Mapping ends in the middle of the packet - -+ * csum only these bytes -+ */ -+ csum_len = tp->mptcp->map_subseq + tp->mptcp->map_data_len - TCP_SKB_CB(tmp)->seq; -+ else -+ csum_len = tmp->len; -+ -+ csum_len -= offset_seq; -+ offset = 0; -+ if (overflowed) { -+ char first_word[4]; -+ first_word[0] = 0; -+ first_word[1] = 0; -+ first_word[2] = 0; -+ first_word[3] = *(tmp->data + offset_seq); -+ csum_tcp = csum_partial(first_word, 4, csum_tcp); -+ offset = 1; -+ csum_len--; -+ overflowed = 0; -+ } -+ -+ csum_tcp = skb_checksum(tmp, offset + offset_seq, csum_len, -+ csum_tcp); -+ -+ /* Was it on an odd-length? Then we have to merge the next byte -+ * correctly (see above) -+ */ -+ if (csum_len != (csum_len & (~1))) -+ overflowed = 1; -+ -+ if (mptcp_is_data_seq(tmp) && !dss_csum_added) { -+ __be32 data_seq = htonl((u32)(tp->mptcp->map_data_seq >> 32)); -+ -+ /* If a 64-bit dss is present, we increase the offset -+ * by 4 bytes, as the high-order 64-bits will be added -+ * in the final csum_partial-call. -+ */ -+ u32 offset = skb_transport_offset(tmp) + -+ TCP_SKB_CB(tmp)->dss_off; -+ if (TCP_SKB_CB(tmp)->mptcp_flags & MPTCPHDR_SEQ64_SET) -+ offset += 4; -+ -+ csum_tcp = skb_checksum(tmp, offset, -+ MPTCP_SUB_LEN_SEQ_CSUM, -+ csum_tcp); -+ -+ csum_tcp = csum_partial(&data_seq, -+ sizeof(data_seq), csum_tcp); -+ -+ dss_csum_added = 1; /* Just do it once */ -+ } else if (mptcp_is_data_mpcapable(tmp) && !dss_csum_added) { -+ u32 offset = skb_transport_offset(tmp) + TCP_SKB_CB(tmp)->dss_off; -+ __be64 data_seq = htonll(tp->mptcp->map_data_seq); -+ __be32 rel_seq = htonl(tp->mptcp->map_subseq - tp->mptcp->rcv_isn); -+ -+ csum_tcp = csum_partial(&data_seq, sizeof(data_seq), csum_tcp); -+ csum_tcp = csum_partial(&rel_seq, sizeof(rel_seq), csum_tcp); -+ -+ csum_tcp = skb_checksum(tmp, offset, 4, csum_tcp); -+ -+ dss_csum_added = 1; -+ } -+ last = tmp; -+ iter++; -+ -+ if (!skb_queue_is_last(&sk->sk_receive_queue, tmp) && -+ !before(TCP_SKB_CB(tmp1)->seq, -+ tp->mptcp->map_subseq + tp->mptcp->map_data_len)) -+ break; -+ next_seq = TCP_SKB_CB(tmp)->end_seq; -+ } -+ -+ /* Now, checksum must be 0 */ -+ if (unlikely(csum_fold(csum_tcp))) { -+ struct mptcp_tcp_sock *mptcp; -+ struct sock *sk_it = NULL; -+ -+ pr_debug("%s csum is wrong: %#x tcp-seq %u dss_csum_added %d overflowed %d iterations %d\n", -+ __func__, csum_fold(csum_tcp), TCP_SKB_CB(last)->seq, -+ dss_csum_added, overflowed, iter); -+ -+ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_CSUMFAIL); -+ tp->mptcp->send_mp_fail = 1; -+ -+ /* map_data_seq is the data-seq number of the -+ * mapping we are currently checking -+ */ -+ tp->mpcb->csum_cutoff_seq = tp->mptcp->map_data_seq; -+ -+ /* Search for another subflow that is fully established */ -+ mptcp_for_each_sub(tp->mpcb, mptcp) { -+ sk_it = mptcp_to_sock(mptcp); -+ -+ if (sk_it != sk && -+ tcp_sk(sk_it)->mptcp->fully_established) -+ break; -+ -+ sk_it = NULL; -+ } -+ -+ if (sk_it) { -+ mptcp_send_reset(sk); -+ ans = -1; -+ } else { -+ tp->mpcb->send_infinite_mapping = 1; -+ -+ /* Need to purge the rcv-queue as it's no more valid */ -+ while ((tmp = __skb_dequeue(&sk->sk_receive_queue)) != NULL) { -+ tp->copied_seq = TCP_SKB_CB(tmp)->end_seq; -+ kfree_skb(tmp); -+ } -+ -+ mptcp_fallback_close(tp->mpcb, sk); -+ -+ ans = 0; -+ } -+ } -+ -+ return ans; -+} -+ -+static inline void mptcp_prepare_skb(struct sk_buff *skb, -+ const struct sock *sk) -+{ -+ const struct tcp_sock *tp = tcp_sk(sk); -+ struct tcp_skb_cb *tcb = TCP_SKB_CB(skb); -+ u32 inc = 0, end_seq = tcb->end_seq; -+ -+ if (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN) -+ end_seq--; -+ /* If skb is the end of this mapping (end is always at mapping-boundary -+ * thanks to the splitting/trimming), then we need to increase -+ * data-end-seq by 1 if this here is a data-fin. -+ * -+ * We need to do -1 because end_seq includes the subflow-FIN. -+ */ -+ if (tp->mptcp->map_data_fin && -+ end_seq == tp->mptcp->map_subseq + tp->mptcp->map_data_len) { -+ inc = 1; -+ -+ /* We manually set the fin-flag if it is a data-fin. For easy -+ * processing in tcp_recvmsg. -+ */ -+ TCP_SKB_CB(skb)->tcp_flags |= TCPHDR_FIN; -+ } else { -+ /* We may have a subflow-fin with data but without data-fin */ -+ TCP_SKB_CB(skb)->tcp_flags &= ~TCPHDR_FIN; -+ } -+ -+ /* Adapt data-seq's to the packet itself. We kinda transform the -+ * dss-mapping to a per-packet granularity. This is necessary to -+ * correctly handle overlapping mappings coming from different -+ * subflows. Otherwise it would be a complete mess. -+ */ -+ tcb->seq = ((u32)tp->mptcp->map_data_seq) + tcb->seq - tp->mptcp->map_subseq; -+ tcb->end_seq = tcb->seq + skb->len + inc; -+} -+ -+static inline void mptcp_reset_mapping(struct tcp_sock *tp, u32 old_copied_seq) -+{ -+ tp->mptcp->map_data_len = 0; -+ tp->mptcp->map_data_seq = 0; -+ tp->mptcp->map_subseq = 0; -+ tp->mptcp->map_data_fin = 0; -+ tp->mptcp->mapping_present = 0; -+ -+ /* In infinite mapping receiver mode, we have to advance the implied -+ * data-sequence number when we progress the subflow's data. -+ */ -+ if (tp->mpcb->infinite_mapping_rcv) -+ tp->mpcb->infinite_rcv_seq += (tp->copied_seq - old_copied_seq); -+} -+ -+/* The DSS-mapping received on the sk only covers the second half of the skb -+ * (cut at seq). We trim the head from the skb. -+ * Data will be freed upon kfree(). -+ * -+ * Inspired by tcp_trim_head(). -+ */ -+static void mptcp_skb_trim_head(struct sk_buff *skb, struct sock *sk, u32 seq) -+{ -+ int len = seq - TCP_SKB_CB(skb)->seq; -+ u32 new_seq = TCP_SKB_CB(skb)->seq + len; -+ u32 delta_truesize; -+ -+ delta_truesize = __pskb_trim_head(skb, len); -+ -+ TCP_SKB_CB(skb)->seq = new_seq; -+ -+ if (delta_truesize) { -+ skb->truesize -= delta_truesize; -+ atomic_sub(delta_truesize, &sk->sk_rmem_alloc); -+ sk_mem_uncharge(sk, delta_truesize); -+ } -+} -+ -+/* The DSS-mapping received on the sk only covers the first half of the skb -+ * (cut at seq). We create a second skb (@return), and queue it in the rcv-queue -+ * as further packets may resolve the mapping of the second half of data. -+ * -+ * Inspired by tcp_fragment(). -+ */ -+static int mptcp_skb_split_tail(struct sk_buff *skb, struct sock *sk, u32 seq) -+{ -+ struct sk_buff *buff; -+ int nsize; -+ int nlen, len; -+ u8 flags; -+ -+ len = seq - TCP_SKB_CB(skb)->seq; -+ nsize = skb_headlen(skb) - len + tcp_sk(sk)->tcp_header_len; -+ if (nsize < 0) -+ nsize = 0; -+ -+ /* Get a new skb... force flag on. */ -+ buff = alloc_skb(nsize, GFP_ATOMIC); -+ if (buff == NULL) -+ return -ENOMEM; -+ -+ skb_reserve(buff, tcp_sk(sk)->tcp_header_len); -+ skb_reset_transport_header(buff); -+ -+ flags = TCP_SKB_CB(skb)->tcp_flags; -+ TCP_SKB_CB(skb)->tcp_flags = flags & ~(TCPHDR_FIN); -+ TCP_SKB_CB(buff)->tcp_flags = flags; -+ -+ /* We absolutly need to call skb_set_owner_r before refreshing the -+ * truesize of buff, otherwise the moved data will account twice. -+ */ -+ skb_set_owner_r(buff, sk); -+ nlen = skb->len - len - nsize; -+ buff->truesize += nlen; -+ skb->truesize -= nlen; -+ -+ /* Correct the sequence numbers. */ -+ TCP_SKB_CB(buff)->seq = TCP_SKB_CB(skb)->seq + len; -+ TCP_SKB_CB(buff)->end_seq = TCP_SKB_CB(skb)->end_seq; -+ TCP_SKB_CB(skb)->end_seq = TCP_SKB_CB(buff)->seq; -+ -+ skb_split(skb, buff, len); -+ -+ __skb_queue_after(&sk->sk_receive_queue, skb, buff); -+ -+ return 0; -+} -+ -+/* @return: 0 everything is fine. Just continue processing -+ * 1 subflow is broken stop everything -+ * -1 this packet was broken - continue with the next one. -+ */ -+static int mptcp_prevalidate_skb(struct sock *sk, struct sk_buff *skb) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct mptcp_cb *mpcb = tp->mpcb; -+ -+ /* If we are in infinite mode, the subflow-fin is in fact a data-fin. */ -+ if (!skb->len && (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN) && -+ !mptcp_is_data_fin(skb) && !mpcb->infinite_mapping_rcv) { -+ /* Remove a pure subflow-fin from the queue and increase -+ * copied_seq. -+ */ -+ tp->copied_seq = TCP_SKB_CB(skb)->end_seq; -+ __skb_unlink(skb, &sk->sk_receive_queue); -+ __kfree_skb(skb); -+ return -1; -+ } -+ -+ /* If we are not yet fully established and do not know the mapping for -+ * this segment, this path has to fallback to infinite or be torn down. -+ */ -+ if (!tp->mptcp->fully_established && !mptcp_is_data_seq(skb) && -+ !mptcp_is_data_mpcapable(skb) && -+ !tp->mptcp->mapping_present && !mpcb->infinite_mapping_rcv) { -+ pr_debug("%s %#x will fallback - pi %d from %pS, seq %u mptcp-flags %#x\n", -+ __func__, mpcb->mptcp_loc_token, -+ tp->mptcp->path_index, __builtin_return_address(0), -+ TCP_SKB_CB(skb)->seq, TCP_SKB_CB(skb)->mptcp_flags); -+ -+ if (!is_master_tp(tp)) { -+ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_FBDATASUB); -+ mptcp_send_reset(sk); -+ return 1; -+ } -+ -+ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_FBDATAINIT); -+ -+ mpcb->infinite_mapping_snd = 1; -+ mpcb->infinite_mapping_rcv = 1; -+ mpcb->infinite_rcv_seq = mptcp_get_rcv_nxt_64(mptcp_meta_tp(tp)); -+ -+ mptcp_fallback_close(mpcb, sk); -+ -+ /* We do a seamless fallback and should not send a inf.mapping. */ -+ mpcb->send_infinite_mapping = 0; -+ tp->mptcp->fully_established = 1; -+ } -+ -+ /* Receiver-side becomes fully established when a whole rcv-window has -+ * been received without the need to fallback due to the previous -+ * condition. -+ */ -+ if (!tp->mptcp->fully_established) { -+ tp->mptcp->init_rcv_wnd -= skb->len; -+ if (tp->mptcp->init_rcv_wnd < 0) -+ mptcp_become_fully_estab(sk); -+ } -+ -+ return 0; -+} -+ -+static void mptcp_restart_sending(struct sock *meta_sk) -+{ -+ struct tcp_sock *meta_tp = tcp_sk(meta_sk); -+ struct mptcp_cb *mpcb = meta_tp->mpcb; -+ struct sk_buff *wq_head, *skb, *tmp; -+ -+ skb = tcp_rtx_queue_head(meta_sk); -+ -+ /* We resend everything that has not been acknowledged, thus we need -+ * to move it from the rtx-tree to the write-queue. -+ */ -+ wq_head = tcp_write_queue_head(meta_sk); -+ -+ skb_rbtree_walk_from_safe(skb, tmp) { -+ list_del(&skb->tcp_tsorted_anchor); -+ tcp_rtx_queue_unlink(skb, meta_sk); -+ INIT_LIST_HEAD(&skb->tcp_tsorted_anchor); -+ -+ if (wq_head) -+ __skb_queue_before(&meta_sk->sk_write_queue, wq_head, skb); -+ else -+ tcp_add_write_queue_tail(meta_sk, skb); -+ } -+ -+ /* We artificially restart the whole send-queue. Thus, -+ * it is as if no packets are in flight -+ */ -+ meta_tp->packets_out = 0; -+ -+ /* If the snd_nxt already wrapped around, we have to -+ * undo the wrapping, as we are restarting from snd_una -+ * on. -+ */ -+ if (meta_tp->snd_nxt < meta_tp->snd_una) { -+ mpcb->snd_high_order[mpcb->snd_hiseq_index] -= 2; -+ mpcb->snd_hiseq_index = mpcb->snd_hiseq_index ? 0 : 1; -+ } -+ meta_tp->snd_nxt = meta_tp->snd_una; -+ -+ /* Trigger a sending on the meta. */ -+ mptcp_push_pending_frames(meta_sk); -+} -+ -+/* @return: 0 everything is fine. Just continue processing -+ * 1 subflow is broken stop everything -+ * -1 this packet was broken - continue with the next one. -+ */ -+static int mptcp_detect_mapping(struct sock *sk, struct sk_buff *skb) -+{ -+ struct tcp_sock *tp = tcp_sk(sk), *meta_tp = mptcp_meta_tp(tp); -+ struct mptcp_cb *mpcb = tp->mpcb; -+ struct tcp_skb_cb *tcb = TCP_SKB_CB(skb); -+ u32 *ptr; -+ u32 data_seq, sub_seq, data_len, tcp_end_seq; -+ bool set_infinite_rcv = false; -+ -+ /* If we are in infinite-mapping-mode, the subflow is guaranteed to be -+ * in-order at the data-level. Thus data-seq-numbers can be inferred -+ * from what is expected at the data-level. -+ */ -+ if (mpcb->infinite_mapping_rcv) { -+ /* copied_seq may be bigger than tcb->seq (e.g., when the peer -+ * retransmits data that actually has already been acknowledged with -+ * newer data, if he did not receive our acks). Thus, we need -+ * to account for this overlap as well. -+ */ -+ tp->mptcp->map_data_seq = mpcb->infinite_rcv_seq - (tp->copied_seq - tcb->seq); -+ tp->mptcp->map_subseq = tcb->seq; -+ tp->mptcp->map_data_len = skb->len; -+ tp->mptcp->map_data_fin = !!(TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN); -+ tp->mptcp->mapping_present = 1; -+ return 0; -+ } -+ -+ if (!tp->mptcp->mapping_present && mptcp_is_data_mpcapable(skb)) { -+ __u32 *ptr = (__u32 *)(skb_transport_header(skb) + TCP_SKB_CB(skb)->dss_off); -+ -+ sub_seq = 1 + tp->mptcp->rcv_isn; -+ data_seq = meta_tp->rcv_nxt; -+ data_len = get_unaligned_be16(ptr); -+ } else if (!mptcp_is_data_seq(skb)) { -+ /* No mapping here? -+ * Exit - it is either already set or still on its way -+ */ -+ if (!tp->mptcp->mapping_present && -+ tp->rcv_nxt - tp->copied_seq > 65536) { -+ /* Too many packets without a mapping, -+ * this subflow is broken -+ */ -+ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_NODSSWINDOW); -+ mptcp_send_reset(sk); -+ return 1; -+ } -+ -+ return 0; -+ } else { -+ /* Well, then the DSS-mapping is there. So, read it! */ -+ ptr = mptcp_skb_set_data_seq(skb, &data_seq, mpcb); -+ ptr++; -+ sub_seq = get_unaligned_be32(ptr) + tp->mptcp->rcv_isn; -+ ptr++; -+ data_len = get_unaligned_be16(ptr); -+ } -+ -+ /* If it's an empty skb with DATA_FIN, sub_seq must get fixed. -+ * The draft sets it to 0, but we really would like to have the -+ * real value, to have an easy handling afterwards here in this -+ * function. -+ */ -+ if (mptcp_is_data_fin(skb) && skb->len == 0) -+ sub_seq = TCP_SKB_CB(skb)->seq; -+ -+ /* If there is already a mapping - we check if it maps with the current -+ * one. If not - we reset. -+ */ -+ if (tp->mptcp->mapping_present && -+ (data_seq != (u32)tp->mptcp->map_data_seq || -+ sub_seq != tp->mptcp->map_subseq || -+ data_len != tp->mptcp->map_data_len + tp->mptcp->map_data_fin || -+ mptcp_is_data_fin(skb) != tp->mptcp->map_data_fin)) { -+ /* Mapping in packet is different from what we want */ -+ pr_debug("%s Mappings do not match!\n", __func__); -+ pr_debug("%s dseq %u mdseq %u, sseq %u msseq %u dlen %u mdlen %u dfin %d mdfin %d\n", -+ __func__, data_seq, (u32)tp->mptcp->map_data_seq, -+ sub_seq, tp->mptcp->map_subseq, data_len, -+ tp->mptcp->map_data_len, mptcp_is_data_fin(skb), -+ tp->mptcp->map_data_fin); -+ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_DSSNOMATCH); -+ mptcp_send_reset(sk); -+ return 1; -+ } -+ -+ /* If the previous check was good, the current mapping is valid and we exit. */ -+ if (tp->mptcp->mapping_present) -+ return 0; -+ -+ /* Mapping not yet set on this subflow - we set it here! */ -+ -+ if (!data_len) { -+ mpcb->infinite_mapping_rcv = 1; -+ mpcb->send_infinite_mapping = 1; -+ tp->mptcp->fully_established = 1; -+ /* We need to repeat mp_fail's until the sender felt -+ * back to infinite-mapping - here we stop repeating it. -+ */ -+ tp->mptcp->send_mp_fail = 0; -+ -+ /* We have to fixup data_len - it must be the same as skb->len */ -+ data_len = skb->len + (mptcp_is_data_fin(skb) ? 1 : 0); -+ sub_seq = tcb->seq; -+ -+ mptcp_restart_sending(tp->meta_sk); -+ -+ mptcp_fallback_close(mpcb, sk); -+ -+ /* data_seq and so on are set correctly */ -+ -+ /* At this point, the meta-ofo-queue has to be emptied, -+ * as the following data is guaranteed to be in-order at -+ * the data and subflow-level -+ */ -+ skb_rbtree_purge(&meta_tp->out_of_order_queue); -+ -+ set_infinite_rcv = true; -+ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_INFINITEMAPRX); -+ } -+ -+ /* We are sending mp-fail's and thus are in fallback mode. -+ * Ignore packets which do not announce the fallback and still -+ * want to provide a mapping. -+ */ -+ if (tp->mptcp->send_mp_fail) { -+ tp->copied_seq = TCP_SKB_CB(skb)->end_seq; -+ __skb_unlink(skb, &sk->sk_receive_queue); -+ __kfree_skb(skb); -+ return -1; -+ } -+ -+ /* FIN increased the mapping-length by 1 */ -+ if (mptcp_is_data_fin(skb)) -+ data_len--; -+ -+ /* Subflow-sequences of packet must be -+ * (at least partially) be part of the DSS-mapping's -+ * subflow-sequence-space. -+ * -+ * Basically the mapping is not valid, if either of the -+ * following conditions is true: -+ * -+ * 1. It's not a data_fin and -+ * MPTCP-sub_seq >= TCP-end_seq -+ * -+ * 2. It's a data_fin and TCP-end_seq > TCP-seq and -+ * MPTCP-sub_seq >= TCP-end_seq -+ * -+ * The previous two can be merged into: -+ * TCP-end_seq > TCP-seq and MPTCP-sub_seq >= TCP-end_seq -+ * Because if it's not a data-fin, TCP-end_seq > TCP-seq -+ * -+ * 3. It's a data_fin and skb->len == 0 and -+ * MPTCP-sub_seq > TCP-end_seq -+ * -+ * 4. It's not a data_fin and TCP-end_seq > TCP-seq and -+ * MPTCP-sub_seq + MPTCP-data_len <= TCP-seq -+ */ -+ -+ /* subflow-fin is not part of the mapping - ignore it here ! */ -+ tcp_end_seq = tcb->end_seq; -+ if (tcb->tcp_flags & TCPHDR_FIN) -+ tcp_end_seq--; -+ if ((!before(sub_seq, tcb->end_seq) && after(tcp_end_seq, tcb->seq)) || -+ (mptcp_is_data_fin(skb) && skb->len == 0 && after(sub_seq, tcb->end_seq)) || -+ (!after(sub_seq + data_len, tcb->seq) && after(tcp_end_seq, tcb->seq))) { -+ /* Subflow-sequences of packet is different from what is in the -+ * packet's dss-mapping. The peer is misbehaving - reset -+ */ -+ pr_debug("%s Packet's mapping does not map to the DSS sub_seq %u end_seq %u, tcp_end_seq %u seq %u dfin %u len %u data_len %u copied_seq %u\n", -+ __func__, sub_seq, tcb->end_seq, tcp_end_seq, -+ tcb->seq, mptcp_is_data_fin(skb), -+ skb->len, data_len, tp->copied_seq); -+ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_DSSTCPMISMATCH); -+ mptcp_send_reset(sk); -+ return 1; -+ } -+ -+ /* Does the DSS had 64-bit seqnum's ? */ -+ if (!(tcb->mptcp_flags & MPTCPHDR_SEQ64_SET)) { -+ /* Wrapped around? */ -+ if (unlikely(after(data_seq, meta_tp->rcv_nxt) && data_seq < meta_tp->rcv_nxt)) { -+ tp->mptcp->map_data_seq = mptcp_get_data_seq_64(mpcb, !mpcb->rcv_hiseq_index, data_seq); -+ } else { -+ /* Else, access the default high-order bits */ -+ tp->mptcp->map_data_seq = mptcp_get_data_seq_64(mpcb, mpcb->rcv_hiseq_index, data_seq); -+ } -+ } else { -+ tp->mptcp->map_data_seq = mptcp_get_data_seq_64(mpcb, (tcb->mptcp_flags & MPTCPHDR_SEQ64_INDEX) ? 1 : 0, data_seq); -+ -+ if (unlikely(tcb->mptcp_flags & MPTCPHDR_SEQ64_OFO)) { -+ /* We make sure that the data_seq is invalid. -+ * It will be dropped later. -+ */ -+ tp->mptcp->map_data_seq += 0xFFFFFFFF; -+ tp->mptcp->map_data_seq += 0xFFFFFFFF; -+ } -+ } -+ -+ if (set_infinite_rcv) -+ mpcb->infinite_rcv_seq = tp->mptcp->map_data_seq; -+ -+ tp->mptcp->map_data_len = data_len; -+ tp->mptcp->map_subseq = sub_seq; -+ tp->mptcp->map_data_fin = mptcp_is_data_fin(skb) ? 1 : 0; -+ tp->mptcp->mapping_present = 1; -+ -+ return 0; -+} -+ -+/* Similar to tcp_sequence(...) */ -+static inline bool mptcp_sequence(const struct tcp_sock *meta_tp, -+ u64 data_seq, u64 end_data_seq) -+{ -+ const struct mptcp_cb *mpcb = meta_tp->mpcb; -+ u64 rcv_wup64; -+ -+ /* Wrap-around? */ -+ if (meta_tp->rcv_wup > meta_tp->rcv_nxt) { -+ rcv_wup64 = ((u64)(mpcb->rcv_high_order[mpcb->rcv_hiseq_index] - 1) << 32) | -+ meta_tp->rcv_wup; -+ } else { -+ rcv_wup64 = mptcp_get_data_seq_64(mpcb, mpcb->rcv_hiseq_index, -+ meta_tp->rcv_wup); -+ } -+ -+ return !before64(end_data_seq, rcv_wup64) && -+ !after64(data_seq, mptcp_get_rcv_nxt_64(meta_tp) + tcp_receive_window(meta_tp)); -+} -+ -+/* @return: 0 everything is fine. Just continue processing -+ * -1 this packet was broken - continue with the next one. -+ */ -+static int mptcp_validate_mapping(struct sock *sk, struct sk_buff *skb) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct sk_buff *tmp, *tmp1; -+ u32 tcp_end_seq; -+ -+ if (!tp->mptcp->mapping_present) -+ return 0; -+ -+ /* either, the new skb gave us the mapping and the first segment -+ * in the sub-rcv-queue has to be trimmed ... -+ */ -+ tmp = skb_peek(&sk->sk_receive_queue); -+ if (before(TCP_SKB_CB(tmp)->seq, tp->mptcp->map_subseq) && -+ after(TCP_SKB_CB(tmp)->end_seq, tp->mptcp->map_subseq)) { -+ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_DSSTRIMHEAD); -+ mptcp_skb_trim_head(tmp, sk, tp->mptcp->map_subseq); -+ } -+ -+ /* ... or the new skb (tail) has to be split at the end. */ -+ tcp_end_seq = TCP_SKB_CB(skb)->end_seq; -+ if (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN) -+ tcp_end_seq--; -+ if (after(tcp_end_seq, tp->mptcp->map_subseq + tp->mptcp->map_data_len)) { -+ u32 seq = tp->mptcp->map_subseq + tp->mptcp->map_data_len; -+ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_DSSSPLITTAIL); -+ if (mptcp_skb_split_tail(skb, sk, seq)) { /* Allocation failed */ -+ /* TODO : maybe handle this here better. -+ * We now just force meta-retransmission. -+ */ -+ tp->copied_seq = TCP_SKB_CB(skb)->end_seq; -+ __skb_unlink(skb, &sk->sk_receive_queue); -+ __kfree_skb(skb); -+ return -1; -+ } -+ } -+ -+ /* Now, remove old sk_buff's from the receive-queue. -+ * This may happen if the mapping has been lost for these segments and -+ * the next mapping has already been received. -+ */ -+ if (before(TCP_SKB_CB(skb_peek(&sk->sk_receive_queue))->seq, tp->mptcp->map_subseq)) { -+ skb_queue_walk_safe(&sk->sk_receive_queue, tmp1, tmp) { -+ if (!before(TCP_SKB_CB(tmp1)->seq, tp->mptcp->map_subseq)) -+ break; -+ -+ tp->copied_seq = TCP_SKB_CB(tmp1)->end_seq; -+ __skb_unlink(tmp1, &sk->sk_receive_queue); -+ -+ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_PURGEOLD); -+ /* Impossible that we could free skb here, because his -+ * mapping is known to be valid from previous checks -+ */ -+ __kfree_skb(tmp1); -+ } -+ } -+ -+ return 0; -+} -+ -+/* @return: 0 everything is fine. Just continue processing -+ * 1 subflow is broken stop everything -+ * -1 this mapping has been put in the meta-receive-queue -+ * -2 this mapping has been eaten by the application -+ */ -+static int mptcp_queue_skb(struct sock *sk) -+{ -+ struct tcp_sock *tp = tcp_sk(sk), *meta_tp = mptcp_meta_tp(tp); -+ struct sock *meta_sk = mptcp_meta_sk(sk); -+ struct mptcp_cb *mpcb = tp->mpcb; -+ struct sk_buff *tmp, *tmp1; -+ u64 rcv_nxt64 = mptcp_get_rcv_nxt_64(meta_tp); -+ u32 old_copied_seq = tp->copied_seq; -+ bool data_queued = false; -+ -+ /* Have we not yet received the full mapping? */ -+ if (!tp->mptcp->mapping_present || -+ before(tp->rcv_nxt, tp->mptcp->map_subseq + tp->mptcp->map_data_len)) -+ return 0; -+ -+ /* Is this an overlapping mapping? rcv_nxt >= end_data_seq -+ * OR -+ * This mapping is out of window -+ */ -+ if (!before64(rcv_nxt64, tp->mptcp->map_data_seq + tp->mptcp->map_data_len + tp->mptcp->map_data_fin) || -+ !mptcp_sequence(meta_tp, tp->mptcp->map_data_seq, -+ tp->mptcp->map_data_seq + tp->mptcp->map_data_len + tp->mptcp->map_data_fin)) { -+ skb_queue_walk_safe(&sk->sk_receive_queue, tmp1, tmp) { -+ __skb_unlink(tmp1, &sk->sk_receive_queue); -+ tp->copied_seq = TCP_SKB_CB(tmp1)->end_seq; -+ __kfree_skb(tmp1); -+ -+ if (!skb_queue_empty(&sk->sk_receive_queue) && -+ !before(TCP_SKB_CB(tmp)->seq, -+ tp->mptcp->map_subseq + tp->mptcp->map_data_len)) -+ break; -+ } -+ -+ mptcp_reset_mapping(tp, old_copied_seq); -+ -+ return -1; -+ } -+ -+ /* Record it, because we want to send our data_fin on the same path */ -+ if (tp->mptcp->map_data_fin) { -+ mpcb->dfin_path_index = tp->mptcp->path_index; -+ mpcb->dfin_combined = !!(sk->sk_shutdown & RCV_SHUTDOWN); -+ } -+ -+ /* Verify the checksum */ -+ if (mpcb->dss_csum && !mpcb->infinite_mapping_rcv) { -+ int ret = mptcp_verif_dss_csum(sk); -+ -+ if (ret <= 0) { -+ mptcp_reset_mapping(tp, old_copied_seq); -+ return 1; -+ } -+ } -+ -+ if (before64(rcv_nxt64, tp->mptcp->map_data_seq)) { -+ /* Seg's have to go to the meta-ofo-queue */ -+ skb_queue_walk_safe(&sk->sk_receive_queue, tmp1, tmp) { -+ tp->copied_seq = TCP_SKB_CB(tmp1)->end_seq; -+ mptcp_prepare_skb(tmp1, sk); -+ __skb_unlink(tmp1, &sk->sk_receive_queue); -+ /* MUST be done here, because fragstolen may be true later. -+ * Then, kfree_skb_partial will not account the memory. -+ */ -+ skb_orphan(tmp1); -+ -+ if (!mpcb->in_time_wait) /* In time-wait, do not receive data */ -+ tcp_data_queue_ofo(meta_sk, tmp1); -+ else -+ __kfree_skb(tmp1); -+ -+ if (!skb_queue_empty(&sk->sk_receive_queue) && -+ !before(TCP_SKB_CB(tmp)->seq, -+ tp->mptcp->map_subseq + tp->mptcp->map_data_len)) -+ break; -+ } -+ -+ /* Quick ACK if more 3/4 of the receive window is filled */ -+ if (after64(tp->mptcp->map_data_seq, -+ rcv_nxt64 + 3 * (tcp_receive_window(meta_tp) >> 2))) -+ tcp_enter_quickack_mode(sk, TCP_MAX_QUICKACKS); -+ -+ } else { -+ /* Ready for the meta-rcv-queue */ -+ skb_queue_walk_safe(&sk->sk_receive_queue, tmp1, tmp) { -+ int eaten = 0; -+ bool fragstolen = false; -+ u32 old_rcv_nxt = meta_tp->rcv_nxt; -+ -+ tp->copied_seq = TCP_SKB_CB(tmp1)->end_seq; -+ mptcp_prepare_skb(tmp1, sk); -+ __skb_unlink(tmp1, &sk->sk_receive_queue); -+ /* MUST be done here, because fragstolen may be true. -+ * Then, kfree_skb_partial will not account the memory. -+ */ -+ skb_orphan(tmp1); -+ -+ /* This segment has already been received */ -+ if (!after(TCP_SKB_CB(tmp1)->end_seq, meta_tp->rcv_nxt)) { -+ __kfree_skb(tmp1); -+ goto next; -+ } -+ -+ if (mpcb->in_time_wait) /* In time-wait, do not receive data */ -+ eaten = 1; -+ -+ if (!eaten) -+ eaten = tcp_queue_rcv(meta_sk, tmp1, &fragstolen); -+ -+ meta_tp->rcv_nxt = TCP_SKB_CB(tmp1)->end_seq; -+ -+ if (TCP_SKB_CB(tmp1)->tcp_flags & TCPHDR_FIN) -+ mptcp_fin(meta_sk); -+ -+ /* Check if this fills a gap in the ofo queue */ -+ if (!RB_EMPTY_ROOT(&meta_tp->out_of_order_queue)) -+ tcp_ofo_queue(meta_sk); -+ -+ mptcp_check_rcvseq_wrap(meta_tp, old_rcv_nxt); -+ -+ if (eaten) -+ kfree_skb_partial(tmp1, fragstolen); -+ -+ data_queued = true; -+next: -+ if (!skb_queue_empty(&sk->sk_receive_queue) && -+ !before(TCP_SKB_CB(tmp)->seq, -+ tp->mptcp->map_subseq + tp->mptcp->map_data_len)) -+ break; -+ } -+ } -+ -+ inet_csk(meta_sk)->icsk_ack.lrcvtime = tcp_jiffies32; -+ mptcp_reset_mapping(tp, old_copied_seq); -+ -+ return data_queued ? -1 : -2; -+} -+ -+void mptcp_data_ready(struct sock *sk) -+{ -+ struct sock *meta_sk = mptcp_meta_sk(sk); -+ struct sk_buff *skb, *tmp; -+ int queued = 0; -+ -+ tcp_mstamp_refresh(tcp_sk(meta_sk)); -+ -+ /* restart before the check, because mptcp_fin might have changed the -+ * state. -+ */ -+restart: -+ /* If the meta cannot receive data, there is no point in pushing data. -+ * If we are in time-wait, we may still be waiting for the final FIN. -+ * So, we should proceed with the processing. -+ */ -+ if (!mptcp_sk_can_recv(meta_sk) && !tcp_sk(sk)->mpcb->in_time_wait) { -+ skb_queue_purge(&sk->sk_receive_queue); -+ tcp_sk(sk)->copied_seq = tcp_sk(sk)->rcv_nxt; -+ goto exit; -+ } -+ -+ /* Iterate over all segments, detect their mapping (if we don't have -+ * one yet), validate them and push everything one level higher. -+ */ -+ skb_queue_walk_safe(&sk->sk_receive_queue, skb, tmp) { -+ int ret; -+ /* Pre-validation - e.g., early fallback */ -+ ret = mptcp_prevalidate_skb(sk, skb); -+ if (ret < 0) -+ goto restart; -+ else if (ret > 0) -+ break; -+ -+ /* Set the current mapping */ -+ ret = mptcp_detect_mapping(sk, skb); -+ if (ret < 0) -+ goto restart; -+ else if (ret > 0) -+ break; -+ -+ /* Validation */ -+ if (mptcp_validate_mapping(sk, skb) < 0) -+ goto restart; -+ -+ /* Push a level higher */ -+ ret = mptcp_queue_skb(sk); -+ if (ret < 0) { -+ if (ret == -1) -+ queued = ret; -+ goto restart; -+ } else if (ret == 0) { -+ continue; -+ } else { /* ret == 1 */ -+ break; -+ } -+ } -+ -+exit: -+ if (tcp_sk(sk)->close_it && sk->sk_state == TCP_FIN_WAIT2) { -+ tcp_send_ack(sk); -+ tcp_sk(sk)->ops->time_wait(sk, TCP_TIME_WAIT, 0); -+ } -+ -+ if (queued == -1 && !sock_flag(meta_sk, SOCK_DEAD)) -+ meta_sk->sk_data_ready(meta_sk); -+} -+ -+struct mp_join *mptcp_find_join(const struct sk_buff *skb) -+{ -+ const struct tcphdr *th = tcp_hdr(skb); -+ unsigned char *ptr; -+ int length = (th->doff * 4) - sizeof(struct tcphdr); -+ -+ /* Jump through the options to check whether JOIN is there */ -+ ptr = (unsigned char *)(th + 1); -+ while (length > 0) { -+ int opcode = *ptr++; -+ int opsize; -+ -+ switch (opcode) { -+ case TCPOPT_EOL: -+ return NULL; -+ case TCPOPT_NOP: /* Ref: RFC 793 section 3.1 */ -+ length--; -+ continue; -+ default: -+ opsize = *ptr++; -+ if (opsize < 2) /* "silly options" */ -+ return NULL; -+ if (opsize > length) -+ return NULL; /* don't parse partial options */ -+ if (opcode == TCPOPT_MPTCP && -+ ((struct mptcp_option *)(ptr - 2))->sub == MPTCP_SUB_JOIN) { -+ return (struct mp_join *)(ptr - 2); -+ } -+ ptr += opsize - 2; -+ length -= opsize; -+ } -+ } -+ return NULL; -+} -+ -+int mptcp_lookup_join(struct sk_buff *skb, struct inet_timewait_sock *tw) -+{ -+ struct sock *meta_sk; -+ u32 token; -+ bool meta_v4; -+ struct mp_join *join_opt = mptcp_find_join(skb); -+ if (!join_opt) -+ return 0; -+ -+ /* MPTCP structures were not initialized, so return error */ -+ if (mptcp_init_failed) -+ return -1; -+ -+ token = join_opt->u.syn.token; -+ meta_sk = mptcp_hash_find(dev_net(skb_dst(skb)->dev), token); -+ if (!meta_sk) { -+ MPTCP_INC_STATS(dev_net(skb_dst(skb)->dev), MPTCP_MIB_JOINNOTOKEN); -+ mptcp_debug("%s:mpcb not found:%x\n", __func__, token); -+ return -1; -+ } -+ -+ meta_v4 = meta_sk->sk_family == AF_INET; -+ if (meta_v4) { -+ if (skb->protocol == htons(ETH_P_IPV6)) { -+ mptcp_debug("SYN+MP_JOIN with IPV6 address on pure IPV4 meta\n"); -+ sock_put(meta_sk); /* Taken by mptcp_hash_find */ -+ return -1; -+ } -+ } else if (skb->protocol == htons(ETH_P_IP) && meta_sk->sk_ipv6only) { -+ mptcp_debug("SYN+MP_JOIN with IPV4 address on IPV6_V6ONLY meta\n"); -+ sock_put(meta_sk); /* Taken by mptcp_hash_find */ -+ return -1; -+ } -+ -+ /* Coming from time-wait-sock processing in tcp_v4_rcv. -+ * We have to deschedule it before continuing, because otherwise -+ * mptcp_v4_do_rcv will hit again on it inside tcp_v4_hnd_req. -+ */ -+ if (tw) -+ inet_twsk_deschedule_put(tw); -+ -+ /* OK, this is a new syn/join, let's create a new open request and -+ * send syn+ack -+ */ -+ if (skb->protocol == htons(ETH_P_IP)) { -+ tcp_v4_do_rcv(meta_sk, skb); -+#if IS_ENABLED(CONFIG_IPV6) -+ } else { -+ tcp_v6_do_rcv(meta_sk, skb); -+#endif /* CONFIG_IPV6 */ -+ } -+ sock_put(meta_sk); /* Taken by mptcp_hash_find */ -+ return 1; -+} -+ -+int mptcp_do_join_short(struct sk_buff *skb, -+ const struct mptcp_options_received *mopt, -+ struct net *net) -+{ -+ struct sock *meta_sk; -+ u32 token; -+ bool meta_v4; -+ -+ token = mopt->mptcp_rem_token; -+ meta_sk = mptcp_hash_find(net, token); -+ if (!meta_sk) { -+ MPTCP_INC_STATS(dev_net(skb_dst(skb)->dev), MPTCP_MIB_JOINNOTOKEN); -+ mptcp_debug("%s:mpcb not found:%x\n", __func__, token); -+ return -1; -+ } -+ -+ meta_v4 = meta_sk->sk_family == AF_INET; -+ if (meta_v4) { -+ if (skb->protocol == htons(ETH_P_IPV6)) { -+ mptcp_debug("SYN+MP_JOIN with IPV6 address on pure IPV4 meta\n"); -+ sock_put(meta_sk); /* Taken by mptcp_hash_find */ -+ return -1; -+ } -+ } else if (skb->protocol == htons(ETH_P_IP) && meta_sk->sk_ipv6only) { -+ mptcp_debug("SYN+MP_JOIN with IPV4 address on IPV6_V6ONLY meta\n"); -+ sock_put(meta_sk); /* Taken by mptcp_hash_find */ -+ return -1; -+ } -+ -+ /* OK, this is a new syn/join, let's create a new open request and -+ * send syn+ack -+ */ -+ -+ /* mptcp_v4_do_rcv tries to free the skb - we prevent this, as -+ * the skb will finally be freed by tcp_v4_do_rcv (where we are -+ * coming from) -+ */ -+ skb_get(skb); -+ if (skb->protocol == htons(ETH_P_IP)) { -+ tcp_v4_do_rcv(meta_sk, skb); -+#if IS_ENABLED(CONFIG_IPV6) -+ } else { /* IPv6 */ -+ tcp_v6_do_rcv(meta_sk, skb); -+#endif /* CONFIG_IPV6 */ -+ } -+ -+ sock_put(meta_sk); /* Taken by mptcp_hash_find */ -+ return 0; -+} -+ -+/** -+ * Equivalent of tcp_fin() for MPTCP -+ * Can be called only when the FIN is validly part -+ * of the data seqnum space. Not before when we get holes. -+ */ -+void mptcp_fin(struct sock *meta_sk) -+{ -+ struct sock *sk = NULL; -+ struct tcp_sock *meta_tp = tcp_sk(meta_sk); -+ struct mptcp_cb *mpcb = meta_tp->mpcb; -+ struct mptcp_tcp_sock *mptcp; -+ unsigned char state; -+ -+ mptcp_for_each_sub(mpcb, mptcp) { -+ struct sock *sk_it = mptcp_to_sock(mptcp); -+ -+ if (tcp_sk(sk_it)->mptcp->path_index == mpcb->dfin_path_index) { -+ sk = sk_it; -+ break; -+ } -+ } -+ -+ if (!sk || sk->sk_state == TCP_CLOSE) -+ sk = mptcp_select_ack_sock(meta_sk); -+ -+ inet_csk_schedule_ack(sk); -+ -+ if (!mpcb->in_time_wait) { -+ meta_sk->sk_shutdown |= RCV_SHUTDOWN; -+ sock_set_flag(meta_sk, SOCK_DONE); -+ state = meta_sk->sk_state; -+ } else { -+ state = mpcb->mptw_state; -+ } -+ -+ switch (state) { -+ case TCP_SYN_RECV: -+ case TCP_ESTABLISHED: -+ /* Move to CLOSE_WAIT */ -+ tcp_set_state(meta_sk, TCP_CLOSE_WAIT); -+ inet_csk(sk)->icsk_ack.pingpong = 1; -+ break; -+ -+ case TCP_CLOSE_WAIT: -+ case TCP_CLOSING: -+ /* Received a retransmission of the FIN, do -+ * nothing. -+ */ -+ break; -+ case TCP_LAST_ACK: -+ /* RFC793: Remain in the LAST-ACK state. */ -+ break; -+ -+ case TCP_FIN_WAIT1: -+ /* This case occurs when a simultaneous close -+ * happens, we must ack the received FIN and -+ * enter the CLOSING state. -+ */ -+ tcp_send_ack(sk); -+ tcp_set_state(meta_sk, TCP_CLOSING); -+ break; -+ case TCP_FIN_WAIT2: -+ /* Received a FIN -- send ACK and enter TIME_WAIT. */ -+ tcp_send_ack(sk); -+ meta_tp->ops->time_wait(meta_sk, TCP_TIME_WAIT, 0); -+ break; -+ default: -+ /* Only TCP_LISTEN and TCP_CLOSE are left, in these -+ * cases we should never reach this piece of code. -+ */ -+ pr_err("%s: Impossible, meta_sk->sk_state=%d\n", __func__, -+ meta_sk->sk_state); -+ break; -+ } -+ -+ /* It _is_ possible, that we have something out-of-order _after_ FIN. -+ * Probably, we should reset in this case. For now drop them. -+ */ -+ skb_rbtree_purge(&meta_tp->out_of_order_queue); -+ sk_mem_reclaim(meta_sk); -+ -+ if (!sock_flag(meta_sk, SOCK_DEAD)) { -+ meta_sk->sk_state_change(meta_sk); -+ -+ /* Do not send POLL_HUP for half duplex close. */ -+ if (meta_sk->sk_shutdown == SHUTDOWN_MASK || -+ meta_sk->sk_state == TCP_CLOSE) -+ sk_wake_async(meta_sk, SOCK_WAKE_WAITD, POLL_HUP); -+ else -+ sk_wake_async(meta_sk, SOCK_WAKE_WAITD, POLL_IN); -+ } -+ -+ return; -+} -+ -+/* Similar to tcp_xmit_retransmit_queue */ -+static void mptcp_xmit_retransmit_queue(struct sock *meta_sk) -+{ -+ struct tcp_sock *meta_tp = tcp_sk(meta_sk); -+ struct sk_buff *skb, *rtx_head; -+ -+ if (!meta_tp->packets_out) -+ return; -+ -+ skb = rtx_head = tcp_rtx_queue_head(meta_sk); -+ skb_rbtree_walk_from(skb) { -+ if (mptcp_retransmit_skb(meta_sk, skb)) -+ return; -+ -+ if (skb == rtx_head) -+ inet_csk_reset_xmit_timer(meta_sk, ICSK_TIME_RETRANS, -+ inet_csk(meta_sk)->icsk_rto, -+ TCP_RTO_MAX); -+ } -+} -+ -+static void mptcp_snd_una_update(struct tcp_sock *meta_tp, u32 data_ack) -+{ -+ u32 delta = data_ack - meta_tp->snd_una; -+ -+ sock_owned_by_me((struct sock *)meta_tp); -+ meta_tp->bytes_acked += delta; -+ meta_tp->snd_una = data_ack; -+} -+ -+/* Handle the DATA_ACK */ -+static bool mptcp_process_data_ack(struct sock *sk, const struct sk_buff *skb) -+{ -+ struct sock *meta_sk = mptcp_meta_sk(sk); -+ struct tcp_sock *meta_tp = tcp_sk(meta_sk), *tp = tcp_sk(sk); -+ struct tcp_skb_cb *tcb = TCP_SKB_CB(skb); -+ u32 prior_snd_una = meta_tp->snd_una; -+ int prior_packets; -+ u32 nwin, data_ack, data_seq; -+ u16 data_len = 0; -+ -+ /* A valid packet came in - subflow is operational again */ -+ tp->pf = 0; -+ -+ /* Even if there is no data-ack, we stop retransmitting. -+ * Except if this is a SYN/ACK. Then it is just a retransmission -+ */ -+ if (tp->mptcp->pre_established && !tcp_hdr(skb)->syn) { -+ tp->mptcp->pre_established = 0; -+ sk_stop_timer(sk, &tp->mptcp->mptcp_ack_timer); -+ -+ if (meta_tp->mpcb->pm_ops->established_subflow) -+ meta_tp->mpcb->pm_ops->established_subflow(sk); -+ } -+ -+ /* If we are in infinite mapping mode, rx_opt.data_ack has been -+ * set by mptcp_clean_rtx_infinite. -+ */ -+ if (!(tcb->mptcp_flags & MPTCPHDR_ACK) && !tp->mpcb->infinite_mapping_snd) -+ return false; -+ -+ if (unlikely(!tp->mptcp->fully_established) && -+ tp->mptcp->snt_isn + 1 != TCP_SKB_CB(skb)->ack_seq) -+ /* As soon as a subflow-data-ack (not acking syn, thus snt_isn + 1) -+ * includes a data-ack, we are fully established -+ */ -+ mptcp_become_fully_estab(sk); -+ -+ /* After we did the subflow-only processing (stopping timer and marking -+ * subflow as established), check if we can proceed with MPTCP-level -+ * processing. -+ */ -+ if (meta_sk->sk_state == TCP_CLOSE) -+ return false; -+ -+ /* Get the data_seq */ -+ if (mptcp_is_data_seq(skb)) { -+ data_seq = tp->mptcp->rx_opt.data_seq; -+ data_len = tp->mptcp->rx_opt.data_len; -+ } else { -+ data_seq = meta_tp->snd_wl1; -+ } -+ -+ data_ack = tp->mptcp->rx_opt.data_ack; -+ -+ /* If the ack is older than previous acks -+ * then we can probably ignore it. -+ */ -+ if (before(data_ack, prior_snd_una)) -+ goto exit; -+ -+ /* If the ack includes data we haven't sent yet, discard -+ * this segment (RFC793 Section 3.9). -+ */ -+ if (after(data_ack, meta_tp->snd_nxt)) -+ goto exit; -+ -+ /* First valid DATA_ACK, we can stop sending the special MP_CAPABLE */ -+ tp->mpcb->send_mptcpv1_mpcapable = 0; -+ -+ /*** Now, update the window - inspired by tcp_ack_update_window ***/ -+ nwin = ntohs(tcp_hdr(skb)->window); -+ -+ if (likely(!tcp_hdr(skb)->syn)) -+ nwin <<= tp->rx_opt.snd_wscale; -+ -+ if (tcp_may_update_window(meta_tp, data_ack, data_seq, nwin)) { -+ tcp_update_wl(meta_tp, data_seq); -+ -+ /* Draft v09, Section 3.3.5: -+ * [...] It should only update its local receive window values -+ * when the largest sequence number allowed (i.e. DATA_ACK + -+ * receive window) increases. [...] -+ */ -+ if (meta_tp->snd_wnd != nwin && -+ !before(data_ack + nwin, tcp_wnd_end(meta_tp))) { -+ meta_tp->snd_wnd = nwin; -+ -+ if (nwin > meta_tp->max_window) -+ meta_tp->max_window = nwin; -+ } -+ } -+ /*** Done, update the window ***/ -+ -+ /* We passed data and got it acked, remove any soft error -+ * log. Something worked... -+ */ -+ sk->sk_err_soft = 0; -+ inet_csk(meta_sk)->icsk_probes_out = 0; -+ meta_tp->rcv_tstamp = tcp_jiffies32; -+ prior_packets = meta_tp->packets_out; -+ if (!prior_packets) -+ goto no_queue; -+ -+ mptcp_snd_una_update(meta_tp, data_ack); -+ -+ mptcp_clean_rtx_queue(meta_sk, prior_snd_una); -+ -+ /* We are in loss-state, and something got acked, retransmit the whole -+ * queue now! -+ */ -+ if (inet_csk(meta_sk)->icsk_ca_state == TCP_CA_Loss && -+ after(data_ack, prior_snd_una)) { -+ mptcp_xmit_retransmit_queue(meta_sk); -+ inet_csk(meta_sk)->icsk_ca_state = TCP_CA_Open; -+ } -+ -+ /* Simplified version of tcp_new_space, because the snd-buffer -+ * is handled by all the subflows. -+ */ -+ if (sock_flag(meta_sk, SOCK_QUEUE_SHRUNK)) { -+ sock_reset_flag(meta_sk, SOCK_QUEUE_SHRUNK); -+ if (meta_sk->sk_socket && -+ test_bit(SOCK_NOSPACE, &meta_sk->sk_socket->flags)) -+ meta_sk->sk_write_space(meta_sk); -+ } -+ -+ if (meta_sk->sk_state != TCP_ESTABLISHED) { -+ int ret = mptcp_rcv_state_process(meta_sk, sk, skb, data_seq, data_len); -+ -+ if (ret < 0) -+ return true; -+ else if (ret > 0) -+ return false; -+ } -+ -+exit: -+ mptcp_push_pending_frames(meta_sk); -+ -+ return false; -+ -+no_queue: -+ if (tcp_send_head(meta_sk)) -+ tcp_ack_probe(meta_sk); -+ -+ mptcp_push_pending_frames(meta_sk); -+ -+ return false; -+} -+ -+void mptcp_clean_rtx_infinite(const struct sk_buff *skb, struct sock *sk) -+{ -+ struct tcp_sock *tp = tcp_sk(sk), *meta_tp = tcp_sk(mptcp_meta_sk(sk)); -+ -+ if (!tp->mpcb->infinite_mapping_snd) -+ return; -+ -+ /* The difference between both write_seq's represents the offset between -+ * data-sequence and subflow-sequence. As we are infinite, this must -+ * match. -+ * -+ * Thus, from this difference we can infer the meta snd_una. -+ */ -+ tp->mptcp->rx_opt.data_ack = meta_tp->snd_nxt - tp->snd_nxt + -+ tp->snd_una; -+ -+ mptcp_process_data_ack(sk, skb); -+} -+ -+/**** static functions used by mptcp_parse_options */ -+ -+static void mptcp_send_reset_rem_id(const struct mptcp_cb *mpcb, u8 rem_id) -+{ -+ struct mptcp_tcp_sock *mptcp; -+ struct hlist_node *tmp; -+ -+ mptcp_for_each_sub_safe(mpcb, mptcp, tmp) { -+ struct sock *sk_it = mptcp_to_sock(mptcp); -+ -+ if (tcp_sk(sk_it)->mptcp->rem_id == rem_id) { -+ mptcp_reinject_data(sk_it, 0); -+ mptcp_send_reset(sk_it); -+ } -+ } -+} -+ -+static inline bool is_valid_addropt_opsize(u8 mptcp_ver, -+ struct mp_add_addr *mpadd, -+ int opsize) -+{ -+#if IS_ENABLED(CONFIG_IPV6) -+ if (mptcp_ver < MPTCP_VERSION_1 && mpadd->u_bit.v0.ipver == 6) { -+ return opsize == MPTCP_SUB_LEN_ADD_ADDR6 || -+ opsize == MPTCP_SUB_LEN_ADD_ADDR6 + 2; -+ } -+ if (mptcp_ver >= MPTCP_VERSION_1) -+ return opsize == MPTCP_SUB_LEN_ADD_ADDR6_VER1 || -+ opsize == MPTCP_SUB_LEN_ADD_ADDR6_VER1 + 2 || -+ opsize == MPTCP_SUB_LEN_ADD_ADDR4_VER1 || -+ opsize == MPTCP_SUB_LEN_ADD_ADDR4_VER1 + 2; -+#endif -+ if (mptcp_ver < MPTCP_VERSION_1 && mpadd->u_bit.v0.ipver == 4) { -+ return opsize == MPTCP_SUB_LEN_ADD_ADDR4 || -+ opsize == MPTCP_SUB_LEN_ADD_ADDR4 + 2; -+ } -+ if (mptcp_ver >= MPTCP_VERSION_1) { -+ return opsize == MPTCP_SUB_LEN_ADD_ADDR4_VER1 || -+ opsize == MPTCP_SUB_LEN_ADD_ADDR4_VER1 + 2; -+ } -+ return false; -+} -+ -+void mptcp_parse_options(const uint8_t *ptr, int opsize, -+ struct mptcp_options_received *mopt, -+ const struct sk_buff *skb, -+ struct tcp_sock *tp) -+{ -+ const struct mptcp_option *mp_opt = (struct mptcp_option *)ptr; -+ const struct tcphdr *th = tcp_hdr(skb); -+ -+ /* If the socket is mp-capable we would have a mopt. */ -+ if (!mopt) -+ return; -+ -+ switch (mp_opt->sub) { -+ case MPTCP_SUB_CAPABLE: -+ { -+ const struct mp_capable *mpcapable = (struct mp_capable *)ptr; -+ -+ if (mpcapable->ver == MPTCP_VERSION_0 && -+ ((th->syn && opsize != MPTCP_SUB_LEN_CAPABLE_SYN) || -+ (!th->syn && th->ack && opsize != MPTCP_SUB_LEN_CAPABLE_ACK))) { -+ mptcp_debug("%s: mp_capable v0: bad option size %d\n", -+ __func__, opsize); -+ break; -+ } -+ -+ if (mpcapable->ver == MPTCP_VERSION_1 && -+ ((th->syn && !th->ack && opsize != MPTCPV1_SUB_LEN_CAPABLE_SYN) || -+ (th->syn && th->ack && opsize != MPTCPV1_SUB_LEN_CAPABLE_SYNACK) || -+ (!th->syn && th->ack && opsize != MPTCPV1_SUB_LEN_CAPABLE_ACK && -+ opsize != MPTCPV1_SUB_LEN_CAPABLE_DATA && -+ opsize != MPTCPV1_SUB_LEN_CAPABLE_DATA_CSUM))) { -+ mptcp_debug("%s: mp_capable v1: bad option size %d\n", -+ __func__, opsize); -+ break; -+ } -+ -+ /* MPTCP-RFC 6824: -+ * "If receiving a message with the 'B' flag set to 1, and this -+ * is not understood, then this SYN MUST be silently ignored; -+ */ -+ if (mpcapable->b) { -+ mopt->drop_me = 1; -+ break; -+ } -+ -+ /* MPTCP-RFC 6824: -+ * "An implementation that only supports this method MUST set -+ * bit "H" to 1, and bits "C" through "G" to 0." -+ */ -+ if (!mpcapable->h) -+ break; -+ -+ mopt->saw_mpc = 1; -+ mopt->dss_csum = sysctl_mptcp_checksum || mpcapable->a; -+ -+ if (mpcapable->ver == MPTCP_VERSION_0) { -+ if (opsize == MPTCP_SUB_LEN_CAPABLE_SYN) -+ mopt->mptcp_sender_key = mpcapable->sender_key; -+ -+ if (opsize == MPTCP_SUB_LEN_CAPABLE_ACK) { -+ mopt->mptcp_sender_key = mpcapable->sender_key; -+ mopt->mptcp_receiver_key = mpcapable->receiver_key; -+ } -+ } else if (mpcapable->ver == MPTCP_VERSION_1) { -+ if (opsize == MPTCPV1_SUB_LEN_CAPABLE_SYNACK) -+ mopt->mptcp_sender_key = mpcapable->sender_key; -+ -+ if (opsize == MPTCPV1_SUB_LEN_CAPABLE_ACK) { -+ mopt->mptcp_sender_key = mpcapable->sender_key; -+ mopt->mptcp_receiver_key = mpcapable->receiver_key; -+ } -+ -+ if (opsize == MPTCPV1_SUB_LEN_CAPABLE_DATA || -+ opsize == MPTCPV1_SUB_LEN_CAPABLE_DATA_CSUM) { -+ mopt->mptcp_sender_key = mpcapable->sender_key; -+ mopt->mptcp_receiver_key = mpcapable->receiver_key; -+ -+ TCP_SKB_CB(skb)->mptcp_flags |= MPTCPHDR_MPC_DATA; -+ -+ ptr += sizeof(struct mp_capable); -+ TCP_SKB_CB(skb)->dss_off = (ptr - skb_transport_header(skb)); -+ -+ /* Is a check-sum present? */ -+ if (opsize == MPTCPV1_SUB_LEN_CAPABLE_DATA_CSUM) -+ TCP_SKB_CB(skb)->mptcp_flags |= MPTCPHDR_DSS_CSUM; -+ } -+ } -+ -+ mopt->mptcp_ver = mpcapable->ver; -+ break; -+ } -+ case MPTCP_SUB_JOIN: -+ { -+ const struct mp_join *mpjoin = (struct mp_join *)ptr; -+ -+ if (opsize != MPTCP_SUB_LEN_JOIN_SYN && -+ opsize != MPTCP_SUB_LEN_JOIN_SYNACK && -+ opsize != MPTCP_SUB_LEN_JOIN_ACK) { -+ mptcp_debug("%s: mp_join: bad option size %d\n", -+ __func__, opsize); -+ break; -+ } -+ -+ /* saw_mpc must be set, because in tcp_check_req we assume that -+ * it is set to support falling back to reg. TCP if a rexmitted -+ * SYN has no MP_CAPABLE or MP_JOIN -+ */ -+ switch (opsize) { -+ case MPTCP_SUB_LEN_JOIN_SYN: -+ mopt->is_mp_join = 1; -+ mopt->saw_mpc = 1; -+ mopt->low_prio = mpjoin->b; -+ mopt->rem_id = mpjoin->addr_id; -+ mopt->mptcp_rem_token = mpjoin->u.syn.token; -+ mopt->mptcp_recv_nonce = mpjoin->u.syn.nonce; -+ break; -+ case MPTCP_SUB_LEN_JOIN_SYNACK: -+ mopt->saw_mpc = 1; -+ mopt->low_prio = mpjoin->b; -+ mopt->rem_id = mpjoin->addr_id; -+ mopt->mptcp_recv_tmac = mpjoin->u.synack.mac; -+ mopt->mptcp_recv_nonce = mpjoin->u.synack.nonce; -+ break; -+ case MPTCP_SUB_LEN_JOIN_ACK: -+ mopt->saw_mpc = 1; -+ mopt->join_ack = 1; -+ memcpy(mopt->mptcp_recv_mac, mpjoin->u.ack.mac, 20); -+ break; -+ } -+ break; -+ } -+ case MPTCP_SUB_DSS: -+ { -+ const struct mp_dss *mdss = (struct mp_dss *)ptr; -+ struct tcp_skb_cb *tcb = TCP_SKB_CB(skb); -+ -+ /* We check opsize for the csum and non-csum case. We do this, -+ * because the draft says that the csum SHOULD be ignored if -+ * it has not been negotiated in the MP_CAPABLE but still is -+ * present in the data. -+ * -+ * It will get ignored later in mptcp_queue_skb. -+ */ -+ if (opsize != mptcp_sub_len_dss(mdss, 0) && -+ opsize != mptcp_sub_len_dss(mdss, 1)) { -+ mptcp_debug("%s: mp_dss: bad option size %d\n", -+ __func__, opsize); -+ break; -+ } -+ -+ ptr += 4; -+ -+ if (mdss->A) { -+ tcb->mptcp_flags |= MPTCPHDR_ACK; -+ -+ if (mdss->a) { -+ mopt->data_ack = (u32) get_unaligned_be64(ptr); -+ ptr += MPTCP_SUB_LEN_ACK_64; -+ } else { -+ mopt->data_ack = get_unaligned_be32(ptr); -+ ptr += MPTCP_SUB_LEN_ACK; -+ } -+ } -+ -+ tcb->dss_off = (ptr - skb_transport_header(skb)); -+ -+ if (mdss->M) { -+ if (mdss->m) { -+ u64 data_seq64 = get_unaligned_be64(ptr); -+ -+ tcb->mptcp_flags |= MPTCPHDR_SEQ64_SET; -+ mopt->data_seq = (u32) data_seq64; -+ -+ ptr += 12; /* 64-bit dseq + subseq */ -+ } else { -+ mopt->data_seq = get_unaligned_be32(ptr); -+ ptr += 8; /* 32-bit dseq + subseq */ -+ } -+ mopt->data_len = get_unaligned_be16(ptr); -+ -+ tcb->mptcp_flags |= MPTCPHDR_SEQ; -+ -+ /* Is a check-sum present? */ -+ if (opsize == mptcp_sub_len_dss(mdss, 1)) -+ tcb->mptcp_flags |= MPTCPHDR_DSS_CSUM; -+ -+ /* DATA_FIN only possible with DSS-mapping */ -+ if (mdss->F) -+ tcb->mptcp_flags |= MPTCPHDR_FIN; -+ } -+ -+ break; -+ } -+ case MPTCP_SUB_ADD_ADDR: -+ { -+ struct mp_add_addr *mpadd = (struct mp_add_addr *)ptr; -+ -+ /* If tcp_sock is not available, MPTCP version can't be -+ * retrieved and ADD_ADDR opsize validation is not possible. -+ */ -+ if (!tp || !tp->mpcb) -+ break; -+ -+ if (!is_valid_addropt_opsize(tp->mpcb->mptcp_ver, -+ mpadd, opsize)) { -+ mptcp_debug("%s: mp_add_addr: bad option size %d\n", -+ __func__, opsize); -+ break; -+ } -+ -+ /* We have to manually parse the options if we got two of them. */ -+ if (mopt->saw_add_addr) { -+ mopt->more_add_addr = 1; -+ break; -+ } -+ mopt->saw_add_addr = 1; -+ mopt->add_addr_ptr = ptr; -+ break; -+ } -+ case MPTCP_SUB_REMOVE_ADDR: -+ if ((opsize - MPTCP_SUB_LEN_REMOVE_ADDR) < 0) { -+ mptcp_debug("%s: mp_remove_addr: bad option size %d\n", -+ __func__, opsize); -+ break; -+ } -+ -+ if (mopt->saw_rem_addr) { -+ mopt->more_rem_addr = 1; -+ break; -+ } -+ mopt->saw_rem_addr = 1; -+ mopt->rem_addr_ptr = ptr; -+ break; -+ case MPTCP_SUB_PRIO: -+ { -+ const struct mp_prio *mpprio = (struct mp_prio *)ptr; -+ -+ if (opsize != MPTCP_SUB_LEN_PRIO && -+ opsize != MPTCP_SUB_LEN_PRIO_ADDR) { -+ mptcp_debug("%s: mp_prio: bad option size %d\n", -+ __func__, opsize); -+ break; -+ } -+ -+ mopt->saw_low_prio = 1; -+ mopt->low_prio = mpprio->b; -+ -+ if (opsize == MPTCP_SUB_LEN_PRIO_ADDR) { -+ mopt->saw_low_prio = 2; -+ mopt->prio_addr_id = mpprio->addr_id; -+ } -+ break; -+ } -+ case MPTCP_SUB_FAIL: -+ if (opsize != MPTCP_SUB_LEN_FAIL) { -+ mptcp_debug("%s: mp_fail: bad option size %d\n", -+ __func__, opsize); -+ break; -+ } -+ mopt->mp_fail = 1; -+ break; -+ case MPTCP_SUB_FCLOSE: -+ if (opsize != MPTCP_SUB_LEN_FCLOSE) { -+ mptcp_debug("%s: mp_fclose: bad option size %d\n", -+ __func__, opsize); -+ break; -+ } -+ -+ mopt->mp_fclose = 1; -+ mopt->mptcp_sender_key = ((struct mp_fclose *)ptr)->key; -+ -+ break; -+ default: -+ mptcp_debug("%s: Received unkown subtype: %d\n", -+ __func__, mp_opt->sub); -+ break; -+ } -+} -+ -+/** Parse only MPTCP options */ -+void tcp_parse_mptcp_options(const struct sk_buff *skb, -+ struct mptcp_options_received *mopt) -+{ -+ const struct tcphdr *th = tcp_hdr(skb); -+ int length = (th->doff * 4) - sizeof(struct tcphdr); -+ const unsigned char *ptr = (const unsigned char *)(th + 1); -+ -+ while (length > 0) { -+ int opcode = *ptr++; -+ int opsize; -+ -+ switch (opcode) { -+ case TCPOPT_EOL: -+ return; -+ case TCPOPT_NOP: /* Ref: RFC 793 section 3.1 */ -+ length--; -+ continue; -+ default: -+ opsize = *ptr++; -+ if (opsize < 2) /* "silly options" */ -+ return; -+ if (opsize > length) -+ return; /* don't parse partial options */ -+ if (opcode == TCPOPT_MPTCP) -+ mptcp_parse_options(ptr - 2, opsize, mopt, skb, NULL); -+ } -+ ptr += opsize - 2; -+ length -= opsize; -+ } -+} -+ -+bool mptcp_check_rtt(const struct tcp_sock *tp, int time) -+{ -+ struct mptcp_cb *mpcb = tp->mpcb; -+ struct mptcp_tcp_sock *mptcp; -+ u32 rtt_max = 0; -+ -+ /* In MPTCP, we take the max delay across all flows, -+ * in order to take into account meta-reordering buffers. -+ */ -+ mptcp_for_each_sub(mpcb, mptcp) { -+ struct sock *sk = mptcp_to_sock(mptcp); -+ -+ if (!mptcp_sk_can_recv(sk)) -+ continue; -+ -+ if (rtt_max < tcp_sk(sk)->rcv_rtt_est.rtt_us) -+ rtt_max = tcp_sk(sk)->rcv_rtt_est.rtt_us; -+ } -+ if (time < (rtt_max >> 3) || !rtt_max) -+ return true; -+ -+ return false; -+} -+ -+static void mptcp_handle_add_addr(const unsigned char *ptr, struct sock *sk) -+{ -+ struct mp_add_addr *mpadd = (struct mp_add_addr *)ptr; -+ struct mptcp_cb *mpcb = tcp_sk(sk)->mpcb; -+ union inet_addr addr; -+ sa_family_t family; -+ __be16 port = 0; -+ bool is_v4; -+ -+ if (mpcb->mptcp_ver < MPTCP_VERSION_1) { -+ is_v4 = mpadd->u_bit.v0.ipver == 4; -+ } else { -+ is_v4 = mpadd->len == MPTCP_SUB_LEN_ADD_ADDR4_VER1 || -+ mpadd->len == MPTCP_SUB_LEN_ADD_ADDR4_VER1 + 2; -+ -+ /* TODO: support ADD_ADDRv1 retransmissions */ -+ if (mpadd->u_bit.v1.echo) -+ return; -+ } -+ -+ if (is_v4) { -+ u8 hash_mac_check[SHA256_DIGEST_SIZE]; -+ __be16 hmacport = 0; -+ char *recv_hmac; -+ -+ if (mpcb->mptcp_ver < MPTCP_VERSION_1) -+ goto skip_hmac_v4; -+ -+ recv_hmac = (char *)mpadd->u.v4.mac; -+ if (mpadd->len == MPTCP_SUB_LEN_ADD_ADDR4_VER1) { -+ recv_hmac -= sizeof(mpadd->u.v4.port); -+ } else if (mpadd->len == MPTCP_SUB_LEN_ADD_ADDR4_VER1 + 2) { -+ hmacport = mpadd->u.v4.port; -+ } -+ mptcp_hmac(mpcb->mptcp_ver, (u8 *)&mpcb->mptcp_rem_key, -+ (u8 *)&mpcb->mptcp_loc_key, hash_mac_check, 3, -+ 1, (u8 *)&mpadd->addr_id, -+ 4, (u8 *)&mpadd->u.v4.addr.s_addr, -+ 2, (u8 *)&hmacport); -+ if (memcmp(&hash_mac_check[SHA256_DIGEST_SIZE - sizeof(u64)], recv_hmac, 8) != 0) -+ /* ADD_ADDR2 discarded */ -+ return; -+skip_hmac_v4: -+ if ((mpcb->mptcp_ver == MPTCP_VERSION_0 && -+ mpadd->len == MPTCP_SUB_LEN_ADD_ADDR4 + 2) || -+ (mpcb->mptcp_ver == MPTCP_VERSION_1 && -+ mpadd->len == MPTCP_SUB_LEN_ADD_ADDR4_VER1 + 2)) -+ port = mpadd->u.v4.port; -+ family = AF_INET; -+ addr.in = mpadd->u.v4.addr; -+#if IS_ENABLED(CONFIG_IPV6) -+ } else { -+ u8 hash_mac_check[SHA256_DIGEST_SIZE]; -+ __be16 hmacport = 0; -+ char *recv_hmac; -+ -+ if (mpcb->mptcp_ver < MPTCP_VERSION_1) -+ goto skip_hmac_v6; -+ -+ recv_hmac = (char *)mpadd->u.v6.mac; -+ if (mpadd->len == MPTCP_SUB_LEN_ADD_ADDR6_VER1) { -+ recv_hmac -= sizeof(mpadd->u.v6.port); -+ } else if (mpadd->len == MPTCP_SUB_LEN_ADD_ADDR6_VER1 + 2) { -+ hmacport = mpadd->u.v6.port; -+ } -+ mptcp_hmac(mpcb->mptcp_ver, (u8 *)&mpcb->mptcp_rem_key, -+ (u8 *)&mpcb->mptcp_loc_key, hash_mac_check, 3, -+ 1, (u8 *)&mpadd->addr_id, -+ 16, (u8 *)&mpadd->u.v6.addr.s6_addr, -+ 2, (u8 *)&hmacport); -+ if (memcmp(&hash_mac_check[SHA256_DIGEST_SIZE - sizeof(u64)], recv_hmac, 8) != 0) -+ /* ADD_ADDR2 discarded */ -+ return; -+skip_hmac_v6: -+ if ((mpcb->mptcp_ver == MPTCP_VERSION_0 && -+ mpadd->len == MPTCP_SUB_LEN_ADD_ADDR6 + 2) || -+ (mpcb->mptcp_ver == MPTCP_VERSION_1 && -+ mpadd->len == MPTCP_SUB_LEN_ADD_ADDR6_VER1 + 2)) -+ port = mpadd->u.v6.port; -+ family = AF_INET6; -+ addr.in6 = mpadd->u.v6.addr; -+#endif /* CONFIG_IPV6 */ -+ } -+ -+ if (mpcb->pm_ops->add_raddr) -+ mpcb->pm_ops->add_raddr(mpcb, &addr, family, port, mpadd->addr_id); -+ -+ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_ADDADDRRX); -+} -+ -+static void mptcp_handle_rem_addr(const unsigned char *ptr, struct sock *sk) -+{ -+ struct mp_remove_addr *mprem = (struct mp_remove_addr *)ptr; -+ int i; -+ u8 rem_id; -+ struct mptcp_cb *mpcb = tcp_sk(sk)->mpcb; -+ -+ for (i = 0; i <= mprem->len - MPTCP_SUB_LEN_REMOVE_ADDR; i++) { -+ rem_id = (&mprem->addrs_id)[i]; -+ -+ if (mpcb->pm_ops->rem_raddr) -+ mpcb->pm_ops->rem_raddr(mpcb, rem_id); -+ mptcp_send_reset_rem_id(mpcb, rem_id); -+ -+ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_REMADDRSUB); -+ } -+ -+ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_REMADDRRX); -+} -+ -+static void mptcp_parse_addropt(const struct sk_buff *skb, struct sock *sk) -+{ -+ struct tcphdr *th = tcp_hdr(skb); -+ unsigned char *ptr; -+ int length = (th->doff * 4) - sizeof(struct tcphdr); -+ -+ /* Jump through the options to check whether ADD_ADDR is there */ -+ ptr = (unsigned char *)(th + 1); -+ while (length > 0) { -+ int opcode = *ptr++; -+ int opsize; -+ -+ switch (opcode) { -+ case TCPOPT_EOL: -+ return; -+ case TCPOPT_NOP: -+ length--; -+ continue; -+ default: -+ opsize = *ptr++; -+ if (opsize < 2) -+ return; -+ if (opsize > length) -+ return; /* don't parse partial options */ -+ if (opcode == TCPOPT_MPTCP && -+ ((struct mptcp_option *)ptr)->sub == MPTCP_SUB_ADD_ADDR) { -+ u8 mptcp_ver = tcp_sk(sk)->mpcb->mptcp_ver; -+ struct mp_add_addr *mpadd = (struct mp_add_addr *)ptr; -+ -+ if (!is_valid_addropt_opsize(mptcp_ver, mpadd, -+ opsize)) -+ goto cont; -+ -+ mptcp_handle_add_addr(ptr, sk); -+ } -+ if (opcode == TCPOPT_MPTCP && -+ ((struct mptcp_option *)ptr)->sub == MPTCP_SUB_REMOVE_ADDR) { -+ if ((opsize - MPTCP_SUB_LEN_REMOVE_ADDR) < 0) -+ goto cont; -+ -+ mptcp_handle_rem_addr(ptr, sk); -+ } -+cont: -+ ptr += opsize - 2; -+ length -= opsize; -+ } -+ } -+ return; -+} -+ -+static bool mptcp_mp_fastclose_rcvd(struct sock *sk) -+{ -+ struct mptcp_tcp_sock *mptcp = tcp_sk(sk)->mptcp; -+ struct mptcp_cb *mpcb = tcp_sk(sk)->mpcb; -+ -+ if (likely(!mptcp->rx_opt.mp_fclose)) -+ return false; -+ -+ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_FASTCLOSERX); -+ mptcp->rx_opt.mp_fclose = 0; -+ if (mptcp->rx_opt.mptcp_sender_key != mpcb->mptcp_loc_key) -+ return false; -+ -+ mptcp_sub_force_close_all(mpcb, NULL); -+ -+ tcp_reset(mptcp_meta_sk(sk)); -+ -+ return true; -+} -+ -+static void mptcp_mp_fail_rcvd(struct sock *sk, const struct tcphdr *th) -+{ -+ struct mptcp_tcp_sock *mptcp = tcp_sk(sk)->mptcp; -+ struct sock *meta_sk = mptcp_meta_sk(sk); -+ struct mptcp_cb *mpcb = tcp_sk(sk)->mpcb; -+ -+ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_MPFAILRX); -+ mptcp->rx_opt.mp_fail = 0; -+ -+ if (!th->rst && !mpcb->infinite_mapping_snd) { -+ mpcb->send_infinite_mapping = 1; -+ -+ mptcp_restart_sending(meta_sk); -+ -+ mptcp_fallback_close(mpcb, sk); -+ } -+} -+ -+static inline void mptcp_path_array_check(struct sock *meta_sk) -+{ -+ struct mptcp_cb *mpcb = tcp_sk(meta_sk)->mpcb; -+ -+ if (unlikely(mpcb->list_rcvd)) { -+ mpcb->list_rcvd = 0; -+ if (mpcb->pm_ops->new_remote_address) -+ mpcb->pm_ops->new_remote_address(meta_sk); -+ } -+} -+ -+bool mptcp_handle_options(struct sock *sk, const struct tcphdr *th, -+ const struct sk_buff *skb) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct mptcp_options_received *mopt = &tp->mptcp->rx_opt; -+ struct mptcp_cb *mpcb = tp->mpcb; -+ -+ if (tp->mpcb->infinite_mapping_rcv || tp->mpcb->infinite_mapping_snd) -+ return false; -+ -+ if (mptcp_mp_fastclose_rcvd(sk)) -+ return true; -+ -+ if (sk->sk_state == TCP_RST_WAIT && !th->rst) -+ return true; -+ -+ if (mopt->saw_mpc && !tp->mpcb->rem_key_set) -+ mptcp_initialize_recv_vars(mptcp_meta_tp(tp), tp->mpcb, -+ mopt->mptcp_sender_key); -+ -+ if (unlikely(mopt->mp_fail)) -+ mptcp_mp_fail_rcvd(sk, th); -+ -+ /* RFC 6824, Section 3.3: -+ * If a checksum is not present when its use has been negotiated, the -+ * receiver MUST close the subflow with a RST as it is considered broken. -+ */ -+ if ((mptcp_is_data_seq(skb) || mptcp_is_data_mpcapable(skb)) && -+ tp->mpcb->dss_csum && -+ !(TCP_SKB_CB(skb)->mptcp_flags & MPTCPHDR_DSS_CSUM)) { -+ mptcp_send_reset(sk); -+ return true; -+ } -+ -+ /* We have to acknowledge retransmissions of the third -+ * ack. -+ */ -+ if (mopt->join_ack) { -+ tcp_send_delayed_ack(sk); -+ mopt->join_ack = 0; -+ } -+ -+ if (mopt->saw_add_addr || mopt->saw_rem_addr) { -+ if (mopt->more_add_addr || mopt->more_rem_addr) { -+ mptcp_parse_addropt(skb, sk); -+ } else { -+ if (mopt->saw_add_addr) -+ mptcp_handle_add_addr(mopt->add_addr_ptr, sk); -+ if (mopt->saw_rem_addr) -+ mptcp_handle_rem_addr(mopt->rem_addr_ptr, sk); -+ } -+ -+ mopt->more_add_addr = 0; -+ mopt->saw_add_addr = 0; -+ mopt->more_rem_addr = 0; -+ mopt->saw_rem_addr = 0; -+ } -+ if (mopt->saw_low_prio) { -+ if (mopt->saw_low_prio == 1) { -+ tp->mptcp->rcv_low_prio = mopt->low_prio; -+ if (mpcb->pm_ops->prio_changed) -+ mpcb->pm_ops->prio_changed(sk, mopt->low_prio); -+ } else { -+ struct mptcp_tcp_sock *mptcp; -+ -+ mptcp_for_each_sub(tp->mpcb, mptcp) { -+ if (mptcp->rem_id == mopt->prio_addr_id) { -+ mptcp->rcv_low_prio = mopt->low_prio; -+ if (mpcb->pm_ops->prio_changed) -+ mpcb->pm_ops->prio_changed(sk, -+ mopt->low_prio); -+ } -+ } -+ } -+ mopt->saw_low_prio = 0; -+ } -+ -+ if (mptcp_process_data_ack(sk, skb)) -+ return true; -+ -+ mptcp_path_array_check(mptcp_meta_sk(sk)); -+ /* Socket may have been mp_killed by a REMOVE_ADDR */ -+ if (tp->mp_killed) -+ return true; -+ -+ return false; -+} -+ -+static void _mptcp_rcv_synsent_fastopen(struct sock *meta_sk, -+ struct sk_buff *skb, bool rtx_queue) -+{ -+ struct tcp_sock *meta_tp = tcp_sk(meta_sk); -+ struct tcp_sock *master_tp = tcp_sk(meta_tp->mpcb->master_sk); -+ u32 new_mapping = meta_tp->write_seq - master_tp->snd_una; -+ -+ /* If the server only acknowledges partially the data sent in -+ * the SYN, we need to trim the acknowledged part because -+ * we don't want to retransmit this already received data. -+ * When we reach this point, tcp_ack() has already cleaned up -+ * fully acked segments. However, tcp trims partially acked -+ * segments only when retransmitting. Since MPTCP comes into -+ * play only now, we will fake an initial transmit, and -+ * retransmit_skb() will not be called. The following fragment -+ * comes from __tcp_retransmit_skb(). -+ */ -+ if (before(TCP_SKB_CB(skb)->seq, master_tp->snd_una)) { -+ BUG_ON(before(TCP_SKB_CB(skb)->end_seq, -+ master_tp->snd_una)); -+ /* tcp_trim_head can only returns ENOMEM if skb is -+ * cloned. It is not the case here (see -+ * tcp_send_syn_data). -+ */ -+ BUG_ON(tcp_trim_head(meta_sk, skb, master_tp->snd_una - -+ TCP_SKB_CB(skb)->seq)); -+ } -+ -+ TCP_SKB_CB(skb)->seq += new_mapping; -+ TCP_SKB_CB(skb)->end_seq += new_mapping; -+ TCP_SKB_CB(skb)->sacked = 0; -+ -+ list_del(&skb->tcp_tsorted_anchor); -+ -+ if (rtx_queue) -+ tcp_rtx_queue_unlink(skb, meta_sk); -+ else -+ tcp_unlink_write_queue(skb, meta_sk); -+ -+ INIT_LIST_HEAD(&skb->tcp_tsorted_anchor); -+ -+ tcp_add_write_queue_tail(meta_sk, skb); -+} -+ -+/* In case of fastopen, some data can already be in the write queue. -+ * We need to update the sequence number of the segments as they -+ * were initially TCP sequence numbers. -+ */ -+static void mptcp_rcv_synsent_fastopen(struct sock *meta_sk) -+{ -+ struct tcp_sock *meta_tp = tcp_sk(meta_sk); -+ struct tcp_sock *master_tp = tcp_sk(meta_tp->mpcb->master_sk); -+ struct sk_buff *skb_write_head, *skb_rtx_head, *tmp; -+ -+ skb_write_head = tcp_write_queue_head(meta_sk); -+ skb_rtx_head = tcp_rtx_queue_head(meta_sk); -+ -+ if (!(skb_write_head || skb_rtx_head)) -+ return; -+ -+ /* There should only be one skb in {write, rtx} queue: the data not -+ * acknowledged in the SYN+ACK. In this case, we need to map -+ * this data to data sequence numbers. -+ */ -+ -+ WARN_ON(skb_write_head && skb_rtx_head); -+ -+ if (skb_write_head) { -+ skb_queue_walk_from_safe(&meta_sk->sk_write_queue, -+ skb_write_head, tmp) { -+ _mptcp_rcv_synsent_fastopen(meta_sk, skb_write_head, -+ false); -+ } -+ } -+ -+ if (skb_rtx_head) { -+ skb_rbtree_walk_from_safe(skb_rtx_head, tmp) { -+ _mptcp_rcv_synsent_fastopen(meta_sk, skb_rtx_head, -+ true); -+ } -+ } -+ -+ /* We can advance write_seq by the number of bytes unacknowledged -+ * and that were mapped in the previous loop. -+ */ -+ meta_tp->write_seq += master_tp->write_seq - master_tp->snd_una; -+ -+ /* The packets from the master_sk will be entailed to it later -+ * Until that time, its write queue is empty, and -+ * write_seq must align with snd_una -+ */ -+ master_tp->snd_nxt = master_tp->write_seq = master_tp->snd_una; -+ master_tp->packets_out = 0; -+ tcp_clear_retrans(meta_tp); -+ tcp_clear_retrans(master_tp); -+ tcp_set_ca_state(meta_tp->mpcb->master_sk, TCP_CA_Open); -+ tcp_set_ca_state(meta_sk, TCP_CA_Open); -+} -+ -+/* The skptr is needed, because if we become MPTCP-capable, we have to switch -+ * from meta-socket to master-socket. -+ * -+ * @return: 1 - we want to reset this connection -+ * 2 - we want to discard the received syn/ack -+ * 0 - everything is fine - continue -+ */ -+int mptcp_rcv_synsent_state_process(struct sock *sk, struct sock **skptr, -+ const struct sk_buff *skb, -+ const struct mptcp_options_received *mopt) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ -+ if (mptcp(tp)) { -+ u8 hash_mac_check[SHA256_DIGEST_SIZE]; -+ struct mptcp_cb *mpcb = tp->mpcb; -+ -+ mptcp_hmac(mpcb->mptcp_ver, (u8 *)&mpcb->mptcp_rem_key, -+ (u8 *)&mpcb->mptcp_loc_key, hash_mac_check, 2, -+ 4, (u8 *)&tp->mptcp->rx_opt.mptcp_recv_nonce, -+ 4, (u8 *)&tp->mptcp->mptcp_loc_nonce); -+ if (memcmp(hash_mac_check, -+ (char *)&tp->mptcp->rx_opt.mptcp_recv_tmac, 8)) { -+ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_JOINSYNACKMAC); -+ mptcp_sub_force_close(sk); -+ return 1; -+ } -+ -+ /* Set this flag in order to postpone data sending -+ * until the 4th ack arrives. -+ */ -+ tp->mptcp->pre_established = 1; -+ tp->mptcp->rcv_low_prio = tp->mptcp->rx_opt.low_prio; -+ -+ mptcp_hmac(mpcb->mptcp_ver, (u8 *)&mpcb->mptcp_loc_key, -+ (u8 *)&mpcb->mptcp_rem_key, -+ tp->mptcp->sender_mac, 2, -+ 4, (u8 *)&tp->mptcp->mptcp_loc_nonce, -+ 4, (u8 *)&tp->mptcp->rx_opt.mptcp_recv_nonce); -+ -+ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_JOINSYNACKRX); -+ } else if (mopt->saw_mpc) { -+ struct sock *meta_sk = sk; -+ -+ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_MPCAPABLEACTIVEACK); -+ if (mopt->mptcp_ver > tcp_sk(sk)->mptcp_ver) -+ /* TODO Consider adding new MPTCP_INC_STATS entry */ -+ goto fallback; -+ if (tcp_sk(sk)->mptcp_ver == MPTCP_VERSION_1 && -+ mopt->mptcp_ver < MPTCP_VERSION_1) -+ /* TODO Consider adding new MPTCP_INC_STATS entry */ -+ /* TODO - record this in the cache - use v0 next time */ -+ goto fallback; -+ -+ if (mptcp_create_master_sk(sk, mopt->mptcp_sender_key, 1, -+ mopt->mptcp_ver, -+ ntohs(tcp_hdr(skb)->window))) -+ return 2; -+ -+ sk = tcp_sk(sk)->mpcb->master_sk; -+ *skptr = sk; -+ tp = tcp_sk(sk); -+ -+ /* If fastopen was used data might be in the send queue. We -+ * need to update their sequence number to MPTCP-level seqno. -+ * Note that it can happen in rare cases that fastopen_req is -+ * NULL and syn_data is 0 but fastopen indeed occurred and -+ * data has been queued in the write queue (but not sent). -+ * Example of such rare cases: connect is non-blocking and -+ * TFO is configured to work without cookies. -+ */ -+ mptcp_rcv_synsent_fastopen(meta_sk); -+ -+ /* -1, because the SYN consumed 1 byte. In case of TFO, we -+ * start the subflow-sequence number as if the data of the SYN -+ * is not part of any mapping. -+ */ -+ tp->mptcp->snt_isn = tp->snd_una - 1; -+ tp->mpcb->dss_csum = mopt->dss_csum; -+ if (tp->mpcb->dss_csum) -+ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_CSUMENABLED); -+ -+ if (tp->mpcb->mptcp_ver >= MPTCP_VERSION_1) -+ tp->mpcb->send_mptcpv1_mpcapable = 1; -+ -+ tp->mptcp->include_mpc = 1; -+ -+ /* Ensure that fastopen is handled at the meta-level. */ -+ tp->fastopen_req = NULL; -+ -+ sk_set_socket(sk, meta_sk->sk_socket); -+ sk->sk_wq = meta_sk->sk_wq; -+ -+ bh_unlock_sock(sk); -+ /* hold in sk_clone_lock due to initialization to 2 */ -+ sock_put(sk); -+ } else { -+ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_MPCAPABLEACTIVEFALLBACK); -+fallback: -+ tp->request_mptcp = 0; -+ -+ if (tp->inside_tk_table) -+ mptcp_hash_remove_bh(tp); -+ } -+ -+ if (mptcp(tp)) -+ tp->mptcp->rcv_isn = TCP_SKB_CB(skb)->seq; -+ -+ return 0; -+} -+ -+/* Similar to tcp_should_expand_sndbuf */ -+bool mptcp_should_expand_sndbuf(const struct sock *sk) -+{ -+ const struct sock *meta_sk = mptcp_meta_sk(sk); -+ const struct tcp_sock *meta_tp = tcp_sk(meta_sk); -+ const struct mptcp_tcp_sock *mptcp; -+ -+ /* We circumvent this check in tcp_check_space, because we want to -+ * always call sk_write_space. So, we reproduce the check here. -+ */ -+ if (!meta_sk->sk_socket || -+ !test_bit(SOCK_NOSPACE, &meta_sk->sk_socket->flags)) -+ return false; -+ -+ /* If the user specified a specific send buffer setting, do -+ * not modify it. -+ */ -+ if (meta_sk->sk_userlocks & SOCK_SNDBUF_LOCK) -+ return false; -+ -+ /* If we are under global TCP memory pressure, do not expand. */ -+ if (tcp_under_memory_pressure(meta_sk)) -+ return false; -+ -+ /* If we are under soft global TCP memory pressure, do not expand. */ -+ if (sk_memory_allocated(meta_sk) >= sk_prot_mem_limits(meta_sk, 0)) -+ return false; -+ -+ /* For MPTCP we look for a subsocket that could send data. -+ * If we found one, then we update the send-buffer. -+ */ -+ mptcp_for_each_sub(meta_tp->mpcb, mptcp) { -+ const struct sock *sk_it = mptcp_to_sock(mptcp); -+ const struct tcp_sock *tp_it = tcp_sk(sk_it); -+ -+ if (!mptcp_sk_can_send(sk_it)) -+ continue; -+ -+ if (tcp_packets_in_flight(tp_it) < tp_it->snd_cwnd) -+ return true; -+ } -+ -+ return false; -+} -+ -+void mptcp_tcp_set_rto(struct sock *sk) -+{ -+ tcp_set_rto(sk); -+ mptcp_set_rto(sk); -+} -diff -aurN linux-5.4.64/net/mptcp/mptcp_ipv4.c linux-5.4.64.mptcp/net/mptcp/mptcp_ipv4.c ---- linux-5.4.64/net/mptcp/mptcp_ipv4.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-5.4.64.mptcp/net/mptcp/mptcp_ipv4.c 2020-09-10 19:25:10.507220869 +0200 -@@ -0,0 +1,431 @@ -+/* -+ * MPTCP implementation - IPv4-specific functions -+ * -+ * Initial Design & Implementation: -+ * Sébastien Barré -+ * -+ * Current Maintainer: -+ * Christoph Paasch -+ * -+ * Additional authors: -+ * Jaakko Korkeaniemi -+ * Gregory Detal -+ * Fabien Duchêne -+ * Andreas Seelinger -+ * Lavkesh Lahngir -+ * Andreas Ripke -+ * Vlad Dogaru -+ * Octavian Purdila -+ * John Ronan -+ * Catalin Nicutar -+ * Brandon Heller -+ * -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version -+ * 2 of the License, or (at your option) any later version. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+u32 mptcp_v4_get_nonce(__be32 saddr, __be32 daddr, __be16 sport, __be16 dport) -+{ -+ return siphash_4u32((__force u32)saddr, (__force u32)daddr, -+ (__force u32)sport << 16 | (__force u32)dport, -+ mptcp_seed++, &mptcp_secret); -+} -+ -+u64 mptcp_v4_get_key(__be32 saddr, __be32 daddr, __be16 sport, __be16 dport, -+ u32 seed) -+{ -+ return siphash_2u64((__force u64)saddr << 32 | (__force u64)daddr, -+ (__force u64)seed << 32 | (__force u64)sport << 16 | (__force u64)dport, -+ &mptcp_secret); -+} -+ -+ -+static void mptcp_v4_reqsk_destructor(struct request_sock *req) -+{ -+ mptcp_reqsk_destructor(req); -+ -+ tcp_v4_reqsk_destructor(req); -+} -+ -+static int mptcp_v4_init_req(struct request_sock *req, const struct sock *sk, -+ struct sk_buff *skb, bool want_cookie) -+{ -+ tcp_request_sock_ipv4_ops.init_req(req, sk, skb, want_cookie); -+ -+ mptcp_rsk(req)->hash_entry.pprev = NULL; -+ mptcp_rsk(req)->is_sub = 0; -+ inet_rsk(req)->mptcp_rqsk = 1; -+ -+ /* In case of SYN-cookies, we wait for the isn to be generated - it is -+ * input to the key-generation. -+ */ -+ if (!want_cookie) -+ mptcp_reqsk_init(req, sk, skb, false); -+ -+ return 0; -+} -+ -+#ifdef CONFIG_SYN_COOKIES -+static u32 mptcp_v4_cookie_init_seq(struct request_sock *req, const struct sock *sk, -+ const struct sk_buff *skb, __u16 *mssp) -+{ -+ __u32 isn = cookie_v4_init_sequence(req, sk, skb, mssp); -+ -+ tcp_rsk(req)->snt_isn = isn; -+ -+ mptcp_reqsk_init(req, sk, skb, true); -+ -+ return isn; -+} -+#endif -+ -+/* May be called without holding the meta-level lock */ -+static int mptcp_v4_join_init_req(struct request_sock *req, const struct sock *meta_sk, -+ struct sk_buff *skb, bool want_cookie) -+{ -+ struct mptcp_request_sock *mtreq = mptcp_rsk(req); -+ const struct mptcp_cb *mpcb = tcp_sk(meta_sk)->mpcb; -+ union inet_addr addr; -+ int loc_id; -+ bool low_prio = false; -+ -+ if (!mpcb->rem_key_set) -+ return -1; -+ -+ /* We need to do this as early as possible. Because, if we fail later -+ * (e.g., get_local_id), then reqsk_free tries to remove the -+ * request-socket from the htb in mptcp_hash_request_remove as pprev -+ * may be different from NULL. -+ */ -+ mtreq->hash_entry.pprev = NULL; -+ -+ tcp_request_sock_ipv4_ops.init_req(req, meta_sk, skb, want_cookie); -+ -+ mtreq->mptcp_loc_nonce = mptcp_v4_get_nonce(ip_hdr(skb)->saddr, -+ ip_hdr(skb)->daddr, -+ tcp_hdr(skb)->source, -+ tcp_hdr(skb)->dest); -+ addr.ip = inet_rsk(req)->ir_loc_addr; -+ loc_id = mpcb->pm_ops->get_local_id(meta_sk, AF_INET, &addr, &low_prio); -+ if (loc_id == -1) -+ return -1; -+ mtreq->loc_id = loc_id; -+ mtreq->low_prio = low_prio; -+ -+ mptcp_join_reqsk_init(mpcb, req, skb); -+ -+ return 0; -+} -+ -+/* Similar to tcp_request_sock_ops */ -+struct request_sock_ops mptcp_request_sock_ops __read_mostly = { -+ .family = PF_INET, -+ .obj_size = sizeof(struct mptcp_request_sock), -+ .rtx_syn_ack = tcp_rtx_synack, -+ .send_ack = tcp_v4_reqsk_send_ack, -+ .destructor = mptcp_v4_reqsk_destructor, -+ .send_reset = tcp_v4_send_reset, -+ .syn_ack_timeout = tcp_syn_ack_timeout, -+}; -+ -+/* Similar to: tcp_v4_conn_request -+ * May be called without holding the meta-level lock -+ */ -+static int mptcp_v4_join_request(struct sock *meta_sk, struct sk_buff *skb) -+{ -+ return tcp_conn_request(&mptcp_request_sock_ops, -+ &mptcp_join_request_sock_ipv4_ops, -+ meta_sk, skb); -+} -+ -+/* Similar to: tcp_v4_do_rcv -+ * We only process join requests here. (either the SYN or the final ACK) -+ */ -+int mptcp_v4_do_rcv(struct sock *meta_sk, struct sk_buff *skb) -+{ -+ const struct tcphdr *th = tcp_hdr(skb); -+ const struct iphdr *iph = ip_hdr(skb); -+ struct sock *child, *rsk = NULL, *sk; -+ int ret; -+ -+ sk = inet_lookup_established(sock_net(meta_sk), &tcp_hashinfo, -+ iph->saddr, th->source, iph->daddr, -+ th->dest, inet_iif(skb)); -+ -+ if (!sk) -+ goto new_subflow; -+ -+ if (is_meta_sk(sk)) { -+ WARN("%s Did not find a sub-sk - did found the meta!\n", __func__); -+ sock_put(sk); -+ goto discard; -+ } -+ -+ if (sk->sk_state == TCP_TIME_WAIT) { -+ inet_twsk_put(inet_twsk(sk)); -+ goto discard; -+ } -+ -+ if (sk->sk_state == TCP_NEW_SYN_RECV) { -+ struct request_sock *req = inet_reqsk(sk); -+ bool req_stolen; -+ -+ if (!mptcp_can_new_subflow(meta_sk)) -+ goto reset_and_discard; -+ -+ local_bh_disable(); -+ child = tcp_check_req(meta_sk, skb, req, false, &req_stolen); -+ if (!child) { -+ reqsk_put(req); -+ local_bh_enable(); -+ goto discard; -+ } -+ -+ if (child != meta_sk) { -+ ret = mptcp_finish_handshake(child, skb); -+ if (ret) { -+ rsk = child; -+ local_bh_enable(); -+ goto reset_and_discard; -+ } -+ -+ bh_unlock_sock(meta_sk); -+ local_bh_enable(); -+ return 0; -+ } -+ -+ /* tcp_check_req failed */ -+ reqsk_put(req); -+ -+ local_bh_enable(); -+ goto discard; -+ } -+ -+ ret = tcp_v4_do_rcv(sk, skb); -+ sock_put(sk); -+ -+ return ret; -+ -+new_subflow: -+ if (!mptcp_can_new_subflow(meta_sk)) -+ goto reset_and_discard; -+ -+ child = tcp_v4_cookie_check(meta_sk, skb); -+ if (!child) -+ goto discard; -+ -+ if (child != meta_sk) { -+ ret = mptcp_finish_handshake(child, skb); -+ if (ret) { -+ rsk = child; -+ goto reset_and_discard; -+ } -+ } -+ -+ if (tcp_hdr(skb)->syn) { -+ local_bh_disable(); -+ mptcp_v4_join_request(meta_sk, skb); -+ local_bh_enable(); -+ } -+ -+discard: -+ kfree_skb(skb); -+ return 0; -+ -+reset_and_discard: -+ tcp_v4_send_reset(rsk, skb); -+ goto discard; -+} -+ -+/* Create a new IPv4 subflow. -+ * -+ * We are in user-context and meta-sock-lock is hold. -+ */ -+int __mptcp_init4_subsockets(struct sock *meta_sk, const struct mptcp_loc4 *loc, -+ __be16 sport, struct mptcp_rem4 *rem, -+ struct sock **subsk) -+{ -+ struct tcp_sock *tp; -+ struct sock *sk; -+ struct sockaddr_in loc_in, rem_in; -+ struct socket_alloc sock_full; -+ struct socket *sock = (struct socket *)&sock_full; -+ int ret; -+ -+ /** First, create and prepare the new socket */ -+ memcpy(&sock_full, meta_sk->sk_socket, sizeof(sock_full)); -+ sock->state = SS_UNCONNECTED; -+ sock->ops = NULL; -+ -+ ret = inet_create(sock_net(meta_sk), sock, IPPROTO_TCP, 1); -+ if (unlikely(ret < 0)) { -+ net_err_ratelimited("%s inet_create failed ret: %d\n", -+ __func__, ret); -+ return ret; -+ } -+ -+ sk = sock->sk; -+ tp = tcp_sk(sk); -+ -+ /* All subsockets need the MPTCP-lock-class */ -+ lockdep_set_class_and_name(&(sk)->sk_lock.slock, &meta_slock_key, meta_slock_key_name); -+ lockdep_init_map(&(sk)->sk_lock.dep_map, meta_key_name, &meta_key, 0); -+ -+ ret = mptcp_add_sock(meta_sk, sk, loc->loc4_id, rem->rem4_id, GFP_KERNEL); -+ if (ret) { -+ net_err_ratelimited("%s mptcp_add_sock failed ret: %d\n", -+ __func__, ret); -+ goto error; -+ } -+ -+ tp->mptcp->slave_sk = 1; -+ tp->mptcp->low_prio = loc->low_prio; -+ -+ /* Initializing the timer for an MPTCP subflow */ -+ timer_setup(&tp->mptcp->mptcp_ack_timer, mptcp_ack_handler, 0); -+ -+ /** Then, connect the socket to the peer */ -+ loc_in.sin_family = AF_INET; -+ rem_in.sin_family = AF_INET; -+ loc_in.sin_port = sport; -+ if (rem->port) -+ rem_in.sin_port = rem->port; -+ else -+ rem_in.sin_port = inet_sk(meta_sk)->inet_dport; -+ loc_in.sin_addr = loc->addr; -+ rem_in.sin_addr = rem->addr; -+ -+ if (loc->if_idx) -+ sk->sk_bound_dev_if = loc->if_idx; -+ -+ ret = kernel_bind(sock, (struct sockaddr *)&loc_in, -+ sizeof(struct sockaddr_in)); -+ if (ret < 0) { -+ net_err_ratelimited("%s: token %#x bind() to %pI4 index %d failed, error %d\n", -+ __func__, tcp_sk(meta_sk)->mpcb->mptcp_loc_token, -+ &loc_in.sin_addr, loc->if_idx, ret); -+ goto error; -+ } -+ -+ mptcp_debug("%s: token %#x pi %d src_addr:%pI4:%d dst_addr:%pI4:%d ifidx: %d\n", -+ __func__, tcp_sk(meta_sk)->mpcb->mptcp_loc_token, -+ tp->mptcp->path_index, &loc_in.sin_addr, -+ ntohs(loc_in.sin_port), &rem_in.sin_addr, -+ ntohs(rem_in.sin_port), loc->if_idx); -+ -+ if (tcp_sk(meta_sk)->mpcb->pm_ops->init_subsocket_v4) -+ tcp_sk(meta_sk)->mpcb->pm_ops->init_subsocket_v4(sk, rem->addr); -+ -+ ret = kernel_connect(sock, (struct sockaddr *)&rem_in, -+ sizeof(struct sockaddr_in), O_NONBLOCK); -+ if (ret < 0 && ret != -EINPROGRESS) { -+ net_err_ratelimited("%s: MPTCP subsocket connect() failed, error %d\n", -+ __func__, ret); -+ goto error; -+ } -+ -+ MPTCP_INC_STATS(sock_net(meta_sk), MPTCP_MIB_JOINSYNTX); -+ -+ sk_set_socket(sk, meta_sk->sk_socket); -+ sk->sk_wq = meta_sk->sk_wq; -+ -+ if (subsk) -+ *subsk = sk; -+ -+ return 0; -+ -+error: -+ /* May happen if mptcp_add_sock fails first */ -+ if (!mptcp(tp)) { -+ tcp_close(sk, 0); -+ } else { -+ local_bh_disable(); -+ mptcp_sub_force_close(sk); -+ local_bh_enable(); -+ } -+ return ret; -+} -+EXPORT_SYMBOL(__mptcp_init4_subsockets); -+ -+const struct inet_connection_sock_af_ops mptcp_v4_specific = { -+ .queue_xmit = ip_queue_xmit, -+ .send_check = tcp_v4_send_check, -+ .rebuild_header = inet_sk_rebuild_header, -+ .sk_rx_dst_set = inet_sk_rx_dst_set, -+ .conn_request = mptcp_conn_request, -+ .syn_recv_sock = tcp_v4_syn_recv_sock, -+ .net_header_len = sizeof(struct iphdr), -+ .setsockopt = ip_setsockopt, -+ .getsockopt = ip_getsockopt, -+ .addr2sockaddr = inet_csk_addr2sockaddr, -+ .sockaddr_len = sizeof(struct sockaddr_in), -+#ifdef CONFIG_COMPAT -+ .compat_setsockopt = compat_ip_setsockopt, -+ .compat_getsockopt = compat_ip_getsockopt, -+#endif -+ .mtu_reduced = tcp_v4_mtu_reduced, -+}; -+ -+struct tcp_request_sock_ops mptcp_request_sock_ipv4_ops; -+struct tcp_request_sock_ops mptcp_join_request_sock_ipv4_ops; -+ -+/* General initialization of IPv4 for MPTCP */ -+int mptcp_pm_v4_init(void) -+{ -+ int ret = 0; -+ struct request_sock_ops *ops = &mptcp_request_sock_ops; -+ -+ mptcp_request_sock_ipv4_ops = tcp_request_sock_ipv4_ops; -+ mptcp_request_sock_ipv4_ops.init_req = mptcp_v4_init_req; -+#ifdef CONFIG_SYN_COOKIES -+ mptcp_request_sock_ipv4_ops.cookie_init_seq = mptcp_v4_cookie_init_seq; -+#endif -+ mptcp_join_request_sock_ipv4_ops = tcp_request_sock_ipv4_ops; -+ mptcp_join_request_sock_ipv4_ops.init_req = mptcp_v4_join_init_req; -+ -+ ops->slab_name = kasprintf(GFP_KERNEL, "request_sock_%s", "MPTCP"); -+ if (ops->slab_name == NULL) { -+ ret = -ENOMEM; -+ goto out; -+ } -+ -+ ops->slab = kmem_cache_create(ops->slab_name, ops->obj_size, 0, -+ SLAB_TYPESAFE_BY_RCU|SLAB_HWCACHE_ALIGN, -+ NULL); -+ -+ if (ops->slab == NULL) { -+ ret = -ENOMEM; -+ goto err_reqsk_create; -+ } -+ -+out: -+ return ret; -+ -+err_reqsk_create: -+ kfree(ops->slab_name); -+ ops->slab_name = NULL; -+ goto out; -+} -+ -+void mptcp_pm_v4_undo(void) -+{ -+ kmem_cache_destroy(mptcp_request_sock_ops.slab); -+ kfree(mptcp_request_sock_ops.slab_name); -+} -diff -aurN linux-5.4.64/net/mptcp/mptcp_ipv6.c linux-5.4.64.mptcp/net/mptcp/mptcp_ipv6.c ---- linux-5.4.64/net/mptcp/mptcp_ipv6.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-5.4.64.mptcp/net/mptcp/mptcp_ipv6.c 2020-09-10 19:25:10.507220869 +0200 -@@ -0,0 +1,479 @@ -+/* -+ * MPTCP implementation - IPv6-specific functions -+ * -+ * Initial Design & Implementation: -+ * Sébastien Barré -+ * -+ * Current Maintainer: -+ * Jaakko Korkeaniemi -+ * -+ * Additional authors: -+ * Jaakko Korkeaniemi -+ * Gregory Detal -+ * Fabien Duchêne -+ * Andreas Seelinger -+ * Lavkesh Lahngir -+ * Andreas Ripke -+ * Vlad Dogaru -+ * Octavian Purdila -+ * John Ronan -+ * Catalin Nicutar -+ * Brandon Heller -+ * -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version -+ * 2 of the License, or (at your option) any later version. -+ */ -+ -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+__u32 mptcp_v6_get_nonce(const __be32 *saddr, const __be32 *daddr, -+ __be16 sport, __be16 dport) -+{ -+ const struct { -+ struct in6_addr saddr; -+ struct in6_addr daddr; -+ u32 seed; -+ __be16 sport; -+ __be16 dport; -+ } __aligned(SIPHASH_ALIGNMENT) combined = { -+ .saddr = *(struct in6_addr *)saddr, -+ .daddr = *(struct in6_addr *)daddr, -+ .seed = mptcp_seed++, -+ .sport = sport, -+ .dport = dport -+ }; -+ -+ return siphash(&combined, offsetofend(typeof(combined), dport), -+ &mptcp_secret); -+} -+ -+u64 mptcp_v6_get_key(const __be32 *saddr, const __be32 *daddr, -+ __be16 sport, __be16 dport, u32 seed) -+{ -+ const struct { -+ struct in6_addr saddr; -+ struct in6_addr daddr; -+ u32 seed; -+ __be16 sport; -+ __be16 dport; -+ } __aligned(SIPHASH_ALIGNMENT) combined = { -+ .saddr = *(struct in6_addr *)saddr, -+ .daddr = *(struct in6_addr *)daddr, -+ .seed = seed, -+ .sport = sport, -+ .dport = dport -+ }; -+ -+ return siphash(&combined, offsetofend(typeof(combined), dport), -+ &mptcp_secret); -+} -+ -+static void mptcp_v6_reqsk_destructor(struct request_sock *req) -+{ -+ mptcp_reqsk_destructor(req); -+ -+ tcp_v6_reqsk_destructor(req); -+} -+ -+static int mptcp_v6_init_req(struct request_sock *req, const struct sock *sk, -+ struct sk_buff *skb, bool want_cookie) -+{ -+ tcp_request_sock_ipv6_ops.init_req(req, sk, skb, want_cookie); -+ -+ mptcp_rsk(req)->hash_entry.pprev = NULL; -+ mptcp_rsk(req)->is_sub = 0; -+ inet_rsk(req)->mptcp_rqsk = 1; -+ -+ /* In case of SYN-cookies, we wait for the isn to be generated - it is -+ * input to the key-generation. -+ */ -+ if (!want_cookie) -+ mptcp_reqsk_init(req, sk, skb, false); -+ -+ return 0; -+} -+ -+#ifdef CONFIG_SYN_COOKIES -+static u32 mptcp_v6_cookie_init_seq(struct request_sock *req, const struct sock *sk, -+ const struct sk_buff *skb, __u16 *mssp) -+{ -+ __u32 isn = cookie_v6_init_sequence(req, sk, skb, mssp); -+ -+ tcp_rsk(req)->snt_isn = isn; -+ -+ mptcp_reqsk_init(req, sk, skb, true); -+ -+ return isn; -+} -+#endif -+ -+/* May be called without holding the meta-level lock */ -+static int mptcp_v6_join_init_req(struct request_sock *req, const struct sock *meta_sk, -+ struct sk_buff *skb, bool want_cookie) -+{ -+ struct mptcp_request_sock *mtreq = mptcp_rsk(req); -+ const struct mptcp_cb *mpcb = tcp_sk(meta_sk)->mpcb; -+ union inet_addr addr; -+ int loc_id; -+ bool low_prio = false; -+ -+ if (!mpcb->rem_key_set) -+ return -1; -+ -+ /* We need to do this as early as possible. Because, if we fail later -+ * (e.g., get_local_id), then reqsk_free tries to remove the -+ * request-socket from the htb in mptcp_hash_request_remove as pprev -+ * may be different from NULL. -+ */ -+ mtreq->hash_entry.pprev = NULL; -+ -+ tcp_request_sock_ipv6_ops.init_req(req, meta_sk, skb, want_cookie); -+ -+ mtreq->mptcp_loc_nonce = mptcp_v6_get_nonce(ipv6_hdr(skb)->saddr.s6_addr32, -+ ipv6_hdr(skb)->daddr.s6_addr32, -+ tcp_hdr(skb)->source, -+ tcp_hdr(skb)->dest); -+ addr.in6 = inet_rsk(req)->ir_v6_loc_addr; -+ loc_id = mpcb->pm_ops->get_local_id(meta_sk, AF_INET6, &addr, &low_prio); -+ if (loc_id == -1) -+ return -1; -+ mtreq->loc_id = loc_id; -+ mtreq->low_prio = low_prio; -+ -+ mptcp_join_reqsk_init(mpcb, req, skb); -+ -+ return 0; -+} -+ -+/* Similar to tcp6_request_sock_ops */ -+struct request_sock_ops mptcp6_request_sock_ops __read_mostly = { -+ .family = AF_INET6, -+ .obj_size = sizeof(struct mptcp_request_sock), -+ .rtx_syn_ack = tcp_rtx_synack, -+ .send_ack = tcp_v6_reqsk_send_ack, -+ .destructor = mptcp_v6_reqsk_destructor, -+ .send_reset = tcp_v6_send_reset, -+ .syn_ack_timeout = tcp_syn_ack_timeout, -+}; -+ -+/* Similar to: tcp_v6_conn_request -+ * May be called without holding the meta-level lock -+ */ -+static int mptcp_v6_join_request(struct sock *meta_sk, struct sk_buff *skb) -+{ -+ return tcp_conn_request(&mptcp6_request_sock_ops, -+ &mptcp_join_request_sock_ipv6_ops, -+ meta_sk, skb); -+} -+ -+int mptcp_v6_do_rcv(struct sock *meta_sk, struct sk_buff *skb) -+{ -+ const struct tcphdr *th = tcp_hdr(skb); -+ const struct ipv6hdr *ip6h = ipv6_hdr(skb); -+ struct sock *child, *rsk = NULL, *sk; -+ int ret; -+ -+ sk = __inet6_lookup_established(sock_net(meta_sk), -+ &tcp_hashinfo, -+ &ip6h->saddr, th->source, -+ &ip6h->daddr, ntohs(th->dest), -+ tcp_v6_iif(skb), tcp_v6_sdif(skb)); -+ -+ if (!sk) -+ goto new_subflow; -+ -+ if (is_meta_sk(sk)) { -+ WARN("%s Did not find a sub-sk - did found the meta!\n", __func__); -+ sock_put(sk); -+ goto discard; -+ } -+ -+ if (sk->sk_state == TCP_TIME_WAIT) { -+ inet_twsk_put(inet_twsk(sk)); -+ goto discard; -+ } -+ -+ if (sk->sk_state == TCP_NEW_SYN_RECV) { -+ struct request_sock *req = inet_reqsk(sk); -+ bool req_stolen; -+ -+ if (!mptcp_can_new_subflow(meta_sk)) -+ goto reset_and_discard; -+ -+ local_bh_disable(); -+ child = tcp_check_req(meta_sk, skb, req, false, &req_stolen); -+ if (!child) { -+ reqsk_put(req); -+ local_bh_enable(); -+ goto discard; -+ } -+ -+ if (child != meta_sk) { -+ ret = mptcp_finish_handshake(child, skb); -+ if (ret) { -+ rsk = child; -+ local_bh_enable(); -+ goto reset_and_discard; -+ } -+ -+ bh_unlock_sock(meta_sk); -+ local_bh_enable(); -+ return 0; -+ } -+ -+ /* tcp_check_req failed */ -+ reqsk_put(req); -+ -+ local_bh_enable(); -+ goto discard; -+ } -+ -+ ret = tcp_v6_do_rcv(sk, skb); -+ sock_put(sk); -+ -+ return ret; -+ -+new_subflow: -+ if (!mptcp_can_new_subflow(meta_sk)) -+ goto reset_and_discard; -+ -+ child = tcp_v6_cookie_check(meta_sk, skb); -+ if (!child) -+ goto discard; -+ -+ if (child != meta_sk) { -+ ret = mptcp_finish_handshake(child, skb); -+ if (ret) { -+ rsk = child; -+ goto reset_and_discard; -+ } -+ } -+ -+ if (tcp_hdr(skb)->syn) { -+ local_bh_disable(); -+ mptcp_v6_join_request(meta_sk, skb); -+ local_bh_enable(); -+ } -+ -+discard: -+ kfree_skb(skb); -+ return 0; -+ -+reset_and_discard: -+ tcp_v6_send_reset(rsk, skb); -+ goto discard; -+} -+ -+/* Create a new IPv6 subflow. -+ * -+ * We are in user-context and meta-sock-lock is hold. -+ */ -+int __mptcp_init6_subsockets(struct sock *meta_sk, const struct mptcp_loc6 *loc, -+ __be16 sport, struct mptcp_rem6 *rem, -+ struct sock **subsk) -+{ -+ struct tcp_sock *tp; -+ struct sock *sk; -+ struct sockaddr_in6 loc_in, rem_in; -+ struct socket_alloc sock_full; -+ struct socket *sock = (struct socket *)&sock_full; -+ int ret; -+ -+ /** First, create and prepare the new socket */ -+ memcpy(&sock_full, meta_sk->sk_socket, sizeof(sock_full)); -+ sock->state = SS_UNCONNECTED; -+ sock->ops = NULL; -+ -+ ret = inet6_create(sock_net(meta_sk), sock, IPPROTO_TCP, 1); -+ if (unlikely(ret < 0)) { -+ net_err_ratelimited("%s inet6_create failed ret: %d\n", -+ __func__, ret); -+ return ret; -+ } -+ -+ sk = sock->sk; -+ tp = tcp_sk(sk); -+ -+ /* All subsockets need the MPTCP-lock-class */ -+ lockdep_set_class_and_name(&(sk)->sk_lock.slock, &meta_slock_key, meta_slock_key_name); -+ lockdep_init_map(&(sk)->sk_lock.dep_map, meta_key_name, &meta_key, 0); -+ -+ ret = mptcp_add_sock(meta_sk, sk, loc->loc6_id, rem->rem6_id, GFP_KERNEL); -+ if (ret) { -+ net_err_ratelimited("%s mptcp_add_sock failed ret: %d\n", -+ __func__, ret); -+ goto error; -+ } -+ -+ tp->mptcp->slave_sk = 1; -+ tp->mptcp->low_prio = loc->low_prio; -+ -+ /* Initializing the timer for an MPTCP subflow */ -+ timer_setup(&tp->mptcp->mptcp_ack_timer, mptcp_ack_handler, 0); -+ -+ /** Then, connect the socket to the peer */ -+ loc_in.sin6_family = AF_INET6; -+ rem_in.sin6_family = AF_INET6; -+ loc_in.sin6_port = sport; -+ if (rem->port) -+ rem_in.sin6_port = rem->port; -+ else -+ rem_in.sin6_port = inet_sk(meta_sk)->inet_dport; -+ loc_in.sin6_addr = loc->addr; -+ rem_in.sin6_addr = rem->addr; -+ -+ if (loc->if_idx) -+ sk->sk_bound_dev_if = loc->if_idx; -+ -+ ret = kernel_bind(sock, (struct sockaddr *)&loc_in, -+ sizeof(struct sockaddr_in6)); -+ if (ret < 0) { -+ net_err_ratelimited("%s: token %#x bind() to %pI6 index %d failed, error %d\n", -+ __func__, tcp_sk(meta_sk)->mpcb->mptcp_loc_token, -+ &loc_in.sin6_addr, loc->if_idx, ret); -+ goto error; -+ } -+ -+ mptcp_debug("%s: token %#x pi %d src_addr:%pI6:%d dst_addr:%pI6:%d ifidx: %u\n", -+ __func__, tcp_sk(meta_sk)->mpcb->mptcp_loc_token, -+ tp->mptcp->path_index, &loc_in.sin6_addr, -+ ntohs(loc_in.sin6_port), &rem_in.sin6_addr, -+ ntohs(rem_in.sin6_port), loc->if_idx); -+ -+ if (tcp_sk(meta_sk)->mpcb->pm_ops->init_subsocket_v6) -+ tcp_sk(meta_sk)->mpcb->pm_ops->init_subsocket_v6(sk, rem->addr); -+ -+ ret = kernel_connect(sock, (struct sockaddr *)&rem_in, -+ sizeof(struct sockaddr_in6), O_NONBLOCK); -+ if (ret < 0 && ret != -EINPROGRESS) { -+ net_err_ratelimited("%s: MPTCP subsocket connect() failed, error %d\n", -+ __func__, ret); -+ goto error; -+ } -+ -+ MPTCP_INC_STATS(sock_net(meta_sk), MPTCP_MIB_JOINSYNTX); -+ -+ sk_set_socket(sk, meta_sk->sk_socket); -+ sk->sk_wq = meta_sk->sk_wq; -+ -+ if (subsk) -+ *subsk = sk; -+ -+ return 0; -+ -+error: -+ /* May happen if mptcp_add_sock fails first */ -+ if (!mptcp(tp)) { -+ tcp_close(sk, 0); -+ } else { -+ local_bh_disable(); -+ mptcp_sub_force_close(sk); -+ local_bh_enable(); -+ } -+ return ret; -+} -+EXPORT_SYMBOL(__mptcp_init6_subsockets); -+ -+const struct inet_connection_sock_af_ops mptcp_v6_specific = { -+ .queue_xmit = inet6_csk_xmit, -+ .send_check = tcp_v6_send_check, -+ .rebuild_header = inet6_sk_rebuild_header, -+ .sk_rx_dst_set = inet6_sk_rx_dst_set, -+ .conn_request = mptcp_conn_request, -+ .syn_recv_sock = tcp_v6_syn_recv_sock, -+ .net_header_len = sizeof(struct ipv6hdr), -+ .net_frag_header_len = sizeof(struct frag_hdr), -+ .setsockopt = ipv6_setsockopt, -+ .getsockopt = ipv6_getsockopt, -+ .addr2sockaddr = inet6_csk_addr2sockaddr, -+ .sockaddr_len = sizeof(struct sockaddr_in6), -+#ifdef CONFIG_COMPAT -+ .compat_setsockopt = compat_ipv6_setsockopt, -+ .compat_getsockopt = compat_ipv6_getsockopt, -+#endif -+ .mtu_reduced = tcp_v6_mtu_reduced, -+}; -+ -+const struct inet_connection_sock_af_ops mptcp_v6_mapped = { -+ .queue_xmit = ip_queue_xmit, -+ .send_check = tcp_v4_send_check, -+ .rebuild_header = inet_sk_rebuild_header, -+ .sk_rx_dst_set = inet_sk_rx_dst_set, -+ .conn_request = mptcp_conn_request, -+ .syn_recv_sock = tcp_v6_syn_recv_sock, -+ .net_header_len = sizeof(struct iphdr), -+ .setsockopt = ipv6_setsockopt, -+ .getsockopt = ipv6_getsockopt, -+ .addr2sockaddr = inet6_csk_addr2sockaddr, -+ .sockaddr_len = sizeof(struct sockaddr_in6), -+#ifdef CONFIG_COMPAT -+ .compat_setsockopt = compat_ipv6_setsockopt, -+ .compat_getsockopt = compat_ipv6_getsockopt, -+#endif -+ .mtu_reduced = tcp_v4_mtu_reduced, -+}; -+ -+struct tcp_request_sock_ops mptcp_request_sock_ipv6_ops; -+struct tcp_request_sock_ops mptcp_join_request_sock_ipv6_ops; -+ -+int mptcp_pm_v6_init(void) -+{ -+ int ret = 0; -+ struct request_sock_ops *ops = &mptcp6_request_sock_ops; -+ -+ mptcp_request_sock_ipv6_ops = tcp_request_sock_ipv6_ops; -+ mptcp_request_sock_ipv6_ops.init_req = mptcp_v6_init_req; -+#ifdef CONFIG_SYN_COOKIES -+ mptcp_request_sock_ipv6_ops.cookie_init_seq = mptcp_v6_cookie_init_seq; -+#endif -+ -+ mptcp_join_request_sock_ipv6_ops = tcp_request_sock_ipv6_ops; -+ mptcp_join_request_sock_ipv6_ops.init_req = mptcp_v6_join_init_req; -+ -+ ops->slab_name = kasprintf(GFP_KERNEL, "request_sock_%s", "MPTCP6"); -+ if (ops->slab_name == NULL) { -+ ret = -ENOMEM; -+ goto out; -+ } -+ -+ ops->slab = kmem_cache_create(ops->slab_name, ops->obj_size, 0, -+ SLAB_TYPESAFE_BY_RCU|SLAB_HWCACHE_ALIGN, -+ NULL); -+ -+ if (ops->slab == NULL) { -+ ret = -ENOMEM; -+ goto err_reqsk_create; -+ } -+ -+out: -+ return ret; -+ -+err_reqsk_create: -+ kfree(ops->slab_name); -+ ops->slab_name = NULL; -+ goto out; -+} -+ -+void mptcp_pm_v6_undo(void) -+{ -+ kmem_cache_destroy(mptcp6_request_sock_ops.slab); -+ kfree(mptcp6_request_sock_ops.slab_name); -+} -diff -aurN linux-5.4.64/net/mptcp/mptcp_ndiffports.c linux-5.4.64.mptcp/net/mptcp/mptcp_ndiffports.c ---- linux-5.4.64/net/mptcp/mptcp_ndiffports.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-5.4.64.mptcp/net/mptcp/mptcp_ndiffports.c 2020-09-10 19:25:10.507220869 +0200 -@@ -0,0 +1,174 @@ -+#include -+ -+#include -+#include -+ -+#if IS_ENABLED(CONFIG_IPV6) -+#include -+#endif -+ -+struct ndiffports_priv { -+ /* Worker struct for subflow establishment */ -+ struct work_struct subflow_work; -+ -+ struct mptcp_cb *mpcb; -+}; -+ -+static int num_subflows __read_mostly = 2; -+module_param(num_subflows, int, 0644); -+MODULE_PARM_DESC(num_subflows, "choose the number of subflows per MPTCP connection"); -+ -+/** -+ * Create all new subflows, by doing calls to mptcp_initX_subsockets -+ * -+ * This function uses a goto next_subflow, to allow releasing the lock between -+ * new subflows and giving other processes a chance to do some work on the -+ * socket and potentially finishing the communication. -+ **/ -+static void create_subflow_worker(struct work_struct *work) -+{ -+ const struct ndiffports_priv *pm_priv = container_of(work, -+ struct ndiffports_priv, -+ subflow_work); -+ struct mptcp_cb *mpcb = pm_priv->mpcb; -+ struct sock *meta_sk = mpcb->meta_sk; -+ int iter = 0; -+ -+next_subflow: -+ if (iter) { -+ release_sock(meta_sk); -+ mutex_unlock(&mpcb->mpcb_mutex); -+ -+ cond_resched(); -+ } -+ mutex_lock(&mpcb->mpcb_mutex); -+ lock_sock_nested(meta_sk, SINGLE_DEPTH_NESTING); -+ -+ if (!mptcp(tcp_sk(meta_sk))) -+ goto exit; -+ -+ iter++; -+ -+ if (sock_flag(meta_sk, SOCK_DEAD)) -+ goto exit; -+ -+ if (mpcb->master_sk && -+ !tcp_sk(mpcb->master_sk)->mptcp->fully_established) -+ goto exit; -+ -+ if (num_subflows > iter && num_subflows > mptcp_subflow_count(mpcb)) { -+ if (meta_sk->sk_family == AF_INET || -+ mptcp_v6_is_v4_mapped(meta_sk)) { -+ struct mptcp_loc4 loc; -+ struct mptcp_rem4 rem; -+ -+ loc.addr.s_addr = inet_sk(meta_sk)->inet_saddr; -+ loc.loc4_id = 0; -+ loc.low_prio = 0; -+ if (mpcb->master_sk) -+ loc.if_idx = mpcb->master_sk->sk_bound_dev_if; -+ else -+ loc.if_idx = 0; -+ -+ rem.addr.s_addr = inet_sk(meta_sk)->inet_daddr; -+ rem.port = inet_sk(meta_sk)->inet_dport; -+ rem.rem4_id = 0; /* Default 0 */ -+ -+ mptcp_init4_subsockets(meta_sk, &loc, &rem); -+ } else { -+#if IS_ENABLED(CONFIG_IPV6) -+ struct mptcp_loc6 loc; -+ struct mptcp_rem6 rem; -+ -+ loc.addr = inet6_sk(meta_sk)->saddr; -+ loc.loc6_id = 0; -+ loc.low_prio = 0; -+ if (mpcb->master_sk) -+ loc.if_idx = mpcb->master_sk->sk_bound_dev_if; -+ else -+ loc.if_idx = 0; -+ -+ rem.addr = meta_sk->sk_v6_daddr; -+ rem.port = inet_sk(meta_sk)->inet_dport; -+ rem.rem6_id = 0; /* Default 0 */ -+ -+ mptcp_init6_subsockets(meta_sk, &loc, &rem); -+#endif -+ } -+ goto next_subflow; -+ } -+ -+exit: -+ release_sock(meta_sk); -+ mutex_unlock(&mpcb->mpcb_mutex); -+ mptcp_mpcb_put(mpcb); -+ sock_put(meta_sk); -+} -+ -+static void ndiffports_new_session(const struct sock *meta_sk) -+{ -+ struct mptcp_cb *mpcb = tcp_sk(meta_sk)->mpcb; -+ struct ndiffports_priv *fmp = (struct ndiffports_priv *)&mpcb->mptcp_pm[0]; -+ -+ /* Initialize workqueue-struct */ -+ INIT_WORK(&fmp->subflow_work, create_subflow_worker); -+ fmp->mpcb = mpcb; -+} -+ -+static void ndiffports_create_subflows(struct sock *meta_sk) -+{ -+ struct mptcp_cb *mpcb = tcp_sk(meta_sk)->mpcb; -+ struct ndiffports_priv *pm_priv = (struct ndiffports_priv *)&mpcb->mptcp_pm[0]; -+ -+ if (mptcp_in_infinite_mapping_weak(mpcb) || -+ mpcb->server_side || sock_flag(meta_sk, SOCK_DEAD)) -+ return; -+ -+ if (!work_pending(&pm_priv->subflow_work)) { -+ sock_hold(meta_sk); -+ refcount_inc(&mpcb->mpcb_refcnt); -+ queue_work(mptcp_wq, &pm_priv->subflow_work); -+ } -+} -+ -+static int ndiffports_get_local_id(const struct sock *meta_sk, -+ sa_family_t family, union inet_addr *addr, -+ bool *low_prio) -+{ -+ return 0; -+} -+ -+static struct mptcp_pm_ops ndiffports __read_mostly = { -+ .new_session = ndiffports_new_session, -+ .fully_established = ndiffports_create_subflows, -+ .get_local_id = ndiffports_get_local_id, -+ .name = "ndiffports", -+ .owner = THIS_MODULE, -+}; -+ -+/* General initialization of MPTCP_PM */ -+static int __init ndiffports_register(void) -+{ -+ BUILD_BUG_ON(sizeof(struct ndiffports_priv) > MPTCP_PM_SIZE); -+ -+ if (mptcp_register_path_manager(&ndiffports)) -+ goto exit; -+ -+ return 0; -+ -+exit: -+ return -1; -+} -+ -+static void ndiffports_unregister(void) -+{ -+ mptcp_unregister_path_manager(&ndiffports); -+} -+ -+module_init(ndiffports_register); -+module_exit(ndiffports_unregister); -+ -+MODULE_AUTHOR("Christoph Paasch"); -+MODULE_LICENSE("GPL"); -+MODULE_DESCRIPTION("NDIFF-PORTS MPTCP"); -+MODULE_VERSION("0.88"); -diff -aurN linux-5.4.64/net/mptcp/mptcp_netlink.c linux-5.4.64.mptcp/net/mptcp/mptcp_netlink.c ---- linux-5.4.64/net/mptcp/mptcp_netlink.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-5.4.64.mptcp/net/mptcp/mptcp_netlink.c 2020-09-10 19:25:10.507220869 +0200 -@@ -0,0 +1,1271 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* MPTCP implementation - Netlink Path Manager -+ * -+ * Analysis, Design and Implementation: -+ * - Gregory Detal -+ * - Sébastien Barré -+ * - Matthieu Baerts -+ * - Pau Espin Pedrol -+ * - Detlev Casanova -+ * - David Verbeiren -+ * - Frank Vanbever -+ * - Antoine Maes -+ * - Tim Froidcoeur -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version -+ * 2 of the License, or (at your option) any later version. -+ */ -+ -+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt -+#include -+#include -+#include -+#include -+#include -+#if IS_ENABLED(CONFIG_IPV6) -+#include -+#endif -+ -+#define MPTCP_MAX_ADDR 8 -+ -+struct mptcp_nl_priv { -+ /* Unfortunately we need to store this to generate MP_JOINs in case -+ * of the peer generating a subflow (see get_local_id). -+ */ -+ u8 loc4_bits; -+ u8 announced4; -+ struct mptcp_loc4 locaddr4[MPTCP_MAX_ADDR]; -+ -+#if IS_ENABLED(CONFIG_IPV6) -+ u8 loc6_bits; -+ u8 announced6; -+ struct mptcp_loc6 locaddr6[MPTCP_MAX_ADDR]; -+#endif -+ -+ u16 remove_addrs; -+ -+ bool is_closed; -+}; -+ -+static struct genl_family mptcp_genl_family; -+ -+#define MPTCP_GENL_EV_GRP_OFFSET 0 -+#define MPTCP_GENL_CMD_GRP_OFFSET 1 -+ -+static const struct genl_multicast_group mptcp_mcgrps[] = { -+ [MPTCP_GENL_EV_GRP_OFFSET] = { .name = MPTCP_GENL_EV_GRP_NAME, }, -+ [MPTCP_GENL_CMD_GRP_OFFSET] = { .name = MPTCP_GENL_CMD_GRP_NAME, }, -+}; -+ -+static const struct nla_policy mptcp_nl_genl_policy[MPTCP_ATTR_MAX + 1] = { -+ [MPTCP_ATTR_TOKEN] = { .type = NLA_U32, }, -+ [MPTCP_ATTR_FAMILY] = { .type = NLA_U16, }, -+ [MPTCP_ATTR_LOC_ID] = { .type = NLA_U8, }, -+ [MPTCP_ATTR_REM_ID] = { .type = NLA_U8, }, -+ [MPTCP_ATTR_SADDR4] = { .type = NLA_U32, }, -+ [MPTCP_ATTR_SADDR6] = { .type = NLA_BINARY, -+ .len = sizeof(struct in6_addr), }, -+ [MPTCP_ATTR_DADDR4] = { .type = NLA_U32, }, -+ [MPTCP_ATTR_DADDR6] = { .type = NLA_BINARY, -+ .len = sizeof(struct in6_addr), }, -+ [MPTCP_ATTR_SPORT] = { .type = NLA_U16, }, -+ [MPTCP_ATTR_DPORT] = { .type = NLA_U16, }, -+ [MPTCP_ATTR_BACKUP] = { .type = NLA_U8, }, -+ [MPTCP_ATTR_TIMEOUT] = { .type = NLA_U32, }, -+ [MPTCP_ATTR_IF_IDX] = { .type = NLA_S32, }, -+}; -+ -+/* Defines the userspace PM filter on events. Set events are ignored. */ -+static u16 mptcp_nl_event_filter; -+ -+static inline struct mptcp_nl_priv * -+mptcp_nl_priv(const struct sock *meta_sk) -+{ -+ return (struct mptcp_nl_priv *)&tcp_sk(meta_sk)->mpcb->mptcp_pm[0]; -+} -+ -+static inline bool -+mptcp_nl_must_notify(u16 event, const struct sock *meta_sk) -+{ -+ struct mptcp_nl_priv *priv = mptcp_nl_priv(meta_sk); -+ -+ /* close_session() can be called before other events because it is -+ * also called when doing a fallback to TCP. We don't want to send -+ * events to the user-space after having sent the CLOSED event. -+ */ -+ if (priv->is_closed) -+ return false; -+ -+ if (event == MPTCPF_EVENT_CLOSED) -+ priv->is_closed = true; -+ -+ if (mptcp_nl_event_filter & event) -+ return false; -+ -+ if (!genl_has_listeners(&mptcp_genl_family, sock_net(meta_sk), 0)) -+ return false; -+ -+ return true; -+} -+ -+/* Find the first free index in the bitfield starting from 0 */ -+static int -+mptcp_nl_find_free_index(u8 bitfield) -+{ -+ int i; -+ -+ /* There are anyways no free bits... */ -+ if (bitfield == 0xff) -+ return -1; -+ -+ i = ffs(~bitfield) - 1; -+ if (i < 0) -+ return -1; -+ -+ return i; -+} -+ -+static inline int -+mptcp_nl_put_subsk(struct sk_buff *msg, struct sock *sk) -+{ -+ struct inet_sock *isk = inet_sk(sk); -+ struct sock *meta_sk = mptcp_meta_sk(sk); -+ u8 backup; -+ u8 sk_err; -+ -+ if (nla_put_u16(msg, MPTCP_ATTR_FAMILY, sk->sk_family)) -+ goto nla_put_failure; -+ -+ if (nla_put_u8(msg, MPTCP_ATTR_LOC_ID, tcp_sk(sk)->mptcp->loc_id)) -+ goto nla_put_failure; -+ -+ if (nla_put_u8(msg, MPTCP_ATTR_REM_ID, tcp_sk(sk)->mptcp->rem_id)) -+ goto nla_put_failure; -+ -+ switch (sk->sk_family) { -+ case AF_INET: -+ if (nla_put_u32(msg, MPTCP_ATTR_SADDR4, isk->inet_saddr)) -+ goto nla_put_failure; -+ -+ if (nla_put_u32(msg, MPTCP_ATTR_DADDR4, isk->inet_daddr)) -+ goto nla_put_failure; -+ break; -+#if IS_ENABLED(CONFIG_IPV6) -+ case AF_INET6: { -+ struct ipv6_pinfo *np = inet6_sk(sk); -+ -+ if (nla_put(msg, MPTCP_ATTR_SADDR6, sizeof(np->saddr), -+ &np->saddr)) -+ goto nla_put_failure; -+ -+ if (nla_put(msg, MPTCP_ATTR_DADDR6, sizeof(sk->sk_v6_daddr), -+ &sk->sk_v6_daddr)) -+ goto nla_put_failure; -+ break; -+ } -+#endif -+ default: -+ goto nla_put_failure; -+ } -+ -+ if (nla_put_u16(msg, MPTCP_ATTR_SPORT, ntohs(isk->inet_sport))) -+ goto nla_put_failure; -+ -+ if (nla_put_u16(msg, MPTCP_ATTR_DPORT, ntohs(isk->inet_dport))) -+ goto nla_put_failure; -+ -+ backup = !!(tcp_sk(sk)->mptcp->rcv_low_prio || -+ tcp_sk(sk)->mptcp->low_prio); -+ -+ if (nla_put_u8(msg, MPTCP_ATTR_BACKUP, backup)) -+ goto nla_put_failure; -+ -+ if (nla_put_s32(msg, MPTCP_ATTR_IF_IDX, sk->sk_bound_dev_if)) -+ goto nla_put_failure; -+ -+ sk_err = sk->sk_err ? : tcp_sk(sk)->mptcp->sk_err; -+ if (unlikely(sk_err != 0) && meta_sk->sk_state == TCP_ESTABLISHED && -+ nla_put_u8(msg, MPTCP_ATTR_ERROR, sk_err)) -+ goto nla_put_failure; -+ -+ return 0; -+ -+nla_put_failure: -+ return -1; -+} -+ -+static inline struct sk_buff * -+mptcp_nl_mcast_prepare(struct mptcp_cb *mpcb, struct sock *sk, int cmd, -+ void **hdr) -+{ -+ struct sk_buff *msg; -+ -+ /* possible optimisation: use the needed size */ -+ msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC); -+ if (!msg) -+ return NULL; -+ -+ *hdr = genlmsg_put(msg, 0, 0, &mptcp_genl_family, 0, cmd); -+ if (!*hdr) -+ goto free_msg; -+ -+ if (nla_put_u32(msg, MPTCP_ATTR_TOKEN, mpcb->mptcp_loc_token)) -+ goto nla_put_failure; -+ -+ if (sk && mptcp_nl_put_subsk(msg, sk)) -+ goto nla_put_failure; -+ -+ return msg; -+ -+nla_put_failure: -+ genlmsg_cancel(msg, *hdr); -+free_msg: -+ nlmsg_free(msg); -+ return NULL; -+} -+ -+static inline int -+mptcp_nl_mcast_send(struct mptcp_cb *mpcb, struct sk_buff *msg, void *hdr) -+{ -+ int ret; -+ struct sock *meta_sk = mpcb->meta_sk; -+ -+ genlmsg_end(msg, hdr); -+ -+ ret = genlmsg_multicast_netns(&mptcp_genl_family, sock_net(meta_sk), -+ msg, 0, MPTCP_GENL_EV_GRP_OFFSET, -+ GFP_ATOMIC); -+ if (ret && ret != -ESRCH) -+ pr_err("%s: genlmsg_multicast failed with %d\n", __func__, ret); -+ return ret; -+} -+ -+static inline void -+mptcp_nl_mcast(struct mptcp_cb *mpcb, struct sock *sk, int cmd) -+{ -+ void *hdr; -+ struct sk_buff *msg; -+ -+ msg = mptcp_nl_mcast_prepare(mpcb, sk, cmd, &hdr); -+ if (msg) -+ mptcp_nl_mcast_send(mpcb, msg, hdr); -+ else -+ pr_warn("%s: unable to prepare multicast message\n", __func__); -+} -+ -+static inline void -+mptcp_nl_mcast_fail(struct sk_buff *msg, void *hdr) -+{ -+ genlmsg_cancel(msg, hdr); -+ nlmsg_free(msg); -+} -+ -+static void -+mptcp_nl_new(const struct sock *meta_sk, bool established) -+{ -+ struct mptcp_cb *mpcb = tcp_sk(meta_sk)->mpcb; -+ -+ mptcp_nl_mcast(mpcb, mpcb->master_sk, -+ established ? MPTCP_EVENT_ESTABLISHED -+ : MPTCP_EVENT_CREATED); -+} -+ -+static void -+mptcp_nl_pm_new_session(const struct sock *meta_sk) -+{ -+ if (!mptcp_nl_must_notify(MPTCPF_EVENT_CREATED, meta_sk)) -+ return; -+ -+ mptcp_nl_new(meta_sk, false); -+} -+ -+static inline int -+mptcp_nl_loc_id_to_index_lookup(struct sock *meta_sk, sa_family_t family, -+ u8 addr_id) -+{ -+ struct mptcp_nl_priv *priv = mptcp_nl_priv(meta_sk); -+ int i; -+ -+ switch (family) { -+ case AF_INET: -+ mptcp_for_each_bit_set(priv->loc4_bits, i) { -+ if (priv->locaddr4[i].loc4_id == addr_id) -+ return i; -+ } -+ break; -+#if IS_ENABLED(CONFIG_IPV6) -+ case AF_INET6: -+ mptcp_for_each_bit_set(priv->loc6_bits, i) { -+ if (priv->locaddr6[i].loc6_id == addr_id) -+ return i; -+ } -+ break; -+#endif -+ } -+ return -1; -+} -+ -+static inline void -+mptcp_nl_sk_setup_locaddr(struct sock *meta_sk, struct sock *sk) -+{ -+ struct mptcp_nl_priv *priv = mptcp_nl_priv(meta_sk); -+ bool backup = !!(tcp_sk(sk)->mptcp->rcv_low_prio || -+ tcp_sk(sk)->mptcp->low_prio); -+ sa_family_t family = mptcp_v6_is_v4_mapped(sk) ? AF_INET -+ : sk->sk_family; -+ u8 addr_id = tcp_sk(sk)->mptcp->loc_id; -+ int idx = mptcp_nl_loc_id_to_index_lookup(meta_sk, family, -+ addr_id); -+ -+ /* Same as in mptcp_fullmesh.c: exception for transparent sockets */ -+ int if_idx = inet_sk(sk)->transparent ? inet_sk(sk)->rx_dst_ifindex : -+ sk->sk_bound_dev_if; -+ -+ switch (family) { -+ case AF_INET: { -+ struct inet_sock *isk = inet_sk(sk); -+ -+ if (idx == -1) -+ idx = mptcp_nl_find_free_index(priv->loc4_bits); -+ if (idx == -1) { -+ pr_warn("No free index for sk loc_id v4\n"); -+ return; -+ } -+ priv->locaddr4[idx].addr.s_addr = isk->inet_saddr; -+ priv->locaddr4[idx].loc4_id = addr_id; -+ priv->locaddr4[idx].low_prio = backup; -+ priv->locaddr4[idx].if_idx = if_idx; -+ priv->loc4_bits |= 1 << idx; -+ priv->announced4 |= 1 << idx; -+ break; -+ } -+#if IS_ENABLED(CONFIG_IPV6) -+ case AF_INET6: { -+ struct ipv6_pinfo *np = inet6_sk(sk); -+ -+ if (idx == -1) -+ idx = mptcp_nl_find_free_index(priv->loc6_bits); -+ if (idx == -1) { -+ pr_warn("No free index for sk loc_id v6\n"); -+ return; -+ } -+ priv->locaddr6[idx].addr = np->saddr; -+ priv->locaddr6[idx].loc6_id = addr_id; -+ priv->locaddr6[idx].low_prio = backup; -+ priv->locaddr6[idx].if_idx = if_idx; -+ priv->loc6_bits |= 1 << idx; -+ priv->announced6 |= 1 << idx; -+ break; -+ } -+#endif -+ } -+} -+ -+static void -+mptcp_nl_pm_fully_established(struct sock *meta_sk) -+{ -+ mptcp_nl_sk_setup_locaddr(meta_sk, tcp_sk(meta_sk)->mpcb->master_sk); -+ -+ if (!mptcp_nl_must_notify(MPTCPF_EVENT_ESTABLISHED, meta_sk)) -+ return; -+ -+ mptcp_nl_new(meta_sk, true); -+} -+ -+static void -+mptcp_nl_pm_close_session(struct sock *meta_sk) -+{ -+ if (!mptcp_nl_must_notify(MPTCPF_EVENT_CLOSED, meta_sk)) -+ return; -+ -+ mptcp_nl_mcast(tcp_sk(meta_sk)->mpcb, NULL, MPTCP_EVENT_CLOSED); -+} -+ -+static void -+mptcp_nl_pm_established_subflow(struct sock *sk) -+{ -+ struct sock *meta_sk = mptcp_meta_sk(sk); -+ -+ mptcp_nl_sk_setup_locaddr(meta_sk, sk); -+ -+ if (!mptcp_nl_must_notify(MPTCPF_EVENT_SUB_ESTABLISHED, meta_sk)) -+ return; -+ -+ mptcp_nl_mcast(tcp_sk(meta_sk)->mpcb, sk, MPTCP_EVENT_SUB_ESTABLISHED); -+} -+ -+static void -+mptcp_nl_pm_delete_subflow(struct sock *sk) -+{ -+ struct sock *meta_sk = mptcp_meta_sk(sk); -+ -+ if (!mptcp_nl_must_notify(MPTCPF_EVENT_SUB_CLOSED, meta_sk)) -+ return; -+ -+ mptcp_nl_mcast(tcp_sk(meta_sk)->mpcb, sk, MPTCP_EVENT_SUB_CLOSED); -+} -+ -+static void -+mptcp_nl_pm_add_raddr(struct mptcp_cb *mpcb, const union inet_addr *addr, -+ sa_family_t family, __be16 port, u8 id) -+{ -+ struct sk_buff *msg; -+ void *hdr; -+ -+ if (!mptcp_nl_must_notify(MPTCPF_EVENT_ANNOUNCED, mpcb->meta_sk)) -+ return; -+ -+ msg = mptcp_nl_mcast_prepare(mpcb, NULL, MPTCP_EVENT_ANNOUNCED, &hdr); -+ if (!msg) -+ return; -+ -+ if (nla_put_u8(msg, MPTCP_ATTR_REM_ID, id)) -+ goto nla_put_failure; -+ -+ if (nla_put_u16(msg, MPTCP_ATTR_FAMILY, family)) -+ goto nla_put_failure; -+ -+ switch (family) { -+ case AF_INET: -+ if (nla_put_u32(msg, MPTCP_ATTR_DADDR4, addr->ip)) -+ goto nla_put_failure; -+ break; -+#if IS_ENABLED(CONFIG_IPV6) -+ case AF_INET6: -+ if (nla_put(msg, MPTCP_ATTR_DADDR6, sizeof(addr->ip6), -+ &addr->ip6)) -+ goto nla_put_failure; -+ break; -+#endif -+ default: -+ goto nla_put_failure; -+ } -+ -+ if (nla_put_u16(msg, MPTCP_ATTR_DPORT, ntohs(port))) -+ goto nla_put_failure; -+ -+ mptcp_nl_mcast_send(mpcb, msg, hdr); -+ -+ return; -+ -+nla_put_failure: -+ mptcp_nl_mcast_fail(msg, hdr); -+} -+ -+static void -+mptcp_nl_pm_rem_raddr(struct mptcp_cb *mpcb, u8 id) -+{ -+ struct sk_buff *msg; -+ void *hdr; -+ -+ if (!mptcp_nl_must_notify(MPTCPF_EVENT_REMOVED, mpcb->meta_sk)) -+ return; -+ -+ msg = mptcp_nl_mcast_prepare(mpcb, NULL, MPTCP_EVENT_REMOVED, &hdr); -+ -+ if (!msg) -+ return; -+ -+ if (nla_put_u8(msg, MPTCP_ATTR_REM_ID, id)) -+ goto nla_put_failure; -+ -+ mptcp_nl_mcast_send(mpcb, msg, hdr); -+ -+ return; -+ -+nla_put_failure: -+ mptcp_nl_mcast_fail(msg, hdr); -+} -+ -+static int -+mptcp_nl_pm_get_local_id(const struct sock *meta_sk, sa_family_t family, -+ union inet_addr *addr, bool *low_prio) -+{ -+ struct mptcp_nl_priv *priv = mptcp_nl_priv(meta_sk); -+ int i, id = 0; -+ -+ switch (family) { -+ case AF_INET: -+ mptcp_for_each_bit_set(priv->loc4_bits, i) { -+ if (addr->in.s_addr == priv->locaddr4[i].addr.s_addr) { -+ id = priv->locaddr4[i].loc4_id; -+ *low_prio = priv->locaddr4[i].low_prio; -+ goto out; -+ } -+ } -+ break; -+#if IS_ENABLED(CONFIG_IPV6) -+ case AF_INET6: -+ mptcp_for_each_bit_set(priv->loc6_bits, i) { -+ if (ipv6_addr_equal(&addr->in6, -+ &priv->locaddr6[i].addr)) { -+ id = priv->locaddr6[i].loc6_id; -+ *low_prio = priv->locaddr6[i].low_prio; -+ goto out; -+ } -+ } -+ break; -+#endif -+ } -+ return -1; -+ -+out: -+ return id; -+} -+ -+static void -+mptcp_nl_pm_addr_signal(struct sock *sk, unsigned *size, -+ struct tcp_out_options *opts, struct sk_buff *skb) -+{ -+ struct mptcp_nl_priv *priv = mptcp_nl_priv(sk); -+ struct mptcp_cb *mpcb = tcp_sk(sk)->mpcb; -+ u8 unannounced; -+ int remove_addr_len; -+ -+ unannounced = (~priv->announced4) & priv->loc4_bits; -+ if (unannounced && -+ MAX_TCP_OPTION_SPACE - *size >= MPTCP_SUB_LEN_ADD_ADDR4_ALIGN) { -+ int i = mptcp_nl_find_free_index(~unannounced); -+ -+ opts->options |= OPTION_MPTCP; -+ opts->mptcp_options |= OPTION_ADD_ADDR; -+ opts->add_addr4.addr_id = priv->locaddr4[i].loc4_id; -+ opts->add_addr4.addr = priv->locaddr4[i].addr; -+ opts->add_addr_v4 = 1; -+ -+ if (skb) -+ priv->announced4 |= (1 << i); -+ *size += MPTCP_SUB_LEN_ADD_ADDR4_ALIGN; -+ } -+ -+#if IS_ENABLED(CONFIG_IPV6) -+ unannounced = (~priv->announced6) & priv->loc6_bits; -+ if (unannounced && -+ MAX_TCP_OPTION_SPACE - *size >= MPTCP_SUB_LEN_ADD_ADDR6_ALIGN) { -+ int i = mptcp_nl_find_free_index(~unannounced); -+ -+ opts->options |= OPTION_MPTCP; -+ opts->mptcp_options |= OPTION_ADD_ADDR; -+ opts->add_addr6.addr_id = priv->locaddr6[i].loc6_id; -+ opts->add_addr6.addr = priv->locaddr6[i].addr; -+ opts->add_addr_v6 = 1; -+ -+ if (skb) -+ priv->announced6 |= (1 << i); -+ *size += MPTCP_SUB_LEN_ADD_ADDR6_ALIGN; -+ } -+#endif -+ -+ if (likely(!priv->remove_addrs)) -+ goto exit; -+ -+ remove_addr_len = mptcp_sub_len_remove_addr_align(priv->remove_addrs); -+ if (MAX_TCP_OPTION_SPACE - *size < remove_addr_len) -+ goto exit; -+ -+ opts->options |= OPTION_MPTCP; -+ opts->mptcp_options |= OPTION_REMOVE_ADDR; -+ opts->remove_addrs = priv->remove_addrs; -+ -+ if (skb) -+ priv->remove_addrs = 0; -+ *size += remove_addr_len; -+ -+exit: -+ mpcb->addr_signal = !!((~priv->announced4) & priv->loc4_bits || -+#if IS_ENABLED(CONFIG_IPV6) -+ (~priv->announced6) & priv->loc6_bits || -+#endif -+ priv->remove_addrs); -+} -+ -+static void -+mptcp_nl_pm_prio_changed(struct sock *sk, int low_prio) -+{ -+ struct sock *meta_sk = mptcp_meta_sk(sk); -+ -+ if (!mptcp_nl_must_notify(MPTCPF_EVENT_SUB_PRIORITY, meta_sk)) -+ return; -+ -+ mptcp_nl_mcast(tcp_sk(meta_sk)->mpcb, sk, MPTCP_EVENT_SUB_PRIORITY); -+} -+ -+static int -+mptcp_nl_genl_announce(struct sk_buff *skb, struct genl_info *info) -+{ -+ struct sock *meta_sk, *subsk; -+ struct mptcp_cb *mpcb; -+ struct mptcp_nl_priv *priv; -+ u32 token; -+ u8 addr_id, backup = 0; -+ u16 family; -+ int i, ret = 0; -+ union inet_addr saddr; -+ int if_idx = 0; -+ bool useless; /* unused out parameter "low_prio" */ -+ -+ if (!info->attrs[MPTCP_ATTR_TOKEN] || !info->attrs[MPTCP_ATTR_FAMILY] || -+ !info->attrs[MPTCP_ATTR_LOC_ID]) -+ return -EINVAL; -+ -+ token = nla_get_u32(info->attrs[MPTCP_ATTR_TOKEN]); -+ meta_sk = mptcp_hash_find(genl_info_net(info), token); -+ if (!meta_sk) -+ return -EINVAL; -+ -+ mpcb = tcp_sk(meta_sk)->mpcb; -+ priv = mptcp_nl_priv(meta_sk); -+ family = nla_get_u16(info->attrs[MPTCP_ATTR_FAMILY]); -+ addr_id = nla_get_u8(info->attrs[MPTCP_ATTR_LOC_ID]); -+ -+ if (info->attrs[MPTCP_ATTR_BACKUP]) -+ backup = nla_get_u8(info->attrs[MPTCP_ATTR_BACKUP]); -+ -+ if (info->attrs[MPTCP_ATTR_IF_IDX]) -+ if_idx = nla_get_s32(info->attrs[MPTCP_ATTR_IF_IDX]); -+ -+ mutex_lock(&mpcb->mpcb_mutex); -+ lock_sock_nested(meta_sk, SINGLE_DEPTH_NESTING); -+ -+ switch (family) { -+ case AF_INET: -+ if (!info->attrs[MPTCP_ATTR_SADDR4]) { -+ ret = -EINVAL; -+ goto exit; -+ } -+ -+ saddr.in.s_addr = nla_get_u32(info->attrs[MPTCP_ATTR_SADDR4]); -+ i = mptcp_nl_pm_get_local_id(meta_sk, family, -+ &saddr, &useless); -+ if (i < 0) { -+ i = mptcp_nl_find_free_index(priv->loc4_bits); -+ if (i < 0) { -+ ret = -ENOBUFS; -+ goto exit; -+ } -+ } else if (i != addr_id) { -+ ret = -EINVAL; -+ goto exit; -+ } -+ -+ priv->locaddr4[i].addr.s_addr = saddr.in.s_addr; -+ priv->locaddr4[i].loc4_id = addr_id; -+ priv->locaddr4[i].low_prio = !!backup; -+ priv->locaddr4[i].if_idx = if_idx; -+ priv->loc4_bits |= 1 << i; -+ priv->announced4 &= ~(1 << i); -+ break; -+#if IS_ENABLED(CONFIG_IPV6) -+ case AF_INET6: -+ if (!info->attrs[MPTCP_ATTR_SADDR6]) { -+ ret = -EINVAL; -+ goto exit; -+ } -+ -+ saddr.in6 = *(struct in6_addr *) -+ nla_data(info->attrs[MPTCP_ATTR_SADDR6]); -+ i = mptcp_nl_pm_get_local_id(meta_sk, family, &saddr, &useless); -+ if (i < 0) { -+ i = mptcp_nl_find_free_index(priv->loc6_bits); -+ if (i < 0) { -+ ret = -ENOBUFS; -+ goto exit; -+ } -+ } else if (i != addr_id) { -+ ret = -EINVAL; -+ goto exit; -+ } -+ -+ priv->locaddr6[i].addr = saddr.in6; -+ priv->locaddr6[i].loc6_id = addr_id; -+ priv->locaddr6[i].low_prio = !!backup; -+ priv->locaddr6[i].if_idx = if_idx; -+ priv->loc6_bits |= 1 << i; -+ priv->announced6 &= ~(1 << i); -+ break; -+#endif -+ default: -+ ret = -EINVAL; -+ goto exit; -+ } -+ -+ mpcb->addr_signal = 1; -+ -+ rcu_read_lock_bh(); -+ subsk = mptcp_select_ack_sock(meta_sk); -+ if (subsk) -+ tcp_send_ack(subsk); -+ rcu_read_unlock_bh(); -+ -+exit: -+ release_sock(meta_sk); -+ mutex_unlock(&mpcb->mpcb_mutex); -+ sock_put(meta_sk); -+ return ret; -+} -+ -+static int -+mptcp_nl_genl_remove(struct sk_buff *skb, struct genl_info *info) -+{ -+ struct sock *meta_sk, *subsk; -+ struct mptcp_cb *mpcb; -+ struct mptcp_nl_priv *priv; -+ u32 token; -+ u8 addr_id; -+ int i; -+ int retcode; -+ bool found = false; -+ -+ if (!info->attrs[MPTCP_ATTR_TOKEN] || !info->attrs[MPTCP_ATTR_LOC_ID]) -+ return -EINVAL; -+ -+ token = nla_get_u32(info->attrs[MPTCP_ATTR_TOKEN]); -+ meta_sk = mptcp_hash_find(genl_info_net(info), token); -+ if (!meta_sk) -+ return -EINVAL; -+ -+ mpcb = tcp_sk(meta_sk)->mpcb; -+ priv = mptcp_nl_priv(meta_sk); -+ addr_id = nla_get_u8(info->attrs[MPTCP_ATTR_LOC_ID]); -+ -+ mutex_lock(&mpcb->mpcb_mutex); -+ lock_sock_nested(meta_sk, SINGLE_DEPTH_NESTING); -+ -+ mptcp_for_each_bit_set(priv->loc4_bits, i) { -+ if (priv->locaddr4[i].loc4_id == addr_id) { -+ priv->loc4_bits &= ~(1 << i); -+ found = true; -+ break; -+ } -+ } -+ -+#if IS_ENABLED(CONFIG_IPV6) -+ if (!found) { -+ mptcp_for_each_bit_set(priv->loc6_bits, i) { -+ if (priv->locaddr6[i].loc6_id == addr_id) { -+ priv->loc6_bits &= ~(1 << i); -+ found = true; -+ break; -+ } -+ } -+ } -+#endif -+ -+ if (found) { -+ priv->remove_addrs |= 1 << addr_id; -+ mpcb->addr_signal = 1; -+ -+ rcu_read_lock_bh(); -+ subsk = mptcp_select_ack_sock(meta_sk); -+ if (subsk) -+ tcp_send_ack(subsk); -+ rcu_read_unlock_bh(); -+ retcode = 0; -+ } else { -+ retcode = -EINVAL; -+ } -+ -+ release_sock(meta_sk); -+ mutex_unlock(&mpcb->mpcb_mutex); -+ sock_put(meta_sk); -+ return retcode; -+} -+ -+static int -+mptcp_nl_genl_create(struct sk_buff *skb, struct genl_info *info) -+{ -+ struct sock *meta_sk, *subsk = NULL; -+ struct mptcp_cb *mpcb; -+ struct mptcp_nl_priv *priv; -+ u32 token; -+ u16 family, sport; -+ u8 loc_id, rem_id, backup = 0; -+ int i, ret = 0; -+ int if_idx; -+ -+ if (!info->attrs[MPTCP_ATTR_TOKEN] || !info->attrs[MPTCP_ATTR_FAMILY] || -+ !info->attrs[MPTCP_ATTR_LOC_ID] || !info->attrs[MPTCP_ATTR_REM_ID]) -+ return -EINVAL; -+ -+ token = nla_get_u32(info->attrs[MPTCP_ATTR_TOKEN]); -+ meta_sk = mptcp_hash_find(genl_info_net(info), token); -+ if (!meta_sk) -+ /* We use a more specific value than EINVAL here so that -+ * userspace can handle this specific case easily. This is -+ * useful to check the case in which userspace tries to create a -+ * subflow for a connection which was already destroyed recently -+ * in kernelspace, but userspace didn't have time to realize -+ * about it because there is a gap of time between kernel -+ * destroying the connection and userspace receiving the event -+ * through Netlink. It can easily happen for short life-time -+ * conns. -+ */ -+ return -EBADR; -+ -+ mpcb = tcp_sk(meta_sk)->mpcb; -+ -+ mutex_lock(&mpcb->mpcb_mutex); -+ lock_sock_nested(meta_sk, SINGLE_DEPTH_NESTING); -+ -+ if (sock_flag(meta_sk, SOCK_DEAD)) { -+ /* Same as for the EBADR case. In this case, though, we know for -+ * sure the conn owner of the subflow existed at some point (no -+ * invalid token possibility) -+ */ -+ ret = -EOWNERDEAD; -+ goto unlock; -+ } -+ -+ if (!mptcp_can_new_subflow(meta_sk)) { -+ /* Same as for the EBADR and EOWNERDEAD case but here, the MPTCP -+ * session has just been stopped, it is no longer possible to -+ * create new subflows. -+ */ -+ ret = -ENOTCONN; -+ goto unlock; -+ } -+ -+ if (mpcb->master_sk && -+ !tcp_sk(mpcb->master_sk)->mptcp->fully_established) { -+ /* First condition is not only in there for safely purposes, it -+ * can also be triggered in the same scenario as in EBADR and -+ * EOWNERDEAD -+ */ -+ ret = -EAGAIN; -+ goto unlock; -+ } -+ -+ priv = mptcp_nl_priv(meta_sk); -+ -+ family = nla_get_u16(info->attrs[MPTCP_ATTR_FAMILY]); -+ loc_id = nla_get_u8(info->attrs[MPTCP_ATTR_LOC_ID]); -+ rem_id = nla_get_u8(info->attrs[MPTCP_ATTR_REM_ID]); -+ -+ sport = info->attrs[MPTCP_ATTR_SPORT] -+ ? htons(nla_get_u16(info->attrs[MPTCP_ATTR_SPORT])) : 0; -+ backup = info->attrs[MPTCP_ATTR_BACKUP] -+ ? nla_get_u8(info->attrs[MPTCP_ATTR_BACKUP]) : 0; -+ if_idx = info->attrs[MPTCP_ATTR_IF_IDX] -+ ? nla_get_s32(info->attrs[MPTCP_ATTR_IF_IDX]) : 0; -+ -+ switch (family) { -+ case AF_INET: { -+ struct mptcp_rem4 rem = { -+ .rem4_id = rem_id, -+ }; -+ struct mptcp_loc4 loc = { -+ .loc4_id = loc_id, -+ }; -+ -+ if (!info->attrs[MPTCP_ATTR_DADDR4] || -+ !info->attrs[MPTCP_ATTR_DPORT]) { -+ goto create_failed; -+ } else { -+ rem.addr.s_addr = -+ nla_get_u32(info->attrs[MPTCP_ATTR_DADDR4]); -+ rem.port = -+ ntohs(nla_get_u16(info->attrs[MPTCP_ATTR_DPORT])); -+ } -+ -+ if (!info->attrs[MPTCP_ATTR_SADDR4]) { -+ bool found = false; -+ -+ mptcp_for_each_bit_set(priv->loc4_bits, i) { -+ if (priv->locaddr4[i].loc4_id == loc_id) { -+ loc.addr = priv->locaddr4[i].addr; -+ loc.low_prio = -+ priv->locaddr4[i].low_prio; -+ loc.if_idx = -+ priv->locaddr4[i].if_idx; -+ found = true; -+ break; -+ } -+ } -+ -+ if (!found) -+ goto create_failed; -+ } else { -+ loc.addr.s_addr = -+ nla_get_u32(info->attrs[MPTCP_ATTR_SADDR4]); -+ loc.low_prio = backup; -+ loc.if_idx = if_idx; -+ } -+ -+ ret = __mptcp_init4_subsockets(meta_sk, &loc, sport, &rem, -+ &subsk); -+ if (ret < 0) -+ goto unlock; -+ break; -+ } -+#if IS_ENABLED(CONFIG_IPV6) -+ case AF_INET6: { -+ struct mptcp_rem6 rem = { -+ .rem6_id = rem_id, -+ }; -+ struct mptcp_loc6 loc = { -+ .loc6_id = loc_id, -+ }; -+ -+ if (!info->attrs[MPTCP_ATTR_DADDR6] || -+ !info->attrs[MPTCP_ATTR_DPORT]) { -+ goto create_failed; -+ } else { -+ rem.addr = *(struct in6_addr *) -+ nla_data(info->attrs[MPTCP_ATTR_DADDR6]); -+ rem.port = -+ ntohs(nla_get_u16(info->attrs[MPTCP_ATTR_DPORT])); -+ } -+ -+ if (!info->attrs[MPTCP_ATTR_SADDR6]) { -+ bool found = false; -+ -+ mptcp_for_each_bit_set(priv->loc6_bits, i) { -+ if (priv->locaddr6[i].loc6_id == loc_id) { -+ loc.addr = priv->locaddr6[i].addr; -+ loc.low_prio = -+ priv->locaddr6[i].low_prio; -+ loc.if_idx = -+ priv->locaddr6[i].if_idx; -+ -+ found = true; -+ break; -+ } -+ } -+ -+ if (!found) -+ goto create_failed; -+ } else { -+ loc.addr = *(struct in6_addr *) -+ nla_data(info->attrs[MPTCP_ATTR_SADDR6]); -+ loc.low_prio = backup; -+ loc.if_idx = if_idx; -+ } -+ -+ ret = __mptcp_init6_subsockets(meta_sk, &loc, sport, &rem, -+ &subsk); -+ if (ret < 0) -+ goto unlock; -+ break; -+ } -+#endif -+ default: -+ goto create_failed; -+ } -+ -+unlock: -+ release_sock(meta_sk); -+ mutex_unlock(&mpcb->mpcb_mutex); -+ sock_put(meta_sk); -+ return ret; -+ -+create_failed: -+ ret = -EINVAL; -+ goto unlock; -+} -+ -+static struct sock * -+mptcp_nl_subsk_lookup(struct mptcp_cb *mpcb, struct nlattr **attrs) -+{ -+ struct sock *sk; -+ struct mptcp_tcp_sock *mptcp; -+ struct hlist_node *tmp; -+ u16 family; -+ __be16 sport, dport; -+ -+ if (!attrs[MPTCP_ATTR_FAMILY] || !attrs[MPTCP_ATTR_SPORT] || -+ !attrs[MPTCP_ATTR_DPORT]) -+ goto exit; -+ -+ family = nla_get_u16(attrs[MPTCP_ATTR_FAMILY]); -+ sport = htons(nla_get_u16(attrs[MPTCP_ATTR_SPORT])); -+ dport = htons(nla_get_u16(attrs[MPTCP_ATTR_DPORT])); -+ -+ switch (family) { -+ case AF_INET: { -+ __be32 saddr, daddr; -+ -+ if (!attrs[MPTCP_ATTR_SADDR4] || !attrs[MPTCP_ATTR_DADDR4]) -+ break; -+ -+ saddr = nla_get_u32(attrs[MPTCP_ATTR_SADDR4]); -+ daddr = nla_get_u32(attrs[MPTCP_ATTR_DADDR4]); -+ -+ mptcp_for_each_sub_safe(mpcb, mptcp, tmp) { -+ struct sock *subsk = mptcp_to_sock(mptcp); -+ struct inet_sock *isk = inet_sk(subsk); -+ -+ if (subsk->sk_family != AF_INET) -+ continue; -+ -+ if (isk->inet_saddr == saddr && -+ isk->inet_daddr == daddr && -+ isk->inet_sport == sport && -+ isk->inet_dport == dport) { -+ sk = subsk; -+ goto found; -+ } -+ } -+ break; -+ } -+#if IS_ENABLED(CONFIG_IPV6) -+ case AF_INET6: { -+ struct in6_addr saddr, daddr; -+ -+ if (!attrs[MPTCP_ATTR_SADDR6] || !attrs[MPTCP_ATTR_DADDR6]) -+ break; -+ -+ saddr = *(struct in6_addr *)nla_data(attrs[MPTCP_ATTR_SADDR6]); -+ daddr = *(struct in6_addr *)nla_data(attrs[MPTCP_ATTR_DADDR6]); -+ -+ mptcp_for_each_sub_safe(mpcb, mptcp, tmp) { -+ struct sock *subsk = mptcp_to_sock(mptcp); -+ struct inet_sock *isk = inet_sk(subsk); -+ struct ipv6_pinfo *np; -+ -+ if (subsk->sk_family != AF_INET6) -+ continue; -+ -+ np = inet6_sk(subsk); -+ if (ipv6_addr_equal(&saddr, &np->saddr) && -+ ipv6_addr_equal(&daddr, &subsk->sk_v6_daddr) && -+ isk->inet_sport == sport && -+ isk->inet_dport == dport) { -+ sk = subsk; -+ goto found; -+ } -+ } -+ break; -+ } -+#endif -+ } -+ -+exit: -+ sk = NULL; -+found: -+ return sk; -+} -+ -+static int -+mptcp_nl_genl_destroy(struct sk_buff *skb, struct genl_info *info) -+{ -+ struct sock *meta_sk, *subsk; -+ struct mptcp_cb *mpcb; -+ int ret = 0; -+ u32 token; -+ -+ if (!info->attrs[MPTCP_ATTR_TOKEN]) -+ return -EINVAL; -+ -+ token = nla_get_u32(info->attrs[MPTCP_ATTR_TOKEN]); -+ -+ meta_sk = mptcp_hash_find(genl_info_net(info), token); -+ if (!meta_sk) -+ return -EINVAL; -+ -+ mpcb = tcp_sk(meta_sk)->mpcb; -+ -+ mutex_lock(&mpcb->mpcb_mutex); -+ lock_sock_nested(meta_sk, SINGLE_DEPTH_NESTING); -+ -+ subsk = mptcp_nl_subsk_lookup(mpcb, info->attrs); -+ if (subsk) { -+ local_bh_disable(); -+ mptcp_reinject_data(subsk, 0); -+ mptcp_send_reset(subsk); -+ local_bh_enable(); -+ } else { -+ ret = -EINVAL; -+ } -+ -+ release_sock(meta_sk); -+ mutex_unlock(&mpcb->mpcb_mutex); -+ sock_put(meta_sk); -+ return ret; -+} -+ -+static int -+mptcp_nl_genl_conn_exists(struct sk_buff *skb, struct genl_info *info) -+{ -+ struct sock *meta_sk; -+ u32 token; -+ -+ if (!info->attrs[MPTCP_ATTR_TOKEN]) -+ return -EINVAL; -+ -+ token = nla_get_u32(info->attrs[MPTCP_ATTR_TOKEN]); -+ -+ meta_sk = mptcp_hash_find(genl_info_net(info), token); -+ if (!meta_sk) -+ return -ENOTCONN; -+ -+ sock_put(meta_sk); -+ return 0; -+} -+ -+static int -+mptcp_nl_genl_priority(struct sk_buff *skb, struct genl_info *info) -+{ -+ struct sock *meta_sk, *subsk; -+ struct mptcp_cb *mpcb; -+ int ret = 0; -+ u32 token; -+ u8 backup = 0; -+ -+ if (!info->attrs[MPTCP_ATTR_TOKEN]) -+ return -EINVAL; -+ -+ token = nla_get_u32(info->attrs[MPTCP_ATTR_TOKEN]); -+ if (info->attrs[MPTCP_ATTR_BACKUP]) -+ backup = nla_get_u8(info->attrs[MPTCP_ATTR_BACKUP]); -+ -+ meta_sk = mptcp_hash_find(genl_info_net(info), token); -+ if (!meta_sk) -+ return -EINVAL; -+ -+ mpcb = tcp_sk(meta_sk)->mpcb; -+ -+ mutex_lock(&mpcb->mpcb_mutex); -+ lock_sock_nested(meta_sk, SINGLE_DEPTH_NESTING); -+ -+ subsk = mptcp_nl_subsk_lookup(mpcb, info->attrs); -+ if (subsk) { -+ tcp_sk(subsk)->mptcp->send_mp_prio = 1; -+ tcp_sk(subsk)->mptcp->low_prio = !!backup; -+ -+ local_bh_disable(); -+ if (mptcp_sk_can_send_ack(subsk)) -+ tcp_send_ack(subsk); -+ else -+ ret = -ENOTCONN; -+ local_bh_enable(); -+ } else { -+ ret = -EINVAL; -+ } -+ -+ release_sock(meta_sk); -+ mutex_unlock(&mpcb->mpcb_mutex); -+ sock_put(meta_sk); -+ return ret; -+} -+ -+static int -+mptcp_nl_genl_set_filter(struct sk_buff *skb, struct genl_info *info) -+{ -+ u16 flags; -+ -+ if (!info->attrs[MPTCP_ATTR_FLAGS]) -+ return -EINVAL; -+ -+ flags = nla_get_u16(info->attrs[MPTCP_ATTR_FLAGS]); -+ -+ /* Only want to receive events that correspond to these flags */ -+ mptcp_nl_event_filter = ~flags; -+ -+ return 0; -+} -+ -+static struct genl_ops mptcp_genl_ops[] = { -+ { -+ .cmd = MPTCP_CMD_ANNOUNCE, -+ .doit = mptcp_nl_genl_announce, -+ .flags = GENL_ADMIN_PERM, -+ }, -+ { -+ .cmd = MPTCP_CMD_REMOVE, -+ .doit = mptcp_nl_genl_remove, -+ .flags = GENL_ADMIN_PERM, -+ }, -+ { -+ .cmd = MPTCP_CMD_SUB_CREATE, -+ .doit = mptcp_nl_genl_create, -+ .flags = GENL_ADMIN_PERM, -+ }, -+ { -+ .cmd = MPTCP_CMD_SUB_DESTROY, -+ .doit = mptcp_nl_genl_destroy, -+ .flags = GENL_ADMIN_PERM, -+ }, -+ { -+ .cmd = MPTCP_CMD_SUB_PRIORITY, -+ .doit = mptcp_nl_genl_priority, -+ .flags = GENL_ADMIN_PERM, -+ }, -+ { -+ .cmd = MPTCP_CMD_SET_FILTER, -+ .doit = mptcp_nl_genl_set_filter, -+ .flags = GENL_ADMIN_PERM, -+ }, -+ { -+ .cmd = MPTCP_CMD_EXIST, -+ .doit = mptcp_nl_genl_conn_exists, -+ .flags = GENL_ADMIN_PERM, -+ }, -+}; -+ -+static struct mptcp_pm_ops mptcp_nl_pm_ops = { -+ .new_session = mptcp_nl_pm_new_session, -+ .close_session = mptcp_nl_pm_close_session, -+ .fully_established = mptcp_nl_pm_fully_established, -+ .established_subflow = mptcp_nl_pm_established_subflow, -+ .delete_subflow = mptcp_nl_pm_delete_subflow, -+ .add_raddr = mptcp_nl_pm_add_raddr, -+ .rem_raddr = mptcp_nl_pm_rem_raddr, -+ .get_local_id = mptcp_nl_pm_get_local_id, -+ .addr_signal = mptcp_nl_pm_addr_signal, -+ .prio_changed = mptcp_nl_pm_prio_changed, -+ .name = "netlink", -+ .owner = THIS_MODULE, -+}; -+ -+static struct genl_family mptcp_genl_family = { -+ .hdrsize = 0, -+ .name = MPTCP_GENL_NAME, -+ .version = MPTCP_GENL_VER, -+ .maxattr = MPTCP_ATTR_MAX, -+ .policy = mptcp_nl_genl_policy, -+ .netnsok = true, -+ .module = THIS_MODULE, -+ .ops = mptcp_genl_ops, -+ .n_ops = ARRAY_SIZE(mptcp_genl_ops), -+ .mcgrps = mptcp_mcgrps, -+ .n_mcgrps = ARRAY_SIZE(mptcp_mcgrps), -+}; -+ -+static int __init -+mptcp_nl_init(void) -+{ -+ int ret; -+ -+ BUILD_BUG_ON(sizeof(struct mptcp_nl_priv) > MPTCP_PM_SIZE); -+ -+ ret = genl_register_family(&mptcp_genl_family); -+ if (ret) -+ goto out_genl; -+ -+ ret = mptcp_register_path_manager(&mptcp_nl_pm_ops); -+ if (ret) -+ goto out_pm; -+ -+ return 0; -+out_pm: -+ genl_unregister_family(&mptcp_genl_family); -+out_genl: -+ return ret; -+} -+ -+static void __exit -+mptcp_nl_exit(void) -+{ -+ mptcp_unregister_path_manager(&mptcp_nl_pm_ops); -+ genl_unregister_family(&mptcp_genl_family); -+} -+ -+module_init(mptcp_nl_init); -+module_exit(mptcp_nl_exit); -+ -+MODULE_AUTHOR("Gregory Detal "); -+MODULE_LICENSE("GPL"); -+MODULE_DESCRIPTION("MPTCP netlink-based path manager"); -+MODULE_ALIAS_GENL_FAMILY(MPTCP_GENL_NAME); -diff -aurN linux-5.4.64/net/mptcp/mptcp_olia.c linux-5.4.64.mptcp/net/mptcp/mptcp_olia.c ---- linux-5.4.64/net/mptcp/mptcp_olia.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-5.4.64.mptcp/net/mptcp/mptcp_olia.c 2020-09-10 19:25:10.507220869 +0200 -@@ -0,0 +1,318 @@ -+/* -+ * MPTCP implementation - OPPORTUNISTIC LINKED INCREASES CONGESTION CONTROL: -+ * -+ * Algorithm design: -+ * Ramin Khalili -+ * Nicolas Gast -+ * Jean-Yves Le Boudec -+ * -+ * Implementation: -+ * Ramin Khalili -+ * -+ * Ported to the official MPTCP-kernel: -+ * Christoph Paasch -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version -+ * 2 of the License, or (at your option) any later version. -+ */ -+ -+ -+#include -+#include -+ -+#include -+ -+static int scale = 10; -+ -+struct mptcp_olia { -+ u32 mptcp_loss1; -+ u32 mptcp_loss2; -+ u32 mptcp_loss3; -+ int epsilon_num; -+ u32 epsilon_den; -+ int mptcp_snd_cwnd_cnt; -+}; -+ -+static inline int mptcp_olia_sk_can_send(const struct sock *sk) -+{ -+ return mptcp_sk_can_send(sk) && tcp_sk(sk)->srtt_us; -+} -+ -+static inline u64 mptcp_olia_scale(u64 val, int scale) -+{ -+ return (u64) val << scale; -+} -+ -+/* take care of artificially inflate (see RFC5681) -+ * of cwnd during fast-retransmit phase -+ */ -+static u32 mptcp_get_crt_cwnd(struct sock *sk) -+{ -+ const struct inet_connection_sock *icsk = inet_csk(sk); -+ -+ if (icsk->icsk_ca_state == TCP_CA_Recovery) -+ return tcp_sk(sk)->snd_ssthresh; -+ else -+ return tcp_sk(sk)->snd_cwnd; -+} -+ -+/* return the dominator of the first term of the increasing term */ -+static u64 mptcp_get_rate(const struct mptcp_cb *mpcb , u32 path_rtt) -+{ -+ struct mptcp_tcp_sock *mptcp; -+ u64 rate = 1; /* We have to avoid a zero-rate because it is used as a divisor */ -+ -+ mptcp_for_each_sub(mpcb, mptcp) { -+ struct sock *sk = mptcp_to_sock(mptcp); -+ struct tcp_sock *tp = tcp_sk(sk); -+ u64 scaled_num; -+ u32 tmp_cwnd; -+ -+ if (!mptcp_olia_sk_can_send(sk)) -+ continue; -+ -+ tmp_cwnd = mptcp_get_crt_cwnd(sk); -+ scaled_num = mptcp_olia_scale(tmp_cwnd, scale) * path_rtt; -+ rate += div_u64(scaled_num , tp->srtt_us); -+ } -+ rate *= rate; -+ return rate; -+} -+ -+/* find the maximum cwnd, used to find set M */ -+static u32 mptcp_get_max_cwnd(const struct mptcp_cb *mpcb) -+{ -+ struct mptcp_tcp_sock *mptcp; -+ u32 best_cwnd = 0; -+ -+ mptcp_for_each_sub(mpcb, mptcp) { -+ struct sock *sk = mptcp_to_sock(mptcp); -+ u32 tmp_cwnd; -+ -+ if (!mptcp_olia_sk_can_send(sk)) -+ continue; -+ -+ tmp_cwnd = mptcp_get_crt_cwnd(sk); -+ if (tmp_cwnd > best_cwnd) -+ best_cwnd = tmp_cwnd; -+ } -+ return best_cwnd; -+} -+ -+static void mptcp_get_epsilon(const struct mptcp_cb *mpcb) -+{ -+ struct mptcp_tcp_sock *mptcp; -+ struct mptcp_olia *ca; -+ struct tcp_sock *tp; -+ struct sock *sk; -+ u64 tmp_int, tmp_rtt, best_int = 0, best_rtt = 1; -+ u32 max_cwnd, tmp_cwnd, established_cnt = 0; -+ u8 M = 0, B_not_M = 0; -+ -+ /* TODO - integrate this in the following loop - we just want to iterate once */ -+ -+ max_cwnd = mptcp_get_max_cwnd(mpcb); -+ -+ /* find the best path */ -+ mptcp_for_each_sub(mpcb, mptcp) { -+ sk = mptcp_to_sock(mptcp); -+ tp = tcp_sk(sk); -+ ca = inet_csk_ca(sk); -+ -+ if (!mptcp_olia_sk_can_send(sk)) -+ continue; -+ -+ established_cnt++; -+ -+ tmp_rtt = (u64)tp->srtt_us * tp->srtt_us; -+ /* TODO - check here and rename variables */ -+ tmp_int = max(ca->mptcp_loss3 - ca->mptcp_loss2, -+ ca->mptcp_loss2 - ca->mptcp_loss1); -+ -+ if ((u64)tmp_int * best_rtt >= (u64)best_int * tmp_rtt) { -+ best_rtt = tmp_rtt; -+ best_int = tmp_int; -+ } -+ } -+ -+ /* TODO - integrate this here in mptcp_get_max_cwnd and in the previous loop */ -+ /* find the size of M and B_not_M */ -+ mptcp_for_each_sub(mpcb, mptcp) { -+ sk = mptcp_to_sock(mptcp); -+ tp = tcp_sk(sk); -+ ca = inet_csk_ca(sk); -+ -+ if (!mptcp_olia_sk_can_send(sk)) -+ continue; -+ -+ tmp_cwnd = mptcp_get_crt_cwnd(sk); -+ if (tmp_cwnd == max_cwnd) { -+ M++; -+ } else { -+ tmp_rtt = (u64)tp->srtt_us * tp->srtt_us; -+ tmp_int = max(ca->mptcp_loss3 - ca->mptcp_loss2, -+ ca->mptcp_loss2 - ca->mptcp_loss1); -+ -+ if ((u64)tmp_int * best_rtt == (u64)best_int * tmp_rtt) -+ B_not_M++; -+ } -+ } -+ -+ /* check if the path is in M or B_not_M and set the value of epsilon accordingly */ -+ mptcp_for_each_sub(mpcb, mptcp) { -+ sk = mptcp_to_sock(mptcp); -+ tp = tcp_sk(sk); -+ ca = inet_csk_ca(sk); -+ -+ if (!mptcp_olia_sk_can_send(sk)) -+ continue; -+ -+ if (B_not_M == 0) { -+ ca->epsilon_num = 0; -+ ca->epsilon_den = 1; -+ } else { -+ tmp_rtt = (u64)tp->srtt_us * tp->srtt_us; -+ tmp_int = max(ca->mptcp_loss3 - ca->mptcp_loss2, -+ ca->mptcp_loss2 - ca->mptcp_loss1); -+ tmp_cwnd = mptcp_get_crt_cwnd(sk); -+ -+ if (tmp_cwnd < max_cwnd && -+ (u64)tmp_int * best_rtt == (u64)best_int * tmp_rtt) { -+ ca->epsilon_num = 1; -+ ca->epsilon_den = established_cnt * B_not_M; -+ } else if (tmp_cwnd == max_cwnd) { -+ ca->epsilon_num = -1; -+ ca->epsilon_den = established_cnt * M; -+ } else { -+ ca->epsilon_num = 0; -+ ca->epsilon_den = 1; -+ } -+ } -+ } -+} -+ -+/* setting the initial values */ -+static void mptcp_olia_init(struct sock *sk) -+{ -+ const struct tcp_sock *tp = tcp_sk(sk); -+ struct mptcp_olia *ca = inet_csk_ca(sk); -+ -+ if (mptcp(tp)) { -+ ca->mptcp_loss1 = tp->snd_una; -+ ca->mptcp_loss2 = tp->snd_una; -+ ca->mptcp_loss3 = tp->snd_una; -+ ca->mptcp_snd_cwnd_cnt = 0; -+ ca->epsilon_num = 0; -+ ca->epsilon_den = 1; -+ } -+} -+ -+/* updating inter-loss distance and ssthresh */ -+static void mptcp_olia_set_state(struct sock *sk, u8 new_state) -+{ -+ if (!mptcp(tcp_sk(sk))) -+ return; -+ -+ if (new_state == TCP_CA_Loss || -+ new_state == TCP_CA_Recovery || new_state == TCP_CA_CWR) { -+ struct mptcp_olia *ca = inet_csk_ca(sk); -+ -+ if (ca->mptcp_loss3 != ca->mptcp_loss2 && -+ !inet_csk(sk)->icsk_retransmits) { -+ ca->mptcp_loss1 = ca->mptcp_loss2; -+ ca->mptcp_loss2 = ca->mptcp_loss3; -+ } -+ } -+} -+ -+/* main algorithm */ -+static void mptcp_olia_cong_avoid(struct sock *sk, u32 ack, u32 acked) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct mptcp_olia *ca = inet_csk_ca(sk); -+ const struct mptcp_cb *mpcb = tp->mpcb; -+ -+ u64 inc_num, inc_den, rate, cwnd_scaled; -+ -+ if (!mptcp(tp)) { -+ tcp_reno_cong_avoid(sk, ack, acked); -+ return; -+ } -+ -+ ca->mptcp_loss3 = tp->snd_una; -+ -+ if (!tcp_is_cwnd_limited(sk)) -+ return; -+ -+ /* slow start if it is in the safe area */ -+ if (tcp_in_slow_start(tp)) { -+ tcp_slow_start(tp, acked); -+ return; -+ } -+ -+ mptcp_get_epsilon(mpcb); -+ rate = mptcp_get_rate(mpcb, tp->srtt_us); -+ cwnd_scaled = mptcp_olia_scale(tp->snd_cwnd, scale); -+ inc_den = ca->epsilon_den * tp->snd_cwnd * rate ? : 1; -+ -+ /* calculate the increasing term, scaling is used to reduce the rounding effect */ -+ if (ca->epsilon_num == -1) { -+ if (ca->epsilon_den * cwnd_scaled * cwnd_scaled < rate) { -+ inc_num = rate - ca->epsilon_den * -+ cwnd_scaled * cwnd_scaled; -+ ca->mptcp_snd_cwnd_cnt -= div64_u64( -+ mptcp_olia_scale(inc_num , scale) , inc_den); -+ } else { -+ inc_num = ca->epsilon_den * -+ cwnd_scaled * cwnd_scaled - rate; -+ ca->mptcp_snd_cwnd_cnt += div64_u64( -+ mptcp_olia_scale(inc_num , scale) , inc_den); -+ } -+ } else { -+ inc_num = ca->epsilon_num * rate + -+ ca->epsilon_den * cwnd_scaled * cwnd_scaled; -+ ca->mptcp_snd_cwnd_cnt += div64_u64( -+ mptcp_olia_scale(inc_num , scale) , inc_den); -+ } -+ -+ -+ if (ca->mptcp_snd_cwnd_cnt >= (1 << scale) - 1) { -+ if (tp->snd_cwnd < tp->snd_cwnd_clamp) -+ tp->snd_cwnd++; -+ ca->mptcp_snd_cwnd_cnt = 0; -+ } else if (ca->mptcp_snd_cwnd_cnt <= 0 - (1 << scale) + 1) { -+ tp->snd_cwnd = max((int) 1 , (int) tp->snd_cwnd - 1); -+ ca->mptcp_snd_cwnd_cnt = 0; -+ } -+} -+ -+static struct tcp_congestion_ops mptcp_olia = { -+ .init = mptcp_olia_init, -+ .ssthresh = tcp_reno_ssthresh, -+ .cong_avoid = mptcp_olia_cong_avoid, -+ .undo_cwnd = tcp_reno_undo_cwnd, -+ .set_state = mptcp_olia_set_state, -+ .owner = THIS_MODULE, -+ .name = "olia", -+}; -+ -+static int __init mptcp_olia_register(void) -+{ -+ BUILD_BUG_ON(sizeof(struct mptcp_olia) > ICSK_CA_PRIV_SIZE); -+ return tcp_register_congestion_control(&mptcp_olia); -+} -+ -+static void __exit mptcp_olia_unregister(void) -+{ -+ tcp_unregister_congestion_control(&mptcp_olia); -+} -+ -+module_init(mptcp_olia_register); -+module_exit(mptcp_olia_unregister); -+ -+MODULE_AUTHOR("Ramin Khalili, Nicolas Gast, Jean-Yves Le Boudec"); -+MODULE_LICENSE("GPL"); -+MODULE_DESCRIPTION("MPTCP COUPLED CONGESTION CONTROL"); -+MODULE_VERSION("0.1"); -diff -aurN linux-5.4.64/net/mptcp/mptcp_output.c linux-5.4.64.mptcp/net/mptcp/mptcp_output.c ---- linux-5.4.64/net/mptcp/mptcp_output.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-5.4.64.mptcp/net/mptcp/mptcp_output.c 2020-09-10 19:25:10.507220869 +0200 -@@ -0,0 +1,1997 @@ -+/* -+ * MPTCP implementation - Sending side -+ * -+ * Initial Design & Implementation: -+ * Sébastien Barré -+ * -+ * Current Maintainer & Author: -+ * Christoph Paasch -+ * -+ * Additional authors: -+ * Jaakko Korkeaniemi -+ * Gregory Detal -+ * Fabien Duchêne -+ * Andreas Seelinger -+ * Lavkesh Lahngir -+ * Andreas Ripke -+ * Vlad Dogaru -+ * Octavian Purdila -+ * John Ronan -+ * Catalin Nicutar -+ * Brandon Heller -+ * -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version -+ * 2 of the License, or (at your option) any later version. -+ */ -+ -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+ -+static const int mptcp_dss_len = MPTCP_SUB_LEN_DSS_ALIGN + -+ MPTCP_SUB_LEN_ACK_ALIGN + -+ MPTCP_SUB_LEN_SEQ_ALIGN; -+ -+static inline int mptcp_sub_len_remove_addr(u16 bitfield) -+{ -+ unsigned int c; -+ for (c = 0; bitfield; c++) -+ bitfield &= bitfield - 1; -+ return MPTCP_SUB_LEN_REMOVE_ADDR + c - 1; -+} -+ -+int mptcp_sub_len_remove_addr_align(u16 bitfield) -+{ -+ return ALIGN(mptcp_sub_len_remove_addr(bitfield), 4); -+} -+EXPORT_SYMBOL(mptcp_sub_len_remove_addr_align); -+ -+/* get the data-seq and end-data-seq and store them again in the -+ * tcp_skb_cb -+ */ -+static bool mptcp_reconstruct_mapping(struct sk_buff *skb) -+{ -+ const struct mp_dss *mpdss = (struct mp_dss *)TCP_SKB_CB(skb)->dss; -+ __be32 *p32; -+ __be16 *p16; -+ -+ if (!mptcp_is_data_seq(skb)) -+ return false; -+ -+ if (!mpdss->M) -+ return false; -+ -+ /* Move the pointer to the data-seq */ -+ p32 = (__be32 *)mpdss; -+ p32++; -+ if (mpdss->A) { -+ p32++; -+ if (mpdss->a) -+ p32++; -+ } -+ -+ TCP_SKB_CB(skb)->seq = ntohl(*p32); -+ -+ /* Get the data_len to calculate the end_data_seq */ -+ p32++; -+ p32++; -+ p16 = (__be16 *)p32; -+ TCP_SKB_CB(skb)->end_seq = ntohs(*p16) + TCP_SKB_CB(skb)->seq; -+ -+ return true; -+} -+ -+static bool mptcp_is_reinjected(const struct sk_buff *skb) -+{ -+ return TCP_SKB_CB(skb)->mptcp_flags & MPTCP_REINJECT; -+} -+ -+static void mptcp_find_and_set_pathmask(struct sock *meta_sk, struct sk_buff *skb) -+{ -+ struct rb_node **p = &meta_sk->tcp_rtx_queue.rb_node; -+ struct rb_node *parent; -+ struct sk_buff *skb_it; -+ -+ while (*p) { -+ parent = *p; -+ skb_it = rb_to_skb(parent); -+ if (before(TCP_SKB_CB(skb)->seq, TCP_SKB_CB(skb_it)->seq)) { -+ p = &parent->rb_left; -+ continue; -+ } -+ if (after(TCP_SKB_CB(skb)->seq, TCP_SKB_CB(skb_it)->seq)) { -+ p = &parent->rb_right; -+ continue; -+ } -+ -+ TCP_SKB_CB(skb)->path_mask = TCP_SKB_CB(skb_it)->path_mask; -+ break; -+ } -+} -+ -+/* Reinject data from one TCP subflow to the meta_sk. If sk == NULL, we are -+ * coming from the meta-retransmit-timer -+ */ -+static void __mptcp_reinject_data(struct sk_buff *orig_skb, struct sock *meta_sk, -+ struct sock *sk, int clone_it, -+ enum tcp_queue tcp_queue) -+{ -+ struct sk_buff *skb, *skb1; -+ const struct tcp_sock *meta_tp = tcp_sk(meta_sk); -+ struct mptcp_cb *mpcb = meta_tp->mpcb; -+ u32 seq, end_seq; -+ -+ if (clone_it) { -+ /* pskb_copy is necessary here, because the TCP/IP-headers -+ * will be changed when it's going to be reinjected on another -+ * subflow. -+ */ -+ tcp_skb_tsorted_save(orig_skb) { -+ skb = pskb_copy_for_clone(orig_skb, GFP_ATOMIC); -+ } tcp_skb_tsorted_restore(orig_skb); -+ } else { -+ if (tcp_queue == TCP_FRAG_IN_WRITE_QUEUE) { -+ __skb_unlink(orig_skb, &sk->sk_write_queue); -+ } else { -+ list_del(&orig_skb->tcp_tsorted_anchor); -+ tcp_rtx_queue_unlink(orig_skb, sk); -+ INIT_LIST_HEAD(&orig_skb->tcp_tsorted_anchor); -+ } -+ sock_set_flag(sk, SOCK_QUEUE_SHRUNK); -+ sk->sk_wmem_queued -= orig_skb->truesize; -+ sk_mem_uncharge(sk, orig_skb->truesize); -+ skb = orig_skb; -+ } -+ if (unlikely(!skb)) -+ return; -+ -+ /* Make sure that this list is clean */ -+ tcp_skb_tsorted_anchor_cleanup(skb); -+ -+ if (sk && !mptcp_reconstruct_mapping(skb)) { -+ __kfree_skb(skb); -+ return; -+ } -+ -+ skb->sk = meta_sk; -+ -+ /* Reset subflow-specific TCP control-data */ -+ TCP_SKB_CB(skb)->sacked = 0; -+ TCP_SKB_CB(skb)->tcp_flags &= (TCPHDR_ACK | TCPHDR_PSH); -+ -+ /* If it reached already the destination, we don't have to reinject it */ -+ if (!after(TCP_SKB_CB(skb)->end_seq, meta_tp->snd_una)) { -+ __kfree_skb(skb); -+ return; -+ } -+ -+ /* Only reinject segments that are fully covered by the mapping */ -+ if (skb->len + (mptcp_is_data_fin(skb) ? 1 : 0) != -+ TCP_SKB_CB(skb)->end_seq - TCP_SKB_CB(skb)->seq) { -+ struct rb_node *parent, **p = &meta_sk->tcp_rtx_queue.rb_node; -+ u32 end_seq = TCP_SKB_CB(skb)->end_seq; -+ u32 seq = TCP_SKB_CB(skb)->seq; -+ -+ __kfree_skb(skb); -+ -+ /* Ok, now we have to look for the full mapping in the meta -+ * send-queue :S -+ */ -+ -+ /* First, find the first skb that covers us */ -+ while (*p) { -+ parent = *p; -+ skb = rb_to_skb(parent); -+ -+ /* Not yet at the mapping? */ -+ if (!after(end_seq, TCP_SKB_CB(skb)->seq)) { -+ p = &parent->rb_left; -+ continue; -+ } -+ -+ if (!before(seq, TCP_SKB_CB(skb)->end_seq)) { -+ p = &parent->rb_right; -+ continue; -+ } -+ -+ break; -+ } -+ -+ if (*p) { -+ /* We found it, now let's reinject everything */ -+ skb = rb_to_skb(*p); -+ -+ skb_rbtree_walk_from(skb) { -+ if (after(TCP_SKB_CB(skb)->end_seq, end_seq)) -+ return; -+ __mptcp_reinject_data(skb, meta_sk, NULL, 1, -+ TCP_FRAG_IN_RTX_QUEUE); -+ } -+ } -+ return; -+ } -+ -+ /* Segment goes back to the MPTCP-layer. So, we need to zero the -+ * path_mask/dss. -+ */ -+ memset(TCP_SKB_CB(skb)->dss, 0 , mptcp_dss_len); -+ -+ /* We need to find out the path-mask from the meta-write-queue -+ * to properly select a subflow. -+ */ -+ mptcp_find_and_set_pathmask(meta_sk, skb); -+ -+ /* If it's empty, just add */ -+ if (skb_queue_empty(&mpcb->reinject_queue)) { -+ skb_queue_head(&mpcb->reinject_queue, skb); -+ return; -+ } -+ -+ /* Find place to insert skb - or even we can 'drop' it, as the -+ * data is already covered by other skb's in the reinject-queue. -+ * -+ * This is inspired by code from tcp_data_queue. -+ */ -+ -+ skb1 = skb_peek_tail(&mpcb->reinject_queue); -+ seq = TCP_SKB_CB(skb)->seq; -+ while (1) { -+ if (!after(TCP_SKB_CB(skb1)->seq, seq)) -+ break; -+ if (skb_queue_is_first(&mpcb->reinject_queue, skb1)) { -+ skb1 = NULL; -+ break; -+ } -+ skb1 = skb_queue_prev(&mpcb->reinject_queue, skb1); -+ } -+ -+ /* Do skb overlap to previous one? */ -+ end_seq = TCP_SKB_CB(skb)->end_seq; -+ if (skb1 && before(seq, TCP_SKB_CB(skb1)->end_seq)) { -+ if (!after(end_seq, TCP_SKB_CB(skb1)->end_seq)) { -+ /* All the bits are present. Don't reinject */ -+ __kfree_skb(skb); -+ return; -+ } -+ if (seq == TCP_SKB_CB(skb1)->seq) { -+ if (skb_queue_is_first(&mpcb->reinject_queue, skb1)) -+ skb1 = NULL; -+ else -+ skb1 = skb_queue_prev(&mpcb->reinject_queue, skb1); -+ } -+ } -+ if (!skb1) -+ __skb_queue_head(&mpcb->reinject_queue, skb); -+ else -+ __skb_queue_after(&mpcb->reinject_queue, skb1, skb); -+ -+ /* And clean segments covered by new one as whole. */ -+ while (!skb_queue_is_last(&mpcb->reinject_queue, skb)) { -+ skb1 = skb_queue_next(&mpcb->reinject_queue, skb); -+ -+ if (!after(end_seq, TCP_SKB_CB(skb1)->seq)) -+ break; -+ -+ if (before(end_seq, TCP_SKB_CB(skb1)->end_seq)) -+ break; -+ -+ __skb_unlink(skb1, &mpcb->reinject_queue); -+ __kfree_skb(skb1); -+ } -+ return; -+} -+ -+/* Inserts data into the reinject queue */ -+void mptcp_reinject_data(struct sock *sk, int clone_it) -+{ -+ struct sock *meta_sk = mptcp_meta_sk(sk); -+ struct sk_buff *skb_it, *tmp; -+ enum tcp_queue tcp_queue; -+ -+ /* It has already been closed - there is really no point in reinjecting */ -+ if (meta_sk->sk_state == TCP_CLOSE) -+ return; -+ -+ skb_queue_walk_safe(&sk->sk_write_queue, skb_it, tmp) { -+ struct tcp_skb_cb *tcb = TCP_SKB_CB(skb_it); -+ /* Subflow syn's and fin's are not reinjected. -+ * -+ * As well as empty subflow-fins with a data-fin. -+ * They are reinjected below (without the subflow-fin-flag) -+ */ -+ if (tcb->tcp_flags & TCPHDR_SYN || -+ (tcb->tcp_flags & TCPHDR_FIN && !mptcp_is_data_fin(skb_it)) || -+ (tcb->tcp_flags & TCPHDR_FIN && mptcp_is_data_fin(skb_it) && !skb_it->len)) -+ continue; -+ -+ if (mptcp_is_reinjected(skb_it)) -+ continue; -+ -+ tcb->mptcp_flags |= MPTCP_REINJECT; -+ __mptcp_reinject_data(skb_it, meta_sk, sk, clone_it, -+ TCP_FRAG_IN_WRITE_QUEUE); -+ } -+ -+ skb_it = tcp_rtx_queue_head(sk); -+ skb_rbtree_walk_from_safe(skb_it, tmp) { -+ struct tcp_skb_cb *tcb = TCP_SKB_CB(skb_it); -+ -+ /* Subflow syn's and fin's are not reinjected. -+ * -+ * As well as empty subflow-fins with a data-fin. -+ * They are reinjected below (without the subflow-fin-flag) -+ */ -+ if (tcb->tcp_flags & TCPHDR_SYN || -+ (tcb->tcp_flags & TCPHDR_FIN && !mptcp_is_data_fin(skb_it)) || -+ (tcb->tcp_flags & TCPHDR_FIN && mptcp_is_data_fin(skb_it) && !skb_it->len)) -+ continue; -+ -+ if (mptcp_is_reinjected(skb_it)) -+ continue; -+ -+ tcb->mptcp_flags |= MPTCP_REINJECT; -+ __mptcp_reinject_data(skb_it, meta_sk, sk, clone_it, -+ TCP_FRAG_IN_RTX_QUEUE); -+ } -+ -+ skb_it = tcp_write_queue_tail(meta_sk); -+ tcp_queue = TCP_FRAG_IN_WRITE_QUEUE; -+ -+ if (!skb_it) { -+ skb_it = skb_rb_last(&meta_sk->tcp_rtx_queue); -+ tcp_queue = TCP_FRAG_IN_RTX_QUEUE; -+ } -+ -+ /* If sk has sent the empty data-fin, we have to reinject it too. */ -+ if (skb_it && mptcp_is_data_fin(skb_it) && skb_it->len == 0 && -+ TCP_SKB_CB(skb_it)->path_mask & mptcp_pi_to_flag(tcp_sk(sk)->mptcp->path_index)) { -+ __mptcp_reinject_data(skb_it, meta_sk, NULL, 1, tcp_queue); -+ } -+ -+ tcp_sk(sk)->pf = 1; -+ -+ mptcp_push_pending_frames(meta_sk); -+} -+EXPORT_SYMBOL(mptcp_reinject_data); -+ -+static void mptcp_combine_dfin(const struct sk_buff *skb, -+ const struct sock *meta_sk, -+ struct sock *subsk) -+{ -+ const struct tcp_sock *meta_tp = tcp_sk(meta_sk); -+ const struct mptcp_cb *mpcb = meta_tp->mpcb; -+ -+ /* In infinite mapping we always try to combine */ -+ if (mpcb->infinite_mapping_snd) -+ goto combine; -+ -+ /* Don't combine, if they didn't combine when closing - otherwise we end -+ * up in TIME_WAIT, even if our app is smart enough to avoid it. -+ */ -+ if (!mptcp_sk_can_recv(meta_sk) && !mpcb->dfin_combined) -+ return; -+ -+ /* Don't combine if there is still outstanding data that remains to be -+ * DATA_ACKed, because otherwise we may never be able to deliver this. -+ */ -+ if (meta_tp->snd_una != TCP_SKB_CB(skb)->seq) -+ return; -+ -+combine: -+ if (tcp_close_state(subsk)) { -+ subsk->sk_shutdown |= SEND_SHUTDOWN; -+ TCP_SKB_CB(skb)->tcp_flags |= TCPHDR_FIN; -+ } -+} -+ -+static int mptcp_write_dss_mapping(const struct tcp_sock *tp, const struct sk_buff *skb, -+ __be32 *ptr) -+{ -+ const struct tcp_skb_cb *tcb = TCP_SKB_CB(skb); -+ __be32 *start = ptr; -+ __u16 data_len; -+ -+ *ptr++ = htonl(tcb->seq); /* data_seq */ -+ -+ /* If it's a non-data DATA_FIN, we set subseq to 0 (draft v7) */ -+ if (mptcp_is_data_fin(skb) && skb->len == 0) -+ *ptr++ = 0; /* subseq */ -+ else -+ *ptr++ = htonl(tp->write_seq - tp->mptcp->snt_isn); /* subseq */ -+ -+ if (tcb->mptcp_flags & MPTCPHDR_INF) -+ data_len = 0; -+ else -+ data_len = tcb->end_seq - tcb->seq; -+ -+ if (tp->mpcb->dss_csum && data_len) { -+ __sum16 *p16 = (__sum16 *)ptr; -+ __be32 hdseq = mptcp_get_highorder_sndbits(skb, tp->mpcb); -+ __wsum csum; -+ -+ *ptr = htonl(((data_len) << 16) | -+ (TCPOPT_EOL << 8) | -+ (TCPOPT_EOL)); -+ csum = csum_partial(ptr - 2, 12, skb->csum); -+ p16++; -+ *p16++ = csum_fold(csum_partial(&hdseq, sizeof(hdseq), csum)); -+ } else { -+ *ptr++ = htonl(((data_len) << 16) | -+ (TCPOPT_NOP << 8) | -+ (TCPOPT_NOP)); -+ } -+ -+ return ptr - start; -+} -+ -+static int mptcp_write_dss_data_ack(const struct tcp_sock *tp, const struct sk_buff *skb, -+ __be32 *ptr) -+{ -+ struct mp_dss *mdss = (struct mp_dss *)ptr; -+ __be32 *start = ptr; -+ -+ mdss->kind = TCPOPT_MPTCP; -+ mdss->sub = MPTCP_SUB_DSS; -+ mdss->rsv1 = 0; -+ mdss->rsv2 = 0; -+ mdss->F = mptcp_is_data_fin(skb) ? 1 : 0; -+ mdss->m = 0; -+ mdss->M = mptcp_is_data_seq(skb) ? 1 : 0; -+ mdss->a = 0; -+ mdss->A = 1; -+ mdss->len = mptcp_sub_len_dss(mdss, tp->mpcb->dss_csum); -+ ptr++; -+ -+ *ptr++ = htonl(mptcp_meta_tp(tp)->rcv_nxt); -+ -+ return ptr - start; -+} -+ -+/* RFC6824 states that once a particular subflow mapping has been sent -+ * out it must never be changed. However, packets may be split while -+ * they are in the retransmission queue (due to SACK or ACKs) and that -+ * arguably means that we would change the mapping (e.g. it splits it, -+ * our sends out a subset of the initial mapping). -+ * -+ * Furthermore, the skb checksum is not always preserved across splits -+ * (e.g. mptcp_fragment) which would mean that we need to recompute -+ * the DSS checksum in this case. -+ * -+ * To avoid this we save the initial DSS mapping which allows us to -+ * send the same DSS mapping even for fragmented retransmits. -+ */ -+static void mptcp_save_dss_data_seq(const struct tcp_sock *tp, struct sk_buff *skb) -+{ -+ struct tcp_skb_cb *tcb = TCP_SKB_CB(skb); -+ __be32 *ptr = (__be32 *)tcb->dss; -+ -+ tcb->mptcp_flags |= MPTCPHDR_SEQ; -+ -+ ptr += mptcp_write_dss_data_ack(tp, skb, ptr); -+ ptr += mptcp_write_dss_mapping(tp, skb, ptr); -+} -+ -+/* Write the MP_CAPABLE with data-option */ -+static int mptcp_write_mpcapable_data(const struct tcp_sock *tp, -+ struct sk_buff *skb, -+ __be32 *ptr) -+{ -+ struct mp_capable *mpc = (struct mp_capable *)ptr; -+ u8 length; -+ -+ if (tp->mpcb->dss_csum) -+ length = MPTCPV1_SUB_LEN_CAPABLE_DATA_CSUM; -+ else -+ length = MPTCPV1_SUB_LEN_CAPABLE_DATA; -+ -+ mpc->kind = TCPOPT_MPTCP; -+ mpc->len = length; -+ mpc->sub = MPTCP_SUB_CAPABLE; -+ mpc->ver = MPTCP_VERSION_1; -+ mpc->a = tp->mpcb->dss_csum; -+ mpc->b = 0; -+ mpc->rsv = 0; -+ mpc->h = 1; -+ -+ ptr++; -+ memcpy(ptr, TCP_SKB_CB(skb)->dss, mptcp_dss_len); -+ -+ mpc->sender_key = tp->mpcb->mptcp_loc_key; -+ mpc->receiver_key = tp->mpcb->mptcp_rem_key; -+ -+ /* dss is in a union with inet_skb_parm and -+ * the IP layer expects zeroed IPCB fields. -+ */ -+ memset(TCP_SKB_CB(skb)->dss, 0, mptcp_dss_len); -+ -+ return MPTCPV1_SUB_LEN_CAPABLE_DATA_ALIGN / sizeof(*ptr); -+} -+ -+/* Write the saved DSS mapping to the header */ -+static int mptcp_write_dss_data_seq(const struct tcp_sock *tp, struct sk_buff *skb, -+ __be32 *ptr) -+{ -+ int length; -+ __be32 *start = ptr; -+ -+ if (tp->mpcb->rem_key_set) { -+ memcpy(ptr, TCP_SKB_CB(skb)->dss, mptcp_dss_len); -+ -+ /* update the data_ack */ -+ start[1] = htonl(mptcp_meta_tp(tp)->rcv_nxt); -+ -+ length = mptcp_dss_len / sizeof(*ptr); -+ } else { -+ memcpy(ptr, TCP_SKB_CB(skb)->dss, MPTCP_SUB_LEN_DSS_ALIGN); -+ -+ ptr++; -+ memcpy(ptr, TCP_SKB_CB(skb)->dss + 2, MPTCP_SUB_LEN_SEQ_ALIGN); -+ -+ length = (MPTCP_SUB_LEN_DSS_ALIGN + MPTCP_SUB_LEN_SEQ_ALIGN) / sizeof(*ptr); -+ } -+ -+ /* dss is in a union with inet_skb_parm and -+ * the IP layer expects zeroed IPCB fields. -+ */ -+ memset(TCP_SKB_CB(skb)->dss, 0 , mptcp_dss_len); -+ -+ return length; -+} -+ -+static bool mptcp_skb_entail(struct sock *sk, struct sk_buff *skb, int reinject) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ const struct sock *meta_sk = mptcp_meta_sk(sk); -+ struct mptcp_cb *mpcb = tp->mpcb; -+ struct tcp_skb_cb *tcb; -+ struct sk_buff *subskb = NULL; -+ -+ if (!reinject) -+ TCP_SKB_CB(skb)->mptcp_flags |= (mpcb->snd_hiseq_index ? -+ MPTCPHDR_SEQ64_INDEX : 0); -+ -+ tcp_skb_tsorted_save(skb) { -+ subskb = pskb_copy_for_clone(skb, GFP_ATOMIC); -+ } tcp_skb_tsorted_restore(skb); -+ if (!subskb) -+ return false; -+ -+ /* At the subflow-level we need to call again tcp_init_tso_segs. We -+ * force this, by setting pcount to 0. It has been set to 1 prior to -+ * the call to mptcp_skb_entail. -+ */ -+ tcp_skb_pcount_set(subskb, 0); -+ -+ TCP_SKB_CB(skb)->path_mask |= mptcp_pi_to_flag(tp->mptcp->path_index); -+ -+ /* Compute checksum */ -+ if (tp->mpcb->dss_csum) -+ subskb->csum = skb->csum = skb_checksum(skb, 0, skb->len, 0); -+ -+ tcb = TCP_SKB_CB(subskb); -+ -+ if (tp->mpcb->send_infinite_mapping && -+ !tp->mpcb->infinite_mapping_snd && -+ !before(tcb->seq, mptcp_meta_tp(tp)->snd_nxt)) { -+ tp->mptcp->fully_established = 1; -+ tp->mpcb->infinite_mapping_snd = 1; -+ tp->mptcp->infinite_cutoff_seq = tp->write_seq; -+ tcb->mptcp_flags |= MPTCPHDR_INF; -+ } -+ -+ if (mptcp_is_data_fin(subskb)) -+ mptcp_combine_dfin(subskb, meta_sk, sk); -+ -+ mptcp_save_dss_data_seq(tp, subskb); -+ -+ if (mpcb->send_mptcpv1_mpcapable) { -+ TCP_SKB_CB(subskb)->mptcp_flags |= MPTCPHDR_MPC_DATA; -+ mpcb->send_mptcpv1_mpcapable = 0; -+ } -+ -+ tcb->seq = tp->write_seq; -+ -+ /* Take into account seg len */ -+ tp->write_seq += subskb->len + ((tcb->tcp_flags & TCPHDR_FIN) ? 1 : 0); -+ tcb->end_seq = tp->write_seq; -+ -+ /* txstamp_ack is handled at the meta-level */ -+ tcb->txstamp_ack = 0; -+ -+ /* If it's a non-payload DATA_FIN (also no subflow-fin), the -+ * segment is not part of the subflow but on a meta-only-level. -+ */ -+ if (!mptcp_is_data_fin(subskb) || tcb->end_seq != tcb->seq) { -+ /* Make sure that this list is clean */ -+ INIT_LIST_HEAD(&subskb->tcp_tsorted_anchor); -+ -+ tcp_add_write_queue_tail(sk, subskb); -+ sk->sk_wmem_queued += subskb->truesize; -+ sk_mem_charge(sk, subskb->truesize); -+ } else { -+ /* Necessary to initialize for tcp_transmit_skb. mss of 1, as -+ * skb->len = 0 will force tso_segs to 1. -+ */ -+ tcp_init_tso_segs(subskb, 1); -+ -+ /* Empty data-fins are sent immediatly on the subflow */ -+ if (tcp_transmit_skb(sk, subskb, 0, GFP_ATOMIC)) -+ return false; -+ } -+ -+ if (!tp->mptcp->fully_established) { -+ tp->mptcp->second_packet = 1; -+ tp->mptcp->last_end_data_seq = TCP_SKB_CB(skb)->end_seq; -+ } -+ -+ return true; -+} -+ -+/* Fragment an skb and update the mptcp meta-data. Due to reinject, we -+ * might need to undo some operations done by tcp_fragment. -+ * -+ * Be careful, the skb may come from 3 different places: -+ * - The send-queue (tcp_queue == TCP_FRAG_IN_WRITE_QUEUE) -+ * - The retransmit-queue (tcp_queue == TCP_FRAG_IN_RTX_QUEUE) -+ * - The reinject-queue (reinject == -1) -+ */ -+static int mptcp_fragment(struct sock *meta_sk, enum tcp_queue tcp_queue, -+ struct sk_buff *skb, u32 len, -+ gfp_t gfp, int reinject) -+{ -+ int ret, diff, old_factor; -+ struct sk_buff *buff; -+ u8 flags; -+ -+ if (skb_headlen(skb) < len) -+ diff = skb->len - len; -+ else -+ diff = skb->data_len; -+ old_factor = tcp_skb_pcount(skb); -+ -+ /* The mss_now in tcp_fragment is used to set the tso_segs of the skb. -+ * At the MPTCP-level we do not care about the absolute value. All we -+ * care about is that it is set to 1 for accurate packets_out -+ * accounting. -+ */ -+ ret = tcp_fragment(meta_sk, tcp_queue, skb, len, UINT_MAX, gfp); -+ if (ret) -+ return ret; -+ -+ if (tcp_queue == TCP_FRAG_IN_WRITE_QUEUE) -+ buff = skb->next; -+ else -+ buff = skb_rb_next(skb); -+ -+ flags = TCP_SKB_CB(skb)->mptcp_flags; -+ TCP_SKB_CB(skb)->mptcp_flags = flags & ~(MPTCPHDR_FIN); -+ TCP_SKB_CB(buff)->mptcp_flags = flags; -+ TCP_SKB_CB(buff)->path_mask = TCP_SKB_CB(skb)->path_mask; -+ -+ /* If reinject == 1, the buff will be added to the reinject -+ * queue, which is currently not part of memory accounting. So -+ * undo the changes done by tcp_fragment and update the -+ * reinject queue. Also, undo changes to the packet counters. -+ */ -+ if (reinject == 1) { -+ int undo = buff->truesize - diff; -+ meta_sk->sk_wmem_queued -= undo; -+ sk_mem_uncharge(meta_sk, undo); -+ -+ tcp_sk(meta_sk)->mpcb->reinject_queue.qlen++; -+ if (tcp_queue == TCP_FRAG_IN_WRITE_QUEUE) -+ meta_sk->sk_write_queue.qlen--; -+ -+ if (!before(tcp_sk(meta_sk)->snd_nxt, TCP_SKB_CB(buff)->end_seq)) { -+ undo = old_factor - tcp_skb_pcount(skb) - -+ tcp_skb_pcount(buff); -+ if (undo) -+ tcp_adjust_pcount(meta_sk, skb, -undo); -+ } -+ -+ /* tcp_fragment's call to sk_stream_alloc_skb initializes the -+ * tcp_tsorted_anchor. We need to revert this as it clashes -+ * with the refdst pointer. -+ */ -+ tcp_skb_tsorted_anchor_cleanup(buff); -+ } -+ -+ return 0; -+} -+ -+/* Inspired by tcp_write_wakeup */ -+int mptcp_write_wakeup(struct sock *meta_sk, int mib) -+{ -+ struct tcp_sock *meta_tp = tcp_sk(meta_sk); -+ struct sk_buff *skb; -+ int ans = 0; -+ -+ if (meta_sk->sk_state == TCP_CLOSE) -+ return -1; -+ -+ skb = tcp_send_head(meta_sk); -+ if (skb && -+ before(TCP_SKB_CB(skb)->seq, tcp_wnd_end(meta_tp))) { -+ unsigned int mss; -+ unsigned int seg_size = tcp_wnd_end(meta_tp) - TCP_SKB_CB(skb)->seq; -+ struct sock *subsk = meta_tp->mpcb->sched_ops->get_subflow(meta_sk, skb, true); -+ struct tcp_sock *subtp; -+ -+ WARN_ON(TCP_SKB_CB(skb)->sacked); -+ -+ if (!subsk) -+ goto window_probe; -+ subtp = tcp_sk(subsk); -+ mss = tcp_current_mss(subsk); -+ -+ seg_size = min(tcp_wnd_end(meta_tp) - TCP_SKB_CB(skb)->seq, -+ tcp_wnd_end(subtp) - subtp->write_seq); -+ -+ if (before(meta_tp->pushed_seq, TCP_SKB_CB(skb)->end_seq)) -+ meta_tp->pushed_seq = TCP_SKB_CB(skb)->end_seq; -+ -+ /* We are probing the opening of a window -+ * but the window size is != 0 -+ * must have been a result SWS avoidance ( sender ) -+ */ -+ if (seg_size < TCP_SKB_CB(skb)->end_seq - TCP_SKB_CB(skb)->seq || -+ skb->len > mss) { -+ seg_size = min(seg_size, mss); -+ TCP_SKB_CB(skb)->tcp_flags |= TCPHDR_PSH; -+ if (mptcp_fragment(meta_sk, TCP_FRAG_IN_WRITE_QUEUE, -+ skb, seg_size, GFP_ATOMIC, 0)) -+ return -1; -+ } else if (!tcp_skb_pcount(skb)) { -+ /* see mptcp_write_xmit on why we use UINT_MAX */ -+ tcp_set_skb_tso_segs(skb, UINT_MAX); -+ } -+ -+ TCP_SKB_CB(skb)->tcp_flags |= TCPHDR_PSH; -+ if (!mptcp_skb_entail(subsk, skb, 0)) -+ return -1; -+ -+ mptcp_check_sndseq_wrap(meta_tp, TCP_SKB_CB(skb)->end_seq - -+ TCP_SKB_CB(skb)->seq); -+ tcp_event_new_data_sent(meta_sk, skb); -+ -+ __tcp_push_pending_frames(subsk, mss, TCP_NAGLE_PUSH); -+ tcp_update_skb_after_send(meta_sk, skb, meta_tp->tcp_wstamp_ns); -+ meta_tp->lsndtime = tcp_jiffies32; -+ -+ return 0; -+ } else { -+ struct mptcp_tcp_sock *mptcp; -+ -+window_probe: -+ if (between(meta_tp->snd_up, meta_tp->snd_una + 1, -+ meta_tp->snd_una + 0xFFFF)) { -+ mptcp_for_each_sub(meta_tp->mpcb, mptcp) { -+ struct sock *sk_it = mptcp_to_sock(mptcp); -+ -+ if (mptcp_sk_can_send_ack(sk_it)) -+ tcp_xmit_probe_skb(sk_it, 1, mib); -+ } -+ } -+ -+ /* At least one of the tcp_xmit_probe_skb's has to succeed */ -+ mptcp_for_each_sub(meta_tp->mpcb, mptcp) { -+ struct sock *sk_it = mptcp_to_sock(mptcp); -+ int ret; -+ -+ if (!mptcp_sk_can_send_ack(sk_it)) -+ continue; -+ -+ ret = tcp_xmit_probe_skb(sk_it, 0, mib); -+ if (unlikely(ret > 0)) -+ ans = ret; -+ } -+ return ans; -+ } -+} -+ -+bool mptcp_write_xmit(struct sock *meta_sk, unsigned int mss_now, int nonagle, -+ int push_one, gfp_t gfp) -+{ -+ struct tcp_sock *meta_tp = tcp_sk(meta_sk), *subtp; -+ struct mptcp_tcp_sock *mptcp; -+ struct sock *subsk = NULL; -+ struct mptcp_cb *mpcb = meta_tp->mpcb; -+ struct sk_buff *skb; -+ int reinject = 0; -+ unsigned int sublimit; -+ __u32 path_mask = 0; -+ -+ tcp_mstamp_refresh(meta_tp); -+ -+ if (inet_csk(meta_sk)->icsk_retransmits) { -+ /* If the timer already once fired, retransmit the head of the -+ * queue to unblock us ASAP. -+ */ -+ if (meta_tp->packets_out && !mpcb->infinite_mapping_snd) -+ mptcp_retransmit_skb(meta_sk, tcp_rtx_queue_head(meta_sk)); -+ } -+ -+ while ((skb = mpcb->sched_ops->next_segment(meta_sk, &reinject, &subsk, -+ &sublimit))) { -+ enum tcp_queue tcp_queue = TCP_FRAG_IN_WRITE_QUEUE; -+ unsigned int limit; -+ -+ WARN(TCP_SKB_CB(skb)->sacked, "sacked: %u reinject: %u", -+ TCP_SKB_CB(skb)->sacked, reinject); -+ -+ subtp = tcp_sk(subsk); -+ mss_now = tcp_current_mss(subsk); -+ -+ if (reinject == 1) { -+ if (!after(TCP_SKB_CB(skb)->end_seq, meta_tp->snd_una)) { -+ /* Segment already reached the peer, take the next one */ -+ __skb_unlink(skb, &mpcb->reinject_queue); -+ __kfree_skb(skb); -+ continue; -+ } -+ } else if (reinject == -1) { -+ tcp_queue = TCP_FRAG_IN_RTX_QUEUE; -+ } -+ -+ /* If the segment was cloned (e.g. a meta retransmission), -+ * the header must be expanded/copied so that there is no -+ * corruption of TSO information. -+ */ -+ if (skb_unclone(skb, GFP_ATOMIC)) -+ break; -+ -+ if (unlikely(!tcp_snd_wnd_test(meta_tp, skb, mss_now))) -+ break; -+ -+ /* Force tso_segs to 1 by using UINT_MAX. -+ * We actually don't care about the exact number of segments -+ * emitted on the subflow. We need just to set tso_segs, because -+ * we still need an accurate packets_out count in -+ * tcp_event_new_data_sent. -+ */ -+ tcp_set_skb_tso_segs(skb, UINT_MAX); -+ -+ /* Check for nagle, irregardless of tso_segs. If the segment is -+ * actually larger than mss_now (TSO segment), then -+ * tcp_nagle_check will have partial == false and always trigger -+ * the transmission. -+ * tcp_write_xmit has a TSO-level nagle check which is not -+ * subject to the MPTCP-level. It is based on the properties of -+ * the subflow, not the MPTCP-level. -+ * When the segment is a reinjection or redundant scheduled -+ * segment, nagle check at meta-level may prevent -+ * sending. This could hurt with certain schedulers, as they -+ * to reinjection to recover from a window-stall or reduce latency. -+ * Therefore, Nagle check should be disabled in that case. -+ */ -+ if (!reinject && -+ unlikely(!tcp_nagle_test(meta_tp, skb, mss_now, -+ (tcp_skb_is_last(meta_sk, skb) ? -+ nonagle : TCP_NAGLE_PUSH)))) -+ break; -+ -+ limit = mss_now; -+ /* skb->len > mss_now is the equivalent of tso_segs > 1 in -+ * tcp_write_xmit. Otherwise split-point would return 0. -+ */ -+ if (skb->len > mss_now && !tcp_urg_mode(meta_tp)) -+ /* We limit the size of the skb so that it fits into the -+ * window. Call tcp_mss_split_point to avoid duplicating -+ * code. -+ * We really only care about fitting the skb into the -+ * window. That's why we use UINT_MAX. If the skb does -+ * not fit into the cwnd_quota or the NIC's max-segs -+ * limitation, it will be split by the subflow's -+ * tcp_write_xmit which does the appropriate call to -+ * tcp_mss_split_point. -+ */ -+ limit = tcp_mss_split_point(meta_sk, skb, mss_now, -+ UINT_MAX / mss_now, -+ nonagle); -+ -+ if (sublimit) -+ limit = min(limit, sublimit); -+ -+ if (skb->len > limit && -+ unlikely(mptcp_fragment(meta_sk, tcp_queue, -+ skb, limit, gfp, reinject))) -+ break; -+ -+ if (!mptcp_skb_entail(subsk, skb, reinject)) -+ break; -+ -+ if (reinject <= 0) -+ tcp_update_skb_after_send(meta_sk, skb, meta_tp->tcp_wstamp_ns); -+ meta_tp->lsndtime = tcp_jiffies32; -+ -+ path_mask |= mptcp_pi_to_flag(subtp->mptcp->path_index); -+ -+ if (!reinject) { -+ mptcp_check_sndseq_wrap(meta_tp, -+ TCP_SKB_CB(skb)->end_seq - -+ TCP_SKB_CB(skb)->seq); -+ tcp_event_new_data_sent(meta_sk, skb); -+ } -+ -+ tcp_minshall_update(meta_tp, mss_now, skb); -+ -+ if (reinject > 0) { -+ __skb_unlink(skb, &mpcb->reinject_queue); -+ kfree_skb(skb); -+ } -+ -+ if (push_one) -+ break; -+ } -+ -+ mptcp_for_each_sub(mpcb, mptcp) { -+ subsk = mptcp_to_sock(mptcp); -+ subtp = tcp_sk(subsk); -+ -+ if (!(path_mask & mptcp_pi_to_flag(subtp->mptcp->path_index))) -+ continue; -+ -+ mss_now = tcp_current_mss(subsk); -+ -+ /* Nagle is handled at the MPTCP-layer, so -+ * always push on the subflow -+ */ -+ __tcp_push_pending_frames(subsk, mss_now, TCP_NAGLE_PUSH); -+ } -+ -+ return !meta_tp->packets_out && tcp_send_head(meta_sk); -+} -+ -+void mptcp_write_space(struct sock *sk) -+{ -+ mptcp_push_pending_frames(mptcp_meta_sk(sk)); -+} -+ -+u32 __mptcp_select_window(struct sock *sk) -+{ -+ struct inet_connection_sock *icsk = inet_csk(sk); -+ struct tcp_sock *tp = tcp_sk(sk), *meta_tp = mptcp_meta_tp(tp); -+ struct sock *meta_sk = mptcp_meta_sk(sk); -+ int mss, free_space, full_space, window; -+ -+ /* MSS for the peer's data. Previous versions used mss_clamp -+ * here. I don't know if the value based on our guesses -+ * of peer's MSS is better for the performance. It's more correct -+ * but may be worse for the performance because of rcv_mss -+ * fluctuations. --SAW 1998/11/1 -+ */ -+ mss = icsk->icsk_ack.rcv_mss; -+ free_space = tcp_space(meta_sk); -+ full_space = min_t(int, meta_tp->window_clamp, -+ tcp_full_space(meta_sk)); -+ -+ if (mss > full_space) -+ mss = full_space; -+ -+ if (free_space < (full_space >> 1)) { -+ /* If free_space is decreasing due to mostly meta-level -+ * out-of-order packets, don't turn off the quick-ack mode. -+ */ -+ if (meta_tp->rcv_nxt - meta_tp->copied_seq > ((full_space - free_space) >> 1)) -+ icsk->icsk_ack.quick = 0; -+ -+ if (tcp_memory_pressure) -+ /* TODO this has to be adapted when we support different -+ * MSS's among the subflows. -+ */ -+ meta_tp->rcv_ssthresh = min(meta_tp->rcv_ssthresh, -+ 4U * meta_tp->advmss); -+ -+ if (free_space < mss) -+ return 0; -+ } -+ -+ if (free_space > meta_tp->rcv_ssthresh) -+ free_space = meta_tp->rcv_ssthresh; -+ -+ /* Don't do rounding if we are using window scaling, since the -+ * scaled window will not line up with the MSS boundary anyway. -+ */ -+ window = meta_tp->rcv_wnd; -+ if (tp->rx_opt.rcv_wscale) { -+ window = free_space; -+ -+ /* Advertise enough space so that it won't get scaled away. -+ * Import case: prevent zero window announcement if -+ * 1< mss. -+ */ -+ if (((window >> tp->rx_opt.rcv_wscale) << tp-> -+ rx_opt.rcv_wscale) != window) -+ window = (((window >> tp->rx_opt.rcv_wscale) + 1) -+ << tp->rx_opt.rcv_wscale); -+ } else { -+ /* Get the largest window that is a nice multiple of mss. -+ * Window clamp already applied above. -+ * If our current window offering is within 1 mss of the -+ * free space we just keep it. This prevents the divide -+ * and multiply from happening most of the time. -+ * We also don't do any window rounding when the free space -+ * is too small. -+ */ -+ if (window <= free_space - mss || window > free_space) -+ window = (free_space / mss) * mss; -+ else if (mss == full_space && -+ free_space > window + (full_space >> 1)) -+ window = free_space; -+ } -+ -+ return window; -+} -+ -+void mptcp_syn_options(const struct sock *sk, struct tcp_out_options *opts, -+ unsigned *remaining) -+{ -+ const struct tcp_sock *tp = tcp_sk(sk); -+ -+ opts->options |= OPTION_MPTCP; -+ if (is_master_tp(tp)) { -+ opts->mptcp_options |= OPTION_MP_CAPABLE | OPTION_TYPE_SYN; -+ opts->mptcp_ver = tp->mptcp_ver; -+ -+ if (tp->mptcp_ver >= MPTCP_VERSION_1) -+ *remaining -= MPTCPV1_SUB_LEN_CAPABLE_SYN_ALIGN; -+ else -+ *remaining -= MPTCP_SUB_LEN_CAPABLE_SYN_ALIGN; -+ -+ opts->mp_capable.sender_key = tp->mptcp_loc_key; -+ opts->dss_csum = !!sysctl_mptcp_checksum; -+ } else { -+ const struct mptcp_cb *mpcb = tp->mpcb; -+ -+ opts->mptcp_options |= OPTION_MP_JOIN | OPTION_TYPE_SYN; -+ *remaining -= MPTCP_SUB_LEN_JOIN_SYN_ALIGN; -+ opts->mp_join_syns.token = mpcb->mptcp_rem_token; -+ opts->mp_join_syns.low_prio = tp->mptcp->low_prio; -+ opts->addr_id = tp->mptcp->loc_id; -+ opts->mp_join_syns.sender_nonce = tp->mptcp->mptcp_loc_nonce; -+ } -+} -+ -+void mptcp_synack_options(struct request_sock *req, -+ struct tcp_out_options *opts, unsigned *remaining) -+{ -+ struct mptcp_request_sock *mtreq; -+ mtreq = mptcp_rsk(req); -+ -+ opts->options |= OPTION_MPTCP; -+ /* MPCB not yet set - thus it's a new MPTCP-session */ -+ if (!mtreq->is_sub) { -+ opts->mptcp_options |= OPTION_MP_CAPABLE | OPTION_TYPE_SYNACK; -+ opts->mptcp_ver = mtreq->mptcp_ver; -+ opts->mp_capable.sender_key = mtreq->mptcp_loc_key; -+ opts->dss_csum = !!sysctl_mptcp_checksum || mtreq->dss_csum; -+ if (mtreq->mptcp_ver >= MPTCP_VERSION_1) { -+ *remaining -= MPTCPV1_SUB_LEN_CAPABLE_SYNACK_ALIGN; -+ } else { -+ *remaining -= MPTCP_SUB_LEN_CAPABLE_SYN_ALIGN; -+ } -+ } else { -+ opts->mptcp_options |= OPTION_MP_JOIN | OPTION_TYPE_SYNACK; -+ opts->mp_join_syns.sender_truncated_mac = -+ mtreq->mptcp_hash_tmac; -+ opts->mp_join_syns.sender_nonce = mtreq->mptcp_loc_nonce; -+ opts->mp_join_syns.low_prio = mtreq->low_prio; -+ opts->addr_id = mtreq->loc_id; -+ *remaining -= MPTCP_SUB_LEN_JOIN_SYNACK_ALIGN; -+ } -+} -+ -+void mptcp_established_options(struct sock *sk, struct sk_buff *skb, -+ struct tcp_out_options *opts, unsigned *size) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct mptcp_cb *mpcb = tp->mpcb; -+ const struct tcp_skb_cb *tcb = skb ? TCP_SKB_CB(skb) : NULL; -+ -+ /* We are coming from tcp_current_mss with the meta_sk as an argument. -+ * It does not make sense to check for the options, because when the -+ * segment gets sent, another subflow will be chosen. -+ */ -+ if (!skb && is_meta_sk(sk)) -+ return; -+ -+ if (unlikely(tp->send_mp_fclose)) { -+ opts->options |= OPTION_MPTCP; -+ opts->mptcp_options |= OPTION_MP_FCLOSE; -+ opts->mp_capable.receiver_key = mpcb->mptcp_rem_key; -+ *size += MPTCP_SUB_LEN_FCLOSE_ALIGN; -+ return; -+ } -+ -+ /* 1. If we are the sender of the infinite-mapping, we need the -+ * MPTCPHDR_INF-flag, because a retransmission of the -+ * infinite-announcment still needs the mptcp-option. -+ * -+ * We need infinite_cutoff_seq, because retransmissions from before -+ * the infinite-cutoff-moment still need the MPTCP-signalling to stay -+ * consistent. -+ * -+ * 2. If we are the receiver of the infinite-mapping, we always skip -+ * mptcp-options, because acknowledgments from before the -+ * infinite-mapping point have already been sent out. -+ * -+ * I know, the whole infinite-mapping stuff is ugly... -+ * -+ * TODO: Handle wrapped data-sequence numbers -+ * (even if it's very unlikely) -+ */ -+ if (unlikely(mpcb->infinite_mapping_snd) && -+ ((mpcb->send_infinite_mapping && tcb && -+ mptcp_is_data_seq(skb) && -+ !(tcb->mptcp_flags & MPTCPHDR_INF) && -+ !before(tcb->seq, tp->mptcp->infinite_cutoff_seq)) || -+ !mpcb->send_infinite_mapping)) -+ return; -+ -+ if (unlikely(tp->mptcp->include_mpc)) { -+ opts->options |= OPTION_MPTCP; -+ opts->mptcp_options |= OPTION_MP_CAPABLE | -+ OPTION_TYPE_ACK; -+ -+ if (mpcb->mptcp_ver >= MPTCP_VERSION_1) -+ *size += MPTCPV1_SUB_LEN_CAPABLE_ACK_ALIGN; -+ else -+ *size += MPTCP_SUB_LEN_CAPABLE_ACK_ALIGN; -+ -+ opts->mptcp_ver = mpcb->mptcp_ver; -+ opts->mp_capable.sender_key = mpcb->mptcp_loc_key; -+ opts->mp_capable.receiver_key = mpcb->mptcp_rem_key; -+ opts->dss_csum = mpcb->dss_csum; -+ -+ if (skb) -+ tp->mptcp->include_mpc = 0; -+ } -+ if (unlikely(tp->mptcp->pre_established) && -+ (!skb || !(tcb->tcp_flags & (TCPHDR_FIN | TCPHDR_RST)))) { -+ opts->options |= OPTION_MPTCP; -+ opts->mptcp_options |= OPTION_MP_JOIN | OPTION_TYPE_ACK; -+ *size += MPTCP_SUB_LEN_JOIN_ACK_ALIGN; -+ } -+ -+ if (unlikely(mpcb->addr_signal) && mpcb->pm_ops->addr_signal && -+ mpcb->mptcp_ver >= MPTCP_VERSION_1 && skb && !mptcp_is_data_seq(skb)) { -+ mpcb->pm_ops->addr_signal(sk, size, opts, skb); -+ -+ if (opts->add_addr_v6) -+ /* Skip subsequent options */ -+ return; -+ } -+ -+ if (!tp->mptcp->include_mpc && !tp->mptcp->pre_established) { -+ opts->options |= OPTION_MPTCP; -+ opts->mptcp_options |= OPTION_DATA_ACK; -+ /* If !skb, we come from tcp_current_mss and thus we always -+ * assume that the DSS-option will be set for the data-packet. -+ */ -+ if (skb && !mptcp_is_data_seq(skb) && mpcb->rem_key_set) { -+ *size += MPTCP_SUB_LEN_ACK_ALIGN; -+ } else if ((skb && mptcp_is_data_mpcapable(skb)) || -+ (!skb && tp->mpcb->send_mptcpv1_mpcapable)) { -+ *size += MPTCPV1_SUB_LEN_CAPABLE_DATA_ALIGN; -+ } else { -+ /* Doesn't matter, if csum included or not. It will be -+ * either 10 or 12, and thus aligned = 12 -+ */ -+ if (mpcb->rem_key_set) -+ *size += MPTCP_SUB_LEN_ACK_ALIGN + -+ MPTCP_SUB_LEN_SEQ_ALIGN; -+ else -+ *size += MPTCP_SUB_LEN_SEQ_ALIGN; -+ } -+ -+ *size += MPTCP_SUB_LEN_DSS_ALIGN; -+ } -+ -+ /* In fallback mp_fail-mode, we have to repeat it until the fallback -+ * has been done by the sender -+ */ -+ if (unlikely(tp->mptcp->send_mp_fail) && skb && -+ MAX_TCP_OPTION_SPACE - *size >= MPTCP_SUB_LEN_FAIL) { -+ opts->options |= OPTION_MPTCP; -+ opts->mptcp_options |= OPTION_MP_FAIL; -+ *size += MPTCP_SUB_LEN_FAIL; -+ } -+ -+ if (unlikely(mpcb->addr_signal) && mpcb->pm_ops->addr_signal && -+ mpcb->mptcp_ver < MPTCP_VERSION_1) -+ mpcb->pm_ops->addr_signal(sk, size, opts, skb); -+ -+ if (unlikely(tp->mptcp->send_mp_prio) && -+ MAX_TCP_OPTION_SPACE - *size >= MPTCP_SUB_LEN_PRIO_ALIGN) { -+ opts->options |= OPTION_MPTCP; -+ opts->mptcp_options |= OPTION_MP_PRIO; -+ if (skb) -+ tp->mptcp->send_mp_prio = 0; -+ *size += MPTCP_SUB_LEN_PRIO_ALIGN; -+ } -+ -+ return; -+} -+ -+u16 mptcp_select_window(struct sock *sk) -+{ -+ u16 new_win = tcp_select_window(sk); -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct tcp_sock *meta_tp = mptcp_meta_tp(tp); -+ -+ meta_tp->rcv_wnd = tp->rcv_wnd; -+ meta_tp->rcv_wup = meta_tp->rcv_nxt; -+ -+ return new_win; -+} -+ -+void mptcp_options_write(__be32 *ptr, struct tcp_sock *tp, -+ const struct tcp_out_options *opts, -+ struct sk_buff *skb) -+{ -+ if (unlikely(OPTION_MP_CAPABLE & opts->mptcp_options)) { -+ struct mp_capable *mpc = (struct mp_capable *)ptr; -+ -+ mpc->kind = TCPOPT_MPTCP; -+ -+ if (OPTION_TYPE_SYN & opts->mptcp_options) { -+ mpc->ver = opts->mptcp_ver; -+ -+ if (mpc->ver >= MPTCP_VERSION_1) { -+ mpc->len = MPTCPV1_SUB_LEN_CAPABLE_SYN; -+ ptr += MPTCPV1_SUB_LEN_CAPABLE_SYN_ALIGN >> 2; -+ } else { -+ mpc->sender_key = opts->mp_capable.sender_key; -+ mpc->len = MPTCP_SUB_LEN_CAPABLE_SYN; -+ ptr += MPTCP_SUB_LEN_CAPABLE_SYN_ALIGN >> 2; -+ } -+ } else if (OPTION_TYPE_SYNACK & opts->mptcp_options) { -+ mpc->ver = opts->mptcp_ver; -+ -+ if (mpc->ver >= MPTCP_VERSION_1) { -+ mpc->len = MPTCPV1_SUB_LEN_CAPABLE_SYNACK; -+ ptr += MPTCPV1_SUB_LEN_CAPABLE_SYNACK_ALIGN >> 2; -+ } else { -+ mpc->len = MPTCP_SUB_LEN_CAPABLE_SYN; -+ ptr += MPTCP_SUB_LEN_CAPABLE_SYN_ALIGN >> 2; -+ } -+ -+ mpc->sender_key = opts->mp_capable.sender_key; -+ } else if (OPTION_TYPE_ACK & opts->mptcp_options) { -+ mpc->len = MPTCP_SUB_LEN_CAPABLE_ACK; -+ mpc->ver = opts->mptcp_ver; -+ ptr += MPTCP_SUB_LEN_CAPABLE_ACK_ALIGN >> 2; -+ -+ mpc->sender_key = opts->mp_capable.sender_key; -+ mpc->receiver_key = opts->mp_capable.receiver_key; -+ } -+ -+ mpc->sub = MPTCP_SUB_CAPABLE; -+ mpc->a = opts->dss_csum; -+ mpc->b = 0; -+ mpc->rsv = 0; -+ mpc->h = 1; -+ } -+ if (unlikely(OPTION_MP_JOIN & opts->mptcp_options)) { -+ struct mp_join *mpj = (struct mp_join *)ptr; -+ -+ mpj->kind = TCPOPT_MPTCP; -+ mpj->sub = MPTCP_SUB_JOIN; -+ mpj->rsv = 0; -+ -+ if (OPTION_TYPE_SYN & opts->mptcp_options) { -+ mpj->len = MPTCP_SUB_LEN_JOIN_SYN; -+ mpj->u.syn.token = opts->mp_join_syns.token; -+ mpj->u.syn.nonce = opts->mp_join_syns.sender_nonce; -+ mpj->b = opts->mp_join_syns.low_prio; -+ mpj->addr_id = opts->addr_id; -+ ptr += MPTCP_SUB_LEN_JOIN_SYN_ALIGN >> 2; -+ } else if (OPTION_TYPE_SYNACK & opts->mptcp_options) { -+ mpj->len = MPTCP_SUB_LEN_JOIN_SYNACK; -+ mpj->u.synack.mac = -+ opts->mp_join_syns.sender_truncated_mac; -+ mpj->u.synack.nonce = opts->mp_join_syns.sender_nonce; -+ mpj->b = opts->mp_join_syns.low_prio; -+ mpj->addr_id = opts->addr_id; -+ ptr += MPTCP_SUB_LEN_JOIN_SYNACK_ALIGN >> 2; -+ } else if (OPTION_TYPE_ACK & opts->mptcp_options) { -+ mpj->len = MPTCP_SUB_LEN_JOIN_ACK; -+ mpj->addr_id = 0; /* addr_id is rsv (RFC 6824, p. 21) */ -+ memcpy(mpj->u.ack.mac, &tp->mptcp->sender_mac[0], 20); -+ ptr += MPTCP_SUB_LEN_JOIN_ACK_ALIGN >> 2; -+ } -+ } -+ if (unlikely(OPTION_ADD_ADDR & opts->mptcp_options)) { -+ struct mp_add_addr *mpadd = (struct mp_add_addr *)ptr; -+ struct mptcp_cb *mpcb = tp->mpcb; -+ -+ mpadd->kind = TCPOPT_MPTCP; -+ if (opts->add_addr_v4) { -+ mpadd->addr_id = opts->add_addr4.addr_id; -+ mpadd->u.v4.addr = opts->add_addr4.addr; -+ if (mpcb->mptcp_ver < MPTCP_VERSION_1) { -+ mpadd->u_bit.v0.sub = MPTCP_SUB_ADD_ADDR; -+ mpadd->u_bit.v0.ipver = 4; -+ mpadd->len = MPTCP_SUB_LEN_ADD_ADDR4; -+ ptr += MPTCP_SUB_LEN_ADD_ADDR4_ALIGN >> 2; -+ } else { -+ mpadd->u_bit.v1.sub = MPTCP_SUB_ADD_ADDR; -+ mpadd->u_bit.v1.rsv = 0; -+ mpadd->u_bit.v1.echo = 0; -+ memcpy((char *)mpadd->u.v4.mac - 2, -+ (char *)&opts->add_addr4.trunc_mac, 8); -+ mpadd->len = MPTCP_SUB_LEN_ADD_ADDR4_VER1; -+ ptr += MPTCP_SUB_LEN_ADD_ADDR4_ALIGN_VER1 >> 2; -+ } -+ } else if (opts->add_addr_v6) { -+ mpadd->addr_id = opts->add_addr6.addr_id; -+ memcpy(&mpadd->u.v6.addr, &opts->add_addr6.addr, -+ sizeof(mpadd->u.v6.addr)); -+ if (mpcb->mptcp_ver < MPTCP_VERSION_1) { -+ mpadd->u_bit.v0.sub = MPTCP_SUB_ADD_ADDR; -+ mpadd->u_bit.v0.ipver = 6; -+ mpadd->len = MPTCP_SUB_LEN_ADD_ADDR6; -+ ptr += MPTCP_SUB_LEN_ADD_ADDR6_ALIGN >> 2; -+ } else { -+ mpadd->u_bit.v1.sub = MPTCP_SUB_ADD_ADDR; -+ mpadd->u_bit.v1.rsv = 0; -+ mpadd->u_bit.v1.echo = 0; -+ memcpy((char *)mpadd->u.v6.mac - 2, -+ (char *)&opts->add_addr6.trunc_mac, 8); -+ mpadd->len = MPTCP_SUB_LEN_ADD_ADDR6_VER1; -+ ptr += MPTCP_SUB_LEN_ADD_ADDR6_ALIGN_VER1 >> 2; -+ } -+ } -+ -+ MPTCP_INC_STATS(sock_net((struct sock *)tp), MPTCP_MIB_ADDADDRTX); -+ } -+ if (unlikely(OPTION_REMOVE_ADDR & opts->mptcp_options)) { -+ struct mp_remove_addr *mprem = (struct mp_remove_addr *)ptr; -+ u8 *addrs_id; -+ int id, len, len_align; -+ -+ len = mptcp_sub_len_remove_addr(opts->remove_addrs); -+ len_align = mptcp_sub_len_remove_addr_align(opts->remove_addrs); -+ -+ mprem->kind = TCPOPT_MPTCP; -+ mprem->len = len; -+ mprem->sub = MPTCP_SUB_REMOVE_ADDR; -+ mprem->rsv = 0; -+ addrs_id = &mprem->addrs_id; -+ -+ mptcp_for_each_bit_set(opts->remove_addrs, id) -+ *(addrs_id++) = id; -+ -+ /* Fill the rest with NOP's */ -+ if (len_align > len) { -+ int i; -+ for (i = 0; i < len_align - len; i++) -+ *(addrs_id++) = TCPOPT_NOP; -+ } -+ -+ ptr += len_align >> 2; -+ -+ MPTCP_INC_STATS(sock_net((struct sock *)tp), MPTCP_MIB_REMADDRTX); -+ } -+ if (unlikely(OPTION_MP_FAIL & opts->mptcp_options)) { -+ struct mp_fail *mpfail = (struct mp_fail *)ptr; -+ -+ mpfail->kind = TCPOPT_MPTCP; -+ mpfail->len = MPTCP_SUB_LEN_FAIL; -+ mpfail->sub = MPTCP_SUB_FAIL; -+ mpfail->rsv1 = 0; -+ mpfail->rsv2 = 0; -+ mpfail->data_seq = htonll(tp->mpcb->csum_cutoff_seq); -+ -+ ptr += MPTCP_SUB_LEN_FAIL_ALIGN >> 2; -+ } -+ if (unlikely(OPTION_MP_FCLOSE & opts->mptcp_options)) { -+ struct mp_fclose *mpfclose = (struct mp_fclose *)ptr; -+ -+ mpfclose->kind = TCPOPT_MPTCP; -+ mpfclose->len = MPTCP_SUB_LEN_FCLOSE; -+ mpfclose->sub = MPTCP_SUB_FCLOSE; -+ mpfclose->rsv1 = 0; -+ mpfclose->rsv2 = 0; -+ mpfclose->key = opts->mp_capable.receiver_key; -+ -+ ptr += MPTCP_SUB_LEN_FCLOSE_ALIGN >> 2; -+ } -+ -+ if (OPTION_DATA_ACK & opts->mptcp_options) { -+ if (!mptcp_is_data_seq(skb) && tp->mpcb->rem_key_set) -+ ptr += mptcp_write_dss_data_ack(tp, skb, ptr); -+ else if (mptcp_is_data_mpcapable(skb)) -+ ptr += mptcp_write_mpcapable_data(tp, skb, ptr); -+ else -+ ptr += mptcp_write_dss_data_seq(tp, skb, ptr); -+ } -+ if (unlikely(OPTION_MP_PRIO & opts->mptcp_options)) { -+ struct mp_prio *mpprio = (struct mp_prio *)ptr; -+ -+ mpprio->kind = TCPOPT_MPTCP; -+ mpprio->len = MPTCP_SUB_LEN_PRIO; -+ mpprio->sub = MPTCP_SUB_PRIO; -+ mpprio->rsv = 0; -+ mpprio->b = tp->mptcp->low_prio; -+ mpprio->addr_id = TCPOPT_NOP; -+ -+ ptr += MPTCP_SUB_LEN_PRIO_ALIGN >> 2; -+ } -+} -+ -+/* Sends the datafin */ -+void mptcp_send_fin(struct sock *meta_sk) -+{ -+ struct sk_buff *skb, *tskb = tcp_write_queue_tail(meta_sk); -+ struct tcp_sock *meta_tp = tcp_sk(meta_sk); -+ int mss_now; -+ -+ if ((1 << meta_sk->sk_state) & (TCPF_CLOSE_WAIT | TCPF_LAST_ACK)) -+ meta_tp->mpcb->passive_close = 1; -+ -+ /* Optimization, tack on the FIN if we have a queue of -+ * unsent frames. But be careful about outgoing SACKS -+ * and IP options. -+ */ -+ mss_now = mptcp_current_mss(meta_sk); -+ -+ if (tskb) { -+ TCP_SKB_CB(tskb)->mptcp_flags |= MPTCPHDR_FIN; -+ TCP_SKB_CB(tskb)->end_seq++; -+ meta_tp->write_seq++; -+ } else { -+ /* Socket is locked, keep trying until memory is available. */ -+ for (;;) { -+ skb = alloc_skb_fclone(MAX_TCP_HEADER, -+ meta_sk->sk_allocation); -+ if (skb) -+ break; -+ yield(); -+ } -+ /* Reserve space for headers and prepare control bits. */ -+ INIT_LIST_HEAD(&skb->tcp_tsorted_anchor); -+ skb_reserve(skb, MAX_TCP_HEADER); -+ -+ tcp_init_nondata_skb(skb, meta_tp->write_seq, TCPHDR_ACK); -+ TCP_SKB_CB(skb)->end_seq++; -+ TCP_SKB_CB(skb)->mptcp_flags |= MPTCPHDR_FIN; -+ tcp_queue_skb(meta_sk, skb); -+ } -+ __tcp_push_pending_frames(meta_sk, mss_now, TCP_NAGLE_OFF); -+} -+ -+void mptcp_send_active_reset(struct sock *meta_sk, gfp_t priority) -+{ -+ struct tcp_sock *meta_tp = tcp_sk(meta_sk); -+ struct mptcp_cb *mpcb = meta_tp->mpcb; -+ struct sock *sk; -+ -+ if (hlist_empty(&mpcb->conn_list)) -+ return; -+ -+ WARN_ON(meta_tp->send_mp_fclose); -+ -+ /* First - select a socket */ -+ sk = mptcp_select_ack_sock(meta_sk); -+ -+ /* May happen if no subflow is in an appropriate state, OR -+ * we are in infinite mode or about to go there - just send a reset -+ */ -+ if (!sk || mptcp_in_infinite_mapping_weak(mpcb)) { -+ /* tcp_done must be handled with bh disabled */ -+ if (!in_serving_softirq()) -+ local_bh_disable(); -+ -+ mptcp_sub_force_close_all(mpcb, NULL); -+ -+ if (!in_serving_softirq()) -+ local_bh_enable(); -+ return; -+ } -+ -+ tcp_mstamp_refresh(meta_tp); -+ -+ tcp_sk(sk)->send_mp_fclose = 1; -+ /** Reset all other subflows */ -+ -+ /* tcp_done must be handled with bh disabled */ -+ if (!in_serving_softirq()) -+ local_bh_disable(); -+ -+ mptcp_sub_force_close_all(mpcb, sk); -+ -+ tcp_set_state(sk, TCP_RST_WAIT); -+ -+ if (!in_serving_softirq()) -+ local_bh_enable(); -+ -+ tcp_send_ack(sk); -+ tcp_clear_xmit_timers(sk); -+ inet_csk_reset_keepalive_timer(sk, inet_csk(sk)->icsk_rto); -+ -+ meta_tp->send_mp_fclose = 1; -+ inet_csk(sk)->icsk_retransmits = 0; -+ -+ /* Prevent exp backoff reverting on ICMP dest unreachable */ -+ inet_csk(sk)->icsk_backoff = 0; -+ -+ MPTCP_INC_STATS(sock_net(meta_sk), MPTCP_MIB_FASTCLOSETX); -+} -+ -+static void mptcp_ack_retransmit_timer(struct sock *sk) -+{ -+ struct inet_connection_sock *icsk = inet_csk(sk); -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct net *net = sock_net(sk); -+ struct sk_buff *skb; -+ -+ if (inet_csk(sk)->icsk_af_ops->rebuild_header(sk)) -+ goto out; /* Routing failure or similar */ -+ -+ tcp_mstamp_refresh(tp); -+ -+ if (tcp_write_timeout(sk)) { -+ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_JOINACKRTO); -+ tp->mptcp->pre_established = 0; -+ sk_stop_timer(sk, &tp->mptcp->mptcp_ack_timer); -+ tp->ops->send_active_reset(sk, GFP_ATOMIC); -+ goto out; -+ } -+ -+ skb = alloc_skb(MAX_TCP_HEADER, GFP_ATOMIC); -+ if (skb == NULL) { -+ sk_reset_timer(sk, &tp->mptcp->mptcp_ack_timer, -+ jiffies + icsk->icsk_rto); -+ return; -+ } -+ -+ /* Reserve space for headers and prepare control bits */ -+ skb_reserve(skb, MAX_TCP_HEADER); -+ tcp_init_nondata_skb(skb, tp->snd_una, TCPHDR_ACK); -+ -+ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_JOINACKRXMIT); -+ -+ if (tcp_transmit_skb(sk, skb, 0, GFP_ATOMIC) > 0) { -+ /* Retransmission failed because of local congestion, -+ * do not backoff. -+ */ -+ if (!icsk->icsk_retransmits) -+ icsk->icsk_retransmits = 1; -+ sk_reset_timer(sk, &tp->mptcp->mptcp_ack_timer, -+ jiffies + icsk->icsk_rto); -+ return; -+ } -+ -+ if (!tp->retrans_stamp) -+ tp->retrans_stamp = tcp_time_stamp(tp) ? : 1; -+ -+ icsk->icsk_retransmits++; -+ icsk->icsk_rto = min(icsk->icsk_rto << 1, TCP_RTO_MAX); -+ sk_reset_timer(sk, &tp->mptcp->mptcp_ack_timer, -+ jiffies + icsk->icsk_rto); -+ if (retransmits_timed_out(sk, net->ipv4.sysctl_tcp_retries1 + 1, 0)) -+ __sk_dst_reset(sk); -+ -+out:; -+} -+ -+void mptcp_ack_handler(struct timer_list *t) -+{ -+ struct mptcp_tcp_sock *mptcp = from_timer(mptcp, t, mptcp_ack_timer); -+ struct sock *sk = (struct sock *)mptcp->tp; -+ struct sock *meta_sk = mptcp_meta_sk(sk); -+ -+ bh_lock_sock(meta_sk); -+ if (sock_owned_by_user(meta_sk)) { -+ /* Try again later */ -+ sk_reset_timer(sk, &tcp_sk(sk)->mptcp->mptcp_ack_timer, -+ jiffies + (HZ / 20)); -+ goto out_unlock; -+ } -+ -+ if (sk->sk_state == TCP_CLOSE) -+ goto out_unlock; -+ if (!tcp_sk(sk)->mptcp->pre_established) -+ goto out_unlock; -+ -+ mptcp_ack_retransmit_timer(sk); -+ -+ sk_mem_reclaim(sk); -+ -+out_unlock: -+ bh_unlock_sock(meta_sk); -+ sock_put(sk); -+} -+ -+/* Similar to tcp_retransmit_skb -+ * -+ * The diff is that we handle the retransmission-stats (retrans_stamp) at the -+ * meta-level. -+ */ -+int mptcp_retransmit_skb(struct sock *meta_sk, struct sk_buff *skb) -+{ -+ struct tcp_sock *meta_tp = tcp_sk(meta_sk); -+ struct sock *subsk; -+ unsigned int limit, mss_now; -+ int err = -1; -+ -+ WARN_ON(TCP_SKB_CB(skb)->sacked); -+ -+ /* Do not sent more than we queued. 1/4 is reserved for possible -+ * copying overhead: fragmentation, tunneling, mangling etc. -+ * -+ * This is a meta-retransmission thus we check on the meta-socket. -+ */ -+ if (refcount_read(&meta_sk->sk_wmem_alloc) > -+ min(meta_sk->sk_wmem_queued + (meta_sk->sk_wmem_queued >> 2), meta_sk->sk_sndbuf)) { -+ return -EAGAIN; -+ } -+ -+ /* We need to make sure that the retransmitted segment can be sent on a -+ * subflow right now. If it is too big, it needs to be fragmented. -+ */ -+ subsk = meta_tp->mpcb->sched_ops->get_subflow(meta_sk, skb, false); -+ if (!subsk) { -+ /* We want to increase icsk_retransmits, thus return 0, so that -+ * mptcp_meta_retransmit_timer enters the desired branch. -+ */ -+ err = 0; -+ goto failed; -+ } -+ mss_now = tcp_current_mss(subsk); -+ -+ /* If the segment was cloned (e.g. a meta retransmission), the header -+ * must be expanded/copied so that there is no corruption of TSO -+ * information. -+ */ -+ if (skb_unclone(skb, GFP_ATOMIC)) { -+ err = -ENOMEM; -+ goto failed; -+ } -+ -+ /* Must have been set by mptcp_write_xmit before */ -+ BUG_ON(!tcp_skb_pcount(skb)); -+ -+ limit = mss_now; -+ /* skb->len > mss_now is the equivalent of tso_segs > 1 in -+ * tcp_write_xmit. Otherwise split-point would return 0. -+ */ -+ if (skb->len > mss_now && !tcp_urg_mode(meta_tp)) -+ limit = tcp_mss_split_point(meta_sk, skb, mss_now, -+ UINT_MAX / mss_now, -+ TCP_NAGLE_OFF); -+ -+ limit = min(limit, tcp_wnd_end(meta_tp) - TCP_SKB_CB(skb)->seq); -+ -+ if (skb->len > limit && -+ unlikely(mptcp_fragment(meta_sk, TCP_FRAG_IN_RTX_QUEUE, skb, -+ limit, GFP_ATOMIC, 0))) -+ goto failed; -+ -+ if (!mptcp_skb_entail(subsk, skb, -1)) -+ goto failed; -+ -+ /* Update global TCP statistics. */ -+ MPTCP_INC_STATS(sock_net(meta_sk), MPTCP_MIB_RETRANSSEGS); -+ -+ /* Diff to tcp_retransmit_skb */ -+ -+ /* Save stamp of the first retransmit. */ -+ if (!meta_tp->retrans_stamp) { -+ tcp_mstamp_refresh(meta_tp); -+ meta_tp->retrans_stamp = tcp_time_stamp(meta_tp); -+ } -+ -+ __tcp_push_pending_frames(subsk, mss_now, TCP_NAGLE_PUSH); -+ tcp_update_skb_after_send(meta_sk, skb, meta_tp->tcp_wstamp_ns); -+ meta_tp->lsndtime = tcp_jiffies32; -+ -+ return 0; -+ -+failed: -+ __NET_INC_STATS(sock_net(meta_sk), LINUX_MIB_TCPRETRANSFAIL); -+ return err; -+} -+ -+/* Similar to tcp_retransmit_timer -+ * -+ * The diff is that we have to handle retransmissions of the FAST_CLOSE-message -+ * and that we don't have an srtt estimation at the meta-level. -+ */ -+void mptcp_meta_retransmit_timer(struct sock *meta_sk) -+{ -+ struct tcp_sock *meta_tp = tcp_sk(meta_sk); -+ struct mptcp_cb *mpcb = meta_tp->mpcb; -+ struct inet_connection_sock *meta_icsk = inet_csk(meta_sk); -+ int err; -+ -+ /* In fallback, retransmission is handled at the subflow-level */ -+ if (!meta_tp->packets_out || mpcb->infinite_mapping_snd) -+ return; -+ -+ WARN_ON(tcp_rtx_queue_empty(meta_sk)); -+ -+ if (!meta_tp->snd_wnd && !sock_flag(meta_sk, SOCK_DEAD) && -+ !((1 << meta_sk->sk_state) & (TCPF_SYN_SENT | TCPF_SYN_RECV))) { -+ /* Receiver dastardly shrinks window. Our retransmits -+ * become zero probes, but we should not timeout this -+ * connection. If the socket is an orphan, time it out, -+ * we cannot allow such beasts to hang infinitely. -+ */ -+ struct inet_sock *meta_inet = inet_sk(meta_sk); -+ if (meta_sk->sk_family == AF_INET) { -+ net_dbg_ratelimited("MPTCP: Peer %pI4:%u/%u unexpectedly shrunk window %u:%u (repaired)\n", -+ &meta_inet->inet_daddr, -+ ntohs(meta_inet->inet_dport), -+ meta_inet->inet_num, meta_tp->snd_una, -+ meta_tp->snd_nxt); -+ } -+#if IS_ENABLED(CONFIG_IPV6) -+ else if (meta_sk->sk_family == AF_INET6) { -+ net_dbg_ratelimited("MPTCP: Peer %pI6:%u/%u unexpectedly shrunk window %u:%u (repaired)\n", -+ &meta_sk->sk_v6_daddr, -+ ntohs(meta_inet->inet_dport), -+ meta_inet->inet_num, meta_tp->snd_una, -+ meta_tp->snd_nxt); -+ } -+#endif -+ if (tcp_jiffies32 - meta_tp->rcv_tstamp > TCP_RTO_MAX) { -+ tcp_write_err(meta_sk); -+ return; -+ } -+ -+ mptcp_retransmit_skb(meta_sk, tcp_rtx_queue_head(meta_sk)); -+ goto out_reset_timer; -+ } -+ -+ if (tcp_write_timeout(meta_sk)) -+ return; -+ -+ if (meta_icsk->icsk_retransmits == 0) -+ __NET_INC_STATS(sock_net(meta_sk), LINUX_MIB_TCPTIMEOUTS); -+ -+ meta_icsk->icsk_ca_state = TCP_CA_Loss; -+ -+ err = mptcp_retransmit_skb(meta_sk, tcp_rtx_queue_head(meta_sk)); -+ if (err > 0) { -+ /* Retransmission failed because of local congestion, -+ * do not backoff. -+ */ -+ if (!meta_icsk->icsk_retransmits) -+ meta_icsk->icsk_retransmits = 1; -+ inet_csk_reset_xmit_timer(meta_sk, ICSK_TIME_RETRANS, -+ min(meta_icsk->icsk_rto, TCP_RESOURCE_PROBE_INTERVAL), -+ TCP_RTO_MAX); -+ return; -+ } -+ -+ /* Increase the timeout each time we retransmit. Note that -+ * we do not increase the rtt estimate. rto is initialized -+ * from rtt, but increases here. Jacobson (SIGCOMM 88) suggests -+ * that doubling rto each time is the least we can get away with. -+ * In KA9Q, Karn uses this for the first few times, and then -+ * goes to quadratic. netBSD doubles, but only goes up to *64, -+ * and clamps at 1 to 64 sec afterwards. Note that 120 sec is -+ * defined in the protocol as the maximum possible RTT. I guess -+ * we'll have to use something other than TCP to talk to the -+ * University of Mars. -+ * -+ * PAWS allows us longer timeouts and large windows, so once -+ * implemented ftp to mars will work nicely. We will have to fix -+ * the 120 second clamps though! -+ */ -+ meta_icsk->icsk_backoff++; -+ meta_icsk->icsk_retransmits++; -+ -+out_reset_timer: -+ /* If stream is thin, use linear timeouts. Since 'icsk_backoff' is -+ * used to reset timer, set to 0. Recalculate 'icsk_rto' as this -+ * might be increased if the stream oscillates between thin and thick, -+ * thus the old value might already be too high compared to the value -+ * set by 'tcp_set_rto' in tcp_input.c which resets the rto without -+ * backoff. Limit to TCP_THIN_LINEAR_RETRIES before initiating -+ * exponential backoff behaviour to avoid continue hammering -+ * linear-timeout retransmissions into a black hole -+ */ -+ if (meta_sk->sk_state == TCP_ESTABLISHED && -+ (meta_tp->thin_lto || sock_net(meta_sk)->ipv4.sysctl_tcp_thin_linear_timeouts) && -+ tcp_stream_is_thin(meta_tp) && -+ meta_icsk->icsk_retransmits <= TCP_THIN_LINEAR_RETRIES) { -+ meta_icsk->icsk_backoff = 0; -+ /* We cannot do the same as in tcp_write_timer because the -+ * srtt is not set here. -+ */ -+ mptcp_set_rto(meta_sk); -+ } else { -+ /* Use normal (exponential) backoff */ -+ meta_icsk->icsk_rto = min(meta_icsk->icsk_rto << 1, TCP_RTO_MAX); -+ } -+ inet_csk_reset_xmit_timer(meta_sk, ICSK_TIME_RETRANS, meta_icsk->icsk_rto, TCP_RTO_MAX); -+ -+ return; -+} -+ -+void mptcp_sub_retransmit_timer(struct sock *sk) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ -+ tcp_retransmit_timer(sk); -+ -+ if (!tp->fastopen_rsk) { -+ mptcp_reinject_data(sk, 1); -+ mptcp_set_rto(sk); -+ } -+} -+ -+/* Modify values to an mptcp-level for the initial window of new subflows */ -+void mptcp_select_initial_window(const struct sock *sk, int __space, __u32 mss, -+ __u32 *rcv_wnd, __u32 *window_clamp, -+ int wscale_ok, __u8 *rcv_wscale, -+ __u32 init_rcv_wnd) -+{ -+ const struct mptcp_cb *mpcb = tcp_sk(sk)->mpcb; -+ -+ *window_clamp = mpcb->orig_window_clamp; -+ __space = tcp_win_from_space(sk, mpcb->orig_sk_rcvbuf); -+ -+ tcp_select_initial_window(sk, __space, mss, rcv_wnd, window_clamp, -+ wscale_ok, rcv_wscale, init_rcv_wnd); -+} -+ -+static inline u64 mptcp_calc_rate(const struct sock *meta_sk, unsigned int mss) -+{ -+ struct mptcp_tcp_sock *mptcp; -+ u64 rate = 0; -+ -+ mptcp_for_each_sub(tcp_sk(meta_sk)->mpcb, mptcp) { -+ struct sock *sk = mptcp_to_sock(mptcp); -+ struct tcp_sock *tp = tcp_sk(sk); -+ int this_mss; -+ u64 this_rate; -+ -+ if (!mptcp_sk_can_send(sk)) -+ continue; -+ -+ /* Do not consider subflows without a RTT estimation yet -+ * otherwise this_rate >>> rate. -+ */ -+ if (unlikely(!tp->srtt_us)) -+ continue; -+ -+ this_mss = tcp_current_mss(sk); -+ -+ /* If this_mss is smaller than mss, it means that a segment will -+ * be splitted in two (or more) when pushed on this subflow. If -+ * you consider that mss = 1428 and this_mss = 1420 then two -+ * segments will be generated: a 1420-byte and 8-byte segment. -+ * The latter will introduce a large overhead as for a single -+ * data segment 2 slots will be used in the congestion window. -+ * Therefore reducing by ~2 the potential throughput of this -+ * subflow. Indeed, 1428 will be send while 2840 could have been -+ * sent if mss == 1420 reducing the throughput by 2840 / 1428. -+ * -+ * The following algorithm take into account this overhead -+ * when computing the potential throughput that MPTCP can -+ * achieve when generating mss-byte segments. -+ * -+ * The formulae is the following: -+ * \sum_{\forall sub} ratio * \frac{mss * cwnd_sub}{rtt_sub} -+ * Where ratio is computed as follows: -+ * \frac{mss}{\ceil{mss / mss_sub} * mss_sub} -+ * -+ * ratio gives the reduction factor of the theoretical -+ * throughput a subflow can achieve if MPTCP uses a specific -+ * MSS value. -+ */ -+ this_rate = div64_u64((u64)mss * mss * (USEC_PER_SEC << 3) * -+ max(tp->snd_cwnd, tp->packets_out), -+ (u64)tp->srtt_us * -+ DIV_ROUND_UP(mss, this_mss) * this_mss); -+ rate += this_rate; -+ } -+ -+ return rate; -+} -+ -+static unsigned int __mptcp_current_mss(const struct sock *meta_sk) -+{ -+ struct mptcp_tcp_sock *mptcp; -+ unsigned int mss = 0; -+ u64 rate = 0; -+ -+ mptcp_for_each_sub(tcp_sk(meta_sk)->mpcb, mptcp) { -+ struct sock *sk = mptcp_to_sock(mptcp); -+ int this_mss; -+ u64 this_rate; -+ -+ if (!mptcp_sk_can_send(sk)) -+ continue; -+ -+ this_mss = tcp_current_mss(sk); -+ -+ /* Same mss values will produce the same throughput. */ -+ if (this_mss == mss) -+ continue; -+ -+ /* See whether using this mss value can theoretically improve -+ * the performances. -+ */ -+ this_rate = mptcp_calc_rate(meta_sk, this_mss); -+ if (this_rate >= rate) { -+ mss = this_mss; -+ rate = this_rate; -+ } -+ } -+ -+ return mss; -+} -+ -+unsigned int mptcp_current_mss(struct sock *meta_sk) -+{ -+ unsigned int mss = __mptcp_current_mss(meta_sk); -+ -+ /* If no subflow is available, we take a default-mss from the -+ * meta-socket. -+ */ -+ return !mss ? tcp_current_mss(meta_sk) : mss; -+} -+ -+int mptcp_check_snd_buf(const struct tcp_sock *tp) -+{ -+ const struct mptcp_tcp_sock *mptcp; -+ u32 rtt_max = tp->srtt_us; -+ u64 bw_est; -+ -+ if (!tp->srtt_us) -+ return tp->reordering + 1; -+ -+ mptcp_for_each_sub(tp->mpcb, mptcp) { -+ const struct sock *sk = mptcp_to_sock(mptcp); -+ -+ if (!mptcp_sk_can_send(sk)) -+ continue; -+ -+ if (rtt_max < tcp_sk(sk)->srtt_us) -+ rtt_max = tcp_sk(sk)->srtt_us; -+ } -+ -+ bw_est = div64_u64(((u64)tp->snd_cwnd * rtt_max) << 16, -+ (u64)tp->srtt_us); -+ -+ return max_t(unsigned int, (u32)(bw_est >> 16), -+ tp->reordering + 1); -+} -+ -+unsigned int mptcp_xmit_size_goal(const struct sock *meta_sk, u32 mss_now, -+ int large_allowed) -+{ -+ u32 xmit_size_goal = 0; -+ -+ if (large_allowed && !tcp_sk(meta_sk)->mpcb->dss_csum) { -+ struct mptcp_tcp_sock *mptcp; -+ -+ mptcp_for_each_sub(tcp_sk(meta_sk)->mpcb, mptcp) { -+ struct sock *sk = mptcp_to_sock(mptcp); -+ int this_size_goal; -+ -+ if (!mptcp_sk_can_send(sk)) -+ continue; -+ -+ this_size_goal = tcp_xmit_size_goal(sk, mss_now, 1); -+ if (this_size_goal > xmit_size_goal) -+ xmit_size_goal = this_size_goal; -+ } -+ } -+ -+ return max(xmit_size_goal, mss_now); -+} -+ -diff -aurN linux-5.4.64/net/mptcp/mptcp_pm.c linux-5.4.64.mptcp/net/mptcp/mptcp_pm.c ---- linux-5.4.64/net/mptcp/mptcp_pm.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-5.4.64.mptcp/net/mptcp/mptcp_pm.c 2020-09-10 19:25:10.507220869 +0200 -@@ -0,0 +1,226 @@ -+/* -+ * MPTCP implementation - MPTCP-subflow-management -+ * -+ * Initial Design & Implementation: -+ * Sébastien Barré -+ * -+ * Current Maintainer & Author: -+ * Christoph Paasch -+ * -+ * Additional authors: -+ * Jaakko Korkeaniemi -+ * Gregory Detal -+ * Fabien Duchêne -+ * Andreas Seelinger -+ * Lavkesh Lahngir -+ * Andreas Ripke -+ * Vlad Dogaru -+ * Octavian Purdila -+ * John Ronan -+ * Catalin Nicutar -+ * Brandon Heller -+ * -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version -+ * 2 of the License, or (at your option) any later version. -+ */ -+ -+ -+#include -+#include -+ -+static DEFINE_SPINLOCK(mptcp_pm_list_lock); -+static LIST_HEAD(mptcp_pm_list); -+ -+static int mptcp_default_id(const struct sock *meta_sk, sa_family_t family, -+ union inet_addr *addr, bool *low_prio) -+{ -+ return 0; -+} -+ -+struct mptcp_pm_ops mptcp_pm_default = { -+ .get_local_id = mptcp_default_id, /* We do not care */ -+ .name = "default", -+ .owner = THIS_MODULE, -+}; -+ -+static struct mptcp_pm_ops *mptcp_pm_find(const char *name) -+{ -+ struct mptcp_pm_ops *e; -+ -+ list_for_each_entry_rcu(e, &mptcp_pm_list, list) { -+ if (strcmp(e->name, name) == 0) -+ return e; -+ } -+ -+ return NULL; -+} -+ -+int mptcp_register_path_manager(struct mptcp_pm_ops *pm) -+{ -+ int ret = 0; -+ -+ if (!pm->get_local_id) -+ return -EINVAL; -+ -+ spin_lock(&mptcp_pm_list_lock); -+ if (mptcp_pm_find(pm->name)) { -+ pr_notice("%s already registered\n", pm->name); -+ ret = -EEXIST; -+ } else { -+ list_add_tail_rcu(&pm->list, &mptcp_pm_list); -+ pr_info("%s registered\n", pm->name); -+ } -+ spin_unlock(&mptcp_pm_list_lock); -+ -+ return ret; -+} -+EXPORT_SYMBOL_GPL(mptcp_register_path_manager); -+ -+void mptcp_unregister_path_manager(struct mptcp_pm_ops *pm) -+{ -+ spin_lock(&mptcp_pm_list_lock); -+ list_del_rcu(&pm->list); -+ spin_unlock(&mptcp_pm_list_lock); -+ -+ /* Wait for outstanding readers to complete before the -+ * module gets removed entirely. -+ * -+ * A try_module_get() should fail by now as our module is -+ * in "going" state since no refs are held anymore and -+ * module_exit() handler being called. -+ */ -+ synchronize_rcu(); -+} -+EXPORT_SYMBOL_GPL(mptcp_unregister_path_manager); -+ -+void mptcp_get_default_path_manager(char *name) -+{ -+ struct mptcp_pm_ops *pm; -+ -+ BUG_ON(list_empty(&mptcp_pm_list)); -+ -+ rcu_read_lock(); -+ pm = list_entry(mptcp_pm_list.next, struct mptcp_pm_ops, list); -+ strncpy(name, pm->name, MPTCP_PM_NAME_MAX); -+ rcu_read_unlock(); -+} -+ -+int mptcp_set_default_path_manager(const char *name) -+{ -+ struct mptcp_pm_ops *pm; -+ int ret = -ENOENT; -+ -+ spin_lock(&mptcp_pm_list_lock); -+ pm = mptcp_pm_find(name); -+#ifdef CONFIG_MODULES -+ if (!pm && capable(CAP_NET_ADMIN)) { -+ spin_unlock(&mptcp_pm_list_lock); -+ -+ request_module("mptcp_%s", name); -+ spin_lock(&mptcp_pm_list_lock); -+ pm = mptcp_pm_find(name); -+ } -+#endif -+ -+ if (pm) { -+ list_move(&pm->list, &mptcp_pm_list); -+ ret = 0; -+ } else { -+ pr_info("%s is not available\n", name); -+ } -+ spin_unlock(&mptcp_pm_list_lock); -+ -+ return ret; -+} -+ -+static struct mptcp_pm_ops *__mptcp_pm_find_autoload(const char *name) -+{ -+ struct mptcp_pm_ops *pm = mptcp_pm_find(name); -+#ifdef CONFIG_MODULES -+ if (!pm && capable(CAP_NET_ADMIN)) { -+ rcu_read_unlock(); -+ request_module("mptcp_%s", name); -+ rcu_read_lock(); -+ pm = mptcp_pm_find(name); -+ } -+#endif -+ return pm; -+} -+ -+void mptcp_init_path_manager(struct mptcp_cb *mpcb) -+{ -+ struct mptcp_pm_ops *pm; -+ struct sock *meta_sk = mpcb->meta_sk; -+ struct tcp_sock *meta_tp = tcp_sk(meta_sk); -+ -+ rcu_read_lock(); -+ /* if path manager was set using socket option */ -+ if (meta_tp->mptcp_pm_setsockopt) { -+ pm = __mptcp_pm_find_autoload(meta_tp->mptcp_pm_name); -+ if (pm && try_module_get(pm->owner)) { -+ mpcb->pm_ops = pm; -+ goto out; -+ } -+ } -+ -+ list_for_each_entry_rcu(pm, &mptcp_pm_list, list) { -+ if (try_module_get(pm->owner)) { -+ mpcb->pm_ops = pm; -+ break; -+ } -+ } -+out: -+ rcu_read_unlock(); -+} -+ -+/* Change path manager for socket */ -+int mptcp_set_path_manager(struct sock *sk, const char *name) -+{ -+ struct mptcp_pm_ops *pm; -+ int err = 0; -+ -+ rcu_read_lock(); -+ pm = __mptcp_pm_find_autoload(name); -+ -+ if (!pm) { -+ err = -ENOENT; -+ } else if (!ns_capable(sock_net(sk)->user_ns, CAP_NET_ADMIN)) { -+ err = -EPERM; -+ } else { -+ strcpy(tcp_sk(sk)->mptcp_pm_name, name); -+ tcp_sk(sk)->mptcp_pm_setsockopt = 1; -+ } -+ rcu_read_unlock(); -+ -+ return err; -+} -+ -+/* Manage refcounts on socket close. */ -+void mptcp_cleanup_path_manager(struct mptcp_cb *mpcb) -+{ -+ module_put(mpcb->pm_ops->owner); -+} -+ -+/* Fallback to the default path-manager. */ -+void mptcp_fallback_default(struct mptcp_cb *mpcb) -+{ -+ struct mptcp_pm_ops *pm; -+ -+ mptcp_cleanup_path_manager(mpcb); -+ pm = mptcp_pm_find("default"); -+ -+ /* Cannot fail - it's the default module */ -+ try_module_get(pm->owner); -+ mpcb->pm_ops = pm; -+} -+EXPORT_SYMBOL_GPL(mptcp_fallback_default); -+ -+/* Set default value from kernel configuration at bootup */ -+static int __init mptcp_path_manager_default(void) -+{ -+ return mptcp_set_default_path_manager(CONFIG_DEFAULT_MPTCP_PM); -+} -+late_initcall(mptcp_path_manager_default); -diff -aurN linux-5.4.64/net/mptcp/mptcp_redundant.c linux-5.4.64.mptcp/net/mptcp/mptcp_redundant.c ---- linux-5.4.64/net/mptcp/mptcp_redundant.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-5.4.64.mptcp/net/mptcp/mptcp_redundant.c 2020-09-10 19:25:10.507220869 +0200 -@@ -0,0 +1,392 @@ -+/* -+ * MPTCP Scheduler to reduce latency and jitter. -+ * -+ * This scheduler sends all packets redundantly on all available subflows. -+ * -+ * Initial Design & Implementation: -+ * Tobias Erbshaeusser -+ * Alexander Froemmgen -+ * -+ * Initial corrections & modifications: -+ * Christian Pinedo -+ * Igor Lopez -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version -+ * 2 of the License, or (at your option) any later version. -+ */ -+ -+#include -+#include -+ -+/* Struct to store the data of a single subflow */ -+struct redsched_priv { -+ /* The skb or NULL */ -+ struct sk_buff *skb; -+ /* End sequence number of the skb. This number should be checked -+ * to be valid before the skb field is used -+ */ -+ u32 skb_end_seq; -+}; -+ -+/* Struct to store the data of the control block */ -+struct redsched_cb { -+ /* The next subflow where a skb should be sent or NULL */ -+ struct tcp_sock *next_subflow; -+}; -+ -+/* Returns the socket data from a given subflow socket */ -+static struct redsched_priv *redsched_get_priv(struct tcp_sock *tp) -+{ -+ return (struct redsched_priv *)&tp->mptcp->mptcp_sched[0]; -+} -+ -+/* Returns the control block data from a given meta socket */ -+static struct redsched_cb *redsched_get_cb(struct tcp_sock *tp) -+{ -+ return (struct redsched_cb *)&tp->mpcb->mptcp_sched[0]; -+} -+ -+static bool redsched_get_active_valid_sks(struct sock *meta_sk) -+{ -+ struct tcp_sock *meta_tp = tcp_sk(meta_sk); -+ struct mptcp_cb *mpcb = meta_tp->mpcb; -+ struct mptcp_tcp_sock *mptcp; -+ int active_valid_sks = 0; -+ -+ mptcp_for_each_sub(mpcb, mptcp) { -+ struct sock *sk = mptcp_to_sock(mptcp); -+ -+ if (subflow_is_active((struct tcp_sock *)sk) && -+ !mptcp_is_def_unavailable(sk)) -+ active_valid_sks++; -+ } -+ -+ return active_valid_sks; -+} -+ -+static bool redsched_use_subflow(struct sock *meta_sk, -+ int active_valid_sks, -+ struct tcp_sock *tp, -+ struct sk_buff *skb) -+{ -+ if (!skb || !mptcp_is_available((struct sock *)tp, skb, false)) -+ return false; -+ -+ if (TCP_SKB_CB(skb)->path_mask != 0) -+ return subflow_is_active(tp); -+ -+ if (TCP_SKB_CB(skb)->path_mask == 0) { -+ if (active_valid_sks == -1) -+ active_valid_sks = redsched_get_active_valid_sks(meta_sk); -+ -+ if (subflow_is_backup(tp) && active_valid_sks > 0) -+ return false; -+ else -+ return true; -+ } -+ -+ return false; -+} -+ -+#define mptcp_entry_next_rcu(__mptcp) \ -+ hlist_entry_safe(rcu_dereference_raw(hlist_next_rcu( \ -+ &(__mptcp)->node)), struct mptcp_tcp_sock, node) -+ -+static void redsched_update_next_subflow(struct tcp_sock *tp, -+ struct redsched_cb *red_cb) -+{ -+ struct mptcp_tcp_sock *mptcp = mptcp_entry_next_rcu(tp->mptcp); -+ -+ if (mptcp) -+ red_cb->next_subflow = mptcp->tp; -+ else -+ red_cb->next_subflow = NULL; -+} -+ -+static struct sock *red_get_available_subflow(struct sock *meta_sk, -+ struct sk_buff *skb, -+ bool zero_wnd_test) -+{ -+ struct tcp_sock *meta_tp = tcp_sk(meta_sk); -+ struct mptcp_cb *mpcb = meta_tp->mpcb; -+ struct redsched_cb *red_cb = redsched_get_cb(meta_tp); -+ struct tcp_sock *first_tp = red_cb->next_subflow, *tp; -+ struct mptcp_tcp_sock *mptcp; -+ int found = 0; -+ -+ /* Answer data_fin on same subflow */ -+ if (meta_sk->sk_shutdown & RCV_SHUTDOWN && -+ skb && mptcp_is_data_fin(skb)) { -+ mptcp_for_each_sub(mpcb, mptcp) { -+ struct sock *sk = mptcp_to_sock(mptcp); -+ -+ if (tcp_sk(sk)->mptcp->path_index == -+ mpcb->dfin_path_index && -+ mptcp_is_available(sk, skb, zero_wnd_test)) -+ return sk; -+ } -+ } -+ -+ if (!first_tp && !hlist_empty(&mpcb->conn_list)) { -+ first_tp = hlist_entry_safe(rcu_dereference_raw(hlist_first_rcu(&mpcb->conn_list)), -+ struct mptcp_tcp_sock, node)->tp; -+ } -+ tp = first_tp; -+ -+ /* still NULL (no subflow in conn_list?) */ -+ if (!first_tp) -+ return NULL; -+ -+ /* Search for a subflow to send it. -+ * -+ * We want to pick a subflow that is after 'first_tp' in the list of subflows. -+ * Thus, the first mptcp_for_each_sub()-loop tries to walk the list up -+ * to the subflow 'tp' and then checks whether any one of the remaining -+ * ones is eligible to send. -+ * The second mptcp_for_each-sub()-loop is then iterating from the -+ * beginning of the list up to 'first_tp'. -+ */ -+ mptcp_for_each_sub(mpcb, mptcp) { -+ /* We go up to the subflow 'tp' and start from there */ -+ if (tp == mptcp->tp) -+ found = 1; -+ -+ if (!found) -+ continue; -+ tp = mptcp->tp; -+ -+ if (mptcp_is_available((struct sock *)tp, skb, -+ zero_wnd_test)) { -+ redsched_update_next_subflow(tp, red_cb); -+ return (struct sock *)tp; -+ } -+ } -+ -+ mptcp_for_each_sub(mpcb, mptcp) { -+ tp = mptcp->tp; -+ -+ if (tp == first_tp) -+ break; -+ -+ if (mptcp_is_available((struct sock *)tp, skb, -+ zero_wnd_test)) { -+ redsched_update_next_subflow(tp, red_cb); -+ return (struct sock *)tp; -+ } -+ } -+ -+ /* No space */ -+ return NULL; -+} -+ -+/* Corrects the stored skb pointers if they are invalid */ -+static void redsched_correct_skb_pointers(struct sock *meta_sk, -+ struct redsched_priv *red_p) -+{ -+ struct tcp_sock *meta_tp = tcp_sk(meta_sk); -+ -+ if (red_p->skb && -+ (!after(red_p->skb_end_seq, meta_tp->snd_una) || -+ after(red_p->skb_end_seq, meta_tp->snd_nxt))) -+ red_p->skb = NULL; -+} -+ -+/* Returns the next skb from the queue */ -+static struct sk_buff *redsched_next_skb_from_queue(struct sk_buff_head *queue, -+ struct sk_buff *previous, -+ struct sock *meta_sk) -+{ -+ struct sk_buff *skb; -+ -+ if (!previous) -+ return tcp_rtx_queue_head(meta_sk) ? : skb_peek(queue); -+ -+ /* sk_data->skb stores the last scheduled packet for this subflow. -+ * If sk_data->skb was scheduled but not sent (e.g., due to nagle), -+ * we have to schedule it again. -+ * -+ * For the redundant scheduler, there are two cases: -+ * 1. sk_data->skb was not sent on another subflow: -+ * we have to schedule it again to ensure that we do not -+ * skip this packet. -+ * 2. sk_data->skb was already sent on another subflow: -+ * with regard to the redundant semantic, we have to -+ * schedule it again. However, we keep it simple and ignore it, -+ * as it was already sent by another subflow. -+ * This might be changed in the future. -+ * -+ * For case 1, send_head is equal previous, as only a single -+ * packet can be skipped. -+ */ -+ if (tcp_send_head(meta_sk) == previous) -+ return tcp_send_head(meta_sk); -+ -+ skb = skb_rb_next(previous); -+ if (skb) -+ return skb; -+ -+ return tcp_send_head(meta_sk); -+} -+ -+static struct sk_buff *mptcp_red_next_segment(struct sock *meta_sk, -+ int *reinject, -+ struct sock **subsk, -+ unsigned int *limit) -+{ -+ struct tcp_sock *meta_tp = tcp_sk(meta_sk); -+ struct mptcp_cb *mpcb = meta_tp->mpcb; -+ struct redsched_cb *red_cb = redsched_get_cb(meta_tp); -+ struct tcp_sock *first_tp = red_cb->next_subflow, *tp; -+ struct mptcp_tcp_sock *mptcp; -+ int active_valid_sks = -1; -+ struct sk_buff *skb; -+ int found = 0; -+ -+ /* As we set it, we have to reset it as well. */ -+ *limit = 0; -+ -+ if (skb_queue_empty(&mpcb->reinject_queue) && -+ skb_queue_empty(&meta_sk->sk_write_queue) && -+ tcp_rtx_queue_empty(meta_sk)) -+ /* Nothing to send */ -+ return NULL; -+ -+ /* First try reinjections */ -+ skb = skb_peek(&mpcb->reinject_queue); -+ if (skb) { -+ *subsk = get_available_subflow(meta_sk, skb, false); -+ if (!*subsk) -+ return NULL; -+ *reinject = 1; -+ return skb; -+ } -+ -+ /* Then try indistinctly redundant and normal skbs */ -+ -+ if (!first_tp && !hlist_empty(&mpcb->conn_list)) { -+ first_tp = hlist_entry_safe(rcu_dereference_raw(hlist_first_rcu(&mpcb->conn_list)), -+ struct mptcp_tcp_sock, node)->tp; -+ } -+ -+ /* still NULL (no subflow in conn_list?) */ -+ if (!first_tp) -+ return NULL; -+ -+ tp = first_tp; -+ -+ *reinject = 0; -+ active_valid_sks = redsched_get_active_valid_sks(meta_sk); -+ -+ /* We want to pick a subflow that is after 'first_tp' in the list of subflows. -+ * Thus, the first mptcp_for_each_sub()-loop tries to walk the list up -+ * to the subflow 'tp' and then checks whether any one of the remaining -+ * ones can send a segment. -+ * The second mptcp_for_each-sub()-loop is then iterating from the -+ * beginning of the list up to 'first_tp'. -+ */ -+ mptcp_for_each_sub(mpcb, mptcp) { -+ struct redsched_priv *red_p; -+ -+ if (tp == mptcp->tp) -+ found = 1; -+ -+ if (!found) -+ continue; -+ -+ tp = mptcp->tp; -+ -+ /* Correct the skb pointers of the current subflow */ -+ red_p = redsched_get_priv(tp); -+ redsched_correct_skb_pointers(meta_sk, red_p); -+ -+ skb = redsched_next_skb_from_queue(&meta_sk->sk_write_queue, -+ red_p->skb, meta_sk); -+ if (skb && redsched_use_subflow(meta_sk, active_valid_sks, tp, -+ skb)) { -+ red_p->skb = skb; -+ red_p->skb_end_seq = TCP_SKB_CB(skb)->end_seq; -+ redsched_update_next_subflow(tp, red_cb); -+ *subsk = (struct sock *)tp; -+ -+ if (TCP_SKB_CB(skb)->path_mask) -+ *reinject = -1; -+ return skb; -+ } -+ } -+ -+ mptcp_for_each_sub(mpcb, mptcp) { -+ struct redsched_priv *red_p; -+ -+ tp = mptcp->tp; -+ -+ if (tp == first_tp) -+ break; -+ -+ /* Correct the skb pointers of the current subflow */ -+ red_p = redsched_get_priv(tp); -+ redsched_correct_skb_pointers(meta_sk, red_p); -+ -+ skb = redsched_next_skb_from_queue(&meta_sk->sk_write_queue, -+ red_p->skb, meta_sk); -+ if (skb && redsched_use_subflow(meta_sk, active_valid_sks, tp, -+ skb)) { -+ red_p->skb = skb; -+ red_p->skb_end_seq = TCP_SKB_CB(skb)->end_seq; -+ redsched_update_next_subflow(tp, red_cb); -+ *subsk = (struct sock *)tp; -+ -+ if (TCP_SKB_CB(skb)->path_mask) -+ *reinject = -1; -+ return skb; -+ } -+ } -+ -+ /* Nothing to send */ -+ return NULL; -+} -+ -+static void redsched_release(struct sock *sk) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct redsched_cb *red_cb = redsched_get_cb(tp); -+ -+ /* Check if the next subflow would be the released one. If yes correct -+ * the pointer -+ */ -+ if (red_cb->next_subflow == tp) -+ redsched_update_next_subflow(tp, red_cb); -+} -+ -+static struct mptcp_sched_ops mptcp_sched_red = { -+ .get_subflow = red_get_available_subflow, -+ .next_segment = mptcp_red_next_segment, -+ .release = redsched_release, -+ .name = "redundant", -+ .owner = THIS_MODULE, -+}; -+ -+static int __init red_register(void) -+{ -+ BUILD_BUG_ON(sizeof(struct redsched_priv) > MPTCP_SCHED_SIZE); -+ BUILD_BUG_ON(sizeof(struct redsched_cb) > MPTCP_SCHED_DATA_SIZE); -+ -+ if (mptcp_register_scheduler(&mptcp_sched_red)) -+ return -1; -+ -+ return 0; -+} -+ -+static void red_unregister(void) -+{ -+ mptcp_unregister_scheduler(&mptcp_sched_red); -+} -+ -+module_init(red_register); -+module_exit(red_unregister); -+ -+MODULE_AUTHOR("Tobias Erbshaeusser, Alexander Froemmgen"); -+MODULE_LICENSE("GPL"); -+MODULE_DESCRIPTION("REDUNDANT MPTCP"); -+MODULE_VERSION("0.90"); -diff -aurN linux-5.4.64/net/mptcp/mptcp_rr.c linux-5.4.64.mptcp/net/mptcp/mptcp_rr.c ---- linux-5.4.64/net/mptcp/mptcp_rr.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-5.4.64.mptcp/net/mptcp/mptcp_rr.c 2020-09-10 19:25:10.507220869 +0200 -@@ -0,0 +1,309 @@ -+/* MPTCP Scheduler module selector. Highly inspired by tcp_cong.c */ -+ -+#include -+#include -+ -+static unsigned char num_segments __read_mostly = 1; -+module_param(num_segments, byte, 0644); -+MODULE_PARM_DESC(num_segments, "The number of consecutive segments that are part of a burst"); -+ -+static bool cwnd_limited __read_mostly = 1; -+module_param(cwnd_limited, bool, 0644); -+MODULE_PARM_DESC(cwnd_limited, "if set to 1, the scheduler tries to fill the congestion-window on all subflows"); -+ -+struct rrsched_priv { -+ unsigned char quota; -+}; -+ -+static struct rrsched_priv *rrsched_get_priv(const struct tcp_sock *tp) -+{ -+ return (struct rrsched_priv *)&tp->mptcp->mptcp_sched[0]; -+} -+ -+/* If the sub-socket sk available to send the skb? */ -+static bool mptcp_rr_is_available(const struct sock *sk, const struct sk_buff *skb, -+ bool zero_wnd_test, bool cwnd_test) -+{ -+ const struct tcp_sock *tp = tcp_sk(sk); -+ unsigned int space, in_flight; -+ -+ /* Set of states for which we are allowed to send data */ -+ if (!mptcp_sk_can_send(sk)) -+ return false; -+ -+ /* We do not send data on this subflow unless it is -+ * fully established, i.e. the 4th ack has been received. -+ */ -+ if (tp->mptcp->pre_established) -+ return false; -+ -+ if (tp->pf) -+ return false; -+ -+ if (inet_csk(sk)->icsk_ca_state == TCP_CA_Loss) { -+ /* If SACK is disabled, and we got a loss, TCP does not exit -+ * the loss-state until something above high_seq has been acked. -+ * (see tcp_try_undo_recovery) -+ * -+ * high_seq is the snd_nxt at the moment of the RTO. As soon -+ * as we have an RTO, we won't push data on the subflow. -+ * Thus, snd_una can never go beyond high_seq. -+ */ -+ if (!tcp_is_reno(tp)) -+ return false; -+ else if (tp->snd_una != tp->high_seq) -+ return false; -+ } -+ -+ if (!tp->mptcp->fully_established) { -+ /* Make sure that we send in-order data */ -+ if (skb && tp->mptcp->second_packet && -+ tp->mptcp->last_end_data_seq != TCP_SKB_CB(skb)->seq) -+ return false; -+ } -+ -+ if (!cwnd_test) -+ goto zero_wnd_test; -+ -+ in_flight = tcp_packets_in_flight(tp); -+ /* Not even a single spot in the cwnd */ -+ if (in_flight >= tp->snd_cwnd) -+ return false; -+ -+ /* Now, check if what is queued in the subflow's send-queue -+ * already fills the cwnd. -+ */ -+ space = (tp->snd_cwnd - in_flight) * tp->mss_cache; -+ -+ if (tp->write_seq - tp->snd_nxt > space) -+ return false; -+ -+zero_wnd_test: -+ if (zero_wnd_test && !before(tp->write_seq, tcp_wnd_end(tp))) -+ return false; -+ -+ return true; -+} -+ -+/* Are we not allowed to reinject this skb on tp? */ -+static int mptcp_rr_dont_reinject_skb(const struct tcp_sock *tp, const struct sk_buff *skb) -+{ -+ /* If the skb has already been enqueued in this sk, try to find -+ * another one. -+ */ -+ return skb && -+ /* Has the skb already been enqueued into this subsocket? */ -+ mptcp_pi_to_flag(tp->mptcp->path_index) & TCP_SKB_CB(skb)->path_mask; -+} -+ -+/* We just look for any subflow that is available */ -+static struct sock *rr_get_available_subflow(struct sock *meta_sk, -+ struct sk_buff *skb, -+ bool zero_wnd_test) -+{ -+ const struct mptcp_cb *mpcb = tcp_sk(meta_sk)->mpcb; -+ struct sock *sk = NULL, *bestsk = NULL, *backupsk = NULL; -+ struct mptcp_tcp_sock *mptcp; -+ -+ /* Answer data_fin on same subflow!!! */ -+ if (meta_sk->sk_shutdown & RCV_SHUTDOWN && -+ skb && mptcp_is_data_fin(skb)) { -+ mptcp_for_each_sub(mpcb, mptcp) { -+ sk = mptcp_to_sock(mptcp); -+ if (tcp_sk(sk)->mptcp->path_index == mpcb->dfin_path_index && -+ mptcp_rr_is_available(sk, skb, zero_wnd_test, true)) -+ return sk; -+ } -+ } -+ -+ /* First, find the best subflow */ -+ mptcp_for_each_sub(mpcb, mptcp) { -+ struct tcp_sock *tp; -+ -+ sk = mptcp_to_sock(mptcp); -+ tp = tcp_sk(sk); -+ -+ if (!mptcp_rr_is_available(sk, skb, zero_wnd_test, true)) -+ continue; -+ -+ if (mptcp_rr_dont_reinject_skb(tp, skb)) { -+ backupsk = sk; -+ continue; -+ } -+ -+ bestsk = sk; -+ } -+ -+ if (bestsk) { -+ sk = bestsk; -+ } else if (backupsk) { -+ /* It has been sent on all subflows once - let's give it a -+ * chance again by restarting its pathmask. -+ */ -+ if (skb) -+ TCP_SKB_CB(skb)->path_mask = 0; -+ sk = backupsk; -+ } -+ -+ return sk; -+} -+ -+/* Returns the next segment to be sent from the mptcp meta-queue. -+ * (chooses the reinject queue if any segment is waiting in it, otherwise, -+ * chooses the normal write queue). -+ * Sets *@reinject to 1 if the returned segment comes from the -+ * reinject queue. Sets it to 0 if it is the regular send-head of the meta-sk, -+ * and sets it to -1 if it is a meta-level retransmission to optimize the -+ * receive-buffer. -+ */ -+static struct sk_buff *__mptcp_rr_next_segment(const struct sock *meta_sk, int *reinject) -+{ -+ const struct mptcp_cb *mpcb = tcp_sk(meta_sk)->mpcb; -+ struct sk_buff *skb = NULL; -+ -+ *reinject = 0; -+ -+ /* If we are in fallback-mode, just take from the meta-send-queue */ -+ if (mpcb->infinite_mapping_snd || mpcb->send_infinite_mapping) -+ return tcp_send_head(meta_sk); -+ -+ skb = skb_peek(&mpcb->reinject_queue); -+ -+ if (skb) -+ *reinject = 1; -+ else -+ skb = tcp_send_head(meta_sk); -+ return skb; -+} -+ -+static struct sk_buff *mptcp_rr_next_segment(struct sock *meta_sk, -+ int *reinject, -+ struct sock **subsk, -+ unsigned int *limit) -+{ -+ const struct mptcp_cb *mpcb = tcp_sk(meta_sk)->mpcb; -+ struct sock *choose_sk = NULL; -+ struct mptcp_tcp_sock *mptcp; -+ struct sk_buff *skb = __mptcp_rr_next_segment(meta_sk, reinject); -+ unsigned char split = num_segments; -+ unsigned char iter = 0, full_subs = 0; -+ -+ /* As we set it, we have to reset it as well. */ -+ *limit = 0; -+ -+ if (!skb) -+ return NULL; -+ -+ if (*reinject) { -+ *subsk = rr_get_available_subflow(meta_sk, skb, false); -+ if (!*subsk) -+ return NULL; -+ -+ return skb; -+ } -+ -+retry: -+ -+ /* First, we look for a subflow who is currently being used */ -+ mptcp_for_each_sub(mpcb, mptcp) { -+ struct sock *sk_it = mptcp_to_sock(mptcp); -+ struct tcp_sock *tp_it = tcp_sk(sk_it); -+ struct rrsched_priv *rr_p = rrsched_get_priv(tp_it); -+ -+ if (!mptcp_rr_is_available(sk_it, skb, false, cwnd_limited)) -+ continue; -+ -+ iter++; -+ -+ /* Is this subflow currently being used? */ -+ if (rr_p->quota > 0 && rr_p->quota < num_segments) { -+ split = num_segments - rr_p->quota; -+ choose_sk = sk_it; -+ goto found; -+ } -+ -+ /* Or, it's totally unused */ -+ if (!rr_p->quota) { -+ split = num_segments; -+ choose_sk = sk_it; -+ } -+ -+ /* Or, it must then be fully used */ -+ if (rr_p->quota >= num_segments) -+ full_subs++; -+ } -+ -+ /* All considered subflows have a full quota, and we considered at -+ * least one. -+ */ -+ if (iter && iter == full_subs) { -+ /* So, we restart this round by setting quota to 0 and retry -+ * to find a subflow. -+ */ -+ mptcp_for_each_sub(mpcb, mptcp) { -+ struct sock *sk_it = mptcp_to_sock(mptcp); -+ struct tcp_sock *tp_it = tcp_sk(sk_it); -+ struct rrsched_priv *rr_p = rrsched_get_priv(tp_it); -+ -+ if (!mptcp_rr_is_available(sk_it, skb, false, cwnd_limited)) -+ continue; -+ -+ rr_p->quota = 0; -+ } -+ -+ goto retry; -+ } -+ -+found: -+ if (choose_sk) { -+ unsigned int mss_now; -+ struct tcp_sock *choose_tp = tcp_sk(choose_sk); -+ struct rrsched_priv *rr_p = rrsched_get_priv(choose_tp); -+ -+ if (!mptcp_rr_is_available(choose_sk, skb, false, true)) -+ return NULL; -+ -+ *subsk = choose_sk; -+ mss_now = tcp_current_mss(*subsk); -+ *limit = split * mss_now; -+ -+ if (skb->len > mss_now) -+ rr_p->quota += DIV_ROUND_UP(skb->len, mss_now); -+ else -+ rr_p->quota++; -+ -+ return skb; -+ } -+ -+ return NULL; -+} -+ -+static struct mptcp_sched_ops mptcp_sched_rr = { -+ .get_subflow = rr_get_available_subflow, -+ .next_segment = mptcp_rr_next_segment, -+ .name = "roundrobin", -+ .owner = THIS_MODULE, -+}; -+ -+static int __init rr_register(void) -+{ -+ BUILD_BUG_ON(sizeof(struct rrsched_priv) > MPTCP_SCHED_SIZE); -+ -+ if (mptcp_register_scheduler(&mptcp_sched_rr)) -+ return -1; -+ -+ return 0; -+} -+ -+static void rr_unregister(void) -+{ -+ mptcp_unregister_scheduler(&mptcp_sched_rr); -+} -+ -+module_init(rr_register); -+module_exit(rr_unregister); -+ -+MODULE_AUTHOR("Christoph Paasch"); -+MODULE_LICENSE("GPL"); -+MODULE_DESCRIPTION("ROUNDROBIN MPTCP"); -+MODULE_VERSION("0.89"); -diff -aurN linux-5.4.64/net/mptcp/mptcp_sched.c linux-5.4.64.mptcp/net/mptcp/mptcp_sched.c ---- linux-5.4.64/net/mptcp/mptcp_sched.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-5.4.64.mptcp/net/mptcp/mptcp_sched.c 2020-09-10 19:25:10.511220802 +0200 -@@ -0,0 +1,647 @@ -+/* MPTCP Scheduler module selector. Highly inspired by tcp_cong.c */ -+ -+#include -+#include -+#include -+ -+static DEFINE_SPINLOCK(mptcp_sched_list_lock); -+static LIST_HEAD(mptcp_sched_list); -+ -+struct defsched_priv { -+ u32 last_rbuf_opti; -+}; -+ -+static struct defsched_priv *defsched_get_priv(const struct tcp_sock *tp) -+{ -+ return (struct defsched_priv *)&tp->mptcp->mptcp_sched[0]; -+} -+ -+bool mptcp_is_def_unavailable(struct sock *sk) -+{ -+ const struct tcp_sock *tp = tcp_sk(sk); -+ -+ /* Set of states for which we are allowed to send data */ -+ if (!mptcp_sk_can_send(sk)) -+ return true; -+ -+ /* We do not send data on this subflow unless it is -+ * fully established, i.e. the 4th ack has been received. -+ */ -+ if (tp->mptcp->pre_established) -+ return true; -+ -+ if (tp->pf) -+ return true; -+ -+ return false; -+} -+EXPORT_SYMBOL_GPL(mptcp_is_def_unavailable); -+ -+static bool mptcp_is_temp_unavailable(struct sock *sk, -+ const struct sk_buff *skb, -+ bool zero_wnd_test) -+{ -+ const struct tcp_sock *tp = tcp_sk(sk); -+ unsigned int mss_now, space, in_flight; -+ -+ if (inet_csk(sk)->icsk_ca_state == TCP_CA_Loss) { -+ /* If SACK is disabled, and we got a loss, TCP does not exit -+ * the loss-state until something above high_seq has been -+ * acked. (see tcp_try_undo_recovery) -+ * -+ * high_seq is the snd_nxt at the moment of the RTO. As soon -+ * as we have an RTO, we won't push data on the subflow. -+ * Thus, snd_una can never go beyond high_seq. -+ */ -+ if (!tcp_is_reno(tp)) -+ return true; -+ else if (tp->snd_una != tp->high_seq) -+ return true; -+ } -+ -+ if (!tp->mptcp->fully_established) { -+ /* Make sure that we send in-order data */ -+ if (skb && tp->mptcp->second_packet && -+ tp->mptcp->last_end_data_seq != TCP_SKB_CB(skb)->seq) -+ return true; -+ } -+ -+ in_flight = tcp_packets_in_flight(tp); -+ /* Not even a single spot in the cwnd */ -+ if (in_flight >= tp->snd_cwnd) -+ return true; -+ -+ mss_now = tcp_current_mss(sk); -+ -+ /* Now, check if what is queued in the subflow's send-queue -+ * already fills the cwnd. -+ */ -+ space = (tp->snd_cwnd - in_flight) * mss_now; -+ -+ if (tp->write_seq - tp->snd_nxt >= space) -+ return true; -+ -+ if (zero_wnd_test && !before(tp->write_seq, tcp_wnd_end(tp))) -+ return true; -+ -+ /* Don't send on this subflow if we bypass the allowed send-window at -+ * the per-subflow level. Similar to tcp_snd_wnd_test, but manually -+ * calculated end_seq (because here at this point end_seq is still at -+ * the meta-level). -+ */ -+ if (skb && zero_wnd_test && -+ after(tp->write_seq + min(skb->len, mss_now), tcp_wnd_end(tp))) -+ return true; -+ -+ return false; -+} -+ -+/* Is the sub-socket sk available to send the skb? */ -+bool mptcp_is_available(struct sock *sk, const struct sk_buff *skb, -+ bool zero_wnd_test) -+{ -+ return !mptcp_is_def_unavailable(sk) && -+ !mptcp_is_temp_unavailable(sk, skb, zero_wnd_test); -+} -+EXPORT_SYMBOL_GPL(mptcp_is_available); -+ -+/* Are we not allowed to reinject this skb on tp? */ -+static int mptcp_dont_reinject_skb(const struct tcp_sock *tp, const struct sk_buff *skb) -+{ -+ /* If the skb has already been enqueued in this sk, try to find -+ * another one. -+ */ -+ return skb && -+ /* Has the skb already been enqueued into this subsocket? */ -+ mptcp_pi_to_flag(tp->mptcp->path_index) & TCP_SKB_CB(skb)->path_mask; -+} -+ -+bool subflow_is_backup(const struct tcp_sock *tp) -+{ -+ return tp->mptcp->rcv_low_prio || tp->mptcp->low_prio; -+} -+EXPORT_SYMBOL_GPL(subflow_is_backup); -+ -+bool subflow_is_active(const struct tcp_sock *tp) -+{ -+ return !tp->mptcp->rcv_low_prio && !tp->mptcp->low_prio; -+} -+EXPORT_SYMBOL_GPL(subflow_is_active); -+ -+/* Generic function to iterate over used and unused subflows and to select the -+ * best one -+ */ -+static struct sock -+*get_subflow_from_selectors(struct mptcp_cb *mpcb, struct sk_buff *skb, -+ bool (*selector)(const struct tcp_sock *), -+ bool zero_wnd_test, bool *force) -+{ -+ struct sock *bestsk = NULL; -+ u32 min_srtt = 0xffffffff; -+ bool found_unused = false; -+ bool found_unused_una = false; -+ struct mptcp_tcp_sock *mptcp; -+ -+ mptcp_for_each_sub(mpcb, mptcp) { -+ struct sock *sk = mptcp_to_sock(mptcp); -+ struct tcp_sock *tp = tcp_sk(sk); -+ bool unused = false; -+ -+ /* First, we choose only the wanted sks */ -+ if (!(*selector)(tp)) -+ continue; -+ -+ if (!mptcp_dont_reinject_skb(tp, skb)) -+ unused = true; -+ else if (found_unused) -+ /* If a unused sk was found previously, we continue - -+ * no need to check used sks anymore. -+ */ -+ continue; -+ -+ if (mptcp_is_def_unavailable(sk)) -+ continue; -+ -+ if (mptcp_is_temp_unavailable(sk, skb, zero_wnd_test)) { -+ if (unused) -+ found_unused_una = true; -+ continue; -+ } -+ -+ if (unused) { -+ if (!found_unused) { -+ /* It's the first time we encounter an unused -+ * sk - thus we reset the bestsk (which might -+ * have been set to a used sk). -+ */ -+ min_srtt = 0xffffffff; -+ bestsk = NULL; -+ } -+ found_unused = true; -+ } -+ -+ if (tp->srtt_us < min_srtt) { -+ min_srtt = tp->srtt_us; -+ bestsk = sk; -+ } -+ } -+ -+ if (bestsk) { -+ /* The force variable is used to mark the returned sk as -+ * previously used or not-used. -+ */ -+ if (found_unused) -+ *force = true; -+ else -+ *force = false; -+ } else { -+ /* The force variable is used to mark if there are temporally -+ * unavailable not-used sks. -+ */ -+ if (found_unused_una) -+ *force = true; -+ else -+ *force = false; -+ } -+ -+ return bestsk; -+} -+ -+/* This is the scheduler. This function decides on which flow to send -+ * a given MSS. If all subflows are found to be busy, NULL is returned -+ * The flow is selected based on the shortest RTT. -+ * If all paths have full cong windows, we simply return NULL. -+ * -+ * Additionally, this function is aware of the backup-subflows. -+ */ -+struct sock *get_available_subflow(struct sock *meta_sk, struct sk_buff *skb, -+ bool zero_wnd_test) -+{ -+ struct mptcp_cb *mpcb = tcp_sk(meta_sk)->mpcb; -+ struct sock *sk; -+ bool looping = false, force; -+ -+ /* Answer data_fin on same subflow!!! */ -+ if (meta_sk->sk_shutdown & RCV_SHUTDOWN && -+ skb && mptcp_is_data_fin(skb)) { -+ struct mptcp_tcp_sock *mptcp; -+ -+ mptcp_for_each_sub(mpcb, mptcp) { -+ sk = mptcp_to_sock(mptcp); -+ -+ if (tcp_sk(sk)->mptcp->path_index == mpcb->dfin_path_index && -+ mptcp_is_available(sk, skb, zero_wnd_test)) -+ return sk; -+ } -+ } -+ -+ /* Find the best subflow */ -+restart: -+ sk = get_subflow_from_selectors(mpcb, skb, &subflow_is_active, -+ zero_wnd_test, &force); -+ if (force) -+ /* one unused active sk or one NULL sk when there is at least -+ * one temporally unavailable unused active sk -+ */ -+ return sk; -+ -+ sk = get_subflow_from_selectors(mpcb, skb, &subflow_is_backup, -+ zero_wnd_test, &force); -+ if (!force && skb) { -+ /* one used backup sk or one NULL sk where there is no one -+ * temporally unavailable unused backup sk -+ * -+ * the skb passed through all the available active and backups -+ * sks, so clean the path mask -+ */ -+ TCP_SKB_CB(skb)->path_mask = 0; -+ -+ if (!looping) { -+ looping = true; -+ goto restart; -+ } -+ } -+ return sk; -+} -+EXPORT_SYMBOL_GPL(get_available_subflow); -+ -+static struct sk_buff *mptcp_rcv_buf_optimization(struct sock *sk, int penal) -+{ -+ struct sock *meta_sk; -+ const struct tcp_sock *tp = tcp_sk(sk); -+ struct mptcp_tcp_sock *mptcp; -+ struct sk_buff *skb_head; -+ struct defsched_priv *def_p = defsched_get_priv(tp); -+ -+ meta_sk = mptcp_meta_sk(sk); -+ skb_head = tcp_rtx_queue_head(meta_sk); -+ -+ if (!skb_head) -+ return NULL; -+ -+ /* If penalization is optional (coming from mptcp_next_segment() and -+ * We are not send-buffer-limited we do not penalize. The retransmission -+ * is just an optimization to fix the idle-time due to the delay before -+ * we wake up the application. -+ */ -+ if (!penal && sk_stream_memory_free(meta_sk)) -+ goto retrans; -+ -+ /* Only penalize again after an RTT has elapsed */ -+ if (tcp_jiffies32 - def_p->last_rbuf_opti < usecs_to_jiffies(tp->srtt_us >> 3)) -+ goto retrans; -+ -+ /* Half the cwnd of the slow flows */ -+ mptcp_for_each_sub(tp->mpcb, mptcp) { -+ struct tcp_sock *tp_it = mptcp->tp; -+ -+ if (tp_it != tp && -+ TCP_SKB_CB(skb_head)->path_mask & mptcp_pi_to_flag(tp_it->mptcp->path_index)) { -+ if (tp->srtt_us < tp_it->srtt_us && inet_csk((struct sock *)tp_it)->icsk_ca_state == TCP_CA_Open) { -+ u32 prior_cwnd = tp_it->snd_cwnd; -+ -+ tp_it->snd_cwnd = max(tp_it->snd_cwnd >> 1U, 1U); -+ -+ /* If in slow start, do not reduce the ssthresh */ -+ if (prior_cwnd >= tp_it->snd_ssthresh) -+ tp_it->snd_ssthresh = max(tp_it->snd_ssthresh >> 1U, 2U); -+ -+ def_p->last_rbuf_opti = tcp_jiffies32; -+ } -+ } -+ } -+ -+retrans: -+ -+ /* Segment not yet injected into this path? Take it!!! */ -+ if (!(TCP_SKB_CB(skb_head)->path_mask & mptcp_pi_to_flag(tp->mptcp->path_index))) { -+ bool do_retrans = false; -+ mptcp_for_each_sub(tp->mpcb, mptcp) { -+ struct tcp_sock *tp_it = mptcp->tp; -+ -+ if (tp_it != tp && -+ TCP_SKB_CB(skb_head)->path_mask & mptcp_pi_to_flag(tp_it->mptcp->path_index)) { -+ if (tp_it->snd_cwnd <= 4) { -+ do_retrans = true; -+ break; -+ } -+ -+ if (4 * tp->srtt_us >= tp_it->srtt_us) { -+ do_retrans = false; -+ break; -+ } else { -+ do_retrans = true; -+ } -+ } -+ } -+ -+ if (do_retrans && mptcp_is_available(sk, skb_head, false)) { -+ trace_mptcp_retransmit(sk, skb_head); -+ return skb_head; -+ } -+ } -+ return NULL; -+} -+ -+/* Returns the next segment to be sent from the mptcp meta-queue. -+ * (chooses the reinject queue if any segment is waiting in it, otherwise, -+ * chooses the normal write queue). -+ * Sets *@reinject to 1 if the returned segment comes from the -+ * reinject queue. Sets it to 0 if it is the regular send-head of the meta-sk, -+ * and sets it to -1 if it is a meta-level retransmission to optimize the -+ * receive-buffer. -+ */ -+static struct sk_buff *__mptcp_next_segment(struct sock *meta_sk, int *reinject) -+{ -+ const struct mptcp_cb *mpcb = tcp_sk(meta_sk)->mpcb; -+ struct sk_buff *skb = NULL; -+ -+ *reinject = 0; -+ -+ /* If we are in fallback-mode, just take from the meta-send-queue */ -+ if (mpcb->infinite_mapping_snd || mpcb->send_infinite_mapping) -+ return tcp_send_head(meta_sk); -+ -+ skb = skb_peek(&mpcb->reinject_queue); -+ -+ if (skb) { -+ *reinject = 1; -+ } else { -+ skb = tcp_send_head(meta_sk); -+ -+ if (!skb && meta_sk->sk_socket && -+ test_bit(SOCK_NOSPACE, &meta_sk->sk_socket->flags) && -+ sk_stream_wspace(meta_sk) < sk_stream_min_wspace(meta_sk)) { -+ struct sock *subsk = mpcb->sched_ops->get_subflow(meta_sk, NULL, -+ false); -+ if (!subsk) -+ return NULL; -+ -+ skb = mptcp_rcv_buf_optimization(subsk, 0); -+ if (skb) -+ *reinject = -1; -+ } -+ } -+ return skb; -+} -+ -+struct sk_buff *mptcp_next_segment(struct sock *meta_sk, -+ int *reinject, -+ struct sock **subsk, -+ unsigned int *limit) -+{ -+ struct sk_buff *skb = __mptcp_next_segment(meta_sk, reinject); -+ unsigned int mss_now, in_flight_space; -+ int remaining_in_flight_space; -+ u32 max_len, max_segs, window; -+ struct tcp_sock *subtp; -+ u16 gso_max_segs; -+ -+ /* As we set it, we have to reset it as well. */ -+ *limit = 0; -+ -+ if (!skb) -+ return NULL; -+ -+ *subsk = tcp_sk(meta_sk)->mpcb->sched_ops->get_subflow(meta_sk, skb, false); -+ if (!*subsk) -+ return NULL; -+ -+ subtp = tcp_sk(*subsk); -+ mss_now = tcp_current_mss(*subsk); -+ -+ if (!*reinject && unlikely(!tcp_snd_wnd_test(tcp_sk(meta_sk), skb, mss_now))) { -+ skb = mptcp_rcv_buf_optimization(*subsk, 1); -+ if (skb) -+ *reinject = -1; -+ else -+ return NULL; -+ } -+ -+ /* No splitting required, as we will only send one single segment */ -+ if (skb->len <= mss_now) -+ return skb; -+ -+ /* The following is similar to tcp_mss_split_point, but -+ * we do not care about nagle, because we will anyways -+ * use TCP_NAGLE_PUSH, which overrides this. -+ */ -+ -+ gso_max_segs = (*subsk)->sk_gso_max_segs; -+ if (!gso_max_segs) /* No gso supported on the subflow's NIC */ -+ gso_max_segs = 1; -+ max_segs = min_t(unsigned int, tcp_cwnd_test(subtp, skb), gso_max_segs); -+ if (!max_segs) -+ return NULL; -+ -+ /* max_len is what would fit in the cwnd (respecting the 2GSO-limit of -+ * tcp_cwnd_test), but ignoring whatever was already queued. -+ */ -+ max_len = min(mss_now * max_segs, skb->len); -+ -+ in_flight_space = (subtp->snd_cwnd - tcp_packets_in_flight(subtp)) * mss_now; -+ remaining_in_flight_space = (int)in_flight_space - (subtp->write_seq - subtp->snd_nxt); -+ -+ if (remaining_in_flight_space <= 0) -+ WARN_ONCE(1, "in_flight %u cwnd %u wseq %u snxt %u mss_now %u cache %u", -+ tcp_packets_in_flight(subtp), subtp->snd_cwnd, -+ subtp->write_seq, subtp->snd_nxt, mss_now, subtp->mss_cache); -+ else -+ /* max_len now fits exactly in the write-queue, taking into -+ * account what was already queued. -+ */ -+ max_len = min_t(u32, max_len, remaining_in_flight_space); -+ -+ window = tcp_wnd_end(subtp) - subtp->write_seq; -+ -+ /* max_len now also respects the announced receive-window */ -+ max_len = min(max_len, window); -+ -+ *limit = max_len; -+ -+ return skb; -+} -+EXPORT_SYMBOL_GPL(mptcp_next_segment); -+ -+static void defsched_init(struct sock *sk) -+{ -+ struct defsched_priv *def_p = defsched_get_priv(tcp_sk(sk)); -+ -+ def_p->last_rbuf_opti = tcp_jiffies32; -+} -+ -+struct mptcp_sched_ops mptcp_sched_default = { -+ .get_subflow = get_available_subflow, -+ .next_segment = mptcp_next_segment, -+ .init = defsched_init, -+ .name = "default", -+ .owner = THIS_MODULE, -+}; -+ -+static struct mptcp_sched_ops *mptcp_sched_find(const char *name) -+{ -+ struct mptcp_sched_ops *e; -+ -+ list_for_each_entry_rcu(e, &mptcp_sched_list, list) { -+ if (strcmp(e->name, name) == 0) -+ return e; -+ } -+ -+ return NULL; -+} -+ -+int mptcp_register_scheduler(struct mptcp_sched_ops *sched) -+{ -+ int ret = 0; -+ -+ if (!sched->get_subflow || !sched->next_segment) -+ return -EINVAL; -+ -+ spin_lock(&mptcp_sched_list_lock); -+ if (mptcp_sched_find(sched->name)) { -+ pr_notice("%s already registered\n", sched->name); -+ ret = -EEXIST; -+ } else { -+ list_add_tail_rcu(&sched->list, &mptcp_sched_list); -+ pr_info("%s registered\n", sched->name); -+ } -+ spin_unlock(&mptcp_sched_list_lock); -+ -+ return ret; -+} -+EXPORT_SYMBOL_GPL(mptcp_register_scheduler); -+ -+void mptcp_unregister_scheduler(struct mptcp_sched_ops *sched) -+{ -+ spin_lock(&mptcp_sched_list_lock); -+ list_del_rcu(&sched->list); -+ spin_unlock(&mptcp_sched_list_lock); -+ -+ /* Wait for outstanding readers to complete before the -+ * module gets removed entirely. -+ * -+ * A try_module_get() should fail by now as our module is -+ * in "going" state since no refs are held anymore and -+ * module_exit() handler being called. -+ */ -+ synchronize_rcu(); -+} -+EXPORT_SYMBOL_GPL(mptcp_unregister_scheduler); -+ -+void mptcp_get_default_scheduler(char *name) -+{ -+ struct mptcp_sched_ops *sched; -+ -+ BUG_ON(list_empty(&mptcp_sched_list)); -+ -+ rcu_read_lock(); -+ sched = list_entry(mptcp_sched_list.next, struct mptcp_sched_ops, list); -+ strncpy(name, sched->name, MPTCP_SCHED_NAME_MAX); -+ rcu_read_unlock(); -+} -+ -+int mptcp_set_default_scheduler(const char *name) -+{ -+ struct mptcp_sched_ops *sched; -+ int ret = -ENOENT; -+ -+ spin_lock(&mptcp_sched_list_lock); -+ sched = mptcp_sched_find(name); -+#ifdef CONFIG_MODULES -+ if (!sched && capable(CAP_NET_ADMIN)) { -+ spin_unlock(&mptcp_sched_list_lock); -+ -+ request_module("mptcp_%s", name); -+ spin_lock(&mptcp_sched_list_lock); -+ sched = mptcp_sched_find(name); -+ } -+#endif -+ -+ if (sched) { -+ list_move(&sched->list, &mptcp_sched_list); -+ ret = 0; -+ } else { -+ pr_info("%s is not available\n", name); -+ } -+ spin_unlock(&mptcp_sched_list_lock); -+ -+ return ret; -+} -+ -+/* Must be called with rcu lock held */ -+static struct mptcp_sched_ops *__mptcp_sched_find_autoload(const char *name) -+{ -+ struct mptcp_sched_ops *sched = mptcp_sched_find(name); -+#ifdef CONFIG_MODULES -+ if (!sched && capable(CAP_NET_ADMIN)) { -+ rcu_read_unlock(); -+ request_module("mptcp_%s", name); -+ rcu_read_lock(); -+ sched = mptcp_sched_find(name); -+ } -+#endif -+ return sched; -+} -+ -+void mptcp_init_scheduler(struct mptcp_cb *mpcb) -+{ -+ struct mptcp_sched_ops *sched; -+ struct sock *meta_sk = mpcb->meta_sk; -+ struct tcp_sock *meta_tp = tcp_sk(meta_sk); -+ -+ rcu_read_lock(); -+ /* if scheduler was set using socket option */ -+ if (meta_tp->mptcp_sched_setsockopt) { -+ sched = __mptcp_sched_find_autoload(meta_tp->mptcp_sched_name); -+ if (sched && try_module_get(sched->owner)) { -+ mpcb->sched_ops = sched; -+ goto out; -+ } -+ } -+ -+ list_for_each_entry_rcu(sched, &mptcp_sched_list, list) { -+ if (try_module_get(sched->owner)) { -+ mpcb->sched_ops = sched; -+ break; -+ } -+ } -+out: -+ rcu_read_unlock(); -+} -+ -+/* Change scheduler for socket */ -+int mptcp_set_scheduler(struct sock *sk, const char *name) -+{ -+ struct mptcp_sched_ops *sched; -+ int err = 0; -+ -+ rcu_read_lock(); -+ sched = __mptcp_sched_find_autoload(name); -+ -+ if (!sched) { -+ err = -ENOENT; -+ } else if (!ns_capable(sock_net(sk)->user_ns, CAP_NET_ADMIN)) { -+ err = -EPERM; -+ } else { -+ strcpy(tcp_sk(sk)->mptcp_sched_name, name); -+ tcp_sk(sk)->mptcp_sched_setsockopt = 1; -+ } -+ rcu_read_unlock(); -+ -+ return err; -+} -+ -+/* Manage refcounts on socket close. */ -+void mptcp_cleanup_scheduler(struct mptcp_cb *mpcb) -+{ -+ module_put(mpcb->sched_ops->owner); -+} -+ -+/* Set default value from kernel configuration at bootup */ -+static int __init mptcp_scheduler_default(void) -+{ -+ BUILD_BUG_ON(sizeof(struct defsched_priv) > MPTCP_SCHED_SIZE); -+ -+ return mptcp_set_default_scheduler(CONFIG_DEFAULT_MPTCP_SCHED); -+} -+late_initcall(mptcp_scheduler_default); -diff -aurN linux-5.4.64/net/mptcp/mptcp_wvegas.c linux-5.4.64.mptcp/net/mptcp/mptcp_wvegas.c ---- linux-5.4.64/net/mptcp/mptcp_wvegas.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-5.4.64.mptcp/net/mptcp/mptcp_wvegas.c 2020-09-10 19:25:10.511220802 +0200 -@@ -0,0 +1,271 @@ -+/* -+ * MPTCP implementation - WEIGHTED VEGAS -+ * -+ * Algorithm design: -+ * Yu Cao -+ * Mingwei Xu -+ * Xiaoming Fu -+ * -+ * Implementation: -+ * Yu Cao -+ * Enhuan Dong -+ * -+ * Ported to the official MPTCP-kernel: -+ * Christoph Paasch -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version -+ * 2 of the License, or (at your option) any later version. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+static int initial_alpha = 2; -+static int total_alpha = 10; -+static int gamma = 1; -+ -+module_param(initial_alpha, int, 0644); -+MODULE_PARM_DESC(initial_alpha, "initial alpha for all subflows"); -+module_param(total_alpha, int, 0644); -+MODULE_PARM_DESC(total_alpha, "total alpha for all subflows"); -+module_param(gamma, int, 0644); -+MODULE_PARM_DESC(gamma, "limit on increase (scale by 2)"); -+ -+#define MPTCP_WVEGAS_SCALE 16 -+ -+/* wVegas variables */ -+struct wvegas { -+ u32 beg_snd_nxt; /* right edge during last RTT */ -+ u8 doing_wvegas_now;/* if true, do wvegas for this RTT */ -+ -+ u16 cnt_rtt; /* # of RTTs measured within last RTT */ -+ u32 sampled_rtt; /* cumulative RTTs measured within last RTT (in usec) */ -+ u32 base_rtt; /* the min of all wVegas RTT measurements seen (in usec) */ -+ -+ u64 instant_rate; /* cwnd / srtt_us, unit: pkts/us * 2^16 */ -+ u64 weight; /* the ratio of subflow's rate to the total rate, * 2^16 */ -+ int alpha; /* alpha for each subflows */ -+ -+ u32 queue_delay; /* queue delay*/ -+}; -+ -+ -+static inline u64 mptcp_wvegas_scale(u32 val, int scale) -+{ -+ return (u64) val << scale; -+} -+ -+static void wvegas_enable(const struct sock *sk) -+{ -+ const struct tcp_sock *tp = tcp_sk(sk); -+ struct wvegas *wvegas = inet_csk_ca(sk); -+ -+ wvegas->doing_wvegas_now = 1; -+ -+ wvegas->beg_snd_nxt = tp->snd_nxt; -+ -+ wvegas->cnt_rtt = 0; -+ wvegas->sampled_rtt = 0; -+ -+ wvegas->instant_rate = 0; -+ wvegas->alpha = initial_alpha; -+ wvegas->weight = mptcp_wvegas_scale(1, MPTCP_WVEGAS_SCALE); -+ -+ wvegas->queue_delay = 0; -+} -+ -+static inline void wvegas_disable(const struct sock *sk) -+{ -+ struct wvegas *wvegas = inet_csk_ca(sk); -+ -+ wvegas->doing_wvegas_now = 0; -+} -+ -+static void mptcp_wvegas_init(struct sock *sk) -+{ -+ struct wvegas *wvegas = inet_csk_ca(sk); -+ -+ wvegas->base_rtt = 0x7fffffff; -+ wvegas_enable(sk); -+} -+ -+static inline u64 mptcp_wvegas_rate(u32 cwnd, u32 rtt_us) -+{ -+ return div_u64(mptcp_wvegas_scale(cwnd, MPTCP_WVEGAS_SCALE), rtt_us); -+} -+ -+static void mptcp_wvegas_pkts_acked(struct sock *sk, -+ const struct ack_sample *sample) -+{ -+ struct wvegas *wvegas = inet_csk_ca(sk); -+ u32 vrtt; -+ -+ if (sample->rtt_us < 0) -+ return; -+ -+ vrtt = sample->rtt_us + 1; -+ -+ if (vrtt < wvegas->base_rtt) -+ wvegas->base_rtt = vrtt; -+ -+ wvegas->sampled_rtt += vrtt; -+ wvegas->cnt_rtt++; -+} -+ -+static void mptcp_wvegas_state(struct sock *sk, u8 ca_state) -+{ -+ if (ca_state == TCP_CA_Open) -+ wvegas_enable(sk); -+ else -+ wvegas_disable(sk); -+} -+ -+static void mptcp_wvegas_cwnd_event(struct sock *sk, enum tcp_ca_event event) -+{ -+ if (event == CA_EVENT_CWND_RESTART) { -+ mptcp_wvegas_init(sk); -+ } else if (event == CA_EVENT_LOSS) { -+ struct wvegas *wvegas = inet_csk_ca(sk); -+ wvegas->instant_rate = 0; -+ } -+} -+ -+static inline u32 mptcp_wvegas_ssthresh(const struct tcp_sock *tp) -+{ -+ return min(tp->snd_ssthresh, tp->snd_cwnd); -+} -+ -+static u64 mptcp_wvegas_weight(const struct mptcp_cb *mpcb, const struct sock *sk) -+{ -+ u64 total_rate = 0; -+ const struct wvegas *wvegas = inet_csk_ca(sk); -+ struct mptcp_tcp_sock *mptcp; -+ -+ if (!mpcb) -+ return wvegas->weight; -+ -+ -+ mptcp_for_each_sub(mpcb, mptcp) { -+ struct sock *sub_sk = mptcp_to_sock(mptcp); -+ struct wvegas *sub_wvegas = inet_csk_ca(sub_sk); -+ -+ /* sampled_rtt is initialized by 0 */ -+ if (mptcp_sk_can_send(sub_sk) && (sub_wvegas->sampled_rtt > 0)) -+ total_rate += sub_wvegas->instant_rate; -+ } -+ -+ if (total_rate && wvegas->instant_rate) -+ return div64_u64(mptcp_wvegas_scale(wvegas->instant_rate, MPTCP_WVEGAS_SCALE), total_rate); -+ else -+ return wvegas->weight; -+} -+ -+static void mptcp_wvegas_cong_avoid(struct sock *sk, u32 ack, u32 acked) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct wvegas *wvegas = inet_csk_ca(sk); -+ -+ if (!wvegas->doing_wvegas_now) { -+ tcp_reno_cong_avoid(sk, ack, acked); -+ return; -+ } -+ -+ if (after(ack, wvegas->beg_snd_nxt)) { -+ wvegas->beg_snd_nxt = tp->snd_nxt; -+ -+ if (wvegas->cnt_rtt <= 2) { -+ tcp_reno_cong_avoid(sk, ack, acked); -+ } else { -+ u32 rtt, diff, q_delay; -+ u64 target_cwnd; -+ -+ rtt = wvegas->sampled_rtt / wvegas->cnt_rtt; -+ target_cwnd = div_u64(((u64)tp->snd_cwnd * wvegas->base_rtt), rtt); -+ -+ diff = div_u64((u64)tp->snd_cwnd * (rtt - wvegas->base_rtt), rtt); -+ -+ if (diff > gamma && tcp_in_slow_start(tp)) { -+ tp->snd_cwnd = min(tp->snd_cwnd, (u32)target_cwnd+1); -+ tp->snd_ssthresh = mptcp_wvegas_ssthresh(tp); -+ -+ } else if (tcp_in_slow_start(tp)) { -+ tcp_slow_start(tp, acked); -+ } else { -+ if (diff >= wvegas->alpha) { -+ wvegas->instant_rate = mptcp_wvegas_rate(tp->snd_cwnd, rtt); -+ wvegas->weight = mptcp_wvegas_weight(tp->mpcb, sk); -+ wvegas->alpha = max(2U, (u32)((wvegas->weight * total_alpha) >> MPTCP_WVEGAS_SCALE)); -+ } -+ if (diff > wvegas->alpha) { -+ tp->snd_cwnd--; -+ tp->snd_ssthresh = mptcp_wvegas_ssthresh(tp); -+ } else if (diff < wvegas->alpha) { -+ tp->snd_cwnd++; -+ } -+ -+ /* Try to drain link queue if needed*/ -+ q_delay = rtt - wvegas->base_rtt; -+ if ((wvegas->queue_delay == 0) || (wvegas->queue_delay > q_delay)) -+ wvegas->queue_delay = q_delay; -+ -+ if (q_delay >= 2 * wvegas->queue_delay) { -+ u32 backoff_factor = div_u64(mptcp_wvegas_scale(wvegas->base_rtt, MPTCP_WVEGAS_SCALE), 2 * rtt); -+ tp->snd_cwnd = ((u64)tp->snd_cwnd * backoff_factor) >> MPTCP_WVEGAS_SCALE; -+ wvegas->queue_delay = 0; -+ } -+ } -+ -+ if (tp->snd_cwnd < 2) -+ tp->snd_cwnd = 2; -+ else if (tp->snd_cwnd > tp->snd_cwnd_clamp) -+ tp->snd_cwnd = tp->snd_cwnd_clamp; -+ -+ tp->snd_ssthresh = tcp_current_ssthresh(sk); -+ } -+ -+ wvegas->cnt_rtt = 0; -+ wvegas->sampled_rtt = 0; -+ } -+ /* Use normal slow start */ -+ else if (tcp_in_slow_start(tp)) -+ tcp_slow_start(tp, acked); -+} -+ -+ -+static struct tcp_congestion_ops mptcp_wvegas __read_mostly = { -+ .init = mptcp_wvegas_init, -+ .ssthresh = tcp_reno_ssthresh, -+ .cong_avoid = mptcp_wvegas_cong_avoid, -+ .undo_cwnd = tcp_reno_undo_cwnd, -+ .pkts_acked = mptcp_wvegas_pkts_acked, -+ .set_state = mptcp_wvegas_state, -+ .cwnd_event = mptcp_wvegas_cwnd_event, -+ -+ .owner = THIS_MODULE, -+ .name = "wvegas", -+}; -+ -+static int __init mptcp_wvegas_register(void) -+{ -+ BUILD_BUG_ON(sizeof(struct wvegas) > ICSK_CA_PRIV_SIZE); -+ tcp_register_congestion_control(&mptcp_wvegas); -+ return 0; -+} -+ -+static void __exit mptcp_wvegas_unregister(void) -+{ -+ tcp_unregister_congestion_control(&mptcp_wvegas); -+} -+ -+module_init(mptcp_wvegas_register); -+module_exit(mptcp_wvegas_unregister); -+ -+MODULE_AUTHOR("Yu Cao, Enhuan Dong"); -+MODULE_LICENSE("GPL"); -+MODULE_DESCRIPTION("MPTCP wVegas"); -+MODULE_VERSION("0.1"); -diff -aurN linux-5.4.64/net/socket.c linux-5.4.64.mptcp/net/socket.c ---- linux-5.4.64/net/socket.c 2020-09-09 19:12:37.000000000 +0200 -+++ linux-5.4.64.mptcp/net/socket.c 2020-09-10 19:25:10.511220802 +0200 -@@ -91,6 +91,7 @@ - #include - - #include -+#include - #include - #include - -@@ -1350,6 +1351,7 @@ - int err; - struct socket *sock; - const struct net_proto_family *pf; -+ int old_protocol = protocol; - - /* - * Check protocol is in range -@@ -1370,6 +1372,9 @@ - family = PF_PACKET; - } - -+ if (old_protocol == IPPROTO_MPTCP) -+ protocol = IPPROTO_TCP; -+ - err = security_socket_create(family, type, protocol, kern); - if (err) - return err; -@@ -1419,6 +1424,10 @@ - if (err < 0) - goto out_module_put; - -+ if (sysctl_mptcp_enabled && old_protocol == IPPROTO_MPTCP && -+ type == SOCK_STREAM && (family == AF_INET || family == AF_INET6)) -+ mptcp_enable_sock(sock->sk); -+ - /* - * Now to bump the refcnt of the [loadable] module that owns this - * socket at sock_release time we decrement its refcnt. -diff -aurN linux-5.4.64/tools/include/uapi/linux/bpf.h linux-5.4.64.mptcp/tools/include/uapi/linux/bpf.h ---- linux-5.4.64/tools/include/uapi/linux/bpf.h 2020-09-09 19:12:37.000000000 +0200 -+++ linux-5.4.64.mptcp/tools/include/uapi/linux/bpf.h 2020-09-10 19:25:10.511220802 +0200 -@@ -3438,6 +3438,7 @@ - BPF_TCP_LISTEN, - BPF_TCP_CLOSING, /* Now a valid state */ - BPF_TCP_NEW_SYN_RECV, -+ BPF_TCP_RST_WAIT, - - BPF_TCP_MAX_STATES /* Leave at the end! */ - }; diff --git a/root/target/linux/generic/hack-5.4/692-tcp_nanqinlang.patch b/root/target/linux/generic/hack-5.4/692-tcp_nanqinlang.patch deleted file mode 100644 index 56051ae7..00000000 --- a/root/target/linux/generic/hack-5.4/692-tcp_nanqinlang.patch +++ /dev/null @@ -1,1037 +0,0 @@ ---- a/net/ipv4/Makefile.anc 2019-11-23 23:01:47.069966970 +0100 -+++ b/net/ipv4/Makefile 2019-11-23 23:03:01.416428035 +0100 -@@ -48,6 +48,7 @@ - obj-$(CONFIG_INET_UDP_DIAG) += udp_diag.o - obj-$(CONFIG_INET_RAW_DIAG) += raw_diag.o - obj-$(CONFIG_TCP_CONG_BBR) += tcp_bbr.o -+obj-$(CONFIG_TCP_CONG_NANQINLANG) += tcp_nanqinlang.o - obj-$(CONFIG_TCP_CONG_BIC) += tcp_bic.o - obj-$(CONFIG_TCP_CONG_CDG) += tcp_cdg.o - obj-$(CONFIG_TCP_CONG_CUBIC) += tcp_cubic.o ---- a/net/ipv4/Kconfig.anc 2019-11-23 23:01:52.649851417 +0100 -+++ b/net/ipv4/Kconfig 2019-11-23 23:04:21.974762180 +0100 -@@ -681,6 +681,21 @@ - bufferbloat, policers, or AQM schemes that do not provide a delay - signal. It requires the fq ("Fair Queue") pacing packet scheduler. - -+config TCP_CONG_NANQINLANG -+ tristate "NANGINLANG TCP" -+ default n -+ ---help--- -+ -+ BBR (Bottleneck Bandwidth and RTT) TCP congestion control aims to -+ maximize network utilization and minimize queues. It builds an explicit -+ model of the the bottleneck delivery rate and path round-trip -+ propagation delay. It tolerates packet loss and delay unrelated to -+ congestion. It can operate over LAN, WAN, cellular, wifi, or cable -+ modem links. It can coexist with flows that use loss-based congestion -+ control, and can operate with shallow buffers, deep buffers, -+ bufferbloat, policers, or AQM schemes that do not provide a delay -+ signal. It requires the fq ("Fair Queue") pacing packet scheduler. -+ - config TCP_CONG_LIA - tristate "MPTCP Linked Increase" - depends on MPTCP -@@ -763,6 +778,9 @@ - config DEFAULT_BBR - bool "BBR" if TCP_CONG_BBR=y - -+ config DEFAULT_NANQINLANG -+ bool "BBR" if TCP_CONG_NANQINLANG=y -+ - config DEFAULT_LIA - bool "Lia" if TCP_CONG_LIA=y - -@@ -806,6 +824,7 @@ - default "dctcp" if DEFAULT_DCTCP - default "cdg" if DEFAULT_CDG - default "bbr" if DEFAULT_BBR -+ default "nanqinlang" if DEFAULT_NANQINLANG - default "cubic" - - config TCP_MD5SIG ---- /dev/null 2019-11-25 21:13:36.728349757 +0100 -+++ b/net/ipv4/tcp_nanqinlang.c 2019-11-25 21:10:00.392068414 +0100 -@@ -0,0 +1,982 @@ -+/* Bottleneck Bandwidth and RTT (BBR) congestion control -+ * -+ * BBR congestion control computes the sending rate based on the delivery -+ * rate (throughput) estimated from ACKs. In a nutshell: -+ * -+ * On each ACK, update our model of the network path: -+ * bottleneck_bandwidth = windowed_max(delivered / elapsed, 10 round trips) -+ * min_rtt = windowed_min(rtt, 10 seconds) -+ * pacing_rate = pacing_gain * bottleneck_bandwidth -+ * cwnd = max(cwnd_gain * bottleneck_bandwidth * min_rtt, 4) -+ * -+ * The core algorithm does not react directly to packet losses or delays, -+ * although BBR may adjust the size of next send per ACK when loss is -+ * observed, or adjust the sending rate if it estimates there is a -+ * traffic policer, in order to keep the drop rate reasonable. -+ * -+ * Here is a state transition diagram for BBR: -+ * -+ * | -+ * V -+ * +---> STARTUP ----+ -+ * | | | -+ * | V | -+ * | DRAIN ----+ -+ * | | | -+ * | V | -+ * +---> PROBE_BW ----+ -+ * | ^ | | -+ * | | | | -+ * | +----+ | -+ * | | -+ * +---- PROBE_RTT <--+ -+ * -+ * A BBR flow starts in STARTUP, and ramps up its sending rate quickly. -+ * When it estimates the pipe is full, it enters DRAIN to drain the queue. -+ * In steady state a BBR flow only uses PROBE_BW and PROBE_RTT. -+ * A long-lived BBR flow spends the vast majority of its time remaining -+ * (repeatedly) in PROBE_BW, fully probing and utilizing the pipe's bandwidth -+ * in a fair manner, with a small, bounded queue. *If* a flow has been -+ * continuously sending for the entire min_rtt window, and hasn't seen an RTT -+ * sample that matches or decreases its min_rtt estimate for 10 seconds, then -+ * it briefly enters PROBE_RTT to cut inflight to a minimum value to re-probe -+ * the path's two-way propagation delay (min_rtt). When exiting PROBE_RTT, if -+ * we estimated that we reached the full bw of the pipe then we enter PROBE_BW; -+ * otherwise we enter STARTUP to try to fill the pipe. -+ * -+ * BBR is described in detail in: -+ * "BBR: Congestion-Based Congestion Control", -+ * Neal Cardwell, Yuchung Cheng, C. Stephen Gunn, Soheil Hassas Yeganeh, -+ * Van Jacobson. ACM Queue, Vol. 14 No. 5, September-October 2016. -+ * -+ * There is a public e-mail list for discussing BBR development and testing: -+ * https://groups.google.com/forum/#!forum/bbr-dev -+ * -+ * NOTE: BBR might be used with the fq qdisc ("man tc-fq") with pacing enabled, -+ * otherwise TCP stack falls back to an internal pacing using one high -+ * resolution timer per TCP socket and may use more resources. -+ */ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+/* Scale factor for rate in pkt/uSec unit to avoid truncation in bandwidth -+ * estimation. The rate unit ~= (1500 bytes / 1 usec / 2^24) ~= 715 bps. -+ * This handles bandwidths from 0.06pps (715bps) to 256Mpps (3Tbps) in a u32. -+ * Since the minimum window is >=4 packets, the lower bound isn't -+ * an issue. The upper bound isn't an issue with existing technologies. -+ */ -+#define BW_SCALE 24 -+#define BW_UNIT (1 << BW_SCALE) -+ -+#define BBR_SCALE 8 /* scaling factor for fractions in BBR (e.g. gains) */ -+#define BBR_UNIT (1 << BBR_SCALE) -+ -+/* BBR has the following modes for deciding how fast to send: */ -+enum bbr_mode { -+ BBR_STARTUP, /* ramp up sending rate rapidly to fill pipe */ -+ BBR_DRAIN, /* drain any queue created during startup */ -+ BBR_PROBE_BW, /* discover, share bw: pace around estimated bw */ -+ BBR_PROBE_RTT, /* cut inflight to min to probe min_rtt */ -+}; -+ -+/* BBR congestion control block */ -+struct bbr { -+ u32 min_rtt_us; /* min RTT in min_rtt_win_sec window */ -+ u32 min_rtt_stamp; /* timestamp of min_rtt_us */ -+ u32 probe_rtt_done_stamp; /* end time for BBR_PROBE_RTT mode */ -+ struct minmax bw; /* Max recent delivery rate in pkts/uS << 24 */ -+ u32 rtt_cnt; /* count of packet-timed rounds elapsed */ -+ u32 next_rtt_delivered; /* scb->tx.delivered at end of round */ -+ u64 cycle_mstamp; /* time of this cycle phase start */ -+ u32 mode:3, /* current bbr_mode in state machine */ -+ prev_ca_state:3, /* CA state on previous ACK */ -+ packet_conservation:1, /* use packet conservation? */ -+ round_start:1, /* start of packet-timed tx->ack round? */ -+ idle_restart:1, /* restarting after idle? */ -+ probe_rtt_round_done:1, /* a BBR_PROBE_RTT round at 4 pkts? */ -+ unused:13, -+ lt_is_sampling:1, /* taking long-term ("LT") samples now? */ -+ lt_rtt_cnt:7, /* round trips in long-term interval */ -+ lt_use_bw:1; /* use lt_bw as our bw estimate? */ -+ u32 lt_bw; /* LT est delivery rate in pkts/uS << 24 */ -+ u32 lt_last_delivered; /* LT intvl start: tp->delivered */ -+ u32 lt_last_stamp; /* LT intvl start: tp->delivered_mstamp */ -+ u32 lt_last_lost; /* LT intvl start: tp->lost */ -+ u32 pacing_gain:10, /* current gain for setting pacing rate */ -+ cwnd_gain:10, /* current gain for setting cwnd */ -+ full_bw_reached:1, /* reached full bw in Startup? */ -+ full_bw_cnt:2, /* number of rounds without large bw gains */ -+ cycle_idx:3, /* current index in pacing_gain cycle array */ -+ has_seen_rtt:1, /* have we seen an RTT sample yet? */ -+ unused_b:5; -+ u32 prior_cwnd; /* prior cwnd upon entering loss recovery */ -+ u32 full_bw; /* recent bw, to estimate if pipe is full */ -+}; -+ -+#define CYCLE_LEN 8 /* number of phases in a pacing gain cycle */ -+ -+/* Window length of bw filter (in rounds): */ -+static const int bbr_bw_rtts = CYCLE_LEN + 2; -+/* Window length of min_rtt filter (in sec): */ -+static const u32 bbr_min_rtt_win_sec = 10; -+/* Minimum time (in ms) spent at bbr_cwnd_min_target in BBR_PROBE_RTT mode: */ -+static const u32 bbr_probe_rtt_mode_ms = 100; -+/* Skip TSO below the following bandwidth (bits/sec): */ -+static const int bbr_min_tso_rate = 1200000; -+ -+/* We use a high_gain value of 2/ln(2) because it's the smallest pacing gain -+ * that will allow a smoothly increasing pacing rate that will double each RTT -+ * and send the same number of packets per RTT that an un-paced, slow-starting -+ * Reno or CUBIC flow would: -+ */ -+static const int bbr_high_gain = BBR_UNIT * 3000 / 1000 + 1; -+/* The pacing gain of 1/high_gain in BBR_DRAIN is calculated to typically drain -+ * the queue created in BBR_STARTUP in a single round: -+ */ -+static const int bbr_drain_gain = BBR_UNIT * 1000 / 3000; -+/* The gain for deriving steady-state cwnd tolerates delayed/stretched ACKs: */ -+static const int bbr_cwnd_gain = BBR_UNIT * 2; -+/* The pacing_gain values for the PROBE_BW gain cycle, to discover/share bw: */ -+static const int bbr_pacing_gain[] = { -+ BBR_UNIT * 6 / 4, /* probe for more available bw */ -+ BBR_UNIT * 3 / 4, /* drain queue and/or yield bw to other flows */ -+ BBR_UNIT * 5 / 4, BBR_UNIT * 5 / 4, BBR_UNIT * 5 / 4, /* cruise at 1.0*bw to utilize pipe, */ -+ BBR_UNIT * 6 / 4, BBR_UNIT * 6 / 4, BBR_UNIT * 6 / 4 /* without creating excess queue... */ -+}; -+/* Randomize the starting gain cycling phase over N phases: */ -+static const u32 bbr_cycle_rand = 7; -+ -+/* Try to keep at least this many packets in flight, if things go smoothly. For -+ * smooth functioning, a sliding window protocol ACKing every other packet -+ * needs at least 4 packets in flight: -+ */ -+static const u32 bbr_cwnd_min_target = 4; -+ -+/* To estimate if BBR_STARTUP mode (i.e. high_gain) has filled pipe... */ -+/* If bw has increased significantly (1.25x), there may be more bw available: */ -+static const u32 bbr_full_bw_thresh = BBR_UNIT * 5 / 4; -+/* But after 3 rounds w/o significant bw growth, estimate pipe is full: */ -+static const u32 bbr_full_bw_cnt = 3; -+ -+/* "long-term" ("LT") bandwidth estimator parameters... */ -+/* The minimum number of rounds in an LT bw sampling interval: */ -+static const u32 bbr_lt_intvl_min_rtts = 4; -+/* If lost/delivered ratio > 20%, interval is "lossy" and we may be policed: */ -+static const u32 bbr_lt_loss_thresh = 50; -+/* If 2 intervals have a bw ratio <= 1/8, their bw is "consistent": */ -+static const u32 bbr_lt_bw_ratio = BBR_UNIT / 4; -+/* If 2 intervals have a bw diff <= 4 Kbit/sec their bw is "consistent": */ -+static const u32 bbr_lt_bw_diff = 4000 / 8; -+/* If we estimate we're policed, use lt_bw for this many round trips: */ -+static const u32 bbr_lt_bw_max_rtts = 48; -+ -+static void bbr_check_probe_rtt_done(struct sock *sk); -+ -+/* Do we estimate that STARTUP filled the pipe? */ -+static bool bbr_full_bw_reached(const struct sock *sk) -+{ -+ const struct bbr *bbr = inet_csk_ca(sk); -+ -+ return bbr->full_bw_reached; -+} -+ -+/* Return the windowed max recent bandwidth sample, in pkts/uS << BW_SCALE. */ -+static u32 bbr_max_bw(const struct sock *sk) -+{ -+ struct bbr *bbr = inet_csk_ca(sk); -+ -+ return minmax_get(&bbr->bw); -+} -+ -+/* Return the estimated bandwidth of the path, in pkts/uS << BW_SCALE. */ -+static u32 bbr_bw(const struct sock *sk) -+{ -+ struct bbr *bbr = inet_csk_ca(sk); -+ -+ return bbr->lt_use_bw ? bbr->lt_bw : bbr_max_bw(sk); -+} -+ -+/* Return rate in bytes per second, optionally with a gain. -+ * The order here is chosen carefully to avoid overflow of u64. This should -+ * work for input rates of up to 2.9Tbit/sec and gain of 2.89x. -+ */ -+static u64 bbr_rate_bytes_per_sec(struct sock *sk, u64 rate, int gain) -+{ -+ unsigned int mss = tcp_sk(sk)->mss_cache; -+ -+ if (!tcp_needs_internal_pacing(sk)) -+ mss = tcp_mss_to_mtu(sk, mss); -+ rate *= mss; -+ rate *= gain; -+ rate >>= BBR_SCALE; -+ rate *= USEC_PER_SEC; -+ return rate >> BW_SCALE; -+} -+ -+/* Convert a BBR bw and gain factor to a pacing rate in bytes per second. */ -+static u32 bbr_bw_to_pacing_rate(struct sock *sk, u32 bw, int gain) -+{ -+ u64 rate = bw; -+ -+ rate = bbr_rate_bytes_per_sec(sk, rate, gain); -+ rate = min_t(u64, rate, sk->sk_max_pacing_rate); -+ return rate; -+} -+ -+/* Initialize pacing rate to: high_gain * init_cwnd / RTT. */ -+static void bbr_init_pacing_rate_from_rtt(struct sock *sk) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct bbr *bbr = inet_csk_ca(sk); -+ u64 bw; -+ u32 rtt_us; -+ -+ if (tp->srtt_us) { /* any RTT sample yet? */ -+ rtt_us = max(tp->srtt_us >> 3, 1U); -+ bbr->has_seen_rtt = 1; -+ } else { /* no RTT sample yet */ -+ rtt_us = USEC_PER_MSEC; /* use nominal default RTT */ -+ } -+ bw = (u64)tp->snd_cwnd * BW_UNIT; -+ do_div(bw, rtt_us); -+ sk->sk_pacing_rate = bbr_bw_to_pacing_rate(sk, bw, bbr_high_gain); -+} -+ -+/* Pace using current bw estimate and a gain factor. In order to help drive the -+ * network toward lower queues while maintaining high utilization and low -+ * latency, the average pacing rate aims to be slightly (~1%) lower than the -+ * estimated bandwidth. This is an important aspect of the design. In this -+ * implementation this slightly lower pacing rate is achieved implicitly by not -+ * including link-layer headers in the packet size used for the pacing rate. -+ */ -+static void bbr_set_pacing_rate(struct sock *sk, u32 bw, int gain) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct bbr *bbr = inet_csk_ca(sk); -+ u32 rate = bbr_bw_to_pacing_rate(sk, bw, gain); -+ -+ if (unlikely(!bbr->has_seen_rtt && tp->srtt_us)) -+ bbr_init_pacing_rate_from_rtt(sk); -+ if (bbr_full_bw_reached(sk) || rate > sk->sk_pacing_rate) -+ sk->sk_pacing_rate = rate; -+} -+ -+/* override sysctl_tcp_min_tso_segs */ -+static u32 bbr_min_tso_segs(struct sock *sk) -+{ -+ return sk->sk_pacing_rate < (bbr_min_tso_rate >> 3) ? 1 : 2; -+} -+ -+static u32 bbr_tso_segs_goal(struct sock *sk) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ u32 segs, bytes; -+ -+ /* Sort of tcp_tso_autosize() but ignoring -+ * driver provided sk_gso_max_size. -+ */ -+ bytes = min_t(u32, sk->sk_pacing_rate >> sk->sk_pacing_shift, -+ GSO_MAX_SIZE - 1 - MAX_TCP_HEADER); -+ segs = max_t(u32, bytes / tp->mss_cache, bbr_min_tso_segs(sk)); -+ -+ return min(segs, 0x7FU); -+} -+ -+/* Save "last known good" cwnd so we can restore it after losses or PROBE_RTT */ -+static void bbr_save_cwnd(struct sock *sk) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct bbr *bbr = inet_csk_ca(sk); -+ -+ if (bbr->prev_ca_state < TCP_CA_Recovery && bbr->mode != BBR_PROBE_RTT) -+ bbr->prior_cwnd = tp->snd_cwnd; /* this cwnd is good enough */ -+ else /* loss recovery or BBR_PROBE_RTT have temporarily cut cwnd */ -+ bbr->prior_cwnd = max(bbr->prior_cwnd, tp->snd_cwnd); -+} -+ -+static void bbr_cwnd_event(struct sock *sk, enum tcp_ca_event event) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct bbr *bbr = inet_csk_ca(sk); -+ -+ if (event == CA_EVENT_TX_START && tp->app_limited) { -+ bbr->idle_restart = 1; -+ /* Avoid pointless buffer overflows: pace at est. bw if we don't -+ * need more speed (we're restarting from idle and app-limited). -+ */ -+ if (bbr->mode == BBR_PROBE_BW) -+ bbr_set_pacing_rate(sk, bbr_bw(sk), BBR_UNIT); -+ else if (bbr->mode == BBR_PROBE_RTT) -+ bbr_check_probe_rtt_done(sk); -+ } -+} -+ -+/* Find target cwnd. Right-size the cwnd based on min RTT and the -+ * estimated bottleneck bandwidth: -+ * -+ * cwnd = bw * min_rtt * gain = BDP * gain -+ * -+ * The key factor, gain, controls the amount of queue. While a small gain -+ * builds a smaller queue, it becomes more vulnerable to noise in RTT -+ * measurements (e.g., delayed ACKs or other ACK compression effects). This -+ * noise may cause BBR to under-estimate the rate. -+ * -+ * To achieve full performance in high-speed paths, we budget enough cwnd to -+ * fit full-sized skbs in-flight on both end hosts to fully utilize the path: -+ * - one skb in sending host Qdisc, -+ * - one skb in sending host TSO/GSO engine -+ * - one skb being received by receiver host LRO/GRO/delayed-ACK engine -+ * Don't worry, at low rates (bbr_min_tso_rate) this won't bloat cwnd because -+ * in such cases tso_segs_goal is 1. The minimum cwnd is 4 packets, -+ * which allows 2 outstanding 2-packet sequences, to try to keep pipe -+ * full even with ACK-every-other-packet delayed ACKs. -+ */ -+static u32 bbr_target_cwnd(struct sock *sk, u32 bw, int gain) -+{ -+ struct bbr *bbr = inet_csk_ca(sk); -+ u32 cwnd; -+ u64 w; -+ -+ /* If we've never had a valid RTT sample, cap cwnd at the initial -+ * default. This should only happen when the connection is not using TCP -+ * timestamps and has retransmitted all of the SYN/SYNACK/data packets -+ * ACKed so far. In this case, an RTO can cut cwnd to 1, in which -+ * case we need to slow-start up toward something safe: TCP_INIT_CWND. -+ */ -+ if (unlikely(bbr->min_rtt_us == ~0U)) /* no valid RTT samples yet? */ -+ return TCP_INIT_CWND; /* be safe: cap at default initial cwnd*/ -+ -+ w = (u64)bw * bbr->min_rtt_us; -+ -+ /* Apply a gain to the given value, then remove the BW_SCALE shift. */ -+ cwnd = (((w * gain) >> BBR_SCALE) + BW_UNIT - 1) / BW_UNIT; -+ -+ /* Allow enough full-sized skbs in flight to utilize end systems. */ -+ cwnd += 3 * bbr_tso_segs_goal(sk); -+ -+ /* Reduce delayed ACKs by rounding up cwnd to the next even number. */ -+ cwnd = (cwnd + 1) & ~1U; -+ -+ /* Ensure gain cycling gets inflight above BDP even for small BDPs. */ -+ if (bbr->mode == BBR_PROBE_BW && gain > BBR_UNIT) -+ cwnd += 2; -+ -+ return cwnd; -+} -+ -+/* An optimization in BBR to reduce losses: On the first round of recovery, we -+ * follow the packet conservation principle: send P packets per P packets acked. -+ * After that, we slow-start and send at most 2*P packets per P packets acked. -+ * After recovery finishes, or upon undo, we restore the cwnd we had when -+ * recovery started (capped by the target cwnd based on estimated BDP). -+ * -+ * TODO(ycheng/ncardwell): implement a rate-based approach. -+ */ -+static bool bbr_set_cwnd_to_recover_or_restore( -+ struct sock *sk, const struct rate_sample *rs, u32 acked, u32 *new_cwnd) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct bbr *bbr = inet_csk_ca(sk); -+ u8 prev_state = bbr->prev_ca_state, state = inet_csk(sk)->icsk_ca_state; -+ u32 cwnd = tp->snd_cwnd; -+ -+ /* An ACK for P pkts should release at most 2*P packets. We do this -+ * in two steps. First, here we deduct the number of lost packets. -+ * Then, in bbr_set_cwnd() we slow start up toward the target cwnd. -+ */ -+ if (rs->losses > 0) -+ cwnd = max_t(s32, cwnd - rs->losses, 1); -+ -+ if (state == TCP_CA_Recovery && prev_state != TCP_CA_Recovery) { -+ /* Starting 1st round of Recovery, so do packet conservation. */ -+ bbr->packet_conservation = 1; -+ bbr->next_rtt_delivered = tp->delivered; /* start round now */ -+ /* Cut unused cwnd from app behavior, TSQ, or TSO deferral: */ -+ cwnd = tcp_packets_in_flight(tp) + acked; -+ } else if (prev_state >= TCP_CA_Recovery && state < TCP_CA_Recovery) { -+ /* Exiting loss recovery; restore cwnd saved before recovery. */ -+ cwnd = max(cwnd, bbr->prior_cwnd); -+ bbr->packet_conservation = 0; -+ } -+ bbr->prev_ca_state = state; -+ -+ if (bbr->packet_conservation) { -+ *new_cwnd = max(cwnd, tcp_packets_in_flight(tp) + acked); -+ return true; /* yes, using packet conservation */ -+ } -+ *new_cwnd = cwnd; -+ return false; -+} -+ -+/* Slow-start up toward target cwnd (if bw estimate is growing, or packet loss -+ * has drawn us down below target), or snap down to target if we're above it. -+ */ -+static void bbr_set_cwnd(struct sock *sk, const struct rate_sample *rs, -+ u32 acked, u32 bw, int gain) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct bbr *bbr = inet_csk_ca(sk); -+ u32 cwnd = tp->snd_cwnd, target_cwnd = 0; -+ -+ if (!acked) -+ goto done; /* no packet fully ACKed; just apply caps */ -+ -+ if (bbr_set_cwnd_to_recover_or_restore(sk, rs, acked, &cwnd)) -+ goto done; -+ -+ /* If we're below target cwnd, slow start cwnd toward target cwnd. */ -+ target_cwnd = bbr_target_cwnd(sk, bw, gain); -+ if (bbr_full_bw_reached(sk)) /* only cut cwnd if we filled the pipe */ -+ cwnd = min(cwnd + acked, target_cwnd); -+ else if (cwnd < target_cwnd || tp->delivered < TCP_INIT_CWND) -+ cwnd = cwnd + acked; -+ cwnd = max(cwnd, bbr_cwnd_min_target); -+ -+done: -+ tp->snd_cwnd = min(cwnd, tp->snd_cwnd_clamp); /* apply global cap */ -+ if (bbr->mode == BBR_PROBE_RTT) /* drain queue, refresh min_rtt */ -+ tp->snd_cwnd = min(tp->snd_cwnd, bbr_cwnd_min_target); -+} -+ -+/* End cycle phase if it's time and/or we hit the phase's in-flight target. */ -+static bool bbr_is_next_cycle_phase(struct sock *sk, -+ const struct rate_sample *rs) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct bbr *bbr = inet_csk_ca(sk); -+ bool is_full_length = -+ tcp_stamp_us_delta(tp->delivered_mstamp, bbr->cycle_mstamp) > -+ bbr->min_rtt_us; -+ u32 inflight, bw; -+ -+ /* The pacing_gain of 1.0 paces at the estimated bw to try to fully -+ * use the pipe without increasing the queue. -+ */ -+ if (bbr->pacing_gain == BBR_UNIT) -+ return is_full_length; /* just use wall clock time */ -+ -+ inflight = rs->prior_in_flight; /* what was in-flight before ACK? */ -+ bw = bbr_max_bw(sk); -+ -+ /* A pacing_gain > 1.0 probes for bw by trying to raise inflight to at -+ * least pacing_gain*BDP; this may take more than min_rtt if min_rtt is -+ * small (e.g. on a LAN). We do not persist if packets are lost, since -+ * a path with small buffers may not hold that much. -+ */ -+ if (bbr->pacing_gain > BBR_UNIT) -+ return is_full_length && -+ (rs->losses || /* perhaps pacing_gain*BDP won't fit */ -+ inflight >= bbr_target_cwnd(sk, bw, bbr->pacing_gain)); -+ -+ /* A pacing_gain < 1.0 tries to drain extra queue we added if bw -+ * probing didn't find more bw. If inflight falls to match BDP then we -+ * estimate queue is drained; persisting would underutilize the pipe. -+ */ -+ return is_full_length || -+ inflight <= bbr_target_cwnd(sk, bw, BBR_UNIT); -+} -+ -+static void bbr_advance_cycle_phase(struct sock *sk) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct bbr *bbr = inet_csk_ca(sk); -+ -+ bbr->cycle_idx = (bbr->cycle_idx + 1) & (CYCLE_LEN - 1); -+ bbr->cycle_mstamp = tp->delivered_mstamp; -+ bbr->pacing_gain = bbr->lt_use_bw ? BBR_UNIT : -+ bbr_pacing_gain[bbr->cycle_idx]; -+} -+ -+/* Gain cycling: cycle pacing gain to converge to fair share of available bw. */ -+static void bbr_update_cycle_phase(struct sock *sk, -+ const struct rate_sample *rs) -+{ -+ struct bbr *bbr = inet_csk_ca(sk); -+ -+ if (bbr->mode == BBR_PROBE_BW && bbr_is_next_cycle_phase(sk, rs)) -+ bbr_advance_cycle_phase(sk); -+} -+ -+static void bbr_reset_startup_mode(struct sock *sk) -+{ -+ struct bbr *bbr = inet_csk_ca(sk); -+ -+ bbr->mode = BBR_STARTUP; -+ bbr->pacing_gain = bbr_high_gain; -+ bbr->cwnd_gain = bbr_high_gain; -+} -+ -+static void bbr_reset_probe_bw_mode(struct sock *sk) -+{ -+ struct bbr *bbr = inet_csk_ca(sk); -+ -+ bbr->mode = BBR_PROBE_BW; -+ bbr->pacing_gain = BBR_UNIT; -+ bbr->cwnd_gain = bbr_cwnd_gain; -+ bbr->cycle_idx = CYCLE_LEN - 1 - prandom_u32_max(bbr_cycle_rand); -+ bbr_advance_cycle_phase(sk); /* flip to next phase of gain cycle */ -+} -+ -+static void bbr_reset_mode(struct sock *sk) -+{ -+ if (!bbr_full_bw_reached(sk)) -+ bbr_reset_startup_mode(sk); -+ else -+ bbr_reset_probe_bw_mode(sk); -+} -+ -+/* Start a new long-term sampling interval. */ -+static void bbr_reset_lt_bw_sampling_interval(struct sock *sk) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct bbr *bbr = inet_csk_ca(sk); -+ -+ bbr->lt_last_stamp = div_u64(tp->delivered_mstamp, USEC_PER_MSEC); -+ bbr->lt_last_delivered = tp->delivered; -+ bbr->lt_last_lost = tp->lost; -+ bbr->lt_rtt_cnt = 0; -+} -+ -+/* Completely reset long-term bandwidth sampling. */ -+static void bbr_reset_lt_bw_sampling(struct sock *sk) -+{ -+ struct bbr *bbr = inet_csk_ca(sk); -+ -+ bbr->lt_bw = 0; -+ bbr->lt_use_bw = 0; -+ bbr->lt_is_sampling = false; -+ bbr_reset_lt_bw_sampling_interval(sk); -+} -+ -+/* Long-term bw sampling interval is done. Estimate whether we're policed. */ -+static void bbr_lt_bw_interval_done(struct sock *sk, u32 bw) -+{ -+ struct bbr *bbr = inet_csk_ca(sk); -+ u32 diff; -+ -+ if (bbr->lt_bw) { /* do we have bw from a previous interval? */ -+ /* Is new bw close to the lt_bw from the previous interval? */ -+ diff = abs(bw - bbr->lt_bw); -+ if ((diff * BBR_UNIT <= bbr_lt_bw_ratio * bbr->lt_bw) || -+ (bbr_rate_bytes_per_sec(sk, diff, BBR_UNIT) <= -+ bbr_lt_bw_diff)) { -+ /* All criteria are met; estimate we're policed. */ -+ bbr->lt_bw = (bw + bbr->lt_bw) >> 1; /* avg 2 intvls */ -+ bbr->lt_use_bw = 1; -+ bbr->pacing_gain = BBR_UNIT; /* try to avoid drops */ -+ bbr->lt_rtt_cnt = 0; -+ return; -+ } -+ } -+ bbr->lt_bw = bw; -+ bbr_reset_lt_bw_sampling_interval(sk); -+} -+ -+/* Token-bucket traffic policers are common (see "An Internet-Wide Analysis of -+ * Traffic Policing", SIGCOMM 2016). BBR detects token-bucket policers and -+ * explicitly models their policed rate, to reduce unnecessary losses. We -+ * estimate that we're policed if we see 2 consecutive sampling intervals with -+ * consistent throughput and high packet loss. If we think we're being policed, -+ * set lt_bw to the "long-term" average delivery rate from those 2 intervals. -+ */ -+static void bbr_lt_bw_sampling(struct sock *sk, const struct rate_sample *rs) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct bbr *bbr = inet_csk_ca(sk); -+ u32 lost, delivered; -+ u64 bw; -+ u32 t; -+ -+ if (bbr->lt_use_bw) { /* already using long-term rate, lt_bw? */ -+ if (bbr->mode == BBR_PROBE_BW && bbr->round_start && -+ ++bbr->lt_rtt_cnt >= bbr_lt_bw_max_rtts) { -+ bbr_reset_lt_bw_sampling(sk); /* stop using lt_bw */ -+ bbr_reset_probe_bw_mode(sk); /* restart gain cycling */ -+ } -+ return; -+ } -+ -+ /* Wait for the first loss before sampling, to let the policer exhaust -+ * its tokens and estimate the steady-state rate allowed by the policer. -+ * Starting samples earlier includes bursts that over-estimate the bw. -+ */ -+ if (!bbr->lt_is_sampling) { -+ if (!rs->losses) -+ return; -+ bbr_reset_lt_bw_sampling_interval(sk); -+ bbr->lt_is_sampling = true; -+ } -+ -+ /* To avoid underestimates, reset sampling if we run out of data. */ -+ if (rs->is_app_limited) { -+ bbr_reset_lt_bw_sampling(sk); -+ return; -+ } -+ -+ if (bbr->round_start) -+ bbr->lt_rtt_cnt++; /* count round trips in this interval */ -+ if (bbr->lt_rtt_cnt < bbr_lt_intvl_min_rtts) -+ return; /* sampling interval needs to be longer */ -+ if (bbr->lt_rtt_cnt > 4 * bbr_lt_intvl_min_rtts) { -+ bbr_reset_lt_bw_sampling(sk); /* interval is too long */ -+ return; -+ } -+ -+ /* End sampling interval when a packet is lost, so we estimate the -+ * policer tokens were exhausted. Stopping the sampling before the -+ * tokens are exhausted under-estimates the policed rate. -+ */ -+ if (!rs->losses) -+ return; -+ -+ /* Calculate packets lost and delivered in sampling interval. */ -+ lost = tp->lost - bbr->lt_last_lost; -+ delivered = tp->delivered - bbr->lt_last_delivered; -+ /* Is loss rate (lost/delivered) >= lt_loss_thresh? If not, wait. */ -+ if (!delivered || (lost << BBR_SCALE) < bbr_lt_loss_thresh * delivered) -+ return; -+ -+ /* Find average delivery rate in this sampling interval. */ -+ t = div_u64(tp->delivered_mstamp, USEC_PER_MSEC) - bbr->lt_last_stamp; -+ if ((s32)t < 1) -+ return; /* interval is less than one ms, so wait */ -+ /* Check if can multiply without overflow */ -+ if (t >= ~0U / USEC_PER_MSEC) { -+ bbr_reset_lt_bw_sampling(sk); /* interval too long; reset */ -+ return; -+ } -+ t *= USEC_PER_MSEC; -+ bw = (u64)delivered * BW_UNIT; -+ do_div(bw, t); -+ bbr_lt_bw_interval_done(sk, bw); -+} -+ -+/* Estimate the bandwidth based on how fast packets are delivered */ -+static void bbr_update_bw(struct sock *sk, const struct rate_sample *rs) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct bbr *bbr = inet_csk_ca(sk); -+ u64 bw; -+ -+ bbr->round_start = 0; -+ if (rs->delivered < 0 || rs->interval_us <= 0) -+ return; /* Not a valid observation */ -+ -+ /* See if we've reached the next RTT */ -+ if (!before(rs->prior_delivered, bbr->next_rtt_delivered)) { -+ bbr->next_rtt_delivered = tp->delivered; -+ bbr->rtt_cnt++; -+ bbr->round_start = 1; -+ bbr->packet_conservation = 0; -+ } -+ -+ bbr_lt_bw_sampling(sk, rs); -+ -+ /* Divide delivered by the interval to find a (lower bound) bottleneck -+ * bandwidth sample. Delivered is in packets and interval_us in uS and -+ * ratio will be <<1 for most connections. So delivered is first scaled. -+ */ -+ bw = (u64)rs->delivered * BW_UNIT; -+ do_div(bw, rs->interval_us); -+ -+ /* If this sample is application-limited, it is likely to have a very -+ * low delivered count that represents application behavior rather than -+ * the available network rate. Such a sample could drag down estimated -+ * bw, causing needless slow-down. Thus, to continue to send at the -+ * last measured network rate, we filter out app-limited samples unless -+ * they describe the path bw at least as well as our bw model. -+ * -+ * So the goal during app-limited phase is to proceed with the best -+ * network rate no matter how long. We automatically leave this -+ * phase when app writes faster than the network can deliver :) -+ */ -+ if (!rs->is_app_limited || bw >= bbr_max_bw(sk)) { -+ /* Incorporate new sample into our max bw filter. */ -+ minmax_running_max(&bbr->bw, bbr_bw_rtts, bbr->rtt_cnt, bw); -+ } -+} -+ -+/* Estimate when the pipe is full, using the change in delivery rate: BBR -+ * estimates that STARTUP filled the pipe if the estimated bw hasn't changed by -+ * at least bbr_full_bw_thresh (25%) after bbr_full_bw_cnt (3) non-app-limited -+ * rounds. Why 3 rounds: 1: rwin autotuning grows the rwin, 2: we fill the -+ * higher rwin, 3: we get higher delivery rate samples. Or transient -+ * cross-traffic or radio noise can go away. CUBIC Hystart shares a similar -+ * design goal, but uses delay and inter-ACK spacing instead of bandwidth. -+ */ -+static void bbr_check_full_bw_reached(struct sock *sk, -+ const struct rate_sample *rs) -+{ -+ struct bbr *bbr = inet_csk_ca(sk); -+ u32 bw_thresh; -+ -+ if (bbr_full_bw_reached(sk) || !bbr->round_start || rs->is_app_limited) -+ return; -+ -+ bw_thresh = (u64)bbr->full_bw * bbr_full_bw_thresh >> BBR_SCALE; -+ if (bbr_max_bw(sk) >= bw_thresh) { -+ bbr->full_bw = bbr_max_bw(sk); -+ bbr->full_bw_cnt = 0; -+ return; -+ } -+ ++bbr->full_bw_cnt; -+ bbr->full_bw_reached = bbr->full_bw_cnt >= bbr_full_bw_cnt; -+} -+ -+/* If pipe is probably full, drain the queue and then enter steady-state. */ -+static void bbr_check_drain(struct sock *sk, const struct rate_sample *rs) -+{ -+ struct bbr *bbr = inet_csk_ca(sk); -+ -+ if (bbr->mode == BBR_STARTUP && bbr_full_bw_reached(sk)) { -+ bbr->mode = BBR_DRAIN; /* drain queue we created */ -+ bbr->pacing_gain = bbr_drain_gain; /* pace slow to drain */ -+ bbr->cwnd_gain = bbr_high_gain; /* maintain cwnd */ -+ tcp_sk(sk)->snd_ssthresh = -+ bbr_target_cwnd(sk, bbr_max_bw(sk), BBR_UNIT); -+ } /* fall through to check if in-flight is already small: */ -+ if (bbr->mode == BBR_DRAIN && -+ tcp_packets_in_flight(tcp_sk(sk)) <= -+ bbr_target_cwnd(sk, bbr_max_bw(sk), BBR_UNIT)) -+ bbr_reset_probe_bw_mode(sk); /* we estimate queue is drained */ -+} -+ -+static void bbr_check_probe_rtt_done(struct sock *sk) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct bbr *bbr = inet_csk_ca(sk); -+ -+ if (!(bbr->probe_rtt_done_stamp && -+ after(tcp_jiffies32, bbr->probe_rtt_done_stamp))) -+ return; -+ -+ bbr->min_rtt_stamp = tcp_jiffies32; /* wait a while until PROBE_RTT */ -+ tp->snd_cwnd = max(tp->snd_cwnd, bbr->prior_cwnd); -+ bbr_reset_mode(sk); -+} -+ -+/* The goal of PROBE_RTT mode is to have BBR flows cooperatively and -+ * periodically drain the bottleneck queue, to converge to measure the true -+ * min_rtt (unloaded propagation delay). This allows the flows to keep queues -+ * small (reducing queuing delay and packet loss) and achieve fairness among -+ * BBR flows. -+ * -+ * The min_rtt filter window is 10 seconds. When the min_rtt estimate expires, -+ * we enter PROBE_RTT mode and cap the cwnd at bbr_cwnd_min_target=4 packets. -+ * After at least bbr_probe_rtt_mode_ms=200ms and at least one packet-timed -+ * round trip elapsed with that flight size <= 4, we leave PROBE_RTT mode and -+ * re-enter the previous mode. BBR uses 200ms to approximately bound the -+ * performance penalty of PROBE_RTT's cwnd capping to roughly 2% (200ms/10s). -+ * -+ * Note that flows need only pay 2% if they are busy sending over the last 10 -+ * seconds. Interactive applications (e.g., Web, RPCs, video chunks) often have -+ * natural silences or low-rate periods within 10 seconds where the rate is low -+ * enough for long enough to drain its queue in the bottleneck. We pick up -+ * these min RTT measurements opportunistically with our min_rtt filter. :-) -+ */ -+static void bbr_update_min_rtt(struct sock *sk, const struct rate_sample *rs) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct bbr *bbr = inet_csk_ca(sk); -+ bool filter_expired; -+ -+ /* Track min RTT seen in the min_rtt_win_sec filter window: */ -+ filter_expired = after(tcp_jiffies32, -+ bbr->min_rtt_stamp + bbr_min_rtt_win_sec * HZ); -+ if (rs->rtt_us >= 0 && -+ (rs->rtt_us <= bbr->min_rtt_us || -+ (filter_expired && !rs->is_ack_delayed))) { -+ bbr->min_rtt_us = rs->rtt_us; -+ bbr->min_rtt_stamp = tcp_jiffies32; -+ } -+ -+ if (bbr_probe_rtt_mode_ms > 0 && filter_expired && -+ !bbr->idle_restart && bbr->mode != BBR_PROBE_RTT) { -+ bbr->mode = BBR_PROBE_RTT; /* dip, drain queue */ -+ bbr->pacing_gain = BBR_UNIT; -+ bbr->cwnd_gain = BBR_UNIT; -+ bbr_save_cwnd(sk); /* note cwnd so we can restore it */ -+ bbr->probe_rtt_done_stamp = 0; -+ } -+ -+ if (bbr->mode == BBR_PROBE_RTT) { -+ /* Ignore low rate samples during this mode. */ -+ tp->app_limited = -+ (tp->delivered + tcp_packets_in_flight(tp)) ? : 1; -+ /* Maintain min packets in flight for max(200 ms, 1 round). */ -+ if (!bbr->probe_rtt_done_stamp && -+ tcp_packets_in_flight(tp) <= bbr_cwnd_min_target) { -+ bbr->probe_rtt_done_stamp = tcp_jiffies32 + -+ msecs_to_jiffies(bbr_probe_rtt_mode_ms); -+ bbr->probe_rtt_round_done = 0; -+ bbr->next_rtt_delivered = tp->delivered; -+ } else if (bbr->probe_rtt_done_stamp) { -+ if (bbr->round_start) -+ bbr->probe_rtt_round_done = 1; -+ if (bbr->probe_rtt_round_done) -+ bbr_check_probe_rtt_done(sk); -+ } -+ } -+ /* Restart after idle ends only once we process a new S/ACK for data */ -+ if (rs->delivered > 0) -+ bbr->idle_restart = 0; -+} -+ -+static void bbr_update_model(struct sock *sk, const struct rate_sample *rs) -+{ -+ bbr_update_bw(sk, rs); -+ bbr_update_cycle_phase(sk, rs); -+ bbr_check_full_bw_reached(sk, rs); -+ bbr_check_drain(sk, rs); -+ bbr_update_min_rtt(sk, rs); -+} -+ -+static void bbr_main(struct sock *sk, const struct rate_sample *rs) -+{ -+ struct bbr *bbr = inet_csk_ca(sk); -+ u32 bw; -+ -+ bbr_update_model(sk, rs); -+ -+ bw = bbr_bw(sk); -+ bbr_set_pacing_rate(sk, bw, bbr->pacing_gain); -+ bbr_set_cwnd(sk, rs, rs->acked_sacked, bw, bbr->cwnd_gain); -+} -+ -+static void bbr_init(struct sock *sk) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct bbr *bbr = inet_csk_ca(sk); -+ -+ bbr->prior_cwnd = 0; -+ tp->snd_ssthresh = TCP_INFINITE_SSTHRESH; -+ bbr->rtt_cnt = 0; -+ bbr->next_rtt_delivered = 0; -+ bbr->prev_ca_state = TCP_CA_Open; -+ bbr->packet_conservation = 0; -+ -+ bbr->probe_rtt_done_stamp = 0; -+ bbr->probe_rtt_round_done = 0; -+ bbr->min_rtt_us = tcp_min_rtt(tp); -+ bbr->min_rtt_stamp = tcp_jiffies32; -+ -+ minmax_reset(&bbr->bw, bbr->rtt_cnt, 0); /* init max bw to 0 */ -+ -+ bbr->has_seen_rtt = 0; -+ bbr_init_pacing_rate_from_rtt(sk); -+ -+ bbr->round_start = 0; -+ bbr->idle_restart = 0; -+ bbr->full_bw_reached = 0; -+ bbr->full_bw = 0; -+ bbr->full_bw_cnt = 0; -+ bbr->cycle_mstamp = 0; -+ bbr->cycle_idx = 0; -+ bbr_reset_lt_bw_sampling(sk); -+ bbr_reset_startup_mode(sk); -+ -+ cmpxchg(&sk->sk_pacing_status, SK_PACING_NONE, SK_PACING_NEEDED); -+} -+ -+static u32 bbr_sndbuf_expand(struct sock *sk) -+{ -+ /* Provision 3 * cwnd since BBR may slow-start even during recovery. */ -+ return 3; -+} -+ -+/* In theory BBR does not need to undo the cwnd since it does not -+ * always reduce cwnd on losses (see bbr_main()). Keep it for now. -+ */ -+static u32 bbr_undo_cwnd(struct sock *sk) -+{ -+ struct bbr *bbr = inet_csk_ca(sk); -+ -+ bbr->full_bw = 0; /* spurious slow-down; reset full pipe detection */ -+ bbr->full_bw_cnt = 0; -+ bbr_reset_lt_bw_sampling(sk); -+ return tcp_sk(sk)->snd_cwnd; -+} -+ -+/* Entering loss recovery, so save cwnd for when we exit or undo recovery. */ -+static u32 bbr_ssthresh(struct sock *sk) -+{ -+ bbr_save_cwnd(sk); -+ return tcp_sk(sk)->snd_ssthresh; -+} -+ -+static size_t bbr_get_info(struct sock *sk, u32 ext, int *attr, -+ union tcp_cc_info *info) -+{ -+ if (ext & (1 << (INET_DIAG_BBRINFO - 1)) || -+ ext & (1 << (INET_DIAG_VEGASINFO - 1))) { -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct bbr *bbr = inet_csk_ca(sk); -+ u64 bw = bbr_bw(sk); -+ -+ bw = bw * tp->mss_cache * USEC_PER_SEC >> BW_SCALE; -+ memset(&info->bbr, 0, sizeof(info->bbr)); -+ info->bbr.bbr_bw_lo = (u32)bw; -+ info->bbr.bbr_bw_hi = (u32)(bw >> 32); -+ info->bbr.bbr_min_rtt = bbr->min_rtt_us; -+ info->bbr.bbr_pacing_gain = bbr->pacing_gain; -+ info->bbr.bbr_cwnd_gain = bbr->cwnd_gain; -+ *attr = INET_DIAG_BBRINFO; -+ return sizeof(info->bbr); -+ } -+ return 0; -+} -+ -+static void bbr_set_state(struct sock *sk, u8 new_state) -+{ -+ struct bbr *bbr = inet_csk_ca(sk); -+ -+ if (new_state == TCP_CA_Loss) { -+ struct rate_sample rs = { .losses = 1 }; -+ -+ bbr->prev_ca_state = TCP_CA_Loss; -+ bbr->full_bw = 0; -+ bbr->round_start = 1; /* treat RTO like end of a round */ -+ bbr_lt_bw_sampling(sk, &rs); -+ } -+} -+ -+static struct tcp_congestion_ops tcp_bbr_cong_ops __read_mostly = { -+ .flags = TCP_CONG_NON_RESTRICTED, -+ .name = "nanqinlang", -+ .owner = THIS_MODULE, -+ .init = bbr_init, -+ .cong_control = bbr_main, -+ .sndbuf_expand = bbr_sndbuf_expand, -+ .undo_cwnd = bbr_undo_cwnd, -+ .cwnd_event = bbr_cwnd_event, -+ .ssthresh = bbr_ssthresh, -+ .min_tso_segs = bbr_min_tso_segs, -+ .get_info = bbr_get_info, -+ .set_state = bbr_set_state, -+}; -+ -+static int __init bbr_register(void) -+{ -+ BUILD_BUG_ON(sizeof(struct bbr) > ICSK_CA_PRIV_SIZE); -+ return tcp_register_congestion_control(&tcp_bbr_cong_ops); -+} -+ -+static void __exit bbr_unregister(void) -+{ -+ tcp_unregister_congestion_control(&tcp_bbr_cong_ops); -+} -+ -+module_init(bbr_register); -+module_exit(bbr_unregister); -+ -+MODULE_AUTHOR("Van Jacobson "); -+MODULE_AUTHOR("Neal Cardwell "); -+MODULE_AUTHOR("Yuchung Cheng "); -+MODULE_AUTHOR("Soheil Hassas Yeganeh "); -+MODULE_LICENSE("Dual BSD/GPL"); -+MODULE_DESCRIPTION("TCP BBR (Bottleneck Bandwidth and RTT)"); -+MODULE_AUTHOR("Nanqinlang "); diff --git a/root/target/linux/generic/hack-5.4/998-ndpi-netfilter.patch b/root/target/linux/generic/hack-5.4/998-ndpi-netfilter.patch deleted file mode 100644 index cd8d61a7..00000000 --- a/root/target/linux/generic/hack-5.4/998-ndpi-netfilter.patch +++ /dev/null @@ -1,116 +0,0 @@ -diff --git a/include/net/netfilter/nf_conntrack_extend.h b/include/net/netfilter/nf_conntrack_extend.h -index 21f887c..59980ec 100644 ---- a/include/net/netfilter/nf_conntrack_extend.h -+++ b/include/net/netfilter/nf_conntrack_extend.h -@@ -28,7 +28,8 @@ enum nf_ct_ext_id { - #if IS_ENABLED(CONFIG_NETFILTER_SYNPROXY) - NF_CT_EXT_SYNPROXY, - #endif -- NF_CT_EXT_NUM, -+ NF_CT_EXT_CUSTOM, -+ NF_CT_EXT_NUM=NF_CT_EXT_CUSTOM+CONFIG_NF_CONNTRACK_CUSTOM, - }; - - #define NF_CT_EXT_HELPER_TYPE struct nf_conn_help -@@ -96,5 +97,6 @@ struct nf_ct_ext_type { - }; - - int nf_ct_extend_register(const struct nf_ct_ext_type *type); -+int nf_ct_extend_custom_register(struct nf_ct_ext_type *type,unsigned long int cid); - void nf_ct_extend_unregister(const struct nf_ct_ext_type *type); - #endif /* _NF_CONNTRACK_EXTEND_H */ -diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig -index 7581e82..30a11eb 100644 ---- a/net/netfilter/Kconfig -+++ b/net/netfilter/Kconfig -@@ -85,6 +85,16 @@ config NF_CONNTRACK_SECMARK - - If unsure, say 'N'. - -+config NF_CONNTRACK_CUSTOM -+ int "Number of custom extend" -+ range 0 8 -+ depends on NETFILTER_ADVANCED -+ default "2" -+ help -+ This parameter specifies how many custom extensions can be registered. -+ -+ The default value is 2. -+ - config NF_CONNTRACK_ZONES - bool 'Connection tracking zones' - depends on NETFILTER_ADVANCED -diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c -index 85f643c..44e2fdd 100644 ---- a/net/netfilter/nf_conntrack_core.c -+++ b/net/netfilter/nf_conntrack_core.c -@@ -1971,7 +1971,7 @@ int nf_conntrack_set_hashsize(const char *val, const struct kernel_param *kp) - static __always_inline unsigned int total_extension_size(void) - { - /* remember to add new extensions below */ -- BUILD_BUG_ON(NF_CT_EXT_NUM > 9); -+ BUILD_BUG_ON(NF_CT_EXT_NUM > 12); - - return sizeof(struct nf_ct_ext) + - sizeof(struct nf_conn_help) -diff --git a/net/netfilter/nf_conntrack_extend.c b/net/netfilter/nf_conntrack_extend.c -index 9fe0ddc..5a9054e 100644 ---- a/net/netfilter/nf_conntrack_extend.c -+++ b/net/netfilter/nf_conntrack_extend.c -@@ -108,11 +108,56 @@ int nf_ct_extend_register(const struct nf_ct_ext_type *type) - } - EXPORT_SYMBOL_GPL(nf_ct_extend_register); - -+static unsigned long int nf_ct_ext_cust_id[CONFIG_NF_CONNTRACK_CUSTOM]; -+static enum nf_ct_ext_id -+nf_ct_extend_get_custom_id(unsigned long int ext_id); -+ -+int nf_ct_extend_custom_register(struct nf_ct_ext_type *type, -+ unsigned long int cid) -+{ -+ int ret; -+ enum nf_ct_ext_id new_id = nf_ct_extend_get_custom_id(cid); -+ if(!new_id) -+ return -EBUSY; -+ type->id = new_id; -+ ret = nf_ct_extend_register(type); -+ if(ret < 0) { -+ mutex_lock(&nf_ct_ext_type_mutex); -+ nf_ct_ext_cust_id[new_id - NF_CT_EXT_CUSTOM] = 0; -+ mutex_unlock(&nf_ct_ext_type_mutex); -+ } -+ return ret; -+} -+EXPORT_SYMBOL_GPL(nf_ct_extend_custom_register); -+ -+static enum nf_ct_ext_id -+nf_ct_extend_get_custom_id(unsigned long int ext_id) -+{ -+ enum nf_ct_ext_id ret = 0; -+ int i; -+ mutex_lock(&nf_ct_ext_type_mutex); -+ for(i = 0; i < CONFIG_NF_CONNTRACK_CUSTOM; i++) { -+ if(!nf_ct_ext_cust_id[i]) { -+ nf_ct_ext_cust_id[i] = ext_id; -+ ret = i+NF_CT_EXT_CUSTOM; -+ break; -+ } -+ if(nf_ct_ext_cust_id[i] == ext_id) { -+ ret = i+NF_CT_EXT_CUSTOM; -+ break; -+ } -+ } -+ mutex_unlock(&nf_ct_ext_type_mutex); -+ return ret; -+} -+ - /* This MUST be called in process context. */ - void nf_ct_extend_unregister(const struct nf_ct_ext_type *type) - { - mutex_lock(&nf_ct_ext_type_mutex); - RCU_INIT_POINTER(nf_ct_ext_types[type->id], NULL); -+ if(type->id >= NF_CT_EXT_CUSTOM && type->id < NF_CT_EXT_NUM) -+ nf_ct_ext_cust_id[type->id-NF_CT_EXT_CUSTOM] = 0; - mutex_unlock(&nf_ct_ext_type_mutex); - synchronize_rcu(); - } diff --git a/root/target/linux/generic/hack-5.4/999-stop-promiscuous-info.patch b/root/target/linux/generic/hack-5.4/999-stop-promiscuous-info.patch deleted file mode 100644 index 850613b5..00000000 --- a/root/target/linux/generic/hack-5.4/999-stop-promiscuous-info.patch +++ /dev/null @@ -1,47 +0,0 @@ ---- a/net/core/dev.c 2018-08-10 10:31:41.199494561 +0200 -+++ b/net/core/dev.c 2018-08-10 10:32:03.635272509 +0200 -@@ -6613,9 +6613,11 @@ - } - } - if (dev->flags != old_flags) { -+ /* - pr_info("device %s %s promiscuous mode\n", - dev->name, - dev->flags & IFF_PROMISC ? "entered" : "left"); -+ */ - if (audit_enabled) { - current_uid_gid(&uid, &gid); - audit_log(current->audit_context, GFP_ATOMIC, ---- a/drivers/net/usb/r8152.c 2020-08-13 13:11:25.866435255 +0200 -+++ b/drivers/net/usb/r8152.c 2020-08-13 13:11:51.973994306 +0200 -@@ -2353,7 +2353,7 @@ - - if (netdev->flags & IFF_PROMISC) { - /* Unconditionally log net taps. */ -- netif_notice(tp, link, netdev, "Promiscuous mode enabled\n"); -+ //netif_notice(tp, link, netdev, "Promiscuous mode enabled\n"); - ocp_data |= RCR_AM | RCR_AAP; - mc_filter[1] = 0xffffffff; - mc_filter[0] = 0xffffffff; ---- a/drivers/net/usb/pegasus.c 2020-08-13 13:14:15.519570376 +0200 -+++ b/drivers/net/usb/pegasus.c 2020-08-13 13:14:26.795380006 +0200 -@@ -1031,7 +1031,7 @@ - - if (net->flags & IFF_PROMISC) { - pegasus->eth_regs[EthCtrl2] |= RX_PROMISCUOUS; -- netif_info(pegasus, link, net, "Promiscuous mode enabled\n"); -+ //netif_info(pegasus, link, net, "Promiscuous mode enabled\n"); - } else if (!netdev_mc_empty(net) || (net->flags & IFF_ALLMULTI)) { - pegasus->eth_regs[EthCtrl0] |= RX_MULTICAST; - pegasus->eth_regs[EthCtrl2] &= ~RX_PROMISCUOUS; ---- a/drivers/net/ethernet/realtek/r8169_main.c 2020-08-13 13:15:44.478068638 +0200 -+++ b/drivers/net/ethernet/realtek/r8169_main.c 2020-08-13 13:15:59.181820450 +0200 -@@ -4313,7 +4313,7 @@ - - if (dev->flags & IFF_PROMISC) { - /* Unconditionally log net taps. */ -- netif_notice(tp, link, dev, "Promiscuous mode enabled\n"); -+ //netif_notice(tp, link, dev, "Promiscuous mode enabled\n"); - rx_mode |= AcceptAllPhys; - } else if (netdev_mc_count(dev) > MC_FILTER_LIMIT || - dev->flags & IFF_ALLMULTI || diff --git a/root/target/linux/ipq40xx/base-files/etc/board.d/01_leds b/root/target/linux/ipq40xx/base-files/etc/board.d/01_leds old mode 100644 new mode 100755 index 5a9a05cd..a512a4d0 --- a/root/target/linux/ipq40xx/base-files/etc/board.d/01_leds +++ b/root/target/linux/ipq40xx/base-files/etc/board.d/01_leds @@ -8,50 +8,43 @@ board_config_update board=$(board_name) -boardname="${board##*,}" case "$board" in alfa-network,ap120c-ac) - ucidef_set_led_netdev "wan" "WAN" "${boardname}:amber:wan" "eth1" + ucidef_set_led_netdev "wan" "WAN" "amber:wan" "eth1" ;; asus,rt-ac58u) - ucidef_set_led_netdev "wan" "WAN" "${boardname}:blue:wan" "eth1" - ucidef_set_led_switch "lan" "LAN" "${boardname}:blue:lan" "switch0" "0x1e" - ;; -asus,rt-acrh17) - ucidef_set_led_default "status" "STATUS" "${boardname}:blue:status" "1" - ucidef_set_led_wlan "wlan2g" "WLAN2G" "${boardname}:blue:wlan2g" "phy1tpt" - ucidef_set_led_wlan "wlan5g" "WLAN5G" "${boardname}:blue:wlan5g" "phy0tpt" - ucidef_set_led_netdev "wan" "WAN" "${boardname}:blue:wan" "eth1" - ucidef_set_led_switch "lan1" "LAN1" "${boardname}:blue:lan1" "switch0" "0x02" - ucidef_set_led_switch "lan2" "LAN2" "${boardname}:blue:lan2" "switch0" "0x04" - ucidef_set_led_switch "lan3" "LAN3" "${boardname}:blue:lan3" "switch0" "0x08" - ucidef_set_led_switch "lan4" "LAN4" "${boardname}:blue:lan4" "switch0" "0x10" + ucidef_set_led_netdev "wan" "WAN" "blue:wan" "eth1" + ucidef_set_led_switch "lan" "LAN" "blue:lan" "switch0" "0x1e" ;; avm,fritzbox-4040) - ucidef_set_led_wlan "wlan" "WLAN" "fritz4040:green:wlan" "phy0tpt" "phy1tpt" - ucidef_set_led_netdev "wan" "WAN" "fritz4040:green:wan" "eth1" - ucidef_set_led_switch "lan" "LAN" "fritz4040:green:lan" "switch0" "0x1e" + ucidef_set_led_wlan "wlan" "WLAN" "green:wlan" "phy0tpt" "phy1tpt" + ucidef_set_led_netdev "wan" "WAN" "green:wan" "eth1" + ucidef_set_led_switch "lan" "LAN" "green:lan" "switch0" "0x1e" ;; avm,fritzbox-7530 |\ glinet,gl-b1300) - ucidef_set_led_wlan "wlan" "WLAN" "${boardname}:green:wlan" "phy0tpt" + ucidef_set_led_wlan "wlan" "WLAN" "green:wlan" "phy0tpt" + ;; +edgecore,oap100) + ucidef_set_led_wlan "wlan2g" "WLAN2G" "blue:wlan2g" "phy0tpt" + ucidef_set_led_wlan "wlan5g" "WLAN5G" "blue:wlan5g" "phy1tpt" ;; engenius,eap1300) - ucidef_set_led_netdev "lan" "LAN" "${boardname}:blue:lan" "eth0" - ucidef_set_led_wlan "wlan2g" "WLAN2G" "${boardname}:blue:wlan2g" "phy0tpt" - ucidef_set_led_wlan "wlan5g" "WLAN5G" "${boardname}:yellow:wlan5g" "phy1tpt" - ucidef_set_led_default "mesh" "MESH" "${boardname}:blue:mesh" "0" + ucidef_set_led_netdev "lan" "LAN" "blue:lan" "eth0" + ucidef_set_led_wlan "wlan2g" "WLAN2G" "blue:wlan2g" "phy0tpt" + ucidef_set_led_wlan "wlan5g" "WLAN5G" "yellow:wlan5g" "phy1tpt" + ucidef_set_led_default "mesh" "MESH" "blue:mesh" "0" ;; engenius,eap2200) - ucidef_set_led_netdev "lan1" "LAN1" "${boardname}:blue:lan1" "eth0" - ucidef_set_led_netdev "lan2" "LAN2" "${boardname}:blue:lan2" "eth1" + ucidef_set_led_netdev "lan1" "LAN1" "blue:lan1" "eth0" + ucidef_set_led_netdev "lan2" "LAN2" "blue:lan2" "eth1" ;; engenius,ens620ext) - ucidef_set_led_wlan "wlan2g" "WLAN2G" "${boardname}:green:wlan2G" "phy0tpt" - ucidef_set_led_wlan "wlan5g" "WLAN5G" "${boardname}:green:wlan5G" "phy1tpt" - ucidef_set_led_netdev "lan1" "LAN1" "${boardname}:green:lan1" "eth0" - ucidef_set_led_netdev "lan2" "LAN2" "${boardname}:green:lan2" "eth1" + ucidef_set_led_wlan "wlan2g" "WLAN2G" "green:wlan2g" "phy0tpt" + ucidef_set_led_wlan "wlan5g" "WLAN5G" "green:wlan5g" "phy1tpt" + ucidef_set_led_netdev "lan1" "LAN1" "green:lan1" "eth0" + ucidef_set_led_netdev "lan2" "LAN2" "green:lan2" "eth1" ;; pangu,l1000) ucidef_set_led_default "power" "POWER" "${boardname}:blue:power" "1" @@ -60,34 +53,35 @@ ucidef_set_led_wlan "wlan5g" "WLAN5G" "${boardname}:blue:wlan5g" "phy1tpt" ucidef_set_led_switch "wan" "WAN" "${boardname}:blue:wan" "switch0" "0x20" ;; mobipromo,cm520-79f) - ucidef_set_led_netdev "wan" "WAN" "${boardname}:blue:wan" "eth1" - ucidef_set_led_switch "lan1" "LAN1" "${boardname}:blue:lan1" "switch0" "0x10" - ucidef_set_led_switch "lan2" "LAN2" "${boardname}:blue:lan2" "switch0" "0x08" + ucidef_set_led_netdev "wan" "WAN" "blue:wan" "eth1" + ucidef_set_led_switch "lan1" "LAN1" "blue:lan1" "switch0" "0x10" + ucidef_set_led_switch "lan2" "LAN2" "blue:lan2" "switch0" "0x08" + ;; +pangu,l1000) + ucidef_set_led_default "power" "POWER" "blue:power" "1" + ucidef_set_led_wlan "wlan2g" "WLAN2G" "blue:wlan2g" "phy0tpt" + ucidef_set_led_wlan "wlan5g" "WLAN5G" "blue:wlan5g" "phy1tpt" + ucidef_set_led_netdev "wan" "WAN" "blue:wan" "eth1" + ;; +p2w,r619ac |\ +p2w,r619ac-128m) + ucidef_set_led_wlan "wlan2g" "WLAN2G" "blue:wlan2g" "phy0tpt" + ucidef_set_led_wlan "wlan5g" "WLAN5G" "blue:wlan5g" "phy1tpt" ;; netgear,ex6100v2 |\ netgear,ex6150v2) - ucidef_set_led_wlan "wlan2g" "WLAN2G" "ex61x0v2:green:router" "phy0tpt" - ucidef_set_led_wlan "wlan5g" "WLAN5G" "ex61x0v2:green:client" "phy1tpt" - ;; -p2w,r619ac |\ -p2w,r619ac-128m) - ucidef_set_led_wlan "wlan2g" "WLAN2G" "r619ac:blue:wlan2g" "phy0tpt" - ucidef_set_led_wlan "wlan5g" "WLAN5G" "r619ac:blue:wlan5g" "phy1tpt" + ucidef_set_led_wlan "wlan2g" "WLAN2G" "green:router" "phy0tpt" + ucidef_set_led_wlan "wlan5g" "WLAN5G" "green:client" "phy1tpt" ;; qxwlan,e2600ac-c1 |\ qxwlan,e2600ac-c2) - ucidef_set_led_wlan "wlan2g" "WLAN0" "e2600ac:green:wlan0" "phy0tpt" - ucidef_set_led_wlan "wlan5g" "WLAN1" "e2600ac:green:wlan1" "phy1tpt" - ;; -zyxel,nbg6617) - ucidef_set_led_wlan "wlan2g" "WLAN2G" "${boardname}:green:wlan2G" "phy0tpt" - ucidef_set_led_wlan "wlan5g" "WLAN5G" "${boardname}:green:wlan5G" "phy1tpt" + ucidef_set_led_wlan "wlan2g" "WLAN0" "green:wlan0" "phy0tpt" + ucidef_set_led_wlan "wlan5g" "WLAN1" "green:wlan1" "phy1tpt" ;; +zyxel,nbg6617 |\ zyxel,wre6606) - ucidef_set_led_wlan "wlan2g" "WLAN2G" "${boardname}:green:wlan2g" "phy0tpt" - ucidef_set_led_wlan "wlan5g" "WLAN5G" "${boardname}:green:wlan5g" "phy1tpt" - ;; -*) + ucidef_set_led_wlan "wlan2g" "WLAN2G" "green:wlan2g" "phy0tpt" + ucidef_set_led_wlan "wlan5g" "WLAN5G" "green:wlan5g" "phy1tpt" ;; esac diff --git a/root/target/linux/ipq40xx/base-files/etc/board.d/02_network b/root/target/linux/ipq40xx/base-files/etc/board.d/02_network index f49f224e..3ffab649 100755 --- a/root/target/linux/ipq40xx/base-files/etc/board.d/02_network +++ b/root/target/linux/ipq40xx/base-files/etc/board.d/02_network @@ -16,7 +16,10 @@ ipq40xx_setup_interfaces() 8dev,jalapeno|\ alfa-network,ap120c-ac|\ engenius,emr3500|\ - engenius,ens620ext) + engenius,ens620ext|\ + luma,wrtq-329acn|\ + plasmacloud,pa1200|\ + plasmacloud,pa2200) ucidef_set_interfaces_lan_wan "eth0" "eth1" ;; aruba,ap-303|\ @@ -38,22 +41,25 @@ ipq40xx_setup_interfaces() ;; asus,map-ac2200|\ cilab,meshpoint-one|\ + edgecore,ecw5211|\ + edgecore,oap100|\ openmesh,a42|\ openmesh,a62) ucidef_set_interfaces_lan_wan "eth1" "eth0" ;; asus,rt-ac58u|\ - p2w,r619ac-128m|\ - p2w,r619ac|\ - zyxel,nbg6617) + zyxel,nbg6617)|\ + p2w,r619ac-128m)|\ + p2w,r619ac) ucidef_set_interfaces_lan_wan "eth0" "eth1" ucidef_add_switch "switch0" \ "0u@eth0" "1:lan:4" "2:lan:3" "3:lan:2" "4:lan:1" ;; avm,fritzbox-4040|\ linksys,ea6350v3|\ - pangu,l1000|\ - linksys,ea8300) + linksys,ea8300|\ + pangu,l1000|\ + linksys,mr8300) ucidef_set_interfaces_lan_wan "eth0" "eth1" ucidef_add_switch "switch0" \ "0u@eth0" "1:lan" "2:lan" "3:lan" "4:lan" @@ -62,7 +68,10 @@ ipq40xx_setup_interfaces() ucidef_add_switch "switch0" \ "0u@eth0" "1:lan" "2:lan" "3:lan" "4:lan" ;; - avm,fritzrepeater-3000|\ + avm,fritzrepeater-3000) + ucidef_add_switch "switch0" \ + "0u@eth0" "4:lan:1" "5:lan:2" + ;; compex,wpj419|\ compex,wpj428|\ engenius,eap2200) @@ -78,6 +87,9 @@ ipq40xx_setup_interfaces() ucidef_add_switch "switch0" \ "0u@eth0" "3:lan" "4:lan" ;; + devolo,magic-2-wifi-next) + ucidef_set_interface_lan "eth0 eth1 eth2" + ;; ezviz,cs-w3-wd1200g-eup) ucidef_set_interfaces_lan_wan "eth0" "eth1" ucidef_add_switch "switch0" \ @@ -133,6 +145,10 @@ ipq40xx_setup_macs() cilab,meshpoint-one) label_mac=$(mtd_get_mac_binary "ART" 0x1006) ;; + devolo,magic-2-wifi-next) + lan_mac=$(mtd_get_mac_ascii APPSBLENV MacAddress0) + label_mac=$lan_mac + ;; dlink,dap-2610) lan_mac=$(mtd_get_mac_ascii bdcfg lanmac) label_mac=$lan_mac @@ -171,4 +187,4 @@ ipq40xx_setup_interfaces $board ipq40xx_setup_macs $board board_config_flush -exit 0 +exit 0 \ No newline at end of file diff --git a/root/target/linux/ipq40xx/base-files/etc/board.d/03_gpio_switches b/root/target/linux/ipq40xx/base-files/etc/board.d/03_gpio_switches old mode 100644 new mode 100755 diff --git a/root/target/linux/ipq40xx/base-files/etc/hotplug.d/firmware/11-ath10k-caldata b/root/target/linux/ipq40xx/base-files/etc/hotplug.d/firmware/11-ath10k-caldata index 22fbf2db..003734d0 100644 --- a/root/target/linux/ipq40xx/base-files/etc/hotplug.d/firmware/11-ath10k-caldata +++ b/root/target/linux/ipq40xx/base-files/etc/hotplug.d/firmware/11-ath10k-caldata @@ -36,14 +36,20 @@ case "$FIRMWARE" in ath10k_patch_mac $(mtd_get_mac_binary ORGDATA 0x32) ;; engenius,eap2200 |\ - openmesh,a62) + openmesh,a62 |\ + plasmacloud,pa2200) caldata_extract "0:ART" 0x9000 0x2f20 ;; - linksys,ea8300) + linksys,ea8300 |\ + linksys,mr8300) caldata_extract "ART" 0x9000 0x2f20 # OEM assigns 4 sequential MACs ath10k_patch_mac $(macaddr_setbit_la $(macaddr_add "$(cat /sys/class/net/eth0/address)" 4)) ;; + pangu,l1000) + caldata_extract "ART" 0x5000 0x2f20 + ath10k_patch_mac $(macaddr_add "$(cat /sys/class/net/eth0/address)" 3) + ;; esac ;; "ath10k/pre-cal-ahb-a000000.wifi.bin") @@ -57,7 +63,7 @@ case "$FIRMWARE" in glinet,gl-s1300 |\ linksys,ea6350v3 |\ mobipromo,cm520-79f |\ - p2w,r619ac-128m |\ + p2w,r619ac-128m |\ p2w,r619ac |\ qcom,ap-dk01.1-c1) caldata_extract "ART" 0x1000 0x2f20 @@ -95,15 +101,24 @@ case "$FIRMWARE" in cellc,rtl30vw |\ compex,wpj419 |\ compex,wpj428 |\ + edgecore,ecw5211 |\ + edgecore,oap100 |\ engenius,eap1300 |\ engenius,eap2200 |\ + luma,wrtq-329acn|\ openmesh,a42 |\ openmesh,a62 |\ + plasmacloud,pa1200 |\ + plasmacloud,pa2200 |\ qxwlan,e2600ac-c1 |\ qxwlan,e2600ac-c2 |\ unielec,u4019-32m) caldata_extract "0:ART" 0x1000 0x2f20 ;; + devolo,magic-2-wifi-next) + caldata_extract "ART" 0x1000 0x2f20 + ath10k_patch_mac $(mtd_get_mac_ascii APPSBLENV WiFiMacAddress0) + ;; dlink,dap-2610) caldata_extract "ART" 0x1000 0x2f20 ath10k_patch_mac $(mtd_get_mac_ascii bdcfg wlanmac) @@ -120,7 +135,8 @@ case "$FIRMWARE" in caldata_extract "ART" 0x1000 0x2f20 ath10k_patch_mac $(macaddr_add $(mtd_get_mac_ascii u-boot-env ethaddr) +2) ;; - linksys,ea8300) + linksys,ea8300 |\ + linksys,mr8300) caldata_extract "ART" 0x1000 0x2f20 ath10k_patch_mac $(macaddr_add "$(cat /sys/class/net/eth0/address)" 2) ;; @@ -155,9 +171,9 @@ case "$FIRMWARE" in glinet,gl-b1300 |\ glinet,gl-s1300 |\ linksys,ea6350v3 |\ - mobipromo,cm520-79f |\ - p2w,r619ac-128m |\ + p2w,r619ac-128m |\ p2w,r619ac |\ + mobipromo,cm520-79f |\ qcom,ap-dk01.1-c1) caldata_extract "ART" 0x5000 0x2f20 ;; @@ -194,15 +210,24 @@ case "$FIRMWARE" in cellc,rtl30vw |\ compex,wpj419 |\ compex,wpj428 |\ + edgecore,ecw5211 |\ + edgecore,oap100 |\ engenius,eap1300 |\ engenius,eap2200 |\ + luma,wrtq-329acn|\ openmesh,a42 |\ openmesh,a62 |\ + plasmacloud,pa1200 |\ + plasmacloud,pa2200 |\ qxwlan,e2600ac-c1 |\ qxwlan,e2600ac-c2 |\ unielec,u4019-32m) caldata_extract "0:ART" 0x5000 0x2f20 ;; + devolo,magic-2-wifi-next) + caldata_extract "ART" 0x5000 0x2f20 + ath10k_patch_mac $(mtd_get_mac_ascii APPSBLENV WiFiMacAddress1) + ;; dlink,dap-2610) caldata_extract "ART" 0x5000 0x2f20 ath10k_patch_mac $(mtd_get_mac_ascii bdcfg wlanmac_a) @@ -219,14 +244,15 @@ case "$FIRMWARE" in caldata_extract "ART" 0x5000 0x2f20 ath10k_patch_mac $(macaddr_add $(mtd_get_mac_ascii u-boot-env ethaddr) +3) ;; - linksys,ea8300) + linksys,ea8300 |\ + linksys,mr8300) caldata_extract "ART" 0x5000 0x2f20 ath10k_patch_mac $(macaddr_add "$(cat /sys/class/net/eth0/address)" 3) ;; - pangu,l1000) - caldata_extract "ART" 0x5000 0x2f20 - th10k_patch_mac $(macaddr_add "$(cat /sys/class/net/eth0/address)" 3) - ;; + pangu,l1000) + caldata_extract "ART" 0x1000 0x2f20 + ath10k_patch_mac $(macaddr_add "$(cat /sys/class/net/eth0/address)" 2) + ;; meraki,mr33) caldata_extract_ubi "ART" 0x5000 0x2f20 caldata_valid "202f" || caldata_extract "ART" 0x5000 0x2f20 @@ -247,4 +273,4 @@ case "$FIRMWARE" in *) exit 1 ;; -esac +esac \ No newline at end of file diff --git a/root/target/linux/ipq40xx/base-files/etc/hotplug.d/net/21_adjust_network b/root/target/linux/ipq40xx/base-files/etc/hotplug.d/net/21_adjust_network old mode 100644 new mode 100755 diff --git a/root/target/linux/ipq40xx/base-files/etc/init.d/bootcount b/root/target/linux/ipq40xx/base-files/etc/init.d/bootcount old mode 100644 new mode 100755 diff --git a/root/target/linux/ipq40xx/base-files/etc/inittab b/root/target/linux/ipq40xx/base-files/etc/inittab new file mode 100755 index 00000000..3181021a --- /dev/null +++ b/root/target/linux/ipq40xx/base-files/etc/inittab @@ -0,0 +1,5 @@ +# Copyright (c) 2013 The Linux Foundation. All rights reserved. +::sysinit:/etc/init.d/rcS S boot +::shutdown:/etc/init.d/rcS K shutdown +ttyMSM0::askfirst:/usr/libexec/login.sh +ttyMSM1::askfirst:/usr/libexec/login.sh diff --git a/root/target/linux/ipq40xx/base-files/etc/uci-defaults/04_led_migration b/root/target/linux/ipq40xx/base-files/etc/uci-defaults/04_led_migration new file mode 100755 index 00000000..c4f82b35 --- /dev/null +++ b/root/target/linux/ipq40xx/base-files/etc/uci-defaults/04_led_migration @@ -0,0 +1,19 @@ +. /lib/functions/migrations.sh + +board=$(board_name) + +case "$board" in +engenius,emr3500) + migrate_leds "emr3500:=" + ;; +engenius,ens620ext|\ +zyxel,nbg6617) + migrate_leds ":wlan2G=:wlan2g" ":wlan5G=:wlan5g" + ;; +esac + +remove_devicename_leds + +migrations_apply system + +exit 0 diff --git a/root/target/linux/ipq40xx/base-files/lib/preinit/05_set_iface_mac_ipq40xx.sh b/root/target/linux/ipq40xx/base-files/lib/preinit/05_set_iface_mac_ipq40xx.sh old mode 100644 new mode 100755 index d769f39e..b1e814cb --- a/root/target/linux/ipq40xx/base-files/lib/preinit/05_set_iface_mac_ipq40xx.sh +++ b/root/target/linux/ipq40xx/base-files/lib/preinit/05_set_iface_mac_ipq40xx.sh @@ -7,12 +7,6 @@ preinit_set_mac_address() { ip link set dev eth0 address $(macaddr_add "$base_mac" +1) ip link set dev eth1 address $(macaddr_add "$base_mac" +3) ;; - asus,rt-acrh17|\ - asus,rt-ac58u) - CI_UBIPART=UBI_DEV - base_mac=$(mtd_get_mac_binary_ubi Factory 4102) - ip link set dev eth0 address $(macaddr_add "$base_mac" +1) - ;; ezviz,cs-w3-wd1200g-eup) ip link set dev eth0 address $(mtd_get_mac_binary "ART" 0x6) ip link set dev eth1 address $(mtd_get_mac_binary "ART" 0x0) @@ -21,7 +15,8 @@ preinit_set_mac_address() { base_mac=$(cat /sys/class/net/eth0/address) ip link set dev eth1 address $(macaddr_add "${base_mac}" +1) ;; - linksys,ea8300) + linksys,ea8300|\ + linksys,mr8300) base_mac=$(mtd_get_mac_ascii devinfo hw_mac_addr) ip link set dev eth0 address "${base_mac}" ip link set dev eth1 address $(macaddr_add "${base_mac}" 1) diff --git a/root/target/linux/ipq40xx/base-files/lib/preinit/06_set_preinit_iface_ipq40xx.sh b/root/target/linux/ipq40xx/base-files/lib/preinit/06_set_preinit_iface_ipq40xx.sh old mode 100644 new mode 100755 index 5ca17622..5f476051 --- a/root/target/linux/ipq40xx/base-files/lib/preinit/06_set_preinit_iface_ipq40xx.sh +++ b/root/target/linux/ipq40xx/base-files/lib/preinit/06_set_preinit_iface_ipq40xx.sh @@ -8,11 +8,13 @@ set_preinit_iface() { ezviz,cs-w3-wd1200g-eup| \ glinet,gl-b1300| \ linksys,ea8300| \ + linksys,mr8300| \ meraki,mr33| \ zyxel,nbg6617) ifname=eth0 ;; - *) + devolo,magic-2-wifi-next) + ifname=eth1 ;; esac } diff --git a/root/target/linux/ipq40xx/base-files/lib/upgrade/linksys.sh b/root/target/linux/ipq40xx/base-files/lib/upgrade/linksys.sh new file mode 100755 index 00000000..c7ee381f --- /dev/null +++ b/root/target/linux/ipq40xx/base-files/lib/upgrade/linksys.sh @@ -0,0 +1,122 @@ +linksys_get_target_firmware() { + local cur_boot_part mtd_ubi0 + + cur_boot_part="$(/usr/sbin/fw_printenv -n boot_part)" + if [ -z "${cur_boot_part}" ]; then + mtd_ubi0=$(cat /sys/devices/virtual/ubi/ubi0/mtd_num) + case "$(grep -E "^mtd${mtd_ubi0}:" /proc/mtd | cut -d '"' -f 2)" in + kernel|rootfs) + cur_boot_part=1 + ;; + alt_kernel|alt_rootfs) + cur_boot_part=2 + ;; + esac + >&2 printf "Current boot_part='%s' selected from ubi0/mtd_num='%s'" \ + "${cur_boot_part}" "${mtd_ubi0}" + fi + + # OEM U-Boot for EA6350v3, EA8300 and MR8300; bootcmd= + # if test $auto_recovery = no; + # then bootipq; + # elif test $boot_part = 1; + # then run bootpart1; + # else run bootpart2; + # fi + + case "$cur_boot_part" in + 1) + fw_setenv -s - <<-EOF + boot_part 2 + auto_recovery yes + EOF + printf "alt_kernel" + return + ;; + 2) + fw_setenv -s - <<-EOF + boot_part 1 + auto_recovery yes + EOF + printf "kernel" + return + ;; + *) + return + ;; + esac +} + +linksys_get_root_magic() { + (get_image "$@" | dd skip=786432 bs=4 count=1 | hexdump -v -n 4 -e '1/1 "%02x"') 2>/dev/null +} + +platform_do_upgrade_linksys() { + local magic_long="$(get_magic_long "$1")" + + local rm_oem_fw_vols="squashfs ubifs" # from OEM [alt_]rootfs UBI + local vol + + mkdir -p /var/lock + local part_label="$(linksys_get_target_firmware)" + touch /var/lock/fw_printenv.lock + + if [ -z "$part_label" ]; then + echo "cannot find target partition" + exit 1 + fi + + local target_mtd=$(find_mtd_part "$part_label") + + [ "$magic_long" = "73797375" ] && { + CI_KERNPART="$part_label" + if [ "$part_label" = "kernel" ]; then + CI_UBIPART="rootfs" + else + CI_UBIPART="alt_rootfs" + fi + + local mtdnum="$(find_mtd_index "$CI_UBIPART")" + if [ ! "$mtdnum" ]; then + echo "cannot find ubi mtd partition $CI_UBIPART" + return 1 + fi + + local ubidev="$(nand_find_ubi "$CI_UBIPART")" + if [ ! "$ubidev" ]; then + ubiattach -m "$mtdnum" + sync + ubidev="$(nand_find_ubi "$CI_UBIPART")" + fi + + if [ "$ubidev" ]; then + for vol in $rm_oem_fw_vols; do + ubirmvol "/dev/$ubidev" -N "$vol" 2>/dev/null + done + fi + + # complete std upgrade + nand_upgrade_tar "$1" + } + + [ "$magic_long" = "27051956" ] && { + # This magic is for a uImage (which is a sysupgrade image) + # check firmwares' rootfs types + local oldroot="$(linksys_get_root_magic "$target_mtd")" + local newroot="$(linksys_get_root_magic "$1")" + + if [ "$newroot" = "55424923" ] && [ "$oldroot" = "55424923" ]; then + # we're upgrading from a firmware with UBI to one with UBI + # erase everything to be safe + # - Is that really needed? Won't remove (or comment) the if, + # because it may be needed in a future device. + #mtd erase $part_label + #get_image "$1" | mtd -n write - $part_label + echo "writing \"$1\" UBI image to \"$part_label\" (UBI)..." + get_image "$1" | mtd write - "$part_label" + else + echo "writing \"$1\" image to \"$part_label\"" + get_image "$1" | mtd write - "$part_label" + fi + } +} \ No newline at end of file diff --git a/root/target/linux/ipq40xx/base-files/lib/upgrade/openmesh.sh b/root/target/linux/ipq40xx/base-files/lib/upgrade/openmesh.sh new file mode 100755 index 00000000..8e02186e --- /dev/null +++ b/root/target/linux/ipq40xx/base-files/lib/upgrade/openmesh.sh @@ -0,0 +1,106 @@ +# The U-Boot loader of the OpenMesh devices requires image sizes and +# checksums to be provided in the U-Boot environment. +# The OpenMesh devices come with 2 main partitions - while one is active +# sysupgrade will flash the other. The boot order is changed to boot the +# newly flashed partition. If the new partition can't be booted due to +# upgrade failures the previously used partition is loaded. + +platform_do_upgrade_openmesh() { + local tar_file="$1" + local restore_backup + local primary_kernel_mtd + + local setenv_script="/tmp/fw_env_upgrade" + + local kernel_mtd="$(find_mtd_index $PART_NAME)" + local kernel_offset="$(cat /sys/class/mtd/mtd${kernel_mtd}/offset)" + local total_size="$(cat /sys/class/mtd/mtd${kernel_mtd}/size)" + + # detect to which flash region the new image is written to. + # + # 1. check what is the mtd index for the first flash region on this + # device + # 2. check if the target partition ("inactive") has the mtd index of + # the first flash region + # + # - when it is: the new bootseq will be 1,2 and the first region is + # modified + # - when it isnt: bootseq will be 2,1 and the second region is + # modified + # + # The detection has to be done via the hardcoded mtd partition because + # the current boot might be done with the fallback region. Let us + # assume that the current bootseq is 1,2. The bootloader detected that + # the image in flash region 1 is corrupt and thus switches to flash + # region 2. The bootseq in the u-boot-env is now still the same and + # the sysupgrade code can now only rely on the actual mtd indexes and + # not the bootseq variable to detect the currently booted flash + # region/image. + # + # In the above example, an implementation which uses bootseq ("1,2") to + # detect the currently booted image would assume that region 1 is booted + # and then overwrite the variables for the wrong flash region (aka the + # one which isn't modified). This could result in a device which doesn't + # boot anymore to Linux until it was reflashed with ap51-flash. + local next_boot_part="1" + case "$(board_name)" in + openmesh,a42) + primary_kernel_mtd=8 + ;; + openmesh,a62) + primary_kernel_mtd=10 + ;; + *) + echo "failed to detect primary kernel mtd partition for board" + return 1 + ;; + esac + [ "$kernel_mtd" = "$primary_kernel_mtd" ] || next_boot_part="2" + + 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) + local rootfs_length=$(tar xf $tar_file ${board_dir}/root -O | wc -c) + # rootfs without EOF marker + rootfs_length=$((rootfs_length-4)) + + local kernel_md5=$(tar xf $tar_file ${board_dir}/kernel -O | md5sum); kernel_md5="${kernel_md5%% *}" + # md5 checksum of rootfs with EOF marker + local rootfs_md5=$(tar xf $tar_file ${board_dir}/root -O | dd bs=1 count=$rootfs_length | md5sum); rootfs_md5="${rootfs_md5%% *}" + + # + # add tar support to get_image() to use default_do_upgrade() instead? + # + + # take care of restoring a saved config + [ -n "$UPGRADE_BACKUP" ] && restore_backup="${MTD_CONFIG_ARGS} -j ${UPGRADE_BACKUP}" + + mtd -q erase inactive + tar xf $tar_file ${board_dir}/root -O | mtd -n -p $kernel_length $restore_backup write - $PART_NAME + tar xf $tar_file ${board_dir}/kernel -O | mtd -n write - $PART_NAME + + # prepare new u-boot env + if [ "$next_boot_part" = "1" ]; then + echo "bootseq 1,2" > $setenv_script + else + echo "bootseq 2,1" > $setenv_script + fi + + printf "kernel_size_%i 0x%08x\n" $next_boot_part $kernel_length >> $setenv_script + printf "vmlinux_start_addr 0x%08x\n" ${kernel_offset} >> $setenv_script + printf "vmlinux_size 0x%08x\n" ${kernel_length} >> $setenv_script + printf "vmlinux_checksum %s\n" ${kernel_md5} >> $setenv_script + + printf "rootfs_size_%i 0x%08x\n" $next_boot_part $((total_size-kernel_length)) >> $setenv_script + printf "rootfs_start_addr 0x%08x\n" $((kernel_offset+kernel_length)) >> $setenv_script + printf "rootfs_size 0x%08x\n" ${rootfs_length} >> $setenv_script + printf "rootfs_checksum %s\n" ${rootfs_md5} >> $setenv_script + + # store u-boot env changes + mkdir -p /var/lock + fw_setenv -s $setenv_script || { + echo "failed to update U-Boot environment" + return 1 + } +} diff --git a/root/target/linux/ipq40xx/base-files/lib/upgrade/platform.sh b/root/target/linux/ipq40xx/base-files/lib/upgrade/platform.sh index 66fd2c50..3a5b8218 100644 --- a/root/target/linux/ipq40xx/base-files/lib/upgrade/platform.sh +++ b/root/target/linux/ipq40xx/base-files/lib/upgrade/platform.sh @@ -4,141 +4,28 @@ REQUIRE_IMAGE_METADATA=1 RAMFS_COPY_BIN='fw_printenv fw_setenv' RAMFS_COPY_DATA='/etc/fw_env.config /var/lock/fw_printenv.lock' -ubi_kill_if_exist() { - local ubidev="$( nand_find_ubi "$CI_UBIPART" )" - local c_ubivol="$( nand_find_volume $ubidev $1 )" - umount -f /dev/$c_ubivol 2>/dev/null - [ "$c_ubivol" ] && ubirmvol /dev/$ubidev -N $1 || true - echo "Partition $1 removed." -} - -# idea from @981213 -# Tar sysupgrade for ASUS RT-AC82U/RT-AC58U -# An ubi repartition is required due to the strange partition table created by Asus. -# We create all the factory partitions to make sure that the U-boot tftp recovery still works. -# The reserved kernel partition size should be enough to put the factory image in. -asus_nand_upgrade_tar() { - local kpart_size="$1" - local tar_file="$2" - - 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` - - local mtdnum="$( find_mtd_index "$CI_UBIPART" )" - if [ ! "$mtdnum" ]; then - echo "cannot find ubi mtd partition $CI_UBIPART" - return 1 - fi - - local ubidev="$( nand_find_ubi "$CI_UBIPART" )" - if [ ! "$ubidev" ]; then - ubiattach -m "$mtdnum" - sync - ubidev="$( nand_find_ubi "$CI_UBIPART" )" - fi - - if [ ! "$ubidev" ]; then - echo "cannot find ubi device $CI_UBIPART" - return 1 - fi - - local root_ubivol="$( nand_find_volume $ubidev rootfs )" - # 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; - fi - fi - - ubi_kill_if_exist rootfs_data - ubi_kill_if_exist rootfs - ubi_kill_if_exist jffs2 - ubi_kill_if_exist linux2 - ubi_kill_if_exist linux - - ubimkvol /dev/$ubidev -N linux -s $kpart_size - ubimkvol /dev/$ubidev -N linux2 -s $kpart_size - ubimkvol /dev/$ubidev -N jffs2 -s 2539520 - ubimkvol /dev/$ubidev -N rootfs -s $rootfs_length - ubimkvol /dev/$ubidev -N rootfs_data -m - - local kern_ubivol="$(nand_find_volume $ubidev $CI_KERNPART)" - echo "Kernel at $kern_ubivol.Writing..." - tar xf $tar_file ${board_dir}/kernel -O | \ - ubiupdatevol /dev/$kern_ubivol -s $kernel_length - - echo "Done." - - local root_ubivol="$(nand_find_volume $ubidev rootfs)" - echo "Rootfs at $root_ubivol.Writing..." - tar xf $tar_file ${board_dir}/root -O | \ - ubiupdatevol /dev/$root_ubivol -s $rootfs_length - - echo "Done." - - nand_do_upgrade_success -} - -# idea from @981213 -# Factory image sysupgrade for ASUS RT-AC82U/RT-AC58U -# Delete all the partitions we created before, create "linux" partition and write factory image in. -# Skip the first 64bytes which is an uImage header to verify the firmware. -# The kernel partition size should be the original one. -asus_nand_upgrade_factory() { - local kpart_size="$1" - local fw_file="$2" - - local mtdnum="$( find_mtd_index "$CI_UBIPART" )" - if [ ! "$mtdnum" ]; then - echo "cannot find ubi mtd partition $CI_UBIPART" - return 1 - fi - - local ubidev="$( nand_find_ubi "$CI_UBIPART" )" - if [ ! "$ubidev" ]; then - ubiattach -m "$mtdnum" - sync - ubidev="$( nand_find_ubi "$CI_UBIPART" )" - fi - - if [ ! "$ubidev" ]; then - echo "cannot find ubi device $CI_UBIPART" - return 1 - fi - - local root_ubivol="$( nand_find_volume $ubidev rootfs )" - # 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; - fi - fi - - ubi_kill_if_exist rootfs_data - ubi_kill_if_exist rootfs - ubi_kill_if_exist jffs2 - ubi_kill_if_exist linux2 - ubi_kill_if_exist linux - - ubimkvol /dev/$ubidev -N linux -s $kpart_size - - local kern_ubivol="$(nand_find_volume $ubidev $CI_KERNPART)" - echo "Asus linux at $kern_ubivol.Writing..." - ubiupdatevol /dev/$kern_ubivol --skip=64 $fw_file - echo "Done." - - umount -a - reboot -f -} - platform_check_image() { + case "$(board_name)" in + asus,rt-ac58u) + CI_UBIPART="UBI_DEV" + local ubidev=$(nand_find_ubi $CI_UBIPART) + local asus_root=$(nand_find_volume $ubidev jffs2) + + [ -n "$asus_root" ] || return 0 + + cat << EOF +jffs2 partition is still present. +There's probably no space left +to install the filesystem. + +You need to delete the jffs2 partition first: +# ubirmvol /dev/ubi0 --name=jffs2 + +Once this is done. Retry. +EOF + return 1 + ;; + esac return 0; } @@ -178,8 +65,12 @@ platform_do_upgrade() { avm,fritzbox-7530 |\ avm,fritzrepeater-1200 |\ avm,fritzrepeater-3000 |\ + buffalo,wtr-m2133hp |\ cilab,meshpoint-one |\ + edgecore,ecw5211 |\ + edgecore,oap100 |\ engenius,eap2200 |\ + luma,wrtq-329acn |\ mobipromo,cm520-79f |\ qxwlan,e2600ac-c2) nand_do_upgrade "$1" @@ -199,29 +90,21 @@ platform_do_upgrade() { CI_KERNPART="linux" nand_do_upgrade "$1" ;; - asus,rt-acrh17|\ asus,rt-ac58u) - local magic=$(get_magic_long "$1") CI_UBIPART="UBI_DEV" CI_KERNPART="linux" - if [ "$magic" == "27051956" ]; then - echo "Got Asus factory image." - asus_nand_upgrade_factory 50409472 "$1" - else - asus_nand_upgrade_tar 20951040 "$1" - fi + nand_do_upgrade "$1" ;; cellc,rtl30vw) CI_UBIPART="ubifs" askey_do_upgrade "$1" ;; - compex,wpj419|\ - p2w,r619ac-128m|\ - p2w,r619ac) + compex,wpj419) nand_do_upgrade "$1" ;; linksys,ea6350v3 |\ - linksys,ea8300) + linksys,ea8300 |\ + linksys,mr8300) platform_do_upgrade_linksys "$1" ;; meraki,mr33) @@ -229,9 +112,11 @@ platform_do_upgrade() { nand_do_upgrade "$1" ;; openmesh,a42 |\ - openmesh,a62) + openmesh,a62 |\ + plasmacloud,pa1200 |\ + plasmacloud,pa2200) PART_NAME="inactive" - platform_do_upgrade_openmesh "$1" + platform_do_upgrade_dualboot_datachk "$1" ;; zyxel,nbg6617) zyxel_do_upgrade "$1" diff --git a/root/target/linux/ipq40xx/files-5.4/drivers/net/ethernet/qualcomm/essedma/Makefile b/root/target/linux/ipq40xx/files-5.4/drivers/net/ethernet/qualcomm/essedma/Makefile deleted file mode 100644 index 4e6cd650..00000000 --- a/root/target/linux/ipq40xx/files-5.4/drivers/net/ethernet/qualcomm/essedma/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -# -## Makefile for the Qualcomm Atheros ethernet edma driver -# - - -obj-$(CONFIG_ESSEDMA) += essedma.o - -essedma-objs := edma_axi.o edma.o edma_ethtool.o - diff --git a/root/target/linux/ipq40xx/files-5.4/drivers/net/ethernet/qualcomm/essedma/edma.c b/root/target/linux/ipq40xx/files-5.4/drivers/net/ethernet/qualcomm/essedma/edma.c deleted file mode 100644 index 5561cc23..00000000 --- a/root/target/linux/ipq40xx/files-5.4/drivers/net/ethernet/qualcomm/essedma/edma.c +++ /dev/null @@ -1,2177 +0,0 @@ -/* - * Copyright (c) 2014 - 2016, The Linux Foundation. All rights reserved. - * - * Permission to use, copy, modify, and/or distribute this software for - * any purpose with or without fee is hereby granted, provided that the - * above copyright notice and this permission notice appear in all copies. - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT - * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include -#include -#include "ess_edma.h" -#include "edma.h" - -extern struct net_device *edma_netdev[EDMA_MAX_PORTID_SUPPORTED]; -bool edma_stp_rstp; -u16 edma_ath_eth_type; - -/* edma_skb_priority_offset() - * get edma skb priority - */ -static unsigned int edma_skb_priority_offset(struct sk_buff *skb) -{ - return (skb->priority >> 2) & 1; -} - -/* edma_alloc_tx_ring() - * Allocate Tx descriptors ring - */ -static int edma_alloc_tx_ring(struct edma_common_info *edma_cinfo, - struct edma_tx_desc_ring *etdr) -{ - struct platform_device *pdev = edma_cinfo->pdev; - - /* Initialize ring */ - etdr->size = sizeof(struct edma_sw_desc) * etdr->count; - etdr->sw_next_to_fill = 0; - etdr->sw_next_to_clean = 0; - - /* Allocate SW descriptors */ - etdr->sw_desc = vzalloc(etdr->size); - if (!etdr->sw_desc) { - dev_err(&pdev->dev, "buffer alloc of tx ring failed=%p", etdr); - return -ENOMEM; - } - - /* Allocate HW descriptors */ - etdr->hw_desc = dma_alloc_coherent(&pdev->dev, etdr->size, &etdr->dma, - GFP_KERNEL); - if (!etdr->hw_desc) { - dev_err(&pdev->dev, "descriptor allocation for tx ring failed"); - vfree(etdr->sw_desc); - return -ENOMEM; - } - - return 0; -} - -/* edma_free_tx_ring() - * Free tx rings allocated by edma_alloc_tx_rings - */ -static void edma_free_tx_ring(struct edma_common_info *edma_cinfo, - struct edma_tx_desc_ring *etdr) -{ - struct platform_device *pdev = edma_cinfo->pdev; - - if (likely(etdr->dma)) - dma_free_coherent(&pdev->dev, etdr->size, etdr->hw_desc, - etdr->dma); - - vfree(etdr->sw_desc); - etdr->sw_desc = NULL; -} - -/* edma_alloc_rx_ring() - * allocate rx descriptor ring - */ -static int edma_alloc_rx_ring(struct edma_common_info *edma_cinfo, - struct edma_rfd_desc_ring *erxd) -{ - struct platform_device *pdev = edma_cinfo->pdev; - - erxd->size = sizeof(struct edma_sw_desc) * erxd->count; - erxd->sw_next_to_fill = 0; - erxd->sw_next_to_clean = 0; - - /* Allocate SW descriptors */ - erxd->sw_desc = vzalloc(erxd->size); - if (!erxd->sw_desc) - return -ENOMEM; - - /* Alloc HW descriptors */ - erxd->hw_desc = dma_alloc_coherent(&pdev->dev, erxd->size, &erxd->dma, - GFP_KERNEL); - if (!erxd->hw_desc) { - vfree(erxd->sw_desc); - return -ENOMEM; - } - - /* Initialize pending_fill */ - erxd->pending_fill = 0; - - return 0; -} - -/* edma_free_rx_ring() - * Free rx ring allocated by alloc_rx_ring - */ -static void edma_free_rx_ring(struct edma_common_info *edma_cinfo, - struct edma_rfd_desc_ring *rxdr) -{ - struct platform_device *pdev = edma_cinfo->pdev; - - if (likely(rxdr->dma)) - dma_free_coherent(&pdev->dev, rxdr->size, rxdr->hw_desc, - rxdr->dma); - - vfree(rxdr->sw_desc); - rxdr->sw_desc = NULL; -} - -/* edma_configure_tx() - * Configure transmission control data - */ -static void edma_configure_tx(struct edma_common_info *edma_cinfo) -{ - u32 txq_ctrl_data; - - txq_ctrl_data = (EDMA_TPD_BURST << EDMA_TXQ_NUM_TPD_BURST_SHIFT); - txq_ctrl_data |= EDMA_TXQ_CTRL_TPD_BURST_EN; - txq_ctrl_data |= (EDMA_TXF_BURST << EDMA_TXQ_TXF_BURST_NUM_SHIFT); - edma_write_reg(EDMA_REG_TXQ_CTRL, txq_ctrl_data); -} - - -/* edma_configure_rx() - * configure reception control data - */ -static void edma_configure_rx(struct edma_common_info *edma_cinfo) -{ - struct edma_hw *hw = &edma_cinfo->hw; - u32 rss_type, rx_desc1, rxq_ctrl_data; - - /* Set RSS type */ - rss_type = hw->rss_type; - edma_write_reg(EDMA_REG_RSS_TYPE, rss_type); - - /* Set RFD burst number */ - rx_desc1 = (EDMA_RFD_BURST << EDMA_RXQ_RFD_BURST_NUM_SHIFT); - - /* Set RFD prefetch threshold */ - rx_desc1 |= (EDMA_RFD_THR << EDMA_RXQ_RFD_PF_THRESH_SHIFT); - - /* Set RFD in host ring low threshold to generte interrupt */ - rx_desc1 |= (EDMA_RFD_LTHR << EDMA_RXQ_RFD_LOW_THRESH_SHIFT); - edma_write_reg(EDMA_REG_RX_DESC1, rx_desc1); - - /* Set Rx FIFO threshold to start to DMA data to host */ - rxq_ctrl_data = EDMA_FIFO_THRESH_128_BYTE; - - if (!edma_cinfo->is_single_phy) { - /* Set RX remove vlan bit */ - rxq_ctrl_data |= EDMA_RXQ_CTRL_RMV_VLAN; - } - - edma_write_reg(EDMA_REG_RXQ_CTRL, rxq_ctrl_data); -} - -/* edma_alloc_rx_buf() - * does skb allocation for the received packets. - */ -static int edma_alloc_rx_buf(struct edma_common_info - *edma_cinfo, - struct edma_rfd_desc_ring *erdr, - int cleaned_count, int queue_id) -{ - struct platform_device *pdev = edma_cinfo->pdev; - struct edma_rx_free_desc *rx_desc; - struct edma_sw_desc *sw_desc; - struct sk_buff *skb; - unsigned int i; - u16 prod_idx, length; - u32 reg_data; - - if (cleaned_count > erdr->count) - cleaned_count = erdr->count - 1; - - i = erdr->sw_next_to_fill; - - while (cleaned_count) { - sw_desc = &erdr->sw_desc[i]; - length = edma_cinfo->rx_head_buffer_len; - - if (sw_desc->flags & EDMA_SW_DESC_FLAG_SKB_REUSE) { - skb = sw_desc->skb; - - /* Clear REUSE Flag */ - sw_desc->flags &= ~EDMA_SW_DESC_FLAG_SKB_REUSE; - } else { - /* alloc skb */ - skb = netdev_alloc_skb_ip_align(edma_netdev[0], length); - if (!skb) { - /* Better luck next round */ - break; - } - } - - if (edma_cinfo->page_mode) { - struct page *pg = alloc_page(GFP_ATOMIC); - - if (!pg) { - dev_kfree_skb_any(skb); - break; - } - - sw_desc->dma = dma_map_page(&pdev->dev, pg, 0, - edma_cinfo->rx_page_buffer_len, - DMA_FROM_DEVICE); - if (dma_mapping_error(&pdev->dev, - sw_desc->dma)) { - __free_page(pg); - dev_kfree_skb_any(skb); - break; - } - - skb_fill_page_desc(skb, 0, pg, 0, - edma_cinfo->rx_page_buffer_len); - sw_desc->flags = EDMA_SW_DESC_FLAG_SKB_FRAG; - sw_desc->length = edma_cinfo->rx_page_buffer_len; - } else { - sw_desc->dma = dma_map_single(&pdev->dev, skb->data, - length, DMA_FROM_DEVICE); - if (dma_mapping_error(&pdev->dev, - sw_desc->dma)) { - dev_kfree_skb_any(skb); - break; - } - - sw_desc->flags = EDMA_SW_DESC_FLAG_SKB_HEAD; - sw_desc->length = length; - } - - /* Update the buffer info */ - sw_desc->skb = skb; - rx_desc = (&((struct edma_rx_free_desc *)(erdr->hw_desc))[i]); - rx_desc->buffer_addr = cpu_to_le64(sw_desc->dma); - if (++i == erdr->count) - i = 0; - cleaned_count--; - } - - erdr->sw_next_to_fill = i; - - if (i == 0) - prod_idx = erdr->count - 1; - else - prod_idx = i - 1; - - /* Update the producer index */ - edma_read_reg(EDMA_REG_RFD_IDX_Q(queue_id), ®_data); - reg_data &= ~EDMA_RFD_PROD_IDX_BITS; - reg_data |= prod_idx; - edma_write_reg(EDMA_REG_RFD_IDX_Q(queue_id), reg_data); - - /* If we couldn't allocate all the buffers - * we increment the alloc failure counters - */ - if (cleaned_count) - edma_cinfo->edma_ethstats.rx_alloc_fail_ctr++; - - return cleaned_count; -} - -/* edma_init_desc() - * update descriptor ring size, buffer and producer/consumer index - */ -static void edma_init_desc(struct edma_common_info *edma_cinfo) -{ - struct edma_rfd_desc_ring *rfd_ring; - struct edma_tx_desc_ring *etdr; - int i = 0, j = 0; - u32 data = 0; - u16 hw_cons_idx = 0; - - /* Set the base address of every TPD ring. */ - for (i = 0; i < edma_cinfo->num_tx_queues; i++) { - etdr = edma_cinfo->tpd_ring[i]; - - /* Update descriptor ring base address */ - edma_write_reg(EDMA_REG_TPD_BASE_ADDR_Q(i), (u32)etdr->dma); - edma_read_reg(EDMA_REG_TPD_IDX_Q(i), &data); - - /* Calculate hardware consumer index */ - hw_cons_idx = (data >> EDMA_TPD_CONS_IDX_SHIFT) & 0xffff; - etdr->sw_next_to_fill = hw_cons_idx; - etdr->sw_next_to_clean = hw_cons_idx; - data &= ~(EDMA_TPD_PROD_IDX_MASK << EDMA_TPD_PROD_IDX_SHIFT); - data |= hw_cons_idx; - - /* update producer index */ - edma_write_reg(EDMA_REG_TPD_IDX_Q(i), data); - - /* update SW consumer index register */ - edma_write_reg(EDMA_REG_TX_SW_CONS_IDX_Q(i), hw_cons_idx); - - /* Set TPD ring size */ - edma_write_reg(EDMA_REG_TPD_RING_SIZE, - edma_cinfo->tx_ring_count & - EDMA_TPD_RING_SIZE_MASK); - } - - for (i = 0, j = 0; i < edma_cinfo->num_rx_queues; i++) { - rfd_ring = edma_cinfo->rfd_ring[j]; - /* Update Receive Free descriptor ring base address */ - edma_write_reg(EDMA_REG_RFD_BASE_ADDR_Q(j), - (u32)(rfd_ring->dma)); - j += ((edma_cinfo->num_rx_queues == 4) ? 2 : 1); - } - - data = edma_cinfo->rx_head_buffer_len; - if (edma_cinfo->page_mode) - data = edma_cinfo->rx_page_buffer_len; - - data &= EDMA_RX_BUF_SIZE_MASK; - data <<= EDMA_RX_BUF_SIZE_SHIFT; - - /* Update RFD ring size and RX buffer size */ - data |= (edma_cinfo->rx_ring_count & EDMA_RFD_RING_SIZE_MASK) - << EDMA_RFD_RING_SIZE_SHIFT; - - edma_write_reg(EDMA_REG_RX_DESC0, data); - - /* Disable TX FIFO low watermark and high watermark */ - edma_write_reg(EDMA_REG_TXF_WATER_MARK, 0); - - /* Load all of base address above */ - edma_read_reg(EDMA_REG_TX_SRAM_PART, &data); - data |= 1 << EDMA_LOAD_PTR_SHIFT; - edma_write_reg(EDMA_REG_TX_SRAM_PART, data); -} - -/* edma_receive_checksum - * Api to check checksum on receive packets - */ -static void edma_receive_checksum(struct edma_rx_return_desc *rd, - struct sk_buff *skb) -{ - skb_checksum_none_assert(skb); - - /* check the RRD IP/L4 checksum bit to see if - * its set, which in turn indicates checksum - * failure. - */ - if (rd->rrd6 & EDMA_RRD_CSUM_FAIL_MASK) - return; - - skb->ip_summed = CHECKSUM_UNNECESSARY; -} - -/* edma_clean_rfd() - * clean up rx resourcers on error - */ -static void edma_clean_rfd(struct edma_rfd_desc_ring *erdr, u16 index) -{ - struct edma_rx_free_desc *rx_desc; - struct edma_sw_desc *sw_desc; - - rx_desc = (&((struct edma_rx_free_desc *)(erdr->hw_desc))[index]); - sw_desc = &erdr->sw_desc[index]; - if (sw_desc->skb) { - dev_kfree_skb_any(sw_desc->skb); - sw_desc->skb = NULL; - } - - memset(rx_desc, 0, sizeof(struct edma_rx_free_desc)); -} - -/* edma_rx_complete_fraglist() - * Complete Rx processing for fraglist skbs - */ -static void edma_rx_complete_stp_rstp(struct sk_buff *skb, int port_id, struct edma_rx_return_desc *rd) -{ - int i; - u32 priority; - u16 port_type; - u8 mac_addr[EDMA_ETH_HDR_LEN]; - - port_type = (rd->rrd1 >> EDMA_RRD_PORT_TYPE_SHIFT) - & EDMA_RRD_PORT_TYPE_MASK; - /* if port type is 0x4, then only proceed with - * other stp/rstp calculation - */ - if (port_type == EDMA_RX_ATH_HDR_RSTP_PORT_TYPE) { - u8 bpdu_mac[6] = {0x01, 0x80, 0xc2, 0x00, 0x00, 0x00}; - - /* calculate the frame priority */ - priority = (rd->rrd1 >> EDMA_RRD_PRIORITY_SHIFT) - & EDMA_RRD_PRIORITY_MASK; - - for (i = 0; i < EDMA_ETH_HDR_LEN; i++) - mac_addr[i] = skb->data[i]; - - /* Check if destination mac addr is bpdu addr */ - if (!memcmp(mac_addr, bpdu_mac, 6)) { - /* destination mac address is BPDU - * destination mac address, then add - * atheros header to the packet. - */ - u16 athr_hdr = (EDMA_RX_ATH_HDR_VERSION << EDMA_RX_ATH_HDR_VERSION_SHIFT) | - (priority << EDMA_RX_ATH_HDR_PRIORITY_SHIFT) | - (EDMA_RX_ATH_HDR_RSTP_PORT_TYPE << EDMA_RX_ATH_PORT_TYPE_SHIFT) | port_id; - skb_push(skb, 4); - memcpy(skb->data, mac_addr, EDMA_ETH_HDR_LEN); - *(uint16_t *)&skb->data[12] = htons(edma_ath_eth_type); - *(uint16_t *)&skb->data[14] = htons(athr_hdr); - } - } -} - -/* - * edma_rx_complete_fraglist() - * Complete Rx processing for fraglist skbs - */ -static int edma_rx_complete_fraglist(struct sk_buff *skb, u16 num_rfds, u16 length, u32 sw_next_to_clean, - u16 *cleaned_count, struct edma_rfd_desc_ring *erdr, struct edma_common_info *edma_cinfo) -{ - struct platform_device *pdev = edma_cinfo->pdev; - struct edma_hw *hw = &edma_cinfo->hw; - struct sk_buff *skb_temp; - struct edma_sw_desc *sw_desc; - int i; - u16 size_remaining; - - skb->data_len = 0; - skb->tail += (hw->rx_head_buff_size - 16); - skb->len = skb->truesize = length; - size_remaining = length - (hw->rx_head_buff_size - 16); - - /* clean-up all related sw_descs */ - for (i = 1; i < num_rfds; i++) { - struct sk_buff *skb_prev; - sw_desc = &erdr->sw_desc[sw_next_to_clean]; - skb_temp = sw_desc->skb; - - dma_unmap_single(&pdev->dev, sw_desc->dma, - sw_desc->length, DMA_FROM_DEVICE); - - if (size_remaining < hw->rx_head_buff_size) - skb_put(skb_temp, size_remaining); - else - skb_put(skb_temp, hw->rx_head_buff_size); - - /* - * If we are processing the first rfd, we link - * skb->frag_list to the skb corresponding to the - * first RFD - */ - if (i == 1) - skb_shinfo(skb)->frag_list = skb_temp; - else - skb_prev->next = skb_temp; - skb_prev = skb_temp; - skb_temp->next = NULL; - - skb->data_len += skb_temp->len; - size_remaining -= skb_temp->len; - - /* Increment SW index */ - sw_next_to_clean = (sw_next_to_clean + 1) & (erdr->count - 1); - (*cleaned_count)++; - } - - return sw_next_to_clean; -} - -/* edma_rx_complete_paged() - * Complete Rx processing for paged skbs - */ -static int edma_rx_complete_paged(struct sk_buff *skb, u16 num_rfds, u16 length, u32 sw_next_to_clean, - u16 *cleaned_count, struct edma_rfd_desc_ring *erdr, struct edma_common_info *edma_cinfo) -{ - struct platform_device *pdev = edma_cinfo->pdev; - struct sk_buff *skb_temp; - struct edma_sw_desc *sw_desc; - int i; - u16 size_remaining; - - skb_frag_t *frag = &skb_shinfo(skb)->frags[0]; - - /* Setup skbuff fields */ - skb->len = length; - - if (likely(num_rfds <= 1)) { - skb->data_len = length; - skb->truesize += edma_cinfo->rx_page_buffer_len; - skb_fill_page_desc(skb, 0, skb_frag_page(frag), - 16, length); - } else { - skb_frag_size_sub(frag, 16); - skb->data_len = skb_frag_size(frag); - skb->truesize += edma_cinfo->rx_page_buffer_len; - size_remaining = length - skb_frag_size(frag); - - skb_fill_page_desc(skb, 0, skb_frag_page(frag), - 16, skb_frag_size(frag)); - - /* clean-up all related sw_descs */ - for (i = 1; i < num_rfds; i++) { - sw_desc = &erdr->sw_desc[sw_next_to_clean]; - skb_temp = sw_desc->skb; - frag = &skb_shinfo(skb_temp)->frags[0]; - dma_unmap_page(&pdev->dev, sw_desc->dma, - sw_desc->length, DMA_FROM_DEVICE); - - if (size_remaining < edma_cinfo->rx_page_buffer_len) - skb_frag_size_set(frag, size_remaining); - - skb_fill_page_desc(skb, i, skb_frag_page(frag), - 0, skb_frag_size(frag)); - - skb_shinfo(skb_temp)->nr_frags = 0; - dev_kfree_skb_any(skb_temp); - - skb->data_len += skb_frag_size(frag); - skb->truesize += edma_cinfo->rx_page_buffer_len; - size_remaining -= skb_frag_size(frag); - - /* Increment SW index */ - sw_next_to_clean = (sw_next_to_clean + 1) & (erdr->count - 1); - (*cleaned_count)++; - } - } - - return sw_next_to_clean; -} - -/* - * edma_rx_complete() - * Main api called from the poll function to process rx packets. - */ -static u16 edma_rx_complete(struct edma_common_info *edma_cinfo, - int *work_done, int work_to_do, int queue_id, - struct napi_struct *napi) -{ - struct platform_device *pdev = edma_cinfo->pdev; - struct edma_rfd_desc_ring *erdr = edma_cinfo->rfd_ring[queue_id]; - struct net_device *netdev; - struct edma_adapter *adapter; - struct edma_sw_desc *sw_desc; - struct sk_buff *skb; - struct edma_rx_return_desc *rd; - u16 hash_type, rrd[8], cleaned_count = 0, length = 0, num_rfds = 1, - sw_next_to_clean, hw_next_to_clean = 0, vlan = 0, ret_count = 0; - u32 data = 0; - u8 *vaddr; - int port_id, i, drop_count = 0; - u32 priority; - u16 count = erdr->count, rfd_avail; - u8 queue_to_rxid[8] = {0, 0, 1, 1, 2, 2, 3, 3}; - - cleaned_count = erdr->pending_fill; - sw_next_to_clean = erdr->sw_next_to_clean; - - edma_read_reg(EDMA_REG_RFD_IDX_Q(queue_id), &data); - hw_next_to_clean = (data >> EDMA_RFD_CONS_IDX_SHIFT) & - EDMA_RFD_CONS_IDX_MASK; - - do { - while (sw_next_to_clean != hw_next_to_clean) { - if (!work_to_do) - break; - - sw_desc = &erdr->sw_desc[sw_next_to_clean]; - skb = sw_desc->skb; - - /* Unmap the allocated buffer */ - if (likely(sw_desc->flags & EDMA_SW_DESC_FLAG_SKB_HEAD)) - dma_unmap_single(&pdev->dev, sw_desc->dma, - sw_desc->length, DMA_FROM_DEVICE); - else - dma_unmap_page(&pdev->dev, sw_desc->dma, - sw_desc->length, DMA_FROM_DEVICE); - - /* Get RRD */ - if (edma_cinfo->page_mode) { - vaddr = kmap_atomic(skb_frag_page(&skb_shinfo(skb)->frags[0])); - memcpy((uint8_t *)&rrd[0], vaddr, 16); - rd = (struct edma_rx_return_desc *)rrd; - kunmap_atomic(vaddr); - } else { - rd = (struct edma_rx_return_desc *)skb->data; - } - - /* Check if RRD is valid */ - if (!(rd->rrd7 & EDMA_RRD_DESC_VALID)) { - edma_clean_rfd(erdr, sw_next_to_clean); - sw_next_to_clean = (sw_next_to_clean + 1) & - (erdr->count - 1); - cleaned_count++; - continue; - } - - /* Get the number of RFDs from RRD */ - num_rfds = rd->rrd1 & EDMA_RRD_NUM_RFD_MASK; - - /* Get Rx port ID from switch */ - port_id = (rd->rrd1 >> EDMA_PORT_ID_SHIFT) & EDMA_PORT_ID_MASK; - if ((!port_id) || (port_id > EDMA_MAX_PORTID_SUPPORTED)) { - dev_err(&pdev->dev, "Invalid RRD source port bit set"); - for (i = 0; i < num_rfds; i++) { - edma_clean_rfd(erdr, sw_next_to_clean); - sw_next_to_clean = (sw_next_to_clean + 1) & (erdr->count - 1); - cleaned_count++; - } - continue; - } - - /* check if we have a sink for the data we receive. - * If the interface isn't setup, we have to drop the - * incoming data for now. - */ - netdev = edma_cinfo->portid_netdev_lookup_tbl[port_id]; - if (!netdev) { - edma_clean_rfd(erdr, sw_next_to_clean); - sw_next_to_clean = (sw_next_to_clean + 1) & - (erdr->count - 1); - cleaned_count++; - continue; - } - adapter = netdev_priv(netdev); - - /* This code is added to handle a usecase where high - * priority stream and a low priority stream are - * received simultaneously on DUT. The problem occurs - * if one of the Rx rings is full and the corresponding - * core is busy with other stuff. This causes ESS CPU - * port to backpressure all incoming traffic including - * high priority one. We monitor free descriptor count - * on each CPU and whenever it reaches threshold (< 80), - * we drop all low priority traffic and let only high - * priotiy traffic pass through. We can hence avoid - * ESS CPU port to send backpressure on high priroity - * stream. - */ - priority = (rd->rrd1 >> EDMA_RRD_PRIORITY_SHIFT) - & EDMA_RRD_PRIORITY_MASK; - if (likely(!priority && !edma_cinfo->page_mode && (num_rfds <= 1))) { - rfd_avail = (count + sw_next_to_clean - hw_next_to_clean - 1) & (count - 1); - if (rfd_avail < EDMA_RFD_AVAIL_THR) { - sw_desc->flags = EDMA_SW_DESC_FLAG_SKB_REUSE; - sw_next_to_clean = (sw_next_to_clean + 1) & (erdr->count - 1); - adapter->stats.rx_dropped++; - cleaned_count++; - drop_count++; - if (drop_count == 3) { - work_to_do--; - (*work_done)++; - drop_count = 0; - } - if (cleaned_count >= EDMA_RX_BUFFER_WRITE) { - /* If buffer clean count reaches 16, we replenish HW buffers. */ - ret_count = edma_alloc_rx_buf(edma_cinfo, erdr, cleaned_count, queue_id); - edma_write_reg(EDMA_REG_RX_SW_CONS_IDX_Q(queue_id), - sw_next_to_clean); - cleaned_count = ret_count; - erdr->pending_fill = ret_count; - } - continue; - } - } - - work_to_do--; - (*work_done)++; - - /* Increment SW index */ - sw_next_to_clean = (sw_next_to_clean + 1) & - (erdr->count - 1); - - cleaned_count++; - - /* Get the packet size and allocate buffer */ - length = rd->rrd6 & EDMA_RRD_PKT_SIZE_MASK; - - if (edma_cinfo->page_mode) { - /* paged skb */ - sw_next_to_clean = edma_rx_complete_paged(skb, num_rfds, length, sw_next_to_clean, &cleaned_count, erdr, edma_cinfo); - if (!pskb_may_pull(skb, ETH_HLEN)) { - dev_kfree_skb_any(skb); - continue; - } - } else { - /* single or fraglist skb */ - - /* Addition of 16 bytes is required, as in the packet - * first 16 bytes are rrd descriptors, so actual data - * starts from an offset of 16. - */ - skb_reserve(skb, 16); - if (likely((num_rfds <= 1) || !edma_cinfo->fraglist_mode)) { - skb_put(skb, length); - } else { - sw_next_to_clean = edma_rx_complete_fraglist(skb, num_rfds, length, sw_next_to_clean, &cleaned_count, erdr, edma_cinfo); - } - } - - if (edma_stp_rstp) { - edma_rx_complete_stp_rstp(skb, port_id, rd); - } - - skb->protocol = eth_type_trans(skb, netdev); - - /* Record Rx queue for RFS/RPS and fill flow hash from HW */ - skb_record_rx_queue(skb, queue_to_rxid[queue_id]); - if (netdev->features & NETIF_F_RXHASH) { - hash_type = (rd->rrd5 >> EDMA_HASH_TYPE_SHIFT); - if ((hash_type > EDMA_HASH_TYPE_START) && (hash_type < EDMA_HASH_TYPE_END)) - skb_set_hash(skb, rd->rrd2, PKT_HASH_TYPE_L4); - } - -#ifdef CONFIG_NF_FLOW_COOKIE - skb->flow_cookie = rd->rrd3 & EDMA_RRD_FLOW_COOKIE_MASK; -#endif - edma_receive_checksum(rd, skb); - - /* Process VLAN HW acceleration indication provided by HW */ - if (unlikely(adapter->default_vlan_tag != rd->rrd4)) { - vlan = rd->rrd4; - if (likely(rd->rrd7 & EDMA_RRD_CVLAN)) - __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), vlan); - else if (rd->rrd1 & EDMA_RRD_SVLAN) - __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021AD), vlan); - } - - /* Update rx statistics */ - adapter->stats.rx_packets++; - adapter->stats.rx_bytes += length; - - /* Check if we reached refill threshold */ - if (cleaned_count >= EDMA_RX_BUFFER_WRITE) { - ret_count = edma_alloc_rx_buf(edma_cinfo, erdr, cleaned_count, queue_id); - edma_write_reg(EDMA_REG_RX_SW_CONS_IDX_Q(queue_id), - sw_next_to_clean); - cleaned_count = ret_count; - erdr->pending_fill = ret_count; - } - - /* At this point skb should go to stack */ - napi_gro_receive(napi, skb); - } - - /* Check if we still have NAPI budget */ - if (!work_to_do) - break; - - /* Read index once again since we still have NAPI budget */ - edma_read_reg(EDMA_REG_RFD_IDX_Q(queue_id), &data); - hw_next_to_clean = (data >> EDMA_RFD_CONS_IDX_SHIFT) & - EDMA_RFD_CONS_IDX_MASK; - } while (hw_next_to_clean != sw_next_to_clean); - - erdr->sw_next_to_clean = sw_next_to_clean; - - /* Refill here in case refill threshold wasn't reached */ - if (likely(cleaned_count)) { - ret_count = edma_alloc_rx_buf(edma_cinfo, erdr, cleaned_count, queue_id); - erdr->pending_fill = ret_count; - if (ret_count) { - if (net_ratelimit()) - dev_dbg(&pdev->dev, "Not all buffers was reallocated"); - } - - edma_write_reg(EDMA_REG_RX_SW_CONS_IDX_Q(queue_id), - erdr->sw_next_to_clean); - } - - return erdr->pending_fill; -} - -/* edma_delete_rfs_filter() - * Remove RFS filter from switch - */ -static int edma_delete_rfs_filter(struct edma_adapter *adapter, - struct edma_rfs_filter_node *filter_node) -{ - int res = -1; - - struct flow_keys *keys = &filter_node->keys; - - if (likely(adapter->set_rfs_rule)) - res = (*adapter->set_rfs_rule)(adapter->netdev, - flow_get_u32_src(keys), flow_get_u32_dst(keys), - keys->ports.src, keys->ports.dst, - keys->basic.ip_proto, filter_node->rq_id, 0); - - return res; -} - -/* edma_add_rfs_filter() - * Add RFS filter to switch - */ -static int edma_add_rfs_filter(struct edma_adapter *adapter, - struct flow_keys *keys, u16 rq, - struct edma_rfs_filter_node *filter_node) -{ - int res = -1; - - struct flow_keys *dest_keys = &filter_node->keys; - - memcpy(dest_keys, &filter_node->keys, sizeof(*dest_keys)); -/* - dest_keys->control = keys->control; - dest_keys->basic = keys->basic; - dest_keys->addrs = keys->addrs; - dest_keys->ports = keys->ports; - dest_keys.ip_proto = keys->ip_proto; -*/ - /* Call callback registered by ESS driver */ - if (likely(adapter->set_rfs_rule)) - res = (*adapter->set_rfs_rule)(adapter->netdev, flow_get_u32_src(keys), - flow_get_u32_dst(keys), keys->ports.src, keys->ports.dst, - keys->basic.ip_proto, rq, 1); - - return res; -} - -/* edma_rfs_key_search() - * Look for existing RFS entry - */ -static struct edma_rfs_filter_node *edma_rfs_key_search(struct hlist_head *h, - struct flow_keys *key) -{ - struct edma_rfs_filter_node *p; - - hlist_for_each_entry(p, h, node) - if (flow_get_u32_src(&p->keys) == flow_get_u32_src(key) && - flow_get_u32_dst(&p->keys) == flow_get_u32_dst(key) && - p->keys.ports.src == key->ports.src && - p->keys.ports.dst == key->ports.dst && - p->keys.basic.ip_proto == key->basic.ip_proto) - return p; - return NULL; -} - -/* edma_initialise_rfs_flow_table() - * Initialise EDMA RFS flow table - */ -static void edma_initialise_rfs_flow_table(struct edma_adapter *adapter) -{ - int i; - - spin_lock_init(&adapter->rfs.rfs_ftab_lock); - - /* Initialize EDMA flow hash table */ - for (i = 0; i < EDMA_RFS_FLOW_ENTRIES; i++) - INIT_HLIST_HEAD(&adapter->rfs.hlist_head[i]); - - adapter->rfs.max_num_filter = EDMA_RFS_FLOW_ENTRIES; - adapter->rfs.filter_available = adapter->rfs.max_num_filter; - adapter->rfs.hashtoclean = 0; - - /* Add timer to get periodic RFS updates from OS */ - timer_setup(&adapter->rfs.expire_rfs, edma_flow_may_expire, 0); - mod_timer(&adapter->rfs.expire_rfs, jiffies + HZ / 4); -} - -/* edma_free_rfs_flow_table() - * Free EDMA RFS flow table - */ -static void edma_free_rfs_flow_table(struct edma_adapter *adapter) -{ - int i; - - /* Remove sync timer */ - del_timer_sync(&adapter->rfs.expire_rfs); - spin_lock_bh(&adapter->rfs.rfs_ftab_lock); - - /* Free EDMA RFS table entries */ - adapter->rfs.filter_available = 0; - - /* Clean-up EDMA flow hash table */ - for (i = 0; i < EDMA_RFS_FLOW_ENTRIES; i++) { - struct hlist_head *hhead; - struct hlist_node *tmp; - struct edma_rfs_filter_node *filter_node; - int res; - - hhead = &adapter->rfs.hlist_head[i]; - hlist_for_each_entry_safe(filter_node, tmp, hhead, node) { - res = edma_delete_rfs_filter(adapter, filter_node); - if (res < 0) - dev_warn(&adapter->netdev->dev, - "EDMA going down but RFS entry %d not allowed to be flushed by Switch", - filter_node->flow_id); - hlist_del(&filter_node->node); - kfree(filter_node); - } - } - spin_unlock_bh(&adapter->rfs.rfs_ftab_lock); -} - -/* edma_tx_unmap_and_free() - * clean TX buffer - */ -static inline void edma_tx_unmap_and_free(struct platform_device *pdev, - struct edma_sw_desc *sw_desc) -{ - struct sk_buff *skb = sw_desc->skb; - - if (likely((sw_desc->flags & EDMA_SW_DESC_FLAG_SKB_HEAD) || - (sw_desc->flags & EDMA_SW_DESC_FLAG_SKB_FRAGLIST))) - /* unmap_single for skb head area */ - dma_unmap_single(&pdev->dev, sw_desc->dma, - sw_desc->length, DMA_TO_DEVICE); - else if (sw_desc->flags & EDMA_SW_DESC_FLAG_SKB_FRAG) - /* unmap page for paged fragments */ - dma_unmap_page(&pdev->dev, sw_desc->dma, - sw_desc->length, DMA_TO_DEVICE); - - if (likely(sw_desc->flags & EDMA_SW_DESC_FLAG_LAST)) - dev_kfree_skb_any(skb); - - sw_desc->flags = 0; -} - -/* edma_tx_complete() - * Used to clean tx queues and update hardware and consumer index - */ -static void edma_tx_complete(struct edma_common_info *edma_cinfo, int queue_id) -{ - struct edma_tx_desc_ring *etdr = edma_cinfo->tpd_ring[queue_id]; - struct edma_sw_desc *sw_desc; - struct platform_device *pdev = edma_cinfo->pdev; - int i; - - u16 sw_next_to_clean = etdr->sw_next_to_clean; - u16 hw_next_to_clean; - u32 data = 0; - - edma_read_reg(EDMA_REG_TPD_IDX_Q(queue_id), &data); - hw_next_to_clean = (data >> EDMA_TPD_CONS_IDX_SHIFT) & EDMA_TPD_CONS_IDX_MASK; - - /* clean the buffer here */ - while (sw_next_to_clean != hw_next_to_clean) { - sw_desc = &etdr->sw_desc[sw_next_to_clean]; - edma_tx_unmap_and_free(pdev, sw_desc); - sw_next_to_clean = (sw_next_to_clean + 1) & (etdr->count - 1); - } - - etdr->sw_next_to_clean = sw_next_to_clean; - - /* update the TPD consumer index register */ - edma_write_reg(EDMA_REG_TX_SW_CONS_IDX_Q(queue_id), sw_next_to_clean); - - /* Wake the queue if queue is stopped and netdev link is up */ - for (i = 0; i < EDMA_MAX_NETDEV_PER_QUEUE && etdr->nq[i] ; i++) { - if (netif_tx_queue_stopped(etdr->nq[i])) { - if ((etdr->netdev[i]) && netif_carrier_ok(etdr->netdev[i])) - netif_tx_wake_queue(etdr->nq[i]); - } - } -} - -/* edma_get_tx_buffer() - * Get sw_desc corresponding to the TPD - */ -static struct edma_sw_desc *edma_get_tx_buffer(struct edma_common_info *edma_cinfo, - struct edma_tx_desc *tpd, int queue_id) -{ - struct edma_tx_desc_ring *etdr = edma_cinfo->tpd_ring[queue_id]; - return &etdr->sw_desc[tpd - (struct edma_tx_desc *)etdr->hw_desc]; -} - -/* edma_get_next_tpd() - * Return a TPD descriptor for transfer - */ -static struct edma_tx_desc *edma_get_next_tpd(struct edma_common_info *edma_cinfo, - int queue_id) -{ - struct edma_tx_desc_ring *etdr = edma_cinfo->tpd_ring[queue_id]; - u16 sw_next_to_fill = etdr->sw_next_to_fill; - struct edma_tx_desc *tpd_desc = - (&((struct edma_tx_desc *)(etdr->hw_desc))[sw_next_to_fill]); - - etdr->sw_next_to_fill = (etdr->sw_next_to_fill + 1) & (etdr->count - 1); - - return tpd_desc; -} - -/* edma_tpd_available() - * Check number of free TPDs - */ -static inline u16 edma_tpd_available(struct edma_common_info *edma_cinfo, - int queue_id) -{ - struct edma_tx_desc_ring *etdr = edma_cinfo->tpd_ring[queue_id]; - - u16 sw_next_to_fill; - u16 sw_next_to_clean; - u16 count = 0; - - sw_next_to_clean = etdr->sw_next_to_clean; - sw_next_to_fill = etdr->sw_next_to_fill; - - if (likely(sw_next_to_clean <= sw_next_to_fill)) - count = etdr->count; - - return count + sw_next_to_clean - sw_next_to_fill - 1; -} - -/* edma_tx_queue_get() - * Get the starting number of the queue - */ -static inline int edma_tx_queue_get(struct edma_adapter *adapter, - struct sk_buff *skb, int txq_id) -{ - /* skb->priority is used as an index to skb priority table - * and based on packet priority, correspong queue is assigned. - */ - return adapter->tx_start_offset[txq_id] + edma_skb_priority_offset(skb); -} - -/* edma_tx_update_hw_idx() - * update the producer index for the ring transmitted - */ -static void edma_tx_update_hw_idx(struct edma_common_info *edma_cinfo, - struct sk_buff *skb, int queue_id) -{ - struct edma_tx_desc_ring *etdr = edma_cinfo->tpd_ring[queue_id]; - u32 tpd_idx_data; - - /* Read and update the producer index */ - edma_read_reg(EDMA_REG_TPD_IDX_Q(queue_id), &tpd_idx_data); - tpd_idx_data &= ~EDMA_TPD_PROD_IDX_BITS; - tpd_idx_data |= (etdr->sw_next_to_fill & EDMA_TPD_PROD_IDX_MASK) - << EDMA_TPD_PROD_IDX_SHIFT; - - edma_write_reg(EDMA_REG_TPD_IDX_Q(queue_id), tpd_idx_data); -} - -/* edma_rollback_tx() - * Function to retrieve tx resources in case of error - */ -static void edma_rollback_tx(struct edma_adapter *adapter, - struct edma_tx_desc *start_tpd, int queue_id) -{ - struct edma_tx_desc_ring *etdr = adapter->edma_cinfo->tpd_ring[queue_id]; - struct edma_sw_desc *sw_desc; - struct edma_tx_desc *tpd = NULL; - u16 start_index, index; - - start_index = start_tpd - (struct edma_tx_desc *)(etdr->hw_desc); - - index = start_index; - while (index != etdr->sw_next_to_fill) { - tpd = (&((struct edma_tx_desc *)(etdr->hw_desc))[index]); - sw_desc = &etdr->sw_desc[index]; - edma_tx_unmap_and_free(adapter->pdev, sw_desc); - memset(tpd, 0, sizeof(struct edma_tx_desc)); - if (++index == etdr->count) - index = 0; - } - etdr->sw_next_to_fill = start_index; -} - -/* edma_tx_map_and_fill() - * gets called from edma_xmit_frame - * - * This is where the dma of the buffer to be transmitted - * gets mapped - */ -static int edma_tx_map_and_fill(struct edma_common_info *edma_cinfo, - struct edma_adapter *adapter, struct sk_buff *skb, int queue_id, - unsigned int flags_transmit, u16 from_cpu, u16 dp_bitmap, - bool packet_is_rstp, int nr_frags) -{ - struct edma_sw_desc *sw_desc = NULL; - struct platform_device *pdev = edma_cinfo->pdev; - struct edma_tx_desc *tpd = NULL, *start_tpd = NULL; - struct sk_buff *iter_skb; - int i = 0; - u32 word1 = 0, word3 = 0, lso_word1 = 0, svlan_tag = 0; - u16 buf_len, lso_desc_len = 0; - - /* It should either be a nr_frags skb or fraglist skb but not both */ - BUG_ON(nr_frags && skb_has_frag_list(skb)); - - if (skb_is_gso(skb)) { - /* TODO: What additional checks need to be performed here */ - if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV4) { - lso_word1 |= EDMA_TPD_IPV4_EN; - ip_hdr(skb)->check = 0; - tcp_hdr(skb)->check = ~csum_tcpudp_magic(ip_hdr(skb)->saddr, - ip_hdr(skb)->daddr, 0, IPPROTO_TCP, 0); - } else if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV6) { - lso_word1 |= EDMA_TPD_LSO_V2_EN; - ipv6_hdr(skb)->payload_len = 0; - tcp_hdr(skb)->check = ~csum_ipv6_magic(&ipv6_hdr(skb)->saddr, - &ipv6_hdr(skb)->daddr, 0, IPPROTO_TCP, 0); - } else - return -EINVAL; - - lso_word1 |= EDMA_TPD_LSO_EN | ((skb_shinfo(skb)->gso_size & EDMA_TPD_MSS_MASK) << EDMA_TPD_MSS_SHIFT) | - (skb_transport_offset(skb) << EDMA_TPD_HDR_SHIFT); - } else if (flags_transmit & EDMA_HW_CHECKSUM) { - u8 css, cso; - cso = skb_checksum_start_offset(skb); - css = cso + skb->csum_offset; - - word1 |= (EDMA_TPD_CUSTOM_CSUM_EN); - word1 |= (cso >> 1) << EDMA_TPD_HDR_SHIFT; - word1 |= ((css >> 1) << EDMA_TPD_CUSTOM_CSUM_SHIFT); - } - - if (skb->protocol == htons(ETH_P_PPP_SES)) - word1 |= EDMA_TPD_PPPOE_EN; - - if (flags_transmit & EDMA_VLAN_TX_TAG_INSERT_FLAG) { - switch(skb->vlan_proto) { - case htons(ETH_P_8021Q): - word3 |= (1 << EDMA_TX_INS_CVLAN); - word3 |= skb_vlan_tag_get(skb) << EDMA_TX_CVLAN_TAG_SHIFT; - break; - case htons(ETH_P_8021AD): - word1 |= (1 << EDMA_TX_INS_SVLAN); - svlan_tag = skb_vlan_tag_get(skb) << EDMA_TX_SVLAN_TAG_SHIFT; - break; - default: - dev_err(&pdev->dev, "no ctag or stag present\n"); - goto vlan_tag_error; - } - } else if (flags_transmit & EDMA_VLAN_TX_TAG_INSERT_DEFAULT_FLAG) { - word3 |= (1 << EDMA_TX_INS_CVLAN); - word3 |= (adapter->default_vlan_tag) << EDMA_TX_CVLAN_TAG_SHIFT; - } - - if (packet_is_rstp) { - word3 |= dp_bitmap << EDMA_TPD_PORT_BITMAP_SHIFT; - word3 |= from_cpu << EDMA_TPD_FROM_CPU_SHIFT; - } else { - word3 |= adapter->dp_bitmap << EDMA_TPD_PORT_BITMAP_SHIFT; - } - - buf_len = skb_headlen(skb); - - if (lso_word1) { - if (lso_word1 & EDMA_TPD_LSO_V2_EN) { - - /* IPv6 LSOv2 descriptor */ - start_tpd = tpd = edma_get_next_tpd(edma_cinfo, queue_id); - sw_desc = edma_get_tx_buffer(edma_cinfo, tpd, queue_id); - sw_desc->flags |= EDMA_SW_DESC_FLAG_SKB_NONE; - - /* LSOv2 descriptor overrides addr field to pass length */ - tpd->addr = cpu_to_le16(skb->len); - tpd->svlan_tag = svlan_tag; - tpd->word1 = word1 | lso_word1; - tpd->word3 = word3; - } - - tpd = edma_get_next_tpd(edma_cinfo, queue_id); - if (!start_tpd) - start_tpd = tpd; - sw_desc = edma_get_tx_buffer(edma_cinfo, tpd, queue_id); - - /* The last buffer info contain the skb address, - * so skb will be freed after unmap - */ - sw_desc->length = lso_desc_len; - sw_desc->flags |= EDMA_SW_DESC_FLAG_SKB_HEAD; - - sw_desc->dma = dma_map_single(&adapter->pdev->dev, - skb->data, buf_len, DMA_TO_DEVICE); - if (dma_mapping_error(&pdev->dev, sw_desc->dma)) - goto dma_error; - - tpd->addr = cpu_to_le32(sw_desc->dma); - tpd->len = cpu_to_le16(buf_len); - - tpd->svlan_tag = svlan_tag; - tpd->word1 = word1 | lso_word1; - tpd->word3 = word3; - - /* The last buffer info contain the skb address, - * so it will be freed after unmap - */ - sw_desc->length = lso_desc_len; - sw_desc->flags |= EDMA_SW_DESC_FLAG_SKB_HEAD; - - buf_len = 0; - } - - if (likely(buf_len)) { - - /* TODO Do not dequeue descriptor if there is a potential error */ - tpd = edma_get_next_tpd(edma_cinfo, queue_id); - - if (!start_tpd) - start_tpd = tpd; - - sw_desc = edma_get_tx_buffer(edma_cinfo, tpd, queue_id); - - /* The last buffer info contain the skb address, - * so it will be free after unmap - */ - sw_desc->length = buf_len; - sw_desc->flags |= EDMA_SW_DESC_FLAG_SKB_HEAD; - sw_desc->dma = dma_map_single(&adapter->pdev->dev, - skb->data, buf_len, DMA_TO_DEVICE); - if (dma_mapping_error(&pdev->dev, sw_desc->dma)) - goto dma_error; - - tpd->addr = cpu_to_le32(sw_desc->dma); - tpd->len = cpu_to_le16(buf_len); - - tpd->svlan_tag = svlan_tag; - tpd->word1 = word1 | lso_word1; - tpd->word3 = word3; - } - - /* Walk through all paged fragments */ - while (nr_frags--) { - skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; - buf_len = skb_frag_size(frag); - tpd = edma_get_next_tpd(edma_cinfo, queue_id); - sw_desc = edma_get_tx_buffer(edma_cinfo, tpd, queue_id); - sw_desc->length = buf_len; - sw_desc->flags |= EDMA_SW_DESC_FLAG_SKB_FRAG; - - sw_desc->dma = skb_frag_dma_map(&pdev->dev, frag, 0, buf_len, DMA_TO_DEVICE); - - if (dma_mapping_error(NULL, sw_desc->dma)) - goto dma_error; - - tpd->addr = cpu_to_le32(sw_desc->dma); - tpd->len = cpu_to_le16(buf_len); - - tpd->svlan_tag = svlan_tag; - tpd->word1 = word1 | lso_word1; - tpd->word3 = word3; - i++; - } - - /* Walk through all fraglist skbs */ - skb_walk_frags(skb, iter_skb) { - buf_len = iter_skb->len; - tpd = edma_get_next_tpd(edma_cinfo, queue_id); - sw_desc = edma_get_tx_buffer(edma_cinfo, tpd, queue_id); - sw_desc->length = buf_len; - sw_desc->dma = dma_map_single(&adapter->pdev->dev, - iter_skb->data, buf_len, DMA_TO_DEVICE); - - if (dma_mapping_error(NULL, sw_desc->dma)) - goto dma_error; - - tpd->addr = cpu_to_le32(sw_desc->dma); - tpd->len = cpu_to_le16(buf_len); - tpd->svlan_tag = svlan_tag; - tpd->word1 = word1 | lso_word1; - tpd->word3 = word3; - sw_desc->flags |= EDMA_SW_DESC_FLAG_SKB_FRAGLIST; - } - - if (tpd) - tpd->word1 |= 1 << EDMA_TPD_EOP_SHIFT; - - sw_desc->skb = skb; - sw_desc->flags |= EDMA_SW_DESC_FLAG_LAST; - - return 0; - -dma_error: - edma_rollback_tx(adapter, start_tpd, queue_id); - dev_err(&pdev->dev, "TX DMA map failed\n"); -vlan_tag_error: - return -ENOMEM; -} - -/* edma_check_link() - * check Link status - */ -static int edma_check_link(struct edma_adapter *adapter) -{ - struct phy_device *phydev = adapter->phydev; - - if (!(adapter->poll_required)) - return __EDMA_LINKUP; - - if (phydev->link) - return __EDMA_LINKUP; - - return __EDMA_LINKDOWN; -} - -/* edma_adjust_link() - * check for edma link status - */ -void edma_adjust_link(struct net_device *netdev) -{ - int status; - struct edma_adapter *adapter = netdev_priv(netdev); - struct phy_device *phydev = adapter->phydev; - - if (!test_bit(__EDMA_UP, &adapter->state_flags)) - return; - - status = edma_check_link(adapter); - - if (status == __EDMA_LINKUP && adapter->link_state == __EDMA_LINKDOWN) { - dev_info(&adapter->pdev->dev, "%s: GMAC Link is up with phy_speed=%d\n", netdev->name, phydev->speed); - adapter->link_state = __EDMA_LINKUP; - if (adapter->edma_cinfo->is_single_phy) { - ess_set_port_status_speed(adapter->edma_cinfo, phydev, - ffs(adapter->dp_bitmap) - 1); - } - netif_carrier_on(netdev); - if (netif_running(netdev)) - netif_tx_wake_all_queues(netdev); - } else if (status == __EDMA_LINKDOWN && adapter->link_state == __EDMA_LINKUP) { - dev_info(&adapter->pdev->dev, "%s: GMAC Link is down\n", netdev->name); - adapter->link_state = __EDMA_LINKDOWN; - netif_carrier_off(netdev); - netif_tx_stop_all_queues(netdev); - } -} - -/* edma_get_stats() - * Statistics api used to retreive the tx/rx statistics - */ -struct net_device_stats *edma_get_stats(struct net_device *netdev) -{ - struct edma_adapter *adapter = netdev_priv(netdev); - - return &adapter->stats; -} - -/* edma_xmit() - * Main api to be called by the core for packet transmission - */ -netdev_tx_t edma_xmit(struct sk_buff *skb, - struct net_device *net_dev) -{ - struct edma_adapter *adapter = netdev_priv(net_dev); - struct edma_common_info *edma_cinfo = adapter->edma_cinfo; - struct edma_tx_desc_ring *etdr; - u16 from_cpu, dp_bitmap, txq_id; - int ret, nr_frags = 0, num_tpds_needed = 1, queue_id; - unsigned int flags_transmit = 0; - bool packet_is_rstp = false; - struct netdev_queue *nq = NULL; - - if (skb_shinfo(skb)->nr_frags) { - nr_frags = skb_shinfo(skb)->nr_frags; - num_tpds_needed += nr_frags; - } else if (skb_has_frag_list(skb)) { - struct sk_buff *iter_skb; - - skb_walk_frags(skb, iter_skb) - num_tpds_needed++; - } - - if (num_tpds_needed > EDMA_MAX_SKB_FRAGS) { - dev_err(&net_dev->dev, - "skb received with fragments %d which is more than %lu", - num_tpds_needed, EDMA_MAX_SKB_FRAGS); - dev_kfree_skb_any(skb); - adapter->stats.tx_errors++; - return NETDEV_TX_OK; - } - - if (edma_stp_rstp) { - u16 ath_hdr, ath_eth_type; - u8 mac_addr[EDMA_ETH_HDR_LEN]; - ath_eth_type = ntohs(*(uint16_t *)&skb->data[12]); - if (ath_eth_type == edma_ath_eth_type) { - packet_is_rstp = true; - ath_hdr = htons(*(uint16_t *)&skb->data[14]); - dp_bitmap = ath_hdr & EDMA_TX_ATH_HDR_PORT_BITMAP_MASK; - from_cpu = (ath_hdr & EDMA_TX_ATH_HDR_FROM_CPU_MASK) >> EDMA_TX_ATH_HDR_FROM_CPU_SHIFT; - memcpy(mac_addr, skb->data, EDMA_ETH_HDR_LEN); - - skb_pull(skb, 4); - - memcpy(skb->data, mac_addr, EDMA_ETH_HDR_LEN); - } - } - - /* this will be one of the 4 TX queues exposed to linux kernel */ - txq_id = skb_get_queue_mapping(skb); - queue_id = edma_tx_queue_get(adapter, skb, txq_id); - etdr = edma_cinfo->tpd_ring[queue_id]; - nq = netdev_get_tx_queue(net_dev, txq_id); - - local_bh_disable(); - /* Tx is not handled in bottom half context. Hence, we need to protect - * Tx from tasks and bottom half - */ - - if (num_tpds_needed > edma_tpd_available(edma_cinfo, queue_id)) { - /* not enough descriptor, just stop queue */ - netif_tx_stop_queue(nq); - local_bh_enable(); - dev_dbg(&net_dev->dev, "Not enough descriptors available"); - edma_cinfo->edma_ethstats.tx_desc_error++; - return NETDEV_TX_BUSY; - } - - /* Check and mark VLAN tag offload */ - if (!adapter->edma_cinfo->is_single_phy) { - if (unlikely(skb_vlan_tag_present(skb))) - flags_transmit |= EDMA_VLAN_TX_TAG_INSERT_FLAG; - else if (adapter->default_vlan_tag) - flags_transmit |= EDMA_VLAN_TX_TAG_INSERT_DEFAULT_FLAG; - } - - /* Check and mark checksum offload */ - if (likely(skb->ip_summed == CHECKSUM_PARTIAL)) - flags_transmit |= EDMA_HW_CHECKSUM; - - /* Map and fill descriptor for Tx */ - ret = edma_tx_map_and_fill(edma_cinfo, adapter, skb, queue_id, - flags_transmit, from_cpu, dp_bitmap, packet_is_rstp, nr_frags); - if (ret) { - dev_kfree_skb_any(skb); - adapter->stats.tx_errors++; - goto netdev_okay; - } - - /* Update SW producer index */ - edma_tx_update_hw_idx(edma_cinfo, skb, queue_id); - - /* update tx statistics */ - adapter->stats.tx_packets++; - adapter->stats.tx_bytes += skb->len; - -netdev_okay: - local_bh_enable(); - return NETDEV_TX_OK; -} - -/* - * edma_flow_may_expire() - * Timer function called periodically to delete the node - */ -void edma_flow_may_expire(struct timer_list *t) -{ - struct edma_rfs_flow_table *table = from_timer(table, t, expire_rfs); - struct edma_adapter *adapter = - container_of(table, typeof(*adapter), rfs); - int j; - - spin_lock_bh(&adapter->rfs.rfs_ftab_lock); - for (j = 0; j < EDMA_RFS_EXPIRE_COUNT_PER_CALL; j++) { - struct hlist_head *hhead; - struct hlist_node *tmp; - struct edma_rfs_filter_node *n; - bool res; - - hhead = &adapter->rfs.hlist_head[adapter->rfs.hashtoclean++]; - hlist_for_each_entry_safe(n, tmp, hhead, node) { - res = rps_may_expire_flow(adapter->netdev, n->rq_id, - n->flow_id, n->filter_id); - if (res) { - int ret; - ret = edma_delete_rfs_filter(adapter, n); - if (ret < 0) - dev_dbg(&adapter->netdev->dev, - "RFS entry %d not allowed to be flushed by Switch", - n->flow_id); - else { - hlist_del(&n->node); - kfree(n); - adapter->rfs.filter_available++; - } - } - } - } - - adapter->rfs.hashtoclean = adapter->rfs.hashtoclean & (EDMA_RFS_FLOW_ENTRIES - 1); - spin_unlock_bh(&adapter->rfs.rfs_ftab_lock); - mod_timer(&adapter->rfs.expire_rfs, jiffies + HZ / 4); -} - -/* edma_rx_flow_steer() - * Called by core to to steer the flow to CPU - */ -int edma_rx_flow_steer(struct net_device *dev, const struct sk_buff *skb, - u16 rxq, u32 flow_id) -{ - struct flow_keys keys; - struct edma_rfs_filter_node *filter_node; - struct edma_adapter *adapter = netdev_priv(dev); - u16 hash_tblid; - int res; - - if (skb->protocol == htons(ETH_P_IPV6)) { - dev_err(&adapter->pdev->dev, "IPv6 not supported\n"); - res = -EINVAL; - goto no_protocol_err; - } - - /* Dissect flow parameters - * We only support IPv4 + TCP/UDP - */ - res = skb_flow_dissect_flow_keys(skb, &keys, 0); - if (!((keys.basic.ip_proto == IPPROTO_TCP) || (keys.basic.ip_proto == IPPROTO_UDP))) { - res = -EPROTONOSUPPORT; - goto no_protocol_err; - } - - /* Check if table entry exists */ - hash_tblid = skb_get_hash_raw(skb) & EDMA_RFS_FLOW_ENTRIES_MASK; - - spin_lock_bh(&adapter->rfs.rfs_ftab_lock); - filter_node = edma_rfs_key_search(&adapter->rfs.hlist_head[hash_tblid], &keys); - - if (filter_node) { - if (rxq == filter_node->rq_id) { - res = -EEXIST; - goto out; - } else { - res = edma_delete_rfs_filter(adapter, filter_node); - if (res < 0) - dev_warn(&adapter->netdev->dev, - "Cannot steer flow %d to different queue", - filter_node->flow_id); - else { - adapter->rfs.filter_available++; - res = edma_add_rfs_filter(adapter, &keys, rxq, filter_node); - if (res < 0) { - dev_warn(&adapter->netdev->dev, - "Cannot steer flow %d to different queue", - filter_node->flow_id); - } else { - adapter->rfs.filter_available--; - filter_node->rq_id = rxq; - filter_node->filter_id = res; - } - } - } - } else { - if (adapter->rfs.filter_available == 0) { - res = -EBUSY; - goto out; - } - - filter_node = kmalloc(sizeof(*filter_node), GFP_ATOMIC); - if (!filter_node) { - res = -ENOMEM; - goto out; - } - - res = edma_add_rfs_filter(adapter, &keys, rxq, filter_node); - if (res < 0) { - kfree(filter_node); - goto out; - } - - adapter->rfs.filter_available--; - filter_node->rq_id = rxq; - filter_node->filter_id = res; - filter_node->flow_id = flow_id; - filter_node->keys = keys; - INIT_HLIST_NODE(&filter_node->node); - hlist_add_head(&filter_node->node, &adapter->rfs.hlist_head[hash_tblid]); - } - -out: - spin_unlock_bh(&adapter->rfs.rfs_ftab_lock); -no_protocol_err: - return res; -} - -/* edma_register_rfs_filter() - * Add RFS filter callback - */ -int edma_register_rfs_filter(struct net_device *netdev, - set_rfs_filter_callback_t set_filter) -{ - struct edma_adapter *adapter = netdev_priv(netdev); - - spin_lock_bh(&adapter->rfs.rfs_ftab_lock); - - if (adapter->set_rfs_rule) { - spin_unlock_bh(&adapter->rfs.rfs_ftab_lock); - return -1; - } - - adapter->set_rfs_rule = set_filter; - spin_unlock_bh(&adapter->rfs.rfs_ftab_lock); - - return 0; -} - -/* edma_alloc_tx_rings() - * Allocate rx rings - */ -int edma_alloc_tx_rings(struct edma_common_info *edma_cinfo) -{ - struct platform_device *pdev = edma_cinfo->pdev; - int i, err = 0; - - for (i = 0; i < edma_cinfo->num_tx_queues; i++) { - err = edma_alloc_tx_ring(edma_cinfo, edma_cinfo->tpd_ring[i]); - if (err) { - dev_err(&pdev->dev, "Tx Queue alloc %u failed\n", i); - return err; - } - } - - return 0; -} - -/* edma_free_tx_rings() - * Free tx rings - */ -void edma_free_tx_rings(struct edma_common_info *edma_cinfo) -{ - int i; - - for (i = 0; i < edma_cinfo->num_tx_queues; i++) - edma_free_tx_ring(edma_cinfo, edma_cinfo->tpd_ring[i]); -} - -/* edma_free_tx_resources() - * Free buffers associated with tx rings - */ -void edma_free_tx_resources(struct edma_common_info *edma_cinfo) -{ - struct edma_tx_desc_ring *etdr; - struct edma_sw_desc *sw_desc; - struct platform_device *pdev = edma_cinfo->pdev; - int i, j; - - for (i = 0; i < edma_cinfo->num_tx_queues; i++) { - etdr = edma_cinfo->tpd_ring[i]; - for (j = 0; j < EDMA_TX_RING_SIZE; j++) { - sw_desc = &etdr->sw_desc[j]; - if (sw_desc->flags & (EDMA_SW_DESC_FLAG_SKB_HEAD | - EDMA_SW_DESC_FLAG_SKB_FRAG | EDMA_SW_DESC_FLAG_SKB_FRAGLIST)) - edma_tx_unmap_and_free(pdev, sw_desc); - } - } -} - -/* edma_alloc_rx_rings() - * Allocate rx rings - */ -int edma_alloc_rx_rings(struct edma_common_info *edma_cinfo) -{ - struct platform_device *pdev = edma_cinfo->pdev; - int i, j, err = 0; - - for (i = 0, j = 0; i < edma_cinfo->num_rx_queues; i++) { - err = edma_alloc_rx_ring(edma_cinfo, edma_cinfo->rfd_ring[j]); - if (err) { - dev_err(&pdev->dev, "Rx Queue alloc%u failed\n", i); - return err; - } - j += ((edma_cinfo->num_rx_queues == 4) ? 2 : 1); - } - - return 0; -} - -/* edma_free_rx_rings() - * free rx rings - */ -void edma_free_rx_rings(struct edma_common_info *edma_cinfo) -{ - int i, j; - - for (i = 0, j = 0; i < edma_cinfo->num_rx_queues; i++) { - edma_free_rx_ring(edma_cinfo, edma_cinfo->rfd_ring[j]); - j += ((edma_cinfo->num_rx_queues == 4) ? 2 : 1); - } -} - -/* edma_free_queues() - * Free the queues allocaated - */ -void edma_free_queues(struct edma_common_info *edma_cinfo) -{ - int i , j; - - for (i = 0; i < edma_cinfo->num_tx_queues; i++) { - if (edma_cinfo->tpd_ring[i]) - kfree(edma_cinfo->tpd_ring[i]); - edma_cinfo->tpd_ring[i] = NULL; - } - - for (i = 0, j = 0; i < edma_cinfo->num_rx_queues; i++) { - if (edma_cinfo->rfd_ring[j]) - kfree(edma_cinfo->rfd_ring[j]); - edma_cinfo->rfd_ring[j] = NULL; - j += ((edma_cinfo->num_rx_queues == 4) ? 2 : 1); - } - - edma_cinfo->num_rx_queues = 0; - edma_cinfo->num_tx_queues = 0; - - return; -} - -/* edma_free_rx_resources() - * Free buffers associated with tx rings - */ -void edma_free_rx_resources(struct edma_common_info *edma_cinfo) -{ - struct edma_rfd_desc_ring *erdr; - struct edma_sw_desc *sw_desc; - struct platform_device *pdev = edma_cinfo->pdev; - int i, j, k; - - for (i = 0, k = 0; i < edma_cinfo->num_rx_queues; i++) { - erdr = edma_cinfo->rfd_ring[k]; - for (j = 0; j < EDMA_RX_RING_SIZE; j++) { - sw_desc = &erdr->sw_desc[j]; - if (likely(sw_desc->flags & EDMA_SW_DESC_FLAG_SKB_HEAD)) { - dma_unmap_single(&pdev->dev, sw_desc->dma, - sw_desc->length, DMA_FROM_DEVICE); - edma_clean_rfd(erdr, j); - } else if ((sw_desc->flags & EDMA_SW_DESC_FLAG_SKB_FRAG)) { - dma_unmap_page(&pdev->dev, sw_desc->dma, - sw_desc->length, DMA_FROM_DEVICE); - edma_clean_rfd(erdr, j); - } - } - k += ((edma_cinfo->num_rx_queues == 4) ? 2 : 1); - - } -} - -/* edma_alloc_queues_tx() - * Allocate memory for all rings - */ -int edma_alloc_queues_tx(struct edma_common_info *edma_cinfo) -{ - int i; - - for (i = 0; i < edma_cinfo->num_tx_queues; i++) { - struct edma_tx_desc_ring *etdr; - etdr = kzalloc(sizeof(struct edma_tx_desc_ring), GFP_KERNEL); - if (!etdr) - goto err; - etdr->count = edma_cinfo->tx_ring_count; - edma_cinfo->tpd_ring[i] = etdr; - } - - return 0; -err: - edma_free_queues(edma_cinfo); - return -1; -} - -/* edma_alloc_queues_rx() - * Allocate memory for all rings - */ -int edma_alloc_queues_rx(struct edma_common_info *edma_cinfo) -{ - int i, j; - - for (i = 0, j = 0; i < edma_cinfo->num_rx_queues; i++) { - struct edma_rfd_desc_ring *rfd_ring; - rfd_ring = kzalloc(sizeof(struct edma_rfd_desc_ring), - GFP_KERNEL); - if (!rfd_ring) - goto err; - rfd_ring->count = edma_cinfo->rx_ring_count; - edma_cinfo->rfd_ring[j] = rfd_ring; - j += ((edma_cinfo->num_rx_queues == 4) ? 2 : 1); - } - return 0; -err: - edma_free_queues(edma_cinfo); - return -1; -} - -/* edma_clear_irq_status() - * Clear interrupt status - */ -void edma_clear_irq_status() -{ - edma_write_reg(EDMA_REG_RX_ISR, 0xff); - edma_write_reg(EDMA_REG_TX_ISR, 0xffff); - edma_write_reg(EDMA_REG_MISC_ISR, 0x1fff); - edma_write_reg(EDMA_REG_WOL_ISR, 0x1); -}; - -/* edma_configure() - * Configure skb, edma interrupts and control register. - */ -int edma_configure(struct edma_common_info *edma_cinfo) -{ - struct edma_hw *hw = &edma_cinfo->hw; - u32 intr_modrt_data; - u32 intr_ctrl_data = 0; - int i, j, ret_count; - - edma_read_reg(EDMA_REG_INTR_CTRL, &intr_ctrl_data); - intr_ctrl_data &= ~(1 << EDMA_INTR_SW_IDX_W_TYP_SHIFT); - intr_ctrl_data |= hw->intr_sw_idx_w << EDMA_INTR_SW_IDX_W_TYP_SHIFT; - edma_write_reg(EDMA_REG_INTR_CTRL, intr_ctrl_data); - - edma_clear_irq_status(); - - /* Clear any WOL status */ - edma_write_reg(EDMA_REG_WOL_CTRL, 0); - intr_modrt_data = (EDMA_TX_IMT << EDMA_IRQ_MODRT_TX_TIMER_SHIFT); - intr_modrt_data |= (EDMA_RX_IMT << EDMA_IRQ_MODRT_RX_TIMER_SHIFT); - edma_write_reg(EDMA_REG_IRQ_MODRT_TIMER_INIT, intr_modrt_data); - edma_configure_tx(edma_cinfo); - edma_configure_rx(edma_cinfo); - - /* Allocate the RX buffer */ - for (i = 0, j = 0; i < edma_cinfo->num_rx_queues; i++) { - struct edma_rfd_desc_ring *ring = edma_cinfo->rfd_ring[j]; - ret_count = edma_alloc_rx_buf(edma_cinfo, ring, ring->count, j); - if (ret_count) { - dev_dbg(&edma_cinfo->pdev->dev, "not all rx buffers allocated\n"); - } - j += ((edma_cinfo->num_rx_queues == 4) ? 2 : 1); - } - - /* Configure descriptor Ring */ - edma_init_desc(edma_cinfo); - return 0; -} - -/* edma_irq_enable() - * Enable default interrupt generation settings - */ -void edma_irq_enable(struct edma_common_info *edma_cinfo) -{ - struct edma_hw *hw = &edma_cinfo->hw; - int i, j; - - edma_write_reg(EDMA_REG_RX_ISR, 0xff); - for (i = 0, j = 0; i < edma_cinfo->num_rx_queues; i++) { - edma_write_reg(EDMA_REG_RX_INT_MASK_Q(j), hw->rx_intr_mask); - j += ((edma_cinfo->num_rx_queues == 4) ? 2 : 1); - } - edma_write_reg(EDMA_REG_TX_ISR, 0xffff); - for (i = 0; i < edma_cinfo->num_tx_queues; i++) - edma_write_reg(EDMA_REG_TX_INT_MASK_Q(i), hw->tx_intr_mask); -} - -/* edma_irq_disable() - * Disable Interrupt - */ -void edma_irq_disable(struct edma_common_info *edma_cinfo) -{ - int i; - - for (i = 0; i < EDMA_MAX_RECEIVE_QUEUE; i++) - edma_write_reg(EDMA_REG_RX_INT_MASK_Q(i), 0x0); - - for (i = 0; i < EDMA_MAX_TRANSMIT_QUEUE; i++) - edma_write_reg(EDMA_REG_TX_INT_MASK_Q(i), 0x0); - edma_write_reg(EDMA_REG_MISC_IMR, 0); - edma_write_reg(EDMA_REG_WOL_IMR, 0); -} - -/* edma_free_irqs() - * Free All IRQs - */ -void edma_free_irqs(struct edma_adapter *adapter) -{ - struct edma_common_info *edma_cinfo = adapter->edma_cinfo; - int i, j; - int k = ((edma_cinfo->num_rx_queues == 4) ? 1 : 2); - - for (i = 0; i < CONFIG_NR_CPUS; i++) { - for (j = edma_cinfo->edma_percpu_info[i].tx_start; j < (edma_cinfo->edma_percpu_info[i].tx_start + 4); j++) - free_irq(edma_cinfo->tx_irq[j], &edma_cinfo->edma_percpu_info[i]); - - for (j = edma_cinfo->edma_percpu_info[i].rx_start; j < (edma_cinfo->edma_percpu_info[i].rx_start + k); j++) - free_irq(edma_cinfo->rx_irq[j], &edma_cinfo->edma_percpu_info[i]); - } -} - -/* edma_enable_rx_ctrl() - * Enable RX queue control - */ -void edma_enable_rx_ctrl(struct edma_hw *hw) -{ - u32 data; - - edma_read_reg(EDMA_REG_RXQ_CTRL, &data); - data |= EDMA_RXQ_CTRL_EN; - edma_write_reg(EDMA_REG_RXQ_CTRL, data); -} - - -/* edma_enable_tx_ctrl() - * Enable TX queue control - */ -void edma_enable_tx_ctrl(struct edma_hw *hw) -{ - u32 data; - - edma_read_reg(EDMA_REG_TXQ_CTRL, &data); - data |= EDMA_TXQ_CTRL_TXQ_EN; - edma_write_reg(EDMA_REG_TXQ_CTRL, data); -} - -/* edma_stop_rx_tx() - * Disable RX/TQ Queue control - */ -void edma_stop_rx_tx(struct edma_hw *hw) -{ - u32 data; - - edma_read_reg(EDMA_REG_RXQ_CTRL, &data); - data &= ~EDMA_RXQ_CTRL_EN; - edma_write_reg(EDMA_REG_RXQ_CTRL, data); - edma_read_reg(EDMA_REG_TXQ_CTRL, &data); - data &= ~EDMA_TXQ_CTRL_TXQ_EN; - edma_write_reg(EDMA_REG_TXQ_CTRL, data); -} - -/* edma_reset() - * Reset the EDMA - */ -int edma_reset(struct edma_common_info *edma_cinfo) -{ - struct edma_hw *hw = &edma_cinfo->hw; - - edma_irq_disable(edma_cinfo); - - edma_clear_irq_status(); - - edma_stop_rx_tx(hw); - - return 0; -} - -/* edma_fill_netdev() - * Fill netdev for each etdr - */ -int edma_fill_netdev(struct edma_common_info *edma_cinfo, int queue_id, - int dev, int txq_id) -{ - struct edma_tx_desc_ring *etdr; - int i = 0; - - etdr = edma_cinfo->tpd_ring[queue_id]; - - while (etdr->netdev[i]) - i++; - - if (i >= EDMA_MAX_NETDEV_PER_QUEUE) - return -1; - - /* Populate the netdev associated with the tpd ring */ - etdr->netdev[i] = edma_netdev[dev]; - etdr->nq[i] = netdev_get_tx_queue(edma_netdev[dev], txq_id); - - return 0; -} - -/* edma_set_mac() - * Change the Ethernet Address of the NIC - */ -int edma_set_mac_addr(struct net_device *netdev, void *p) -{ - struct sockaddr *addr = p; - - if (!is_valid_ether_addr(addr->sa_data)) - return -EINVAL; - - if (netif_running(netdev)) - return -EBUSY; - - memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len); - return 0; -} - -/* edma_set_stp_rstp() - * set stp/rstp - */ -void edma_set_stp_rstp(bool rstp) -{ - edma_stp_rstp = rstp; -} - -/* edma_assign_ath_hdr_type() - * assign atheros header eth type - */ -void edma_assign_ath_hdr_type(int eth_type) -{ - edma_ath_eth_type = eth_type & EDMA_ETH_TYPE_MASK; -} - -/* edma_get_default_vlan_tag() - * Used by other modules to get the default vlan tag - */ -int edma_get_default_vlan_tag(struct net_device *netdev) -{ - struct edma_adapter *adapter = netdev_priv(netdev); - - if (adapter->default_vlan_tag) - return adapter->default_vlan_tag; - - return 0; -} - -/* edma_open() - * gets called when netdevice is up, start the queue. - */ -int edma_open(struct net_device *netdev) -{ - struct edma_adapter *adapter = netdev_priv(netdev); - struct platform_device *pdev = adapter->edma_cinfo->pdev; - - netif_tx_start_all_queues(netdev); - edma_initialise_rfs_flow_table(adapter); - set_bit(__EDMA_UP, &adapter->state_flags); - - /* if Link polling is enabled, in our case enabled for WAN, then - * do a phy start, else always set link as UP - */ - if (adapter->poll_required) { - if (!IS_ERR(adapter->phydev)) { - phy_start(adapter->phydev); - phy_start_aneg(adapter->phydev); - adapter->link_state = __EDMA_LINKDOWN; - } else { - dev_dbg(&pdev->dev, "Invalid PHY device for a link polled interface\n"); - } - } else { - adapter->link_state = __EDMA_LINKUP; - netif_carrier_on(netdev); - } - - return 0; -} - - -/* edma_close() - * gets called when netdevice is down, stops the queue. - */ -int edma_close(struct net_device *netdev) -{ - struct edma_adapter *adapter = netdev_priv(netdev); - - edma_free_rfs_flow_table(adapter); - netif_carrier_off(netdev); - netif_tx_stop_all_queues(netdev); - - if (adapter->poll_required) { - if (!IS_ERR(adapter->phydev)) - phy_stop(adapter->phydev); - } - - adapter->link_state = __EDMA_LINKDOWN; - - /* Set GMAC state to UP before link state is checked - */ - clear_bit(__EDMA_UP, &adapter->state_flags); - - return 0; -} - -/* edma_poll - * polling function that gets called when the napi gets scheduled. - * - * Main sequence of task performed in this api - * is clear irq status -> clear_tx_irq -> clean_rx_irq-> - * enable interrupts. - */ -int edma_poll(struct napi_struct *napi, int budget) -{ - struct edma_per_cpu_queues_info *edma_percpu_info = container_of(napi, - struct edma_per_cpu_queues_info, napi); - struct edma_common_info *edma_cinfo = edma_percpu_info->edma_cinfo; - u32 reg_data; - u32 shadow_rx_status, shadow_tx_status; - int queue_id; - int i, work_done = 0; - u16 rx_pending_fill; - - /* Store the Rx/Tx status by ANDing it with - * appropriate CPU RX?TX mask - */ - edma_read_reg(EDMA_REG_RX_ISR, ®_data); - edma_percpu_info->rx_status |= reg_data & edma_percpu_info->rx_mask; - shadow_rx_status = edma_percpu_info->rx_status; - edma_read_reg(EDMA_REG_TX_ISR, ®_data); - edma_percpu_info->tx_status |= reg_data & edma_percpu_info->tx_mask; - shadow_tx_status = edma_percpu_info->tx_status; - - /* Every core will have a start, which will be computed - * in probe and stored in edma_percpu_info->tx_start variable. - * We will shift the status bit by tx_start to obtain - * status bits for the core on which the current processing - * is happening. Since, there are 4 tx queues per core, - * we will run the loop till we get the correct queue to clear. - */ - while (edma_percpu_info->tx_status) { - queue_id = ffs(edma_percpu_info->tx_status) - 1; - edma_tx_complete(edma_cinfo, queue_id); - edma_percpu_info->tx_status &= ~(1 << queue_id); - } - - /* Every core will have a start, which will be computed - * in probe and stored in edma_percpu_info->tx_start variable. - * We will shift the status bit by tx_start to obtain - * status bits for the core on which the current processing - * is happening. Since, there are 4 tx queues per core, we - * will run the loop till we get the correct queue to clear. - */ - while (edma_percpu_info->rx_status) { - queue_id = ffs(edma_percpu_info->rx_status) - 1; - rx_pending_fill = edma_rx_complete(edma_cinfo, &work_done, - budget, queue_id, napi); - - if (likely(work_done < budget)) { - if (rx_pending_fill) { - /* reschedule poll() to refill rx buffer deficit */ - work_done = budget; - break; - } - edma_percpu_info->rx_status &= ~(1 << queue_id); - } else { - break; - } - } - - /* Clear the status register, to avoid the interrupts to - * reoccur.This clearing of interrupt status register is - * done here as writing to status register only takes place - * once the producer/consumer index has been updated to - * reflect that the packet transmission/reception went fine. - */ - edma_write_reg(EDMA_REG_RX_ISR, shadow_rx_status); - edma_write_reg(EDMA_REG_TX_ISR, shadow_tx_status); - - /* If budget not fully consumed, exit the polling mode */ - if (likely(work_done < budget)) { - napi_complete(napi); - - /* re-enable the interrupts */ - for (i = 0; i < edma_cinfo->num_rxq_per_core; i++) - edma_write_reg(EDMA_REG_RX_INT_MASK_Q(edma_percpu_info->rx_start + i), 0x1); - for (i = 0; i < edma_cinfo->num_txq_per_core; i++) - edma_write_reg(EDMA_REG_TX_INT_MASK_Q(edma_percpu_info->tx_start + i), 0x1); - } - - return work_done; -} - -/* edma interrupt() - * interrupt handler - */ -irqreturn_t edma_interrupt(int irq, void *dev) -{ - struct edma_per_cpu_queues_info *edma_percpu_info = (struct edma_per_cpu_queues_info *) dev; - struct edma_common_info *edma_cinfo = edma_percpu_info->edma_cinfo; - int i; - - /* Unmask the TX/RX interrupt register */ - for (i = 0; i < edma_cinfo->num_rxq_per_core; i++) - edma_write_reg(EDMA_REG_RX_INT_MASK_Q(edma_percpu_info->rx_start + i), 0x0); - - for (i = 0; i < edma_cinfo->num_txq_per_core; i++) - edma_write_reg(EDMA_REG_TX_INT_MASK_Q(edma_percpu_info->tx_start + i), 0x0); - - napi_schedule(&edma_percpu_info->napi); - - return IRQ_HANDLED; -} diff --git a/root/target/linux/ipq40xx/files-5.4/drivers/net/ethernet/qualcomm/essedma/edma.h b/root/target/linux/ipq40xx/files-5.4/drivers/net/ethernet/qualcomm/essedma/edma.h deleted file mode 100644 index 015e5f50..00000000 --- a/root/target/linux/ipq40xx/files-5.4/drivers/net/ethernet/qualcomm/essedma/edma.h +++ /dev/null @@ -1,455 +0,0 @@ -/* - * Copyright (c) 2014 - 2016, The Linux Foundation. All rights reserved. - * - * Permission to use, copy, modify, and/or distribute this software for - * any purpose with or without fee is hereby granted, provided that the - * above copyright notice and this permission notice appear in all copies. - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT - * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _EDMA_H_ -#define _EDMA_H_ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "ess_edma.h" - -#define EDMA_CPU_CORES_SUPPORTED 4 -#define EDMA_MAX_PORTID_SUPPORTED 5 -#define EDMA_MAX_VLAN_SUPPORTED EDMA_MAX_PORTID_SUPPORTED -#define EDMA_MAX_PORTID_BITMAP_INDEX (EDMA_MAX_PORTID_SUPPORTED + 1) -#define EDMA_MAX_PORTID_BITMAP_SUPPORTED 0x1f /* 0001_1111 = 0x1f */ -#define EDMA_MAX_NETDEV_PER_QUEUE 4 /* 3 Netdev per queue, 1 space for indexing */ - -#define EDMA_MAX_RECEIVE_QUEUE 8 -#define EDMA_MAX_TRANSMIT_QUEUE 16 - -/* WAN/LAN adapter number */ -#define EDMA_WAN 0 -#define EDMA_LAN 1 - -/* VLAN tag */ -#define EDMA_LAN_DEFAULT_VLAN 1 -#define EDMA_WAN_DEFAULT_VLAN 2 - -#define EDMA_DEFAULT_GROUP1_VLAN 1 -#define EDMA_DEFAULT_GROUP2_VLAN 2 -#define EDMA_DEFAULT_GROUP3_VLAN 3 -#define EDMA_DEFAULT_GROUP4_VLAN 4 -#define EDMA_DEFAULT_GROUP5_VLAN 5 - -/* Queues exposed to linux kernel */ -#define EDMA_NETDEV_TX_QUEUE 4 -#define EDMA_NETDEV_RX_QUEUE 4 - -/* Number of queues per core */ -#define EDMA_NUM_TXQ_PER_CORE 4 -#define EDMA_NUM_RXQ_PER_CORE 2 - -#define EDMA_TPD_EOP_SHIFT 31 - -#define EDMA_PORT_ID_SHIFT 12 -#define EDMA_PORT_ID_MASK 0x7 - -/* tpd word 3 bit 18-28 */ -#define EDMA_TPD_PORT_BITMAP_SHIFT 18 - -#define EDMA_TPD_FROM_CPU_SHIFT 25 - -#define EDMA_FROM_CPU_MASK 0x80 -#define EDMA_SKB_PRIORITY_MASK 0x38 - -/* TX/RX descriptor ring count */ -/* should be a power of 2 */ -#define EDMA_RX_RING_SIZE 128 -#define EDMA_TX_RING_SIZE 128 - -/* Flags used in paged/non paged mode */ -#define EDMA_RX_HEAD_BUFF_SIZE_JUMBO 256 -#define EDMA_RX_HEAD_BUFF_SIZE 1540 - -/* MAX frame size supported by switch */ -#define EDMA_MAX_JUMBO_FRAME_SIZE 9216 - -/* Configurations */ -#define EDMA_INTR_CLEAR_TYPE 0 -#define EDMA_INTR_SW_IDX_W_TYPE 0 -#define EDMA_FIFO_THRESH_TYPE 0 -#define EDMA_RSS_TYPE 0 -#define EDMA_RX_IMT 0x0020 -#define EDMA_TX_IMT 0x0050 -#define EDMA_TPD_BURST 5 -#define EDMA_TXF_BURST 0x100 -#define EDMA_RFD_BURST 8 -#define EDMA_RFD_THR 16 -#define EDMA_RFD_LTHR 0 - -/* RX/TX per CPU based mask/shift */ -#define EDMA_TX_PER_CPU_MASK 0xF -#define EDMA_RX_PER_CPU_MASK 0x3 -#define EDMA_TX_PER_CPU_MASK_SHIFT 0x2 -#define EDMA_RX_PER_CPU_MASK_SHIFT 0x1 -#define EDMA_TX_CPU_START_SHIFT 0x2 -#define EDMA_RX_CPU_START_SHIFT 0x1 - -/* FLags used in transmit direction */ -#define EDMA_HW_CHECKSUM 0x00000001 -#define EDMA_VLAN_TX_TAG_INSERT_FLAG 0x00000002 -#define EDMA_VLAN_TX_TAG_INSERT_DEFAULT_FLAG 0x00000004 - -#define EDMA_SW_DESC_FLAG_LAST 0x1 -#define EDMA_SW_DESC_FLAG_SKB_HEAD 0x2 -#define EDMA_SW_DESC_FLAG_SKB_FRAG 0x4 -#define EDMA_SW_DESC_FLAG_SKB_FRAGLIST 0x8 -#define EDMA_SW_DESC_FLAG_SKB_NONE 0x10 -#define EDMA_SW_DESC_FLAG_SKB_REUSE 0x20 - - -#define EDMA_MAX_SKB_FRAGS (MAX_SKB_FRAGS + 1) - -/* Ethtool specific list of EDMA supported features */ -#define EDMA_SUPPORTED_FEATURES (SUPPORTED_10baseT_Half \ - | SUPPORTED_10baseT_Full \ - | SUPPORTED_100baseT_Half \ - | SUPPORTED_100baseT_Full \ - | SUPPORTED_1000baseT_Full) - -/* Recevie side atheros Header */ -#define EDMA_RX_ATH_HDR_VERSION 0x2 -#define EDMA_RX_ATH_HDR_VERSION_SHIFT 14 -#define EDMA_RX_ATH_HDR_PRIORITY_SHIFT 11 -#define EDMA_RX_ATH_PORT_TYPE_SHIFT 6 -#define EDMA_RX_ATH_HDR_RSTP_PORT_TYPE 0x4 - -/* Transmit side atheros Header */ -#define EDMA_TX_ATH_HDR_PORT_BITMAP_MASK 0x7F -#define EDMA_TX_ATH_HDR_FROM_CPU_MASK 0x80 -#define EDMA_TX_ATH_HDR_FROM_CPU_SHIFT 7 - -#define EDMA_TXQ_START_CORE0 8 -#define EDMA_TXQ_START_CORE1 12 -#define EDMA_TXQ_START_CORE2 0 -#define EDMA_TXQ_START_CORE3 4 - -#define EDMA_TXQ_IRQ_MASK_CORE0 0x0F00 -#define EDMA_TXQ_IRQ_MASK_CORE1 0xF000 -#define EDMA_TXQ_IRQ_MASK_CORE2 0x000F -#define EDMA_TXQ_IRQ_MASK_CORE3 0x00F0 - -#define EDMA_ETH_HDR_LEN 12 -#define EDMA_ETH_TYPE_MASK 0xFFFF - -#define EDMA_RX_BUFFER_WRITE 16 -#define EDMA_RFD_AVAIL_THR 80 - -#define EDMA_GMAC_NO_MDIO_PHY PHY_MAX_ADDR - -extern int ssdk_rfs_ipct_rule_set(__be32 ip_src, __be32 ip_dst, - __be16 sport, __be16 dport, - uint8_t proto, u16 loadbalance, bool action); -struct edma_ethtool_statistics { - u32 tx_q0_pkt; - u32 tx_q1_pkt; - u32 tx_q2_pkt; - u32 tx_q3_pkt; - u32 tx_q4_pkt; - u32 tx_q5_pkt; - u32 tx_q6_pkt; - u32 tx_q7_pkt; - u32 tx_q8_pkt; - u32 tx_q9_pkt; - u32 tx_q10_pkt; - u32 tx_q11_pkt; - u32 tx_q12_pkt; - u32 tx_q13_pkt; - u32 tx_q14_pkt; - u32 tx_q15_pkt; - u32 tx_q0_byte; - u32 tx_q1_byte; - u32 tx_q2_byte; - u32 tx_q3_byte; - u32 tx_q4_byte; - u32 tx_q5_byte; - u32 tx_q6_byte; - u32 tx_q7_byte; - u32 tx_q8_byte; - u32 tx_q9_byte; - u32 tx_q10_byte; - u32 tx_q11_byte; - u32 tx_q12_byte; - u32 tx_q13_byte; - u32 tx_q14_byte; - u32 tx_q15_byte; - u32 rx_q0_pkt; - u32 rx_q1_pkt; - u32 rx_q2_pkt; - u32 rx_q3_pkt; - u32 rx_q4_pkt; - u32 rx_q5_pkt; - u32 rx_q6_pkt; - u32 rx_q7_pkt; - u32 rx_q0_byte; - u32 rx_q1_byte; - u32 rx_q2_byte; - u32 rx_q3_byte; - u32 rx_q4_byte; - u32 rx_q5_byte; - u32 rx_q6_byte; - u32 rx_q7_byte; - u32 tx_desc_error; - u32 rx_alloc_fail_ctr; -}; - -struct edma_mdio_data { - struct mii_bus *mii_bus; - void __iomem *membase; - int phy_irq[PHY_MAX_ADDR]; -}; - -/* EDMA LINK state */ -enum edma_link_state { - __EDMA_LINKUP, /* Indicate link is UP */ - __EDMA_LINKDOWN /* Indicate link is down */ -}; - -/* EDMA GMAC state */ -enum edma_gmac_state { - __EDMA_UP /* use to indicate GMAC is up */ -}; - -/* edma transmit descriptor */ -struct edma_tx_desc { - __le16 len; /* full packet including CRC */ - __le16 svlan_tag; /* vlan tag */ - __le32 word1; /* byte 4-7 */ - __le32 addr; /* address of buffer */ - __le32 word3; /* byte 12 */ -}; - -/* edma receive return descriptor */ -struct edma_rx_return_desc { - u16 rrd0; - u16 rrd1; - u16 rrd2; - u16 rrd3; - u16 rrd4; - u16 rrd5; - u16 rrd6; - u16 rrd7; -}; - -/* RFD descriptor */ -struct edma_rx_free_desc { - __le32 buffer_addr; /* buffer address */ -}; - -/* edma hw specific data */ -struct edma_hw { - u32 __iomem *hw_addr; /* inner register address */ - struct edma_adapter *adapter; /* netdevice adapter */ - u32 rx_intr_mask; /*rx interrupt mask */ - u32 tx_intr_mask; /* tx interrupt nask */ - u32 misc_intr_mask; /* misc interrupt mask */ - u32 wol_intr_mask; /* wake on lan interrupt mask */ - bool intr_clear_type; /* interrupt clear */ - bool intr_sw_idx_w; /* interrupt software index */ - u32 rx_head_buff_size; /* Rx buffer size */ - u8 rss_type; /* rss protocol type */ -}; - -/* edma_sw_desc stores software descriptor - * SW descriptor has 1:1 map with HW descriptor - */ -struct edma_sw_desc { - struct sk_buff *skb; - dma_addr_t dma; /* dma address */ - u16 length; /* Tx/Rx buffer length */ - u32 flags; -}; - -/* per core related information */ -struct edma_per_cpu_queues_info { - struct napi_struct napi; /* napi associated with the core */ - u32 tx_mask; /* tx interrupt mask */ - u32 rx_mask; /* rx interrupt mask */ - u32 tx_status; /* tx interrupt status */ - u32 rx_status; /* rx interrupt status */ - u32 tx_start; /* tx queue start */ - u32 rx_start; /* rx queue start */ - struct edma_common_info *edma_cinfo; /* edma common info */ -}; - -/* edma specific common info */ -struct edma_common_info { - struct edma_tx_desc_ring *tpd_ring[16]; /* 16 Tx queues */ - struct edma_rfd_desc_ring *rfd_ring[8]; /* 8 Rx queues */ - struct platform_device *pdev; /* device structure */ - struct net_device *netdev[EDMA_MAX_PORTID_SUPPORTED]; - struct net_device *portid_netdev_lookup_tbl[EDMA_MAX_PORTID_BITMAP_INDEX]; - struct ctl_table_header *edma_ctl_table_hdr; - int num_gmac; - struct edma_ethtool_statistics edma_ethstats; /* ethtool stats */ - int num_rx_queues; /* number of rx queue */ - u32 num_tx_queues; /* number of tx queue */ - u32 tx_irq[16]; /* number of tx irq */ - u32 rx_irq[8]; /* number of rx irq */ - u32 from_cpu; /* from CPU TPD field */ - u32 num_rxq_per_core; /* Rx queues per core */ - u32 num_txq_per_core; /* Tx queues per core */ - u16 tx_ring_count; /* Tx ring count */ - u16 rx_ring_count; /* Rx ring*/ - u16 rx_head_buffer_len; /* rx buffer length */ - u16 rx_page_buffer_len; /* rx buffer length */ - u32 page_mode; /* Jumbo frame supported flag */ - u32 fraglist_mode; /* fraglist supported flag */ - struct edma_hw hw; /* edma hw specific structure */ - struct edma_per_cpu_queues_info edma_percpu_info[CONFIG_NR_CPUS]; /* per cpu information */ - spinlock_t stats_lock; /* protect edma stats area for updation */ - struct timer_list edma_stats_timer; - bool is_single_phy; - void __iomem *ess_hw_addr; - struct clk *ess_clk; -}; - -/* transimit packet descriptor (tpd) ring */ -struct edma_tx_desc_ring { - struct netdev_queue *nq[EDMA_MAX_NETDEV_PER_QUEUE]; /* Linux queue index */ - struct net_device *netdev[EDMA_MAX_NETDEV_PER_QUEUE]; - /* Array of netdevs associated with the tpd ring */ - void *hw_desc; /* descriptor ring virtual address */ - struct edma_sw_desc *sw_desc; /* buffer associated with ring */ - int netdev_bmp; /* Bitmap for per-ring netdevs */ - u32 size; /* descriptor ring length in bytes */ - u16 count; /* number of descriptors in the ring */ - dma_addr_t dma; /* descriptor ring physical address */ - u16 sw_next_to_fill; /* next Tx descriptor to fill */ - u16 sw_next_to_clean; /* next Tx descriptor to clean */ -}; - -/* receive free descriptor (rfd) ring */ -struct edma_rfd_desc_ring { - void *hw_desc; /* descriptor ring virtual address */ - struct edma_sw_desc *sw_desc; /* buffer associated with ring */ - u16 size; /* bytes allocated to sw_desc */ - u16 count; /* number of descriptors in the ring */ - dma_addr_t dma; /* descriptor ring physical address */ - u16 sw_next_to_fill; /* next descriptor to fill */ - u16 sw_next_to_clean; /* next descriptor to clean */ - u16 pending_fill; /* fill pending from previous iteration */ -}; - -/* edma_rfs_flter_node - rfs filter node in hash table */ -struct edma_rfs_filter_node { - struct flow_keys keys; - u32 flow_id; /* flow_id of filter provided by kernel */ - u16 filter_id; /* filter id of filter returned by adaptor */ - u16 rq_id; /* desired rq index */ - struct hlist_node node; /* edma rfs list node */ -}; - -/* edma_rfs_flow_tbl - rfs flow table */ -struct edma_rfs_flow_table { - u16 max_num_filter; /* Maximum number of filters edma supports */ - u16 hashtoclean; /* hash table index to clean next */ - int filter_available; /* Number of free filters available */ - struct hlist_head hlist_head[EDMA_RFS_FLOW_ENTRIES]; - spinlock_t rfs_ftab_lock; - struct timer_list expire_rfs; /* timer function for edma_rps_may_expire_flow */ -}; - -/* EDMA net device structure */ -struct edma_adapter { - struct net_device *netdev; /* netdevice */ - struct platform_device *pdev; /* platform device */ - struct edma_common_info *edma_cinfo; /* edma common info */ - struct phy_device *phydev; /* Phy device */ - struct edma_rfs_flow_table rfs; /* edma rfs flow table */ - struct net_device_stats stats; /* netdev statistics */ - set_rfs_filter_callback_t set_rfs_rule; - u32 flags;/* status flags */ - unsigned long state_flags; /* GMAC up/down flags */ - u32 forced_speed; /* link force speed */ - u32 forced_duplex; /* link force duplex */ - u32 link_state; /* phy link state */ - u32 phy_mdio_addr; /* PHY device address on MII interface */ - u32 poll_required; /* check if link polling is required */ - u32 tx_start_offset[CONFIG_NR_CPUS]; /* tx queue start */ - u32 default_vlan_tag; /* vlan tag */ - u32 dp_bitmap; - uint8_t phy_id[MII_BUS_ID_SIZE + 3]; -}; - -int edma_alloc_queues_tx(struct edma_common_info *edma_cinfo); -int edma_alloc_queues_rx(struct edma_common_info *edma_cinfo); -int edma_open(struct net_device *netdev); -int edma_close(struct net_device *netdev); -void edma_free_tx_resources(struct edma_common_info *edma_c_info); -void edma_free_rx_resources(struct edma_common_info *edma_c_info); -int edma_alloc_tx_rings(struct edma_common_info *edma_cinfo); -int edma_alloc_rx_rings(struct edma_common_info *edma_cinfo); -void edma_free_tx_rings(struct edma_common_info *edma_cinfo); -void edma_free_rx_rings(struct edma_common_info *edma_cinfo); -void edma_free_queues(struct edma_common_info *edma_cinfo); -void edma_irq_disable(struct edma_common_info *edma_cinfo); -int edma_reset(struct edma_common_info *edma_cinfo); -int edma_poll(struct napi_struct *napi, int budget); -netdev_tx_t edma_xmit(struct sk_buff *skb, - struct net_device *netdev); -int edma_configure(struct edma_common_info *edma_cinfo); -void edma_irq_enable(struct edma_common_info *edma_cinfo); -void edma_enable_tx_ctrl(struct edma_hw *hw); -void edma_enable_rx_ctrl(struct edma_hw *hw); -void edma_stop_rx_tx(struct edma_hw *hw); -void edma_free_irqs(struct edma_adapter *adapter); -irqreturn_t edma_interrupt(int irq, void *dev); -void edma_write_reg(u16 reg_addr, u32 reg_value); -void edma_read_reg(u16 reg_addr, volatile u32 *reg_value); -struct net_device_stats *edma_get_stats(struct net_device *netdev); -int edma_set_mac_addr(struct net_device *netdev, void *p); -int edma_rx_flow_steer(struct net_device *dev, const struct sk_buff *skb, - u16 rxq, u32 flow_id); -int edma_register_rfs_filter(struct net_device *netdev, - set_rfs_filter_callback_t set_filter); -void edma_flow_may_expire(struct timer_list *t); -void edma_set_ethtool_ops(struct net_device *netdev); -void edma_set_stp_rstp(bool tag); -void edma_assign_ath_hdr_type(int tag); -int edma_get_default_vlan_tag(struct net_device *netdev); -void edma_adjust_link(struct net_device *netdev); -int edma_fill_netdev(struct edma_common_info *edma_cinfo, int qid, int num, int txq_id); -void edma_read_append_stats(struct edma_common_info *edma_cinfo); -void edma_change_tx_coalesce(int usecs); -void edma_change_rx_coalesce(int usecs); -void edma_get_tx_rx_coalesce(u32 *reg_val); -void edma_clear_irq_status(void); -void ess_set_port_status_speed(struct edma_common_info *edma_cinfo, - struct phy_device *phydev, uint8_t port_id); -#endif /* _EDMA_H_ */ diff --git a/root/target/linux/ipq40xx/files-5.4/drivers/net/ethernet/qualcomm/essedma/edma_axi.c b/root/target/linux/ipq40xx/files-5.4/drivers/net/ethernet/qualcomm/essedma/edma_axi.c deleted file mode 100644 index 50335b0d..00000000 --- a/root/target/linux/ipq40xx/files-5.4/drivers/net/ethernet/qualcomm/essedma/edma_axi.c +++ /dev/null @@ -1,1359 +0,0 @@ -/* - * Copyright (c) 2014 - 2016, The Linux Foundation. All rights reserved. - * - * Permission to use, copy, modify, and/or distribute this software for - * any purpose with or without fee is hereby granted, provided that the - * above copyright notice and this permission notice appear in all copies. - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT - * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "edma.h" -#include "ess_edma.h" - -/* Weight round robin and virtual QID mask */ -#define EDMA_WRR_VID_SCTL_MASK 0xffff - -/* Weight round robin and virtual QID shift */ -#define EDMA_WRR_VID_SCTL_SHIFT 16 - -char edma_axi_driver_name[] = "ess_edma"; -static const u32 default_msg = NETIF_MSG_DRV | NETIF_MSG_PROBE | - NETIF_MSG_LINK | NETIF_MSG_TIMER | NETIF_MSG_IFDOWN | NETIF_MSG_IFUP; - -static u32 edma_hw_addr; - -char edma_tx_irq[16][64]; -char edma_rx_irq[8][64]; -struct net_device *edma_netdev[EDMA_MAX_PORTID_SUPPORTED]; -static u16 tx_start[4] = {EDMA_TXQ_START_CORE0, EDMA_TXQ_START_CORE1, - EDMA_TXQ_START_CORE2, EDMA_TXQ_START_CORE3}; -static u32 tx_mask[4] = {EDMA_TXQ_IRQ_MASK_CORE0, EDMA_TXQ_IRQ_MASK_CORE1, - EDMA_TXQ_IRQ_MASK_CORE2, EDMA_TXQ_IRQ_MASK_CORE3}; - -static u32 edma_default_ltag __read_mostly = EDMA_LAN_DEFAULT_VLAN; -static u32 edma_default_wtag __read_mostly = EDMA_WAN_DEFAULT_VLAN; -static u32 edma_default_group1_vtag __read_mostly = EDMA_DEFAULT_GROUP1_VLAN; -static u32 edma_default_group2_vtag __read_mostly = EDMA_DEFAULT_GROUP2_VLAN; -static u32 edma_default_group3_vtag __read_mostly = EDMA_DEFAULT_GROUP3_VLAN; -static u32 edma_default_group4_vtag __read_mostly = EDMA_DEFAULT_GROUP4_VLAN; -static u32 edma_default_group5_vtag __read_mostly = EDMA_DEFAULT_GROUP5_VLAN; -static u32 edma_rss_idt_val = EDMA_RSS_IDT_VALUE; -static u32 edma_rss_idt_idx; - -static int edma_weight_assigned_to_q __read_mostly; -static int edma_queue_to_virtual_q __read_mostly; -static bool edma_enable_rstp __read_mostly; -static int edma_athr_hdr_eth_type __read_mostly; - -static int page_mode; -module_param(page_mode, int, 0); -MODULE_PARM_DESC(page_mode, "enable page mode"); - -static int overwrite_mode; -module_param(overwrite_mode, int, 0); -MODULE_PARM_DESC(overwrite_mode, "overwrite default page_mode setting"); - -static int jumbo_mru = EDMA_RX_HEAD_BUFF_SIZE; -module_param(jumbo_mru, int, 0); -MODULE_PARM_DESC(jumbo_mru, "enable fraglist support"); - -static int num_rxq = 4; -module_param(num_rxq, int, 0); -MODULE_PARM_DESC(num_rxq, "change the number of rx queues"); - -void edma_write_reg(u16 reg_addr, u32 reg_value) -{ - writel(reg_value, ((void __iomem *)(edma_hw_addr + reg_addr))); -} - -void edma_read_reg(u16 reg_addr, volatile u32 *reg_value) -{ - *reg_value = readl((void __iomem *)(edma_hw_addr + reg_addr)); -} - -static void ess_write_reg(struct edma_common_info *edma, u16 reg_addr, u32 reg_value) -{ - writel(reg_value, ((void __iomem *) - ((unsigned long)edma->ess_hw_addr + reg_addr))); -} - -static void ess_read_reg(struct edma_common_info *edma, u16 reg_addr, - volatile u32 *reg_value) -{ - *reg_value = readl((void __iomem *) - ((unsigned long)edma->ess_hw_addr + reg_addr)); -} - -static int ess_reset(struct edma_common_info *edma) -{ - struct device_node *switch_node = NULL; - struct reset_control *ess_rst; - u32 regval; - - switch_node = of_find_node_by_name(NULL, "ess-switch"); - if (!switch_node) { - pr_err("switch-node not found\n"); - return -EINVAL; - } - - ess_rst = of_reset_control_get(switch_node, "ess_rst"); - of_node_put(switch_node); - - if (IS_ERR(ess_rst)) { - pr_err("failed to find ess_rst!\n"); - return -ENOENT; - } - - reset_control_assert(ess_rst); - msleep(10); - reset_control_deassert(ess_rst); - msleep(100); - reset_control_put(ess_rst); - - /* Enable only port 5 <--> port 0 - * bits 0:6 bitmap of ports it can fwd to */ -#define SET_PORT_BMP(r,v) \ - ess_read_reg(edma, r, ®val); \ - ess_write_reg(edma, r, ((regval & ~0x3F) | v)); - - SET_PORT_BMP(ESS_PORT0_LOOKUP_CTRL,0x20); - SET_PORT_BMP(ESS_PORT1_LOOKUP_CTRL,0x00); - SET_PORT_BMP(ESS_PORT2_LOOKUP_CTRL,0x00); - SET_PORT_BMP(ESS_PORT3_LOOKUP_CTRL,0x00); - SET_PORT_BMP(ESS_PORT4_LOOKUP_CTRL,0x00); - SET_PORT_BMP(ESS_PORT5_LOOKUP_CTRL,0x01); - ess_write_reg(edma, ESS_RGMII_CTRL, 0x400); - ess_write_reg(edma, ESS_PORT0_STATUS, ESS_PORT_1G_FDX); - ess_write_reg(edma, ESS_PORT5_STATUS, ESS_PORT_1G_FDX); - ess_write_reg(edma, ESS_PORT0_HEADER_CTRL, 0); -#undef SET_PORT_BMP - - /* forward multicast and broadcast frames to CPU */ - ess_write_reg(edma, ESS_FWD_CTRL1, - (ESS_PORTS_ALL << ESS_FWD_CTRL1_UC_FLOOD_S) | - (ESS_PORTS_ALL << ESS_FWD_CTRL1_MC_FLOOD_S) | - (ESS_PORTS_ALL << ESS_FWD_CTRL1_BC_FLOOD_S)); - - return 0; -} - -void ess_set_port_status_speed(struct edma_common_info *edma, - struct phy_device *phydev, uint8_t port_id) -{ - uint16_t reg_off = ESS_PORT0_STATUS + (4 * port_id); - uint32_t reg_val = 0; - - ess_read_reg(edma, reg_off, ®_val); - - /* reset the speed bits [0:1] */ - reg_val &= ~ESS_PORT_STATUS_SPEED_INV; - - /* set the new speed */ - switch(phydev->speed) { - case SPEED_1000: reg_val |= ESS_PORT_STATUS_SPEED_1000; break; - case SPEED_100: reg_val |= ESS_PORT_STATUS_SPEED_100; break; - case SPEED_10: reg_val |= ESS_PORT_STATUS_SPEED_10; break; - default: reg_val |= ESS_PORT_STATUS_SPEED_INV; break; - } - - /* check full/half duplex */ - if (phydev->duplex) { - reg_val |= ESS_PORT_STATUS_DUPLEX_MODE; - } else { - reg_val &= ~ESS_PORT_STATUS_DUPLEX_MODE; - } - - ess_write_reg(edma, reg_off, reg_val); -} - -/* edma_change_tx_coalesce() - * change tx interrupt moderation timer - */ -void edma_change_tx_coalesce(int usecs) -{ - u32 reg_value; - - /* Here, we right shift the value from the user by 1, this is - * done because IMT resolution timer is 2usecs. 1 count - * of this register corresponds to 2 usecs. - */ - edma_read_reg(EDMA_REG_IRQ_MODRT_TIMER_INIT, ®_value); - reg_value = ((reg_value & 0xffff) | ((usecs >> 1) << 16)); - edma_write_reg(EDMA_REG_IRQ_MODRT_TIMER_INIT, reg_value); -} - -/* edma_change_rx_coalesce() - * change rx interrupt moderation timer - */ -void edma_change_rx_coalesce(int usecs) -{ - u32 reg_value; - - /* Here, we right shift the value from the user by 1, this is - * done because IMT resolution timer is 2usecs. 1 count - * of this register corresponds to 2 usecs. - */ - edma_read_reg(EDMA_REG_IRQ_MODRT_TIMER_INIT, ®_value); - reg_value = ((reg_value & 0xffff0000) | (usecs >> 1)); - edma_write_reg(EDMA_REG_IRQ_MODRT_TIMER_INIT, reg_value); -} - -/* edma_get_tx_rx_coalesce() - * Get tx/rx interrupt moderation value - */ -void edma_get_tx_rx_coalesce(u32 *reg_val) -{ - edma_read_reg(EDMA_REG_IRQ_MODRT_TIMER_INIT, reg_val); -} - -void edma_read_append_stats(struct edma_common_info *edma_cinfo) -{ - uint32_t *p; - int i; - u32 stat; - - spin_lock_bh(&edma_cinfo->stats_lock); - p = (uint32_t *)&(edma_cinfo->edma_ethstats); - - for (i = 0; i < EDMA_MAX_TRANSMIT_QUEUE; i++) { - edma_read_reg(EDMA_REG_TX_STAT_PKT_Q(i), &stat); - *p += stat; - p++; - } - - for (i = 0; i < EDMA_MAX_TRANSMIT_QUEUE; i++) { - edma_read_reg(EDMA_REG_TX_STAT_BYTE_Q(i), &stat); - *p += stat; - p++; - } - - for (i = 0; i < EDMA_MAX_RECEIVE_QUEUE; i++) { - edma_read_reg(EDMA_REG_RX_STAT_PKT_Q(i), &stat); - *p += stat; - p++; - } - - for (i = 0; i < EDMA_MAX_RECEIVE_QUEUE; i++) { - edma_read_reg(EDMA_REG_RX_STAT_BYTE_Q(i), &stat); - *p += stat; - p++; - } - - spin_unlock_bh(&edma_cinfo->stats_lock); -} - -static void edma_statistics_timer(struct timer_list *t) -{ - struct edma_common_info *edma_cinfo = - from_timer(edma_cinfo, t, edma_stats_timer); - - edma_read_append_stats(edma_cinfo); - - mod_timer(&edma_cinfo->edma_stats_timer, jiffies + 1*HZ); -} - -static int edma_enable_stp_rstp(struct ctl_table *table, int write, - void __user *buffer, size_t *lenp, - loff_t *ppos) -{ - int ret; - - ret = proc_dointvec(table, write, buffer, lenp, ppos); - if (write) - edma_set_stp_rstp(edma_enable_rstp); - - return ret; -} - -static int edma_ath_hdr_eth_type(struct ctl_table *table, int write, - void __user *buffer, size_t *lenp, - loff_t *ppos) -{ - int ret; - - ret = proc_dointvec(table, write, buffer, lenp, ppos); - if (write) - edma_assign_ath_hdr_type(edma_athr_hdr_eth_type); - - return ret; -} - -static int edma_change_default_lan_vlan(struct ctl_table *table, int write, - void __user *buffer, size_t *lenp, - loff_t *ppos) -{ - struct edma_adapter *adapter; - int ret; - - if (!edma_netdev[1]) { - pr_err("Netdevice for default_lan does not exist\n"); - return -1; - } - - adapter = netdev_priv(edma_netdev[1]); - - ret = proc_dointvec(table, write, buffer, lenp, ppos); - - if (write) - adapter->default_vlan_tag = edma_default_ltag; - - return ret; -} - -static int edma_change_default_wan_vlan(struct ctl_table *table, int write, - void __user *buffer, size_t *lenp, - loff_t *ppos) -{ - struct edma_adapter *adapter; - int ret; - - if (!edma_netdev[0]) { - pr_err("Netdevice for default_wan does not exist\n"); - return -1; - } - - adapter = netdev_priv(edma_netdev[0]); - - ret = proc_dointvec(table, write, buffer, lenp, ppos); - - if (write) - adapter->default_vlan_tag = edma_default_wtag; - - return ret; -} - -static int edma_change_group1_vtag(struct ctl_table *table, int write, - void __user *buffer, size_t *lenp, - loff_t *ppos) -{ - struct edma_adapter *adapter; - struct edma_common_info *edma_cinfo; - int ret; - - if (!edma_netdev[0]) { - pr_err("Netdevice for Group 1 does not exist\n"); - return -1; - } - - adapter = netdev_priv(edma_netdev[0]); - edma_cinfo = adapter->edma_cinfo; - - ret = proc_dointvec(table, write, buffer, lenp, ppos); - - if (write) - adapter->default_vlan_tag = edma_default_group1_vtag; - - return ret; -} - -static int edma_change_group2_vtag(struct ctl_table *table, int write, - void __user *buffer, size_t *lenp, - loff_t *ppos) -{ - struct edma_adapter *adapter; - struct edma_common_info *edma_cinfo; - int ret; - - if (!edma_netdev[1]) { - pr_err("Netdevice for Group 2 does not exist\n"); - return -1; - } - - adapter = netdev_priv(edma_netdev[1]); - edma_cinfo = adapter->edma_cinfo; - - ret = proc_dointvec(table, write, buffer, lenp, ppos); - - if (write) - adapter->default_vlan_tag = edma_default_group2_vtag; - - return ret; -} - -static int edma_change_group3_vtag(struct ctl_table *table, int write, - void __user *buffer, size_t *lenp, - loff_t *ppos) -{ - struct edma_adapter *adapter; - struct edma_common_info *edma_cinfo; - int ret; - - if (!edma_netdev[2]) { - pr_err("Netdevice for Group 3 does not exist\n"); - return -1; - } - - adapter = netdev_priv(edma_netdev[2]); - edma_cinfo = adapter->edma_cinfo; - - ret = proc_dointvec(table, write, buffer, lenp, ppos); - - if (write) - adapter->default_vlan_tag = edma_default_group3_vtag; - - return ret; -} - -static int edma_change_group4_vtag(struct ctl_table *table, int write, - void __user *buffer, size_t *lenp, - loff_t *ppos) -{ - struct edma_adapter *adapter; - struct edma_common_info *edma_cinfo; - int ret; - - if (!edma_netdev[3]) { - pr_err("Netdevice for Group 4 does not exist\n"); - return -1; - } - - adapter = netdev_priv(edma_netdev[3]); - edma_cinfo = adapter->edma_cinfo; - - ret = proc_dointvec(table, write, buffer, lenp, ppos); - - if (write) - adapter->default_vlan_tag = edma_default_group4_vtag; - - return ret; -} - -static int edma_change_group5_vtag(struct ctl_table *table, int write, - void __user *buffer, size_t *lenp, - loff_t *ppos) -{ - struct edma_adapter *adapter; - struct edma_common_info *edma_cinfo; - int ret; - - if (!edma_netdev[4]) { - pr_err("Netdevice for Group 5 does not exist\n"); - return -1; - } - - adapter = netdev_priv(edma_netdev[4]); - edma_cinfo = adapter->edma_cinfo; - - ret = proc_dointvec(table, write, buffer, lenp, ppos); - - if (write) - adapter->default_vlan_tag = edma_default_group5_vtag; - - return ret; -} - -static int edma_set_rss_idt_value(struct ctl_table *table, int write, - void __user *buffer, size_t *lenp, - loff_t *ppos) -{ - int ret; - - ret = proc_dointvec(table, write, buffer, lenp, ppos); - if (write && !ret) - edma_write_reg(EDMA_REG_RSS_IDT(edma_rss_idt_idx), - edma_rss_idt_val); - return ret; -} - -static int edma_set_rss_idt_idx(struct ctl_table *table, int write, - void __user *buffer, size_t *lenp, - loff_t *ppos) -{ - int ret; - u32 old_value = edma_rss_idt_idx; - - ret = proc_dointvec(table, write, buffer, lenp, ppos); - if (!write || ret) - return ret; - - if (edma_rss_idt_idx >= EDMA_NUM_IDT) { - pr_err("Invalid RSS indirection table index %d\n", - edma_rss_idt_idx); - edma_rss_idt_idx = old_value; - return -EINVAL; - } - return ret; -} - -static int edma_weight_assigned_to_queues(struct ctl_table *table, int write, - void __user *buffer, size_t *lenp, - loff_t *ppos) -{ - int ret, queue_id, weight; - u32 reg_data, data, reg_addr; - - ret = proc_dointvec(table, write, buffer, lenp, ppos); - if (write) { - queue_id = edma_weight_assigned_to_q & EDMA_WRR_VID_SCTL_MASK; - if (queue_id < 0 || queue_id > 15) { - pr_err("queue_id not within desired range\n"); - return -EINVAL; - } - - weight = edma_weight_assigned_to_q >> EDMA_WRR_VID_SCTL_SHIFT; - if (weight < 0 || weight > 0xF) { - pr_err("queue_id not within desired range\n"); - return -EINVAL; - } - - data = weight << EDMA_WRR_SHIFT(queue_id); - - reg_addr = EDMA_REG_WRR_CTRL_Q0_Q3 + (queue_id & ~0x3); - edma_read_reg(reg_addr, ®_data); - reg_data &= ~(1 << EDMA_WRR_SHIFT(queue_id)); - edma_write_reg(reg_addr, data | reg_data); - } - - return ret; -} - -static int edma_queue_to_virtual_queue_map(struct ctl_table *table, int write, - void __user *buffer, size_t *lenp, - loff_t *ppos) -{ - int ret, queue_id, virtual_qid; - u32 reg_data, data, reg_addr; - - ret = proc_dointvec(table, write, buffer, lenp, ppos); - if (write) { - queue_id = edma_queue_to_virtual_q & EDMA_WRR_VID_SCTL_MASK; - if (queue_id < 0 || queue_id > 15) { - pr_err("queue_id not within desired range\n"); - return -EINVAL; - } - - virtual_qid = edma_queue_to_virtual_q >> - EDMA_WRR_VID_SCTL_SHIFT; - if (virtual_qid < 0 || virtual_qid > 8) { - pr_err("queue_id not within desired range\n"); - return -EINVAL; - } - - data = virtual_qid << EDMA_VQ_ID_SHIFT(queue_id); - - reg_addr = EDMA_REG_VQ_CTRL0 + (queue_id & ~0x3); - edma_read_reg(reg_addr, ®_data); - reg_data &= ~(1 << EDMA_VQ_ID_SHIFT(queue_id)); - edma_write_reg(reg_addr, data | reg_data); - } - - return ret; -} - -static struct ctl_table edma_table[] = { - { - .procname = "default_lan_tag", - .data = &edma_default_ltag, - .maxlen = sizeof(int), - .mode = 0644, - .proc_handler = edma_change_default_lan_vlan - }, - { - .procname = "default_wan_tag", - .data = &edma_default_wtag, - .maxlen = sizeof(int), - .mode = 0644, - .proc_handler = edma_change_default_wan_vlan - }, - { - .procname = "weight_assigned_to_queues", - .data = &edma_weight_assigned_to_q, - .maxlen = sizeof(int), - .mode = 0644, - .proc_handler = edma_weight_assigned_to_queues - }, - { - .procname = "queue_to_virtual_queue_map", - .data = &edma_queue_to_virtual_q, - .maxlen = sizeof(int), - .mode = 0644, - .proc_handler = edma_queue_to_virtual_queue_map - }, - { - .procname = "enable_stp_rstp", - .data = &edma_enable_rstp, - .maxlen = sizeof(int), - .mode = 0644, - .proc_handler = edma_enable_stp_rstp - }, - { - .procname = "athr_hdr_eth_type", - .data = &edma_athr_hdr_eth_type, - .maxlen = sizeof(int), - .mode = 0644, - .proc_handler = edma_ath_hdr_eth_type - }, - { - .procname = "default_group1_vlan_tag", - .data = &edma_default_group1_vtag, - .maxlen = sizeof(int), - .mode = 0644, - .proc_handler = edma_change_group1_vtag - }, - { - .procname = "default_group2_vlan_tag", - .data = &edma_default_group2_vtag, - .maxlen = sizeof(int), - .mode = 0644, - .proc_handler = edma_change_group2_vtag - }, - { - .procname = "default_group3_vlan_tag", - .data = &edma_default_group3_vtag, - .maxlen = sizeof(int), - .mode = 0644, - .proc_handler = edma_change_group3_vtag - }, - { - .procname = "default_group4_vlan_tag", - .data = &edma_default_group4_vtag, - .maxlen = sizeof(int), - .mode = 0644, - .proc_handler = edma_change_group4_vtag - }, - { - .procname = "default_group5_vlan_tag", - .data = &edma_default_group5_vtag, - .maxlen = sizeof(int), - .mode = 0644, - .proc_handler = edma_change_group5_vtag - }, - { - .procname = "edma_rss_idt_value", - .data = &edma_rss_idt_val, - .maxlen = sizeof(int), - .mode = 0644, - .proc_handler = edma_set_rss_idt_value - }, - { - .procname = "edma_rss_idt_idx", - .data = &edma_rss_idt_idx, - .maxlen = sizeof(int), - .mode = 0644, - .proc_handler = edma_set_rss_idt_idx - }, - {} -}; - -static int ess_parse(struct edma_common_info *edma) -{ - struct device_node *switch_node; - int ret = -EINVAL; - - switch_node = of_find_node_by_name(NULL, "ess-switch"); - if (!switch_node) { - pr_err("cannot find ess-switch node\n"); - goto out; - } - - edma->ess_hw_addr = of_io_request_and_map(switch_node, - 0, KBUILD_MODNAME); - if (!edma->ess_hw_addr) { - pr_err("%s ioremap fail.", __func__); - goto out; - } - - edma->ess_clk = of_clk_get_by_name(switch_node, "ess_clk"); - ret = clk_prepare_enable(edma->ess_clk); -out: - of_node_put(switch_node); - return ret; -} - -/* edma_axi_netdev_ops - * Describe the operations supported by registered netdevices - * - * static const struct net_device_ops edma_axi_netdev_ops = { - * .ndo_open = edma_open, - * .ndo_stop = edma_close, - * .ndo_start_xmit = edma_xmit_frame, - * .ndo_set_mac_address = edma_set_mac_addr, - * } - */ -static const struct net_device_ops edma_axi_netdev_ops = { - .ndo_open = edma_open, - .ndo_stop = edma_close, - .ndo_start_xmit = edma_xmit, - .ndo_set_mac_address = edma_set_mac_addr, -#ifdef CONFIG_RFS_ACCEL - .ndo_rx_flow_steer = edma_rx_flow_steer, - .ndo_register_rfs_filter = edma_register_rfs_filter, - .ndo_get_default_vlan_tag = edma_get_default_vlan_tag, -#endif - .ndo_get_stats = edma_get_stats, -}; - -/* edma_axi_probe() - * Initialise an adapter identified by a platform_device structure. - * - * The OS initialization, configuring of the adapter private structure, - * and a hardware reset occur in the probe. - */ -static int edma_axi_probe(struct platform_device *pdev) -{ - struct edma_common_info *edma_cinfo; - struct edma_hw *hw; - struct edma_adapter *adapter[EDMA_MAX_PORTID_SUPPORTED]; - struct resource *res; - struct device_node *np = pdev->dev.of_node; - struct device_node *pnp; - struct device_node *mdio_node = NULL; - struct platform_device *mdio_plat = NULL; - struct mii_bus *miibus = NULL; - struct edma_mdio_data *mdio_data = NULL; - int i, j, k, err = 0; - int portid_bmp; - int idx = 0, idx_mac = 0; - - if (CONFIG_NR_CPUS != EDMA_CPU_CORES_SUPPORTED) { - dev_err(&pdev->dev, "Invalid CPU Cores\n"); - return -EINVAL; - } - - if ((num_rxq != 4) && (num_rxq != 8)) { - dev_err(&pdev->dev, "Invalid RX queue, edma probe failed\n"); - return -EINVAL; - } - edma_cinfo = kzalloc(sizeof(struct edma_common_info), GFP_KERNEL); - if (!edma_cinfo) { - err = -ENOMEM; - goto err_alloc; - } - - edma_cinfo->pdev = pdev; - - of_property_read_u32(np, "qcom,num_gmac", &edma_cinfo->num_gmac); - if (edma_cinfo->num_gmac > EDMA_MAX_PORTID_SUPPORTED) { - pr_err("Invalid DTSI Entry for qcom,num_gmac\n"); - err = -EINVAL; - goto err_cinfo; - } - - /* Initialize the netdev array before allocation - * to avoid double free - */ - for (i = 0 ; i < edma_cinfo->num_gmac ; i++) - edma_netdev[i] = NULL; - - for (i = 0 ; i < edma_cinfo->num_gmac ; i++) { - edma_netdev[i] = alloc_etherdev_mqs(sizeof(struct edma_adapter), - EDMA_NETDEV_TX_QUEUE, EDMA_NETDEV_RX_QUEUE); - - if (!edma_netdev[i]) { - dev_err(&pdev->dev, - "net device alloc fails for index=%d\n", i); - err = -ENODEV; - goto err_ioremap; - } - - SET_NETDEV_DEV(edma_netdev[i], &pdev->dev); - platform_set_drvdata(pdev, edma_netdev[i]); - edma_cinfo->netdev[i] = edma_netdev[i]; - } - - /* Fill ring details */ - edma_cinfo->num_tx_queues = EDMA_MAX_TRANSMIT_QUEUE; - edma_cinfo->num_txq_per_core = (EDMA_MAX_TRANSMIT_QUEUE / 4); - edma_cinfo->tx_ring_count = EDMA_TX_RING_SIZE; - - /* Update num rx queues based on module parameter */ - edma_cinfo->num_rx_queues = num_rxq; - edma_cinfo->num_rxq_per_core = ((num_rxq == 4) ? 1 : 2); - - edma_cinfo->rx_ring_count = EDMA_RX_RING_SIZE; - - hw = &edma_cinfo->hw; - - /* Fill HW defaults */ - hw->tx_intr_mask = EDMA_TX_IMR_NORMAL_MASK; - hw->rx_intr_mask = EDMA_RX_IMR_NORMAL_MASK; - - of_property_read_u32(np, "qcom,page-mode", &edma_cinfo->page_mode); - of_property_read_u32(np, "qcom,rx_head_buf_size", - &hw->rx_head_buff_size); - - if (overwrite_mode) { - dev_info(&pdev->dev, "page mode overwritten"); - edma_cinfo->page_mode = page_mode; - } - - if (jumbo_mru) - edma_cinfo->fraglist_mode = 1; - - if (edma_cinfo->page_mode) - hw->rx_head_buff_size = EDMA_RX_HEAD_BUFF_SIZE_JUMBO; - else if (edma_cinfo->fraglist_mode) - hw->rx_head_buff_size = jumbo_mru; - else if (!hw->rx_head_buff_size) - hw->rx_head_buff_size = EDMA_RX_HEAD_BUFF_SIZE; - - hw->misc_intr_mask = 0; - hw->wol_intr_mask = 0; - - hw->intr_clear_type = EDMA_INTR_CLEAR_TYPE; - hw->intr_sw_idx_w = EDMA_INTR_SW_IDX_W_TYPE; - - /* configure RSS type to the different protocol that can be - * supported - */ - hw->rss_type = EDMA_RSS_TYPE_IPV4TCP | EDMA_RSS_TYPE_IPV6_TCP | - EDMA_RSS_TYPE_IPV4_UDP | EDMA_RSS_TYPE_IPV6UDP | - EDMA_RSS_TYPE_IPV4 | EDMA_RSS_TYPE_IPV6; - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - - edma_cinfo->hw.hw_addr = devm_ioremap_resource(&pdev->dev, res); - if (IS_ERR(edma_cinfo->hw.hw_addr)) { - err = PTR_ERR(edma_cinfo->hw.hw_addr); - goto err_ioremap; - } - - edma_hw_addr = (u32)edma_cinfo->hw.hw_addr; - - /* Parse tx queue interrupt number from device tree */ - for (i = 0; i < edma_cinfo->num_tx_queues; i++) - edma_cinfo->tx_irq[i] = platform_get_irq(pdev, i); - - /* Parse rx queue interrupt number from device tree - * Here we are setting j to point to the point where we - * left tx interrupt parsing(i.e 16) and run run the loop - * from 0 to 7 to parse rx interrupt number. - */ - for (i = 0, j = edma_cinfo->num_tx_queues, k = 0; - i < edma_cinfo->num_rx_queues; i++) { - edma_cinfo->rx_irq[k] = platform_get_irq(pdev, j); - k += ((num_rxq == 4) ? 2 : 1); - j += ((num_rxq == 4) ? 2 : 1); - } - - edma_cinfo->rx_head_buffer_len = edma_cinfo->hw.rx_head_buff_size; - edma_cinfo->rx_page_buffer_len = PAGE_SIZE; - - err = edma_alloc_queues_tx(edma_cinfo); - if (err) { - dev_err(&pdev->dev, "Allocation of TX queue failed\n"); - goto err_tx_qinit; - } - - err = edma_alloc_queues_rx(edma_cinfo); - if (err) { - dev_err(&pdev->dev, "Allocation of RX queue failed\n"); - goto err_rx_qinit; - } - - err = edma_alloc_tx_rings(edma_cinfo); - if (err) { - dev_err(&pdev->dev, "Allocation of TX resources failed\n"); - goto err_tx_rinit; - } - - err = edma_alloc_rx_rings(edma_cinfo); - if (err) { - dev_err(&pdev->dev, "Allocation of RX resources failed\n"); - goto err_rx_rinit; - } - - /* Initialize netdev and netdev bitmap for transmit descriptor rings */ - for (i = 0; i < edma_cinfo->num_tx_queues; i++) { - struct edma_tx_desc_ring *etdr = edma_cinfo->tpd_ring[i]; - int j; - - etdr->netdev_bmp = 0; - for (j = 0; j < EDMA_MAX_NETDEV_PER_QUEUE; j++) { - etdr->netdev[j] = NULL; - etdr->nq[j] = NULL; - } - } - - if (of_property_read_bool(np, "qcom,mdio_supported")) { - mdio_node = of_find_compatible_node(NULL, NULL, - "qcom,ipq4019-mdio"); - if (!mdio_node) { - dev_err(&pdev->dev, "cannot find mdio node by phandle"); - err = -EIO; - goto err_mdiobus_init_fail; - } - - mdio_plat = of_find_device_by_node(mdio_node); - if (!mdio_plat) { - dev_err(&pdev->dev, - "cannot find platform device from mdio node"); - of_node_put(mdio_node); - err = -EIO; - goto err_mdiobus_init_fail; - } - - mdio_data = dev_get_drvdata(&mdio_plat->dev); - if (!mdio_data) { - dev_err(&pdev->dev, - "cannot get mii bus reference from device data"); - of_node_put(mdio_node); - err = -EIO; - goto err_mdiobus_init_fail; - } - - miibus = mdio_data->mii_bus; - } - - if (of_property_read_bool(np, "qcom,single-phy") && - edma_cinfo->num_gmac == 1) { - err = ess_parse(edma_cinfo); - if (!err) - err = ess_reset(edma_cinfo); - if (err) - goto err_single_phy_init; - else - edma_cinfo->is_single_phy = true; - } - - for_each_available_child_of_node(np, pnp) { - const char *mac_addr; - - /* this check is needed if parent and daughter dts have - * different number of gmac nodes - */ - if (idx_mac == edma_cinfo->num_gmac) { - of_node_put(np); - break; - } - - mac_addr = of_get_mac_address(pnp); - if (!IS_ERR(mac_addr)) - memcpy(edma_netdev[idx_mac]->dev_addr, mac_addr, ETH_ALEN); - - idx_mac++; - } - - /* Populate the adapter structure register the netdevice */ - for (i = 0; i < edma_cinfo->num_gmac; i++) { - int k, m; - - adapter[i] = netdev_priv(edma_netdev[i]); - adapter[i]->netdev = edma_netdev[i]; - adapter[i]->pdev = pdev; - for (j = 0; j < CONFIG_NR_CPUS; j++) { - m = i % 2; - adapter[i]->tx_start_offset[j] = - ((j << EDMA_TX_CPU_START_SHIFT) + (m << 1)); - /* Share the queues with available net-devices. - * For instance , with 5 net-devices - * eth0/eth2/eth4 will share q0,q1,q4,q5,q8,q9,q12,q13 - * and eth1/eth3 will get the remaining. - */ - for (k = adapter[i]->tx_start_offset[j]; k < - (adapter[i]->tx_start_offset[j] + 2); k++) { - if (edma_fill_netdev(edma_cinfo, k, i, j)) { - pr_err("Netdev overflow Error\n"); - goto err_register; - } - } - } - - adapter[i]->edma_cinfo = edma_cinfo; - edma_netdev[i]->netdev_ops = &edma_axi_netdev_ops; - edma_netdev[i]->max_mtu = 9000; - edma_netdev[i]->features = NETIF_F_HW_CSUM | NETIF_F_RXCSUM - | NETIF_F_HW_VLAN_CTAG_RX | NETIF_F_SG | - NETIF_F_TSO | NETIF_F_GRO; - edma_netdev[i]->hw_features = NETIF_F_HW_CSUM | NETIF_F_RXCSUM | - NETIF_F_HW_VLAN_CTAG_RX - | NETIF_F_SG | NETIF_F_TSO | NETIF_F_GRO; - edma_netdev[i]->vlan_features = NETIF_F_HW_CSUM | NETIF_F_SG | - NETIF_F_TSO | NETIF_F_GRO; - edma_netdev[i]->wanted_features = NETIF_F_HW_CSUM | NETIF_F_SG | - NETIF_F_TSO | NETIF_F_GRO; - -#ifdef CONFIG_RFS_ACCEL - edma_netdev[i]->features |= NETIF_F_NTUPLE; - edma_netdev[i]->hw_features |= NETIF_F_NTUPLE; - edma_netdev[i]->vlan_features |= NETIF_F_NTUPLE; - edma_netdev[i]->wanted_features |= NETIF_F_NTUPLE; -#endif - edma_set_ethtool_ops(edma_netdev[i]); - - /* This just fill in some default MAC address - */ - if (!is_valid_ether_addr(edma_netdev[i]->dev_addr)) { - random_ether_addr(edma_netdev[i]->dev_addr); - pr_info("EDMA using MAC@ - using"); - pr_info("%02x:%02x:%02x:%02x:%02x:%02x\n", - *(edma_netdev[i]->dev_addr), - *(edma_netdev[i]->dev_addr + 1), - *(edma_netdev[i]->dev_addr + 2), - *(edma_netdev[i]->dev_addr + 3), - *(edma_netdev[i]->dev_addr + 4), - *(edma_netdev[i]->dev_addr + 5)); - } - - err = register_netdev(edma_netdev[i]); - if (err) - goto err_register; - - /* carrier off reporting is important to - * ethtool even BEFORE open - */ - netif_carrier_off(edma_netdev[i]); - - /* Allocate reverse irq cpu mapping structure for - * receive queues - */ -#ifdef CONFIG_RFS_ACCEL - edma_netdev[i]->rx_cpu_rmap = - alloc_irq_cpu_rmap(EDMA_NETDEV_RX_QUEUE); - if (!edma_netdev[i]->rx_cpu_rmap) { - err = -ENOMEM; - goto err_rmap_alloc_fail; - } -#endif - } - - for (i = 0; i < EDMA_MAX_PORTID_BITMAP_INDEX; i++) - edma_cinfo->portid_netdev_lookup_tbl[i] = NULL; - - for_each_available_child_of_node(np, pnp) { - const uint32_t *vlan_tag = NULL; - int len; - - /* this check is needed if parent and daughter dts have - * different number of gmac nodes - */ - if (idx == edma_cinfo->num_gmac) - break; - - /* Populate port-id to netdev lookup table */ - vlan_tag = of_get_property(pnp, "vlan_tag", &len); - if (!vlan_tag) { - pr_err("Vlan tag parsing Failed.\n"); - goto err_rmap_alloc_fail; - } - - adapter[idx]->default_vlan_tag = of_read_number(vlan_tag, 1); - vlan_tag++; - portid_bmp = of_read_number(vlan_tag, 1); - adapter[idx]->dp_bitmap = portid_bmp; - - portid_bmp = portid_bmp >> 1; /* We ignore CPU Port bit 0 */ - while (portid_bmp) { - int port_bit = ffs(portid_bmp); - - if (port_bit > EDMA_MAX_PORTID_SUPPORTED) - goto err_rmap_alloc_fail; - edma_cinfo->portid_netdev_lookup_tbl[port_bit] = - edma_netdev[idx]; - portid_bmp &= ~(1 << (port_bit - 1)); - } - - if (!of_property_read_u32(pnp, "qcom,poll_required", - &adapter[idx]->poll_required)) { - if (adapter[idx]->poll_required) { - of_property_read_u32(pnp, "qcom,phy_mdio_addr", - &adapter[idx]->phy_mdio_addr); - of_property_read_u32(pnp, "qcom,forced_speed", - &adapter[idx]->forced_speed); - of_property_read_u32(pnp, "qcom,forced_duplex", - &adapter[idx]->forced_duplex); - - /* create a phyid using MDIO bus id - * and MDIO bus address - */ - snprintf(adapter[idx]->phy_id, - MII_BUS_ID_SIZE + 3, PHY_ID_FMT, - miibus->id, - adapter[idx]->phy_mdio_addr); - } - } else { - adapter[idx]->poll_required = 0; - adapter[idx]->forced_speed = SPEED_1000; - adapter[idx]->forced_duplex = DUPLEX_FULL; - } - - idx++; - } - - edma_cinfo->edma_ctl_table_hdr = register_net_sysctl(&init_net, - "net/edma", - edma_table); - if (!edma_cinfo->edma_ctl_table_hdr) { - dev_err(&pdev->dev, "edma sysctl table hdr not registered\n"); - goto err_unregister_sysctl_tbl; - } - - /* Disable all 16 Tx and 8 rx irqs */ - edma_irq_disable(edma_cinfo); - - err = edma_reset(edma_cinfo); - if (err) { - err = -EIO; - goto err_reset; - } - - /* populate per_core_info, do a napi_Add, request 16 TX irqs, - * 8 RX irqs, do a napi enable - */ - for (i = 0; i < CONFIG_NR_CPUS; i++) { - u8 rx_start; - - edma_cinfo->edma_percpu_info[i].napi.state = 0; - - netif_napi_add(edma_netdev[0], - &edma_cinfo->edma_percpu_info[i].napi, - edma_poll, 64); - napi_enable(&edma_cinfo->edma_percpu_info[i].napi); - edma_cinfo->edma_percpu_info[i].tx_mask = tx_mask[i]; - edma_cinfo->edma_percpu_info[i].rx_mask = EDMA_RX_PER_CPU_MASK - << (i << EDMA_RX_PER_CPU_MASK_SHIFT); - edma_cinfo->edma_percpu_info[i].tx_start = tx_start[i]; - edma_cinfo->edma_percpu_info[i].rx_start = - i << EDMA_RX_CPU_START_SHIFT; - rx_start = i << EDMA_RX_CPU_START_SHIFT; - edma_cinfo->edma_percpu_info[i].tx_status = 0; - edma_cinfo->edma_percpu_info[i].rx_status = 0; - edma_cinfo->edma_percpu_info[i].edma_cinfo = edma_cinfo; - - /* Request irq per core */ - for (j = edma_cinfo->edma_percpu_info[i].tx_start; - j < tx_start[i] + 4; j++) { - sprintf(&edma_tx_irq[j][0], "edma_eth_tx%d", j); - err = request_irq(edma_cinfo->tx_irq[j], - edma_interrupt, - 0, - &edma_tx_irq[j][0], - &edma_cinfo->edma_percpu_info[i]); - if (err) - goto err_reset; - } - - for (j = edma_cinfo->edma_percpu_info[i].rx_start; - j < (rx_start + - ((edma_cinfo->num_rx_queues == 4) ? 1 : 2)); - j++) { - sprintf(&edma_rx_irq[j][0], "edma_eth_rx%d", j); - err = request_irq(edma_cinfo->rx_irq[j], - edma_interrupt, - 0, - &edma_rx_irq[j][0], - &edma_cinfo->edma_percpu_info[i]); - if (err) - goto err_reset; - } - -#ifdef CONFIG_RFS_ACCEL - for (j = edma_cinfo->edma_percpu_info[i].rx_start; - j < rx_start + 2; j += 2) { - err = irq_cpu_rmap_add(edma_netdev[0]->rx_cpu_rmap, - edma_cinfo->rx_irq[j]); - if (err) - goto err_rmap_add_fail; - } -#endif - } - - /* Used to clear interrupt status, allocate rx buffer, - * configure edma descriptors registers - */ - err = edma_configure(edma_cinfo); - if (err) { - err = -EIO; - goto err_configure; - } - - /* Configure RSS indirection table. - * 128 hash will be configured in the following - * pattern: hash{0,1,2,3} = {Q0,Q2,Q4,Q6} respectively - * and so on - */ - for (i = 0; i < EDMA_NUM_IDT; i++) - edma_write_reg(EDMA_REG_RSS_IDT(i), EDMA_RSS_IDT_VALUE); - - /* Configure load balance mapping table. - * 4 table entry will be configured according to the - * following pattern: load_balance{0,1,2,3} = {Q0,Q1,Q3,Q4} - * respectively. - */ - edma_write_reg(EDMA_REG_LB_RING, EDMA_LB_REG_VALUE); - - /* Configure Virtual queue for Tx rings - * User can also change this value runtime through - * a sysctl - */ - edma_write_reg(EDMA_REG_VQ_CTRL0, EDMA_VQ_REG_VALUE); - edma_write_reg(EDMA_REG_VQ_CTRL1, EDMA_VQ_REG_VALUE); - - /* Configure Max AXI Burst write size to 128 bytes*/ - edma_write_reg(EDMA_REG_AXIW_CTRL_MAXWRSIZE, - EDMA_AXIW_MAXWRSIZE_VALUE); - - /* Enable All 16 tx and 8 rx irq mask */ - edma_irq_enable(edma_cinfo); - edma_enable_tx_ctrl(&edma_cinfo->hw); - edma_enable_rx_ctrl(&edma_cinfo->hw); - - for (i = 0; i < edma_cinfo->num_gmac; i++) { - if (adapter[i]->poll_required) { - int phy_mode = of_get_phy_mode(np); - - if (phy_mode < 0) - phy_mode = PHY_INTERFACE_MODE_SGMII; - adapter[i]->phydev = - phy_connect(edma_netdev[i], - (const char *)adapter[i]->phy_id, - &edma_adjust_link, - phy_mode); - if (IS_ERR(adapter[i]->phydev)) { - dev_dbg(&pdev->dev, "PHY attach FAIL"); - err = -EIO; - goto edma_phy_attach_fail; - } else { - linkmode_set_bit(ETHTOOL_LINK_MODE_Pause_BIT, - adapter[i]->phydev->advertising); - linkmode_set_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, - adapter[i]->phydev->advertising); - linkmode_set_bit(ETHTOOL_LINK_MODE_Pause_BIT, - adapter[i]->phydev->supported); - linkmode_set_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, - adapter[i]->phydev->supported); - } - } else { - adapter[i]->phydev = NULL; - } - } - - spin_lock_init(&edma_cinfo->stats_lock); - - timer_setup(&edma_cinfo->edma_stats_timer, edma_statistics_timer, 0); - mod_timer(&edma_cinfo->edma_stats_timer, jiffies + 1*HZ); - - return 0; - -edma_phy_attach_fail: - miibus = NULL; -err_configure: -#ifdef CONFIG_RFS_ACCEL - for (i = 0; i < edma_cinfo->num_gmac; i++) { - free_irq_cpu_rmap(adapter[i]->netdev->rx_cpu_rmap); - adapter[i]->netdev->rx_cpu_rmap = NULL; - } -#endif -err_rmap_add_fail: - edma_free_irqs(adapter[0]); - for (i = 0; i < CONFIG_NR_CPUS; i++) - napi_disable(&edma_cinfo->edma_percpu_info[i].napi); -err_reset: -err_unregister_sysctl_tbl: -err_rmap_alloc_fail: - for (i = 0; i < edma_cinfo->num_gmac; i++) - unregister_netdev(edma_netdev[i]); -err_register: -err_single_phy_init: - iounmap(edma_cinfo->ess_hw_addr); - clk_disable_unprepare(edma_cinfo->ess_clk); -err_mdiobus_init_fail: - edma_free_rx_rings(edma_cinfo); -err_rx_rinit: - edma_free_tx_rings(edma_cinfo); -err_tx_rinit: - edma_free_queues(edma_cinfo); -err_rx_qinit: -err_tx_qinit: - iounmap(edma_cinfo->hw.hw_addr); -err_ioremap: - for (i = 0; i < edma_cinfo->num_gmac; i++) { - if (edma_netdev[i]) - free_netdev(edma_netdev[i]); - } -err_cinfo: - kfree(edma_cinfo); -err_alloc: - return err; -} - -/* edma_axi_remove() - * Device Removal Routine - * - * edma_axi_remove is called by the platform subsystem to alert the driver - * that it should release a platform device. - */ -static int edma_axi_remove(struct platform_device *pdev) -{ - struct edma_adapter *adapter = netdev_priv(edma_netdev[0]); - struct edma_common_info *edma_cinfo = adapter->edma_cinfo; - struct edma_hw *hw = &edma_cinfo->hw; - int i; - - for (i = 0; i < edma_cinfo->num_gmac; i++) - unregister_netdev(edma_netdev[i]); - - edma_stop_rx_tx(hw); - for (i = 0; i < CONFIG_NR_CPUS; i++) - napi_disable(&edma_cinfo->edma_percpu_info[i].napi); - - edma_irq_disable(edma_cinfo); - edma_write_reg(EDMA_REG_RX_ISR, 0xff); - edma_write_reg(EDMA_REG_TX_ISR, 0xffff); -#ifdef CONFIG_RFS_ACCEL - for (i = 0; i < edma_cinfo->num_gmac; i++) { - free_irq_cpu_rmap(edma_netdev[i]->rx_cpu_rmap); - edma_netdev[i]->rx_cpu_rmap = NULL; - } -#endif - - for (i = 0; i < edma_cinfo->num_gmac; i++) { - struct edma_adapter *adapter = netdev_priv(edma_netdev[i]); - - if (adapter->phydev) - phy_disconnect(adapter->phydev); - } - - del_timer_sync(&edma_cinfo->edma_stats_timer); - edma_free_irqs(adapter); - unregister_net_sysctl_table(edma_cinfo->edma_ctl_table_hdr); - iounmap(edma_cinfo->ess_hw_addr); - clk_disable_unprepare(edma_cinfo->ess_clk); - edma_free_tx_resources(edma_cinfo); - edma_free_rx_resources(edma_cinfo); - edma_free_tx_rings(edma_cinfo); - edma_free_rx_rings(edma_cinfo); - edma_free_queues(edma_cinfo); - for (i = 0; i < edma_cinfo->num_gmac; i++) - free_netdev(edma_netdev[i]); - - kfree(edma_cinfo); - - return 0; -} - -static const struct of_device_id edma_of_mtable[] = { - {.compatible = "qcom,ess-edma" }, - {} -}; -MODULE_DEVICE_TABLE(of, edma_of_mtable); - -static struct platform_driver edma_axi_driver = { - .driver = { - .name = edma_axi_driver_name, - .of_match_table = edma_of_mtable, - }, - .probe = edma_axi_probe, - .remove = edma_axi_remove, -}; - -module_platform_driver(edma_axi_driver); - -MODULE_AUTHOR("Qualcomm Atheros Inc"); -MODULE_DESCRIPTION("QCA ESS EDMA driver"); -MODULE_LICENSE("GPL"); diff --git a/root/target/linux/ipq40xx/files-5.4/drivers/net/ethernet/qualcomm/essedma/edma_ethtool.c b/root/target/linux/ipq40xx/files-5.4/drivers/net/ethernet/qualcomm/essedma/edma_ethtool.c deleted file mode 100644 index 1270e20a..00000000 --- a/root/target/linux/ipq40xx/files-5.4/drivers/net/ethernet/qualcomm/essedma/edma_ethtool.c +++ /dev/null @@ -1,384 +0,0 @@ -/* - * Copyright (c) 2015 - 2016, The Linux Foundation. All rights reserved. - * - * Permission to use, copy, modify, and/or distribute this software for - * any purpose with or without fee is hereby granted, provided that the - * above copyright notice and this permission notice appear in all copies. - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT - * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include -#include -#include -#include "edma.h" - -struct edma_ethtool_stats { - uint8_t stat_string[ETH_GSTRING_LEN]; - uint32_t stat_offset; -}; - -#define EDMA_STAT(m) offsetof(struct edma_ethtool_statistics, m) -#define DRVINFO_LEN 32 - -/* Array of strings describing statistics - */ -static const struct edma_ethtool_stats edma_gstrings_stats[] = { - {"tx_q0_pkt", EDMA_STAT(tx_q0_pkt)}, - {"tx_q1_pkt", EDMA_STAT(tx_q1_pkt)}, - {"tx_q2_pkt", EDMA_STAT(tx_q2_pkt)}, - {"tx_q3_pkt", EDMA_STAT(tx_q3_pkt)}, - {"tx_q4_pkt", EDMA_STAT(tx_q4_pkt)}, - {"tx_q5_pkt", EDMA_STAT(tx_q5_pkt)}, - {"tx_q6_pkt", EDMA_STAT(tx_q6_pkt)}, - {"tx_q7_pkt", EDMA_STAT(tx_q7_pkt)}, - {"tx_q8_pkt", EDMA_STAT(tx_q8_pkt)}, - {"tx_q9_pkt", EDMA_STAT(tx_q9_pkt)}, - {"tx_q10_pkt", EDMA_STAT(tx_q10_pkt)}, - {"tx_q11_pkt", EDMA_STAT(tx_q11_pkt)}, - {"tx_q12_pkt", EDMA_STAT(tx_q12_pkt)}, - {"tx_q13_pkt", EDMA_STAT(tx_q13_pkt)}, - {"tx_q14_pkt", EDMA_STAT(tx_q14_pkt)}, - {"tx_q15_pkt", EDMA_STAT(tx_q15_pkt)}, - {"tx_q0_byte", EDMA_STAT(tx_q0_byte)}, - {"tx_q1_byte", EDMA_STAT(tx_q1_byte)}, - {"tx_q2_byte", EDMA_STAT(tx_q2_byte)}, - {"tx_q3_byte", EDMA_STAT(tx_q3_byte)}, - {"tx_q4_byte", EDMA_STAT(tx_q4_byte)}, - {"tx_q5_byte", EDMA_STAT(tx_q5_byte)}, - {"tx_q6_byte", EDMA_STAT(tx_q6_byte)}, - {"tx_q7_byte", EDMA_STAT(tx_q7_byte)}, - {"tx_q8_byte", EDMA_STAT(tx_q8_byte)}, - {"tx_q9_byte", EDMA_STAT(tx_q9_byte)}, - {"tx_q10_byte", EDMA_STAT(tx_q10_byte)}, - {"tx_q11_byte", EDMA_STAT(tx_q11_byte)}, - {"tx_q12_byte", EDMA_STAT(tx_q12_byte)}, - {"tx_q13_byte", EDMA_STAT(tx_q13_byte)}, - {"tx_q14_byte", EDMA_STAT(tx_q14_byte)}, - {"tx_q15_byte", EDMA_STAT(tx_q15_byte)}, - {"rx_q0_pkt", EDMA_STAT(rx_q0_pkt)}, - {"rx_q1_pkt", EDMA_STAT(rx_q1_pkt)}, - {"rx_q2_pkt", EDMA_STAT(rx_q2_pkt)}, - {"rx_q3_pkt", EDMA_STAT(rx_q3_pkt)}, - {"rx_q4_pkt", EDMA_STAT(rx_q4_pkt)}, - {"rx_q5_pkt", EDMA_STAT(rx_q5_pkt)}, - {"rx_q6_pkt", EDMA_STAT(rx_q6_pkt)}, - {"rx_q7_pkt", EDMA_STAT(rx_q7_pkt)}, - {"rx_q0_byte", EDMA_STAT(rx_q0_byte)}, - {"rx_q1_byte", EDMA_STAT(rx_q1_byte)}, - {"rx_q2_byte", EDMA_STAT(rx_q2_byte)}, - {"rx_q3_byte", EDMA_STAT(rx_q3_byte)}, - {"rx_q4_byte", EDMA_STAT(rx_q4_byte)}, - {"rx_q5_byte", EDMA_STAT(rx_q5_byte)}, - {"rx_q6_byte", EDMA_STAT(rx_q6_byte)}, - {"rx_q7_byte", EDMA_STAT(rx_q7_byte)}, - {"tx_desc_error", EDMA_STAT(tx_desc_error)}, - {"rx_alloc_fail_ctr", EDMA_STAT(rx_alloc_fail_ctr)}, -}; - -#define EDMA_STATS_LEN ARRAY_SIZE(edma_gstrings_stats) - -/* edma_get_strset_count() - * Get strset count - */ -static int edma_get_strset_count(struct net_device *netdev, - int sset) -{ - switch (sset) { - case ETH_SS_STATS: - return EDMA_STATS_LEN; - default: - netdev_dbg(netdev, "%s: Invalid string set", __func__); - return -EOPNOTSUPP; - } -} - - -/* edma_get_strings() - * get stats string - */ -static void edma_get_strings(struct net_device *netdev, uint32_t stringset, - uint8_t *data) -{ - uint8_t *p = data; - uint32_t i; - - switch (stringset) { - case ETH_SS_STATS: - for (i = 0; i < EDMA_STATS_LEN; i++) { - memcpy(p, edma_gstrings_stats[i].stat_string, - min((size_t)ETH_GSTRING_LEN, - strlen(edma_gstrings_stats[i].stat_string) - + 1)); - p += ETH_GSTRING_LEN; - } - break; - } -} - -/* edma_get_ethtool_stats() - * Get ethtool statistics - */ -static void edma_get_ethtool_stats(struct net_device *netdev, - struct ethtool_stats *stats, uint64_t *data) -{ - struct edma_adapter *adapter = netdev_priv(netdev); - struct edma_common_info *edma_cinfo = adapter->edma_cinfo; - int i; - uint8_t *p = NULL; - - edma_read_append_stats(edma_cinfo); - - for(i = 0; i < EDMA_STATS_LEN; i++) { - p = (uint8_t *)&(edma_cinfo->edma_ethstats) + - edma_gstrings_stats[i].stat_offset; - data[i] = *(uint32_t *)p; - } -} - -/* edma_get_drvinfo() - * get edma driver info - */ -static void edma_get_drvinfo(struct net_device *dev, - struct ethtool_drvinfo *info) -{ - strlcpy(info->driver, "ess_edma", DRVINFO_LEN); - strlcpy(info->bus_info, "axi", ETHTOOL_BUSINFO_LEN); -} - -/* edma_nway_reset() - * Reset the phy, if available. - */ -static int edma_nway_reset(struct net_device *netdev) -{ - return -EINVAL; -} - -/* edma_get_wol() - * get wake on lan info - */ -static void edma_get_wol(struct net_device *netdev, - struct ethtool_wolinfo *wol) -{ - wol->supported = 0; - wol->wolopts = 0; -} - -/* edma_get_msglevel() - * get message level. - */ -static uint32_t edma_get_msglevel(struct net_device *netdev) -{ - return 0; -} - -/* edma_get_settings() - * Get edma settings - */ -static int edma_get_settings(struct net_device *netdev, - struct ethtool_link_ksettings *cmd) -{ - struct edma_adapter *adapter = netdev_priv(netdev); - - if (adapter->poll_required) { - struct phy_device *phydev = NULL; - uint16_t phyreg; - - if ((adapter->forced_speed != SPEED_UNKNOWN) - && !(adapter->poll_required)) - return -EPERM; - - phydev = adapter->phydev; - - linkmode_copy(cmd->link_modes.advertising, phydev->advertising); - linkmode_copy(cmd->link_modes.supported, phydev->supported); - - cmd->base.autoneg = phydev->autoneg; - - if (adapter->link_state == __EDMA_LINKDOWN) { - cmd->base.speed = SPEED_UNKNOWN; - cmd->base.duplex = DUPLEX_UNKNOWN; - } else { - cmd->base.speed = phydev->speed; - cmd->base.duplex = phydev->duplex; - } - - cmd->base.phy_address = adapter->phy_mdio_addr; - - phyreg = (uint16_t)phy_read(adapter->phydev, MII_LPA); - if (phyreg & LPA_10HALF) - linkmode_set_bit(ETHTOOL_LINK_MODE_10baseT_Half_BIT, - cmd->link_modes.lp_advertising); - - if (phyreg & LPA_10FULL) - linkmode_set_bit(ETHTOOL_LINK_MODE_10baseT_Full_BIT, - cmd->link_modes.lp_advertising); - - if (phyreg & LPA_100HALF) - linkmode_set_bit(ETHTOOL_LINK_MODE_100baseT_Half_BIT, - cmd->link_modes.lp_advertising); - - if (phyreg & LPA_100FULL) - linkmode_set_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT, - cmd->link_modes.lp_advertising); - - phyreg = (uint16_t)phy_read(adapter->phydev, MII_STAT1000); - if (phyreg & LPA_1000HALF) - linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT, - cmd->link_modes.lp_advertising); - - if (phyreg & LPA_1000FULL) - linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT, - cmd->link_modes.lp_advertising); - } else { - /* If the speed/duplex for this GMAC is forced and we - * are not polling for link state changes, return the - * values as specified by platform. This will be true - * for GMACs connected to switch, and interfaces that - * do not use a PHY. - */ - if (!(adapter->poll_required)) { - if (adapter->forced_speed != SPEED_UNKNOWN) { - /* set speed and duplex */ - cmd->base.speed = SPEED_1000; - cmd->base.duplex = DUPLEX_FULL; - - /* Populate capabilities advertised by self */ - linkmode_zero(cmd->link_modes.advertising); - cmd->base.autoneg = 0; - cmd->base.port = PORT_TP; - cmd->base.transceiver = XCVR_EXTERNAL; - } else { - /* non link polled and non - * forced speed/duplex interface - */ - return -EIO; - } - } - } - - return 0; -} - -/* edma_set_settings() - * Set EDMA settings - */ -static int edma_set_settings(struct net_device *netdev, - const struct ethtool_link_ksettings *cmd) -{ - struct edma_adapter *adapter = netdev_priv(netdev); - struct phy_device *phydev = NULL; - - if ((adapter->forced_speed != SPEED_UNKNOWN) && - !adapter->poll_required) - return -EPERM; - - phydev = adapter->phydev; - linkmode_copy(phydev->advertising, cmd->link_modes.advertising); - linkmode_copy(phydev->supported, cmd->link_modes.supported); - phydev->autoneg = cmd->base.autoneg; - phydev->speed = cmd->base.speed; - phydev->duplex = cmd->base.duplex; - - genphy_config_aneg(phydev); - - return 0; -} - -/* edma_get_coalesce - * get interrupt mitigation - */ -static int edma_get_coalesce(struct net_device *netdev, - struct ethtool_coalesce *ec) -{ - u32 reg_val; - - edma_get_tx_rx_coalesce(®_val); - - /* We read the Interrupt Moderation Timer(IMT) register value, - * use lower 16 bit for rx and higher 16 bit for Tx. We do a - * left shift by 1, because IMT resolution timer is 2usecs. - * Hence the value given by the register is multiplied by 2 to - * get the actual time in usecs. - */ - ec->tx_coalesce_usecs = (((reg_val >> 16) & 0xffff) << 1); - ec->rx_coalesce_usecs = ((reg_val & 0xffff) << 1); - - return 0; -} - -/* edma_set_coalesce - * set interrupt mitigation - */ -static int edma_set_coalesce(struct net_device *netdev, - struct ethtool_coalesce *ec) -{ - if (ec->tx_coalesce_usecs) - edma_change_tx_coalesce(ec->tx_coalesce_usecs); - if (ec->rx_coalesce_usecs) - edma_change_rx_coalesce(ec->rx_coalesce_usecs); - - return 0; -} - -/* edma_set_priv_flags() - * Set EDMA private flags - */ -static int edma_set_priv_flags(struct net_device *netdev, u32 flags) -{ - return 0; -} - -/* edma_get_priv_flags() - * get edma driver flags - */ -static u32 edma_get_priv_flags(struct net_device *netdev) -{ - return 0; -} - -/* edma_get_ringparam() - * get ring size - */ -static void edma_get_ringparam(struct net_device *netdev, - struct ethtool_ringparam *ring) -{ - struct edma_adapter *adapter = netdev_priv(netdev); - struct edma_common_info *edma_cinfo = adapter->edma_cinfo; - - ring->tx_max_pending = edma_cinfo->tx_ring_count; - ring->rx_max_pending = edma_cinfo->rx_ring_count; -} - -/* Ethtool operations - */ -static const struct ethtool_ops edma_ethtool_ops = { - .get_drvinfo = &edma_get_drvinfo, - .get_link = ðtool_op_get_link, - .get_msglevel = &edma_get_msglevel, - .nway_reset = &edma_nway_reset, - .get_wol = &edma_get_wol, - .get_link_ksettings = &edma_get_settings, - .set_link_ksettings = &edma_set_settings, - .get_strings = &edma_get_strings, - .get_sset_count = &edma_get_strset_count, - .get_ethtool_stats = &edma_get_ethtool_stats, - .get_coalesce = &edma_get_coalesce, - .set_coalesce = &edma_set_coalesce, - .get_priv_flags = edma_get_priv_flags, - .set_priv_flags = edma_set_priv_flags, - .get_ringparam = edma_get_ringparam, -}; - -/* edma_set_ethtool_ops - * Set ethtool operations - */ -void edma_set_ethtool_ops(struct net_device *netdev) -{ - netdev->ethtool_ops = &edma_ethtool_ops; -} diff --git a/root/target/linux/ipq40xx/files-5.4/drivers/net/ethernet/qualcomm/essedma/ess_edma.h b/root/target/linux/ipq40xx/files-5.4/drivers/net/ethernet/qualcomm/essedma/ess_edma.h deleted file mode 100644 index 021be98a..00000000 --- a/root/target/linux/ipq40xx/files-5.4/drivers/net/ethernet/qualcomm/essedma/ess_edma.h +++ /dev/null @@ -1,389 +0,0 @@ -/* - * Copyright (c) 2014 - 2016, The Linux Foundation. All rights reserved. - * - * Permission to use, copy, modify, and/or distribute this software for - * any purpose with or without fee is hereby granted, provided that the - * above copyright notice and this permission notice appear in all copies. - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT - * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _ESS_EDMA_H_ -#define _ESS_EDMA_H_ - -#include - -struct edma_adapter; -struct edma_hw; - -/* register definition */ -#define EDMA_REG_MAS_CTRL 0x0 -#define EDMA_REG_TIMEOUT_CTRL 0x004 -#define EDMA_REG_DBG0 0x008 -#define EDMA_REG_DBG1 0x00C -#define EDMA_REG_SW_CTRL0 0x100 -#define EDMA_REG_SW_CTRL1 0x104 - -/* Interrupt Status Register */ -#define EDMA_REG_RX_ISR 0x200 -#define EDMA_REG_TX_ISR 0x208 -#define EDMA_REG_MISC_ISR 0x210 -#define EDMA_REG_WOL_ISR 0x218 - -#define EDMA_MISC_ISR_RX_URG_Q(x) (1 << x) - -#define EDMA_MISC_ISR_AXIR_TIMEOUT 0x00000100 -#define EDMA_MISC_ISR_AXIR_ERR 0x00000200 -#define EDMA_MISC_ISR_TXF_DEAD 0x00000400 -#define EDMA_MISC_ISR_AXIW_ERR 0x00000800 -#define EDMA_MISC_ISR_AXIW_TIMEOUT 0x00001000 - -#define EDMA_WOL_ISR 0x00000001 - -/* Interrupt Mask Register */ -#define EDMA_REG_MISC_IMR 0x214 -#define EDMA_REG_WOL_IMR 0x218 - -#define EDMA_RX_IMR_NORMAL_MASK 0x1 -#define EDMA_TX_IMR_NORMAL_MASK 0x1 -#define EDMA_MISC_IMR_NORMAL_MASK 0x80001FFF -#define EDMA_WOL_IMR_NORMAL_MASK 0x1 - -/* Edma receive consumer index */ -#define EDMA_REG_RX_SW_CONS_IDX_Q(x) (0x220 + ((x) << 2)) /* x is the queue id */ -/* Edma transmit consumer index */ -#define EDMA_REG_TX_SW_CONS_IDX_Q(x) (0x240 + ((x) << 2)) /* x is the queue id */ - -/* IRQ Moderator Initial Timer Register */ -#define EDMA_REG_IRQ_MODRT_TIMER_INIT 0x280 -#define EDMA_IRQ_MODRT_TIMER_MASK 0xFFFF -#define EDMA_IRQ_MODRT_RX_TIMER_SHIFT 0 -#define EDMA_IRQ_MODRT_TX_TIMER_SHIFT 16 - -/* Interrupt Control Register */ -#define EDMA_REG_INTR_CTRL 0x284 -#define EDMA_INTR_CLR_TYP_SHIFT 0 -#define EDMA_INTR_SW_IDX_W_TYP_SHIFT 1 -#define EDMA_INTR_CLEAR_TYPE_W1 0 -#define EDMA_INTR_CLEAR_TYPE_R 1 - -/* RX Interrupt Mask Register */ -#define EDMA_REG_RX_INT_MASK_Q(x) (0x300 + ((x) << 2)) /* x = queue id */ - -/* TX Interrupt mask register */ -#define EDMA_REG_TX_INT_MASK_Q(x) (0x340 + ((x) << 2)) /* x = queue id */ - -/* Load Ptr Register - * Software sets this bit after the initialization of the head and tail - */ -#define EDMA_REG_TX_SRAM_PART 0x400 -#define EDMA_LOAD_PTR_SHIFT 16 - -/* TXQ Control Register */ -#define EDMA_REG_TXQ_CTRL 0x404 -#define EDMA_TXQ_CTRL_IP_OPTION_EN 0x10 -#define EDMA_TXQ_CTRL_TXQ_EN 0x20 -#define EDMA_TXQ_CTRL_ENH_MODE 0x40 -#define EDMA_TXQ_CTRL_LS_8023_EN 0x80 -#define EDMA_TXQ_CTRL_TPD_BURST_EN 0x100 -#define EDMA_TXQ_CTRL_LSO_BREAK_EN 0x200 -#define EDMA_TXQ_NUM_TPD_BURST_MASK 0xF -#define EDMA_TXQ_TXF_BURST_NUM_MASK 0xFFFF -#define EDMA_TXQ_NUM_TPD_BURST_SHIFT 0 -#define EDMA_TXQ_TXF_BURST_NUM_SHIFT 16 - -#define EDMA_REG_TXF_WATER_MARK 0x408 /* In 8-bytes */ -#define EDMA_TXF_WATER_MARK_MASK 0x0FFF -#define EDMA_TXF_LOW_WATER_MARK_SHIFT 0 -#define EDMA_TXF_HIGH_WATER_MARK_SHIFT 16 -#define EDMA_TXQ_CTRL_BURST_MODE_EN 0x80000000 - -/* WRR Control Register */ -#define EDMA_REG_WRR_CTRL_Q0_Q3 0x40c -#define EDMA_REG_WRR_CTRL_Q4_Q7 0x410 -#define EDMA_REG_WRR_CTRL_Q8_Q11 0x414 -#define EDMA_REG_WRR_CTRL_Q12_Q15 0x418 - -/* Weight round robin(WRR), it takes queue as input, and computes - * starting bits where we need to write the weight for a particular - * queue - */ -#define EDMA_WRR_SHIFT(x) (((x) * 5) % 20) - -/* Tx Descriptor Control Register */ -#define EDMA_REG_TPD_RING_SIZE 0x41C -#define EDMA_TPD_RING_SIZE_SHIFT 0 -#define EDMA_TPD_RING_SIZE_MASK 0xFFFF - -/* Transmit descriptor base address */ -#define EDMA_REG_TPD_BASE_ADDR_Q(x) (0x420 + ((x) << 2)) /* x = queue id */ - -/* TPD Index Register */ -#define EDMA_REG_TPD_IDX_Q(x) (0x460 + ((x) << 2)) /* x = queue id */ - -#define EDMA_TPD_PROD_IDX_BITS 0x0000FFFF -#define EDMA_TPD_CONS_IDX_BITS 0xFFFF0000 -#define EDMA_TPD_PROD_IDX_MASK 0xFFFF -#define EDMA_TPD_CONS_IDX_MASK 0xFFFF -#define EDMA_TPD_PROD_IDX_SHIFT 0 -#define EDMA_TPD_CONS_IDX_SHIFT 16 - -/* TX Virtual Queue Mapping Control Register */ -#define EDMA_REG_VQ_CTRL0 0x4A0 -#define EDMA_REG_VQ_CTRL1 0x4A4 - -/* Virtual QID shift, it takes queue as input, and computes - * Virtual QID position in virtual qid control register - */ -#define EDMA_VQ_ID_SHIFT(i) (((i) * 3) % 24) - -/* Virtual Queue Default Value */ -#define EDMA_VQ_REG_VALUE 0x240240 - -/* Tx side Port Interface Control Register */ -#define EDMA_REG_PORT_CTRL 0x4A8 -#define EDMA_PAD_EN_SHIFT 15 - -/* Tx side VLAN Configuration Register */ -#define EDMA_REG_VLAN_CFG 0x4AC - -#define EDMA_TX_CVLAN 16 -#define EDMA_TX_INS_CVLAN 17 -#define EDMA_TX_CVLAN_TAG_SHIFT 0 - -#define EDMA_TX_SVLAN 14 -#define EDMA_TX_INS_SVLAN 15 -#define EDMA_TX_SVLAN_TAG_SHIFT 16 - -/* Tx Queue Packet Statistic Register */ -#define EDMA_REG_TX_STAT_PKT_Q(x) (0x700 + ((x) << 3)) /* x = queue id */ - -#define EDMA_TX_STAT_PKT_MASK 0xFFFFFF - -/* Tx Queue Byte Statistic Register */ -#define EDMA_REG_TX_STAT_BYTE_Q(x) (0x704 + ((x) << 3)) /* x = queue id */ - -/* Load Balance Based Ring Offset Register */ -#define EDMA_REG_LB_RING 0x800 -#define EDMA_LB_RING_ENTRY_MASK 0xff -#define EDMA_LB_RING_ID_MASK 0x7 -#define EDMA_LB_RING_PROFILE_ID_MASK 0x3 -#define EDMA_LB_RING_ENTRY_BIT_OFFSET 8 -#define EDMA_LB_RING_ID_OFFSET 0 -#define EDMA_LB_RING_PROFILE_ID_OFFSET 3 -#define EDMA_LB_REG_VALUE 0x6040200 - -/* Load Balance Priority Mapping Register */ -#define EDMA_REG_LB_PRI_START 0x804 -#define EDMA_REG_LB_PRI_END 0x810 -#define EDMA_LB_PRI_REG_INC 4 -#define EDMA_LB_PRI_ENTRY_BIT_OFFSET 4 -#define EDMA_LB_PRI_ENTRY_MASK 0xf - -/* RSS Priority Mapping Register */ -#define EDMA_REG_RSS_PRI 0x820 -#define EDMA_RSS_PRI_ENTRY_MASK 0xf -#define EDMA_RSS_RING_ID_MASK 0x7 -#define EDMA_RSS_PRI_ENTRY_BIT_OFFSET 4 - -/* RSS Indirection Register */ -#define EDMA_REG_RSS_IDT(x) (0x840 + ((x) << 2)) /* x = No. of indirection table */ -#define EDMA_NUM_IDT 16 -#define EDMA_RSS_IDT_VALUE 0x64206420 - -/* Default RSS Ring Register */ -#define EDMA_REG_DEF_RSS 0x890 -#define EDMA_DEF_RSS_MASK 0x7 - -/* RSS Hash Function Type Register */ -#define EDMA_REG_RSS_TYPE 0x894 -#define EDMA_RSS_TYPE_NONE 0x01 -#define EDMA_RSS_TYPE_IPV4TCP 0x02 -#define EDMA_RSS_TYPE_IPV6_TCP 0x04 -#define EDMA_RSS_TYPE_IPV4_UDP 0x08 -#define EDMA_RSS_TYPE_IPV6UDP 0x10 -#define EDMA_RSS_TYPE_IPV4 0x20 -#define EDMA_RSS_TYPE_IPV6 0x40 -#define EDMA_RSS_HASH_MODE_MASK 0x7f - -#define EDMA_REG_RSS_HASH_VALUE 0x8C0 - -#define EDMA_REG_RSS_TYPE_RESULT 0x8C4 - -#define EDMA_HASH_TYPE_START 0 -#define EDMA_HASH_TYPE_END 5 -#define EDMA_HASH_TYPE_SHIFT 12 - -#define EDMA_RFS_FLOW_ENTRIES 1024 -#define EDMA_RFS_FLOW_ENTRIES_MASK (EDMA_RFS_FLOW_ENTRIES - 1) -#define EDMA_RFS_EXPIRE_COUNT_PER_CALL 128 - -/* RFD Base Address Register */ -#define EDMA_REG_RFD_BASE_ADDR_Q(x) (0x950 + ((x) << 2)) /* x = queue id */ - -/* RFD Index Register */ -#define EDMA_REG_RFD_IDX_Q(x) (0x9B0 + ((x) << 2)) - -#define EDMA_RFD_PROD_IDX_BITS 0x00000FFF -#define EDMA_RFD_CONS_IDX_BITS 0x0FFF0000 -#define EDMA_RFD_PROD_IDX_MASK 0xFFF -#define EDMA_RFD_CONS_IDX_MASK 0xFFF -#define EDMA_RFD_PROD_IDX_SHIFT 0 -#define EDMA_RFD_CONS_IDX_SHIFT 16 - -/* Rx Descriptor Control Register */ -#define EDMA_REG_RX_DESC0 0xA10 -#define EDMA_RFD_RING_SIZE_MASK 0xFFF -#define EDMA_RX_BUF_SIZE_MASK 0xFFFF -#define EDMA_RFD_RING_SIZE_SHIFT 0 -#define EDMA_RX_BUF_SIZE_SHIFT 16 - -#define EDMA_REG_RX_DESC1 0xA14 -#define EDMA_RXQ_RFD_BURST_NUM_MASK 0x3F -#define EDMA_RXQ_RFD_PF_THRESH_MASK 0x1F -#define EDMA_RXQ_RFD_LOW_THRESH_MASK 0xFFF -#define EDMA_RXQ_RFD_BURST_NUM_SHIFT 0 -#define EDMA_RXQ_RFD_PF_THRESH_SHIFT 8 -#define EDMA_RXQ_RFD_LOW_THRESH_SHIFT 16 - -/* RXQ Control Register */ -#define EDMA_REG_RXQ_CTRL 0xA18 -#define EDMA_FIFO_THRESH_TYPE_SHIF 0 -#define EDMA_FIFO_THRESH_128_BYTE 0x0 -#define EDMA_FIFO_THRESH_64_BYTE 0x1 -#define EDMA_RXQ_CTRL_RMV_VLAN 0x00000002 -#define EDMA_RXQ_CTRL_EN 0x0000FF00 - -/* AXI Burst Size Config */ -#define EDMA_REG_AXIW_CTRL_MAXWRSIZE 0xA1C -#define EDMA_AXIW_MAXWRSIZE_VALUE 0x0 - -/* Rx Statistics Register */ -#define EDMA_REG_RX_STAT_BYTE_Q(x) (0xA30 + ((x) << 2)) /* x = queue id */ -#define EDMA_REG_RX_STAT_PKT_Q(x) (0xA50 + ((x) << 2)) /* x = queue id */ - -/* WoL Pattern Length Register */ -#define EDMA_REG_WOL_PATTERN_LEN0 0xC00 -#define EDMA_WOL_PT_LEN_MASK 0xFF -#define EDMA_WOL_PT0_LEN_SHIFT 0 -#define EDMA_WOL_PT1_LEN_SHIFT 8 -#define EDMA_WOL_PT2_LEN_SHIFT 16 -#define EDMA_WOL_PT3_LEN_SHIFT 24 - -#define EDMA_REG_WOL_PATTERN_LEN1 0xC04 -#define EDMA_WOL_PT4_LEN_SHIFT 0 -#define EDMA_WOL_PT5_LEN_SHIFT 8 -#define EDMA_WOL_PT6_LEN_SHIFT 16 - -/* WoL Control Register */ -#define EDMA_REG_WOL_CTRL 0xC08 -#define EDMA_WOL_WK_EN 0x00000001 -#define EDMA_WOL_MG_EN 0x00000002 -#define EDMA_WOL_PT0_EN 0x00000004 -#define EDMA_WOL_PT1_EN 0x00000008 -#define EDMA_WOL_PT2_EN 0x00000010 -#define EDMA_WOL_PT3_EN 0x00000020 -#define EDMA_WOL_PT4_EN 0x00000040 -#define EDMA_WOL_PT5_EN 0x00000080 -#define EDMA_WOL_PT6_EN 0x00000100 - -/* MAC Control Register */ -#define EDMA_REG_MAC_CTRL0 0xC20 -#define EDMA_REG_MAC_CTRL1 0xC24 - -/* WoL Pattern Register */ -#define EDMA_REG_WOL_PATTERN_START 0x5000 -#define EDMA_PATTERN_PART_REG_OFFSET 0x40 - - -/* TX descriptor fields */ -#define EDMA_TPD_HDR_SHIFT 0 -#define EDMA_TPD_PPPOE_EN 0x00000100 -#define EDMA_TPD_IP_CSUM_EN 0x00000200 -#define EDMA_TPD_TCP_CSUM_EN 0x0000400 -#define EDMA_TPD_UDP_CSUM_EN 0x00000800 -#define EDMA_TPD_CUSTOM_CSUM_EN 0x00000C00 -#define EDMA_TPD_LSO_EN 0x00001000 -#define EDMA_TPD_LSO_V2_EN 0x00002000 -#define EDMA_TPD_IPV4_EN 0x00010000 -#define EDMA_TPD_MSS_MASK 0x1FFF -#define EDMA_TPD_MSS_SHIFT 18 -#define EDMA_TPD_CUSTOM_CSUM_SHIFT 18 - -/* RRD descriptor fields */ -#define EDMA_RRD_NUM_RFD_MASK 0x000F -#define EDMA_RRD_SVLAN 0x8000 -#define EDMA_RRD_FLOW_COOKIE_MASK 0x07FF; - -#define EDMA_RRD_PKT_SIZE_MASK 0x3FFF -#define EDMA_RRD_CSUM_FAIL_MASK 0xC000 -#define EDMA_RRD_CVLAN 0x0001 -#define EDMA_RRD_DESC_VALID 0x8000 - -#define EDMA_RRD_PRIORITY_SHIFT 4 -#define EDMA_RRD_PRIORITY_MASK 0x7 -#define EDMA_RRD_PORT_TYPE_SHIFT 7 -#define EDMA_RRD_PORT_TYPE_MASK 0x1F - -#define ESS_RGMII_CTRL 0x0004 - -/* Port status registers */ -#define ESS_PORT0_STATUS 0x007C -#define ESS_PORT1_STATUS 0x0080 -#define ESS_PORT2_STATUS 0x0084 -#define ESS_PORT3_STATUS 0x0088 -#define ESS_PORT4_STATUS 0x008C -#define ESS_PORT5_STATUS 0x0090 - -#define ESS_PORT_STATUS_HDX_FLOW_CTL 0x80 -#define ESS_PORT_STATUS_DUPLEX_MODE 0x40 -#define ESS_PORT_STATUS_RX_FLOW_EN 0x20 -#define ESS_PORT_STATUS_TX_FLOW_EN 0x10 -#define ESS_PORT_STATUS_RX_MAC_EN 0x08 -#define ESS_PORT_STATUS_TX_MAC_EN 0x04 -#define ESS_PORT_STATUS_SPEED_INV 0x03 -#define ESS_PORT_STATUS_SPEED_1000 0x02 -#define ESS_PORT_STATUS_SPEED_100 0x01 -#define ESS_PORT_STATUS_SPEED_10 0x00 - -#define ESS_PORT_1G_FDX (ESS_PORT_STATUS_DUPLEX_MODE | ESS_PORT_STATUS_RX_FLOW_EN | \ - ESS_PORT_STATUS_TX_FLOW_EN | ESS_PORT_STATUS_RX_MAC_EN | \ - ESS_PORT_STATUS_TX_MAC_EN | ESS_PORT_STATUS_SPEED_1000) - -#define PHY_STATUS_REG 0x11 -#define PHY_STATUS_SPEED 0xC000 -#define PHY_STATUS_SPEED_SHIFT 14 -#define PHY_STATUS_DUPLEX 0x2000 -#define PHY_STATUS_DUPLEX_SHIFT 13 -#define PHY_STATUS_SPEED_DUPLEX_RESOLVED 0x0800 -#define PHY_STATUS_CARRIER 0x0400 -#define PHY_STATUS_CARRIER_SHIFT 10 - -/* Port lookup control registers */ -#define ESS_PORT0_LOOKUP_CTRL 0x0660 -#define ESS_PORT1_LOOKUP_CTRL 0x066C -#define ESS_PORT2_LOOKUP_CTRL 0x0678 -#define ESS_PORT3_LOOKUP_CTRL 0x0684 -#define ESS_PORT4_LOOKUP_CTRL 0x0690 -#define ESS_PORT5_LOOKUP_CTRL 0x069C - -#define ESS_PORT0_HEADER_CTRL 0x009C - -#define ESS_PORTS_ALL 0x3f - -#define ESS_FWD_CTRL1 0x0624 -#define ESS_FWD_CTRL1_UC_FLOOD BITS(0, 7) -#define ESS_FWD_CTRL1_UC_FLOOD_S 0 -#define ESS_FWD_CTRL1_MC_FLOOD BITS(8, 7) -#define ESS_FWD_CTRL1_MC_FLOOD_S 8 -#define ESS_FWD_CTRL1_BC_FLOOD BITS(16, 7) -#define ESS_FWD_CTRL1_BC_FLOOD_S 16 -#define ESS_FWD_CTRL1_IGMP BITS(24, 7) -#define ESS_FWD_CTRL1_IGMP_S 24 - -#endif /* _ESS_EDMA_H_ */ diff --git a/root/target/linux/ipq40xx/files/arch/arm/boot/dts/qcom-ipq4019-cm520-79f.dts b/root/target/linux/ipq40xx/files/arch/arm/boot/dts/qcom-ipq4019-cm520-79f.dts deleted file mode 100644 index 019a8a19..00000000 --- a/root/target/linux/ipq40xx/files/arch/arm/boot/dts/qcom-ipq4019-cm520-79f.dts +++ /dev/null @@ -1,300 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later OR MIT - -#include "qcom-ipq4019.dtsi" -#include -#include -#include - -/ { - model = "MobiPromo CM520-79F"; - compatible = "mobipromo,cm520-79f"; - - aliases { - led-boot = &led_sys; - led-failsafe = &led_sys; - led-running = &led_sys; - led-upgrade = &led_sys; - }; - - chosen { - bootargs-append = " ubi.block=0,1 root=/dev/ubiblock0_1"; - }; - - soc { - rng@22000 { - status = "okay"; - }; - - mdio@90000 { - status = "okay"; - pinctrl-0 = <&mdio_pins>; - pinctrl-names = "default"; - reset-gpios = <&tlmm 47 GPIO_ACTIVE_LOW>; - reset-delay-us = <1000>; - }; - - ess-psgmii@98000 { - status = "okay"; - }; - - tcsr@1949000 { - compatible = "qcom,tcsr"; - reg = <0x1949000 0x100>; - qcom,wifi_glb_cfg = ; - }; - - tcsr@194b000 { - compatible = "qcom,tcsr"; - reg = <0x194b000 0x100>; - qcom,usb-hsphy-mode-select = ; - }; - - ess_tcsr@1953000 { - compatible = "qcom,tcsr"; - reg = <0x1953000 0x1000>; - qcom,ess-interface-select = ; - }; - - tcsr@1957000 { - compatible = "qcom,tcsr"; - reg = <0x1957000 0x100>; - qcom,wifi_noc_memtype_m0_m2 = ; - }; - - usb2@60f8800 { - status = "okay"; - - dwc3@6000000 { - #address-cells = <1>; - #size-cells = <0>; - - usb2_port1: port@1 { - reg = <1>; - #trigger-source-cells = <0>; - }; - }; - }; - - usb3@8af8800 { - status = "okay"; - - dwc3@8a00000 { - #address-cells = <1>; - #size-cells = <0>; - - usb3_port1: port@1 { - reg = <1>; - #trigger-source-cells = <0>; - }; - - usb3_port2: port@2 { - reg = <2>; - #trigger-source-cells = <0>; - }; - }; - }; - - crypto@8e3a000 { - status = "okay"; - }; - - watchdog@b017000 { - status = "okay"; - }; - - ess-switch@c000000 { - status = "okay"; - }; - - edma@c080000 { - status = "okay"; - }; - }; - - led_spi { - compatible = "spi-gpio"; - #address-cells = <1>; - #size-cells = <0>; - - sck-gpios = <&tlmm 40 GPIO_ACTIVE_HIGH>; - mosi-gpios = <&tlmm 36 GPIO_ACTIVE_HIGH>; - num-chipselects = <0>; - - led_gpio: led_gpio@0 { - compatible = "fairchild,74hc595"; - reg = <0>; - gpio-controller; - #gpio-cells = <2>; - registers-number = <1>; - spi-max-frequency = <1000000>; - }; - }; - - leds { - compatible = "gpio-leds"; - - led_usb: usb { - label = "cm520-79f:blue:usb"; - gpios = <&tlmm 10 GPIO_ACTIVE_HIGH>; - linux,default-trigger = "usbport"; - trigger-sources = <&usb3_port1>, <&usb3_port2>, <&usb2_port1>; - }; - - led_sys: can { - label = "cm520-79f:blue:can"; - gpios = <&tlmm 11 GPIO_ACTIVE_HIGH>; - }; - - wan { - label = "cm520-79f:blue:wan"; - gpios = <&led_gpio 0 GPIO_ACTIVE_LOW>; - }; - - lan1 { - label = "cm520-79f:blue:lan1"; - gpios = <&led_gpio 1 GPIO_ACTIVE_LOW>; - }; - - lan2 { - label = "cm520-79f:blue:lan2"; - gpios = <&led_gpio 2 GPIO_ACTIVE_LOW>; - }; - - wlan2g { - label = "cm520-79f:blue:wlan2g"; - gpios = <&led_gpio 5 GPIO_ACTIVE_LOW>; - linux,default-trigger = "phy0tpt"; - }; - - wlan5g { - label = "cm520-79f:blue:wlan5g"; - gpios = <&led_gpio 6 GPIO_ACTIVE_LOW>; - linux,default-trigger = "phy1tpt"; - }; - }; - - keys { - compatible = "gpio-keys"; - - reset { - label = "reset"; - gpios = <&tlmm 18 GPIO_ACTIVE_LOW>; - linux,code = ; - }; - }; -}; - -&blsp_dma { - status = "okay"; -}; - -&blsp1_uart1 { - status = "okay"; -}; - -&blsp1_uart2 { - status = "okay"; -}; - -&cryptobam { - status = "okay"; -}; - -&gmac0 { - mtd-mac-address = <&art 0x1006>; -}; - -&gmac1 { - mtd-mac-address = <&art 0x5006>; -}; - -&nand { - pinctrl-0 = <&nand_pins>; - pinctrl-names = "default"; - status = "okay"; - - nand@0 { - partitions { - compatible = "fixed-partitions"; - #address-cells = <1>; - #size-cells = <1>; - - partition@0 { - label = "Bootloader"; - reg = <0x0 0xb00000>; - }; - - art: partition@b00000 { - label = "ART"; - reg = <0xb00000 0x80000>; - read-only; - }; - - partition@b80000 { - label = "rootfs"; - reg = <0xb80000 0x7480000>; - }; - }; - }; -}; - -&qpic_bam { - status = "okay"; -}; - -&tlmm { - mdio_pins: mdio_pinmux { - mux_1 { - pins = "gpio6"; - function = "mdio"; - bias-pull-up; - }; - - mux_2 { - pins = "gpio7"; - function = "mdc"; - bias-pull-up; - }; - }; - - nand_pins: nand_pins { - pullups { - pins = "gpio52", "gpio53", "gpio58", - "gpio59"; - function = "qpic"; - bias-pull-up; - }; - - pulldowns { - pins = "gpio54", "gpio55", "gpio56", - "gpio57", "gpio60", "gpio61", - "gpio62", "gpio63", "gpio64", - "gpio65", "gpio66", "gpio67", - "gpio68", "gpio69"; - function = "qpic"; - bias-pull-down; - }; - }; -}; - -&usb3_ss_phy { - status = "okay"; -}; - -&usb3_hs_phy { - status = "okay"; -}; - -&usb2_hs_phy { - status = "okay"; -}; - -&wifi0 { - status = "okay"; - qcom,ath10k-calibration-variant = "CM520-79F"; -}; - -&wifi1 { - status = "okay"; - qcom,ath10k-calibration-variant = "CM520-79F"; -}; diff --git a/root/target/linux/ipq40xx/files/arch/arm/boot/dts/qcom-ipq4019-l1000.dts b/root/target/linux/ipq40xx/files/arch/arm/boot/dts/qcom-ipq4019-l1000.dts index 1dfdf582..abea83f9 100644 --- a/root/target/linux/ipq40xx/files/arch/arm/boot/dts/qcom-ipq4019-l1000.dts +++ b/root/target/linux/ipq40xx/files/arch/arm/boot/dts/qcom-ipq4019-l1000.dts @@ -11,7 +11,7 @@ / { - model = "PANGU L1000"; + model = "ANTROUTERGZ1000"; compatible = "pangu,l1000", "qcom,ipq4019"; @@ -123,24 +123,30 @@ compatible = "gpio-leds"; power: status { - label = "l1000:blue:status"; + label = "blue:status"; gpios = <&tlmm 3 GPIO_ACTIVE_LOW>; }; wlan2g { - label = "l1000:blue:wlan2g"; + label = "blue:wlan2g"; gpios = <&tlmm 1 GPIO_ACTIVE_LOW>; }; wlan5g { - label = "l1000:bule:wlan5g"; + label = "bule:wlan5g"; gpios = <&tlmm 2 GPIO_ACTIVE_LOW>; }; - wan: wan { - label = "l1000:bule:usb"; + wan { + label = "bule:wan"; gpios = <&tlmm 4 GPIO_ACTIVE_LOW>; - }; + }; + usb { + label = "bule::usb"; + gpios = <&tlmm 5 GPIO_ACTIVE_LOW>; + trigger-sources = <&usb2>, <&usb3>; + linux,default-trigger = "usbport"; + }; }; }; diff --git a/root/target/linux/ipq40xx/files/arch/arm/boot/dts/qcom-ipq4019-r619ac.dtsi b/root/target/linux/ipq40xx/files/arch/arm/boot/dts/qcom-ipq4019-r619ac.dtsi index 81018dd0..42a186f6 100644 --- a/root/target/linux/ipq40xx/files/arch/arm/boot/dts/qcom-ipq4019-r619ac.dtsi +++ b/root/target/linux/ipq40xx/files/arch/arm/boot/dts/qcom-ipq4019-r619ac.dtsi @@ -84,18 +84,18 @@ pinctrl-names = "default"; led_sys: sys { - label = "r619ac:blue:sys"; + label = "blue:sys"; gpios = <&tlmm 39 GPIO_ACTIVE_HIGH>; }; wlan2g { - label = "r619ac:blue:wlan2g"; + label = "blue:wlan2g"; gpios = <&tlmm 32 GPIO_ACTIVE_HIGH>; linux,default-trigger = "phy0tpt"; }; wlan5g { - label = "r619ac:blue:wlan5g"; + label = "blue:wlan5g"; gpios = <&tlmm 50 GPIO_ACTIVE_HIGH>; linux,default-trigger = "phy1tpt"; }; diff --git a/root/target/linux/ipq40xx/image/Makefile b/root/target/linux/ipq40xx/image/Makefile index d0ac19ba..673d60a0 100644 --- a/root/target/linux/ipq40xx/image/Makefile +++ b/root/target/linux/ipq40xx/image/Makefile @@ -317,6 +317,25 @@ define Device/compex_wpj428 endef TARGET_DEVICES += compex_wpj428 +define Device/devolo_magic-2-wifi-next + $(call Device/FitImage) + DEVICE_VENDOR := devolo + DEVICE_MODEL := Magic 2 WiFi next + SOC := qcom-ipq4018 + KERNEL_SIZE := 4096k + + # If the bootloader sees 0xDEADC0DE and this trailer at the 64k boundary of a TFTP image + # it will bootm it, just like we want for the initramfs. + KERNEL_INITRAMFS := kernel-bin | gzip | fit gzip $$(DTS_DIR)/$$(DEVICE_DTS).dtb | pad-to 64k |\ + append-string -e '\xDE\xAD\xC0\xDE{"fl_initramfs":""}\x00' + + IMAGE_SIZE := 26624k + IMAGES := sysupgrade.bin + IMAGE/sysupgrade.bin := append-kernel | append-rootfs | pad-rootfs | append-metadata + DEVICE_PACKAGES := ipq-wifi-devolo_magic-2-wifi-next uboot-envtools +endef +TARGET_DEVICES += devolo_magic-2-wifi-next + define Device/dlink_dap-2610 $(call Device/FitImageLzma) DEVICE_VENDOR := D-Link @@ -344,6 +363,32 @@ define Device/dlink_dap-2610 endef TARGET_DEVICES += dlink_dap-2610 +define Device/edgecore_ecw5211 + $(call Device/FitImage) + $(call Device/UbiFit) + DEVICE_VENDOR := Edgecore + DEVICE_MODEL := ECW5211 + SOC := qcom-ipq4018 + BLOCKSIZE := 128k + PAGESIZE := 2048 + DEVICE_PACKAGES := kmod-tpm-i2c-atmel kmod-usb-acm uboot-envtools +endef +TARGET_DEVICES += edgecore_ecw5211 + +define Device/edgecore_oap100 + $(call Device/FitImage) + $(call Device/UbiFit) + DEVICE_VENDOR := Edgecore + DEVICE_MODEL := OAP100 + SOC := qcom-ipq4019 + BLOCKSIZE := 128k + PAGESIZE := 2048 + IMAGES := nand-sysupgrade.bin + DEVICE_DTS_CONFIG := config@ap.dk07.1-c1 + DEVICE_PACKAGES := ipq-wifi-edgecore_oap100 kmod-usb-acm kmod-usb-net kmod-usb-net-cdc-qmi uqmi +endef +TARGET_DEVICES += edgecore_oap100 + define Device/engenius_eap1300 $(call Device/FitImage) DEVICE_VENDOR := EnGenius @@ -515,6 +560,34 @@ define Device/linksys_ea8300 endef TARGET_DEVICES += linksys_ea8300 +define Device/linksys_mr8300 + $(call Device/FitzImage) + DEVICE_VENDOR := Linksys + DEVICE_MODEL := MR8300 + SOC := qcom-ipq4019 + KERNEL_SIZE := 3072k + IMAGE_SIZE := 87040k + BLOCKSIZE := 128k + PAGESIZE := 2048 + UBINIZE_OPTS := -E 5 # EOD marks to "hide" factory sig at EOF + IMAGES += factory.bin + IMAGE/factory.bin := append-kernel | pad-to $$$$(KERNEL_SIZE) | append-ubi | linksys-image type=MR8300 + DEVICE_PACKAGES := uboot-envtools ath10k-firmware-qca9888-ct ipq-wifi-linksys_mr8300-v0 kmod-usb-ledtrig-usbport +endef +TARGET_DEVICES += linksys_mr8300 + +define Device/luma_wrtq-329acn + $(call Device/FitImage) + DEVICE_VENDOR := Luma Home + DEVICE_MODEL := WRTQ-329ACN + SOC := qcom-ipq4018 + DEVICE_PACKAGES := ipq-wifi-luma_wrtq-329acn kmod-ath3k kmod-eeprom-at24 kmod-i2c-gpio uboot-envtools + IMAGE_SIZE := 76632k + BLOCKSIZE := 128k + PAGESIZE := 2048 +endef +TARGET_DEVICES += luma_wrtq-329acn + define Device/meraki_mr33 $(call Device/FitImage) DEVICE_VENDOR := Cisco Meraki @@ -540,6 +613,7 @@ TARGET_DEVICES += mobipromo_cm520-79f define Device/netgear_ex61x0v2 $(call Device/DniImage) + DEVICE_VENDOR := NETGEAR DEVICE_DTS_CONFIG := config@4 NETGEAR_BOARD_ID := EX6150v2series NETGEAR_HW_ID := 29765285+16+0+128+2x2 @@ -549,7 +623,6 @@ endef define Device/netgear_ex6100v2 $(call Device/netgear_ex61x0v2) - DEVICE_VENDOR := Netgear DEVICE_MODEL := EX6100 DEVICE_VARIANT := v2 endef @@ -557,7 +630,6 @@ TARGET_DEVICES += netgear_ex6100v2 define Device/netgear_ex6150v2 $(call Device/netgear_ex61x0v2) - DEVICE_VENDOR := Netgear DEVICE_MODEL := EX6150 DEVICE_VARIANT := v2 endef @@ -593,9 +665,40 @@ define Device/openmesh_a62 IMAGE/sysupgrade.bin/squashfs := append-rootfs | pad-rootfs | sysupgrade-tar rootfs=$$$$@ | append-metadata DEVICE_PACKAGES := ath10k-firmware-qca9888-ct uboot-envtools endef - TARGET_DEVICES += openmesh_a62 +define Device/plasmacloud_pa1200 + $(call Device/FitImageLzma) + DEVICE_VENDOR := Plasma Cloud + DEVICE_MODEL := PA1200 + SOC := qcom-ipq4018 + DEVICE_DTS_CONFIG := config@pc.pa1200 + BLOCKSIZE := 64k + KERNEL = kernel-bin | lzma | fit lzma $$(DTS_DIR)/$$(DEVICE_DTS).dtb | pad-to $$(BLOCKSIZE) + IMAGE_SIZE := 15616k + IMAGES += factory.bin + IMAGE/factory.bin := append-rootfs | pad-rootfs | openmesh-image ce_type=PA1200 + IMAGE/sysupgrade.bin/squashfs := append-rootfs | pad-rootfs | sysupgrade-tar rootfs=$$$$@ | append-metadata + DEVICE_PACKAGES := uboot-envtools ipq-wifi-plasmacloud-pa1200 +endef +TARGET_DEVICES += plasmacloud_pa1200 + +define Device/plasmacloud_pa2200 + $(call Device/FitImageLzma) + DEVICE_VENDOR := Plasma Cloud + DEVICE_MODEL := PA2200 + SOC := qcom-ipq4019 + DEVICE_DTS_CONFIG := config@pc.pa2200 + BLOCKSIZE := 64k + KERNEL = kernel-bin | lzma | fit lzma $$(DTS_DIR)/$$(DEVICE_DTS).dtb | pad-to $$(BLOCKSIZE) + IMAGE_SIZE := 15552k + IMAGES += factory.bin + IMAGE/factory.bin := append-rootfs | pad-rootfs | openmesh-image ce_type=PA2200 + IMAGE/sysupgrade.bin/squashfs := append-rootfs | pad-rootfs | sysupgrade-tar rootfs=$$$$@ | append-metadata + DEVICE_PACKAGES := ath10k-firmware-qca9888-ct ipq-wifi-plasmacloud-pa2200 uboot-envtools +endef +TARGET_DEVICES += plasmacloud_pa2200 + define Device/qcom_ap-dk01.1-c1 DEVICE_VENDOR := Qualcomm Atheros DEVICE_MODEL := AP-DK01.1 @@ -671,6 +774,21 @@ define Device/p2w_r619ac-128m endef TARGET_DEVICES += p2w_r619ac-128m +define Device/pangu_l1000 + $(call Device/FitImage) + $(call Device/UbiFit) + DEVICE_VENDOR := PANGU + DEVICE_MODEL := L1000 + SOC := qcom-ipq4019 + DEVICE_DTS := qcom-ipq4019-l1000 + KERNEL_INSTALL := 1 + BLOCKSIZE := 128k + PAGESIZE := 2048 + BOARD_NAME := l1000 + DEVICE_PACKAGES := ipq-wifi-pangu_l1000 +endef +TARGET_DEVICES += pangu_l1000 + define Device/qxwlan_e2600ac-c1 $(call Device/FitImage) DEVICE_VENDOR := Qxwlan @@ -746,4 +864,4 @@ define Device/zyxel_wre6606 endef TARGET_DEVICES += zyxel_wre6606 -$(eval $(call BuildImage)) +$(eval $(call BuildImage)) \ No newline at end of file diff --git a/root/target/linux/ipq40xx/patches-5.4/901-arm-boot-add-dts-files.patch b/root/target/linux/ipq40xx/patches-5.4/901-arm-boot-add-dts-files.patch index 5aa9be3b..d278ead6 100644 --- a/root/target/linux/ipq40xx/patches-5.4/901-arm-boot-add-dts-files.patch +++ b/root/target/linux/ipq40xx/patches-5.4/901-arm-boot-add-dts-files.patch @@ -10,7 +10,7 @@ Signed-off-by: John Crispin --- a/arch/arm/boot/dts/Makefile +++ b/arch/arm/boot/dts/Makefile -@@ -837,11 +837,53 @@ dtb-$(CONFIG_ARCH_QCOM) += \ +@@ -837,11 +837,60 @@ dtb-$(CONFIG_ARCH_QCOM) += \ qcom-apq8074-dragonboard.dtb \ qcom-apq8084-ifc6540.dtb \ qcom-apq8084-mtp.dtb \ @@ -18,8 +18,10 @@ Signed-off-by: John Crispin + qcom-ipq4018-ap120c-ac.dtb \ + qcom-ipq4018-dap-2610.dtb \ + qcom-ipq4018-cs-w3-wd1200g-eup.dtb \ ++ qcom-ipq4018-magic-2-wifi-next.dtb \ + qcom-ipq4018-ea6350v3.dtb \ + qcom-ipq4018-eap1300.dtb \ ++ qcom-ipq4018-ecw5211.dtb \ + qcom-ipq4018-emd1.dtb \ + qcom-ipq4018-emr3500.dtb \ + qcom-ipq4018-ens620ext.dtb \ @@ -29,8 +31,11 @@ Signed-off-by: John Crispin + qcom-ipq4018-jalapeno.dtb \ + qcom-ipq4018-meshpoint-one.dtb \ + qcom-ipq4018-nbg6617.dtb \ ++ qcom-ipq4019-oap100.dtb \ ++ qcom-ipq4018-pa1200.dtb \ + qcom-ipq4018-rt-ac58u.dtb \ + qcom-ipq4018-wre6606.dtb \ ++ qcom-ipq4018-wrtq-329acn.dtb \ qcom-ipq4019-ap.dk01.1-c1.dtb \ qcom-ipq4019-ap.dk04.1-c1.dtb \ qcom-ipq4019-ap.dk04.1-c3.dtb \ @@ -43,17 +48,19 @@ Signed-off-by: John Crispin + qcom-ipq4019-fritzbox-7530.dtb \ + qcom-ipq4019-fritzrepeater-1200.dtb \ + qcom-ipq4019-fritzrepeater-3000.dtb \ -+ qcom-ipq4019-r619ac.dtb \ -+ qcom-ipq4019-l1000.dtb \ -+ qcom-ipq4019-r619ac-128m.dtb \ + qcom-ipq4019-map-ac2200.dtb \ ++ qcom-ipq4019-mr8300.dtb \ + qcom-ipq4019-e2600ac-c1.dtb \ + qcom-ipq4019-e2600ac-c2.dtb \ + qcom-ipq4019-habanero-dvk.dtb \ ++ qcom-ipq4019-pa2200.dtb \ + qcom-ipq4019-rtl30vw.dtb \ + qcom-ipq4019-u4019-32m.dtb \ + qcom-ipq4019-wpj419.dtb \ + qcom-ipq4019-wtr-m2133hp.dtb \ ++ qcom-ipq4019-r619ac.dtb \ ++ qcom-ipq4019-r619ac-128m.dtb \ ++ qcom-ipq4019-l1000.dtb \ + qcom-ipq4028-wpj428.dtb \ + qcom-ipq4029-ap-303.dtb \ + qcom-ipq4029-ap-303h.dtb \ @@ -63,4 +70,4 @@ Signed-off-by: John Crispin + qcom-ipq4029-mr33.dtb \ qcom-ipq8064-ap148.dtb \ qcom-msm8660-surf.dtb \ - qcom-msm8960-cdp.dtb \ + qcom-msm8960-cdp.dtb \ \ No newline at end of file diff --git a/root/target/linux/mediatek/Makefile b/root/target/linux/mediatek/Makefile deleted file mode 100644 index 8ccaa927..00000000 --- a/root/target/linux/mediatek/Makefile +++ /dev/null @@ -1,19 +0,0 @@ -# Copyright (c) 2015 OpenWrt.org -# -include $(TOPDIR)/rules.mk - -ARCH:=arm -BOARD:=mediatek -BOARDNAME:=MediaTek Ralink ARM -SUBTARGETS:=mt7622 mt7623 mt7629 -FEATURES:=squashfs nand ramdisk fpu ext4 usb - -KERNEL_PATCHVER:=5.4 -KERNEL_TESTING_PATCHVER:=5.4 - -include $(INCLUDE_DIR)/target.mk -DEFAULT_PACKAGES += \ - kmod-leds-gpio kmod-gpio-button-hotplug \ - wpad-mini uboot-envtools partx-utils e2fsprogs - -$(eval $(call BuildTarget)) diff --git a/root/target/linux/mediatek/base-files/etc/inittab b/root/target/linux/mediatek/base-files/etc/inittab deleted file mode 100644 index 18857874..00000000 --- a/root/target/linux/mediatek/base-files/etc/inittab +++ /dev/null @@ -1,4 +0,0 @@ -::sysinit:/etc/init.d/rcS S boot -::shutdown:/etc/init.d/rcS K shutdown -::askconsole:/usr/libexec/login.sh -ttyS0::askfirst:/usr/libexec/login.sh diff --git a/root/target/linux/mediatek/base-files/etc/uci-defaults/99-net-ps b/root/target/linux/mediatek/base-files/etc/uci-defaults/99-net-ps deleted file mode 100755 index 674589a1..00000000 --- a/root/target/linux/mediatek/base-files/etc/uci-defaults/99-net-ps +++ /dev/null @@ -1,6 +0,0 @@ -uci set network.globals.default_rps_val=14 -uci set network.globals.default_rps_flow_cnt=256 -uci set network.globals.default_xps_val=14 -uci set network.globals.default_ps=1 -uci commit -exit 0 diff --git a/root/target/linux/mediatek/base-files/lib/preinit/05_set_preinit_iface b/root/target/linux/mediatek/base-files/lib/preinit/05_set_preinit_iface deleted file mode 100644 index 0184a7c6..00000000 --- a/root/target/linux/mediatek/base-files/lib/preinit/05_set_preinit_iface +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/sh - -set_preinit_iface() { - ifconfig eth0 up - ifname=lan -} - -boot_hook_add preinit_main set_preinit_iface - diff --git a/root/target/linux/mediatek/base-files/lib/preinit/06_set_rps_sock_flow b/root/target/linux/mediatek/base-files/lib/preinit/06_set_rps_sock_flow deleted file mode 100644 index 9a84ff4b..00000000 --- a/root/target/linux/mediatek/base-files/lib/preinit/06_set_rps_sock_flow +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/sh - -set_rps_sock_flow() { - echo 1024 > /proc/sys/net/core/rps_sock_flow_entries -} - -boot_hook_add preinit_main set_rps_sock_flow - diff --git a/root/target/linux/mediatek/base-files/lib/preinit/07_set_iface_mac b/root/target/linux/mediatek/base-files/lib/preinit/07_set_iface_mac deleted file mode 100644 index 1ad70145..00000000 --- a/root/target/linux/mediatek/base-files/lib/preinit/07_set_iface_mac +++ /dev/null @@ -1,48 +0,0 @@ -#!/bin/sh -# Copyright (C) 2018 OpenWrt.org - -RECOVERY_PART=/dev/mmcblk0p1 - -preinit_set_mac_address() { - local mac - - . /lib/functions.sh - . /lib/functions/system.sh - - case $(board_name) in - 'bananapi,bpi-r2'|\ - "unielec,u7623"*) - if [ -b $RECOVERY_PART ]; then - insmod nls_cp437 - insmod nls_iso8859-1 - insmod fat - insmod vfat - mkdir -p /tmp/recovery - mount -o rw,noatime $RECOVERY_PART /tmp/recovery - - if [ -f "/tmp/recovery/mac_addr" ]; - then - mac=$(cat /tmp/recovery/mac_addr) - else - mac=$(cat /sys/class/net/eth0/address) - echo "$mac" > /tmp/recovery/mac_addr - fi - - sync - umount /tmp/recovery - rm -rf /tmp/recovery - fi - - ip link set dev lan address $mac 2> /dev/null - - mac=$(macaddr_add $mac 1) - - ip link set dev wan1 address $mac 2>/dev/null - ip link set dev wan2 address $mac 2>/dev/null - ip link set dev wan3 address $mac 2>/dev/null - ip link set dev wan4 address $mac 2>/dev/null - ;; - esac -} - -boot_hook_add preinit_main preinit_set_mac_address diff --git a/root/target/linux/mediatek/base-files/lib/preinit/79_move_config b/root/target/linux/mediatek/base-files/lib/preinit/79_move_config deleted file mode 100644 index e8e62883..00000000 --- a/root/target/linux/mediatek/base-files/lib/preinit/79_move_config +++ /dev/null @@ -1,19 +0,0 @@ -#!/bin/sh -# Copyright (C) 2015 OpenWrt.org - -RECOVERY_PART=/dev/mmcblk0p1 - -move_config() { - if [ -b $RECOVERY_PART ]; then - insmod nls_cp437 - insmod nls_iso8859-1 - insmod fat - insmod vfat - mkdir -p /recovery - mount -o rw,noatime $RECOVERY_PART /recovery - [ -f /recovery/sysupgrade.tgz ] && mv -f /recovery/sysupgrade.tgz / - umount /recovery - fi -} - -boot_hook_add preinit_mount_root move_config diff --git a/root/target/linux/mediatek/base-files/lib/preinit/90_init_jffs2 b/root/target/linux/mediatek/base-files/lib/preinit/90_init_jffs2 deleted file mode 100644 index 8a510b74..00000000 --- a/root/target/linux/mediatek/base-files/lib/preinit/90_init_jffs2 +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/sh -do_firstboot() { - if [ "$(mount | grep jffs2)" = "" ]; then - /sbin/firstboot -y - fi -} -boot_hook_add preinit_main do_firstboot \ No newline at end of file diff --git a/root/target/linux/mediatek/base-files/lib/upgrade/platform.sh b/root/target/linux/mediatek/base-files/lib/upgrade/platform.sh deleted file mode 100755 index ee69952e..00000000 --- a/root/target/linux/mediatek/base-files/lib/upgrade/platform.sh +++ /dev/null @@ -1,85 +0,0 @@ -platform_do_upgrade() { - local board=$(board_name) - case "$board" in - "unielec,u7623"*) - #Keep the persisten random mac address (if it exists) - mkdir -p /tmp/recovery - mount -o rw,noatime /dev/mmcblk0p1 /tmp/recovery - [ -f "/tmp/recovery/mac_addr" ] && \ - mv -f /tmp/recovery/mac_addr /tmp/ - umount /tmp/recovery - - #1310720 is the offset in bytes from the start of eMMC and to - #the location of the kernel (2560 512 byte sectors) - get_image "$1" | dd of=/dev/mmcblk0 bs=1310720 seek=1 conv=fsync - - mount -o rw,noatime /dev/mmcblk0p1 /tmp/recovery - [ -f "/tmp/mac_addr" ] && mv -f /tmp/mac_addr /tmp/recovery - sync - umount /tmp/recovery - ;; - bananapi,bpi-r2) - local tar_file="$1" - - echo "flashing kernel" - tar xf $tar_file sysupgrade-7623n-bananapi-bpi-r2/kernel -O | mtd write - kernel - - echo "flashing rootfs" - tar xf $tar_file sysupgrade-7623n-bananapi-bpi-r2/root -O | mtd write - rootfs - ;; - *) - default_do_upgrade "$ARGV" - ;; - esac -} - -PART_NAME=firmware - -platform_check_image() { - local board=$(board_name) - - [ "$#" -gt 1 ] && return 1 - - case "$board" in - bananapi,bpi-r2) - local tar_file="$1" - local kernel_length=`(tar xf $tar_file sysupgrade-7623n-bananapi-bpi-r2/kernel -O | wc -c) 2> /dev/null` - local rootfs_length=`(tar xf $tar_file sysupgrade-7623n-bananapi-bpi-r2/root -O | wc -c) 2> /dev/null` - [ "$kernel_length" = 0 -o "$rootfs_length" = 0 ] && { - echo "The upgrade image is corrupt." - return 1 - } - ;; - "unielec,u7623"*) - local magic="$(get_magic_long "$1")" - [ "$magic" != "27051956" ] && { - echo "Invalid image type." - return 1 - } - return 0 - ;; - - *) - echo "Sysupgrade is not supported on your board yet." - return 1 - ;; - esac - - return 0 -} - -platform_copy_config_emmc() { - mkdir -p /recovery - mount -o rw,noatime /dev/mmcblk0p1 /recovery - cp -af "$CONF_TAR" /recovery/ - sync - umount /recovery -} - -platform_copy_config() { - case "$(board_name)" in - "unielec,u7623"*) - platform_copy_config_emmc - ;; - esac -} diff --git a/root/target/linux/mediatek/modules.mk b/root/target/linux/mediatek/modules.mk deleted file mode 100644 index eb81afe2..00000000 --- a/root/target/linux/mediatek/modules.mk +++ /dev/null @@ -1,51 +0,0 @@ -define KernelPackage/ata-ahci-mtk - TITLE:=Mediatek AHCI Serial ATA support - KCONFIG:=CONFIG_AHCI_MTK - FILES:= \ - $(LINUX_DIR)/drivers/ata/ahci_mtk.ko \ - $(LINUX_DIR)/drivers/ata/libahci_platform.ko - AUTOLOAD:=$(call AutoLoad,40,libahci libahci_platform ahci_mtk,1) - $(call AddDepends/ata) - DEPENDS+=@(TARGET_mediatek_mt7622||TARGET_mediatek_mt7623) -endef - -define KernelPackage/ata-ahci-mtk/description - Mediatek AHCI Serial ATA host controllers -endef - -$(eval $(call KernelPackage,ata-ahci-mtk)) - -define KernelPackage/sdhci-mtk - SUBMENU:=Other modules - TITLE:=Mediatek SDHCI driver - DEPENDS:=@TARGET_mediatek_mt7622 +kmod-sdhci - KCONFIG:=CONFIG_MMC_MTK - FILES:= \ - $(LINUX_DIR)/drivers/mmc/host/mtk-sd.ko - AUTOLOAD:=$(call AutoProbe,mtk-sd,1) -endef - -$(eval $(call KernelPackage,sdhci-mtk)) - -define KernelPackage/crypto-hw-mtk - TITLE:= MediaTek's Crypto Engine module - DEPENDS:=@TARGET_mediatek - KCONFIG:= \ - CONFIG_CRYPTO_HW=y \ - CONFIG_CRYPTO_AES=y \ - CONFIG_CRYPTO_AEAD=y \ - CONFIG_CRYPTO_SHA1=y \ - CONFIG_CRYPTO_SHA256=y \ - CONFIG_CRYPTO_SHA512=y \ - CONFIG_CRYPTO_HMAC=y \ - CONFIG_CRYPTO_DEV_MEDIATEK - FILES:=$(LINUX_DIR)/drivers/crypto/mediatek/mtk-crypto.ko - AUTOLOAD:=$(call AutoLoad,90,mtk-crypto) - $(call AddDepends/crypto) -endef - -define KernelPackage/crypto-hw-mtk/description - MediaTek's EIP97 Cryptographic Engine driver. -endef - -$(eval $(call KernelPackage,crypto-hw-mtk)) diff --git a/root/target/linux/mediatek/mt7623/base-files/etc/board.d/02_network b/root/target/linux/mediatek/mt7623/base-files/etc/board.d/02_network deleted file mode 100755 index a162e373..00000000 --- a/root/target/linux/mediatek/mt7623/base-files/etc/board.d/02_network +++ /dev/null @@ -1,36 +0,0 @@ -#!/bin/sh - -. /lib/functions.sh -. /lib/functions/uci-defaults.sh -. /lib/functions/system.sh - -mediatek_setup_interfaces() -{ - local board="$1" - - case $board in - bananapi,bpi-r2|\ - unielec,u7623-02-emmc-512m) - ucidef_set_interfaces_lan_wan "wan1 wan2 wan3 wan4" "lan" - ;; - esac -} - -mediatek_setup_macs() -{ - local board="$1" - - case $board in - unielec,u7623-02-emmc-512m) - ucidef_set_interface_macaddr "lan" "$(cat /sys/class/net/lan/address)" - ;; - esac -} - -board_config_update -board=$(board_name) -mediatek_setup_interfaces $board -mediatek_setup_macs $board -board_config_flush - -exit 0 diff --git a/root/target/linux/mediatek/mt7623/base-files/lib/preinit/07_set_iface_mac b/root/target/linux/mediatek/mt7623/base-files/lib/preinit/07_set_iface_mac deleted file mode 100644 index 8141c3db..00000000 --- a/root/target/linux/mediatek/mt7623/base-files/lib/preinit/07_set_iface_mac +++ /dev/null @@ -1,47 +0,0 @@ -#!/bin/sh -# Copyright (C) 2018 OpenWrt.org - -RECOVERY_PART=/dev/mmcblk0p1 - -preinit_set_mac_address() { - local mac - - . /lib/functions.sh - . /lib/functions/system.sh - - case $(board_name) in - unielec,u7623-02-emmc-512m) - if [ -b $RECOVERY_PART ]; then - insmod nls_cp437 - insmod nls_iso8859-1 - insmod fat - insmod vfat - mkdir -p /tmp/recovery - mount -o rw,noatime $RECOVERY_PART /tmp/recovery - - if [ -f "/tmp/recovery/mac_addr" ]; - then - mac=$(cat /tmp/recovery/mac_addr) - else - mac=$(cat /sys/class/net/eth0/address) - echo "$mac" > /tmp/recovery/mac_addr - fi - - sync - umount /tmp/recovery - rm -rf /tmp/recovery - fi - - ip link set dev lan address $mac 2> /dev/null - - mac=$(macaddr_add $mac 1) - - ip link set dev wan1 address $mac 2>/dev/null - ip link set dev wan2 address $mac 2>/dev/null - ip link set dev wan3 address $mac 2>/dev/null - ip link set dev wan4 address $mac 2>/dev/null - ;; - esac -} - -boot_hook_add preinit_main preinit_set_mac_address diff --git a/root/target/linux/mediatek/mt7623/base-files/lib/preinit/79_move_config b/root/target/linux/mediatek/mt7623/base-files/lib/preinit/79_move_config deleted file mode 100644 index 4be18114..00000000 --- a/root/target/linux/mediatek/mt7623/base-files/lib/preinit/79_move_config +++ /dev/null @@ -1,19 +0,0 @@ -#!/bin/sh -# Copyright (C) 2012-2015 OpenWrt.org - -move_config() { - local partdev - - . /lib/upgrade/common.sh - - if export_bootdevice && export_partdevice partdev -1; then - if mount -t vfat -o rw,noatime "/dev/$partdev" /mnt; then - if [ -f /mnt/sysupgrade.tgz ]; then - mv -f /mnt/sysupgrade.tgz / - fi - umount /mnt - fi - fi -} - -boot_hook_add preinit_mount_root move_config diff --git a/root/target/linux/mediatek/mt7623/base-files/lib/upgrade/platform.sh b/root/target/linux/mediatek/mt7623/base-files/lib/upgrade/platform.sh deleted file mode 100755 index f117f98c..00000000 --- a/root/target/linux/mediatek/mt7623/base-files/lib/upgrade/platform.sh +++ /dev/null @@ -1,154 +0,0 @@ -platform_do_upgrade() { - local board=$(board_name) - - case "$board" in - unielec,u7623-02-emmc-512m) - #Keep the persisten random mac address (if it exists) - mkdir -p /tmp/recovery - mount -o rw,noatime /dev/mmcblk0p1 /tmp/recovery - [ -f "/tmp/recovery/mac_addr" ] && \ - mv -f /tmp/recovery/mac_addr /tmp/ - umount /tmp/recovery - - #1310720 is the offset in bytes from the start of eMMC and to - #the location of the kernel (2560 512 byte sectors) - get_image "$1" | dd of=/dev/mmcblk0 bs=1310720 seek=1 conv=fsync - - mount -o rw,noatime /dev/mmcblk0p1 /tmp/recovery - [ -f "/tmp/mac_addr" ] && mv -f /tmp/mac_addr /tmp/recovery - sync - umount /tmp/recovery - ;; - bananapi,bpi-r2) - local diskdev partdev diff - - export_bootdevice && export_partdevice diskdev -2 || { - echo "Unable to determine upgrade device" - return 1 - } - - sync - - if [ "$SAVE_PARTITIONS" = "1" ]; then - get_partitions "/dev/$diskdev" bootdisk - - #extract the boot sector from the image - get_image "$@" | dd of=/tmp/image.bs count=1 bs=512b - - get_partitions /tmp/image.bs image - - #compare tables - diff="$(grep -F -x -v -f /tmp/partmap.bootdisk /tmp/partmap.image)" - else - diff=1 - fi - - if [ -n "$diff" ]; then - get_image "$@" | dd of="/dev/$diskdev" bs=4096 conv=fsync - - # Separate removal and addtion is necessary; otherwise, partition 1 - # will be missing if it overlaps with the old partition 2 - partx -d - "/dev/$diskdev" - partx -a - "/dev/$diskdev" - - return 0 - fi - - #write uboot image - get_image "$@" | dd of="$diskdev" bs=1024 skip=320 seek=320 count=700 conv=fsync - #iterate over each partition from the image and write it to the boot disk - while read part start size; do - part="$(($part - 2))" - if export_partdevice partdev $part; then - echo "Writing image to /dev/$partdev..." - get_image "$@" | dd of="/dev/$partdev" ibs="512" obs=1M skip="$start" count="$size" conv=fsync - else - echo "Unable to find partition $part device, skipped." - fi - done < /tmp/partmap.image - - #copy partition uuid - echo "Writing new UUID to /dev/$diskdev..." - get_image "$@" | dd of="/dev/$diskdev" bs=1 skip=440 count=4 seek=440 conv=fsync - ;; - *) - default_do_upgrade "$1" - ;; - esac -} - -PART_NAME=firmware - -platform_check_image() { - local board=$(board_name) - local magic="$(get_magic_long "$1")" - - [ "$#" -gt 1 ] && return 1 - - case "$board" in - unielec,u7623-02-emmc-512m) - [ "$magic" != "27051956" ] && { - echo "Invalid image type." - return 1 - } - return 0 - ;; - bananapi,bpi-r2) - local diskdev partdev diff - - export_bootdevice && export_partdevice diskdev -2 || { - echo "Unable to determine upgrade device" - return 1 - } - - get_partitions "/dev/$diskdev" bootdisk - - #extract the boot sector from the image - get_image "$@" | dd of=/tmp/image.bs count=1 bs=512b 2>/dev/null - - get_partitions /tmp/image.bs image - - #compare tables - diff="$(grep -F -x -v -f /tmp/partmap.bootdisk /tmp/partmap.image)" - - rm -f /tmp/image.bs /tmp/partmap.bootdisk /tmp/partmap.image - - if [ -n "$diff" ]; then - echo "Partition layout has changed. Full image will be written." - ask_bool 0 "Abort" && exit 1 - return 0 - fi - ;; - *) - echo "Sysupgrade is not supported on your board yet." - return 1 - ;; - esac - - return 0 -} - -platform_copy_config_emmc() { - mkdir -p /recovery - mount -o rw,noatime /dev/mmcblk0p1 /recovery - cp -af "$UPGRADE_BACKUP" "/recovery/$BACKUP_FILE" - sync - umount /recovery -} - -platform_copy_config() { - case "$(board_name)" in - unielec,u7623-02-emmc-512m) - platform_copy_config_emmc - ;; - bananapi,bpi-r2) - local partdev - - if export_partdevice partdev -1; then - mount -t vfat -o rw,noatime "/dev/$partdev" /mnt - cp -af "$CONF_TAR" /mnt/ - umount /mnt - fi - ;; - esac -} diff --git a/root/target/linux/mediatek/mt7623/config-4.14 b/root/target/linux/mediatek/mt7623/config-4.14 deleted file mode 100644 index 07f6b76d..00000000 --- a/root/target/linux/mediatek/mt7623/config-4.14 +++ /dev/null @@ -1,570 +0,0 @@ -# CONFIG_AIO is not set -CONFIG_ALIGNMENT_TRAP=y -CONFIG_ARCH_CLOCKSOURCE_DATA=y -CONFIG_ARCH_HAS_DEBUG_VIRTUAL=y -CONFIG_ARCH_HAS_ELF_RANDOMIZE=y -CONFIG_ARCH_HAS_GCOV_PROFILE_ALL=y -CONFIG_ARCH_HAS_SET_MEMORY=y -CONFIG_ARCH_HAS_SG_CHAIN=y -CONFIG_ARCH_HAS_STRICT_KERNEL_RWX=y -CONFIG_ARCH_HAS_STRICT_MODULE_RWX=y -CONFIG_ARCH_HAS_TICK_BROADCAST=y -CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y -CONFIG_ARCH_HIBERNATION_POSSIBLE=y -CONFIG_ARCH_MEDIATEK=y -CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y -CONFIG_ARCH_MULTIPLATFORM=y -# CONFIG_ARCH_MULTI_CPU_AUTO is not set -CONFIG_ARCH_MULTI_V6_V7=y -CONFIG_ARCH_MULTI_V7=y -CONFIG_ARCH_NR_GPIO=0 -CONFIG_ARCH_OPTIONAL_KERNEL_RWX=y -CONFIG_ARCH_OPTIONAL_KERNEL_RWX_DEFAULT=y -# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set -# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set -CONFIG_ARCH_SUPPORTS_ATOMIC_RMW=y -CONFIG_ARCH_SUPPORTS_UPROBES=y -CONFIG_ARCH_SUSPEND_POSSIBLE=y -CONFIG_ARCH_USE_BUILTIN_BSWAP=y -CONFIG_ARCH_USE_CMPXCHG_LOCKREF=y -# CONFIG_ARCH_WANTS_THP_SWAP is not set -CONFIG_ARCH_WANT_GENERAL_HUGETLB=y -CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y -CONFIG_ARM=y -CONFIG_ARM_APPENDED_DTB=y -CONFIG_ARM_ARCH_TIMER=y -CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y -CONFIG_ARM_ATAG_DTB_COMPAT=y -CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_EXTEND=y -# CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_FROM_BOOTLOADER is not set -CONFIG_ARM_CPU_SUSPEND=y -# CONFIG_ARM_CPU_TOPOLOGY is not set -CONFIG_ARM_GIC=y -CONFIG_ARM_HAS_SG_CHAIN=y -CONFIG_ARM_L1_CACHE_SHIFT=6 -CONFIG_ARM_L1_CACHE_SHIFT_6=y -# CONFIG_ARM_LPAE is not set -CONFIG_ARM_MEDIATEK_CPUFREQ=y -CONFIG_ARM_PATCH_IDIV=y -CONFIG_ARM_PATCH_PHYS_VIRT=y -# CONFIG_ARM_SMMU is not set -CONFIG_ARM_THUMB=y -CONFIG_ARM_THUMBEE=y -CONFIG_ARM_UNWIND=y -CONFIG_ARM_VIRT_EXT=y -CONFIG_ATAGS=y -CONFIG_ATAGS_PROC=y -CONFIG_AUTO_ZRELADDR=y -CONFIG_BLK_DEV_LOOP=y -CONFIG_BLK_MQ_PCI=y -CONFIG_BOUNCE=y -# CONFIG_CACHE_L2X0 is not set -CONFIG_CC_STACKPROTECTOR=y -# CONFIG_CC_STACKPROTECTOR_NONE is not set -CONFIG_CC_STACKPROTECTOR_REGULAR=y -CONFIG_CFG80211=m -CONFIG_CFG80211_CRDA_SUPPORT=y -# CONFIG_CFG80211_DEBUGFS is not set -CONFIG_CFG80211_DEFAULT_PS=y -# CONFIG_CFG80211_DEVELOPER_WARNINGS is not set -# CONFIG_CFG80211_INTERNAL_REGDB is not set -# CONFIG_CFG80211_WEXT is not set -CONFIG_CLEANCACHE=y -CONFIG_CLKDEV_LOOKUP=y -CONFIG_CLKSRC_MMIO=y -CONFIG_CLONE_BACKWARDS=y -CONFIG_CMDLINE="earlyprintk console=ttyS0,115200 vmalloc=256M" -CONFIG_CMDLINE_EXTEND=y -CONFIG_COMMON_CLK=y -CONFIG_COMMON_CLK_MEDIATEK=y -CONFIG_COMMON_CLK_MT2701=y -CONFIG_COMMON_CLK_MT2701_BDPSYS=y -CONFIG_COMMON_CLK_MT2701_ETHSYS=y -CONFIG_COMMON_CLK_MT2701_HIFSYS=y -CONFIG_COMMON_CLK_MT2701_IMGSYS=y -CONFIG_COMMON_CLK_MT2701_MMSYS=y -CONFIG_COMMON_CLK_MT2701_VDECSYS=y -# CONFIG_COMMON_CLK_MT7622 is not set -# CONFIG_COMMON_CLK_MT8135 is not set -# CONFIG_COMMON_CLK_MT8173 is not set -CONFIG_COMPACTION=y -CONFIG_COREDUMP=y -# CONFIG_CPUFREQ_DT is not set -CONFIG_CPU_32v6K=y -CONFIG_CPU_32v7=y -CONFIG_CPU_ABRT_EV7=y -# CONFIG_CPU_BPREDICT_DISABLE is not set -CONFIG_CPU_CACHE_V7=y -CONFIG_CPU_CACHE_VIPT=y -CONFIG_CPU_COPY_V6=y -CONFIG_CPU_CP15=y -CONFIG_CPU_CP15_MMU=y -CONFIG_CPU_FREQ=y -CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y -CONFIG_CPU_FREQ_GOV_ATTR_SET=y -CONFIG_CPU_FREQ_GOV_COMMON=y -CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y -CONFIG_CPU_FREQ_GOV_ONDEMAND=y -CONFIG_CPU_FREQ_GOV_PERFORMANCE=y -CONFIG_CPU_FREQ_GOV_POWERSAVE=y -# CONFIG_CPU_FREQ_GOV_USERSPACE is not set -CONFIG_CPU_FREQ_STAT=y -CONFIG_CPU_HAS_ASID=y -# CONFIG_CPU_HOTPLUG_STATE_CONTROL is not set -# CONFIG_CPU_ICACHE_DISABLE is not set -CONFIG_CPU_PABRT_V7=y -CONFIG_CPU_PM=y -CONFIG_CPU_RMAP=y -# CONFIG_CPU_THERMAL is not set -CONFIG_CPU_THUMB_CAPABLE=y -CONFIG_CPU_TLB_V7=y -CONFIG_CPU_V7=y -CONFIG_CRASH_CORE=y -CONFIG_CRC16=y -# CONFIG_CRC32_SARWATE is not set -CONFIG_CRC32_SLICEBY8=y -CONFIG_CROSS_MEMORY_ATTACH=y -CONFIG_CRYPTO_ACOMP2=y -CONFIG_CRYPTO_AEAD=y -CONFIG_CRYPTO_AEAD2=y -CONFIG_CRYPTO_CRC32=y -CONFIG_CRYPTO_CRC32C=y -CONFIG_CRYPTO_CTR=y -CONFIG_CRYPTO_DEFLATE=y -CONFIG_CRYPTO_DEV_MEDIATEK=y -CONFIG_CRYPTO_DRBG=y -CONFIG_CRYPTO_DRBG_HMAC=y -CONFIG_CRYPTO_DRBG_MENU=y -CONFIG_CRYPTO_HASH=y -CONFIG_CRYPTO_HASH2=y -CONFIG_CRYPTO_HMAC=y -CONFIG_CRYPTO_HW=y -CONFIG_CRYPTO_JITTERENTROPY=y -CONFIG_CRYPTO_LZO=y -CONFIG_CRYPTO_MANAGER=y -CONFIG_CRYPTO_MANAGER2=y -CONFIG_CRYPTO_NULL=y -CONFIG_CRYPTO_NULL2=y -CONFIG_CRYPTO_RNG=y -CONFIG_CRYPTO_RNG2=y -CONFIG_CRYPTO_RNG_DEFAULT=y -CONFIG_CRYPTO_SEQIV=y -CONFIG_CRYPTO_SHA1=y -CONFIG_CRYPTO_SHA256=y -CONFIG_CRYPTO_SHA512=y -CONFIG_CRYPTO_WORKQUEUE=y -CONFIG_DCACHE_WORD_ACCESS=y -CONFIG_DEBUG_ALIGN_RODATA=y -CONFIG_DEBUG_BUGVERBOSE=y -CONFIG_DEBUG_GPIO=y -CONFIG_DEBUG_INFO=y -CONFIG_DEBUG_LL=y -CONFIG_DEBUG_LL_INCLUDE="debug/8250.S" -CONFIG_DEBUG_MT6589_UART0=y -# CONFIG_DEBUG_MT8127_UART0 is not set -# CONFIG_DEBUG_MT8135_UART3 is not set -CONFIG_DEBUG_PREEMPT=y -CONFIG_DEBUG_UART_8250=y -# CONFIG_DEBUG_UART_8250_FLOW_CONTROL is not set -CONFIG_DEBUG_UART_8250_SHIFT=2 -# CONFIG_DEBUG_UART_8250_WORD is not set -CONFIG_DEBUG_UART_PHYS=0x11004000 -CONFIG_DEBUG_UART_VIRT=0xf1004000 -CONFIG_DEBUG_UNCOMPRESS=y -# CONFIG_DEBUG_USER is not set -CONFIG_DEFAULT_DUMMY=y -CONFIG_DEFAULT_SCHEDULER=y -CONFIG_DMADEVICES=y -CONFIG_DMA_ENGINE=y -# CONFIG_DMA_NOOP_OPS is not set -CONFIG_DMA_OF=y -# CONFIG_DMA_VIRT_OPS is not set -# CONFIG_DRM_LIB_RANDOM is not set -CONFIG_DTC=y -CONFIG_EARLY_PRINTK=y -CONFIG_EDAC_ATOMIC_SCRUB=y -CONFIG_EDAC_SUPPORT=y -CONFIG_ELF_CORE=y -CONFIG_EXPORTFS=y -CONFIG_EXT4_FS=y -# CONFIG_F2FS_CHECK_FS is not set -CONFIG_F2FS_FS=y -# CONFIG_F2FS_FS_SECURITY is not set -CONFIG_F2FS_FS_XATTR=y -CONFIG_F2FS_STAT_FS=y -CONFIG_FIXED_PHY=y -CONFIG_FIX_EARLYCON_MEM=y -CONFIG_FREEZER=y -CONFIG_FS_MBCACHE=y -CONFIG_FUTEX_PI=y -CONFIG_GENERIC_ALLOCATOR=y -CONFIG_GENERIC_BUG=y -CONFIG_GENERIC_CLOCKEVENTS=y -CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y -CONFIG_GENERIC_CPU_AUTOPROBE=y -CONFIG_GENERIC_EARLY_IOREMAP=y -CONFIG_GENERIC_IDLE_POLL_SETUP=y -CONFIG_GENERIC_IO=y -CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y -CONFIG_GENERIC_IRQ_SHOW=y -CONFIG_GENERIC_IRQ_SHOW_LEVEL=y -CONFIG_GENERIC_MSI_IRQ=y -CONFIG_GENERIC_MSI_IRQ_DOMAIN=y -CONFIG_GENERIC_PCI_IOMAP=y -CONFIG_GENERIC_PHY=y -CONFIG_GENERIC_PINCONF=y -CONFIG_GENERIC_PINCTRL_GROUPS=y -CONFIG_GENERIC_PINMUX_FUNCTIONS=y -CONFIG_GENERIC_SCHED_CLOCK=y -CONFIG_GENERIC_SMP_IDLE_THREAD=y -CONFIG_GENERIC_STRNCPY_FROM_USER=y -CONFIG_GENERIC_STRNLEN_USER=y -CONFIG_GPIOLIB=y -CONFIG_GPIO_SYSFS=y -# CONFIG_GPS is not set -# CONFIG_GRO_CELLS is not set -CONFIG_HANDLE_DOMAIN_IRQ=y -CONFIG_HARDIRQS_SW_RESEND=y -CONFIG_HAS_DMA=y -CONFIG_HAS_IOMEM=y -CONFIG_HAS_IOPORT_MAP=y -# CONFIG_HAVE_64BIT_ALIGNED_ACCESS is not set -CONFIG_HAVE_ARCH_AUDITSYSCALL=y -CONFIG_HAVE_ARCH_BITREVERSE=y -CONFIG_HAVE_ARCH_JUMP_LABEL=y -CONFIG_HAVE_ARCH_KGDB=y -CONFIG_HAVE_ARCH_PFN_VALID=y -CONFIG_HAVE_ARCH_SECCOMP_FILTER=y -CONFIG_HAVE_ARCH_TRACEHOOK=y -CONFIG_HAVE_ARM_ARCH_TIMER=y -CONFIG_HAVE_ARM_SMCCC=y -# CONFIG_HAVE_BOOTMEM_INFO_NODE is not set -CONFIG_HAVE_CC_STACKPROTECTOR=y -CONFIG_HAVE_CLK=y -CONFIG_HAVE_CLK_PREPARE=y -CONFIG_HAVE_CONTEXT_TRACKING=y -CONFIG_HAVE_C_RECORDMCOUNT=y -CONFIG_HAVE_DEBUG_KMEMLEAK=y -CONFIG_HAVE_DMA_API_DEBUG=y -CONFIG_HAVE_DMA_CONTIGUOUS=y -CONFIG_HAVE_DYNAMIC_FTRACE=y -CONFIG_HAVE_DYNAMIC_FTRACE_WITH_REGS=y -CONFIG_HAVE_EBPF_JIT=y -CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y -CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y -CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y -CONFIG_HAVE_FUNCTION_TRACER=y -CONFIG_HAVE_GENERIC_DMA_COHERENT=y -CONFIG_HAVE_IDE=y -CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y -CONFIG_HAVE_MEMBLOCK=y -CONFIG_HAVE_MOD_ARCH_SPECIFIC=y -CONFIG_HAVE_NET_DSA=y -CONFIG_HAVE_OPROFILE=y -CONFIG_HAVE_OPTPROBES=y -CONFIG_HAVE_PERF_EVENTS=y -CONFIG_HAVE_PERF_REGS=y -CONFIG_HAVE_PERF_USER_STACK_DUMP=y -CONFIG_HAVE_PROC_CPU=y -CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y -CONFIG_HAVE_SMP=y -CONFIG_HAVE_SYSCALL_TRACEPOINTS=y -CONFIG_HAVE_UID16=y -CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y -# CONFIG_HIGHMEM is not set -# CONFIG_HIGHPTE is not set -CONFIG_HOTPLUG_CPU=y -CONFIG_HWMON=y -CONFIG_HW_RANDOM=y -CONFIG_HW_RANDOM_MTK=y -CONFIG_HZ_FIXED=0 -CONFIG_HZ_PERIODIC=y -CONFIG_I2C=y -CONFIG_I2C_BOARDINFO=y -CONFIG_I2C_CHARDEV=y -CONFIG_I2C_MT65XX=y -CONFIG_ICPLUS_PHY=y -CONFIG_IIO=y -# CONFIG_IIO_BUFFER is not set -# CONFIG_IIO_TRIGGER is not set -CONFIG_INITRAMFS_COMPRESSION="" -# CONFIG_INITRAMFS_FORCE is not set -CONFIG_INITRAMFS_ROOT_GID=1000 -CONFIG_INITRAMFS_ROOT_UID=1000 -CONFIG_INITRAMFS_SOURCE="/openwrt/trunk/build_dir/target-arm_cortex-a7_musl-1.1.14_eabi/root-mediatek /openwrt/trunk/target/linux/generic/image/initramfs-base-files.txt" -CONFIG_IOMMU_HELPER=y -# CONFIG_IOMMU_IO_PGTABLE_ARMV7S is not set -# CONFIG_IOMMU_IO_PGTABLE_LPAE is not set -CONFIG_IOMMU_SUPPORT=y -CONFIG_IRQCHIP=y -CONFIG_IRQ_DOMAIN=y -CONFIG_IRQ_DOMAIN_HIERARCHY=y -CONFIG_IRQ_FORCED_THREADING=y -CONFIG_IRQ_WORK=y -CONFIG_JBD2=y -CONFIG_KALLSYMS=y -CONFIG_KEXEC=y -CONFIG_KEXEC_CORE=y -CONFIG_LDISC_AUTOLOAD=y -CONFIG_LEDS_MT6323=y -CONFIG_LIBFDT=y -CONFIG_LOCK_SPIN_ON_OWNER=y -CONFIG_LZO_COMPRESS=y -CONFIG_LZO_DECOMPRESS=y -# CONFIG_MACH_MT2701 is not set -# CONFIG_MACH_MT6589 is not set -# CONFIG_MACH_MT6592 is not set -CONFIG_MACH_MT7623=y -# CONFIG_MACH_MT8127 is not set -# CONFIG_MACH_MT8135 is not set -CONFIG_MAGIC_SYSRQ=y -CONFIG_MDIO_BITBANG=y -CONFIG_MDIO_BUS=y -CONFIG_MDIO_DEVICE=y -CONFIG_MDIO_GPIO=y -CONFIG_MEDIATEK_MT6577_AUXADC=y -CONFIG_MEDIATEK_WATCHDOG=y -CONFIG_MFD_CORE=y -CONFIG_MFD_MT6397=y -CONFIG_MFD_SYSCON=y -CONFIG_MIGHT_HAVE_CACHE_L2X0=y -CONFIG_MIGHT_HAVE_PCI=y -CONFIG_MIGRATION=y -CONFIG_MMC=y -CONFIG_MMC_BLOCK=y -CONFIG_MMC_MTK=y -CONFIG_MMC_SDHCI=y -# CONFIG_MMC_SDHCI_PCI is not set -CONFIG_MMC_SDHCI_PLTFM=y -# CONFIG_MMC_TIFM_SD is not set -CONFIG_MODULES_USE_ELF_REL=y -# CONFIG_MPTCP_BINDER is not set -# CONFIG_MPTCP_FULLMESH is not set -# CONFIG_MPTCP_NDIFFPORTS is not set -# CONFIG_MPTCP_REDUNDANT is not set -# CONFIG_MPTCP_ROUNDROBIN is not set -CONFIG_MTD_BLOCK2MTD=y -CONFIG_MTD_CMDLINE_PARTS=y -CONFIG_MTD_M25P80=y -CONFIG_MTD_MT81xx_NOR=y -CONFIG_MTD_NAND=y -CONFIG_MTD_NAND_ECC=y -CONFIG_MTD_NAND_MTK=y -CONFIG_MTD_SPI_NOR=y -CONFIG_MTD_SPLIT_FIRMWARE=y -CONFIG_MTD_SPLIT_UIMAGE_FW=y -CONFIG_MTD_UBI=y -CONFIG_MTD_UBI_BEB_LIMIT=20 -CONFIG_MTD_UBI_BLOCK=y -# CONFIG_MTD_UBI_FASTMAP is not set -# CONFIG_MTD_UBI_GLUEBI is not set -CONFIG_MTD_UBI_WL_THRESHOLD=4096 -CONFIG_MTK_BTIF=y -CONFIG_MTK_COMBO=y -# CONFIG_MTK_COMBO_BT is not set -CONFIG_MTK_COMBO_CHIP="CONSYS_7623" -# CONFIG_MTK_COMBO_CHIP_CONSYS_6572 is not set -# CONFIG_MTK_COMBO_CHIP_CONSYS_6580 is not set -# CONFIG_MTK_COMBO_CHIP_CONSYS_6582 is not set -# CONFIG_MTK_COMBO_CHIP_CONSYS_6592 is not set -# CONFIG_MTK_COMBO_CHIP_CONSYS_6735 is not set -# CONFIG_MTK_COMBO_CHIP_CONSYS_6752 is not set -# CONFIG_MTK_COMBO_CHIP_CONSYS_6755 is not set -# CONFIG_MTK_COMBO_CHIP_CONSYS_6797 is not set -CONFIG_MTK_COMBO_CHIP_CONSYS_7623=y -# CONFIG_MTK_COMBO_CHIP_CONSYS_8127 is not set -# CONFIG_MTK_COMBO_CHIP_CONSYS_8163 is not set -# CONFIG_MTK_COMBO_CHIP_MT6620 is not set -# CONFIG_MTK_COMBO_CHIP_MT6628 is not set -# CONFIG_MTK_COMBO_CHIP_MT6630 is not set -# CONFIG_MTK_COMBO_COMM is not set -# CONFIG_MTK_COMBO_BT_HCI is not set -CONFIG_MTK_COMBO_PLAT_PATH="" -CONFIG_MTK_COMBO_WIFI=m -# CONFIG_MTK_CONN_LTE_IDC_SUPPORT is not set -CONFIG_MTK_DHCPV6C_WIFI=y -CONFIG_MTK_EFUSE=y -# CONFIG_MTK_GPS_SUPPORT is not set -# CONFIG_MTK_HSDMA is not set -CONFIG_MTK_INFRACFG=y -# CONFIG_MTK_IOMMU is not set -# CONFIG_MTK_IOMMU_V1 is not set -CONFIG_MTK_PASSPOINT_R1_SUPPORT=y -CONFIG_MTK_PASSPOINT_R2_SUPPORT=y -CONFIG_MTK_PLATFORM="mt7623" -CONFIG_MTK_PMIC_WRAP=y -CONFIG_MTK_SCPSYS=y -CONFIG_MTK_THERMAL=y -CONFIG_MTK_TIMER=y -CONFIG_MTK_WAPI_SUPPORT=y -CONFIG_MTK_WIFI_MCC_SUPPORT=y -CONFIG_MULTI_IRQ_HANDLER=y -CONFIG_MUTEX_SPIN_ON_OWNER=y -CONFIG_NEED_DMA_MAP_STATE=y -CONFIG_NEON=y -CONFIG_NET_DSA=y -CONFIG_NET_DSA_MT7530=y -# CONFIG_NET_DSA_SMSC_LAN9303_I2C is not set -CONFIG_NET_DSA_TAG_MTK=y -CONFIG_NET_FLOW_LIMIT=y -CONFIG_NET_MEDIATEK_HNAT=y -CONFIG_NET_MEDIATEK_SOC=y -CONFIG_NET_SWITCHDEV=y -# CONFIG_NET_VENDOR_AURORA is not set -CONFIG_NET_VENDOR_MEDIATEK=y -# CONFIG_NET_VENDOR_WIZNET is not set -CONFIG_NL80211_TESTMODE=y -CONFIG_NLS=y -CONFIG_NO_BOOTMEM=y -CONFIG_NR_CPUS=4 -CONFIG_NVMEM=y -CONFIG_OF=y -CONFIG_OF_ADDRESS=y -CONFIG_OF_ADDRESS_PCI=y -CONFIG_OF_EARLY_FLATTREE=y -CONFIG_OF_FLATTREE=y -CONFIG_OF_GPIO=y -CONFIG_OF_IRQ=y -CONFIG_OF_MDIO=y -CONFIG_OF_NET=y -CONFIG_OF_PCI=y -CONFIG_OF_PCI_IRQ=y -CONFIG_OF_RESERVED_MEM=y -CONFIG_OLD_SIGACTION=y -CONFIG_OLD_SIGSUSPEND3=y -CONFIG_PADATA=y -CONFIG_PAGE_OFFSET=0xC0000000 -CONFIG_PCI=y -CONFIG_PCIEAER=y -CONFIG_PCIEPORTBUS=y -CONFIG_PCIE_MEDIATEK=y -CONFIG_PCIE_PME=y -CONFIG_PCI_DOMAINS=y -CONFIG_PCI_DOMAINS_GENERIC=y -CONFIG_PCI_MSI=y -CONFIG_PCI_MSI_IRQ_DOMAIN=y -CONFIG_PERF_USE_VMALLOC=y -CONFIG_PGTABLE_LEVELS=2 -CONFIG_PGTABLE_MAPPING=y -CONFIG_PHYLIB=y -CONFIG_PHY_MTK_TPHY=y -CONFIG_PINCTRL=y -CONFIG_PINCTRL_MT2701=y -CONFIG_PINCTRL_MT6397=y -CONFIG_PINCTRL_MTK=y -CONFIG_PM=y -CONFIG_PM_CLK=y -# CONFIG_PM_DEBUG is not set -CONFIG_PM_GENERIC_DOMAINS=y -CONFIG_PM_GENERIC_DOMAINS_OF=y -CONFIG_PM_GENERIC_DOMAINS_SLEEP=y -CONFIG_PM_OPP=y -CONFIG_PM_SLEEP=y -CONFIG_PM_SLEEP_SMP=y -CONFIG_POWER_RESET=y -CONFIG_POWER_SUPPLY=y -CONFIG_PREEMPT=y -CONFIG_PREEMPT_COUNT=y -# CONFIG_PREEMPT_NONE is not set -CONFIG_PREEMPT_RCU=y -CONFIG_PRINTK_TIME=y -CONFIG_PWM=y -CONFIG_PWM_MEDIATEK=y -# CONFIG_PWM_MTK_DISP is not set -CONFIG_PWM_SYSFS=y -CONFIG_RAS=y -CONFIG_RATIONAL=y -CONFIG_RCU_CPU_STALL_TIMEOUT=21 -# CONFIG_RCU_EXPERT is not set -CONFIG_RCU_NEED_SEGCBLIST=y -CONFIG_RCU_STALL_COMMON=y -CONFIG_REGMAP=y -CONFIG_REGMAP_I2C=y -CONFIG_REGMAP_MMIO=y -CONFIG_REGMAP_SPI=y -CONFIG_REGULATOR=y -CONFIG_REGULATOR_FIXED_VOLTAGE=y -CONFIG_REGULATOR_GPIO=y -CONFIG_REGULATOR_MT6323=y -# CONFIG_REGULATOR_MT6380 is not set -# CONFIG_REGULATOR_MT6397 is not set -# CONFIG_REGULATOR_QCOM_SPMI is not set -CONFIG_RESET_CONTROLLER=y -CONFIG_RFS_ACCEL=y -CONFIG_RPS=y -CONFIG_RTC_CLASS=y -# CONFIG_RTC_DRV_CMOS is not set -# CONFIG_RTC_DRV_MT6397 is not set -# CONFIG_RTC_DRV_MT7622 is not set -CONFIG_RTC_I2C_AND_SPI=y -# CONFIG_RTL8723BS is not set -CONFIG_RWSEM_SPIN_ON_OWNER=y -CONFIG_RWSEM_XCHGADD_ALGORITHM=y -# CONFIG_SCHED_INFO is not set -# CONFIG_SCSI_DMA is not set -# CONFIG_SERIAL_8250_DMA is not set -CONFIG_SERIAL_8250_FSL=y -CONFIG_SERIAL_8250_MT6577=y -CONFIG_SERIAL_8250_NR_UARTS=4 -CONFIG_SERIAL_8250_RUNTIME_UARTS=4 -CONFIG_SMP=y -# CONFIG_SMP_ON_UP is not set -CONFIG_SPARSE_IRQ=y -CONFIG_SPI=y -CONFIG_SPI_BITBANG=y -CONFIG_SPI_MASTER=y -CONFIG_SPI_MT65XX=y -CONFIG_SPMI=y -CONFIG_SRCU=y -# CONFIG_STRIP_ASM_SYMS is not set -CONFIG_SUSPEND=y -CONFIG_SUSPEND_FREEZER=y -CONFIG_SWCONFIG=y -CONFIG_SWIOTLB=y -CONFIG_SWPHY=y -CONFIG_SWP_EMULATE=y -CONFIG_SYS_SUPPORTS_APM_EMULATION=y -CONFIG_TASKS_RCU=y -CONFIG_THERMAL=y -CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y -CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=0 -CONFIG_THERMAL_GOV_STEP_WISE=y -CONFIG_THERMAL_OF=y -CONFIG_THIN_ARCHIVES=y -# CONFIG_THUMB2_KERNEL is not set -CONFIG_TICK_CPU_ACCOUNTING=y -CONFIG_TIMER_OF=y -CONFIG_TIMER_PROBE=y -CONFIG_TREE_SRCU=y -CONFIG_UBIFS_FS=y -# CONFIG_UBIFS_FS_ADVANCED_COMPR is not set -CONFIG_UBIFS_FS_LZO=y -CONFIG_UBIFS_FS_ZLIB=y -CONFIG_UEVENT_HELPER_PATH="" -CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h" -CONFIG_UNINLINE_SPIN_UNLOCK=y -CONFIG_USB=y -CONFIG_USB_COMMON=y -# CONFIG_USB_EHCI_HCD is not set -# CONFIG_USB_MTU3 is not set -CONFIG_USB_SUPPORT=y -CONFIG_USB_XHCI_HCD=y -CONFIG_USB_XHCI_MTK=y -CONFIG_USB_XHCI_PLATFORM=y -CONFIG_USE_OF=y -CONFIG_VECTORS_BASE=0xffff0000 -CONFIG_VFP=y -CONFIG_VFPv3=y -CONFIG_VM_EVENT_COUNTERS=y -CONFIG_WATCHDOG_CORE=y -# CONFIG_WILC1000_SDIO is not set -# CONFIG_WILC1000_SPI is not set -CONFIG_XPS=y -CONFIG_XZ_DEC_ARM=y -CONFIG_XZ_DEC_BCJ=y -CONFIG_ZBOOT_ROM_BSS=0 -CONFIG_ZBOOT_ROM_TEXT=0 -CONFIG_ZLIB_DEFLATE=y -CONFIG_ZLIB_INFLATE=y -CONFIG_ZSMALLOC=y -# CONFIG_ZSMALLOC_STAT is not set \ No newline at end of file diff --git a/root/target/linux/mediatek/mt7623/config-5.4 b/root/target/linux/mediatek/mt7623/config-5.4 deleted file mode 100644 index 6e1ff28b..00000000 --- a/root/target/linux/mediatek/mt7623/config-5.4 +++ /dev/null @@ -1,561 +0,0 @@ -# CONFIG_AIO is not set -CONFIG_ALIGNMENT_TRAP=y -CONFIG_ARCH_32BIT_OFF_T=y -CONFIG_ARCH_CLOCKSOURCE_DATA=y -CONFIG_ARCH_HAS_BINFMT_FLAT=y -CONFIG_ARCH_HAS_DEBUG_VIRTUAL=y -CONFIG_ARCH_HAS_ELF_RANDOMIZE=y -CONFIG_ARCH_HAS_FORTIFY_SOURCE=y -CONFIG_ARCH_HAS_GCOV_PROFILE_ALL=y -CONFIG_ARCH_HAS_KCOV=y -CONFIG_ARCH_HAS_KEEPINITRD=y -CONFIG_ARCH_HAS_MEMBARRIER_SYNC_CORE=y -CONFIG_ARCH_HAS_PHYS_TO_DMA=y -CONFIG_ARCH_HAS_SETUP_DMA_OPS=y -CONFIG_ARCH_HAS_SET_MEMORY=y -CONFIG_ARCH_HAS_STRICT_KERNEL_RWX=y -CONFIG_ARCH_HAS_STRICT_MODULE_RWX=y -CONFIG_ARCH_HAS_TEARDOWN_DMA_OPS=y -CONFIG_ARCH_HAS_TICK_BROADCAST=y -CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y -CONFIG_ARCH_HIBERNATION_POSSIBLE=y -CONFIG_ARCH_KEEP_MEMBLOCK=y -CONFIG_ARCH_MEDIATEK=y -CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y -# CONFIG_ARCH_MILBEAUT is not set -CONFIG_ARCH_MULTIPLATFORM=y -CONFIG_ARCH_MULTI_V6_V7=y -CONFIG_ARCH_MULTI_V7=y -CONFIG_ARCH_NR_GPIO=0 -CONFIG_ARCH_OPTIONAL_KERNEL_RWX=y -CONFIG_ARCH_OPTIONAL_KERNEL_RWX_DEFAULT=y -# CONFIG_ARCH_RDA is not set -CONFIG_ARCH_SUPPORTS_ATOMIC_RMW=y -CONFIG_ARCH_SUPPORTS_UPROBES=y -CONFIG_ARCH_SUSPEND_POSSIBLE=y -CONFIG_ARCH_USE_BUILTIN_BSWAP=y -CONFIG_ARCH_USE_CMPXCHG_LOCKREF=y -CONFIG_ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT=y -CONFIG_ARCH_WANT_GENERAL_HUGETLB=y -CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y -CONFIG_ARM=y -CONFIG_ARM_APPENDED_DTB=y -CONFIG_ARM_ARCH_TIMER=y -CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y -# CONFIG_ARM_ATAG_DTB_COMPAT is not set -CONFIG_ARM_CPU_SUSPEND=y -# CONFIG_ARM_CPU_TOPOLOGY is not set -# CONFIG_ARM_ERRATA_814220 is not set -# CONFIG_ARM_ERRATA_857271 is not set -# CONFIG_ARM_ERRATA_857272 is not set -CONFIG_ARM_GIC=y -CONFIG_ARM_HAS_SG_CHAIN=y -CONFIG_ARM_L1_CACHE_SHIFT=6 -CONFIG_ARM_L1_CACHE_SHIFT_6=y -# CONFIG_ARM_LPAE is not set -CONFIG_ARM_MEDIATEK_CPUFREQ=y -CONFIG_ARM_PATCH_IDIV=y -CONFIG_ARM_PATCH_PHYS_VIRT=y -# CONFIG_ARM_SMMU is not set -CONFIG_ARM_THUMB=y -CONFIG_ARM_THUMBEE=y -CONFIG_ARM_UNWIND=y -CONFIG_ARM_VIRT_EXT=y -CONFIG_ATAGS=y -CONFIG_AUTO_ZRELADDR=y -# CONFIG_BACKLIGHT_CLASS_DEVICE is not set -CONFIG_BINFMT_FLAT_ARGVP_ENVP_ON_STACK=y -CONFIG_BLK_DEV_LOOP=y -CONFIG_BLK_MQ_PCI=y -CONFIG_BLK_PM=y -CONFIG_BOUNCE=y -# CONFIG_CACHE_L2X0 is not set -CONFIG_CC_CAN_LINK=y -CONFIG_CC_HAS_ASM_INLINE=y -CONFIG_CC_HAS_KASAN_GENERIC=y -CONFIG_CC_HAS_WARN_MAYBE_UNINITIALIZED=y -CONFIG_CLEANCACHE=y -CONFIG_CLKDEV_LOOKUP=y -CONFIG_CLKSRC_MMIO=y -CONFIG_CLONE_BACKWARDS=y -CONFIG_CMDLINE="earlyprintk console=ttyS0,115200 rootfstype=squashfs,jffs2" -CONFIG_CMDLINE_FROM_BOOTLOADER=y -CONFIG_COMMON_CLK=y -CONFIG_COMMON_CLK_MEDIATEK=y -CONFIG_COMMON_CLK_MT2701=y -# CONFIG_COMMON_CLK_MT2701_AUDSYS is not set -CONFIG_COMMON_CLK_MT2701_BDPSYS=y -CONFIG_COMMON_CLK_MT2701_ETHSYS=y -# CONFIG_COMMON_CLK_MT2701_G3DSYS is not set -CONFIG_COMMON_CLK_MT2701_HIFSYS=y -CONFIG_COMMON_CLK_MT2701_IMGSYS=y -CONFIG_COMMON_CLK_MT2701_MMSYS=y -CONFIG_COMMON_CLK_MT2701_VDECSYS=y -# CONFIG_COMMON_CLK_MT7622 is not set -# CONFIG_COMMON_CLK_MT7629 is not set -# CONFIG_COMMON_CLK_MT8135 is not set -# CONFIG_COMMON_CLK_MT8173 is not set -CONFIG_COMMON_CLK_MT8516=y -# CONFIG_COMMON_CLK_MT8516_AUDSYS is not set -CONFIG_COMPAT_32BIT_TIME=y -CONFIG_COREDUMP=y -# CONFIG_CPUFREQ_DT is not set -CONFIG_CPU_32v6K=y -CONFIG_CPU_32v7=y -CONFIG_CPU_ABRT_EV7=y -# CONFIG_CPU_BPREDICT_DISABLE is not set -CONFIG_CPU_CACHE_V7=y -CONFIG_CPU_CACHE_VIPT=y -CONFIG_CPU_COPY_V6=y -CONFIG_CPU_CP15=y -CONFIG_CPU_CP15_MMU=y -CONFIG_CPU_FREQ=y -CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y -CONFIG_CPU_FREQ_GOV_ATTR_SET=y -CONFIG_CPU_FREQ_GOV_COMMON=y -CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y -CONFIG_CPU_FREQ_GOV_ONDEMAND=y -CONFIG_CPU_FREQ_GOV_PERFORMANCE=y -CONFIG_CPU_FREQ_GOV_POWERSAVE=y -# CONFIG_CPU_FREQ_GOV_USERSPACE is not set -CONFIG_CPU_FREQ_STAT=y -CONFIG_CPU_HAS_ASID=y -# 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_PABRT_V7=y -CONFIG_CPU_PM=y -CONFIG_CPU_RMAP=y -CONFIG_CPU_SPECTRE=y -# CONFIG_CPU_THERMAL is not set -CONFIG_CPU_THUMB_CAPABLE=y -CONFIG_CPU_TLB_V7=y -CONFIG_CPU_V7=y -CONFIG_CRC16=y -# CONFIG_CRC32_SARWATE is not set -CONFIG_CRC32_SLICEBY8=y -CONFIG_CROSS_MEMORY_ATTACH=y -CONFIG_CRYPTO_ACOMP2=y -CONFIG_CRYPTO_AEAD=y -CONFIG_CRYPTO_AEAD2=y -CONFIG_CRYPTO_AKCIPHER2=y -CONFIG_CRYPTO_CRC32=y -CONFIG_CRYPTO_CRC32C=y -CONFIG_CRYPTO_CTR=y -CONFIG_CRYPTO_DEFLATE=y -CONFIG_CRYPTO_DEV_MEDIATEK=y -CONFIG_CRYPTO_DRBG=y -CONFIG_CRYPTO_DRBG_HMAC=y -CONFIG_CRYPTO_DRBG_MENU=y -CONFIG_CRYPTO_HASH=y -CONFIG_CRYPTO_HASH2=y -CONFIG_CRYPTO_HASH_INFO=y -CONFIG_CRYPTO_HMAC=y -CONFIG_CRYPTO_HW=y -CONFIG_CRYPTO_JITTERENTROPY=y -CONFIG_CRYPTO_KPP2=y -CONFIG_CRYPTO_LIB_AES=y -CONFIG_CRYPTO_LIB_SHA256=y -CONFIG_CRYPTO_LZO=y -CONFIG_CRYPTO_MANAGER=y -CONFIG_CRYPTO_MANAGER2=y -CONFIG_CRYPTO_NULL=y -CONFIG_CRYPTO_NULL2=y -CONFIG_CRYPTO_RNG=y -CONFIG_CRYPTO_RNG2=y -CONFIG_CRYPTO_RNG_DEFAULT=y -CONFIG_CRYPTO_SEQIV=y -CONFIG_CRYPTO_SHA1=y -CONFIG_CRYPTO_SHA256=y -CONFIG_CRYPTO_SHA512=y -CONFIG_CRYPTO_ZSTD=y -CONFIG_DCACHE_WORD_ACCESS=y -CONFIG_DEBUG_ALIGN_RODATA=y -CONFIG_DEBUG_BUGVERBOSE=y -CONFIG_DEBUG_GPIO=y -CONFIG_DEBUG_INFO=y -CONFIG_DEBUG_LL=y -CONFIG_DEBUG_LL_INCLUDE="debug/8250.S" -CONFIG_DEBUG_MISC=y -CONFIG_DEBUG_MT6589_UART0=y -# CONFIG_DEBUG_MT8127_UART0 is not set -# CONFIG_DEBUG_MT8135_UART3 is not set -CONFIG_DEBUG_PREEMPT=y -CONFIG_DEBUG_UART_8250=y -# CONFIG_DEBUG_UART_8250_FLOW_CONTROL is not set -CONFIG_DEBUG_UART_8250_SHIFT=2 -# CONFIG_DEBUG_UART_8250_WORD is not set -CONFIG_DEBUG_UART_PHYS=0x11004000 -CONFIG_DEBUG_UART_VIRT=0xf1004000 -CONFIG_DEBUG_UNCOMPRESS=y -# CONFIG_DEBUG_USER is not set -CONFIG_DMADEVICES=y -CONFIG_DMA_ENGINE=y -CONFIG_DMA_OF=y -CONFIG_DMA_REMAP=y -CONFIG_DTC=y -CONFIG_EARLY_PRINTK=y -CONFIG_EDAC_ATOMIC_SCRUB=y -CONFIG_EDAC_SUPPORT=y -CONFIG_EINT_MTK=y -CONFIG_ELF_CORE=y -# CONFIG_ENERGY_MODEL is not set -CONFIG_EXT4_FS=y -# CONFIG_F2FS_CHECK_FS is not set -CONFIG_F2FS_FS=y -# CONFIG_F2FS_FS_SECURITY is not set -CONFIG_F2FS_FS_XATTR=y -CONFIG_F2FS_STAT_FS=y -CONFIG_FIXED_PHY=y -CONFIG_FIX_EARLYCON_MEM=y -CONFIG_FREEZER=y -# CONFIG_FSL_QDMA is not set -CONFIG_FS_IOMAP=y -CONFIG_FS_MBCACHE=y -CONFIG_FW_LOADER_PAGED_BUF=y -CONFIG_GENERIC_ALLOCATOR=y -CONFIG_GENERIC_BUG=y -CONFIG_GENERIC_CLOCKEVENTS=y -CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y -CONFIG_GENERIC_CPU_AUTOPROBE=y -CONFIG_GENERIC_EARLY_IOREMAP=y -CONFIG_GENERIC_IDLE_POLL_SETUP=y -CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y -CONFIG_GENERIC_IRQ_MIGRATION=y -CONFIG_GENERIC_IRQ_MULTI_HANDLER=y -CONFIG_GENERIC_IRQ_SHOW=y -CONFIG_GENERIC_IRQ_SHOW_LEVEL=y -CONFIG_GENERIC_MSI_IRQ=y -CONFIG_GENERIC_MSI_IRQ_DOMAIN=y -CONFIG_GENERIC_PCI_IOMAP=y -CONFIG_GENERIC_PHY=y -CONFIG_GENERIC_PINCONF=y -CONFIG_GENERIC_PINCTRL_GROUPS=y -CONFIG_GENERIC_PINMUX_FUNCTIONS=y -CONFIG_GENERIC_SCHED_CLOCK=y -CONFIG_GENERIC_SMP_IDLE_THREAD=y -CONFIG_GENERIC_STRNCPY_FROM_USER=y -CONFIG_GENERIC_STRNLEN_USER=y -CONFIG_GPIOLIB=y -CONFIG_GPIO_SYSFS=y -# CONFIG_HABANA_AI is not set -CONFIG_HANDLE_DOMAIN_IRQ=y -CONFIG_HARDEN_BRANCH_PREDICTOR=y -CONFIG_HARDIRQS_SW_RESEND=y -CONFIG_HAS_DMA=y -CONFIG_HAS_IOMEM=y -CONFIG_HAS_IOPORT_MAP=y -CONFIG_HAVE_ARCH_AUDITSYSCALL=y -CONFIG_HAVE_ARCH_BITREVERSE=y -CONFIG_HAVE_ARCH_JUMP_LABEL=y -CONFIG_HAVE_ARCH_KGDB=y -CONFIG_HAVE_ARCH_PFN_VALID=y -CONFIG_HAVE_ARCH_SECCOMP_FILTER=y -CONFIG_HAVE_ARCH_THREAD_STRUCT_WHITELIST=y -CONFIG_HAVE_ARCH_TRACEHOOK=y -CONFIG_HAVE_ARM_ARCH_TIMER=y -CONFIG_HAVE_ARM_SMCCC=y -CONFIG_HAVE_CLK=y -CONFIG_HAVE_CLK_PREPARE=y -CONFIG_HAVE_CONTEXT_TRACKING=y -CONFIG_HAVE_COPY_THREAD_TLS=y -CONFIG_HAVE_C_RECORDMCOUNT=y -CONFIG_HAVE_DEBUG_KMEMLEAK=y -CONFIG_HAVE_DMA_CONTIGUOUS=y -CONFIG_HAVE_DYNAMIC_FTRACE=y -CONFIG_HAVE_DYNAMIC_FTRACE_WITH_REGS=y -CONFIG_HAVE_EBPF_JIT=y -CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y -CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y -CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y -CONFIG_HAVE_FUNCTION_TRACER=y -CONFIG_HAVE_IDE=y -CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y -CONFIG_HAVE_LD_DEAD_CODE_DATA_ELIMINATION=y -CONFIG_HAVE_MOD_ARCH_SPECIFIC=y -CONFIG_HAVE_NET_DSA=y -CONFIG_HAVE_OPROFILE=y -CONFIG_HAVE_OPTPROBES=y -CONFIG_HAVE_PCI=y -CONFIG_HAVE_PERF_EVENTS=y -CONFIG_HAVE_PERF_REGS=y -CONFIG_HAVE_PERF_USER_STACK_DUMP=y -CONFIG_HAVE_PROC_CPU=y -CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y -CONFIG_HAVE_RSEQ=y -CONFIG_HAVE_SMP=y -CONFIG_HAVE_SYSCALL_TRACEPOINTS=y -CONFIG_HAVE_UID16=y -CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y -CONFIG_HIGHMEM=y -# CONFIG_HIGHPTE is not set -CONFIG_HOTPLUG_CPU=y -CONFIG_HWMON=y -CONFIG_HW_RANDOM=y -CONFIG_HW_RANDOM_MTK=y -CONFIG_HZ_FIXED=0 -CONFIG_I2C=y -CONFIG_I2C_BOARDINFO=y -CONFIG_I2C_CHARDEV=y -CONFIG_I2C_MT65XX=y -# CONFIG_I2C_NVIDIA_GPU is not set -CONFIG_ICPLUS_PHY=y -# CONFIG_IGC is not set -CONFIG_IIO=y -# CONFIG_IIO_BUFFER is not set -# CONFIG_IIO_TRIGGER is not set -CONFIG_INITRAMFS_COMPRESSION="" -CONFIG_INITRAMFS_ROOT_GID=1000 -CONFIG_INITRAMFS_ROOT_UID=1000 -CONFIG_INITRAMFS_SOURCE="/openwrt/trunk/build_dir/target-arm_cortex-a7_musl-1.1.14_eabi/root-mediatek /openwrt/trunk/target/linux/generic/image/initramfs-base-files.txt" -CONFIG_INIT_STACK_NONE=y -# CONFIG_IOMMU_DEBUGFS is not set -# CONFIG_IOMMU_IO_PGTABLE_ARMV7S is not set -# CONFIG_IOMMU_IO_PGTABLE_LPAE is not set -CONFIG_IOMMU_SUPPORT=y -CONFIG_IO_URING=y -CONFIG_IRQCHIP=y -CONFIG_IRQ_DOMAIN=y -CONFIG_IRQ_DOMAIN_HIERARCHY=y -CONFIG_IRQ_FORCED_THREADING=y -CONFIG_IRQ_WORK=y -CONFIG_JBD2=y -CONFIG_KALLSYMS=y -CONFIG_LEDS_MT6323=y -CONFIG_LIBFDT=y -CONFIG_LOCK_DEBUGGING_SUPPORT=y -CONFIG_LOCK_SPIN_ON_OWNER=y -CONFIG_LZO_COMPRESS=y -CONFIG_LZO_DECOMPRESS=y -# CONFIG_MACH_MT2701 is not set -# CONFIG_MACH_MT6589 is not set -# CONFIG_MACH_MT6592 is not set -CONFIG_MACH_MT7623=y -# CONFIG_MACH_MT7629 is not set -# CONFIG_MACH_MT8127 is not set -# CONFIG_MACH_MT8135 is not set -CONFIG_MAGIC_SYSRQ=y -CONFIG_MDIO_BITBANG=y -CONFIG_MDIO_BUS=y -CONFIG_MDIO_DEVICE=y -CONFIG_MDIO_GPIO=y -CONFIG_MEDIATEK_MT6577_AUXADC=y -CONFIG_MEDIATEK_WATCHDOG=y -CONFIG_MEMFD_CREATE=y -CONFIG_MFD_CORE=y -CONFIG_MFD_MT6397=y -# CONFIG_MFD_STPMIC1 is not set -CONFIG_MFD_SYSCON=y -CONFIG_MIGHT_HAVE_CACHE_L2X0=y -CONFIG_MIGRATION=y -# CONFIG_MISC_ALCOR_PCI is not set -CONFIG_MMC=y -CONFIG_MMC_BLOCK=y -CONFIG_MMC_MTK=y -CONFIG_MMC_SDHCI=y -# CONFIG_MMC_SDHCI_PCI is not set -CONFIG_MMC_SDHCI_PLTFM=y -# CONFIG_MMC_TIFM_SD is not set -CONFIG_MODULES_USE_ELF_REL=y -# CONFIG_MT753X_GSW is not set -CONFIG_MTD_BLOCK2MTD=y -CONFIG_MTD_CMDLINE_PARTS=y -CONFIG_MTD_SPI_NOR=y -CONFIG_MTD_SPLIT_FIRMWARE=y -CONFIG_MTD_SPLIT_UIMAGE_FW=y -CONFIG_MTD_UBI=y -CONFIG_MTD_UBI_BEB_LIMIT=20 -CONFIG_MTD_UBI_BLOCK=y -# CONFIG_MTD_UBI_FASTMAP is not set -# CONFIG_MTD_UBI_GLUEBI is not set -CONFIG_MTD_UBI_WL_THRESHOLD=4096 -# CONFIG_MTK_CMDQ is not set -# CONFIG_MTK_CQDMA is not set -CONFIG_MTK_EFUSE=y -# CONFIG_MTK_HSDMA is not set -CONFIG_MTK_INFRACFG=y -# CONFIG_MTK_IOMMU is not set -# CONFIG_MTK_IOMMU_V1 is not set -CONFIG_MTK_PMIC_WRAP=y -CONFIG_MTK_SCPSYS=y -CONFIG_MTK_THERMAL=y -CONFIG_MTK_TIMER=y -# CONFIG_MTK_UART_APDMA is not set -CONFIG_MUTEX_SPIN_ON_OWNER=y -CONFIG_NEED_DMA_MAP_STATE=y -CONFIG_NEON=y -CONFIG_NET_DEVLINK=y -CONFIG_NET_DSA=y -CONFIG_NET_DSA_MT7530=y -CONFIG_NET_DSA_TAG_MTK=y -# CONFIG_NET_DSA_TAG_QCA is not set -CONFIG_NET_FLOW_LIMIT=y -CONFIG_NET_MEDIATEK_SOC=y -CONFIG_NET_SWITCHDEV=y -# CONFIG_NET_VENDOR_AURORA is not set -CONFIG_NET_VENDOR_MEDIATEK=y -# CONFIG_NET_VENDOR_WIZNET is not set -CONFIG_NLS=y -CONFIG_NO_HZ=y -CONFIG_NO_HZ_COMMON=y -CONFIG_NO_HZ_IDLE=y -CONFIG_NR_CPUS=4 -CONFIG_NVMEM=y -# CONFIG_NVMEM_REBOOT_MODE is not set -CONFIG_NVMEM_SYSFS=y -CONFIG_OF=y -CONFIG_OF_ADDRESS=y -CONFIG_OF_EARLY_FLATTREE=y -CONFIG_OF_FLATTREE=y -CONFIG_OF_GPIO=y -CONFIG_OF_IRQ=y -CONFIG_OF_KOBJ=y -CONFIG_OF_MDIO=y -CONFIG_OF_NET=y -CONFIG_OLD_SIGACTION=y -CONFIG_OLD_SIGSUSPEND3=y -CONFIG_PADATA=y -CONFIG_PAGE_OFFSET=0xC0000000 -CONFIG_PCI=y -CONFIG_PCIEAER=y -CONFIG_PCIEPORTBUS=y -CONFIG_PCIE_MEDIATEK=y -CONFIG_PCIE_PME=y -CONFIG_PCI_DOMAINS=y -CONFIG_PCI_DOMAINS_GENERIC=y -# CONFIG_PCI_MESON is not set -CONFIG_PCI_MSI=y -CONFIG_PCI_MSI_IRQ_DOMAIN=y -# CONFIG_PCI_V3_SEMI is not set -CONFIG_PERF_USE_VMALLOC=y -CONFIG_PGTABLE_LEVELS=2 -CONFIG_PHYLIB=y -CONFIG_PHYLINK=y -CONFIG_PHY_MTK_TPHY=y -# CONFIG_PHY_MTK_UFS is not set -# CONFIG_PHY_MTK_XSPHY is not set -CONFIG_PINCTRL=y -CONFIG_PINCTRL_MT2701=y -CONFIG_PINCTRL_MT6397=y -CONFIG_PINCTRL_MT7623=y -CONFIG_PINCTRL_MTK=y -CONFIG_PINCTRL_MTK_MOORE=y -CONFIG_PM=y -CONFIG_PM_CLK=y -# CONFIG_PM_DEBUG is not set -CONFIG_PM_GENERIC_DOMAINS=y -CONFIG_PM_GENERIC_DOMAINS_OF=y -CONFIG_PM_GENERIC_DOMAINS_SLEEP=y -CONFIG_PM_OPP=y -CONFIG_PM_SLEEP=y -CONFIG_PM_SLEEP_SMP=y -CONFIG_POWER_RESET=y -CONFIG_POWER_SUPPLY=y -CONFIG_POWER_SUPPLY_HWMON=y -CONFIG_PREEMPT=y -CONFIG_PREEMPTION=y -CONFIG_PREEMPT_COUNT=y -# CONFIG_PREEMPT_NONE is not set -CONFIG_PREEMPT_RCU=y -CONFIG_PRINTK_TIME=y -CONFIG_PWM=y -CONFIG_PWM_MEDIATEK=y -# CONFIG_PWM_MTK_DISP is not set -CONFIG_PWM_SYSFS=y -# CONFIG_QCOM_SPMI_ADC5 is not set -CONFIG_RAS=y -CONFIG_RATIONAL=y -CONFIG_RCU_CPU_STALL_TIMEOUT=21 -# CONFIG_RCU_EXPERT is not set -CONFIG_RCU_NEED_SEGCBLIST=y -CONFIG_RCU_STALL_COMMON=y -CONFIG_REFCOUNT_FULL=y -CONFIG_REGMAP=y -CONFIG_REGMAP_I2C=y -CONFIG_REGMAP_MMIO=y -CONFIG_REGMAP_SPI=y -CONFIG_REGULATOR=y -CONFIG_REGULATOR_FIXED_VOLTAGE=y -CONFIG_REGULATOR_GPIO=y -CONFIG_REGULATOR_MT6323=y -# CONFIG_REGULATOR_MT6380 is not set -# CONFIG_REGULATOR_MT6397 is not set -# CONFIG_REGULATOR_QCOM_SPMI is not set -CONFIG_RESET_CONTROLLER=y -CONFIG_RFS_ACCEL=y -CONFIG_RPS=y -CONFIG_RTC_CLASS=y -# CONFIG_RTC_DRV_MT6397 is not set -# CONFIG_RTC_DRV_MT7622 is not set -CONFIG_RTC_I2C_AND_SPI=y -CONFIG_RWSEM_SPIN_ON_OWNER=y -# CONFIG_SENSORS_OCC_P8_I2C is not set -# CONFIG_SERIAL_8250_DMA is not set -CONFIG_SERIAL_8250_FSL=y -CONFIG_SERIAL_8250_MT6577=y -CONFIG_SERIAL_8250_NR_UARTS=4 -CONFIG_SERIAL_8250_RUNTIME_UARTS=4 -CONFIG_SERIAL_MCTRL_GPIO=y -CONFIG_SGL_ALLOC=y -CONFIG_SMP=y -# CONFIG_SMP_ON_UP is not set -CONFIG_SPARSE_IRQ=y -CONFIG_SPI=y -CONFIG_SPI_BITBANG=y -CONFIG_SPI_MASTER=y -CONFIG_SPI_MEM=y -CONFIG_SPI_MT65XX=y -CONFIG_SPMI=y -CONFIG_SRCU=y -# CONFIG_STRIP_ASM_SYMS is not set -CONFIG_SUSPEND=y -CONFIG_SUSPEND_FREEZER=y -CONFIG_SWCONFIG=y -CONFIG_SWPHY=y -CONFIG_SWP_EMULATE=y -CONFIG_SYS_SUPPORTS_APM_EMULATION=y -CONFIG_TASKS_RCU=y -CONFIG_THERMAL=y -CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y -CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=0 -CONFIG_THERMAL_GOV_STEP_WISE=y -CONFIG_THERMAL_OF=y -# CONFIG_THUMB2_KERNEL is not set -CONFIG_TICK_CPU_ACCOUNTING=y -CONFIG_TIMER_OF=y -CONFIG_TIMER_PROBE=y -# CONFIG_TI_CPSW_PHY_SEL is not set -CONFIG_TREE_SRCU=y -# CONFIG_TRUSTED_FOUNDATIONS is not set -CONFIG_UBIFS_FS=y -# CONFIG_UBIFS_FS_ADVANCED_COMPR is not set -CONFIG_UBIFS_FS_LZO=y -CONFIG_UBIFS_FS_ZLIB=y -CONFIG_UBIFS_FS_ZSTD=y -CONFIG_UEVENT_HELPER_PATH="" -CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h" -CONFIG_UNINLINE_SPIN_UNLOCK=y -CONFIG_UNWINDER_ARM=y -# CONFIG_UNWINDER_FRAME_POINTER is not set -CONFIG_USB=y -CONFIG_USB_COMMON=y -# CONFIG_USB_EHCI_HCD is not set -CONFIG_USB_SUPPORT=y -CONFIG_USB_XHCI_HCD=y -CONFIG_USB_XHCI_MTK=y -CONFIG_USB_XHCI_PLATFORM=y -CONFIG_USE_OF=y -CONFIG_VFP=y -CONFIG_VFPv3=y -CONFIG_VM_EVENT_COUNTERS=y -CONFIG_WATCHDOG_CORE=y -CONFIG_XPS=y -CONFIG_XXHASH=y -CONFIG_XZ_DEC_ARM=y -CONFIG_XZ_DEC_BCJ=y -CONFIG_ZBOOT_ROM_BSS=0 -CONFIG_ZBOOT_ROM_TEXT=0 -CONFIG_ZLIB_DEFLATE=y -CONFIG_ZLIB_INFLATE=y -CONFIG_ZSTD_COMPRESS=y -CONFIG_ZSTD_DECOMPRESS=y diff --git a/root/target/linux/mediatek/patches-4.14/0229-fix-memory-size-for-bpi-r2.patch b/root/target/linux/mediatek/patches-4.14/0229-fix-memory-size-for-bpi-r2.patch deleted file mode 100644 index 517b5be6..00000000 --- a/root/target/linux/mediatek/patches-4.14/0229-fix-memory-size-for-bpi-r2.patch +++ /dev/null @@ -1,23 +0,0 @@ ---- a/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts 2018-12-26 16:53:06.778501203 +0100 -+++ b/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts 2018-12-26 16:55:46.280213376 +0100 -@@ -22,6 +22,7 @@ - }; - - memory { -- reg = <0 0x80000000 0 0x20000000>; -+ device_type = "memory"; -+ reg = <0 0x80000000 0 0x80000000>; - }; - -@@ -115,11 +116,6 @@ - }; - }; - -- memory@80000000 { -- device_type = "memory"; -- reg = <0 0x80000000 0 0x40000000>; -- }; -- - mt7530: switch@0 { - compatible = "mediatek,mt7530"; - }; diff --git a/root/target/linux/mediatek/patches-4.14/0229-update-gpio-leds-for-bpi-r2.patch b/root/target/linux/mediatek/patches-4.14/0229-update-gpio-leds-for-bpi-r2.patch deleted file mode 100644 index ef9b4a79..00000000 --- a/root/target/linux/mediatek/patches-4.14/0229-update-gpio-leds-for-bpi-r2.patch +++ /dev/null @@ -1,27 +0,0 @@ -Index: linux-4.14.51/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts -=================================================================== ---- linux-4.14.51.orig/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts -+++ linux-4.14.51/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts -@@ -87,19 +87,19 @@ - - blue { - label = "bpi-r2:pio:blue"; -- gpios = <&pio 241 GPIO_ACTIVE_HIGH>; -+ gpios = <&pio 240 GPIO_ACTIVE_LOW>; - default-state = "off"; - }; - - green { - label = "bpi-r2:pio:green"; -- gpios = <&pio 240 GPIO_ACTIVE_HIGH>; -+ gpios = <&pio 241 GPIO_ACTIVE_LOW>; - default-state = "off"; - }; - - red { - label = "bpi-r2:pio:red"; -- gpios = <&pio 239 GPIO_ACTIVE_HIGH>; -+ gpios = <&pio 239 GPIO_ACTIVE_LOW>; - default-state = "off"; - }; - }; diff --git a/root/target/linux/mediatek/patches-4.14/0230-update-pcie-for-bpi-r2.patch b/root/target/linux/mediatek/patches-4.14/0230-update-pcie-for-bpi-r2.patch deleted file mode 100644 index f202cae7..00000000 --- a/root/target/linux/mediatek/patches-4.14/0230-update-pcie-for-bpi-r2.patch +++ /dev/null @@ -1,48 +0,0 @@ -Index: linux-4.14.51/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts -=================================================================== ---- linux-4.14.51.orig/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts -+++ linux-4.14.51/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts -@@ -266,6 +266,28 @@ - vqmmc-supply = <&mt6323_vio18_reg>; - }; - -+&pcie { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pcie_default>; -+ status = "okay"; -+ -+ pcie@0,0 { -+ status = "okay"; -+ }; -+ -+ pcie@1,0 { -+ status = "okay"; -+ }; -+}; -+ -+&pcie0_phy { -+ status = "okay"; -+}; -+ -+&pcie1_phy { -+ status = "okay"; -+}; -+ - &pio { - cir_pins_a:cir@0 { - pins_cir { -@@ -433,6 +455,14 @@ - }; - }; - -+ pcie_default: pcie_pin_default { -+ pins_cmd_dat { -+ pinmux = , -+ ; -+ bias-disable; -+ }; -+ }; -+ - pwm_pins_a: pwm@0 { - pins_pwm { - pinmux = , diff --git a/root/target/linux/mediatek/patches-4.14/0231-enable-trgmii-on-bpi-r2.patch b/root/target/linux/mediatek/patches-4.14/0231-enable-trgmii-on-bpi-r2.patch deleted file mode 100644 index 7c30af0a..00000000 --- a/root/target/linux/mediatek/patches-4.14/0231-enable-trgmii-on-bpi-r2.patch +++ /dev/null @@ -1,22 +0,0 @@ -Index: linux-4.14.51/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts -=================================================================== ---- linux-4.14.51.orig/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts -+++ linux-4.14.51/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts -@@ -141,7 +141,7 @@ - gmac1: mac@1 { - compatible = "mediatek,eth-mac"; - reg = <1>; -- phy-mode = "rgmii"; -+ phy-mode = "trgmii"; - - fixed-link { - speed = <1000>; -@@ -206,7 +206,7 @@ - reg = <5>; - label = "cpu"; - ethernet = <&gmac1>; -- phy-mode = "rgmii"; -+ phy-mode = "trgmii"; - - fixed-link { - speed = <1000>; diff --git a/root/target/linux/mediatek/patches-4.14/0232-merge-mt6625l-wifi-driver.patch b/root/target/linux/mediatek/patches-4.14/0232-merge-mt6625l-wifi-driver.patch deleted file mode 100644 index 25dca71f..00000000 --- a/root/target/linux/mediatek/patches-4.14/0232-merge-mt6625l-wifi-driver.patch +++ /dev/null @@ -1,217327 +0,0 @@ -From e6b369a5ade19206db433b46d0102ae000b87e99 Mon Sep 17 00:00:00 2001 -From: frank -Date: Wed, 20 Dec 2017 22:36:53 +0100 -Subject: [PATCH] merge mt6625l wifi driver - ---- - arch/arm/boot/dts/mt7623.dtsi | 48 + - arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts | 263 + - drivers/misc/Kconfig | 1 + - drivers/misc/Makefile | 2 + - drivers/misc/mediatek/Kconfig | 11 + - drivers/misc/mediatek/Makefile | 19 + - drivers/misc/mediatek/btif/Kconfig | 4 + - drivers/misc/mediatek/btif/Makefile | 33 + - drivers/misc/mediatek/btif/common/Makefile | 31 + - .../misc/mediatek/btif/common/btif_dma_plat.c | 1436 ++ - drivers/misc/mediatek/btif/common/btif_plat.c | 1396 ++ - .../misc/mediatek/btif/common/inc/mtk_btif.h | 370 + - .../mediatek/btif/common/inc/mtk_btif_exp.h | 280 + - drivers/misc/mediatek/btif/common/mtk_btif.c | 3472 +++++ - .../misc/mediatek/btif/common/mtk_btif_exp.c | 786 ++ - .../btif/common/plat_inc/btif_dma_priv.h | 164 + - .../btif/common/plat_inc/btif_dma_pub.h | 197 + - .../mediatek/btif/common/plat_inc/btif_priv.h | 105 + - .../mediatek/btif/common/plat_inc/btif_pub.h | 237 + - .../btif/common/plat_inc/plat_common.h | 307 + - drivers/misc/mediatek/connectivity/Kconfig | 298 + - drivers/misc/mediatek/connectivity/Makefile | 41 + - .../mediatek/connectivity/common/Makefile | 23 + - .../common/common_detect/Makefile | 47 + - .../common/common_detect/drv_init/Makefile | 22 + - .../common_detect/drv_init/ant_drv_init.c | 38 + - .../drv_init/bluetooth_drv_init.c | 35 + - .../common_detect/drv_init/common_drv_init.c | 103 + - .../common_detect/drv_init/conn_drv_init.c | 80 + - .../common_detect/drv_init/fm_drv_init.c | 33 + - .../common_detect/drv_init/gps_drv_init.c | 35 + - .../common_detect/drv_init/inc/ant_drv_init.h | 20 + - .../drv_init/inc/bluetooth_drv_init.h | 20 + - .../drv_init/inc/common_drv_init.h | 31 + - .../drv_init/inc/conn_drv_init.h | 18 + - .../common_detect/drv_init/inc/fm_drv_init.h | 20 + - .../common_detect/drv_init/inc/gps_drv_init.h | 19 + - .../drv_init/inc/wlan_drv_init.h | 30 + - .../common_detect/drv_init/wlan_drv_init.c | 74 + - .../common/common_detect/mtk_wcn_stub_alps.c | 605 + - .../common/common_detect/sdio_detect.c | 269 + - .../common/common_detect/sdio_detect.h | 43 + - .../common/common_detect/wmt_detect.c | 380 + - .../common/common_detect/wmt_detect.h | 114 + - .../common/common_detect/wmt_detect_pwr.c | 232 + - .../common/common_detect/wmt_detect_pwr.h | 29 + - .../common/common_detect/wmt_gpio.c | 371 + - .../common/common_detect/wmt_gpio.h | 103 + - .../common/common_detect/wmt_stp_exp.c | 480 + - .../common/common_detect/wmt_stp_exp.h | 610 + - .../connectivity/common/conn_soc/Makefile | 65 + - .../common/conn_soc/core/Makefile | 22 + - .../common/conn_soc/core/btm_core.c | 1376 ++ - .../common/conn_soc/core/dbg_core.c | 13 + - .../common/conn_soc/core/include/btm_core.h | 133 + - .../common/conn_soc/core/include/dbg_core.h | 69 + - .../common/conn_soc/core/include/psm_core.h | 251 + - .../common/conn_soc/core/include/stp_core.h | 629 + - .../common/conn_soc/core/include/stp_wmt.h | 89 + - .../common/conn_soc/core/include/wmt_conf.h | 74 + - .../common/conn_soc/core/include/wmt_core.h | 428 + - .../common/conn_soc/core/include/wmt_ctrl.h | 120 + - .../common/conn_soc/core/include/wmt_func.h | 140 + - .../common/conn_soc/core/include/wmt_ic.h | 122 + - .../common/conn_soc/core/include/wmt_lib.h | 300 + - .../common/conn_soc/core/psm_core.c | 1889 +++ - .../common/conn_soc/core/stp_core.c | 3358 +++++ - .../common/conn_soc/core/wmt_conf.c | 529 + - .../common/conn_soc/core/wmt_core.c | 2521 ++++ - .../common/conn_soc/core/wmt_ctrl.c | 1019 ++ - .../common/conn_soc/core/wmt_func.c | 713 + - .../common/conn_soc/core/wmt_ic_soc.c | 2452 ++++ - .../common/conn_soc/core/wmt_lib.c | 1938 +++ - .../common/conn_soc/include/stp_exp.h | 252 + - .../common/conn_soc/include/wmt.h | 19 + - .../common/conn_soc/include/wmt_exp.h | 329 + - .../common/conn_soc/include/wmt_plat.h | 295 + - .../common/conn_soc/linux/Makefile | 6 + - .../conn_soc/linux/include/bgw_desense.h | 74 + - .../common/conn_soc/linux/include/osal.h | 348 + - .../conn_soc/linux/include/osal_typedef.h | 90 + - .../common/conn_soc/linux/include/wmt_idc.h | 97 + - .../common/conn_soc/linux/pri/Makefile | 21 + - .../conn_soc/linux/pri/include/stp_btif.h | 31 + - .../conn_soc/linux/pri/include/stp_dbg.h | 316 + - .../conn_soc/linux/pri/include/wmt_dev.h | 71 + - .../common/conn_soc/linux/pri/stp_btif.c | 279 + - .../common/conn_soc/linux/pri/stp_dbg.c | 2060 +++ - .../common/conn_soc/linux/pri/stp_exp.c | 279 + - .../common/conn_soc/linux/pri/wmt_dev.c | 2566 ++++ - .../common/conn_soc/linux/pri/wmt_exp.c | 610 + - .../common/conn_soc/linux/pub/Makefile | 27 + - .../common/conn_soc/linux/pub/bgw_desense.c | 153 + - .../common/conn_soc/linux/pub/osal.c | 1210 ++ - .../common/conn_soc/linux/pub/stp_chrdev_bt.c | 899 ++ - .../conn_soc/linux/pub/wmt_chrdev_wifi.c | 668 + - .../common/conn_soc/linux/pub/wmt_idc.c | 307 + - .../common/conn_soc/mt7623/Makefile | 25 + - .../mt7623/include/mtk_wcn_consys_hw.h | 287 + - .../conn_soc/mt7623/mtk_wcn_consys_hw.c | 737 ++ - .../common/conn_soc/mt7623/wmt_plat_alps.c | 1071 ++ - .../misc/mediatek/connectivity/wlan/Makefile | 8 + - .../mediatek/connectivity/wlan/gen2/Makefile | 237 + - .../connectivity/wlan/gen2/common/debug.c | 165 + - .../connectivity/wlan/gen2/common/dump.c | 345 + - .../connectivity/wlan/gen2/common/wlan_bow.c | 3442 +++++ - .../connectivity/wlan/gen2/common/wlan_lib.c | 6240 +++++++++ - .../connectivity/wlan/gen2/common/wlan_oid.c | 11050 ++++++++++++++++ - .../connectivity/wlan/gen2/common/wlan_p2p.c | 1654 +++ - .../wlan/gen2/include/CFG_Wifi_File.h | 238 + - .../connectivity/wlan/gen2/include/config.h | 1628 +++ - .../connectivity/wlan/gen2/include/debug.h | 466 + - .../connectivity/wlan/gen2/include/link.h | 368 + - .../wlan/gen2/include/mgmt/aa_fsm.h | 188 + - .../wlan/gen2/include/mgmt/ais_fsm.h | 573 + - .../wlan/gen2/include/mgmt/assoc.h | 112 + - .../wlan/gen2/include/mgmt/auth.h | 125 + - .../wlan/gen2/include/mgmt/bow_fsm.h | 184 + - .../connectivity/wlan/gen2/include/mgmt/bss.h | 265 + - .../connectivity/wlan/gen2/include/mgmt/cnm.h | 258 + - .../wlan/gen2/include/mgmt/cnm_mem.h | 1164 ++ - .../wlan/gen2/include/mgmt/cnm_scan.h | 169 + - .../wlan/gen2/include/mgmt/cnm_timer.h | 235 + - .../wlan/gen2/include/mgmt/hem_mbox.h | 446 + - .../wlan/gen2/include/mgmt/hs20.h | 148 + - .../connectivity/wlan/gen2/include/mgmt/mib.h | 153 + - .../wlan/gen2/include/mgmt/p2p_assoc.h | 55 + - .../wlan/gen2/include/mgmt/p2p_bss.h | 56 + - .../wlan/gen2/include/mgmt/p2p_fsm.h | 2190 +++ - .../wlan/gen2/include/mgmt/p2p_func.h | 155 + - .../wlan/gen2/include/mgmt/p2p_ie.h | 156 + - .../wlan/gen2/include/mgmt/p2p_rlm.h | 74 + - .../wlan/gen2/include/mgmt/p2p_rlm_obss.h | 64 + - .../wlan/gen2/include/mgmt/p2p_scan.h | 81 + - .../wlan/gen2/include/mgmt/p2p_state.h | 43 + - .../wlan/gen2/include/mgmt/privacy.h | 230 + - .../wlan/gen2/include/mgmt/rate.h | 93 + - .../connectivity/wlan/gen2/include/mgmt/rlm.h | 396 + - .../wlan/gen2/include/mgmt/rlm_domain.h | 557 + - .../wlan/gen2/include/mgmt/rlm_obss.h | 150 + - .../wlan/gen2/include/mgmt/rlm_protection.h | 122 + - .../wlan/gen2/include/mgmt/rlm_txpwr_init.h | 1213 ++ - .../wlan/gen2/include/mgmt/roaming_fsm.h | 171 + - .../connectivity/wlan/gen2/include/mgmt/rsn.h | 271 + - .../wlan/gen2/include/mgmt/scan.h | 988 ++ - .../wlan/gen2/include/mgmt/sec_fsm.h | 233 + - .../wlan/gen2/include/mgmt/stats.h | 368 + - .../wlan/gen2/include/mgmt/swcr.h | 187 + - .../wlan/gen2/include/mgmt/tdls.h | 262 + - .../wlan/gen2/include/mgmt/wapi.h | 104 + - .../wlan/gen2/include/mgmt/wlan_typedef.h | 87 + - .../connectivity/wlan/gen2/include/mgmt/wnm.h | 95 + - .../wlan/gen2/include/nic/adapter.h | 1506 +++ - .../connectivity/wlan/gen2/include/nic/bow.h | 322 + - .../wlan/gen2/include/nic/cmd_buf.h | 150 + - .../connectivity/wlan/gen2/include/nic/hal.h | 618 + - .../wlan/gen2/include/nic/hif_rx.h | 220 + - .../wlan/gen2/include/nic/hif_tx.h | 214 + - .../connectivity/wlan/gen2/include/nic/mac.h | 2323 ++++ - .../wlan/gen2/include/nic/mtreg.h | 272 + - .../connectivity/wlan/gen2/include/nic/nic.h | 498 + - .../wlan/gen2/include/nic/nic_rx.h | 420 + - .../wlan/gen2/include/nic/nic_tx.h | 642 + - .../connectivity/wlan/gen2/include/nic/p2p.h | 192 + - .../wlan/gen2/include/nic/p2p_cmd_buf.h | 83 + - .../wlan/gen2/include/nic/p2p_mac.h | 207 + - .../wlan/gen2/include/nic/p2p_nic.h | 62 + - .../wlan/gen2/include/nic/p2p_nic_cmd_event.h | 70 + - .../wlan/gen2/include/nic/que_mgt.h | 971 ++ - .../wlan/gen2/include/nic/wlan_def.h | 1010 ++ - .../wlan/gen2/include/nic_cmd_event.h | 2290 ++++ - .../wlan/gen2/include/nic_init_cmd_event.h | 177 + - .../wlan/gen2/include/p2p_precomp.h | 201 + - .../wlan/gen2/include/p2p_typedef.h | 165 + - .../connectivity/wlan/gen2/include/precomp.h | 388 + - .../connectivity/wlan/gen2/include/pwr_mgt.h | 141 + - .../connectivity/wlan/gen2/include/queue.h | 195 + - .../connectivity/wlan/gen2/include/rftest.h | 294 + - .../wlan/gen2/include/tdls_extr.h | 427 + - .../connectivity/wlan/gen2/include/typedef.h | 244 + - .../connectivity/wlan/gen2/include/wlan_bow.h | 352 + - .../connectivity/wlan/gen2/include/wlan_lib.h | 1001 ++ - .../connectivity/wlan/gen2/include/wlan_oid.h | 1715 +++ - .../connectivity/wlan/gen2/include/wlan_p2p.h | 307 + - .../connectivity/wlan/gen2/mgmt/aaa_fsm.c | 1303 ++ - .../connectivity/wlan/gen2/mgmt/ais_fsm.c | 5039 +++++++ - .../connectivity/wlan/gen2/mgmt/assoc.c | 1932 +++ - .../connectivity/wlan/gen2/mgmt/auth.c | 1211 ++ - .../connectivity/wlan/gen2/mgmt/bss.c | 2521 ++++ - .../connectivity/wlan/gen2/mgmt/cnm.c | 738 ++ - .../connectivity/wlan/gen2/mgmt/cnm_mem.c | 1236 ++ - .../connectivity/wlan/gen2/mgmt/cnm_timer.c | 482 + - .../connectivity/wlan/gen2/mgmt/hem_mbox.c | 816 ++ - .../connectivity/wlan/gen2/mgmt/hs20.c | 498 + - .../connectivity/wlan/gen2/mgmt/mib.c | 111 + - .../connectivity/wlan/gen2/mgmt/p2p_assoc.c | 87 + - .../connectivity/wlan/gen2/mgmt/p2p_bss.c | 58 + - .../connectivity/wlan/gen2/mgmt/p2p_fsm.c | 3139 +++++ - .../connectivity/wlan/gen2/mgmt/p2p_func.c | 3796 ++++++ - .../connectivity/wlan/gen2/mgmt/p2p_ie.c | 612 + - .../connectivity/wlan/gen2/mgmt/p2p_rlm.c | 905 ++ - .../wlan/gen2/mgmt/p2p_rlm_obss.c | 313 + - .../connectivity/wlan/gen2/mgmt/p2p_scan.c | 756 ++ - .../connectivity/wlan/gen2/mgmt/p2p_state.c | 466 + - .../connectivity/wlan/gen2/mgmt/privacy.c | 915 ++ - .../connectivity/wlan/gen2/mgmt/rate.c | 497 + - .../connectivity/wlan/gen2/mgmt/rlm.c | 1858 +++ - .../connectivity/wlan/gen2/mgmt/rlm_domain.c | 1791 +++ - .../connectivity/wlan/gen2/mgmt/rlm_obss.c | 436 + - .../wlan/gen2/mgmt/rlm_protection.c | 105 + - .../connectivity/wlan/gen2/mgmt/roaming_fsm.c | 539 + - .../connectivity/wlan/gen2/mgmt/rsn.c | 2533 ++++ - .../connectivity/wlan/gen2/mgmt/saa_fsm.c | 1788 +++ - .../connectivity/wlan/gen2/mgmt/scan.c | 3103 +++++ - .../connectivity/wlan/gen2/mgmt/scan_fsm.c | 2136 +++ - .../connectivity/wlan/gen2/mgmt/sec_fsm.c | 1112 ++ - .../connectivity/wlan/gen2/mgmt/stats.c | 1342 ++ - .../connectivity/wlan/gen2/mgmt/swcr.c | 1170 ++ - .../connectivity/wlan/gen2/mgmt/tdls.c | 5199 ++++++++ - .../connectivity/wlan/gen2/mgmt/tdls_com.c | 741 ++ - .../connectivity/wlan/gen2/mgmt/wapi.c | 491 + - .../connectivity/wlan/gen2/mgmt/wnm.c | 301 + - .../connectivity/wlan/gen2/nic/cmd_buf.c | 254 + - .../mediatek/connectivity/wlan/gen2/nic/nic.c | 4062 ++++++ - .../wlan/gen2/nic/nic_cmd_event.c | 1636 +++ - .../connectivity/wlan/gen2/nic/nic_pwr_mgt.c | 669 + - .../connectivity/wlan/gen2/nic/nic_rx.c | 3782 ++++++ - .../connectivity/wlan/gen2/nic/nic_tx.c | 2350 ++++ - .../connectivity/wlan/gen2/nic/p2p_nic.c | 192 + - .../connectivity/wlan/gen2/nic/que_mgt.c | 5038 +++++++ - .../connectivity/wlan/gen2/os/linux/gl_bow.c | 1177 ++ - .../wlan/gen2/os/linux/gl_cfg80211.c | 3110 +++++ - .../connectivity/wlan/gen2/os/linux/gl_init.c | 3501 +++++ - .../connectivity/wlan/gen2/os/linux/gl_kal.c | 4801 +++++++ - .../connectivity/wlan/gen2/os/linux/gl_p2p.c | 4671 +++++++ - .../wlan/gen2/os/linux/gl_p2p_cfg80211.c | 1935 +++ - .../wlan/gen2/os/linux/gl_p2p_init.c | 433 + - .../wlan/gen2/os/linux/gl_p2p_kal.c | 1314 ++ - .../connectivity/wlan/gen2/os/linux/gl_proc.c | 1020 ++ - .../connectivity/wlan/gen2/os/linux/gl_rst.c | 228 + - .../wlan/gen2/os/linux/gl_vendor.c | 1220 ++ - .../connectivity/wlan/gen2/os/linux/gl_wext.c | 4158 ++++++ - .../wlan/gen2/os/linux/gl_wext_priv.c | 3142 +++++ - .../wlan/gen2/os/linux/hif/ahb/ahb.c | 1643 +++ - .../wlan/gen2/os/linux/hif/ahb/arm.c | 31 + - .../wlan/gen2/os/linux/hif/ahb/include/hif.h | 340 + - .../gen2/os/linux/hif/ahb/include/hif_gdma.h | 154 + - .../gen2/os/linux/hif/ahb/include/hif_pdma.h | 141 + - .../os/linux/hif/ahb/include/mtk_porting.h | 91 + - .../gen2/os/linux/hif/ahb/mt8127/ahb_pdma.c | 480 + - .../wlan/gen2/os/linux/include/gl_cfg80211.h | 341 + - .../wlan/gen2/os/linux/include/gl_kal.h | 1565 +++ - .../wlan/gen2/os/linux/include/gl_os.h | 1270 ++ - .../wlan/gen2/os/linux/include/gl_p2p_ioctl.h | 743 ++ - .../wlan/gen2/os/linux/include/gl_p2p_kal.h | 243 + - .../wlan/gen2/os/linux/include/gl_p2p_os.h | 242 + - .../wlan/gen2/os/linux/include/gl_rst.h | 133 + - .../wlan/gen2/os/linux/include/gl_sec.h | 21 + - .../wlan/gen2/os/linux/include/gl_typedef.h | 298 + - .../wlan/gen2/os/linux/include/gl_vendor.h | 619 + - .../wlan/gen2/os/linux/include/gl_wext.h | 357 + - .../wlan/gen2/os/linux/include/gl_wext_priv.h | 402 + - .../wlan/gen2/os/linux/platform.c | 542 + - .../connectivity/wlan/gen2/os/version.h | 190 + - drivers/misc/mediatek/include/mt-plat/aee.h | 284 + - .../misc/mediatek/include/mt-plat/mrdump.h | 204 + - .../mt-plat/mt7622/include/mach/mtk_thermal.h | 295 + - .../mt8127/include/mach/mt_freqhopping.h | 159 + - .../mt8127/include/mach/mt_spm_mtcmos.h | 37 + - .../mt8127/include/mach/mtk_boot_share_page.h | 40 + - .../mt-plat/mt8127/include/mach/mtk_thermal.h | 301 + - .../misc/mediatek/include/mt-plat/mt_sched.h | 34 + - .../misc/mediatek/include/mt-plat/mtk_io.h | 23 + - .../misc/mediatek/include/mt-plat/mtk_lpae.h | 62 + - .../include/mt-plat/mtk_mdm_monitor.h | 42 + - .../include/mt-plat/mtk_platform_debug.h | 28 + - .../include/mt-plat/mtk_ram_console.h | 162 + - .../misc/mediatek/include/mt-plat/mtk_rtc.h | 85 + - .../include/mt-plat/mtk_thermal_ext_control.h | 69 + - .../include/mt-plat/mtk_thermal_monitor.h | 102 + - .../include/mt-plat/mtk_thermal_platform.h | 114 + - .../include/mt-plat/mtk_thermal_trace.h | 47 + - .../include/mt-plat/mtk_thermal_typedefs.h | 241 + - .../include/mt-plat/mtk_wcn_cmb_stub.h | 185 + - .../misc/mediatek/include/mt-plat/rt-regmap.h | 291 + - .../mediatek/include/mt-plat/sync_write.h | 88 + - .../misc/mediatek/include/mt-plat/wakelock.h | 67 + - drivers/soc/mediatek/mtk-pmic-wrap.c | 16 + - drivers/watchdog/mtk_wdt.c | 363 +- - include/linux/wakelock.h | 67 + - include/net/cfg80211.h | 2 +- - include/net/genetlink.h | 45 + - include/soc/mediatek/pmic_wrap.h | 19 + - include/uapi/linux/genetlink.h | 1 + - 294 files changed, 214777 insertions(+), 12 deletions(-) - create mode 100644 drivers/misc/mediatek/Kconfig - create mode 100644 drivers/misc/mediatek/Makefile - create mode 100644 drivers/misc/mediatek/btif/Kconfig - create mode 100644 drivers/misc/mediatek/btif/Makefile - create mode 100644 drivers/misc/mediatek/btif/common/Makefile - create mode 100644 drivers/misc/mediatek/btif/common/btif_dma_plat.c - create mode 100644 drivers/misc/mediatek/btif/common/btif_plat.c - create mode 100644 drivers/misc/mediatek/btif/common/inc/mtk_btif.h - create mode 100644 drivers/misc/mediatek/btif/common/inc/mtk_btif_exp.h - create mode 100644 drivers/misc/mediatek/btif/common/mtk_btif.c - create mode 100644 drivers/misc/mediatek/btif/common/mtk_btif_exp.c - create mode 100644 drivers/misc/mediatek/btif/common/plat_inc/btif_dma_priv.h - create mode 100644 drivers/misc/mediatek/btif/common/plat_inc/btif_dma_pub.h - create mode 100644 drivers/misc/mediatek/btif/common/plat_inc/btif_priv.h - create mode 100644 drivers/misc/mediatek/btif/common/plat_inc/btif_pub.h - create mode 100644 drivers/misc/mediatek/btif/common/plat_inc/plat_common.h - create mode 100644 drivers/misc/mediatek/connectivity/Kconfig - create mode 100644 drivers/misc/mediatek/connectivity/Makefile - create mode 100644 drivers/misc/mediatek/connectivity/common/Makefile - create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/Makefile - create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/drv_init/Makefile - create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/drv_init/ant_drv_init.c - create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/drv_init/bluetooth_drv_init.c - create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/drv_init/common_drv_init.c - create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/drv_init/conn_drv_init.c - create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/drv_init/fm_drv_init.c - create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/drv_init/gps_drv_init.c - create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/ant_drv_init.h - create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/bluetooth_drv_init.h - create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/common_drv_init.h - create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/conn_drv_init.h - create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/fm_drv_init.h - create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/gps_drv_init.h - create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/wlan_drv_init.h - create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/drv_init/wlan_drv_init.c - create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/mtk_wcn_stub_alps.c - create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/sdio_detect.c - create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/sdio_detect.h - create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/wmt_detect.c - create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/wmt_detect.h - create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/wmt_detect_pwr.c - create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/wmt_detect_pwr.h - create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/wmt_gpio.c - create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/wmt_gpio.h - create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/wmt_stp_exp.c - create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/wmt_stp_exp.h - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/Makefile - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/core/Makefile - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/core/btm_core.c - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/core/dbg_core.c - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/core/include/btm_core.h - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/core/include/dbg_core.h - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/core/include/psm_core.h - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/core/include/stp_core.h - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/core/include/stp_wmt.h - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_conf.h - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_core.h - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_ctrl.h - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_func.h - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_ic.h - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_lib.h - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/core/psm_core.c - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/core/stp_core.c - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_conf.c - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_core.c - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_ctrl.c - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_func.c - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_ic_soc.c - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_lib.c - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/include/stp_exp.h - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/include/wmt.h - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/include/wmt_exp.h - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/include/wmt_plat.h - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/linux/Makefile - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/linux/include/bgw_desense.h - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/linux/include/osal.h - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/linux/include/osal_typedef.h - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/linux/include/wmt_idc.h - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/Makefile - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/include/stp_btif.h - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/include/stp_dbg.h - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/include/wmt_dev.h - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/stp_btif.c - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/stp_dbg.c - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/stp_exp.c - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/wmt_dev.c - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/wmt_exp.c - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/Makefile - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/bgw_desense.c - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/osal.c - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/stp_chrdev_bt.c - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/wmt_chrdev_wifi.c - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/wmt_idc.c - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/mt7623/Makefile - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/mt7623/include/mtk_wcn_consys_hw.h - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/mt7623/mtk_wcn_consys_hw.c - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/mt7623/wmt_plat_alps.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/Makefile - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/Makefile - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/common/debug.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/common/dump.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/common/wlan_bow.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/common/wlan_lib.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/common/wlan_oid.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/common/wlan_p2p.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/CFG_Wifi_File.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/config.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/debug.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/link.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/aa_fsm.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/ais_fsm.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/assoc.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/auth.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/bow_fsm.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/bss.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/cnm.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/cnm_mem.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/cnm_scan.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/cnm_timer.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/hem_mbox.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/hs20.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/mib.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_assoc.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_bss.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_fsm.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_func.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_ie.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_rlm.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_rlm_obss.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_scan.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_state.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/privacy.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rate.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rlm.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rlm_domain.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rlm_obss.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rlm_protection.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rlm_txpwr_init.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/roaming_fsm.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rsn.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/scan.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/sec_fsm.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/stats.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/swcr.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/tdls.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/wapi.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/wlan_typedef.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/wnm.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/adapter.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/bow.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/cmd_buf.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/hal.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/hif_rx.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/hif_tx.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/mac.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/mtreg.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/nic.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/nic_rx.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/nic_tx.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/p2p.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/p2p_cmd_buf.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/p2p_mac.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/p2p_nic.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/p2p_nic_cmd_event.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/que_mgt.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/wlan_def.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/nic_cmd_event.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/nic_init_cmd_event.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/p2p_precomp.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/p2p_typedef.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/precomp.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/pwr_mgt.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/queue.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/rftest.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/tdls_extr.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/typedef.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/wlan_bow.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/wlan_lib.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/wlan_oid.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/wlan_p2p.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/aaa_fsm.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/ais_fsm.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/assoc.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/auth.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/bss.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/cnm.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/cnm_mem.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/cnm_timer.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/hem_mbox.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/hs20.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/mib.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_assoc.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_bss.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_fsm.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_func.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_ie.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_rlm.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_rlm_obss.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_scan.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_state.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/privacy.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rate.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rlm.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rlm_domain.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rlm_obss.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rlm_protection.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/roaming_fsm.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rsn.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/saa_fsm.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/scan.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/scan_fsm.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/sec_fsm.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/stats.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/swcr.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/tdls.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/tdls_com.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/wapi.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/wnm.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/nic/cmd_buf.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic_cmd_event.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic_pwr_mgt.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic_rx.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic_tx.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/nic/p2p_nic.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/nic/que_mgt.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_bow.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_cfg80211.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_init.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_kal.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_p2p.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_p2p_cfg80211.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_p2p_init.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_p2p_kal.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_proc.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_rst.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_vendor.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_wext.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_wext_priv.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/ahb.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/arm.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/include/hif.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/include/hif_gdma.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/include/hif_pdma.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/include/mtk_porting.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/mt8127/ahb_pdma.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_cfg80211.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_kal.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_os.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_p2p_ioctl.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_p2p_kal.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_p2p_os.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_rst.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_sec.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_typedef.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_vendor.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_wext.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_wext_priv.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/platform.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/version.h - create mode 100644 drivers/misc/mediatek/include/mt-plat/aee.h - create mode 100644 drivers/misc/mediatek/include/mt-plat/mrdump.h - create mode 100644 drivers/misc/mediatek/include/mt-plat/mt7622/include/mach/mtk_thermal.h - create mode 100644 drivers/misc/mediatek/include/mt-plat/mt8127/include/mach/mt_freqhopping.h - create mode 100644 drivers/misc/mediatek/include/mt-plat/mt8127/include/mach/mt_spm_mtcmos.h - create mode 100644 drivers/misc/mediatek/include/mt-plat/mt8127/include/mach/mtk_boot_share_page.h - create mode 100644 drivers/misc/mediatek/include/mt-plat/mt8127/include/mach/mtk_thermal.h - create mode 100644 drivers/misc/mediatek/include/mt-plat/mt_sched.h - create mode 100644 drivers/misc/mediatek/include/mt-plat/mtk_io.h - create mode 100644 drivers/misc/mediatek/include/mt-plat/mtk_lpae.h - create mode 100644 drivers/misc/mediatek/include/mt-plat/mtk_mdm_monitor.h - create mode 100644 drivers/misc/mediatek/include/mt-plat/mtk_platform_debug.h - create mode 100644 drivers/misc/mediatek/include/mt-plat/mtk_ram_console.h - create mode 100644 drivers/misc/mediatek/include/mt-plat/mtk_rtc.h - create mode 100644 drivers/misc/mediatek/include/mt-plat/mtk_thermal_ext_control.h - create mode 100644 drivers/misc/mediatek/include/mt-plat/mtk_thermal_monitor.h - create mode 100644 drivers/misc/mediatek/include/mt-plat/mtk_thermal_platform.h - create mode 100644 drivers/misc/mediatek/include/mt-plat/mtk_thermal_trace.h - create mode 100644 drivers/misc/mediatek/include/mt-plat/mtk_thermal_typedefs.h - create mode 100644 drivers/misc/mediatek/include/mt-plat/mtk_wcn_cmb_stub.h - create mode 100644 drivers/misc/mediatek/include/mt-plat/rt-regmap.h - create mode 100644 drivers/misc/mediatek/include/mt-plat/sync_write.h - create mode 100644 drivers/misc/mediatek/include/mt-plat/wakelock.h - create mode 100644 include/linux/wakelock.h - create mode 100644 include/soc/mediatek/pmic_wrap.h - -diff --git a/arch/arm/boot/dts/mt7623.dtsi b/arch/arm/boot/dts/mt7623.dtsi -index 5361d48a2240..bdfd22bbf7fd 100644 ---- a/arch/arm/boot/dts/mt7623.dtsi -+++ b/arch/arm/boot/dts/mt7623.dtsi -@@ -263,6 +263,8 @@ - compatible = "mediatek,mt7623-wdt", - "mediatek,mt6589-wdt"; - reg = <0 0x10007000 0 0x100>; -+ interrupts = ; -+ #reset-cells = <1>; - }; - - timer: timer@10008000 { -@@ -486,6 +488,29 @@ - nvmem-cell-names = "calibration-data"; - }; - -+ btif_tx: btif_tx@11000780 { -+ compatible = "mediatek,btif_tx"; -+ reg = <0 0x11000780 0 0x80>; -+ interrupts = ; -+ status = "okay"; -+ }; -+ -+ btif_rx: btif_rx@11000800 { -+ compatible = "mediatek,btif_rx"; -+ reg = <0 0x11000800 0 0x80>; -+ interrupts = ; -+ status = "okay"; -+ }; -+ -+ btif: btif@1100c000 { -+ compatible = "mediatek,btif"; -+ reg = <0 0x1100c000 0 0x1000>; -+ interrupts = ; -+ clocks = <&pericfg CLK_PERI_BTIF>, <&pericfg CLK_PERI_AP_DMA>; -+ clock-names = "btifc", "apdmac"; -+ status = "okay"; -+ }; -+ - nandc: nfi@1100d000 { - compatible = "mediatek,mt7623-nfc", - "mediatek,mt2701-nfc"; -@@ -660,6 +685,29 @@ - status = "disabled"; - }; - -+ consys: consys@18070000 { -+ compatible = "mediatek,mt7623-consys"; -+ reg = <0 0x18070000 0 0x0200>, /*CONN_MCU_CONFIG_BASE */ -+ <0 0x10001000 0 0x1600>; /*TOPCKGEN_BASE */ -+ clocks = <&infracfg CLK_INFRA_CONNMCU>; -+ clock-names = "consysbus"; -+ power-domains = <&scpsys MT2701_POWER_DOMAIN_CONN>; -+ interrupts = , /* BGF_EINT */ -+ ; /* WDT_EINT */ -+ resets = <&watchdog MT2701_TOPRGU_CONN_MCU_RST>; -+ reset-names = "connsys"; -+ status="disabled"; -+ }; -+ -+ wifi:wifi@180f0000 { -+ compatible = "mediatek,mt7623-wifi", -+ "mediatek,wifi"; -+ reg = <0 0x180f0000 0 0x005c>; -+ interrupts = ; -+ clocks = <&pericfg CLK_PERI_AP_DMA>; -+ clock-names = "wifi-dma"; -+ }; -+ - hifsys: syscon@1a000000 { - compatible = "mediatek,mt7623-hifsys", - "mediatek,mt2701-hifsys", -diff --git a/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts b/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts -index 9ea67ea28a47..0f4c356ebaec 100644 ---- a/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts -+++ b/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts -@@ -57,6 +57,18 @@ - }; - }; - -+ reserved-memory { -+ #address-cells = <2>; -+ #size-cells = <2>; -+ ranges; -+ consys-reserve-memory { -+ compatible = "mediatek,consys-reserve-memory"; -+ no-map; -+ size = <0 0x100000>; -+ alignment = <0 0x100000>; -+ }; -+ }; -+ - leds { - compatible = "gpio-leds"; - pinctrl-names = "default"; -@@ -439,6 +451,24 @@ - ; - }; - }; -+ -+ consys_pins_default: consys_pins_default { -+ adie { -+ pinmux = , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ ; -+ bias-disable; -+ }; -+ }; - }; - - &pwm { -@@ -472,9 +502,239 @@ - default-state = "off"; - }; - }; -+ -+ mt6323regulator: mt6323regulator{ -+ compatible = "mediatek,mt6323-regulator"; -+ -+ mt6323_vproc_reg: buck_vproc{ -+ regulator-name = "vproc"; -+ regulator-min-microvolt = < 700000>; -+ regulator-max-microvolt = <1350000>; -+ regulator-ramp-delay = <12500>; -+ regulator-always-on; -+ regulator-boot-on; -+ }; -+ -+ mt6323_vsys_reg: buck_vsys{ -+ regulator-name = "vsys"; -+ regulator-min-microvolt = <1400000>; -+ regulator-max-microvolt = <2987500>; -+ regulator-ramp-delay = <25000>; -+ regulator-always-on; -+ regulator-boot-on; -+ }; -+ -+ mt6323_vpa_reg: buck_vpa{ -+ regulator-name = "vpa"; -+ regulator-min-microvolt = < 500000>; -+ regulator-max-microvolt = <3650000>; -+ }; -+ -+ mt6323_vtcxo_reg: ldo_vtcxo{ -+ regulator-name = "vtcxo"; -+ regulator-min-microvolt = <2800000>; -+ regulator-max-microvolt = <2800000>; -+ regulator-enable-ramp-delay = <90>; -+ regulator-always-on; -+ regulator-boot-on; -+ }; -+ -+ mt6323_vcn28_reg: ldo_vcn28{ -+ regulator-name = "vcn28"; -+ regulator-min-microvolt = <2800000>; -+ regulator-max-microvolt = <2800000>; -+ regulator-enable-ramp-delay = <185>; -+ }; -+ -+ mt6323_vcn33_bt_reg: ldo_vcn33_bt{ -+ regulator-name = "vcn33_bt"; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3600000>; -+ regulator-enable-ramp-delay = <185>; -+ }; -+ -+ mt6323_vcn33_wifi_reg: ldo_vcn33_wifi{ -+ regulator-name = "vcn33_wifi"; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3600000>; -+ regulator-enable-ramp-delay = <185>; -+ }; -+ -+ mt6323_va_reg: ldo_va{ -+ regulator-name = "va"; -+ regulator-min-microvolt = <2800000>; -+ regulator-max-microvolt = <2800000>; -+ regulator-enable-ramp-delay = <216>; -+ regulator-always-on; -+ regulator-boot-on; -+ }; -+ -+ mt6323_vcama_reg: ldo_vcama{ -+ regulator-name = "vcama"; -+ regulator-min-microvolt = <1500000>; -+ regulator-max-microvolt = <2800000>; -+ regulator-enable-ramp-delay = <216>; -+ }; -+ -+ mt6323_vio28_reg: ldo_vio28{ -+ regulator-name = "vio28"; -+ regulator-min-microvolt = <2800000>; -+ regulator-max-microvolt = <2800000>; -+ regulator-enable-ramp-delay = <216>; -+ regulator-always-on; -+ regulator-boot-on; -+ }; -+ -+ mt6323_vusb_reg: ldo_vusb{ -+ regulator-name = "vusb"; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ regulator-enable-ramp-delay = <216>; -+ regulator-boot-on; -+ }; -+ -+ mt6323_vmc_reg: ldo_vmc{ -+ regulator-name = "vmc"; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <3300000>; -+ regulator-enable-ramp-delay = <36>; -+ regulator-boot-on; -+ }; -+ -+ mt6323_vmch_reg: ldo_vmch{ -+ regulator-name = "vmch"; -+ regulator-min-microvolt = <3000000>; -+ regulator-max-microvolt = <3300000>; -+ regulator-enable-ramp-delay = <36>; -+ regulator-boot-on; -+ }; -+ -+ mt6323_vemc3v3_reg: ldo_vemc3v3{ -+ regulator-name = "vemc3v3"; -+ regulator-min-microvolt = <3000000>; -+ regulator-max-microvolt = <3300000>; -+ regulator-enable-ramp-delay = <36>; -+ regulator-boot-on; -+ }; -+ -+ mt6323_vgp1_reg: ldo_vgp1{ -+ regulator-name = "vgp1"; -+ regulator-min-microvolt = <1200000>; -+ regulator-max-microvolt = <3300000>; -+ regulator-enable-ramp-delay = <216>; -+ }; -+ -+ mt6323_vgp2_reg: ldo_vgp2{ -+ regulator-name = "vgp2"; -+ regulator-min-microvolt = <1200000>; -+ regulator-max-microvolt = <3000000>; -+ regulator-enable-ramp-delay = <216>; -+ }; -+ -+ mt6323_vgp3_reg: ldo_vgp3{ -+ regulator-name = "vgp3"; -+ regulator-min-microvolt = <1200000>; -+ regulator-max-microvolt = <1800000>; -+ regulator-enable-ramp-delay = <216>; -+ }; -+ -+ mt6323_vcn18_reg: ldo_vcn18{ -+ regulator-name = "vcn18"; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ regulator-enable-ramp-delay = <216>; -+ }; -+ -+ mt6323_vsim1_reg: ldo_vsim1{ -+ regulator-name = "vsim1"; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <3000000>; -+ regulator-enable-ramp-delay = <216>; -+ }; -+ -+ mt6323_vsim2_reg: ldo_vsim2{ -+ regulator-name = "vsim2"; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <3000000>; -+ regulator-enable-ramp-delay = <216>; -+ }; -+ -+ mt6323_vrtc_reg: ldo_vrtc{ -+ regulator-name = "vrtc"; -+ regulator-min-microvolt = <2800000>; -+ regulator-max-microvolt = <2800000>; -+ regulator-always-on; -+ regulator-boot-on; -+ }; -+ -+ mt6323_vcamaf_reg: ldo_vcamaf{ -+ regulator-name = "vcamaf"; -+ regulator-min-microvolt = <1200000>; -+ regulator-max-microvolt = <3300000>; -+ regulator-enable-ramp-delay = <216>; -+ }; -+ -+ mt6323_vibr_reg: ldo_vibr{ -+ regulator-name = "vibr"; -+ regulator-min-microvolt = <1200000>; -+ regulator-max-microvolt = <3300000>; -+ regulator-enable-ramp-delay = <36>; -+ }; -+ -+ mt6323_vrf18_reg: ldo_vrf18{ -+ regulator-name = "vrf18"; -+ regulator-min-microvolt = <1825000>; -+ regulator-max-microvolt = <1825000>; -+ regulator-enable-ramp-delay = <187>; -+ }; -+ -+ mt6323_vm_reg: ldo_vm{ -+ regulator-name = "vm"; -+ regulator-min-microvolt = <1200000>; -+ regulator-max-microvolt = <1800000>; -+ regulator-enable-ramp-delay = <216>; -+ regulator-always-on; -+ regulator-boot-on; -+ }; -+ -+ mt6323_vio18_reg: ldo_vio18{ -+ regulator-name = "vio18"; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ regulator-enable-ramp-delay = <216>; -+ regulator-always-on; -+ regulator-boot-on; -+ }; -+ -+ mt6323_vcamd_reg: ldo_vcamd{ -+ regulator-name = "vcamd"; -+ regulator-min-microvolt = <1200000>; -+ regulator-max-microvolt = <1800000>; -+ regulator-enable-ramp-delay = <216>; -+ }; -+ -+ mt6323_vcamio_reg: ldo_vcamio{ -+ regulator-name = "vcamio"; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ regulator-enable-ramp-delay = <216>; -+ }; -+ }; -+ - }; - }; - -+&consys { -+ mediatek,pwrap-regmap = <&pwrap>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&consys_pins_default>; -+ vcn18-supply = <&mt6323_vcn18_reg>; -+ vcn28-supply = <&mt6323_vcn28_reg>; -+ vcn33_bt-supply = <&mt6323_vcn33_bt_reg>; -+ vcn33_wifi-supply = <&mt6323_vcn33_wifi_reg>; -+ status = "okay"; -+}; -+ - &spi0 { - pinctrl-names = "default"; - pinctrl-0 = <&spi0_pins_a>; -@@ -515,3 +775,6 @@ - status = "okay"; - }; - -+&watchdog { -+ status = "okay"; -+}; -diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig -index 8136dc7e863d..11ef310bd1c7 100644 ---- a/drivers/misc/Kconfig -+++ b/drivers/misc/Kconfig -@@ -518,4 +518,5 @@ source "drivers/misc/mic/Kconfig" - source "drivers/misc/genwqe/Kconfig" - source "drivers/misc/echo/Kconfig" - source "drivers/misc/cxl/Kconfig" -+source "drivers/misc/mediatek/Kconfig" - endmenu -diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile -index ad0e64fdba34..c25aa08d17f5 100644 ---- a/drivers/misc/Makefile -+++ b/drivers/misc/Makefile -@@ -74,3 +74,5 @@ OBJCOPYFLAGS_lkdtm_rodata_objcopy.o := \ - targets += lkdtm_rodata.o lkdtm_rodata_objcopy.o - $(obj)/lkdtm_rodata_objcopy.o: $(obj)/lkdtm_rodata.o FORCE - $(call if_changed,objcopy) -+ -+obj-$(CONFIG_MTK_COMBO) += mediatek/ -diff --git a/drivers/misc/mediatek/Kconfig b/drivers/misc/mediatek/Kconfig -new file mode 100644 -index 000000000000..4829a6598c7a ---- /dev/null -+++ b/drivers/misc/mediatek/Kconfig -@@ -0,0 +1,11 @@ -+menu "Mediatek Peripherals " -+ -+config MTK_PLATFORM -+ string "MTK platform name" -+source "drivers/misc/mediatek/btif/Kconfig" -+ -+menu "Modem & Connectivity related configs" -+source "drivers/misc/mediatek/connectivity/Kconfig" -+endmenu -+ -+endmenu # CONN -diff --git a/drivers/misc/mediatek/Makefile b/drivers/misc/mediatek/Makefile -new file mode 100644 -index 000000000000..5e7f06db38f2 ---- /dev/null -+++ b/drivers/misc/mediatek/Makefile -@@ -0,0 +1,19 @@ -+# -+# Copyright (C) 2015 MediaTek Inc. -+# -+# 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. -+# -+# This program is distributed in the hope that it will be useful, -+# but WITHOUT ANY WARRANTY; without even the implied warranty of -+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+# GNU General Public License for more details. -+# -+ -+#$(call all-subdir-src-or-makefile) -+subdir-ccflags-y += -Werror -+subdir-ccflags-y += -I$(srctree)/drivers/misc/mediatek/include/mt-plat/ -+ -+obj-$(CONFIG_MTK_COMBO) += connectivity/ -+obj-$(CONFIG_MTK_BTIF) += btif/ -diff --git a/drivers/misc/mediatek/btif/Kconfig b/drivers/misc/mediatek/btif/Kconfig -new file mode 100644 -index 000000000000..908898bd95c3 ---- /dev/null -+++ b/drivers/misc/mediatek/btif/Kconfig -@@ -0,0 +1,4 @@ -+config MTK_BTIF -+ tristate"MediaTek BTIF Driver" -+ help -+ MTK connectivity BTIF driver for A/D die -diff --git a/drivers/misc/mediatek/btif/Makefile b/drivers/misc/mediatek/btif/Makefile -new file mode 100644 -index 000000000000..2be3ab66f426 ---- /dev/null -+++ b/drivers/misc/mediatek/btif/Makefile -@@ -0,0 +1,33 @@ -+# -+# Copyright (C) 2015 MediaTek Inc. -+# -+# 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. -+# -+# This program is distributed in the hope that it will be useful, -+# but WITHOUT ANY WARRANTY; without even the implied warranty of -+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+# GNU General Public License for more details. -+# -+ -+# BTIF driver for AD DIE -+# If KERNELRELEASE is defined, we've been invoked from the -+# kernel build system and can use its language. -+ifneq ($(KERNELRELEASE),) -+ #subdir-ccflags-y can be used in 2.6.34 in the future -+ MTK_PLATFORM := $(subst ",,$(CONFIG_MTK_PLATFORM)) -+ subdir-ccflags-y += -I$(srctree)/drivers/misc/mediatek/include/mt-plat/$(MTK_PLATFORM)/include -+ subdir-ccflags-y += -I$(srctree)/arch/arm/mach-$(MTK_PLATFORM)/include/mach -+ subdir-ccflags-y += -I$(srctree)/drivers/misc/mediatek/include/mt-plat -+ -+ obj-y += common/ -+ -+# Otherwise we were called directly from the command -+# line; invoke the kernel build system. -+else -+ KERNELDIR ?= /lib/modules/$(shell uname -r)/build -+ PWD := $(shell pwd) -+default: -+ $(MAKE) -C $(KERNELDIR) M=$(PWD) modules -+endif -diff --git a/drivers/misc/mediatek/btif/common/Makefile b/drivers/misc/mediatek/btif/common/Makefile -new file mode 100644 -index 000000000000..61e9d4ea9e89 ---- /dev/null -+++ b/drivers/misc/mediatek/btif/common/Makefile -@@ -0,0 +1,31 @@ -+# -+# Copyright (C) 2015 MediaTek Inc. -+# -+# 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. -+# -+# This program is distributed in the hope that it will be useful, -+# but WITHOUT ANY WARRANTY; without even the implied warranty of -+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+# GNU General Public License for more details. -+# -+ -+# BTIF driver for AD DIE -+# If KERNELRELEASE is defined, we've been invoked from the -+# kernel build system and can use its language. -+ifneq ($(KERNELRELEASE),) -+ ccflags-y += -I$(src)/inc -+ ccflags-y += -I$(src)/plat_inc -+ -+ obj-y += btif.o -+ btif-y := mtk_btif.o mtk_btif_exp.o btif_dma_plat.o btif_plat.o -+ -+# Otherwise we were called directly from the command -+# line; invoke the kernel build system. -+else -+ KERNELDIR ?= /lib/modules/$(shell uname -r)/build -+ PWD := $(shell pwd) -+default: -+ $(MAKE) -C $(KERNELDIR) M=$(PWD) modules -+endif -diff --git a/drivers/misc/mediatek/btif/common/btif_dma_plat.c b/drivers/misc/mediatek/btif/common/btif_dma_plat.c -new file mode 100644 -index 000000000000..58be46927953 ---- /dev/null -+++ b/drivers/misc/mediatek/btif/common/btif_dma_plat.c -@@ -0,0 +1,1436 @@ -+/* -+ * Copyright (C) 2015 MediaTek Inc. -+ * -+ * 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. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#include -+#include -+ -+#ifdef DFT_TAG -+#undef DFT_TAG -+#endif -+#define DFT_TAG "MTK-BTIF-DMA" -+ -+#include "btif_dma_priv.h" -+ -+#define DMA_USER_ID "btif_driver" -+ -+/************************************Global variable***********************************/ -+ -+static MTK_BTIF_DMA_VFIFO mtk_tx_dma_vfifo = { -+ .vfifo = { -+ .p_vir_addr = NULL, -+ .phy_addr = 0, -+ .vfifo_size = TX_DMA_VFF_SIZE, -+ .thre = DMA_TX_THRE(TX_DMA_VFF_SIZE), -+ }, -+ .wpt = 0, -+ .last_wpt_wrap = 0, -+ .rpt = 0, -+ .last_rpt_wrap = 0, -+}; -+ -+static MTK_BTIF_IRQ_STR mtk_btif_tx_dma_irq = { -+ .name = "mtk btif tx dma irq", -+ .is_irq_sup = true, -+ .reg_flag = false, -+#ifdef CONFIG_OF -+ .irq_flags = IRQF_TRIGGER_NONE, -+#else -+ .irq_id = MT_DMA_BTIF_TX_IRQ_ID, -+ .sens_type = IRQ_SENS_LVL, -+ .lvl_type = IRQ_LVL_LOW, -+#endif -+ .p_irq_handler = NULL, -+}; -+ -+static MTK_BTIF_DMA_VFIFO mtk_rx_dma_vfifo = { -+ .vfifo = { -+ .p_vir_addr = NULL, -+ .phy_addr = 0, -+ .vfifo_size = RX_DMA_VFF_SIZE, -+ .thre = DMA_RX_THRE(RX_DMA_VFF_SIZE), -+ }, -+ -+ .wpt = 0, -+ .last_wpt_wrap = 0, -+ .rpt = 0, -+ .last_rpt_wrap = 0, -+}; -+ -+static MTK_BTIF_IRQ_STR mtk_btif_rx_dma_irq = { -+ .name = "mtk btif rx dma irq", -+ .is_irq_sup = true, -+ .reg_flag = false, -+#ifdef CONFIG_OF -+ .irq_flags = IRQF_TRIGGER_NONE, -+#else -+ .irq_id = MT_DMA_BTIF_RX_IRQ_ID, -+ .sens_type = IRQ_SENS_LVL, -+ .lvl_type = IRQ_LVL_LOW, -+#endif -+ .p_irq_handler = NULL, -+}; -+ -+static MTK_DMA_INFO_STR mtk_btif_tx_dma = { -+#ifndef CONFIG_OF -+ .base = AP_DMA_BASE + BTIF_TX_DMA_OFFSET, -+#endif -+ .dir = DMA_DIR_TX, -+ .p_irq = &mtk_btif_tx_dma_irq, -+ .p_vfifo = &(mtk_tx_dma_vfifo.vfifo), -+}; -+ -+static MTK_DMA_INFO_STR mtk_btif_rx_dma = { -+#ifndef CONFIG_OF -+ .base = AP_DMA_BASE + BTIF_RX_DMA_OFFSET, -+#endif -+ .dir = DMA_DIR_RX, -+ .p_irq = &mtk_btif_rx_dma_irq, -+ .p_vfifo = &(mtk_rx_dma_vfifo.vfifo), -+}; -+ -+static spinlock_t g_clk_cg_spinlock; /*dma clock's spinlock */ -+ -+/************************************Function declearation***********************************/ -+static int _is_tx_dma_in_flush(P_MTK_DMA_INFO_STR p_dma_info); -+static int _tx_dma_flush(P_MTK_DMA_INFO_STR p_dma_info); -+static int btif_rx_dma_ctrl(P_MTK_DMA_INFO_STR p_dma_info, -+ ENUM_DMA_CTRL ctrl_id); -+static int btif_tx_dma_ctrl(P_MTK_DMA_INFO_STR p_dma_info, -+ ENUM_DMA_CTRL ctrl_id); -+static int btif_rx_dma_ier_ctrl(P_MTK_DMA_INFO_STR p_dma_info, bool en); -+static int btif_tx_dma_ier_ctrl(P_MTK_DMA_INFO_STR p_dma_info, bool en); -+static int hal_rx_dma_dump_reg(P_MTK_DMA_INFO_STR p_dma_info, -+ ENUM_BTIF_REG_ID flag); -+static int hal_tx_dma_dump_reg(P_MTK_DMA_INFO_STR p_dma_info, -+ ENUM_BTIF_REG_ID flag); -+static int is_tx_dma_irq_finish_done(P_MTK_DMA_INFO_STR p_dma_info); -+static int _btif_dma_dump_dbg_reg(void); -+static void hal_btif_tx_dma_vff_set_for_4g(void); -+static void hal_btif_rx_dma_vff_set_for_4g(void); -+ -+/***************************************************************************** -+* FUNCTION -+* hal_tx_dma_ier_ctrl -+* DESCRIPTION -+* BTIF Tx DMA's interrupt enable/disable -+* PARAMETERS -+* p_dma_info [IN] pointer to BTIF dma channel's information -+* enable [IN] control if tx interrupt enabled or not -+* dma_dir [IN] DMA's direction -+* RETURNS -+* 0 means success, negative means fail -+*****************************************************************************/ -+static int hal_btif_dma_ier_ctrl(P_MTK_DMA_INFO_STR p_dma_info, bool en); -+ -+/***************************************************************************** -+* FUNCTION -+* hal_dma_receive_data -+* DESCRIPTION -+* receive data from btif module in DMA polling mode -+* PARAMETERS -+* p_dma_info [IN] pointer to BTIF dma channel's information -+* p_buf [IN/OUT] pointer to rx data buffer -+* max_len [IN] max length of rx buffer -+* RETURNS -+* positive means data is available, 0 means no data available -+*****************************************************************************/ -+#ifndef MTK_BTIF_MARK_UNUSED_API -+static int hal_dma_receive_data(P_MTK_DMA_INFO_STR p_dma_info, -+ unsigned char *p_buf, -+ const unsigned int max_len); -+ -+/************************************Function***********************************/ -+#endif -+ -+#ifdef CONFIG_OF -+static void hal_dma_set_default_setting(ENUM_DMA_DIR dma_dir) -+{ -+ struct device_node *node = NULL; -+ unsigned int irq_info[3] = {0, 0, 0}; -+ unsigned int phy_base; -+ -+ if (dma_dir == DMA_DIR_RX) { -+ node = of_find_compatible_node(NULL, NULL, "mediatek,btif_rx"); -+ if (node) { -+ mtk_btif_rx_dma.p_irq->irq_id = irq_of_parse_and_map(node, 0); -+ /*fixme, be compitable arch 64bits*/ -+ mtk_btif_rx_dma.base = (unsigned long)of_iomap(node, 0); -+ BTIF_INFO_FUNC("get rx_dma irq(%d),register base(0x%lx)\n", -+ mtk_btif_rx_dma.p_irq->irq_id, mtk_btif_rx_dma.base); -+ } else { -+ BTIF_ERR_FUNC("get rx_dma device node fail\n"); -+ } -+ /* get the interrupt line behaviour */ -+ if (of_property_read_u32_array(node, "interrupts", irq_info, ARRAY_SIZE(irq_info))) { -+ BTIF_ERR_FUNC("get interrupt flag from DTS fail\n"); -+ } else { -+ mtk_btif_rx_dma.p_irq->irq_flags = irq_info[2]; -+ BTIF_INFO_FUNC("get interrupt flag(0x%x)\n", -+ mtk_btif_rx_dma.p_irq->irq_flags); -+ } -+ if (of_property_read_u32_index(node, "reg", 1, &phy_base)) { -+ BTIF_ERR_FUNC("get register phy base from DTS fail,dma_dir(%d)\n", -+ dma_dir); -+ } else { -+ BTIF_INFO_FUNC("get register phy base dma_dir(%d)(0x%x)\n", -+ dma_dir, (unsigned int)phy_base); -+ } -+ } else if (dma_dir == DMA_DIR_TX) { -+ node = of_find_compatible_node(NULL, NULL, "mediatek,btif_tx"); -+ if (node) { -+ mtk_btif_tx_dma.p_irq->irq_id = irq_of_parse_and_map(node, 0); -+ /*fixme, be compitable arch 64bits*/ -+ mtk_btif_tx_dma.base = (unsigned long)of_iomap(node, 0); -+ BTIF_INFO_FUNC("get tx_dma irq(%d),register base(0x%lx)\n", -+ mtk_btif_tx_dma.p_irq->irq_id, mtk_btif_tx_dma.base); -+ } else { -+ BTIF_ERR_FUNC("get tx_dma device node fail\n"); -+ } -+ /* get the interrupt line behaviour */ -+ if (of_property_read_u32_array(node, "interrupts", irq_info, ARRAY_SIZE(irq_info))) { -+ BTIF_ERR_FUNC("get interrupt flag from DTS fail\n"); -+ } else { -+ mtk_btif_tx_dma.p_irq->irq_flags = irq_info[2]; -+ BTIF_INFO_FUNC("get interrupt flag(0x%x)\n", -+ mtk_btif_tx_dma.p_irq->irq_flags); -+ } -+ -+ if (of_property_read_u32_index(node, "reg", 1, &phy_base)) { -+ BTIF_ERR_FUNC("get register phy base from DTS fail,dma_dir(%d)\n", -+ dma_dir); -+ } else { -+ BTIF_INFO_FUNC("get register phy base dma_dir(%d)(0x%x)\n", -+ dma_dir, (unsigned int)phy_base); -+ } -+ } -+ -+} -+#endif -+ -+/***************************************************************************** -+* FUNCTION -+* hal_tx_dma_info_get -+* DESCRIPTION -+* get btif tx dma channel's information -+* PARAMETERS -+* dma_dir [IN] DMA's direction -+* RETURNS -+* pointer to btif dma's information structure -+*****************************************************************************/ -+P_MTK_DMA_INFO_STR hal_btif_dma_info_get(ENUM_DMA_DIR dma_dir) -+{ -+ P_MTK_DMA_INFO_STR p_dma_info = NULL; -+ -+ BTIF_TRC_FUNC(); -+#ifdef CONFIG_OF -+ hal_dma_set_default_setting(dma_dir); -+#endif -+ if (dma_dir == DMA_DIR_RX) -+ /*Rx DMA*/ -+ p_dma_info = &mtk_btif_rx_dma; -+ else if (dma_dir == DMA_DIR_TX) -+ /*Tx DMA*/ -+ p_dma_info = &mtk_btif_tx_dma; -+ else -+ /*print error log*/ -+ BTIF_ERR_FUNC("invalid DMA dir (%d)\n", dma_dir); -+ spin_lock_init(&g_clk_cg_spinlock); -+ BTIF_TRC_FUNC(); -+ return p_dma_info; -+} -+ -+/***************************************************************************** -+* FUNCTION -+* hal_btif_clk_ctrl -+* DESCRIPTION -+* control clock output enable/disable of DMA module -+* PARAMETERS -+* p_dma_info [IN] pointer to BTIF dma channel's information -+* RETURNS -+* 0 means success, negative means fail -+*****************************************************************************/ -+int hal_btif_dma_clk_ctrl(P_MTK_DMA_INFO_STR p_dma_info, ENUM_CLOCK_CTRL flag) -+{ -+/*In MTK DMA BTIF channel, there's only one global CG on AP_DMA, no sub channel's CG bit*/ -+/*according to Artis's comment, clock of DMA and BTIF is default off, so we assume it to be off by default*/ -+ int i_ret = 0; -+ unsigned long irq_flag = 0; -+ -+#if MTK_BTIF_ENABLE_CLK_REF_COUNTER -+ static atomic_t s_clk_ref = ATOMIC_INIT(0); -+#else -+ static ENUM_CLOCK_CTRL status = CLK_OUT_DISABLE; -+#endif -+ -+ spin_lock_irqsave(&(g_clk_cg_spinlock), irq_flag); -+ -+#if MTK_BTIF_ENABLE_CLK_CTL -+ -+#if MTK_BTIF_ENABLE_CLK_REF_COUNTER -+ -+ if (flag == CLK_OUT_ENABLE) { -+ if (atomic_inc_return(&s_clk_ref) == 1) { -+#if defined(CONFIG_MTK_CLKMGR) -+ i_ret = enable_clock(MTK_BTIF_APDMA_CLK_CG, DMA_USER_ID); -+#else -+ BTIF_DBG_FUNC("[CCF]enable clk_btif_apdma\n"); -+ i_ret = clk_enable(clk_btif_apdma); -+#endif /* defined(CONFIG_MTK_CLKMGR) */ -+ if (i_ret) { -+ BTIF_WARN_FUNC -+ ("enable_clock for MTK_BTIF_APDMA_CLK_CG failed, ret:%d", -+ i_ret); -+ } -+ } -+ } else if (flag == CLK_OUT_DISABLE) { -+ if (atomic_dec_return(&s_clk_ref) == 0) { -+#if defined(CONFIG_MTK_CLKMGR) -+ i_ret = disable_clock(MTK_BTIF_APDMA_CLK_CG, DMA_USER_ID); -+ if (i_ret) { -+ BTIF_WARN_FUNC -+ ("disable_clock for MTK_BTIF_APDMA_CLK_CG failed, ret:%d", -+ i_ret); -+ } -+#else -+ BTIF_DBG_FUNC("[CCF] clk_disable(clk_btif_apdma) calling\n"); -+ clk_disable(clk_btif_apdma); -+#endif /* defined(CONFIG_MTK_CLKMGR) */ -+ } -+ } else { -+ i_ret = ERR_INVALID_PAR; -+ BTIF_ERR_FUNC("invalid clock ctrl flag (%d)\n", flag); -+ } -+ -+#else -+ -+ if (status == flag) { -+ i_ret = 0; -+ BTIF_DBG_FUNC("dma clock already %s\n", -+ CLK_OUT_ENABLE == -+ status ? "enabled" : "disabled"); -+ } else { -+ if (flag == CLK_OUT_ENABLE) { -+#if defined(CONFIG_MTK_CLKMGR) -+ i_ret = enable_clock(MTK_BTIF_APDMA_CLK_CG, DMA_USER_ID); -+#else -+ BTIF_DBG_FUNC("[CCF]enable clk_btif_apdma\n"); -+ i_ret = clk_enable(clk_btif_apdma); -+#endif /* defined(CONFIG_MTK_CLKMGR) */ -+ status = (i_ret == 0) ? flag : status; -+ if (i_ret) { -+ BTIF_WARN_FUNC -+ ("enable_clock for MTK_BTIF_APDMA_CLK_CG failed, ret:%d", -+ i_ret); -+ } -+ } else if (flag == CLK_OUT_DISABLE) { -+#if defined(CONFIG_MTK_CLKMGR) -+ i_ret = disable_clock(MTK_BTIF_APDMA_CLK_CG, DMA_USER_ID); -+ status = (i_ret == 0) ? flag : status; -+ if (i_ret) { -+ BTIF_WARN_FUNC -+ ("disable_clock for MTK_BTIF_APDMA_CLK_CG failed, ret:%d", -+ i_ret); -+ } -+#else -+ BTIF_DBG_FUNC("[CCF] clk_disable_unprepare(clk_btif_apdma) calling\n"); -+ clk_disable(clk_btif_apdma); -+#endif /* defined(CONFIG_MTK_CLKMGR) */ -+ } else { -+ i_ret = ERR_INVALID_PAR; -+ BTIF_ERR_FUNC("invalid clock ctrl flag (%d)\n", flag); -+ } -+ } -+#endif -+ -+#else -+ -+#if MTK_BTIF_ENABLE_CLK_REF_COUNTER -+ -+#else -+ -+ status = flag; -+#endif -+ -+ i_ret = 0; -+#endif -+ -+ spin_unlock_irqrestore(&(g_clk_cg_spinlock), irq_flag); -+ -+#if MTK_BTIF_ENABLE_CLK_REF_COUNTER -+ if (i_ret == 0) { -+ BTIF_DBG_FUNC("dma clock %s\n", flag == CLK_OUT_ENABLE ? "enabled" : "disabled"); -+ } else { -+ BTIF_ERR_FUNC("%s dma clock failed, ret(%d)\n", -+ flag == CLK_OUT_ENABLE ? "enable" : "disable", i_ret); -+ } -+#else -+ -+ if (i_ret == 0) { -+ BTIF_DBG_FUNC("dma clock %s\n", flag == CLK_OUT_ENABLE ? "enabled" : "disabled"); -+ } else { -+ BTIF_ERR_FUNC("%s dma clock failed, ret(%d)\n", -+ flag == CLK_OUT_ENABLE ? "enable" : "disable", i_ret); -+ } -+#endif -+#if defined(CONFIG_MTK_CLKMGR) -+ BTIF_DBG_FUNC("DMA's clock is %s\n", (clock_is_on(MTK_BTIF_APDMA_CLK_CG) == 0) ? "off" : "on"); -+#endif -+ return i_ret; -+} -+ -+int hal_btif_dma_hw_init(P_MTK_DMA_INFO_STR p_dma_info) -+{ -+ int i_ret = 0; -+ unsigned int dat = 0; -+ unsigned long base = p_dma_info->base; -+ unsigned long addr_h = 0; -+ P_DMA_VFIFO p_vfifo = p_dma_info->p_vfifo; -+ P_MTK_BTIF_DMA_VFIFO p_mtk_dma_vfifo = container_of(p_vfifo, -+ MTK_BTIF_DMA_VFIFO, -+ vfifo); -+ -+ if (p_dma_info->dir == DMA_DIR_RX) { -+ /*Rx DMA*/ -+ /*do hardware reset*/ -+ /* BTIF_SET_BIT(RX_DMA_RST(base), DMA_HARD_RST);*/ -+ /* BTIF_CLR_BIT(RX_DMA_RST(base), DMA_HARD_RST);*/ -+ BTIF_SET_BIT(RX_DMA_RST(base), DMA_WARM_RST); -+ do { -+ dat = BTIF_READ32(RX_DMA_EN(base)); -+ } while (0x01 & dat); -+ /*write vfifo base address to VFF_ADDR*/ -+ btif_reg_sync_writel(p_vfifo->phy_addr, RX_DMA_VFF_ADDR(base)); -+ if (enable_4G()) -+ hal_btif_rx_dma_vff_set_for_4g(); -+ else { -+ addr_h = p_vfifo->phy_addr >> 16; -+ addr_h = addr_h >> 16; -+ btif_reg_sync_writel(addr_h, RX_DMA_VFF_ADDR_H(base)); -+ } -+ /*write vfifo length to VFF_LEN*/ -+ btif_reg_sync_writel(p_vfifo->vfifo_size, RX_DMA_VFF_LEN(base)); -+ /*write wpt to VFF_WPT*/ -+ btif_reg_sync_writel(p_mtk_dma_vfifo->wpt, -+ RX_DMA_VFF_WPT(base)); -+ btif_reg_sync_writel(p_mtk_dma_vfifo->rpt, -+ RX_DMA_VFF_RPT(base)); -+ /*write vff_thre to VFF_THRESHOLD*/ -+ btif_reg_sync_writel(p_vfifo->thre, RX_DMA_VFF_THRE(base)); -+ /*clear Rx DMA's interrupt status*/ -+ BTIF_SET_BIT(RX_DMA_INT_FLAG(base), -+ RX_DMA_INT_DONE | RX_DMA_INT_THRE); -+ -+ /*enable Rx IER by default*/ -+ btif_rx_dma_ier_ctrl(p_dma_info, true); -+ } else { -+/*Tx DMA*/ -+/*do hardware reset*/ -+/* BTIF_SET_BIT(TX_DMA_RST(base), DMA_HARD_RST);*/ -+/* BTIF_CLR_BIT(TX_DMA_RST(base), DMA_HARD_RST);*/ -+ BTIF_SET_BIT(TX_DMA_RST(base), DMA_WARM_RST); -+ do { -+ dat = BTIF_READ32(TX_DMA_EN(base)); -+ } while (0x01 & dat); -+/*write vfifo base address to VFF_ADDR*/ -+ btif_reg_sync_writel(p_vfifo->phy_addr, TX_DMA_VFF_ADDR(base)); -+ if (enable_4G()) -+ hal_btif_tx_dma_vff_set_for_4g(); -+ else { -+ addr_h = p_vfifo->phy_addr >> 16; -+ addr_h = addr_h >> 16; -+ btif_reg_sync_writel(addr_h, TX_DMA_VFF_ADDR_H(base)); -+ } -+/*write vfifo length to VFF_LEN*/ -+ btif_reg_sync_writel(p_vfifo->vfifo_size, TX_DMA_VFF_LEN(base)); -+/*write wpt to VFF_WPT*/ -+ btif_reg_sync_writel(p_mtk_dma_vfifo->wpt, -+ TX_DMA_VFF_WPT(base)); -+ btif_reg_sync_writel(p_mtk_dma_vfifo->rpt, -+ TX_DMA_VFF_RPT(base)); -+/*write vff_thre to VFF_THRESHOLD*/ -+ btif_reg_sync_writel(p_vfifo->thre, TX_DMA_VFF_THRE(base)); -+ -+ BTIF_CLR_BIT(TX_DMA_INT_FLAG(base), TX_DMA_INT_FLAG_MASK); -+ -+ hal_btif_dma_ier_ctrl(p_dma_info, false); -+ } -+ -+ return i_ret; -+} -+ -+/***************************************************************************** -+* FUNCTION -+* hal_tx_dma_ctrl -+* DESCRIPTION -+* enable/disable Tx DMA channel -+* PARAMETERS -+* p_dma_info [IN] pointer to BTIF dma channel's information -+* ctrl_id [IN] enable/disable ID -+* RETURNS -+* 0 means success; negative means fail -+*****************************************************************************/ -+int hal_btif_dma_ctrl(P_MTK_DMA_INFO_STR p_dma_info, ENUM_DMA_CTRL ctrl_id) -+{ -+ unsigned int i_ret = -1; -+ ENUM_DMA_DIR dir = p_dma_info->dir; -+ -+ if (dir == DMA_DIR_RX) -+ i_ret = btif_rx_dma_ctrl(p_dma_info, ctrl_id); -+ else if (dir == DMA_DIR_TX) -+ i_ret = btif_tx_dma_ctrl(p_dma_info, ctrl_id); -+ else { -+ /*TODO: print error log*/ -+ BTIF_ERR_FUNC("invalid dma ctrl id (%d)\n", ctrl_id); -+ i_ret = ERR_INVALID_PAR; -+ } -+ return i_ret; -+} -+ -+int hal_btif_dma_rx_cb_reg(P_MTK_DMA_INFO_STR p_dma_info, -+ dma_rx_buf_write rx_cb) -+{ -+ if (p_dma_info->rx_cb != NULL) { -+ BTIF_DBG_FUNC -+ ("rx_cb already registered, replace (0x%p) with (0x%p)\n", -+ p_dma_info->rx_cb, rx_cb); -+ } -+ p_dma_info->rx_cb = rx_cb; -+ return 0; -+} -+ -+int btif_tx_dma_ctrl(P_MTK_DMA_INFO_STR p_dma_info, ENUM_DMA_CTRL ctrl_id) -+{ -+ unsigned int i_ret = -1; -+ unsigned long base = p_dma_info->base; -+ unsigned int dat; -+ -+ BTIF_TRC_FUNC(); -+ if (ctrl_id == DMA_CTRL_DISABLE) { -+ /*if write 0 to EN bit, DMA will be stopped imediately*/ -+ /*if write 1 to STOP bit, DMA will be stopped after current transaction finished*/ -+ /*BTIF_CLR_BIT(TX_DMA_EN(base), DMA_EN_BIT);*/ -+ BTIF_SET_BIT(TX_DMA_STOP(base), DMA_STOP_BIT); -+ do { -+ dat = BTIF_READ32(TX_DMA_STOP(base)); -+ } while (0x1 & dat); -+ BTIF_DBG_FUNC("BTIF Tx DMA disabled,EN(0x%x),STOP(0x%x)\n", -+ BTIF_READ32(TX_DMA_EN(base)), BTIF_READ32(TX_DMA_STOP(base))); -+ i_ret = 0; -+ } else if (ctrl_id == DMA_CTRL_ENABLE) { -+ BTIF_SET_BIT(TX_DMA_EN(base), DMA_EN_BIT); -+ BTIF_DBG_FUNC("BTIF Tx DMA enabled\n"); -+ i_ret = 0; -+ } else { -+/*TODO: print error log*/ -+ BTIF_ERR_FUNC("invalid DMA ctrl_id (%d)\n", ctrl_id); -+ i_ret = ERR_INVALID_PAR; -+ } -+ BTIF_TRC_FUNC(); -+ return i_ret; -+} -+ -+int btif_rx_dma_ctrl(P_MTK_DMA_INFO_STR p_dma_info, ENUM_DMA_CTRL ctrl_id) -+{ -+ unsigned int i_ret = -1; -+ unsigned long base = p_dma_info->base; -+ unsigned int dat; -+ -+ BTIF_TRC_FUNC(); -+ -+ if (ctrl_id == DMA_CTRL_DISABLE) { -+ /*if write 0 to EN bit, DMA will be stopped imediately*/ -+ /*if write 1 to STOP bit, DMA will be stopped after current transaction finished*/ -+ /*BTIF_CLR_BIT(RX_DMA_EN(base), DMA_EN_BIT);*/ -+ BTIF_SET_BIT(RX_DMA_STOP(base), DMA_STOP_BIT); -+ do { -+ dat = BTIF_READ32(RX_DMA_STOP(base)); -+ } while (0x1 & dat); -+ BTIF_DBG_FUNC("BTIF Rx DMA disabled,EN(0x%x),STOP(0x%x)\n", -+ BTIF_READ32(RX_DMA_EN(base)), BTIF_READ32(RX_DMA_STOP(base))); -+ i_ret = 0; -+ } else if (ctrl_id == DMA_CTRL_ENABLE) { -+ BTIF_SET_BIT(RX_DMA_EN(base), DMA_EN_BIT); -+ BTIF_DBG_FUNC("BTIF Rx DMA enabled\n"); -+ i_ret = 0; -+ } else { -+/*TODO: print error log*/ -+ BTIF_ERR_FUNC("invalid DMA ctrl_id (%d)\n", ctrl_id); -+ i_ret = ERR_INVALID_PAR; -+ } -+ BTIF_TRC_FUNC(); -+ -+ return i_ret; -+} -+ -+/***************************************************************************** -+* FUNCTION -+* hal_tx_vfifo_reset -+* DESCRIPTION -+* reset tx virtual fifo information, except memory information -+* PARAMETERS -+* p_dma_info [IN] pointer to BTIF dma channel's information -+* RETURNS -+* 0 means success, negative means fail -+*****************************************************************************/ -+int hal_btif_vfifo_reset(P_MTK_DMA_INFO_STR p_dma_info) -+{ -+ unsigned int i_ret = -1; -+ P_DMA_VFIFO p_vfifo = p_dma_info->p_vfifo; -+ P_MTK_BTIF_DMA_VFIFO p_mtk_dma_vfifo = container_of(p_vfifo, -+ MTK_BTIF_DMA_VFIFO, -+ vfifo); -+ -+ BTIF_TRC_FUNC(); -+ p_mtk_dma_vfifo->rpt = 0; -+ p_mtk_dma_vfifo->last_rpt_wrap = 0; -+ p_mtk_dma_vfifo->wpt = 0; -+ p_mtk_dma_vfifo->last_wpt_wrap = 0; -+ BTIF_TRC_FUNC(); -+ return i_ret; -+} -+ -+/***************************************************************************** -+* FUNCTION -+* hal_tx_dma_ier_ctrl -+* DESCRIPTION -+* BTIF Tx DMA's interrupt enable/disable -+* PARAMETERS -+* p_dma_info [IN] pointer to BTIF dma channel's information -+* enable [IN] control if tx interrupt enabled or not -+* RETURNS -+* 0 means success, negative means fail -+*****************************************************************************/ -+int hal_btif_dma_ier_ctrl(P_MTK_DMA_INFO_STR p_dma_info, bool en) -+{ -+ unsigned int i_ret = -1; -+ ENUM_DMA_DIR dir = p_dma_info->dir; -+ -+ if (dir == DMA_DIR_RX) { -+ i_ret = btif_rx_dma_ier_ctrl(p_dma_info, en); -+ } else if (dir == DMA_DIR_TX) { -+ i_ret = btif_tx_dma_ier_ctrl(p_dma_info, en); -+ } else { -+/*TODO: print error log*/ -+ BTIF_ERR_FUNC("invalid DMA dma dir (%d)\n", dir); -+ i_ret = ERR_INVALID_PAR; -+ } -+ -+ return i_ret; -+} -+ -+int btif_rx_dma_ier_ctrl(P_MTK_DMA_INFO_STR p_dma_info, bool en) -+{ -+ unsigned int i_ret = -1; -+ unsigned long base = p_dma_info->base; -+ -+ BTIF_TRC_FUNC(); -+ if (!en) { -+ BTIF_CLR_BIT(RX_DMA_INT_EN(base), -+ (RX_DMA_INT_THRE_EN | RX_DMA_INT_DONE_EN)); -+ } else { -+ BTIF_SET_BIT(RX_DMA_INT_EN(base), -+ (RX_DMA_INT_THRE_EN | RX_DMA_INT_DONE_EN)); -+ } -+ i_ret = 0; -+ BTIF_TRC_FUNC(); -+ -+ return i_ret; -+} -+ -+int btif_tx_dma_ier_ctrl(P_MTK_DMA_INFO_STR p_dma_info, bool en) -+{ -+ unsigned int i_ret = -1; -+ unsigned long base = p_dma_info->base; -+ -+ BTIF_TRC_FUNC(); -+ if (!en) -+ BTIF_CLR_BIT(TX_DMA_INT_EN(base), TX_DMA_INTEN_BIT); -+ else -+ BTIF_SET_BIT(TX_DMA_INT_EN(base), TX_DMA_INTEN_BIT); -+ i_ret = 0; -+ BTIF_TRC_FUNC(); -+ -+ return i_ret; -+} -+ -+static int is_tx_dma_irq_finish_done(P_MTK_DMA_INFO_STR p_dma_info) -+{ -+ int tx_irq_done = 0; -+#if MTK_BTIF_ENABLE_CLK_REF_COUNTER -+/*if we enable this clock reference couner, just return , because when enter IRQ handler, DMA's clock will be opened*/ -+ tx_irq_done = 1; -+#else -+ unsigned long flag = 0; -+ unsigned long base = p_dma_info->base; -+ -+ spin_lock_irqsave(&(g_clk_cg_spinlock), flag); -+ tx_irq_done = ((BTIF_READ32(TX_DMA_INT_FLAG(base)) & TX_DMA_INT_FLAG_MASK) == 0) ? 1 : 0; -+ spin_unlock_irqrestore(&(g_clk_cg_spinlock), flag); -+#endif -+ return tx_irq_done; -+} -+ -+/***************************************************************************** -+* FUNCTION -+* hal_tx_dma_irq_handler -+* DESCRIPTION -+* lower level tx interrupt handler -+* PARAMETERS -+* p_dma_info [IN] pointer to BTIF dma channel's information -+* RETURNS -+* 0 means success, negative means fail -+*****************************************************************************/ -+int hal_tx_dma_irq_handler(P_MTK_DMA_INFO_STR p_dma_info) -+{ -+#define MAX_CONTINIOUS_TIMES 512 -+ unsigned int i_ret = -1; -+ unsigned int valid_size = 0; -+ unsigned int vff_len = 0; -+ unsigned int left_len = 0; -+ unsigned long base = p_dma_info->base; -+ static int flush_irq_counter; -+ static struct timeval start_timer; -+ static struct timeval end_timer; -+ unsigned long flag = 0; -+ -+ spin_lock_irqsave(&(g_clk_cg_spinlock), flag); -+ -+#if defined(CONFIG_MTK_CLKMGR) -+ if (clock_is_on(MTK_BTIF_APDMA_CLK_CG) == 0) { -+ spin_unlock_irqrestore(&(g_clk_cg_spinlock), flag); -+ BTIF_ERR_FUNC -+ ("%s: clock is off before irq status clear done!!!\n", -+ __FILE__); -+ return i_ret; -+ } -+#endif -+/*check if Tx VFF Left Size equal to VFIFO size or not*/ -+ vff_len = BTIF_READ32(TX_DMA_VFF_LEN(base)); -+ valid_size = BTIF_READ32(TX_DMA_VFF_VALID_SIZE(base)); -+ left_len = BTIF_READ32(TX_DMA_VFF_LEFT_SIZE(base)); -+ if (flush_irq_counter == 0) -+ do_gettimeofday(&start_timer); -+ if ((valid_size > 0) && (valid_size < 8)) { -+ i_ret = _tx_dma_flush(p_dma_info); -+ flush_irq_counter++; -+ if (flush_irq_counter >= MAX_CONTINIOUS_TIMES) { -+ do_gettimeofday(&end_timer); -+/* -+ * when btif tx fifo cannot accept any data and counts of bytes left in tx vfifo < 8 for a while -+ * we assume that btif cannot send data for a long time -+ * in order not to generate interrupt continiously, which may effect system's performance. -+ * we clear tx flag and disable btif tx interrupt -+ */ -+/*clear interrupt flag*/ -+ BTIF_CLR_BIT(TX_DMA_INT_FLAG(base), -+ TX_DMA_INT_FLAG_MASK); -+/*vFIFO data has been read by DMA controller, just disable tx dma's irq*/ -+ i_ret = hal_btif_dma_ier_ctrl(p_dma_info, false); -+ BTIF_ERR_FUNC -+ ("**********************ERROR, ERROR, ERROR**************************\n"); -+ BTIF_ERR_FUNC -+ ("BTIF Tx IRQ happened %d times (continiously), between %d.%d and %d.%d\n", -+ MAX_CONTINIOUS_TIMES, start_timer.tv_sec, -+ start_timer.tv_usec, end_timer.tv_usec, -+ end_timer.tv_usec); -+ } -+ } else if (vff_len == left_len) { -+ flush_irq_counter = 0; -+/*clear interrupt flag*/ -+ BTIF_CLR_BIT(TX_DMA_INT_FLAG(base), TX_DMA_INT_FLAG_MASK); -+/*vFIFO data has been read by DMA controller, just disable tx dma's irq*/ -+ i_ret = hal_btif_dma_ier_ctrl(p_dma_info, false); -+ } else { -+#if 0 -+ BTIF_ERR_FUNC -+ ("**********************WARNING**************************\n"); -+ BTIF_ERR_FUNC("invalid irq condition, dump register\n"); -+ hal_dma_dump_reg(p_dma_info, REG_TX_DMA_ALL); -+#endif -+ BTIF_DBG_FUNC -+ ("superious IRQ occurs, vff_len(%d), valid_size(%d), left_len(%d)\n", -+ vff_len, valid_size, left_len); -+ } -+ -+ spin_unlock_irqrestore(&(g_clk_cg_spinlock), flag); -+ -+ return i_ret; -+} -+ -+/***************************************************************************** -+* FUNCTION -+* hal_dma_send_data -+* DESCRIPTION -+* send data through btif in DMA mode -+* PARAMETERS -+* p_dma_info [IN] pointer to BTIF dma channel's information -+* p_buf [IN] pointer to rx data buffer -+* max_len [IN] tx buffer length -+* RETURNS -+* 0 means success, negative means fail -+*****************************************************************************/ -+int hal_dma_send_data(P_MTK_DMA_INFO_STR p_dma_info, -+ const unsigned char *p_buf, const unsigned int buf_len) -+{ -+ unsigned int i_ret = -1; -+ unsigned long base = p_dma_info->base; -+ P_DMA_VFIFO p_vfifo = p_dma_info->p_vfifo; -+ unsigned int len_to_send = buf_len; -+ unsigned int ava_len = 0; -+ unsigned int wpt = 0; -+ unsigned int last_wpt_wrap = 0; -+ unsigned int vff_size = 0; -+ unsigned char *p_data = (unsigned char *)p_buf; -+ P_MTK_BTIF_DMA_VFIFO p_mtk_vfifo = container_of(p_vfifo, -+ MTK_BTIF_DMA_VFIFO, -+ vfifo); -+ -+ BTIF_TRC_FUNC(); -+ if ((p_buf == NULL) || (buf_len == 0)) { -+ i_ret = ERR_INVALID_PAR; -+ BTIF_ERR_FUNC("invalid parameters, p_buf:0x%p, buf_len:%d\n", -+ p_buf, buf_len); -+ return i_ret; -+ } -+/*check if tx dma in flush operation? if yes, should wait until DMA finish flush operation*/ -+/*currently uplayer logic will make sure this pre-condition*/ -+/*disable Tx IER, in case Tx irq happens, flush bit may be set in irq handler*/ -+ btif_tx_dma_ier_ctrl(p_dma_info, false); -+ -+ vff_size = p_mtk_vfifo->vfifo.vfifo_size; -+ ava_len = BTIF_READ32(TX_DMA_VFF_LEFT_SIZE(base)); -+ wpt = BTIF_READ32(TX_DMA_VFF_WPT(base)) & DMA_WPT_MASK; -+ last_wpt_wrap = BTIF_READ32(TX_DMA_VFF_WPT(base)) & DMA_WPT_WRAP; -+ -+/* -+ * copy data to vFIFO, Note: ava_len should always large than buf_len, -+ * otherwise common logic layer will not call hal_dma_send_data -+ */ -+ if (buf_len > ava_len) { -+ BTIF_ERR_FUNC -+ ("length to send:(%d) < length available(%d), abnormal!!!---!!!\n", -+ buf_len, ava_len); -+ WARN_ON(buf_len > ava_len); /* this will cause kernel panic */ -+ } -+ -+ len_to_send = buf_len < ava_len ? buf_len : ava_len; -+ if (len_to_send + wpt >= vff_size) { -+ unsigned int tail_len = vff_size - wpt; -+ -+ memcpy((p_mtk_vfifo->vfifo.p_vir_addr + wpt), p_data, tail_len); -+ p_data += tail_len; -+ memcpy(p_mtk_vfifo->vfifo.p_vir_addr, -+ p_data, len_to_send - tail_len); -+/*make sure all data write to memory area tx vfifo locates*/ -+ mb(); -+ -+/*calculate WPT*/ -+ wpt = wpt + len_to_send - vff_size; -+ last_wpt_wrap ^= DMA_WPT_WRAP; -+ } else { -+ memcpy((p_mtk_vfifo->vfifo.p_vir_addr + wpt), -+ p_data, len_to_send); -+/*make sure all data write to memory area tx vfifo locates*/ -+ mb(); -+ -+/*calculate WPT*/ -+ wpt += len_to_send; -+ } -+ p_mtk_vfifo->wpt = wpt; -+ p_mtk_vfifo->last_wpt_wrap = last_wpt_wrap; -+ -+/*make sure tx dma is allowed(tx flush bit is not set) to use before update WPT*/ -+ if (hal_dma_is_tx_allow(p_dma_info)) { -+ /*make sure tx dma enabled*/ -+ hal_btif_dma_ctrl(p_dma_info, DMA_CTRL_ENABLE); -+ -+ /*update WTP to Tx DMA controller's control register*/ -+ btif_reg_sync_writel(wpt | last_wpt_wrap, TX_DMA_VFF_WPT(base)); -+ -+ if ((BTIF_READ32(TX_DMA_VFF_VALID_SIZE(base)) < 8) && -+ (BTIF_READ32(TX_DMA_VFF_VALID_SIZE(base)) > 0)) { -+ /* -+ * 0 < valid size in Tx vFIFO < 8 && TX Flush is not in process? -+ * if yes, set flush bit to DMA -+ */ -+ _tx_dma_flush(p_dma_info); -+ } -+ i_ret = len_to_send; -+ } else { -+/*TODO: print error log*/ -+ BTIF_ERR_FUNC("Tx DMA flush operation is in process, this case should never happen,", -+ "please check if tx operation is allowed before call this API\n"); -+/*if flush operation is in process , we will return 0*/ -+ i_ret = 0; -+ } -+ -+/*Enable Tx IER*/ -+ btif_tx_dma_ier_ctrl(p_dma_info, true); -+ -+ BTIF_TRC_FUNC(); -+ return i_ret; -+} -+ -+/***************************************************************************** -+* FUNCTION -+* hal_dma_is_tx_complete -+* DESCRIPTION -+* get tx complete flag -+* PARAMETERS -+* p_dma_info [IN] pointer to BTIF dma channel's information -+* RETURNS -+* true means tx complete, false means tx in process -+*****************************************************************************/ -+bool hal_dma_is_tx_complete(P_MTK_DMA_INFO_STR p_dma_info) -+{ -+ bool b_ret = -1; -+ unsigned long base = p_dma_info->base; -+ unsigned int valid_size = BTIF_READ32(TX_DMA_VFF_VALID_SIZE(base)); -+ unsigned int inter_size = BTIF_READ32(TX_DMA_INT_BUF_SIZE(base)); -+ unsigned int tx_done = is_tx_dma_irq_finish_done(p_dma_info); -+ -+/* -+ * only when virtual FIFO valid size and Tx channel internal buffer size are both becomes to be 0, -+ * we can identify tx operation finished -+ * confirmed with DE. -+ */ -+ if ((valid_size == 0) && (inter_size == 0) && (tx_done == 1)) { -+ b_ret = true; -+ BTIF_DBG_FUNC("DMA tx finished.\n"); -+ } else { -+ BTIF_DBG_FUNC -+ ("DMA tx is in process. vfifo valid size(%d), dma internal size (%d), tx_done(%d)\n", -+ valid_size, inter_size, tx_done); -+ b_ret = false; -+ } -+ -+ return b_ret; -+} -+ -+/***************************************************************************** -+* FUNCTION -+* hal_dma_get_ava_room -+* DESCRIPTION -+* get tx available room -+* PARAMETERS -+* p_dma_info [IN] pointer to BTIF dma channel's information -+* RETURNS -+* available room size -+*****************************************************************************/ -+int hal_dma_get_ava_room(P_MTK_DMA_INFO_STR p_dma_info) -+{ -+ int i_ret = -1; -+ unsigned long base = p_dma_info->base; -+ -+/*read vFIFO's left size*/ -+ i_ret = BTIF_READ32(TX_DMA_VFF_LEFT_SIZE(base)); -+ BTIF_DBG_FUNC("DMA tx ava room (%d).\n", i_ret); -+ if (i_ret == 0) -+ BTIF_INFO_FUNC("DMA tx vfifo is full.\n"); -+ -+ return i_ret; -+} -+ -+/***************************************************************************** -+* FUNCTION -+* hal_dma_is_tx_allow -+* DESCRIPTION -+* is tx operation allowed by DMA -+* PARAMETERS -+* p_dma_info [IN] pointer to BTIF dma channel's information -+* RETURNS -+* true if tx operation is allowed; false if tx is not allowed -+*****************************************************************************/ -+bool hal_dma_is_tx_allow(P_MTK_DMA_INFO_STR p_dma_info) -+{ -+#define MIN_TX_MB ((26 * 1000000 / 13) / 1000000) -+#define AVE_TX_MB ((26 * 1000000 / 8) / 1000000) -+ -+ bool b_ret = false; -+ unsigned int wait_us = 8 / MIN_TX_MB; /*only ava length */ -+/*see if flush operation is in process*/ -+ b_ret = _is_tx_dma_in_flush(p_dma_info) ? false : true; -+ if (!b_ret) { -+ usleep_range(wait_us, 2 * wait_us); -+ b_ret = _is_tx_dma_in_flush(p_dma_info) ? false : true; -+ } -+ if (!b_ret) -+ BTIF_WARN_FUNC("btif tx dma is not allowed\n"); -+/*after Tx flush operation finished, HW will set DMA_EN back to 0 and stop DMA*/ -+ return b_ret; -+} -+ -+ -+/***************************************************************************** -+* FUNCTION -+* hal_rx_dma_irq_handler -+* DESCRIPTION -+* lower level rx interrupt handler -+* PARAMETERS -+* p_dma_info [IN] pointer to BTIF dma channel's information -+* p_buf [IN/OUT] pointer to rx data buffer -+* max_len [IN] max length of rx buffer -+* RETURNS -+* 0 means success, negative means fail -+*****************************************************************************/ -+int hal_rx_dma_irq_handler(P_MTK_DMA_INFO_STR p_dma_info, -+ unsigned char *p_buf, const unsigned int max_len) -+{ -+ int i_ret = -1; -+ unsigned int valid_len = 0; -+ unsigned int wpt_wrap = 0; -+ unsigned int rpt_wrap = 0; -+ unsigned int wpt = 0; -+ unsigned int rpt = 0; -+ unsigned int tail_len = 0; -+ unsigned int real_len = 0; -+ unsigned long base = p_dma_info->base; -+ P_DMA_VFIFO p_vfifo = p_dma_info->p_vfifo; -+ dma_rx_buf_write rx_cb = p_dma_info->rx_cb; -+ unsigned char *p_vff_buf = NULL; -+ unsigned char *vff_base = p_vfifo->p_vir_addr; -+ unsigned int vff_size = p_vfifo->vfifo_size; -+ P_MTK_BTIF_DMA_VFIFO p_mtk_vfifo = container_of(p_vfifo, -+ MTK_BTIF_DMA_VFIFO, -+ vfifo); -+ unsigned long flag = 0; -+ -+ spin_lock_irqsave(&(g_clk_cg_spinlock), flag); -+#if defined(CONFIG_MTK_CLKMGR) -+ if (clock_is_on(MTK_BTIF_APDMA_CLK_CG) == 0) { -+ spin_unlock_irqrestore(&(g_clk_cg_spinlock), flag); -+ BTIF_ERR_FUNC("%s: clock is off before irq handle done!!!\n", -+ __FILE__); -+ return i_ret; -+ } -+#endif -+/*disable DMA Rx IER*/ -+ hal_btif_dma_ier_ctrl(p_dma_info, false); -+ -+/*clear Rx DMA's interrupt status*/ -+ BTIF_SET_BIT(RX_DMA_INT_FLAG(base), RX_DMA_INT_DONE | RX_DMA_INT_THRE); -+ -+ valid_len = BTIF_READ32(RX_DMA_VFF_VALID_SIZE(base)); -+ rpt = BTIF_READ32(RX_DMA_VFF_RPT(base)); -+ wpt = BTIF_READ32(RX_DMA_VFF_WPT(base)); -+ if ((valid_len == 0) && (rpt == wpt)) { -+ BTIF_DBG_FUNC -+ ("rx interrupt, no data available in Rx DMA, wpt(0x%08x), rpt(0x%08x)\n", -+ rpt, wpt); -+ } -+ -+ i_ret = 0; -+ -+ while ((valid_len > 0) || (rpt != wpt)) { -+ rpt_wrap = rpt & DMA_RPT_WRAP; -+ wpt_wrap = wpt & DMA_WPT_WRAP; -+ rpt &= DMA_RPT_MASK; -+ wpt &= DMA_WPT_MASK; -+ -+/*calcaute length of available data in vFIFO*/ -+ if (wpt_wrap != p_mtk_vfifo->last_wpt_wrap) -+ real_len = wpt + vff_size - rpt; -+ else -+ real_len = wpt - rpt; -+ -+ if (rx_cb != NULL) { -+ tail_len = vff_size - rpt; -+ p_vff_buf = vff_base + rpt; -+ if (tail_len >= real_len) { -+ (*rx_cb) (p_dma_info, p_vff_buf, real_len); -+ } else { -+ (*rx_cb) (p_dma_info, p_vff_buf, tail_len); -+ p_vff_buf = vff_base; -+ (*rx_cb) (p_dma_info, p_vff_buf, real_len - -+ tail_len); -+ } -+ i_ret += real_len; -+ } else -+ BTIF_ERR_FUNC("no rx_cb found, please check your init process\n"); -+ mb(); -+ rpt += real_len; -+ if (rpt >= vff_size) { -+ /*read wrap bit should be revert*/ -+ rpt_wrap ^= DMA_RPT_WRAP; -+ rpt %= vff_size; -+ } -+ rpt |= rpt_wrap; -+/*record wpt, last_wpt_wrap, rpt, last_rpt_wrap*/ -+ p_mtk_vfifo->wpt = wpt; -+ p_mtk_vfifo->last_wpt_wrap = wpt_wrap; -+ -+ p_mtk_vfifo->rpt = rpt; -+ p_mtk_vfifo->last_rpt_wrap = rpt_wrap; -+ -+/*update rpt information to DMA controller*/ -+ btif_reg_sync_writel(rpt, RX_DMA_VFF_RPT(base)); -+ -+/*get vff valid size again and check if rx data is processed completely*/ -+ valid_len = BTIF_READ32(RX_DMA_VFF_VALID_SIZE(base)); -+ -+ rpt = BTIF_READ32(RX_DMA_VFF_RPT(base)); -+ wpt = BTIF_READ32(RX_DMA_VFF_WPT(base)); -+ } -+ -+/*enable DMA Rx IER*/ -+ hal_btif_dma_ier_ctrl(p_dma_info, true); -+ -+ spin_unlock_irqrestore(&(g_clk_cg_spinlock), flag); -+ -+ return i_ret; -+} -+ -+static int hal_tx_dma_dump_reg(P_MTK_DMA_INFO_STR p_dma_info, -+ ENUM_BTIF_REG_ID flag) -+{ -+ int i_ret = -1; -+ unsigned long base = p_dma_info->base; -+ unsigned int int_flag = 0; -+ unsigned int enable = 0; -+ unsigned int stop = 0; -+ unsigned int flush = 0; -+ unsigned int wpt = 0; -+ unsigned int rpt = 0; -+ unsigned int int_buf = 0; -+ unsigned int valid_size = 0; -+ /*unsigned long irq_flag = 0;*/ -+ -+#if defined(CONFIG_MTK_CLKMGR) -+ /*spin_lock_irqsave(&(g_clk_cg_spinlock), irq_flag);*/ -+ if (clock_is_on(MTK_BTIF_APDMA_CLK_CG) == 0) { -+ /*spin_unlock_irqrestore(&(g_clk_cg_spinlock), irq_flag);*/ -+ BTIF_ERR_FUNC("%s: clock is off, this should never happen!!!\n", -+ __FILE__); -+ return i_ret; -+ } -+#endif -+ int_flag = BTIF_READ32(TX_DMA_INT_FLAG(base)); -+ enable = BTIF_READ32(TX_DMA_EN(base)); -+ stop = BTIF_READ32(TX_DMA_STOP(base)); -+ flush = BTIF_READ32(TX_DMA_FLUSH(base)); -+ wpt = BTIF_READ32(TX_DMA_VFF_WPT(base)); -+ rpt = BTIF_READ32(TX_DMA_VFF_RPT(base)); -+ int_buf = BTIF_READ32(TX_DMA_INT_BUF_SIZE(base)); -+ valid_size = BTIF_READ32(TX_DMA_VFF_VALID_SIZE(base)); -+ /*spin_unlock_irqrestore(&(g_clk_cg_spinlock), irq_flag);*/ -+ -+ BTIF_INFO_FUNC("DMA's clock is on\n"); -+ BTIF_INFO_FUNC("Tx DMA's base address: 0x%lx\n", base); -+ -+ if (flag == REG_TX_DMA_ALL) { -+ BTIF_INFO_FUNC("TX_EN(:0x%x\n", enable); -+ BTIF_INFO_FUNC("INT_FLAG:0x%x\n", int_flag); -+ BTIF_INFO_FUNC("TX_STOP:0x%x\n", stop); -+ BTIF_INFO_FUNC("TX_FLUSH:0x%x\n", flush); -+ BTIF_INFO_FUNC("TX_WPT:0x%x\n", wpt); -+ BTIF_INFO_FUNC("TX_RPT:0x%x\n", rpt); -+ BTIF_INFO_FUNC("INT_BUF_SIZE:0x%x\n", int_buf); -+ BTIF_INFO_FUNC("VALID_SIZE:0x%x\n", valid_size); -+ BTIF_INFO_FUNC("INT_EN:0x%x\n", -+ BTIF_READ32(TX_DMA_INT_EN(base))); -+ BTIF_INFO_FUNC("TX_RST:0x%x\n", BTIF_READ32(TX_DMA_RST(base))); -+ BTIF_INFO_FUNC("VFF_ADDR:0x%x\n", -+ BTIF_READ32(TX_DMA_VFF_ADDR(base))); -+ BTIF_INFO_FUNC("VFF_LEN:0x%x\n", -+ BTIF_READ32(TX_DMA_VFF_LEN(base))); -+ BTIF_INFO_FUNC("TX_THRE:0x%x\n", -+ BTIF_READ32(TX_DMA_VFF_THRE(base))); -+ BTIF_INFO_FUNC("W_INT_BUF_SIZE:0x%x\n", -+ BTIF_READ32(TX_DMA_W_INT_BUF_SIZE(base))); -+ BTIF_INFO_FUNC("LEFT_SIZE:0x%x\n", -+ BTIF_READ32(TX_DMA_VFF_LEFT_SIZE(base))); -+ BTIF_INFO_FUNC("DBG_STATUS:0x%x\n", -+ BTIF_READ32(TX_DMA_DEBUG_STATUS(base))); -+ i_ret = 0; -+ } else { -+ BTIF_WARN_FUNC("unknown flag:%d\n", flag); -+ } -+ BTIF_INFO_FUNC("tx dma %s\n", (enable & DMA_EN_BIT) && -+ (!(stop && DMA_STOP_BIT)) ? "enabled" : "stopped"); -+ BTIF_INFO_FUNC("data in tx dma is %s sent by HW\n", -+ ((wpt == rpt) && -+ (int_buf == 0)) ? "completely" : "not completely"); -+ -+ return i_ret; -+} -+ -+static int hal_rx_dma_dump_reg(P_MTK_DMA_INFO_STR p_dma_info, -+ ENUM_BTIF_REG_ID flag) -+{ -+ int i_ret = -1; -+ unsigned long base = p_dma_info->base; -+ unsigned int int_flag = 0; -+ unsigned int enable = 0; -+ unsigned int stop = 0; -+ unsigned int flush = 0; -+ unsigned int wpt = 0; -+ unsigned int rpt = 0; -+ unsigned int int_buf = 0; -+ unsigned int valid_size = 0; -+ /*unsigned long irq_flag = 0;*/ -+#if defined(CONFIG_MTK_CLKMGR) -+ /*spin_lock_irqsave(&(g_clk_cg_spinlock), irq_flag);*/ -+ if (clock_is_on(MTK_BTIF_APDMA_CLK_CG) == 0) { -+ /*spin_unlock_irqrestore(&(g_clk_cg_spinlock), irq_flag);*/ -+ BTIF_ERR_FUNC("%s: clock is off, this should never happen!!!\n", -+ __FILE__); -+ return i_ret; -+ } -+#endif -+ BTIF_INFO_FUNC("dump DMA status register\n"); -+ _btif_dma_dump_dbg_reg(); -+ -+ int_flag = BTIF_READ32(RX_DMA_INT_FLAG(base)); -+ enable = BTIF_READ32(RX_DMA_EN(base)); -+ stop = BTIF_READ32(RX_DMA_STOP(base)); -+ flush = BTIF_READ32(RX_DMA_FLUSH(base)); -+ wpt = BTIF_READ32(RX_DMA_VFF_WPT(base)); -+ rpt = BTIF_READ32(RX_DMA_VFF_RPT(base)); -+ int_buf = BTIF_READ32(RX_DMA_INT_BUF_SIZE(base)); -+ valid_size = BTIF_READ32(RX_DMA_VFF_VALID_SIZE(base)); -+ /*spin_unlock_irqrestore(&(g_clk_cg_spinlock), irq_flag);*/ -+ -+ BTIF_INFO_FUNC("DMA's clock is on\n"); -+ BTIF_INFO_FUNC("Rx DMA's base address: 0x%lx\n", base); -+ -+ if (flag == REG_RX_DMA_ALL) { -+ BTIF_INFO_FUNC("RX_EN(:0x%x\n", enable); -+ BTIF_INFO_FUNC("RX_STOP:0x%x\n", stop); -+ BTIF_INFO_FUNC("RX_FLUSH:0x%x\n", flush); -+ BTIF_INFO_FUNC("INT_FLAG:0x%x\n", int_flag); -+ BTIF_INFO_FUNC("RX_WPT:0x%x\n", wpt); -+ BTIF_INFO_FUNC("RX_RPT:0x%x\n", rpt); -+ BTIF_INFO_FUNC("INT_BUF_SIZE:0x%x\n", int_buf); -+ BTIF_INFO_FUNC("VALID_SIZE:0x%x\n", valid_size); -+ BTIF_INFO_FUNC("INT_EN:0x%x\n", -+ BTIF_READ32(RX_DMA_INT_EN(base))); -+ BTIF_INFO_FUNC("RX_RST:0x%x\n", BTIF_READ32(RX_DMA_RST(base))); -+ BTIF_INFO_FUNC("VFF_ADDR:0x%x\n", -+ BTIF_READ32(RX_DMA_VFF_ADDR(base))); -+ BTIF_INFO_FUNC("VFF_LEN:0x%x\n", -+ BTIF_READ32(RX_DMA_VFF_LEN(base))); -+ BTIF_INFO_FUNC("RX_THRE:0x%x\n", -+ BTIF_READ32(RX_DMA_VFF_THRE(base))); -+ BTIF_INFO_FUNC("RX_FLOW_CTRL_THRE:0x%x\n", -+ BTIF_READ32(RX_DMA_FLOW_CTRL_THRE(base))); -+ BTIF_INFO_FUNC("LEFT_SIZE:0x%x\n", -+ BTIF_READ32(RX_DMA_VFF_LEFT_SIZE(base))); -+ BTIF_INFO_FUNC("DBG_STATUS:0x%x\n", -+ BTIF_READ32(RX_DMA_DEBUG_STATUS(base))); -+ i_ret = 0; -+ } else { -+ BTIF_WARN_FUNC("unknown flag:%d\n", flag); -+ } -+ BTIF_INFO_FUNC("rx dma %s\n", (enable & DMA_EN_BIT) && -+ (!(stop && DMA_STOP_BIT)) ? "enabled" : "stopped"); -+ BTIF_INFO_FUNC("data in rx dma is %s by driver\n", -+ ((wpt == rpt) && -+ (int_buf == 0)) ? "received" : "not received"); -+ -+ return i_ret; -+} -+ -+/***************************************************************************** -+* FUNCTION -+* hal_dma_dump_reg -+* DESCRIPTION -+* dump BTIF module's information when needed -+* PARAMETERS -+* p_dma_info [IN] pointer to BTIF dma channel's information -+* flag [IN] register id flag -+* RETURNS -+* 0 means success, negative means fail -+*****************************************************************************/ -+int hal_dma_dump_reg(P_MTK_DMA_INFO_STR p_dma_info, ENUM_BTIF_REG_ID flag) -+{ -+ unsigned int i_ret = -1; -+ -+ if (p_dma_info->dir == DMA_DIR_TX) -+ i_ret = hal_tx_dma_dump_reg(p_dma_info, flag); -+ else if (p_dma_info->dir == DMA_DIR_RX) -+ i_ret = hal_rx_dma_dump_reg(p_dma_info, flag); -+ else -+ BTIF_WARN_FUNC("unknown dir:%d\n", p_dma_info->dir); -+ -+ return i_ret; -+} -+ -+static int _tx_dma_flush(P_MTK_DMA_INFO_STR p_dma_info) -+{ -+ unsigned int i_ret = -1; -+ unsigned long base = p_dma_info->base; -+ unsigned int stop = BTIF_READ32(TX_DMA_STOP(base)); -+ -+/*in MTK DMA BTIF channel we cannot set STOP and FLUSH bit at the same time*/ -+ if ((stop && DMA_STOP_BIT) != 0) -+ BTIF_ERR_FUNC("BTIF's DMA in stop state, omit flush operation\n"); -+ else { -+ BTIF_DBG_FUNC("flush tx dma\n"); -+ BTIF_SET_BIT(TX_DMA_FLUSH(base), DMA_FLUSH_BIT); -+ i_ret = 0; -+ } -+ return i_ret; -+} -+ -+static int _is_tx_dma_in_flush(P_MTK_DMA_INFO_STR p_dma_info) -+{ -+ bool b_ret = true; -+ unsigned long base = p_dma_info->base; -+ -+/*see if flush operation is in process*/ -+ b_ret = ((DMA_FLUSH_BIT & BTIF_READ32(TX_DMA_FLUSH(base))) != 0) ? true : false; -+ -+ return b_ret; -+} -+ -+int hal_dma_pm_ops(P_MTK_DMA_INFO_STR p_dma_info, MTK_BTIF_PM_OPID opid) -+{ -+ int i_ret = -1; -+ -+ BTIF_INFO_FUNC("op id: %d\n", opid); -+ switch (opid) { -+ case BTIF_PM_DPIDLE_EN: -+ i_ret = 0; -+ break; -+ case BTIF_PM_DPIDLE_DIS: -+ i_ret = 0; -+ break; -+ case BTIF_PM_SUSPEND: -+ i_ret = 0; -+ break; -+ case BTIF_PM_RESUME: -+ i_ret = 0; -+ break; -+ case BTIF_PM_RESTORE_NOIRQ:{ -+ unsigned int flag = 0; -+ P_MTK_BTIF_IRQ_STR p_irq = p_dma_info->p_irq; -+ -+#ifdef CONFIG_OF -+ flag = p_irq->irq_flags; -+#else -+ switch (p_irq->sens_type) { -+ case IRQ_SENS_EDGE: -+ if (p_irq->edge_type == IRQ_EDGE_FALL) -+ flag = IRQF_TRIGGER_FALLING; -+ else if (p_irq->edge_type == IRQ_EDGE_RAISE) -+ flag = IRQF_TRIGGER_RISING; -+ else if (p_irq->edge_type == IRQ_EDGE_BOTH) -+ flag = IRQF_TRIGGER_RISING | -+ IRQF_TRIGGER_FALLING; -+ else -+ flag = IRQF_TRIGGER_FALLING; /*make this as default type */ -+ break; -+ case IRQ_SENS_LVL: -+ if (p_irq->lvl_type == IRQ_LVL_LOW) -+ flag = IRQF_TRIGGER_LOW; -+ else if (p_irq->lvl_type == IRQ_LVL_HIGH) -+ flag = IRQF_TRIGGER_HIGH; -+ else -+ flag = IRQF_TRIGGER_LOW; /*make this as default type */ -+ break; -+ default: -+ flag = IRQF_TRIGGER_LOW; /*make this as default type */ -+ break; -+ } -+#endif -+/* irq_set_irq_type(p_irq->irq_id, flag); */ -+ i_ret = 0; -+ } -+ i_ret = 0; -+ break; -+ default: -+ i_ret = ERR_INVALID_PAR; -+ break; -+ } -+ -+ return i_ret; -+} -+ -+/***************************************************************************** -+* FUNCTION -+* hal_dma_receive_data -+* DESCRIPTION -+* receive data from btif module in DMA polling mode -+* PARAMETERS -+* p_dma_info [IN] pointer to BTIF dma channel's information -+* p_buf [IN/OUT] pointer to rx data buffer -+* max_len [IN] max length of rx buffer -+* RETURNS -+* positive means data is available, 0 means no data available -+*****************************************************************************/ -+#ifndef MTK_BTIF_MARK_UNUSED_API -+int hal_dma_receive_data(P_MTK_DMA_INFO_STR p_dma_info, -+ unsigned char *p_buf, const unsigned int max_len) -+{ -+ unsigned int i_ret = -1; -+ -+ return i_ret; -+} -+#endif -+ -+int _btif_dma_dump_dbg_reg(void) -+{ -+#if 0 -+ static MTK_BTIF_DMA_REG_DMP_DBG g_dma_dbg_regs[] = { -+ {0x10201180, 0x0}, -+ {0x10201184, 0x0}, -+ {0x10201188, 0x0}, -+ {0x1020118C, 0x0}, -+ {0x10201190, 0x0}, -+ {0x1000320C, 0x0}, -+ {0x10003210, 0x0}, -+ {0x10003214, 0x0}, -+ }; -+ -+ int i = 0; -+ char *addr1 = NULL; -+ char *addr2 = NULL; -+ -+ int array_num = ARRAY_SIZE(g_dma_dbg_regs) -+ -+ addr1 = ioremap(g_dma_dbg_regs[0].reg_addr, 0x20); -+ if (addr1) { -+ for (i = 0; i < 5; i++) -+ g_dma_dbg_regs[i].reg_val = *(volatile unsigned int*)(addr1 + i*4); -+ iounmap(addr1); -+ } -+ -+ addr2 = ioremap(g_dma_dbg_regs[5].reg_addr, 0x10); -+ if (addr2) { -+ g_dma_dbg_regs[5].reg_val = *(volatile unsigned int*)(addr2); -+ g_dma_dbg_regs[6].reg_val = *(volatile unsigned int*)(addr2+4); -+ g_dma_dbg_regs[7].reg_val = *(volatile unsigned int*)(addr2+8); -+ iounmap(addr2); -+ } -+ -+ for (i = 0; i < array_num; i++) -+ BTIF_INFO_FUNC("-<0x%lx, 0x%08x>\n", g_dma_dbg_regs[i].reg_addr, g_dma_dbg_regs[i].reg_val); -+#endif -+ return 0; -+} -+ -+static void hal_btif_tx_dma_vff_set_for_4g(void) -+{ -+ BTIF_DBG_FUNC("Set btif tx_vff_addr bit29\n"); -+ BTIF_SET_BIT(TX_DMA_VFF_ADDR_H(mtk_btif_tx_dma.base), DMA_VFF_BIT29_OFFSET); -+ BTIF_DBG_FUNC("Dump value of bit29 0x%x:(0x%x)\n", TX_DMA_VFF_ADDR_H(mtk_btif_tx_dma.base), -+ BTIF_READ32(TX_DMA_VFF_ADDR_H(mtk_btif_tx_dma.base))); -+} -+static void hal_btif_rx_dma_vff_set_for_4g(void) -+{ -+ BTIF_DBG_FUNC("Set btif rx_vff_addr bit29\n"); -+ BTIF_SET_BIT(RX_DMA_VFF_ADDR_H(mtk_btif_rx_dma.base), DMA_VFF_BIT29_OFFSET); -+ BTIF_DBG_FUNC("Dump value of bit29 0x%x:(0x%x)\n", RX_DMA_VFF_ADDR_H(mtk_btif_rx_dma.base), -+ BTIF_READ32(RX_DMA_VFF_ADDR_H(mtk_btif_rx_dma.base))); -+} -+ -diff --git a/drivers/misc/mediatek/btif/common/btif_plat.c b/drivers/misc/mediatek/btif/common/btif_plat.c -new file mode 100644 -index 000000000000..baf2a0b6d0c8 ---- /dev/null -+++ b/drivers/misc/mediatek/btif/common/btif_plat.c -@@ -0,0 +1,1396 @@ -+/* -+ * Copyright (C) 2015 MediaTek Inc. -+ * -+ * 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. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#ifdef DFT_TAG -+#undef DFT_TAG -+#endif -+#define DFT_TAG "MTK-BTIF" -+ -+#define NEW_TX_HANDLING_SUPPORT 1 -+ -+#include "btif_pub.h" -+#include "btif_priv.h" -+ -+#define BTIF_USER_ID "btif_driver" -+ -+static spinlock_t g_clk_cg_spinlock; /*BTIF clock's spinlock */ -+ -+/*-----------------------------BTIF Module Clock and Power Control Defination------------------*/ -+ -+MTK_BTIF_IRQ_STR mtk_btif_irq = { -+ .name = "mtk btif irq", -+ .is_irq_sup = true, -+ .reg_flag = false, -+#ifdef CONFIG_OF -+ .irq_flags = IRQF_TRIGGER_NONE, -+#else -+ .irq_id = MT_BTIF_IRQ_ID, -+ .sens_type = IRQ_SENS_LVL, -+ .lvl_type = IRQ_LVL_LOW, -+#endif -+ .p_irq_handler = NULL, -+}; -+ -+/* -+ * will call clock manager's API export by WCP to control BTIF's clock, -+ * but we may need to access these registers in case of btif clock control logic is wrong in clock manager -+ */ -+ -+MTK_BTIF_INFO_STR mtk_btif = { -+#ifndef CONFIG_OF -+ .base = MTK_BTIF_REG_BASE, -+#endif -+ .p_irq = &mtk_btif_irq, -+ .tx_fifo_size = BTIF_TX_FIFO_SIZE, -+ .rx_fifo_size = BTIF_RX_FIFO_SIZE, -+ .tx_tri_lvl = BTIF_TX_FIFO_THRE, -+ .rx_tri_lvl = BTIF_RX_FIFO_THRE, -+ .rx_data_len = 0, -+ .p_tx_fifo = NULL, -+}; -+#if !(NEW_TX_HANDLING_SUPPORT) -+static bool _btif_is_tx_allow(P_MTK_BTIF_INFO_STR p_btif); -+#endif -+ -+static int btif_rx_irq_handler(P_MTK_BTIF_INFO_STR p_btif_info, -+ unsigned char *p_buf, -+ const unsigned int max_len); -+static int btif_tx_irq_handler(P_MTK_BTIF_INFO_STR p_btif); -+ -+/***************************************************************************** -+* FUNCTION -+* hal_btif_rx_ier_ctrl -+* DESCRIPTION -+* BTIF Rx interrupt enable/disable -+* PARAMETERS -+* p_base [IN] BTIF module's base address -+* enable [IN] control if rx interrupt enabled or not -+* RETURNS -+* 0 means success, negative means fail -+*****************************************************************************/ -+static int hal_btif_rx_ier_ctrl(P_MTK_BTIF_INFO_STR p_btif, bool en); -+ -+/***************************************************************************** -+* FUNCTION -+* hal_btif_tx_ier_ctrl -+* DESCRIPTION -+* BTIF Tx interrupt enable/disable -+* PARAMETERS -+* p_base [IN] BTIF module's base address -+* enable [IN] control if tx interrupt enabled or not -+* RETURNS -+* 0 means success, negative means fail -+*****************************************************************************/ -+static int hal_btif_tx_ier_ctrl(P_MTK_BTIF_INFO_STR p_btif, bool en); -+ -+#ifndef MTK_BTIF_MARK_UNUSED_API -+static int btif_sleep_ctrl(P_MTK_BTIF_INFO_STR p_btif, bool en); -+ -+/***************************************************************************** -+* FUNCTION -+* _btif_receive_data -+* DESCRIPTION -+* receive data from btif module in FIFO polling mode -+* PARAMETERS -+* p_base [IN] BTIF module's base address -+* p_buf [IN/OUT] pointer to rx data buffer -+* max_len [IN] max length of rx buffer -+* RETURNS -+* positive means data is available, 0 means no data available -+*****************************************************************************/ -+static int _btif_receive_data(P_MTK_BTIF_INFO_STR p_btif, -+ unsigned char *p_buf, const unsigned int max_len); -+static int btif_tx_thr_set(P_MTK_BTIF_INFO_STR p_btif, unsigned int thr_count); -+#endif -+ -+static int btif_dump_array(char *string, char *p_buf, int len) -+{ -+ unsigned int idx = 0; -+ unsigned char str[30]; -+ unsigned char *p_str; -+ -+ pr_debug("========dump %s start ========\n", string, len); -+ p_str = &str[0]; -+ for (idx = 0; idx < len; idx++, p_buf++) { -+ sprintf(p_str, "%02x ", *p_buf); -+ p_str += 3; -+ if (7 == (idx % 8)) { -+ *p_str++ = '\n'; -+ *p_str = '\0'; -+ pr_debug("%s", str); -+ p_str = &str[0]; -+ } -+ } -+ if (len % 8) { -+ *p_str++ = '\n'; -+ *p_str = '\0'; -+ pr_debug("%s", str); -+ } -+ pr_debug("========dump %s end========\n", string); -+ return 0; -+} -+ -+#if NEW_TX_HANDLING_SUPPORT -+static int _btif_tx_fifo_init(P_MTK_BTIF_INFO_STR p_btif_info) -+{ -+ int i_ret = -1; -+ -+ spin_lock_init(&(p_btif_info->tx_fifo_spinlock)); -+ -+ if (p_btif_info->p_tx_fifo == NULL) { -+ p_btif_info->p_tx_fifo = kzalloc(sizeof(struct kfifo), -+ GFP_ATOMIC); -+ if (p_btif_info->p_tx_fifo == NULL) { -+ i_ret = -ENOMEM; -+ BTIF_ERR_FUNC("kzalloc for p_btif->p_tx_fifo failed\n"); -+ goto ret; -+ } -+ -+ i_ret = kfifo_alloc(p_btif_info->p_tx_fifo, -+ BTIF_HAL_TX_FIFO_SIZE, GFP_ATOMIC); -+ if (i_ret != 0) { -+ BTIF_ERR_FUNC("kfifo_alloc failed, errno(%d)\n", i_ret); -+ i_ret = -ENOMEM; -+ goto ret; -+ } -+ i_ret = 0; -+ } else { -+ BTIF_WARN_FUNC -+ ("p_btif_info->p_tx_fifo is already init p_btif_info->p_tx_fifo(0x%p)\n", -+ p_btif_info->p_tx_fifo); -+ i_ret = 0; -+ } -+ret: -+ return i_ret; -+} -+ -+static int _get_btif_tx_fifo_room(P_MTK_BTIF_INFO_STR p_btif_info) -+{ -+ int i_ret = 0; -+ unsigned long flag = 0; -+ -+ spin_lock_irqsave(&(p_btif_info->tx_fifo_spinlock), flag); -+ if (p_btif_info->p_tx_fifo == NULL) -+ i_ret = 0; -+ else -+ i_ret = kfifo_avail(p_btif_info->p_tx_fifo); -+ spin_unlock_irqrestore(&(p_btif_info->tx_fifo_spinlock), flag); -+ BTIF_DBG_FUNC("tx kfifo:0x%p, available room:%d\n", p_btif_info->p_tx_fifo, i_ret); -+ return i_ret; -+} -+ -+static int _btif_tx_fifo_reset(P_MTK_BTIF_INFO_STR p_btif_info) -+{ -+ int i_ret = 0; -+ -+ if (p_btif_info->p_tx_fifo != NULL) -+ kfifo_reset(p_btif_info->p_tx_fifo); -+ return i_ret; -+} -+ -+#endif -+ -+#ifdef CONFIG_OF -+static void _btif_set_default_setting(void) -+{ -+ struct device_node *node = NULL; -+ unsigned int irq_info[3] = {0, 0, 0}; -+ unsigned int phy_base; -+ -+ node = of_find_compatible_node(NULL, NULL, "mediatek,btif"); -+ if (node) { -+ mtk_btif.p_irq->irq_id = irq_of_parse_and_map(node, 0); -+ /*fixme, be compitable arch 64bits*/ -+ mtk_btif.base = (unsigned long)of_iomap(node, 0); -+ BTIF_INFO_FUNC("get btif irq(%d),register base(0x%lx)\n", -+ mtk_btif.p_irq->irq_id, mtk_btif.base); -+ } else { -+ BTIF_ERR_FUNC("get btif device node fail\n"); -+ } -+ -+ /* get the interrupt line behaviour */ -+ if (of_property_read_u32_array(node, "interrupts", irq_info, ARRAY_SIZE(irq_info))) { -+ BTIF_ERR_FUNC("get interrupt flag from DTS fail\n"); -+ } else { -+ mtk_btif.p_irq->irq_flags = irq_info[2]; -+ BTIF_INFO_FUNC("get interrupt flag(0x%x)\n", mtk_btif.p_irq->irq_flags); -+ } -+ -+ if (of_property_read_u32_index(node, "reg", 1, &phy_base)) -+ BTIF_ERR_FUNC("get register phy base from DTS fail\n"); -+ else -+ BTIF_INFO_FUNC("get register phy base(0x%x)\n", (unsigned int)phy_base); -+} -+#endif -+ -+/***************************************************************************** -+* FUNCTION -+* hal_btif_info_get -+* DESCRIPTION -+* get btif's information included base address , irq related information -+* PARAMETERS -+* RETURNS -+* BTIF's information -+*****************************************************************************/ -+P_MTK_BTIF_INFO_STR hal_btif_info_get(void) -+{ -+#if NEW_TX_HANDLING_SUPPORT -+ int i_ret = 0; -+/*tx fifo and fifo lock init*/ -+ i_ret = _btif_tx_fifo_init(&mtk_btif); -+ if (i_ret == 0) -+ BTIF_INFO_FUNC("_btif_tx_fifo_init succeed\n"); -+ else -+ BTIF_ERR_FUNC("_btif_tx_fifo_init failed, i_ret:%d\n", i_ret); -+ -+#endif -+ -+#ifdef CONFIG_OF -+ _btif_set_default_setting(); -+#endif -+ -+ spin_lock_init(&g_clk_cg_spinlock); -+ -+ return &mtk_btif; -+} -+/***************************************************************************** -+* FUNCTION -+* hal_btif_clk_get_and_prepare -+* DESCRIPTION -+* get clock from device tree and prepare for enable/disable control -+* PARAMETERS -+* pdev device pointer -+* RETURNS -+* 0 means success, negative means fail -+*****************************************************************************/ -+#if !defined(CONFIG_MTK_CLKMGR) -+int hal_btif_clk_get_and_prepare(struct platform_device *pdev) -+{ -+ int i_ret = -1; -+ -+ clk_btif = devm_clk_get(&pdev->dev, "btifc"); -+ if (IS_ERR(clk_btif)) { -+ BTIF_ERR_FUNC("[CCF]cannot get clk_btif clock.\n"); -+ return PTR_ERR(clk_btif); -+ } -+ BTIF_ERR_FUNC("[CCF]clk_btif=%p\n", clk_btif); -+ clk_btif_apdma = devm_clk_get(&pdev->dev, "apdmac"); -+ if (IS_ERR(clk_btif_apdma)) { -+ BTIF_ERR_FUNC("[CCF]cannot get clk_btif_apdma clock.\n"); -+ return PTR_ERR(clk_btif_apdma); -+ } -+ BTIF_ERR_FUNC("[CCF]clk_btif_apdma=%p\n", clk_btif_apdma); -+ -+ i_ret = clk_prepare(clk_btif); -+ if (i_ret != 0) { -+ BTIF_ERR_FUNC("clk_prepare clk_btif failed! ret:%d\n", i_ret); -+ return i_ret; -+ } -+ -+ i_ret = clk_prepare(clk_btif_apdma); -+ if (i_ret != 0) { -+ BTIF_ERR_FUNC("clk_prepare clk_btif_apdma failed! ret:%d\n", i_ret); -+ return i_ret; -+ } -+ return i_ret; -+} -+/***************************************************************************** -+* FUNCTION -+* hal_btif_clk_unprepare -+* DESCRIPTION -+* unprepare btif clock and apdma clock -+* PARAMETERS -+* none -+* RETURNS -+* 0 means success, negative means fail -+*****************************************************************************/ -+int hal_btif_clk_unprepare(void) -+{ -+ clk_unprepare(clk_btif); -+ clk_unprepare(clk_btif_apdma); -+ return 0; -+} -+#endif -+/***************************************************************************** -+* FUNCTION -+* hal_btif_clk_ctrl -+* DESCRIPTION -+* control clock output enable/disable of BTIF module -+* PARAMETERS -+* p_base [IN] BTIF module's base address -+* RETURNS -+* 0 means success, negative means fail -+*****************************************************************************/ -+int hal_btif_clk_ctrl(P_MTK_BTIF_INFO_STR p_btif, ENUM_CLOCK_CTRL flag) -+{ -+/*In MTK BTIF, there's only one global CG on AP_DMA, no sub channel's CG bit*/ -+/*according to Artis's comment, clock of DMA and BTIF is default off, so we assume it to be off by default*/ -+ int i_ret = 0; -+ unsigned long irq_flag = 0; -+ -+#if MTK_BTIF_ENABLE_CLK_REF_COUNTER -+ static atomic_t s_clk_ref = ATOMIC_INIT(0); -+#else -+ static ENUM_CLOCK_CTRL status = CLK_OUT_DISABLE; -+#endif -+ -+ spin_lock_irqsave(&(g_clk_cg_spinlock), irq_flag); -+ -+#if MTK_BTIF_ENABLE_CLK_CTL -+ -+#if MTK_BTIF_ENABLE_CLK_REF_COUNTER -+ -+ if (flag == CLK_OUT_ENABLE) { -+ if (atomic_inc_return(&s_clk_ref) == 1) { -+#if defined(CONFIG_MTK_CLKMGR) -+ i_ret = enable_clock(MTK_BTIF_CG_BIT, BTIF_USER_ID); -+#else -+ BTIF_DBG_FUNC("[CCF]enable clk_btif\n"); -+ i_ret = clk_enable(clk_btif); -+#endif /* defined(CONFIG_MTK_CLKMGR) */ -+ if (i_ret) { -+ BTIF_WARN_FUNC -+ ("enable_clock for MTK_BTIF_CG_BIT failed, ret:%d", -+ i_ret); -+ } -+ } -+ } else if (flag == CLK_OUT_DISABLE) { -+ if (atomic_dec_return(&s_clk_ref) == 0) { -+#if defined(CONFIG_MTK_CLKMGR) -+ i_ret = disable_clock(MTK_BTIF_CG_BIT, BTIF_USER_ID); -+ if (i_ret) { -+ BTIF_WARN_FUNC -+ ("disable_clock for MTK_BTIF_CG_BIT failed, ret:%d", -+ i_ret); -+ } -+#else -+ BTIF_DBG_FUNC("[CCF] clk_disable(clk_btif) calling\n"); -+ clk_disable(clk_btif); -+#endif /* defined(CONFIG_MTK_CLKMGR) */ -+ } -+ } else { -+ i_ret = ERR_INVALID_PAR; -+ BTIF_ERR_FUNC("invalid clock ctrl flag (%d)\n", flag); -+ } -+ -+#else -+ -+ if (status == flag) { -+ i_ret = 0; -+ BTIF_DBG_FUNC("btif clock already %s\n", -+ CLK_OUT_ENABLE == -+ status ? "enabled" : "disabled"); -+ } else { -+ if (flag == CLK_OUT_ENABLE) { -+#if defined(CONFIG_MTK_CLKMGR) -+ i_ret = enable_clock(MTK_BTIF_CG_BIT, BTIF_USER_ID); -+#else -+ BTIF_DBG_FUNC("[CCF]enable clk_btif\n"); -+ i_ret = clk_enable(clk_btif); -+#endif /* defined(CONFIG_MTK_CLKMGR) */ -+ status = (i_ret == 0) ? flag : status; -+ if (i_ret) { -+ BTIF_WARN_FUNC -+ ("enable_clock for MTK_BTIF_CG_BIT failed, ret:%d", -+ i_ret); -+ } -+ } else if (flag == CLK_OUT_DISABLE) { -+#if defined(CONFIG_MTK_CLKMGR) -+ i_ret = disable_clock(MTK_BTIF_CG_BIT, BTIF_USER_ID); -+ status = (i_ret == 0) ? flag : status; -+ if (i_ret) { -+ BTIF_WARN_FUNC -+ ("disable_clock for MTK_BTIF_CG_BIT failed, ret:%d", -+ i_ret); -+ } -+#else -+ BTIF_DBG_FUNC("[CCF] clk_disable(clk_btif) calling\n"); -+ clk_disable(clk_btif); -+#endif /* defined(CONFIG_MTK_CLKMGR) */ -+ } else { -+ i_ret = ERR_INVALID_PAR; -+ BTIF_ERR_FUNC("invalid clock ctrl flag (%d)\n", flag); -+ } -+ } -+#endif -+ -+#else -+ -+#if MTK_BTIF_ENABLE_CLK_REF_COUNTER -+ -+#else -+ -+ status = flag; -+#endif -+ -+ i_ret = 0; -+#endif -+ -+ spin_unlock_irqrestore(&(g_clk_cg_spinlock), irq_flag); -+ -+#if MTK_BTIF_ENABLE_CLK_REF_COUNTER -+ if (i_ret == 0) { -+ BTIF_DBG_FUNC("btif clock %s\n", flag == CLK_OUT_ENABLE ? "enabled" : "disabled"); -+ } else { -+ BTIF_ERR_FUNC("%s btif clock failed, ret(%d)\n", -+ flag == CLK_OUT_ENABLE ? "enable" : "disable", i_ret); -+ } -+#else -+ -+ if (i_ret == 0) { -+ BTIF_DBG_FUNC("btif clock %s\n", flag == CLK_OUT_ENABLE ? "enabled" : "disabled"); -+ } else { -+ BTIF_ERR_FUNC("%s btif clock failed, ret(%d)\n", -+ flag == CLK_OUT_ENABLE ? "enable" : "disable", i_ret); -+ } -+#endif -+#if defined(CONFIG_MTK_CLKMGR) -+ BTIF_DBG_FUNC("BTIF's clock is %s\n", (clock_is_on(MTK_BTIF_CG_BIT) == 0) ? "off" : "on"); -+#endif -+ return i_ret; -+} -+ -+static int btif_new_handshake_ctrl(P_MTK_BTIF_INFO_STR p_btif, bool enable) -+{ -+ unsigned long base = p_btif->base; -+ -+ if (enable == true) -+ BTIF_SET_BIT(BTIF_HANDSHAKE(base), BTIF_HANDSHAKE_EN_HANDSHAKE); -+ else -+ BTIF_CLR_BIT(BTIF_HANDSHAKE(base), BTIF_HANDSHAKE_EN_HANDSHAKE); -+ return true; -+} -+ -+/***************************************************************************** -+* FUNCTION -+* hal_btif_hw_init -+* DESCRIPTION -+* BTIF hardware init -+* PARAMETERS -+* p_base [IN] BTIF module's base address -+* RETURNS -+* 0 means success, negative means fail -+*****************************************************************************/ -+int hal_btif_hw_init(P_MTK_BTIF_INFO_STR p_btif) -+{ -+/*Chaozhong: To be implement*/ -+ int i_ret = -1; -+ unsigned long base = p_btif->base; -+ -+#if NEW_TX_HANDLING_SUPPORT -+ _btif_tx_fifo_reset(p_btif); -+#endif -+ -+/*set to normal mode*/ -+ btif_reg_sync_writel(BTIF_FAKELCR_NORMAL_MODE, BTIF_FAKELCR(base)); -+/*set to newhandshake mode*/ -+ btif_new_handshake_ctrl(p_btif, true); -+/*No need to access: enable sleep mode*/ -+/*No need to access: set Rx timeout count*/ -+/*set Tx threshold*/ -+/*set Rx threshold*/ -+/*disable internal loopback test*/ -+ -+/*set Rx FIFO clear bit to 1*/ -+ BTIF_SET_BIT(BTIF_FIFOCTRL(base), BTIF_FIFOCTRL_CLR_RX); -+/*clear Rx FIFO clear bit to 0*/ -+ BTIF_CLR_BIT(BTIF_FIFOCTRL(base), BTIF_FIFOCTRL_CLR_RX); -+/*set Tx FIFO clear bit to 1*/ -+ BTIF_SET_BIT(BTIF_FIFOCTRL(base), BTIF_FIFOCTRL_CLR_TX); -+/*clear Tx FIFO clear bit to 0*/ -+ BTIF_CLR_BIT(BTIF_FIFOCTRL(base), BTIF_FIFOCTRL_CLR_TX); -+ -+ btif_reg_sync_writel(BTIF_TRI_LVL_TX(p_btif->tx_tri_lvl) -+ | BTIF_TRI_LVL_RX(p_btif->rx_tri_lvl) -+ | BTIF_TRI_LOOP_DIS, BTIF_TRI_LVL(base)); -+ hal_btif_loopback_ctrl(p_btif, false); -+/*disable BTIF Tx DMA mode*/ -+ hal_btif_tx_mode_ctrl(p_btif, false); -+/*disable BTIF Rx DMA mode*/ -+ hal_btif_rx_mode_ctrl(p_btif, false); -+/*auto reset*/ -+ BTIF_SET_BIT(BTIF_DMA_EN(base), BTIF_DMA_EN_AUTORST_EN); -+/*disable Tx IER*/ -+ hal_btif_tx_ier_ctrl(p_btif, false); -+/*enable Rx IER by default*/ -+ hal_btif_rx_ier_ctrl(p_btif, true); -+ -+ i_ret = 0; -+ return i_ret; -+} -+ -+/***************************************************************************** -+* FUNCTION -+* hal_btif_rx_ier_ctrl -+* DESCRIPTION -+* BTIF Rx interrupt enable/disable -+* PARAMETERS -+* p_base [IN] BTIF module's base address -+* enable [IN] control if rx interrupt enabled or not -+* RETURNS -+* 0 means success, negative means fail -+*****************************************************************************/ -+int hal_btif_rx_ier_ctrl(P_MTK_BTIF_INFO_STR p_btif, bool en) -+{ -+ int i_ret = -1; -+ unsigned long base = p_btif->base; -+ -+ if (en == false) -+ BTIF_CLR_BIT(BTIF_IER(base), BTIF_IER_RXFEN); -+ else -+ BTIF_SET_BIT(BTIF_IER(base), BTIF_IER_RXFEN); -+ -+/*TODO:do we need to read back ? Answer: no*/ -+ i_ret = 0; -+ return i_ret; -+} -+ -+/***************************************************************************** -+* FUNCTION -+* hal_btif_tx_ier_ctrl -+* DESCRIPTION -+* BTIF Tx interrupt enable/disable -+* PARAMETERS -+* p_base [IN] BTIF module's base address -+* enable [IN] control if tx interrupt enabled or not -+* RETURNS -+* 0 means success, negative means fail -+*****************************************************************************/ -+int hal_btif_tx_ier_ctrl(P_MTK_BTIF_INFO_STR p_btif, bool en) -+{ -+ int i_ret = -1; -+ unsigned long base = p_btif->base; -+ -+ if (en == false) -+ BTIF_CLR_BIT(BTIF_IER(base), BTIF_IER_TXEEN); -+ else -+ BTIF_SET_BIT(BTIF_IER(base), BTIF_IER_TXEEN); -+ -+/*TODO:do we need to read back ? Answer: no*/ -+ i_ret = 0; -+ -+ return i_ret; -+} -+ -+#ifndef MTK_BTIF_MARK_UNUSED_API -+ -+/***************************************************************************** -+* FUNCTION -+* _btif_receive_data -+* DESCRIPTION -+* receive data from btif module in FIFO polling mode -+* PARAMETERS -+* p_base [IN] BTIF module's base address -+* p_buf [IN/OUT] pointer to rx data buffer -+* max_len [IN] max length of rx buffer -+* RETURNS -+* positive means data is available, 0 means no data available -+*****************************************************************************/ -+int _btif_receive_data(P_MTK_BTIF_INFO_STR p_btif, -+ unsigned char *p_buf, const unsigned int max_len) -+{ -+/*Chaozhong: To be implement*/ -+ int i_ret = -1; -+ -+/*check parameter valid or not*/ -+ if ((p_buf == NULL) || (max_len == 0)) { -+ i_ret = ERR_INVALID_PAR; -+ return i_ret; -+ } -+ i_ret = btif_rx_irq_handler(p_btif, p_buf, max_len); -+ -+ return i_ret; -+} -+ -+int btif_sleep_ctrl(P_MTK_BTIF_INFO_STR p_btif, bool en) -+{ -+ int i_ret = -1; -+ unsigned long base = p_btif->base; -+ -+ if (en == false) -+ BTIF_CLR_BIT(BTIF_SLEEP_EN(base), BTIF_SLEEP_EN_BIT); -+ else -+ BTIF_SET_BIT(BTIF_SLEEP_EN(base), BTIF_SLEEP_EN_BIT); -+ -+/*TODO:do we need to read back ? Answer: no*/ -+/*TODO:do we need to dsb?*/ -+ i_ret = 0; -+ return i_ret; -+} -+ -+static int btif_tx_thr_set(P_MTK_BTIF_INFO_STR p_btif, unsigned int thr_count) -+{ -+ int i_ret = -1; -+ unsigned long base = p_btif->base; -+ unsigned int value = 0; -+ -+/*read BTIF_TRI_LVL*/ -+ value = BTIF_READ32(BTIF_TRI_LVL(base)); -+/*clear Tx threshold bits*/ -+ value &= (~BTIF_TRI_LVL_TX_MASK); -+/*set tx threshold bits*/ -+ value |= BTIF_TRI_LVL_TX(BTIF_TX_FIFO_THRE); -+/*write back to BTIF_TRI_LVL*/ -+ btif_reg_sync_writel(value, BTIF_TRI_LVL(base)); -+ -+ return i_ret; -+} -+ -+/***************************************************************************** -+* FUNCTION -+* btif_rx_fifo_reset -+* DESCRIPTION -+* reset BTIF's rx fifo -+* PARAMETERS -+* p_base [IN] BTIF module's base address -+* ec [IN] control if loopback mode is enabled or not -+* RETURNS -+* 0 means success, negative means fail -+*****************************************************************************/ -+static int btif_rx_fifo_reset(P_MTK_BTIF_INFO_STR p_btif) -+{ -+/*Chaozhong: To be implement*/ -+ int i_ret = -1; -+ unsigned long base = p_btif->base; -+ -+/*set Rx FIFO clear bit to 1*/ -+ BTIF_SET_BIT(BTIF_FIFOCTRL(base), BTIF_FIFOCTRL_CLR_RX); -+ -+/*clear Rx FIFO clear bit to 0*/ -+ BTIF_CLR_BIT(BTIF_FIFOCTRL(base), BTIF_FIFOCTRL_CLR_RX); -+ -+/*TODO:do we need to read back ? Answer: no*/ -+/*TODO:do we need to dsb?*/ -+ i_ret = 0; -+ return i_ret; -+} -+ -+/***************************************************************************** -+* FUNCTION -+* btif_tx_fifo_reset -+* DESCRIPTION -+* reset BTIF's tx fifo -+* PARAMETERS -+* p_base [IN] BTIF module's base address -+* RETURNS -+* 0 means success, negative means fail -+*****************************************************************************/ -+static int btif_tx_fifo_reset(P_MTK_BTIF_INFO_STR p_btif) -+{ -+ int i_ret = -1; -+ unsigned long base = p_btif->base; -+ -+/*set Tx FIFO clear bit to 1*/ -+ BTIF_SET_BIT(BTIF_FIFOCTRL(base), BTIF_FIFOCTRL_CLR_TX); -+ -+/*clear Tx FIFO clear bit to 0*/ -+ BTIF_CLR_BIT(BTIF_FIFOCTRL(base), BTIF_FIFOCTRL_CLR_TX); -+ -+/*TODO:do we need to read back ? Answer: no*/ -+/*TODO:do we need to dsb?*/ -+ i_ret = 0; -+ return i_ret; -+} -+ -+#endif -+ -+/***************************************************************************** -+* FUNCTION -+* hal_btif_loopback_ctrl -+* DESCRIPTION -+* BTIF Tx/Rx loopback mode set, this operation can only be done after set BTIF to normal mode -+* PARAMETERS -+* RETURNS -+* 0 means success, negative means fail -+*****************************************************************************/ -+int hal_btif_loopback_ctrl(P_MTK_BTIF_INFO_STR p_btif, bool en) -+{ -+ int i_ret = -1; -+ unsigned long base = p_btif->base; -+ -+ if (en == false) -+ BTIF_CLR_BIT(BTIF_TRI_LVL(base), BTIF_TRI_LOOP_EN); -+ else -+ BTIF_SET_BIT(BTIF_TRI_LVL(base), BTIF_TRI_LOOP_EN); -+ -+/*TODO:do we need to read back ? Answer: no*/ -+/*TODO:do we need to dsb?*/ -+ i_ret = 0; -+ return i_ret; -+} -+ -+ -+/***************************************************************************** -+* FUNCTION -+* hal_btif_rx_handler -+* DESCRIPTION -+* lower level interrupt handler -+* PARAMETERS -+* p_base [IN] BTIF module's base address -+* p_buf [IN/OUT] pointer to rx data buffer -+* max_len [IN] max length of rx buffer -+* RETURNS -+* 0 means success; negative means fail; positive means rx data length -+*****************************************************************************/ -+int hal_btif_irq_handler(P_MTK_BTIF_INFO_STR p_btif, -+ unsigned char *p_buf, const unsigned int max_len) -+{ -+/*Chaozhong: To be implement*/ -+ int i_ret = -1; -+ unsigned int iir = 0; -+ unsigned int rx_len = 0; -+ unsigned long base = p_btif->base; -+ -+#if 0 -+/*check parameter valid or not*/ -+ if ((p_buf == NULL) || (max_len == 0)) { -+ i_ret = ERR_INVALID_PAR; -+ return i_ret; -+ } -+#endif -+ unsigned long irq_flag = 0; -+ -+ spin_lock_irqsave(&(g_clk_cg_spinlock), irq_flag); -+ -+#if defined(CONFIG_MTK_CLKMGR) -+ if (clock_is_on(MTK_BTIF_CG_BIT) == 0) { -+ spin_unlock_irqrestore(&(g_clk_cg_spinlock), irq_flag); -+ BTIF_ERR_FUNC("%s: clock is off before irq handle done!!!\n", -+ __FILE__); -+ return i_ret; -+ } -+#endif -+/*read interrupt identifier register*/ -+ iir = BTIF_READ32(BTIF_IIR(base)); -+ -+/*is rx interrupt exist?*/ -+#if 0 -+ while ((iir & BTIF_IIR_RX) && (rx_len < max_len)) { -+ rx_len += -+ btif_rx_irq_handler(p_btif, (p_buf + rx_len), -+ (max_len - rx_len)); -+ -+/*update IIR*/ -+ iir = BTIF_READ32(BTIF_IIR(base)); -+ } -+#endif -+ -+ while (iir & (BTIF_IIR_RX | BTIF_IIR_RX_TIMEOUT)) { -+ rx_len += btif_rx_irq_handler(p_btif, p_buf, max_len); -+ -+/*update IIR*/ -+ iir = BTIF_READ32(BTIF_IIR(base)); -+ } -+ -+/*is tx interrupt exist?*/ -+ if (iir & BTIF_IIR_TX_EMPTY) -+ i_ret = btif_tx_irq_handler(p_btif); -+ spin_unlock_irqrestore(&(g_clk_cg_spinlock), irq_flag); -+ -+ i_ret = rx_len != 0 ? rx_len : i_ret; -+ return i_ret; -+} -+ -+int hal_btif_rx_cb_reg(P_MTK_BTIF_INFO_STR p_btif_info, btif_rx_buf_write rx_cb) -+{ -+ if (p_btif_info->rx_cb != NULL) -+ BTIF_DBG_FUNC("rx_cb already registered, replace (0x%p) with (0x%p)\n", -+ p_btif_info->rx_cb, rx_cb); -+ p_btif_info->rx_cb = rx_cb; -+ -+ return 0; -+} -+ -+/***************************************************************************** -+* FUNCTION -+* btif_rx_irq_handler -+* DESCRIPTION -+* lower level rx interrupt handler -+* PARAMETERS -+* p_base [IN] BTIF module's base address -+* RETURNS -+* positive means length of rx data , negative means fail -+*****************************************************************************/ -+static int btif_rx_irq_handler(P_MTK_BTIF_INFO_STR p_btif_info, -+ unsigned char *p_buf, const unsigned int max_len) -+{ -+/*Chaozhong: To be implement*/ -+ int i_ret = 0; -+ unsigned int iir = 0; -+ unsigned int rx_len = 0; -+ unsigned long base = p_btif_info->base; -+ unsigned char rx_buf[256]; -+ unsigned int local_buf_len = 256; -+ btif_rx_buf_write rx_cb = p_btif_info->rx_cb; -+ unsigned int total_len = 0; -+ -+/*read interrupt identifier register*/ -+ iir = BTIF_READ32(BTIF_IIR(base)); -+ while ((iir & (BTIF_IIR_RX | BTIF_IIR_RX_TIMEOUT)) && -+ (rx_len < local_buf_len)) { -+ rx_buf[rx_len] = BTIF_READ8(base); -+ rx_len++; -+/*need to consult CC Hwang for advice */ -+/* -+ * whether we need to do memory barrier here -+ * Ans: no -+ */ -+/* -+ * whether we need to d memory barrier when call BTIF_SET_BIT or BTIF_CLR_BIT -+ * Ans: no -+ */ -+ if (rx_len == local_buf_len) { -+ if (rx_cb) -+ (*rx_cb) (p_btif_info, rx_buf, rx_len); -+ rx_len = 0; -+ total_len += rx_len; -+ } -+ iir = BTIF_READ32(BTIF_IIR(base)); -+ } -+ total_len += rx_len; -+ if (rx_len && rx_cb) -+ (*rx_cb) (p_btif_info, rx_buf, rx_len); -+ -+/* -+ * make sure all data write back to memory, mb or dsb? -+ * need to consult CC Hwang for advice -+ * Ans: no need here -+ */ -+ i_ret = total_len; -+ return i_ret; -+} -+ -+/***************************************************************************** -+* FUNCTION -+* btif_tx_irq_handler -+* DESCRIPTION -+* lower level tx interrupt handler -+* PARAMETERS -+* p_base [IN] BTIF module's base address -+* p_buf [IN/OUT] pointer to rx data buffer -+* max_len [IN] max length of rx buffer -+* RETURNS -+* 0 means success, negative means fail -+*****************************************************************************/ -+static int btif_tx_irq_handler(P_MTK_BTIF_INFO_STR p_btif) -+{ -+ int i_ret = -1; -+ -+#if NEW_TX_HANDLING_SUPPORT -+ int how_many = 0; -+ unsigned int lsr; -+ unsigned int ava_len = 0; -+ unsigned long base = p_btif->base; -+ char local_buf[BTIF_TX_FIFO_SIZE]; -+ char *p_data = local_buf; -+ unsigned long flag = 0; -+ -+ struct kfifo *p_tx_fifo = p_btif->p_tx_fifo; -+ -+/*read LSR and check THER or TEMT, either one is 1 means can accept tx data*/ -+ lsr = BTIF_READ32(BTIF_LSR(base)); -+ -+ if (lsr & BTIF_LSR_TEMT_BIT) -+ /*Tx Holding Register if empty, which means we can write tx FIFO count to BTIF*/ -+ ava_len = BTIF_TX_FIFO_SIZE; -+ else if (lsr & BTIF_LSR_THRE_BIT) -+ /*Tx Holding Register if empty, which means we can write (Tx FIFO count - Tx threshold)to BTIF*/ -+ ava_len = BTIF_TX_FIFO_SIZE - BTIF_TX_FIFO_THRE; -+ else { -+ /*this means data size in tx FIFO is more than Tx threshold, we will not write data to THR*/ -+ ava_len = 0; -+ goto ret; -+ } -+ spin_lock_irqsave(&(p_btif->tx_fifo_spinlock), flag); -+ how_many = kfifo_out(p_tx_fifo, local_buf, ava_len); -+ spin_unlock_irqrestore(&(p_btif->tx_fifo_spinlock), flag); -+ BTIF_DBG_FUNC("BTIF tx size %d done, left:%d\n", how_many, -+ kfifo_avail(p_tx_fifo)); -+ while (how_many--) -+ btif_reg_sync_writeb(*(p_data++), BTIF_THR(base)); -+ -+ spin_lock_irqsave(&(p_btif->tx_fifo_spinlock), flag); -+/*clear Tx enable flag if necessary*/ -+ if (kfifo_is_empty(p_tx_fifo)) { -+ hal_btif_tx_ier_ctrl(p_btif, false); -+ BTIF_DBG_FUNC("BTIF tx FIFO is empty\n"); -+ } -+ spin_unlock_irqrestore(&(p_btif->tx_fifo_spinlock), flag); -+ret: -+#else -+/*clear Tx enable flag*/ -+ hal_btif_tx_ier_ctrl(p_btif, false); -+#endif -+ i_ret = 0; -+ return i_ret; -+} -+ -+/***************************************************************************** -+* FUNCTION -+* hal_btif_tx_mode_ctrl -+* DESCRIPTION -+* set BTIF tx to corresponding mode (PIO/DMA) -+* PARAMETERS -+* p_base [IN] BTIF module's base address -+* mode [IN] rx mode -+* RETURNS -+* 0 means success, negative means fail -+*****************************************************************************/ -+int hal_btif_tx_mode_ctrl(P_MTK_BTIF_INFO_STR p_btif, ENUM_BTIF_MODE mode) -+{ -+ int i_ret = -1; -+ unsigned long base = p_btif->base; -+ -+ if (mode == BTIF_MODE_DMA) -+ /*set to DMA mode*/ -+ BTIF_SET_BIT(BTIF_DMA_EN(base), BTIF_DMA_EN_TX); -+ else -+ /*set to PIO mode*/ -+ BTIF_CLR_BIT(BTIF_DMA_EN(base), BTIF_DMA_EN_TX); -+ -+ i_ret = 0; -+ return i_ret; -+} -+ -+/***************************************************************************** -+* FUNCTION -+* hal_btif_rx_mode_ctrl -+* DESCRIPTION -+* set BTIF rx to corresponding mode (PIO/DMA) -+* PARAMETERS -+* p_base [IN] BTIF module's base address -+* mode [IN] rx mode -+* RETURNS -+* 0 means success, negative means fail -+*****************************************************************************/ -+int hal_btif_rx_mode_ctrl(P_MTK_BTIF_INFO_STR p_btif, ENUM_BTIF_MODE mode) -+{ -+ int i_ret = -1; -+ unsigned long base = p_btif->base; -+ -+ if (mode == BTIF_MODE_DMA) -+ /*set to DMA mode*/ -+ BTIF_SET_BIT(BTIF_DMA_EN(base), BTIF_DMA_EN_RX); -+ else -+ /*set to PIO mode*/ -+ BTIF_CLR_BIT(BTIF_DMA_EN(base), BTIF_DMA_EN_RX); -+ -+ i_ret = 0; -+ return i_ret; -+} -+ -+/***************************************************************************** -+* FUNCTION -+* hal_btif_send_data -+* DESCRIPTION -+* send data through btif in FIFO mode -+* PARAMETERS -+* p_base [IN] BTIF module's base address -+* p_buf [IN] pointer to rx data buffer -+* max_len [IN] tx buffer length -+* RETURNS -+* positive means number of data sent; 0 means no data put to FIFO; negative means error happens -+*****************************************************************************/ -+int hal_btif_send_data(P_MTK_BTIF_INFO_STR p_btif, -+ const unsigned char *p_buf, const unsigned int buf_len) -+{ -+/*Chaozhong: To be implement*/ -+ int i_ret = -1; -+ -+ unsigned int ava_len = 0; -+ unsigned int sent_len = 0; -+ -+#if !(NEW_TX_HANDLING_SUPPORT) -+ unsigned long base = p_btif->base; -+ unsigned int lsr = 0; -+ unsigned int left_len = 0; -+ unsigned char *p_data = (unsigned char *)p_buf; -+#endif -+ -+/*check parameter valid or not*/ -+ if ((p_buf == NULL) || (buf_len == 0)) { -+ i_ret = ERR_INVALID_PAR; -+ return i_ret; -+ } -+#if NEW_TX_HANDLING_SUPPORT -+ ava_len = _get_btif_tx_fifo_room(p_btif); -+ sent_len = buf_len <= ava_len ? buf_len : ava_len; -+ if (sent_len > 0) { -+ int enqueue_len = 0; -+ unsigned long flag = 0; -+ -+ spin_lock_irqsave(&(p_btif->tx_fifo_spinlock), flag); -+ enqueue_len = kfifo_in(p_btif->p_tx_fifo, -+ (unsigned char *)p_buf, sent_len); -+ if (sent_len != enqueue_len) { -+ BTIF_ERR_FUNC("target tx len:%d, len sent:%d\n", -+ sent_len, enqueue_len); -+ } -+ i_ret = enqueue_len; -+ mb(); -+/*enable BTIF Tx IRQ*/ -+ hal_btif_tx_ier_ctrl(p_btif, true); -+ spin_unlock_irqrestore(&(p_btif->tx_fifo_spinlock), flag); -+ BTIF_DBG_FUNC("enqueue len:%d\n", enqueue_len); -+ } else { -+ i_ret = 0; -+ } -+#else -+ while ((_btif_is_tx_allow(p_btif)) && (sent_len < buf_len)) { -+ /*read LSR and check THER or TEMT, either one is 1 means can accept tx data*/ -+ lsr = BTIF_READ32(BTIF_LSR(base)); -+ -+ if (lsr & BTIF_LSR_TEMT_BIT) -+ /*Tx Holding Register if empty, which means we can write tx FIFO count to BTIF*/ -+ ava_len = BTIF_TX_FIFO_SIZE; -+ else if (lsr & BTIF_LSR_THRE_BIT) -+ /*Tx Holding Register if empty, which means we can write (Tx FIFO count - Tx threshold)to BTIF*/ -+ ava_len = BTIF_TX_FIFO_SIZE - BTIF_TX_FIFO_THRE; -+ else { -+ /*this means data size in tx FIFO is more than Tx threshold, we will not write data to THR*/ -+ ava_len = 0; -+ break; -+ } -+ -+ left_len = buf_len - sent_len; -+/*ava_len will be real length will write to BTIF THR*/ -+ ava_len = ava_len > left_len ? left_len : ava_len; -+/*update sent length valud after this operation*/ -+ sent_len += ava_len; -+/* -+ * whether we need memory barrier here? -+ * Ans: No, no memory ordering issue exist, -+ * CPU will make sure logically right -+ */ -+ while (ava_len--) -+ btif_reg_sync_writeb(*(p_data++), BTIF_THR(base)); -+ -+ } -+/* while ((hal_btif_is_tx_allow()) && (sent_len < buf_len)); */ -+ -+ i_ret = sent_len; -+ -+/*enable BTIF Tx IRQ*/ -+ hal_btif_tx_ier_ctrl(p_btif, true); -+#endif -+ return i_ret; -+} -+ -+ -+/***************************************************************************** -+* FUNCTION -+* hal_btif_raise_wak_sig -+* DESCRIPTION -+* raise wakeup signal to counterpart -+* PARAMETERS -+* p_base [IN] BTIF module's base address -+* RETURNS -+* 0 means success, negative means fail -+*****************************************************************************/ -+int hal_btif_raise_wak_sig(P_MTK_BTIF_INFO_STR p_btif) -+{ -+ int i_ret = -1; -+ unsigned long base = p_btif->base; -+#if defined(CONFIG_MTK_CLKMGR) -+ if (clock_is_on(MTK_BTIF_CG_BIT) == 0) { -+ BTIF_ERR_FUNC("%s: clock is off before send wakeup signal!!!\n", -+ __FILE__); -+ return i_ret; -+ } -+#endif -+/*write 0 to BTIF_WAK to pull ap_wakeup_consyss low */ -+ BTIF_CLR_BIT(BTIF_WAK(base), BTIF_WAK_BIT); -+ -+/*wait for a period for longer than 1/32k period, here we use 40us*/ -+ set_current_state(TASK_UNINTERRUPTIBLE); -+ usleep_range(128, 160); -+/* -+ * according to linux/documentation/timers/timers-how-to, we choose usleep_range -+ * SLEEPING FOR ~USECS OR SMALL MSECS ( 10us - 20ms): * Use usleep_range -+ */ -+/*write 1 to pull ap_wakeup_consyss high*/ -+ BTIF_SET_BIT(BTIF_WAK(base), BTIF_WAK_BIT); -+ i_ret = 0; -+ return i_ret; -+} -+ -+/***************************************************************************** -+* FUNCTION -+* hal_btif_dump_reg -+* DESCRIPTION -+* dump BTIF module's information when needed -+* PARAMETERS -+* p_base [IN] BTIF module's base address -+* flag [IN] register id flag -+* RETURNS -+* 0 means success, negative means fail -+*****************************************************************************/ -+int hal_btif_dump_reg(P_MTK_BTIF_INFO_STR p_btif, ENUM_BTIF_REG_ID flag) -+{ -+/*Chaozhong: To be implement*/ -+ int i_ret = -1; -+ int idx = 0; -+ /*unsigned long irq_flag = 0;*/ -+ unsigned long base = p_btif->base; -+ unsigned char reg_map[0xE0 / 4] = { 0 }; -+ unsigned int lsr = 0x0; -+ unsigned int dma_en = 0; -+ -+ /*spin_lock_irqsave(&(g_clk_cg_spinlock), irq_flag);*/ -+#if defined(CONFIG_MTK_CLKMGR) -+ if (clock_is_on(MTK_BTIF_CG_BIT) == 0) { -+ /*spin_unlock_irqrestore(&(g_clk_cg_spinlock), irq_flag);*/ -+ BTIF_ERR_FUNC("%s: clock is off, this should never happen!!!\n", -+ __FILE__); -+ return i_ret; -+ } -+#endif -+ lsr = BTIF_READ32(BTIF_LSR(base)); -+ dma_en = BTIF_READ32(BTIF_DMA_EN(base)); -+ /* -+ * here we omit 1st register which is THR/RBR register to avoid -+ * Rx data read by this debug information accidently -+ */ -+ for (idx = 1; idx < sizeof(reg_map); idx++) -+ reg_map[idx] = BTIF_READ8(p_btif->base + (4 * idx)); -+ /*spin_unlock_irqrestore(&(g_clk_cg_spinlock), irq_flag);*/ -+ BTIF_INFO_FUNC("BTIF's clock is on\n"); -+ BTIF_INFO_FUNC("base address: 0x%lx\n", base); -+ switch (flag) { -+ case REG_BTIF_ALL: -+#if 0 -+ BTIF_INFO_FUNC("BTIF_IER:0x%x\n", BTIF_READ32(BTIF_IER(base))); -+ BTIF_INFO_FUNC("BTIF_IIR:0x%x\n", BTIF_READ32(BTIF_IIR(base))); -+ BTIF_INFO_FUNC("BTIF_FAKELCR:0x%x\n", -+ BTIF_READ32(BTIF_FAKELCR(base))); -+ BTIF_INFO_FUNC("BTIF_LSR:0x%x\n", BTIF_READ32(BTIF_LSR(base))); -+ BTIF_INFO_FUNC("BTIF_SLEEP_EN:0x%x\n", -+ BTIF_READ32(BTIF_SLEEP_EN(base))); -+ BTIF_INFO_FUNC("BTIF_DMA_EN:0x%x\n", -+ BTIF_READ32(BTIF_DMA_EN(base))); -+ BTIF_INFO_FUNC("BTIF_RTOCNT:0x%x\n", -+ BTIF_READ32(BTIF_RTOCNT(base))); -+ BTIF_INFO_FUNC("BTIF_TRI_LVL:0x%x\n", -+ BTIF_READ32(BTIF_TRI_LVL(base))); -+ BTIF_INFO_FUNC("BTIF_WAT_TIME:0x%x\n", -+ BTIF_READ32(BTIF_WAT_TIME(base))); -+ BTIF_INFO_FUNC("BTIF_HANDSHAKE:0x%x\n", -+ BTIF_READ32(BTIF_HANDSHAKE(base))); -+#endif -+ btif_dump_array("BTIF register", reg_map, sizeof(reg_map)); -+ break; -+ default: -+ break; -+ } -+ -+ BTIF_INFO_FUNC("Tx DMA %s\n", -+ (dma_en & BTIF_DMA_EN_TX) ? "enabled" : "disabled"); -+ BTIF_INFO_FUNC("Rx DMA %s\n", -+ (dma_en & BTIF_DMA_EN_RX) ? "enabled" : "disabled"); -+ -+ BTIF_INFO_FUNC("Rx data is %s\n", -+ (lsr & BTIF_LSR_DR_BIT) ? "not empty" : "empty"); -+ BTIF_INFO_FUNC("Tx data is %s\n", -+ (lsr & BTIF_LSR_TEMT_BIT) ? "empty" : "not empty"); -+ -+ return i_ret; -+} -+ -+/***************************************************************************** -+* FUNCTION -+* hal_btif_is_tx_complete -+* DESCRIPTION -+* get tx complete flag -+* PARAMETERS -+* p_base [IN] BTIF module's base address -+* RETURNS -+* true means tx complete, false means tx in process -+*****************************************************************************/ -+bool hal_btif_is_tx_complete(P_MTK_BTIF_INFO_STR p_btif) -+{ -+/*Chaozhong: To be implement*/ -+ bool b_ret = false; -+ unsigned int lsr = 0; -+ unsigned long flags = 0; -+ unsigned long base = p_btif->base; -+ unsigned int tx_empty = 0; -+ unsigned int rx_dr = 0; -+ unsigned int tx_irq_disable = 0; -+ -+/* -+ * 3 conditions allow clock to be disable -+ * 1. if TEMT is set or not -+ * 2. if DR is set or not -+ * 3. Tx IRQ is disabled or not -+ */ -+ lsr = BTIF_READ32(BTIF_LSR(base)); -+ tx_empty = lsr & BTIF_LSR_TEMT_BIT; -+ rx_dr = lsr & BTIF_LSR_DR_BIT; -+ tx_irq_disable = BTIF_READ32(BTIF_IER(base)) & BTIF_IER_TXEEN; -+ -+ b_ret = -+ (tx_empty && (tx_irq_disable == 0) && (rx_dr == 0)) ? true : false; -+ if (!b_ret) { -+ BTIF_DBG_FUNC -+ ("BTIF flag, tx_empty:%d, rx_dr:%d, tx_irq_disable:%d\n", -+ tx_empty, rx_dr, tx_irq_disable); -+ } -+#if NEW_TX_HANDLING_SUPPORT -+ spin_lock_irqsave(&(p_btif->tx_fifo_spinlock), flags); -+/*clear Tx enable flag if necessary*/ -+ if (!(kfifo_is_empty(p_btif->p_tx_fifo))) { -+ BTIF_DBG_FUNC("BTIF tx FIFO is not empty\n"); -+ b_ret = false; -+ } -+ spin_unlock_irqrestore(&(p_btif->tx_fifo_spinlock), flags); -+#endif -+ return b_ret; -+} -+ -+/***************************************************************************** -+* FUNCTION -+* hal_btif_is_tx_allow -+* DESCRIPTION -+* whether tx is allowed -+* PARAMETERS -+* p_base [IN] BTIF module's base address -+* RETURNS -+* true if tx operation is allowed; false if tx is not allowed -+*****************************************************************************/ -+bool hal_btif_is_tx_allow(P_MTK_BTIF_INFO_STR p_btif) -+{ -+#define MIN_TX_MB ((26 * 1000000 / 13) / 1000000) -+#define AVE_TX_MB ((26 * 1000000 / 8) / 1000000) -+ -+/*Chaozhong: To be implement*/ -+ bool b_ret = false; -+ -+#if NEW_TX_HANDLING_SUPPORT -+ unsigned long flags = 0; -+ -+ spin_lock_irqsave(&(p_btif->tx_fifo_spinlock), flags); -+/*clear Tx enable flag if necessary*/ -+ if (kfifo_is_full(p_btif->p_tx_fifo)) { -+ BTIF_WARN_FUNC("BTIF tx FIFO is full\n"); -+ b_ret = false; -+ } else { -+ b_ret = true; -+ } -+ spin_unlock_irqrestore(&(p_btif->tx_fifo_spinlock), flags); -+#else -+ unsigned int lsr = 0; -+ unsigned long base = p_btif->base; -+ unsigned int wait_us = (BTIF_TX_FIFO_SIZE - BTIF_TX_FIFO_THRE) / MIN_TX_MB; /*only ava length */ -+ -+/*read LSR and check THER or TEMT, either one is 1 means can accept tx data*/ -+ lsr = BTIF_READ32(BTIF_LSR(base)); -+ -+ if (!(lsr & (BTIF_LSR_TEMT_BIT | BTIF_LSR_THRE_BIT))) { -+ BTIF_DBG_FUNC("wait for %d ~ %d us\n", wait_us, 3 * wait_us); -+/* usleep_range(wait_us, 3 * 10 * wait_us); */ -+ usleep_range(wait_us, 3 * wait_us); -+ } -+ lsr = BTIF_READ32(BTIF_LSR(base)); -+ b_ret = (lsr & (BTIF_LSR_TEMT_BIT | BTIF_LSR_THRE_BIT)) ? true : false; -+ if (!b_ret) -+ BTIF_DBG_FUNC(" tx is not allowed for the moment\n"); -+ else -+ BTIF_DBG_FUNC(" tx is allowed\n"); -+#endif -+ return b_ret; -+} -+ -+#if !(NEW_TX_HANDLING_SUPPORT) -+ -+static bool _btif_is_tx_allow(P_MTK_BTIF_INFO_STR p_btif) -+{ -+/*Chaozhong: To be implement*/ -+ bool b_ret = false; -+ unsigned long base = p_btif->base; -+ unsigned int lsr = 0; -+ -+/*read LSR and check THER or TEMT, either one is 1 means can accept tx data*/ -+ lsr = BTIF_READ32(BTIF_LSR(base)); -+ b_ret = (lsr & (BTIF_LSR_TEMT_BIT | BTIF_LSR_THRE_BIT)) ? true : false; -+ return b_ret; -+} -+#endif -+ -+int hal_btif_pm_ops(P_MTK_BTIF_INFO_STR p_btif_info, MTK_BTIF_PM_OPID opid) -+{ -+ int i_ret = -1; -+ -+ BTIF_DBG_FUNC("op id: %d\n", opid); -+ switch (opid) { -+ case BTIF_PM_DPIDLE_EN: -+ i_ret = 0; -+ break; -+ case BTIF_PM_DPIDLE_DIS: -+ i_ret = 0; -+ break; -+ case BTIF_PM_SUSPEND: -+ i_ret = 0; -+ break; -+ case BTIF_PM_RESUME: -+ i_ret = 0; -+ break; -+ case BTIF_PM_RESTORE_NOIRQ:{ -+ unsigned int flag = 0; -+ P_MTK_BTIF_IRQ_STR p_irq = p_btif_info->p_irq; -+ -+#ifdef CONFIG_OF -+ flag = p_irq->irq_flags; -+#else -+ switch (p_irq->sens_type) { -+ case IRQ_SENS_EDGE: -+ if (p_irq->edge_type == IRQ_EDGE_FALL) -+ flag = IRQF_TRIGGER_FALLING; -+ else if (p_irq->edge_type == IRQ_EDGE_RAISE) -+ flag = IRQF_TRIGGER_RISING; -+ else if (p_irq->edge_type == IRQ_EDGE_BOTH) -+ flag = IRQF_TRIGGER_RISING | -+ IRQF_TRIGGER_FALLING; -+ else -+ flag = IRQF_TRIGGER_FALLING; /*make this as default type */ -+ break; -+ case IRQ_SENS_LVL: -+ if (p_irq->lvl_type == IRQ_LVL_LOW) -+ flag = IRQF_TRIGGER_LOW; -+ else if (p_irq->lvl_type == IRQ_LVL_HIGH) -+ flag = IRQF_TRIGGER_HIGH; -+ else -+ flag = IRQF_TRIGGER_LOW; /*make this as default type */ -+ break; -+ default: -+ flag = IRQF_TRIGGER_LOW; /*make this as default type */ -+ break; -+ } -+#endif -+/* irq_set_irq_type(p_irq->irq_id, flag); */ -+ i_ret = 0; -+ } -+ break; -+ default: -+ i_ret = ERR_INVALID_PAR; -+ break; -+ } -+ -+ return i_ret; -+} -+void mtk_btif_read_cpu_sw_rst_debug_plat(void) -+{ -+#define CONSYS_AP2CONN_WAKEUP_OFFSET 0x00000064 -+ BTIF_WARN_FUNC("+CONSYS_AP2CONN_WAKEUP_OFFSET(0x%x)\n", -+ BTIF_READ32(mtk_btif.base + CONSYS_AP2CONN_WAKEUP_OFFSET)); -+} -+ -diff --git a/drivers/misc/mediatek/btif/common/inc/mtk_btif.h b/drivers/misc/mediatek/btif/common/inc/mtk_btif.h -new file mode 100644 -index 000000000000..5e2f5a9857d9 ---- /dev/null -+++ b/drivers/misc/mediatek/btif/common/inc/mtk_btif.h -@@ -0,0 +1,370 @@ -+/* -+ * Copyright (C) 2015 MediaTek Inc. -+ * -+ * 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. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#ifndef __MTK_BTIF_H_ -+#define __MTK_BTIF_H_ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include /* gettimeofday */ -+#include -+ -+#include "btif_pub.h" -+#include "btif_dma_pub.h" -+#include "mtk_btif_exp.h" -+ -+#define BTIF_PORT_NR 1 -+#define BTIF_USER_NAME_MAX_LEN 32 -+ -+/*-------------Register Defination Start ---------------*/ -+#if (defined(CONFIG_MTK_GMO_RAM_OPTIMIZE) && !defined(CONFIG_MTK_ENG_BUILD)) -+#define BTIF_RX_BUFFER_SIZE (1024 * 32) -+#else -+#define BTIF_RX_BUFFER_SIZE (1024 * 64) -+#endif -+#define BTIF_TX_FIFO_SIZE (1024 * 4) -+ -+/*------------Register Defination End ----------------*/ -+ -+/*------------BTIF Module Clock and Power Control Defination---------------*/ -+typedef enum _ENUM_BTIF_RX_TYPE_ { -+ BTIF_IRQ_CTX = 0, -+ BTIF_TASKLET_CTX = BTIF_IRQ_CTX + 1, -+ BTIF_THREAD_CTX = BTIF_TASKLET_CTX + 1, -+ BTIF_WQ_CTX = BTIF_THREAD_CTX + 1, -+ BTIF_RX_TYPE_MAX, -+} ENUM_BTIF_RX_TYPE; -+ -+typedef enum _ENUM_BTIF_TX_TYPE_ { -+ BTIF_TX_USER_CTX = 0, -+ BTIF_TX_SINGLE_CTX = BTIF_TX_USER_CTX + 1, -+ BTIF_TX_TYPE_MAX, -+} ENUM_BTIF_TX_TYPE; -+ -+typedef enum _ENUM_BTIF_STATE_ { -+ B_S_OFF = 0, -+ B_S_SUSPEND = B_S_OFF + 1, -+ B_S_DPIDLE = B_S_SUSPEND + 1, -+ B_S_ON = B_S_DPIDLE + 1, -+ B_S_MAX, -+} ENUM_BTIF_STATE; -+ -+#define ENABLE_BTIF_RX_DMA 1 -+#define ENABLE_BTIF_TX_DMA 1 -+ -+#if ENABLE_BTIF_TX_DMA -+#define BTIF_TX_MODE BTIF_MODE_DMA -+#else -+#define BTIF_TX_MODE BTIF_MODE_PIO -+#endif -+ -+#if ENABLE_BTIF_RX_DMA -+#define BTIF_RX_MODE BTIF_MODE_DMA -+#else -+#define BTIF_RX_MODE BTIF_MODE_PIO -+#endif -+ -+#define BTIF_RX_BTM_CTX BTIF_THREAD_CTX/*BTIF_WQ_CTX*//* BTIF_TASKLET_CTX */ -+/* -+ * -- cannot be used because , -+ * mtk_wcn_stp_parser data will call *(stp_if_tx) to send ack, -+ * in which context sleepable lock or usleep operation may be used, -+ * these operation is not allowed in tasklet, may cause schedule_bug -+ */ -+ -+#define BTIF_TX_CTX BTIF_TX_USER_CTX /* BTIF_TX_SINGLE_CTX */ -+ -+#define ENABLE_BTIF_RX_THREAD_RT_SCHED 0 -+#define MAX_BTIF_RXD_TIME_REC 3 -+ -+/*Structure Defination*/ -+ -+/*-----------------BTIF setting--------------*/ -+typedef struct _mtk_btif_setting_ { -+ ENUM_BTIF_MODE tx_mode; /*BTIF Tx Mode Setting */ -+ ENUM_BTIF_MODE rx_mode; /*BTIF Tx Mode Setting */ -+ ENUM_BTIF_RX_TYPE rx_type; /*rx handle type */ -+ ENUM_BTIF_TX_TYPE tx_type; /*tx type */ -+} mtk_btif_setting, *p_mtk_btif_setting; -+/*---------------------------------------------------------------------------*/ -+ -+#if 0 -+/*---------------------------------------------------------------------------*/ -+typedef struct _mtk_btif_register_ { -+ unsigned int iir; /*Interrupt Identification Register */ -+ unsigned int lsr; /*Line Status Register */ -+ unsigned int fake_lcr; /*Fake Lcr Regiseter */ -+ unsigned int fifo_ctrl; /*FIFO Control Register */ -+ unsigned int ier; /*Interrupt Enable Register */ -+ unsigned int sleep_en; /*Sleep Enable Register */ -+ unsigned int rto_counter; /*Rx Timeout Counter Register */ -+ unsigned int dma_en; /*DMA Enalbe Register */ -+ unsigned int tri_lvl; /*Tx/Rx Trigger Level Register */ -+ unsigned int wat_time; /*Async Wait Time Register */ -+ unsigned int handshake; /*New HandShake Mode Register */ -+ unsigned int sleep_wak; /*Sleep Wakeup Reigster */ -+} mtk_btif_register, *p_mtk_btif_register; -+/*---------------------------------------------------------------------------*/ -+ -+#endif -+ -+typedef struct _btif_buf_str_ { -+ unsigned int size; -+ unsigned char *p_buf; -+ /* -+ * For Tx: next Tx data pointer to FIFO; -+ * For Rx: next read data pointer from BTIF user -+ */ -+ unsigned int rd_idx; -+ /* -+ * For Tx: next Tx data pointer from BTIF user; -+ * For Rx: next write data(from FIFO) pointer -+ */ -+ unsigned int wr_idx; -+} btif_buf_str, *p_btif_buf_str; -+ -+/*---------------------------------------------------------------------------*/ -+typedef struct _mtk_btif_dma_ { -+ /*p_mtk_btif*/ void *p_btif; -+ /*BTIF pointer to which DMA belongs */ -+ -+#if 0 -+ unsigned int channel; /*DMA's channel */ -+#endif -+ -+ ENUM_BTIF_DIR dir; /*DMA's direction: */ -+ bool enable; /*DMA enable or disable flag */ -+ -+ P_MTK_DMA_INFO_STR p_dma_info; /*DMA's IRQ information */ -+ -+#if 0 -+ mtk_dma_register register; /*DMA's register */ -+#endif -+ -+ spinlock_t iolock; /*io lock for DMA channel */ -+ atomic_t entry; /* entry count */ -+} mtk_btif_dma, *p_mtk_btif_dma; -+ -+#if (defined(CONFIG_MTK_GMO_RAM_OPTIMIZE) && !defined(CONFIG_MTK_ENG_BUILD)) -+#define BTIF_LOG_ENTRY_NUM 10 -+#else -+#define BTIF_LOG_ENTRY_NUM 30 -+#endif -+ -+#define BTIF_LOG_SZ 1536 -+ -+typedef void (*MTK_BTIF_RX_NOTIFY) (void); -+ -+typedef struct _btif_log_buf_t_ { -+ unsigned int len; -+ struct timeval timer; -+ unsigned char buffer[BTIF_LOG_SZ]; -+} BTIF_LOG_BUF_T, *P_BTIF_LOG_BUF_T; -+ -+typedef struct _btif_log_queue_t_ { -+ ENUM_BTIF_DIR dir; -+ bool enable; -+ bool output_flag; -+ unsigned int in; -+ unsigned int out; -+ unsigned int size; -+ spinlock_t lock; -+ P_BTIF_LOG_BUF_T p_queue[BTIF_LOG_ENTRY_NUM]; -+} BTIF_LOG_QUEUE_T, *P_BTIF_LOG_QUEUE_T; -+ -+/*---------------------------------------------------------------------------*/ -+typedef struct _mtk_btif_ { -+ unsigned int open_counter; /*open counter */ -+ bool enable; /*BTIF module enable flag */ -+ bool lpbk_flag; /*BTIF module enable flag */ -+#if 0 -+ unsigned long base; /* BTIF controller base address */ -+#endif -+ -+ ENUM_BTIF_STATE state; /*BTIF state mechanism */ -+ struct mutex state_mtx; /*lock to BTIF state mechanism's state change */ -+ struct mutex ops_mtx; /*lock to BTIF's open and close */ -+ -+#if 0 -+ mtk_btif_register register; /*BTIF registers */ -+#endif -+ -+ ENUM_BTIF_MODE tx_mode; /* BTIF Tx channel mode */ -+ ENUM_BTIF_MODE rx_mode; /* BTIF Rx channel mode */ -+ struct mutex tx_mtx; /*lock to BTIF's tx process */ -+/*rx handling */ -+ ENUM_BTIF_RX_TYPE btm_type; /*BTIF Rx bottom half context */ -+/*tx handling*/ -+ ENUM_BTIF_TX_TYPE tx_ctx; /*BTIF tx context */ -+/* unsigned char rx_buf[BTIF_RX_BUFFER_SIZE]; */ -+ btif_buf_str btif_buf; -+ spinlock_t rx_irq_spinlock; /*lock for rx irq handling */ -+ -+/*rx workqueue information*/ -+ /*lock to BTIF's rx bottom half when kernel thread is used */ -+ struct mutex rx_mtx; -+ struct workqueue_struct *p_rx_wq; -+ struct work_struct rx_work; -+ -+ struct workqueue_struct *p_tx_wq; -+ struct work_struct tx_work; -+ struct kfifo *p_tx_fifo; -+ -+/*rx tasklet information*/ -+ struct tasklet_struct rx_tasklet; -+ /*lock to BTIF's rx bottom half when tasklet is used */ -+ spinlock_t rx_tasklet_spinlock; -+ -+/*rx thread information*/ -+ struct task_struct *p_task; -+ struct completion rx_comp; -+ -+ mtk_btif_setting *setting; /*BTIF setting */ -+ -+ p_mtk_btif_dma p_tx_dma; /*BTIF Tx channel DMA */ -+ p_mtk_btif_dma p_rx_dma; /*BTIF Rx channel DMA */ -+ -+ MTK_WCN_BTIF_RX_CB rx_cb; /*Rx callback function */ -+ MTK_BTIF_RX_NOTIFY rx_notify; -+ -+ P_MTK_BTIF_INFO_STR p_btif_info; /*BTIF's information */ -+ -+/*Log Tx data to buffer*/ -+ BTIF_LOG_QUEUE_T tx_log; -+ -+/*Log Rx data to buffer*/ -+ BTIF_LOG_QUEUE_T rx_log; -+ -+/* struct list_head *p_user_list; */ -+ struct list_head user_list; -+/* get btif dev pointer*/ -+ void *private_data; -+} mtk_btif, *p_mtk_btif; -+/*---------------------------------------------------------------------------*/ -+ -+/*---------------------------------------------------------------------------*/ -+#if 0 -+/*---------------------------------------------------------------------------*/ -+typedef struct _mtk_dma_register_ { -+ unsigned int int_flag; /*Tx offset:0x0 Rx offset:0x0 */ -+ unsigned int int_enable; /*Tx offset:0x4 Rx offset:0x4 */ -+ unsigned int dma_enable; /*Tx offset:0x8 Rx offset:0x8 */ -+ unsigned int dma_reset; /*Tx offset:0xc Rx offset:0xc */ -+ unsigned int dma_stop; /*Tx offset:0x10 Rx offset:0x10 */ -+ unsigned int dma_flush; /*Tx offset:0x14 Rx offset:0x14 */ -+ unsigned int vff_addr; /*Tx offset:0x1c Rx offset:0x1c */ -+ unsigned int vff_len; /*Tx offset:0x24 Rx offset:0x24 */ -+ unsigned int vff_thr; /*Tx offset:0x28 Rx offset:0x28 */ -+ unsigned int vff_wpt; /*Tx offset:0x2c Rx offset:0x2c */ -+ unsigned int vff_rpt; /*Tx offset:0x30 Rx offset:0x30 */ -+ unsigned int rx_fc_thr; /*Tx:No this register Rx offset:0x34 */ -+ unsigned int int_buf_size; /*Tx offset:0x38 Rx offset:0x38 */ -+ unsigned int vff_valid_size; /*Tx offset:0x3c Rx offset:0x3c */ -+ unsigned int vff_left_size; /*Tx offset:0x40 Rx offset:0x40 */ -+ unsigned int debug_status; /*Tx offset:0x50 Rx offset:0x50 */ -+} mtk_dma_register, *p_mtk_dma_register; -+/*---------------------------------------------------------------------------*/ -+#endif -+ -+/*---------------------------------------------------------------------------*/ -+typedef struct _mtk_btif_user_ { -+ bool enable; /*register its state */ -+ struct list_head entry; /*btif_user's bi-direction list table */ -+ /*BTIF's user, static allocation */ -+ char u_name[BTIF_USER_NAME_MAX_LEN]; -+ unsigned long u_id; -+ p_mtk_btif p_btif; -+} mtk_btif_user, *p_mtk_btif_user; -+ -+/*---------------------------------------------------------------------------*/ -+#define BBS_PTR(ptr, idx) ((ptr->p_buf) + idx) -+ -+#define BBS_SIZE(ptr) ((ptr)->size) -+#define BBS_MASK(ptr) (BBS_SIZE(ptr) - 1) -+#define BBS_COUNT(ptr) ((ptr)->wr_idx >= (ptr)->rd_idx ? (ptr)->wr_idx - \ -+(ptr)->rd_idx : BBS_SIZE(ptr) - \ -+((ptr)->rd_idx - (ptr)->wr_idx)) -+#define BBS_COUNT_CUR(ptr, wr_idx) (wr_idx >= (ptr)->rd_idx ? wr_idx - \ -+(ptr)->rd_idx : BBS_SIZE(ptr) - \ -+((ptr)->rd_idx - wr_idx)) -+ -+#define BBS_LEFT(ptr) (BBS_SIZE(ptr) - BBS_COUNT(ptr)) -+ -+#define BBS_AVL_SIZE(ptr) (BBS_SIZE(ptr) - BBS_COUNT(ptr)) -+#define BBS_FULL(ptr) (BBS_COUNT(ptr) - BBS_SIZE(ptr)) -+#define BBS_EMPTY(ptr) ((ptr)->wr_idx == (ptr)->rd_idx) -+#define BBS_WRITE_MOVE_NEXT(ptr) ((ptr)->wr_idx = \ -+((ptr)->wr_idx + 1) & BBS_MASK(ptr)) -+#define BBS_READ_MOVE_NEXT(ptr) ((ptr)->rd_idx = \ -+((ptr)->rd_idx + 1) & BBS_MASK(ptr)) -+ -+#define BBS_INIT(ptr) \ -+{ \ -+(ptr)->rd_idx = (ptr)->wr_idx = 0; \ -+(ptr)->size = BTIF_RX_BUFFER_SIZE; \ -+} -+ -+ -+#define BTIF_MUTEX_UNLOCK(x) mutex_unlock(x) -+ -+extern mtk_btif g_btif[]; -+ -+int btif_open(p_mtk_btif p_btif); -+int btif_close(p_mtk_btif p_btif); -+int btif_send_data(p_mtk_btif p_btif, -+ const unsigned char *p_buf, unsigned int buf_len); -+int btif_enter_dpidle(p_mtk_btif p_btif); -+int btif_exit_dpidle(p_mtk_btif p_btif); -+int btif_rx_cb_reg(p_mtk_btif p_btif, MTK_WCN_BTIF_RX_CB rx_cb); -+ -+/*for test purpose*/ -+int _btif_suspend(p_mtk_btif p_btif); -+int _btif_resume(p_mtk_btif p_btif); -+int _btif_restore_noirq(p_mtk_btif p_btif); -+ -+int btif_lpbk_ctrl(p_mtk_btif p_btif, bool flag); -+int btif_log_buf_dmp_in(P_BTIF_LOG_QUEUE_T p_log_que, const char *p_buf, -+ int len); -+int btif_dump_data(char *p_buf, int len); -+int btif_log_buf_dmp_out(P_BTIF_LOG_QUEUE_T p_log_que); -+int btif_log_buf_enable(P_BTIF_LOG_QUEUE_T p_log_que); -+int btif_log_buf_disable(P_BTIF_LOG_QUEUE_T p_log_que); -+int btif_log_output_enable(P_BTIF_LOG_QUEUE_T p_log_que); -+int btif_log_output_disable(P_BTIF_LOG_QUEUE_T p_log_que); -+int btif_log_buf_reset(P_BTIF_LOG_QUEUE_T p_log_que); -+int btif_log_buf_init(p_mtk_btif p_btif); -+int btif_dump_reg(p_mtk_btif p_btif); -+int btif_rx_notify_reg(p_mtk_btif p_btif, MTK_BTIF_RX_NOTIFY rx_notify); -+int btif_raise_wak_signal(p_mtk_btif p_btif); -+int btif_clock_ctrl(p_mtk_btif p_btif, int en); -+bool btif_parser_wmt_evt(p_mtk_btif p_btif, -+ const char *sub_str, -+ unsigned int sub_len); -+void mtk_btif_read_cpu_sw_rst_debug(void); -+ -+#endif /*__MTK_BTIF_H_*/ -diff --git a/drivers/misc/mediatek/btif/common/inc/mtk_btif_exp.h b/drivers/misc/mediatek/btif/common/inc/mtk_btif_exp.h -new file mode 100644 -index 000000000000..3752644fe0aa ---- /dev/null -+++ b/drivers/misc/mediatek/btif/common/inc/mtk_btif_exp.h -@@ -0,0 +1,280 @@ -+/* -+ * Copyright (C) 2015 MediaTek Inc. -+ * -+ * 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. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#ifndef _MTK_BTIF_EXP_H_ -+#define _MTK_BTIF_EXP_H_ -+ -+/*--------------marco defination---------------*/ -+#define BTIF_MAX_LEN_PER_PKT 2048 -+#define BTIF_RXD_BE_BLOCKED_DETECT 1 -+/*--------------Enum Defination---------------*/ -+typedef enum _ENUM_BTIF_DPIDLE_ { -+ BTIF_DPIDLE_DISABLE = 0, -+ BTIF_DPIDLE_ENABLE = BTIF_DPIDLE_DISABLE + 1, -+ BTIF_DPIDLE_MAX, -+} ENUM_BTIF_DPIDLE_CTRL; -+ -+typedef enum _ENUM_BTIF_LPBK_MODE_ { -+ BTIF_LPBK_DISABLE = 0, -+ BTIF_LPBK_ENABLE = BTIF_LPBK_DISABLE + 1, -+ BTIF_LPBK_MAX, -+} ENUM_BTIF_LPBK_MODE; -+ -+typedef enum _ENUM_BTIF_DBG_ID_ { -+ BTIF_DISABLE_LOGGER = 0, -+ BTIF_ENABLE_LOGGER = BTIF_DISABLE_LOGGER + 1, -+ BTIF_DUMP_LOG = BTIF_ENABLE_LOGGER + 1, -+ BTIF_CLR_LOG = BTIF_DUMP_LOG + 1, -+ BTIF_DUMP_BTIF_REG = BTIF_CLR_LOG + 1, -+ BTIF_ENABLE_RT_LOG = BTIF_DUMP_BTIF_REG + 1, -+ BTIF_DISABLE_RT_LOG = BTIF_ENABLE_RT_LOG + 1, -+ BTIF_DBG_MAX, -+} ENUM_BTIF_DBG_ID; -+ -+typedef enum _ENUM_BTIF_OP_ERROR_CODE_ { -+ E_BTIF_AGAIN = 0, -+ E_BTIF_FAIL = -1, -+ E_BTIF_BAD_POINTER = -2, -+ E_BTIF_NO_SPACE = -3, -+ E_BTIF_INTR = -4, -+ E_BTIF_INVAL_PARAM = -5, -+ E_BTIF_ALREADY_OPEN = -6, -+ E_BTIF_NOT_OPEN = -7, -+ E_BTIF_INVAL_STATE = -8, -+} ENUM_BTIF_OP_ERROR_CODE; -+ -+/*--------------End of Enum Defination---------------*/ -+ -+/*--------------Type Definition---------------*/ -+ -+typedef int (*MTK_WCN_BTIF_RX_CB) (const unsigned char *p_buf, -+ unsigned int len); -+ -+/*--------------End of Type Definition---------------*/ -+ -+/*--------------Normal Mode API declearation---------------*/ -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_btif_open -+* DESCRIPTION -+* open BTIF interface, will do BTIF module HW and SW initialization -+* PARAMETERS -+* p_owner [IN] pointer to owner who call this API, -+* currently there are 2 owner ("stp" or "btif_tester") -+* may use this module -+* user's id string must be less than 32 bytes -+* for "stp", BTIF will call rx callback function to route rx data to STP module -+* for "stp_tester", BTIF will save rx data -+* and wait for native process to access -+* p_id [IN] BTIF's user id will be put to this address -+* RETURNS -+* int 0 = succeed; others = fail, for detailed information, -+* please see ENUM_BTIF_OP_ERROR_CODE -+* if open success, value p_id will be the only identifier for -+* user to access BTIF's other operations -+* including read/write/dpidle_ctrl/rx_cb_retister -+* this user id is only an identifier used for owner identification -+*****************************************************************************/ -+int mtk_wcn_btif_open(char *p_owner, unsigned long *p_id); -+//EXPORT_SYMBOL(mtk_wcn_btif_open) -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_btif_close -+* DESCRIPTION -+* close BTIF interface, will do BTIF module HW and SW de-initialization -+* once this API is called, p_btif should never be used by BTIF's user again -+* PARAMETERS -+* u_id [IN] BTIF's user id -+* RETURNS -+* int 0 = succeed; -+* others = fail, for detailed information, please see ENUM_BTIF_OP_ERROR_CODE -+*****************************************************************************/ -+int mtk_wcn_btif_close(unsigned long u_id); -+//EXPORT_SYMBOL(mtk_wcn_btif_close) -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_btif_write -+* DESCRIPTION -+* send data throuth BTIF module -+* there's no internal buffer to cache STP data in BTIF driver, -+* if in DMA mode -+* btif driver will check if there's enough space -+* in vFIFO for data to send in DMA mode -+* if yes, put data to vFIFO and return corresponding data length to caller -+* if no, corresponding error code will be returned to called -+* PARAMETERS -+* p_btif [IN] pointer returned by mtk_wcn_btif_open -+* p_buf [IN] pointer to target data to send -+* len [IN] data length (should be less than 2014 bytes per STP package) -+* -+* if in non-DMA mode, BTIF driver will try to write to THR of BTIF controller -+* if btif driver detected that no space is available in Tx FIFO, -+* will return E_BTIF_NO_SPACE, -+* mostly something is wrong with BTIF or consys when this -+* return value is returned -+* RETURNS -+* int positive: data length send through BTIF; -+* negative: please see ENUM_BTIF_OP_ERROR_CODE -+* E_BTIF_AGAIN (0) will be returned to caller if btif does not have -+* enough vFIFO to send data, when caller get 0, -+* he should wait for a moment (5~10ms maybe) and -+* try a few times (maybe 10~20) -+* if still get E_BTIF_AGAIN, should call BTIF's debug API and -+* dump BTIF driver and BTIF/DMA register information to kernel log -+* for debug -+* E_BTIF_BAD_POINTER will be returned to caller if btif is not -+* opened successfully before call this API -+* E_BTIF_INVAL_PARAM will be returned if parameter is not valid -+ -+*****************************************************************************/ -+int mtk_wcn_btif_write(unsigned long u_id, -+ const unsigned char *p_buf, unsigned int len); -+//EXPORT_SYMBOL(mtk_wcn_btif_write) -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_btif_read -+* DESCRIPTION -+* read data from BTIF module -+* PARAMETERS -+* p_btif [IN] pointer returned by mtk_wcn_btif_open -+* p_buf [IN/OUT] pointer to buffer where rx data will be put -+* max_len [IN] max buffer length -+* RETURNS -+* int positive: data length read from BTIF; -+* negative: please see ENUM_BTIF_OP_ERROR_CODE -+*****************************************************************************/ -+int mtk_wcn_btif_read(unsigned long u_id, -+ unsigned char *p_buf, unsigned int max_len); -+//EXPORT_SYMBOL(mtk_wcn_btif_read) -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_btif_dpidle_ctrl -+* DESCRIPTION -+* control if BTIF module allow system enter deepidle state or not -+* PARAMETERS -+* p_btif [IN] pointer returned by mtk_wcn_btif_open -+* en_flag [IN] one of ENUM_BTIF_DPIDLE_CTRL -+* RETURNS -+* int always return 0 -+*****************************************************************************/ -+int mtk_wcn_btif_dpidle_ctrl(unsigned long u_id, ENUM_BTIF_DPIDLE_CTRL en_flag); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_btif_rx_cb_register -+* DESCRIPTION -+* register rx callback function to BTIF module by btif user -+* PARAMETERS -+* p_btif [IN] pointer returned by mtk_wcn_btif_open -+* rx_cb [IN] pointer to stp rx handler callback function, -+* should be comply with MTK_WCN_BTIF_RX_CB -+* RETURNS -+* int 0 = succeed; -+* others = fail, for detailed information, please see ENUM_BTIF_OP_ERROR_CODE -+*****************************************************************************/ -+int mtk_wcn_btif_rx_cb_register(unsigned long u_id, MTK_WCN_BTIF_RX_CB rx_cb); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_btif_wakeup_consys -+* DESCRIPTION -+* once sleep command is sent to con sys, -+* should call this API before send wakeup command to -+* make con sys aware host want to send data to consys -+* PARAMETERS -+* p_btif [IN] pointer returned by mtk_wcn_btif_open -+* RETURNS -+* int 0 = succeed; -+* others = fail, for detailed information, please see ENUM_BTIF_OP_ERROR_CODE -+*****************************************************************************/ -+int mtk_wcn_btif_wakeup_consys(unsigned long u_id); -+ -+/*--------------End of Normal Mode API declearation----------------*/ -+ -+/*--------------Debug Purpose API declearation----------------*/ -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_btif_loopback_ctrl -+* DESCRIPTION -+* enable/disable BTIF internal loopback function, -+* when this function is enabled, -+* data send to btif will be received by btif itself -+* only for debug purpose, should never use this function in normal mode -+* PARAMETERS -+* p_btif [IN] pointer returned by mtk_wcn_btif_open -+* enable [IN] loopback mode control flag, enable or disable, -+* shou be one of ENUM_BTIF_LPBK_MODE -+* RETURNS -+* int 0 = succeed; -+* others = fail, for detailed information, please see ENUM_BTIF_OP_ERROR_CODE -+*****************************************************************************/ -+int mtk_wcn_btif_loopback_ctrl(unsigned long u_id, ENUM_BTIF_LPBK_MODE enable); -+//EXPORT_SYMBOL(mtk_wcn_btif_loopback_ctrl) -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_btif_logger_ctrl -+* DESCRIPTION -+* control BTIF logger function's behavior -+* PARAMETERS -+* p_btif [IN] pointer returned by mtk_wcn_btif_open -+* flag [IN] should be one of ENUM_BTIF_DBG_ID -+* BTIF_DISABLE_LOGGER - disable btif logger -+* BTIF_ENABLE_LOGGER - enable btif logger -+* BTIF_DUMP_LOG - dump log logged by btif -+* BTIF_CLR_LOG - clear btif log buffer -+* BTIF_DUMP_BTIF_REG - dump btif controller's register -+* BTIF_DUMP_DMA_REG - dump DMA controller's register -+* RETURNS -+* int 0 = succeed; -+* others = fail, for detailed information, -+* please see ENUM_BTIF_OP_ERROR_CODE -+*****************************************************************************/ -+int mtk_wcn_btif_dbg_ctrl(unsigned long u_id, ENUM_BTIF_DBG_ID flag); -+//EXPORT_SYMBOL(mtk_wcn_btif_dbg_ctrl); -+/*-----------End of Debug Purpose API declearation------------*/ -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_btif_parser_wmt_evt -+* DESCRIPTION -+* parser wmt sleep/wakeup evt in btif bbs buffer for debug -+* PARAMETERS -+* p_btif [IN] pointer returned by mtk_wcn_btif_open -+* sub_str [IN] the str to be parsered -+* str_len [IN] the length of sub_str -+* RETURNS -+* bool true = succeed; -+* false = fail; -+*****************************************************************************/ -+bool mtk_wcn_btif_parser_wmt_evt(unsigned long u_id, -+ const char *sub_str, unsigned int str_len); -+ -+int mtk_btif_exp_open_test(void); -+int mtk_btif_exp_close_test(void); -+int mtk_btif_exp_write_test(void); -+int mtk_btif_exp_suspend_test(void); -+int mtk_btif_exp_resume_test(void); -+int mtk_btif_exp_enter_dpidle_test(void); -+int mtk_btif_exp_exit_dpidle_test(void); -+int mtk_btif_exp_write_stress_test(unsigned int length, unsigned int loop); -+int mtk_btif_exp_log_debug_test(int flag); -+int mtk_btif_exp_restore_noirq_test(void); -+int btif_wakeup_consys_no_id(void); -+int mtk_btif_exp_clock_ctrl(int en); -+#if BTIF_RXD_BE_BLOCKED_DETECT -+int mtk_btif_rxd_be_blocked_flag_get(void); -+#endif -+void mtk_btif_read_cpu_sw_rst_debug_exp(void); -+#endif /*_MTK_BTIF_EXP_H_*/ -diff --git a/drivers/misc/mediatek/btif/common/mtk_btif.c b/drivers/misc/mediatek/btif/common/mtk_btif.c -new file mode 100644 -index 000000000000..5deb64ef3e56 ---- /dev/null -+++ b/drivers/misc/mediatek/btif/common/mtk_btif.c -@@ -0,0 +1,3472 @@ -+/* -+ * Copyright (C) 2015 MediaTek Inc. -+ * -+ * 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. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+/*-----------linux system header files----------------*/ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+/*#include */ -+/*-----------driver own header files----------------*/ -+#ifdef CONFIG_COMPAT -+#include -+#endif -+#ifdef DFT_TAG -+#undef DFT_TAG -+#endif -+#define DFT_TAG "MTK-BTIF" -+ -+#define BTIF_CDEV_SUPPORT 1 -+ -+#include "btif_pub.h" -+#include "btif_dma_pub.h" -+#include "mtk_btif_exp.h" -+#include "mtk_btif.h" -+ -+/*-----------static function declearation----------------*/ -+static int mtk_btif_probe(struct platform_device *pdev); -+static int mtk_btif_remove(struct platform_device *pdev); -+static int mtk_btif_suspend(struct platform_device *pdev, pm_message_t state); -+static int mtk_btif_resume(struct platform_device *pdev); -+static int mtk_btif_drv_resume(struct device *dev); -+static int mtk_btif_drv_suspend(struct device *pdev); -+ -+static int mtk_btif_restore_noirq(struct device *device); -+static int btif_file_open(struct inode *pinode, struct file *pfile); -+static int btif_file_release(struct inode *pinode, struct file *pfile); -+static ssize_t btif_file_read(struct file *pfile, -+ char __user *buf, size_t count, loff_t *f_ops); -+static unsigned int btif_poll(struct file *filp, poll_table *wait); -+static int _btif_irq_reg(P_MTK_BTIF_IRQ_STR p_irq, -+ mtk_btif_irq_handler irq_handler, void *data); -+static int _btif_irq_free(P_MTK_BTIF_IRQ_STR p_irq, void *data); -+static int _btif_irq_ctrl(P_MTK_BTIF_IRQ_STR p_irq, bool en); -+static int _btif_irq_ctrl_sync(P_MTK_BTIF_IRQ_STR p_irq, bool en); -+static irqreturn_t btif_irq_handler(int irq, void *data); -+static unsigned int btif_pio_rx_data_receiver(P_MTK_BTIF_INFO_STR p_btif_info, -+ unsigned char *p_buf, -+ unsigned int buf_len); -+ -+static irqreturn_t btif_tx_dma_irq_handler(int irq, void *data); -+static irqreturn_t btif_rx_dma_irq_handler(int irq, void *data); -+ -+static unsigned int btif_dma_rx_data_receiver(P_MTK_DMA_INFO_STR p_dma_info, -+ unsigned char *p_buf, -+ unsigned int buf_len); -+static int _btif_controller_tx_setup(p_mtk_btif p_btif); -+static int _btif_controller_tx_free(p_mtk_btif p_btif); -+static int _btif_controller_rx_setup(p_mtk_btif p_btif); -+static int _btif_controller_rx_free(p_mtk_btif p_btif); -+static int _btif_tx_pio_setup(p_mtk_btif p_btif); -+static int _btif_rx_pio_setup(p_mtk_btif p_btif); -+static int _btif_rx_dma_setup(p_mtk_btif p_btif); -+static int _btif_rx_dma_free(p_mtk_btif p_btif); -+static int _btif_tx_dma_setup(p_mtk_btif p_btif); -+static int _btif_tx_dma_free(p_mtk_btif p_btif); -+static int _btif_controller_setup(p_mtk_btif p_btif); -+static int _btif_controller_free(p_mtk_btif p_btif); -+ -+static int _btif_pio_write(p_mtk_btif p_btif, -+ const unsigned char *p_buf, unsigned int buf_len); -+static int _btif_dma_write(p_mtk_btif p_btif, -+ const unsigned char *p_buf, unsigned int buf_len); -+ -+static unsigned int btif_bbs_wr_direct(p_btif_buf_str p_bbs, -+ unsigned char *p_buf, unsigned int buf_len); -+static unsigned int btif_bbs_read(p_btif_buf_str p_bbs, -+ unsigned char *p_buf, unsigned int buf_len); -+static unsigned int btif_bbs_write(p_btif_buf_str p_bbs, -+ unsigned char *p_buf, unsigned int buf_len); -+static void btif_dump_bbs_str(unsigned char *p_str, p_btif_buf_str p_bbs); -+static int _btif_dump_memory(char *str, unsigned char *p_buf, unsigned int buf_len); -+static int _btif_rx_btm_deinit(p_mtk_btif p_btif); -+static int _btif_rx_btm_sched(p_mtk_btif p_btif); -+static int _btif_rx_btm_init(p_mtk_btif p_btif); -+static void btif_rx_tasklet(unsigned long func_data); -+static void btif_rx_worker(struct work_struct *p_work); -+static int btif_rx_thread(void *p_data); -+static int btif_rx_data_consummer(p_mtk_btif p_btif); -+ -+static int _btif_tx_ctx_init(p_mtk_btif p_btif); -+static int _btif_tx_ctx_deinit(p_mtk_btif p_btif); -+static void btif_tx_worker(struct work_struct *p_work); -+ -+static int _btif_state_deinit(p_mtk_btif p_btif); -+static int _btif_state_release(p_mtk_btif p_btif); -+static ENUM_BTIF_STATE _btif_state_get(p_mtk_btif p_btif); -+static int _btif_state_set(p_mtk_btif p_btif, ENUM_BTIF_STATE state); -+static int _btif_state_hold(p_mtk_btif p_btif); -+static int _btif_state_init(p_mtk_btif p_btif); -+ -+static int _btif_dpidle_notify_ctrl(p_mtk_btif p_btif, -+ ENUM_BTIF_DPIDLE_CTRL en_flag); -+static int _btif_enter_dpidle(p_mtk_btif p_btif); -+static int _btif_exit_dpidle(p_mtk_btif p_btif); -+static int _btif_exit_dpidle_from_sus(p_mtk_btif p_btif); -+static int _btif_exit_dpidle_from_dpidle(p_mtk_btif p_btif); -+static int _btif_enter_dpidle_from_on(p_mtk_btif p_btif); -+static int _btif_enter_dpidle_from_sus(p_mtk_btif p_btif); -+ -+#if ENABLE_BTIF_TX_DMA -+static int _btif_vfifo_deinit(p_mtk_btif_dma p_dma); -+static int _btif_vfifo_init(p_mtk_btif_dma p_dma); -+#endif -+ -+static bool _btif_is_tx_complete(p_mtk_btif p_btif); -+static int _btif_init(p_mtk_btif p_btif); -+static int _btif_lpbk_ctrl(p_mtk_btif p_btif, bool flag); -+static int btif_rx_dma_mode_set(int en); -+static int btif_tx_dma_mode_set(int en); -+ -+static int _btif_send_data(p_mtk_btif p_btif, -+ const unsigned char *p_buf, unsigned int buf_len); -+ -+/*-----------end of static function declearation----------------*/ -+ -+static const char *g_state[B_S_MAX] = { -+ "OFF", -+ "SUSPEND", -+ "DPIDLE", -+ "ON", -+}; -+ -+/*-----------BTIF setting--------------*/ -+mtk_btif_setting g_btif_setting[BTIF_PORT_NR] = { -+ { -+ .tx_mode = BTIF_TX_MODE, -+ .rx_mode = BTIF_RX_MODE, -+ .rx_type = BTIF_RX_BTM_CTX, -+ .tx_type = BTIF_TX_CTX, -+ }, -+}; -+ -+mtk_btif g_btif[BTIF_PORT_NR] = { -+ { -+ .open_counter = 0, -+ .state = B_S_OFF, -+ .setting = &g_btif_setting[0], -+ .p_tx_dma = NULL, -+ .p_rx_dma = NULL, -+ .rx_cb = NULL, -+ .p_btif_info = NULL, -+ }, -+}; -+ -+mtk_btif_dma g_dma[BTIF_PORT_NR][BTIF_DIR_MAX] = { -+ { -+ { -+ .p_btif = NULL, -+ .dir = BTIF_TX, -+ .p_dma_info = NULL, -+ .entry = ATOMIC_INIT(0), -+ }, -+ { -+ .p_btif = NULL, -+ .dir = BTIF_RX, -+ .p_dma_info = NULL, -+ .entry = ATOMIC_INIT(0), -+ }, -+ }, -+}; -+ -+#define G_MAX_PKG_LEN (7 * 1024) -+static int g_max_pkg_len = G_MAX_PKG_LEN; /*DMA vFIFO is set to 8 * 1024, we set this to 7/8 * vFIFO size*/ -+static int g_max_pding_data_size = BTIF_RX_BUFFER_SIZE * 3 / 4; -+ -+ -+static int mtk_btif_dbg_lvl = BTIF_LOG_ERR; -+ -+#if BTIF_RXD_BE_BLOCKED_DETECT -+static struct timeval btif_rxd_time_stamp[MAX_BTIF_RXD_TIME_REC]; -+#endif -+/*-----------Platform bus related structures----------------*/ -+#define DRV_NAME "mtk_btif" -+ -+#ifdef CONFIG_OF -+const struct of_device_id apbtif_of_ids[] = { -+ { .compatible = "mediatek,btif", }, -+ {} -+}; -+#endif -+ -+const struct dev_pm_ops mtk_btif_drv_pm_ops = { -+ .restore_noirq = mtk_btif_restore_noirq, -+ .suspend = mtk_btif_drv_suspend, -+ .resume = mtk_btif_drv_resume, -+}; -+ -+struct platform_driver mtk_btif_dev_drv = { -+ .probe = mtk_btif_probe, -+ .remove = mtk_btif_remove, -+#ifdef CONFIG_PM -+ .suspend = mtk_btif_suspend, -+ .resume = mtk_btif_resume, -+#endif -+ .driver = { -+ .name = DRV_NAME, -+ .owner = THIS_MODULE, -+#ifdef CONFIG_PM -+ .pm = &mtk_btif_drv_pm_ops, -+#endif -+#ifdef CONFIG_OF -+ .of_match_table = apbtif_of_ids, -+#endif -+ } -+}; -+ -+#define BTIF_STATE_RELEASE(x) _btif_state_release(x) -+ -+/*-----------End of Platform bus related structures----------------*/ -+ -+/*-----------platform bus related operation APIs----------------*/ -+ -+static int mtk_btif_probe(struct platform_device *pdev) -+{ -+/*Chaozhong: ToDo: to be implement*/ -+/*register IRQ for BTIF and Tx Rx DMA and disable them by default*/ -+ BTIF_INFO_FUNC("DO BTIF PROBE\n"); -+ platform_set_drvdata(pdev, &g_btif[0]); -+ g_btif[0].private_data = (struct device *)&pdev->dev; -+ -+#if !defined(CONFIG_MTK_CLKMGR) -+ hal_btif_clk_get_and_prepare(pdev); -+#endif -+ -+ return 0; -+} -+ -+static int mtk_btif_remove(struct platform_device *pdev) -+{ -+/*Chaozhong: ToDo: to be implement*/ -+ BTIF_INFO_FUNC("DO BTIF REMOVE\n"); -+ platform_set_drvdata(pdev, NULL); -+ g_btif[0].private_data = NULL; -+ return 0; -+} -+ -+int _btif_suspend(p_mtk_btif p_btif) -+{ -+ int i_ret; -+ -+ if (_btif_state_hold(p_btif)) -+ return E_BTIF_INTR; -+ if (p_btif != NULL) { -+ if (!(p_btif->enable)) -+ i_ret = 0; -+ else { -+ if (_btif_state_get(p_btif) == B_S_ON) { -+ BTIF_ERR_FUNC("BTIF in ON state,", -+ "there are data need to be send or recev,suspend fail\n"); -+ i_ret = -1; -+ } else { -+ /* -+ * before disable BTIF controller and DMA controller -+ * we need to set BTIF to ON state -+ */ -+ i_ret = _btif_exit_dpidle(p_btif); -+ if (i_ret == 0) { -+ i_ret += _btif_controller_free(p_btif); -+ i_ret = _btif_controller_tx_free(p_btif); -+ i_ret += _btif_controller_rx_free(p_btif); -+ } -+ if (i_ret != 0) { -+ BTIF_INFO_FUNC("failed\n"); -+ /*Chaozhong: what if failed*/ -+ } else { -+ BTIF_INFO_FUNC("succeed\n"); -+ i_ret = _btif_state_set(p_btif, B_S_SUSPEND); -+ if (i_ret && _btif_init(p_btif)) { -+ /*Chaozhong:BTIF re-init failed? what to do*/ -+ i_ret = _btif_state_set(p_btif, B_S_OFF); -+ } -+ } -+ } -+ } -+ } else -+ i_ret = -1; -+ BTIF_STATE_RELEASE(p_btif); -+ -+ return i_ret; -+} -+ -+ -+static int mtk_btif_drv_suspend(struct device *dev) -+{ -+ struct platform_device *pdev = to_platform_device(dev); -+ pm_message_t state = PMSG_SUSPEND; -+ -+ return mtk_btif_suspend(pdev, state); -+} -+ -+static int mtk_btif_drv_resume(struct device *dev) -+{ -+ struct platform_device *pdev = to_platform_device(dev); -+ -+ return mtk_btif_resume(pdev); -+} -+ -+static int mtk_btif_suspend(struct platform_device *pdev, pm_message_t state) -+{ -+ int i_ret = 0; -+ p_mtk_btif p_btif = NULL; -+ -+/*Chaozhong: ToDo: to be implement*/ -+ BTIF_DBG_FUNC("++\n"); -+ p_btif = platform_get_drvdata(pdev); -+ i_ret = _btif_suspend(p_btif); -+ BTIF_DBG_FUNC("--, i_ret:%d\n", i_ret); -+ return i_ret; -+} -+ -+int _btif_restore_noirq(p_mtk_btif p_btif) -+{ -+ int i_ret = 0; -+ -+/*BTIF IRQ restore no irq*/ -+ i_ret = hal_btif_pm_ops(p_btif->p_btif_info, BTIF_PM_RESTORE_NOIRQ); -+ if (i_ret == 0) { -+ BTIF_INFO_FUNC("BTIF HW IRQ restore succeed\n"); -+ } else { -+ BTIF_INFO_FUNC("BTIF HW IRQ restore failed, i_ret:%d\n", i_ret); -+ return i_ret; -+ } -+/*BTIF DMA restore no irq*/ -+ if (p_btif->tx_mode & BTIF_MODE_DMA) { -+ i_ret = hal_dma_pm_ops(p_btif->p_tx_dma->p_dma_info, -+ BTIF_PM_RESTORE_NOIRQ); -+ if (i_ret == 0) { -+ BTIF_INFO_FUNC("BTIF Tx DMA IRQ restore succeed\n"); -+ } else { -+ BTIF_INFO_FUNC -+ ("BTIF Tx DMA IRQ restore failed, i_ret:%d\n", -+ i_ret); -+ return i_ret; -+ } -+ } -+ if (p_btif->rx_mode & BTIF_MODE_DMA) { -+ i_ret = hal_dma_pm_ops(p_btif->p_rx_dma->p_dma_info, -+ BTIF_PM_RESTORE_NOIRQ); -+ if (i_ret == 0) { -+ BTIF_INFO_FUNC("BTIF Rx DMA IRQ restore succeed\n"); -+ } else { -+ BTIF_INFO_FUNC -+ ("BTIF Rx DMA IRQ restore failed, i_ret:%d\n", -+ i_ret); -+ return i_ret; -+ } -+ } -+ return i_ret; -+} -+ -+static int mtk_btif_restore_noirq(struct device *dev) -+{ -+ int i_ret = 0; -+ struct platform_device *pdev = to_platform_device(dev); -+ p_mtk_btif p_btif = platform_get_drvdata(pdev); -+ -+ BTIF_INFO_FUNC("++\n"); -+ if (_btif_state_hold(p_btif)) -+ return E_BTIF_INTR; -+ if (p_btif->enable) -+ BTIF_ERR_FUNC("!!!-----------------!BTIF is not closed before IPOH shutdown!!!---------------!\n"); -+ WARN_ON(p_btif->enable); -+ -+ i_ret = _btif_restore_noirq(p_btif); -+ BTIF_STATE_RELEASE(p_btif); -+ BTIF_INFO_FUNC("--\n"); -+ return 0; -+} -+ -+int _btif_resume(p_mtk_btif p_btif) -+{ -+ int i_ret = 0; -+ ENUM_BTIF_STATE state = B_S_MAX; -+ -+ if (_btif_state_hold(p_btif)) -+ return E_BTIF_INTR; -+ if (p_btif != NULL) { -+ state = _btif_state_get(p_btif); -+ if (!(p_btif->enable)) -+ i_ret = 0; -+ else if (state == B_S_SUSPEND) -+ i_ret = _btif_enter_dpidle(p_btif); -+ else -+ BTIF_INFO_FUNC -+ ("BTIF state: %s before resume, do nothing\n", g_state[state]); -+ } else -+ i_ret = -1; -+ BTIF_STATE_RELEASE(p_btif); -+ -+ return i_ret; -+} -+ -+static int mtk_btif_resume(struct platform_device *pdev) -+{ -+ int i_ret = 0; -+ p_mtk_btif p_btif = NULL; -+/*Chaozhong: ToDo: to be implement*/ -+ BTIF_DBG_FUNC("++\n"); -+ p_btif = platform_get_drvdata(pdev); -+ i_ret = _btif_resume(p_btif); -+ BTIF_DBG_FUNC("--, i_ret:%d\n", i_ret); -+ return 0; -+} -+ -+/*-----------device node----------------*/ -+#if BTIF_CDEV_SUPPORT -+ -+dev_t btif_dev; -+struct class *p_btif_class; -+struct device *p_btif_dev; -+const char *p_btif_dev_name = "btif"; -+static struct semaphore wr_mtx; -+static struct semaphore rd_mtx; -+unsigned char wr_buf[2048]; -+unsigned char rd_buf[2048]; -+static int rx_notify_flag; -+static DECLARE_WAIT_QUEUE_HEAD(btif_wq); -+static int btif_file_open(struct inode *pinode, struct file *pfile); -+static int btif_file_release(struct inode *pinode, struct file *pfile); -+static ssize_t btif_file_read(struct file *pfile, -+ char __user *buf, size_t count, loff_t *f_ops); -+ -+static ssize_t btif_file_write(struct file *filp, -+ const char __user *buf, size_t count, loff_t *f_pos); -+static long btif_unlocked_ioctl(struct file *filp, unsigned int cmd, -+ unsigned long arg); -+#ifdef CONFIG_COMPAT -+static long btif_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); -+#endif -+static struct cdev btif_dev_c; -+static wait_queue_head_t btif_read_inq; /* read queues */ -+ -+const struct file_operations mtk_btif_fops = { -+ .owner = THIS_MODULE, -+ .open = btif_file_open, -+ .release = btif_file_release, -+ .read = btif_file_read, -+ .write = btif_file_write, -+ .unlocked_ioctl = btif_unlocked_ioctl, -+#ifdef CONFIG_COMPAT -+ .compat_ioctl = btif_compat_ioctl, -+#endif -+ .poll = btif_poll, -+}; -+ -+static int btif_chrdev_init(void) -+{ -+ int i_ret; -+ -+ int i_err; -+ -+ /* alloc device number dynamically */ -+ i_ret = alloc_chrdev_region(&btif_dev, 0, 1, p_btif_dev_name); -+ if (i_ret) { -+ BTIF_ERR_FUNC("devuce number allocation failed, i_ret:%d\n", -+ i_ret); -+ } else { -+ BTIF_INFO_FUNC("devuce number allocation succeed\n"); -+ } -+ cdev_init(&btif_dev_c, &mtk_btif_fops); -+ btif_dev_c.owner = THIS_MODULE; -+ i_err = cdev_add(&btif_dev_c, btif_dev, 1); -+ if (i_err) { -+ BTIF_ERR_FUNC("error add btif dev to kernel, error code:%d\n", -+ i_err); -+ unregister_chrdev_region(btif_dev, 1); -+ btif_dev = 0; -+ return -1; -+ } -+ BTIF_INFO_FUNC("add btif dev to kernel succeed\n"); -+ -+ p_btif_class = class_create(THIS_MODULE, p_btif_dev_name); -+ if (IS_ERR(p_btif_class)) { -+ BTIF_ERR_FUNC("error happened when doing class_create\n"); -+ unregister_chrdev_region(btif_dev, 1); -+ btif_dev = 0; -+ return -2; -+ } -+ BTIF_INFO_FUNC("create class for btif succeed\n"); -+ -+ p_btif_dev = device_create(p_btif_class, -+ NULL, btif_dev, 0, p_btif_dev_name); -+ if (IS_ERR(p_btif_dev)) { -+ BTIF_ERR_FUNC("error happened when doing device_create\n"); -+ class_destroy(p_btif_class); -+ p_btif_class = NULL; -+ unregister_chrdev_region(btif_dev, 1); -+ btif_dev = 0; -+ return -3; -+ } -+ BTIF_INFO_FUNC("create device for btif succeed\n"); -+ -+ return 0; -+} -+ -+void btif_rx_notify_cb(void) -+{ -+ BTIF_DBG_FUNC("++\n"); -+ rx_notify_flag = 1; -+ wake_up(&btif_wq); -+ wake_up_interruptible(&btif_read_inq); -+ BTIF_DBG_FUNC("--\n"); -+} -+ -+unsigned int btif_poll(struct file *filp, poll_table *wait) -+{ -+ unsigned int mask = 0; -+ unsigned int ava_len = 0; -+/* btif_bbs_read(&(g_btif[0].btif_buf), rd_buf, sizeof(rd_buf)); */ -+ unsigned int wr_idx = g_btif[0].btif_buf.wr_idx; -+ -+/* BTIF_Rx_IRQ_Disable(); */ -+ ava_len = BBS_COUNT_CUR(&(g_btif[0].btif_buf), wr_idx); -+ BTIF_INFO_FUNC("++\n"); -+ if (ava_len == 0) { -+ poll_wait(filp, &btif_read_inq, wait); -+ wr_idx = g_btif[0].btif_buf.wr_idx; -+ ava_len = BBS_COUNT_CUR(&(g_btif[0].btif_buf), wr_idx); -+/* btif_bbs_read(&(g_btif[0].btif_buf), rd_buf, sizeof(rd_buf)); */ -+ if (ava_len) -+ mask |= POLLIN | POLLRDNORM; /* readable */ -+ } else { -+ mask |= POLLIN | POLLRDNORM; /* readable */ -+ } -+/*make for writable*/ -+ mask |= POLLOUT | POLLWRNORM; /* writable */ -+ BTIF_INFO_FUNC("--, mask:%d\n", mask); -+ return mask; -+} -+ -+static int _btif_file_open(void) -+{ -+ int i_ret = -1; -+ p_mtk_btif p_btif = &g_btif[0]; -+ -+ BTIF_INFO_FUNC("++\n"); -+ -+/*Chaozhong: ToDo: to be implement*/ -+ i_ret = btif_open(p_btif); -+ if ((i_ret != 0) && (i_ret != E_BTIF_ALREADY_OPEN)) { -+ BTIF_ERR_FUNC("btif_open failed, error code:%d\n", i_ret); -+ } else { -+ BTIF_INFO_FUNC("btif_open succeed\n"); -+ i_ret = 0; -+ } -+/*semaphore for read and write operation init*/ -+ sema_init(&wr_mtx, 1); -+ sema_init(&rd_mtx, 1); -+ -+/*buffer for read and write init*/ -+ memset(wr_buf, 0, sizeof(wr_buf)); -+ memset(rd_buf, 0, sizeof(rd_buf)); -+ init_waitqueue_head(&(btif_read_inq)); -+ btif_rx_notify_reg(p_btif, btif_rx_notify_cb); -+ BTIF_INFO_FUNC("--\n"); -+ return i_ret; -+} -+ -+static int _btif_file_close(void) -+{ -+ int i_ret = -1; -+ -+ BTIF_INFO_FUNC("++\n"); -+/*Chaozhong: ToDo: to be implement*/ -+ i_ret = btif_close(&g_btif[0]); -+ if (i_ret != 0) -+ BTIF_ERR_FUNC("btif_close failed, error code:%d\n", i_ret); -+ else -+ BTIF_INFO_FUNC("btif_close succeed\n"); -+ -+ BTIF_INFO_FUNC("--\n"); -+ return i_ret; -+} -+ -+static int btif_file_open(struct inode *pinode, struct file *pfile) -+{ -+ int i_ret = -1; -+ -+ BTIF_INFO_FUNC("pid:%d\n", current->pid); -+ i_ret = 0; -+ return i_ret; -+} -+ -+static int btif_file_release(struct inode *pinode, struct file *pfile) -+{ -+ int i_ret = -1; -+ -+ BTIF_INFO_FUNC("pid:%d\n", current->pid); -+ i_ret = 0; -+ return i_ret; -+} -+ -+static ssize_t btif_file_read(struct file *pfile, -+ char __user *buf, size_t count, loff_t *f_ops) -+{ -+ int i_ret = 0; -+ int rd_len = 0; -+ -+ BTIF_INFO_FUNC("++\n"); -+ down(&rd_mtx); -+ rd_len = btif_bbs_read(&(g_btif[0].btif_buf), rd_buf, sizeof(rd_buf)); -+ while (rd_len == 0) { -+ if (pfile->f_flags & O_NONBLOCK) -+ break; -+ -+ wait_event(btif_wq, rx_notify_flag != 0); -+ rx_notify_flag = 0; -+ rd_len = -+ btif_bbs_read(&(g_btif[0].btif_buf), rd_buf, -+ sizeof(rd_buf)); -+ } -+ -+ if (rd_len == 0) -+ i_ret = 0; -+ else if ((rd_len > 0) && (copy_to_user(buf, rd_buf, rd_len) == 0)) -+ i_ret = rd_len; -+ else -+ i_ret = -EFAULT; -+ -+ up(&rd_mtx); -+ BTIF_INFO_FUNC("--, i_ret:%d\n", i_ret); -+ return i_ret; -+} -+ -+ssize_t btif_file_write(struct file *filp, -+ const char __user *buf, size_t count, loff_t *f_pos) -+{ -+ int i_ret = 0; -+ int copy_size = 0; -+ -+ copy_size = count > sizeof(wr_buf) ? sizeof(wr_buf) : count; -+ -+ BTIF_INFO_FUNC("++\n"); -+ down(&wr_mtx); -+ if (copy_from_user(&wr_buf[0], &buf[0], copy_size)) -+ i_ret = -EFAULT; -+ else -+ i_ret = btif_send_data(&g_btif[0], wr_buf, copy_size); -+ -+ up(&wr_mtx); -+ BTIF_INFO_FUNC("--, i_ret:%d\n", i_ret); -+ -+ return i_ret; -+} -+#ifdef CONFIG_COMPAT -+long btif_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) -+{ -+ long ret; -+ -+ BTIF_INFO_FUNC("cmd[0x%x]\n", cmd); -+ ret = btif_unlocked_ioctl(filp, cmd, arg); -+ return ret; -+} -+#endif -+long btif_unlocked_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) -+{ -+#define BTIF_IOC_MAGIC 0xb0 -+#define BTIF_IOCTL_OPEN _IOW(BTIF_IOC_MAGIC, 1, int) -+#define BTIF_IOCTL_CLOSE _IOW(BTIF_IOC_MAGIC, 2, int) -+#define BTIF_IOCTL_LPBK_CTRL _IOWR(BTIF_IOC_MAGIC, 3, int) -+#define BTIF_IOCTL_LOG_FUNC_CTRL _IOWR(BTIF_IOC_MAGIC, 4, int) -+#define BTIF_IOCTL_RT_LOG_CTRL _IOWR(BTIF_IOC_MAGIC, 5, int) -+#define BTIF_IOCTL_LOG_DUMP _IOWR(BTIF_IOC_MAGIC, 6, int) -+#define BTIF_IOCTL_REG_DUMP _IOWR(BTIF_IOC_MAGIC, 7, int) -+#define BTIF_IOCTL_DMA_CTRL _IOWR(BTIF_IOC_MAGIC, 8, int) -+ -+ long ret = 0; -+/* unsigned char p_buf[NAME_MAX + 1]; */ -+ p_mtk_btif p_btif = &g_btif[0]; -+ -+ BTIF_INFO_FUNC("++\n"); -+ BTIF_DBG_FUNC("cmd (%u), arg (0x%lx)\n", cmd, arg); -+ -+ switch (cmd) { -+ case BTIF_IOCTL_OPEN: -+ ret = _btif_file_open(); -+ break; -+ case BTIF_IOCTL_CLOSE: -+ ret = _btif_file_close(); -+ break; -+ case BTIF_IOCTL_LPBK_CTRL: -+ ret = btif_lpbk_ctrl(p_btif, arg == 0 ? 0 : 1); -+ break; -+ case BTIF_IOCTL_LOG_FUNC_CTRL: -+ if (arg == 0) { -+ ret += btif_log_buf_disable(&p_btif->tx_log); -+ ret += btif_log_buf_disable(&p_btif->rx_log); -+ } else { -+ ret += btif_log_buf_enable(&p_btif->tx_log); -+ ret += btif_log_buf_enable(&p_btif->rx_log); -+ } -+ break; -+ case BTIF_IOCTL_RT_LOG_CTRL: -+ if (arg == 0) { -+ ret += btif_log_output_disable(&p_btif->tx_log); -+ ret += btif_log_output_disable(&p_btif->rx_log); -+ } else { -+ ret += btif_log_output_enable(&p_btif->tx_log); -+ ret += btif_log_output_enable(&p_btif->rx_log); -+ } -+ break; -+ case BTIF_IOCTL_LOG_DUMP: -+ -+ ret += btif_log_buf_dmp_out(&p_btif->tx_log); -+ ret += btif_log_buf_dmp_out(&p_btif->rx_log); -+ break; -+ case BTIF_IOCTL_REG_DUMP: -+ ret += btif_dump_reg(p_btif); -+ break; -+ case BTIF_IOCTL_DMA_CTRL: -+ if (arg == 0) { -+ ret += btif_tx_dma_mode_set(0); -+ ret += btif_rx_dma_mode_set(0); -+ } else { -+ ret += btif_tx_dma_mode_set(1); -+ ret += btif_rx_dma_mode_set(1); -+ } -+ break; -+ default: -+ BTIF_INFO_FUNC("unknown cmd(%d)\n", cmd); -+ ret = -2; -+ break; -+ } -+ BTIF_INFO_FUNC("--\n"); -+ return ret; -+} -+ -+#endif -+ -+/*-----------device property----------------*/ -+//static ssize_t driver_flag_read(struct device_driver *drv, char *buf) -+static ssize_t flag_show(struct device_driver *drv, char *buf) -+{ -+ return sprintf(buf, "btif driver debug level:%d\n", mtk_btif_dbg_lvl); -+} -+ -+//static ssize_t driver_flag_set(struct device_driver *drv, -+static ssize_t flag_store(struct device_driver *drv, -+ const char *buffer, size_t count) -+{ -+ char buf[256]; -+ char *p_buf; -+ unsigned long len = count; -+ long x = 0; -+ long y = 0; -+ long z = 0; -+ int result = 0; -+ char *p_token = NULL; -+ char *p_delimiter = " \t"; -+ -+ BTIF_INFO_FUNC("buffer = %s, count = %zd\n", buffer, count); -+ if (len >= sizeof(buf)) { -+ BTIF_ERR_FUNC("input handling fail!\n"); -+ len = sizeof(buf) - 1; -+ return -1; -+ } -+ -+ memcpy(buf, buffer, sizeof(buf)); -+ p_buf = buf; -+ -+ p_token = strsep(&p_buf, p_delimiter); -+ if (p_token != NULL) { -+ result = kstrtol(p_token, 16, &x); -+ BTIF_INFO_FUNC("x = 0x%08x\n\r", x); -+ } else -+ x = 0; -+/* x = (NULL != p_token) ? kstrtol(p_token, 16, NULL) : 0;*/ -+ -+ p_token = strsep(&p_buf, "\t\n "); -+ if (p_token != NULL) { -+ result = kstrtol(p_token, 16, &y); -+ BTIF_INFO_FUNC("y = 0x%08x\n\r", y); -+ } else -+ y = 0; -+ -+ p_token = strsep(&p_buf, "\t\n "); -+ if (p_token != NULL) -+ result = kstrtol(p_token, 16, &z); -+ else -+ z = 0; -+ -+ BTIF_INFO_FUNC("x(0x%08x), y(0x%08x), z(0x%08x)\n\r", x, y, z); -+ -+ switch (x) { -+ case 1: -+ mtk_btif_exp_open_test(); -+ break; -+ case 2: -+ mtk_btif_exp_close_test(); -+ break; -+ case 3: -+ mtk_btif_exp_write_test(); -+ break; -+ case 4: -+ mtk_btif_exp_enter_dpidle_test(); -+ break; -+ case 5: -+ mtk_btif_exp_exit_dpidle_test(); -+ break; -+ case 6: -+ mtk_btif_exp_suspend_test(); -+ break; -+ case 7: -+ mtk_btif_exp_resume_test(); -+ break; -+ case 8: -+ if (y > BTIF_LOG_LOUD) -+ mtk_btif_dbg_lvl = BTIF_LOG_LOUD; -+ else if (y < BTIF_LOG_ERR) -+ mtk_btif_dbg_lvl = BTIF_LOG_WARN; -+ else -+ mtk_btif_dbg_lvl = y; -+ BTIF_ERR_FUNC("mtk_btif_dbg_lvl set to %d\n", mtk_btif_dbg_lvl); -+ break; -+ case 9: -+ mtk_btif_exp_open_test(); -+ mtk_btif_exp_write_test(); -+ mtk_btif_exp_close_test(); -+ break; -+ case 0xa: -+ mtk_btif_exp_log_debug_test(y); -+ break; -+ case 0xb: -+ btif_tx_dma_mode_set(1); -+ btif_rx_dma_mode_set(1); -+ break; -+ case 0xc: -+ btif_tx_dma_mode_set(0); -+ btif_rx_dma_mode_set(0); -+ break; -+ case 0xd: -+ mtk_btif_exp_restore_noirq_test(); -+ break; -+ case 0xe: -+ btif_wakeup_consys_no_id(); -+ break; -+ case 0xf: -+ mtk_btif_exp_clock_ctrl(y); -+ break; -+ case 0x10: -+ y = y > G_MAX_PKG_LEN ? G_MAX_PKG_LEN : y; -+ y = y < 1024 ? 1024 : y; -+ BTIF_INFO_FUNC("g_max_pkg_len is set to %d\n", y); -+ g_max_pkg_len = y; -+ break; -+ case 0x11: -+ y = y > BTIF_RX_BUFFER_SIZE ? BTIF_RX_BUFFER_SIZE : y; -+ y = y < 1024 ? 1024 : y; -+ BTIF_INFO_FUNC("g_max_pding_data_size is set to %d\n", y); -+ g_max_pding_data_size = y; -+ break; -+ default: -+ mtk_btif_exp_open_test(); -+ mtk_btif_exp_write_stress_test(3030, 1); -+ mtk_btif_exp_close_test(); -+ BTIF_WARN_FUNC("not supported.\n"); -+ break; -+ } -+ -+ return count; -+} -+ -+//FWU: driver_ATTR dropped in 4.14 -+//static DRIVER_ATTR(flag, S_IRUGO | S_IWUSR, driver_flag_read, driver_flag_set); -+static DRIVER_ATTR_RW(flag); -+ -+/*-----------End of platform bus related operation APIs------------*/ -+ -+/*-----------------------platform driver ----------------*/ -+ -+int _btif_irq_reg(P_MTK_BTIF_IRQ_STR p_irq, -+ mtk_btif_irq_handler irq_handler, void *data) -+{ -+ int i_ret = -1; -+ unsigned int irq_id; -+ unsigned int flag; -+ -+ if ((p_irq == NULL) || (irq_handler == NULL)) -+ return E_BTIF_INVAL_PARAM; -+ -+ if (!(p_irq->is_irq_sup)) { -+ BTIF_WARN_FUNC("%s is not supported\n", p_irq->name); -+ return 0; -+ } -+ -+ irq_id = p_irq->irq_id; -+ -+#ifdef CONFIG_OF -+ flag = p_irq->irq_flags; -+#else -+ switch (p_irq->sens_type) { -+ case IRQ_SENS_EDGE: -+ if (p_irq->edge_type == IRQ_EDGE_FALL) -+ flag = IRQF_TRIGGER_FALLING; -+ else if (p_irq->edge_type == IRQ_EDGE_RAISE) -+ flag = IRQF_TRIGGER_RISING; -+ else if (p_irq->edge_type == IRQ_EDGE_BOTH) -+ flag = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING; -+ else -+ /*make this as default type */ -+ flag = IRQF_TRIGGER_FALLING; -+ break; -+ case IRQ_SENS_LVL: -+ if (p_irq->lvl_type == IRQ_LVL_LOW) -+ flag = IRQF_TRIGGER_LOW; -+ else if (p_irq->lvl_type == IRQ_LVL_HIGH) -+ flag = IRQF_TRIGGER_HIGH; -+ else -+ /*make this as default type */ -+ flag = IRQF_TRIGGER_LOW; -+ break; -+ default: -+ /*make this as default type */ -+ flag = IRQF_TRIGGER_LOW; -+ break; -+ } -+#endif -+ -+ p_irq->p_irq_handler = irq_handler; -+ i_ret = request_irq(irq_id, -+ (irq_handler_t) irq_handler, -+ flag, p_irq->name, data); -+ if (i_ret) -+ return i_ret; -+ -+ p_irq->reg_flag = true; -+ return 0; -+} -+ -+int _btif_irq_free(P_MTK_BTIF_IRQ_STR p_irq, void *data) -+{ -+ int i_ret = 0; -+ unsigned int eint_num = p_irq->irq_id; -+ -+ if ((p_irq->is_irq_sup) && (p_irq->reg_flag)) { -+ _btif_irq_ctrl(p_irq, false); -+ free_irq(eint_num, data); -+ p_irq->reg_flag = false; -+ } -+/*do nothing for this operation*/ -+ return i_ret; -+} -+ -+int _btif_irq_ctrl(P_MTK_BTIF_IRQ_STR p_irq, bool en) -+{ -+ unsigned int eint_num = p_irq->irq_id; -+ -+ if (en) -+ enable_irq(eint_num); -+ else -+ disable_irq_nosync(eint_num); -+ -+ return 0; -+} -+ -+int _btif_irq_ctrl_sync(P_MTK_BTIF_IRQ_STR p_irq, bool en) -+{ -+ unsigned int eint_num = p_irq->irq_id; -+ -+ if (en) -+ enable_irq(eint_num); -+ else -+ disable_irq(eint_num); -+ -+ return 0; -+} -+ -+ -+irqreturn_t btif_irq_handler(int irq, void *data) -+{ -+/*search BTIF? just use index 0*/ -+/*Chaozhong: do we need lock here?*/ -+ -+ p_mtk_btif p_btif = (p_mtk_btif) data; /*&(g_btif[index]); */ -+ -+ BTIF_DBG_FUNC("++, p_btif(0x%p)\n", data); -+ -+ _btif_irq_ctrl(p_btif->p_btif_info->p_irq, false); -+ -+#if MTK_BTIF_ENABLE_CLK_REF_COUNTER -+ hal_btif_clk_ctrl(p_btif->p_btif_info, CLK_OUT_ENABLE); -+#endif -+ -+ hal_btif_irq_handler(p_btif->p_btif_info, NULL, 0); -+ -+#if MTK_BTIF_ENABLE_CLK_REF_COUNTER -+ hal_btif_clk_ctrl(p_btif->p_btif_info, CLK_OUT_DISABLE); -+#endif -+ -+ _btif_irq_ctrl(p_btif->p_btif_info->p_irq, true); -+ _btif_rx_btm_sched(p_btif); -+ -+ BTIF_DBG_FUNC("--\n"); -+ return IRQ_HANDLED; -+} -+ -+irqreturn_t btif_tx_dma_irq_handler(int irq, void *data) -+{ -+/*search BTIF? just use index 0*/ -+ -+ p_mtk_btif p_btif = (p_mtk_btif) data; /*&(g_btif[index]); */ -+ p_mtk_btif_dma p_tx_dma = p_btif->p_tx_dma; -+ P_MTK_DMA_INFO_STR p_dma_info = p_tx_dma->p_dma_info; -+ -+ BTIF_DBG_FUNC("++, p_btif(0x%p)\n", data); -+ _btif_irq_ctrl(p_dma_info->p_irq, false); -+ -+#if MTK_BTIF_ENABLE_CLK_REF_COUNTER -+ hal_btif_dma_clk_ctrl(p_dma_info, CLK_OUT_ENABLE); -+#endif -+ -+ hal_tx_dma_irq_handler(p_dma_info); -+ -+#if MTK_BTIF_ENABLE_CLK_REF_COUNTER -+ hal_btif_dma_clk_ctrl(p_dma_info, CLK_OUT_DISABLE); -+#endif -+ _btif_irq_ctrl(p_dma_info->p_irq, true); -+ BTIF_DBG_FUNC("--\n"); -+ return IRQ_HANDLED; -+} -+ -+irqreturn_t btif_rx_dma_irq_handler(int irq, void *data) -+{ -+/*search BTIF? just use index 0*/ -+ -+ p_mtk_btif p_btif = (p_mtk_btif) data; /*&(g_btif[index]); */ -+ p_mtk_btif_dma p_rx_dma = p_btif->p_rx_dma; -+ P_MTK_DMA_INFO_STR p_rx_dma_info = p_rx_dma->p_dma_info; -+ -+ BTIF_DBG_FUNC("++, p_btif(0x%p)\n", data); -+ -+ _btif_irq_ctrl(p_rx_dma_info->p_irq, false); -+ -+#if MTK_BTIF_ENABLE_CLK_REF_COUNTER -+ hal_btif_clk_ctrl(p_btif->p_btif_info, CLK_OUT_ENABLE); -+ hal_btif_dma_clk_ctrl(p_rx_dma_info, CLK_OUT_ENABLE); -+#endif -+ -+ hal_rx_dma_irq_handler(p_rx_dma_info, NULL, 0); -+ -+#if MTK_BTIF_ENABLE_CLK_REF_COUNTER -+ hal_btif_dma_clk_ctrl(p_rx_dma_info, CLK_OUT_DISABLE); -+ hal_btif_clk_ctrl(p_btif->p_btif_info, CLK_OUT_DISABLE); -+#endif -+ -+ _btif_irq_ctrl(p_rx_dma_info->p_irq, true); -+ -+ _btif_rx_btm_sched(p_btif); -+ -+ BTIF_DBG_FUNC("--\n"); -+ -+ return IRQ_HANDLED; -+} -+ -+unsigned int btif_dma_rx_data_receiver(P_MTK_DMA_INFO_STR p_dma_info, -+ unsigned char *p_buf, -+ unsigned int buf_len) -+{ -+ unsigned int index = 0; -+ p_mtk_btif p_btif = &(g_btif[index]); -+ -+#if 0 -+ _btif_dump_memory("", p_buf, buf_len); -+#endif -+ -+ btif_bbs_write(&(p_btif->btif_buf), p_buf, buf_len); -+/*save DMA Rx packet here*/ -+ if (buf_len > 0) -+ btif_log_buf_dmp_in(&p_btif->rx_log, p_buf, buf_len); -+ -+ return 0; -+} -+ -+unsigned int btif_pio_rx_data_receiver(P_MTK_BTIF_INFO_STR p_btif_info, -+ unsigned char *p_buf, -+ unsigned int buf_len) -+{ -+ unsigned int index = 0; -+ p_mtk_btif p_btif = &(g_btif[index]); -+ -+#if 0 -+ _btif_dump_memory("", p_buf, buf_len); -+#endif -+ btif_bbs_write(&(p_btif->btif_buf), p_buf, buf_len); -+ -+/*save PIO Rx packet here*/ -+ if (buf_len > 0) -+ btif_log_buf_dmp_in(&p_btif->rx_log, p_buf, buf_len); -+ -+ return 0; -+} -+ -+bool btif_parser_wmt_evt(p_mtk_btif p_btif, -+ const char *sub_str, -+ unsigned int str_len) -+{ -+ unsigned int data_cnt = 0; -+ unsigned int copy_cnt = 0; -+ char *local_buf = NULL; -+ bool b_ret = false; -+ p_btif_buf_str p_bbs = &(p_btif->btif_buf); -+ unsigned int wr_idx = p_bbs->wr_idx; -+ unsigned int rd_idx = p_bbs->rd_idx; -+ -+ data_cnt = copy_cnt = BBS_COUNT(p_bbs); -+ -+ if (data_cnt < str_len) { -+ BTIF_WARN_FUNC("there is not enough data for parser,need(%d),have(%d)\n", str_len, data_cnt); -+ return false; -+ } -+ BTIF_INFO_FUNC("data count in bbs buffer:%d,wr_idx(%d),rd_idx(%d)\n", data_cnt, wr_idx, rd_idx); -+ local_buf = vmalloc((data_cnt + 3) & ~0x3UL); -+ if (!local_buf) { -+ BTIF_WARN_FUNC("vmalloc memory fail\n"); -+ return false; -+ } -+ -+ if (wr_idx >= rd_idx) { -+ memcpy(local_buf, BBS_PTR(p_bbs, rd_idx), copy_cnt); -+ } else { -+ unsigned int tail_len = BBS_SIZE(p_bbs) - rd_idx; -+ -+ BTIF_INFO_FUNC("tail_Len(%d)\n", tail_len); -+ memcpy(local_buf, BBS_PTR(p_bbs, rd_idx), tail_len); -+ memcpy(local_buf + tail_len, BBS_PTR(p_bbs, 0), copy_cnt - tail_len); -+ } -+ -+ do { -+ int i = 0; -+ int j = 0; -+ int k = 0; -+ int d = 0; -+ -+ BTIF_INFO_FUNC("sub_str_len:%d\n", str_len); -+ for (i = 0; i < copy_cnt; i++) { -+ BTIF_DBG_FUNC("i:%d\n", i); -+ k = i; -+ while (1) { -+ if ((j >= str_len) || (k >= copy_cnt) || (sub_str[j++] != local_buf[k++])) -+ break; -+ } -+ -+ if (j == str_len) { -+ for (d = i; d < (str_len + i); d++) -+ BTIF_INFO_FUNC("0x%2x", local_buf[d]); -+ BTIF_INFO_FUNC("find sub str index:%d\n", i); -+ b_ret = true; -+ break; -+ } -+ if (j < str_len) -+ j = 0; -+ } -+ -+ } while (0); -+ -+ vfree(local_buf); -+ return b_ret; -+} -+int _btif_controller_tx_setup(p_mtk_btif p_btif) -+{ -+ int i_ret = -1; -+ -+ if (p_btif->tx_mode == BTIF_MODE_DMA) { -+ i_ret = _btif_tx_dma_setup(p_btif); -+ if (i_ret) { -+ BTIF_ERR_FUNC("_btif_tx_dma_setup failed,i_ret(%d),", -+ "set tx to PIO mode\n", i_ret); -+ i_ret = _btif_tx_pio_setup(p_btif); -+ } -+ } else -+/*enable Tx PIO mode*/ -+ i_ret = _btif_tx_pio_setup(p_btif); -+ -+ return i_ret; -+} -+ -+int _btif_controller_tx_free(p_mtk_btif p_btif) -+{ -+ int i_ret = -1; -+ -+ if (p_btif->tx_mode == BTIF_MODE_DMA) { -+ i_ret = _btif_tx_dma_free(p_btif); -+ if (i_ret) { -+ BTIF_ERR_FUNC("_btif_tx_dma_free failed, i_ret(%d)\n", -+ i_ret); -+ } -+ } else { -+/*do nothing for Tx PIO mode*/ -+ } -+ return i_ret; -+} -+ -+int _btif_controller_rx_setup(p_mtk_btif p_btif) -+{ -+ int i_ret = -1; -+ -+ if (p_btif->rx_mode == BTIF_MODE_DMA) { -+ i_ret = _btif_rx_dma_setup(p_btif); -+ if (i_ret) { -+ BTIF_ERR_FUNC("_btif_tx_dma_setup failed, i_ret(%d),", -+ "set tx to PIO mode\n", i_ret); -+ i_ret = _btif_rx_pio_setup(p_btif); -+ } -+ } else { -+/*enable Tx PIO mode*/ -+ i_ret = _btif_rx_pio_setup(p_btif); -+ } -+ return i_ret; -+} -+ -+int _btif_controller_rx_free(p_mtk_btif p_btif) -+{ -+ int i_ret = -1; -+ -+ if (p_btif->rx_mode == BTIF_MODE_DMA) { -+ i_ret = _btif_rx_dma_free(p_btif); -+ if (i_ret) { -+ BTIF_ERR_FUNC("_btif_rx_dma_free failed, i_ret(%d)\n", -+ i_ret); -+ } -+ } else { -+/*do nothing for Rx PIO mode*/ -+ } -+ return i_ret; -+} -+ -+int _btif_tx_pio_setup(p_mtk_btif p_btif) -+{ -+ int i_ret = -1; -+ P_MTK_BTIF_INFO_STR p_btif_info = p_btif->p_btif_info; -+ -+/*set Tx to PIO mode*/ -+ p_btif->tx_mode = BTIF_MODE_PIO; -+/*enable Tx PIO mode*/ -+ i_ret = hal_btif_tx_mode_ctrl(p_btif_info, BTIF_MODE_PIO); -+ return i_ret; -+} -+ -+int _btif_rx_pio_setup(p_mtk_btif p_btif) -+{ -+ int i_ret = -1; -+ P_MTK_BTIF_INFO_STR p_btif_info = p_btif->p_btif_info; -+ P_MTK_BTIF_IRQ_STR p_btif_irq = p_btif_info->p_irq; -+ -+ p_btif->rx_mode = BTIF_MODE_PIO; -+/*Enable Rx IRQ*/ -+ _btif_irq_ctrl(p_btif_irq, true); -+/*enable Rx PIO mode*/ -+ i_ret = hal_btif_rx_mode_ctrl(p_btif_info, BTIF_MODE_PIO); -+ return i_ret; -+} -+ -+int _btif_rx_dma_setup(p_mtk_btif p_btif) -+{ -+ int i_ret = -1; -+ P_MTK_BTIF_INFO_STR p_btif_info = NULL; -+ P_MTK_BTIF_IRQ_STR p_btif_irq = NULL; -+ P_MTK_DMA_INFO_STR p_dma_info = p_btif->p_rx_dma->p_dma_info; -+ -+ p_btif_info = p_btif->p_btif_info; -+ p_btif_irq = p_dma_info->p_irq; -+ -+/*vFIFO reset*/ -+ hal_btif_vfifo_reset(p_dma_info); -+ -+ i_ret = hal_btif_dma_clk_ctrl(p_dma_info, CLK_OUT_ENABLE); -+ if (i_ret) { -+ BTIF_ERR_FUNC("hal_btif_dma_clk_ctrl failed, i_ret(%d),", -+ "set rx to pio mode\n", i_ret); -+/*DMA control failed set Rx to PIO mode*/ -+ return _btif_rx_pio_setup(p_btif); -+ } -+/*hardware init*/ -+ hal_btif_dma_hw_init(p_dma_info); -+ -+ hal_btif_dma_rx_cb_reg(p_dma_info, -+ (dma_rx_buf_write) btif_dma_rx_data_receiver); -+ -+/*DMA controller enable*/ -+ i_ret = hal_btif_dma_ctrl(p_dma_info, DMA_CTRL_ENABLE); -+ if (i_ret) { -+ BTIF_ERR_FUNC("hal_btif_dma_ctrl failed, i_ret(%d),", -+ "set rx to pio mode\n", i_ret); -+ hal_btif_dma_clk_ctrl(p_dma_info, CLK_OUT_DISABLE); -+/*DMA control failed set Rx to PIO mode*/ -+ i_ret = _btif_rx_pio_setup(p_btif); -+ } else { -+/*enable Rx DMA mode*/ -+ hal_btif_rx_mode_ctrl(p_btif_info, BTIF_MODE_DMA); -+ -+/*DMA Rx IRQ register*/ -+ _btif_irq_reg(p_btif_irq, btif_rx_dma_irq_handler, p_btif); -+#if 0 -+/*Enable DMA Rx IRQ*/ -+ _btif_irq_ctrl(p_btif_irq, true); -+#endif -+ BTIF_DBG_FUNC("succeed\n"); -+ } -+ return i_ret; -+} -+ -+int _btif_rx_dma_free(p_mtk_btif p_btif) -+{ -+ P_MTK_DMA_INFO_STR p_dma_info = p_btif->p_rx_dma->p_dma_info; -+ P_MTK_BTIF_IRQ_STR p_irq = p_btif->p_rx_dma->p_dma_info->p_irq; -+ -+ hal_btif_dma_rx_cb_reg(p_dma_info, (dma_rx_buf_write) NULL); -+ _btif_irq_free(p_irq, p_btif); -+/*disable BTIF Rx DMA channel*/ -+ hal_btif_dma_ctrl(p_dma_info, DMA_CTRL_DISABLE); -+/*disable clock output*/ -+ return hal_btif_dma_clk_ctrl(p_dma_info, CLK_OUT_DISABLE); -+} -+ -+int _btif_tx_dma_setup(p_mtk_btif p_btif) -+{ -+ int i_ret = -1; -+ P_MTK_BTIF_INFO_STR p_btif_info = p_btif->p_btif_info; -+ P_MTK_DMA_INFO_STR p_dma_info = p_btif->p_tx_dma->p_dma_info; -+ P_MTK_BTIF_IRQ_STR p_btif_irq = p_dma_info->p_irq; -+ -+/*vFIFO reset*/ -+ hal_btif_vfifo_reset(p_dma_info); -+ -+ i_ret = hal_btif_dma_clk_ctrl(p_dma_info, CLK_OUT_ENABLE); -+ if (i_ret) { -+ BTIF_ERR_FUNC("hal_btif_dma_clk_ctrl failed, i_ret(%d)\n", -+ i_ret); -+ return i_ret; -+ } -+/*DMA controller setup*/ -+ hal_btif_dma_hw_init(p_dma_info); -+ -+/*DMA HW Enable*/ -+ i_ret = hal_btif_dma_ctrl(p_dma_info, DMA_CTRL_ENABLE); -+ if (i_ret) { -+ BTIF_ERR_FUNC("hal_btif_dma_ctrl failed, i_ret(%d),", -+ "set tx to pio mode\n", i_ret); -+ -+#if !(MTK_BTIF_ENABLE_CLK_REF_COUNTER) -+ hal_btif_dma_clk_ctrl(p_dma_info, CLK_OUT_DISABLE); -+#endif -+ -+ _btif_tx_pio_setup(p_btif); -+ } else { -+ hal_btif_tx_mode_ctrl(p_btif_info, BTIF_MODE_DMA); -+/*DMA Tx IRQ register*/ -+ _btif_irq_reg(p_btif_irq, btif_tx_dma_irq_handler, p_btif); -+#if 0 -+/*disable DMA Tx IRQ*/ -+ _btif_irq_ctrl(p_btif_irq, false); -+#endif -+ -+ BTIF_DBG_FUNC("succeed\n"); -+ } -+ return i_ret; -+} -+ -+int _btif_tx_dma_free(p_mtk_btif p_btif) -+{ -+ P_MTK_DMA_INFO_STR p_dma_info = p_btif->p_tx_dma->p_dma_info; -+ P_MTK_BTIF_IRQ_STR p_irq = p_btif->p_tx_dma->p_dma_info->p_irq; -+ -+ _btif_irq_free(p_irq, p_btif); -+/*disable BTIF Tx DMA channel*/ -+ hal_btif_dma_ctrl(p_dma_info, DMA_CTRL_DISABLE); -+/*disable clock output*/ -+ return hal_btif_dma_clk_ctrl(p_dma_info, CLK_OUT_DISABLE); -+} -+ -+int btif_lpbk_ctrl(p_mtk_btif p_btif, bool flag) -+{ -+ int i_ret = -1; -+ -+/*hold state mechine lock*/ -+ if (_btif_state_hold(p_btif)) -+ return E_BTIF_INTR; -+#if 0 -+ state = _btif_state_get(p_btif); -+ if (p_btif->enable && B_S_ON == state) -+ i_ret = _btif_lpbk_ctrl(p_btif, flag); -+ else -+ i_ret = E_BTIF_INVAL_STATE; -+#endif -+ i_ret = _btif_exit_dpidle(p_btif); -+ if (i_ret == 0) -+ i_ret = _btif_lpbk_ctrl(p_btif, flag); -+ else -+ i_ret = E_BTIF_INVAL_STATE; -+ -+ BTIF_STATE_RELEASE(p_btif); -+ return i_ret; -+} -+ -+int _btif_lpbk_ctrl(p_mtk_btif p_btif, bool flag) -+{ -+ int i_ret = -1; -+ -+ if (flag) { -+ i_ret = hal_btif_loopback_ctrl(p_btif->p_btif_info, true); -+ BTIF_DBG_FUNC("loopback function enabled\n"); -+ } else { -+ i_ret = hal_btif_loopback_ctrl(p_btif->p_btif_info, false); -+ BTIF_DBG_FUNC("loopback function disabled\n"); -+ } -+ if (i_ret == 0) -+ p_btif->lpbk_flag = flag; -+ -+ return i_ret; -+} -+ -+int btif_clock_ctrl(p_mtk_btif p_btif, int en) -+{ -+ int i_ret = 0; -+ P_MTK_BTIF_INFO_STR p_btif_info = p_btif->p_btif_info; -+ ENUM_CLOCK_CTRL ctrl_flag = en == 0 ? CLK_OUT_DISABLE : CLK_OUT_ENABLE; -+ -+ i_ret = hal_btif_clk_ctrl(p_btif_info, ctrl_flag); -+ -+ if (p_btif->rx_mode == BTIF_MODE_DMA) -+ i_ret += hal_btif_dma_clk_ctrl(p_btif->p_rx_dma->p_dma_info, ctrl_flag); -+ -+ if (p_btif->tx_mode == BTIF_MODE_DMA) -+ i_ret += hal_btif_dma_clk_ctrl(p_btif->p_tx_dma->p_dma_info, ctrl_flag); -+ -+ return i_ret; -+} -+ -+int _btif_controller_setup(p_mtk_btif p_btif) -+{ -+ int i_ret = -1; -+ P_MTK_BTIF_INFO_STR p_btif_info = p_btif->p_btif_info; -+ P_MTK_BTIF_IRQ_STR p_btif_irq = p_btif_info->p_irq; -+ -+/*BTIF rx buffer init*/ -+/* memset(p_btif->rx_buf, 0, BTIF_RX_BUFFER_SIZE); */ -+ BBS_INIT(&(p_btif->btif_buf)); -+/************************************************/ -+ hal_btif_rx_cb_reg(p_btif_info, -+ (btif_rx_buf_write) btif_pio_rx_data_receiver); -+ -+ i_ret = hal_btif_clk_ctrl(p_btif_info, CLK_OUT_ENABLE); -+ if (i_ret) { -+ BTIF_ERR_FUNC("hal_btif_clk_ctrl failed, i_ret(%d)\n", i_ret); -+ return i_ret; -+ } -+/*BTIF controller init*/ -+ i_ret = hal_btif_hw_init(p_btif_info); -+ if (i_ret) { -+ hal_btif_clk_ctrl(p_btif_info, CLK_OUT_DISABLE); -+ BTIF_ERR_FUNC("hal_btif_hw_init failed, i_ret(%d)\n", i_ret); -+ return i_ret; -+ } -+ _btif_lpbk_ctrl(p_btif, p_btif->lpbk_flag); -+/*BTIF IRQ register*/ -+ i_ret = _btif_irq_reg(p_btif_irq, btif_irq_handler, p_btif); -+ if (i_ret) { -+ hal_btif_clk_ctrl(p_btif_info, CLK_OUT_DISABLE); -+ -+ BTIF_ERR_FUNC("_btif_irq_reg failed, i_ret(%d)\n", i_ret); -+ return i_ret; -+ } -+ -+/*disable IRQ*/ -+ _btif_irq_ctrl(p_btif_irq, false); -+ i_ret = 0; -+ BTIF_DBG_FUNC("succeed\n"); -+ return i_ret; -+} -+ -+int _btif_controller_free(p_mtk_btif p_btif) -+{ -+/*No need to set BTIF to PIO mode, only enable BTIF CG*/ -+ hal_btif_rx_cb_reg(p_btif->p_btif_info, (btif_rx_buf_write) NULL); -+ _btif_irq_free(p_btif->p_btif_info->p_irq, p_btif); -+ return hal_btif_clk_ctrl(p_btif->p_btif_info, CLK_OUT_DISABLE); -+} -+ -+int _btif_init(p_mtk_btif p_btif) -+{ -+ int i_ret = 0; -+ -+ i_ret = _btif_controller_setup(p_btif); -+ if (i_ret) { -+ BTIF_ERR_FUNC("_btif_controller_init failed, i_ret(%d)\n", -+ i_ret); -+ _btif_dpidle_notify_ctrl(p_btif, BTIF_DPIDLE_ENABLE); -+ BTIF_STATE_RELEASE(p_btif); -+ return i_ret; -+ } -+ -+ i_ret = _btif_controller_tx_setup(p_btif); -+ if (i_ret) { -+ BTIF_ERR_FUNC("_btif_controller_tx_setup failed, i_ret(%d)\n", -+ i_ret); -+ _btif_controller_free(p_btif); -+ _btif_dpidle_notify_ctrl(p_btif, BTIF_DPIDLE_ENABLE); -+ BTIF_STATE_RELEASE(p_btif); -+ return i_ret; -+ } -+ -+ i_ret = _btif_controller_rx_setup(p_btif); -+ if (i_ret) { -+ BTIF_ERR_FUNC("_btif_controller_tx_setup failed, i_ret(%d)\n", -+ i_ret); -+ _btif_controller_tx_free(p_btif); -+ _btif_controller_free(p_btif); -+ _btif_dpidle_notify_ctrl(p_btif, BTIF_DPIDLE_ENABLE); -+ BTIF_STATE_RELEASE(p_btif); -+ return i_ret; -+ } -+ return i_ret; -+} -+ -+int btif_open(p_mtk_btif p_btif) -+{ -+ int i_ret = -1; -+ -+ if (p_btif->enable) -+ return E_BTIF_ALREADY_OPEN; -+ -+/*hold state mechine lock*/ -+ if (_btif_state_hold(p_btif)) -+ return E_BTIF_INTR; -+/*disable deepidle*/ -+ _btif_dpidle_notify_ctrl(p_btif, BTIF_DPIDLE_DISABLE); -+ -+ i_ret = _btif_init(p_btif); -+ if (i_ret == 0) { -+ /*set BTIF's enable flag*/ -+ p_btif->enable = true; -+ _btif_state_set(p_btif, B_S_ON); -+ } else { -+ _btif_dpidle_notify_ctrl(p_btif, BTIF_DPIDLE_ENABLE); -+ } -+ btif_log_buf_reset(&p_btif->tx_log); -+ btif_log_buf_reset(&p_btif->rx_log); -+ -+ BTIF_STATE_RELEASE(p_btif); -+ -+ BTIF_DBG_FUNC("BTIF's Tx Mode:%d, Rx Mode(%d)\n", -+ p_btif->tx_mode, p_btif->rx_mode); -+ return i_ret; -+} -+ -+int btif_close(p_mtk_btif p_btif) -+{ -+ int i_ret = 0; -+ -+ if (!(p_btif->enable)) -+ return E_BTIF_NOT_OPEN; -+ -+/*hold state mechine lock*/ -+ if (_btif_state_hold(p_btif)) -+ return E_BTIF_INTR; -+/*always set state back to B_S_ON before do close operation*/ -+ _btif_exit_dpidle(p_btif); -+/*set BTIF's state to disable state*/ -+ p_btif->enable = false; -+ -+ _btif_controller_free(p_btif); -+ _btif_controller_tx_free(p_btif); -+ _btif_controller_rx_free(p_btif); -+ -+/*reset BTIF's rx_cb function*/ -+ p_btif->rx_cb = NULL; -+ p_btif->rx_notify = NULL; -+ p_btif->lpbk_flag = false; -+ -+/*set state mechine to B_S_OFF*/ -+ _btif_state_set(p_btif, B_S_OFF); -+ -+ btif_log_buf_disable(&p_btif->tx_log); -+ btif_log_buf_disable(&p_btif->rx_log); -+ -+ BTIF_STATE_RELEASE(p_btif); -+ -+ return i_ret; -+} -+ -+int _btif_exit_dpidle(p_mtk_btif p_btif) -+{ -+ int i_ret = -1; -+ ENUM_BTIF_STATE state = B_S_MAX; -+ -+ state = _btif_state_get(p_btif); -+ switch (state) { -+ case B_S_DPIDLE: -+ i_ret = _btif_exit_dpidle_from_dpidle(p_btif); -+ break; -+ case B_S_SUSPEND: -+/*in suspend state, need to do reinit of btif*/ -+ i_ret = _btif_exit_dpidle_from_sus(p_btif); -+ break; -+ case B_S_OFF: -+ i_ret = _btif_init(p_btif); -+ break; -+ case B_S_ON: -+ i_ret = 0; /* for btif_close case */ -+ break; -+ default: -+ i_ret = E_BTIF_INVAL_PARAM; -+ BTIF_INFO_FUNC("invalid state change:%d->\n", state, B_S_ON); -+ break; -+ } -+ -+ if (i_ret == 0) -+ i_ret = _btif_state_set(p_btif, B_S_ON); -+ return i_ret; -+} -+ -+int btif_exit_dpidle(p_mtk_btif p_btif) -+{ -+ int i_ret = 0; -+ -+/*hold state mechine lock*/ -+ if (_btif_state_hold(p_btif)) -+ return E_BTIF_INTR; -+ i_ret = _btif_exit_dpidle(p_btif); -+ BTIF_STATE_RELEASE(p_btif); -+ return i_ret; -+} -+ -+int _btif_enter_dpidle(p_mtk_btif p_btif) -+{ -+ int i_ret = 0; -+ ENUM_BTIF_STATE state = B_S_MAX; -+ -+ state = _btif_state_get(p_btif); -+ if (state == B_S_ON) { -+ i_ret = _btif_enter_dpidle_from_on(p_btif); -+ } else if (state == B_S_SUSPEND) { -+ /*do reinit and enter deepidle*/ -+ i_ret = _btif_enter_dpidle_from_sus(p_btif); -+ } else if (state == B_S_DPIDLE) { -+ /*do nothing*/ -+ i_ret = 0; -+ } else { -+ BTIF_WARN_FUNC("operation is not allowed, current state:%d\n", -+ state); -+ i_ret = E_BTIF_INVAL_STATE; -+ } -+/*anyway, set to B_S_DPIDLE state*/ -+ if (i_ret == 0) -+ i_ret = _btif_state_set(p_btif, B_S_DPIDLE); -+ return i_ret; -+} -+ -+int btif_enter_dpidle(p_mtk_btif p_btif) -+{ -+ int i_ret = 0; -+ -+/*hold state mechine lock*/ -+ if (_btif_state_hold(p_btif)) -+ return E_BTIF_INTR; -+ i_ret = _btif_enter_dpidle(p_btif); -+ BTIF_STATE_RELEASE(p_btif); -+ return i_ret; -+} -+ -+int _btif_exit_dpidle_from_dpidle(p_mtk_btif p_btif) -+{ -+ int i_ret = 0; -+ -+/*in dpidle state, only need to open related clock*/ -+ if (p_btif->tx_mode == BTIF_MODE_DMA) { -+ /*enable BTIF Tx DMA's clock*/ -+ i_ret += hal_btif_dma_clk_ctrl(p_btif->p_tx_dma->p_dma_info, -+ CLK_OUT_ENABLE); -+ } -+ if (p_btif->rx_mode == BTIF_MODE_DMA) { -+ /*enable BTIF Rx DMA's clock*/ -+ i_ret += hal_btif_dma_clk_ctrl(p_btif->p_rx_dma->p_dma_info, -+ CLK_OUT_ENABLE); -+ } -+/*enable BTIF's clock*/ -+ i_ret += hal_btif_clk_ctrl(p_btif->p_btif_info, CLK_OUT_ENABLE); -+ -+ if (i_ret != 0) -+ BTIF_WARN_FUNC("failed, i_ret:%d\n", i_ret); -+ return i_ret; -+} -+ -+int _btif_exit_dpidle_from_sus(p_mtk_btif p_btif) -+{ -+/*in suspend state, need to do driver re-init*/ -+ -+ int i_ret = _btif_init(p_btif); -+ -+ return i_ret; -+} -+ -+int _btif_enter_dpidle_from_sus(p_mtk_btif p_btif) -+{ -+/*do driiver reinit*/ -+ int i_ret = _btif_init(p_btif); -+ -+ if (i_ret == 0) -+ i_ret = _btif_enter_dpidle_from_on(p_btif); -+ return i_ret; -+} -+ -+int _btif_enter_dpidle_from_on(p_mtk_btif p_btif) -+{ -+#define MAX_WAIT_TIME_MS 5000 -+/* -+ * this max wait time cannot exceed 12s, -+ * because dpm will monitor each device's -+ * resume/suspend process by start up a watch dog timer of 12s -+ * incase of one driver's suspend/resume process block other device's suspend/resume -+ */ -+ int i_ret = 0; -+ unsigned int retry = 0; -+ unsigned int wait_period = 1; -+ unsigned int max_retry = MAX_WAIT_TIME_MS / wait_period; -+ struct timeval timer_start; -+ struct timeval timer_now; -+ -+ do_gettimeofday(&timer_start); -+ -+ while ((!_btif_is_tx_complete(p_btif)) && (retry < max_retry)) { -+ do_gettimeofday(&timer_now); -+ if ((MAX_WAIT_TIME_MS/1000) <= (timer_now.tv_sec - timer_start.tv_sec)) { -+ BTIF_WARN_FUNC("max retry timer expired, timer_start.tv_sec:%d, timer_now.tv_sec:%d,", -+ "retry:%d\n", timer_start.tv_sec, timer_now.tv_sec, retry); -+ break; -+ } -+ msleep(wait_period); -+ retry++; -+ } -+ -+ if (retry < max_retry) { -+ if (p_btif->tx_mode == BTIF_MODE_DMA) { -+ /*disable BTIF Tx DMA's clock*/ -+ i_ret += -+ hal_btif_dma_clk_ctrl(p_btif->p_tx_dma->p_dma_info, -+ CLK_OUT_DISABLE); -+ } -+ if (p_btif->rx_mode == BTIF_MODE_DMA) { -+ /*disable BTIF Rx DMA's clock*/ -+ i_ret += -+ hal_btif_dma_clk_ctrl(p_btif->p_rx_dma->p_dma_info, -+ CLK_OUT_DISABLE); -+ } -+/*disable BTIF's clock*/ -+ i_ret += -+ hal_btif_clk_ctrl(p_btif->p_btif_info, CLK_OUT_DISABLE); -+ -+ if (i_ret) -+ BTIF_WARN_FUNC("failed, i_ret:%d\n", i_ret); -+ } else -+ i_ret = -1; -+ -+ return i_ret; -+} -+ -+int _btif_dpidle_notify_ctrl(p_mtk_btif p_btif, ENUM_BTIF_DPIDLE_CTRL en_flag) -+{ -+/*call WCP's API to control deepidle's enable/disable*/ -+ if (en_flag == BTIF_DPIDLE_DISABLE) -+ hal_btif_pm_ops(p_btif->p_btif_info, BTIF_PM_DPIDLE_DIS); -+ else -+ hal_btif_pm_ops(p_btif->p_btif_info, BTIF_PM_DPIDLE_EN); -+ -+ return 0; -+} -+ -+int btif_rx_cb_reg(p_mtk_btif p_btif, MTK_WCN_BTIF_RX_CB rx_cb) -+{ -+ if (p_btif->rx_cb) { -+ BTIF_WARN_FUNC -+ ("rx cb already exist, rewrite from (0x%p) to (0x%p)\n", -+ p_btif->rx_cb, rx_cb); -+ } -+ p_btif->rx_cb = rx_cb; -+ -+ return 0; -+} -+ -+int btif_raise_wak_signal(p_mtk_btif p_btif) -+{ -+ int i_ret = 0; -+ P_MTK_BTIF_INFO_STR p_btif_info = p_btif->p_btif_info; -+ -+#if MTK_BTIF_ENABLE_CLK_REF_COUNTER -+ hal_btif_clk_ctrl(p_btif->p_btif_info, CLK_OUT_ENABLE); -+#endif -+ -+ i_ret = hal_btif_raise_wak_sig(p_btif_info); -+ -+#if MTK_BTIF_ENABLE_CLK_REF_COUNTER -+ hal_btif_clk_ctrl(p_btif_info, CLK_OUT_DISABLE); -+#endif -+ return i_ret; -+} -+ -+bool _btif_is_tx_complete(p_mtk_btif p_btif) -+{ -+ bool b_ret = false; -+ ENUM_BTIF_MODE tx_mode = p_btif->tx_mode; -+ -+/* -+ * make sure BTIF tx finished in PIO mode -+ * make sure BTIF tx finished and DMA tx finished in DMA mode -+ */ -+ if (tx_mode == BTIF_MODE_DMA) { -+ b_ret = hal_dma_is_tx_complete(p_btif->p_tx_dma->p_dma_info); -+ if (b_ret == false) { -+ BTIF_DBG_FUNC("Tx DMA is not finished\n"); -+ return b_ret; -+ } -+ } -+ -+ b_ret = hal_btif_is_tx_complete(p_btif->p_btif_info); -+ if (b_ret == false) { -+ BTIF_DBG_FUNC("BTIF Tx is not finished\n"); -+ return b_ret; -+ } -+ b_ret = true; -+ return b_ret; -+} -+ -+/*--------------------------------Functions-------------------------------------------*/ -+ -+#if ENABLE_BTIF_TX_DMA -+static int _btif_vfifo_init(p_mtk_btif_dma p_dma) -+{ -+ P_DMA_VFIFO p_vfifo = NULL; -+ struct device *dev = NULL; -+ p_mtk_btif p_btif = NULL; -+ -+ if (p_dma == NULL) { -+ BTIF_ERR_FUNC("p_dma is NULL\n"); -+ return E_BTIF_INVAL_PARAM; -+ } -+ -+ p_btif = (p_mtk_btif)p_dma->p_btif; -+ -+ if (p_btif == NULL) { -+ BTIF_ERR_FUNC("invalid parameter: p_btif(0x%p)\n", p_btif); -+ return E_BTIF_INVAL_PARAM; -+ } -+ -+ dev = (struct device *)p_btif->private_data; -+ if (dev == NULL) -+ BTIF_WARN_FUNC("Null dev pointer!!!!\n"); -+ -+ p_vfifo = p_dma->p_dma_info->p_vfifo; -+ if (p_vfifo->p_vir_addr != NULL) { -+ BTIF_ERR_FUNC -+ ("BTIF vFIFO memory already allocated, do nothing\n"); -+ return E_BTIF_BAD_POINTER; -+ } -+ -+/*vFIFO memory allocation*/ -+ p_vfifo->p_vir_addr = dma_zalloc_coherent(dev, -+ p_vfifo->vfifo_size, -+ &p_vfifo->phy_addr, GFP_DMA | GFP_DMA32); -+ if (p_vfifo->p_vir_addr == NULL) { -+ BTIF_ERR_FUNC("alloc vFIFO memory for BTIF failed\n"); -+ return E_BTIF_FAIL; -+ } -+ -+ if (sizeof(dma_addr_t) == sizeof(unsigned long long)) -+ BTIF_INFO_FUNC("alloc vFIFO for BTIF succeed in arch64,vir addr:0x%p,", -+ "phy addr:0x%llx\n", p_vfifo->p_vir_addr, p_vfifo->phy_addr); -+ else -+ BTIF_INFO_FUNC("alloc vFIFO for BTIF succeed in arch32,vir addr:0x%p,", -+ "phy addr:0x%08x\n", p_vfifo->p_vir_addr, p_vfifo->phy_addr); -+ -+ return 0; -+} -+#endif -+#if ENABLE_BTIF_TX_DMA -+static int _btif_vfifo_deinit(p_mtk_btif_dma p_dma) -+{ -+ P_DMA_VFIFO p_vfifo = NULL; -+ struct device *dev = NULL; -+ p_mtk_btif p_btif = NULL; -+ -+ if (p_dma == NULL) { -+ BTIF_ERR_FUNC("p_dma is NULL\n"); -+ return E_BTIF_INVAL_PARAM; -+ } -+ -+ -+ p_btif = (p_mtk_btif)p_dma->p_btif; -+ if (p_btif == NULL) { -+ BTIF_ERR_FUNC("invalid parameter: p_btif(0x%p)\n", p_btif); -+ return E_BTIF_INVAL_PARAM; -+ } -+ -+ dev = (struct device *)p_btif->private_data; -+ if (dev == NULL) -+ BTIF_WARN_FUNC("Null dev pointer!!!!\n"); -+ -+ p_vfifo = p_dma->p_dma_info->p_vfifo; -+ -+/*free DMA memory if allocated successfully before*/ -+ if (p_vfifo->p_vir_addr != NULL) { -+ dma_free_coherent(dev, -+ p_vfifo->vfifo_size, -+ p_vfifo->p_vir_addr, p_vfifo->phy_addr); -+ p_vfifo->p_vir_addr = NULL; -+ } -+ -+ return 0; -+} -+#endif -+ -+static int _btif_state_init(p_mtk_btif p_btif) -+{ -+ if (p_btif == NULL) { -+ BTIF_ERR_FUNC("p_btif is NULL\n"); -+ return E_BTIF_INVAL_PARAM; -+ } -+ p_btif->state = B_S_OFF; -+ mutex_init(&(p_btif->state_mtx)); -+ -+ return 0; -+} -+ -+static int _btif_state_hold(p_mtk_btif p_btif) -+{ -+ return mutex_lock_killable(&(p_btif->state_mtx)); -+} -+ -+static int _btif_state_set(p_mtk_btif p_btif, ENUM_BTIF_STATE state) -+{ -+/*chaozhong: To do: need to finished state mechine here*/ -+ int i_ret = 0; -+ int ori_state = p_btif->state; -+ -+ if (ori_state == state) { -+ BTIF_INFO_FUNC("already in %s state\n", g_state[state]); -+ return i_ret; -+ } -+ if ((state >= B_S_OFF) && (state < B_S_MAX)) { -+ BTIF_DBG_FUNC("%s->%s request\n", g_state[ori_state], -+ g_state[state]); -+ if (state == B_S_ON) -+ _btif_dpidle_notify_ctrl(p_btif, BTIF_DPIDLE_DISABLE); -+ switch (ori_state) { -+ case B_S_ON: -+/*B_S_ON can only be switched to B_S_OFF, B_S_SUSPEND and B_S_DPIDLE*/ -+/*B_S_ON->B_S_OFF : do nothing here*/ -+/* -+ * B_S_ON->B_S_DPLE : disable clock backup -+ * BTIF and DMA controller's register if necessary -+ */ -+ if (state == B_S_DPIDLE) { -+ /*clock controlled id done in _btif_enter_dpidle*/ -+ p_btif->state = state; -+ i_ret = 0; -+ } else if (state == B_S_OFF) { -+ /*clock controlled is done in btif_close*/ -+ p_btif->state = state; -+ i_ret = 0; -+ } else if (state == B_S_SUSPEND) { -+ /*clock controlled is done in btif_close*/ -+ p_btif->state = state; -+ i_ret = 0; -+ } else { -+ BTIF_ERR_FUNC("%s->%s is not allowed\n", -+ g_state[ori_state], -+ g_state[state]); -+ i_ret = E_BTIF_INVAL_STATE; -+ } -+ break; -+ case B_S_DPIDLE: -+/*B_S_DPIDLE can only be switched to B_S_ON and B_S_SUSPEND*/ -+/*B_S_DPIDLE-> B_S_ON: do nothing for this moment*/ -+/* -+ * B_S_DPIDLE-> B_S_SUSPEND: -+ * disable clock backup BTIF and DMA controller's register if necessary -+ */ -+ if (state == B_S_ON) { -+ /*clock controlled id done in _btif_exit_dpidle*/ -+ p_btif->state = state; -+ i_ret = 0; -+ } else if (state == B_S_SUSPEND) { -+ /*clock controlled is done in _btif_exit_dpidle*/ -+ p_btif->state = state; -+ i_ret = 0; -+ } else { -+ BTIF_ERR_FUNC("%s->%s is not allowed\n", -+ g_state[ori_state], -+ g_state[state]); -+ i_ret = E_BTIF_INVAL_STATE; -+ } -+ break; -+ -+ case B_S_SUSPEND: -+/*B_S_SUSPEND can be switched to B_S_IDLE and B_S_ON*/ -+/*reinit BTIF controller and DMA controller*/ -+ if (state == B_S_DPIDLE) { -+ /* -+ * system call resume API, do resume operation, -+ * change to deepidle state -+ */ -+ p_btif->state = state; -+ i_ret = 0; -+ } else if (state == B_S_ON) { -+ /* -+ * when stp want to send data before -+ * system do resume operation -+ */ -+ p_btif->state = state; -+ i_ret = 0; -+ } else { -+ BTIF_ERR_FUNC("%s->%s is not allowed\n", -+ g_state[ori_state], -+ g_state[state]); -+ i_ret = E_BTIF_INVAL_STATE; -+ } -+ break; -+ -+ case B_S_OFF:{ -+/*B_S_OFF can only be switched to B_S_ON*/ -+ if (state == B_S_ON) { -+ /*clock controlled is done in btif_open*/ -+ p_btif->state = state; -+ i_ret = 0; -+ } else { -+ BTIF_ERR_FUNC("%s->%s is not allowed\n", -+ g_state[ori_state], -+ g_state[state]); -+ i_ret = E_BTIF_INVAL_STATE; -+ } -+ } -+ break; -+ default: -+/*no this possibility*/ -+ BTIF_ERR_FUNC -+ ("state change request is not allowed, this should never happen\n"); -+ break; -+ } -+ -+ if (state != B_S_ON) -+ _btif_dpidle_notify_ctrl(p_btif, BTIF_DPIDLE_ENABLE); -+ -+ } else { -+ i_ret = E_BTIF_INVAL_PARAM; -+ BTIF_ERR_FUNC("invalid state:%d, do nothing\n", state); -+ } -+ return i_ret; -+} -+ -+static ENUM_BTIF_STATE _btif_state_get(p_mtk_btif p_btif) -+{ -+ return p_btif->state; -+} -+ -+static int _btif_state_release(p_mtk_btif p_btif) -+{ -+ int i_ret = 0; -+ -+ BTIF_MUTEX_UNLOCK(&(p_btif->state_mtx)); -+ return i_ret; -+} -+ -+static int _btif_state_deinit(p_mtk_btif p_btif) -+{ -+ if (p_btif == NULL) { -+ BTIF_ERR_FUNC("p_btif is NULL\n"); -+ return E_BTIF_INVAL_PARAM; -+ } -+ p_btif->state = B_S_OFF; -+ mutex_destroy(&(p_btif->state_mtx)); -+ -+ return 0; -+} -+ -+static int btif_rx_data_consummer(p_mtk_btif p_btif) -+{ -+ unsigned int length = 0; -+ unsigned char *p_buf = NULL; -+/*get BTIF rx buffer's information*/ -+ p_btif_buf_str p_bbs = &(p_btif->btif_buf); -+/* -+ * wr_idx of btif_buf may be modified in IRQ handler, -+ * in order not to be effected by case in which irq interrupt this operation, -+ * we record wr_idx here -+ */ -+ unsigned int wr_idx = p_bbs->wr_idx; -+ -+ length = BBS_COUNT_CUR(p_bbs, wr_idx); -+ -+/*make sure length of rx buffer data > 0*/ -+ do { -+ if (length > 0) { -+ /* -+ * check if rx_cb empty or not, if registered , -+ * call user's rx callback to handle these data -+ */ -+ if (p_btif->rx_cb) { -+ if (p_bbs->rd_idx <= wr_idx) { -+ p_buf = BBS_PTR(p_bbs, p_bbs->rd_idx); -+ /* p_buf = &(p_bbs->buf[p_bbs->rd_idx]); */ -+ /* length = BBS_COUNT(p_bbs); */ -+ length = (wr_idx >= (p_bbs)->rd_idx) ? -+ (wr_idx - (p_bbs)->rd_idx) : -+ BBS_SIZE(p_bbs) - -+ ((p_bbs)->rd_idx - wr_idx); -+ if (p_btif->rx_cb) -+ (*(p_btif->rx_cb)) (p_buf, length); -+ else -+ BTIF_ERR_FUNC("p_btif->rx_cb is NULL\n"); -+ /*update rx data read index*/ -+ p_bbs->rd_idx = wr_idx; -+ } else { -+ unsigned int len_tail = -+ BBS_SIZE(p_bbs) - (p_bbs)->rd_idx; -+ /*p_buf = &(p_bbs->buf[p_bbs->->rd_idx]);*/ -+ p_buf = BBS_PTR(p_bbs, p_bbs->rd_idx); -+ if (p_btif->rx_cb) -+ (*(p_btif->rx_cb)) (p_buf, len_tail); -+ else -+ BTIF_ERR_FUNC("p_btif->rx_cb is NULL\n"); -+ length = BBS_COUNT_CUR(p_bbs, wr_idx); -+ length -= len_tail; -+ /*p_buf = &(p_bbs->buf[0]);*/ -+ p_buf = BBS_PTR(p_bbs, 0); -+ if (p_btif->rx_cb) -+ (*(p_btif->rx_cb)) (p_buf, length); -+ else -+ BTIF_ERR_FUNC("p_btif->rx_cb is NULL\n"); -+ /*update rx data read index*/ -+ p_bbs->rd_idx = wr_idx; -+ } -+ } else if (p_btif->rx_notify != NULL) { -+ (*p_btif->rx_notify) (); -+ } else { -+ BTIF_WARN_FUNC -+ ("p_btif:0x%p, both rx_notify and rx_cb are NULL\n", -+ p_btif); -+ break; -+ } -+ } else { -+ BTIF_DBG_FUNC("length:%d\n", length); -+ break; -+ } -+ wr_idx = p_bbs->wr_idx; -+ length = BBS_COUNT_CUR(p_bbs, wr_idx); -+ } while (1); -+ return length; -+} -+ -+#if BTIF_RXD_BE_BLOCKED_DETECT -+static int mtk_btif_rxd_be_blocked_by_timer(void) -+{ -+ int ret = 0; -+ int counter = 0; -+ unsigned int i; -+ struct timeval now; -+ int time_gap[MAX_BTIF_RXD_TIME_REC]; -+ -+ do_gettimeofday(&now); -+ -+ for (i = 0; i < MAX_BTIF_RXD_TIME_REC; i++) { -+ BTIF_INFO_FUNC("btif_rxd_time_stamp[%d]=%d.%d\n", i, -+ btif_rxd_time_stamp[i].tv_sec, btif_rxd_time_stamp[i].tv_usec); -+ if (now.tv_sec >= btif_rxd_time_stamp[i].tv_sec) { -+ time_gap[i] = now.tv_sec - btif_rxd_time_stamp[i].tv_sec; -+ time_gap[i] *= 1000000; /*second*/ -+ if (now.tv_usec >= btif_rxd_time_stamp[i].tv_usec) -+ time_gap[i] += now.tv_usec - btif_rxd_time_stamp[i].tv_usec; -+ else -+ time_gap[i] += 1000000 - now.tv_usec + btif_rxd_time_stamp[i].tv_usec; -+ -+ if (time_gap[i] > 1000000) -+ counter++; -+ BTIF_INFO_FUNC("time_gap[%d]=%d,counter:%d\n", i, time_gap[i], counter); -+ } else { -+ time_gap[i] = 0; -+ BTIF_ERR_FUNC("abnormal case now:%d < time_stamp[%d]:%d\n", now.tv_sec, -+ i, btif_rxd_time_stamp[i].tv_usec); -+ } -+ } -+ if (counter > (MAX_BTIF_RXD_TIME_REC - 2)) -+ ret = 1; -+ return ret; -+} -+static int mtk_btif_rxd_be_blocked_by_data(void) -+{ -+ unsigned int out_index = 0; -+ unsigned int in_index = 0; -+ unsigned int dump_size = 0; -+ unsigned int len = 0; -+ unsigned long flags; -+ unsigned int sync_pkt_n = 0; -+ P_BTIF_LOG_BUF_T p_log_buf = NULL; -+ P_BTIF_LOG_QUEUE_T p_log_que = NULL; -+ p_mtk_btif p_btif = &(g_btif[0]); -+ -+ p_log_que = &p_btif->rx_log; -+ spin_lock_irqsave(&p_log_que->lock, flags); -+ in_index = p_log_que->in; -+ dump_size = p_log_que->size; -+ out_index = p_log_que->size >= -+ BTIF_LOG_ENTRY_NUM ? in_index : (BTIF_LOG_ENTRY_NUM - -+ p_log_que->size + -+ in_index) % BTIF_LOG_ENTRY_NUM; -+ if (dump_size != 0) { -+ while (dump_size--) { -+ p_log_buf = p_log_que->p_queue[0] + out_index; -+ len = p_log_buf->len; -+ if (len > BTIF_LOG_SZ) -+ len = BTIF_LOG_SZ; -+ if ((0x7f == *(p_log_buf->buffer)) && (0x7f == *(p_log_buf->buffer + 1))) { -+ sync_pkt_n++; -+ BTIF_INFO_FUNC("tx pkt_count:%d is sync pkt\n", out_index); -+ } -+ out_index++; -+ out_index %= BTIF_LOG_ENTRY_NUM; -+ } -+ } -+ if (sync_pkt_n == 0) -+ BTIF_ERR_FUNC("there is no sync pkt in BTIF buffer\n"); -+ else -+ BTIF_ERR_FUNC("there are %d sync pkt in BTIF buffer\n", sync_pkt_n); -+ spin_unlock_irqrestore(&p_log_que->lock, flags); -+ return sync_pkt_n; -+} -+ -+int mtk_btif_rxd_be_blocked_flag_get(void) -+{ -+ int ret = 0; -+ int condition1 = 0, condition2 = 0; -+ -+ condition1 = mtk_btif_rxd_be_blocked_by_timer(); -+ condition2 = mtk_btif_rxd_be_blocked_by_data(); -+ if (condition1 && condition2) { -+ BTIF_ERR_FUNC("btif_rxd thread be blocked too long!\n"); -+ ret = 1; -+ } -+ return ret; -+} -+#endif -+static int btif_rx_thread(void *p_data) -+{ -+#if BTIF_RXD_BE_BLOCKED_DETECT -+ unsigned int i = 0; -+#endif -+ p_mtk_btif p_btif = (p_mtk_btif)p_data; -+ -+ -+ while (1) { -+ wait_for_completion_interruptible(&p_btif->rx_comp); -+ -+ if (kthread_should_stop()) { -+ BTIF_WARN_FUNC("btif rx thread stoping ...\n"); -+ break; -+ } -+#ifdef BTIF_RXD_BE_BLOCKED_DETECT -+ do_gettimeofday(&btif_rxd_time_stamp[i]); -+ i++; -+ if (i >= MAX_BTIF_RXD_TIME_REC) -+ i = 0; -+#endif -+ btif_rx_data_consummer(p_btif); -+ } -+ return 0; -+} -+ -+static void btif_rx_worker(struct work_struct *p_work) -+{ -+/*get mtk_btif's pointer*/ -+ p_mtk_btif p_btif = container_of(p_work, mtk_btif, rx_work); -+ -+ BTIF_DBG_FUNC("p_btif:0x%p\n", p_btif); -+/*lock rx_mutex*/ -+ -+ if (mutex_lock_killable(&(p_btif->rx_mtx))) { -+ BTIF_ERR_FUNC("mutex_lock_killable return failed\n"); -+ return; -+ } -+ btif_rx_data_consummer(p_btif); -+ BTIF_MUTEX_UNLOCK(&(p_btif->rx_mtx)); -+} -+ -+static void btif_tx_worker(struct work_struct *p_work) -+{ -+ int i_ret = 0; -+ int leng_sent = 0; -+/*tx fifo out*/ -+ int how_much_get = 0; -+ unsigned char local_buf[384]; -+ -+/*get mtk_btif's pointer*/ -+ p_mtk_btif p_btif = container_of(p_work, mtk_btif, tx_work); -+ -+ BTIF_DBG_FUNC("p_btif:0x%p\n", p_btif); -+ -+ if (mutex_lock_killable(&(p_btif->tx_mtx))) { -+ BTIF_ERR_FUNC("mutex_lock_killable return failed\n"); -+ return; -+ } -+ how_much_get = -+ kfifo_out(p_btif->p_tx_fifo, local_buf, sizeof(local_buf)); -+ do { -+ while (leng_sent < how_much_get) { -+ i_ret = _btif_send_data(p_btif, -+ local_buf + leng_sent, -+ how_much_get - leng_sent); -+ if (i_ret > 0) { -+ leng_sent += i_ret; -+ } else if (i_ret == 0) { -+ BTIF_WARN_FUNC -+ ("_btif_send_data return 0, retry\n"); -+ } else { -+ BTIF_WARN_FUNC -+ ("btif send data fail,reset tx fifo, i_ret(%d)\n", -+ i_ret); -+ kfifo_reset(p_btif->p_tx_fifo); -+ break; -+ } -+ } -+ how_much_get = -+ kfifo_out(p_btif->p_tx_fifo, local_buf, sizeof(local_buf)); -+ leng_sent = 0; -+ } while (how_much_get > 0); -+ BTIF_MUTEX_UNLOCK(&(p_btif->tx_mtx)); -+} -+ -+static void btif_rx_tasklet(unsigned long func_data) -+{ -+ unsigned long flags; -+/*get mtk_btif's pointer*/ -+ p_mtk_btif p_btif = (p_mtk_btif) func_data; -+ -+ BTIF_DBG_FUNC("p_btif:0x%p\n", p_btif); -+/*lock rx_spinlock*/ -+ spin_lock_irqsave(&p_btif->rx_tasklet_spinlock, flags); -+ btif_rx_data_consummer(p_btif); -+ spin_unlock_irqrestore(&p_btif->rx_tasklet_spinlock, flags); -+} -+ -+static int _btif_tx_ctx_init(p_mtk_btif p_btif) -+{ -+ int i_ret = -1; -+ -+ if (p_btif == NULL) { -+ BTIF_ERR_FUNC("p_btif is NULL\n"); -+ return E_BTIF_INVAL_PARAM; -+ } -+ -+ if (p_btif->tx_ctx == BTIF_TX_SINGLE_CTX) { -+ p_btif->p_tx_wq = create_singlethread_workqueue("btif_txd"); -+ -+ if (!(p_btif->p_tx_wq)) { -+ BTIF_ERR_FUNC -+ ("create_singlethread_workqueue for tx thread fail\n"); -+ i_ret = -ENOMEM; -+ goto btm_init_err; -+ } -+ mutex_init(&(p_btif->tx_mtx)); -+/* init btif tx work */ -+ INIT_WORK(&(p_btif->tx_work), btif_tx_worker); -+ BTIF_INFO_FUNC("btif_tx_worker init succeed\n"); -+ -+ p_btif->p_tx_fifo = kzalloc(sizeof(struct kfifo), GFP_ATOMIC); -+ if (p_btif->p_tx_fifo == NULL) { -+ i_ret = -ENOMEM; -+ BTIF_ERR_FUNC("kzalloc for p_btif->p_tx_fifo failed\n"); -+ goto btm_init_err; -+ } -+ -+ i_ret = kfifo_alloc(p_btif->p_tx_fifo, -+ BTIF_TX_FIFO_SIZE, GFP_ATOMIC); -+ if (i_ret != 0) { -+ BTIF_ERR_FUNC("kfifo_alloc failed, errno(%d)\n", i_ret); -+ i_ret = -ENOMEM; -+ goto btm_init_err; -+ } -+ } else if (p_btif->tx_ctx == BTIF_TX_USER_CTX) { -+ BTIF_INFO_FUNC -+ ("nothing is done when btif tx in user's thread\n"); -+ } else { -+ BTIF_ERR_FUNC("unsupported tx context type:%d\n", -+ p_btif->tx_ctx); -+ goto btm_init_err; -+ } -+ -+ BTIF_INFO_FUNC("succeed\n"); -+ -+ i_ret = 0; -+ return i_ret; -+btm_init_err: -+ if (p_btif->tx_ctx == BTIF_TX_SINGLE_CTX) { -+ if (p_btif->p_tx_wq) { -+ destroy_workqueue(p_btif->p_tx_wq); -+ p_btif->p_tx_wq = NULL; -+ BTIF_INFO_FUNC("btif_tx_workqueue destroyed\n"); -+ } -+ kfree(p_btif->p_tx_fifo); -+ } -+ return i_ret; -+} -+ -+static int _btif_tx_ctx_deinit(p_mtk_btif p_btif) -+{ -+ int i_ret = 0; -+ -+ if (p_btif->tx_ctx == BTIF_TX_SINGLE_CTX) { -+ if (p_btif->p_tx_wq) { -+ destroy_workqueue(p_btif->p_tx_wq); -+ p_btif->p_tx_wq = NULL; -+ BTIF_INFO_FUNC("btif_tx_workqueue destroyed\n"); -+ } -+ if (p_btif->p_tx_fifo) { -+ kfifo_free(p_btif->p_tx_fifo); -+ kfree(p_btif->p_tx_fifo); -+ p_btif->p_tx_fifo = NULL; -+ } -+ } -+ return i_ret; -+} -+ -+static int _btif_rx_btm_init(p_mtk_btif p_btif) -+{ -+ int i_ret = -1; -+ -+ if (p_btif == NULL) { -+ BTIF_ERR_FUNC("p_btif is NULL\n"); -+ return E_BTIF_INVAL_PARAM; -+ } -+ -+ if (p_btif->btm_type == BTIF_THREAD_CTX) { -+ init_completion(&p_btif->rx_comp); -+ -+ /*create kernel thread for later rx data handle*/ -+ p_btif->p_task = kthread_create(btif_rx_thread, p_btif, "btif_rxd"); -+ if (p_btif->p_task == NULL) { -+ BTIF_ERR_FUNC("kthread_create fail\n"); -+ i_ret = -ENOMEM; -+ goto btm_init_err; -+ } -+ -+#if ENABLE_BTIF_RX_THREAD_RT_SCHED -+ { -+ int i_ret = -1; -+ int policy = SCHED_FIFO; -+ struct sched_param param; -+ -+ param.sched_priority = MAX_RT_PRIO - 20; -+ i_ret = sched_setscheduler(p_btif->p_task, policy, ¶m); -+ if (i_ret != 0) -+ BTIF_WARN_FUNC("set RT to btif_rxd workqueue failed\n"); -+ else -+ BTIF_INFO_FUNC("set RT to btif_rxd workqueue succeed\n"); -+ } -+#endif -+ -+ wake_up_process(p_btif->p_task); -+ BTIF_INFO_FUNC("btif_rxd start to work!\n"); -+ } else if (p_btif->btm_type == BTIF_WQ_CTX) { -+ p_btif->p_rx_wq = create_singlethread_workqueue("btif_rxwq"); -+ if (!(p_btif->p_rx_wq)) { -+ BTIF_ERR_FUNC("create_singlethread_workqueue fail\n"); -+ i_ret = -ENOMEM; -+ goto btm_init_err; -+ } -+ mutex_init(&(p_btif->rx_mtx)); -+ /* init btif rx work */ -+ INIT_WORK(&(p_btif->rx_work), btif_rx_worker); -+ BTIF_INFO_FUNC("btif_rx_worker init succeed\n"); -+ } else if (p_btif->btm_type == BTIF_TASKLET_CTX) { -+ /*init rx tasklet*/ -+ tasklet_init(&(p_btif->rx_tasklet), btif_rx_tasklet, -+ (unsigned long)p_btif); -+ spin_lock_init(&(p_btif->rx_tasklet_spinlock)); -+ BTIF_INFO_FUNC("btif_rx_tasklet init succeed\n"); -+ } else { -+ BTIF_ERR_FUNC("unsupported rx context type:%d\n", -+ p_btif->btm_type); -+ } -+ -+/*spinlock init*/ -+ spin_lock_init(&(p_btif->rx_irq_spinlock)); -+ BTIF_INFO_FUNC("rx_spin_lock init succeed\n"); -+ -+ i_ret = 0; -+ return i_ret; -+btm_init_err: -+ if (p_btif->btm_type == BTIF_THREAD_CTX) { -+ /*do nothing*/ -+ BTIF_INFO_FUNC("failed\n"); -+ } else if (p_btif->btm_type == BTIF_WQ_CTX) { -+ if (p_btif->p_rx_wq) { -+ destroy_workqueue(p_btif->p_rx_wq); -+ p_btif->p_rx_wq = NULL; -+ BTIF_INFO_FUNC("btif_rx_workqueue destroyed\n"); -+ } -+ } -+ return i_ret; -+} -+ -+static int _btif_rx_btm_sched(p_mtk_btif p_btif) -+{ -+ if (p_btif == NULL) { -+ BTIF_ERR_FUNC("p_btif is NULL\n"); -+ return E_BTIF_INVAL_PARAM; -+ } -+ -+ if (p_btif->btm_type == BTIF_THREAD_CTX) { -+ complete(&p_btif->rx_comp); -+ BTIF_DBG_FUNC("schedule btif_rx_thread\n"); -+ } else if (p_btif->btm_type == BTIF_WQ_CTX) { -+ queue_work(p_btif->p_rx_wq, &(p_btif->rx_work)); -+ BTIF_DBG_FUNC("schedule btif_rx_worker\n"); -+ } else if (p_btif->btm_type == BTIF_TASKLET_CTX) { -+ /*schedule it!*/ -+ tasklet_schedule(&(p_btif->rx_tasklet)); -+ BTIF_DBG_FUNC("schedule btif_rx_tasklet\n"); -+ } else { -+ BTIF_ERR_FUNC("unsupported rx context type:%d\n", -+ p_btif->btm_type); -+ } -+ -+ return 0; -+} -+ -+static int _btif_rx_btm_deinit(p_mtk_btif p_btif) -+{ -+ if (p_btif == NULL) { -+ BTIF_ERR_FUNC("p_btif is NULL\n"); -+ return E_BTIF_INVAL_PARAM; -+ } -+ if (p_btif->btm_type == BTIF_THREAD_CTX) { -+ if (p_btif->p_task != NULL) { -+ BTIF_INFO_FUNC("signaling btif rx thread to stop ...\n"); -+ kthread_stop(p_btif->p_task); -+ } -+ } else if (p_btif->btm_type == BTIF_WQ_CTX) { -+ if (p_btif->p_rx_wq) { -+ cancel_work_sync(&(p_btif->rx_work)); -+ BTIF_INFO_FUNC("btif_rx_worker cancelled\n"); -+ destroy_workqueue(p_btif->p_rx_wq); -+ p_btif->p_rx_wq = NULL; -+ BTIF_INFO_FUNC("btif_rx_workqueue destroyed\n"); -+ } -+ mutex_destroy(&(p_btif->rx_mtx)); -+ } else if (p_btif->btm_type == BTIF_TASKLET_CTX) { -+ tasklet_kill(&(p_btif->rx_tasklet)); -+ BTIF_INFO_FUNC("rx_tasklet killed\n"); -+ } else { -+ BTIF_ERR_FUNC("unsupported rx context type:%d\n", -+ p_btif->btm_type); -+ } -+ -+ spin_lock_init(&(p_btif->rx_irq_spinlock)); -+ -+ return 0; -+} -+ -+ -+void btif_dump_bbs_str(unsigned char *p_str, p_btif_buf_str p_bbs) -+{ -+ BTIF_INFO_FUNC -+ ("%s UBS:0x%p\n Size:0x%p\n read:0x%08x\n write:0x%08x\n", -+ p_str, p_bbs, p_bbs->size, p_bbs->rd_idx, p_bbs->wr_idx); -+} -+ -+unsigned int btif_bbs_write(p_btif_buf_str p_bbs, -+ unsigned char *p_buf, unsigned int buf_len) -+{ -+/*in IRQ context, so read operation won't interrupt this operation*/ -+ -+ unsigned int wr_len = 0; -+ -+ unsigned int emp_len = BBS_LEFT(p_bbs); -+ unsigned int ava_len = emp_len - 1; -+ p_mtk_btif p_btif = container_of(p_bbs, mtk_btif, btif_buf); -+ -+ if (ava_len <= 0) { -+ BTIF_ERR_FUNC -+ ("no empty space left for write, (%d)ava_len, (%d)to write\n", -+ ava_len, buf_len); -+ hal_btif_dump_reg(p_btif->p_btif_info, REG_BTIF_ALL); -+ hal_dma_dump_reg(p_btif->p_rx_dma->p_dma_info, REG_RX_DMA_ALL); -+ return 0; -+ } -+ -+ if (ava_len < buf_len) { -+ BTIF_ERR_FUNC("BTIF overrun, (%d)empty, (%d)needed\n", -+ emp_len, buf_len); -+ hal_btif_dump_reg(p_btif->p_btif_info, REG_BTIF_ALL); -+ hal_dma_dump_reg(p_btif->p_rx_dma->p_dma_info, REG_RX_DMA_ALL); -+ _btif_dump_memory("", p_buf, buf_len); -+ } -+ -+ if (buf_len >= g_max_pkg_len) { -+ BTIF_WARN_FUNC("buf_len too long, (%d)ava_len, (%d)to write\n", -+ ava_len, buf_len); -+ hal_btif_dump_reg(p_btif->p_btif_info, REG_BTIF_ALL); -+ hal_dma_dump_reg(p_btif->p_rx_dma->p_dma_info, REG_RX_DMA_ALL); -+ _btif_dump_memory("", p_buf, buf_len); -+ } -+ -+ wr_len = min(buf_len, ava_len); -+ btif_bbs_wr_direct(p_bbs, p_buf, wr_len); -+ -+ if (BBS_COUNT(p_bbs) >= g_max_pding_data_size) { -+ BTIF_WARN_FUNC("Rx buf_len too long, size(%d)\n", -+ BBS_COUNT(p_bbs)); -+ btif_dump_bbs_str("Rx buffer tooo long", p_bbs); -+ hal_btif_dump_reg(p_btif->p_btif_info, REG_BTIF_ALL); -+ hal_dma_dump_reg(p_btif->p_rx_dma->p_dma_info, REG_RX_DMA_ALL); -+ _btif_dump_memory("", p_buf, buf_len); -+ BBS_INIT(p_bbs); -+ } -+ -+ return wr_len; -+} -+ -+unsigned int btif_bbs_read(p_btif_buf_str p_bbs, -+ unsigned char *p_buf, unsigned int buf_len) -+{ -+ unsigned int rd_len = 0; -+ unsigned int ava_len = 0; -+ unsigned int wr_idx = p_bbs->wr_idx; -+ -+ ava_len = BBS_COUNT_CUR(p_bbs, wr_idx); -+ if (ava_len >= 4096) { -+ BTIF_WARN_FUNC("ava_len too long, size(%d)\n", ava_len); -+ btif_dump_bbs_str("Rx buffer tooo long", p_bbs); -+ } -+ if (ava_len != 0) { -+ if (buf_len >= ava_len) { -+ rd_len = ava_len; -+ if (wr_idx >= (p_bbs)->rd_idx) { -+ memcpy(p_buf, BBS_PTR(p_bbs, -+ p_bbs->rd_idx), -+ ava_len); -+ (p_bbs)->rd_idx = wr_idx; -+ } else { -+ unsigned int tail_len = BBS_SIZE(p_bbs) - -+ (p_bbs)->rd_idx; -+ memcpy(p_buf, BBS_PTR(p_bbs, -+ p_bbs->rd_idx), -+ tail_len); -+ memcpy(p_buf + tail_len, BBS_PTR(p_bbs, -+ 0), ava_len - tail_len); -+ (p_bbs)->rd_idx = wr_idx; -+ } -+ } else { -+ rd_len = buf_len; -+ if (wr_idx >= (p_bbs)->rd_idx) { -+ memcpy(p_buf, BBS_PTR(p_bbs, -+ p_bbs->rd_idx), -+ rd_len); -+ (p_bbs)->rd_idx = (p_bbs)->rd_idx + rd_len; -+ } else { -+ unsigned int tail_len = BBS_SIZE(p_bbs) - -+ (p_bbs)->rd_idx; -+ if (tail_len >= rd_len) { -+ memcpy(p_buf, BBS_PTR(p_bbs, p_bbs->rd_idx), -+ rd_len); -+ (p_bbs)->rd_idx = -+ ((p_bbs)->rd_idx + rd_len) & (BBS_MASK(p_bbs)); -+ } else { -+ memcpy(p_buf, BBS_PTR(p_bbs, p_bbs->rd_idx), tail_len); -+ memcpy(p_buf + tail_len, -+ (p_bbs)->p_buf, rd_len - tail_len); -+ (p_bbs)->rd_idx = rd_len - tail_len; -+ } -+ } -+ } -+ } -+ mb(); -+ return rd_len; -+} -+ -+unsigned int btif_bbs_wr_direct(p_btif_buf_str p_bbs, -+ unsigned char *p_buf, unsigned int buf_len) -+{ -+ unsigned int tail_len = 0; -+ unsigned int l = 0; -+ unsigned int tmp_wr_idx = p_bbs->wr_idx; -+ -+ tail_len = BBS_SIZE(p_bbs) - (tmp_wr_idx & BBS_MASK(p_bbs)); -+ -+ l = min(tail_len, buf_len); -+ -+ memcpy((p_bbs->p_buf) + (tmp_wr_idx & BBS_MASK(p_bbs)), p_buf, l); -+ memcpy(p_bbs->p_buf, p_buf + l, buf_len - l); -+ -+ mb(); -+ -+ tmp_wr_idx += buf_len; -+ tmp_wr_idx &= BBS_MASK(p_bbs); -+ p_bbs->wr_idx = tmp_wr_idx; -+ -+ mb(); -+ return buf_len; -+} -+ -+int _btif_dma_write(p_mtk_btif p_btif, -+ const unsigned char *p_buf, unsigned int buf_len) -+{ -+ unsigned int i_ret = 0; -+ unsigned int retry = 0; -+ unsigned int max_tx_retry = 10; -+ -+ P_MTK_DMA_INFO_STR p_dma_info = p_btif->p_tx_dma->p_dma_info; -+ -+ _btif_irq_ctrl_sync(p_dma_info->p_irq, false); -+ do { -+ /*wait until tx is allowed*/ -+ while (!hal_dma_is_tx_allow(p_dma_info) && -+ (retry < max_tx_retry)) { -+ retry++; -+ if (retry >= max_tx_retry) { -+ BTIF_ERR_FUNC("wait for tx allowed timeout\n"); -+ break; -+ } -+ } -+ if (retry >= max_tx_retry) -+ break; -+ -+ if (buf_len <= hal_dma_get_ava_room(p_dma_info)) -+ i_ret = hal_dma_send_data(p_dma_info, p_buf, buf_len); -+ else -+ i_ret = 0; -+ } while (0); -+ _btif_irq_ctrl_sync(p_dma_info->p_irq, true); -+ return i_ret; -+} -+ -+int _btif_pio_write(p_mtk_btif p_btif, -+ const unsigned char *p_buf, unsigned int buf_len) -+{ -+ unsigned int i_ret = 0; -+ unsigned int sent_len = 0; -+ unsigned int retry = 0; -+ unsigned int max_tx_retry = 10; -+ P_MTK_BTIF_INFO_STR p_btif_info = p_btif->p_btif_info; -+ -+ while ((sent_len < buf_len)) { -+ if (hal_btif_is_tx_allow(p_btif_info)) { -+ i_ret = hal_btif_send_data(p_btif_info, -+ p_buf + sent_len, -+ buf_len - sent_len); -+ if (i_ret > 0) { -+ sent_len += i_ret; -+ BTIF_DBG_FUNC("lent sent:%d, total sent:%d\n", -+ i_ret, sent_len); -+ retry = 0; -+ } -+ } -+ if ((++retry > max_tx_retry) || (i_ret < 0)) { -+ BTIF_INFO_FUNC("exceed retry times limit :%d\n", retry); -+ break; -+ } -+ } -+ i_ret = sent_len; -+ return i_ret; -+} -+ -+int _btif_dump_memory(char *str, unsigned char *p_buf, unsigned int buf_len) -+{ -+ unsigned int idx = 0; -+ -+ pr_debug("%s:, length:%d\n", str, buf_len); -+ for (idx = 0; idx < buf_len;) { -+ pr_debug("%02x ", p_buf[idx]); -+ idx++; -+ if (idx % 8 == 0) -+ pr_debug("\n"); -+ } -+ return 0; -+} -+ -+int btif_send_data(p_mtk_btif p_btif, -+ const unsigned char *p_buf, unsigned int buf_len) -+{ -+ int i_ret = 0; -+ -+ if (p_btif->tx_ctx == BTIF_TX_USER_CTX) { -+ i_ret = _btif_send_data(p_btif, p_buf, buf_len); -+ } else if (p_btif->tx_ctx == BTIF_TX_SINGLE_CTX) { -+ int length = 0; -+/*tx fifo in*/ -+ length = kfifo_in(p_btif->p_tx_fifo, -+ (unsigned char *)p_buf, buf_len); -+ if (length == buf_len) { -+ queue_work(p_btif->p_tx_wq, &(p_btif->tx_work)); -+ BTIF_DBG_FUNC("schedule btif_tx_worker\n"); -+ i_ret = length; -+ } else { -+ i_ret = 0; -+ BTIF_ERR_FUNC("fifo in failed, target len(%d),in len(%d),", -+ "don't schedule btif_tx_worker\n", buf_len, length); -+ } -+ } else { -+ BTIF_ERR_FUNC("invalid btif tx context:%d\n", p_btif->tx_ctx); -+ i_ret = 0; -+ } -+ -+ return i_ret; -+} -+ -+int _btif_send_data(p_mtk_btif p_btif, -+ const unsigned char *p_buf, unsigned int buf_len) -+{ -+ int i_ret = 0; -+ unsigned int state = 0; -+ -+/*make sure BTIF in ON state before doing tx operation*/ -+ if (_btif_state_hold(p_btif)) -+ return E_BTIF_INTR; -+ state = _btif_state_get(p_btif); -+ -+ if (state != B_S_ON) -+ i_ret = _btif_exit_dpidle(p_btif); -+ -+ if (i_ret != 0) { -+ i_ret = E_BTIF_INVAL_STATE; -+ } else if (p_btif->tx_mode == BTIF_MODE_DMA) { -+ /*_btif_dump_memory("tx data:", p_buf, buf_len);*/ -+ i_ret = _btif_dma_write(p_btif, p_buf, buf_len); -+ } else if (p_btif->tx_mode == BTIF_MODE_PIO) { -+ /*_btif_dump_memory("tx data:", p_buf, buf_len);*/ -+ i_ret = _btif_pio_write(p_btif, p_buf, buf_len); -+ } else { -+ BTIF_ERR_FUNC("invalid tx mode:%d\n", p_btif->tx_mode); -+ i_ret = 0; -+ } -+ -+/*save Tx packet here*/ -+ if (i_ret > 0) -+ btif_log_buf_dmp_in(&p_btif->tx_log, p_buf, i_ret); -+ -+ BTIF_STATE_RELEASE(p_btif); -+ return i_ret; -+} -+ -+int btif_dump_reg(p_mtk_btif p_btif) -+{ -+ int i_ret = 0; -+ unsigned int ori_state = 0; -+ -+/*make sure BTIF in ON state before doing tx operation*/ -+ if (_btif_state_hold(p_btif)) -+ return E_BTIF_INTR; -+ ori_state = _btif_state_get(p_btif); -+ -+ if (ori_state == B_S_OFF) { -+ i_ret = E_BTIF_INVAL_STATE; -+ BTIF_ERR_FUNC -+ ("BTIF in OFF state, ", -+ "should no need to dump register, ", -+ "please check wmt's operation is okay or not.\n"); -+ goto dmp_reg_err; -+ } -+ -+ if ((ori_state != B_S_ON) && (ori_state < B_S_MAX)) { -+ BTIF_ERR_FUNC("BTIF's original state is %s, not B_S_ON\n", g_state[ori_state]); -+ BTIF_ERR_FUNC("!!!!---<<>>---!!!"); -+ i_ret = _btif_exit_dpidle(p_btif); -+ } -+ -+ if (i_ret != 0) { -+ i_ret = E_BTIF_INVAL_STATE; -+ BTIF_ERR_FUNC("switch to B_S_ON failed\n"); -+ goto dmp_reg_err; -+ } -+ -+/*dump BTIF register*/ -+ hal_btif_dump_reg(p_btif->p_btif_info, REG_BTIF_ALL); -+ -+/*dump BTIF Tx DMA channel register if in DMA mode*/ -+ if (p_btif->tx_mode == BTIF_MODE_DMA) -+ hal_dma_dump_reg(p_btif->p_tx_dma->p_dma_info, REG_TX_DMA_ALL); -+ else -+ BTIF_INFO_FUNC("BTIF Tx in PIO mode,no need to dump Tx DMA's register\n"); -+ -+/*dump BTIF Rx DMA channel register if in DMA mode*/ -+ if (p_btif->rx_mode == BTIF_MODE_DMA) -+ hal_dma_dump_reg(p_btif->p_rx_dma->p_dma_info, REG_RX_DMA_ALL); -+ else -+ BTIF_INFO_FUNC("BTIF Rx in PIO mode,no need to dump Rx DMA's register\n"); -+ -+ switch (ori_state) { -+ case B_S_SUSPEND: -+/*return to dpidle state*/ -+/* break; */ -+ case B_S_DPIDLE: -+/*return to dpidle state*/ -+ _btif_enter_dpidle(p_btif); -+ break; -+ case B_S_ON: -+/*nothing needs to be done*/ -+ break; -+ default: -+ break; -+ } -+ -+dmp_reg_err: -+ -+ BTIF_STATE_RELEASE(p_btif); -+ return i_ret; -+} -+ -+int btif_rx_notify_reg(p_mtk_btif p_btif, MTK_BTIF_RX_NOTIFY rx_notify) -+{ -+ if (p_btif->rx_notify) { -+ BTIF_WARN_FUNC -+ ("rx cb already exist, rewrite from (0x%p) to (0x%p)\n", -+ p_btif->rx_notify, rx_notify); -+ } -+ p_btif->rx_notify = rx_notify; -+ -+ return 0; -+} -+ -+int btif_dump_data(char *p_buf, int len) -+{ -+ unsigned int idx = 0; -+ unsigned char str[30]; -+ unsigned char *p_str; -+ -+ p_str = &str[0]; -+ for (idx = 0; idx < len; idx++, p_buf++) { -+ sprintf(p_str, "%02x ", *p_buf); -+ p_str += 3; -+ if (7 == (idx % 8)) { -+ *p_str++ = '\n'; -+ *p_str = '\0'; -+ pr_debug("%s", str); -+ p_str = &str[0]; -+ } -+ } -+ if (len % 8) { -+ *p_str++ = '\n'; -+ *p_str = '\0'; -+ pr_debug("%s", str); -+ } -+ return 0; -+} -+ -+int btif_log_buf_dmp_in(P_BTIF_LOG_QUEUE_T p_log_que, const char *p_buf, -+ int len) -+{ -+ P_BTIF_LOG_BUF_T p_log_buf = NULL; -+ char *dir = NULL; -+ struct timeval *p_timer = NULL; -+ unsigned long flags; -+ bool output_flag = false; -+ -+ BTIF_DBG_FUNC("++\n"); -+ -+ if ((p_log_que == NULL) || (p_buf == NULL) || (len == 0)) { -+ BTIF_ERR_FUNC("invalid parameter, p_log_que(0x%x), buf(0x%x), ", -+ "len(%d)\n", p_log_que, p_buf, len); -+ return 0; -+ } -+ if (!(p_log_que->enable)) -+ return 0; -+ -+ dir = p_log_que->dir == BTIF_TX ? "Tx" : "Rx"; -+ output_flag = p_log_que->output_flag; -+ -+ spin_lock_irqsave(&(p_log_que->lock), flags); -+ -+/*get next log buffer for record usage*/ -+ p_log_buf = p_log_que->p_queue[0] + p_log_que->in; -+ p_timer = &p_log_buf->timer; -+ -+/*log time stamp*/ -+ do_gettimeofday(p_timer); -+ -+/*record data information including length and content*/ -+ p_log_buf->len = len; -+ memcpy(p_log_buf->buffer, p_buf, len > BTIF_LOG_SZ ? BTIF_LOG_SZ : len); -+ -+/*update log queue size information*/ -+ p_log_que->size++; -+ p_log_que->size = p_log_que->size > -+ BTIF_LOG_ENTRY_NUM ? BTIF_LOG_ENTRY_NUM : p_log_que->size; -+ -+/*update log queue index information*/ -+ p_log_que->in++; -+ p_log_que->in %= BTIF_LOG_ENTRY_NUM; -+ -+ spin_unlock_irqrestore(&p_log_que->lock, flags); -+ -+/*check if log dynamic output function is enabled or not*/ -+ if (output_flag) { -+ pr_debug("BTIF-DBG, dir:%s, %d.%ds len:%d\n", -+ dir, (int)p_timer->tv_sec, (int)p_timer->tv_usec, len); -+/*output buffer content*/ -+ btif_dump_data((char *)p_buf, len); -+ } -+ BTIF_DBG_FUNC("--\n"); -+ -+ return 0; -+} -+ -+int btif_log_buf_dmp_out(P_BTIF_LOG_QUEUE_T p_log_que) -+{ -+ P_BTIF_LOG_BUF_T p_log_buf = NULL; -+ unsigned int out_index = 0; -+ unsigned int in_index = 0; -+ unsigned int dump_size = 0; -+ unsigned char *p_buf = NULL; -+ unsigned int len = 0; -+ unsigned int pkt_count = 0; -+ unsigned char *p_dir = NULL; -+ struct timeval *p_timer = NULL; -+ unsigned long flags; -+ -+#if 0 /* no matter enable or not, we allowed output */ -+ if (!(p_log_que->enable)) -+ return; -+#endif -+ BTIF_DBG_FUNC("++\n"); -+ -+ spin_lock_irqsave(&p_log_que->lock, flags); -+ in_index = p_log_que->in; -+ dump_size = p_log_que->size; -+ out_index = p_log_que->size >= -+ BTIF_LOG_ENTRY_NUM ? in_index : (BTIF_LOG_ENTRY_NUM - -+ p_log_que->size + -+ in_index) % BTIF_LOG_ENTRY_NUM; -+ p_dir = p_log_que->dir == BTIF_TX ? "Tx" : "Rx"; -+ -+ BTIF_INFO_FUNC("btif %s log buffer size:%d\n", p_dir, dump_size); -+ -+ if (dump_size != 0) { -+ while (dump_size--) { -+ p_log_buf = p_log_que->p_queue[0] + out_index; -+ -+ len = p_log_buf->len; -+ p_buf = p_log_buf->buffer; -+ p_timer = &p_log_buf->timer; -+ -+ len = len > BTIF_LOG_SZ ? BTIF_LOG_SZ : len; -+ -+ BTIF_INFO_FUNC("dir:%s, pkt_count:%d, %d.%ds len:%d\n", -+ p_dir, -+ pkt_count++, -+ (int)p_timer->tv_sec, -+ (int)p_timer->tv_usec, len); -+/*output buffer content*/ -+ btif_dump_data(p_log_buf->buffer, len); -+ out_index++; -+ out_index %= BTIF_LOG_ENTRY_NUM; -+ } -+ } -+ spin_unlock_irqrestore(&p_log_que->lock, flags); -+ BTIF_DBG_FUNC("--\n"); -+ -+ return 0; -+} -+ -+int btif_log_buf_enable(P_BTIF_LOG_QUEUE_T p_log_que) -+{ -+ unsigned long flags; -+ -+ spin_lock_irqsave(&p_log_que->lock, flags); -+ p_log_que->enable = true; -+ spin_unlock_irqrestore(&p_log_que->lock, flags); -+ BTIF_INFO_FUNC("enable %s log function\n", -+ p_log_que->dir == BTIF_TX ? "Tx" : "Rx"); -+ return 0; -+} -+ -+int btif_log_buf_disable(P_BTIF_LOG_QUEUE_T p_log_que) -+{ -+ unsigned long flags; -+ -+ spin_lock_irqsave(&p_log_que->lock, flags); -+ p_log_que->enable = false; -+ spin_unlock_irqrestore(&p_log_que->lock, flags); -+ BTIF_INFO_FUNC("disable %s log function\n", -+ p_log_que->dir == BTIF_TX ? "Tx" : "Rx"); -+ return 0; -+} -+ -+int btif_log_output_enable(P_BTIF_LOG_QUEUE_T p_log_que) -+{ -+ unsigned long flags; -+ -+ spin_lock_irqsave(&p_log_que->lock, flags); -+ p_log_que->output_flag = true; -+ spin_unlock_irqrestore(&p_log_que->lock, flags); -+ BTIF_INFO_FUNC("%s log rt output enabled\n", -+ p_log_que->dir == BTIF_TX ? "Tx" : "Rx"); -+ return 0; -+} -+ -+int btif_log_output_disable(P_BTIF_LOG_QUEUE_T p_log_que) -+{ -+ unsigned long flags; -+ -+ spin_lock_irqsave(&p_log_que->lock, flags); -+ p_log_que->output_flag = false; -+ spin_unlock_irqrestore(&p_log_que->lock, flags); -+ BTIF_INFO_FUNC("%s log rt output disabled\n", -+ p_log_que->dir == BTIF_TX ? "Tx" : "Rx"); -+ return 0; -+} -+ -+int btif_log_buf_reset(P_BTIF_LOG_QUEUE_T p_log_que) -+{ -+ unsigned long flags; -+ -+ spin_lock_irqsave(&p_log_que->lock, flags); -+ -+/*tx log buffer init*/ -+ p_log_que->in = 0; -+ p_log_que->out = 0; -+ p_log_que->size = 0; -+ p_log_que->enable = true; -+ memset((p_log_que->p_queue[0]), 0, sizeof(BTIF_LOG_BUF_T)); -+ -+ spin_unlock_irqrestore(&p_log_que->lock, flags); -+ BTIF_DBG_FUNC("reset %s log buffer\n", -+ p_log_que->dir == BTIF_TX ? "Tx" : "Rx"); -+ return 0; -+} -+ -+int btif_log_buf_init(p_mtk_btif p_btif) -+{ -+/*tx log buffer init*/ -+ p_btif->tx_log.dir = BTIF_TX; -+ p_btif->tx_log.in = 0; -+ p_btif->tx_log.out = 0; -+ p_btif->tx_log.size = 0; -+ p_btif->tx_log.output_flag = false; -+ p_btif->tx_log.enable = true; -+ spin_lock_init(&(p_btif->tx_log.lock)); -+ BTIF_DBG_FUNC("tx_log.p_queue:0x%p\n", p_btif->tx_log.p_queue[0]); -+ memset((p_btif->tx_log.p_queue[0]), 0, sizeof(BTIF_LOG_BUF_T)); -+ -+/*rx log buffer init*/ -+ p_btif->rx_log.dir = BTIF_RX; -+ p_btif->rx_log.in = 0; -+ p_btif->rx_log.out = 0; -+ p_btif->rx_log.size = 0; -+ p_btif->rx_log.output_flag = false; -+ p_btif->rx_log.enable = true; -+ spin_lock_init(&(p_btif->rx_log.lock)); -+ BTIF_DBG_FUNC("rx_log.p_queue:0x%p\n", p_btif->rx_log.p_queue[0]); -+ memset((p_btif->rx_log.p_queue[0]), 0, sizeof(BTIF_LOG_BUF_T)); -+ -+ return 0; -+} -+ -+int btif_tx_dma_mode_set(int en) -+{ -+ int index = 0; -+ ENUM_BTIF_MODE mode = (en == 1) ? BTIF_MODE_DMA : BTIF_MODE_PIO; -+ -+ for (index = 0; index < BTIF_PORT_NR; index++) -+ g_btif[index].tx_mode = mode; -+ -+ return 0; -+} -+ -+int btif_rx_dma_mode_set(int en) -+{ -+ int index = 0; -+ ENUM_BTIF_MODE mode = (en == 1) ? BTIF_MODE_DMA : BTIF_MODE_PIO; -+ -+ for (index = 0; index < BTIF_PORT_NR; index++) -+ g_btif[index].rx_mode = mode; -+ -+ return 0; -+} -+ -+static int BTIF_init(void) -+{ -+ int i_ret = -1; -+ int index = 0; -+ p_mtk_btif_dma p_tx_dma = NULL; -+ p_mtk_btif_dma p_rx_dma = NULL; -+ unsigned char *p_btif_buffer = NULL; -+ unsigned char *p_tx_queue = NULL; -+ unsigned char *p_rx_queue = NULL; -+ -+ BTIF_DBG_FUNC("++\n"); -+ -+/*Platform Driver initialization*/ -+ i_ret = platform_driver_register(&mtk_btif_dev_drv); -+ if (i_ret) { -+ BTIF_ERR_FUNC("BTIF platform driver registered failed, ret(%d)\n", i_ret); -+ goto err_exit1; -+ } -+ -+ i_ret = driver_create_file(&mtk_btif_dev_drv.driver, &driver_attr_flag); -+ if (i_ret) -+ BTIF_ERR_FUNC("BTIF pdriver_create_file failed, ret(%d)\n", i_ret); -+ -+/*SW init*/ -+ for (index = 0; index < BTIF_PORT_NR; index++) { -+ p_btif_buffer = kmalloc(BTIF_RX_BUFFER_SIZE, GFP_ATOMIC); -+ if (!p_btif_buffer) { -+ BTIF_ERR_FUNC("p_btif_buffer kmalloc memory fail\n"); -+ return -1; -+ } -+ BTIF_INFO_FUNC("p_btif_buffer get memory 0x%p\n", p_btif_buffer); -+ p_tx_queue = kmalloc_array(BTIF_LOG_ENTRY_NUM, sizeof(BTIF_LOG_BUF_T), GFP_ATOMIC); -+ if (!p_tx_queue) { -+ BTIF_ERR_FUNC("p_tx_queue kmalloc memory fail\n"); -+ kfree(p_btif_buffer); -+ return -1; -+ } -+ BTIF_INFO_FUNC("p_tx_queue get memory 0x%p\n", p_tx_queue); -+ p_rx_queue = kmalloc_array(BTIF_LOG_ENTRY_NUM, sizeof(BTIF_LOG_BUF_T), GFP_ATOMIC); -+ if (!p_rx_queue) { -+ BTIF_ERR_FUNC("p_rx_queue kmalloc memory fail\n"); -+ kfree(p_btif_buffer); -+ kfree(p_tx_queue); -+ return -1; -+ } -+ BTIF_INFO_FUNC("p_rx_queue get memory 0x%p\n", p_rx_queue); -+ -+ INIT_LIST_HEAD(&(g_btif[index].user_list)); -+ BBS_INIT(&(g_btif[index].btif_buf)); -+ g_btif[index].enable = false; -+ g_btif[index].open_counter = 0; -+ g_btif[index].setting = &g_btif_setting[index]; -+ g_btif[index].p_btif_info = hal_btif_info_get(); -+ g_btif[index].tx_mode = g_btif_setting[index].tx_mode; -+ g_btif[index].rx_mode = g_btif_setting[index].rx_mode; -+ g_btif[index].btm_type = g_btif_setting[index].rx_type; -+ g_btif[index].tx_ctx = g_btif_setting[index].tx_type; -+ g_btif[index].lpbk_flag = false; -+ g_btif[index].rx_cb = NULL; -+ g_btif[index].rx_notify = NULL; -+ g_btif[index].btif_buf.p_buf = p_btif_buffer; -+ g_btif[index].tx_log.p_queue[0] = (P_BTIF_LOG_BUF_T) p_tx_queue; -+ g_btif[index].rx_log.p_queue[0] = (P_BTIF_LOG_BUF_T) p_rx_queue; -+ btif_log_buf_init(&g_btif[index]); -+ -+#if !(MTK_BTIF_ENABLE_CLK_REF_COUNTER) -+/*enable BTIF clock gating by default*/ -+ i_ret = hal_btif_clk_ctrl(g_btif[index].p_btif_info, -+ CLK_OUT_DISABLE); -+ if (i_ret != 0) { -+ BTIF_ERR_FUNC("BTIF controller CG failed\n"); -+ goto err_exit2; -+ } -+#endif -+ -+/* -+ * viftual FIFO memory must be physical continious, -+ * because DMA will access it directly without MMU -+ */ -+#if ENABLE_BTIF_TX_DMA -+ p_tx_dma = &g_dma[index][BTIF_TX]; -+ g_btif[index].p_tx_dma = p_tx_dma; -+ p_tx_dma->dir = BTIF_TX; -+ p_tx_dma->p_btif = &(g_btif[index]); -+ -+/*DMA Tx vFIFO initialization*/ -+ p_tx_dma->p_dma_info = hal_btif_dma_info_get(DMA_DIR_TX); -+/*spinlock init*/ -+ spin_lock_init(&(p_tx_dma->iolock)); -+/*entry setup*/ -+ atomic_set(&(p_tx_dma->entry), 0); -+/*vFIFO initialization*/ -+ i_ret = _btif_vfifo_init(p_tx_dma); -+ if (i_ret != 0) { -+ BTIF_ERR_FUNC("BTIF Tx vFIFO allocation failed\n"); -+ goto err_exit2; -+ } -+ -+#if !(MTK_BTIF_ENABLE_CLK_REF_COUNTER) -+/*enable BTIF Tx DMA channel's clock gating by default*/ -+ i_ret = hal_btif_dma_clk_ctrl(p_tx_dma->p_dma_info, -+ CLK_OUT_DISABLE); -+ if (i_ret != 0) { -+ BTIF_ERR_FUNC("BTIF Tx DMA's CG failed\n"); -+ goto err_exit2; -+ } -+#endif -+ -+#else -+ g_btif[index].p_tx_dma = NULL; -+/*force tx mode to DMA no matter what it is in default setting*/ -+ g_btif[index].tx_mode = BTIF_MODE_PIO; -+#endif -+ -+#if ENABLE_BTIF_RX_DMA -+ p_rx_dma = &g_dma[index][BTIF_RX]; -+ g_btif[index].p_rx_dma = p_rx_dma; -+ p_rx_dma->p_btif = &(g_btif[index]); -+ p_rx_dma->dir = BTIF_RX; -+ -+/*DMA Tx vFIFO initialization*/ -+ p_rx_dma->p_dma_info = hal_btif_dma_info_get(DMA_DIR_RX); -+/*spinlock init*/ -+ spin_lock_init(&(p_rx_dma->iolock)); -+/*entry setup*/ -+ atomic_set(&(p_rx_dma->entry), 0); -+/*vFIFO initialization*/ -+ i_ret = _btif_vfifo_init(p_rx_dma); -+ if (i_ret != 0) { -+ BTIF_ERR_FUNC("BTIF Rx vFIFO allocation failed\n"); -+ goto err_exit2; -+ } -+ -+#if !(MTK_BTIF_ENABLE_CLK_REF_COUNTER) -+/*enable BTIF Tx DMA channel's clock gating by default*/ -+ i_ret = hal_btif_dma_clk_ctrl(p_rx_dma->p_dma_info, -+ CLK_OUT_DISABLE); -+ if (i_ret != 0) { -+ BTIF_ERR_FUNC("BTIF Rx DMA's CG failed\n"); -+ goto err_exit2; -+ } -+#endif -+ -+#else -+ g_btif[index].p_rx_dma = NULL; -+/*force rx mode to DMA no matter what it is in default setting*/ -+ g_btif[index].rx_mode = BTIF_MODE_PIO; -+ -+#endif -+/*PM state mechine initialization*/ -+ i_ret = _btif_state_init(&(g_btif[index])); -+ if (i_ret != 0) { -+ BTIF_ERR_FUNC("BTIF state mechanism init failed\n"); -+ goto err_exit2; -+ } -+ -+/*Rx bottom half initialization*/ -+ i_ret = _btif_rx_btm_init(&(g_btif[index])); -+ if (i_ret != 0) { -+ BTIF_ERR_FUNC("BTIF Rx btm init failed\n"); -+ goto err_exit3; -+ } -+ i_ret = _btif_tx_ctx_init(&(g_btif[index])); -+ if (i_ret != 0) { -+ BTIF_ERR_FUNC("BTIF Tx context init failed\n"); -+ goto err_exit4; -+ } -+/*Character Device initialization*/ -+/*Chaozhong: ToDo: to be initialized*/ -+ -+ mutex_init(&g_btif[index].ops_mtx); -+ } -+ -+/*Debug purpose initialization*/ -+ -+#if BTIF_CDEV_SUPPORT -+ btif_chrdev_init(); -+#endif -+ -+ return 0; -+ -+err_exit4: -+ for (index = 0; index < BTIF_PORT_NR; index++) -+ _btif_tx_ctx_deinit(&(g_btif[index])); -+ -+err_exit3: -+ for (index = 0; index < BTIF_PORT_NR; index++) { -+ _btif_rx_btm_deinit(&(g_btif[index])); -+ -+ _btif_state_deinit(&(g_btif[index])); -+ } -+ -+err_exit2: -+ for (index = 0; index < BTIF_PORT_NR; index++) { -+ p_tx_dma = &g_dma[index][BTIF_TX]; -+ p_rx_dma = &g_dma[index][BTIF_RX]; -+#if ENABLE_BTIF_TX_DMA -+ _btif_vfifo_deinit(p_tx_dma); -+#endif -+ -+#if ENABLE_BTIF_RX_DMA -+ _btif_vfifo_deinit(p_rx_dma); -+#endif -+ g_btif[index].open_counter = 0; -+ g_btif[index].enable = false; -+ } -+ driver_remove_file(&mtk_btif_dev_drv.driver, &driver_attr_flag); -+ platform_driver_unregister(&mtk_btif_dev_drv); -+ -+err_exit1: -+ i_ret = -1; -+ BTIF_DBG_FUNC("--\n"); -+ return i_ret; -+} -+ -+static void BTIF_exit(void) -+{ -+ unsigned int index = 0; -+ p_mtk_btif_dma p_tx_dma = NULL; -+ p_mtk_btif_dma p_rx_dma = NULL; -+ -+ BTIF_DBG_FUNC("++\n"); -+ -+ for (index = 0; index < BTIF_PORT_NR; index++) { -+ g_btif[index].open_counter = 0; -+ g_btif[index].enable = false; -+ p_tx_dma = &g_dma[index][BTIF_TX]; -+ p_rx_dma = &g_dma[index][BTIF_RX]; -+#if ENABLE_BTIF_TX_DMA -+ _btif_vfifo_deinit(p_tx_dma); -+#endif -+ -+#if ENABLE_BTIF_RX_DMA -+ _btif_vfifo_deinit(p_rx_dma); -+#endif -+ _btif_state_deinit(&(g_btif[index])); -+ -+ _btif_rx_btm_deinit(&(g_btif[index])); -+ -+ mutex_destroy(&g_btif[index].ops_mtx); -+ } -+ -+#if !defined(CONFIG_MTK_CLKMGR) -+ hal_btif_clk_unprepare(); -+#endif -+ -+ driver_remove_file(&mtk_btif_dev_drv.driver, &driver_attr_flag); -+ platform_driver_unregister(&mtk_btif_dev_drv); -+ BTIF_DBG_FUNC("--\n"); -+} -+ -+int mtk_btif_hal_get_log_lvl(void) -+{ -+ return mtk_btif_dbg_lvl; -+} -+ -+void mtk_btif_read_cpu_sw_rst_debug(void) -+{ -+ mtk_btif_read_cpu_sw_rst_debug_plat(); -+} -+ -+/*---------------------------------------------------------------------------*/ -+ -+module_init(BTIF_init); -+module_exit(BTIF_exit); -+ -+/*---------------------------------------------------------------------------*/ -+ -+MODULE_AUTHOR("MBJ/WCN/SE/SS1/Chaozhong.Liang"); -+MODULE_DESCRIPTION("MTK BTIF Driver$1.0$"); -+MODULE_LICENSE("GPL"); -+ -+/*---------------------------------------------------------------------------*/ -diff --git a/drivers/misc/mediatek/btif/common/mtk_btif_exp.c b/drivers/misc/mediatek/btif/common/mtk_btif_exp.c -new file mode 100644 -index 000000000000..c0df44558357 ---- /dev/null -+++ b/drivers/misc/mediatek/btif/common/mtk_btif_exp.c -@@ -0,0 +1,786 @@ -+/* -+ * Copyright (C) 2015 MediaTek Inc. -+ * -+ * 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. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#ifdef DFT_TAG -+#undef DFT_TAG -+#endif -+#define DFT_TAG "MTK-BTIF-EXP" -+ -+/*#include "mtk_btif_exp.h"*/ -+#include "mtk_btif.h" -+ -+/*---------------------------------Function----------------------------------*/ -+ -+p_mtk_btif btif_exp_srh_id(unsigned long u_id) -+{ -+ int index = 0; -+ p_mtk_btif p_btif = NULL; -+ struct list_head *p_list = NULL; -+ struct list_head *tmp = NULL; -+ p_mtk_btif_user p_user = NULL; -+ -+ for (index = 0; (index < BTIF_PORT_NR) && (p_btif == NULL); index++) { -+ p_list = &(g_btif[index].user_list); -+ list_for_each(tmp, p_list) { -+ p_user = container_of(tmp, mtk_btif_user, entry); -+ if (u_id == p_user->u_id) { -+ p_btif = p_user->p_btif; -+ BTIF_DBG_FUNC -+ ("BTIF's user id(0x%p), p_btif(0x%p)\n", -+ p_user->u_id, p_btif); -+ break; -+ } -+ } -+ } -+ if (p_btif == NULL) { -+ BTIF_INFO_FUNC -+ ("no btif structure found for BTIF's user id(0x%lx)\n", -+ u_id); -+ } -+ return p_btif; -+} -+ -+/*-----Normal Mode API declearation-------*/ -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_btif_open -+* DESCRIPTION -+* open BTIF interface, will do BTIF module HW and SW initialization -+* PARAMETERS -+* p_owner [IN] pointer to owner who call this API, -+* currently there are 2 owner ("stp" or "btif_tester") -+* may use this module -+* for "stp", BTIF will call rx callback function to route rx data to STP module -+* for "stp_tester", BTIF will save rx data and wait for native process to access -+* p_id [IN] BTIF's user id will be put to this address -+* RETURNS -+* int 0 = BTIF module initialization fail; negative = BTIF module initialization success -+* if open success, value p_id will be the only identifier -+* for user to access BTIF's other operations -+* including read/write/dpidle_ctrl/rx_cb_retister -+* this user id is only an identifier used for owner identification -+*****************************************************************************/ -+int mtk_wcn_btif_open(char *p_owner, unsigned long *p_id) -+{ -+ int i_ret = -1; -+ unsigned int index = 0; -+ p_mtk_btif_user p_new_user = NULL; -+ p_mtk_btif p_btif = &g_btif[index]; -+ struct list_head *p_user_list = &(p_btif->user_list); -+ -+ BTIF_DBG_FUNC("++"); -+ BTIF_DBG_FUNC("p_btif(0x%p)\n", p_btif); -+ -+ if (mutex_lock_killable(&(p_btif->ops_mtx))) { -+ BTIF_ERR_FUNC("mutex_lock_killable return failed\n"); -+ return E_BTIF_INTR; -+ } -+ if ((p_owner == NULL) || (p_id == NULL)) { -+ if (p_id) -+ *p_id = 0; -+ BTIF_ERR_FUNC("parameter invalid, p_owner(0x%p), p_id(0x%p)\n", -+ p_owner, p_id); -+ BTIF_MUTEX_UNLOCK(&(p_btif->ops_mtx)); -+ return E_BTIF_INVAL_PARAM; -+ } -+ -+/*check if btif is already opened or not, if yes, just return fail*/ -+ if (!list_empty(p_user_list)) { -+ struct list_head *pos; -+ p_mtk_btif_user p_user; -+ -+ BTIF_ERR_FUNC("BTIF's user list is not empty\n"); -+ list_for_each(pos, p_user_list) { -+ p_user = container_of(pos, mtk_btif_user, entry); -+ BTIF_INFO_FUNC("BTIF's user id(0x%lx), name(%s)\n", -+ p_user->u_id, p_user->u_name); -+ } -+/*leave p_id alone*/ -+ BTIF_MUTEX_UNLOCK(&(p_btif->ops_mtx)); -+ return E_BTIF_ALREADY_OPEN; -+ } -+ p_new_user = vmalloc(sizeof(mtk_btif_user)); -+ -+ if (p_new_user != NULL) { -+ INIT_LIST_HEAD(&(p_new_user->entry)); -+ p_new_user->enable = false; -+ p_new_user->p_btif = p_btif; -+ p_new_user->u_id = (unsigned long)p_new_user; -+ strncpy(p_new_user->u_name, p_owner, sizeof(p_new_user->u_name) - 1); -+ p_new_user->u_name[sizeof(p_new_user->u_name) - 1] = '\0'; -+ BTIF_DBG_FUNC("owner name:%s, recorded name:%s\n", -+ p_owner, p_new_user->u_name); -+ -+ i_ret = btif_open(p_btif); -+ if (i_ret) { -+ BTIF_ERR_FUNC("btif_open failed, i_ret(%d)\n", i_ret); -+ *p_id = 0; -+/*free btif new user's structure*/ -+ vfree(p_new_user); -+ p_new_user = NULL; -+ } else { -+ BTIF_INFO_FUNC("btif_open succeed\n"); -+ *p_id = p_new_user->u_id; -+/*mark enable flag to true*/ -+ p_new_user->enable = true; -+/*add to uer lsit*/ -+ list_add_tail(&(p_new_user->entry), p_user_list); -+ } -+ } else { -+ *p_id = 0; -+ i_ret = -ENOMEM; -+ BTIF_ERR_FUNC("allocate memory for mtk_btif_user failed\n"); -+ } -+ BTIF_MUTEX_UNLOCK(&(p_btif->ops_mtx)); -+ BTIF_DBG_FUNC("--"); -+ return i_ret; -+} -+EXPORT_SYMBOL(mtk_wcn_btif_open); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_btif_close -+* DESCRIPTION -+* close BTIF interface, will do BTIF module HW and SW de-initialization -+* once this API is called, p_btif should never be used by BTIF's user again -+* PARAMETERS -+* u_id [IN] BTIF's user id -+* RETURNS -+* int 0 = succeed; -+* others = fail, -+* for detailed information, please see ENUM_BTIF_OP_ERROR_CODE -+*****************************************************************************/ -+int mtk_wcn_btif_close(unsigned long u_id) -+{ -+ int i_ret = -1; -+ p_mtk_btif p_btif = NULL; -+ struct list_head *pos = NULL; -+ struct list_head *p_user_list = NULL; -+ -+ BTIF_DBG_FUNC("++"); -+ p_btif = btif_exp_srh_id(u_id); -+ -+ if (p_btif == NULL) -+ return E_BTIF_INVAL_PARAM; -+ -+ if (mutex_lock_killable(&(p_btif->ops_mtx))) { -+ BTIF_ERR_FUNC("mutex_lock_killable return failed\n"); -+ return E_BTIF_INTR; -+ } -+ p_user_list = &(p_btif->user_list); -+ list_for_each(pos, p_user_list) { -+ p_mtk_btif_user p_user = -+ container_of(pos, mtk_btif_user, entry); -+ -+ if (p_user->u_id == u_id) { -+ BTIF_INFO_FUNC -+ ("user who's id is 0x%lx deleted from user list\n", -+ u_id); -+ list_del(pos); -+ vfree(p_user); -+ i_ret = btif_close(p_btif); -+ if (i_ret) -+ BTIF_WARN_FUNC("BTIF close failed"); -+ break; -+ } -+ } -+ BTIF_MUTEX_UNLOCK(&(p_btif->ops_mtx)); -+ BTIF_DBG_FUNC("--"); -+ return 0; -+} -+EXPORT_SYMBOL(mtk_wcn_btif_close); -+ -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_btif_write -+* DESCRIPTION -+* send data throuth BTIF module -+* there's no internal buffer to cache STP data in BTIF driver, -+* if in DMA mode -+* btif driver will check if there's enough space in vFIFO for data to send in DMA mode -+* if yes, put data to vFIFO and return corresponding data length to caller -+* if no, corresponding error code will be returned to called -+* PARAMETERS -+* p_btif [IN] pointer returned by mtk_wcn_btif_open -+* p_buf [IN] pointer to target data to send -+* len [IN] data length (should be less than 2014 bytes per STP package) -+* -+* if in non-DMA mode, BTIF driver will try to write to THR of BTIF controller -+* if btif driver detected that no space is available in Tx FIFO, -+* will return E_BTIF_NO_SPACE, mostly something is wrong with BTIF or -+* consys when this return value is returned -+* RETURNS -+* int positive: data length send through BTIF; -+* negative: please see ENUM_BTIF_OP_ERROR_CODE -+* E_BTIF_AGAIN (0) will be returned to caller -+* if btif does not have enough vFIFO to send data, -+* when caller get 0, he should wait for a moment -+* (5~10ms maybe) and try a few times (maybe 10~20) -+* if still get E_BTIF_AGAIN, -+* should call BTIF's debug API and dump BTIF driver -+* and BTIF/DMA register information to kernel log for debug -+* E_BTIF_BAD_POINTER will be returned to caller -+* if btif is not opened successfully before call this API -+* E_BTIF_INVAL_PARAM will be returned if parameter is not valid -+ -+*****************************************************************************/ -+int mtk_wcn_btif_write(unsigned long u_id, -+ const unsigned char *p_buf, unsigned int len) -+{ -+ int i_ret = -1; -+ p_mtk_btif p_btif = NULL; -+ -+ BTIF_DBG_FUNC("++"); -+ p_btif = btif_exp_srh_id(u_id); -+ -+ if (p_btif == NULL) -+ return E_BTIF_INVAL_PARAM; -+ if (p_buf == NULL) { -+ BTIF_ERR_FUNC("invalid p_buf (0x%p)\n", p_buf); -+ return E_BTIF_INVAL_PARAM; -+ } -+ if ((len == 0) || (len > BTIF_MAX_LEN_PER_PKT)) { -+ BTIF_ERR_FUNC("invalid buffer length(%d)\n", len); -+ return E_BTIF_INVAL_PARAM; -+ } -+ -+ i_ret = btif_send_data(p_btif, p_buf, len); -+ BTIF_DBG_FUNC("--, i_ret:%d\n", i_ret); -+ return i_ret; -+} -+EXPORT_SYMBOL(mtk_wcn_btif_write); -+ -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_btif_read -+* DESCRIPTION -+* read data from BTIF module -+* PARAMETERS -+* p_btif [IN] pointer returned by mtk_wcn_btif_open -+* p_buf [IN/OUT] pointer to buffer where rx data will be put -+* max_len [IN] max buffer length -+* RETURNS -+* int positive: data length read from BTIF; -+* negative: please see ENUM_BTIF_OP_ERROR_CODE -+*****************************************************************************/ -+int mtk_wcn_btif_read(unsigned long u_id, -+ unsigned char *p_buf, unsigned int max_len) -+{ -+ return 0; -+} -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_btif_dpidle_ctrl -+* DESCRIPTION -+* control if BTIF module allow system enter deepidle state or not -+* PARAMETERS -+* p_btif [IN] pointer returned by mtk_wcn_btif_open -+* en_flag [IN] one of ENUM_BTIF_DPIDLE_CTRL -+* RETURNS -+* int always return 0 -+*****************************************************************************/ -+int mtk_wcn_btif_dpidle_ctrl(unsigned long u_id, ENUM_BTIF_DPIDLE_CTRL en_flag) -+{ -+ int i_ret = -1; -+ p_mtk_btif p_btif = NULL; -+ -+ p_btif = btif_exp_srh_id(u_id); -+ -+ if (p_btif == NULL) -+ return E_BTIF_INVAL_PARAM; -+ -+ if (en_flag == BTIF_DPIDLE_DISABLE) -+ i_ret = btif_exit_dpidle(p_btif); -+ else -+ i_ret = btif_enter_dpidle(p_btif); -+ -+ return i_ret; -+} -+EXPORT_SYMBOL(mtk_wcn_btif_dpidle_ctrl); -+ -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_btif_rx_cb_register -+* DESCRIPTION -+* register rx callback function to BTIF module by btif user -+* PARAMETERS -+* p_btif [IN] pointer returned by mtk_wcn_btif_open -+* rx_cb [IN] pointer to stp rx handler callback function, -+* should be comply with MTK_WCN_BTIF_RX_CB -+* RETURNS -+* int 0 = succeed; -+* others = fail, for detailed information, -+* please see ENUM_BTIF_OP_ERROR_CODE -+*****************************************************************************/ -+int mtk_wcn_btif_rx_cb_register(unsigned long u_id, MTK_WCN_BTIF_RX_CB rx_cb) -+{ -+ int i_ret = -1; -+ p_mtk_btif p_btif = NULL; -+ -+ p_btif = btif_exp_srh_id(u_id); -+ -+ if (p_btif == NULL) -+ return E_BTIF_INVAL_PARAM; -+ -+ i_ret = btif_rx_cb_reg(p_btif, rx_cb); -+ -+ return i_ret; -+} -+EXPORT_SYMBOL(mtk_wcn_btif_rx_cb_register); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_btif_wakeup_consys -+* DESCRIPTION -+* once sleep command is sent to con sys, -+* should call this API before send wakeup command -+* to make con sys aware host want to send data to consys -+* PARAMETERS -+* p_btif [IN] pointer returned by mtk_wcn_btif_open -+* RETURNS -+* int 0 = succeed; others = fail, for detailed information, please see ENUM_BTIF_OP_ERROR_CODE -+*****************************************************************************/ -+int mtk_wcn_btif_wakeup_consys(unsigned long u_id) -+{ -+ int i_ret = -1; -+ p_mtk_btif p_btif = NULL; -+ -+ p_btif = btif_exp_srh_id(u_id); -+ -+ if (p_btif == NULL) -+ return E_BTIF_INVAL_PARAM; -+ -+/*i_ret = hal_btif_raise_wak_sig(p_btif->p_btif_info);*/ -+ i_ret = btif_raise_wak_signal(p_btif); -+ -+ return i_ret; -+} -+EXPORT_SYMBOL(mtk_wcn_btif_wakeup_consys); -+ -+ -+/***************End of Normal Mode API declearation**********/ -+ -+/***************Debug Purpose API declearation**********/ -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_btif_loopback_ctrl -+* DESCRIPTION -+* enable/disable BTIF internal loopback function, -+* when this function is enabled data send to btif -+* will be received by btif itself -+* only for debug purpose, should never use this function in normal mode -+* PARAMETERS -+* p_btif [IN] pointer returned by mtk_wcn_btif_open -+* enable [IN] loopback mode control flag, enable or disable, -+* shou be one of ENUM_BTIF_LPBK_MODE -+* RETURNS -+* int 0 = succeed; -+* others = fail, for detailed information, please see ENUM_BTIF_OP_ERROR_CODE -+*****************************************************************************/ -+int mtk_wcn_btif_loopback_ctrl(unsigned long u_id, ENUM_BTIF_LPBK_MODE enable) -+{ -+ int i_ret = -1; -+ p_mtk_btif p_btif = NULL; -+ -+ p_btif = btif_exp_srh_id(u_id); -+ -+ if (p_btif == NULL) -+ return E_BTIF_INVAL_PARAM; -+ i_ret = -+ btif_lpbk_ctrl(p_btif, enable == BTIF_LPBK_ENABLE ? true : false); -+ -+ return i_ret; -+} -+EXPORT_SYMBOL(mtk_wcn_btif_loopback_ctrl); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_btif_logger_ctrl -+* DESCRIPTION -+* control BTIF logger function's behavior -+* PARAMETERS -+* p_btif [IN] pointer returned by mtk_wcn_btif_open -+* flag [IN] should be one of ENUM_BTIF_DBG_ID -+* BTIF_DISABLE_LOGGER - disable btif logger -+* BTIF_ENABLE_LOGGER - enable btif logger -+* BTIF_DUMP_LOG - dump log logged by btif -+* BTIF_CLR_LOG - clear btif log buffer -+* BTIF_DUMP_BTIF_REG - dump btif controller's register -+* BTIF_DUMP_DMA_REG - dump DMA controller's register -+* RETURNS -+* int 0 = succeed; others = fail, for detailed information, please see ENUM_BTIF_OP_ERROR_CODE -+*****************************************************************************/ -+int mtk_wcn_btif_dbg_ctrl(unsigned long u_id, ENUM_BTIF_DBG_ID flag) -+{ -+ int i_ret = -1; -+ p_mtk_btif p_btif = NULL; -+ -+ p_btif = btif_exp_srh_id(u_id); -+ -+ if (p_btif == NULL) -+ return E_BTIF_INVAL_PARAM; -+ -+ i_ret = 0; -+ switch (flag) { -+ case BTIF_DISABLE_LOGGER:{ -+ BTIF_INFO_FUNC -+ ("disable btif log function for both Tx and Rx\n"); -+ btif_log_buf_disable(&p_btif->tx_log); -+ btif_log_buf_disable(&p_btif->rx_log); -+ } -+ break; -+ case BTIF_ENABLE_LOGGER:{ -+ BTIF_INFO_FUNC -+ ("enable btif log function for both Tx and Rx\n"); -+ btif_log_buf_enable(&p_btif->tx_log); -+ btif_log_buf_enable(&p_btif->rx_log); -+ } -+ break; -+ case BTIF_DUMP_LOG:{ -+ BTIF_INFO_FUNC("dump btif log for both Tx and Rx\n"); -+ btif_log_buf_dmp_out(&p_btif->tx_log); -+ btif_log_buf_dmp_out(&p_btif->rx_log); -+ } -+ break; -+ -+ case BTIF_CLR_LOG:{ -+ BTIF_INFO_FUNC("clear btif log for both Tx and Rx\n"); -+ btif_log_buf_reset(&p_btif->tx_log); -+ btif_log_buf_reset(&p_btif->rx_log); -+ } -+ break; -+ case BTIF_DUMP_BTIF_REG: -+ /*TBD*/ btif_dump_reg(p_btif); -+ break; -+ case BTIF_ENABLE_RT_LOG: -+ BTIF_INFO_FUNC -+ ("enable btif real time log for both Tx and Rx\n"); -+ btif_log_output_enable(&p_btif->tx_log); -+ btif_log_output_enable(&p_btif->rx_log); -+ break; -+ case BTIF_DISABLE_RT_LOG: -+ BTIF_INFO_FUNC -+ ("disable btif real time log for both Tx and Rx\n"); -+ btif_log_output_disable(&p_btif->tx_log); -+ btif_log_output_disable(&p_btif->rx_log); -+ break; -+ default: -+ BTIF_INFO_FUNC("not supported flag:%d\n", flag); -+ i_ret = -2; -+ break; -+ } -+ -+ return i_ret; -+} -+EXPORT_SYMBOL(mtk_wcn_btif_dbg_ctrl); -+ -+bool mtk_wcn_btif_parser_wmt_evt(unsigned long u_id, -+ const char *sub_str, unsigned int str_len) -+{ -+ bool b_ret = false; -+ p_mtk_btif p_btif = NULL; -+ -+ p_btif = btif_exp_srh_id(u_id); -+ -+ if (p_btif == NULL) -+ return E_BTIF_INVAL_PARAM; -+ b_ret = btif_parser_wmt_evt(p_btif, sub_str, str_len); -+ BTIF_INFO_FUNC("parser wmt evt %s\n", b_ret ? "ok" : "fail"); -+ -+ return b_ret; -+} -+ -+/**********End of Debug Purpose API declearation**********/ -+ -+int btif_open_no_id(void) -+{ -+ int i_ret = 0; -+ p_mtk_btif p_btif = &g_btif[0]; -+ -+ i_ret = btif_open(p_btif); -+ -+ if (i_ret) -+ BTIF_ERR_FUNC("btif_open failed, i_ret(%d)\n", i_ret); -+ else -+ BTIF_INFO_FUNC("btif_open succeed\n"); -+ -+ return i_ret; -+} -+ -+int btif_close_no_id(void) -+{ -+ int i_ret = 0; -+ p_mtk_btif p_btif = &g_btif[0]; -+ -+ i_ret = btif_close(p_btif); -+ -+ if (i_ret) -+ BTIF_ERR_FUNC("btif_close failed, i_ret(%d)\n", i_ret); -+ else -+ BTIF_INFO_FUNC("btif_close succeed\n"); -+ return i_ret; -+} -+ -+int btif_write_no_id(const unsigned char *p_buf, unsigned int len) -+{ -+ int i_ret = -1; -+ p_mtk_btif p_btif = &g_btif[0]; -+ -+ BTIF_DBG_FUNC("++"); -+ -+ if (p_buf == NULL) { -+ BTIF_ERR_FUNC("invalid p_buf (0x%p)\n", p_buf); -+ return E_BTIF_INVAL_PARAM; -+ } -+ if ((len == 0) || (len > BTIF_MAX_LEN_PER_PKT)) { -+ BTIF_ERR_FUNC("invalid buffer length(%d)\n", len); -+ return E_BTIF_INVAL_PARAM; -+ } -+ -+ i_ret = btif_send_data(p_btif, p_buf, len); -+ BTIF_DBG_FUNC("--, i_ret:%d\n", i_ret); -+ return i_ret; -+} -+ -+int btif_dpidle_ctrl_no_id(ENUM_BTIF_DPIDLE_CTRL en_flag) -+{ -+ int i_ret = -1; -+ p_mtk_btif p_btif = &g_btif[0]; -+ -+ if (en_flag == BTIF_DPIDLE_DISABLE) -+ i_ret = btif_exit_dpidle(p_btif); -+ else -+ i_ret = btif_enter_dpidle(p_btif); -+ -+ return i_ret; -+} -+ -+int btif_wakeup_consys_no_id(void) -+{ -+ int i_ret = -1; -+ p_mtk_btif p_btif = &g_btif[0]; -+ -+/*i_ret = hal_btif_raise_wak_sig(p_btif->p_btif_info);*/ -+ i_ret = btif_raise_wak_signal(p_btif); -+ -+ return i_ret; -+} -+ -+int btif_loopback_ctrl_no_id(ENUM_BTIF_LPBK_MODE enable) -+{ -+ int i_ret = -1; -+ p_mtk_btif p_btif = &g_btif[0]; -+ -+ i_ret = -+ btif_lpbk_ctrl(p_btif, enable == BTIF_LPBK_ENABLE ? true : false); -+ -+ return i_ret; -+} -+ -+int btif_dbg_ctrl_no_id(ENUM_BTIF_DBG_ID flag) -+{ -+ int i_ret = -1; -+ p_mtk_btif p_btif = &g_btif[0]; -+ -+ i_ret = 0; -+ switch (flag) { -+ case BTIF_DISABLE_LOGGER:{ -+ BTIF_INFO_FUNC -+ ("disable btif log function for both Tx and Rx\n"); -+ btif_log_buf_disable(&p_btif->tx_log); -+ btif_log_buf_disable(&p_btif->rx_log); -+ } -+ break; -+ case BTIF_ENABLE_LOGGER:{ -+ BTIF_INFO_FUNC -+ ("enable btif log function for both Tx and Rx\n"); -+ btif_log_buf_enable(&p_btif->tx_log); -+ btif_log_buf_enable(&p_btif->rx_log); -+ } -+ break; -+ case BTIF_DUMP_LOG:{ -+ BTIF_INFO_FUNC("dump btif log for both Tx and Rx\n"); -+ btif_log_buf_dmp_out(&p_btif->tx_log); -+ btif_log_buf_dmp_out(&p_btif->rx_log); -+ } -+ break; -+ -+ case BTIF_CLR_LOG:{ -+ BTIF_INFO_FUNC("clear btif log for both Tx and Rx\n"); -+ btif_log_buf_reset(&p_btif->tx_log); -+ btif_log_buf_reset(&p_btif->rx_log); -+ } -+ break; -+ case BTIF_DUMP_BTIF_REG: -+ /*TBD*/ btif_dump_reg(p_btif); -+ break; -+ case BTIF_ENABLE_RT_LOG: -+ BTIF_INFO_FUNC -+ ("enable btif real time log for both Tx and Rx\n"); -+ btif_log_output_enable(&p_btif->tx_log); -+ btif_log_output_enable(&p_btif->rx_log); -+ break; -+ case BTIF_DISABLE_RT_LOG: -+ BTIF_INFO_FUNC -+ ("disable btif real time log for both Tx and Rx\n"); -+ btif_log_output_disable(&p_btif->tx_log); -+ btif_log_output_disable(&p_btif->rx_log); -+ break; -+ default: -+ BTIF_INFO_FUNC("not supported flag:%d\n", flag); -+ i_ret = -2; -+ break; -+ } -+ -+ return i_ret; -+} -+ -+int mtk_btif_exp_open_test(void) -+{ -+ int i_ret = 0; -+ -+ i_ret = btif_open_no_id(); -+ if (i_ret < 0) { -+ BTIF_INFO_FUNC("mtk_wcn_btif_open failed\n"); -+ return -1; -+ } -+ -+ BTIF_INFO_FUNC("mtk_wcn_btif_open succeed\n"); -+ -+ return i_ret; -+} -+ -+int mtk_btif_exp_close_test(void) -+{ -+ int i_ret = 0; -+ -+ i_ret = btif_close_no_id(); -+ if (i_ret < 0) { -+ BTIF_INFO_FUNC("mtk_wcn_btif_close failed\n"); -+ return -1; -+ } -+ -+ BTIF_INFO_FUNC("mtk_wcn_btif_close succeed\n"); -+ -+ return i_ret; -+} -+ -+int mtk_btif_exp_write_test(void) -+{ -+ return mtk_btif_exp_write_stress_test(100, 10); -+} -+ -+int mtk_btif_exp_write_stress_test(unsigned int length, unsigned int max_loop) -+{ -+#define BUF_LEN 1024 -+ int i_ret = 0; -+ int idx = 0; -+ int buf_len = length > BUF_LEN ? BUF_LEN : length; -+ int loop = max_loop > 1000000 ? 1000000 : max_loop; -+ unsigned char *buffer; -+ -+ buffer = kmalloc(BUF_LEN, GFP_KERNEL); -+ if (!buffer) { -+ BTIF_ERR_FUNC("btif tester kmalloc failed\n"); -+ return -1; -+ } -+ -+ for (idx = 0; idx < buf_len; idx++) -+ /* btif_stress_test_buf[idx] = BUF_LEN -idx; */ -+ *(buffer + idx) = idx % 255; -+ i_ret = btif_loopback_ctrl_no_id(BTIF_LPBK_ENABLE); -+ BTIF_INFO_FUNC("mtk_wcn_btif_loopback_ctrl returned %d\n", i_ret); -+ while (loop--) { -+ i_ret = btif_write_no_id(buffer, buf_len); -+ BTIF_INFO_FUNC("mtk_wcn_btif_write left loop:%d, i_ret:%d\n", -+ loop, i_ret); -+ if (i_ret != buf_len) { -+ BTIF_INFO_FUNC -+ ("mtk_wcn_btif_write failed, target len %d, sent len: %d\n", -+ buf_len, i_ret); -+ break; -+ } -+ buf_len--; -+ if (buf_len <= 0) -+ buf_len = length > BUF_LEN ? BUF_LEN : length; -+ } -+ kfree(buffer); -+ return i_ret; -+} -+ -+int mtk_btif_exp_suspend_test(void) -+{ -+ int i_ret = 0; -+ p_mtk_btif p_btif = &g_btif[0]; -+ -+ i_ret = _btif_suspend(p_btif); -+ return i_ret; -+} -+ -+int mtk_btif_exp_restore_noirq_test(void) -+{ -+ int i_ret = 0; -+ p_mtk_btif p_btif = &g_btif[0]; -+ -+ i_ret = _btif_restore_noirq(p_btif); -+ return i_ret; -+} -+ -+int mtk_btif_exp_clock_ctrl(int en) -+{ -+ int i_ret = 0; -+ p_mtk_btif p_btif = &g_btif[0]; -+ -+ i_ret = btif_clock_ctrl(p_btif, en); -+ return i_ret; -+} -+ -+int mtk_btif_exp_resume_test(void) -+{ -+ int i_ret = 0; -+ p_mtk_btif p_btif = &g_btif[0]; -+ -+ i_ret = _btif_resume(p_btif); -+ return i_ret; -+} -+ -+int mtk_btif_exp_enter_dpidle_test(void) -+{ -+ return btif_dpidle_ctrl_no_id(BTIF_DPIDLE_ENABLE); -+} -+ -+int mtk_btif_exp_exit_dpidle_test(void) -+{ -+ return btif_dpidle_ctrl_no_id(BTIF_DPIDLE_DISABLE); -+} -+ -+int mtk_btif_exp_log_debug_test(int flag) -+{ -+ int i_ret = 0; -+ -+ i_ret = btif_dbg_ctrl_no_id(flag); -+ return i_ret; -+} -+ -+void mtk_btif_read_cpu_sw_rst_debug_exp(void) -+{ -+ mtk_btif_read_cpu_sw_rst_debug(); -+} -+ -+/************End of Function**********/ -diff --git a/drivers/misc/mediatek/btif/common/plat_inc/btif_dma_priv.h b/drivers/misc/mediatek/btif/common/plat_inc/btif_dma_priv.h -new file mode 100644 -index 000000000000..97756f684ab4 ---- /dev/null -+++ b/drivers/misc/mediatek/btif/common/plat_inc/btif_dma_priv.h -@@ -0,0 +1,164 @@ -+/* -+ * Copyright (C) 2015 MediaTek Inc. -+ * -+ * 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. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#ifndef __HAL_BTIF_DMA_H_ -+#define __HAL_BTIF_DMA_H_ -+ -+#include -+#include "btif_dma_pub.h" -+ -+#if defined(CONFIG_MTK_CLKMGR) -+#if defined(CONFIG_ARCH_MT6580) -+#define MTK_BTIF_APDMA_CLK_CG MT_CG_APDMA_SW_CG -+#elif defined(CONFIG_ARCH_MT6735) || defined(CONFIG_ARCH_MT6735M) || defined(CONFIG_ARCH_MT6753) -+#define MTK_BTIF_APDMA_CLK_CG MT_CG_PERI_APDMA -+#endif -+#else -+extern struct clk *clk_btif_apdma; /*btif apdma clock*/ -+#endif /* !defined(CONFIG_MTK_CLKMGR) */ -+ -+#define TX_DMA_VFF_SIZE (1024 * 8) /*Tx vFIFO Len must be 8 Byte allignment */ -+#define RX_DMA_VFF_SIZE (1024 * 8) /*Rx vFIFO Len must be 8 Byte allignment */ -+ -+#define DMA_TX_THRE(n) (n - 7) /*Tx Trigger Level */ -+#define DMA_RX_THRE(n) ((n) * 3 / 4) /*Rx Trigger Level */ -+ -+/**********************************Hardware related defination**************************/ -+#ifndef CONFIG_OF -+/*DMA channel's offset refer to AP_DMA's base address*/ -+#define BTIF_TX_DMA_OFFSET 0x880 -+#define BTIF_RX_DMA_OFFSET 0x900 -+#endif -+ -+/*Register Address Mapping*/ -+#define DMA_INT_FLAG_OFFSET 0x00 -+#define DMA_INT_EN_OFFSET 0x04 -+#define DMA_EN_OFFSET 0x08 -+#define DMA_RST_OFFSET 0x0C -+#define DMA_STOP_OFFSET 0x10 -+#define DMA_FLUSH_OFFSET 0x14 -+ -+#define DMA_BASE_OFFSET 0x1C -+#define DMA_LEN_OFFSET 0x24 -+ -+#define DMA_THRE_OFFSET 0x28 -+#define DMA_WPT_OFFSET 0x2C -+#define DMA_RPT_OFFSET 0x30 -+#define DMA_VALID_OFFSET 0x3C -+#define DMA_LEFT_OFFSET 0x40 -+#define DMA_VFF_BIT29_OFFSET 0x01 -+ -+#define TX_DMA_INT_FLAG(base) (unsigned long)(base + 0x0) /*BTIF Tx Virtual FIFO Interrupt Flag Register */ -+#define TX_DMA_INT_EN(base) (unsigned long)(base + 0x4) /*BTIF Tx Virtual FIFO Interrupt Enable Register */ -+#define TX_DMA_EN(base) (unsigned long)(base + DMA_EN_OFFSET)/*BTIF Tx Virtual FIFO Enable Register */ -+#define TX_DMA_RST(base) (unsigned long)(base + DMA_RST_OFFSET)/*BTIF Tx Virtual FIFO Reset Register */ -+#define TX_DMA_STOP(base) (unsigned long)(base + DMA_STOP_OFFSET)/*BTIF Tx Virtual FIFO STOP Register */ -+#define TX_DMA_FLUSH(base) (unsigned long)(base + DMA_FLUSH_OFFSET)/*BTIF Tx Virtual FIFO Flush Register */ -+#define TX_DMA_VFF_ADDR(base) (unsigned long)(base + 0x1C) /*BTIF Tx Virtual FIFO Base Address Register */ -+#define TX_DMA_VFF_LEN(base) (unsigned long)(base + 0x24) /*BTIF Tx Virtual FIFO Length Register */ -+#define TX_DMA_VFF_THRE(base) (unsigned long)(base + 0x28) /*BTIF Tx Virtual FIFO Threshold Register */ -+#define TX_DMA_VFF_WPT(base) (unsigned long)(base + 0x2C) /*BTIF Tx Virtual FIFO Write Pointer Register */ -+#define TX_DMA_VFF_RPT(base) (unsigned long)(base + 0x30) /*BTIF Tx Virtual FIFO Read Pointer Register */ -+#define TX_DMA_W_INT_BUF_SIZE(base) (unsigned long)(base + 0x34) -+/*BTIF Tx Virtual FIFO Internal Tx Write Buffer Size Register */ -+#define TX_DMA_INT_BUF_SIZE(base) (unsigned long)(base + 0x38) -+/*BTIF Tx Virtual FIFO Internal Tx Buffer Size Register */ -+ -+#define TX_DMA_VFF_VALID_SIZE(base) (unsigned long)(base + 0x3C) /*BTIF Tx Virtual FIFO Valid Size Register */ -+#define TX_DMA_VFF_LEFT_SIZE(base) (unsigned long)(base + 0x40) /*BTIF Tx Virtual FIFO Left Size Register */ -+#define TX_DMA_DEBUG_STATUS(base) (unsigned long)(base + 0x50) /*BTIF Tx Virtual FIFO Debug Status Register */ -+#define TX_DMA_VFF_ADDR_H(base) (unsigned long)(base + 0x54) /*BTIF Tx Virtual FIFO Base High Address Register */ -+ -+/*Rx Register Address Mapping*/ -+#define RX_DMA_INT_FLAG(base) (unsigned long)(base + 0x0) /*BTIF Rx Virtual FIFO Interrupt Flag Register */ -+#define RX_DMA_INT_EN(base) (unsigned long)(base + 0x4) /*BTIF Rx Virtual FIFO Interrupt Enable Register */ -+#define RX_DMA_EN(base) (unsigned long)(base + DMA_EN_OFFSET) /*BTIF Rx Virtual FIFO Enable Register */ -+#define RX_DMA_RST(base) (unsigned long)(base + DMA_RST_OFFSET) /*BTIF Rx Virtual FIFO Reset Register */ -+#define RX_DMA_STOP(base) (unsigned long)(base + DMA_STOP_OFFSET) /*BTIF Rx Virtual FIFO Stop Register */ -+#define RX_DMA_FLUSH(base) (unsigned long)(base + DMA_FLUSH_OFFSET) /*BTIF Rx Virtual FIFO Flush Register */ -+#define RX_DMA_VFF_ADDR(base) (unsigned long)(base + 0x1C) /*BTIF Rx Virtual FIFO Base Address Register */ -+#define RX_DMA_VFF_LEN(base) (unsigned long)(base + 0x24) /*BTIF Rx Virtual FIFO Length Register */ -+#define RX_DMA_VFF_THRE(base) (unsigned long)(base + 0x28) /*BTIF Rx Virtual FIFO Threshold Register */ -+#define RX_DMA_VFF_WPT(base) (unsigned long)(base + 0x2C) /*BTIF Rx Virtual FIFO Write Pointer Register */ -+#define RX_DMA_VFF_RPT(base) (unsigned long)(base + 0x30) /*BTIF Rx Virtual FIFO Read Pointer Register */ -+#define RX_DMA_FLOW_CTRL_THRE(base) (unsigned long)(base + 0x34) /*BTIF Rx Virtual FIFO Flow Control Register */ -+#define RX_DMA_INT_BUF_SIZE(base) (unsigned long)(base + 0x38) /*BTIF Rx Virtual FIFO Internal Buffer Register */ -+#define RX_DMA_VFF_VALID_SIZE(base) (unsigned long)(base + 0x3C) /*BTIF Rx Virtual FIFO Valid Size Register */ -+#define RX_DMA_VFF_LEFT_SIZE(base) (unsigned long)(base + 0x40) /*BTIF Rx Virtual FIFO Left Size Register */ -+#define RX_DMA_DEBUG_STATUS(base) (unsigned long)(base + 0x50) /*BTIF Rx Virtual FIFO Debug Status Register */ -+#define RX_DMA_VFF_ADDR_H(base) (unsigned long)(base + 0x54) /*BTIF Rx Virtual FIFO Base High Address Register */ -+ -+#define DMA_EN_BIT (0x1) -+#define DMA_STOP_BIT (0x1) -+#define DMA_RST_BIT (0x1) -+#define DMA_FLUSH_BIT (0x1) -+ -+#define DMA_WARM_RST (0x1 << 0) -+#define DMA_HARD_RST (0x1 << 1) -+ -+#define DMA_WPT_MASK (0x0000FFFF) -+#define DMA_WPT_WRAP (0x00010000) -+ -+#define DMA_RPT_MASK (0x0000FFFF) -+#define DMA_RPT_WRAP (0x00010000) -+ -+/*APDMA BTIF Tx Reg Ctrl Bit*/ -+#define TX_DMA_INT_FLAG_MASK (0x1) -+ -+#define TX_DMA_INTEN_BIT (0x1) -+ -+#define TX_DMA_ADDR_MASK (0xFFFFFFF8) -+#define TX_DMA_LEN_MASK (0x0000FFF8) -+ -+#define TX_DMA_THRE_MASK (0x0000FFFF) -+ -+#define TX_DMA_W_INT_BUF_MASK (0x000000FF) -+ -+#define TX_DMA_VFF_VALID_MASK (0x0000FFFF) -+#define TX_DMA_VFF_LEFT_MASK (0x0000FFFF) -+ -+/*APDMA BTIF Rx Reg Ctrl Bit*/ -+#define RX_DMA_INT_THRE (0x1 << 0) -+#define RX_DMA_INT_DONE (0x1 << 1) -+ -+#define RX_DMA_INT_THRE_EN (0x1 << 0) -+#define RX_DMA_INT_DONE_EN (0x1 << 1) -+ -+#define RX_DMA_ADDR_MASK (0xFFFFFFF8) -+#define RX_DMA_LEN_MASK (0x0000FFF8) -+ -+#define RX_DMA_THRE_MASK (0x0000FFFF) -+ -+#define RX_DMA_FLOW_CTRL_THRE_MASK (0x000000FF) -+ -+#define RX_DMA_INT_BUF_SIZE_MASK (0x0000001F) -+ -+#define RX_DMA_VFF_VALID_MASK (0x0000001F) -+ -+#define RX_DMA_VFF_LEFT_MASK (0x0000FFFF) -+ -+typedef struct _MTK_BTIF_DMA_VFIFO_ { -+ DMA_VFIFO vfifo; -+ unsigned int wpt; /*DMA's write pointer, which is maintained by SW for Tx DMA and HW for Rx DMA */ -+ unsigned int last_wpt_wrap; /*last wrap bit for wpt */ -+ unsigned int rpt; /*DMA's read pointer, which is maintained by HW for Tx DMA and SW for Rx DMA */ -+ unsigned int last_rpt_wrap; /*last wrap bit for rpt */ -+} MTK_BTIF_DMA_VFIFO, *P_MTK_BTIF_DMA_VFIFO; -+ -+/*for DMA debug purpose*/ -+typedef struct _MTK_BTIF_DMA_REG_DMP_DBG_ { -+ unsigned long reg_addr; -+ unsigned int reg_val; -+} MTK_BTIF_DMA_REG_DMP_DBG, *P_MTK_BTIF_DMA_REG_DMP_DBG; -+ -+#endif /*__HAL_BTIF_DMA_H_*/ -diff --git a/drivers/misc/mediatek/btif/common/plat_inc/btif_dma_pub.h b/drivers/misc/mediatek/btif/common/plat_inc/btif_dma_pub.h -new file mode 100644 -index 000000000000..0773f2ce387a ---- /dev/null -+++ b/drivers/misc/mediatek/btif/common/plat_inc/btif_dma_pub.h -@@ -0,0 +1,197 @@ -+/* -+ * Copyright (C) 2015 MediaTek Inc. -+ * -+ * 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. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#ifndef __HAL_BTIFD_DMA_PUB_H_ -+#define __HAL_BTIFD_DMA_PUB_H_ -+ -+#include -+ -+#include "plat_common.h" -+ -+typedef enum _ENUM_DMA_CTRL_ { -+ DMA_CTRL_DISABLE = 0, -+ DMA_CTRL_ENABLE = DMA_CTRL_DISABLE + 1, -+ DMA_CTRL_BOTH, -+} ENUM_DMA_CTRL; -+ -+/***************************************************************************** -+* FUNCTION -+* hal_tx_dma_info_get -+* DESCRIPTION -+* get btif tx dma channel's information -+* PARAMETERS -+* dma_dir [IN] DMA's direction -+* RETURNS -+* pointer to btif dma's information structure -+*****************************************************************************/ -+P_MTK_DMA_INFO_STR hal_btif_dma_info_get(ENUM_DMA_DIR dma_dir); -+ -+/***************************************************************************** -+* FUNCTION -+* hal_btif_dma_hw_init -+* DESCRIPTION -+* control clock output enable/disable of DMA module -+* PARAMETERS -+* p_dma_info [IN] pointer to BTIF dma channel's information -+* RETURNS -+* 0 means success, negative means fail -+*****************************************************************************/ -+int hal_btif_dma_hw_init(P_MTK_DMA_INFO_STR p_dma_info); -+ -+/***************************************************************************** -+* FUNCTION -+* hal_btif_clk_ctrl -+* DESCRIPTION -+* control clock output enable/disable of DMA module -+* PARAMETERS -+* p_dma_info [IN] pointer to BTIF dma channel's information -+* RETURNS -+* 0 means success, negative means fail -+*****************************************************************************/ -+int hal_btif_dma_clk_ctrl(P_MTK_DMA_INFO_STR p_dma_info, ENUM_CLOCK_CTRL flag); -+ -+/***************************************************************************** -+* FUNCTION -+* hal_tx_dma_ctrl -+* DESCRIPTION -+* enable/disable Tx DMA channel -+* PARAMETERS -+* p_dma_info [IN] pointer to BTIF dma channel's information -+* ctrl_id [IN] enable/disable ID -+* dma_dir [IN] DMA's direction -+* RETURNS -+* 0 means success; negative means fail -+*****************************************************************************/ -+int hal_btif_dma_ctrl(P_MTK_DMA_INFO_STR p_dma_info, ENUM_DMA_CTRL ctrl_id); -+ -+/***************************************************************************** -+* FUNCTION -+* hal_btif_dma_rx_cb_reg -+* DESCRIPTION -+* register rx callback function to dma module -+* PARAMETERS -+* p_dma_info [IN] pointer to BTIF dma channel's information -+* rx_cb [IN] function pointer to btif -+* RETURNS -+* 0 means success; negative means fail -+*****************************************************************************/ -+int hal_btif_dma_rx_cb_reg(P_MTK_DMA_INFO_STR p_dma_info, -+ dma_rx_buf_write rx_cb); -+ -+/***************************************************************************** -+* FUNCTION -+* hal_tx_vfifo_reset -+* DESCRIPTION -+* reset tx virtual fifo information, except memory information -+* PARAMETERS -+* p_dma_info [IN] pointer to BTIF dma channel's information -+* dma_dir [IN] DMA's direction -+* RETURNS -+* 0 means success, negative means fail -+*****************************************************************************/ -+int hal_btif_vfifo_reset(P_MTK_DMA_INFO_STR p_dma_info); -+ -+/***************************************************************************** -+* FUNCTION -+* hal_tx_dma_irq_handler -+* DESCRIPTION -+* lower level tx interrupt handler -+* PARAMETERS -+* p_dma_info [IN] pointer to BTIF dma channel's information -+* RETURNS -+* 0 means success, negative means fail -+*****************************************************************************/ -+int hal_tx_dma_irq_handler(P_MTK_DMA_INFO_STR p_dma_info); -+ -+/***************************************************************************** -+* FUNCTION -+* hal_dma_send_data -+* DESCRIPTION -+* send data through btif in DMA mode -+* PARAMETERS -+* p_dma_info [IN] pointer to BTIF dma channel's information -+* p_buf [IN] pointer to rx data buffer -+* max_len [IN] tx buffer length -+* RETURNS -+* 0 means success, negative means fail -+*****************************************************************************/ -+int hal_dma_send_data(P_MTK_DMA_INFO_STR p_dma_info, -+ const unsigned char *p_buf, const unsigned int buf_len); -+ -+/***************************************************************************** -+* FUNCTION -+* hal_dma_is_tx_complete -+* DESCRIPTION -+* get tx complete flag -+* PARAMETERS -+* p_dma_info [IN] pointer to BTIF dma channel's information -+* RETURNS -+* true means tx complete, false means tx in process -+*****************************************************************************/ -+bool hal_dma_is_tx_complete(P_MTK_DMA_INFO_STR p_dma_info); -+ -+/***************************************************************************** -+* FUNCTION -+* hal_dma_get_ava_room -+* DESCRIPTION -+* get tx available room -+* PARAMETERS -+* p_dma_info [IN] pointer to BTIF dma channel's information -+* RETURNS -+* available room size -+*****************************************************************************/ -+int hal_dma_get_ava_room(P_MTK_DMA_INFO_STR p_dma_info); -+ -+/***************************************************************************** -+* FUNCTION -+* hal_dma_is_tx_allow -+* DESCRIPTION -+* is tx operation allowed by DMA -+* PARAMETERS -+* p_dma_info [IN] pointer to BTIF dma channel's information -+* RETURNS -+* true if tx operation is allowed; false if tx is not allowed -+*****************************************************************************/ -+bool hal_dma_is_tx_allow(P_MTK_DMA_INFO_STR p_dma_info); -+ -+/***************************************************************************** -+* FUNCTION -+* hal_rx_dma_irq_handler -+* DESCRIPTION -+* lower level rx interrupt handler -+* PARAMETERS -+* p_dma_info [IN] pointer to BTIF dma channel's information -+* p_buf [IN/OUT] pointer to rx data buffer -+* max_len [IN] max length of rx buffer -+* RETURNS -+* 0 means success, negative means fail -+*****************************************************************************/ -+int hal_rx_dma_irq_handler(P_MTK_DMA_INFO_STR p_dma_info, -+ unsigned char *p_buf, const unsigned int max_len); -+ -+/***************************************************************************** -+* FUNCTION -+* hal_dma_dump_reg -+* DESCRIPTION -+* dump BTIF module's information when needed -+* PARAMETERS -+* p_dma_info [IN] pointer to BTIF dma channel's information -+* flag [IN] register id flag -+* RETURNS -+* 0 means success, negative means fail -+*****************************************************************************/ -+int hal_dma_dump_reg(P_MTK_DMA_INFO_STR p_dma_info, ENUM_BTIF_REG_ID flag); -+ -+int hal_dma_pm_ops(P_MTK_DMA_INFO_STR p_dma_info, MTK_BTIF_PM_OPID opid); -+ -+#endif /*__HAL_BTIFD_DMA_PUB_H_*/ -diff --git a/drivers/misc/mediatek/btif/common/plat_inc/btif_priv.h b/drivers/misc/mediatek/btif/common/plat_inc/btif_priv.h -new file mode 100644 -index 000000000000..51fe58a82b49 ---- /dev/null -+++ b/drivers/misc/mediatek/btif/common/plat_inc/btif_priv.h -@@ -0,0 +1,105 @@ -+/* -+ * Copyright (C) 2015 MediaTek Inc. -+ * -+ * 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. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#ifndef __HAL_BTIF_H_ -+#define __HAL_BTIF_H_ -+ -+#ifndef CONFIG_OF -+#define MTK_BTIF_REG_BASE BTIF_BASE -+#endif -+ -+#if defined(CONFIG_MTK_CLKMGR) -+#if defined(CONFIG_ARCH_MT6580) -+#define MTK_BTIF_CG_BIT MT_CG_BTIF_SW_CG -+#elif defined(CONFIG_ARCH_MT6735) || defined(CONFIG_ARCH_MT6735M) || defined(CONFIG_ARCH_MT6753) -+#define MTK_BTIF_CG_BIT MT_CG_PERI_BTIF -+#endif -+#else -+struct clk *clk_btif_apdma; /*btif apdma clock*/ -+struct clk *clk_btif; /*btif clock*/ -+#endif /* !defined(CONFIG_MTK_CLKMGR) */ -+ -+#define BTIF_RBR(base) (unsigned long)(base + 0x0) /*RX Buffer Register: read only */ -+#define BTIF_THR(base) (unsigned long)(base + 0x0) /*Rx Holding Register: write only */ -+#define BTIF_IER(base) (unsigned long)(base + 0x4) /*Interrupt Enable Register: read/write */ -+#define BTIF_IIR(base) (unsigned long)(base + 0x8) /*Interrupt Identification Register: read only */ -+#define BTIF_FIFOCTRL(base) (unsigned long)(base + 0x8) /*FIFO Control Register: write only */ -+#define BTIF_FAKELCR(base) (unsigned long)(base + 0xC) /*FAKE LCR Register: read/write */ -+#define BTIF_LSR(base) (unsigned long)(base + 0x14) /*Line Status Register: read only */ -+#define BTIF_SLEEP_EN(base) (unsigned long)(base + 0x48) /*Sleep Enable Register: read/write */ -+#define BTIF_DMA_EN(base) (unsigned long)(base + 0x4C) /*DMA Enable Register: read/write */ -+#define BTIF_RTOCNT(base) (unsigned long)(base + 0x54) /*Rx Timeout Count Register: read/write */ -+#define BTIF_TRI_LVL(base) (unsigned long)(base + 0x60) /*Tx/Rx Trigger Level Control Register: read/write */ -+#define BTIF_WAK(base) (unsigned long)(base + 0x64) /*BTIF module wakeup Register: write only */ -+#define BTIF_WAT_TIME(base) (unsigned long)(base + 0x68) /*BTIF ASYNC Wait Time Control Register: read/write */ -+#define BTIF_HANDSHAKE(base) (unsigned long)(base + 0x6C) /*BTIF New Handshake Control Register: read/write */ -+ -+/*BTIF_IER bits*/ -+#define BTIF_IER_TXEEN (0x1 << 1) /*1: Tx holding register is empty */ -+#define BTIF_IER_RXFEN (0x1 << 0) /*1: Rx buffer contains data */ -+ -+/*BTIF_IIR bits*/ -+#define BTIF_IIR_NINT (0x1 << 0) /*No INT Pending */ -+#define BTIF_IIR_TX_EMPTY (0x1 << 1) /*Tx Holding Register empty */ -+#define BTIF_IIR_RX (0x1 << 2) /*Rx data received */ -+#define BTIF_IIR_RX_TIMEOUT (0x11 << 2) /*Rx data received */ -+ -+/*BTIF_LSR bits*/ -+#define BTIF_LSR_DR_BIT (0x1 << 0) -+#define BTIF_LSR_THRE_BIT (0x1 << 5) -+#define BTIF_LSR_TEMT_BIT (0x1 << 6) -+ -+/*BTIF_FIFOCTRL bits*/ -+#define BTIF_FIFOCTRL_CLR_TX (0x1 << 2) /*Clear Tx FIRO */ -+#define BTIF_FIFOCTRL_CLR_RX (0x1 << 1) /*Clear Rx FIRO */ -+ -+/*BTIF_FAKELCR bits*/ -+#define BTIF_FAKELCR_NORMAL_MODE 0x0 -+ -+/*BTIF_SLEEP_EN bits*/ -+#define BTIF_SLEEP_EN_BIT (0x1 << 0) /*enable Sleep mode */ -+#define BTIF_SLEEP_DIS_BIT (0x0) /*disable sleep mode */ -+ -+/*BTIF_DMA_EN bits*/ -+#define BTIF_DMA_EN_RX (0x1 << 0) /*Enable Rx DMA */ -+#define BTIF_DMA_EN_TX (0x1 << 1) /*Enable Tx DMA */ -+#define BTIF_DMA_EN_AUTORST_EN (0x1 << 2) /*1: timeout counter will be auto reset */ -+#define BTIF_DMA_EN_AUTORST_DIS (0x0 << 2) /* -+ * 0: after Rx timeout happens, -+ * SW shall reset the interrupt by reading BTIF 0x4C -+ */ -+ -+/*BTIF_TRI_LVL bits*/ -+#define BTIF_TRI_LVL_TX_MASK ((0xf) << 0) -+#define BTIF_TRI_LVL_RX_MASK ((0x7) << 4) -+ -+#define BTIF_TRI_LVL_TX(x) ((x & 0xf) << 0) -+#define BTIF_TRI_LVL_RX(x) ((x & 0x7) << 4) -+ -+#define BTIF_TRI_LOOP_EN (0x1 << 7) -+#define BTIF_TRI_LOOP_DIS (0x0 << 7) -+ -+/*BTIF_WAK bits*/ -+#define BTIF_WAK_BIT (0x1 << 0) -+ -+/*BTIF_HANDSHAKE bits*/ -+#define BTIF_HANDSHAKE_EN_HANDSHAKE 1 -+#define BTIF_HANDSHAKE_DIS_HANDSHAKE 0 -+ -+#define BTIF_TX_FIFO_SIZE 16 -+#define BTIF_RX_FIFO_SIZE 8 -+ -+#define BTIF_TX_FIFO_THRE (BTIF_TX_FIFO_SIZE / 2) -+#define BTIF_RX_FIFO_THRE 0x1 /* 0x5 */ -+ -+#endif /*__HAL_BTIF_H_*/ -diff --git a/drivers/misc/mediatek/btif/common/plat_inc/btif_pub.h b/drivers/misc/mediatek/btif/common/plat_inc/btif_pub.h -new file mode 100644 -index 000000000000..1555d5a50c38 ---- /dev/null -+++ b/drivers/misc/mediatek/btif/common/plat_inc/btif_pub.h -@@ -0,0 +1,237 @@ -+/* -+ * Copyright (C) 2015 MediaTek Inc. -+ * -+ * 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. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#ifndef __HAL_BTIF_PUB_H_ -+#define __HAL_BTIF_PUB_H_ -+ -+#include "plat_common.h" -+ -+/*Enum Defination*/ -+/*BTIF Mode Enum */ -+typedef enum _ENUM_BTIF_MODE_ { -+ BTIF_MODE_PIO = 0, -+ BTIF_MODE_DMA = BTIF_MODE_PIO + 1, -+ BTIF_MODE_MAX, -+} ENUM_BTIF_MODE; -+ -+/***************************************************************************** -+* FUNCTION -+* hal_btif_info_get -+* DESCRIPTION -+* get btif's information included base address , irq related information -+* PARAMETERS -+* RETURNS -+* BTIF's information -+*****************************************************************************/ -+P_MTK_BTIF_INFO_STR hal_btif_info_get(void); -+ -+#if 0 /*included in hal_btif_info_get */ -+/***************************************************************************** -+* FUNCTION -+* hal_btif_get_irq -+* DESCRIPTION -+* get BTIF module's IRQ information -+* PARAMETERS -+* RETURNS -+* pointer to BTIF's irq structure -+*****************************************************************************/ -+P_MTK_BTIF_IRQ_STR hal_btif_get_irq(void); -+#endif -+ -+#if !defined(CONFIG_MTK_CLKMGR) -+/***************************************************************************** -+* FUNCTION -+* hal_btif_clk_get_and_prepare -+* DESCRIPTION -+* get clock from device tree and prepare for enable/disable control -+* PARAMETERS -+* pdev device pointer -+* RETURNS -+* 0 means success, negative means fail -+*****************************************************************************/ -+int hal_btif_clk_get_and_prepare(struct platform_device *pdev); -+/***************************************************************************** -+* FUNCTION -+* hal_btif_clk_unprepare -+* DESCRIPTION -+* unprepare btif clock and apdma clock -+* PARAMETERS -+* none -+* RETURNS -+* 0 means success, negative means fail -+*****************************************************************************/ -+int hal_btif_clk_unprepare(void); -+#endif -+/***************************************************************************** -+* FUNCTION -+* hal_btif_clk_ctrl -+* DESCRIPTION -+* control clock output enable/disable of BTIF module -+* PARAMETERS -+* p_base [IN] BTIF module's base address -+* RETURNS -+* 0 means success, negative means fail -+*****************************************************************************/ -+int hal_btif_clk_ctrl(P_MTK_BTIF_INFO_STR p_btif, ENUM_CLOCK_CTRL flag); -+ -+/***************************************************************************** -+* FUNCTION -+* hal_btif_hw_init -+* DESCRIPTION -+* BTIF module init, after this step, BTIF should enable to do tx/rx with PIO -+* mode -+* PARAMETERS -+* p_base [IN] BTIF module's base address -+* RETURNS -+* 0 means success, negative means fail -+*****************************************************************************/ -+int hal_btif_hw_init(P_MTK_BTIF_INFO_STR p_btif); -+ -+/***************************************************************************** -+* FUNCTION -+* hal_btif_rx_cb_reg -+* DESCRIPTION -+* BTIF rx callback register API -+* PARAMETERS -+* p_btif_info [IN] pointer to BTIF's information -+* rx_cb [IN] rx callback function -+* RETURNS -+* 0 means success, negative means fail -+*****************************************************************************/ -+int hal_btif_rx_cb_reg(P_MTK_BTIF_INFO_STR p_btif_info, -+ btif_rx_buf_write rx_cb); -+ -+/***************************************************************************** -+* FUNCTION -+* hal_btif_loopback_ctrl -+* DESCRIPTION -+* BTIF Tx/Rx loopback mode set, this operation can only be done -+* after set BTIF to normal mode -+* PARAMETERS -+* RETURNS -+* 0 means success, negative means fail -+*****************************************************************************/ -+int hal_btif_loopback_ctrl(P_MTK_BTIF_INFO_STR p_btif, bool en); -+ -+/***************************************************************************** -+* FUNCTION -+* hal_btif_rx_handler -+* DESCRIPTION -+* lower level interrupt handler -+* PARAMETERS -+* p_base [IN] BTIF module's base address -+* p_buf [IN/OUT] pointer to rx data buffer -+* max_len [IN] max length of rx buffer -+* RETURNS -+* 0 means success; negative means fail; positive means rx data length -+*****************************************************************************/ -+int hal_btif_irq_handler(P_MTK_BTIF_INFO_STR p_btif, -+ unsigned char *p_buf, const unsigned int max_len); -+ -+/***************************************************************************** -+* FUNCTION -+* hal_btif_tx_mode_ctrl -+* DESCRIPTION -+* set BTIF tx to corresponding mode (PIO/DMA) -+* PARAMETERS -+* p_base [IN] BTIF module's base address -+* mode [IN] rx mode -+* RETURNS -+* 0 means success, negative means fail -+*****************************************************************************/ -+int hal_btif_tx_mode_ctrl(P_MTK_BTIF_INFO_STR p_btif, ENUM_BTIF_MODE mode); -+ -+/***************************************************************************** -+* FUNCTION -+* hal_btif_rx_mode_ctrl -+* DESCRIPTION -+* set BTIF rx to corresponding mode (PIO/DMA) -+* PARAMETERS -+* p_base [IN] BTIF module's base address -+* mode [IN] rx mode -+* RETURNS -+* 0 means success, negative means fail -+*****************************************************************************/ -+int hal_btif_rx_mode_ctrl(P_MTK_BTIF_INFO_STR p_btif, ENUM_BTIF_MODE mode); -+ -+/***************************************************************************** -+* FUNCTION -+* hal_btif_send_data -+* DESCRIPTION -+* send data through btif in FIFO mode -+* PARAMETERS -+* p_base [IN] BTIF module's base address -+* p_buf [IN] pointer to rx data buffer -+* max_len [IN] tx buffer length -+* RETURNS -+* positive means number of data sent; -+* 0 means no data put to FIFO; -+* negative means error happens -+*****************************************************************************/ -+int hal_btif_send_data(P_MTK_BTIF_INFO_STR p_btif, -+ const unsigned char *p_buf, const unsigned int buf_len); -+ -+/***************************************************************************** -+* FUNCTION -+* hal_btif_raise_wak_sig -+* DESCRIPTION -+* raise wakeup signal to counterpart -+* PARAMETERS -+* p_base [IN] BTIF module's base address -+* RETURNS -+* 0 means success, negative means fail -+*****************************************************************************/ -+int hal_btif_raise_wak_sig(P_MTK_BTIF_INFO_STR p_btif); -+ -+/***************************************************************************** -+* FUNCTION -+* hal_btif_dump_reg -+* DESCRIPTION -+* dump BTIF module's information when needed -+* PARAMETERS -+* p_base [IN] BTIF module's base address -+* flag [IN] register id flag -+* RETURNS -+* 0 means success, negative means fail -+*****************************************************************************/ -+int hal_btif_dump_reg(P_MTK_BTIF_INFO_STR p_btif, ENUM_BTIF_REG_ID flag); -+ -+/***************************************************************************** -+* FUNCTION -+* hal_btif_is_tx_complete -+* DESCRIPTION -+* get tx complete flag -+* PARAMETERS -+* p_base [IN] BTIF module's base address -+* RETURNS -+* true means tx complete, false means tx in process -+*****************************************************************************/ -+bool hal_btif_is_tx_complete(P_MTK_BTIF_INFO_STR p_btif); -+ -+/***************************************************************************** -+* FUNCTION -+* hal_btif_is_tx_allow -+* DESCRIPTION -+* whether tx is allowed -+* PARAMETERS -+* p_base [IN] BTIF module's base address -+* RETURNS -+* true if tx operation is allowed; false if tx is not allowed -+*****************************************************************************/ -+bool hal_btif_is_tx_allow(P_MTK_BTIF_INFO_STR p_btif); -+ -+int hal_btif_pm_ops(P_MTK_BTIF_INFO_STR p_btif, MTK_BTIF_PM_OPID opid); -+ -+void mtk_btif_read_cpu_sw_rst_debug_plat(void); -+ -+#endif /*__HAL_BTIF_PUB_H_*/ -diff --git a/drivers/misc/mediatek/btif/common/plat_inc/plat_common.h b/drivers/misc/mediatek/btif/common/plat_inc/plat_common.h -new file mode 100644 -index 000000000000..2a1462cb32ff ---- /dev/null -+++ b/drivers/misc/mediatek/btif/common/plat_inc/plat_common.h -@@ -0,0 +1,307 @@ -+/* -+ * Copyright (C) 2015 MediaTek Inc. -+ * -+ * 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. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#ifndef __HAL_PUB_H_ -+#define __HAL_PUB_H_ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#ifdef CONFIG_OF -+#include -+#include -+#include -+#else -+#include -+#include -+#endif -+#if defined(CONFIG_MTK_CLKMGR) -+#include -+#else -+#include -+#include -+#endif /* defined(CONFIG_MTK_CLKMGR) */ -+#include -+ -+extern int mtk_btif_hal_get_log_lvl(void); -+ -+#define MTK_BTIF_MARK_UNUSED_API -+ -+typedef irq_handler_t mtk_btif_irq_handler; -+ -+#define MTK_BTIF_ENABLE_CLK_CTL 1 -+#define MTK_BTIF_ENABLE_CLK_REF_COUNTER 1 -+ -+#define DBG_LOG_STR_SIZE 256 -+ -+/*Log defination*/ -+static int hal_log_print(const char *str, ...) -+{ -+ va_list args; -+ char temp_sring[DBG_LOG_STR_SIZE]; -+ -+ va_start(args, str); -+ vsnprintf(temp_sring, DBG_LOG_STR_SIZE, str, args); -+ va_end(args); -+ -+ pr_err("%s", temp_sring); -+ -+ return 0; -+} -+ -+#define BTIF_LOG_LOUD 4 -+#define BTIF_LOG_DBG 3 -+#define BTIF_LOG_INFO 2 -+#define BTIF_LOG_WARN 1 -+#define BTIF_LOG_ERR 0 -+ -+#ifndef DFT_TAG -+#define DFT_TAG "[BTIF-DFT]" -+#endif -+ -+#define BTIF_LOUD_FUNC(fmt, arg ...) \ -+do { \ -+ if (mtk_btif_hal_get_log_lvl() >= BTIF_LOG_LOUD) \ -+ hal_log_print(DFT_TAG "[L]%s:" fmt, \ -+ __func__, ## arg); \ -+} while (0) -+ -+#define BTIF_INFO_FUNC(fmt, arg ...) \ -+do { \ -+ if (mtk_btif_hal_get_log_lvl() >= BTIF_LOG_INFO)\ -+ hal_log_print(DFT_TAG "[I]%s:" fmt, \ -+ __func__, ## arg); \ -+} while (0) -+ -+#define BTIF_WARN_FUNC(fmt, arg ...) \ -+do { \ -+ if (mtk_btif_hal_get_log_lvl() >= BTIF_LOG_WARN)\ -+ hal_log_print(DFT_TAG "[W]%s:" fmt, \ -+ __func__, ## arg); \ -+} while (0) -+ -+#define BTIF_ERR_FUNC(fmt, arg ...)\ -+do {\ -+ if (mtk_btif_hal_get_log_lvl() >= BTIF_LOG_ERR)\ -+ hal_log_print(DFT_TAG "[E]%s(%d):" fmt,\ -+ __func__, __LINE__, ## arg);\ -+} while (0) -+ -+#define BTIF_DBG_FUNC(fmt, arg ...) \ -+do { \ -+ if (mtk_btif_hal_get_log_lvl() >= BTIF_LOG_DBG) \ -+ hal_log_print(DFT_TAG "[D]%s:" fmt, \ -+ __func__, ## arg); \ -+} while (0) -+ -+#define BTIF_TRC_FUNC(f) \ -+do { \ -+ if (mtk_btif_hal_get_log_lvl() >= BTIF_LOG_DBG) \ -+ hal_log_print(DFT_TAG "<%s> <%d>\n", \ -+ __func__, __LINE__); \ -+} while (0) -+ -+/*-----------------------------------Enum Defination--------------------------------*/ -+/*IRQ sensetive type */ -+typedef enum _ENUM_IRQ_SENS_TYPE_ { -+ IRQ_SENS_EDGE = 0, -+ IRQ_SENS_LVL = IRQ_SENS_EDGE + 1, -+ IRQ_SENS_TYPE_MAX -+} ENUM_IRQ_SENS_TYPE; -+ -+/*IRQ level trigger type */ -+typedef enum _ENUM_IRQ_LVL_TYPE_ { -+ IRQ_LVL_LOW = 0, -+ IRQ_LVL_HIGH = IRQ_LVL_LOW + 1, -+ IRQ_LVL_MAX -+} ENUM_IRQ_LVL; -+ -+/*IRQ edge trigger type */ -+typedef enum _ENUM_IRQ_EDGE_TYPE_ { -+ IRQ_EDGE_FALL = 0, -+ IRQ_EDGE_RAISE = IRQ_EDGE_FALL + 1, -+ IRQ_EDGE_BOTH = IRQ_EDGE_RAISE + 1, -+ IRQ_EDGE_MAX -+} ENUM_IRQ_EDGE; -+ -+typedef enum _ENUM_CLOCK_CTRL_ { -+ CLK_OUT_DISABLE = 0, -+ CLK_OUT_ENABLE = CLK_OUT_DISABLE + 1, -+ CLK_OUT_MAX -+} ENUM_CLOCK_CTRL; -+ -+/*Error No. table */ -+typedef enum _ENUM_ERROR_CODE_ { -+ ERR_NO_ERROR = 0, -+ ERR_INVALID_PAR = ERR_NO_ERROR - 1, -+ ERR_MAX = ERR_INVALID_PAR - 1, -+} ENUM_ERROR_CODE; -+ -+typedef enum _ENUM_BTIF_DIR_ { -+ BTIF_TX = 0, -+ BTIF_RX = BTIF_TX + 1, -+ BTIF_DIR_MAX, -+} ENUM_BTIF_DIR; -+ -+typedef enum _ENUM_DMA_DIR_ { -+ DMA_DIR_RX = 0, -+ DMA_DIR_TX = DMA_DIR_RX + 1, -+ DMA_DIR_BOTH, -+} ENUM_DMA_DIR; -+ -+typedef enum _ENUM_BTIF_REG_ID_ { -+ REG_IIR = 0, /*Interrupt Identification Register */ -+ REG_LSR = 1, /*Line Status Register */ -+ REG_FAKE_LCR = 2, /*Fake Lcr Regiseter */ -+ REG_FIFO_CTRL = 3, /*FIFO Control Register */ -+ REG_IER = 4, /*Interrupt Enable Register */ -+ REG_SLEEP_EN = 5, /*Sleep Enable Register */ -+ REG_RTO_COUNTER = 6, /*Rx Timeout Counter Register */ -+ REG_DMA_EN = 7, /*DMA Enalbe Register */ -+ REG_TRIG_LVL = 8, /*Tx/Rx Trigger Level Register */ -+ REG_WAT_TIME = 9, /*Async Wait Time Register */ -+ REG_HANDSHAKE = 10, /*New HandShake Mode Register */ -+ REG_SLP_WAK = 11, /*Sleep Wakeup Reigster */ -+ REG_BTIF_ALL = 12, /*all btif controller's registers */ -+ REG_TX_DMA_ALL = 13, -+ REG_RX_DMA_ALL = 14, -+ REG_MAX -+} ENUM_BTIF_REG_ID; -+ -+typedef enum _MTK_BTIF_PM_OPID_ { -+ BTIF_PM_DPIDLE_EN, -+ BTIF_PM_DPIDLE_DIS, -+ BTIF_PM_SUSPEND, -+ BTIF_PM_RESUME, -+ BTIF_PM_RESTORE_NOIRQ, -+} MTK_BTIF_PM_OPID; -+ -+#define BTIF_HAL_TX_FIFO_SIZE (1024 * 4) -+ -+/*-----------------------------------Enum Defination End--------------------------------*/ -+ -+/*****************************structure definition***************************/ -+/*IRQ related information*/ -+typedef struct _MTK_BTIF_IRQ_STR_ { -+ const char *name; -+ bool is_irq_sup; -+ unsigned int irq_id; -+#ifdef CONFIG_OF -+ unsigned int irq_flags; -+#else -+ ENUM_IRQ_SENS_TYPE sens_type; -+ union { -+ ENUM_IRQ_LVL lvl_type; -+ ENUM_IRQ_EDGE edge_type; -+ }; -+#endif -+ bool reg_flag; -+ irq_handler_t p_irq_handler; -+} MTK_BTIF_IRQ_STR, *P_MTK_BTIF_IRQ_STR; -+ -+typedef struct _DMA_VFIFO_ { -+ /*[Driver Access] vFIFO memory'svirtual address */ -+ unsigned char *p_vir_addr; -+ /*[HW Access] dma handle , physically address, set to DMA's HW Register */ -+ dma_addr_t phy_addr; -+ /*DMA's vFIFO size */ -+ unsigned int vfifo_size; -+ /*DMA's threshold value */ -+ unsigned int thre; -+} DMA_VFIFO, *P_DMA_VFIFO; -+ -+typedef unsigned int (*dma_rx_buf_write) (void *p_dma_info, -+ unsigned char *p_buf, -+ unsigned int buf_len); -+typedef unsigned int (*btif_rx_buf_write) (void *p_btif_info, -+ unsigned char *p_buf, -+ unsigned int buf_len); -+ -+/*DMA related information*/ -+typedef struct _MTK_DMA_INFO_STR_ { -+ unsigned long base; -+ ENUM_DMA_DIR dir; -+ P_MTK_BTIF_IRQ_STR p_irq; -+ dma_rx_buf_write rx_cb; -+ P_DMA_VFIFO p_vfifo; -+} MTK_DMA_INFO_STR, *P_MTK_DMA_INFO_STR; -+ -+/*DMA related information*/ -+typedef struct _MTK_BTIF_INFO_STR_ { -+ unsigned long base; /*base address */ -+ P_MTK_BTIF_IRQ_STR p_irq; /*irq related information */ -+ -+ unsigned int tx_fifo_size; /*BTIF tx FIFO size */ -+ unsigned int rx_fifo_size; /*BTIF rx FIFO size */ -+ -+ unsigned int tx_tri_lvl; /*BTIFtx trigger level in FIFO mode */ -+ unsigned int rx_tri_lvl; /*BTIFrx trigger level in FIFO mode */ -+ -+ unsigned int clk_gat_addr; /*clock gating address */ -+ unsigned int set_bit; /*enable clock gating bit */ -+ unsigned int clr_bit; /*clear clock gating bit */ -+ -+ unsigned int rx_data_len; /*rx data length */ -+ -+ btif_rx_buf_write rx_cb; -+ -+ struct kfifo *p_tx_fifo; /*tx fifo */ -+ spinlock_t tx_fifo_spinlock; /*tx fifo spinlock */ -+} MTK_BTIF_INFO_STR, *P_MTK_BTIF_INFO_STR; -+ -+/**********End of Structure Definition***********/ -+ -+/***********register operation***********/ -+#ifdef __KERNEL__ -+/*byte write <1 byte> */ -+#define btif_reg_sync_writeb(v, a) mt_reg_sync_writeb(v, a) -+/*word write <2 byte> */ -+#define btif_reg_sync_writew(v, a) mt_reg_sync_writew(v, a) -+/*long write <4 byte> */ -+#define btif_reg_sync_writel(v, a) mt_reg_sync_writel(v, a) -+#else -+/*byte write <1 byte> */ -+#define btif_reg_sync_writeb(v, a) mt65xx_reg_sync_writeb(v, a) -+/*word write <2 byte> */ -+#define btif_reg_sync_writew(v, a) mt65xx_reg_sync_writew(v, a) -+/*long write <4 byte> */ -+#define btif_reg_sync_writel(v, a) mt65xx_reg_sync_writel(v, a) -+#endif -+#define BTIF_READ8(REG) __raw_readb((unsigned char *)(REG)) -+#define BTIF_READ16(REG) __raw_readw((unsigned short *)(REG)) -+#define BTIF_READ32(REG) __raw_readl((unsigned int *)(REG)) -+ -+#define BTIF_SET_BIT(REG, BITVAL) do { \ -+*((volatile unsigned int *)(REG)) |= ((unsigned int)(BITVAL)); \ -+mb(); /**/ \ -+} \ -+while (0) -+#define BTIF_CLR_BIT(REG, BITVAL) do { \ -+(*(volatile unsigned int *)(REG)) &= ~((unsigned int)(BITVAL)); \ -+mb(); /**/\ -+} \ -+while (0) -+ -+/***********end of register operation *********/ -+ -+#endif /*__HAL_PUB_H_*/ -diff --git a/drivers/misc/mediatek/connectivity/Kconfig b/drivers/misc/mediatek/connectivity/Kconfig -new file mode 100644 -index 000000000000..aa4c3e6f71c9 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/Kconfig -@@ -0,0 +1,298 @@ -+config MTK_COMBO -+ tristate "MediaTek Connectivity Combo Chip Support" -+ help -+ MTK connectivity combo chip driver for MT66xx -+ -+# -+# MTK Combo Chip Selection -+# -+ -+choice -+ prompt "Select Chip" -+ depends on MTK_COMBO -+ -+config MTK_COMBO_CHIP_MT6620 -+ bool "MT6620" -+ help -+ this config is used to decided combo chip version -+ in current platform -+ is -+ MT6620 -+ -+config MTK_COMBO_CHIP_MT6628 -+ bool "MT6628" -+ help -+ this config is used to decided combo chip version -+ in current platform -+ is -+ MT6628 -+ -+config MTK_COMBO_CHIP_MT6630 -+ bool "MT6630" -+ help -+ this config is used to decided combo chip version -+ in current platform -+ is -+ MT6630 -+ -+config MTK_COMBO_CHIP_CONSYS_6572 -+ bool "CONSYS_6572" -+ help -+ this config is used to decided SOC consys version -+ in current platform -+ is -+ MT6572 -+ -+config MTK_COMBO_CHIP_CONSYS_6582 -+ bool "CONSYS_6582" -+ help -+ this config is used to decided SOC consys version -+ in current platform -+ is -+ MT6582 -+ -+config MTK_COMBO_CHIP_CONSYS_8127 -+ bool "CONSYS_8127" -+ help -+ this config is used to decided SOC consys version -+ in current platform -+ is -+ MT6572 -+ -+config MTK_COMBO_CHIP_CONSYS_7623 -+ bool "CONSYS_7623" -+ help -+ this config is used to decide SOC consys version -+ in current platform is MT7623 and prepare proper -+ system services like radio power on/off and firmware -+ download for the Bluetotoh and Wifi. -+ -+ -+config MTK_COMBO_CHIP_CONSYS_6752 -+ bool "CONSYS_6752" -+ help -+ this config is used to decided SOC consys version -+ in current platform -+ is -+ MT6752 -+ -+config MTK_COMBO_CHIP_CONSYS_6592 -+ bool "CONSYS_6592" -+ help -+ this config is used to decided SOC consys version -+ in current platform -+ is -+ MT6592 -+ -+config MTK_COMBO_CHIP_CONSYS_8163 -+ bool "CONSYS_8163" -+ help -+ this config is used to decided SOC consys version -+ in current platform -+ is -+ MT8163 -+ -+config MTK_COMBO_CHIP_CONSYS_6735 -+ bool "CONSYS_6735" -+ help -+ this config is used to decided SOC consys version -+ in current platform -+ is -+ MT6735 -+ -+config MTK_COMBO_CHIP_CONSYS_6755 -+ bool "CONSYS_6755" -+ help -+ this config is used to decided SOC consys version -+ in current platform -+ is -+ MT6755 -+ -+config MTK_COMBO_CHIP_CONSYS_6580 -+ bool "CONSYS_6580" -+ help -+ this config is used to decided SOC consys version -+ in current platform -+ is -+ MT6580 -+ -+config MTK_COMBO_CHIP_CONSYS_6797 -+ bool "CONSYS_6797" -+ help -+ this config is used to decided SOC consys version -+ in current platform -+ is -+ MT6797 -+endchoice -+ -+config MTK_COMBO_CHIP -+ string -+ default "MT6620" if MTK_COMBO_CHIP_MT6620 -+ default "MT6628" if MTK_COMBO_CHIP_MT6628 -+ default "MT6630" if MTK_COMBO_CHIP_MT6630 -+ default "CONSYS_6572" if MTK_COMBO_CHIP_CONSYS_6572 -+ default "CONSYS_6582" if MTK_COMBO_CHIP_CONSYS_6582 -+ default "CONSYS_8127" if MTK_COMBO_CHIP_CONSYS_8127 -+ default "CONSYS_7623" if MTK_COMBO_CHIP_CONSYS_7623 -+ default "CONSYS_6752" if MTK_COMBO_CHIP_CONSYS_6752 -+ default "CONSYS_6755" if MTK_COMBO_CHIP_CONSYS_6755 -+ default "CONSYS_6592" if MTK_COMBO_CHIP_CONSYS_6592 -+ default "CONSYS_8163" if MTK_COMBO_CHIP_CONSYS_8163 -+ default "CONSYS_6735" if MTK_COMBO_CHIP_CONSYS_6735 -+ default "CONSYS_6580" if MTK_COMBO_CHIP_CONSYS_6580 -+ default "CONSYS_6797" if MTK_COMBO_CHIP_CONSYS_6797 -+ help -+ this feature is used to identify combo chip version or SOC chip -+ consys version. -+ -+# -+# Target Platform Selection -+# -+config MTK_COMBO_PLAT_PATH -+ string "Platform folder name" -+ depends on MTK_COMBO -+ default "sample" if MTK_COMBO_PLAT_SAMPLE -+ help -+ Specify platform folder under common driver platform folder: -+ mtk_wcn_combo/common/platform/* -+ -+# -+# MTK COMBO Chip Configuration -+# -+config MTK_COMBO_COMM -+ depends on MTK_COMBO -+ tristate "MediaTek Combo Chip Common part driver" -+ help -+ MediaTek combo chip common part driver -+ -+#config MTK_COMBO_COMM_PS -+# depends on MTK_COMBO_COMM -+# bool "Enable PS support" -+# default n -+# help -+# Enable PS support of common UART interface -+ -+config MTK_COMBO_COMM_UART -+ depends on MTK_COMBO_COMM -+ tristate "Common interface UART" -+ help -+ Use UART for common part interface type -+ -+config MTK_COMBO_COMM_SDIO -+ depends on MTK_COMBO_COMM -+ tristate "Common interface SDIO" -+ help -+ Use SDIO for common part interface type -+ -+config MTK_COMBO_COMM_NPWR -+ depends on MTK_COMBO_COMM -+ bool "Enable NPWR support" -+ default n -+ help -+ Enable NPWR support of new power on swquence -+ -+config MTK_COMBO_COMM_APO -+ depends on MTK_COMBO_COMM -+ bool "Enable always power on support" -+ #default y -+ help -+ Enable chip will always power on -+ -+config MTK_COMBO_BT -+ tristate "MediaTek Combo Chip BT driver" -+ depends on MTK_COMBO -+ select MTK_BTIF -+ help -+ MTK BT /dev/stpbt driver for Bluedroid -+ -+config MTK_COMBO_BT_HCI -+ tristate "MediaTek Combo Chip BlueZ driver" -+ depends on BT && MTK_COMBO -+ select MTK_BTIF -+ help -+ MTK BT driver for BlueZ -+ -+config MTK_COMBO_WIFI -+ tristate "MediaTek combo chip Wi-Fi support" -+ depends on MTK_COMBO -+ select MTK_BTIF -+ select WIRELESS_EXT -+ select WEXT_PRIV -+ -+config MTK_WAPI_SUPPORT -+ bool "MTK_WAPI_SUPPORT" -+ depends on MTK_COMBO_WIFI -+ #default y -+ help -+ if it is set to TRUE: Support WAPI (WLAN Authentication and -+ Privacy Infrastructure) -+ -+config MTK_PASSPOINT_R1_SUPPORT -+ bool "MTK_PASSPOINT_R1_SUPPORT" -+ depends on MTK_COMBO_WIFI -+ help -+ Support Passpoint R1 (Hotspot 2.0 R1) -+ -+config MTK_PASSPOINT_R2_SUPPORT -+ bool "MTK_PASSPOINT_R2_SUPPORT" -+ depends on MTK_COMBO_WIFI -+ help -+ Support Passpoint R2 -+ -+config MTK_WIFI_MCC_SUPPORT -+ bool "MTK_WIFI_MCC_SUPPORT" -+ depends on MTK_COMBO_WIFI -+ #default y -+ help -+ if it is set to TRUE, wlan will support Multi-Channel Concurrency, -+ otherwise, only support Single Channel Concurrency -+ -+config MTK_DHCPV6C_WIFI -+ bool "MTK_DHCPV6C_WIFI" -+ help -+ no: disable this feature -+ -+config MTK_CONN_LTE_IDC_SUPPORT -+ bool "MediaTek CONN LTE IDC support" -+ select MTK_CONN_MD -+ #default y -+ help -+ This option enables CONN LTE IDC support -+ -+menuconfig GPS -+ tristate "GPS drivers" -+ #default y -+ ---help--- -+ Say Y here for supporting GPS. -+ -+if GPS -+config MTK_GPS -+ tristate "MediaTek GPS driver" -+ #default y -+ ---help--- -+ MTK GPS driver -+ To switch gps nmea port driver. -+ Set "yes" to turn on. -+ Set "no" to turn off. -+endif # GPS -+ -+config MTK_GPS_SUPPORT -+ tristate "MediaTek GPS driver" -+ select MTK_GPS -+ help -+ to switch GPS feature on the platform. -+ Set "yes" to turn on and set "no" -+ (with MTK_AGPS_APP=no at the same time) -+ to turn off. -+ -+config MTK_GPS_REGISTER_SETTING -+ tristate "MediaTek GPS Register Setting" -+ depends on MTK_COMBO_GPS -+ help -+ GPS register settings. -+ -+config MTK_GPS_EMI -+ tristate "MediaTek GPS EMI Driver" -+ depends on MTK_COMBO_GPS -+ help -+ GPS EMI driver is for MNL OFFLOAD feature. -diff --git a/drivers/misc/mediatek/connectivity/Makefile b/drivers/misc/mediatek/connectivity/Makefile -new file mode 100644 -index 000000000000..0947788d189a ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/Makefile -@@ -0,0 +1,41 @@ -+# -+# Copyright (C) 2015 MediaTek Inc. -+# -+# 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. -+# -+# This program is distributed in the hope that it will be useful, -+# but WITHOUT ANY WARRANTY; without even the implied warranty of -+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+# GNU General Public License for more details. -+# -+ -+# Connectivity combo driver -+# If KERNELRELEASE is defined, we've been invoked from the -+# kernel build system and can use its language. -+ifneq ($(KERNELRELEASE),) -+subdir-ccflags-y += -D MTK_WCN_REMOVE_KERNEL_MODULE -+ifeq ($(CONFIG_ARM64), y) -+subdir-ccflags-y += -D CONFIG_MTK_WCN_ARM64 -+endif -+ -+ifeq ($(CONFIG_MTK_CONN_LTE_IDC_SUPPORT),y) -+ subdir-ccflags-y += -D WMT_IDC_SUPPORT=1 -+else -+ subdir-ccflags-y += -D WMT_IDC_SUPPORT=0 -+endif -+ subdir-ccflags-y += -D MTK_WCN_WMT_STP_EXP_SYMBOL_ABSTRACT -+ -+ obj-y += common/ -+ obj-$(CONFIG_MTK_COMBO_WIFI) += wlan/ -+ obj-n := dummy.o -+ -+# Otherwise we were called directly from the command line; -+# invoke the kernel build system. -+else -+ KERNELDIR ?= /lib/modules/$(shell uname -r)/build -+ PWD := $(shell pwd) -+default: -+ $(MAKE) -C $(KERNELDIR) M=$(PWD) modules -+endif -diff --git a/drivers/misc/mediatek/connectivity/common/Makefile b/drivers/misc/mediatek/connectivity/common/Makefile -new file mode 100644 -index 000000000000..622b74430e13 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/Makefile -@@ -0,0 +1,23 @@ -+subdir-ccflags-y += -Werror -I$(srctree)/drivers/misc/mediatek/include/mt-plat/$(MTK_PLATFORM)/include -+subdir-ccflags-y += -Werror -I$(srctree)/drivers/misc/mediatek/include/mt-plat -+ -+#ifneq ($(filter "MT6620E3",$(CONFIG_MTK_COMBO_CHIP)),) -+# obj-y += combo/ -+#endif -+#ifneq ($(filter "MT6628",$(CONFIG_MTK_COMBO_CHIP)),) -+# subdir-ccflags-y += -D MT6628 -+# subdir-ccflags-y += -D MERGE_INTERFACE_SUPPORT -+# obj-y += combo/ -+#endif -+#ifneq ($(filter "MT6630",$(CONFIG_MTK_COMBO_CHIP)),) -+# subdir-ccflags-y += -D MT6630 -+#ifneq ($(CONFIG_ARCH_MT2601),y) -+# subdir-ccflags-y += -D MERGE_INTERFACE_SUPPORT -+#endif -+# obj-y += combo/ -+#endif -+ifneq ($(filter "CONSYS_%",$(CONFIG_MTK_COMBO_CHIP)),) -+ obj-y += conn_soc/ -+endif -+ -+obj-y += common_detect/ -diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/Makefile b/drivers/misc/mediatek/connectivity/common/common_detect/Makefile -new file mode 100644 -index 000000000000..8d7dc690affd ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/common_detect/Makefile -@@ -0,0 +1,47 @@ -+subdir-ccflags-y += -I$(srctree)/arch/arm/mach-$(MTK_PLATFORM)/$(ARCH_MTK_PROJECT)/dct/dct -+subdir-ccflags-y += -DWMT_PLAT_ALPS=1 -+ -+COMBO_CHIP_SUPPORT := false -+ifneq ($(filter "MT6620E3",$(CONFIG_MTK_COMBO_CHIP)),) -+ COMBO_CHIP_SUPPORT := true -+endif -+ifneq ($(filter "MT6628",$(CONFIG_MTK_COMBO_CHIP)),) -+ COMBO_CHIP_SUPPORT := true -+endif -+ifneq ($(filter "MT6630",$(CONFIG_MTK_COMBO_CHIP)),) -+ COMBO_CHIP_SUPPORT := true -+endif -+ifeq ($(COMBO_CHIP_SUPPORT), true) -+ subdir-ccflags-y += -D MTK_WCN_COMBO_CHIP_SUPPORT -+ ccflags-y += -I$(src)/../combo/linux/include -+endif -+ -+ifneq ($(filter "CONSYS_%",$(CONFIG_MTK_COMBO_CHIP)),) -+ subdir-ccflags-y += -D MTK_WCN_SOC_CHIP_SUPPORT -+ ccflags-y += -I$(src)/../conn_soc/linux/include -+endif -+ -+ -+ifeq ($(CONFIG_MTK_COMBO),y) -+ ccflags-y += -I$(src)/drv_init/inc -+ obj-y += mtk_wcn_stub_alps.o -+ obj-y += wmt_stp_exp.o -+ obj-y += wmt_gpio.o -+ -+ obj-y += wmt_detect.o -+ obj-y += sdio_detect.o -+ obj-y += wmt_detect_pwr.o -+ -+ obj-y += drv_init/ -+endif -+ -+ifeq ($(CONFIG_MTK_COMBO),m) -+ obj-y += mtk_wcn_stub_alps.o -+ obj-y += wmt_stp_exp.o -+ obj-y += wmt_gpio.o -+ -+ obj-$(CONFIG_MTK_COMBO) += mtk_wmt_detect.o -+ mtk_wmt_detect-objs := wmt_detect.o -+ mtk_wmt_detect-objs += sdio_detect.o -+ mtk_wmt_detect-objs += wmt_detect_pwr.o -+endif -diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/Makefile b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/Makefile -new file mode 100644 -index 000000000000..bb84384b9a24 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/Makefile -@@ -0,0 +1,22 @@ -+ifeq ($(CONFIG_MTK_COMBO),y) -+ ccflags-y += -I$(src)/inc/ -+ ccflags-y += -I$(src)/../ -+ -+ifneq ($(filter "MT6630",$(CONFIG_MTK_COMBO_CHIP)),) -+ ccflags-y += -D MTK_WCN_WLAN_GEN3 -+endif -+ifneq ($(filter "CONSYS_6797",$(CONFIG_MTK_COMBO_CHIP)),) -+ ccflags-y += -D MTK_WCN_WLAN_GEN3 -+else ifneq ($(filter "CONSYS_%",$(CONFIG_MTK_COMBO_CHIP)),) -+ ccflags-y += -D MTK_WCN_WLAN_GEN2 -+endif -+ -+ obj-y += conn_drv_init.o -+ obj-y += common_drv_init.o -+ obj-y += bluetooth_drv_init.o -+ obj-y += gps_drv_init.o -+ obj-y += fm_drv_init.o -+ obj-y += wlan_drv_init.o -+ obj-($(CONFIG_MTK_COMBO_ANT)) += ant_drv_init.o -+ -+endif -diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/ant_drv_init.c b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/ant_drv_init.c -new file mode 100644 -index 000000000000..aa453f9397a4 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/ant_drv_init.c -@@ -0,0 +1,38 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -+ -+#ifdef DFT_TAG -+#undef DFT_TAG -+#endif -+#define DFT_TAG "[ANT-MOD-INIT]" -+ -+#include "wmt_detect.h" -+#include "ant_drv_init.h" -+ -+int do_ant_drv_init(int chip_id) -+{ -+ int i_ret = -1; -+ -+ WMT_DETECT_INFO_FUNC("start to do ANT driver init\n"); -+ switch (chip_id) { -+ case 0x6630: -+ case 0x6797: -+ i_ret = mtk_wcn_stpant_drv_init(); -+ WMT_DETECT_INFO_FUNC("finish ANT driver init, i_ret:%d\n", i_ret); -+ break; -+ default: -+ WMT_DETECT_ERR_FUNC("chipid is not 6630,ANT is not supported!\n"); -+ } -+ return i_ret; -+} -diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/bluetooth_drv_init.c b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/bluetooth_drv_init.c -new file mode 100644 -index 000000000000..47b055433443 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/bluetooth_drv_init.c -@@ -0,0 +1,35 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -+ -+#ifdef DFT_TAG -+#undef DFT_TAG -+#endif -+#define DFT_TAG "[BT-MOD-INIT]" -+ -+#include "wmt_detect.h" -+#include "bluetooth_drv_init.h" -+ -+int do_bluetooth_drv_init(int chip_id) -+{ -+ int i_ret = -1; -+ -+#if defined(CONFIG_MTK_COMBO_BT) || defined(CONFIG_MTK_COMBO_BT_HCI) -+ WMT_DETECT_INFO_FUNC("start to do bluetooth driver init\n"); -+ i_ret = mtk_wcn_stpbt_drv_init(); -+ WMT_DETECT_INFO_FUNC("finish bluetooth driver init, i_ret:%d\n", i_ret); -+#else -+ WMT_DETECT_INFO_FUNC("CONFIG_MTK_COMBO_BT is not defined\n"); -+#endif -+ return i_ret; -+} -diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/common_drv_init.c b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/common_drv_init.c -new file mode 100644 -index 000000000000..f9c332ea266b ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/common_drv_init.c -@@ -0,0 +1,103 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -+ -+#ifdef DFT_TAG -+#undef DFT_TAG -+#endif -+#define DFT_TAG "[WMT-MOD-INIT]" -+ -+#include "wmt_detect.h" -+#include "common_drv_init.h" -+ -+static int do_combo_common_drv_init(int chip_id) -+{ -+ int i_ret = 0; -+ -+#ifdef MTK_WCN_COMBO_CHIP_SUPPORT -+ int i_ret_tmp = 0; -+ -+ WMT_DETECT_DBG_FUNC("start to do combo driver init, chipid:0x%08x\n", chip_id); -+ -+ /* HIF-SDIO driver init */ -+ i_ret_tmp = mtk_wcn_hif_sdio_drv_init(); -+ i_ret += i_ret_tmp; -+ WMT_DETECT_DBG_FUNC("HIF-SDIO driver init, i_ret:%d\n", i_ret); -+ -+ /* WMT driver init */ -+ i_ret_tmp = mtk_wcn_combo_common_drv_init(); -+ i_ret += i_ret_tmp; -+ WMT_DETECT_DBG_FUNC("COMBO COMMON driver init, i_ret:%d\n", i_ret); -+ -+ /* STP-UART driver init */ -+ i_ret_tmp = mtk_wcn_stp_uart_drv_init(); -+ i_ret += i_ret_tmp; -+ WMT_DETECT_DBG_FUNC("STP-UART driver init, i_ret:%d\n", i_ret); -+ -+ /* STP-SDIO driver init */ -+ i_ret_tmp = mtk_wcn_stp_sdio_drv_init(); -+ i_ret += i_ret_tmp; -+ WMT_DETECT_DBG_FUNC("STP-SDIO driver init, i_ret:%d\n", i_ret); -+ -+#else -+ i_ret = -1; -+ WMT_DETECT_ERR_FUNC("COMBO chip is not supported, please check CONFIG_MTK_COMBO_CHIP in kernel config\n"); -+#endif -+ WMT_DETECT_DBG_FUNC("finish combo driver init\n"); -+ return i_ret; -+} -+ -+static int do_soc_common_drv_init(int chip_id) -+{ -+ int i_ret = 0; -+ -+#ifdef MTK_WCN_SOC_CHIP_SUPPORT -+ int i_ret_tmp = 0; -+ -+ WMT_DETECT_DBG_FUNC("start to do soc common driver init, chipid:0x%08x\n", chip_id); -+ -+ /* WMT driver init */ -+ i_ret_tmp = mtk_wcn_soc_common_drv_init(); -+ i_ret += i_ret_tmp; -+ WMT_DETECT_DBG_FUNC("COMBO COMMON driver init, i_ret:%d\n", i_ret); -+ -+#else -+ i_ret = -1; -+ WMT_DETECT_ERR_FUNC("SOC chip is not supported, please check CONFIG_MTK_COMBO_CHIP in kernel config\n"); -+#endif -+ -+ WMT_DETECT_DBG_FUNC("TBD........\n"); -+ return i_ret; -+} -+ -+int do_common_drv_init(int chip_id) -+{ -+ int i_ret = 0; -+ -+ WMT_DETECT_INFO_FUNC("start to do common driver init, chipid:0x%08x\n", chip_id); -+ -+ switch (chip_id) { -+ case 0x6620: -+ case 0x6628: -+ case 0x6630: -+ i_ret = do_combo_common_drv_init(chip_id); -+ break; -+ default: -+ i_ret = do_soc_common_drv_init(chip_id); -+ break; -+ } -+ -+ WMT_DETECT_INFO_FUNC("finish common driver init\n"); -+ -+ return i_ret; -+} -diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/conn_drv_init.c b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/conn_drv_init.c -new file mode 100644 -index 000000000000..8112d2a1d95e ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/conn_drv_init.c -@@ -0,0 +1,80 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -+ -+#ifdef DFT_TAG -+#undef DFT_TAG -+#endif -+#define DFT_TAG "[WCN-MOD-INIT]" -+ -+#include "wmt_detect.h" -+#include "conn_drv_init.h" -+#include "common_drv_init.h" -+#include "fm_drv_init.h" -+#include "wlan_drv_init.h" -+#include "bluetooth_drv_init.h" -+#include "gps_drv_init.h" -+#include "ant_drv_init.h" -+ -+int __weak do_wlan_drv_init(int chip_id) -+{ -+ WMT_DETECT_ERR_FUNC("Can not find wlan module for chip: %d !\n", chip_id); -+ return 0; -+} -+ -+int __weak do_ant_drv_init(int chip_id) -+{ -+ WMT_DETECT_DBG_FUNC("Chip: %d can not support ANT !\n", chip_id); -+ return 0; -+} -+ -+int do_connectivity_driver_init(int chip_id) -+{ -+ int i_ret = 0; -+ int tmp_ret = 0; -+ -+ tmp_ret = do_common_drv_init(chip_id); -+ i_ret += tmp_ret; -+ if (tmp_ret) { -+ WMT_DETECT_ERR_FUNC("do common driver init failed, ret:%d\n", tmp_ret); -+ WMT_DETECT_ERR_FUNC("abort connectivity driver init, because common part is not ready\n"); -+ return i_ret; -+ } -+ -+ tmp_ret = do_bluetooth_drv_init(chip_id); -+ i_ret += tmp_ret; -+ if (tmp_ret) -+ WMT_DETECT_ERR_FUNC("do common driver init failed, ret:%d\n", tmp_ret); -+ -+ tmp_ret = do_gps_drv_init(chip_id); -+ i_ret += tmp_ret; -+ if (tmp_ret) -+ WMT_DETECT_ERR_FUNC("do common driver init failed, ret:%d\n", tmp_ret); -+ -+ tmp_ret = do_fm_drv_init(chip_id); -+ i_ret += tmp_ret; -+ if (tmp_ret) -+ WMT_DETECT_ERR_FUNC("do fm module init failed, ret:%d\n", tmp_ret); -+ -+ tmp_ret = do_wlan_drv_init(chip_id); -+ i_ret += tmp_ret; -+ if (tmp_ret) -+ WMT_DETECT_ERR_FUNC("do wlan module init failed, ret:%d\n", tmp_ret); -+ -+ tmp_ret = do_ant_drv_init(chip_id); -+ i_ret += tmp_ret; -+ if (tmp_ret) -+ WMT_DETECT_ERR_FUNC("do ANT module init failed, ret:%d\n", tmp_ret); -+ -+ return i_ret; -+} -diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/fm_drv_init.c b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/fm_drv_init.c -new file mode 100644 -index 000000000000..069c1cf13bba ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/fm_drv_init.c -@@ -0,0 +1,33 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -+ -+#ifdef DFT_TAG -+#undef DFT_TAG -+#endif -+#define DFT_TAG "[FM-MOD-INIT]" -+ -+#include "wmt_detect.h" -+#include "fm_drv_init.h" -+ -+int do_fm_drv_init(int chip_id) -+{ -+ WMT_DETECT_INFO_FUNC("start to do fm module init\n"); -+ -+#ifdef CONFIG_MTK_FMRADIO -+ mtk_wcn_fm_init(); -+#endif -+ -+ WMT_DETECT_INFO_FUNC("finish fm module init\n"); -+ return 0; -+} -diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/gps_drv_init.c b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/gps_drv_init.c -new file mode 100644 -index 000000000000..6da1d70a3ca6 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/gps_drv_init.c -@@ -0,0 +1,35 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -+ -+#ifdef DFT_TAG -+#undef DFT_TAG -+#endif -+#define DFT_TAG "[GPS-MOD-INIT]" -+ -+#include "wmt_detect.h" -+#include "gps_drv_init.h" -+ -+int do_gps_drv_init(int chip_id) -+{ -+ int i_ret = -1; -+#ifdef CONFIG_MTK_COMBO_GPS -+ WMT_DETECT_INFO_FUNC("start to do gps driver init\n"); -+ i_ret = mtk_wcn_stpgps_drv_init(); -+ WMT_DETECT_INFO_FUNC("finish gps driver init, i_ret:%d\n", i_ret); -+#else -+ WMT_DETECT_INFO_FUNC("CONFIG_MTK_COMBO_GPS is not defined\n"); -+#endif -+ return i_ret; -+ -+} -diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/ant_drv_init.h b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/ant_drv_init.h -new file mode 100644 -index 000000000000..4a436a236290 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/ant_drv_init.h -@@ -0,0 +1,20 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -+ -+#ifndef _ANT_DRIVER_INIT_H_ -+#define _ANT_DRIVER_INIT_H_ -+ -+extern int do_ant_drv_init(int chip_id); -+extern int mtk_wcn_stpant_drv_init(void); -+#endif -diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/bluetooth_drv_init.h b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/bluetooth_drv_init.h -new file mode 100644 -index 000000000000..8a847d361fc8 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/bluetooth_drv_init.h -@@ -0,0 +1,20 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -+ -+#ifndef _BLUETOOTH_DRIVER_INIT_H_ -+#define _BLUETOOTH_DRIVER_INIT_H_ -+ -+extern int do_bluetooth_drv_init(int chip_id); -+extern int mtk_wcn_stpbt_drv_init(void); -+#endif -diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/common_drv_init.h b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/common_drv_init.h -new file mode 100644 -index 000000000000..ea01bd633c3c ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/common_drv_init.h -@@ -0,0 +1,31 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -+ -+#ifndef _COMMON_DRV_INIT_H_ -+#define _COMMON_DRV_INIT_H_ -+extern int do_common_drv_init(int chip_id); -+ -+/*defined in common part driver*/ -+#ifdef MTK_WCN_COMBO_CHIP_SUPPORT -+extern int mtk_wcn_combo_common_drv_init(void); -+extern int mtk_wcn_hif_sdio_drv_init(void); -+extern int mtk_wcn_stp_uart_drv_init(void); -+extern int mtk_wcn_stp_sdio_drv_init(void); -+#endif -+ -+#ifdef MTK_WCN_SOC_CHIP_SUPPORT -+extern int mtk_wcn_soc_common_drv_init(void); -+#endif -+ -+#endif -diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/conn_drv_init.h b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/conn_drv_init.h -new file mode 100644 -index 000000000000..971193eade9e ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/conn_drv_init.h -@@ -0,0 +1,18 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -+ -+#ifndef _CONNECTIVITY_DRV_INIT_H_ -+#define _CONNECTIVITY_DRV_INIT_H_ -+extern int do_connectivity_driver_init(int chip_id); -+#endif -diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/fm_drv_init.h b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/fm_drv_init.h -new file mode 100644 -index 000000000000..f6ea30addc5d ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/fm_drv_init.h -@@ -0,0 +1,20 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -+ -+#ifndef _FM_DRV_INIT_H_ -+#define _FM_DRV_INIT_H_ -+extern int do_fm_drv_init(int chip_id); -+extern int mtk_wcn_fm_init(void); -+extern void mtk_wcn_fm_exit(void); -+#endif -diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/gps_drv_init.h b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/gps_drv_init.h -new file mode 100644 -index 000000000000..006ce072c53b ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/gps_drv_init.h -@@ -0,0 +1,19 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -+ -+#ifndef _GPS_DRIVER_INIT_H_ -+#define _GPS_DRIVER_INIT_H_ -+extern int do_gps_drv_init(int chip_id); -+extern int mtk_wcn_stpgps_drv_init(void); -+#endif -diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/wlan_drv_init.h b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/wlan_drv_init.h -new file mode 100644 -index 000000000000..cb71b50bf950 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/wlan_drv_init.h -@@ -0,0 +1,30 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -+ -+#ifndef _WLAN_DRV_INIT_H_ -+#define _WLAN_DRV_INIT_H_ -+ -+ -+extern int do_wlan_drv_init(int chip_id); -+ -+extern int mtk_wcn_wmt_wifi_init(void); -+ -+#ifdef MTK_WCN_WLAN_GEN2 -+extern int mtk_wcn_wlan_gen2_init(void); -+#endif -+#ifdef MTK_WCN_WLAN_GEN3 -+extern int mtk_wcn_wlan_gen3_init(void); -+#endif -+ -+#endif -diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/wlan_drv_init.c b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/wlan_drv_init.c -new file mode 100644 -index 000000000000..5b0d039a4a42 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/wlan_drv_init.c -@@ -0,0 +1,74 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -+ -+#ifdef DFT_TAG -+#undef DFT_TAG -+#endif -+#define DFT_TAG "[WLAN-MOD-INIT]" -+ -+#include "wmt_detect.h" -+#include "wlan_drv_init.h" -+ -+ -+int do_wlan_drv_init(int chip_id) -+{ -+ int i_ret = 0; -+ -+#ifdef CONFIG_MTK_COMBO_WIFI -+ int ret = 0; -+ -+ WMT_DETECT_INFO_FUNC("start to do wlan module init 0x%x\n", chip_id); -+ -+ /* WMT-WIFI char dev init */ -+ ret = mtk_wcn_wmt_wifi_init(); -+ WMT_DETECT_INFO_FUNC("WMT-WIFI char dev init, ret:%d\n", ret); -+ i_ret += ret; -+ -+ switch (chip_id) { -+ case 0x6630: -+ case 0x6797: -+#ifdef MTK_WCN_WLAN_GEN3 -+ /* WLAN driver init */ -+ ret = mtk_wcn_wlan_gen3_init(); -+ WMT_DETECT_INFO_FUNC("WLAN-GEN3 driver init, ret:%d\n", ret); -+ i_ret += ret; -+#else -+ WMT_DETECT_ERR_FUNC("WLAN-GEN3 driver is not supported, please check CONFIG_MTK_COMBO_CHIP\n"); -+ i_ret = -1; -+#endif -+ break; -+ -+ default: -+#ifdef MTK_WCN_WLAN_GEN2 -+ /* WLAN driver init */ -+ ret = mtk_wcn_wlan_gen2_init(); -+ WMT_DETECT_INFO_FUNC("WLAN-GEN2 driver init, ret:%d\n", ret); -+ i_ret += ret; -+#else -+ WMT_DETECT_ERR_FUNC("WLAN-GEN2 driver is not supported, please check CONFIG_MTK_COMBO_CHIP\n"); -+ i_ret = -1; -+#endif -+ break; -+ } -+ -+ WMT_DETECT_INFO_FUNC("finish wlan module init\n"); -+ -+#else -+ -+ WMT_DETECT_INFO_FUNC("CONFIG_MTK_COMBO_WIFI is not defined\n"); -+ -+#endif -+ -+ return i_ret; -+} -diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/mtk_wcn_stub_alps.c b/drivers/misc/mediatek/connectivity/common/common_detect/mtk_wcn_stub_alps.c -new file mode 100644 -index 000000000000..fa8d437686f2 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/common_detect/mtk_wcn_stub_alps.c -@@ -0,0 +1,605 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -+ -+/*! \file -+ \brief Declaration of library functions -+ -+ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+#define CMB_STUB_DBG_LOG 3 -+#define CMB_STUB_INFO_LOG 2 -+#define CMB_STUB_WARN_LOG 1 -+ -+int gCmbStubLogLevel = CMB_STUB_INFO_LOG; -+ -+#define CMB_STUB_LOG_INFO(fmt, arg...) \ -+do { \ -+ if (gCmbStubLogLevel >= CMB_STUB_INFO_LOG) \ -+ pr_warn(fmt, ##arg); \ -+} while (0) -+#define CMB_STUB_LOG_WARN(fmt, arg...) \ -+do { \ -+ if (gCmbStubLogLevel >= CMB_STUB_WARN_LOG) \ -+ pr_warn(fmt, ##arg); \ -+} while (0) -+#define CMB_STUB_LOG_DBG(fmt, arg...) \ -+do { \ -+ if (gCmbStubLogLevel >= CMB_STUB_DBG_LOG) \ -+ pr_debug(fmt, ##arg); \ -+} while (0) -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include "wmt_detect.h" -+ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+#ifndef MTK_WCN_CMB_FOR_SDIO_1V_AUTOK -+#define MTK_WCN_CMB_FOR_SDIO_1V_AUTOK 0 -+#endif -+ -+#if MTK_WCN_CMB_FOR_SDIO_1V_AUTOK -+struct work_struct *g_sdio_1v_autok_wk = NULL; -+#endif -+int gConnectivityChipId = -1; -+ -+#ifdef MTK_WCN_COMBO_CHIP_SUPPORT -+/* -+* current used uart port name, default is "ttyMT2", -+* will be changed when wmt driver init -+*/ -+char *wmt_uart_port_desc = "ttyMT2"; -+EXPORT_SYMBOL(wmt_uart_port_desc); -+#endif -+ -+static void mtk_wcn_cmb_sdio_request_eirq(msdc_sdio_irq_handler_t irq_handler, void *data); -+static void mtk_wcn_cmb_sdio_enable_eirq(void); -+static void mtk_wcn_cmb_sdio_disable_eirq(void); -+static void mtk_wcn_cmb_sdio_register_pm(pm_callback_t pm_cb, void *data); -+ -+struct sdio_ops mt_sdio_ops[4] = { -+ {NULL, NULL, NULL, NULL}, -+ {NULL, NULL, NULL, NULL}, -+ {mtk_wcn_cmb_sdio_request_eirq, mtk_wcn_cmb_sdio_enable_eirq, -+ mtk_wcn_cmb_sdio_disable_eirq, mtk_wcn_cmb_sdio_register_pm}, -+ {mtk_wcn_cmb_sdio_request_eirq, mtk_wcn_cmb_sdio_enable_eirq, -+ mtk_wcn_cmb_sdio_disable_eirq, mtk_wcn_cmb_sdio_register_pm} -+}; -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+static wmt_aif_ctrl_cb cmb_stub_aif_ctrl_cb; -+static wmt_func_ctrl_cb cmb_stub_func_ctrl_cb; -+static wmt_thermal_query_cb cmb_stub_thermal_ctrl_cb; -+static CMB_STUB_AIF_X cmb_stub_aif_stat = CMB_STUB_AIF_0; -+static wmt_deep_idle_ctrl_cb cmb_stub_deep_idle_ctrl_cb; -+#if MTK_WCN_CMB_FOR_SDIO_1V_AUTOK -+static wmt_get_drv_status cmb_stub_drv_status_ctrl_cb; -+#endif -+static wmt_func_do_reset cmb_stub_do_reset_cb; -+/* A temp translation table between COMBO_AUDIO_STATE_X and CMB_STUB_AIF_X. -+ * This is used for ALPS backward compatible ONLY!!! Remove this table, related -+ * functions, and type definition after modifying other kernel built-in modules, -+ * such as AUDIO. [FixMe][GeorgeKuo] -+ */ -+#if 0 -+static CMB_STUB_AIF_X audio2aif[] = { -+ [COMBO_AUDIO_STATE_0] = CMB_STUB_AIF_0, -+ [COMBO_AUDIO_STATE_1] = CMB_STUB_AIF_1, -+ [COMBO_AUDIO_STATE_2] = CMB_STUB_AIF_2, -+ [COMBO_AUDIO_STATE_3] = CMB_STUB_AIF_3, -+}; -+#endif -+static msdc_sdio_irq_handler_t mtk_wcn_cmb_sdio_eirq_handler; -+static atomic_t sdio_claim_irq_enable_flag; -+static atomic_t irq_enable_flag; -+static pm_callback_t mtk_wcn_cmb_sdio_pm_cb; -+static void *mtk_wcn_cmb_sdio_pm_data; -+static void *mtk_wcn_cmb_sdio_eirq_data; -+ -+static u32 wifi_irq = 0xffffffff; -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+#if MTK_WCN_CMB_FOR_SDIO_1V_AUTOK -+static void mtk_wcn_cmb_stub_1v_autok_work(struct work_struct *work) -+{ -+ CMB_STUB_LOG_WARN("++enter++\n"); -+ mtk_wcn_cmb_stub_func_ctrl(11, 1); -+ mtk_wcn_cmb_stub_func_ctrl(11, 0); -+ CMB_STUB_LOG_WARN("--exit--\n"); -+} -+ -+/*! -+ * \brief A function for Getting current driver status:on/off -+ * -+ * \param driver type:0/bt,1/fm,2/gps,3/wifi,11/autok->run wmt turn on/off wifi flow -+ * -+ * \retval 0/off,2/on,-1/null pointer -+ */ -+static int mtk_wcn_cmb_stub_drv_status(unsigned int type) -+{ -+ int ret = -1; -+ -+ if (cmb_stub_drv_status_ctrl_cb) -+ ret = (*cmb_stub_drv_status_ctrl_cb) (type); -+ else -+ CMB_STUB_LOG_WARN("cmb_stub_drv_status_ctrl_cb is NULL\n"); -+ return ret; -+} -+ -+/*! -+ * \brief A 1v AutoK function for kernel DVFS driver calling when screen off -+ * -+ * \param void -+ * -+ * \retval int,mt6630 state:0/off,1/power on,2/func on, -1/null -+ */ -+int mtk_wcn_cmb_stub_1vautok_for_dvfs(void) -+{ -+ int wmt_status; -+ -+ CMB_STUB_LOG_WARN("DVFS driver call sdio 1v autok\n"); -+ -+ wmt_status = mtk_wcn_cmb_stub_drv_status(4); -+ CMB_STUB_LOG_WARN("current mt6630 status is %d\n", wmt_status); -+ if (0 == wmt_status) { -+ if (g_sdio_1v_autok_wk) -+ schedule_work(g_sdio_1v_autok_wk); -+ else -+ CMB_STUB_LOG_WARN("g_sdio_1v_autok_wk is NULL\n"); -+ } else if ((2 == wmt_status) || (1 == wmt_status)) { -+ CMB_STUB_LOG_WARN("mt6630 is on state,skip AUTOK\n"); -+ } else { -+ CMB_STUB_LOG_WARN("mt6630 is unknown state(%d)\n", wmt_status); -+ } -+ -+ return wmt_status; -+ -+} -+#endif -+/*! -+ * \brief A registration function for WMT-PLAT to register itself to CMB-STUB. -+ * -+ * An MTK-WCN-CMB-STUB registration function provided to WMT-PLAT to register -+ * itself and related callback functions when driver being loaded into kernel. -+ * -+ * \param p_stub_cb a pointer carrying CMB_STUB_CB information -+ * -+ * \retval 0 operation success -+ * \retval -1 invalid parameters -+ */ -+int mtk_wcn_cmb_stub_reg(P_CMB_STUB_CB p_stub_cb) -+{ -+ if ((!p_stub_cb) -+ || (p_stub_cb->size != sizeof(CMB_STUB_CB))) { -+ CMB_STUB_LOG_WARN("[cmb_stub] invalid p_stub_cb:0x%p size(%d)\n", -+ p_stub_cb, (p_stub_cb) ? p_stub_cb->size : 0); -+ return -1; -+ } -+ -+ CMB_STUB_LOG_DBG("[cmb_stub] registered, p_stub_cb:0x%p size(%d)\n", p_stub_cb, p_stub_cb->size); -+ -+ cmb_stub_aif_ctrl_cb = p_stub_cb->aif_ctrl_cb; -+ cmb_stub_func_ctrl_cb = p_stub_cb->func_ctrl_cb; -+ cmb_stub_thermal_ctrl_cb = p_stub_cb->thermal_query_cb; -+ cmb_stub_deep_idle_ctrl_cb = p_stub_cb->deep_idle_ctrl_cb; -+ cmb_stub_do_reset_cb = p_stub_cb->wmt_do_reset_cb; -+#if MTK_WCN_CMB_FOR_SDIO_1V_AUTOK -+ cmb_stub_drv_status_ctrl_cb = p_stub_cb->get_drv_status_cb; -+ g_sdio_1v_autok_wk = vmalloc(sizeof(struct work_struct)); -+ if (!g_sdio_1v_autok_wk) -+ CMB_STUB_LOG_WARN("vmalloc work_struct(%zd) fail\n", sizeof(struct work_struct)); -+ else -+ INIT_WORK(g_sdio_1v_autok_wk, mtk_wcn_cmb_stub_1v_autok_work); -+ -+#endif -+ -+ return 0; -+} -+EXPORT_SYMBOL(mtk_wcn_cmb_stub_reg); -+/*! -+ * \brief A unregistration function for WMT-PLAT to unregister from CMB-STUB. -+ * -+ * An MTK-WCN-CMB-STUB unregistration function provided to WMT-PLAT to -+ * unregister itself and clear callback function references. -+ * -+ * \retval 0 operation success -+ */ -+int mtk_wcn_cmb_stub_unreg(void) -+{ -+ cmb_stub_aif_ctrl_cb = NULL; -+ cmb_stub_func_ctrl_cb = NULL; -+ cmb_stub_thermal_ctrl_cb = NULL; -+ cmb_stub_deep_idle_ctrl_cb = NULL; -+ cmb_stub_do_reset_cb = NULL; -+ CMB_STUB_LOG_INFO("[cmb_stub] unregistered\n"); /* KERN_DEBUG */ -+ -+#if MTK_WCN_CMB_FOR_SDIO_1V_AUTOK -+ if (g_sdio_1v_autok_wk) { -+ vfree(g_sdio_1v_autok_wk); -+ g_sdio_1v_autok_wk = NULL; -+ } -+#endif -+ -+ return 0; -+} -+EXPORT_SYMBOL(mtk_wcn_cmb_stub_unreg); -+ -+/* stub functions for kernel to control audio path pin mux */ -+int mtk_wcn_cmb_stub_aif_ctrl(CMB_STUB_AIF_X state, CMB_STUB_AIF_CTRL ctrl) -+{ -+ int ret; -+ -+ if ((CMB_STUB_AIF_MAX <= state) -+ || (CMB_STUB_AIF_CTRL_MAX <= ctrl)) { -+ -+ CMB_STUB_LOG_WARN("[cmb_stub] aif_ctrl invalid (%d, %d)\n", state, ctrl); -+ return -1; -+ } -+ -+ /* avoid the early interrupt before we register the eirq_handler */ -+ if (cmb_stub_aif_ctrl_cb) { -+ ret = (*cmb_stub_aif_ctrl_cb) (state, ctrl); -+ CMB_STUB_LOG_INFO("[cmb_stub] aif_ctrl_cb state(%d->%d) ctrl(%d) ret(%d)\n", -+ cmb_stub_aif_stat, state, ctrl, ret); /* KERN_DEBUG */ -+ -+ cmb_stub_aif_stat = state; -+ } else { -+ CMB_STUB_LOG_WARN("[cmb_stub] aif_ctrl_cb null\n"); -+ ret = -2; -+ } -+ return ret; -+} -+EXPORT_SYMBOL(mtk_wcn_cmb_stub_aif_ctrl); -+ -+/* Use a temp translation table between COMBO_AUDIO_STATE_X and CMB_STUB_AIF_X -+ * for ALPS backward compatible ONLY!!! Remove this table, related functions, -+ * and type definition after modifying other kernel built-in modules, such as -+ * AUDIO. [FixMe][GeorgeKuo] -+ */ -+ -+void mtk_wcn_cmb_stub_func_ctrl(unsigned int type, unsigned int on) -+{ -+ if (cmb_stub_func_ctrl_cb) -+ (*cmb_stub_func_ctrl_cb) (type, on); -+ else -+ CMB_STUB_LOG_WARN("[cmb_stub] func_ctrl_cb null\n"); -+} -+EXPORT_SYMBOL(mtk_wcn_cmb_stub_func_ctrl); -+ -+int mtk_wcn_cmb_stub_query_ctrl(void) -+{ -+ signed long temp = 0; -+ -+ if (cmb_stub_thermal_ctrl_cb) -+ temp = (*cmb_stub_thermal_ctrl_cb) (); -+ else -+ CMB_STUB_LOG_WARN("[cmb_stub] thermal_ctrl_cb null\n"); -+ -+ return temp; -+} -+ -+/*platform-related APIs*/ -+/* void clr_device_working_ability(UINT32 clockId, MT6573_STATE state); */ -+/* void set_device_working_ability(UINT32 clockId, MT6573_STATE state); */ -+ -+static int _mt_combo_plt_do_deep_idle(COMBO_IF src, int enter) -+{ -+ int ret = -1; -+ -+#if 0 -+ if (src != COMBO_IF_UART && src != COMBO_IF_MSDC && src != COMBO_IF_BTIF) { -+ CMB_STUB_LOG_WARN("src = %d is error\n", src); -+ return ret; -+ } -+ if (src >= 0 && src < COMBO_IF_MAX) -+ CMB_STUB_LOG_INFO("src = %s, to enter deep idle? %d\n", combo_if_name[src], enter); -+#endif -+ /*TODO: For Common SDIO configuration, we need to do some judgement between STP and WIFI -+ to decide if the msdc will enter deep idle safely */ -+ -+ switch (src) { -+ case COMBO_IF_UART: -+ if (enter == 0) { -+ /* clr_device_working_ability(MT65XX_PDN_PERI_UART3, DEEP_IDLE_STATE); */ -+ /* disable_dpidle_by_bit(MT65XX_PDN_PERI_UART2); */ -+#ifdef MTK_WCN_COMBO_CHIP_SUPPORT -+#if 0 -+ ret = mtk_uart_pdn_enable(wmt_uart_port_desc, 0); -+ if (ret < 0) -+ CMB_STUB_LOG_WARN("[CMB] %s exit deep idle failed\n", wmt_uart_port_desc); -+#endif -+#endif -+ } else { -+ /* set_device_working_ability(MT65XX_PDN_PERI_UART3, DEEP_IDLE_STATE); */ -+ /* enable_dpidle_by_bit(MT65XX_PDN_PERI_UART2); */ -+#ifdef MTK_WCN_COMBO_CHIP_SUPPORT -+#if 0 -+ ret = mtk_uart_pdn_enable(wmt_uart_port_desc, 1); -+ if (ret < 0) -+ CMB_STUB_LOG_WARN("[CMB] %s enter deep idle failed\n", wmt_uart_port_desc); -+#endif -+#endif -+ } -+ ret = 0; -+ break; -+ -+ case COMBO_IF_MSDC: -+ if (enter == 0) { -+ /* for common sdio hif */ -+ /* clr_device_working_ability(MT65XX_PDN_PERI_MSDC2, DEEP_IDLE_STATE); */ -+ } else { -+ /* for common sdio hif */ -+ /* set_device_working_ability(MT65XX_PDN_PERI_MSDC2, DEEP_IDLE_STATE); */ -+ } -+ ret = 0; -+ break; -+ -+ case COMBO_IF_BTIF: -+ if (cmb_stub_deep_idle_ctrl_cb) -+ ret = (*cmb_stub_deep_idle_ctrl_cb) (enter); -+ else -+ CMB_STUB_LOG_WARN("NULL function pointer\n"); -+ -+ if (ret) -+ CMB_STUB_LOG_WARN("%s deep idle fail(%d)\n", enter == 1 ? "enter" : "exit", ret); -+ else -+ CMB_STUB_LOG_DBG("%s deep idle ok(%d)\n", enter == 1 ? "enter" : "exit", ret); -+ break; -+ default: -+ break; -+ } -+ -+ return ret; -+} -+ -+int mt_combo_plt_enter_deep_idle(COMBO_IF src) -+{ -+ /* return 0; */ -+ /* TODO: [FixMe][GeorgeKuo] handling this depends on common UART or common SDIO */ -+ return _mt_combo_plt_do_deep_idle(src, 1); -+} -+EXPORT_SYMBOL(mt_combo_plt_enter_deep_idle); -+ -+int mt_combo_plt_exit_deep_idle(COMBO_IF src) -+{ -+ /* return 0; */ -+ /* TODO: [FixMe][GeorgeKuo] handling this depends on common UART or common SDIO */ -+ return _mt_combo_plt_do_deep_idle(src, 0); -+} -+EXPORT_SYMBOL(mt_combo_plt_exit_deep_idle); -+ -+int mtk_wcn_wmt_chipid_query(void) -+{ -+ return gConnectivityChipId; -+} -+EXPORT_SYMBOL(mtk_wcn_wmt_chipid_query); -+ -+void mtk_wcn_wmt_set_chipid(int chipid) -+{ -+ CMB_STUB_LOG_INFO("set current consys chipid (0x%x)\n", chipid); -+ gConnectivityChipId = chipid; -+} -+EXPORT_SYMBOL(mtk_wcn_wmt_set_chipid); -+ -+int mtk_wcn_cmb_stub_do_reset(unsigned int type) -+{ -+ if (cmb_stub_do_reset_cb) -+ return (*cmb_stub_do_reset_cb) (type); -+ else -+ return -1; -+} -+EXPORT_SYMBOL(mtk_wcn_cmb_stub_do_reset); -+ -+static void mtk_wcn_cmb_sdio_enable_eirq(void) -+{ -+ if (atomic_read(&irq_enable_flag)) -+ CMB_STUB_LOG_DBG("wifi eint has been enabled\n"); -+ else { -+ atomic_set(&irq_enable_flag, 1); -+ if (wifi_irq != 0xfffffff) { -+ enable_irq(wifi_irq); -+ CMB_STUB_LOG_DBG(" enable WIFI EINT irq %d !!\n", wifi_irq); -+ } -+ } -+} -+ -+static void mtk_wcn_cmb_sdio_disable_eirq(void) -+{ -+ if (!atomic_read(&irq_enable_flag)) -+ CMB_STUB_LOG_DBG("wifi eint has been disabled!\n"); -+ else { -+ if (wifi_irq != 0xfffffff) { -+ disable_irq_nosync(wifi_irq); -+ CMB_STUB_LOG_DBG("disable WIFI EINT irq %d !!\n", wifi_irq); -+ } -+ atomic_set(&irq_enable_flag, 0); -+ } -+} -+ -+irqreturn_t mtk_wcn_cmb_sdio_eirq_handler_stub(int irq, void *data) -+{ -+ if ((NULL != mtk_wcn_cmb_sdio_eirq_handler)&&(0 != atomic_read(&sdio_claim_irq_enable_flag))) -+ mtk_wcn_cmb_sdio_eirq_handler(mtk_wcn_cmb_sdio_eirq_data); -+ return IRQ_HANDLED; -+} -+ -+static void mtk_wcn_cmb_sdio_request_eirq(msdc_sdio_irq_handler_t irq_handler, void *data) -+{ -+ struct device_node *node; -+ int ret = -EINVAL; -+#if 0 -+ unsigned int gpio_wifi_eint_pin; -+#endif -+ -+ CMB_STUB_LOG_INFO("enter %s\n", __func__); -+ mtk_wcn_sdio_irq_flag_set(0); -+ atomic_set(&irq_enable_flag, 0); -+ mtk_wcn_cmb_sdio_eirq_data = data; -+ mtk_wcn_cmb_sdio_eirq_handler = irq_handler; -+ -+ node = (struct device_node *)of_find_compatible_node(NULL, NULL, "mediatek,connectivity-combo"); -+ if (node) { -+#if 0 -+ gpio_wifi_eint_pin = of_get_gpio(node, 5); -+ CMB_STUB_LOG_INFO("WIFI EINT pin %d !!\n", gpio_wifi_eint_pin); -+ wifi_irq = gpio_to_irq(gpio_wifi_eint_pin); -+#else -+ wifi_irq = irq_of_parse_and_map(node, 0);/* get wifi eint num */ -+#endif -+#if 1 -+ ret = request_irq(wifi_irq, mtk_wcn_cmb_sdio_eirq_handler_stub, IRQF_TRIGGER_LOW, -+ "WIFI-eint", NULL); -+ CMB_STUB_LOG_DBG("WIFI EINT irq %d !!\n", wifi_irq); -+#endif -+ -+ if (ret) -+ CMB_STUB_LOG_WARN("WIFI EINT IRQ LINE NOT AVAILABLE!!\n"); -+ else -+ mtk_wcn_cmb_sdio_disable_eirq();/*not ,chip state is power off*/ -+ } else -+ CMB_STUB_LOG_WARN("[%s] can't find connectivity compatible node\n", __func__); -+ -+ CMB_STUB_LOG_INFO("exit %s\n", __func__); -+} -+ -+static void mtk_wcn_cmb_sdio_register_pm(pm_callback_t pm_cb, void *data) -+{ -+ CMB_STUB_LOG_DBG("mtk_wcn_cmb_sdio_register_pm (0x%p, 0x%p)\n", pm_cb, data); -+ /* register pm change callback */ -+ mtk_wcn_cmb_sdio_pm_cb = pm_cb; -+ mtk_wcn_cmb_sdio_pm_data = data; -+} -+ -+static void mtk_wcn_cmb_sdio_on(int sdio_port_num) -+{ -+ pm_message_t state = {.event = PM_EVENT_USER_RESUME }; -+ -+ CMB_STUB_LOG_INFO("mtk_wcn_cmb_sdio_on (%d)\n", sdio_port_num); -+ -+ /* 1. disable sdio eirq */ -+ mtk_wcn_cmb_sdio_disable_eirq(); -+ -+ /* 2. call sd callback */ -+ if (mtk_wcn_cmb_sdio_pm_cb) { -+ /* pr_warn("mtk_wcn_cmb_sdio_pm_cb(PM_EVENT_USER_RESUME, 0x%p, 0x%p)\n", -+ * mtk_wcn_cmb_sdio_pm_cb, mtk_wcn_cmb_sdio_pm_data); */ -+ mtk_wcn_cmb_sdio_pm_cb(state, mtk_wcn_cmb_sdio_pm_data); -+ } else -+ CMB_STUB_LOG_WARN("mtk_wcn_cmb_sdio_on no sd callback!!\n"); -+} -+ -+static void mtk_wcn_cmb_sdio_off(int sdio_port_num) -+{ -+ pm_message_t state = {.event = PM_EVENT_USER_SUSPEND }; -+ -+ CMB_STUB_LOG_INFO("mtk_wcn_cmb_sdio_off (%d)\n", sdio_port_num); -+ -+ /* 1. call sd callback */ -+ if (mtk_wcn_cmb_sdio_pm_cb) { -+ /* pr_warn("mtk_wcn_cmb_sdio_off(PM_EVENT_USER_SUSPEND, 0x%p, 0x%p)\n", -+ * mtk_wcn_cmb_sdio_pm_cb, mtk_wcn_cmb_sdio_pm_data); */ -+ mtk_wcn_cmb_sdio_pm_cb(state, mtk_wcn_cmb_sdio_pm_data); -+ } else -+ CMB_STUB_LOG_WARN("mtk_wcn_cmb_sdio_off no sd callback!!\n"); -+ -+ /* 2. disable sdio eirq */ -+ mtk_wcn_cmb_sdio_disable_eirq(); -+} -+ -+int board_sdio_ctrl(unsigned int sdio_port_num, unsigned int on) -+{ -+ CMB_STUB_LOG_DBG("mt_mtk_wcn_cmb_sdio_ctrl (%d, %d)\n", sdio_port_num, on); -+ if (on) { -+#if 1 -+ CMB_STUB_LOG_DBG("board_sdio_ctrl force off before on\n"); -+ mtk_wcn_cmb_sdio_off(sdio_port_num); -+#else -+ CMB_STUB_LOG_WARN("skip sdio off before on\n"); -+#endif -+ /* off -> on */ -+ mtk_wcn_cmb_sdio_on(sdio_port_num); -+ if (wifi_irq != 0xfffffff) -+ irq_set_irq_wake(wifi_irq, 1); -+ else -+ CMB_STUB_LOG_WARN("wifi_irq is not available\n"); -+ } else { -+ if (wifi_irq != 0xfffffff) -+ irq_set_irq_wake(wifi_irq, 0); -+ else -+ CMB_STUB_LOG_WARN("wifi_irq is not available\n"); -+ /* on -> off */ -+ mtk_wcn_cmb_sdio_off(sdio_port_num); -+ } -+ -+ return 0; -+} -+EXPORT_SYMBOL(board_sdio_ctrl); -+ -+int mtk_wcn_sdio_irq_flag_set(int flag) -+{ -+ if (0 != flag) -+ atomic_set(&sdio_claim_irq_enable_flag, 1); -+ else -+ atomic_set(&sdio_claim_irq_enable_flag, 0); -+ -+ CMB_STUB_LOG_DBG("sdio_claim_irq_enable_flag:%d\n", atomic_read(&sdio_claim_irq_enable_flag)); -+ -+ return atomic_read(&sdio_claim_irq_enable_flag); -+} -+EXPORT_SYMBOL(mtk_wcn_sdio_irq_flag_set); -diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/sdio_detect.c b/drivers/misc/mediatek/connectivity/common/common_detect/sdio_detect.c -new file mode 100644 -index 000000000000..7ac5ac73ef5d ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/common_detect/sdio_detect.c -@@ -0,0 +1,269 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -+ -+#ifdef DFT_TAG -+#undef DFT_TAG -+#endif -+#define DFT_TAG "[SDIO-DETECT]" -+ -+#include "wmt_detect.h" -+ -+#if MTK_HIF_SDIO_AUTOK_ENABLED -+#include -+#endif -+ -+unsigned int gComboChipId = -1; -+struct sdio_func *g_func = NULL; -+ -+MTK_WCN_HIF_SDIO_CHIP_INFO gChipInfoArray[] = { -+ /* MT6620 *//* Not an SDIO standard class device */ -+ {{SDIO_DEVICE(0x037A, 0x020A)}, 0x6620}, /* SDIO1:FUNC1:WIFI */ -+ {{SDIO_DEVICE(0x037A, 0x020B)}, 0x6620}, /* SDIO2:FUNC1:BT+FM+GPS */ -+ {{SDIO_DEVICE(0x037A, 0x020C)}, 0x6620}, /* 2-function (SDIO2:FUNC1:BT+FM+GPS, FUNC2:WIFI) */ -+ -+ /* MT6628 *//* SDIO1: Wi-Fi, SDIO2: BGF */ -+ {{SDIO_DEVICE(0x037A, 0x6628)}, 0x6628}, -+ -+ /* MT6630 *//* SDIO1: Wi-Fi, SDIO2: BGF */ -+ {{SDIO_DEVICE(0x037A, 0x6630)}, 0x6630}, -+ -+}; -+ -+/* Supported SDIO device table */ -+static const struct sdio_device_id mtk_sdio_id_tbl[] = { -+ /* MT6618 *//* Not an SDIO standard class device */ -+ {SDIO_DEVICE(0x037A, 0x018A)}, /* SDIO1:WIFI */ -+ {SDIO_DEVICE(0x037A, 0x018B)}, /* SDIO2:FUNC1:BT+FM */ -+ {SDIO_DEVICE(0x037A, 0x018C)}, /* 2-function (SDIO2:FUNC1:BT+FM, FUNC2:WIFI) */ -+ -+ /* MT6619 *//* Not an SDIO standard class device */ -+ {SDIO_DEVICE(0x037A, 0x6619)}, /* SDIO2:FUNC1:BT+FM+GPS */ -+ -+ /* MT6620 *//* Not an SDIO standard class device */ -+ {SDIO_DEVICE(0x037A, 0x020A)}, /* SDIO1:FUNC1:WIFI */ -+ {SDIO_DEVICE(0x037A, 0x020B)}, /* SDIO2:FUNC1:BT+FM+GPS */ -+ {SDIO_DEVICE(0x037A, 0x020C)}, /* 2-function (SDIO2:FUNC1:BT+FM+GPS, FUNC2:WIFI) */ -+ -+ /* MT5921 *//* Not an SDIO standard class device */ -+ {SDIO_DEVICE(0x037A, 0x5921)}, -+ -+ /* MT6628 *//* SDIO1: Wi-Fi, SDIO2: BGF */ -+ {SDIO_DEVICE(0x037A, 0x6628)}, -+ -+ /* MT6630 *//* SDIO1: Wi-Fi, SDIO2: BGF */ -+ {SDIO_DEVICE(0x037A, 0x6630)}, -+ { /* end: all zeroes */ }, -+}; -+ -+static int sdio_detect_probe(struct sdio_func *func, const struct sdio_device_id *id); -+ -+static void sdio_detect_remove(struct sdio_func *func); -+ -+static struct sdio_driver mtk_sdio_client_drv = { -+ .name = "mtk_sdio_client", /* MTK SDIO Client Driver */ -+ .id_table = mtk_sdio_id_tbl, /* all supported struct sdio_device_id table */ -+ .probe = sdio_detect_probe, -+ .remove = sdio_detect_remove, -+}; -+ -+static int hif_sdio_match_chipid_by_dev_id(const struct sdio_device_id *id); -+ -+int hif_sdio_is_chipid_valid(int chipId) -+{ -+ int index = -1; -+ -+ int left = 0; -+ int middle = 0; -+ int right = sizeof(gChipInfoArray) / sizeof(gChipInfoArray[0]) - 1; -+ -+ if ((chipId < gChipInfoArray[left].chipId) || (chipId > gChipInfoArray[right].chipId)) -+ return index; -+ -+ middle = (left + right) / 2; -+ -+ while (left <= right) { -+ if (chipId > gChipInfoArray[middle].chipId) { -+ left = middle + 1; -+ } else if (chipId < gChipInfoArray[middle].chipId) { -+ right = middle - 1; -+ } else { -+ index = middle; -+ break; -+ } -+ middle = (left + right) / 2; -+ } -+ -+ if (0 > index) -+ WMT_DETECT_ERR_FUNC("no supported chipid found\n"); -+ else -+ WMT_DETECT_INFO_FUNC("index:%d, chipId:0x%x\n", index, gChipInfoArray[index].chipId); -+ -+ return index; -+} -+ -+int hif_sdio_match_chipid_by_dev_id(const struct sdio_device_id *id) -+{ -+ int maxIndex = sizeof(gChipInfoArray) / sizeof(gChipInfoArray[0]); -+ int index = 0; -+ struct sdio_device_id *localId = NULL; -+ int chipId = -1; -+ -+ for (index = 0; index < maxIndex; index++) { -+ localId = &(gChipInfoArray[index].deviceId); -+ if ((localId->vendor == id->vendor) && (localId->device == id->device)) { -+ chipId = gChipInfoArray[index].chipId; -+ WMT_DETECT_INFO_FUNC -+ ("valid chipId found, index(%d), vendor id(0x%x), device id(0x%x), chip id(0x%x)\n", index, -+ localId->vendor, localId->device, chipId); -+ gComboChipId = chipId; -+ mtk_wcn_wmt_set_chipid(gComboChipId); -+ break; -+ } -+ } -+ if (0 > chipId) { -+ WMT_DETECT_ERR_FUNC("No valid chipId found, vendor id(0x%x), device id(0x%x)\n", id->vendor, -+ id->device); -+ } -+ -+ return chipId; -+} -+ -+int sdio_detect_query_chipid(int waitFlag) -+{ -+ unsigned int timeSlotMs = 200; -+ unsigned int maxTimeSlot = 15; -+ unsigned int counter = 0; -+ /* gComboChipId = 0x6628; */ -+ if (0 == waitFlag) -+ return gComboChipId; -+ if (0 <= hif_sdio_is_chipid_valid(gComboChipId)) -+ return gComboChipId; -+ -+ while (counter < maxTimeSlot) { -+ if (0 <= hif_sdio_is_chipid_valid(gComboChipId)) -+ break; -+ msleep(timeSlotMs); -+ counter++; -+ } -+ -+ return gComboChipId; -+} -+ -+int sdio_detect_do_autok(int chipId) -+{ -+ int i_ret = 0; -+ -+#if MTK_HIF_SDIO_AUTOK_ENABLED -+#if 0 -+ BOOTMODE boot_mode; -+ -+ boot_mode = get_boot_mode(); -+ -+ if (boot_mode == META_BOOT) { -+ WMT_DETECT_INFO_FUNC("omit autok in meta mode\n"); -+ return 0; -+ } -+#endif -+ if (0x6630 == chipId) { -+#ifdef CONFIG_SDIOAUTOK_SUPPORT -+ if (NULL != g_func) { -+ WMT_DETECT_INFO_FUNC("wait_sdio_autok_ready++\n"); -+ i_ret = wait_sdio_autok_ready(g_func->card->host); -+ WMT_DETECT_INFO_FUNC("wait_sdio_autok_ready--\n"); -+ if (0 == i_ret) { -+ WMT_DETECT_INFO_FUNC("wait_sdio_autok_ready return success\n"); -+ } else { -+ WMT_DETECT_INFO_FUNC("wait_sdio_autok_ready return fail, i_ret:%d\n", i_ret); -+ gComboChipId = -1; -+ } -+ } else { -+ WMT_DETECT_INFO_FUNC("g_func NULL, omit autok\n"); -+ } -+#else -+ i_ret = 0; -+ WMT_DETECT_INFO_FUNC("MTK_SDIOAUTOK_SUPPORT not defined\n"); -+#endif -+ } else { -+ WMT_DETECT_INFO_FUNC("MT%x does not support SDIO3.0 autoK is not needed\n", chipId); -+ } -+#else -+ i_ret = 0; -+ WMT_DETECT_INFO_FUNC("MTK_HIF_SDIO_AUTOK_ENABLED is not defined\n"); -+#endif -+ return i_ret; -+} -+ -+/*! -+ * \brief hif_sdio probe function -+ * -+ * hif_sdio probe function called by mmc driver when any matched SDIO function -+ * is detected by it. -+ * -+ * \param func -+ * \param id -+ * -+ * \retval 0 register successfully -+ * \retval < 0 list error code here -+ */ -+static int sdio_detect_probe(struct sdio_func *func, const struct sdio_device_id *id) -+{ -+ int chipId = 0; -+ -+ WMT_DETECT_INFO_FUNC("vendor(0x%x) device(0x%x) num(0x%x)\n", func->vendor, func->device, func->num); -+ chipId = hif_sdio_match_chipid_by_dev_id(id); -+ -+ if ((0x6630 == chipId) && (1 == func->num)) { -+ int ret = 0; -+ -+ g_func = func; -+ WMT_DETECT_INFO_FUNC("autok function detected, func:0x%p\n", g_func); -+ -+ sdio_claim_host(func); -+ ret = sdio_enable_func(func); -+ sdio_release_host(func); -+ if (ret) -+ WMT_DETECT_ERR_FUNC("sdio_enable_func failed!\n"); -+ } -+ -+ return 0; -+} -+ -+static void sdio_detect_remove(struct sdio_func *func) -+{ -+ if (g_func == func) { -+ sdio_claim_host(func); -+ sdio_disable_func(func); -+ sdio_release_host(func); -+ g_func = NULL; -+ } -+ WMT_DETECT_INFO_FUNC("do sdio remove\n"); -+} -+ -+int sdio_detect_init(void) -+{ -+ int ret = -1; -+ /* register to mmc driver */ -+ ret = sdio_register_driver(&mtk_sdio_client_drv); -+ WMT_DETECT_INFO_FUNC("sdio_register_driver() ret=%d\n", ret); -+ return 0; -+} -+ -+int sdio_detect_exit(void) -+{ -+ g_func = NULL; -+ /* register to mmc driver */ -+ sdio_unregister_driver(&mtk_sdio_client_drv); -+ WMT_DETECT_INFO_FUNC("sdio_unregister_driver\n"); -+ return 0; -+} -diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/sdio_detect.h b/drivers/misc/mediatek/connectivity/common/common_detect/sdio_detect.h -new file mode 100644 -index 000000000000..3a0bff9def1b ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/common_detect/sdio_detect.h -@@ -0,0 +1,43 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -+ -+#ifndef _SDIO_DETECT_H_ -+#define _SDIO_DETECT_H_ -+ -+#include -+#include -+#include -+#include -+#include -+ -+#ifdef CONFIG_SDIOAUTOK_SUPPORT -+#define MTK_HIF_SDIO_AUTOK_ENABLED 1 -+extern int wait_sdio_autok_ready(void *); -+#else -+#define MTK_HIF_SDIO_AUTOK_ENABLED 0 -+#endif -+ -+typedef struct _MTK_WCN_HIF_SDIO_CHIP_INFO_ { -+ struct sdio_device_id deviceId; -+ unsigned int chipId; -+} MTK_WCN_HIF_SDIO_CHIP_INFO, *P_MTK_WCN_HIF_SDIO_CHIP_INFO; -+ -+extern int sdio_detect_exit(void); -+extern int sdio_detect_init(void); -+extern int sdio_detect_query_chipid(int waitFlag); -+extern int hif_sdio_is_chipid_valid(int chipId); -+ -+extern int sdio_detect_do_autok(int chipId); -+ -+#endif -diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/wmt_detect.c b/drivers/misc/mediatek/connectivity/common/common_detect/wmt_detect.c -new file mode 100644 -index 000000000000..487852df8f20 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/common_detect/wmt_detect.c -@@ -0,0 +1,380 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -+ -+#include -+#include -+ -+#ifdef DFT_TAG -+#undef DFT_TAG -+#endif -+#define DFT_TAG "[WMT-DETECT]" -+ -+#include "wmt_detect.h" -+#include "wmt_gpio.h" -+ -+#if MTK_WCN_REMOVE_KO -+#include "conn_drv_init.h" -+#endif -+#ifdef CONFIG_COMPAT -+#include -+#endif -+ -+#define WMT_DETECT_MAJOR 154 -+#define WMT_DETECT_DEV_NUM 1 -+#define WMT_DETECT_DRVIER_NAME "mtk_wcn_detect" -+#define WMT_DETECT_DEVICE_NAME "wmtdetect" -+ -+struct class *pDetectClass = NULL; -+struct device *pDetectDev = NULL; -+static int gWmtDetectMajor = WMT_DETECT_MAJOR; -+static struct cdev gWmtDetectCdev; -+unsigned int gWmtDetectDbgLvl = WMT_DETECT_LOG_INFO; -+ -+ -+#ifdef MTK_WCN_COMBO_CHIP_SUPPORT -+inline unsigned int wmt_plat_get_soc_chipid(void) -+{ -+ WMT_DETECT_INFO_FUNC("no soc chip supported, due to MTK_WCN_SOC_CHIP_SUPPORT is not set.\n"); -+ return -1; -+} -+#endif -+ -+static int wmt_detect_open(struct inode *inode, struct file *file) -+{ -+ WMT_DETECT_INFO_FUNC("open major %d minor %d (pid %d)\n", imajor(inode), iminor(inode), current->pid); -+ -+ return 0; -+} -+ -+static int wmt_detect_close(struct inode *inode, struct file *file) -+{ -+ WMT_DETECT_INFO_FUNC("close major %d minor %d (pid %d)\n", imajor(inode), iminor(inode), current->pid); -+ -+ return 0; -+} -+ -+static ssize_t wmt_detect_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos) -+{ -+ WMT_DETECT_INFO_FUNC(" ++\n"); -+ WMT_DETECT_INFO_FUNC(" --\n"); -+ -+ return 0; -+} -+ -+ssize_t wmt_detect_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos) -+{ -+ WMT_DETECT_INFO_FUNC(" ++\n"); -+ WMT_DETECT_INFO_FUNC(" --\n"); -+ -+ return 0; -+} -+ -+static long wmt_detect_unlocked_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) -+{ -+ int retval = 0; -+ -+ WMT_DETECT_INFO_FUNC("cmd (%d),arg(%ld)\n", cmd, arg); -+ -+ switch (cmd) { -+ case COMBO_IOCTL_GET_CHIP_ID: -+ /*just get chipid from sdio-detect module */ -+ /*check if external combo chip exists or not */ -+ /*if yes, just return combo chip id */ -+ /*if no, get soc chipid */ -+ retval = mtk_wcn_wmt_chipid_query(); -+ break; -+ -+ case COMBO_IOCTL_SET_CHIP_ID: -+ mtk_wcn_wmt_set_chipid(arg); -+ -+ break; -+ -+ case COMBO_IOCTL_EXT_CHIP_PWR_ON: -+ retval = wmt_detect_ext_chip_pwr_on(); -+ break; -+ -+ case COMBO_IOCTL_EXT_CHIP_DETECT: -+ retval = wmt_detect_ext_chip_detect(); -+ break; -+ -+ case COMBO_IOCTL_EXT_CHIP_PWR_OFF: -+ retval = wmt_detect_ext_chip_pwr_off(); -+ break; -+ -+ case COMBO_IOCTL_DO_SDIO_AUDOK: -+ retval = sdio_detect_do_autok(arg); -+ break; -+ -+ case COMBO_IOCTL_GET_SOC_CHIP_ID: -+ retval = wmt_plat_get_soc_chipid(); -+ /*get soc chipid by HAL interface */ -+ break; -+ -+ case COMBO_IOCTL_MODULE_CLEANUP: -+#if (MTK_WCN_REMOVE_KO) -+ /*deinit SDIO-DETECT module */ -+ retval = sdio_detect_exit(); -+#else -+ WMT_DETECT_INFO_FUNC("no MTK_WCN_REMOVE_KO defined\n"); -+#endif -+ break; -+ -+ case COMBO_IOCTL_DO_MODULE_INIT: -+#if (MTK_WCN_REMOVE_KO) -+ /*deinit SDIO-DETECT module */ -+ retval = do_connectivity_driver_init(arg); -+#else -+ WMT_DETECT_INFO_FUNC("no MTK_WCN_REMOVE_KO defined\n"); -+#endif -+ break; -+ -+ default: -+ WMT_DETECT_WARN_FUNC("unknown cmd (%d)\n", cmd); -+ retval = 0; -+ break; -+ } -+ return retval; -+} -+#ifdef CONFIG_COMPAT -+static long WMT_compat_detect_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) -+{ -+ long ret; -+ -+ WMT_DETECT_INFO_FUNC("cmd (%d)\n", cmd); -+ ret = wmt_detect_unlocked_ioctl(filp, cmd, arg); -+ return ret; -+} -+#endif -+const struct file_operations gWmtDetectFops = { -+ .open = wmt_detect_open, -+ .release = wmt_detect_close, -+ .read = wmt_detect_read, -+ .write = wmt_detect_write, -+ .unlocked_ioctl = wmt_detect_unlocked_ioctl, -+#ifdef CONFIG_COMPAT -+ .compat_ioctl = WMT_compat_detect_ioctl, -+#endif -+}; -+ -+int wmt_detect_ext_chip_pwr_on(void) -+{ -+ /*pre power on external chip */ -+ /* wmt_plat_pwr_ctrl(FUNC_ON); */ -+#ifdef MTK_WCN_COMBO_CHIP_SUPPORT -+ WMT_DETECT_INFO_FUNC("++\n"); -+ if (0 != wmt_detect_chip_pwr_ctrl(1)) -+ return -1; -+ if (0 != wmt_detect_sdio_pwr_ctrl(1)) -+ return -2; -+ return 0; -+#else -+ WMT_DETECT_INFO_FUNC("combo chip is not supported\n"); -+ return -1; -+#endif -+} -+ -+int wmt_detect_ext_chip_pwr_off(void) -+{ -+ /*pre power off external chip */ -+ /* wmt_plat_pwr_ctrl(FUNC_OFF); */ -+#ifdef MTK_WCN_COMBO_CHIP_SUPPORT -+ WMT_DETECT_INFO_FUNC("--\n"); -+ wmt_detect_sdio_pwr_ctrl(0); -+ return wmt_detect_chip_pwr_ctrl(0); -+#else -+ WMT_DETECT_INFO_FUNC("combo chip is not supported\n"); -+ return 0; -+#endif -+} -+ -+int wmt_detect_ext_chip_detect(void) -+{ -+ int iRet = -1; -+ unsigned int chipId = -1; -+ /*if there is no external combo chip, return -1 */ -+ int bgfEintStatus = -1; -+ -+ WMT_DETECT_INFO_FUNC("++\n"); -+ /*wait for a stable time */ -+ msleep(20); -+ -+ /*read BGF_EINT_PIN status */ -+ bgfEintStatus = wmt_detect_read_ext_cmb_status(); -+ -+ if (0 == bgfEintStatus) { -+ /*external chip does not exist */ -+ WMT_DETECT_INFO_FUNC("external combo chip not detected\n"); -+ } else if (1 == bgfEintStatus) { -+ /*combo chip exists */ -+ WMT_DETECT_INFO_FUNC("external combo chip detected\n"); -+ -+ /*detect chipid by sdio_detect module */ -+ chipId = sdio_detect_query_chipid(1); -+ if (0 <= hif_sdio_is_chipid_valid(chipId)) -+ WMT_DETECT_INFO_FUNC("valid external combo chip id (0x%x)\n", chipId); -+ else -+ WMT_DETECT_INFO_FUNC("invalid external combo chip id (0x%x)\n", chipId); -+ iRet = 0; -+ } else { -+ /*Error exists */ -+ WMT_DETECT_ERR_FUNC("error happens when detecting combo chip\n"); -+ } -+ WMT_DETECT_INFO_FUNC("--\n"); -+ /*return 0 */ -+ return iRet; -+ /*todo: if there is external combo chip, power on chip return 0 */ -+} -+ -+#ifdef MTK_WCN_COMBO_CHIP_SUPPORT -+static int wmt_detect_probe(struct platform_device *pdev) -+{ -+ int ret = 0; -+ -+ WMT_DETECT_ERR_FUNC("platform name: %s\n", pdev->name); -+ ret = wmt_gpio_init(pdev); -+ if (-1 == ret) -+ WMT_DETECT_ERR_FUNC("gpio init fail ret:%d\n", ret); -+ return ret; -+} -+ -+static int wmt_detect_remove(struct platform_device *pdev) -+{ -+ wmt_gpio_deinit(); -+ return 0; -+} -+#endif -+ -+#ifdef MTK_WCN_COMBO_CHIP_SUPPORT -+static struct of_device_id wmt_detect_match[] = { -+ { .compatible = "mediatek,connectivity-combo", }, -+ {} -+}; -+MODULE_DEVICE_TABLE(of, wmt_detect_match); -+ -+static struct platform_driver wmt_detect_driver = { -+ .probe = wmt_detect_probe, -+ .remove = wmt_detect_remove, -+ .driver = { -+ .owner = THIS_MODULE, -+ .name = "mediatek,connectivity-combo", -+ .of_match_table = wmt_detect_match, -+ }, -+}; -+#endif -+ -+/*module_platform_driver(wmt_detect_driver);*/ -+static int wmt_detect_driver_init(void) -+{ -+ dev_t devID = MKDEV(gWmtDetectMajor, 0); -+ int cdevErr = -1; -+ int ret = -1; -+ -+ ret = register_chrdev_region(devID, WMT_DETECT_DEV_NUM, WMT_DETECT_DRVIER_NAME); -+ if (ret) { -+ WMT_DETECT_ERR_FUNC("fail to register chrdev\n"); -+ return ret; -+ } -+ -+ cdev_init(&gWmtDetectCdev, &gWmtDetectFops); -+ gWmtDetectCdev.owner = THIS_MODULE; -+ -+ cdevErr = cdev_add(&gWmtDetectCdev, devID, WMT_DETECT_DEV_NUM); -+ if (cdevErr) { -+ WMT_DETECT_ERR_FUNC("cdev_add() fails (%d)\n", cdevErr); -+ goto err1; -+ } -+ -+ pDetectClass = class_create(THIS_MODULE, WMT_DETECT_DEVICE_NAME); -+ if (IS_ERR(pDetectClass)) { -+ WMT_DETECT_ERR_FUNC("class create fail, error code(%ld)\n", PTR_ERR(pDetectClass)); -+ goto err1; -+ } -+ -+ pDetectDev = device_create(pDetectClass, NULL, devID, NULL, WMT_DETECT_DEVICE_NAME); -+ if (IS_ERR(pDetectDev)) { -+ WMT_DETECT_ERR_FUNC("device create fail, error code(%ld)\n", PTR_ERR(pDetectDev)); -+ goto err2; -+ } -+ -+ WMT_DETECT_INFO_FUNC("driver(major %d) installed success\n", gWmtDetectMajor); -+ -+ /*init SDIO-DETECT module */ -+ sdio_detect_init(); -+ -+#ifdef MTK_WCN_COMBO_CHIP_SUPPORT -+ ret = platform_driver_register(&wmt_detect_driver); -+ if (ret) -+ WMT_DETECT_ERR_FUNC("platform driver register fail ret:%d\n", ret); -+#endif -+ -+ return 0; -+ -+err2: -+ -+ if (pDetectClass) { -+ class_destroy(pDetectClass); -+ pDetectClass = NULL; -+ } -+ -+err1: -+ -+ if (cdevErr == 0) -+ cdev_del(&gWmtDetectCdev); -+ -+ if (ret == 0) { -+ unregister_chrdev_region(devID, WMT_DETECT_DEV_NUM); -+ gWmtDetectMajor = -1; -+ } -+ -+ WMT_DETECT_ERR_FUNC("fail\n"); -+ -+ return -1; -+} -+ -+static void wmt_detect_driver_exit(void) -+{ -+ dev_t dev = MKDEV(gWmtDetectMajor, 0); -+ -+ if (pDetectDev) { -+ device_destroy(pDetectClass, dev); -+ pDetectDev = NULL; -+ } -+ -+ if (pDetectClass) { -+ class_destroy(pDetectClass); -+ pDetectClass = NULL; -+ } -+ -+ cdev_del(&gWmtDetectCdev); -+ unregister_chrdev_region(dev, WMT_DETECT_DEV_NUM); -+ -+#if !(MTK_WCN_REMOVE_KO) -+/*deinit SDIO-DETECT module*/ -+ sdio_detect_exit(); -+#endif -+ -+#ifdef MTK_WCN_COMBO_CHIP_SUPPORT -+ platform_driver_unregister(&wmt_detect_driver); -+#endif -+ -+ WMT_DETECT_INFO_FUNC("done\n"); -+} -+ -+module_init(wmt_detect_driver_init); -+module_exit(wmt_detect_driver_exit); -+ -+MODULE_LICENSE("GPL"); -+MODULE_AUTHOR("Zhiguo.Niu & Chaozhong.Liang @ MBJ/WCNSE/SS1"); -+ -+module_param(gWmtDetectMajor, uint, 0); -diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/wmt_detect.h b/drivers/misc/mediatek/connectivity/common/common_detect/wmt_detect.h -new file mode 100644 -index 000000000000..7e152bfd39ec ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/common_detect/wmt_detect.h -@@ -0,0 +1,114 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -+ -+#ifndef _WMT_DETECT_H_ -+#define _WMT_DETECT_H_ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+#ifdef MTK_WCN_REMOVE_KERNEL_MODULE -+#define MTK_WCN_REMOVE_KO 1 -+#else -+#define MTK_WCN_REMOVE_KO 0 -+#endif -+ -+#include "sdio_detect.h" -+#include "wmt_detect_pwr.h" -+#include -+ -+#define WMT_DETECT_LOG_LOUD 4 -+#define WMT_DETECT_LOG_DBG 3 -+#define WMT_DETECT_LOG_INFO 2 -+#define WMT_DETECT_LOG_WARN 1 -+#define WMT_DETECT_LOG_ERR 0 -+ -+extern unsigned int gWmtDetectDbgLvl; -+ -+#define WMT_DETECT_LOUD_FUNC(fmt, arg...) \ -+do { \ -+ if (gWmtDetectDbgLvl >= WMT_DETECT_LOG_LOUD) \ -+ pr_debug(DFT_TAG"[L]%s:" fmt, __func__ , ##arg); \ -+} while (0) -+#define WMT_DETECT_DBG_FUNC(fmt, arg...) \ -+do { \ -+ if (gWmtDetectDbgLvl >= WMT_DETECT_LOG_DBG) \ -+ pr_debug(DFT_TAG"[D]%s:" fmt, __func__ , ##arg); \ -+} while (0) -+#define WMT_DETECT_INFO_FUNC(fmt, arg...) \ -+do { \ -+ if (gWmtDetectDbgLvl >= WMT_DETECT_LOG_INFO) \ -+ pr_err(DFT_TAG"[I]%s:" fmt, __func__ , ##arg); \ -+} while (0) -+#define WMT_DETECT_WARN_FUNC(fmt, arg...) \ -+do { \ -+ if (gWmtDetectDbgLvl >= WMT_DETECT_LOG_WARN) \ -+ pr_warn(DFT_TAG"[W]%s(%d):" fmt, __func__ , __LINE__, ##arg); \ -+} while (0) -+#define WMT_DETECT_ERR_FUNC(fmt, arg...) \ -+do { \ -+ if (gWmtDetectDbgLvl >= WMT_DETECT_LOG_ERR) \ -+ pr_err(DFT_TAG"[E]%s(%d):" fmt, __func__ , __LINE__, ##arg); \ -+} while (0) -+ -+#define WMT_IOC_MAGIC 'w' -+#define COMBO_IOCTL_GET_CHIP_ID _IOR(WMT_IOC_MAGIC, 0, int) -+#define COMBO_IOCTL_SET_CHIP_ID _IOW(WMT_IOC_MAGIC, 1, int) -+#define COMBO_IOCTL_EXT_CHIP_DETECT _IOR(WMT_IOC_MAGIC, 2, int) -+#define COMBO_IOCTL_GET_SOC_CHIP_ID _IOR(WMT_IOC_MAGIC, 3, int) -+#define COMBO_IOCTL_DO_MODULE_INIT _IOR(WMT_IOC_MAGIC, 4, int) -+#define COMBO_IOCTL_MODULE_CLEANUP _IOR(WMT_IOC_MAGIC, 5, int) -+#define COMBO_IOCTL_EXT_CHIP_PWR_ON _IOR(WMT_IOC_MAGIC, 6, int) -+#define COMBO_IOCTL_EXT_CHIP_PWR_OFF _IOR(WMT_IOC_MAGIC, 7, int) -+#define COMBO_IOCTL_DO_SDIO_AUDOK _IOR(WMT_IOC_MAGIC, 8, int) -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+********************************************************************************/ -+extern int wmt_detect_ext_chip_detect(void); -+extern int wmt_detect_ext_chip_pwr_on(void); -+extern int wmt_detect_ext_chip_pwr_off(void); -+ -+#ifdef MTK_WCN_SOC_CHIP_SUPPORT -+extern unsigned int wmt_plat_get_soc_chipid(void); -+#endif -+ -+#ifdef MTK_WCN_COMBO_CHIP_SUPPORT -+/* mtk_uart_pdn_enable -- request uart port enter/exit deep idle mode, this API is defined in uart driver -+ * -+ * @ port - uart port name, Eg: "ttyMT0", "ttyMT1", "ttyMT2" -+ * @ enable - "1", enable deep idle; "0", disable deep idle -+ * -+ * Return 0 if success, else -1 -+ */ -+extern unsigned int mtk_uart_pdn_enable(char *port, int enable); -+#endif -+ -+#endif -diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/wmt_detect_pwr.c b/drivers/misc/mediatek/connectivity/common/common_detect/wmt_detect_pwr.c -new file mode 100644 -index 000000000000..1dcb7ed358bc ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/common_detect/wmt_detect_pwr.c -@@ -0,0 +1,232 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -+ -+#include -+ -+#ifdef DFT_TAG -+#undef DFT_TAG -+#endif -+#define DFT_TAG "[WMT-DETECT]" -+ -+#include "wmt_detect.h" -+#include "wmt_gpio.h" -+ -+#define INVALID_PIN_ID (0xFFFFFFFF) -+ -+/*copied form WMT module*/ -+static int wmt_detect_dump_pin_conf(void) -+{ -+ WMT_DETECT_DBG_FUNC("[WMT-DETECT]=>dump wmt pin configuration start<=\n"); -+ -+ WMT_DETECT_INFO_FUNC("LDO(GPIO%d), PMU(GPIO%d), PMUV28(GPIO%d)\n", -+ gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_LDO_EN_PIN].gpio_num, -+ gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_PMU_EN_PIN].gpio_num, -+ gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_PMUV28_EN_PIN].gpio_num); -+ -+ WMT_DETECT_INFO_FUNC("RST(GPIO%d), BGF_EINT(GPIO%d), BGF_EINT_NUM(%d)\n", -+ gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_RST_PIN].gpio_num, -+ gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_BGF_EINT_PIN].gpio_num, -+ gpio_to_irq(gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_BGF_EINT_PIN].gpio_num)); -+ -+ WMT_DETECT_INFO_FUNC("WIFI_EINT(GPIO%d), WIFI_EINT_NUM(%d)\n", -+ gpio_ctrl_info.gpio_ctrl_state[GPIO_WIFI_EINT_PIN].gpio_num, -+ gpio_to_irq(gpio_ctrl_info.gpio_ctrl_state[GPIO_WIFI_EINT_PIN].gpio_num)); -+ -+ WMT_DETECT_DBG_FUNC("[WMT-PLAT]=>dump wmt pin configuration ends<=\n"); -+ -+ return 0; -+} -+ -+int _wmt_detect_output_low(unsigned int id) -+{ -+ if (INVALID_PIN_ID != gpio_ctrl_info.gpio_ctrl_state[id].gpio_num) { -+ gpio_direction_output(gpio_ctrl_info.gpio_ctrl_state[id].gpio_num, 0); -+ WMT_DETECT_DBG_FUNC("WMT-DETECT: set GPIO%d to output %d\n", -+ gpio_ctrl_info.gpio_ctrl_state[id].gpio_num, -+ gpio_get_value(gpio_ctrl_info.gpio_ctrl_state[id].gpio_num)); -+ } -+ -+ return 0; -+} -+ -+int _wmt_detect_output_high(unsigned int id) -+{ -+ if (INVALID_PIN_ID != gpio_ctrl_info.gpio_ctrl_state[id].gpio_num) { -+ gpio_direction_output(gpio_ctrl_info.gpio_ctrl_state[id].gpio_num, 1); -+ WMT_DETECT_DBG_FUNC("WMT-DETECT: set GPIO%d to output %d\n", -+ gpio_ctrl_info.gpio_ctrl_state[id].gpio_num, -+ gpio_get_value(gpio_ctrl_info.gpio_ctrl_state[id].gpio_num)); -+ } -+ -+ return 0; -+} -+ -+int _wmt_detect_read_gpio_input(unsigned int id) -+{ -+ int retval = 0; -+ -+ if (INVALID_PIN_ID != gpio_ctrl_info.gpio_ctrl_state[id].gpio_num) { -+ retval = gpio_get_value(gpio_ctrl_info.gpio_ctrl_state[id].gpio_num); -+ WMT_DETECT_DBG_FUNC("WMT-DETECT: get GPIO%d val%d\n", -+ gpio_ctrl_info.gpio_ctrl_state[id].gpio_num, retval); -+ } -+ -+ return retval; -+} -+ -+/*This power on sequence must support all combo chip's basic power on sequence -+ * 1. LDO control is a must, if external LDO exist -+ * 2. PMU control is a must -+ * 3. RST control is a must -+ * 4. WIFI_EINT pin control is a must, used for GPIO mode for EINT status checkup -+ * 5. RTC32k clock control is a must -+ * */ -+static int wmt_detect_chip_pwr_on(void) -+{ -+ int retval = -1; -+ /*setting validiation check*/ -+ if ((INVALID_PIN_ID == gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_PMU_EN_PIN].gpio_num) || -+ (INVALID_PIN_ID == gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_RST_PIN].gpio_num) || -+ (INVALID_PIN_ID == gpio_ctrl_info.gpio_ctrl_state[GPIO_WIFI_EINT_PIN].gpio_num)) { -+ WMT_DETECT_ERR_FUNC("WMT-DETECT: either PMU(%d) or RST(%d) or WIFI_EINT(%d) is not set\n", -+ gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_PMU_EN_PIN].gpio_num, -+ gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_RST_PIN].gpio_num, -+ gpio_ctrl_info.gpio_ctrl_state[GPIO_WIFI_EINT_PIN].gpio_num); -+ -+ return retval; -+ } -+ /*set LDO/PMU/RST to output 0, no pull*/ -+ if (INVALID_PIN_ID != gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_LDO_EN_PIN].gpio_num) -+ _wmt_detect_output_low(GPIO_COMBO_LDO_EN_PIN); -+ if (gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_PMU_EN_PIN].gpio_state[GPIO_PULL_DIS]) { -+ pinctrl_select_state(gpio_ctrl_info.pinctrl_info, -+ gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_PMU_EN_PIN].gpio_state[GPIO_PULL_DIS]); -+ WMT_DETECT_INFO_FUNC("wmt_gpio:set GPIO_COMBO_PMU_EN_PIN to GPIO_PULL_DIS done!\n"); -+ } else -+ WMT_DETECT_ERR_FUNC("wmt_gpio:set GPIO_COMBO_PMU_EN_PIN to GPIO_PULL_DIS fail, is NULL!\n"); -+ _wmt_detect_output_low(GPIO_COMBO_PMU_EN_PIN); -+ if (gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_RST_PIN].gpio_state[GPIO_PULL_DIS]) { -+ pinctrl_select_state(gpio_ctrl_info.pinctrl_info, -+ gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_RST_PIN].gpio_state[GPIO_PULL_DIS]); -+ WMT_DETECT_INFO_FUNC("wmt_gpio:set GPIO_COMBO_RST_PIN to GPIO_PULL_DIS done!\n"); -+ } else -+ WMT_DETECT_ERR_FUNC("wmt_gpio:set GPIO_COMBO_RST_PIN to GPIO_PULL_DIS fail, is NULL!\n"); -+ _wmt_detect_output_low(GPIO_COMBO_RST_PIN); -+ -+#if 0 -+ _wmt_detect_output_high(GPIO_WIFI_EINT_PIN); -+#endif -+ -+ /*pull high LDO*/ -+ if (INVALID_PIN_ID != gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_LDO_EN_PIN].gpio_num) -+ _wmt_detect_output_high(GPIO_COMBO_LDO_EN_PIN); -+ /*sleep for LDO stable time*/ -+ msleep(MAX_LDO_STABLE_TIME); -+ -+ /*export RTC clock, sleep for RTC stable time*/ -+ rtc_gpio_enable_32k(RTC_GPIO_USER_GPS); -+ msleep(MAX_RTC_STABLE_TIME); -+ /*PMU output low, RST output low, to make chip power off completely*/ -+ /*always done*/ -+ /*sleep for power off stable time*/ -+ msleep(MAX_OFF_STABLE_TIME); -+ /*PMU output high, and sleep for reset stable time*/ -+ _wmt_detect_output_high(GPIO_COMBO_PMU_EN_PIN); -+#ifdef CONFIG_MTK_COMBO_COMM_NPWR -+ if ((gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_I2S_DAT_PIN].gpio_num != INVALID_PIN_ID) && -+ (gpio_ctrl_info.gpio_ctrl_state[GPIO_PCM_DAISYNC_PIN].gpio_num != INVALID_PIN_ID)) { -+ msleep(20); -+ _wmt_detect_output_high(GPIO_PCM_DAISYNC_PIN); -+ -+ msleep(20); -+ _wmt_detect_output_high(GPIO_COMBO_I2S_DAT_PIN); -+ -+ msleep(20); -+ _wmt_detect_output_low(GPIO_COMBO_I2S_DAT_PIN); -+ -+ msleep(20); -+ _wmt_detect_output_low(GPIO_PCM_DAISYNC_PIN); -+ -+ msleep(20); -+ } -+#endif -+ msleep(MAX_RST_STABLE_TIME); -+ /*RST output high, and sleep for power on stable time */ -+ _wmt_detect_output_high(GPIO_COMBO_RST_PIN); -+ msleep(MAX_ON_STABLE_TIME); -+ -+ retval = 0; -+ return retval; -+} -+ -+static int wmt_detect_chip_pwr_off(void) -+{ -+ -+ /*set RST pin to input low status*/ -+ if (INVALID_PIN_ID != gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_LDO_EN_PIN].gpio_num) -+ _wmt_detect_output_low(GPIO_COMBO_LDO_EN_PIN); -+ /*set RST pin to input low status*/ -+ if (INVALID_PIN_ID != gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_RST_PIN].gpio_num) -+ _wmt_detect_output_low(GPIO_COMBO_RST_PIN); -+ /*set PMU pin to input low status*/ -+ if (INVALID_PIN_ID != gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_PMU_EN_PIN].gpio_num) -+ _wmt_detect_output_low(GPIO_COMBO_PMU_EN_PIN); -+ return 0; -+} -+ -+int wmt_detect_read_ext_cmb_status(void) -+{ -+ int retval = 0; -+ /*read WIFI_EINT pin status*/ -+ if (INVALID_PIN_ID == gpio_ctrl_info.gpio_ctrl_state[GPIO_WIFI_EINT_PIN].gpio_num) { -+ retval = 0; -+ WMT_DETECT_ERR_FUNC("WMT-DETECT: no WIFI_EINT pin set\n"); -+ } else { -+ retval = _wmt_detect_read_gpio_input(GPIO_WIFI_EINT_PIN); -+ WMT_DETECT_ERR_FUNC("WMT-DETECT: WIFI_EINT input status:%d\n", retval); -+ } -+ return retval; -+} -+ -+int wmt_detect_chip_pwr_ctrl(int on) -+{ -+ int retval = -1; -+ -+ if (0 == on) { -+ /*power off combo chip */ -+ retval = wmt_detect_chip_pwr_off(); -+ } else { -+ wmt_detect_dump_pin_conf(); -+ /*power on combo chip */ -+ retval = wmt_detect_chip_pwr_on(); -+ } -+ return retval; -+} -+ -+int wmt_detect_sdio_pwr_ctrl(int on) -+{ -+ int retval = -1; -+#ifdef MTK_WCN_COMBO_CHIP_SUPPORT -+ if (0 == on) { -+ /*power off SDIO slot */ -+ retval = board_sdio_ctrl(1, 0); -+ } else { -+ /*power on SDIO slot */ -+ retval = board_sdio_ctrl(1, 1); -+ } -+#else -+ WMT_DETECT_WARN_FUNC("WMT-DETECT: MTK_WCN_COMBO_CHIP_SUPPORT is not set\n"); -+#endif -+ return retval; -+} -diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/wmt_detect_pwr.h b/drivers/misc/mediatek/connectivity/common/common_detect/wmt_detect_pwr.h -new file mode 100644 -index 000000000000..32e661520fd0 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/common_detect/wmt_detect_pwr.h -@@ -0,0 +1,29 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -+ -+#ifndef __WMT_DETECT_PWR_H_ -+#define __WMT_DETECT_PWR_H_ -+ -+#define MAX_RTC_STABLE_TIME 100 -+#define MAX_LDO_STABLE_TIME 100 -+#define MAX_RST_STABLE_TIME 30 -+#define MAX_OFF_STABLE_TIME 10 -+#define MAX_ON_STABLE_TIME 30 -+ -+extern int board_sdio_ctrl(unsigned int sdio_port_num, unsigned int on); -+extern int wmt_detect_chip_pwr_ctrl(int on); -+extern int wmt_detect_sdio_pwr_ctrl(int on); -+extern int wmt_detect_read_ext_cmb_status(void); -+ -+#endif -diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/wmt_gpio.c b/drivers/misc/mediatek/connectivity/common/common_detect/wmt_gpio.c -new file mode 100644 -index 000000000000..3a79e1e9d15a ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/common_detect/wmt_gpio.c -@@ -0,0 +1,371 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -+ -+#include "wmt_gpio.h" -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+const PUINT8 gpio_state_name[GPIO_PIN_ID_MAX][GPIO_STATE_MAX] = {{"gpio_ldo_en_pull_dis", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "gpio_ldo_en_in_pulldown", -+ ""}, -+ {"gpio_pmuv28_pull_dis", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "gpio_pmuv28_in_pulldown", -+ ""}, -+ {"gpio_pmu_en_pull_dis", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "gpio_pmu_en_in_pulldown", -+ ""}, -+ {"gpio_rst_pull_dis", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ ""}, -+ {"", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "gpio_bgf_eint_in_pulldown", -+ "gpio_bgf_eint_in_pullup"}, -+ {"", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "gpio_wifi_eint_in_pull_dis", -+ "", -+ "gpio_wifi_eint_in_pullup"}, -+ {"", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "gpio_all_eint_in_pulldown", -+ "gpio_all_eint_in_pullup"}, -+ {"gpio_urxd_uart_pull_dis", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "gpio_urxd_gpio_in_pull_dis", -+ "", -+ "gpio_urxd_gpio_in_pullup"}, -+ {"gpio_utxd_uart_pull_dis", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ ""}, -+ {"gpio_pcm_daiclk_pull_dis", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ ""}, -+ {"gpio_pcm_daipcmin_pull_dis", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ ""}, -+ {"gpio_pcm_daipcmout_pull_dis", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ ""}, -+ {"gpio_pcm_daisync_pull_dis", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ ""}, -+ {"gpio_i2s_ck_pull_dis", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ ""}, -+ {"gpio_i2s_ws_pull_dis", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ ""}, -+ {"gpio_i2s_dat_pull_dis", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ ""}, -+ {"gpio_gps_sync_pull_dis", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ ""}, -+ {"gpio_gps_lna_pull_dis", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ ""} -+}; -+ -+const PUINT8 gpio_pin_name[GPIO_PIN_ID_MAX] = {"gpio_combo_ldo_en_pin", -+ "gpio_combo_pmuv28_en_pin", -+ "gpio_combo_pmu_en_pin", -+ "gpio_combo_rst_pin", -+ "gpio_combo_bgf_eint_pin", -+ "gpio_wifi_eint_pin", -+ "gpio_all_eint_pin", -+ "gpio_combo_urxd_pin", -+ "gpio_combo_utxd_pin", -+ "gpio_pcm_daiclk_pin", -+ "gpio_pcm_daipcmin_pin", -+ "gpio_pcm_daipcmout_pin", -+ "gpio_pcm_daisync_pin", -+ "gpio_combo_i2s_ck_pin", -+ "gpio_combo_i2s_ws_pin", -+ "gpio_combo_i2s_dat_pin", -+ "gpio_gps_sync_pin", -+ "gpio_gps_lna_pin"}; -+ -+GPIO_CTRL_INFO gpio_ctrl_info; -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+INT32 wmt_gpio_init(struct platform_device *pdev) -+{ -+ INT32 iret = 0; -+ UINT32 i, j; -+ struct device_node *node; -+ -+ node = of_find_compatible_node(NULL, NULL, "mediatek,connectivity-combo"); -+ if (!node) { -+ for (i = 0; i < GPIO_PIN_ID_MAX; i++) -+ gpio_ctrl_info.gpio_ctrl_state[i].gpio_num = DEFAULT_PIN_ID; -+ pr_err("wmt_gpio:can't find device tree node!\n"); -+ iret = -1; -+ goto err; -+ } -+ -+ gpio_ctrl_info.pinctrl_info = devm_pinctrl_get(&pdev->dev); -+ if (gpio_ctrl_info.pinctrl_info) { -+ for (i = 0; i < GPIO_PIN_ID_MAX; i++) { -+ gpio_ctrl_info.gpio_ctrl_state[i].gpio_num = of_get_named_gpio(node, -+ gpio_pin_name[i], 0); -+ if (gpio_ctrl_info.gpio_ctrl_state[i].gpio_num < 0) -+ gpio_ctrl_info.gpio_ctrl_state[i].gpio_num = DEFAULT_PIN_ID; -+ if (DEFAULT_PIN_ID != gpio_ctrl_info.gpio_ctrl_state[i].gpio_num) { -+ for (j = 0; j < GPIO_STATE_MAX; j++) { -+ if (0 != strlen(gpio_state_name[i][j])) { -+ gpio_ctrl_info.gpio_ctrl_state[i].gpio_state[j] = -+ pinctrl_lookup_state(gpio_ctrl_info.pinctrl_info, -+ gpio_state_name[i][j]); -+ } else -+ gpio_ctrl_info.gpio_ctrl_state[i].gpio_state[j] = NULL; -+ } -+ } -+ } -+ -+ pr_err("wmt_gpio: gpio init start!\n"); -+ -+ if (gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_PMU_EN_PIN].gpio_state[GPIO_PULL_DIS]) { -+ pinctrl_select_state(gpio_ctrl_info.pinctrl_info, -+ gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_PMU_EN_PIN]. -+ gpio_state[GPIO_PULL_DIS]); -+ pr_err("wmt_gpio:set GPIO_COMBO_PMU_EN_PIN to GPIO_PULL_DIS done!\n"); -+ } else -+ pr_err("wmt_gpio:set GPIO_COMBO_PMU_EN_PIN to GPIO_PULL_DIS fail, is NULL!\n"); -+ -+ if (DEFAULT_PIN_ID != gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_PMU_EN_PIN].gpio_num) { -+ gpio_direction_output(gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_PMU_EN_PIN].gpio_num, -+ 0); -+ pr_err("wmt_gpio:set GPIO_COMBO_PMU_EN_PIN out to 0: %d!\n", -+ gpio_get_value(gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_PMU_EN_PIN].gpio_num)); -+ } -+ -+ if (gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_RST_PIN].gpio_state[GPIO_PULL_DIS]) { -+ pinctrl_select_state(gpio_ctrl_info.pinctrl_info, -+ gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_RST_PIN].gpio_state[GPIO_PULL_DIS]); -+ pr_err("wmt_gpio:set GPIO_COMBO_RST_PIN to GPIO_PULL_DIS done!\n"); -+ } else -+ pr_err("wmt_gpio:set GPIO_COMBO_RST_PIN to GPIO_PULL_DIS fail, is NULL!\n"); -+ -+ if (DEFAULT_PIN_ID != gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_RST_PIN].gpio_num) { -+ gpio_direction_output(gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_RST_PIN].gpio_num, -+ 0); -+ pr_err("wmt_gpio:set GPIO_COMBO_RST_PIN out to 0: %d!\n", -+ gpio_get_value(gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_RST_PIN].gpio_num)); -+ } -+ -+ if (gpio_ctrl_info.gpio_ctrl_state[GPIO_WIFI_EINT_PIN].gpio_state[GPIO_IN_PULLUP]) { -+ pinctrl_select_state(gpio_ctrl_info.pinctrl_info, -+ gpio_ctrl_info.gpio_ctrl_state[GPIO_WIFI_EINT_PIN].gpio_state[GPIO_IN_PULLUP]); -+ pr_err("wmt_gpio:set GPIO_WIFI_EINT_PIN to GPIO_IN_PULLUP done!\n"); -+ } else -+ pr_err("wmt_gpio:set GPIO_WIFI_EINT_PIN to GPIO_IN_PULLUP fail, is NULL!\n"); -+ -+ if (gpio_ctrl_info.gpio_ctrl_state[GPIO_PCM_DAICLK_PIN].gpio_state[GPIO_PULL_DIS]) { -+ pinctrl_select_state(gpio_ctrl_info.pinctrl_info, -+ gpio_ctrl_info.gpio_ctrl_state[GPIO_PCM_DAICLK_PIN].gpio_state[GPIO_PULL_DIS]); -+ pr_err("wmt_gpio:set GPIO_PCM_DAICLK_PIN to GPIO_PULL_DIS done!\n"); -+ } else -+ pr_err("wmt_gpio:set GPIO_PCM_DAICLK_PIN to GPIO_PULL_DIS fail, is NULL!\n"); -+ -+ if (gpio_ctrl_info.gpio_ctrl_state[GPIO_PCM_DAIPCMIN_PIN].gpio_state[GPIO_PULL_DIS]) { -+ pinctrl_select_state(gpio_ctrl_info.pinctrl_info, -+ gpio_ctrl_info.gpio_ctrl_state[GPIO_PCM_DAIPCMIN_PIN]. -+ gpio_state[GPIO_PULL_DIS]); -+ pr_err("wmt_gpio:set GPIO_PCM_DAIPCMIN_PIN to GPIO_PULL_DIS done!\n"); -+ } else -+ pr_err("wmt_gpio:set GPIO_PCM_DAIPCMIN_PIN to GPIO_PULL_DIS fail, is NULL!\n"); -+ -+ if (gpio_ctrl_info.gpio_ctrl_state[GPIO_PCM_DAIPCMOUT_PIN].gpio_state[GPIO_PULL_DIS]) { -+ pinctrl_select_state(gpio_ctrl_info.pinctrl_info, -+ gpio_ctrl_info.gpio_ctrl_state[GPIO_PCM_DAIPCMOUT_PIN]. -+ gpio_state[GPIO_PULL_DIS]); -+ pr_err("wmt_gpio:set GPIO_PCM_DAIPCMOUT_PIN to GPIO_PULL_DIS done!\n"); -+ } else -+ pr_err("wmt_gpio:set GPIO_PCM_DAIPCMOUT_PIN to GPIO_PULL_DIS fail, is NULL!\n"); -+ -+ if (gpio_ctrl_info.gpio_ctrl_state[GPIO_PCM_DAISYNC_PIN].gpio_state[GPIO_PULL_DIS]) { -+ pinctrl_select_state(gpio_ctrl_info.pinctrl_info, -+ gpio_ctrl_info.gpio_ctrl_state[GPIO_PCM_DAISYNC_PIN]. -+ gpio_state[GPIO_PULL_DIS]); -+ pr_err("wmt_gpio:set GPIO_PCM_DAISYNC_PIN to GPIO_PULL_DIS done!\n"); -+ } else -+ pr_err("wmt_gpio:set GPIO_PCM_DAISYNC_PIN to GPIO_PULL_DIS fail, is NULL!\n"); -+ -+ pr_err("wmt_gpio: gpio init done!\n"); -+ } else { -+ pr_err("wmt_gpio:can't find pinctrl dev!\n"); -+ iret = -1; -+ } -+err: -+ return iret; -+} -+ -+INT32 wmt_gpio_deinit(VOID) -+{ -+ INT32 iret = 0; -+ UINT32 i; -+ UINT32 j; -+ -+ for (i = 0; i < GPIO_PIN_ID_MAX; i++) { -+ gpio_ctrl_info.gpio_ctrl_state[i].gpio_num = DEFAULT_PIN_ID; -+ if (DEFAULT_PIN_ID != gpio_ctrl_info.gpio_ctrl_state[i].gpio_num) { -+ for (j = 0; j < GPIO_STATE_MAX; j++) { -+ if (0 != strlen(gpio_state_name[i][j])) -+ gpio_ctrl_info.gpio_ctrl_state[i].gpio_state[j] = NULL; -+ } -+ } -+ } -+ if (gpio_ctrl_info.pinctrl_info) { -+ devm_pinctrl_put(gpio_ctrl_info.pinctrl_info); -+ gpio_ctrl_info.pinctrl_info = NULL; -+ } -+ -+ return iret; -+} -diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/wmt_gpio.h b/drivers/misc/mediatek/connectivity/common/common_detect/wmt_gpio.h -new file mode 100644 -index 000000000000..cd935bfddd99 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/common_detect/wmt_gpio.h -@@ -0,0 +1,103 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -+ -+#ifndef _WMT_GPIO_H_ -+#define _WMT_GPIO_H_ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include "osal.h" -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+#define DEFAULT_PIN_ID (0xffffffff) -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+typedef enum _ENUM_GPIO_PIN_ID { -+ GPIO_COMBO_LDO_EN_PIN = 0, -+ GPIO_COMBO_PMUV28_EN_PIN, -+ GPIO_COMBO_PMU_EN_PIN, -+ GPIO_COMBO_RST_PIN, -+ GPIO_COMBO_BGF_EINT_PIN, -+ GPIO_WIFI_EINT_PIN, -+ GPIO_COMBO_ALL_EINT_PIN, -+ GPIO_COMBO_URXD_PIN, -+ GPIO_COMBO_UTXD_PIN, -+ GPIO_PCM_DAICLK_PIN, -+ GPIO_PCM_DAIPCMIN_PIN, -+ GPIO_PCM_DAIPCMOUT_PIN, -+ GPIO_PCM_DAISYNC_PIN, -+ GPIO_COMBO_I2S_CK_PIN, -+ GPIO_COMBO_I2S_WS_PIN, -+ GPIO_COMBO_I2S_DAT_PIN, -+ GPIO_GPS_SYNC_PIN, -+ GPIO_GPS_LNA_PIN, -+ GPIO_PIN_ID_MAX -+} ENUM_GPIO_PIN_ID, *P_ENUM_GPIO_PIN_ID; -+ -+typedef enum _ENUM_GPIO_STATE_ID { -+ GPIO_PULL_DIS = 0, -+ GPIO_PULL_DOWN, -+ GPIO_PULL_UP, -+ GPIO_OUT_LOW, -+ GPIO_OUT_HIGH, -+ GPIO_IN_DIS, -+ GPIO_IN_EN, -+ GPIO_IN_PULL_DIS, -+ GPIO_IN_PULLDOWN, -+ GPIO_IN_PULLUP, -+ GPIO_STATE_MAX, -+} ENUM_GPIO_STATE_ID, *P_ENUM_GPIO_STATE_ID; -+ -+typedef struct _GPIO_CTRL_STATE { -+ INT32 gpio_num; -+ struct pinctrl_state *gpio_state[GPIO_STATE_MAX]; -+} GPIO_CTRL_STATE, *P_GPIO_CTRL_STATE; -+ -+typedef struct _GPIO_CTRL_INFO { -+ struct pinctrl *pinctrl_info; -+ GPIO_CTRL_STATE gpio_ctrl_state[GPIO_PIN_ID_MAX]; -+} GPIO_CTRL_INFO, *P_GPIO_CTRL_INFO; -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+extern const PUINT8 gpio_state_name[GPIO_PIN_ID_MAX][GPIO_STATE_MAX]; -+extern const PUINT8 gpio_pin_name[GPIO_PIN_ID_MAX]; -+extern GPIO_CTRL_INFO gpio_ctrl_info; -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+INT32 wmt_gpio_init(struct platform_device *pdev); -+ -+INT32 wmt_gpio_deinit(VOID); -+ -+#endif -diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/wmt_stp_exp.c b/drivers/misc/mediatek/connectivity/common/common_detect/wmt_stp_exp.c -new file mode 100644 -index 000000000000..4fc3144b3ba6 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/common_detect/wmt_stp_exp.c -@@ -0,0 +1,480 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -+#include "osal_typedef.h" -+#include "wmt_stp_exp.h" -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+#ifdef DFT_TAG -+#undef DFT_TAG -+#endif -+#define DFT_TAG "[WMT-STP-EXP]" -+ -+#define WMT_STP_EXP_INFO_FUNC(fmt, arg...) pr_debug(DFT_TAG "[I]%s: " fmt, __func__ , ##arg) -+#define WMT_STP_EXP_WARN_FUNC(fmt, arg...) pr_warn(DFT_TAG "[W]%s: " fmt, __func__ , ##arg) -+#define WMT_STP_EXP_ERR_FUNC(fmt, arg...) pr_err(DFT_TAG "[E]%s(%d):ERROR! " fmt, __func__ , __LINE__, ##arg) -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+#ifdef MTK_WCN_WMT_STP_EXP_SYMBOL_ABSTRACT -+/*STP exp*/ -+MTK_WCN_STP_SEND_DATA mtk_wcn_stp_send_data_f = NULL; -+MTK_WCN_STP_SEND_DATA mtk_wcn_stp_send_data_raw_f = NULL; -+MTK_WCN_STP_PARSER_DATA mtk_wcn_stp_parser_data_f = NULL; -+MTK_WCN_STP_RECV_DATA mtk_wcn_stp_receive_data_f = NULL; -+MTK_WCN_STP_IS_RXQ_EMPTY mtk_wcn_stp_is_rxqueue_empty_f = NULL; -+MTK_WCN_STP_IS_RDY mtk_wcn_stp_is_ready_f = NULL; -+MTK_WCN_STP_SET_BLUEZ mtk_wcn_stp_set_bluez_f = NULL; -+MTK_WCN_STP_REG_IF_TX mtk_wcn_stp_if_tx_f = NULL; -+MTK_WCN_STP_REG_IF_RX mtk_wcn_stp_if_rx_f = NULL; -+MTK_WCN_STP_REG_EVENT_CB mtk_wcn_stp_reg_event_cb_f = NULL; -+MTK_WCN_STP_RGE_TX_EVENT_CB mtk_wcn_stp_reg_tx_event_cb_f = NULL; -+MTK_WCN_STP_COREDUMP_START_GET mtk_wcn_stp_coredump_start_get_f = NULL; -+ -+/*WMT exp*/ -+MTK_WCN_WMT_FUNC_CTRL mtk_wcn_wmt_func_on_f = NULL; -+MTK_WCN_WMT_FUNC_CTRL mtk_wcn_wmt_func_off_f = NULL; -+MTK_WCN_WMT_THERM_CTRL mtk_wcn_wmt_therm_ctrl_f = NULL; -+MTK_WCN_WMT_HWVER_GET mtk_wcn_wmt_hwver_get_f = NULL; -+MTK_WCN_WMT_DSNS_CTRL mtk_wcn_wmt_dsns_ctrl_f = NULL; -+MTK_WCN_WMT_MSGCB_REG mtk_wcn_wmt_msgcb_reg_f = NULL; -+MTK_WCN_WMT_MSGCB_UNREG mtk_wcn_wmt_msgcb_unreg_f = NULL; -+MTK_WCN_WMT_SDIO_OP_REG mtk_wcn_wmt_sdio_op_reg_f = NULL; -+MTK_WCN_WMT_SDIO_HOST_AWAKE mtk_wcn_wmt_sdio_host_awake_f = NULL; -+MTK_WCN_WMT_ASSERT mtk_wcn_wmt_assert_f = NULL; -+MTK_WCN_WMT_ASSERT_TIMEOUT mtk_wcn_wmt_assert_timeout_f = NULL; -+MTK_WCN_WMT_IC_INFO_GET mtk_wcn_wmt_ic_info_get_f = NULL; -+MTK_WCN_WMT_PSM_CTRL mtk_wcn_wmt_psm_ctrl_f = NULL; -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+UINT32 mtk_wcn_stp_exp_cb_reg(P_MTK_WCN_STP_EXP_CB_INFO pStpExpCb) -+{ -+ WMT_STP_EXP_INFO_FUNC("call stp exp cb reg\n"); -+ -+ mtk_wcn_stp_send_data_f = pStpExpCb->stp_send_data_cb; -+ mtk_wcn_stp_send_data_raw_f = pStpExpCb->stp_send_data_raw_cb; -+ mtk_wcn_stp_parser_data_f = pStpExpCb->stp_parser_data_cb; -+ mtk_wcn_stp_receive_data_f = pStpExpCb->stp_receive_data_cb; -+ mtk_wcn_stp_is_rxqueue_empty_f = pStpExpCb->stp_is_rxqueue_empty_cb; -+ mtk_wcn_stp_is_ready_f = pStpExpCb->stp_is_ready_cb; -+ mtk_wcn_stp_set_bluez_f = pStpExpCb->stp_set_bluez_cb; -+ mtk_wcn_stp_if_tx_f = pStpExpCb->stp_if_tx_cb; -+ mtk_wcn_stp_if_rx_f = pStpExpCb->stp_if_rx_cb; -+ mtk_wcn_stp_reg_event_cb_f = pStpExpCb->stp_reg_event_cb; -+ mtk_wcn_stp_reg_tx_event_cb_f = pStpExpCb->stp_reg_tx_event_cb; -+ mtk_wcn_stp_coredump_start_get_f = pStpExpCb->stp_coredump_start_get_cb; -+ -+ return 0; -+} -+EXPORT_SYMBOL(mtk_wcn_stp_exp_cb_reg); -+ -+UINT32 mtk_wcn_stp_exp_cb_unreg(VOID) -+{ -+ WMT_STP_EXP_INFO_FUNC("call stp exp cb unreg\n"); -+ -+ mtk_wcn_stp_send_data_f = NULL; -+ mtk_wcn_stp_send_data_raw_f = NULL; -+ mtk_wcn_stp_parser_data_f = NULL; -+ mtk_wcn_stp_receive_data_f = NULL; -+ mtk_wcn_stp_is_rxqueue_empty_f = NULL; -+ mtk_wcn_stp_is_ready_f = NULL; -+ mtk_wcn_stp_set_bluez_f = NULL; -+ mtk_wcn_stp_if_tx_f = NULL; -+ mtk_wcn_stp_if_rx_f = NULL; -+ mtk_wcn_stp_reg_event_cb_f = NULL; -+ mtk_wcn_stp_reg_tx_event_cb_f = NULL; -+ mtk_wcn_stp_coredump_start_get_f = NULL; -+ -+ return 0; -+} -+EXPORT_SYMBOL(mtk_wcn_stp_exp_cb_unreg); -+ -+INT32 mtk_wcn_stp_send_data(const PUINT8 buffer, const UINT32 length, const UINT8 type) -+{ -+ INT32 ret = -1; -+ -+ if (mtk_wcn_stp_send_data_f) { -+ ret = (*mtk_wcn_stp_send_data_f) (buffer, length, type); -+ /* WMT_STP_EXP_INFO_FUNC("mtk_wcn_stp_send_data_f send data(%d)\n",ret); */ -+ } else { -+ WMT_STP_EXP_ERR_FUNC("mtk_wcn_stp_send_data_f cb is null\n"); -+ } -+ -+ return ret; -+ -+} -+EXPORT_SYMBOL(mtk_wcn_stp_send_data); -+ -+INT32 mtk_wcn_stp_send_data_raw(const PUINT8 buffer, const UINT32 length, const UINT8 type) -+{ -+ INT32 ret = -1; -+ -+ if (mtk_wcn_stp_send_data_raw_f) -+ ret = (*mtk_wcn_stp_send_data_raw_f) (buffer, length, type); -+ else -+ WMT_STP_EXP_ERR_FUNC("mtk_wcn_stp_send_data_raw_f cb is null\n"); -+ -+ return ret; -+} -+EXPORT_SYMBOL(mtk_wcn_stp_send_data_raw); -+ -+INT32 mtk_wcn_stp_parser_data(PUINT8 buffer, UINT32 length) -+{ -+ INT32 ret = -1; -+ -+ if (mtk_wcn_stp_parser_data_f) -+ ret = (*mtk_wcn_stp_parser_data_f) (buffer, length); -+ else -+ WMT_STP_EXP_ERR_FUNC("mtk_wcn_stp_parser_data_f cb is null\n"); -+ -+ return ret; -+} -+EXPORT_SYMBOL(mtk_wcn_stp_parser_data); -+ -+INT32 mtk_wcn_stp_receive_data(PUINT8 buffer, UINT32 length, UINT8 type) -+{ -+ INT32 ret = -1; -+ -+ if (mtk_wcn_stp_receive_data_f) -+ ret = (*mtk_wcn_stp_receive_data_f) (buffer, length, type); -+ else -+ WMT_STP_EXP_ERR_FUNC("mtk_wcn_stp_receive_data_f cb is null\n"); -+ -+ return ret; -+} -+EXPORT_SYMBOL(mtk_wcn_stp_receive_data); -+ -+MTK_WCN_BOOL mtk_wcn_stp_is_rxqueue_empty(UINT8 type) -+{ -+ MTK_WCN_BOOL ret = MTK_WCN_BOOL_FALSE; -+ -+ if (mtk_wcn_stp_is_rxqueue_empty_f) -+ ret = (*mtk_wcn_stp_is_rxqueue_empty_f) (type); -+ else -+ WMT_STP_EXP_ERR_FUNC("mtk_wcn_stp_is_rxqueue_empty_f cb is null\n"); -+ -+ return ret; -+} -+EXPORT_SYMBOL(mtk_wcn_stp_is_rxqueue_empty); -+ -+MTK_WCN_BOOL mtk_wcn_stp_is_ready(void) -+{ -+ MTK_WCN_BOOL ret = MTK_WCN_BOOL_FALSE; -+ -+ if (mtk_wcn_stp_is_ready_f) -+ ret = (*mtk_wcn_stp_is_ready_f) (); -+ else -+ WMT_STP_EXP_ERR_FUNC("mtk_wcn_stp_is_ready_f cb is null\n"); -+ -+ return ret; -+} -+EXPORT_SYMBOL(mtk_wcn_stp_is_ready); -+ -+void mtk_wcn_stp_set_bluez(MTK_WCN_BOOL flags) -+{ -+ -+ if (mtk_wcn_stp_set_bluez_f) -+ (*mtk_wcn_stp_set_bluez_f) (flags); -+ else -+ WMT_STP_EXP_ERR_FUNC("mtk_wcn_stp_set_bluez_f cb is null\n"); -+ -+} -+EXPORT_SYMBOL(mtk_wcn_stp_set_bluez); -+ -+INT32 mtk_wcn_stp_register_if_tx(ENUM_STP_TX_IF_TYPE stp_if, MTK_WCN_STP_IF_TX func) -+{ -+ INT32 ret = -1; -+ -+ if (mtk_wcn_stp_if_tx_f) -+ ret = (*mtk_wcn_stp_if_tx_f) (stp_if, func); -+ else -+ WMT_STP_EXP_ERR_FUNC("mtk_wcn_stp_if_tx_f cb is null\n"); -+ -+ return ret; -+} -+EXPORT_SYMBOL(mtk_wcn_stp_register_if_tx); -+ -+INT32 mtk_wcn_stp_register_if_rx(MTK_WCN_STP_IF_RX func) -+{ -+ INT32 ret = -1; -+ -+ if (mtk_wcn_stp_if_rx_f) -+ ret = (*mtk_wcn_stp_if_rx_f) (func); -+ else -+ WMT_STP_EXP_ERR_FUNC("mtk_wcn_stp_if_rx_f cb is null\n"); -+ -+ return ret; -+} -+EXPORT_SYMBOL(mtk_wcn_stp_register_if_rx); -+ -+INT32 mtk_wcn_stp_register_event_cb(INT32 type, MTK_WCN_STP_EVENT_CB func) -+{ -+ INT32 ret = -1; -+ -+ if (mtk_wcn_stp_reg_event_cb_f) -+ ret = (*mtk_wcn_stp_reg_event_cb_f) (type, func); -+ else -+ WMT_STP_EXP_ERR_FUNC("mtk_wcn_stp_reg_event_cb_f cb is null\n"); -+ -+ return ret; -+} -+EXPORT_SYMBOL(mtk_wcn_stp_register_event_cb); -+ -+INT32 mtk_wcn_stp_register_tx_event_cb(INT32 type, MTK_WCN_STP_EVENT_CB func) -+{ -+ INT32 ret = -1; -+ -+ if (mtk_wcn_stp_reg_tx_event_cb_f) -+ ret = (*mtk_wcn_stp_reg_tx_event_cb_f) (type, func); -+ else -+ WMT_STP_EXP_ERR_FUNC("mtk_wcn_stp_reg_tx_event_cb_f cb is null\n"); -+ -+ return ret; -+} -+EXPORT_SYMBOL(mtk_wcn_stp_register_tx_event_cb); -+ -+INT32 mtk_wcn_stp_coredump_start_get(VOID) -+{ -+ INT32 ret = -1; -+ -+ if (mtk_wcn_stp_coredump_start_get_f) -+ ret = (*mtk_wcn_stp_coredump_start_get_f) (); -+ else -+ WMT_STP_EXP_ERR_FUNC("mtk_wcn_stp_coredump_start_get_f cb is null\n"); -+ -+ return ret; -+} -+EXPORT_SYMBOL(mtk_wcn_stp_coredump_start_get); -+ -+UINT32 mtk_wcn_wmt_exp_cb_reg(P_MTK_WCN_WMT_EXP_CB_INFO pWmtExpCb) -+{ -+ WMT_STP_EXP_INFO_FUNC("call wmt exp cb reg\n"); -+ -+ mtk_wcn_wmt_func_on_f = pWmtExpCb->wmt_func_on_cb; -+ mtk_wcn_wmt_func_off_f = pWmtExpCb->wmt_func_off_cb; -+ mtk_wcn_wmt_therm_ctrl_f = pWmtExpCb->wmt_therm_ctrl_cb; -+ mtk_wcn_wmt_hwver_get_f = pWmtExpCb->wmt_hwver_get_cb; -+ mtk_wcn_wmt_dsns_ctrl_f = pWmtExpCb->wmt_dsns_ctrl_cb; -+ mtk_wcn_wmt_msgcb_reg_f = pWmtExpCb->wmt_msgcb_reg_cb; -+ mtk_wcn_wmt_msgcb_unreg_f = pWmtExpCb->wmt_msgcb_unreg_cb; -+ mtk_wcn_wmt_sdio_op_reg_f = pWmtExpCb->wmt_sdio_op_reg_cb; -+ mtk_wcn_wmt_sdio_host_awake_f = pWmtExpCb->wmt_sdio_host_awake_cb; -+ mtk_wcn_wmt_assert_f = pWmtExpCb->wmt_assert_cb; -+ mtk_wcn_wmt_assert_timeout_f = pWmtExpCb->wmt_assert_timeout_cb; -+ mtk_wcn_wmt_ic_info_get_f = pWmtExpCb->wmt_ic_info_get_cb; -+ mtk_wcn_wmt_psm_ctrl_f = pWmtExpCb->wmt_psm_ctrl_cb; -+ return 0; -+} -+EXPORT_SYMBOL(mtk_wcn_wmt_exp_cb_reg); -+ -+UINT32 mtk_wcn_wmt_exp_cb_unreg(VOID) -+{ -+ WMT_STP_EXP_INFO_FUNC("call wmt exp cb unreg\n"); -+ -+ mtk_wcn_wmt_func_on_f = NULL; -+ mtk_wcn_wmt_func_off_f = NULL; -+ mtk_wcn_wmt_therm_ctrl_f = NULL; -+ mtk_wcn_wmt_hwver_get_f = NULL; -+ mtk_wcn_wmt_dsns_ctrl_f = NULL; -+ mtk_wcn_wmt_msgcb_reg_f = NULL; -+ mtk_wcn_wmt_msgcb_unreg_f = NULL; -+ mtk_wcn_wmt_sdio_op_reg_f = NULL; -+ mtk_wcn_wmt_sdio_host_awake_f = NULL; -+ mtk_wcn_wmt_assert_f = NULL; -+ mtk_wcn_wmt_assert_timeout_f = NULL; -+ mtk_wcn_wmt_ic_info_get_f = NULL; -+ mtk_wcn_wmt_psm_ctrl_f = NULL; -+ -+ return 0; -+} -+EXPORT_SYMBOL(mtk_wcn_wmt_exp_cb_unreg); -+ -+MTK_WCN_BOOL mtk_wcn_wmt_func_off(ENUM_WMTDRV_TYPE_T type) -+{ -+ MTK_WCN_BOOL ret = MTK_WCN_BOOL_FALSE; -+ -+ if (mtk_wcn_wmt_func_off_f) -+ ret = (*mtk_wcn_wmt_func_off_f) (type); -+ else -+ WMT_STP_EXP_ERR_FUNC("mtk_wcn_wmt_func_off_f cb is null\n"); -+ -+ return ret; -+} -+EXPORT_SYMBOL(mtk_wcn_wmt_func_off); -+ -+MTK_WCN_BOOL mtk_wcn_wmt_func_on(ENUM_WMTDRV_TYPE_T type) -+{ -+ MTK_WCN_BOOL ret = MTK_WCN_BOOL_FALSE; -+ -+ if (mtk_wcn_wmt_func_on_f) { -+ ret = (*mtk_wcn_wmt_func_on_f) (type); -+ WMT_STP_EXP_INFO_FUNC("mtk_wcn_wmt_func_on_f type(%d)\n", type); -+ } else -+ WMT_STP_EXP_ERR_FUNC("mtk_wcn_wmt_func_on_f cb is null\n"); -+ -+ return ret; -+} -+EXPORT_SYMBOL(mtk_wcn_wmt_func_on); -+ -+INT8 mtk_wcn_wmt_therm_ctrl(ENUM_WMTTHERM_TYPE_T eType) -+{ -+ INT32 ret = -1; -+ -+ if (mtk_wcn_wmt_therm_ctrl_f) -+ ret = (*mtk_wcn_wmt_therm_ctrl_f) (eType); -+ else -+ WMT_STP_EXP_ERR_FUNC("mtk_wcn_wmt_therm_ctrl_f cb is null\n"); -+ -+ return ret; -+} -+EXPORT_SYMBOL(mtk_wcn_wmt_therm_ctrl); -+ -+ENUM_WMTHWVER_TYPE_T mtk_wcn_wmt_hwver_get(VOID) -+{ -+ ENUM_WMTHWVER_TYPE_T ret = WMTHWVER_INVALID; -+ -+ if (mtk_wcn_wmt_hwver_get_f) -+ ret = (*mtk_wcn_wmt_hwver_get_f) (); -+ else -+ WMT_STP_EXP_ERR_FUNC("mtk_wcn_wmt_hwver_get_f cb is null\n"); -+ -+ return ret; -+} -+EXPORT_SYMBOL(mtk_wcn_wmt_hwver_get); -+ -+MTK_WCN_BOOL mtk_wcn_wmt_dsns_ctrl(ENUM_WMTDSNS_TYPE_T eType) -+{ -+ MTK_WCN_BOOL ret = MTK_WCN_BOOL_FALSE; -+ -+ if (mtk_wcn_wmt_dsns_ctrl_f) -+ ret = (*mtk_wcn_wmt_dsns_ctrl_f) (eType); -+ else -+ WMT_STP_EXP_ERR_FUNC("mtk_wcn_wmt_dsns_ctrl_f cb is null\n"); -+ -+ return ret; -+} -+EXPORT_SYMBOL(mtk_wcn_wmt_dsns_ctrl); -+ -+INT32 mtk_wcn_wmt_msgcb_reg(ENUM_WMTDRV_TYPE_T eType, PF_WMT_CB pCb) -+{ -+ INT32 ret = 0; -+ -+ if (mtk_wcn_wmt_msgcb_reg_f) -+ ret = (*mtk_wcn_wmt_msgcb_reg_f) (eType, pCb); -+ else -+ WMT_STP_EXP_ERR_FUNC("mtk_wcn_wmt_msgcb_reg_f cb is null\n"); -+ -+ return ret; -+} -+EXPORT_SYMBOL(mtk_wcn_wmt_msgcb_reg); -+ -+INT32 mtk_wcn_wmt_msgcb_unreg(ENUM_WMTDRV_TYPE_T eType) -+{ -+ INT32 ret = 0; -+ -+ if (mtk_wcn_wmt_msgcb_unreg_f) -+ ret = (*mtk_wcn_wmt_msgcb_unreg_f) (eType); -+ else -+ WMT_STP_EXP_ERR_FUNC("mtk_wcn_wmt_msgcb_unreg_f cb is null\n"); -+ -+ return ret; -+} -+EXPORT_SYMBOL(mtk_wcn_wmt_msgcb_unreg); -+ -+INT32 mtk_wcn_stp_wmt_sdio_op_reg(PF_WMT_SDIO_PSOP own_cb) -+{ -+ INT32 ret = -1; -+ -+ if (mtk_wcn_wmt_sdio_op_reg_f) -+ ret = (*mtk_wcn_wmt_sdio_op_reg_f) (own_cb); -+ else -+ WMT_STP_EXP_ERR_FUNC("mtk_wcn_wmt_sdio_op_reg_f cb is null\n"); -+ -+ return ret; -+} -+EXPORT_SYMBOL(mtk_wcn_stp_wmt_sdio_op_reg); -+ -+INT32 mtk_wcn_stp_wmt_sdio_host_awake(VOID) -+{ -+ INT32 ret = -1; -+ -+ if (mtk_wcn_wmt_sdio_host_awake_f) -+ ret = (*mtk_wcn_wmt_sdio_host_awake_f) (); -+ else -+ WMT_STP_EXP_ERR_FUNC("mtk_wcn_wmt_sdio_host_awake_f cb is null\n"); -+ -+ return ret; -+} -+EXPORT_SYMBOL(mtk_wcn_stp_wmt_sdio_host_awake); -+ -+MTK_WCN_BOOL mtk_wcn_wmt_assert(ENUM_WMTDRV_TYPE_T type, UINT32 reason) -+{ -+ MTK_WCN_BOOL ret = MTK_WCN_BOOL_FALSE; -+ -+ if (mtk_wcn_wmt_assert_f) -+ ret = (*mtk_wcn_wmt_assert_f) (type, reason); -+ else -+ WMT_STP_EXP_ERR_FUNC("mtk_wcn_wmt_assert_f cb is null\n"); -+ -+ return ret; -+} -+EXPORT_SYMBOL(mtk_wcn_wmt_assert); -+ -+MTK_WCN_BOOL mtk_wcn_wmt_assert_timeout(ENUM_WMTDRV_TYPE_T type, UINT32 reason, INT32 timeout) -+{ -+ MTK_WCN_BOOL ret = MTK_WCN_BOOL_FALSE; -+ -+ if (mtk_wcn_wmt_assert_timeout_f) -+ ret = (*mtk_wcn_wmt_assert_timeout_f)(type, reason, timeout); -+ else -+ WMT_STP_EXP_ERR_FUNC("mtk_wcn_wmt_assert_timeout_f cb is null\n"); -+ return ret; -+} -+EXPORT_SYMBOL(mtk_wcn_wmt_assert_timeout); -+ -+UINT32 mtk_wcn_wmt_ic_info_get(ENUM_WMT_CHIPINFO_TYPE_T type) -+{ -+ UINT32 ret = 0; -+ -+ if (mtk_wcn_wmt_ic_info_get_f) -+ ret = (*mtk_wcn_wmt_ic_info_get_f) (type); -+ else -+ WMT_STP_EXP_ERR_FUNC("mtk_wcn_wmt_ic_info_get_f cb is null\n"); -+ -+ return ret; -+} -+EXPORT_SYMBOL(mtk_wcn_wmt_ic_info_get); -+ -+INT32 mtk_wcn_wmt_psm_ctrl(MTK_WCN_BOOL flag) -+{ -+ UINT32 ret = 0; -+ -+ if (mtk_wcn_wmt_psm_ctrl_f) -+ ret = (*mtk_wcn_wmt_psm_ctrl_f)(flag); -+ else -+ WMT_STP_EXP_ERR_FUNC("mtk_wcn_wmt_psm_ctrl_f cb is null\n"); -+ -+ return ret; -+} -+EXPORT_SYMBOL(mtk_wcn_wmt_psm_ctrl); -+ -+#endif -diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/wmt_stp_exp.h b/drivers/misc/mediatek/connectivity/common/common_detect/wmt_stp_exp.h -new file mode 100644 -index 000000000000..1c3dc8965298 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/common_detect/wmt_stp_exp.h -@@ -0,0 +1,610 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -+ -+#ifndef _WMT_STP_EXP_H_ -+#define _WMT_STP_EXP_H_ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include "osal_typedef.h" -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+#ifndef MTK_WCN_CMB_FOR_SDIO_1V_AUTOK -+#define MTK_WCN_CMB_FOR_SDIO_1V_AUTOK 0 -+#endif -+ -+#ifdef MTK_WCN_WMT_STP_EXP_SYMBOL_ABSTRACT -+ -+#if (WMT_IDC_SUPPORT) -+#define CFG_WMT_LTE_COEX_HANDLING 1 -+#define CFG_WMT_LTE_ENABLE_MSGID_MAPPING 0 -+#else -+#define CFG_WMT_LTE_COEX_HANDLING 0 -+#endif -+ -+/*from stp_exp.h*/ -+#define BT_TASK_INDX (0) -+#define FM_TASK_INDX (1) -+#define GPS_TASK_INDX (2) -+#define WIFI_TASK_INDX (3) -+#define WMT_TASK_INDX (4) -+#define STP_TASK_INDX (5) -+#define INFO_TASK_INDX (6) -+#define ANT_TASK_INDX (7) -+#if CFG_WMT_LTE_COEX_HANDLING -+#define COEX_TASK_INDX (8) -+#define MTKSTP_MAX_TASK_NUM (9) -+#else -+#define MTKSTP_MAX_TASK_NUM (8) -+#endif -+ -+#define MTKSTP_BUFFER_SIZE (16384) /* Size of RX Queue */ -+/*end from stp_exp.h*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+********************************************************************************/ -+ -+/*moved from stp_exp.h*/ -+typedef void (*MTK_WCN_STP_EVENT_CB) (void); -+typedef INT32(*MTK_WCN_STP_IF_TX) (const PUINT8 data, const UINT32 size, PUINT32 written_size); -+/* export for HIF driver */ -+typedef void (*MTK_WCN_STP_IF_RX) (const PUINT8 data, INT32 size); -+ -+typedef enum { -+ STP_UART_IF_TX = 0, -+ STP_SDIO_IF_TX = 1, -+ STP_BTIF_IF_TX = 2, -+ STP_MAX_IF_TX -+} ENUM_STP_TX_IF_TYPE; -+ -+/*end moved from stp_exp.h*/ -+ -+typedef INT32(*MTK_WCN_STP_SEND_DATA) (const PUINT8 buffer, const UINT32 length, const UINT8 type); -+typedef INT32(*MTK_WCN_STP_PARSER_DATA) (PUINT8 buffer, UINT32 length); -+typedef INT32(*MTK_WCN_STP_RECV_DATA) (PUINT8 buffer, UINT32 length, UINT8 type); -+typedef MTK_WCN_BOOL(*MTK_WCN_STP_IS_RXQ_EMPTY) (UINT8 type); -+typedef MTK_WCN_BOOL(*MTK_WCN_STP_IS_RDY) (VOID); -+typedef VOID(*MTK_WCN_STP_SET_BLUEZ) (MTK_WCN_BOOL flags); -+typedef INT32(*MTK_WCN_STP_REG_IF_TX) (ENUM_STP_TX_IF_TYPE stp_if, MTK_WCN_STP_IF_TX func); -+typedef INT32(*MTK_WCN_STP_REG_IF_RX) (MTK_WCN_STP_IF_RX func); -+typedef INT32(*MTK_WCN_STP_REG_EVENT_CB) (INT32 type, MTK_WCN_STP_EVENT_CB func); -+typedef INT32(*MTK_WCN_STP_RGE_TX_EVENT_CB) (INT32 type, MTK_WCN_STP_EVENT_CB func); -+typedef INT32(*MTK_WCN_STP_COREDUMP_START_GET)(VOID); -+ -+typedef struct _MTK_WCN_STP_EXP_CB_INFO_ { -+ MTK_WCN_STP_SEND_DATA stp_send_data_cb; -+ MTK_WCN_STP_SEND_DATA stp_send_data_raw_cb; -+ MTK_WCN_STP_PARSER_DATA stp_parser_data_cb; -+ MTK_WCN_STP_RECV_DATA stp_receive_data_cb; -+ MTK_WCN_STP_IS_RXQ_EMPTY stp_is_rxqueue_empty_cb; -+ MTK_WCN_STP_IS_RDY stp_is_ready_cb; -+ MTK_WCN_STP_SET_BLUEZ stp_set_bluez_cb; -+ MTK_WCN_STP_REG_IF_TX stp_if_tx_cb; -+ MTK_WCN_STP_REG_IF_RX stp_if_rx_cb; -+ MTK_WCN_STP_REG_EVENT_CB stp_reg_event_cb; -+ MTK_WCN_STP_RGE_TX_EVENT_CB stp_reg_tx_event_cb; -+ MTK_WCN_STP_COREDUMP_START_GET stp_coredump_start_get_cb; -+} MTK_WCN_STP_EXP_CB_INFO, *P_MTK_WCN_STP_EXP_CB_INFO; -+ -+/*moved from wmt_exp.h*/ -+ -+typedef enum _ENUM_WMTDRV_TYPE_T { -+ WMTDRV_TYPE_BT = 0, -+ WMTDRV_TYPE_FM = 1, -+ WMTDRV_TYPE_GPS = 2, -+ WMTDRV_TYPE_WIFI = 3, -+ WMTDRV_TYPE_WMT = 4, -+ WMTDRV_TYPE_ANT = 5, -+ WMTDRV_TYPE_STP = 6, -+ WMTDRV_TYPE_SDIO1 = 7, -+ WMTDRV_TYPE_SDIO2 = 8, -+ WMTDRV_TYPE_LPBK = 9, -+ WMTDRV_TYPE_COREDUMP = 10, -+#if MTK_WCN_CMB_FOR_SDIO_1V_AUTOK -+ WMTDRV_TYPE_AUTOK = 11, -+#endif -+ WMTDRV_TYPE_MAX -+} ENUM_WMTDRV_TYPE_T, *P_ENUM_WMTDRV_TYPE_T; -+ -+typedef enum _ENUM_WMTDSNS_TYPE_T { -+ WMTDSNS_FM_DISABLE = 0, -+ WMTDSNS_FM_ENABLE = 1, -+ WMTDSNS_FM_GPS_DISABLE = 2, -+ WMTDSNS_FM_GPS_ENABLE = 3, -+ WMTDSNS_MAX -+} ENUM_WMTDSNS_TYPE_T, *P_ENUM_WMTDSNS_TYPE_T; -+ -+typedef enum _ENUM_WMTHWVER_TYPE_T { -+ WMTHWVER_E1 = 0x0, -+ WMTHWVER_E2 = 0x1, -+ WMTHWVER_E3 = 0x2, -+ WMTHWVER_E4 = 0x3, -+ WMTHWVER_E5 = 0x4, -+ WMTHWVER_E6 = 0x5, -+ WMTHWVER_E7 = 0x6, -+ WMTHWVER_MAX, -+ WMTHWVER_INVALID = 0xff -+} ENUM_WMTHWVER_TYPE_T, *P_ENUM_WMTHWVER_TYPE_T; -+ -+typedef enum _ENUM_WMTTHERM_TYPE_T { -+ WMTTHERM_ZERO = 0, -+ WMTTHERM_ENABLE = WMTTHERM_ZERO + 1, -+ WMTTHERM_READ = WMTTHERM_ENABLE + 1, -+ WMTTHERM_DISABLE = WMTTHERM_READ + 1, -+ WMTTHERM_MAX -+} ENUM_WMTTHERM_TYPE_T, *P_ENUM_WMTTHERM_TYPE_T; -+ -+typedef enum _ENUM_WMTMSG_TYPE_T { -+ WMTMSG_TYPE_POWER_ON = 0, -+ WMTMSG_TYPE_POWER_OFF = 1, -+ WMTMSG_TYPE_RESET = 2, -+ WMTMSG_TYPE_STP_RDY = 3, -+ WMTMSG_TYPE_HW_FUNC_ON = 4, -+ WMTMSG_TYPE_MAX -+} ENUM_WMTMSG_TYPE_T, *P_ENUM_WMTMSG_TYPE_T; -+ -+typedef void (*PF_WMT_CB) (ENUM_WMTDRV_TYPE_T, /* Source driver type */ -+ ENUM_WMTDRV_TYPE_T, /* Destination driver type */ -+ ENUM_WMTMSG_TYPE_T, /* Message type */ -+ VOID *, /* READ-ONLY buffer. Buffer is allocated and freed by WMT_drv. Client -+ can't touch this buffer after this function return. */ -+ UINT32 /* Buffer size in unit of byte */ -+); -+ -+typedef enum _SDIO_PS_OP { -+ OWN_SET = 0, -+ OWN_CLR = 1, -+ OWN_STATE = 2, -+} SDIO_PS_OP; -+ -+typedef INT32(*PF_WMT_SDIO_PSOP) (SDIO_PS_OP); -+ -+typedef enum _ENUM_WMTCHIN_TYPE_T { -+ WMTCHIN_CHIPID = 0x0, -+ WMTCHIN_HWVER = WMTCHIN_CHIPID + 1, -+ WMTCHIN_MAPPINGHWVER = WMTCHIN_HWVER + 1, -+ WMTCHIN_FWVER = WMTCHIN_MAPPINGHWVER + 1, -+ WMTCHIN_MAX, -+ -+} ENUM_WMT_CHIPINFO_TYPE_T, *P_ENUM_WMT_CHIPINFO_TYPE_T; -+ -+/*end moved from wmt_exp.h*/ -+ -+typedef MTK_WCN_BOOL(*MTK_WCN_WMT_FUNC_CTRL) (ENUM_WMTDRV_TYPE_T type); -+typedef INT8(*MTK_WCN_WMT_THERM_CTRL) (ENUM_WMTTHERM_TYPE_T eType); -+typedef ENUM_WMTHWVER_TYPE_T(*MTK_WCN_WMT_HWVER_GET) (VOID); -+typedef MTK_WCN_BOOL(*MTK_WCN_WMT_DSNS_CTRL) (ENUM_WMTDSNS_TYPE_T eType); -+typedef INT32(*MTK_WCN_WMT_MSGCB_REG) (ENUM_WMTDRV_TYPE_T eType, PF_WMT_CB pCb); -+typedef INT32(*MTK_WCN_WMT_MSGCB_UNREG) (ENUM_WMTDRV_TYPE_T eType); -+typedef INT32(*MTK_WCN_WMT_SDIO_OP_REG) (PF_WMT_SDIO_PSOP own_cb); -+typedef INT32(*MTK_WCN_WMT_SDIO_HOST_AWAKE) (VOID); -+typedef MTK_WCN_BOOL(*MTK_WCN_WMT_ASSERT) (ENUM_WMTDRV_TYPE_T type, UINT32 reason); -+typedef MTK_WCN_BOOL(*MTK_WCN_WMT_ASSERT_TIMEOUT)(ENUM_WMTDRV_TYPE_T type, -+ UINT32 reason, INT32 timeout); -+typedef UINT32(*MTK_WCN_WMT_IC_INFO_GET) (ENUM_WMT_CHIPINFO_TYPE_T type); -+typedef INT32 (*MTK_WCN_WMT_PSM_CTRL)(MTK_WCN_BOOL flag); -+ -+typedef struct _MTK_WCN_WMT_EXP_CB_INFO_ { -+ MTK_WCN_WMT_FUNC_CTRL wmt_func_on_cb; -+ MTK_WCN_WMT_FUNC_CTRL wmt_func_off_cb; -+ MTK_WCN_WMT_THERM_CTRL wmt_therm_ctrl_cb; -+ MTK_WCN_WMT_HWVER_GET wmt_hwver_get_cb; -+ MTK_WCN_WMT_DSNS_CTRL wmt_dsns_ctrl_cb; -+ MTK_WCN_WMT_MSGCB_REG wmt_msgcb_reg_cb; -+ MTK_WCN_WMT_MSGCB_UNREG wmt_msgcb_unreg_cb; -+ MTK_WCN_WMT_SDIO_OP_REG wmt_sdio_op_reg_cb; -+ MTK_WCN_WMT_SDIO_HOST_AWAKE wmt_sdio_host_awake_cb; -+ MTK_WCN_WMT_ASSERT wmt_assert_cb; -+ MTK_WCN_WMT_ASSERT_TIMEOUT wmt_assert_timeout_cb; -+ MTK_WCN_WMT_IC_INFO_GET wmt_ic_info_get_cb; -+ MTK_WCN_WMT_PSM_CTRL wmt_psm_ctrl_cb; -+} MTK_WCN_WMT_EXP_CB_INFO, *P_MTK_WCN_WMT_EXP_CB_INFO; -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/*exp for WMT/STP register callback*/ -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_exp_cb_reg -+* DESCRIPTION -+* stp driver reigster exp symbols -+* PARAMETERS -+* pStpExpCb [IN] stp callback structure pointer -+* RETURNS -+* UINT32 = 0: OK -+*****************************************************************************/ -+UINT32 mtk_wcn_stp_exp_cb_reg(P_MTK_WCN_STP_EXP_CB_INFO pStpExpCb); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_exp_cb_unreg -+* DESCRIPTION -+* stp driver unreigster exp symbols -+* PARAMETERS -+* VOID -+* RETURNS -+* UINT32 = 0: OK -+*****************************************************************************/ -+UINT32 mtk_wcn_stp_exp_cb_unreg(VOID); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_wmt_exp_cb_reg -+* DESCRIPTION -+* WMT driver reigster exp symbols -+* PARAMETERS -+* pStpExpCb [IN] wmt callback structure pointer -+* RETURNS -+* UINT32 = 0: OK -+*****************************************************************************/ -+UINT32 mtk_wcn_wmt_exp_cb_reg(P_MTK_WCN_WMT_EXP_CB_INFO pWmtExpCb); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_exp_cb_unreg -+* DESCRIPTION -+* wmt driver unreigster exp symbols -+* PARAMETERS -+* VOID -+* RETURNS -+* UINT32 = 0: OK -+*****************************************************************************/ -+UINT32 mtk_wcn_wmt_exp_cb_unreg(VOID); -+ -+/*stp exp symbols*/ -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_send_data -+* DESCRIPTION -+* subfunction send data through STP -+* PARAMETERS -+* buffer [IN] data buffer -+* length [IN] data buffer length -+* type [IN] subfunction type -+* RETURNS -+* INT32 >= 0: length transmitted; < 0: error -+*****************************************************************************/ -+extern INT32 mtk_wcn_stp_send_data(const PUINT8 buffer, const UINT32 length, const UINT8 type); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_send_data_raw -+* DESCRIPTION -+* subfunction send data through STP without seq/ack -+* PARAMETERS -+* buffer [IN] data buffer -+* length [IN] data buffer length -+* type [IN] subfunction type -+* RETURNS -+* INT32 >= 0: length transmitted; < 0: error -+*****************************************************************************/ -+extern INT32 mtk_wcn_stp_send_data_raw(const PUINT8 buffer, const UINT32 length, const UINT8 type); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_parser_data -+* DESCRIPTION -+* push data to serial transport protocol parser engine -+* PARAMETERS -+* buffer [IN] data buffer -+* length [IN] data buffer length -+* RETURNS -+* void -+*****************************************************************************/ -+extern INT32 mtk_wcn_stp_parser_data(PUINT8 buffer, UINT32 length); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_receive_data -+* DESCRIPTION -+* receive data from serial protocol engine -+* PARAMETERS -+* buffer [IN] data buffer -+* length [IN] data buffer length -+* RETURNS -+* INT32 >= 0: size of data received; < 0: error -+*****************************************************************************/ -+extern INT32 mtk_wcn_stp_receive_data(PUINT8 buffer, UINT32 length, UINT8 type); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_is_rxqueue_empty -+* DESCRIPTION -+* Is certain rx queue empty? -+* PARAMETERS -+* type [IN] subfunction type -+* RETURNS -+* INT32 0: queue is NOT empyt; !0: queue is empty -+*****************************************************************************/ -+extern MTK_WCN_BOOL mtk_wcn_stp_is_rxqueue_empty(UINT8 type); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_is_enable -+* DESCRIPTION -+* Is STP ready? -+* PARAMETERS -+* none. -+* RETURNS -+* MTK_WCN_BOOL TRUE:ready, FALSE:not ready -+*****************************************************************************/ -+extern MTK_WCN_BOOL mtk_wcn_stp_is_ready(void); -+ -+/***************************************************************************** -+* FUNCTION -+* set_bluetooth_rx_interface -+* DESCRIPTION -+* Set bluetooth rx interface -+* PARAMETERS -+* rx interface type -+* RETURNS -+* void -+*****************************************************************************/ -+extern void mtk_wcn_stp_set_bluez(MTK_WCN_BOOL flags); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_register_if_tx -+* DESCRIPTION -+* regiter Tx event callback function -+* PARAMETERS -+* stp_if: SDIO or UART, fnnc: Call back function -+* RETURNS -+* INT32: 0:successful , -1: fail -+*****************************************************************************/ -+extern INT32 mtk_wcn_stp_register_if_tx(ENUM_STP_TX_IF_TYPE stp_if, MTK_WCN_STP_IF_TX func); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_register_if_rx -+* DESCRIPTION -+* regiter Rx event callback function -+* PARAMETERS -+* stp_if: SDIO or UART, fnnc: Call back function -+* RETURNS -+* INT32: 0:successful , -1: fail -+*****************************************************************************/ -+extern INT32 mtk_wcn_stp_register_if_rx(MTK_WCN_STP_IF_RX func); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_register_event_cb -+* DESCRIPTION -+* regiter Rx event callback function -+* PARAMETERS -+* func -+* RETURNS -+* INT32: 0:successful , -1: fail -+*****************************************************************************/ -+extern INT32 mtk_wcn_stp_register_event_cb(INT32 type, MTK_WCN_STP_EVENT_CB func); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_register_tx_event_cb -+* DESCRIPTION -+* regiter Tx event callback function -+* PARAMETERS -+* func -+* RETURNS -+* INT32: 0:successful , -1: fail -+*****************************************************************************/ -+extern INT32 mtk_wcn_stp_register_tx_event_cb(INT32 type, MTK_WCN_STP_EVENT_CB func); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_coredump_start_get -+* DESCRIPTION -+* get coredump flag is set or not -+* PARAMETERS -+* VOID -+* RETURNS -+* INT32: 0:coredump flag is not set , 1: coredump flag is set -+*****************************************************************************/ -+extern INT32 mtk_wcn_stp_coredump_start_get(VOID); -+ -+/*wmt exp symbols*/ -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_wmt_func_off -+* DESCRIPTION -+* wmt turn off subsystem -+* PARAMETERS -+* type [IN] subsystem type -+* RETURNS -+* MTK_WCN_BOOL_TRUE: OK; MTK_WCN_BOOL_FALSE:error -+*****************************************************************************/ -+extern MTK_WCN_BOOL mtk_wcn_wmt_func_off(ENUM_WMTDRV_TYPE_T type); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_wmt_func_on -+* DESCRIPTION -+* wmt turn on subsystem -+* PARAMETERS -+* type [IN] subsystem type -+* RETURNS -+* MTK_WCN_BOOL_TRUE: OK; MTK_WCN_BOOL_FALSE:error -+*****************************************************************************/ -+extern MTK_WCN_BOOL mtk_wcn_wmt_func_on(ENUM_WMTDRV_TYPE_T type); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_wmt_therm_ctrl -+* DESCRIPTION -+* query chip temperature by WMT CMD -+* PARAMETERS -+* eType [IN] thermal ctrl type -+* RETURNS -+* >=0: chip temperature; 0xff:error -+*****************************************************************************/ -+extern INT8 mtk_wcn_wmt_therm_ctrl(ENUM_WMTTHERM_TYPE_T eType); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_wmt_hwver_get -+* DESCRIPTION -+* get chip hardware version -+* PARAMETERS -+* VOID -+* RETURNS -+* >=0: chip hw version; 0xff:error -+*****************************************************************************/ -+extern ENUM_WMTHWVER_TYPE_T mtk_wcn_wmt_hwver_get(VOID); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_wmt_ic_info_get -+* DESCRIPTION -+* get chip hardware version or f/w version -+* PARAMETERS -+* type : which kind of information is needed -+* RETURNS -+* f/w version or hw version information -+*****************************************************************************/ -+extern UINT32 mtk_wcn_wmt_ic_info_get(ENUM_WMT_CHIPINFO_TYPE_T type); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_wmt_dsns_ctrl -+* DESCRIPTION -+* fm dsns cmd ctrl -+* PARAMETERS -+* eType [IN] fm dsns ctrl type -+* RETURNS -+* MTK_WCN_BOOL_TRUE: OK; MTK_WCN_BOOL_FALSE:error -+*****************************************************************************/ -+extern MTK_WCN_BOOL mtk_wcn_wmt_dsns_ctrl(ENUM_WMTDSNS_TYPE_T eType); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_wmt_msgcb_reg -+* DESCRIPTION -+* used for subsystem register chip reset callback for received wmt reset msg. -+* PARAMETERS -+* eType [IN] subsystem type -+* pCb [IN] rst callback -+* RETURNS -+* 1: OK; 0:error -+*****************************************************************************/ -+extern INT32 mtk_wcn_wmt_msgcb_reg(ENUM_WMTDRV_TYPE_T eType, PF_WMT_CB pCb); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_wmt_msgcb_unreg -+* DESCRIPTION -+* used for subsystem unregister chip reset callback for received wmt reset msg. -+* PARAMETERS -+* eType [IN] subsystem type -+* RETURNS -+* 1: OK; 0:error -+*****************************************************************************/ -+extern INT32 mtk_wcn_wmt_msgcb_unreg(ENUM_WMTDRV_TYPE_T eType); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_wmt_sdio_op_reg -+* DESCRIPTION -+* used to register callback for set sdio ownership. -+* PARAMETERS -+* own_cb [IN] set owner ship callback -+* RETURNS -+* always return 0; -+*****************************************************************************/ -+extern INT32 mtk_wcn_stp_wmt_sdio_op_reg(PF_WMT_SDIO_PSOP own_cb); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_wmt_sdio_host_awake -+* DESCRIPTION -+* handing host awake when link is stp sdio? -+* PARAMETERS -+* VOID -+* RETURNS -+* always return 0; -+*****************************************************************************/ -+extern INT32 mtk_wcn_stp_wmt_sdio_host_awake(VOID); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_wmt_assert -+* DESCRIPTION -+* host trigger firmware assert -+* PARAMETERS -+* type [IN] subsystem driver type -+* reason [IN] trigger assert reason -+* RETURNS -+* MTK_WCN_BOOL_TRUE: OK; MTK_WCN_BOOL_FALSE:error -+*****************************************************************************/ -+extern MTK_WCN_BOOL mtk_wcn_wmt_assert(ENUM_WMTDRV_TYPE_T type, UINT32 reason); -+ -+/***************************************************************************** -+ * * FUNCTION -+ * * mtk_wcn_wmt_assert_timeout -+ * * DESCRIPTION -+ * * host trigger firmware assert -+ * * PARAMETERS -+ * * type [IN] subsystem driver type -+ * * reason [IN] trigger assert reason -+ * * timeout [IN] trigger assert timeout data -+ * * RETURNS -+ * * MTK_WCN_BOOL_TRUE: OK; MTK_WCN_BOOL_FALSE:error -+ * *****************************************************************************/ -+extern MTK_WCN_BOOL mtk_wcn_wmt_assert_timeout(ENUM_WMTDRV_TYPE_T type, -+ UINT32 reason, INT32 timeout); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_wmt_psm_ctrl -+* DESCRIPTION -+* disable/enable psm -+* PARAMETERS -+* flag [IN] disable:0, enable:1 -+* RETURNS -+* always return 0; -+*****************************************************************************/ -+extern INT32 mtk_wcn_wmt_psm_ctrl(MTK_WCN_BOOL flag); -+ -+#endif -+ -+#endif -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/Makefile b/drivers/misc/mediatek/connectivity/common/conn_soc/Makefile -new file mode 100644 -index 000000000000..286bfd4bfed3 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/Makefile -@@ -0,0 +1,65 @@ -+subdir-ccflags-y += \ -+ -I$(src)/linux/include \ -+ -I$(src)/linux/pri/include \ -+ -I$(src)/core/include \ -+ -I$(src)/include \ -+ -I$(src)/../common_detect \ -+ -I$(srctree)/drivers/misc/mediatek/btif/common/inc -+ -+subdir-ccflags-y += -I$(srctree)/drivers/misc/mediatek/eccci/ -+subdir-ccflags-y += -I$(srctree)/drivers/misc/mediatek/eccci/$(MTK_PLATFORM) -+subdir-ccflags-y += -I$(srctree)/drivers/misc/mediatek/eemcs/ -+subdir-ccflags-y += -I$(srctree)/drivers/misc/mediatek/conn_md/include -+ -+EXT_FLAG=_soc -+COMMON_SRC_PATH := $(src) -+COMMON_OBJ_PATH := $(src) -+ -+ifeq ($(CONFIG_ARCH_MT6580), y) -+subdir-ccflags-y += -D CFG_WMT_READ_EFUSE_VCN33 -+endif -+ -+ifeq ($(CONFIG_MTK_COMBO), m) -+# WMT DRIVER -+obj-$(CONFIG_MTK_COMBO) += mtk_stp_wmt$(EXT_FLAG).o -+# WMT DRIVER-core part -+mtk_stp_wmt$(EXT_FLAG)-objs := core/wmt_core.o core/wmt_ctrl.o core/wmt_func.o core/wmt_ic_soc.o core/wmt_lib.o core/wmt_conf.o -+ -+ -+# WMT DRIVER-linux private part -+mtk_stp_wmt$(EXT_FLAG)-objs += linux/pri/wmt_dev.o linux/pri/wmt_exp.o -+mtk_stp_wmt$(EXT_FLAG)-objs += linux/pri/stp_btif.o -+ -+ -+# WMT DRIVER-OSAL -+mtk_stp_wmt$(EXT_FLAG)-objs += linux/pub/osal.o linux/pub/bgw_desense.o -+# WMT DRIVER-platform implementation -+# ccflags-y += -D WMT_PLAT_ALPS -+# mtk_stp_wmt$(EXT_FLAG)-objs += platform/alps/wmt_plat_alps.o -+ -+# mtk_stp_wmt$(EXT_FLAG)-objs += platform/alps/mtk_wcn_consys_hw.o -+ -+ -+mtk_stp_wmt$(EXT_FLAG)-objs += linux/pri/stp_exp.o core/stp_core.o core/psm_core.o core/btm_core.o linux/pri/stp_dbg.o -+ -+# WMT stub part (built-in kernel image) -+# obj-y += platform/alps/mtk_wcn_consys_stub_alps.o -+ -+ -+ -+obj-$(CONFIG_MTK_COMBO_BT) += mtk_stp_bt$(EXT_FLAG).o -+mtk_stp_bt$(EXT_FLAG)-objs := linux/pub/stp_chrdev_bt.o -+ -+ -+obj-$(CONFIG_MTK_COMBO_WIFI) += mtk_wmt_wifi$(EXT_FLAG).o -+mtk_wmt_wifi$(EXT_FLAG)-objs := linux/pub/wmt_chrdev_wifi.o -+ -+endif -+ -+ifeq ($(CONFIG_MTK_COMBO), y) -+# subdir-ccflags-y += -D WMT_PLAT_ALPS -+obj-y += core/ -+obj-y += linux/ -+#obj-y += $(subst ",,$(CONFIG_MTK_PLATFORM))/ -+obj-y += mt7623/ -+endif -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/core/Makefile b/drivers/misc/mediatek/connectivity/common/conn_soc/core/Makefile -new file mode 100644 -index 000000000000..9df71b9e163e ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/core/Makefile -@@ -0,0 +1,22 @@ -+ifeq ($(CONFIG_MTK_COMBO), y) -+ -+ccflags-y += \ -+ -I$(src)/../linux/include \ -+ -I$(src)/../linux/pri/include \ -+ -I$(src)/../core/include \ -+ -I$(src)/../include \ -+ -I$(src)/../../common_detect \ -+ -I$(srctree)/drivers/misc/mediatek/btif/common/inc \ -+ -+obj-y += wmt_core.o \ -+ wmt_ctrl.o \ -+ wmt_func.o \ -+ wmt_ic_soc.o \ -+ wmt_lib.o \ -+ wmt_conf.o \ -+ btm_core.o \ -+ dbg_core.o \ -+ psm_core.o \ -+ stp_core.o -+ -+endif -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/core/btm_core.c b/drivers/misc/mediatek/connectivity/common/conn_soc/core/btm_core.c -new file mode 100644 -index 000000000000..4946b682d826 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/core/btm_core.c -@@ -0,0 +1,1376 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -+#include -+ -+#include "osal_typedef.h" -+#include "osal.h" -+#include "stp_dbg.h" -+#include "stp_core.h" -+#include "btm_core.h" -+#include "wmt_plat.h" -+ -+#define PFX_BTM "[STP-BTM] " -+#define STP_BTM_LOG_LOUD 4 -+#define STP_BTM_LOG_DBG 3 -+#define STP_BTM_LOG_INFO 2 -+#define STP_BTM_LOG_WARN 1 -+#define STP_BTM_LOG_ERR 0 -+ -+INT32 gBtmDbgLevel = STP_BTM_LOG_INFO; -+ -+#define STP_BTM_LOUD_FUNC(fmt, arg...) \ -+do { \ -+ if (gBtmDbgLevel >= STP_BTM_LOG_LOUD) \ -+ pr_debug(PFX_BTM "%s: " fmt, __func__ , ##arg); \ -+} while (0) -+#define STP_BTM_DBG_FUNC(fmt, arg...) \ -+do { \ -+ if (gBtmDbgLevel >= STP_BTM_LOG_DBG) \ -+ pr_debug(PFX_BTM "%s: " fmt, __func__ , ##arg); \ -+} while (0) -+#define STP_BTM_INFO_FUNC(fmt, arg...) \ -+do { \ -+ if (gBtmDbgLevel >= STP_BTM_LOG_INFO) \ -+ pr_debug(PFX_BTM "[I]%s: " fmt, __func__ , ##arg); \ -+} while (0) -+#define STP_BTM_WARN_FUNC(fmt, arg...) \ -+do { \ -+ if (gBtmDbgLevel >= STP_BTM_LOG_WARN) \ -+ pr_warn(PFX_BTM "[W]%s: " fmt, __func__ , ##arg); \ -+} while (0) -+#define STP_BTM_ERR_FUNC(fmt, arg...) \ -+do { \ -+ if (gBtmDbgLevel >= STP_BTM_LOG_ERR) \ -+ pr_err(PFX_BTM "[E]%s(%d):ERROR! " fmt, __func__ , __LINE__, ##arg); \ -+} while (0) -+#define STP_BTM_TRC_FUNC(f) \ -+do { \ -+ if (gBtmDbgLevel >= STP_BTM_LOG_DBG) \ -+ pr_debug(PFX_BTM "<%s> <%d>\n", __func__, __LINE__); \ -+} while (0) -+ -+#define ASSERT(expr) -+ -+MTKSTP_BTM_T stp_btm_i; -+MTKSTP_BTM_T *stp_btm = &stp_btm_i; -+ -+const char *g_btm_op_name[] = { -+ "STP_OPID_BTM_RETRY", -+ "STP_OPID_BTM_RST", -+ "STP_OPID_BTM_DBG_DUMP", -+ "STP_OPID_BTM_DUMP_TIMEOUT", -+ "STP_OPID_BTM_POLL_CPUPCR", -+ "STP_OPID_BTM_PAGED_DUMP", -+ "STP_OPID_BTM_FULL_DUMP", -+ "STP_OPID_BTM_PAGED_TRACE", -+ "STP_OPID_BTM_FORCE_FW_ASSERT", -+#if CFG_WMT_LTE_COEX_HANDLING -+ "STP_OPID_BTM_WMT_LTE_COEX", -+#endif -+ "STP_OPID_BTM_EXIT" -+}; -+ -+#if 0 -+static char *_stp_pkt_type(int type) -+{ -+ -+ static char s[10]; -+ -+ switch (type) { -+ case WMT_TASK_INDX: -+ osal_memcpy(s, "WMT", strlen("WMT") + 1); -+ break; -+ case BT_TASK_INDX: -+ osal_memcpy(s, "BT", strlen("BT") + 1); -+ break; -+ case GPS_TASK_INDX: -+ osal_memcpy(s, "GPS", strlen("GPS") + 1); -+ break; -+ case FM_TASK_INDX: -+ osal_memcpy(s, "FM", strlen("FM") + 1); -+ break; -+ default: -+ osal_memcpy(s, "UNKNOWN", strlen("UNKNOWN") + 1); -+ break; -+ } -+ -+ return s; -+} -+#endif -+ -+static INT32 _stp_btm_put_dump_to_nl(void) -+{ -+#define NUM_FETCH_ENTRY 8 -+ -+ static UINT8 buf[2048]; -+ static UINT8 tmp[2048]; -+ -+ UINT32 buf_len; -+ STP_PACKET_T *pkt; -+ STP_DBG_HDR_T *hdr; -+ INT32 len; -+ INT32 remain = 0, index = 0; -+ INT32 retry = 0, rc = 0, nl_retry = 0; -+ -+ STP_BTM_INFO_FUNC("Enter..\n"); -+ -+ index = 0; -+ tmp[index++] = '['; -+ tmp[index++] = 'M'; -+ tmp[index++] = ']'; -+ -+ do { -+ index = 3; -+ remain = stp_dbg_dmp_out_ex(&buf[0], &buf_len); -+ if (buf_len > 0) { -+ pkt = (STP_PACKET_T *) buf; -+ hdr = &pkt->hdr; -+ len = pkt->hdr.len; -+ osal_memcpy(&tmp[index], &len, 2); -+ index += 2; -+ if (hdr->dbg_type == STP_DBG_FW_DMP) { -+ osal_memcpy(&tmp[index], pkt->raw, len); -+ -+ if (len <= 1500) { -+ /* pr_warn("\n%s\n+++\n", tmp); */ -+ /* pr_warn("send coredump len:%d\n", len); */ -+ /* pr_warn("send coredump:%s\n", tmp); */ -+ rc = stp_dbg_nl_send((PINT8)&tmp, 2, len+5); -+ -+ while (rc) { -+ nl_retry++; -+ if (nl_retry > 1000) -+ break; -+ STP_BTM_WARN_FUNC -+ ("**dump send fails, and retry again.**\n"); -+ osal_sleep_ms(3); -+ rc = stp_dbg_nl_send((PINT8)&tmp, 2, len+5); -+ if (!rc) -+ STP_BTM_WARN_FUNC("****retry again ok!**\n"); -+ } -+ /* schedule(); */ -+ } else { -+ STP_BTM_INFO_FUNC("dump entry length is over long\n"); -+ BUG_ON(0); -+ } -+ retry = 0; -+ } -+ } else { -+ retry++; -+ osal_sleep_ms(100); -+ } -+ } while ((remain > 0) || (retry < 2)); -+ -+ STP_BTM_INFO_FUNC("Exit..\n"); -+ return 0; -+} -+ -+#define SUB_PKT_SIZE 1024 -+#define SUB_PKT_HEADER 5 /*'[M]',3Bytes; len,2Bytes*/ -+ -+INT32 _stp_btm_put_emi_dump_to_nl(PUINT8 data_buf, INT32 dump_len) -+{ -+ static UINT8 tmp[SUB_PKT_SIZE + SUB_PKT_HEADER]; -+ -+ INT32 remain = dump_len, index = 0; -+ INT32 rc = 0, nl_retry = 0; -+ INT32 len; -+ INT32 offset = 0; -+ -+ STP_BTM_INFO_FUNC("Enter..\n"); -+ -+ if (dump_len > 0) { -+ index = 0; -+ tmp[index++] = '['; -+ tmp[index++] = 'M'; -+ tmp[index++] = ']'; -+ -+ do { -+ index = 3; -+ if (remain >= SUB_PKT_SIZE) -+ len = SUB_PKT_SIZE; -+ else -+ len = remain; -+ remain -= len; -+ -+ osal_memcpy(&tmp[index], &len, 2); -+ index += 2; -+ osal_memcpy(&tmp[index], data_buf + offset, len); -+ offset += len; -+ STP_BTM_DBG_FUNC -+ ("send %d remain %d\n", len, remain); -+ -+ rc = stp_dbg_nl_send((PINT8)&tmp, 2, len + SUB_PKT_HEADER); -+ while (rc) { -+ nl_retry++; -+ if (nl_retry > 1000) -+ break; -+ STP_BTM_WARN_FUNC -+ ("**dump send fails, and retry again.**\n"); -+ osal_sleep_ms(3); -+ rc = stp_dbg_nl_send((PINT8)&tmp, 2, len + SUB_PKT_HEADER); -+ if (!rc) { -+ STP_BTM_WARN_FUNC -+ ("****retry again ok!**\n"); -+ } -+ } -+ /* schedule(); */ -+ } while (remain > 0); -+ } else -+ STP_BTM_INFO_FUNC("dump entry length is 0\n"); -+ -+ STP_BTM_INFO_FUNC("Exit..\n"); -+ return 0; -+} -+ -+static INT32 _stp_btm_put_dump_to_aee(void) -+{ -+ static UINT8 buf[2048]; -+ static UINT8 tmp[2048]; -+ -+ UINT32 buf_len; -+ STP_PACKET_T *pkt; -+ STP_DBG_HDR_T *hdr; -+ INT32 remain = 0; -+ INT32 retry = 0; -+ INT32 ret = 0; -+ -+ STP_BTM_INFO_FUNC("Enter..\n"); -+ -+ do { -+ remain = stp_dbg_dmp_out_ex(&buf[0], &buf_len); -+ if (buf_len > 0) { -+ pkt = (STP_PACKET_T *) buf; -+ hdr = &pkt->hdr; -+ if (hdr->dbg_type == STP_DBG_FW_DMP) { -+ memcpy(&tmp[0], pkt->raw, pkt->hdr.len); -+ -+ if (pkt->hdr.len <= 1500) { -+ tmp[pkt->hdr.len] = '\n'; -+ tmp[pkt->hdr.len + 1] = '\0'; -+ -+ ret = stp_dbg_aee_send(tmp, pkt->hdr.len, 0); -+ } else { -+ STP_BTM_INFO_FUNC("dump entry length is over long\n"); -+ BUG_ON(0); -+ } -+ retry = 0; -+ } -+ } else { -+ retry++; -+ msleep(100); -+ } -+ } while ((remain > 0) || (retry < 2)); -+ -+ STP_BTM_INFO_FUNC("Exit..\n"); -+ return ret; -+} -+ -+#if 0 -+INT32 _stp_trigger_firmware_assert_via_emi(VOID) -+{ -+ PUINT8 p_virtual_addr = NULL; -+ INT32 status = -1; -+ INT32 i = 0, j = 0; -+ -+ do { -+ STP_BTM_INFO_FUNC("[Force Assert] stp_trigger_firmware_assert_via_emi -->\n"); -+ p_virtual_addr = wmt_plat_get_emi_virt_add(EXP_APMEM_CTRL_HOST_OUTBAND_ASSERT_W1); -+ if (!p_virtual_addr) { -+ STP_BTM_ERR_FUNC("get virtual address fail\n"); -+ return -1; -+ } -+ -+ CONSYS_REG_WRITE(p_virtual_addr, EXP_APMEM_HOST_OUTBAND_ASSERT_MAGIC_W1); -+ STP_BTM_INFO_FUNC("[Force Assert] stp_trigger_firmware_assert_via_emi <--\n"); -+#if 1 -+ /* wait for firmware assert */ -+ osal_sleep_ms(50); -+ /* if firmware is not assert self, host driver helps it. */ -+ do { -+ if (0 != mtk_wcn_stp_coredump_start_get()) { -+ status = 0; -+ break; -+ } -+ -+ mtk_wcn_stp_wakeup_consys(); -+ STP_BTM_INFO_FUNC("[Force Assert] wakeup consys (%d)\n", i); -+ stp_dbg_poll_cpupcr(5, 1, 1); -+ osal_sleep_ms(5); -+ -+ i++; -+ if (i > 20) { -+ i = 0; -+ break; -+ } -+ } while (1); -+#endif -+ -+ if (0 != mtk_wcn_stp_coredump_start_get()) { -+ status = 0; -+ break; -+ } -+ -+ j++; -+ if (j > 8) { -+ j = 0; -+ break; -+ } -+ } while (1); -+ -+ return status; -+} -+#else -+INT32 _stp_trigger_firmware_assert_via_emi(VOID) -+{ -+ INT32 status = -1; -+ INT32 j = 0; -+ -+ wmt_plat_force_trigger_assert(STP_FORCE_TRG_ASSERT_DEBUG_PIN); -+ -+ do { -+ if (0 != mtk_wcn_stp_coredump_start_get()) { -+ status = 0; -+ break; -+ } -+ -+ stp_dbg_poll_cpupcr(5, 1, 1); -+ stp_dbg_poll_dmaregs(5, 1); -+ j++; -+ STP_BTM_INFO_FUNC("Wait for assert message (%d)\n", j); -+ osal_sleep_ms(20); -+ if (j > 49) { /* wait for 1 second */ -+ stp_dbg_set_fw_info("host trigger fw assert timeout", -+ osal_strlen("host trigger fw assert timeout"), -+ STP_HOST_TRIGGER_ASSERT_TIMEOUT); -+ wcn_core_dump_timeout(); /* trigger collect SYS_FTRACE */ -+ break; -+ } -+ } while (1); -+ -+ return status; -+} -+#endif -+ -+#define COMBO_DUMP2AEE -+#if 1 -+#define STP_DBG_PAGED_DUMP_BUFFER_SIZE (32*1024*sizeof(char)) -+UINT8 g_paged_dump_buffer[STP_DBG_PAGED_DUMP_BUFFER_SIZE] = { 0 }; -+ -+#define STP_DBG_PAGED_TRACE_SIZE (2048*sizeof(char)) -+UINT8 g_paged_trace_buffer[STP_DBG_PAGED_TRACE_SIZE] = { 0 }; -+ -+UINT32 g_paged_dump_len = 0; -+UINT32 g_paged_trace_len = 0; -+VOID _stp_dump_emi_dump_buffer(UINT8 *buffer, UINT32 len) -+{ -+ UINT32 i = 0; -+ -+ if (len > 16) -+ len = 16; -+ for (i = 0; i < len; i++) { -+ if (i % 16 == 0 && i != 0) -+ pr_cont("\n "); -+ -+ if (buffer[i] == ']' || buffer[i] == '[' || buffer[i] == ',') -+ pr_cont("%c", buffer[i]); -+ else -+ pr_cont("0x%02x ", buffer[i]); -+ } -+} -+#endif -+static INT32 _stp_btm_handler(MTKSTP_BTM_T *stp_btm, P_STP_BTM_OP pStpOp) -+{ -+ INT32 ret = -1; -+ INT32 dump_sink = 1; /* core dump target, 0: aee; 1: netlink */ -+ INT32 Ret = 0; -+ static UINT32 counter; -+ UINT32 full_dump_left = STP_FULL_DUMP_TIME; -+ UINT32 page_counter = 0; -+ UINT32 packet_num = STP_PAGED_DUMP_TIME_LIMIT/100; -+ UINT32 dump_num = 0; -+ ENUM_STP_FW_ISSUE_TYPE issue_type; -+ P_CONSYS_EMI_ADDR_INFO p_ecsi; -+ -+ p_ecsi = wmt_plat_get_emi_phy_add(); -+ osal_assert(p_ecsi); -+ if (NULL == pStpOp) -+ return -1; -+ -+ switch (pStpOp->opId) { -+ case STP_OPID_BTM_EXIT: -+ /* TODO: clean all up? */ -+ ret = 0; -+ break; -+ -+ /*tx timeout retry */ -+ case STP_OPID_BTM_RETRY: -+ stp_do_tx_timeout(); -+ ret = 0; -+ -+ break; -+ -+ /*whole chip reset */ -+ case STP_OPID_BTM_RST: -+ STP_BTM_INFO_FUNC("whole chip reset start!\n"); -+ STP_BTM_INFO_FUNC("....+\n"); -+ if (stp_btm->wmt_notify) { -+ stp_btm->wmt_notify(BTM_RST_OP); -+ ret = 0; -+ } else { -+ STP_BTM_ERR_FUNC("stp_btm->wmt_notify is NULL."); -+ ret = -1; -+ } -+ -+ STP_BTM_INFO_FUNC("whole chip reset end!\n"); -+ -+ break; -+ -+ case STP_OPID_BTM_DBG_DUMP: -+ /*Notify the wmt to get dump data */ -+ STP_BTM_DBG_FUNC("wmt dmp notification\n"); -+ dump_sink = ((stp_btm->wmt_notify(BTM_GET_AEE_SUPPORT_FLAG) == MTK_WCN_BOOL_TRUE) ? 0 : 1); -+ -+ if (dump_sink == 0) -+ _stp_btm_put_dump_to_aee(); -+ else if (dump_sink == 1) -+ _stp_btm_put_dump_to_nl(); -+ else -+ STP_BTM_ERR_FUNC("unknown sink %d\n", dump_sink); -+ -+ break; -+ -+ case STP_OPID_BTM_DUMP_TIMEOUT: -+ /* Flush dump data, and reset compressor */ -+ STP_BTM_INFO_FUNC("Flush dump data\n"); -+ wcn_core_dump_flush(0, MTK_WCN_BOOL_TRUE); -+ break; -+ -+ case STP_OPID_BTM_POLL_CPUPCR: -+ do { -+ UINT32 times; -+ UINT32 sleep; -+ -+ times = pStpOp->au4OpData[0]; -+ sleep = pStpOp->au4OpData[1]; -+ -+ ret = stp_dbg_poll_cpupcr(times, sleep, 0); -+ ret += stp_dbg_poll_dmaregs(times, sleep); -+ } while (0); -+ break; -+ -+ case STP_OPID_BTM_PAGED_DUMP: -+ g_paged_dump_len = 0; -+ issue_type = STP_FW_ASSERT_ISSUE; -+ /*packet number depend on dump_num get from register:0xf0080044 ,support jade*/ -+ wcn_core_dump_deinit_gcoredump(); -+ dump_num = wmt_plat_get_dump_info(p_ecsi->p_ecso->emi_apmem_ctrl_chip_page_dump_num); -+ if (dump_num != 0) { -+ packet_num = dump_num; -+ STP_BTM_WARN_FUNC("get consys dump num packet_num(%d)\n", packet_num); -+ } else { -+ STP_BTM_ERR_FUNC("can not get consys dump num and default num is 35\n"); -+ } -+ Ret = wcn_core_dump_init_gcoredump(packet_num, STP_CORE_DUMP_TIMEOUT); -+ if (Ret) { -+ STP_BTM_ERR_FUNC("core dump init fail\n"); -+ break; -+ } -+ wmt_plat_set_host_dump_state(STP_HOST_DUMP_NOT_START); -+ page_counter = 0; -+ do { -+ UINT32 loop_cnt1 = 0; -+ UINT32 loop_cnt2 = 0; -+ ENUM_HOST_DUMP_STATE host_state; -+ ENUM_CHIP_DUMP_STATE chip_state; -+ UINT32 dump_phy_addr = 0; -+ UINT8 *dump_vir_addr = NULL; -+ UINT32 dump_len = 0; -+ UINT32 isEnd = 0; -+ -+ host_state = (ENUM_HOST_DUMP_STATE)wmt_plat_get_dump_info( -+ p_ecsi->p_ecso->emi_apmem_ctrl_host_sync_state); -+ if (STP_HOST_DUMP_NOT_START == host_state) { -+ counter++; -+ STP_BTM_INFO_FUNC("counter(%d)\n", counter); -+ osal_sleep_ms(100); -+ } else { -+ counter = 0; -+ } -+ while (1) { -+ chip_state = (ENUM_CHIP_DUMP_STATE)wmt_plat_get_dump_info( -+ p_ecsi->p_ecso->emi_apmem_ctrl_chip_sync_state); -+ if (STP_CHIP_DUMP_PUT_DONE == chip_state) { -+ STP_BTM_INFO_FUNC("chip put done\n"); -+ break; -+ } -+ STP_BTM_INFO_FUNC("waiting chip put done\n"); -+ STP_BTM_INFO_FUNC("chip_state: %d\n", chip_state); -+ loop_cnt1++; -+ osal_sleep_ms(5); -+ -+ if (loop_cnt1 > 10) -+ goto paged_dump_end; -+ -+ } -+ -+ wmt_plat_set_host_dump_state(STP_HOST_DUMP_GET); -+ -+ dump_phy_addr = wmt_plat_get_dump_info( -+ p_ecsi->p_ecso->emi_apmem_ctrl_chip_sync_addr); -+ -+ if (!dump_phy_addr) { -+ STP_BTM_ERR_FUNC("get paged dump phy address fail\n"); -+ ret = -1; -+ break; -+ } -+ -+ dump_vir_addr = wmt_plat_get_emi_virt_add(dump_phy_addr - p_ecsi->emi_phy_addr); -+ if (!dump_vir_addr) { -+ STP_BTM_ERR_FUNC("get paged dump phy address fail\n"); -+ ret = -2; -+ break; -+ } -+ dump_len = wmt_plat_get_dump_info( -+ p_ecsi->p_ecso->emi_apmem_ctrl_chip_sync_len); -+ STP_BTM_INFO_FUNC("dump_phy_ddr(%08x),dump_vir_add(0x%p),dump_len(%d)\n", -+ dump_phy_addr, dump_vir_addr, dump_len); -+ -+ /*move dump info according to dump_addr & dump_len */ -+#if 1 -+ osal_memcpy(&g_paged_dump_buffer[0], dump_vir_addr, dump_len); -+ _stp_dump_emi_dump_buffer(&g_paged_dump_buffer[0], dump_len); -+ -+ if (0 == page_counter) { /* do fw assert infor paser in first paged dump */ -+ if (1 == stp_dbg_get_host_trigger_assert()) -+ issue_type = STP_HOST_TRIGGER_FW_ASSERT; -+ -+ ret = stp_dbg_set_fw_info(&g_paged_dump_buffer[0], 512, issue_type); -+ if (ret) { -+ STP_BTM_ERR_FUNC("set fw issue infor fail(%d),maybe fw warm reset...\n", ret); -+ stp_dbg_set_fw_info("Fw Warm reset", osal_strlen("Fw Warm reset"), -+ STP_FW_WARM_RST_ISSUE); -+ } -+ } -+ -+ if (dump_len <= 32 * 1024) { -+ pr_err("g_coredump_mode: %d!\n", g_coredump_mode); -+ if (1 == g_coredump_mode) -+ ret = stp_dbg_aee_send(&g_paged_dump_buffer[0], dump_len, 0); -+ else if (2 == g_coredump_mode) -+ ret = _stp_btm_put_emi_dump_to_nl(&g_paged_dump_buffer[0], dump_len); -+ else{ -+ STP_BTM_INFO_FUNC("coredump is disabled!\n"); -+ return 0; -+ } -+ if (ret == 0) -+ STP_BTM_INFO_FUNC("aee send ok!\n"); -+ else if (ret == 1) -+ STP_BTM_INFO_FUNC("aee send fisish!\n"); -+ else -+ STP_BTM_ERR_FUNC("aee send error!\n"); -+ } else -+ STP_BTM_ERR_FUNC("dump len is over than 32K(%d)\n", dump_len); -+ -+ g_paged_dump_len += dump_len; -+ STP_BTM_INFO_FUNC("dump len update(%d)\n", g_paged_dump_len); -+#endif -+ wmt_plat_update_host_sync_num(); -+ wmt_plat_set_host_dump_state(STP_HOST_DUMP_GET_DONE); -+ -+ STP_BTM_INFO_FUNC("host sync num(%d),chip sync num(%d)\n", -+ wmt_plat_get_dump_info( -+ p_ecsi->p_ecso->emi_apmem_ctrl_host_sync_num), -+ wmt_plat_get_dump_info( -+ p_ecsi->p_ecso->emi_apmem_ctrl_chip_sync_num)); -+ -+ page_counter++; -+ STP_BTM_INFO_FUNC("\n\n++ paged dump counter(%d) ++\n\n\n", page_counter); -+ -+ while (1) { -+ chip_state = (ENUM_CHIP_DUMP_STATE)wmt_plat_get_dump_info( -+ p_ecsi->p_ecso->emi_apmem_ctrl_chip_sync_state); -+ if (STP_CHIP_DUMP_END == chip_state) { -+ STP_BTM_INFO_FUNC("chip put end\n"); -+ wmt_plat_set_host_dump_state(STP_HOST_DUMP_END); -+ break; -+ } -+ STP_BTM_INFO_FUNC("waiting chip put end\n"); -+ -+ loop_cnt2++; -+ osal_sleep_ms(10); -+ -+ if (loop_cnt2 > 10) -+ goto paged_dump_end; -+ } -+ -+paged_dump_end: -+ wmt_plat_set_host_dump_state(STP_HOST_DUMP_NOT_START); -+ -+ if (counter > packet_num) { -+ isEnd = wmt_plat_get_dump_info( -+ p_ecsi->p_ecso->emi_apmem_ctrl_chip_paded_dump_end); -+ -+ if (isEnd) { -+ STP_BTM_INFO_FUNC("paged dump end\n"); -+ -+ STP_BTM_INFO_FUNC("\n\n paged dump print ++\n\n"); -+ _stp_dump_emi_dump_buffer(&g_paged_dump_buffer[0], g_paged_dump_len); -+ STP_BTM_INFO_FUNC("\n\n paged dump print --\n\n"); -+ STP_BTM_INFO_FUNC("\n\n paged dump size = %d, paged dump page number = %d\n\n", -+ g_paged_dump_len, page_counter); -+ counter = 0; -+ ret = 0; -+ } else { -+ STP_BTM_ERR_FUNC("paged dump fail\n"); -+ wmt_plat_set_host_dump_state(STP_HOST_DUMP_NOT_START); -+ stp_dbg_poll_cpupcr(5, 5, 0); -+ stp_dbg_poll_dmaregs(5, 1); -+ counter = 0; -+ ret = -1; -+ } -+ break; -+ } -+ -+ } while (1); -+ -+ break; -+ -+ case STP_OPID_BTM_FULL_DUMP: -+ -+ wmt_plat_set_host_dump_state(STP_HOST_DUMP_NOT_START); -+ do { -+ UINT32 loop_cnt1 = 0; -+ UINT32 loop_cnt2 = 0; -+ ENUM_CHIP_DUMP_STATE chip_state; -+ UINT32 dump_phy_addr = 0; -+ UINT8 *dump_vir_addr = NULL; -+ UINT32 dump_len = 0; -+ UINT32 isFail = 0; -+ -+ while (1) { -+ chip_state = (ENUM_CHIP_DUMP_STATE)wmt_plat_get_dump_info( -+ p_ecsi->p_ecso->emi_apmem_ctrl_chip_sync_state); -+ if (STP_CHIP_DUMP_PUT_DONE == chip_state) -+ break; -+ -+ loop_cnt1++; -+ osal_sleep_ms(10); -+ -+ if (loop_cnt1 > 10) { -+ isFail = 1; -+ goto full_dump_end; -+ } -+ } -+ -+ wmt_plat_set_host_dump_state(STP_HOST_DUMP_GET); -+ -+ dump_phy_addr = wmt_plat_get_dump_info(p_ecsi->p_ecso->emi_apmem_ctrl_chip_sync_addr); -+ if (!dump_phy_addr) { -+ STP_BTM_ERR_FUNC("get phy dump address fail\n"); -+ ret = -1; -+ break; -+ } -+ -+ dump_vir_addr = wmt_plat_get_emi_virt_add(dump_phy_addr - p_ecsi->emi_phy_addr); -+ if (!dump_vir_addr) { -+ STP_BTM_ERR_FUNC("get vir dump address fail\n"); -+ ret = -2; -+ break; -+ } -+ dump_len = wmt_plat_get_dump_info(p_ecsi->p_ecso->emi_apmem_ctrl_chip_sync_len); -+ /*move dump info according to dump_addr & dump_len */ -+ wmt_plat_update_host_sync_num(); -+ wmt_plat_set_host_dump_state(STP_HOST_DUMP_GET_DONE); -+ -+ STP_BTM_INFO_FUNC("host sync num(%d),chip sync num(%d)\n", -+ wmt_plat_get_dump_info( -+ p_ecsi->p_ecso->emi_apmem_ctrl_host_sync_num), -+ wmt_plat_get_dump_info( -+ p_ecsi->p_ecso->emi_apmem_ctrl_chip_sync_num)); -+ -+ while (1) { -+ chip_state = (ENUM_CHIP_DUMP_STATE)wmt_plat_get_dump_info( -+ p_ecsi->p_ecso->emi_apmem_ctrl_chip_sync_state); -+ if (STP_CHIP_DUMP_END == chip_state) { -+ wmt_plat_set_host_dump_state(STP_HOST_DUMP_END); -+ break; -+ } -+ loop_cnt2++; -+ osal_sleep_ms(10); -+ -+ if (loop_cnt2 > 10) { -+ isFail = 1; -+ goto full_dump_end; -+ } -+ } -+ wmt_plat_set_host_dump_state(STP_HOST_DUMP_NOT_START); -+full_dump_end: -+ if (isFail) { -+ STP_BTM_ERR_FUNC("full dump fail\n"); -+ wmt_plat_set_host_dump_state(STP_HOST_DUMP_NOT_START); -+ ret = -1; -+ break; -+ } -+ } while (--full_dump_left > 0); -+ if (0 == full_dump_left) { -+ STP_BTM_INFO_FUNC("full dump end\n"); -+ ret = 0; -+ } -+ break; -+ case STP_OPID_BTM_PAGED_TRACE: -+ g_paged_trace_len = 0; -+ do { -+ UINT32 ctrl_val = 0; -+ UINT32 loop_cnt1 = 0; -+ UINT32 buffer_start = 0; -+ UINT32 buffer_idx = 0; -+ UINT8 *dump_vir_addr = NULL; -+ -+ while (loop_cnt1 < 10) { -+ ctrl_val = wmt_plat_get_dump_info(p_ecsi->p_ecso->emi_apmem_ctrl_state); -+ if (0x8 == ctrl_val) -+ break; -+ osal_sleep_ms(10); -+ loop_cnt1++; -+ } -+ -+ if (loop_cnt1 >= 10) { -+ STP_BTM_ERR_FUNC("polling CTRL STATE fail\n"); -+ ret = -1; -+ break; -+ } -+ -+ buffer_start = wmt_plat_get_dump_info( -+ p_ecsi->p_ecso->emi_apmem_ctrl_chip_print_buff_start); -+ buffer_idx = wmt_plat_get_dump_info( -+ p_ecsi->p_ecso->emi_apmem_ctrl_chip_print_buff_idx); -+ /* buffer_len = buffer_idx - buffer_start; */ -+ g_paged_trace_len = buffer_idx; -+ STP_BTM_INFO_FUNC("paged trace buffer addr(%08x),buffer_len(%d)\n", buffer_start, buffer_idx); -+ dump_vir_addr = wmt_plat_get_emi_virt_add(buffer_start - p_ecsi->emi_phy_addr); -+ if (!dump_vir_addr) { -+ STP_BTM_ERR_FUNC("get vir dump address fail\n"); -+ ret = -2; -+ break; -+ } -+ osal_memcpy(&g_paged_trace_buffer[0], dump_vir_addr, -+ buffer_idx < STP_DBG_PAGED_TRACE_SIZE ? buffer_idx : STP_DBG_PAGED_TRACE_SIZE); -+ /*moving paged trace according to buffer_start & buffer_len */ -+ do { -+ int i = 0; -+ int dump_len = 0; -+ -+ dump_len = -+ buffer_idx < STP_DBG_PAGED_TRACE_SIZE ? buffer_idx : STP_DBG_PAGED_TRACE_SIZE; -+ pr_warn("\n\n -- paged trace hex output --\n\n"); -+ for (i = 0; i < dump_len; i++) { -+ if (i % 16 == 0) -+ pr_cont("\n"); -+ -+ pr_cont("%02x ", g_paged_trace_buffer[i]); -+ } -+ pr_warn("\n\n -- paged trace ascii output --\n\n"); -+ for (i = 0; i < dump_len; i++) { -+ if (i % 64 == 0) -+ pr_cont("\n"); -+ pr_cont("%c", g_paged_trace_buffer[i]); -+ } -+ } while (0); -+ /*move parser fw assert infor to paged dump in the one paged dump */ -+ /* ret = stp_dbg_set_fw_info(&g_paged_trace_buffer[0],g_paged_trace_len,issue_type); */ -+ ret = 0; -+ -+ } while (0); -+ mtk_wcn_stp_ctx_restore(); -+ break; -+ -+#if CFG_WMT_LTE_COEX_HANDLING -+ case STP_OPID_BTM_WMT_LTE_COEX: -+ ret = wmt_idc_msg_to_lte_handing(); -+ break; -+#endif -+ default: -+ ret = -1; -+ break; -+ } -+ -+ return ret; -+} -+ -+static P_OSAL_OP _stp_btm_get_op(MTKSTP_BTM_T *stp_btm, P_OSAL_OP_Q pOpQ) -+{ -+ P_OSAL_OP pOp; -+ /* INT32 ret = 0; */ -+ -+ if (!pOpQ) { -+ STP_BTM_WARN_FUNC("!pOpQ\n"); -+ return NULL; -+ } -+ -+ osal_lock_unsleepable_lock(&(stp_btm->wq_spinlock)); -+ /* acquire lock success */ -+ RB_GET(pOpQ, pOp); -+ osal_unlock_unsleepable_lock(&(stp_btm->wq_spinlock)); -+ -+ if (!pOp) -+ STP_BTM_WARN_FUNC("RB_GET fail\n"); -+ -+ return pOp; -+} -+ -+static INT32 _stp_btm_put_op(MTKSTP_BTM_T *stp_btm, P_OSAL_OP_Q pOpQ, P_OSAL_OP pOp) -+{ -+ INT32 ret; -+ -+ if (!pOpQ || !pOp) { -+ STP_BTM_WARN_FUNC("invalid input param: 0x%p, 0x%p\n", pOpQ, pOp); -+ return 0; /* ;MTK_WCN_BOOL_FALSE; */ -+ } -+ -+ ret = 0; -+ -+ osal_lock_unsleepable_lock(&(stp_btm->wq_spinlock)); -+ /* acquire lock success */ -+ if (!RB_FULL(pOpQ)) -+ RB_PUT(pOpQ, pOp); -+ else -+ ret = -1; -+ -+ osal_unlock_unsleepable_lock(&(stp_btm->wq_spinlock)); -+ -+ if (ret) { -+ STP_BTM_WARN_FUNC("RB_FULL(0x%p) %d ,rFreeOpQ = %p, rActiveOpQ = %p\n", -+ pOpQ, -+ RB_COUNT(pOpQ), -+ &stp_btm->rFreeOpQ, -+ &stp_btm->rActiveOpQ); -+ return 0; -+ } -+ /* STP_BTM_WARN_FUNC("RB_COUNT = %d\n",RB_COUNT(pOpQ)); */ -+ return 1; -+ -+} -+ -+P_OSAL_OP _stp_btm_get_free_op(MTKSTP_BTM_T *stp_btm) -+{ -+ P_OSAL_OP pOp; -+ -+ if (stp_btm) { -+ pOp = _stp_btm_get_op(stp_btm, &stp_btm->rFreeOpQ); -+ if (pOp) -+ osal_memset(&pOp->op, 0, sizeof(pOp->op)); -+ -+ return pOp; -+ } else -+ return NULL; -+} -+ -+INT32 _stp_btm_put_act_op(MTKSTP_BTM_T *stp_btm, P_OSAL_OP pOp) -+{ -+ INT32 bRet = 0; -+ INT32 bCleanup = 0; -+ long wait_ret = -1; -+ -+ P_OSAL_SIGNAL pSignal = NULL; -+ -+ if (!stp_btm || !pOp) { -+ STP_BTM_ERR_FUNC("Input NULL pointer\n"); -+ return bRet; -+ } -+ do { -+ pSignal = &pOp->signal; -+ -+ if (pSignal->timeoutValue) { -+ pOp->result = -9; -+ osal_signal_init(&pOp->signal); -+ } -+ -+ /* put to active Q */ -+ bRet = _stp_btm_put_op(stp_btm, &stp_btm->rActiveOpQ, pOp); -+ if (0 == bRet) { -+ STP_BTM_WARN_FUNC("put active queue fail\n"); -+ bCleanup = 1; /* MTK_WCN_BOOL_TRUE; */ -+ break; -+ } -+ -+ /* wake up wmtd */ -+ osal_trigger_event(&stp_btm->STPd_event); -+ -+ if (pSignal->timeoutValue == 0) { -+ bRet = 1; /* MTK_WCN_BOOL_TRUE; */ -+ /* clean it in wmtd */ -+ break; -+ } -+ -+ /* wait result, clean it here */ -+ bCleanup = 1; /* MTK_WCN_BOOL_TRUE; */ -+ -+ /* check result */ -+ wait_ret = osal_wait_for_signal_timeout(&pOp->signal); -+ -+ STP_BTM_DBG_FUNC("wait completion:%ld\n", wait_ret); -+ if (!wait_ret) { -+ STP_BTM_ERR_FUNC("wait completion timeout\n"); -+ /* TODO: how to handle it? retry? */ -+ } else { -+ if (pOp->result) -+ STP_BTM_WARN_FUNC("op(%d) result:%d\n", pOp->op.opId, pOp->result); -+ -+ bRet = (pOp->result) ? 0 : 1; -+ } -+ } while (0); -+ -+ if (bCleanup) { -+ /* put Op back to freeQ */ -+ _stp_btm_put_op(stp_btm, &stp_btm->rFreeOpQ, pOp); -+ } -+ bRet = (pOp->result) ? 0 : 1; -+ return bRet; -+} -+ -+static INT32 _stp_btm_wait_for_msg(void *pvData) -+{ -+ MTKSTP_BTM_T *stp_btm = (MTKSTP_BTM_T *) pvData; -+ -+ return (!RB_EMPTY(&stp_btm->rActiveOpQ)) || osal_thread_should_stop(&stp_btm->BTMd); -+} -+ -+static INT32 _stp_btm_proc(void *pvData) -+{ -+ MTKSTP_BTM_T *stp_btm = (MTKSTP_BTM_T *) pvData; -+ P_OSAL_OP pOp; -+ INT32 id; -+ INT32 result; -+ -+ if (!stp_btm) { -+ STP_BTM_WARN_FUNC("!stp_btm\n"); -+ return -1; -+ } -+ -+ for (;;) { -+ pOp = NULL; -+ -+ osal_wait_for_event(&stp_btm->STPd_event, _stp_btm_wait_for_msg, (void *)stp_btm); -+ -+ if (osal_thread_should_stop(&stp_btm->BTMd)) { -+ STP_BTM_INFO_FUNC("should stop now...\n"); -+ /* TODO: clean up active opQ */ -+ break; -+ } -+ -+ /* get Op from activeQ */ -+ pOp = _stp_btm_get_op(stp_btm, &stp_btm->rActiveOpQ); -+ -+ if (!pOp) { -+ STP_BTM_WARN_FUNC("get_lxop activeQ fail\n"); -+ continue; -+ } -+ -+ id = osal_op_get_id(pOp); -+ -+ STP_BTM_DBG_FUNC("======> lxop_get_opid = %d, %s, remaining count = *%d*\n", -+ id, (id >= osal_array_size(g_btm_op_name)) ? ("???") : (g_btm_op_name[id]), -+ RB_COUNT(&stp_btm->rActiveOpQ)); -+ -+ if (id >= STP_OPID_BTM_NUM) { -+ STP_BTM_WARN_FUNC("abnormal opid id: 0x%x\n", id); -+ result = -1; -+ goto handler_done; -+ } -+ -+ result = _stp_btm_handler(stp_btm, &pOp->op); -+ -+handler_done: -+ -+ if (result) { -+ STP_BTM_WARN_FUNC("opid id(0x%x)(%s) error(%d)\n", id, -+ (id >= osal_array_size(g_btm_op_name)) ? ("???") : (g_btm_op_name[id]), -+ result); -+ } -+ -+ if (osal_op_is_wait_for_signal(pOp)) { -+ osal_op_raise_signal(pOp, result); -+ } else { -+ /* put Op back to freeQ */ -+ _stp_btm_put_op(stp_btm, &stp_btm->rFreeOpQ, pOp); -+ } -+ -+ if (STP_OPID_BTM_EXIT == id) { -+ break; -+ } else if (STP_OPID_BTM_RST == id) { -+ /* prevent multi reset case */ -+ stp_btm_reset_btm_wq(stp_btm); -+ mtk_wcn_stp_coredump_start_ctrl(0); -+ } -+ } -+ -+ STP_BTM_INFO_FUNC("exits\n"); -+ -+ return 0; -+}; -+ -+static inline INT32 _stp_btm_notify_wmt_rst_wq(MTKSTP_BTM_T *stp_btm) -+{ -+ -+ P_OSAL_OP pOp; -+ INT32 bRet; -+ INT32 retval; -+ -+ if (stp_btm == NULL) -+ return STP_BTM_OPERATION_FAIL; -+ -+ pOp = _stp_btm_get_free_op(stp_btm); -+ if (!pOp) { -+ STP_BTM_WARN_FUNC("get_free_lxop fail\n"); -+ return -1; /* break; */ -+ } -+ pOp->op.opId = STP_OPID_BTM_RST; -+ pOp->signal.timeoutValue = 0; -+ bRet = _stp_btm_put_act_op(stp_btm, pOp); -+ STP_BTM_DBG_FUNC("OPID(%d) type(%zd) bRet(%d)\n\n", pOp->op.opId, pOp->op.au4OpData[0], bRet); -+ retval = (0 == bRet) ? STP_BTM_OPERATION_FAIL : STP_BTM_OPERATION_SUCCESS; -+ -+ return retval; -+} -+ -+static inline INT32 _stp_btm_notify_stp_retry_wq(MTKSTP_BTM_T *stp_btm) -+{ -+ -+ P_OSAL_OP pOp; -+ INT32 bRet; -+ INT32 retval; -+ -+ if (stp_btm == NULL) -+ return STP_BTM_OPERATION_FAIL; -+ -+ pOp = _stp_btm_get_free_op(stp_btm); -+ if (!pOp) { -+ STP_BTM_WARN_FUNC("get_free_lxop fail\n"); -+ return -1; /* break; */ -+ } -+ pOp->op.opId = STP_OPID_BTM_RETRY; -+ pOp->signal.timeoutValue = 0; -+ bRet = _stp_btm_put_act_op(stp_btm, pOp); -+ STP_BTM_DBG_FUNC("OPID(%d) type(%zd) bRet(%d)\n\n", pOp->op.opId, pOp->op.au4OpData[0], bRet); -+ retval = (0 == bRet) ? STP_BTM_OPERATION_FAIL : STP_BTM_OPERATION_SUCCESS; -+ -+ return retval; -+} -+ -+static inline INT32 _stp_btm_notify_coredump_timeout_wq(MTKSTP_BTM_T *stp_btm) -+{ -+ -+ P_OSAL_OP pOp; -+ INT32 bRet; -+ INT32 retval; -+ -+ if (!stp_btm) -+ return STP_BTM_OPERATION_FAIL; -+ -+ pOp = _stp_btm_get_free_op(stp_btm); -+ if (!pOp) { -+ STP_BTM_WARN_FUNC("get_free_lxop fail\n"); -+ return -1; /* break; */ -+ } -+ pOp->op.opId = STP_OPID_BTM_DUMP_TIMEOUT; -+ pOp->signal.timeoutValue = 0; -+ bRet = _stp_btm_put_act_op(stp_btm, pOp); -+ STP_BTM_DBG_FUNC("OPID(%d) type(%zd) bRet(%d)\n\n", pOp->op.opId, pOp->op.au4OpData[0], bRet); -+ retval = (0 == bRet) ? STP_BTM_OPERATION_FAIL : STP_BTM_OPERATION_SUCCESS; -+ -+ return retval; -+} -+ -+static inline INT32 _stp_btm_dump_type(MTKSTP_BTM_T *stp_btm, ENUM_STP_BTM_OPID_T opid) -+{ -+ P_OSAL_OP pOp; -+ INT32 bRet; -+ INT32 retval; -+ -+ pOp = _stp_btm_get_free_op(stp_btm); -+ if (!pOp) { -+ STP_BTM_WARN_FUNC("get_free_lxop fail\n"); -+ return -1; /* break; */ -+ } -+ -+ pOp->op.opId = opid; -+ pOp->signal.timeoutValue = 0; -+ bRet = _stp_btm_put_act_op(stp_btm, pOp); -+ STP_BTM_DBG_FUNC("OPID(%d) type(%zd) bRet(%d)\n\n", pOp->op.opId, pOp->op.au4OpData[0], bRet); -+ retval = (0 == bRet) ? STP_BTM_OPERATION_FAIL : STP_BTM_OPERATION_SUCCESS; -+ -+ return retval; -+} -+ -+static inline INT32 _stp_btm_notify_wmt_dmp_wq(MTKSTP_BTM_T *stp_btm) -+{ -+ -+ INT32 retval; -+#if 0 -+ UINT32 dump_type; -+ UINT8 *virtual_addr = NULL; -+#endif -+ if (stp_btm == NULL) -+ return STP_BTM_OPERATION_FAIL; -+ -+#if 1 /* Paged dump */ -+ STP_BTM_INFO_FUNC("paged dump start++\n"); -+ retval = _stp_btm_dump_type(stp_btm, STP_OPID_BTM_PAGED_DUMP); -+ if (retval) -+ STP_BTM_ERR_FUNC("paged dump fail\n"); -+#else -+ virtual_addr = wmt_plat_get_emi_virt_add(EXP_APMEM_CTRL_CHIP_SYNC_ADDR); -+ if (!virtual_addr) { -+ STP_BTM_ERR_FUNC("get dump type virtual addr fail\n"); -+ return -1; -+ } -+ dump_type = CONSYS_REG_READ(virtual_addr); -+ STP_BTM_INFO_FUNC("dump type:%08x\n", dump_type); -+ -+ if ((dump_type & 0xfffff) == (CONSYS_PAGED_DUMP_START_ADDR & 0xfffff)) { -+ STP_BTM_INFO_FUNC("do paged dump\n"); -+ retval = _stp_btm_dump_type(stp_btm, STP_OPID_BTM_PAGED_DUMP); -+ if (retval) { -+ STP_BTM_ERR_FUNC("paged dump fail,do full dump\n"); -+ _stp_btm_dump_type(stp_btm, STP_OPID_BTM_FULL_DUMP); -+ } -+ } else if ((dump_type & 0xfffff) == (CONSYS_FULL_DUMP_START_ADDR & 0xfffff)) { -+ STP_BTM_INFO_FUNC("do full dump\n"); -+ retval = _stp_btm_dump_type(stp_btm, STP_OPID_BTM_FULL_DUMP); -+ } else { -+ STP_BTM_INFO_FUNC("do normal dump\n"); -+ retval = _stp_btm_dump_type(stp_btm, STP_OPID_BTM_DBG_DUMP); -+ } -+#endif -+ -+ return retval; -+} -+ -+static inline INT32 _stp_notify_btm_poll_cpupcr(MTKSTP_BTM_T *stp_btm, UINT32 times, UINT32 sleep) -+{ -+ -+ P_OSAL_OP pOp; -+ INT32 bRet; -+ INT32 retval; -+ -+ if (stp_btm == NULL) -+ return STP_BTM_OPERATION_FAIL; -+ -+ pOp = _stp_btm_get_free_op(stp_btm); -+ if (!pOp) { -+ /* STP_BTM_WARN_FUNC("get_free_lxop fail\n"); */ -+ return -1; /* break; */ -+ } -+ pOp->op.opId = STP_OPID_BTM_POLL_CPUPCR; -+ pOp->signal.timeoutValue = 0; -+ pOp->op.au4OpData[0] = times; -+ pOp->op.au4OpData[1] = sleep; -+ bRet = _stp_btm_put_act_op(stp_btm, pOp); -+ STP_BTM_DBG_FUNC("OPID(%d) type(%zd) bRet(%d)\n\n", pOp->op.opId, pOp->op.au4OpData[0], bRet); -+ retval = (0 == bRet) ? STP_BTM_OPERATION_FAIL : STP_BTM_OPERATION_SUCCESS; -+ -+ return retval; -+} -+ -+static inline INT32 _stp_btm_notify_wmt_trace_wq(MTKSTP_BTM_T *stp_btm) -+{ -+ P_OSAL_OP pOp; -+ INT32 bRet; -+ INT32 retval; -+ -+ if (stp_btm == NULL) -+ return STP_BTM_OPERATION_FAIL; -+ -+ pOp = _stp_btm_get_free_op(stp_btm); -+ if (!pOp) { -+ /* STP_BTM_WARN_FUNC("get_free_lxop fail\n"); */ -+ return -1; /* break; */ -+ } -+ pOp->op.opId = STP_OPID_BTM_PAGED_TRACE; -+ pOp->signal.timeoutValue = 0; -+ bRet = _stp_btm_put_act_op(stp_btm, pOp); -+ STP_BTM_DBG_FUNC("OPID(%d) type(%zd) bRet(%d)\n\n", pOp->op.opId, pOp->op.au4OpData[0], bRet); -+ retval = (0 == bRet) ? STP_BTM_OPERATION_FAIL : STP_BTM_OPERATION_SUCCESS; -+ -+ return retval; -+} -+ -+static inline INT32 _stp_btm_do_fw_assert_via_emi(MTKSTP_BTM_T *stp_btm) -+{ -+ INT32 ret = -1; -+ -+ ret = _stp_trigger_firmware_assert_via_emi(); -+ -+ return ret; -+ -+} -+ -+INT32 stp_btm_notify_wmt_rst_wq(MTKSTP_BTM_T *stp_btm) -+{ -+ return _stp_btm_notify_wmt_rst_wq(stp_btm); -+} -+ -+INT32 stp_btm_notify_stp_retry_wq(MTKSTP_BTM_T *stp_btm) -+{ -+ return _stp_btm_notify_stp_retry_wq(stp_btm); -+} -+ -+INT32 stp_btm_notify_coredump_timeout_wq(MTKSTP_BTM_T *stp_btm) -+{ -+ return _stp_btm_notify_coredump_timeout_wq(stp_btm); -+} -+ -+INT32 stp_btm_notify_wmt_dmp_wq(MTKSTP_BTM_T *stp_btm) -+{ -+ return _stp_btm_notify_wmt_dmp_wq(stp_btm); -+} -+ -+INT32 stp_btm_notify_wmt_trace_wq(MTKSTP_BTM_T *stp_btm) -+{ -+ return _stp_btm_notify_wmt_trace_wq(stp_btm); -+} -+ -+INT32 stp_notify_btm_poll_cpupcr(MTKSTP_BTM_T *stp_btm, UINT32 times, UINT32 sleep) -+{ -+ return _stp_notify_btm_poll_cpupcr(stp_btm, times, sleep); -+} -+ -+INT32 stp_notify_btm_poll_cpupcr_ctrl(UINT32 en) -+{ -+ return stp_dbg_poll_cuppcr_ctrl(en); -+} -+ -+INT32 stp_notify_btm_do_fw_assert_via_emi(MTKSTP_BTM_T *stp_btm) -+{ -+ INT32 ret = -1; -+#if BTIF_RXD_BE_BLOCKED_DETECT -+ if (is_btif_rxd_be_blocked()) -+ ret = wcn_btif_rxd_blocked_collect_ftrace(); /* trigger collect SYS_FTRACE */ -+ else -+#endif -+ ret = _stp_btm_do_fw_assert_via_emi(stp_btm); -+ return ret; -+} -+ -+#if CFG_WMT_LTE_COEX_HANDLING -+ -+static inline INT32 _stp_notify_btm_handle_wmt_lte_coex(MTKSTP_BTM_T *stp_btm) -+{ -+ P_OSAL_OP pOp; -+ INT32 bRet; -+ INT32 retval; -+ -+ if (stp_btm == NULL) -+ return STP_BTM_OPERATION_FAIL; -+ -+ pOp = _stp_btm_get_free_op(stp_btm); -+ if (!pOp) { -+ /* STP_BTM_WARN_FUNC("get_free_lxop fail\n"); */ -+ return -1; /* break; */ -+ } -+ pOp->op.opId = STP_OPID_BTM_WMT_LTE_COEX; -+ pOp->signal.timeoutValue = 0; -+ bRet = _stp_btm_put_act_op(stp_btm, pOp); -+ STP_BTM_DBG_FUNC("OPID(%d) type(%zd) bRet(%d)\n\n", pOp->op.opId, pOp->op.au4OpData[0], bRet); -+ retval = (0 == bRet) ? STP_BTM_OPERATION_FAIL : STP_BTM_OPERATION_SUCCESS; -+ -+ return retval; -+} -+ -+INT32 stp_notify_btm_handle_wmt_lte_coex(MTKSTP_BTM_T *stp_btm) -+{ -+ return _stp_notify_btm_handle_wmt_lte_coex(stp_btm); -+} -+ -+#endif -+MTKSTP_BTM_T *stp_btm_init(void) -+{ -+ INT32 i = 0x0; -+ INT32 ret = -1; -+ -+ osal_unsleepable_lock_init(&stp_btm->wq_spinlock); -+ osal_event_init(&stp_btm->STPd_event); -+ stp_btm->wmt_notify = wmt_lib_btm_cb; -+ -+ RB_INIT(&stp_btm->rFreeOpQ, STP_BTM_OP_BUF_SIZE); -+ RB_INIT(&stp_btm->rActiveOpQ, STP_BTM_OP_BUF_SIZE); -+ -+ /* Put all to free Q */ -+ for (i = 0; i < STP_BTM_OP_BUF_SIZE; i++) { -+ osal_signal_init(&(stp_btm->arQue[i].signal)); -+ _stp_btm_put_op(stp_btm, &stp_btm->rFreeOpQ, &(stp_btm->arQue[i])); -+ } -+ -+ /*Generate PSM thread, to servie STP-CORE for packet retrying and core dump receiving */ -+ stp_btm->BTMd.pThreadData = (VOID *) stp_btm; -+ stp_btm->BTMd.pThreadFunc = (VOID *) _stp_btm_proc; -+ osal_memcpy(stp_btm->BTMd.threadName, BTM_THREAD_NAME, osal_strlen(BTM_THREAD_NAME)); -+ -+ ret = osal_thread_create(&stp_btm->BTMd); -+ if (ret < 0) { -+ STP_BTM_ERR_FUNC("osal_thread_create fail...\n"); -+ goto ERR_EXIT1; -+ } -+ -+ /* Start STPd thread */ -+ ret = osal_thread_run(&stp_btm->BTMd); -+ if (ret < 0) { -+ STP_BTM_ERR_FUNC("osal_thread_run FAILS\n"); -+ goto ERR_EXIT1; -+ } -+ -+ return stp_btm; -+ -+ERR_EXIT1: -+ -+ return NULL; -+ -+} -+ -+INT32 stp_btm_deinit(MTKSTP_BTM_T *stp_btm) -+{ -+ -+ INT32 ret = -1; -+ -+ STP_BTM_INFO_FUNC("btm deinit\n"); -+ -+ if (!stp_btm) -+ return STP_BTM_OPERATION_FAIL; -+ -+ ret = osal_thread_destroy(&stp_btm->BTMd); -+ if (ret < 0) { -+ STP_BTM_ERR_FUNC("osal_thread_destroy FAILS\n"); -+ return STP_BTM_OPERATION_FAIL; -+ } -+ -+ return STP_BTM_OPERATION_SUCCESS; -+} -+ -+INT32 stp_btm_reset_btm_wq(MTKSTP_BTM_T *stp_btm) -+{ -+ UINT32 i = 0; -+ -+ osal_lock_unsleepable_lock(&(stp_btm->wq_spinlock)); -+ RB_INIT(&stp_btm->rFreeOpQ, STP_BTM_OP_BUF_SIZE); -+ RB_INIT(&stp_btm->rActiveOpQ, STP_BTM_OP_BUF_SIZE); -+ osal_unlock_unsleepable_lock(&(stp_btm->wq_spinlock)); -+ /* Put all to free Q */ -+ for (i = 0; i < STP_BTM_OP_BUF_SIZE; i++) { -+ osal_signal_init(&(stp_btm->arQue[i].signal)); -+ _stp_btm_put_op(stp_btm, &stp_btm->rFreeOpQ, &(stp_btm->arQue[i])); -+ } -+ -+ return 0; -+} -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/core/dbg_core.c b/drivers/misc/mediatek/connectivity/common/conn_soc/core/dbg_core.c -new file mode 100644 -index 000000000000..246448b38b31 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/core/dbg_core.c -@@ -0,0 +1,13 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/btm_core.h b/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/btm_core.h -new file mode 100644 -index 000000000000..9a429b4af1e3 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/btm_core.h -@@ -0,0 +1,133 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -+ -+/*! \file -+ \brief Declaration of library functions -+ -+ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. -+*/ -+ -+#ifndef _BTM_CORE_H -+#define _BTM_CORE_H -+ -+#include "osal_typedef.h" -+#include "osal.h" -+#include "stp_wmt.h" -+#include "wmt_plat.h" -+#include "wmt_idc.h" -+#include "mtk_btif_exp.h" -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+#define STP_BTM_OPERATION_FAIL (-1) -+#define STP_BTM_OPERATION_SUCCESS (0) -+ -+#define STP_BTM_OP_BUF_SIZE (64) -+ -+#define BTM_THREAD_NAME "mtk_stp_btm" -+ -+#define STP_PAGED_DUMP_TIME_LIMIT 3500 -+#define STP_FULL_DUMP_TIME 3 -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+typedef enum _ENUM_STP_BTM_OPID_T { -+ STP_OPID_BTM_RETRY = 0x0, -+ STP_OPID_BTM_RST = 0x1, -+ STP_OPID_BTM_DBG_DUMP = 0x2, -+ STP_OPID_BTM_DUMP_TIMEOUT = 0x3, -+ STP_OPID_BTM_POLL_CPUPCR = 0x4, -+ STP_OPID_BTM_PAGED_DUMP = 0x5, -+ STP_OPID_BTM_FULL_DUMP = 0x6, -+ STP_OPID_BTM_PAGED_TRACE = 0x7, -+ STP_OPID_BTM_FORCE_FW_ASSERT = 0x8, -+#if CFG_WMT_LTE_COEX_HANDLING -+ STP_OPID_BTM_WMT_LTE_COEX = 0x9, -+#endif -+ STP_OPID_BTM_EXIT, -+ STP_OPID_BTM_NUM -+} ENUM_STP_BTM_OPID_T, *P_ENUM_STP_BTM_OPID_T; -+ -+typedef OSAL_OP_DAT STP_BTM_OP; -+typedef P_OSAL_OP_DAT P_STP_BTM_OP; -+ -+typedef struct mtk_stp_btm { -+ OSAL_THREAD BTMd; /* main thread (wmtd) handle */ -+ OSAL_EVENT STPd_event; -+ OSAL_UNSLEEPABLE_LOCK wq_spinlock; -+ -+ OSAL_OP_Q rFreeOpQ; /* free op queue */ -+ OSAL_OP_Q rActiveOpQ; /* active op queue */ -+ OSAL_OP arQue[STP_BTM_OP_BUF_SIZE]; /* real op instances */ -+ -+ /*wmt_notify */ -+ INT32 (*wmt_notify)(MTKSTP_BTM_WMT_OP_T); -+} MTKSTP_BTM_T; -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+INT32 stp_btm_notify_wmt_rst_wq(MTKSTP_BTM_T *stp_btm); -+INT32 stp_btm_notify_stp_retry_wq(MTKSTP_BTM_T *stp_btm); -+INT32 stp_btm_notify_coredump_timeout_wq(MTKSTP_BTM_T *stp_btm); -+INT32 stp_btm_notify_wmt_dmp_wq(MTKSTP_BTM_T *stp_btm); -+INT32 stp_btm_deinit(MTKSTP_BTM_T *stp_btm); -+INT32 stp_btm_reset_btm_wq(MTKSTP_BTM_T *stp_btm); -+INT32 stp_notify_btm_poll_cpupcr(MTKSTP_BTM_T *stp_btm, UINT32 times, UINT32 sleep); -+INT32 stp_notify_btm_poll_cpupcr_ctrl(UINT32 en); -+INT32 stp_btm_notify_wmt_trace_wq(MTKSTP_BTM_T *stp_btm); -+INT32 stp_notify_btm_do_fw_assert_via_emi(MTKSTP_BTM_T *stp_btm); -+INT32 stp_notify_btm_handle_wmt_lte_coex(MTKSTP_BTM_T *stp_btm); -+INT32 wcn_psm_flag_trigger_collect_ftrace(void); -+#if BTIF_RXD_BE_BLOCKED_DETECT -+INT32 wcn_btif_rxd_blocked_collect_ftrace(void); -+MTK_WCN_BOOL is_btif_rxd_be_blocked(void); -+#endif -+MTKSTP_BTM_T *stp_btm_init(void); -+extern unsigned int g_coredump_mode; -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/dbg_core.h b/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/dbg_core.h -new file mode 100644 -index 000000000000..d8c6ebe9c4b0 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/dbg_core.h -@@ -0,0 +1,69 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -+ -+/*! \file -+ \brief Declaration of library functions -+ -+ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. -+*/ -+ -+#ifndef _DBG_CORE_H -+#define _DBG_CORE_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/psm_core.h b/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/psm_core.h -new file mode 100644 -index 000000000000..fe92f25e92c1 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/psm_core.h -@@ -0,0 +1,251 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -+ -+/*! \file -+ \brief Declaration of library functions -+ -+ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. -+*/ -+ -+#ifndef _PSM_CORE_H -+#define _PSM_CORE_H -+ -+#include "osal_typedef.h" -+#include "osal.h" -+#include "stp_wmt.h" -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+#define PFX_PSM "[STP-PSM] " -+#define STP_PSM_LOG_LOUD 4 -+#define STP_PSM_LOG_DBG 3 -+#define STP_PSM_LOG_INFO 2 -+#define STP_PSM_LOG_WARN 1 -+#define STP_PSM_LOG_ERR 0 -+ -+#define ASSERT(expr) -+#define STP_PSM_FIFO_SIZE 0x2000 /* 8kbytes */ -+#define STP_PSM_TX_SIZE 0x800 /* 2kbytes */ -+ -+#define STP_PSM_OPERATION_FAIL (-1) -+#define STP_PSM_OPERATION_SUCCESS (0) -+ -+#define STP_PSM_PACKET_SIZE_MAX (2000) -+ -+#define PSM_HANDLING 127 -+ -+#define STP_PSM_WMT_PS_TASK_HANDLING_TIME 30 /* 20 milli-seconds */ -+#define STP_PSM_IDLE_TIME_SLEEP 30 /* temporary for stress testing */ -+#define STP_PSM_IDLE_TIME_SLEEP_1000 1000 /* for high speed transmission e.g. BT OPP*/ -+#define STP_PSM_SDIO_IDLE_TIME_SLEEP 100 /* temporary for SDIO stress testing */ -+#define STP_PSM_WAIT_EVENT_TIMEOUT 6000 -+#if 0 -+#define STP_PSM_WMT_EVENT_SLEEP_EN (0x1UL << 0) -+#define STP_PSM_WMT_EVENT_WAKEUP_EN (0x1UL << 1) -+#define STP_PSM_BLOCK_DATA_EN (0x1UL << 2) -+#define STP_PSM_WMT_EVENT_DISABLE_MONITOR (0x1UL << 3) -+#define STP_PSM_WMT_EVENT_ROLL_BACK_EN (0x1UL << 4) -+#define STP_PSM_RESET_EN (0x1UL << 5) -+#define STP_PSM_WMT_EVENT_HOST_WAKEUP_EN (0x1UL << 6) -+#define STP_PSM_WMT_EVENT_DISABLE_MONITOR_TX_HIGH_DENSITY (0x1UL << 7) -+#define STP_PSM_WMT_EVENT_DISABLE_MONITOR_RX_HIGH_DENSITY (0x1UL << 8) -+#endif -+ -+#define STP_PSM_WMT_EVENT_SLEEP_EN (0) -+#define STP_PSM_WMT_EVENT_WAKEUP_EN (1) -+#define STP_PSM_BLOCK_DATA_EN (2) -+#define STP_PSM_WMT_EVENT_DISABLE_MONITOR (3) -+#define STP_PSM_WMT_EVENT_ROLL_BACK_EN (4) -+#define STP_PSM_RESET_EN (5) -+#define STP_PSM_WMT_EVENT_HOST_WAKEUP_EN (6) -+#define STP_PSM_WMT_EVENT_DISABLE_MONITOR_TX_HIGH_DENSITY (7) -+#define STP_PSM_WMT_EVENT_DISABLE_MONITOR_RX_HIGH_DENSITY (8) -+ -+#define STP_PSM_DBG_SIZE (16) -+ -+/* OP command ring buffer : must be power of 2 */ -+#define STP_OP_BUF_SIZE (16) -+ -+#define PSM_THREAD_NAME "mtk_stp_psm" -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+typedef enum { -+ ACT = 0, -+ ACT_INACT, -+ INACT, -+ INACT_ACT, -+ STP_PSM_MAX_STATE, -+} MTKSTP_PSM_STATE_T; -+ -+typedef enum _ENUM_STP_OPID_T { -+ STP_OPID_PSM_SLEEP = 0, -+ STP_OPID_PSM_WAKEUP, -+ STP_OPID_PSM_HOST_AWAKE, -+ STP_OPID_PSM_EXIT, -+ STP_OPID_PSM_NUM, -+ STP_OPID_PSM_INALID = STP_OPID_PSM_NUM, -+} ENUM_STP_OPID_T, *P_ENUM_STP_OPID_T; -+ -+typedef enum { -+ MON = 0, -+ UNMON, -+} MTKSTP_PSM_MONSTATE_T; -+ -+typedef INT32(*wmt_notify_t) (MTKSTP_PSM_ACTION_T action); -+typedef INT32(*stp_tx_cb_t) (unsigned char *buffer, UINT32 length, UINT8 type); -+ -+typedef OSAL_OP_DAT STP_OP; -+typedef P_OSAL_OP_DAT P_STP_OP; -+ -+typedef struct mtk_stp_psm { -+ OSAL_THREAD PSMd; /* main thread (wmtd) handle */ -+ OSAL_EVENT STPd_event; -+ -+ OSAL_OP_Q rFreeOpQ; /* free op queue */ -+ OSAL_OP_Q rActiveOpQ; /* active op queue */ -+ OSAL_OP arQue[STP_OP_BUF_SIZE]; /* real op instances */ -+ -+ /* OSAL_OP current_active_op; */ -+ /* P_OSAL_OP current_active_op; */ -+ UINT32 last_active_opId; -+ MTKSTP_PSM_STATE_T work_state; /*working state */ -+ OSAL_BIT_OP_VAR flag; -+ -+ /* in normal cases, sleep op is always enabled; -+ * but in error cases, we can't execute sleep cmd, -+ * Eg: FW assert, core dump -+ */ -+ INT32 sleep_en; -+ -+/* OSAL_UNSLEEPABLE_LOCK flagSpinlock; */ -+ INT32 idle_time_to_sleep; -+ OSAL_WAKE_LOCK wake_lock; -+ OSAL_TIMER psm_timer; /*monitor if active */ -+ OSAL_EVENT wait_wmt_q; -+ OSAL_FIFO hold_fifo; -+ OSAL_SLEEPABLE_LOCK hold_fifo_spinlock_global; -+ OSAL_UNSLEEPABLE_LOCK wq_spinlock; -+ OSAL_SLEEPABLE_LOCK stp_psm_lock; -+ INT32 (*wmt_notify)(MTKSTP_PSM_ACTION_T action); -+ INT32 (*stp_tx_cb)(unsigned char *buffer, UINT32 length, UINT8 type); -+ -+ MTK_WCN_BOOL (*is_wmt_quick_ps_support)(VOID); -+ UINT8 out_buf[STP_PSM_TX_SIZE]; -+} MTKSTP_PSM_T; -+ -+typedef struct { -+ UINT32 prev_flag; -+ UINT32 cur_flag; -+ UINT32 line_num; -+ UINT32 package_no; -+ UINT32 sec; -+ UINT32 usec; -+ UINT32 pid; -+} STP_PSM_ENTRY_T; -+ -+typedef struct stp_psm_record { -+ STP_PSM_ENTRY_T queue[STP_PSM_DBG_SIZE]; -+ UINT32 in; -+ UINT32 out; -+ UINT32 size; -+ OSAL_UNSLEEPABLE_LOCK lock; -+} STP_PSM_RECORD_T; -+ -+typedef struct stp_psm_opid_record { -+ STP_PSM_ENTRY_T queue[STP_PSM_DBG_SIZE]; -+ UINT32 in; -+ UINT32 out; -+ UINT32 size; -+ OSAL_UNSLEEPABLE_LOCK lock; -+} STP_PSM_OPID_RECORD, *P_STP_PSM_OPID_RECORD; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+#define PSM_USE_COUNT_PACKAGE 0 -+ -+#if PSM_USE_COUNT_PACKAGE -+#define MTK_COMBO_PSM_RX_TH_DEFAULT (1600) -+#define MTK_COMBO_PSM_TX_TH_DEFAULT (300) -+INT32 stp_psm_disable_by_tx_rx_density(MTKSTP_PSM_T *stp_psm, INT32 dir); -+#else -+#define SAMPLE_DURATION 1 /*1 second */ -+#define RTX_SPEED_THRESHOLD 50000 /*50KB/s */ -+INT32 stp_psm_disable_by_tx_rx_density(MTKSTP_PSM_T *stp_psm, INT32 dir, INT32 length); -+#endif -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+/*stp-psm external function*/ -+INT32 stp_psm_notify_stp(MTKSTP_PSM_T *stp_psm, const MTKSTP_PSM_ACTION_T action); -+INT32 stp_psm_notify_wmt_wakeup(MTKSTP_PSM_T *stp_psm); -+INT32 stp_psm_notify_wmt_sleep(MTKSTP_PSM_T *stp_psm); -+ -+INT32 stp_psm_start_monitor(MTKSTP_PSM_T *stp_psm); -+INT32 stp_psm_is_to_block_traffic(MTKSTP_PSM_T *stp_psm); -+INT32 stp_psm_is_disable(MTKSTP_PSM_T *stp_psm); -+INT32 stp_psm_has_pending_data(MTKSTP_PSM_T *stp_psm); -+INT32 stp_psm_release_data(MTKSTP_PSM_T *stp_psm); -+INT32 stp_psm_hold_data(MTKSTP_PSM_T *stp_psm, const UINT8 *buffer, const UINT32 len, const UINT8 type); -+INT32 stp_psm_do_wakeup(MTKSTP_PSM_T *stp_psm); -+INT32 stp_psm_reset(MTKSTP_PSM_T *stp_psm); -+INT32 stp_psm_disable(MTKSTP_PSM_T *stp_psm); -+INT32 stp_psm_enable(MTKSTP_PSM_T *stp_psm, INT32 idle_time_to_sleep); -+struct mtk_stp_psm *stp_psm_init(void); -+INT32 stp_psm_deinit(MTKSTP_PSM_T *stp_psm); -+MTK_WCN_BOOL mtk_wcn_stp_psm_dbg_level(UINT32 dbglevel); -+INT32 stp_psm_sleep_for_thermal(MTKSTP_PSM_T *stp_psm); -+INT32 stp_psm_thread_lock_aquire(MTKSTP_PSM_T *stp_psm); -+INT32 stp_psm_thread_lock_release(MTKSTP_PSM_T *stp_psm); -+INT32 stp_psm_set_state(MTKSTP_PSM_T *stp_psm, MTKSTP_PSM_STATE_T state); -+MTK_WCN_BOOL stp_psm_is_quick_ps_support(VOID); -+ -+INT32 stp_psm_set_sleep_enable(MTKSTP_PSM_T *stp_psm); -+INT32 stp_psm_set_sleep_disable(MTKSTP_PSM_T *stp_psm); -+INT32 stp_psm_check_sleep_enable(MTKSTP_PSM_T *stp_psm); -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/stp_core.h b/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/stp_core.h -new file mode 100644 -index 000000000000..eaa5ce773e33 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/stp_core.h -@@ -0,0 +1,629 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -+ -+/*! \file -+ \brief Declaration of library functions -+ -+ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. -+*/ -+ -+#ifndef _STP_CORE_H -+#define _STP_CORE_H -+ -+#include "osal_typedef.h" -+#include "osal.h" -+#include "stp_exp.h" -+#include "psm_core.h" -+#include "btm_core.h" -+#include "stp_btif.h" -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+#define CFG_STP_CORE_CTX_SPIN_LOCK (0) -+ -+#define WMT_LTE_COEX_FLAG (0x16) -+ -+/*configure using SPINLOCK or just mutex for STP-CORE tx*/ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+#define CONFIG_POWER_SAVING_SUPPORT -+ -+#ifdef PFX -+#undef PFX -+#endif -+#define PFX "[STP] " -+ -+#define STP_LOG_DBG 4 -+#define STP_LOG_PKHEAD 3 -+#define STP_LOG_INFO 2 -+#define STP_LOG_WARN 1 -+#define STP_LOG_ERR 0 -+ -+extern unsigned int gStpDbgLvl; -+ -+#define STP_DBG_FUNC(fmt, arg...)\ -+do { \ -+ if (gStpDbgLvl >= STP_LOG_DBG) \ -+ osal_dbg_print(PFX "%s: " fmt, __func__ , ##arg); \ -+} while (0) -+#define STP_INFO_FUNC(fmt, arg...) \ -+do { \ -+ if (gStpDbgLvl >= STP_LOG_INFO) \ -+ osal_dbg_print(PFX "%s:[I] " fmt, __func__ , ##arg); \ -+} while (0) -+#define STP_WARN_FUNC(fmt, arg...) \ -+do { \ -+ if (gStpDbgLvl >= STP_LOG_WARN) \ -+ osal_warn_print(PFX "%s:[W] " fmt, __func__ , ##arg); \ -+} while (0) -+#define STP_ERR_FUNC(fmt, arg...) \ -+do { \ -+ if (gStpDbgLvl >= STP_LOG_ERR) \ -+ osal_err_print(PFX "%s:[E] " fmt, __func__ , ##arg); \ -+} while (0) -+#define STP_TRC_FUNC(f) \ -+do { \ -+ if (gStpDbgLvl >= STP_LOG_DBG) \ -+ osal_dbg_print(PFX "<%s> <%d>\n", __func__, __LINE__); \ -+} while (0) -+ -+#define STP_DUMP_PACKET_HEAD(a, b, c) \ -+do { \ -+ if (gStpDbgLvl >= STP_LOG_PKHEAD) \ -+ stp_dump_data(a, b, c); \ -+} while (0) -+#define STP_TRACE_FUNC(fmt, arg...) \ -+do { \ -+ if (gStpDbgLvl >= STP_LOG_DBG) \ -+ osal_dbg_print(PFX "%s: " fmt, __func__ , ##arg); \ -+} while (0) -+ -+#define STP_MODE_BIT(x) (0x1UL << x) -+#define MTKSTP_UART_FULL_MODE STP_MODE_BIT(0) -+#define MTKSTP_UART_MAND_MODE STP_MODE_BIT(1) -+#define MTKSTP_BTIF_FULL_MODE STP_MODE_BIT(2) -+#define MTKSTP_BTIF_MAND_MODE STP_MODE_BIT(3) -+#define MTKSTP_SDIO_MODE STP_MODE_BIT(4) -+ -+#define MTKSTP_BUFFER_SIZE (16384) -+ -+/*To check function driver's status by the the interface*/ -+/*Operation definition*/ -+#define OP_FUNCTION_ACTIVE 0 -+ -+/*Driver's status*/ -+#define STATUS_OP_INVALID 0 -+#define STATUS_FUNCTION_INVALID 1 -+ -+#define STATUS_FUNCTION_ACTIVE 31 -+#define STATUS_FUNCTION_INACTIVE 32 -+ -+#define MTKSTP_CRC_SIZE (2) -+#define MTKSTP_HEADER_SIZE (4) -+#define MTKSTP_SEQ_SIZE (8) -+ -+/*#define MTKSTP_WINSIZE (4)*/ -+#define MTKSTP_WINSIZE (7) -+#define MTKSTP_TX_TIMEOUT (180) /*TODO: Baudrate to decide this */ -+#define MTKSTP_RETRY_LIMIT (10) -+ -+#define INDEX_INC(idx) \ -+{ \ -+ idx++; \ -+ idx &= 0x7; \ -+} -+ -+#define INDEX_DEC(idx) \ -+{ \ -+ idx--; \ -+ idx &= 0x7; \ -+} -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+typedef INT32(*IF_TX) (const PUINT8 data, const UINT32 size, PUINT32 written_size); -+/* event/signal */ -+typedef INT32(*EVENT_SET) (UINT8 function_type); -+typedef INT32(*EVENT_TX_RESUME) (UINT8 winspace); -+typedef INT32(*FUNCTION_STATUS) (UINT8 type, UINT8 op); -+typedef INT32(*WMT_NOTIFY_FUNC_T) (UINT32 action); -+typedef INT32(*BTM_NOTIFY_WMT_FUNC_T) (INT32); -+ -+#if CFG_STP_CORE_CTX_SPIN_LOCK -+typedef OSAL_UNSLEEPABLE_LOCK STP_CTX_LOCK, *PSTP_CTX_LOCK; -+#else -+typedef OSAL_SLEEPABLE_LOCK STP_CTX_LOCK, *PSTP_CTX_LOCK; -+#endif -+ -+typedef struct { -+ /* common interface */ -+ IF_TX cb_if_tx; -+ /* event/signal */ -+ EVENT_SET cb_event_set; -+ EVENT_TX_RESUME cb_event_tx_resume; -+ FUNCTION_STATUS cb_check_funciton_status; -+} mtkstp_callback; -+ -+typedef enum { -+ MTKSTP_SYNC = 0, -+ MTKSTP_SEQ, -+ MTKSTP_ACK, -+ MTKSTP_NAK, -+ MTKSTP_TYPE, -+ MTKSTP_LENGTH, -+ MTKSTP_CHECKSUM, -+ MTKSTP_DATA, -+ MTKSTP_CRC1, -+ MTKSTP_CRC2, -+ MTKSTP_RESYNC1, -+ MTKSTP_RESYNC2, -+ MTKSTP_RESYNC3, -+ MTKSTP_RESYNC4, -+ MTKSTP_FW_MSG, -+} mtkstp_parser_state; -+ -+typedef struct { -+ mtkstp_parser_state state; -+ UINT8 seq; -+ UINT8 ack; -+ UINT8 nak; -+ UINT8 type; -+ UINT16 length; -+ UINT8 checksum; -+ UINT16 crc; -+#if 1 -+ UINT8 wmtsubtype; -+#endif -+} mtkstp_parser_context_struct; -+ -+typedef struct { -+ UINT8 txseq; /* last tx pkt's seq + 1 */ -+ UINT8 txack; /* last tx pkt's ack */ -+ UINT8 rxack; /* last rx pkt's ack */ -+ UINT8 winspace; /* current sliding window size */ -+ UINT8 expected_rxseq; /* last rx pkt's seq + 1 */ -+ UINT8 retry_times; -+} mtkstp_sequence_context_struct; -+ -+typedef struct { -+ /* MTK_WCN_MUTEX mtx; */ -+ OSAL_UNSLEEPABLE_LOCK mtx; -+ UINT8 buffer[MTKSTP_BUFFER_SIZE]; -+ UINT32 read_p; -+ UINT32 write_p; -+} mtkstp_ring_buffer_struct; -+ -+typedef struct { -+ UINT8 inband_rst_set; -+ UINT32 rx_counter; /* size of current processing pkt in rx_buf[] */ -+ UINT8 rx_buf[MTKSTP_BUFFER_SIZE]; /* input buffer of STP, room for current processing pkt */ -+ UINT32 tx_read; /* read ptr of tx_buf[] */ -+ UINT32 tx_write; /* write ptr of tx_buf[] */ -+ UINT8 tx_buf[MTKSTP_BUFFER_SIZE]; /* output buffer of STP */ -+ UINT32 tx_start_addr[MTKSTP_SEQ_SIZE]; /* ptr of each pkt in tx_buf[] */ -+ UINT32 tx_length[MTKSTP_SEQ_SIZE]; /* length of each pkt in tx_buf[] */ -+ mtkstp_ring_buffer_struct ring[MTKSTP_MAX_TASK_NUM]; /* ring buffers for each function driver */ -+ mtkstp_parser_context_struct parser; /* current rx pkt's content */ -+ mtkstp_sequence_context_struct sequence; /* state machine's current status */ -+ /* MTK_WCN_MUTEX stp_mutex; */ -+ /* OSAL_UNSLEEPABLE_LOCK stp_mutex; */ -+ STP_CTX_LOCK stp_mutex; -+ /* MTK_WCN_TIMER tx_timer; // timer for tx timeout handling */ -+ OSAL_TIMER tx_timer; -+ -+ MTKSTP_PSM_T *psm; -+ MTKSTP_BTM_T *btm; -+ UINT8 f_enable; /* default disabled */ -+ UINT8 f_ready; /* default non-ready */ -+ UINT8 f_pending_type; -+ UINT8 f_coredump; /*block tx flag, for now, only when f/w assert happens, we will set this bit on */ -+ UINT8 en_coredump; -+ /* Flag to identify Blueztooth is Bluez/or MTK Stack */ -+ MTK_WCN_BOOL f_bluez; -+ MTK_WCN_BOOL f_dbg_en; -+ MTK_WCN_BOOL f_autorst_en; -+ -+ /* Flag to identify STP by SDIO or UART */ -+ UINT32 f_mode; -+ -+ /* Flag to indicate the last WMT CLOSE */ -+ UINT32 f_wmt_last_close; -+ -+ /* Flag to indicate evt err has triggered assert or not */ -+ UINT32 f_evt_err_assert; -+} mtkstp_context_struct; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+INT32 stp_send_data_no_ps(UINT8 *buffer, UINT32 length, UINT8 type); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_init -+* DESCRIPTION -+* init STP kernel -+* PARAMETERS -+* cb_func [IN] function pointers of system APIs -+* RETURNS -+* INT32 0 = success, others = failure -+*****************************************************************************/ -+extern INT32 mtk_wcn_stp_init(const mtkstp_callback * const cb_func); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_deinit -+* DESCRIPTION -+* deinit STP kernel -+* PARAMETERS -+* void -+* RETURNS -+* INT32 0 = success, others = failure -+*****************************************************************************/ -+extern INT32 mtk_wcn_stp_deinit(void); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_enable -+* DESCRIPTION -+* enable/disable STP -+* PARAMETERS -+* value [IN] 0 = disable, others = enable -+* RETURNS -+* INT32 0 = success, others = error -+*****************************************************************************/ -+extern INT32 mtk_wcn_stp_enable(INT32 value); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_ready -+* DESCRIPTION -+* ready/non-ready STP -+* PARAMETERS -+* value [IN] 0 = non-ready, others = ready -+* RETURNS -+* INT32 0 = success, others = error -+*****************************************************************************/ -+extern INT32 mtk_wcn_stp_ready(INT32 value); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_coredump_start_ctrl -+* DESCRIPTION -+* set f/w assert flag in STP context -+* PARAMETERS -+* value [IN] 0=assert end, others=assert begins -+* RETURNS -+* INT32 0=success, others=error -+*****************************************************************************/ -+extern INT32 mtk_wcn_stp_coredump_start_ctrl(UINT32 value); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_coredump_start_get -+* DESCRIPTION -+* get f/w assert flag in STP context -+* PARAMETERS -+* VOID -+* RETURNS -+* INT32 0= f/w assert flag is not set, others=f/w assert flag is set -+*****************************************************************************/ -+extern INT32 mtk_wcn_stp_coredump_start_get(VOID); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_send_data_raw -+* DESCRIPTION -+* send raw data to common interface, bypass STP -+* PARAMETERS -+* buffer [IN] data buffer -+* length [IN] data buffer length -+* type [IN] subfunction type -+* RETURNS -+* INT32 length transmitted -+*****************************************************************************/ -+extern INT32 mtk_wcn_stp_send_data_raw(const PUINT8 buffer, const UINT32 length, const UINT8 type); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_set_sdio_mode -+* DESCRIPTION -+* Set stp for SDIO mode -+* PARAMETERS -+* sdio_flag [IN] sdio mode flag (TRUE:SDIO mode, FALSE:UART mode) -+* RETURNS -+* void -+*****************************************************************************/ -+extern void mtk_wcn_stp_set_mode(UINT32 sdio_flag); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_is_uart_fullset_mode -+* DESCRIPTION -+* Is stp use UART Fullset mode? -+* PARAMETERS -+* none. -+* RETURNS -+* MTK_WCN_BOOL TRUE:UART Fullset, FALSE:UART Fullset -+*****************************************************************************/ -+extern MTK_WCN_BOOL mtk_wcn_stp_is_uart_fullset_mode(void); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_is_uart_mand_mode -+* DESCRIPTION -+* Is stp use UART Mandatory mode? -+* PARAMETERS -+* none. -+* RETURNS -+* MTK_WCN_BOOL TRUE:UART Mandatory, FALSE:UART Mandatory -+*****************************************************************************/ -+extern MTK_WCN_BOOL mtk_wcn_stp_is_uart_mand_mode(void); -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_is_btif_fullset_mode -+* DESCRIPTION -+* Is stp use BTIF Fullset mode? -+* PARAMETERS -+* none. -+* RETURNS -+* MTK_WCN_BOOL TRUE:BTIF Fullset, FALSE:BTIF Fullset -+*****************************************************************************/ -+extern MTK_WCN_BOOL mtk_wcn_stp_is_btif_fullset_mode(void); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_is_btif_mand_mode -+* DESCRIPTION -+* Is stp use BTIF Mandatory mode? -+* PARAMETERS -+* none. -+* RETURNS -+* MTK_WCN_BOOL TRUE:BTIF Mandatory, FALSE:BTIF Mandatory -+*****************************************************************************/ -+extern MTK_WCN_BOOL mtk_wcn_stp_is_btif_mand_mode(void); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_is_sdio_mode -+* DESCRIPTION -+* Is stp use SDIO mode? -+* PARAMETERS -+* none. -+* RETURNS -+* MTK_WCN_BOOL TRUE:SDIO mode, FALSE:UART mode -+*****************************************************************************/ -+extern MTK_WCN_BOOL mtk_wcn_stp_is_sdio_mode(void); -+ -+/***************************************************************************** -+* FUNCTION -+* stp_send_inband_reset -+* DESCRIPTION -+* To sync to oringnal stp state with f/w stp -+* PARAMETERS -+* none. -+* RETURNS -+* none -+*****************************************************************************/ -+extern void mtk_wcn_stp_inband_reset(void); -+ -+/***************************************************************************** -+* FUNCTION -+* stp_send_inband_reset -+* DESCRIPTION -+* To send testing command to chip -+* PARAMETERS -+* none. -+* RETURNS -+* none -+*****************************************************************************/ -+extern void mtk_wcn_stp_test_cmd(INT32 no); -+ -+/***************************************************************************** -+* FUNCTION -+* stp_send_inband_reset -+* DESCRIPTION -+* To control STP debugging mechanism -+* PARAMETERS -+* func_no: function control, func_op: dumpping filer, func_param: dumpping parameter -+* RETURNS -+* none -+*****************************************************************************/ -+extern void mtk_wcn_stp_debug_ctrl(INT32 func_no, INT32 func_op, INT32 func_param); -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_flush -+* DESCRIPTION -+* flush all stp context -+* PARAMETERS -+* none. -+* RETURNS -+* none -+*****************************************************************************/ -+extern void mtk_wcn_stp_flush_context(void); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_rx_queue -+* DESCRIPTION -+* flush all stp rx queue -+* PARAMETERS -+* none. -+* RETURNS -+* none -+*****************************************************************************/ -+extern void mtk_wcn_stp_flush_rx_queue(UINT32 type); -+ -+/***************************************************************************** -+* FUNCTION -+* set stp debugging mdoe -+* DESCRIPTION -+* set stp debugging mdoe -+* PARAMETERS -+* dbg_mode: switch to dbg mode ? -+* RETURNS -+* void -+*****************************************************************************/ -+extern void mtk_wcn_stp_set_dbg_mode(MTK_WCN_BOOL dbg_mode); -+ -+/***************************************************************************** -+* FUNCTION -+* set stp auto reset mdoe -+* DESCRIPTION -+* set stp auto reset mdoe -+* PARAMETERS -+* auto_rst: switch to auto reset mode ? -+* RETURNS -+* void -+*****************************************************************************/ -+extern void mtk_wcn_stp_set_auto_rst(MTK_WCN_BOOL auto_rst); -+ -+/*stp_psm support*/ -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_psm_notify_stp -+* DESCRIPTION -+* WMT notification to STP that power saving job is done or not -+* PARAMETERS -+* -+* RETURNS -+* 0: Sccuess Negative value: Fail -+*****************************************************************************/ -+extern int mtk_wcn_stp_psm_notify_stp(const UINT32 action); -+ -+extern int mtk_wcn_stp_set_psm_state(MTKSTP_PSM_STATE_T state); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_psm_enabla -+* DESCRIPTION -+* enable STP PSM -+* PARAMETERS -+* int idle_time_to_sleep: IDLE time to sleep -+* RETURNS -+* 0: Sccuess Negative value: Fail -+*****************************************************************************/ -+extern int mtk_wcn_stp_psm_enable(int idle_time_to_sleep); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_psm_disable -+* DESCRIPTION -+* disable STP PSM -+* PARAMETERS -+* void -+* RETURNS -+* 0: Sccuess Negative value: Fail -+*****************************************************************************/ -+extern int mtk_wcn_stp_psm_disable(void); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_psm_reset -+* DESCRIPTION -+* reset STP PSM (used on whole chip reset) -+* PARAMETERS -+* void -+* RETURNS -+* 0: Sccuess Negative value: Fail -+*****************************************************************************/ -+extern int mtk_wcn_stp_psm_reset(void); -+extern void stp_do_tx_timeout(void); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_btm_get_dmp -+* DESCRIPTION -+* get stp dump related information -+* PARAMETERS -+* buffer: dump placement, len: dump size -+* RETURNS -+* 0: Success Negative Value: Fail -+*****************************************************************************/ -+extern int mtk_wcn_stp_btm_get_dmp(char *buf, int *len); -+ -+extern int mtk_wcn_stp_dbg_enable(void); -+ -+extern int mtk_wcn_stp_dbg_disable(void); -+ -+extern void mtk_wcn_stp_set_if_tx_type(ENUM_STP_TX_IF_TYPE stp_if_type); -+ -+extern int mtk_wcn_sys_if_rx(UINT8 *data, INT32 size); -+ -+extern MTK_WCN_BOOL mtk_wcn_stp_dbg_level(UINT32 dbglevel); -+ -+extern INT32 mtk_wcn_stp_dbg_dump_package(VOID); -+ -+extern int stp_drv_init(void); -+ -+extern void stp_drv_exit(void); -+ -+extern INT32 mtk_wcn_stp_dbg_log_ctrl(UINT32 on); -+ -+extern INT32 mtk_wcn_stp_coredump_flag_ctrl(UINT32 on); -+ -+extern INT32 mtk_wcn_stp_coredump_flag_get(VOID); -+extern INT32 mtk_wcn_stp_notify_sleep_for_thermal(void); -+ -+extern INT32 mtk_wcn_stp_set_wmt_last_close(UINT32 value); -+ -+/*stp btif API declared*/ -+extern INT32 mtk_wcn_stp_open_btif(VOID); -+extern INT32 mtk_wcn_stp_close_btif(VOID); -+extern INT32 mtk_wcn_stp_rxcb_register(MTK_WCN_BTIF_RX_CB rx_cb); -+extern INT32 mtk_wcn_stp_tx(UINT8 *pBuf, UINT32 len, UINT32 *written_len); -+extern INT32 mtk_wcn_stp_wakeup_consys(VOID); -+extern INT32 mtk_wcn_stp_dpidle_ctrl(ENUM_BTIF_DPIDLE_CTRL en_flag); -+extern INT32 mtk_wcn_stp_lpbk_ctrl(ENUM_BTIF_LPBK_MODE mode); -+extern INT32 mtk_wcn_stp_logger_ctrl(ENUM_BTIF_DBG_ID flag); -+extern VOID mtk_wcn_stp_ctx_save(VOID); -+extern VOID mtk_wcn_stp_ctx_restore(VOID); -+extern INT32 mtk_wcn_stp_wmt_evt_err_trg_assert(VOID); -+extern VOID mtk_wcn_stp_set_wmt_evt_err_trg_assert(UINT32 value); -+extern UINT32 mtk_wcn_stp_get_wmt_evt_err_trg_assert(VOID); -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif /* _STP_CORE_H_ */ -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/stp_wmt.h b/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/stp_wmt.h -new file mode 100644 -index 000000000000..94b3d8a597ac ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/stp_wmt.h -@@ -0,0 +1,89 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -+ -+/*! \file -+ \brief Declaration of library functions -+ -+ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. -+*/ -+ -+#ifndef _STP_WMT_H -+#define _STP_WMT_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+typedef enum { -+ BTM_RST_OP = 0, -+ BTM_DMP_OP = 1, -+ BTM_GET_AEE_SUPPORT_FLAG = 2, -+ BTM_MAX_OP, -+} MTKSTP_BTM_WMT_OP_T; -+ -+typedef enum { -+ SLEEP = 0, -+ HOST_AWAKE, -+ WAKEUP, -+ EIRQ, -+ ROLL_BACK, -+ STP_PSM_MAX_ACTION -+} MTKSTP_PSM_ACTION_T; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+extern MTK_WCN_BOOL wmt_lib_btm_cb(MTKSTP_BTM_WMT_OP_T op); -+ -+extern INT32 wmt_lib_ps_stp_cb(MTKSTP_PSM_ACTION_T action); -+extern MTK_WCN_BOOL wmt_lib_is_quick_ps_support(VOID); -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif /* _STP_WMT_H_ */ -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_conf.h b/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_conf.h -new file mode 100644 -index 000000000000..4c64b6b5e65b ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_conf.h -@@ -0,0 +1,74 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -+ -+/*! \file -+ \brief Declaration of library functions -+ -+ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. -+*/ -+ -+#ifndef _WMT_CONF_H_ -+#define _WMT_CONF_H_ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+#define CUST_CFG_WMT "WMT_SOC.cfg" -+#define CUST_CFG_WMT_PREFIX "/system/etc/firmware/" -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+INT32 wmt_conf_read_file(VOID); -+P_WMT_GEN_CONF wmt_conf_get_cfg(VOID); -+INT32 wmt_conf_set_cfg_file(const char *name); -+ -+#endif /* _WMT_CONF_H_ */ -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_core.h b/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_core.h -new file mode 100644 -index 000000000000..cca52a15cc98 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_core.h -@@ -0,0 +1,428 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -+ -+/*! \file -+ \brief Declaration of library functions -+ -+ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. -+*/ -+ -+#ifndef _WMT_CORE_H_ -+#define _WMT_CORE_H_ -+ -+#include "osal.h" -+#include "wmt_ctrl.h" -+#include "wmt_exp.h" -+#include "wmt_plat.h" -+/* TODO: [GeorgeKuo][FixMe] remove temporarily */ -+/* for AIF state definition */ -+/* #include "mtk_wcn_cmb_stub.h" */ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+#define CFG_CORE_MT6620_SUPPORT 0 /* whether MT6620 is supported or not */ -+ -+#define CFG_CORE_MT6628_SUPPORT 0 /* whether MT6628 is supported or not */ -+ -+#define CFG_CORE_SOC_SUPPORT 1 -+ -+/* TODO:[ChangeFeature][George] move this definition outside so that wmt_dev can remove wmt_core.h inclusion. */ -+#define defaultPatchName "mt66xx_patch_hdr.bin" -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+#define BCNT_PATCH_BUF_HEADROOM (8) -+ -+#define DWCNT_HIF_CONF (4) -+#define DWCNT_STRAP_CONF (4) -+#define DWCNT_RESERVED (8) -+#define DWCNT_CTRL_DATA (16) -+ -+#if 0 /* TODO: [obsolete][GeorgeKuo]: remove ubsolete definitions */ -+#define WMT_SET (1) -+#define WMT_QUERY (0) -+#define WMT_PKT_FMT_RAW (1) -+#define WMT_PKT_FMT_STP (0) -+#endif -+ -+#define WMT_FUNC_CTRL_ON (MTK_WCN_BOOL_TRUE) -+#define WMT_FUNC_CTRL_OFF (MTK_WCN_BOOL_FALSE) -+ -+#define WMT_HDR_LEN (4) /* header length */ -+#define WMT_STS_LEN (1) /* status length */ -+#define WMT_FLAG_LEN (1) -+#define WMT_HIF_UART_INFO_LEN (4) -+#define WMT_FUNC_CTRL_PARAM_LEN (1) -+ -+#define WMT_DEFAULT_BAUD_RATE (115200) -+ -+#define INIT_CMD(c, e, s) {.cmd = c, .cmdSz = sizeof(c), .evt = e, .evtSz = sizeof(e), .str = s} -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+typedef enum _ENUM_WMT_FM_T { -+ WMT_FM_INVALID = 0, -+ WMT_FM_I2C = 1, -+ WMT_FM_COMM = 2, -+ WMT_FM_MAX -+} ENUM_WMT_FM_T, *P_ENUM_WMT_FM_T; -+ -+typedef enum _ENUM_WMT_HIF_T { -+ WMT_HIF_UART = 0, -+ WMT_HIF_SDIO = 1, -+ WMT_HIF_BTIF = 2, -+ WMT_HIF_MAX -+} ENUM_WMT_HIF_T, *P_ENUM_WMT_HIF_T; -+ -+#if 0 /* [George] moved to wmt_exp.h for hif_sdio's use */ -+typedef enum { -+ WMT_SDIO_SLOT_INVALID = 0, -+ WMT_SDIO_SLOT_SDIO1 = 1, /* Wi-Fi dedicated SDIO1 */ -+ WMT_SDIO_SLOT_SDIO2 = 2, -+ WMT_SDIO_SLOT_MAX -+} WMT_SDIO_SLOT_NUM; -+ -+typedef enum { -+ WMT_SDIO_FUNC_STP = 0, -+ WMT_SDIO_FUNC_WIFI = 1, -+ WMT_SDIO_FUNC_MAX -+} WMT_SDIO_FUNC_TYPE; -+#endif -+ -+typedef enum _ENUM_WMT_OPID_T { -+ WMT_OPID_HIF_CONF = 0, -+ WMT_OPID_PWR_ON = 1, -+ WMT_OPID_PWR_OFF = 2, -+ WMT_OPID_FUNC_ON = 3, -+ WMT_OPID_FUNC_OFF = 4, -+ WMT_OPID_REG_RW = 5, /* TODO:[ChangeFeature][George] is this OP obsoleted? */ -+ WMT_OPID_EXIT = 6, -+ WMT_OPID_PWR_SV = 7, -+ WMT_OPID_DSNS = 8, -+ WMT_OPID_LPBK = 9, -+ WMT_OPID_CMD_TEST = 10, -+ WMT_OPID_HW_RST = 11, -+ WMT_OPID_SW_RST = 12, -+ WMT_OPID_BAUD_RST = 13, -+ WMT_OPID_STP_RST = 14, -+ WMT_OPID_THERM_CTRL = 15, -+ WMT_OPID_EFUSE_RW = 16, -+ WMT_OPID_GPIO_CTRL = 17, -+ WMT_OPID_FW_COREDMP = 18, -+ WMT_OPID_GPIO_STATE = 19, -+ WMT_OPID_BGW_DS = 20, -+ WMT_OPID_SET_MCU_CLK = 21, -+ WMT_OPID_ADIE_LPBK_TEST = 22, -+#if CFG_WMT_LTE_COEX_HANDLING -+ WMT_OPID_IDC_MSG_HANDLING = 23, -+#endif -+#ifdef CONFIG_MTK_COMBO_ANT -+ WMT_OPID_ANT_RAM_DOWN = 24, -+ WMT_OPID_ANT_RAM_STA_GET = 25, -+#endif -+ WMT_OPID_MAX -+} ENUM_WMT_OPID_T, *P_ENUM_WMT_OPID_T; -+ -+typedef OSAL_OP_DAT WMT_OP; -+typedef P_OSAL_OP_DAT P_WMT_OP; -+ -+typedef struct _WMT_HIF_CONF { -+ UINT32 hifType; /* HIF Type */ -+ UINT32 au4HifConf[DWCNT_HIF_CONF]; /* HIF Config */ -+ UINT32 au4StrapConf[DWCNT_STRAP_CONF]; /* Strap Config */ -+} WMT_HIF_CONF, *P_WMT_HIF_CONF; -+ -+typedef INT32(*WMT_OPID_FUNC) (P_WMT_OP); -+ -+typedef struct _WMT_GEN_CONF { -+ UINT8 cfgExist; -+ -+ UINT8 coex_wmt_ant_mode; -+ UINT8 coex_wmt_ext_component; -+ UINT8 coex_wmt_wifi_time_ctl; -+ UINT8 coex_wmt_ext_pta_dev_on; -+ /*mt6592 and LTE coex filter mode setting */ -+ UINT8 coex_wmt_filter_mode; -+ -+ UINT8 coex_bt_rssi_upper_limit; -+ UINT8 coex_bt_rssi_mid_limit; -+ UINT8 coex_bt_rssi_lower_limit; -+ UINT8 coex_bt_pwr_high; -+ UINT8 coex_bt_pwr_mid; -+ UINT8 coex_bt_pwr_low; -+ -+ UINT8 coex_wifi_rssi_upper_limit; -+ UINT8 coex_wifi_rssi_mid_limit; -+ UINT8 coex_wifi_rssi_lower_limit; -+ UINT8 coex_wifi_pwr_high; -+ UINT8 coex_wifi_pwr_mid; -+ UINT8 coex_wifi_pwr_low; -+ -+ UINT8 coex_ext_pta_hi_tx_tag; -+ UINT8 coex_ext_pta_hi_rx_tag; -+ UINT8 coex_ext_pta_lo_tx_tag; -+ UINT8 coex_ext_pta_lo_rx_tag; -+ UINT16 coex_ext_pta_sample_t1; -+ UINT16 coex_ext_pta_sample_t2; -+ UINT8 coex_ext_pta_wifi_bt_con_trx; -+ -+ UINT32 coex_misc_ext_pta_on; -+ UINT32 coex_misc_ext_feature_set; -+ /*GPS LNA setting */ -+ UINT8 wmt_gps_lna_pin; -+ UINT8 wmt_gps_lna_enable; -+ /*Power on sequence */ -+ UINT8 pwr_on_rtc_slot; -+ UINT8 pwr_on_ldo_slot; -+ UINT8 pwr_on_rst_slot; -+ UINT8 pwr_on_off_slot; -+ UINT8 pwr_on_on_slot; -+ UINT8 co_clock_flag; -+ -+ /* Combo chip side SDIO driving setting */ -+ UINT32 sdio_driving_cfg; -+ -+} WMT_GEN_CONF, *P_WMT_GEN_CONF; -+ -+typedef enum _ENUM_DRV_STS_ { -+#if 0 -+ DRV_STS_INVALID = 0, -+ DRV_STS_UNREG = 1, /* Initial State */ -+#endif -+ DRV_STS_POWER_OFF = 0, /* initial state */ -+ DRV_STS_POWER_ON = 1, /* powered on, only WMT */ -+ DRV_STS_FUNC_ON = 2, /* FUNC ON */ -+ DRV_STS_MAX -+} ENUM_DRV_STS, *P_ENUM_DRV_STS; -+ -+typedef enum _WMT_IC_PIN_ID_ { -+ WMT_IC_PIN_AUDIO = 0, -+ WMT_IC_PIN_EEDI = 1, -+ WMT_IC_PIN_EEDO = 2, -+ WMT_IC_PIN_GSYNC = 3, -+ WMT_IC_PIN_MAX -+} WMT_IC_PIN_ID, *P_WMT_IC_PIN_ID; -+ -+typedef enum _WMT_IC_PIN_STATE_ { -+ WMT_IC_PIN_EN = 0, -+ WMT_IC_PIN_DIS = 1, -+ WMT_IC_AIF_0 = 2, /* = CMB_STUB_AIF_0, */ -+ WMT_IC_AIF_1 = 3, /* = CMB_STUB_AIF_1, */ -+ WMT_IC_AIF_2 = 4, /* = CMB_STUB_AIF_2, */ -+ WMT_IC_AIF_3 = 5, /* = CMB_STUB_AIF_3, */ -+ WMT_IC_PIN_MUX = 6, -+ WMT_IC_PIN_GPIO = 7, -+ WMT_IC_PIN_GPIO_HIGH = 8, -+ WMT_IC_PIN_GPIO_LOW = 9, -+ WMT_IC_PIN_STATE_MAX -+} WMT_IC_PIN_STATE, *P_WMT_IC_PIN_STATE; -+ -+typedef enum _WMT_CO_CLOCK_ { -+ WMT_CO_CLOCK_DIS = 0, -+ WMT_CO_CLOCK_EN = 1, -+ WMT_CO_CLOCK_MAX -+} WMT_CO_CLOCK, *P_WMT_CO_CLOCK; -+ -+typedef INT32(*SW_INIT) (P_WMT_HIF_CONF pWmtHifConf); -+typedef INT32(*SW_DEINIT) (P_WMT_HIF_CONF pWmtHifConf); -+typedef INT32(*IC_PIN_CTRL) (WMT_IC_PIN_ID id, WMT_IC_PIN_STATE state, UINT32 flag); -+typedef INT32(*IC_VER_CHECK) (VOID); -+typedef INT32(*CO_CLOCK_CTRL) (WMT_CO_CLOCK on); -+typedef MTK_WCN_BOOL(*IS_QUICK_SLEEP_SUPPORT) (VOID); -+typedef MTK_WCN_BOOL(*IS_AEE_DUMP_SUPPORT) (VOID); -+ -+typedef struct _WMT_IC_OPS_ { -+ UINT32 icId; -+ SW_INIT sw_init; -+ SW_DEINIT sw_deinit; -+ IC_PIN_CTRL ic_pin_ctrl; -+ IC_VER_CHECK ic_ver_check; -+ CO_CLOCK_CTRL co_clock_ctrl; -+ IS_QUICK_SLEEP_SUPPORT is_quick_sleep; -+ IS_AEE_DUMP_SUPPORT is_aee_dump_support; -+} WMT_IC_OPS, *P_WMT_IC_OPS; -+ -+typedef struct _WMT_CTX_ { -+ ENUM_DRV_STS eDrvStatus[WMTDRV_TYPE_MAX]; /* Controlled driver status */ -+ UINT32 wmtInfoBit; /* valid info bit */ -+ WMT_HIF_CONF wmtHifConf; /* HIF information */ -+ -+ /* Pointer to WMT_IC_OPS. Shall be assigned to a correct table in stp_init -+ * if and only if getting chip id successfully. hwver and fwver are kept in -+ * WMT-IC module only. -+ */ -+ P_WMT_IC_OPS p_ic_ops; -+} WMT_CTX, *P_WMT_CTX; -+ -+/* TODO:[ChangeFeature][George] remove WMT_PKT. replace it with hardcoded arrays. */ -+/* Using this struct relies on compiler's implementation and pack() settings */ -+typedef struct _WMT_PKT_ { -+ UINT8 eType; /* PKT_TYPE_* */ -+ UINT8 eOpCode; /* OPCODE_* */ -+ UINT16 u2SduLen; /* 2 bytes length, little endian */ -+ UINT8 aucParam[32]; -+} WMT_PKT, *P_WMT_PKT; -+ -+/* WMT Packet Format */ -+typedef enum _ENUM_PKT_TYPE { -+ PKT_TYPE_INVALID = 0, -+ PKT_TYPE_CMD = 1, -+ PKT_TYPE_EVENT = 2, -+ _PKT_TYPE_MAX -+} ENUM_PKT_TYPE, *P_ENUM_PKT_TYPE; -+ -+typedef enum _ENUM_OPCODE { -+ OPCODE_INVALID = 0, -+ OPCODE_PATCH = 1, -+ OPCODE_TEST = 2, -+ OPCODE_WAKEUP = 3, -+ OPCODE_HIF = 4, -+ OPCODE_STRAP_CONF = 5, -+ OPCODE_FUNC_CTRL = 6, -+ OPCODE_RESET = 7, -+ OPCODE_INT = 8, -+ OPCODE_MAX -+} ENUM_OPCODE, *P_ENUM_OPCODE; -+ -+typedef enum { -+ WMT_STP_CONF_EN = 0, -+ WMT_STP_CONF_RDY = 1, -+ WMT_STP_CONF_MODE = 2, -+ WMT_STP_CONF_MAX -+} WMT_STP_CONF_TYPE; -+ -+struct init_script { -+ UINT8 *cmd; -+ UINT32 cmdSz; -+ UINT8 *evt; -+ UINT32 evtSz; -+ UINT8 *str; -+}; -+ -+typedef struct _WMT_PATCH { -+ UINT8 ucDateTime[16]; -+ UINT8 ucPLat[4]; -+ UINT16 u2HwVer; -+ UINT16 u2SwVer; -+ UINT32 u4PatchVer; -+} WMT_PATCH, *P_WMT_PATCH; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+#if CFG_CORE_MT6620_SUPPORT -+extern WMT_IC_OPS wmt_ic_ops_mt6620; -+#endif -+ -+#if CFG_CORE_MT6628_SUPPORT -+extern WMT_IC_OPS wmt_ic_ops_mt6628; -+#endif -+ -+#if CFG_CORE_SOC_SUPPORT -+extern WMT_IC_OPS wmt_ic_ops_soc; -+#endif -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+extern INT32 wmt_core_init(VOID); -+extern INT32 wmt_core_deinit(VOID); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_wmtd -+* DESCRIPTION -+* deinit STP kernel -+* PARAMETERS -+* void -+* RETURNS -+* INT32 0 = success, others = failure -+*****************************************************************************/ -+extern INT32 wmt_core_opid(P_WMT_OP pWmtOp); -+ -+extern INT32 wmt_core_ctrl(ENUM_WMT_CTRL_T ctrId, unsigned long *pPa1, unsigned long *pPa2); -+ -+extern INT32 wmt_core_func_ctrl_cmd(ENUM_WMTDRV_TYPE_T type, MTK_WCN_BOOL fgEn); -+ -+extern INT32 wmt_core_reg_rw_raw(UINT32 isWrite, UINT32 offset, PUINT32 pVal, UINT32 mask); -+ -+extern VOID wmt_core_dump_data(PUINT8 pData, PUINT8 pTitle, UINT32 len); -+ -+extern MTK_WCN_BOOL wmt_core_patch_check(UINT32 u4PatchVer, UINT32 u4HwVer); -+ -+extern INT32 wmt_core_init_script(struct init_script *script, INT32 count); -+ -+extern INT32 wmt_core_rx(PUINT8 pBuf, UINT32 bufLen, UINT32 *readSize); -+ -+extern INT32 wmt_core_tx(const PUINT8 pData, UINT32 size, PUINT32 writtenSize, MTK_WCN_BOOL bRawFlag); -+extern MTK_WCN_BOOL wmt_core_is_quick_ps_support(void); -+ -+extern MTK_WCN_BOOL wmt_core_get_aee_dump_flag(void); -+ -+#if CFG_CORE_INTERNAL_TXRX -+extern INT32 wmt_core_lpbk_do_stp_init(void); -+extern INT32 wmt_core_lpbk_do_stp_deinit(void); -+#endif -+ -+extern VOID wmt_core_set_coredump_state(ENUM_DRV_STS state); -+#if CFG_WMT_LTE_COEX_HANDLING -+extern VOID wmt_core_set_flag_for_test(UINT32 enable); -+extern UINT32 wmt_core_get_flag_for_test(VOID); -+#endif -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+static _osal_inline_ MTK_WCN_BOOL wmt_core_ic_ops_check(P_WMT_IC_OPS p_ops) -+{ -+ if (!p_ops) -+ return MTK_WCN_BOOL_FALSE; -+ -+ if ((NULL == p_ops->sw_init) -+ || (NULL == p_ops->sw_deinit) -+ || (NULL == p_ops->ic_ver_check) -+ || (NULL == p_ops->ic_pin_ctrl)) -+ return MTK_WCN_BOOL_FALSE; -+ else -+ return MTK_WCN_BOOL_TRUE; -+} -+ -+#endif /* _WMT_CORE_H_ */ -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_ctrl.h b/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_ctrl.h -new file mode 100644 -index 000000000000..0ff3d6058c39 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_ctrl.h -@@ -0,0 +1,120 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -+ -+/*! \file -+ \brief Declaration of library functions -+ -+ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. -+*/ -+ -+#ifndef _WMT_CTRL_H_ -+#define _WMT_CTRL_H_ -+ -+#include "osal.h" -+#include "wmt_stp_exp.h" -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+#define DWCNT_CTRL_DATA (16) -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+typedef struct _WMT_CTRL_DATA_ { -+ SIZE_T ctrlId; -+ SIZE_T au4CtrlData[DWCNT_CTRL_DATA]; -+} WMT_CTRL_DATA, *P_WMT_CTRL_DATA; -+ -+typedef enum _ENUM_WMT_CTRL_T { -+ WMT_CTRL_HW_PWR_OFF = 0, /* whole chip power off */ -+ WMT_CTRL_HW_PWR_ON = 1, /* whole chip power on */ -+ WMT_CTRL_HW_RST = 2, /* whole chip rst */ -+ WMT_CTRL_STP_CLOSE = 3, -+ WMT_CTRL_STP_OPEN = 4, -+ WMT_CTRL_STP_CONF = 5, -+ WMT_CTRL_FREE_PATCH = 6, -+ WMT_CTRL_GET_PATCH = 7, -+ WMT_CTRL_GET_PATCH_NAME = 8, -+ WMT_CTRL_HWIDVER_SET = 9, /* TODO: rename this and add chip id information in addition to chip version */ -+ WMT_CTRL_STP_RST = 10, -+ WMT_CTRL_GET_WMT_CONF = 11, -+ WMT_CTRL_TX = 12, /* [FixMe][GeorgeKuo]: to be removed by Sean's stp integration */ -+ WMT_CTRL_RX = 13, /* [FixMe][GeorgeKuo]: to be removed by Sean's stp integration */ -+ WMT_CTRL_RX_FLUSH = 14, /* [FixMe][SeanWang]: to be removed by Sean's stp integration */ -+ WMT_CTRL_GPS_SYNC_SET = 15, -+ WMT_CTRL_GPS_LNA_SET = 16, -+ WMT_CTRL_PATCH_SEARCH = 17, -+ WMT_CTRL_CRYSTAL_TRIMING_GET = 18, -+ WMT_CTRL_CRYSTAL_TRIMING_PUT = 19, -+ WMT_CTRL_HW_STATE_DUMP = 20, -+ WMT_CTRL_GET_PATCH_NUM = 21, -+ WMT_CTRL_GET_PATCH_INFO = 22, -+ WMT_CTRL_SOC_PALDO_CTRL = 23, -+ WMT_CTRL_SOC_WAKEUP_CONSYS = 24, -+ WMT_CTRL_SET_STP_DBG_INFO = 25, -+ WMT_CTRL_BGW_DESENSE_CTRL = 26, -+ WMT_CTRL_EVT_ERR_TRG_ASSERT = 27, -+#if CFG_WMT_LTE_COEX_HANDLING -+ WMT_CTRL_GET_TDM_REQ_ANTSEL = 28, -+#endif -+ WMT_CTRL_EVT_PARSER = 29, -+ WMT_CTRL_MAX -+} ENUM_WMT_CTRL_T, *P_ENUM_WMT_CTRL_T; -+ -+typedef INT32(*WMT_CTRL_FUNC) (P_WMT_CTRL_DATA); -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+extern INT32 wmt_ctrl(P_WMT_CTRL_DATA pWmtCtrlData); -+ -+extern INT32 wmt_ctrl_tx_ex(const PUINT8 pData, const UINT32 size, PUINT32 writtenSize, const MTK_WCN_BOOL bRawFlag); -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif /* _WMT_CTRL_H_ */ -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_func.h b/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_func.h -new file mode 100644 -index 000000000000..d586f442e7ef ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_func.h -@@ -0,0 +1,140 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -+ -+/*! \file -+ \brief Declaration of library functions -+ -+ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. -+*/ -+ -+#ifndef _WMT_FUNC_H_ -+#define _WMT_FUNC_H_ -+ -+#include "osal_typedef.h" -+#include "osal.h" -+#include "wmt_core.h" -+#include "wmt_plat.h" -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+#if 1 /* defined(CONFIG_MTK_COMBO_HCI_DRIVER) || defined(CONFIG_MTK_COMBO_BT) */ -+#define CFG_FUNC_BT_SUPPORT 1 -+#else -+#define CFG_FUNC_BT_SUPPORT 0 -+#endif -+ -+#if 1 /* defined(CONFIG_MTK_COMBO_FM) */ -+#define CFG_FUNC_FM_SUPPORT 1 -+#else -+#define CFG_FUNC_FM_SUPPORT 0 -+#endif -+ -+#if 1 /* defined(CONFIG_MTK_COMBO_GPS) */ -+#define CFG_FUNC_GPS_SUPPORT 1 -+#else -+#define CFG_FUNC_GPS_SUPPORT 0 -+#endif -+ -+#if 1 /* defined(CONFIG_MTK_COMBO_WIFI) */ -+#define CFG_FUNC_WIFI_SUPPORT 1 -+#else -+#define CFG_FUNC_WIFI_SUPPORT 0 -+#endif -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+typedef INT32(*SUBSYS_FUNC_ON) (P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf); -+typedef INT32(*SUBSYS_FUNC_OFF) (P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf); -+ -+typedef struct _WMT_FUNC_OPS_ { -+ SUBSYS_FUNC_ON func_on; -+ SUBSYS_FUNC_OFF func_off; -+} WMT_FUNC_OPS, *P_WMT_FUNC_OPS; -+ -+typedef struct _CMB_PIN_CTRL_REG_ { -+ UINT32 regAddr; -+ UINT32 regValue; -+ UINT32 regMask; -+ -+} CMB_PIN_CTRL_REG, *P_CMB_PIN_CTRL_REG; -+ -+typedef struct _CMB_PIN_CTRL_ { -+ UINT32 pinId; -+ UINT32 regNum; -+ P_CMB_PIN_CTRL_REG pFuncOnArray; -+ P_CMB_PIN_CTRL_REG pFuncOffArray; -+ -+} CMB_PIN_CTRL, *P_CMB_PIN_CTRL; -+ -+typedef enum _ENUM_CMP_PIN_ID_ { -+ CMB_PIN_EEDI_ID = 0, -+ CMB_PIN_EEDO_ID = 1, -+ CMB_PIN_GSYNC_ID = 2, -+} ENUM_CMP_PIN_ID, *P_ENUM_CMP_PIN_ID; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+#if CFG_FUNC_BT_SUPPORT -+extern WMT_FUNC_OPS wmt_func_bt_ops; -+#endif -+ -+#if CFG_FUNC_FM_SUPPORT -+extern WMT_FUNC_OPS wmt_func_fm_ops; -+#endif -+ -+#if CFG_FUNC_GPS_SUPPORT -+extern WMT_FUNC_OPS wmt_func_gps_ops; -+#endif -+ -+#if CFG_FUNC_WIFI_SUPPORT -+extern WMT_FUNC_OPS wmt_func_wifi_ops; -+#endif -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif /* _WMT_FUNC_H_ */ -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_ic.h b/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_ic.h -new file mode 100644 -index 000000000000..901becfdb92f ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_ic.h -@@ -0,0 +1,122 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -+ -+/*! \file -+ \brief Declaration of library functions -+ -+ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. -+*/ -+ -+#ifndef _WMT_IC_H_ -+#define _WMT_IC_H_ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+#include "wmt_core.h" -+#include "wmt_exp.h" -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+#define WMT_IC_NAME_MT6620 "MT6620" -+#define WMT_IC_NAME_MT6628 "MT6628" -+#define WMT_IC_NAME_DEFAULT "SOC_CONSYS" -+ -+#define WMT_IC_VER_E1 "E1" -+#define WMT_IC_VER_E2 "E2" -+#define WMT_IC_VER_E3 "E3" -+#define WMT_IC_VER_E4 "E4" -+#define WMT_IC_VER_E5 "E5" -+#define WMT_IC_VER_E6 "E6" -+ -+#define WMT_IC_PATCH_DUMMY_EXT "_ex" -+#define WMT_IC_PATCH_NO_EXT "" -+#define WMT_IC_PATCH_E1_EXT "_e1" -+#define WMT_IC_PATCH_E2_EXT "_e2" -+#define WMT_IC_PATCH_E3_EXT "_e3" -+#define WMT_IC_PATCH_E4_EXT "_e4" -+#define WMT_IC_PATCH_E5_EXT "_e5" -+#define WMT_IC_PATCH_E6_EXT "_e6" -+ -+#define WMT_IC_PATCH_TAIL "_hdr.bin" -+ -+#define WMT_IC_INVALID_CHIP_ID 0xFFFF -+ -+#define MAJORNUM(x) (x & 0x00F0) -+#define MINORNUM(x) (x & 0x000F) -+ -+/******************************************************************************* -+* R E G I S T E R M A P -+******************************************************************************** -+*/ -+/* General definition used for ALL/UNKNOWN CHIPS */ -+/* Now MT6620 uses these definitions */ -+#define GEN_CONFG_BASE (0x80000000UL) -+#define GEN_HVR (GEN_CONFG_BASE + 0x0UL) /* HW_VER */ -+#define GEN_FVR (GEN_CONFG_BASE + 0x4UL) /* FW_VER */ -+#define GEN_VER_MASK (0x0000FFFFUL) /* HW_VER and FW_VER valid bits mask */ -+#define GEN_HCR (GEN_CONFG_BASE + 0x8UL) /* HW_CODE, chip id */ -+#define GEN_HCR_MASK (0x0000FFFFUL) /* HW_CODE valid bits mask */ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+typedef struct _WMT_IC_INFO_S { -+ UINT32 u4HwVer; /* u4HwId */ -+ PUINT8 cChipName; -+ PUINT8 cChipVersion; -+ PUINT8 cPatchNameExt; -+ MTK_WCN_BOOL bPsmSupport; -+ MTK_WCN_BOOL bWorkWithoutPatch; -+ ENUM_WMTHWVER_TYPE_T eWmtHwVer; -+} WMT_IC_INFO_S, *P_WMT_IC_INFO_S; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif /* _WMT_IC_H_ */ -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_lib.h b/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_lib.h -new file mode 100644 -index 000000000000..b0c05cf3a252 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_lib.h -@@ -0,0 +1,300 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -+ -+/*! \file -+ \brief Declaration of library functions -+ -+ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. -+*/ -+ -+#ifndef _WMT_LIB_H_ -+#define _WMT_LIB_H_ -+ -+#include "osal.h" -+#include "wmt_core.h" -+#include "wmt_exp.h" -+#include -+#include "stp_wmt.h" -+#include "wmt_plat.h" -+#include "wmt_idc.h" -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+#define WMT_OP_BUF_SIZE (16) -+ -+typedef enum _ENUM_WMTRSTRET_TYPE_T { -+ WMTRSTRET_SUCCESS = 0x0, -+ WMTRSTRET_FAIL = 0x1, -+ WMTRSTRET_ONGOING = 0x2, -+ WMTRSTRET_MAX -+} ENUM_WMTRSTRET_TYPE_T, *P_ENUM_WMTRSTRET_TYPE_T; -+ -+/* -+3(retry times) * 180 (STP retry time out) -++ 10 (firmware process time) + -+10 (transmit time) + -+10 (uart process -> WMT response pool) + -+230 (others) -+*/ -+#define WMT_LIB_RX_TIMEOUT 20000 /*800-->cover v1.2phone BT function on time (~830ms) */ -+/* -+open wifi during wifi power on procedure -+(because wlan is insert to system after mtk_hif_sdio module, -+so wifi card is not registered to hif module -+when mtk_wcn_wmt_func_on is called by wifi through rfkill) -+*/ -+#define MAX_WIFI_ON_TIME 55000 -+ -+#define WMT_PWRON_RTY_DFT 2 -+#define MAX_RETRY_TIME_DUE_TO_RX_TIMEOUT (WMT_PWRON_RTY_DFT * WMT_LIB_RX_TIMEOUT) -+#define MAX_EACH_FUNC_ON_WHEN_CHIP_POWER_ON_ALREADY WMT_LIB_RX_TIMEOUT /*each WMT command */ -+#define MAX_FUNC_ON_TIME \ -+ (MAX_WIFI_ON_TIME + MAX_RETRY_TIME_DUE_TO_RX_TIMEOUT + MAX_EACH_FUNC_ON_WHEN_CHIP_POWER_ON_ALREADY * 3) -+ -+#define MAX_EACH_FUNC_OFF (WMT_LIB_RX_TIMEOUT + 1000) /*1000->WMT_LIB_RX_TIMEOUT + 1000, logical judgement */ -+#define MAX_FUNC_OFF_TIME (MAX_EACH_FUNC_OFF * 4) -+ -+#define MAX_EACH_WMT_CMD (WMT_LIB_RX_TIMEOUT + 1000) /*1000->WMT_LIB_RX_TIMEOUT + 1000, logical judgement */ -+ -+#define MAX_GPIO_CTRL_TIME (2000) /* [FixMe][GeorgeKuo] a temp value */ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/* AIF FLAG definition */ -+/* bit(0): share pin or not */ -+#define WMT_LIB_AIF_FLAG_MASK (0x1UL) -+#define WMT_LIB_AIF_FLAG_SHARE (0x1UL << 0) -+#define WMT_LIB_AIF_FLAG_SEPARATE (0x0UL << 0) -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/* bit field offset definition */ -+typedef enum { -+ WMT_STAT_PWR = 0, /* is powered on */ -+ WMT_STAT_STP_REG = 1, /* is STP driver registered: */ -+ WMT_STAT_STP_OPEN = 2, /* is STP opened: default FALSE */ -+ WMT_STAT_STP_EN = 3, /* is STP enabled: default FALSE */ -+ WMT_STAT_STP_RDY = 4, /* is STP ready for client: default FALSE */ -+ WMT_STAT_RX = 5, /* is rx data available */ -+ WMT_STAT_CMD = 6, /* is cmd string to be read */ -+ WMT_STAT_RST_ON = 7, -+ WMT_STAT_MAX -+} WMT_STAT; -+ -+typedef enum _ENUM_WMTRSTSRC_TYPE_T { -+ WMTRSTSRC_RESET_BT = 0x0, -+ WMTRSTSRC_RESET_FM = 0x1, -+ WMTRSTSRC_RESET_GPS = 0x2, -+ WMTRSTSRC_RESET_WIFI = 0x3, -+ WMTRSTSRC_RESET_STP = 0x4, -+ WMTRSTSRC_RESET_TEST = 0x5, -+ WMTRSTSRC_RESET_MAX -+} ENUM_WMTRSTSRC_TYPE_T, *P_ENUM_WMTRSTSRC_TYPE_T; -+ -+typedef struct { -+ PF_WMT_CB fDrvRst[4]; -+} WMT_FDRV_CB, *P_WMT_FDRV_CB; -+ -+typedef struct { -+ UINT32 dowloadSeq; -+ UINT8 addRess[4]; -+ UINT8 patchName[256]; -+} WMT_PATCH_INFO, *P_WMT_PATCH_INFO; -+ -+/* OS independent wrapper for WMT_OP */ -+typedef struct _DEV_WMT_ { -+ -+ OSAL_SLEEPABLE_LOCK psm_lock; -+ OSAL_SLEEPABLE_LOCK idc_lock; -+ /* WMTd thread information */ -+ /* struct task_struct *pWmtd; */ -+ OSAL_THREAD thread; /* main thread (wmtd) handle */ -+ /* wait_queue_head_t rWmtdWq; */ -+ OSAL_EVENT rWmtdWq; /*WMTd command wait queue */ -+ /* ULONG state; */ -+ OSAL_BIT_OP_VAR state; /* bit field of WMT_STAT */ -+ -+ /* STP context information */ -+ /* wait_queue_head_t rWmtRxWq; */ -+ OSAL_EVENT rWmtRxWq; /* STP Rx wait queue */ -+ /* WMT_STP_FUNC rStpFunc; */ -+ WMT_FDRV_CB rFdrvCb; /* STP functions */ -+ -+ /* WMT Configurations */ -+ WMT_HIF_CONF rWmtHifConf; -+ WMT_GEN_CONF rWmtGenConf; -+ -+ /* Patch information */ -+ UINT8 cPatchName[NAME_MAX + 1]; -+ UINT8 cFullPatchName[NAME_MAX + 1]; -+ UINT32 patchNum; -+ -+ const osal_firmware *pPatch; -+ -+ UINT8 cWmtcfgName[NAME_MAX + 1]; -+ const osal_firmware *pWmtCfg; -+ -+ const osal_firmware *pNvram; -+ -+ /* Current used UART port description */ -+ INT8 cUartName[NAME_MAX + 1]; -+ -+ OSAL_OP_Q rFreeOpQ; /* free op queue */ -+ OSAL_OP_Q rActiveOpQ; /* active op queue */ -+ OSAL_OP arQue[WMT_OP_BUF_SIZE]; /* real op instances */ -+ P_OSAL_OP pCurOP; /* current op */ -+ -+ /* cmd str buffer */ -+ UINT8 cCmd[NAME_MAX + 1]; -+ INT32 cmdResult; -+ /* struct completion cmd_comp; */ -+ /* wait_queue_head_t cmd_wq; */ -+ OSAL_SIGNAL cmdResp; /* read command queues */ -+ OSAL_EVENT cmdReq; -+ -+ /* WMT loopback Thread Information */ -+ /* WMT_CMB_VER combo_ver; */ -+ /* P_WMT_CMB_CHIP_INFO_S pChipInfo; */ -+ UINT32 chip_id; -+ UINT32 hw_ver; -+ UINT32 fw_ver; -+ /* TODO: [FixMe][GeorgeKuo] remove this translated version code in the */ -+ /* future. Just return the above 3 info to querist */ -+ ENUM_WMTHWVER_TYPE_T eWmtHwVer; -+ -+ P_WMT_PATCH_INFO pWmtPatchInfo; -+} DEV_WMT, *P_DEV_WMT; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+extern DEV_WMT gDevWmt; -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+extern INT32 wmt_lib_init(VOID); -+extern INT32 wmt_lib_deinit(VOID); -+extern INT32 wmt_lib_tx(PUINT8 data, UINT32 size, PUINT32 writtenSize); -+extern INT32 wmt_lib_tx_raw(PUINT8 data, UINT32 size, PUINT32 writtenSize); -+extern INT32 wmt_lib_rx(PUINT8 buff, UINT32 buffLen, PUINT32 readSize); -+extern VOID wmt_lib_flush_rx(VOID); -+ -+#if CFG_WMT_PS_SUPPORT -+extern INT32 wmt_lib_ps_set_idle_time(UINT32 psIdleTime); -+extern INT32 wmt_lib_ps_init(VOID); -+extern INT32 wmt_lib_ps_deinit(VOID); -+extern INT32 wmt_lib_ps_enable(VOID); -+extern INT32 wmt_lib_ps_ctrl(UINT32 state); -+ -+extern INT32 wmt_lib_ps_disable(VOID); -+extern VOID wmt_lib_ps_irq_cb(VOID); -+#endif -+extern VOID wmt_lib_ps_set_sdio_psop(PF_WMT_SDIO_PSOP own_cb); -+ -+/* LXOP functions: */ -+extern P_OSAL_OP wmt_lib_get_free_op(VOID); -+extern INT32 wmt_lib_put_op_to_free_queue(P_OSAL_OP pOp); -+extern MTK_WCN_BOOL wmt_lib_put_act_op(P_OSAL_OP pOp); -+ -+/* extern ENUM_WMTHWVER_TYPE_T wmt_lib_get_hwver (VOID); */ -+extern UINT32 wmt_lib_get_icinfo(ENUM_WMT_CHIPINFO_TYPE_T type); -+ -+extern MTK_WCN_BOOL wmt_lib_is_therm_ctrl_support(VOID); -+extern MTK_WCN_BOOL wmt_lib_is_dsns_ctrl_support(VOID); -+extern INT32 wmt_lib_trigger_cmd_signal(INT32 result); -+extern PUINT8 wmt_lib_get_cmd(VOID); -+extern P_OSAL_EVENT wmt_lib_get_cmd_event(VOID); -+extern INT32 wmt_lib_set_patch_name(PUINT8 cPatchName); -+extern INT32 wmt_lib_set_hif(unsigned long hifconf); -+extern P_WMT_HIF_CONF wmt_lib_get_hif(VOID); -+extern MTK_WCN_BOOL wmt_lib_get_cmd_status(VOID); -+ -+/* GeorgeKuo: replace set_chip_gpio() with more specific ones */ -+#if 0 /* moved to wmt_exp.h */ -+extern INT32 wmt_lib_set_aif(CMB_STUB_AIF_X aif, MTK_WCN_BOOL share); /* set AUDIO interface options */ -+#endif -+extern INT32 wmt_lib_host_awake_get(VOID); -+extern INT32 wmt_lib_host_awake_put(VOID); -+extern UINT32 wmt_lib_dbg_level_set(UINT32 level); -+ -+extern INT32 wmt_lib_msgcb_reg(ENUM_WMTDRV_TYPE_T eType, PF_WMT_CB pCb); -+ -+extern INT32 wmt_lib_msgcb_unreg(ENUM_WMTDRV_TYPE_T eType); -+ENUM_WMTRSTRET_TYPE_T wmt_lib_cmb_rst(ENUM_WMTRSTSRC_TYPE_T src); -+MTK_WCN_BOOL wmt_lib_sw_rst(INT32 baudRst); -+MTK_WCN_BOOL wmt_lib_hw_rst(VOID); -+INT32 wmt_lib_reg_rw(UINT32 isWrite, UINT32 offset, PUINT32 pvalue, UINT32 mask); -+INT32 wmt_lib_efuse_rw(UINT32 isWrite, UINT32 offset, PUINT32 pvalue, UINT32 mask); -+ -+extern INT32 DISABLE_PSM_MONITOR(void); -+extern VOID ENABLE_PSM_MONITOR(void); -+extern INT32 wmt_lib_notify_stp_sleep(void); -+extern void wmt_lib_psm_lock_release(void); -+extern INT32 wmt_lib_psm_lock_aquire(void); -+extern VOID wmt_lib_idc_lock_release(VOID); -+extern INT32 wmt_lib_idc_lock_aquire(VOID); -+extern INT32 wmt_lib_set_stp_wmt_last_close(UINT32 value); -+ -+extern VOID wmt_lib_set_patch_num(UINT32 num); -+extern VOID wmt_lib_set_patch_info(P_WMT_PATCH_INFO pPatchinfo); -+extern INT32 wmt_lib_set_current_op(P_DEV_WMT pWmtDev, P_OSAL_OP pOp); -+extern P_OSAL_OP wmt_lib_get_current_op(P_DEV_WMT pWmtDev); -+extern PUINT8 wmt_lib_get_fwinfor_from_emi(UINT8 section, UINT32 offset, PUINT8 buff, UINT32 len); -+extern INT32 wmt_lib_poll_cpupcr(UINT32 count, UINT16 sleep, UINT16 toAee); -+extern PUINT8 wmt_lib_get_cpupcr_xml_format(PUINT32 len); -+extern INT32 wmt_lib_register_thermal_ctrl_cb(thermal_query_ctrl_cb thermal_ctrl); -+extern UINT32 wmt_lib_set_host_assert_info(UINT32 type, UINT32 reason, UINT32 en); -+extern INT8 wmt_lib_co_clock_get(VOID); -+extern UINT32 wmt_lib_soc_set_wifiver(UINT32 wifiver); -+ -+#if CFG_WMT_LTE_COEX_HANDLING -+extern MTK_WCN_BOOL wmt_lib_handle_idc_msg(ipc_ilm_t *idc_infor); -+#endif -+#if CFG_WMT_PS_SUPPORT -+extern UINT32 wmt_lib_quick_sleep_ctrl(UINT32 en); -+#endif -+#if CONSYS_ENALBE_SET_JTAG -+extern UINT32 wmt_lib_jtag_flag_set(UINT32 en); -+#endif -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif /* _WMT_LIB_H_ */ -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/core/psm_core.c b/drivers/misc/mediatek/connectivity/common/conn_soc/core/psm_core.c -new file mode 100644 -index 000000000000..f37da4761009 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/core/psm_core.c -@@ -0,0 +1,1889 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -+#include "osal_typedef.h" -+#include "osal.h" -+#include "psm_core.h" -+#include "stp_core.h" -+#include -+ -+INT32 gPsmDbgLevel = STP_PSM_LOG_INFO; -+MTKSTP_PSM_T stp_psm_i; -+MTKSTP_PSM_T *stp_psm = &stp_psm_i; -+ -+STP_PSM_RECORD_T *g_stp_psm_dbg = NULL; -+static UINT32 g_record_num; -+ -+P_STP_PSM_OPID_RECORD g_stp_psm_opid_dbg = NULL; -+static UINT32 g_opid_record_num; -+ -+#define STP_PSM_LOUD_FUNC(fmt, arg...) \ -+do { \ -+ if (gPsmDbgLevel >= STP_PSM_LOG_LOUD) \ -+ pr_debug(PFX_PSM "%s: " fmt, __func__ , ##arg); \ -+} while (0) -+#define STP_PSM_DBG_FUNC(fmt, arg...) \ -+do { \ -+ if (gPsmDbgLevel >= STP_PSM_LOG_DBG) \ -+ pr_debug(PFX_PSM "%s: " fmt, __func__ , ##arg); \ -+} while (0) -+#define STP_PSM_INFO_FUNC(fmt, arg...) \ -+do { \ -+ if (gPsmDbgLevel >= STP_PSM_LOG_INFO) \ -+ pr_debug(PFX_PSM "[I]%s: " fmt, __func__ , ##arg); \ -+} while (0) -+#define STP_PSM_WARN_FUNC(fmt, arg...) \ -+do { \ -+ if (gPsmDbgLevel >= STP_PSM_LOG_WARN) \ -+ pr_warn(PFX_PSM "[W]%s: " fmt, __func__ , ##arg); \ -+} while (0) -+#define STP_PSM_ERR_FUNC(fmt, arg...) \ -+do { \ -+ if (gPsmDbgLevel >= STP_PSM_LOG_ERR) \ -+ pr_err(PFX_PSM "[E]%s(%d):ERROR! " fmt, __func__ , __LINE__, ##arg); \ -+} while (0) -+#define STP_PSM_TRC_FUNC(f) \ -+do { \ -+ if (gPsmDbgLevel >= STP_PSM_LOG_DBG) \ -+ pr_debug(PFX_PSM "<%s> <%d>\n", __func__, __LINE__); \ -+} while (0) -+ -+static inline INT32 _stp_psm_notify_wmt(MTKSTP_PSM_T *stp_psm, const MTKSTP_PSM_ACTION_T action); -+static INT32 _stp_psm_thread_lock_aquire(MTKSTP_PSM_T *stp_psm); -+static INT32 _stp_psm_thread_lock_release(MTKSTP_PSM_T *stp_psm); -+static INT32 _stp_psm_dbg_dmp_in(STP_PSM_RECORD_T *stp_psm_dbg, UINT32 flag, UINT32 line_num); -+static INT32 _stp_psm_dbg_out_printk(STP_PSM_RECORD_T *stp_psm_dbg); -+ -+static INT32 _stp_psm_opid_dbg_dmp_in(P_STP_PSM_OPID_RECORD p_opid_dbg, UINT32 opid, UINT32 line_num); -+static INT32 _stp_psm_opid_dbg_out_printk(P_STP_PSM_OPID_RECORD p_opid_dbg); -+ -+static const char *g_psm_state[STP_PSM_MAX_STATE] = { -+ "ACT", -+ "ACT_INACT", -+ "INACT", -+ "INACT_ACT" -+}; -+ -+static const char *g_psm_action[STP_PSM_MAX_ACTION] = { -+ "SLEEP", -+ "HOST_AWAKE", -+ "WAKEUP", -+ "EIRQ", -+ "ROLL_BACK" -+}; -+ -+static const char *g_psm_op_name[STP_OPID_PSM_NUM] = { -+ "STP_OPID_PSM_SLEEP", -+ "STP_OPID_PSM_WAKEUP", -+ "STP_OPID_PSM_HOST_AWAKE", -+ "STP_OPID_PSM_EXIT" -+}; -+ -+static int _stp_psm_release_data(MTKSTP_PSM_T *stp_psm); -+ -+static inline int _stp_psm_get_state(MTKSTP_PSM_T *stp_psm); -+ -+static int _stp_psm_is_redundant_active_op(P_OSAL_OP pOp, P_OSAL_OP_Q pOpQ); -+ -+static int _stp_psm_clean_up_redundant_active_op(P_OSAL_OP_Q pOpQ); -+static MTK_WCN_BOOL _stp_psm_is_quick_ps_support(VOID); -+ -+MTK_WCN_BOOL mtk_wcn_stp_psm_dbg_level(UINT32 dbglevel) -+{ -+ if (dbglevel <= 4) { -+ gPsmDbgLevel = dbglevel; -+ STP_PSM_INFO_FUNC("gPsmDbgLevel = %d\n", gPsmDbgLevel); -+ return true; -+ } -+ STP_PSM_INFO_FUNC("invalid psm debug level. gPsmDbgLevel = %d\n", gPsmDbgLevel); -+ -+ return false; -+} -+ -+static INT32 _stp_psm_handler(MTKSTP_PSM_T *stp_psm, P_STP_OP pStpOp) -+{ -+ INT32 ret = -1; -+ -+ /* if (NULL == pStpOp) */ -+ /* { */ -+ /* return -1; */ -+ /* } */ -+ ret = _stp_psm_thread_lock_aquire(stp_psm); -+ if (ret) { -+ STP_PSM_ERR_FUNC("--->lock psm_thread_lock failed ret=%d\n", ret); -+ return ret; -+ } -+ -+ switch (pStpOp->opId) { -+ case STP_OPID_PSM_EXIT: -+ /* TODO: clean all up? */ -+ ret = 0; -+ break; -+ -+ case STP_OPID_PSM_SLEEP: -+ if (stp_psm_check_sleep_enable(stp_psm) > 0) -+ ret = _stp_psm_notify_wmt(stp_psm, SLEEP); -+ else -+ STP_PSM_INFO_FUNC("cancel sleep request\n"); -+ -+ break; -+ -+ case STP_OPID_PSM_WAKEUP: -+ ret = _stp_psm_notify_wmt(stp_psm, WAKEUP); -+ break; -+ -+ case STP_OPID_PSM_HOST_AWAKE: -+ ret = _stp_psm_notify_wmt(stp_psm, HOST_AWAKE); -+ break; -+ -+ default: -+ STP_PSM_ERR_FUNC("invalid operation id (%d)\n", pStpOp->opId); -+ ret = -1; -+ break; -+ } -+ _stp_psm_thread_lock_release(stp_psm); -+ return ret; -+} -+ -+static P_OSAL_OP _stp_psm_get_op(MTKSTP_PSM_T *stp_psm, P_OSAL_OP_Q pOpQ) -+{ -+ P_OSAL_OP pOp; -+ -+ if (!pOpQ) { -+ STP_PSM_WARN_FUNC("pOpQ == NULL\n"); -+ return NULL; -+ } -+ -+ osal_lock_unsleepable_lock(&(stp_psm->wq_spinlock)); -+ /* acquire lock success */ -+ RB_GET(pOpQ, pOp); -+ -+ if ((pOpQ == &stp_psm->rActiveOpQ) && (NULL != pOp)) { -+ /* stp_psm->current_active_op = pOp; */ -+ stp_psm->last_active_opId = pOp->op.opId; -+ } -+ osal_unlock_unsleepable_lock(&(stp_psm->wq_spinlock)); -+ -+ if ((pOpQ == &stp_psm->rActiveOpQ) && (NULL != pOp)) -+ STP_PSM_DBG_FUNC("last_active_opId(%d)\n", stp_psm->last_active_opId); -+ -+ if (!pOp) -+ STP_PSM_WARN_FUNC("RB_GET fail\n"); -+ -+ return pOp; -+} -+ -+static INT32 _stp_psm_dump_active_q(P_OSAL_OP_Q pOpQ) -+{ -+ UINT32 read_idx; -+ UINT32 write_idx; -+ UINT32 opId; -+ -+ if (pOpQ == &stp_psm->rActiveOpQ) { -+ read_idx = stp_psm->rActiveOpQ.read; -+ write_idx = stp_psm->rActiveOpQ.write; -+ -+ STP_PSM_DBG_FUNC("Active op list:++\n"); -+ while ((read_idx & RB_MASK(pOpQ)) != (write_idx & RB_MASK(pOpQ))) { -+ opId = pOpQ->queue[read_idx & RB_MASK(pOpQ)]->op.opId; -+ if (opId < STP_OPID_PSM_NUM) -+ STP_PSM_DBG_FUNC("%s\n", g_psm_op_name[opId]); -+ else -+ STP_PSM_WARN_FUNC("Unknown OP Id\n"); -+ -+ ++read_idx; -+ } -+ STP_PSM_DBG_FUNC("Active op list:--\n"); -+ } else { -+ STP_PSM_DBG_FUNC("%s: not active queue, dont dump\n", __func__); -+ } -+ -+ return 0; -+} -+ -+static int _stp_psm_is_redundant_active_op(P_OSAL_OP pOp, P_OSAL_OP_Q pOpQ) -+{ -+ unsigned int opId = 0; -+ unsigned int prev_opId = 0; -+ -+ /* if((pOpQ == &stp_psm->rActiveOpQ) && (NULL != stp_psm->current_active_op)) */ -+ if ((pOpQ == &stp_psm->rActiveOpQ) && (STP_OPID_PSM_INALID != stp_psm->last_active_opId)) { -+ opId = pOp->op.opId; -+ -+ if (opId == STP_OPID_PSM_SLEEP) { -+ if (RB_EMPTY(pOpQ)) { -+ /* prev_opId = stp_psm->current_active_op->op.opId; */ -+ prev_opId = stp_psm->last_active_opId; -+ } else { -+ prev_opId = pOpQ->queue[(pOpQ->write - 1) & RB_MASK(pOpQ)]->op.opId; -+ } -+ -+ if (prev_opId == STP_OPID_PSM_SLEEP) { -+ STP_PSM_DBG_FUNC("redundant sleep opId found\n"); -+ return 1; -+ } else { -+ return 0; -+ } -+ } else { -+ if (RB_EMPTY(pOpQ)) { -+ /* prev_opId = stp_psm->current_active_op->op.opId; */ -+ prev_opId = stp_psm->last_active_opId; -+ } else { -+ prev_opId = pOpQ->queue[(pOpQ->write - 1) & RB_MASK(pOpQ)]->op.opId; -+ } -+ -+ if (((opId == STP_OPID_PSM_WAKEUP) && (prev_opId == STP_OPID_PSM_WAKEUP)) || -+ ((opId == STP_OPID_PSM_HOST_AWAKE) && (prev_opId == STP_OPID_PSM_WAKEUP)) || -+ ((opId == STP_OPID_PSM_HOST_AWAKE) && (prev_opId == STP_OPID_PSM_HOST_AWAKE)) || -+ ((opId == STP_OPID_PSM_WAKEUP) && (prev_opId == STP_OPID_PSM_HOST_AWAKE)) -+ ) { -+ STP_PSM_DBG_FUNC("redundant opId found, opId(%d), preOpid(%d)\n", opId, prev_opId); -+ return 1; -+ } else { -+ return 0; -+ } -+ } -+ } else { -+ return 0; -+ } -+ -+} -+ -+static int _stp_psm_clean_up_redundant_active_op(P_OSAL_OP_Q pOpQ) -+{ -+ unsigned int prev_opId = 0; -+ unsigned int prev_prev_opId = 0; -+ -+ P_OSAL_OP pOp; -+ P_OSAL_OP_Q pFreeOpQ = &stp_psm->rFreeOpQ; -+ -+ if (pOpQ == &stp_psm->rActiveOpQ) { -+ /* sleep , wakeup | sleep, --> null | sleep (x) */ -+ /* wakeup , sleep , wakeup | sleep --> wakeup | sleep (v) */ -+ /* sleep , wakeup , sleep | wakeup --> sleep | wakeup (v) */ -+ /* xxx, sleep | sleep --> xxx, sleep (v) */ -+ /* xxx, wakeup | wakeup --> xxx, wakeup (v) */ -+ /* xxx, awake | awake --> xxx, awake (v) --> should never happen */ -+ while (RB_COUNT(pOpQ) > 2) { -+ prev_opId = pOpQ->queue[(pOpQ->write - 1) & RB_MASK(pOpQ)]->op.opId; -+ prev_prev_opId = pOpQ->queue[(pOpQ->write - 2) & RB_MASK(pOpQ)]->op.opId; -+ -+ if ((prev_opId == STP_OPID_PSM_SLEEP && prev_prev_opId == STP_OPID_PSM_WAKEUP) || -+ (prev_opId == STP_OPID_PSM_SLEEP && prev_prev_opId == STP_OPID_PSM_HOST_AWAKE) || -+ (prev_opId == STP_OPID_PSM_WAKEUP && prev_prev_opId == STP_OPID_PSM_SLEEP) || -+ (prev_opId == STP_OPID_PSM_HOST_AWAKE && prev_prev_opId == STP_OPID_PSM_SLEEP) -+ ) { -+ RB_GET(pOpQ, pOp); -+ RB_PUT(pFreeOpQ, pOp); -+ RB_GET(pOpQ, pOp); -+ RB_PUT(pFreeOpQ, pOp); -+ } else if (prev_opId == prev_prev_opId) { -+ RB_GET(pOpQ, pOp); -+ STP_PSM_DBG_FUNC("redundant opId(%d) found, remove it\n", pOp->op.opId); -+ RB_PUT(pFreeOpQ, pOp); -+ } -+ } -+ } -+ -+ return 0; -+} -+ -+static INT32 _stp_psm_put_op(MTKSTP_PSM_T *stp_psm, P_OSAL_OP_Q pOpQ, P_OSAL_OP pOp) -+{ -+ INT32 ret; -+ -+ /* if (!pOpQ || !pOp) */ -+ /* { */ -+ /* STP_PSM_WARN_FUNC("pOpQ = 0x%p, pLxOp = 0x%p\n", pOpQ, pOp); */ -+ /* return 0; */ -+ /* } */ -+ ret = 0; -+ -+ osal_lock_unsleepable_lock(&(stp_psm->wq_spinlock)); -+ /* acquire lock success */ -+ if (pOpQ == &stp_psm->rActiveOpQ) { -+ if (!_stp_psm_is_redundant_active_op(pOp, pOpQ)) { -+ /* acquire lock success */ -+ if (!RB_FULL(pOpQ)) { -+ RB_PUT(pOpQ, pOp); -+ STP_PSM_DBG_FUNC("opId(%d) enqueue\n", pOp->op.opId); -+ } else { -+ STP_PSM_INFO_FUNC("************ Active Queue Full ************\n"); -+ ret = -1; -+ } -+ -+ _stp_psm_clean_up_redundant_active_op(pOpQ); -+ } else { -+ /*redundant opId, mark ret as success */ -+ P_OSAL_OP_Q pFreeOpQ = &stp_psm->rFreeOpQ; -+ -+ if (!RB_FULL(pFreeOpQ)) -+ RB_PUT(pFreeOpQ, pOp); -+ else -+ osal_assert(!RB_FULL(pFreeOpQ)); -+ -+ ret = 0; -+ } -+ } else { -+ if (!RB_FULL(pOpQ)) -+ RB_PUT(pOpQ, pOp); -+ else -+ ret = -1; -+ -+ } -+ -+ if (pOpQ == &stp_psm->rActiveOpQ) -+ _stp_psm_dump_active_q(&stp_psm->rActiveOpQ); -+ -+ -+ osal_unlock_unsleepable_lock(&(stp_psm->wq_spinlock)); -+ STP_PSM_DBG_FUNC("stp_psm do unlock,active queue? (%s)\n", (pOpQ == &stp_psm->rActiveOpQ) ? "y" : "n"); -+ -+ if (ret) { -+ STP_PSM_WARN_FUNC("RB_FULL, RB_COUNT=%d , RB_SIZE=%d\n", RB_COUNT(pOpQ), RB_SIZE(pOpQ)); -+ return 0; -+ } else -+ return 1; -+ -+} -+ -+P_OSAL_OP _stp_psm_get_free_op(MTKSTP_PSM_T *stp_psm) -+{ -+ P_OSAL_OP pOp; -+ -+ if (stp_psm) { -+ pOp = _stp_psm_get_op(stp_psm, &stp_psm->rFreeOpQ); -+ if (pOp) -+ osal_memset(&pOp->op, 0, sizeof(pOp->op)); -+ -+ return pOp; -+ } else -+ return NULL; -+ -+} -+ -+INT32 _stp_psm_put_act_op(MTKSTP_PSM_T *stp_psm, P_OSAL_OP pOp) -+{ -+ INT32 bRet = 0; /* MTK_WCN_BOOL_FALSE; */ -+ INT32 bCleanup = 0; /* MTK_WCN_BOOL_FALSE; */ -+ INT32 wait_ret = -1; -+ P_OSAL_SIGNAL pSignal = NULL; -+ -+ do { -+ if (!stp_psm || !pOp) { -+ STP_PSM_ERR_FUNC("stp_psm = %p, pOp = %p\n", stp_psm, pOp); -+ break; -+ } -+ -+ pSignal = &pOp->signal; -+ -+ if (pSignal->timeoutValue) { -+ pOp->result = -9; -+ osal_signal_init(&pOp->signal); -+ } -+ -+ /* put to active Q */ -+ bRet = _stp_psm_put_op(stp_psm, &stp_psm->rActiveOpQ, pOp); -+ -+ if (0 == bRet) { -+ STP_PSM_WARN_FUNC("+++++++++++ Put op Active queue Fail\n"); -+ bCleanup = 1; /* MTK_WCN_BOOL_TRUE; */ -+ break; -+ } -+ _stp_psm_opid_dbg_dmp_in(g_stp_psm_opid_dbg, pOp->op.opId, __LINE__); -+ -+ /* wake up wmtd */ -+ osal_trigger_event(&stp_psm->STPd_event); -+ -+ if (pSignal->timeoutValue == 0) { -+ bRet = 1; /* MTK_WCN_BOOL_TRUE; */ -+ /* clean it in wmtd */ -+ break; -+ } -+ -+ /* wait result, clean it here */ -+ bCleanup = 1; /* MTK_WCN_BOOL_TRUE; */ -+ -+ /* check result */ -+ wait_ret = osal_wait_for_signal_timeout(&pOp->signal); -+ STP_PSM_DBG_FUNC("wait completion:%d\n", wait_ret); -+ if (!wait_ret) { -+ STP_PSM_ERR_FUNC("wait completion timeout\n"); -+ /* TODO: how to handle it? retry? */ -+ } else { -+ if (pOp->result) -+ STP_PSM_WARN_FUNC("op(%d) result:%d\n", pOp->op.opId, pOp->result); -+ /* op completes, check result */ -+ bRet = (pOp->result) ? 0 : 1; -+ } -+ } while (0); -+ -+ if (bCleanup) { -+ /* put Op back to freeQ */ -+ bRet = _stp_psm_put_op(stp_psm, &stp_psm->rFreeOpQ, pOp); -+ if (bRet == 0) -+ STP_PSM_WARN_FUNC("+++++++++++ Put op active free fail, maybe disable/enable psm\n"); -+ } -+ -+ return bRet; -+} -+ -+static INT32 _stp_psm_wait_for_msg(void *pvData) -+{ -+ MTKSTP_PSM_T *stp_psm = (MTKSTP_PSM_T *) pvData; -+ -+ STP_PSM_DBG_FUNC("%s: stp_psm->rActiveOpQ = %d\n", __func__, RB_COUNT(&stp_psm->rActiveOpQ)); -+ -+ return (!RB_EMPTY(&stp_psm->rActiveOpQ)) || osal_thread_should_stop(&stp_psm->PSMd); -+} -+ -+static INT32 _stp_psm_proc(void *pvData) -+{ -+ MTKSTP_PSM_T *stp_psm = (MTKSTP_PSM_T *) pvData; -+ P_OSAL_OP pOp; -+ UINT32 id; -+ INT32 result; -+ -+ if (!stp_psm) { -+ STP_PSM_WARN_FUNC("!stp_psm\n"); -+ return -1; -+ } -+/* STP_PSM_INFO_FUNC("wmtd starts running: pWmtDev(0x%p) [pol, rt_pri, n_pri, pri]=[%d, %d, %d, %d]\n", */ -+/* stp_psm, current->policy, current->rt_priority, current->normal_prio, current->prio); */ -+ -+ for (;;) { -+ -+ pOp = NULL; -+ -+ osal_wait_for_event(&stp_psm->STPd_event, _stp_psm_wait_for_msg, (void *)stp_psm); -+ -+ /* we set reset flag when calling stp_reset after cleanup all op. */ -+ if (osal_test_bit(STP_PSM_RESET_EN, &stp_psm->flag)) { -+ osal_clear_bit(STP_PSM_RESET_EN, &stp_psm->flag); -+ _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); -+ } -+ if (osal_thread_should_stop(&stp_psm->PSMd)) { -+ STP_PSM_INFO_FUNC("should stop now...\n"); -+ /* TODO: clean up active opQ */ -+ break; -+ } -+ -+ /* get Op from activeQ */ -+ pOp = _stp_psm_get_op(stp_psm, &stp_psm->rActiveOpQ); -+ if (!pOp) { -+ STP_PSM_WARN_FUNC("+++++++++++ Get op from activeQ fail, maybe disable/enable psm\n"); -+ continue; -+ } -+ -+ id = osal_op_get_id(pOp); -+ -+ if (id >= STP_OPID_PSM_NUM) { -+ STP_PSM_WARN_FUNC("abnormal opid id: 0x%x\n", id); -+ result = -1; -+ goto handler_done; -+ } -+ -+ result = _stp_psm_handler(stp_psm, &pOp->op); -+ -+handler_done: -+ -+ if (result) { -+ STP_PSM_WARN_FUNC("opid id(0x%x)(%s) error(%d)\n", id, -+ (id >= 4) ? ("???") : (g_psm_op_name[id]), result); -+ } -+ -+ if (osal_op_is_wait_for_signal(pOp)) -+ osal_op_raise_signal(pOp, result); -+ else { -+ /* put Op back to freeQ */ -+ if (_stp_psm_put_op(stp_psm, &stp_psm->rFreeOpQ, pOp) == 0) -+ STP_PSM_WARN_FUNC("+++++++++++ Put op to FreeOpQ fail, maybe disable/enable psm\n"); -+ } -+ -+ if (STP_OPID_PSM_EXIT == id) -+ break; -+ } -+ STP_PSM_INFO_FUNC("exits\n"); -+ -+ return 0; -+}; -+ -+static inline INT32 _stp_psm_get_time(void) -+{ -+ if (gPsmDbgLevel >= STP_PSM_LOG_LOUD) -+ osal_printtimeofday(">>>"); -+ -+ return 0; -+} -+ -+static inline INT32 _stp_psm_get_state(MTKSTP_PSM_T *stp_psm) -+{ -+ -+ if (stp_psm == NULL) -+ return STP_PSM_OPERATION_FAIL; -+ -+ if (stp_psm->work_state < STP_PSM_MAX_STATE) -+ return stp_psm->work_state; -+ STP_PSM_ERR_FUNC("work_state = %d, invalid\n", stp_psm->work_state); -+ -+ return STP_PSM_OPERATION_FAIL; -+} -+ -+static inline INT32 _stp_psm_set_state(MTKSTP_PSM_T *stp_psm, const MTKSTP_PSM_STATE_T state) -+{ -+ if (stp_psm == NULL) -+ return STP_PSM_OPERATION_FAIL; -+ -+ if (stp_psm->work_state < STP_PSM_MAX_STATE) { -+ _stp_psm_get_time(); -+ /* STP_PSM_INFO_FUNC("work_state = %s --> %s\n", -+ * g_psm_state[stp_psm->work_state], g_psm_state[state]); -+ */ -+ -+ stp_psm->work_state = state; -+ if (stp_psm->work_state != ACT) { -+ /* osal_lock_unsleepable_lock(&stp_psm->flagSpinlock); */ -+ osal_set_bit(STP_PSM_BLOCK_DATA_EN, &stp_psm->flag); -+ _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); -+ /* osal_unlock_unsleepable_lock(&stp_psm->flagSpinlock); */ -+ } -+ } else -+ STP_PSM_ERR_FUNC("work_state = %d, invalid\n", stp_psm->work_state); -+ -+ -+ return STP_PSM_OPERATION_SUCCESS; -+} -+ -+static inline INT32 _stp_psm_start_monitor(MTKSTP_PSM_T *stp_psm) -+{ -+ -+ if (!stp_psm) -+ return STP_PSM_OPERATION_FAIL; -+ -+ if (osal_test_bit(STP_PSM_WMT_EVENT_DISABLE_MONITOR, &stp_psm->flag)) { -+ STP_PSM_DBG_FUNC("STP-PSM DISABLE, DONT restart monitor!\n\r"); -+ return STP_PSM_OPERATION_SUCCESS; -+ } -+ -+ STP_PSM_LOUD_FUNC("start monitor\n"); -+ osal_timer_modify(&stp_psm->psm_timer, stp_psm->idle_time_to_sleep); -+ -+ return STP_PSM_OPERATION_SUCCESS; -+} -+ -+static inline INT32 _stp_psm_stop_monitor(MTKSTP_PSM_T *stp_psm) -+{ -+ -+ if (!stp_psm) -+ return STP_PSM_OPERATION_FAIL; -+ -+ STP_PSM_DBG_FUNC("stop monitor\n"); -+ osal_timer_stop_sync(&stp_psm->psm_timer); -+ -+ return STP_PSM_OPERATION_SUCCESS; -+} -+ -+INT32 _stp_psm_hold_data(MTKSTP_PSM_T *stp_psm, const UINT8 *buffer, const UINT32 len, const UINT8 type) -+{ -+ INT32 available_space = 0; -+ INT32 needed_space = 0; -+ UINT8 delimiter[] = { 0xbb, 0xbb }; -+ -+ if (!stp_psm) -+ return STP_PSM_OPERATION_FAIL; -+ -+ osal_lock_sleepable_lock(&stp_psm->hold_fifo_spinlock_global); -+ -+ available_space = STP_PSM_FIFO_SIZE - osal_fifo_len(&stp_psm->hold_fifo); -+ needed_space = len + sizeof(UINT8) + sizeof(UINT32) + 2; -+ -+ /* STP_PSM_INFO_FUNC("*******FIFO Available(%d), Need(%d)\n", available_space, needed_space); */ -+ -+ if (available_space < needed_space) { -+ STP_PSM_ERR_FUNC("FIFO Available!! Reset FIFO\n"); -+ osal_fifo_reset(&stp_psm->hold_fifo); -+ } -+ /* type */ -+ osal_fifo_in(&stp_psm->hold_fifo, (PUINT8) &type, sizeof(UINT8)); -+ /* length */ -+ osal_fifo_in(&stp_psm->hold_fifo, (PUINT8) &len, sizeof(UINT32)); -+ /* buffer */ -+ osal_fifo_in(&stp_psm->hold_fifo, (PUINT8) buffer, len); -+ /* delimiter */ -+ osal_fifo_in(&stp_psm->hold_fifo, (PUINT8) delimiter, 2); -+ -+ osal_unlock_sleepable_lock(&stp_psm->hold_fifo_spinlock_global); -+ -+ return len; -+ -+} -+ -+INT32 _stp_psm_has_pending_data(MTKSTP_PSM_T *stp_psm) -+{ -+ return osal_fifo_len(&stp_psm->hold_fifo); -+} -+ -+INT32 _stp_psm_release_data(MTKSTP_PSM_T *stp_psm) -+{ -+ -+ INT32 i = 20; /*Max buffered packet number */ -+ INT32 ret = 0; -+ UINT8 type = 0; -+ UINT32 len = 0; -+ UINT8 delimiter[2]; -+ -+ /* STP_PSM_ERR_FUNC("++++++++++release data++len=%d\n", osal_fifo_len(&stp_psm->hold_fifo)); */ -+ while (osal_fifo_len(&stp_psm->hold_fifo) && i > 0) { -+ /* acquire spinlock */ -+ osal_lock_sleepable_lock(&stp_psm->hold_fifo_spinlock_global); -+ -+ ret = osal_fifo_out(&stp_psm->hold_fifo, (PUINT8) &type, sizeof(UINT8)); -+ ret = osal_fifo_out(&stp_psm->hold_fifo, (PUINT8) &len, sizeof(UINT32)); -+ -+ if (len > STP_PSM_PACKET_SIZE_MAX) { -+ STP_PSM_ERR_FUNC("***psm packet's length too Long!****\n"); -+ STP_PSM_INFO_FUNC("***reset psm's fifo***\n"); -+ } else { -+ osal_memset(stp_psm->out_buf, 0, STP_PSM_TX_SIZE); -+ ret = osal_fifo_out(&stp_psm->hold_fifo, (PUINT8) stp_psm->out_buf, len); -+ } -+ -+ ret = osal_fifo_out(&stp_psm->hold_fifo, (PUINT8) delimiter, 2); -+ -+ if (delimiter[0] == 0xbb && delimiter[1] == 0xbb) { -+ /* osal_buffer_dump(stp_psm->out_buf, "psm->out_buf", len, 32); */ -+ stp_send_data_no_ps(stp_psm->out_buf, len, type); -+ } else { -+ STP_PSM_ERR_FUNC("***psm packet fifo parsing fail****\n"); -+ STP_PSM_INFO_FUNC("***reset psm's fifo***\n"); -+ -+ osal_fifo_reset(&stp_psm->hold_fifo); -+ } -+ i--; -+ osal_unlock_sleepable_lock(&stp_psm->hold_fifo_spinlock_global); -+ } -+ return STP_PSM_OPERATION_SUCCESS; -+} -+ -+static inline INT32 _stp_psm_notify_wmt_host_awake_wq(MTKSTP_PSM_T *stp_psm) -+{ -+ -+ P_OSAL_OP pOp; -+ INT32 bRet; -+ INT32 retval; -+ -+ if (stp_psm == NULL) -+ return STP_PSM_OPERATION_FAIL; -+ -+ pOp = _stp_psm_get_free_op(stp_psm); -+ if (!pOp) { -+ STP_PSM_WARN_FUNC("get_free_lxop fail\n"); -+ return -1; /* break; */ -+ } -+ -+ pOp->op.opId = STP_OPID_PSM_HOST_AWAKE; -+ pOp->signal.timeoutValue = 0; -+ bRet = _stp_psm_put_act_op(stp_psm, pOp); -+ -+ STP_PSM_DBG_FUNC("OPID(%d) type(%zd) bRet(%d)\n\n", pOp->op.opId, pOp->op.au4OpData[0], bRet); -+ -+ retval = (0 == bRet) ? (STP_PSM_OPERATION_FAIL) : 0; -+ -+ return retval; -+} -+ -+static inline INT32 _stp_psm_notify_wmt_wakeup_wq(MTKSTP_PSM_T *stp_psm) -+{ -+ P_OSAL_OP pOp; -+ INT32 bRet; -+ INT32 retval; -+ -+ if (stp_psm == NULL) -+ return STP_PSM_OPERATION_FAIL; -+ -+ pOp = _stp_psm_get_free_op(stp_psm); -+ if (!pOp) { -+ STP_PSM_WARN_FUNC("get_free_lxop fail\n"); -+ return -1; /* break; */ -+ } -+ -+ pOp->op.opId = STP_OPID_PSM_WAKEUP; -+ pOp->signal.timeoutValue = 0; -+ bRet = _stp_psm_put_act_op(stp_psm, pOp); -+ if (0 == bRet) { -+ STP_PSM_WARN_FUNC("OPID(%d) type(%zd) bRet(%s)\n\n", -+ pOp->op.opId, pOp->op.au4OpData[0], "fail"); -+ } -+ retval = (0 == bRet) ? (STP_PSM_OPERATION_FAIL) : (STP_PSM_OPERATION_SUCCESS); -+ -+ return retval; -+} -+ -+static inline INT32 _stp_psm_notify_wmt_sleep_wq(MTKSTP_PSM_T *stp_psm) -+{ -+ P_OSAL_OP pOp; -+ INT32 bRet; -+ INT32 retval; -+ -+ if (stp_psm == NULL) -+ return STP_PSM_OPERATION_FAIL; -+ -+ if (osal_test_bit(STP_PSM_WMT_EVENT_DISABLE_MONITOR_TX_HIGH_DENSITY, &stp_psm->flag)) -+ return 0; -+#if PSM_USE_COUNT_PACKAGE -+ if (osal_test_bit(STP_PSM_WMT_EVENT_DISABLE_MONITOR_RX_HIGH_DENSITY, &stp_psm->flag)) -+ return 0; -+#endif -+ if (osal_test_bit(STP_PSM_WMT_EVENT_DISABLE_MONITOR, &stp_psm->flag)) -+ return 0; -+ -+ pOp = _stp_psm_get_free_op(stp_psm); -+ if (!pOp) { -+ STP_PSM_WARN_FUNC("get_free_lxop fail\n"); -+ return -1; /* break; */ -+ } -+ -+ pOp->op.opId = STP_OPID_PSM_SLEEP; -+ pOp->signal.timeoutValue = 0; -+ bRet = _stp_psm_put_act_op(stp_psm, pOp); -+ -+ STP_PSM_DBG_FUNC("OPID(%d) type(%zd) bRet(%d)\n\n", pOp->op.opId, pOp->op.au4OpData[0], bRet); -+ -+ retval = (0 == bRet) ? (STP_PSM_OPERATION_FAIL) : 1; -+ -+ return retval; -+} -+ -+/*internal function*/ -+ -+static inline INT32 _stp_psm_reset(MTKSTP_PSM_T *stp_psm) -+{ -+ INT32 i = 0; -+ P_OSAL_OP_Q pOpQ; -+ P_OSAL_OP pOp; -+ -+ STP_PSM_DBG_FUNC("PSM MODE RESET=============================>\n\r"); -+ -+ STP_PSM_DBG_FUNC("_stp_psm_reset\n"); -+ STP_PSM_DBG_FUNC("reset-wake_lock(%d)\n", osal_wake_lock_count(&stp_psm->wake_lock)); -+ osal_wake_unlock(&stp_psm->wake_lock); -+ STP_PSM_DBG_FUNC("reset-wake_lock(%d)\n", osal_wake_lock_count(&stp_psm->wake_lock)); -+ -+ /* --> disable psm <--// */ -+ stp_psm->flag.data = 0; -+ osal_set_bit(STP_PSM_WMT_EVENT_DISABLE_MONITOR, &stp_psm->flag); -+ _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); -+ _stp_psm_stop_monitor(stp_psm); -+ -+ /* --> prepare the op list <--// */ -+ osal_lock_unsleepable_lock(&(stp_psm->wq_spinlock)); -+ RB_INIT(&stp_psm->rFreeOpQ, STP_OP_BUF_SIZE); -+ RB_INIT(&stp_psm->rActiveOpQ, STP_OP_BUF_SIZE); -+ -+ /* stp_psm->current_active_op = NULL; */ -+ stp_psm->last_active_opId = STP_OPID_PSM_INALID; -+ -+ pOpQ = &stp_psm->rFreeOpQ; -+ for (i = 0; i < STP_OP_BUF_SIZE; i++) { -+ if (!RB_FULL(pOpQ)) { -+ pOp = &stp_psm->arQue[i]; -+ RB_PUT(pOpQ, pOp); -+ } -+ } -+ osal_unlock_unsleepable_lock(&(stp_psm->wq_spinlock)); -+ -+ /* --> clean up interal data structure<--// */ -+ _stp_psm_set_state(stp_psm, ACT); -+ -+ osal_lock_sleepable_lock(&stp_psm->hold_fifo_spinlock_global); -+ osal_fifo_reset(&stp_psm->hold_fifo); -+ osal_unlock_sleepable_lock(&stp_psm->hold_fifo_spinlock_global); -+ -+ /* --> stop psm thread wait <--// */ -+ osal_set_bit(STP_PSM_RESET_EN, &stp_psm->flag); -+ _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); -+ osal_trigger_event(&stp_psm->wait_wmt_q); -+ -+ STP_PSM_DBG_FUNC("PSM MODE RESET<============================\n\r"); -+ -+ return STP_PSM_OPERATION_SUCCESS; -+} -+ -+static INT32 _stp_psm_wait_wmt_event(void *pvData) -+{ -+ MTKSTP_PSM_T *stp_psm = (MTKSTP_PSM_T *) pvData; -+ -+ STP_PSM_DBG_FUNC("%s, stp_psm->flag= %ld\n", __func__, stp_psm->flag.data); -+ -+ return (osal_test_bit(STP_PSM_WMT_EVENT_SLEEP_EN, &stp_psm->flag)) || -+ (osal_test_bit(STP_PSM_WMT_EVENT_WAKEUP_EN, &stp_psm->flag)) || -+ (osal_test_bit(STP_PSM_WMT_EVENT_ROLL_BACK_EN, &stp_psm->flag)) || -+ (osal_test_bit(STP_PSM_RESET_EN, &stp_psm->flag)); -+} -+ -+static inline INT32 _stp_psm_wait_wmt_event_wq(MTKSTP_PSM_T *stp_psm) -+{ -+ -+ INT32 retval = 0; -+ -+ if (stp_psm == NULL) -+ return STP_PSM_OPERATION_FAIL; -+ -+ osal_wait_for_event_timeout(&stp_psm->wait_wmt_q, _stp_psm_wait_wmt_event, (void *)stp_psm); -+ -+ if (osal_test_bit(STP_PSM_WMT_EVENT_WAKEUP_EN, &stp_psm->flag)) { -+ osal_clear_bit(STP_PSM_WMT_EVENT_WAKEUP_EN, &stp_psm->flag); -+ _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); -+/* osal_lock_unsleepable_lock(&stp_psm->flagSpinlock); */ -+ /* STP send data here: STP enqueue data to psm buffer. */ -+ _stp_psm_release_data(stp_psm); -+ /* STP send data here: STP enqueue data to psm buffer. We release packet by the next one. */ -+ osal_clear_bit(STP_PSM_BLOCK_DATA_EN, &stp_psm->flag); -+ _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); -+ /* STP send data here: STP sends data directly without PSM. */ -+ _stp_psm_set_state(stp_psm, ACT); -+/* osal_unlock_unsleepable_lock(&stp_psm->flagSpinlock); */ -+ -+ if (stp_psm_is_quick_ps_support()) -+ stp_psm_notify_wmt_sleep(stp_psm); -+ else -+ _stp_psm_start_monitor(stp_psm); -+ } else if (osal_test_bit(STP_PSM_WMT_EVENT_SLEEP_EN, &stp_psm->flag)) { -+ osal_clear_bit(STP_PSM_WMT_EVENT_SLEEP_EN, &stp_psm->flag); -+ _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); -+ _stp_psm_set_state(stp_psm, INACT); -+ -+ STP_PSM_DBG_FUNC("mt_combo_plt_enter_deep_idle++\n"); -+ mt_combo_plt_enter_deep_idle(COMBO_IF_BTIF); -+ STP_PSM_DBG_FUNC("mt_combo_plt_enter_deep_idle--\n"); -+ -+ STP_PSM_DBG_FUNC("sleep-wake_lock(%d)\n", osal_wake_lock_count(&stp_psm->wake_lock)); -+ osal_wake_unlock(&stp_psm->wake_lock); -+ STP_PSM_DBG_FUNC("sleep-wake_lock#(%d)\n", osal_wake_lock_count(&stp_psm->wake_lock)); -+ } else if (osal_test_bit(STP_PSM_WMT_EVENT_ROLL_BACK_EN, &stp_psm->flag)) { -+ osal_clear_bit(STP_PSM_WMT_EVENT_ROLL_BACK_EN, &stp_psm->flag); -+ _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); -+ if (_stp_psm_get_state(stp_psm) == ACT_INACT) { -+ /* osal_lock_unsleepable_lock(&stp_psm->flagSpinlock); */ -+ _stp_psm_release_data(stp_psm); -+ osal_clear_bit(STP_PSM_BLOCK_DATA_EN, &stp_psm->flag); -+ _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); -+ _stp_psm_set_state(stp_psm, ACT); -+ /* osal_unlock_unsleepable_lock(&stp_psm->flagSpinlock); */ -+ } else if (_stp_psm_get_state(stp_psm) == INACT_ACT) { -+ _stp_psm_set_state(stp_psm, INACT); -+ STP_PSM_INFO_FUNC("[WARNING]PSM state rollback due too wakeup fail\n"); -+ } -+ } else if (osal_test_bit(STP_PSM_RESET_EN, &stp_psm->flag)) { -+ osal_clear_bit(STP_PSM_WMT_EVENT_ROLL_BACK_EN, &stp_psm->flag); -+ _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); -+ } else { -+ STP_PSM_ERR_FUNC("flag = %ld<== Abnormal flag be set!!\n\r", stp_psm->flag.data); -+ STP_PSM_ERR_FUNC("state = %d, flag = %ld\n", stp_psm->work_state, stp_psm->flag.data); -+ wcn_psm_flag_trigger_collect_ftrace(); /* trigger collect SYS_FTRACE */ -+ _stp_psm_dbg_out_printk(g_stp_psm_dbg); -+ } -+ retval = STP_PSM_OPERATION_SUCCESS; -+ -+ return retval; -+} -+ -+static inline INT32 _stp_psm_notify_stp(MTKSTP_PSM_T *stp_psm, const MTKSTP_PSM_ACTION_T action) -+{ -+ -+ INT32 retval = 0; -+ -+ if (action == EIRQ) { -+ STP_PSM_DBG_FUNC("Call _stp_psm_notify_wmt_host_awake_wq\n\r"); -+ -+ _stp_psm_notify_wmt_host_awake_wq(stp_psm); -+ -+ return STP_PSM_OPERATION_FAIL; -+ } -+ -+ if ((_stp_psm_get_state(stp_psm) < STP_PSM_MAX_STATE) && (_stp_psm_get_state(stp_psm) >= 0)) { -+ STP_PSM_DBG_FUNC("state = %s, action=%s\n\r", g_psm_state[_stp_psm_get_state(stp_psm)], -+ g_psm_action[action]); -+ } -+ /* If STP trigger WAKEUP and SLEEP, to do the job below */ -+ switch (_stp_psm_get_state(stp_psm)) { -+ /* stp trigger */ -+ case ACT_INACT: -+ -+ if (action == SLEEP) { -+ STP_PSM_LOUD_FUNC("Action = %s, ACT_INACT state, ready to INACT\n\r", g_psm_action[action]); -+ osal_clear_bit(STP_PSM_WMT_EVENT_WAKEUP_EN, &stp_psm->flag); -+ _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); -+ osal_set_bit(STP_PSM_WMT_EVENT_SLEEP_EN, &stp_psm->flag); -+ _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); -+ /* wake_up(&stp_psm->wait_wmt_q); */ -+ osal_trigger_event(&stp_psm->wait_wmt_q); -+ } else if (action == ROLL_BACK) { -+ STP_PSM_LOUD_FUNC("Action = %s, ACT_INACT state, back to ACT\n\r", g_psm_action[action]); -+ /* stp_psm->flag &= ~STP_PSM_WMT_EVENT_ROLL_BACK_EN; */ -+ osal_set_bit(STP_PSM_WMT_EVENT_ROLL_BACK_EN, &stp_psm->flag); -+ _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); -+ /* wake_up(&stp_psm->wait_wmt_q); */ -+ osal_trigger_event(&stp_psm->wait_wmt_q); -+ } else { -+ if (action < STP_PSM_MAX_ACTION) { -+ STP_PSM_ERR_FUNC("Action = %s, ACT_INACT state, the case should not happens\n\r", -+ g_psm_action[action]); -+ STP_PSM_ERR_FUNC("state = %d, flag = %ld\n", stp_psm->work_state, stp_psm->flag.data); -+ } else { -+ STP_PSM_ERR_FUNC("Invalid Action!!\n\r"); -+ } -+ _stp_psm_dbg_out_printk(g_stp_psm_dbg); -+ retval = STP_PSM_OPERATION_FAIL; -+ } -+ break; -+ /* stp trigger */ -+ -+ case INACT_ACT: -+ -+ if (action == WAKEUP) { -+ STP_PSM_LOUD_FUNC("Action = %s, INACT_ACT state, ready to ACT\n\r", g_psm_action[action]); -+ osal_clear_bit(STP_PSM_WMT_EVENT_SLEEP_EN, &stp_psm->flag); -+ _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); -+ osal_set_bit(STP_PSM_WMT_EVENT_WAKEUP_EN, &stp_psm->flag); -+ _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); -+ /* wake_up(&stp_psm->wait_wmt_q); */ -+ osal_trigger_event(&stp_psm->wait_wmt_q); -+ } else if (action == HOST_AWAKE) { -+ STP_PSM_LOUD_FUNC("Action = %s, INACT_ACT state, ready to ACT\n\r", g_psm_action[action]); -+ osal_clear_bit(STP_PSM_WMT_EVENT_SLEEP_EN, &stp_psm->flag); -+ _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); -+ osal_set_bit(STP_PSM_WMT_EVENT_WAKEUP_EN, &stp_psm->flag); -+ _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); -+ /* wake_up(&stp_psm->wait_wmt_q); */ -+ osal_trigger_event(&stp_psm->wait_wmt_q); -+ } else if (action == ROLL_BACK) { -+ STP_PSM_LOUD_FUNC("Action = %s, INACT_ACT state, back to INACT\n\r", g_psm_action[action]); -+ osal_set_bit(STP_PSM_WMT_EVENT_ROLL_BACK_EN, &stp_psm->flag); -+ _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); -+ /* wake_up(&stp_psm->wait_wmt_q); */ -+ osal_trigger_event(&stp_psm->wait_wmt_q); -+ } else { -+ if (action < STP_PSM_MAX_ACTION) { -+ STP_PSM_ERR_FUNC("Action = %s, INACT_ACT state, the case should not happens\n\r", -+ g_psm_action[action]); -+ STP_PSM_ERR_FUNC("state = %d, flag = %ld\n", stp_psm->work_state, stp_psm->flag.data); -+ } else { -+ STP_PSM_ERR_FUNC("Invalid Action!!\n\r"); -+ } -+ _stp_psm_dbg_out_printk(g_stp_psm_dbg); -+ retval = STP_PSM_OPERATION_FAIL; -+ } -+ break; -+ -+ case INACT: -+ -+ if (action < STP_PSM_MAX_ACTION) { -+ STP_PSM_ERR_FUNC("Action = %s, INACT state, the case should not happens\n\r", -+ g_psm_action[action]); -+ STP_PSM_ERR_FUNC("state = %d, flag = %ld\n", stp_psm->work_state, stp_psm->flag.data); -+ } else { -+ STP_PSM_ERR_FUNC("Invalid Action!!\n\r"); -+ } -+ _stp_psm_dbg_out_printk(g_stp_psm_dbg); -+ retval = -1; -+ -+ break; -+ -+ case ACT: -+ -+ if (action < STP_PSM_MAX_ACTION) { -+ STP_PSM_ERR_FUNC("Action = %s, ACT state, the case should not happens\n\r", -+ g_psm_action[action]); -+ STP_PSM_ERR_FUNC("state = %d, flag = %ld\n", stp_psm->work_state, stp_psm->flag.data); -+ } else { -+ STP_PSM_ERR_FUNC("Invalid Action!!\n\r"); -+ } -+ _stp_psm_dbg_out_printk(g_stp_psm_dbg); -+ retval = STP_PSM_OPERATION_FAIL; -+ -+ break; -+ -+ default: -+ -+ /*invalid */ -+ if (action < STP_PSM_MAX_ACTION) { -+ STP_PSM_ERR_FUNC("Action = %s, Invalid state, the case should not happens\n\r", -+ g_psm_action[action]); -+ STP_PSM_ERR_FUNC("state = %d, flag = %ld\n", stp_psm->work_state, stp_psm->flag.data); -+ } else { -+ STP_PSM_ERR_FUNC("Invalid Action!!\n\r"); -+ } -+ _stp_psm_dbg_out_printk(g_stp_psm_dbg); -+ retval = STP_PSM_OPERATION_FAIL; -+ -+ break; -+ } -+ -+ return retval; -+ -+} -+ -+static inline INT32 _stp_psm_notify_wmt(MTKSTP_PSM_T *stp_psm, const MTKSTP_PSM_ACTION_T action) -+{ -+ INT32 ret = 0; -+ -+ if (stp_psm == NULL) -+ return STP_PSM_OPERATION_FAIL; -+ -+ switch (_stp_psm_get_state(stp_psm)) { -+ case ACT: -+ -+ if (action == SLEEP) { -+ if (osal_test_bit(STP_PSM_WMT_EVENT_DISABLE_MONITOR, &stp_psm->flag)) { -+ STP_PSM_ERR_FUNC("psm monitor disabled, can't do sleep op\n"); -+ return STP_PSM_OPERATION_FAIL; -+ } -+ -+ _stp_psm_set_state(stp_psm, ACT_INACT); -+ -+ _stp_psm_release_data(stp_psm); -+ -+ if (stp_psm->wmt_notify) { -+ stp_psm->wmt_notify(SLEEP); -+ _stp_psm_wait_wmt_event_wq(stp_psm); -+ } else { -+ STP_PSM_ERR_FUNC("stp_psm->wmt_notify = NULL\n"); -+ ret = STP_PSM_OPERATION_FAIL; -+ } -+ } else if (action == WAKEUP || action == HOST_AWAKE) { -+ STP_PSM_INFO_FUNC("In ACT state, dont do WAKEUP/HOST_AWAKE again\n"); -+ _stp_psm_release_data(stp_psm); -+ } else { -+ STP_PSM_ERR_FUNC("invalid operation, the case should not happen\n"); -+ STP_PSM_ERR_FUNC("state = %d, flag = %ld\n", stp_psm->work_state, stp_psm->flag.data); -+ _stp_psm_dbg_out_printk(g_stp_psm_dbg); -+ ret = STP_PSM_OPERATION_FAIL; -+ -+ } -+ -+ break; -+ -+ case INACT: -+ -+ if (action == WAKEUP) { -+ _stp_psm_set_state(stp_psm, INACT_ACT); -+ -+ if (stp_psm->wmt_notify) { -+ STP_PSM_DBG_FUNC("wakeup +wake_lock(%d)\n", osal_wake_lock_count(&stp_psm->wake_lock)); -+ osal_wake_lock(&stp_psm->wake_lock); -+ STP_PSM_DBG_FUNC("wakeup +wake_lock(%d)#\n", osal_wake_lock_count(&stp_psm->wake_lock)); -+ -+ STP_PSM_DBG_FUNC("mt_combo_plt_exit_deep_idle++\n"); -+ mt_combo_plt_exit_deep_idle(COMBO_IF_BTIF); -+ STP_PSM_DBG_FUNC("mt_combo_plt_exit_deep_idle--\n"); -+ -+ stp_psm->wmt_notify(WAKEUP); -+ _stp_psm_wait_wmt_event_wq(stp_psm); -+ } else { -+ STP_PSM_ERR_FUNC("stp_psm->wmt_notify = NULL\n"); -+ ret = STP_PSM_OPERATION_FAIL; -+ } -+ } else if (action == HOST_AWAKE) { -+ _stp_psm_set_state(stp_psm, INACT_ACT); -+ -+ if (stp_psm->wmt_notify) { -+ STP_PSM_DBG_FUNC("host awake +wake_lock(%d)\n", -+ osal_wake_lock_count(&stp_psm->wake_lock)); -+ osal_wake_lock(&stp_psm->wake_lock); -+ STP_PSM_DBG_FUNC("host awake +wake_lock(%d)#\n", -+ osal_wake_lock_count(&stp_psm->wake_lock)); -+ -+ STP_PSM_DBG_FUNC("mt_combo_plt_exit_deep_idle++\n"); -+ mt_combo_plt_exit_deep_idle(COMBO_IF_BTIF); -+ STP_PSM_DBG_FUNC("mt_combo_plt_exit_deep_idle--\n"); -+ -+ stp_psm->wmt_notify(HOST_AWAKE); -+ _stp_psm_wait_wmt_event_wq(stp_psm); -+ } else { -+ STP_PSM_ERR_FUNC("stp_psm->wmt_notify = NULL\n"); -+ ret = STP_PSM_OPERATION_FAIL; -+ } -+ } else if (action == SLEEP) { -+ STP_PSM_INFO_FUNC("In INACT state, dont do SLEEP again\n"); -+ } else { -+ STP_PSM_ERR_FUNC("invalid operation, the case should not happen\n"); -+ STP_PSM_ERR_FUNC("state = %d, flag = %ld\n", stp_psm->work_state, stp_psm->flag.data); -+ _stp_psm_dbg_out_printk(g_stp_psm_dbg); -+ ret = STP_PSM_OPERATION_FAIL; -+ } -+ -+ break; -+ -+ default: -+ -+ /*invalid */ -+ STP_PSM_ERR_FUNC("invalid state, the case should not happen\n"); -+ STP_PSM_ERR_FUNC("state = %d, flag = %ld\n", stp_psm->work_state, stp_psm->flag.data); -+ _stp_psm_dbg_out_printk(g_stp_psm_dbg); -+ ret = STP_PSM_OPERATION_FAIL; -+ -+ break; -+ } -+ return ret; -+} -+ -+static inline void _stp_psm_stp_is_idle(unsigned long data) -+{ -+ MTKSTP_PSM_T *stp_psm = (MTKSTP_PSM_T *) data; -+ -+ osal_clear_bit(STP_PSM_WMT_EVENT_DISABLE_MONITOR_RX_HIGH_DENSITY, &stp_psm->flag); -+ _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); -+ osal_clear_bit(STP_PSM_WMT_EVENT_DISABLE_MONITOR_TX_HIGH_DENSITY, &stp_psm->flag); -+ _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); -+ if (osal_test_bit(STP_PSM_WMT_EVENT_DISABLE_MONITOR, &stp_psm->flag)) { -+ STP_PSM_DBG_FUNC("STP-PSM DISABLE!\n"); -+ return; -+ } -+ -+ if (1 == _stp_psm_notify_wmt_sleep_wq(stp_psm)) -+ STP_PSM_INFO_FUNC("**IDLE is over %d msec, go to sleep!!!**\n", stp_psm->idle_time_to_sleep); -+} -+ -+static inline INT32 _stp_psm_init_monitor(MTKSTP_PSM_T *stp_psm) -+{ -+ if (!stp_psm) -+ return STP_PSM_OPERATION_FAIL; -+ -+ STP_PSM_INFO_FUNC("init monitor\n"); -+ -+ stp_psm->psm_timer.timeoutHandler = _stp_psm_stp_is_idle; -+ stp_psm->psm_timer.timeroutHandlerData = (unsigned long)stp_psm; -+ osal_timer_create(&stp_psm->psm_timer); -+ -+ return STP_PSM_OPERATION_SUCCESS; -+} -+ -+static inline INT32 _stp_psm_deinit_monitor(MTKSTP_PSM_T *stp_psm) -+{ -+ -+ if (!stp_psm) -+ return STP_PSM_OPERATION_FAIL; -+ -+ STP_PSM_INFO_FUNC("deinit monitor\n"); -+ -+ osal_timer_stop_sync(&stp_psm->psm_timer); -+ -+ return 0; -+} -+ -+static inline INT32 _stp_psm_is_to_block_traffic(MTKSTP_PSM_T *stp_psm) -+{ -+ INT32 iRet = -1; -+ -+/* osal_lock_unsleepable_lock(&stp_psm->flagSpinlock); */ -+ -+ if (osal_test_bit(STP_PSM_BLOCK_DATA_EN, &stp_psm->flag)) -+ iRet = 1; -+ else -+ iRet = 0; -+ -+/* osal_unlock_unsleepable_lock(&stp_psm->flagSpinlock); */ -+ return iRet; -+} -+ -+static inline INT32 _stp_psm_is_disable(MTKSTP_PSM_T *stp_psm) -+{ -+ if (osal_test_bit(STP_PSM_WMT_EVENT_DISABLE_MONITOR, &stp_psm->flag)) -+ return 1; -+ else -+ return 0; -+} -+ -+static inline INT32 _stp_psm_do_wait(MTKSTP_PSM_T *stp_psm, MTKSTP_PSM_STATE_T state) -+{ -+ -+#define POLL_WAIT 20 /* 200 */ -+#define POLL_WAIT_TIME 2000 -+ -+ INT32 i = 0; -+ INT32 limit = POLL_WAIT_TIME / POLL_WAIT; -+ -+ while (_stp_psm_get_state(stp_psm) != state && i < limit) { -+ osal_sleep_ms(POLL_WAIT); -+ i++; -+ STP_PSM_INFO_FUNC("STP is waiting state for %s, i=%d, state = %d\n", g_psm_state[state], i, -+ _stp_psm_get_state(stp_psm)); -+ } -+ -+ if (i == limit) { -+ STP_PSM_WARN_FUNC("-Wait for %s takes %d msec\n", g_psm_state[state], i * POLL_WAIT); -+ _stp_psm_opid_dbg_out_printk(g_stp_psm_opid_dbg); -+ return STP_PSM_OPERATION_FAIL; -+ } -+ STP_PSM_DBG_FUNC("+Total waits for %s takes %d msec\n", g_psm_state[state], i * POLL_WAIT); -+ /* _stp_psm_dbg_out_printk(g_stp_psm_opid_dbg); */ -+ return STP_PSM_OPERATION_SUCCESS; -+} -+ -+static inline INT32 _stp_psm_do_wakeup(MTKSTP_PSM_T *stp_psm) -+{ -+ -+ INT32 ret = 0; -+ INT32 retry = 10; -+ P_OSAL_OP_Q pOpQ; -+ P_OSAL_OP pOp; -+ -+ STP_PSM_LOUD_FUNC("*** Do Force Wakeup!***\n\r"); -+ -+ /* <1>If timer is active, we will stop it. */ -+ _stp_psm_stop_monitor(stp_psm); -+ -+ osal_lock_unsleepable_lock(&(stp_psm->wq_spinlock)); -+ -+ pOpQ = &stp_psm->rFreeOpQ; -+ -+ while (!RB_EMPTY(&stp_psm->rActiveOpQ)) { -+ RB_GET(&stp_psm->rActiveOpQ, pOp); -+ if (NULL != pOp && !RB_FULL(pOpQ)) { -+ STP_PSM_DBG_FUNC("opid = %d\n", pOp->op.opId); -+ RB_PUT(pOpQ, pOp); -+ } else { -+ STP_PSM_ERR_FUNC("clear up active queue fail, freeQ full\n"); -+ } -+ } -+ osal_unlock_unsleepable_lock(&(stp_psm->wq_spinlock)); -+ /* <5>We issue wakeup request into op queue. and wait for active. */ -+ do { -+ ret = _stp_psm_notify_wmt_wakeup_wq(stp_psm); -+ -+ if (ret == STP_PSM_OPERATION_SUCCESS) { -+ ret = _stp_psm_do_wait(stp_psm, ACT); -+ -+ /* STP_PSM_INFO_FUNC("<< wait ret = %d, num of activeQ = %d\n", -+ * ret, RB_COUNT(&stp_psm->rActiveOpQ)); -+ */ -+ if (ret == STP_PSM_OPERATION_SUCCESS) -+ break; -+ } else -+ STP_PSM_ERR_FUNC("_stp_psm_notify_wmt_wakeup_wq fail!!\n"); -+ -+ /* STP_PSM_INFO_FUNC("retry = %d\n", retry); */ -+ retry--; -+ -+ if (retry == 0) -+ break; -+ } while (1); -+ -+ if (retry == 0) -+ return STP_PSM_OPERATION_FAIL; -+ else -+ return STP_PSM_OPERATION_SUCCESS; -+} -+ -+static inline INT32 _stp_psm_disable(MTKSTP_PSM_T *stp_psm) -+{ -+ INT32 ret = STP_PSM_OPERATION_FAIL; -+ -+ STP_PSM_DBG_FUNC("PSM Disable start\n\r"); -+ -+ osal_set_bit(STP_PSM_WMT_EVENT_DISABLE_MONITOR, &stp_psm->flag); -+ _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); -+ ret = _stp_psm_do_wakeup(stp_psm); -+ if (ret == STP_PSM_OPERATION_SUCCESS) -+ STP_PSM_DBG_FUNC("PSM Disable Success\n"); -+ else -+ STP_PSM_ERR_FUNC("***PSM Disable Fail***\n"); -+ -+ return ret; -+} -+ -+static inline INT32 _stp_psm_enable(MTKSTP_PSM_T *stp_psm, INT32 idle_time_to_sleep) -+{ -+ INT32 ret = STP_PSM_OPERATION_FAIL; -+ -+ STP_PSM_LOUD_FUNC("PSM Enable start\n\r"); -+ -+ osal_set_bit(STP_PSM_WMT_EVENT_DISABLE_MONITOR, &stp_psm->flag); -+ _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); -+ -+ ret = _stp_psm_do_wakeup(stp_psm); -+ if (ret == STP_PSM_OPERATION_SUCCESS) { -+ osal_clear_bit(STP_PSM_WMT_EVENT_DISABLE_MONITOR, &stp_psm->flag); -+ _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); -+ stp_psm->idle_time_to_sleep = idle_time_to_sleep; -+ -+ if (osal_wake_lock_count(&stp_psm->wake_lock) == 0) { -+ STP_PSM_DBG_FUNC("psm_en+wake_lock(%d)\n", osal_wake_lock_count(&stp_psm->wake_lock)); -+ osal_wake_lock(&stp_psm->wake_lock); -+ STP_PSM_DBG_FUNC("psm_en+wake_lock(%d)#\n", osal_wake_lock_count(&stp_psm->wake_lock)); -+ } -+ -+ _stp_psm_start_monitor(stp_psm); -+ -+ STP_PSM_DBG_FUNC("PSM Enable succeed\n\r"); -+ } else -+ STP_PSM_ERR_FUNC("***PSM Enable Fail***\n"); -+ -+ return ret; -+} -+ -+INT32 _stp_psm_thread_lock_aquire(MTKSTP_PSM_T *stp_psm) -+{ -+ return osal_lock_sleepable_lock(&stp_psm->stp_psm_lock); -+} -+ -+INT32 _stp_psm_thread_lock_release(MTKSTP_PSM_T *stp_psm) -+{ -+ osal_unlock_sleepable_lock(&stp_psm->stp_psm_lock); -+ return 0; -+} -+ -+MTK_WCN_BOOL _stp_psm_is_quick_ps_support(VOID) -+{ -+ if (stp_psm->is_wmt_quick_ps_support) -+ return (*(stp_psm->is_wmt_quick_ps_support)) (); -+ -+ STP_PSM_DBG_FUNC("stp_psm->is_wmt_quick_ps_support is NULL, return false\n\r"); -+ return MTK_WCN_BOOL_FALSE; -+} -+ -+MTK_WCN_BOOL stp_psm_is_quick_ps_support(VOID) -+{ -+ return _stp_psm_is_quick_ps_support(); -+} -+ -+#if PSM_USE_COUNT_PACKAGE -+int stp_psm_disable_by_tx_rx_density(MTKSTP_PSM_T *stp_psm, int dir) -+{ -+ -+ /* easy the variable maintain beween stp tx, rx thread. */ -+ /* so we create variable for tx, rx respectively. */ -+ -+ static int tx_cnt; -+ static int rx_cnt; -+ static int is_tx_first = 1; -+ static int is_rx_first = 1; -+ static unsigned long tx_end_time; -+ static unsigned long rx_end_time; -+ -+ /* */ -+ /* BT A2DP TX CNT = 220, RX CNT = 843 */ -+ /* BT FTP Transferring TX CNT = 574, RX CNT = 2233 (1228~1588) */ -+ /* BT FTP Receiving TX CNT = 204, RX CNT = 3301 (2072~2515) */ -+ /* BT OPP Tx TX_CNT= 330, RX CNT = 1300~1800 */ -+ /* BT OPP Rx TX_CNT= (109~157), RX CNT = 1681~2436 */ -+ if (dir == 0) { /* tx */ -+ -+ tx_cnt++; -+ -+ if (((long)jiffies - (long)tx_end_time >= 0) || (is_tx_first)) { -+ tx_end_time = jiffies + (3 * HZ); -+ STP_PSM_INFO_FUNC("tx cnt = %d in the previous 3 sec\n", tx_cnt); -+ /* if(tx_cnt > 400)//for high traffic , not to do sleep. */ -+ if (tx_cnt > 300) { -+ osal_set_bit(STP_PSM_WMT_EVENT_DISABLE_MONITOR_TX_HIGH_DENSITY, &stp_psm->flag); -+ _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); -+ stp_psm_start_monitor(stp_psm); -+ } else { -+ osal_clear_bit(STP_PSM_WMT_EVENT_DISABLE_MONITOR_TX_HIGH_DENSITY, &stp_psm->flag); -+ _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); -+ } -+ tx_cnt = 0; -+ if (is_tx_first) -+ is_tx_first = 0; -+ } -+ } else { -+ rx_cnt++; -+ -+ if (((long)jiffies - (long)rx_end_time >= 0) || (is_rx_first)) { -+ rx_end_time = jiffies + (3 * HZ); -+ STP_PSM_INFO_FUNC("rx cnt = %d in the previous 3 sec\n", rx_cnt); -+ -+ /* if(rx_cnt > 2000)//for high traffic , not to do sleep. */ -+ if (rx_cnt > 1200) { /* for high traffic , not to do sleep. */ -+ osal_set_bit(STP_PSM_WMT_EVENT_DISABLE_MONITOR_RX_HIGH_DENSITY, &stp_psm->flag); -+ _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); -+ stp_psm_start_monitor(stp_psm); -+ } else { -+ osal_clear_bit(STP_PSM_WMT_EVENT_DISABLE_MONITOR_RX_HIGH_DENSITY, &stp_psm->flag); -+ _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); -+ } -+ rx_cnt = 0; -+ if (is_rx_first) -+ is_rx_first = 0; -+ } -+ } -+ -+ return 0; -+} -+ -+#else -+static struct timeval tv_now, tv_end; -+static INT32 sample_start; -+static INT32 tx_sum_len; -+static INT32 rx_sum_len; -+ -+INT32 stp_psm_disable_by_tx_rx_density(MTKSTP_PSM_T *stp_psm, INT32 dir, INT32 length) -+{ -+ if (sample_start) { -+ if (dir) -+ rx_sum_len += length; -+ else -+ tx_sum_len += length; -+ -+ do_gettimeofday(&tv_now); -+ /* STP_PSM_INFO_FUNC("tv_now:%d.%d tv_end:%d.%d\n", -+ * tv_now.tv_sec,tv_now.tv_usec,tv_end.tv_sec,tv_end.tv_usec); -+ */ -+ if (((tv_now.tv_sec == tv_end.tv_sec) && (tv_now.tv_usec > tv_end.tv_usec)) || -+ (tv_now.tv_sec > tv_end.tv_sec)) { -+ STP_PSM_INFO_FUNC("STP speed rx:%d tx:%d\n", rx_sum_len, tx_sum_len); -+ if ((rx_sum_len + tx_sum_len) > RTX_SPEED_THRESHOLD) { -+ /* STP_PSM_INFO_FUNC("High speed,Disable monitor\n"); */ -+ osal_set_bit(STP_PSM_WMT_EVENT_DISABLE_MONITOR_TX_HIGH_DENSITY, &stp_psm->flag); -+ stp_psm->idle_time_to_sleep = STP_PSM_IDLE_TIME_SLEEP_1000; -+ stp_psm_start_monitor(stp_psm); -+ } else { -+ /* STP_PSM_INFO_FUNC("Low speed,Enable monitor\n"); */ -+ stp_psm->idle_time_to_sleep = STP_PSM_IDLE_TIME_SLEEP; -+ osal_clear_bit(STP_PSM_WMT_EVENT_DISABLE_MONITOR_TX_HIGH_DENSITY, &stp_psm->flag); -+ } -+ sample_start = 0; -+ rx_sum_len = 0; -+ tx_sum_len = 0; -+ } -+ } else { -+ sample_start = 1; -+ do_gettimeofday(&tv_now); -+ tv_end = tv_now; -+ tv_end.tv_sec += SAMPLE_DURATION; -+ } -+ -+ return 0; -+} -+#endif -+ -+/*external function for WMT module to do sleep/wakeup*/ -+INT32 stp_psm_set_state(MTKSTP_PSM_T *stp_psm, MTKSTP_PSM_STATE_T state) -+{ -+ return _stp_psm_set_state(stp_psm, state); -+} -+ -+INT32 stp_psm_thread_lock_aquire(MTKSTP_PSM_T *stp_psm) -+{ -+ return _stp_psm_thread_lock_aquire(stp_psm); -+} -+ -+INT32 stp_psm_thread_lock_release(MTKSTP_PSM_T *stp_psm) -+{ -+ return _stp_psm_thread_lock_release(stp_psm); -+} -+ -+INT32 stp_psm_do_wakeup(MTKSTP_PSM_T *stp_psm) -+{ -+ return _stp_psm_do_wakeup(stp_psm); -+} -+ -+INT32 stp_psm_notify_stp(MTKSTP_PSM_T *stp_psm, const MTKSTP_PSM_ACTION_T action) -+{ -+ -+ return _stp_psm_notify_stp(stp_psm, action); -+} -+ -+INT32 stp_psm_notify_wmt_wakeup(MTKSTP_PSM_T *stp_psm) -+{ -+ return _stp_psm_notify_wmt_wakeup_wq(stp_psm); -+} -+ -+int stp_psm_notify_wmt_sleep(MTKSTP_PSM_T *stp_psm) -+{ -+ -+ return _stp_psm_notify_wmt_sleep_wq(stp_psm); -+} -+ -+INT32 stp_psm_start_monitor(MTKSTP_PSM_T *stp_psm) -+{ -+ return _stp_psm_start_monitor(stp_psm); -+} -+ -+INT32 stp_psm_is_to_block_traffic(MTKSTP_PSM_T *stp_psm) -+{ -+ return _stp_psm_is_to_block_traffic(stp_psm); -+} -+ -+INT32 stp_psm_is_disable(MTKSTP_PSM_T *stp_psm) -+{ -+ return _stp_psm_is_disable(stp_psm); -+} -+ -+INT32 stp_psm_has_pending_data(MTKSTP_PSM_T *stp_psm) -+{ -+ return _stp_psm_has_pending_data(stp_psm); -+} -+ -+INT32 stp_psm_release_data(MTKSTP_PSM_T *stp_psm) -+{ -+ return _stp_psm_release_data(stp_psm); -+} -+ -+INT32 stp_psm_hold_data(MTKSTP_PSM_T *stp_psm, const UINT8 *buffer, const UINT32 len, const UINT8 type) -+{ -+ return _stp_psm_hold_data(stp_psm, buffer, len, type); -+} -+ -+INT32 stp_psm_disable(MTKSTP_PSM_T *stp_psm) -+{ -+ return _stp_psm_disable(stp_psm); -+} -+ -+INT32 stp_psm_enable(MTKSTP_PSM_T *stp_psm, INT32 idle_time_to_sleep) -+{ -+ return _stp_psm_enable(stp_psm, idle_time_to_sleep); -+} -+ -+INT32 stp_psm_reset(MTKSTP_PSM_T *stp_psm) -+{ -+ stp_psm_set_sleep_enable(stp_psm); -+ -+ return _stp_psm_reset(stp_psm); -+} -+ -+INT32 stp_psm_sleep_for_thermal(MTKSTP_PSM_T *stp_psm) -+{ -+ return _stp_psm_notify_wmt_sleep_wq(stp_psm); -+} -+ -+INT32 stp_psm_set_sleep_enable(MTKSTP_PSM_T *stp_psm) -+{ -+ INT32 ret = 0; -+ -+ if (stp_psm) { -+ stp_psm->sleep_en = 1; -+ STP_PSM_DBG_FUNC("\n"); -+ ret = 0; -+ } else { -+ STP_PSM_INFO_FUNC("Null pointer\n"); -+ ret = -1; -+ } -+ -+ return ret; -+} -+ -+INT32 stp_psm_set_sleep_disable(MTKSTP_PSM_T *stp_psm) -+{ -+ INT32 ret = 0; -+ -+ if (stp_psm) { -+ stp_psm->sleep_en = 0; -+ STP_PSM_DBG_FUNC("\n"); -+ ret = 0; -+ } else { -+ STP_PSM_INFO_FUNC("Null pointer\n"); -+ ret = -1; -+ } -+ -+ return ret; -+} -+ -+/* stp_psm_check_sleep_enable - to check if sleep cmd is enabled or not -+ * @ stp_psm - pointer of psm -+ * -+ * return 1 if sleep is enabled; else return 0 if disabled; else error code -+ */ -+INT32 stp_psm_check_sleep_enable(MTKSTP_PSM_T *stp_psm) -+{ -+ INT32 ret = 0; -+ -+ if (stp_psm) { -+ ret = stp_psm->sleep_en; -+ STP_PSM_DBG_FUNC("%s\n", ret ? "enabled" : "disabled"); -+ } else { -+ STP_PSM_INFO_FUNC("Null pointer\n"); -+ ret = -1; -+ } -+ -+ return ret; -+} -+ -+static INT32 _stp_psm_dbg_dmp_in(STP_PSM_RECORD_T *stp_psm_dbg, UINT32 flag, UINT32 line_num) -+{ -+ INT32 index = 0; -+ struct timeval now; -+ -+ if (stp_psm_dbg) { -+ osal_lock_unsleepable_lock(&stp_psm_dbg->lock); -+ do_gettimeofday(&now); -+ index = stp_psm_dbg->in - 1; -+ index = (index + STP_PSM_DBG_SIZE) % STP_PSM_DBG_SIZE; -+ STP_PSM_DBG_FUNC("index(%d)\n", index); -+ stp_psm_dbg->queue[stp_psm_dbg->in].prev_flag = stp_psm_dbg->queue[index].cur_flag; -+ stp_psm_dbg->queue[stp_psm_dbg->in].cur_flag = flag; -+ stp_psm_dbg->queue[stp_psm_dbg->in].line_num = line_num; -+ stp_psm_dbg->queue[stp_psm_dbg->in].package_no = g_record_num++; -+ stp_psm_dbg->queue[stp_psm_dbg->in].sec = now.tv_sec; -+ stp_psm_dbg->queue[stp_psm_dbg->in].usec = now.tv_usec; -+ stp_psm_dbg->size++; -+ STP_PSM_DBG_FUNC("pre_Flag = %d, cur_flag = %d\n", stp_psm_dbg->queue[stp_psm_dbg->in].prev_flag, -+ stp_psm_dbg->queue[stp_psm_dbg->in].cur_flag); -+ stp_psm_dbg->size = (stp_psm_dbg->size > STP_PSM_DBG_SIZE) ? STP_PSM_DBG_SIZE : stp_psm_dbg->size; -+ stp_psm_dbg->in = (stp_psm_dbg->in >= (STP_PSM_DBG_SIZE - 1)) ? (0) : (stp_psm_dbg->in + 1); -+ STP_PSM_DBG_FUNC("record size = %d, in = %d num = %d\n", stp_psm_dbg->size, stp_psm_dbg->in, line_num); -+ -+ osal_unlock_unsleepable_lock(&stp_psm_dbg->lock); -+ } -+ return 0; -+} -+ -+static INT32 _stp_psm_dbg_out_printk(STP_PSM_RECORD_T *stp_psm_dbg) -+{ -+ -+ UINT32 dumpSize = 0; -+ UINT32 inIndex = 0; -+ UINT32 outIndex = 0; -+ -+ if (!stp_psm_dbg) { -+ STP_PSM_ERR_FUNC("NULL g_stp_psm_dbg reference\n"); -+ return -1; -+ } -+ osal_lock_unsleepable_lock(&stp_psm_dbg->lock); -+ -+ inIndex = stp_psm_dbg->in; -+ dumpSize = stp_psm_dbg->size; -+ if (STP_PSM_DBG_SIZE == dumpSize) -+ outIndex = inIndex; -+ else -+ outIndex = ((inIndex + STP_PSM_DBG_SIZE) - dumpSize) % STP_PSM_DBG_SIZE; -+ -+ STP_PSM_INFO_FUNC("loged record size = %d, in(%d), out(%d)\n", dumpSize, inIndex, outIndex); -+ while (dumpSize > 0) { -+ -+ pr_debug("STP-PSM:%d.%ds, n(%d)pre_flag(%d)cur_flag(%d)line_no(%d)\n", -+ stp_psm_dbg->queue[outIndex].sec, -+ stp_psm_dbg->queue[outIndex].usec, -+ stp_psm_dbg->queue[outIndex].package_no, -+ stp_psm_dbg->queue[outIndex].prev_flag, -+ stp_psm_dbg->queue[outIndex].cur_flag, stp_psm_dbg->queue[outIndex].line_num); -+ -+ outIndex = (outIndex >= (STP_PSM_DBG_SIZE - 1)) ? (0) : (outIndex + 1); -+ dumpSize--; -+ -+ } -+ -+ osal_unlock_unsleepable_lock(&stp_psm_dbg->lock); -+ -+ return 0; -+} -+ -+static INT32 _stp_psm_opid_dbg_dmp_in(P_STP_PSM_OPID_RECORD p_opid_dbg, UINT32 opid, UINT32 line_num) -+{ -+ INT32 index = 0; -+ struct timeval now; -+ -+ if (p_opid_dbg) { -+ osal_lock_unsleepable_lock(&p_opid_dbg->lock); -+ do_gettimeofday(&now); -+ index = p_opid_dbg->in - 1; -+ index = (index + STP_PSM_DBG_SIZE) % STP_PSM_DBG_SIZE; -+ STP_PSM_DBG_FUNC("index(%d)\n", index); -+ p_opid_dbg->queue[p_opid_dbg->in].prev_flag = p_opid_dbg->queue[index].cur_flag; -+ p_opid_dbg->queue[p_opid_dbg->in].cur_flag = opid; -+ p_opid_dbg->queue[p_opid_dbg->in].line_num = line_num; -+ p_opid_dbg->queue[p_opid_dbg->in].package_no = g_opid_record_num++; -+ p_opid_dbg->queue[p_opid_dbg->in].sec = now.tv_sec; -+ p_opid_dbg->queue[p_opid_dbg->in].usec = now.tv_usec; -+ p_opid_dbg->queue[p_opid_dbg->in].pid = current->pid; -+ p_opid_dbg->size++; -+ STP_PSM_DBG_FUNC("pre_opid = %d, cur_opid = %d\n", p_opid_dbg->queue[p_opid_dbg->in].prev_flag, -+ p_opid_dbg->queue[p_opid_dbg->in].cur_flag); -+ p_opid_dbg->size = (p_opid_dbg->size > STP_PSM_DBG_SIZE) ? STP_PSM_DBG_SIZE : p_opid_dbg->size; -+ p_opid_dbg->in = (p_opid_dbg->in >= (STP_PSM_DBG_SIZE - 1)) ? (0) : (p_opid_dbg->in + 1); -+ STP_PSM_DBG_FUNC("opid record size = %d, in = %d num = %d\n", p_opid_dbg->size, p_opid_dbg->in, -+ line_num); -+ -+ osal_unlock_unsleepable_lock(&p_opid_dbg->lock); -+ } -+ return 0; -+ -+} -+ -+static INT32 _stp_psm_opid_dbg_out_printk(P_STP_PSM_OPID_RECORD p_opid_dbg) -+{ -+ UINT32 dumpSize = 0; -+ UINT32 inIndex = 0; -+ UINT32 outIndex = 0; -+ -+ if (!p_opid_dbg) { -+ STP_PSM_ERR_FUNC("NULL p_opid_dbg reference\n"); -+ return -1; -+ } -+ osal_lock_unsleepable_lock(&p_opid_dbg->lock); -+ -+ inIndex = p_opid_dbg->in; -+ dumpSize = p_opid_dbg->size; -+ if (STP_PSM_DBG_SIZE == dumpSize) -+ outIndex = inIndex; -+ else -+ outIndex = ((inIndex + STP_PSM_DBG_SIZE) - dumpSize) % STP_PSM_DBG_SIZE; -+ -+ STP_PSM_INFO_FUNC("loged record size = %d, in(%d), out(%d)\n", dumpSize, inIndex, outIndex); -+ while (dumpSize > 0) { -+ -+ pr_debug("STP-PSM:%d.%ds, n(%d)pre_flag(%d)cur_flag(%d)line_no(%d) pid(%d)\n", -+ p_opid_dbg->queue[outIndex].sec, -+ p_opid_dbg->queue[outIndex].usec, -+ p_opid_dbg->queue[outIndex].package_no, -+ p_opid_dbg->queue[outIndex].prev_flag, -+ p_opid_dbg->queue[outIndex].cur_flag, -+ p_opid_dbg->queue[outIndex].line_num, p_opid_dbg->queue[outIndex].pid); -+ -+ outIndex = (outIndex >= (STP_PSM_DBG_SIZE - 1)) ? (0) : (outIndex + 1); -+ dumpSize--; -+ -+ } -+ -+ osal_unlock_unsleepable_lock(&p_opid_dbg->lock); -+ -+ return 0; -+ -+} -+ -+MTKSTP_PSM_T *stp_psm_init(void) -+{ -+ INT32 err = 0; -+ INT32 i = 0; -+ INT32 ret = -1; -+ -+ STP_PSM_INFO_FUNC("psm init\n"); -+ -+ stp_psm->work_state = ACT; -+ stp_psm->wmt_notify = wmt_lib_ps_stp_cb; -+ stp_psm->is_wmt_quick_ps_support = wmt_lib_is_quick_ps_support; -+ stp_psm->idle_time_to_sleep = STP_PSM_IDLE_TIME_SLEEP; -+ stp_psm->flag.data = 0; -+ stp_psm->stp_tx_cb = NULL; -+ stp_psm_set_sleep_enable(stp_psm); -+ -+ ret = osal_fifo_init(&stp_psm->hold_fifo, NULL, STP_PSM_FIFO_SIZE); -+ if (ret < 0) { -+ STP_PSM_ERR_FUNC("FIFO INIT FAILS\n"); -+ goto ERR_EXIT4; -+ } -+ -+ osal_fifo_reset(&stp_psm->hold_fifo); -+ osal_sleepable_lock_init(&stp_psm->hold_fifo_spinlock_global); -+ osal_unsleepable_lock_init(&stp_psm->wq_spinlock); -+ osal_sleepable_lock_init(&stp_psm->stp_psm_lock); -+ -+/* osal_unsleepable_lock_init(&stp_psm->flagSpinlock); */ -+ -+ osal_memcpy(stp_psm->wake_lock.name, "MT662x", 6); -+ osal_wake_lock_init(&stp_psm->wake_lock); -+ -+ osal_event_init(&stp_psm->STPd_event); -+ RB_INIT(&stp_psm->rFreeOpQ, STP_OP_BUF_SIZE); -+ RB_INIT(&stp_psm->rActiveOpQ, STP_OP_BUF_SIZE); -+ /* Put all to free Q */ -+ for (i = 0; i < STP_OP_BUF_SIZE; i++) { -+ osal_signal_init(&(stp_psm->arQue[i].signal)); -+ _stp_psm_put_op(stp_psm, &stp_psm->rFreeOpQ, &(stp_psm->arQue[i])); -+ } -+ /* stp_psm->current_active_op = NULL; */ -+ stp_psm->last_active_opId = STP_OPID_PSM_INALID; -+ /*Generate BTM thread, to servie STP-CORE and WMT-CORE for sleeping, waking up and host awake */ -+ stp_psm->PSMd.pThreadData = (VOID *) stp_psm; -+ stp_psm->PSMd.pThreadFunc = (VOID *) _stp_psm_proc; -+ osal_memcpy(stp_psm->PSMd.threadName, PSM_THREAD_NAME, osal_strlen(PSM_THREAD_NAME)); -+ -+ ret = osal_thread_create(&stp_psm->PSMd); -+ if (ret < 0) { -+ STP_PSM_ERR_FUNC("osal_thread_create fail...\n"); -+ goto ERR_EXIT5; -+ } -+ /* init_waitqueue_head(&stp_psm->wait_wmt_q); */ -+ stp_psm->wait_wmt_q.timeoutValue = STP_PSM_WAIT_EVENT_TIMEOUT; -+ osal_event_init(&stp_psm->wait_wmt_q); -+ -+ err = _stp_psm_init_monitor(stp_psm); -+ if (err) { -+ STP_PSM_ERR_FUNC("__stp_psm_init ERROR\n"); -+ goto ERR_EXIT6; -+ } -+ /* Start STPd thread */ -+ ret = osal_thread_run(&stp_psm->PSMd); -+ if (ret < 0) { -+ STP_PSM_ERR_FUNC("osal_thread_run FAILS\n"); -+ goto ERR_EXIT6; -+ } -+ /* psm disable in default */ -+ _stp_psm_disable(stp_psm); -+ -+ g_stp_psm_dbg = (STP_PSM_RECORD_T *) osal_malloc(osal_sizeof(STP_PSM_RECORD_T)); -+ if (!g_stp_psm_dbg) { -+ STP_PSM_ERR_FUNC("stp psm dbg allocate memory fail!\n"); -+ return NULL; -+ } -+ osal_memset(g_stp_psm_dbg, 0, osal_sizeof(STP_PSM_RECORD_T)); -+ osal_unsleepable_lock_init(&g_stp_psm_dbg->lock); -+ -+ g_stp_psm_opid_dbg = (STP_PSM_OPID_RECORD *) osal_malloc(osal_sizeof(STP_PSM_OPID_RECORD)); -+ if (!g_stp_psm_opid_dbg) { -+ STP_PSM_ERR_FUNC("stp psm dbg allocate memory fail!\n"); -+ return NULL; -+ } -+ osal_memset(g_stp_psm_opid_dbg, 0, osal_sizeof(STP_PSM_OPID_RECORD)); -+ osal_unsleepable_lock_init(&g_stp_psm_opid_dbg->lock); -+ -+ return stp_psm; -+ -+ERR_EXIT6: -+ -+ ret = osal_thread_destroy(&stp_psm->PSMd); -+ if (ret < 0) { -+ STP_PSM_ERR_FUNC("osal_thread_destroy FAILS\n"); -+ goto ERR_EXIT5; -+ } -+ERR_EXIT5: -+ osal_fifo_deinit(&stp_psm->hold_fifo); -+ERR_EXIT4: -+ -+ return NULL; -+} -+ -+INT32 stp_psm_deinit(MTKSTP_PSM_T *stp_psm) -+{ -+ INT32 ret = -1; -+ -+ STP_PSM_INFO_FUNC("psm deinit\n"); -+ -+ if (g_stp_psm_dbg) { -+ osal_unsleepable_lock_deinit(&g_stp_psm_dbg->lock); -+ osal_free(g_stp_psm_dbg); -+ g_stp_psm_dbg = NULL; -+ } -+ -+ if (!stp_psm) -+ return STP_PSM_OPERATION_FAIL; -+ -+ ret = osal_thread_destroy(&stp_psm->PSMd); -+ if (ret < 0) -+ STP_PSM_ERR_FUNC("osal_thread_destroy FAILS\n"); -+ -+ ret = _stp_psm_deinit_monitor(stp_psm); -+ if (ret < 0) -+ STP_PSM_ERR_FUNC("_stp_psm_deinit_monitor ERROR\n"); -+ -+ osal_wake_lock_deinit(&stp_psm->wake_lock); -+ osal_fifo_deinit(&stp_psm->hold_fifo); -+ osal_sleepable_lock_deinit(&stp_psm->hold_fifo_spinlock_global); -+ osal_unsleepable_lock_deinit(&stp_psm->wq_spinlock); -+ osal_sleepable_lock_deinit(&stp_psm->stp_psm_lock); -+/* osal_unsleepable_lock_deinit(&stp_psm->flagSpinlock); */ -+ -+ return STP_PSM_OPERATION_SUCCESS; -+} -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/core/stp_core.c b/drivers/misc/mediatek/connectivity/common/conn_soc/core/stp_core.c -new file mode 100644 -index 000000000000..046af2a58e69 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/core/stp_core.c -@@ -0,0 +1,3358 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -+ -+#include "osal_typedef.h" -+#include "stp_core.h" -+#include "psm_core.h" -+#include "btm_core.h" -+#include "stp_dbg.h" -+#include "stp_btif.h" -+ -+#define PFX "[STP] " -+#define STP_LOG_DBG 4 -+#define STP_LOG_PKHEAD 3 -+#define STP_LOG_INFO 2 -+#define STP_LOG_WARN 1 -+#define STP_LOG_ERR 0 -+ -+#define STP_DEL_SIZE 2 /* STP delimiter length */ -+ -+UINT32 gStpDbgLvl = STP_LOG_INFO; -+unsigned int g_coredump_mode = 0; -+#define REMOVE_USELESS_LOG 1 -+ -+#define STP_POLL_CPUPCR_NUM 16 -+#define STP_POLL_CPUPCR_DELAY 10 -+#define STP_RETRY_OPTIMIZE 0 -+ -+/* global variables */ -+static const UINT8 stp_delimiter[STP_DEL_SIZE] = { 0x55, 0x55 }; -+ -+static INT32 fgEnableNak; /* 0=enable NAK; 1=disable NAK */ -+static INT32 fgEnableDelimiter; /* 0=disable Delimiter; 1=enable Delimiter */ -+#if STP_RETRY_OPTIMIZE -+static UINT32 g_retry_times; -+#endif -+/* common interface */ -+static IF_TX sys_if_tx; -+/* event/signal */ -+static EVENT_SET sys_event_set; -+static EVENT_TX_RESUME sys_event_tx_resume; -+static FUNCTION_STATUS sys_check_function_status; -+/* kernel lib */ -+/* int g_block_tx = 0; */ -+static mtkstp_context_struct stp_core_ctx = { 0 }; -+ -+#define STP_PSM_CORE(x) ((x).psm) -+#define STP_SET_PSM_CORE(x, v) ((x).psm = (v)) -+ -+#define STP_BTM_CORE(x) ((x).btm) -+#define STP_SET_BTM_CORE(x, v) ((x).btm = (v)) -+ -+#define STP_IS_ENABLE(x) ((x).f_enable != 0) -+#define STP_NOT_ENABLE(x) ((x).f_enable == 0) -+#define STP_SET_ENABLE(x, v) ((x).f_enable = (v)) -+ -+#define STP_IS_READY(x) ((x).f_ready != 0) -+#define STP_NOT_READY(x) ((x).f_ready == 0) -+#define STP_SET_READY(x, v) ((x).f_ready = (v)) -+ -+#define STP_PENDING_TYPE(x) ((x).f_pending_type) -+#define STP_SET_PENDING_TYPE(x, v) ((x).f_pending_type = (v)) -+ -+#define STP_BLUE_ANGEL (0) -+#define STP_BLUE_Z (1) -+#define STP_BT_STK(x) ((x).f_bluez) -+#define STP_BT_STK_IS_BLUEZ(x) ((x).f_bluez == (STP_BLUE_Z)) -+#define STP_SET_BT_STK(x, v) ((x).f_bluez = (v)) -+ -+#define STP_IS_ENABLE_DBG(x) ((x).f_dbg_en != 0) -+#define STP_NOT_ENABLE_DBG(x) ((x).f_dbg_en == 0) -+#define STP_SET_ENABLE_DBG(x, v) ((x).f_dbg_en = (v)) -+ -+#define STP_IS_ENABLE_RST(x) ((x).f_autorst_en != 0) -+#define STP_NOT_ENABLE_RST(x) ((x).f_autorst_en == 0) -+#define STP_SET_ENABLE_RST(x, v) ((x).f_autorst_en = (v)) -+ -+#define STP_SUPPORT_PROTOCOL(x) ((x).f_mode) -+#define STP_SET_SUPPORT_PROTOCOL(x, v) ((x).f_mode = (v)) -+ -+#define STP_FW_COREDUMP_FLAG(x) ((x).f_coredump) -+#define STP_SET_FW_COREDUMP_FLAG(x, v) ((x).f_coredump = (v)) -+#define STP_ENABLE_FW_COREDUMP(x, v) ((x).en_coredump = (v)) -+#define STP_ENABLE_FW_COREDUMP_FLAG(x) ((x).en_coredump) -+ -+#define STP_WMT_LAST_CLOSE(x) ((x).f_wmt_last_close) -+#define STP_SET_WMT_LAST_CLOSE(x, v) ((x).f_wmt_last_close = (v)) -+ -+#define STP_EVT_ERR_ASSERT(x) ((x).f_evt_err_assert) -+#define STP_SET_EVT_ERR_ASSERT(x, v) ((x).f_evt_err_assert = (v)) -+ -+/*[PatchNeed]Need to calculate the timeout value*/ -+static UINT32 mtkstp_tx_timeout = MTKSTP_TX_TIMEOUT; -+static mtkstp_parser_state prev_state = -1; -+ -+#define CONFIG_DEBUG_STP_TRAFFIC_SUPPORT -+#ifdef CONFIG_DEBUG_STP_TRAFFIC_SUPPORT -+static MTKSTP_DBG_T *g_mtkstp_dbg; -+#endif -+static VOID stp_dbg_pkt_log(INT32 type, INT32 txAck, INT32 seq, INT32 crc, INT32 dir, const UINT8 *pBuf, INT32 len); -+static MTK_WCN_BOOL stp_check_crc(UINT8 *buffer, UINT32 length, UINT16 crc); -+static VOID stp_update_tx_queue(UINT32 txseq); -+static VOID stp_rest_ctx_state(VOID); -+static VOID stp_change_rx_state(mtkstp_parser_state next); -+static void stp_tx_timeout_handler(unsigned long data); -+static VOID stp_dump_data(const UINT8 *buf, const UINT8 *title, const UINT32 len); -+static VOID stp_dump_tx_queue(UINT32 txseq); -+static INT32 stp_is_apply_powersaving(VOID); -+/*static INT32 stp_is_privileges_cmd(const UINT8 *buffer, const UINT32 length, const UINT8 type);*/ -+static MTK_WCN_BOOL stp_is_tx_res_available(UINT32 length); -+static VOID stp_add_to_tx_queue(const UINT8 *buffer, UINT32 length); -+static INT32 stp_add_to_rx_queue(UINT8 *buffer, UINT32 length, UINT8 type); -+static VOID stp_send_tx_queue(UINT32 txseq); -+static VOID stp_send_ack(UINT8 txAck, UINT8 nak); -+static INT32 stp_process_rxack(VOID); -+static VOID stp_process_packet(VOID); -+ -+/*private functions*/ -+ -+static INT32 stp_ctx_lock_init(mtkstp_context_struct *pctx) -+{ -+#if CFG_STP_CORE_CTX_SPIN_LOCK -+ return osal_unsleepable_lock_init(&((pctx)->stp_mutex)); -+#else -+ osal_sleepable_lock_init(&((pctx)->stp_mutex)); -+ return 0; -+#endif -+} -+ -+static INT32 stp_ctx_lock_deinit(mtkstp_context_struct *pctx) -+{ -+#if CFG_STP_CORE_CTX_SPIN_LOCK -+ return osal_unsleepable_lock_deinit(&((pctx)->stp_mutex)); -+#else -+ return osal_sleepable_lock_deinit(&((pctx)->stp_mutex)); -+#endif -+} -+ -+static INT32 stp_ctx_lock(mtkstp_context_struct *pctx) -+{ -+#if CFG_STP_CORE_CTX_SPIN_LOCK -+ return osal_lock_unsleepable_lock(&((pctx)->stp_mutex)); -+#else -+ return osal_lock_sleepable_lock(&((pctx)->stp_mutex)); -+#endif -+} -+ -+static INT32 stp_ctx_unlock(mtkstp_context_struct *pctx) -+{ -+#if CFG_STP_CORE_CTX_SPIN_LOCK -+ return osal_unlock_unsleepable_lock(&((pctx)->stp_mutex)); -+#else -+ return osal_unlock_sleepable_lock(&((pctx)->stp_mutex)); -+#endif -+} -+ -+MTK_WCN_BOOL mtk_wcn_stp_dbg_level(UINT32 dbglevel) -+{ -+ if (dbglevel <= 4) { -+ gStpDbgLvl = dbglevel; -+ STP_INFO_FUNC("gStpDbgLvl = %d\n", gStpDbgLvl); -+ return MTK_WCN_BOOL_TRUE; -+ } -+ STP_INFO_FUNC("invalid stp debug level. gStpDbgLvl = %d\n", gStpDbgLvl); -+ -+ return MTK_WCN_BOOL_FALSE; -+} -+ -+#if !(REMOVE_USELESS_LOG) -+static UINT8 *stp_type_to_dbg_string(UINT32 type) -+{ -+ UINT8 *type_name = NULL; -+ -+ if (type == BT_TASK_INDX) -+ type_name = "< BT>"; -+ else if (type == GPS_TASK_INDX) -+ type_name = ""; -+ else if (type == WMT_TASK_INDX) -+ type_name = ""; -+ else if (type == FM_TASK_INDX) -+ type_name = "< FM>"; -+ else if (type == ANT_TASK_INDX) -+ type_name = ""; -+ -+ return type_name; -+} -+#endif -+#if 0 -+/***************************************************************************** -+* FUNCTION -+* crc16 -+* DESCRIPTION -+* Compute the CRC-16 for the data buffer -+* PARAMETERS -+* crc [IN] previous CRC value -+* buffer [IN] data buffer -+* length [IN] data buffer length -+* RETURNS -+* the updated CRC value -+*****************************************************************************/ -+static UINT16 crc16(const UINT8 *buffer, const UINT32 length) -+{ -+ UINT32 crc, i; -+ -+ /* FIXME: Add STP checksum feature */ -+ crc = 0; -+ for (i = 0; i < length; i++, buffer++) -+ crc = (crc >> 8) ^ crc16_table[(crc ^ (*buffer)) & 0xff]; -+ -+ return crc; -+} -+ -+#endif -+ -+VOID stp_dbg_pkt_log(INT32 type, INT32 txAck, INT32 seq, INT32 crc, INT32 dir, const UINT8 *pBuf, INT32 len) -+{ -+ -+#ifndef CONFIG_LOG_STP_INTERNAL -+ return; -+#endif -+ -+ if (STP_IS_ENABLE_DBG(stp_core_ctx)) { -+ stp_dbg_log_pkt(g_mtkstp_dbg, STP_DBG_PKT, type, /* type */ -+ txAck, /* ack */ -+ seq, /* seq */ -+ crc, /* crc */ -+ dir, /* dir */ -+ len, /* len */ -+ pBuf); /* body */ -+ } else { -+ STP_DBG_FUNC("stp_dbg not enabled"); -+ } -+} -+ -+/***************************************************************************** -+* FUNCTION -+* stp_check_crc -+* DESCRIPTION -+* check the check sum of packet payload -+* PARAMETERS -+* pdata [IN] the data want to check -+* length [IN] the length of pdata -+* crc [IN] the crc of pdata -+* RETURNS -+* KAL_TRUE crc is ok -+* KAL_FALSE crc is wrong -+*****************************************************************************/ -+static MTK_WCN_BOOL stp_check_crc(UINT8 *buffer, UINT32 length, UINT16 crc) -+{ -+ /*----------------------------------------------------------------*/ -+ /* Local Variables */ -+ /*----------------------------------------------------------------*/ -+ UINT16 checksum; -+ -+ /*----------------------------------------------------------------*/ -+ /* Code Body */ -+ /*----------------------------------------------------------------*/ -+ -+ /* FIXME: Add STP feature: check or skip crc */ -+ -+ checksum = osal_crc16(buffer, length); -+ if (checksum == crc) -+ return MTK_WCN_BOOL_TRUE; -+ -+ STP_ERR_FUNC("CRC fail, length = %d, rx = %x, calc = %x \r\n", length, crc, checksum); -+ return MTK_WCN_BOOL_FALSE; -+ -+} -+ -+/***************************************************************************** -+* FUNCTION -+* stp_update_tx_queue -+* DESCRIPTION -+* update packet's ACK field -+* PARAMETERS -+* txseq [IN] index of the tx packet which we want to update -+* RETURNS -+* void -+*****************************************************************************/ -+static void stp_update_tx_queue(UINT32 txseq) -+{ -+ INT32 tx_read, i; -+ UINT8 checksum = 0; -+ -+ tx_read = stp_core_ctx.tx_start_addr[txseq]; -+ stp_core_ctx.tx_buf[tx_read] &= 0xf8; -+ stp_core_ctx.tx_buf[tx_read] |= stp_core_ctx.sequence.txack; -+ -+ for (i = 0; i < 3; i++) { -+ checksum += stp_core_ctx.tx_buf[tx_read]; -+ tx_read++; -+ if (tx_read >= MTKSTP_BUFFER_SIZE) -+ tx_read -= MTKSTP_BUFFER_SIZE; -+ -+ } -+ -+ stp_core_ctx.tx_buf[tx_read] = checksum; -+ -+} -+ -+/***************************************************************************** -+* FUNCTION -+* stp_rest_ctx_state -+* DESCRIPTION -+* Reset stp context state variables only. Mutex and timer resources are not touched. -+* -+* PARAMETERS -+* void -+* RETURNS -+* void -+*****************************************************************************/ -+static VOID stp_rest_ctx_state(VOID) -+{ -+ INT32 i; -+ -+ /* osal_lock_unsleepable_lock(&stp_core_ctx.stp_mutex); */ -+ stp_ctx_lock(&stp_core_ctx); -+ stp_core_ctx.rx_counter = 0; -+ -+ /*reset rx buffer pointer */ -+ for (i = 0; i < MTKSTP_MAX_TASK_NUM; i++) { -+ stp_core_ctx.ring[i].read_p = 0; -+ stp_core_ctx.ring[i].write_p = 0; -+ } -+ -+ /*reset tx buffer pointer */ -+ stp_core_ctx.tx_write = 0; -+ stp_core_ctx.tx_read = 0; -+ -+ /*reset STP protocol context */ -+ stp_core_ctx.parser.state = MTKSTP_SYNC; -+ stp_core_ctx.sequence.txseq = 0; -+ stp_core_ctx.sequence.txack = 7; -+ stp_core_ctx.sequence.rxack = 7; -+ stp_core_ctx.sequence.winspace = MTKSTP_WINSIZE; -+ stp_core_ctx.sequence.expected_rxseq = 0; -+ stp_core_ctx.sequence.retry_times = 0; -+ stp_core_ctx.inband_rst_set = 0; -+ -+ /* osal_unlock_unsleepable_lock(&stp_core_ctx.stp_mutex); */ -+ stp_ctx_unlock(&stp_core_ctx); -+} -+ -+/***************************************************************************** -+* FUNCTION -+* stp_change_rx_state -+* DESCRIPTION -+* change the rx fsm of STP to "next" -+* PARAMETERS -+* next [IN] the next state of rx fsm -+* RETURNS -+* void -+*****************************************************************************/ -+static VOID stp_change_rx_state(mtkstp_parser_state next) -+{ -+ prev_state = stp_core_ctx.parser.state; -+ stp_core_ctx.parser.state = next; -+ -+} -+ -+/* static void stp_tx_timeout_handler(void){ */ -+static void stp_tx_timeout_handler(unsigned long data) -+{ -+ STP_WARN_FUNC("call retry btm retry wq ...\n"); -+ /*shorten the softirq lattency */ -+ stp_btm_notify_stp_retry_wq(STP_BTM_CORE(stp_core_ctx)); -+ STP_WARN_FUNC("call retry btm retry wq ...#\n"); -+} -+ -+VOID stp_do_tx_timeout(VOID) -+{ -+ UINT32 seq; -+ UINT32 ret; -+ INT32 iRet; -+ ENUM_STP_FW_ISSUE_TYPE issue_type; -+ UINT8 resync[4]; -+ -+ STP_WARN_FUNC("==============================================================================\n"); -+ -+ /* osal_lock_unsleepable_lock(&stp_core_ctx.stp_mutex); */ -+ stp_ctx_lock(&stp_core_ctx); -+ -+#if STP_RETRY_OPTIMIZE -+ if ((g_retry_times != 0) && (stp_core_ctx.sequence.retry_times == 0)) { -+ STP_INFO_FUNC("STP TX timeout has been recoveryed by resend,record_retry_time(%d)\n", g_retry_times); -+ g_retry_times = 0; -+ stp_ctx_unlock(&stp_core_ctx); -+ return; -+ } -+#endif -+ if (stp_core_ctx.sequence.retry_times > (MTKSTP_RETRY_LIMIT)) { -+ STP_INFO_FUNC("STP retry times(%d) have reached retry limit,stop it\n", -+ stp_core_ctx.sequence.retry_times); -+ stp_ctx_unlock(&stp_core_ctx); -+ return; -+ } -+#if STP_RETRY_OPTIMIZE -+ else -+ STP_DBG_FUNC("current TX timeout package has not received ACK yet,retry_times(%d)\n", -+ g_retry_times); -+#endif -+ /*polling cpupcr when no ack occurs at first retry */ -+ stp_notify_btm_poll_cpupcr(STP_BTM_CORE(stp_core_ctx), STP_POLL_CPUPCR_NUM, STP_POLL_CPUPCR_DELAY); -+ -+ seq = stp_core_ctx.sequence.rxack; -+ INDEX_INC(seq); -+ -+ if (seq != stp_core_ctx.sequence.txseq) { -+ osal_memset(&resync[0], 127, 4); -+ (*sys_if_tx) (&resync[0], 4, &ret); -+ if (ret != 4) { -+ STP_ERR_FUNC("mtkstp_tx_timeout_handler: send resync fail\n"); -+ osal_assert(0); -+ } -+ -+ do { -+ STP_WARN_FUNC("[stp.ctx]*rxack (=last rx ack) = %d\n\r", stp_core_ctx.sequence.rxack); -+ STP_WARN_FUNC("[stp.ctx]txack (=last rx seq)= %d\n\r", stp_core_ctx.sequence.txack); -+ STP_WARN_FUNC("[stp.ctx]*txseq (=next tx seq)= %d\n\r", stp_core_ctx.sequence.txseq); -+ STP_WARN_FUNC("Resend STP packet from %d -> %d\n\r", seq, -+ (stp_core_ctx.sequence.txseq <= 0) ? (7) : (stp_core_ctx.sequence.txseq - 1)); -+ stp_dump_tx_queue(seq); -+ -+ stp_send_tx_queue(seq); -+ INDEX_INC(seq); -+ } while (seq != stp_core_ctx.sequence.txseq); -+ -+ } -+ -+ osal_timer_stop(&stp_core_ctx.tx_timer); -+ osal_timer_start(&stp_core_ctx.tx_timer, mtkstp_tx_timeout); -+ -+ if (stp_core_ctx.sequence.winspace == MTKSTP_WINSIZE) { -+ osal_timer_stop(&stp_core_ctx.tx_timer); -+ STP_ERR_FUNC("mtkstp_tx_timeout_handler: wmt_stop_timer\n"); -+ } else { -+ stp_core_ctx.sequence.retry_times++; -+ STP_ERR_FUNC("mtkstp_tx_timeout_handler, retry = %d\n", stp_core_ctx.sequence.retry_times); -+#if STP_RETRY_OPTIMIZE -+ g_retry_times = stp_core_ctx.sequence.retry_times; -+#endif -+ /*If retry too much, try to recover STP by return back to initializatin state */ -+ /*And not to retry again */ -+ if (stp_core_ctx.sequence.retry_times > MTKSTP_RETRY_LIMIT) { -+#if STP_RETRY_OPTIMIZE -+ g_retry_times = 0; -+#endif -+ osal_timer_stop(&stp_core_ctx.tx_timer); -+ stp_ctx_unlock(&stp_core_ctx); -+ -+ STP_ERR_FUNC("mtkstp_tx_timeout_handler: wmt_stop_timer\n"); -+ -+ STP_ERR_FUNC("TX retry limit = %d\n", MTKSTP_RETRY_LIMIT); -+ osal_assert(0); -+ mtk_wcn_stp_dbg_dump_package(); -+ -+ /*Whole Chip Reset Procedure Invoke */ -+ /*if(STP_NOT_ENABLE_DBG(stp_core_ctx)) */ -+ -+ if (0 == mtk_wcn_stp_get_wmt_evt_err_trg_assert()) { -+ stp_psm_disable(STP_PSM_CORE(stp_core_ctx)); -+ mtk_wcn_stp_set_wmt_evt_err_trg_assert(1); -+ stp_dbg_set_host_assert_info(4, 36, 1); -+ STP_INFO_FUNC("**STP NoAck trigger firmware assert**\n"); -+ iRet = stp_notify_btm_do_fw_assert_via_emi(STP_BTM_CORE(stp_core_ctx)); -+ -+ if (iRet) { -+ STP_ERR_FUNC("host tigger fw assert fail(%d), do noack handle flow\n", iRet); -+ mtk_wcn_stp_set_wmt_evt_err_trg_assert(0); -+ issue_type = STP_FW_NOACK_ISSUE; -+ iRet = stp_dbg_set_fw_info("STP NoAck", osal_strlen("STP NoAck"), issue_type); -+ -+ osal_dbg_assert_aee("[SOC_CONNSYS]NoAck", -+ "**[WCN_ISSUE_INFO]STP Tx Timeout**\n F/W has NO any RESPONSE. Please check F/W status first\n"); -+ if (STP_IS_ENABLE_RST(stp_core_ctx)) { -+ STP_SET_READY(stp_core_ctx, 0); -+ stp_btm_notify_wmt_rst_wq(STP_BTM_CORE(stp_core_ctx)); -+ } else { -+ STP_INFO_FUNC("No to launch whole chip reset! for debugging purpose\n"); -+ } -+ } -+ } else { -+ STP_INFO_FUNC("do trigger assert & chip reset in wmt\n"); -+ } -+ return; -+ } -+ } -+ -+ /* osal_unlock_unsleepable_lock(&stp_core_ctx.stp_mutex); */ -+ stp_ctx_unlock(&stp_core_ctx); -+ STP_WARN_FUNC("==============================================================================#\n"); -+} -+ -+static VOID stp_dump_data(const UINT8 *buf, const UINT8 *title, const UINT32 len) -+{ -+ osal_buffer_dump(buf, title, len, 32); -+} -+ -+/***************************************************************************** -+ * FUNCTION -+ * stp_tx_timeout_handler -+ * DESCRIPTION -+ * tx timeout handler, send resync & retransmitt -+ * PARAMETERS -+ * void -+ * RETURNS -+ * void -+ *****************************************************************************/ -+static VOID stp_dump_tx_queue(UINT32 txseq) -+{ -+ INT32 tx_read, tx_length, last_len; -+ -+ tx_read = stp_core_ctx.tx_start_addr[txseq]; -+ tx_length = stp_core_ctx.tx_length[txseq]; -+ -+ STP_ERR_FUNC("tx_seq=%d ..", txseq); -+ -+ if (tx_read + tx_length < MTKSTP_BUFFER_SIZE) { -+ stp_dump_data(&stp_core_ctx.tx_buf[tx_read], "tx_q", (tx_length >= 8) ? (8) : (tx_length)); -+ } else { -+ last_len = MTKSTP_BUFFER_SIZE - tx_read; -+ stp_dump_data(&stp_core_ctx.tx_buf[tx_read], "tx_q_0", (last_len >= 8) ? (8) : (last_len)); -+ stp_dump_data(&stp_core_ctx.tx_buf[0], "tx_q_0", -+ ((tx_length - last_len) ? (8) : (tx_length - last_len))); -+ } -+} -+ -+/***************************************************************************** -+* FUNCTION -+* stp_is_apply_powersaving -+* DESCRIPTION -+* Check if STP support power saving mode. -+* PARAMETERS -+* -+* RETURNS -+* True: support power saving False: not support power saving -+*****************************************************************************/ -+static INT32 stp_is_apply_powersaving(VOID) -+{ -+ -+ if (STP_IS_READY(stp_core_ctx) && !stp_psm_is_disable(STP_PSM_CORE(stp_core_ctx))) { -+ /* osal_dbg_print("apply power saving\n"); */ -+ return MTK_WCN_BOOL_TRUE; -+ } -+ if (mtk_wcn_stp_is_sdio_mode()) -+ return MTK_WCN_BOOL_FALSE; -+ -+ STP_DBG_FUNC("not apply power saving\n"); -+ return MTK_WCN_BOOL_FALSE; -+} -+#if 0 -+/***************************************************************************** -+* FUNCTION -+* stp_is_privileges_cmd -+* DESCRIPTION -+* Check if the data is privilege command -+* PARAMETERS -+* -+* RETURNS -+* True/False -+*****************************************************************************/ -+static INT32 stp_is_privileges_cmd(const UINT8 *buffer, const UINT32 length, const UINT8 type) -+{ -+ typedef struct privileges_cmd { -+ UINT32 length; -+ UINT8 type; -+ UINT8 buf[7]; /* MAX length of target command is only 5 currently */ -+ } p_cmd_t; -+ -+ p_cmd_t p_cmd_table[] = { -+ {0x05, WMT_TASK_INDX, {0x01, 0x03, 0x01, 0x00, 0x01} }, /* sleep command */ -+ {0x05, WMT_TASK_INDX, {0x01, 0x03, 0x01, 0x00, 0x02} }, /* host_awake command */ -+ }; -+ -+ UINT32 i; -+ UINT32 size = sizeof(p_cmd_table) / sizeof(p_cmd_table[0]); -+ -+ for (i = 0; i < size; i++) { -+ if (type != p_cmd_table[i].type) -+ continue; -+ -+ if (length != p_cmd_table[i].length) -+ continue; -+ -+ if (osal_memcmp(p_cmd_table[i].buf, buffer, length)) -+ continue; -+ -+ /* matched entry is found */ -+ STP_DBG_FUNC("It's p_cmd_t\n"); -+ return MTK_WCN_BOOL_TRUE; -+ } -+ -+ return MTK_WCN_BOOL_FALSE; -+} -+#endif -+/***************************************************************************** -+* FUNCTION -+* tx_queue_room_available -+* DESCRIPTION -+* check room if available, -+* PARAMETERS -+* buffer [IN] data buffer -+* length [IN] data buffer length -+* RETURNS -+* void -+*****************************************************************************/ -+static MTK_WCN_BOOL stp_is_tx_res_available(UINT32 length) -+{ -+ UINT32 roomLeft; -+ -+ /* -+ Get available space of TX Queue -+ */ -+ if (stp_core_ctx.tx_read <= stp_core_ctx.tx_write) -+ roomLeft = MTKSTP_BUFFER_SIZE - stp_core_ctx.tx_write + stp_core_ctx.tx_read - 1; -+ else -+ roomLeft = stp_core_ctx.tx_read - stp_core_ctx.tx_write - 1; -+ -+ if (roomLeft < length) { -+ STP_ERR_FUNC("%s: tx queue room shortage\n", __func__); -+ return MTK_WCN_BOOL_FALSE; -+ } else -+ return MTK_WCN_BOOL_TRUE; -+} -+ -+/***************************************************************************** -+* FUNCTION -+* stp_add_to_tx_queue -+* DESCRIPTION -+* put data to tx queue -+* PARAMETERS -+* buffer [IN] data buffer -+* length [IN] data buffer length -+* RETURNS -+* void -+*****************************************************************************/ -+static VOID stp_add_to_tx_queue(const UINT8 *buffer, UINT32 length) -+{ -+ UINT32 last_len; -+ -+ /* Get available space of TX Queue */ -+ if (length + stp_core_ctx.tx_write < MTKSTP_BUFFER_SIZE) { -+ osal_memcpy(stp_core_ctx.tx_buf + stp_core_ctx.tx_write, buffer, length); -+ stp_core_ctx.tx_write += length; -+ } else { -+ last_len = MTKSTP_BUFFER_SIZE - stp_core_ctx.tx_write; -+ osal_memcpy(stp_core_ctx.tx_buf + stp_core_ctx.tx_write, buffer, last_len); -+ osal_memcpy(stp_core_ctx.tx_buf, buffer + last_len, length - last_len); -+ -+ stp_core_ctx.tx_write = length - last_len; -+ } -+ -+} -+ -+/***************************************************************************** -+* FUNCTION -+* stp_add_to_rx_queue -+* DESCRIPTION -+* put data to corresponding task's rx queue and notify corresponding task -+* PARAMETERS -+* buffer [IN] data buffer -+* length [IN] data buffer length -+* type [IN] corresponding task index -+* RETURNS -+* INT32 0=success, others=error -+*****************************************************************************/ -+static INT32 stp_add_to_rx_queue(UINT8 *buffer, UINT32 length, UINT8 type) -+{ -+ UINT32 roomLeft, last_len; -+ -+ osal_lock_unsleepable_lock(&stp_core_ctx.ring[type].mtx); -+ -+ if (stp_core_ctx.ring[type].read_p <= stp_core_ctx.ring[type].write_p) -+ roomLeft = MTKSTP_BUFFER_SIZE - stp_core_ctx.ring[type].write_p + stp_core_ctx.ring[type].read_p - 1; -+ else -+ roomLeft = stp_core_ctx.ring[type].read_p - stp_core_ctx.ring[type].write_p - 1; -+ -+ if (roomLeft < length) { -+ osal_unlock_unsleepable_lock(&stp_core_ctx.ring[type].mtx); -+ STP_ERR_FUNC("Queue is full !!!, type = %d\n", type); -+ osal_assert(0); -+ return -1; -+ } -+ -+ if (length + stp_core_ctx.ring[type].write_p < MTKSTP_BUFFER_SIZE) { -+ osal_memcpy(stp_core_ctx.ring[type].buffer + stp_core_ctx.ring[type].write_p, buffer, length); -+ stp_core_ctx.ring[type].write_p += length; -+ } else { -+ last_len = MTKSTP_BUFFER_SIZE - stp_core_ctx.ring[type].write_p; -+ osal_memcpy(stp_core_ctx.ring[type].buffer + stp_core_ctx.ring[type].write_p, buffer, last_len); -+ osal_memcpy(stp_core_ctx.ring[type].buffer, buffer + last_len, length - last_len); -+ stp_core_ctx.ring[type].write_p = length - last_len; -+ } -+ -+ osal_unlock_unsleepable_lock(&stp_core_ctx.ring[type].mtx); -+ -+ return 0; -+} -+ -+/***************************************************************************** -+* FUNCTION -+* stp_send_tx_queue -+* DESCRIPTION -+* send data in tx buffer to common interface -+* PARAMETERS -+* txseq [IN] sequence number of outgoing packet in tx buffer -+* RETURNS -+* void -+*****************************************************************************/ -+static VOID stp_send_tx_queue(UINT32 txseq) -+{ -+ UINT32 ret; -+ INT32 tx_read, tx_length, last_len; -+ -+ tx_read = stp_core_ctx.tx_start_addr[txseq]; -+ tx_length = stp_core_ctx.tx_length[txseq]; -+ -+ stp_update_tx_queue(txseq); -+ -+ if (tx_read + tx_length < MTKSTP_BUFFER_SIZE) { -+ -+ (*sys_if_tx) (&stp_core_ctx.tx_buf[tx_read], tx_length, &ret); -+ -+ if (ret != tx_length) { -+ STP_ERR_FUNC("stp_send_tx_queue, %d/%d\n", tx_length, ret); -+ osal_assert(0); -+ } -+ } else { -+ last_len = MTKSTP_BUFFER_SIZE - tx_read; -+ (*sys_if_tx) (&stp_core_ctx.tx_buf[tx_read], last_len, &ret); -+ -+ if (ret != last_len) { -+ STP_ERR_FUNC("stp_send_tx_queue, %d/%d\n", last_len, ret); -+ osal_assert(0); -+ } -+ -+ (*sys_if_tx) (&stp_core_ctx.tx_buf[0], tx_length - last_len, &ret); -+ -+ if (ret != tx_length - last_len) { -+ STP_ERR_FUNC("stp_send_tx_queue, %d/%d\n", tx_length - last_len, ret); -+ osal_assert(0); -+ } -+ } -+ -+} -+ -+/***************************************************************************** -+* FUNCTION -+* stp_send_ack -+* DESCRIPTION -+* send ack packet to the peer -+* PARAMETERS -+* txAck [IN] Ack number -+* nak [IN] 0 = ack; !0 = NAK -+* RETURNS -+* void -+*****************************************************************************/ -+static VOID stp_send_ack(UINT8 txAck, UINT8 nak) -+{ -+ UINT8 mtkstp_header[MTKSTP_HEADER_SIZE]; -+ UINT32 ret; -+ INT32 iStatus; -+ -+ mtkstp_header[0] = 0x80 + (0 << 3) + txAck; /* stp_core_ctx.sequence.txack; */ -+ -+ if (fgEnableNak == 0) -+ mtkstp_header[1] = 0x00; /* disable NAK */ -+ else -+ mtkstp_header[1] = ((nak == 0) ? 0x00 : 0x80); -+ -+ mtkstp_header[2] = 0; -+ mtkstp_header[3] = (mtkstp_header[0] + mtkstp_header[1] + mtkstp_header[2]) & 0xff; -+ -+ stp_dbg_pkt_log(STP_TASK_INDX, txAck, 0, 0, PKT_DIR_TX, NULL, 0); -+ -+ if (fgEnableDelimiter == 1) { -+ iStatus = (*sys_if_tx) ((PUINT8) &stp_delimiter[0], STP_DEL_SIZE, &ret); -+ STP_DUMP_PACKET_HEAD((PUINT8) &stp_delimiter[0], "tx del", STP_DEL_SIZE); -+ if (ret != STP_DEL_SIZE) { -+ STP_ERR_FUNC("stp_send_ack, %d/%d status %d\n", STP_DEL_SIZE, ret, iStatus); -+ osal_assert(0); -+ } -+ } -+ -+ iStatus = (*sys_if_tx) (&mtkstp_header[0], MTKSTP_HEADER_SIZE, &ret); -+ -+ if (ret != MTKSTP_HEADER_SIZE) { -+ STP_ERR_FUNC("stp_send_ack, %d/%d status %d\n", MTKSTP_HEADER_SIZE, ret, iStatus); -+ osal_assert(0); -+ } -+ -+} -+ -+INT32 stp_send_data_no_ps(UINT8 *buffer, UINT32 length, UINT8 type) -+{ -+ UINT8 mtkstp_header[MTKSTP_HEADER_SIZE], temp[2]; -+ UINT8 *p_tx_buf = NULL; -+ UINT16 crc; -+ INT32 ret = 0; -+ -+ /* osal_lock_unsleepable_lock(&stp_core_ctx.stp_mutex); */ -+ stp_ctx_lock(&stp_core_ctx); -+ -+ /*Only WMT can set raw data */ -+ if (STP_NOT_ENABLE(stp_core_ctx) && WMT_TASK_INDX != type) { -+ /* no op */ -+ /* NULL; */ -+ } else if (STP_NOT_ENABLE(stp_core_ctx) && WMT_TASK_INDX == type) { -+ /* ret = mtk_wcn_stp_send_data_raw(buffer, length, type); */ -+ /* NULL; */ -+ } -+ /* STP over SDIO */ -+ else if ((mtk_wcn_stp_is_sdio_mode() || mtk_wcn_stp_is_btif_mand_mode()) && STP_IS_ENABLE(stp_core_ctx)) { -+ osal_printtimeofday("[ STP][SDIO][ B][W]"); -+ -+ mtkstp_header[0] = 0x80; -+ mtkstp_header[1] = (type << 4) + (((length) >> 8) & 0x0f); -+ mtkstp_header[2] = (length) & 0xff; -+ mtkstp_header[3] = 0x00; -+ -+ p_tx_buf = &stp_core_ctx.tx_buf[0]; -+ osal_memcpy(p_tx_buf, mtkstp_header, MTKSTP_HEADER_SIZE); -+ p_tx_buf += MTKSTP_HEADER_SIZE; -+ -+ osal_memcpy(p_tx_buf, buffer, length); -+ p_tx_buf += length; -+ -+ temp[0] = 0x00; -+ temp[1] = 0x00; -+ osal_memcpy(p_tx_buf, temp, 2); -+ stp_dbg_pkt_log(type, -+ stp_core_ctx.sequence.txack, -+ stp_core_ctx.sequence.txseq, 0, PKT_DIR_TX, buffer, length); -+ (*sys_if_tx) (&stp_core_ctx.tx_buf[0], (MTKSTP_HEADER_SIZE + length + 2), &ret); -+ if ((MTKSTP_HEADER_SIZE + length + 2) != ret) { -+ STP_ERR_FUNC("stp send tx packet: %d, maybe stp_if_tx == NULL\n", ret); -+ osal_assert(0); -+ ret = 0; -+ } else { -+ ret = (INT32) length; -+ } -+ -+ osal_printtimeofday("[ STP][SDIO][ E][W]"); -+ } -+ /* STP over BTIF OR UART */ -+ else if ((mtk_wcn_stp_is_btif_fullset_mode()) && STP_IS_ENABLE(stp_core_ctx)) { -+ -+ if ((stp_core_ctx.sequence.winspace > 0) && -+ (stp_is_tx_res_available(MTKSTP_HEADER_SIZE + length + MTKSTP_CRC_SIZE))) { -+ mtkstp_header[0] = 0x80 + (stp_core_ctx.sequence.txseq << 3) + stp_core_ctx.sequence.txack; -+ mtkstp_header[1] = (type << 4) + ((length & 0xf00) >> 8); -+ mtkstp_header[2] = length & 0xff; -+ mtkstp_header[3] = (mtkstp_header[0] + mtkstp_header[1] + mtkstp_header[2]) & 0xff; -+ -+ stp_core_ctx.tx_start_addr[stp_core_ctx.sequence.txseq] = stp_core_ctx.tx_write; -+ stp_core_ctx.tx_length[stp_core_ctx.sequence.txseq] = MTKSTP_HEADER_SIZE + length + 2; -+ -+ if (fgEnableDelimiter == 1) { -+ stp_core_ctx.tx_length[stp_core_ctx.sequence.txseq] += STP_DEL_SIZE; -+ stp_add_to_tx_queue(&stp_delimiter[0], STP_DEL_SIZE); -+ } -+ -+ stp_add_to_tx_queue(mtkstp_header, MTKSTP_HEADER_SIZE); -+ -+ /*Make Payload */ -+ stp_add_to_tx_queue(buffer, length); -+ -+ /*Make CRC */ -+ crc = osal_crc16(buffer, length); -+ temp[0] = crc & 0xff; -+ temp[1] = (crc & 0xff00) >> 8; -+ stp_add_to_tx_queue(temp, 2); -+ -+ stp_dbg_pkt_log(type, -+ stp_core_ctx.sequence.txack, -+ stp_core_ctx.sequence.txseq, crc, PKT_DIR_TX, buffer, length); -+ -+ /*Kick to UART */ -+ stp_send_tx_queue(stp_core_ctx.sequence.txseq); -+ INDEX_INC(stp_core_ctx.sequence.txseq); -+ stp_core_ctx.sequence.winspace--; -+ -+ /*Setup the Retry Timer */ -+ osal_timer_stop(&stp_core_ctx.tx_timer); -+ if (stp_core_ctx.sequence.winspace != MTKSTP_WINSIZE) -+ osal_timer_start(&stp_core_ctx.tx_timer, mtkstp_tx_timeout); -+ else -+ STP_ERR_FUNC("mtk_wcn_stp_send_data: wmt_stop_timer\n"); -+ -+ ret = (INT32) length; -+ } else { -+ /* No winspace to send. Let caller retry */ -+ STP_ERR_FUNC("%s: There is no winspace/txqueue to send !!!\n", __func__); -+ ret = 0; -+ } -+ } -+ -+ stp_ctx_unlock(&stp_core_ctx); -+ /* osal_unlock_unsleepable_lock(&stp_core_ctx.stp_mutex); */ -+ -+ return ret; -+} -+ -+/***************************************************************************** -+* FUNCTION -+* stp_process_rxack -+* DESCRIPTION -+* process ack packet -+* PARAMETERS -+* void -+* RETURNS -+* INT32 0=success, others=error -+*****************************************************************************/ -+static INT32 stp_process_rxack(VOID) -+{ -+ INT32 j, k; -+ UINT8 rxack; -+ INT32 fgResult = (-1); -+ -+ if (stp_core_ctx.sequence.rxack != stp_core_ctx.parser.ack) { -+ j = k = 0; -+ rxack = stp_core_ctx.sequence.rxack; -+ INDEX_INC(rxack); -+ while (rxack != stp_core_ctx.sequence.txseq) { -+ j++; -+ if (rxack == stp_core_ctx.parser.ack) { -+ k = 1; -+ break; -+ } -+ INDEX_INC(rxack); -+ } -+ if (k == 1) { -+ stp_core_ctx.sequence.rxack = stp_core_ctx.parser.ack; -+ stp_core_ctx.tx_read = stp_core_ctx.tx_start_addr[rxack] + stp_core_ctx.tx_length[rxack]; -+ if (stp_core_ctx.tx_read >= MTKSTP_BUFFER_SIZE) -+ stp_core_ctx.tx_read -= MTKSTP_BUFFER_SIZE; -+ -+ stp_core_ctx.sequence.winspace += j; -+ stp_core_ctx.sequence.retry_times = 0; -+ -+ osal_timer_stop(&stp_core_ctx.tx_timer); -+ if (stp_core_ctx.sequence.winspace != MTKSTP_WINSIZE) -+ osal_timer_start(&stp_core_ctx.tx_timer, mtkstp_tx_timeout); -+ -+ fgResult = 0; -+ } -+ } -+ -+ return fgResult; -+} -+ -+/***************************************************************************** -+* FUNCTION -+* stp_process_packet -+* DESCRIPTION -+* process STP packet -+* PARAMETERS -+* void -+* RETURNS -+* void -+*****************************************************************************/ -+static VOID stp_process_packet(VOID) -+{ -+ INT32 fgTriggerResume = (-1); -+ UINT8 txAck = 0; -+ static INT32 fgRxOk; -+ MTK_WCN_BOOL b; -+ MTK_WCN_BOOL is_function_active = 0; -+ static INT32 stp_process_packet_fail_count; -+ INT32 iRet = -1; -+ -+ stp_dbg_pkt_log(stp_core_ctx.parser.type, -+ stp_core_ctx.parser.ack, -+ stp_core_ctx.parser.seq, -+ stp_core_ctx.parser.crc, PKT_DIR_RX, stp_core_ctx.rx_buf, stp_core_ctx.parser.length); -+ /*Optimization */ -+ /*If bluez, direct send packet to hci_core not through RX buffer! */ -+ if ((stp_core_ctx.sequence.expected_rxseq == stp_core_ctx.parser.seq) && -+ (stp_core_ctx.parser.type == BT_TASK_INDX) && STP_BT_STK_IS_BLUEZ(stp_core_ctx)) { -+ /*Indicate packet to hci_stp */ -+ STP_DBG_FUNC("Send Packet to BT_SUBFUCTION, len = %d\n", stp_core_ctx.rx_counter); -+ -+ b = mtk_wcn_sys_if_rx(stp_core_ctx.rx_buf, stp_core_ctx.rx_counter); -+ if (b) -+ STP_ERR_FUNC("mtk_wcn_sys_if_rx is NULL\n"); -+ -+ /* osal_lock_unsleepable_lock(&stp_core_ctx.stp_mutex); */ -+ stp_ctx_lock(&stp_core_ctx); -+ /*Process rx ack */ -+ fgTriggerResume = stp_process_rxack(); -+ stp_core_ctx.sequence.txack = stp_core_ctx.parser.seq; -+ INDEX_INC(stp_core_ctx.sequence.expected_rxseq); -+ txAck = stp_core_ctx.sequence.txack; -+ -+ /*Send ack back */ -+ stp_send_ack(txAck, 0); -+ -+ /* osal_unlock_unsleepable_lock(&stp_core_ctx.stp_mutex); */ -+ stp_ctx_unlock(&stp_core_ctx); -+ fgRxOk = 0; -+ } -+ /* sequence matches expected, enqueue packet */ -+ else if (stp_core_ctx.sequence.expected_rxseq == stp_core_ctx.parser.seq) { -+ is_function_active = -+ ((*sys_check_function_status) (stp_core_ctx.parser.type, OP_FUNCTION_ACTIVE) == -+ STATUS_FUNCTION_ACTIVE); -+ /*If type is valid and function works, then try to enqueue */ -+ if ((stp_core_ctx.parser.type < MTKSTP_MAX_TASK_NUM) && (is_function_active == MTK_WCN_BOOL_TRUE)) { -+ if (stp_core_ctx.parser.type == BT_TASK_INDX) { -+ static const UINT8 rst_buf[7] = { 0x04, 0x0e, 0x04, 0x01, 0x3, 0xc, 0x00 }; -+ -+ if (!osal_strncmp(stp_core_ctx.rx_buf, rst_buf, 7)) -+ osal_printtimeofday("############ BT Rest end <--"); -+ } -+ -+ stp_ctx_lock(&stp_core_ctx); -+ -+ fgTriggerResume = stp_process_rxack(); -+ stp_core_ctx.sequence.txack = stp_core_ctx.parser.seq; -+ INDEX_INC(stp_core_ctx.sequence.expected_rxseq); -+ -+ /*Send tx ack */ -+ txAck = stp_core_ctx.sequence.txack; -+ stp_send_ack(txAck, 0); -+ -+ stp_ctx_unlock(&stp_core_ctx); -+#if CFG_WMT_LTE_COEX_HANDLING -+ if ((stp_core_ctx.parser.type == WMT_TASK_INDX) && -+ (stp_core_ctx.parser.wmtsubtype == WMT_LTE_COEX_FLAG)) { -+ fgRxOk = -+ stp_add_to_rx_queue(stp_core_ctx.rx_buf, stp_core_ctx.rx_counter, COEX_TASK_INDX); -+ } else { -+ fgRxOk = -+ stp_add_to_rx_queue(stp_core_ctx.rx_buf, stp_core_ctx.rx_counter, -+ stp_core_ctx.parser.type); -+ } -+#else -+ if ((stp_core_ctx.parser.type == WMT_TASK_INDX) && -+ (stp_core_ctx.parser.wmtsubtype == WMT_LTE_COEX_FLAG)) { -+ STP_WARN_FUNC("BT/WIFI & LTE coex in non-LTE projects,drop it...\n"); -+ } else { -+ fgRxOk = -+ stp_add_to_rx_queue(stp_core_ctx.rx_buf, stp_core_ctx.rx_counter, -+ stp_core_ctx.parser.type); -+ } -+#endif -+ } else { -+ if (is_function_active == MTK_WCN_BOOL_FALSE) { -+ STP_ERR_FUNC("function type = %d is inactive, so no en-queue to rx\n", -+ stp_core_ctx.parser.type); -+ fgRxOk = 0; /*drop packet */ -+ } else { -+ STP_ERR_FUNC("mtkstp_process_packet: type = %x, the type is invalid\n", -+ stp_core_ctx.parser.type); -+ fgRxOk = 0; /*drop packet */ -+ } -+ stp_ctx_lock(&stp_core_ctx); -+ -+ fgTriggerResume = stp_process_rxack(); -+ stp_core_ctx.sequence.txack = stp_core_ctx.parser.seq; -+ INDEX_INC(stp_core_ctx.sequence.expected_rxseq); -+ -+ /*Send tx ack */ -+ txAck = stp_core_ctx.sequence.txack; -+ stp_send_ack(txAck, 0); -+ -+ stp_ctx_unlock(&stp_core_ctx); -+ } -+ -+ /* enqueue successfully */ -+ if (fgRxOk == 0) { -+ stp_process_packet_fail_count = 0; -+ /*notify corresponding subfunction of incoming data */ -+#if CFG_WMT_LTE_COEX_HANDLING -+ if ((stp_core_ctx.parser.type == WMT_TASK_INDX) && -+ (stp_core_ctx.parser.wmtsubtype == WMT_LTE_COEX_FLAG)) { -+#if 1 -+ STP_DBG_FUNC -+ ("WMT/LTE package:[0x%2x][0x%2x][0x%2x][0x%2x][0x%2x][0x%2x][0x%2x][0x%2x]\n", -+ stp_core_ctx.rx_buf[0], stp_core_ctx.rx_buf[1], stp_core_ctx.rx_buf[2], -+ stp_core_ctx.rx_buf[3], stp_core_ctx.rx_buf[4], stp_core_ctx.rx_buf[5], -+ stp_core_ctx.rx_buf[6], stp_core_ctx.rx_buf[7]); -+#endif -+ stp_notify_btm_handle_wmt_lte_coex(STP_BTM_CORE(stp_core_ctx)); -+ } else { -+ (*sys_event_set) (stp_core_ctx.parser.type); -+ } -+#else -+ if ((stp_core_ctx.parser.type == WMT_TASK_INDX) && -+ (stp_core_ctx.parser.wmtsubtype == WMT_LTE_COEX_FLAG)) { -+ STP_WARN_FUNC("omit BT/WIFI & LTE coex msg handling in non-LTE projects\n"); -+ } else { -+ (*sys_event_set) (stp_core_ctx.parser.type); -+ } -+#endif -+ } else { -+ stp_process_packet_fail_count++; -+ /*Queue is full */ -+ if (stp_core_ctx.parser.type == GPS_TASK_INDX) { -+ /*Clear Rx Queue if GPS */ -+ mtk_wcn_stp_flush_rx_queue(GPS_TASK_INDX); -+ } else { -+ /*notify corresponding subfunction of incoming data */ -+ (*sys_event_set) (stp_core_ctx.parser.type); -+ } -+ /*enqueue fail, don't send ack and wait for peer retry */ -+ STP_ERR_FUNC("Enqueue to Rx queue fail, maybe function %d queue is full\n", -+ stp_core_ctx.parser.type); -+ } -+ } -+ /*sequence not match && previous packet enqueue successfully, send the previous ACK */ -+ else if (fgRxOk == 0) { -+ STP_ERR_FUNC("mtkstp_process_packet: expected_rxseq = %d, parser.seq = %d\n", -+ stp_core_ctx.sequence.expected_rxseq, stp_core_ctx.parser.seq); -+ stp_process_packet_fail_count++; -+ -+ stp_ctx_lock(&stp_core_ctx); -+ /* osal_lock_unsleepable_lock(&stp_core_ctx.stp_mutex); */ -+ txAck = stp_core_ctx.sequence.txack; -+ stp_send_ack(txAck, 1); -+ stp_ctx_unlock(&stp_core_ctx); -+ /* osal_unlock_unsleepable_lock(&stp_core_ctx.stp_mutex); */ -+ STP_ERR_FUNC -+ ("sequence not match && previous packet enqueue successfully, send the previous ACK (ack no =%d)\n", -+ txAck); -+ } -+ /*sequence not match && previous packet enqueue failed, do nothing, make the other side timeout */ -+ else { -+ stp_process_packet_fail_count++; -+ STP_ERR_FUNC -+ ("sequence not match && previous packet enqueue failed, do nothing, make the other side timeout\n"); -+ } -+ -+ if (fgTriggerResume == 0) { -+ /*[PatchNeed]Just Notificaiton, not blocking call */ -+ /* notify adaptation layer for possible tx resume mechanism */ -+ (*sys_event_tx_resume) (stp_core_ctx.sequence.winspace); -+ } -+ -+ if (stp_process_packet_fail_count > MTKSTP_RETRY_LIMIT) { -+ stp_process_packet_fail_count = 0; -+ STP_ERR_FUNC("The process packet fail count > 10 lastly\n\r, whole chip reset\n\r"); -+ mtk_wcn_stp_dbg_dump_package(); -+ /*Whole Chip Reset Procedure Invoke */ -+ /*if(STP_NOT_ENABLE_DBG(stp_core_ctx)) */ -+ if (0 == mtk_wcn_stp_get_wmt_evt_err_trg_assert()) { -+ stp_psm_disable(STP_PSM_CORE(stp_core_ctx)); -+ mtk_wcn_stp_set_wmt_evt_err_trg_assert(1); -+ stp_dbg_set_host_assert_info(4, 37, 1); -+ STP_INFO_FUNC("**Ack Miss trigger firmware assert**\n"); -+ iRet = stp_notify_btm_do_fw_assert_via_emi(STP_BTM_CORE(stp_core_ctx)); -+ if (iRet) { -+ mtk_wcn_stp_set_wmt_evt_err_trg_assert(0); -+ /* (*sys_dbg_assert_aee)("[MT662x]Ack Miss", "**STP Ack Miss**\n Ack Miss.\n"); */ -+ osal_dbg_assert_aee("[SOC_CONSYS]Ack Miss", -+ "**[WCN_ISSUE_INFO]STP Ack Miss**\n Ack Miss.\n"); -+ -+ if (STP_IS_ENABLE_RST(stp_core_ctx)) { -+ STP_SET_READY(stp_core_ctx, 0); -+ stp_btm_notify_wmt_rst_wq(STP_BTM_CORE(stp_core_ctx)); -+ } else { -+ STP_INFO_FUNC("No to launch whole chip reset! for debugging purpose\n"); -+ } -+ } -+ } -+ } -+ -+} -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_init -+* DESCRIPTION -+* init STP kernel -+* PARAMETERS -+* cb_func [IN] function pointers of system APIs -+* RETURNS -+* INT32 0 = success, others = failure -+*****************************************************************************/ -+INT32 mtk_wcn_stp_init(const mtkstp_callback * const cb_func) -+{ -+ INT32 ret = 0; -+ INT32 i = 0; -+ -+ /* Function pointer to point to the currently used transmission interface -+ */ -+ sys_if_tx = cb_func->cb_if_tx; -+ -+ /* Used to inform the function driver has received the corresponding type of information */ -+ sys_event_set = cb_func->cb_event_set; -+ -+ /* Used to inform the function driver can continue to send information and -+ STP has resources to deal with -+ */ -+ sys_event_tx_resume = cb_func->cb_event_tx_resume; -+ -+ /* STP driver determines whether the function is enable. If not enable and -+ STP has received the kind of information, and STP have the right to put it away. -+ */ -+ sys_check_function_status = cb_func->cb_check_funciton_status; -+ -+ /* osal_unsleepable_lock_init(&stp_core_ctx.stp_mutex); */ -+ stp_ctx_lock_init(&stp_core_ctx); -+ /* Setup timer to be used to check if f/w receive the data in the specific time -+ interval after being sent -+ */ -+ for (i = 0; i < MTKSTP_MAX_TASK_NUM; i++) -+ osal_unsleepable_lock_init(&stp_core_ctx.ring[i].mtx); -+ -+ stp_core_ctx.tx_timer.timeoutHandler = stp_tx_timeout_handler; -+ stp_core_ctx.tx_timer.timeroutHandlerData = 0; -+ osal_timer_create(&stp_core_ctx.tx_timer); -+ -+ STP_SET_BT_STK(stp_core_ctx, 0); -+ STP_SET_ENABLE(stp_core_ctx, 0); -+ STP_SET_ENABLE_DBG(stp_core_ctx, 0); -+ STP_SET_ENABLE_RST(stp_core_ctx, 0); -+ STP_SET_PENDING_TYPE(stp_core_ctx, 0); -+ STP_SET_READY(stp_core_ctx, 0); -+ STP_SET_SUPPORT_PROTOCOL(stp_core_ctx, 0); -+ STP_SET_PSM_CORE(stp_core_ctx, stp_psm_init()); -+ STP_SET_FW_COREDUMP_FLAG(stp_core_ctx, 0); -+ STP_ENABLE_FW_COREDUMP(stp_core_ctx, 0); -+ STP_SET_WMT_LAST_CLOSE(stp_core_ctx, 0); -+ STP_SET_EVT_ERR_ASSERT(stp_core_ctx, 0); -+ -+ if (!STP_PSM_CORE(stp_core_ctx)) { -+ ret = (-3); -+ goto ERROR; -+ } -+ -+ STP_SET_BTM_CORE(stp_core_ctx, stp_btm_init()); -+ if (!STP_BTM_CORE(stp_core_ctx)) { -+ STP_ERR_FUNC("STP_BTM_CORE(stp_core_ctx) initialization fail!\n"); -+ ret = (-3); -+ goto ERROR; -+ } -+ -+ if (STP_BTM_CORE(stp_core_ctx) != NULL) -+ g_mtkstp_dbg = stp_dbg_init(STP_BTM_CORE(stp_core_ctx)); -+ else -+ g_mtkstp_dbg = stp_dbg_init(NULL); -+ -+ if (!g_mtkstp_dbg) { -+ STP_ERR_FUNC("g_mtkstp_dbg initialization fail!\n"); -+ ret = (-3); -+ goto ERROR; -+ } -+ STP_SET_ENABLE_RST(stp_core_ctx, 1); -+#ifdef CONFIG_LOG_STP_INTERNAL -+ mtk_wcn_stp_dbg_enable(); -+#else -+ mtk_wcn_stp_dbg_enable(); -+#endif -+ goto RETURN; -+ -+ERROR: -+ stp_psm_deinit(STP_PSM_CORE(stp_core_ctx)); -+ -+RETURN: -+ return ret; -+ -+} -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_deinit -+* DESCRIPTION -+* deinit STP kernel -+* PARAMETERS -+* void -+* RETURNS -+* INT32 0 = success, others = failure -+*****************************************************************************/ -+INT32 mtk_wcn_stp_deinit(void) -+{ -+ UINT32 i = 0; -+ -+ sys_if_tx = NULL; -+ sys_event_set = NULL; -+ sys_event_tx_resume = NULL; -+ sys_check_function_status = NULL; -+ -+ stp_dbg_deinit(g_mtkstp_dbg); -+ stp_btm_deinit(STP_BTM_CORE(stp_core_ctx)); -+ stp_psm_deinit(STP_PSM_CORE(stp_core_ctx)); -+ -+ for (i = 0; i < MTKSTP_MAX_TASK_NUM; i++) -+ osal_unsleepable_lock_deinit(&stp_core_ctx.ring[i].mtx); -+ -+ stp_ctx_lock_deinit(&stp_core_ctx); -+ return 0; -+} -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_btm_get_dmp -+* DESCRIPTION -+* get stp dump related information -+* PARAMETERS -+* buffer: dump placement, len: dump size -+* RETURNS -+* 0: Success Negative Value: Fail -+*****************************************************************************/ -+ -+int mtk_wcn_stp_btm_get_dmp(char *buf, int *len) -+{ -+ return stp_dbg_dmp_out(g_mtkstp_dbg, buf, len); -+} -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_psm_notify_stp -+* DESCRIPTION -+* WMT notification to STP that power saving job is done or not -+* PARAMETERS -+* -+* RETURNS -+* 0: Sccuess Negative value: Fail -+*****************************************************************************/ -+int mtk_wcn_stp_psm_notify_stp(const MTKSTP_PSM_ACTION_T action) -+{ -+ return stp_psm_notify_stp(STP_PSM_CORE(stp_core_ctx), action); -+} -+ -+int mtk_wcn_stp_set_psm_state(MTKSTP_PSM_STATE_T state) -+{ -+ return stp_psm_set_state(STP_PSM_CORE(stp_core_ctx), state); -+} -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_psm_enable -+* DESCRIPTION -+* enable STP sleep/wakeup support -+* PARAMETERS -+* void -+* RETURNS -+* 0: Sccuess Negative value: Fail -+*****************************************************************************/ -+INT32 mtk_wcn_stp_psm_enable(INT32 idle_time_to_sleep) -+{ -+#if 0 -+ if (MTK_WCN_BOOL_TRUE == stp_psm_is_quick_ps_support()) { -+ if (mtk_wcn_stp_is_ready()) -+ return stp_psm_enable(STP_PSM_CORE(stp_core_ctx), idle_time_to_sleep); -+ STP_WARN_FUNC("STP Not Ready, Dont do Sleep/Wakeup\n"); -+ return -1; -+ } -+ if (mtk_wcn_stp_is_ready() && mtk_wcn_stp_is_btif_fullset_mode()) { -+ return stp_psm_enable(STP_PSM_CORE(stp_core_ctx), idle_time_to_sleep); -+ } else if (mtk_wcn_stp_is_sdio_mode()) { -+ stp_psm_enable(STP_PSM_CORE(stp_core_ctx), idle_time_to_sleep); -+ STP_DBG_FUNC("PSM is not support under SDIO mode\n"); -+ return 0; -+ } -+ STP_WARN_FUNC("STP Not Ready, Dont do Sleep/Wakeup\n"); -+ return -1; -+ -+#else -+ if (mtk_wcn_stp_is_ready() && mtk_wcn_stp_is_btif_fullset_mode()) { -+ return stp_psm_enable(STP_PSM_CORE(stp_core_ctx), idle_time_to_sleep); -+ } else if (mtk_wcn_stp_is_sdio_mode()) { -+ stp_psm_enable(STP_PSM_CORE(stp_core_ctx), idle_time_to_sleep); -+ STP_DBG_FUNC("PSM is not support under SDIO mode\n"); -+ return 0; -+ } -+ STP_WARN_FUNC("STP Not Ready, Dont do Sleep/Wakeup\n"); -+ return -1; -+#endif -+} -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_psm_disable -+* DESCRIPTION -+* disable STP sleep/wakeup support -+* PARAMETERS -+* void -+* RETURNS -+* 0: Sccuess Negative value: Fail -+*****************************************************************************/ -+extern INT32 mtk_wcn_stp_psm_disable(VOID) -+{ -+#if 0 -+ if (MTK_WCN_BOOL_TRUE == stp_psm_is_quick_ps_support()) { -+ if (mtk_wcn_stp_is_ready()) -+ return stp_psm_disable(STP_PSM_CORE(stp_core_ctx)); -+ STP_WARN_FUNC("STP Not Ready, Dont do Sleep/Wakeup\n"); -+ return -1; -+ } -+ if (mtk_wcn_stp_is_ready() && mtk_wcn_stp_is_btif_fullset_mode()) { -+ return stp_psm_disable(STP_PSM_CORE(stp_core_ctx)); -+ } else if (mtk_wcn_stp_is_sdio_mode()) { -+ stp_psm_disable(STP_PSM_CORE(stp_core_ctx)); -+ return 0; -+ } -+ STP_WARN_FUNC("STP Not Ready, Dont do Sleep/Wakeup\n"); -+ return -1; -+ -+#else -+ if (mtk_wcn_stp_is_ready() && mtk_wcn_stp_is_btif_fullset_mode()) { -+ return stp_psm_disable(STP_PSM_CORE(stp_core_ctx)); -+ } else if (mtk_wcn_stp_is_sdio_mode()) { -+ stp_psm_disable(STP_PSM_CORE(stp_core_ctx)); -+ return 0; -+ } -+ STP_DBG_FUNC("STP Not Ready, Dont do Sleep/Wakeup\n"); -+ return 0; -+ -+#endif -+} -+ -+extern INT32 mtk_wcn_stp_psm_reset(VOID) -+{ -+ return stp_psm_reset(STP_PSM_CORE(stp_core_ctx)); -+} -+ -+extern INT32 mtk_wcn_stp_dbg_disable(VOID) -+{ -+ if (STP_IS_ENABLE_DBG(stp_core_ctx)) { -+ STP_DBG_FUNC("STP dbg mode is turned off\n"); -+ STP_SET_ENABLE_DBG(stp_core_ctx, 0); -+ stp_dbg_disable(g_mtkstp_dbg); -+ } else { -+ STP_WARN_FUNC("STP dbg mode has been turned off\n"); -+ } -+ -+ return 0; -+} -+ -+extern INT32 mtk_wcn_stp_dbg_enable(VOID) -+{ -+ if (STP_NOT_ENABLE_DBG(stp_core_ctx)) { -+ STP_DBG_FUNC("STP dbg mode is turned on\n"); -+ STP_SET_ENABLE_DBG(stp_core_ctx, 1); -+ stp_dbg_enable(g_mtkstp_dbg); -+ } else { -+ STP_WARN_FUNC("STP dbg mode has been turned on\n"); -+ } -+ -+ return 0; -+} -+ -+INT32 mtk_wcn_stp_dbg_log_ctrl(UINT32 on) -+{ -+ stp_dbg_log_ctrl(on); -+ return 0; -+} -+ -+INT32 mtk_wcn_stp_coredump_flag_ctrl(UINT32 on) -+{ -+ STP_ENABLE_FW_COREDUMP(stp_core_ctx, on); -+ STP_INFO_FUNC("coredump function mode: %d.\n", on); -+ g_coredump_mode = on; -+ return 0; -+} -+ -+INT32 mtk_wcn_stp_coredump_flag_get(VOID) -+{ -+ return STP_ENABLE_FW_COREDUMP_FLAG(stp_core_ctx); -+} -+ -+static INT32 stp_parser_data_in_mand_mode(UINT32 length, UINT8 *p_data) -+{ -+ UINT8 padding_len = 0; -+ INT32 remain_length; /* GeorgeKuo: sync from MAUI, change to unsigned */ -+ MTK_WCN_BOOL is_function_active = 0; -+ INT32 i = length; -+ -+ while (i > 0) { -+ switch (stp_core_ctx.parser.state) { -+ case MTKSTP_SYNC: /* b'10 */ -+ /* if (((*p_data & 0x80) == 0x80) && ((*p_data & 0x40) == 0x00)) */ -+ /* if(*p_data == 0x80) */ -+ if ((*p_data & 0x80) == 0x80) { -+ /* STP_DBG_FUNC("[STP] STP Packet Start =========>\n"); */ -+ if (*p_data != 0x80) -+ STP_WARN_FUNC("SDIO not 0x80!!(0x%x)\n", *p_data); -+ -+ if (i >= 4) { -+#if !(REMOVE_USELESS_LOG) -+ /*print header, when get the full STP header */ -+ UINT32 type = (*(p_data + 1) & 0x70) >> 4; -+ UINT8 *type_name = ""; -+ -+ type_name = stp_type_to_dbg_string(type); -+ STP_DBG_FUNC( -+ "STP Rx Header: [%02x %02x %02x %02x] type=%s, len=%d, seq=%d, ack=%d\n", -+ *p_data, *(p_data + 1), *(p_data + 2), *(p_data + 3), -+ type_name, ((*(p_data + 1) & 0x0f) << 8) + *(p_data + 2), -+ (*p_data & 0x38) >> 3, *p_data & 0x07); -+#endif -+ } else { -+ STP_WARN_FUNC("STP Rx: discard due to i < 4 (%d)\n", i); -+ } -+ -+ /* STP_DBG_FUNC("[STP] sync->nak\n"); */ -+ stp_change_rx_state(MTKSTP_NAK); -+ stp_core_ctx.rx_counter++; -+ } else { -+ STP_WARN_FUNC("sync to sync!!(0x%x)\n", *p_data); -+ stp_change_rx_state(MTKSTP_SYNC); -+ } -+ break; -+ -+ case MTKSTP_NAK: -+ /* STP_DBG_FUNC("[STP] nak->length\n"); */ -+ stp_change_rx_state(MTKSTP_LENGTH); -+ stp_core_ctx.parser.type = (*p_data & 0x70) >> 4; -+ if (stp_core_ctx.parser.type <= MTKSTP_MAX_TASK_NUM) { -+ stp_core_ctx.parser.length = (*p_data & 0x0f) << 8; -+ stp_core_ctx.rx_counter++; -+ } else { -+ STP_WARN_FUNC("nak to sync\n"); -+ stp_change_rx_state(MTKSTP_SYNC); -+ } -+ break; -+ -+ case MTKSTP_LENGTH: -+ /* STP_DBG_FUNC("[STP] length -> checksum\n"); */ -+ stp_change_rx_state(MTKSTP_CHECKSUM); -+ stp_core_ctx.parser.length += *p_data; -+ -+ /*Valid length checking */ -+ if (stp_core_ctx.parser.length < 2000) { -+ stp_core_ctx.rx_counter++; -+ } else { -+ STP_WARN_FUNC("The length of STP packet is not valid !!! length = %d\n", -+ stp_core_ctx.parser.length); -+ stp_change_rx_state(MTKSTP_SYNC); -+ stp_core_ctx.rx_counter = 0; -+ /* return -1; */ -+ } -+ -+ break; -+ -+ case MTKSTP_CHECKSUM: -+ -+ if ((stp_core_ctx.parser.type == STP_TASK_INDX) || -+ (stp_core_ctx.parser.type == INFO_TASK_INDX)) { -+ stp_change_rx_state(MTKSTP_FW_MSG); -+ stp_core_ctx.rx_counter = 0; -+ i -= 1; -+ if (i != 0) -+ p_data += 1; -+ -+ continue; -+ } -+ -+ if (stp_core_ctx.parser.length == 0) { -+ STP_WARN_FUNC("checksum to sync\n"); -+ stp_change_rx_state(MTKSTP_SYNC); -+ stp_core_ctx.rx_counter = 0; -+ } else { -+ /* STP_DBG_FUNC("[STP] checksum->data\n"); */ -+ stp_change_rx_state(MTKSTP_DATA); -+ stp_core_ctx.rx_counter = 0; -+ } -+ break; -+ -+ case MTKSTP_DATA: -+ -+ /* block copy instead of byte copy */ -+ if (stp_core_ctx.parser.length < stp_core_ctx.rx_counter) { -+ STP_ERR_FUNC("Abnormal length in STP_DATA phase 0x%x, 0x%x\n", -+ stp_core_ctx.parser.length, stp_core_ctx.rx_counter); -+ osal_assert(0); -+ } -+ remain_length = stp_core_ctx.parser.length - stp_core_ctx.rx_counter; -+ if (i >= remain_length) { -+ /*boundary checking */ -+ if (stp_core_ctx.rx_counter + remain_length >= MTKSTP_BUFFER_SIZE) { -+ STP_ERR_FUNC("Abnormal!! Memory operation over boundary!!\n"); -+ stp_change_rx_state(MTKSTP_SYNC); -+ stp_core_ctx.rx_counter = 0; -+ return -1; -+ } -+ -+ osal_memcpy(stp_core_ctx.rx_buf + stp_core_ctx.rx_counter, p_data, -+ remain_length); -+ i -= remain_length; -+ p_data += remain_length; -+ stp_core_ctx.rx_counter = stp_core_ctx.parser.length; -+ stp_core_ctx.parser.state = MTKSTP_CRC1; -+ continue; -+ -+ } else { /* only copy by data length */ -+ -+ /*fixed klocwork insight issue */ -+ /*boundary checking */ -+ if (i + stp_core_ctx.rx_counter >= MTKSTP_BUFFER_SIZE) { -+ STP_ERR_FUNC("Abnormal!! Memory operation over boundary 2!!\n"); -+ stp_core_ctx.rx_counter = 0; -+ return -1; -+ } -+ -+ osal_memcpy(stp_core_ctx.rx_buf + stp_core_ctx.rx_counter, p_data, i); -+ stp_core_ctx.rx_counter += i; /* all remain buffer are data */ -+ i = 0; -+ p_data += i; -+ continue; -+ } -+ break; -+ -+ case MTKSTP_CRC1: -+ stp_change_rx_state(MTKSTP_CRC2); -+ break; -+ -+ case MTKSTP_CRC2: -+#if 1 -+ if (stp_core_ctx.parser.type == WMT_TASK_INDX) { -+ stp_core_ctx.parser.wmtsubtype = stp_core_ctx.rx_buf[1]; -+ STP_DBG_FUNC("wmt sub type (0x%x)\n", stp_core_ctx.parser.wmtsubtype); -+ } -+#endif -+ /*SDIO mode do it. */ -+ if (mtk_wcn_stp_is_sdio_mode()) { -+ /*STP packet 4-bytes alignment */ -+ /*Discard padding bytes , otherwise make parser state machine disorder */ -+ if (i <= 4) { -+ /*STP_DBG_FUNC("STP last block padding %d bytes\n", i-1); */ -+ p_data += (i - 1); -+ i -= (i - 1); -+ } else { -+ padding_len = (0x04 - ((stp_core_ctx.parser.length + 6) & 0x03)) & 0x03; -+ p_data += padding_len; -+ i -= padding_len; -+ /*STP_DBG_FUNC("STP Agg padding %d bytes\n", padding_len); */ -+ } -+ } -+ stp_dbg_pkt_log(stp_core_ctx.parser.type, -+ 0, 0, 0, PKT_DIR_RX, stp_core_ctx.rx_buf, stp_core_ctx.rx_counter); -+ if ((stp_core_ctx.parser.type == BT_TASK_INDX) && STP_BT_STK_IS_BLUEZ(stp_core_ctx)) { -+ int b; -+ -+ /*Indicate packet to hci_stp */ -+ if (gStpDbgLvl >= STP_LOG_DBG) { -+ stp_dump_data(stp_core_ctx.rx_buf, "indicate_to_bt_core", -+ stp_core_ctx.rx_counter); -+ } -+ -+ b = mtk_wcn_sys_if_rx(stp_core_ctx.rx_buf, stp_core_ctx.rx_counter); -+ if (b) -+ STP_ERR_FUNC("mtk_wcn_sys_if_rx is NULL\n"); -+ -+ } else { -+ -+ is_function_active = ( -+ (*sys_check_function_status)(stp_core_ctx.parser.type, OP_FUNCTION_ACTIVE) -+ == STATUS_FUNCTION_ACTIVE); -+ -+ /*check type and function if active? */ -+ if ((stp_core_ctx.parser.type < MTKSTP_MAX_TASK_NUM) -+ && (is_function_active == MTK_WCN_BOOL_TRUE)) { -+#if CFG_WMT_LTE_COEX_HANDLING -+ if ((stp_core_ctx.parser.type == WMT_TASK_INDX) -+ && stp_core_ctx.parser.wmtsubtype == WMT_LTE_COEX_FLAG) { -+ STP_INFO_FUNC("wmt/lte coex package!\n"); -+ stp_add_to_rx_queue(stp_core_ctx.rx_buf, -+ stp_core_ctx.rx_counter, COEX_TASK_INDX); -+ stp_notify_btm_handle_wmt_lte_coex(STP_BTM_CORE(stp_core_ctx)); -+ } else { -+ stp_add_to_rx_queue(stp_core_ctx.rx_buf, -+ stp_core_ctx.rx_counter, -+ stp_core_ctx.parser.type); -+ -+ /*notify corresponding subfunction of incoming data */ -+ (*sys_event_set) (stp_core_ctx.parser.type); -+ } -+#else -+ if ((stp_core_ctx.parser.type == WMT_TASK_INDX) -+ && stp_core_ctx.parser.wmtsubtype == WMT_LTE_COEX_FLAG) { -+ STP_WARN_FUNC -+ ("omit BT/WIFI & LTE coex msg handling in non-LTE projects\n"); -+ } else { -+ stp_add_to_rx_queue(stp_core_ctx.rx_buf, -+ stp_core_ctx.rx_counter, -+ stp_core_ctx.parser.type); -+ -+ /*notify corresponding subfunction of incoming data */ -+ (*sys_event_set) (stp_core_ctx.parser.type); -+ } -+#endif -+ } else { -+ if (is_function_active == MTK_WCN_BOOL_FALSE) { -+ STP_ERR_FUNC -+ ("function type = %d is inactive, so no en-queue to rx\n", -+ stp_core_ctx.parser.type); -+ } else { -+ STP_ERR_FUNC -+ ("mtkstp_process_packet: type = %x, the type is invalid\n", -+ stp_core_ctx.parser.type); -+ } -+ } -+ } -+ -+ /* STP_DBG_FUNC("[STP] crc2->sync\n"); */ -+ /* STP_DBG_FUNC("[STP] STP Packet End <=========\n"); */ -+ stp_core_ctx.rx_counter = 0; -+ stp_change_rx_state(MTKSTP_SYNC); -+ -+ break; -+ -+ case MTKSTP_FW_MSG: -+ -+ /*f/w assert and exception information */ -+ if (stp_core_ctx.parser.length < stp_core_ctx.rx_counter) { -+ STP_ERR_FUNC("Abnormal length in STP_DATA phase 0x%x, 0x%x\n", -+ stp_core_ctx.parser.length, stp_core_ctx.rx_counter); -+ } -+ -+ remain_length = stp_core_ctx.parser.length - stp_core_ctx.rx_counter; -+ -+ if (i >= remain_length) { -+ osal_memcpy(stp_core_ctx.rx_buf + stp_core_ctx.rx_counter, p_data, -+ remain_length); -+ i -= remain_length; -+ p_data += remain_length; -+ stp_core_ctx.rx_counter = stp_core_ctx.parser.length; -+ *(stp_core_ctx.rx_buf + stp_core_ctx.rx_counter) = '\0'; -+ /*Trace32 Dump */ -+ if (stp_core_ctx.parser.type == STP_TASK_INDX) { -+ /* g_block_tx = 1; */ -+ mtk_wcn_stp_coredump_start_ctrl(1); -+ pr_debug("[len=%d][type=%d]\n%s\n", stp_core_ctx.rx_counter, -+ stp_core_ctx.parser.type, stp_core_ctx.rx_buf); -+ /*use paged dump or full dump */ -+ stp_btm_notify_wmt_dmp_wq(stp_core_ctx.btm); -+#if 0 -+ stp_dbg_log_pkt(g_mtkstp_dbg, STP_DBG_FW_DMP /*STP_DBG_FW_ASSERT */ , 5, -+ 0, 0, 0, 0, -+ (stp_core_ctx.rx_counter + 1), stp_core_ctx.rx_buf); -+#endif -+ } -+ -+ /*discard CRC */ -+ /* we will discard antoher CRC on the outer switch procedure. */ -+ if (i >= 1) { -+ STP_INFO_FUNC("crc discard.. i = %d\n", i); -+ i -= 1; -+ if (i > 0) -+ p_data += 1; -+ -+ } -+ -+ /*STP packet 4-bytes alignment */ -+ /*Discard padding bytes , otherwise make parser state machine disorder */ -+ if (i <= 4) { -+ STP_INFO_FUNC -+ ("\n[STP]FW_EVENT========= block padding %d bytes =========\n", -+ i - 1); -+ p_data += (i - 1); -+ i -= (i - 1); -+ } else { -+ padding_len = (0x04 - ((stp_core_ctx.parser.length + 6) & 0x03)) & 0x03; -+ p_data += padding_len; -+ i -= padding_len; -+ STP_INFO_FUNC -+ ("\n[STP]FW_EVENT========= STP Agg padding %d bytes =========\n", -+ padding_len); -+ } -+ stp_change_rx_state(MTKSTP_SYNC); -+ -+ } else { /* only copy by data length */ -+ -+ STP_ERR_FUNC("raw data doesn't contain full stp packet!!\n"); -+ } -+ break; -+ default: -+ break; -+ } -+ p_data++; -+ i--; -+ } -+ -+ return 0; -+} -+ -+static INT32 stp_parser_data_in_full_mode(UINT32 length, UINT8 *p_data) -+{ -+ INT32 remain_length; /* GeorgeKuo: sync from MAUI, change to unsigned */ -+ INT32 i = length; -+ -+ while (i > 0) { -+ switch (stp_core_ctx.parser.state) { -+ -+ case MTKSTP_RESYNC1: /* RESYNC must be 4 _continuous_ 0x7f */ -+ if (*p_data == 0x7f) -+ stp_change_rx_state(MTKSTP_RESYNC2); -+ else -+ stp_change_rx_state(MTKSTP_RESYNC1); -+ break; -+ case MTKSTP_RESYNC2: -+ if (*p_data == 0x7f) -+ stp_change_rx_state(MTKSTP_RESYNC3); -+ else -+ stp_change_rx_state(MTKSTP_RESYNC1); -+ break; -+ case MTKSTP_RESYNC3: -+ if (*p_data == 0x7f) -+ stp_change_rx_state(MTKSTP_RESYNC4); -+ else -+ stp_change_rx_state(MTKSTP_RESYNC1); -+ break; -+ case MTKSTP_RESYNC4: -+ if (*p_data == 0x7f) -+ stp_change_rx_state(MTKSTP_SYNC); -+ else -+ stp_change_rx_state(MTKSTP_RESYNC1); -+ break; -+ case MTKSTP_SYNC: /* b'10 */ -+ STP_DUMP_PACKET_HEAD(p_data, "rx (uart):", length > 4 ? 4 : length); -+ if (((*p_data & 0x80) == 0x80) && ((*p_data & 0x40) == 0x00)) { -+ stp_change_rx_state(MTKSTP_NAK); -+ stp_core_ctx.parser.seq = (*p_data & 0x38) >> 3; -+ stp_core_ctx.parser.ack = *p_data & 0x07; -+ stp_core_ctx.rx_buf[0] = *p_data; -+ /* Geoge FIXME: WHY comment the following line? */ -+ /* stp_core_ctx.rx_counter++; */ -+ -+ if (i >= 4 && gStpDbgLvl >= STP_LOG_DBG) { -+ /*print header, when get the full STP header */ -+#if !(REMOVE_USELESS_LOG) -+ int type = (*(p_data + 1) & 0x70) >> 4; -+ char *type_name = ""; -+ -+ type_name = stp_type_to_dbg_string(type); -+ -+ STP_DBG_FUNC -+ ("STP Rx Header: [%02x %02x %02x %02x] type=%s, len=%d, seq=%d, ack=%d\n", -+ *p_data, *(p_data + 1), *(p_data + 2), *(p_data + 3), type_name, -+ ((*(p_data + 1) & 0x0f) << 8) + *(p_data + 2), -+ (*p_data & 0x38) >> 3, *p_data & 0x07); -+#endif -+ } else { -+ STP_DBG_FUNC("STP Rx: discard due to i < 4\n"); -+ } -+ } else if ((*p_data == 0x7f) && (prev_state == MTKSTP_RESYNC4)) { -+ /* if this 0x7f is continuous to resync pattern */ -+ /* skip this continuous 0x7f, remain current & prev state */ -+ osal_assert(0); -+ STP_ERR_FUNC("MTKSTP_SYNC: continuous resync pattern, buff = %x\n", *p_data); -+ } else if (*p_data == 0x7f) { /* a start of 0x7f, maybe this is resync pattern */ -+ stp_change_rx_state(MTKSTP_RESYNC2); -+ osal_assert(0); -+ STP_ERR_FUNC("MTKSTP_SYNC: go to MTKSTP_RESYNC2, buff = %x\n", *p_data); -+ } else if (*p_data == 0x55) { /* STP delimiter */ -+ /* do nothing for delimiter */ -+ } else { /* unexpected, go to resync1 */ -+ osal_assert(0); -+ STP_ERR_FUNC("MTKSTP_SYNC: unexpected data, buff = %x\n", *p_data); -+ } -+ break; -+ -+ case MTKSTP_NAK: -+ /* (*sys_dbg_print)("MTKSTP_NAK : mtk_wcn_stp_parser_data, buff = %x", *p_data); */ -+ if (fgEnableNak == 0) -+ stp_core_ctx.parser.nak = 0; /* disable NAK */ -+ else -+ stp_core_ctx.parser.nak = (*p_data & 0x80) >> 7; -+ -+ stp_core_ctx.parser.type = (*p_data & 0x70) >> 4; -+ stp_core_ctx.parser.length = (*p_data & 0x0f) << 8; -+ stp_core_ctx.rx_buf[1] = *p_data; -+ /* Geoge FIXME: WHY comment the following line? */ -+ /*stp_core_ctx.rx_counter++; */ -+ if (stp_core_ctx.parser.nak) -+ STP_ERR_FUNC("MTKSTP_NAK TRUE: mtk_wcn_stp_parser_data, buff = %x\n", *p_data); -+ -+ if (stp_core_ctx.parser.type < MTKSTP_MAX_TASK_NUM) -+ stp_change_rx_state(MTKSTP_LENGTH); -+ else -+ stp_change_rx_state(MTKSTP_SYNC); -+ break; -+ -+ case MTKSTP_LENGTH: -+ /* (*sys_dbg_print)("MTKSTP_LENGTH : mtk_wcn_stp_parser_data, buff = %x", *p_data); */ -+ stp_change_rx_state(MTKSTP_CHECKSUM); -+ stp_core_ctx.parser.length += *p_data; -+ -+ /*Valid length checking */ -+ if (stp_core_ctx.parser.length > 2048) { -+ STP_ERR_FUNC("The length of STP packet is not valid !!! length = %d\n", -+ stp_core_ctx.parser.length); -+ stp_change_rx_state(MTKSTP_RESYNC1); -+ stp_core_ctx.rx_counter = 0; -+ STP_TRACE_FUNC("--\n"); -+ return -1; -+ } -+ -+ stp_core_ctx.rx_buf[2] = *p_data; -+ /* Geoge FIXME: WHY comment the following line? */ -+ /*stp_core_ctx.rx_counter++; */ -+ break; -+ -+ case MTKSTP_CHECKSUM: -+ /* (*sys_dbg_print)("MTKSTP_CHECKSUM : mtk_wcn_stp_parser_data, buff = %x", *p_data); */ -+ if ((stp_core_ctx.parser.type == STP_TASK_INDX) || -+ (stp_core_ctx.parser.type == INFO_TASK_INDX)) { -+ stp_change_rx_state(MTKSTP_FW_MSG); -+ stp_core_ctx.rx_counter = 0; -+ i -= 1; -+ if (i != 0) -+ p_data += 1; -+ -+ continue; -+ } -+ -+ if (((stp_core_ctx.rx_buf[0] + -+ stp_core_ctx.rx_buf[1] + stp_core_ctx.rx_buf[2]) & 0xff) == *p_data) { -+ /* header only packet */ -+ if (stp_core_ctx.parser.length == 0) { -+ INT32 fgTriggerResume = (-1); -+ -+ /* osal_lock_unsleepable_lock(&stp_core_ctx.stp_mutex); */ -+ stp_ctx_lock(&stp_core_ctx); -+ if (stp_core_ctx.inband_rst_set == 0) { -+ stp_dbg_pkt_log(STP_TASK_INDX, -+ stp_core_ctx.parser.ack, -+ stp_core_ctx.parser.seq, -+ 5, /* STP type id */ -+ PKT_DIR_RX, -+ NULL, -+ 0); -+ fgTriggerResume = stp_process_rxack(); -+ } else { -+ STP_WARN_FUNC -+ ("Now it's inband reset process and drop ACK packet.\n"); -+ } -+ -+ if (fgTriggerResume == 0) { -+ /* notify adaptation layer for -+ * possible tx resume mechanism -+ */ -+ (*sys_event_tx_resume) (stp_core_ctx.sequence.winspace); -+ } -+ stp_ctx_unlock(&stp_core_ctx); -+ /* osal_unlock_unsleepable_lock(&stp_core_ctx.stp_mutex); */ -+ stp_change_rx_state(MTKSTP_SYNC); -+ stp_core_ctx.rx_counter = 0; -+ } else { -+ stp_change_rx_state(MTKSTP_DATA); -+ stp_core_ctx.rx_counter = 0; -+ } -+ } else { -+ STP_ERR_FUNC("The checksum of header is error !!! %02x %02x %02x %02x\n", -+ stp_core_ctx.rx_buf[0], stp_core_ctx.rx_buf[1], -+ stp_core_ctx.rx_buf[2], *p_data); -+ /* George FIXME: error handling mechanism shall be refined */ -+ stp_change_rx_state(MTKSTP_RESYNC1); -+ stp_core_ctx.rx_counter = 0; -+ -+ /* since checksum error is usually related to interface -+ * buffer overflow, so we just let timeout mechanism to -+ * handle such error. -+ */ -+ STP_TRACE_FUNC("--\n"); -+ /* return and purge COMM port */ -+ return -1; -+ /*stp_send_ack(1); NAK mechanism is removed */ -+ } -+ break; -+ -+ case MTKSTP_DATA: -+#if 0 -+ if (stp_core_ctx.rx_counter < stp_core_ctx.parser.length) { -+ stp_core_ctx.rx_buf[stp_core_ctx.rx_counter] = *p_data; -+ stp_core_ctx.rx_counter++; -+ } -+ if (stp_core_ctx.rx_counter == stp_core_ctx.parser.length) -+ stp_change_rx_state(MTKSTP_CRC1); -+#else -+ /* block copy instead of byte copy */ -+ if (stp_core_ctx.parser.length < stp_core_ctx.rx_counter) { -+ STP_ERR_FUNC("Abnormal length in STP_DATA phase 0x%x, 0x%x\n", -+ stp_core_ctx.parser.length, stp_core_ctx.rx_counter); -+ osal_assert(0); -+ } -+ remain_length = stp_core_ctx.parser.length - stp_core_ctx.rx_counter; -+ if (i >= remain_length) { -+ osal_memcpy(stp_core_ctx.rx_buf + stp_core_ctx.rx_counter, p_data, -+ remain_length); -+ -+ i -= remain_length; -+ p_data += remain_length; -+ stp_core_ctx.rx_counter = stp_core_ctx.parser.length; -+ stp_core_ctx.parser.state = MTKSTP_CRC1; -+ continue; -+ } else { /* only copy by data length */ -+ -+ /*fixed klocwork insight issue */ -+ if (i + stp_core_ctx.rx_counter >= MTKSTP_BUFFER_SIZE) { -+ STP_ERR_FUNC -+ ("Fail to handle Packet, maybe it doesn't follow STP protocol.\n"); -+ stp_change_rx_state(MTKSTP_RESYNC1); -+ stp_core_ctx.rx_counter = 0; -+ STP_TRACE_FUNC("--\n"); -+ return -1; -+ } -+ -+ osal_memcpy(stp_core_ctx.rx_buf + stp_core_ctx.rx_counter, p_data, i); -+ stp_core_ctx.rx_counter += i; /* all remain buffer are data */ -+ i = 0; -+ p_data += i; -+ continue; -+ } -+#endif -+ break; -+ -+ case MTKSTP_CRC1: -+ stp_change_rx_state(MTKSTP_CRC2); -+ stp_core_ctx.parser.crc = *p_data; -+ break; -+ case MTKSTP_CRC2: -+ stp_change_rx_state(MTKSTP_SYNC); -+ stp_core_ctx.parser.crc += (*p_data) << 8; -+#if 1 -+ if (stp_core_ctx.parser.type == WMT_TASK_INDX) { -+ stp_core_ctx.parser.wmtsubtype = stp_core_ctx.rx_buf[1]; -+ STP_DBG_FUNC("wmt sub type is (0x%x)\n", stp_core_ctx.parser.wmtsubtype); -+ } -+#endif -+ if (stp_check_crc(stp_core_ctx.rx_buf, stp_core_ctx.rx_counter, stp_core_ctx.parser.crc) -+ == MTK_WCN_BOOL_TRUE) { -+ if (stp_core_ctx.inband_rst_set == 0) -+ stp_process_packet(); -+ else -+ STP_WARN_FUNC("Now it's inband reset process and drop packet.\n"); -+ } else { -+ STP_ERR_FUNC("The CRC of packet is error !!!\n"); -+ /* George FIXME: error handling mechanism shall be refined */ -+ stp_change_rx_state(MTKSTP_RESYNC1); -+ stp_core_ctx.rx_counter = 0; -+ -+ /* since checksum error is usually related to interface -+ * buffer overflow, so we just let timeout mechanism to -+ * handle such error. -+ */ -+ STP_TRACE_FUNC("--\n"); -+ /* return and purge COMM port */ -+ return -1; -+ /*stp_send_ack(1); NAK mechanism is removed */ -+ } -+ break; -+ -+ case MTKSTP_FW_MSG: -+#if CFG_WMT_DUMP_INT_STATUS -+ if (MTK_WCN_BOOL_TRUE == wmt_plat_dump_BGF_irq_status()) -+ wmt_plat_BGF_irq_dump_status(); -+#endif -+ if (STP_IS_READY(stp_core_ctx)) -+ mtk_wcn_stp_dbg_dump_package(); -+ -+ STP_SET_READY(stp_core_ctx, 0); -+ /*stp inband reset */ -+ if (stp_core_ctx.parser.type == STP_TASK_INDX && -+ stp_core_ctx.parser.seq == 0 && -+ stp_core_ctx.parser.ack == 0 && -+ stp_core_ctx.parser.length == 0 && stp_core_ctx.inband_rst_set == 1) { -+ STP_INFO_FUNC("Inband reset event get! Resync STP with firmware!\n\r"); -+ stp_rest_ctx_state(); -+ stp_change_rx_state(MTKSTP_RESYNC1); -+ stp_core_ctx.inband_rst_set = 0; -+ /* STP_INFO_FUNC("Restart STP Timer\n\r"); */ -+ /* (*sys_timer_start)(stp_core_ctx.tx_timer, -+ * mtkstp_tx_timeout, -+ * (MTK_WCN_TIMER_CB)stp_tx_timeout_handler, -+ * NULL); -+ */ -+ STP_TRACE_FUNC("--\n"); -+ return 0; -+ } -+ -+ /*f/w assert and exception information */ -+ if (stp_core_ctx.parser.length < stp_core_ctx.rx_counter) { -+ STP_ERR_FUNC("Abnormal length in STP_DATA phase 0x%x, 0x%x\n", -+ stp_core_ctx.parser.length, stp_core_ctx.rx_counter); -+ osal_assert(0); -+ } -+ -+ remain_length = stp_core_ctx.parser.length - stp_core_ctx.rx_counter; -+ if (i >= remain_length) { -+ osal_memcpy(stp_core_ctx.rx_buf + stp_core_ctx.rx_counter, p_data, -+ remain_length); -+ i -= remain_length; -+ p_data += remain_length; -+ stp_core_ctx.rx_counter = stp_core_ctx.parser.length; -+ stp_change_rx_state(MTKSTP_SYNC); -+ *(stp_core_ctx.rx_buf + stp_core_ctx.rx_counter) = '\0'; -+ /* STP_ERR_FUNC("%s [%d]\n", stp_core_ctx.rx_buf, stp_core_ctx.rx_counter); */ -+#if 0 -+ if ((stp_core_ctx.rx_counter == 1) && (stp_core_ctx.rx_buf[0] == 0xFF)) { -+ /* For MT6620, enable/disable coredump function is controlled by -+ * firmware for the moment, we need to set coredump enable flag -+ * to be 1 after see firmware send a pariticallar character(0xff) -+ * before any coredump packet is sent -+ */ -+ mtk_wcn_stp_coredump_flag_ctrl(1); -+ } -+#endif -+ /*Trace32 Dump */ -+ if (STP_IS_ENABLE_DBG(stp_core_ctx) && -+ (stp_core_ctx.parser.type == STP_TASK_INDX)) { -+ if (0 != stp_core_ctx.rx_counter) { -+ STP_SET_READY(stp_core_ctx, 0); -+ mtk_wcn_stp_ctx_save(); -+ STP_INFO_FUNC("++ start to read paged dump and paged trace ++\n"); -+ stp_btm_notify_wmt_dmp_wq(stp_core_ctx.btm); -+ stp_btm_notify_wmt_trace_wq(stp_core_ctx.btm); -+ STP_INFO_FUNC("++ start to read paged dump and paged trace --\n"); -+ -+ } -+ STP_INFO_FUNC("[len=%d][type=%d]\n%s\n", stp_core_ctx.rx_counter, -+ stp_core_ctx.parser.type, stp_core_ctx.rx_buf); -+ } -+ -+ /*Runtime FW Log */ -+ else if (STP_IS_ENABLE_DBG(stp_core_ctx) -+ && (stp_core_ctx.parser.type == INFO_TASK_INDX)) { -+ stp_dbg_log_pkt(g_mtkstp_dbg, STP_DBG_FW_LOG, STP_TASK_INDX, 5, 0, 0, 0, -+ (stp_core_ctx.rx_counter + 1), stp_core_ctx.rx_buf); -+ mtk_wcn_stp_dbg_dump_package(); -+ } -+ /*Normal mode: whole chip reset */ -+ else { -+ /*Aee Kernel Warning Message Shown First */ -+ /* (*sys_dbg_assert_aee)("[MT662x]f/w Assert", stp_core_ctx.rx_buf); */ -+ mtk_wcn_stp_coredump_start_ctrl(0); -+ mtk_wcn_stp_dbg_dump_package(); -+ -+ osal_dbg_assert_aee(stp_core_ctx.rx_buf, stp_core_ctx.rx_buf); -+ /*Whole Chip Reset Procedure Invoke */ -+ if (STP_IS_ENABLE_RST(stp_core_ctx)) { -+ STP_SET_READY(stp_core_ctx, 0); -+ stp_btm_notify_wmt_rst_wq(STP_BTM_CORE(stp_core_ctx)); -+ } else { -+ STP_INFO_FUNC -+ ("No to launch whole chip reset! for debugging purpose\n"); -+ } -+ } -+ /*discard CRC */ -+ if (i >= 2) { -+ STP_DBG_FUNC("crc discard.. i = %d\n", i); -+ i -= 2; -+ if (i > 0) -+ p_data += 2; -+ } -+ continue; -+ } else { /* only copy by data length */ -+ -+ /*fixed klocwork insight issue */ -+ if (i + stp_core_ctx.rx_counter >= MTKSTP_BUFFER_SIZE) { -+ STP_ERR_FUNC -+ ("Fail to handle Packet, maybe it doesn't follow STP protocol.\n"); -+ stp_change_rx_state(MTKSTP_RESYNC1); -+ stp_core_ctx.rx_counter = 0; -+ return -1; -+ } -+ osal_memcpy(stp_core_ctx.rx_buf + stp_core_ctx.rx_counter, p_data, i); -+ stp_core_ctx.rx_counter += i; /* all remain buffer are data */ -+ i = 0; -+ p_data += i; -+ continue; -+ } -+ -+ break; -+ default: -+ break; -+ } -+ p_data++; -+ i--; -+ } -+ -+ return 0; -+} -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_parser_data -+* DESCRIPTION -+* push data to serial transport protocol parser engine -+* PARAMETERS -+* buffer [IN] data buffer -+* length [IN] data buffer length -+* RETURNS -+* int 0 = success; -1 = crc/checksum error -+*****************************************************************************/ -+#if STP_EXP_HID_API_EXPORT -+int _mtk_wcn_stp_parser_data(UINT8 *buffer, UINT32 length) -+#else -+int mtk_wcn_stp_parser_data(UINT8 *buffer, UINT32 length) -+#endif -+{ -+ /*----------------------------------------------------------------*/ -+ /* Local Variables */ -+ /*----------------------------------------------------------------*/ -+ INT32 i; -+ UINT8 *p_data; -+ INT32 ret = 0; -+#ifdef DEBUG_DUMP_PACKET_HEAD -+ static UINT32 counter; -+ -+ STP_TRACE_FUNC("++, rx (cnt=%d,len=%d)\n", ++counter, length); -+#endif -+ -+#if 0 -+#ifdef CONFIG_POWER_SAVING_SUPPORT -+ if (stp_is_apply_powersaving()) { -+ /* If now chip is awake, to restart monitor! */ -+ if (!stp_psm_is_to_block_traffic(STP_PSM_CORE(stp_core_ctx))) { -+ STP_DBG_FUNC("To restart moinotr when rx\n\r"); -+ stp_psm_start_monitor(STP_PSM_CORE(stp_core_ctx)); -+ } -+ } -+#endif -+#endif -+ -+ /*----------------------------------------------------------------*/ -+ /* Code Body */ -+ /*----------------------------------------------------------------*/ -+ /* George FIXME: WHY or HOW can we reduct the locked region? */ -+ /*flags = (*sys_mutex_lock)(stp_core_ctx.stp_mutex); */ -+ i = length; -+ p_data = (UINT8 *) buffer; -+ -+/* stp_dump_data(buffer, "rx queue", length); */ -+ -+ /*STP is not enabled and only WMT can use Raw data path */ -+ if (STP_NOT_ENABLE(stp_core_ctx) && WMT_TASK_INDX == STP_PENDING_TYPE(stp_core_ctx)) { -+ /* route to task who send command */ -+ stp_add_to_rx_queue(buffer, length, STP_PENDING_TYPE(stp_core_ctx)); -+ -+ /* mike: notify corresponding subfunction of incoming data */ -+ (*sys_event_set) (STP_PENDING_TYPE(stp_core_ctx)); -+ } -+ /* STP over SDIO */ -+ else if ((mtk_wcn_stp_is_sdio_mode() || mtk_wcn_stp_is_btif_mand_mode()) && STP_IS_ENABLE(stp_core_ctx)) { -+#if !(REMOVE_USELESS_LOG) -+ if (gStpDbgLvl >= STP_LOG_DBG) -+ stp_dump_data(buffer, "sdio parser_in", length); -+#endif -+ /* STP_DBG_FUNC("sdio stp parser data length = %d\n", length); */ -+ ret = stp_parser_data_in_mand_mode(i, p_data); -+ } -+ /* STP over UART */ -+ else if (mtk_wcn_stp_is_btif_fullset_mode() && STP_IS_ENABLE(stp_core_ctx)) -+ ret = stp_parser_data_in_full_mode(i, p_data); -+ -+ /* George FIXME: WHY or HOW can we reduct the locked region? */ -+ /*(*sys_mutex_unlock)(stp_core_ctx.stp_mutex, flags); */ -+ STP_TRACE_FUNC("--\n"); -+ return ret; -+} -+#if !STP_EXP_HID_API_EXPORT -+EXPORT_SYMBOL(mtk_wcn_stp_parser_data); -+#endif -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_enable -+* DESCRIPTION -+* enable/disable STP -+* PARAMETERS -+* value [IN] 0=disable, others=enable -+* RETURNS -+* INT32 0=success, others=error -+*****************************************************************************/ -+INT32 mtk_wcn_stp_enable(INT32 value) -+{ -+ STP_DBG_FUNC("%s: set the current enable = (%d)\n", __func__, value); -+ -+ stp_rest_ctx_state(); -+ STP_SET_ENABLE(stp_core_ctx, value); -+ if (!value) { -+ mtk_wcn_stp_psm_reset(); -+ } else { -+/* g_block_tx = 0; */ -+ mtk_wcn_stp_coredump_start_ctrl(0); -+ } -+ return 0; -+} -+ -+INT32 mtk_wcn_stp_dbg_dump_package(VOID) -+{ -+ if (STP_NOT_ENABLE(stp_core_ctx)) { -+ STP_INFO_FUNC("STP dbg mode is off\n"); -+ -+ } else { -+ STP_INFO_FUNC("STP dbg mode is on\n"); -+ /* if (0 == g_block_tx) */ -+ if (0 == mtk_wcn_stp_coredump_start_get()) { -+ mtk_wcn_consys_stp_btif_logger_ctrl(BTIF_DUMP_LOG); -+ mtk_wcn_consys_stp_btif_logger_ctrl(BTIF_DUMP_BTIF_REG); -+ stp_dbg_dmp_printk(g_mtkstp_dbg); -+ } else { -+ STP_INFO_FUNC("assert start flag is set, disable packet dump function\n"); -+ } -+ } -+ return 0; -+} -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_ready -+* DESCRIPTION -+* ready/un-ready STP -+* PARAMETERS -+* value [IN] 0=un-ready, others=ready -+* RETURNS -+* INT32 0=success, others=error -+*****************************************************************************/ -+INT32 mtk_wcn_stp_ready(INT32 value) -+{ -+ STP_DBG_FUNC("set ready (%d)\n", value); -+ -+ STP_SET_READY(stp_core_ctx, value); -+ /*if whole chip reset, reset the debuggine mode */ -+#ifndef CONFIG_LOG_STP_INTERNAL -+ /* mtk_wcn_stp_dbg_disable(); */ -+#endif -+ -+ if (stp_is_apply_powersaving()) { -+ STP_INFO_FUNC("Restart the stp-psm monitor !!\n"); -+ stp_psm_disable(STP_PSM_CORE(stp_core_ctx)); -+ } -+ -+ return 0; -+} -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_coredump_start_ctrl -+* DESCRIPTION -+* set f/w assert flag in STP context -+* PARAMETERS -+* value [IN] 0=assert end, others=assert begins -+* RETURNS -+* INT32 0=success, others=error -+*****************************************************************************/ -+INT32 mtk_wcn_stp_coredump_start_ctrl(UINT32 value) -+{ -+ STP_DBG_FUNC("set f/w assert (%d)\n", value); -+ -+ STP_SET_FW_COREDUMP_FLAG(stp_core_ctx, value); -+ -+ return 0; -+} -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_coredump_start_get -+* DESCRIPTION -+* get f/w assert flag in STP context -+* PARAMETERS -+* VOID -+* RETURNS -+* INT32 0= f/w assert flag is not set, others=f/w assert flag is set -+*****************************************************************************/ -+#if STP_EXP_HID_API_EXPORT -+INT32 _mtk_wcn_stp_coredump_start_get(VOID) -+#else -+INT32 mtk_wcn_stp_coredump_start_get(VOID) -+#endif -+{ -+ return STP_FW_COREDUMP_FLAG(stp_core_ctx); -+} -+ -+/* mtk_wcn_stp_set_wmt_last_close -- set the state of link(UART or SDIO) -+ * @ value - 1, link already be closed; 0, link is open -+ * -+ * Return 0 if success; else error code -+ */ -+INT32 mtk_wcn_stp_set_wmt_last_close(UINT32 value) -+{ -+ STP_INFO_FUNC("set wmt_last_close flag (%d)\n", value); -+ -+ STP_SET_WMT_LAST_CLOSE(stp_core_ctx, value); -+ -+ return 0; -+} -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_send_data -+* DESCRIPTION -+* subfunction send data through STP -+* PARAMETERS -+* buffer [IN] data buffer -+* length [IN] data buffer length -+* type [IN] subfunction type -+* RETURNS -+* INT32 > 0: length transmitted; = 0: error -+*****************************************************************************/ -+#if STP_EXP_HID_API_EXPORT -+INT32 _mtk_wcn_stp_send_data(const PUINT8 buffer, const UINT32 length, const UINT8 type) -+#else -+INT32 mtk_wcn_stp_send_data(const PUINT8 buffer, const UINT32 length, const UINT8 type) -+#endif -+{ -+ UINT8 mtkstp_header[MTKSTP_HEADER_SIZE], temp[2]; -+ UINT8 *p_tx_buf = NULL; -+ UINT16 crc; -+ INT32 ret = 0; -+ MTK_WCN_BOOL is_quick_enable = MTK_WCN_BOOL_TRUE; -+ -+ /* osal_buffer_dump(buffer,"tx", length, 32); */ -+ -+ if (0 != STP_WMT_LAST_CLOSE(stp_core_ctx)) { -+ STP_ERR_FUNC("WMT lats close,should not have tx request!\n"); -+ return length; -+ } -+ /* if(g_block_tx) */ -+ if (0 != mtk_wcn_stp_coredump_start_get()) { -+ STP_ERR_FUNC("STP fw coredump start flag set...\n"); -+ return length; -+ } -+#ifdef CONFIG_POWER_SAVING_SUPPORT -+ is_quick_enable = stp_psm_is_quick_ps_support(); -+ STP_DBG_FUNC("is quick sleep enable:%s\n", is_quick_enable ? "yes" : "no"); -+ if (MTK_WCN_BOOL_TRUE == is_quick_enable) { -+ if (type != WMT_TASK_INDX) { -+#if PSM_USE_COUNT_PACKAGE -+ stp_psm_disable_by_tx_rx_density(STP_PSM_CORE(stp_core_ctx), 0); -+#else -+ stp_psm_disable_by_tx_rx_density(STP_PSM_CORE(stp_core_ctx), 0, length); -+#endif -+ } -+ /* if(stp_is_apply_powersaving()) */ -+ { -+ if (type == WMT_TASK_INDX) -+ goto DONT_MONITOR; -+ /*-----------------------------STP_PSM_Lock----------------------------------------*/ -+ ret = stp_psm_thread_lock_aquire(STP_PSM_CORE(stp_core_ctx)); -+ if (ret) { -+ STP_ERR_FUNC("--->lock psm_thread_lock failed ret=%d\n", ret); -+ return ret; -+ } -+ -+ if (!stp_psm_is_to_block_traffic(STP_PSM_CORE(stp_core_ctx))) { -+ if (stp_psm_has_pending_data(STP_PSM_CORE(stp_core_ctx))) { -+ STP_WARN_FUNC("***** Release psm hold data before send normal data *****\n"); -+ stp_psm_release_data(STP_PSM_CORE(stp_core_ctx)); -+ } -+ } else { -+ ret = stp_psm_hold_data(STP_PSM_CORE(stp_core_ctx), buffer, length, type); -+ stp_psm_notify_wmt_wakeup(STP_PSM_CORE(stp_core_ctx)); -+ /*-----------------------------STP_PSM_UnLock----------------------------------------*/ -+ stp_psm_thread_lock_release(STP_PSM_CORE(stp_core_ctx)); -+ return ret; -+ } -+ } -+ } else { -+ /* if(stp_is_apply_powersaving()) */ -+ { -+ if (type == WMT_TASK_INDX) -+ goto DONT_MONITOR; -+ /* If now chip is awake, to restart monitor! */ -+ /* STP_INFO_FUNC("check if block traffic !!\n"); */ -+ /*-----------------------------STP_PSM_Lock----------------------------------------*/ -+ ret = stp_psm_thread_lock_aquire(STP_PSM_CORE(stp_core_ctx)); -+ if (ret) { -+ STP_ERR_FUNC("--->lock psm_thread_lock failed ret=%d\n", ret); -+ return ret; -+ } -+ -+ if (!stp_psm_is_to_block_traffic(STP_PSM_CORE(stp_core_ctx))) { -+ /* STP_INFO_FUNC("not to block !!\n"); */ -+ if (stp_psm_has_pending_data(STP_PSM_CORE(stp_core_ctx))) { -+ STP_WARN_FUNC("***** Release psm hold data before send normal data *****\n"); -+ stp_psm_release_data(STP_PSM_CORE(stp_core_ctx)); -+ } -+ stp_psm_start_monitor(STP_PSM_CORE(stp_core_ctx)); -+ } else { -+ /* STP_INFO_FUNC("to block !!\n"); */ -+ -+ /* STP_INFO_FUNC("*****hold data in psm queue data length = %d\n", -+ * length); -+ */ -+ /* stp_dump_data(buffer, "Hold in psm queue", length); */ -+ /* hold datas */ -+ ret = stp_psm_hold_data(STP_PSM_CORE(stp_core_ctx), buffer, length, type); -+ /* wmt notification */ -+ STP_INFO_FUNC("#####Type = %d, to inform WMT to wakeup chip, ret = %d:0x%2x,0x%2x\n", -+ type, ret, *buffer, *(buffer + 1)); -+ stp_psm_notify_wmt_wakeup(STP_PSM_CORE(stp_core_ctx)); -+ /* STP_INFO_FUNC("*********Type = %d, to inform WMT to wakeup chip>end\n", type); */ -+ /*-----------------------------STP_PSM_UnLock----------------------------------------*/ -+ stp_psm_thread_lock_release(STP_PSM_CORE(stp_core_ctx)); -+ return ret; -+ } -+ } -+ } -+DONT_MONITOR: -+#endif -+ if (type == BT_TASK_INDX) { -+ static const UINT8 rst_buf[4] = { 0x01, 0x03, 0x0c, 0x00 }; -+ -+ if (!osal_strncmp(buffer, rst_buf, 4)) -+ osal_printtimeofday("############ BT Rest start -->"); -+ } -+ /* osal_lock_unsleepable_lock(&stp_core_ctx.stp_mutex); */ -+ stp_ctx_lock(&stp_core_ctx); -+ /*Only WMT can set raw data */ -+ if (STP_NOT_ENABLE(stp_core_ctx) && WMT_TASK_INDX != type) { -+ /* no-op */ -+ /* NULL; */ -+ } else if (STP_NOT_ENABLE(stp_core_ctx) && WMT_TASK_INDX == type) { -+ /* ret = mtk_wcn_stp_send_data_raw(buffer, length, type); */ -+ /* NULL; */ -+ } -+ /* STP over SDIO */ -+ else if ((mtk_wcn_stp_is_sdio_mode() || mtk_wcn_stp_is_btif_mand_mode()) && STP_IS_ENABLE(stp_core_ctx)) { -+ -+ /* osal_printtimeofday("[ STP][SDIO][ B][W]"); */ -+ -+ mtkstp_header[0] = 0x80; -+ mtkstp_header[1] = (type << 4) + (((length) >> 8) & 0x0f); -+ mtkstp_header[2] = (length) & 0xff; -+ mtkstp_header[3] = 0x00; -+ -+ /* HEADER */ -+ p_tx_buf = &stp_core_ctx.tx_buf[0]; -+ osal_memcpy(p_tx_buf, mtkstp_header, MTKSTP_HEADER_SIZE); -+ p_tx_buf += MTKSTP_HEADER_SIZE; -+ -+ /* PAYLOAD */ -+ osal_memcpy(p_tx_buf, buffer, length); -+ p_tx_buf += length; -+ -+ /* CRC */ -+ temp[0] = 0x00; -+ temp[1] = 0x00; -+ osal_memcpy(p_tx_buf, temp, 2); -+ stp_dbg_pkt_log(type, 0, 0, 0, PKT_DIR_TX, buffer, length); -+ (*sys_if_tx) (&stp_core_ctx.tx_buf[0], (MTKSTP_HEADER_SIZE + length + 2), &ret); -+ -+ if ((MTKSTP_HEADER_SIZE + length + 2) != ret) { -+ STP_ERR_FUNC("stp send tx packet: %d, maybe stp_if_tx == NULL\n", ret); -+ osal_assert(0); -+ ret = 0; -+ } else { -+ ret = (INT32) length; -+ } -+ -+ /* osal_printtimeofday("[ STP][SDIO][ E][W]"); */ -+ } -+ /* STP over UART */ -+ else if (mtk_wcn_stp_is_btif_fullset_mode() && STP_IS_ENABLE(stp_core_ctx)) { -+ -+ /* osal_printtimeofday("[ STP][UART][ B][W]"); */ -+ /* STP_INFO_FUNC("Write byte %d\n", length); */ -+ -+ if ((stp_core_ctx.sequence.winspace > 0) && -+ (stp_core_ctx.inband_rst_set == 0) && -+ (stp_is_tx_res_available(MTKSTP_HEADER_SIZE + length + MTKSTP_CRC_SIZE))) { -+ /*Make Header */ -+ /* (*sys_dbg_print)("mtk_wcn_stp_send_data 1, txseq = %d, winspace = %d", -+ * stp_core_ctx.sequence.txseq, stp_core_ctx.sequence.winspace); -+ */ -+ mtkstp_header[0] = 0x80 + (stp_core_ctx.sequence.txseq << 3) + stp_core_ctx.sequence.txack; -+ mtkstp_header[1] = (type << 4) + ((length & 0xf00) >> 8); -+ mtkstp_header[2] = length & 0xff; -+ mtkstp_header[3] = (mtkstp_header[0] + mtkstp_header[1] + mtkstp_header[2]) & 0xff; -+ stp_core_ctx.tx_start_addr[stp_core_ctx.sequence.txseq] = stp_core_ctx.tx_write; -+ stp_core_ctx.tx_length[stp_core_ctx.sequence.txseq] = MTKSTP_HEADER_SIZE + length + 2; -+ if (fgEnableDelimiter == 1) { -+ stp_core_ctx.tx_length[stp_core_ctx.sequence.txseq] += STP_DEL_SIZE; -+ stp_add_to_tx_queue(&stp_delimiter[0], STP_DEL_SIZE); -+ } -+ stp_add_to_tx_queue(mtkstp_header, MTKSTP_HEADER_SIZE); -+ -+ /*Make Payload */ -+ stp_add_to_tx_queue(buffer, length); -+ -+ /*Make CRC */ -+ crc = osal_crc16(buffer, length); -+ temp[0] = crc & 0xff; -+ temp[1] = (crc & 0xff00) >> 8; -+ stp_add_to_tx_queue(temp, 2); -+ stp_dbg_pkt_log(type, -+ stp_core_ctx.sequence.txack, -+ stp_core_ctx.sequence.txseq, crc, PKT_DIR_TX, buffer, length); -+ -+ /*Kick to UART */ -+ stp_send_tx_queue(stp_core_ctx.sequence.txseq); -+ -+ INDEX_INC(stp_core_ctx.sequence.txseq); -+ stp_core_ctx.sequence.winspace--; -+ -+ /*Setup the Retry Timer */ -+ osal_timer_stop(&stp_core_ctx.tx_timer); -+ if (stp_core_ctx.sequence.winspace != MTKSTP_WINSIZE) -+ osal_timer_start(&stp_core_ctx.tx_timer, mtkstp_tx_timeout); -+ else -+ STP_ERR_FUNC("mtk_wcn_stp_send_data: wmt_stop_timer\n"); -+ -+ ret = (INT32) length; -+ } else { -+ /* -+ No winspace to send. Let caller retry -+ */ -+ if (stp_core_ctx.inband_rst_set == 1) -+ STP_WARN_FUNC("Now it's inband reset process and drop sent packet.\n"); -+ else -+ STP_ERR_FUNC("There is no winspace/txqueue to send !!!\n"); -+ -+ ret = 0; -+ } -+ -+ /* osal_printtimeofday("[ STP][UART][ E][W]"); */ -+ } -+ /* osal_unlock_unsleepable_lock(&stp_core_ctx.stp_mutex); */ -+ stp_ctx_unlock(&stp_core_ctx); -+ -+#ifdef CONFIG_POWER_SAVING_SUPPORT -+ -+ if (MTK_WCN_BOOL_TRUE == is_quick_enable) { -+ if (type != WMT_TASK_INDX) { -+ stp_psm_notify_wmt_sleep(STP_PSM_CORE(stp_core_ctx)); -+ /*-----------------------STP_PSM_UnLock-------------------------*/ -+ stp_psm_thread_lock_release(STP_PSM_CORE(stp_core_ctx)); -+ } -+ } else { -+ /* if(stp_is_apply_powersaving()) */ -+ /* { */ -+ if (type != WMT_TASK_INDX) { -+ -+ /*--------------------STP_PSM_UnLock--------------------------*/ -+ stp_psm_thread_lock_release(STP_PSM_CORE(stp_core_ctx)); -+ } -+ /* } */ -+ } -+#endif -+ -+ return ret; -+} -+#if !STP_EXP_HID_API_EXPORT -+EXPORT_SYMBOL(mtk_wcn_stp_send_data); -+#endif -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_send_data_raw -+* DESCRIPTION -+* send raw data to common interface, bypass STP -+* PARAMETERS -+* buffer [IN] data buffer -+* length [IN] data buffer length -+* type [IN] subfunction type -+* RETURNS -+* INT32 >= 0: length transmitted; < 0: error -+*****************************************************************************/ -+#if STP_EXP_HID_API_EXPORT -+INT32 _mtk_wcn_stp_send_data_raw(const PUINT8 buffer, const UINT32 length, const UINT8 type) -+#else -+INT32 mtk_wcn_stp_send_data_raw(const PUINT8 buffer, const UINT32 length, const UINT8 type) -+#endif -+{ -+ UINT32 written = 0; -+ INT32 ret = 0; -+ -+ if (0 != STP_WMT_LAST_CLOSE(stp_core_ctx)) { -+ STP_ERR_FUNC("WMT lats close,should not have tx request!"); -+ return length; -+ } -+ -+ STP_DBG_FUNC("mtk_wcn_stp_send_data_raw, type = %d, data = %x %x %x %x %x %x ", type, buffer[0], buffer[1], -+ buffer[2], buffer[3], buffer[4], buffer[5]); -+ STP_SET_PENDING_TYPE(stp_core_ctx, type); /* remember tx type, forward following rx to this type */ -+ -+ /* osal_lock_unsleepable_lock(&stp_core_ctx.stp_mutex); */ -+ stp_ctx_lock(&stp_core_ctx); -+ stp_dbg_pkt_log(type, 0, 0, 0, PKT_DIR_TX, buffer, 1); -+ (*sys_if_tx) (&buffer[0], length, &written); -+ /* osal_unlock_unsleepable_lock(&stp_core_ctx.stp_mutex); */ -+ stp_ctx_unlock(&stp_core_ctx); -+ -+ if (written == 0) -+ stp_dump_data(&buffer[0], "tx raw failed:", length); -+ -+ if (written == length) -+ ret = (INT32) written; -+ else -+ ret = (-1); -+ -+ return ret; -+} -+#if !STP_EXP_HID_API_EXPORT -+EXPORT_SYMBOL(mtk_wcn_stp_send_data_raw); -+#endif -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_receive_data -+* DESCRIPTION -+* receive data from serial protocol engine -+* PARAMETERS -+* buffer [IN] data buffer -+* length [IN] data buffer length -+* type [IN] subfunction type -+* RETURNS -+* INT32 >= 0: size of data received; < 0: error -+*****************************************************************************/ -+#if STP_EXP_HID_API_EXPORT -+INT32 _mtk_wcn_stp_receive_data(UINT8 *buffer, UINT32 length, UINT8 type) -+#else -+INT32 mtk_wcn_stp_receive_data(UINT8 *buffer, UINT32 length, UINT8 type) -+#endif -+{ -+ /* GeorgeKuo modify: reduce "if" branch */ -+ UINT16 copyLen = 0; -+ UINT16 tailLen = 0; -+ -+ osal_lock_unsleepable_lock(&stp_core_ctx.ring[type].mtx); -+ -+ while (stp_core_ctx.ring[type].read_p != stp_core_ctx.ring[type].write_p) { -+ /* GeorgeKuo modify: reduce if branch */ -+ if (stp_core_ctx.ring[type].write_p > stp_core_ctx.ring[type].read_p) { -+ copyLen = stp_core_ctx.ring[type].write_p - stp_core_ctx.ring[type].read_p; -+ if (copyLen > length) -+ copyLen = length; -+ -+ osal_memcpy(buffer, stp_core_ctx.ring[type].buffer + stp_core_ctx.ring[type].read_p, copyLen); -+ stp_core_ctx.ring[type].read_p += copyLen; -+ } else { -+ tailLen = MTKSTP_BUFFER_SIZE - stp_core_ctx.ring[type].read_p; -+ if (tailLen > length) { /* exclude equal case to skip wrap check */ -+ copyLen = length; -+ osal_memcpy(buffer, stp_core_ctx.ring[type].buffer + stp_core_ctx.ring[type].read_p, -+ copyLen); -+ stp_core_ctx.ring[type].read_p += copyLen; -+ } else { -+ /* part 1: copy tailLen */ -+ osal_memcpy(buffer, stp_core_ctx.ring[type].buffer + stp_core_ctx.ring[type].read_p, -+ tailLen); -+ -+ buffer += tailLen; /* update buffer offset */ -+ -+ /* part 2: check if head length is enough */ -+ copyLen = length - tailLen; -+ copyLen = -+ (stp_core_ctx.ring[type].write_p < -+ copyLen) ? stp_core_ctx.ring[type].write_p : copyLen; -+ -+ if (copyLen) -+ osal_memcpy(buffer, stp_core_ctx.ring[type].buffer + 0, copyLen); -+ -+ /* Update read_p final position */ -+ stp_core_ctx.ring[type].read_p = copyLen; -+ -+ /* update return length: head + tail */ -+ copyLen += tailLen; -+ } -+ } -+ break; -+ } -+ -+ osal_unlock_unsleepable_lock(&stp_core_ctx.ring[type].mtx); -+ -+ if ((MTK_WCN_BOOL_TRUE == stp_psm_is_quick_ps_support()) && (type != WMT_TASK_INDX)) { -+#if PSM_USE_COUNT_PACKAGE -+ stp_psm_disable_by_tx_rx_density(STP_PSM_CORE(stp_core_ctx), 1); -+#else -+ stp_psm_disable_by_tx_rx_density(STP_PSM_CORE(stp_core_ctx), 1, copyLen); -+#endif -+ } -+ -+ return copyLen; -+} -+#if !STP_EXP_HID_API_EXPORT -+EXPORT_SYMBOL(mtk_wcn_stp_receive_data); -+#endif -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_is_rxqueue_empty -+* DESCRIPTION -+* Is certain rx queue empty? -+* PARAMETERS -+* type [IN] subfunction type -+* RETURNS -+* INT32 0: queue is NOT empyt; !0: queue is empty -+*****************************************************************************/ -+#if STP_EXP_HID_API_EXPORT -+INT32 _mtk_wcn_stp_is_rxqueue_empty(UINT8 type) -+#else -+INT32 mtk_wcn_stp_is_rxqueue_empty(UINT8 type) -+#endif -+{ -+ INT32 ret; -+ -+ osal_lock_unsleepable_lock(&stp_core_ctx.ring[type].mtx); -+ -+ if (stp_core_ctx.ring[type].read_p == stp_core_ctx.ring[type].write_p) -+ ret = 1; /* queue is empty */ -+ else -+ ret = 0; /* queue is not empty */ -+ -+ osal_unlock_unsleepable_lock(&stp_core_ctx.ring[type].mtx); -+ -+ return ret; -+} -+#if !STP_EXP_HID_API_EXPORT -+EXPORT_SYMBOL(mtk_wcn_stp_is_rxqueue_empty); -+#endif -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_set_sdio_mode -+* DESCRIPTION -+* Set stp for SDIO mode -+* PARAMETERS -+* sdio_flag [IN] sdio mode flag (TRUE:SDIO mode, FALSE:UART mode) -+* RETURNS -+* void -+*****************************************************************************/ -+ -+void mtk_wcn_stp_set_mode(UINT32 mode) -+{ -+ STP_SET_SUPPORT_PROTOCOL(stp_core_ctx, mode); -+ -+ STP_DBG_FUNC("STP_SUPPORT_PROTOCOL = %08x\n", STP_SUPPORT_PROTOCOL(stp_core_ctx)); -+} -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_is_uart_fullset_mode -+* DESCRIPTION -+* Is stp use UART fullset mode? -+* PARAMETERS -+* none. -+* RETURNS -+* MTK_WCN_BOOL TRUE:Uart Fullset mode, FALSE:Not UART Fullset mode -+*****************************************************************************/ -+MTK_WCN_BOOL mtk_wcn_stp_is_uart_fullset_mode(void) -+{ -+ /* -+ bit 0: uart fullset mode -+ bit 1: uart mandatory mode -+ bit 2: sdio mode -+ */ -+ if (STP_SUPPORT_PROTOCOL(stp_core_ctx) & MTKSTP_UART_FULL_MODE) -+ return MTK_WCN_BOOL_TRUE; -+ else -+ return MTK_WCN_BOOL_FALSE; -+} -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_is_uart_mand_mode -+* DESCRIPTION -+* Is stp use UART mandatory mode? -+* PARAMETERS -+* none. -+* RETURNS -+* MTK_WCN_BOOL TRUE:Uart Mandatory mode, FALSE:Not UART Mandotary mode -+*****************************************************************************/ -+MTK_WCN_BOOL mtk_wcn_stp_is_uart_mand_mode(void) -+{ -+ /* -+ bit 0: uart fullset mode -+ bit 1: uart mandatory mode -+ bit 2: sdio mode -+ */ -+ if (STP_SUPPORT_PROTOCOL(stp_core_ctx) & MTKSTP_UART_MAND_MODE) -+ return MTK_WCN_BOOL_TRUE; -+ else -+ return MTK_WCN_BOOL_FALSE; -+} -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_is_btif_fullset_mode -+* DESCRIPTION -+* Is stp use BTIF fullset mode? -+* PARAMETERS -+* none. -+* RETURNS -+* MTK_WCN_BOOL TRUE:BTIF Fullset mode, FALSE:Not BTIF Fullset mode -+*****************************************************************************/ -+MTK_WCN_BOOL mtk_wcn_stp_is_btif_fullset_mode(void) -+{ -+ -+ if (STP_SUPPORT_PROTOCOL(stp_core_ctx) & MTKSTP_BTIF_FULL_MODE) -+ return MTK_WCN_BOOL_TRUE; -+ else -+ return MTK_WCN_BOOL_FALSE; -+} -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_is_btif_mand_mode -+* DESCRIPTION -+* Is stp use BTIF mandatory mode? -+* PARAMETERS -+* none. -+* RETURNS -+* MTK_WCN_BOOL TRUE:BTIF Mandatory mode, FALSE:Not BTIF Mandotary mode -+*****************************************************************************/ -+ -+MTK_WCN_BOOL mtk_wcn_stp_is_btif_mand_mode(void) -+{ -+ -+ if (STP_SUPPORT_PROTOCOL(stp_core_ctx) & MTKSTP_BTIF_MAND_MODE) -+ return MTK_WCN_BOOL_TRUE; -+ else -+ return MTK_WCN_BOOL_FALSE; -+} -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_is_sdio_mode -+* DESCRIPTION -+* Is stp use SDIO mode? -+* PARAMETERS -+* none. -+* RETURNS -+* MTK_WCN_BOOL TRUE:SDIO mode, FALSE:UART mode -+*****************************************************************************/ -+MTK_WCN_BOOL mtk_wcn_stp_is_sdio_mode(void) -+{ -+ /* -+ bit 0: uart fullset mode -+ bit 1: uart mandatory mode -+ bit 2: sdio mode -+ */ -+ if (STP_SUPPORT_PROTOCOL(stp_core_ctx) & MTKSTP_SDIO_MODE) -+ return MTK_WCN_BOOL_TRUE; -+ else -+ return MTK_WCN_BOOL_FALSE; -+} -+ -+/***************************************************************************** -+* FUNCTION -+* stp_send_inband_reset -+* DESCRIPTION -+* To sync to oringnal stp state with f/w stp -+* PARAMETERS -+* none. -+* RETURNS -+* none -+*****************************************************************************/ -+void mtk_wcn_stp_inband_reset(void) -+{ -+ UINT8 inband_reset_packet[64]; -+ UINT32 txseq = 0; -+ UINT32 txack = 0; -+ UINT32 crc = 0; -+ UINT32 ret = 0; -+ UINT32 reset_payload_len = 0; -+ -+ /*512 bytes */ -+ UINT8 reset_payload[] = { -+ 0xc0, 0x01, 0xc0, 0xde, 0x3e, 0xd1, 0xa7, 0xef -+ }; -+ -+ /* osal_lock_unsleepable_lock(&stp_core_ctx.stp_mutex); */ -+ stp_ctx_lock(&stp_core_ctx); -+ -+ /*RESYNC*/ inband_reset_packet[0] = 0x7f; -+ inband_reset_packet[1] = 0x7f; -+ inband_reset_packet[2] = 0x7f; -+ inband_reset_packet[3] = 0x7f; -+ inband_reset_packet[4] = 0x7f; -+ inband_reset_packet[5] = 0x7f; -+ inband_reset_packet[6] = 0x7f; -+ inband_reset_packet[7] = 0x7f; -+ -+ /*header */ -+ reset_payload_len = sizeof(reset_payload) / sizeof(reset_payload[0]); -+ inband_reset_packet[8] = 0x80 + (txseq << 3) + txack; -+ inband_reset_packet[9] = (STP_TASK_INDX << 4) + ((reset_payload_len & 0xf00) >> 8); -+ inband_reset_packet[10] = reset_payload_len & 0xff; -+ inband_reset_packet[11] = (inband_reset_packet[8] + inband_reset_packet[9] + inband_reset_packet[10]) & 0xff; -+ -+ /*payload */ -+ osal_memcpy(&inband_reset_packet[12], reset_payload, reset_payload_len); -+ -+ /*crc */ -+ crc = osal_crc16(&reset_payload[0], reset_payload_len); -+ inband_reset_packet[12 + reset_payload_len] = crc & 0xff; -+ inband_reset_packet[12 + reset_payload_len + 1] = (crc & 0xff00) >> 8; -+ -+ (*sys_if_tx) (&inband_reset_packet[0], 14 + reset_payload_len, &ret); -+ -+ if (ret != (14 + reset_payload_len)) -+ STP_ERR_FUNC("Inband sending error, sending %d , but ret = %d\n", 10 + reset_payload_len, ret); -+ -+ stp_core_ctx.inband_rst_set = 1; -+ stp_ctx_unlock(&stp_core_ctx); -+ /* osal_unlock_unsleepable_lock(&stp_core_ctx.stp_mutex); */ -+} -+ -+void mtk_wcn_stp_debug_ctrl(INT32 op, INT32 filter, INT32 filter_param) -+{ -+ /*nothing at now*/ -+} -+ -+void mtk_wcn_stp_test_cmd(INT32 cmd_no) -+{ -+ UINT8 test_packet[64]; -+ UINT32 txseq = 0; -+ UINT32 txack = 0; -+ UINT32 crc = 0; -+ UINT32 ret = 0; -+ UINT32 reset_payload_len = 0; -+ -+ UINT8 test_payload[] = { -+ 0xAA, 0xAA, 0xC0, 0xDE, 0x3E, 0xD1, 0xA7, 0xEF -+ }; -+/* */ -+/* select your test command by cmd_no */ -+/* */ -+ if (cmd_no == 0) { -+ /* to test new command to chip */ -+ /* osal_lock_unsleepable_lock(&stp_core_ctx.stp_mutex); */ -+ stp_ctx_lock(&stp_core_ctx); -+ -+ /*RESYNC*/ test_packet[0] = 0x7f; -+ test_packet[1] = 0x7f; -+ test_packet[2] = 0x7f; -+ test_packet[3] = 0x7f; -+ test_packet[4] = 0x7f; -+ test_packet[5] = 0x7f; -+ test_packet[6] = 0x7f; -+ test_packet[7] = 0x7f; -+ -+ /*header */ -+ reset_payload_len = sizeof(test_payload) / sizeof(test_payload[0]); -+ test_packet[8] = 0x80 + (txseq << 3) + txack; -+ test_packet[9] = (STP_TASK_INDX << 4) + ((reset_payload_len & 0xf00) >> 8); -+ test_packet[10] = reset_payload_len & 0xff; -+ test_packet[11] = (test_packet[8] + test_packet[9] + test_packet[10]) & 0xff; -+ -+ /*payload */ -+ osal_memcpy(&test_packet[12], test_payload, reset_payload_len); -+ -+ /*crc */ -+ crc = osal_crc16(&test_payload[0], reset_payload_len); -+ test_packet[12 + reset_payload_len] = crc & 0xff; -+ test_packet[12 + reset_payload_len + 1] = (crc & 0xff00) >> 8; -+ -+ (*sys_if_tx) (&test_packet[0], 14 + reset_payload_len, &ret); -+ if (ret != (14 + reset_payload_len)) { -+ STP_ERR_FUNC("stp test sending error, sending %d , but ret = %d\n", 10 + reset_payload_len, -+ ret); -+ } -+ /* osal_unlock_unsleepable_lock(&stp_core_ctx.stp_mutex); */ -+ stp_ctx_unlock(&stp_core_ctx); -+ } -+ -+} -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_flush_context -+* DESCRIPTION -+* Flush STP Context -+* PARAMETERS -+* none. -+* RETURNS -+* none -+*****************************************************************************/ -+void mtk_wcn_stp_flush_context(void) -+{ -+ stp_rest_ctx_state(); -+} -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_flush_rx_queue -+* DESCRIPTION -+* Flush STP Rx Queue -+* PARAMETERS -+* none. -+* RETURNS -+* none -+*****************************************************************************/ -+ -+void mtk_wcn_stp_flush_rx_queue(UINT32 type) -+{ -+ osal_lock_unsleepable_lock(&stp_core_ctx.ring[type].mtx); -+ if (type < MTKSTP_MAX_TASK_NUM) { -+ stp_core_ctx.ring[type].read_p = 0; -+ stp_core_ctx.ring[type].write_p = 0; -+ } -+ osal_unlock_unsleepable_lock(&stp_core_ctx.ring[type].mtx); -+} -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_is_enable -+* DESCRIPTION -+* STP is ready? -+* PARAMETERS -+* none. -+* RETURNS -+* none -+*****************************************************************************/ -+#if STP_EXP_HID_API_EXPORT -+MTK_WCN_BOOL _mtk_wcn_stp_is_ready(void) -+#else -+MTK_WCN_BOOL mtk_wcn_stp_is_ready(void) -+#endif -+{ -+ return STP_IS_READY(stp_core_ctx); -+} -+#if !STP_EXP_HID_API_EXPORT -+EXPORT_SYMBOL(mtk_wcn_stp_is_ready); -+#endif -+/***************************************************************************** -+* FUNCTION -+* set_bluetooth_rx_interface -+* DESCRIPTION -+* Set bluetooth rx interface -+* PARAMETERS -+* rx interface type -+* RETURNS -+* void -+*****************************************************************************/ -+#if STP_EXP_HID_API_EXPORT -+void _mtk_wcn_stp_set_bluez(MTK_WCN_BOOL bluez_flag) -+#else -+void mtk_wcn_stp_set_bluez(MTK_WCN_BOOL bluez_flag) -+#endif -+{ -+ /* g_mtkstp_bluez_flag = bluez_flag; */ -+ STP_SET_BT_STK(stp_core_ctx, bluez_flag); -+} -+#if !STP_EXP_HID_API_EXPORT -+EXPORT_SYMBOL(mtk_wcn_stp_set_bluez); -+#endif -+/***************************************************************************** -+* FUNCTION -+* set stp debugging mdoe -+* DESCRIPTION -+* set stp debugging mdoe -+* PARAMETERS -+* dbg_mode: switch to dbg mode ? -+* RETURNS -+* void -+*****************************************************************************/ -+void mtk_wcn_stp_set_dbg_mode(MTK_WCN_BOOL dbg_mode) -+{ -+ STP_SET_ENABLE_DBG(stp_core_ctx, dbg_mode); -+} -+ -+/***************************************************************************** -+* FUNCTION -+* set stp auto reset mdoe -+* DESCRIPTION -+* set stp auto reset mdoe -+* PARAMETERS -+* auto_rst: switch to auto reset mode ? -+* RETURNS -+* void -+*****************************************************************************/ -+void mtk_wcn_stp_set_auto_rst(MTK_WCN_BOOL auto_rst) -+{ -+ STP_SET_ENABLE_RST(stp_core_ctx, auto_rst); -+} -+ -+INT32 mtk_wcn_stp_notify_sleep_for_thermal(void) -+{ -+ return stp_psm_sleep_for_thermal(STP_PSM_CORE(stp_core_ctx)); -+} -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_open_btif -+* DESCRIPTION -+* init btif hw & sw by owner stp -+* PARAMETERS -+* VOID -+* RETURNS -+* INT32 0-success,other fail. -+*****************************************************************************/ -+INT32 mtk_wcn_stp_open_btif(VOID) -+{ -+ return mtk_wcn_consys_stp_btif_open(); -+} -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_open_close -+* DESCRIPTION -+* close btif hw & sw by owner stp -+* PARAMETERS -+* VOID -+* RETURNS -+* INT32 0-success,other fail. -+*****************************************************************************/ -+INT32 mtk_wcn_stp_close_btif(VOID) -+{ -+ return mtk_wcn_consys_stp_btif_close(); -+} -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_rx_cb_register -+* DESCRIPTION -+* register stp rx cb to btif -+* PARAMETERS -+* MTK_WCN_BTIF_RX_CB stp rx handle function -+* RETURNS -+* INT32 0-success,other fail. -+*****************************************************************************/ -+INT32 mtk_wcn_stp_rxcb_register(MTK_WCN_BTIF_RX_CB rx_cb) -+{ -+ return mtk_wcn_consys_stp_btif_rx_cb_register(rx_cb); -+} -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_tx -+* DESCRIPTION -+* send stp package by btif -+* PARAMETERS -+* pBuf:package buffer pointer,len:package length -+* written_len:package written length -+* RETURNS -+* INT32 package length-success,other fail. -+*****************************************************************************/ -+INT32 mtk_wcn_stp_tx(UINT8 *pBuf, UINT32 len, UINT32 *written_len) -+{ -+ INT32 iRet = -1; -+ -+ iRet = mtk_wcn_consys_stp_btif_tx(pBuf, len, written_len); -+ return iRet; -+} -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_wakeup_consys -+* DESCRIPTION -+* STP wakeup consys by btif -+* PARAMETERS -+* VOID -+* RETURNS -+* INT32 0-success,other fail. -+*****************************************************************************/ -+INT32 mtk_wcn_stp_wakeup_consys(VOID) -+{ -+ /*log wakeup int for debug */ -+ stp_dbg_pkt_log(7, 0, 0, 0, PKT_DIR_TX, NULL, 0); -+ return mtk_wcn_consys_stp_btif_wakeup(); -+} -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_dpidle_ctrl -+* DESCRIPTION -+* decide AP enter or exit deep idle -+* PARAMETERS -+* en_flag:1,enter,0,exit -+* RETURNS -+* always 0 -+*****************************************************************************/ -+INT32 mtk_wcn_stp_dpidle_ctrl(ENUM_BTIF_DPIDLE_CTRL en_flag) -+{ -+ mtk_wcn_consys_stp_btif_dpidle_ctrl(en_flag); -+ -+ return 0; -+} -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_lpbk_ctrl -+* DESCRIPTION -+* enable stp internal lpbk test or not -+* PARAMETERS -+* mode:1,enable,0,disabel -+* RETURNS -+* INT32 0-success,other fail. -+*****************************************************************************/ -+INT32 mtk_wcn_stp_lpbk_ctrl(ENUM_BTIF_LPBK_MODE mode) -+{ -+ return mtk_wcn_consys_stp_btif_lpbk_ctrl(mode); -+} -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_logger_ctrl -+* DESCRIPTION -+* dump btif buffer or register status when No ACK or assert occurs -+* PARAMETERS -+* flag:see enum value in ENUM_BTIF_DBG_ID -+* RETURNS -+* INT32 0-success,other fail. -+*****************************************************************************/ -+INT32 mtk_wcn_stp_logger_ctrl(ENUM_BTIF_DBG_ID flag) -+{ -+ return mtk_wcn_consys_stp_btif_logger_ctrl(flag); -+} -+ -+VOID mtk_wcn_stp_ctx_save(void) -+{ -+ STP_INFO_FUNC("start ++\n"); -+ mtk_wcn_stp_coredump_start_ctrl(1); -+ stp_psm_set_sleep_disable(stp_core_ctx.psm); -+ STP_INFO_FUNC("exit --\n"); -+} -+ -+VOID mtk_wcn_stp_ctx_restore(void) -+{ -+ STP_INFO_FUNC("start ++\n"); -+ stp_psm_set_sleep_enable(stp_core_ctx.psm); -+ stp_btm_reset_btm_wq(STP_BTM_CORE(stp_core_ctx)); -+ -+ if (STP_IS_ENABLE_RST(stp_core_ctx)) -+ stp_btm_notify_wmt_rst_wq(STP_BTM_CORE(stp_core_ctx)); -+ else -+ STP_INFO_FUNC("No to launch whole chip reset! for debugging purpose\n"); -+#if STP_RETRY_OPTIMIZE -+ g_retry_times = 0; -+#endif -+ STP_INFO_FUNC("exit --\n"); -+} -+ -+INT32 mtk_wcn_stp_wmt_evt_err_trg_assert(void) -+{ -+ INT32 ret = -1; -+ -+ if (mtk_wcn_stp_coredump_start_get() != 0) { -+ STP_INFO_FUNC("firmware assert has been triggered\n"); -+ return 0; -+ } -+ -+ ret = stp_notify_btm_do_fw_assert_via_emi(STP_BTM_CORE(stp_core_ctx)); -+ if (ret) { -+ STP_ERR_FUNC("evt err trigger assert fail,do chip reset to recovery\n"); -+ -+ mtk_wcn_stp_set_wmt_evt_err_trg_assert(0); -+ if (STP_IS_ENABLE_RST(stp_core_ctx)) -+ stp_btm_notify_wmt_rst_wq(STP_BTM_CORE(stp_core_ctx)); -+ else -+ STP_INFO_FUNC("No to launch whole chip reset! for debugging purpose\n"); -+ } -+ -+ return ret; -+} -+ -+VOID mtk_wcn_stp_set_wmt_evt_err_trg_assert(UINT32 value) -+{ -+ STP_INFO_FUNC("set evt err tigger assert flag to %d\n", value); -+ STP_SET_EVT_ERR_ASSERT(stp_core_ctx, value); -+} -+ -+UINT32 mtk_wcn_stp_get_wmt_evt_err_trg_assert(void) -+{ -+ return STP_EVT_ERR_ASSERT(stp_core_ctx); -+} -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_conf.c b/drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_conf.c -new file mode 100644 -index 000000000000..3009bd26df41 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_conf.c -@@ -0,0 +1,529 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -+ -+#ifdef DFT_TAG -+#undef DFT_TAG -+#endif -+#define DFT_TAG "[WMT-CONF]" -+ -+#include "osal_typedef.h" -+/* #include "osal.h" */ -+#include "wmt_lib.h" -+#include "wmt_dev.h" -+#include "wmt_conf.h" -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+struct parse_data { -+ PINT8 name; -+ INT32 (*parser)(P_DEV_WMT pWmtDev, const struct parse_data *data, const PINT8 value); -+ PINT8 (*writer)(P_DEV_WMT pWmtDev, const struct parse_data *data); -+ /*PINT8 param1, *param2, *param3; */ -+ /* TODO:[FixMe][George] CLARIFY WHAT SHOULD BE USED HERE!!! */ -+ PINT8 param1; -+ PINT8 param2; -+ PINT8 param3; -+}; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/****************************************************************************** -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************* -+*/ -+static INT32 wmt_conf_parse_char(P_DEV_WMT pWmtDev, const struct parse_data *data, const PINT8 pos); -+ -+static PINT8 wmt_conf_write_char(P_DEV_WMT pWmtDev, const struct parse_data *data); -+ -+static INT32 wmt_conf_parse_short(P_DEV_WMT pWmtDev, const struct parse_data *data, const PINT8 pos); -+ -+static PINT8 wmt_conf_write_short(P_DEV_WMT pWmtDev, const struct parse_data *data); -+ -+static INT32 wmt_conf_parse_int(P_DEV_WMT pWmtDev, const struct parse_data *data, const PINT8 pos); -+ -+static PINT8 wmt_conf_write_int(P_DEV_WMT pWmtDev, const struct parse_data *data); -+ -+static INT32 wmt_conf_parse_pair(P_DEV_WMT pWmtDev, const PINT8 pKey, const PINT8 pVal); -+ -+static INT32 wmt_conf_parse(P_DEV_WMT pWmtDev, const PINT8 pInBuf, UINT32 size); -+ -+#define OFFSET(v) ((void *) &((P_DEV_WMT) 0)->v) -+ -+#define CHAR(f) \ -+{ \ -+ #f, \ -+ wmt_conf_parse_char, \ -+ wmt_conf_write_char, \ -+ OFFSET(rWmtGenConf.f), \ -+ NULL, \ -+ NULL \ -+} -+/* #define CHAR(f) _CHAR(f), NULL, NULL} */ -+ -+#define SHORT(f) \ -+{ \ -+ #f, \ -+ wmt_conf_parse_short, \ -+ wmt_conf_write_short, \ -+ OFFSET(rWmtGenConf.f), \ -+ NULL, \ -+ NULL \ -+} -+/* #define SHORT(f) _SHORT(f), NULL, NULL */ -+ -+#define INT(f) \ -+{ \ -+ #f, \ -+ wmt_conf_parse_int, \ -+ wmt_conf_write_int, \ -+ OFFSET(rWmtGenConf.f), \ -+ NULL, \ -+ NULL \ -+} -+/* #define INT(f) _INT(f), NULL, NULL */ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+static const struct parse_data wmtcfg_fields[] = { -+ CHAR(coex_wmt_ant_mode), -+ CHAR(coex_wmt_ext_component), -+ CHAR(coex_wmt_wifi_time_ctl), -+ CHAR(coex_wmt_ext_pta_dev_on), -+ CHAR(coex_wmt_filter_mode), -+ -+ CHAR(coex_bt_rssi_upper_limit), -+ CHAR(coex_bt_rssi_mid_limit), -+ CHAR(coex_bt_rssi_lower_limit), -+ CHAR(coex_bt_pwr_high), -+ CHAR(coex_bt_pwr_mid), -+ CHAR(coex_bt_pwr_low), -+ -+ CHAR(coex_wifi_rssi_upper_limit), -+ CHAR(coex_wifi_rssi_mid_limit), -+ CHAR(coex_wifi_rssi_lower_limit), -+ CHAR(coex_wifi_pwr_high), -+ CHAR(coex_wifi_pwr_mid), -+ CHAR(coex_wifi_pwr_low), -+ -+ CHAR(coex_ext_pta_hi_tx_tag), -+ CHAR(coex_ext_pta_hi_rx_tag), -+ CHAR(coex_ext_pta_lo_tx_tag), -+ CHAR(coex_ext_pta_lo_rx_tag), -+ SHORT(coex_ext_pta_sample_t1), -+ SHORT(coex_ext_pta_sample_t2), -+ CHAR(coex_ext_pta_wifi_bt_con_trx), -+ -+ INT(coex_misc_ext_pta_on), -+ INT(coex_misc_ext_feature_set), -+ -+ CHAR(wmt_gps_lna_pin), -+ CHAR(wmt_gps_lna_enable), -+ -+ CHAR(pwr_on_rtc_slot), -+ CHAR(pwr_on_ldo_slot), -+ CHAR(pwr_on_rst_slot), -+ CHAR(pwr_on_off_slot), -+ CHAR(pwr_on_on_slot), -+ CHAR(co_clock_flag), -+ -+ INT(sdio_driving_cfg), -+ -+}; -+ -+#define NUM_WMTCFG_FIELDS (osal_sizeof(wmtcfg_fields) / osal_sizeof(wmtcfg_fields[0])) -+ -+static int wmt_conf_parse_char(P_DEV_WMT pWmtDev, const struct parse_data *data, const PINT8 pos) -+{ -+ PINT8 dst; -+ long res; -+ int ret; -+ -+ dst = (PINT8) (((PUINT8) pWmtDev) + (long)data->param1); -+ -+ if ((osal_strlen(pos) > 2) && ((*pos) == '0') && (*(pos + 1) == 'x')) { -+ ret = osal_strtol(pos + 2, 16, &res); -+ if (ret) -+ WMT_ERR_FUNC("fail(%d)\n", ret); -+ *dst = res; -+ WMT_DBG_FUNC("wmtcfg==> %s=0x%x\n", data->name, *dst); -+ } else { -+ ret = osal_strtol(pos, 10, &res); -+ if (ret) -+ WMT_ERR_FUNC("fail(%d)\n", ret); -+ *dst = res; -+ WMT_DBG_FUNC("wmtcfg==> %s=%d\n", data->name, *dst); -+ } -+ return 0; -+} -+ -+static PINT8 wmt_conf_write_char(P_DEV_WMT pWmtDev, const struct parse_data *data) -+{ -+ PINT8 src; -+ INT32 res; -+ PINT8 value; -+ -+ src = (PINT8) (((PUINT8) pWmtDev) + (long)data->param1); -+ -+ value = osal_malloc(20); -+ if (value == NULL) -+ return NULL; -+ res = osal_snprintf(value, 20, "0x%x", *src); -+ if (res < 0 || res >= 20) { -+ osal_free(value); -+ return NULL; -+ } -+ value[20 - 1] = '\0'; -+ return value; -+} -+ -+static int wmt_conf_parse_short(P_DEV_WMT pWmtDev, const struct parse_data *data, const PINT8 pos) -+{ -+ PUINT16 dst; -+ long res; -+ int ret; -+ -+ dst = (PINT16) (((PUINT8) pWmtDev) + (long)data->param1); -+ -+ /* WMT_INFO_FUNC(">strlen(pos)=%d\n", strlen(pos)); */ -+ -+ if ((osal_strlen(pos) > 2) && ((*pos) == '0') && (*(pos + 1) == 'x')) { -+ ret = osal_strtol(pos + 2, 16, &res); -+ if (ret) -+ WMT_ERR_FUNC("fail(%d)\n", ret); -+ *dst = res; -+ WMT_DBG_FUNC("wmtcfg==> %s=0x%x\n", data->name, *dst); -+ } else { -+ ret = osal_strtol(pos, 10, &res); -+ if (ret) -+ WMT_ERR_FUNC("fail(%d)\n", ret); -+ *dst = res; -+ WMT_DBG_FUNC("wmtcfg==> %s=%d\n", data->name, *dst); -+ } -+ -+ return 0; -+} -+ -+static PINT8 wmt_conf_write_short(P_DEV_WMT pWmtDev, const struct parse_data *data) -+{ -+ PINT16 src; -+ INT32 res; -+ PINT8 value; -+ -+ /* TODO: [FixMe][George] FIX COMPILE WARNING HERE! */ -+ src = (PINT16) (((PUINT8) pWmtDev) + (long)data->param1); -+ -+ value = osal_malloc(20); -+ if (value == NULL) -+ return NULL; -+ res = osal_snprintf(value, 20, "0x%x", *src); -+ if (res < 0 || res >= 20) { -+ osal_free(value); -+ return NULL; -+ } -+ value[20 - 1] = '\0'; -+ return value; -+} -+ -+static int wmt_conf_parse_int(P_DEV_WMT pWmtDev, const struct parse_data *data, const PINT8 pos) -+{ -+ PUINT32 dst; -+ long res; -+ int ret; -+ -+ dst = (PINT32) (((PUINT8) pWmtDev) + (long)data->param1); -+ -+ /* WMT_INFO_FUNC(">strlen(pos)=%d\n", strlen(pos)); */ -+ -+ if ((osal_strlen(pos) > 2) && ((*pos) == '0') && (*(pos + 1) == 'x')) { -+ ret = osal_strtol(pos + 2, 16, &res); -+ if (ret) -+ WMT_ERR_FUNC("fail(%d)\n", ret); -+ *dst = res; -+ WMT_DBG_FUNC("wmtcfg==> %s=0x%x\n", data->name, *dst); -+ } else { -+ ret = osal_strtol(pos, 10, &res); -+ if (ret) -+ WMT_ERR_FUNC("fail(%d)\n", ret); -+ *dst = res; -+ WMT_DBG_FUNC("wmtcfg==> %s=%d\n", data->name, *dst); -+ } -+ -+ return 0; -+} -+ -+static PINT8 wmt_conf_write_int(P_DEV_WMT pWmtDev, const struct parse_data *data) -+{ -+ PINT32 src; -+ INT32 res; -+ PINT8 value; -+ -+ src = (PUINT32) (((PUINT8) pWmtDev) + (long)data->param1); -+ -+ value = osal_malloc(20); -+ if (value == NULL) -+ return NULL; -+ res = osal_snprintf(value, 20, "0x%x", *src); -+ if (res < 0 || res >= 20) { -+ osal_free(value); -+ return NULL; -+ } -+ value[20 - 1] = '\0'; -+ return value; -+} -+ -+static INT32 wmt_conf_parse_pair(P_DEV_WMT pWmtDev, const PINT8 pKey, const PINT8 pVal) -+{ -+ int i = 0; -+ int ret = 0; -+ -+ /* WMT_INFO_FUNC( DBG_NAME "cfg(%s) val(%s)\n", pKey, pVal); */ -+ -+ for (i = 0; i < NUM_WMTCFG_FIELDS; i++) { -+ const struct parse_data *field = &wmtcfg_fields[i]; -+ -+ if (osal_strcmp(pKey, field->name) != 0) -+ continue; -+ if (field->parser(pWmtDev, field, pVal)) { -+ WMT_ERR_FUNC("failed to parse %s '%s'.\n", pKey, pVal); -+ ret = -1; -+ } -+ break; -+ } -+ if (i == NUM_WMTCFG_FIELDS) { -+ WMT_ERR_FUNC("unknown field '%s'.\n", pKey); -+ ret = -1; -+ } -+ -+ return ret; -+} -+ -+static INT32 wmt_conf_parse(P_DEV_WMT pWmtDev, const PINT8 pInBuf, UINT32 size) -+{ -+ PINT8 pch; -+ PINT8 pBuf; -+ PINT8 pLine; -+ PINT8 pKey; -+ PINT8 pVal; -+ PINT8 pPos; -+ INT32 ret = 0; -+ INT32 i = 0; -+ PINT8 pa = NULL; -+ -+ pBuf = osal_malloc(size); -+ if (!pBuf) -+ return -1; -+ -+ osal_memcpy(pBuf, pInBuf, size); -+ pBuf[size] = '\0'; -+ -+ pch = pBuf; -+ /* pch is to be updated by strsep(). Keep pBuf unchanged!! */ -+ -+#if 0 -+ { -+ PINT8 buf_ptr = pBuf; -+ INT32 k = 0; -+ -+ WMT_INFO_FUNC("%s len=%d", "wmcfg.content:", size); -+ for (k = 0; k < size; k++) { -+ /* if(k%16 == 0) WMT_INFO_FUNC("\n"); */ -+ WMT_INFO_FUNC("%c", buf_ptr[k]); -+ } -+ WMT_INFO_FUNC("--end\n"); -+ } -+#endif -+ -+ while ((pLine = osal_strsep(&pch, "\r\n")) != NULL) { -+ /* pch is updated to the end of pLine by strsep() and updated to '\0' */ -+ /*WMT_INFO_FUNC("strsep offset(%d), char(%d, '%c' )\n", pLine-pBuf, *pLine, *pLine); */ -+ /* parse each line */ -+ -+ /* WMT_INFO_FUNC("==> Line = (%s)\n", pLine); */ -+ -+ if (!*pLine) -+ continue; -+ -+ pVal = osal_strchr(pLine, '='); -+ if (!pVal) { -+ WMT_WARN_FUNC("mal-format cfg string(%s)\n", pLine); -+ continue; -+ } -+ -+ /* |<-pLine->|'='<-pVal->|'\n' ('\0')| */ -+ *pVal = '\0'; /* replace '=' with '\0' to get key */ -+ /* |<-pKey->|'\0'|<-pVal->|'\n' ('\0')| */ -+ pKey = pLine; -+ -+ if ((pVal - pBuf) < size) -+ pVal++; -+ -+ /*key handling */ -+ pPos = pKey; -+ /*skip space characeter */ -+ while (((*pPos) == ' ') || ((*pPos) == '\t') || ((*pPos) == '\n')) { -+ if ((pPos - pBuf) >= size) -+ break; -+ pPos++; -+ } -+ /*key head */ -+ pKey = pPos; -+ while (((*pPos) != ' ') && ((*pPos) != '\t') && ((*pPos) != '\0') && ((*pPos) != '\n')) { -+ if ((pPos - pBuf) >= size) -+ break; -+ pPos++; -+ } -+ /*key tail */ -+ (*pPos) = '\0'; -+ -+ /*value handling */ -+ pPos = pVal; -+ /*skip space characeter */ -+ while (((*pPos) == ' ') || ((*pPos) == '\t') || ((*pPos) == '\n')) { -+ if ((pPos - pBuf) >= size) -+ break; -+ pPos++; -+ } -+ /*value head */ -+ pVal = pPos; -+ while (((*pPos) != ' ') && ((*pPos) != '\t') && ((*pPos) != '\0') && ((*pPos) != '\n')) { -+ if ((pPos - pBuf) >= size) -+ break; -+ pPos++; -+ } -+ /*value tail */ -+ (*pPos) = '\0'; -+ -+ /* WMT_DBG_FUNC("parse (key: #%s#, value: #%s#)\n", pKey, pVal); */ -+ ret = wmt_conf_parse_pair(pWmtDev, pKey, pVal); -+ WMT_DBG_FUNC("parse (%s, %s, %d)\n", pKey, pVal, ret); -+ if (ret) -+ WMT_WARN_FUNC("parse fail (%s, %s, %d)\n", pKey, pVal, ret); -+ } -+ -+ for (i = 0; i < NUM_WMTCFG_FIELDS; i++) { -+ const struct parse_data *field = &wmtcfg_fields[i]; -+ -+ pa = field->writer(pWmtDev, field); -+ if (pa) { -+ WMT_DBG_FUNC("#%d(%s)=>%s\n", i, field->name, pa); -+ osal_free(pa); -+ } else { -+ WMT_ERR_FUNC("failed to parse '%s'.\n", field->name); -+ } -+ } -+ osal_free(pBuf); -+ return 0; -+} -+ -+INT32 wmt_conf_set_cfg_file(const char *name) -+{ -+ if (NULL == name) { -+ WMT_ERR_FUNC("name is NULL\n"); -+ return -1; -+ } -+ if (osal_strlen(name) >= osal_sizeof(gDevWmt.cWmtcfgName)) { -+ WMT_ERR_FUNC("name is too long, length=%d, expect to < %d\n", osal_strlen(name), -+ osal_sizeof(gDevWmt.cWmtcfgName)); -+ return -2; -+ } -+ osal_memset(&gDevWmt.cWmtcfgName[0], 0, osal_sizeof(gDevWmt.cWmtcfgName)); -+ osal_strcpy(&(gDevWmt.cWmtcfgName[0]), name); -+ WMT_ERR_FUNC("WMT config file is set to (%s)\n", &(gDevWmt.cWmtcfgName[0])); -+ -+ return 0; -+} -+ -+INT32 wmt_conf_read_file(VOID) -+{ -+ INT32 ret = -1; -+ -+ osal_memset(&gDevWmt.rWmtGenConf, 0, osal_sizeof(gDevWmt.rWmtGenConf)); -+ osal_memset(&gDevWmt.pWmtCfg, 0, osal_sizeof(gDevWmt.pWmtCfg)); -+ -+#if 1 -+ osal_memset(&gDevWmt.cWmtcfgName[0], 0, osal_sizeof(gDevWmt.cWmtcfgName)); -+ -+ osal_strncat(&(gDevWmt.cWmtcfgName[0]), CUST_CFG_WMT_PREFIX, osal_sizeof(CUST_CFG_WMT_PREFIX)); -+ osal_strncat(&(gDevWmt.cWmtcfgName[0]), CUST_CFG_WMT, osal_sizeof(CUST_CFG_WMT)); -+#endif -+ -+ if (!osal_strlen(&(gDevWmt.cWmtcfgName[0]))) { -+ WMT_ERR_FUNC("empty Wmtcfg name\n"); -+ osal_assert(0); -+ return ret; -+ } -+ WMT_DBG_FUNC("WMT config file:%s\n", &(gDevWmt.cWmtcfgName[0])); -+ if (0 == wmt_dev_patch_get(&gDevWmt.cWmtcfgName[0], (osal_firmware **) &gDevWmt.pWmtCfg, 0)) { -+ /*get full name patch success */ -+ WMT_DBG_FUNC("get full file name(%s) buf(0x%p) size(%d)\n", -+ &gDevWmt.cWmtcfgName[0], gDevWmt.pWmtCfg->data, gDevWmt.pWmtCfg->size); -+ -+ if (0 == wmt_conf_parse(&gDevWmt, (const PINT8)gDevWmt.pWmtCfg->data, gDevWmt.pWmtCfg->size)) { -+ /*config file exists */ -+ gDevWmt.rWmtGenConf.cfgExist = 1; -+ -+ WMT_DBG_FUNC("&gDevWmt.rWmtGenConf=%p\n", &gDevWmt.rWmtGenConf); -+ ret = 0; -+ } else { -+ WMT_ERR_FUNC("wmt conf parsing fail\n"); -+ osal_assert(0); -+ ret = -1; -+ } -+ wmt_dev_patch_put((osal_firmware **) &gDevWmt.pWmtCfg); -+/* -+ if (gDevWmt.pWmtCfg) -+ { -+ if (gDevWmt.pWmtCfg->data) -+ { -+ osal_free(gDevWmt.pWmtCfg->data); -+ } -+ osal_free(gDevWmt.pWmtCfg); -+ gDevWmt.pWmtCfg = 0; -+ } -+*/ -+ return ret; -+ } -+ WMT_ERR_FUNC("read %s file fails\n", &(gDevWmt.cWmtcfgName[0])); -+ osal_assert(0); -+ -+ gDevWmt.rWmtGenConf.cfgExist = 0; -+ return ret; -+} -+ -+P_WMT_GEN_CONF wmt_conf_get_cfg(VOID) -+{ -+ if (0 == gDevWmt.rWmtGenConf.cfgExist) -+ return NULL; -+ -+ return &gDevWmt.rWmtGenConf; -+} -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_core.c b/drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_core.c -new file mode 100644 -index 000000000000..cca6729d53a0 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_core.c -@@ -0,0 +1,2521 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -+/*! \file -+ \brief Declaration of library functions -+ -+ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+#ifdef DFT_TAG -+#undef DFT_TAG -+#endif -+#define DFT_TAG "[WMT-CORE]" -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "osal_typedef.h" -+ -+#include "wmt_lib.h" -+#include "wmt_core.h" -+#include "wmt_ctrl.h" -+#include "wmt_ic.h" -+#include "wmt_conf.h" -+ -+#include "wmt_func.h" -+#include "stp_core.h" -+#include "psm_core.h" -+ -+ -+P_WMT_FUNC_OPS gpWmtFuncOps[4] = { -+#if CFG_FUNC_BT_SUPPORT -+ [0] = &wmt_func_bt_ops, -+#else -+ [0] = NULL, -+#endif -+ -+#if CFG_FUNC_FM_SUPPORT -+ [1] = &wmt_func_fm_ops, -+#else -+ [1] = NULL, -+#endif -+ -+#if CFG_FUNC_GPS_SUPPORT -+ [2] = &wmt_func_gps_ops, -+#else -+ [2] = NULL, -+#endif -+ -+#if CFG_FUNC_WIFI_SUPPORT -+ [3] = &wmt_func_wifi_ops, -+#else -+ [3] = NULL, -+#endif -+ -+}; -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/* TODO:[FixMe][GeorgeKuo]: is it an MT6620 only or general general setting? -+*move to wmt_ic_6620 temporarily. -+*/ -+/* BT Port 2 Feature. */ -+/* #define CFG_WMT_BT_PORT2 (1) */ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+static WMT_CTX gMtkWmtCtx; -+static UINT8 gLpbkBuf[1024+5] = { 0 }; -+#ifdef CONFIG_MTK_COMBO_ANT -+static UINT8 gAntBuf[1024] = { 0 }; -+#define CFG_CHECK_WMT_RESULT (1) -+#endif -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+static INT32 opfunc_hif_conf(P_WMT_OP pWmtOp); -+static INT32 opfunc_pwr_on(P_WMT_OP pWmtOp); -+static INT32 opfunc_pwr_off(P_WMT_OP pWmtOp); -+static INT32 opfunc_func_on(P_WMT_OP pWmtOp); -+static INT32 opfunc_func_off(P_WMT_OP pWmtOp); -+static INT32 opfunc_reg_rw(P_WMT_OP pWmtOp); -+static INT32 opfunc_exit(P_WMT_OP pWmtOp); -+static INT32 opfunc_pwr_sv(P_WMT_OP pWmtOp); -+static INT32 opfunc_dsns(P_WMT_OP pWmtOp); -+static INT32 opfunc_lpbk(P_WMT_OP pWmtOp); -+static INT32 opfunc_cmd_test(P_WMT_OP pWmtOp); -+static INT32 opfunc_hw_rst(P_WMT_OP pWmtOp); -+static INT32 opfunc_sw_rst(P_WMT_OP pWmtOp); -+static INT32 opfunc_stp_rst(P_WMT_OP pWmtOp); -+static INT32 opfunc_therm_ctrl(P_WMT_OP pWmtOp); -+static INT32 opfunc_efuse_rw(P_WMT_OP pWmtOp); -+static INT32 opfunc_therm_ctrl(P_WMT_OP pWmtOp); -+static INT32 opfunc_gpio_ctrl(P_WMT_OP pWmtOp); -+static INT32 opfunc_pin_state(P_WMT_OP pWmtOp); -+static INT32 opfunc_bgw_ds(P_WMT_OP pWmtOp); -+static INT32 opfunc_set_mcu_clk(P_WMT_OP pWmtOp); -+static INT32 opfunc_adie_lpbk_test(P_WMT_OP pWmtOp); -+#if CFG_WMT_LTE_COEX_HANDLING -+static INT32 opfunc_idc_msg_handling(P_WMT_OP pWmtOp); -+#endif -+#ifdef CONFIG_MTK_COMBO_ANT -+static INT32 opfunc_ant_ram_down(P_WMT_OP pWmtOp); -+static INT32 opfunc_ant_ram_stat_get(P_WMT_OP pWmtOp); -+#endif -+static VOID wmt_core_dump_func_state(PINT8 pSource); -+static INT32 wmt_core_stp_init(VOID); -+static INT32 wmt_core_stp_deinit(VOID); -+static INT32 wmt_core_hw_check(VOID); -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+static const UINT8 WMT_SLEEP_CMD[] = { 0x01, 0x03, 0x01, 0x00, 0x01 }; -+static const UINT8 WMT_SLEEP_EVT[] = { 0x02, 0x03, 0x02, 0x00, 0x00, 0x01 }; -+ -+static const UINT8 WMT_HOST_AWAKE_CMD[] = { 0x01, 0x03, 0x01, 0x00, 0x02 }; -+static const UINT8 WMT_HOST_AWAKE_EVT[] = { 0x02, 0x03, 0x02, 0x00, 0x00, 0x02 }; -+ -+static const UINT8 WMT_WAKEUP_CMD[] = { 0xFF }; -+static const UINT8 WMT_WAKEUP_EVT[] = { 0x02, 0x03, 0x02, 0x00, 0x00, 0x03 }; -+ -+static UINT8 WMT_THERM_CMD[] = { 0x01, 0x11, 0x01, 0x00, -+ 0x00 /*thermal sensor operation */ -+}; -+static UINT8 WMT_THERM_CTRL_EVT[] = { 0x02, 0x11, 0x01, 0x00, 0x00 }; -+static UINT8 WMT_THERM_READ_EVT[] = { 0x02, 0x11, 0x02, 0x00, 0x00, 0x00 }; -+ -+static UINT8 WMT_EFUSE_CMD[] = { 0x01, 0x0D, 0x08, 0x00, -+ 0x01, /*[4]operation, 0:init, 1:write 2:read */ -+ 0x01, /*[5]Number of register setting */ -+ 0xAA, 0xAA, /*[6-7]Address */ -+ 0xBB, 0xBB, 0xBB, 0xBB /*[8-11] Value */ -+}; -+ -+static UINT8 WMT_EFUSE_EVT[] = { 0x02, 0x0D, 0x08, 0x00, -+ 0xAA, /*[4]operation, 0:init, 1:write 2:read */ -+ 0xBB, /*[5]Number of register setting */ -+ 0xCC, 0xCC, /*[6-7]Address */ -+ 0xDD, 0xDD, 0xDD, 0xDD /*[8-11] Value */ -+}; -+ -+static UINT8 WMT_DSNS_CMD[] = { 0x01, 0x0E, 0x02, 0x00, 0x01, -+ 0x00 /*desnse type */ -+}; -+static UINT8 WMT_DSNS_EVT[] = { 0x02, 0x0E, 0x01, 0x00, 0x00 }; -+ -+/* TODO:[NewFeature][GeorgeKuo] Update register group in ONE CMD/EVT */ -+static UINT8 WMT_SET_REG_CMD[] = { 0x01, 0x08, 0x10, 0x00 /*length */ -+ , 0x00 /*op: w(1) & r(2) */ -+ , 0x01 /*type: reg */ -+ , 0x00 /*res */ -+ , 0x01 /*1 register */ -+ , 0x00, 0x00, 0x00, 0x00 /* addr */ -+ , 0x00, 0x00, 0x00, 0x00 /* value */ -+ , 0xFF, 0xFF, 0xFF, 0xFF /*mask */ -+}; -+ -+static UINT8 WMT_SET_REG_WR_EVT[] = { 0x02, 0x08, 0x04, 0x00 /*length */ -+ , 0x00 /*S: 0 */ -+ , 0x00 /*type: reg */ -+ , 0x00 /*rev */ -+ , 0x01 /*1 register */ -+ /* , 0x00, 0x00, 0x00, 0x00 */ /* addr */ -+ /* , 0x00, 0x00, 0x00, 0x00 */ /* value */ -+}; -+ -+static UINT8 WMT_SET_REG_RD_EVT[] = { 0x02, 0x08, 0x04, 0x00 /*length */ -+ , 0x00 /*S: 0 */ -+ , 0x00 /*type: reg */ -+ , 0x00 /*rev */ -+ , 0x01 /*1 register */ -+ , 0x00, 0x00, 0x00, 0x00 /* addr */ -+ , 0x00, 0x00, 0x00, 0x00 /* value */ -+}; -+ -+#ifdef CONFIG_MTK_COMBO_ANT -+static UINT8 WMT_ANT_RAM_STA_GET_CMD[] = { 0x01, 0x06, 0x02, 0x00, 0x05, 0x02 -+}; -+ -+static UINT8 WMT_ANT_RAM_STA_GET_EVT[] = { 0x02, 0x06, 0x03, 0x00 /*length */ -+ , 0x05, 0x02, 0x00 /*S: result */ -+}; -+ -+static UINT8 WMT_ANT_RAM_DWN_CMD[] = { 0x01, 0x15, 0x00, 0x00, 0x01 -+}; -+ -+static UINT8 WMT_ANT_RAM_DWN_EVT[] = { 0x02, 0x15, 0x01, 0x00 /*length */ -+ , 0x00 -+}; -+#endif -+ -+/* GeorgeKuo: Use designated initializers described in -+ * http://gcc.gnu.org/onlinedocs/gcc-4.0.4/gcc/Designated-Inits.html -+ */ -+ -+static const WMT_OPID_FUNC wmt_core_opfunc[] = { -+ [WMT_OPID_HIF_CONF] = opfunc_hif_conf, -+ [WMT_OPID_PWR_ON] = opfunc_pwr_on, -+ [WMT_OPID_PWR_OFF] = opfunc_pwr_off, -+ [WMT_OPID_FUNC_ON] = opfunc_func_on, -+ [WMT_OPID_FUNC_OFF] = opfunc_func_off, -+ [WMT_OPID_REG_RW] = opfunc_reg_rw, /* TODO:[ChangeFeature][George] is this OP obsoleted? */ -+ [WMT_OPID_EXIT] = opfunc_exit, -+ [WMT_OPID_PWR_SV] = opfunc_pwr_sv, -+ [WMT_OPID_DSNS] = opfunc_dsns, -+ [WMT_OPID_LPBK] = opfunc_lpbk, -+ [WMT_OPID_CMD_TEST] = opfunc_cmd_test, -+ [WMT_OPID_HW_RST] = opfunc_hw_rst, -+ [WMT_OPID_SW_RST] = opfunc_sw_rst, -+ [WMT_OPID_STP_RST] = opfunc_stp_rst, -+ [WMT_OPID_THERM_CTRL] = opfunc_therm_ctrl, -+ [WMT_OPID_EFUSE_RW] = opfunc_efuse_rw, -+ [WMT_OPID_GPIO_CTRL] = opfunc_gpio_ctrl, -+ [WMT_OPID_GPIO_STATE] = opfunc_pin_state, -+ [WMT_OPID_BGW_DS] = opfunc_bgw_ds, -+ [WMT_OPID_SET_MCU_CLK] = opfunc_set_mcu_clk, -+ [WMT_OPID_ADIE_LPBK_TEST] = opfunc_adie_lpbk_test, -+#if CFG_WMT_LTE_COEX_HANDLING -+ [WMT_OPID_IDC_MSG_HANDLING] = opfunc_idc_msg_handling, -+#endif -+#ifdef CONFIG_MTK_COMBO_ANT -+ [WMT_OPID_ANT_RAM_DOWN] = opfunc_ant_ram_down, -+ [WMT_OPID_ANT_RAM_STA_GET] = opfunc_ant_ram_stat_get, -+#endif -+}; -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+INT32 wmt_core_init(VOID) -+{ -+ INT32 i = 0; -+ -+ osal_memset(&gMtkWmtCtx, 0, osal_sizeof(gMtkWmtCtx)); -+ /* gMtkWmtCtx.p_ops is cleared to NULL */ -+ -+ /* default FUNC_OFF state */ -+ for (i = 0; i < WMTDRV_TYPE_MAX; ++i) { -+ /* WinMo is default to DRV_STS_UNREG; */ -+ gMtkWmtCtx.eDrvStatus[i] = DRV_STS_POWER_OFF; -+ } -+ -+ return 0; -+} -+ -+INT32 wmt_core_deinit(VOID) -+{ -+ /* return to init state */ -+ osal_memset(&gMtkWmtCtx, 0, osal_sizeof(gMtkWmtCtx)); -+ /* gMtkWmtCtx.p_ops is cleared to NULL */ -+ return 0; -+} -+ -+/* TODO: [ChangeFeature][George] Is wmt_ctrl a good interface? maybe not...... */ -+/* parameters shall be copied in/from ctrl buffer, which is also a size-wasting buffer. */ -+INT32 wmt_core_tx(const PUINT8 pData, const UINT32 size, PUINT32 writtenSize, const MTK_WCN_BOOL bRawFlag) -+{ -+ INT32 iRet; -+#if 0 /* Test using direct function call instead of wmt_ctrl() interface */ -+ WMT_CTRL_DATA ctrlData; -+ -+ ctrlData.ctrlId = WMT_CTRL_TX; -+ ctrlData.au4CtrlData[0] = (UINT32) pData; -+ ctrlData.au4CtrlData[1] = size; -+ ctrlData.au4CtrlData[2] = (UINT32) writtenSize; -+ ctrlData.au4CtrlData[3] = bRawFlag; -+ -+ iRet = wmt_ctrl(&ctrlData); -+ if (iRet) { -+ /* ERROR */ -+ WMT_ERR_FUNC("WMT-CORE: wmt_core_ctrl failed: WMT_CTRL_TX, iRet:%d\n", iRet); -+ /* (*sys_dbg_assert)(0, __FILE__, __LINE__); */ -+ osal_assert(0); -+ } -+#endif -+ iRet = wmt_ctrl_tx_ex(pData, size, writtenSize, bRawFlag); -+ if (0 == *writtenSize) { -+ INT32 retry_times = 0; -+ INT32 max_retry_times = 3; -+ INT32 retry_delay_ms = 360; -+ -+ WMT_WARN_FUNC("WMT-CORE: wmt_ctrl_tx_ex failed and written ret:%d, maybe no winspace in STP layer\n", -+ *writtenSize); -+ while ((0 == *writtenSize) && (retry_times < max_retry_times)) { -+ WMT_ERR_FUNC("WMT-CORE: retrying, wait for %d ms\n", retry_delay_ms); -+ osal_sleep_ms(retry_delay_ms); -+ -+ iRet = wmt_ctrl_tx_ex(pData, size, writtenSize, bRawFlag); -+ retry_times++; -+ } -+ } -+ return iRet; -+} -+ -+INT32 wmt_core_rx(PUINT8 pBuf, UINT32 bufLen, UINT32 *readSize) -+{ -+ INT32 iRet; -+ WMT_CTRL_DATA ctrlData; -+ -+ ctrlData.ctrlId = WMT_CTRL_RX; -+ ctrlData.au4CtrlData[0] = (SIZE_T) pBuf; -+ ctrlData.au4CtrlData[1] = bufLen; -+ ctrlData.au4CtrlData[2] = (SIZE_T) readSize; -+ -+ iRet = wmt_ctrl(&ctrlData); -+ if (iRet) { -+ /* ERROR */ -+ WMT_ERR_FUNC("WMT-CORE: wmt_core_ctrl failed: WMT_CTRL_RX, iRet:%d\n", iRet); -+ mtk_wcn_stp_dbg_dump_package(); -+ osal_assert(0); -+ } -+ return iRet; -+} -+ -+INT32 wmt_core_rx_flush(UINT32 type) -+{ -+ INT32 iRet; -+ WMT_CTRL_DATA ctrlData; -+ -+ ctrlData.ctrlId = WMT_CTRL_RX_FLUSH; -+ ctrlData.au4CtrlData[0] = (UINT32) type; -+ -+ iRet = wmt_ctrl(&ctrlData); -+ if (iRet) { -+ /* ERROR */ -+ WMT_ERR_FUNC("WMT-CORE: wmt_core_ctrl failed: WMT_CTRL_RX_FLUSH, iRet:%d\n", iRet); -+ osal_assert(0); -+ } -+ return iRet; -+} -+ -+INT32 wmt_core_func_ctrl_cmd(ENUM_WMTDRV_TYPE_T type, MTK_WCN_BOOL fgEn) -+{ -+ INT32 iRet = 0; -+ UINT32 u4WmtCmdPduLen; -+ UINT32 u4WmtEventPduLen; -+ UINT32 u4ReadSize; -+ UINT32 u4WrittenSize; -+ WMT_PKT rWmtPktCmd; -+ WMT_PKT rWmtPktEvent; -+ MTK_WCN_BOOL fgFail; -+ -+ /* TODO:[ChangeFeature][George] remove WMT_PKT. replace it with hardcoded arrays. */ -+ /* Using this struct relies on compiler's implementation and pack() settings */ -+ osal_memset(&rWmtPktCmd, 0, osal_sizeof(rWmtPktCmd)); -+ osal_memset(&rWmtPktEvent, 0, osal_sizeof(rWmtPktEvent)); -+ -+ rWmtPktCmd.eType = (UINT8) PKT_TYPE_CMD; -+ rWmtPktCmd.eOpCode = (UINT8) OPCODE_FUNC_CTRL; -+ -+ /* Flag field: driver type */ -+ rWmtPktCmd.aucParam[0] = (UINT8) type; -+ /* Parameter field: ON/OFF */ -+ rWmtPktCmd.aucParam[1] = (fgEn == WMT_FUNC_CTRL_ON) ? 1 : 0; -+ rWmtPktCmd.u2SduLen = WMT_FLAG_LEN + WMT_FUNC_CTRL_PARAM_LEN; /* (2) */ -+ -+ /* WMT Header + WMT SDU */ -+ u4WmtCmdPduLen = WMT_HDR_LEN + rWmtPktCmd.u2SduLen; /* (6) */ -+ u4WmtEventPduLen = WMT_HDR_LEN + WMT_STS_LEN; /* (5) */ -+ -+ do { -+ fgFail = MTK_WCN_BOOL_TRUE; -+/* iRet = (*kal_stp_tx)((PUINT8)&rWmtPktCmd, u4WmtCmdPduLen, &u4WrittenSize); */ -+ iRet = wmt_core_tx((PUINT8) &rWmtPktCmd, u4WmtCmdPduLen, &u4WrittenSize, MTK_WCN_BOOL_FALSE); -+ if (iRet) { -+ WMT_ERR_FUNC("WMT-CORE: wmt_func_ctrl_cmd kal_stp_tx failed\n"); -+ break; -+ } -+ -+ iRet = wmt_core_rx((PUINT8) &rWmtPktEvent, u4WmtEventPduLen, &u4ReadSize); -+ if (iRet) { -+ WMT_ERR_FUNC("WMT-CORE: wmt_func_ctrl_cmd kal_stp_rx failed\n"); -+ break; -+ } -+ -+ /* Error Checking */ -+ if (PKT_TYPE_EVENT != rWmtPktEvent.eType) { -+ WMT_ERR_FUNC("WMT-CORE: wmt_func_ctrl_cmd PKT_TYPE_EVENT != rWmtPktEvent.eType %d\n", -+ rWmtPktEvent.eType); -+ break; -+ } -+ -+ if (rWmtPktCmd.eOpCode != rWmtPktEvent.eOpCode) { -+ WMT_ERR_FUNC -+ ("WMT-CORE: wmt_func_ctrl_cmd rWmtPktCmd.eOpCode(0x%x) != rWmtPktEvent.eType(0x%x)\n", -+ rWmtPktCmd.eOpCode, rWmtPktEvent.eOpCode); -+ break; -+ } -+ -+ if (u4WmtEventPduLen != (rWmtPktEvent.u2SduLen + WMT_HDR_LEN)) { -+ WMT_ERR_FUNC -+ ("WMT-CORE: wmt_func_ctrl_cmd u4WmtEventPduLen(0x%x) != rWmtPktEvent.u2SduLen(0x%x)+4\n", -+ u4WmtEventPduLen, rWmtPktEvent.u2SduLen); -+ break; -+ } -+ /* Status field of event check */ -+ if (0 != rWmtPktEvent.aucParam[0]) { -+ WMT_ERR_FUNC("WMT-CORE: wmt_func_ctrl_cmd, 0 != status(%d)\n", rWmtPktEvent.aucParam[0]); -+ break; -+ } -+ -+ fgFail = MTK_WCN_BOOL_FALSE; -+ } while (0); -+ -+ if (MTK_WCN_BOOL_FALSE == fgFail) { -+ /* WMT_INFO_FUNC("WMT-CORE: wmt_func_ctrl_cmd OK!\n"); */ -+ return 0; -+ } -+ WMT_ERR_FUNC("WMT-CORE: wmt_func_ctrl_cmd 0x%x FAIL\n", rWmtPktCmd.aucParam[0]); -+ return -3; -+} -+ -+INT32 wmt_core_opid_handler(P_WMT_OP pWmtOp) -+{ -+ UINT32 opId; -+ INT32 ret; -+ -+ opId = pWmtOp->opId; -+ -+ if (wmt_core_opfunc[opId]) { -+ ret = (*(wmt_core_opfunc[opId])) (pWmtOp); /*wmtCoreOpidHandlerPack[].opHandler */ -+ return ret; -+ } -+ WMT_ERR_FUNC("WMT-CORE: null handler (%d)\n", pWmtOp->opId); -+ return -2; -+ -+} -+ -+INT32 wmt_core_opid(P_WMT_OP pWmtOp) -+{ -+ -+ /*sanity check */ -+ if (NULL == pWmtOp) { -+ WMT_ERR_FUNC("null pWmtOP\n"); -+ /*print some message with error info */ -+ return -1; -+ } -+ -+ if (WMT_OPID_MAX <= pWmtOp->opId) { -+ WMT_ERR_FUNC("WMT-CORE: invalid OPID(%d)\n", pWmtOp->opId); -+ return -2; -+ } -+ /* TODO: [FixMe][GeorgeKuo] do sanity check to const function table when init and skip checking here */ -+ return wmt_core_opid_handler(pWmtOp); -+} -+ -+INT32 wmt_core_ctrl(ENUM_WMT_CTRL_T ctrId, unsigned long *pPa1, unsigned long *pPa2) -+{ -+ INT32 iRet = -1; -+ WMT_CTRL_DATA ctrlData; -+ SIZE_T val1 = (pPa1) ? *pPa1 : 0; -+ SIZE_T val2 = (pPa2) ? *pPa2 : 0; -+ -+ ctrlData.ctrlId = (SIZE_T) ctrId; -+ ctrlData.au4CtrlData[0] = val1; -+ ctrlData.au4CtrlData[1] = val2; -+ -+ iRet = wmt_ctrl(&ctrlData); -+ if (iRet) { -+ /* ERROR */ -+ WMT_ERR_FUNC("WMT-CORE: wmt_core_ctrl failed: id(%d), type(%d), value(%d) iRet:(%d)\n", ctrId, val1, -+ val2, iRet); -+ osal_assert(0); -+ } else { -+ if (pPa1) -+ *pPa1 = ctrlData.au4CtrlData[0]; -+ if (pPa2) -+ *pPa2 = ctrlData.au4CtrlData[1]; -+ } -+ return iRet; -+} -+ -+VOID wmt_core_dump_data(PUINT8 pData, PUINT8 pTitle, UINT32 len) -+{ -+ PUINT8 ptr = pData; -+ INT32 k = 0; -+ -+ WMT_INFO_FUNC("%s len=%d\n", pTitle, len); -+ for (k = 0; k < len; k++) { -+ if (k % 16 == 0) -+ WMT_INFO_FUNC("\n"); -+ WMT_INFO_FUNC("0x%02x ", *ptr); -+ ptr++; -+ } -+ WMT_INFO_FUNC("--end\n"); -+} -+ -+/*! -+ * \brief An WMT-CORE function to support read, write, and read after write to -+ * an internal register. -+ * -+ * Detailed description. -+ * -+ * \param isWrite 1 for write, 0 for read -+ * \param offset of register to be written or read -+ * \param pVal a pointer to the 32-bit value to be writtern or read -+ * \param mask a 32-bit mask to be applied for the read or write operation -+ * -+ * \retval 0 operation success -+ * \retval -1 invalid parameters -+ * \retval -2 tx cmd fail -+ * \retval -3 rx event fail -+ * \retval -4 read check error -+ */ -+INT32 wmt_core_reg_rw_raw(UINT32 isWrite, UINT32 offset, PUINT32 pVal, UINT32 mask) -+{ -+ INT32 iRet; -+ UINT32 u4Res; -+ UINT32 evtLen; -+ UINT8 evtBuf[16] = { 0 }; -+ -+ WMT_SET_REG_CMD[4] = (isWrite) ? 0x1 : 0x2; /* w:1, r:2 */ -+ osal_memcpy(&WMT_SET_REG_CMD[8], &offset, 4); /* offset */ -+ osal_memcpy(&WMT_SET_REG_CMD[12], pVal, 4); /* [2] is var addr */ -+ osal_memcpy(&WMT_SET_REG_CMD[16], &mask, 4); /* mask */ -+ -+ /* send command */ -+ iRet = wmt_core_tx(WMT_SET_REG_CMD, sizeof(WMT_SET_REG_CMD), &u4Res, MTK_WCN_BOOL_FALSE); -+ if ((iRet) || (u4Res != sizeof(WMT_SET_REG_CMD))) { -+ WMT_ERR_FUNC("Tx REG_CMD fail!(%d) len (%d, %d)\n", iRet, u4Res, sizeof(WMT_SET_REG_CMD)); -+ return -2; -+ } -+ -+ /* receive event */ -+ evtLen = (isWrite) ? sizeof(WMT_SET_REG_WR_EVT) : sizeof(WMT_SET_REG_RD_EVT); -+ iRet = wmt_core_rx(evtBuf, evtLen, &u4Res); -+ if ((iRet) || (u4Res != evtLen)) { -+ WMT_ERR_FUNC("Rx REG_EVT fail!(%d) len(%d, %d)\n", iRet, u4Res, evtLen); -+ return -3; -+ } -+ -+ if (!isWrite) { -+ UINT32 rxEvtAddr; -+ UINT32 txCmdAddr; -+ -+ osal_memcpy(&txCmdAddr, &WMT_SET_REG_CMD[8], 4); -+ osal_memcpy(&rxEvtAddr, &evtBuf[8], 4); -+ -+ /* check read result */ -+ if (txCmdAddr != rxEvtAddr) { -+ WMT_ERR_FUNC("Check read addr fail (0x%08x, 0x%08x)\n", rxEvtAddr, txCmdAddr); -+ return -4; -+ } -+ WMT_DBG_FUNC("Check read addr(0x%08x) ok\n", rxEvtAddr); -+ -+ osal_memcpy(pVal, &evtBuf[12], 4); -+ } -+ -+ /* no error here just return 0 */ -+ return 0; -+} -+ -+INT32 wmt_core_init_script(struct init_script *script, INT32 count) -+{ -+ UINT8 evtBuf[256]; -+ UINT32 u4Res; -+ INT32 i = 0; -+ INT32 iRet; -+ -+ for (i = 0; i < count; i++) { -+ WMT_DBG_FUNC("WMT-CORE: init_script operation %s start\n", script[i].str); -+ /* CMD */ -+ /* iRet = (*kal_stp_tx)(script[i].cmd, script[i].cmdSz, &u4Res); */ -+ iRet = wmt_core_tx(script[i].cmd, script[i].cmdSz, &u4Res, MTK_WCN_BOOL_FALSE); -+ if (iRet || (u4Res != script[i].cmdSz)) { -+ WMT_ERR_FUNC("WMT-CORE: write (%s) iRet(%d) cmd len err(%d, %d)\n", script[i].str, iRet, u4Res, -+ script[i].cmdSz); -+ break; -+ } -+ /* EVENT BUF */ -+ osal_memset(evtBuf, 0, sizeof(evtBuf)); -+ iRet = wmt_core_rx(evtBuf, script[i].evtSz, &u4Res); -+ if (iRet || (u4Res != script[i].evtSz)) { -+ WMT_ERR_FUNC("WMT-CORE: read (%s) iRet(%d) evt len err(rx:%d, exp:%d)\n", script[i].str, iRet, -+ u4Res, script[i].evtSz); -+ mtk_wcn_stp_dbg_dump_package(); -+ break; -+ } -+ /* RESULT */ -+ if (0x14 != evtBuf[1]) { /* workaround RF calibration data EVT,do not care this EVT */ -+ if (osal_memcmp(evtBuf, script[i].evt, script[i].evtSz) != 0) { -+ WMT_ERR_FUNC("WMT-CORE:compare %s result error\n", script[i].str); -+ WMT_ERR_FUNC -+ ("WMT-CORE:rx(%d):[%02X,%02X,%02X,%02X,%02X] exp(%d):[%02X,%02X,%02X,%02X,%02X]\n", -+ u4Res, evtBuf[0], evtBuf[1], evtBuf[2], evtBuf[3], evtBuf[4], script[i].evtSz, -+ script[i].evt[0], script[i].evt[1], script[i].evt[2], script[i].evt[3], -+ script[i].evt[4]); -+ mtk_wcn_stp_dbg_dump_package(); -+ break; -+ } -+ } -+ WMT_DBG_FUNC("init_script operation %s ok\n", script[i].str); -+ } -+ -+ return (i == count) ? 0 : -1; -+} -+ -+static INT32 wmt_core_stp_init(VOID) -+{ -+ INT32 iRet = -1; -+ unsigned long ctrlPa1; -+ unsigned long ctrlPa2; -+ UINT8 co_clock_type; -+ P_WMT_CTX pctx = &gMtkWmtCtx; -+ P_WMT_GEN_CONF pWmtGenConf = NULL; -+ -+ wmt_conf_read_file(); -+ pWmtGenConf = wmt_conf_get_cfg(); -+ if (!(pctx->wmtInfoBit & WMT_OP_HIF_BIT)) { -+ WMT_ERR_FUNC("WMT-CORE: no hif info!\n"); -+ osal_assert(0); -+ return -1; -+ } -+ /* 4 <1> open stp */ -+ ctrlPa1 = 0; -+ ctrlPa2 = 0; -+ iRet = wmt_core_ctrl(WMT_CTRL_STP_OPEN, &ctrlPa1, &ctrlPa2); -+ if (iRet) { -+ WMT_ERR_FUNC("WMT-CORE: wmt open stp\n"); -+ return -2; -+ } -+ /* 4 <1.5> disable and un-ready stp */ -+ ctrlPa1 = WMT_STP_CONF_EN; -+ ctrlPa2 = 0; -+ iRet += wmt_core_ctrl(WMT_CTRL_STP_CONF, &ctrlPa1, &ctrlPa2); -+ ctrlPa1 = WMT_STP_CONF_RDY; -+ ctrlPa2 = 0; -+ iRet += wmt_core_ctrl(WMT_CTRL_STP_CONF, &ctrlPa1, &ctrlPa2); -+ -+ /* 4 <2> set mode and enable */ -+ if (WMT_HIF_BTIF == pctx->wmtHifConf.hifType) { -+ ctrlPa1 = WMT_STP_CONF_MODE; -+ ctrlPa2 = MTKSTP_BTIF_MAND_MODE; -+ iRet += wmt_core_ctrl(WMT_CTRL_STP_CONF, &ctrlPa1, &ctrlPa2); -+ } -+ -+ ctrlPa1 = WMT_STP_CONF_EN; -+ ctrlPa2 = 1; -+ iRet += wmt_core_ctrl(WMT_CTRL_STP_CONF, &ctrlPa1, &ctrlPa2); -+ if (iRet) { -+ WMT_ERR_FUNC("WMT-CORE: stp_init <1><2> fail:%d\n", iRet); -+ return -3; -+ } -+ /* TODO: [ChangeFeature][GeorgeKuo] can we apply raise UART baud rate firstly for ALL supported chips??? */ -+ -+ iRet = wmt_core_hw_check(); -+ if (iRet) { -+ WMT_ERR_FUNC("hw_check fail:%d\n", iRet); -+ return -4; -+ } -+ /* mtkWmtCtx.p_ic_ops is identified and checked ok */ -+ if ((NULL != pctx->p_ic_ops->co_clock_ctrl) && (pWmtGenConf != NULL)) { -+ co_clock_type = (pWmtGenConf->co_clock_flag & 0x0f); -+ (*(pctx->p_ic_ops->co_clock_ctrl)) (co_clock_type == 0 ? WMT_CO_CLOCK_DIS : WMT_CO_CLOCK_EN); -+ } else { -+ WMT_WARN_FUNC("pctx->p_ic_ops->co_clock_ctrl(0x%x), pWmtGenConf(0x%x)\n", pctx->p_ic_ops->co_clock_ctrl, -+ pWmtGenConf); -+ } -+ osal_assert(NULL != pctx->p_ic_ops->sw_init); -+ if (NULL != pctx->p_ic_ops->sw_init) { -+ iRet = (*(pctx->p_ic_ops->sw_init)) (&pctx->wmtHifConf); -+ } else { -+ WMT_ERR_FUNC("gMtkWmtCtx.p_ic_ops->sw_init is NULL\n"); -+ return -5; -+ } -+ if (iRet) { -+ WMT_ERR_FUNC("gMtkWmtCtx.p_ic_ops->sw_init fail:%d\n", iRet); -+ return -6; -+ } -+ /* 4 <10> set stp ready */ -+ ctrlPa1 = WMT_STP_CONF_RDY; -+ ctrlPa2 = 1; -+ iRet = wmt_core_ctrl(WMT_CTRL_STP_CONF, &ctrlPa1, &ctrlPa2); -+ -+ return iRet; -+} -+ -+static INT32 wmt_core_stp_deinit(VOID) -+{ -+ INT32 iRet; -+ unsigned long ctrlPa1; -+ unsigned long ctrlPa2; -+ -+ WMT_DBG_FUNC(" start\n"); -+ -+ if (NULL == gMtkWmtCtx.p_ic_ops) { -+ WMT_WARN_FUNC("gMtkWmtCtx.p_ic_ops is NULL\n"); -+ goto deinit_ic_ops_done; -+ } -+ if (NULL != gMtkWmtCtx.p_ic_ops->sw_deinit) { -+ iRet = (*(gMtkWmtCtx.p_ic_ops->sw_deinit)) (&gMtkWmtCtx.wmtHifConf); -+ /* unbind WMT-IC */ -+ gMtkWmtCtx.p_ic_ops = NULL; -+ } else { -+ WMT_ERR_FUNC("gMtkWmtCtx.p_ic_ops->sw_init is NULL\n"); -+ } -+ -+deinit_ic_ops_done: -+ -+ /* 4 <1> un-ready, disable, and close stp. */ -+ ctrlPa1 = WMT_STP_CONF_RDY; -+ ctrlPa2 = 0; -+ iRet = wmt_core_ctrl(WMT_CTRL_STP_CONF, &ctrlPa1, &ctrlPa2); -+ ctrlPa1 = WMT_STP_CONF_EN; -+ ctrlPa2 = 0; -+ iRet += wmt_core_ctrl(WMT_CTRL_STP_CONF, &ctrlPa1, &ctrlPa2); -+ ctrlPa1 = 0; -+ ctrlPa2 = 0; -+ iRet += wmt_core_ctrl(WMT_CTRL_STP_CLOSE, &ctrlPa1, &ctrlPa2); -+ -+ if (iRet) -+ WMT_WARN_FUNC("end with fail:%d\n", iRet); -+ -+ return iRet; -+} -+ -+static VOID wmt_core_dump_func_state(PINT8 pSource) -+{ -+ WMT_WARN_FUNC("[%s]status(b:%d f:%d g:%d w:%d lpbk:%d coredump:%d wmt:%d stp:%d)\n", -+ (pSource == NULL ? (PINT8) "CORE" : pSource), -+ gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_BT], -+ gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_FM], -+ gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_GPS], -+ gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WIFI], -+ gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_LPBK], -+ gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_COREDUMP], -+ gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT], gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_STP] -+ ); -+ return; -+ -+} -+ -+MTK_WCN_BOOL wmt_core_patch_check(UINT32 u4PatchVer, UINT32 u4HwVer) -+{ -+ if (MAJORNUM(u4HwVer) != MAJORNUM(u4PatchVer)) { -+ /*major no. does not match */ -+ WMT_ERR_FUNC("WMT-CORE: chip version(0x%d) does not match patch version(0x%d)\n", u4HwVer, u4PatchVer); -+ return MTK_WCN_BOOL_FALSE; -+ } -+ return MTK_WCN_BOOL_TRUE; -+} -+ -+static INT32 wmt_core_hw_check(VOID) -+{ -+ UINT32 chipid; -+ P_WMT_IC_OPS p_ops; -+ INT32 iret; -+ -+ /* 1. get chip id */ -+ chipid = 0; -+ WMT_LOUD_FUNC("before read hwcode (chip id)\n"); -+ iret = wmt_core_reg_rw_raw(0, GEN_HCR, &chipid, GEN_HCR_MASK); /* read 0x80000008 */ -+ if (iret) { -+ WMT_ERR_FUNC("get hwcode (chip id) fail (%d)\n", iret); -+ return -2; -+ } -+ WMT_DBG_FUNC("get hwcode (chip id) (0x%x)\n", chipid); -+ -+ /* TODO:[ChangeFeature][George]: use a better way to select a correct ops table based on chip id */ -+ switch (chipid) { -+#if CFG_CORE_MT6620_SUPPORT -+ case 0x6620: -+ p_ops = &wmt_ic_ops_mt6620; -+ break; -+#endif -+#if CFG_CORE_MT6628_SUPPORT -+ case 0x6628: -+ p_ops = &wmt_ic_ops_mt6628; -+ break; -+#endif -+#if CFG_CORE_SOC_SUPPORT -+ case 0x6572: -+ case 0x6582: -+ case 0x6592: -+ case 0x8127: -+ case 0x6571: -+ case 0x6752: -+ case 0x0279: -+ case 0x0326: -+ case 0x0321: -+ case 0x0335: -+ case 0x0337: -+ case 0x8163: -+ case 0x6580: -+ p_ops = &wmt_ic_ops_soc; -+ break; -+#endif -+ default: -+ p_ops = (P_WMT_IC_OPS) NULL; -+#if CFG_CORE_SOC_SUPPORT -+ if (0x7f90 == chipid - 0x600) { -+ p_ops = &wmt_ic_ops_soc; -+ chipid -= 0xf6d; -+ } -+#endif -+ break; -+ } -+ -+ if (NULL == p_ops) { -+ WMT_ERR_FUNC("unsupported chip id (hw_code): 0x%x\n", chipid); -+ return -3; -+ } else if (MTK_WCN_BOOL_FALSE == wmt_core_ic_ops_check(p_ops)) { -+ WMT_ERR_FUNC -+ ("chip id(0x%x) with null operation fp: init(0x%p), deinit(0x%p), pin_ctrl(0x%p), ver_chk(0x%p)\n", -+ chipid, p_ops->sw_init, p_ops->sw_deinit, p_ops->ic_pin_ctrl, p_ops->ic_ver_check); -+ return -4; -+ } -+ WMT_DBG_FUNC("chip id(0x%x) fp: init(0x%p), deinit(0x%p), pin_ctrl(0x%p), ver_chk(0x%p)\n", -+ chipid, p_ops->sw_init, p_ops->sw_deinit, p_ops->ic_pin_ctrl, p_ops->ic_ver_check); -+ -+ wmt_ic_ops_soc.icId = chipid; -+ WMT_DBG_FUNC("wmt_ic_ops_soc.icId(0x%x)\n", wmt_ic_ops_soc.icId); -+ iret = p_ops->ic_ver_check(); -+ if (iret) { -+ WMT_ERR_FUNC("chip id(0x%x) ver_check error:%d\n", chipid, iret); -+ return -5; -+ } -+ -+ WMT_DBG_FUNC("chip id(0x%x) ver_check ok\n", chipid); -+ gMtkWmtCtx.p_ic_ops = p_ops; -+ return 0; -+} -+ -+static INT32 opfunc_hif_conf(P_WMT_OP pWmtOp) -+{ -+ if (!(pWmtOp->u4InfoBit & WMT_OP_HIF_BIT)) { -+ WMT_ERR_FUNC("WMT-CORE: no HIF_BIT in WMT_OP!\n"); -+ return -1; -+ } -+ -+ if (gMtkWmtCtx.wmtInfoBit & WMT_OP_HIF_BIT) { -+ WMT_ERR_FUNC("WMT-CORE: WMT HIF already exist. overwrite! old (%d), new(%d))\n", -+ gMtkWmtCtx.wmtHifConf.hifType, pWmtOp->au4OpData[0]); -+ } else { -+ gMtkWmtCtx.wmtInfoBit |= WMT_OP_HIF_BIT; -+ WMT_ERR_FUNC("WMT-CORE: WMT HIF info added\n"); -+ } -+ -+ osal_memcpy(&gMtkWmtCtx.wmtHifConf, &pWmtOp->au4OpData[0], osal_sizeof(gMtkWmtCtx.wmtHifConf)); -+ return 0; -+ -+} -+ -+static INT32 opfunc_pwr_on(P_WMT_OP pWmtOp) -+{ -+ -+ INT32 iRet; -+ unsigned long ctrlPa1; -+ unsigned long ctrlPa2; -+ INT32 retry = WMT_PWRON_RTY_DFT; -+ -+ if (DRV_STS_POWER_OFF != gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT]) { -+ WMT_ERR_FUNC("WMT-CORE: already powered on, WMT DRV_STS_[0x%x]\n", -+ gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT]); -+ osal_assert(0); -+ return -1; -+ } -+ /* TODO: [FixMe][GeorgeKuo]: clarify the following is reqiured or not! */ -+ if (pWmtOp->u4InfoBit & WMT_OP_HIF_BIT) -+ opfunc_hif_conf(pWmtOp); -+ -+pwr_on_rty: -+ /* power on control */ -+ ctrlPa1 = 0; -+ ctrlPa2 = 0; -+ iRet = wmt_core_ctrl(WMT_CTRL_HW_PWR_ON, &ctrlPa1, &ctrlPa2); -+ if (iRet) { -+ WMT_ERR_FUNC("WMT-CORE: WMT_CTRL_HW_PWR_ON fail iRet(%d)\n", iRet); -+ if (0 == retry--) { -+ WMT_INFO_FUNC("WMT-CORE: retry (%d)\n", retry); -+ goto pwr_on_rty; -+ } -+ return -1; -+ } -+ gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT] = DRV_STS_POWER_ON; -+ -+ /* init stp */ -+ iRet = wmt_core_stp_init(); -+ if (iRet) { -+ WMT_ERR_FUNC("WMT-CORE: wmt_core_stp_init fail (%d)\n", iRet); -+ osal_assert(0); -+ -+ /* deinit stp */ -+ iRet = wmt_core_stp_deinit(); -+ iRet = opfunc_pwr_off(pWmtOp); -+ if (iRet) -+ WMT_ERR_FUNC("WMT-CORE: opfunc_pwr_off fail during pwr_on retry\n"); -+ -+ if (0 < retry--) { -+ WMT_INFO_FUNC("WMT-CORE: retry (%d)\n", retry); -+ goto pwr_on_rty; -+ } -+ iRet = -2; -+ return iRet; -+ } -+ -+ WMT_DBG_FUNC("WMT-CORE: WMT [FUNC_ON]\n"); -+ gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT] = DRV_STS_FUNC_ON; -+ -+ /* What to do when state is changed from POWER_OFF to POWER_ON? -+ * 1. STP driver does s/w reset -+ * 2. UART does 0xFF wake up -+ * 3. SDIO does re-init command(changed to trigger by host) -+ */ -+ return iRet; -+ -+} -+ -+static INT32 opfunc_pwr_off(P_WMT_OP pWmtOp) -+{ -+ -+ INT32 iRet; -+ unsigned long ctrlPa1; -+ unsigned long ctrlPa2; -+ -+ if (DRV_STS_POWER_OFF == gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT]) { -+ WMT_WARN_FUNC("WMT-CORE: WMT already off, WMT DRV_STS_[0x%x]\n", -+ gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT]); -+ osal_assert(0); -+ return -1; -+ } -+ if (MTK_WCN_BOOL_FALSE == g_pwr_off_flag) { -+ WMT_WARN_FUNC("CONNSYS power off be disabled, maybe need trigger core dump!\n"); -+ osal_assert(0); -+ return -2; -+ } -+ -+ /* wmt and stp are initialized successfully */ -+ if (DRV_STS_FUNC_ON == gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT]) { -+ iRet = wmt_core_stp_deinit(); -+ if (iRet) { -+ WMT_WARN_FUNC("wmt_core_stp_deinit fail (%d)\n", iRet); -+ /*should let run to power down chip */ -+ } -+ } -+ gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT] = DRV_STS_POWER_ON; -+ -+ /* power off control */ -+ ctrlPa1 = 0; -+ ctrlPa2 = 0; -+ iRet = wmt_core_ctrl(WMT_CTRL_HW_PWR_OFF, &ctrlPa1, &ctrlPa2); -+ if (iRet) -+ WMT_WARN_FUNC("HW_PWR_OFF fail (%d)\n", iRet); -+ WMT_WARN_FUNC("HW_PWR_OFF ok\n"); -+ -+ /*anyway, set to POWER_OFF state */ -+ gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT] = DRV_STS_POWER_OFF; -+ return iRet; -+ -+} -+ -+static INT32 opfunc_func_on(P_WMT_OP pWmtOp) -+{ -+ INT32 iRet = -1; -+ INT32 iPwrOffRet = -1; -+ UINT32 drvType; -+ -+ drvType = pWmtOp->au4OpData[0]; -+ -+ /* Check abnormal type */ -+ if (WMTDRV_TYPE_COREDUMP < drvType) { -+ WMT_ERR_FUNC("abnormal Fun(%d)\n", drvType); -+ osal_assert(0); -+ return -1; -+ } -+ -+ /* Check abnormal state */ -+ if ((DRV_STS_POWER_OFF > gMtkWmtCtx.eDrvStatus[drvType]) -+ || (DRV_STS_MAX <= gMtkWmtCtx.eDrvStatus[drvType])) { -+ WMT_ERR_FUNC("func(%d) status[0x%x] abnormal\n", drvType, gMtkWmtCtx.eDrvStatus[drvType]); -+ osal_assert(0); -+ return -2; -+ } -+ -+ /* check if func already on */ -+ if (DRV_STS_FUNC_ON == gMtkWmtCtx.eDrvStatus[drvType]) { -+ WMT_WARN_FUNC("func(%d) already on\n", drvType); -+ return 0; -+ } -+ /*enable power off flag, if flag=0, power off connsys will not be executed */ -+ mtk_wcn_set_connsys_power_off_flag(MTK_WCN_BOOL_TRUE); -+ /* check if chip power on is needed */ -+ if (DRV_STS_FUNC_ON != gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT]) { -+ iRet = opfunc_pwr_on(pWmtOp); -+ -+ if (iRet) { -+ WMT_ERR_FUNC("func(%d) pwr_on fail(%d)\n", drvType, iRet); -+ osal_assert(0); -+ -+ /* check all sub-func and do power off */ -+ return -3; -+ } -+ } -+ -+ if (WMTDRV_TYPE_WMT > drvType) { -+ if (NULL != gpWmtFuncOps[drvType] && NULL != gpWmtFuncOps[drvType]->func_on) { -+ iRet = (*(gpWmtFuncOps[drvType]->func_on)) (gMtkWmtCtx.p_ic_ops, wmt_conf_get_cfg()); -+ if (0 != iRet) -+ gMtkWmtCtx.eDrvStatus[drvType] = DRV_STS_POWER_OFF; -+ else -+ gMtkWmtCtx.eDrvStatus[drvType] = DRV_STS_FUNC_ON; -+ } else { -+ WMT_WARN_FUNC("WMT-CORE: ops for type(%d) not found\n", drvType); -+ iRet = -5; -+ } -+ } else { -+ if (WMTDRV_TYPE_LPBK == drvType) -+ gMtkWmtCtx.eDrvStatus[drvType] = DRV_STS_FUNC_ON; -+ else if (WMTDRV_TYPE_COREDUMP == drvType) -+ gMtkWmtCtx.eDrvStatus[drvType] = DRV_STS_FUNC_ON; -+ iRet = 0; -+ } -+ -+ if (iRet) { -+ WMT_ERR_FUNC("WMT-CORE:type(0x%x) function on failed, ret(%d)\n", drvType, iRet); -+ osal_assert(0); -+ /* FIX-ME:[Chaozhong Liang], Error handling? check subsystem state and do pwr off if necessary? */ -+ /* check all sub-func and do power off */ -+ if ((DRV_STS_POWER_OFF == gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_BT]) && -+ (DRV_STS_POWER_OFF == gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_GPS]) && -+ (DRV_STS_POWER_OFF == gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_FM]) && -+ (DRV_STS_POWER_OFF == gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WIFI]) && -+ (DRV_STS_POWER_OFF == gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_LPBK]) && -+ (DRV_STS_POWER_OFF == gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_COREDUMP])) { -+ WMT_INFO_FUNC("WMT-CORE:Fun(%d) [POWER_OFF] and power down chip\n", drvType); -+ mtk_wcn_wmt_system_state_reset(); -+ -+ iPwrOffRet = opfunc_pwr_off(pWmtOp); -+ if (iPwrOffRet) { -+ WMT_ERR_FUNC("WMT-CORE: wmt_pwr_off fail(%d) when turn off func(%d)\n", iPwrOffRet, -+ drvType); -+ osal_assert(0); -+ } -+ } -+ return iRet; -+ } -+ -+ wmt_core_dump_func_state("AF FUNC ON"); -+ -+ return 0; -+} -+ -+static INT32 opfunc_func_off(P_WMT_OP pWmtOp) -+{ -+ -+ INT32 iRet = -1; -+ UINT32 drvType; -+ -+ drvType = pWmtOp->au4OpData[0]; -+ /* Check abnormal type */ -+ if (WMTDRV_TYPE_COREDUMP < drvType) { -+ WMT_ERR_FUNC("WMT-CORE: abnormal Fun(%d) in wmt_func_off\n", drvType); -+ osal_assert(0); -+ return -1; -+ } -+ -+ /* Check abnormal state */ -+ if (DRV_STS_MAX <= gMtkWmtCtx.eDrvStatus[drvType]) { -+ WMT_ERR_FUNC("WMT-CORE: Fun(%d) DRV_STS_[0x%x] abnormal in wmt_func_off\n", -+ drvType, gMtkWmtCtx.eDrvStatus[drvType]); -+ osal_assert(0); -+ return -2; -+ } -+ -+ if (DRV_STS_FUNC_ON != gMtkWmtCtx.eDrvStatus[drvType]) { -+ WMT_WARN_FUNC("WMT-CORE: Fun(%d) DRV_STS_[0x%x] already non-FUN_ON in wmt_func_off\n", -+ drvType, gMtkWmtCtx.eDrvStatus[drvType]); -+ /* needs to check 4 subsystem's state? */ -+ return 0; -+ } else if (WMTDRV_TYPE_WMT > drvType) { -+ if (NULL != gpWmtFuncOps[drvType] && NULL != gpWmtFuncOps[drvType]->func_off) { -+ iRet = (*(gpWmtFuncOps[drvType]->func_off)) (gMtkWmtCtx.p_ic_ops, wmt_conf_get_cfg()); -+ } else { -+ WMT_WARN_FUNC("WMT-CORE: ops for type(%d) not found\n", drvType); -+ iRet = -3; -+ } -+ } else { -+ if (WMTDRV_TYPE_LPBK == drvType) -+ gMtkWmtCtx.eDrvStatus[drvType] = DRV_STS_POWER_OFF; -+ else if (WMTDRV_TYPE_COREDUMP == drvType) -+ gMtkWmtCtx.eDrvStatus[drvType] = DRV_STS_POWER_OFF; -+ iRet = 0; -+ } -+ -+ /* shall we put device state to POWER_OFF state when fail? */ -+ gMtkWmtCtx.eDrvStatus[drvType] = DRV_STS_POWER_OFF; -+ -+ if (iRet) { -+ WMT_ERR_FUNC("WMT-CORE: type(0x%x) function off failed, ret(%d)\n", drvType, iRet); -+ osal_assert(0); -+ /* no matter subsystem function control fail or not, -+ *chip should be powered off when no subsystem is active -+ */ -+ /* return iRet; */ -+ } -+ -+ /* check all sub-func and do power off */ -+ if ((DRV_STS_POWER_OFF == gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_BT]) && -+ (DRV_STS_POWER_OFF == gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_GPS]) && -+ (DRV_STS_POWER_OFF == gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_FM]) && -+ (DRV_STS_POWER_OFF == gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WIFI]) && -+ (DRV_STS_POWER_OFF == gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_LPBK]) && -+ (DRV_STS_POWER_OFF == gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_COREDUMP])) { -+ WMT_INFO_FUNC("WMT-CORE:Fun(%d) [POWER_OFF] and power down chip\n", drvType); -+ -+ iRet = opfunc_pwr_off(pWmtOp); -+ if (iRet) { -+ WMT_ERR_FUNC("WMT-CORE: wmt_pwr_off fail(%d) when turn off func(%d)\n", iRet, drvType); -+ osal_assert(0); -+ } -+ } -+ -+ wmt_core_dump_func_state("AF FUNC OFF"); -+ return iRet; -+} -+ -+/* TODO:[ChangeFeature][George] is this OP obsoleted? */ -+static INT32 opfunc_reg_rw(P_WMT_OP pWmtOp) -+{ -+ INT32 iret; -+ -+ if (DRV_STS_FUNC_ON != gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT]) { -+ WMT_ERR_FUNC("reg_rw when WMT is powered off\n"); -+ return -1; -+ } -+ iret = wmt_core_reg_rw_raw(pWmtOp->au4OpData[0], -+ pWmtOp->au4OpData[1], (PUINT32) pWmtOp->au4OpData[2], pWmtOp->au4OpData[3]); -+ -+ return iret; -+} -+ -+static INT32 opfunc_exit(P_WMT_OP pWmtOp) -+{ -+ /* TODO: [FixMe][George] is ok to leave this function empty??? */ -+ WMT_WARN_FUNC("EMPTY FUNCTION\n"); -+ return 0; -+} -+ -+static INT32 opfunc_pwr_sv(P_WMT_OP pWmtOp) -+{ -+ INT32 ret = -1; -+ UINT32 u4_result = 0; -+ UINT32 evt_len; -+ UINT8 evt_buf[16] = { 0 }; -+ unsigned long ctrlPa1 = 0; -+ unsigned long ctrlPa2 = 0; -+ -+ typedef INT32(*STP_PSM_CB) (INT32); -+ STP_PSM_CB psm_cb = NULL; -+ -+ if (SLEEP == pWmtOp->au4OpData[0]) { -+ WMT_DBG_FUNC("**** Send sleep command\n"); -+ /* mtk_wcn_stp_set_psm_state(ACT_INACT); */ -+ /* (*kal_stp_flush_rx)(WMT_TASK_INDX); */ -+ ret = wmt_core_tx((PUINT8) &WMT_SLEEP_CMD[0], sizeof(WMT_SLEEP_CMD), &u4_result, 0); -+ if (ret || (u4_result != sizeof(WMT_SLEEP_CMD))) { -+ WMT_ERR_FUNC("wmt_core: SLEEP_CMD ret(%d) cmd len err(%d, %d) ", ret, u4_result, -+ sizeof(WMT_SLEEP_CMD)); -+ goto pwr_sv_done; -+ } -+ -+ evt_len = sizeof(WMT_SLEEP_EVT); -+ ret = wmt_core_rx(evt_buf, evt_len, &u4_result); -+ if (ret || (u4_result != evt_len)) { -+ unsigned long type = WMTDRV_TYPE_WMT; -+ unsigned long reason = 33; -+ unsigned long ctrlpa = 1; -+ -+ wmt_core_rx_flush(WMT_TASK_INDX); -+ WMT_ERR_FUNC("wmt_core: read SLEEP_EVT fail(%d) len(%d, %d)", ret, u4_result, evt_len); -+ mtk_wcn_stp_dbg_dump_package(); -+ ret = wmt_core_ctrl(WMT_CTRL_EVT_PARSER, &ctrlpa, 0); -+ if (!ret) { /* parser ok */ -+ reason = 38; /* host schedule issue reason code */ -+ WMT_WARN_FUNC("This evt error may be caused by system schedule issue\n"); -+ } -+ wmt_core_ctrl(WMT_CTRL_EVT_ERR_TRG_ASSERT, &type, &reason); -+ goto pwr_sv_done; -+ } -+ -+ if (osal_memcmp(evt_buf, WMT_SLEEP_EVT, sizeof(WMT_SLEEP_EVT)) != 0) { -+ WMT_ERR_FUNC("wmt_core: compare WMT_SLEEP_EVT error\n"); -+ wmt_core_rx_flush(WMT_TASK_INDX); -+ WMT_ERR_FUNC("wmt_core: rx(%d):[%02X,%02X,%02X,%02X,%02X,%02X]\n", -+ u4_result, -+ evt_buf[0], -+ evt_buf[1], -+ evt_buf[2], -+ evt_buf[3], -+ evt_buf[4], -+ evt_buf[5]); -+ WMT_ERR_FUNC("wmt_core: exp(%d):[%02X,%02X,%02X,%02X,%02X,%02X]\n", -+ sizeof(WMT_SLEEP_EVT), -+ WMT_SLEEP_EVT[0], -+ WMT_SLEEP_EVT[1], -+ WMT_SLEEP_EVT[2], -+ WMT_SLEEP_EVT[3], -+ WMT_SLEEP_EVT[4], -+ WMT_SLEEP_EVT[5]); -+ mtk_wcn_stp_dbg_dump_package(); -+ goto pwr_sv_done; -+ } else { -+ WMT_DBG_FUNC("Send sleep command OK!\n"); -+ } -+ } else if (pWmtOp->au4OpData[0] == WAKEUP) { -+ WMT_DBG_FUNC("wakeup connsys by btif"); -+ -+ ret = wmt_core_ctrl(WMT_CTRL_SOC_WAKEUP_CONSYS, &ctrlPa1, &ctrlPa2); -+ if (ret) { -+ WMT_ERR_FUNC("wmt-core:WAKEUP_CONSYS by BTIF fail(%d)", ret); -+ goto pwr_sv_done; -+ } -+#if 0 -+ WMT_DBG_FUNC("**** Send wakeup command\n"); -+ ret = wmt_core_tx(WMT_WAKEUP_CMD, sizeof(WMT_WAKEUP_CMD), &u4_result, 1); -+ -+ if (ret || (u4_result != sizeof(WMT_WAKEUP_CMD))) { -+ wmt_core_rx_flush(WMT_TASK_INDX); -+ WMT_ERR_FUNC("wmt_core: WAKEUP_CMD ret(%d) cmd len err(%d, %d) ", ret, u4_result, -+ sizeof(WMT_WAKEUP_CMD)); -+ goto pwr_sv_done; -+ } -+#endif -+ evt_len = sizeof(WMT_WAKEUP_EVT); -+ ret = wmt_core_rx(evt_buf, evt_len, &u4_result); -+ if (ret || (u4_result != evt_len)) { -+ unsigned long type = WMTDRV_TYPE_WMT; -+ unsigned long reason = 34; -+ unsigned long ctrlpa = 2; -+ -+ WMT_ERR_FUNC("wmt_core: read WAKEUP_EVT fail(%d) len(%d, %d)", ret, u4_result, evt_len); -+ mtk_wcn_stp_dbg_dump_package(); -+ ret = wmt_core_ctrl(WMT_CTRL_EVT_PARSER, &ctrlpa, 0); -+ if (!ret) { /* parser ok */ -+ reason = 39; /* host schedule issue reason code */ -+ WMT_WARN_FUNC("This evt error may be caused by system schedule issue\n"); -+ } -+ wmt_core_ctrl(WMT_CTRL_EVT_ERR_TRG_ASSERT, &type, &reason); -+ goto pwr_sv_done; -+ } -+ -+ if (osal_memcmp(evt_buf, WMT_WAKEUP_EVT, sizeof(WMT_WAKEUP_EVT)) != 0) { -+ WMT_ERR_FUNC("wmt_core: compare WMT_WAKEUP_EVT error\n"); -+ wmt_core_rx_flush(WMT_TASK_INDX); -+ WMT_ERR_FUNC("wmt_core: rx(%d):[%02X,%02X,%02X,%02X,%02X,%02X]\n", -+ u4_result, -+ evt_buf[0], -+ evt_buf[1], -+ evt_buf[2], -+ evt_buf[3], -+ evt_buf[4], -+ evt_buf[5]); -+ WMT_ERR_FUNC("wmt_core: exp(%d):[%02X,%02X,%02X,%02X,%02X,%02X]\n", -+ sizeof(WMT_WAKEUP_EVT), -+ WMT_WAKEUP_EVT[0], -+ WMT_WAKEUP_EVT[1], -+ WMT_WAKEUP_EVT[2], -+ WMT_WAKEUP_EVT[3], -+ WMT_WAKEUP_EVT[4], -+ WMT_WAKEUP_EVT[5]); -+ mtk_wcn_stp_dbg_dump_package(); -+ goto pwr_sv_done; -+ } else { -+ WMT_DBG_FUNC("Send wakeup command OK!\n"); -+ } -+ } else if (pWmtOp->au4OpData[0] == HOST_AWAKE) { -+ -+ WMT_DBG_FUNC("**** Send host awake command\n"); -+ -+ psm_cb = (STP_PSM_CB) pWmtOp->au4OpData[1]; -+ /* (*kal_stp_flush_rx)(WMT_TASK_INDX); */ -+ ret = wmt_core_tx((PUINT8) WMT_HOST_AWAKE_CMD, sizeof(WMT_HOST_AWAKE_CMD), &u4_result, 0); -+ if (ret || (u4_result != sizeof(WMT_HOST_AWAKE_CMD))) { -+ WMT_ERR_FUNC("wmt_core: HOST_AWAKE_CMD ret(%d) cmd len err(%d, %d) ", ret, u4_result, -+ sizeof(WMT_HOST_AWAKE_CMD)); -+ goto pwr_sv_done; -+ } -+ -+ evt_len = sizeof(WMT_HOST_AWAKE_EVT); -+ ret = wmt_core_rx(evt_buf, evt_len, &u4_result); -+ if (ret || (u4_result != evt_len)) { -+ unsigned long type = WMTDRV_TYPE_WMT; -+ unsigned long reason = 35; -+ unsigned long ctrlpa = 3; -+ -+ wmt_core_rx_flush(WMT_TASK_INDX); -+ WMT_ERR_FUNC("wmt_core: read HOST_AWAKE_EVT fail(%d) len(%d, %d)", ret, u4_result, evt_len); -+ mtk_wcn_stp_dbg_dump_package(); -+ ret = wmt_core_ctrl(WMT_CTRL_EVT_PARSER, &ctrlpa, 0); -+ if (!ret) { /* parser ok */ -+ reason = 40; /* host schedule issue reason code */ -+ WMT_WARN_FUNC("This evt error may be caused by system schedule issue\n"); -+ } -+ wmt_core_ctrl(WMT_CTRL_EVT_ERR_TRG_ASSERT, &type, &reason); -+ goto pwr_sv_done; -+ } -+ -+ if (osal_memcmp(evt_buf, WMT_HOST_AWAKE_EVT, sizeof(WMT_HOST_AWAKE_EVT)) != 0) { -+ WMT_ERR_FUNC("wmt_core: compare WMT_HOST_AWAKE_EVT error\n"); -+ wmt_core_rx_flush(WMT_TASK_INDX); -+ WMT_ERR_FUNC("wmt_core: rx(%d):[%02X,%02X,%02X,%02X,%02X,%02X]\n", -+ u4_result, -+ evt_buf[0], -+ evt_buf[1], -+ evt_buf[2], -+ evt_buf[3], -+ evt_buf[4], -+ evt_buf[5]); -+ WMT_ERR_FUNC("wmt_core: exp(%d):[%02X,%02X,%02X,%02X,%02X,%02X]\n", -+ sizeof(WMT_HOST_AWAKE_EVT), -+ WMT_HOST_AWAKE_EVT[0], -+ WMT_HOST_AWAKE_EVT[1], -+ WMT_HOST_AWAKE_EVT[2], -+ WMT_HOST_AWAKE_EVT[3], -+ WMT_HOST_AWAKE_EVT[4], -+ WMT_HOST_AWAKE_EVT[5]); -+ mtk_wcn_stp_dbg_dump_package(); -+ /* goto pwr_sv_done; */ -+ } else { -+ WMT_DBG_FUNC("Send host awake command OK!\n"); -+ } -+ } -+pwr_sv_done: -+ -+ if (pWmtOp->au4OpData[0] < STP_PSM_MAX_ACTION) { -+ psm_cb = (STP_PSM_CB) pWmtOp->au4OpData[1]; -+ WMT_DBG_FUNC("Do STP-CB! %d %p / %p\n", pWmtOp->au4OpData[0], (PVOID) pWmtOp->au4OpData[1], -+ (PVOID) psm_cb); -+ if (NULL != psm_cb) { -+ psm_cb(pWmtOp->au4OpData[0]); -+ } else { -+ WMT_ERR_FUNC("fatal error !!!, psm_cb = %p, god, someone must have corrupted our memory.\n", -+ psm_cb); -+ } -+ } -+ -+ return ret; -+} -+ -+static INT32 opfunc_dsns(P_WMT_OP pWmtOp) -+{ -+ -+ INT32 iRet = -1; -+ UINT32 u4Res; -+ UINT32 evtLen; -+ UINT8 evtBuf[16] = { 0 }; -+ -+ WMT_DSNS_CMD[4] = (UINT8) pWmtOp->au4OpData[0]; -+ WMT_DSNS_CMD[5] = (UINT8) pWmtOp->au4OpData[1]; -+ -+ /* send command */ -+ /* iRet = (*kal_stp_tx)(WMT_DSNS_CMD, osal_sizeof(WMT_DSNS_CMD), &u4Res); */ -+ iRet = wmt_core_tx((PUINT8) WMT_DSNS_CMD, osal_sizeof(WMT_DSNS_CMD), &u4Res, MTK_WCN_BOOL_FALSE); -+ if (iRet || (u4Res != osal_sizeof(WMT_DSNS_CMD))) { -+ WMT_ERR_FUNC("WMT-CORE: DSNS_CMD iRet(%d) cmd len err(%d, %d)\n", iRet, u4Res, -+ osal_sizeof(WMT_DSNS_CMD)); -+ return iRet; -+ } -+ -+ evtLen = osal_sizeof(WMT_DSNS_EVT); -+ -+ iRet = wmt_core_rx(evtBuf, evtLen, &u4Res); -+ if (iRet || (u4Res != evtLen)) { -+ WMT_ERR_FUNC("WMT-CORE: read DSNS_EVT fail(%d) len(%d, %d)\n", iRet, u4Res, evtLen); -+ mtk_wcn_stp_dbg_dump_package(); -+ return iRet; -+ } -+ -+ if (osal_memcmp(evtBuf, WMT_DSNS_EVT, osal_sizeof(WMT_DSNS_EVT)) != 0) { -+ WMT_ERR_FUNC("WMT-CORE: compare WMT_DSNS_EVT error\n"); -+ WMT_ERR_FUNC("WMT-CORE: rx(%d):[%02X,%02X,%02X,%02X,%02X] exp(%d):[%02X,%02X,%02X,%02X,%02X]\n", -+ u4Res, evtBuf[0], evtBuf[1], evtBuf[2], evtBuf[3], evtBuf[4], -+ osal_sizeof(WMT_DSNS_EVT), WMT_DSNS_EVT[0], WMT_DSNS_EVT[1], WMT_DSNS_EVT[2], -+ WMT_DSNS_EVT[3], WMT_DSNS_EVT[4]); -+ } else { -+ WMT_INFO_FUNC("Send WMT_DSNS_CMD command OK!\n"); -+ } -+ -+ return iRet; -+} -+ -+#if CFG_CORE_INTERNAL_TXRX -+INT32 wmt_core_lpbk_do_stp_init(void) -+{ -+ INT32 iRet = 0; -+ unsigned long ctrlPa1 = 0; -+ unsigned long ctrlPa2 = 0; -+ -+ ctrlPa1 = 0; -+ ctrlPa2 = 0; -+ iRet = wmt_core_ctrl(WMT_CTRL_STP_OPEN, &ctrlPa1, &ctrlPa2); -+ if (iRet) { -+ WMT_ERR_FUNC("WMT-CORE: wmt open stp\n"); -+ return -1; -+ } -+ -+ ctrlPa1 = WMT_STP_CONF_MODE; -+ ctrlPa2 = MTKSTP_BTIF_MAND_MODE; -+ iRet += wmt_core_ctrl(WMT_CTRL_STP_CONF, &ctrlPa1, &ctrlPa2); -+ -+ ctrlPa1 = WMT_STP_CONF_EN; -+ ctrlPa2 = 1; -+ iRet += wmt_core_ctrl(WMT_CTRL_STP_CONF, &ctrlPa1, &ctrlPa2); -+ if (iRet) { -+ WMT_ERR_FUNC("WMT-CORE: stp_init <1><2> fail:%d\n", iRet); -+ return -2; -+ } -+} -+ -+INT32 wmt_core_lpbk_do_stp_deinit(void) -+{ -+ INT32 iRet = 0; -+ unsigned long ctrlPa1 = 0; -+ unsigned long ctrlPa2 = 0; -+ -+ ctrlPa1 = 0; -+ ctrlPa2 = 0; -+ iRet = wmt_core_ctrl(WMT_CTRL_STP_CLOSE, &ctrlPa1, &ctrlPa2); -+ if (iRet) { -+ WMT_ERR_FUNC("WMT-CORE: wmt open stp\n"); -+ return -1; -+ } -+ -+ return 0; -+} -+#endif -+static INT32 opfunc_lpbk(P_WMT_OP pWmtOp) -+{ -+ -+ INT32 iRet; -+ UINT32 u4WrittenSize = 0; -+ UINT32 u4ReadSize = 0; -+ UINT32 buf_length = 0; -+ UINT32 *pbuffer = NULL; -+ UINT16 len_in_cmd; -+ -+ /* UINT32 offset; */ -+ UINT8 WMT_TEST_LPBK_CMD[] = { 0x1, 0x2, 0x0, 0x0, 0x7 }; -+ UINT8 WMT_TEST_LPBK_EVT[] = { 0x2, 0x2, 0x0, 0x0, 0x0 }; -+ -+ /* UINT8 lpbk_buf[1024 + 5] = {0}; */ -+ MTK_WCN_BOOL fgFail; -+ -+ buf_length = pWmtOp->au4OpData[0]; /* packet length */ -+ pbuffer = (VOID *) pWmtOp->au4OpData[1]; /* packet buffer pointer */ -+ WMT_DBG_FUNC("WMT-CORE: -->wmt_do_lpbk\n"); -+ -+#if 0 -+ osal_memcpy(&WMT_TEST_LPBK_EVT[0], &WMT_TEST_LPBK_CMD[0], osal_sizeof(WMT_TEST_LPBK_CMD)); -+#endif -+#if !CFG_CORE_INTERNAL_TXRX -+ /*check if WMTDRV_TYPE_LPBK function is already on */ -+ if (DRV_STS_FUNC_ON != gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_LPBK] -+ || buf_length + osal_sizeof(WMT_TEST_LPBK_CMD) > osal_sizeof(gLpbkBuf)) { -+ WMT_ERR_FUNC("WMT-CORE: abnormal LPBK in wmt_do_lpbk\n"); -+ osal_assert(0); -+ return -2; -+ } -+#endif -+ /*package loopback for STP */ -+ -+ /* init buffer */ -+ osal_memset(gLpbkBuf, 0, osal_sizeof(gLpbkBuf)); -+ -+ len_in_cmd = buf_length + 1; /* add flag field */ -+ -+ osal_memcpy(&WMT_TEST_LPBK_CMD[2], &len_in_cmd, 2); -+ osal_memcpy(&WMT_TEST_LPBK_EVT[2], &len_in_cmd, 2); -+ -+ /* wmt cmd */ -+ osal_memcpy(gLpbkBuf, WMT_TEST_LPBK_CMD, osal_sizeof(WMT_TEST_LPBK_CMD)); -+ osal_memcpy(gLpbkBuf + osal_sizeof(WMT_TEST_LPBK_CMD), pbuffer, buf_length); -+ -+ do { -+ fgFail = MTK_WCN_BOOL_TRUE; -+ /*send packet through STP */ -+ -+ /* iRet = (*kal_stp_tx)( -+ *(PUINT8)gLpbkBuf, -+ *osal_sizeof(WMT_TEST_LPBK_CMD) + buf_length, -+ *&u4WrittenSize); -+ */ -+ iRet = wmt_core_tx((PUINT8) gLpbkBuf, -+ (osal_sizeof(WMT_TEST_LPBK_CMD) + buf_length), -+ &u4WrittenSize, -+ MTK_WCN_BOOL_FALSE); -+ if (iRet) { -+ WMT_ERR_FUNC("opfunc_lpbk wmt_core_tx failed\n"); -+ break; -+ } -+ WMT_INFO_FUNC("opfunc_lpbk wmt_core_tx OK\n"); -+ -+ /*receive firmware response from STP */ -+ iRet = wmt_core_rx((PUINT8) gLpbkBuf, (osal_sizeof(WMT_TEST_LPBK_EVT) + buf_length), &u4ReadSize); -+ if (iRet) { -+ WMT_ERR_FUNC("opfunc_lpbk wmt_core_rx failed\n"); -+ break; -+ } -+ WMT_INFO_FUNC("opfunc_lpbk wmt_core_rx OK\n"); -+ /*check if loopback response ok or not */ -+ if (u4ReadSize != (osal_sizeof(WMT_TEST_LPBK_CMD) + buf_length)) { -+ WMT_ERR_FUNC("lpbk event read size wrong(%d, %d)\n", u4ReadSize, -+ (osal_sizeof(WMT_TEST_LPBK_CMD) + buf_length)); -+ break; -+ } -+ WMT_INFO_FUNC("lpbk event read size right(%d, %d)\n", u4ReadSize, -+ (osal_sizeof(WMT_TEST_LPBK_CMD) + buf_length)); -+ -+ if (osal_memcmp(WMT_TEST_LPBK_EVT, gLpbkBuf, osal_sizeof(WMT_TEST_LPBK_EVT))) { -+ WMT_ERR_FUNC("WMT-CORE WMT_TEST_LPBK_EVT error! read len %d [%02x,%02x,%02x,%02x,%02x]\n", -+ (INT32) u4ReadSize, gLpbkBuf[0], gLpbkBuf[1], gLpbkBuf[2], gLpbkBuf[3], gLpbkBuf[4] -+ ); -+ break; -+ } -+ pWmtOp->au4OpData[0] = u4ReadSize - osal_sizeof(WMT_TEST_LPBK_EVT); -+ osal_memcpy((VOID *) pWmtOp->au4OpData[1], gLpbkBuf + osal_sizeof(WMT_TEST_LPBK_CMD), buf_length); -+ fgFail = MTK_WCN_BOOL_FALSE; -+ } while (0); -+ /*return result */ -+ /* WMT_DBG_FUNC("WMT-CORE: <--wmt_do_lpbk, fgFail = %d\n", fgFail); */ -+ return fgFail; -+ -+} -+ -+static INT32 opfunc_cmd_test(P_WMT_OP pWmtOp) -+{ -+ -+ INT32 iRet = 0; -+ UINT32 cmdNo = 0; -+ UINT32 cmdNoPa = 0; -+ -+ UINT8 tstCmd[64]; -+ UINT8 tstEvt[64]; -+ UINT8 tstEvtTmp[64]; -+ UINT32 u4Res; -+ SIZE_T tstCmdSz = 0; -+ SIZE_T tstEvtSz = 0; -+ -+ UINT8 *pRes = NULL; -+ UINT32 resBufRoom = 0; -+ /*test command list */ -+ /*1 */ -+ UINT8 WMT_ASSERT_CMD[] = { 0x01, 0x02, 0x01, 0x00, 0x08 }; -+ UINT8 WMT_ASSERT_EVT[] = { 0x02, 0x02, 0x00, 0x00, 0x00 }; -+ UINT8 WMT_NOACK_CMD[] = { 0x01, 0x02, 0x01, 0x00, 0x0A }; -+ UINT8 WMT_NOACK_EVT[] = { 0x02, 0x02, 0x00, 0x00, 0x00 }; -+ UINT8 WMT_WARNRST_CMD[] = { 0x01, 0x02, 0x01, 0x00, 0x0B }; -+ UINT8 WMT_WARNRST_EVT[] = { 0x02, 0x02, 0x00, 0x00, 0x00 }; -+ UINT8 WMT_FWLOGTST_CMD[] = { 0x01, 0x02, 0x01, 0x00, 0x0C }; -+ UINT8 WMT_FWLOGTST_EVT[] = { 0x02, 0x02, 0x00, 0x00, 0x00 }; -+ -+ UINT8 WMT_EXCEPTION_CMD[] = { 0x01, 0x02, 0x01, 0x00, 0x09 }; -+ UINT8 WMT_EXCEPTION_EVT[] = { 0x02, 0x02, 0x00, 0x00, 0x00 }; -+ /*2 */ -+ UINT8 WMT_COEXDBG_CMD[] = { 0x01, 0x10, 0x02, 0x00, -+ 0x08, -+ 0xAA /*Debugging Parameter */ -+ }; -+ UINT8 WMT_COEXDBG_1_EVT[] = { 0x02, 0x10, 0x05, 0x00, -+ 0x00, -+ 0xAA, 0xAA, 0xAA, 0xAA /*event content */ -+ }; -+ UINT8 WMT_COEXDBG_2_EVT[] = { 0x02, 0x10, 0x07, 0x00, -+ 0x00, -+ 0xAA, 0xAA, 0xAA, 0xAA, 0xBB, 0xBB /*event content */ -+ }; -+ UINT8 WMT_COEXDBG_3_EVT[] = { 0x02, 0x10, 0x0B, 0x00, -+ 0x00, -+ 0xAA, 0xAA, 0xAA, 0xAA, 0xBB, 0xBB, 0xBB, 0xBB /*event content */ -+ }; -+ /*test command list -end */ -+ -+ cmdNo = pWmtOp->au4OpData[0]; -+ -+ WMT_INFO_FUNC("Send Test command %d!\n", cmdNo); -+ if (cmdNo == 0) { -+ /*dead command */ -+ WMT_INFO_FUNC("Send Assert command !\n"); -+ tstCmdSz = osal_sizeof(WMT_ASSERT_CMD); -+ tstEvtSz = osal_sizeof(WMT_ASSERT_EVT); -+ osal_memcpy(tstCmd, WMT_ASSERT_CMD, tstCmdSz); -+ osal_memcpy(tstEvt, WMT_ASSERT_EVT, tstEvtSz); -+ } else if (cmdNo == 1) { -+ /*dead command */ -+ WMT_INFO_FUNC("Send Exception command !\n"); -+ tstCmdSz = osal_sizeof(WMT_EXCEPTION_CMD); -+ tstEvtSz = osal_sizeof(WMT_EXCEPTION_EVT); -+ osal_memcpy(tstCmd, WMT_EXCEPTION_CMD, tstCmdSz); -+ osal_memcpy(tstEvt, WMT_EXCEPTION_EVT, tstEvtSz); -+ } else if (cmdNo == 2) { -+ cmdNoPa = pWmtOp->au4OpData[1]; -+ pRes = (PUINT8) pWmtOp->au4OpData[2]; -+ resBufRoom = pWmtOp->au4OpData[3]; -+ if (cmdNoPa <= 0xf) { -+ WMT_INFO_FUNC("Send Coexistence Debug command [0x%x]!\n", cmdNoPa); -+ tstCmdSz = osal_sizeof(WMT_COEXDBG_CMD); -+ osal_memcpy(tstCmd, WMT_COEXDBG_CMD, tstCmdSz); -+ if (tstCmdSz > 5) -+ tstCmd[5] = cmdNoPa; -+ -+ /*setup the expected event length */ -+ if (cmdNoPa <= 0x4) { -+ tstEvtSz = osal_sizeof(WMT_COEXDBG_1_EVT); -+ osal_memcpy(tstEvt, WMT_COEXDBG_1_EVT, tstEvtSz); -+ } else if (cmdNoPa == 0x5) { -+ tstEvtSz = osal_sizeof(WMT_COEXDBG_2_EVT); -+ osal_memcpy(tstEvt, WMT_COEXDBG_2_EVT, tstEvtSz); -+ } else if (cmdNoPa >= 0x6 && cmdNoPa <= 0xf) { -+ tstEvtSz = osal_sizeof(WMT_COEXDBG_3_EVT); -+ osal_memcpy(tstEvt, WMT_COEXDBG_3_EVT, tstEvtSz); -+ } else { -+ -+ } -+ } else { -+ WMT_ERR_FUNC("cmdNoPa is wrong\n"); -+ return iRet; -+ } -+ } else if (cmdNo == 3) { -+ /*dead command */ -+ WMT_INFO_FUNC("Send No Ack command !\n"); -+ tstCmdSz = osal_sizeof(WMT_NOACK_CMD); -+ tstEvtSz = osal_sizeof(WMT_NOACK_EVT); -+ osal_memcpy(tstCmd, WMT_NOACK_CMD, tstCmdSz); -+ osal_memcpy(tstEvt, WMT_NOACK_EVT, tstEvtSz); -+ } else if (cmdNo == 4) { -+ /*dead command */ -+ WMT_INFO_FUNC("Send Warm reset command !\n"); -+ tstCmdSz = osal_sizeof(WMT_WARNRST_CMD); -+ tstEvtSz = osal_sizeof(WMT_WARNRST_EVT); -+ osal_memcpy(tstCmd, WMT_WARNRST_CMD, tstCmdSz); -+ osal_memcpy(tstEvt, WMT_WARNRST_EVT, tstEvtSz); -+ } else if (cmdNo == 5) { -+ /*dead command */ -+ WMT_INFO_FUNC("Send f/w log test command !\n"); -+ tstCmdSz = osal_sizeof(WMT_FWLOGTST_CMD); -+ tstEvtSz = osal_sizeof(WMT_FWLOGTST_EVT); -+ osal_memcpy(tstCmd, WMT_FWLOGTST_CMD, tstCmdSz); -+ osal_memcpy(tstEvt, WMT_FWLOGTST_EVT, tstEvtSz); -+ } -+ -+ else { -+ /*Placed youer test WMT command here, easiler to integrate and test with F/W side */ -+ } -+ -+ /* send command */ -+ /* iRet = (*kal_stp_tx)(tstCmd, tstCmdSz, &u4Res); */ -+ iRet = wmt_core_tx((PUINT8) tstCmd, tstCmdSz, &u4Res, MTK_WCN_BOOL_FALSE); -+ if (iRet || (u4Res != tstCmdSz)) { -+ WMT_ERR_FUNC("WMT-CORE: wmt_cmd_test iRet(%d) cmd len err(%d, %d)\n", iRet, u4Res, tstCmdSz); -+ return -1; -+ } -+ -+ if ((cmdNo == 0) || (cmdNo == 1) || cmdNo == 3) { -+ WMT_INFO_FUNC("WMT-CORE: not to rx event for assert command\n"); -+ return 0; -+ } -+ -+ iRet = wmt_core_rx(tstEvtTmp, tstEvtSz, &u4Res); -+ -+ /*Event Post Handling */ -+ if (cmdNo == 2) { -+ WMT_INFO_FUNC("#=========================================================#\n"); -+ WMT_INFO_FUNC("coext debugging id = %d", cmdNoPa); -+ if (tstEvtSz > 5) { -+ wmt_core_dump_data(&tstEvtTmp[5], "coex debugging ", tstEvtSz - 5); -+ } else { -+ /* error log */ -+ WMT_ERR_FUNC("error coex debugging event\n"); -+ } -+ /*put response to buffer for shell to read */ -+ if (pRes != NULL && resBufRoom > 0) { -+ pWmtOp->au4OpData[3] = resBufRoom < tstEvtSz - 5 ? resBufRoom : tstEvtSz - 5; -+ osal_memcpy(pRes, &tstEvtTmp[5], pWmtOp->au4OpData[3]); -+ } else -+ pWmtOp->au4OpData[3] = 0; -+ WMT_INFO_FUNC("#=========================================================#\n"); -+ } -+ -+ return iRet; -+ -+} -+ -+static INT32 opfunc_hw_rst(P_WMT_OP pWmtOp) -+{ -+ -+ INT32 iRet = -1; -+ unsigned long ctrlPa1; -+ unsigned long ctrlPa2; -+ -+ wmt_core_dump_func_state("BE HW RST"); -+ /*-->Reset WMT data structure*/ -+ /* gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_BT] = DRV_STS_POWER_OFF; */ -+ gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_FM] = DRV_STS_POWER_OFF; -+ gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_GPS] = DRV_STS_POWER_OFF; -+ /* gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WIFI] = DRV_STS_POWER_OFF; */ -+ gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_LPBK] = DRV_STS_POWER_OFF; -+ gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_STP] = DRV_STS_POWER_OFF; -+ gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_COREDUMP] = DRV_STS_POWER_OFF; -+ /*enable power off flag, if flag=0, power off connsys will not be executed */ -+ mtk_wcn_set_connsys_power_off_flag(MTK_WCN_BOOL_TRUE); -+ /* if wmt is poweroff, we need poweron chip first */ -+ /* Zhiguo : this action also needed in BTIF interface to avoid KE */ -+#if 1 -+ if (DRV_STS_POWER_OFF == gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT]) { -+ WMT_WARN_FUNC("WMT-CORE: WMT is off, need re-poweron\n"); -+ /* power on control */ -+ ctrlPa1 = 0; -+ ctrlPa2 = 0; -+ iRet = wmt_core_ctrl(WMT_CTRL_HW_PWR_ON, &ctrlPa1, &ctrlPa2); -+ if (iRet) { -+ WMT_ERR_FUNC("WMT-CORE: WMT_CTRL_HW_PWR_ON fail iRet(%d)\n", iRet); -+ return -1; -+ } -+ gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT] = DRV_STS_POWER_ON; -+ } -+#endif -+ if (gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_BT] == DRV_STS_FUNC_ON) { -+ -+ ctrlPa1 = BT_PALDO; -+ ctrlPa2 = PALDO_OFF; -+ iRet = wmt_core_ctrl(WMT_CTRL_SOC_PALDO_CTRL, &ctrlPa1, &ctrlPa2); -+ if (iRet) -+ WMT_ERR_FUNC("WMT-CORE: wmt_ctrl_soc_paldo_ctrl failed(%d)(%d)(%d)\n", iRet, ctrlPa1, ctrlPa2); -+ -+ gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_BT] = DRV_STS_POWER_OFF; -+ } -+ -+ if (gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WIFI] == DRV_STS_FUNC_ON) { -+ -+ if (NULL != gpWmtFuncOps[WMTDRV_TYPE_WIFI] && NULL != gpWmtFuncOps[WMTDRV_TYPE_WIFI]->func_off) { -+ iRet = gpWmtFuncOps[WMTDRV_TYPE_WIFI]->func_off(gMtkWmtCtx.p_ic_ops, wmt_conf_get_cfg()); -+ if (iRet) { -+ WMT_ERR_FUNC("WMT-CORE: turn off WIFI func fail (%d)\n", iRet); -+ -+ /* check all sub-func and do power off */ -+ } else { -+ WMT_INFO_FUNC("wmt core: turn off WIFI func ok!!\n"); -+ } -+ } -+ gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WIFI] = DRV_STS_POWER_OFF; -+ } -+#if 0 -+ /*<4>Power off Combo chip */ -+ ctrlPa1 = 0; -+ ctrlPa2 = 0; -+ iRet = wmt_core_ctrl(WMT_CTRL_HW_RST, &ctrlPa1, &ctrlPa2); -+ if (iRet) -+ WMT_ERR_FUNC("WMT-CORE: [HW RST] WMT_CTRL_POWER_OFF fail (%d)", iRet); -+ WMT_INFO_FUNC("WMT-CORE: [HW RST] WMT_CTRL_POWER_OFF ok (%d)", iRet); -+#endif -+ gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT] = DRV_STS_POWER_OFF; -+ -+ /*-->PesetCombo chip*/ -+ iRet = wmt_core_ctrl(WMT_CTRL_HW_RST, &ctrlPa1, &ctrlPa2); -+ if (iRet) -+ WMT_ERR_FUNC("WMT-CORE: -->[HW RST] fail iRet(%d)\n", iRet); -+ WMT_WARN_FUNC("WMT-CORE: -->[HW RST] ok\n"); -+ -+ gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT] = DRV_STS_POWER_ON; -+ -+ /* 4 close stp */ -+ ctrlPa1 = 0; -+ ctrlPa2 = 0; -+ iRet = wmt_core_ctrl(WMT_CTRL_STP_CLOSE, &ctrlPa1, &ctrlPa2); -+ if (iRet) { -+ if (iRet == -2) { -+ WMT_INFO_FUNC("WMT-CORE:stp should have be closed\n"); -+ return 0; -+ } -+ WMT_ERR_FUNC("WMT-CORE: wmt close stp failed\n"); -+ return -1; -+ } -+ -+ wmt_core_dump_func_state("AF HW RST"); -+ return iRet; -+ -+} -+ -+static INT32 opfunc_sw_rst(P_WMT_OP pWmtOp) -+{ -+ INT32 iRet = 0; -+ -+ iRet = wmt_core_stp_init(); -+ if (!iRet) -+ gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT] = DRV_STS_FUNC_ON; -+ return iRet; -+} -+ -+static INT32 opfunc_stp_rst(P_WMT_OP pWmtOp) -+{ -+ -+ return 0; -+} -+ -+static INT32 opfunc_therm_ctrl(P_WMT_OP pWmtOp) -+{ -+ -+ INT32 iRet = -1; -+ UINT32 u4Res; -+ UINT32 evtLen; -+ UINT8 evtBuf[16] = { 0 }; -+ -+ WMT_THERM_CMD[4] = pWmtOp->au4OpData[0]; /*CMD type, refer to ENUM_WMTTHERM_TYPE_T */ -+ -+ /* send command */ -+ /* iRet = (*kal_stp_tx)(WMT_THERM_CMD, osal_sizeof(WMT_THERM_CMD), &u4Res); */ -+ iRet = wmt_core_tx((PUINT8) WMT_THERM_CMD, osal_sizeof(WMT_THERM_CMD), &u4Res, MTK_WCN_BOOL_FALSE); -+ if (iRet || (u4Res != osal_sizeof(WMT_THERM_CMD))) { -+ WMT_ERR_FUNC("WMT-CORE: THERM_CTRL_CMD iRet(%d) cmd len err(%d, %d)\n", iRet, u4Res, -+ osal_sizeof(WMT_THERM_CMD)); -+ return iRet; -+ } -+ -+ evtLen = 16; -+ -+ iRet = wmt_core_rx(evtBuf, evtLen, &u4Res); -+ if (iRet || ((u4Res != osal_sizeof(WMT_THERM_CTRL_EVT)) && (u4Res != osal_sizeof(WMT_THERM_READ_EVT)))) { -+ WMT_ERR_FUNC("WMT-CORE: read THERM_CTRL_EVT/THERM_READ_EVENT fail(%d) len(%d, %d)\n", iRet, u4Res, -+ evtLen); -+ mtk_wcn_stp_dbg_dump_package(); -+ return iRet; -+ } -+ if (u4Res == osal_sizeof(WMT_THERM_CTRL_EVT)) { -+ if (osal_memcmp(evtBuf, WMT_THERM_CTRL_EVT, osal_sizeof(WMT_THERM_CTRL_EVT)) != 0) { -+ WMT_ERR_FUNC("WMT-CORE: compare WMT_THERM_CTRL_EVT error\n"); -+ WMT_ERR_FUNC("WMT-CORE: rx(%d):[%02X,%02X,%02X,%02X,%02X] exp(%d):[%02X,%02X,%02X,%02X,%02X]\n", -+ u4Res, evtBuf[0], evtBuf[1], evtBuf[2], evtBuf[3], evtBuf[4], -+ osal_sizeof(WMT_THERM_CTRL_EVT), WMT_THERM_CTRL_EVT[0], WMT_THERM_CTRL_EVT[1], -+ WMT_THERM_CTRL_EVT[2], WMT_THERM_CTRL_EVT[3], WMT_THERM_CTRL_EVT[4]); -+ pWmtOp->au4OpData[1] = MTK_WCN_BOOL_FALSE; /*will return to function driver */ -+ mtk_wcn_stp_dbg_dump_package(); -+ } else { -+ WMT_DBG_FUNC("Send WMT_THERM_CTRL_CMD command OK!\n"); -+ pWmtOp->au4OpData[1] = MTK_WCN_BOOL_TRUE; /*will return to function driver */ -+ } -+ } else { -+ /*no need to judge the real thermal value */ -+ if (osal_memcmp(evtBuf, WMT_THERM_READ_EVT, osal_sizeof(WMT_THERM_READ_EVT) - 1) != 0) { -+ WMT_ERR_FUNC("WMT-CORE: compare WMT_THERM_READ_EVT error\n"); -+ WMT_ERR_FUNC("WMT-CORE: rx(%d):[%02X,%02X,%02X,%02X,%02X,%02X] exp(%d):[%02X,%02X,%02X,%02X]\n", -+ u4Res, evtBuf[0], evtBuf[1], evtBuf[2], evtBuf[3], evtBuf[4], evtBuf[5], -+ osal_sizeof(WMT_THERM_READ_EVT), WMT_THERM_READ_EVT[0], WMT_THERM_READ_EVT[1], -+ WMT_THERM_READ_EVT[2], WMT_THERM_READ_EVT[3]); -+ pWmtOp->au4OpData[1] = 0xFF; /*will return to function driver */ -+ mtk_wcn_stp_dbg_dump_package(); -+ } else { -+ WMT_DBG_FUNC("Send WMT_THERM_READ_CMD command OK!\n"); -+ pWmtOp->au4OpData[1] = evtBuf[5]; /*will return to function driver */ -+ } -+ } -+ -+ return iRet; -+ -+} -+ -+static INT32 opfunc_efuse_rw(P_WMT_OP pWmtOp) -+{ -+ -+ INT32 iRet = -1; -+ UINT32 u4Res; -+ UINT32 evtLen; -+ UINT8 evtBuf[16] = { 0 }; -+ -+ if (DRV_STS_FUNC_ON != gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT]) { -+ WMT_ERR_FUNC("WMT-CORE: wmt_efuse_rw fail: chip is powered off\n"); -+ return -1; -+ } -+ -+ WMT_EFUSE_CMD[4] = (pWmtOp->au4OpData[0]) ? 0x1 : 0x2; /* w:2, r:1 */ -+ osal_memcpy(&WMT_EFUSE_CMD[6], (PUINT8) &pWmtOp->au4OpData[1], 2); /* address */ -+ osal_memcpy(&WMT_EFUSE_CMD[8], (PUINT32) pWmtOp->au4OpData[2], 4); /* value */ -+ -+ wmt_core_dump_data(&WMT_EFUSE_CMD[0], "efuse_cmd", osal_sizeof(WMT_EFUSE_CMD)); -+ -+ /* send command */ -+ /* iRet = (*kal_stp_tx)(WMT_EFUSE_CMD, osal_sizeof(WMT_EFUSE_CMD), &u4Res); */ -+ iRet = wmt_core_tx((PUINT8) WMT_EFUSE_CMD, osal_sizeof(WMT_EFUSE_CMD), &u4Res, MTK_WCN_BOOL_FALSE); -+ if (iRet || (u4Res != osal_sizeof(WMT_EFUSE_CMD))) { -+ WMT_ERR_FUNC("WMT-CORE: EFUSE_CMD iRet(%d) cmd len err(%d, %d)\n", iRet, u4Res, -+ osal_sizeof(WMT_EFUSE_CMD)); -+ return iRet; -+ } -+ -+ evtLen = (pWmtOp->au4OpData[0]) ? osal_sizeof(WMT_EFUSE_EVT) : osal_sizeof(WMT_EFUSE_EVT); -+ -+ iRet = wmt_core_rx(evtBuf, evtLen, &u4Res); -+ if (iRet || (u4Res != evtLen)) -+ WMT_ERR_FUNC("WMT-CORE: read REG_EVB fail(%d) len(%d, %d)\n", iRet, u4Res, evtLen); -+ wmt_core_dump_data(&evtBuf[0], "efuse_evt", osal_sizeof(evtBuf)); -+ -+ return iRet; -+ -+} -+ -+static INT32 opfunc_gpio_ctrl(P_WMT_OP pWmtOp) -+{ -+ INT32 iRet = -1; -+ WMT_IC_PIN_ID id; -+ WMT_IC_PIN_STATE stat; -+ UINT32 flag; -+ -+ if (DRV_STS_FUNC_ON != gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT]) { -+ WMT_ERR_FUNC("WMT-CORE: wmt_gpio_ctrl fail: chip is powered off\n"); -+ return -1; -+ } -+ -+ if (!gMtkWmtCtx.p_ic_ops->ic_pin_ctrl) { -+ WMT_ERR_FUNC("WMT-CORE: error, gMtkWmtCtx.p_ic_ops->ic_pin_ctrl(NULL)\n"); -+ return -1; -+ } -+ -+ id = pWmtOp->au4OpData[0]; -+ stat = pWmtOp->au4OpData[1]; -+ flag = pWmtOp->au4OpData[2]; -+ -+ WMT_INFO_FUNC("ic pin id:%d, stat:%d, flag:0x%x\n", id, stat, flag); -+ -+ iRet = (*(gMtkWmtCtx.p_ic_ops->ic_pin_ctrl)) (id, stat, flag); -+ -+ return iRet; -+} -+ -+MTK_WCN_BOOL wmt_core_is_quick_ps_support(void) -+{ -+ P_WMT_CTX pctx = &gMtkWmtCtx; -+ -+ if ((NULL != pctx->p_ic_ops) && (NULL != pctx->p_ic_ops->is_quick_sleep)) -+ return (*(pctx->p_ic_ops->is_quick_sleep)) (); -+ -+ return MTK_WCN_BOOL_FALSE; -+} -+ -+MTK_WCN_BOOL wmt_core_get_aee_dump_flag(void) -+{ -+ MTK_WCN_BOOL bRet = MTK_WCN_BOOL_FALSE; -+ P_WMT_CTX pctx = &gMtkWmtCtx; -+ -+ if ((NULL != pctx->p_ic_ops) && (NULL != pctx->p_ic_ops->is_aee_dump_support)) -+ bRet = (*(pctx->p_ic_ops->is_aee_dump_support)) (); -+ else -+ bRet = MTK_WCN_BOOL_FALSE; -+ -+ return bRet; -+} -+ -+INT32 opfunc_pin_state(P_WMT_OP pWmtOp) -+{ -+ -+ unsigned long ctrlPa1 = 0; -+ unsigned long ctrlPa2 = 0; -+ UINT32 iRet = 0; -+ -+ iRet = wmt_core_ctrl(WMT_CTRL_HW_STATE_DUMP, &ctrlPa1, &ctrlPa2); -+ return iRet; -+} -+ -+static INT32 opfunc_bgw_ds(P_WMT_OP pWmtOp) -+{ -+ INT32 iRet = -1; -+ UINT32 u4WrittenSize = 0; -+ UINT32 u4ReadSize = 0; -+ UINT32 buf_len = 0; -+ UINT8 *buffer = NULL; -+ UINT8 evt_buffer[8] = { 0 }; -+ MTK_WCN_BOOL fgFail; -+ -+ UINT8 WMT_BGW_DESENSE_CMD[] = { -+ 0x01, 0x0e, 0x0f, 0x00, -+ 0x02, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00 -+ }; -+ UINT8 WMT_BGW_DESENSE_EVT[] = { 0x02, 0x0e, 0x01, 0x00, 0x00 }; -+ -+ buf_len = pWmtOp->au4OpData[0]; -+ buffer = (PUINT8) pWmtOp->au4OpData[1]; -+ -+ osal_memcpy(&WMT_BGW_DESENSE_CMD[5], buffer, buf_len); -+ -+ do { -+ fgFail = MTK_WCN_BOOL_TRUE; -+ -+ iRet = -+ wmt_core_tx(&WMT_BGW_DESENSE_CMD[0], osal_sizeof(WMT_BGW_DESENSE_CMD), &u4WrittenSize, -+ MTK_WCN_BOOL_FALSE); -+ if (iRet || (u4WrittenSize != osal_sizeof(WMT_BGW_DESENSE_CMD))) { -+ WMT_ERR_FUNC("bgw desense tx CMD fail(%d),size(%d)\n", iRet, u4WrittenSize); -+ break; -+ } -+ -+ iRet = wmt_core_rx(evt_buffer, osal_sizeof(WMT_BGW_DESENSE_EVT), &u4ReadSize); -+ if (iRet || (u4ReadSize != osal_sizeof(WMT_BGW_DESENSE_EVT))) { -+ WMT_ERR_FUNC("bgw desense rx EVT fail(%d),size(%d)\n", iRet, u4ReadSize); -+ break; -+ } -+ -+ if (osal_memcmp(evt_buffer, WMT_BGW_DESENSE_EVT, osal_sizeof(WMT_BGW_DESENSE_EVT)) != 0) { -+ WMT_ERR_FUNC -+ ("bgw desense WMT_BGW_DESENSE_EVT compare fail:0x%02x,0x%02x,0x%02x,0x%02x,0x%02x\n", -+ evt_buffer[0], evt_buffer[1], evt_buffer[2], evt_buffer[3], evt_buffer[4]); -+ break; -+ } -+ -+ fgFail = MTK_WCN_BOOL_FALSE; -+ -+ } while (0); -+ -+ return fgFail; -+} -+ -+static INT32 opfunc_set_mcu_clk(P_WMT_OP pWmtOp) -+{ -+ UINT32 kind = 0; -+ INT32 iRet = -1; -+ UINT32 u4WrittenSize = 0; -+ UINT32 u4ReadSize = 0; -+ UINT8 evt_buffer[12] = { 0 }; -+ MTK_WCN_BOOL fgFail; -+ PUINT8 set_mcu_clk_str[] = { -+ "Enable MCU PLL", -+ "SET MCU CLK to 26M", -+ "SET MCU CLK to 37M", -+ "SET MCU CLK to 64M", -+ "SET MCU CLK to 69M", -+ "SET MCU CLK to 104M", -+ "SET MCU CLK to 118.857M", -+ "SET MCU CLK to 138.67M", -+ "Disable MCU PLL" -+ }; -+ UINT8 WMT_SET_MCU_CLK_CMD[] = { -+ 0x01, 0x08, 0x10, 0x00, -+ 0x01, 0x01, 0x00, 0x01, -+ 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, -+ 0xff, 0xff, 0xff, 0xff -+ }; -+ UINT8 WMT_SET_MCU_CLK_EVT[] = { 0x02, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01 }; -+ -+ UINT8 WMT_EN_MCU_CLK_CMD[] = { 0x34, 0x03, 0x00, 0x80, 0x00, 0x00, 0x01, 0x00 }; /* enable pll clk */ -+ UINT8 WMT_26_MCU_CLK_CMD[] = { 0x0c, 0x01, 0x00, 0x80, 0x00, 0x4d, 0x84, 0x00 }; /* set 26M */ -+ UINT8 WMT_37_MCU_CLK_CMD[] = { 0x0c, 0x01, 0x00, 0x80, 0x1e, 0x4d, 0x84, 0x00 }; /* set 37.8M */ -+ UINT8 WMT_64_MCU_CLK_CMD[] = { 0x0c, 0x01, 0x00, 0x80, 0x1d, 0x4d, 0x84, 0x00 }; /* set 64M */ -+ UINT8 WMT_69_MCU_CLK_CMD[] = { 0x0c, 0x01, 0x00, 0x80, 0x1c, 0x4d, 0x84, 0x00 }; /* set 69M */ -+ UINT8 WMT_104_MCU_CLK_CMD[] = { 0x0c, 0x01, 0x00, 0x80, 0x5b, 0x4d, 0x84, 0x00 }; /* set 104M */ -+ UINT8 WMT_108_MCU_CLK_CMD[] = { 0x0c, 0x01, 0x00, 0x80, 0x5a, 0x4d, 0x84, 0x00 }; /* set 118.857M */ -+ UINT8 WMT_138_MCU_CLK_CMD[] = { 0x0c, 0x01, 0x00, 0x80, 0x59, 0x4d, 0x84, 0x00 }; /* set 138.67M */ -+ UINT8 WMT_DIS_MCU_CLK_CMD[] = { 0x34, 0x03, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00 }; /* disable pll clk */ -+ -+ kind = pWmtOp->au4OpData[0]; -+ WMT_INFO_FUNC("do %s\n", set_mcu_clk_str[kind]); -+ -+ switch (kind) { -+ case 0: -+ osal_memcpy(&WMT_SET_MCU_CLK_CMD[8], &WMT_EN_MCU_CLK_CMD[0], osal_sizeof(WMT_EN_MCU_CLK_CMD)); -+ break; -+ case 1: -+ osal_memcpy(&WMT_SET_MCU_CLK_CMD[8], &WMT_26_MCU_CLK_CMD[0], osal_sizeof(WMT_26_MCU_CLK_CMD)); -+ break; -+ case 2: -+ osal_memcpy(&WMT_SET_MCU_CLK_CMD[8], &WMT_37_MCU_CLK_CMD[0], osal_sizeof(WMT_37_MCU_CLK_CMD)); -+ break; -+ case 3: -+ osal_memcpy(&WMT_SET_MCU_CLK_CMD[8], &WMT_64_MCU_CLK_CMD[0], osal_sizeof(WMT_64_MCU_CLK_CMD)); -+ break; -+ case 4: -+ osal_memcpy(&WMT_SET_MCU_CLK_CMD[8], &WMT_69_MCU_CLK_CMD[0], osal_sizeof(WMT_69_MCU_CLK_CMD)); -+ break; -+ case 5: -+ osal_memcpy(&WMT_SET_MCU_CLK_CMD[8], &WMT_104_MCU_CLK_CMD[0], osal_sizeof(WMT_104_MCU_CLK_CMD)); -+ break; -+ case 6: -+ osal_memcpy(&WMT_SET_MCU_CLK_CMD[8], &WMT_108_MCU_CLK_CMD[0], osal_sizeof(WMT_108_MCU_CLK_CMD)); -+ break; -+ case 7: -+ osal_memcpy(&WMT_SET_MCU_CLK_CMD[8], &WMT_138_MCU_CLK_CMD[0], osal_sizeof(WMT_138_MCU_CLK_CMD)); -+ break; -+ case 8: -+ osal_memcpy(&WMT_SET_MCU_CLK_CMD[8], &WMT_DIS_MCU_CLK_CMD[0], osal_sizeof(WMT_DIS_MCU_CLK_CMD)); -+ break; -+ default: -+ WMT_ERR_FUNC("unknown kind\n"); -+ break; -+ } -+ -+ do { -+ fgFail = MTK_WCN_BOOL_TRUE; -+ -+ iRet = -+ wmt_core_tx(&WMT_SET_MCU_CLK_CMD[0], osal_sizeof(WMT_SET_MCU_CLK_CMD), &u4WrittenSize, -+ MTK_WCN_BOOL_FALSE); -+ if (iRet || (u4WrittenSize != osal_sizeof(WMT_SET_MCU_CLK_CMD))) { -+ WMT_ERR_FUNC("WMT_SET_MCU_CLK_CMD fail(%d),size(%d)\n", iRet, u4WrittenSize); -+ break; -+ } -+ -+ iRet = wmt_core_rx(evt_buffer, osal_sizeof(WMT_SET_MCU_CLK_EVT), &u4ReadSize); -+ if (iRet || (u4ReadSize != osal_sizeof(WMT_SET_MCU_CLK_EVT))) { -+ WMT_ERR_FUNC("WMT_SET_MCU_CLK_EVT fail(%d),size(%d)\n", iRet, u4ReadSize); -+ break; -+ } -+ -+ if (osal_memcmp(evt_buffer, WMT_SET_MCU_CLK_EVT, osal_sizeof(WMT_SET_MCU_CLK_EVT)) != 0) { -+ WMT_ERR_FUNC("WMT_SET_MCU_CLK_EVT compare fail:0x%02x,0x%02x,0x%02x,0x%02x,0x%02x\n", -+ evt_buffer[0], evt_buffer[1], evt_buffer[2], evt_buffer[3], evt_buffer[4], -+ evt_buffer[5], evt_buffer[6], evt_buffer[7]); -+ break; -+ } -+ -+ fgFail = MTK_WCN_BOOL_FALSE; -+ -+ } while (0); -+ -+ if (MTK_WCN_BOOL_FALSE == fgFail) -+ WMT_INFO_FUNC("wmt-core:%s: ok!\n", set_mcu_clk_str[kind]); -+ -+ WMT_INFO_FUNC("wmt-core:%s: fail!\n", set_mcu_clk_str[kind]); -+ -+ return fgFail; -+} -+ -+static INT32 opfunc_adie_lpbk_test(P_WMT_OP pWmtOp) -+{ -+ UINT8 *buffer = NULL; -+ MTK_WCN_BOOL fgFail; -+ UINT32 u4Res; -+ UINT32 aDieChipid = 0; -+ UINT8 soc_adie_chipid_cmd[] = { 0x01, 0x13, 0x04, 0x00, 0x02, 0x04, 0x24, 0x00 }; -+ UINT8 soc_adie_chipid_evt[] = { 0x02, 0x13, 0x09, 0x00, 0x00, 0x02, 0x04, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00 }; -+ UINT8 evtbuf[20]; -+ INT32 iRet = -1; -+ -+ buffer = (PUINT8) pWmtOp->au4OpData[1]; -+ -+ do { -+ fgFail = MTK_WCN_BOOL_TRUE; -+ -+ /* read A die chipid by wmt cmd */ -+ iRet = -+ wmt_core_tx((PUINT8) &soc_adie_chipid_cmd[0], osal_sizeof(soc_adie_chipid_cmd), &u4Res, -+ MTK_WCN_BOOL_FALSE); -+ if (iRet || (u4Res != osal_sizeof(soc_adie_chipid_cmd))) { -+ WMT_ERR_FUNC("wmt_core:read A die chipid CMD fail(%d),size(%d)\n", iRet, u4Res); -+ break; -+ } -+ osal_memset(evtbuf, 0, osal_sizeof(evtbuf)); -+ iRet = wmt_core_rx(evtbuf, osal_sizeof(soc_adie_chipid_evt), &u4Res); -+ if (iRet || (u4Res != osal_sizeof(soc_adie_chipid_evt))) { -+ WMT_ERR_FUNC("wmt_core:read A die chipid EVT fail(%d),size(%d)\n", iRet, u4Res); -+ break; -+ } -+ osal_memcpy(&aDieChipid, &evtbuf[u4Res - 2], 2); -+ osal_memcpy(buffer, &evtbuf[u4Res - 2], 2); -+ pWmtOp->au4OpData[0] = 2; -+ WMT_INFO_FUNC("get SOC A die chipid(0x%x)\n", aDieChipid); -+ -+ fgFail = MTK_WCN_BOOL_FALSE; -+ -+ } while (0); -+ -+ return fgFail; -+} -+ -+#if CFG_WMT_LTE_COEX_HANDLING -+static INT32 opfunc_idc_msg_handling(P_WMT_OP pWmtOp) -+{ -+ MTK_WCN_BOOL fgFail; -+ UINT32 u4Res; -+ UINT8 host_lte_btwf_coex_cmd[] = { 0x01, 0x10, 0x00, 0x00, 0x00 }; -+ UINT8 host_lte_btwf_coex_evt[] = { 0x02, 0x10, 0x01, 0x00, 0x00 }; -+ UINT8 *pTxBuf = NULL; -+ UINT8 evtbuf[8] = { 0 }; -+ INT32 iRet = -1; -+ UINT16 msg_len = 0; -+ UINT32 total_len = 0; -+ UINT32 index = 0; -+ UINT8 *msg_local_buffer = NULL; -+ -+ msg_local_buffer = kmalloc(1300, GFP_KERNEL); -+ if (!msg_local_buffer) { -+ WMT_ERR_FUNC("msg_local_buffer kmalloc memory fail\n"); -+ return 0; -+ } -+ -+ pTxBuf = (UINT8 *) pWmtOp->au4OpData[0]; -+ if (NULL == pTxBuf) { -+ WMT_ERR_FUNC("idc msg buffer is NULL\n"); -+ return -1; -+ } -+ iRet = wmt_lib_idc_lock_aquire(); -+ if (iRet) { -+ WMT_ERR_FUNC("--->lock idc_lock failed, ret=%d\n", iRet); -+ return iRet; -+ } -+ osal_memcpy(&msg_len, &pTxBuf[0], osal_sizeof(msg_len)); -+ if (msg_len > 1200) { -+ wmt_lib_idc_lock_release(); -+ WMT_ERR_FUNC("abnormal idc msg len:%d\n", msg_len); -+ return -2; -+ } -+ msg_len += 1; /*flag byte */ -+ -+ osal_memcpy(&host_lte_btwf_coex_cmd[2], &msg_len, 2); -+ host_lte_btwf_coex_cmd[4] = (pWmtOp->au4OpData[1] & 0x00ff); -+ osal_memcpy(&msg_local_buffer[0], &host_lte_btwf_coex_cmd[0], osal_sizeof(host_lte_btwf_coex_cmd)); -+ osal_memcpy(&msg_local_buffer[osal_sizeof(host_lte_btwf_coex_cmd)], -+ &pTxBuf[osal_sizeof(msg_len)], msg_len - 1); -+ -+ wmt_lib_idc_lock_release(); -+ total_len = osal_sizeof(host_lte_btwf_coex_cmd) + msg_len - 1; -+ -+ WMT_DBG_FUNC("wmt_core:idc msg payload len form lte(%d),wmt msg total len(%d)\n", msg_len - 1, -+ total_len); -+ WMT_DBG_FUNC("wmt_core:idc msg payload:\n"); -+ -+ for (index = 0; index < total_len; index++) -+ WMT_DBG_FUNC("0x%02x ", msg_local_buffer[index]); -+ -+ -+ do { -+ fgFail = MTK_WCN_BOOL_TRUE; -+ -+ /* read A die chipid by wmt cmd */ -+ iRet = wmt_core_tx((PUINT8) &msg_local_buffer[0], total_len, &u4Res, MTK_WCN_BOOL_FALSE); -+ if (iRet || (u4Res != total_len)) { -+ WMT_ERR_FUNC("wmt_core:send lte idc msg to connsys fail(%d),size(%d)\n", iRet, u4Res); -+ break; -+ } -+ osal_memset(evtbuf, 0, osal_sizeof(evtbuf)); -+ iRet = wmt_core_rx(evtbuf, osal_sizeof(host_lte_btwf_coex_evt), &u4Res); -+ if (iRet || (u4Res != osal_sizeof(host_lte_btwf_coex_evt))) { -+ WMT_ERR_FUNC("wmt_core:recv host_lte_btwf_coex_evt fail(%d),size(%d)\n", iRet, u4Res); -+ break; -+ } -+ -+ fgFail = MTK_WCN_BOOL_FALSE; -+ -+ } while (0); -+ kfree(msg_local_buffer); -+ return fgFail; -+} -+#endif -+ -+VOID wmt_core_set_coredump_state(ENUM_DRV_STS state) -+{ -+ WMT_INFO_FUNC("wmt-core: set coredump state(%d)\n", state); -+ gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_COREDUMP] = state; -+} -+#ifdef CONFIG_MTK_COMBO_ANT -+INT32 opfunc_ant_ram_down(P_WMT_OP pWmtOp) -+{ -+ INT32 iRet = 0; -+ size_t ctrlPa1 = pWmtOp->au4OpData[0]; -+ UINT32 ctrlPa2 = pWmtOp->au4OpData[1]; -+ PUINT8 pbuf = (PUINT8) ctrlPa1; -+ UINT32 fragSeq = 0; -+ UINT16 fragSize = 0; -+ UINT16 wmtCmdLen; -+ UINT16 wmtPktLen; -+ UINT32 u4Res = 0; -+ UINT8 antEvtBuf[osal_sizeof(WMT_ANT_RAM_DWN_EVT)]; -+#if 1 -+ UINT32 ctrlPa3 = pWmtOp->au4OpData[2]; -+ -+ do { -+ fragSize = ctrlPa2; -+ fragSeq = ctrlPa3; -+ gAntBuf[5] = fragSeq; -+ -+ -+ wmtPktLen = fragSize + sizeof(WMT_ANT_RAM_DWN_CMD) + 1; -+ -+ /*WMT command length cal */ -+ wmtCmdLen = wmtPktLen - 4; -+#if 0 -+ WMT_ANT_RAM_DWN_CMD[2] = wmtCmdLen & 0xFF; -+ WMT_ANT_RAM_DWN_CMD[3] = (wmtCmdLen & 0xFF00) >> 16; -+#else -+ osal_memcpy(&WMT_ANT_RAM_DWN_CMD[2], &wmtCmdLen, 2); -+#endif -+ -+ -+ -+ WMT_ANT_RAM_DWN_CMD[4] = 1; /*RAM CODE download */ -+ -+ osal_memcpy(gAntBuf, WMT_ANT_RAM_DWN_CMD, sizeof(WMT_ANT_RAM_DWN_CMD)); -+ -+ /*copy ram code content to global buffer */ -+ osal_memcpy(&gAntBuf[osal_sizeof(WMT_ANT_RAM_DWN_CMD) + 1], pbuf, fragSize); -+ -+ iRet = wmt_core_tx(gAntBuf, wmtPktLen, &u4Res, MTK_WCN_BOOL_FALSE); -+ if (iRet || (u4Res != wmtPktLen)) { -+ WMT_ERR_FUNC("wmt_core: write fragSeq(%d) size(%d, %d) fail(%d)\n", fragSeq, -+ wmtPktLen, u4Res, iRet); -+ iRet = -4; -+ break; -+ } -+ WMT_DBG_FUNC("wmt_core: write fragSeq(%d) size(%d, %d) ok\n", -+ fragSeq, wmtPktLen, u4Res); -+ -+ osal_memset(antEvtBuf, 0, sizeof(antEvtBuf)); -+ -+ WMT_ANT_RAM_DWN_EVT[4] = 0; /*download result; 0 */ -+ -+ iRet = wmt_core_rx(antEvtBuf, sizeof(WMT_ANT_RAM_DWN_EVT), &u4Res); -+ if (iRet || (u4Res != sizeof(WMT_ANT_RAM_DWN_EVT))) { -+ WMT_ERR_FUNC("wmt_core: read WMT_ANT_RAM_DWN_EVT length(%zu, %d) fail(%d)\n", -+ sizeof(WMT_ANT_RAM_DWN_EVT), u4Res, iRet); -+ iRet = -5; -+ break; -+ } -+#if CFG_CHECK_WMT_RESULT -+ if (osal_memcmp(antEvtBuf, WMT_ANT_RAM_DWN_EVT, sizeof(WMT_ANT_RAM_DWN_EVT)) != 0) { -+ WMT_ERR_FUNC("wmt_core: compare WMT_ANT_RAM_DWN_EVT result error\n"); -+ WMT_ERR_FUNC("rx(%d):[%02X,%02X,%02X,%02X,%02X] exp(%zu):[%02X,%02X,%02X,%02X,%02X]\n", -+ u4Res, antEvtBuf[0], antEvtBuf[1], antEvtBuf[2], antEvtBuf[3], -+ antEvtBuf[4], sizeof(WMT_ANT_RAM_DWN_EVT), WMT_ANT_RAM_DWN_EVT[0], -+ WMT_ANT_RAM_DWN_EVT[1], WMT_ANT_RAM_DWN_EVT[2], WMT_ANT_RAM_DWN_EVT[3], -+ WMT_ANT_RAM_DWN_EVT[4]); -+ iRet = -6; -+ break; -+ } -+#endif -+ WMT_DBG_FUNC("wmt_core: read WMT_ANT_RAM_DWN_EVT length(%zu, %d) ok\n", -+ sizeof(WMT_ANT_RAM_DWN_EVT), u4Res); -+ -+ } while (0); -+#else -+ UINT32 patchSize = ctrlPa2; -+ UINT32 patchSizePerFrag = 1000; -+ UINT32 offset; -+ UINT32 fragNum = 0; -+ /*cal patch fragNum */ -+ fragNum = (patchSize + patchSizePerFrag - 1) / patchSizePerFrag; -+ if (2 >= fragNum) { -+ WMT_WARN_FUNC("ANT ramcode size(%d) too short\n", patchSize); -+ return -1; -+ } -+ -+ while (fragSeq < fragNum) { -+ /*update fragNum */ -+ fragSeq++; -+ -+ if (1 == fragSeq) { -+ fragSize = patchSizePerFrag; -+ /*first package */ -+ gAntBuf[5] = 1; /*RAM CODE start */ -+ } else if (fragNum == fragSeq) { -+ /*last package */ -+ fragSize = patchSizePerFrag; -+ gAntBuf[5] = 3; /*RAM CODE end */ -+ } else { -+ /*middle package */ -+ fragSize = patchSize - ((fragNum - 1) * patchSizePerFrag); -+ gAntBuf[5] = 2; /*RAM CODE confinue */ -+ } -+ wmtPktLen = fragSize + sizeof(WMT_ANT_RAM_OP_CMD) + 1; -+ -+ /*WMT command length cal */ -+ wmtCmdLen = wmtPktLen - 4; -+ -+ WMT_ANT_RAM_OP_CMD[2] = wmtCmdLen & 0xFF; -+ WMT_ANT_RAM_OP_CMD[3] = (wmtCmdLen & 0xFF00) >> 16; -+ -+ WMT_ANT_RAM_OP_CMD[4] = 1; /*RAM CODE download */ -+ -+ osal_memcpy(gAntBuf, WMT_ANT_RAM_OP_CMD, sizeof(WMT_ANT_RAM_OP_CMD)); -+ -+ /*copy ram code content to global buffer */ -+ osal_memcpy(&gAntBuf[6], pbuf, fragSize); -+ -+ /*update offset */ -+ offset += fragSize; -+ pbuf += offset; -+ -+ iRet = wmt_core_tx(gAntBuf, wmtPktLen, &u4Res, MTK_WCN_BOOL_FALSE); -+ if (iRet || (u4Res != wmtPktLen)) { -+ WMT_ERR_FUNC("wmt_core: write fragSeq(%d) size(%d, %d) fail(%d)\n", fragSeq, -+ wmtPktLen, u4Res, iRet); -+ iRet = -4; -+ break; -+ } -+ WMT_DBG_FUNC("wmt_core: write fragSeq(%d) size(%d, %d) ok\n", -+ fragSeq, wmtPktLen, u4Res); -+ -+ osal_memset(antEvtBuf, 0, sizeof(antEvtBuf)); -+ -+ WMT_SET_RAM_OP_EVT[4] = 0; /*download result; 0 */ -+ -+ iRet = wmt_core_rx(antEvtBuf, sizeof(WMT_SET_RAM_OP_EVT), &u4Res); -+ if (iRet || (u4Res != sizeof(WMT_SET_RAM_OP_EVT))) { -+ WMT_ERR_FUNC("wmt_core: read WMT_SET_RAM_OP_EVT length(%d, %d) fail(%d)\n", -+ sizeof(WMT_SET_RAM_OP_EVT), u4Res, iRet); -+ iRet = -5; -+ break; -+ } -+#if CFG_CHECK_WMT_RESULT -+ if (osal_memcmp(antEvtBuf, WMT_SET_RAM_OP_EVT, sizeof(WMT_SET_RAM_OP_EVT)) != 0) { -+ WMT_ERR_FUNC("wmt_core: compare WMT_SET_RAM_OP_EVT result error\n"); -+ WMT_ERR_FUNC("rx(%d):[%02X,%02X,%02X,%02X,%02X] exp(%d):[%02X,%02X,%02X,%02X,%02X]\n", -+ u4Res, antEvtBuf[0], antEvtBuf[1], antEvtBuf[2], antEvtBuf[3], -+ antEvtBuf[4], sizeof(WMT_SET_RAM_OP_EVT), WMT_SET_RAM_OP_EVT[0], -+ WMT_SET_RAM_OP_EVT[1], WMT_SET_RAM_OP_EVT[2], WMT_SET_RAM_OP_EVT[3], -+ WMT_SET_RAM_OP_EVT[4]); -+ iRet = -6; -+ break; -+ } -+#endif -+ WMT_DBG_FUNC("wmt_core: read WMT_SET_RAM_OP_EVT length(%d, %d) ok\n", -+ sizeof(WMT_SET_RAM_OP_EVT), u4Res); -+ -+ -+ } -+ if (fragSeq != fragNum) -+ iRet = -7; -+#endif -+ return iRet; -+} -+ -+ -+INT32 opfunc_ant_ram_stat_get(P_WMT_OP pWmtOp) -+{ -+ INT32 iRet = 0; -+ UINT32 u4Res = 0; -+ UINT32 wmtPktLen = osal_sizeof(WMT_ANT_RAM_STA_GET_CMD); -+ UINT32 u4AntRamStatus = 0; -+ UINT8 antEvtBuf[osal_sizeof(WMT_ANT_RAM_STA_GET_EVT)]; -+ -+ -+ iRet = wmt_core_tx(WMT_ANT_RAM_STA_GET_CMD, wmtPktLen, &u4Res, MTK_WCN_BOOL_FALSE); -+ if (iRet || (u4Res != wmtPktLen)) { -+ WMT_ERR_FUNC -+ ("wmt_core: write wmt and ramcode status query command failed, (%d, %d), iRet(%d)\n", -+ wmtPktLen, u4Res, iRet); -+ iRet = -4; -+ return iRet; -+ } -+ -+ -+ iRet = wmt_core_rx(antEvtBuf, sizeof(WMT_ANT_RAM_STA_GET_EVT), &u4Res); -+ if (iRet || (u4Res != sizeof(WMT_ANT_RAM_STA_GET_EVT))) { -+ WMT_ERR_FUNC("wmt_core: read WMT_ANT_RAM_STA_GET_EVT length(%zu, %d) fail(%d)\n", -+ sizeof(WMT_ANT_RAM_STA_GET_EVT), u4Res, iRet); -+ iRet = -5; -+ return iRet; -+ } -+#if CFG_CHECK_WMT_RESULT -+ if (osal_memcmp(antEvtBuf, WMT_ANT_RAM_STA_GET_EVT, sizeof(WMT_ANT_RAM_STA_GET_EVT) - 1) != -+ 0) { -+ WMT_ERR_FUNC("wmt_core: compare WMT_ANT_RAM_STA_GET_EVT result error\n"); -+ WMT_ERR_FUNC("rx(%d):[%02X,%02X,%02X,%02X,%02X] exp(%zu):[%02X,%02X,%02X,%02X,%02X]\n", -+ u4Res, antEvtBuf[0], antEvtBuf[1], antEvtBuf[2], antEvtBuf[3], antEvtBuf[4], -+ sizeof(WMT_ANT_RAM_STA_GET_EVT), WMT_ANT_RAM_STA_GET_EVT[0], -+ WMT_ANT_RAM_STA_GET_EVT[1], WMT_ANT_RAM_STA_GET_EVT[2], -+ WMT_ANT_RAM_STA_GET_EVT[3], WMT_ANT_RAM_STA_GET_EVT[4]); -+ iRet = -6; -+ return iRet; -+ } -+#endif -+ if (0 == iRet) { -+ u4AntRamStatus = antEvtBuf[sizeof(WMT_ANT_RAM_STA_GET_EVT) - 1]; -+ pWmtOp->au4OpData[2] = u4AntRamStatus; -+ WMT_INFO_FUNC("ANT ram code %s\n", -+ 1 == u4AntRamStatus ? "exist already" : "not exist"); -+ } -+ return iRet; -+} -+#endif -+ -+#if CFG_WMT_LTE_COEX_HANDLING -+/*TEST CODE*/ -+static UINT32 g_open_wmt_lte_flag; -+VOID wmt_core_set_flag_for_test(UINT32 enable) -+{ -+ WMT_INFO_FUNC("%s wmt_lte_flag\n", enable ? "enable" : "disable"); -+ g_open_wmt_lte_flag = enable; -+} -+ -+UINT32 wmt_core_get_flag_for_test(VOID) -+{ -+ return g_open_wmt_lte_flag; -+} -+#endif -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_ctrl.c b/drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_ctrl.c -new file mode 100644 -index 000000000000..fa603c208e59 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_ctrl.c -@@ -0,0 +1,1019 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -+ -+/*! \file -+ \brief Declaration of library functions -+ -+ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+#ifdef DFT_TAG -+#undef DFT_TAG -+#endif -+#define DFT_TAG "[WMT-CTRL]" -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "osal_typedef.h" -+#include "osal.h" -+ -+#include "wmt_ctrl.h" -+#include "wmt_core.h" -+#include "wmt_ic.h" -+#include "wmt_lib.h" -+#include "wmt_dev.h" -+#include "wmt_plat.h" -+#include "stp_core.h" -+#include "stp_dbg.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+/* moved to wmt_ctrl.h */ -+/*static INT32 wmt_ctrl_tx_ex (UINT8 *pData, UINT32 size, UINT32 *writtenSize, MTK_WCN_BOOL bRawFlag);*/ -+ -+static INT32 wmt_ctrl_stp_conf_ex(WMT_STP_CONF_TYPE type, UINT32 value); -+ -+static INT32 wmt_ctrl_hw_pwr_off(P_WMT_CTRL_DATA); -+static INT32 wmt_ctrl_hw_pwr_on(P_WMT_CTRL_DATA); -+static INT32 wmt_ctrl_hw_rst(P_WMT_CTRL_DATA); -+static INT32 wmt_ctrl_stp_close(P_WMT_CTRL_DATA); -+static INT32 wmt_ctrl_stp_open(P_WMT_CTRL_DATA); -+static INT32 wmt_ctrl_stp_conf(P_WMT_CTRL_DATA); -+static INT32 wmt_ctrl_free_patch(P_WMT_CTRL_DATA); -+static INT32 wmt_ctrl_get_patch(P_WMT_CTRL_DATA); -+#if 0 -+static INT32 wmt_ctrl_host_baudrate_set(P_WMT_CTRL_DATA); -+static INT32 wmt_ctrl_sdio_hw(P_WMT_CTRL_DATA); -+static INT32 wmt_ctrl_sdio_func(P_WMT_CTRL_DATA); -+#endif -+static INT32 wmt_ctrl_hwidver_set(P_WMT_CTRL_DATA); -+static INT32 wmt_ctrl_stp_rst(P_WMT_CTRL_DATA); -+static INT32 wmt_ctrl_get_wmt_conf(P_WMT_CTRL_DATA); -+static INT32 wmt_ctrl_others(P_WMT_CTRL_DATA); -+static INT32 wmt_ctrl_tx(P_WMT_CTRL_DATA); -+static INT32 wmt_ctrl_rx(P_WMT_CTRL_DATA); -+static INT32 wmt_ctrl_patch_search(P_WMT_CTRL_DATA); -+static INT32 wmt_ctrl_crystal_triming_put(P_WMT_CTRL_DATA pWmtCtrlData); -+static INT32 wmt_ctrl_crystal_triming_get(P_WMT_CTRL_DATA pWmtCtrlData); -+static INT32 wmt_ctrl_hw_state_show(P_WMT_CTRL_DATA pWmtCtrlData); -+static INT32 wmt_ctrl_get_patch_num(P_WMT_CTRL_DATA); -+static INT32 wmt_ctrl_get_patch_info(P_WMT_CTRL_DATA); -+static INT32 wmt_ctrl_soc_paldo_ctrl(P_WMT_CTRL_DATA); -+static INT32 wmt_ctrl_soc_wakeup_consys(P_WMT_CTRL_DATA); -+static INT32 wmt_ctrl_set_stp_dbg_info(P_WMT_CTRL_DATA); -+static INT32 wmt_ctrl_bgw_desense_ctrl(P_WMT_CTRL_DATA); -+static INT32 wmt_ctrl_evt_err_trg_assert(P_WMT_CTRL_DATA); -+static INT32 wmt_ctrl_evt_parser(P_WMT_CTRL_DATA pWmtCtrlData); -+#if CFG_WMT_LTE_COEX_HANDLING -+static INT32 wmt_ctrl_get_tdm_req_antsel(P_WMT_CTRL_DATA); -+#endif -+ -+static INT32 wmt_ctrl_rx_flush(P_WMT_CTRL_DATA); -+ -+static INT32 wmt_ctrl_gps_sync_set(P_WMT_CTRL_DATA pData); -+ -+static INT32 wmt_ctrl_gps_lna_set(P_WMT_CTRL_DATA pData); -+ -+static INT32 wmt_ctrl_get_patch_name(P_WMT_CTRL_DATA pWmtCtrlData); -+ -+/* TODO: [FixMe][GeorgeKuo]: remove unused function */ -+/*static INT32 wmt_ctrl_hwver_get(P_WMT_CTRL_DATA);*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/* GeorgeKuo: Use designated initializers described in -+ * http://gcc.gnu.org/onlinedocs/gcc-4.0.4/gcc/Designated-Inits.html -+ */ -+static const WMT_CTRL_FUNC wmt_ctrl_func[] = { -+ [WMT_CTRL_HW_PWR_OFF] = wmt_ctrl_hw_pwr_off, -+ [WMT_CTRL_HW_PWR_ON] = wmt_ctrl_hw_pwr_on, -+ [WMT_CTRL_HW_RST] = wmt_ctrl_hw_rst, -+ [WMT_CTRL_STP_CLOSE] = wmt_ctrl_stp_close, -+ [WMT_CTRL_STP_OPEN] = wmt_ctrl_stp_open, -+ [WMT_CTRL_STP_CONF] = wmt_ctrl_stp_conf, -+ [WMT_CTRL_FREE_PATCH] = wmt_ctrl_free_patch, -+ [WMT_CTRL_GET_PATCH] = wmt_ctrl_get_patch, -+ [WMT_CTRL_GET_PATCH_NAME] = wmt_ctrl_get_patch_name, -+ [WMT_CTRL_HWIDVER_SET] = wmt_ctrl_hwidver_set, -+ [WMT_CTRL_STP_RST] = wmt_ctrl_stp_rst, -+ [WMT_CTRL_GET_WMT_CONF] = wmt_ctrl_get_wmt_conf, -+ [WMT_CTRL_TX] = wmt_ctrl_tx, -+ [WMT_CTRL_RX] = wmt_ctrl_rx, -+ [WMT_CTRL_RX_FLUSH] = wmt_ctrl_rx_flush, -+ [WMT_CTRL_GPS_SYNC_SET] = wmt_ctrl_gps_sync_set, -+ [WMT_CTRL_GPS_LNA_SET] = wmt_ctrl_gps_lna_set, -+ [WMT_CTRL_PATCH_SEARCH] = wmt_ctrl_patch_search, -+ [WMT_CTRL_CRYSTAL_TRIMING_GET] = wmt_ctrl_crystal_triming_get, -+ [WMT_CTRL_CRYSTAL_TRIMING_PUT] = wmt_ctrl_crystal_triming_put, -+ [WMT_CTRL_HW_STATE_DUMP] = wmt_ctrl_hw_state_show, -+ [WMT_CTRL_GET_PATCH_NUM] = wmt_ctrl_get_patch_num, -+ [WMT_CTRL_GET_PATCH_INFO] = wmt_ctrl_get_patch_info, -+ [WMT_CTRL_SOC_PALDO_CTRL] = wmt_ctrl_soc_paldo_ctrl, -+ [WMT_CTRL_SOC_WAKEUP_CONSYS] = wmt_ctrl_soc_wakeup_consys, -+ [WMT_CTRL_SET_STP_DBG_INFO] = wmt_ctrl_set_stp_dbg_info, -+ [WMT_CTRL_BGW_DESENSE_CTRL] = wmt_ctrl_bgw_desense_ctrl, -+ [WMT_CTRL_EVT_ERR_TRG_ASSERT] = wmt_ctrl_evt_err_trg_assert, -+#if CFG_WMT_LTE_COEX_HANDLING -+ [WMT_CTRL_GET_TDM_REQ_ANTSEL] = wmt_ctrl_get_tdm_req_antsel, -+#endif -+ [WMT_CTRL_EVT_PARSER] = wmt_ctrl_evt_parser, -+ [WMT_CTRL_MAX] = wmt_ctrl_others, -+}; -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+INT32 wmt_ctrl(P_WMT_CTRL_DATA pWmtCtrlData) -+{ -+ UINT32 ctrlId; -+ -+ if (NULL == pWmtCtrlData) { -+ osal_assert(0); -+ return -1; -+ } -+ -+ ctrlId = pWmtCtrlData->ctrlId; -+ /*1sanity check, including wmtCtrlId */ -+ if ((NULL == pWmtCtrlData) -+ || (WMT_CTRL_MAX <= ctrlId)) -+ /* || (ctrlId < WMT_CTRL_HW_PWR_OFF) ) [FixMe][GeorgeKuo]: useless comparison */ -+ { -+ osal_assert(NULL != pWmtCtrlData); -+ osal_assert(WMT_CTRL_MAX > ctrlId); -+ /* osal_assert(ctrlId >= WMT_CTRL_HW_PWR_OFF); [FixMe][GeorgeKuo]: useless comparison */ -+ return -2; -+ } -+ /* TODO: [FixMe][GeorgeKuo] do sanity check to const function table when init and skip checking here */ -+ if (wmt_ctrl_func[ctrlId]) { -+ /*call servicd handling API */ -+ return (*(wmt_ctrl_func[ctrlId])) (pWmtCtrlData); /* serviceHandlerPack[ctrlId].serviceHandler */ -+ } -+ osal_assert(NULL != wmt_ctrl_func[ctrlId]); -+ return -3; -+ -+} -+ -+INT32 wmt_ctrl_tx(P_WMT_CTRL_DATA pWmtCtrlData /*UINT8 *pData, UINT32 size, UINT32 *writtenSize */) -+{ -+ UINT8 *pData = (PUINT8) pWmtCtrlData->au4CtrlData[0]; -+ UINT32 size = pWmtCtrlData->au4CtrlData[1]; -+ PUINT32 writtenSize = (PUINT32) pWmtCtrlData->au4CtrlData[2]; -+ MTK_WCN_BOOL bRawFlag = pWmtCtrlData->au4CtrlData[3]; -+ -+ return wmt_ctrl_tx_ex(pData, size, writtenSize, bRawFlag); -+} -+ -+INT32 wmt_ctrl_rx(P_WMT_CTRL_DATA pWmtCtrlData /*UINT8 *pBuff, UINT32 buffLen, UINT32 *readSize */) -+{ -+ P_DEV_WMT pDev = &gDevWmt; /* single instance */ -+ INT32 readLen; -+ long waitRet = -1; -+ PUINT8 pBuff = (PUINT8) pWmtCtrlData->au4CtrlData[0]; -+ UINT32 buffLen = pWmtCtrlData->au4CtrlData[1]; -+ PUINT32 readSize = (PUINT32) pWmtCtrlData->au4CtrlData[2]; -+ -+ if (readSize) -+ *readSize = 0; -+ -+ /* sanity check */ -+ if (!buffLen) { -+ WMT_WARN_FUNC("buffLen = 0\n"); -+ osal_assert(buffLen); -+ return 0; -+ } -+#if 0 -+ if (!pDev) { -+ WMT_WARN_FUNC("gpDevWmt = NULL\n"); -+ osal_assert(pDev); -+ return -1; -+ } -+#endif -+ -+ if (!osal_test_bit(WMT_STAT_STP_OPEN, &pDev->state)) { -+ WMT_WARN_FUNC("state(0x%lx)\n", pDev->state); -+ osal_assert(osal_test_bit(WMT_STAT_STP_OPEN, &pDev->state)); -+ return -2; -+ } -+ -+ /* sanity ok, proceeding rx operation */ -+ /* read_len = mtk_wcn_stp_receive_data(data, size, WMT_TASK_INDX); */ -+ readLen = mtk_wcn_stp_receive_data(pBuff, buffLen, WMT_TASK_INDX); -+ -+ while (readLen == 0) { /* got nothing, wait for STP's signal */ -+ WMT_LOUD_FUNC("before wmt_dev_rx_timeout\n"); -+ /* iRet = wait_event_interruptible(pdev->rWmtRxWq, osal_test_bit(WMT_STAT_RX, &pdev->state)); */ -+ /* waitRet = wait_event_interruptible_timeout( -+ * pDev->rWmtRxWq, -+ * osal_test_bit(WMT_STAT_RX, &pdev->state), -+ * msecs_to_jiffies(WMT_LIB_RX_TIMEOUT)); -+ */ -+ pDev->rWmtRxWq.timeoutValue = WMT_LIB_RX_TIMEOUT; -+ /* waitRet = osal_wait_for_event_bit_timeout(&pDev->rWmtRxWq, &pDev->state, WMT_STAT_RX); */ -+ waitRet = wmt_dev_rx_timeout(&pDev->rWmtRxWq); -+ -+ WMT_LOUD_FUNC("wmt_dev_rx_timeout returned\n"); -+ -+ if (0 == waitRet) { -+ WMT_ERR_FUNC("wmt_dev_rx_timeout: timeout,jiffies(%lu),timeoutvalue(%d)\n", -+ jiffies, pDev->rWmtRxWq.timeoutValue); -+ return -1; -+ } else if (waitRet < 0) { -+ WMT_WARN_FUNC("wmt_dev_rx_timeout: interrupted by signal (%ld)\n", waitRet); -+ return waitRet; -+ } -+ WMT_DBG_FUNC("wmt_dev_rx_timeout, iRet(%ld)\n", waitRet); -+ /* read_len = mtk_wcn_stp_receive_data(data, size, WMT_TASK_INDX); */ -+ readLen = mtk_wcn_stp_receive_data(pBuff, buffLen, WMT_TASK_INDX); -+ -+ if (0 == readLen) -+ WMT_WARN_FUNC("wmt_ctrl_rx be signaled, but no rx data(%ld)\n", waitRet); -+ -+ } -+ -+ if (readSize) -+ *readSize = readLen; -+ -+ return 0; -+ -+} -+ -+INT32 wmt_ctrl_tx_ex(const PUINT8 pData, const UINT32 size, PUINT32 writtenSize, const MTK_WCN_BOOL bRawFlag) -+{ -+ P_DEV_WMT pDev = &gDevWmt; /* single instance */ -+ INT32 iRet; -+ -+ if (NULL != writtenSize) -+ *writtenSize = 0; -+ -+ /* sanity check */ -+ if (0 == size) { -+ WMT_WARN_FUNC("size to tx is 0\n"); -+ osal_assert(size); -+ return -1; -+ } -+ -+ /* if STP is not enabled yet, can't use this function. Use tx_raw instead */ -+ if (!osal_test_bit(WMT_STAT_STP_OPEN, &pDev->state) || !osal_test_bit(WMT_STAT_STP_EN, &pDev->state)) { -+ WMT_ERR_FUNC("wmt state(0x%lx)\n", pDev->state); -+ osal_assert(osal_test_bit(WMT_STAT_STP_EN, &pDev->state)); -+ osal_assert(osal_test_bit(WMT_STAT_STP_OPEN, &pDev->state)); -+ return -2; -+ } -+ -+ /* sanity ok, proceeding tx operation */ -+ /*retval = mtk_wcn_stp_send_data(data, size, WMTDRV_TYPE_WMT); */ -+ mtk_wcn_stp_flush_rx_queue(WMT_TASK_INDX); -+ if (bRawFlag) -+ iRet = mtk_wcn_stp_send_data_raw(pData, size, WMT_TASK_INDX); -+ else -+ iRet = mtk_wcn_stp_send_data(pData, size, WMT_TASK_INDX); -+ -+ if (iRet != size) { -+ WMT_WARN_FUNC("write(%d) written(%d)\n", size, iRet); -+ osal_assert(iRet == size); -+ } -+ -+ if (writtenSize) -+ *writtenSize = iRet; -+ -+ return 0; -+ -+} -+ -+INT32 wmt_ctrl_rx_flush(P_WMT_CTRL_DATA pWmtCtrlData) -+{ -+ UINT32 type = pWmtCtrlData->au4CtrlData[0]; -+ -+ WMT_INFO_FUNC("flush rx %d queue\n", type); -+ mtk_wcn_stp_flush_rx_queue(type); -+ -+ return 0; -+} -+ -+INT32 wmt_ctrl_hw_pwr_off(P_WMT_CTRL_DATA pWmtCtrlData) -+{ -+ INT32 iret; -+ -+/*psm should be disabled before wmt_ic_deinit*/ -+ P_DEV_WMT pDev = &gDevWmt; -+ -+ if (osal_test_and_clear_bit(WMT_STAT_PWR, &pDev->state)) { -+ WMT_DBG_FUNC("on->off\n"); -+ iret = wmt_plat_pwr_ctrl(FUNC_OFF); -+ } else { -+ WMT_WARN_FUNC("already off\n"); -+ iret = 0; -+ } -+ -+ return iret; -+} -+ -+INT32 wmt_ctrl_hw_pwr_on(P_WMT_CTRL_DATA pWmtCtrlData) -+{ -+ INT32 iret; -+ /*psm should be enabled right after wmt_ic_init */ -+ P_DEV_WMT pDev = &gDevWmt; -+ if (osal_test_and_set_bit(WMT_STAT_PWR, &pDev->state)) { -+ WMT_WARN_FUNC("already on\n"); -+ iret = 0; -+ } else { -+ WMT_DBG_FUNC("off->on\n"); -+ iret = wmt_plat_pwr_ctrl(FUNC_ON); -+ } -+ -+ return iret; -+} -+ -+INT32 wmt_ctrl_ul_cmd(P_DEV_WMT pWmtDev, const UINT8 *pCmdStr) -+{ -+ INT32 waitRet = -1; -+ P_OSAL_SIGNAL pCmdSignal; -+ P_OSAL_EVENT pCmdReq; -+ -+ if (osal_test_and_set_bit(WMT_STAT_CMD, &pWmtDev->state)) { -+ WMT_WARN_FUNC("cmd buf is occupied by (%s)\n", pWmtDev->cCmd); -+ return -1; -+ } -+ -+ /* indicate baud rate change to user space app */ -+#if 0 -+ INIT_COMPLETION(pWmtDev->cmd_comp); -+ pWmtDev->cmd_result = -1; -+ strncpy(pWmtDev->cCmd, pCmdStr, NAME_MAX); -+ pWmtDev->cCmd[NAME_MAX] = '\0'; -+ wake_up_interruptible(&pWmtDev->cmd_wq); -+#endif -+ -+ pCmdSignal = &pWmtDev->cmdResp; -+ osal_signal_init(pCmdSignal); -+ pCmdSignal->timeoutValue = 2000; -+ osal_strncpy(pWmtDev->cCmd, pCmdStr, NAME_MAX); -+ pWmtDev->cCmd[NAME_MAX] = '\0'; -+ -+ pCmdReq = &pWmtDev->cmdReq; -+ -+ osal_trigger_event(&pWmtDev->cmdReq); -+ WMT_DBG_FUNC("str(%s) request ok\n", pCmdStr); -+ -+/* waitRet = wait_for_completion_interruptible_timeout(&pWmtDev->cmd_comp, msecs_to_jiffies(2000)); */ -+ waitRet = osal_wait_for_signal_timeout(pCmdSignal); -+ WMT_LOUD_FUNC("wait signal iRet:%d\n", waitRet); -+ if (0 == waitRet) { -+ WMT_ERR_FUNC("wait signal timeout\n"); -+ return -2; -+ } -+ -+ WMT_DBG_FUNC("str(%s) result(%d)\n", pCmdStr, pWmtDev->cmdResult); -+ -+ return pWmtDev->cmdResult; -+} -+ -+INT32 wmt_ctrl_hw_rst(P_WMT_CTRL_DATA pWmtCtrlData) -+{ -+ wmt_plat_pwr_ctrl(FUNC_RST); -+ return 0; -+} -+ -+INT32 wmt_ctrl_hw_state_show(P_WMT_CTRL_DATA pWmtCtrlData) -+{ -+ wmt_plat_pwr_ctrl(FUNC_STAT); -+ return 0; -+} -+ -+INT32 wmt_ctrl_stp_close(P_WMT_CTRL_DATA pWmtCtrlData) -+{ -+ P_DEV_WMT pDev = &gDevWmt; /* single instance */ -+ INT32 iRet = 0; -+ /* un-register to STP-core for rx */ -+ iRet = mtk_wcn_stp_register_event_cb(WMT_TASK_INDX, NULL); /* mtk_wcn_stp_register_event_cb */ -+ if (iRet) { -+ WMT_WARN_FUNC("stp_reg cb unregister fail(%d)\n", iRet); -+ return -1; -+ } -+ -+ /*un-register rxcb to btif */ -+ iRet = mtk_wcn_stp_rxcb_register(NULL); -+ if (iRet) { -+ WMT_WARN_FUNC("mtk_wcn_stp_rxcb_unregister fail(%d)\n", iRet); -+ return -2; -+ } -+ -+ iRet = mtk_wcn_stp_close_btif(); -+ if (iRet) { -+ WMT_WARN_FUNC("mtk_wcn_stp_close_btif fail(%d)\n", iRet); -+ return -3; -+ } -+ osal_clear_bit(WMT_STAT_STP_OPEN, &pDev->state); -+ -+ return 0; -+} -+ -+INT32 wmt_ctrl_stp_open(P_WMT_CTRL_DATA pWmtCtrlData) -+{ -+ P_DEV_WMT pDev = &gDevWmt; /* single instance */ -+ INT32 iRet; -+ -+ iRet = mtk_wcn_stp_open_btif(); -+ if (iRet) { -+ WMT_WARN_FUNC("mtk_wcn_stp_open_btif fail(%d)\n", iRet); -+ return -1; -+ } -+ -+ /*register stp rx call back to btif */ -+ iRet = mtk_wcn_stp_rxcb_register((MTK_WCN_BTIF_RX_CB) mtk_wcn_stp_parser_data); -+ if (iRet) { -+ WMT_WARN_FUNC("mtk_wcn_stp_rxcb_register fail(%d)\n", iRet); -+ return -2; -+ } -+ /* register to STP-core for rx */ -+ iRet = mtk_wcn_stp_register_event_cb(WMT_TASK_INDX, wmt_dev_rx_event_cb); -+ if (iRet) { -+ WMT_WARN_FUNC("stp_reg cb fail(%d)\n", iRet); -+ return -3; -+ } -+ -+ osal_set_bit(WMT_STAT_STP_OPEN, &pDev->state); -+ -+#if 0 -+ iRet = mtk_wcn_stp_lpbk_ctrl(1); -+#endif -+ -+ return 0; -+} -+ -+INT32 wmt_ctrl_patch_search(P_WMT_CTRL_DATA pWmtCtrlData) -+{ -+ P_DEV_WMT pDev = &gDevWmt; /* single instance */ -+ INT32 iRet; -+ UINT8 cmdStr[NAME_MAX + 1] = { 0 }; -+ -+ osal_snprintf(cmdStr, NAME_MAX, "srh_patch"); -+ iRet = wmt_ctrl_ul_cmd(pDev, cmdStr); -+ if (iRet) { -+ WMT_WARN_FUNC("wmt_ctrl_ul_cmd fail(%d)\n", iRet); -+ return -1; -+ } -+ return 0; -+} -+ -+INT32 wmt_ctrl_get_patch_num(P_WMT_CTRL_DATA pWmtCtrlData) -+{ -+ P_DEV_WMT pDev = &gDevWmt; /* single instance */ -+ -+ pWmtCtrlData->au4CtrlData[0] = pDev->patchNum; -+ return 0; -+} -+ -+INT32 wmt_ctrl_get_patch_info(P_WMT_CTRL_DATA pWmtCtrlData) -+{ -+ P_DEV_WMT pDev = &gDevWmt; /* single instance */ -+ UINT32 downLoadSeq = 0; -+ P_WMT_PATCH_INFO pPatchinfo = NULL; -+ PUINT8 pNbuf = NULL; -+ PUINT8 pAbuf = NULL; -+ -+ downLoadSeq = pWmtCtrlData->au4CtrlData[0]; -+ WMT_DBG_FUNC("download seq is %d\n", downLoadSeq); -+ -+ pPatchinfo = pDev->pWmtPatchInfo + downLoadSeq - 1; -+ pNbuf = (PUINT8) pWmtCtrlData->au4CtrlData[1]; -+ pAbuf = (PUINT8) pWmtCtrlData->au4CtrlData[2]; -+ if (pPatchinfo) { -+ osal_memcpy(pNbuf, pPatchinfo->patchName, osal_sizeof(pPatchinfo->patchName)); -+ osal_memcpy(pAbuf, pPatchinfo->addRess, osal_sizeof(pPatchinfo->addRess)); -+ WMT_DBG_FUNC("get 4 address bytes is 0x%2x,0x%2x,0x%2x,0x%2x", pAbuf[0], pAbuf[1], pAbuf[2], pAbuf[3]); -+ } else { -+ WMT_ERR_FUNC("NULL patchinfo pointer\n"); -+ } -+ -+ return 0; -+} -+ -+INT32 wmt_ctrl_soc_paldo_ctrl(P_WMT_CTRL_DATA pWmtCtrlData) -+{ -+ INT32 iRet = 0; -+ ENUM_PALDO_TYPE ept = pWmtCtrlData->au4CtrlData[0]; -+ ENUM_PALDO_OP epo = pWmtCtrlData->au4CtrlData[1]; -+ -+ WMT_DBG_FUNC("ept(%d),epo(%d)\n", ept, epo); -+ iRet = wmt_plat_soc_paldo_ctrl(ept, epo); -+ if (iRet) { -+ if (PMIC_CHIPID_PALDO == ept) { -+ /* special handling for PMIC CHIPID */ -+ pWmtCtrlData->au4CtrlData[2] = iRet; -+ } else { -+ /* for other PA handling */ -+ WMT_ERR_FUNC("soc palod ctrl fail(%d)\n", iRet); -+ } -+ } -+ -+ return iRet; -+} -+ -+INT32 wmt_ctrl_soc_wakeup_consys(P_WMT_CTRL_DATA pWmtCtrlData) -+{ -+ INT32 iRet = 0; -+ -+ iRet = mtk_wcn_stp_wakeup_consys(); -+ if (iRet) -+ WMT_ERR_FUNC("soc palod ctrl fail(%d)\n", iRet); -+ -+ return iRet; -+} -+ -+INT32 wmt_ctrl_stp_conf_ex(WMT_STP_CONF_TYPE type, UINT32 value) -+{ -+ INT32 iRet = -1; -+ -+ switch (type) { -+ case WMT_STP_CONF_EN: -+ iRet = mtk_wcn_stp_enable(value); -+ break; -+ -+ case WMT_STP_CONF_RDY: -+ iRet = mtk_wcn_stp_ready(value); -+ break; -+ -+ case WMT_STP_CONF_MODE: -+ mtk_wcn_stp_set_mode(value); -+ iRet = 0; -+ break; -+ -+ default: -+ WMT_WARN_FUNC("invalid type(%d) value(%d)\n", type, value); -+ break; -+ } -+ return iRet; -+} -+ -+INT32 wmt_ctrl_stp_conf(P_WMT_CTRL_DATA pWmtCtrlData) -+{ -+ INT32 iRet = -1; -+ P_DEV_WMT pDev = &gDevWmt; /* single instance */ -+ UINT32 type; -+ UINT32 value; -+ -+ if (!osal_test_bit(WMT_STAT_STP_OPEN, &pDev->state)) { -+ WMT_WARN_FUNC("CTRL_STP_ENABLE but invalid Handle of WmtStp\n"); -+ return -1; -+ } -+ -+ type = pWmtCtrlData->au4CtrlData[0]; -+ value = pWmtCtrlData->au4CtrlData[1]; -+ iRet = wmt_ctrl_stp_conf_ex(type, value); -+ -+ if (!iRet) { -+ if (WMT_STP_CONF_EN == type) { -+ if (value) { -+ osal_set_bit(WMT_STAT_STP_EN, &pDev->state); -+ WMT_DBG_FUNC("enable STP\n"); -+ } else { -+ osal_clear_bit(WMT_STAT_STP_EN, &pDev->state); -+ WMT_DBG_FUNC("disable STP\n"); -+ } -+ } -+ } -+ -+ return iRet; -+} -+ -+INT32 wmt_ctrl_free_patch(P_WMT_CTRL_DATA pWmtCtrlData) -+{ -+ UINT32 patchSeq = pWmtCtrlData->au4CtrlData[0]; -+ -+ WMT_DBG_FUNC("BF free patch, gDevWmt.pPatch(0x%08x)\n", gDevWmt.pPatch); -+ if (NULL != gDevWmt.pPatch) -+ wmt_dev_patch_put((osal_firmware **) &(gDevWmt.pPatch)); -+ -+ WMT_DBG_FUNC("AF free patch, gDevWmt.pPatch(0x%08x)\n", gDevWmt.pPatch); -+ if (patchSeq == gDevWmt.patchNum) { -+ WMT_DBG_FUNC("the %d patch has been download\n", patchSeq); -+ wmt_dev_patch_info_free(); -+ } -+ return 0; -+} -+ -+INT32 wmt_ctrl_get_patch_name(P_WMT_CTRL_DATA pWmtCtrlData) -+{ -+ PUINT8 pBuf = (PUINT8) pWmtCtrlData->au4CtrlData[0]; -+ -+ osal_memcpy(pBuf, gDevWmt.cPatchName, osal_sizeof(gDevWmt.cPatchName)); -+ return 0; -+} -+ -+INT32 wmt_ctrl_crystal_triming_put(P_WMT_CTRL_DATA pWmtCtrlData) -+{ -+ WMT_DBG_FUNC("BF free patch, gDevWmt.pPatch(0x%08x)\n", gDevWmt.pPatch); -+ if (NULL != gDevWmt.pNvram) -+ wmt_dev_patch_put((osal_firmware **) &(gDevWmt.pNvram)); -+ -+ WMT_DBG_FUNC("AF free patch, gDevWmt.pNvram(0x%08x)\n", gDevWmt.pNvram); -+ return 0; -+} -+ -+INT32 wmt_ctrl_crystal_triming_get(P_WMT_CTRL_DATA pWmtCtrlData) -+{ -+ INT32 iRet = 0x0; -+ PUINT8 pFileName = (PUINT8) pWmtCtrlData->au4CtrlData[0]; -+ PPUINT8 ppBuf = (PPUINT8) pWmtCtrlData->au4CtrlData[1]; -+ PUINT32 pSize = (PUINT32) pWmtCtrlData->au4CtrlData[2]; -+ -+ osal_firmware *pNvram = NULL; -+ -+ if ((NULL == pFileName) || (NULL == pSize)) { -+ WMT_ERR_FUNC("parameter error, pFileName(0x%08x), pSize(0x%08x)\n", pFileName, pSize); -+ iRet = -1; -+ return iRet; -+ } -+ if (0 == wmt_dev_patch_get(pFileName, &pNvram, 0)) { -+ *ppBuf = (PUINT8) (pNvram)->data; -+ *pSize = (pNvram)->size; -+ gDevWmt.pNvram = pNvram; -+ return 0; -+ } -+ return -1; -+ -+} -+ -+INT32 wmt_ctrl_get_patch(P_WMT_CTRL_DATA pWmtCtrlData) -+{ -+ UINT8 *pFullPatchName = NULL; -+ UINT8 *pDefPatchName = NULL; -+ PUINT8 *ppBuf = (PUINT8 *) pWmtCtrlData->au4CtrlData[2]; -+ PUINT32 pSize = (PUINT32) pWmtCtrlData->au4CtrlData[3]; -+ -+ osal_firmware *pPatch = NULL; -+ -+ pFullPatchName = (PUINT8) pWmtCtrlData->au4CtrlData[1]; -+ WMT_DBG_FUNC("BF get patch, pPatch(0x%08x)\n", pPatch); -+ if ((NULL != pFullPatchName) -+ && (0 == wmt_dev_patch_get(pFullPatchName, &pPatch, BCNT_PATCH_BUF_HEADROOM))) { -+ /*get full name patch success */ -+ WMT_DBG_FUNC("get full patch name(%s) buf(0x%p) size(%d)\n", -+ pFullPatchName, (pPatch)->data, (pPatch)->size); -+ WMT_DBG_FUNC("AF get patch, pPatch(0x%08x)\n", pPatch); -+ *ppBuf = (PUINT8) (pPatch)->data; -+ *pSize = (pPatch)->size; -+ gDevWmt.pPatch = pPatch; -+ return 0; -+ } -+ -+ pDefPatchName = (PUINT8) pWmtCtrlData->au4CtrlData[0]; -+ if ((NULL != pDefPatchName) -+ && (0 == wmt_dev_patch_get(pDefPatchName, &pPatch, BCNT_PATCH_BUF_HEADROOM))) { -+ WMT_DBG_FUNC("get def patch name(%s) buf(0x%p) size(%d)\n", -+ pDefPatchName, (pPatch)->data, (pPatch)->size); -+ WMT_DBG_FUNC("AF get patch, pPatch(0x%08x)\n", pPatch); -+ /*get full name patch success */ -+ *ppBuf = (PUINT8) (pPatch)->data; -+ *pSize = (pPatch)->size; -+ gDevWmt.pPatch = pPatch; -+ return 0; -+ } -+ return -1; -+ -+} -+ -+/*do not need contol uart because B/G/F send/receive data by BTIF*/ -+#if 0 -+INT32 wmt_ctrl_host_baudrate_set(P_WMT_CTRL_DATA pWmtCtrlData) -+{ -+ INT32 iRet = -1; -+ char cmdStr[NAME_MAX + 1] = { 0 }; -+ UINT32 u4Baudrate = pWmtCtrlData->au4CtrlData[0]; -+ UINT32 u4FlowCtrl = pWmtCtrlData->au4CtrlData[1]; -+ -+ WMT_DBG_FUNC("baud(%d), flowctrl(%d)\n", u4Baudrate, u4FlowCtrl); -+ -+ if (osal_test_bit(WMT_STAT_STP_OPEN, &gDevWmt.state)) { -+ osal_snprintf(cmdStr, NAME_MAX, "baud_%d_%d", u4Baudrate, u4FlowCtrl); -+ iRet = wmt_ctrl_ul_cmd(&gDevWmt, cmdStr); -+ if (iRet) { -+ WMT_WARN_FUNC("CTRL_BAUDRATE baud(%d), flowctrl(%d) fail(%d)\n", -+ u4Baudrate, pWmtCtrlData->au4CtrlData[1], iRet); -+ } else { -+ WMT_DBG_FUNC("CTRL_BAUDRATE baud(%d), flowctrl(%d) ok\n", u4Baudrate, u4FlowCtrl); -+ } -+ } else { -+ WMT_INFO_FUNC("CTRL_BAUDRATE but invalid Handle of WmtStp\n"); -+ } -+ return iRet; -+} -+#endif -+/*do not need control SDIO because wifi send/receive data by sdio*/ -+#if 0 -+INT32 wmt_ctrl_sdio_hw(P_WMT_CTRL_DATA pWmtCtrlData) -+{ -+ INT32 iRet = 0; -+ UINT32 statBit = WMT_STAT_SDIO1_ON; -+ P_DEV_WMT pDev = &gDevWmt; /* single instance */ -+ -+ WMT_SDIO_SLOT_NUM sdioSlotNum = pWmtCtrlData->au4CtrlData[0]; -+ ENUM_FUNC_STATE funcState = pWmtCtrlData->au4CtrlData[1]; -+ -+ if ((WMT_SDIO_SLOT_INVALID == sdioSlotNum) -+ || (WMT_SDIO_SLOT_MAX <= sdioSlotNum)) { -+ WMT_WARN_FUNC("CTRL_SDIO_SLOT(%d) but invalid slot num\n", sdioSlotNum); -+ return -1; -+ } -+ -+ WMT_DBG_FUNC("WMT_CTRL_SDIO_HW (0x%x, %d)\n", sdioSlotNum, funcState); -+ -+ if (WMT_SDIO_SLOT_SDIO2 == sdioSlotNum) -+ statBit = WMT_STAT_SDIO2_ON; -+ -+ if (funcState) { -+ if (osal_test_and_set_bit(statBit, &pDev->state)) { -+ WMT_WARN_FUNC("CTRL_SDIO_SLOT slotNum(%d) already ON\n", sdioSlotNum); -+ /* still return 0 */ -+ iRet = 0; -+ } else { -+ iRet = wmt_plat_sdio_ctrl(sdioSlotNum, FUNC_ON); -+ } -+ } else { -+ if (osal_test_and_clear_bit(statBit, &pDev->state)) { -+ iRet = wmt_plat_sdio_ctrl(sdioSlotNum, FUNC_OFF); -+ } else { -+ WMT_WARN_FUNC("CTRL_SDIO_SLOT slotNum(%d) already OFF\n", sdioSlotNum); -+ /* still return 0 */ -+ iRet = 0; -+ } -+ } -+ -+ return iRet; -+} -+ -+INT32 wmt_ctrl_sdio_func(P_WMT_CTRL_DATA pWmtCtrlData) -+{ -+ INT32 iRet = -1; -+ UINT32 statBit = WMT_STAT_SDIO_WIFI_ON; -+ INT32 retry = 10; -+ P_DEV_WMT pDev = &gDevWmt; /* single instance */ -+ WMT_SDIO_FUNC_TYPE sdioFuncType = pWmtCtrlData->au4CtrlData[0]; -+ UINT32 u4On = pWmtCtrlData->au4CtrlData[1]; -+ -+ if (WMT_SDIO_FUNC_MAX <= sdioFuncType) { -+ WMT_ERR_FUNC("CTRL_SDIO_FUNC, invalid func type (%d)\n", sdioFuncType); -+ return -1; -+ } -+ -+ if (WMT_SDIO_FUNC_STP == sdioFuncType) -+ statBit = WMT_STAT_SDIO_STP_ON; -+ -+ if (u4On) { -+ if (osal_test_bit(statBit, &pDev->state)) { -+ WMT_WARN_FUNC("CTRL_SDIO_FUNC(%d) but already ON\n", sdioFuncType); -+ iRet = 0; -+ } else { -+ while (retry-- > 0 && iRet != 0) { -+ if (iRet) { -+ /* sleep 150ms before sdio slot ON ready */ -+ osal_sleep_ms(150); -+ } -+ iRet = mtk_wcn_hif_sdio_wmt_control(sdioFuncType, MTK_WCN_BOOL_TRUE); -+ if (HIF_SDIO_ERR_NOT_PROBED == iRet) { -+ /* not probed case, retry */ -+ continue; -+ } else if (HIF_SDIO_ERR_CLT_NOT_REG == iRet) { -+ /* For WiFi, client not reg yet, no need to retry, -+ *WiFi function can work any time when wlan.ko -+ *is insert into system -+ */ -+ iRet = 0; -+ } else { -+ /* other fail cases, stop */ -+ break; -+ } -+ } -+ if (!retry || iRet) { -+ WMT_ERR_FUNC("mtk_wcn_hif_sdio_wmt_control(%d, TRUE) fail(%d) retry(%d)\n", -+ sdioFuncType, iRet, retry); -+ } else { -+ osal_set_bit(statBit, &pDev->state); -+ } -+ } -+ } else { -+ if (osal_test_bit(statBit, &pDev->state)) { -+ iRet = mtk_wcn_hif_sdio_wmt_control(sdioFuncType, MTK_WCN_BOOL_FALSE); -+ if (iRet) -+ WMT_ERR_FUNC("mtk_wcn_hif_sdio_wmt_control(%d, FALSE) fail(%d)\n", sdioFuncType, iRet); -+ /*any way, set to OFF state */ -+ osal_clear_bit(statBit, &pDev->state); -+ } else { -+ WMT_WARN_FUNC("CTRL_SDIO_FUNC(%d) but already OFF\n", sdioFuncType); -+ iRet = 0; -+ } -+ } -+ -+ return iRet; -+} -+#endif -+ -+ -+INT32 wmt_ctrl_hwidver_set(P_WMT_CTRL_DATA pWmtCtrlData) -+{ -+ P_DEV_WMT pDev = &gDevWmt; /* single instance */ -+ -+ /* input sanity check is done in wmt_ctrl() */ -+ pDev->chip_id = (pWmtCtrlData->au4CtrlData[0] & 0xFFFF0000) >> 16; -+ pDev->hw_ver = pWmtCtrlData->au4CtrlData[0] & 0x0000FFFF; -+ pDev->fw_ver = pWmtCtrlData->au4CtrlData[1] & 0x0000FFFF; -+ -+ /* TODO: [FixMe][GeorgeKuo] remove translated ENUM_WMTHWVER_TYPE_T in the future!!! */ -+ /* Only use hw_ver read from hw. */ -+ pDev->eWmtHwVer = (ENUM_WMTHWVER_TYPE_T) (pWmtCtrlData->au4CtrlData[1] & 0xFFFF0000) >> 16; -+ -+ return 0; -+} -+ -+INT32 wmt_ctrl_set_stp_dbg_info(P_WMT_CTRL_DATA pWmtCtrlData) -+{ -+ UINT8 *pRomVer = NULL; -+ P_WMT_PATCH pPatch = NULL; -+ UINT32 chipID = 0; -+ -+ chipID = pWmtCtrlData->au4CtrlData[0]; -+ pRomVer = (PUINT8) (pWmtCtrlData->au4CtrlData[1]); -+ pPatch = (P_WMT_PATCH) (pWmtCtrlData->au4CtrlData[2]); -+ if (!pRomVer) { -+ WMT_ERR_FUNC("pRomVer null pointer\n"); -+ return -1; -+ } -+ if (!pPatch) { -+ WMT_ERR_FUNC("pPatch null pointer\n"); -+ return -2; -+ } -+ WMT_DBG_FUNC("chipid(0x%x),rom(%s),patch date(%s),patch plat(%s)\n", chipID, pRomVer, pPatch->ucDateTime, -+ pPatch->ucPLat); -+ return stp_dbg_set_version_info(chipID, pRomVer, &(pPatch->ucDateTime[0]), &(pPatch->ucPLat[0])); -+} -+ -+static INT32 wmt_ctrl_bgw_desense_ctrl(P_WMT_CTRL_DATA pWmtCtrlData) -+{ -+ UINT32 cmd = pWmtCtrlData->au4CtrlData[0]; -+ -+ WMT_INFO_FUNC("wmt-ctrl:send native cmd(%d)\n", cmd); -+ wmt_dev_send_cmd_to_daemon(cmd); -+ -+ return 0; -+} -+ -+static INT32 wmt_ctrl_evt_err_trg_assert(P_WMT_CTRL_DATA pWmtCtrlData) -+{ -+ INT32 iRet = -1; -+ -+ ENUM_WMTDRV_TYPE_T drv_type; -+ UINT32 reason = 0; -+ -+ drv_type = pWmtCtrlData->au4CtrlData[0]; -+ reason = pWmtCtrlData->au4CtrlData[1]; -+ WMT_WARN_FUNC("wmt-ctrl:drv_type(%d),reason(%d)\n", drv_type, reason); -+ -+ if (0 == mtk_wcn_stp_get_wmt_evt_err_trg_assert()) { -+ mtk_wcn_stp_set_wmt_evt_err_trg_assert(1); -+ wmt_lib_set_host_assert_info(drv_type, reason, 1); -+ -+ iRet = mtk_wcn_stp_wmt_evt_err_trg_assert(); -+ if (iRet) -+ mtk_wcn_stp_set_wmt_evt_err_trg_assert(0); -+ } else { -+ /* maybe assert triggered by stp noack*/ -+ WMT_INFO_FUNC("do trigger assert & chip reset in stp noack\n"); -+ } -+ return 0; -+} -+ -+#if CFG_WMT_LTE_COEX_HANDLING -+static INT32 wmt_ctrl_get_tdm_req_antsel(P_WMT_CTRL_DATA pWmtCtrlData) -+{ -+ INT32 antsel_index = wmt_plat_get_tdm_antsel_index(); -+ -+ if (0 <= antsel_index) -+ pWmtCtrlData->au4CtrlData[0] = antsel_index; -+ else -+ pWmtCtrlData->au4CtrlData[0] = 0xff; -+ -+ WMT_INFO_FUNC("get tdm req antsel index is %d\n", antsel_index); -+ -+ return 0; -+} -+#endif -+ -+static INT32 wmt_ctrl_evt_parser(P_WMT_CTRL_DATA pWmtCtrlData) -+{ -+ INT32 ret = -1; -+ UINT32 evt_idx = (UINT32) pWmtCtrlData->au4CtrlData[0]; -+ UINT8 *p_buf = NULL; -+ -+ static UINT8 sleep_evt[] = { 0x02, 0x03, 0x02, 0x00, 0x00, 0x01 }; -+ static UINT8 wakeup_evt[] = { 0x02, 0x03, 0x02, 0x00, 0x00, 0x03 }; -+ static UINT8 hostawake_evt[] = { 0x02, 0x03, 0x02, 0x00, 0x00, 0x02 }; -+ static UINT8 *evt_array[] = { sleep_evt, wakeup_evt, hostawake_evt }; -+ -+ p_buf = evt_array[evt_idx - 1]; -+ -+ WMT_INFO_FUNC("evt index:%d,p_buf:%p\n", evt_idx, p_buf); -+ -+ ret = mtk_wcn_consys_stp_btif_parser_wmt_evt(p_buf, 6); -+ if (ret == 1) { -+ WMT_INFO_FUNC("parser wmt evt from BTIF buf is OK\n"); -+ return 0; -+ } -+ WMT_ERR_FUNC("parser wmt evt from BTIF buf fail(%d)\n", ret); -+ return -1; -+} -+ -+static INT32 wmt_ctrl_gps_sync_set(P_WMT_CTRL_DATA pData) -+{ -+ INT32 iret; -+ -+ WMT_INFO_FUNC("ctrl GPS_SYNC(%d)\n", (0 == pData->au4CtrlData[0]) ? PIN_STA_DEINIT : PIN_STA_MUX); -+ iret = wmt_plat_gpio_ctrl(PIN_GPS_SYNC, (0 == pData->au4CtrlData[0]) ? PIN_STA_DEINIT : PIN_STA_MUX); -+ -+ if (iret) { -+ WMT_WARN_FUNC("ctrl GPS_SYNC(%d) fail!(%d) ignore it...\n", -+ (0 == pData->au4CtrlData[0]) ? PIN_STA_DEINIT : PIN_STA_MUX, iret); -+ } -+ -+ return 0; -+} -+ -+static INT32 wmt_ctrl_gps_lna_set(P_WMT_CTRL_DATA pData) -+{ -+ INT32 iret; -+ -+ WMT_INFO_FUNC("ctrl GPS_LNA(%d)\n", (0 == pData->au4CtrlData[0]) ? PIN_STA_DEINIT : PIN_STA_OUT_H); -+ iret = wmt_plat_gpio_ctrl(PIN_GPS_LNA, (0 == pData->au4CtrlData[0]) ? PIN_STA_DEINIT : PIN_STA_OUT_H); -+ -+ if (iret) { -+ WMT_WARN_FUNC("ctrl GPS_SYNC(%d) fail!(%d) ignore it...\n", -+ (0 == pData->au4CtrlData[0]) ? PIN_STA_DEINIT : PIN_STA_OUT_H, iret); -+ } -+ -+ return 0; -+} -+ -+INT32 wmt_ctrl_stp_rst(P_WMT_CTRL_DATA pWmtCtrlData) -+{ -+ return 0; -+} -+ -+INT32 wmt_ctrl_get_wmt_conf(P_WMT_CTRL_DATA pWmtCtrlData) -+{ -+ P_DEV_WMT pDev = &gDevWmt; /* single instance */ -+ -+ pWmtCtrlData->au4CtrlData[0] = (SIZE_T) &pDev->rWmtGenConf; -+ -+ return 0; -+} -+ -+INT32 wmt_ctrl_others(P_WMT_CTRL_DATA pWmtCtrlData) -+{ -+ WMT_ERR_FUNC("wmt_ctrl_others, invalid CTRL ID (%d)\n", pWmtCtrlData->ctrlId); -+ return -1; -+} -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_func.c b/drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_func.c -new file mode 100644 -index 000000000000..d42d572c9292 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_func.c -@@ -0,0 +1,713 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -+ -+/*! \file -+ \brief Declaration of library functions -+ -+ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+#ifdef DFT_TAG -+#undef DFT_TAG -+#endif -+#define DFT_TAG "[WMT-FUNC]" -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "osal_typedef.h" -+ -+#include "wmt_func.h" -+#include "wmt_lib.h" -+#include "wmt_core.h" -+#include "wmt_exp.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+#if CFG_FUNC_BT_SUPPORT -+ -+static INT32 wmt_func_bt_on(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf); -+static INT32 wmt_func_bt_off(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf); -+ -+WMT_FUNC_OPS wmt_func_bt_ops = { -+ /* BT subsystem function on/off */ -+ .func_on = wmt_func_bt_on, -+ .func_off = wmt_func_bt_off -+}; -+#endif -+ -+#if CFG_FUNC_FM_SUPPORT -+ -+static INT32 wmt_func_fm_on(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf); -+static INT32 wmt_func_fm_off(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf); -+ -+WMT_FUNC_OPS wmt_func_fm_ops = { -+ /* FM subsystem function on/off */ -+ .func_on = wmt_func_fm_on, -+ .func_off = wmt_func_fm_off -+}; -+#endif -+ -+#if CFG_FUNC_GPS_SUPPORT -+ -+static INT32 wmt_func_gps_on(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf); -+static INT32 wmt_func_gps_off(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf); -+ -+WMT_FUNC_OPS wmt_func_gps_ops = { -+ /* GPS subsystem function on/off */ -+ .func_on = wmt_func_gps_on, -+ .func_off = wmt_func_gps_off -+}; -+ -+#endif -+ -+#if CFG_FUNC_WIFI_SUPPORT -+static INT32 wmt_func_wifi_on(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf); -+static INT32 wmt_func_wifi_off(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf); -+ -+WMT_FUNC_OPS wmt_func_wifi_ops = { -+ /* Wi-Fi subsystem function on/off */ -+ .func_on = wmt_func_wifi_on, -+ .func_off = wmt_func_wifi_off -+}; -+#endif -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+#if CFG_FUNC_GPS_SUPPORT -+CMB_PIN_CTRL_REG eediPinOhRegs[] = { -+ { -+ /* pull down ctrl register */ -+ .regAddr = 0x80050020, -+ .regValue = ~(0x1 << 5), -+ .regMask = 0x00000020, -+ }, -+ { -+ /* pull up ctrl register */ -+ .regAddr = 0x80050000, -+ .regValue = 0x1 << 5, -+ .regMask = 0x00000020, -+ }, -+ { -+ /* iomode ctrl register */ -+ .regAddr = 0x80050110, -+ .regValue = 0x1 << 0, -+ .regMask = 0x00000007, -+ }, -+ { -+ /* output high/low ctrl register */ -+ .regAddr = 0x80050040, -+ .regValue = 0x1 << 5, -+ .regMask = 0x00000020, -+ } -+ -+}; -+ -+CMB_PIN_CTRL_REG eediPinOlRegs[] = { -+ { -+ .regAddr = 0x80050020, -+ .regValue = 0x1 << 5, -+ .regMask = 0x00000020UL, -+ }, -+ { -+ .regAddr = 0x80050000, -+ .regValue = ~(0x1 << 5), -+ .regMask = 0x00000020, -+ }, -+ { -+ .regAddr = 0x80050110, -+ .regValue = 0x1 << 0, -+ .regMask = 0x00000007, -+ }, -+ { -+ .regAddr = 0x80050040, -+ .regValue = ~(0x1 << 5), -+ .regMask = 0x00000020, -+ } -+}; -+ -+CMB_PIN_CTRL_REG eedoPinOhRegs[] = { -+ { -+ .regAddr = 0x80050020, -+ .regValue = ~(0x1 << 7), -+ .regMask = 0x00000080UL, -+ }, -+ { -+ .regAddr = 0x80050000, -+ .regValue = 0x1 << 7, -+ .regMask = 0x00000080UL, -+ }, -+ { -+ .regAddr = 0x80050110, -+ .regValue = 0x1 << 12, -+ .regMask = 0x00007000UL, -+ }, -+ { -+ .regAddr = 0x80050040, -+ .regValue = 0x1 << 7, -+ .regMask = 0x00000080, -+ } -+}; -+ -+CMB_PIN_CTRL_REG eedoPinOlRegs[] = { -+ { -+ .regAddr = 0x80050020, -+ .regValue = 0x1 << 7, -+ .regMask = 0x00000080, -+ }, -+ { -+ .regAddr = 0x80050000, -+ .regValue = ~(0x1 << 7), -+ .regMask = 0x00000080, -+ }, -+ { -+ .regAddr = 0x80050110, -+ .regValue = 0x1 << 12, -+ .regMask = 0x00007000, -+ }, -+ { -+ .regAddr = 0x80050040, -+ .regValue = ~(0x1 << 7), -+ .regMask = 0x00000080, -+ } -+ -+}; -+ -+CMB_PIN_CTRL_REG gsyncPinOnRegs[] = { -+ { -+ .regAddr = 0x80050110, -+ .regValue = 0x3 << 20, -+ .regMask = 0x7 << 20, -+ } -+ -+}; -+ -+CMB_PIN_CTRL_REG gsyncPinOffRegs[] = { -+ { -+ .regAddr = 0x80050110, -+ .regValue = 0x0 << 20, -+ .regMask = 0x7 << 20, -+ } -+}; -+ -+/* templete usage for GPIO control */ -+CMB_PIN_CTRL gCmbPinCtrl[3] = { -+ { -+ .pinId = CMB_PIN_EEDI_ID, -+ .regNum = 4, -+ .pFuncOnArray = eediPinOhRegs, -+ .pFuncOffArray = eediPinOlRegs, -+ }, -+ { -+ .pinId = CMB_PIN_EEDO_ID, -+ .regNum = 4, -+ .pFuncOnArray = eedoPinOhRegs, -+ .pFuncOffArray = eedoPinOlRegs, -+ }, -+ { -+ .pinId = CMB_PIN_GSYNC_ID, -+ .regNum = 1, -+ .pFuncOnArray = gsyncPinOnRegs, -+ .pFuncOffArray = gsyncPinOffRegs, -+ } -+}; -+#endif -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#if CFG_FUNC_BT_SUPPORT -+ -+INT32 _osal_inline_ wmt_func_bt_ctrl(ENUM_FUNC_STATE funcState) -+{ -+ /*only need to send turn BT subsystem wmt command */ -+ return wmt_core_func_ctrl_cmd(WMTDRV_TYPE_BT, (FUNC_ON == funcState) ? MTK_WCN_BOOL_TRUE : MTK_WCN_BOOL_FALSE); -+} -+ -+INT32 wmt_func_bt_on(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf) -+{ -+ /* return wmt_func_bt_ctrl(FUNC_ON); */ -+ INT32 iRet = -1; -+ unsigned long ctrlPa1; -+ unsigned long ctrlPa2; -+ -+ ctrlPa1 = BT_PALDO; -+ ctrlPa2 = PALDO_ON; -+ iRet = wmt_core_ctrl(WMT_CTRL_SOC_PALDO_CTRL, &ctrlPa1, &ctrlPa2); -+ if (iRet) { -+ WMT_ERR_FUNC("wmt-func: wmt_ctrl_soc_paldo_ctrl failed(%d)(%d)(%d)\n", iRet, ctrlPa1, ctrlPa2); -+ return -1; -+ } -+ iRet = wmt_core_func_ctrl_cmd(WMTDRV_TYPE_BT, MTK_WCN_BOOL_TRUE); -+ if (iRet) { -+ WMT_ERR_FUNC("wmt-func: wmt_core_func_ctrl_cmd(bt_on) failed(%d)\n", iRet); -+ ctrlPa1 = BT_PALDO; -+ ctrlPa2 = PALDO_OFF; -+ wmt_core_ctrl(WMT_CTRL_SOC_PALDO_CTRL, &ctrlPa1, &ctrlPa2); -+ -+ /*do coredump when bt on fail */ -+ wmt_core_set_coredump_state(DRV_STS_FUNC_ON); -+ ctrlPa1 = WMTDRV_TYPE_BT; -+ ctrlPa2 = 32; -+ wmt_core_ctrl(WMT_CTRL_EVT_ERR_TRG_ASSERT, &ctrlPa1, &ctrlPa2); -+ return -2; -+ } -+ osal_set_bit(WMT_BT_ON, &gBtWifiGpsState); -+ if (osal_test_bit(WMT_GPS_ON, &gBtWifiGpsState)) { -+ /* send msg to GPS native for sending de-sense CMD */ -+ ctrlPa1 = 1; -+ ctrlPa2 = 0; -+ wmt_core_ctrl(WMT_CTRL_BGW_DESENSE_CTRL, &ctrlPa1, &ctrlPa2); -+ } -+ return 0; -+} -+ -+INT32 wmt_func_bt_off(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf) -+{ -+ /* return wmt_func_bt_ctrl(FUNC_OFF); */ -+ INT32 iRet1 = -1; -+ INT32 iRet2 = -1; -+ unsigned long ctrlPa1; -+ unsigned long ctrlPa2; -+ -+ iRet1 = wmt_core_func_ctrl_cmd(WMTDRV_TYPE_BT, MTK_WCN_BOOL_FALSE); -+ if (iRet1) -+ WMT_ERR_FUNC("wmt-func: wmt_core_func_ctrl_cmd(bt_off) failed(%d)\n", iRet1); -+ -+ ctrlPa1 = BT_PALDO; -+ ctrlPa2 = PALDO_OFF; -+ iRet2 = wmt_core_ctrl(WMT_CTRL_SOC_PALDO_CTRL, &ctrlPa1, &ctrlPa2); -+ if (iRet2) -+ WMT_ERR_FUNC("wmt-func: wmt_ctrl_soc_paldo_ctrl(bt_off) failed(%d)\n", iRet2); -+ -+ if (iRet1 + iRet2) { -+ /*do coredump when bt off fail */ -+ wmt_core_set_coredump_state(DRV_STS_FUNC_ON); -+ ctrlPa1 = WMTDRV_TYPE_BT; -+ ctrlPa2 = 32; -+ wmt_core_ctrl(WMT_CTRL_EVT_ERR_TRG_ASSERT, &ctrlPa1, &ctrlPa2); -+ return -1; -+ } -+ -+ osal_clear_bit(WMT_BT_ON, &gBtWifiGpsState); -+ if ((!osal_test_bit(WMT_WIFI_ON, &gBtWifiGpsState)) && (osal_test_bit(WMT_GPS_ON, &gBtWifiGpsState))) { -+ /* send msg to GPS native for stopping send de-sense CMD */ -+ ctrlPa1 = 0; -+ ctrlPa2 = 0; -+ wmt_core_ctrl(WMT_CTRL_BGW_DESENSE_CTRL, &ctrlPa1, &ctrlPa2); -+ } -+ return 0; -+} -+ -+#endif -+ -+#if CFG_FUNC_GPS_SUPPORT -+ -+INT32 _osal_inline_ wmt_func_gps_ctrl(ENUM_FUNC_STATE funcState) -+{ -+ /*send turn GPS subsystem wmt command */ -+ return wmt_core_func_ctrl_cmd(WMTDRV_TYPE_GPS, (FUNC_ON == funcState) ? MTK_WCN_BOOL_TRUE : MTK_WCN_BOOL_FALSE); -+} -+ -+INT32 wmt_func_gps_pre_ctrl(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf, ENUM_FUNC_STATE funcStatus) -+{ -+ UINT32 i = 0; -+ INT32 iRet = 0; -+ UINT32 regAddr = 0; -+ UINT32 regValue = 0; -+ UINT32 regMask = 0; -+ UINT32 regNum = 0; -+ P_CMB_PIN_CTRL_REG pReg; -+ P_CMB_PIN_CTRL pCmbPinCtrl = &gCmbPinCtrl[CMB_PIN_GSYNC_ID]; -+ WMT_CTRL_DATA ctrlData; -+ WMT_IC_PIN_ID wmtIcPinId = WMT_IC_PIN_MAX; -+ /* sanity check */ -+ if (FUNC_ON != funcStatus && FUNC_OFF != funcStatus) { -+ WMT_ERR_FUNC("invalid funcStatus(%d)\n", funcStatus); -+ return -1; -+ } -+ /* turn on GPS sync function on both side */ -+ ctrlData.ctrlId = WMT_CTRL_GPS_SYNC_SET; -+ ctrlData.au4CtrlData[0] = (FUNC_ON == funcStatus) ? 1 : 0; -+ iRet = wmt_ctrl(&ctrlData); -+ if (iRet) { -+ /*we suppose this would never print */ -+ WMT_ERR_FUNC("ctrl GPS_SYNC_SET(%d) fail, ret(%d)\n", funcStatus, iRet); -+ /* TODO:[FixMe][George] error handling? */ -+ return -2; -+ } -+ WMT_INFO_FUNC("ctrl GPS_SYNC_SET(%d) ok\n", funcStatus); -+ -+ -+ if ((NULL == pOps->ic_pin_ctrl) || -+ (0 > pOps->ic_pin_ctrl( -+ WMT_IC_PIN_GSYNC, -+ FUNC_ON == funcStatus ? WMT_IC_PIN_MUX : WMT_IC_PIN_GPIO, -+ 1))) { /*WMT_IC_PIN_GSYNC */ -+ pCmbPinCtrl = &gCmbPinCtrl[CMB_PIN_GSYNC_ID]; -+ regNum = pCmbPinCtrl->regNum; -+ for (i = 0; i < regNum; i++) { -+ if (FUNC_ON == funcStatus) -+ pReg = &pCmbPinCtrl->pFuncOnArray[i]; -+ else -+ pReg = &pCmbPinCtrl->pFuncOffArray[i]; -+ -+ regAddr = pReg->regAddr; -+ regValue = pReg->regValue; -+ regMask = pReg->regMask; -+ -+ iRet = wmt_core_reg_rw_raw(1, regAddr, ®Value, regMask); -+ if (iRet) { -+ WMT_ERR_FUNC("set reg for GPS_SYNC function fail(%d)\n", iRet); -+ /* TODO:[FixMe][Chaozhong] error handling? */ -+ return -2; -+ } -+ -+ } -+ } else { -+ WMT_INFO_FUNC("set reg for GPS_SYNC function okay by chip ic_pin_ctrl\n"); -+ } -+ WMT_INFO_FUNC("ctrl combo chip gps sync function succeed\n"); -+ /* turn on GPS lna ctrl function */ -+ if (NULL != pConf) { -+ if (0 == pConf->wmt_gps_lna_enable) { -+ -+ WMT_INFO_FUNC("host pin used for gps lna\n"); -+ /* host LNA ctrl pin needed */ -+ ctrlData.ctrlId = WMT_CTRL_GPS_LNA_SET; -+ ctrlData.au4CtrlData[0] = FUNC_ON == funcStatus ? 1 : 0; -+ iRet = wmt_ctrl(&ctrlData); -+ if (iRet) { -+ /*we suppose this would never print */ -+ WMT_ERR_FUNC("ctrl host GPS_LNA output high fail, ret(%d)\n", iRet); -+ /* TODO:[FixMe][Chaozhong] error handling? */ -+ return -3; -+ } -+ WMT_INFO_FUNC("ctrl host gps lna function succeed\n"); -+ } else { -+ WMT_INFO_FUNC("combo chip pin(%s) used for gps lna\n", -+ 0 == pConf->wmt_gps_lna_pin ? "EEDI" : "EEDO"); -+ wmtIcPinId = 0 == pConf->wmt_gps_lna_pin ? WMT_IC_PIN_EEDI : WMT_IC_PIN_EEDO; -+ if ((NULL == pOps->ic_pin_ctrl) || -+ (0 > pOps->ic_pin_ctrl( -+ wmtIcPinId, -+ FUNC_ON == funcStatus ? WMT_IC_PIN_GPIO_HIGH : WMT_IC_PIN_GPIO_LOW, -+ 1))) { /*WMT_IC_PIN_GSYNC */ -+ if (0 == pConf->wmt_gps_lna_pin) { -+ /* EEDI needed */ -+ pCmbPinCtrl = &gCmbPinCtrl[CMB_PIN_EEDI_ID]; -+ } else if (1 == pConf->wmt_gps_lna_pin) { -+ /* EEDO needed */ -+ pCmbPinCtrl = &gCmbPinCtrl[CMB_PIN_EEDO_ID]; -+ } -+ regNum = pCmbPinCtrl->regNum; -+ for (i = 0; i < regNum; i++) { -+ if (FUNC_ON == funcStatus) -+ pReg = &pCmbPinCtrl->pFuncOnArray[i]; -+ else -+ pReg = &pCmbPinCtrl->pFuncOffArray[i]; -+ regAddr = pReg->regAddr; -+ regValue = pReg->regValue; -+ regMask = pReg->regMask; -+ -+ iRet = wmt_core_reg_rw_raw(1, regAddr, ®Value, regMask); -+ if (iRet) { -+ WMT_ERR_FUNC("set reg for GPS_LNA function fail(%d)\n", iRet); -+ /* TODO:[FixMe][Chaozhong] error handling? */ -+ return -3; -+ } -+ } -+ WMT_INFO_FUNC("ctrl combo chip gps lna succeed\n"); -+ } else { -+ WMT_INFO_FUNC("set reg for GPS_LNA function okay by chip ic_pin_ctrl\n"); -+ } -+ } -+ } -+ return 0; -+ -+} -+ -+INT32 wmt_func_gps_pre_on(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf) -+{ -+ return wmt_func_gps_pre_ctrl(pOps, pConf, FUNC_ON); -+} -+ -+INT32 wmt_func_gps_pre_off(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf) -+{ -+ -+ return wmt_func_gps_pre_ctrl(pOps, pConf, FUNC_OFF); -+} -+ -+INT32 wmt_func_gps_on(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf) -+{ -+ INT32 iRet = 0; -+ unsigned long ctrlPa1; -+ unsigned long ctrlPa2; -+ UINT8 co_clock_type = (pConf->co_clock_flag & 0x0f); -+ -+ if ((co_clock_type) && (0 == pConf->wmt_gps_lna_enable)) { /* use SOC external LNA */ -+ if (!osal_test_bit(WMT_FM_ON, &gGpsFmState)) { -+ ctrlPa1 = GPS_PALDO; -+ ctrlPa2 = PALDO_ON; -+ wmt_core_ctrl(WMT_CTRL_SOC_PALDO_CTRL, &ctrlPa1, &ctrlPa2); -+ } else { -+ WMT_INFO_FUNC("LDO VCN28 has been turn on by FM\n"); -+ } -+ } -+ -+ iRet = wmt_func_gps_pre_on(pOps, pConf); -+ if (0 == iRet) { -+ iRet = wmt_func_gps_ctrl(FUNC_ON); -+ if (!iRet) { -+ osal_set_bit(WMT_GPS_ON, &gBtWifiGpsState); -+ if ((osal_test_bit(WMT_BT_ON, &gBtWifiGpsState)) -+ || (osal_test_bit(WMT_WIFI_ON, &gBtWifiGpsState))) { -+ /* send msg to GPS native for sending de-sense CMD */ -+ ctrlPa1 = 1; -+ ctrlPa2 = 0; -+ wmt_core_ctrl(WMT_CTRL_BGW_DESENSE_CTRL, &ctrlPa1, &ctrlPa2); -+ } -+ -+ if ((co_clock_type) && (0 == pConf->wmt_gps_lna_enable)) /* use SOC external LNA */ -+ osal_set_bit(WMT_GPS_ON, &gGpsFmState); -+ } -+ } -+ return iRet; -+} -+ -+INT32 wmt_func_gps_off(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf) -+{ -+ INT32 iRet = 0; -+ unsigned long ctrlPa1 = 0; -+ unsigned long ctrlPa2 = 0; -+ UINT8 co_clock_type = (pConf->co_clock_flag & 0x0f); -+ -+ iRet = wmt_func_gps_pre_off(pOps, pConf); -+ if (0 == iRet) { -+ iRet = wmt_func_gps_ctrl(FUNC_OFF); -+ if (!iRet) { -+ osal_clear_bit(WMT_GPS_ON, &gBtWifiGpsState); -+ if ((osal_test_bit(WMT_BT_ON, &gBtWifiGpsState)) -+ || (osal_test_bit(WMT_WIFI_ON, &gBtWifiGpsState))) { -+ /* send msg to GPS native for stop sending de-sense CMD */ -+ ctrlPa1 = 0; -+ ctrlPa2 = 0; -+ wmt_core_ctrl(WMT_CTRL_BGW_DESENSE_CTRL, &ctrlPa1, &ctrlPa2); -+ } -+ } -+ } -+ -+ if ((co_clock_type) && (0 == pConf->wmt_gps_lna_enable)) { /* use SOC external LNA */ -+ if (osal_test_bit(WMT_FM_ON, &gGpsFmState)) -+ WMT_INFO_FUNC("FM is still on, do not turn off LDO VCN28\n"); -+ else { -+ ctrlPa1 = GPS_PALDO; -+ ctrlPa2 = PALDO_OFF; -+ wmt_core_ctrl(WMT_CTRL_SOC_PALDO_CTRL, &ctrlPa1, &ctrlPa2); -+ } -+ -+ osal_clear_bit(WMT_GPS_ON, &gGpsFmState); -+ } -+ -+ return iRet; -+ -+} -+#endif -+ -+#if CFG_FUNC_FM_SUPPORT -+ -+INT32 _osal_inline_ wmt_func_fm_ctrl(ENUM_FUNC_STATE funcState) -+{ -+ /*only need to send turn FM subsystem wmt command */ -+ return wmt_core_func_ctrl_cmd(WMTDRV_TYPE_FM, (FUNC_ON == funcState) ? MTK_WCN_BOOL_TRUE : MTK_WCN_BOOL_FALSE); -+} -+ -+INT32 wmt_func_fm_on(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf) -+{ -+ /* return wmt_func_fm_ctrl(FUNC_ON); */ -+ unsigned long ctrlPa1 = 0; -+ unsigned long ctrlPa2 = 0; -+ INT32 iRet = -1; -+ UINT8 co_clock_type = (pConf->co_clock_flag & 0x0f); -+ -+ if (co_clock_type) { -+ if (!osal_test_bit(WMT_GPS_ON, &gGpsFmState)) { -+ ctrlPa1 = FM_PALDO; -+ ctrlPa2 = PALDO_ON; -+ wmt_core_ctrl(WMT_CTRL_SOC_PALDO_CTRL, &ctrlPa1, &ctrlPa2); -+ } else { -+ WMT_INFO_FUNC("LDO VCN28 has been turn on by GPS\n"); -+ } -+ } -+ -+ iRet = wmt_core_func_ctrl_cmd(WMTDRV_TYPE_FM, MTK_WCN_BOOL_TRUE); -+ if (!iRet) { -+ if (co_clock_type) -+ osal_set_bit(WMT_FM_ON, &gGpsFmState); -+ } -+ -+ return iRet; -+} -+ -+INT32 wmt_func_fm_off(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf) -+{ -+ /* return wmt_func_fm_ctrl(FUNC_OFF); */ -+ unsigned long ctrlPa1 = 0; -+ unsigned long ctrlPa2 = 0; -+ INT32 iRet = -1; -+ UINT8 co_clock_type = (pConf->co_clock_flag & 0x0f); -+ -+ iRet = wmt_core_func_ctrl_cmd(WMTDRV_TYPE_FM, MTK_WCN_BOOL_FALSE); -+ -+ if (co_clock_type) { -+ if (osal_test_bit(WMT_GPS_ON, &gGpsFmState)) { -+ WMT_INFO_FUNC("GPS is still on, do not turn off LDO VCN28\n"); -+ } else { -+ ctrlPa1 = FM_PALDO; -+ ctrlPa2 = PALDO_OFF; -+ wmt_core_ctrl(WMT_CTRL_SOC_PALDO_CTRL, &ctrlPa1, &ctrlPa2); -+ } -+ -+ osal_clear_bit(WMT_FM_ON, &gGpsFmState); -+ } -+ -+ return iRet; -+} -+ -+#endif -+ -+#if CFG_FUNC_WIFI_SUPPORT -+ -+/*in soc, wmt turn on wifi directly, no not need operate SDIO*/ -+#if 0 -+INT32 wmt_func_wifi_ctrl(ENUM_FUNC_STATE funcState) -+{ -+ INT32 iRet = 0; -+ unsigned long ctrlPa1 = WMT_SDIO_FUNC_WIFI; -+ unsigned long ctrlPa2 = (FUNC_ON == funcState) ? 1 : 0; /* turn on Wi-Fi driver */ -+ -+ iRet = wmt_core_ctrl(WMT_CTRL_SDIO_FUNC, &ctrlPa1, &ctrlPa2); -+ if (iRet) { -+ WMT_ERR_FUNC("WMT-FUNC: turn on WIFI function fail (%d)", iRet); -+ return -1; -+ } -+ return 0; -+} -+#endif -+ -+INT32 wmt_func_wifi_on(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf) -+{ -+ int iRet = 0; -+ unsigned long ctrlPa1; -+ unsigned long ctrlPa2; -+ -+ if (NULL != mtk_wcn_wlan_probe) { -+ -+ WMT_WARN_FUNC("WMT-FUNC: wmt wlan func on before wlan probe\n"); -+ iRet = (*mtk_wcn_wlan_probe) (); -+ if (iRet) { -+ WMT_ERR_FUNC("WMT-FUNC: wmt call wlan probe fail(%d)\n", iRet); -+ iRet = -1; -+ } else { -+ WMT_WARN_FUNC("WMT-FUNC: wmt call wlan probe ok\n"); -+ } -+ } else { -+ WMT_ERR_FUNC("WMT-FUNC: null pointer mtk_wcn_wlan_probe\n"); -+ gWifiProbed = 1; -+ iRet = -2; -+ } -+ -+ if (!iRet) { -+ osal_set_bit(WMT_WIFI_ON, &gBtWifiGpsState); -+ if (osal_test_bit(WMT_GPS_ON, &gBtWifiGpsState)) { -+ /* send msg to GPS native for sending de-sense CMD */ -+ ctrlPa1 = 1; -+ ctrlPa2 = 0; -+ wmt_core_ctrl(WMT_CTRL_BGW_DESENSE_CTRL, &ctrlPa1, &ctrlPa2); -+ } -+ } -+ return iRet; -+#if 0 -+ return wmt_func_wifi_ctrl(FUNC_ON); -+#endif -+} -+ -+INT32 wmt_func_wifi_off(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf) -+{ -+ int iRet = 0; -+ -+ unsigned long ctrlPa1 = 0; -+ unsigned long ctrlPa2 = 0; -+ -+ if (NULL != mtk_wcn_wlan_remove) { -+ -+ WMT_WARN_FUNC("WMT-FUNC: wmt wlan func on before wlan remove\n"); -+ iRet = (*mtk_wcn_wlan_remove) (); -+ if (iRet) { -+ WMT_ERR_FUNC("WMT-FUNC: wmt call wlan remove fail(%d)\n", iRet); -+ iRet = -1; -+ } else { -+ WMT_WARN_FUNC("WMT-FUNC: wmt call wlan remove ok\n"); -+ } -+ } else { -+ WMT_ERR_FUNC("WMT-FUNC: null pointer mtk_wcn_wlan_remove\n"); -+ iRet = -2; -+ } -+ -+ if (!iRet) { -+ osal_clear_bit(WMT_WIFI_ON, &gBtWifiGpsState); -+ if ((!osal_test_bit(WMT_BT_ON, &gBtWifiGpsState)) && (osal_test_bit(WMT_GPS_ON, &gBtWifiGpsState))) { -+ /* send msg to GPS native for stopping send de-sense CMD */ -+ ctrlPa1 = 0; -+ ctrlPa2 = 0; -+ wmt_core_ctrl(WMT_CTRL_BGW_DESENSE_CTRL, &ctrlPa1, &ctrlPa2); -+ } -+ } -+ return iRet; -+#if 0 -+ return wmt_func_wifi_ctrl(FUNC_OFF); -+#endif -+} -+#endif -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_ic_soc.c b/drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_ic_soc.c -new file mode 100644 -index 000000000000..c07052bce8e6 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_ic_soc.c -@@ -0,0 +1,2452 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -+ -+/*! \file -+ \brief Declaration of library functions -+ -+ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+#ifdef DFT_TAG -+#undef DFT_TAG -+#endif -+#define DFT_TAG "[WMT-IC]" -+#define CFG_IC_SOC 1 -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "osal_typedef.h" -+#include "wmt_ic.h" -+#include "wmt_core.h" -+#include "wmt_lib.h" -+#include "stp_core.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+#define DEFAULT_PATCH_FRAG_SIZE (1000) -+#define WMT_PATCH_FRAG_1ST (0x1) -+#define WMT_PATCH_FRAG_MID (0x2) -+#define WMT_PATCH_FRAG_LAST (0x3) -+ -+#define CFG_CHECK_WMT_RESULT (1) -+/* BT Port 2 Feature. this command does not need -+ * after coex command is downconfirmed by LC, -+ */ -+#define CFG_WMT_BT_PORT2 (0) -+ -+#define CFG_SET_OPT_REG (0) -+#define CFG_WMT_I2S_DBGUART_SUPPORT (0) -+#define CFG_SET_OPT_REG_SWLA (0) -+#define CFG_SET_OPT_REG_MCUCLK (0) -+#define CFG_SET_OPT_REG_MCUIRQ (0) -+ -+#define CFG_SUBSYS_COEX_NEED 0 -+ -+#define CFG_WMT_COREDUMP_ENABLE 0 -+ -+#define CFG_WMT_MULTI_PATCH (1) -+ -+#define CFG_WMT_CRYSTAL_TIMING_SET (0) -+ -+#define CFG_WMT_SDIO_DRIVING_SET (0) -+ -+#define CFG_WMT_UART_HIF_USE (0) -+ -+#define CFG_WMT_WIFI_5G_SUPPORT (1) -+ -+#define CFG_WMT_PATCH_DL_OPTM (1) -+#if CFG_WMT_LTE_COEX_HANDLING -+#define CFG_WMT_FILTER_MODE_SETTING (1) -+#else -+#define CFG_WMT_FILTER_MODE_SETTING (0) -+#endif -+#define MTK_WCN_CMB_MERGE_INTERFACE_SUPPORT (0) -+ -+#define CFG_WMT_POWER_ON_DLM (1) -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+static UINT8 gFullPatchName[NAME_MAX + 1]; -+static const WMT_IC_INFO_S *gp_soc_info; -+static WMT_PATCH gp_soc_patch_info; -+static WMT_CO_CLOCK gCoClockEn = WMT_CO_CLOCK_DIS; -+#if 0 -+static UINT8 WMT_WAKEUP_DIS_GATE_CMD[] = { 0x1, 0x3, 0x01, 0x00, 0x04 }; -+static UINT8 WMT_WAKEUP_DIS_GATE_EVT[] = { 0x2, 0x3, 0x02, 0x0, 0x0, 0x04 }; -+ -+static UINT8 WMT_WAKEUP_EN_GATE_CMD[] = { 0x1, 0x3, 0x01, 0x00, 0x05 }; -+static UINT8 WMT_WAKEUP_EN_GATE_EVT[] = { 0x2, 0x3, 0x02, 0x0, 0x0, 0x05 }; -+#endif -+ -+#if CFG_WMT_UART_HIF_USE -+static UINT8 WMT_QUERY_BAUD_CMD[] = { 0x01, 0x04, 0x01, 0x00, 0x02 }; -+static UINT8 WMT_QUERY_BAUD_EVT_115200[] = { 0x02, 0x04, 0x06, 0x00, 0x00, 0x02, 0x00, 0xC2, 0x01, 0x00 }; -+static UINT8 WMT_QUERY_BAUD_EVT_X[] = { 0x02, 0x04, 0x06, 0x00, 0x00, 0x02, 0xAA, 0xAA, 0xAA, 0xBB }; -+static UINT8 WMT_SET_BAUD_CMD_X[] = { 0x01, 0x04, 0x05, 0x00, 0x01, 0xAA, 0xAA, 0xAA, 0xBB }; -+static UINT8 WMT_SET_BAUD_EVT[] = { 0x02, 0x04, 0x02, 0x00, 0x00, 0x01 }; -+static UINT8 WMT_SET_WAKEUP_WAKE_CMD_RAW[] = { 0xFF }; -+static UINT8 WMT_SET_WAKEUP_WAKE_EVT[] = { 0x02, 0x03, 0x02, 0x00, 0x00, 0x03 }; -+#endif -+static UINT8 WMT_QUERY_STP_CMD[] = { 0x01, 0x04, 0x01, 0x00, 0x04 }; -+static UINT8 WMT_QUERY_STP_EVT_DEFAULT[] = { 0x02, 0x04, 0x06, 0x00, 0x00, 0x04, 0x11, 0x00, 0x00, 0x00 }; -+static UINT8 WMT_QUERY_STP_EVT[] = { 0x02, 0x04, 0x06, 0x00, 0x00, 0x04, 0xDF, 0x0E, 0x68, 0x01 }; -+static UINT8 WMT_PATCH_CMD[] = { 0x01, 0x01, 0x00, 0x00, 0x00 }; -+static UINT8 WMT_PATCH_EVT[] = { 0x02, 0x01, 0x01, 0x00, 0x00 }; -+static UINT8 WMT_RESET_CMD[] = { 0x01, 0x07, 0x01, 0x00, 0x04 }; -+static UINT8 WMT_RESET_EVT[] = { 0x02, 0x07, 0x01, 0x00, 0x00 }; -+ -+#if CFG_WMT_BT_PORT2 -+static UINT8 WMT_BTP2_CMD[] = { 0x01, 0x10, 0x03, 0x00, 0x01, 0x03, 0x01 }; -+static UINT8 WMT_BTP2_EVT[] = { 0x02, 0x10, 0x01, 0x00, 0x00 }; -+#endif -+ -+/*soc patial patch address cmd & evt need firmware owner provide*/ -+#if CFG_WMT_MULTI_PATCH -+static UINT8 WMT_PATCH_ADDRESS_CMD[] = { -+ 0x01, 0x08, 0x10, 0x00, -+ 0x01, 0x01, 0x00, 0x01, -+ 0x3c, 0x02, 0x09, 0x02, -+ 0x00, 0x00, 0x00, 0x00, -+ 0xff, 0xff, 0xff, 0xff -+}; -+static UINT8 WMT_PATCH_ADDRESS_EVT[] = { 0x02, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01 }; -+ -+static UINT8 WMT_PATCH_P_ADDRESS_CMD[] = { -+ 0x01, 0x08, 0x10, 0x00, -+ 0x01, 0x01, 0x00, 0x01, -+ 0xc4, 0x04, 0x09, 0x02, -+ 0x00, 0x3f, 0x00, 0x01, -+ 0xff, 0xff, 0xff, 0xff -+}; -+static UINT8 WMT_PATCH_P_ADDRESS_EVT[] = { 0x02, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01 }; -+#endif -+ -+/*coex cmd/evt++*/ -+static UINT8 WMT_COEX_SETTING_CONFIG_CMD[] = { 0x01, 0x10, 0x02, 0x00, 0x01, 0x00 }; -+static UINT8 WMT_COEX_SETTING_CONFIG_EVT[] = { 0x02, 0x10, 0x01, 0x00, 0x00 }; -+ -+#if CFG_SUBSYS_COEX_NEED -+static UINT8 WMT_BT_COEX_SETTING_CONFIG_CMD[] = { 0x01, 0x10, 0x0B, -+ 0x00, 0x02, -+ 0x00, 0x00, 0x00, 0x00, -+ 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0xAA -+}; -+static UINT8 WMT_BT_COEX_SETTING_CONFIG_EVT[] = { 0x02, 0x10, 0x01, 0x00, 0x00 }; -+ -+static UINT8 WMT_WIFI_COEX_SETTING_CONFIG_CMD[] = { 0x01, 0x10, 0x0C, -+ 0x00, 0x03, -+ 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0xAA -+}; -+static UINT8 WMT_WIFI_COEX_SETTING_CONFIG_EVT[] = { 0x02, 0x10, 0x01, 0x00, 0x00 }; -+ -+static UINT8 WMT_PTA_COEX_SETTING_CONFIG_CMD[] = { 0x01, 0x10, 0x0A, -+ 0x00, 0x04, -+ 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xEE, 0xFF, 0xFF, 0xFE -+}; -+static UINT8 WMT_PTA_COEX_SETTING_CONFIG_EVT[] = { 0x02, 0x10, 0x01, 0x00, 0x00 }; -+ -+static UINT8 WMT_MISC_COEX_SETTING_CONFIG_CMD[] = { 0x01, 0x10, 0x09, -+ 0x00, 0x05, -+ 0xAA, 0xAA, 0xAA, 0xAA, -+ 0xBB, 0xBB, 0xBB, 0xBB -+}; -+static UINT8 WMT_MISC_COEX_SETTING_CONFIG_EVT[] = { 0x02, 0x10, 0x01, 0x00, 0x00 }; -+#endif -+ -+/*coex cmd/evt--*/ -+static UINT8 WMT_SET_STP_CMD[] = { 0x01, 0x04, 0x05, 0x00, 0x03, 0xDF, 0x0E, 0x68, 0x01 }; -+static UINT8 WMT_SET_STP_EVT[] = { 0x02, 0x04, 0x02, 0x00, 0x00, 0x03 }; -+static UINT8 WMT_STRAP_CONF_CMD_FM_COMM[] = { 0x01, 0x05, 0x02, 0x00, 0x02, 0x02 }; -+static UINT8 WMT_STRAP_CONF_EVT[] = { 0x02, 0x05, 0x02, 0x00, 0x00, 0x02 }; -+ -+#if 0 -+static UINT8 WMT_SET_OSC32K_BYPASS_CMD[] = { 0x01, 0x0A, 0x01, 0x00, 0x05 }; -+static UINT8 WMT_SET_OSC32K_BYPASS_EVT[] = { 0x02, 0x0A, 0x01, 0x00, 0x00 }; -+#endif -+ -+#if 0 -+/* to enable dump feature */ -+static UINT8 WMT_CORE_DUMP_EN_CMD[] = { 0x01, 0x0F, 0x02, 0x00, 0x03, 0x01 }; -+static UINT8 WMT_CORE_DUMP_EN_EVT[] = { 0x02, 0x0F, 0x01, 0x00, 0x00 }; -+ -+/* to get system stack dump when f/w assert */ -+static UINT8 WMT_CORE_DUMP_LEVEL_01_CMD[] = { 0x1, 0x0F, 0x07, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; -+static UINT8 WMT_CORE_DUMP_LEVEL_01_EVT[] = { 0x2, 0x0F, 0x01, 0x00, 0x00 }; -+ -+/* to get task and system stack dump when f/w assert */ -+static UINT8 WMT_CORE_DUMP_LEVEL_02_CMD[] = { 0x1, 0x0F, 0x07, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; -+static UINT8 WMT_CORE_DUMP_LEVEL_02_EVT[] = { 0x2, 0x0F, 0x01, 0x00, 0x00 }; -+ -+/* to get bt related memory dump when f/w assert */ -+static UINT8 WMT_CORE_DUMP_LEVEL_03_CMD[] = { 0x1, 0x0F, 0x07, 0x00, 0x03, 0x00, 0x00, 0x09, 0xF0, 0x00, 0x0A }; -+static UINT8 WMT_CORE_DUMP_LEVEL_03_EVT[] = { 0x2, 0x0F, 0x01, 0x00, 0x00 }; -+#endif -+/* to get full dump when f/w assert */ -+static UINT8 WMT_CORE_DUMP_LEVEL_04_CMD[] = { 0x1, 0x0F, 0x07, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; -+static UINT8 WMT_CORE_DUMP_LEVEL_04_EVT[] = { 0x2, 0x0F, 0x01, 0x00, 0x00 }; -+ -+static UINT8 WMT_CORE_CO_CLOCK_CMD[] = { 0x1, 0x0A, 0x02, 0x00, 0x08, 0x03 }; -+static UINT8 WMT_CORE_CO_CLOCK_EVT[] = { 0x2, 0x0A, 0x01, 0x00, 0x00 }; -+ -+static UINT8 WMT_CORE_START_RF_CALIBRATION_CMD[] = { 0x1, 0x14, 0x1, 0x00, 0x01 }; -+static UINT8 WMT_CORE_START_RF_CALIBRATION_EVT[] = { 0x2, 0x14, 0x02, 0x00, 0x00, 0x01 }; -+ -+#if (MTK_WCN_CMB_MERGE_INTERFACE_SUPPORT) -+static UINT8 WMT_SET_I2S_SLAVE_REG_CMD[] = { 0x01, 0x08, 0x10, 0x00 /*length */ -+ , 0x01 /* op: w */ -+ , 0x01 /*type: reg */ -+ , 0x00 /*rev */ -+ , 0x01 /*1 registers */ -+ , 0x78, 0x00, 0x05, 0x80 /*addr:0x80050078 */ -+ , 0x00, 0x00, 0x11, 0x01 /*value:0x11010000 */ -+ , 0x00, 0x00, 0x77, 0x07 /*mask:0x07770000 */ -+}; -+ -+static UINT8 WMT_SET_I2S_SLAVE_REG_EVT[] = { 0x02, 0x08, 0x04, 0x00 /*length */ -+ , 0x00 /*S: 0 */ -+ , 0x00 /*type: reg */ -+ , 0x00 /*rev */ -+ , 0x01 /*1 registers */ -+}; -+ -+static UINT8 WMT_SET_DAI_TO_PAD_REG_CMD[] = { 0x01, 0x08, 0x10, 0x00 /*length */ -+ , 0x01 /* op: w */ -+ , 0x01 /*type: reg */ -+ , 0x00 /*rev */ -+ , 0x01 /*1 registers */ -+ , 0x74, 0x00, 0x05, 0x80 /*addr:0x80050074 */ -+ , 0x44, 0x44, 0x00, 0x00 /*value:0x11010000 */ -+ , 0x77, 0x77, 0x00, 0x00 /*mask:0x07770000 */ -+}; -+ -+static UINT8 WMT_SET_DAI_TO_PAD_REG_EVT[] = { 0x02, 0x08, 0x04, 0x00 /*length */ -+ , 0x00 /*S: 0 */ -+ , 0x00 /*type: reg */ -+ , 0x00 /*rev */ -+ , 0x01 /*1 registers */ -+}; -+ -+static UINT8 WMT_SET_DAI_REG_CMD[] = { 0x01, 0x08, 0x10, 0x00 /*length */ -+ , 0x01 /* op: w */ -+ , 0x01 /*type: reg */ -+ , 0x00 /*rev */ -+ , 0x01 /*1 registers */ -+ , 0xA0, 0x00, 0x05, 0x80 /*addr:0x80050074 */ -+ , 0x04, 0x00, 0x00, 0x00 /*value:0x11010000 */ -+ , 0x04, 0x00, 0x00, 0x00 /*mask:0x07770000 */ -+}; -+ -+static UINT8 WMT_SET_DAI_REG_EVT[] = { 0x02, 0x08, 0x04, 0x00 /*length */ -+ , 0x00 /*S: 0 */ -+ , 0x00 /*type: reg */ -+ , 0x00 /*rev */ -+ , 0x01 /*1 registers */ -+}; -+#endif -+ -+#if !(CFG_IC_SOC) /* For MT6628 no need to set ALLEINT registers, done in f/w */ -+/* enable all interrupt */ -+static UINT8 WMT_SET_ALLINT_REG_CMD[] = { 0x01, 0x08, 0x10, 0x00 /*length */ -+ , 0x01 /* op: w */ -+ , 0x01 /*type: reg */ -+ , 0x00 /*rev */ -+ , 0x01 /*1 registers */ -+ , 0x00, 0x03, 0x05, 0x80 /*addr:0x80050300 */ -+ , 0x00, 0xC4, 0x00, 0x00 /*value:0x0000C400 */ -+ , 0x00, 0xC4, 0x00, 0x00 /*mask:0x0000C400 */ -+}; -+ -+static UINT8 WMT_SET_ALLINT_REG_EVT[] = { 0x02, 0x08, 0x04, 0x00 /*length */ -+ , 0x00 /*S: 0 */ -+ , 0x00 /*type: reg */ -+ , 0x00 /*rev */ -+ , 0x01 /*1 registers */ -+}; -+ -+#endif -+ -+#if CFG_SET_OPT_REG_SWLA /* enable swla: eesk(7) eecs(8) oscen(19) sck0(24) scs0(25) */ -+static UINT8 WMT_SET_SWLA_REG_CMD[] = { 0x01, 0x08, 0x1C, 0x00 /*length */ -+ , 0x01 /* op: w */ -+ , 0x01 /*type: reg */ -+ , 0x00 /*rev */ -+ , 0x02 /*2 registers */ -+ , 0x10, 0x01, 0x05, 0x80 /*addr:0x80050110 */ -+ , 0x10, 0x10, 0x01, 0x00 /*value:0x00011010 */ -+ , 0xF0, 0xF0, 0x0F, 0x00 /*mask:0x000FF0F0 */ -+ , 0x40, 0x01, 0x05, 0x80 /*addr:0x80050140 */ -+ , 0x00, 0x10, 0x01, 0x00 /*value:0x00011000 */ -+ , 0x00, 0xF0, 0x0F, 0x00 /*mask:0x000FF000 */ -+}; -+ -+static UINT8 WMT_SET_SWLA_REG_EVT[] = { 0x02, 0x08, 0x04, 0x00 /*length */ -+ , 0x00 /*S: 0 */ -+ , 0x00 /*type: reg */ -+ , 0x00 /*rev */ -+ , 0x02 /*2 registers */ -+}; -+#endif -+ -+#if CFG_SET_OPT_REG_MCUCLK /* enable mcu clk: antsel_4, eedi */ -+static UINT8 WMT_SET_MCUCLK_REG_CMD[] = { 0x01, 0x08, (4 + 12 * 4), 0x00 /*length */ -+ , 0x01 /* op: w */ -+ , 0x01 /* type: reg */ -+ , 0x00 /* rev */ -+ , 0x04 /* 4 registers */ -+ , 0x00, 0x04, 0x00, 0x80 /* addr:0x8000 0400 */ -+ , 0x00, 0x14, 0x00, 0x00 /* value:0x0000 1400(osc, hclk), 0x0000 1501(PLL, en) */ -+ , 0xFF, 0xFF, 0x00, 0x00 /* mask:0x0000 FFFF */ -+ , 0x80, 0x01, 0x05, 0x80 /* addr:0x8005 0180 */ -+ , 0x12, 0x13, 0x00, 0x00 /* value:0x0000 1312(osc, hclk), 0x0000 1a19(PLL, en) */ -+ , 0xFF, 0xFF, 0x00, 0x00 /* mask:0x0000 FFFF */ -+ , 0x00, 0x01, 0x05, 0x80 /* addr:0x8005 0100 */ -+ , 0x00, 0x00, 0x02, 0x00 /* value:0x0002 0000 */ -+ , 0x00, 0x00, 0x0F, 0x00 /* mask:0x000F 0000 */ -+ , 0x10, 0x01, 0x05, 0x80 /* addr:0x8005 0110 */ -+ , 0x02, 0x00, 0x00, 0x00 /* value:0x0000 0002 */ -+ , 0x0F, 0x00, 0x00, 0x00 /* mask:0x0000 000F */ -+}; -+ -+static UINT8 WMT_SET_MCUCLK_REG_EVT[] = { 0x02, 0x08, 0x04, 0x00 /*length */ -+ , 0x00 /* S: 0 */ -+ , 0x00 /* type: reg */ -+ , 0x00 /* rev */ -+ , 0x04 /* 4 registers */ -+}; -+#endif -+ -+#if CFG_WMT_I2S_DBGUART_SUPPORT /* register write for debug uart */ -+static UINT8 WMT_SET_DBGUART_REG_CMD[] = { 0x01, 0x08, 0x1C, 0x00 /*length */ -+ , 0x01 /* op: w */ -+ , 0x01 /*type: reg */ -+ , 0x00 /*rev */ -+ , 0x02 /*2 registers */ -+ , 0x30, 0x01, 0x05, 0x80 /*addr:0x80050130 */ -+ , 0x00, 0x00, 0x00, 0x00 /*value:0x00000000 */ -+ , 0xF0, 0x0F, 0x00, 0x00 /*mask:0x00000FF0 */ -+ , 0x40, 0x01, 0x05, 0x80 /*addr:0x80050140 */ -+ , 0x00, 0x01, 0x00, 0x00 /*value:0x00000100 */ -+ , 0x00, 0x01, 0x00, 0x00 /*mask:0x00000100 */ -+}; -+ -+static UINT8 WMT_SET_DBGUART_REG_EVT[] = { 0x02, 0x08, 0x04, 0x00 /*length */ -+ , 0x00 /*S: 0 */ -+ , 0x00 /*type: reg */ -+ , 0x00 /*rev */ -+ , 0x02 /*2 registers */ -+}; -+#endif -+ -+#if CFG_SET_OPT_REG_MCUIRQ /* enable mcu irq: antsel_4, wlan_act */ -+#if 1 /* Ray */ -+static UINT8 WMT_SET_MCUIRQ_REG_CMD[] = { 0x01, 0x08, (4 + 12 * 4), 0x00 /*length */ -+ , 0x01 /* op: w */ -+ , 0x01 /* type: reg */ -+ , 0x00 /* rev */ -+ , 0x04 /* 4 registers */ -+ , 0x00, 0x04, 0x00, 0x80 /* addr:0x8000_0400 */ -+ , 0x03, 0x14, 0x00, 0x00 /* value:0x0000_1403 check confg debug flag 3 low word */ -+ , 0xFF, 0xFF, 0x00, 0x00 /* mask:0x0000_FFFF */ -+ /* cirq_int_n */ -+ , 0x10, 0x01, 0x05, 0x80 /* addr:0x8005_0110 */ -+ , 0x02, 0x00, 0x00, 0x00 /* value:0x0000_0002 set EEDI as cirq_int_n debug flag (monitor flag2) */ -+ , 0x07, 0x00, 0x00, 0x00 /* mask:0x0000_0007 */ -+ , 0x00, 0x01, 0x05, 0x80 /* addr:0x8005_0100 */ -+ , 0x00, 0x00, 0x02, 0x00 /* value:0x0002_0000 (ANTSEL4=>monitor flag 0, ahb_x2_gt_ck debug flag) */ -+ , 0x00, 0x00, 0x07, 0x00 /* mask:0x0007_0000 */ -+ /* 1. ARM irq_b, monitor flag 0 */ -+ , 0x80, 0x01, 0x05, 0x80 /* addr:0x8005_0180 */ -+ , 0x1F, 0x1E, 0x00, 0x00 /* value:0x0000_1E1F check mcusys debug flag */ -+ , 0x7F, 0x7F, 0x00, 0x00 /* mask:0x0000_7F7F */ -+}; -+ -+static UINT8 WMT_SET_MCUIRQ_REG_EVT[] = { 0x02, 0x08, 0x04, 0x00 /*length */ -+ , 0x00 /* S: 0 */ -+ , 0x00 /* type: reg */ -+ , 0x00 /* rev */ -+ , 0x04 /* 5 registers */ -+}; -+#elif 0 /* KC */ -+static UINT8 WMT_SET_MCUIRQ_REG_CMD[] = { 0x01, 0x08, (4 + 12 * 5), 0x00 /*length */ -+ , 0x01 /* op: w */ -+ , 0x01 /* type: reg */ -+ , 0x00 /* rev */ -+ , 0x05 /* 5 registers */ -+ , 0x00, 0x04, 0x00, 0x80 /* addr:0x8000_0400 */ -+ , 0x00, 0x02, 0x00, 0x00 /* value:0x0000_0200 [15:8]=0x2 arm irq_b, 0xA irq_bus[5] bt_timcon_irq_b */ -+ , 0x00, 0xFF, 0x00, 0x00 /* mask:0x0000_FF00 */ -+ /* 1. ARM irq_b, monitor flag 0 */ -+ , 0x80, 0x01, 0x05, 0x80 /* addr:0x8005_0180 */ -+ , 0x18, 0x00, 0x00, 0x00 /* value:0x0000_0018 [6:0]=001_1000 (monitor flag 0 select, MCUSYS, SEL:8) */ -+ , 0x7F, 0x00, 0x00, 0x00 /* mask:0x0000_007F */ -+ , 0x00, 0x01, 0x05, 0x80 /* addr:0x8005_0100 */ -+ , 0x00, 0x00, 0x02, 0x00 /* value:0x0002_0000 (ANTSEL4=>monitor flag 0) */ -+ , 0x00, 0x00, 0x07, 0x00 /* mask:0x0007_0000 */ -+ /* 2. irq_bus[5] bt_timcon_irq_b monitor flag 15 */ -+ , 0xB0, 0x01, 0x05, 0x80 /* addr:0x8005_01B0 */ -+ , 0x00, 0x00, 0x00, 0x16 /* value:0x1600_0000 [30:24]=001_0110 (monitor flag 15 select, MCUSYS, SEL:6) */ -+ , 0x00, 0x00, 0x00, 0x7F /* mask:0x7F00_0000 */ -+ , 0x30, 0x01, 0x05, 0x80 /* addr:0x8005_0130 */ -+ , 0x00, 0x20, 0x00, 0x00 /* value:0x0000_2000 (WLAN_ACT=>monitor flag 15) */ -+ , 0x00, 0x70, 0x00, 0x00 /* mask:0x0000_7000 */ -+}; -+ -+static UINT8 WMT_SET_MCUIRQ_REG_EVT[] = { 0x02, 0x08, 0x04, 0x00 /*length */ -+ , 0x00 /* S: 0 */ -+ , 0x00 /* type: reg */ -+ , 0x00 /* rev */ -+ , 0x05 /* 5 registers */ -+}; -+#endif -+#endif -+ -+#if CFG_WMT_CRYSTAL_TIMING_SET -+static UINT8 WMT_SET_CRYSTAL_TRIMING_CMD[] = { 0x01, 0x12, 0x02, 0x00, 0x01, 0x00 }; -+static UINT8 WMT_SET_CRYSTAL_TRIMING_EVT[] = { 0x02, 0x12, 0x02, 0x00, 0x01, 0x00 }; -+ -+static UINT8 WMT_GET_CRYSTAL_TRIMING_CMD[] = { 0x01, 0x12, 0x02, 0x00, 0x00, 0x00 }; -+static UINT8 WMT_GET_CRYSTAL_TRIMING_EVT[] = { 0x02, 0x12, 0x02, 0x00, 0x00, 0x00 }; -+#endif -+ -+#ifdef CFG_WMT_READ_EFUSE_VCN33 -+static UINT8 WMT_GET_EFUSE_VCN33_CMD[] = { 0x01, 0x12, 0x02, 0x00, 0x04, 0x00 }; -+static UINT8 WMT_GET_EFUSE_VCN33_EVT[] = { 0x02, 0x12, 0x02, 0x00, 0x04, 0x00 }; -+#endif -+ -+/* set sdio driving */ -+#if CFG_WMT_SDIO_DRIVING_SET -+static UINT8 WMT_SET_SDIO_DRV_REG_CMD[] = { 0x01, 0x08, 0x10, 0x00 /*length */ -+ , 0x01 /* op: w */ -+ , 0x01 /*type: reg */ -+ , 0x00 /*rev */ -+ , 0x01 /*1 registers */ -+ , 0x50, 0x00, 0x05, 0x80 /*addr:0x80050050 */ -+ , 0x44, 0x44, 0x04, 0x00 /*value:0x00044444 */ -+ , 0x77, 0x77, 0x07, 0x00 /*mask:0x00077777 */ -+}; -+ -+static UINT8 WMT_SET_SDIO_DRV_REG_EVT[] = { 0x02, 0x08, 0x04, 0x00 /*length */ -+ , 0x00 /*S: 0 */ -+ , 0x00 /*type: reg */ -+ , 0x00 /*rev */ -+ , 0x01 /*1 registers */ -+}; -+#endif -+ -+#if CFG_WMT_WIFI_5G_SUPPORT -+static UINT8 WMT_GET_SOC_ADIE_CHIPID_CMD[] = { 0x01, 0x13, 0x04, 0x00, 0x02, 0x04, 0x24, 0x00 }; -+static UINT8 WMT_GET_SOC_ADIE_CHIPID_EVT[] = { -+ 0x02, 0x13, 0x09, 0x00, 0x00, 0x02, 0x04, 0x24, -+ 0x00, 0x00, 0x00, 0x00, 0x00 -+}; -+static UINT8 WMT_GET_SOC_6625_L_CMD[] = { 0x01, 0x13, 0x04, 0x00, 0x02, 0x04, 0x20, 0x01 }; -+static UINT8 WMT_GET_SOC_6625_L_EVT[] = { -+ 0x02, 0x13, 0x09, 0x00, 0x00, 0x02, 0x04, 0x20, -+ 0x01, 0x00, 0x00, 0x00, 0x00 -+}; -+#endif -+ -+#if CFG_WMT_PATCH_DL_OPTM -+static UINT8 WMT_SET_MCU_CLK_EN_CMD[] = { -+ 0x01, 0x08, 0x10, 0x00, -+ 0x01, 0x01, 0x00, 0x01, -+ 0x34, 0x03, 0x00, 0x80, -+ 0x00, 0x00, 0x01, 0x00, -+ 0xff, 0xff, 0xff, 0xff -+}; -+static UINT8 WMT_SET_MCU_CLK_EN_EVT[] = { 0x02, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01 }; -+ -+static UINT8 WMT_SET_MCU_CLK_138_CMD[] = { -+ 0x01, 0x08, 0x10, 0x00, -+ 0x01, 0x01, 0x00, 0x01, -+ 0x0c, 0x01, 0x00, 0x80, -+ 0x59, 0x4d, 0x84, 0x00, -+ 0xff, 0xff, 0xff, 0xff -+}; -+static UINT8 WMT_SET_MCU_CLK_138_EVT[] = { 0x02, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01 }; -+ -+static UINT8 WMT_SET_MCU_CLK_26_CMD[] = { -+ 0x01, 0x08, 0x10, 0x00, -+ 0x01, 0x01, 0x00, 0x01, -+ 0x0c, 0x01, 0x00, 0x80, -+ 0x00, 0x4d, 0x84, 0x00, -+ 0xff, 0xff, 0xff, 0xff -+}; -+static UINT8 WMT_SET_MCU_CLK_26_EVT[] = { 0x02, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01 }; -+ -+static UINT8 WMT_SET_MCU_CLK_DIS_CMD[] = { -+ 0x01, 0x08, 0x10, 0x00, -+ 0x01, 0x01, 0x00, 0x01, -+ 0x34, 0x03, 0x00, 0x80, -+ 0x00, 0x00, 0x00, 0x00, -+ 0xff, 0xff, 0xff, 0xff -+}; -+static UINT8 WMT_SET_MCU_CLK_DIS_EVT[] = { 0x02, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01 }; -+ -+/*only for 6797,enable high clock frequency*/ -+/*CLK EN*/ -+static UINT8 WMT_SET_MCU_CLK_EN_6797[] = { -+ 0x01, 0x08, 0x10, 0x00, 0x01, 0x01, 0x00, 0x01, -+ 0x10, 0x11, 0x02, 0x81, 0x00, 0x00, 0x00, 0x10, -+ 0x00, 0x00, 0x00, 0x10 -+}; -+/*RATIO SET*/ -+static UINT8 WMT_SET_MCU_RATIO_SET_6797[] = { -+ 0x01, 0x08, 0x10, 0x00, 0x01, 0x01, 0x00, 0x01, -+ 0x0c, 0x01, 0x00, 0x80, 0x40, 0x00, 0x00, 0x00, -+ 0xc0, 0x00, 0x00, 0x00 -+}; -+/*DIV SET*/ -+static UINT8 WMT_SET_MCU_DIV_SET_6797[] = { -+ 0x01, 0x08, 0x10, 0x00, 0x01, 0x01, 0x00, 0x01, -+ 0x18, 0x11, 0x02, 0x80, 0x07, 0x00, 0x00, 0x00, -+ 0x3f, 0x00, 0x00, 0x00 -+}; -+/*HCLK SET*/ -+static UINT8 WMT_SET_MCU_HCLK_SET_6797[] = { -+ 0x01, 0x08, 0x10, 0x00, 0x01, 0x01, 0x00, 0x01, -+ 0x00, 0x11, 0x02, 0x81, 0x04, 0x00, 0x00, 0x00, -+ 0x07, 0x00, 0x00, 0x00 -+}; -+ -+/*Change clock to 26MHz*/ -+/*HCLK DIS*/ -+static UINT8 WMT_SET_MCU_HCLK_DIS_6797[] = { -+ 0x01, 0x08, 0x10, 0x00, 0x01, 0x01, 0x00, 0x01, -+ 0x00, 0x11, 0x02, 0x81, 0x00, 0x00, 0x00, 0x00, -+ 0x07, 0x00, 0x00, 0x00 -+}; -+/*RATIO DIS*/ -+static UINT8 WMT_SET_MCU_RATIO_DIS_6797[] = { -+ 0x01, 0x08, 0x10, 0x00, 0x01, 0x01, 0x00, 0x01, -+ 0x0c, 0x01, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, -+ 0xc0, 0x00, 0x00, 0x00 -+}; -+/*CLK DIS*/ -+static UINT8 WMT_SET_MCU_CLK_DIS_6797[] = { -+ 0x01, 0x08, 0x10, 0x00, 0x01, 0x01, 0x00, 0x01, -+ 0x10, 0x11, 0x02, 0x81, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x10 -+}; -+ -+static UINT8 WMT_SET_MCU_CLK_EVT_6797[] = { -+ 0x02, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01 -+}; -+ -+#endif -+ -+#if CFG_WMT_FILTER_MODE_SETTING -+static UINT8 WMT_COEX_EXT_COMPONENT_CMD[] = {0x01, 0x10, 0x03, 0x00, 0x0d, 0x00, 0x00}; -+static UINT8 WMT_COEX_FILTER_SPEC_CMD_TEST[] = { -+ 0x01, 0x10, 0x45, 0x00, 0x11, 0x00, 0x00, 0x01, -+ 0x00, 0x11, 0x11, 0x16, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x63, 0x63, 0x63, 0x00, 0x39, 0x43, 0x63, -+ 0x63, 0x02, 0x02, 0x03, 0x00, 0x01, 0x01, 0x01, -+ 0x01, 0x0e, 0x0e, 0x0e, 0x00, 0x0a, 0x0c, 0x0e, -+ 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; -+static UINT8 WMT_COEX_LTE_FREQ_IDX_TABLE_CMD[] = { -+ 0x01, 0x10, 0x21, 0x00, 0x12, 0xfc, 0x08, 0x15, -+ 0x09, 0x2e, 0x09, 0x47, 0x09, 0xc4, 0x09, 0xd4, -+ 0x09, 0xe3, 0x09, 0x5a, 0x0a, 0x14, 0x09, 0x2d, -+ 0x09, 0x46, 0x09, 0x60, 0x09, 0xd3, 0x09, 0xe2, -+ 0x09, 0x59, 0x0a, 0x8B, 0x0a}; -+static UINT8 WMT_COEX_LTE_CHAN_UNSAFE_CMD[] = { 0x01, 0x10, 0x02, 0x00, 0x13, 0x00 }; -+static UINT8 WMT_COEX_IS_LTE_L_CMD[] = { 0x01, 0x10, 0x02, 0x00, 0x21, 0x01 }; -+ -+#if 0 -+static UINT8 WMT_COEX_SPLIT_FILTER_CMD_TEST[] = { -+ 0x01, 0x10, 0x19, 0x00, 0x0F, 0x00, 0x00, 0x00, -+ 0x00, 0x6c, 0x09, 0x8a, 0x09, 0x8a, 0x09, 0x9e, -+ 0x09, 0x01, 0x07, 0x07, 0x0b, 0x07, 0x07, 0x00, -+ 0x32, 0x27, 0x4e, 0x27, 0x32 -+}; -+ -+static UINT8 WMT_COEX_FILTER_SPEC_CMD_TEST[] = { -+ 0x01, 0x10, 0x45, 0x00, 0x11, 0x00, 0x00, 0x01, -+ 0x00, 0x07, 0x07, 0x07, 0x54, 0x54, 0x00, 0x00, -+ 0x00, 0x50, 0x50, 0x50, 0x54, 0x54, 0x39, 0x39, -+ 0x39, 0x02, 0x02, 0x02, 0x0e, 0x0e, 0x01, 0x01, -+ 0x01, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0a, 0x0a, -+ 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00 -+}; -+ -+static UINT8 WMT_COEX_LTE_FREQ_IDX_TABLE_CMD_TEST[] = { -+ 0x01, 0x10, 0x21, 0x00, 0x12, 0xfc, 0x08, 0x15, -+ 0x09, 0x2e, 0x09, 0x47, 0x09, 0xc4, 0x09, 0xdd, -+ 0x09, 0xf6, 0x09, 0x0f, 0xaf, 0x14, 0x09, 0x2d, -+ 0x09, 0x46, 0x09, 0x5f, 0x09, 0xdd, 0x09, 0xf5, -+ 0x09, 0x0d, 0x0a, 0x27, 0x0a -+}; -+static UINT8 WMT_COEX_LTE_CHAN_UNSAFE_CMD_TEST[] = { 0x01, 0x10, 0x02, 0x00, 0x13, 0x00 }; -+static UINT8 WMT_COEX_EXT_COMPONENT_CMD_TEST[] = { 0x01, 0x10, 0x03, 0x00, 0x0d, 0x7f, 0x03 }; -+#endif -+ -+static UINT8 WMT_COEX_FILTER_SPEC_CMD_0[] = { -+ 0x01, 0x10, 0x45, 0x00, 0x11, 0x00, 0x00, 0x01, -+ 0x00, 0x16, 0x16, 0x16, 0x16, 0x00, 0x00, 0x00, -+ 0x00, 0x63, 0x63, 0x63, 0x63, 0x3c, 0x3c, 0x3c, -+ 0x3c, 0x04, 0x04, 0x04, 0x04, 0x01, 0x01, 0x01, -+ 0x01, 0x0e, 0x0e, 0x0e, 0x0e, 0x0b, 0x0b, 0x0b, -+ 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00 -+}; -+ -+static UINT8 WMT_COEX_LTE_FREQ_IDX_TABLE_CMD_0[] = { -+ 0x01, 0x10, 0x21, 0x00, 0x12, 0xfc, 0x08, 0x15, -+ 0x09, 0x2e, 0x09, 0x47, 0x09, 0xc4, 0x09, 0xdd, -+ 0x09, 0xf6, 0x09, 0x0f, 0x0a, 0x14, 0x09, 0x2d, -+ 0x09, 0x46, 0x09, 0x5f, 0x09, 0xdd, 0x09, 0xf5, -+ 0x09, 0x0d, 0x0a, 0x27, 0x0a -+}; -+static UINT8 WMT_COEX_TDM_REQ_ANTSEL_NUM_CMD[] = { 0x01, 0x10, 0x02, 0x00, 0x14, 0x00 }; -+static UINT8 WMT_COEX_IS_LTE_PROJ_CMD[] = { 0x01, 0x10, 0x02, 0x00, 0x15, 0x01 }; -+static UINT8 WMT_COEX_SPLIT_MODE_EVT[] = { 0x02, 0x10, 0x01, 0x00, 0x00 }; -+ -+static UINT8 WMT_COEX_FILTER_SPEC_CMD_6752[] = { -+ 0x01, 0x10, 0x45, 0x00, 0x11, 0x00, 0x00, 0x01, -+ 0x00, 0x11, 0x11, 0x16, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x63, 0x63, 0x63, 0x00, 0x39, 0x43, 0x63, -+ 0x63, 0x02, 0x02, 0x03, 0x00, 0x01, 0x01, 0x01, -+ 0x01, 0x0E, 0x0E, 0x0E, 0x00, 0x0A, 0x0C, 0x0E, -+ 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00 -+}; -+ -+static UINT8 WMT_COEX_LTE_FREQ_IDX_TABLE_CMD_6752[] = { -+ 0x01, 0x10, 0x21, 0x00, 0x12, 0xFC, 0x08, 0x15, -+ 0x09, 0x2E, 0x09, 0x47, 0x09, 0xC4, 0x09, 0xD4, -+ 0x09, 0xE3, 0x09, 0x5A, 0x0A, 0x14, 0x09, 0x2D, -+ 0x09, 0x46, 0x09, 0x60, 0x09, 0xD3, 0x09, 0xE2, -+ 0x09, 0x59, 0x0A, 0x8B, 0x0A -+}; -+#endif -+ -+#if CFG_WMT_POWER_ON_DLM -+static UINT8 WMT_POWER_CTRL_DLM_CMD1[] = { -+ 0x01, 0x08, 0x10, 0x00, -+ 0x01, 0x01, 0x00, 0x01, -+ 0x60, 0x00, 0x10, 0x80, -+ 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x0f, 0x00, 0x00 -+}; -+ -+static UINT8 WMT_POWER_CTRL_DLM_CMD2[] = { -+ 0x01, 0x08, 0x10, 0x00, -+ 0x01, 0x01, 0x00, 0x01, -+ 0x60, 0x00, 0x10, 0x80, -+ 0x00, 0x00, 0x00, 0x00, -+ 0xf0, 0x00, 0x00, 0x00 -+}; -+ -+static UINT8 WMT_POWER_CTRL_DLM_CMD3[] = { -+ 0x01, 0x08, 0x10, 0x00, -+ 0x01, 0x01, 0x00, 0x01, -+ 0x60, 0x00, 0x10, 0x80, -+ 0x00, 0x00, 0x00, 0x00, -+ 0x08, 0x00, 0x00, 0x00 -+}; -+static UINT8 WMT_POWER_CTRL_DLM_EVT[] = { 0x02, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01 }; -+#endif -+ -+#if (!CFG_IC_SOC) -+ -+/* stp sdio init scripts */ -+static struct init_script init_table_1_1[] = { -+ /* table_1_1 is only applied to common SDIO interface */ -+ INIT_CMD(WMT_SET_ALLINT_REG_CMD, WMT_SET_ALLINT_REG_EVT, "enable all interrupt"), -+ /* applied to MT6628 ? */ -+ INIT_CMD(WMT_WAKEUP_DIS_GATE_CMD, WMT_WAKEUP_DIS_GATE_EVT, "disable gating"), -+}; -+ -+#endif -+ -+static struct init_script init_table_1_2[] = { -+ INIT_CMD(WMT_QUERY_STP_CMD, WMT_QUERY_STP_EVT_DEFAULT, "query stp default"), -+}; -+ -+#if CFG_WMT_UART_HIF_USE -+static struct init_script init_table_2[] = { -+ INIT_CMD(WMT_QUERY_BAUD_CMD, WMT_QUERY_BAUD_EVT_X, "query baud X"), -+}; -+#endif -+ -+static struct init_script init_table_3[] = { -+ INIT_CMD(WMT_RESET_CMD, WMT_RESET_EVT, "wmt reset"), -+#if CFG_WMT_BT_PORT2 -+ INIT_CMD(WMT_BTP2_CMD, WMT_BTP2_EVT, "set bt port2"), -+#endif -+}; -+ -+#if CFG_WMT_CRYSTAL_TIMING_SET -+static struct init_script set_crystal_timing_script[] = { -+ INIT_CMD(WMT_SET_CRYSTAL_TRIMING_CMD, WMT_SET_CRYSTAL_TRIMING_EVT, "set crystal trim value"), -+}; -+ -+static struct init_script get_crystal_timing_script[] = { -+ INIT_CMD(WMT_GET_CRYSTAL_TRIMING_CMD, WMT_GET_CRYSTAL_TRIMING_EVT, "get crystal trim value"), -+}; -+#endif -+#ifdef CFG_WMT_READ_EFUSE_VCN33 -+static struct init_script get_efuse_vcn33_script[] = { -+ INIT_CMD(WMT_GET_EFUSE_VCN33_CMD, WMT_GET_EFUSE_VCN33_EVT, "get efuse vcn33 value"), -+}; -+#endif -+ -+static struct init_script init_table_4[] = { -+ INIT_CMD(WMT_SET_STP_CMD, WMT_SET_STP_EVT, "set stp"), -+}; -+ -+static struct init_script init_table_5[] = { -+ INIT_CMD(WMT_QUERY_STP_CMD, WMT_QUERY_STP_EVT, "query stp"), -+}; -+ -+static struct init_script init_table_5_1[] = { -+ INIT_CMD(WMT_STRAP_CONF_CMD_FM_COMM, WMT_STRAP_CONF_EVT, "configure FM comm"), -+}; -+ -+static struct init_script init_table_6[] = { -+ INIT_CMD(WMT_CORE_DUMP_LEVEL_04_CMD, WMT_CORE_DUMP_LEVEL_04_EVT, "setup core dump level"), -+}; -+ -+static struct init_script calibration_table[] = { -+ INIT_CMD(WMT_CORE_START_RF_CALIBRATION_CMD, WMT_CORE_START_RF_CALIBRATION_EVT, "start RF calibration data"), -+}; -+ -+#if CFG_WMT_PATCH_DL_OPTM -+static struct init_script set_mcuclk_table_1[] = { -+ INIT_CMD(WMT_SET_MCU_CLK_EN_CMD, WMT_SET_MCU_CLK_EN_EVT, "enable set mcu clk"), -+ INIT_CMD(WMT_SET_MCU_CLK_138_CMD, WMT_SET_MCU_CLK_138_EVT, "set mcu clk to 138.67MH"), -+}; -+ -+static struct init_script set_mcuclk_table_2[] = { -+ INIT_CMD(WMT_SET_MCU_CLK_26_CMD, WMT_SET_MCU_CLK_26_EVT, "set mcu clk to 26MH"), -+ INIT_CMD(WMT_SET_MCU_CLK_DIS_CMD, WMT_SET_MCU_CLK_DIS_EVT, "disable set mcu clk"), -+}; -+ -+static struct init_script set_mcuclk_table_3[] = { -+ INIT_CMD(WMT_SET_MCU_CLK_EN_6797, WMT_SET_MCU_CLK_EVT_6797, "enable set mcu clk"), -+ INIT_CMD(WMT_SET_MCU_RATIO_SET_6797, WMT_SET_MCU_CLK_EVT_6797, "mcu ratio set"), -+ INIT_CMD(WMT_SET_MCU_DIV_SET_6797, WMT_SET_MCU_CLK_EVT_6797, "mcu div set"), -+ INIT_CMD(WMT_SET_MCU_HCLK_SET_6797, WMT_SET_MCU_CLK_EVT_6797, "set mcu clk to hclk"), -+}; -+static struct init_script set_mcuclk_table_4[] = { -+ INIT_CMD(WMT_SET_MCU_HCLK_DIS_6797, WMT_SET_MCU_CLK_EVT_6797, "disable mcu hclk"), -+ INIT_CMD(WMT_SET_MCU_RATIO_DIS_6797, WMT_SET_MCU_CLK_EVT_6797, "disable mcu ratio set"), -+ INIT_CMD(WMT_SET_MCU_CLK_DIS_6797, WMT_SET_MCU_CLK_EVT_6797, "disable mcu clk set"), -+}; -+ -+#endif -+ -+#if CFG_WMT_FILTER_MODE_SETTING -+static struct init_script set_wifi_lte_coex_table_1[] = { -+ INIT_CMD(WMT_COEX_FILTER_SPEC_CMD_6752, WMT_COEX_SPLIT_MODE_EVT, "wifi lte coex filter spec"), -+ INIT_CMD(WMT_COEX_LTE_FREQ_IDX_TABLE_CMD_6752, WMT_COEX_SPLIT_MODE_EVT, "wifi lte freq idx"), -+ INIT_CMD(WMT_COEX_IS_LTE_PROJ_CMD, WMT_COEX_SPLIT_MODE_EVT, "set LTE project"), -+}; -+ -+static struct init_script set_wifi_lte_coex_table_2[] = { -+ INIT_CMD(WMT_COEX_EXT_COMPONENT_CMD, WMT_COEX_SPLIT_MODE_EVT, "wifi lte ext component"), -+ INIT_CMD(WMT_COEX_FILTER_SPEC_CMD_TEST, WMT_COEX_SPLIT_MODE_EVT, "wifi lte coex filter"), -+ INIT_CMD(WMT_COEX_LTE_FREQ_IDX_TABLE_CMD, WMT_COEX_SPLIT_MODE_EVT, "wifi lte freq id table"), -+ INIT_CMD(WMT_COEX_LTE_CHAN_UNSAFE_CMD, WMT_COEX_SPLIT_MODE_EVT, "wifi lte unsafe channel"), -+ INIT_CMD(WMT_COEX_IS_LTE_L_CMD, WMT_COEX_SPLIT_MODE_EVT, "wifi coex is L branch"), -+}; -+ -+static struct init_script set_wifi_lte_coex_table_0[] = { -+#if 0 -+ INIT_CMD(WMT_COEX_SPLIT_FILTER_CMD_TEST, WMT_COEX_SPLIT_MODE_EVT, "wifi lte coex split filter"), -+ INIT_CMD(WMT_COEX_FILTER_SPEC_CMD_TEST, WMT_COEX_SPLIT_MODE_EVT, "wifi lte coex filter spec"), -+ INIT_CMD(WMT_COEX_LTE_FREQ_IDX_TABLE_CMD_TEST, WMT_COEX_SPLIT_MODE_EVT, "wifi lte freq idx"), -+ INIT_CMD(WMT_COEX_LTE_CHAN_UNSAFE_CMD_TEST, WMT_COEX_SPLIT_MODE_EVT, "wifi lte channel unsafe"), -+ INIT_CMD(WMT_COEX_EXT_COMPONENT_CMD_TEST, WMT_COEX_SPLIT_MODE_EVT, "wifi coex ext component"), -+#endif -+ INIT_CMD(WMT_COEX_FILTER_SPEC_CMD_0, WMT_COEX_SPLIT_MODE_EVT, "def wifi lte coex filter spec"), -+ INIT_CMD(WMT_COEX_LTE_FREQ_IDX_TABLE_CMD_0, WMT_COEX_SPLIT_MODE_EVT, "def wifi lte freq idx"), -+}; -+ -+static struct init_script get_tdm_req_antsel_num_table[] = { -+ INIT_CMD(WMT_COEX_TDM_REQ_ANTSEL_NUM_CMD, WMT_COEX_SPLIT_MODE_EVT, "get tdm req antsel num"), -+}; -+#endif -+ -+#if CFG_SET_OPT_REG -+static struct init_script set_registers[] = { -+ /* INIT_CMD(WMT_SET_GPS_REG_CMD, WMT_SET_GPS_REG_EVT, "set wmt registers"), */ -+ /* INIT_CMD(WMT_SET_SDIODRV_REG_CMD, WMT_SET_SDIODRV_REG_EVT, "set SDIO driving registers") */ -+#if CFG_WMT_I2S_DBGUART_SUPPORT -+ INIT_CMD(WMT_SET_DBGUART_REG_CMD, WMT_SET_DBGUART_REG_EVT, "set debug uart registers"), -+#endif -+#if CFG_SET_OPT_REG_SWLA -+ INIT_CMD(WMT_SET_SWLA_REG_CMD, WMT_SET_SWLA_REG_EVT, "set swla registers"), -+#endif -+#if CFG_SET_OPT_REG_MCUCLK -+ INIT_CMD(WMT_SET_MCUCLK_REG_CMD, WMT_SET_MCUCLK_REG_EVT, "set mcuclk dbg registers"), -+#endif -+#if CFG_SET_OPT_REG_MCUIRQ -+ INIT_CMD(WMT_SET_MCUIRQ_REG_CMD, WMT_SET_MCUIRQ_REG_EVT, "set mcu irq dbg registers"), -+#endif -+}; -+#endif -+ -+static struct init_script coex_table[] = { -+ INIT_CMD(WMT_COEX_SETTING_CONFIG_CMD, WMT_COEX_SETTING_CONFIG_EVT, "coex_wmt"), -+ -+#if CFG_SUBSYS_COEX_NEED -+/* no need in MT6628 */ -+ INIT_CMD(WMT_BT_COEX_SETTING_CONFIG_CMD, WMT_BT_COEX_SETTING_CONFIG_EVT, "coex_bt"), -+ INIT_CMD(WMT_WIFI_COEX_SETTING_CONFIG_CMD, WMT_WIFI_COEX_SETTING_CONFIG_EVT, "coex_wifi"), -+ INIT_CMD(WMT_PTA_COEX_SETTING_CONFIG_CMD, WMT_PTA_COEX_SETTING_CONFIG_EVT, "coex_ext_pta"), -+ INIT_CMD(WMT_MISC_COEX_SETTING_CONFIG_CMD, WMT_MISC_COEX_SETTING_CONFIG_EVT, "coex_misc"), -+#endif -+}; -+ -+static struct init_script osc_type_table[] = { -+ INIT_CMD(WMT_CORE_CO_CLOCK_CMD, WMT_CORE_CO_CLOCK_EVT, "osc_type"), -+}; -+ -+#if (MTK_WCN_CMB_MERGE_INTERFACE_SUPPORT) -+static struct init_script merge_pcm_table[] = { -+ INIT_CMD(WMT_SET_I2S_SLAVE_REG_CMD, WMT_SET_I2S_SLAVE_REG_EVT, "I2S_Slave"), -+ INIT_CMD(WMT_SET_DAI_TO_PAD_REG_CMD, WMT_SET_DAI_TO_PAD_REG_EVT, "DAI_PAD"), -+ INIT_CMD(WMT_SET_DAI_REG_CMD, WMT_SET_DAI_REG_EVT, "DAI_EVT"), -+}; -+#endif -+ -+#if CFG_WMT_SDIO_DRIVING_SET -+static struct init_script sdio_driving_table[] = { -+ INIT_CMD(WMT_SET_SDIO_DRV_REG_CMD, WMT_SET_SDIO_DRV_REG_EVT, "sdio_driving"), -+}; -+#endif -+ -+#if CFG_WMT_POWER_ON_DLM -+static struct init_script wmt_power_on_dlm_table[] = { -+ INIT_CMD(WMT_POWER_CTRL_DLM_CMD1, WMT_POWER_CTRL_DLM_EVT, "power on dlm cmd1"), -+ INIT_CMD(WMT_POWER_CTRL_DLM_CMD2, WMT_POWER_CTRL_DLM_EVT, "power on dlm cmd2"), -+ INIT_CMD(WMT_POWER_CTRL_DLM_CMD3, WMT_POWER_CTRL_DLM_EVT, "power on dlm cmd3") -+}; -+#endif -+ -+/* SOC Chip Version and Info Table */ -+static const WMT_IC_INFO_S mtk_wcn_soc_info_table[] = { -+ { -+ .u4HwVer = 0x8A00, -+ .cChipName = WMT_IC_NAME_DEFAULT, -+ .cChipVersion = WMT_IC_VER_E1, -+ .cPatchNameExt = WMT_IC_PATCH_E1_EXT, -+ /* need to refine? */ -+ .eWmtHwVer = WMTHWVER_E1, -+ .bWorkWithoutPatch = MTK_WCN_BOOL_FALSE, -+ .bPsmSupport = MTK_WCN_BOOL_TRUE, -+ }, -+ { -+ .u4HwVer = 0x8A01, -+ .cChipName = WMT_IC_NAME_DEFAULT, -+ .cChipVersion = WMT_IC_VER_E2, -+ .cPatchNameExt = WMT_IC_PATCH_E1_EXT, -+ .eWmtHwVer = WMTHWVER_E2, -+ .bWorkWithoutPatch = MTK_WCN_BOOL_FALSE, -+ .bPsmSupport = MTK_WCN_BOOL_TRUE, -+ }, -+ { -+ .u4HwVer = 0x8B01, -+ .cChipName = WMT_IC_NAME_DEFAULT, -+ .cChipVersion = WMT_IC_VER_E3, -+ .cPatchNameExt = WMT_IC_PATCH_E1_EXT, -+ .eWmtHwVer = WMTHWVER_E3, -+ .bWorkWithoutPatch = MTK_WCN_BOOL_FALSE, -+ .bPsmSupport = MTK_WCN_BOOL_TRUE, -+ } -+}; -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+static INT32 mtk_wcn_soc_sw_init(P_WMT_HIF_CONF pWmtHifConf); -+ -+static INT32 mtk_wcn_soc_sw_deinit(P_WMT_HIF_CONF pWmtHifConf); -+ -+static INT32 mtk_wcn_soc_pin_ctrl(WMT_IC_PIN_ID id, WMT_IC_PIN_STATE state, UINT32 flag); -+ -+static INT32 mtk_wcn_soc_aif_ctrl(WMT_IC_PIN_STATE state, UINT32 flag); -+ -+static INT32 mtk_wcn_soc_ver_check(VOID); -+ -+static const WMT_IC_INFO_S *mtk_wcn_soc_find_wmt_ic_info(const UINT32 hw_ver); -+ -+static INT32 wmt_stp_init_coex(VOID); -+ -+#if CFG_WMT_FILTER_MODE_SETTING -+static INT32 wmt_stp_wifi_lte_coex(VOID); -+#endif -+ -+#if CFG_WMT_MULTI_PATCH -+static INT32 mtk_wcn_soc_patch_dwn(UINT32 index); -+static INT32 mtk_wcn_soc_patch_info_prepare(VOID); -+#else -+static INT32 mtk_wcn_soc_patch_dwn(VOID); -+#endif -+ -+static INT32 mtk_wcn_soc_co_clock_ctrl(WMT_CO_CLOCK on); -+static WMT_CO_CLOCK mtk_wcn_soc_co_clock_get(VOID); -+ -+#if CFG_WMT_CRYSTAL_TIMING_SET -+static INT32 mtk_wcn_soc_crystal_triming_set(VOID); -+#endif -+ -+static MTK_WCN_BOOL mtk_wcn_soc_quick_sleep_flag_get(VOID); -+ -+static MTK_WCN_BOOL mtk_wcn_soc_aee_dump_flag_get(VOID); -+ -+#if CFG_WMT_SDIO_DRIVING_SET -+static INT32 mtk_wcn_soc_set_sdio_driving(void); -+#endif -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/* SOC Operation Function Table */ -+WMT_IC_OPS wmt_ic_ops_soc = { -+ .icId = 0x0000, /* soc may have mt6572/82/71/83,but they have the same sw init flow */ -+ .sw_init = mtk_wcn_soc_sw_init, -+ .sw_deinit = mtk_wcn_soc_sw_deinit, -+ .ic_pin_ctrl = mtk_wcn_soc_pin_ctrl, -+ .ic_ver_check = mtk_wcn_soc_ver_check, -+ .co_clock_ctrl = mtk_wcn_soc_co_clock_ctrl, -+ .is_quick_sleep = mtk_wcn_soc_quick_sleep_flag_get, -+ .is_aee_dump_support = mtk_wcn_soc_aee_dump_flag_get, -+}; -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+static INT32 mtk_wcn_soc_sw_init(P_WMT_HIF_CONF pWmtHifConf) -+{ -+ INT32 iRet = -1; -+ unsigned long ctrlPa1; -+ unsigned long ctrlPa2; -+ UINT32 hw_ver; -+ WMT_CTRL_DATA ctrlData; -+#ifdef CFG_WMT_READ_EFUSE_VCN33 -+ UINT32 efuse_d3_vcn33 = 2; /*default voltage is 3.5V*/ -+#endif -+#if CFG_WMT_MULTI_PATCH -+ UINT32 patch_num = 0; -+ UINT32 patch_index = 0; -+#endif -+#if CFG_WMT_WIFI_5G_SUPPORT -+ UINT32 dDieChipid = 0; -+ UINT32 aDieChipid = 0; -+ UINT8 evtbuf[20]; -+ UINT32 u4Res; -+ UINT32 pmicChipid = 0; -+#endif -+ WMT_DBG_FUNC(" start\n"); -+ -+ osal_assert(NULL != gp_soc_info); -+ if ((NULL == gp_soc_info) -+ || (NULL == pWmtHifConf) -+ ) { -+ WMT_ERR_FUNC("null pointers: gp_soc_info(0x%p), pWmtHifConf(0x%p)\n", gp_soc_info, pWmtHifConf); -+ return -1; -+ } -+ -+ hw_ver = gp_soc_info->u4HwVer; -+ -+ /* 4 <3.2> start init for BTIF */ -+ if (WMT_HIF_BTIF == pWmtHifConf->hifType) { -+ /* 1. Query chip STP default options (TEST-ONLY) */ -+ /* WMT_DBG_FUNC("WMT-CORE: init_table_1_2 set chip baud:%d", pWmtHifConf->au4HifConf[0]); */ -+ iRet = wmt_core_init_script(init_table_1_2, osal_array_size(init_table_1_2)); -+ if (iRet) { -+ WMT_ERR_FUNC("init_table_1_2 fail(%d)\n", iRet); -+ osal_assert(0); -+ return -2; -+ } -+ /* 2. Set chip STP options */ -+ iRet = wmt_core_init_script(init_table_4, osal_array_size(init_table_4)); -+ if (iRet) { -+ WMT_ERR_FUNC("init_table_4 fail(%d)\n", iRet); -+ return -3; -+ } -+ -+ /* 3. Enable host full mode */ -+ ctrlPa1 = WMT_STP_CONF_MODE; -+ ctrlPa2 = MTKSTP_BTIF_FULL_MODE; -+ iRet = wmt_core_ctrl(WMT_CTRL_STP_CONF, &ctrlPa1, &ctrlPa2); -+ ctrlPa1 = WMT_STP_CONF_EN; -+ ctrlPa2 = 1; -+ iRet += wmt_core_ctrl(WMT_CTRL_STP_CONF, &ctrlPa1, &ctrlPa2); -+ if (iRet) { -+ WMT_ERR_FUNC("enable host STP-BTIF-FULL mode fail(%d)\n", iRet); -+ return -4; -+ } -+ WMT_DBG_FUNC("enable host STP-BTIF-FULL mode\n"); -+ /*4. wait for 10ms, enough for chip do mechanism switch.(at least 2ms is needed) */ -+ osal_sleep_ms(10); -+ /* 5. Query chip STP options (TEST-ONLY) */ -+ iRet = wmt_core_init_script(init_table_5, osal_array_size(init_table_5)); -+ if (iRet) { -+ WMT_ERR_FUNC("init_table_5 fail(%d)\n", iRet); -+ return -5; -+ } -+ } -+#if CFG_WMT_POWER_ON_DLM -+ iRet = wmt_core_init_script(wmt_power_on_dlm_table, osal_array_size(wmt_power_on_dlm_table)); -+ if (iRet) -+ WMT_ERR_FUNC("wmt_power_on_dlm_table fail(%d)\n", iRet); -+ WMT_DBG_FUNC("wmt_power_on_dlm_table ok\n"); -+#endif -+ /* 6. download patch */ -+#if CFG_WMT_MULTI_PATCH -+ /* 6.1 Let launcher to search patch info */ -+ iRet = mtk_wcn_soc_patch_info_prepare(); -+ if (iRet) { -+ WMT_ERR_FUNC("patch info perpare fail(%d)\n", iRet); -+ return -6; -+ } -+ -+ /* 6.2 Read patch number */ -+ ctrlPa1 = 0; -+ ctrlPa2 = 0; -+ wmt_core_ctrl(WMT_CTRL_GET_PATCH_NUM, &ctrlPa1, &ctrlPa2); -+ patch_num = ctrlPa1; -+ WMT_DBG_FUNC("patch total num = [%d]\n", patch_num); -+ -+#if CFG_WMT_PATCH_DL_OPTM -+ if (0x0279 == wmt_ic_ops_soc.icId) { -+ iRet = wmt_core_init_script(set_mcuclk_table_3, osal_array_size(set_mcuclk_table_3)); -+ if (iRet) -+ WMT_ERR_FUNC("set_mcuclk_table_3 fail(%d)\n", iRet); -+ } else { -+ iRet = wmt_core_init_script(set_mcuclk_table_1, osal_array_size(set_mcuclk_table_1)); -+ if (iRet) -+ WMT_ERR_FUNC("set_mcuclk_table_1 fail(%d)\n", iRet); -+ } -+#endif -+ /* 6.3 Multi-patch Patch download */ -+ for (patch_index = 0; patch_index < patch_num; patch_index++) { -+ iRet = mtk_wcn_soc_patch_dwn(patch_index); -+ if (iRet) { -+ WMT_ERR_FUNC("patch dwn fail (%d),patch_index(%d)\n", iRet, patch_index); -+ return -7; -+ } -+ iRet = wmt_core_init_script(init_table_3, osal_array_size(init_table_3)); -+ if (iRet) { -+ WMT_ERR_FUNC("init_table_3 fail(%d)\n", iRet); -+ return -8; -+ } -+ } -+ -+#if CFG_WMT_PATCH_DL_OPTM -+ if (0x0279 == wmt_ic_ops_soc.icId) { -+ iRet = wmt_core_init_script(set_mcuclk_table_4, osal_array_size(set_mcuclk_table_4)); -+ if (iRet) -+ WMT_ERR_FUNC("set_mcuclk_table_4 fail(%d)\n", iRet); -+ } else { -+ iRet = wmt_core_init_script(set_mcuclk_table_2, osal_array_size(set_mcuclk_table_2)); -+ if (iRet) -+ WMT_ERR_FUNC("set_mcuclk_table_2 fail(%d)\n", iRet); -+ } -+#endif -+ -+#else -+ /* 6.3 Patch download */ -+ iRet = mtk_wcn_soc_patch_dwn(); -+ /* If patch download fail, we just ignore this error and let chip init process goes on */ -+ if (iRet) -+ WMT_ERR_FUNC("patch dwn fail (%d), just omit\n", iRet); -+ -+ /* 6.4. WMT Reset command */ -+ iRet = wmt_core_init_script(init_table_3, osal_array_size(init_table_3)); -+ if (iRet) { -+ WMT_ERR_FUNC("init_table_3 fail(%d)\n", iRet); -+ return -8; -+ } -+#endif -+ -+#ifdef CFG_WMT_READ_EFUSE_VCN33 -+ /*get CrystalTiming value before set it */ -+ iRet = wmt_core_tx(get_efuse_vcn33_script[0].cmd, get_efuse_vcn33_script[0].cmdSz, &u4Res, -+ MTK_WCN_BOOL_FALSE); -+ if (iRet || (u4Res != get_efuse_vcn33_script[0].cmdSz)) { -+ WMT_ERR_FUNC("WMT-CORE: write (%s) iRet(%d) cmd len err(%d, %d)\n", -+ get_efuse_vcn33_script[0].str, iRet, u4Res, get_efuse_vcn33_script[0].cmdSz); -+ } -+ /* EVENT BUF */ -+ osal_memset(get_efuse_vcn33_script[0].evt, 0, get_efuse_vcn33_script[0].evtSz); -+ iRet = wmt_core_rx(get_efuse_vcn33_script[0].evt, get_efuse_vcn33_script[0].evtSz, &u4Res); -+ if (iRet || (u4Res != get_efuse_vcn33_script[0].evtSz)) { -+ WMT_ERR_FUNC("WMT-CORE: read (%s) iRet(%d) evt len err(rx:%d, exp:%d)\n", -+ get_efuse_vcn33_script[0].str, iRet, u4Res, get_efuse_vcn33_script[0].evtSz); -+ mtk_wcn_stp_dbg_dump_package(); -+ } -+ efuse_d3_vcn33 = WMT_GET_EFUSE_VCN33_EVT[5] & 0x03; -+ WMT_INFO_FUNC("Read efuse to set PMIC voltage:(%d)\n", efuse_d3_vcn33); -+ wmt_set_pmic_voltage(efuse_d3_vcn33); -+#endif -+ -+#if CFG_WMT_FILTER_MODE_SETTING -+ if ((0x6580 == wmt_ic_ops_soc.icId) || -+ (0x8163 == wmt_ic_ops_soc.icId) || -+ (0x6752 == wmt_ic_ops_soc.icId) || -+ (0x6582 == wmt_ic_ops_soc.icId) || -+ (0x6592 == wmt_ic_ops_soc.icId) || -+ (0x0279 == wmt_ic_ops_soc.icId) || -+ (0x0326 == wmt_ic_ops_soc.icId) || -+ (0x0321 == wmt_ic_ops_soc.icId) || (0x0335 == wmt_ic_ops_soc.icId) || (0x0337 == wmt_ic_ops_soc.icId)) { -+ wmt_stp_wifi_lte_coex(); -+ WMT_DBG_FUNC("wmt_stp_wifi_lte_coex done!\n"); -+ } -+ if ((0x6582 == wmt_ic_ops_soc.icId) || (0x6592 == wmt_ic_ops_soc.icId)) { -+ /*get gpio tdm req antsel number */ -+ ctrlPa1 = 0; -+ ctrlPa2 = 0; -+ wmt_core_ctrl(WMT_CTRL_GET_TDM_REQ_ANTSEL, &ctrlPa1, &ctrlPa2); -+ WMT_INFO_FUNC("get GPIO TDM REQ ANTSEL number(%d)\n", ctrlPa1); -+ /*set gpio tdm req antsel number to firmware */ -+ WMT_COEX_TDM_REQ_ANTSEL_NUM_CMD[5] = ctrlPa1; -+ iRet = wmt_core_init_script(get_tdm_req_antsel_num_table, -+ osal_array_size(get_tdm_req_antsel_num_table)); -+ if (iRet) -+ WMT_ERR_FUNC("get_tdm_req_antsel_num_table fail(%d)\n", iRet); -+ } -+#endif -+ /* 7. start RF calibration data */ -+ ctrlPa1 = BT_PALDO; -+ ctrlPa2 = PALDO_ON; -+ iRet = wmt_core_ctrl(WMT_CTRL_SOC_PALDO_CTRL, &ctrlPa1, &ctrlPa2); -+ ctrlPa1 = WIFI_PALDO; -+ ctrlPa2 = PALDO_ON; -+ iRet = wmt_core_ctrl(WMT_CTRL_SOC_PALDO_CTRL, &ctrlPa1, &ctrlPa2); -+ -+ iRet = wmt_core_init_script(calibration_table, osal_array_size(calibration_table)); -+ if (iRet) { -+ /* pwrap_read(0x0210,&ctrlPa1); */ -+ /* pwrap_read(0x0212,&ctrlPa2); */ -+ WMT_ERR_FUNC("power status: 210:(%d),212:(%d)!\n", ctrlPa1, ctrlPa2); -+ WMT_ERR_FUNC("calibration_table fail(%d)\n", iRet); -+ return -9; -+ } -+ -+ ctrlPa1 = BT_PALDO; -+ ctrlPa2 = PALDO_OFF; -+ iRet = wmt_core_ctrl(WMT_CTRL_SOC_PALDO_CTRL, &ctrlPa1, &ctrlPa2); -+ ctrlPa1 = WIFI_PALDO; -+ ctrlPa2 = PALDO_OFF; -+ iRet = wmt_core_ctrl(WMT_CTRL_SOC_PALDO_CTRL, &ctrlPa1, &ctrlPa2); -+ -+ iRet = wmt_stp_init_coex(); -+ if (iRet) { -+ WMT_ERR_FUNC("init_coex fail(%d)\n", iRet); -+ return -10; -+ } -+ WMT_DBG_FUNC("init_coex ok\n"); -+ -+#if CFG_WMT_CRYSTAL_TIMING_SET -+ mtk_wcn_soc_crystal_triming_set(); -+#endif -+ -+#if CFG_WMT_SDIO_DRIVING_SET -+ mtk_wcn_soc_set_sdio_driving(); -+#endif -+ -+ if (WMT_CO_CLOCK_EN == mtk_wcn_soc_co_clock_get()) { -+ WMT_INFO_FUNC("co-clock enabled.\n"); -+ -+ iRet = wmt_core_init_script(osc_type_table, osal_array_size(osc_type_table)); -+ if (iRet) { -+ WMT_ERR_FUNC("osc_type_table fail(%d), goes on\n", iRet); -+ return -11; -+ } -+ } else { -+ WMT_WARN_FUNC("co-clock disabled.\n"); -+ } -+#if (MTK_WCN_CMB_MERGE_INTERFACE_SUPPORT) -+ iRet = wmt_core_init_script(merge_pcm_table, osal_array_size(merge_pcm_table)); -+ if (iRet) { -+ WMT_ERR_FUNC("merge_pcm_table fail(%d), goes on\n", iRet); -+ return -12; -+ } -+#endif -+ -+ /* 15. Set FM strap */ -+ WMT_STRAP_CONF_CMD_FM_COMM[5] = (UINT8) pWmtHifConf->au4StrapConf[0]; -+ WMT_STRAP_CONF_EVT[5] = (UINT8) pWmtHifConf->au4StrapConf[0]; -+ iRet = wmt_core_init_script(init_table_5_1, osal_array_size(init_table_5_1)); -+ if (iRet) { -+ WMT_ERR_FUNC("init_table_5_1 fm mode(%d) fail(%d)\n", pWmtHifConf->au4StrapConf[0], iRet); -+ return -13; -+ } -+ WMT_DBG_FUNC("set fm mode (%d) ok\n", pWmtHifConf->au4StrapConf[0]); -+ -+#if CFG_SET_OPT_REG /*set registers */ -+ iRet = wmt_core_init_script(set_registers, osal_array_size(set_registers)); -+ if (iRet) { -+ WMT_ERR_FUNC("set_registers fail(%d)", iRet); -+ return -14; -+ } -+#endif -+ -+#if CFG_WMT_COREDUMP_ENABLE -+ /*Open Core Dump Function @QC begin */ -+ mtk_wcn_stp_coredump_flag_ctrl(1); -+#endif -+ if (0 != mtk_wcn_stp_coredump_flag_get()) { -+ iRet = wmt_core_init_script(init_table_6, osal_array_size(init_table_6)); -+ if (iRet) { -+ WMT_ERR_FUNC("init_table_6 core dump setting fail(%d)\n", iRet); -+ return -15; -+ } -+ WMT_DBG_FUNC("enable soc_consys firmware coredump\n"); -+ } else { -+ WMT_DBG_FUNC("disable soc_consys firmware coredump\n"); -+ } -+ -+#if CFG_WMT_WIFI_5G_SUPPORT -+ dDieChipid = wmt_ic_ops_soc.icId; -+ WMT_DBG_FUNC("current SOC chipid is 0x%x\n", dDieChipid); -+ if (0x6592 == dDieChipid) { -+ /* read A die chipid by wmt cmd */ -+ iRet = -+ wmt_core_tx((PUINT8) &WMT_GET_SOC_ADIE_CHIPID_CMD[0], sizeof(WMT_GET_SOC_ADIE_CHIPID_CMD), &u4Res, -+ MTK_WCN_BOOL_FALSE); -+ if (iRet || (u4Res != sizeof(WMT_GET_SOC_ADIE_CHIPID_CMD))) { -+ WMT_ERR_FUNC("wmt_core:read A die chipid CMD fail(%d),size(%d)\n", iRet, u4Res); -+ return -16; -+ } -+ osal_memset(evtbuf, 0, sizeof(evtbuf)); -+ iRet = wmt_core_rx(evtbuf, sizeof(WMT_GET_SOC_ADIE_CHIPID_EVT), &u4Res); -+ if (iRet || (u4Res != sizeof(WMT_GET_SOC_ADIE_CHIPID_EVT))) { -+ WMT_ERR_FUNC("wmt_core:read A die chipid EVT fail(%d),size(%d)\n", iRet, u4Res); -+ return -17; -+ } -+ -+ osal_memcpy(&aDieChipid, &evtbuf[u4Res - 2], 2); -+ WMT_INFO_FUNC("get SOC A die chipid(0x%x)\n", aDieChipid); -+ -+ if (0x6625 == aDieChipid) { -+ iRet = -+ wmt_core_tx((PUINT8) &WMT_GET_SOC_6625_L_CMD[0], sizeof(WMT_GET_SOC_6625_L_CMD), &u4Res, -+ MTK_WCN_BOOL_FALSE); -+ if (iRet || (u4Res != sizeof(WMT_GET_SOC_6625_L_CMD))) -+ WMT_ERR_FUNC("wmt_core:read A die efuse CMD fail(%d),size(%d)\n", iRet, u4Res); -+ osal_memset(evtbuf, 0, sizeof(evtbuf)); -+ iRet = wmt_core_rx(evtbuf, sizeof(WMT_GET_SOC_6625_L_EVT), &u4Res); -+ if (iRet || (u4Res != sizeof(WMT_GET_SOC_6625_L_EVT))) -+ WMT_ERR_FUNC("wmt_core:read A die efuse EVT fail(%d),size(%d)\n", iRet, u4Res); -+ -+ WMT_INFO_FUNC("read SOC Adie Efuse(0x120) value:0x%2x,0x%2x,0x%2x,0x%2x -> %s\n", -+ evtbuf[u4Res - 4], evtbuf[u4Res - 3], evtbuf[u4Res - 2], evtbuf[u4Res - 1], -+ evtbuf[u4Res - 2] == 0x31 ? "MT6625L" : "MT6625"); -+ } -+ /* get PMIC chipid */ -+ -+ ctrlData.ctrlId = WMT_CTRL_SOC_PALDO_CTRL; -+ ctrlData.au4CtrlData[0] = PMIC_CHIPID_PALDO; -+ ctrlData.au4CtrlData[1] = 0; -+ iRet = wmt_ctrl(&ctrlData); -+ if (iRet < 0) { -+ WMT_ERR_FUNC("wmt_core: read PMIC chipid fail(%d)\n", iRet); -+ return -18; -+ } -+ pmicChipid = ctrlData.au4CtrlData[2]; -+ WMT_INFO_FUNC("current PMIC chipid(0x%x)\n", pmicChipid); -+ -+ /* MT6625 & MT6322, write 1 to 0x0414[12] */ -+ /* MT6625 & MT6323, assert */ -+ /* MT6627 & (MT6322 or MT6323),write 0 to 0x0414[12] */ -+ -+ switch (aDieChipid) { -+ case 0x6625: -+ if (0x6322 == pmicChipid) { -+ WMT_INFO_FUNC("wmt-core:enable wifi 5G support\n"); -+ ctrlPa1 = WIFI_5G_PALDO; -+ ctrlPa2 = PALDO_ON; -+ wmt_core_ctrl(WMT_CTRL_SOC_PALDO_CTRL, &ctrlPa1, &ctrlPa2); -+ } else if (0x6323 == pmicChipid) { -+ osal_assert(0); -+ } else { -+ WMT_WARN_FUNC("wmt-core: unknown PMIC chipid\n"); -+ } -+ break; -+ case 0x6627: -+ if ((0x6322 == pmicChipid) || (0x6323 == pmicChipid)) { -+ WMT_INFO_FUNC("wmt-core: disable wifi 5G support\n"); -+ ctrlPa1 = WIFI_5G_PALDO; -+ ctrlPa2 = PALDO_OFF; -+ wmt_core_ctrl(WMT_CTRL_SOC_PALDO_CTRL, &ctrlPa1, &ctrlPa2); -+ } else { -+ WMT_WARN_FUNC("wmt-core: unknown PMIC chipid\n"); -+ } -+ break; -+ default: -+ WMT_WARN_FUNC("wmt-core: unknown A die chipid(0x%x)\n", aDieChipid); -+ break; -+ } -+ } -+#endif -+ -+#if 1 -+ ctrlData.ctrlId = WMT_CTRL_SET_STP_DBG_INFO; -+ ctrlData.au4CtrlData[0] = wmt_ic_ops_soc.icId; -+ ctrlData.au4CtrlData[1] = (SIZE_T) gp_soc_info->cChipVersion; -+ ctrlData.au4CtrlData[2] = (SIZE_T) &gp_soc_patch_info; -+ iRet = wmt_ctrl(&ctrlData); -+ if (iRet) { -+ WMT_ERR_FUNC("set dump info fail(%d)\n", iRet); -+ return -19; -+ } -+#endif -+ -+#if CFG_WMT_PS_SUPPORT -+ osal_assert(NULL != gp_soc_info); -+ if (NULL != gp_soc_info) { -+ if (MTK_WCN_BOOL_FALSE != gp_soc_info->bPsmSupport) -+ wmt_lib_ps_enable(); -+ else -+ wmt_lib_ps_disable(); -+ } -+#endif -+ -+ return 0; -+} -+ -+static INT32 mtk_wcn_soc_sw_deinit(P_WMT_HIF_CONF pWmtHifConf) -+{ -+ WMT_DBG_FUNC(" start\n"); -+ -+#if CFG_WMT_PS_SUPPORT -+ osal_assert(NULL != gp_soc_info); -+ if ((NULL != gp_soc_info) -+ && (MTK_WCN_BOOL_FALSE != gp_soc_info->bPsmSupport)) { -+ wmt_lib_ps_disable(); -+ } -+#endif -+ -+ gp_soc_info = NULL; -+ -+ return 0; -+} -+ -+static INT32 mtk_wcn_soc_aif_ctrl(WMT_IC_PIN_STATE state, UINT32 flag) -+{ -+ INT32 ret = -1; -+ UINT32 val; -+ -+ if ((flag & WMT_LIB_AIF_FLAG_MASK) == WMT_LIB_AIF_FLAG_SHARE) { -+ WMT_INFO_FUNC("PCM & I2S PIN SHARE\n"); -+#if 0 -+ switch (state) { -+ case WMT_IC_AIF_0: -+ /* BT_PCM_OFF & FM line in/out */ -+ val = 0x00000770; -+ ret = wmt_core_reg_rw_raw(1, 0x80050140, &val, 0x00000FF0); -+ val = 0x00000000; -+ ret += wmt_core_reg_rw_raw(1, 0x80050150, &val, 0x00000800); -+ break; -+ -+ case WMT_IC_AIF_1: -+ /* BT_PCM_ON & FM line in/out */ -+ val = 0x00000700; -+ ret = wmt_core_reg_rw_raw(1, 0x80050140, &val, 0x00000FF0); -+ val = 0x00000000; -+ ret += wmt_core_reg_rw_raw(1, 0x80050150, &val, 0x00000800); -+ break; -+ -+ case WMT_IC_AIF_2: -+ /* BT_PCM_OFF & FM I2S */ -+ val = 0x00000710; -+ ret = wmt_core_reg_rw_raw(1, 0x80050140, &val, 0x00000FF0); -+ val = 0x00000800; /* 800:3-wire, 000: 4-wire */ -+ ret += wmt_core_reg_rw_raw(1, 0x80050150, &val, 0x00000800); -+ break; -+ default: -+ WMT_ERR_FUNC("unsupported state (%d)\n", state); -+ ret = -1; -+ break; -+ } -+#else -+ WMT_WARN_FUNC("TBD!!"); -+ ret = 0; -+#endif -+ } else { -+ /*PCM & I2S separate */ -+ WMT_INFO_FUNC("PCM & I2S PIN SEPARATE\n"); -+#if 0 -+ switch (state) { -+ case WMT_IC_AIF_0: -+ /* BT_PCM_OFF & FM line in/out */ -+ val = 0x00000770; -+ ret = wmt_core_reg_rw_raw(1, 0x80050140, &val, 0x00000FF0); -+ val = 0x00000000; -+ ret += wmt_core_reg_rw_raw(1, 0x80050150, &val, 0x00000800); -+ break; -+ -+ case WMT_IC_AIF_1: -+ /* BT_PCM_ON & FM line in/out */ -+ val = 0x00000700; -+ ret = wmt_core_reg_rw_raw(1, 0x80050140, &val, 0x00000FF0); -+ val = 0x00000000; -+ ret += wmt_core_reg_rw_raw(1, 0x80050150, &val, 0x00000800); -+ break; -+ -+ case WMT_IC_AIF_2: -+ /* BT_PCM_OFF & FM I2S */ -+ val = 0x00000070; -+ ret = wmt_core_reg_rw_raw(1, 0x80050140, &val, 0x00000FF0); -+ val = 0x00000800; /* 800:3-wire, 000: 4-wire */ -+ ret += wmt_core_reg_rw_raw(1, 0x80050150, &val, 0x00000800); -+ -+ break; -+ case WMT_IC_AIF_3: -+ val = 0x00000000; -+ ret = wmt_core_reg_rw_raw(1, 0x80050140, &val, 0x00000FF0); -+ val = 0x00000800; /* 800:3-wire, 000: 4-wire */ -+ ret += wmt_core_reg_rw_raw(1, 0x80050150, &val, 0x00000800); -+ -+ break; -+ default: -+ WMT_ERR_FUNC("unsupported state (%d)\n", state); -+ ret = -1; -+ break; -+ } -+#else -+ switch (state) { -+ case WMT_IC_AIF_0: -+ /* BT_PCM_OFF & FM line in/out */ -+ ret = 0; -+ break; -+ case WMT_IC_AIF_1: -+ /* BT_PCM_ON & FM line in/out */ -+ ret = 0; -+ break; -+ -+ case WMT_IC_AIF_2: -+ /* BT_PCM_OFF & FM I2S */ -+ val = 0x01110000; -+ ret = wmt_core_reg_rw_raw(1, 0x80050078, &val, 0x0FFF0000); -+ -+ break; -+ case WMT_IC_AIF_3: -+ ret = 0; -+ break; -+ -+ default: -+ WMT_ERR_FUNC("unsupported state (%d)\n", state); -+ ret = -1; -+ break; -+ } -+#endif -+ } -+ -+ if (!ret) -+ WMT_WARN_FUNC("new state(%d) fail(%d)\n", state, ret); -+ WMT_INFO_FUNC("new state(%d) ok\n", state); -+ -+ return ret; -+} -+ -+static INT32 mtk_wcn_soc_gps_sync_ctrl(WMT_IC_PIN_STATE state, UINT32 flag) -+{ -+ INT32 iRet = -1; -+ UINT32 uVal = 0; -+ -+ /* mt6797 can not access reg:0x80050078 and no need to do GPS SYNC */ -+ if (0x0279 != wmt_ic_ops_soc.icId) { -+ if (WMT_IC_PIN_MUX == state) -+ uVal = 0x1 << 28; -+ else -+ uVal = 0x5 << 28; -+ iRet = wmt_core_reg_rw_raw(1, 0x80050078, &uVal, 0x7 << 28); -+ if (iRet) -+ WMT_ERR_FUNC("gps_sync pin ctrl failed, iRet(%d)\n", iRet); -+ } else -+ WMT_INFO_FUNC("This chip no need to sync GPS and MODEM!\n"); -+ -+ /* anyway, we return 0 */ -+ return 0; -+} -+ -+static INT32 mtk_wcn_soc_pin_ctrl(WMT_IC_PIN_ID id, WMT_IC_PIN_STATE state, UINT32 flag) -+{ -+ INT32 ret; -+ -+ WMT_DBG_FUNC("ic pin id:%d, state:%d, flag:0x%x\n", id, state, flag); -+ -+ ret = -1; -+ switch (id) { -+ case WMT_IC_PIN_AUDIO: -+ ret = mtk_wcn_soc_aif_ctrl(state, flag); -+ break; -+ -+ case WMT_IC_PIN_EEDI: -+ WMT_WARN_FUNC("TBD!!"); -+ /* We just return 0 here, prevent from WMT-FUNC do other register read/write */ -+ ret = 0; -+ break; -+ -+ case WMT_IC_PIN_EEDO: -+ WMT_WARN_FUNC("TBD!!"); -+ /* We just return 0 here, prevent from WMT-FUNC do other register read/write */ -+ ret = 0; -+ break; -+ case WMT_IC_PIN_GSYNC: -+ ret = mtk_wcn_soc_gps_sync_ctrl(state, flag); -+ break; -+ default: -+ break; -+ } -+ WMT_INFO_FUNC("ret = (%d)\n", ret); -+ -+ return ret; -+} -+ -+INT32 mtk_wcn_soc_co_clock_ctrl(WMT_CO_CLOCK on) -+{ -+ INT32 iRet = 0; -+ -+ if ((WMT_CO_CLOCK_DIS <= on) && (WMT_CO_CLOCK_MAX > on)) { -+ gCoClockEn = on; -+ } else { -+ WMT_DBG_FUNC("0x%x: error parameter:%d\n", wmt_ic_ops_soc.icId, on); -+ iRet = -1; -+ } -+ WMT_DBG_FUNC("0x%x: Co-clock %s\n", wmt_ic_ops_soc.icId, -+ (gCoClockEn == WMT_CO_CLOCK_DIS) ? "disabled" : "enabled"); -+ -+ return iRet; -+} -+ -+static MTK_WCN_BOOL mtk_wcn_soc_quick_sleep_flag_get(VOID) -+{ -+ return MTK_WCN_BOOL_TRUE; -+} -+ -+static MTK_WCN_BOOL mtk_wcn_soc_aee_dump_flag_get(VOID) -+{ -+ return MTK_WCN_BOOL_FALSE; -+} -+ -+WMT_CO_CLOCK mtk_wcn_soc_co_clock_get(VOID) -+{ -+ return gCoClockEn; -+} -+ -+static INT32 mtk_wcn_soc_ver_check(VOID) -+{ -+ UINT32 hw_ver; -+ UINT32 fw_ver; -+ INT32 iret; -+ const WMT_IC_INFO_S *p_info; -+ unsigned long ctrlPa1; -+ unsigned long ctrlPa2; -+ -+ /* 1. identify chip versions: HVR(HW_VER) and FVR(FW_VER) */ -+ WMT_LOUD_FUNC("0x%x: before read hw_ver (hw version)\n", wmt_ic_ops_soc.icId); -+ iret = wmt_core_reg_rw_raw(0, GEN_HVR, &hw_ver, GEN_VER_MASK); -+ if (iret) { -+ WMT_ERR_FUNC("0x%x: read hw_ver fail:%d\n", wmt_ic_ops_soc.icId, iret); -+ return -2; -+ } -+ WMT_WARN_FUNC("0x%x: read hw_ver (hw version) (0x%x)\n", wmt_ic_ops_soc.icId, hw_ver); -+ -+ WMT_LOUD_FUNC("0x%x: before fw_ver (rom version)\n", wmt_ic_ops_soc.icId); -+ wmt_core_reg_rw_raw(0, GEN_FVR, &fw_ver, GEN_VER_MASK); -+ if (iret) { -+ WMT_ERR_FUNC("0x%x: read fw_ver fail:%d\n", wmt_ic_ops_soc.icId, iret); -+ return -2; -+ } -+ WMT_WARN_FUNC("0x%x: read fw_ver (rom version) (0x%x)\n", wmt_ic_ops_soc.icId, fw_ver); -+ -+ p_info = mtk_wcn_soc_find_wmt_ic_info(hw_ver); -+ if (NULL == p_info) { -+ WMT_ERR_FUNC("0x%x: hw_ver(0x%x) find wmt ic info fail\n", wmt_ic_ops_soc.icId); -+ return -3; -+ } -+ WMT_WARN_FUNC("0x%x: ic info: %s.%s (0x%x/0x%x, WMTHWVER:%d, patch_ext:%s)\n", -+ wmt_ic_ops_soc.icId, p_info->cChipName, p_info->cChipVersion, -+ hw_ver, fw_ver, p_info->eWmtHwVer, p_info->cPatchNameExt); -+ -+ /* hw id & version */ -+ ctrlPa1 = (wmt_ic_ops_soc.icId << 16) | (hw_ver & 0x0000FFFF); -+ /* translated hw version & fw rom version */ -+ ctrlPa2 = ((UINT32) (p_info->eWmtHwVer) << 16) | (fw_ver & 0x0000FFFF); -+ -+ iret = wmt_core_ctrl(WMT_CTRL_HWIDVER_SET, &ctrlPa1, &ctrlPa2); -+ if (iret) -+ WMT_WARN_FUNC("0x%x: WMT_CTRL_HWIDVER_SET fail(%d)\n", wmt_ic_ops_soc.icId, iret); -+ -+ gp_soc_info = p_info; -+ return 0; -+} -+ -+static const WMT_IC_INFO_S *mtk_wcn_soc_find_wmt_ic_info(const UINT32 hw_ver) -+{ -+ /* match chipversion with u4HwVer item in mtk_wcn_soc_info_table */ -+ const UINT32 size = osal_array_size(mtk_wcn_soc_info_table); -+ INT32 index = 0; -+ -+ /* George: reverse the search order to favor newer version products -+ * TODO:[FixMe][GeorgeKuo] Remove full match once API wmt_lib_get_hwver() -+ * is changed correctly in the future!! -+ * Leave full match here is a workaround for GPS to distinguish E3/E4 ICs. -+ */ -+ index = size - 1; -+ /* full match */ -+ while ((0 <= index) && (hw_ver != mtk_wcn_soc_info_table[index].u4HwVer)) -+ --index; -+ if (0 <= index) { -+ WMT_DBG_FUNC("found ic info(0x%x) by full match! index:%d\n", hw_ver, index); -+ return &mtk_wcn_soc_info_table[index]; -+ } -+ -+ WMT_WARN_FUNC("find no ic info for (0x%x) by full match!try major num match!\n", hw_ver); -+ -+ /* George: The ONLY CORRECT method to find supported hw table. Match MAJOR -+ * NUM only can help us support future minor hw ECO, or fab switch, etc. -+ * FULL matching eliminate such flexibility and software package have to be -+ * updated EACH TIME even when minor hw ECO or fab switch!!! -+ */ -+ /* George: reverse the search order to favor newer version products */ -+ index = size - 1; -+ /* major num match */ -+ while ((0 <= index) && -+ (MAJORNUM(hw_ver) != MAJORNUM(mtk_wcn_soc_info_table[index].u4HwVer))) { -+ --index; -+ } -+ if (0 <= index) { -+ WMT_DBG_FUNC("0x%x: found ic info for hw_ver(0x%x) by major num! index:%d\n", -+ wmt_ic_ops_soc.icId, hw_ver, index); -+ return &mtk_wcn_soc_info_table[index]; -+ } -+ -+ WMT_ERR_FUNC("0x%x: find no ic info for hw_ver(0x%x) by full match nor major num match!\n", -+ wmt_ic_ops_soc.icId, hw_ver); -+ WMT_ERR_FUNC("Set default chip version: E1!\n"); -+ return &mtk_wcn_soc_info_table[0]; -+} -+ -+#if CFG_WMT_FILTER_MODE_SETTING -+static INT32 wmt_stp_wifi_lte_coex(VOID) -+{ -+ INT32 iRet; -+ unsigned long addr; -+ WMT_GEN_CONF *pWmtGenConf; -+ -+ /*Get wmt config */ -+ iRet = wmt_core_ctrl(WMT_CTRL_GET_WMT_CONF, &addr, 0); -+ if (iRet) { -+ WMT_ERR_FUNC("ctrl GET_WMT_CONF fail(%d)\n", iRet); -+ return -2; -+ } -+ WMT_DBG_FUNC("ctrl GET_WMT_CONF ok(0x%08lx)\n", addr); -+ -+ pWmtGenConf = (P_WMT_GEN_CONF) addr; -+ -+ /*Check if WMT.cfg exists */ -+ if (pWmtGenConf->cfgExist == 0) { -+ WMT_INFO_FUNC("cfgExist == 0, skip config chip\n"); -+ /*if WMT.cfg not existed, still return success and adopt the default value */ -+ return 0; -+ } -+ -+ osal_sleep_ms(5); -+ -+ if (pWmtGenConf->coex_wmt_filter_mode == 0) { -+ if ((0x6752 == wmt_ic_ops_soc.icId) || -+ (0x6580 == wmt_ic_ops_soc.icId) || -+ (0x8163 == wmt_ic_ops_soc.icId) || -+ (0x0326 == wmt_ic_ops_soc.icId) || -+ (0x0321 == wmt_ic_ops_soc.icId) || -+ (0x0335 == wmt_ic_ops_soc.icId) || (0x0337 == wmt_ic_ops_soc.icId)) { -+ iRet = -+ wmt_core_init_script(set_wifi_lte_coex_table_1, osal_array_size(set_wifi_lte_coex_table_1)); -+ WMT_DBG_FUNC("wmt_core:set_wifi_lte_coex_table_1 %s(%d)\n", iRet ? "fail" : "ok", iRet); -+ } else if (0x0279 == wmt_ic_ops_soc.icId) { -+ /* add WMT_COXE_CONFIG_EXT_COMPONENT_OPCODE command for 2G4 eLNA demand*/ -+ if (pWmtGenConf->coex_wmt_ext_component) { -+ WMT_INFO_FUNC("coex_wmt_ext_component:0x%x\n", pWmtGenConf->coex_wmt_ext_component); -+ set_wifi_lte_coex_table_2[0].cmd[5] = pWmtGenConf->coex_wmt_ext_component; -+ } -+ iRet = -+ wmt_core_init_script(set_wifi_lte_coex_table_2, osal_array_size(set_wifi_lte_coex_table_2)); -+ WMT_DBG_FUNC("wmt_core:set_wifi_lte_coex_table_2 %s(%d)\n", iRet ? "fail" : "ok", iRet); -+ } else { -+ iRet = -+ wmt_core_init_script(set_wifi_lte_coex_table_0, osal_array_size(set_wifi_lte_coex_table_0)); -+ WMT_DBG_FUNC("wmt_core:set_wifi_lte_coex_table_0 %s(%d)\n", iRet ? "fail" : "ok", iRet); -+ } -+ } -+ -+ return iRet; -+} -+#endif -+ -+static INT32 wmt_stp_init_coex(VOID) -+{ -+ INT32 iRet; -+ unsigned long addr; -+ WMT_GEN_CONF *pWmtGenConf; -+ -+#define COEX_WMT 0 -+ -+#if CFG_SUBSYS_COEX_NEED -+ /* no need for MT6628 */ -+#define COEX_BT 1 -+#define COEX_WIFI 2 -+#define COEX_PTA 3 -+#define COEX_MISC 4 -+#endif -+ /*Get wmt config */ -+ iRet = wmt_core_ctrl(WMT_CTRL_GET_WMT_CONF, &addr, 0); -+ if (iRet) { -+ WMT_ERR_FUNC("ctrl GET_WMT_CONF fail(%d)\n", iRet); -+ return -2; -+ } -+ WMT_INFO_FUNC("ctrl GET_WMT_CONF ok(0x%08lx)\n", addr); -+ -+ pWmtGenConf = (P_WMT_GEN_CONF) addr; -+ -+ /*Check if WMT.cfg exists */ -+ if (pWmtGenConf->cfgExist == 0) { -+ WMT_INFO_FUNC("cfgExist == 0, skip config chip\n"); -+ /*if WMT.cfg not existed, still return success and adopt the default value */ -+ return 0; -+ } -+ -+ /*Dump the coex-related info */ -+ WMT_DBG_FUNC("coex_wmt:0x%x\n", pWmtGenConf->coex_wmt_ant_mode); -+#if CFG_SUBSYS_COEX_NEED -+ WMT_DBG_FUNC("coex_bt:0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n", -+ pWmtGenConf->coex_bt_rssi_upper_limit, -+ pWmtGenConf->coex_bt_rssi_mid_limit, -+ pWmtGenConf->coex_bt_rssi_lower_limit, -+ pWmtGenConf->coex_bt_pwr_high, pWmtGenConf->coex_bt_pwr_mid, pWmtGenConf->coex_bt_pwr_low); -+ WMT_DBG_FUNC("coex_wifi:0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n", -+ pWmtGenConf->coex_wifi_rssi_upper_limit, -+ pWmtGenConf->coex_wifi_rssi_mid_limit, -+ pWmtGenConf->coex_wifi_rssi_lower_limit, -+ pWmtGenConf->coex_wifi_pwr_high, pWmtGenConf->coex_wifi_pwr_mid, pWmtGenConf->coex_wifi_pwr_low); -+ WMT_DBG_FUNC("coex_ext_pta:0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n", -+ pWmtGenConf->coex_ext_pta_hi_tx_tag, -+ pWmtGenConf->coex_ext_pta_hi_rx_tag, -+ pWmtGenConf->coex_ext_pta_lo_tx_tag, -+ pWmtGenConf->coex_ext_pta_lo_rx_tag, -+ pWmtGenConf->coex_ext_pta_sample_t1, -+ pWmtGenConf->coex_ext_pta_sample_t2, pWmtGenConf->coex_ext_pta_wifi_bt_con_trx); -+ WMT_DBG_FUNC("coex_misc:0x%x 0x%x 0x%x\n", -+ pWmtGenConf->coex_misc_ext_pta_on, pWmtGenConf->coex_misc_ext_feature_set); -+#endif -+ -+ /*command adjustion due to WMT.cfg */ -+ coex_table[COEX_WMT].cmd[5] = pWmtGenConf->coex_wmt_ant_mode; -+ if (gWmtDbgLvl >= WMT_LOG_DBG) -+ wmt_core_dump_data(&coex_table[COEX_WMT].cmd[0], coex_table[COEX_WMT].str, coex_table[COEX_WMT].cmdSz); -+ -+#if CFG_SUBSYS_COEX_NEED -+ coex_table[COEX_BT].cmd[9] = pWmtGenConf->coex_bt_rssi_upper_limit; -+ coex_table[COEX_BT].cmd[10] = pWmtGenConf->coex_bt_rssi_mid_limit; -+ coex_table[COEX_BT].cmd[11] = pWmtGenConf->coex_bt_rssi_lower_limit; -+ coex_table[COEX_BT].cmd[12] = pWmtGenConf->coex_bt_pwr_high; -+ coex_table[COEX_BT].cmd[13] = pWmtGenConf->coex_bt_pwr_mid; -+ coex_table[COEX_BT].cmd[14] = pWmtGenConf->coex_bt_pwr_low; -+ if (gWmtDbgLvl >= WMT_LOG_DBG) -+ wmt_core_dump_data(&coex_table[COEX_BT].cmd[0], coex_table[COEX_BT].str, coex_table[COEX_BT].cmdSz); -+ -+ coex_table[COEX_WIFI].cmd[10] = pWmtGenConf->coex_wifi_rssi_upper_limit; -+ coex_table[COEX_WIFI].cmd[11] = pWmtGenConf->coex_wifi_rssi_mid_limit; -+ coex_table[COEX_WIFI].cmd[12] = pWmtGenConf->coex_wifi_rssi_lower_limit; -+ coex_table[COEX_WIFI].cmd[13] = pWmtGenConf->coex_wifi_pwr_high; -+ coex_table[COEX_WIFI].cmd[14] = pWmtGenConf->coex_wifi_pwr_mid; -+ coex_table[COEX_WIFI].cmd[15] = pWmtGenConf->coex_wifi_pwr_low; -+ if (gWmtDbgLvl >= WMT_LOG_DBG) -+ wmt_core_dump_data(&coex_table[COEX_WIFI].cmd[0], -+ coex_table[COEX_WIFI].str, coex_table[COEX_WIFI].cmdSz); -+ -+ coex_table[COEX_PTA].cmd[5] = pWmtGenConf->coex_ext_pta_hi_tx_tag; -+ coex_table[COEX_PTA].cmd[6] = pWmtGenConf->coex_ext_pta_hi_rx_tag; -+ coex_table[COEX_PTA].cmd[7] = pWmtGenConf->coex_ext_pta_lo_tx_tag; -+ coex_table[COEX_PTA].cmd[8] = pWmtGenConf->coex_ext_pta_lo_rx_tag; -+ coex_table[COEX_PTA].cmd[9] = ((pWmtGenConf->coex_ext_pta_sample_t1 & 0xff00) >> 8); -+ coex_table[COEX_PTA].cmd[10] = ((pWmtGenConf->coex_ext_pta_sample_t1 & 0x00ff) >> 0); -+ coex_table[COEX_PTA].cmd[11] = ((pWmtGenConf->coex_ext_pta_sample_t2 & 0xff00) >> 8); -+ coex_table[COEX_PTA].cmd[12] = ((pWmtGenConf->coex_ext_pta_sample_t2 & 0x00ff) >> 0); -+ coex_table[COEX_PTA].cmd[13] = pWmtGenConf->coex_ext_pta_wifi_bt_con_trx; -+ if (gWmtDbgLvl >= WMT_LOG_DBG) -+ wmt_core_dump_data(&coex_table[COEX_PTA].cmd[0], coex_table[COEX_PTA].str, coex_table[COEX_PTA].cmdSz); -+ -+ osal_memcpy(&coex_table[COEX_MISC].cmd[5], &pWmtGenConf->coex_misc_ext_pta_on, -+ sizeof(pWmtGenConf->coex_misc_ext_pta_on)); -+ osal_memcpy(&coex_table[COEX_MISC].cmd[9], &pWmtGenConf->coex_misc_ext_feature_set, -+ sizeof(pWmtGenConf->coex_misc_ext_feature_set)); -+ -+ wmt_core_dump_data(&coex_table[COEX_MISC].cmd[0], coex_table[COEX_MISC].str, coex_table[COEX_MISC].cmdSz); -+#endif -+ -+ iRet = wmt_core_init_script(coex_table, sizeof(coex_table) / sizeof(coex_table[0])); -+ -+ return iRet; -+} -+ -+#if CFG_WMT_SDIO_DRIVING_SET -+static INT32 mtk_wcn_soc_set_sdio_driving(void) -+{ -+ INT32 ret = 0; -+ -+ unsigned long addr; -+ WMT_GEN_CONF *pWmtGenConf; -+ UINT32 drv_val = 0; -+ -+ /*Get wmt config */ -+ ret = wmt_core_ctrl(WMT_CTRL_GET_WMT_CONF, &addr, 0); -+ if (ret) { -+ WMT_ERR_FUNC("ctrl GET_WMT_CONF fail(%d)\n", ret); -+ return -1; -+ } -+ WMT_INFO_FUNC("ctrl GET_WMT_CONF ok(0x%08lx)\n", addr); -+ -+ pWmtGenConf = (P_WMT_GEN_CONF) addr; -+ -+ /*Check if WMT.cfg exists */ -+ if (pWmtGenConf->cfgExist == 0) { -+ WMT_INFO_FUNC("cfgExist == 0, skip config chip\n"); -+ /*if WMT.cfg not existed, still return success and adopt the default value */ -+ return 0; -+ } -+ -+ drv_val = pWmtGenConf->sdio_driving_cfg; -+ -+ /*Dump the sdio driving related info */ -+ WMT_INFO_FUNC("sdio driving:0x%x\n", drv_val); -+ -+ sdio_driving_table[0].cmd[12] = (UINT8) ((drv_val & 0x00000077UL) >> 0); /* DAT0 and DAT1 */ -+ sdio_driving_table[0].cmd[13] = (UINT8) ((drv_val & 0x00007700UL) >> 8); /* DAT2 and DAT3 */ -+ sdio_driving_table[0].cmd[14] = (UINT8) ((drv_val & 0x00070000UL) >> 16); /* CMD */ -+ -+ ret = wmt_core_init_script(sdio_driving_table, sizeof(sdio_driving_table) / sizeof(sdio_driving_table[0])); -+ -+ return ret; -+} -+#endif -+ -+#if CFG_WMT_CRYSTAL_TIMING_SET -+static INT32 mtk_wcn_soc_crystal_triming_set(VOID) -+{ -+ INT32 iRet = 0; -+ PUINT8 pbuf = NULL; -+ UINT32 bufLen = 0; -+ WMT_CTRL_DATA ctrlData; -+ UINT32 uCryTimOffset = 0x6D; -+ MTK_WCN_BOOL bIsNvramExist = MTK_WCN_BOOL_FALSE; -+ INT8 cCrystalTimingOffset = 0x0; -+ UINT8 cCrystalTiming = 0x0; -+ INT32 iCrystalTiming = 0x0; -+ MTK_WCN_BOOL bIsCrysTrimEnabled = MTK_WCN_BOOL_FALSE; -+ UINT32 u4Res; -+ -+ bIsNvramExist = MTK_WCN_BOOL_FALSE; -+ /**/ ctrlData.ctrlId = WMT_CTRL_CRYSTAL_TRIMING_GET; -+ ctrlData.au4CtrlData[0] = (UINT32) "/data/nvram/APCFG/APRDEB/WIFI"; -+ ctrlData.au4CtrlData[1] = (UINT32) &pbuf; -+ ctrlData.au4CtrlData[2] = (UINT32) &bufLen; -+ -+ iRet = wmt_ctrl(&ctrlData); -+ if (0 != iRet) { -+ WMT_ERR_FUNC("0x%x: WMT_CTRL_CRYSTAL_TRIMING_GET fail:%d\n", wmt_ic_ops_soc.icId, iRet); -+ bIsNvramExist = MTK_WCN_BOOL_FALSE; -+ bIsCrysTrimEnabled = MTK_WCN_BOOL_FALSE; -+ cCrystalTimingOffset = 0x0; -+ cCrystalTiming = 0x0; -+ iRet = -1; -+ } else { -+ WMT_DBG_FUNC("0x%x: nvram pBuf(0x%08x), bufLen(%d)\n", wmt_ic_ops_soc.icId, pbuf, bufLen); -+ if (bufLen < (uCryTimOffset + 1)) { -+ WMT_ERR_FUNC("0x%x: nvram len(%d) too short, crystalTimging value offset(%d)\n", -+ wmt_ic_ops_soc.icId, bufLen, uCryTimOffset); -+ bIsNvramExist = MTK_WCN_BOOL_FALSE; -+ bIsCrysTrimEnabled = MTK_WCN_BOOL_FALSE; -+ cCrystalTimingOffset = 0x0; -+ cCrystalTiming = 0x0; -+ } else { -+ bIsNvramExist = MTK_WCN_BOOL_TRUE; -+ cCrystalTimingOffset = *(pbuf + uCryTimOffset); -+ if (cCrystalTimingOffset & 0x80) { -+ bIsCrysTrimEnabled = MTK_WCN_BOOL_TRUE; -+ cCrystalTimingOffset = (UINT8) cCrystalTimingOffset & 0x7f; -+ } -+ WMT_DBG_FUNC("cCrystalTimingOffset (%d), bIsCrysTrimEnabled(%d)\n", cCrystalTimingOffset, -+ bIsCrysTrimEnabled); -+ } -+ ctrlData.ctrlId = WMT_CTRL_CRYSTAL_TRIMING_PUT; -+ ctrlData.au4CtrlData[0] = (UINT32) "/data/nvram/APCFG/APRDEB/WIFI"; -+ iRet = wmt_ctrl(&ctrlData); -+ if (0 != iRet) { -+ WMT_ERR_FUNC("0x%x: WMT_CTRL_CRYSTAL_TRIMING_PUT fail:%d\n", wmt_ic_ops_soc.icId, iRet); -+ iRet = -2; -+ } else { -+ WMT_DBG_FUNC("0x%x: WMT_CTRL_CRYSTAL_TRIMING_PUT succeed\n", wmt_ic_ops_soc.icId); -+ } -+ } -+ if ((MTK_WCN_BOOL_TRUE == bIsNvramExist) && (MTK_WCN_BOOL_TRUE == bIsCrysTrimEnabled)) { -+ /*get CrystalTiming value before set it */ -+ iRet = -+ wmt_core_tx(get_crystal_timing_script[0].cmd, get_crystal_timing_script[0].cmdSz, &u4Res, -+ MTK_WCN_BOOL_FALSE); -+ if (iRet || (u4Res != get_crystal_timing_script[0].cmdSz)) { -+ WMT_ERR_FUNC("WMT-CORE: write (%s) iRet(%d) cmd len err(%d, %d)\n", -+ get_crystal_timing_script[0].str, iRet, u4Res, get_crystal_timing_script[0].cmdSz); -+ iRet = -3; -+ goto done; -+ } -+ /* EVENT BUF */ -+ osal_memset(get_crystal_timing_script[0].evt, 0, get_crystal_timing_script[0].evtSz); -+ iRet = wmt_core_rx(get_crystal_timing_script[0].evt, get_crystal_timing_script[0].evtSz, &u4Res); -+ if (iRet || (u4Res != get_crystal_timing_script[0].evtSz)) { -+ WMT_ERR_FUNC("WMT-CORE: read (%s) iRet(%d) evt len err(rx:%d, exp:%d)\n", -+ get_crystal_timing_script[0].str, iRet, u4Res, get_crystal_timing_script[0].evtSz); -+ mtk_wcn_stp_dbg_dump_package(); -+ iRet = -4; -+ goto done; -+ } -+ -+ iCrystalTiming = WMT_GET_CRYSTAL_TRIMING_EVT[5] & 0x7f; -+ if (cCrystalTimingOffset & 0x40) { -+ /*nagative offset value */ -+ iCrystalTiming = iCrystalTiming + cCrystalTimingOffset - 128; -+ } else { -+ iCrystalTiming += cCrystalTimingOffset; -+ } -+ WMT_DBG_FUNC("iCrystalTiming (0x%x)\n", iCrystalTiming); -+ cCrystalTiming = iCrystalTiming > 0x7f ? 0x7f : iCrystalTiming; -+ cCrystalTiming = iCrystalTiming < 0 ? 0 : iCrystalTiming; -+ WMT_DBG_FUNC("cCrystalTiming (0x%x)\n", cCrystalTiming); -+ /* set_crystal_timing_script */ -+ WMT_SET_CRYSTAL_TRIMING_CMD[5] = cCrystalTiming; -+ WMT_GET_CRYSTAL_TRIMING_EVT[5] = cCrystalTiming; -+ -+ iRet = wmt_core_init_script(set_crystal_timing_script, osal_array_size(set_crystal_timing_script)); -+ if (iRet) { -+ WMT_ERR_FUNC("set_crystal_timing_script fail(%d)\n", iRet); -+ iRet = -5; -+ } else { -+ WMT_DBG_FUNC("set crystal timing value (0x%x) succeed\n", WMT_SET_CRYSTAL_TRIMING_CMD[5]); -+ iRet = -+ wmt_core_init_script(get_crystal_timing_script, osal_array_size(get_crystal_timing_script)); -+ if (iRet) { -+ WMT_ERR_FUNC("get_crystal_timing_script fail(%d)\n", iRet); -+ iRet = -6; -+ } else { -+ WMT_INFO_FUNC("succeed, updated crystal timing value (0x%x)\n", -+ WMT_GET_CRYSTAL_TRIMING_EVT[5]); -+ iRet = 0x0; -+ } -+ } -+ } -+done: -+ return iRet; -+} -+#endif -+ -+#if CFG_WMT_MULTI_PATCH -+static INT32 mtk_wcn_soc_patch_info_prepare(VOID) -+{ -+ INT32 iRet = -1; -+ WMT_CTRL_DATA ctrlData; -+ -+ ctrlData.ctrlId = WMT_CTRL_PATCH_SEARCH; -+ iRet = wmt_ctrl(&ctrlData); -+ -+ return iRet; -+} -+ -+static INT32 mtk_wcn_soc_patch_dwn(UINT32 index) -+{ -+ INT32 iRet = -1; -+ P_WMT_PATCH patchHdr; -+ PUINT8 pbuf; -+ UINT32 patchSize; -+ UINT32 fragSeq; -+ UINT32 fragNum; -+ UINT16 fragSize = 0; -+ UINT16 cmdLen; -+ UINT32 offset; -+ UINT32 u4Res; -+ UINT8 evtBuf[8]; -+ UINT8 addressevtBuf[12]; -+ UINT8 addressByte[4]; -+ PINT8 cDataTime = NULL; -+ /*PINT8 cPlat = NULL; */ -+ UINT16 u2HwVer = 0; -+ UINT16 u2SwVer = 0; -+ UINT32 u4PatchVer = 0; -+ UINT32 patchSizePerFrag = 0; -+ WMT_CTRL_DATA ctrlData; -+ -+ /*1.check hardware information */ -+ if (NULL == gp_soc_info) { -+ WMT_ERR_FUNC("null gp_soc_info!\n"); -+ return -1; -+ } -+ -+ osal_memset(gFullPatchName, 0, osal_sizeof(gFullPatchName)); -+ -+ ctrlData.ctrlId = WMT_CTRL_GET_PATCH_INFO; -+ ctrlData.au4CtrlData[0] = index + 1; -+ ctrlData.au4CtrlData[1] = (SIZE_T) &gFullPatchName; -+ ctrlData.au4CtrlData[2] = (SIZE_T) &addressByte; -+ iRet = wmt_ctrl(&ctrlData); -+ WMT_DBG_FUNC("the %d time valid patch found: (%s)\n", index + 1, gFullPatchName); -+ -+ /* <2.2> read patch content */ -+ ctrlData.ctrlId = WMT_CTRL_GET_PATCH; -+ ctrlData.au4CtrlData[0] = (SIZE_T) NULL; -+ ctrlData.au4CtrlData[1] = (SIZE_T) &gFullPatchName; -+ ctrlData.au4CtrlData[2] = (SIZE_T) &pbuf; -+ ctrlData.au4CtrlData[3] = (SIZE_T) &patchSize; -+ iRet = wmt_ctrl(&ctrlData); -+ if (iRet) { -+ WMT_ERR_FUNC("wmt_core: WMT_CTRL_GET_PATCH fail:%d\n", iRet); -+ iRet -= 1; -+ goto done; -+ } -+ -+ /* |<-BCNT_PATCH_BUF_HEADROOM(8) bytes dummy allocated->|<-patch file->| */ -+ pbuf += BCNT_PATCH_BUF_HEADROOM; -+ /* patch file with header: -+ * |<-patch header: 28 Bytes->|<-patch body: X Bytes ----->| -+ */ -+ patchHdr = (P_WMT_PATCH) pbuf; -+ /* check patch file information */ -+ -+ cDataTime = patchHdr->ucDateTime; -+ u2HwVer = patchHdr->u2HwVer; -+ u2SwVer = patchHdr->u2SwVer; -+ u4PatchVer = patchHdr->u4PatchVer; -+ /*cPlat = &patchHdr->ucPLat[0]; */ -+ -+ cDataTime[15] = '\0'; -+ if (index == 0) { -+ WMT_DBG_FUNC("===========================================\n"); -+ WMT_INFO_FUNC("[Patch]BuiltTime = %s, HVer = 0x%x, SVer = 0x%x, PhVer = 0x%04x,Platform = %c%c%c%c\n", -+ cDataTime, ((u2HwVer & 0x00ff) << 8) | ((u2HwVer & 0xff00) >> 8), -+ ((u2SwVer & 0x00ff) << 8) | ((u2SwVer & 0xff00) >> 8), -+ ((u4PatchVer & 0xff000000) >> 24) | ((u4PatchVer & 0x00ff0000) >> 16), -+ patchHdr->ucPLat[0], patchHdr->ucPLat[1], patchHdr->ucPLat[2], patchHdr->ucPLat[3]); -+ WMT_DBG_FUNC("[Consys Patch] Hw Ver = 0x%x\n", ((u2HwVer & 0x00ff) << 8) | ((u2HwVer & 0xff00) >> 8)); -+ WMT_DBG_FUNC("[Consys Patch] Sw Ver = 0x%x\n", ((u2SwVer & 0x00ff) << 8) | ((u2SwVer & 0xff00) >> 8)); -+ WMT_DBG_FUNC("[Consys Patch] Ph Ver = 0x%04x\n", -+ ((u4PatchVer & 0xff000000) >> 24) | ((u4PatchVer & 0x00ff0000) >> 16)); -+ WMT_DBG_FUNC("[Consys Patch] Platform = %c%c%c%c\n", patchHdr->ucPLat[0], patchHdr->ucPLat[1], -+ patchHdr->ucPLat[2], patchHdr->ucPLat[3]); -+ WMT_DBG_FUNC("===========================================\n"); -+ } -+ -+ /* remove patch header: -+ * |<-patch body: X Bytes (X=patchSize)--->| -+ */ -+ patchSize -= sizeof(WMT_PATCH); -+ pbuf += sizeof(WMT_PATCH); -+ patchSizePerFrag = DEFAULT_PATCH_FRAG_SIZE; -+ /* reserve 1st patch cmd space before patch body -+ * |<-WMT_CMD: 5Bytes->|<-patch body: X Bytes (X=patchSize)----->| -+ */ -+ /* gp_soc_patch_info = patchHdr; */ -+ osal_memcpy(&gp_soc_patch_info, patchHdr, osal_sizeof(WMT_PATCH)); -+ pbuf -= sizeof(WMT_PATCH_CMD); -+ -+ fragNum = patchSize / patchSizePerFrag; -+ fragNum += ((fragNum * patchSizePerFrag) == patchSize) ? 0 : 1; -+ -+ WMT_DBG_FUNC("patch size(%d) fragNum(%d)\n", patchSize, fragNum); -+ -+ /*send wmt part patch address command */ -+ if (0x6752 == wmt_ic_ops_soc.icId || -+ 0x8127 == wmt_ic_ops_soc.icId || -+ 0x7623 == wmt_ic_ops_soc.icId || -+ 0x6571 == wmt_ic_ops_soc.icId || -+ 0x0326 == wmt_ic_ops_soc.icId || -+ 0x0321 == wmt_ic_ops_soc.icId || -+ 0x0335 == wmt_ic_ops_soc.icId || -+ 0x0337 == wmt_ic_ops_soc.icId || 0x8163 == wmt_ic_ops_soc.icId || 0x6580 == wmt_ic_ops_soc.icId) { -+ /* MT6571 patch RAM base */ -+ WMT_PATCH_ADDRESS_CMD[8] = 0x40; -+ WMT_PATCH_P_ADDRESS_CMD[8] = 0xc8; -+ } -+ /*send wmt part patch address command */ -+ if (0x0279 == wmt_ic_ops_soc.icId) { -+ /* MT6797 patch RAM base */ -+ WMT_PATCH_ADDRESS_CMD[8] = 0x08; -+ WMT_PATCH_ADDRESS_CMD[9] = 0x05; -+ WMT_PATCH_P_ADDRESS_CMD[8] = 0x2c; -+ WMT_PATCH_P_ADDRESS_CMD[9] = 0x0b; -+ } -+ -+ /*send wmt part patch address command */ -+ iRet = -+ wmt_core_tx((PUINT8) &WMT_PATCH_ADDRESS_CMD[0], sizeof(WMT_PATCH_ADDRESS_CMD), &u4Res, MTK_WCN_BOOL_FALSE); -+ if (iRet || (u4Res != sizeof(WMT_PATCH_ADDRESS_CMD))) { -+ WMT_ERR_FUNC("wmt_core:wmt patch address CMD fail(%d),size(%d)\n", iRet, u4Res); -+ iRet -= 1; -+ goto done; -+ } -+ osal_memset(addressevtBuf, 0, sizeof(addressevtBuf)); -+ iRet = wmt_core_rx(addressevtBuf, sizeof(WMT_PATCH_ADDRESS_EVT), &u4Res); -+ if (iRet || (u4Res != sizeof(WMT_PATCH_ADDRESS_EVT))) { -+ WMT_ERR_FUNC("wmt_core:wmt patch address EVT fail(%d),size(%d)\n", iRet, u4Res); -+ iRet -= 1; -+ goto done; -+ } -+#if CFG_CHECK_WMT_RESULT -+ if (osal_memcmp(addressevtBuf, WMT_PATCH_ADDRESS_EVT, osal_sizeof(WMT_PATCH_ADDRESS_EVT)) != 0) { -+ WMT_ERR_FUNC("wmt_core: write WMT_PATCH_ADDRESS_CMD status fail\n"); -+ iRet -= 1; -+ goto done; -+ } -+#endif -+ -+ /*send part patch address command */ -+ osal_memcpy(&WMT_PATCH_P_ADDRESS_CMD[12], addressByte, osal_sizeof(addressByte)); -+ WMT_DBG_FUNC("4 bytes address command:0x%02x,0x%02x,0x%02x,0x%02x", -+ WMT_PATCH_P_ADDRESS_CMD[12], -+ WMT_PATCH_P_ADDRESS_CMD[13], WMT_PATCH_P_ADDRESS_CMD[14], WMT_PATCH_P_ADDRESS_CMD[15]); -+ iRet = -+ wmt_core_tx((PUINT8) &WMT_PATCH_P_ADDRESS_CMD[0], sizeof(WMT_PATCH_P_ADDRESS_CMD), &u4Res, -+ MTK_WCN_BOOL_FALSE); -+ if (iRet || (u4Res != sizeof(WMT_PATCH_P_ADDRESS_CMD))) { -+ WMT_ERR_FUNC("wmt_core:wmt part patch address CMD fail(%d),size(%d),index(%d)\n", iRet, u4Res, index); -+ iRet -= 1; -+ goto done; -+ } -+ osal_memset(addressevtBuf, 0, sizeof(addressevtBuf)); -+ iRet = wmt_core_rx(addressevtBuf, sizeof(WMT_PATCH_P_ADDRESS_EVT), &u4Res); -+ if (iRet || (u4Res != sizeof(WMT_PATCH_P_ADDRESS_EVT))) { -+ WMT_ERR_FUNC("wmt_core:wmt patch address EVT fail(%d),size(%d),index(%d)\n", iRet, u4Res, index); -+ iRet -= 1; -+ goto done; -+ } -+#if CFG_CHECK_WMT_RESULT -+ if (osal_memcmp(addressevtBuf, WMT_PATCH_P_ADDRESS_EVT, osal_sizeof(WMT_PATCH_ADDRESS_EVT)) != 0) { -+ WMT_ERR_FUNC("wmt_core: write WMT_PATCH_ADDRESS_CMD status fail,index(%d)\n", index); -+ iRet -= 1; -+ goto done; -+ } -+#endif -+ -+ /* send all fragments */ -+ offset = sizeof(WMT_PATCH_CMD); -+ fragSeq = 0; -+ while (fragSeq < fragNum) { -+ WMT_DBG_FUNC("patch size(%d) fragNum(%d)\n", patchSize, fragNum); -+ if (fragSeq == (fragNum - 1)) { -+ /* last fragment */ -+ fragSize = patchSize - fragSeq * patchSizePerFrag; -+ WMT_PATCH_CMD[4] = WMT_PATCH_FRAG_LAST; -+ } else { -+ fragSize = patchSizePerFrag; -+ WMT_PATCH_CMD[4] = (fragSeq == 0) ? WMT_PATCH_FRAG_1ST : WMT_PATCH_FRAG_MID; -+ } -+ /* update length field in CMD:flag+frag */ -+ cmdLen = 1 + fragSize; -+ osal_memcpy(&WMT_PATCH_CMD[2], &cmdLen, 2); -+ /* copy patch CMD to buf (overwrite last 5-byte in prev frag) */ -+ osal_memcpy(pbuf + offset - sizeof(WMT_PATCH_CMD), WMT_PATCH_CMD, sizeof(WMT_PATCH_CMD)); -+ -+ /* iRet = -+ *(*kal_stp_tx)(pbuf + offset - sizeof(WMT_PATCH_CMD), fragSize + sizeof(WMT_PATCH_CMD), -+ *&u4Res); -+ */ -+ iRet = -+ wmt_core_tx(pbuf + offset - sizeof(WMT_PATCH_CMD), fragSize + sizeof(WMT_PATCH_CMD), -+ &u4Res, MTK_WCN_BOOL_FALSE); -+ if (iRet || (u4Res != fragSize + sizeof(WMT_PATCH_CMD))) { -+ WMT_ERR_FUNC("wmt_core: write fragSeq(%d) size(%d, %d) fail(%d)\n", fragSeq, -+ fragSize + sizeof(WMT_PATCH_CMD), u4Res, iRet); -+ iRet -= 1; -+ break; -+ } -+ WMT_DBG_FUNC("wmt_core: write fragSeq(%d) size(%d, %d) ok\n", -+ fragSeq, fragSize + sizeof(WMT_PATCH_CMD), u4Res); -+ -+ osal_memset(evtBuf, 0, sizeof(evtBuf)); -+ /* iRet = (*kal_stp_rx)(evtBuf, sizeof(WMT_PATCH_EVT), &u4Res); */ -+ iRet = wmt_core_rx(evtBuf, sizeof(WMT_PATCH_EVT), &u4Res); -+ if (iRet || (u4Res != sizeof(WMT_PATCH_EVT))) { -+ WMT_ERR_FUNC("wmt_core: read WMT_PATCH_EVT length(%d, %d) fail(%d)\n", sizeof(WMT_PATCH_EVT), -+ u4Res, iRet); -+ iRet -= 1; -+ break; -+ } -+#if CFG_CHECK_WMT_RESULT -+ if (osal_memcmp(evtBuf, WMT_PATCH_EVT, sizeof(WMT_PATCH_EVT)) != 0) { -+ WMT_ERR_FUNC("wmt_core: compare WMT_PATCH_EVT error rx(%d):[%02X,%02X,%02X,%02X,%02X]\n", -+ u4Res, -+ evtBuf[0], -+ evtBuf[1], -+ evtBuf[2], -+ evtBuf[3], -+ evtBuf[4]); -+ WMT_ERR_FUNC("wmt_core: exp(%d):[%02X,%02X,%02X,%02X,%02X]\n", -+ sizeof(WMT_PATCH_EVT), -+ WMT_PATCH_EVT[0], -+ WMT_PATCH_EVT[1], -+ WMT_PATCH_EVT[2], -+ WMT_PATCH_EVT[3], -+ WMT_PATCH_EVT[4]); -+ iRet -= 1; -+ break; -+ } -+#endif -+ WMT_DBG_FUNC("wmt_core: read WMT_PATCH_EVT length(%d, %d) ok\n", sizeof(WMT_PATCH_EVT), u4Res); -+ offset += patchSizePerFrag; -+ ++fragSeq; -+ } -+ -+ WMT_WARN_FUNC("wmt_core: patch dwn:%d frag(%d, %d) %s\n", -+ iRet, fragSeq, fragSize, (!iRet && (fragSeq == fragNum)) ? "ok" : "fail"); -+ -+ if (fragSeq != fragNum) -+ iRet -= 1; -+done: -+ /* WMT_CTRL_FREE_PATCH always return 0 */ -+ /* wmt_core_ctrl(WMT_CTRL_FREE_PATCH, NULL, NULL); */ -+ ctrlData.ctrlId = WMT_CTRL_FREE_PATCH; -+ ctrlData.au4CtrlData[0] = index + 1; -+ wmt_ctrl(&ctrlData); -+ -+ return iRet; -+} -+ -+#else -+static INT32 mtk_wcn_soc_patch_dwn(VOID) -+{ -+ INT32 iRet = -1; -+ P_WMT_PATCH patchHdr; -+ PUINT8 pbuf; -+ UINT32 patchSize; -+ UINT32 fragSeq; -+ UINT32 fragNum; -+ UINT16 fragSize = 0; -+ UINT16 cmdLen; -+ UINT32 offset; -+ UINT32 u4Res; -+ UINT8 evtBuf[8]; -+ PINT8 cDataTime = NULL; -+ /*PINT8 cPlat = NULL; */ -+ UINT16 u2HwVer = 0; -+ UINT16 u2SwVer = 0; -+ UINT32 u4PatchVer = 0; -+ UINT32 patchSizePerFrag = 0; -+ WMT_CTRL_DATA ctrlData; -+ -+ /*1.check hardware information */ -+ if (NULL == gp_soc_info) { -+ WMT_ERR_FUNC("null gp_soc_info!\n"); -+ return -1; -+ } -+ /* <2> search patch and read patch content */ -+ /* <2.1> search patch */ -+ ctrlData.ctrlId = WMT_CTRL_PATCH_SEARCH; -+ iRet = wmt_ctrl(&ctrlData); -+ if (0 == iRet) { -+ /* patch with correct Hw Ver Major Num found */ -+ ctrlData.ctrlId = WMT_CTRL_GET_PATCH_NAME; -+ ctrlData.au4CtrlData[0] = (UINT32) &gFullPatchName; -+ iRet = wmt_ctrl(&ctrlData); -+ -+ WMT_INFO_FUNC("valid patch found: (%s)\n", gFullPatchName); -+ /* <2.2> read patch content */ -+ ctrlData.ctrlId = WMT_CTRL_GET_PATCH; -+ ctrlData.au4CtrlData[0] = (UINT32) NULL; -+ ctrlData.au4CtrlData[1] = (UINT32) &gFullPatchName; -+ -+ } else { -+ iRet -= 1; -+ return iRet; -+ } -+ ctrlData.au4CtrlData[2] = (UINT32) &pbuf; -+ ctrlData.au4CtrlData[3] = (UINT32) &patchSize; -+ iRet = wmt_ctrl(&ctrlData); -+ if (iRet) { -+ WMT_ERR_FUNC("wmt_core: WMT_CTRL_GET_PATCH fail:%d\n", iRet); -+ iRet -= 1; -+ goto done; -+ } -+ -+ /* |<-BCNT_PATCH_BUF_HEADROOM(8) bytes dummy allocated->|<-patch file->| */ -+ pbuf += BCNT_PATCH_BUF_HEADROOM; -+ /* patch file with header: -+ * |<-patch header: 28 Bytes->|<-patch body: X Bytes ----->| -+ */ -+ patchHdr = (P_WMT_PATCH) pbuf; -+ /* check patch file information */ -+ -+ cDataTime = patchHdr->ucDateTime; -+ u2HwVer = patchHdr->u2HwVer; -+ u2SwVer = patchHdr->u2SwVer; -+ u4PatchVer = patchHdr->u4PatchVer; -+ /*cPlat = &patchHdr->ucPLat[0]; */ -+ -+ cDataTime[15] = '\0'; -+ WMT_DBG_FUNC("===========================================\n"); -+ WMT_INFO_FUNC("[ConsysPatch]BuiltTime = %s, HVer = 0x%x, SVer = 0x%x, PhVer = 0x%04x,Platform = %c%c%c%c\n", -+ cDataTime, ((u2HwVer & 0x00ff) << 8) | ((u2HwVer & 0xff00) >> 8), -+ ((u2SwVer & 0x00ff) << 8) | ((u2SwVer & 0xff00) >> 8), -+ ((u4PatchVer & 0xff000000) >> 24) | ((u4PatchVer & 0x00ff0000) >> 16), -+ patchHdr->ucPLat[0], patchHdr->ucPLat[1], patchHdr->ucPLat[2], patchHdr->ucPLat[3]); -+ WMT_DBG_FUNC("[Consys Patch] Hw Ver = 0x%x\n", ((u2HwVer & 0x00ff) << 8) | ((u2HwVer & 0xff00) >> 8)); -+ WMT_DBG_FUNC("[Consys Patch] Sw Ver = 0x%x\n", ((u2SwVer & 0x00ff) << 8) | ((u2SwVer & 0xff00) >> 8)); -+ WMT_DBG_FUNC("[Consys Patch] Ph Ver = 0x%04x\n", -+ ((u4PatchVer & 0xff000000) >> 24) | ((u4PatchVer & 0x00ff0000) >> 16)); -+ WMT_DBG_FUNC("[Consys Patch] Platform = %c%c%c%c\n", patchHdr->ucPLat[0], patchHdr->ucPLat[1], -+ patchHdr->ucPLat[2], patchHdr->ucPLat[3]); -+ WMT_DBG_FUNC("===========================================\n"); -+ -+ /* remove patch header: -+ * |<-patch body: X Bytes (X=patchSize)--->| -+ */ -+ patchSize -= sizeof(WMT_PATCH); -+ pbuf += sizeof(WMT_PATCH); -+ patchSizePerFrag = DEFAULT_PATCH_FRAG_SIZE; -+ /* reserve 1st patch cmd space before patch body -+ * |<-WMT_CMD: 5Bytes->|<-patch body: X Bytes (X=patchSize)----->| -+ */ -+ pbuf -= sizeof(WMT_PATCH_CMD); -+ -+ fragNum = patchSize / patchSizePerFrag; -+ fragNum += ((fragNum * patchSizePerFrag) == patchSize) ? 0 : 1; -+ -+ WMT_DBG_FUNC("patch size(%d) fragNum(%d)\n", patchSize, fragNum); -+ -+ /* send all fragments */ -+ offset = sizeof(WMT_PATCH_CMD); -+ fragSeq = 0; -+ while (fragSeq < fragNum) { -+ WMT_DBG_FUNC("patch size(%d) fragNum(%d)\n", patchSize, fragNum); -+ if (fragSeq == (fragNum - 1)) { -+ /* last fragment */ -+ fragSize = patchSize - fragSeq * patchSizePerFrag; -+ WMT_PATCH_CMD[4] = WMT_PATCH_FRAG_LAST; -+ } else { -+ fragSize = patchSizePerFrag; -+ WMT_PATCH_CMD[4] = (fragSeq == 0) ? WMT_PATCH_FRAG_1ST : WMT_PATCH_FRAG_MID; -+ } -+ /* update length field in CMD:flag+frag */ -+ cmdLen = 1 + fragSize; -+ osal_memcpy(&WMT_PATCH_CMD[2], &cmdLen, 2); -+ /* copy patch CMD to buf (overwrite last 5-byte in prev frag) */ -+ osal_memcpy(pbuf + offset - sizeof(WMT_PATCH_CMD), WMT_PATCH_CMD, sizeof(WMT_PATCH_CMD)); -+ -+ /* iRet = -+ * (*kal_stp_tx)(pbuf + offset - sizeof(WMT_PATCH_CMD), fragSize + sizeof(WMT_PATCH_CMD), -+ * &u4Res); -+ */ -+ iRet = -+ wmt_core_tx(pbuf + offset - sizeof(WMT_PATCH_CMD), fragSize + sizeof(WMT_PATCH_CMD), &u4Res, -+ MTK_WCN_BOOL_FALSE); -+ if (iRet || (u4Res != fragSize + sizeof(WMT_PATCH_CMD))) { -+ WMT_ERR_FUNC("wmt_core: write fragSeq(%d) size(%d, %d) fail(%d)\n", fragSeq, -+ fragSize + sizeof(WMT_PATCH_CMD), u4Res, iRet); -+ iRet -= 1; -+ break; -+ } -+ WMT_DBG_FUNC("wmt_core: write fragSeq(%d) size(%d, %d) ok\n", -+ fragSeq, fragSize + sizeof(WMT_PATCH_CMD), u4Res); -+ -+ osal_memset(evtBuf, 0, sizeof(evtBuf)); -+ /* iRet = (*kal_stp_rx)(evtBuf, sizeof(WMT_PATCH_EVT), &u4Res); */ -+ iRet = wmt_core_rx(evtBuf, sizeof(WMT_PATCH_EVT), &u4Res); -+ if (iRet || (u4Res != sizeof(WMT_PATCH_EVT))) { -+ WMT_ERR_FUNC("wmt_core: read WMT_PATCH_EVT length(%d, %d) fail(%d)\n", sizeof(WMT_PATCH_EVT), -+ u4Res, iRet); -+ iRet -= 1; -+ break; -+ } -+#if CFG_CHECK_WMT_RESULT -+ if (osal_memcmp(evtBuf, WMT_PATCH_EVT, sizeof(WMT_PATCH_EVT)) != 0) { -+ WMT_ERR_FUNC("wmt_core: compare WMT_PATCH_EVT error rx(%d):[%02X,%02X,%02X,%02X,%02X]\n", -+ u4Res, -+ evtBuf[0], -+ evtBuf[1], -+ evtBuf[2], -+ evtBuf[3], -+ evtBuf[4]); -+ WMT_ERR_FUNC("wmt_core: exp(%d):[%02X,%02X,%02X,%02X,%02X]\n", -+ sizeof(WMT_PATCH_EVT), -+ WMT_PATCH_EVT[0], -+ WMT_PATCH_EVT[1], -+ WMT_PATCH_EVT[2], -+ WMT_PATCH_EVT[3], -+ WMT_PATCH_EVT[4]); -+ iRet -= 1; -+ break; -+ } -+#endif -+ WMT_DBG_FUNC("wmt_core: read WMT_PATCH_EVT length(%d, %d) ok\n", sizeof(WMT_PATCH_EVT), u4Res); -+ offset += patchSizePerFrag; -+ ++fragSeq; -+ } -+ -+ WMT_WARN_FUNC("wmt_core: patch dwn:%d frag(%d, %d) %s\n", -+ iRet, fragSeq, fragSize, (!iRet && (fragSeq == fragNum)) ? "ok" : "fail"); -+ -+ if (fragSeq != fragNum) -+ iRet -= 1; -+done: -+ /* WMT_CTRL_FREE_PATCH always return 0 */ -+ wmt_core_ctrl(WMT_CTRL_FREE_PATCH, NULL, NULL); -+ -+ return iRet; -+} -+ -+#endif -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_lib.c b/drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_lib.c -new file mode 100644 -index 000000000000..747ed64af2d2 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_lib.c -@@ -0,0 +1,1938 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -+/*! \file -+ \brief Declaration of library functions -+ -+ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+#ifdef DFT_TAG -+#undef DFT_TAG -+#endif -+#define DFT_TAG "[WMT-LIB]" -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "osal_typedef.h" -+ -+#include "wmt_dev.h" -+#include "wmt_lib.h" -+#include "wmt_conf.h" -+#include "wmt_core.h" -+#include "wmt_plat.h" -+ -+#include "stp_core.h" -+#include "btm_core.h" -+#include "psm_core.h" -+#include "stp_dbg.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/* A table for translation: CMB_STUB_AIF_X=>WMT_IC_PIN_STATE */ -+static const WMT_IC_PIN_STATE cmb_aif2pin_stat[] = { -+ [CMB_STUB_AIF_0] = WMT_IC_AIF_0, -+ [CMB_STUB_AIF_1] = WMT_IC_AIF_1, -+ [CMB_STUB_AIF_2] = WMT_IC_AIF_2, -+ [CMB_STUB_AIF_3] = WMT_IC_AIF_3, -+}; -+ -+#if CFG_WMT_PS_SUPPORT -+static UINT32 gPsIdleTime = STP_PSM_IDLE_TIME_SLEEP; -+static UINT32 gPsEnable = 1; -+static PF_WMT_SDIO_PSOP sdio_own_ctrl; -+#endif -+ -+#define WMT_STP_CPUPCR_BUF_SIZE 6144 -+static UINT8 g_cpupcr_buf[WMT_STP_CPUPCR_BUF_SIZE] = { 0 }; -+ -+static UINT32 g_quick_sleep_ctrl = 1; -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+DEV_WMT gDevWmt; -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+#if CFG_WMT_PS_SUPPORT -+static MTK_WCN_BOOL wmt_lib_ps_action(MTKSTP_PSM_ACTION_T action); -+static MTK_WCN_BOOL wmt_lib_ps_do_sleep(VOID); -+static MTK_WCN_BOOL wmt_lib_ps_do_wakeup(VOID); -+static MTK_WCN_BOOL wmt_lib_ps_do_host_awake(VOID); -+static INT32 wmt_lib_ps_handler(MTKSTP_PSM_ACTION_T action); -+#endif -+ -+static MTK_WCN_BOOL wmt_lib_put_op(P_OSAL_OP_Q pOpQ, P_OSAL_OP pLxOp); -+ -+static P_OSAL_OP wmt_lib_get_op(P_OSAL_OP_Q pOpQ); -+ -+static INT32 wmtd_thread(PVOID pvData); -+ -+static INT32 wmt_lib_pin_ctrl(WMT_IC_PIN_ID id, WMT_IC_PIN_STATE stat, UINT32 flag); -+static MTK_WCN_BOOL wmt_lib_hw_state_show(VOID); -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+INT32 wmt_lib_idc_lock_aquire(VOID) -+{ -+ return osal_lock_sleepable_lock(&gDevWmt.idc_lock); -+} -+ -+VOID wmt_lib_idc_lock_release(VOID) -+{ -+ osal_unlock_sleepable_lock(&gDevWmt.idc_lock); -+} -+INT32 wmt_lib_psm_lock_aquire(void) -+{ -+ return osal_lock_sleepable_lock(&gDevWmt.psm_lock); -+} -+ -+void wmt_lib_psm_lock_release(void) -+{ -+ osal_unlock_sleepable_lock(&gDevWmt.psm_lock); -+} -+ -+INT32 DISABLE_PSM_MONITOR(void) -+{ -+ INT32 ret = 0; -+ -+ /* osal_lock_sleepable_lock(&gDevWmt.psm_lock); */ -+ ret = wmt_lib_psm_lock_aquire(); -+ if (ret) { -+ WMT_ERR_FUNC("--->lock psm_lock failed, ret=%d\n", ret); -+ return ret; -+ } -+#if CFG_WMT_PS_SUPPORT -+ ret = wmt_lib_ps_disable(); -+ if (ret) { -+ WMT_ERR_FUNC("wmt_lib_ps_disable fail, ret=%d\n", ret); -+ wmt_lib_psm_lock_release(); -+ } -+#endif -+ -+ return ret; -+} -+ -+void ENABLE_PSM_MONITOR(void) -+{ -+#if CFG_WMT_PS_SUPPORT -+ wmt_lib_ps_enable(); -+#endif -+ /* osal_unlock_sleepable_lock(&gDevWmt.psm_lock); */ -+ wmt_lib_psm_lock_release(); -+} -+ -+INT32 wmt_lib_init(VOID) -+{ -+ INT32 iRet; -+ UINT32 i; -+ P_DEV_WMT pDevWmt; -+ P_OSAL_THREAD pThraed; -+ -+ /* create->init->start */ -+ /* 1. create: static allocation with zero initialization */ -+ pDevWmt = &gDevWmt; -+ osal_memset(&gDevWmt, 0, sizeof(gDevWmt)); -+ -+ iRet = wmt_conf_read_file(); -+ if (iRet) { -+ WMT_ERR_FUNC("read wmt config file fail(%d)\n", iRet); -+ return -1; -+ } -+ -+ pThraed = &gDevWmt.thread; -+ -+ /* Create mtk_wmtd thread */ -+ osal_strncpy(pThraed->threadName, "mtk_wmtd", sizeof(pThraed->threadName)); -+ pThraed->pThreadData = (VOID *) pDevWmt; -+ pThraed->pThreadFunc = (VOID *) wmtd_thread; -+ iRet = osal_thread_create(pThraed); -+ if (iRet) { -+ WMT_ERR_FUNC("osal_thread_create(0x%p) fail(%d)\n", pThraed, iRet); -+ return -2; -+ } -+ -+ /* 2. initialize */ -+ /* Initialize wmt_core */ -+ -+ iRet = wmt_core_init(); -+ if (iRet) { -+ WMT_ERR_FUNC("wmt_core_init() fail(%d)\n", iRet); -+ return -1; -+ } -+ -+ /* Initialize WMTd Thread Information: Thread */ -+ osal_event_init(&pDevWmt->rWmtdWq); -+ osal_sleepable_lock_init(&pDevWmt->psm_lock); -+ osal_sleepable_lock_init(&pDevWmt->idc_lock); -+ osal_sleepable_lock_init(&pDevWmt->rActiveOpQ.sLock); -+ osal_sleepable_lock_init(&pDevWmt->rFreeOpQ.sLock); -+ pDevWmt->state.data = 0; -+ -+ /* Initialize op queue */ -+ RB_INIT(&pDevWmt->rFreeOpQ, WMT_OP_BUF_SIZE); -+ RB_INIT(&pDevWmt->rActiveOpQ, WMT_OP_BUF_SIZE); -+ /* Put all to free Q */ -+ for (i = 0; i < WMT_OP_BUF_SIZE; i++) { -+ osal_signal_init(&(pDevWmt->arQue[i].signal)); -+ wmt_lib_put_op(&pDevWmt->rFreeOpQ, &(pDevWmt->arQue[i])); -+ } -+ -+ /* initialize stp resources */ -+ osal_event_init(&pDevWmt->rWmtRxWq); -+ -+ /*function driver callback */ -+ for (i = 0; i < WMTDRV_TYPE_WIFI; i++) -+ pDevWmt->rFdrvCb.fDrvRst[i] = NULL; -+ -+ pDevWmt->hw_ver = WMTHWVER_MAX; -+ WMT_INFO_FUNC("***********Init, hw->ver = %x\n", pDevWmt->hw_ver); -+ -+ /* TODO:[FixMe][GeorgeKuo]: wmt_lib_conf_init */ -+ /* initialize default configurations */ -+ /* i4Result = wmt_lib_conf_init(VOID); */ -+ /* WMT_WARN_FUNC("wmt_drv_conf_init(%d)\n", i4Result); */ -+ -+ osal_signal_init(&pDevWmt->cmdResp); -+ osal_event_init(&pDevWmt->cmdReq); -+ -+ /* initialize platform resources */ -+ if (0 != gDevWmt.rWmtGenConf.cfgExist) -+ iRet = wmt_plat_init(gDevWmt.rWmtGenConf.co_clock_flag & 0x0f); -+ else -+ iRet = wmt_plat_init(0); -+ -+ if (iRet) { -+ WMT_ERR_FUNC("wmt_plat_init() fail(%d)\n", iRet); -+ return -3; -+ } -+#if CFG_WMT_PS_SUPPORT -+ iRet = wmt_lib_ps_init(); -+ if (iRet) { -+ WMT_ERR_FUNC("wmt_lib_ps_init() fail(%d)\n", iRet); -+ return -4; -+ } -+#endif -+ -+ /* 3. start: start running mtk_wmtd */ -+ iRet = osal_thread_run(pThraed); -+ if (iRet) { -+ WMT_ERR_FUNC("osal_thread_run(0x%p) fail(%d)\n", pThraed, iRet); -+ return -5; -+ } -+ -+ /*4. register irq callback to WMT-PLAT */ -+ wmt_plat_irq_cb_reg(wmt_lib_ps_irq_cb); -+ -+ /*5. register audio if control callback to WMT-PLAT */ -+ wmt_plat_aif_cb_reg(wmt_lib_set_aif); -+ -+ /*6. register function control callback to WMT-PLAT */ -+ wmt_plat_func_ctrl_cb_reg(mtk_wcn_wmt_func_ctrl_for_plat); -+ -+ wmt_plat_deep_idle_ctrl_cb_reg(mtk_wcn_consys_stp_btif_dpidle_ctrl); -+ /*7 reset gps/bt state */ -+ -+ mtk_wcn_wmt_system_state_reset(); -+ -+#ifdef MTK_WCN_WMT_STP_EXP_SYMBOL_ABSTRACT -+ mtk_wcn_wmt_exp_init(); -+#endif -+ -+#if CFG_WMT_LTE_COEX_HANDLING -+ wmt_idc_init(); -+#endif -+ WMT_DBG_FUNC("init success\n"); -+ return 0; -+} -+ -+INT32 wmt_lib_deinit(VOID) -+{ -+ INT32 iRet; -+ P_DEV_WMT pDevWmt; -+ P_OSAL_THREAD pThraed; -+ INT32 i; -+ INT32 iResult; -+ -+ pDevWmt = &gDevWmt; -+ pThraed = &gDevWmt.thread; -+ iResult = 0; -+ -+ /* stop->deinit->destroy */ -+ -+ /* 1. stop: stop running mtk_wmtd */ -+ iRet = osal_thread_stop(pThraed); -+ if (iRet) { -+ WMT_ERR_FUNC("osal_thread_stop(0x%p) fail(%d)\n", pThraed, iRet); -+ iResult += 1; -+ } -+ -+ /* 2. deinit: */ -+ -+#if CFG_WMT_PS_SUPPORT -+ iRet = wmt_lib_ps_deinit(); -+ if (iRet) { -+ WMT_ERR_FUNC("wmt_lib_ps_deinit fail(%d)\n", iRet); -+ iResult += 2; -+ } -+#endif -+ -+ iRet = wmt_plat_deinit(); -+ if (iRet) { -+ WMT_ERR_FUNC("wmt_plat_deinit fail(%d)\n", iRet); -+ iResult += 4; -+ } -+ -+ osal_event_deinit(&pDevWmt->cmdReq); -+ osal_signal_deinit(&pDevWmt->cmdResp); -+ -+ /* de-initialize stp resources */ -+ osal_event_deinit(&pDevWmt->rWmtRxWq); -+ -+ for (i = 0; i < WMT_OP_BUF_SIZE; i++) -+ osal_signal_deinit(&(pDevWmt->arQue[i].signal)); -+ -+ -+ osal_sleepable_lock_deinit(&pDevWmt->rFreeOpQ.sLock); -+ osal_sleepable_lock_deinit(&pDevWmt->rActiveOpQ.sLock); -+ osal_sleepable_lock_deinit(&pDevWmt->idc_lock); -+ osal_sleepable_lock_deinit(&pDevWmt->psm_lock); -+ osal_event_deinit(&pDevWmt->rWmtdWq); -+ -+ iRet = wmt_core_deinit(); -+ if (iRet) { -+ WMT_ERR_FUNC("wmt_core_deinit fail(%d)\n", iRet); -+ iResult += 8; -+ } -+ -+ /* 3. destroy */ -+ iRet = osal_thread_destroy(pThraed); -+ if (iRet) { -+ WMT_ERR_FUNC("osal_thread_stop(0x%p) fail(%d)\n", pThraed, iRet); -+ iResult += 16; -+ } -+ osal_memset(&gDevWmt, 0, sizeof(gDevWmt)); -+ -+#ifdef MTK_WCN_WMT_STP_EXP_SYMBOL_ABSTRACT -+ mtk_wcn_wmt_exp_deinit(); -+#endif -+ -+#if CFG_WMT_LTE_COEX_HANDLING -+ wmt_idc_deinit(); -+#endif -+ -+ return iResult; -+} -+ -+VOID wmt_lib_flush_rx(VOID) -+{ -+ mtk_wcn_stp_flush_rx_queue(WMT_TASK_INDX); -+} -+ -+INT32 wmt_lib_trigger_cmd_signal(INT32 result) -+{ -+ P_OSAL_SIGNAL pSignal = &gDevWmt.cmdResp; -+ -+ gDevWmt.cmdResult = result; -+ osal_raise_signal(pSignal); -+ WMT_DBG_FUNC("wakeup cmdResp\n"); -+ return 0; -+} -+ -+P_OSAL_EVENT wmt_lib_get_cmd_event(VOID) -+{ -+ return &gDevWmt.cmdReq; -+} -+ -+INT32 wmt_lib_set_patch_name(PUINT8 cPatchName) -+{ -+ osal_strncpy(gDevWmt.cPatchName, cPatchName, NAME_MAX); -+ return 0; -+} -+ -+INT32 wmt_lib_set_hif(unsigned long hifconf) -+{ -+ UINT32 val; -+ P_WMT_HIF_CONF pHif = &gDevWmt.rWmtHifConf; -+ -+ val = hifconf & 0xF; -+ if (STP_UART_FULL == val) { -+ pHif->hifType = WMT_HIF_UART; -+ val = (hifconf >> 8); -+ pHif->au4HifConf[0] = val; -+ pHif->au4HifConf[1] = val; -+ mtk_wcn_stp_set_if_tx_type(STP_UART_IF_TX); -+ } else if (STP_SDIO == val) { -+ pHif->hifType = WMT_HIF_SDIO; -+ mtk_wcn_stp_set_if_tx_type(STP_SDIO_IF_TX); -+ } else if (STP_BTIF_FULL == val) { -+ pHif->hifType = WMT_HIF_BTIF; -+ mtk_wcn_stp_set_if_tx_type(STP_BTIF_IF_TX); -+ } else { -+ WMT_WARN_FUNC("invalid stp mode: %u\n", val); -+ mtk_wcn_stp_set_if_tx_type(STP_MAX_IF_TX); -+ return -1; -+ } -+ -+ val = (hifconf & 0xF0) >> 4; -+ if (WMT_FM_COMM == val) { -+ pHif->au4StrapConf[0] = WMT_FM_COMM; -+ } else if (WMT_FM_I2C == val) { -+ pHif->au4StrapConf[0] = WMT_FM_I2C; -+ } else { -+ WMT_WARN_FUNC("invalid fm mode: %u\n", val); -+ return -2; -+ } -+ -+ WMT_WARN_FUNC("new hifType: %d, fm:%d\n", pHif->hifType, pHif->au4StrapConf[0]); -+ return 0; -+} -+ -+P_WMT_HIF_CONF wmt_lib_get_hif(VOID) -+{ -+ return &gDevWmt.rWmtHifConf; -+} -+ -+PUINT8 wmt_lib_get_cmd(VOID) -+{ -+ if (osal_test_and_clear_bit(WMT_STAT_CMD, &gDevWmt.state)) -+ return gDevWmt.cCmd; -+ -+ return NULL; -+} -+ -+MTK_WCN_BOOL wmt_lib_get_cmd_status(VOID) -+{ -+ return osal_test_bit(WMT_STAT_CMD, &gDevWmt.state) ? MTK_WCN_BOOL_TRUE : MTK_WCN_BOOL_FALSE; -+} -+ -+#if CFG_WMT_PS_SUPPORT -+INT32 wmt_lib_ps_set_idle_time(UINT32 psIdleTime) -+{ -+ gPsIdleTime = psIdleTime; -+ return gPsIdleTime; -+} -+ -+INT32 wmt_lib_ps_ctrl(UINT32 state) -+{ -+ if (0 == state) { -+ wmt_lib_ps_disable(); -+ gPsEnable = 0; -+ } else { -+ gPsEnable = 1; -+ wmt_lib_ps_enable(); -+ } -+ return 0; -+} -+ -+INT32 wmt_lib_ps_enable(VOID) -+{ -+ if (gPsEnable) -+ mtk_wcn_stp_psm_enable(gPsIdleTime); -+ -+ return 0; -+} -+ -+INT32 wmt_lib_ps_disable(VOID) -+{ -+ if (gPsEnable) -+ return mtk_wcn_stp_psm_disable(); -+ -+ return 0; -+} -+ -+INT32 wmt_lib_ps_init(VOID) -+{ -+ /* mtk_wcn_stp_psm_register_wmt_cb(wmt_lib_ps_stp_cb); */ -+ return 0; -+} -+ -+INT32 wmt_lib_ps_deinit(VOID) -+{ -+ /* mtk_wcn_stp_psm_unregister_wmt_cb(); */ -+ return 0; -+} -+ -+static MTK_WCN_BOOL wmt_lib_ps_action(MTKSTP_PSM_ACTION_T action) -+{ -+ P_OSAL_OP lxop; -+ MTK_WCN_BOOL bRet; -+ UINT32 u4Wait; -+ P_OSAL_SIGNAL pSignal; -+ -+ lxop = wmt_lib_get_free_op(); -+ if (!lxop) { -+ WMT_WARN_FUNC("get_free_lxop fail\n"); -+ return MTK_WCN_BOOL_FALSE; -+ } -+ pSignal = &lxop->signal; -+ pSignal->timeoutValue = 0; -+ lxop->op.opId = WMT_OPID_PWR_SV; -+ lxop->op.au4OpData[0] = action; -+ lxop->op.au4OpData[1] = (SIZE_T) mtk_wcn_stp_psm_notify_stp; -+ u4Wait = 0; -+ bRet = wmt_lib_put_act_op(lxop); -+ return bRet; -+} -+ -+#if CFG_WMT_LTE_COEX_HANDLING -+MTK_WCN_BOOL wmt_lib_handle_idc_msg(ipc_ilm_t *idc_infor) -+{ -+ P_OSAL_OP lxop; -+ MTK_WCN_BOOL bRet = MTK_WCN_BOOL_FALSE; -+ P_OSAL_SIGNAL pSignal; -+ INT32 ret = 0; -+ UINT16 msg_len = 0; -+ static UINT8 msg_local_buffer[1300]; -+#if CFG_WMT_LTE_ENABLE_MSGID_MAPPING -+ MTK_WCN_BOOL unknown_msgid = MTK_WCN_BOOL_FALSE; -+#endif -+ WMT_DBG_FUNC("idc_infor from conn_md is 0x%p\n", idc_infor); -+ ret = wmt_lib_idc_lock_aquire(); -+ if (ret) { -+ WMT_ERR_FUNC("--->lock idc_lock failed, ret=%d\n", ret); -+ return MTK_WCN_BOOL_FALSE; -+ } -+ msg_len = idc_infor->local_para_ptr->msg_len - osal_sizeof(local_para_struct); -+ osal_memcpy(&msg_local_buffer[0], &msg_len, osal_sizeof(msg_len)); -+ osal_memcpy(&msg_local_buffer[osal_sizeof(msg_len)], -+ &(idc_infor->local_para_ptr->data[0]), msg_len - 1); -+ wmt_lib_idc_lock_release(); -+ lxop = wmt_lib_get_free_op(); -+ if (!lxop) { -+ WMT_WARN_FUNC("get_free_lxop fail\n"); -+ return MTK_WCN_BOOL_FALSE; -+ } -+ pSignal = &lxop->signal; -+ pSignal->timeoutValue = MAX_EACH_WMT_CMD; -+ lxop->op.opId = WMT_OPID_IDC_MSG_HANDLING; -+ lxop->op.au4OpData[0] = (size_t) msg_local_buffer; -+ /*msg opcode fill rule is still not clrear,need scott comment */ -+ /***********************************************************/ -+ WMT_DBG_FUNC("ilm msg id is (0x%08x)\n", idc_infor->msg_id); -+ -+#if CFG_WMT_LTE_ENABLE_MSGID_MAPPING -+ switch (idc_infor->msg_id) { -+ case IPC_MSG_ID_EL1_LTE_DEFAULT_PARAM_IND: -+ lxop->op.au4OpData[1] = WMT_IDC_TX_OPCODE_LTE_PARA; -+ break; -+ case IPC_MSG_ID_EL1_LTE_OPER_FREQ_PARAM_IND: -+ lxop->op.au4OpData[1] = WMT_IDC_TX_OPCODE_LTE_FREQ; -+ break; -+ case IPC_MSG_ID_EL1_WIFI_MAX_PWR_IND: -+ lxop->op.au4OpData[1] = WMT_IDC_TX_OPCODE_WIFI_MAX_POWER; -+ break; -+ case IPC_MSG_ID_EL1_LTE_TX_IND: -+ lxop->op.au4OpData[1] = WMT_IDC_TX_OPCODE_LTE_INDICATION; -+ break; -+ case IPC_MSG_ID_EL1_LTE_CONNECTION_STATUS_IND: -+ lxop->op.au4OpData[1] = WMT_IDC_TX_OPCODE_LTE_CONNECTION_STAS; -+ break; -+ default: -+ unknown_msgid = MTK_WCN_BOOL_TRUE; -+ break; -+ } -+ -+ if (MTK_WCN_BOOL_FALSE == unknown_msgid) { -+ /*wake up chip first */ -+ if (DISABLE_PSM_MONITOR()) { -+ WMT_ERR_FUNC("wake up failed\n"); -+ wmt_lib_put_op_to_free_queue(lxop); -+ return MTK_WCN_BOOL_FALSE; -+ } -+ -+ bRet = wmt_lib_put_act_op(lxop); -+ ENABLE_PSM_MONITOR(); -+ if (MTK_WCN_BOOL_FALSE == bRet) -+ WMT_WARN_FUNC("WMT_OPID_IDC_MSG_HANDLING fail(%d)\n", bRet); -+ else -+ WMT_DBG_FUNC("OPID(%d) type(%d) ok\n", lxop->op.opId, lxop->op.au4OpData[1]); -+ } else { -+ bRet = MTK_WCN_BOOL_FALSE; -+ wmt_lib_put_op_to_free_queue(lxop); -+ WMT_ERR_FUNC("unknown msgid from LTE(%d)\n", idc_infor->msg_id); -+ } -+#else -+ if ((idc_infor->msg_id >= IPC_EL1_MSG_ID_BEGIN) -+ && (idc_infor->msg_id <= IPC_EL1_MSG_ID_BEGIN + IPC_EL1_MSG_ID_RANGE)) { -+ lxop->op.au4OpData[1] = idc_infor->msg_id - IPC_EL1_MSG_ID_BEGIN + LTE_MSG_ID_OFFSET - 1; -+ -+ WMT_DBG_FUNC("LTE->CONN:(0x%x->0x%zx)\n", idc_infor->msg_id, lxop->op.au4OpData[1]); -+ /*wake up chip first */ -+ if (DISABLE_PSM_MONITOR()) { -+ WMT_ERR_FUNC("wake up failed\n"); -+ wmt_lib_put_op_to_free_queue(lxop); -+ return MTK_WCN_BOOL_FALSE; -+ } -+ -+ bRet = wmt_lib_put_act_op(lxop); -+ ENABLE_PSM_MONITOR(); -+ if (MTK_WCN_BOOL_FALSE == bRet) { -+ WMT_WARN_FUNC("WMT_OPID_IDC_MSG_HANDLING fail(%d)\n", bRet); -+ } else { -+ WMT_DBG_FUNC("wmt_lib_handle_idc_msg OPID(%d) type(%d) ok\n", -+ lxop->op.opId, lxop->op.au4OpData[1]); -+ } -+ } else { -+ wmt_lib_put_op_to_free_queue(lxop); -+ WMT_ERR_FUNC("msgid(%d) out of range,wmt drop it!\n", idc_infor->msg_id); -+ } -+#endif -+ -+ return bRet; -+} -+#endif -+ -+static MTK_WCN_BOOL wmt_lib_ps_do_sleep(VOID) -+{ -+ return wmt_lib_ps_action(SLEEP); -+} -+ -+static MTK_WCN_BOOL wmt_lib_ps_do_wakeup(VOID) -+{ -+ return wmt_lib_ps_action(WAKEUP); -+} -+ -+static MTK_WCN_BOOL wmt_lib_ps_do_host_awake(VOID) -+{ -+#if 1 -+ return wmt_lib_ps_action(WAKEUP); -+#else -+ return wmt_lib_ps_action(HOST_AWAKE); -+#endif -+} -+ -+/* extern int g_block_tx; */ -+static INT32 wmt_lib_ps_handler(MTKSTP_PSM_ACTION_T action) -+{ -+ INT32 ret; -+ -+ ret = 0; /* TODO:[FixMe][George] initial value or compile warning? */ -+ /* if(g_block_tx && (action == SLEEP)) */ -+ if ((0 != mtk_wcn_stp_coredump_start_get()) && (action == SLEEP)) { -+ mtk_wcn_stp_psm_notify_stp(SLEEP); -+ return ret; -+ } -+ -+ /*MT662x Not Ready */ -+ if (!mtk_wcn_stp_is_ready()) { -+ WMT_DBG_FUNC("MT662x Not Ready, Dont Send Sleep/Wakeup Command\n"); -+ mtk_wcn_stp_psm_notify_stp(ROLL_BACK); -+ return 0; -+ } -+ -+ if (SLEEP == action) { -+ WMT_DBG_FUNC("send op-----------> sleep job\n"); -+ -+ if (!mtk_wcn_stp_is_sdio_mode()) { -+ ret = wmt_lib_ps_do_sleep(); -+ WMT_DBG_FUNC("enable host eirq\n"); -+ wmt_plat_eirq_ctrl(PIN_BGF_EINT, PIN_STA_EINT_EN); -+#if CFG_WMT_DUMP_INT_STATUS -+ if (MTK_WCN_BOOL_TRUE == wmt_plat_dump_BGF_irq_status()) -+ wmt_plat_BGF_irq_dump_status(); -+#endif -+ } else { -+ /* ret = mtk_wcn_stp_sdio_do_own_set(); */ -+ if (sdio_own_ctrl) { -+ ret = (*sdio_own_ctrl) (OWN_SET); -+ } else { -+ WMT_ERR_FUNC("sdio_own_ctrl is not registered\n"); -+ ret = -1; -+ } -+ -+ if (!ret) { -+ mtk_wcn_stp_psm_notify_stp(SLEEP); -+ } else if (ret == -2) { -+ mtk_wcn_stp_psm_notify_stp(ROLL_BACK); -+ WMT_WARN_FUNC("===[SDIO-PS] rollback due to tx busy===%%\n"); -+ } else { -+ mtk_wcn_stp_psm_notify_stp(SLEEP); -+ WMT_ERR_FUNC("===[SDIO-PS] set own fails!===%%\n"); -+ } -+ } -+ -+ WMT_DBG_FUNC("send op<---------- sleep job\n"); -+ } else if (WAKEUP == action) { -+ WMT_DBG_FUNC("send op --------> wake job\n"); -+ -+ if (!mtk_wcn_stp_is_sdio_mode()) { -+ WMT_DBG_FUNC("disable host eirq\n"); -+#if CFG_WMT_DUMP_INT_STATUS -+ if (MTK_WCN_BOOL_TRUE == wmt_plat_dump_BGF_irq_status()) -+ wmt_plat_BGF_irq_dump_status(); -+#endif -+ wmt_plat_eirq_ctrl(PIN_BGF_EINT, PIN_STA_EINT_DIS); -+ ret = wmt_lib_ps_do_wakeup(); -+ } else { -+ /* ret = mtk_wcn_stp_sdio_do_own_clr(); */ -+ -+ if (sdio_own_ctrl) { -+ ret = (*sdio_own_ctrl) (OWN_CLR); -+ } else { -+ WMT_ERR_FUNC("sdio_own_ctrl is not registered\n"); -+ ret = -1; -+ } -+ -+ if (!ret) { -+ mtk_wcn_stp_psm_notify_stp(WAKEUP); -+ } else { -+ mtk_wcn_stp_psm_notify_stp(WAKEUP); -+ WMT_ERR_FUNC("===[SDIO-PS] set own back fails!===%%\n"); -+ } -+ } -+ -+ WMT_DBG_FUNC("send op<---------- wake job\n"); -+ } else if (HOST_AWAKE == action) { -+ WMT_DBG_FUNC("send op-----------> host awake job\n"); -+ -+ if (!mtk_wcn_stp_is_sdio_mode()) { -+ WMT_DBG_FUNC("disable host eirq\n"); -+ /* IRQ already disabled */ -+ /* wmt_plat_eirq_ctrl(PIN_BGF_EINT, PIN_STA_EINT_DIS); */ -+#if 0 -+ if (MTK_WCN_BOOL_TRUE == wmt_plat_dump_BGF_irq_status()) -+ wmt_plat_BGF_irq_dump_status(); -+#endif -+ ret = wmt_lib_ps_do_host_awake(); -+ } else { -+ WMT_DBG_FUNC("[SDIO-PS] SDIO host awake! ####\n"); -+ -+ /* ret = mtk_wcn_stp_sdio_do_own_clr(); */ -+ -+ if (sdio_own_ctrl) { -+ ret = (*sdio_own_ctrl) (OWN_CLR); -+ } else { -+ WMT_ERR_FUNC("sdio_own_ctrl is not registered\n"); -+ ret = -1; -+ } -+ -+ /* Here we set ret to 0 directly */ -+ ret = 0; -+ if (!ret) { -+ mtk_wcn_stp_psm_notify_stp(HOST_AWAKE); -+ } else { -+ mtk_wcn_stp_psm_notify_stp(HOST_AWAKE); -+ WMT_ERR_FUNC("===[SDIO-PS]set own back fails!===%%\n"); -+ } -+ } -+ -+ WMT_DBG_FUNC("send op<----------- host awake job\n"); -+ } else if (EIRQ == action) { -+ WMT_DBG_FUNC("send op -------------> eirq job\n"); -+ -+ if (!mtk_wcn_stp_is_sdio_mode()) { -+ WMT_DBG_FUNC("disable host eirq\n"); -+ /* Disable interrupt */ -+ /* wmt_plat_eirq_ctrl(PIN_BGF_EINT, PIN_STA_EINT_DIS); */ -+ ret = mtk_wcn_stp_psm_notify_stp(EIRQ); -+ } else { -+ WMT_ERR_FUNC("[SDIO-PS]sdio own-back eirq!######\n"); -+ ret = mtk_wcn_stp_psm_notify_stp(EIRQ); -+ } -+ -+ WMT_DBG_FUNC("send op<----------- eirq job\n"); -+ } -+ -+ return ret; -+} -+#endif /* end of CFG_WMT_PS_SUPPORT */ -+ -+INT32 wmt_lib_ps_stp_cb(MTKSTP_PSM_ACTION_T action) -+{ -+#if CFG_WMT_PS_SUPPORT -+ return wmt_lib_ps_handler(action); -+#else -+ WMT_WARN_FUNC("CFG_WMT_PS_SUPPORT is not set\n"); -+ return 0; -+#endif -+} -+ -+MTK_WCN_BOOL wmt_lib_is_quick_ps_support(VOID) -+{ -+ if ((g_quick_sleep_ctrl) && (wmt_dev_get_early_suspend_state() == MTK_WCN_BOOL_TRUE)) -+ return wmt_core_is_quick_ps_support(); -+ else -+ return MTK_WCN_BOOL_FALSE; -+} -+ -+VOID wmt_lib_ps_irq_cb(VOID) -+{ -+#if CFG_WMT_PS_SUPPORT -+ wmt_lib_ps_handler(EIRQ); -+#else -+ WMT_DBG_FUNC("CFG_WMT_PS_SUPPORT is not set\n"); -+ return; -+#endif -+} -+ -+VOID wmt_lib_ps_set_sdio_psop(PF_WMT_SDIO_PSOP own_cb) -+{ -+#if CFG_WMT_PS_SUPPORT -+ sdio_own_ctrl = own_cb; -+#endif -+} -+ -+UINT32 wmt_lib_wait_event_checker(P_OSAL_THREAD pThread) -+{ -+ P_DEV_WMT pDevWmt; -+ -+ if (pThread) { -+ pDevWmt = (P_DEV_WMT) (pThread->pThreadData); -+ return !RB_EMPTY(&pDevWmt->rActiveOpQ); -+ } -+ WMT_ERR_FUNC("pThread(NULL)\n"); -+ return 0; -+} -+ -+static INT32 wmtd_thread(void *pvData) -+{ -+ P_DEV_WMT pWmtDev = (P_DEV_WMT) pvData; -+ P_OSAL_EVENT pEvent = NULL; -+ P_OSAL_OP pOp; -+ INT32 iResult; -+ -+ if (NULL == pWmtDev) { -+ WMT_ERR_FUNC("pWmtDev(NULL)\n"); -+ return -1; -+ } -+ WMT_INFO_FUNC("wmtd thread starts\n"); -+ -+ pEvent = &(pWmtDev->rWmtdWq); -+ -+ for (;;) { -+ pOp = NULL; -+ pEvent->timeoutValue = 0; -+/* osal_thread_wait_for_event(&pWmtDev->thread, pEvent);*/ -+ osal_thread_wait_for_event(&pWmtDev->thread, pEvent, wmt_lib_wait_event_checker); -+ -+ if (osal_thread_should_stop(&pWmtDev->thread)) { -+ WMT_INFO_FUNC("wmtd thread should stop now...\n"); -+ /* TODO: clean up active opQ */ -+ break; -+ } -+ -+ /* get Op from activeQ */ -+ pOp = wmt_lib_get_op(&pWmtDev->rActiveOpQ); -+ if (!pOp) { -+ WMT_WARN_FUNC("get_lxop activeQ fail\n"); -+ continue; -+ } -+#if 0 /* wmt_core_opid_handler will do sanity check on opId, so no usage here */ -+ id = lxop_get_opid(pLxOp); -+ if (id >= WMT_OPID_MAX) { -+ WMT_WARN_FUNC("abnormal opid id: 0x%x\n", id); -+ iResult = -1; -+ goto handlerDone; -+ } -+#endif -+ -+ if (osal_test_bit(WMT_STAT_RST_ON, &pWmtDev->state)) { -+ /* when whole chip reset, only HW RST and SW RST cmd can execute */ -+ if ((pOp->op.opId == WMT_OPID_HW_RST) || (pOp->op.opId == WMT_OPID_SW_RST) -+ || (pOp->op.opId == WMT_OPID_GPIO_STATE)) { -+ iResult = wmt_core_opid(&pOp->op); -+ } else { -+ iResult = -2; -+ WMT_WARN_FUNC("Whole chip resetting, opid (%d) failed, iRet(%d)\n", pOp->op.opId, -+ iResult); -+ } -+ } else { -+ wmt_lib_set_current_op(pWmtDev, pOp); -+ iResult = wmt_core_opid(&pOp->op); -+ wmt_lib_set_current_op(pWmtDev, NULL); -+ } -+ -+ if (iResult) -+ WMT_WARN_FUNC("opid (%d) failed, iRet(%d)\n", pOp->op.opId, iResult); -+ -+ if (osal_op_is_wait_for_signal(pOp)) { -+ osal_op_raise_signal(pOp, iResult); -+ } else { -+ /* put Op back to freeQ */ -+ wmt_lib_put_op(&pWmtDev->rFreeOpQ, pOp); -+ } -+ -+ if (WMT_OPID_EXIT == pOp->op.opId) { -+ WMT_INFO_FUNC("wmtd thread received exit signal\n"); -+ break; -+ } -+ } -+ -+ WMT_INFO_FUNC("wmtd thread exits succeed\n"); -+ -+ return 0; -+}; -+ -+static MTK_WCN_BOOL wmt_lib_put_op(P_OSAL_OP_Q pOpQ, P_OSAL_OP pOp) -+{ -+ INT32 iRet; -+ -+ if (!pOpQ || !pOp) { -+ WMT_WARN_FUNC("invalid input param: pOpQ(0x%p), pLxOp(0x%p)\n", pOpQ, pOp); -+ osal_assert(pOpQ); -+ osal_assert(pOp); -+ return MTK_WCN_BOOL_FALSE; -+ } -+ -+ iRet = osal_lock_sleepable_lock(&pOpQ->sLock); -+ if (iRet) { -+ WMT_WARN_FUNC("osal_lock_sleepable_lock iRet(%d)\n", iRet); -+ return MTK_WCN_BOOL_FALSE; -+ } -+#if 0 -+ if (pOpQ == &gDevWmt.rFreeOpQ) -+ WMT_INFO_FUNC("current wmt free queue count is(%d),opid(%d)\n", RB_COUNT(pOpQ), pOp->op.opId); -+#endif -+ /* acquire lock success */ -+ if (!RB_FULL(pOpQ)) -+ RB_PUT(pOpQ, pOp); -+ else -+ iRet = -1; -+ -+ osal_unlock_sleepable_lock(&pOpQ->sLock); -+ -+ if (iRet) { -+ WMT_WARN_FUNC("RB_FULL(0x%p)\n", pOpQ); -+ return MTK_WCN_BOOL_FALSE; -+ } else { -+ return MTK_WCN_BOOL_TRUE; -+ } -+} -+ -+static P_OSAL_OP wmt_lib_get_op(P_OSAL_OP_Q pOpQ) -+{ -+ P_OSAL_OP pOp; -+ INT32 iRet; -+ -+ if (NULL == pOpQ) { -+ WMT_ERR_FUNC("pOpQ = NULL\n"); -+ osal_assert(pOpQ); -+ return NULL; -+ } -+ -+ iRet = osal_lock_sleepable_lock(&pOpQ->sLock); -+ if (iRet) { -+ WMT_ERR_FUNC("osal_lock_sleepable_lock iRet(%d)\n", iRet); -+ return NULL; -+ } -+ -+ /* acquire lock success */ -+ RB_GET(pOpQ, pOp); -+ osal_unlock_sleepable_lock(&pOpQ->sLock); -+ -+ if (NULL == pOp) { -+ WMT_WARN_FUNC("RB_GET return NULL\n"); -+ osal_assert(pOp); -+ } -+ -+ return pOp; -+} -+ -+INT32 wmt_lib_put_op_to_free_queue(P_OSAL_OP pOp) -+{ -+ P_DEV_WMT pWmtDev = &gDevWmt; -+ -+ if (MTK_WCN_BOOL_FALSE == wmt_lib_put_op(&pWmtDev->rFreeOpQ, pOp)) -+ return -1; -+ else -+ return 0; -+} -+ -+P_OSAL_OP wmt_lib_get_free_op(VOID) -+{ -+ P_OSAL_OP pOp = NULL; -+ P_DEV_WMT pDevWmt = &gDevWmt; -+ -+ osal_assert(pDevWmt); -+ -+ pOp = wmt_lib_get_op(&pDevWmt->rFreeOpQ); -+ if (pOp) -+ osal_memset(&pOp->op, 0, osal_sizeof(pOp->op)); -+ return pOp; -+} -+ -+MTK_WCN_BOOL wmt_lib_put_act_op(P_OSAL_OP pOp) -+{ -+ P_DEV_WMT pWmtDev = &gDevWmt; -+ MTK_WCN_BOOL bRet = MTK_WCN_BOOL_FALSE; -+ MTK_WCN_BOOL bCleanup = MTK_WCN_BOOL_FALSE; -+ P_OSAL_SIGNAL pSignal = NULL; -+ long waitRet = -1; -+ P_OSAL_THREAD pThread; -+ -+ osal_assert(pWmtDev); -+ osal_assert(pOp); -+ -+ do { -+ if (!pWmtDev || !pOp) { -+ WMT_ERR_FUNC("pWmtDev(0x%p), pOp(0x%p)\n", pWmtDev, pOp); -+ break; -+ } -+ if ((0 != mtk_wcn_stp_coredump_start_get()) && -+ (WMT_OPID_HW_RST != pOp->op.opId) && -+ (WMT_OPID_SW_RST != pOp->op.opId) && (WMT_OPID_GPIO_STATE != pOp->op.opId)) { -+ bCleanup = MTK_WCN_BOOL_TRUE; -+ WMT_WARN_FUNC("block tx flag is set\n"); -+ break; -+ } -+ pSignal = &pOp->signal; -+/* pOp->u4WaitMs = u4WaitMs; */ -+ if (pSignal->timeoutValue) { -+ pOp->result = -9; -+ osal_signal_init(pSignal); -+ } -+ -+ /* put to active Q */ -+ bRet = wmt_lib_put_op(&pWmtDev->rActiveOpQ, pOp); -+ if (MTK_WCN_BOOL_FALSE == bRet) { -+ WMT_WARN_FUNC("put to active queue fail\n"); -+ bCleanup = MTK_WCN_BOOL_TRUE; -+ break; -+ } -+ -+ /* wake up wmtd */ -+ /* wake_up_interruptible(&pWmtDev->rWmtdWq); */ -+ osal_trigger_event(&pWmtDev->rWmtdWq); -+ -+ if (0 == pSignal->timeoutValue) { -+ bRet = MTK_WCN_BOOL_TRUE; -+ /* clean it in wmtd */ -+ break; -+ } -+ /* wait result, clean it here */ -+ bCleanup = MTK_WCN_BOOL_TRUE; -+ -+ /* check result */ -+ /* wait_ret = wait_for_completion_interruptible_timeout(&pOp->comp, msecs_to_jiffies(u4WaitMs)); */ -+ /* wait_ret = wait_for_completion_timeout(&pOp->comp, msecs_to_jiffies(u4WaitMs)); */ -+ waitRet = osal_wait_for_signal_timeout(pSignal); -+ WMT_DBG_FUNC("osal_wait_for_signal_timeout:%ld\n", waitRet); -+ -+ /* if (unlikely(!wait_ret)) { */ -+ if (0 == waitRet) { -+ pThread = &gDevWmt.thread; -+ WMT_ERR_FUNC -+ ("wait completion timeout, opId(%d), show wmtd_thread stack!\n", pOp->op.opId); -+ /* TODO: how to handle it? retry? */ -+ wcn_wmtd_timeout_collect_ftrace(); /* trigger collect SYS_FTRACE */ -+ osal_thread_show_stack(pThread); -+ } else { -+ if (pOp->result) -+ WMT_WARN_FUNC("opId(%d) result:%d\n", pOp->op.opId, pOp->result); -+ } -+ /* op completes, check result */ -+ bRet = (pOp->result) ? MTK_WCN_BOOL_FALSE : MTK_WCN_BOOL_TRUE; -+ } while (0); -+ -+ if (bCleanup) { -+ /* put Op back to freeQ */ -+ wmt_lib_put_op(&pWmtDev->rFreeOpQ, pOp); -+ } -+ -+ return bRet; -+} -+ -+/* TODO:[ChangeFeature][George] is this function obsoleted? */ -+#if 0 -+INT32 wmt_lib_reg_rw(UINT32 isWrite, UINT32 offset, PUINT32 pvalue, UINT32 mask) -+{ -+ P_WMT_LXOP lxop; -+ MTK_WCN_BOOL bRet; -+ PUINT32 plv = NULL; -+ UINT32 pbuf[2]; -+ P_OSAL_EVENT pSignal = NULL; -+ -+ if (!pvalue) { -+ WMT_WARN_FUNC("!pvalue\n"); -+ return -1; -+ } -+ lxop = wmt_lib_get_free_lxop(); -+ if (!lxop) { -+ WMT_WARN_FUNC("get_free_lxop fail\n"); -+ -+ return -1; -+ } -+ -+ plv = (PUINT32) (((UINT32) pbuf + 0x3) & ~0x3UL); -+ *plv = *pvalue; -+ pSignal = &lxop->signal; -+ WMT_DBG_FUNC("OPID_REG_RW isWrite(%d) offset(0x%x) value(0x%x) mask(0x%x)\n", isWrite, offset, *pvalue, mask); -+ -+ lxop->op.opId = WMT_OPID_REG_RW; -+ lxop->op.au4OpData[0] = isWrite; -+ lxop->op.au4OpData[1] = offset; -+ lxop->op.au4OpData[2] = (UINT32) plv; -+ lxop->op.au4OpData[3] = mask; -+ pSignal->timeoutValue = MAX_EACH_WMT_CMD; -+ -+ DISABLE_PSM_MONITOR(); -+ bRet = wmt_lib_put_act_lxop(lxop); -+ ENABLE_PSM_MONITOR(); -+ -+ if (MTK_WCN_BOOL_FALSE != bRet) { -+ WMT_DBG_FUNC("OPID_REG_RW isWrite(%u) offset(0x%x) value(0x%x) mask(0x%x) ok\n", -+ isWrite, offset, *plv, mask); -+ if (!isWrite) -+ *pvalue = *plv; -+ } else { -+ WMT_WARN_FUNC("OPID_REG_RW isWrite(%u) offset(0x%x) value(0x%x) mask(0x%x) bRet(%d)\n", -+ isWrite, offset, *plv, mask, bRet); -+ } -+ -+ return bRet; -+} -+#endif -+ -+/* TODO:[ChangeFeature][George] is this function obsoleted? */ -+#if 0 -+static VOID wmt_lib_clear_chip_id(VOID) -+{ -+/* -+ gDevWmt.pChipInfo = NULL; -+*/ -+ gDevWmt.hw_ver = WMTHWVER_INVALID; -+} -+#endif -+ -+/* TODO: [FixMe][GeorgeKuo]: change this API to report real chip id, hw_ver, and */ -+/* fw_ver instead of WMT-translated WMTHWVER */ -+ENUM_WMTHWVER_TYPE_T wmt_lib_get_hwver(VOID) -+{ -+/* -+ P_WMT_CMB_CHIP_INFO_S pChipInfo = NULL; -+ P_DEV_WMT pWmtDev = gpDevWmt; -+ pChipInfo = wmt_lib_get_chip_info(pWmtDev); -+ return pChipInfo != NULL ? pChipInfo->eHwVersion : WMTHWVER_INVALID; -+ */ -+ return gDevWmt.eWmtHwVer; -+} -+ -+UINT32 wmt_lib_get_icinfo(ENUM_WMT_CHIPINFO_TYPE_T index) -+{ -+ if (WMTCHIN_CHIPID == index) -+ return gDevWmt.chip_id; -+ else if (WMTCHIN_HWVER == index) -+ return gDevWmt.hw_ver; -+ else if (WMTCHIN_MAPPINGHWVER == index) -+ return gDevWmt.eWmtHwVer; -+ else if (WMTCHIN_FWVER == index) -+ return gDevWmt.fw_ver; -+ -+ return 0; -+ -+} -+ -+PUINT8 wmt_lib_def_patch_name(VOID) -+{ -+ WMT_INFO_FUNC("wmt-lib: use default patch name (%s)\n", gDevWmt.cPatchName); -+ return gDevWmt.cPatchName; -+} -+ -+MTK_WCN_BOOL wmt_lib_is_therm_ctrl_support(VOID) -+{ -+ MTK_WCN_BOOL bIsSupportTherm = MTK_WCN_BOOL_TRUE; -+ /* TODO:[FixMe][GeorgeKuo]: move IC-dependent checking to ic-implementation file */ -+ if (((0x6620 == gDevWmt.chip_id) && (WMTHWVER_E3 > gDevWmt.eWmtHwVer)) -+ || (WMTHWVER_INVALID == gDevWmt.eWmtHwVer)) { -+ WMT_ERR_FUNC("thermal command fail: chip version(WMTHWVER_TYPE:%d) is not valid\n", gDevWmt.eWmtHwVer); -+ bIsSupportTherm = MTK_WCN_BOOL_FALSE; -+ } -+ if (!mtk_wcn_stp_is_ready()) { -+ WMT_ERR_FUNC("thermal command can not be send: STP is not ready\n"); -+ bIsSupportTherm = MTK_WCN_BOOL_FALSE; -+ } -+ -+ return bIsSupportTherm; -+} -+ -+MTK_WCN_BOOL wmt_lib_is_dsns_ctrl_support(VOID) -+{ -+ /* TODO:[FixMe][GeorgeKuo]: move IC-dependent checking to ic-implementation file */ -+ if (((0x6620 == gDevWmt.chip_id) && (WMTHWVER_E3 > gDevWmt.eWmtHwVer)) -+ || (WMTHWVER_INVALID == gDevWmt.eWmtHwVer)) { -+ WMT_ERR_FUNC("thermal command fail: chip version(WMTHWVER_TYPE:%d) is not valid\n", gDevWmt.eWmtHwVer); -+ return MTK_WCN_BOOL_FALSE; -+ } -+ -+ return MTK_WCN_BOOL_TRUE; -+} -+ -+/*! -+ * \brief Update combo chip pin settings (GPIO) -+ * -+ * An internal library function to support various settings for chip GPIO. It is -+ * updated in a grouping way: configure all required pins in a single call. -+ * -+ * \param id desired pin ID to be controlled -+ * \param stat desired pin states to be set -+ * \param flag supplementary options for this operation -+ * -+ * \retval 0 operation success -+ * \retval -1 invalid id -+ * \retval -2 invalid stat -+ * \retval < 0 error for operation fail -+ */ -+static INT32 wmt_lib_pin_ctrl(WMT_IC_PIN_ID id, WMT_IC_PIN_STATE stat, UINT32 flag) -+{ -+ P_OSAL_OP pOp; -+ MTK_WCN_BOOL bRet; -+ P_OSAL_SIGNAL pSignal; -+ -+ /* input sanity check */ -+ if (WMT_IC_PIN_MAX <= id) { -+ WMT_ERR_FUNC("invalid ic pin id(%d)\n", id); -+ return -1; -+ } -+ if (WMT_IC_PIN_STATE_MAX <= stat) { -+ WMT_ERR_FUNC("invalid ic pin state (%d)\n", stat); -+ return -2; -+ } -+ -+ pOp = wmt_lib_get_free_op(); -+ if (!pOp) { -+ WMT_WARN_FUNC("get_free_lxop fail\n"); -+ return MTK_WCN_BOOL_FALSE; -+ } -+ -+ WMT_DBG_FUNC("call WMT_OPID_GPIO_CTRL (ic pin id:%d, stat:%d, flag:0x%x)\n", id, stat, flag); -+ -+ pSignal = &pOp->signal; -+ pOp->op.opId = WMT_OPID_GPIO_CTRL; -+ pOp->op.au4OpData[0] = id; -+ pOp->op.au4OpData[1] = stat; -+ pOp->op.au4OpData[2] = flag; -+ pSignal->timeoutValue = MAX_EACH_WMT_CMD; -+ -+ /*wake up chip first */ -+ if (DISABLE_PSM_MONITOR()) { -+ WMT_ERR_FUNC("wake up failed\n"); -+ wmt_lib_put_op_to_free_queue(pOp); -+ return -1; -+ } -+ -+ bRet = wmt_lib_put_act_op(pOp); -+ ENABLE_PSM_MONITOR(); -+ if (MTK_WCN_BOOL_FALSE == bRet) -+ WMT_WARN_FUNC("PIN_ID(%d) PIN_STATE(%d) flag(%d) fail\n", id, stat, flag); -+ else -+ WMT_DBG_FUNC("OPID(%d) type(%d) ok\n", pOp->op.opId, pOp->op.au4OpData[0]); -+ -+ return 0; -+} -+ -+INT32 wmt_lib_reg_rw(UINT32 isWrite, UINT32 offset, PUINT32 pvalue, UINT32 mask) -+{ -+ P_OSAL_OP pOp; -+ MTK_WCN_BOOL bRet; -+ UINT32 value; -+ P_OSAL_SIGNAL pSignal; -+ -+ if (!pvalue) { -+ WMT_WARN_FUNC("!pvalue\n"); -+ return -1; -+ } -+ -+ pOp = wmt_lib_get_free_op(); -+ if (!pOp) { -+ WMT_WARN_FUNC("get_free_lxop fail\n"); -+ return -1; -+ } -+ -+ pSignal = &pOp->signal; -+ pSignal->timeoutValue = MAX_EACH_WMT_CMD; -+ value = *pvalue; -+ WMT_DBG_FUNC("OPID_REG_RW isWrite(%u) offset(0x%x) value(0x%x) mask(0x%x)\n\n", isWrite, offset, *pvalue, mask); -+ pOp->op.opId = WMT_OPID_REG_RW; -+ pOp->op.au4OpData[0] = isWrite; -+ pOp->op.au4OpData[1] = offset; -+ pOp->op.au4OpData[2] = (SIZE_T)&value; -+ pOp->op.au4OpData[3] = mask; -+ if (DISABLE_PSM_MONITOR()) { -+ WMT_ERR_FUNC("wake up failed\n"); -+ wmt_lib_put_op_to_free_queue(pOp); -+ return -1; -+ } -+ -+ bRet = wmt_lib_put_act_op(pOp); -+ ENABLE_PSM_MONITOR(); -+ -+ if (MTK_WCN_BOOL_FALSE != bRet) { -+ WMT_DBG_FUNC("OPID_REG_RW isWrite(%u) offset(0x%x) value(0x%x) mask(0x%x) ok\n", -+ isWrite, offset, value, mask); -+ if (!isWrite) -+ *pvalue = value; -+ -+ return 0; -+ } -+ WMT_WARN_FUNC("OPID_REG_RW isWrite(%u) offset(0x%x) value(0x%x) mask(0x%x) bRet(%d)\n", -+ isWrite, offset, value, mask, bRet); -+ return -1; -+} -+ -+INT32 wmt_lib_efuse_rw(UINT32 isWrite, UINT32 offset, PUINT32 pvalue, UINT32 mask) -+{ -+ P_OSAL_OP pOp; -+ MTK_WCN_BOOL bRet; -+ UINT32 value; -+ P_OSAL_SIGNAL pSignal; -+ -+ if (!pvalue) { -+ WMT_WARN_FUNC("!pvalue\n"); -+ return -1; -+ } -+ -+ pOp = wmt_lib_get_free_op(); -+ if (!pOp) { -+ WMT_WARN_FUNC("get_free_lxop fail\n"); -+ return -1; -+ } -+ -+ pSignal = &pOp->signal; -+ pSignal->timeoutValue = MAX_EACH_WMT_CMD; -+ value = *pvalue; -+ WMT_DBG_FUNC("OPID_EFUSE_RW isWrite(%u) offset(0x%x) value(0x%x) mask(0x%x)\n\n", -+ isWrite, offset, *pvalue, mask); -+ pOp->op.opId = WMT_OPID_EFUSE_RW; -+ pOp->op.au4OpData[0] = isWrite; -+ pOp->op.au4OpData[1] = offset; -+ pOp->op.au4OpData[2] = (SIZE_T)&value; -+ pOp->op.au4OpData[3] = mask; -+ if (DISABLE_PSM_MONITOR()) { -+ WMT_ERR_FUNC("wake up failed\n"); -+ wmt_lib_put_op_to_free_queue(pOp); -+ return -1; -+ } -+ -+ bRet = wmt_lib_put_act_op(pOp); -+ ENABLE_PSM_MONITOR(); -+ -+ if (MTK_WCN_BOOL_FALSE != bRet) { -+ WMT_DBG_FUNC("OPID_EFUSE_RW isWrite(%u) offset(0x%x) value(0x%x) mask(0x%x) ok\n", -+ isWrite, offset, value, mask); -+ if (!isWrite) -+ *pvalue = value; -+ -+ return 0; -+ } -+ WMT_WARN_FUNC("OPID_REG_RW isWrite(%u) offset(0x%x) value(0x%x) mask(0x%x) bRet(%d)\n", -+ isWrite, offset, value, mask, bRet); -+ return -1; -+ -+} -+ -+/*! -+ * \brief update combo chip AUDIO Interface (AIF) settings -+ * -+ * A library function to support updating chip AUDIO pin settings. A group of -+ * pins is updated as a whole. -+ * -+ * \param aif desired audio interface state to use -+ * \param flag whether audio pin is shared or not -+ * -+ * \retval 0 operation success -+ * \retval -1 invalid aif -+ * \retval < 0 error for invalid parameters or operation fail -+ */ -+INT32 wmt_lib_set_aif(CMB_STUB_AIF_X aif, MTK_WCN_BOOL share) -+{ -+ if (CMB_STUB_AIF_MAX <= aif) { -+ WMT_ERR_FUNC("invalid aif (%d)\n", aif); -+ return -1; -+ } -+ WMT_DBG_FUNC("call pin_ctrl for aif:%d, share:%d\n", aif, (MTK_WCN_BOOL_TRUE == share) ? 1 : 0); -+ /* Translate CMB_STUB_AIF_X into WMT_IC_PIN_STATE by array */ -+ return wmt_lib_pin_ctrl(WMT_IC_PIN_AUDIO, -+ cmb_aif2pin_stat[aif], -+ (MTK_WCN_BOOL_TRUE == share) ? WMT_LIB_AIF_FLAG_SHARE : WMT_LIB_AIF_FLAG_SEPARATE); -+} -+ -+INT32 wmt_lib_host_awake_get(VOID) -+{ -+ return wmt_plat_wake_lock_ctrl(WL_OP_GET); -+} -+ -+INT32 wmt_lib_host_awake_put(VOID) -+{ -+ return wmt_plat_wake_lock_ctrl(WL_OP_PUT); -+} -+ -+MTK_WCN_BOOL wmt_lib_btm_cb(MTKSTP_BTM_WMT_OP_T op) -+{ -+ MTK_WCN_BOOL bRet = MTK_WCN_BOOL_FALSE; -+ -+ if (op == BTM_RST_OP) { -+ /* high priority, not to enqueue into the queue of wmtd */ -+ WMT_INFO_FUNC("Invoke whole chip reset from stp_btm!!!\n"); -+ wmt_lib_cmb_rst(WMTRSTSRC_RESET_STP); -+ bRet = MTK_WCN_BOOL_TRUE; -+ } else if (op == BTM_DMP_OP) { -+ -+ WMT_WARN_FUNC("TBD!!!\n"); -+ } else if (op == BTM_GET_AEE_SUPPORT_FLAG) { -+ bRet = wmt_core_get_aee_dump_flag(); -+ } -+ return bRet; -+} -+ -+MTK_WCN_BOOL wmt_cdev_rstmsg_snd(ENUM_WMTRSTMSG_TYPE_T msg) -+{ -+ -+ INT32 i = 0; -+ P_DEV_WMT pDevWmt = &gDevWmt; -+ PUINT8 drv_name[] = { -+ "DRV_TYPE_BT", -+ "DRV_TYPE_FM", -+ "DRV_TYPE_GPS", -+ "DRV_TYPE_WIFI" -+ }; -+ -+ for (i = 0; i <= WMTDRV_TYPE_WIFI; i++) { -+ /* <1> check if reset callback is registered */ -+ if (pDevWmt->rFdrvCb.fDrvRst[i]) { -+ /* <2> send the msg to this subfucntion */ -+ /*src, dst, msg_type, msg_data, msg_size */ -+ pDevWmt->rFdrvCb.fDrvRst[i] (WMTDRV_TYPE_WMT, i, WMTMSG_TYPE_RESET, &msg, -+ sizeof(ENUM_WMTRSTMSG_TYPE_T)); -+ WMT_INFO_FUNC("type = %s, msg sent\n", drv_name[i]); -+ } else { -+ WMT_DBG_FUNC("type = %s, unregistered\n", drv_name[i]); -+ } -+ } -+ -+ return MTK_WCN_BOOL_TRUE; -+} -+ -+VOID wmt_lib_state_init(VOID) -+{ -+ /* UINT32 i = 0; */ -+ P_DEV_WMT pDevWmt = &gDevWmt; -+ P_OSAL_OP pOp; -+ -+ /* Initialize op queue */ -+ /* RB_INIT(&pDevWmt->rFreeOpQ, WMT_OP_BUF_SIZE); */ -+ /* RB_INIT(&pDevWmt->rActiveOpQ, WMT_OP_BUF_SIZE); */ -+ -+ while (!RB_EMPTY(&pDevWmt->rActiveOpQ)) { -+#if 0 -+ osal_signal_init(&(pOp->signal)); -+ wmt_lib_put_op(&pDevWmt->rFreeOpQ, pOp); -+#endif -+ pOp = wmt_lib_get_op(&pDevWmt->rActiveOpQ); -+ if (pOp) { -+ if (osal_op_is_wait_for_signal(pOp)) -+ osal_op_raise_signal(pOp, -1); -+ else -+ wmt_lib_put_op(&pDevWmt->rFreeOpQ, pOp); -+ } -+ } -+ -+ /* Put all to free Q */ -+ /* -+ for (i = 0; i < WMT_OP_BUF_SIZE; i++) { -+ osal_signal_init(&(pDevWmt->arQue[i].signal)); -+ wmt_lib_put_op(&pDevWmt->rFreeOpQ, &(pDevWmt->arQue[i])); -+ } */ -+} -+ -+#if 0 -+INT32 wmt_lib_sdio_ctrl(UINT32 on) -+{ -+ -+ P_OSAL_OP pOp; -+ MTK_WCN_BOOL bRet; -+ P_OSAL_SIGNAL pSignal; -+ -+ pOp = wmt_lib_get_free_op(); -+ if (!pOp) { -+ WMT_WARN_FUNC("get_free_lxop fail\n"); -+ return MTK_WCN_BOOL_FALSE; -+ } -+ -+ WMT_DBG_FUNC("call WMT_OPID_SDIO_CTRL\n"); -+ -+ pSignal = &pOp->signal; -+ pOp->op.opId = WMT_OPID_SDIO_CTRL; -+ pOp->op.au4OpData[0] = on; -+ pSignal->timeoutValue = MAX_GPIO_CTRL_TIME; -+ -+ bRet = wmt_lib_put_act_op(pOp); -+ if (MTK_WCN_BOOL_FALSE == bRet) { -+ WMT_WARN_FUNC("WMT_OPID_SDIO_CTRL failed\n"); -+ return -1; -+ } -+ WMT_DBG_FUNC("OPID(WMT_OPID_SDIO_CTRL)ok\n"); -+ -+ return 0; -+} -+#endif -+ -+MTK_WCN_BOOL wmt_lib_hw_state_show(VOID) -+{ -+ P_OSAL_OP pOp; -+ MTK_WCN_BOOL bRet; -+ P_OSAL_SIGNAL pSignal; -+ -+ pOp = wmt_lib_get_free_op(); -+ if (!pOp) { -+ WMT_WARN_FUNC("get_free_lxop fail\n"); -+ return MTK_WCN_BOOL_FALSE; -+ } -+ -+ WMT_DBG_FUNC("call WMT_OPID_HW_STATE_SHOW\n"); -+ -+ pSignal = &pOp->signal; -+ pOp->op.opId = WMT_OPID_GPIO_STATE; -+ pSignal->timeoutValue = MAX_GPIO_CTRL_TIME; -+ -+ bRet = wmt_lib_put_act_op(pOp); -+ if (MTK_WCN_BOOL_FALSE == bRet) { -+ WMT_WARN_FUNC("WMT_OPID_HW_STATE_SHOW failed\n"); -+ return MTK_WCN_BOOL_FALSE; -+ } -+ WMT_DBG_FUNC("OPID(WMT_OPID_HW_STATE_SHOW)ok\n"); -+ return MTK_WCN_BOOL_TRUE; -+} -+ -+MTK_WCN_BOOL wmt_lib_hw_rst(VOID) -+{ -+ -+ P_OSAL_OP pOp; -+ MTK_WCN_BOOL bRet; -+ P_OSAL_SIGNAL pSignal; -+ P_DEV_WMT pDevWmt = &gDevWmt; -+ -+ wmt_lib_state_init(); -+ -+ osal_clear_bit(WMT_STAT_STP_REG, &pDevWmt->state); -+ osal_clear_bit(WMT_STAT_STP_OPEN, &pDevWmt->state); -+ osal_clear_bit(WMT_STAT_STP_EN, &pDevWmt->state); -+ osal_clear_bit(WMT_STAT_STP_RDY, &pDevWmt->state); -+ osal_clear_bit(WMT_STAT_RX, &pDevWmt->state); -+ osal_clear_bit(WMT_STAT_CMD, &pDevWmt->state); -+ -+ /*Before do hardware reset, we show GPIO state to check if others modified our pin state accidentially */ -+ wmt_lib_hw_state_show(); -+ pOp = wmt_lib_get_free_op(); -+ if (!pOp) { -+ WMT_WARN_FUNC("get_free_lxop fail\n"); -+ return MTK_WCN_BOOL_FALSE; -+ } -+ -+ WMT_DBG_FUNC("call WMT_OPID_HW_RST\n"); -+ -+ pSignal = &pOp->signal; -+ pOp->op.opId = WMT_OPID_HW_RST; -+ pSignal->timeoutValue = MAX_GPIO_CTRL_TIME; -+ -+ bRet = wmt_lib_put_act_op(pOp); -+ if (MTK_WCN_BOOL_FALSE == bRet) { -+ WMT_WARN_FUNC("WMT_OPID_HW_RST failed\n"); -+ return MTK_WCN_BOOL_FALSE; -+ } -+ WMT_DBG_FUNC("OPID(WMT_OPID_HW_RST)ok\n"); -+ return MTK_WCN_BOOL_TRUE; -+} -+ -+MTK_WCN_BOOL wmt_lib_sw_rst(INT32 baudRst) -+{ -+ -+ P_OSAL_OP pOp; -+ MTK_WCN_BOOL bRet; -+ P_OSAL_SIGNAL pSignal; -+ -+ /* <1> wmt state reset */ -+ wmt_lib_state_init(); -+ -+ /* <2> Reset STP data structure */ -+ WMT_DBG_FUNC("Cleanup STP context\n"); -+ mtk_wcn_stp_flush_context(); -+ /* <3> Reset STP-PSM data structure */ -+ WMT_DBG_FUNC("Cleanup STP-PSM context\n"); -+ mtk_wcn_stp_psm_reset(); -+ -+ /* <4> do sw reset in wmt-core */ -+ pOp = wmt_lib_get_free_op(); -+ if (!pOp) { -+ WMT_WARN_FUNC("get_free_lxop fail\n"); -+ return MTK_WCN_BOOL_FALSE; -+ } -+ -+ WMT_DBG_FUNC("call WMT_OPID_SW_RST\n"); -+ -+ pSignal = &pOp->signal; -+ pSignal->timeoutValue = MAX_FUNC_ON_TIME; -+ -+ pOp->op.opId = WMT_OPID_SW_RST; -+ pOp->op.au4OpData[0] = baudRst; -+ -+ bRet = wmt_lib_put_act_op(pOp); -+ if (MTK_WCN_BOOL_FALSE == bRet) { -+ WMT_WARN_FUNC("WMT_OPID_SW_RST failed\n"); -+ return MTK_WCN_BOOL_FALSE; -+ } -+ WMT_DBG_FUNC("OPID(WMT_OPID_SW_RST)ok\n"); -+ return MTK_WCN_BOOL_TRUE; -+} -+ -+ENUM_WMTRSTRET_TYPE_T wmt_lib_cmb_rst(ENUM_WMTRSTSRC_TYPE_T src) -+{ -+#define RETRYTIMES 10 -+ MTK_WCN_BOOL bRet; -+ ENUM_WMTRSTRET_TYPE_T retval = WMTRSTRET_MAX; -+ ENUM_WMTRSTMSG_TYPE_T rstMsg = WMTRSTMSG_RESET_MAX; -+ INT32 retries = RETRYTIMES; -+ P_DEV_WMT pDevWmt = &gDevWmt; -+ P_OSAL_OP pOp; -+ PUINT8 srcName[] = { "WMTRSTSRC_RESET_BT", -+ "WMTRSTSRC_RESET_FM", -+ "WMTRSTSRC_RESET_GPS", -+ "WMTRSTSRC_RESET_WIFI", -+ "WMTRSTSRC_RESET_STP", -+ "WMTRSTSRC_RESET_TEST" -+ }; -+ -+ if (src < WMTRSTSRC_RESET_MAX) -+ WMT_INFO_FUNC("reset source = %s\n", srcName[src]); -+ -+ if (WMTRSTSRC_RESET_TEST == src) { -+ pOp = wmt_lib_get_current_op(pDevWmt); -+ if (pOp && ((WMT_OPID_FUNC_ON == pOp->op.opId) -+ || (WMT_OPID_FUNC_OFF == pOp->op.opId))) { -+ WMT_INFO_FUNC("can't do reset by test src when func on/off\n"); -+ return -1; -+ } -+ } -+ /* <1> Consider the multi-context combo_rst case. */ -+ if (osal_test_and_set_bit(WMT_STAT_RST_ON, &pDevWmt->state)) { -+ retval = WMTRSTRET_ONGOING; -+ goto rstDone; -+ } -+ /* <2> Block all STP request */ -+ mtk_wcn_stp_enable(0); -+ -+ /* <3> RESET_START notification */ -+ bRet = wmt_cdev_rstmsg_snd(WMTRSTMSG_RESET_START); -+ if (bRet == MTK_WCN_BOOL_FALSE) { -+ WMT_ERR_FUNC("[whole chip reset] fail at wmt_lib_rstmsg_snd!\n"); -+ retval = WMTRSTRET_FAIL; -+ goto rstDone; -+ } -+ /* wakeup blocked opid */ -+ pOp = wmt_lib_get_current_op(pDevWmt); -+ if (osal_op_is_wait_for_signal(pOp)) -+ osal_op_raise_signal(pOp, -1); -+ -+ /* wakeup blocked cmd */ -+ wmt_dev_rx_event_cb(); -+ -+ /* <4> retry until reset flow successful */ -+ while (retries > 0) { -+ /* <4.1> reset combo hw */ -+ bRet = wmt_lib_hw_rst(); -+ if (bRet == MTK_WCN_BOOL_FALSE) { -+ WMT_ERR_FUNC("[whole chip reset] fail at wmt_lib_hw_rst!\n"); -+ retries--; -+ continue; -+ } -+ /* <4.2> reset driver/combo sw */ -+ bRet = wmt_lib_sw_rst(1); -+ if (bRet == MTK_WCN_BOOL_FALSE) { -+ WMT_ERR_FUNC("[whole chip reset] fail at wmt_lib_sw_rst!\n"); -+ retries--; -+ continue; -+ } -+ break; -+ } -+ -+ osal_clear_bit(WMT_STAT_RST_ON, &pDevWmt->state); -+ -+ if (bRet == MTK_WCN_BOOL_FALSE) { -+ rstMsg = WMTRSTMSG_RESET_END_FAIL; -+ WMT_WARN_FUNC("[whole chip reset] fail! retries = %d\n", RETRYTIMES - retries); -+ } else { -+ rstMsg = WMTRSTMSG_RESET_END; -+ WMT_INFO_FUNC("[whole chip reset] ok! retries = %d\n", RETRYTIMES - retries); -+ } -+ -+ /* <5> RESET_END notification */ -+ bRet = wmt_cdev_rstmsg_snd(rstMsg); -+ if (bRet == MTK_WCN_BOOL_FALSE) { -+ WMT_ERR_FUNC("[whole chip reset] fail at wmt_lib_rstmsg_snd!\n"); -+ retval = WMTRSTRET_FAIL; -+ } else { -+ retval = WMTRSTMSG_RESET_END == rstMsg ? WMTRSTRET_SUCCESS : WMTRSTRET_FAIL; -+ } -+ mtk_wcn_stp_coredump_start_ctrl(0); -+ mtk_wcn_stp_set_wmt_evt_err_trg_assert(0); -+rstDone: -+ if (osal_test_and_clear_bit(WMT_STAT_RST_ON, &pDevWmt->state)) -+ WMT_WARN_FUNC("[whole chip reset] retval = %d\n", retval); -+ -+ return retval; -+} -+ -+MTK_WCN_BOOL wmt_lib_msgcb_reg(ENUM_WMTDRV_TYPE_T eType, PF_WMT_CB pCb) -+{ -+ -+ MTK_WCN_BOOL bRet = MTK_WCN_BOOL_FALSE; -+ P_DEV_WMT pWmtDev = &gDevWmt; -+ -+ if (eType >= 0 && eType <= WMTDRV_TYPE_WIFI) { -+ WMT_DBG_FUNC("reg ok!\n"); -+ pWmtDev->rFdrvCb.fDrvRst[eType] = pCb; -+ bRet = MTK_WCN_BOOL_TRUE; -+ } else { -+ WMT_WARN_FUNC("reg fail!\n"); -+ } -+ -+ return bRet; -+} -+ -+MTK_WCN_BOOL wmt_lib_msgcb_unreg(ENUM_WMTDRV_TYPE_T eType) -+{ -+ MTK_WCN_BOOL bRet = MTK_WCN_BOOL_FALSE; -+ P_DEV_WMT pWmtDev = &gDevWmt; -+ -+ if (eType >= 0 && eType <= WMTDRV_TYPE_WIFI) { -+ WMT_DBG_FUNC("unreg ok!\n"); -+ pWmtDev->rFdrvCb.fDrvRst[eType] = NULL; -+ bRet = MTK_WCN_BOOL_TRUE; -+ } else { -+ WMT_WARN_FUNC("unreg fail!\n"); -+ } -+ -+ return bRet; -+} -+ -+UINT32 wmt_lib_dbg_level_set(UINT32 level) -+{ -+ gWmtDbgLvl = level > WMT_LOG_LOUD ? WMT_LOG_LOUD : level; -+ return 0; -+} -+ -+INT32 wmt_lib_set_stp_wmt_last_close(UINT32 value) -+{ -+ return mtk_wcn_stp_set_wmt_last_close(value); -+} -+ -+INT32 wmt_lib_notify_stp_sleep(void) -+{ -+ INT32 iRet = 0x0; -+ -+ iRet = wmt_lib_psm_lock_aquire(); -+ if (iRet) { -+ WMT_ERR_FUNC("--->lock psm_lock failed, iRet=%d\n", iRet); -+ return iRet; -+ } -+ -+ iRet = mtk_wcn_stp_notify_sleep_for_thermal(); -+ wmt_lib_psm_lock_release(); -+ -+ return iRet; -+} -+ -+VOID wmt_lib_set_patch_num(UINT32 num) -+{ -+ P_DEV_WMT pWmtDev = &gDevWmt; -+ -+ pWmtDev->patchNum = num; -+} -+ -+VOID wmt_lib_set_patch_info(P_WMT_PATCH_INFO pPatchinfo) -+{ -+ P_DEV_WMT pWmtDev = &gDevWmt; -+ -+ if (pPatchinfo) -+ pWmtDev->pWmtPatchInfo = pPatchinfo; -+ -+} -+ -+INT32 wmt_lib_set_current_op(P_DEV_WMT pWmtDev, P_OSAL_OP pOp) -+{ -+ if (pWmtDev) { -+ pWmtDev->pCurOP = pOp; -+ WMT_DBG_FUNC("pOp=0x%p\n", pOp); -+ return 0; -+ } -+ WMT_ERR_FUNC("Invalid pointer\n"); -+ return -1; -+} -+ -+P_OSAL_OP wmt_lib_get_current_op(P_DEV_WMT pWmtDev) -+{ -+ if (pWmtDev) -+ return pWmtDev->pCurOP; -+ -+ WMT_ERR_FUNC("Invalid pointer\n"); -+ return NULL; -+} -+ -+UINT8 *wmt_lib_get_fwinfor_from_emi(UINT8 section, UINT32 offset, UINT8 *buf, UINT32 len) -+{ -+ UINT8 *pAddr = NULL; -+ UINT32 sublen1 = 0; -+ UINT32 sublen2 = 0; -+ P_CONSYS_EMI_ADDR_INFO p_consys_info; -+ -+ p_consys_info = wmt_plat_get_emi_phy_add(); -+ osal_assert(p_consys_info); -+ -+ if (section == 0) { -+ pAddr = wmt_plat_get_emi_virt_add(0x0); -+ if (len > 1024) -+ len = 1024; -+ if (!pAddr) { -+ WMT_ERR_FUNC("wmt-lib: get EMI virtual base address fail\n"); -+ } else { -+ WMT_INFO_FUNC("vir addr(0x%p)\n", pAddr); -+ osal_memcpy(&buf[0], pAddr, len); -+ } -+ } else { -+ if (offset >= 0x7fff) -+ offset = 0x0; -+ -+ if (offset + len > 32768) { -+ pAddr = wmt_plat_get_emi_virt_add(offset + p_consys_info->paged_trace_off); -+ if (!pAddr) { -+ WMT_ERR_FUNC("wmt-lib: get part1 EMI virtual base address fail\n"); -+ } else { -+ WMT_INFO_FUNC("part1 vir addr(0x%p)\n", pAddr); -+ sublen1 = 0x7fff - offset; -+ osal_memcpy(&buf[0], pAddr, sublen1); -+ } -+ pAddr = wmt_plat_get_emi_virt_add(p_consys_info->paged_trace_off); -+ if (!pAddr) { -+ WMT_ERR_FUNC("wmt-lib: get part2 EMI virtual base address fail\n"); -+ } else { -+ WMT_INFO_FUNC("part2 vir addr(0x%p)\n", pAddr); -+ sublen2 = len - sublen1; -+ osal_memcpy(&buf[sublen1], pAddr, sublen2); -+ } -+ } else { -+ pAddr = wmt_plat_get_emi_virt_add(offset + p_consys_info->paged_trace_off); -+ if (!pAddr) { -+ WMT_ERR_FUNC("wmt-lib: get EMI virtual base address fail\n"); -+ } else { -+ WMT_INFO_FUNC("vir addr(0x%p)\n", pAddr); -+ osal_memcpy(&buf[0], pAddr, len); -+ } -+ } -+ } -+ -+ return 0; -+} -+ -+INT32 wmt_lib_poll_cpupcr(UINT32 count, UINT16 sleep, UINT16 toAee) -+{ -+ ENUM_STP_FW_ISSUE_TYPE issue_type; -+ -+ issue_type = STP_DBG_PROC_TEST; -+ -+ stp_dbg_poll_cpupcr(count, sleep, 1); -+ -+ if (toAee) { -+ stp_dbg_set_fw_info("STP ProcTest", osal_strlen("STP ProcTest"), issue_type); -+ osal_dbg_assert_aee("[SOC_CONSYS]ProcTest", -+ "**[WCN_ISSUE_INFO]STP Tx Timeout**\n Polling CPUPCR for FW debug usage\n"); -+ } else { -+ WMT_INFO_FUNC("wmt_lib:do not pass cpupcr to AEE\n"); -+ } -+ return 0; -+} -+ -+UINT8 *wmt_lib_get_cpupcr_xml_format(UINT32 *len) -+{ -+ PUINT8 temp; -+ UINT32 i = 0; -+ -+ osal_memset(&g_cpupcr_buf[0], 0, WMT_STP_CPUPCR_BUF_SIZE); -+ temp = g_cpupcr_buf; -+ stp_dbg_cpupcr_infor_format(&temp, len); -+ -+ pr_debug("print xml buffer,len(%d):\n\n", *len); -+ for (i = 0; i < *len; i++) -+ pr_cont("%c", g_cpupcr_buf[i]); -+ -+ return &g_cpupcr_buf[0]; -+} -+ -+UINT32 wmt_lib_set_host_assert_info(UINT32 type, UINT32 reason, UINT32 en) -+{ -+ return stp_dbg_set_host_assert_info(type, reason, en); -+} -+ -+INT32 wmt_lib_register_thermal_ctrl_cb(thermal_query_ctrl_cb thermal_ctrl) -+{ -+ wmt_plat_thermal_ctrl_cb_reg(thermal_ctrl); -+ return 0; -+} -+ -+INT8 wmt_lib_co_clock_get(void) -+{ -+ if (gDevWmt.rWmtGenConf.cfgExist) -+ return gDevWmt.rWmtGenConf.co_clock_flag; -+ else -+ return -1; -+} -+ -+#if CFG_WMT_PS_SUPPORT -+UINT32 wmt_lib_quick_sleep_ctrl(UINT32 en) -+{ -+ WMT_WARN_FUNC("%s quick sleep mode\n", en ? "enable" : "disable"); -+ g_quick_sleep_ctrl = en; -+ return 0; -+} -+#endif -+ -+#if CONSYS_ENALBE_SET_JTAG -+UINT32 wmt_lib_jtag_flag_set(UINT32 en) -+{ -+ return wmt_plat_jtag_flag_ctrl(en); -+} -+#endif -+ -+UINT32 wmt_lib_soc_set_wifiver(UINT32 wifiver) -+{ -+ return stp_dbg_set_wifiver(wifiver); -+} -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/include/stp_exp.h b/drivers/misc/mediatek/connectivity/common/conn_soc/include/stp_exp.h -new file mode 100644 -index 000000000000..b1b5285638f9 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/include/stp_exp.h -@@ -0,0 +1,252 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -+ -+/*! \file -+ \brief Declaration of library functions -+ -+ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. -+*/ -+ -+#ifndef _STP_EXP_H_ -+#define _STP_EXP_H_ -+ -+#include "osal_typedef.h" -+#include "osal.h" -+#include "wmt_stp_exp.h" -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+#ifndef MTK_WCN_WMT_STP_EXP_SYMBOL_ABSTRACT -+ -+#define BT_TASK_INDX (0) -+#define FM_TASK_INDX (1) -+#define GPS_TASK_INDX (2) -+#define WIFI_TASK_INDX (3) -+#define WMT_TASK_INDX (4) -+#define STP_TASK_INDX (5) -+#define INFO_TASK_INDX (6) -+#define ANT_TASK_INDX (7) -+#if CFG_WMT_LTE_COEX_HANDLING -+#define COEX_TASK_INDX (8) -+#define MTKSTP_MAX_TASK_NUM (9) -+#else -+#define MTKSTP_MAX_TASK_NUM (8) -+#endif -+ -+#define MTKSTP_BUFFER_SIZE (16384) /* Size of RX Queue */ -+ -+#define STP_EXP_HID_API_EXPORT 0 -+ -+#else -+ -+#define STP_EXP_HID_API_EXPORT 1 -+ -+#endif -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+#ifndef MTK_WCN_WMT_STP_EXP_SYMBOL_ABSTRACT -+typedef void (*MTK_WCN_STP_EVENT_CB) (void); -+typedef INT32 (*MTK_WCN_STP_IF_TX) (const UINT8 *data, const UINT32 size, UINT32 *written_size); -+/* export for HIF driver */ -+typedef void (*MTK_WCN_STP_IF_RX) (const UINT8 *data, INT32 size); -+ -+typedef enum { -+ STP_UART_IF_TX = 0, -+ STP_SDIO_IF_TX = 1, -+ STP_BTIF_IF_TX = 2, -+ STP_MAX_IF_TX -+} ENUM_STP_TX_IF_TYPE; -+#endif -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+#ifndef MTK_WCN_WMT_STP_EXP_SYMBOL_ABSTRACT -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_receive_data -+* DESCRIPTION -+* receive data from serial protocol engine -+* PARAMETERS -+* buffer [IN] data buffer -+* length [IN] data buffer length -+* RETURNS -+* INT32 >= 0: size of data received; < 0: error -+*****************************************************************************/ -+extern INT32 mtk_wcn_stp_receive_data(UINT8 *buffer, UINT32 length, UINT8 type); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_send_data -+* DESCRIPTION -+* subfunction send data through STP -+* PARAMETERS -+* buffer [IN] data buffer -+* length [IN] data buffer length -+* type [IN] subfunction type -+* RETURNS -+* INT32 >= 0: length transmitted; < 0: error -+*****************************************************************************/ -+extern INT32 mtk_wcn_stp_send_data(const PUINT8 buffer, const UINT32 length, const UINT8 type); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_is_rxqueue_empty -+* DESCRIPTION -+* Is certain rx queue empty? -+* PARAMETERS -+* type [IN] subfunction type -+* RETURNS -+* INT32 0: queue is NOT empyt; !0: queue is empty -+*****************************************************************************/ -+extern MTK_WCN_BOOL mtk_wcn_stp_is_rxqueue_empty(UINT8 type); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_is_enable -+* DESCRIPTION -+* Is STP ready? -+* PARAMETERS -+* none. -+* RETURNS -+* MTK_WCN_BOOL TRUE:ready, FALSE:not ready -+*****************************************************************************/ -+extern MTK_WCN_BOOL mtk_wcn_stp_is_ready(void); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_parser_data -+* DESCRIPTION -+* push data to serial transport protocol parser engine -+* PARAMETERS -+* buffer [IN] data buffer -+* length [IN] data buffer length -+* RETURNS -+* void -+*****************************************************************************/ -+extern int mtk_wcn_stp_parser_data(UINT8 *buffer, UINT32 length); -+ -+/***************************************************************************** -+* FUNCTION -+* set_bluetooth_rx_interface -+* DESCRIPTION -+* Set bluetooth rx interface -+* PARAMETERS -+* rx interface type -+* RETURNS -+* void -+*****************************************************************************/ -+extern void mtk_wcn_stp_set_bluez(MTK_WCN_BOOL sdio_flag); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_register_tx_event_cb -+* DESCRIPTION -+* regiter Tx event callback function -+* PARAMETERS -+* func -+* RETURNS -+* int: 0:successful , -1: fail -+*****************************************************************************/ -+extern int mtk_wcn_stp_register_tx_event_cb(int type, MTK_WCN_STP_EVENT_CB func); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_register_event_cb -+* DESCRIPTION -+* regiter Rx event callback function -+* PARAMETERS -+* func -+* RETURNS -+* int: 0:successful , -1: fail -+*****************************************************************************/ -+extern int mtk_wcn_stp_register_event_cb(int type, MTK_WCN_STP_EVENT_CB func); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_register_if_tx -+* DESCRIPTION -+* regiter Tx event callback function -+* PARAMETERS -+* stp_if: SDIO or UART, fnnc: Call back function -+* RETURNS -+* int: 0:successful , -1: fail -+*****************************************************************************/ -+extern int mtk_wcn_stp_register_if_tx(ENUM_STP_TX_IF_TYPE stp_if, MTK_WCN_STP_IF_TX func); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_register_if_rx -+* DESCRIPTION -+* regiter Rx event callback function -+* PARAMETERS -+* stp_if: SDIO or UART, fnnc: Call back function -+* RETURNS -+* int: 0:successful , -1: fail -+*****************************************************************************/ -+extern int mtk_wcn_stp_register_if_rx(MTK_WCN_STP_IF_RX func); -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#else -+extern INT32 _mtk_wcn_stp_receive_data(PUINT8 buffer, UINT32 length, UINT8 type); -+extern INT32 _mtk_wcn_stp_send_data_raw(const PUINT8 buffer, const UINT32 length, const UINT8 type); -+extern INT32 _mtk_wcn_stp_send_data(const PUINT8 buffer, const UINT32 length, const UINT8 type); -+extern MTK_WCN_BOOL _mtk_wcn_stp_is_rxqueue_empty(UINT8 type); -+extern MTK_WCN_BOOL _mtk_wcn_stp_is_ready(void); -+extern INT32 _mtk_wcn_stp_parser_data(UINT8 *buffer, UINT32 length); -+extern void _mtk_wcn_stp_set_bluez(MTK_WCN_BOOL sdio_flag); -+extern INT32 _mtk_wcn_stp_register_tx_event_cb(INT32 type, MTK_WCN_STP_EVENT_CB func); -+extern INT32 _mtk_wcn_stp_register_event_cb(INT32 type, MTK_WCN_STP_EVENT_CB func); -+extern INT32 _mtk_wcn_stp_register_if_tx(ENUM_STP_TX_IF_TYPE stp_if, MTK_WCN_STP_IF_TX func); -+extern INT32 _mtk_wcn_stp_register_if_rx(MTK_WCN_STP_IF_RX func); -+extern INT32 _mtk_wcn_stp_coredump_start_get(VOID); -+ -+#endif -+ -+#endif /* _WMT_EXP_H_ */ -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/include/wmt.h b/drivers/misc/mediatek/connectivity/common/conn_soc/include/wmt.h -new file mode 100644 -index 000000000000..6d10c3ff2659 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/include/wmt.h -@@ -0,0 +1,19 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -+ -+#ifndef _MTKWMT_H_ -+#define _MTKWMT_H_ -+#include "wmt_core.h" -+ -+#endif /*_MTKWMT_H_*/ -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/include/wmt_exp.h b/drivers/misc/mediatek/connectivity/common/conn_soc/include/wmt_exp.h -new file mode 100644 -index 000000000000..06238e07879f ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/include/wmt_exp.h -@@ -0,0 +1,329 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -+ -+/*! \file -+ \brief Declaration of library functions -+ -+ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. -+*/ -+ -+#ifndef _WMT_EXP_H_ -+#define _WMT_EXP_H_ -+ -+#include -+#include "osal.h" -+#include "wmt_plat.h" -+#include "wmt_stp_exp.h" -+/* not to reference to internal wmt */ -+/* #include "wmt_core.h" */ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+#if 1 /* moved from wmt_lib.h */ -+#ifndef DFT_TAG -+#define DFT_TAG "[WMT-DFT]" -+#endif -+ -+#define WMT_LOUD_FUNC(fmt, arg...) \ -+do { \ -+ if (gWmtDbgLvl >= WMT_LOG_LOUD) \ -+ osal_dbg_print(DFT_TAG "[L]%s:" fmt, __func__ , ##arg); \ -+} while (0) -+#define WMT_INFO_FUNC(fmt, arg...) \ -+do { \ -+ if (gWmtDbgLvl >= WMT_LOG_INFO) \ -+ osal_dbg_print(DFT_TAG "[I]%s:" fmt, __func__ , ##arg); \ -+} while (0) -+#define WMT_WARN_FUNC(fmt, arg...) \ -+do { \ -+ if (gWmtDbgLvl >= WMT_LOG_WARN) \ -+ osal_warn_print(DFT_TAG "[W]%s:" fmt, __func__ , ##arg); \ -+} while (0) -+#define WMT_ERR_FUNC(fmt, arg...) \ -+do { \ -+ if (gWmtDbgLvl >= WMT_LOG_ERR) \ -+ osal_err_print(DFT_TAG "[E]%s(%d):" fmt, __func__ , __LINE__, ##arg); \ -+} while (0) -+#define WMT_DBG_FUNC(fmt, arg...) \ -+do { \ -+ if (gWmtDbgLvl >= WMT_LOG_DBG) \ -+ osal_dbg_print(DFT_TAG "[D]%s:" fmt, __func__ , ##arg); \ -+} while (0) -+#define WMT_TRC_FUNC(f) \ -+do { \ -+ if (gWmtDbgLvl >= WMT_LOG_DBG) \ -+ osal_dbg_print(DFT_TAG "<%s> <%d>\n", __func__, __LINE__); \ -+} while (0) -+ -+#endif -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#if 1 /* moved from wmt_lib.h */ -+extern UINT32 gWmtDbgLvl; -+#endif -+extern OSAL_BIT_OP_VAR gBtWifiGpsState; -+extern OSAL_BIT_OP_VAR gGpsFmState; -+extern UINT32 gWifiProbed; -+extern MTK_WCN_BOOL g_pwr_off_flag; -+extern UINT32 g_IsNeedDoChipReset; -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+#if 1 /* moved from wmt_lib.h */ -+#define WMT_LOG_LOUD 4 -+#define WMT_LOG_DBG 3 -+#define WMT_LOG_INFO 2 -+#define WMT_LOG_WARN 1 -+#define WMT_LOG_ERR 0 -+#endif -+#define CFG_CORE_INTERNAL_TXRX 0 /*just do TX/RX in host side */ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+#ifndef MTK_WCN_WMT_STP_EXP_SYMBOL_ABSTRACT -+typedef enum _ENUM_WMTDRV_TYPE_T { -+ WMTDRV_TYPE_BT = 0, -+ WMTDRV_TYPE_FM = 1, -+ WMTDRV_TYPE_GPS = 2, -+ WMTDRV_TYPE_WIFI = 3, -+ WMTDRV_TYPE_WMT = 4, -+ WMTDRV_TYPE_STP = 5, -+ WMTDRV_TYPE_LPBK = 6, -+ WMTDRV_TYPE_COREDUMP = 7, -+ WMTDRV_TYPE_MAX -+} ENUM_WMTDRV_TYPE_T, *P_ENUM_WMTDRV_TYPE_T; -+ -+/* TODO: [ChangeFeature][GeorgeKuo] Reconsider usage of this type */ -+/* TODO: how do we extend for new chip and newer revision? */ -+/* TODO: This way is hard to extend */ -+typedef enum _ENUM_WMTHWVER_TYPE_T { -+ WMTHWVER_E1 = 0x0, -+ WMTHWVER_E2 = 0x1, -+ WMTHWVER_E3 = 0x2, -+ WMTHWVER_E4 = 0x3, -+ WMTHWVER_E5 = 0x4, -+ WMTHWVER_E6 = 0x5, -+ WMTHWVER_MAX, -+ WMTHWVER_INVALID = 0xff -+} ENUM_WMTHWVER_TYPE_T, *P_ENUM_WMTHWVER_TYPE_T; -+ -+typedef enum _ENUM_WMTDSNS_TYPE_T { -+ WMTDSNS_FM_DISABLE = 0, -+ WMTDSNS_FM_ENABLE = 1, -+ WMTDSNS_FM_GPS_DISABLE = 2, -+ WMTDSNS_FM_GPS_ENABLE = 3, -+ WMTDSNS_MAX -+} ENUM_WMTDSNS_TYPE_T, *P_ENUM_WMTDSNS_TYPE_T; -+ -+typedef enum _ENUM_WMTTHERM_TYPE_T { -+ WMTTHERM_ZERO = 0, -+ WMTTHERM_ENABLE = WMTTHERM_ZERO + 1, -+ WMTTHERM_READ = WMTTHERM_ENABLE + 1, -+ WMTTHERM_DISABLE = WMTTHERM_READ + 1, -+ WMTTHERM_MAX -+} ENUM_WMTTHERM_TYPE_T, *P_ENUM_WMTTHERM_TYPE_T; -+ -+typedef enum _ENUM_WMTMSG_TYPE_T { -+ WMTMSG_TYPE_POWER_ON = 0, -+ WMTMSG_TYPE_POWER_OFF = 1, -+ WMTMSG_TYPE_RESET = 2, -+ WMTMSG_TYPE_STP_RDY = 3, -+ WMTMSG_TYPE_HW_FUNC_ON = 4, -+ WMTMSG_TYPE_MAX -+} ENUM_WMTMSG_TYPE_T, *P_ENUM_WMTMSG_TYPE_T; -+ -+typedef void (*PF_WMT_CB) (ENUM_WMTDRV_TYPE_T, /* Source driver type */ -+ ENUM_WMTDRV_TYPE_T, /* Destination driver type */ -+ ENUM_WMTMSG_TYPE_T, /* Message type */ -+ VOID *, /* READ-ONLY buffer. Buffer is allocated and freed by WMT_drv. Client -+ can't touch this buffer after this function return. */ -+ UINT32 /* Buffer size in unit of byte */ -+); -+ -+typedef enum _SDIO_PS_OP { -+ OWN_SET = 0, -+ OWN_CLR = 1, -+ OWN_STATE = 2, -+} SDIO_PS_OP; -+ -+typedef INT32(*PF_WMT_SDIO_PSOP) (SDIO_PS_OP); -+ -+typedef enum _ENUM_WMTCHIN_TYPE_T { -+ WMTCHIN_CHIPID = 0x0, -+ WMTCHIN_HWVER = WMTCHIN_CHIPID + 1, -+ WMTCHIN_MAPPINGHWVER = WMTCHIN_HWVER + 1, -+ WMTCHIN_FWVER = WMTCHIN_MAPPINGHWVER + 1, -+ WMTCHIN_MAX, -+ -+} ENUM_WMT_CHIPINFO_TYPE_T, *P_ENUM_WMT_CHIPINFO_TYPE_T; -+ -+#endif -+ -+typedef enum _ENUM_WMTRSTMSG_TYPE_T { -+ WMTRSTMSG_RESET_START = 0x0, -+ WMTRSTMSG_RESET_END = 0x1, -+ WMTRSTMSG_RESET_END_FAIL = 0x2, -+ WMTRSTMSG_RESET_MAX, -+ WMTRSTMSG_RESET_INVALID = 0xff -+} ENUM_WMTRSTMSG_TYPE_T, *P_ENUM_WMTRSTMSG_TYPE_T; -+ -+typedef enum _ENUM_BT_GPS_ONOFF_STATE_T { -+ WMT_BT_ON = 0, -+ WMT_GPS_ON = 1, -+ WMT_WIFI_ON = 2, -+ WMT_FM_ON = 3, -+ WMT_BT_GPS_STATE_MAX, -+ WMT_BT_GPS_STATE_INVALID = 0xff -+} ENUM_BT_GPS_ONOFF_STATE_T, *P_ENUM_BT_GPS_ONOFF_STATE_T; -+ -+#if 1 /* moved from wmt_core.h */ -+typedef enum { -+ WMT_SDIO_SLOT_INVALID = 0, -+ WMT_SDIO_SLOT_SDIO1 = 1, /* Wi-Fi dedicated SDIO1 */ -+ WMT_SDIO_SLOT_SDIO2 = 2, -+ WMT_SDIO_SLOT_MAX -+} WMT_SDIO_SLOT_NUM; -+ -+typedef enum { -+ WMT_SDIO_FUNC_STP = 0, -+ WMT_SDIO_FUNC_WIFI = 1, -+ WMT_SDIO_FUNC_MAX -+} WMT_SDIO_FUNC_TYPE; -+#endif -+ -+typedef INT32(*wmt_wlan_probe_cb) (VOID); -+typedef INT32(*wmt_wlan_remove_cb) (VOID); -+typedef INT32(*wmt_wlan_bus_cnt_get_cb) (VOID); -+typedef INT32(*wmt_wlan_bus_cnt_clr_cb) (VOID); -+ -+typedef struct _MTK_WCN_WMT_WLAN_CB_INFO { -+ wmt_wlan_probe_cb wlan_probe_cb; -+ wmt_wlan_remove_cb wlan_remove_cb; -+ wmt_wlan_bus_cnt_get_cb wlan_bus_cnt_get_cb; -+ wmt_wlan_bus_cnt_clr_cb wlan_bus_cnt_clr_cb; -+} MTK_WCN_WMT_WLAN_CB_INFO, *P_MTK_WCN_WMT_WLAN_CB_INFO; -+ -+#ifdef CONFIG_MTK_COMBO_ANT -+typedef enum _ENUM_WMT_ANT_RAM_CTRL_T { -+ WMT_ANT_RAM_GET_STATUS = 0, -+ WMT_ANT_RAM_DOWNLOAD = WMT_ANT_RAM_GET_STATUS + 1, -+ WMT_ANT_RAM_CTRL_MAX -+} ENUM_WMT_ANT_RAM_CTRL, *P_ENUM_WMT_ANT_RAM_CTRL; -+ -+typedef enum _ENUM_WMT_ANT_RAM_SEQ_T { -+ WMT_ANT_RAM_START_PKT = 1, -+ WMT_ANT_RAM_CONTINUE_PKT = WMT_ANT_RAM_START_PKT + 1, -+ WMT_ANT_RAM_END_PKT = WMT_ANT_RAM_CONTINUE_PKT + 1, -+ WMT_ANT_RAM_SEQ_MAX -+} ENUM_WMT_ANT_RAM_SEQ, *P_ENUM_WMT_ANT_RAM_SEQ; -+ -+typedef enum _ENUM_WMT_ANT_RAM_STATUS_T { -+ WMT_ANT_RAM_NOT_EXIST = 0, -+ WMT_ANT_RAM_EXIST = WMT_ANT_RAM_NOT_EXIST + 1, -+ WMT_ANT_RAM_DOWN_OK = WMT_ANT_RAM_EXIST + 1, -+ WMT_ANT_RAM_DOWN_FAIL = WMT_ANT_RAM_DOWN_OK + 1, -+ WMT_ANT_RAM_PARA_ERR = WMT_ANT_RAM_DOWN_FAIL + 1, -+ WMT_ANT_RAM_OP_ERR = WMT_ANT_RAM_PARA_ERR + 1, -+ WMT_ANT_RAM_MAX -+} ENUM_WMT_ANT_RAM_STATUS, *P_ENUM_WMT_ANT_RAM_STATUS; -+#endif -+ -+extern INT32 mtk_wcn_wmt_wlan_reg(P_MTK_WCN_WMT_WLAN_CB_INFO pWmtWlanCbInfo); -+extern INT32 mtk_wcn_wmt_wlan_unreg(VOID); -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+extern wmt_wlan_probe_cb mtk_wcn_wlan_probe; -+extern wmt_wlan_remove_cb mtk_wcn_wlan_remove; -+extern wmt_wlan_bus_cnt_get_cb mtk_wcn_wlan_bus_tx_cnt; -+extern wmt_wlan_bus_cnt_clr_cb mtk_wcn_wlan_bus_tx_cnt_clr; -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+/*subsystem function ctrl APIs*/ -+extern MTK_WCN_BOOL mtk_wcn_wmt_assert(ENUM_WMTDRV_TYPE_T type, UINT32 reason); -+ -+#ifndef MTK_WCN_WMT_STP_EXP_SYMBOL_ABSTRACT -+#define WMT_EXP_HID_API_EXPORT 0 -+ -+extern MTK_WCN_BOOL mtk_wcn_wmt_func_off(ENUM_WMTDRV_TYPE_T type); -+ -+extern MTK_WCN_BOOL mtk_wcn_wmt_func_on(ENUM_WMTDRV_TYPE_T type); -+ -+extern MTK_WCN_BOOL mtk_wcn_wmt_dsns_ctrl(ENUM_WMTDSNS_TYPE_T eType); -+ -+extern MTK_WCN_BOOL mtk_wcn_wmt_assert(ENUM_WMTDRV_TYPE_T type, UINT32 reason); -+ -+extern INT32 mtk_wcn_wmt_msgcb_reg(ENUM_WMTDRV_TYPE_T eType, PF_WMT_CB pCb); -+ -+extern INT32 mtk_wcn_wmt_msgcb_unreg(ENUM_WMTDRV_TYPE_T eType); -+ -+extern INT32 mtk_wcn_stp_wmt_sdio_op_reg(PF_WMT_SDIO_PSOP own_cb); -+ -+extern INT32 mtk_wcn_stp_wmt_sdio_host_awake(VOID); -+/* -+return value: -+enable/disable thermal sensor function: true(1)/false(0) -+read thermal sensor function: thermal value -+ -+*/ -+extern INT8 mtk_wcn_wmt_therm_ctrl(ENUM_WMTTHERM_TYPE_T eType); -+ -+extern ENUM_WMTHWVER_TYPE_T mtk_wcn_wmt_hwver_get(VOID); -+ -+#else -+#define WMT_EXP_HID_API_EXPORT 1 -+#endif -+ -+#ifdef CONFIG_MTK_COMBO_ANT -+extern ENUM_WMT_ANT_RAM_STATUS mtk_wcn_wmt_ant_ram_ctrl(ENUM_WMT_ANT_RAM_CTRL ctrlId, PUINT8 pBuf, -+ UINT32 length, ENUM_WMT_ANT_RAM_SEQ seq); -+#endif -+extern INT32 wmt_lib_set_aif(CMB_STUB_AIF_X aif, MTK_WCN_BOOL share); /* set AUDIO interface options */ -+extern VOID wmt_lib_ps_irq_cb(VOID); -+ -+extern VOID mtk_wcn_wmt_func_ctrl_for_plat(UINT32 on, ENUM_WMTDRV_TYPE_T type); -+ -+extern INT32 mtk_wcn_wmt_system_state_reset(VOID); -+extern MTK_WCN_BOOL mtk_wcn_set_connsys_power_off_flag(MTK_WCN_BOOL value); -+#ifdef MTK_WCN_WMT_STP_EXP_SYMBOL_ABSTRACT -+extern VOID mtk_wcn_wmt_exp_init(VOID); -+extern VOID mtk_wcn_wmt_exp_deinit(VOID); -+#endif -+extern INT8 mtk_wcn_wmt_co_clock_flag_get(VOID); -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif /* _WMT_EXP_H_ */ -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/include/wmt_plat.h b/drivers/misc/mediatek/connectivity/common/conn_soc/include/wmt_plat.h -new file mode 100644 -index 000000000000..075496cac54f ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/include/wmt_plat.h -@@ -0,0 +1,295 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -+ -+/*! \file -+ \brief Declaration of library functions -+ -+ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. -+*/ -+ -+#ifndef _WMT_PLAT_H_ -+#define _WMT_PLAT_H_ -+#include "osal_typedef.h" -+#include "stp_exp.h" -+#include -+ -+/* #include "mtk_wcn_consys_hw.h" */ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+#if 1 /* moved from wmt_exp.h */ -+#ifndef DFT_TAG -+#define DFT_TAG "[WMT-DFT]" -+#endif -+ -+#define WMT_PLAT_LOG_LOUD 4 -+#define WMT_PLAT_LOG_DBG 3 -+#define WMT_PLAT_LOG_INFO 2 -+#define WMT_PLAT_LOG_WARN 1 -+#define WMT_PLAT_LOG_ERR 0 -+ -+extern UINT32 wmtPlatLogLvl; -+ -+#define WMT_PLAT_LOUD_FUNC(fmt, arg...) \ -+do { \ -+ if (wmtPlatLogLvl >= WMT_PLAT_LOG_LOUD) \ -+ pr_debug(DFT_TAG "[L]%s:" fmt, __func__ , ##arg); \ -+} while (0) -+#define WMT_PLAT_INFO_FUNC(fmt, arg...) \ -+do { \ -+ if (wmtPlatLogLvl >= WMT_PLAT_LOG_INFO) \ -+ pr_debug(DFT_TAG "[I]%s:" fmt, __func__ , ##arg); \ -+} while (0) -+#define WMT_PLAT_WARN_FUNC(fmt, arg...) \ -+do { \ -+ if (wmtPlatLogLvl >= WMT_PLAT_LOG_WARN) \ -+ pr_warn(DFT_TAG "[W]%s:" fmt, __func__ , ##arg); \ -+} while (0) -+#define WMT_PLAT_ERR_FUNC(fmt, arg...) \ -+do { \ -+ if (wmtPlatLogLvl >= WMT_PLAT_LOG_ERR) \ -+ pr_err(DFT_TAG "[E]%s(%d):" fmt, __func__ , __LINE__, ##arg); \ -+} while (0) -+#define WMT_PLAT_DBG_FUNC(fmt, arg...) \ -+do { \ -+ if (wmtPlatLogLvl >= WMT_PLAT_LOG_DBG) \ -+ pr_debug(DFT_TAG "[D]%s:" fmt, __func__ , ##arg); \ -+} while (0) -+ -+#endif -+ -+#define CFG_WMT_PS_SUPPORT 1 /* moved from wmt_exp.h */ -+ -+#define CFG_WMT_DUMP_INT_STATUS 0 -+#define CONSYS_ENALBE_SET_JTAG 1 -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+typedef enum _ENUM_FUNC_STATE_ { -+ FUNC_ON = 0, -+ FUNC_OFF = 1, -+ FUNC_RST = 2, -+ FUNC_STAT = 3, -+ FUNC_CTRL_MAX, -+} ENUM_FUNC_STATE, *P_ENUM_FUNC_STATE; -+ -+typedef enum _ENUM_PIN_ID_ { -+ PIN_BGF_EINT = 0, -+ PIN_I2S_GRP = 1, -+ PIN_GPS_SYNC = 2, -+ PIN_GPS_LNA = 3, -+#if CFG_WMT_LTE_COEX_HANDLING -+ PIN_TDM_REQ = 4, -+#endif -+ PIN_ID_MAX -+} ENUM_PIN_ID, *P_ENUM_PIN_ID; -+ -+typedef enum _ENUM_PIN_STATE_ { -+ PIN_STA_INIT = 0, -+ PIN_STA_OUT_L = 1, -+ PIN_STA_OUT_H = 2, -+ PIN_STA_IN_L = 3, -+ PIN_STA_MUX = 4, -+ PIN_STA_EINT_EN = 5, -+ PIN_STA_EINT_DIS = 6, -+ PIN_STA_DEINIT = 7, -+ PIN_STA_SHOW = 8, -+ PIN_STA_MAX -+} ENUM_PIN_STATE, *P_ENUM_PIN_STATE; -+ -+typedef enum _CMB_IF_TYPE_ { -+ CMB_IF_UART = 0, -+ CMB_IF_WIFI_SDIO = 1, -+ CMB_IF_BGF_SDIO = 2, -+ CMB_IF_BGWF_SDIO = 3, -+ CMB_IF_TYPE_MAX -+} CMB_IF_TYPE, *P_CMB_IF_TYPE; -+ -+typedef INT32(*fp_set_pin) (ENUM_PIN_STATE); -+ -+typedef enum _ENUM_WL_OP_ { -+ WL_OP_GET = 0, -+ WL_OP_PUT = 1, -+ WL_OP_MAX -+} ENUM_WL_OP, *P_ENUM_WL_OP; -+ -+typedef enum _ENUM_PALDO_TYPE_ { -+ BT_PALDO = 0, -+ WIFI_PALDO = 1, -+ FM_PALDO = 2, -+ GPS_PALDO = 3, -+ PMIC_CHIPID_PALDO = 4, -+ WIFI_5G_PALDO = 5, -+ PALDO_TYPE_MAX -+} ENUM_PALDO_TYPE, *P_ENUM_PALDO_TYPE; -+ -+typedef enum _ENUM_PALDO_OP_ { -+ PALDO_OFF = 0, -+ PALDO_ON = 1, -+ PALDO_OP_MAX -+} ENUM_PALDO_OP, *P_ENUM_PALDO_OP; -+ -+typedef enum _ENUM_HOST_DUMP_STATE_T { -+ STP_HOST_DUMP_NOT_START = 0, -+ STP_HOST_DUMP_GET = 1, -+ STP_HOST_DUMP_GET_DONE = 2, -+ STP_HOST_DUMP_END = 3, -+ STP_HOST_DUMP_MAX -+} ENUM_HOST_DUMP_STATE, *P_ENUM_HOST_DUMP_STATE_T; -+ -+typedef enum _ENUM_FORCE_TRG_ASSERT_T { -+ STP_FORCE_TRG_ASSERT_EMI = 0, -+ STP_FORCE_TRG_ASSERT_DEBUG_PIN = 1, -+ STP_FORCE_TRG_ASSERT_MAX = 2 -+} ENUM_FORCE_TRG_ASSERT_T, *P_ENUM_FORCE_TRG_ASSERT_T; -+ -+typedef enum _ENUM_CHIP_DUMP_STATE_T { -+ STP_CHIP_DUMP_NOT_START = 0, -+ STP_CHIP_DUMP_PUT = 1, -+ STP_CHIP_DUMP_PUT_DONE = 2, -+ STP_CHIP_DUMP_END = 3, -+ STP_CHIP_DUMP_MAX -+} ENUM_CHIP_DUMP_STATE, *P_ENUM_CHIP_DUMP_STATE_T; -+ -+typedef struct _EMI_CTRL_STATE_OFFSET_ { -+ UINT32 emi_apmem_ctrl_state; -+ UINT32 emi_apmem_ctrl_host_sync_state; -+ UINT32 emi_apmem_ctrl_host_sync_num; -+ UINT32 emi_apmem_ctrl_chip_sync_state; -+ UINT32 emi_apmem_ctrl_chip_sync_num; -+ UINT32 emi_apmem_ctrl_chip_sync_addr; -+ UINT32 emi_apmem_ctrl_chip_sync_len; -+ UINT32 emi_apmem_ctrl_chip_print_buff_start; -+ UINT32 emi_apmem_ctrl_chip_print_buff_len; -+ UINT32 emi_apmem_ctrl_chip_print_buff_idx; -+ UINT32 emi_apmem_ctrl_chip_int_status; -+ UINT32 emi_apmem_ctrl_chip_paded_dump_end; -+ UINT32 emi_apmem_ctrl_host_outband_assert_w1; -+ UINT32 emi_apmem_ctrl_chip_page_dump_num; -+} EMI_CTRL_STATE_OFFSET, *P_EMI_CTRL_STATE_OFFSET; -+ -+typedef struct _BGF_IRQ_BALANCE_ { -+ UINT32 counter; -+ unsigned long flags; -+ spinlock_t lock; -+} BGF_IRQ_BALANCE, *P_BGF_IRQ_BALANCE; -+ -+typedef struct _CONSYS_EMI_ADDR_INFO_ { -+ UINT32 emi_phy_addr; -+ UINT32 paged_trace_off; -+ UINT32 paged_dump_off; -+ UINT32 full_dump_off; -+ P_EMI_CTRL_STATE_OFFSET p_ecso; -+} CONSYS_EMI_ADDR_INFO, *P_CONSYS_EMI_ADDR_INFO; -+ -+typedef struct _GPIO_TDM_REQ_INFO_ { -+ UINT32 ant_sel_index; -+ UINT32 gpio_number; -+ UINT32 cr_address; -+} GPIO_TDM_REQ_INFO, *P_GPIO_TDM_REQ_INFO; -+ -+typedef VOID(*irq_cb) (VOID); -+typedef INT32(*device_audio_if_cb) (CMB_STUB_AIF_X aif, MTK_WCN_BOOL share); -+typedef VOID(*func_ctrl_cb) (UINT32 on, UINT32 type); -+typedef long (*thermal_query_ctrl_cb) (VOID); -+typedef INT32(*deep_idle_ctrl_cb) (UINT32); -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+extern UINT32 gWmtDbgLvl; -+extern struct device *wmt_dev; -+#ifdef CFG_WMT_READ_EFUSE_VCN33 -+extern INT32 wmt_set_pmic_voltage(UINT32 level); -+#endif -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+INT32 wmt_plat_init(UINT32 co_clock_type); -+ -+INT32 wmt_plat_deinit(VOID); -+ -+INT32 wmt_plat_pwr_ctrl(ENUM_FUNC_STATE state); -+ -+INT32 wmt_plat_gpio_ctrl(ENUM_PIN_ID id, ENUM_PIN_STATE state); -+ -+INT32 wmt_plat_eirq_ctrl(ENUM_PIN_ID id, ENUM_PIN_STATE state); -+ -+INT32 wmt_plat_wake_lock_ctrl(ENUM_WL_OP opId); -+ -+INT32 wmt_plat_audio_ctrl(CMB_STUB_AIF_X state, CMB_STUB_AIF_CTRL ctrl); -+ -+VOID wmt_plat_irq_cb_reg(irq_cb bgf_irq_cb); -+VOID wmt_plat_aif_cb_reg(device_audio_if_cb aif_ctrl_cb); -+VOID wmt_plat_func_ctrl_cb_reg(func_ctrl_cb subsys_func_ctrl); -+VOID wmt_plat_thermal_ctrl_cb_reg(thermal_query_ctrl_cb thermal_query_ctrl); -+VOID wmt_plat_deep_idle_ctrl_cb_reg(deep_idle_ctrl_cb deep_idle_ctrl); -+ -+INT32 wmt_plat_soc_paldo_ctrl(ENUM_PALDO_TYPE ePt, ENUM_PALDO_OP ePo); -+UINT8 *wmt_plat_get_emi_virt_add(UINT32 offset); -+#if CONSYS_ENALBE_SET_JTAG -+UINT32 wmt_plat_jtag_flag_ctrl(UINT32 en); -+#endif -+#if CFG_WMT_DUMP_INT_STATUS -+VOID wmt_plat_BGF_irq_dump_status(VOID); -+MTK_WCN_BOOL wmt_plat_dump_BGF_irq_status(VOID); -+#endif -+P_CONSYS_EMI_ADDR_INFO wmt_plat_get_emi_phy_add(VOID); -+UINT32 wmt_plat_read_cpupcr(VOID); -+UINT32 wmt_plat_read_dmaregs(UINT32); -+INT32 wmt_plat_set_host_dump_state(ENUM_HOST_DUMP_STATE state); -+UINT32 wmt_plat_force_trigger_assert(ENUM_FORCE_TRG_ASSERT_T type); -+INT32 wmt_plat_update_host_sync_num(VOID); -+INT32 wmt_plat_get_dump_info(UINT32 offset); -+UINT32 wmt_plat_get_soc_chipid(VOID); -+INT32 wmt_plat_set_dbg_mode(UINT32 flag); -+VOID wmt_plat_set_dynamic_dumpmem(UINT32 *buf); -+#if CFG_WMT_LTE_COEX_HANDLING -+INT32 wmt_plat_get_tdm_antsel_index(VOID); -+#endif -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif /* _WMT_PLAT_H_ */ -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/linux/Makefile b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/Makefile -new file mode 100644 -index 000000000000..905207118938 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/Makefile -@@ -0,0 +1,6 @@ -+ifeq ($(CONFIG_MTK_COMBO), y) -+ -+obj-y += pub/ -+obj-y += pri/ -+ -+endif -\ No newline at end of file -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/linux/include/bgw_desense.h b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/include/bgw_desense.h -new file mode 100644 -index 000000000000..95d1ab02a9fa ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/include/bgw_desense.h -@@ -0,0 +1,74 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -+ -+#ifndef __BGW_DESENSE_H_ -+#define __BGW_DESENSE_H_ -+ -+#ifdef MSG -+#undef MSG -+#endif -+ -+#ifdef ERR -+#undef ERR -+#endif -+ -+#define PFX1 "[BWG] " -+#define MSG(fmt, arg ...) pr_debug(PFX1 "[D]%s: " fmt, __func__ , ##arg) -+#define ERR(fmt, arg ...) pr_debug(PFX1 "[D]%s: " fmt, __func__ , ##arg) -+ -+#ifdef NETLINK_TEST -+#undef NETLINK_TEST -+#endif -+ -+#define NETLINK_TEST 17 -+ -+#ifdef MAX_NL_MSG_LEN -+#undef MAX_NL_MSG_LEN -+#endif -+ -+#define MAX_NL_MSG_LEN 1024 -+ -+ -+#ifdef ON -+#undef ON -+#endif -+#ifdef OFF -+#undef OFF -+#endif -+#ifdef ACK -+#undef ACK -+#endif -+ -+#define ON 1 -+#define OFF 0 -+#define ACK 2 -+ -+/* -+used send command to native process -+ -+parameter: command could be macro ON: enable co-exist; OFF: disable co-exist; -+ACK: after get native process init message send ACK -+ -+*/ -+extern void send_command_to_daemon(const int command); -+ -+/* -+before use kernel socket, please call init socket first -+return value: 0: ok; -1: fail -+*/ -+extern int bgw_init_socket(void); -+ -+extern void bgw_destroy_netlink_kernel(void); -+ -+#endif -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/linux/include/osal.h b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/include/osal.h -new file mode 100644 -index 000000000000..493a4dd16f23 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/include/osal.h -@@ -0,0 +1,348 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -+ -+/*! \file -+ \brief Declaration of library functions -+ -+ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. -+*/ -+ -+#ifndef _OSAL_H_ -+#define _OSAL_H_ -+ -+#include -+#include -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+#define OS_BIT_OPS_SUPPORT 1 -+ -+#define _osal_inline_ inline -+ -+#define MAX_THREAD_NAME_LEN 16 -+#define MAX_WAKE_LOCK_NAME_LEN 16 -+#define OSAL_OP_BUF_SIZE 64 -+ -+#if (defined(CONFIG_MTK_GMO_RAM_OPTIMIZE) && !defined(CONFIG_MT_ENG_BUILD)) -+#define OSAL_OP_DATA_SIZE 8 -+#else -+#define OSAL_OP_DATA_SIZE 32 -+#endif -+ -+#define DBG_LOG_STR_SIZE 256 -+ -+#define osal_sizeof(x) sizeof(x) -+ -+#define osal_array_size(x) (sizeof(x)/sizeof(x[0])) -+ -+#ifndef NAME_MAX -+#define NAME_MAX 256 -+#endif -+ -+#define WMT_OP_BIT(x) (0x1UL << x) -+#define WMT_OP_HIF_BIT WMT_OP_BIT(0) -+ -+#define RB_SIZE(prb) ((prb)->size) -+#define RB_MASK(prb) (RB_SIZE(prb) - 1) -+#define RB_COUNT(prb) ((prb)->write - (prb)->read) -+#define RB_FULL(prb) (RB_COUNT(prb) >= RB_SIZE(prb)) -+#define RB_EMPTY(prb) ((prb)->write == (prb)->read) -+ -+#define RB_INIT(prb, qsize) \ -+do { \ -+ (prb)->read = (prb)->write = 0; \ -+ (prb)->size = (qsize); \ -+} while (0) -+ -+#define RB_PUT(prb, value) \ -+do { \ -+ if (!RB_FULL(prb)) { \ -+ (prb)->queue[(prb)->write & RB_MASK(prb)] = value; \ -+ ++((prb)->write); \ -+ } \ -+ else { \ -+ osal_assert(!RB_FULL(prb)); \ -+ } \ -+} while (0) -+ -+#define RB_GET(prb, value) \ -+do { \ -+ if (!RB_EMPTY(prb)) { \ -+ value = (prb)->queue[(prb)->read & RB_MASK(prb)]; \ -+ ++((prb)->read); \ -+ if (RB_EMPTY(prb)) { \ -+ (prb)->read = (prb)->write = 0; \ -+ } \ -+ } \ -+ else { \ -+ value = NULL; \ -+ osal_assert(!RB_EMPTY(prb)); \ -+ } \ -+} while (0) -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+typedef VOID(*P_TIMEOUT_HANDLER) (unsigned long); -+typedef INT32(*P_COND) (VOID *); -+ -+typedef struct _OSAL_TIMER_ { -+ struct timer_list timer; -+ P_TIMEOUT_HANDLER timeoutHandler; -+ unsigned long timeroutHandlerData; -+} OSAL_TIMER, *P_OSAL_TIMER; -+ -+typedef struct _OSAL_UNSLEEPABLE_LOCK_ { -+ spinlock_t lock; -+ unsigned long flag; -+} OSAL_UNSLEEPABLE_LOCK, *P_OSAL_UNSLEEPABLE_LOCK; -+ -+typedef struct _OSAL_SLEEPABLE_LOCK_ { -+ struct mutex lock; -+} OSAL_SLEEPABLE_LOCK, *P_OSAL_SLEEPABLE_LOCK; -+ -+typedef struct _OSAL_SIGNAL_ { -+ struct completion comp; -+ UINT32 timeoutValue; -+} OSAL_SIGNAL, *P_OSAL_SIGNAL; -+ -+typedef struct _OSAL_EVENT_ { -+ wait_queue_head_t waitQueue; -+/* VOID *pWaitQueueData; */ -+ UINT32 timeoutValue; -+ INT32 waitFlag; -+ -+} OSAL_EVENT, *P_OSAL_EVENT; -+ -+typedef struct _OSAL_THREAD_ { -+ struct task_struct *pThread; -+ VOID *pThreadFunc; -+ VOID *pThreadData; -+ char threadName[MAX_THREAD_NAME_LEN]; -+} OSAL_THREAD, *P_OSAL_THREAD; -+ -+typedef struct _OSAL_FIFO_ { -+ /*fifo definition */ -+ VOID *pFifoBody; -+ spinlock_t fifoSpinlock; -+ /*fifo operations */ -+ INT32 (*FifoInit)(struct _OSAL_FIFO_ *pFifo, UINT8 *buf, UINT32); -+ INT32 (*FifoDeInit)(struct _OSAL_FIFO_ *pFifo); -+ INT32 (*FifoReset)(struct _OSAL_FIFO_ *pFifo); -+ INT32 (*FifoSz)(struct _OSAL_FIFO_ *pFifo); -+ INT32 (*FifoAvailSz)(struct _OSAL_FIFO_ *pFifo); -+ INT32 (*FifoLen)(struct _OSAL_FIFO_ *pFifo); -+ INT32 (*FifoIsEmpty)(struct _OSAL_FIFO_ *pFifo); -+ INT32 (*FifoIsFull)(struct _OSAL_FIFO_ *pFifo); -+ INT32 (*FifoDataIn)(struct _OSAL_FIFO_ *pFifo, const VOID *buf, UINT32 len); -+ INT32 (*FifoDataOut)(struct _OSAL_FIFO_ *pFifo, void *buf, UINT32 len); -+} OSAL_FIFO, *P_OSAL_FIFO; -+ -+typedef struct firmware osal_firmware; -+ -+typedef struct _OSAL_OP_DAT { -+ UINT32 opId; /* Event ID */ -+ UINT32 u4InfoBit; /* Reserved */ -+ SIZE_T au4OpData[OSAL_OP_DATA_SIZE]; /* OP Data */ -+} OSAL_OP_DAT, *P_OSAL_OP_DAT; -+ -+typedef struct _OSAL_LXOP_ { -+ OSAL_OP_DAT op; -+ OSAL_SIGNAL signal; -+ INT32 result; -+} OSAL_OP, *P_OSAL_OP; -+ -+typedef struct _OSAL_LXOP_Q { -+ OSAL_SLEEPABLE_LOCK sLock; -+ UINT32 write; -+ UINT32 read; -+ UINT32 size; -+ P_OSAL_OP queue[OSAL_OP_BUF_SIZE]; -+} OSAL_OP_Q, *P_OSAL_OP_Q; -+ -+typedef struct _OSAL_WAKE_LOCK_ { -+ #ifdef CONFIG_PM_WAKELOCKS -+ struct wakeup_source wake_lock; -+ #else -+ struct wake_lock wake_lock; -+ #endif -+ UINT8 name[MAX_WAKE_LOCK_NAME_LEN]; -+} OSAL_WAKE_LOCK, *P_OSAL_WAKE_LOCK; -+#if 1 -+typedef struct _OSAL_BIT_OP_VAR_ { -+ unsigned long data; -+ OSAL_UNSLEEPABLE_LOCK opLock; -+} OSAL_BIT_OP_VAR, *P_OSAL_BIT_OP_VAR; -+#else -+#define OSAL_BIT_OP_VAR unsigned long -+#define P_OSAL_BIT_OP_VAR unsigned long * -+ -+#endif -+typedef UINT32(*P_OSAL_EVENT_CHECKER) (P_OSAL_THREAD pThread); -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+extern UINT32 osal_strlen(const char *str); -+extern INT32 osal_strcmp(const char *dst, const char *src); -+extern INT32 osal_strncmp(const char *dst, const char *src, UINT32 len); -+extern char *osal_strcpy(char *dst, const char *src); -+extern char *osal_strncpy(char *dst, const char *src, UINT32 len); -+extern char *osal_strcat(char *dst, const char *src); -+extern char *osal_strncat(char *dst, const char *src, UINT32 len); -+extern char *osal_strchr(const char *str, UINT8 c); -+extern char *osal_strsep(char **str, const char *c); -+extern int osal_strtol(const char *str, UINT32 adecimal, long *res); -+extern INT32 osal_snprintf(char *buf, UINT32 len, const char *fmt, ...); -+extern char *osal_strstr(char *str1, const char *str2); -+ -+extern INT32 osal_err_print(const char *str, ...); -+extern INT32 osal_dbg_print(const char *str, ...); -+extern INT32 osal_warn_print(const char *str, ...); -+ -+extern INT32 osal_dbg_assert(INT32 expr, const char *file, INT32 line); -+extern INT32 osal_sprintf(char *str, const char *format, ...); -+extern VOID *osal_malloc(UINT32 size); -+extern VOID osal_free(const VOID *dst); -+extern VOID *osal_memset(VOID *buf, INT32 i, UINT32 len); -+extern VOID *osal_memcpy(VOID *dst, const VOID *src, UINT32 len); -+extern INT32 osal_memcmp(const VOID *buf1, const VOID *buf2, UINT32 len); -+ -+extern INT32 osal_sleep_ms(UINT32 ms); -+extern INT32 osal_udelay(UINT32 us); -+extern INT32 osal_timer_create(P_OSAL_TIMER); -+extern INT32 osal_timer_start(P_OSAL_TIMER, UINT32); -+extern INT32 osal_timer_stop(P_OSAL_TIMER); -+extern INT32 osal_timer_stop_sync(P_OSAL_TIMER pTimer); -+extern INT32 osal_timer_modify(P_OSAL_TIMER, UINT32); -+extern INT32 osal_timer_delete(P_OSAL_TIMER); -+ -+extern INT32 osal_fifo_init(P_OSAL_FIFO pFifo, UINT8 *buffer, UINT32 size); -+extern VOID osal_fifo_deinit(P_OSAL_FIFO pFifo); -+extern INT32 osal_fifo_reset(P_OSAL_FIFO pFifo); -+extern UINT32 osal_fifo_in(P_OSAL_FIFO pFifo, PUINT8 buffer, UINT32 size); -+extern UINT32 osal_fifo_out(P_OSAL_FIFO pFifo, PUINT8 buffer, UINT32 size); -+extern UINT32 osal_fifo_len(P_OSAL_FIFO pFifo); -+extern UINT32 osal_fifo_sz(P_OSAL_FIFO pFifo); -+extern UINT32 osal_fifo_avail(P_OSAL_FIFO pFifo); -+extern UINT32 osal_fifo_is_empty(P_OSAL_FIFO pFifo); -+extern UINT32 osal_fifo_is_full(P_OSAL_FIFO pFifo); -+ -+extern INT32 osal_wake_lock_init(P_OSAL_WAKE_LOCK plock); -+extern INT32 osal_wake_lock(P_OSAL_WAKE_LOCK plock); -+extern INT32 osal_wake_unlock(P_OSAL_WAKE_LOCK plock); -+extern INT32 osal_wake_lock_count(P_OSAL_WAKE_LOCK plock); -+extern INT32 osal_wake_lock_deinit(P_OSAL_WAKE_LOCK plock); -+ -+#if defined(CONFIG_PROVE_LOCKING) -+#define osal_unsleepable_lock_init(l) { spin_lock_init(&((l)->lock)); } -+#else -+extern INT32 osal_unsleepable_lock_init(P_OSAL_UNSLEEPABLE_LOCK); -+#endif -+extern INT32 osal_lock_unsleepable_lock(P_OSAL_UNSLEEPABLE_LOCK); -+extern INT32 osal_unlock_unsleepable_lock(P_OSAL_UNSLEEPABLE_LOCK); -+extern INT32 osal_unsleepable_lock_deinit(P_OSAL_UNSLEEPABLE_LOCK); -+ -+#if defined(CONFIG_PROVE_LOCKING) -+#define osal_sleepable_lock_init(l) { mutex_init(&((l)->lock)); } -+#else -+extern INT32 osal_sleepable_lock_init(P_OSAL_SLEEPABLE_LOCK); -+#endif -+extern INT32 osal_lock_sleepable_lock(P_OSAL_SLEEPABLE_LOCK); -+extern INT32 osal_unlock_sleepable_lock(P_OSAL_SLEEPABLE_LOCK); -+extern INT32 osal_sleepable_lock_deinit(P_OSAL_SLEEPABLE_LOCK); -+ -+extern INT32 osal_signal_init(P_OSAL_SIGNAL); -+extern INT32 osal_wait_for_signal(P_OSAL_SIGNAL); -+extern INT32 osal_wait_for_signal_timeout(P_OSAL_SIGNAL); -+extern INT32 osal_raise_signal(P_OSAL_SIGNAL); -+extern INT32 osal_signal_deinit(P_OSAL_SIGNAL); -+ -+extern INT32 osal_event_init(P_OSAL_EVENT); -+extern INT32 osal_wait_for_event(P_OSAL_EVENT, P_COND, void *); -+extern INT32 osal_wait_for_event_timeout(P_OSAL_EVENT, P_COND, void *); -+extern INT32 osal_trigger_event(P_OSAL_EVENT); -+ -+extern INT32 osal_event_deinit(P_OSAL_EVENT); -+ -+extern INT32 osal_thread_create(P_OSAL_THREAD); -+extern INT32 osal_thread_run(P_OSAL_THREAD); -+extern INT32 osal_thread_should_stop(P_OSAL_THREAD); -+extern INT32 osal_thread_stop(P_OSAL_THREAD); -+/*extern INT32 osal_thread_wait_for_event(P_OSAL_THREAD, P_OSAL_EVENT);*/ -+extern INT32 osal_thread_wait_for_event(P_OSAL_THREAD, P_OSAL_EVENT, P_OSAL_EVENT_CHECKER); -+/*check pOsalLxOp and OSAL_THREAD_SHOULD_STOP*/ -+extern INT32 osal_thread_destroy(P_OSAL_THREAD); -+ -+extern INT32 osal_clear_bit(UINT32 bitOffset, P_OSAL_BIT_OP_VAR pData); -+extern INT32 osal_set_bit(UINT32 bitOffset, P_OSAL_BIT_OP_VAR pData); -+extern INT32 osal_test_bit(UINT32 bitOffset, P_OSAL_BIT_OP_VAR pData); -+extern INT32 osal_test_and_clear_bit(UINT32 bitOffset, P_OSAL_BIT_OP_VAR pData); -+extern INT32 osal_test_and_set_bit(UINT32 bitOffset, P_OSAL_BIT_OP_VAR pData); -+ -+extern INT32 osal_dbg_assert_aee(const char *module, const char *detail_description); -+extern INT32 osal_gettimeofday(PINT32 sec, PINT32 usec); -+extern INT32 osal_printtimeofday(const PUINT8 prefix); -+ -+extern VOID osal_buffer_dump(const UINT8 *buf, const UINT8 *title, UINT32 len, UINT32 limit); -+ -+extern UINT32 osal_op_get_id(P_OSAL_OP pOp); -+extern MTK_WCN_BOOL osal_op_is_wait_for_signal(P_OSAL_OP pOp); -+extern VOID osal_op_raise_signal(P_OSAL_OP pOp, INT32 result); -+extern VOID osal_set_op_result(P_OSAL_OP pOp, INT32 result); -+extern UINT16 osal_crc16(const UINT8 *buffer, const UINT32 length); -+extern VOID osal_thread_show_stack(P_OSAL_THREAD pThread); -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#define osal_assert(condition) \ -+do { \ -+ if (!(condition)) \ -+ osal_err_print("%s, %d, (%s)\n", __FILE__, __LINE__, #condition); \ -+} while (0) -+ -+#endif /* _OSAL_H_ */ -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/linux/include/osal_typedef.h b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/include/osal_typedef.h -new file mode 100644 -index 000000000000..b3a9c57e062d ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/include/osal_typedef.h -@@ -0,0 +1,90 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -+ -+/*! \file -+ \brief Declaration of library functions -+ -+ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. -+*/ -+ -+#ifndef _OSAL_TYPEDEF_H_ -+#define _OSAL_TYPEDEF_H_ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#ifdef CONFIG_EARLYSUSPEND -+#include -+#else -+#include -+#endif -+#include -+#include -+#ifdef WMT_PLAT_ALPS -+#include -+#endif -+#include -+#ifdef CONFIG_PM_WAKELOCKS -+#include -+#else -+#include -+#endif -+#include -+ -+#ifndef _TYPEDEFS_H /*fix redifine */ -+typedef char INT8; -+#endif -+ -+typedef void VOID, *PVOID, **PPVOID; -+typedef char *PINT8, **PPINT8; -+typedef short INT16, *PINT16, **PPINT16; -+typedef int INT32, *PINT32, **PPINT32; -+typedef long long INT64, *PINT64, **PPINT64; -+ -+typedef unsigned char UINT8, *PUINT8, **PPUINT8; -+typedef unsigned short UINT16, *PUINT16, **PPUINT16; -+typedef unsigned int UINT32, *PUINT32, **PPUINT32; -+typedef unsigned long long UINT64, *PUINT64, **PPUINT64; -+ -+typedef size_t SIZE_T; -+ -+typedef int MTK_WCN_BOOL; -+#ifndef MTK_WCN_BOOL_TRUE -+#define MTK_WCN_BOOL_FALSE ((MTK_WCN_BOOL) 0) -+#define MTK_WCN_BOOL_TRUE ((MTK_WCN_BOOL) 1) -+#endif -+ -+#endif /*_OSAL_TYPEDEF_H_*/ -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/linux/include/wmt_idc.h b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/include/wmt_idc.h -new file mode 100644 -index 000000000000..17be778484c1 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/include/wmt_idc.h -@@ -0,0 +1,97 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -+ -+#ifndef _WMT_IDC_H_ -+#define _WMT_IDC_H_ -+ -+#include "osal_typedef.h" -+#include "osal.h" -+#include "wmt_stp_exp.h" -+ -+#if CFG_WMT_LTE_COEX_HANDLING -+ -+#include "wmt_stp_exp.h" -+#include "conn_md_exp.h" -+ -+#define LTE_IDC_BUFFER_MAX_SIZE 1024 -+/*comment from firmware owner,max pckage num is 5,but should not happened*/ -+#define WMT_IDC_RX_MAX_LEN 384 -+#define LTE_MSG_ID_OFFSET 0x30 -+ -+typedef enum { -+ WMT_IDC_TX_OPCODE_MIN = 0, -+ WMT_IDC_TX_OPCODE_LTE_PARA = 0x0a, -+ WMT_IDC_TX_OPCODE_LTE_FREQ = 0x0b, -+ WMT_IDC_TX_OPCODE_WIFI_MAX_POWER = 0x0c, -+ WMT_IDC_TX_OPCODE_DEBUG_MONITOR = 0x0e, -+ WMT_IDC_TX_OPCODE_SPLIT_FILTER = 0x0f, -+ WMT_IDC_TX_OPCODE_LTE_CONNECTION_STAS = 0x16, -+ WMT_IDC_TX_OPCODE_LTE_HW_IF_INDICATION = 0x17, -+ WMT_IDC_TX_OPCODE_LTE_INDICATION = 0x20, -+ WMT_IDC_TX_OPCODE_MAX -+} WMT_IDC_TX_OPCODE; -+ -+typedef enum { -+ WMT_IDC_RX_OPCODE_BTWF_DEF_PARA = 0x0, -+ WMT_IDC_RX_OPCODE_BTWF_CHAN_RAN = 0x1, -+ /* WMT_IDC_RX_OPCODE_TDM_REQ = 0x10, */ -+ WMT_IDC_RX_OPCODE_DEBUG_MONITOR = 0x02, -+ WMT_IDC_RX_OPCODE_LTE_FREQ_IDX_TABLE = 0x03, -+ WMT_IDC_RX_OPCODE_BTWF_PROFILE_IND = 0x04, -+ WMT_IDC_RX_OPCODE_UART_PIN_SEL = 0x05, -+ WMT_IDC_RX_OPCODE_MAX -+} WMT_IDC_RX_OPCODE; -+ -+#if (CFG_WMT_LTE_ENABLE_MSGID_MAPPING == 0) -+typedef enum { -+ IPC_L4C_MSG_ID_INVALID = IPC_L4C_MSG_ID_BEGIN, -+ IPC_L4C_MSG_ID_END, -+ IPC_EL1_MSG_ID_INVALID = IPC_EL1_MSG_ID_BEGIN, -+ /* below are EL1 IPC messages sent from AP */ -+ IPC_MSG_ID_EL1_LTE_TX_ALLOW_IND, -+ IPC_MSG_ID_EL1_WIFIBT_OPER_DEFAULT_PARAM_IND, -+ IPC_MSG_ID_EL1_WIFIBT_OPER_FREQ_IND, -+ IPC_MSG_ID_EL1_WIFIBT_FREQ_IDX_TABLE_IND, -+ IPC_MSG_ID_EL1_WIFIBT_PROFILE_IND, -+ -+ /* below are EL1 messages sent to AP */ -+ IPC_MSG_ID_EL1_LTE_DEFAULT_PARAM_IND, -+ IPC_MSG_ID_EL1_LTE_OPER_FREQ_PARAM_IND, -+ IPC_MSG_ID_EL1_WIFI_MAX_PWR_IND, -+ IPC_MSG_ID_EL1_LTE_TX_IND, -+ IPC_MSG_ID_EL1_LTE_CONNECTION_STATUS_IND, -+ IPC_MSG_ID_EL1_PIN_TYPE_IND, -+ IPC_MSG_ID_EL1_LTE_HW_INTERFACE_IND, -+ IPC_MSG_ID_EL1_DUMMY13_IND, -+ IPC_MSG_ID_EL1_DUMMY14_IND, -+ IPC_MSG_ID_EL1_DUMMY15_IND, -+ IPC_EL1_MSG_ID_END, -+} IPC_MSG_ID_CODE; -+#endif -+ -+typedef struct _MTK_WCN_WMT_IDC_INFO_ { -+ ipc_ilm_t iit; -+ CONN_MD_BRIDGE_OPS ops; -+ UINT8 buffer[LTE_IDC_BUFFER_MAX_SIZE]; -+} MTK_WCN_WMT_IDC_INFO, *P_MTK_WCN_WMT_IDC_INFO; -+ -+extern INT32 wmt_idc_init(VOID); -+extern INT32 wmt_idc_deinit(VOID); -+extern INT32 wmt_idc_msg_from_lte_handing(ipc_ilm_t *ilm); -+extern INT32 wmt_idc_msg_to_lte_handing(VOID); -+extern UINT32 wmt_idc_msg_to_lte_handing_for_test(UINT8 *p_buf, UINT32 len); -+ -+#endif /* endif CFG_WMT_LTE_COEX_HANDLING */ -+ -+#endif /* _WMT_IDC_H_ */ -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/Makefile b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/Makefile -new file mode 100644 -index 000000000000..ff0f0b0aefda ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/Makefile -@@ -0,0 +1,21 @@ -+ifeq ($(CONFIG_MTK_COMBO), y) -+ -+ccflags-y += \ -+ -I$(src)/../../linux/include \ -+ -I$(src)/../../linux/pri/include \ -+ -I$(src)/../../core/include \ -+ -I$(src)/../../include \ -+ -I$(src)/../include \ -+ -I$(src)/../../../common_detect \ -+ -I$(srctree)/drivers/misc/mediatek/btif/common/inc \ -+ -I$(srctree)/drivers/misc/mediatek/mach/$(MTK_PLATFORM)/include/mach -+ -+ccflags-y += -DWMT_CREATE_NODE_DYNAMIC=1 -+ -+obj-y += stp_btif.o \ -+ stp_dbg.o \ -+ stp_exp.o \ -+ wmt_dev.o \ -+ wmt_exp.o -+ -+endif -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/include/stp_btif.h b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/include/stp_btif.h -new file mode 100644 -index 000000000000..3730fbba6928 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/include/stp_btif.h -@@ -0,0 +1,31 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -+ -+#ifndef _STP_BTIF_H_ -+#define _STP_BTIF_H_ -+ -+#include "osal_typedef.h" -+#include "mtk_btif_exp.h" -+ -+extern INT32 mtk_wcn_consys_stp_btif_open(VOID); -+extern INT32 mtk_wcn_consys_stp_btif_close(VOID); -+extern INT32 mtk_wcn_consys_stp_btif_rx_cb_register(MTK_WCN_BTIF_RX_CB rx_cb); -+extern INT32 mtk_wcn_consys_stp_btif_tx(const UINT8 *pBuf, const UINT32 len, UINT32 *written_len); -+extern INT32 mtk_wcn_consys_stp_btif_wakeup(VOID); -+extern INT32 mtk_wcn_consys_stp_btif_dpidle_ctrl(ENUM_BTIF_DPIDLE_CTRL en_flag); -+extern INT32 mtk_wcn_consys_stp_btif_lpbk_ctrl(ENUM_BTIF_LPBK_MODE mode); -+extern INT32 mtk_wcn_consys_stp_btif_logger_ctrl(ENUM_BTIF_DBG_ID flag); -+extern MTK_WCN_BOOL mtk_wcn_consys_stp_btif_parser_wmt_evt(const UINT8 *str, UINT32 len); -+ -+#endif -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/include/stp_dbg.h b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/include/stp_dbg.h -new file mode 100644 -index 000000000000..de5684a16853 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/include/stp_dbg.h -@@ -0,0 +1,316 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -+ -+#ifndef _STP_DEBUG_H_ -+#define _STP_DEBUG_H_ -+ -+#include -+#include "osal.h" -+ -+#define CONFIG_LOG_STP_INTERNAL -+ -+#if 1 /* #ifndef CONFIG_LOG_STP_INTERNAL */ -+#define STP_PKT_SZ 16 -+#define STP_DMP_SZ 2048 -+#define STP_PKT_NO 2048 -+ -+#define STP_DBG_LOG_ENTRY_NUM 60 -+#define STP_DBG_LOG_ENTRY_SZ 64 -+ -+#else -+ -+#define STP_PKT_SZ 16 -+#define STP_DMP_SZ 16 -+#define STP_PKT_NO 16 -+ -+#define STP_DBG_LOG_ENTRY_NUM 28 -+#define STP_DBG_LOG_ENTRY_SZ 64 -+ -+#endif -+ -+typedef enum { -+ STP_DBG_EN = 0, -+ STP_DBG_PKT = 1, -+ STP_DBG_DR = 2, -+ STP_DBG_FW_ASSERT = 3, -+ STP_DBG_FW_LOG = 4, -+ STP_DBG_FW_DMP = 5, -+ STP_DBG_MAX -+} STP_DBG_OP_T; -+ -+typedef enum { -+ STP_DBG_PKT_FIL_ALL = 0, -+ STP_DBG_PKT_FIL_BT = 1, -+ STP_DBG_PKT_FIL_GPS = 2, -+ STP_DBG_PKT_FIL_FM = 3, -+ STP_DBG_PKT_FIL_WMT = 4, -+ STP_DBG_PKT_FIL_MAX -+} STP_DBG_PKT_FIL_T; -+ -+static char *const gStpDbgType[] = { -+ "< BT>", -+ "< FM>", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "" -+}; -+ -+typedef enum { -+ STP_DBG_DR_MAX = 0, -+} STP_DBG_DR_FIL_T; -+ -+typedef enum { -+ STP_DBG_FW_MAX = 0, -+} STP_DBG_FW_FIL_T; -+ -+typedef enum { -+ PKT_DIR_RX = 0, -+ PKT_DIR_TX -+} STP_DBG_PKT_DIR_T; -+ -+/*simple log system ++*/ -+ -+typedef struct { -+ /*type: 0. pkt trace 1. fw info -+ * 2. assert info 3. trace32 dump . -+ * -1. linked to the the previous -+ */ -+ int id; -+ int len; -+ char buffer[STP_DBG_LOG_ENTRY_SZ]; -+} MTKSTP_LOG_ENTRY_T; -+ -+typedef struct log_sys { -+ MTKSTP_LOG_ENTRY_T queue[STP_DBG_LOG_ENTRY_NUM]; -+ unsigned int size; -+ unsigned int in; -+ unsigned int out; -+ spinlock_t lock; -+} MTKSTP_LOG_SYS_T; -+/*--*/ -+ -+typedef struct stp_dbg_pkt_hdr { -+ /* packet information */ -+ unsigned int sec; -+ unsigned int usec; -+ unsigned int dbg_type; -+ unsigned int dmy; -+ unsigned int no; -+ unsigned int dir; -+ -+ /* packet content */ -+ unsigned int type; -+ unsigned int len; -+ unsigned int ack; -+ unsigned int seq; -+ unsigned int chs; -+ unsigned int crc; -+} STP_DBG_HDR_T; -+ -+typedef struct stp_dbg_pkt { -+ struct stp_dbg_pkt_hdr hdr; -+ unsigned char raw[STP_DMP_SZ]; -+} STP_PACKET_T; -+ -+typedef struct mtkstp_dbg_t { -+ /*log_sys */ -+ int pkt_trace_no; -+ void *btm; -+ int is_enable; -+ MTKSTP_LOG_SYS_T *logsys; -+} MTKSTP_DBG_T; -+ -+/* extern void aed_combo_exception(const int *, int, const int *, int, const char *); */ -+ -+#define STP_CORE_DUMP_TIMEOUT (5*60*1000) /* default 5minutes */ -+#define STP_OJB_NAME_SZ 20 -+#define STP_CORE_DUMP_INFO_SZ 500 -+#define STP_CORE_DUMP_INIT_SIZE 1 -+typedef enum wcn_compress_algorithm_t { -+ GZIP = 0, -+ BZIP2 = 1, -+ RAR = 2, -+ LMA = 3, -+ MAX -+} WCN_COMPRESS_ALG_T; -+ -+typedef INT32 (*COMPRESS_HANDLER) (void *worker, UINT8 *in_buf, INT32 in_sz, UINT8 *out_buf, INT32 *out_sz, -+ INT32 finish); -+typedef struct wcn_compressor_t { -+ /* current object name */ -+ UINT8 name[STP_OJB_NAME_SZ + 1]; -+ -+ /* buffer for raw data, named L1 */ -+ PUINT8 L1_buf; -+ INT32 L1_buf_sz; -+ INT32 L1_pos; -+ -+ /* target buffer, named L2 */ -+ PUINT8 L2_buf; -+ INT32 L2_buf_sz; -+ INT32 L2_pos; -+ -+ /* compress state */ -+ UINT8 f_done; -+ UINT16 reserved; -+ UINT32 uncomp_size; -+ UINT32 crc32; -+ -+ /* compress algorithm */ -+ UINT8 f_compress_en; -+ WCN_COMPRESS_ALG_T compress_type; -+ void *worker; -+ COMPRESS_HANDLER handler; -+} WCN_COMPRESSOR_T, *P_WCN_COMPRESSOR_T; -+ -+P_WCN_COMPRESSOR_T wcn_compressor_init(PUINT8 name, INT32 L1_buf_sz, INT32 L2_buf_sz); -+INT32 wcn_compressor_deinit(P_WCN_COMPRESSOR_T compressor); -+INT32 wcn_compressor_in(P_WCN_COMPRESSOR_T compressor, PUINT8 buf, INT32 len, INT32 finish); -+INT32 wcn_compressor_out(P_WCN_COMPRESSOR_T compressor, PUINT8 *pbuf, PINT32 len); -+INT32 wcn_compressor_reset(P_WCN_COMPRESSOR_T compressor, UINT8 enable, WCN_COMPRESS_ALG_T type); -+ -+typedef enum core_dump_state_t { -+ CORE_DUMP_INIT = 0, -+ CORE_DUMP_DOING, -+ CORE_DUMP_TIMEOUT, -+ CORE_DUMP_DONE, -+ CORE_DUMP_MAX -+} CORE_DUMP_STA; -+ -+typedef struct core_dump_t { -+ /* compress dump data and buffered */ -+ P_WCN_COMPRESSOR_T compressor; -+ -+ /* timer for monitor timeout */ -+ OSAL_TIMER dmp_timer; -+ UINT32 timeout; -+ -+ OSAL_SLEEPABLE_LOCK dmp_lock; -+ -+ /* state machine for core dump flow */ -+ CORE_DUMP_STA sm; -+ -+ /* dump info */ -+ INT8 info[STP_CORE_DUMP_INFO_SZ + 1]; -+} WCN_CORE_DUMP_T, *P_WCN_CORE_DUMP_T; -+ -+typedef enum _ENUM_STP_FW_ISSUE_TYPE_ { -+ STP_FW_ISSUE_TYPE_INVALID = 0x0, -+ STP_FW_ASSERT_ISSUE = 0x1, -+ STP_FW_NOACK_ISSUE = 0x2, -+ STP_FW_WARM_RST_ISSUE = 0x3, -+ STP_DBG_PROC_TEST = 0x4, -+ STP_HOST_TRIGGER_FW_ASSERT = 0x5, -+ STP_HOST_TRIGGER_ASSERT_TIMEOUT = 0x6, -+ STP_FW_ISSUE_TYPE_MAX -+} ENUM_STP_FW_ISSUE_TYPE, *P_ENUM_STP_FW_ISSUE_TYPE; -+ -+/* this was added for support dmareg's issue */ -+typedef enum _ENUM_DMA_ISSUE_TYPE_ { -+ CONNSYS_CLK_GATE_STATUS = 0x00, -+ CONSYS_EMI_STATUS, -+ SYSRAM1, -+ SYSRAM2, -+ SYSRAM3, -+ DMA_REGS_MAX -+} ENUM_DMA_ISSUE_TYPE; -+#define STP_PATCH_TIME_SIZE 12 -+#define STP_DBG_CPUPCR_NUM 512 -+#define STP_DBG_DMAREGS_NUM 16 -+#define STP_PATCH_BRANCH_SZIE 8 -+#define STP_ASSERT_INFO_SIZE 64 -+#define STP_DBG_ROM_VER_SIZE 4 -+#define STP_ASSERT_TYPE_SIZE 32 -+ -+typedef struct stp_dbg_host_assert_t { -+ UINT32 drv_type; -+ UINT32 reason; -+ UINT32 assert_from_host; -+} STP_DBG_HOST_ASSERT_T, *P_STP_DBG_HOST_ASSERT_T; -+ -+typedef struct stp_dbg_cpupcr_t { -+ UINT32 chipId; -+ UINT8 romVer[STP_DBG_ROM_VER_SIZE]; -+ UINT8 patchVer[STP_PATCH_TIME_SIZE]; -+ UINT8 branchVer[STP_PATCH_BRANCH_SZIE]; -+ UINT32 wifiVer; -+ UINT32 count; -+ UINT32 stop_flag; -+ UINT32 buffer[STP_DBG_CPUPCR_NUM]; -+ UINT8 assert_info[STP_ASSERT_INFO_SIZE]; -+ UINT32 fwTaskId; -+ UINT32 fwRrq; -+ UINT32 fwIsr; -+ STP_DBG_HOST_ASSERT_T host_assert_info; -+ UINT8 assert_type[STP_ASSERT_TYPE_SIZE]; -+ ENUM_STP_FW_ISSUE_TYPE issue_type; -+ OSAL_SLEEPABLE_LOCK lock; -+} STP_DBG_CPUPCR_T, *P_STP_DBG_CPUPCR_T; -+ -+typedef struct stp_dbg_dmaregs_t { -+ UINT32 count; -+ UINT32 dmaIssue[DMA_REGS_MAX][STP_DBG_DMAREGS_NUM]; -+ OSAL_SLEEPABLE_LOCK lock; -+} STP_DBG_DMAREGS_T, *P_STP_DBG_DMAREGS_T; -+ -+typedef enum _ENUM_ASSERT_INFO_PARSER_TYPE_ { -+ STP_DBG_ASSERT_INFO = 0x0, -+ STP_DBG_FW_TASK_ID = 0x1, -+ STP_DBG_FW_ISR = 0x2, -+ STP_DBG_FW_IRQ = 0x3, -+ STP_DBG_ASSERT_TYPE = 0x4, -+ STP_DBG_PARSER_TYPE_MAX -+} ENUM_ASSERT_INFO_PARSER_TYPE, *P_ENUM_ASSERT_INFO_PARSER_TYPE; -+ -+P_WCN_CORE_DUMP_T wcn_core_dump_init(UINT32 packet_num, UINT32 timeout); -+INT32 wcn_core_dump_deinit(P_WCN_CORE_DUMP_T dmp); -+INT32 wcn_core_dump_in(P_WCN_CORE_DUMP_T dmp, PUINT8 buf, INT32 len); -+INT32 wcn_core_dump_out(P_WCN_CORE_DUMP_T dmp, PUINT8 *pbuf, PINT32 len); -+INT32 wcn_core_dump_reset(P_WCN_CORE_DUMP_T dmp, UINT32 timeout); -+INT32 wcn_core_dump_timeout(void); -+INT32 wcn_wmtd_timeout_collect_ftrace(void); -+ -+extern INT32 wcn_core_dump_init_gcoredump(UINT32 packet_num, UINT32 timeout); -+extern INT32 wcn_core_dump_deinit_gcoredump(VOID); -+extern INT32 wcn_core_dump_flush(INT32 rst, MTK_WCN_BOOL is_coredump_timeout); -+extern int stp_dbg_enable(MTKSTP_DBG_T *stp_dbg); -+extern int stp_dbg_disable(MTKSTP_DBG_T *stp_dbg); -+extern MTKSTP_DBG_T *stp_dbg_init(void *); -+extern int stp_dbg_deinit(MTKSTP_DBG_T *stp_dbg); -+extern int stp_dbg_dmp_out_ex(char *buf, int *len); -+extern int stp_dbg_dmp_out(MTKSTP_DBG_T *stp_dbg, char *buf, int *len); -+extern int stp_dbg_dmp_printk(MTKSTP_DBG_T *stp_dbg); -+extern char stp_dbg_nl_send(PINT8 aucMsg, UINT8 cmd, INT32 len); -+ -+extern INT32 stp_dbg_aee_send(unsigned char *aucMsg, INT32 len, INT32 cmd); -+extern INT32 _stp_btm_put_emi_dump_to_nl(PUINT8 data_buf, INT32 dump_len); -+extern int -+stp_dbg_log_pkt(MTKSTP_DBG_T *stp_dbg, -+ int dbg_type, int type, int ack_no, int seq_no, int crc, int dir, int len, const unsigned char *body); -+extern int stp_dbg_log_ctrl(unsigned int on); -+extern INT32 stp_dbg_poll_cpupcr(UINT32 times, UINT32 sleep, UINT32 cmd); -+extern INT32 stp_dbg_poll_dmaregs(UINT32 times, UINT32 sleep); -+extern INT32 stp_dbg_poll_cuppcr_ctrl(UINT32 en); -+extern INT32 stp_dbg_set_version_info(UINT32 chipid, PUINT8 pRomVer, PUINT8 pPatchVer, -+ PUINT8 pPatchBrh); -+extern INT32 stp_dbg_set_wifiver(UINT32 wifiver); -+extern INT32 stp_dbg_cpupcr_infor_format(PPUINT8 buf, PUINT32 len); -+extern INT32 stp_dbg_set_fw_info(PUINT8 assert_info, UINT32 len, ENUM_STP_FW_ISSUE_TYPE issue_type); -+extern INT32 stp_dbg_set_host_assert_info(UINT32 drv_type, UINT32 reason, UINT32 en); -+extern UINT32 stp_dbg_get_host_trigger_assert(VOID); -+#endif /* end of _STP_DEBUG_H_ */ -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/include/wmt_dev.h b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/include/wmt_dev.h -new file mode 100644 -index 000000000000..5788eb355549 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/include/wmt_dev.h -@@ -0,0 +1,71 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -+ -+#ifndef _WMT_DEV_H_ -+#define _WMT_DEV_H_ -+ -+#include "osal.h" -+ -+#define STP_UART_FULL 0x01 -+#define STP_UART_MAND 0x02 -+#define STP_BTIF_FULL 0x03 -+#define STP_SDIO 0x04 -+ -+#define CFG_WMT_DBG_SUPPORT 1 /* support wmt_dbg or not */ -+#define CFG_WMT_PROC_FOR_AEE 1 -+ -+extern VOID wmt_dev_rx_event_cb(VOID); -+extern INT32 wmt_dev_rx_timeout(P_OSAL_EVENT pEvent); -+extern INT32 wmt_dev_patch_get(PUINT8 pPatchName, osal_firmware **ppPatch, INT32 padSzBuf); -+extern INT32 wmt_dev_patch_put(osal_firmware **ppPatch); -+extern VOID wmt_dev_patch_info_free(VOID); -+extern VOID wmt_dev_send_cmd_to_daemon(UINT32 cmd); -+extern MTK_WCN_BOOL wmt_dev_get_early_suspend_state(VOID); -+ -+#if CFG_WMT_DBG_SUPPORT -+typedef struct _COEX_BUF { -+ UINT8 buffer[128]; -+ INT32 availSize; -+} COEX_BUF, *P_COEX_BUF; -+ -+typedef enum _ENUM_CMD_TYPE_T { -+ WMTDRV_CMD_ASSERT = 0, -+ WMTDRV_CMD_EXCEPTION = 1, -+ WMTDRV_CMD_COEXDBG_00 = 2, -+ WMTDRV_CMD_COEXDBG_01 = 3, -+ WMTDRV_CMD_COEXDBG_02 = 4, -+ WMTDRV_CMD_COEXDBG_03 = 5, -+ WMTDRV_CMD_COEXDBG_04 = 6, -+ WMTDRV_CMD_COEXDBG_05 = 7, -+ WMTDRV_CMD_COEXDBG_06 = 8, -+ WMTDRV_CMD_COEXDBG_07 = 9, -+ WMTDRV_CMD_COEXDBG_08 = 10, -+ WMTDRV_CMD_COEXDBG_09 = 11, -+ WMTDRV_CMD_COEXDBG_10 = 12, -+ WMTDRV_CMD_COEXDBG_11 = 13, -+ WMTDRV_CMD_COEXDBG_12 = 14, -+ WMTDRV_CMD_COEXDBG_13 = 15, -+ WMTDRV_CMD_COEXDBG_14 = 16, -+ WMTDRV_CMD_COEXDBG_15 = 17, -+ WMTDRV_CMD_NOACK_TEST = 18, -+ WMTDRV_CMD_WARNRST_TEST = 19, -+ WMTDRV_CMD_FWTRACE_TEST = 20, -+ WMTDRV_CMD_MAX -+} ENUM_WMTDRV_CMD_T, *P_ENUM_WMTDRV_CMD_T; -+ -+#endif -+ -+typedef INT32(*WMT_DEV_DBG_FUNC) (INT32 par1, INT32 par2, INT32 par3); -+ -+#endif /*_WMT_DEV_H_*/ -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/stp_btif.c b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/stp_btif.c -new file mode 100644 -index 000000000000..76debb4674f9 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/stp_btif.c -@@ -0,0 +1,279 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -+ -+/*file: stp_btif, mainly control stp & btif interaction*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+#ifdef DFT_TAG -+#undef DFT_TAG -+#endif -+#define DFT_TAG "[STP-BTIF]" -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "osal_typedef.h" -+#include "wmt_exp.h" -+#include "stp_exp.h" -+#include "stp_btif.h" -+ -+#include -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+#define BTIF_OWNER_NAME "CONSYS_STP" -+ -+#define STP_MAX_PACKAGE_ALLOWED (2000) -+ -+#define STP_BTIF_TX_RTY_LMT (10) -+#define STP_BTIF_TX_RTY_DLY (5) -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+unsigned long stpBtifId = 0; -+unsigned long *pBtifRef = &stpBtifId; -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+INT32 mtk_wcn_consys_stp_btif_open(VOID) -+{ -+ INT32 iRet = -1; -+ -+ iRet = mtk_wcn_btif_open(BTIF_OWNER_NAME, pBtifRef); -+ if (iRet) { -+ WMT_WARN_FUNC("STP open btif fail(%d)\n", iRet); -+ return -1; -+ } -+ WMT_DBG_FUNC("STP open bitf OK\n"); -+ -+ mtk_wcn_stp_register_if_tx(STP_BTIF_IF_TX, (MTK_WCN_STP_IF_TX) mtk_wcn_consys_stp_btif_tx); -+ -+ return 0; -+} -+ -+INT32 mtk_wcn_consys_stp_btif_close(VOID) -+{ -+ INT32 iRet = 0; -+ -+ if (!stpBtifId) { -+ WMT_WARN_FUNC("NULL BTIF ID reference!\n"); -+ iRet = -1; -+ } else { -+ iRet = mtk_wcn_btif_close(stpBtifId); -+ if (iRet) { -+ WMT_WARN_FUNC("STP close btif fail(%d)\n", iRet); -+ iRet = -2; -+ } else { -+ stpBtifId = 0; -+ WMT_DBG_FUNC("STP close btif OK\n"); -+ } -+ } -+ return iRet; -+} -+ -+INT32 mtk_wcn_consys_stp_btif_rx_cb_register(MTK_WCN_BTIF_RX_CB rx_cb) -+{ -+ INT32 iRet = 0; -+ -+ if (!stpBtifId) { -+ WMT_WARN_FUNC("NULL BTIF ID reference\n!"); -+ iRet = -1; -+ } else { -+ iRet = mtk_wcn_btif_rx_cb_register(stpBtifId, rx_cb); -+ if (iRet) { -+ WMT_WARN_FUNC("STP register rxcb to btif fail(%d)\n", iRet); -+ iRet = -2; -+ } else { -+ WMT_DBG_FUNC("STP register rxcb to btif OK\n"); -+ } -+ } -+ return iRet; -+} -+ -+INT32 mtk_wcn_consys_stp_btif_tx(const UINT8 *pBuf, const UINT32 len, UINT32 *written_len) -+{ -+ INT32 retry_left = STP_BTIF_TX_RTY_LMT; -+ INT32 wr_count = 0; -+ INT32 written = 0; -+ -+ if (!stpBtifId) { -+ WMT_WARN_FUNC("NULL BTIF ID reference!\n"); -+ return -1; -+ } -+ -+ if (len == 0) { -+ *written_len = 0; -+ WMT_INFO_FUNC("special case for STP-CORE,pbuf(%p)\n", pBuf); -+ return 0; -+ } -+ -+ *written_len = 0; -+ -+ if (len > STP_MAX_PACKAGE_ALLOWED) { -+ WMT_WARN_FUNC("abnormal pacage length,len(%d),pid[%d/%s]\n", len, current->pid, current->comm); -+ return -2; -+ } -+ wr_count = mtk_wcn_btif_write(stpBtifId, pBuf, len); -+ -+ if (wr_count < 0) { -+ WMT_ERR_FUNC("mtk_wcn_btif_write err(%d)\n", wr_count); -+ *written_len = 0; -+ return -3; -+ } -+ if (wr_count == len) { -+ /*perfect case */ -+ *written_len = wr_count; -+ return wr_count; -+ } -+ -+ while ((retry_left--) && (wr_count < len)) { -+ osal_sleep_ms(STP_BTIF_TX_RTY_DLY); -+ written = mtk_wcn_btif_write(stpBtifId, pBuf + wr_count, len - wr_count); -+ if (written < 0) { -+ WMT_ERR_FUNC("mtk_wcn_btif_write err(%d)when do recovered\n", written); -+ break; -+ } -+ wr_count += written; -+ } -+ -+ if (wr_count == len) { -+ WMT_INFO_FUNC("recovered,len(%d),retry_left(%d)\n", len, retry_left); -+ /*recovered case */ -+ *written_len = wr_count; -+ return wr_count; -+ } -+ -+ WMT_ERR_FUNC("stp btif write fail,len(%d),written(%d),retry_left(%d),pid[%d/%s]\n", -+ len, wr_count, retry_left, current->pid, current->comm); -+ *written_len = 0; -+ return -wr_count; -+} -+ -+INT32 mtk_wcn_consys_stp_btif_rx(UINT8 *pBuf, UINT32 len) -+{ -+ return 0; -+} -+ -+INT32 mtk_wcn_consys_stp_btif_wakeup(VOID) -+{ -+ INT32 iRet = 0; -+ -+ if (!stpBtifId) { -+ WMT_WARN_FUNC("NULL BTIF ID reference!\n"); -+ iRet = -1; -+ } else { -+ iRet = mtk_wcn_btif_wakeup_consys(stpBtifId); -+ if (iRet) { -+ WMT_WARN_FUNC("STP btif wakeup consys fail(%d)\n", iRet); -+ iRet = -2; -+ } else { -+ WMT_DBG_FUNC("STP btif wakeup consys ok\n"); -+ } -+ } -+ -+ return iRet; -+} -+ -+INT32 mtk_wcn_consys_stp_btif_dpidle_ctrl(ENUM_BTIF_DPIDLE_CTRL en_flag) -+{ -+ INT32 iRet = 0; -+ -+ if (!stpBtifId) { -+ WMT_WARN_FUNC("NULL BTIF ID reference!\n"); -+ iRet = -1; -+ } else { -+ mtk_wcn_btif_dpidle_ctrl(stpBtifId, en_flag); -+ WMT_DBG_FUNC("stp btif dpidle ctrl done,en_flag(%d)\n", en_flag); -+ } -+ -+ return iRet; -+} -+ -+INT32 mtk_wcn_consys_stp_btif_lpbk_ctrl(ENUM_BTIF_LPBK_MODE mode) -+{ -+ INT32 iRet = 0; -+ -+ if (!stpBtifId) { -+ WMT_WARN_FUNC("NULL BTIF ID reference!\n"); -+ iRet = -1; -+ } else { -+ iRet = mtk_wcn_btif_loopback_ctrl(stpBtifId, mode); -+ if (iRet) { -+ WMT_WARN_FUNC("STP btif lpbk ctrl fail(%d)\n", iRet); -+ iRet = -2; -+ } else { -+ WMT_INFO_FUNC("stp btif lpbk ctrl ok,mode(%d)\n", mode); -+ } -+ } -+ -+ return iRet; -+} -+ -+INT32 mtk_wcn_consys_stp_btif_logger_ctrl(ENUM_BTIF_DBG_ID flag) -+{ -+ INT32 iRet = 0; -+ -+ if (!stpBtifId) { -+ WMT_WARN_FUNC("NULL BTIF ID reference!\n"); -+ iRet = -1; -+ } else { -+ iRet = mtk_wcn_btif_dbg_ctrl(stpBtifId, flag); -+ if (iRet) { -+ WMT_WARN_FUNC("STP btif log dbg ctrl fail(%d)\n", iRet); -+ iRet = -2; -+ } else { -+ WMT_INFO_FUNC("stp btif log dbg ctrl ok,flag(%d)\n", flag); -+ } -+ } -+ -+ return iRet; -+} -+ -+INT32 mtk_wcn_consys_stp_btif_parser_wmt_evt(const UINT8 *str, UINT32 len) -+{ -+ if (!stpBtifId) { -+ WMT_WARN_FUNC("NULL BTIF ID reference!\n"); -+ return -1; -+ } else { -+ return (INT32) mtk_wcn_btif_parser_wmt_evt(stpBtifId, str, len); -+ } -+} -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/stp_dbg.c b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/stp_dbg.c -new file mode 100644 -index 000000000000..fd8e9a97a0b8 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/stp_dbg.c -@@ -0,0 +1,2060 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -+#include /* GFP_KERNEL */ -+#include /* init_timer, add_time, del_timer_sync */ -+#include /* gettimeofday */ -+#include -+#include /* kzalloc */ -+#include /* task's status */ -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+ -+#include "osal_typedef.h" -+#include "stp_dbg.h" -+/* #include "stp_btm.h" */ -+#include "btm_core.h" -+#include "wmt_plat.h" -+ -+#define PFX_STP_DBG "[STPDbg]" -+#define STP_DBG_LOG_LOUD 4 -+#define STP_DBG_LOG_DBG 3 -+#define STP_DBG_LOG_INFO 2 -+#define STP_DBG_LOG_WARN 1 -+#define STP_DBG_LOG_ERR 0 -+ -+unsigned int gStpDbgDbgLevel = STP_DBG_LOG_INFO; -+unsigned int gStpDbgLogOut = 0; -+ -+#define STP_DBG_LOUD_FUNC(fmt, arg...) \ -+do { \ -+ if (gStpDbgDbgLevel >= STP_DBG_LOG_LOUD) \ -+ pr_debug(PFX_STP_DBG "%s: " fmt, __func__ , ##arg); \ -+} while (0) -+#define STP_DBG_DBG_FUNC(fmt, arg...) \ -+do { \ -+ if (gStpDbgDbgLevel >= STP_DBG_LOG_DBG) \ -+ pr_debug(PFX_STP_DBG "%s: " fmt, __func__ , ##arg); \ -+} while (0) -+#define STP_DBG_INFO_FUNC(fmt, arg...) \ -+do { \ -+ if (gStpDbgDbgLevel >= STP_DBG_LOG_INFO) \ -+ pr_debug(PFX_STP_DBG "%s: " fmt, __func__ , ##arg); \ -+} while (0) -+#define STP_DBG_WARN_FUNC(fmt, arg...) \ -+do { \ -+ if (gStpDbgDbgLevel >= STP_DBG_LOG_WARN) \ -+ pr_warn(PFX_STP_DBG "%s: " fmt, __func__ , ##arg); \ -+} while (0) -+#define STP_DBG_ERR_FUNC(fmt, arg...) \ -+do { \ -+ if (gStpDbgDbgLevel >= STP_DBG_LOG_ERR) \ -+ pr_err(PFX_STP_DBG "%s: " fmt, __func__ , ##arg); \ -+} while (0) -+#define STP_DBG_TRC_FUNC(f) \ -+do { \ -+ if (gStpDbgDbgLevel >= STP_DBG_LOG_DBG) \ -+ pr_debug(PFX_STP_DBG "<%s> <%d>\n", __func__, __LINE__); \ -+} while (0) -+ -+MTKSTP_DBG_T *g_stp_dbg = NULL; -+ -+#define STP_DBG_FAMILY_NAME "STP_DBG" -+#define MAX_BIND_PROCESS (4) -+#ifdef WMT_PLAT_ALPS -+#define STP_DBG_AEE_EXP_API (1) -+#else -+#define STP_DBG_AEE_EXP_API (0) -+#endif -+enum { -+ __STP_DBG_ATTR_INVALID, -+ STP_DBG_ATTR_MSG, -+ __STP_DBG_ATTR_MAX, -+}; -+#define STP_DBG_ATTR_MAX (__STP_DBG_ATTR_MAX - 1) -+ -+enum { -+ __STP_DBG_COMMAND_INVALID, -+ STP_DBG_COMMAND_BIND, -+ STP_DBG_COMMAND_RESET, -+ __STP_DBG_COMMAND_MAX, -+}; -+#define MTK_WIFI_COMMAND_MAX (__STP_DBG_COMMAND_MAX - 1) -+ -+static struct genl_family stp_dbg_gnl_family = { -+ .id = GENL_ID_GENERATE, -+ .hdrsize = 0, -+ .name = STP_DBG_FAMILY_NAME, -+ .version = 1, -+ .maxattr = STP_DBG_ATTR_MAX, -+}; -+ -+static void stp_dbg_nl_init(void); -+static void stp_dbg_nl_deinit(void); -+static int stp_dbg_nl_bind(struct sk_buff *skb, struct genl_info *info); -+static int stp_dbg_nl_reset(struct sk_buff *skb, struct genl_info *info); -+ -+/* attribute policy */ -+static struct nla_policy stp_dbg_genl_policy[STP_DBG_ATTR_MAX + 1] = { -+ [STP_DBG_ATTR_MSG] = {.type = NLA_NUL_STRING}, -+}; -+ -+/* operation definition */ -+#if 0 -+static struct genl_ops stp_dbg_gnl_ops_bind = { -+ .cmd = STP_DBG_COMMAND_BIND, -+ .flags = 0, -+ .policy = stp_dbg_genl_policy, -+ .doit = stp_dbg_nl_bind, -+ .dumpit = NULL, -+}; -+ -+static struct genl_ops stp_dbg_gnl_ops_reset = { -+ .cmd = STP_DBG_COMMAND_RESET, -+ .flags = 0, -+ .policy = stp_dbg_genl_policy, -+ .doit = stp_dbg_nl_reset, -+ .dumpit = NULL, -+}; -+#endif -+static struct genl_ops stp_dbg_gnl_ops_array[] = { -+ { -+ .cmd = STP_DBG_COMMAND_BIND, -+ .flags = 0, -+ .policy = stp_dbg_genl_policy, -+ .doit = stp_dbg_nl_bind, -+ .dumpit = NULL, -+ }, -+ { -+ .cmd = STP_DBG_COMMAND_RESET, -+ .flags = 0, -+ .policy = stp_dbg_genl_policy, -+ .doit = stp_dbg_nl_reset, -+ .dumpit = NULL, -+ }, -+}; -+ -+#if 0 -+#define E2S(x) #x -+static char *dmaRegsStr[] = { -+ E2S(CONNSYS_CLK_GATE_STATUS), -+ E2S(CONSYS_EMI_STATUS), -+ E2S(SYSRAM1), -+ E2S(SYSRAM2), -+ E2S(SYSRAM3) -+}; -+#endif -+static unsigned int stp_dbg_seqnum; -+static int num_bind_process; -+static pid_t bind_pid[MAX_BIND_PROCESS]; -+ -+static P_WCN_CORE_DUMP_T g_core_dump; -+ -+static P_STP_DBG_CPUPCR_T g_stp_dbg_cpupcr; -+ -+/* just show in log at present */ -+static P_STP_DBG_DMAREGS_T g_stp_dbg_dmaregs; -+ -+/* core_dump_timeout_handler - handler of coredump timeout -+ * @ data - core dump object's pointer -+ * -+ * No return value -+ */ -+static void core_dump_timeout_handler(unsigned long data) -+{ -+ P_WCN_CORE_DUMP_T dmp = (P_WCN_CORE_DUMP_T) data; -+ -+ STP_DBG_INFO_FUNC(" start\n"); -+ -+ stp_btm_notify_coredump_timeout_wq(g_stp_dbg->btm); -+ -+ STP_DBG_INFO_FUNC(" end\n"); -+ -+ if (dmp) -+ dmp->sm = CORE_DUMP_TIMEOUT; -+} -+ -+/* wcn_core_dump_init - create core dump sys -+ * @ timeout - core dump time out value -+ * -+ * Return object pointer if success, else NULL -+ */ -+P_WCN_CORE_DUMP_T wcn_core_dump_init(UINT32 packet_num, UINT32 timeout) -+{ -+#define KBYTES (1024*sizeof(char)) -+#define L1_BUF_SIZE (32*KBYTES) -+ -+ P_WCN_CORE_DUMP_T core_dmp = NULL; -+ -+ core_dmp = (P_WCN_CORE_DUMP_T) osal_malloc(sizeof(WCN_CORE_DUMP_T)); -+ if (!core_dmp) { -+ STP_DBG_ERR_FUNC("alloc mem failed!\n"); -+ goto fail; -+ } -+ -+ osal_memset(core_dmp, 0, sizeof(WCN_CORE_DUMP_T)); -+ -+ core_dmp->compressor = wcn_compressor_init("core_dump_compressor", L1_BUF_SIZE, 18*packet_num*KBYTES); -+ if (!core_dmp->compressor) { -+ STP_DBG_ERR_FUNC("create compressor failed!\n"); -+ goto fail; -+ } -+ wcn_compressor_reset(core_dmp->compressor, 1, GZIP); -+ -+ core_dmp->dmp_timer.timeoutHandler = core_dump_timeout_handler; -+ core_dmp->dmp_timer.timeroutHandlerData = (unsigned long)core_dmp; -+ osal_timer_create(&core_dmp->dmp_timer); -+ core_dmp->timeout = timeout; -+ -+ osal_sleepable_lock_init(&core_dmp->dmp_lock); -+ -+ core_dmp->sm = CORE_DUMP_INIT; -+ STP_DBG_INFO_FUNC("create coredump object OK!\n"); -+ -+ return core_dmp; -+ -+fail: -+ if (core_dmp && core_dmp->compressor) { -+ wcn_compressor_deinit(core_dmp->compressor); -+ core_dmp->compressor = NULL; -+ } -+ if (core_dmp) -+ osal_free(core_dmp); -+ -+ return NULL; -+} -+INT32 wcn_core_dump_init_gcoredump(UINT32 packet_num, UINT32 timeout) -+{ -+ INT32 Ret = 0; -+ -+ g_core_dump = wcn_core_dump_init(packet_num, timeout); -+ if (g_core_dump == NULL) -+ Ret = -1; -+ return Ret; -+} -+ -+/* wcn_core_dump_deinit - destroy core dump object -+ * @ dmp - pointer of object -+ * -+ * Retunr 0 if success, else error code -+ */ -+INT32 wcn_core_dump_deinit(P_WCN_CORE_DUMP_T dmp) -+{ -+ if (dmp && dmp->compressor) { -+ wcn_compressor_deinit(dmp->compressor); -+ dmp->compressor = NULL; -+ } -+ -+ if (dmp) { -+ osal_sleepable_lock_deinit(&dmp->dmp_lock); -+ osal_timer_stop(&dmp->dmp_timer); -+ osal_free(dmp); -+ } -+ -+ return 0; -+} -+ -+INT32 wcn_core_dump_deinit_gcoredump(VOID) -+{ -+ wcn_core_dump_deinit(g_core_dump); -+ return 0; -+} -+ -+static INT32 wcn_core_dump_check_end(PUINT8 buf, INT32 len) -+{ -+ if (strnstr(buf, "coredump end", len)) -+ return 1; -+ else -+ return 0; -+} -+ -+/* wcn_core_dump_in - add a packet to compressor buffer -+ * @ dmp - pointer of object -+ * @ buf - input buffer -+ * @ len - data length -+ * -+ * Retunr 0 if success; return 1 if find end string; else error code -+ */ -+INT32 wcn_core_dump_in(P_WCN_CORE_DUMP_T dmp, PUINT8 buf, INT32 len) -+{ -+ INT32 ret = 0; -+ INT32 tmp; -+ -+#define INFO_HEAD ";SOC_CONSYS FW CORE, " -+ -+ if ((!dmp) || (!buf)) { -+ STP_DBG_ERR_FUNC("invalid pointer!\n"); -+ return -1; -+ } -+ -+ ret = osal_lock_sleepable_lock(&dmp->dmp_lock); -+ if (ret) { -+ STP_DBG_ERR_FUNC("--->lock dmp->dmp_lock failed, ret=%d\n", ret); -+ return ret; -+ } -+ -+ switch (dmp->sm) { -+ case CORE_DUMP_INIT: -+ wcn_compressor_reset(dmp->compressor, 1, GZIP); -+ osal_timer_start(&dmp->dmp_timer, STP_CORE_DUMP_TIMEOUT); -+ -+ /* first package, copy to info buffer */ -+ osal_strcpy(&dmp->info[0], INFO_HEAD); -+ -+ if (NULL == (strnstr(buf, "", 32))) { -+ osal_memcpy(&dmp->info[osal_strlen(INFO_HEAD)], "Fw warm reset exception...", -+ osal_strlen("Fw warm reset exception...")); -+ dmp->info[osal_strlen(INFO_HEAD) + osal_strlen("Fw warm reset exception...") + 1] = '\0'; -+ } else { -+ char *pStr = buf; -+ char *pDtr = NULL; -+ -+ pDtr = osal_strchr(pStr, '-'); -+ if (NULL != pDtr) { -+ tmp = pDtr - pStr; -+ osal_memcpy(&dmp->info[osal_strlen(INFO_HEAD)], buf, tmp); -+ dmp->info[osal_strlen(dmp->info) + 1] = '\0'; -+ } else { -+ tmp = STP_CORE_DUMP_INFO_SZ - osal_strlen(INFO_HEAD); -+ tmp = (len > tmp) ? tmp : len; -+ osal_memcpy(&dmp->info[osal_strlen(INFO_HEAD)], buf, tmp); -+ dmp->info[STP_CORE_DUMP_INFO_SZ] = '\0'; -+ } -+ -+ } -+ /* show coredump start info on UI */ -+ /* osal_dbg_assert_aee("MT662x f/w coredump start", "MT662x firmware coredump start"); */ -+#if STP_DBG_AEE_EXP_API -+ aee_kernel_dal_show("SOC_CONSYS coredump start ....\n"); -+#endif -+ /* parsing data, and check end srting */ -+ ret = wcn_core_dump_check_end(buf, len); -+ if (ret == 1) { -+ STP_DBG_INFO_FUNC("core dump end!\n"); -+ dmp->sm = CORE_DUMP_DONE; -+ wcn_compressor_in(dmp->compressor, buf, len, 0); -+ } else { -+ dmp->sm = CORE_DUMP_DOING; -+ wcn_compressor_in(dmp->compressor, buf, len, 0); -+ } -+ break; -+ -+ case CORE_DUMP_DOING: -+ /* parsing data, and check end srting */ -+ ret = wcn_core_dump_check_end(buf, len); -+ if (ret == 1) { -+ STP_DBG_INFO_FUNC("core dump end!\n"); -+ dmp->sm = CORE_DUMP_DONE; -+ wcn_compressor_in(dmp->compressor, buf, len, 0); -+ } else { -+ dmp->sm = CORE_DUMP_DOING; -+ wcn_compressor_in(dmp->compressor, buf, len, 0); -+ } -+ break; -+ -+ case CORE_DUMP_DONE: -+ wcn_compressor_reset(dmp->compressor, 1, GZIP); -+ osal_timer_start(&dmp->dmp_timer, STP_CORE_DUMP_TIMEOUT); -+ wcn_compressor_in(dmp->compressor, buf, len, 0); -+ dmp->sm = CORE_DUMP_DOING; -+ break; -+ -+ case CORE_DUMP_TIMEOUT: -+ break; -+ default: -+ break; -+ } -+ -+ osal_unlock_sleepable_lock(&dmp->dmp_lock); -+ -+ return ret; -+} -+ -+/* wcn_core_dump_out - get compressed data from compressor buffer -+ * @ dmp - pointer of object -+ * @ pbuf - target buffer's pointer -+ * @ len - data length -+ * -+ * Retunr 0 if success; else error code -+ */ -+INT32 wcn_core_dump_out(P_WCN_CORE_DUMP_T dmp, PUINT8 *pbuf, PINT32 plen) -+{ -+ INT32 ret = 0; -+ -+ if ((!dmp) || (!pbuf) || (!plen)) { -+ STP_DBG_ERR_FUNC("invalid pointer!\n"); -+ return -1; -+ } -+ -+ ret = osal_lock_sleepable_lock(&dmp->dmp_lock); -+ if (ret) { -+ STP_DBG_ERR_FUNC("--->lock dmp->dmp_lock failed, ret=%d\n", ret); -+ return ret; -+ } -+ -+ ret = wcn_compressor_out(dmp->compressor, pbuf, plen); -+ -+ osal_unlock_sleepable_lock(&dmp->dmp_lock); -+ -+ return ret; -+} -+ -+/* wcn_core_dump_reset - reset core dump sys -+ * @ dmp - pointer of object -+ * @ timeout - core dump time out value -+ * -+ * Retunr 0 if success, else error code -+ */ -+INT32 wcn_core_dump_reset(P_WCN_CORE_DUMP_T dmp, UINT32 timeout) -+{ -+ if (!dmp) { -+ STP_DBG_ERR_FUNC("invalid pointer!\n"); -+ return -1; -+ } -+ -+ dmp->sm = CORE_DUMP_INIT; -+ dmp->timeout = timeout; -+ osal_timer_stop(&dmp->dmp_timer); -+ wcn_compressor_reset(dmp->compressor, 1, GZIP); -+ osal_memset(dmp->info, 0, STP_CORE_DUMP_INFO_SZ + 1); -+ -+ wcn_core_dump_deinit(dmp); -+ g_core_dump = wcn_core_dump_init(STP_CORE_DUMP_INIT_SIZE, STP_CORE_DUMP_TIMEOUT); -+ -+ return 0; -+} -+ -+/* wcn_wmtd_timeout_collect_ftrace - wmtd timeout ,this func can collect SYS_FTRACE -+ * -+ * Retunr 0 if success -+ */ -+#define WMTD_TIMEOUT_INFO_HEAD "Wait wmtd complation timeout ,just collect SYS_FTRACE to DB" -+INT32 wcn_wmtd_timeout_collect_ftrace(void) -+{ -+ PUINT8 pbuf; -+ INT32 len; -+ -+ pbuf = "Wait wmtd complation timeout"; -+ len = osal_strlen("Wait wmtd complation timeout"); -+ osal_strcpy(&g_core_dump->info[0], WMTD_TIMEOUT_INFO_HEAD); -+#ifdef WMT_PLAT_ALPS -+ aed_combo_exception(NULL, 0, (const int *)pbuf, len, (const char *)g_core_dump->info); -+#endif -+ return 0; -+} -+/* wcn_psm_flag_trigger_collect_ftrace - wmtd timeout ,this func can collect SYS_FTRACE -+ * -+ * Retunr 0 if success -+ */ -+#define PSM_ABNORMAL_FLAG_INFO_HEAD "Abnormal PSM flag be set ,just collect SYS_FTRACE to DB" -+INT32 wcn_psm_flag_trigger_collect_ftrace(void) -+{ -+ PUINT8 pbuf; -+ INT32 len; -+ -+ pbuf = "Abnormal PSM flag be set"; -+ len = osal_strlen("Abnormal PSM flag be set"); -+ osal_strcpy(&g_core_dump->info[0], PSM_ABNORMAL_FLAG_INFO_HEAD); -+#ifdef WMT_PLAT_ALPS -+ aed_combo_exception(NULL, 0, (const int *)pbuf, len, (const char *)g_core_dump->info); -+#endif -+ return 0; -+} -+#if BTIF_RXD_BE_BLOCKED_DETECT -+MTK_WCN_BOOL is_btif_rxd_be_blocked(void) -+{ -+ MTK_WCN_BOOL flag = MTK_WCN_BOOL_FALSE; -+ -+ if (mtk_btif_rxd_be_blocked_flag_get()) -+ flag = MTK_WCN_BOOL_TRUE; -+ return flag; -+} -+/* wcn_btif_rxd_blocked_collect_ftrace - btif rxd be blocked,this func can collect SYS_FTRACE -+ * -+ * Retunr 0 if success -+ */ -+#define BTIF_RXD_BLOCKED_INFO_HEAD "Btif_rxd thread be blocked too long,just collect SYS_FTRACE to DB" -+INT32 wcn_btif_rxd_blocked_collect_ftrace(void) -+{ -+ PUINT8 pbuf; -+ INT32 len; -+ -+ pbuf = "Btif_rxd thread be blocked too long"; -+ len = osal_strlen("Btif_rxd thread be blocked too long"); -+ osal_strcpy(&g_core_dump->info[0], BTIF_RXD_BLOCKED_INFO_HEAD); -+#ifdef WMT_PLAT_ALPS -+ aed_combo_exception(NULL, 0, (const int *)pbuf, len, (const char *)g_core_dump->info); -+#endif -+ return 0; -+} -+#endif -+/* wcn_core_dump_timeout - wait for FW assert info timeout ,this func can collect SYS_FTRACE -+ * -+ * Retunr 0 if success -+ */ -+#define TIMEOUT_INFO_HEAD "Trigger assert timeout ,just collect SYS_FTRACE to DB" -+INT32 wcn_core_dump_timeout(void) -+{ -+ PUINT8 pbuf; -+ INT32 len; -+ -+ pbuf = "Trigger assert timeout"; -+ len = osal_strlen("Trigger assert timeout"); -+ osal_strcpy(&g_core_dump->info[0], TIMEOUT_INFO_HEAD); -+#ifdef WMT_PLAT_ALPS -+ aed_combo_exception(NULL, 0, (const int *)pbuf, len, (const char *)g_core_dump->info); -+#endif -+ return 0; -+} -+ -+#define ENABLE_F_TRACE 0 -+/* wcn_core_dump_flush - Fulsh dump data and reset core dump sys -+ * -+ * Retunr 0 if success, else error code -+ */ -+INT32 wcn_core_dump_flush(INT32 rst, MTK_WCN_BOOL coredump_is_timeout) -+{ -+ PUINT8 pbuf = NULL; -+ INT32 len = 0; -+ -+ if (!g_core_dump) { -+ STP_DBG_ERR_FUNC("invalid pointer!\n"); -+ return -1; -+ } -+ -+ wcn_core_dump_out(g_core_dump, &pbuf, &len); -+ STP_DBG_INFO_FUNC("buf 0x%zx, len %d\n", (SIZE_T) pbuf, len); -+#ifdef WMT_PLAT_ALPS -+ /* show coredump end info on UI */ -+ /* osal_dbg_assert_aee("MT662x f/w coredump end", "MT662x firmware coredump ends"); */ -+#if STP_DBG_AEE_EXP_API -+ if (coredump_is_timeout) -+ aee_kernel_dal_show("++ SOC_CONSYS coredump tiemout ,pass received coredump to AEE ++\n"); -+ else -+ aee_kernel_dal_show("++ SOC_CONSYS coredump get successfully ++\n"); -+ /* call AEE driver API */ -+#if ENABLE_F_TRACE -+ aed_combo_exception_api(NULL, 0, (const int *)pbuf, len, (const char *)g_core_dump->info, DB_OPT_FTRACE); -+#else -+ aed_combo_exception(NULL, 0, (const int *)pbuf, len, (const char *)g_core_dump->info); -+#endif -+ -+#endif -+ -+#endif // WMT_PLAT_ALPS -+ -+ /* reset */ -+ wcn_core_dump_reset(g_core_dump, STP_CORE_DUMP_TIMEOUT); -+ -+ return 0; -+} -+ -+static INT32 wcn_gzip_compressor(void *worker, UINT8 *in_buf, INT32 in_sz, UINT8 *out_buf, INT32 *out_sz, -+ INT32 finish) -+{ -+ INT32 ret = 0; -+ z_stream *stream = NULL; -+ INT32 tmp = *out_sz; -+ -+ STP_DBG_INFO_FUNC("need to compressor :buf 0x%zx, size %d\n", (SIZE_T) in_buf, in_sz); -+ STP_DBG_INFO_FUNC("before compressor,avalible buf: 0x%zx, size %d\n", (SIZE_T) out_buf, tmp); -+ -+ stream = (z_stream *) worker; -+ if (!stream) { -+ STP_DBG_ERR_FUNC("invalid workspace!\n"); -+ return -1; -+ } -+ -+ if (in_sz > 0) { -+#if 0 -+ ret = zlib_deflateReset(stream); -+ if (ret != Z_OK) { -+ STP_DBG_ERR_FUNC("reset failed!\n"); -+ return -2; -+ } -+#endif -+ -+ stream->next_in = in_buf; -+ stream->avail_in = in_sz; -+ stream->next_out = out_buf; -+ stream->avail_out = tmp; -+ -+ zlib_deflate(stream, Z_FULL_FLUSH); -+ -+ if (finish) { -+ while (1) { -+ int val = zlib_deflate(stream, Z_FINISH); -+ -+ if (val == Z_OK) -+ continue; -+ else if (val == Z_STREAM_END) -+ break; -+ STP_DBG_ERR_FUNC("finish operation failed %d\n", val); -+ return -3; -+ } -+ } -+ -+ *out_sz = tmp - stream->avail_out; -+ } -+ -+ STP_DBG_INFO_FUNC("after compressor,avalible buf: 0x%zx, compress rate %d -> %d\n", (SIZE_T) out_buf, in_sz, -+ *out_sz); -+ -+ return ret; -+} -+ -+/* wcn_compressor_init - create a compressor and do init -+ * @ name - compressor's name -+ * @ L1_buf_sz - L1 buffer size -+ * @ L2_buf_sz - L2 buffer size -+ * -+ * Retunr object's pointer if success, else NULL -+ */ -+P_WCN_COMPRESSOR_T wcn_compressor_init(PUINT8 name, INT32 L1_buf_sz, INT32 L2_buf_sz) -+{ -+ z_stream *pstream = NULL; -+ P_WCN_COMPRESSOR_T compress = NULL; -+ -+ compress = (P_WCN_COMPRESSOR_T) osal_malloc(sizeof(WCN_COMPRESSOR_T)); -+ if (!compress) { -+ STP_DBG_ERR_FUNC("alloc compressor failed!\n"); -+ goto fail; -+ } -+ -+ osal_memset(compress, 0, sizeof(WCN_COMPRESSOR_T)); -+ osal_memcpy(compress->name, name, STP_OJB_NAME_SZ); -+ -+ compress->f_compress_en = 0; -+ compress->compress_type = GZIP; -+ -+ if (compress->compress_type == GZIP) { -+ compress->worker = osal_malloc(sizeof(z_stream)); -+ if (!compress->worker) { -+ STP_DBG_ERR_FUNC("alloc stream failed!\n"); -+ goto fail; -+ } -+ pstream = (z_stream *) compress->worker; -+ -+ pstream->workspace = osal_malloc(zlib_deflate_workspacesize(MAX_WBITS, MAX_MEM_LEVEL)); -+ if (!pstream->workspace) { -+ STP_DBG_ERR_FUNC("alloc workspace failed!\n"); -+ goto fail; -+ } -+ zlib_deflateInit2(pstream, Z_DEFAULT_COMPRESSION, Z_DEFLATED, -MAX_WBITS, -+ DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY); -+ } -+ -+ compress->handler = wcn_gzip_compressor; -+ compress->L1_buf_sz = L1_buf_sz; -+ compress->L2_buf_sz = L2_buf_sz; -+ compress->L1_pos = 0; -+ compress->L2_pos = 0; -+ compress->uncomp_size = 0; -+ compress->crc32 = 0xffffffffUL; -+ -+ compress->L1_buf = osal_malloc(compress->L1_buf_sz); -+ if (!compress->L1_buf) { -+ STP_DBG_ERR_FUNC("alloc %d bytes for L1 buf failed!\n", compress->L1_buf_sz); -+ goto fail; -+ } -+ -+ compress->L2_buf = osal_malloc(compress->L2_buf_sz); -+ if (!compress->L2_buf) { -+ STP_DBG_ERR_FUNC("alloc %d bytes for L2 buf failed!\n", compress->L2_buf_sz); -+ goto fail; -+ } -+ -+ STP_DBG_INFO_FUNC("create compressor OK! L1 %d bytes, L2 %d bytes\n", L1_buf_sz, L2_buf_sz); -+ return compress; -+ -+fail: -+ if (compress) { -+ if (compress->L2_buf) { -+ osal_free(compress->L2_buf); -+ compress->L2_buf = NULL; -+ } -+ -+ if (compress->L1_buf) { -+ osal_free(compress->L1_buf); -+ compress->L1_buf = NULL; -+ } -+ -+ if (compress->worker) { -+ pstream = (z_stream *) compress->worker; -+ if ((compress->compress_type == GZIP) && pstream->workspace) { -+ zlib_deflateEnd(pstream); -+ osal_free(pstream->workspace); -+ } -+ osal_free(compress->worker); -+ compress->worker = NULL; -+ } -+ -+ if (compress->worker) { -+ osal_free(compress->worker); -+ compress->worker = NULL; -+ } -+ -+ osal_free(compress); -+ compress = NULL; -+ } -+ -+ STP_DBG_ERR_FUNC("init failed!\n"); -+ -+ return NULL; -+} -+ -+/* wcn_compressor_deinit - distroy a compressor -+ * @ cprs - compressor's pointer -+ * -+ * Retunr 0 if success, else NULL -+ */ -+INT32 wcn_compressor_deinit(P_WCN_COMPRESSOR_T cprs) -+{ -+ z_stream *pstream = NULL; -+ -+ if (cprs) { -+ if (cprs->L2_buf) { -+ osal_free(cprs->L2_buf); -+ cprs->L2_buf = NULL; -+ } -+ -+ if (cprs->L1_buf) { -+ osal_free(cprs->L1_buf); -+ cprs->L1_buf = NULL; -+ } -+ -+ if (cprs->worker) { -+ pstream = (z_stream *) cprs->worker; -+ if ((cprs->compress_type == GZIP) && pstream->workspace) { -+ zlib_deflateEnd(pstream); -+ osal_free(pstream->workspace); -+ } -+ osal_free(cprs->worker); -+ cprs->worker = NULL; -+ } -+ -+ cprs->handler = NULL; -+ -+ osal_free(cprs); -+ } -+ -+ STP_DBG_INFO_FUNC("destroy OK\n"); -+ -+ return 0; -+} -+ -+/* wcn_compressor_in - put in a raw data, and compress L1 buffer if need -+ * @ cprs - compressor's pointer -+ * @ buf - raw data buffer -+ * @ len - raw data length -+ * @ finish - core dump finish or not, 1: finished; 0: not finish -+ * -+ * Retunr 0 if success, else NULL -+ */ -+INT32 wcn_compressor_in(P_WCN_COMPRESSOR_T cprs, PUINT8 buf, INT32 len, INT32 finish) -+{ -+ INT32 tmp_len = 0; -+ INT32 ret = 0; -+ -+ if (!cprs) { -+ STP_DBG_ERR_FUNC("invalid para!\n"); -+ return -1; -+ } -+ -+ cprs->uncomp_size += len; -+ -+ /* check L1 buf valid space */ -+ if (len > (cprs->L1_buf_sz - cprs->L1_pos)) { -+ STP_DBG_INFO_FUNC("L1 buffer full\n"); -+ -+ if (cprs->f_compress_en && cprs->handler) { -+ /* need compress */ -+ /* compress L1 buffer, and put result to L2 buffer */ -+ tmp_len = cprs->L2_buf_sz - cprs->L2_pos; -+ ret = -+ cprs->handler(cprs->worker, cprs->L1_buf, cprs->L1_pos, &cprs->L2_buf[cprs->L2_pos], -+ &tmp_len, finish); -+ if (!ret) { -+ cprs->crc32 = (crc32(cprs->crc32, cprs->L1_buf, cprs->L1_pos)); -+ cprs->L2_pos += tmp_len; -+ if (cprs->L2_pos > cprs->L2_buf_sz) -+ STP_DBG_ERR_FUNC("coredump size too large(%d), L2 buf overflow\n", -+ cprs->L2_pos); -+ -+ if (finish) { -+ /* Add 8 byte suffix -+ === -+ 32 bits UNCOMPRESS SIZE -+ 32 bits CRC -+ */ -+ *(uint32_t *) (&cprs->L2_buf[cprs->L2_pos]) = (cprs->crc32 ^ 0xffffffffUL); -+ *(uint32_t *) (&cprs->L2_buf[cprs->L2_pos + 4]) = cprs->uncomp_size; -+ cprs->L2_pos += 8; -+ } -+ STP_DBG_INFO_FUNC("compress OK!\n"); -+ } else -+ STP_DBG_ERR_FUNC("compress error!\n"); -+ } else { -+ /* no need compress */ -+ /* Flush L1 buffer to L2 buffer */ -+ STP_DBG_INFO_FUNC("No need do compress, Put to L2 buf\n"); -+ -+ tmp_len = cprs->L2_buf_sz - cprs->L2_pos; -+ tmp_len = (cprs->L1_pos > tmp_len) ? tmp_len : cprs->L1_pos; -+ osal_memcpy(&cprs->L2_buf[cprs->L2_pos], cprs->L1_buf, tmp_len); -+ cprs->L2_pos += tmp_len; -+ } -+ -+ /* reset L1 buf pos */ -+ cprs->L1_pos = 0; -+ -+ /* put curren data to L1 buf */ -+ if (len > cprs->L1_buf_sz) { -+ STP_DBG_ERR_FUNC("len=%d, too long err!\n", len); -+ } else { -+ STP_DBG_INFO_FUNC("L1 Flushed, and Put %d bytes to L1 buf\n", len); -+ osal_memcpy(&cprs->L1_buf[cprs->L1_pos], buf, len); -+ cprs->L1_pos += len; -+ } -+ } else { -+ /* put to L1 buffer */ -+ STP_DBG_INFO_FUNC("Put %d bytes to L1 buf\n", len); -+ -+ osal_memcpy(&cprs->L1_buf[cprs->L1_pos], buf, len); -+ cprs->L1_pos += len; -+ } -+ -+ return ret; -+} -+ -+/* wcn_compressor_out - get the result data from L2 buffer -+ * @ cprs - compressor's pointer -+ * @ pbuf - point to L2 buffer -+ * @ plen - out len -+ * -+ * Retunr 0 if success, else NULL -+ */ -+INT32 wcn_compressor_out(P_WCN_COMPRESSOR_T cprs, PUINT8 *pbuf, PINT32 plen) -+{ -+ INT32 ret = 0; -+ INT32 tmp_len = 0; -+ -+ if ((!cprs) || (!pbuf) || (!plen)) { -+ STP_DBG_ERR_FUNC("invalid para!\n"); -+ return -1; -+ } -+ /* check if there's L1 data need flush to L2 buffer */ -+ if (cprs->L1_pos > 0) { -+ tmp_len = cprs->L2_buf_sz - cprs->L2_pos; -+ -+ if (cprs->f_compress_en && cprs->handler) { -+ /* need compress */ -+ ret = -+ cprs->handler(cprs->worker, cprs->L1_buf, cprs->L1_pos, &cprs->L2_buf[cprs->L2_pos], -+ &tmp_len, 1); -+ -+ if (!ret) { -+ cprs->crc32 = (crc32(cprs->crc32, cprs->L1_buf, cprs->L1_pos)); -+ cprs->L2_pos += tmp_len; -+ -+ /* Add 8 byte suffix -+ === -+ 32 bits UNCOMPRESS SIZE -+ 32 bits CRC -+ */ -+ *(uint32_t *) (&cprs->L2_buf[cprs->L2_pos]) = (cprs->crc32 ^ 0xffffffffUL); -+ *(uint32_t *) (&cprs->L2_buf[cprs->L2_pos + 4]) = cprs->uncomp_size; -+ cprs->L2_pos += 8; -+ -+ STP_DBG_INFO_FUNC("compress OK!\n"); -+ } else { -+ STP_DBG_ERR_FUNC("compress error!\n"); -+ } -+ } else { -+ /* no need compress */ -+ tmp_len = (cprs->L1_pos > tmp_len) ? tmp_len : cprs->L1_pos; -+ osal_memcpy(&cprs->L2_buf[cprs->L2_pos], cprs->L1_buf, tmp_len); -+ cprs->L2_pos += tmp_len; -+ } -+ -+ cprs->L1_pos = 0; -+ } -+ -+ *pbuf = cprs->L2_buf; -+ *plen = cprs->L2_pos; -+ -+ STP_DBG_INFO_FUNC("0x%zx, len %d\n", (SIZE_T)*pbuf, *plen); -+ -+ return 0; -+} -+ -+/* wcn_compressor_reset - reset compressor -+ * @ cprs - compressor's pointer -+ * @ enable - enable/disable compress -+ * @ type - compress algorithm -+ * -+ * Retunr 0 if success, else NULL -+ */ -+INT32 wcn_compressor_reset(P_WCN_COMPRESSOR_T cprs, UINT8 enable, WCN_COMPRESS_ALG_T type) -+{ -+ if (!cprs) { -+ STP_DBG_ERR_FUNC("invalid para!\n"); -+ return -1; -+ } -+ -+ cprs->f_compress_en = enable; -+ /* cprs->f_compress_en = 0; // disable compress for test */ -+ cprs->compress_type = type; -+ cprs->L1_pos = 0; -+ cprs->L2_pos = 0; -+ cprs->uncomp_size = 0; -+ cprs->crc32 = 0xffffffffUL; -+ -+ /* zlib_deflateEnd((z_stream*)cprs->worker); */ -+ -+ STP_DBG_INFO_FUNC("OK! compress algorithm %d\n", type); -+ -+ return 0; -+} -+ -+static void stp_dbg_dump_data(unsigned char *pBuf, char *title, int len) -+{ -+ int k = 0; -+ -+ pr_debug(" %s-len:%d\n", title, len); -+ -+ for (k = 0; k < len; k++) { -+ if (k % 16 == 0 && k != 0) -+ pr_cont("\n "); -+ pr_cont("0x%02x ", pBuf[k]); -+ } -+ pr_debug("--end\n"); -+} -+ -+static int _stp_dbg_enable(MTKSTP_DBG_T *stp_dbg) -+{ -+ -+ unsigned long flags; -+ -+ spin_lock_irqsave(&(stp_dbg->logsys->lock), flags); -+ stp_dbg->pkt_trace_no = 0; -+ stp_dbg->is_enable = 1; -+ spin_unlock_irqrestore(&(stp_dbg->logsys->lock), flags); -+ -+ return 0; -+} -+ -+static int _stp_dbg_disable(MTKSTP_DBG_T *stp_dbg) -+{ -+ -+ unsigned long flags; -+ -+ spin_lock_irqsave(&(stp_dbg->logsys->lock), flags); -+ stp_dbg->pkt_trace_no = 0; -+ memset(stp_dbg->logsys, 0, sizeof(MTKSTP_LOG_SYS_T)); -+ stp_dbg->is_enable = 0; -+ spin_unlock_irqrestore(&(stp_dbg->logsys->lock), flags); -+ -+ return 0; -+} -+ -+static int _stp_dbg_dmp_in(MTKSTP_DBG_T *stp_dbg, char *buf, int len) -+{ -+ unsigned long flags; -+ STP_DBG_HDR_T *pHdr = NULL; -+ char *pBuf = NULL; -+ unsigned int length = 0; -+ unsigned int internalFlag = stp_dbg->logsys->size < STP_DBG_LOG_ENTRY_NUM; -+ /* #ifdef CONFIG_LOG_STP_INTERNAL */ -+ /* Here we record log in this circle buffer, if buffer is full , -+ select to overlap earlier log, logic should be okay */ -+ internalFlag = 1; -+ /* #endif */ -+ spin_lock_irqsave(&(stp_dbg->logsys->lock), flags); -+ -+ if (internalFlag) { -+ stp_dbg->logsys->queue[stp_dbg->logsys->in].id = 0; -+ stp_dbg->logsys->queue[stp_dbg->logsys->in].len = len; -+ memset(&(stp_dbg->logsys->queue[stp_dbg->logsys->in].buffer[0]), -+ 0, ((len >= STP_DBG_LOG_ENTRY_SZ) ? (STP_DBG_LOG_ENTRY_SZ) : (len))); -+ memcpy(&(stp_dbg->logsys->queue[stp_dbg->logsys->in].buffer[0]), -+ buf, ((len >= STP_DBG_LOG_ENTRY_SZ) ? (STP_DBG_LOG_ENTRY_SZ) : (len))); -+ -+ stp_dbg->logsys->size++; -+ stp_dbg->logsys->size = -+ (stp_dbg->logsys->size > STP_DBG_LOG_ENTRY_NUM) ? STP_DBG_LOG_ENTRY_NUM : stp_dbg->logsys->size; -+ -+ if (0 != gStpDbgLogOut) { -+ pHdr = (STP_DBG_HDR_T *) &(stp_dbg->logsys->queue[stp_dbg->logsys->in].buffer[0]); -+ pBuf = (char *)&(stp_dbg->logsys->queue[stp_dbg->logsys->in].buffer[0]) + sizeof(STP_DBG_HDR_T); -+ length = stp_dbg->logsys->queue[stp_dbg->logsys->in].len - sizeof(STP_DBG_HDR_T); -+ pr_debug("STP-DBG:%d.%ds, %s:pT%sn(%d)l(%d)s(%d)a(%d)\n", -+ pHdr->sec, -+ pHdr->usec, -+ pHdr->dir == PKT_DIR_TX ? "Tx" : "Rx", -+ gStpDbgType[pHdr->type], pHdr->no, pHdr->len, pHdr->seq, pHdr->ack); -+ if (0 < length) -+ stp_dbg_dump_data(pBuf, pHdr->dir == PKT_DIR_TX ? "Tx" : "Rx", length); -+ } -+ stp_dbg->logsys->in = -+ (stp_dbg->logsys->in >= (STP_DBG_LOG_ENTRY_NUM - 1)) ? (0) : (stp_dbg->logsys->in + 1); -+ STP_DBG_DBG_FUNC("logsys size = %d, in = %d\n", stp_dbg->logsys->size, stp_dbg->logsys->in); -+ } else { -+ STP_DBG_WARN_FUNC("logsys FULL!\n"); -+ } -+ -+ spin_unlock_irqrestore(&(stp_dbg->logsys->lock), flags); -+ -+ return 0; -+} -+ -+int stp_gdb_notify_btm_dmp_wq(MTKSTP_DBG_T *stp_dbg) -+{ -+ int retval = 0; -+/* #ifndef CONFIG_LOG_STP_INTERNAL */ -+ -+ if (stp_dbg->btm != NULL) -+ retval += stp_btm_notify_wmt_dmp_wq((MTKSTP_BTM_T *) stp_dbg->btm); -+/* #endif */ -+ -+ return retval; -+} -+ -+int stp_dbg_log_ctrl(unsigned int on) -+{ -+ if (on != 0) { -+ gStpDbgLogOut = 1; -+ pr_debug("STP-DBG: enable pkt log dump out.\n"); -+ } else { -+ gStpDbgLogOut = 0; -+ pr_debug("STP-DBG: disable pkt log dump out.\n"); -+ } -+ return 0; -+} -+ -+int stp_dbg_dmp_in(MTKSTP_DBG_T *stp_dbg, char *buf, int len) -+{ -+ return _stp_dbg_dmp_in(stp_dbg, buf, len); -+} -+ -+int stp_dbg_dmp_printk(MTKSTP_DBG_T *stp_dbg) -+{ -+#define MAX_DMP_NUM 80 -+ unsigned long flags; -+ char *pBuf = NULL; -+ int len = 0; -+ STP_DBG_HDR_T *pHdr = NULL; -+ UINT32 dumpSize = 0; -+ UINT32 inIndex = 0; -+ UINT32 outIndex = 0; -+ -+ spin_lock_irqsave(&(stp_dbg->logsys->lock), flags); -+ /* Not to dequeue from loging system */ -+ inIndex = stp_dbg->logsys->in; -+ dumpSize = stp_dbg->logsys->size; -+ if (STP_DBG_LOG_ENTRY_NUM == dumpSize) -+ outIndex = inIndex; -+ else -+ outIndex = ((inIndex + STP_DBG_LOG_ENTRY_NUM) - dumpSize) % STP_DBG_LOG_ENTRY_NUM; -+ -+ if (dumpSize > MAX_DMP_NUM) { -+ -+ outIndex += (dumpSize - MAX_DMP_NUM); -+ outIndex %= STP_DBG_LOG_ENTRY_NUM; -+ dumpSize = MAX_DMP_NUM; -+ -+ } -+ STP_DBG_INFO_FUNC("loged packet size = %d, in(%d), out(%d)\n", dumpSize, inIndex, outIndex); -+ while (dumpSize > 0) { -+ pHdr = (STP_DBG_HDR_T *) &(stp_dbg->logsys->queue[outIndex].buffer[0]); -+ pBuf = &(stp_dbg->logsys->queue[outIndex].buffer[0]) + sizeof(STP_DBG_HDR_T); -+ len = stp_dbg->logsys->queue[outIndex].len - sizeof(STP_DBG_HDR_T); -+ len = len > STP_PKT_SZ ? STP_PKT_SZ : len; -+ pr_debug("STP-DBG:%d.%ds, %s:pT%sn(%d)l(%d)s(%d)a(%d)\n", -+ pHdr->sec, -+ pHdr->usec, -+ pHdr->dir == PKT_DIR_TX ? "Tx" : "Rx", -+ gStpDbgType[pHdr->type], pHdr->no, pHdr->len, pHdr->seq, pHdr->ack); -+ -+ if (0 < len) -+ stp_dbg_dump_data(pBuf, pHdr->dir == PKT_DIR_TX ? "Tx" : "Rx", len); -+ outIndex = (outIndex >= (STP_DBG_LOG_ENTRY_NUM - 1)) ? (0) : (outIndex + 1); -+ dumpSize--; -+ -+ } -+ -+ spin_unlock_irqrestore(&(stp_dbg->logsys->lock), flags); -+ -+ return 0; -+} -+ -+int stp_dbg_dmp_out_ex(char *buf, int *len) -+{ -+ return stp_dbg_dmp_out(g_stp_dbg, buf, len); -+} -+ -+int stp_dbg_dmp_out(MTKSTP_DBG_T *stp_dbg, char *buf, int *len) -+{ -+ -+ unsigned long flags; -+ int remaining = 0; -+ *len = 0; -+ spin_lock_irqsave(&(stp_dbg->logsys->lock), flags); -+ -+ if (stp_dbg->logsys->size > 0) { -+ memcpy(buf, &(stp_dbg->logsys->queue[stp_dbg->logsys->out].buffer[0]), -+ stp_dbg->logsys->queue[stp_dbg->logsys->out].len); -+ -+ (*len) = stp_dbg->logsys->queue[stp_dbg->logsys->out].len; -+ stp_dbg->logsys->out = -+ (stp_dbg->logsys->out >= (STP_DBG_LOG_ENTRY_NUM - 1)) ? (0) : (stp_dbg->logsys->out + 1); -+ stp_dbg->logsys->size--; -+ -+ STP_DBG_DBG_FUNC("logsys size = %d, out = %d\n", stp_dbg->logsys->size, stp_dbg->logsys->out); -+ } else { -+ STP_DBG_LOUD_FUNC("logsys EMPTY!\n"); -+ } -+ -+ remaining = (stp_dbg->logsys->size == 0) ? (0) : (1); -+ -+ spin_unlock_irqrestore(&(stp_dbg->logsys->lock), flags); -+ -+ return remaining; -+} -+ -+static int stp_dbg_fill_hdr(struct stp_dbg_pkt_hdr *hdr, int type, int ack, int seq, int crc, int dir, int len, -+ int dbg_type) -+{ -+ -+ struct timeval now; -+ -+ if (!hdr) { -+ STP_DBG_ERR_FUNC("function invalid\n"); -+ return -EINVAL; -+ } -+ do_gettimeofday(&now); -+ hdr->dbg_type = dbg_type; -+ hdr->ack = ack; -+ hdr->seq = seq; -+ hdr->sec = now.tv_sec; -+ hdr->usec = now.tv_usec; -+ hdr->crc = crc; -+ hdr->dir = dir; /* rx */ -+ hdr->dmy = 0xffffffff; -+ hdr->len = len; -+ hdr->type = type; -+ return 0; -+ -+} -+ -+static int stp_dbg_add_pkt(MTKSTP_DBG_T *stp_dbg, struct stp_dbg_pkt_hdr *hdr, const unsigned char *body) -+{ -+ /* fix the frame size large issues. */ -+ static struct stp_dbg_pkt stp_pkt; -+ uint32_t hdr_sz = sizeof(struct stp_dbg_pkt_hdr); -+ uint32_t body_sz = 0; -+ -+ BUG_ON(!stp_dbg); -+ -+ if (hdr->dbg_type == STP_DBG_PKT) -+ body_sz = (hdr->len <= STP_PKT_SZ) ? (hdr->len) : (STP_PKT_SZ); -+ else -+ body_sz = (hdr->len <= STP_DMP_SZ) ? (hdr->len) : (STP_DMP_SZ); -+ -+ hdr->no = stp_dbg->pkt_trace_no++; -+ memcpy((uint8_t *) &stp_pkt.hdr, (uint8_t *) hdr, hdr_sz); -+ if (body != NULL) -+ memcpy((uint8_t *) &stp_pkt.raw[0], body, body_sz); -+ -+ _stp_dbg_dmp_in(stp_dbg, (char *)&stp_pkt, hdr_sz + body_sz); -+ /* Only FW DMP MSG should inform BTM-CORE to dump packet to native process */ -+ if (hdr->dbg_type == STP_DBG_FW_DMP) -+ stp_gdb_notify_btm_dmp_wq(stp_dbg); -+ -+ return 0; -+} -+ -+int stp_dbg_log_pkt(MTKSTP_DBG_T *stp_dbg, int dbg_type, -+ int type, int ack_no, int seq_no, int crc, int dir, int len, const unsigned char *body) -+{ -+ -+ struct stp_dbg_pkt_hdr hdr; -+ -+ if (stp_dbg->is_enable == 0) { -+ /*dbg is disable,and not to log */ -+ } else { -+ hdr.no = 0; -+ hdr.chs = 0; -+ stp_dbg_fill_hdr(&hdr, -+ (int)type, (int)ack_no, (int)seq_no, (int)crc, (int)dir, (int)len, (int)dbg_type); -+ -+ stp_dbg_add_pkt(stp_dbg, &hdr, body); -+ } -+ -+ return 0; -+} -+ -+int stp_dbg_enable(MTKSTP_DBG_T *stp_dbg) -+{ -+ return _stp_dbg_enable(stp_dbg); -+} -+ -+int stp_dbg_disable(MTKSTP_DBG_T *stp_dbg) -+{ -+ return _stp_dbg_disable(stp_dbg); -+} -+ -+static void stp_dbg_nl_init(void) -+{ -+#if 0 -+ if (genl_register_family(&stp_dbg_gnl_family) != 0) { -+ STP_DBG_ERR_FUNC("%s(): GE_NELINK family registration fail\n", __func__); -+ } else { -+ if (genl_register_ops(&stp_dbg_gnl_family, &stp_dbg_gnl_ops_bind) != 0) -+ STP_DBG_ERR_FUNC("%s(): BIND operation registration fail\n", __func__); -+ -+ if (genl_register_ops(&stp_dbg_gnl_family, &stp_dbg_gnl_ops_reset) != 0) -+ STP_DBG_ERR_FUNC("%s(): RESET operation registration fail\n", __func__); -+ -+ } -+#endif -+ if (genl_register_family_with_ops(&stp_dbg_gnl_family, stp_dbg_gnl_ops_array) != 0) -+ STP_DBG_ERR_FUNC("%s(): GE_NELINK family registration fail\n", __func__); -+} -+ -+static void stp_dbg_nl_deinit(void) -+{ -+ genl_unregister_family(&stp_dbg_gnl_family); -+} -+ -+static int stp_dbg_nl_bind(struct sk_buff *skb, struct genl_info *info) -+{ -+ struct nlattr *na; -+ char *mydata; -+ -+ if (info == NULL) -+ goto out; -+ -+ STP_DBG_INFO_FUNC("%s():->\n", __func__); -+ -+ na = info->attrs[STP_DBG_ATTR_MSG]; -+ -+ if (na) -+ mydata = (char *)nla_data(na); -+ -+ if (num_bind_process < MAX_BIND_PROCESS) { -+ bind_pid[num_bind_process] = info->snd_portid; -+ num_bind_process++; -+ STP_DBG_INFO_FUNC("%s():-> pid = %d\n", __func__, info->snd_portid); -+ } else { -+ STP_DBG_ERR_FUNC("%s(): exceeding binding limit %d\n", __func__, MAX_BIND_PROCESS); -+ } -+ -+out: -+ return 0; -+} -+ -+static int stp_dbg_nl_reset(struct sk_buff *skb, struct genl_info *info) -+{ -+ STP_DBG_ERR_FUNC("%s(): should not be invoked\n", __func__); -+ -+ return 0; -+} -+ -+INT8 stp_dbg_nl_send(PINT8 aucMsg, UINT8 cmd, INT32 len) -+{ -+ struct sk_buff *skb = NULL; -+ void *msg_head = NULL; -+ int rc = -1; -+ int i; -+ -+ if (num_bind_process == 0) { -+ /* no listening process */ -+ STP_DBG_ERR_FUNC("%s(): the process is not invoked\n", __func__); -+ return 0; -+ } -+ -+ for (i = 0; i < num_bind_process; i++) { -+ skb = genlmsg_new(2048, GFP_KERNEL); -+ -+ if (skb) { -+ msg_head = genlmsg_put(skb, 0, stp_dbg_seqnum++, &stp_dbg_gnl_family, 0, cmd); -+ if (msg_head == NULL) { -+ nlmsg_free(skb); -+ STP_DBG_ERR_FUNC("%s(): genlmsg_put fail...\n", __func__); -+ return -1; -+ } -+ -+ rc = nla_put(skb, STP_DBG_ATTR_MSG, len, aucMsg); -+ if (rc != 0) { -+ nlmsg_free(skb); -+ STP_DBG_ERR_FUNC("%s(): nla_put_string fail...%d\n", __func__, rc); -+ return -1; -+ } -+ -+ /* finalize the message */ -+ genlmsg_end(skb, msg_head); -+ -+ /* sending message */ -+ rc = genlmsg_unicast(&init_net, skb, bind_pid[i]); -+ if (rc != 0) { -+ STP_DBG_ERR_FUNC("%s(): genlmsg_unicast fail...\n", __func__); -+ return -1; -+ } -+ } else { -+ STP_DBG_ERR_FUNC("%s(): genlmsg_new fail...\n", __func__); -+ return -1; -+ } -+ } -+ -+ return 0; -+} -+ -+INT32 stp_dbg_aee_send(unsigned char *aucMsg, INT32 len, INT32 cmd) -+{ -+ INT32 ret = 0; -+ -+ /* buffered to compressor */ -+ ret = wcn_core_dump_in(g_core_dump, aucMsg, len); -+ if (ret == 1) -+ wcn_core_dump_flush(0, MTK_WCN_BOOL_FALSE); -+ -+ return ret; -+} -+ -+UINT8 *_stp_dbg_id_to_task(UINT32 id) -+{ -+ UINT8 *taskStr[] = { -+ "Task_WMT", -+ "Task_BT", -+ "Task_Wifi", -+ "Task_Tst", -+ "Task_FM", -+ "Task_Idle", -+ "Task_DrvStp", -+ "Task_DrvBtif", -+ "Task_NatBt" -+ }; -+ return taskStr[id]; -+} -+ -+INT32 _stp_dbg_parser_assert_str(PINT8 str, ENUM_ASSERT_INFO_PARSER_TYPE type) -+{ -+ char *pStr = NULL; -+ char *pDtr = NULL; -+ char *pTemp = NULL; -+ char *pTemp2 = NULL; -+ char tempBuf[64] = { 0 }; -+ UINT32 len = 0; -+ long res; -+ INT32 ret; -+ -+ PUINT8 parser_sub_string[] = { -+ " ", -+ "id=", -+ "isr=", -+ "irq=", -+ "rc=" -+ }; -+ -+ if (!str) { -+ STP_DBG_ERR_FUNC("NULL string source\n"); -+ return -1; -+ } -+ -+ if (!g_stp_dbg_cpupcr) { -+ STP_DBG_ERR_FUNC("NULL pointer\n"); -+ return -2; -+ } -+ -+ pStr = str; -+ STP_DBG_DBG_FUNC("source infor:%s\n", pStr); -+ switch (type) { -+ case STP_DBG_ASSERT_INFO: -+ pDtr = osal_strstr(pStr, parser_sub_string[type]); -+ if (NULL != pDtr) { -+ pDtr += osal_strlen(parser_sub_string[type]); -+ pTemp = osal_strchr(pDtr, ' '); -+ } else { -+ STP_DBG_ERR_FUNC("parser str is NULL,substring(%s)\n", parser_sub_string[type]); -+ return -3; -+ } -+ len = pTemp - pDtr; -+ osal_memcpy(&g_stp_dbg_cpupcr->assert_info[0], "assert@", osal_strlen("assert@")); -+ osal_memcpy(&g_stp_dbg_cpupcr->assert_info[osal_strlen("assert@")], pDtr, len); -+ g_stp_dbg_cpupcr->assert_info[osal_strlen("assert@") + len] = '_'; -+ -+ pTemp = osal_strchr(pDtr, '#'); -+ pTemp += 1; -+ -+ pTemp2 = osal_strchr(pTemp, ' '); -+ osal_memcpy(&g_stp_dbg_cpupcr->assert_info[osal_strlen("assert@") + len + 1], pTemp, pTemp2 - pTemp); -+ g_stp_dbg_cpupcr->assert_info[osal_strlen("assert@") + len + 1 + pTemp2 - pTemp] = '\0'; -+ STP_DBG_INFO_FUNC("assert info:%s\n", &g_stp_dbg_cpupcr->assert_info[0]); -+ break; -+ case STP_DBG_FW_TASK_ID: -+ pDtr = osal_strstr(pStr, parser_sub_string[type]); -+ if (NULL != pDtr) { -+ pDtr += osal_strlen(parser_sub_string[type]); -+ pTemp = osal_strchr(pDtr, ' '); -+ } else { -+ STP_DBG_ERR_FUNC("parser str is NULL,substring(%s)\n", parser_sub_string[type]); -+ return -3; -+ } -+ len = pTemp - pDtr; -+ osal_memcpy(&tempBuf[0], pDtr, len); -+ tempBuf[len] = '\0'; -+ ret = osal_strtol(tempBuf, 16, &res); -+ if (ret) { -+ STP_DBG_ERR_FUNC("get fw task id fail(%d)\n", ret); -+ return -4; -+ } -+ g_stp_dbg_cpupcr->fwTaskId = (UINT32)res; -+ -+ STP_DBG_INFO_FUNC("fw task id :%x\n", (UINT32)res); -+ break; -+ case STP_DBG_FW_ISR: -+ pDtr = osal_strstr(pStr, parser_sub_string[type]); -+ if (NULL != pDtr) { -+ pDtr += osal_strlen(parser_sub_string[type]); -+ pTemp = osal_strchr(pDtr, ','); -+ } else { -+ STP_DBG_ERR_FUNC("parser str is NULL,substring(%s)\n", parser_sub_string[type]); -+ return -3; -+ } -+ len = pTemp - pDtr; -+ osal_memcpy(&tempBuf[0], pDtr, len); -+ tempBuf[len] = '\0'; -+ ret = osal_strtol(tempBuf, 16, &res); -+ if (ret) { -+ STP_DBG_ERR_FUNC("get fw isr id fail(%d)\n", ret); -+ return -4; -+ } -+ g_stp_dbg_cpupcr->fwIsr = (UINT32)res; -+ -+ STP_DBG_INFO_FUNC("fw isr str:%x\n", (UINT32)res); -+ break; -+ case STP_DBG_FW_IRQ: -+ pDtr = osal_strstr(pStr, parser_sub_string[type]); -+ if (NULL != pDtr) { -+ pDtr += osal_strlen(parser_sub_string[type]); -+ pTemp = osal_strchr(pDtr, ','); -+ } else { -+ STP_DBG_ERR_FUNC("parser str is NULL,substring(%s)\n", parser_sub_string[type]); -+ return -3; -+ } -+ len = pTemp - pDtr; -+ osal_memcpy(&tempBuf[0], pDtr, len); -+ tempBuf[len] = '\0'; -+ ret = osal_strtol(tempBuf, 16, &res); -+ if (ret) { -+ STP_DBG_ERR_FUNC("get fw irq id fail(%d)\n", ret); -+ return -4; -+ } -+ g_stp_dbg_cpupcr->fwRrq = (UINT32)res; -+ -+ STP_DBG_INFO_FUNC("fw irq value:%x\n", (UINT32)res); -+ break; -+ case STP_DBG_ASSERT_TYPE: -+ pDtr = osal_strstr(pStr, parser_sub_string[type]); -+ if (NULL != pDtr) { -+ pDtr += osal_strlen(parser_sub_string[type]); -+ pTemp = osal_strchr(pDtr, ','); -+ } else { -+ STP_DBG_ERR_FUNC("parser str is NULL,substring(%s)\n", parser_sub_string[type]); -+ return -3; -+ } -+ len = pTemp - pDtr; -+ osal_memcpy(&tempBuf[0], pDtr, len); -+ tempBuf[len] = '\0'; -+ -+ if (0 == osal_memcmp(tempBuf, "*", len)) -+ osal_memcpy(&g_stp_dbg_cpupcr->assert_type[0], "general assert", osal_strlen("general assert")); -+ if (0 == osal_memcmp(tempBuf, "Watch Dog Timeout", len)) -+ osal_memcpy(&g_stp_dbg_cpupcr->assert_type[0], "wdt", osal_strlen("wdt")); -+ if (0 == osal_memcmp(tempBuf, "RB_FULL", osal_strlen("RB_FULL"))) { -+ osal_memcpy(&g_stp_dbg_cpupcr->assert_type[0], tempBuf, len); -+ -+ pDtr = osal_strstr(&g_stp_dbg_cpupcr->assert_type[0], "RB_FULL("); -+ if (NULL != pDtr) { -+ pDtr += osal_strlen("RB_FULL("); -+ pTemp = osal_strchr(pDtr, ')'); -+ } else { -+ STP_DBG_ERR_FUNC("parser str is NULL,substring(RB_FULL()\n"); -+ return -4; -+ } -+ len = pTemp - pDtr; -+ osal_memcpy(&tempBuf[0], pDtr, len); -+ tempBuf[len] = '\0'; -+ ret = osal_strtol(tempBuf, 16, &res); -+ if (ret) { -+ STP_DBG_ERR_FUNC("get fw task id fail(%d)\n", ret); -+ return -5; -+ } -+ g_stp_dbg_cpupcr->fwTaskId = (UINT32)res; -+ -+ STP_DBG_INFO_FUNC("update fw task id :%x\n", (UINT32)res); -+ } -+ -+ STP_DBG_INFO_FUNC("fw asert type:%s\n", g_stp_dbg_cpupcr->assert_type); -+ break; -+ default: -+ STP_DBG_ERR_FUNC("unknown parser type\n"); -+ break; -+ } -+ -+ return 0; -+} -+ -+P_STP_DBG_CPUPCR_T stp_dbg_cpupcr_init(VOID) -+{ -+ P_STP_DBG_CPUPCR_T pSdCpupcr = NULL; -+ -+ pSdCpupcr = (P_STP_DBG_CPUPCR_T) osal_malloc(osal_sizeof(STP_DBG_CPUPCR_T)); -+ if (!pSdCpupcr) { -+ STP_DBG_ERR_FUNC("stp dbg cpupcr allocate memory fail!\n"); -+ return NULL; -+ } -+ -+ osal_memset(pSdCpupcr, 0, osal_sizeof(STP_DBG_CPUPCR_T)); -+ -+ osal_sleepable_lock_init(&pSdCpupcr->lock); -+ -+ return pSdCpupcr; -+} -+ -+P_STP_DBG_DMAREGS_T stp_dbg_dmaregs_init(VOID) -+{ -+ P_STP_DBG_DMAREGS_T pDmaRegs = NULL; -+ -+ pDmaRegs = (P_STP_DBG_DMAREGS_T) osal_malloc(osal_sizeof(STP_DBG_DMAREGS_T)); -+ if (!pDmaRegs) { -+ STP_DBG_ERR_FUNC("stp dbg dmareg allocate memory fail!\n"); -+ return NULL; -+ } -+ -+ osal_memset(pDmaRegs, 0, osal_sizeof(STP_DBG_DMAREGS_T)); -+ -+ osal_sleepable_lock_init(&pDmaRegs->lock); -+ -+ return pDmaRegs; -+} -+ -+VOID stp_dbg_cpupcr_deinit(P_STP_DBG_CPUPCR_T pCpupcr) -+{ -+ if (pCpupcr) { -+ osal_sleepable_lock_deinit(&pCpupcr->lock); -+ osal_free(pCpupcr); -+ pCpupcr = NULL; -+ } -+} -+ -+VOID stp_dbg_dmaregs_deinit(P_STP_DBG_DMAREGS_T pDmaRegs) -+{ -+ if (pDmaRegs) { -+ osal_sleepable_lock_deinit(&pDmaRegs->lock); -+ osal_free(pDmaRegs); -+ pDmaRegs = NULL; -+ } -+} -+ -+INT32 stp_dbg_poll_cpupcr(UINT32 times, UINT32 sleep, UINT32 cmd) -+{ -+ INT32 i = 0; -+ -+ if (!g_stp_dbg_cpupcr) { -+ STP_DBG_ERR_FUNC("NULL reference pointer\n"); -+ return -1; -+ } -+ -+ if (!cmd) { -+ if (g_stp_dbg_cpupcr->count + times > STP_DBG_CPUPCR_NUM) -+ times = STP_DBG_CPUPCR_NUM - g_stp_dbg_cpupcr->count; -+ -+ osal_lock_sleepable_lock(&g_stp_dbg_cpupcr->lock); -+ -+ for (i = 0; i < times; i++) { -+ STP_DBG_INFO_FUNC("i:%d,cpupcr:%08x\n", i, wmt_plat_read_cpupcr()); -+ /* osal_memcpy( -+ * &g_stp_dbg_cpupcr->buffer[i], -+ * (UINT8*)(CONSYS_REG_READ(CONSYS_CPUPCR_REG)), -+ * osal_sizeof(UINT32)); -+ */ -+ g_stp_dbg_cpupcr->buffer[g_stp_dbg_cpupcr->count + i] = wmt_plat_read_cpupcr(); -+ osal_sleep_ms(sleep); -+ } -+ g_stp_dbg_cpupcr->count += times; -+ -+ osal_unlock_sleepable_lock(&g_stp_dbg_cpupcr->lock); -+ } else { -+ STP_DBG_INFO_FUNC("stp-dbg: for proc test polling cpupcr\n"); -+ if (times > STP_DBG_CPUPCR_NUM) -+ times = STP_DBG_CPUPCR_NUM; -+ -+ osal_lock_sleepable_lock(&g_stp_dbg_cpupcr->lock); -+ g_stp_dbg_cpupcr->count = 0; -+ for (i = 0; i < times; i++) { -+ STP_DBG_INFO_FUNC("i:%d,cpupcr:%08x\n", i, wmt_plat_read_cpupcr()); -+ /* osal_memcpy( -+ * &g_stp_dbg_cpupcr->buffer[i], -+ * (UINT8*)(CONSYS_REG_READ(CONSYS_CPUPCR_REG)), -+ * osal_sizeof(UINT32)); -+ */ -+ g_stp_dbg_cpupcr->buffer[i] = wmt_plat_read_cpupcr(); -+ osal_sleep_ms(sleep); -+ } -+ g_stp_dbg_cpupcr->count = times; -+ -+ osal_unlock_sleepable_lock(&g_stp_dbg_cpupcr->lock); -+ -+ } -+ return 0; -+} -+ -+INT32 stp_dbg_poll_dmaregs(UINT32 times, UINT32 sleep) -+{ -+#if 0 -+ INT32 i = 0; -+ -+ if (!g_stp_dbg_dmaregs) { -+ STP_DBG_ERR_FUNC("NULL reference pointer\n"); -+ return -1; -+ } -+ -+ osal_lock_sleepable_lock(&g_stp_dbg_dmaregs->lock); -+ -+ if (g_stp_dbg_dmaregs->count + times > STP_DBG_DMAREGS_NUM) { -+ if (g_stp_dbg_dmaregs->count > STP_DBG_DMAREGS_NUM) { -+ STP_DBG_ERR_FUNC("g_stp_dbg_dmaregs->count:%d must less than STP_DBG_DMAREGS_NUM:%d\n", -+ g_stp_dbg_dmaregs->count, STP_DBG_DMAREGS_NUM); -+ g_stp_dbg_dmaregs->count = 0; -+ STP_DBG_ERR_FUNC("g_stp_dbg_dmaregs->count be set default value 0\n"); -+ } -+ times = STP_DBG_DMAREGS_NUM - g_stp_dbg_dmaregs->count; -+ } -+ if (times > STP_DBG_DMAREGS_NUM) { -+ STP_DBG_ERR_FUNC("times overflow, set default value:0\n"); -+ times = 0; -+ } -+ STP_DBG_WARN_FUNC("---------Now Polling DMA relative Regs -------------\n"); -+ for (i = 0; i < times; i++) { -+ INT32 k = 0; -+ -+ for (; k < DMA_REGS_MAX; k++) { -+ STP_DBG_WARN_FUNC("times:%d,i:%d reg: %s, regs:%08x\n", times, i, dmaRegsStr[k], -+ wmt_plat_read_dmaregs(k)); -+ /* g_stp_dbg_dmaregs->dmaIssue[k][g_stp_dbg_dmaregs->count + i] = wmt_plat_read_dmaregs(k); */ -+ } -+ osal_sleep_ms(sleep); -+ } -+ STP_DBG_WARN_FUNC("---------Polling DMA relative Regs End-------------\n"); -+ g_stp_dbg_dmaregs->count += times; -+ -+ osal_unlock_sleepable_lock(&g_stp_dbg_dmaregs->lock); -+#else -+ return 0; -+#endif -+} -+ -+INT32 stp_dbg_poll_cuppcr_ctrl(UINT32 en) -+{ -+ -+ STP_DBG_INFO_FUNC("%s polling cpupcr\n", en == 0 ? "start" : "stop"); -+ -+ osal_lock_sleepable_lock(&g_stp_dbg_cpupcr->lock); -+ g_stp_dbg_cpupcr->stop_flag = en; -+ osal_unlock_sleepable_lock(&g_stp_dbg_cpupcr->lock); -+ return 0; -+} -+ -+INT32 stp_dbg_set_version_info(UINT32 chipid, UINT8 *pRomVer, UINT8 *pPatchVer, UINT8 *pPatchBrh) -+{ -+ if (g_stp_dbg_cpupcr) { -+ osal_lock_sleepable_lock(&g_stp_dbg_cpupcr->lock); -+ g_stp_dbg_cpupcr->chipId = chipid; -+ -+ if (pRomVer) -+ osal_memcpy(g_stp_dbg_cpupcr->romVer, pRomVer, 2); -+ if (pPatchVer) -+ osal_memcpy(g_stp_dbg_cpupcr->patchVer, pPatchVer, 8); -+ if (pPatchBrh) -+ osal_memcpy(g_stp_dbg_cpupcr->branchVer, pPatchBrh, 4); -+ -+ osal_unlock_sleepable_lock(&g_stp_dbg_cpupcr->lock); -+ } else { -+ STP_DBG_ERR_FUNC("NULL pointer\n"); -+ return -1; -+ } -+ STP_DBG_INFO_FUNC("chipid(0x%x),romver(%s),patchver(%s),branchver(%s)\n", g_stp_dbg_cpupcr->chipId, -+ &g_stp_dbg_cpupcr->romVer[0], &g_stp_dbg_cpupcr->patchVer[0], &g_stp_dbg_cpupcr->branchVer[0]); -+ return 0; -+} -+INT32 stp_dbg_set_wifiver(UINT32 wifiver) -+{ -+ if (g_stp_dbg_cpupcr) { -+ osal_lock_sleepable_lock(&g_stp_dbg_cpupcr->lock); -+ g_stp_dbg_cpupcr->wifiVer = wifiver; -+ osal_unlock_sleepable_lock(&g_stp_dbg_cpupcr->lock); -+ } else { -+ STP_DBG_ERR_FUNC("NULL pointer\n"); -+ return -1; -+ } -+ STP_DBG_INFO_FUNC("wifiver(%x)\n", g_stp_dbg_cpupcr->wifiVer); -+ return 0; -+} -+ -+INT32 stp_dbg_set_host_assert_info(UINT32 drv_type, UINT32 reason, UINT32 en) -+{ -+ osal_lock_sleepable_lock(&g_stp_dbg_cpupcr->lock); -+ -+ g_stp_dbg_cpupcr->host_assert_info.assert_from_host = en; -+ g_stp_dbg_cpupcr->host_assert_info.drv_type = drv_type; -+ g_stp_dbg_cpupcr->host_assert_info.reason = reason; -+ -+ osal_unlock_sleepable_lock(&g_stp_dbg_cpupcr->lock); -+ -+ return 0; -+} -+ -+UINT32 stp_dbg_get_host_trigger_assert(VOID) -+{ -+ return g_stp_dbg_cpupcr->host_assert_info.assert_from_host; -+} -+ -+INT32 stp_dbg_set_fw_info(UINT8 *issue_info, UINT32 len, ENUM_STP_FW_ISSUE_TYPE issue_type) -+{ -+ ENUM_ASSERT_INFO_PARSER_TYPE type_index; -+ PUINT8 tempbuf = NULL; -+ UINT32 i = 0; -+ INT32 iRet = 0; -+ -+ if (NULL == issue_info) { -+ STP_DBG_ERR_FUNC("null issue infor\n"); -+ return -1; -+ } -+ STP_DBG_INFO_FUNC("issue type(%d)\n", issue_type); -+ g_stp_dbg_cpupcr->issue_type = issue_type; -+ osal_memset(&g_stp_dbg_cpupcr->assert_info[0], 0, STP_ASSERT_INFO_SIZE); -+ -+ /*print patch version when assert happened */ -+ STP_DBG_INFO_FUNC("=======================================\n"); -+ STP_DBG_INFO_FUNC("[consys patch]patch version:%s\n", g_stp_dbg_cpupcr->patchVer); -+ STP_DBG_INFO_FUNC("[consys patch]ALPS branch:%s\n", g_stp_dbg_cpupcr->branchVer); -+ STP_DBG_INFO_FUNC("=======================================\n"); -+ -+ if ((STP_FW_ASSERT_ISSUE == issue_type) || -+ (STP_HOST_TRIGGER_FW_ASSERT == issue_type) || (STP_HOST_TRIGGER_ASSERT_TIMEOUT == issue_type)) { -+ if ((STP_FW_ASSERT_ISSUE == issue_type) || (STP_HOST_TRIGGER_FW_ASSERT == issue_type)) { -+ tempbuf = osal_malloc(len + 1); -+ if (!tempbuf) -+ return -2; -+ -+ osal_memcpy(&tempbuf[0], issue_info, len); -+ -+ for (i = 0; i < len; i++) { -+ if (tempbuf[i] == '\0') -+ tempbuf[i] = '?'; -+ } -+ -+ tempbuf[len] = '\0'; -+ -+ for (type_index = STP_DBG_ASSERT_INFO; type_index < STP_DBG_PARSER_TYPE_MAX; type_index++) -+ iRet += _stp_dbg_parser_assert_str(&tempbuf[0], type_index); -+ -+ if (iRet) -+ STP_DBG_ERR_FUNC("passert assert infor fail(%d)\n", iRet); -+ -+ } -+ if ((STP_HOST_TRIGGER_FW_ASSERT == issue_type) || (STP_HOST_TRIGGER_ASSERT_TIMEOUT == issue_type)) { -+ switch (g_stp_dbg_cpupcr->host_assert_info.drv_type) { -+ case 0: -+ STP_DBG_INFO_FUNC("BT trigger assert\n"); -+ osal_lock_sleepable_lock(&g_stp_dbg_cpupcr->lock); -+ if (31 != g_stp_dbg_cpupcr->host_assert_info.reason) -+ /*BT firmware trigger assert */ -+ { -+ g_stp_dbg_cpupcr->fwTaskId = 1; -+ -+ } else -+ /*BT stack trigger assert */ -+ { -+ g_stp_dbg_cpupcr->fwTaskId = 8; -+ } -+ -+ g_stp_dbg_cpupcr->host_assert_info.assert_from_host = 0; -+ /* g_stp_dbg_cpupcr->host_assert_info.drv_type = 0; */ -+ /* g_stp_dbg_cpupcr->host_assert_info.reason = 0; */ -+ -+ osal_unlock_sleepable_lock(&g_stp_dbg_cpupcr->lock); -+ -+ break; -+ case 4: -+ STP_DBG_INFO_FUNC("WMT trigger assert\n"); -+ osal_lock_sleepable_lock(&g_stp_dbg_cpupcr->lock); -+ if (STP_HOST_TRIGGER_ASSERT_TIMEOUT == issue_type) -+ osal_memcpy(&g_stp_dbg_cpupcr->assert_info[0], issue_info, len); -+ -+ if ((38 == g_stp_dbg_cpupcr->host_assert_info.reason) || -+ (39 == g_stp_dbg_cpupcr->host_assert_info.reason) || -+ (40 == g_stp_dbg_cpupcr->host_assert_info.reason)) -+ g_stp_dbg_cpupcr->fwTaskId = 6; /* HOST schedule reason trigger */ -+ else -+ g_stp_dbg_cpupcr->fwTaskId = 0; /* Must be firmware reason */ -+ g_stp_dbg_cpupcr->host_assert_info.assert_from_host = 0; -+ osal_unlock_sleepable_lock(&g_stp_dbg_cpupcr->lock); -+ break; -+ default: -+ break; -+ } -+ -+ } -+ osal_free(tempbuf); -+ } else if (STP_FW_NOACK_ISSUE == issue_type) { -+ osal_lock_sleepable_lock(&g_stp_dbg_cpupcr->lock); -+ osal_memcpy(&g_stp_dbg_cpupcr->assert_info[0], issue_info, len); -+ g_stp_dbg_cpupcr->fwTaskId = 6; -+ g_stp_dbg_cpupcr->fwRrq = 0; -+ g_stp_dbg_cpupcr->fwIsr = 0; -+ osal_unlock_sleepable_lock(&g_stp_dbg_cpupcr->lock); -+ } else if (STP_DBG_PROC_TEST == issue_type) { -+ osal_lock_sleepable_lock(&g_stp_dbg_cpupcr->lock); -+ osal_memcpy(&g_stp_dbg_cpupcr->assert_info[0], issue_info, len); -+ g_stp_dbg_cpupcr->fwTaskId = 0; -+ g_stp_dbg_cpupcr->fwRrq = 0; -+ g_stp_dbg_cpupcr->fwIsr = 0; -+ osal_unlock_sleepable_lock(&g_stp_dbg_cpupcr->lock); -+ } else if (STP_FW_WARM_RST_ISSUE == issue_type) { -+ osal_lock_sleepable_lock(&g_stp_dbg_cpupcr->lock); -+ osal_memcpy(&g_stp_dbg_cpupcr->assert_info[0], issue_info, len); -+ g_stp_dbg_cpupcr->fwTaskId = 0; -+ g_stp_dbg_cpupcr->fwRrq = 0; -+ g_stp_dbg_cpupcr->fwIsr = 0; -+ osal_unlock_sleepable_lock(&g_stp_dbg_cpupcr->lock); -+ } else { -+ STP_DBG_ERR_FUNC("invalid issue type(%d)\n", issue_type); -+ return -3; -+ } -+ -+ return iRet; -+} -+ -+INT32 stp_dbg_cpupcr_infor_format(PPUINT8 buf, PUINT32 str_len) -+{ -+ UINT32 len = 0; -+ UINT32 i = 0; -+ -+ if (!g_stp_dbg_cpupcr) { -+ STP_DBG_ERR_FUNC("NULL pointer\n"); -+ return -1; -+ } -+ -+ /*format common information about issue */ -+ len = osal_sprintf(*buf, "
\n\t"); -+ len += osal_sprintf(*buf + len, "\n\t\tMT%x\n\t\n\t", g_stp_dbg_cpupcr->chipId); -+ len += osal_sprintf(*buf + len, "\n\t\t"); -+ len += osal_sprintf(*buf + len, "%s\n\t\t", g_stp_dbg_cpupcr->romVer); -+ if (!(osal_memcmp(g_stp_dbg_cpupcr->branchVer, "ALPS", strlen("ALPS")))) -+ len += osal_sprintf(*buf + len, "Internal Dev\n\t\t", g_stp_dbg_cpupcr->branchVer); -+ else -+ len += osal_sprintf(*buf + len, "W%sMP\n\t\t", g_stp_dbg_cpupcr->branchVer); -+ -+ len += osal_sprintf(*buf + len, "%s\n\t\t", g_stp_dbg_cpupcr->patchVer); -+ -+ if (0 == g_stp_dbg_cpupcr->wifiVer) -+ len += osal_sprintf(*buf + len, "NULL\n\t"); -+ else -+ len += osal_sprintf(*buf + len, "0x%X.%X\n\t", -+ (UINT8)((g_stp_dbg_cpupcr->wifiVer & 0xFF00)>>8), (UINT8)(g_stp_dbg_cpupcr->wifiVer & 0xFF)); -+ -+ len += osal_sprintf(*buf + len, "\n\t"); -+ -+ /*format issue information: no ack, assert */ -+ len += osal_sprintf(*buf + len, "\n\t\t\n\t\t\t"); -+ if ((STP_FW_NOACK_ISSUE == g_stp_dbg_cpupcr->issue_type) || -+ (STP_DBG_PROC_TEST == g_stp_dbg_cpupcr->issue_type) || -+ (STP_FW_WARM_RST_ISSUE == g_stp_dbg_cpupcr->issue_type)) { -+ len += -+ osal_sprintf(*buf + len, "%s\n\t\t\n\t\t\n\t\t\t", -+ g_stp_dbg_cpupcr->assert_info); -+ len += osal_sprintf(*buf + len, "NULL\n\t\t\n\t\n\t"); -+ len += osal_sprintf(*buf + len, "\n\t\tNULL\n\t\t"); -+ len += osal_sprintf(*buf + len, "NULL\n\t\t"); -+ len += -+ osal_sprintf(*buf + len, "\n\t\t\t%s\n\t\t\t", -+ _stp_dbg_id_to_task(g_stp_dbg_cpupcr->fwTaskId)); -+ len += osal_sprintf(*buf + len, "IRQ_0x%x\n\t\t\t", g_stp_dbg_cpupcr->fwRrq); -+ len += osal_sprintf(*buf + len, "0x%x\n\t\t\t", g_stp_dbg_cpupcr->fwIsr); -+ len += osal_sprintf(*buf + len, "NULL\n\t\t\t"); -+ len += osal_sprintf(*buf + len, "NULL\n\t\t\t"); -+ } else if ((STP_FW_ASSERT_ISSUE == g_stp_dbg_cpupcr->issue_type) || -+ (STP_HOST_TRIGGER_FW_ASSERT == g_stp_dbg_cpupcr->issue_type) || -+ (STP_HOST_TRIGGER_ASSERT_TIMEOUT == g_stp_dbg_cpupcr->issue_type)) { -+ len += -+ osal_sprintf(*buf + len, "%s\n\t\t\n\t\t\n\t\t\t", -+ g_stp_dbg_cpupcr->assert_info); -+ len += osal_sprintf(*buf + len, "%s\n\t\t\n\t\n\t", g_stp_dbg_cpupcr->assert_type); -+ len += osal_sprintf(*buf + len, "\n\t\tNULL\n\t\t"); -+ len += osal_sprintf(*buf + len, "NULL\n\t\t"); -+ len += -+ osal_sprintf(*buf + len, "\n\t\t\t%s\n\t\t\t", -+ _stp_dbg_id_to_task(g_stp_dbg_cpupcr->fwTaskId)); -+ if (32 == g_stp_dbg_cpupcr->host_assert_info.reason || 33 == g_stp_dbg_cpupcr->host_assert_info.reason -+ || 34 == g_stp_dbg_cpupcr->host_assert_info.reason -+ || 35 == g_stp_dbg_cpupcr->host_assert_info.reason -+ || 36 == g_stp_dbg_cpupcr->host_assert_info.reason -+ || 37 == g_stp_dbg_cpupcr->host_assert_info.reason -+ || 38 == g_stp_dbg_cpupcr->host_assert_info.reason -+ || 39 == g_stp_dbg_cpupcr->host_assert_info.reason -+ || 40 == g_stp_dbg_cpupcr->host_assert_info.reason) { -+ /*handling wmt turn on/off bt cmd has ack but no evt issue */ -+ /*one of both the irqx and irs is nULL, then use task to find MOF */ -+ len += osal_sprintf(*buf + len, "NULL\n\t\t\t"); -+ } else { -+ len += osal_sprintf(*buf + len, "IRQ_0x%x\n\t\t\t", g_stp_dbg_cpupcr->fwRrq); -+ } -+ len += osal_sprintf(*buf + len, "0x%x\n\t\t\t", g_stp_dbg_cpupcr->fwIsr); -+ -+ if (STP_FW_ASSERT_ISSUE == g_stp_dbg_cpupcr->issue_type) { -+ len += osal_sprintf(*buf + len, "NULL\n\t\t\t"); -+ len += osal_sprintf(*buf + len, "NULL\n\t\t\t"); -+ } -+ -+ if ((STP_HOST_TRIGGER_FW_ASSERT == g_stp_dbg_cpupcr->issue_type) || -+ (STP_HOST_TRIGGER_ASSERT_TIMEOUT == g_stp_dbg_cpupcr->issue_type)) { -+ len += -+ osal_sprintf(*buf + len, "%d\n\t\t\t", -+ g_stp_dbg_cpupcr->host_assert_info.drv_type); -+ len += -+ osal_sprintf(*buf + len, "%d\n\t\t\t", -+ g_stp_dbg_cpupcr->host_assert_info.reason); -+ } -+ } else { -+ len += osal_sprintf(*buf + len, "NULL\n\t\t\n\t\t\n\t\t\t"); -+ len += osal_sprintf(*buf + len, "NULL\n\t\t\n\t\n\t"); -+ len += osal_sprintf(*buf + len, "\n\t\tNULL\n\t\t"); -+ len += osal_sprintf(*buf + len, "NULL\n\t\t"); -+ len += osal_sprintf(*buf + len, "\n\t\t\tNULL\n\t\t\t"); -+ len += osal_sprintf(*buf + len, "NULL\n\t\t\t"); -+ len += osal_sprintf(*buf + len, "NULL\n\t\t\t"); -+ len += osal_sprintf(*buf + len, "NULL\n\t\t\t"); -+ len += osal_sprintf(*buf + len, "NULL\n\t\t\t"); -+ } -+ -+ len += osal_sprintf(*buf + len, ""); -+ STP_DBG_INFO_FUNC("stp-dbg:sub len1 for debug(%d)\n", len); -+ -+ if (!g_stp_dbg_cpupcr->count) -+ len += osal_sprintf(*buf + len, "NULL"); -+ else { -+ for (i = 0; i < g_stp_dbg_cpupcr->count; i++) -+ len += osal_sprintf(*buf + len, "%08x,", g_stp_dbg_cpupcr->buffer[i]); -+ } -+ STP_DBG_INFO_FUNC("stp-dbg:sub len2 for debug(%d)\n", len); -+ len += osal_sprintf(*buf + len, "\n\t\t\t"); -+ len += osal_sprintf(*buf + len, "NULL\n\t\t\n\t\n
\n"); -+ STP_DBG_INFO_FUNC("buffer len[%d]\n", len); -+ /* STP_DBG_INFO_FUNC("Format infor:\n%s\n",*buf); */ -+ *str_len = len; -+ -+ osal_lock_sleepable_lock(&g_stp_dbg_cpupcr->lock); -+ osal_memset(&g_stp_dbg_cpupcr->buffer[0], 0, STP_DBG_CPUPCR_NUM); -+ g_stp_dbg_cpupcr->count = 0; -+ g_stp_dbg_cpupcr->host_assert_info.reason = 0; -+ g_stp_dbg_cpupcr->host_assert_info.drv_type = 0; -+ osal_unlock_sleepable_lock(&g_stp_dbg_cpupcr->lock); -+ -+ return 0; -+ -+} -+ -+MTKSTP_DBG_T *stp_dbg_init(void *btm_half) -+{ -+ -+ MTKSTP_DBG_T *stp_dbg = NULL; -+ -+ STP_DBG_INFO_FUNC("stp-dbg init\n"); -+ -+ stp_dbg = kzalloc(sizeof(MTKSTP_DBG_T), GFP_KERNEL); -+ if (stp_dbg == NULL) -+ goto ERR_EXIT1; -+ if (IS_ERR(stp_dbg)) { -+ STP_DBG_ERR_FUNC("-ENOMEM\n"); -+ goto ERR_EXIT1; -+ } -+ -+ stp_dbg->logsys = vmalloc(sizeof(MTKSTP_LOG_SYS_T)); -+ if (stp_dbg->logsys == NULL) -+ goto ERR_EXIT2; -+ if (IS_ERR(stp_dbg->logsys)) { -+ STP_DBG_ERR_FUNC("-ENOMEM stp_gdb->logsys\n"); -+ goto ERR_EXIT2; -+ } -+ memset(stp_dbg->logsys, 0, sizeof(MTKSTP_LOG_SYS_T)); -+ spin_lock_init(&(stp_dbg->logsys->lock)); -+ stp_dbg->pkt_trace_no = 0; -+ stp_dbg->is_enable = 0; -+ g_stp_dbg = stp_dbg; -+ -+ if (btm_half != NULL) -+ stp_dbg->btm = btm_half; -+ else -+ stp_dbg->btm = NULL; -+ -+ -+ /* bind to netlink */ -+ stp_dbg_nl_init(); -+ g_core_dump = wcn_core_dump_init(STP_CORE_DUMP_INIT_SIZE, STP_CORE_DUMP_TIMEOUT); -+ g_stp_dbg_cpupcr = stp_dbg_cpupcr_init(); -+ g_stp_dbg_dmaregs = stp_dbg_dmaregs_init(); -+ -+ return stp_dbg; -+ -+ERR_EXIT2: -+ kfree(stp_dbg); -+ return NULL; -+ -+ERR_EXIT1: -+ kfree(stp_dbg); -+ return NULL; -+} -+ -+int stp_dbg_deinit(MTKSTP_DBG_T *stp_dbg) -+{ -+ -+ STP_DBG_INFO_FUNC("stp-dbg deinit\n"); -+ -+ wcn_core_dump_deinit(g_core_dump); -+ -+ stp_dbg_cpupcr_deinit(g_stp_dbg_cpupcr); -+ stp_dbg_dmaregs_deinit(g_stp_dbg_dmaregs); -+ /* unbind with netlink */ -+ stp_dbg_nl_deinit(); -+ -+ if (stp_dbg->logsys) -+ vfree(stp_dbg->logsys); -+ -+ kfree(stp_dbg); -+ -+ return 0; -+} -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/stp_exp.c b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/stp_exp.c -new file mode 100644 -index 000000000000..f7f4aff010d4 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/stp_exp.c -@@ -0,0 +1,279 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include /* udelay() */ -+ -+#include -+ -+ -+#include "osal_typedef.h" -+#include "stp_core.h" -+#include "stp_exp.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+static MTK_WCN_STP_IF_TX stp_uart_if_tx; -+static MTK_WCN_STP_IF_TX stp_sdio_if_tx; -+static MTK_WCN_STP_IF_TX stp_btif_if_tx; -+static ENUM_STP_TX_IF_TYPE g_stp_if_type = STP_MAX_IF_TX; -+static MTK_WCN_STP_IF_RX stp_if_rx; -+static MTK_WCN_STP_EVENT_CB event_callback_tbl[MTKSTP_MAX_TASK_NUM] = { 0x0 }; -+static MTK_WCN_STP_EVENT_CB tx_event_callback_tbl[MTKSTP_MAX_TASK_NUM] = { 0x0 }; -+ -+/****************************************************************************** -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************* -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+INT32 mtk_wcn_sys_if_rx(UINT8 *data, INT32 size) -+{ -+ if (stp_if_rx == 0x0) -+ return -1; -+ -+ (*stp_if_rx) (data, size); -+ return 0; -+} -+ -+static INT32 mtk_wcn_sys_if_tx(const PUINT8 data, const UINT32 size, PUINT32 written_size) -+{ -+ -+ if (STP_UART_IF_TX == g_stp_if_type) -+ return stp_uart_if_tx != NULL ? (*stp_uart_if_tx) (data, size, written_size) : -1; -+ else if (STP_SDIO_IF_TX == g_stp_if_type) -+ return stp_sdio_if_tx != NULL ? (*stp_sdio_if_tx) (data, size, written_size) : -1; -+ else if (STP_BTIF_IF_TX == g_stp_if_type) -+ return stp_btif_if_tx != NULL ? (*stp_btif_if_tx) (data, size, written_size) : -1; -+ /*if (g_stp_if_type >= STP_MAX_IF_TX) *//* George: remove ALWAYS TRUE condition */ -+ return -1; -+} -+ -+static INT32 mtk_wcn_sys_event_set(UINT8 function_type) -+{ -+ if ((function_type < MTKSTP_MAX_TASK_NUM) && (event_callback_tbl[function_type] != 0x0)) { -+ (*event_callback_tbl[function_type]) (); -+ } else { -+ /* FIXME: error handling */ -+ pr_err("[%s] STP set event fail. It seems the function is not active.\n", __func__); -+ } -+ -+ return 0; -+} -+ -+static INT32 mtk_wcn_sys_event_tx_resume(UINT8 winspace) -+{ -+ int type = 0; -+ -+ for (type = 0; type < MTKSTP_MAX_TASK_NUM; type++) { -+ if (tx_event_callback_tbl[type]) -+ tx_event_callback_tbl[type] (); -+ } -+ -+ return 0; -+} -+ -+static INT32 mtk_wcn_sys_check_function_status(UINT8 type, UINT8 op) -+{ -+ -+ /* op == FUNCTION_ACTIVE, to check if funciton[type] is active ? */ -+ if (!(type < MTKSTP_MAX_TASK_NUM)) -+ return STATUS_FUNCTION_INVALID; -+ -+ if (op == OP_FUNCTION_ACTIVE) { -+ if (event_callback_tbl[type] != 0x0) -+ return STATUS_FUNCTION_ACTIVE; -+ else -+ return STATUS_FUNCTION_INACTIVE; -+ -+ } -+ /* you can define more operation here ..., to queury function's status/information */ -+ -+ return STATUS_OP_INVALID; -+} -+ -+#if STP_EXP_HID_API_EXPORT -+INT32 _mtk_wcn_stp_register_if_rx(MTK_WCN_STP_IF_RX func) -+#else -+INT32 mtk_wcn_stp_register_if_rx(MTK_WCN_STP_IF_RX func) -+#endif -+{ -+ stp_if_rx = func; -+ -+ return 0; -+} -+#if !STP_EXP_HID_API_EXPORT -+EXPORT_SYMBOL(mtk_wcn_stp_register_if_rx); -+#endif -+ -+VOID mtk_wcn_stp_set_if_tx_type(ENUM_STP_TX_IF_TYPE stp_if_type) -+{ -+ static const char * const ifType[] = { -+ "UART", -+ "SDIO", -+ "BTIF", -+ "UNKNOWN" -+ }; -+ g_stp_if_type = stp_if_type; -+ pr_debug("[%s] set STP_IF_TX to %s.\n", __func__, ifType[stp_if_type]); -+} -+ -+#if STP_EXP_HID_API_EXPORT -+INT32 _mtk_wcn_stp_register_if_tx(ENUM_STP_TX_IF_TYPE stp_if, MTK_WCN_STP_IF_TX func) -+#else -+INT32 mtk_wcn_stp_register_if_tx(ENUM_STP_TX_IF_TYPE stp_if, MTK_WCN_STP_IF_TX func) -+#endif -+{ -+ if (STP_UART_IF_TX == stp_if) { -+ stp_uart_if_tx = func; -+ } else if (STP_SDIO_IF_TX == stp_if) { -+ stp_sdio_if_tx = func; -+ } else if (STP_BTIF_IF_TX == stp_if) { -+ stp_btif_if_tx = func; -+ } else { -+ pr_debug("[%s] STP_IF_TX(%d) out of boundary.\n", __func__, stp_if); -+ return -1; -+ } -+ -+ return 0; -+} -+#if !STP_EXP_HID_API_EXPORT -+EXPORT_SYMBOL(mtk_wcn_stp_register_if_tx); -+#endif -+ -+#if STP_EXP_HID_API_EXPORT -+INT32 _mtk_wcn_stp_register_event_cb(INT32 type, MTK_WCN_STP_EVENT_CB func) -+#else -+INT32 mtk_wcn_stp_register_event_cb(INT32 type, MTK_WCN_STP_EVENT_CB func) -+#endif -+{ -+ if (type < MTKSTP_MAX_TASK_NUM) { -+ event_callback_tbl[type] = func; -+ -+ /*clear rx queue */ -+ pr_debug("Flush type = %d Rx Queue\n", type); -+ mtk_wcn_stp_flush_rx_queue(type); -+ } -+ -+ return 0; -+} -+#if !STP_EXP_HID_API_EXPORT -+EXPORT_SYMBOL(mtk_wcn_stp_register_event_cb); -+#endif -+ -+#if STP_EXP_HID_API_EXPORT -+INT32 _mtk_wcn_stp_register_tx_event_cb(INT32 type, MTK_WCN_STP_EVENT_CB func) -+#else -+INT32 mtk_wcn_stp_register_tx_event_cb(INT32 type, MTK_WCN_STP_EVENT_CB func) -+#endif -+{ -+ if (type < MTKSTP_MAX_TASK_NUM) -+ tx_event_callback_tbl[type] = func; -+ else -+ BUG_ON(0); -+ -+ return 0; -+} -+#if !STP_EXP_HID_API_EXPORT -+EXPORT_SYMBOL(mtk_wcn_stp_register_tx_event_cb); -+#endif -+ -+INT32 stp_drv_init(VOID) -+{ -+ INT32 ret = 0; -+ -+ mtkstp_callback cb = { -+ .cb_if_tx = mtk_wcn_sys_if_tx, -+ .cb_event_set = mtk_wcn_sys_event_set, -+ .cb_event_tx_resume = mtk_wcn_sys_event_tx_resume, -+ .cb_check_funciton_status = mtk_wcn_sys_check_function_status -+ }; -+ -+#ifdef MTK_WCN_WMT_STP_EXP_SYMBOL_ABSTRACT -+ MTK_WCN_STP_EXP_CB_INFO stpExpCb = { -+ .stp_send_data_cb = _mtk_wcn_stp_send_data, -+ .stp_send_data_raw_cb = _mtk_wcn_stp_send_data_raw, -+ .stp_parser_data_cb = _mtk_wcn_stp_parser_data, -+ .stp_receive_data_cb = _mtk_wcn_stp_receive_data, -+ .stp_is_rxqueue_empty_cb = _mtk_wcn_stp_is_rxqueue_empty, -+ .stp_is_ready_cb = _mtk_wcn_stp_is_ready, -+ .stp_set_bluez_cb = _mtk_wcn_stp_set_bluez, -+ .stp_if_tx_cb = _mtk_wcn_stp_register_if_tx, -+ .stp_if_rx_cb = _mtk_wcn_stp_register_if_rx, -+ .stp_reg_event_cb = _mtk_wcn_stp_register_event_cb, -+ .stp_reg_tx_event_cb = _mtk_wcn_stp_register_tx_event_cb, -+ .stp_coredump_start_get_cb = _mtk_wcn_stp_coredump_start_get, -+ }; -+#endif -+ -+ ret = mtk_wcn_stp_init(&cb); -+#ifdef MTK_WCN_WMT_STP_EXP_SYMBOL_ABSTRACT -+ mtk_wcn_stp_exp_cb_reg(&stpExpCb); -+#endif -+ return ret; -+} -+ -+VOID stp_drv_exit(VOID) -+{ -+ mtk_wcn_stp_deinit(); -+ -+#ifdef MTK_WCN_WMT_STP_EXP_SYMBOL_ABSTRACT -+ mtk_wcn_stp_exp_cb_unreg(); -+#endif -+ -+} -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/wmt_dev.c b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/wmt_dev.c -new file mode 100644 -index 000000000000..f70c88796f09 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/wmt_dev.c -@@ -0,0 +1,2566 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -+ -+/*! \file -+ \brief brief description -+ -+ Detailed descriptions here. -+ -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+#ifdef DFT_TAG -+#undef DFT_TAG -+#endif -+#define DFT_TAG "[WMT-DEV]" -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+#include "osal_typedef.h" -+#include "osal.h" -+#include "wmt_dev.h" -+#include "wmt_core.h" -+#include "wmt_exp.h" -+#include "wmt_lib.h" -+#include "wmt_conf.h" -+#include "psm_core.h" -+#include "stp_core.h" -+#include "stp_exp.h" -+#include "bgw_desense.h" -+#include -+#include "wmt_idc.h" -+#ifdef CONFIG_COMPAT -+#include -+#endif -+#if WMT_CREATE_NODE_DYNAMIC -+#include -+#endif -+#define BUF_LEN_MAX 384 -+#include -+#ifdef CONFIG_COMPAT -+#define COMPAT_WMT_IOCTL_SET_PATCH_NAME _IOW(WMT_IOC_MAGIC, 4, compat_uptr_t) -+#define COMPAT_WMT_IOCTL_LPBK_TEST _IOWR(WMT_IOC_MAGIC, 8, compat_uptr_t) -+#define COMPAT_WMT_IOCTL_SET_PATCH_INFO _IOW(WMT_IOC_MAGIC, 15, compat_uptr_t) -+#define COMPAT_WMT_IOCTL_PORT_NAME _IOWR(WMT_IOC_MAGIC, 20, compat_uptr_t) -+#define COMPAT_WMT_IOCTL_WMT_CFG_NAME _IOWR(WMT_IOC_MAGIC, 21, compat_uptr_t) -+#define COMPAT_WMT_IOCTL_SEND_BGW_DS_CMD _IOW(WMT_IOC_MAGIC, 25, compat_uptr_t) -+#define COMPAT_WMT_IOCTL_ADIE_LPBK_TEST _IOWR(WMT_IOC_MAGIC, 26, compat_uptr_t) -+#endif -+ -+#define WMT_IOC_MAGIC 0xa0 -+#define WMT_IOCTL_SET_PATCH_NAME _IOW(WMT_IOC_MAGIC, 4, char*) -+#define WMT_IOCTL_SET_STP_MODE _IOW(WMT_IOC_MAGIC, 5, int) -+#define WMT_IOCTL_FUNC_ONOFF_CTRL _IOW(WMT_IOC_MAGIC, 6, int) -+#define WMT_IOCTL_LPBK_POWER_CTRL _IOW(WMT_IOC_MAGIC, 7, int) -+#define WMT_IOCTL_LPBK_TEST _IOWR(WMT_IOC_MAGIC, 8, char*) -+#define WMT_IOCTL_GET_CHIP_INFO _IOR(WMT_IOC_MAGIC, 12, int) -+#define WMT_IOCTL_SET_LAUNCHER_KILL _IOW(WMT_IOC_MAGIC, 13, int) -+#define WMT_IOCTL_SET_PATCH_NUM _IOW(WMT_IOC_MAGIC, 14, int) -+#define WMT_IOCTL_SET_PATCH_INFO _IOW(WMT_IOC_MAGIC, 15, char*) -+#define WMT_IOCTL_PORT_NAME _IOWR(WMT_IOC_MAGIC, 20, char*) -+#define WMT_IOCTL_WMT_CFG_NAME _IOWR(WMT_IOC_MAGIC, 21, char*) -+#define WMT_IOCTL_WMT_QUERY_CHIPID _IOR(WMT_IOC_MAGIC, 22, int) -+#define WMT_IOCTL_WMT_TELL_CHIPID _IOW(WMT_IOC_MAGIC, 23, int) -+#define WMT_IOCTL_WMT_COREDUMP_CTRL _IOW(WMT_IOC_MAGIC, 24, int) -+#define WMT_IOCTL_SEND_BGW_DS_CMD _IOW(WMT_IOC_MAGIC, 25, char*) -+#define WMT_IOCTL_ADIE_LPBK_TEST _IOWR(WMT_IOC_MAGIC, 26, char*) -+#define WMT_IOCTL_FW_DBGLOG_CTRL _IOR(WMT_IOC_MAGIC, 29, int) -+#define WMT_IOCTL_DYNAMIC_DUMP_CTRL _IOR(WMT_IOC_MAGIC, 30, char*) -+ -+#define MTK_WMT_VERSION "SOC Consys WMT Driver - v1.0" -+#define MTK_WMT_DATE "2013/01/20" -+#define WMT_DEV_MAJOR 190 /* never used number */ -+#define WMT_DEV_NUM 1 -+#define WMT_DEV_INIT_TO_MS (2 * 1000) -+#define DYNAMIC_DUMP_BUF 109 -+ -+#if CFG_WMT_DBG_SUPPORT -+#define WMT_DBG_PROCNAME "driver/wmt_dbg" -+#endif -+ -+#define WMT_DRIVER_NAME "mtk_stp_wmt" -+ -+P_OSAL_EVENT gpRxEvent = NULL; -+ -+UINT32 u4RxFlag = 0x0; -+static atomic_t gRxCount = ATOMIC_INIT(0); -+ -+/* Linux UINT8 device */ -+static int gWmtMajor = WMT_DEV_MAJOR; -+static struct cdev gWmtCdev; -+static atomic_t gWmtRefCnt = ATOMIC_INIT(0); -+/* WMT driver information */ -+static UINT8 gLpbkBuf[1024+5] = { 0 }; -+ -+static UINT32 gLpbkBufLog; /* George LPBK debug */ -+static INT32 gWmtInitDone; -+static wait_queue_head_t gWmtInitWq; -+ -+P_WMT_PATCH_INFO pPatchInfo = NULL; -+UINT32 pAtchNum = 0; -+ -+#if (defined(CONFIG_MTK_GMO_RAM_OPTIMIZE) && !defined(CONFIG_MT_ENG_BUILD)) -+#define WMT_EMI_DEBUG_BUF_SIZE (8*1024) -+#else -+#define WMT_EMI_DEBUG_BUF_SIZE (32*1024) -+#endif -+ -+static UINT8 gEmiBuf[WMT_EMI_DEBUG_BUF_SIZE]; -+UINT8 *buf_emi; -+ -+#if CFG_WMT_PROC_FOR_AEE -+static struct proc_dir_entry *gWmtAeeEntry; -+#define WMT_AEE_PROCNAME "driver/wmt_aee" -+#define WMT_PROC_AEE_SIZE 3072 -+static UINT32 g_buf_len; -+static UINT8 *pBuf; -+#endif -+ -+#if WMT_CREATE_NODE_DYNAMIC -+struct class *wmt_class = NULL; -+struct device *wmt_dev = NULL; -+#endif -+ -+#if CFG_WMT_DBG_SUPPORT -+static struct proc_dir_entry *gWmtDbgEntry; -+COEX_BUF gCoexBuf; -+ -+static INT32 wmt_dbg_psm_ctrl(INT32 par1, INT32 par2, INT32 par3); -+static INT32 wmt_dbg_quick_sleep_ctrl(INT32 par1, INT32 par2, INT32 par3); -+static INT32 wmt_dbg_dsns_ctrl(INT32 par1, INT32 par2, INT32 par3); -+static INT32 wmt_dbg_hwver_get(INT32 par1, INT32 par2, INT32 par3); -+static INT32 wmt_dbg_inband_rst(INT32 par1, INT32 par2, INT32 par3); -+static INT32 wmt_dbg_chip_rst(INT32 par1, INT32 par2, INT32 par3); -+static INT32 wmt_dbg_func_ctrl(INT32 par1, INT32 par2, INT32 par3); -+static INT32 wmt_dbg_raed_chipid(INT32 par1, INT32 par2, INT32 par3); -+static INT32 wmt_dbg_wmt_dbg_level(INT32 par1, INT32 par2, INT32 par3); -+static INT32 wmt_dbg_stp_dbg_level(INT32 par1, INT32 par2, INT32 par3); -+static INT32 wmt_dbg_reg_read(INT32 par1, INT32 par2, INT32 par3); -+static INT32 wmt_dbg_reg_write(INT32 par1, INT32 par2, INT32 par3); -+static INT32 wmt_dbg_coex_test(INT32 par1, INT32 par2, INT32 par3); -+static INT32 wmt_dbg_assert_test(INT32 par1, INT32 par2, INT32 par3); -+static INT32 wmt_dbg_cmd_test_api(ENUM_WMTDRV_CMD_T cmd); -+static INT32 wmt_dbg_rst_ctrl(INT32 par1, INT32 par2, INT32 par3); -+static INT32 wmt_dbg_ut_test(INT32 par1, INT32 par2, INT32 par3); -+static INT32 wmt_dbg_efuse_read(INT32 par1, INT32 par2, INT32 par3); -+static INT32 wmt_dbg_efuse_write(INT32 par1, INT32 par2, INT32 par3); -+static INT32 wmt_dbg_sdio_ctrl(INT32 par1, INT32 par2, INT32 par3); -+static INT32 wmt_dbg_stp_dbg_ctrl(INT32 par1, INT32 par2, INT32 par3); -+static INT32 wmt_dbg_stp_dbg_log_ctrl(INT32 par1, INT32 par2, INT32 par3); -+static INT32 wmt_dbg_wmt_assert_ctrl(INT32 par1, INT32 par2, INT32 par3); -+ -+#if CFG_CORE_INTERNAL_TXRX -+static INT32 wmt_dbg_internal_lpbk_test(INT32 par1, INT32 par2, INT32 par3); -+#endif -+static INT32 wmt_dbg_fwinfor_from_emi(INT32 par1, INT32 par2, INT32 par3); -+static INT32 wmt_dbg_set_mcu_clock(INT32 par1, INT32 par2, INT32 par3); -+static INT32 wmt_dbg_poll_cpupcr(INT32 par1, INT32 par2, INT32 par3); -+#if CONSYS_ENALBE_SET_JTAG -+static INT32 wmt_dbg_jtag_flag_ctrl(INT32 par1, INT32 par2, INT32 par3); -+#endif -+#if CFG_WMT_LTE_COEX_HANDLING -+static INT32 wmt_dbg_lte_coex_test(INT32 par1, INT32 par2, INT32 par3); -+#endif -+#endif -+static void wmt_dbg_fwinfor_print_buff(UINT32 len) -+{ -+ UINT32 i = 0; -+ UINT32 idx = 0; -+ -+ for (i = 0; i < len; i++) { -+ buf_emi[idx] = gEmiBuf[i]; -+ if (gEmiBuf[i] == '\n') { -+ pr_cont("%s", buf_emi); -+ osal_memset(buf_emi, 0, BUF_LEN_MAX); -+ idx = 0; -+ } else { -+ idx++; -+ } -+ if (idx == BUF_LEN_MAX-1) { -+ buf_emi[idx] = '\0'; -+ pr_cont("%s", buf_emi); -+ osal_memset(buf_emi, 0, BUF_LEN_MAX); -+ idx = 0; -+ } -+ } -+} -+ -+/*LCM on/off ctrl for wmt varabile*/ -+static struct work_struct gPwrOnOffWork; -+UINT32 g_es_lr_flag_for_quick_sleep = 1; /* for ctrl quick sleep flag */ -+UINT32 g_es_lr_flag_for_lpbk_onoff = 0; /* for ctrl lpbk on off */ -+OSAL_SLEEPABLE_LOCK g_es_lr_lock; -+ -+#ifdef CONFIG_EARLYSUSPEND -+ -+static void wmt_dev_early_suspend(struct early_suspend *h) -+{ -+ osal_lock_sleepable_lock(&g_es_lr_lock); -+ g_es_lr_flag_for_quick_sleep = 1; -+ g_es_lr_flag_for_lpbk_onoff = 0; -+ osal_unlock_sleepable_lock(&g_es_lr_lock); -+ -+ WMT_WARN_FUNC("@@@@@@@@@@wmt enter early suspend@@@@@@@@@@@@@@\n"); -+ -+ schedule_work(&gPwrOnOffWork); -+} -+ -+static void wmt_dev_late_resume(struct early_suspend *h) -+{ -+ osal_lock_sleepable_lock(&g_es_lr_lock); -+ g_es_lr_flag_for_quick_sleep = 0; -+ g_es_lr_flag_for_lpbk_onoff = 1; -+ osal_unlock_sleepable_lock(&g_es_lr_lock); -+ -+ WMT_WARN_FUNC("@@@@@@@@@@wmt enter late resume@@@@@@@@@@@@@@\n"); -+ -+ schedule_work(&gPwrOnOffWork); -+ -+} -+ -+struct early_suspend wmt_early_suspend_handler = { -+ .suspend = wmt_dev_early_suspend, -+ .resume = wmt_dev_late_resume, -+}; -+ -+#else -+ -+static struct notifier_block wmt_fb_notifier; -+static int wmt_fb_notifier_callback(struct notifier_block *self, unsigned long event, void *data) -+{ -+ struct fb_event *evdata = data; -+ INT32 blank; -+ -+ WMT_DBG_FUNC("wmt_fb_notifier_callback\n"); -+ -+ /* If we aren't interested in this event, skip it immediately ... */ -+ if (event != FB_EVENT_BLANK) -+ return 0; -+ -+ blank = *(INT32 *)evdata->data; -+ WMT_DBG_FUNC("fb_notify(blank=%d)\n", blank); -+ -+ switch (blank) { -+ case FB_BLANK_UNBLANK: -+ osal_lock_sleepable_lock(&g_es_lr_lock); -+ g_es_lr_flag_for_quick_sleep = 0; -+ g_es_lr_flag_for_lpbk_onoff = 1; -+ osal_unlock_sleepable_lock(&g_es_lr_lock); -+ WMT_WARN_FUNC("@@@@@@@@@@wmt enter UNBLANK @@@@@@@@@@@@@@\n"); -+ schedule_work(&gPwrOnOffWork); -+ break; -+ case FB_BLANK_POWERDOWN: -+ osal_lock_sleepable_lock(&g_es_lr_lock); -+ g_es_lr_flag_for_quick_sleep = 1; -+ g_es_lr_flag_for_lpbk_onoff = 0; -+ osal_unlock_sleepable_lock(&g_es_lr_lock); -+ WMT_WARN_FUNC("@@@@@@@@@@wmt enter early POWERDOWN @@@@@@@@@@@@@@\n"); -+ schedule_work(&gPwrOnOffWork); -+ break; -+ default: -+ break; -+ } -+ return 0; -+} -+#endif -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+static void wmt_pwr_on_off_handler(struct work_struct *work) -+{ -+ INT32 retryCounter = 1; -+ -+ WMT_DBG_FUNC("wmt_pwr_on_off_handler start to run\n"); -+ -+ osal_lock_sleepable_lock(&g_es_lr_lock); -+ -+ if (g_es_lr_flag_for_lpbk_onoff) { -+ do { -+ if (MTK_WCN_BOOL_FALSE == mtk_wcn_wmt_func_on(WMTDRV_TYPE_LPBK)) { -+ WMT_WARN_FUNC("WMT turn on LPBK fail, retrying, retryCounter left:%d!\n", retryCounter); -+ retryCounter--; -+ osal_sleep_ms(1000); -+ } else { -+ WMT_INFO_FUNC("WMT turn on LPBK suceed\n"); -+ break; -+ } -+ } while (retryCounter > 0); -+ } else { -+ if (MTK_WCN_BOOL_FALSE == mtk_wcn_wmt_func_off(WMTDRV_TYPE_LPBK)) -+ WMT_WARN_FUNC("WMT turn off LPBK fail\n"); -+ else -+ WMT_DBG_FUNC("WMT turn off LPBK suceed\n"); -+ -+ } -+ -+ osal_unlock_sleepable_lock(&g_es_lr_lock); -+ -+} -+ -+ -+MTK_WCN_BOOL wmt_dev_get_early_suspend_state(void) -+{ -+ MTK_WCN_BOOL bRet = (0 == g_es_lr_flag_for_quick_sleep) ? MTK_WCN_BOOL_FALSE : MTK_WCN_BOOL_TRUE; -+ /* WMT_INFO_FUNC("bRet:%d\n", bRet); */ -+ return bRet; -+} -+ -+#if CFG_WMT_DBG_SUPPORT -+ -+static const WMT_DEV_DBG_FUNC wmt_dev_dbg_func[] = { -+ [0] = wmt_dbg_psm_ctrl, -+ [1] = wmt_dbg_quick_sleep_ctrl, -+ [2] = wmt_dbg_dsns_ctrl, -+ [3] = wmt_dbg_hwver_get, -+ [4] = wmt_dbg_assert_test, -+ [5] = wmt_dbg_inband_rst, -+ [6] = wmt_dbg_chip_rst, -+ [7] = wmt_dbg_func_ctrl, -+ [8] = wmt_dbg_raed_chipid, -+ [9] = wmt_dbg_wmt_dbg_level, -+ [0xa] = wmt_dbg_stp_dbg_level, -+ [0xb] = wmt_dbg_reg_read, -+ [0xc] = wmt_dbg_reg_write, -+ [0xd] = wmt_dbg_coex_test, -+ [0xe] = wmt_dbg_rst_ctrl, -+ [0xf] = wmt_dbg_ut_test, -+ [0x10] = wmt_dbg_efuse_read, -+ [0x11] = wmt_dbg_efuse_write, -+ [0x12] = wmt_dbg_sdio_ctrl, -+ [0x13] = wmt_dbg_stp_dbg_ctrl, -+ [0x14] = wmt_dbg_stp_dbg_log_ctrl, -+ [0x15] = wmt_dbg_wmt_assert_ctrl, -+ [0x16] = wmt_dbg_fwinfor_from_emi, -+ [0x17] = wmt_dbg_set_mcu_clock, -+ [0x18] = wmt_dbg_poll_cpupcr, -+ [0x19] = wmt_dbg_jtag_flag_ctrl, -+#if CFG_WMT_LTE_COEX_HANDLING -+ [0x20] = wmt_dbg_lte_coex_test, -+#endif -+}; -+ -+INT32 wmt_dbg_psm_ctrl(INT32 par1, INT32 par2, INT32 par3) -+{ -+#if CFG_WMT_PS_SUPPORT -+ if (0 == par2) { -+ wmt_lib_ps_ctrl(0); -+ WMT_INFO_FUNC("disable PSM\n"); -+ } else { -+ par2 = (1 > par2 || 20000 < par2) ? STP_PSM_IDLE_TIME_SLEEP : par2; -+ wmt_lib_ps_set_idle_time(par2); -+ wmt_lib_ps_ctrl(1); -+ WMT_WARN_FUNC("enable PSM, idle to sleep time = %d ms\n", par2); -+ } -+#else -+ WMT_INFO_FUNC("WMT PS not supported\n"); -+#endif -+ return 0; -+} -+ -+INT32 wmt_dbg_quick_sleep_ctrl(INT32 par1, INT32 par2, INT32 par3) -+{ -+#if CFG_WMT_PS_SUPPORT -+ UINT32 en_flag = par2; -+ -+ wmt_lib_quick_sleep_ctrl(en_flag); -+#else -+ WMT_WARN_FUNC("WMT PS not supported\n"); -+#endif -+ return 0; -+} -+ -+INT32 wmt_dbg_dsns_ctrl(INT32 par1, INT32 par2, INT32 par3) -+{ -+ if (WMTDSNS_FM_DISABLE <= par2 && WMTDSNS_MAX > par2) { -+ WMT_INFO_FUNC("DSNS type (%d)\n", par2); -+ mtk_wcn_wmt_dsns_ctrl(par2); -+ } else { -+ WMT_WARN_FUNC("invalid DSNS type\n"); -+ } -+ return 0; -+} -+ -+INT32 wmt_dbg_hwver_get(INT32 par1, INT32 par2, INT32 par3) -+{ -+ WMT_INFO_FUNC("query chip version\n"); -+ mtk_wcn_wmt_hwver_get(); -+ return 0; -+} -+ -+INT32 wmt_dbg_assert_test(INT32 par1, INT32 par2, INT32 par3) -+{ -+ if (0 == par3) { -+ /* par2 = 0: send assert command */ -+ /* par2 != 0: send exception command */ -+ return wmt_dbg_cmd_test_api(0 == par2 ? 0 : 1); -+ } else if (1 == par3) { -+ /* send noack command */ -+ return wmt_dbg_cmd_test_api(18); -+ } else if (2 == par3) { -+ /* warn reset test */ -+ return wmt_dbg_cmd_test_api(19); -+ } else if (3 == par3) { -+ /* firmware trace test */ -+ return wmt_dbg_cmd_test_api(20); -+ } -+ { -+ INT32 sec = 8; -+ INT32 times = 0; -+ -+ times = par3; -+ do { -+ WMT_INFO_FUNC("Send Assert Command per 8 secs!!\n"); -+ wmt_dbg_cmd_test_api(0); -+ osal_sleep_ms(sec * 1000); -+ } while (--times); -+ } -+ return 0; -+} -+ -+INT32 wmt_dbg_cmd_test_api(ENUM_WMTDRV_CMD_T cmd) -+{ -+ -+ P_OSAL_OP pOp = NULL; -+ MTK_WCN_BOOL bRet = MTK_WCN_BOOL_FALSE; -+ P_OSAL_SIGNAL pSignal; -+ -+ pOp = wmt_lib_get_free_op(); -+ if (!pOp) { -+ WMT_WARN_FUNC("get_free_lxop fail\n"); -+ return MTK_WCN_BOOL_FALSE; -+ } -+ -+ pSignal = &pOp->signal; -+ -+ pOp->op.opId = WMT_OPID_CMD_TEST; -+ -+ pSignal->timeoutValue = MAX_EACH_WMT_CMD; -+ /*this test command should be run with usb cable connected, so no host awake is needed */ -+ /* wmt_lib_host_awake_get(); */ -+ switch (cmd) { -+ case WMTDRV_CMD_ASSERT: -+ pOp->op.au4OpData[0] = 0; -+ break; -+ case WMTDRV_CMD_EXCEPTION: -+ pOp->op.au4OpData[0] = 1; -+ break; -+ case WMTDRV_CMD_NOACK_TEST: -+ pOp->op.au4OpData[0] = 3; -+ break; -+ case WMTDRV_CMD_WARNRST_TEST: -+ pOp->op.au4OpData[0] = 4; -+ break; -+ case WMTDRV_CMD_FWTRACE_TEST: -+ pOp->op.au4OpData[0] = 5; -+ break; -+ default: -+ if (WMTDRV_CMD_COEXDBG_00 <= cmd && WMTDRV_CMD_COEXDBG_15 >= cmd) { -+ pOp->op.au4OpData[0] = 2; -+ pOp->op.au4OpData[1] = cmd - 2; -+ } else { -+ pOp->op.au4OpData[0] = 0xff; -+ pOp->op.au4OpData[1] = 0xff; -+ } -+ pOp->op.au4OpData[2] = (SIZE_T) gCoexBuf.buffer; -+ pOp->op.au4OpData[3] = osal_sizeof(gCoexBuf.buffer); -+ break; -+ } -+ WMT_INFO_FUNC("CMD_TEST, opid(%d), par(%d, %d)\n", pOp->op.opId, pOp->op.au4OpData[0], pOp->op.au4OpData[1]); -+ /*wake up chip first */ -+ if (DISABLE_PSM_MONITOR()) { -+ WMT_ERR_FUNC("wake up failed\n"); -+ wmt_lib_put_op_to_free_queue(pOp); -+ return -1; -+ } -+ bRet = wmt_lib_put_act_op(pOp); -+ ENABLE_PSM_MONITOR(); -+ if ((cmd != WMTDRV_CMD_ASSERT) && -+ (cmd != WMTDRV_CMD_EXCEPTION) && -+ (cmd != WMTDRV_CMD_NOACK_TEST) && (cmd != WMTDRV_CMD_WARNRST_TEST) && (cmd != WMTDRV_CMD_FWTRACE_TEST)) { -+ if (MTK_WCN_BOOL_FALSE == bRet) { -+ gCoexBuf.availSize = 0; -+ } else { -+ gCoexBuf.availSize = pOp->op.au4OpData[3]; -+ WMT_INFO_FUNC("gCoexBuf.availSize = %d\n", gCoexBuf.availSize); -+ } -+ } -+ /* wmt_lib_host_awake_put(); */ -+ WMT_INFO_FUNC("CMD_TEST, opid (%d), par(%d, %d), ret(%d), result(%s)\n", -+ pOp->op.opId, -+ pOp->op.au4OpData[0], -+ pOp->op.au4OpData[1], bRet, MTK_WCN_BOOL_FALSE == bRet ? "failed" : "succeed"); -+ -+ return 0; -+} -+ -+INT32 wmt_dbg_inband_rst(INT32 par1, INT32 par2, INT32 par3) -+{ -+ if (0 == par2) { -+ WMT_INFO_FUNC("inband reset test!!\n"); -+ mtk_wcn_stp_inband_reset(); -+ } else { -+ WMT_INFO_FUNC("STP context reset in host side!!\n"); -+ mtk_wcn_stp_flush_context(); -+ } -+ -+ return 0; -+} -+ -+INT32 wmt_dbg_chip_rst(INT32 par1, INT32 par2, INT32 par3) -+{ -+ if (0 == par2) { -+ if (mtk_wcn_stp_is_ready()) { -+ WMT_INFO_FUNC("whole chip reset test\n"); -+ wmt_lib_cmb_rst(WMTRSTSRC_RESET_TEST); -+ } else { -+ WMT_INFO_FUNC("STP not ready , not to launch whole chip reset test\n"); -+ } -+ } else if (1 == par2) { -+ WMT_INFO_FUNC("chip hardware reset test\n"); -+ wmt_lib_hw_rst(); -+ } else { -+ WMT_INFO_FUNC("chip software reset test\n"); -+ wmt_lib_sw_rst(1); -+ } -+ return 0; -+} -+ -+INT32 wmt_dbg_func_ctrl(INT32 par1, INT32 par2, INT32 par3) -+{ -+ if (WMTDRV_TYPE_WMT > par2 || WMTDRV_TYPE_LPBK == par2) { -+ if (0 == par3) { -+ WMT_INFO_FUNC("function off test, type(%d)\n", par2); -+ mtk_wcn_wmt_func_off(par2); -+ } else { -+ WMT_INFO_FUNC("function on test, type(%d)\n", par2); -+ mtk_wcn_wmt_func_on(par2); -+ } -+ } else { -+ WMT_INFO_FUNC("function ctrl test, invalid type(%d)\n", par2); -+ } -+ return 0; -+} -+ -+INT32 wmt_dbg_raed_chipid(INT32 par1, INT32 par2, INT32 par3) -+{ -+ WMT_INFO_FUNC("chip version = %d\n", wmt_lib_get_icinfo(WMTCHIN_MAPPINGHWVER)); -+ return 0; -+} -+ -+INT32 wmt_dbg_wmt_dbg_level(INT32 par1, INT32 par2, INT32 par3) -+{ -+ par2 = (WMT_LOG_ERR <= par2 && WMT_LOG_LOUD >= par2) ? par2 : WMT_LOG_INFO; -+ wmt_lib_dbg_level_set(par2); -+ WMT_INFO_FUNC("set wmt log level to %d\n", par2); -+ return 0; -+} -+ -+INT32 wmt_dbg_stp_dbg_level(INT32 par1, INT32 par2, INT32 par3) -+{ -+ par2 = (0 <= par2 && 4 >= par2) ? par2 : 2; -+ mtk_wcn_stp_dbg_level(par2); -+ WMT_INFO_FUNC("set stp log level to %d\n", par2); -+ return 0; -+ -+} -+ -+INT32 wmt_dbg_reg_read(INT32 par1, INT32 par2, INT32 par3) -+{ -+ /* par2-->register address */ -+ /* par3-->register mask */ -+ UINT32 value = 0x0; -+ UINT32 iRet = -1; -+#if 0 -+ DISABLE_PSM_MONITOR(); -+ iRet = wmt_core_reg_rw_raw(0, par2, &value, par3); -+ ENABLE_PSM_MONITOR(); -+#endif -+ iRet = wmt_lib_reg_rw(0, par2, &value, par3); -+ WMT_INFO_FUNC("read combo chip register (0x%08x) with mask (0x%08x) %s, value = 0x%08x\n", -+ par2, par3, iRet != 0 ? "failed" : "succeed", iRet != 0 ? -1 : value); -+ return 0; -+} -+ -+INT32 wmt_dbg_reg_write(INT32 par1, INT32 par2, INT32 par3) -+{ -+ /* par2-->register address */ -+ /* par3-->value to set */ -+ UINT32 iRet = -1; -+#if 0 -+ DISABLE_PSM_MONITOR(); -+ iRet = wmt_core_reg_rw_raw(1, par2, &par3, 0xffffffff); -+ ENABLE_PSM_MONITOR(); -+#endif -+ iRet = wmt_lib_reg_rw(1, par2, &par3, 0xffffffff); -+ WMT_INFO_FUNC("write combo chip register (0x%08x) with value (0x%08x) %s\n", -+ par2, par3, iRet != 0 ? "failed" : "succeed"); -+ return 0; -+} -+ -+INT32 wmt_dbg_efuse_read(INT32 par1, INT32 par2, INT32 par3) -+{ -+ /* par2-->efuse address */ -+ /* par3-->register mask */ -+ UINT32 value = 0x0; -+ UINT32 iRet = -1; -+ -+ iRet = wmt_lib_efuse_rw(0, par2, &value, par3); -+ WMT_INFO_FUNC("read combo chip efuse (0x%08x) with mask (0x%08x) %s, value = 0x%08x\n", -+ par2, par3, iRet != 0 ? "failed" : "succeed", iRet != 0 ? -1 : value); -+ return 0; -+} -+ -+INT32 wmt_dbg_efuse_write(INT32 par1, INT32 par2, INT32 par3) -+{ -+ /* par2-->efuse address */ -+ /* par3-->value to set */ -+ UINT32 iRet = -1; -+ -+ iRet = wmt_lib_efuse_rw(1, par2, &par3, 0xffffffff); -+ WMT_INFO_FUNC("write combo chip efuse (0x%08x) with value (0x%08x) %s\n", -+ par2, par3, iRet != 0 ? "failed" : "succeed"); -+ return 0; -+} -+ -+INT32 wmt_dbg_sdio_ctrl(INT32 par1, INT32 par2, INT32 par3) -+{ -+/*remove sdio card detect/remove control because of btif is used*/ -+#if 0 -+ INT32 iRet = -1; -+ -+ iRet = wmt_lib_sdio_ctrl(0 != par2 ? 1 : 0); -+ WMT_INFO_FUNC("ctrl SDIO function %s\n", 0 == iRet ? "succeed" : "failed"); -+#endif -+ return 0; -+} -+ -+INT32 wmt_dbg_stp_dbg_ctrl(INT32 par1, INT32 par2, INT32 par3) -+{ -+ if (1 < par2) { -+ mtk_wcn_stp_dbg_dump_package(); -+ return 0; -+ } -+ WMT_INFO_FUNC("%s stp debug function\n", 0 == par2 ? "disable" : "enable"); -+ if (0 == par2) -+ mtk_wcn_stp_dbg_disable(); -+ else if (1 == par2) -+ mtk_wcn_stp_dbg_enable(); -+ -+ return 0; -+} -+ -+INT32 wmt_dbg_stp_dbg_log_ctrl(INT32 par1, INT32 par2, INT32 par3) -+{ -+ mtk_wcn_stp_dbg_log_ctrl(0 != par2 ? 1 : 0); -+ return 0; -+} -+ -+INT32 wmt_dbg_wmt_assert_ctrl(INT32 par1, INT32 par2, INT32 par3) -+{ -+ mtk_wcn_stp_coredump_flag_ctrl(0 != par2 ? 1 : 0); -+ return 0; -+} -+ -+INT32 wmt_dbg_fwinfor_from_emi(INT32 par1, INT32 par2, INT32 par3) -+{ -+ UINT32 offset = 0; -+ UINT32 len = 0; -+ UINT32 *pAddr = NULL; -+ UINT32 cur_idx_pagedtrace; -+ static UINT32 prev_idx_pagedtrace; -+ MTK_WCN_BOOL isBreak = MTK_WCN_BOOL_TRUE; -+ -+ offset = par2; -+ len = par3; -+ -+ buf_emi = kmalloc(sizeof(UINT8) * BUF_LEN_MAX, GFP_KERNEL); -+ if (!buf_emi) { -+ WMT_ERR_FUNC("buf kmalloc memory fail\n"); -+ return 0; -+ } -+ osal_memset(buf_emi, 0, BUF_LEN_MAX); -+ osal_memset(&gEmiBuf[0], 0, WMT_EMI_DEBUG_BUF_SIZE); -+ wmt_lib_get_fwinfor_from_emi(0, offset, &gEmiBuf[0], 0x100); -+ -+ if (offset == 1) { -+ do { -+ pAddr = (PUINT32) wmt_plat_get_emi_virt_add(0x24); -+ cur_idx_pagedtrace = *pAddr; -+ -+ if (cur_idx_pagedtrace > prev_idx_pagedtrace) { -+ len = cur_idx_pagedtrace - prev_idx_pagedtrace; -+ wmt_lib_get_fwinfor_from_emi(1, prev_idx_pagedtrace, &gEmiBuf[0], len); -+ wmt_dbg_fwinfor_print_buff(len); -+ prev_idx_pagedtrace = cur_idx_pagedtrace; -+ } -+ -+ if (cur_idx_pagedtrace < prev_idx_pagedtrace) { -+ if (prev_idx_pagedtrace >= 0x8000) { -+ pr_debug("++ prev_idx_pagedtrace invalid ...++\n\\n"); -+ prev_idx_pagedtrace = 0x8000 - 1; -+ continue; -+ } -+ -+ len = 0x8000 - prev_idx_pagedtrace - 1; -+ wmt_lib_get_fwinfor_from_emi(1, prev_idx_pagedtrace, &gEmiBuf[0], len); -+ pr_debug("\n\n -- CONNSYS paged trace ascii output (cont...) --\n\n"); -+ wmt_dbg_fwinfor_print_buff(len); -+ -+ len = cur_idx_pagedtrace; -+ wmt_lib_get_fwinfor_from_emi(1, 0x0, &gEmiBuf[0], len); -+ pr_debug("\n\n -- CONNSYS paged trace ascii output (end) --\n\n"); -+ wmt_dbg_fwinfor_print_buff(len); -+ prev_idx_pagedtrace = cur_idx_pagedtrace; -+ } -+ msleep(100); -+ } while (isBreak); -+ } -+ -+ pr_debug("\n\n -- control word --\n\n"); -+ wmt_dbg_fwinfor_print_buff(256); -+ if (len > 1024 * 4) -+ len = 1024 * 4; -+ -+ WMT_WARN_FUNC("get fw infor from emi at offset(0x%x),len(0x%x)\n", offset, len); -+ osal_memset(&gEmiBuf[0], 0, WMT_EMI_DEBUG_BUF_SIZE); -+ wmt_lib_get_fwinfor_from_emi(1, offset, &gEmiBuf[0], len); -+ -+ pr_debug("\n\n -- paged trace hex output --\n\n"); -+ wmt_dbg_fwinfor_print_buff(len); -+ pr_debug("\n\n -- paged trace ascii output --\n\n"); -+ wmt_dbg_fwinfor_print_buff(len); -+ kfree(buf_emi); -+ return 0; -+} -+ -+INT32 wmt_dbg_coex_test(INT32 par1, INT32 par2, INT32 par3) -+{ -+ WMT_INFO_FUNC("coexistance test cmd!!\n"); -+ return wmt_dbg_cmd_test_api(par2 + WMTDRV_CMD_COEXDBG_00); -+} -+ -+INT32 wmt_dbg_rst_ctrl(INT32 par1, INT32 par2, INT32 par3) -+{ -+ WMT_INFO_FUNC("%s audo rst\n", 0 == par2 ? "disable" : "enable"); -+ mtk_wcn_stp_set_auto_rst(0 == par2 ? 0 : 1); -+ return 0; -+} -+ -+INT32 wmt_dbg_ut_test(INT32 par1, INT32 par2, INT32 par3) -+{ -+ -+ INT32 i = 0; -+ INT32 j = 0; -+ INT32 iRet = 0; -+ -+ i = 20; -+ while ((i--) > 0) { -+ WMT_INFO_FUNC("#### UT WMT and STP Function On/Off .... %d\n", i); -+ j = 10; -+ while ((j--) > 0) { -+ WMT_INFO_FUNC("#### BT On .... (%d, %d)\n", i, j); -+ iRet = mtk_wcn_wmt_func_on(WMTDRV_TYPE_BT); -+ if (iRet == MTK_WCN_BOOL_FALSE) -+ break; -+ -+ WMT_INFO_FUNC("#### GPS On .... (%d, %d)\n", i, j); -+ iRet = mtk_wcn_wmt_func_on(WMTDRV_TYPE_GPS); -+ if (iRet == MTK_WCN_BOOL_FALSE) -+ break; -+ -+ WMT_INFO_FUNC("#### FM On .... (%d, %d)\n", i, j); -+ iRet = mtk_wcn_wmt_func_on(WMTDRV_TYPE_FM); -+ if (iRet == MTK_WCN_BOOL_FALSE) -+ break; -+ -+ WMT_INFO_FUNC("#### WIFI On .... (%d, %d)\n", i, j); -+ iRet = mtk_wcn_wmt_func_on(WMTDRV_TYPE_WIFI); -+ if (iRet == MTK_WCN_BOOL_FALSE) -+ break; -+ -+ WMT_INFO_FUNC("#### BT Off .... (%d, %d)\n", i, j); -+ iRet = mtk_wcn_wmt_func_off(WMTDRV_TYPE_BT); -+ if (iRet == MTK_WCN_BOOL_FALSE) -+ break; -+ -+ WMT_INFO_FUNC("#### GPS Off ....(%d, %d)\n", i, j); -+ iRet = mtk_wcn_wmt_func_off(WMTDRV_TYPE_GPS); -+ if (iRet == MTK_WCN_BOOL_FALSE) -+ break; -+ -+ WMT_INFO_FUNC("#### FM Off .... (%d, %d)\n", i, j); -+ iRet = mtk_wcn_wmt_func_off(WMTDRV_TYPE_FM); -+ if (iRet == MTK_WCN_BOOL_FALSE) -+ break; -+ -+ WMT_INFO_FUNC("#### WIFI Off ....(%d, %d)\n", i, j); -+ iRet = mtk_wcn_wmt_func_off(WMTDRV_TYPE_WIFI); -+ if (iRet == MTK_WCN_BOOL_FALSE) -+ break; -+ -+ } -+ if (iRet == MTK_WCN_BOOL_FALSE) -+ break; -+ -+ } -+ if (iRet == MTK_WCN_BOOL_FALSE) -+ WMT_INFO_FUNC("#### UT FAIL!!\n"); -+ else -+ WMT_INFO_FUNC("#### UT PASS!!\n"); -+ -+ return iRet; -+} -+ -+#if CFG_CORE_INTERNAL_TXRX -+ -+struct lpbk_package { -+ long payload_length; -+ unsigned char out_payload[2048]; -+ unsigned char in_payload[2048]; -+}; -+ -+static INT32 wmt_internal_loopback(INT32 count, INT32 max) -+{ -+ int ret = 0; -+ int loop; -+ int offset; -+ struct lpbk_package lpbk_buffer; -+ P_OSAL_OP pOp; -+ P_OSAL_SIGNAL pSignal = NULL; -+ -+ for (loop = 0; loop < count; loop++) { -+ /* <1> init buffer */ -+ osal_memset((void *)&lpbk_buffer, 0, sizeof(struct lpbk_package)); -+ lpbk_buffer.payload_length = max; -+ for (offset = 0; offset < max; offset++) -+ lpbk_buffer.out_payload[offset] = (offset + 1) /*for test use: begin from 1 */ & 0xFF; -+ -+ -+ memcpy(&gLpbkBuf[0], &lpbk_buffer.out_payload[0], max); -+ -+ pOp = wmt_lib_get_free_op(); -+ if (!pOp) { -+ WMT_WARN_FUNC("get_free_lxop fail\n"); -+ ret = -1; -+ break; -+ } -+ pSignal = &pOp->signal; -+ pOp->op.opId = WMT_OPID_LPBK; -+ pOp->op.au4OpData[0] = lpbk_buffer.payload_length; /* packet length */ -+ pOp->op.au4OpData[1] = (UINT32) &gLpbkBuf[0]; -+ pSignal->timeoutValue = MAX_EACH_WMT_CMD; -+ WMT_INFO_FUNC("OPID(%d) type(%d) start\n", pOp->op.opId, pOp->op.au4OpData[0]); -+ if (DISABLE_PSM_MONITOR()) { -+ WMT_ERR_FUNC("wake up failed,OPID(%d) type(%d) abort\n", pOp->op.opId, pOp->op.au4OpData[0]); -+ wmt_lib_put_op_to_free_queue(pOp); -+ ret = -2; -+ } -+ -+ ret = wmt_lib_put_act_op(pOp); -+ ENABLE_PSM_MONITOR(); -+ if (MTK_WCN_BOOL_FALSE == ret) { -+ WMT_WARN_FUNC("OPID(%d) type(%d)fail\n", pOp->op.opId, pOp->op.au4OpData[0]); -+ ret = -3; -+ break; -+ } -+ WMT_INFO_FUNC("OPID(%d) length(%d) ok\n", pOp->op.opId, pOp->op.au4OpData[0]); -+ -+ memcpy(&lpbk_buffer.in_payload[0], &gLpbkBuf[0], max); -+ -+ ret = pOp->op.au4OpData[0]; -+ /*<3> compare result */ -+ if (memcmp(lpbk_buffer.in_payload, lpbk_buffer.out_payload, lpbk_buffer.payload_length)) { -+ WMT_INFO_FUNC("[%s] WMT_TEST_LPBK_CMD payload compare error\n", __func__); -+ ret = -4; -+ break; -+ } -+ WMT_ERR_FUNC("[%s] exec WMT_TEST_LPBK_CMD succeed(loop = %d, size = %ld)\n", __func__, loop, -+ lpbk_buffer.payload_length); -+ -+ } -+ -+ if (loop != count) -+ WMT_ERR_FUNC("fail at loop(%d) buf_length(%d)\n", loop, max); -+ -+ -+ return ret; -+} -+ -+INT32 wmt_dbg_internal_lpbk_test(INT32 par1, INT32 par2, INT32 par3) -+{ -+ UINT32 count; -+ UINT32 length; -+ -+ count = par1; -+ length = par2; -+ -+ WMT_INFO_FUNC("count[%d],length[%d]\n", count, length); -+ -+ wmt_core_lpbk_do_stp_init(); -+ -+ wmt_internal_loopback(count, length); -+ -+ wmt_core_lpbk_do_stp_deinit(); -+ return 0; -+} -+#endif -+ -+static INT32 wmt_dbg_set_mcu_clock(INT32 par1, INT32 par2, INT32 par3) -+{ -+ int ret = 0; -+ P_OSAL_OP pOp; -+ P_OSAL_SIGNAL pSignal = NULL; -+ UINT32 kind = 0; -+ -+ kind = par2; -+ pOp = wmt_lib_get_free_op(); -+ if (!pOp) { -+ WMT_WARN_FUNC("get_free_lxop fail\n"); -+ return -1; -+ } -+ pSignal = &pOp->signal; -+ pOp->op.opId = WMT_OPID_SET_MCU_CLK; -+ pOp->op.au4OpData[0] = kind; -+ pSignal->timeoutValue = MAX_EACH_WMT_CMD; -+ -+ WMT_INFO_FUNC("OPID(%d) kind(%d) start\n", pOp->op.opId, pOp->op.au4OpData[0]); -+ if (DISABLE_PSM_MONITOR()) { -+ WMT_ERR_FUNC("wake up failed,OPID(%d) kind(%d) abort\n", pOp->op.opId, pOp->op.au4OpData[0]); -+ wmt_lib_put_op_to_free_queue(pOp); -+ return -2; -+ } -+ -+ ret = wmt_lib_put_act_op(pOp); -+ ENABLE_PSM_MONITOR(); -+ if (MTK_WCN_BOOL_FALSE == ret) { -+ WMT_WARN_FUNC("OPID(%d) kind(%d)fail(%d)\n", pOp->op.opId, pOp->op.au4OpData[0], ret); -+ return -3; -+ } -+ WMT_INFO_FUNC("OPID(%d) kind(%d) ok\n", pOp->op.opId, pOp->op.au4OpData[0]); -+ -+ return ret; -+} -+ -+static INT32 wmt_dbg_poll_cpupcr(INT32 par1, INT32 par2, INT32 par3) -+{ -+ UINT32 count = 0; -+ UINT16 sleep = 0; -+ UINT16 toAee = 0; -+ -+ count = par2; -+ sleep = (par3 & 0xF0) >> 4; -+ toAee = (par3 & 0x0F); -+ -+ WMT_INFO_FUNC("polling count[%d],polling sleep[%d],toaee[%d]\n", count, sleep, toAee); -+ wmt_lib_poll_cpupcr(count, sleep, toAee); -+ -+ return 0; -+} -+ -+#if CONSYS_ENALBE_SET_JTAG -+static INT32 wmt_dbg_jtag_flag_ctrl(INT32 par1, INT32 par2, INT32 par3) -+{ -+ UINT32 en_flag = par2; -+ -+ wmt_lib_jtag_flag_set(en_flag); -+ return 0; -+} -+#endif -+ -+#if CFG_WMT_LTE_COEX_HANDLING -+static INT32 wmt_dbg_lte_to_wmt_test(UINT32 opcode, UINT32 msg_len) -+{ -+ ipc_ilm_t ilm; -+ local_para_struct *p_buf_str; -+ INT32 i = 0; -+ INT32 iRet = -1; -+ -+ WMT_INFO_FUNC("opcode(0x%02x),msg_len(%d)\n", opcode, msg_len); -+ p_buf_str = osal_malloc(osal_sizeof(local_para_struct) + msg_len); -+ if (NULL == p_buf_str) { -+ WMT_ERR_FUNC("kmalloc for local para ptr structure failed.\n"); -+ return -1; -+ } -+ p_buf_str->msg_len = msg_len; -+ for (i = 0; i < msg_len; i++) -+ p_buf_str->data[i] = i; -+ -+ ilm.local_para_ptr = p_buf_str; -+ ilm.msg_id = opcode; -+ -+ iRet = wmt_lib_handle_idc_msg(&ilm); -+ osal_free(p_buf_str); -+ return iRet; -+ -+} -+ -+static INT32 wmt_dbg_lte_coex_test(INT32 par1, INT32 par2, INT32 par3) -+{ -+ UINT8 *local_buffer = NULL; -+ UINT32 handle_len; -+ INT32 iRet = -1; -+ static UINT8 wmt_to_lte_test_evt1[] = { 0x02, 0x16, 0x0d, 0x00, -+ 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, -+ 0xa, 0xb -+ }; -+ static UINT8 wmt_to_lte_test_evt2[] = { 0x02, 0x16, 0x09, 0x00, -+ 0x01, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 -+ }; -+ static UINT8 wmt_to_lte_test_evt3[] = { 0x02, 0x16, 0x02, 0x00, -+ 0x02, 0xff -+ }; -+ static UINT8 wmt_to_lte_test_evt4[] = { 0x02, 0x16, 0x0d, 0x00, -+ 0x03, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, -+ 0xa, 0xb -+ }; -+ -+ local_buffer = kmalloc(512, GFP_KERNEL); -+ if (!local_buffer) { -+ WMT_ERR_FUNC("local_buffer kmalloc memory fail\n"); -+ return 0; -+ } -+ -+ if (par2 == 1) { -+ handle_len = -+ wmt_idc_msg_to_lte_handing_for_test(&wmt_to_lte_test_evt1[0], osal_sizeof(wmt_to_lte_test_evt1)); -+ if (handle_len != osal_sizeof(wmt_to_lte_test_evt1)) { -+ WMT_ERR_FUNC("par2=1,wmt send to lte msg fail:handle_len(%d),buff_len(%d)\n", -+ handle_len, osal_sizeof(wmt_to_lte_test_evt1)); -+ } else { -+ WMT_INFO_FUNC("par2=1,wmt send to lte msg OK! send_len(%d)\n", handle_len); -+ } -+ } -+ if (par2 == 2) { -+ osal_memcpy(&local_buffer[0], &wmt_to_lte_test_evt1[0], osal_sizeof(wmt_to_lte_test_evt1)); -+ osal_memcpy(&local_buffer[osal_sizeof(wmt_to_lte_test_evt1)], -+ &wmt_to_lte_test_evt2[0], osal_sizeof(wmt_to_lte_test_evt2)); -+ -+ handle_len = -+ wmt_idc_msg_to_lte_handing_for_test(&local_buffer[0], -+ osal_sizeof(wmt_to_lte_test_evt1) + -+ osal_sizeof(wmt_to_lte_test_evt2)); -+ if (handle_len != osal_sizeof(wmt_to_lte_test_evt1) + osal_sizeof(wmt_to_lte_test_evt2)) { -+ WMT_ERR_FUNC("par2=2,wmt send to lte msg fail:handle_len(%d),buff_len(%d)\n", -+ handle_len, osal_sizeof(wmt_to_lte_test_evt1) + osal_sizeof(wmt_to_lte_test_evt2)); -+ } else { -+ WMT_INFO_FUNC("par2=1,wmt send to lte msg OK! send_len(%d)\n", handle_len); -+ } -+ } -+ if (par2 == 3) { -+ osal_memcpy(&local_buffer[0], &wmt_to_lte_test_evt1[0], osal_sizeof(wmt_to_lte_test_evt1)); -+ osal_memcpy(&local_buffer[osal_sizeof(wmt_to_lte_test_evt1)], -+ &wmt_to_lte_test_evt2[0], osal_sizeof(wmt_to_lte_test_evt2)); -+ osal_memcpy(&local_buffer[osal_sizeof(wmt_to_lte_test_evt1) + osal_sizeof(wmt_to_lte_test_evt2)], -+ &wmt_to_lte_test_evt3[0], osal_sizeof(wmt_to_lte_test_evt3)); -+ -+ handle_len = wmt_idc_msg_to_lte_handing_for_test(&local_buffer[0], osal_sizeof(wmt_to_lte_test_evt1) + -+ osal_sizeof(wmt_to_lte_test_evt2) + -+ osal_sizeof(wmt_to_lte_test_evt3)); -+ if (handle_len != -+ osal_sizeof(wmt_to_lte_test_evt1) + osal_sizeof(wmt_to_lte_test_evt2) + -+ osal_sizeof(wmt_to_lte_test_evt3)) { -+ WMT_ERR_FUNC("par2=3,wmt send to lte msg fail:handle_len(%d),buff_len(%d)\n", handle_len, -+ osal_sizeof(wmt_to_lte_test_evt1) + osal_sizeof(wmt_to_lte_test_evt2) + -+ osal_sizeof(wmt_to_lte_test_evt3)); -+ } else { -+ WMT_INFO_FUNC("par3=1,wmt send to lte msg OK! send_len(%d)\n", handle_len); -+ } -+ } -+ if (par2 == 4) { -+ handle_len = -+ wmt_idc_msg_to_lte_handing_for_test(&wmt_to_lte_test_evt4[0], osal_sizeof(wmt_to_lte_test_evt4)); -+ if (handle_len != osal_sizeof(wmt_to_lte_test_evt4)) { -+ WMT_ERR_FUNC("par2=1,wmt send to lte msg fail:handle_len(%d),buff_len(%d)\n", -+ handle_len, osal_sizeof(wmt_to_lte_test_evt4)); -+ } else { -+ WMT_INFO_FUNC("par2=1,wmt send to lte msg OK! send_len(%d)\n", handle_len); -+ } -+ } -+ if (par2 == 5) { -+ if (par3 >= 1024) -+ par3 = 1024; -+ -+ iRet = wmt_dbg_lte_to_wmt_test(IPC_MSG_ID_EL1_LTE_DEFAULT_PARAM_IND, par3); -+ WMT_INFO_FUNC("IPC_MSG_ID_EL1_LTE_DEFAULT_PARAM_IND test result(%d)\n", iRet); -+ } -+ if (par2 == 6) { -+ if (par3 >= 1024) -+ par3 = 1024; -+ -+ iRet = wmt_dbg_lte_to_wmt_test(IPC_MSG_ID_EL1_LTE_OPER_FREQ_PARAM_IND, par3); -+ WMT_INFO_FUNC("IPC_MSG_ID_EL1_LTE_OPER_FREQ_PARAM_IND test result(%d)\n", iRet); -+ } -+ if (par2 == 7) { -+ if (par3 >= 1024) -+ par3 = 1024; -+ -+ iRet = wmt_dbg_lte_to_wmt_test(IPC_MSG_ID_EL1_WIFI_MAX_PWR_IND, par3); -+ WMT_INFO_FUNC("IPC_MSG_ID_EL1_WIFI_MAX_PWR_IND test result(%d)\n", iRet); -+ } -+ if (par2 == 8) { -+ if (par3 >= 1024) -+ par3 = 1024; -+ -+ iRet = wmt_dbg_lte_to_wmt_test(IPC_MSG_ID_EL1_LTE_TX_IND, par3); -+ WMT_INFO_FUNC("IPC_MSG_ID_EL1_LTE_TX_IND test result(%d)\n", iRet); -+ } -+ if (par2 == 9) { -+ if (par3 > 0) -+ wmt_core_set_flag_for_test(1); -+ else -+ wmt_core_set_flag_for_test(0); -+ } -+ return 0; -+ kfree(local_buffer); -+} -+#endif -+ -+static ssize_t wmt_dev_dbg_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos) -+{ -+ -+ INT32 retval = 0; -+ INT32 i_ret = 0; -+ PINT8 warn_msg = "no data available, please run echo 15 xx > /proc/driver/wmt_psm first\n"; -+ -+ if (*f_pos > 0) { -+ retval = 0; -+ } else { -+ /*len = sprintf(page, "%d\n", g_psm_enable); */ -+ if (gCoexBuf.availSize <= 0) { -+ WMT_INFO_FUNC("no data available, please run echo 15 xx > /proc/driver/wmt_psm first\n"); -+ retval = osal_strlen(warn_msg) + 1; -+ if (count < retval) -+ retval = count; -+ -+ i_ret = copy_to_user(buf, warn_msg, retval); -+ if (i_ret) { -+ WMT_ERR_FUNC("copy to buffer failed, ret:%d\n", retval); -+ retval = -EFAULT; -+ goto err_exit; -+ } -+ *f_pos += retval; -+ } else { -+ INT32 i = 0; -+ INT32 len = 0; -+ INT8 msg_info[128]; -+ INT32 max_num = 0; -+ /*we do not check page buffer, because there are only -+ * 100 bytes in g_coex_buf, no reason page buffer is not -+ * enough, a bomb is placed here on unexpected condition -+ */ -+ -+ WMT_INFO_FUNC("%d bytes available\n", gCoexBuf.availSize); -+ max_num = ((osal_sizeof(msg_info) > count ? osal_sizeof(msg_info) : count) - 1) / 5; -+ -+ if (max_num > gCoexBuf.availSize) -+ max_num = gCoexBuf.availSize; -+ else -+ WMT_INFO_FUNC("round to %d bytes due to local buffer size limitation\n", max_num); -+ -+ -+ for (i = 0; i < max_num; i++) -+ len += osal_sprintf(msg_info + len, "0x%02x ", gCoexBuf.buffer[i]); -+ -+ -+ len += osal_sprintf(msg_info + len, "\n"); -+ retval = len; -+ -+ i_ret = copy_to_user(buf, msg_info, retval); -+ if (i_ret) { -+ WMT_ERR_FUNC("copy to buffer failed, ret:%d\n", retval); -+ retval = -EFAULT; -+ goto err_exit; -+ } -+ *f_pos += retval; -+ -+ } -+ } -+ gCoexBuf.availSize = 0; -+err_exit: -+ -+ return retval; -+} -+ -+static ssize_t wmt_dev_dbg_write(struct file *filp, const char __user *buffer, size_t count, loff_t *f_pos) -+{ -+ INT8 buf[256]; -+ PINT8 pBuf; -+ ssize_t len = count; -+ INT32 x = 0, y = 0, z = 0; -+ PINT8 pToken = NULL; -+ PINT8 pDelimiter = " \t"; -+ long res; -+ INT32 ret; -+ -+ WMT_INFO_FUNC("write parameter len = %d\n\r", (INT32) len); -+ if (len >= osal_sizeof(buf)) { -+ WMT_ERR_FUNC("input handling fail!\n"); -+ len = osal_sizeof(buf) - 1; -+ return -1; -+ } -+ -+ if (copy_from_user(buf, buffer, len)) -+ return -EFAULT; -+ -+ buf[len] = '\0'; -+ WMT_INFO_FUNC("write parameter data = %s\n\r", buf); -+ -+ pBuf = buf; -+ pToken = osal_strsep(&pBuf, pDelimiter); -+ -+ if (pToken != NULL) { -+ ret = osal_strtol(pToken, 16, &res); -+ if (ret) { -+ WMT_ERR_FUNC("get x fail(%d)\n", ret); -+ x = 0; -+ } -+ x = res; -+ } else { -+ x = 0; -+ } -+ -+ pToken = osal_strsep(&pBuf, "\t\n "); -+ if (pToken != NULL) { -+ ret = osal_strtol(pToken, 16, &res); -+ if (ret) { -+ WMT_ERR_FUNC("get y fail(%d)\n", ret); -+ y = 0; -+ } -+ y = res; -+ WMT_INFO_FUNC("y = 0x%08x\n\r", y); -+ } else { -+ y = 3000; -+ /*efuse, register read write default value */ -+ if (0x11 == x || 0x12 == x || 0x13 == x) -+ y = 0x80000000; -+ -+ } -+ -+ pToken = osal_strsep(&pBuf, "\t\n "); -+ if (pToken != NULL) { -+ ret = osal_strtol(pToken, 16, &res); -+ if (ret) { -+ WMT_ERR_FUNC("get z fail(%d)\n", ret); -+ z = 0; -+ } -+ z = res; -+ } else { -+ z = 10; -+ /*efuse, register read write default value */ -+ if (0x11 == x || 0x12 == x || 0x13 == x) -+ z = 0xffffffff; -+ -+ } -+ -+ WMT_WARN_FUNC("x(0x%08x), y(0x%08x), z(0x%08x)\n\r", x, y, z); -+ -+ if (osal_array_size(wmt_dev_dbg_func) > x && NULL != wmt_dev_dbg_func[x]) -+ (*wmt_dev_dbg_func[x]) (x, y, z); -+ else -+ WMT_WARN_FUNC("no handler defined for command id(0x%08x)\n\r", x); -+ -+ return len; -+} -+ -+INT32 wmt_dev_dbg_setup(VOID) -+{ -+ static const struct file_operations wmt_dbg_fops = { -+ .owner = THIS_MODULE, -+ .read = wmt_dev_dbg_read, -+ .write = wmt_dev_dbg_write, -+ }; -+ gWmtDbgEntry = proc_create(WMT_DBG_PROCNAME, 0664, NULL, &wmt_dbg_fops); -+ if (gWmtDbgEntry == NULL) { -+ WMT_ERR_FUNC("Unable to create /proc entry\n\r"); -+ return -1; -+ } -+ return 0; -+} -+ -+INT32 wmt_dev_dbg_remove(VOID) -+{ -+ if (NULL != gWmtDbgEntry) -+ remove_proc_entry(WMT_DBG_PROCNAME, NULL); -+ -+#if CFG_WMT_PS_SUPPORT -+ wmt_lib_ps_deinit(); -+#endif -+ return 0; -+} -+#endif -+ -+#if CFG_WMT_PROC_FOR_AEE -+ -+static ssize_t wmt_dev_proc_for_aee_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos) -+{ -+ INT32 retval = 0; -+ UINT32 len = 0; -+ -+ WMT_INFO_FUNC("%s: count %d pos %lld\n", __func__, count, *f_pos); -+ -+ if (0 == *f_pos) { -+ pBuf = wmt_lib_get_cpupcr_xml_format(&len); -+ g_buf_len = len; -+ WMT_INFO_FUNC("wmt_dev:wmt for aee buffer len(%d)\n", g_buf_len); -+ } -+ -+ if (g_buf_len >= count) { -+ -+ retval = copy_to_user(buf, pBuf, count); -+ if (retval) { -+ WMT_ERR_FUNC("copy to aee buffer failed, ret:%d\n", retval); -+ retval = -EFAULT; -+ goto err_exit; -+ } -+ -+ *f_pos += count; -+ g_buf_len -= count; -+ pBuf += count; -+ WMT_INFO_FUNC("wmt_dev:after read,wmt for aee buffer len(%d)\n", g_buf_len); -+ -+ retval = count; -+ } else if (0 != g_buf_len) { -+ -+ retval = copy_to_user(buf, pBuf, g_buf_len); -+ if (retval) { -+ WMT_ERR_FUNC("copy to aee buffer failed, ret:%d\n", retval); -+ retval = -EFAULT; -+ goto err_exit; -+ } -+ -+ *f_pos += g_buf_len; -+ len = g_buf_len; -+ g_buf_len = 0; -+ pBuf += len; -+ retval = len; -+ WMT_INFO_FUNC("wmt_dev:after read,wmt for aee buffer len(%d)\n", g_buf_len); -+ } else { -+ WMT_INFO_FUNC("wmt_dev: no data available for aee\n"); -+ retval = 0; -+ } -+err_exit: -+ return retval; -+} -+ -+static ssize_t wmt_dev_proc_for_aee_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos) -+{ -+ WMT_TRC_FUNC(); -+ return 0; -+} -+ -+INT32 wmt_dev_proc_for_aee_setup(VOID) -+{ -+ static const struct file_operations wmt_aee_fops = { -+ .owner = THIS_MODULE, -+ .read = wmt_dev_proc_for_aee_read, -+ .write = wmt_dev_proc_for_aee_write, -+ }; -+ -+ gWmtDbgEntry = proc_create(WMT_AEE_PROCNAME, 0664, NULL, &wmt_aee_fops); -+ if (gWmtDbgEntry == NULL) { -+ WMT_ERR_FUNC("Unable to create /proc entry\n\r"); -+ return -1; -+ } -+ -+ return 0; -+} -+ -+INT32 wmt_dev_proc_for_aee_remove(VOID) -+{ -+ if (NULL != gWmtAeeEntry) -+ remove_proc_entry(WMT_AEE_PROCNAME, NULL); -+ -+ return 0; -+} -+#endif -+ -+VOID wmt_dev_rx_event_cb(VOID) -+{ -+ u4RxFlag = 1; -+ atomic_inc(&gRxCount); -+ if (NULL != gpRxEvent) { -+ /* u4RxFlag = 1; */ -+ /* atomic_inc(&gRxCount); */ -+ wake_up_interruptible(&gpRxEvent->waitQueue); -+ } else { -+ /* WMT_ERR_FUNC("null gpRxEvent, flush rx!\n"); */ -+ /* wmt_lib_flush_rx(); */ -+ } -+} -+ -+INT32 wmt_dev_rx_timeout(P_OSAL_EVENT pEvent) -+{ -+ -+ UINT32 ms = pEvent->timeoutValue; -+ long lRet = 0; -+ -+ gpRxEvent = pEvent; -+ if (0 != ms) -+ lRet = wait_event_interruptible_timeout(gpRxEvent->waitQueue, 0 != u4RxFlag, msecs_to_jiffies(ms)); -+ else -+ lRet = wait_event_interruptible(gpRxEvent->waitQueue, u4RxFlag != 0); -+ -+ u4RxFlag = 0; -+/* gpRxEvent = NULL; */ -+ if (atomic_dec_return(&gRxCount)) { -+ WMT_ERR_FUNC("gRxCount != 0 (%d), reset it!\n", atomic_read(&gRxCount)); -+ atomic_set(&gRxCount, 0); -+ } -+ -+ return lRet; -+} -+ -+INT32 wmt_dev_read_file(PUINT8 pName, const PPUINT8 ppBufPtr, INT32 offset, INT32 padSzBuf) -+{ -+ INT32 iRet = -1; -+ struct file *fd; -+ /* ssize_t iRet; */ -+ INT32 file_len; -+ INT32 read_len; -+ PVOID pBuf; -+ mm_segment_t fs; -+ -+ /* struct cred *cred = get_task_cred(current); */ -+ //const struct cred *cred = get_current_cred(); -+ -+ if (!ppBufPtr) { -+ WMT_ERR_FUNC("invalid ppBufptr!\n"); -+ return -1; -+ } -+ *ppBufPtr = NULL; -+ -+ fd = filp_open(pName, O_RDONLY, 0); -+ if (IS_ERR(fd)) { -+ WMT_ERR_FUNC("error code:%d\n", PTR_ERR(fd)); -+ return -2; -+ } -+ -+ if(fd->f_op == NULL) { -+ printk(KERN_ERR "invalid file op \r\n"); -+ return -3; -+ } -+ -+#if 0 -+ if (!fd || IS_ERR(fd) || !fd->f_op || !fd->f_op->read) { -+ WMT_ERR_FUNC("failed to open or read!(0x%p, %d, %d, %d)\n", fd, PTR_ERR(fd), cred->fsuid, cred->fsgid); -+ if (IS_ERR(fd)) -+ WMT_ERR_FUNC("error code:%d\n", PTR_ERR(fd)); -+ return -1; -+ } -+#endif -+ file_len = fd->f_path.dentry->d_inode->i_size; -+ file_len = fd->f_op->llseek(fd, 0, 2); -+ fd->f_op->llseek(fd, 0, 0); -+ pBuf = vmalloc((file_len + BCNT_PATCH_BUF_HEADROOM + 3) & ~0x3UL); -+ if (!pBuf) { -+ WMT_ERR_FUNC("failed to vmalloc(%d)\n", (INT32) ((file_len + 3) & ~0x3UL)); -+ goto read_file_done; -+ } -+ -+ do { -+ if (fd->f_pos != offset) { -+ if (fd->f_op->llseek) { -+ if (fd->f_op->llseek(fd, offset, 0) != offset) { -+ WMT_ERR_FUNC("failed to seek!!\n"); -+ goto read_file_done; -+ } -+ } else { -+ fd->f_pos = offset; -+ } -+ } -+ -+ fs=get_fs(); -+ read_len = vfs_read(fd, pBuf + padSzBuf, file_len, &fd->f_pos); -+ set_fs(fs); -+ if (read_len != file_len) -+ WMT_WARN_FUNC("read abnormal: read_len(%d), file_len(%d)\n", read_len, file_len); -+ -+ } while (false); -+ -+ iRet = 0; -+ *ppBufPtr = pBuf; -+ -+read_file_done: -+ if (iRet) { -+ if (pBuf) -+ vfree(pBuf); -+ -+ } -+ -+ filp_close(fd, NULL); -+ -+ return (iRet) ? iRet : read_len; -+} -+ -+/* TODO: [ChangeFeature][George] refine this function name for general filesystem read operation, not patch only. */ -+INT32 wmt_dev_patch_get(PUINT8 pPatchName, osal_firmware **ppPatch, INT32 padSzBuf) -+{ -+ INT32 iRet = -1; -+ osal_firmware *pfw; -+ uid_t orig_uid; -+ gid_t orig_gid; -+ -+ /* struct cred *cred = get_task_cred(current); */ -+ struct cred *cred = (struct cred *)get_current_cred(); -+ -+ mm_segment_t orig_fs = get_fs(); -+ -+ if (*ppPatch) { -+ WMT_WARN_FUNC("f/w patch already exists\n"); -+ if ((*ppPatch)->data) -+ vfree((*ppPatch)->data); -+ -+ kfree(*ppPatch); -+ *ppPatch = NULL; -+ } -+ -+ if (!osal_strlen(pPatchName)) { -+ WMT_ERR_FUNC("empty f/w name\n"); -+ osal_assert((osal_strlen(pPatchName) > 0)); -+ return -1; -+ } -+ -+ pfw = kzalloc(sizeof(osal_firmware), /*GFP_KERNEL */ GFP_ATOMIC); -+ if (!pfw) { -+ WMT_ERR_FUNC("kzalloc(%d) fail\n", sizeof(osal_firmware)); -+ return -2; -+ } -+ -+ orig_uid = cred->fsuid.val; -+ orig_gid = cred->fsgid.val; -+ cred->fsuid.val = cred->fsgid.val = 0; -+ -+ set_fs(get_ds()); -+ -+ /* load patch file from fs */ -+ iRet = wmt_dev_read_file(pPatchName, (const PPUINT8)&pfw->data, 0, padSzBuf); -+ set_fs(orig_fs); -+ -+ cred->fsuid.val = orig_uid; -+ cred->fsgid.val = orig_gid; -+ -+ -+ if (iRet > 0) { -+ pfw->size = iRet; -+ *ppPatch = pfw; -+ WMT_DBG_FUNC("load (%s) to addr(0x%p) success\n", pPatchName, pfw->data); -+ return 0; -+ } -+ kfree(pfw); -+ *ppPatch = NULL; -+ WMT_ERR_FUNC("load file (%s) fail, iRet(%d)\n", pPatchName, iRet); -+ return -1; -+} -+ -+INT32 wmt_dev_patch_put(osal_firmware **ppPatch) -+{ -+ if (NULL != *ppPatch) { -+ if ((*ppPatch)->data) -+ vfree((*ppPatch)->data); -+ -+ kfree(*ppPatch); -+ *ppPatch = NULL; -+ } -+ return 0; -+} -+ -+VOID wmt_dev_patch_info_free(VOID) -+{ -+ -+ kfree(pPatchInfo); -+ pPatchInfo = NULL; -+ -+} -+ -+MTK_WCN_BOOL wmt_dev_is_file_exist(PUINT8 pFileName) -+{ -+ struct file *fd = NULL; -+ /* ssize_t iRet; */ -+ INT32 fileLen = -1; -+ const struct cred *cred = get_current_cred(); -+ -+ if (pFileName == NULL) { -+ WMT_ERR_FUNC("invalid file name pointer(%p)\n", pFileName); -+ return MTK_WCN_BOOL_FALSE; -+ } -+ if (osal_strlen(pFileName) < osal_strlen(defaultPatchName)) { -+ WMT_ERR_FUNC("invalid file name(%s)\n", pFileName); -+ return MTK_WCN_BOOL_FALSE; -+ } -+ /* struct cred *cred = get_task_cred(current); */ -+ -+ fd = filp_open(pFileName, O_RDONLY, 0); -+ if (!fd || IS_ERR(fd) || !fd->f_op || !fd->f_op->read) { -+ WMT_ERR_FUNC("failed to open or read(%s)!(0x%p, %d, %d)\n", pFileName, fd, cred->fsuid, cred->fsgid); -+ return MTK_WCN_BOOL_FALSE; -+ } -+ fileLen = fd->f_path.dentry->d_inode->i_size; -+ filp_close(fd, NULL); -+ fd = NULL; -+ if (fileLen <= 0) { -+ WMT_ERR_FUNC("invalid file(%s), length(%d)\n", pFileName, fileLen); -+ return MTK_WCN_BOOL_FALSE; -+ } -+ WMT_ERR_FUNC("valid file(%s), length(%d)\n", pFileName, fileLen); -+ return true; -+ -+} -+ -+/* static unsigned long count_last_access_sdio = 0; */ -+static unsigned long count_last_access_btif; -+static unsigned long jiffies_last_poll; -+ -+#if 0 -+static INT32 wmt_dev_tra_sdio_update(void) -+{ -+ count_last_access_sdio += 1; -+ /* WMT_INFO_FUNC("jiffies_last_access_sdio: jiffies = %ul\n", jiffies); */ -+ -+ return 0; -+} -+#endif -+ -+extern INT32 wmt_dev_tra_bitf_update(void) -+{ -+ count_last_access_btif += 1; -+ /* WMT_INFO_FUNC("jiffies_last_access_btif: jiffies = %ul\n", jiffies); */ -+ -+ return 0; -+} -+ -+static UINT32 wmt_dev_tra_ahb_poll(void) -+{ -+#define TIME_THRESHOLD_TO_TEMP_QUERY 3000 -+#define COUNT_THRESHOLD_TO_TEMP_QUERY 200 -+ -+ unsigned long ahb_during_count = 0; -+ unsigned long poll_during_time = 0; -+ -+ /* if (jiffies > jiffies_last_poll) */ -+ if (time_after(jiffies, jiffies_last_poll)) -+ poll_during_time = jiffies - jiffies_last_poll; -+ else -+ poll_during_time = 0xffffffff; -+ -+ -+ WMT_DBG_FUNC("**jiffies_to_mesecs(0xffffffff) = %lu\n", jiffies_to_msecs(0xffffffff)); -+ -+ if (jiffies_to_msecs(poll_during_time) < TIME_THRESHOLD_TO_TEMP_QUERY) { -+ WMT_DBG_FUNC("**poll_during_time = %lu < %lu, not to query\n", -+ jiffies_to_msecs(poll_during_time), TIME_THRESHOLD_TO_TEMP_QUERY); -+ return -1; -+ } -+ /* ahb_during_count = count_last_access_sdio; */ -+ if (NULL == mtk_wcn_wlan_bus_tx_cnt) { -+ WMT_ERR_FUNC("WMT-DEV:mtk_wcn_wlan_bus_tx_cnt null pointer\n"); -+ return -1; -+ } -+ ahb_during_count = (*mtk_wcn_wlan_bus_tx_cnt) (); -+ -+ if (ahb_during_count < COUNT_THRESHOLD_TO_TEMP_QUERY) { -+ WMT_DBG_FUNC("**ahb_during_count = %lu < %lu, not to query\n", -+ ahb_during_count, COUNT_THRESHOLD_TO_TEMP_QUERY); -+ return -2; -+ } -+ -+ if (NULL == mtk_wcn_wlan_bus_tx_cnt_clr) { -+ WMT_ERR_FUNC("WMT-DEV:mtk_wcn_wlan_bus_tx_cnt_clr null pointer\n"); -+ return -3; -+ } -+ (*mtk_wcn_wlan_bus_tx_cnt_clr) (); -+ /* count_last_access_sdio = 0; */ -+ jiffies_last_poll = jiffies; -+ -+ WMT_INFO_FUNC("**poll_during_time = %lu > %lu, ahb_during_count = %lu > %lu, query\n", -+ jiffies_to_msecs(poll_during_time), TIME_THRESHOLD_TO_TEMP_QUERY, -+ jiffies_to_msecs(ahb_during_count), COUNT_THRESHOLD_TO_TEMP_QUERY); -+ -+ return 0; -+} -+ -+long wmt_dev_tm_temp_query(void) -+{ -+#define HISTORY_NUM 5 -+#define TEMP_THRESHOLD 65 -+#define REFRESH_TIME 300 /* sec */ -+ -+ static INT32 temp_table[HISTORY_NUM] = { 99 }; /* not query yet. */ -+ static INT32 idx_temp_table; -+ static struct timeval query_time, now_time; -+ -+ INT8 query_cond = 0; -+ INT32 current_temp = 0; -+ INT32 index = 0; -+ long return_temp = 0; -+ /* Query condition 1: */ -+ /* If we have the high temperature records on the past, we continue to query/monitor */ -+ /* the real temperature until cooling */ -+ for (index = 0; index < HISTORY_NUM; index++) { -+ if (temp_table[index] >= TEMP_THRESHOLD) { -+ query_cond = 1; -+ WMT_DBG_FUNC("temperature table is still initial value, we should query temp temperature..\n"); -+ } -+ } -+ -+ do_gettimeofday(&now_time); -+#if 1 -+ /* Query condition 2: */ -+ /* Moniter the ahb bus activity to decide if we have the need to query temperature. */ -+ if (!query_cond) { -+ if (wmt_dev_tra_ahb_poll() == 0) { -+ query_cond = 1; -+ WMT_INFO_FUNC("ahb traffic , we must query temperature..\n"); -+ } else { -+ WMT_DBG_FUNC("ahb idle traffic ....\n"); -+ } -+ -+ /* only WIFI tx power might make temperature varies largely */ -+#if 0 -+ if (!query_cond) { -+ last_access_time = wmt_dev_tra_uart_poll(); -+ if (jiffies_to_msecs(last_access_time) < TIME_THRESHOLD_TO_TEMP_QUERY) { -+ query_cond = 1; -+ WMT_DBG_FUNC("uart busy traffic , we must query temperature..\n"); -+ } else { -+ WMT_DBG_FUNC("uart still idle traffic , we don't query temp temperature..\n"); -+ } -+ } -+#endif -+ } -+#endif -+ /* Query condition 3: */ -+ /* If the query time exceeds the a certain of period, refresh temp table. */ -+ /* */ -+ if (!query_cond) { -+ /* time overflow, we refresh temp table again for simplicity! */ -+ if ((now_time.tv_sec < query_time.tv_sec) || -+ ((now_time.tv_sec > query_time.tv_sec) && (now_time.tv_sec - query_time.tv_sec) > REFRESH_TIME)) { -+ query_cond = 1; -+ -+ WMT_INFO_FUNC("It is long time (> %d sec) not to query, we must query temp temperature..\n", -+ REFRESH_TIME); -+ for (index = 0; index < HISTORY_NUM; index++) -+ temp_table[index] = 99; -+ -+ } -+ } -+ -+ if (query_cond) { -+ /* update the temperature record */ -+ mtk_wcn_wmt_therm_ctrl(WMTTHERM_ENABLE); -+ current_temp = mtk_wcn_wmt_therm_ctrl(WMTTHERM_READ); -+ mtk_wcn_wmt_therm_ctrl(WMTTHERM_DISABLE); -+ idx_temp_table = (idx_temp_table + 1) % HISTORY_NUM; -+ temp_table[idx_temp_table] = current_temp; -+ do_gettimeofday(&query_time); -+ -+ WMT_INFO_FUNC("[Thermal] current_temp = 0x%x\n", (current_temp & 0xFF)); -+ } else { -+ current_temp = temp_table[idx_temp_table]; -+ idx_temp_table = (idx_temp_table + 1) % HISTORY_NUM; -+ temp_table[idx_temp_table] = current_temp; -+ } -+ -+ /* */ -+ /* Dump information */ -+ /* */ -+ WMT_DBG_FUNC("[Thermal] idx_temp_table = %d\n", idx_temp_table); -+ WMT_DBG_FUNC("[Thermal] now.time = %d, query.time = %d, REFRESH_TIME = %d\n", now_time.tv_sec, -+ query_time.tv_sec, REFRESH_TIME); -+ -+ WMT_DBG_FUNC("[0] = %d, [1] = %d, [2] = %d, [3] = %d, [4] = %d\n----\n", -+ temp_table[0], temp_table[1], temp_table[2], temp_table[3], temp_table[4]); -+ -+ return_temp = ((current_temp & 0x80) == 0x0) ? current_temp : (-1) * (current_temp & 0x7f); -+ -+ return return_temp; -+} -+ -+ssize_t WMT_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos) -+{ -+ INT32 iRet = 0; -+ UINT8 wrBuf[NAME_MAX + 1] = { 0 }; -+ INT32 copySize = (count < NAME_MAX) ? count : NAME_MAX; -+ -+ WMT_LOUD_FUNC("count:%d copySize:%d\n", count, copySize); -+ -+ if (copySize > 0) { -+ if (copy_from_user(wrBuf, buf, copySize)) { -+ iRet = -EFAULT; -+ goto write_done; -+ } -+ iRet = copySize; -+ wrBuf[NAME_MAX] = '\0'; -+ -+ if (!strncasecmp(wrBuf, "ok", NAME_MAX)) { -+ WMT_DBG_FUNC("resp str ok\n"); -+ /* pWmtDevCtx->cmd_result = 0; */ -+ wmt_lib_trigger_cmd_signal(0); -+ } else { -+ WMT_WARN_FUNC("warning resp str (%s)\n", wrBuf); -+ /* pWmtDevCtx->cmd_result = -1; */ -+ wmt_lib_trigger_cmd_signal(-1); -+ } -+ /* complete(&pWmtDevCtx->cmd_comp); */ -+ -+ } -+ -+write_done: -+ return iRet; -+} -+ -+ssize_t WMT_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos) -+{ -+ INT32 iRet = 0; -+ PUINT8 pCmd = NULL; -+ UINT32 cmdLen = 0; -+ -+ pCmd = wmt_lib_get_cmd(); -+ -+ if (pCmd != NULL) { -+ cmdLen = osal_strlen(pCmd) < NAME_MAX ? osal_strlen(pCmd) : NAME_MAX; -+ WMT_DBG_FUNC("cmd str(%s)\n", pCmd); -+ if (copy_to_user(buf, pCmd, cmdLen)) -+ iRet = -EFAULT; -+ else -+ iRet = cmdLen; -+ -+ } -+#if 0 -+ if (test_and_clear_bit(WMT_STAT_CMD, &pWmtDevCtx->state)) { -+ iRet = osal_strlen(localBuf) < NAME_MAX ? osal_strlen(localBuf) : NAME_MAX; -+ /* we got something from STP driver */ -+ WMT_DBG_FUNC("copy cmd to user by read:%s\n", localBuf); -+ if (copy_to_user(buf, localBuf, iRet)) { -+ iRet = -EFAULT; -+ goto read_done; -+ } -+ } -+#endif -+ return iRet; -+} -+ -+unsigned int WMT_poll(struct file *filp, poll_table *wait) -+{ -+ UINT32 mask = 0; -+ P_OSAL_EVENT pEvent = wmt_lib_get_cmd_event(); -+ -+ poll_wait(filp, &pEvent->waitQueue, wait); -+ /* empty let select sleep */ -+ if (MTK_WCN_BOOL_TRUE == wmt_lib_get_cmd_status()) -+ mask |= POLLIN | POLLRDNORM; /* readable */ -+ -+#if 0 -+ if (test_bit(WMT_STAT_CMD, &pWmtDevCtx->state)) -+ mask |= POLLIN | POLLRDNORM; /* readable */ -+ -+#endif -+ mask |= POLLOUT | POLLWRNORM; /* writable */ -+ return mask; -+} -+ -+/* INT32 WMT_ioctl(struct inode *inode, struct file *filp, UINT32 cmd, unsigned long arg) */ -+long WMT_unlocked_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) -+{ -+ -+ INT32 iRet = 0; -+ UINT8 *pBuffer = NULL; -+ -+ WMT_DBG_FUNC("cmd (%u), arg (0x%lx)\n", cmd, arg); -+ switch (cmd) { -+ case WMT_IOCTL_SET_PATCH_NAME: /* patch location */ -+ { -+ -+ pBuffer = kmalloc(NAME_MAX + 1, GFP_KERNEL); -+ if (!pBuffer) { -+ WMT_ERR_FUNC("pBuffer kmalloc memory fail\n"); -+ return 0; -+ } -+ if (copy_from_user(pBuffer, (void *)arg, NAME_MAX)) { -+ iRet = -EFAULT; -+ kfree(pBuffer); -+ break; -+ } -+ pBuffer[NAME_MAX] = '\0'; -+ wmt_lib_set_patch_name(pBuffer); -+ kfree(pBuffer); -+ } -+ break; -+ -+ case WMT_IOCTL_SET_STP_MODE: /* stp/hif/fm mode */ -+ -+ /* set hif conf */ -+ do { -+ P_OSAL_OP pOp; -+ MTK_WCN_BOOL bRet; -+ P_OSAL_SIGNAL pSignal = NULL; -+ P_WMT_HIF_CONF pHif = NULL; -+ -+ iRet = wmt_lib_set_hif(arg); -+ if (0 != iRet) { -+ WMT_INFO_FUNC("wmt_lib_set_hif fail\n"); -+ break; -+ } -+ -+ pOp = wmt_lib_get_free_op(); -+ if (!pOp) { -+ WMT_INFO_FUNC("get_free_lxop fail\n"); -+ break; -+ } -+ pSignal = &pOp->signal; -+ pOp->op.opId = WMT_OPID_HIF_CONF; -+ -+ pHif = wmt_lib_get_hif(); -+ -+ osal_memcpy(&pOp->op.au4OpData[0], pHif, sizeof(WMT_HIF_CONF)); -+ pOp->op.u4InfoBit = WMT_OP_HIF_BIT; -+ pSignal->timeoutValue = 0; -+ -+ bRet = wmt_lib_put_act_op(pOp); -+ WMT_DBG_FUNC("WMT_OPID_HIF_CONF result(%d)\n", bRet); -+ iRet = (MTK_WCN_BOOL_FALSE == bRet) ? -EFAULT : 0; -+ } while (0); -+ -+ break; -+ -+ case WMT_IOCTL_FUNC_ONOFF_CTRL: /* test turn on/off func */ -+ -+ do { -+ MTK_WCN_BOOL bRet = MTK_WCN_BOOL_FALSE; -+ -+ if (arg & 0x80000000) -+ bRet = mtk_wcn_wmt_func_on(arg & 0xF); -+ else -+ bRet = mtk_wcn_wmt_func_off(arg & 0xF); -+ -+ iRet = (MTK_WCN_BOOL_FALSE == bRet) ? -EFAULT : 0; -+ } while (0); -+ -+ break; -+ -+ case WMT_IOCTL_LPBK_POWER_CTRL: -+ /*switch Loopback function on/off -+ arg: bit0 = 1:turn loopback function on -+ bit0 = 0:turn loopback function off -+ */ -+ do { -+ MTK_WCN_BOOL bRet = MTK_WCN_BOOL_FALSE; -+ -+ if (arg & 0x01) -+ bRet = mtk_wcn_wmt_func_on(WMTDRV_TYPE_LPBK); -+ else -+ bRet = mtk_wcn_wmt_func_off(WMTDRV_TYPE_LPBK); -+ -+ iRet = (MTK_WCN_BOOL_FALSE == bRet) ? -EFAULT : 0; -+ } while (0); -+ -+ break; -+ -+ case WMT_IOCTL_LPBK_TEST: -+ do { -+ P_OSAL_OP pOp; -+ MTK_WCN_BOOL bRet; -+ UINT32 u4Wait; -+ /* UINT8 lpbk_buf[1024] = {0}; */ -+ UINT32 effectiveLen = 0; -+ P_OSAL_SIGNAL pSignal = NULL; -+ -+ if (copy_from_user(&effectiveLen, (void *)arg, sizeof(effectiveLen))) { -+ iRet = -EFAULT; -+ WMT_ERR_FUNC("copy_from_user failed at %d\n", __LINE__); -+ break; -+ } -+ if (effectiveLen > sizeof(gLpbkBuf)) { -+ iRet = -EFAULT; -+ WMT_ERR_FUNC("length is too long\n"); -+ break; -+ } -+ WMT_DBG_FUNC("len = %d\n", effectiveLen); -+ -+ pOp = wmt_lib_get_free_op(); -+ if (!pOp) { -+ WMT_WARN_FUNC("get_free_lxop fail\n"); -+ iRet = -EFAULT; -+ break; -+ } -+ u4Wait = 2000; -+ if (copy_from_user(&gLpbkBuf[0], (void *)arg + sizeof(unsigned long), effectiveLen)) { -+ WMT_ERR_FUNC("copy_from_user failed at %d\n", __LINE__); -+ iRet = -EFAULT; -+ break; -+ } -+ pSignal = &pOp->signal; -+ pOp->op.opId = WMT_OPID_LPBK; -+ pOp->op.au4OpData[0] = effectiveLen; /* packet length */ -+ pOp->op.au4OpData[1] = (SIZE_T) &gLpbkBuf[0]; /* packet buffer pointer */ -+ memcpy(&gLpbkBufLog, &gLpbkBuf[((effectiveLen >= 4) ? effectiveLen - 4 : 0)], 4); -+ pSignal->timeoutValue = MAX_EACH_WMT_CMD; -+ WMT_INFO_FUNC("OPID(%d) type(%d) start\n", pOp->op.opId, pOp->op.au4OpData[0]); -+ if (DISABLE_PSM_MONITOR()) { -+ WMT_ERR_FUNC("wake up failed,OPID(%d) type(%d) abort\n", -+ pOp->op.opId, pOp->op.au4OpData[0]); -+ wmt_lib_put_op_to_free_queue(pOp); -+ return -1; -+ } -+ -+ bRet = wmt_lib_put_act_op(pOp); -+ ENABLE_PSM_MONITOR(); -+ if (MTK_WCN_BOOL_FALSE == bRet) { -+ WMT_WARN_FUNC("OPID(%d) type(%d) buf tail(0x%08x) fail\n", -+ pOp->op.opId, pOp->op.au4OpData[0], gLpbkBufLog); -+ iRet = -1; -+ break; -+ } -+ WMT_INFO_FUNC("OPID(%d) length(%d) ok\n", pOp->op.opId, pOp->op.au4OpData[0]); -+ iRet = pOp->op.au4OpData[0]; -+ if (copy_to_user((void *)arg + sizeof(SIZE_T) + sizeof(UINT8[2048]), gLpbkBuf, iRet)) { -+ iRet = -EFAULT; -+ break; -+ } -+ -+ } while (0); -+ -+ break; -+ -+ case WMT_IOCTL_ADIE_LPBK_TEST: -+ do { -+ P_OSAL_OP pOp; -+ MTK_WCN_BOOL bRet; -+ P_OSAL_SIGNAL pSignal = NULL; -+ -+ pOp = wmt_lib_get_free_op(); -+ if (!pOp) { -+ WMT_WARN_FUNC("get_free_lxop fail\n"); -+ iRet = -EFAULT; -+ break; -+ } -+ -+ pSignal = &pOp->signal; -+ pOp->op.opId = WMT_OPID_ADIE_LPBK_TEST; -+ pOp->op.au4OpData[0] = 0; -+ pOp->op.au4OpData[1] = (SIZE_T) &gLpbkBuf[0]; -+ pSignal->timeoutValue = MAX_EACH_WMT_CMD; -+ WMT_INFO_FUNC("OPID(%d) start\n", pOp->op.opId); -+ if (DISABLE_PSM_MONITOR()) { -+ WMT_ERR_FUNC("wake up failed,OPID(%d)abort\n", pOp->op.opId); -+ wmt_lib_put_op_to_free_queue(pOp); -+ return -1; -+ } -+ -+ bRet = wmt_lib_put_act_op(pOp); -+ ENABLE_PSM_MONITOR(); -+ if (MTK_WCN_BOOL_FALSE == bRet) { -+ WMT_WARN_FUNC("OPID(%d) fail\n", pOp->op.opId); -+ iRet = -1; -+ break; -+ } -+ WMT_INFO_FUNC("OPID(%d) length(%d) ok\n", pOp->op.opId, pOp->op.au4OpData[0]); -+ iRet = pOp->op.au4OpData[0]; -+ if (copy_to_user((void *)arg + sizeof(SIZE_T), gLpbkBuf, iRet)) { -+ iRet = -EFAULT; -+ break; -+ } -+ -+ } while (0); -+ -+ break; -+ -+ case 10: -+ { -+ pBuffer = kmalloc(NAME_MAX + 1, GFP_KERNEL); -+ if (!pBuffer) { -+ WMT_ERR_FUNC("pBuffer kmalloc memory fail\n"); -+ return 0; -+ } -+ wmt_lib_host_awake_get(); -+ mtk_wcn_stp_coredump_start_ctrl(1); -+ osal_strcpy(pBuffer, "MT662x f/w coredump start-"); -+ if (copy_from_user -+ (pBuffer + osal_strlen(pBuffer), (void *)arg, NAME_MAX - osal_strlen(pBuffer))) { -+ /* osal_strcpy(pBuffer, "MT662x f/w assert core dump start"); */ -+ WMT_ERR_FUNC("copy assert string failed\n"); -+ } -+ pBuffer[NAME_MAX] = '\0'; -+ osal_dbg_assert_aee(pBuffer, pBuffer); -+ kfree(pBuffer); -+ } -+ break; -+ case 11: -+ { -+ osal_dbg_assert_aee("MT662x f/w coredump end", "MT662x firmware coredump ends"); -+ wmt_lib_host_awake_put(); -+ } -+ break; -+ -+ case WMT_IOCTL_GET_CHIP_INFO: -+ { -+ if (0 == arg) -+ return wmt_lib_get_icinfo(WMTCHIN_CHIPID); -+ else if (1 == arg) -+ return wmt_lib_get_icinfo(WMTCHIN_HWVER); -+ else if (2 == arg) -+ return wmt_lib_get_icinfo(WMTCHIN_FWVER); -+ -+ } -+ break; -+ -+ case WMT_IOCTL_SET_LAUNCHER_KILL:{ -+ if (1 == arg) { -+ WMT_INFO_FUNC("launcher may be killed,block abnormal stp tx.\n"); -+ wmt_lib_set_stp_wmt_last_close(1); -+ } else { -+ wmt_lib_set_stp_wmt_last_close(0); -+ } -+ -+ } -+ break; -+ -+ case WMT_IOCTL_SET_PATCH_NUM:{ -+ pAtchNum = arg; -+ WMT_DBG_FUNC(" get patch num from launcher = %d\n", pAtchNum); -+ wmt_lib_set_patch_num(pAtchNum); -+ pPatchInfo = kcalloc(pAtchNum, sizeof(WMT_PATCH_INFO), GFP_ATOMIC); -+ if (!pPatchInfo) { -+ WMT_ERR_FUNC("allocate memory fail!\n"); -+ break; -+ } -+ } -+ break; -+ -+ case WMT_IOCTL_SET_PATCH_INFO:{ -+ WMT_PATCH_INFO wMtPatchInfo; -+ P_WMT_PATCH_INFO pTemp = NULL; -+ UINT32 dWloadSeq; -+ static UINT32 counter; -+ -+ if (!pPatchInfo) { -+ WMT_ERR_FUNC("NULL patch info pointer\n"); -+ break; -+ } -+ -+ if (copy_from_user(&wMtPatchInfo, (void *)arg, sizeof(WMT_PATCH_INFO))) { -+ WMT_ERR_FUNC("copy_from_user failed at %d\n", __LINE__); -+ iRet = -EFAULT; -+ break; -+ } -+ -+ dWloadSeq = wMtPatchInfo.dowloadSeq; -+ WMT_DBG_FUNC( -+ "patch dl seq %d,name %s,address info 0x%02x,0x%02x,0x%02x,0x%02x\n", -+ dWloadSeq, wMtPatchInfo.patchName, -+ wMtPatchInfo.addRess[0], -+ wMtPatchInfo.addRess[1], -+ wMtPatchInfo.addRess[2], -+ wMtPatchInfo.addRess[3]); -+ osal_memcpy(pPatchInfo + dWloadSeq - 1, &wMtPatchInfo, sizeof(WMT_PATCH_INFO)); -+ pTemp = pPatchInfo + dWloadSeq - 1; -+ if (++counter == pAtchNum) { -+ wmt_lib_set_patch_info(pPatchInfo); -+ counter = 0; -+ } -+ } -+ break; -+ -+ case WMT_IOCTL_WMT_COREDUMP_CTRL: -+ mtk_wcn_stp_coredump_flag_ctrl(arg); -+ break; -+ case WMT_IOCTL_WMT_QUERY_CHIPID: -+ { -+ iRet = mtk_wcn_wmt_chipid_query(); -+ WMT_WARN_FUNC("chipid = 0x%x\n", iRet); -+ } -+ break; -+ case WMT_IOCTL_SEND_BGW_DS_CMD: -+ do { -+ P_OSAL_OP pOp; -+ MTK_WCN_BOOL bRet; -+ UINT8 desense_buf[14] = { 0 }; -+ UINT32 effectiveLen = 14; -+ P_OSAL_SIGNAL pSignal = NULL; -+ -+ pOp = wmt_lib_get_free_op(); -+ if (!pOp) { -+ WMT_WARN_FUNC("get_free_lxop fail\n"); -+ iRet = -EFAULT; -+ break; -+ } -+ if (copy_from_user(&desense_buf[0], (void *)arg, effectiveLen)) { -+ WMT_ERR_FUNC("copy_from_user failed at %d\n", __LINE__); -+ iRet = -EFAULT; -+ break; -+ } -+ pSignal = &pOp->signal; -+ pOp->op.opId = WMT_OPID_BGW_DS; -+ pOp->op.au4OpData[0] = effectiveLen; /* packet length */ -+ pOp->op.au4OpData[1] = (SIZE_T) &desense_buf[0]; /* packet buffer pointer */ -+ pSignal->timeoutValue = MAX_EACH_WMT_CMD; -+ WMT_INFO_FUNC("OPID(%d) start\n", pOp->op.opId); -+ if (DISABLE_PSM_MONITOR()) { -+ WMT_ERR_FUNC("wake up failed,opid(%d) abort\n", pOp->op.opId); -+ wmt_lib_put_op_to_free_queue(pOp); -+ return -1; -+ } -+ -+ bRet = wmt_lib_put_act_op(pOp); -+ ENABLE_PSM_MONITOR(); -+ if (MTK_WCN_BOOL_FALSE == bRet) { -+ WMT_WARN_FUNC("OPID(%d) fail\n", pOp->op.opId); -+ iRet = -1; -+ break; -+ } -+ WMT_INFO_FUNC("OPID(%d) length(%d) ok\n", pOp->op.opId, pOp->op.au4OpData[0]); -+ iRet = pOp->op.au4OpData[0]; -+ -+ } while (0); -+ -+ break; -+ case WMT_IOCTL_FW_DBGLOG_CTRL: -+ { -+ iRet = wmt_plat_set_dbg_mode(arg); -+ if (iRet == 0) -+ wmt_dbg_fwinfor_from_emi(0, 1, 0); -+ } -+ break; -+ case WMT_IOCTL_DYNAMIC_DUMP_CTRL: -+ { -+ UINT32 i = 0, j = 0, k = 0; -+ UINT8 *pBuf = NULL; -+ UINT32 int_buf[10]; -+ char Buffer[10][11]; -+ -+ pBuf = kmalloc(DYNAMIC_DUMP_BUF + 1, GFP_KERNEL); -+ if (!pBuf) { -+ WMT_ERR_FUNC("pBuf kmalloc memory fail\n"); -+ return 0; -+ } -+ if (copy_from_user(pBuf, (void *)arg, DYNAMIC_DUMP_BUF)) { -+ iRet = -EFAULT; -+ kfree(pBuf); -+ break; -+ } -+ pBuf[DYNAMIC_DUMP_BUF] = '\0'; -+ WMT_INFO_FUNC("get dynamic dump data from property(%s)\n", pBuf); -+ memset(Buffer, 0, 10*11); -+ for (i = 0; i < DYNAMIC_DUMP_BUF; i++) { -+ if (pBuf[i] == '/') { -+ k = 0; -+ j++; -+ } else { -+ Buffer[j][k] = pBuf[i]; -+ k++; -+ } -+ } -+ for (j = 0; j < 10; j++) { -+ iRet = kstrtou32(Buffer[j], 0, &int_buf[j]); -+ if (iRet) { -+ WMT_ERR_FUNC("string convert fail(%d)\n", iRet); -+ break; -+ } -+ WMT_INFO_FUNC("dynamic dump data buf[%d]:(0x%x)\n", j, int_buf[j]); -+ } -+ wmt_plat_set_dynamic_dumpmem(int_buf); -+ kfree(pBuf); -+ } -+ break; -+ default: -+ iRet = -EINVAL; -+ WMT_WARN_FUNC("unknown cmd (%d)\n", cmd); -+ break; -+ } -+ -+ return iRet; -+} -+#ifdef CONFIG_COMPAT -+long WMT_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) -+{ -+ long ret; -+ WMT_INFO_FUNC("cmd[0x%x]\n", cmd); -+ switch (cmd) { -+ case COMPAT_WMT_IOCTL_SET_PATCH_NAME: -+ ret = WMT_unlocked_ioctl(filp, WMT_IOCTL_SET_PATCH_NAME, (unsigned long)compat_ptr(arg)); -+ break; -+ case COMPAT_WMT_IOCTL_LPBK_TEST: -+ ret = WMT_unlocked_ioctl(filp, WMT_IOCTL_LPBK_TEST, (unsigned long)compat_ptr(arg)); -+ break; -+ case COMPAT_WMT_IOCTL_SET_PATCH_INFO: -+ ret = WMT_unlocked_ioctl(filp, WMT_IOCTL_SET_PATCH_INFO, (unsigned long)compat_ptr(arg)); -+ break; -+ case COMPAT_WMT_IOCTL_PORT_NAME: -+ ret = WMT_unlocked_ioctl(filp, WMT_IOCTL_PORT_NAME, (unsigned long)compat_ptr(arg)); -+ break; -+ case COMPAT_WMT_IOCTL_WMT_CFG_NAME: -+ ret = WMT_unlocked_ioctl(filp, WMT_IOCTL_WMT_CFG_NAME, (unsigned long)compat_ptr(arg)); -+ break; -+ case COMPAT_WMT_IOCTL_SEND_BGW_DS_CMD: -+ ret = WMT_unlocked_ioctl(filp, WMT_IOCTL_SEND_BGW_DS_CMD, (unsigned long)compat_ptr(arg)); -+ break; -+ default: { -+ ret = WMT_unlocked_ioctl(filp, cmd, arg); -+ break; -+ } -+ } -+ return ret; -+} -+#endif -+static int WMT_open(struct inode *inode, struct file *file) -+{ -+ long ret; -+ -+ WMT_INFO_FUNC("major %d minor %d (pid %d)\n", imajor(inode), iminor(inode), current->pid); -+ ret = wait_event_timeout(gWmtInitWq, gWmtInitDone != 0, msecs_to_jiffies(WMT_DEV_INIT_TO_MS)); -+ if (!ret) { -+ WMT_WARN_FUNC("wait_event_timeout (%d)ms,(%d)jiffies,return -EIO\n", -+ WMT_DEV_INIT_TO_MS, msecs_to_jiffies(WMT_DEV_INIT_TO_MS)); -+ return -EIO; -+ } -+ -+ if (atomic_inc_return(&gWmtRefCnt) == 1) -+ WMT_INFO_FUNC("1st call\n"); -+ -+ return 0; -+} -+ -+static int WMT_close(struct inode *inode, struct file *file) -+{ -+ WMT_INFO_FUNC("major %d minor %d (pid %d)\n", imajor(inode), iminor(inode), current->pid); -+ -+ if (atomic_dec_return(&gWmtRefCnt) == 0) -+ WMT_INFO_FUNC("last call\n"); -+ -+ return 0; -+} -+ -+const struct file_operations gWmtFops = { -+ .open = WMT_open, -+ .release = WMT_close, -+ .read = WMT_read, -+ .write = WMT_write, -+/* .ioctl = WMT_ioctl, */ -+ .unlocked_ioctl = WMT_unlocked_ioctl, -+#ifdef CONFIG_COMPAT -+ .compat_ioctl = WMT_compat_ioctl, -+#endif -+ .poll = WMT_poll, -+}; -+ -+void wmt_dev_bgw_desense_init(VOID) -+{ -+ bgw_init_socket(); -+} -+ -+void wmt_dev_bgw_desense_deinit(VOID) -+{ -+ bgw_destroy_netlink_kernel(); -+} -+ -+void wmt_dev_send_cmd_to_daemon(UINT32 cmd) -+{ -+ send_command_to_daemon(cmd); -+} -+ -+static int WMT_init(void) -+{ -+ dev_t devID = MKDEV(gWmtMajor, 0); -+ INT32 cdevErr = -1; -+ INT32 ret = -1; -+ -+ WMT_INFO_FUNC("WMT Version= %s DATE=%s\n", MTK_WMT_VERSION, MTK_WMT_DATE); -+ /* Prepare a UINT8 device */ -+ /*static allocate chrdev */ -+ gWmtInitDone = 0; -+ init_waitqueue_head((wait_queue_head_t *) &gWmtInitWq); -+ stp_drv_init(); -+ -+ ret = register_chrdev_region(devID, WMT_DEV_NUM, WMT_DRIVER_NAME); -+ if (ret) { -+ WMT_ERR_FUNC("fail to register chrdev\n"); -+ return ret; -+ } -+ cdev_init(&gWmtCdev, &gWmtFops); -+ gWmtCdev.owner = THIS_MODULE; -+ cdevErr = cdev_add(&gWmtCdev, devID, WMT_DEV_NUM); -+ if (cdevErr) { -+ WMT_ERR_FUNC("cdev_add() fails (%d)\n", cdevErr); -+ goto error; -+ } -+ WMT_INFO_FUNC("driver(major %d) installed\n", gWmtMajor); -+#if WMT_CREATE_NODE_DYNAMIC -+ wmt_class = class_create(THIS_MODULE, "stpwmt"); -+ if (IS_ERR(wmt_class)) -+ goto error; -+ wmt_dev = device_create(wmt_class, NULL, devID, NULL, "stpwmt"); -+ if (IS_ERR(wmt_dev)) -+ goto error; -+#endif -+ -+#if 0 -+ pWmtDevCtx = wmt_drv_create(); -+ if (!pWmtDevCtx) { -+ WMT_ERR_FUNC("wmt_drv_create() fails\n"); -+ goto error; -+ } -+ ret = wmt_drv_init(pWmtDevCtx); -+ if (ret) { -+ WMT_ERR_FUNC("wmt_drv_init() fails (%d)\n", ret); -+ goto error; -+ } -+ WMT_INFO_FUNC("stp_btmcb_reg\n"); -+ wmt_cdev_btmcb_reg(); -+ ret = wmt_drv_start(pWmtDevCtx); -+ if (ret) { -+ WMT_ERR_FUNC("wmt_drv_start() fails (%d)\n", ret); -+ goto error; -+ } -+#endif -+ ret = wmt_lib_init(); -+ if (ret) { -+ WMT_ERR_FUNC("wmt_lib_init() fails (%d)\n", ret); -+ goto error; -+ } -+#if CFG_WMT_DBG_SUPPORT -+ wmt_dev_dbg_setup(); -+#endif -+ -+#if CFG_WMT_PROC_FOR_AEE -+ wmt_dev_proc_for_aee_setup(); -+#endif -+ -+ WMT_INFO_FUNC("wmt_dev register thermal cb\n"); -+ wmt_lib_register_thermal_ctrl_cb(wmt_dev_tm_temp_query); -+ wmt_dev_bgw_desense_init(); -+ gWmtInitDone = 1; -+ wake_up(&gWmtInitWq); -+ osal_sleepable_lock_init(&g_es_lr_lock); -+ INIT_WORK(&gPwrOnOffWork, wmt_pwr_on_off_handler); -+#ifdef CONFIG_EARLYSUSPEND -+ register_early_suspend(&wmt_early_suspend_handler); -+ WMT_INFO_FUNC("register_early_suspend finished\n"); -+#else -+ wmt_fb_notifier.notifier_call = wmt_fb_notifier_callback; -+ ret = fb_register_client(&wmt_fb_notifier); -+ if (ret) -+ WMT_ERR_FUNC("wmt register fb_notifier failed! ret(%d)\n", ret); -+ else -+ WMT_INFO_FUNC("wmt register fb_notifier OK!\n"); -+#endif -+ WMT_INFO_FUNC("success\n"); -+ return 0; -+ -+error: -+ wmt_lib_deinit(); -+#if CFG_WMT_DBG_SUPPORT -+ wmt_dev_dbg_remove(); -+#endif -+#if WMT_CREATE_NODE_DYNAMIC -+ if (!(IS_ERR(wmt_dev))) -+ device_destroy(wmt_class, devID); -+ if (!(IS_ERR(wmt_class))) { -+ class_destroy(wmt_class); -+ wmt_class = NULL; -+ } -+#endif -+ -+ if (cdevErr == 0) -+ cdev_del(&gWmtCdev); -+ -+ if (ret == 0) { -+ unregister_chrdev_region(devID, WMT_DEV_NUM); -+ gWmtMajor = -1; -+ } -+ -+ WMT_ERR_FUNC("fail\n"); -+ -+ return -1; -+} -+ -+static void WMT_exit(void) -+{ -+ dev_t dev = MKDEV(gWmtMajor, 0); -+ -+ osal_sleepable_lock_deinit(&g_es_lr_lock); -+#ifdef CONFIG_EARLYSUSPEND -+ unregister_early_suspend(&wmt_early_suspend_handler); -+ WMT_INFO_FUNC("unregister_early_suspend finished\n"); -+#else -+ fb_unregister_client(&wmt_fb_notifier); -+#endif -+ -+ wmt_dev_bgw_desense_deinit(); -+ -+ wmt_lib_register_thermal_ctrl_cb(NULL); -+ -+ wmt_lib_deinit(); -+ -+#if CFG_WMT_DBG_SUPPORT -+ wmt_dev_dbg_remove(); -+#endif -+ -+#if CFG_WMT_PROC_FOR_AEE -+ wmt_dev_proc_for_aee_remove(); -+#endif -+#if WMT_CREATE_NODE_DYNAMIC -+ if (wmt_dev) { -+ device_destroy(wmt_class, dev); -+ wmt_dev = NULL; -+ } -+ if (wmt_class) { -+ class_destroy(wmt_class); -+ wmt_class = NULL; -+ } -+#endif -+ cdev_del(&gWmtCdev); -+ unregister_chrdev_region(dev, WMT_DEV_NUM); -+ gWmtMajor = -1; -+ -+ stp_drv_exit(); -+ -+ WMT_INFO_FUNC("done\n"); -+} -+ -+#ifdef MTK_WCN_REMOVE_KERNEL_MODULE -+ -+int mtk_wcn_soc_common_drv_init(void) -+{ -+ return WMT_init(); -+ -+} -+EXPORT_SYMBOL(mtk_wcn_soc_common_drv_init); -+void mtk_wcn_soc_common_drv_exit(void) -+{ -+ return WMT_exit(); -+} -+EXPORT_SYMBOL(mtk_wcn_soc_common_drv_exit); -+ -+#else -+module_init(WMT_init); -+module_exit(WMT_exit); -+#endif -+MODULE_LICENSE("GPL"); -+MODULE_AUTHOR("MediaTek Inc WCN"); -+MODULE_DESCRIPTION("MTK WCN combo driver for WMT function"); -+ -+module_param(gWmtMajor, uint, 0); -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/wmt_exp.c b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/wmt_exp.c -new file mode 100644 -index 000000000000..9f2192d9a3e5 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/wmt_exp.c -@@ -0,0 +1,610 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -+ -+/*! \file -+ \brief Declaration of library functions -+ -+ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+#ifdef DFT_TAG -+#undef DFT_TAG -+#endif -+#define DFT_TAG "[WMT-EXP]" -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "osal_typedef.h" -+ -+#include -+#include -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+wmt_wlan_probe_cb mtk_wcn_wlan_probe = NULL; -+wmt_wlan_remove_cb mtk_wcn_wlan_remove = NULL; -+wmt_wlan_bus_cnt_get_cb mtk_wcn_wlan_bus_tx_cnt = NULL; -+wmt_wlan_bus_cnt_clr_cb mtk_wcn_wlan_bus_tx_cnt_clr = NULL; -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+OSAL_BIT_OP_VAR gBtWifiGpsState; -+OSAL_BIT_OP_VAR gGpsFmState; -+UINT32 gWifiProbed = 0; -+UINT32 gWmtDbgLvl = WMT_LOG_DBG; -+MTK_WCN_BOOL g_pwr_off_flag = MTK_WCN_BOOL_TRUE; -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+static MTK_WCN_BOOL mtk_wcn_wmt_func_ctrl(ENUM_WMTDRV_TYPE_T type, ENUM_WMT_OPID_T opId); -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+static MTK_WCN_BOOL mtk_wcn_wmt_func_ctrl(ENUM_WMTDRV_TYPE_T type, ENUM_WMT_OPID_T opId) -+{ -+ P_OSAL_OP pOp; -+ MTK_WCN_BOOL bRet; -+ P_OSAL_SIGNAL pSignal; -+ -+ pOp = wmt_lib_get_free_op(); -+ if (!pOp) { -+ WMT_WARN_FUNC("get_free_lxop fail\n"); -+ return MTK_WCN_BOOL_FALSE; -+ } -+ -+ pSignal = &pOp->signal; -+ -+ pOp->op.opId = opId; -+ pOp->op.au4OpData[0] = type; -+ if (WMTDRV_TYPE_WIFI == type) -+ pSignal->timeoutValue = 4000; -+ /*donot block system server/init/netd from longer than 5s, in case of ANR happens*/ -+ else -+ pSignal->timeoutValue = (WMT_OPID_FUNC_ON == pOp->op.opId) ? MAX_FUNC_ON_TIME : MAX_FUNC_OFF_TIME; -+ -+ WMT_INFO_FUNC("OPID(%d) type(%d) start\n", pOp->op.opId, pOp->op.au4OpData[0]); -+ -+ /*do not check return value, we will do this either way */ -+ wmt_lib_host_awake_get(); -+ /*wake up chip first */ -+ if (DISABLE_PSM_MONITOR()) { -+ WMT_ERR_FUNC("wake up failed,OPID(%d) type(%d) abort\n", pOp->op.opId, pOp->op.au4OpData[0]); -+ wmt_lib_put_op_to_free_queue(pOp); -+ wmt_lib_host_awake_put(); -+ return MTK_WCN_BOOL_FALSE; -+ } -+ -+ bRet = wmt_lib_put_act_op(pOp); -+ ENABLE_PSM_MONITOR(); -+ wmt_lib_host_awake_put(); -+ -+ if (MTK_WCN_BOOL_FALSE == bRet) -+ WMT_WARN_FUNC("OPID(%d) type(%d) fail\n", pOp->op.opId, pOp->op.au4OpData[0]); -+ else -+ WMT_WARN_FUNC("OPID(%d) type(%d) ok\n", pOp->op.opId, pOp->op.au4OpData[0]); -+ -+ return bRet; -+} -+ -+#if WMT_EXP_HID_API_EXPORT -+MTK_WCN_BOOL _mtk_wcn_wmt_func_off(ENUM_WMTDRV_TYPE_T type) -+#else -+MTK_WCN_BOOL mtk_wcn_wmt_func_off(ENUM_WMTDRV_TYPE_T type) -+#endif -+{ -+ MTK_WCN_BOOL ret; -+ -+ if (type == WMTDRV_TYPE_BT) -+ osal_printtimeofday("############ BT OFF ====>"); -+ -+ ret = mtk_wcn_wmt_func_ctrl(type, WMT_OPID_FUNC_OFF); -+ -+ if (type == WMTDRV_TYPE_BT) -+ osal_printtimeofday("############ BT OFF <===="); -+ -+ return ret; -+} -+#if !WMT_EXP_HID_API_EXPORT -+EXPORT_SYMBOL(mtk_wcn_wmt_func_off); -+#endif -+ -+#if WMT_EXP_HID_API_EXPORT -+MTK_WCN_BOOL _mtk_wcn_wmt_func_on(ENUM_WMTDRV_TYPE_T type) -+#else -+MTK_WCN_BOOL mtk_wcn_wmt_func_on(ENUM_WMTDRV_TYPE_T type) -+#endif -+{ -+ MTK_WCN_BOOL ret; -+ -+ if (type == WMTDRV_TYPE_BT) -+ osal_printtimeofday("############ BT ON ====>"); -+ -+ ret = mtk_wcn_wmt_func_ctrl(type, WMT_OPID_FUNC_ON); -+ -+ if (type == WMTDRV_TYPE_BT) -+ osal_printtimeofday(" ############BT ON <===="); -+ -+ return ret; -+} -+#if !WMT_EXP_HID_API_EXPORT -+EXPORT_SYMBOL(mtk_wcn_wmt_func_on); -+#endif -+ -+VOID mtk_wcn_wmt_func_ctrl_for_plat(UINT32 on, ENUM_WMTDRV_TYPE_T type) -+{ -+ if (on) -+ mtk_wcn_wmt_func_on(type); -+ else -+ mtk_wcn_wmt_func_off(type); -+} -+ -+/* -+return value: -+enable/disable thermal sensor function: true(1)/false(0) -+read thermal sensor function:thermal value -+ -+*/ -+#if WMT_EXP_HID_API_EXPORT -+INT8 _mtk_wcn_wmt_therm_ctrl(ENUM_WMTTHERM_TYPE_T eType) -+#else -+INT8 mtk_wcn_wmt_therm_ctrl(ENUM_WMTTHERM_TYPE_T eType) -+#endif -+{ -+ P_OSAL_OP pOp; -+ P_WMT_OP pOpData; -+ MTK_WCN_BOOL bRet; -+ P_OSAL_SIGNAL pSignal; -+ -+ /*parameter validation check */ -+ if (WMTTHERM_MAX < eType || WMTTHERM_ENABLE > eType) { -+ WMT_ERR_FUNC("invalid thermal control command (%d)\n", eType); -+ return MTK_WCN_BOOL_FALSE; -+ } -+ -+ /*check if chip support thermal control function or not */ -+ bRet = wmt_lib_is_therm_ctrl_support(); -+ if (MTK_WCN_BOOL_FALSE == bRet) { -+ WMT_ERR_FUNC("thermal ctrl function not supported\n"); -+ return MTK_WCN_BOOL_FALSE; -+ } -+ -+ pOp = wmt_lib_get_free_op(); -+ if (!pOp) { -+ WMT_WARN_FUNC("get_free_lxop fail\n"); -+ return MTK_WCN_BOOL_FALSE; -+ } -+ -+ pSignal = &pOp->signal; -+ pOpData = &pOp->op; -+ pOpData->opId = WMT_OPID_THERM_CTRL; -+ /*parameter fill */ -+ pOpData->au4OpData[0] = eType; -+ pSignal->timeoutValue = MAX_EACH_WMT_CMD; -+ -+ WMT_INFO_FUNC("OPID(%d) type(%d) start\n", pOp->op.opId, pOp->op.au4OpData[0]); -+ -+ if (DISABLE_PSM_MONITOR()) { -+ WMT_ERR_FUNC("wake up failed,OPID(%d) type(%d) abort!\n", pOp->op.opId, pOp->op.au4OpData[0]); -+ wmt_lib_put_op_to_free_queue(pOp); -+ return -1; -+ } -+ -+ bRet = wmt_lib_put_act_op(pOp); -+ ENABLE_PSM_MONITOR(); -+ -+ if (MTK_WCN_BOOL_FALSE == bRet) { -+ WMT_WARN_FUNC("OPID(%d) type(%d) fail\n\n", pOpData->opId, pOpData->au4OpData[0]); -+ /*0xFF means read error occurs */ -+ /*will return to function driver */ -+ pOpData->au4OpData[1] = (eType == WMTTHERM_READ) ? 0xFF : MTK_WCN_BOOL_FALSE; -+ } else { -+ WMT_INFO_FUNC("OPID(%d) type(%d) return(%d) ok\n\n", -+ pOpData->opId, pOpData->au4OpData[0], pOpData->au4OpData[1]); -+ } -+ /*return value will be put to lxop->op.au4OpData[1] */ -+ WMT_DBG_FUNC("therm ctrl type(%d), iRet(0x%08x)\n", eType, pOpData->au4OpData[1]); -+ return (INT8) pOpData->au4OpData[1]; -+} -+#if !WMT_EXP_HID_API_EXPORT -+EXPORT_SYMBOL(mtk_wcn_wmt_therm_ctrl); -+#endif -+ -+#if WMT_EXP_HID_API_EXPORT -+ENUM_WMTHWVER_TYPE_T _mtk_wcn_wmt_hwver_get(VOID) -+#else -+ENUM_WMTHWVER_TYPE_T mtk_wcn_wmt_hwver_get(VOID) -+#endif -+{ -+ /* TODO: [ChangeFeature][GeorgeKuo] Reconsider usage of this type */ -+ /* TODO: how do we extend for new chip and newer revision? */ -+ /* TODO: This way is hard to extend */ -+ return wmt_lib_get_icinfo(WMTCHIN_MAPPINGHWVER); -+} -+#if !WMT_EXP_HID_API_EXPORT -+EXPORT_SYMBOL(mtk_wcn_wmt_hwver_get); -+#endif -+ -+#if WMT_EXP_HID_API_EXPORT -+MTK_WCN_BOOL _mtk_wcn_wmt_dsns_ctrl(ENUM_WMTDSNS_TYPE_T eType) -+#else -+MTK_WCN_BOOL mtk_wcn_wmt_dsns_ctrl(ENUM_WMTDSNS_TYPE_T eType) -+#endif -+{ -+ P_OSAL_OP pOp; -+ P_WMT_OP pOpData; -+ MTK_WCN_BOOL bRet; -+ P_OSAL_SIGNAL pSignal; -+ -+ if (WMTDSNS_MAX <= eType) { -+ WMT_ERR_FUNC("invalid desense control command (%d)\n", eType); -+ return MTK_WCN_BOOL_FALSE; -+ } -+ -+ /*check if chip support thermal control function or not */ -+ bRet = wmt_lib_is_dsns_ctrl_support(); -+ if (MTK_WCN_BOOL_FALSE == bRet) { -+ WMT_ERR_FUNC("thermal ctrl function not supported\n"); -+ return MTK_WCN_BOOL_FALSE; -+ } -+ -+ pOp = wmt_lib_get_free_op(); -+ if (!pOp) { -+ WMT_WARN_FUNC("get_free_lxop fail\n"); -+ return MTK_WCN_BOOL_FALSE; -+ } -+ -+ pSignal = &pOp->signal; -+ pOpData = &pOp->op; -+ pOpData->opId = WMT_OPID_DSNS; -+ pSignal->timeoutValue = MAX_EACH_WMT_CMD; -+ /*parameter fill */ -+ if ((WMTDSNS_FM_DISABLE <= eType) && (WMTDSNS_FM_GPS_ENABLE >= eType)) { -+ pOpData->au4OpData[0] = WMTDRV_TYPE_FM; -+ pOpData->au4OpData[1] = eType; -+ } -+ -+ WMT_INFO_FUNC("OPID(%d) type(%d) start\n", pOp->op.opId, pOp->op.au4OpData[0]); -+ -+ if (DISABLE_PSM_MONITOR()) { -+ WMT_ERR_FUNC("wake up failed,OPID(%d) type(%d) abort\n", pOp->op.opId, pOp->op.au4OpData[0]); -+ wmt_lib_put_op_to_free_queue(pOp); -+ return MTK_WCN_BOOL_FALSE; -+ } -+ -+ bRet = wmt_lib_put_act_op(pOp); -+ ENABLE_PSM_MONITOR(); -+ -+ if (MTK_WCN_BOOL_FALSE == bRet) -+ WMT_WARN_FUNC("OPID(%d) type(%d) fail\n\n", pOpData->opId, pOpData->au4OpData[0]); -+ else -+ WMT_INFO_FUNC("OPID(%d) type(%d) ok\n\n", pOpData->opId, pOpData->au4OpData[0]); -+ -+ return bRet; -+} -+#if !WMT_EXP_HID_API_EXPORT -+EXPORT_SYMBOL(mtk_wcn_wmt_dsns_ctrl); -+#endif -+ -+#if WMT_EXP_HID_API_EXPORT -+INT32 _mtk_wcn_wmt_msgcb_reg(ENUM_WMTDRV_TYPE_T eType, PF_WMT_CB pCb) -+#else -+INT32 mtk_wcn_wmt_msgcb_reg(ENUM_WMTDRV_TYPE_T eType, PF_WMT_CB pCb) -+#endif -+{ -+ return (INT32) wmt_lib_msgcb_reg(eType, pCb); -+} -+#if !WMT_EXP_HID_API_EXPORT -+EXPORT_SYMBOL(mtk_wcn_wmt_msgcb_reg); -+#endif -+ -+#if WMT_EXP_HID_API_EXPORT -+INT32 _mtk_wcn_wmt_msgcb_unreg(ENUM_WMTDRV_TYPE_T eType) -+#else -+INT32 mtk_wcn_wmt_msgcb_unreg(ENUM_WMTDRV_TYPE_T eType) -+#endif -+{ -+ return (INT32) wmt_lib_msgcb_unreg(eType); -+} -+#if !WMT_EXP_HID_API_EXPORT -+EXPORT_SYMBOL(mtk_wcn_wmt_msgcb_unreg); -+#endif -+ -+#if WMT_EXP_HID_API_EXPORT -+INT32 _mtk_wcn_stp_wmt_sdio_op_reg(PF_WMT_SDIO_PSOP own_cb) -+#else -+INT32 mtk_wcn_stp_wmt_sdio_op_reg(PF_WMT_SDIO_PSOP own_cb) -+#endif -+{ -+ wmt_lib_ps_set_sdio_psop(own_cb); -+ return 0; -+} -+#if !WMT_EXP_HID_API_EXPORT -+EXPORT_SYMBOL(mtk_wcn_stp_wmt_sdio_op_reg); -+#endif -+ -+#if WMT_EXP_HID_API_EXPORT -+INT32 _mtk_wcn_stp_wmt_sdio_host_awake(VOID) -+#else -+INT32 mtk_wcn_stp_wmt_sdio_host_awake(VOID) -+#endif -+{ -+ wmt_lib_ps_irq_cb(); -+ return 0; -+} -+#if !WMT_EXP_HID_API_EXPORT -+EXPORT_SYMBOL(mtk_wcn_stp_wmt_sdio_host_awake); -+#endif -+ -+#if WMT_EXP_HID_API_EXPORT -+MTK_WCN_BOOL _mtk_wcn_wmt_assert(ENUM_WMTDRV_TYPE_T type, UINT32 reason) -+#else -+MTK_WCN_BOOL mtk_wcn_wmt_assert(ENUM_WMTDRV_TYPE_T type, UINT32 reason) -+#endif -+{ -+ P_OSAL_OP pOp = NULL; -+ MTK_WCN_BOOL bRet = MTK_WCN_BOOL_FALSE; -+ P_OSAL_SIGNAL pSignal; -+ -+ pOp = wmt_lib_get_free_op(); -+ if (!pOp) { -+ WMT_WARN_FUNC("get_free_lxop fail\n"); -+ return MTK_WCN_BOOL_FALSE; -+ } -+ -+ wmt_lib_set_host_assert_info(type, reason, 1); -+ -+ pSignal = &pOp->signal; -+ -+ pOp->op.opId = WMT_OPID_CMD_TEST; -+ -+ pSignal->timeoutValue = MAX_EACH_WMT_CMD; -+ /*this test command should be run with usb cable connected, so no host awake is needed */ -+ /* wmt_lib_host_awake_get(); */ -+ pOp->op.au4OpData[0] = 0; -+ -+ /*wake up chip first */ -+ if (DISABLE_PSM_MONITOR()) { -+ WMT_ERR_FUNC("wake up failed,assert flow abort\n"); -+ wmt_lib_put_op_to_free_queue(pOp); -+ return MTK_WCN_BOOL_FALSE; -+ } -+ -+ bRet = wmt_lib_put_act_op(pOp); -+ ENABLE_PSM_MONITOR(); -+ -+ /* wmt_lib_host_awake_put(); */ -+ WMT_INFO_FUNC("CMD_TEST, opid (%d), par(%d, %d), ret(%d), result(%s)\n", -+ pOp->op.opId, -+ pOp->op.au4OpData[0], -+ pOp->op.au4OpData[1], bRet, MTK_WCN_BOOL_FALSE == bRet ? "failed" : "succeed"); -+ -+ return bRet; -+} -+#if !WMT_EXP_HID_API_EXPORT -+EXPORT_SYMBOL(mtk_wcn_wmt_assert); -+#endif -+ -+INT8 mtk_wcn_wmt_co_clock_flag_get(void) -+{ -+ return wmt_lib_co_clock_get(); -+} -+EXPORT_SYMBOL(mtk_wcn_wmt_co_clock_flag_get); -+ -+INT32 mtk_wcn_wmt_system_state_reset(void) -+{ -+ osal_memset(&gBtWifiGpsState, 0, osal_sizeof(gBtWifiGpsState)); -+ osal_memset(&gGpsFmState, 0, osal_sizeof(gGpsFmState)); -+ -+ return 0; -+} -+ -+INT32 mtk_wcn_wmt_wlan_reg(P_MTK_WCN_WMT_WLAN_CB_INFO pWmtWlanCbInfo) -+{ -+ INT32 iRet = -1; -+ -+ if (!pWmtWlanCbInfo) { -+ WMT_ERR_FUNC("wlan cb info in null!\n"); -+ return -1; -+ } -+ -+ WMT_INFO_FUNC("wmt wlan cb register\n"); -+ mtk_wcn_wlan_probe = pWmtWlanCbInfo->wlan_probe_cb; -+ mtk_wcn_wlan_remove = pWmtWlanCbInfo->wlan_remove_cb; -+ mtk_wcn_wlan_bus_tx_cnt = pWmtWlanCbInfo->wlan_bus_cnt_get_cb; -+ mtk_wcn_wlan_bus_tx_cnt_clr = pWmtWlanCbInfo->wlan_bus_cnt_clr_cb; -+ -+ if (gWifiProbed) { -+ WMT_INFO_FUNC("wlan has been done power on,call probe directly\n"); -+ iRet = (*mtk_wcn_wlan_probe) (); -+ if (!iRet) { -+ WMT_INFO_FUNC("call wlan probe OK when do wlan register to wmt\n"); -+ gWifiProbed = 0; -+ } else { -+ WMT_ERR_FUNC("call wlan probe fail(%d) when do wlan register to wmt\n", iRet); -+ return -2; -+ } -+ } -+ return 0; -+} -+EXPORT_SYMBOL(mtk_wcn_wmt_wlan_reg); -+ -+INT32 mtk_wcn_wmt_wlan_unreg(void) -+{ -+ WMT_INFO_FUNC("wmt wlan cb unregister\n"); -+ mtk_wcn_wlan_probe = NULL; -+ mtk_wcn_wlan_remove = NULL; -+ mtk_wcn_wlan_bus_tx_cnt = NULL; -+ mtk_wcn_wlan_bus_tx_cnt_clr = NULL; -+ -+ return 0; -+} -+EXPORT_SYMBOL(mtk_wcn_wmt_wlan_unreg); -+ -+MTK_WCN_BOOL mtk_wcn_set_connsys_power_off_flag(MTK_WCN_BOOL value) -+{ -+ g_pwr_off_flag = value; -+ if (g_pwr_off_flag) -+ WMT_DBG_FUNC("enable connsys power off flag\n"); -+ else -+ WMT_INFO_FUNC("disable connsys power off, maybe need trigger coredump!\n"); -+ return g_pwr_off_flag; -+} -+EXPORT_SYMBOL(mtk_wcn_set_connsys_power_off_flag); -+ -+#ifdef MTK_WCN_WMT_STP_EXP_SYMBOL_ABSTRACT -+VOID mtk_wcn_wmt_exp_init(void) -+{ -+ MTK_WCN_WMT_EXP_CB_INFO wmtExpCb = { -+ -+ .wmt_func_on_cb = _mtk_wcn_wmt_func_on, -+ .wmt_func_off_cb = _mtk_wcn_wmt_func_off, -+ .wmt_therm_ctrl_cb = _mtk_wcn_wmt_therm_ctrl, -+ .wmt_hwver_get_cb = _mtk_wcn_wmt_hwver_get, -+ .wmt_dsns_ctrl_cb = _mtk_wcn_wmt_dsns_ctrl, -+ .wmt_msgcb_reg_cb = _mtk_wcn_wmt_msgcb_reg, -+ .wmt_msgcb_unreg_cb = _mtk_wcn_wmt_msgcb_unreg, -+ .wmt_sdio_op_reg_cb = _mtk_wcn_stp_wmt_sdio_op_reg, -+ .wmt_sdio_host_awake_cb = _mtk_wcn_stp_wmt_sdio_host_awake, -+ .wmt_assert_cb = _mtk_wcn_wmt_assert -+ }; -+ -+ mtk_wcn_wmt_exp_cb_reg(&wmtExpCb); -+} -+ -+VOID mtk_wcn_wmt_exp_deinit(void) -+{ -+ mtk_wcn_wmt_exp_cb_unreg(); -+} -+#ifdef CONFIG_MTK_COMBO_ANT -+/* -+ ctrlId: get ram code status opId or ram code download opId -+ pBuf: pointer to ANT ram code -+ length: total length of ANT ram code -+*/ -+ENUM_WMT_ANT_RAM_STATUS mtk_wcn_wmt_ant_ram_ctrl(ENUM_WMT_ANT_RAM_CTRL ctrlId, PUINT8 pBuf, -+ UINT32 length, ENUM_WMT_ANT_RAM_SEQ seq) -+{ -+ ENUM_WMT_ANT_RAM_STATUS eRet = 0; -+ P_OSAL_OP pOp = NULL; -+ MTK_WCN_BOOL bRet = MTK_WCN_BOOL_FALSE; -+ P_OSAL_SIGNAL pSignal; -+ -+ /*1. parameter validation check */ -+ /*for WMT_ANT_RAM_GET_STATUS, ignore pBuf and length */ -+ /*for WMT_ANT_RAM_DOWNLOAD, -+ pBuf must not be NULL, kernel space memory pointer -+ length must be large than 0 */ -+ -+ if ((WMT_ANT_RAM_GET_STATUS > ctrlId) || (WMT_ANT_RAM_CTRL_MAX <= ctrlId)) { -+ WMT_ERR_FUNC("error ctrlId:%d detected.\n", ctrlId); -+ eRet = WMT_ANT_RAM_PARA_ERR; -+ return eRet; -+ } -+ -+ if ((WMT_ANT_RAM_DOWNLOAD == ctrlId) && -+ ((NULL == pBuf) || -+ (0 >= length) || -+ (1000 < length) || (seq >= WMT_ANT_RAM_SEQ_MAX) || (seq < WMT_ANT_RAM_START_PKT))) { -+ eRet = WMT_ANT_RAM_PARA_ERR; -+ WMT_ERR_FUNC -+ ("error parameter detected, ctrlId:%d, pBuf:%p,length(0x%x),seq(%d) .\n", -+ ctrlId, pBuf, length, seq); -+ return eRet; -+ } -+ /*get WMT opId */ -+ pOp = wmt_lib_get_free_op(); -+ if (!pOp) { -+ WMT_DBG_FUNC("get_free_lxop fail\n"); -+ return MTK_WCN_BOOL_FALSE; -+ } -+ -+ pSignal = &pOp->signal; -+ pSignal->timeoutValue = -+ (WMT_ANT_RAM_DOWNLOAD == ctrlId) ? MAX_FUNC_ON_TIME : MAX_EACH_WMT_CMD; -+ -+ pOp->op.opId = -+ (WMT_ANT_RAM_DOWNLOAD == ctrlId) ? WMT_OPID_ANT_RAM_DOWN : WMT_OPID_ANT_RAM_STA_GET; -+ pOp->op.au4OpData[0] = (size_t) pBuf; -+ pOp->op.au4OpData[1] = length; -+ pOp->op.au4OpData[2] = seq; -+ -+ -+ /*disable PSM monitor */ -+ if (DISABLE_PSM_MONITOR()) { -+ WMT_ERR_FUNC("wake up failed\n"); -+ wmt_lib_put_op_to_free_queue(pOp); -+ return MTK_WCN_BOOL_FALSE; -+ } -+ /*wakeup wmtd thread */ -+ bRet = wmt_lib_put_act_op(pOp); -+ -+ /*enable PSM monitor */ -+ ENABLE_PSM_MONITOR(); -+ -+ WMT_DBG_FUNC("CMD_TEST, opid (%d), ret(%d),retVal(%zu) result(%s)\n", -+ pOp->op.opId, -+ bRet, -+ pOp->op.au4OpData[2], MTK_WCN_BOOL_FALSE == bRet ? "failed" : "succeed"); -+ -+ /*check return value and return result */ -+ if (MTK_WCN_BOOL_FALSE == bRet) { -+ eRet = WMT_ANT_RAM_OP_ERR; -+ } else { -+ eRet = (WMT_ANT_RAM_DOWNLOAD == ctrlId) ? -+ WMT_ANT_RAM_DOWN_OK : -+ ((1 == pOp->op.au4OpData[2]) ? WMT_ANT_RAM_EXIST : WMT_ANT_RAM_NOT_EXIST); -+ } -+ -+ return eRet; -+ -+} -+EXPORT_SYMBOL(mtk_wcn_wmt_ant_ram_ctrl); -+#endif -+ -+#endif -+VOID mtk_wcn_wmt_set_wifi_ver(UINT32 Value) -+{ -+ wmt_lib_soc_set_wifiver(Value); -+} -+EXPORT_SYMBOL(mtk_wcn_wmt_set_wifi_ver); -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/Makefile b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/Makefile -new file mode 100644 -index 000000000000..eb37baf87b02 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/Makefile -@@ -0,0 +1,27 @@ -+ifeq ($(CONFIG_MTK_COMBO), y) -+ -+ccflags-y += \ -+ -I$(src)/../../linux/include \ -+ -I$(src)/../../linux/pri/include \ -+ -I$(src)/../../core/include \ -+ -I$(src)/../../include \ -+ -I$(src)/../include \ -+ -I$(src)/../../../common_detect \ -+ -I$(srctree)/drivers/misc/mediatek/include/mt-plat/$(MTK_PLATFORM)/include/mach \ -+ -DMTK_BT_HCI=1 -+ -+ccflags-y += -DWMT_CREATE_NODE_DYNAMIC=1 -+ -+ifeq ($(CONFIG_MTK_TC1_FEATURE), y) -+ ccflags-y += -DCFG_TC1_FEATURE=1 -+else -+ ccflags-y += -DCFG_TC1_FEATURE=0 -+endif -+ -+obj-y += osal.o \ -+ bgw_desense.o \ -+ wmt_idc.o -+obj-$(CONFIG_MTK_COMBO_BT) += stp_chrdev_bt.o -+obj-$(CONFIG_MTK_COMBO_WIFI) += wmt_chrdev_wifi.o -+ -+endif -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/bgw_desense.c b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/bgw_desense.c -new file mode 100644 -index 000000000000..11e45aa13087 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/bgw_desense.c -@@ -0,0 +1,153 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -+ -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include "bgw_desense.h" -+ -+static struct sock *g_nl_sk; -+/* static struct sockaddr_nl src_addr, des_addr; */ -+/* static struct iovec iov; */ -+static int pid; -+/* static struct msghdr msg; */ -+ -+void bgw_destroy_netlink_kernel(void) -+{ -+ if (g_nl_sk != NULL) { -+ /* sock_release(g_nl_sk->sk_socket); */ -+ netlink_kernel_release(g_nl_sk); -+ MSG("release socket\n"); -+ return; -+ } -+ ERR("no socket yet\n"); -+} -+ -+void send_command_to_daemon(const int command /*struct sk_buff *skb */) -+{ -+/* -+ struct iphdr *iph; -+ struct ethhdr *ehdr; -+ */ -+ struct nlmsghdr *nlh; -+ struct sk_buff *nl_skb; -+ int res; -+ -+ MSG("here we will send command to native daemon\n"); -+/* if(skb == NULL) -+ { -+ ERR("invalid sk_buff\n"); -+ return; -+ } -+*/ -+ if (!g_nl_sk) { -+ ERR("invalid socket\n"); -+ return; -+ } -+ if (pid == 0) { -+ ERR("invalid native process pid\n"); -+ return; -+ } -+ /*alloc data buffer for sending to native */ -+ /*malloc data space at least 1500 bytes, which is ethernet data length */ -+ nl_skb = alloc_skb(NLMSG_SPACE(MAX_NL_MSG_LEN), GFP_ATOMIC); -+ if (nl_skb == NULL) { -+ ERR("malloc skb error\n"); -+ return; -+ } -+ MSG("malloc data space done\n"); -+ /* -+ ehdr = eth_hdr(skb); -+ iph = ip_hdr(skb); -+ */ -+ -+/* nlh = NLMSG_PUT(nl_skb, 0, 0, 0, NLMSG_SPACE(1500)-sizeof(struct nlmsghdr)); */ -+ nlh = nlmsg_put(nl_skb, 0, 0, 0, MAX_NL_MSG_LEN, 0); -+ if (nlh == NULL) { -+ MSG("nlh is NULL\n"); -+ kfree_skb(nl_skb); -+ return; -+ } -+ NETLINK_CB(nl_skb).portid = 0; -+ -+/* memcpy(NLMSG_DATA(nlh), ACK, 5); */ -+ *(char *)NLMSG_DATA(nlh) = command; -+ res = netlink_unicast(g_nl_sk, nl_skb, pid, MSG_DONTWAIT); -+ if (res == 0) { -+ MSG("send to user space process error\n"); -+ return; -+ } -+ ERR("send to user space process done, data length = %d\n", res); -+} -+ -+static void nl_data_handler(struct sk_buff *__skb) -+{ -+ struct sk_buff *skb; -+ struct nlmsghdr *nlh; -+ int i; -+ int len; -+ char str[128]; -+ -+ MSG("we got netlink message\n"); -+ len = NLMSG_SPACE(MAX_NL_MSG_LEN); -+ skb = skb_get(__skb); -+ if (skb == NULL) -+ ERR("skb_get return NULL"); -+ if (skb->len >= NLMSG_SPACE(0)) { /*presume there is 5byte payload at leaset */ -+ MSG("length is enough\n"); -+ nlh = nlmsg_hdr(skb); /* point to data which include in skb */ -+ memcpy(str, NLMSG_DATA(nlh), sizeof(str)); -+ for (i = 0; i < 3; i++) -+ MSG("str[%d = %c]", i, str[i]); -+ MSG("str[0] = %d, str[1] = %d, str[2] = %d\n", str[0], str[1], str[2]); -+ if (str[0] == 'B' && str[1] == 'G' && str[2] == 'W') { -+ MSG("got native daemon init command, record it's pid\n"); -+ pid = nlh->nlmsg_pid; /*record the native process PID */ -+ MSG("native daemon pid is %d\n", pid); -+ } else { -+ ERR("this is not BGW message, ignore it\n"); -+ return; -+ } -+ } else { -+ ERR("not engouth data length\n"); -+ return; -+ } -+ -+ kfree_skb(skb); -+ -+ send_command_to_daemon(ACK); -+} -+ -+int bgw_init_socket(void) -+{ -+ struct netlink_kernel_cfg cfg; -+ -+ memset(&cfg, 0, sizeof(cfg)); -+ cfg.input = nl_data_handler; -+ -+ g_nl_sk = __netlink_kernel_create(&init_net, NETLINK_TEST, THIS_MODULE, &cfg); -+ -+ if (g_nl_sk == NULL) { -+ ERR("netlink_kernel_create error\n"); -+ return -1; -+ } -+ MSG("netlink_kernel_create ok\n"); -+ return 0; -+} -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/osal.c b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/osal.c -new file mode 100644 -index 000000000000..4ebbd51c0259 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/osal.c -@@ -0,0 +1,1210 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -+ -+/*! \file -+ \brief Declaration of library functions -+ -+ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "osal_typedef.h" -+#include "osal.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/* CRC table for the CRC-16. The poly is 0x8005 (x^16 + x^15 + x^2 + 1) */ -+static UINT16 const crc16_table[256] = { -+ 0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241, -+ 0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440, -+ 0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40, -+ 0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841, -+ 0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40, -+ 0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41, -+ 0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641, -+ 0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040, -+ 0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240, -+ 0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441, -+ 0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41, -+ 0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840, -+ 0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41, -+ 0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40, -+ 0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640, -+ 0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041, -+ 0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240, -+ 0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441, -+ 0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41, -+ 0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840, -+ 0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41, -+ 0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40, -+ 0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1, 0xB681, 0x7640, -+ 0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041, -+ 0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241, -+ 0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440, -+ 0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40, -+ 0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841, -+ 0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40, -+ 0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41, -+ 0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641, -+ 0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040 -+}; -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+/*string operations*/ -+_osal_inline_ UINT32 osal_strlen(const char *str) -+{ -+ return strlen(str); -+} -+ -+_osal_inline_ INT32 osal_strcmp(const char *dst, const char *src) -+{ -+ return strcmp(dst, src); -+} -+ -+_osal_inline_ INT32 osal_strncmp(const char *dst, const char *src, UINT32 len) -+{ -+ return strncmp(dst, src, len); -+} -+ -+_osal_inline_ char *osal_strcpy(char *dst, const char *src) -+{ -+ return strcpy(dst, src); -+} -+ -+_osal_inline_ char *osal_strncpy(char *dst, const char *src, UINT32 len) -+{ -+ return strncpy(dst, src, len); -+} -+ -+_osal_inline_ char *osal_strcat(char *dst, const char *src) -+{ -+ return strcat(dst, src); -+} -+ -+_osal_inline_ char *osal_strncat(char *dst, const char *src, UINT32 len) -+{ -+ return strncat(dst, src, len); -+} -+ -+_osal_inline_ char *osal_strchr(const char *str, UINT8 c) -+{ -+ return strchr(str, c); -+} -+ -+_osal_inline_ char *osal_strsep(char **str, const char *c) -+{ -+ return strsep(str, c); -+} -+ -+_osal_inline_ int osal_strtol(const char *str, UINT32 adecimal, long *res) -+{ -+ return kstrtol(str, adecimal, res); -+} -+ -+_osal_inline_ char *osal_strstr(char *str1, const char *str2) -+{ -+ return strstr(str1, str2); -+} -+ -+INT32 osal_snprintf(char *buf, UINT32 len, const char *fmt, ...) -+{ -+ INT32 iRet = 0; -+ va_list args; -+ -+ /*va_start(args, fmt); */ -+ va_start(args, fmt); -+ /*iRet = snprintf(buf, len, fmt, args); */ -+ iRet = vsnprintf(buf, len, fmt, args); -+ va_end(args); -+ -+ return iRet; -+} -+ -+INT32 osal_err_print(const char *str, ...) -+{ -+ va_list args; -+ char tempString[DBG_LOG_STR_SIZE]; -+ -+ va_start(args, str); -+ vsnprintf(tempString, DBG_LOG_STR_SIZE, str, args); -+ va_end(args); -+ -+ pr_err("%s", tempString); -+ -+ return 0; -+} -+ -+INT32 osal_dbg_print(const char *str, ...) -+{ -+ va_list args; -+ char tempString[DBG_LOG_STR_SIZE]; -+ -+ va_start(args, str); -+ vsnprintf(tempString, DBG_LOG_STR_SIZE, str, args); -+ va_end(args); -+ -+ pr_debug("%s", tempString); -+ -+ return 0; -+} -+ -+INT32 osal_warn_print(const char *str, ...) -+{ -+ va_list args; -+ char tempString[DBG_LOG_STR_SIZE]; -+ -+ va_start(args, str); -+ vsnprintf(tempString, DBG_LOG_STR_SIZE, str, args); -+ va_end(args); -+ -+ pr_warn("%s", tempString); -+ -+ return 0; -+} -+ -+INT32 osal_dbg_assert(INT32 expr, const char *file, INT32 line) -+{ -+ if (!expr) { -+ pr_warn("%s (%d)\n", file, line); -+ /*BUG_ON(!expr); */ -+#ifdef CFG_COMMON_GPIO_DBG_PIN -+/* package this part */ -+ mt_set_gpio_out(GPIO70, GPIO_OUT_ZERO); -+ pr_warn("toggle GPIO70\n"); -+ udelay(10); -+ mt_set_gpio_out(GPIO70, GPIO_OUT_ONE); -+#endif -+ return 1; -+ } -+ return 0; -+ -+} -+ -+INT32 osal_dbg_assert_aee(const char *module, const char *detail_description) -+{ -+ osal_err_print("[WMT-ASSERT]" "[E][Module]:%s, [INFO]%s\n", module, detail_description); -+ -+#ifdef WMT_PLAT_ALPS -+ /* aee_kernel_warning(module,detail_description); */ -+ aee_kernel_warning_api(__FILE__, __LINE__, DB_OPT_WCN_ISSUE_INFO, module, detail_description); -+#endif -+ return 0; -+} -+ -+INT32 osal_sprintf(char *str, const char *format, ...) -+{ -+ INT32 iRet = 0; -+ va_list args; -+ -+ va_start(args, format); -+ iRet = vsnprintf(str, DBG_LOG_STR_SIZE, format, args); -+ va_end(args); -+ -+ return iRet; -+} -+ -+_osal_inline_ VOID *osal_malloc(UINT32 size) -+{ -+ return vmalloc(size); -+} -+ -+_osal_inline_ VOID osal_free(const VOID *dst) -+{ -+ vfree(dst); -+} -+ -+_osal_inline_ VOID *osal_memset(VOID *buf, INT32 i, UINT32 len) -+{ -+ return memset(buf, i, len); -+} -+ -+_osal_inline_ VOID *osal_memcpy(VOID *dst, const VOID *src, UINT32 len) -+{ -+#ifdef CONFIG_MTK_WCN_ARM64 -+ char *tmp; -+ const char *s; -+ size_t i; -+ -+ tmp = dst; -+ s = src; -+ for (i = 0; i < len; i++) -+ tmp[i] = s[i]; -+ -+ return dst; -+ -+#else -+ return memcpy(dst, src, len); -+#endif -+} -+ -+_osal_inline_ INT32 osal_memcmp(const VOID *buf1, const VOID *buf2, UINT32 len) -+{ -+ return memcmp(buf1, buf2, len); -+} -+ -+_osal_inline_ UINT16 osal_crc16(const UINT8 *buffer, const UINT32 length) -+{ -+ UINT16 crc = 0; -+ UINT32 i = 0; -+ -+ /* FIXME: Add STP checksum feature */ -+ crc = 0; -+ for (i = 0; i < length; i++, buffer++) -+ crc = (crc >> 8) ^ crc16_table[(crc ^ (*buffer)) & 0xff]; -+ -+ return crc; -+} -+ -+_osal_inline_ VOID osal_thread_show_stack(P_OSAL_THREAD pThread) -+{ -+ return show_stack(pThread->pThread, NULL); -+} -+ -+/* -+ *OSAL layer Thread Opeartion related APIs -+ * -+ * -+*/ -+_osal_inline_ INT32 osal_thread_create(P_OSAL_THREAD pThread) -+{ -+ pThread->pThread = kthread_create(pThread->pThreadFunc, pThread->pThreadData, pThread->threadName); -+ if (NULL == pThread->pThread) -+ return -1; -+ -+ return 0; -+} -+ -+_osal_inline_ INT32 osal_thread_run(P_OSAL_THREAD pThread) -+{ -+ if (pThread->pThread) { -+ wake_up_process(pThread->pThread); -+ return 0; -+ } else { -+ return -1; -+ } -+} -+ -+_osal_inline_ INT32 osal_thread_stop(P_OSAL_THREAD pThread) -+{ -+ INT32 iRet; -+ -+ if ((pThread) && (pThread->pThread)) { -+ iRet = kthread_stop(pThread->pThread); -+ /* pThread->pThread = NULL; */ -+ return iRet; -+ } -+ return -1; -+} -+ -+_osal_inline_ INT32 osal_thread_should_stop(P_OSAL_THREAD pThread) -+{ -+ if ((pThread) && (pThread->pThread)) -+ return kthread_should_stop(); -+ else -+ return 1; -+ -+} -+ -+_osal_inline_ INT32 -+osal_thread_wait_for_event(P_OSAL_THREAD pThread, P_OSAL_EVENT pEvent, P_OSAL_EVENT_CHECKER pChecker) -+{ -+ /* P_DEV_WMT pDevWmt;*/ -+ -+ if ((pThread) && (pThread->pThread) && (pEvent) && (pChecker)) { -+ /* pDevWmt = (P_DEV_WMT)(pThread->pThreadData);*/ -+ return wait_event_interruptible(pEvent->waitQueue, (/*!RB_EMPTY(&pDevWmt->rActiveOpQ) || */ -+ osal_thread_should_stop(pThread) -+ || (*pChecker) (pThread))); -+ } -+ return -1; -+} -+ -+_osal_inline_ INT32 osal_thread_destroy(P_OSAL_THREAD pThread) -+{ -+ if (pThread && (pThread->pThread)) { -+ kthread_stop(pThread->pThread); -+ pThread->pThread = NULL; -+ } -+ return 0; -+} -+ -+/* -+ *OSAL layer Signal Opeartion related APIs -+ *initialization -+ *wait for signal -+ *wait for signal timerout -+ *raise signal -+ *destroy a signal -+ * -+*/ -+ -+_osal_inline_ INT32 osal_signal_init(P_OSAL_SIGNAL pSignal) -+{ -+ if (pSignal) { -+ init_completion(&pSignal->comp); -+ return 0; -+ } else { -+ return -1; -+ } -+} -+ -+_osal_inline_ INT32 osal_wait_for_signal(P_OSAL_SIGNAL pSignal) -+{ -+ if (pSignal) { -+ wait_for_completion_interruptible(&pSignal->comp); -+ return 0; -+ } else { -+ return -1; -+ } -+} -+ -+_osal_inline_ INT32 osal_wait_for_signal_timeout(P_OSAL_SIGNAL pSignal) -+{ -+ /* return wait_for_completion_interruptible_timeout(&pSignal->comp, msecs_to_jiffies(pSignal->timeoutValue)); */ -+ /* [ChangeFeature][George] gps driver may be closed by -ERESTARTSYS. -+ * Avoid using *interruptible" version in order to complete our jobs, such -+ * as function off gracefully. -+ */ -+ return wait_for_completion_timeout(&pSignal->comp, msecs_to_jiffies(pSignal->timeoutValue)); -+} -+ -+_osal_inline_ INT32 osal_raise_signal(P_OSAL_SIGNAL pSignal) -+{ -+ /* TODO:[FixMe][GeorgeKuo]: DO sanity check here!!! */ -+ complete(&pSignal->comp); -+ return 0; -+} -+ -+_osal_inline_ INT32 osal_signal_deinit(P_OSAL_SIGNAL pSignal) -+{ -+ /* TODO:[FixMe][GeorgeKuo]: DO sanity check here!!! */ -+ pSignal->timeoutValue = 0; -+ return 0; -+} -+ -+/* -+ *OSAL layer Event Opeartion related APIs -+ *initialization -+ *wait for signal -+ *wait for signal timerout -+ *raise signal -+ *destroy a signal -+ * -+*/ -+ -+INT32 osal_event_init(P_OSAL_EVENT pEvent) -+{ -+ init_waitqueue_head(&pEvent->waitQueue); -+ -+ return 0; -+} -+ -+INT32 osal_wait_for_event(P_OSAL_EVENT pEvent, INT32(*condition) (PVOID), void *cond_pa) -+{ -+ return wait_event_interruptible(pEvent->waitQueue, condition(cond_pa)); -+} -+ -+INT32 osal_wait_for_event_timeout(P_OSAL_EVENT pEvent, INT32(*condition) (PVOID), void *cond_pa) -+{ -+ return wait_event_interruptible_timeout(pEvent->waitQueue, condition(cond_pa), -+ msecs_to_jiffies(pEvent->timeoutValue)); -+} -+ -+INT32 osal_trigger_event(P_OSAL_EVENT pEvent) -+{ -+ INT32 ret = 0; -+ -+ wake_up_interruptible(&pEvent->waitQueue); -+ return ret; -+} -+ -+INT32 osal_event_deinit(P_OSAL_EVENT pEvent) -+{ -+ return 0; -+} -+ -+_osal_inline_ long osal_wait_for_event_bit_set(P_OSAL_EVENT pEvent, unsigned long *pState, UINT32 bitOffset) -+{ -+ UINT32 ms = pEvent->timeoutValue; -+ -+ if (ms != 0) { -+ return wait_event_interruptible_timeout(pEvent->waitQueue, test_bit(bitOffset, pState), -+ msecs_to_jiffies(ms)); -+ } else { -+ return wait_event_interruptible(pEvent->waitQueue, test_bit(bitOffset, pState)); -+ } -+ -+} -+ -+_osal_inline_ long osal_wait_for_event_bit_clr(P_OSAL_EVENT pEvent, unsigned long *pState, UINT32 bitOffset) -+{ -+ UINT32 ms = pEvent->timeoutValue; -+ -+ if (ms != 0) { -+ return wait_event_interruptible_timeout(pEvent->waitQueue, !test_bit(bitOffset, pState), -+ msecs_to_jiffies(ms)); -+ } else { -+ return wait_event_interruptible(pEvent->waitQueue, !test_bit(bitOffset, pState)); -+ } -+ -+} -+ -+/* -+ *bit test and set/clear operations APIs -+ * -+ * -+*/ -+#if OS_BIT_OPS_SUPPORT -+#define osal_bit_op_lock(x) -+#define osal_bit_op_unlock(x) -+#else -+ -+_osal_inline_ INT32 osal_bit_op_lock(P_OSAL_UNSLEEPABLE_LOCK pLock) -+{ -+ -+ return 0; -+} -+ -+_osal_inline_ INT32 osal_bit_op_unlock(P_OSAL_UNSLEEPABLE_LOCK pLock) -+{ -+ -+ return 0; -+} -+#endif -+_osal_inline_ INT32 osal_clear_bit(UINT32 bitOffset, P_OSAL_BIT_OP_VAR pData) -+{ -+ osal_bit_op_lock(&(pData->opLock)); -+ clear_bit(bitOffset, &pData->data); -+ osal_bit_op_unlock(&(pData->opLock)); -+ return 0; -+} -+ -+_osal_inline_ INT32 osal_set_bit(UINT32 bitOffset, P_OSAL_BIT_OP_VAR pData) -+{ -+ osal_bit_op_lock(&(pData->opLock)); -+ set_bit(bitOffset, &pData->data); -+ osal_bit_op_unlock(&(pData->opLock)); -+ return 0; -+} -+ -+_osal_inline_ INT32 osal_test_bit(UINT32 bitOffset, P_OSAL_BIT_OP_VAR pData) -+{ -+ UINT32 iRet = 0; -+ -+ osal_bit_op_lock(&(pData->opLock)); -+ iRet = test_bit(bitOffset, &pData->data); -+ osal_bit_op_unlock(&(pData->opLock)); -+ return iRet; -+} -+ -+_osal_inline_ INT32 osal_test_and_clear_bit(UINT32 bitOffset, P_OSAL_BIT_OP_VAR pData) -+{ -+ UINT32 iRet = 0; -+ -+ osal_bit_op_lock(&(pData->opLock)); -+ iRet = test_and_clear_bit(bitOffset, &pData->data); -+ osal_bit_op_unlock(&(pData->opLock)); -+ return iRet; -+ -+} -+ -+_osal_inline_ INT32 osal_test_and_set_bit(UINT32 bitOffset, P_OSAL_BIT_OP_VAR pData) -+{ -+ UINT32 iRet = 0; -+ -+ osal_bit_op_lock(&(pData->opLock)); -+ iRet = test_and_set_bit(bitOffset, &pData->data); -+ osal_bit_op_unlock(&(pData->opLock)); -+ return iRet; -+} -+ -+/* -+ *tiemr operations APIs -+ *create -+ *stop -+ * modify -+ *create -+ *delete -+ * -+*/ -+ -+INT32 osal_timer_create(P_OSAL_TIMER pTimer) -+{ -+ struct timer_list *timer = &pTimer->timer; -+ -+ init_timer(timer); -+ timer->function = pTimer->timeoutHandler; -+ timer->data = (unsigned long)pTimer->timeroutHandlerData; -+ return 0; -+} -+ -+INT32 osal_timer_start(P_OSAL_TIMER pTimer, UINT32 ms) -+{ -+ -+ struct timer_list *timer = &pTimer->timer; -+ -+ timer->expires = jiffies + (ms / (1000 / HZ)); -+ add_timer(timer); -+ return 0; -+} -+ -+INT32 osal_timer_stop(P_OSAL_TIMER pTimer) -+{ -+ struct timer_list *timer = &pTimer->timer; -+ -+ del_timer(timer); -+ return 0; -+} -+ -+INT32 osal_timer_stop_sync(P_OSAL_TIMER pTimer) -+{ -+ struct timer_list *timer = &pTimer->timer; -+ -+ del_timer_sync(timer); -+ return 0; -+} -+ -+INT32 osal_timer_modify(P_OSAL_TIMER pTimer, UINT32 ms) -+{ -+ -+ mod_timer(&pTimer->timer, jiffies + (ms) / (1000 / HZ)); -+ return 0; -+} -+ -+INT32 _osal_fifo_init(OSAL_FIFO *pFifo, UINT8 *buf, UINT32 size) -+{ -+ struct kfifo *fifo = NULL; -+ INT32 ret = -1; -+ -+ if (!pFifo) { -+ pr_err("pFifo must be !NULL\n"); -+ return -1; -+ } -+ if (pFifo->pFifoBody) { -+ pr_err("pFifo->pFifoBody must be NULL\n"); -+ pr_err("pFifo(0x%p), pFifo->pFifoBody(0x%p)\n", pFifo, pFifo->pFifoBody); -+ return -1; -+ } -+ fifo = kzalloc(sizeof(struct kfifo), GFP_ATOMIC); -+ if (!buf) { -+ /*fifo's buffer is not ready, we allocate automatically */ -+ ret = kfifo_alloc(fifo, size, /*GFP_KERNEL */ GFP_ATOMIC); -+ } else { -+ if (is_power_of_2(size)) { -+ kfifo_init(fifo, buf, size); -+ ret = 0; -+ } else { -+ kfifo_free(fifo); -+ fifo = NULL; -+ ret = -1; -+ } -+ } -+ -+ pFifo->pFifoBody = fifo; -+ return (ret < 0) ? (-1) : (0); -+} -+ -+INT32 _osal_fifo_deinit(OSAL_FIFO *pFifo) -+{ -+ struct kfifo *fifo = NULL; -+ -+ if (!pFifo || !pFifo->pFifoBody) { -+ pr_err("%s:pFifo = NULL or pFifo->pFifoBody = NULL, error\n", __func__); -+ return -1; -+ } -+ -+ fifo = (struct kfifo *)pFifo->pFifoBody; -+ -+ if (fifo) -+ kfifo_free(fifo); -+ -+ return 0; -+} -+ -+INT32 _osal_fifo_size(OSAL_FIFO *pFifo) -+{ -+ struct kfifo *fifo = NULL; -+ INT32 ret = 0; -+ -+ if (!pFifo || !pFifo->pFifoBody) { -+ pr_err("%s:pFifo = NULL or pFifo->pFifoBody = NULL, error\n", __func__); -+ return -1; -+ } -+ -+ fifo = (struct kfifo *)pFifo->pFifoBody; -+ -+ if (fifo) -+ ret = kfifo_size(fifo); -+ -+ return ret; -+} -+ -+/*returns unused bytes in fifo*/ -+INT32 _osal_fifo_avail_size(OSAL_FIFO *pFifo) -+{ -+ struct kfifo *fifo = NULL; -+ INT32 ret = 0; -+ -+ if (!pFifo || !pFifo->pFifoBody) { -+ pr_err("%s:pFifo = NULL or pFifo->pFifoBody = NULL, error\n", __func__); -+ return -1; -+ } -+ -+ fifo = (struct kfifo *)pFifo->pFifoBody; -+ -+ if (fifo) -+ ret = kfifo_avail(fifo); -+ -+ return ret; -+} -+ -+/*returns used bytes in fifo*/ -+INT32 _osal_fifo_len(OSAL_FIFO *pFifo) -+{ -+ struct kfifo *fifo = NULL; -+ INT32 ret = 0; -+ -+ if (!pFifo || !pFifo->pFifoBody) { -+ pr_err("%s:pFifo = NULL or pFifo->pFifoBody = NULL, error\n", __func__); -+ return -1; -+ } -+ -+ fifo = (struct kfifo *)pFifo->pFifoBody; -+ -+ if (fifo) -+ ret = kfifo_len(fifo); -+ -+ return ret; -+} -+ -+INT32 _osal_fifo_is_empty(OSAL_FIFO *pFifo) -+{ -+ struct kfifo *fifo = NULL; -+ INT32 ret = 0; -+ -+ if (!pFifo || !pFifo->pFifoBody) { -+ pr_err("%s:pFifo = NULL or pFifo->pFifoBody = NULL, error\n", __func__); -+ return -1; -+ } -+ -+ fifo = (struct kfifo *)pFifo->pFifoBody; -+ -+ if (fifo) -+ ret = kfifo_is_empty(fifo); -+ -+ return ret; -+} -+ -+INT32 _osal_fifo_is_full(OSAL_FIFO *pFifo) -+{ -+ struct kfifo *fifo = NULL; -+ INT32 ret = 0; -+ -+ if (!pFifo || !pFifo->pFifoBody) { -+ pr_err("%s:pFifo = NULL or pFifo->pFifoBody = NULL, error\n", __func__); -+ return -1; -+ } -+ -+ fifo = (struct kfifo *)pFifo->pFifoBody; -+ -+ if (fifo) -+ ret = kfifo_is_full(fifo); -+ -+ return ret; -+} -+ -+INT32 _osal_fifo_data_in(OSAL_FIFO *pFifo, const VOID *buf, UINT32 len) -+{ -+ struct kfifo *fifo = NULL; -+ INT32 ret = 0; -+ -+ if (!pFifo || !pFifo->pFifoBody) { -+ pr_err("%s:pFifo = NULL or pFifo->pFifoBody = NULL, error\n", __func__); -+ return -1; -+ } -+ -+ fifo = (struct kfifo *)pFifo->pFifoBody; -+ -+ if (fifo && buf && (len <= _osal_fifo_avail_size(pFifo))) { -+ ret = kfifo_in(fifo, buf, len); -+ } else { -+ pr_err("%s: kfifo_in, error, len = %d, _osal_fifo_avail_size = %d, buf=%p\n", -+ __func__, len, _osal_fifo_avail_size(pFifo), buf); -+ -+ ret = 0; -+ } -+ -+ return ret; -+} -+ -+INT32 _osal_fifo_data_out(OSAL_FIFO *pFifo, void *buf, UINT32 len) -+{ -+ struct kfifo *fifo = NULL; -+ INT32 ret = 0; -+ -+ if (!pFifo || !pFifo->pFifoBody) { -+ pr_err("%s:pFifo = NULL or pFifo->pFifoBody = NULL, error\n", __func__); -+ return -1; -+ } -+ -+ fifo = (struct kfifo *)pFifo->pFifoBody; -+ -+ if (fifo && buf && (len <= _osal_fifo_len(pFifo))) { -+ ret = kfifo_out(fifo, buf, len); -+ } else { -+ pr_err("%s: kfifo_out, error, len = %d, osal_fifo_len = %d, buf=%p\n", -+ __func__, len, _osal_fifo_len(pFifo), buf); -+ -+ ret = 0; -+ } -+ -+ return ret; -+} -+ -+INT32 _osal_fifo_reset(OSAL_FIFO *pFifo) -+{ -+ struct kfifo *fifo = NULL; -+ -+ if (!pFifo || !pFifo->pFifoBody) { -+ pr_err("%s:pFifo = NULL or pFifo->pFifoBody = NULL, error\n", __func__); -+ return -1; -+ } -+ -+ fifo = (struct kfifo *)pFifo->pFifoBody; -+ -+ if (fifo) -+ kfifo_reset(fifo); -+ -+ return 0; -+} -+ -+INT32 osal_fifo_init(P_OSAL_FIFO pFifo, UINT8 *buffer, UINT32 size) -+{ -+ if (!pFifo) { -+ pr_err("%s:pFifo = NULL, error\n", __func__); -+ return -1; -+ } -+ -+ pFifo->FifoInit = _osal_fifo_init; -+ pFifo->FifoDeInit = _osal_fifo_deinit; -+ pFifo->FifoSz = _osal_fifo_size; -+ pFifo->FifoAvailSz = _osal_fifo_avail_size; -+ pFifo->FifoLen = _osal_fifo_len; -+ pFifo->FifoIsEmpty = _osal_fifo_is_empty; -+ pFifo->FifoIsFull = _osal_fifo_is_full; -+ pFifo->FifoDataIn = _osal_fifo_data_in; -+ pFifo->FifoDataOut = _osal_fifo_data_out; -+ pFifo->FifoReset = _osal_fifo_reset; -+ -+ if (NULL != pFifo->pFifoBody) { -+ pr_err("%s:Because pFifo room is avialable, we clear the room and allocate them again.\n", __func__); -+ pFifo->FifoDeInit(pFifo->pFifoBody); -+ pFifo->pFifoBody = NULL; -+ } -+ -+ pFifo->FifoInit(pFifo, buffer, size); -+ -+ return 0; -+} -+ -+VOID osal_fifo_deinit(P_OSAL_FIFO pFifo) -+{ -+ if (pFifo) -+ pFifo->FifoDeInit(pFifo); -+ else { -+ pr_err("%s:pFifo = NULL, error\n", __func__); -+ return; -+ } -+ kfree(pFifo->pFifoBody); -+} -+ -+INT32 osal_fifo_reset(P_OSAL_FIFO pFifo) -+{ -+ INT32 ret = -1; -+ -+ if (pFifo) { -+ ret = pFifo->FifoReset(pFifo); -+ } else { -+ pr_err("%s:pFifo = NULL, error\n", __func__); -+ ret = -1; -+ } -+ return ret; -+} -+ -+UINT32 osal_fifo_in(P_OSAL_FIFO pFifo, PUINT8 buffer, UINT32 size) -+{ -+ UINT32 ret = 0; -+ -+ if (pFifo) { -+ ret = pFifo->FifoDataIn(pFifo, buffer, size); -+ } else { -+ pr_err("%s:pFifo = NULL, error\n", __func__); -+ ret = 0; -+ } -+ -+ return ret; -+} -+ -+UINT32 osal_fifo_out(P_OSAL_FIFO pFifo, PUINT8 buffer, UINT32 size) -+{ -+ UINT32 ret = 0; -+ -+ if (pFifo) { -+ ret = pFifo->FifoDataOut(pFifo, buffer, size); -+ } else { -+ pr_err("%s:pFifo = NULL, error\n", __func__); -+ ret = 0; -+ } -+ -+ return ret; -+} -+ -+UINT32 osal_fifo_len(P_OSAL_FIFO pFifo) -+{ -+ UINT32 ret = 0; -+ -+ if (pFifo) { -+ ret = pFifo->FifoLen(pFifo); -+ } else { -+ pr_err("%s:pFifo = NULL, error\n", __func__); -+ ret = 0; -+ } -+ -+ return ret; -+} -+ -+UINT32 osal_fifo_sz(P_OSAL_FIFO pFifo) -+{ -+ UINT32 ret = 0; -+ -+ if (pFifo) { -+ ret = pFifo->FifoSz(pFifo); -+ } else { -+ pr_err("%s:pFifo = NULL, error\n", __func__); -+ ret = 0; -+ } -+ -+ return ret; -+} -+ -+UINT32 osal_fifo_avail(P_OSAL_FIFO pFifo) -+{ -+ UINT32 ret = 0; -+ -+ if (pFifo) { -+ ret = pFifo->FifoAvailSz(pFifo); -+ } else { -+ pr_err("%s:pFifo = NULL, error\n", __func__); -+ ret = 0; -+ } -+ -+ return ret; -+} -+ -+UINT32 osal_fifo_is_empty(P_OSAL_FIFO pFifo) -+{ -+ UINT32 ret = 0; -+ -+ if (pFifo) { -+ ret = pFifo->FifoIsEmpty(pFifo); -+ } else { -+ pr_err("%s:pFifo = NULL, error\n", __func__); -+ ret = 0; -+ } -+ -+ return ret; -+} -+ -+UINT32 osal_fifo_is_full(P_OSAL_FIFO pFifo) -+{ -+ UINT32 ret = 0; -+ -+ if (pFifo) { -+ ret = pFifo->FifoIsFull(pFifo); -+ } else { -+ pr_err("%s:pFifo = NULL, error\n", __func__); -+ ret = 0; -+ } -+ return ret; -+} -+ -+INT32 osal_wake_lock_init(P_OSAL_WAKE_LOCK pLock) -+{ -+ if (!pLock) -+ return -1; -+ -+ #ifdef CONFIG_PM_WAKELOCKS -+ wakeup_source_init(&pLock->wake_lock, pLock->name); -+ #else -+ wake_lock_init(&pLock->wake_lock, WAKE_LOCK_SUSPEND, pLock->name); -+ #endif -+ return 0; -+} -+ -+INT32 osal_wake_lock_deinit(P_OSAL_WAKE_LOCK pLock) -+{ -+ if (!pLock) -+ return -1; -+ -+ #ifdef CONFIG_PM_WAKELOCKS -+ wakeup_source_trash(&pLock->wake_lock); -+ #else -+ wake_lock_destroy(&pLock->wake_lock); -+ #endif -+ return 0; -+} -+ -+INT32 osal_wake_lock(P_OSAL_WAKE_LOCK pLock) -+{ -+ if (!pLock) -+ return -1; -+ -+ #ifdef CONFIG_PM_WAKELOCKS -+ __pm_stay_awake(&pLock->wake_lock); -+ #else -+ wake_lock(&pLock->wake_lock); -+ #endif -+ -+ return 0; -+} -+ -+INT32 osal_wake_unlock(P_OSAL_WAKE_LOCK pLock) -+{ -+ if (!pLock) -+ return -1; -+ -+ #ifdef CONFIG_PM_WAKELOCKS -+ __pm_relax(&pLock->wake_lock); -+ #else -+ wake_unlock(&pLock->wake_lock); -+ #endif -+ -+ return 0; -+ -+} -+ -+INT32 osal_wake_lock_count(P_OSAL_WAKE_LOCK pLock) -+{ -+ INT32 count = 0; -+ -+ if (!pLock) -+ return -1; -+ -+ #ifdef CONFIG_PM_WAKELOCKS -+ count = pLock->wake_lock.active; -+ #else -+ count = wake_lock_active(&pLock->wake_lock); -+ #endif -+ return count; -+} -+ -+/* -+ *sleepable lock operations APIs -+ *init -+ *lock -+ *unlock -+ *destroy -+ * -+*/ -+ -+#if !defined(CONFIG_PROVE_LOCKING) -+INT32 osal_unsleepable_lock_init(P_OSAL_UNSLEEPABLE_LOCK pUSL) -+{ -+ spin_lock_init(&(pUSL->lock)); -+ return 0; -+} -+#endif -+ -+INT32 osal_lock_unsleepable_lock(P_OSAL_UNSLEEPABLE_LOCK pUSL) -+{ -+ spin_lock_irqsave(&(pUSL->lock), pUSL->flag); -+ return 0; -+} -+ -+INT32 osal_unlock_unsleepable_lock(P_OSAL_UNSLEEPABLE_LOCK pUSL) -+{ -+ spin_unlock_irqrestore(&(pUSL->lock), pUSL->flag); -+ return 0; -+} -+ -+INT32 osal_unsleepable_lock_deinit(P_OSAL_UNSLEEPABLE_LOCK pUSL) -+{ -+ return 0; -+} -+ -+/* -+ *unsleepable operations APIs -+ *init -+ *lock -+ *unlock -+ *destroy -+ -+ * -+*/ -+ -+#if !defined(CONFIG_PROVE_LOCKING) -+INT32 osal_sleepable_lock_init(P_OSAL_SLEEPABLE_LOCK pSL) -+{ -+ mutex_init(&pSL->lock); -+ return 0; -+} -+#endif -+ -+INT32 osal_lock_sleepable_lock(P_OSAL_SLEEPABLE_LOCK pSL) -+{ -+ return mutex_lock_killable(&pSL->lock); -+} -+ -+INT32 osal_unlock_sleepable_lock(P_OSAL_SLEEPABLE_LOCK pSL) -+{ -+ mutex_unlock(&pSL->lock); -+ return 0; -+} -+ -+INT32 osal_sleepable_lock_deinit(P_OSAL_SLEEPABLE_LOCK pSL) -+{ -+ mutex_destroy(&pSL->lock); -+ return 0; -+} -+ -+INT32 osal_sleep_ms(UINT32 ms) -+{ -+ msleep(ms); -+ return 0; -+} -+ -+INT32 osal_udelay(UINT32 us) -+{ -+ udelay(us); -+ return 0; -+} -+ -+INT32 osal_gettimeofday(PINT32 sec, PINT32 usec) -+{ -+ INT32 ret = 0; -+ struct timeval now; -+ -+ do_gettimeofday(&now); -+ -+ if (sec != NULL) -+ *sec = now.tv_sec; -+ else -+ ret = -1; -+ -+ if (usec != NULL) -+ *usec = now.tv_usec; -+ else -+ ret = -1; -+ -+ return ret; -+} -+ -+INT32 osal_printtimeofday(const PUINT8 prefix) -+{ -+ INT32 ret; -+ INT32 sec; -+ INT32 usec; -+ -+ ret = osal_gettimeofday(&sec, &usec); -+ ret += osal_dbg_print("%s>sec=%d, usec=%d\n", prefix, sec, usec); -+ -+ return ret; -+} -+ -+VOID osal_buffer_dump(const UINT8 *buf, const UINT8 *title, const UINT32 len, const UINT32 limit) -+{ -+ INT32 k; -+ UINT32 dump_len; -+ -+ pr_warn("start of dump>[%s] len=%d, limit=%d,", title, len, limit); -+ -+ dump_len = ((0 != limit) && (len > limit)) ? limit : len; -+#if 0 -+ if (limit != 0) -+ len = (len > limit) ? (limit) : (len); -+ -+#endif -+ -+ for (k = 0; k < dump_len; k++) { -+ if ((k != 0) && (k % 16 == 0)) -+ pr_cont("\n"); -+ pr_cont("0x%02x ", buf[k]); -+ } -+ pr_warn("op.opId : 0xFFFFFFFF; -+} -+ -+MTK_WCN_BOOL osal_op_is_wait_for_signal(P_OSAL_OP pOp) -+{ -+ return (pOp && pOp->signal.timeoutValue) ? MTK_WCN_BOOL_TRUE : MTK_WCN_BOOL_FALSE; -+} -+ -+VOID osal_op_raise_signal(P_OSAL_OP pOp, INT32 result) -+{ -+ if (pOp) { -+ pOp->result = result; -+ osal_raise_signal(&pOp->signal); -+ } -+} -+ -+VOID osal_set_op_result(P_OSAL_OP pOp, INT32 result) -+{ -+ if (pOp) -+ pOp->result = result; -+ -+} -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/stp_chrdev_bt.c b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/stp_chrdev_bt.c -new file mode 100644 -index 000000000000..190fa3944d80 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/stp_chrdev_bt.c -@@ -0,0 +1,899 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#if WMT_CREATE_NODE_DYNAMIC -+#include -+#endif -+#include -+ -+#include "osal_typedef.h" -+#include "stp_exp.h" -+#include "wmt_exp.h" -+ -+MODULE_LICENSE("Dual BSD/GPL"); -+ -+#ifdef MTK_BT_HCI -+#define MTK_BT_DEBUG 0 -+#include -+#include -+#endif -+ -+ -+#define BT_DRIVER_NAME "mtk_stp_BT_chrdev" -+#define BT_DEV_MAJOR 192 /* Never used number */ -+ -+#define PFX "[MTK-BT] " -+#define BT_LOG_DBG 3 -+#define BT_LOG_INFO 2 -+#define BT_LOG_WARN 1 -+#define BT_LOG_ERR 0 -+ -+#define COMBO_IOC_MAGIC 0xb0 -+#define COMBO_IOCTL_FW_ASSERT _IOWR(COMBO_IOC_MAGIC, 0, int) -+#define COMBO_IOCTL_BT_IC_HW_VER _IOWR(COMBO_IOC_MAGIC, 1, void*) -+#define COMBO_IOCTL_BT_IC_FW_VER _IOWR(COMBO_IOC_MAGIC, 2, void*) -+#define COMBO_IOC_BT_HWVER _IOWR(COMBO_IOC_MAGIC, 3, void*) -+ -+static UINT32 gDbgLevel = BT_LOG_INFO; -+ -+#define BT_DBG_FUNC(fmt, arg...) \ -+ do { if (gDbgLevel >= BT_LOG_DBG) \ -+ pr_debug(PFX "%s: " fmt, __func__ , ##arg); \ -+ } while (0) -+#define BT_INFO_FUNC(fmt, arg...) \ -+ do { if (gDbgLevel >= BT_LOG_INFO) \ -+ pr_warn(PFX "%s: " fmt, __func__ , ##arg); \ -+ } while (0) -+#define BT_WARN_FUNC(fmt, arg...) \ -+ do { if (gDbgLevel >= BT_LOG_WARN) \ -+ pr_err(PFX "%s: " fmt, __func__ , ##arg); \ -+ } while (0) -+#define BT_ERR_FUNC(fmt, arg...) \ -+ do { if (gDbgLevel >= BT_LOG_ERR) \ -+ pr_err(PFX "%s: " fmt, __func__ , ##arg); \ -+ } while (0) -+ -+#define VERSION "1.0" -+ -+#ifdef MTK_BT_HCI -+ -+#define NUM_REASSEMBLY 32 -+struct mtk_hci { -+ struct hci_dev *hdev; -+ struct work_struct work; -+ struct sk_buff_head txq; -+ struct sk_buff *reassembly[NUM_REASSEMBLY]; -+}; -+ -+static struct mtk_hci mtk_hci; -+ -+#endif -+ -+#if WMT_CREATE_NODE_DYNAMIC -+struct class *stpbt_class = NULL; -+struct device *stpbt_dev = NULL; -+#endif -+ -+static INT32 BT_devs = 1; /* Device count */ -+static INT32 BT_major = BT_DEV_MAJOR; /* Dynamic allocation */ -+module_param(BT_major, uint, 0); -+static struct cdev BT_cdev; -+ -+#define BT_BUFFER_SIZE 2048 -+static UINT8 i_buf[BT_BUFFER_SIZE]; /* Input buffer of read() */ -+static UINT8 o_buf[BT_BUFFER_SIZE]; /* Output buffer of write() */ -+ -+static struct semaphore wr_mtx, rd_mtx; -+/* Wait queue for poll and read */ -+static wait_queue_head_t inq; -+static DECLARE_WAIT_QUEUE_HEAD(BT_wq); -+static INT32 flag; -+/* Reset flag for whole chip reset senario */ -+static volatile INT32 rstflag; -+ -+#ifdef MTK_BT_HCI -+static int hci_reassembly(struct hci_dev *hdev, int type, void *data, -+ int count, __u8 index) -+{ -+ int len = 0; -+ int hlen = 0; -+ int offset = 0; -+ int remain = count; -+ struct sk_buff *skb; -+ struct bt_skb_cb *scb; -+ u16 opcode = 0; -+ unsigned char *pdata = data; -+ -+ struct mtk_hci *info = NULL; -+ struct hci_event_hdr *ehdr = NULL; -+ struct hci_ev_cmd_complete *ev = NULL; -+ struct hci_rp_read_local_ext_features *ext = NULL; -+ -+ info = hci_get_drvdata(hdev); -+ if ( NULL == info ) { -+ printk(KERN_ERR "mtk_bt_hci: invalid info point\n"); -+ return 0; -+ } -+ -+ if ((type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT) || -+ index >= NUM_REASSEMBLY) -+ return -EILSEQ; -+ -+ skb = info->reassembly[index]; -+ -+ if (!skb) { -+ switch (type) { -+ case HCI_ACLDATA_PKT: -+ len = HCI_MAX_FRAME_SIZE; -+ hlen = HCI_ACL_HDR_SIZE; -+ break; -+ case HCI_EVENT_PKT: -+ len = HCI_MAX_EVENT_SIZE; -+ hlen = HCI_EVENT_HDR_SIZE; -+ break; -+ case HCI_SCODATA_PKT: -+ len = HCI_MAX_SCO_SIZE; -+ hlen = HCI_SCO_HDR_SIZE; -+ break; -+ } -+ -+ skb = bt_skb_alloc(len, GFP_ATOMIC); -+ if (!skb) -+ return -ENOMEM; -+ -+ scb = (void *) skb->cb; -+ scb->expect = hlen; -+ scb->pkt_type = type; -+ -+ info->reassembly[index] = skb; -+ } -+ -+ while (count) { -+ scb = (void *) skb->cb; -+ len = min_t(uint, scb->expect, count); -+ -+ /* -+ * Workaround for MT7623+MT6625 BT: the max page in response of cmd READ_LOCAL_EXT_FEATURES -+ * should be 1, instead of 2, so changing it to 1 here -+ */ -+ -+ if (HCI_EVENT_PKT == type) -+ { -+ ehdr = (void *)pdata; -+ offset = sizeof(struct hci_event_hdr); -+ if ( HCI_EV_CMD_COMPLETE == ehdr->evt) -+ { -+ ev = (struct hci_ev_cmd_complete *)&pdata[offset]; -+ -+ offset += sizeof(struct hci_ev_cmd_complete); -+ -+ opcode = __le16_to_cpu(ev->opcode); -+ if(HCI_OP_READ_LOCAL_EXT_FEATURES == opcode) { -+ ext = (struct hci_rp_read_local_ext_features *) &pdata[offset]; -+ if( !ext->status && ext->max_page >= 2) { -+ pr_info("%s: this workaround is applied for mediatek BT\n", __func__); -+ ext->max_page = 1; -+ } -+ } -+ -+ } -+ } -+ -+ memcpy(skb_put(skb, len), data, len); -+ -+ count -= len; -+ data += len; -+ scb->expect -= len; -+ remain = count; -+ -+ switch (type) { -+ case HCI_EVENT_PKT: -+ if (skb->len == HCI_EVENT_HDR_SIZE) { -+ struct hci_event_hdr *h = hci_event_hdr(skb); -+ -+ scb->expect = h->plen; -+ -+ if (skb_tailroom(skb) < scb->expect) { -+ kfree_skb(skb); -+ info->reassembly[index] = NULL; -+ return -ENOMEM; -+ } -+ } -+ -+ break; -+ -+ case HCI_ACLDATA_PKT: -+ if (skb->len == HCI_ACL_HDR_SIZE) { -+ struct hci_acl_hdr *h = hci_acl_hdr(skb); -+ -+ scb->expect = __le16_to_cpu(h->dlen); -+ -+ if (skb_tailroom(skb) < scb->expect) { -+ kfree_skb(skb); -+ info->reassembly[index] = NULL; -+ return -ENOMEM; -+ } -+ } -+ break; -+ -+ case HCI_SCODATA_PKT: -+ if (skb->len == HCI_SCO_HDR_SIZE) { -+ struct hci_sco_hdr *h = hci_sco_hdr(skb); -+ -+ scb->expect = h->dlen; -+ -+ if (skb_tailroom(skb) < scb->expect) { -+ kfree_skb(skb); -+ info->reassembly[index] = NULL; -+ return -ENOMEM; -+ } -+ } -+ break; -+ } -+ -+ if (scb->expect == 0) { -+ /* Complete frame */ -+ -+ bt_cb(skb)->pkt_type = type; -+ hci_recv_frame(hdev, skb); -+ -+ info->reassembly[index] = NULL; -+ return remain; -+ } -+ } -+ -+ return remain; -+} -+ -+int hci_recv_fragment(struct hci_dev *hdev, int type, void *data, int count) -+{ -+ int rem = 0; -+ -+ if (type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT) -+ return -EILSEQ; -+ -+ while (count) { -+ rem = hci_reassembly(hdev, type, data, count, type - 1); -+ if (rem < 0) -+ return rem; -+ -+ data += (count - rem); -+ count = rem; -+ } -+ -+ return rem; -+} -+#endif -+ -+#ifdef MTK_BT_HCI -+void -+hex_dump(char *prefix, char *p, int len) -+{ -+ int i; -+ -+ pr_err("%s ", prefix); -+ for (i = 0; i < len; i++) -+ pr_err("%02x ", (*p++ & 0xff)); -+ pr_err("\n"); -+} -+ -+static int -+mtk_bt_hci_open(struct hci_dev *hdev) -+{ -+ int err = 0; -+ -+#if MTK_BT_DEBUG == 1 -+ pr_err("# %s\n", __func__); -+#endif -+ -+ err = mtk_wcn_wmt_func_on(WMTDRV_TYPE_BT); -+ if (err != MTK_WCN_BOOL_TRUE) { -+ pr_err("%s func on failed with %d\n", __func__, err); -+ return -ENODEV; -+ } -+ -+ set_bit(HCI_RUNNING, &hdev->flags); -+ -+ mtk_wcn_stp_set_bluez(1); -+ -+ return 0; -+} -+ -+static int -+mtk_bt_hci_close(struct hci_dev *hdev) -+{ -+ int err = 0; -+ -+#if MTK_BT_DEBUG == 1 -+ pr_err("# %s\n", __func__); -+#endif -+ -+ mtk_wcn_stp_set_bluez(0); -+ -+ clear_bit(HCI_RUNNING, &hdev->flags); -+ -+ err = mtk_wcn_wmt_func_off(WMTDRV_TYPE_BT); -+ if (err != MTK_WCN_BOOL_TRUE) { -+ pr_err("%s func off failed with %d\n", __func__, err); -+ return -EIO; -+ } -+ -+ return 0; -+} -+ -+static void -+mtk_bt_hci_work(struct work_struct *work) -+{ -+ int err; -+ struct sk_buff *skb; -+ -+#if MTK_BT_DEBUG == 1 -+ pr_err("# %s\n", __func__); -+#endif -+ -+ while ((skb = skb_dequeue(&mtk_hci.txq))) { -+ skb_push(skb, 1); -+ skb->data[0] = bt_cb(skb)->pkt_type; -+ -+#if MTK_BT_DEBUG == 1 -+ hex_dump(">>", skb->data, skb->len); -+#endif -+ -+ err = mtk_wcn_stp_send_data(skb->data, skb->len, BT_TASK_INDX); -+ if (err < 0) { -+ pr_err("%s err=%d\n", __func__, err); -+ mtk_hci.hdev->stat.err_tx++; -+ skb_queue_head(&mtk_hci.txq, skb); -+ break; -+ } -+ -+ mtk_hci.hdev->stat.byte_tx += skb->len; -+ kfree_skb(skb); -+ } -+} -+ -+static int -+mtk_bt_hci_send(struct hci_dev *hdev, struct sk_buff *skb) -+{ -+#if MTK_BT_DEBUG == 1 -+ pr_err("# %s\n", __func__); -+#endif -+ -+ if (mtk_hci.hdev && !test_bit(HCI_RUNNING, &mtk_hci.hdev->flags)) -+ return -EBUSY; -+ -+ switch (bt_cb(skb)->pkt_type) { -+ case HCI_COMMAND_PKT: -+ mtk_hci.hdev->stat.cmd_tx++; -+ break; -+ -+ case HCI_ACLDATA_PKT: -+ mtk_hci.hdev->stat.acl_tx++; -+ break; -+ -+ case HCI_SCODATA_PKT: -+ mtk_hci.hdev->stat.sco_tx++; -+ break; -+ -+ default: -+ return -EILSEQ; -+ } -+ -+ skb_queue_tail(&mtk_hci.txq, skb); -+ schedule_work(&mtk_hci.work); -+ -+ return 0; -+} -+ -+static int -+mtk_bt_hci_flush(struct hci_dev *hdev) -+{ -+ pr_err("%s: todo\n", __func__); -+ -+ return 0; -+} -+ -+static void -+mtk_bt_hci_receive(const PUINT8 data, INT32 size) -+{ -+ int err; -+ -+#if MTK_BT_DEBUG == 1 -+ pr_err("# %s\n", __func__); -+ hex_dump("<<", data, size); -+#endif -+ -+ err = hci_recv_fragment(mtk_hci.hdev, data[0], (void *)&data[1], size - 1); -+ if (err < 0) -+ pr_err("%s: hci_recv_fragment failed with %d\n", __func__, err); -+ -+ if (mtk_hci.hdev) -+ mtk_hci.hdev->stat.byte_rx += size - 1; -+} -+ -+static void -+mtk_bt_hci_notify(struct hci_dev *hdev, unsigned int evt) -+{ -+ static const char * const notify_str[] = { -+ "null", -+ "HCI_NOTIFY_CONN_ADD", -+ "HCI_NOTIFY_CONN_DEL", -+ "HCI_NOTIFY_VOICE_SETTING" -+ }; -+ -+ if (evt > HCI_NOTIFY_VOICE_SETTING) -+ pr_info("%s event=0x%x\n", __func__, evt); -+ else -+ pr_info("%s event(%d)=%s\n", __func__, evt, notify_str[evt]); -+} -+#endif -+ -+#ifdef MTK_BT_HCI -+ -+int mtk_bt_hci_init(void) -+{ -+ INT32 hci_err = 0; -+ -+ mtk_hci.hdev = hci_alloc_dev(); -+ if (!(mtk_hci.hdev)) { -+ mtk_hci.hdev = NULL; -+ BT_ERR_FUNC("%s hci_alloc_dev failed\n", __func__); -+ return -ENOMEM; -+ } -+ -+ mtk_hci.hdev->bus = HCI_SDIO; -+ mtk_hci.hdev->open = mtk_bt_hci_open; -+ mtk_hci.hdev->close = mtk_bt_hci_close; -+ mtk_hci.hdev->send = mtk_bt_hci_send; -+ mtk_hci.hdev->flush = mtk_bt_hci_flush; -+ mtk_hci.hdev->notify = mtk_bt_hci_notify; -+ SET_HCIDEV_DEV(mtk_hci.hdev, stpbt_dev); -+ -+ hci_set_drvdata(mtk_hci.hdev, &mtk_hci); -+ -+ mtk_wcn_stp_register_if_rx(mtk_bt_hci_receive); -+ -+ hci_err = hci_register_dev(mtk_hci.hdev); -+ if (hci_err) { -+ BT_ERR_FUNC("%s hci_register_dev failed with %d\n", __func__, hci_err); -+ hci_free_dev(mtk_hci.hdev); -+ mtk_hci.hdev = NULL; -+ return hci_err; -+ } -+ -+ skb_queue_head_init(&mtk_hci.txq); -+ INIT_WORK(&mtk_hci.work, mtk_bt_hci_work); -+ -+ return 0; -+} -+#endif -+ -+ -+static VOID bt_cdev_rst_cb(ENUM_WMTDRV_TYPE_T src, -+ ENUM_WMTDRV_TYPE_T dst, ENUM_WMTMSG_TYPE_T type, PVOID buf, UINT32 sz) -+{ -+ /* -+ Handle whole chip reset messages -+ */ -+ ENUM_WMTRSTMSG_TYPE_T rst_msg; -+ -+ if (sz <= sizeof(ENUM_WMTRSTMSG_TYPE_T)) { -+ memcpy((PINT8)&rst_msg, (PINT8)buf, sz); -+ BT_DBG_FUNC("src = %d, dst = %d, type = %d, buf = 0x%x sz = %d, max = %d\n", src, -+ dst, type, rst_msg, sz, WMTRSTMSG_RESET_MAX); -+ if ((src == WMTDRV_TYPE_WMT) && (dst == WMTDRV_TYPE_BT) -+ && (type == WMTMSG_TYPE_RESET)) { -+ if (rst_msg == WMTRSTMSG_RESET_START) { -+ BT_INFO_FUNC("BT reset start!\n"); -+ rstflag = 1; -+ wake_up_interruptible(&inq); -+ -+ } else if (rst_msg == WMTRSTMSG_RESET_END) { -+ BT_INFO_FUNC("BT reset end!\n"); -+ rstflag = 2; -+ wake_up_interruptible(&inq); -+ } -+ } -+ } else { -+ /* Invalid message format */ -+ BT_WARN_FUNC("Invalid message format!\n"); -+ } -+} -+ -+VOID BT_event_cb(VOID) -+{ -+ BT_DBG_FUNC("BT_event_cb()\n"); -+ -+ flag = 1; -+ -+ /* -+ * Finally, wake up any reader blocked in poll or read -+ */ -+ wake_up_interruptible(&inq); -+ wake_up(&BT_wq); -+} -+ -+unsigned int BT_poll(struct file *filp, poll_table *wait) -+{ -+ UINT32 mask = 0; -+ -+/* down(&wr_mtx); */ -+ /* -+ * The buffer is circular; it is considered full -+ * if "wp" is right behind "rp". "left" is 0 if the -+ * buffer is empty, and it is "1" if it is completely full. -+ */ -+ if (mtk_wcn_stp_is_rxqueue_empty(BT_TASK_INDX)) { -+ poll_wait(filp, &inq, wait); -+ -+ if (!mtk_wcn_stp_is_rxqueue_empty(BT_TASK_INDX) || rstflag) -+ /* BT Rx queue has valid data, or whole chip reset occurs */ -+ mask |= POLLIN | POLLRDNORM; /* Readable */ -+ } else { -+ mask |= POLLIN | POLLRDNORM; /* Readable */ -+ } -+ -+ /* Do we need condition here? */ -+ mask |= POLLOUT | POLLWRNORM; /* Writable */ -+/* up(&wr_mtx); */ -+ return mask; -+} -+ -+ssize_t BT_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos) -+{ -+ INT32 retval = 0; -+ INT32 write_size; -+ INT32 written = 0; -+ -+ down(&wr_mtx); -+ -+ BT_DBG_FUNC("%s: count %zd pos %lld\n", __func__, count, *f_pos); -+ if (rstflag) { -+ if (rstflag == 1) { /* Reset start */ -+ retval = -88; -+ BT_INFO_FUNC("%s: detect whole chip reset start\n", __func__); -+ } else if (rstflag == 2) { /* Reset end */ -+ retval = -99; -+ BT_INFO_FUNC("%s: detect whole chip reset end\n", __func__); -+ } -+ goto OUT; -+ } -+ -+ if (count > 0) { -+ if (count < BT_BUFFER_SIZE) { -+ write_size = count; -+ } else { -+ write_size = BT_BUFFER_SIZE; -+ BT_ERR_FUNC("%s: count > BT_BUFFER_SIZE\n", __func__); -+ } -+ -+ if (copy_from_user(&o_buf[0], &buf[0], write_size)) { -+ retval = -EFAULT; -+ goto OUT; -+ } -+ -+ written = mtk_wcn_stp_send_data(&o_buf[0], write_size, BT_TASK_INDX); -+ if (0 == written) { -+ retval = -ENOSPC; -+ /* No space is available, native program should not call BT_write with no delay */ -+ BT_ERR_FUNC -+ ("Packet length %zd, sent length %d, retval = %d\n", -+ count, written, retval); -+ } else { -+ retval = written; -+ } -+ -+ } else { -+ retval = -EFAULT; -+ BT_ERR_FUNC("Packet length %zd is not allowed, retval = %d\n", count, retval); -+ } -+ -+OUT: -+ up(&wr_mtx); -+ return retval; -+} -+ -+ssize_t BT_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos) -+{ -+ static int chip_reset_count; -+ INT32 retval = 0; -+ -+ down(&rd_mtx); -+ -+ BT_DBG_FUNC("%s: count %zd pos %lld\n", __func__, count, *f_pos); -+ if (rstflag) { -+ if (rstflag == 1) { /* Reset start */ -+ retval = -88; -+ if ((chip_reset_count%500) == 0) -+ BT_INFO_FUNC("%s: detect whole chip reset start, %d\n", __func__, chip_reset_count); -+ chip_reset_count++; -+ } else if (rstflag == 2) { /* Reset end */ -+ retval = -99; -+ BT_INFO_FUNC("%s: detect whole chip reset end\n", __func__); -+ chip_reset_count = 0; -+ } -+ goto OUT; -+ } -+ -+ if (count > BT_BUFFER_SIZE) { -+ count = BT_BUFFER_SIZE; -+ BT_ERR_FUNC("%s: count > BT_BUFFER_SIZE\n", __func__); -+ } -+ -+ retval = mtk_wcn_stp_receive_data(i_buf, count, BT_TASK_INDX); -+ -+ while (retval == 0) { /* Got nothing, wait for STP's signal */ -+ /* -+ * If nonblocking mode, return directly. -+ * O_NONBLOCK is specified during open() -+ */ -+ if (filp->f_flags & O_NONBLOCK) { -+ BT_DBG_FUNC("Non-blocking BT_read\n"); -+ retval = -EAGAIN; -+ goto OUT; -+ } -+ -+ BT_DBG_FUNC("%s: wait_event 1\n", __func__); -+ wait_event(BT_wq, flag != 0); -+ BT_DBG_FUNC("%s: wait_event 2\n", __func__); -+ flag = 0; -+ retval = mtk_wcn_stp_receive_data(i_buf, count, BT_TASK_INDX); -+ BT_DBG_FUNC("%s: mtk_wcn_stp_receive_data returns %d\n", __func__, retval); -+ } -+ -+ /* Got something from STP driver */ -+ if (copy_to_user(buf, i_buf, retval)) { -+ retval = -EFAULT; -+ goto OUT; -+ } -+ -+OUT: -+ up(&rd_mtx); -+ BT_DBG_FUNC("%s: retval = %d\n", __func__, retval); -+ return retval; -+} -+ -+/* int BT_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) */ -+long BT_unlocked_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) -+{ -+ INT32 retval = 0; -+ MTK_WCN_BOOL bRet = MTK_WCN_BOOL_TRUE; -+ ENUM_WMTHWVER_TYPE_T hw_ver_sym = WMTHWVER_INVALID; -+ -+ BT_DBG_FUNC("%s: cmd: 0x%x\n", __func__, cmd); -+ -+ switch (cmd) { -+ case COMBO_IOC_BT_HWVER: -+ /* Get combo HW version */ -+ hw_ver_sym = mtk_wcn_wmt_hwver_get(); -+ BT_INFO_FUNC("%s: HW version = %d, sizeof(hw_ver_sym) = %zd\n", -+ __func__, hw_ver_sym, sizeof(hw_ver_sym)); -+ if (copy_to_user((int __user *)arg, &hw_ver_sym, sizeof(hw_ver_sym))) -+ retval = -EFAULT; -+ break; -+ -+ case COMBO_IOCTL_FW_ASSERT: -+ /* Trigger FW assert for debug */ -+ BT_INFO_FUNC("%s: Host trigger FW assert......, reason:%lu\n", __func__, arg); -+ bRet = mtk_wcn_wmt_assert(WMTDRV_TYPE_BT, arg); -+ if (bRet == MTK_WCN_BOOL_TRUE) { -+ BT_INFO_FUNC("Host trigger FW assert succeed\n"); -+ retval = 0; -+ } else { -+ BT_ERR_FUNC("Host trigger FW assert Failed\n"); -+ retval = (-EBUSY); -+ } -+ break; -+ case COMBO_IOCTL_BT_IC_HW_VER: -+ retval = mtk_wcn_wmt_ic_info_get(WMTCHIN_HWVER); -+ break; -+ case COMBO_IOCTL_BT_IC_FW_VER: -+ retval = mtk_wcn_wmt_ic_info_get(WMTCHIN_FWVER); -+ break; -+ default: -+ retval = -EFAULT; -+ BT_ERR_FUNC("Unknown cmd (%d)\n", cmd); -+ break; -+ } -+ -+ return retval; -+} -+ -+long BT_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) -+{ -+ return BT_unlocked_ioctl(filp, cmd, arg); -+} -+ -+static int BT_open(struct inode *inode, struct file *file) -+{ -+ BT_INFO_FUNC("%s: major %d minor %d pid %d\n", __func__, imajor(inode), iminor(inode), current->pid); -+ -+ /* Turn on BT */ -+ if (MTK_WCN_BOOL_FALSE == mtk_wcn_wmt_func_on(WMTDRV_TYPE_BT)) { -+ BT_WARN_FUNC("WMT turn on BT fail!\n"); -+ return -ENODEV; -+ } -+ -+ BT_INFO_FUNC("WMT turn on BT OK!\n"); -+ rstflag = 0; -+ -+ if (mtk_wcn_stp_is_ready()) { -+ -+ mtk_wcn_stp_set_bluez(0); -+ -+ BT_INFO_FUNC("Now it's in MTK Bluetooth Mode\n"); -+ BT_INFO_FUNC("STP is ready!\n"); -+ -+ BT_DBG_FUNC("Register BT event callback!\n"); -+ mtk_wcn_stp_register_event_cb(BT_TASK_INDX, BT_event_cb); -+ } else { -+ BT_ERR_FUNC("STP is not ready\n"); -+ mtk_wcn_wmt_func_off(WMTDRV_TYPE_BT); -+ return -ENODEV; -+ } -+ -+ BT_DBG_FUNC("Register BT reset callback!\n"); -+ mtk_wcn_wmt_msgcb_reg(WMTDRV_TYPE_BT, bt_cdev_rst_cb); -+ -+ /* init_MUTEX(&wr_mtx); */ -+ sema_init(&wr_mtx, 1); -+ /* init_MUTEX(&rd_mtx); */ -+ sema_init(&rd_mtx, 1); -+ BT_INFO_FUNC("%s: finish\n", __func__); -+ -+ return 0; -+} -+ -+static int BT_close(struct inode *inode, struct file *file) -+{ -+ BT_INFO_FUNC("%s: major %d minor %d pid %d\n", __func__, imajor(inode), iminor(inode), current->pid); -+ rstflag = 0; -+ mtk_wcn_wmt_msgcb_unreg(WMTDRV_TYPE_BT); -+ mtk_wcn_stp_register_event_cb(BT_TASK_INDX, NULL); -+ -+ if (MTK_WCN_BOOL_FALSE == mtk_wcn_wmt_func_off(WMTDRV_TYPE_BT)) { -+ BT_ERR_FUNC("WMT turn off BT fail!\n"); -+ return -EIO; /* Mostly, native program will not check this return value. */ -+ } -+ -+ BT_INFO_FUNC("WMT turn off BT OK!\n"); -+ -+ return 0; -+} -+ -+const struct file_operations BT_fops = { -+ .open = BT_open, -+ .release = BT_close, -+ .read = BT_read, -+ .write = BT_write, -+ /* .ioctl = BT_ioctl, */ -+ .unlocked_ioctl = BT_unlocked_ioctl, -+ .compat_ioctl = BT_compat_ioctl, -+ .poll = BT_poll -+}; -+ -+ -+ -+static int BT_init(void) -+{ -+ dev_t dev = MKDEV(BT_major, 0); -+ INT32 alloc_ret = 0; -+ INT32 cdev_err = 0; -+ -+ /* Static allocate char device */ -+ alloc_ret = register_chrdev_region(dev, 1, BT_DRIVER_NAME); -+ if (alloc_ret) { -+ BT_ERR_FUNC("%s: Failed to register char device\n", __func__); -+ return alloc_ret; -+ } -+ -+ cdev_init(&BT_cdev, &BT_fops); -+ BT_cdev.owner = THIS_MODULE; -+ -+ cdev_err = cdev_add(&BT_cdev, dev, BT_devs); -+ if (cdev_err) -+ goto error; -+ -+#if WMT_CREATE_NODE_DYNAMIC -+ stpbt_class = class_create(THIS_MODULE, "stpbt"); -+ if (IS_ERR(stpbt_class)) -+ goto error; -+ stpbt_dev = device_create(stpbt_class, NULL, dev, NULL, "stpbt"); -+ if (IS_ERR(stpbt_dev)) -+ goto error; -+#endif -+ -+ BT_INFO_FUNC("%s driver(major %d) installed\n", BT_DRIVER_NAME, BT_major); -+ -+ /* Init wait queue */ -+ init_waitqueue_head(&(inq)); -+ -+#ifdef MTK_BT_HCI -+ mtk_bt_hci_init(); -+#endif -+ -+ return 0; -+ -+error: -+#if WMT_CREATE_NODE_DYNAMIC -+ if (!IS_ERR(stpbt_dev)) -+ device_destroy(stpbt_class, dev); -+ if (!IS_ERR(stpbt_class)) { -+ class_destroy(stpbt_class); -+ stpbt_class = NULL; -+ } -+#endif -+ if (cdev_err == 0) -+ cdev_del(&BT_cdev); -+ -+ if (alloc_ret == 0) -+ unregister_chrdev_region(dev, BT_devs); -+ -+ return -1; -+} -+ -+static void BT_exit(void) -+{ -+ dev_t dev = MKDEV(BT_major, 0); -+ -+#if WMT_CREATE_NODE_DYNAMIC -+ if (stpbt_dev) { -+ device_destroy(stpbt_class, dev); -+ stpbt_dev = NULL; -+ } -+ if (stpbt_class) { -+ class_destroy(stpbt_class); -+ stpbt_class = NULL; -+ } -+#endif -+ -+ cdev_del(&BT_cdev); -+ unregister_chrdev_region(dev, BT_devs); -+ -+ BT_INFO_FUNC("%s driver removed\n", BT_DRIVER_NAME); -+} -+ -+#ifdef MTK_WCN_REMOVE_KERNEL_MODULE -+ -+int mtk_wcn_stpbt_drv_init(void) -+{ -+ return BT_init(); -+} -+EXPORT_SYMBOL(mtk_wcn_stpbt_drv_init); -+ -+void mtk_wcn_stpbt_drv_exit(void) -+{ -+ return BT_exit(); -+} -+EXPORT_SYMBOL(mtk_wcn_stpbt_drv_exit); -+ -+#else -+ -+module_init(BT_init); -+module_exit(BT_exit); -+ -+#endif -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/wmt_chrdev_wifi.c b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/wmt_chrdev_wifi.c -new file mode 100644 -index 000000000000..c43bec5f7452 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/wmt_chrdev_wifi.c -@@ -0,0 +1,668 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "wmt_exp.h" -+#include "stp_exp.h" -+ -+MODULE_LICENSE("Dual BSD/GPL"); -+ -+#define WIFI_DRIVER_NAME "mtk_wmt_WIFI_chrdev" -+#define WIFI_DEV_MAJOR 155 -+ -+#define PFX "[MTK-WIFI] " -+#define WIFI_LOG_DBG 3 -+#define WIFI_LOG_INFO 2 -+#define WIFI_LOG_WARN 1 -+#define WIFI_LOG_ERR 0 -+ -+UINT32 gDbgLevel = WIFI_LOG_DBG; -+ -+#define WIFI_DBG_FUNC(fmt, arg...)\ -+ do {if (gDbgLevel >= WIFI_LOG_DBG) printk(PFX "%s: " fmt, __func__ , ##arg); } while (0) -+#define WIFI_INFO_FUNC(fmt, arg...)\ -+ do {if (gDbgLevel >= WIFI_LOG_INFO) printk(PFX "%s: " fmt, __func__ , ##arg); } while (0) -+#define WIFI_WARN_FUNC(fmt, arg...)\ -+ do {if (gDbgLevel >= WIFI_LOG_WARN) printk(PFX "%s: " fmt, __func__ , ##arg); } while (0) -+#define WIFI_ERR_FUNC(fmt, arg...)\ -+ do {if (gDbgLevel >= WIFI_LOG_ERR) printk(PFX "%s: " fmt, __func__ , ##arg); } while (0) -+#define WIFI_TRC_FUNC(f)\ -+ do {if (gDbgLevel >= WIFI_LOG_DBG) printk(PFX "<%s> <%d>\n", __func__, __LINE__); } while (0) -+ -+#define VERSION "1.0" -+ -+#define WLAN_IFACE_NAME "wlan0" -+#if CFG_TC1_FEATURE -+#define LEGACY_IFACE_NAME "legacy0" -+#endif -+ -+enum { -+ WLAN_MODE_HALT, -+ WLAN_MODE_AP, -+ WLAN_MODE_STA_P2P, -+ WLAN_MODE_MAX -+}; -+static INT32 wlan_mode = WLAN_MODE_HALT; -+static INT32 powered; -+static INT8 *ifname = WLAN_IFACE_NAME; -+#if CFG_TC1_FEATURE -+volatile INT32 wlan_if_changed = 0; -+EXPORT_SYMBOL(wlan_if_changed); -+#endif -+ -+typedef enum _ENUM_RESET_STATUS_T { -+ RESET_FAIL, -+ RESET_SUCCESS -+} ENUM_RESET_STATUS_T; -+ -+/* -+ * enable = 1, mode = 0 => init P2P network -+ * enable = 1, mode = 1 => init Soft AP network -+ * enable = 0 => uninit P2P/AP network -+ */ -+typedef struct _PARAM_CUSTOM_P2P_SET_STRUCT_T { -+ UINT32 u4Enable; -+ UINT32 u4Mode; -+} PARAM_CUSTOM_P2P_SET_STRUCT_T, *P_PARAM_CUSTOM_P2P_SET_STRUCT_T; -+typedef INT32(*set_p2p_mode) (struct net_device *netdev, PARAM_CUSTOM_P2P_SET_STRUCT_T p2pmode); -+ -+static set_p2p_mode pf_set_p2p_mode; -+VOID register_set_p2p_mode_handler(set_p2p_mode handler) -+{ -+ WIFI_INFO_FUNC("(pid %d) register set p2p mode handler %p\n", current->pid, handler); -+ pf_set_p2p_mode = handler; -+} -+EXPORT_SYMBOL(register_set_p2p_mode_handler); -+ -+/* For dynamical debug level setting */ -+/* copy of debug.h in wlan driver */ -+#define DBG_CLASS_ERROR BIT(0) -+#define DBG_CLASS_WARN BIT(1) -+#define DBG_CLASS_STATE BIT(2) -+#define DBG_CLASS_EVENT BIT(3) -+#define DBG_CLASS_TRACE BIT(4) -+#define DBG_CLASS_INFO BIT(5) -+#define DBG_CLASS_LOUD BIT(6) -+#define DBG_CLASS_TEMP BIT(7) -+#define DBG_CLASS_MASK BITS(0, 7) -+ -+typedef enum _ENUM_DBG_MODULE_T { -+ DBG_INIT_IDX = 0, /* For driver initial */ -+ DBG_HAL_IDX, /* For HAL(HW) Layer */ -+ DBG_INTR_IDX, /* For Interrupt */ -+ DBG_REQ_IDX, -+ DBG_TX_IDX, -+ DBG_RX_IDX, -+ DBG_RFTEST_IDX, /* For RF test mode */ -+ DBG_EMU_IDX, /* Developer specific */ -+ -+ DBG_SW1_IDX, /* Developer specific */ -+ DBG_SW2_IDX, /* Developer specific */ -+ DBG_SW3_IDX, /* Developer specific */ -+ DBG_SW4_IDX, /* Developer specific */ -+ -+ DBG_HEM_IDX, /* HEM */ -+ DBG_AIS_IDX, /* AIS */ -+ DBG_RLM_IDX, /* RLM */ -+ DBG_MEM_IDX, /* RLM */ -+ DBG_CNM_IDX, /* CNM */ -+ DBG_RSN_IDX, /* RSN */ -+ DBG_BSS_IDX, /* BSS */ -+ DBG_SCN_IDX, /* SCN */ -+ DBG_SAA_IDX, /* SAA */ -+ DBG_AAA_IDX, /* AAA */ -+ DBG_P2P_IDX, /* P2P */ -+ DBG_QM_IDX, /* QUE_MGT */ -+ DBG_SEC_IDX, /* SEC */ -+ DBG_BOW_IDX, /* BOW */ -+ DBG_WAPI_IDX, /* WAPI */ -+ DBG_ROAMING_IDX, /* ROAMING */ -+ -+ DBG_MODULE_NUM /* Notice the XLOG check */ -+} ENUM_DBG_MODULE_T; -+/* end */ -+typedef VOID(*set_dbg_level) (UINT8 modules[DBG_MODULE_NUM]); -+ -+UINT8 wlan_dbg_level[DBG_MODULE_NUM]; -+static set_dbg_level pf_set_dbg_level; -+VOID register_set_dbg_level_handler(set_dbg_level handler) -+{ -+ pf_set_dbg_level = handler; -+} -+EXPORT_SYMBOL(register_set_dbg_level_handler); -+ -+static INT32 WIFI_devs = 1; -+static INT32 WIFI_major = WIFI_DEV_MAJOR; -+module_param(WIFI_major, uint, 0); -+static struct cdev WIFI_cdev; -+volatile INT32 retflag = 0; -+static struct semaphore wr_mtx; -+ -+#define WMT_CHECK_DO_CHIP_RESET() \ -+do { \ -+ if (g_IsNeedDoChipReset) { \ -+ g_IsNeedDoChipReset = 0; \ -+ WIFI_ERR_FUNC("Do core dump and chip reset in %s line %d\n", __func__, __LINE__); \ -+ mtk_wcn_wmt_assert(WMTDRV_TYPE_WIFI, 40); \ -+ } \ -+} while (0) -+ -+/******************************************************************* -+ * WHOLE CHIP RESET PROCEDURE: -+ * -+ * WMTRSTMSG_RESET_START callback -+ * -> wlanRemove -+ * -> WMTRSTMSG_RESET_END callback -+ * -+ ******************************************************************* -+*/ -+/*-----------------------------------------------------------------*/ -+/* -+ * Receiving RESET_START message -+ */ -+/*-----------------------------------------------------------------*/ -+INT32 wifi_reset_start(VOID) -+{ -+ struct net_device *netdev = NULL; -+ PARAM_CUSTOM_P2P_SET_STRUCT_T p2pmode; -+ -+ down(&wr_mtx); -+ -+ if (powered == 1) { -+ netdev = dev_get_by_name(&init_net, ifname); -+ if (netdev == NULL) { -+ WIFI_ERR_FUNC("Fail to get %s net device\n", ifname); -+ } else { -+ p2pmode.u4Enable = 0; -+ p2pmode.u4Mode = 0; -+ -+ if (pf_set_p2p_mode) { -+ if (pf_set_p2p_mode(netdev, p2pmode) != 0) -+ WIFI_ERR_FUNC("Turn off p2p/ap mode fail"); -+ else -+ WIFI_INFO_FUNC("Turn off p2p/ap mode"); -+ } -+ dev_put(netdev); -+ netdev = NULL; -+ } -+ } else { -+ /* WIFI is off before whole chip reset, do nothing */ -+ } -+ -+ return 0; -+} -+EXPORT_SYMBOL(wifi_reset_start); -+ -+/*-----------------------------------------------------------------*/ -+/* -+ * Receiving RESET_END/RESET_END_FAIL message -+ */ -+/*-----------------------------------------------------------------*/ -+INT32 wifi_reset_end(ENUM_RESET_STATUS_T status) -+{ -+ struct net_device *netdev = NULL; -+ PARAM_CUSTOM_P2P_SET_STRUCT_T p2pmode; -+ INT32 wait_cnt = 0; -+ INT32 ret = -1; -+ -+ if (status == RESET_FAIL) { -+ /* whole chip reset fail, donot recover WIFI */ -+ ret = 0; -+ up(&wr_mtx); -+ } else if (status == RESET_SUCCESS) { -+ WIFI_WARN_FUNC("WIFI state recovering...\n"); -+ -+ if (powered == 1) { -+ /* WIFI is on before whole chip reset, reopen it now */ -+ if (MTK_WCN_BOOL_FALSE == mtk_wcn_wmt_func_on(WMTDRV_TYPE_WIFI)) { -+ WIFI_ERR_FUNC("WMT turn on WIFI fail!\n"); -+ goto done; -+ } else { -+ WIFI_INFO_FUNC("WMT turn on WIFI success!\n"); -+ } -+ -+ if (pf_set_p2p_mode == NULL) { -+ WIFI_ERR_FUNC("Set p2p mode handler is NULL\n"); -+ goto done; -+ } -+ -+ netdev = dev_get_by_name(&init_net, ifname); -+ while (netdev == NULL && wait_cnt < 10) { -+ WIFI_ERR_FUNC("Fail to get %s net device, sleep 300ms\n", ifname); -+ msleep(300); -+ wait_cnt++; -+ netdev = dev_get_by_name(&init_net, ifname); -+ } -+ if (wait_cnt >= 10) { -+ WIFI_ERR_FUNC("Get %s net device timeout\n", ifname); -+ goto done; -+ } -+ -+ if (wlan_mode == WLAN_MODE_STA_P2P) { -+ p2pmode.u4Enable = 1; -+ p2pmode.u4Mode = 0; -+ if (pf_set_p2p_mode(netdev, p2pmode) != 0) { -+ WIFI_ERR_FUNC("Set wlan mode fail\n"); -+ } else { -+ WIFI_WARN_FUNC("Set wlan mode %d\n", WLAN_MODE_STA_P2P); -+ ret = 0; -+ } -+ } else if (wlan_mode == WLAN_MODE_AP) { -+ p2pmode.u4Enable = 1; -+ p2pmode.u4Mode = 1; -+ if (pf_set_p2p_mode(netdev, p2pmode) != 0) { -+ WIFI_ERR_FUNC("Set wlan mode fail\n"); -+ } else { -+ WIFI_WARN_FUNC("Set wlan mode %d\n", WLAN_MODE_AP); -+ ret = 0; -+ } -+ } -+done: -+ if (netdev != NULL) -+ dev_put(netdev); -+ } else { -+ /* WIFI is off before whole chip reset, do nothing */ -+ ret = 0; -+ } -+ up(&wr_mtx); -+ } -+ -+ return ret; -+} -+EXPORT_SYMBOL(wifi_reset_end); -+ -+static int WIFI_open(struct inode *inode, struct file *file) -+{ -+ WIFI_INFO_FUNC("%s: major %d minor %d (pid %d)\n", __func__, imajor(inode), iminor(inode), current->pid); -+ -+ return 0; -+} -+ -+static int WIFI_close(struct inode *inode, struct file *file) -+{ -+ WIFI_INFO_FUNC("%s: major %d minor %d (pid %d)\n", __func__, imajor(inode), iminor(inode), current->pid); -+ retflag = 0; -+ -+ return 0; -+} -+ -+ssize_t WIFI_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos) -+{ -+ INT32 retval = -EIO; -+ INT8 local[12] = { 0 }; -+ struct net_device *netdev = NULL; -+ PARAM_CUSTOM_P2P_SET_STRUCT_T p2pmode; -+ INT32 wait_cnt = 0; -+ -+ down(&wr_mtx); -+ if (count <= 0) { -+ WIFI_ERR_FUNC("WIFI_write invalid param\n"); -+ goto done; -+ } -+ -+ if (0 == copy_from_user(local, buf, (count > sizeof(local)) ? sizeof(local) : count)) { -+ local[11] = 0; -+ WIFI_INFO_FUNC("WIFI_write %s\n", local); -+ -+ if (local[0] == '0') { -+ if (powered == 0) { -+ WIFI_INFO_FUNC("WIFI is already power off!\n"); -+ retval = count; -+ wlan_mode = WLAN_MODE_HALT; -+ goto done; -+ } -+ -+ netdev = dev_get_by_name(&init_net, ifname); -+ if (netdev == NULL) { -+ WIFI_ERR_FUNC("Fail to get %s net device\n", ifname); -+ } else { -+ p2pmode.u4Enable = 0; -+ p2pmode.u4Mode = 0; -+ -+ if (pf_set_p2p_mode) { -+ if (pf_set_p2p_mode(netdev, p2pmode) != 0) { -+ WIFI_ERR_FUNC("Turn off p2p/ap mode fail"); -+ } else { -+ WIFI_INFO_FUNC("Turn off p2p/ap mode"); -+ wlan_mode = WLAN_MODE_HALT; -+ } -+ } -+ dev_put(netdev); -+ netdev = NULL; -+ } -+ -+ if (MTK_WCN_BOOL_FALSE == mtk_wcn_wmt_func_off(WMTDRV_TYPE_WIFI)) { -+ WIFI_ERR_FUNC("WMT turn off WIFI fail!\n"); -+ WMT_CHECK_DO_CHIP_RESET(); -+ } else { -+ WIFI_INFO_FUNC("WMT turn off WIFI OK!\n"); -+ powered = 0; -+ retval = count; -+ wlan_mode = WLAN_MODE_HALT; -+#if CFG_TC1_FEATURE -+ ifname = WLAN_IFACE_NAME; -+ wlan_if_changed = 0; -+#endif -+ } -+ } else if (local[0] == '1') { -+ if (powered == 1) { -+ WIFI_INFO_FUNC("WIFI is already power on!\n"); -+ retval = count; -+ goto done; -+ } -+ -+ if (MTK_WCN_BOOL_FALSE == mtk_wcn_wmt_func_on(WMTDRV_TYPE_WIFI)) { -+ WIFI_ERR_FUNC("WMT turn on WIFI fail!\n"); -+ WMT_CHECK_DO_CHIP_RESET(); -+ } else { -+ powered = 1; -+ retval = count; -+ WIFI_INFO_FUNC("WMT turn on WIFI success!\n"); -+ wlan_mode = WLAN_MODE_HALT; -+ } -+ } else if (local[0] == 'D') { -+ INT32 k = 0; -+ /* -+ * 0: no debug -+ * 1: common debug output -+ * 2: more detials -+ * 3: verbose -+ */ -+ switch (local[1]) { -+ case '0': -+ for (k = 0; k < DBG_MODULE_NUM; k++) -+ wlan_dbg_level[k] = 0; -+ if (pf_set_dbg_level) -+ pf_set_dbg_level(wlan_dbg_level); -+ break; -+ case '1': -+ for (k = 0; k < DBG_MODULE_NUM; k++) { -+ wlan_dbg_level[k] = DBG_CLASS_ERROR | -+ DBG_CLASS_WARN | -+ DBG_CLASS_STATE | DBG_CLASS_EVENT | DBG_CLASS_TRACE | DBG_CLASS_INFO; -+ } -+ wlan_dbg_level[DBG_TX_IDX] &= ~(DBG_CLASS_EVENT | DBG_CLASS_TRACE | DBG_CLASS_INFO); -+ wlan_dbg_level[DBG_RX_IDX] &= ~(DBG_CLASS_EVENT | DBG_CLASS_TRACE | DBG_CLASS_INFO); -+ wlan_dbg_level[DBG_REQ_IDX] &= ~(DBG_CLASS_EVENT | DBG_CLASS_TRACE | DBG_CLASS_INFO); -+ wlan_dbg_level[DBG_INTR_IDX] = 0; -+ wlan_dbg_level[DBG_MEM_IDX] = 0; -+ if (pf_set_dbg_level) -+ pf_set_dbg_level(wlan_dbg_level); -+ break; -+ case '2': -+ for (k = 0; k < DBG_MODULE_NUM; k++) { -+ wlan_dbg_level[k] = DBG_CLASS_ERROR | -+ DBG_CLASS_WARN | -+ DBG_CLASS_STATE | DBG_CLASS_EVENT | DBG_CLASS_TRACE | DBG_CLASS_INFO; -+ } -+ wlan_dbg_level[DBG_INTR_IDX] = 0; -+ wlan_dbg_level[DBG_MEM_IDX] = 0; -+ if (pf_set_dbg_level) -+ pf_set_dbg_level(wlan_dbg_level); -+ break; -+ case '3': -+ for (k = 0; k < DBG_MODULE_NUM; k++) { -+ wlan_dbg_level[k] = DBG_CLASS_ERROR | -+ DBG_CLASS_WARN | -+ DBG_CLASS_STATE | -+ DBG_CLASS_EVENT | DBG_CLASS_TRACE | DBG_CLASS_INFO | DBG_CLASS_LOUD; -+ } -+ if (pf_set_dbg_level) -+ pf_set_dbg_level(wlan_dbg_level); -+ break; -+ default: -+ break; -+ } -+ } else if (local[0] == 'S' || local[0] == 'P' || local[0] == 'A') { -+ if (powered == 0) { -+ /* If WIFI is off, turn on WIFI first */ -+ if (MTK_WCN_BOOL_FALSE == mtk_wcn_wmt_func_on(WMTDRV_TYPE_WIFI)) { -+ WIFI_ERR_FUNC("WMT turn on WIFI fail!\n"); -+ WMT_CHECK_DO_CHIP_RESET(); -+ goto done; -+ } else { -+ powered = 1; -+ WIFI_INFO_FUNC("WMT turn on WIFI success!\n"); -+ wlan_mode = WLAN_MODE_HALT; -+ } -+ } -+ -+ if (pf_set_p2p_mode == NULL) { -+ WIFI_ERR_FUNC("Set p2p mode handler is NULL\n"); -+ goto done; -+ } -+ -+ netdev = dev_get_by_name(&init_net, ifname); -+ while (netdev == NULL && wait_cnt < 10) { -+ WIFI_ERR_FUNC("Fail to get %s net device, sleep 300ms\n", ifname); -+ msleep(300); -+ wait_cnt++; -+ netdev = dev_get_by_name(&init_net, ifname); -+ } -+ if (wait_cnt >= 10) { -+ WIFI_ERR_FUNC("Get %s net device timeout\n", ifname); -+ goto done; -+ } -+ -+ if ((wlan_mode == WLAN_MODE_STA_P2P && (local[0] == 'S' || local[0] == 'P')) || -+ (wlan_mode == WLAN_MODE_AP && (local[0] == 'A'))) { -+ WIFI_INFO_FUNC("WIFI is already in mode %d!\n", wlan_mode); -+ retval = count; -+ goto done; -+ } -+ -+ if ((wlan_mode == WLAN_MODE_AP && (local[0] == 'S' || local[0] == 'P')) || -+ (wlan_mode == WLAN_MODE_STA_P2P && (local[0] == 'A'))) { -+ p2pmode.u4Enable = 0; -+ p2pmode.u4Mode = 0; -+ if (pf_set_p2p_mode(netdev, p2pmode) != 0) { -+ WIFI_ERR_FUNC("Turn off p2p/ap mode fail"); -+ goto done; -+ } -+ } -+ -+ if (local[0] == 'S' || local[0] == 'P') { -+#if CFG_TC1_FEATURE -+ /* Restore NIC name to wlan0 */ -+ rtnl_lock(); -+ if (strcmp(ifname, WLAN_IFACE_NAME) != 0) { -+ if (dev_change_name(netdev, WLAN_IFACE_NAME) != 0) { -+ WIFI_ERR_FUNC("netdev name change to %s fail\n", WLAN_IFACE_NAME); -+ rtnl_unlock(); -+ goto done; -+ } else { -+ WIFI_INFO_FUNC("netdev name changed %s --> %s\n", ifname, -+ WLAN_IFACE_NAME); -+ ifname = WLAN_IFACE_NAME; -+ wlan_if_changed = 0; -+ } -+ } -+ rtnl_unlock(); -+#endif -+ p2pmode.u4Enable = 1; -+ p2pmode.u4Mode = 0; -+ if (pf_set_p2p_mode(netdev, p2pmode) != 0) { -+ WIFI_ERR_FUNC("Set wlan mode fail\n"); -+ } else { -+ WIFI_INFO_FUNC("Set wlan mode %d --> %d\n", wlan_mode, WLAN_MODE_STA_P2P); -+ wlan_mode = WLAN_MODE_STA_P2P; -+ retval = count; -+ } -+ } else if (local[0] == 'A') { -+#if CFG_TC1_FEATURE -+ /* Change NIC name to legacy0, since wlan0 is used for AP */ -+ rtnl_lock(); -+ if (strcmp(ifname, LEGACY_IFACE_NAME) != 0) { -+ if (dev_change_name(netdev, LEGACY_IFACE_NAME) != 0) { -+ WIFI_ERR_FUNC("netdev name change to %s fail\n", LEGACY_IFACE_NAME); -+ rtnl_unlock(); -+ goto done; -+ } else { -+ WIFI_INFO_FUNC("netdev name changed %s --> %s\n", ifname, -+ LEGACY_IFACE_NAME); -+ ifname = LEGACY_IFACE_NAME; -+ wlan_if_changed = 1; -+ } -+ } -+ rtnl_unlock(); -+#endif -+ p2pmode.u4Enable = 1; -+ p2pmode.u4Mode = 1; -+ if (pf_set_p2p_mode(netdev, p2pmode) != 0) { -+ WIFI_ERR_FUNC("Set wlan mode fail\n"); -+ } else { -+ WIFI_INFO_FUNC("Set wlan mode %d --> %d\n", wlan_mode, WLAN_MODE_AP); -+ wlan_mode = WLAN_MODE_AP; -+ retval = count; -+ } -+ } -+ dev_put(netdev); -+ netdev = NULL; -+ } -+ } -+done: -+ if (netdev != NULL) -+ dev_put(netdev); -+ -+ up(&wr_mtx); -+ return retval; -+} -+ -+const struct file_operations WIFI_fops = { -+ .open = WIFI_open, -+ .release = WIFI_close, -+ .write = WIFI_write, -+}; -+ -+#if WMT_CREATE_NODE_DYNAMIC -+struct class *wmtwifi_class = NULL; -+#endif -+ -+static int WIFI_init(void) -+{ -+ dev_t dev = MKDEV(WIFI_major, 0); -+ INT32 alloc_ret = 0; -+ INT32 cdev_err = 0; -+#if WMT_CREATE_NODE_DYNAMIC -+ struct device *wmtwifi_dev = NULL; -+#endif -+ -+ /* static allocate chrdev */ -+ alloc_ret = register_chrdev_region(dev, 1, WIFI_DRIVER_NAME); -+ if (alloc_ret) { -+ WIFI_ERR_FUNC("Fail to register chrdev\n"); -+ return alloc_ret; -+ } -+ -+ cdev_init(&WIFI_cdev, &WIFI_fops); -+ WIFI_cdev.owner = THIS_MODULE; -+ -+ cdev_err = cdev_add(&WIFI_cdev, dev, WIFI_devs); -+ if (cdev_err) -+ goto error; -+ -+#if WMT_CREATE_NODE_DYNAMIC /* mknod replace */ -+ wmtwifi_class = class_create(THIS_MODULE, "wmtWifi"); -+ if (IS_ERR(wmtwifi_class)) -+ goto error; -+ wmtwifi_dev = device_create(wmtwifi_class, NULL, dev, NULL, "wmtWifi"); -+ if (wmtwifi_dev == NULL) -+ goto error; -+ if (IS_ERR(wmtwifi_dev)) -+ goto error; -+#endif -+ -+ sema_init(&wr_mtx, 1); -+ -+ WIFI_INFO_FUNC("%s driver(major %d) installed.\n", WIFI_DRIVER_NAME, WIFI_major); -+ retflag = 0; -+ wlan_mode = WLAN_MODE_HALT; -+ pf_set_p2p_mode = NULL; -+ -+ return 0; -+ -+error: -+#if WMT_CREATE_NODE_DYNAMIC -+ if (!IS_ERR(wmtwifi_dev)) -+ device_destroy(wmtwifi_class, dev); -+ if (!IS_ERR(wmtwifi_class)) { -+ class_destroy(wmtwifi_class); -+ wmtwifi_class = NULL; -+ } -+#endif -+ -+ if (cdev_err == 0) -+ cdev_del(&WIFI_cdev); -+ -+ if (alloc_ret == 0) -+ unregister_chrdev_region(dev, WIFI_devs); -+ -+ return -1; -+} -+ -+static void WIFI_exit(void) -+{ -+ dev_t dev = MKDEV(WIFI_major, 0); -+ -+ retflag = 0; -+ -+#if WMT_CREATE_NODE_DYNAMIC -+ device_destroy(wmtwifi_class, dev); -+ class_destroy(wmtwifi_class); -+ wmtwifi_class = NULL; -+#endif -+ -+ cdev_del(&WIFI_cdev); -+ unregister_chrdev_region(dev, WIFI_devs); -+ -+ WIFI_INFO_FUNC("%s driver removed.\n", WIFI_DRIVER_NAME); -+} -+ -+#ifdef MTK_WCN_REMOVE_KERNEL_MODULE -+ -+INT32 mtk_wcn_wmt_wifi_init(VOID) -+{ -+ return WIFI_init(); -+} -+EXPORT_SYMBOL(mtk_wcn_wmt_wifi_init); -+ -+VOID mtk_wcn_wmt_wifi_exit(VOID) -+{ -+ return WIFI_exit(); -+} -+EXPORT_SYMBOL(mtk_wcn_wmt_wifi_exit); -+ -+#else -+ -+module_init(WIFI_init); -+module_exit(WIFI_exit); -+ -+#endif -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/wmt_idc.c b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/wmt_idc.c -new file mode 100644 -index 000000000000..641e516f603d ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/wmt_idc.c -@@ -0,0 +1,307 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -+ -+#include "osal_typedef.h" -+#include "wmt_idc.h" -+#include "wmt_lib.h" -+ -+#if CFG_WMT_LTE_COEX_HANDLING -+ -+MTK_WCN_WMT_IDC_INFO gWmtIdcInfo; -+ -+INT32 wmt_idc_init(VOID) -+{ -+ INT32 iRet; -+ -+ osal_memset(&gWmtIdcInfo, 0, osal_sizeof(gWmtIdcInfo)); -+ gWmtIdcInfo.iit.src_mod_id = AP_MOD_WMT; -+ gWmtIdcInfo.iit.dest_mod_id = MD_MOD_EL1; -+ gWmtIdcInfo.iit.sap_id = 0; -+ gWmtIdcInfo.ops.rx_cb = wmt_idc_msg_from_lte_handing; -+ -+ iRet = mtk_conn_md_bridge_reg(gWmtIdcInfo.iit.src_mod_id, &gWmtIdcInfo.ops); -+ if (iRet) { -+ WMT_ERR_FUNC("mtk_conn_md_bridge_reg fail(%d)\n", iRet); -+ return -1; -+ } -+ /* mtk_wcn_stp_flush_rx_queue(COEX_TASK_INDX); */ -+ return 0; -+ -+} -+ -+INT32 wmt_idc_deinit(VOID) -+{ -+ INT32 iRet; -+ -+ iRet = mtk_conn_md_bridge_unreg(gWmtIdcInfo.iit.src_mod_id); -+ if (iRet) -+ WMT_ERR_FUNC("mtk_conn_md_bridge_unreg fail(%d)\n", iRet); -+ -+ osal_memset(&gWmtIdcInfo, 0, osal_sizeof(gWmtIdcInfo)); -+ -+ return 0; -+} -+ -+INT32 wmt_idc_msg_from_lte_handing(ipc_ilm_t *ilm) -+{ -+ MTK_WCN_BOOL bRet; -+ -+ if (NULL == ilm) { -+ WMT_ERR_FUNC("NULL pointer\n"); -+ return -1; -+ } -+ if (mtk_wcn_stp_is_ready()) { -+ bRet = wmt_lib_handle_idc_msg(ilm); -+ if (MTK_WCN_BOOL_FALSE == bRet) { -+ WMT_ERR_FUNC("wmt handing idc msg fail\n"); -+ return -2; -+ } -+ } else { -+ WMT_INFO_FUNC("Received LTE msg,but STP is not ready,drop it!\n"); -+ } -+ return 0; -+} -+ -+VOID wmt_idc_dump_debug_msg(UINT8 *str, UINT8 *p_buf, UINT32 buf_len) -+{ -+ UINT32 idx = 0; -+ -+ WMT_DBG_FUNC("%s:, length:%d\n", str, buf_len); -+ -+ WMT_DBG_FUNC("ASCII output:\n"); -+ -+ for (idx = 0; idx < buf_len;) { -+ WMT_DBG_FUNC("%c", p_buf[idx]); -+ idx++; -+ if (0 == idx % 16) -+ WMT_DBG_FUNC("\n"); -+ } -+ -+ WMT_DBG_FUNC("HEX output:\n"); -+ -+ for (idx = 0; idx < buf_len;) { -+ WMT_DBG_FUNC("%02x ", p_buf[idx]); -+ idx++; -+ if (0 == idx % 16) -+ WMT_DBG_FUNC("\n"); -+ } -+} -+ -+INT32 wmt_idc_msg_to_lte_handing(VOID) -+{ -+ UINT32 readlen = 0; -+ local_para_struct *p_lps = NULL; -+ UINT8 *p_data = NULL; -+ UINT8 opcode = 0; -+ UINT16 msg_len = 0; -+ UINT32 handle_len = 0; -+#if CFG_WMT_LTE_ENABLE_MSGID_MAPPING -+ MTK_WCN_BOOL unknown_msgid = MTK_WCN_BOOL_FALSE; -+#endif -+ readlen = mtk_wcn_stp_receive_data(&gWmtIdcInfo.buffer[0], LTE_IDC_BUFFER_MAX_SIZE, COEX_TASK_INDX); -+ if (readlen == 0) { -+ osal_sleep_ms(5); -+ readlen = mtk_wcn_stp_receive_data(&gWmtIdcInfo.buffer[0], LTE_IDC_BUFFER_MAX_SIZE, COEX_TASK_INDX); -+ } -+ -+ if (readlen > 0) { -+ WMT_DBG_FUNC("read data len from fw(%d)\n", readlen); -+ wmt_idc_dump_debug_msg("WMT->LTE from STP buffer", &gWmtIdcInfo.buffer[0], readlen); -+ p_data = &gWmtIdcInfo.buffer[0]; -+ -+ while (handle_len < readlen) { -+ p_data += 2; /*omit direction & opcode 2 bytes */ -+ osal_memcpy(&msg_len, p_data, 2); -+ msg_len -= 1; /*flag byte */ -+ WMT_DBG_FUNC("current raw data len(%d) from connsys firmware\n", msg_len); -+ -+ p_data += 2; /*length: 2 bytes */ -+ -+ /*how to handle flag(msg type) need to Scott comment */ -+ /************************************************/ -+ -+ if (*p_data == WMT_IDC_RX_OPCODE_DEBUG_MONITOR) -+ /*do not need transfer to LTE */ -+ { -+ p_data += 1; /*flag : 1 byte */ -+ /*need to handle these debug message */ -+ wmt_idc_dump_debug_msg("WIFI DEBUG MONITOR", p_data, msg_len); -+ } else -+ /*need to transfer to LTE */ -+ { -+ p_lps = -+ (local_para_struct *) osal_malloc(osal_sizeof(local_para_struct) + -+ osal_sizeof(UINT8) * msg_len); -+ if (NULL == p_lps) { -+ WMT_ERR_FUNC("allocate local_para_struct memory fail\n"); -+ return -1; -+ } -+ -+ p_lps->msg_len = msg_len + osal_sizeof(local_para_struct); -+ -+ opcode = *p_data; -+ WMT_DBG_FUNC("current opcode(%d) to LTE\n", opcode); -+ -+ p_data += 1; /*flag : 1 byte */ -+ osal_memcpy(p_lps->data, p_data, msg_len); -+ -+ gWmtIdcInfo.iit.local_para_ptr = p_lps; -+ -+#if CFG_WMT_LTE_ENABLE_MSGID_MAPPING -+ switch (opcode) { -+ case WMT_IDC_RX_OPCODE_BTWF_DEF_PARA: -+ gWmtIdcInfo.iit.msg_id = IPC_MSG_ID_EL1_WIFIBT_OPER_DEFAULT_PARAM_IND; -+ break; -+ case WMT_IDC_RX_OPCODE_BTWF_CHAN_RAN: -+ gWmtIdcInfo.iit.msg_id = IPC_MSG_ID_EL1_WIFIBT_OPER_FREQ_IND; -+ break; -+ case WMT_IDC_RX_OPCODE_LTE_FREQ_IDX_TABLE: -+ gWmtIdcInfo.iit.msg_id = IPC_MSG_ID_EL1_WIFIBT_FREQ_IDX_TABLE_IND; -+ break; -+ case WMT_IDC_RX_OPCODE_BTWF_PROFILE_IND: -+ gWmtIdcInfo.iit.msg_id = IPC_MSG_ID_EL1_WIFIBT_PROFILE_IND; -+ break; -+ case WMT_IDC_RX_OPCODE_UART_PIN_SEL: -+ gWmtIdcInfo.iit.msg_id = IPC_MSG_ID_EL1_PIN_TYPE_IND; -+ break; -+ /* case WMT_IDC_RX_OPCODE_TDM_REQ: */ -+ /* gWmtIdcInfo.iit.msg_id = IPC_MSG_ID_EL1_WIFIBT_OPER_FREQ_IND; */ -+ /* break; */ -+ default: -+ unknown_msgid = MTK_WCN_BOOL_TRUE; -+ WMT_ERR_FUNC("unknown opcode(%d) from connsys firmware\n", opcode); -+ break; -+ } -+ if (MTK_WCN_BOOL_FALSE == unknown_msgid) { -+ /*handling flag value in wmt cmd */ -+ mtk_conn_md_bridge_send_msg(&gWmtIdcInfo.iit); -+ } -+#else -+ if (opcode >= LTE_MSG_ID_OFFSET) { -+ gWmtIdcInfo.iit.msg_id = opcode + IPC_EL1_MSG_ID_BEGIN - LTE_MSG_ID_OFFSET + 1; -+ /*handling flag value in wmt cmd */ -+ mtk_conn_md_bridge_send_msg(&gWmtIdcInfo.iit); -+ WMT_DBG_FUNC("CONN->LTE: (0x%x->0x%x)\n", opcode, gWmtIdcInfo.iit.msg_id); -+ } else { -+ WMT_ERR_FUNC("opcode(%d)from connsys fw is out of range,drop it!\n", opcode); -+ } -+#endif -+ osal_free(p_lps); -+ } -+ -+ p_data += msg_len; /*point to next package header */ -+ -+ handle_len += (msg_len + 5); -+ } -+ -+ } else { -+ WMT_ERR_FUNC("there is no coex data in stp buffer\n"); -+ } -+ -+ osal_memset(&gWmtIdcInfo.buffer[0], 0, LTE_IDC_BUFFER_MAX_SIZE); -+ -+ return 0; -+} -+ -+UINT32 wmt_idc_msg_to_lte_handing_for_test(UINT8 *p_buf, UINT32 len) -+{ -+ UINT32 readlen = len; -+ local_para_struct *p_lps = NULL; -+ UINT8 *p_data = NULL; -+ UINT8 opcode = 0; -+ UINT16 msg_len = 0; -+ UINT32 handle_len = 0; -+ MTK_WCN_BOOL unknown_msgid = MTK_WCN_BOOL_FALSE; -+ -+ osal_memcpy(&gWmtIdcInfo.buffer[0], p_buf, len); -+ -+ if (readlen > 0) { -+ WMT_DBG_FUNC("read data len from fw(%d)\n", readlen); -+ p_data = &gWmtIdcInfo.buffer[0]; -+ -+ while (handle_len < readlen) { -+ p_data += 2; /*omit direction & opcode 2 bytes */ -+ osal_memcpy(&msg_len, p_data, 2); -+ msg_len -= 1; /*flag byte */ -+ WMT_DBG_FUNC("current raw data len(%d) from connsys firmware\n", msg_len); -+ -+ p_data += 2; /*length: 2 bytes */ -+ -+ /*how to handle flag(msg type) need to Scott comment */ -+ /************************************************/ -+ -+ if (*p_data == WMT_IDC_RX_OPCODE_DEBUG_MONITOR) -+ /*do not need transfer to LTE */ -+ { -+ p_data += 1; /*flag : 1 byte */ -+ /*need to handle these debug message */ -+ wmt_idc_dump_debug_msg("WIFI DEBUG MONITOR", p_data, msg_len); -+ } else -+ /*need to transfer to LTE */ -+ { -+ p_lps = -+ (local_para_struct *) osal_malloc(osal_sizeof(local_para_struct) + -+ osal_sizeof(UINT8) * msg_len); -+ if (NULL == p_lps) { -+ WMT_ERR_FUNC("allocate local_para_struct memory fail\n"); -+ return -1; -+ } -+ -+ p_lps->msg_len = msg_len + osal_sizeof(local_para_struct); -+ -+ opcode = *p_data; -+ WMT_DBG_FUNC("current opcode(%d) to LTE\n", opcode); -+ -+ p_data += 1; /*flag : 1 byte */ -+ osal_memcpy(p_lps->data, p_data, msg_len); -+ -+ gWmtIdcInfo.iit.local_para_ptr = p_lps; -+ -+ switch (opcode) { -+ case WMT_IDC_RX_OPCODE_BTWF_DEF_PARA: -+ gWmtIdcInfo.iit.msg_id = IPC_MSG_ID_EL1_WIFIBT_OPER_DEFAULT_PARAM_IND; -+ break; -+ case WMT_IDC_RX_OPCODE_BTWF_CHAN_RAN: -+ gWmtIdcInfo.iit.msg_id = IPC_MSG_ID_EL1_WIFIBT_OPER_FREQ_IND; -+ break; -+ /* case WMT_IDC_RX_OPCODE_TDM_REQ: */ -+ /* gWmtIdcInfo.iit.msg_id = IPC_MSG_ID_EL1_WIFIBT_OPER_FREQ_IND; */ -+ /* break; */ -+ default: -+ unknown_msgid = MTK_WCN_BOOL_TRUE; -+ WMT_ERR_FUNC("unknown opcode(%d) from connsys firmware\n", opcode); -+ break; -+ } -+ if (MTK_WCN_BOOL_FALSE == unknown_msgid) { -+ /*handling flag value in wmt cmd */ -+ mtk_conn_md_bridge_send_msg(&gWmtIdcInfo.iit); -+ } -+ osal_free(p_lps); -+ } -+ -+ p_data += msg_len; /*point to next package header */ -+ -+ handle_len += (msg_len + 5); -+ } -+ -+ } else { -+ WMT_ERR_FUNC("there is no coex data in stp buffer\n"); -+ } -+ -+ osal_memset(&gWmtIdcInfo.buffer[0], 0, LTE_IDC_BUFFER_MAX_SIZE); -+ -+ return handle_len; -+} -+ -+#endif -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/mt7623/Makefile b/drivers/misc/mediatek/connectivity/common/conn_soc/mt7623/Makefile -new file mode 100644 -index 000000000000..c201e8291b8e ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/mt7623/Makefile -@@ -0,0 +1,25 @@ -+# WMT HAL driver for MT7623 -+ -+ccflags-y += \ -+ -I$(src)/include \ -+ -I$(src)/../linux/include \ -+ -I$(src)/../include \ -+ -I$(src)/../../common_detect -+ -+ ifeq ($(CONFIG_MTK_CLKMGR),y) -+ ccflags-y += -I$(srctree)/drivers/misc/mediatek/include/mt-plat/$(MTK_PLATFORM)/include/mach -+ endif -+ #ifeq ($(CONFIG_MTK_EMI_MPU),y) -+ ccflags-y += -I$(srctree)/drivers/misc/mediatek/include/mt-plat/$(MTK_PLATFORM)/include/mach -+ #endif -+ -+subdir-ccflags-y += -D MTK_WCN_WMT_STP_EXP_SYMBOL_ABSTRACT -+ -+ifeq ($(CONFIG_MTK_CONN_LTE_IDC_SUPPORT),y) -+ subdir-ccflags-y += -DWMT_IDC_SUPPORT=1 -+else -+ subdir-ccflags-y += -DWMT_IDC_SUPPORT=0 -+endif -+ -+obj-y += mtk_wcn_consys_hw.o -+obj-y += wmt_plat_alps.o -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/mt7623/include/mtk_wcn_consys_hw.h b/drivers/misc/mediatek/connectivity/common/conn_soc/mt7623/include/mtk_wcn_consys_hw.h -new file mode 100644 -index 000000000000..94d6af9d0b3e ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/mt7623/include/mtk_wcn_consys_hw.h -@@ -0,0 +1,287 @@ -+/*! \file -+ \brief Declaration of library functions -+ -+ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. -+*/ -+ -+#ifndef _MTK_WCN_CONSYS_HW_H_ -+#define _MTK_WCN_CONSYS_HW_H_ -+ -+#include -+/*#include */ -+#include "wmt_plat.h" -+ -+/*device tree mode*/ -+#ifdef CONFIG_OF -+/* #if 1 */ -+#include -+#include -+#include -+#include -+#endif -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+#define CONSYS_BT_WIFI_SHARE_V33 0 -+#define CONSYS_PMIC_CTRL_ENABLE 1 -+#define CONSYS_PMIC_CTRL_UPMU 1 -+#define CONSYS_EMI_MPU_SETTING 0 -+#define CONSYS_AHB_CLK_MAGEMENT 1 -+#define CONSYS_USE_PLATFORM_WRITE 1 -+#define CONSYS_PWR_ON_OFF_API_AVAILABLE 1 -+#define CONSYS_CLOCK_BUF_CTRL 0 -+#if defined(CONFIG_MTK_LEGACY) -+#define CONFIG_MTK_PMIC_LEGACY 0 -+#endif -+#define CONFIG_RESET_CONTROL 1 -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/*tag start:new platform need to make sure these define */ -+#define PLATFORM_SOC_CHIP 0x7623 -+/*tag end*/ -+ -+#ifdef CONFIG_OF -+ -+struct CONSYS_BASE_ADDRESS { -+ SIZE_T mcu_base; -+ SIZE_T ap_rgu_base; -+ SIZE_T topckgen_base; -+ SIZE_T spm_base; -+}; -+ -+/*TOPCKGEN_BASE*/ -+#define CONSYS_TOP_CLKCG_CLR_OFFSET 0x00000084 -+#define CONSYS_TOP_CLKCG_SET_OFFSET 0x00000054 -+#define CONSYS_WD_SYS_RST_OFFSET 0x00000018 -+#define CONSYS_AP2CONN_OSC_EN_OFFSET 0x00000800 -+#define CONSYS_EMI_MAPPING_OFFSET 0x00000310 -+/*AP_RGU_BASE*/ -+#define CONSYS_CPU_SW_RST_OFFSET 0x00000018 -+/*SPM_BASE*/ -+#define CONSYS_PWRON_CONFG_EN_OFFSET 0x00000000 -+#define CONSYS_TOP1_PWR_CTRL_OFFSET 0x00000280 -+#define CONSYS_PWR_CONN_ACK_OFFSET 0x0000060c -+#define CONSYS_PWR_CONN_ACK_S_OFFSET 0x00000610 -+/*CONN_MCU_CONFIG_BASE*/ -+#define CONSYS_CHIP_ID_OFFSET 0x00000008 -+#define CONSYS_ROM_RAM_DELSEL_OFFSET 0x00000114 -+#define CONSYS_MCU_CFG_ACR_OFFSET 0x00000110 -+#define CONSYS_CPUPCR_OFFSET 0x00000160 -+/*AXI bus*/ -+ -+#define CONSYS_TOPAXI_PROT_EN_OFFSET 0x1220 -+#define CONSYS_TOPAXI_PROT_STA1_OFFSET 0x0228 -+#endif -+ -+#define CONSYS_SET_BIT(REG, BITVAL) (*((volatile UINT32*)(REG)) |= ((UINT32)(BITVAL))) -+#define CONSYS_CLR_BIT(REG, BITVAL) ((*(volatile UINT32*)(REG)) &= ~((UINT32)(BITVAL))) -+#define CONSYS_CLR_BIT_WITH_KEY(REG, BITVAL, KEY) {\ -+ UINT32 val = (*(volatile UINT32*)(REG)); \ -+ val &= ~((UINT32)(BITVAL)); \ -+ val |= ((UINT32)(KEY)); \ -+ (*(volatile UINT32*)(REG)) = val;\ -+} -+#define CONSYS_REG_READ(addr) (*((volatile UINT32*)(addr))) -+#if CONSYS_USE_PLATFORM_WRITE -+#define CONSYS_REG_WRITE(addr, data) mt_reg_sync_writel(data, addr) -+#else -+#define CONSYS_REG_WRITE(addr, data) (*((volatile UINT32*)(addr)) = (UINT32)(data)) -+#endif -+ -+/*tag start: connsys register base address (hard code, no use) */ -+#define AP_RGU_BASE 0xF0007000 -+#define TOPCKGEN_BASE 0xF0000000 -+#define SPM_BASE 0xF0006000 -+#define CONN_MCU_CONFIG_BASE 0xF8070000 -+/*GIC Interrupt ID*/ -+#define MT_CONN2AP_BTIF_WAKEUP_IRQ_ID 237 -+/*tag end*/ -+ -+/*connsys register offset define(hard code mode)*/ -+#if 1 -+ /*top clock gating control register */ -+#define CONSYS_TOP_CLKCG_CLR_REG (TOPCKGEN_BASE + 0x00000084) -+#define CONSYS_TOP_CLKCG_SET_REG (TOPCKGEN_BASE + 0x00000054) -+#define CONSYS_TOP_CLKCG_BIT (0x1 << 26) -+ -+ /*SPM clock gating control register */ -+#define CONSYS_PWRON_CONFG_EN_REG (SPM_BASE + 0x00000000) -+#define CONSYS_PWRON_CONFG_EN_VALUE (0x0b160001) -+#define CONSYS_PWRON_CONFG_DIS_VALUE (0x0b160000) -+#endif -+ -+#define CONSYS_CPU_SW_RST_REG (AP_RGU_BASE + 0x00000018) -+#define CONSYS_TOP1_PWR_CTRL_REG (SPM_BASE + 0x00000280) -+#define CONSYS_PWR_CONN_ACK_REG (SPM_BASE + 0x0000060c) -+#define CONSYS_PWR_CONN_ACK_S_REG (SPM_BASE + 0x00000610) -+ -+#define CONSYS_WD_SYS_RST_REG (TOPCKGEN_BASE + 0x00000018) -+#define CONSYS_CHIP_ID_REG (CONN_MCU_CONFIG_BASE + 0x00000008) -+#define CONSYS_ROM_RAM_DELSEL_REG (CONN_MCU_CONFIG_BASE + 0x00000114) -+#define CONSYS_MCU_CFG_ACR_REG (CONN_MCU_CONFIG_BASE + 0x00000110) -+#define CONSYS_AFE_REG (CONN_TOP_CR_BASE + 0x00002000) -+#define CONSYS_AFE_REG_DIG_RCK_01 (CONSYS_AFE_REG + 0x00000010) -+#define CONSYS_AFE_REG_WBG_PLL_02 (CONSYS_AFE_REG + 0x00000028) -+#define CONSYS_AFE_REG_WBG_WB_TX_01 (CONSYS_AFE_REG + 0x0000003c) -+#define CONSYS_AFE_REG_DIG_RCK_01_VALUE (0x174b0160) -+#define CONSYS_AFE_REG_WBG_PLL_02_VALUE (0x844083fe) -+#define CONSYS_AFE_REG_WBG_WB_TX_01_VALUE (0x7fc39a20) -+ -+#define CONSYS_TOPAXI_PROT_EN (TOPCKGEN_BASE + 0x0220) -+#define CONSYS_TOPAXI_PROT_STA1 (TOPCKGEN_BASE + 0x0228) -+#define CONSYS_PROT_MASK ((0x1<<13) | (0x1<<14) | (0x1<<15)) /* bit 13, 14, 15 */ -+/*CONSYS_CPU_SW_RST_REG*/ -+#define CONSYS_CPU_SW_RST_BIT (0x1 << 12) -+#define CONSYS_CPU_SW_RST_CTRL_KEY (0x88 << 24) -+ -+/*CONSYS_TOP1_PWR_CTRL_REG*/ -+#define CONSYS_SPM_PWR_RST_BIT (0x1 << 0) -+#define CONSYS_SPM_PWR_ISO_S_BIT (0x1 << 1) -+#define CONSYS_SPM_PWR_ON_BIT (0x1 << 2) -+#define CONSYS_SPM_PWR_ON_S_BIT (0x1 << 3) -+#define CONSYS_CLK_CTRL_BIT (0x1 << 4) -+#define CONSYS_SRAM_CONN_PD_BIT (0x1 << 8) -+ -+/*CONSYS_PWR_CONN_ACK_REG*/ -+#define CONSYS_PWR_ON_ACK_BIT (0x1 << 1) -+ -+/*CONSYS_PWR_CONN_ACK_S_REG*/ -+#define CONSYS_PWR_CONN_ACK_S_BIT (0x1 << 1) -+ -+/*CONSYS_WD_SYS_RST_REG*/ -+#define CONSYS_WD_SYS_RST_CTRL_KEY (0x88 << 24) -+#define CONSYS_WD_SYS_RST_BIT (0x1 << 9) -+ -+/*CONSYS_MCU_CFG_ACR_REG*/ -+#define CONSYS_MCU_CFG_ACR_MBIST_BIT (0x1 << 18) -+ -+/* EMI part mapping & ctrl*/ -+#define KBYTE (1024*sizeof(char)) -+#define CONSYS_EMI_AP_PHY_OFFSET (0x80000) -+#define CONSYS_EMI_AP_PHY_BASE (0x80080000) -+#define CONSYS_EMI_FW_PHY_BASE (0xf0080000) -+#define CONSYS_EMI_MEM_SIZE (343*KBYTE) /*coredump space , 343K is enough */ -+#define CONSYS_EMI_PAGED_TRACE_OFFSET (0x400) -+#define CONSYS_EMI_PAGED_DUMP_OFFSET (0x8400) -+#define CONSYS_EMI_FULL_DUMP_OFFSET (0x10400) -+ -+/*cpupcr*/ -+#define CONSYS_CPUPCR_REG (CONN_MCU_CONFIG_BASE + 0x00000160) -+/*emi mapping*/ -+#define CONSYS_EMI_MAPPING (TOPCKGEN_BASE + 0x1310) -+ -+/*control app2cnn_osc_en*/ -+#define CONSYS_AP2CONN_OSC_EN_REG (TOPCKGEN_BASE + 0x00001800) -+#define CONSYS_AP2CONN_OSC_EN_BIT (0x1 << 16) -+#define CONSYS_AP2CONN_WAKEUP_BIT (0x1 << 17) -+ -+/*paged dump address start*/ -+#define CONSYS_PAGED_DUMP_START_ADDR (0xf0088400) -+#define CONSYS_PAGED_DUMP_SIZE (32*KBYTE) -+ -+/*full dump address start*/ -+#define CONSYS_FULL_DUMP_START_ADDR (0xf0090400) -+#define CONSYS_FULL_DUMP_DLM_LEN (0x1f000) -+#define CONSYS_FULL_DUMP_SYSB2_START (CONSYS_FULL_DUMP_START_ADDR + CONSYS_FULL_DUMP_DLM_LEN) -+#define CONSYS_FULL_DUMP_SYSB2_LEN (0x6800) -+#define CONSYS_FULL_DUMP_SYSB3_START (CONSYS_FULL_DUMP_SYSB2_START + CONSYS_FULL_DUMP_SYSB2_LEN) -+#define CONSYS_FULL_DUMP_SYSB3_LEN (0x16800) -+ -+/*force fw assert pattern*/ -+#define EXP_APMEM_HOST_OUTBAND_ASSERT_MAGIC_W1 (0x19b30bb1) -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+typedef enum _ENUM_EMI_CTRL_STATE_OFFSET_ { -+ EXP_APMEM_CTRL_STATE = 0x0, -+ EXP_APMEM_CTRL_HOST_SYNC_STATE = 0x4, -+ EXP_APMEM_CTRL_HOST_SYNC_NUM = 0x8, -+ EXP_APMEM_CTRL_CHIP_SYNC_STATE = 0xc, -+ EXP_APMEM_CTRL_CHIP_SYNC_NUM = 0x10, -+ EXP_APMEM_CTRL_CHIP_SYNC_ADDR = 0x14, -+ EXP_APMEM_CTRL_CHIP_SYNC_LEN = 0x18, -+ EXP_APMEM_CTRL_CHIP_PRINT_BUFF_START = 0x1c, -+ EXP_APMEM_CTRL_CHIP_PRINT_BUFF_LEN = 0x20, -+ EXP_APMEM_CTRL_CHIP_PRINT_BUFF_IDX = 0x24, -+ EXP_APMEM_CTRL_CHIP_INT_STATUS = 0x28, -+ EXP_APMEM_CTRL_CHIP_PAGED_DUMP_END = 0x2c, -+ EXP_APMEM_CTRL_HOST_OUTBAND_ASSERT_W1 = 0x30, -+ EXP_APMEM_CTRL_CHIP_DYNAMIC_DUMP = 0x48, -+ EXP_APMEM_CTRL_MAX -+} ENUM_EMI_CTRL_STATE_OFFSET, *P_ENUM_EMI_CTRL_STATE_OFFSET; -+ -+#if CONSYS_BT_WIFI_SHARE_V33 -+typedef struct _BT_WIFI_V33_STATUS_ { -+ UINT32 counter; -+ UINT32 flags; -+ spinlock_t lock; -+} BT_WIFI_V33_STATUS; -+ -+#endif -+ -+typedef enum _CONSYS_GPS_CO_CLOCK_TYPE_ { -+ GPS_TCXO_TYPE = 0, -+ GPS_CO_TSX_TYPE = 1, -+ GPS_CO_DCXO_TYPE = 2, -+ GPS_CO_VCTCXO_TYPE = 3, -+ GPS_CO_CLOCK_TYPE_MAX -+} CONSYS_GPS_CO_CLOCK_TYPE, *P_CONSYS_GPS_CO_CLOCK_TYPE; -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+extern struct CONSYS_BASE_ADDRESS conn_reg; -+#if CONSYS_BT_WIFI_SHARE_V33 -+extern BT_WIFI_V33_STATUS gBtWifiV33; -+#endif -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+extern INT32 mtk_wcn_consys_hw_init(VOID); -+extern INT32 mtk_wcn_consys_hw_deinit(VOID); -+extern INT32 mtk_wcn_consys_hw_pwr_off(VOID); -+extern INT32 mtk_wcn_consys_hw_pwr_on(UINT32 co_clock_type); -+extern INT32 mtk_wcn_consys_hw_rst(UINT32 co_clock_type); -+extern INT32 mtk_wcn_consys_hw_bt_paldo_ctrl(UINT32 enable); -+extern INT32 mtk_wcn_consys_hw_wifi_paldo_ctrl(UINT32 enable); -+extern INT32 mtk_wcn_consys_hw_vcn28_ctrl(UINT32 enable); -+extern INT32 mtk_wcn_consys_hw_state_show(VOID); -+extern UINT8 *mtk_wcn_consys_emi_virt_addr_get(UINT32 ctrl_state_offset); -+#if CONSYS_ENALBE_SET_JTAG -+extern UINT32 mtk_wcn_consys_jtag_flag_ctrl(UINT32 en); -+#endif -+extern UINT32 mtk_wcn_consys_soc_chipid(VOID); -+#if !defined(CONFIG_MTK_GPIO_LEGACY) -+extern struct pinctrl *mtk_wcn_consys_get_pinctrl(VOID); -+#endif -+extern INT32 mtk_wcn_consys_set_dynamic_dump(PUINT32 buf); -+#endif /* _MTK_WCN_CMB_HW_H_ */ -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/mt7623/mtk_wcn_consys_hw.c b/drivers/misc/mediatek/connectivity/common/conn_soc/mt7623/mtk_wcn_consys_hw.c -new file mode 100644 -index 000000000000..191f7312f897 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/mt7623/mtk_wcn_consys_hw.c -@@ -0,0 +1,737 @@ -+/*! \file -+ \brief Declaration of library functions -+ -+ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+#ifdef DFT_TAG -+#undef DFT_TAG -+#endif -+#define DFT_TAG "[WMT-CONSYS-HW]" -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include -+#include -+#include -+#include "osal_typedef.h" -+#include "mtk_wcn_consys_hw.h" -+#include -+#include -+#include -+#if CONSYS_EMI_MPU_SETTING -+#include -+#endif -+ -+#include -+#ifdef CONFIG_MTK_HIBERNATION -+#include -+#endif -+ -+#include -+ -+#if CONSYS_CLOCK_BUF_CTRL -+#include -+#endif -+ -+#include -+#include -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+static INT32 mtk_wmt_probe(struct platform_device *pdev); -+static INT32 mtk_wmt_remove(struct platform_device *pdev); -+ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+struct CONSYS_BASE_ADDRESS conn_reg; -+static phys_addr_t gConEmiPhyBase; -+static UINT8 __iomem *pEmibaseaddr; -+static struct clk *clk_infra_conn_main; /*ctrl infra_connmcu_bus clk */ -+static struct platform_device *my_pdev; -+static struct reset_control *rstc; -+static struct regulator *reg_VCN18; -+static struct regulator *reg_VCN28; -+static struct regulator *reg_VCN33_BT; -+static struct regulator *reg_VCN33_WIFI; -+static struct pinctrl *consys_pinctrl; -+static struct pinctrl *mt6625_spi_pinctrl; -+static struct pinctrl_state *mt6625_spi_default; -+static struct regmap *pmic_regmap; -+#define DYNAMIC_DUMP_GROUP_NUM 5 -+ -+static const struct of_device_id apwmt_of_ids[] = { -+ {.compatible = "mediatek,mt7623-consys",} -+}; -+MODULE_DEVICE_TABLE(of, apwmt_of_ids); -+ -+static struct platform_driver mtk_wmt_dev_drv = { -+ .probe = mtk_wmt_probe, -+ .remove = mtk_wmt_remove, -+ .driver = { -+ .name = "mt7623consys", -+ .owner = THIS_MODULE, -+ .of_match_table = of_match_ptr(apwmt_of_ids), -+ }, -+}; -+ -+static INT32 mtk_wmt_probe(struct platform_device *pdev) -+{ -+ int ret = 0; -+ struct device_node *node = NULL; -+ -+ pm_runtime_enable(&pdev->dev); -+ my_pdev = pdev; -+ mt6625_spi_pinctrl = devm_pinctrl_get(&pdev->dev); -+ if (IS_ERR(mt6625_spi_pinctrl)) { -+ ret = PTR_ERR(mt6625_spi_pinctrl); -+ WMT_PLAT_ERR_FUNC("Wmt cannot find pinctrl!\n"); -+ goto set_pin_exit; -+ } -+ mt6625_spi_default = pinctrl_lookup_state(mt6625_spi_pinctrl, "consys_pins_default"); -+ if (IS_ERR(mt6625_spi_default)) { -+ ret = PTR_ERR(mt6625_spi_default); -+ WMT_PLAT_ERR_FUNC("Wmt Cannot find pinctrl default!\n"); -+ goto set_pin_exit; -+ } -+ pinctrl_select_state(mt6625_spi_pinctrl, mt6625_spi_default); -+set_pin_exit: -+ -+ node = of_parse_phandle(pdev->dev.of_node, "mediatek,pwrap-regmap", 0); -+ if (node) { -+ pmic_regmap = pwrap_node_to_regmap(node); -+ if (IS_ERR(pmic_regmap)) -+ goto set_pmic_wrap_exit; -+ } else { -+ WMT_PLAT_ERR_FUNC("Pwrap node has not register regmap.\n"); -+ goto set_pmic_wrap_exit; -+ } -+set_pmic_wrap_exit: -+ -+ clk_infra_conn_main = devm_clk_get(&pdev->dev, "consysbus"); -+ if (IS_ERR(clk_infra_conn_main)) { -+ WMT_PLAT_ERR_FUNC("sean debug [CCF]cannot get clk_infra_conn_main clock.\n"); -+ return PTR_ERR(clk_infra_conn_main); -+ } -+ WMT_PLAT_DBG_FUNC("[CCF]clk_infra_conn_main=%p\n", clk_infra_conn_main); -+ -+ reg_VCN18 = devm_regulator_get(&pdev->dev, "vcn18"); -+ if (IS_ERR(reg_VCN18)) { -+ ret = PTR_ERR(reg_VCN18); -+ WMT_PLAT_ERR_FUNC("Regulator_get VCN_1V8 fail, ret=%d\n", ret); -+ } -+ reg_VCN28 = devm_regulator_get(&pdev->dev, "vcn28"); -+ if (IS_ERR(reg_VCN28)) { -+ ret = PTR_ERR(reg_VCN28); -+ WMT_PLAT_ERR_FUNC("Regulator_get VCN_2V8 fail, ret=%d\n", ret); -+ } -+ reg_VCN33_BT = devm_regulator_get(&pdev->dev, "vcn33_bt"); -+ if (IS_ERR(reg_VCN33_BT)) { -+ ret = PTR_ERR(reg_VCN33_BT); -+ WMT_PLAT_ERR_FUNC("Regulator_get VCN33_BT fail, ret=%d\n", ret); -+ } -+ reg_VCN33_WIFI = devm_regulator_get(&pdev->dev, "vcn33_wifi"); -+ if (IS_ERR(reg_VCN33_WIFI)) { -+ ret = PTR_ERR(reg_VCN33_WIFI); -+ WMT_PLAT_ERR_FUNC("Regulator_get VCN33_WIFI fail, ret=%d\n", ret); -+ } -+ -+ rstc = devm_reset_control_get(&pdev->dev, "connsys"); -+ if (IS_ERR(rstc)) { -+ ret = PTR_ERR(rstc); -+ WMT_PLAT_ERR_FUNC("CanNot get consys reset. ret=%d\n", ret); -+ return PTR_ERR(rstc); -+ } -+ -+ consys_pinctrl = devm_pinctrl_get(&pdev->dev); -+ if (IS_ERR(consys_pinctrl)) { -+ ret = PTR_ERR(consys_pinctrl); -+ WMT_PLAT_ERR_FUNC("CanNot find consys pinctrl. ret=%d\n", ret); -+ return PTR_ERR(consys_pinctrl); -+ } -+ return 0; -+} -+ -+static INT32 mtk_wmt_remove(struct platform_device *pdev) -+{ -+ pm_runtime_disable(&pdev->dev); -+ -+ return 0; -+} -+ -+VOID mtk_wcn_consys_power_on(VOID) -+{ -+ INT32 iRet = -1; -+printk(KERN_ALERT "DEBUG: Passed %s %d \n",__FUNCTION__,__LINE__); -+ iRet = pm_runtime_get_sync(&my_pdev->dev); -+printk(KERN_ALERT "DEBUG: Passed %s %d \n",__FUNCTION__,__LINE__); -+ if (iRet) -+ WMT_PLAT_ERR_FUNC("pm_runtime_get_sync() fail(%d)\n", iRet); -+ else -+ WMT_PLAT_INFO_FUNC("pm_runtime_get_sync() CONSYS ok\n"); -+ -+ iRet = device_init_wakeup(&my_pdev->dev, true); -+printk(KERN_ALERT "DEBUG: Passed %s %d \n",__FUNCTION__,__LINE__); -+ if (iRet) -+ WMT_PLAT_ERR_FUNC("device_init_wakeup(true) fail.\n"); -+ else -+ WMT_PLAT_INFO_FUNC("device_init_wakeup(true) CONSYS ok\n"); -+} -+ -+VOID mtk_wcn_consys_power_off(VOID) -+{ -+ INT32 iRet = -1; -+ -+ iRet = pm_runtime_put_sync(&my_pdev->dev); -+ if (iRet) -+ WMT_PLAT_ERR_FUNC("pm_runtime_put_sync() fail.\n"); -+ else -+ WMT_PLAT_INFO_FUNC("pm_runtime_put_sync() CONSYS ok\n"); -+ -+ iRet = device_init_wakeup(&my_pdev->dev, false); -+ if (iRet) -+ WMT_PLAT_ERR_FUNC("device_init_wakeup(false) fail.\n"); -+ else -+ WMT_PLAT_INFO_FUNC("device_init_wakeup(false) CONSYS ok\n"); -+} -+ -+INT32 mtk_wcn_consys_hw_reg_ctrl(UINT32 on, UINT32 co_clock_type) -+{ -+ UINT32 retry = 10; -+ UINT32 consysHwChipId = 0; -+ -+ WMT_PLAT_DBG_FUNC("CONSYS-HW-REG-CTRL(0x%08x),start\n", on); -+ if (on) { -+ WMT_PLAT_DBG_FUNC("++\n"); -+printk(KERN_ALERT "DEBUG: Passed %s %d \n",__FUNCTION__,__LINE__); -+ /*need PMIC driver provide new API protocol */ -+ /*1.AP power on VCN_1V8 LDO (with PMIC_WRAP API) VCN_1V8 */ -+ regulator_set_mode(reg_VCN18, REGULATOR_MODE_STANDBY); -+printk(KERN_ALERT "DEBUG: Passed %s %d \n",__FUNCTION__,__LINE__); -+ /* VOL_DEFAULT, VOL_1200, VOL_1300, VOL_1500, VOL_1800... */ -+ if (reg_VCN18) { -+printk(KERN_ALERT "DEBUG: Passed %s %d \n",__FUNCTION__,__LINE__); -+ regulator_set_voltage(reg_VCN18, 1800000, 1800000); -+printk(KERN_ALERT "DEBUG: Passed %s %d \n",__FUNCTION__,__LINE__); -+ if (regulator_enable(reg_VCN18)) -+ WMT_PLAT_ERR_FUNC("enable VCN18 fail\n"); -+ else -+ WMT_PLAT_DBG_FUNC("enable VCN18 ok\n"); -+ } -+ udelay(150); -+printk(KERN_ALERT "DEBUG: Passed %s %d \n",__FUNCTION__,__LINE__); -+ if (co_clock_type) { -+ /*step0,clk buf ctrl */ -+ WMT_PLAT_INFO_FUNC("co clock type(%d),turn on clk buf\n", co_clock_type); -+#if CONSYS_CLOCK_BUF_CTRL -+ clk_buf_ctrl(CLK_BUF_CONN, 1); -+#endif -+ /*if co-clock mode: */ -+ /*2.set VCN28 to SW control mode (with PMIC_WRAP API) */ -+ /*turn on VCN28 LDO only when FMSYS is activated" */ -+ regmap_update_bits(pmic_regmap, 0x41C, 0x1 << 14, 0x0 << 14);/*V28*/ -+ } else { -+ /*if NOT co-clock: */ -+ /*2.1.switch VCN28 to HW control mode (with PMIC_WRAP API) */ -+ regmap_update_bits(pmic_regmap, 0x41C, 0x1 << 14, 0x1 << 14);/*V28*/ -+ /*2.2.turn on VCN28 LDO (with PMIC_WRAP API)" */ -+ /*fix vcn28 not balance warning */ -+ if (reg_VCN28) { -+ regulator_set_voltage(reg_VCN28, 2800000, 2800000); -+ if (regulator_enable(reg_VCN28)) -+ WMT_PLAT_ERR_FUNC("enable VCN_2V8 fail!\n"); -+ else -+ WMT_PLAT_DBG_FUNC("enable VCN_2V8 ok\n"); -+ } -+ } -+ -+ /*3.assert CONNSYS CPU SW reset 0x10007018 "[12]=1'b1 [31:24]=8'h88 (key)" */ -+printk(KERN_ALERT "DEBUG: Passed %s %d \n",__FUNCTION__,__LINE__); -+ reset_control_reset(rstc); -+printk(KERN_ALERT "DEBUG: Passed %s %d \n",__FUNCTION__,__LINE__); -+ mtk_wcn_consys_power_on(); -+printk(KERN_ALERT "DEBUG: Passed %s %d \n",__FUNCTION__,__LINE__); -+ /*11.26M is ready now, delay 10us for mem_pd de-assert */ -+ udelay(10); -+ /*enable AP bus clock : connmcu_bus_pd API: enable_clock() ++?? */ -+ clk_prepare_enable(clk_infra_conn_main); -+printk(KERN_ALERT "DEBUG: Passed %s %d \n",__FUNCTION__,__LINE__); -+ WMT_PLAT_DBG_FUNC("[CCF]enable clk_infra_conn_main\n"); -+ /*12.poll CONNSYS CHIP ID until chipid is returned 0x18070008 */ -+ while (retry-- > 0) { -+ consysHwChipId = CONSYS_REG_READ(conn_reg.mcu_base + CONSYS_CHIP_ID_OFFSET) - 0xf6d; -+ -+ if ((consysHwChipId == 0x0321) || (consysHwChipId == 0x0335) || (consysHwChipId == 0x0337)) { -+ WMT_PLAT_INFO_FUNC("retry(%d)consys chipId(0x%08x)\n", retry, consysHwChipId); -+ break; -+ } -+ if ((consysHwChipId == 0x8163) || (consysHwChipId == 0x8127) || (consysHwChipId == 0x7623)) { -+ WMT_PLAT_INFO_FUNC("retry(%d)consys chipId(0x%08x)\n", retry, consysHwChipId); -+ break; -+ } -+ -+ WMT_PLAT_ERR_FUNC("Read CONSYS chipId(0x%08x)", consysHwChipId); -+ msleep(20); -+ } -+ -+ if ((0 == retry) || (0 == consysHwChipId)) -+ WMT_PLAT_ERR_FUNC("Maybe has a consys power on issue,(0x%08x)\n", consysHwChipId); -+ -+ msleep(40); -+ -+ } else { -+ -+ clk_disable_unprepare(clk_infra_conn_main); -+ WMT_PLAT_DBG_FUNC("[CCF] clk_disable_unprepare(clk_infra_conn_main) calling\n"); -+ mtk_wcn_consys_power_off(); -+ -+ if (co_clock_type) { -+ /*VCN28 has been turned off by GPS OR FM */ -+#if CONSYS_CLOCK_BUF_CTRL -+ clk_buf_ctrl(CLK_BUF_CONN, 0); -+#endif -+ } else { -+ regmap_update_bits(pmic_regmap, 0x41C, 0x1 << 14, 0x0 << 14);/*V28*/ -+ /*turn off VCN28 LDO (with PMIC_WRAP API)" */ -+ if (reg_VCN28) { -+ if (regulator_disable(reg_VCN28)) -+ WMT_PLAT_ERR_FUNC("disable VCN_2V8 fail!\n"); -+ else -+ WMT_PLAT_DBG_FUNC("disable VCN_2V8 ok\n"); -+ } -+ } -+ -+ /*AP power off MT6625L VCN_1V8 LDO */ -+ regulator_set_mode(reg_VCN18, REGULATOR_MODE_STANDBY); -+ if (reg_VCN18) { -+ if (regulator_disable(reg_VCN18)) -+ WMT_PLAT_ERR_FUNC("disable VCN_1V8 fail!\n"); -+ else -+ WMT_PLAT_DBG_FUNC("disable VCN_1V8 ok\n"); -+ } -+ -+ } -+ WMT_PLAT_DBG_FUNC("CONSYS-HW-REG-CTRL(0x%08x),finish\n", on); -+ return 0; -+} -+ -+INT32 mtk_wcn_consys_hw_gpio_ctrl(UINT32 on) -+{ -+ INT32 iRet = 0; -+ -+ WMT_PLAT_DBG_FUNC("CONSYS-HW-GPIO-CTRL(0x%08x), start\n", on); -+ -+ if (on) { -+ -+ /* TODO: [FixMe][GeorgeKuo] double check if BGF_INT is implemented ok */ -+ /* iRet += wmt_plat_gpio_ctrl(PIN_BGF_EINT, PIN_STA_MUX); */ -+ iRet += wmt_plat_eirq_ctrl(PIN_BGF_EINT, PIN_STA_INIT); -+ iRet += wmt_plat_eirq_ctrl(PIN_BGF_EINT, PIN_STA_EINT_DIS); -+ WMT_PLAT_DBG_FUNC("CONSYS-HW, BGF IRQ registered and disabled\n"); -+ -+ } else { -+ -+ /* set bgf eint/all eint to deinit state, namely input low state */ -+ iRet += wmt_plat_eirq_ctrl(PIN_BGF_EINT, PIN_STA_EINT_DIS); -+ iRet += wmt_plat_eirq_ctrl(PIN_BGF_EINT, PIN_STA_DEINIT); -+ WMT_PLAT_DBG_FUNC("CONSYS-HW, BGF IRQ unregistered and disabled\n"); -+ /* iRet += wmt_plat_gpio_ctrl(PIN_BGF_EINT, PIN_STA_DEINIT); */ -+ } -+ WMT_PLAT_DBG_FUNC("CONSYS-HW-GPIO-CTRL(0x%08x), finish\n", on); -+ return iRet; -+ -+} -+ -+INT32 mtk_wcn_consys_hw_pwr_on(UINT32 co_clock_type) -+{ -+ INT32 iRet = 0; -+ -+ WMT_PLAT_INFO_FUNC("CONSYS-HW-PWR-ON, start\n"); -+ -+ iRet += mtk_wcn_consys_hw_reg_ctrl(1, co_clock_type); -+ iRet += mtk_wcn_consys_hw_gpio_ctrl(1); -+ -+ WMT_PLAT_INFO_FUNC("CONSYS-HW-PWR-ON, finish(%d)\n", iRet); -+ return iRet; -+} -+ -+INT32 mtk_wcn_consys_hw_pwr_off(VOID) -+{ -+ INT32 iRet = 0; -+ -+ WMT_PLAT_INFO_FUNC("CONSYS-HW-PWR-OFF, start\n"); -+ -+ iRet += mtk_wcn_consys_hw_reg_ctrl(0, 0); -+ iRet += mtk_wcn_consys_hw_gpio_ctrl(0); -+ -+ WMT_PLAT_INFO_FUNC("CONSYS-HW-PWR-OFF, finish(%d)\n", iRet); -+ return iRet; -+} -+ -+INT32 mtk_wcn_consys_hw_rst(UINT32 co_clock_type) -+{ -+ INT32 iRet = 0; -+ -+ WMT_PLAT_INFO_FUNC("CONSYS-HW, hw_rst start, eirq should be disabled before this step\n"); -+ -+ /*1. do whole hw power off flow */ -+ iRet += mtk_wcn_consys_hw_reg_ctrl(0, co_clock_type); -+ -+ /*2. do whole hw power on flow */ -+ iRet += mtk_wcn_consys_hw_reg_ctrl(1, co_clock_type); -+ -+ WMT_PLAT_INFO_FUNC("CONSYS-HW, hw_rst finish, eirq should be enabled after this step\n"); -+ return iRet; -+} -+ -+#if CONSYS_BT_WIFI_SHARE_V33 -+INT32 mtk_wcn_consys_hw_bt_paldo_ctrl(UINT32 enable) -+{ -+ /* spin_lock_irqsave(&gBtWifiV33.lock,gBtWifiV33.flags); */ -+ if (enable) { -+ if (1 == gBtWifiV33.counter) { -+ gBtWifiV33.counter++; -+ WMT_PLAT_DBG_FUNC("V33 has been enabled,counter(%d)\n", gBtWifiV33.counter); -+ } else if (2 == gBtWifiV33.counter) { -+ WMT_PLAT_DBG_FUNC("V33 has been enabled,counter(%d)\n", gBtWifiV33.counter); -+ } else { -+#if CONSYS_PMIC_CTRL_ENABLE -+ /*do BT PMIC on,depenency PMIC API ready */ -+ /*switch BT PALDO control from SW mode to HW mode:0x416[5]-->0x1 */ -+ /* VOL_DEFAULT, VOL_3300, VOL_3400, VOL_3500, VOL_3600 */ -+ hwPowerOn(MT6323_POWER_LDO_VCN33, VOL_3300, "wcn_drv"); -+ upmu_set_vcn33_on_ctrl_bt(1); -+#endif -+ WMT_PLAT_INFO_FUNC("WMT do BT/WIFI v3.3 on\n"); -+ gBtWifiV33.counter++; -+ } -+ -+ } else { -+ if (1 == gBtWifiV33.counter) { -+ /*do BT PMIC off */ -+ /*switch BT PALDO control from HW mode to SW mode:0x416[5]-->0x0 */ -+#if CONSYS_PMIC_CTRL_ENABLE -+ upmu_set_vcn33_on_ctrl_bt(0); -+ hwPowerDown(MT6323_POWER_LDO_VCN33, "wcn_drv"); -+#endif -+ WMT_PLAT_INFO_FUNC("WMT do BT/WIFI v3.3 off\n"); -+ gBtWifiV33.counter--; -+ } else if (2 == gBtWifiV33.counter) { -+ gBtWifiV33.counter--; -+ WMT_PLAT_DBG_FUNC("V33 no need disabled,counter(%d)\n", gBtWifiV33.counter); -+ } else { -+ WMT_PLAT_DBG_FUNC("V33 has been disabled,counter(%d)\n", gBtWifiV33.counter); -+ } -+ -+ } -+ /* spin_unlock_irqrestore(&gBtWifiV33.lock,gBtWifiV33.flags); */ -+ return 0; -+} -+ -+INT32 mtk_wcn_consys_hw_wifi_paldo_ctrl(UINT32 enable) -+{ -+ mtk_wcn_consys_hw_bt_paldo_ctrl(enable); -+ return 0; -+} -+ -+#else -+INT32 mtk_wcn_consys_hw_bt_paldo_ctrl(UINT32 enable) -+{ -+ -+ if (enable) { -+ /*do BT PMIC on,depenency PMIC API ready */ -+ /*switch BT PALDO control from SW mode to HW mode:0x416[5]-->0x1 */ -+ if (reg_VCN33_BT) { -+ regulator_set_voltage(reg_VCN33_BT, 3300000, 3300000); -+ if (regulator_enable(reg_VCN33_BT)) -+ WMT_PLAT_ERR_FUNC("WMT do BT PMIC on fail!\n"); -+ } -+ regmap_update_bits(pmic_regmap, 0x416, 0x1 << 5, 0x1 << 5);/*BT*/ -+ WMT_PLAT_INFO_FUNC("WMT do BT PMIC on\n"); -+ } else { -+ /*do BT PMIC off */ -+ /*switch BT PALDO control from HW mode to SW mode:0x416[5]-->0x0 */ -+ regmap_update_bits(pmic_regmap, 0x416, 0x1 << 5, 0x0 << 5);/*BT*/ -+ if (reg_VCN33_BT) -+ if (regulator_disable(reg_VCN33_BT)) -+ WMT_PLAT_ERR_FUNC("WMT do BT PMIC off fail!\n"); -+ WMT_PLAT_INFO_FUNC("WMT do BT PMIC off\n"); -+ } -+ -+ return 0; -+ -+} -+ -+INT32 mtk_wcn_consys_hw_wifi_paldo_ctrl(UINT32 enable) -+{ -+ -+ if (enable) { -+ /*do WIFI PMIC on,depenency PMIC API ready */ -+ /*switch WIFI PALDO control from SW mode to HW mode:0x418[14]-->0x1 */ -+ if (reg_VCN33_WIFI) { -+ regulator_set_voltage(reg_VCN33_WIFI, 3300000, 3300000); -+ if (regulator_enable(reg_VCN33_WIFI)) -+ WMT_PLAT_ERR_FUNC("WMT do WIFI PMIC on fail!\n"); -+ else -+ WMT_PLAT_INFO_FUNC("WMT do WIFI PMIC on !\n"); -+ } -+ regmap_update_bits(pmic_regmap, 0x418, 0x1 << 14, 0x1 << 14);/*WIFI*/ -+ WMT_PLAT_INFO_FUNC("WMT do WIFI PMIC on\n"); -+ } else { -+ /*do WIFI PMIC off */ -+ /*switch WIFI PALDO control from HW mode to SW mode:0x418[14]-->0x0 */ -+ regmap_update_bits(pmic_regmap, 0x418, 0x1 << 14, 0x0 << 14);/*WIFI*/ -+ if (reg_VCN33_WIFI) -+ if (regulator_disable(reg_VCN33_WIFI)) -+ WMT_PLAT_ERR_FUNC("WMT do WIFI PMIC off fail!\n"); -+ WMT_PLAT_INFO_FUNC("WMT do WIFI PMIC off\n"); -+ } -+ -+ return 0; -+} -+ -+#endif -+INT32 mtk_wcn_consys_hw_vcn28_ctrl(UINT32 enable) -+{ -+ if (enable) { -+ /*in co-clock mode,need to turn on vcn28 when fm on */ -+ if (reg_VCN28) { -+ regulator_set_voltage(reg_VCN28, 2800000, 2800000); -+ if (regulator_enable(reg_VCN28)) -+ WMT_PLAT_ERR_FUNC("WMT do VCN28 PMIC on fail!\n"); -+ } -+ WMT_PLAT_INFO_FUNC("turn on vcn28 for fm/gps usage in co-clock mode\n"); -+ } else { -+ /*in co-clock mode,need to turn off vcn28 when fm off */ -+ if (reg_VCN28) -+ if (regulator_disable(reg_VCN28)) -+ WMT_PLAT_ERR_FUNC("WMT do VCN28 PMIC off fail!\n"); -+ WMT_PLAT_INFO_FUNC("turn off vcn28 for fm/gps usage in co-clock mode\n"); -+ } -+ return 0; -+} -+ -+INT32 mtk_wcn_consys_hw_state_show(VOID) -+{ -+ return 0; -+} -+ -+INT32 mtk_wcn_consys_hw_restore(struct device *device) -+{ -+ UINT32 addrPhy = 0; -+ -+ if (gConEmiPhyBase) { -+ -+#if CONSYS_EMI_MPU_SETTING -+ /*set MPU for EMI share Memory */ -+ WMT_PLAT_INFO_FUNC("setting MPU for EMI share memory\n"); -+ -+#if 0 -+ emi_mpu_set_region_protection(gConEmiPhyBase + SZ_1M/2, -+ gConEmiPhyBase + SZ_1M, -+ 5, -+ SET_ACCESS_PERMISSON(FORBIDDEN, NO_PROTECTION, FORBIDDEN, NO_PROTECTION)); -+ -+ -+#else -+ WMT_PLAT_WARN_FUNC("not define platform config\n"); -+#endif -+ -+#endif -+ /*consys to ap emi remapping register:10001310, cal remapping address */ -+ addrPhy = (gConEmiPhyBase & 0xFFF00000) >> 20; -+ -+ /*enable consys to ap emi remapping bit12 */ -+ addrPhy = addrPhy | 0x1000; -+ -+ CONSYS_REG_WRITE(conn_reg.topckgen_base + CONSYS_EMI_MAPPING_OFFSET, -+ CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_EMI_MAPPING_OFFSET) | addrPhy); -+ -+ WMT_PLAT_INFO_FUNC("CONSYS_EMI_MAPPING dump in restore cb(0x%08x)\n", -+ CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_EMI_MAPPING_OFFSET)); -+ -+#if 1 -+ pEmibaseaddr = ioremap_nocache(gConEmiPhyBase + CONSYS_EMI_AP_PHY_OFFSET, CONSYS_EMI_MEM_SIZE); -+#else -+ pEmibaseaddr = ioremap_nocache(CONSYS_EMI_AP_PHY_BASE, CONSYS_EMI_MEM_SIZE); -+#endif -+ if (pEmibaseaddr) { -+ WMT_PLAT_INFO_FUNC("EMI mapping OK(0x%p)\n", pEmibaseaddr); -+ memset_io(pEmibaseaddr, 0, CONSYS_EMI_MEM_SIZE); -+ } else { -+ WMT_PLAT_ERR_FUNC("EMI mapping fail\n"); -+ } -+ } else { -+ WMT_PLAT_ERR_FUNC("consys emi memory address gConEmiPhyBase invalid\n"); -+ } -+ -+ return 0; -+} -+ -+/*Reserved memory by device tree!*/ -+int reserve_memory_consys_fn(struct reserved_mem *rmem) -+{ -+ WMT_PLAT_WARN_FUNC(" name: %s, base: 0x%llx, size: 0x%llx\n", rmem->name, -+ (unsigned long long)rmem->base, (unsigned long long)rmem->size); -+ gConEmiPhyBase = rmem->base; -+ return 0; -+} -+ -+RESERVEDMEM_OF_DECLARE(reserve_memory_test, "mediatek,consys-reserve-memory", reserve_memory_consys_fn); -+ -+ -+INT32 mtk_wcn_consys_hw_init(void) -+{ -+ -+ INT32 iRet = -1; -+ UINT32 addrPhy = 0; -+ INT32 i = 0; -+ struct device_node *node = NULL; -+ -+ node = of_find_compatible_node(NULL, NULL, "mediatek,mt7623-consys"); -+ if (node) { -+ /* registers base address */ -+ conn_reg.mcu_base = (SIZE_T) of_iomap(node, i); -+ WMT_PLAT_DBG_FUNC("Get mcu register base(0x%zx)\n", conn_reg.mcu_base); -+ i++; -+ -+ conn_reg.topckgen_base = (SIZE_T) of_iomap(node, i); -+ WMT_PLAT_DBG_FUNC("Get topckgen register base(0x%zx)\n", conn_reg.topckgen_base); -+ i++; -+ } else { -+ WMT_PLAT_ERR_FUNC("[%s] can't find CONSYS compatible node\n", __func__); -+ return iRet; -+ } -+ if (gConEmiPhyBase) { -+#if CONSYS_EMI_MPU_SETTING -+ /*set MPU for EMI share Memory */ -+ WMT_PLAT_INFO_FUNC("setting MPU for EMI share memory\n"); -+ -+#if 0 -+ emi_mpu_set_region_protection(gConEmiPhyBase + SZ_1M/2, -+ gConEmiPhyBase + SZ_1M, -+ 5, -+ SET_ACCESS_PERMISSON(FORBIDDEN, NO_PROTECTION, FORBIDDEN, NO_PROTECTION)); -+#else -+ WMT_PLAT_WARN_FUNC("not define platform config\n"); -+#endif -+ -+#endif -+ WMT_PLAT_DBG_FUNC("get consys start phy address(0x%zx)\n", (SIZE_T) gConEmiPhyBase); -+ -+ /*consys to ap emi remapping register:10001310, cal remapping address */ -+ addrPhy = (gConEmiPhyBase & 0xFFF00000) >> 20; -+ -+ /*enable consys to ap emi remapping bit12 */ -+ addrPhy = addrPhy | 0x1000; -+ -+ CONSYS_REG_WRITE(conn_reg.topckgen_base + CONSYS_EMI_MAPPING_OFFSET, -+ CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_EMI_MAPPING_OFFSET) | addrPhy); -+ -+ WMT_PLAT_INFO_FUNC("CONSYS_EMI_MAPPING dump(0x%08x)\n", -+ CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_EMI_MAPPING_OFFSET)); -+ -+#if 1 -+ pEmibaseaddr = ioremap_nocache(gConEmiPhyBase + CONSYS_EMI_AP_PHY_OFFSET, CONSYS_EMI_MEM_SIZE); -+#else -+ pEmibaseaddr = ioremap_nocache(CONSYS_EMI_AP_PHY_BASE, CONSYS_EMI_MEM_SIZE); -+#endif -+ /* pEmibaseaddr = ioremap_nocache(0x80090400,270*KBYTE); */ -+ if (pEmibaseaddr) { -+ WMT_PLAT_INFO_FUNC("EMI mapping OK(0x%p)\n", pEmibaseaddr); -+ memset_io(pEmibaseaddr, 0, CONSYS_EMI_MEM_SIZE); -+ iRet = 0; -+ } else { -+ WMT_PLAT_ERR_FUNC("EMI mapping fail\n"); -+ } -+ } else { -+ WMT_PLAT_ERR_FUNC("consys emi memory address gConEmiPhyBase invalid\n"); -+ } -+#ifdef CONFIG_MTK_HIBERNATION -+ WMT_PLAT_INFO_FUNC("register connsys restore cb for complying with IPOH function\n"); -+ register_swsusp_restore_noirq_func(ID_M_CONNSYS, mtk_wcn_consys_hw_restore, NULL); -+#endif -+ iRet = platform_driver_register(&mtk_wmt_dev_drv); -+ if (iRet) -+ WMT_PLAT_ERR_FUNC("WMT platform driver registered failed(%d)\n", iRet); -+ return iRet; -+} -+ -+INT32 mtk_wcn_consys_hw_deinit(void) -+{ -+ if (pEmibaseaddr) { -+ iounmap(pEmibaseaddr); -+ pEmibaseaddr = NULL; -+ } -+#ifdef CONFIG_MTK_HIBERNATION -+ unregister_swsusp_restore_noirq_func(ID_M_CONNSYS); -+#endif -+ -+ platform_driver_unregister(&mtk_wmt_dev_drv); -+ return 0; -+} -+ -+UINT8 *mtk_wcn_consys_emi_virt_addr_get(UINT32 ctrl_state_offset) -+{ -+ UINT8 *p_virtual_addr = NULL; -+ -+ if (!pEmibaseaddr) { -+ WMT_PLAT_ERR_FUNC("EMI base address is NULL\n"); -+ return NULL; -+ } -+ WMT_PLAT_DBG_FUNC("ctrl_state_offset(%08x)\n", ctrl_state_offset); -+ p_virtual_addr = pEmibaseaddr + ctrl_state_offset; -+ -+ return p_virtual_addr; -+} -+ -+UINT32 mtk_wcn_consys_soc_chipid(void) -+{ -+ return PLATFORM_SOC_CHIP; -+} -+ -+struct pinctrl *mtk_wcn_consys_get_pinctrl() -+{ -+ return consys_pinctrl; -+} -+INT32 mtk_wcn_consys_set_dynamic_dump(PUINT32 str_buf) -+{ -+ PUINT8 vir_addr = NULL; -+ -+ vir_addr = mtk_wcn_consys_emi_virt_addr_get(EXP_APMEM_CTRL_CHIP_DYNAMIC_DUMP); -+ if (!vir_addr) { -+ WMT_PLAT_ERR_FUNC("get vir address fail\n"); -+ return -2; -+ } -+ memcpy(vir_addr, str_buf, DYNAMIC_DUMP_GROUP_NUM*8); -+ WMT_PLAT_INFO_FUNC("dynamic dump register value(0x%08x)\n", CONSYS_REG_READ(vir_addr)); -+ return 0; -+} -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/mt7623/wmt_plat_alps.c b/drivers/misc/mediatek/connectivity/common/conn_soc/mt7623/wmt_plat_alps.c -new file mode 100644 -index 000000000000..3a3be8308f6a ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/mt7623/wmt_plat_alps.c -@@ -0,0 +1,1071 @@ -+/*! \file -+ \brief Declaration of library functions -+ -+ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+#ifdef DFT_TAG -+#undef DFT_TAG -+#endif -+#define DFT_TAG "[WMT-PLAT]" -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include -+ -+/* ALPS header files */ -+/*#include */ -+/*#include */ -+#if defined(CONFIG_MTK_GPIO_LEGACY) -+#include -+#endif -+#include -+ -+/* MTK_WCN_COMBO header files */ -+#include "osal_typedef.h" -+#include "mtk_wcn_consys_hw.h" -+#include "stp_dbg.h" -+ -+#define CFG_WMT_WAKELOCK_SUPPORT 1 -+ -+#ifdef CONFIG_MTK_MT6306_SUPPORT -+#define MTK_WCN_MT6306_IS_READY 1 -+#else -+#define MTK_WCN_MT6306_IS_READY 0 -+#endif -+ -+#if MTK_WCN_MT6306_IS_READY -+#include -+ -+#ifdef GPIO_GPS_LNA_PIN -+#undef GPIO_GPS_LNA_PIN -+#endif -+ -+#define GPIO_GPS_LNA_PIN GPIO7 -+#endif -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+EMI_CTRL_STATE_OFFSET mtk_wcn_emi_state_off = { -+ .emi_apmem_ctrl_state = EXP_APMEM_CTRL_STATE, -+ .emi_apmem_ctrl_host_sync_state = EXP_APMEM_CTRL_HOST_SYNC_STATE, -+ .emi_apmem_ctrl_host_sync_num = EXP_APMEM_CTRL_HOST_SYNC_NUM, -+ .emi_apmem_ctrl_chip_sync_state = EXP_APMEM_CTRL_CHIP_SYNC_STATE, -+ .emi_apmem_ctrl_chip_sync_num = EXP_APMEM_CTRL_CHIP_SYNC_NUM, -+ .emi_apmem_ctrl_chip_sync_addr = EXP_APMEM_CTRL_CHIP_SYNC_ADDR, -+ .emi_apmem_ctrl_chip_sync_len = EXP_APMEM_CTRL_CHIP_SYNC_LEN, -+ .emi_apmem_ctrl_chip_print_buff_start = EXP_APMEM_CTRL_CHIP_PRINT_BUFF_START, -+ .emi_apmem_ctrl_chip_print_buff_len = EXP_APMEM_CTRL_CHIP_PRINT_BUFF_LEN, -+ .emi_apmem_ctrl_chip_print_buff_idx = EXP_APMEM_CTRL_CHIP_PRINT_BUFF_IDX, -+ .emi_apmem_ctrl_chip_int_status = EXP_APMEM_CTRL_CHIP_INT_STATUS, -+ .emi_apmem_ctrl_chip_paded_dump_end = EXP_APMEM_CTRL_CHIP_PAGED_DUMP_END, -+ .emi_apmem_ctrl_host_outband_assert_w1 = EXP_APMEM_CTRL_HOST_OUTBAND_ASSERT_W1, -+}; -+ -+CONSYS_EMI_ADDR_INFO mtk_wcn_emi_addr_info = { -+ .emi_phy_addr = CONSYS_EMI_FW_PHY_BASE, -+ .paged_trace_off = CONSYS_EMI_PAGED_TRACE_OFFSET, -+ .paged_dump_off = CONSYS_EMI_PAGED_DUMP_OFFSET, -+ .full_dump_off = CONSYS_EMI_FULL_DUMP_OFFSET, -+ .p_ecso = &mtk_wcn_emi_state_off, -+}; -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+static VOID wmt_plat_bgf_eirq_cb(VOID); -+ -+static INT32 wmt_plat_bgf_eint_ctrl(ENUM_PIN_STATE state); -+static INT32 wmt_plat_i2s_ctrl(ENUM_PIN_STATE state); -+static INT32 wmt_plat_gps_sync_ctrl(ENUM_PIN_STATE state); -+static INT32 wmt_plat_gps_lna_ctrl(ENUM_PIN_STATE state); -+ -+static INT32 wmt_plat_dump_pin_conf(VOID); -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+UINT32 gCoClockFlag = 0; -+BGF_IRQ_BALANCE gbgfIrqBle; -+UINT32 wmtPlatLogLvl = WMT_PLAT_LOG_DBG; -+#if CONSYS_BT_WIFI_SHARE_V33 -+BT_WIFI_V33_STATUS gBtWifiV33; -+#endif -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+#if CFG_WMT_WAKELOCK_SUPPORT -+static struct mutex gOsSLock; -+#ifdef CONFIG_PM_WAKELOCKS -+static struct wakeup_source wmtWakeLock; -+#else -+static struct wake_lock wmtWakeLock; -+#endif -+#endif -+ -+irq_cb wmt_plat_bgf_irq_cb = NULL; -+device_audio_if_cb wmt_plat_audio_if_cb = NULL; -+func_ctrl_cb wmt_plat_func_ctrl_cb = NULL; -+thermal_query_ctrl_cb wmt_plat_thermal_query_ctrl_cb = NULL; -+deep_idle_ctrl_cb wmt_plat_deep_idle_ctrl_cb = NULL; -+ -+static const fp_set_pin gfp_set_pin_table[] = { -+ [PIN_BGF_EINT] = wmt_plat_bgf_eint_ctrl, -+ [PIN_I2S_GRP] = wmt_plat_i2s_ctrl, -+ [PIN_GPS_SYNC] = wmt_plat_gps_sync_ctrl, -+ [PIN_GPS_LNA] = wmt_plat_gps_lna_ctrl, -+}; -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+/*! -+ * \brief audio control callback function for CMB_STUB on ALPS -+ * -+ * A platform function required for dynamic binding with CMB_STUB on ALPS. -+ * -+ * \param state desired audio interface state to use -+ * \param flag audio interface control options -+ * -+ * \retval 0 operation success -+ * \retval -1 invalid parameters -+ * \retval < 0 error for operation fail -+ */ -+INT32 wmt_plat_audio_ctrl(CMB_STUB_AIF_X state, CMB_STUB_AIF_CTRL ctrl) -+{ -+ INT32 iRet = 0; -+ UINT32 pinShare = 0; -+ -+ /* input sanity check */ -+ if ((CMB_STUB_AIF_MAX <= state) -+ || (CMB_STUB_AIF_CTRL_MAX <= ctrl)) { -+ return -1; -+ } -+ -+ iRet = 0; -+ -+ /* set host side first */ -+ switch (state) { -+ case CMB_STUB_AIF_0: -+ /* BT_PCM_OFF & FM line in/out */ -+ iRet += wmt_plat_gpio_ctrl(PIN_I2S_GRP, PIN_STA_DEINIT); -+ break; -+ -+ case CMB_STUB_AIF_1: -+ iRet += wmt_plat_gpio_ctrl(PIN_I2S_GRP, PIN_STA_DEINIT); -+ break; -+ -+ case CMB_STUB_AIF_2: -+ iRet += wmt_plat_gpio_ctrl(PIN_I2S_GRP, PIN_STA_INIT); -+ break; -+ -+ case CMB_STUB_AIF_3: -+ iRet += wmt_plat_gpio_ctrl(PIN_I2S_GRP, PIN_STA_INIT); -+ break; -+ -+ default: -+ /* FIXME: move to cust folder? */ -+ WMT_PLAT_ERR_FUNC("invalid state [%d]\n", state); -+ iRet = -1; -+ break; -+ } -+ -+ if (CMB_STUB_AIF_CTRL_EN == ctrl) { -+ WMT_PLAT_INFO_FUNC("call chip aif setting\n"); -+ /* need to control chip side GPIO */ -+ if (NULL != wmt_plat_audio_if_cb) { -+ iRet += (*wmt_plat_audio_if_cb) (state, (pinShare) ? MTK_WCN_BOOL_TRUE : MTK_WCN_BOOL_FALSE); -+ } else { -+ WMT_PLAT_WARN_FUNC("wmt_plat_audio_if_cb is not registered\n"); -+ iRet -= 1; -+ } -+ -+ } else { -+ WMT_PLAT_INFO_FUNC("skip chip aif setting\n"); -+ } -+ -+ return iRet; -+ -+} -+ -+static VOID wmt_plat_func_ctrl(UINT32 type, UINT32 on) -+{ -+ if (wmt_plat_func_ctrl_cb) -+ (*wmt_plat_func_ctrl_cb) (on, type); -+} -+ -+static long wmt_plat_thermal_ctrl(VOID) -+{ -+ long temp = 0; -+ -+ if (wmt_plat_thermal_query_ctrl_cb) -+ temp = (*wmt_plat_thermal_query_ctrl_cb) (); -+ -+ return temp; -+} -+ -+static INT32 wmt_plat_deep_idle_ctrl(UINT32 dpilde_ctrl) -+{ -+ INT32 iRet = -1; -+ -+ if (wmt_plat_deep_idle_ctrl_cb) -+ iRet = (*wmt_plat_deep_idle_ctrl_cb) (dpilde_ctrl); -+ -+ return iRet; -+} -+ -+static VOID wmt_plat_bgf_eirq_cb(VOID) -+{ -+#if CFG_WMT_PS_SUPPORT -+/* #error "need to disable EINT here" */ -+ /* wmt_lib_ps_irq_cb(); */ -+ if (NULL != wmt_plat_bgf_irq_cb) -+ (*(wmt_plat_bgf_irq_cb)) (); -+ else -+ WMT_PLAT_WARN_FUNC("WMT-PLAT: wmt_plat_bgf_irq_cb not registered\n"); -+#else -+ return; -+#endif -+ -+} -+ -+irqreturn_t wmt_plat_bgf_irq_isr(INT32 i, VOID *arg) -+{ -+#if CFG_WMT_PS_SUPPORT -+ wmt_plat_eirq_ctrl(PIN_BGF_EINT, PIN_STA_EINT_DIS); -+ wmt_plat_bgf_eirq_cb(); -+#else -+ WMT_PLAT_INFO_FUNC("skip irq handing because psm is disable"); -+#endif -+ return IRQ_HANDLED; -+} -+ -+VOID wmt_plat_irq_cb_reg(irq_cb bgf_irq_cb) -+{ -+ wmt_plat_bgf_irq_cb = bgf_irq_cb; -+} -+EXPORT_SYMBOL(wmt_plat_irq_cb_reg); -+ -+VOID wmt_plat_aif_cb_reg(device_audio_if_cb aif_ctrl_cb) -+{ -+ wmt_plat_audio_if_cb = aif_ctrl_cb; -+} -+EXPORT_SYMBOL(wmt_plat_aif_cb_reg); -+ -+VOID wmt_plat_func_ctrl_cb_reg(func_ctrl_cb subsys_func_ctrl) -+{ -+ wmt_plat_func_ctrl_cb = subsys_func_ctrl; -+} -+EXPORT_SYMBOL(wmt_plat_func_ctrl_cb_reg); -+ -+VOID wmt_plat_thermal_ctrl_cb_reg(thermal_query_ctrl_cb thermal_query_ctrl) -+{ -+ wmt_plat_thermal_query_ctrl_cb = thermal_query_ctrl; -+} -+EXPORT_SYMBOL(wmt_plat_thermal_ctrl_cb_reg); -+ -+VOID wmt_plat_deep_idle_ctrl_cb_reg(deep_idle_ctrl_cb deep_idle_ctrl) -+{ -+ wmt_plat_deep_idle_ctrl_cb = deep_idle_ctrl; -+} -+EXPORT_SYMBOL(wmt_plat_deep_idle_ctrl_cb_reg); -+ -+UINT32 wmt_plat_soc_co_clock_flag_get(VOID) -+{ -+ return gCoClockFlag; -+} -+ -+static UINT32 wmt_plat_soc_co_clock_flag_set(UINT32 flag) -+{ -+ gCoClockFlag = flag; -+ return 0; -+} -+ -+INT32 wmt_plat_init(UINT32 co_clock_type) -+{ -+ CMB_STUB_CB stub_cb; -+ INT32 iret; -+ /*init wmt function ctrl wakelock if wake lock is supported by host platform */ -+ -+ wmt_plat_soc_co_clock_flag_set(co_clock_type); -+ -+ stub_cb.aif_ctrl_cb = wmt_plat_audio_ctrl; -+ stub_cb.func_ctrl_cb = wmt_plat_func_ctrl; -+ stub_cb.thermal_query_cb = wmt_plat_thermal_ctrl; -+ stub_cb.deep_idle_ctrl_cb = wmt_plat_deep_idle_ctrl; -+ stub_cb.size = sizeof(stub_cb); -+ -+ /* register to cmb_stub */ -+ iret = mtk_wcn_cmb_stub_reg(&stub_cb); -+#ifdef CFG_WMT_WAKELOCK_SUPPORT -+#ifdef CONFIG_PM_WAKELOCKS -+ wakeup_source_init(&wmtWakeLock, "wmtFuncCtrl"); -+#else -+ wake_lock_init(&wmtWakeLock, WAKE_LOCK_SUSPEND, "wmtFuncCtrl"); -+#endif -+ mutex_init(&gOsSLock); -+#endif -+ -+#if CONSYS_BT_WIFI_SHARE_V33 -+ gBtWifiV33.counter = 0; -+ spin_lock_init(&gBtWifiV33.lock); -+#endif -+ -+ iret += mtk_wcn_consys_hw_init(); -+ -+ spin_lock_init(&gbgfIrqBle.lock); -+ WMT_PLAT_DBG_FUNC("WMT-PLAT: ALPS platform init (%d)\n", iret); -+ -+ return 0; -+} -+EXPORT_SYMBOL(wmt_plat_init); -+ -+INT32 wmt_plat_deinit(VOID) -+{ -+ INT32 iret = 0; -+ /* 2. unreg to cmb_stub */ -+ iret = mtk_wcn_cmb_stub_unreg(); -+printk(KERN_ALERT "DEBUG: Passed %s %d now calling wmt wakelock deinit\n",__FUNCTION__,__LINE__); -+ /*3. wmt wakelock deinit */ -+#ifdef CFG_WMT_WAKELOCK_SUPPORT -+#ifdef CONFIG_PM_WAKELOCKS -+printk(KERN_ALERT "DEBUG: Passed %s %d now calling wakeup_source_trash\n",__FUNCTION__,__LINE__); -+ wakeup_source_trash(&wmtWakeLock); -+#else -+printk(KERN_ALERT "DEBUG: Passed %s %d now calling wake lock destroy %d\n",__FUNCTION__,__LINE__,(int)&wmtWakeLock); -+//destroy calls wakeup_source_trash with &lock->ws -+printk(KERN_ALERT "DEBUG: Passed %s %d now wmtWakeLock:%d\n",__FUNCTION__,__LINE__,(int)&wmtWakeLock); -+printk(KERN_ALERT "DEBUG: Passed %s %d now wmtWakeLock->ws: %d\n",__FUNCTION__,__LINE__,(int)&(wmtWakeLock.ws)); -+ wake_lock_destroy(&wmtWakeLock); -+#endif -+printk(KERN_ALERT "DEBUG: Passed %s %d now calling mutex_destroy\n",__FUNCTION__,__LINE__); -+ mutex_destroy(&gOsSLock); -+ WMT_PLAT_DBG_FUNC("destroy wmtWakeLock\n"); -+#endif -+printk(KERN_ALERT "DEBUG: Passed %s %d now calling consys hw deinit\n",__FUNCTION__,__LINE__); -+ -+ iret += mtk_wcn_consys_hw_deinit(); -+ -+ WMT_PLAT_DBG_FUNC("WMT-PLAT: ALPS platform init (%d)\n", iret); -+ -+ return 0; -+} -+EXPORT_SYMBOL(wmt_plat_deinit); -+ -+static INT32 wmt_plat_dump_pin_conf(VOID) -+{ -+ WMT_PLAT_DBG_FUNC("[WMT-PLAT]=>dump wmt pin configuration start<=\n"); -+#if defined(CONFIG_MTK_GPIO_LEGACY) -+ -+#ifdef GPIO_COMBO_BGF_EINT_PIN -+ WMT_PLAT_DBG_FUNC("BGF_EINT(GPIO%d)\n", GPIO_COMBO_BGF_EINT_PIN); -+#else -+ WMT_PLAT_DBG_FUNC("BGF_EINT(not defined)\n"); -+#endif -+ -+#ifdef CUST_EINT_COMBO_BGF_NUM -+ WMT_PLAT_DBG_FUNC("BGF_EINT_NUM(%d)\n", CUST_EINT_COMBO_BGF_NUM); -+#else -+ WMT_PLAT_DBG_FUNC("BGF_EINT_NUM(not defined)\n"); -+#endif -+ -+#ifdef GPIO_COMBO_URXD_PIN -+ WMT_PLAT_DBG_FUNC("UART_RX(GPIO%d)\n", GPIO_COMBO_URXD_PIN); -+#else -+ WMT_PLAT_DBG_FUNC("UART_RX(not defined)\n"); -+#endif -+#if defined(FM_DIGITAL_INPUT) || defined(FM_DIGITAL_OUTPUT) -+#ifdef GPIO_COMBO_I2S_CK_PIN -+ WMT_PLAT_DBG_FUNC("I2S_CK(GPIO%d)\n", GPIO_COMBO_I2S_CK_PIN); -+#else -+ WMT_PLAT_DBG_FUNC("I2S_CK(not defined)\n"); -+#endif -+#ifdef GPIO_COMBO_I2S_WS_PIN -+ WMT_PLAT_DBG_FUNC("I2S_WS(GPIO%d)\n", GPIO_COMBO_I2S_WS_PIN); -+#else -+ WMT_PLAT_DBG_FUNC("I2S_WS(not defined)\n"); -+#endif -+#ifdef GPIO_COMBO_I2S_DAT_PIN -+ WMT_PLAT_DBG_FUNC("I2S_DAT(GPIO%d)\n", GPIO_COMBO_I2S_DAT_PIN); -+#else -+ WMT_PLAT_DBG_FUNC("I2S_DAT(not defined)\n"); -+#endif -+#else /* FM_ANALOG_INPUT || FM_ANALOG_OUTPUT */ -+ WMT_PLAT_DBG_FUNC("FM digital mode is not set, no need for I2S GPIOs\n"); -+#endif -+#ifdef GPIO_GPS_SYNC_PIN -+ WMT_PLAT_DBG_FUNC("GPS_SYNC(GPIO%d)\n", GPIO_GPS_SYNC_PIN); -+#else -+ WMT_PLAT_DBG_FUNC("GPS_SYNC(not defined)\n"); -+#endif -+ -+#ifdef GPIO_GPS_LNA_PIN -+ WMT_PLAT_INFO_FUNC("GPS_LNA(GPIO%d)\n", GPIO_GPS_LNA_PIN); -+#else -+ WMT_PLAT_INFO_FUNC("GPS_LNA(not defined)\n"); -+#endif -+ -+#else /* #if defined(CONFIG_MTK_GPIO_LEGACY) */ -+#endif -+ WMT_PLAT_DBG_FUNC("[WMT-PLAT]=>dump wmt pin configuration emds<=\n"); -+ return 0; -+} -+ -+INT32 wmt_plat_pwr_ctrl(ENUM_FUNC_STATE state) -+{ -+ INT32 ret = -1; -+ -+ switch (state) { -+ case FUNC_ON: -+ /* TODO:[ChangeFeature][George] always output this or by request throuth /proc or sysfs? */ -+ wmt_plat_dump_pin_conf(); -+ ret = mtk_wcn_consys_hw_pwr_on(gCoClockFlag); -+ break; -+ -+ case FUNC_OFF: -+ ret = mtk_wcn_consys_hw_pwr_off(); -+ break; -+ -+ case FUNC_RST: -+ ret = mtk_wcn_consys_hw_rst(gCoClockFlag); -+ break; -+ case FUNC_STAT: -+ ret = mtk_wcn_consys_hw_state_show(); -+ break; -+ default: -+ WMT_PLAT_WARN_FUNC("WMT-PLAT:Warnning, invalid state(%d) in pwr_ctrl\n", state); -+ break; -+ } -+ -+ return ret; -+} -+EXPORT_SYMBOL(wmt_plat_pwr_ctrl); -+ -+INT32 wmt_plat_eirq_ctrl(ENUM_PIN_ID id, ENUM_PIN_STATE state) -+{ -+#ifdef CONFIG_OF -+ struct device_node *node; -+ unsigned int irq_info[3] = { 0, 0, 0 }; -+#endif -+ INT32 iret = -EINVAL; -+ static INT32 bgf_irq_num = -1; -+ static UINT32 bgf_irq_flag; -+ /* TODO: [ChangeFeature][GeorgeKuo]: use another function to handle this, as done in gpio_ctrls */ -+ -+ if ((PIN_STA_INIT != state) -+ && (PIN_STA_DEINIT != state) -+ && (PIN_STA_EINT_EN != state) -+ && (PIN_STA_EINT_DIS != state)) { -+ WMT_PLAT_WARN_FUNC("WMT-PLAT:invalid PIN_STATE(%d) in eirq_ctrl for PIN(%d)\n", state, id); -+ return -1; -+ } -+ -+ switch (id) { -+ case PIN_BGF_EINT: -+ -+ if (PIN_STA_INIT == state) { -+#ifdef CONFIG_OF -+ node = of_find_compatible_node(NULL, NULL, "mediatek,mt7623-consys"); -+ if (node) { -+ bgf_irq_num = irq_of_parse_and_map(node, 0); -+ /* get the interrupt line behaviour */ -+ if (of_property_read_u32_array(node, "interrupts", irq_info, ARRAY_SIZE(irq_info))) { -+ WMT_PLAT_ERR_FUNC("get irq flags from DTS fail!!\n"); -+ return iret; -+ } -+ bgf_irq_flag = irq_info[2]; -+ WMT_PLAT_INFO_FUNC("get irq id(%d) and irq trigger flag(%d) from DT\n", bgf_irq_num, -+ bgf_irq_flag); -+ } else { -+ WMT_PLAT_ERR_FUNC("[%s] can't find CONSYS compatible node\n", __func__); -+ return iret; -+ } -+#else -+ bgf_irq_num = MT_CONN2AP_BTIF_WAKEUP_IRQ_ID; -+ bgf_irq_flag = IRQF_TRIGGER_LOW; -+#endif -+ iret = request_irq(bgf_irq_num, wmt_plat_bgf_irq_isr, bgf_irq_flag, "BTIF_WAKEUP_IRQ", NULL); -+ if (iret) { -+ WMT_PLAT_ERR_FUNC("request_irq fail,irq_no(%d),iret(%d)\n", bgf_irq_num, iret); -+ return iret; -+ } -+ gbgfIrqBle.counter = 1; -+ -+ } else if (PIN_STA_EINT_EN == state) { -+ -+ spin_lock_irqsave(&gbgfIrqBle.lock, gbgfIrqBle.flags); -+ if (gbgfIrqBle.counter) { -+ WMT_PLAT_DBG_FUNC("BGF INT has been enabled,counter(%d)\n", gbgfIrqBle.counter); -+ } else { -+ enable_irq(bgf_irq_num); -+ gbgfIrqBle.counter++; -+ } -+ WMT_PLAT_DBG_FUNC("WMT-PLAT:BGFInt (en)\n"); -+ spin_unlock_irqrestore(&gbgfIrqBle.lock, gbgfIrqBle.flags); -+ } else if (PIN_STA_EINT_DIS == state) { -+ spin_lock_irqsave(&gbgfIrqBle.lock, gbgfIrqBle.flags); -+ if (!gbgfIrqBle.counter) { -+ WMT_PLAT_INFO_FUNC("BGF INT has been disabled,counter(%d)\n", gbgfIrqBle.counter); -+ } else { -+ disable_irq_nosync(bgf_irq_num); -+ gbgfIrqBle.counter--; -+ } -+ WMT_PLAT_DBG_FUNC("WMT-PLAT:BGFInt (dis)\n"); -+ spin_unlock_irqrestore(&gbgfIrqBle.lock, gbgfIrqBle.flags); -+ } else { -+ free_irq(bgf_irq_num, NULL); -+ /* de-init: nothing to do in ALPS, such as un-registration... */ -+ } -+ iret = 0; -+ break; -+ -+ default: -+ WMT_PLAT_WARN_FUNC("WMT-PLAT:unsupported EIRQ(PIN_ID:%d) in eirq_ctrl\n", id); -+ iret = -1; -+ break; -+ } -+ -+ return iret; -+} -+EXPORT_SYMBOL(wmt_plat_eirq_ctrl); -+ -+INT32 wmt_plat_gpio_ctrl(ENUM_PIN_ID id, ENUM_PIN_STATE state) -+{ -+ if ((PIN_ID_MAX > id) -+ && (PIN_STA_MAX > state)) { -+ -+ /* TODO: [FixMe][GeorgeKuo] do sanity check to const function table when init and skip checking here */ -+ if (gfp_set_pin_table[id]) -+ return (*(gfp_set_pin_table[id])) (state); /* .handler */ -+ WMT_PLAT_WARN_FUNC("WMT-PLAT: null fp for gpio_ctrl(%d)\n", id); -+ return -2; -+ } -+ return -1; -+} -+EXPORT_SYMBOL(wmt_plat_gpio_ctrl); -+ -+INT32 wmt_plat_bgf_eint_ctrl(ENUM_PIN_STATE state) -+{ -+#if defined(CONFIG_MTK_GPIO_LEGACY) -+#ifdef GPIO_COMBO_BGF_EINT_PIN -+ switch (state) { -+ case PIN_STA_INIT: -+ /*set to gpio input low, pull down enable */ -+ mt_set_gpio_mode(GPIO_COMBO_BGF_EINT_PIN, GPIO_COMBO_BGF_EINT_PIN_M_GPIO); -+ mt_set_gpio_dir(GPIO_COMBO_BGF_EINT_PIN, GPIO_DIR_IN); -+ mt_set_gpio_pull_select(GPIO_COMBO_BGF_EINT_PIN, GPIO_PULL_DOWN); -+ mt_set_gpio_pull_enable(GPIO_COMBO_BGF_EINT_PIN, GPIO_PULL_ENABLE); -+ WMT_PLAT_DBG_FUNC("WMT-PLAT:BGFInt init(in pd)\n"); -+ break; -+ -+ case PIN_STA_MUX: -+ mt_set_gpio_mode(GPIO_COMBO_BGF_EINT_PIN, GPIO_COMBO_BGF_EINT_PIN_M_GPIO); -+ mt_set_gpio_pull_enable(GPIO_COMBO_BGF_EINT_PIN, GPIO_PULL_ENABLE); -+ mt_set_gpio_pull_select(GPIO_COMBO_BGF_EINT_PIN, GPIO_PULL_UP); -+ mt_set_gpio_mode(GPIO_COMBO_BGF_EINT_PIN, GPIO_COMBO_BGF_EINT_PIN_M_EINT); -+ WMT_PLAT_DBG_FUNC("WMT-PLAT:BGFInt mux (eint)\n"); -+ break; -+ -+ case PIN_STA_IN_L: -+ case PIN_STA_DEINIT: -+ /*set to gpio input low, pull down enable */ -+ mt_set_gpio_mode(GPIO_COMBO_BGF_EINT_PIN, GPIO_COMBO_BGF_EINT_PIN_M_GPIO); -+ mt_set_gpio_dir(GPIO_COMBO_BGF_EINT_PIN, GPIO_DIR_IN); -+ mt_set_gpio_pull_select(GPIO_COMBO_BGF_EINT_PIN, GPIO_PULL_DOWN); -+ mt_set_gpio_pull_enable(GPIO_COMBO_BGF_EINT_PIN, GPIO_PULL_ENABLE); -+ WMT_PLAT_DBG_FUNC("WMT-PLAT:BGFInt deinit(in pd)\n"); -+ break; -+ -+ default: -+ WMT_PLAT_WARN_FUNC("WMT-PLAT:Warnning, invalid state(%d) on BGF EINT\n", state); -+ break; -+ } -+#else -+ WMT_PLAT_INFO_FUNC("WMT-PLAT:BGF EINT not defined\n"); -+#endif -+#else /* #if defined(CONFIG_MTK_GPIO_LEGACY) */ -+#endif -+ return 0; -+} -+ -+static INT32 wmt_plat_gps_sync_ctrl(ENUM_PIN_STATE state) -+{ -+#if defined(CONFIG_MTK_GPIO_LEGACY) -+ -+#ifdef GPIO_GPS_SYNC_PIN -+#ifndef GPIO_GPS_SYNC_PIN_M_GPS_SYNC -+#ifdef GPIO_GPS_SYNC_PIN_M_MD1_GPS_SYNC -+#define GPIO_GPS_SYNC_PIN_M_GPS_SYNC GPIO_GPS_SYNC_PIN_M_MD1_GPS_SYNC -+#else -+#ifdef GPIO_GPS_SYNC_PIN_M_MD2_GPS_SYNC -+#define GPIO_GPS_SYNC_PIN_M_GPS_SYNC GPIO_GPS_SYNC_PIN_M_MD2_GPS_SYNC -+#endif -+#endif -+#endif -+ switch (state) { -+ case PIN_STA_INIT: -+ case PIN_STA_DEINIT: -+ mt_set_gpio_mode(GPIO_GPS_SYNC_PIN, GPIO_GPS_SYNC_PIN_M_GPIO); -+ mt_set_gpio_dir(GPIO_GPS_SYNC_PIN, GPIO_DIR_OUT); -+ mt_set_gpio_out(GPIO_GPS_SYNC_PIN, GPIO_OUT_ZERO); -+ break; -+ -+ case PIN_STA_MUX: -+ mt_set_gpio_mode(GPIO_GPS_SYNC_PIN, GPIO_GPS_SYNC_PIN_M_GPS_SYNC); -+ break; -+ -+ default: -+ break; -+ } -+#endif -+ -+#else /* #if defined(CONFIG_MTK_GPIO_LEGACY) */ -+#endif -+ return 0; -+} -+ -+#if MTK_WCN_MT6306_IS_READY -+/* MT6306 GPIO7 is GPIO_GPS_LNA_EN, for K2 common phone pin modification */ -+static INT32 wmt_plat_gps_lna_ctrl(ENUM_PIN_STATE state) -+{ -+#ifdef GPIO_GPS_LNA_PIN -+ switch (state) { -+ case PIN_STA_INIT: -+ case PIN_STA_DEINIT: -+ WMT_PLAT_ERR_FUNC("Gps LNA pin ctrl %d!\n", state); -+ mt6306_set_gpio_dir(GPIO_GPS_LNA_PIN, GPIO_DIR_OUT); -+ mt6306_set_gpio_out(GPIO_GPS_LNA_PIN, GPIO_OUT_ZERO); -+ break; -+ case PIN_STA_OUT_H: -+ WMT_PLAT_ERR_FUNC("Gps LNA pin output high!\n"); -+ mt6306_set_gpio_out(GPIO_GPS_LNA_PIN, GPIO_OUT_ONE); -+ break; -+ case PIN_STA_OUT_L: -+ WMT_PLAT_ERR_FUNC("Gps LNA pin output low!\n"); -+ mt6306_set_gpio_out(GPIO_GPS_LNA_PIN, GPIO_OUT_ZERO); -+ break; -+ default: -+ WMT_PLAT_WARN_FUNC("%d mode not defined for gps lna pin !!!\n", state); -+ break; -+ } -+ return 0; -+#else -+ WMT_PLAT_WARN_FUNC("host gps lna pin not defined!!!\n"); -+ return 0; -+#endif -+} -+#else -+ -+static INT32 wmt_plat_gps_lna_ctrl(ENUM_PIN_STATE state) -+{ -+#if !defined(CONFIG_MTK_GPIO_LEGACY) -+ static struct pinctrl_state *gps_lna_init; -+ static struct pinctrl_state *gps_lna_oh; -+ static struct pinctrl_state *gps_lna_ol; -+ static struct pinctrl *consys_pinctrl; -+ -+ WMT_PLAT_DBG_FUNC("ENTER++\n"); -+ consys_pinctrl = mtk_wcn_consys_get_pinctrl(); -+ if (NULL == consys_pinctrl) { -+ WMT_PLAT_ERR_FUNC("get consys pinctrl fail\n"); -+ return -1; -+ } -+ -+ gps_lna_init = pinctrl_lookup_state(consys_pinctrl, "gps_lna_state_init"); -+ if (NULL == gps_lna_init) { -+ WMT_PLAT_ERR_FUNC("Cannot find gps lna pin init state!\n"); -+ return -2; -+ } -+ -+ gps_lna_oh = pinctrl_lookup_state(consys_pinctrl, "gps_lna_state_oh"); -+ if (NULL == gps_lna_oh) { -+ WMT_PLAT_ERR_FUNC("Cannot find gps lna pin oh state!\n"); -+ return -3; -+ } -+ -+ gps_lna_ol = pinctrl_lookup_state(consys_pinctrl, "gps_lna_state_ol"); -+ if (NULL == gps_lna_ol) { -+ WMT_PLAT_ERR_FUNC("Cannot find gps lna pin ol state!\n"); -+ return -4; -+ } -+ -+ switch (state) { -+ case PIN_STA_INIT: -+ case PIN_STA_DEINIT: -+ pinctrl_select_state(consys_pinctrl, gps_lna_init); -+ WMT_PLAT_INFO_FUNC("set gps lna to init\n"); -+ break; -+ case PIN_STA_OUT_H: -+ pinctrl_select_state(consys_pinctrl, gps_lna_oh); -+ WMT_PLAT_INFO_FUNC("set gps lna to oh\n"); -+ break; -+ case PIN_STA_OUT_L: -+ pinctrl_select_state(consys_pinctrl, gps_lna_ol); -+ WMT_PLAT_INFO_FUNC("set gps lna to ol\n"); -+ break; -+ -+ default: -+ WMT_PLAT_WARN_FUNC("%d mode not defined for gps lna pin !!!\n", state); -+ break; -+ } -+ return 0; -+#else -+#ifdef GPIO_GPS_LNA_PIN -+ switch (state) { -+ case PIN_STA_INIT: -+ case PIN_STA_DEINIT: -+ mt_set_gpio_pull_enable(GPIO_GPS_LNA_PIN, GPIO_PULL_DISABLE); -+ mt_set_gpio_dir(GPIO_GPS_LNA_PIN, GPIO_DIR_OUT); -+ mt_set_gpio_mode(GPIO_GPS_LNA_PIN, GPIO_GPS_LNA_PIN_M_GPIO); -+ mt_set_gpio_out(GPIO_GPS_LNA_PIN, GPIO_OUT_ZERO); -+ break; -+ case PIN_STA_OUT_H: -+ mt_set_gpio_out(GPIO_GPS_LNA_PIN, GPIO_OUT_ONE); -+ break; -+ case PIN_STA_OUT_L: -+ mt_set_gpio_out(GPIO_GPS_LNA_PIN, GPIO_OUT_ZERO); -+ break; -+ -+ default: -+ WMT_PLAT_WARN_FUNC("%d mode not defined for gps lna pin !!!\n", state); -+ break; -+ } -+ return 0; -+#else -+ WMT_PLAT_WARN_FUNC("host gps lna pin not defined!!!\n"); -+ return 0; -+#endif -+#endif /* !defined(CONFIG_MTK_GPIO_LEGACY) */ -+} -+#endif -+ -+INT32 wmt_plat_i2s_ctrl(ENUM_PIN_STATE state) -+{ -+ /* TODO: [NewFeature][GeorgeKuo]: GPIO_I2Sx is changed according to different project. */ -+ /* TODO: provide a translation table in board_custom.h for different ALPS project customization. */ -+#if defined(CONFIG_MTK_GPIO_LEGACY) -+ -+#if defined(FM_DIGITAL_INPUT) || defined(FM_DIGITAL_OUTPUT) -+#if defined(GPIO_COMBO_I2S_CK_PIN) -+ switch (state) { -+ case PIN_STA_INIT: -+ case PIN_STA_MUX: -+ mt_set_gpio_mode(GPIO_COMBO_I2S_CK_PIN, GPIO_COMBO_I2S_CK_PIN_M_I2S0_CK); -+ mt_set_gpio_mode(GPIO_COMBO_I2S_WS_PIN, GPIO_COMBO_I2S_WS_PIN_M_I2S0_WS); -+ mt_set_gpio_mode(GPIO_COMBO_I2S_DAT_PIN, GPIO_COMBO_I2S_DAT_PIN_M_I2S0_DAT); -+ WMT_PLAT_DBG_FUNC("WMT-PLAT:I2S init (I2S0 system)\n"); -+ break; -+ case PIN_STA_IN_L: -+ case PIN_STA_DEINIT: -+ mt_set_gpio_mode(GPIO_COMBO_I2S_CK_PIN, GPIO_COMBO_I2S_CK_PIN_M_GPIO); -+ mt_set_gpio_dir(GPIO_COMBO_I2S_CK_PIN, GPIO_DIR_OUT); -+ mt_set_gpio_out(GPIO_COMBO_I2S_CK_PIN, GPIO_OUT_ZERO); -+ -+ mt_set_gpio_mode(GPIO_COMBO_I2S_WS_PIN, GPIO_COMBO_I2S_WS_PIN_M_GPIO); -+ mt_set_gpio_dir(GPIO_COMBO_I2S_WS_PIN, GPIO_DIR_OUT); -+ mt_set_gpio_out(GPIO_COMBO_I2S_WS_PIN, GPIO_OUT_ZERO); -+ -+ mt_set_gpio_mode(GPIO_COMBO_I2S_DAT_PIN, GPIO_COMBO_I2S_DAT_PIN_M_GPIO); -+ mt_set_gpio_dir(GPIO_COMBO_I2S_DAT_PIN, GPIO_DIR_OUT); -+ mt_set_gpio_out(GPIO_COMBO_I2S_DAT_PIN, GPIO_OUT_ZERO); -+ WMT_PLAT_DBG_FUNC("WMT-PLAT:I2S deinit (out 0)\n"); -+ break; -+ default: -+ WMT_PLAT_WARN_FUNC("WMT-PLAT:Warnning, invalid state(%d) on I2S Group\n", state); -+ break; -+ } -+#else -+ WMT_PLAT_ERR_FUNC("[MT6620]Error:FM digital mode set, but no I2S GPIOs defined\n"); -+#endif -+#else -+ WMT_PLAT_INFO_FUNC -+ ("[MT6620]warnning:FM digital mode is not set, no I2S GPIO settings should be modified by combo driver\n"); -+#endif -+ -+#else /* #if defined(CONFIG_MTK_GPIO_LEGACY) */ -+#endif -+ return 0; -+} -+ -+INT32 wmt_plat_wake_lock_ctrl(ENUM_WL_OP opId) -+{ -+#ifdef CFG_WMT_WAKELOCK_SUPPORT -+ static INT32 counter; -+ INT32 status; -+ INT32 ret = 0; -+ -+ ret = mutex_lock_killable(&gOsSLock); -+ if (ret) { -+ WMT_PLAT_ERR_FUNC("--->lock gOsSLock failed, ret=%d\n", ret); -+ return ret; -+ } -+ -+ if (WL_OP_GET == opId) -+ ++counter; -+ else if (WL_OP_PUT == opId) -+ --counter; -+ -+ mutex_unlock(&gOsSLock); -+ if (WL_OP_GET == opId && counter == 1) { -+ #ifdef CONFIG_PM_WAKELOCKS -+ __pm_stay_awake(&wmtWakeLock); -+ status = wmtWakeLock.active; -+ #else -+ wake_lock(&wmtWakeLock); -+ status = wake_lock_active(&wmtWakeLock); -+ #endif -+ WMT_PLAT_DBG_FUNC("WMT-PLAT: after wake_lock(%d), counter(%d)\n", status, counter); -+ -+ } else if (WL_OP_PUT == opId && counter == 0) { -+ #ifdef CONFIG_PM_WAKELOCKS -+ __pm_relax(&wmtWakeLock); -+ status = wmtWakeLock.active; -+ #else -+ wake_unlock(&wmtWakeLock); -+ status = wake_lock_active(&wmtWakeLock); -+ #endif -+ WMT_PLAT_DBG_FUNC("WMT-PLAT: after wake_unlock(%d), counter(%d)\n", status, counter); -+ } else { -+ #ifdef CONFIG_PM_WAKELOCKS -+ status = wmtWakeLock.active; -+ #else -+ status = wake_lock_active(&wmtWakeLock); -+ #endif -+ WMT_PLAT_WARN_FUNC("WMT-PLAT: wakelock status(%d), counter(%d)\n", status, counter); -+ } -+ return 0; -+#else -+ WMT_PLAT_WARN_FUNC("WMT-PLAT: host awake function is not supported.\n"); -+ return 0; -+ -+#endif -+} -+EXPORT_SYMBOL(wmt_plat_wake_lock_ctrl); -+ -+INT32 wmt_plat_soc_paldo_ctrl(ENUM_PALDO_TYPE ePt, ENUM_PALDO_OP ePo) -+{ -+ INT32 iRet = 0; -+ -+ switch (ePt) { -+ -+ case BT_PALDO: -+ iRet = mtk_wcn_consys_hw_bt_paldo_ctrl(ePo); -+ break; -+ case WIFI_PALDO: -+ iRet = mtk_wcn_consys_hw_wifi_paldo_ctrl(ePo); -+ break; -+ case FM_PALDO: -+ case GPS_PALDO: -+ iRet = mtk_wcn_consys_hw_vcn28_ctrl(ePo); -+ break; -+ default: -+ WMT_PLAT_WARN_FUNC("WMT-PLAT:Warnning, invalid type(%d) in palod_ctrl\n", ePt); -+ break; -+ } -+ return iRet; -+} -+EXPORT_SYMBOL(wmt_plat_soc_paldo_ctrl); -+ -+UINT8 *wmt_plat_get_emi_virt_add(UINT32 offset) -+{ -+ return mtk_wcn_consys_emi_virt_addr_get(offset); -+} -+EXPORT_SYMBOL(wmt_plat_get_emi_virt_add); -+ -+P_CONSYS_EMI_ADDR_INFO wmt_plat_get_emi_phy_add(VOID) -+{ -+ return &mtk_wcn_emi_addr_info; -+} -+EXPORT_SYMBOL(wmt_plat_get_emi_phy_add); -+ -+#if CONSYS_ENALBE_SET_JTAG -+UINT32 wmt_plat_jtag_flag_ctrl(UINT32 en) -+{ -+ return 0; -+} -+EXPORT_SYMBOL(wmt_plat_jtag_flag_ctrl); -+#endif -+ -+#if CFG_WMT_DUMP_INT_STATUS -+VOID wmt_plat_BGF_irq_dump_status(VOID) -+{ -+ WMT_PLAT_INFO_FUNC("this function is null in MT8127\n"); -+} -+EXPORT_SYMBOL(wmt_plat_BGF_irq_dump_status); -+ -+MTK_WCN_BOOL wmt_plat_dump_BGF_irq_status(VOID) -+{ -+ return MTK_WCN_BOOL_FALSE; -+} -+EXPORT_SYMBOL(wmt_plat_dump_BGF_irq_status); -+#endif -+ -+UINT32 wmt_plat_read_cpupcr(void) -+{ -+ return CONSYS_REG_READ(conn_reg.mcu_base + CONSYS_CPUPCR_OFFSET); -+} -+EXPORT_SYMBOL(wmt_plat_read_cpupcr); -+ -+UINT32 wmt_plat_read_dmaregs(UINT32 type) -+{ -+ return 0; -+#if 0 -+ switch (type) { -+ case CONNSYS_CLK_GATE_STATUS: -+ return CONSYS_REG_READ(CONNSYS_CLK_GATE_STATUS_REG); -+ case CONSYS_EMI_STATUS: -+ return CONSYS_REG_READ(CONSYS_EMI_STATUS_REG); -+ case SYSRAM1: -+ return CONSYS_REG_READ(SYSRAM1_REG); -+ case SYSRAM2: -+ return CONSYS_REG_READ(SYSRAM2_REG); -+ case SYSRAM3: -+ return CONSYS_REG_READ(SYSRAM3_REG); -+ default: -+ return 0; -+ } -+#endif -+} -+ -+INT32 wmt_plat_set_host_dump_state(ENUM_HOST_DUMP_STATE state) -+{ -+ PUINT8 p_virtual_addr = NULL; -+ -+ p_virtual_addr = wmt_plat_get_emi_virt_add(EXP_APMEM_CTRL_HOST_SYNC_STATE); -+ if (!p_virtual_addr) { -+ WMT_PLAT_ERR_FUNC("get virtual address fail\n"); -+ return -1; -+ } -+ -+ CONSYS_REG_WRITE(p_virtual_addr, state); -+ -+ return 0; -+} -+EXPORT_SYMBOL(wmt_plat_set_host_dump_state); -+ -+UINT32 wmt_plat_force_trigger_assert(ENUM_FORCE_TRG_ASSERT_T type) -+{ -+ PUINT8 p_virtual_addr = NULL; -+ -+ switch (type) { -+ case STP_FORCE_TRG_ASSERT_EMI: -+ -+ WMT_PLAT_INFO_FUNC("[Force Assert] stp_trigger_firmware_assert_via_emi -->\n"); -+ p_virtual_addr = wmt_plat_get_emi_virt_add(EXP_APMEM_CTRL_HOST_OUTBAND_ASSERT_W1); -+ if (!p_virtual_addr) { -+ WMT_PLAT_ERR_FUNC("get virtual address fail\n"); -+ return -1; -+ } -+ -+ CONSYS_REG_WRITE(p_virtual_addr, EXP_APMEM_HOST_OUTBAND_ASSERT_MAGIC_W1); -+ WMT_PLAT_INFO_FUNC("[Force Assert] stp_trigger_firmware_assert_via_emi <--\n"); -+ break; -+ case STP_FORCE_TRG_ASSERT_DEBUG_PIN: -+ -+ CONSYS_REG_WRITE(conn_reg.topckgen_base + CONSYS_AP2CONN_OSC_EN_OFFSET, -+ CONSYS_REG_READ(conn_reg.topckgen_base + -+ CONSYS_AP2CONN_OSC_EN_OFFSET) & ~CONSYS_AP2CONN_WAKEUP_BIT); -+ WMT_PLAT_INFO_FUNC("enable:dump CONSYS_AP2CONN_OSC_EN_REG(0x%x)\n", -+ CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_AP2CONN_OSC_EN_OFFSET)); -+ usleep_range(64, 96); -+ CONSYS_REG_WRITE(conn_reg.topckgen_base + CONSYS_AP2CONN_OSC_EN_OFFSET, -+ CONSYS_REG_READ(conn_reg.topckgen_base + -+ CONSYS_AP2CONN_OSC_EN_OFFSET) | CONSYS_AP2CONN_WAKEUP_BIT); -+ WMT_PLAT_INFO_FUNC("disable:dump CONSYS_AP2CONN_OSC_EN_REG(0x%x)\n", -+ CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_AP2CONN_OSC_EN_OFFSET)); -+ -+ break; -+ default: -+ WMT_PLAT_ERR_FUNC("unknown force trigger assert type\n"); -+ break; -+ } -+ -+ return 0; -+} -+EXPORT_SYMBOL(wmt_plat_force_trigger_assert); -+ -+INT32 wmt_plat_update_host_sync_num(VOID) -+{ -+ PUINT8 p_virtual_addr = NULL; -+ UINT32 sync_num = 0; -+ -+ p_virtual_addr = wmt_plat_get_emi_virt_add(EXP_APMEM_CTRL_HOST_SYNC_NUM); -+ if (!p_virtual_addr) { -+ WMT_PLAT_ERR_FUNC("get virtual address fail\n"); -+ return -1; -+ } -+ -+ sync_num = CONSYS_REG_READ(p_virtual_addr); -+ CONSYS_REG_WRITE(p_virtual_addr, sync_num + 1); -+ -+ return 0; -+} -+EXPORT_SYMBOL(wmt_plat_update_host_sync_num); -+ -+INT32 wmt_plat_get_dump_info(UINT32 offset) -+{ -+ PUINT8 p_virtual_addr = NULL; -+ -+ p_virtual_addr = wmt_plat_get_emi_virt_add(offset); -+ if (!p_virtual_addr) { -+ WMT_PLAT_ERR_FUNC("get virtual address fail\n"); -+ return -1; -+ } -+ WMT_PLAT_INFO_FUNC("connsys_reg_read (0x%x), (0x%p), (0x%x)\n", CONSYS_REG_READ(p_virtual_addr), p_virtual_addr, -+ offset); -+ return CONSYS_REG_READ(p_virtual_addr); -+} -+EXPORT_SYMBOL(wmt_plat_get_dump_info); -+ -+UINT32 wmt_plat_get_soc_chipid(void) -+{ -+ UINT32 chipId = mtk_wcn_consys_soc_chipid(); -+ -+ WMT_PLAT_INFO_FUNC("current SOC chip:0x%x\n", chipId); -+ return chipId; -+} -+EXPORT_SYMBOL(wmt_plat_get_soc_chipid); -+ -+#if CFG_WMT_LTE_COEX_HANDLING -+INT32 wmt_plat_get_tdm_antsel_index(VOID) -+{ -+ WMT_PLAT_INFO_FUNC("not support LTE in this platform\n"); -+ return 0; -+} -+EXPORT_SYMBOL(wmt_plat_get_tdm_antsel_index); -+#endif -+INT32 wmt_plat_set_dbg_mode(UINT32 flag) -+{ -+ return -1; -+} -+VOID wmt_plat_set_dynamic_dumpmem(UINT32 *buf) -+{ -+ mtk_wcn_consys_set_dynamic_dump(buf); -+} -diff --git a/drivers/misc/mediatek/connectivity/wlan/Makefile b/drivers/misc/mediatek/connectivity/wlan/Makefile -new file mode 100644 -index 000000000000..36ce26810912 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/Makefile -@@ -0,0 +1,8 @@ -+ifeq ($(CONFIG_MTK_COMBO_WIFI),y) -+ subdir-ccflags-y += -D MTK_WCN_BUILT_IN_DRIVER -+endif -+ -+ifneq ($(filter "CONSYS_%",$(CONFIG_MTK_COMBO_CHIP)),) -+$(warning include gen2) -+ obj-y += gen2/ -+endif -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/Makefile b/drivers/misc/mediatek/connectivity/wlan/gen2/Makefile -new file mode 100644 -index 000000000000..09e4d66436a0 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/Makefile -@@ -0,0 +1,237 @@ -+# --------------------------------------------------- -+# Compile Options -+# --------------------------------------------------- -+ccflags-y += -DLINUX -DMT6628 -+ -+ccflags-y += -DCFG_SUPPORT_AGPS_ASSIST=1 -+ccflags-y += -DCFG_SUPPORT_TSF_USING_BOOTTIME=1 -+ccflags-y += -DCFG_P2P_LEGACY_COEX_REVISE=1 -+ccflags-y += -DARP_MONITER_ENABLE=1 -+ -+ifeq ($(CONFIG_MTK_WAPI_SUPPORT), y) -+ ccflags-y += -DCFG_SUPPORT_WAPI=1 -+else -+ ccflags-y += -DCFG_SUPPORT_WAPI=0 -+endif -+ -+ifeq ($(CONFIG_MTK_WIFI_MCC_SUPPORT), y) -+ ccflags-y += -DCFG_SUPPORT_MCC=1 -+else -+ ccflags-y += -DCFG_SUPPORT_MCC=0 -+endif -+ -+ifeq ($(CONFIG_HAVE_XLOG_FEATURE), y) -+ ccflags-y += -DCFG_SUPPORT_XLOG=1 -+else -+ ccflags-y += -DCFG_SUPPORT_XLOG=0 -+endif -+ -+ifeq ($(CONFIG_MTK_AEE_FEATURE), y) -+ ccflags-y += -DCFG_SUPPORT_AEE=1 -+else -+ ccflags-y += -DCFG_SUPPORT_AEE=0 -+endif -+ -+#ifeq ($(CONFIG_MTK_COMBO_WIFI_HIF_SDIO1), y) -+# ccflags-y += -D_HIF_SDIO=1 -+#endif -+ -+ifeq ($(CONFIG_MTK_PASSPOINT_R1_SUPPORT), y) -+ ccflags-y += -DCFG_SUPPORT_HOTSPOT_2_0=1 -+ ccflags-y += -DCFG_HS20_DEBUG=1 -+ ccflags-y += -DCFG_ENABLE_GTK_FRAME_FILTER=1 -+else -+ ccflags-y += -DCFG_SUPPORT_HOTSPOT_2_0=0 -+ ccflags-y += -DCFG_HS20_DEBUG=0 -+ ccflags-y += -DCFG_ENABLE_GTK_FRAME_FILTER=0 -+endif -+ -+MTK_MET_PROFILING_SUPPORT = no -+ifeq ($(MTK_MET_PROFILING_SUPPORT), yes) -+ ccflags-y += -DCFG_SUPPORT_MET_PROFILING=1 -+else -+ ccflags-y += -DCFG_SUPPORT_MET_PROFILING=0 -+endif -+ -+ifeq ($(CONFIG_MTK_TC1_FEATURE), y) -+ifeq ($(CONFIG_MTK_GPT_SCHEME_SUPPORT), y) -+ ccflags-y += -I$(srctree)/drivers/misc/mediatek/tc1_interface/gpt -+else -+ ccflags-y += -I$(srctree)/drivers/misc/mediatek/tc1_interface/pmt -+endif -+ ccflags-y += -DCFG_TC1_FEATURE=1 -+ ccflags-y += -DCFG_SUPPORT_CFG_FILE=1 -+else -+ ccflags-y += -DCFG_TC1_FEATURE=0 -+endif -+ -+MTK_SRAM_SIZE_OPTION=0 -+ifeq ($(CONFIG_ARCH_MT6755), y) -+ MTK_SRAM_SIZE_OPTION=2 -+endif -+ifeq ($(CONFIG_ARCH_MT6735), y) -+ MTK_SRAM_SIZE_OPTION=1 -+endif -+ifeq ($(CONFIG_ARCH_MT6735M), y) -+ MTK_SRAM_SIZE_OPTION=1 -+endif -+ifeq ($(CONFIG_ARCH_MT6753), y) -+ MTK_SRAM_SIZE_OPTION=1 -+endif -+ifeq ($(CONFIG_ARCH_MT6580), y) -+ MTK_SRAM_SIZE_OPTION=1 -+endif -+ifeq ($(CONFIG_ARCH_MT8163), y) -+ MTK_SRAM_SIZE_OPTION=1 -+endif -+ccflags-y += -DCFG_SRAM_SIZE_OPTION=$(MTK_SRAM_SIZE_OPTION) -+ -+ifeq ($(strip $(TRUSTONIC_TEE_SUPPORT)),yes) -+ifeq ($(strip $(MTK_TEE_CCCI_SECURE_SHARE_MEM_SUPPORT)),yes) -+ ccflags-y += -DTRUSTONIC_TEE_SUPPORT -+ ccflags-y += -DMTK_TEE_CCCI_SECURE_SHARE_MEM_SUPPORT -+endif -+endif -+ -+ccflags-y += -D_HIF_SDIO=1 -+ -+ccflags-y += -DDBG=0 -+ccflags-y += -I$(src)/os -I$(src)/os/linux/include -I$(src)/os/linux/hif/ahb/include -+ccflags-y += -I$(src)/include -I$(src)/include/nic -I$(src)/include/mgmt -+ccflags-y += -I$(srctree)/drivers/misc/mediatek/base/power/include -+ccflags-y += -I$(srctree)/drivers/misc/mediatek/include/ -+ -+MODULE_NAME := wlan_gen2 -+obj-$(CONFIG_MTK_COMBO_WIFI) += $(MODULE_NAME).o -+#obj-m += $(MODULE_NAME).o if CONFIG_MTK_COMBO_WIFI=m ==> obj-m means ko module, not build in obj-y -+ -+# --------------------------------------------------- -+# Directory List -+# --------------------------------------------------- -+COMMON_DIR := common/ -+OS_DIR := os/linux/ -+HIF_DIR := os/linux/hif/ahb/ -+NIC_DIR := nic/ -+MGMT_DIR := mgmt/ -+DMA_DIR := ../../../../platform/$(call lc,$(MTK_PLATFORM))/kernel/drivers/wifi/ -+PLAT_DIR := os/linux/plat/$(MTK_PLATFORM)/ -+HIF_AHB_PDMA := $(HIF_DIR)$(MTK_PLATFORM)/ -+#$(call lc,$(MTK_PLATFORM)) -+ -+ -+# --------------------------------------------------- -+# Objects List -+# --------------------------------------------------- -+ -+COMMON_OBJS := $(COMMON_DIR)dump.o \ -+ $(COMMON_DIR)wlan_lib.o \ -+ $(COMMON_DIR)wlan_oid.o \ -+ $(COMMON_DIR)wlan_bow.o \ -+ $(COMMON_DIR)debug.o -+ -+NIC_OBJS := $(NIC_DIR)nic.o \ -+ $(NIC_DIR)nic_tx.o \ -+ $(NIC_DIR)nic_rx.o \ -+ $(NIC_DIR)nic_pwr_mgt.o \ -+ $(NIC_DIR)cmd_buf.o \ -+ $(NIC_DIR)que_mgt.o \ -+ $(NIC_DIR)nic_cmd_event.o -+ -+OS_OBJS := $(OS_DIR)gl_init.o \ -+ $(OS_DIR)gl_kal.o \ -+ $(OS_DIR)gl_bow.o \ -+ $(OS_DIR)gl_wext.o \ -+ $(OS_DIR)gl_wext_priv.o \ -+ $(OS_DIR)gl_rst.o \ -+ $(OS_DIR)gl_cfg80211.o \ -+ $(OS_DIR)gl_vendor.o \ -+ $(OS_DIR)platform.o \ -+ $(OS_DIR)gl_proc.o -+ -+MGMT_OBJS := $(MGMT_DIR)ais_fsm.o \ -+ $(MGMT_DIR)aaa_fsm.o \ -+ $(MGMT_DIR)assoc.o \ -+ $(MGMT_DIR)auth.o \ -+ $(MGMT_DIR)bss.o \ -+ $(MGMT_DIR)cnm.o \ -+ $(MGMT_DIR)cnm_timer.o \ -+ $(MGMT_DIR)cnm_mem.o \ -+ $(MGMT_DIR)hem_mbox.o \ -+ $(MGMT_DIR)mib.o \ -+ $(MGMT_DIR)privacy.o \ -+ $(MGMT_DIR)rate.o \ -+ $(MGMT_DIR)rlm.o \ -+ $(MGMT_DIR)rlm_domain.o \ -+ $(MGMT_DIR)rlm_obss.o \ -+ $(MGMT_DIR)rlm_protection.o \ -+ $(MGMT_DIR)rsn.o \ -+ $(MGMT_DIR)saa_fsm.o \ -+ $(MGMT_DIR)scan.o \ -+ $(MGMT_DIR)scan_fsm.o \ -+ $(MGMT_DIR)sec_fsm.o \ -+ $(MGMT_DIR)swcr.o \ -+ $(MGMT_DIR)swcr.o \ -+ $(MGMT_DIR)roaming_fsm.o \ -+ $(MGMT_DIR)hs20.o -+ -+# --------------------------------------------------- -+# TDLS Objects List -+# --------------------------------------------------- -+MGMT_OBJS += $(MGMT_DIR)tdls.o \ -+ $(MGMT_DIR)tdls_com.o -+ -+# --------------------------------------------------- -+# STATS Objects List -+# --------------------------------------------------- -+MGMT_OBJS += $(MGMT_DIR)stats.o -+ -+# --------------------------------------------------- -+# P2P Objects List -+# --------------------------------------------------- -+ -+COMMON_OBJS += $(COMMON_DIR)wlan_p2p.o -+ -+NIC_OBJS += $(NIC_DIR)p2p_nic.o -+ -+OS_OBJS += $(OS_DIR)gl_p2p.o \ -+ $(OS_DIR)gl_p2p_cfg80211.o \ -+ $(OS_DIR)gl_p2p_init.o \ -+ $(OS_DIR)gl_p2p_kal.o -+ -+MGMT_OBJS += $(MGMT_DIR)p2p_assoc.o \ -+ $(MGMT_DIR)p2p_bss.o \ -+ $(MGMT_DIR)p2p_fsm.o \ -+ $(MGMT_DIR)p2p_func.o \ -+ $(MGMT_DIR)p2p_rlm.o \ -+ $(MGMT_DIR)p2p_rlm_obss.o \ -+ $(MGMT_DIR)p2p_scan.o \ -+ $(MGMT_DIR)p2p_ie.o \ -+ $(MGMT_DIR)p2p_state.o -+ -+ -+ifeq ($(CONFIG_MTK_WAPI_SUPPORT), y) -+MGMT_OBJS += $(MGMT_DIR)wapi.o -+endif -+ -+ifeq ($(WLAN_PROC), y) -+OS_OBJS += gl_proc.o -+endif -+ -+$(warning $(CONFIG_MACH_MT7623)) -+ -+ifeq ($(CONFIG_MACH_MT7623), y) -+HIF_AHB_PDMA = $(HIF_DIR)mt8127/ -+endif -+HIF_OBJS := $(HIF_DIR)arm.o \ -+ $(HIF_DIR)ahb.o \ -+ $(HIF_AHB_PDMA)ahb_pdma.o -+ifeq ($(CONFIG_ARCH_MT6755), y) -+PLAT_OBJS := $(PLAT_DIR)plat_priv.o -+$(MODULE_NAME)-objs += $(PLAT_OBJS) -+endif -+$(MODULE_NAME)-objs += $(COMMON_OBJS) -+$(MODULE_NAME)-objs += $(NIC_OBJS) -+$(MODULE_NAME)-objs += $(OS_OBJS) -+$(MODULE_NAME)-objs += $(HIF_OBJS) -+$(MODULE_NAME)-objs += $(MGMT_OBJS) -+ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/common/debug.c b/drivers/misc/mediatek/connectivity/wlan/gen2/common/debug.c -new file mode 100644 -index 000000000000..e31e0b86d231 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/common/debug.c -@@ -0,0 +1,165 @@ -+#include "precomp.h" -+#include "gl_kal.h" -+ -+struct COMMAND { -+ UINT_8 ucCID; -+ BOOLEAN fgSetQuery; -+ BOOLEAN fgNeedResp; -+ UINT_8 ucCmdSeqNum; -+}; -+ -+struct SECURITY_FRAME { -+ UINT_16 u2EthType; -+ UINT_16 u2Reserved; -+}; -+ -+struct MGMT_FRAME { -+ UINT_16 u2FrameCtl; -+ UINT_16 u2DurationID; -+}; -+ -+struct TC_RES_RELEASE_ENTRY { -+ UINT_64 u8RelaseTime; -+ UINT_32 u4RelCID; -+ UINT_8 ucTc4RelCnt; -+ UINT_8 ucAvailableTc4; -+}; -+ -+struct CMD_TRACE_ENTRY { -+ UINT_64 u8TxTime; -+ COMMAND_TYPE eCmdType; -+ union { -+ struct COMMAND rCmd; -+ struct SECURITY_FRAME rSecFrame; -+ struct MGMT_FRAME rMgmtFrame; -+ } u; -+}; -+ -+#define TC_RELEASE_TRACE_BUF_MAX_NUM 100 -+#define TXED_CMD_TRACE_BUF_MAX_NUM 100 -+ -+static struct TC_RES_RELEASE_ENTRY *gprTcReleaseTraceBuffer; -+static struct CMD_TRACE_ENTRY *gprCmdTraceEntry; -+VOID wlanDebugInit(VOID) -+{ -+ /* debug for command/tc4 resource begin */ -+ gprTcReleaseTraceBuffer = -+ kalMemAlloc(TC_RELEASE_TRACE_BUF_MAX_NUM * sizeof(struct TC_RES_RELEASE_ENTRY), PHY_MEM_TYPE); -+ kalMemZero(gprTcReleaseTraceBuffer, TC_RELEASE_TRACE_BUF_MAX_NUM * sizeof(struct TC_RES_RELEASE_ENTRY)); -+ gprCmdTraceEntry = kalMemAlloc(TXED_CMD_TRACE_BUF_MAX_NUM * sizeof(struct CMD_TRACE_ENTRY), PHY_MEM_TYPE); -+ kalMemZero(gprCmdTraceEntry, TXED_CMD_TRACE_BUF_MAX_NUM * sizeof(struct CMD_TRACE_ENTRY)); -+ /* debug for command/tc4 resource end */ -+} -+ -+VOID wlanDebugUninit(VOID) -+{ -+ /* debug for command/tc4 resource begin */ -+ kalMemFree(gprTcReleaseTraceBuffer, PHY_MEM_TYPE, -+ TC_RELEASE_TRACE_BUF_MAX_NUM * sizeof(struct TC_RES_RELEASE_ENTRY)); -+ kalMemFree(gprCmdTraceEntry, PHY_MEM_TYPE, TXED_CMD_TRACE_BUF_MAX_NUM * sizeof(struct CMD_TRACE_ENTRY)); -+ /* debug for command/tc4 resource end */ -+} -+ -+VOID wlanTraceTxCmd(P_CMD_INFO_T prCmd) -+{ -+ static UINT_16 u2CurEntry; -+ struct CMD_TRACE_ENTRY *prCurCmd = &gprCmdTraceEntry[u2CurEntry]; -+ -+ prCurCmd->u8TxTime = sched_clock(); -+ prCurCmd->eCmdType = prCmd->eCmdType; -+ if (prCmd->eCmdType == COMMAND_TYPE_MANAGEMENT_FRAME) { -+ P_WLAN_MAC_MGMT_HEADER_T prMgmt = (P_WLAN_MAC_MGMT_HEADER_T)((P_MSDU_INFO_T)prCmd->prPacket)->prPacket; -+ -+ prCurCmd->u.rMgmtFrame.u2FrameCtl = prMgmt->u2FrameCtrl; -+ prCurCmd->u.rMgmtFrame.u2DurationID = prMgmt->u2Duration; -+ } else if (prCmd->eCmdType == COMMAND_TYPE_SECURITY_FRAME) { -+ PUINT_8 pucPkt = (PUINT_8)((struct sk_buff *)prCmd->prPacket)->data; -+ -+ prCurCmd->u.rSecFrame.u2EthType = -+ (pucPkt[ETH_TYPE_LEN_OFFSET] << 8) | (pucPkt[ETH_TYPE_LEN_OFFSET + 1]); -+ } else { -+ prCurCmd->u.rCmd.ucCID = prCmd->ucCID; -+ prCurCmd->u.rCmd.ucCmdSeqNum = prCmd->ucCmdSeqNum; -+ prCurCmd->u.rCmd.fgNeedResp = prCmd->fgNeedResp; -+ prCurCmd->u.rCmd.fgSetQuery = prCmd->fgSetQuery; -+ } -+ u2CurEntry++; -+ if (u2CurEntry == TC_RELEASE_TRACE_BUF_MAX_NUM) -+ u2CurEntry = 0; -+} -+ -+VOID wlanTraceReleaseTcRes(P_ADAPTER_T prAdapter, PUINT_8 aucTxRlsCnt, UINT_8 ucAvailable) -+{ -+ static UINT_16 u2CurEntry; -+ struct TC_RES_RELEASE_ENTRY *prCurBuf = &gprTcReleaseTraceBuffer[u2CurEntry]; -+ -+ HAL_MCR_RD(prAdapter, MCR_D2HRM2R, &prCurBuf->u4RelCID); -+ prCurBuf->u8RelaseTime = sched_clock(); -+ prCurBuf->ucTc4RelCnt = aucTxRlsCnt[TC4_INDEX]; -+ prCurBuf->ucAvailableTc4 = ucAvailable; -+ u2CurEntry++; -+ if (u2CurEntry == TXED_CMD_TRACE_BUF_MAX_NUM) -+ u2CurEntry = 0; -+} -+ -+VOID wlanDumpTcResAndTxedCmd(PUINT_8 pucBuf, UINT_32 maxLen) -+{ -+ UINT_16 i = 0; -+ struct CMD_TRACE_ENTRY *prCmd = gprCmdTraceEntry; -+ struct TC_RES_RELEASE_ENTRY *prTcRel = gprTcReleaseTraceBuffer; -+ -+ if (pucBuf) { -+ int bufLen = 0; -+ -+ for (; i < TXED_CMD_TRACE_BUF_MAX_NUM/2; i++) { -+ bufLen = snprintf(pucBuf, maxLen, -+ "%d: Time %llu, Type %d, Content %08x; %d: Time %llu, Type %d, Content %08x\n", -+ i*2, prCmd[i*2].u8TxTime, prCmd[i*2].eCmdType, *(PUINT_32)(&prCmd[i*2].u.rCmd.ucCID), -+ i*2+1, prCmd[i*2+1].u8TxTime, prCmd[i*2+1].eCmdType, -+ *(PUINT_32)(&prCmd[i*2+1].u.rCmd.ucCID)); -+ if (bufLen <= 0 || (UINT_32)bufLen >= maxLen) -+ break; -+ pucBuf += bufLen; -+ maxLen -= bufLen; -+ } -+ for (i = 0; i < TC_RELEASE_TRACE_BUF_MAX_NUM/2; i++) { -+ bufLen = snprintf(pucBuf, maxLen, -+ "%d: Time %llu, Tc4Cnt %d, Free %d, CID %08x; %d: Time %llu, Tc4Cnt %d, Free %d CID %08x\n", -+ i*2, prTcRel[i*2].u8RelaseTime, prTcRel[i*2].ucTc4RelCnt, prTcRel[i*2].ucAvailableTc4, -+ prTcRel[i*2].u4RelCID, -+ i*2+1, prTcRel[i*2+1].u8RelaseTime, prTcRel[i*2+1].ucTc4RelCnt, -+ prTcRel[i*2+1].ucAvailableTc4, prTcRel[i*2+1].u4RelCID); -+ if (bufLen <= 0 || (UINT_32)bufLen >= maxLen) -+ break; -+ pucBuf += bufLen; -+ maxLen -= bufLen; -+ } -+ return; -+ } -+ for (; i < TXED_CMD_TRACE_BUF_MAX_NUM/4; i++) { -+ LOG_FUNC("%d: Time %llu, Type %d, Content %08x; %d: Time %llu, Type %d, Content %08x; ", -+ i*4, prCmd[i*4].u8TxTime, prCmd[i*4].eCmdType, -+ *(PUINT_32)(&prCmd[i*4].u.rCmd.ucCID), -+ i*4+1, prCmd[i*4+1].u8TxTime, prCmd[i*4+1].eCmdType, -+ *(PUINT_32)(&prCmd[i*4+1].u.rCmd.ucCID)); -+ LOG_FUNC("%d: Time %llu, Type %d, Content %08x; %d: Time %llu, Type %d, Content %08x\n", -+ i*4+2, prCmd[i*4+2].u8TxTime, prCmd[i*4+2].eCmdType, -+ *(PUINT_32)(&prCmd[i*4+2].u.rCmd.ucCID), -+ i*4+3, prCmd[i*4+3].u8TxTime, prCmd[i*4+3].eCmdType, -+ *(PUINT_32)(&prCmd[i*4+3].u.rCmd.ucCID)); -+ } -+ for (i = 0; i < TC_RELEASE_TRACE_BUF_MAX_NUM/4; i++) { -+ LOG_FUNC( -+ "%d: Time %llu, Tc4Cnt %d, Free %d, CID %08x; %d: Time %llu, Tc4Cnt %d, Free %d, CID %08x;", -+ i*4, prTcRel[i*4].u8RelaseTime, prTcRel[i*4].ucTc4RelCnt, -+ prTcRel[i*4].ucAvailableTc4, prTcRel[i*4].u4RelCID, -+ i*4+1, prTcRel[i*4+1].u8RelaseTime, prTcRel[i*4+1].ucTc4RelCnt, -+ prTcRel[i*4+1].ucAvailableTc4, prTcRel[i*4+1].u4RelCID); -+ LOG_FUNC( -+ " %d: Time %llu, Tc4Cnt %d, Free %d, CID %08x; %d: Time %llu, Tc4Cnt %d, Free %d, CID %08x\n", -+ i*4+2, prTcRel[i*4+2].u8RelaseTime, prTcRel[i*4+2].ucTc4RelCnt, -+ prTcRel[i*4+2].ucAvailableTc4, prTcRel[i*4+2].u4RelCID, -+ i*4+3, prTcRel[i*4+3].u8RelaseTime, prTcRel[i*4+3].ucTc4RelCnt, -+ prTcRel[i*4+3].ucAvailableTc4, prTcRel[i*4+3].u4RelCID); -+ } -+} -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/common/dump.c b/drivers/misc/mediatek/connectivity/wlan/gen2/common/dump.c -new file mode 100644 -index 000000000000..486ba239f16a ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/common/dump.c -@@ -0,0 +1,345 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/common/dump.c#1 -+*/ -+ -+/*! \file "dump.c" -+ \brief Provide memory dump function for debugging. -+ -+ Provide memory dump function for debugging. -+*/ -+ -+/* -+** Log: dump.c -+ * -+ * 11 24 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * Adjust code for DBG and CONFIG_XLOG. -+ * -+ * 11 10 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * Using the new XLOG define for dum Memory. -+ * -+ * 11 03 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * Add dumpMemory8 at XLOG support. -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 19:58:51 GMT mtk01426 -+** Init develop -+** -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "precomp.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to dump a segment of memory in bytes. -+* -+* \param[in] pucStartAddr Pointer to the starting address of the memory to be dumped. -+* \param[in] u4Length Length of the memory to be dumped. -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID dumpMemory8(IN PUINT_8 pucStartAddr, IN UINT_32 u4Length) -+{ -+ ASSERT(pucStartAddr); -+ -+ LOG_FUNC("DUMP8 ADDRESS: %p, Length: %u\n", pucStartAddr, u4Length); -+ -+ while (u4Length > 0) { -+ if (u4Length >= 16) { -+ LOG_FUNC( -+ "(%p) %02x %02x %02x %02x %02x %02x %02x %02x - %02x %02x %02x %02x %02x %02x %02x %02x\n", -+ pucStartAddr, pucStartAddr[0], pucStartAddr[1], pucStartAddr[2], pucStartAddr[3], -+ pucStartAddr[4], pucStartAddr[5], pucStartAddr[6], pucStartAddr[7], pucStartAddr[8], -+ pucStartAddr[9], pucStartAddr[10], pucStartAddr[11], pucStartAddr[12], pucStartAddr[13], -+ pucStartAddr[14], pucStartAddr[15]); -+ u4Length -= 16; -+ pucStartAddr += 16; -+ } else { -+ switch (u4Length) { -+ case 1: -+ LOG_FUNC("(%p) %02x\n", pucStartAddr, pucStartAddr[0]); -+ break; -+ case 2: -+ LOG_FUNC("(%p) %02x %02x\n", pucStartAddr, pucStartAddr[0], pucStartAddr[1]); -+ break; -+ case 3: -+ LOG_FUNC("(%p) %02x %02x %02x\n", -+ pucStartAddr, pucStartAddr[0], pucStartAddr[1], pucStartAddr[2]); -+ break; -+ case 4: -+ LOG_FUNC("(%p) %02x %02x %02x %02x\n", -+ pucStartAddr, -+ pucStartAddr[0], pucStartAddr[1], pucStartAddr[2], pucStartAddr[3]); -+ break; -+ case 5: -+ LOG_FUNC("(%p) %02x %02x %02x %02x %02x\n", -+ pucStartAddr, -+ pucStartAddr[0], pucStartAddr[1], pucStartAddr[2], pucStartAddr[3], -+ pucStartAddr[4]); -+ break; -+ case 6: -+ LOG_FUNC("(%p) %02x %02x %02x %02x %02x %02x\n", -+ pucStartAddr, -+ pucStartAddr[0], pucStartAddr[1], pucStartAddr[2], pucStartAddr[3], -+ pucStartAddr[4], pucStartAddr[5]); -+ break; -+ case 7: -+ LOG_FUNC("(%p) %02x %02x %02x %02x %02x %02x %02x\n", -+ pucStartAddr, -+ pucStartAddr[0], pucStartAddr[1], pucStartAddr[2], pucStartAddr[3], -+ pucStartAddr[4], pucStartAddr[5], pucStartAddr[6]); -+ break; -+ case 8: -+ LOG_FUNC("(%p) %02x %02x %02x %02x %02x %02x %02x %02x\n", -+ pucStartAddr, -+ pucStartAddr[0], pucStartAddr[1], pucStartAddr[2], pucStartAddr[3], -+ pucStartAddr[4], pucStartAddr[5], pucStartAddr[6], pucStartAddr[7]); -+ break; -+ case 9: -+ LOG_FUNC("(%p) %02x %02x %02x %02x %02x %02x %02x %02x - %02x\n", -+ pucStartAddr, -+ pucStartAddr[0], pucStartAddr[1], pucStartAddr[2], pucStartAddr[3], -+ pucStartAddr[4], pucStartAddr[5], pucStartAddr[6], pucStartAddr[7], -+ pucStartAddr[8]); -+ break; -+ case 10: -+ LOG_FUNC("(%p) %02x %02x %02x %02x %02x %02x %02x %02x - %02x %02x\n", -+ pucStartAddr, -+ pucStartAddr[0], pucStartAddr[1], pucStartAddr[2], pucStartAddr[3], -+ pucStartAddr[4], pucStartAddr[5], pucStartAddr[6], pucStartAddr[7], -+ pucStartAddr[8], pucStartAddr[9]); -+ break; -+ case 11: -+ LOG_FUNC("(%p) %02x %02x %02x %02x %02x %02x %02x %02x - %02x %02x %02x\n", -+ pucStartAddr, -+ pucStartAddr[0], pucStartAddr[1], pucStartAddr[2], pucStartAddr[3], -+ pucStartAddr[4], pucStartAddr[5], pucStartAddr[6], pucStartAddr[7], -+ pucStartAddr[8], pucStartAddr[9], pucStartAddr[10]); -+ break; -+ case 12: -+ LOG_FUNC("(%p) %02x %02x %02x %02x %02x %02x %02x %02x - %02x %02x %02x %02x\n", -+ pucStartAddr, -+ pucStartAddr[0], pucStartAddr[1], pucStartAddr[2], pucStartAddr[3], -+ pucStartAddr[4], pucStartAddr[5], pucStartAddr[6], pucStartAddr[7], -+ pucStartAddr[8], pucStartAddr[9], pucStartAddr[10], pucStartAddr[11]); -+ break; -+ case 13: -+ LOG_FUNC("(%p) %02x %02x %02x %02x %02x %02x %02x %02x - %02x %02x %02x %02x %02x\n", -+ pucStartAddr, -+ pucStartAddr[0], pucStartAddr[1], pucStartAddr[2], pucStartAddr[3], -+ pucStartAddr[4], pucStartAddr[5], pucStartAddr[6], pucStartAddr[7], -+ pucStartAddr[8], pucStartAddr[9], pucStartAddr[10], pucStartAddr[11], -+ pucStartAddr[12]); -+ break; -+ case 14: -+ LOG_FUNC("(%p) %02x %02x %02x %02x %02x %02x %02x %02x - %02x %02x %02x %02x %02x %02x\n", -+ pucStartAddr, pucStartAddr[0], pucStartAddr[1], pucStartAddr[2], pucStartAddr[3], -+ pucStartAddr[4], pucStartAddr[5], pucStartAddr[6], pucStartAddr[7], -+ pucStartAddr[8], pucStartAddr[9], pucStartAddr[10], pucStartAddr[11], -+ pucStartAddr[12], pucStartAddr[13]); -+ break; -+ case 15: -+ LOG_FUNC( -+ "(%p) %02x %02x %02x %02x %02x %02x %02x %02x - %02x %02x %02x %02x %02x %02x %02x\n", -+ pucStartAddr, pucStartAddr[0], pucStartAddr[1], pucStartAddr[2], pucStartAddr[3], -+ pucStartAddr[4], pucStartAddr[5], pucStartAddr[6], pucStartAddr[7], -+ pucStartAddr[8], pucStartAddr[9], pucStartAddr[10], pucStartAddr[11], -+ pucStartAddr[12], pucStartAddr[13], pucStartAddr[14]); -+ break; -+ /* -+ default: -+ break; -+ */ -+ } -+ u4Length = 0; -+ } -+ } -+ -+ LOG_FUNC("\n"); -+ -+} /* end of dumpMemory8() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to dump a segment of memory in double words. -+* -+* \param[in] pucStartAddr Pointer to the starting address of the memory to be dumped. -+* \param[in] u4Length Length of the memory to be dumped. -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID dumpMemory32(IN PUINT_32 pu4StartAddr, IN UINT_32 u4Length) -+{ -+ PUINT_8 pucAddr; -+ -+ ASSERT(pu4StartAddr); -+ -+ LOG_FUNC("DUMP32 ADDRESS: %p, Length: %u\n", pu4StartAddr, u4Length); -+ -+ if (IS_NOT_ALIGN_4((ULONG) pu4StartAddr)) { -+ UINT_32 u4ProtrudeLen = sizeof(UINT_32) - ((ULONG) pu4StartAddr % 4); -+ -+ u4ProtrudeLen = ((u4Length < u4ProtrudeLen) ? u4Length : u4ProtrudeLen); -+ LOG_FUNC("pu4StartAddr is not at DW boundary.\n"); -+ pucAddr = (PUINT_8) &pu4StartAddr[0]; -+ -+ switch (u4ProtrudeLen) { -+ case 1: -+ LOG_FUNC("(%p) %02x------\n", pu4StartAddr, pucAddr[0]); -+ break; -+ case 2: -+ LOG_FUNC("(%p) %02x%02x----\n", pu4StartAddr, pucAddr[1], pucAddr[0]); -+ break; -+ case 3: -+ LOG_FUNC("(%p) %02x%02x%02x--\n", pu4StartAddr, pucAddr[2], pucAddr[1], pucAddr[0]); -+ break; -+ default: -+ break; -+ } -+ -+ u4Length -= u4ProtrudeLen; -+ pu4StartAddr = (PUINT_32) ((ULONG) pu4StartAddr + u4ProtrudeLen); -+ } -+ -+ while (u4Length > 0) { -+ if (u4Length >= 16) { -+ LOG_FUNC("(%p) %08x %08x %08x %08x\n", -+ pu4StartAddr, pu4StartAddr[0], pu4StartAddr[1], pu4StartAddr[2], pu4StartAddr[3]); -+ pu4StartAddr += 4; -+ u4Length -= 16; -+ } else { -+ switch (u4Length) { -+ case 1: -+ pucAddr = (PUINT_8) &pu4StartAddr[0]; -+ LOG_FUNC("(%p) ------%02x\n", pu4StartAddr, pucAddr[0]); -+ break; -+ case 2: -+ pucAddr = (PUINT_8) &pu4StartAddr[0]; -+ LOG_FUNC("(%p) ----%02x%02x\n", pu4StartAddr, pucAddr[1], pucAddr[0]); -+ break; -+ case 3: -+ pucAddr = (PUINT_8) &pu4StartAddr[0]; -+ LOG_FUNC("(%p) --%02x%02x%02x\n", pu4StartAddr, pucAddr[2], pucAddr[1], pucAddr[0]); -+ break; -+ case 4: -+ LOG_FUNC("(%p) %08x\n", pu4StartAddr, pu4StartAddr[0]); -+ break; -+ case 5: -+ pucAddr = (PUINT_8) &pu4StartAddr[1]; -+ LOG_FUNC("(%p) %08x ------%02x\n", pu4StartAddr, pu4StartAddr[0], pucAddr[0]); -+ break; -+ case 6: -+ pucAddr = (PUINT_8) &pu4StartAddr[1]; -+ LOG_FUNC("(%p) %08x ----%02x%02x\n", -+ pu4StartAddr, pu4StartAddr[0], pucAddr[1], pucAddr[0]); -+ break; -+ case 7: -+ pucAddr = (PUINT_8) &pu4StartAddr[1]; -+ LOG_FUNC("(%p) %08x --%02x%02x%02x\n", -+ pu4StartAddr, pu4StartAddr[0], pucAddr[2], pucAddr[1], pucAddr[0]); -+ break; -+ case 8: -+ LOG_FUNC("(%p) %08x %08x\n", pu4StartAddr, pu4StartAddr[0], pu4StartAddr[1]); -+ break; -+ case 9: -+ pucAddr = (PUINT_8) &pu4StartAddr[2]; -+ LOG_FUNC("(%p) %08x %08x ------%02x\n", -+ pu4StartAddr, pu4StartAddr[0], pu4StartAddr[1], pucAddr[0]); -+ break; -+ case 10: -+ pucAddr = (PUINT_8) &pu4StartAddr[2]; -+ LOG_FUNC("(%p) %08x %08x ----%02x%02x\n", -+ pu4StartAddr, pu4StartAddr[0], pu4StartAddr[1], pucAddr[1], pucAddr[0]); -+ break; -+ case 11: -+ pucAddr = (PUINT_8) &pu4StartAddr[2]; -+ LOG_FUNC("(%p) %08x %08x --%02x%02x%02x\n", -+ pu4StartAddr, -+ pu4StartAddr[0], pu4StartAddr[1], pucAddr[2], pucAddr[1], pucAddr[0]); -+ break; -+ case 12: -+ LOG_FUNC("(%p) %08x %08x %08x\n", -+ pu4StartAddr, pu4StartAddr[0], pu4StartAddr[1], pu4StartAddr[2]); -+ break; -+ case 13: -+ pucAddr = (PUINT_8) &pu4StartAddr[3]; -+ LOG_FUNC("(%p) %08x %08x %08x ------%02x\n", -+ pu4StartAddr, pu4StartAddr[0], pu4StartAddr[1], pu4StartAddr[2], pucAddr[0]); -+ break; -+ case 14: -+ pucAddr = (PUINT_8) &pu4StartAddr[3]; -+ LOG_FUNC("(%p) %08x %08x %08x ----%02x%02x\n", -+ pu4StartAddr, -+ pu4StartAddr[0], pu4StartAddr[1], pu4StartAddr[2], pucAddr[1], pucAddr[0]); -+ break; -+ case 15: -+ pucAddr = (PUINT_8) &pu4StartAddr[3]; -+ LOG_FUNC("(%p) %08x %08x %08x --%02x%02x%02x\n", -+ pu4StartAddr, -+ pu4StartAddr[0], pu4StartAddr[1], pu4StartAddr[2], -+ pucAddr[2], pucAddr[1], pucAddr[0]); -+ break; -+ /* -+ default: -+ break; -+ */ -+ } -+ u4Length = 0; -+ } -+ } -+ -+} /* end of dumpMemory32() */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/common/wlan_bow.c b/drivers/misc/mediatek/connectivity/wlan/gen2/common/wlan_bow.c -new file mode 100644 -index 000000000000..21bd849827e1 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/common/wlan_bow.c -@@ -0,0 +1,3442 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/common/wlan_bow.c#1 -+*/ -+ -+/*! \file wlan_bow.c -+ \brief This file contains the 802.11 PAL commands processing routines for -+ MediaTek Inc. 802.11 Wireless LAN Adapters. -+*/ -+ -+/* -+** Log: wlan_bow.c -+ * -+ * 03 02 2012 terry.wu -+ * NULL -+ * Sync CFG80211 modification from branch 2,2. -+ * -+ * 01 16 2012 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Support BOW for 5GHz band. -+ * -+ * 01 09 2012 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * [ALPS00110632] [Rose][LCA42][Cross Feature][Bluetooth]The "KE" pops up after the device reboots automatically.(once) -+ * -+ * Fix bow link disconnected event dereference. -+ * -+ * 09 29 2011 cm.chang -+ * NULL -+ * Change the function prototype of rlmDomainGetChnlList() -+ * -+ * 07 06 2011 terry.wu -+ * [WCXRP00000735] [MT6620 Wi-Fi][BoW][FW/Driver] Protect BoW connection establishment -+ * Improve BoW connection establishment speed. -+ * -+ * 06 23 2011 cp.wu -+ * [WCXRP00000798] [MT6620 Wi-Fi][Firmware] Follow-ups for WAPI frequency offset workaround in firmware SCN module -+ * change parameter name from PeerAddr to BSSID -+ * -+ * 06 21 2011 terry.wu -+ * NULL -+ * Fix BoW KE. -+ * -+ * 06 20 2011 terry.wu -+ * NULL -+ * Add BoW Rate Limitation. -+ * -+ * 06 20 2011 cp.wu -+ * [WCXRP00000798] [MT6620 Wi-Fi][Firmware] Follow-ups for WAPI frequency offset workaround in firmware SCN module -+ * 1. specify target's BSSID when requesting channel privilege. -+ * 2. pass BSSID information to firmware domain -+ * -+ * 06 17 2011 terry.wu -+ * NULL -+ * Add BoW 11N support. -+ * -+ * 06 07 2011 cp.wu -+ * [WCXRP00000681] [MT5931][Firmware] HIF code size reduction -+ * aware more compile options. -+ * -+ * 05 25 2011 terry.wu -+ * [WCXRP00000735] [MT6620 Wi-Fi][BoW][FW/Driver] Protect BoW connection establishment -+ * Add BoW Cancel Scan Request and Turn On deactive network function. -+ * -+ * 05 23 2011 terry.wu -+ * [WCXRP00000735] [MT6620 Wi-Fi][BoW][FW/Driver] Protect BoW connection establishment -+ * Add some BoW error handling. -+ * -+ * 05 22 2011 terry.wu -+ * [WCXRP00000735] [MT6620 Wi-Fi][BoW][FW/Driver] Protect BoW connection establishment -+ * . -+ * -+ * 05 22 2011 terry.wu -+ * [WCXRP00000735] [MT6620 Wi-Fi][BoW][FW/Driver] Protect BoW connection establishment -+ * Only reply probe response to its peer or mached SSID for BoW AP. -+ * -+ * 05 22 2011 terry.wu -+ * [WCXRP00000735] [MT6620 Wi-Fi][BoW][FW/Driver] Protect BoW connection establishment -+ * Add BoW SAA retry and disable disconnect event when AAA fail . -+ * -+ * 05 21 2011 terry.wu -+ * [WCXRP00000735] [MT6620 Wi-Fi][BoW][FW/Driver] Protect BoW connection establishment -+ * Protect BoW connection establishment. -+ * -+ * 05 17 2011 terry.wu -+ * [WCXRP00000730] [MT6620 Wi-Fi][BoW] Send deauth while disconnecting -+ * Send deauth while disconnecting BoW link. -+ * -+ * 05 17 2011 terry.wu -+ * [WCXRP00000707] [MT6620 Wi-Fi][Driver] Fix BoW Multiple Physical Link connect/disconnect issue -+ * Fix wrong StaRec state of BoW . -+ * -+ * 05 06 2011 terry.wu -+ * [WCXRP00000707] [MT6620 Wi-Fi][Driver] Fix BoW Multiple Physical Link connect/disconnect issue -+ * Fix BoW Multiple Physical Link connect/disconnect issue. -+ * -+ * 05 03 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Use kalMemAlloc to allocate event buffer for kalIndicateBOWEvent. -+ * -+ * 04 15 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Fix prAssocRspSwRfb casting. -+ * -+ * 04 15 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Add BOW short range mode. -+ * -+ * 04 12 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Add WMM IE for BOW initiator data. -+ * -+ * 04 10 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Change Link disconnection event procedure for hotspot and change skb length check to 1514 bytes. -+ * -+ * 04 09 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Change Link connection event procedure and change skb length check to 1512 bytes. -+ * -+ * 03 28 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Simplify link disconnected routine, remove link disconnected other routine. -+ * -+ * 03 27 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Support multiple physical link. -+ * -+ * 03 27 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Add new feature - multiple physical link support. -+ * -+ * 02 22 2011 wh.su -+ * [WCXRP00000486] [MT6620 Wi-Fi][BOW] Fixed the bow send frame but not encrypted issue -+ * fixed the BOW packet sending without encrypted issue. -+ * -+ * 02 21 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Fix BOW link disconnection bug. -+ * -+ * 02 16 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Add bowNotifyAllLinkDisconnected interface and change channel grant procedure for bow starting. -+ * -+ * 02 11 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Update BOW channel granted function. -+ * -+ * 02 10 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Fix kernel API change issue. -+ * Before ALPS 2.2 (2.2 included), kfifo_alloc() is -+ * struct kfifo *kfifo_alloc(unsigned int size, gfp_t gfp_mask, spinlock_t *lock); -+ * After ALPS 2.3, kfifo_alloc() is changed to -+ * int kfifo_alloc(struct kfifo *fifo, unsigned int size, gfp_t gfp_mask); -+ * -+ * 02 09 2011 cp.wu -+ * [WCXRP00000430] [MT6620 Wi-Fi][Firmware][Driver] Create V1.2 branch for MT6620E1 and MT6620E3 -+ * create V1.2 driver branch based on label MT6620_WIFI_DRIVER_V1_2_110209_1031 -+ * with BOW and P2P enabled as default -+ * -+ * 02 08 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Replace kfifo_get and kfifo_put with kfifo_out and kfifo_in. -+ * Update BOW get MAC status, remove returning event for AIS network type. -+ * -+ * 01 26 2011 cm.chang -+ * [WCXRP00000395] [MT6620 Wi-Fi][Driver][FW] Search STA_REC with additional net type index argument -+ * . -+ * -+ * 01 11 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Update BOW Activity Report structure and bug fix. -+ * -+ * 01 10 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Update BOW to support multiple physical link. -+ * -+ * 12 08 2010 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Support concurrent networks. -+ * -+ * 12 07 2010 cm.chang -+ * [WCXRP00000239] MT6620 Wi-Fi][Driver][FW] Merge concurrent branch back to maintrunk -+ * 1. BSSINFO include RLM parameter -+ * 2. free all sta records when network is disconnected -+ * -+ * 11 11 2010 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Fix BoW timer assert issue. -+ * -+ * 10 18 2010 chinghwa.yu -+ * [WCXRP00000110] [MT6620 Wi-Fi] [Driver] Fix BoW Connected event size -+ * Fix for event returnning Band. -+ * -+ * 10 18 2010 chinghwa.yu -+ * [WCXRP00000110] [MT6620 Wi-Fi] [Driver] Fix BoW Connected event size -+ * Fix wrong BoW event size. -+ * -+ * 10 04 2010 cp.wu -+ * [WCXRP00000077] [MT6620 Wi-Fi][Driver][FW] Eliminate use of ENUM_NETWORK_TYPE_T and replaced -+ * by ENUM_NETWORK_TYPE_INDEX_T only remove ENUM_NETWORK_TYPE_T definitions -+ * -+ * 09 27 2010 chinghwa.yu -+ * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000065] Update BoW design and settings -+ * Update BCM/BoW design and settings. -+ * -+ * 09 16 2010 chinghwa.yu -+ * NULL -+ * Fix bowResponderScanDone error when prBssDesc is NULL. -+ * -+ * 09 14 2010 chinghwa.yu -+ * NULL -+ * Add bowRunEventAAAComplete. -+ * -+ * 09 14 2010 cp.wu -+ * NULL -+ * indicate correct AIS network information for PAL. -+ * -+ * 09 03 2010 kevin.huang -+ * NULL -+ * Refine #include sequence and solve recursive/nested #include issue -+ * -+ * 08 24 2010 cm.chang -+ * NULL -+ * Support RLM initail channel of Ad-hoc, P2P and BOW -+ * -+ * 08 24 2010 chinghwa.yu -+ * NULL -+ * Initialize nicActivateNetwork(prAdapter as soon as bow is starting.. -+ * -+ * 08 24 2010 chinghwa.yu -+ * NULL -+ * Update BOW for the 1st time. -+ * -+ * 08 23 2010 cp.wu -+ * NULL -+ * revise constant definitions to be matched with implementation (original cmd-event definition is deprecated) -+ * -+ * 07 30 2010 cp.wu -+ * NULL -+ * 1) BoW wrapper: use definitions instead of hard-coded constant for error code -+ * 2) AIS-FSM: eliminate use of desired RF parameters, use prTargetBssDesc instead -+ * 3) add handling for RX_PKT_DESTINATION_HOST_WITH_FORWARD for GO-broadcast frames -+ * -+ * 07 15 2010 cp.wu -+ * -+ * sync. bluetooth-over-Wi-Fi interface to driver interface document v0.2.6. -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 25 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add API in que_mgt to retrieve sta-rec index for security frames. -+ * -+ * 06 24 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 802.1x and bluetooth-over-Wi-Fi security frames are now delievered to firmware via command path instead of data path. -+ * -+ * 06 11 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) migrate assoc.c. -+ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness -+ * 3) add configuration options for CNM_MEM and RSN modules -+ * 4) add data path for management frames -+ * 5) eliminate rPacketInfo of MSDU_INFO_T -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 05 17 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * 1) add timeout handler mechanism for pending command packets -+ * 2) add p2p add/removal key -+ * -+ * 05 13 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * add NULL OID implementation for WOL-related OIDs. -+ * -+ * 05 13 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * 1) all BT physical handles shares the same RSSI/Link Quality. -+ * 2) simplify BT command composing -+ * -+ * 04 28 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * change prefix for data structure used to communicate with 802.11 PAL -+ * to avoid ambiguous naming with firmware interface -+ * -+ * 04 27 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * add multiple physical link support -+ * -+ * 04 14 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * information buffer for query oid/ioctl is now buffered in prCmdInfo -+ * instead of glue-layer variable to improve multiple oid/ioctl capability -+ * -+ * 04 13 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * add framework for BT-over-Wi-Fi support. -+ * * 1) prPendingCmdInfo is replaced by queue for multiple handler capability -+ * * 2) command sequence number is now increased atomically -+ * * 3) private data could be hold and taken use for other purpose -+** -+*/ -+ -+/****************************************************************************** -+* C O M P I L E R F L A G S -+******************************************************************************* -+*/ -+ -+/****************************************************************************** -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************* -+*/ -+#include "precomp.h" -+ -+#if CFG_ENABLE_BT_OVER_WIFI -+ -+/****************************************************************************** -+* C O N S T A N T S -+******************************************************************************* -+*/ -+ -+/****************************************************************************** -+* D A T A T Y P E S -+******************************************************************************* -+*/ -+ -+/****************************************************************************** -+* P U B L I C D A T A -+******************************************************************************* -+*/ -+ -+static UINT_32 g_u4LinkCount; -+static UINT_32 g_u4Beaconing; -+static BOW_TABLE_T arBowTable[CFG_BOW_PHYSICAL_LINK_NUM]; -+ -+/****************************************************************************** -+* P R I V A T E D A T A -+******************************************************************************* -+*/ -+ -+const BOW_CMD_T arBowCmdTable[] = { -+ {BOW_CMD_ID_GET_MAC_STATUS, bowCmdGetMacStatus}, -+ {BOW_CMD_ID_SETUP_CONNECTION, bowCmdSetupConnection}, -+ {BOW_CMD_ID_DESTROY_CONNECTION, bowCmdDestroyConnection}, -+ {BOW_CMD_ID_SET_PTK, bowCmdSetPTK}, -+ {BOW_CMD_ID_READ_RSSI, bowCmdReadRSSI}, -+ {BOW_CMD_ID_READ_LINK_QUALITY, bowCmdReadLinkQuality}, -+ {BOW_CMD_ID_SHORT_RANGE_MODE, bowCmdShortRangeMode}, -+ {BOW_CMD_ID_GET_CHANNEL_LIST, bowCmdGetChannelList}, -+}; -+ -+/****************************************************************************** -+* M A C R O S -+******************************************************************************* -+*/ -+ -+/****************************************************************************** -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************* -+*/ -+ -+/****************************************************************************** -+* F U N C T I O N S -+******************************************************************************* -+*/ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief command packet generation utility -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] ucCID Command ID -+* \param[in] fgSetQuery Set or Query -+* \param[in] fgNeedResp Need for response -+* \param[in] pfCmdDoneHandler Function pointer when command is done -+* \param[in] u4SetQueryInfoLen The length of the set/query buffer -+* \param[in] pucInfoBuffer Pointer to set/query buffer -+* -+* -+* \retval WLAN_STATUS_PENDING -+* \retval WLAN_STATUS_FAILURE -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSendSetQueryBowCmd(IN P_ADAPTER_T prAdapter, -+ IN UINT_8 ucCID, -+ IN BOOLEAN fgSetQuery, -+ IN BOOLEAN fgNeedResp, -+ IN PFN_CMD_DONE_HANDLER pfCmdDoneHandler, -+ IN PFN_CMD_TIMEOUT_HANDLER pfCmdTimeoutHandler, -+ IN UINT_32 u4SetQueryInfoLen, IN PUINT_8 pucInfoBuffer, IN UINT_8 ucSeqNumber) -+{ -+ P_GLUE_INFO_T prGlueInfo; -+ P_CMD_INFO_T prCmdInfo; -+ P_WIFI_CMD_T prWifiCmd; -+ UINT_8 ucCmdSeqNum; -+ -+ ASSERT(prAdapter); -+ -+ prGlueInfo = prAdapter->prGlueInfo; -+ ASSERT(prGlueInfo); -+ -+ DBGLOG(REQ, TRACE, "Command ID = 0x%08X\n", ucCID); -+ -+ prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, (CMD_HDR_SIZE + u4SetQueryInfoLen)); -+ -+ if (!prCmdInfo) { -+ DBGLOG(INIT, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); -+ return WLAN_STATUS_FAILURE; -+ } -+ /* increase command sequence number */ -+ ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter); -+ DBGLOG(REQ, TRACE, "ucCmdSeqNum =%d\n", ucCmdSeqNum); -+ -+ /* Setup common CMD Info Packet */ -+ prCmdInfo->eCmdType = COMMAND_TYPE_NETWORK_IOCTL; -+ prCmdInfo->eNetworkType = NETWORK_TYPE_BOW_INDEX; -+ prCmdInfo->u2InfoBufLen = (UINT_16) (CMD_HDR_SIZE + u4SetQueryInfoLen); -+ prCmdInfo->pfCmdDoneHandler = pfCmdDoneHandler; -+ prCmdInfo->pfCmdTimeoutHandler = pfCmdTimeoutHandler; -+ prCmdInfo->fgIsOid = FALSE; -+ prCmdInfo->ucCID = ucCID; -+ prCmdInfo->fgSetQuery = fgSetQuery; -+ prCmdInfo->fgNeedResp = fgNeedResp; -+ prCmdInfo->fgDriverDomainMCR = FALSE; -+ prCmdInfo->ucCmdSeqNum = ucCmdSeqNum; -+ prCmdInfo->u4SetInfoLen = u4SetQueryInfoLen; -+ prCmdInfo->pvInformationBuffer = NULL; -+ prCmdInfo->u4InformationBufferLength = 0; -+ prCmdInfo->u4PrivateData = (UINT_32) ucSeqNumber; -+ -+ /* Setup WIFI_CMD_T (no payload) */ -+ prWifiCmd = (P_WIFI_CMD_T) (prCmdInfo->pucInfoBuffer); -+ prWifiCmd->u2TxByteCount_UserPriority = prCmdInfo->u2InfoBufLen; -+ prWifiCmd->ucCID = prCmdInfo->ucCID; -+ prWifiCmd->ucSetQuery = prCmdInfo->fgSetQuery; -+ prWifiCmd->ucSeqNum = prCmdInfo->ucCmdSeqNum; -+ -+ if (u4SetQueryInfoLen > 0 && pucInfoBuffer != NULL) -+ kalMemCopy(prWifiCmd->aucBuffer, pucInfoBuffer, u4SetQueryInfoLen); -+ /* insert into prCmdQueue */ -+ kalEnqueueCommand(prGlueInfo, (P_QUE_ENTRY_T) prCmdInfo); -+ -+ /* wakeup txServiceThread later */ -+ GLUE_SET_EVENT(prGlueInfo); -+ return WLAN_STATUS_PENDING; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to dispatch command coming from 802.11 PAL -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] prCmd Pointer to the buffer that holds the command -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS wlanbowHandleCommand(IN P_ADAPTER_T prAdapter, IN P_AMPC_COMMAND prCmd) -+{ -+ WLAN_STATUS retval = WLAN_STATUS_FAILURE; -+ UINT_16 i; -+ -+ ASSERT(prAdapter); -+ -+ for (i = 0; i < sizeof(arBowCmdTable) / sizeof(BOW_CMD_T); i++) { -+ if ((arBowCmdTable[i].uCmdID == prCmd->rHeader.ucCommandId) && arBowCmdTable[i].pfCmdHandle) { -+ retval = arBowCmdTable[i].pfCmdHandle(prAdapter, prCmd); -+ break; -+ } -+ } -+ -+ return retval; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This is command handler for BOW_CMD_ID_GET_MAC_STATUS -+* coming from 802.11 PAL -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] prCmd Pointer to the buffer that holds the command -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS bowCmdGetMacStatus(IN P_ADAPTER_T prAdapter, IN P_AMPC_COMMAND prCmd) -+{ -+ P_AMPC_EVENT prEvent; -+ P_BOW_MAC_STATUS prMacStatus; -+ UINT_8 idx = 0; -+ UINT_8 ucPrimaryChannel; -+ ENUM_BAND_T eBand; -+ ENUM_CHNL_EXT_T eBssSCO; -+ UINT_8 ucNumOfChannel = 0; /* MAX_BOW_NUMBER_OF_CHANNEL; */ -+ -+ RF_CHANNEL_INFO_T aucChannelList[MAX_BOW_NUMBER_OF_CHANNEL]; -+ -+ ASSERT(prAdapter); -+ -+ /* 3 <1> If LinkCount != 0 -> OK (optional) */ -+ -+ eBand = BAND_2G4; -+ eBssSCO = CHNL_EXT_SCN; -+ -+ /* fill event header */ -+ prEvent = (P_AMPC_EVENT) kalMemAlloc((sizeof(AMPC_EVENT) + sizeof(BOW_MAC_STATUS)), VIR_MEM_TYPE); -+ if (!prEvent) { -+ ASSERT(FALSE); -+ return WLAN_STATUS_FAILURE; -+ } -+ prEvent->rHeader.ucEventId = BOW_EVENT_ID_MAC_STATUS; -+ prEvent->rHeader.ucSeqNumber = prCmd->rHeader.ucSeqNumber; -+ prEvent->rHeader.u2PayloadLength = sizeof(BOW_MAC_STATUS); -+ -+ /* fill event body */ -+ prMacStatus = (P_BOW_MAC_STATUS) (prEvent->aucPayload); -+ kalMemZero(prMacStatus, sizeof(BOW_MAC_STATUS)); -+ -+ /* 3 <2> Call CNM to decide if BOW available. */ -+ if (cnmBowIsPermitted(prAdapter)) -+ prMacStatus->ucAvailability = TRUE; -+ else -+ prMacStatus->ucAvailability = FALSE; -+ -+ memcpy(prMacStatus->aucMacAddr, prAdapter->rWifiVar.aucDeviceAddress, PARAM_MAC_ADDR_LEN); -+ -+ if (cnmPreferredChannel(prAdapter, &eBand, &ucPrimaryChannel, &eBssSCO)) { -+#if CFG_BOW_TEST -+ DBGLOG(BOW, TRACE, "bowCmdGetMacStatus, Get preferred channel.\n"); -+#endif -+ -+ prMacStatus->ucNumOfChannel = 1; -+ prMacStatus->arChannelList[0].ucChannelBand = eBand; -+ prMacStatus->arChannelList[0].ucChannelNum = ucPrimaryChannel; -+ } else { -+#if CFG_BOW_TEST -+ DBGLOG(BOW, TRACE, -+ "bowCmdGetMacStatus, Get channel list. Current number of channel, %d.\n", ucNumOfChannel); -+#endif -+ -+ rlmDomainGetChnlList(prAdapter, BAND_2G4, FALSE, MAX_BOW_NUMBER_OF_CHANNEL_2G4, -+ &ucNumOfChannel, aucChannelList); -+ -+ if (ucNumOfChannel > 0) { -+ for (idx = 0; idx < ucNumOfChannel; idx++) { -+ prMacStatus->arChannelList[idx].ucChannelBand = aucChannelList[idx].eBand; -+ prMacStatus->arChannelList[idx].ucChannelNum = aucChannelList[idx].ucChannelNum; -+ } -+ -+ prMacStatus->ucNumOfChannel = ucNumOfChannel; -+ } -+ -+ rlmDomainGetChnlList(prAdapter, BAND_5G, FALSE, MAX_BOW_NUMBER_OF_CHANNEL_5G, -+ &ucNumOfChannel, aucChannelList); -+ -+ if (ucNumOfChannel > 0) { -+ for (idx = 0; idx < ucNumOfChannel; idx++) { -+ prMacStatus->arChannelList[prMacStatus->ucNumOfChannel + idx].ucChannelBand = -+ aucChannelList[idx].eBand; -+ prMacStatus->arChannelList[prMacStatus->ucNumOfChannel + idx].ucChannelNum = -+ aucChannelList[idx].ucChannelNum; -+ } -+ -+ prMacStatus->ucNumOfChannel = prMacStatus->ucNumOfChannel + ucNumOfChannel; -+ -+ } -+ } -+ -+#if CFG_BOW_TEST -+ DBGLOG(BOW, TRACE, -+ "ucNumOfChannel,eBand,aucChannelList,%x,%x,%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x.\n", -+ ucNumOfChannel, aucChannelList[0].eBand, aucChannelList[0].ucChannelNum, aucChannelList[1].ucChannelNum, -+ aucChannelList[2].ucChannelNum, aucChannelList[3].ucChannelNum, aucChannelList[4].ucChannelNum, -+ aucChannelList[5].ucChannelNum, aucChannelList[6].ucChannelNum, aucChannelList[7].ucChannelNum, -+ aucChannelList[8].ucChannelNum, aucChannelList[9].ucChannelNum, aucChannelList[10].ucChannelNum, -+ aucChannelList[11].ucChannelNum, aucChannelList[12].ucChannelNum, aucChannelList[13].ucChannelNum, -+ aucChannelList[14].ucChannelNum, aucChannelList[15].ucChannelNum, aucChannelList[16].ucChannelNum, -+ aucChannelList[17].ucChannelNum)); -+ -+ DBGLOG(BOW, TRACE, -+ "prMacStatus->ucNumOfChannel, eBand, %x, %x.\n", -+ prMacStatus->ucNumOfChannel, prMacStatus->arChannelList[0].ucChannelBand); -+ DBGLOG(BOW, TRACE, -+ "prMacStatus->arChannelList, %x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x.\n", -+ prMacStatus->arChannelList[0].ucChannelNum, prMacStatus->arChannelList[1].ucChannelNum, -+ prMacStatus->arChannelList[2].ucChannelNum, prMacStatus->arChannelList[3].ucChannelNum, -+ prMacStatus->arChannelList[4].ucChannelNum, prMacStatus->arChannelList[5].ucChannelNum, -+ prMacStatus->arChannelList[6].ucChannelNum, prMacStatus->arChannelList[7].ucChannelNum, -+ prMacStatus->arChannelList[8].ucChannelNum, prMacStatus->arChannelList[9].ucChannelNum, -+ prMacStatus->arChannelList[10].ucChannelNum, prMacStatus->arChannelList[11].ucChannelNum, -+ prMacStatus->arChannelList[12].ucChannelNum, prMacStatus->arChannelList[13].ucChannelNum, -+ prMacStatus->arChannelList[14].ucChannelNum, prMacStatus->arChannelList[15].ucChannelNum, -+ prMacStatus->arChannelList[16].ucChannelNum, prMacStatus->arChannelList[17].ucChannelNum)); -+ -+ DBGLOG(BOW, TRACE, "prMacStatus->ucNumOfChannel, %x.\n", prMacStatus->ucNumOfChannel); -+ DBGLOG(BOW, TRACE, -+ "prMacStatus->arChannelList[0].ucChannelBand, %x.\n", prMacStatus->arChannelList[0].ucChannelBand); -+ DBGLOG(BOW, TRACE, -+ "prMacStatus->arChannelList[0].ucChannelNum, %x.\n", prMacStatus->arChannelList[0].ucChannelNum); -+ DBGLOG(BOW, TRACE, "prMacStatus->ucAvailability, %x.\n", prMacStatus->ucAvailability); -+ DBGLOG(BOW, TRACE, "prMacStatus->aucMacAddr, %x:%x:%x:%x:%x:%x.\n", -+ prMacStatus->aucMacAddr[0], -+ prMacStatus->aucMacAddr[1], -+ prMacStatus->aucMacAddr[2], -+ prMacStatus->aucMacAddr[3], prMacStatus->aucMacAddr[4], prMacStatus->aucMacAddr[5])); -+#endif -+ -+ kalIndicateBOWEvent(prAdapter->prGlueInfo, prEvent); -+ -+ kalMemFree(prEvent, VIR_MEM_TYPE, (sizeof(AMPC_EVENT) + sizeof(BOW_MAC_STATUS))); -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This is command handler for BOW_CMD_ID_SETUP_CONNECTION -+* coming from 802.11 PAL -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] prCmd Pointer to the buffer that holds the command -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS bowCmdSetupConnection(IN P_ADAPTER_T prAdapter, IN P_AMPC_COMMAND prCmd) -+{ -+ P_BOW_SETUP_CONNECTION prBowSetupConnection; -+ CMD_BT_OVER_WIFI rCmdBtOverWifi; -+ P_BOW_FSM_INFO_T prBowFsmInfo; -+ BOW_TABLE_T rBowTable; -+ -+ UINT_8 ucBowTableIdx = 0; -+ -+ ASSERT(prAdapter); -+ -+ prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); -+ prBowSetupConnection = (P_BOW_SETUP_CONNECTION) &(prCmd->aucPayload[0]); -+ -+ /* parameter size check */ -+ if (prCmd->rHeader.u2PayloadLength != sizeof(BOW_SETUP_CONNECTION)) { -+ wlanbowCmdEventSetStatus(prAdapter, prCmd, BOWCMD_STATUS_INVALID); -+ return WLAN_STATUS_INVALID_LENGTH; -+ } -+ /* 3 <1> If ucLinkCount >= 4 -> Fail. */ -+ if (g_u4LinkCount >= CFG_BOW_PHYSICAL_LINK_NUM) { -+ wlanbowCmdEventSetStatus(prAdapter, prCmd, BOWCMD_STATUS_UNACCEPTED); -+ return WLAN_STATUS_NOT_ACCEPTED; -+ } -+ /* 3 <2> Call CNM, check if BOW is available. */ -+ if (!cnmBowIsPermitted(prAdapter)) { -+ wlanbowCmdEventSetStatus(prAdapter, prCmd, BOWCMD_STATUS_UNACCEPTED); -+ return WLAN_STATUS_NOT_ACCEPTED; -+ } -+ /* 3 <3> Lookup BOW Table, if Peer MAC address exist and valid -> Fail. */ -+ if (bowCheckBowTableIfVaild(prAdapter, prBowSetupConnection->aucPeerAddress)) { -+ wlanbowCmdEventSetStatus(prAdapter, prCmd, BOWCMD_STATUS_UNACCEPTED); -+ return WLAN_STATUS_NOT_ACCEPTED; -+ } -+ -+ if (EQUAL_MAC_ADDR(prBowSetupConnection->aucPeerAddress, prAdapter->rWifiVar.aucDeviceAddress)) { -+ wlanbowCmdEventSetStatus(prAdapter, prCmd, BOWCMD_STATUS_INVALID); -+ return WLAN_STATUS_NOT_ACCEPTED; -+ } -+ /* fill CMD_BT_OVER_WIFI */ -+ rCmdBtOverWifi.ucAction = BOW_SETUP_CMD; -+ rCmdBtOverWifi.ucChannelNum = prBowSetupConnection->ucChannelNum; -+ COPY_MAC_ADDR(rCmdBtOverWifi.rPeerAddr, prBowSetupConnection->aucPeerAddress); -+ rCmdBtOverWifi.u2BeaconInterval = prBowSetupConnection->u2BeaconInterval; -+ rCmdBtOverWifi.ucTimeoutDiscovery = prBowSetupConnection->ucTimeoutDiscovery; -+ rCmdBtOverWifi.ucTimeoutInactivity = prBowSetupConnection->ucTimeoutInactivity; -+ rCmdBtOverWifi.ucRole = prBowSetupConnection->ucRole; -+ rCmdBtOverWifi.PAL_Capabilities = prBowSetupConnection->ucPAL_Capabilities; -+ rCmdBtOverWifi.cMaxTxPower = prBowSetupConnection->cMaxTxPower; -+ -+ if (prBowSetupConnection->ucChannelNum > 14) -+ rCmdBtOverWifi.ucChannelBand = BAND_5G; -+ else -+ rCmdBtOverWifi.ucChannelBand = BAND_2G4; -+ -+ COPY_MAC_ADDR(prBowFsmInfo->aucPeerAddress, prBowSetupConnection->aucPeerAddress); -+ -+#if CFG_BOW_PHYSICAL_LINK_NUM > 1 -+ /*Channel check for supporting multiple physical link */ -+ if (g_u4LinkCount > 0) { -+ if (prBowSetupConnection->ucChannelNum != prBowFsmInfo->ucPrimaryChannel) { -+ wlanbowCmdEventSetStatus(prAdapter, prCmd, BOWCMD_STATUS_UNACCEPTED); -+ return WLAN_STATUS_NOT_ACCEPTED; -+ } -+ } -+#endif -+ -+ prBowFsmInfo->ucPrimaryChannel = prBowSetupConnection->ucChannelNum; -+ prBowFsmInfo->eBand = rCmdBtOverWifi.ucChannelBand; -+ prBowFsmInfo->u2BeaconInterval = prBowSetupConnection->u2BeaconInterval; -+ prBowFsmInfo->ucRole = prBowSetupConnection->ucRole; -+ -+ if (prBowSetupConnection->ucPAL_Capabilities > 0) -+ prBowFsmInfo->fgSupportQoS = TRUE; -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "bowCmdSetupConnection.\n"); -+ DBGLOG(BOW, EVENT, "rCmdBtOverWifi Channel Number - 0x%x.\n", rCmdBtOverWifi.ucChannelNum); -+ DBGLOG(BOW, EVENT, "rCmdBtOverWifi Peer address - %x:%x:%x:%x:%x:%x.\n", rCmdBtOverWifi.rPeerAddr[0], -+ rCmdBtOverWifi.rPeerAddr[1], -+ rCmdBtOverWifi.rPeerAddr[2], -+ rCmdBtOverWifi.rPeerAddr[3], rCmdBtOverWifi.rPeerAddr[4], rCmdBtOverWifi.rPeerAddr[5]); -+ DBGLOG(BOW, EVENT, "rCmdBtOverWifi Beacon interval - 0x%x.\n", rCmdBtOverWifi.u2BeaconInterval); -+ DBGLOG(BOW, EVENT, "rCmdBtOverWifi Timeout activity - 0x%x.\n", rCmdBtOverWifi.ucTimeoutDiscovery); -+ DBGLOG(BOW, EVENT, "rCmdBtOverWifi Timeout inactivity - 0x%x.\n", rCmdBtOverWifi.ucTimeoutInactivity); -+ DBGLOG(BOW, EVENT, "rCmdBtOverWifi Role - 0x%x.\n", rCmdBtOverWifi.ucRole); -+ DBGLOG(BOW, EVENT, "rCmdBtOverWifi PAL capability - 0x%x.\n", rCmdBtOverWifi.PAL_Capabilities); -+ DBGLOG(BOW, EVENT, "rCmdBtOverWifi Max Tx power - 0x%x.\n", rCmdBtOverWifi.cMaxTxPower); -+#endif -+ -+ /* 3 <4> Get a free BOW entry, mark as Valid, fill in Peer MAC address, LinkCount += 1, state == Starting. */ -+ if (!bowGetBowTableFreeEntry(prAdapter, &ucBowTableIdx)) { -+ wlanbowCmdEventSetStatus(prAdapter, prCmd, BOWCMD_STATUS_UNACCEPTED); -+ return WLAN_STATUS_NOT_ACCEPTED; -+ } -+ -+ prBowFsmInfo->prTargetBssDesc = NULL; -+ -+ kalMemZero(&rBowTable, sizeof(BOW_TABLE_T)); -+ -+ COPY_MAC_ADDR(rBowTable.aucPeerAddress, prBowSetupConnection->aucPeerAddress); -+ /* owTable.eState = BOW_DEVICE_STATE_ACQUIRING_CHANNEL; */ -+ rBowTable.fgIsValid = TRUE; -+ rBowTable.ucAcquireID = prBowFsmInfo->ucSeqNumOfChReq; -+ /* rBowTable.ucRole = prBowSetupConnection->ucRole; */ -+ /* rBowTable.ucChannelNum = prBowSetupConnection->ucChannelNum; */ -+ bowSetBowTableContent(prAdapter, ucBowTableIdx, &rBowTable); -+ -+ kalSetBowRole(prAdapter->prGlueInfo, rCmdBtOverWifi.ucRole, prBowSetupConnection->aucPeerAddress); -+ -+ GLUE_INC_REF_CNT(g_u4LinkCount); -+ -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "bowStarting, g_u4LinkCount, %x.\n", g_u4LinkCount); -+#endif -+ -+ if (g_u4LinkCount == 1) { -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "bowStarting, cnmTimerInitTimer.\n"); -+ DBGLOG(BOW, EVENT, "prBowFsmInfo->u2BeaconInterval, %d.\n", prBowFsmInfo->u2BeaconInterval); -+#endif -+ cnmTimerInitTimer(prAdapter, -+ &prBowFsmInfo->rStartingBeaconTimer, -+ (PFN_MGMT_TIMEOUT_FUNC) bowSendBeacon, (ULONG) NULL); -+ -+ cnmTimerInitTimer(prAdapter, -+ &prBowFsmInfo->rChGrantedTimer, -+ (PFN_MGMT_TIMEOUT_FUNC) bowChGrantedTimeout, (ULONG) NULL); -+ -+ /* Reset Global Variable */ -+ g_u4Beaconing = 0; -+ -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "bowCmdSetupConnection, g_u4LinkCount, %x.\n", g_u4LinkCount); -+ DBGLOG(BOW, EVENT, "kalInitBowDevice, bow0\n"); -+#endif -+#if CFG_BOW_SEPARATE_DATA_PATH -+ kalInitBowDevice(prAdapter->prGlueInfo, BOWDEVNAME); -+#endif -+ -+ /*Active BoW Network */ -+ SET_NET_ACTIVE(prAdapter, NETWORK_TYPE_BOW_INDEX); -+ SET_NET_PWR_STATE_ACTIVE(prAdapter, NETWORK_TYPE_BOW_INDEX); -+ nicActivateNetwork(prAdapter, NETWORK_TYPE_BOW_INDEX); -+ -+ } -+ -+ if (rCmdBtOverWifi.ucRole == BOW_INITIATOR) { -+ bowSetBowTableState(prAdapter, prBowSetupConnection->aucPeerAddress, -+ BOW_DEVICE_STATE_ACQUIRING_CHANNEL); -+ bowRequestCh(prAdapter); -+ } else { -+ bowSetBowTableState(prAdapter, prBowSetupConnection->aucPeerAddress, BOW_DEVICE_STATE_SCANNING); -+ bowResponderScan(prAdapter); -+ } -+ -+ wlanbowCmdEventSetStatus(prAdapter, prCmd, BOWCMD_STATUS_SUCCESS); -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This is command handler for BOW_CMD_ID_DESTROY_CONNECTION -+* coming from 802.11 PAL -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] prCmd Pointer to the buffer that holds the command -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS bowCmdDestroyConnection(IN P_ADAPTER_T prAdapter, IN P_AMPC_COMMAND prCmd) -+{ -+ P_BOW_DESTROY_CONNECTION prBowDestroyConnection; -+ CMD_BT_OVER_WIFI rCmdBtOverWifi; -+ P_BOW_FSM_INFO_T prBowFsmInfo; -+#if CFG_BOW_TEST -+ UINT_8 ucIdx; -+#endif -+ -+ ASSERT(prAdapter); -+ -+ prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); -+ -+ /* 3 <1> If LinkCount == 0 ->Fail (Optional) */ -+ if (g_u4LinkCount == 0) { -+ wlanbowCmdEventSetStatus(prAdapter, prCmd, BOWCMD_STATUS_UNACCEPTED); -+ return WLAN_STATUS_NOT_ACCEPTED; -+ } -+ /* parameter size check */ -+ if (prCmd->rHeader.u2PayloadLength != sizeof(BOW_DESTROY_CONNECTION)) { -+ wlanbowCmdEventSetStatus(prAdapter, prCmd, BOWCMD_STATUS_UNACCEPTED); -+ return WLAN_STATUS_INVALID_LENGTH; -+ } -+ /* 3 <2> Lookup BOW table, check if is not exist (Valid and Peer MAC address) -> Fail */ -+ prBowDestroyConnection = (P_BOW_DESTROY_CONNECTION) &(prCmd->aucPayload[0]); -+ -+ if (!bowCheckBowTableIfVaild(prAdapter, prBowDestroyConnection->aucPeerAddress)) { -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "bowCmdDestroyConnection, bowCheckIfVaild, not accepted.\n"); -+#endif -+ return WLAN_STATUS_NOT_ACCEPTED; -+ } -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, -+ "bowCmdDestroyConnection, destroy Peer address - %x:%x:%x:%x:%x:%x.\n", -+ prBowDestroyConnection->aucPeerAddress[0], prBowDestroyConnection->aucPeerAddress[1], -+ prBowDestroyConnection->aucPeerAddress[2], prBowDestroyConnection->aucPeerAddress[3], -+ prBowDestroyConnection->aucPeerAddress[4], prBowDestroyConnection->aucPeerAddress[5])); -+#endif -+ -+ /* fill CMD_BT_OVER_WIFI */ -+ rCmdBtOverWifi.ucAction = 2; -+ COPY_MAC_ADDR(rCmdBtOverWifi.rPeerAddr, prBowDestroyConnection->aucPeerAddress); -+ COPY_MAC_ADDR(prBowFsmInfo->aucPeerAddress, prBowDestroyConnection->aucPeerAddress); -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, -+ "bowCmdDestroyConnection, rCmdBtOverWifi.rPeerAddr - %x:%x:%x:%x:%x:%x.\n", rCmdBtOverWifi.rPeerAddr[0], -+ rCmdBtOverWifi.rPeerAddr[1], rCmdBtOverWifi.rPeerAddr[2], rCmdBtOverWifi.rPeerAddr[3], -+ rCmdBtOverWifi.rPeerAddr[4], rCmdBtOverWifi.rPeerAddr[5]); -+#endif -+ -+#if CFG_BOW_TEST -+ for (ucIdx = 0; ucIdx < 11; ucIdx++) { -+ DBGLOG(BOW, EVENT, -+ "BoW receiving PAL packet delta time vs packet number -- %d ms vs %x.\n", ucIdx, -+ g_arBowRevPalPacketTime[ucIdx]); -+ } -+#endif -+ -+ wlanbowCmdEventSetStatus(prAdapter, prCmd, BOWCMD_STATUS_SUCCESS); -+ -+ return wlanoidSendSetQueryBowCmd(prAdapter, -+ CMD_ID_CMD_BT_OVER_WIFI, -+ TRUE, -+ FALSE, -+ wlanbowCmdEventLinkDisconnected, -+ wlanbowCmdTimeoutHandler, -+ sizeof(CMD_BT_OVER_WIFI), -+ (PUINT_8)&rCmdBtOverWifi, prCmd->rHeader.ucSeqNumber); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This is command handler for BOW_CMD_ID_SET_PTK -+* coming from 802.11 PAL -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] prCmd Pointer to the buffer that holds the command -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS bowCmdSetPTK(IN P_ADAPTER_T prAdapter, IN P_AMPC_COMMAND prCmd) -+{ -+ P_BOW_SET_PTK prBowSetPTK; -+ CMD_802_11_KEY rCmdKey; -+ -+ ASSERT(prAdapter); -+ -+ /* parameter size check */ -+ if (prCmd->rHeader.u2PayloadLength != sizeof(BOW_SET_PTK)) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ prBowSetPTK = (P_BOW_SET_PTK) &(prCmd->aucPayload[0]); -+ -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "prBowSetPTK->aucPeerAddress, %x:%x:%x:%x:%x:%x.\n", -+ prBowSetPTK->aucPeerAddress[0], -+ prBowSetPTK->aucPeerAddress[1], -+ prBowSetPTK->aucPeerAddress[2], -+ prBowSetPTK->aucPeerAddress[3], -+ prBowSetPTK->aucPeerAddress[4], prBowSetPTK->aucPeerAddress[5])); -+ -+ DBGLOG(BOW, EVENT, -+ "rCmdKey.ucIsAuthenticator, %x.\n", kalGetBowRole(prAdapter->prGlueInfo, prBowSetPTK->aucPeerAddress)); -+#endif -+ -+ if (!bowCheckBowTableIfVaild(prAdapter, prBowSetPTK->aucPeerAddress)) { -+ wlanbowCmdEventSetStatus(prAdapter, prCmd, BOWCMD_STATUS_UNACCEPTED); -+ -+ return WLAN_STATUS_NOT_ACCEPTED; -+ } -+ -+ if (bowGetBowTableState(prAdapter, prBowSetPTK->aucPeerAddress) != BOW_DEVICE_STATE_CONNECTED) { -+ wlanbowCmdEventSetStatus(prAdapter, prCmd, BOWCMD_STATUS_FAILURE); -+ -+ return WLAN_STATUS_NOT_ACCEPTED; -+ } -+ /* fill CMD_802_11_KEY */ -+ rCmdKey.ucAddRemove = 1; /* add */ -+ rCmdKey.ucTxKey = 1; -+ rCmdKey.ucKeyType = 1; -+ rCmdKey.ucIsAuthenticator = kalGetBowRole(prAdapter->prGlueInfo, prBowSetPTK->aucPeerAddress); -+ COPY_MAC_ADDR(rCmdKey.aucPeerAddr, prBowSetPTK->aucPeerAddress); -+ rCmdKey.ucNetType = NETWORK_TYPE_BOW_INDEX; /* BT Over Wi-Fi */ -+ rCmdKey.ucAlgorithmId = CIPHER_SUITE_CCMP; /* AES */ -+ rCmdKey.ucKeyId = 0; -+ rCmdKey.ucKeyLen = 16; /* AES = 128bit */ -+ kalMemCopy(rCmdKey.aucKeyMaterial, prBowSetPTK->aucTemporalKey, 16); -+ -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "prBowSetPTK->aucTemporalKey, %x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x.\n", -+ prBowSetPTK->aucTemporalKey[0], -+ prBowSetPTK->aucTemporalKey[1], -+ prBowSetPTK->aucTemporalKey[2], -+ prBowSetPTK->aucTemporalKey[3], -+ prBowSetPTK->aucTemporalKey[4], -+ prBowSetPTK->aucTemporalKey[5], -+ prBowSetPTK->aucTemporalKey[6], -+ prBowSetPTK->aucTemporalKey[7], -+ prBowSetPTK->aucTemporalKey[8], -+ prBowSetPTK->aucTemporalKey[9], -+ prBowSetPTK->aucTemporalKey[10], -+ prBowSetPTK->aucTemporalKey[11], -+ prBowSetPTK->aucTemporalKey[12], -+ prBowSetPTK->aucTemporalKey[13], -+ prBowSetPTK->aucTemporalKey[14], prBowSetPTK->aucTemporalKey[15])); -+ -+ DBGLOG(BOW, EVENT, "rCmdKey.aucKeyMaterial, %x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x.\n", -+ rCmdKey.aucKeyMaterial[0], -+ rCmdKey.aucKeyMaterial[1], -+ rCmdKey.aucKeyMaterial[2], -+ rCmdKey.aucKeyMaterial[3], -+ rCmdKey.aucKeyMaterial[4], -+ rCmdKey.aucKeyMaterial[5], -+ rCmdKey.aucKeyMaterial[6], -+ rCmdKey.aucKeyMaterial[7], -+ rCmdKey.aucKeyMaterial[8], -+ rCmdKey.aucKeyMaterial[9], -+ rCmdKey.aucKeyMaterial[10], -+ rCmdKey.aucKeyMaterial[11], -+ rCmdKey.aucKeyMaterial[12], -+ rCmdKey.aucKeyMaterial[13], rCmdKey.aucKeyMaterial[14], rCmdKey.aucKeyMaterial[15])); -+#endif -+ -+ return wlanoidSendSetQueryBowCmd(prAdapter, -+ CMD_ID_ADD_REMOVE_KEY, -+ TRUE, -+ FALSE, -+ wlanbowCmdEventSetCommon, -+ wlanbowCmdTimeoutHandler, -+ sizeof(CMD_802_11_KEY), (PUINT_8)&rCmdKey, prCmd->rHeader.ucSeqNumber); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This is command handler for BOW_CMD_ID_READ_RSSI -+* coming from 802.11 PAL -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] prCmd Pointer to the buffer that holds the command -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS bowCmdReadRSSI(IN P_ADAPTER_T prAdapter, IN P_AMPC_COMMAND prCmd) -+{ -+ P_BOW_READ_RSSI prBowReadRSSI; -+ -+ ASSERT(prAdapter); -+ -+ /* parameter size check */ -+ if (prCmd->rHeader.u2PayloadLength != sizeof(BOW_READ_RSSI)) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ prBowReadRSSI = (P_BOW_READ_RSSI) &(prCmd->aucPayload[0]); -+ -+ return wlanoidSendSetQueryBowCmd(prAdapter, -+ CMD_ID_GET_LINK_QUALITY, -+ FALSE, -+ TRUE, -+ wlanbowCmdEventReadRssi, -+ wlanbowCmdTimeoutHandler, 0, NULL, prCmd->rHeader.ucSeqNumber); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This is command handler for BOW_CMD_ID_READ_LINK_QUALITY -+* coming from 802.11 PAL -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] prCmd Pointer to the buffer that holds the command -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS bowCmdReadLinkQuality(IN P_ADAPTER_T prAdapter, IN P_AMPC_COMMAND prCmd) -+{ -+ P_BOW_READ_LINK_QUALITY prBowReadLinkQuality; -+ -+ ASSERT(prAdapter); -+ -+ /* parameter size check */ -+ if (prCmd->rHeader.u2PayloadLength != sizeof(P_BOW_READ_LINK_QUALITY)) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ prBowReadLinkQuality = (P_BOW_READ_LINK_QUALITY) &(prCmd->aucPayload[0]); -+ -+ return wlanoidSendSetQueryBowCmd(prAdapter, -+ CMD_ID_GET_LINK_QUALITY, -+ FALSE, -+ TRUE, -+ wlanbowCmdEventReadLinkQuality, -+ wlanbowCmdTimeoutHandler, 0, NULL, prCmd->rHeader.ucSeqNumber); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This is command handler for BOW_CMD_ID_SHORT_RANGE_MODE -+* coming from 802.11 PAL -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] prCmd Pointer to the buffer that holds the command -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS bowCmdShortRangeMode(IN P_ADAPTER_T prAdapter, IN P_AMPC_COMMAND prCmd) -+{ -+ P_BOW_SHORT_RANGE_MODE prBowShortRangeMode; -+ CMD_TX_PWR_T rTxPwrParam; -+ -+ ASSERT(prAdapter); -+ -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "bowCmdShortRangeMode.\n"); -+#endif -+ -+ prBowShortRangeMode = (P_BOW_SHORT_RANGE_MODE) &(prCmd->aucPayload[0]); -+ -+ /* parameter size check */ -+ if (prCmd->rHeader.u2PayloadLength != sizeof(BOW_SHORT_RANGE_MODE)) { -+ wlanbowCmdEventSetStatus(prAdapter, prCmd, BOWCMD_STATUS_UNACCEPTED); -+ return WLAN_STATUS_INVALID_LENGTH; -+ } -+ -+ if (!bowCheckBowTableIfVaild(prAdapter, prBowShortRangeMode->aucPeerAddress)) { -+ wlanbowCmdEventSetStatus(prAdapter, prCmd, BOWCMD_STATUS_UNACCEPTED); -+ return WLAN_STATUS_NOT_ACCEPTED; -+ } -+ -+ if (bowGetBowTableState(prAdapter, prBowShortRangeMode->aucPeerAddress) != BOW_DEVICE_STATE_CONNECTED) { -+ wlanbowCmdEventSetStatus(prAdapter, prCmd, BOWCMD_STATUS_FAILURE); -+ return WLAN_STATUS_NOT_ACCEPTED; -+ } -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "prBowShortRangeMode->aucPeerAddress, %x:%x:%x:%x:%x:%x.\n", -+ prBowShortRangeMode->aucPeerAddress[0], -+ prBowShortRangeMode->aucPeerAddress[1], -+ prBowShortRangeMode->aucPeerAddress[2], -+ prBowShortRangeMode->aucPeerAddress[3], -+ prBowShortRangeMode->aucPeerAddress[4], prBowShortRangeMode->aucPeerAddress[5])); -+#endif -+ -+ rTxPwrParam.cTxPwr2G4Cck = (prBowShortRangeMode->cTxPower << 1); -+ -+ rTxPwrParam.cTxPwr2G4OFDM_BPSK = (prBowShortRangeMode->cTxPower << 1); -+ rTxPwrParam.cTxPwr2G4OFDM_QPSK = (prBowShortRangeMode->cTxPower << 1); -+ rTxPwrParam.cTxPwr2G4OFDM_16QAM = (prBowShortRangeMode->cTxPower << 1); -+ -+ rTxPwrParam.cTxPwr2G4OFDM_48Mbps = (prBowShortRangeMode->cTxPower << 1); -+ rTxPwrParam.cTxPwr2G4OFDM_54Mbps = (prBowShortRangeMode->cTxPower << 1); -+ -+ rTxPwrParam.cTxPwr2G4HT20_BPSK = (prBowShortRangeMode->cTxPower << 1); -+ rTxPwrParam.cTxPwr2G4HT20_QPSK = (prBowShortRangeMode->cTxPower << 1); -+ rTxPwrParam.cTxPwr2G4HT20_16QAM = (prBowShortRangeMode->cTxPower << 1); -+ rTxPwrParam.cTxPwr2G4HT20_MCS5 = (prBowShortRangeMode->cTxPower << 1); -+ rTxPwrParam.cTxPwr2G4HT20_MCS6 = (prBowShortRangeMode->cTxPower << 1); -+ rTxPwrParam.cTxPwr2G4HT20_MCS7 = (prBowShortRangeMode->cTxPower << 1); -+ -+ rTxPwrParam.cTxPwr2G4HT40_BPSK = (prBowShortRangeMode->cTxPower << 1); -+ rTxPwrParam.cTxPwr2G4HT40_QPSK = (prBowShortRangeMode->cTxPower << 1); -+ rTxPwrParam.cTxPwr2G4HT40_16QAM = (prBowShortRangeMode->cTxPower << 1); -+ rTxPwrParam.cTxPwr2G4HT40_MCS5 = (prBowShortRangeMode->cTxPower << 1); -+ rTxPwrParam.cTxPwr2G4HT40_MCS6 = (prBowShortRangeMode->cTxPower << 1); -+ rTxPwrParam.cTxPwr2G4HT40_MCS7 = (prBowShortRangeMode->cTxPower << 1); -+ -+ rTxPwrParam.cTxPwr5GOFDM_BPSK = (prBowShortRangeMode->cTxPower << 1); -+ rTxPwrParam.cTxPwr5GOFDM_QPSK = (prBowShortRangeMode->cTxPower << 1); -+ rTxPwrParam.cTxPwr5GOFDM_16QAM = (prBowShortRangeMode->cTxPower << 1); -+ rTxPwrParam.cTxPwr5GOFDM_48Mbps = (prBowShortRangeMode->cTxPower << 1); -+ rTxPwrParam.cTxPwr5GOFDM_54Mbps = (prBowShortRangeMode->cTxPower << 1); -+ -+ rTxPwrParam.cTxPwr5GHT20_BPSK = (prBowShortRangeMode->cTxPower << 1); -+ rTxPwrParam.cTxPwr5GHT20_QPSK = (prBowShortRangeMode->cTxPower << 1); -+ rTxPwrParam.cTxPwr5GHT20_16QAM = (prBowShortRangeMode->cTxPower << 1); -+ rTxPwrParam.cTxPwr5GHT20_MCS5 = (prBowShortRangeMode->cTxPower << 1); -+ rTxPwrParam.cTxPwr5GHT20_MCS6 = (prBowShortRangeMode->cTxPower << 1); -+ rTxPwrParam.cTxPwr5GHT20_MCS7 = (prBowShortRangeMode->cTxPower << 1); -+ rTxPwrParam.cTxPwr5GHT40_BPSK = (prBowShortRangeMode->cTxPower << 1); -+ rTxPwrParam.cTxPwr5GHT40_QPSK = (prBowShortRangeMode->cTxPower << 1); -+ rTxPwrParam.cTxPwr5GHT40_16QAM = (prBowShortRangeMode->cTxPower << 1); -+ rTxPwrParam.cTxPwr5GHT40_MCS5 = (prBowShortRangeMode->cTxPower << 1); -+ rTxPwrParam.cTxPwr5GHT40_MCS6 = (prBowShortRangeMode->cTxPower << 1); -+ rTxPwrParam.cTxPwr5GHT40_MCS7 = (prBowShortRangeMode->cTxPower << 1); -+ -+ if (nicUpdateTxPower(prAdapter, &rTxPwrParam) == WLAN_STATUS_SUCCESS) { -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "bowCmdShortRangeMode, %x.\n", WLAN_STATUS_SUCCESS); -+#endif -+ wlanbowCmdEventSetStatus(prAdapter, prCmd, BOWCMD_STATUS_SUCCESS); -+ return WLAN_STATUS_SUCCESS; -+ } -+ wlanbowCmdEventSetStatus(prAdapter, prCmd, BOWCMD_STATUS_FAILURE); -+ return WLAN_STATUS_FAILURE; -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This is command handler for BOW_CMD_ID_GET_CHANNEL_LIST -+* coming from 802.11 PAL -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] prCmd Pointer to the buffer that holds the command -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS bowCmdGetChannelList(IN P_ADAPTER_T prAdapter, IN P_AMPC_COMMAND prCmd) -+{ -+ ASSERT(prAdapter); -+ -+ /* not supported yet */ -+ return WLAN_STATUS_FAILURE; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This is generic command done handler -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] prCmdInfo Pointer to the buffer that holds the command info -+* \param[in] pucEventBuf Pointer to the set buffer OR event buffer -+* -+* \retval none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID wlanbowCmdEventSetStatus(IN P_ADAPTER_T prAdapter, IN P_AMPC_COMMAND prCmd, IN UINT_8 ucEventBuf) -+{ -+ P_AMPC_EVENT prEvent; -+ P_BOW_COMMAND_STATUS prBowCmdStatus; -+ -+ ASSERT(prAdapter); -+ -+ /* fill event header */ -+ prEvent = (P_AMPC_EVENT) kalMemAlloc((sizeof(AMPC_EVENT) + sizeof(BOW_COMMAND_STATUS)), VIR_MEM_TYPE); -+ if (!prEvent) { -+ ASSERT(FALSE); -+ return; -+ } -+ prEvent->rHeader.ucEventId = BOW_EVENT_ID_COMMAND_STATUS; -+ prEvent->rHeader.ucSeqNumber = prCmd->rHeader.ucSeqNumber; -+ prEvent->rHeader.u2PayloadLength = sizeof(BOW_COMMAND_STATUS); -+ -+ /* fill event body */ -+ prBowCmdStatus = (P_BOW_COMMAND_STATUS) (prEvent->aucPayload); -+ kalMemZero(prBowCmdStatus, sizeof(BOW_COMMAND_STATUS)); -+ -+ prBowCmdStatus->ucStatus = ucEventBuf; -+ -+ kalIndicateBOWEvent(prAdapter->prGlueInfo, prEvent); -+ -+ kalMemFree(prEvent, VIR_MEM_TYPE, (sizeof(AMPC_EVENT) + sizeof(BOW_COMMAND_STATUS))); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This is generic command done handler -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] prCmdInfo Pointer to the buffer that holds the command info -+* \param[in] pucEventBuf Pointer to the set buffer OR event buffer -+* -+* \retval none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID wlanbowCmdEventSetCommon(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) -+{ -+ P_AMPC_EVENT prEvent; -+ P_BOW_COMMAND_STATUS prBowCmdStatus; -+ -+ ASSERT(prAdapter); -+ -+ /* fill event header */ -+ prEvent = (P_AMPC_EVENT) kalMemAlloc((sizeof(AMPC_EVENT) + sizeof(BOW_COMMAND_STATUS)), VIR_MEM_TYPE); -+ if (!prEvent) { -+ ASSERT(FALSE); -+ return; -+ } -+ prEvent->rHeader.ucEventId = BOW_EVENT_ID_COMMAND_STATUS; -+ prEvent->rHeader.ucSeqNumber = (UINT_8) prCmdInfo->u4PrivateData; -+ prEvent->rHeader.u2PayloadLength = sizeof(BOW_COMMAND_STATUS); -+ -+ /* fill event body */ -+ prBowCmdStatus = (P_BOW_COMMAND_STATUS) (prEvent->aucPayload); -+ kalMemZero(prBowCmdStatus, sizeof(BOW_COMMAND_STATUS)); -+ -+ prBowCmdStatus->ucStatus = BOWCMD_STATUS_SUCCESS; -+ -+ kalIndicateBOWEvent(prAdapter->prGlueInfo, prEvent); -+ -+ kalMemFree(prEvent, VIR_MEM_TYPE, (sizeof(AMPC_EVENT) + sizeof(BOW_COMMAND_STATUS))); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief command done handler for CMD_ID_CMD_BT_OVER_WIFI -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] prCmdInfo Pointer to the buffer that holds the command info -+* \param[in] pucEventBuf Pointer to the set buffer OR event buffer -+* -+* \retval none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID wlanbowCmdEventLinkConnected(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) -+{ -+ P_AMPC_EVENT prEvent; -+ P_BOW_LINK_CONNECTED prBowLinkConnected; -+ P_BOW_FSM_INFO_T prBowFsmInfo; -+ P_BSS_INFO_T prBssInfo; -+ -+ ASSERT(prAdapter); -+ -+ prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_BOW_INDEX]); -+ -+ /* fill event header */ -+ prEvent = (P_AMPC_EVENT) kalMemAlloc((sizeof(AMPC_EVENT) + sizeof(BOW_LINK_CONNECTED)), VIR_MEM_TYPE); -+ if (!prEvent) { -+ ASSERT(FALSE); -+ return; -+ } -+ prEvent->rHeader.ucEventId = BOW_EVENT_ID_LINK_CONNECTED; -+ prEvent->rHeader.ucSeqNumber = (UINT_8) prCmdInfo->u4PrivateData; -+ prEvent->rHeader.u2PayloadLength = sizeof(BOW_LINK_CONNECTED); -+ -+ /* fill event body */ -+ prBowLinkConnected = (P_BOW_LINK_CONNECTED) (prEvent->aucPayload); -+ kalMemZero(prBowLinkConnected, sizeof(BOW_LINK_CONNECTED)); -+ prBowLinkConnected->rChannel.ucChannelNum = prBssInfo->ucPrimaryChannel; -+ prBowLinkConnected->rChannel.ucChannelBand = prBssInfo->eBand; -+ COPY_MAC_ADDR(prBowLinkConnected->aucPeerAddress, prBowFsmInfo->aucPeerAddress); -+ -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "prEvent->rHeader.ucEventId, 0x%x\n", prEvent->rHeader.ucEventId); -+ DBGLOG(BOW, EVENT, "prEvent->rHeader.ucSeqNumber, 0x%x\n", prEvent->rHeader.ucSeqNumber); -+ DBGLOG(BOW, EVENT, "prEvent->rHeader.u2PayloadLength, 0x%x\n", prEvent->rHeader.u2PayloadLength); -+ DBGLOG(BOW, EVENT, -+ "prBowLinkConnected->rChannel.ucChannelNum, 0x%x\n", prBowLinkConnected->rChannel.ucChannelNum); -+ DBGLOG(BOW, EVENT, -+ "prBowLinkConnected->rChannel.ucChannelBand, 0x%x\n", prBowLinkConnected->rChannel.ucChannelBand); -+ DBGLOG(BOW, EVENT, -+ "wlanbowCmdEventLinkConnected, prBowFsmInfo->aucPeerAddress, %x:%x:%x:%x:%x:%x.\n", -+ prBowFsmInfo->aucPeerAddress[0], prBowFsmInfo->aucPeerAddress[1], prBowFsmInfo->aucPeerAddress[2], -+ prBowFsmInfo->aucPeerAddress[3], prBowFsmInfo->aucPeerAddress[4], prBowFsmInfo->aucPeerAddress[5]); -+ DBGLOG(BOW, EVENT, -+ "wlanbowCmdEventLinkConnected, prBowLinkConnected->aucPeerAddress, %x:%x:%x:%x:%x:%x.\n", -+ prBowLinkConnected->aucPeerAddress[0], prBowLinkConnected->aucPeerAddress[1], -+ prBowLinkConnected->aucPeerAddress[2], prBowLinkConnected->aucPeerAddress[3], -+ prBowLinkConnected->aucPeerAddress[4], prBowLinkConnected->aucPeerAddress[5])); -+ DBGLOG(BOW, EVENT, "wlanbowCmdEventLinkConnected, g_u4LinkCount, %x.\n", g_u4LinkCount); -+#endif -+ -+ /*Indicate Event to PAL */ -+ kalIndicateBOWEvent(prAdapter->prGlueInfo, prEvent); -+ kalMemFree(prEvent, VIR_MEM_TYPE, (sizeof(AMPC_EVENT) + sizeof(BOW_LINK_CONNECTED))); -+ -+ /*Release channel if granted */ -+ if (prBowFsmInfo->fgIsChannelGranted) { -+ cnmTimerStopTimer(prAdapter, &prBowFsmInfo->rChGrantedTimer); -+ /* bowReleaseCh(prAdapter); */ -+ /*Requested, not granted yet */ -+ } else if (prBowFsmInfo->fgIsChannelRequested) { -+ prBowFsmInfo->fgIsChannelRequested = FALSE; -+ } -+ -+ /* set to connected status */ -+ bowSetBowTableState(prAdapter, prBowFsmInfo->aucPeerAddress, BOW_DEVICE_STATE_CONNECTED); -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief command done handler for CMD_ID_CMD_BT_OVER_WIFI -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] prCmdInfo Pointer to the buffer that holds the command info -+* \param[in] pucEventBuf Pointer to the set buffer OR event buffer -+* -+* \retval none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID wlanbowCmdEventLinkDisconnected(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) -+{ -+ P_AMPC_EVENT prEvent; -+ P_BOW_LINK_DISCONNECTED prBowLinkDisconnected; -+ P_BOW_FSM_INFO_T prBowFsmInfo; -+ BOW_TABLE_T rBowTable; -+ UINT_8 ucBowTableIdx; -+ ENUM_BOW_DEVICE_STATE eFsmState; -+ BOOLEAN fgSendDeauth = FALSE; -+ -+ ASSERT(prAdapter); -+ -+ prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); -+ eFsmState = bowGetBowTableState(prAdapter, prBowFsmInfo->aucPeerAddress); -+ -+ if (eFsmState == BOW_DEVICE_STATE_DISCONNECTED) { -+ /*do nothing */ -+ return; -+ } -+ /*Cancel scan */ -+ else if (eFsmState == BOW_DEVICE_STATE_SCANNING && !(prBowFsmInfo->fgIsChannelRequested)) { -+ bowResponderCancelScan(prAdapter, FALSE); -+ bowSetBowTableState(prAdapter, prBowFsmInfo->aucPeerAddress, BOW_DEVICE_STATE_DISCONNECTING); -+ return; -+ } -+ /* fill event header */ -+ prEvent = (P_AMPC_EVENT) kalMemAlloc((sizeof(AMPC_EVENT) + sizeof(BOW_LINK_DISCONNECTED)), VIR_MEM_TYPE); -+ if (!prEvent) { -+ ASSERT(FALSE); -+ return; -+ } -+ prEvent->rHeader.ucEventId = BOW_EVENT_ID_LINK_DISCONNECTED; -+ if ((prCmdInfo->u4PrivateData)) -+ prEvent->rHeader.ucSeqNumber = (UINT_8) prCmdInfo->u4PrivateData; -+ else -+ prEvent->rHeader.ucSeqNumber = 0; -+ -+ prEvent->rHeader.u2PayloadLength = sizeof(BOW_LINK_DISCONNECTED); -+ -+ /* fill event body */ -+ prBowLinkDisconnected = (P_BOW_LINK_DISCONNECTED) (prEvent->aucPayload); -+ kalMemZero(prBowLinkDisconnected, sizeof(BOW_LINK_DISCONNECTED)); -+ prBowLinkDisconnected->ucReason = 0x0; -+ COPY_MAC_ADDR(prBowLinkDisconnected->aucPeerAddress, prBowFsmInfo->aucPeerAddress); -+ -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "prEvent->rHeader.ucEventId, 0x%x\n", prEvent->rHeader.ucEventId); -+ DBGLOG(BOW, EVENT, "prEvent->rHeader.ucSeqNumber, 0x%x\n", prEvent->rHeader.ucSeqNumber); -+ DBGLOG(BOW, EVENT, "prEvent->rHeader.u2PayloadLength, 0x%x\n", prEvent->rHeader.u2PayloadLength); -+ -+ DBGLOG(BOW, EVENT, "wlanbowCmdEventLinkDisconnected, prBowFsmInfo->aucPeerAddress, %x:%x:%x:%x:%x:%x.\n", -+ prBowFsmInfo->aucPeerAddress[0], -+ prBowFsmInfo->aucPeerAddress[1], -+ prBowFsmInfo->aucPeerAddress[2], -+ prBowFsmInfo->aucPeerAddress[3], -+ prBowFsmInfo->aucPeerAddress[4], prBowFsmInfo->aucPeerAddress[5])); -+ -+ DBGLOG(BOW, EVENT, -+ "wlanbowCmdEventLinkDisconnected, prBowLinkDisconnected->aucPeerAddress, %x:%x:%x:%x:%x:%x.\n", -+ prBowLinkDisconnected->aucPeerAddress[0], prBowLinkDisconnected->aucPeerAddress[1], -+ prBowLinkDisconnected->aucPeerAddress[2], prBowLinkDisconnected->aucPeerAddress[3], -+ prBowLinkDisconnected->aucPeerAddress[4], prBowLinkDisconnected->aucPeerAddress[5])); -+ -+ DBGLOG(BOW, EVENT, "wlanbowCmdEventLinkDisconnected, g_u4LinkCount, %x.\n", g_u4LinkCount); -+#endif -+ -+ /*Indicate BoW event to PAL */ -+#if 0 -+ kalIndicateBOWEvent(prAdapter->prGlueInfo, prEvent); -+ kalMemFree(prEvent, VIR_MEM_TYPE, (sizeof(AMPC_EVENT) + sizeof(BOW_LINK_DISCONNECTED))); -+#endif -+ -+ /* set to disconnected status */ -+ prBowFsmInfo->prTargetStaRec = -+ cnmGetStaRecByAddress(prAdapter, NETWORK_TYPE_BOW_INDEX, prBowLinkDisconnected->aucPeerAddress); -+ if (!(prBowFsmInfo->prTargetStaRec)) { -+ kalMemFree(prEvent, VIR_MEM_TYPE, (sizeof(AMPC_EVENT) + sizeof(BOW_LINK_DISCONNECTED))); -+ ASSERT(FALSE); -+ return; -+ } -+ -+ /*Release channel if granted */ -+ if (prBowFsmInfo->fgIsChannelGranted) { -+ cnmTimerStopTimer(prAdapter, &prBowFsmInfo->rChGrantedTimer); -+ bowReleaseCh(prAdapter); -+ /*Requested, not granted yet */ -+ } else if (prBowFsmInfo->fgIsChannelRequested) { -+ prBowFsmInfo->fgIsChannelRequested = FALSE; -+ /* bowReleaseCh(prAdapter); */ -+ } -+#if 1 -+ /*Send Deauth to connected peer */ -+ if (eFsmState == BOW_DEVICE_STATE_CONNECTED && (prBowFsmInfo->prTargetStaRec->ucStaState == STA_STATE_3)) { -+ fgSendDeauth = TRUE; -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, -+ "wlanbowCmdEventLinkDisconnected, bowGetBowTableState, %x.\n", -+ bowGetBowTableState(prAdapter, prBowLinkDisconnected->aucPeerAddress)); -+#endif -+ authSendDeauthFrame(prAdapter, -+ prBowFsmInfo->prTargetStaRec, -+ (P_SW_RFB_T) NULL, -+ REASON_CODE_DEAUTH_LEAVING_BSS, (PFN_TX_DONE_HANDLER) bowDisconnectLink); -+ } -+#endif -+ -+#if 0 -+ /* 3 <3>Stop this link; flush Tx; -+ * send deAuthentication -> abort. SAA, AAA. need to check BOW table state == Connected. -+ */ -+ if (prAdapter->prGlueInfo->i4TxPendingFrameNum > 0) -+ kalFlushPendingTxPackets(prAdapter->prGlueInfo); -+ -+ /* flush pending security frames */ -+ if (prAdapter->prGlueInfo->i4TxPendingSecurityFrameNum > 0) -+ kalClearSecurityFrames(prAdapter->prGlueInfo); -+#endif -+ -+ /*Update BoW table */ -+ bowGetBowTableEntryByPeerAddress(prAdapter, prBowLinkDisconnected->aucPeerAddress, &ucBowTableIdx); -+ rBowTable.fgIsValid = FALSE; -+ rBowTable.eState = BOW_DEVICE_STATE_DISCONNECTED; -+ kalMemZero(rBowTable.aucPeerAddress, sizeof(rBowTable.aucPeerAddress)); -+ bowSetBowTableContent(prAdapter, ucBowTableIdx, &rBowTable); -+ -+ /*Indicate BoW event to PAL */ -+ kalIndicateBOWEvent(prAdapter->prGlueInfo, prEvent); -+ kalMemFree(prEvent, VIR_MEM_TYPE, (sizeof(AMPC_EVENT) + sizeof(BOW_LINK_DISCONNECTED))); -+ -+ /*Decrease link count */ -+ GLUE_DEC_REF_CNT(g_u4LinkCount); -+ -+ /*If no need to send deauth, DO disconnect now */ -+ /*If need to send deauth, DO disconnect at deauth Tx done */ -+ if (!fgSendDeauth) -+ bowDisconnectLink(prAdapter, NULL, TX_RESULT_SUCCESS); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief command done handler for CMD_ID_CMD_BT_OVER_WIFI -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] prCmdInfo Pointer to the buffer that holds the command info -+* \param[in] pucEventBuf Pointer to the set buffer OR event buffer -+* -+* \retval none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID wlanbowCmdEventSetSetupConnection(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) -+{ -+ P_AMPC_EVENT prEvent; -+ P_BOW_COMMAND_STATUS prBowCmdStatus; -+ P_WIFI_CMD_T prWifiCmd; -+ P_CMD_BT_OVER_WIFI prCmdBtOverWifi; -+ P_BOW_FSM_INFO_T prBowFsmInfo; -+ -+ ASSERT(prAdapter); -+ -+ prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); -+ -+ /* restore original command for rPeerAddr */ -+ prWifiCmd = (P_WIFI_CMD_T) (prCmdInfo->pucInfoBuffer); -+ prCmdBtOverWifi = (P_CMD_BT_OVER_WIFI) (prWifiCmd->aucBuffer); -+ -+ /* fill event header */ -+ prEvent = (P_AMPC_EVENT) kalMemAlloc((sizeof(AMPC_EVENT) + sizeof(BOW_COMMAND_STATUS)), VIR_MEM_TYPE); -+ if (!prEvent) { -+ ASSERT(FALSE); -+ return; -+ } -+ prEvent->rHeader.ucEventId = BOW_EVENT_ID_COMMAND_STATUS; -+ prEvent->rHeader.ucSeqNumber = (UINT_8) prCmdInfo->u4PrivateData; -+ prEvent->rHeader.u2PayloadLength = sizeof(BOW_COMMAND_STATUS); -+ -+ /* fill event body */ -+ prBowCmdStatus = (P_BOW_COMMAND_STATUS) (prEvent->aucPayload); -+ kalMemZero(prBowCmdStatus, sizeof(BOW_COMMAND_STATUS)); -+ prBowCmdStatus->ucStatus = BOWCMD_STATUS_SUCCESS; -+ -+ /*Indicate BoW event to PAL */ -+ kalIndicateBOWEvent(prAdapter->prGlueInfo, prEvent); -+ kalMemFree(prEvent, VIR_MEM_TYPE, (sizeof(AMPC_EVENT) + sizeof(BOW_COMMAND_STATUS))); -+ -+ /* set to starting status */ -+ kalSetBowState(prAdapter->prGlueInfo, BOW_DEVICE_STATE_STARTING, prCmdBtOverWifi->rPeerAddr); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This is the command done handler for BOW_CMD_ID_READ_LINK_QUALITY -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] prCmdInfo Pointer to the buffer that holds the command info -+* \param[in] pucEventBuf Pointer to the set buffer OR event buffer -+* -+* \retval none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID wlanbowCmdEventReadLinkQuality(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) -+{ -+ P_EVENT_LINK_QUALITY prLinkQuality; -+ P_AMPC_EVENT prEvent; -+ P_BOW_LINK_QUALITY prBowLinkQuality; -+ -+ ASSERT(prAdapter); -+ -+ prLinkQuality = (P_EVENT_LINK_QUALITY) pucEventBuf; -+ -+ /* fill event header */ -+ prEvent = (P_AMPC_EVENT) kalMemAlloc((sizeof(AMPC_EVENT) + sizeof(BOW_LINK_QUALITY)), VIR_MEM_TYPE); -+ if (!prEvent) { -+ ASSERT(FALSE); -+ return; -+ } -+ prEvent->rHeader.ucEventId = BOW_EVENT_ID_LINK_QUALITY; -+ prEvent->rHeader.ucSeqNumber = (UINT_8) prCmdInfo->u4PrivateData; -+ prEvent->rHeader.u2PayloadLength = sizeof(BOW_LINK_QUALITY); -+ -+ /* fill event body */ -+ prBowLinkQuality = (P_BOW_LINK_QUALITY) (prEvent->aucPayload); -+ kalMemZero(prBowLinkQuality, sizeof(BOW_LINK_QUALITY)); -+ prBowLinkQuality->ucLinkQuality = (UINT_8) prLinkQuality->cLinkQuality; -+ -+ kalIndicateBOWEvent(prAdapter->prGlueInfo, prEvent); -+ -+ kalMemFree(prEvent, VIR_MEM_TYPE, (sizeof(AMPC_EVENT) + sizeof(BOW_LINK_QUALITY))); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This is the command done handler for BOW_CMD_ID_READ_RSSI -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] prCmdInfo Pointer to the buffer that holds the command info -+* \param[in] pucEventBuf Pointer to the set buffer OR event buffer -+* -+* \retval none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID wlanbowCmdEventReadRssi(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) -+{ -+ P_EVENT_LINK_QUALITY prLinkQuality; -+ P_AMPC_EVENT prEvent; -+ P_BOW_RSSI prBowRssi; -+ -+ ASSERT(prAdapter); -+ -+ prLinkQuality = (P_EVENT_LINK_QUALITY) pucEventBuf; -+ -+ /* fill event header */ -+ prEvent = (P_AMPC_EVENT) kalMemAlloc((sizeof(AMPC_EVENT) + sizeof(BOW_LINK_QUALITY)), VIR_MEM_TYPE); -+ if (!prEvent) { -+ ASSERT(FALSE); -+ return; -+ } -+ prEvent->rHeader.ucEventId = BOW_EVENT_ID_RSSI; -+ prEvent->rHeader.ucSeqNumber = (UINT_8) prCmdInfo->u4PrivateData; -+ prEvent->rHeader.u2PayloadLength = sizeof(BOW_RSSI); -+ -+ /* fill event body */ -+ prBowRssi = (P_BOW_RSSI) (prEvent->aucPayload); -+ kalMemZero(prBowRssi, sizeof(BOW_RSSI)); -+ prBowRssi->cRssi = (INT_8) prLinkQuality->cRssi; -+ -+ kalIndicateBOWEvent(prAdapter->prGlueInfo, prEvent); -+ -+ kalMemFree(prEvent, VIR_MEM_TYPE, (sizeof(AMPC_EVENT) + sizeof(BOW_LINK_QUALITY))); -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This is the default command timeout handler -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] prCmdInfo Pointer to the buffer that holds the command info -+* -+* \retval none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID wlanbowCmdTimeoutHandler(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo) -+{ -+ P_AMPC_EVENT prEvent; -+ P_BOW_COMMAND_STATUS prBowCmdStatus; -+ -+ ASSERT(prAdapter); -+ -+ /* fill event header */ -+ prEvent = (P_AMPC_EVENT) kalMemAlloc((sizeof(AMPC_EVENT) + sizeof(BOW_COMMAND_STATUS)), VIR_MEM_TYPE); -+ if (!prEvent) { -+ ASSERT(FALSE); -+ return; -+ } -+ prEvent->rHeader.ucEventId = BOW_EVENT_ID_COMMAND_STATUS; -+ prEvent->rHeader.ucSeqNumber = (UINT_8) prCmdInfo->u4PrivateData; -+ prEvent->rHeader.u2PayloadLength = sizeof(BOW_COMMAND_STATUS); -+ -+ /* fill event body */ -+ prBowCmdStatus = (P_BOW_COMMAND_STATUS) (prEvent->aucPayload); -+ kalMemZero(prBowCmdStatus, sizeof(BOW_COMMAND_STATUS)); -+ -+ prBowCmdStatus->ucStatus = BOWCMD_STATUS_TIMEOUT; /* timeout */ -+ -+ kalIndicateBOWEvent(prAdapter->prGlueInfo, prEvent); -+ -+ kalMemFree(prEvent, VIR_MEM_TYPE, (sizeof(AMPC_EVENT) + sizeof(BOW_COMMAND_STATUS))); -+ -+} -+ -+VOID bowStopping(IN P_ADAPTER_T prAdapter) -+{ -+ P_BOW_FSM_INFO_T prBowFsmInfo; -+ P_BSS_INFO_T prBowBssInfo; -+ -+ ASSERT(prAdapter); -+ -+ prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); -+ prBowBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_BOW_INDEX]); -+ -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "bowStoping.\n"); -+ DBGLOG(BOW, EVENT, "bowStoping, SSID %s.\n", prBowBssInfo->aucSSID); -+ DBGLOG(BOW, EVENT, "bowStoping, prBowBssInfo->aucBSSID, %x:%x:%x:%x:%x:%x.\n", -+ prBowBssInfo->aucBSSID[0], -+ prBowBssInfo->aucBSSID[1], -+ prBowBssInfo->aucBSSID[2], -+ prBowBssInfo->aucBSSID[3], prBowBssInfo->aucBSSID[4], prBowBssInfo->aucBSSID[5])); -+ DBGLOG(BOW, EVENT, "bowStoping, prBssInfo->aucOwnMacAddr, %x:%x:%x:%x:%x:%x.\n", -+ prBowBssInfo->aucOwnMacAddr[0], -+ prBowBssInfo->aucOwnMacAddr[1], -+ prBowBssInfo->aucOwnMacAddr[2], -+ prBowBssInfo->aucOwnMacAddr[3], -+ prBowBssInfo->aucOwnMacAddr[4], prBowBssInfo->aucOwnMacAddr[5])); -+ DBGLOG(BOW, EVENT, "bowStoping, prAdapter->rWifiVar.aucDeviceAddress, %x:%x:%x:%x:%x:%x.\n", -+ prAdapter->rWifiVar.aucDeviceAddress[0], -+ prAdapter->rWifiVar.aucDeviceAddress[1], -+ prAdapter->rWifiVar.aucDeviceAddress[2], -+ prAdapter->rWifiVar.aucDeviceAddress[3], -+ prAdapter->rWifiVar.aucDeviceAddress[4], prAdapter->rWifiVar.aucDeviceAddress[5])); -+ DBGLOG(BOW, EVENT, "bowStopping, g_u4LinkCount, %x.\n", g_u4LinkCount); -+ DBGLOG(BOW, EVENT, "prBowFsmInfo->aucPeerAddress, %x:%x:%x:%x:%x:%x.\n", prBowFsmInfo->aucPeerAddress[0], -+ prBowFsmInfo->aucPeerAddress[1], -+ prBowFsmInfo->aucPeerAddress[2], -+ prBowFsmInfo->aucPeerAddress[3], -+ prBowFsmInfo->aucPeerAddress[4], prBowFsmInfo->aucPeerAddress[5])); -+ kalPrint("BoW Stoping,[%d,%d]\n", g_u4LinkCount, g_u4Beaconing); -+#endif -+ -+ if (g_u4LinkCount == 0) { -+ /*Stop beaconing */ -+ GLUE_DEC_REF_CNT(g_u4Beaconing); -+ -+ /*Deactive BoW network */ -+ /* prBowBssInfo->fgIsNetActive = FALSE; */ -+ /* prBowBssInfo->fgIsBeaconActivated = FALSE; */ -+ nicPmIndicateBssAbort(prAdapter, NETWORK_TYPE_BOW_INDEX); -+ bowChangeMediaState(prAdapter, PARAM_MEDIA_STATE_DISCONNECTED); -+ nicUpdateBss(prAdapter, NETWORK_TYPE_BOW_INDEX); -+ /*temp solution for FW hal_pwr_mgt.c#3037 ASSERT */ -+ nicDeactivateNetwork(prAdapter, NETWORK_TYPE_BOW_INDEX); -+ SET_NET_PWR_STATE_IDLE(prAdapter, NETWORK_TYPE_BOW_INDEX); -+ UNSET_NET_ACTIVE(prAdapter, NETWORK_TYPE_BOW_INDEX); -+ -+ } -+ -+} -+ -+VOID bowStarting(IN P_ADAPTER_T prAdapter) -+{ -+ P_BOW_FSM_INFO_T prBowFsmInfo; -+ P_BSS_INFO_T prBssInfo; -+ -+ ASSERT(prAdapter); -+ -+ prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); -+ -+ if (g_u4LinkCount == 1) { -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "BoW Starting.\n"); -+ DBGLOG(BOW, EVENT, "BoW channel granted.\n"); -+#endif -+ -+#if 0 -+ /*Active BoW Network */ -+ SET_NET_ACTIVE(prAdapter, NETWORK_TYPE_BOW_INDEX); -+ SET_NET_PWR_STATE_ACTIVE(prAdapter, NETWORK_TYPE_BOW_INDEX); -+ nicActivateNetwork(prAdapter, NETWORK_TYPE_BOW_INDEX); -+#endif -+ -+ /* 3 <1> Update BSS_INFO_T per Network Basis */ -+ /* 4 <1.1> Setup Operation Mode */ -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_BOW_INDEX]); -+ prBssInfo->ucNetTypeIndex = NETWORK_TYPE_BOW_INDEX; -+ prBssInfo->eCurrentOPMode = OP_MODE_BOW; -+ -+ /* 4 <1.2> Setup SSID */ -+ COPY_MAC_ADDR(prBssInfo->aucOwnMacAddr, prAdapter->rWifiVar.aucDeviceAddress); -+ COPY_MAC_ADDR(prBssInfo->aucBSSID, prAdapter->rWifiVar.aucDeviceAddress); -+ prBssInfo->ucSSIDLen = BOW_SSID_LEN; -+ bowAssignSsid(prBssInfo->aucSSID, prBssInfo->aucOwnMacAddr); -+ -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "SSID %s.\n", prBssInfo->aucSSID); -+ DBGLOG(BOW, EVENT, "prBssInfo->aucBSSID, %x:%x:%x:%x:%x:%x.\n", -+ prBssInfo->aucBSSID[0], -+ prBssInfo->aucBSSID[1], -+ prBssInfo->aucBSSID[2], -+ prBssInfo->aucBSSID[3], prBssInfo->aucBSSID[4], prBssInfo->aucBSSID[5])); -+ DBGLOG(BOW, EVENT, "prBssInfo->aucOwnMacAddr, %x:%x:%x:%x:%x:%x.\n", -+ prBssInfo->aucOwnMacAddr[0], -+ prBssInfo->aucOwnMacAddr[1], -+ prBssInfo->aucOwnMacAddr[2], -+ prBssInfo->aucOwnMacAddr[3], -+ prBssInfo->aucOwnMacAddr[4], prBssInfo->aucOwnMacAddr[5])); -+ DBGLOG(BOW, EVENT, "prAdapter->rWifiVar.aucDeviceAddress, %x:%x:%x:%x:%x:%x.\n", -+ prAdapter->rWifiVar.aucDeviceAddress[0], -+ prAdapter->rWifiVar.aucDeviceAddress[1], -+ prAdapter->rWifiVar.aucDeviceAddress[2], -+ prAdapter->rWifiVar.aucDeviceAddress[3], -+ prAdapter->rWifiVar.aucDeviceAddress[4], prAdapter->rWifiVar.aucDeviceAddress[5])); -+#endif -+ -+ /* 4 <1.3> Clear current AP's STA_RECORD_T and current AID */ -+ prBssInfo->prStaRecOfAP = (P_STA_RECORD_T) NULL; -+ prBssInfo->u2AssocId = 0; -+ -+ /* 4 <1.4> Setup Channel, Band and Phy Attributes */ -+ prBssInfo->ucPrimaryChannel = prBowFsmInfo->ucPrimaryChannel; -+ if (prBowFsmInfo->eBand == BAND_2G4) -+ prBssInfo->eBand = BAND_2G4; -+ else -+ prBssInfo->eBand = BAND_5G; -+ -+#if CFG_BOW_SUPPORT_11N -+ /* Depend on eBand */ -+ prBssInfo->ucPhyTypeSet = prAdapter->rWifiVar.ucAvailablePhyTypeSet & PHY_TYPE_SET_802_11BGN; -+ /* Depend on eCurrentOPMode and ucPhyTypeSet */ -+ prBssInfo->ucConfigAdHocAPMode = AP_MODE_MIXED_11BG; -+ -+ prBssInfo->ucNonHTBasicPhyType = (UINT_8) -+ rNonHTApModeAttributes[prBssInfo->ucConfigAdHocAPMode].ePhyTypeIndex; -+ prBssInfo->u2BSSBasicRateSet = rNonHTApModeAttributes[prBssInfo->ucConfigAdHocAPMode].u2BSSBasicRateSet; -+ -+ prBssInfo->u2OperationalRateSet = -+ rNonHTPhyAttributes[prBssInfo->ucNonHTBasicPhyType].u2SupportedRateSet; -+ -+ rateGetDataRatesFromRateSet(prBssInfo->u2OperationalRateSet, -+ prBssInfo->u2BSSBasicRateSet, -+ prBssInfo->aucAllSupportedRates, &prBssInfo->ucAllSupportedRatesLen); -+ -+#else -+ if (prBssInfo->eBand == BAND_2G4) { -+ /* Depend on eBand */ -+ prBssInfo->ucPhyTypeSet = PHY_TYPE_SET_802_11BG; -+ /* Depend on eCurrentOPMode and ucPhyTypeSet */ -+ prBssInfo->ucConfigAdHocAPMode = AP_MODE_MIXED_11BG; -+ -+ /* RATE_SET_ERP; */ -+ prBssInfo->u2BSSBasicRateSet = BASIC_RATE_SET_ERP; -+ prBssInfo->u2OperationalRateSet = RATE_SET_ERP; -+ prBssInfo->ucNonHTBasicPhyType = PHY_TYPE_ERP_INDEX; -+ } else { -+ /* Depend on eBand */ -+ /* prBssInfo->ucPhyTypeSet = PHY_TYPE_SET_802_11BG; */ -+ /* Depend on eCurrentOPMode and ucPhyTypeSet */ -+ /* prBssInfo->ucConfigAdHocAPMode = AP_MODE_MIXED_11BG; */ -+ /* Depend on eBand */ -+ prBssInfo->ucPhyTypeSet = PHY_TYPE_SET_802_11A; -+ /* Depend on eCurrentOPMode and ucPhyTypeSet */ -+ prBssInfo->ucConfigAdHocAPMode = AP_MODE_11A; -+ -+ /* RATE_SET_ERP; */ -+ /* prBssInfo->u2BSSBasicRateSet = BASIC_RATE_SET_ERP; */ -+ /* prBssInfo->u2OperationalRateSet = RATE_SET_ERP; */ -+ -+ /* RATE_SET_ERP; */ -+ prBssInfo->u2BSSBasicRateSet = BASIC_RATE_SET_OFDM; -+ prBssInfo->u2OperationalRateSet = RATE_SET_OFDM; -+ prBssInfo->ucNonHTBasicPhyType = PHY_TYPE_OFDM_INDEX; -+ } -+ -+#endif -+ prBssInfo->fgErpProtectMode = FALSE; -+ -+ /* 4 <1.5> Setup MIB for current BSS */ -+ prBssInfo->u2BeaconInterval = prBowFsmInfo->u2BeaconInterval; -+ prBssInfo->ucDTIMPeriod = DOT11_DTIM_PERIOD_DEFAULT; -+ prBssInfo->u2ATIMWindow = 0; -+ prBssInfo->ucBeaconTimeoutCount = 0; -+ if (prBowFsmInfo->fgSupportQoS) { -+ prAdapter->rWifiVar.fgSupportQoS = TRUE; -+ prBssInfo->fgIsQBSS = TRUE; -+ } -+ /* 3 <2> Update BSS_INFO_T common part */ -+#if CFG_SUPPORT_AAA -+ bssInitForAP(prAdapter, prBssInfo, TRUE); -+ nicQmUpdateWmmParms(prAdapter, NETWORK_TYPE_BOW_INDEX); -+#endif /* CFG_SUPPORT_AAA */ -+ prBssInfo->fgIsNetActive = TRUE; -+ prBssInfo->fgIsBeaconActivated = TRUE; -+ -+ /* 3 <3> Set MAC HW */ -+ -+ /* 4 <2> Initiate BSS_INFO_T - common part */ -+ BOW_BSS_INFO_INIT(prAdapter, NETWORK_TYPE_BOW_INDEX); -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, -+ "prBowFsmInfo->aucPeerAddress, %x:%x:%x:%x:%x:%x.\n", prBowFsmInfo->aucPeerAddress[0], -+ prBowFsmInfo->aucPeerAddress[1], prBowFsmInfo->aucPeerAddress[2], -+ prBowFsmInfo->aucPeerAddress[3], prBowFsmInfo->aucPeerAddress[4], -+ prBowFsmInfo->aucPeerAddress[5])); -+#endif -+ -+ /* 4 <3.1> use command packets to inform firmware */ -+ rlmBssInitForAPandIbss(prAdapter, prBssInfo); -+ nicUpdateBss(prAdapter, NETWORK_TYPE_BOW_INDEX); -+ -+ /* 4 <3.2> Update AdHoc PM parameter */ -+ nicPmIndicateBssCreated(prAdapter, NETWORK_TYPE_BOW_INDEX); -+ -+ /* 4 <3.1> Reset HW TSF Update Mode and Beacon Mode */ -+ -+ /* 4 <3.2> Setup BSSID */ -+ /* TODO: rxmSetRxFilterBSSID0 */ -+/* rxmSetRxFilterBSSID0(prBssInfo->ucHwBssidId, prBssInfo->aucBSSID); */ -+ -+ /* 4 <3.3> Setup RX Filter to accept Probe Request */ -+ /* TODO: f get/set RX filter. */ -+ -+#if 0 -+ { -+ UINT_32 u4RxFilter; -+ -+ if (halMacRxGetRxFilters(&u4RxFilter) == HAL_STATUS_SUCCESS) { -+ -+ u4RxFilter &= ~BIT(RXFILTER_DROP_PROBE_REQ); -+ -+ halMacRxSetRxFilters(u4RxFilter); -+ } -+ } -+#endif -+ } -+ -+ /*Update BoW Table */ -+ bowSetBowTableState(prAdapter, prBowFsmInfo->aucPeerAddress, BOW_DEVICE_STATE_STARTING); -+ -+#if CFG_BOW_TEST -+ kalPrint("BoW Starting,[%d,%d]\n", g_u4LinkCount, g_u4Beaconing); -+ DBGLOG(BOW, EVENT, "bowStarting, g_u4LinkCount, %x.\n", g_u4LinkCount); -+#endif -+ -+ /*Start beaconing */ -+ if (g_u4Beaconing < 1) { -+ GLUE_INC_REF_CNT(g_u4Beaconing); -+ bssSendBeaconProbeResponse(prAdapter, NETWORK_TYPE_BOW_INDEX, NULL, 0); -+ cnmTimerStartTimer(prAdapter, &prBowFsmInfo->rStartingBeaconTimer, prBowFsmInfo->u2BeaconInterval); -+ } -+#if 0 -+ /*Responder: Start to scan Initiator */ -+ if (prBowFsmInfo->ucRole == BOW_RESPONDER) { -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "bowStarting responder, start scan result searching.\n"); -+#endif -+ cnmTimerStopTimer(prAdapter, &prBowFsmInfo->rChGrantedTimer); -+ bowReleaseCh(prAdapter); -+ bowResponderScan(prAdapter); -+ } -+ /*Initiator: Request channel, wait for responder */ -+ else { -+ /* Todo:: Nothing*/ -+ /* bowRequestCh(prAdapter); */ -+ } -+#endif -+ -+} -+ -+VOID bowAssignSsid(IN PUINT_8 pucSsid, IN PUINT_8 puOwnMacAddr) -+{ -+ UINT_8 i; -+ UINT_8 aucSSID[] = BOW_WILDCARD_SSID; -+ -+ kalMemCopy(pucSsid, aucSSID, BOW_WILDCARD_SSID_LEN); -+ -+ for (i = 0; i < 6; i++) { -+ pucSsid[(3 * i) + 3] = 0x2D; -+ if ((*(puOwnMacAddr + i) >> 4) < 0xA) -+ *(pucSsid + (3 * i) + 4) = (*(puOwnMacAddr + i) >> 4) + 0x30; -+ else -+ *(pucSsid + (3 * i) + 4) = (*(puOwnMacAddr + i) >> 4) + 0x57; -+ -+ if ((*(puOwnMacAddr + i) & 0x0F) < 0xA) -+ pucSsid[(3 * i) + 5] = (*(puOwnMacAddr + i) & 0x0F) + 0x30; -+ else -+ pucSsid[(3 * i) + 5] = (*(puOwnMacAddr + i) & 0x0F) + 0x57; -+ } -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will validate the Rx Probe Request Frame and then return -+* result to BSS to indicate if need to send the corresponding Probe Response -+* Frame if the specified conditions were matched. -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* @param[in] prSwRfb Pointer to SW RFB data structure. -+* @param[out] pu4ControlFlags Control flags for replying the Probe Response -+* -+* @retval TRUE Reply the Probe Response -+* @retval FALSE Don't reply the Probe Response -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN bowValidateProbeReq(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, OUT PUINT_32 pu4ControlFlags) -+{ -+ P_WLAN_MAC_MGMT_HEADER_T prMgtHdr; -+ P_BOW_FSM_INFO_T prBowFsmInfo; -+ P_BSS_INFO_T prBssInfo; -+ P_IE_SSID_T prIeSsid = (P_IE_SSID_T) NULL; -+ PUINT_8 pucIE; -+ UINT_16 u2IELength; -+ UINT_16 u2Offset = 0; -+ BOOLEAN fgReplyProbeResp = FALSE; -+ -+ ASSERT(prSwRfb); -+ ASSERT(pu4ControlFlags); -+ -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_BOW_INDEX]); -+ prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); -+ -+#if 0 /* CFG_BOW_TEST */ -+ DBGLOG(BOW, EVENT, "bowValidateProbeReq.\n"); -+#endif -+ -+ /* 4 <1> Parse Probe Req IE and Get IE ptr (SSID, Supported Rate IE, ...) */ -+ prMgtHdr = (P_WLAN_MAC_MGMT_HEADER_T) prSwRfb->pvHeader; -+ -+ u2IELength = prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen; -+ pucIE = (PUINT_8) ((ULONG) prSwRfb->pvHeader + prSwRfb->u2HeaderLen); -+ -+ IE_FOR_EACH(pucIE, u2IELength, u2Offset) { -+ if (ELEM_ID_SSID == IE_ID(pucIE)) { -+ if ((!prIeSsid) && (IE_LEN(pucIE) <= ELEM_MAX_LEN_SSID)) -+ prIeSsid = (P_IE_SSID_T) pucIE; -+ break; -+ } -+ } /* end of IE_FOR_EACH */ -+ -+ IE_FOR_EACH(pucIE, u2IELength, u2Offset) { -+ if (ELEM_ID_SSID == IE_ID(pucIE)) { -+ if ((!prIeSsid) && (IE_LEN(pucIE) <= ELEM_MAX_LEN_SSID)) -+ prIeSsid = (P_IE_SSID_T) pucIE; -+ break; -+ } -+ } /* end of IE_FOR_EACH */ -+ -+ /* 4 <2> Check network conditions */ -+ /*If BoW AP is beaconing */ -+ if (prBssInfo->eCurrentOPMode == OP_MODE_BOW && g_u4Beaconing > 0) { -+ -+ /*Check the probe requset sender is our peer */ -+ if (bowCheckBowTableIfVaild(prAdapter, prMgtHdr->aucSrcAddr)) -+ fgReplyProbeResp = TRUE; -+ /*Check the probe request target SSID is our SSID */ -+ else if ((prIeSsid) && -+ EQUAL_SSID(prBssInfo->aucSSID, prBssInfo->ucSSIDLen, prIeSsid->aucSSID, prIeSsid->ucLength)) -+ fgReplyProbeResp = TRUE; -+ else -+ fgReplyProbeResp = FALSE; -+ } -+ -+ return fgReplyProbeResp; -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will indicate an Event of "Media Disconnect" to HOST -+* -+* @param[in] u4Param Unused timer parameter -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID bowSendBeacon(IN P_ADAPTER_T prAdapter, IN ULONG ulParam) -+{ -+ P_BOW_FSM_INFO_T prBowFsmInfo; -+ -+ prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); -+ -+ if ((g_u4Beaconing != 0) && (g_u4LinkCount > 0) && (g_u4LinkCount < CFG_BOW_PHYSICAL_LINK_NUM)) { -+ /* Send beacon */ -+ bssSendBeaconProbeResponse(prAdapter, NETWORK_TYPE_BOW_INDEX, NULL, 0); -+ cnmTimerStartTimer(prAdapter, &prBowFsmInfo->rStartingBeaconTimer, prBowFsmInfo->u2BeaconInterval); -+ } -+#if CFG_BOW_TEST -+ else -+ kalPrint("BoW Send Beacon,[%d,%d]\n", g_u4LinkCount, g_u4Beaconing); -+#endif -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will indicate an Event of "Media Disconnect" to HOST -+* -+* @param[in] u4Param Unused timer parameter -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID bowResponderScan(IN P_ADAPTER_T prAdapter) -+{ -+ P_BOW_FSM_INFO_T prBowFsmInfo; -+ P_MSG_SCN_SCAN_REQ prScanReqMsg; -+ P_BSS_INFO_T prBssInfo; -+ -+ ASSERT(prAdapter); -+ -+ prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_BOW_INDEX]); -+ -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "bowResponderScan.\n"); -+ kalPrint("BOW SCAN [REQ:%d]\n", prBowFsmInfo->ucSeqNumOfScanReq + 1); -+#endif -+ -+ prScanReqMsg = (P_MSG_SCN_SCAN_REQ) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_SCN_SCAN_REQ)); -+ -+ if (!prScanReqMsg) { -+ ASSERT(0); /* Can't trigger SCAN FSM */ -+ return; -+ } -+ -+ /*Fill scan message */ -+ prScanReqMsg->rMsgHdr.eMsgId = MID_BOW_SCN_SCAN_REQ; -+ prScanReqMsg->ucSeqNum = ++prBowFsmInfo->ucSeqNumOfScanReq; -+ prScanReqMsg->ucNetTypeIndex = (UINT_8) NETWORK_TYPE_BOW_INDEX; -+ prScanReqMsg->eScanType = SCAN_TYPE_ACTIVE_SCAN; -+ prScanReqMsg->ucSSIDType = SCAN_REQ_SSID_SPECIFIED; -+ prScanReqMsg->ucSSIDLength = BOW_SSID_LEN; -+ bowAssignSsid(prScanReqMsg->aucSSID, prBowFsmInfo->aucPeerAddress); -+ prScanReqMsg->ucChannelListNum = 1; -+ -+ if (prBowFsmInfo->eBand == BAND_2G4) { -+ prScanReqMsg->eScanChannel = SCAN_CHANNEL_SPECIFIED; -+ prScanReqMsg->arChnlInfoList[0].eBand = BAND_2G4; -+ } else { -+ prScanReqMsg->eScanChannel = SCAN_CHANNEL_5G; -+ prScanReqMsg->arChnlInfoList[0].eBand = BAND_5G; -+ } -+ -+ prScanReqMsg->arChnlInfoList[0].ucChannelNum = prBowFsmInfo->ucPrimaryChannel; -+ prScanReqMsg->u2IELen = 0; -+ -+ /*Send scan message */ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prScanReqMsg, MSG_SEND_METHOD_BUF); -+ -+ /*Change state to SCANNING */ -+ bowSetBowTableState(prAdapter, prBowFsmInfo->aucPeerAddress, BOW_DEVICE_STATE_SCANNING); -+ -+ /* prBowFsmInfo->fgTryScan = FALSE; */ /* Will enable background sleep for infrastructure */ -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID bowResponderScanDone(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) -+{ -+ P_MSG_SCN_SCAN_DONE prScanDoneMsg; -+ P_BOW_FSM_INFO_T prBowFsmInfo; -+ P_BSS_DESC_T prBssDesc; -+ UINT_8 ucSeqNumOfCompMsg; -+ P_CONNECTION_SETTINGS_T prConnSettings; -+ ENUM_BOW_DEVICE_STATE eFsmState; -+ ENUM_SCAN_STATUS eScanStatus; -+ -+ ASSERT(prAdapter); -+ ASSERT(prMsgHdr); -+ -+ prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); -+ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); -+ prScanDoneMsg = (P_MSG_SCN_SCAN_DONE) prMsgHdr; -+ eFsmState = bowGetBowTableState(prAdapter, prBowFsmInfo->aucPeerAddress); -+ -+ ASSERT(prScanDoneMsg->ucNetTypeIndex == NETWORK_TYPE_BOW_INDEX); -+ -+ ucSeqNumOfCompMsg = prScanDoneMsg->ucSeqNum; -+ eScanStatus = prScanDoneMsg->eScanStatus; -+ -+ cnmMemFree(prAdapter, prMsgHdr); -+ -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "bowResponderScanDone.\n"); -+ kalPrint("BOW SCAN [DONE:%d]\n", ucSeqNumOfCompMsg); -+#endif -+ -+ if (eScanStatus == SCAN_STATUS_CANCELLED) { -+#if CFG_BOW_TEST -+ kalPrint("BOW SCAN [CANCELLED:%d]\n", ucSeqNumOfCompMsg); -+#endif -+ if (eFsmState == BOW_DEVICE_STATE_DISCONNECTING) { -+ wlanoidSendSetQueryBowCmd(prAdapter, -+ CMD_ID_CMD_BT_OVER_WIFI, -+ TRUE, -+ FALSE, -+ wlanbowCmdEventLinkDisconnected, -+ wlanbowCmdTimeoutHandler, 0, NULL, 0); -+ } -+ return; -+ } else if (eFsmState == BOW_DEVICE_STATE_DISCONNECTED) { -+ /* bowDisconnectLink(prAdapter, NULL, TX_RESULT_SUCCESS); */ -+ return; -+ } else if (ucSeqNumOfCompMsg != prBowFsmInfo->ucSeqNumOfScanReq) { -+ DBGLOG(BOW, EVENT, "Sequence no. of BOW Responder scan done is not matched.\n"); -+ return; -+ } -+ prConnSettings->fgIsScanReqIssued = FALSE; -+ prBssDesc = scanSearchBssDescByBssid(prAdapter, prBowFsmInfo->aucPeerAddress); -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "End scan result searching.\n"); -+#endif -+ -+ /* Initiator is FOUND */ -+ if (prBssDesc != NULL) { -+ /* (prBssDesc->aucBSSID != NULL)) */ -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "Search Bow Peer address - %x:%x:%x:%x:%x:%x.\n", prBssDesc->aucBSSID[0], -+ prBssDesc->aucBSSID[1], -+ prBssDesc->aucBSSID[2], -+ prBssDesc->aucBSSID[3], prBssDesc->aucBSSID[4], prBssDesc->aucBSSID[5]); -+ DBGLOG(BOW, EVENT, "Starting to join initiator.\n"); -+#endif -+ /*Set target BssDesc */ -+ prBowFsmInfo->prTargetBssDesc = prBssDesc; -+ /*Request channel to do JOIN */ -+ bowSetBowTableState(prAdapter, prBowFsmInfo->aucPeerAddress, -+ BOW_DEVICE_STATE_ACQUIRING_CHANNEL); -+ bowRequestCh(prAdapter); -+ } -+ /*Initiator is NOT FOUND */ -+ else { -+ /*Scan again, until PAL timeout */ -+ bowResponderScan(prAdapter); -+#if 0 -+ wlanoidSendSetQueryBowCmd(prAdapter, -+ CMD_ID_CMD_BT_OVER_WIFI, -+ TRUE, -+ FALSE, -+ wlanbowCmdEventLinkDisconnected, -+ wlanbowCmdTimeoutHandler, 0, NULL, 0); -+#endif -+ } -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Function for cancelling scan request. There is another option to extend channel privilige -+* for another purpose. -+* -+* @param fgIsChannelExtention - Keep the channel previlege, but can cancel scan timer. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID bowResponderCancelScan(IN P_ADAPTER_T prAdapter, IN BOOLEAN fgIsChannelExtention) -+{ -+ -+ P_MSG_SCN_SCAN_CANCEL prScanCancel = (P_MSG_SCN_SCAN_CANCEL) NULL; -+ P_BOW_FSM_INFO_T prBowFsmInfo = (P_BOW_FSM_INFO_T) NULL; -+ -+ DEBUGFUNC("bowResponderCancelScan()"); -+ -+ do { -+ ASSERT(prAdapter); -+ -+ prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); -+ -+ if (TRUE) { -+#if CFG_BOW_TEST -+ kalPrint("BOW SCAN [CANCEL:%d]\n", prBowFsmInfo->ucSeqNumOfScanReq); -+#endif -+ /* There is a channel privilege on hand. */ -+ -+ DBGLOG(P2P, TRACE, "BOW Cancel Scan\n"); -+ -+ prScanCancel = -+ (P_MSG_SCN_SCAN_CANCEL) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_SCN_SCAN_CANCEL)); -+ if (!prScanCancel) { -+ /* Buffer not enough, can not cancel scan request. */ -+ DBGLOG(P2P, TRACE, "Buffer not enough, can not cancel scan.\n"); -+ ASSERT(FALSE); -+ break; -+ } -+ -+ prScanCancel->rMsgHdr.eMsgId = MID_BOW_SCN_SCAN_CANCEL; -+ prScanCancel->ucNetTypeIndex = NETWORK_TYPE_BOW_INDEX; -+ prScanCancel->ucSeqNum = prBowFsmInfo->ucSeqNumOfScanReq; -+#if CFG_ENABLE_WIFI_DIRECT -+ prScanCancel->fgIsChannelExt = fgIsChannelExtention; -+#endif -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prScanCancel, MSG_SEND_METHOD_BUF); -+ -+ } -+ -+ } while (FALSE); -+ -+} /* bowResponderCancelScan */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Initialization of JOIN STATE -+* -+* @param[in] prBssDesc The pointer of BSS_DESC_T which is the BSS we will try to join with. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID bowResponderJoin(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBssDesc) -+{ -+ P_BOW_FSM_INFO_T prBowFsmInfo; -+ P_BSS_INFO_T prBssInfo; -+ P_CONNECTION_SETTINGS_T prConnSettings; -+ P_STA_RECORD_T prStaRec; -+ P_MSG_JOIN_REQ_T prJoinReqMsg; -+ -+ ASSERT(prBssDesc); -+ ASSERT(prAdapter); -+ -+ DBGLOG(BOW, EVENT, "Starting bowResponderJoin.\n"); -+ -+ prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_BOW_INDEX]); -+ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); -+ -+ /* 4 <1> We are going to connect to this BSS. */ -+ prBssDesc->fgIsConnecting = TRUE; -+ bowSetBowTableState(prAdapter, prBowFsmInfo->aucPeerAddress, BOW_DEVICE_STATE_CONNECTING); -+ -+ /* 4 <2> Setup corresponding STA_RECORD_T */ -+ /*Support First JOIN and retry */ -+ prStaRec = bssCreateStaRecFromBssDesc(prAdapter, STA_TYPE_BOW_AP, NETWORK_TYPE_BOW_INDEX, prBssDesc); -+ if (!prStaRec) -+ return; -+ -+ prBowFsmInfo->prTargetStaRec = prStaRec; -+ -+ /* 4 <3> Update ucAvailableAuthTypes which we can choice during SAA */ -+ prStaRec->fgIsReAssoc = FALSE; -+ prBowFsmInfo->ucAvailableAuthTypes = (UINT_8) AUTH_TYPE_OPEN_SYSTEM; -+ prStaRec->ucTxAuthAssocRetryLimit = TX_AUTH_ASSOCI_RETRY_LIMIT; -+ -+ /* 4 <4> Use an appropriate Authentication Algorithm Number among the ucAvailableAuthTypes */ -+ if (prBowFsmInfo->ucAvailableAuthTypes & (UINT_8) AUTH_TYPE_OPEN_SYSTEM) { -+ -+ DBGLOG(BOW, LOUD, "JOIN INIT: Try to do Authentication with AuthType == OPEN_SYSTEM.\n"); -+ prBowFsmInfo->ucAvailableAuthTypes &= ~(UINT_8) AUTH_TYPE_OPEN_SYSTEM; -+ -+ prStaRec->ucAuthAlgNum = (UINT_8) AUTH_ALGORITHM_NUM_OPEN_SYSTEM; -+ } else { -+ ASSERT(0); -+ } -+ -+ /* 4 <4.1> sync. to firmware domain */ -+ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); -+ -+ /* 4 <5> Overwrite Connection Setting for eConnectionPolicy */ -+ if (prBssDesc->ucSSIDLen) { -+ COPY_SSID(prConnSettings->aucSSID, prConnSettings->ucSSIDLen, prBssDesc->aucSSID, prBssDesc->ucSSIDLen); -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "bowResponderJoin, SSID %s.\n", prBssDesc->aucSSID); -+ DBGLOG(BOW, EVENT, "bowResponderJoin, SSID %s.\n", prConnSettings->aucSSID); -+#endif -+ } -+ /* 4 <6> Send a Msg to trigger SAA to start JOIN process. */ -+ prJoinReqMsg = (P_MSG_JOIN_REQ_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_JOIN_REQ_T)); -+ if (!prJoinReqMsg) { -+ -+ ASSERT(0); /* Can't trigger SAA FSM */ -+ return; -+ } -+ -+ prJoinReqMsg->rMsgHdr.eMsgId = MID_BOW_SAA_FSM_START; -+ prJoinReqMsg->ucSeqNum = ++prBowFsmInfo->ucSeqNumOfReqMsg; -+ prJoinReqMsg->prStaRec = prStaRec; -+ -+ prBssInfo->prStaRecOfAP = prStaRec; -+ -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "prStaRec->eStaType, %x.\n", prStaRec->eStaType); -+ DBGLOG(BOW, INFO, "BoW trigger SAA [%pM]\n", prStaRec->aucMacAddr); -+#endif -+ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prJoinReqMsg, MSG_SEND_METHOD_BUF); -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will handle the Join Complete Event from SAA FSM for BOW FSM -+* -+* @param[in] prMsgHdr Message of Join Complete of SAA FSM. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID bowFsmRunEventJoinComplete(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) -+{ -+ P_MSG_JOIN_COMP_T prJoinCompMsg; -+ P_BOW_FSM_INFO_T prBowFsmInfo; -+ P_STA_RECORD_T prStaRec; -+ P_SW_RFB_T prAssocRspSwRfb; -+ P_BSS_INFO_T prBssInfo; -+ P_WLAN_ASSOC_RSP_FRAME_T prAssocRspFrame = (P_WLAN_ASSOC_RSP_FRAME_T) NULL; -+ UINT_16 u2IELength; -+ PUINT_8 pucIE; -+ P_BSS_INFO_T prBowBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_BOW_INDEX]); -+ -+ ASSERT(prAdapter); -+ ASSERT(prMsgHdr); -+ -+ prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); -+ prJoinCompMsg = (P_MSG_JOIN_COMP_T) prMsgHdr; -+ prStaRec = prJoinCompMsg->prStaRec; -+ -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "Start bowfsmRunEventJoinComplete.\n"); -+ DBGLOG(BOW, EVENT, "bowfsmRunEventJoinComplete ptr check\n"); -+ DBGLOG(BOW, EVENT, "prMsgHdr %x\n", prMsgHdr); -+ DBGLOG(BOW, EVENT, "prAdapter %x\n", prAdapter); -+ DBGLOG(BOW, EVENT, "prBowFsmInfo %x\n", prBowFsmInfo); -+ DBGLOG(BOW, EVENT, "prStaRec %x\n", prStaRec); -+#endif -+ -+ ASSERT(prStaRec); -+ ASSERT(prBowFsmInfo); -+ -+ /* Check SEQ NUM */ -+ if (prJoinCompMsg->ucSeqNum == prBowFsmInfo->ucSeqNumOfReqMsg) { -+ COPY_MAC_ADDR(prBowFsmInfo->aucPeerAddress, prStaRec->aucMacAddr); -+ -+ /* 4 <1> JOIN was successful */ -+ if (prJoinCompMsg->rJoinStatus == WLAN_STATUS_SUCCESS) { -+ prAssocRspSwRfb = prJoinCompMsg->prSwRfb; -+ prAssocRspFrame = (P_WLAN_ASSOC_RSP_FRAME_T) prAssocRspSwRfb->pvHeader; -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_BOW_INDEX]); -+ -+ u2IELength = (UINT_16) ((prAssocRspSwRfb->u2PacketLen - prAssocRspSwRfb->u2HeaderLen) - -+ (OFFSET_OF(WLAN_ASSOC_RSP_FRAME_T, aucInfoElem[0]) - -+ WLAN_MAC_MGMT_HEADER_LEN)); -+ pucIE = prAssocRspFrame->aucInfoElem; -+ -+ prStaRec->eStaType = STA_TYPE_BOW_AP; -+ prStaRec->u2DesiredNonHTRateSet &= prBowBssInfo->u2OperationalRateSet; -+ prStaRec->ucDesiredPhyTypeSet = prStaRec->ucPhyTypeSet & prBowBssInfo->ucPhyTypeSet; -+#if CFG_BOW_RATE_LIMITATION -+ /* 4 <1.2>Update Rate Set */ -+ /*Limit Rate Set to 24M, 48M, 54M */ -+ prStaRec->u2DesiredNonHTRateSet &= (RATE_SET_BIT_24M | RATE_SET_BIT_48M | RATE_SET_BIT_54M); -+ /*If peer cannot support the above rate set, fix on the available highest rate */ -+ if (prStaRec->u2DesiredNonHTRateSet == 0) { -+ UINT_8 ucHighestRateIndex; -+ -+ if (rateGetHighestRateIndexFromRateSet -+ (prBowBssInfo->u2OperationalRateSet, &ucHighestRateIndex)) { -+ prStaRec->u2DesiredNonHTRateSet = BIT(ucHighestRateIndex); -+ } -+ } -+#endif -+ -+ /* 4 <1.1> Change FW's Media State immediately. */ -+ bowChangeMediaState(prAdapter, PARAM_MEDIA_STATE_CONNECTED); -+ -+ mqmProcessAssocRsp(prAdapter, prAssocRspSwRfb, pucIE, u2IELength); -+ -+ /* 4 <1.2> Update HT information and set channel */ -+ /* Record HT related parameters in rStaRec and rBssInfo -+ * Note: it shall be called before nicUpdateBss() -+ */ -+#if CFG_BOW_SUPPORT_11N -+ rlmProcessAssocRsp(prAdapter, prAssocRspSwRfb, pucIE, u2IELength); -+#endif -+ -+ /* 4 <1.3> Update BSS_INFO_T */ -+ nicUpdateBss(prAdapter, NETWORK_TYPE_BOW_INDEX); -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "Finish bowUpdateBssInfoForJOIN.\n"); -+#endif -+ /* 4 <1.4> Activate current AP's STA_RECORD_T in Driver. */ -+ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_3); -+ -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "bowFsmRunEventJoinComplete, qmActivateStaRec.\n"); -+#endif -+ -+ /* 4 <1.7> Set the Next State of BOW FSM */ -+ wlanoidSendSetQueryBowCmd(prAdapter, -+ CMD_ID_CMD_BT_OVER_WIFI, -+ TRUE, -+ FALSE, -+ wlanbowCmdEventLinkConnected, wlanbowCmdTimeoutHandler, 0, NULL, 0); -+ } -+ /* 4 <2> JOIN was not successful */ -+ else { -+ /*Retry */ -+ bowResponderJoin(prAdapter, prBowFsmInfo->prTargetBssDesc); -+#if 0 -+ wlanoidSendSetQueryBowCmd(prAdapter, -+ CMD_ID_CMD_BT_OVER_WIFI, -+ TRUE, -+ FALSE, -+ wlanbowCmdEventLinkDisconnected, -+ wlanbowCmdTimeoutHandler, 0, NULL, 0); -+#endif -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "Start bowfsmRunEventJoinComplete -- Join failed.\n"); -+ DBGLOG(BOW, INFO, "BoW trigger SAA REJOIN\n"); -+#endif -+ } -+ } -+ -+ cnmMemFree(prAdapter, prMsgHdr); -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will indicate the Media State to HOST -+* -+* @param[in] eConnectionState Current Media State -+* @param[in] fgDelayIndication Set TRUE for postponing the Disconnect Indication. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+bowIndicationOfMediaStateToHost(IN P_ADAPTER_T prAdapter, -+ IN ENUM_PARAM_MEDIA_STATE_T eConnectionState, IN BOOLEAN fgDelayIndication) -+{ -+ EVENT_CONNECTION_STATUS rEventConnStatus; -+ P_CONNECTION_SETTINGS_T prConnSettings; -+ P_BSS_INFO_T prBssInfo; -+ P_BOW_FSM_INFO_T prBowFsmInfo; -+ -+ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_BOW_INDEX]); -+ prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); -+ -+ /* NOTE(Kevin): Move following line to bowChangeMediaState() macro per CM's request. */ -+ /* prBowBssInfo->eConnectionState = eConnectionState; */ -+ -+ /* For indicating the Disconnect Event only if current media state is -+ * disconnected and we didn't do indication yet. -+ */ -+ if (prBssInfo->eConnectionState == PARAM_MEDIA_STATE_DISCONNECTED) { -+ if (prBssInfo->eConnectionStateIndicated == eConnectionState) -+ return; -+ } -+ -+ if (!fgDelayIndication) { -+ /* 4 <0> Cancel Delay Timer */ -+ cnmTimerStopTimer(prAdapter, &prBowFsmInfo->rIndicationOfDisconnectTimer); -+ -+ /* 4 <1> Fill EVENT_CONNECTION_STATUS */ -+ rEventConnStatus.ucMediaStatus = (UINT_8) eConnectionState; -+ -+ if (eConnectionState == PARAM_MEDIA_STATE_CONNECTED) { -+ rEventConnStatus.ucReasonOfDisconnect = DISCONNECT_REASON_CODE_RESERVED; -+ -+ if (prBssInfo->eCurrentOPMode == OP_MODE_BOW) { -+ rEventConnStatus.ucInfraMode = (UINT_8) NET_TYPE_INFRA; -+ rEventConnStatus.u2AID = prBssInfo->u2AssocId; -+ rEventConnStatus.u2ATIMWindow = 0; -+ } else if (prBssInfo->eCurrentOPMode == OP_MODE_IBSS) { -+ rEventConnStatus.ucInfraMode = (UINT_8) NET_TYPE_IBSS; -+ rEventConnStatus.u2AID = 0; -+ rEventConnStatus.u2ATIMWindow = prBssInfo->u2ATIMWindow; -+ } else { -+ ASSERT(0); -+ } -+ -+ COPY_SSID(rEventConnStatus.aucSsid, -+ rEventConnStatus.ucSsidLen, prConnSettings->aucSSID, prConnSettings->ucSSIDLen); -+ -+ COPY_MAC_ADDR(rEventConnStatus.aucBssid, prBssInfo->aucBSSID); -+ -+ rEventConnStatus.u2BeaconPeriod = prBssInfo->u2BeaconInterval; -+ rEventConnStatus.u4FreqInKHz = nicChannelNum2Freq(prBssInfo->ucPrimaryChannel); -+ -+ switch (prBssInfo->ucNonHTBasicPhyType) { -+ case PHY_TYPE_HR_DSSS_INDEX: -+ rEventConnStatus.ucNetworkType = (UINT_8) PARAM_NETWORK_TYPE_DS; -+ break; -+ -+ case PHY_TYPE_ERP_INDEX: -+ rEventConnStatus.ucNetworkType = (UINT_8) PARAM_NETWORK_TYPE_OFDM24; -+ break; -+ -+ case PHY_TYPE_OFDM_INDEX: -+ rEventConnStatus.ucNetworkType = (UINT_8) PARAM_NETWORK_TYPE_OFDM5; -+ break; -+ -+ default: -+ ASSERT(0); -+ rEventConnStatus.ucNetworkType = (UINT_8) PARAM_NETWORK_TYPE_DS; -+ break; -+ } -+ } else { -+#if CFG_PRIVACY_MIGRATION -+ /* Clear the pmkid cache while media disconnect */ -+ secClearPmkid(prAdapter); -+#endif -+ -+ rEventConnStatus.ucReasonOfDisconnect = prBssInfo->ucReasonOfDisconnect; -+ -+ } -+ -+ /* 4 <2> Indication */ -+ nicMediaStateChange(prAdapter, NETWORK_TYPE_BOW_INDEX, &rEventConnStatus); -+ prBssInfo->eConnectionStateIndicated = eConnectionState; -+ } else { -+ /* NOTE: Only delay the Indication of Disconnect Event */ -+ ASSERT(eConnectionState == PARAM_MEDIA_STATE_DISCONNECTED); -+ -+ DBGLOG(BOW, INFO, "Postpone the indication of Disconnect for %d seconds\n", -+ prConnSettings->ucDelayTimeOfDisconnectEvent); -+ -+ cnmTimerStartTimer(prAdapter, -+ &prBowFsmInfo->rIndicationOfDisconnectTimer, -+ SEC_TO_MSEC(prConnSettings->ucDelayTimeOfDisconnectEvent)); -+ } -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will indicate the Event of Tx Fail of AAA Module. -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* @param[in] prStaRec Pointer to the STA_RECORD_T -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID bowRunEventAAATxFail(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec) -+{ -+ P_BSS_INFO_T prBssInfo; -+ -+ ASSERT(prAdapter); -+ ASSERT(prStaRec); -+ -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "bowRunEventAAATxFail , bssRemoveStaRecFromClientList.\n"); -+ DBGLOG(BOW, INFO, "BoW AAA TxFail, target state %d\n", prStaRec->ucStaState + 1); -+#endif -+ -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]); -+ bssRemoveStaRecFromClientList(prAdapter, prBssInfo, prStaRec); -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will indicate the Event of Successful Completion of AAA Module. -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* @param[in] prStaRec Pointer to the STA_RECORD_T -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS bowRunEventAAAComplete(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec) -+{ -+ P_BOW_FSM_INFO_T prBowFsmInfo; -+ -+ ASSERT(prStaRec); -+ -+ prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); -+ -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "bowRunEventAAAComplete, cnmStaRecChangeState, STA_STATE_3.\n"); -+ DBGLOG(BOW, INFO, "BoW AAA complete [%pM]\n", prStaRec->aucMacAddr); -+#endif -+ -+ /*Update BssInfo to connected */ -+ bowChangeMediaState(prAdapter, PARAM_MEDIA_STATE_CONNECTED); -+ nicUpdateBss(prAdapter, NETWORK_TYPE_BOW_INDEX); -+ -+ /*Update StaRec to State3 */ -+ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_3); -+ -+ /*Connected */ -+ wlanoidSendSetQueryBowCmd(prAdapter, -+ CMD_ID_CMD_BT_OVER_WIFI, -+ TRUE, FALSE, wlanbowCmdEventLinkConnected, wlanbowCmdTimeoutHandler, 0, NULL, 0); -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will handle RxDeauth -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* @param[in] prStaRec Pointer to the STA_RECORD_T -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+ -+WLAN_STATUS bowRunEventRxDeAuth(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN P_SW_RFB_T prSwRfb) -+{ -+ P_BSS_INFO_T prBowBssInfo; -+ P_BOW_FSM_INFO_T prBowFsmInfo; -+ ENUM_BOW_DEVICE_STATE eFsmState; -+ -+ ASSERT(prAdapter); -+ -+ prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); -+ prBowBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_BOW_INDEX]); -+ -+ if (!IS_STA_IN_BOW(prStaRec)) -+ return WLAN_STATUS_NOT_ACCEPTED; -+ -+ eFsmState = bowGetBowTableState(prAdapter, prStaRec->aucMacAddr); -+ -+ if (eFsmState == BOW_DEVICE_STATE_DISCONNECTED) { -+ /*do nothing */ -+ return WLAN_STATUS_NOT_ACCEPTED; -+ } -+ -+ if (prStaRec->ucStaState > STA_STATE_1) { -+ -+ if (STA_STATE_3 == prStaRec->ucStaState) { -+ /* P_MSG_AIS_ABORT_T prAisAbortMsg; */ -+ -+ /* NOTE(Kevin): Change state immediately to avoid starvation of -+ * MSG buffer because of too many deauth frames before changing -+ * the STA state. -+ */ -+ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); -+ } -+ -+ COPY_MAC_ADDR(prBowFsmInfo->aucPeerAddress, prStaRec->aucMacAddr); -+ -+ wlanoidSendSetQueryBowCmd(prAdapter, -+ CMD_ID_CMD_BT_OVER_WIFI, -+ TRUE, -+ FALSE, wlanbowCmdEventLinkDisconnected, wlanbowCmdTimeoutHandler, 0, NULL, 0); -+ -+ return WLAN_STATUS_SUCCESS; -+ } -+ -+ return WLAN_STATUS_NOT_ACCEPTED; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function handle BoW Link disconnect. -+* -+* \param[in] pMsduInfo Pointer to the Msdu Info -+* \param[in] rStatus The Tx done status -+* -+* \return - -+* -+* \note after receive deauth frame, callback function call this -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID bowDisconnectLink(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus) -+{ -+ P_BOW_FSM_INFO_T prBowFsmInfo; -+ P_STA_RECORD_T prStaRec; -+ -+ ASSERT(prAdapter); -+ -+ prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); -+ -+ /*Free target StaRec */ -+ if (prMsduInfo) -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); -+ else -+ prStaRec = prBowFsmInfo->prTargetStaRec; -+ -+ if (prStaRec) -+ /* cnmStaRecFree(prAdapter, prStaRec, TRUE); */ -+ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); -+ kalPrint("bowDisconnectLink\n"); -+ /*No one connected */ -+ if (g_u4LinkCount == 0 && g_u4Beaconing != 0) { -+ cnmTimerStopTimer(prAdapter, &prBowFsmInfo->rStartingBeaconTimer); -+ bowStopping(prAdapter); -+ kalPrint("bowStopping\n"); -+ /*Restore TxPower from Short range mode */ -+#if CFG_SUPPORT_NVRAM && 0 -+ wlanLoadManufactureData(prAdapter, kalGetConfiguration(prAdapter->prGlueInfo)); -+#endif -+ /*Uninit BoW Interface */ -+#if CFG_BOW_SEPARATE_DATA_PATH -+ kalUninitBowDevice(prAdapter->prGlueInfo); -+#endif -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will validate the Rx Assoc Req Frame and then return -+* the status code to AAA to indicate if need to perform following actions -+* when the specified conditions were matched. -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* @param[in] prSwRfb Pointer to SW RFB data structure. -+* @param[out] pu2StatusCode The Status Code of Validation Result -+* -+* @retval TRUE Reply the Assoc Resp -+* @retval FALSE Don't reply the Assoc Resp -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN bowValidateAssocReq(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, OUT PUINT_16 pu2StatusCode) -+{ -+ BOOLEAN fgReplyAssocResp = FALSE; -+ P_BSS_INFO_T prBowBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_BOW_INDEX]); -+ P_STA_RECORD_T prStaRec = (P_STA_RECORD_T) NULL; -+ P_BOW_FSM_INFO_T prBowFsmInfo; -+ P_WLAN_ASSOC_REQ_FRAME_T prAssocReqFrame = (P_WLAN_ASSOC_REQ_FRAME_T) NULL; -+ OS_SYSTIME rCurrentTime; -+ static OS_SYSTIME rLastRejectAssocTime; -+ -+ ASSERT(prAdapter); -+ -+ prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); -+ prAssocReqFrame = (P_WLAN_ASSOC_REQ_FRAME_T) prSwRfb->pvHeader; -+ *pu2StatusCode = STATUS_CODE_REQ_DECLINED; -+ -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "bowValidateAssocReq, prBowFsmInfo->aucPeerAddress, %x:%x:%x:%x:%x:%x.\n", -+ prBowFsmInfo->aucPeerAddress[0], -+ prBowFsmInfo->aucPeerAddress[1], -+ prBowFsmInfo->aucPeerAddress[2], -+ prBowFsmInfo->aucPeerAddress[3], -+ prBowFsmInfo->aucPeerAddress[4], prBowFsmInfo->aucPeerAddress[5])); -+ DBGLOG(BOW, EVENT, "bowValidateAssocReq, prAssocReqFrame->aucSrcAddr, %x:%x:%x:%x:%x:%x.\n", -+ prAssocReqFrame->aucSrcAddr[0], -+ prAssocReqFrame->aucSrcAddr[1], -+ prAssocReqFrame->aucSrcAddr[2], -+ prAssocReqFrame->aucSrcAddr[3], -+ prAssocReqFrame->aucSrcAddr[4], prAssocReqFrame->aucSrcAddr[5])); -+#endif -+ -+ /*Assoc Accept */ -+ while (EQUAL_MAC_ADDR(prAssocReqFrame->aucSrcAddr, prBowFsmInfo->aucPeerAddress)) { -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "bowValidateAssocReq, return wlanbowCmdEventLinkConnected.\n"); -+#endif -+ /*Update StaRec */ -+ prStaRec = cnmGetStaRecByAddress(prAdapter, -+ (UINT_8) NETWORK_TYPE_BOW_INDEX, prAssocReqFrame->aucSrcAddr); -+ if (!prStaRec) -+ break; -+ prStaRec->eStaType = STA_TYPE_BOW_CLIENT; -+ prStaRec->u2DesiredNonHTRateSet &= prBowBssInfo->u2OperationalRateSet; -+ prStaRec->ucDesiredPhyTypeSet = prStaRec->ucPhyTypeSet & prBowBssInfo->ucPhyTypeSet; -+ -+#if CFG_BOW_RATE_LIMITATION -+ /*Limit Rate Set to 24M, 48M, 54M */ -+ prStaRec->u2DesiredNonHTRateSet &= (RATE_SET_BIT_24M | RATE_SET_BIT_48M | RATE_SET_BIT_54M); -+ /*If peer cannot support the above rate set, fix on the available highest rate */ -+ if (prStaRec->u2DesiredNonHTRateSet == 0) { -+ UINT_8 ucHighestRateIndex; -+ -+ if (rateGetHighestRateIndexFromRateSet(prBowBssInfo->u2OperationalRateSet, &ucHighestRateIndex)) -+ prStaRec->u2DesiredNonHTRateSet = BIT(ucHighestRateIndex); -+ else { -+ /*If no available rate is found, DECLINE the association */ -+ *pu2StatusCode = STATUS_CODE_ASSOC_DENIED_RATE_NOT_SUPPORTED; -+ break; -+ } -+ } -+#endif -+ prStaRec->ucNetTypeIndex = NETWORK_TYPE_BOW_INDEX; -+ -+ /*Undpate BssInfo to FW */ -+ bowChangeMediaState(prAdapter, PARAM_MEDIA_STATE_CONNECTED); -+ nicUpdateBss(prAdapter, NETWORK_TYPE_BOW_INDEX); -+ -+ /*reply successful */ -+ *pu2StatusCode = STATUS_CODE_SUCCESSFUL; -+ fgReplyAssocResp = TRUE; -+ break; -+ } -+ -+ /*Reject Assoc */ -+ if (*pu2StatusCode != STATUS_CODE_SUCCESSFUL) { -+ /*Reply Assoc with reject every 5s */ -+ rCurrentTime = kalGetTimeTick(); -+ if (CHECK_FOR_TIMEOUT(rCurrentTime, rLastRejectAssocTime, MSEC_TO_SYSTIME(5000)) || -+ rLastRejectAssocTime == 0) { -+ fgReplyAssocResp = TRUE; -+ rLastRejectAssocTime = rCurrentTime; -+ } -+ } -+ -+ return fgReplyAssocResp; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will validate the Rx Auth Frame and then return -+* the status code to AAA to indicate if need to perform following actions -+* when the specified conditions were matched. -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* @param[in] prSwRfb Pointer to SW RFB data structure. -+* @param[in] pprStaRec Pointer to pointer of STA_RECORD_T structure. -+* @param[out] pu2StatusCode The Status Code of Validation Result -+* -+* @retval TRUE Reply the Auth -+* @retval FALSE Don't reply the Auth -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN -+bowValidateAuth(IN P_ADAPTER_T prAdapter, -+ IN P_SW_RFB_T prSwRfb, IN PP_STA_RECORD_T pprStaRec, OUT PUINT_16 pu2StatusCode) -+{ -+ BOOLEAN fgReplyAuth = FALSE; -+ P_BSS_INFO_T prBowBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_BOW_INDEX]); -+ P_STA_RECORD_T prStaRec = (P_STA_RECORD_T) NULL; -+ P_BOW_FSM_INFO_T prBowFsmInfo; -+ P_WLAN_AUTH_FRAME_T prAuthFrame = (P_WLAN_AUTH_FRAME_T) NULL; -+ OS_SYSTIME rCurrentTime; -+ static OS_SYSTIME rLastRejectAuthTime; -+ -+ /* TODO(Kevin): Call BoW functions to check .. -+ 1. Check we are BoW now. -+ 2. Check we can accept connection from thsi peer -+ 3. Check Black List here. -+ */ -+ -+ prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); -+ prAuthFrame = (P_WLAN_AUTH_FRAME_T) prSwRfb->pvHeader; -+ -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "bowValidateAuth, prBowFsmInfo->aucPeerAddress, %x:%x:%x:%x:%x:%x.\n", -+ prBowFsmInfo->aucPeerAddress[0], -+ prBowFsmInfo->aucPeerAddress[1], -+ prBowFsmInfo->aucPeerAddress[2], -+ prBowFsmInfo->aucPeerAddress[3], -+ prBowFsmInfo->aucPeerAddress[4], prBowFsmInfo->aucPeerAddress[5])); -+ DBGLOG(BOW, EVENT, "bowValidateAuth, prAuthFrame->aucSrcAddr, %x:%x:%x:%x:%x:%x.\n", -+ prAuthFrame->aucSrcAddr[0], -+ prAuthFrame->aucSrcAddr[1], -+ prAuthFrame->aucSrcAddr[2], -+ prAuthFrame->aucSrcAddr[3], prAuthFrame->aucSrcAddr[4], prAuthFrame->aucSrcAddr[5])); -+#endif -+ -+ prStaRec = cnmGetStaRecByAddress(prAdapter, (UINT_8) NETWORK_TYPE_BOW_INDEX, prAuthFrame->aucSrcAddr); -+ if (!prStaRec) { -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "bowValidateAuth, cnmStaRecAlloc.\n"); -+#endif -+ prStaRec = cnmStaRecAlloc(prAdapter, (UINT_8) NETWORK_TYPE_BOW_INDEX); -+ -+ /* TODO(Kevin): Error handling of allocation of STA_RECORD_T for -+ * exhausted case and do removal of unused STA_RECORD_T. -+ */ -+ if (!prStaRec) -+ return fgReplyAuth; -+ COPY_MAC_ADDR(prStaRec->aucMacAddr, prAuthFrame->aucSrcAddr); -+ prSwRfb->ucStaRecIdx = prStaRec->ucIndex; -+ prBowBssInfo->prStaRecOfAP = prStaRec; -+ -+ /* NOTE(Kevin): Better to change state here, not at TX Done */ -+ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "bowValidateAuth, cnmStaRecChangeState.\n"); -+#endif -+ } else { -+ prSwRfb->ucStaRecIdx = prStaRec->ucIndex; -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "bowValidateAuth, prStaRec->ucIndex, %x.\n", prStaRec->ucIndex); -+#endif -+ bssRemoveStaRecFromClientList(prAdapter, prBowBssInfo, prStaRec); -+ } -+ -+ if (EQUAL_MAC_ADDR(prAuthFrame->aucSrcAddr, prBowFsmInfo->aucPeerAddress)) { -+ -+ prStaRec->eStaType = STA_TYPE_BOW_CLIENT; -+ prStaRec->ucNetTypeIndex = NETWORK_TYPE_BOW_INDEX; -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "bowValidateAuth, prStaRec->eStaType, %x.\n", prStaRec->eStaType); -+ DBGLOG(BOW, EVENT, "bowValidateAuth, prStaRec->ucNetTypeIndex, %x.\n", prStaRec->ucNetTypeIndex); -+#endif -+ /* Update Station Record - Status/Reason Code */ -+ prStaRec->u2StatusCode = STATUS_CODE_SUCCESSFUL; -+ prStaRec->ucJoinFailureCount = 0; -+ *pprStaRec = prStaRec; -+ *pu2StatusCode = STATUS_CODE_SUCCESSFUL; -+ fgReplyAuth = TRUE; -+ } else { -+ cnmStaRecFree(prAdapter, prStaRec, FALSE); -+ *pu2StatusCode = STATUS_CODE_REQ_DECLINED; -+ -+ /*Reply auth with reject every 5s */ -+ rCurrentTime = kalGetTimeTick(); -+ if (CHECK_FOR_TIMEOUT(rCurrentTime, rLastRejectAuthTime, MSEC_TO_SYSTIME(5000)) || -+ rLastRejectAuthTime == 0) { -+ fgReplyAuth = TRUE; -+ rLastRejectAuthTime = rCurrentTime; -+ } -+ } -+ -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "bowValidateAuth, fgReplyAuth, %x.\n", fgReplyAuth); -+#endif -+ return fgReplyAuth; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is invoked when CNM granted channel privilege -+* -+* \param[in] prAdapter Pointer of ADAPTER_T -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID bowRunEventChGrant(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) -+{ -+ P_BSS_INFO_T prBowBssInfo; -+ P_BOW_FSM_INFO_T prBowFsmInfo; -+ P_MSG_CH_GRANT_T prMsgChGrant; -+ UINT_8 ucTokenID; -+ UINT_32 u4GrantInterval; -+ ENUM_BOW_DEVICE_STATE eFsmState; -+ -+ ASSERT(prAdapter); -+ ASSERT(prMsgHdr); -+ -+ prBowBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_BOW_INDEX]); -+ prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); -+ prMsgChGrant = (P_MSG_CH_GRANT_T) prMsgHdr; -+ ucTokenID = prMsgChGrant->ucTokenID; -+ u4GrantInterval = prMsgChGrant->u4GrantInterval; -+ -+ /* 1. free message */ -+ cnmMemFree(prAdapter, prMsgHdr); -+ prBowFsmInfo->fgIsChannelGranted = TRUE; -+ -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "Entering bowRunEventChGrant.\n"); -+#endif -+ -+ eFsmState = bowGetBowTableState(prAdapter, prBowFsmInfo->aucPeerAddress); -+ -+ /*Release channel */ -+ if ((!prBowFsmInfo->fgIsChannelRequested) || -+ (prBowFsmInfo->ucSeqNumOfChReq != ucTokenID) || -+ (eFsmState == BOW_DEVICE_STATE_DISCONNECTED) || (eFsmState == BOW_DEVICE_STATE_DISCONNECTING)) { -+#if CFG_BOW_TEST -+ DBGLOG(BOW, INFO, "BoW Channel [GIVE UP:%d]\n", ucTokenID); -+ DBGLOG(BOW, INFO, "[Requested:%d][ucSeqNumOfChReq:%d][eFsmState:%d]\n", -+ prBowFsmInfo->fgIsChannelRequested, prBowFsmInfo->ucSeqNumOfChReq, eFsmState); -+#endif -+ bowReleaseCh(prAdapter); -+ return; -+ } -+ -+ /* 2. channel privilege has been approved */ -+ prBowFsmInfo->u4ChGrantedInterval = u4GrantInterval; -+ -+#if 0 -+ cnmTimerStartTimer(prAdapter, -+ &prBowFsmInfo->rChGrantedTimer, -+ prBowFsmInfo->u4ChGrantedInterval - BOW_JOIN_CH_GRANT_THRESHOLD); -+#else -+ cnmTimerStartTimer(prAdapter, -+ &prBowFsmInfo->rChGrantedTimer, BOW_JOIN_CH_REQUEST_INTERVAL - BOW_JOIN_CH_GRANT_THRESHOLD); -+#endif -+ -+ /* 3.2 set local variable to indicate join timer is ticking */ -+ prBowFsmInfo->fgIsInfraChannelFinished = FALSE; -+ -+#if CFG_BOW_TEST -+ DBGLOG(BOW, INFO, "BoW Channel [GRANTED:%d].\n", ucTokenID); -+#endif -+ -+ if (eFsmState == BOW_DEVICE_STATE_ACQUIRING_CHANNEL) { -+ bowStarting(prAdapter); -+ bowReleaseCh(prAdapter); -+ if (prBowFsmInfo->ucRole == BOW_RESPONDER) -+ bowResponderJoin(prAdapter, prBowFsmInfo->prTargetBssDesc); -+ } else { -+ /*update bssinfo */ -+ nicUpdateBss(prAdapter, NETWORK_TYPE_BOW_INDEX); -+ bowReleaseCh(prAdapter); -+ } -+ -+} /* end of aisFsmRunEventChGrant() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is to inform CNM for channel privilege requesting -+* has been released -+* -+* \param[in] prAdapter Pointer of ADAPTER_T -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID bowRequestCh(IN P_ADAPTER_T prAdapter) -+{ -+ P_BOW_FSM_INFO_T prBowFsmInfo; -+ P_MSG_CH_REQ_T prMsgChReq; -+ -+ ASSERT(prAdapter); -+ -+ prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); -+ -+ if (prBowFsmInfo->fgIsChannelGranted == FALSE) { -+ -+#if CFG_BOW_TEST -+ DBGLOG(BOW, INFO, "BoW channel [REQUEST:%d], %d, %d.\n", prBowFsmInfo->ucSeqNumOfChReq + 1, -+ prBowFsmInfo->ucPrimaryChannel, prBowFsmInfo->eBand); -+#endif -+ prMsgChReq = (P_MSG_CH_REQ_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_CH_REQ_T)); -+ -+ if (!prMsgChReq) { -+ ASSERT(0); /* Can't indicate CNM for channel acquiring */ -+ return; -+ } -+ -+ prMsgChReq->rMsgHdr.eMsgId = MID_MNY_CNM_CH_REQ; -+ prMsgChReq->ucNetTypeIndex = NETWORK_TYPE_BOW_INDEX; -+ prMsgChReq->ucTokenID = ++prBowFsmInfo->ucSeqNumOfChReq; -+ prMsgChReq->eReqType = CH_REQ_TYPE_JOIN; -+#if 0 -+ prMsgChReq->u4MaxInterval = BOW_JOIN_CH_REQUEST_INTERVAL; -+#else -+ prMsgChReq->u4MaxInterval = 1; -+#endif -+ /* prBowFsmInfo->prTargetBssDesc->ucChannelNum; */ -+ prMsgChReq->ucPrimaryChannel = prBowFsmInfo->ucPrimaryChannel; -+ /* prBowFsmInfo->prTargetBssDesc->eSco; */ -+ prMsgChReq->eRfSco = CHNL_EXT_SCN; -+ /* prBowFsmInfo->prTargetBssDesc->eBand; */ -+ prMsgChReq->eRfBand = prBowFsmInfo->eBand; -+ COPY_MAC_ADDR(prMsgChReq->aucBSSID, prBowFsmInfo->aucPeerAddress); -+ -+ prBowFsmInfo->fgIsChannelRequested = TRUE; -+ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgChReq, MSG_SEND_METHOD_BUF); -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is to inform BOW that channel privilege is granted -+* has been released -+* -+* \param[in] prAdapter Pointer of ADAPTER_T -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID bowReleaseCh(IN P_ADAPTER_T prAdapter) -+{ -+ P_BOW_FSM_INFO_T prBowFsmInfo; -+ P_MSG_CH_ABORT_T prMsgChAbort; -+ -+ ASSERT(prAdapter); -+ -+ prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); -+ -+ if (prBowFsmInfo->fgIsChannelGranted != FALSE || prBowFsmInfo->fgIsChannelRequested != FALSE) { -+#if CFG_BOW_TEST -+ DBGLOG(BOW, INFO, "BoW channel [RELEASE:%d] %d, %d.\n", prBowFsmInfo->ucSeqNumOfChReq, -+ prBowFsmInfo->ucPrimaryChannel, prBowFsmInfo->eBand); -+#endif -+ -+ prBowFsmInfo->fgIsChannelRequested = FALSE; -+ prBowFsmInfo->fgIsChannelGranted = FALSE; -+ -+ /* 1. return channel privilege to CNM immediately */ -+ prMsgChAbort = (P_MSG_CH_ABORT_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_CH_ABORT_T)); -+ if (!prMsgChAbort) { -+ ASSERT(0); /* Can't release Channel to CNM */ -+ return; -+ } -+ -+ prMsgChAbort->rMsgHdr.eMsgId = MID_MNY_CNM_CH_ABORT; -+ prMsgChAbort->ucNetTypeIndex = NETWORK_TYPE_BOW_INDEX; -+ prMsgChAbort->ucTokenID = prBowFsmInfo->ucSeqNumOfChReq; -+ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgChAbort, MSG_SEND_METHOD_BUF); -+ } -+ -+} /* end of aisFsmReleaseCh() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will indicate an Event of "Media Disconnect" to HOST -+* -+* @param[in] u4Param Unused timer parameter -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID bowChGrantedTimeout(IN P_ADAPTER_T prAdapter, IN ULONG ulParam) -+{ -+ P_BOW_FSM_INFO_T prBowFsmInfo; -+ ENUM_BOW_DEVICE_STATE eFsmState; -+ -+ ASSERT(prAdapter); -+ -+ prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); -+ -+#if CFG_BOW_TEST -+ DBGLOG(BOW, INFO, "BoW Channel [TIMEOUT]\n"); -+#endif -+#if 1 -+ /* bowReleaseCh(prAdapter); */ -+ eFsmState = bowGetBowTableState(prAdapter, prBowFsmInfo->aucPeerAddress); -+ -+ /*If connecting is not completed, request CH again */ -+ if ((eFsmState == BOW_DEVICE_STATE_CONNECTING) || (eFsmState == BOW_DEVICE_STATE_STARTING)) -+ bowRequestCh(prAdapter); -+#endif -+} -+ -+BOOLEAN bowNotifyAllLinkDisconnected(IN P_ADAPTER_T prAdapter) -+{ -+ UINT_8 ucBowTableIdx = 0; -+ CMD_INFO_T rCmdInfo; -+ -+ ASSERT(prAdapter); -+ -+ kalMemZero(&rCmdInfo, sizeof(CMD_INFO_T)); -+ -+ while (ucBowTableIdx < CFG_BOW_PHYSICAL_LINK_NUM) { -+ if (arBowTable[ucBowTableIdx].fgIsValid) { -+ COPY_MAC_ADDR(prAdapter->rWifiVar.rBowFsmInfo.aucPeerAddress, -+ arBowTable[ucBowTableIdx].aucPeerAddress); -+ -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, -+ "bowNotifyAllLinkDisconnected, arBowTable[%x].aucPeerAddress, %x:%x:%x:%x:%x:%x.\n", -+ ucBowTableIdx, arBowTable[ucBowTableIdx].aucPeerAddress[0], -+ arBowTable[ucBowTableIdx].aucPeerAddress[1], -+ arBowTable[ucBowTableIdx].aucPeerAddress[2], -+ arBowTable[ucBowTableIdx].aucPeerAddress[3], -+ arBowTable[ucBowTableIdx].aucPeerAddress[4], -+ arBowTable[ucBowTableIdx].aucPeerAddress[5])); -+ DBGLOG(BOW, EVENT, -+ "bowNotifyAllLinkDisconnected, arBowTable[%x].fgIsValid, %x.\n", ucBowTableIdx, -+ arBowTable[ucBowTableIdx].fgIsValid); -+#endif -+#if 1 -+ wlanoidSendSetQueryBowCmd(prAdapter, -+ CMD_ID_CMD_BT_OVER_WIFI, -+ TRUE, -+ FALSE, -+ wlanbowCmdEventLinkDisconnected, -+ wlanbowCmdTimeoutHandler, 0, NULL, 0); -+#else -+ wlanbowCmdEventLinkDisconnected(prAdapter, &rCmdInfo, NULL); -+#endif -+ } -+ -+ ucBowTableIdx += 1; -+ } -+ -+ return TRUE; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief to retrieve Bluetooth-over-Wi-Fi state from glue layer -+* -+* \param[in] -+* prGlueInfo -+* rPeerAddr -+* \return -+* ENUM_BOW_DEVICE_STATE -+*/ -+/*----------------------------------------------------------------------------*/ -+ -+BOOLEAN bowCheckBowTableIfVaild(IN P_ADAPTER_T prAdapter, IN UINT_8 aucPeerAddress[6]) -+{ -+ UINT_8 idx; -+ -+ KAL_SPIN_LOCK_DECLARATION(); -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_BOW_TABLE); -+ -+ for (idx = 0; idx < CFG_BOW_PHYSICAL_LINK_NUM; idx++) { -+ if (arBowTable[idx].fgIsValid && EQUAL_MAC_ADDR(arBowTable[idx].aucPeerAddress, aucPeerAddress)) { -+ -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "kalCheckBowifVaild, aucPeerAddress %x, %x:%x:%x:%x:%x:%x.\n", idx, -+ aucPeerAddress[0], -+ aucPeerAddress[1], -+ aucPeerAddress[2], -+ aucPeerAddress[3], aucPeerAddress[4], aucPeerAddress[5])); -+ -+ DBGLOG(BOW, EVENT, -+ "kalCheckBowifVaild, arBowTable[idx].aucPeerAddress %x, %x:%x:%x:%x:%x:%x.\n", idx, -+ arBowTable[idx].aucPeerAddress[0], arBowTable[idx].aucPeerAddress[1], -+ arBowTable[idx].aucPeerAddress[2], arBowTable[idx].aucPeerAddress[3], -+ arBowTable[idx].aucPeerAddress[4], arBowTable[idx].aucPeerAddress[5])); -+ -+ DBGLOG(BOW, EVENT, -+ "kalCheckBowifVaild, arBowTable[idx].fgIsValid, %x, %x.\n", idx, -+ arBowTable[idx].fgIsValid); -+ -+#endif -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_BOW_TABLE); -+ return TRUE; -+ } -+ } -+ -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_BOW_TABLE); -+ return FALSE; -+} -+ -+BOOLEAN bowGetBowTableContent(IN P_ADAPTER_T prAdapter, IN UINT_8 ucBowTableIdx, OUT P_BOW_TABLE_T prBowTable) -+{ -+ KAL_SPIN_LOCK_DECLARATION(); -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_BOW_TABLE); -+ -+ if (arBowTable[ucBowTableIdx].fgIsValid) { -+ -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, -+ "bowGetBowTableContent, arBowTable[idx].fgIsValid, %x, %x.\n", ucBowTableIdx, -+ arBowTable[ucBowTableIdx].fgIsValid); -+ DBGLOG(BOW, INFO, "GET State [%d]\n", arBowTable[ucBowTableIdx].eState); -+#endif -+ prBowTable = &(arBowTable[ucBowTableIdx]); -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_BOW_TABLE); -+ -+ return TRUE; -+ } -+ -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_BOW_TABLE); -+ -+ return FALSE; -+} -+ -+BOOLEAN bowSetBowTableContent(IN P_ADAPTER_T prAdapter, IN UINT_8 ucBowTableIdx, IN P_BOW_TABLE_T prBowTable) -+{ -+ KAL_SPIN_LOCK_DECLARATION(); -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_BOW_TABLE); -+ -+ COPY_MAC_ADDR(arBowTable[ucBowTableIdx].aucPeerAddress, prBowTable->aucPeerAddress); -+ arBowTable[ucBowTableIdx].eState = prBowTable->eState; -+ arBowTable[ucBowTableIdx].fgIsValid = prBowTable->fgIsValid; -+ arBowTable[ucBowTableIdx].ucAcquireID = prBowTable->ucAcquireID; -+ -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_BOW_TABLE); -+ -+ kalSetBowState(prAdapter->prGlueInfo, prBowTable->eState, prBowTable->aucPeerAddress); -+ /* kalSetBowRole(prAdapter->prGlueInfo, prBowTable->ucRole, prBowTable->aucPeerAddress); */ -+ -+#if CFG_BOW_TEST -+ DBGLOG(BOW, INFO, "SET State [%d]\n", arBowTable[ucBowTableIdx].eState); -+ DBGLOG(BOW, EVENT, -+ "kalCheckBowifVaild, arBowTable[ucBowTableIdx].fgIsValid, %x, %x.\n", ucBowTableIdx, -+ arBowTable[ucBowTableIdx].fgIsValid); -+#endif -+ -+ return TRUE; -+ -+} -+ -+BOOLEAN -+bowGetBowTableEntryByPeerAddress(IN P_ADAPTER_T prAdapter, IN UINT_8 aucPeerAddress[6], OUT PUINT_8 pucBowTableIdx) -+{ -+ UINT_8 idx; -+ -+ KAL_SPIN_LOCK_DECLARATION(); -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_BOW_TABLE); -+ -+ for (idx = 0; idx < CFG_BOW_PHYSICAL_LINK_NUM; idx++) { -+ if (arBowTable[idx].fgIsValid && EQUAL_MAC_ADDR(arBowTable[idx].aucPeerAddress, aucPeerAddress)) { -+ -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "kalCheckBowifVaild, aucPeerAddress %x, %x:%x:%x:%x:%x:%x.\n", idx, -+ aucPeerAddress[0], -+ aucPeerAddress[1], -+ aucPeerAddress[2], -+ aucPeerAddress[3], aucPeerAddress[4], aucPeerAddress[5])); -+ DBGLOG(BOW, EVENT, -+ "kalCheckBowifVaild, arBowTable[idx].aucPeerAddress %x, %x:%x:%x:%x:%x:%x.\n", idx, -+ arBowTable[idx].aucPeerAddress[0], arBowTable[idx].aucPeerAddress[1], -+ arBowTable[idx].aucPeerAddress[2], arBowTable[idx].aucPeerAddress[3], -+ arBowTable[idx].aucPeerAddress[4], arBowTable[idx].aucPeerAddress[5])); -+ DBGLOG(BOW, EVENT, -+ "kalCheckBowifVaild, arBowTable[idx].fgIsValid, %x, %x.\n", idx, -+ arBowTable[idx].fgIsValid); -+#endif -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_BOW_TABLE); -+ -+ *pucBowTableIdx = idx; -+ -+ return TRUE; -+ } -+ } -+ -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_BOW_TABLE); -+ -+ return FALSE; -+} -+ -+BOOLEAN bowGetBowTableFreeEntry(IN P_ADAPTER_T prAdapter, OUT PUINT_8 pucBowTableIdx) -+{ -+ UINT_8 idx; -+ -+ KAL_SPIN_LOCK_DECLARATION(); -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_BOW_TABLE); -+ -+ for (idx = 0; idx < CFG_BOW_PHYSICAL_LINK_NUM; idx++) { -+ if (!arBowTable[idx].fgIsValid) { -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, -+ "bowGetBowTableFreeEntry, arBowTable[idx].fgIsValid, %x, %x.\n", idx, -+ arBowTable[idx].fgIsValid); -+#endif -+ *pucBowTableIdx = idx; -+ arBowTable[idx].fgIsValid = TRUE; -+ -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_BOW_TABLE); -+ -+ return TRUE; -+ } -+ } -+ -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_BOW_TABLE); -+ -+ return FALSE; -+} -+ -+ENUM_BOW_DEVICE_STATE bowGetBowTableState(IN P_ADAPTER_T prAdapter, IN UINT_8 aucPeerAddress[6]) -+{ -+ UINT_8 idx; -+ -+ KAL_SPIN_LOCK_DECLARATION(); -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_BOW_TABLE); -+ -+ for (idx = 0; idx < CFG_BOW_PHYSICAL_LINK_NUM; idx++) { -+ if (arBowTable[idx].fgIsValid && EQUAL_MAC_ADDR(arBowTable[idx].aucPeerAddress, aucPeerAddress)) { -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "bowGetState, aucPeerAddress %x, %x:%x:%x:%x:%x:%x.\n", idx, -+ aucPeerAddress[0], -+ aucPeerAddress[1], -+ aucPeerAddress[2], -+ aucPeerAddress[3], aucPeerAddress[4], aucPeerAddress[5])); -+ DBGLOG(BOW, EVENT, "bowGetState, arBowTable[idx].aucPeerAddress %x, %x:%x:%x:%x:%x:%x.\n", idx, -+ arBowTable[idx].aucPeerAddress[0], -+ arBowTable[idx].aucPeerAddress[1], -+ arBowTable[idx].aucPeerAddress[2], -+ arBowTable[idx].aucPeerAddress[3], -+ arBowTable[idx].aucPeerAddress[4], arBowTable[idx].aucPeerAddress[5])); -+ DBGLOG(BOW, EVENT, -+ "bowGetState, arBowTable[idx].fgIsValid, %x, %x.\n", idx, arBowTable[idx].fgIsValid); -+ DBGLOG(BOW, EVENT, -+ "bowGetState, arBowTable[idx].eState;, %x, %x.\n", idx, arBowTable[idx].eState); -+ DBGLOG(BOW, INFO, "GET State [%d]\n", arBowTable[idx].eState); -+#endif -+ -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_BOW_TABLE); -+ -+ return arBowTable[idx].eState; -+ } -+ } -+ -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_BOW_TABLE); -+ -+ return BOW_DEVICE_STATE_DISCONNECTED; -+} -+ -+BOOLEAN bowSetBowTableState(IN P_ADAPTER_T prAdapter, IN UINT_8 aucPeerAddress[6], IN ENUM_BOW_DEVICE_STATE eState) -+{ -+ UINT_8 ucBowTableIdx; -+ -+ if (bowGetBowTableEntryByPeerAddress(prAdapter, aucPeerAddress, &ucBowTableIdx)) { -+ KAL_SPIN_LOCK_DECLARATION(); -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_BOW_TABLE); -+ -+ arBowTable[ucBowTableIdx].eState = eState; -+#if CFG_BOW_TEST -+ DBGLOG(BOW, INFO, "SET State [%d]\n", eState); -+#endif -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_BOW_TABLE); -+ -+ kalSetBowState(prAdapter->prGlueInfo, eState, aucPeerAddress); -+ return TRUE; -+ } -+ return FALSE; -+} -+ -+#endif -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/common/wlan_lib.c b/drivers/misc/mediatek/connectivity/wlan/gen2/common/wlan_lib.c -new file mode 100644 -index 000000000000..1c59f861047e ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/common/wlan_lib.c -@@ -0,0 +1,6240 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/common/wlan_lib.c#2 -+*/ -+/*! \file wlan_lib.c -+ \brief Internal driver stack will export the required procedures here for GLUE Layer. -+ -+ This file contains all routines which are exported from MediaTek 802.11 Wireless -+ LAN driver stack to GLUE Layer. -+*/ -+ -+/* -+** Log: wlan_lib.c -+** -+** 08 15 2012 eason.tsai -+** [ALPS00338170] [Need Patch] [Volunteer Patch] modify build warning -+** fix build waring for codechange -+ * -+ * 07 13 2012 cp.wu -+ * [WCXRP00001259] [MT6620 Wi-Fi][Driver][Firmware] Send a signal to firmware for termination -+ * after SDIO error has happened -+ * [driver domain] add force reset by host-to-device interrupt mechanism -+ * -+ * 06 11 2012 cp.wu -+ * [WCXRP00001252] [MT6620 Wi-Fi][Driver] Add debug message while encountering firmware response timeout -+ * output message while timeout event occurs -+ * -+ * 06 11 2012 eason.tsai -+ * NULL -+ * change from binay to hex code -+ * -+ * 06 08 2012 eason.tsai -+ * NULL -+ * Nvram context covert from 6620 to 6628 for old 6620 meta tool -+ * -+ * 05 11 2012 cp.wu -+ * [WCXRP00001237] [MT6620 Wi-Fi][Driver] Show MAC address and MAC address source for ACS's convenience -+ * show MAC address & source while initiliazation -+ * -+ * 03 29 2012 eason.tsai -+ * [WCXRP00001216] [MT6628 Wi-Fi][Driver]add conditional define -+ * add conditional define. -+ * -+ * 03 04 2012 eason.tsai -+ * NULL -+ * modify the cal fail report code. -+ * -+ * 03 02 2012 terry.wu -+ * NULL -+ * Sync CFG80211 modification from branch 2,2. -+ * -+ * 01 16 2012 cp.wu -+ * [WCXRP00001169] [MT6620 Wi-Fi][Driver] API and behavior modification for preferred band -+ * configuration with corresponding network configuration correct scan result removing policy. -+ * -+ * 01 16 2012 cp.wu -+ * [MT6620 Wi-Fi][Driver] API and behavior modification for preferred band configuration with -+ * corresponding network configuration add wlanSetPreferBandByNetwork() for glue layer to invoke -+ * for setting preferred band configuration corresponding to network type. -+ * -+ * 01 05 2012 wh.su -+ * [WCXRP00001153] [MT6620 Wi-Fi][Driver] Adding the get_ch_list and set_tx_power proto type function -+ * Adding the related ioctl / wlan oid function to set the Tx power cfg. -+ * -+ * 11 28 2011 cp.wu -+ * [WCXRP00001125] [MT6620 Wi-Fi][Firmware] Strengthen Wi-Fi power off sequence to have a clearroom environment -+ * when returining to ROM code -+ * 1. Due to firmware now stops HIF DMA for powering off, do not try to receive any packet from firmware -+ * 2. Take use of prAdapter->fgIsEnterD3ReqIssued for tracking whether it is powering off or not -+ * -+ * 11 14 2011 cm.chang -+ * [WCXRP00001104] [All Wi-Fi][FW] Show init process by HW mail-box register -+ * Show FW initial ID when timeout to wait for ready bit -+ * -+ * 11 11 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * modify the xlog related code. -+ * -+ * 10 18 2011 cp.wu -+ * [WCXRP00001022] [MT6628 Driver][Firmware Download] Add multi section independent download functionality -+ * when powering off, always clear pending interrupts, then wait for RDY to be de-asserted -+ * -+ * 10 14 2011 cp.wu -+ * [WCXRP00001022] [MT6628 Driver][Firmware Download] Add multi section independent download functionality -+ * shorten the packet length for firmware download if no more than 2048 bytes. -+ * -+ * 10 03 2011 cp.wu -+ * [WCXRP00001022] [MT6628 Driver][Firmware Download] Add multi section independent download functionality -+ * add firmware download path in divided scatters. -+ * -+ * 10 03 2011 cp.wu -+ * [MT6628 Driver][Firmware Download] Add multi section independent download functionality -+ * add firmware downloading aggregated path. -+ * -+ * 09 30 2011 cm.chang -+ * [WCXRP00001020] [MT6620 Wi-Fi][Driver] Handle secondary channel offset of AP in 5GHz band -+ * . -+ * -+ * 09 20 2011 cp.wu -+ * [WCXRP00000994] [MT6620 Wi-Fi][Driver] dump message for bus error and reset bus error flag while re-initialized -+ * 1. always show error message for SDIO bus errors. -+ * 2. reset bus error flag when re-initialization -+ * -+ * 08 26 2011 cm.chang -+ * [WCXRP00000952] [MT5931 Wi-Fi][FW] Handshake with BWCS before DPD/TX power calibration -+ * Fix compiling error for WinXP MT5931 driver -+ * -+ * 08 25 2011 chinghwa.yu -+ * [WCXRP00000063] Update BCM CoEx design and settings -+ * Add BWCS Sync ready for WinXP. -+ * -+ * 08 25 2011 chinghwa.yu -+ * [WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm -+ * Add DFS switch. -+ * -+ * 08 24 2011 chinghwa.yu -+ * [WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm -+ * Update RDD test mode cases. -+ * -+ * 08 19 2011 cp.wu -+ * [WCXRP00000702] [MT5931][Driver] Modify initialization sequence for E1 ASIC -+ * escape from normal path if any error is occurred. -+ * -+ * 08 15 2011 cp.wu -+ * [WCXRP00000851] [MT6628 Wi-Fi][Driver] Add HIFSYS related definition to driver source tree -+ * reuse firmware download logic of MT6620 for MT6628. -+ * -+ * 08 15 2011 cp.wu -+ * [WCXRP00000913] [MT6620 Wi-Fi] create repository of source code dedicated for MT6620 E6 ASIC -+ * support to load different firmware image for E3/E4/E5 and E6 ASIC on win32 platforms. -+ * -+ * 08 02 2011 yuche.tsai -+ * [WCXRP00000896] [Volunteer Patch][WiFi Direct][Driver] GO with multiple client, TX deauth to a -+ * disconnecting device issue. -+ * Fix GO send deauth frame issue. -+ * -+ * 07 22 2011 jeffrey.chang -+ * [WCXRP00000864] [MT5931] Add command to adjust OSC stable time -+ * modify driver to set OSC stable time after f/w download -+ * -+ * 07 18 2011 chinghwa.yu -+ * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm -+ * Add CMD/Event for RDD and BWCS. -+ * -+ * 06 24 2011 cp.wu -+ * [WCXRP00000812] [MT6620 Wi-Fi][Driver] not show NVRAM when there is no valid MAC address in NVRAM content -+ * if there is no valid address in chip, generate a new one from driver domain instead of firmware domain -+ * due to sufficient randomness -+ * -+ * 06 23 2011 cp.wu -+ * [WCXRP00000812] [MT6620 Wi-Fi][Driver] not show NVRAM when there is no valid MAC address in NVRAM content -+ * check with firmware for valid MAC address. -+ * -+ * 06 20 2011 cp.wu -+ * [WCXRP00000702] [MT5931][Driver] Modify initialization sequence for E1 ASIC -+ * disable whole-chip resetting mechanism due to the need of further ECO to work as expected. -+ * -+ * 05 31 2011 cp.wu -+ * [WCXRP00000749] [MT6620 Wi-Fi][Driver] Add band edge tx power control to Wi-Fi NVRAM -+ * changed to use non-zero checking for valid bit in NVRAM content -+ * -+ * 05 27 2011 cp.wu -+ * [WCXRP00000749] [MT6620 Wi-Fi][Driver] Add band edge tx power control to Wi-Fi NVRAM -+ * invoke CMD_ID_SET_EDGE_TXPWR_LIMIT when there is valid data exist in NVRAM content. -+ * -+ * 05 18 2011 cp.wu -+ * [WCXRP00000734] [MT6620 Wi-Fi][Driver] Pass PHY_PARAM in NVRAM to firmware domain -+ * pass PHY_PARAM in NVRAM from driver to firmware. -+ * -+ * 05 11 2011 cp.wu -+ * [WCXRP00000718] [MT6620 Wi-Fi] modify the behavior of setting tx power -+ * correct assertion. -+ * -+ * 05 11 2011 cp.wu -+ * [WCXRP00000718] [MT6620 Wi-Fi] modify the behavior of setting tx power -+ * ACPI APIs migrate to wlan_lib.c for glue layer to invoke. -+ * -+ * 05 11 2011 cm.chang -+ * [WCXRP00000717] [MT5931 Wi-Fi][Driver] Handle wrong NVRAM content about AP bandwidth setting -+ * . -+ * -+ * 05 05 2011 cp.wu -+ * [WCXRP00000702] [MT5931][Driver] Modify initialization sequence for E1 ASIC -+ * change delay from 100ms to 120ms upon DE's suggestion. -+ * -+ * 05 05 2011 cp.wu -+ * [WCXRP00000702] [MT5931][Driver] Modify initialization sequence for E1 ASIC -+ * add delay after whole-chip resetting for MT5931 E1 ASIC. -+ * -+ * 04 22 2011 cp.wu -+ * [WCXRP00000598] [MT6620 Wi-Fi][Driver] Implementation of interface for communicating with user space -+ * process for RESET_START and RESET_END events skip power-off handshaking when RESET indication is received. -+ * -+ * 04 22 2011 george.huang -+ * [WCXRP00000621] [MT6620 Wi-Fi][Driver] Support P2P supplicant to set power mode -+ * . -+ * -+ * 04 18 2011 cp.wu -+ * [WCXRP00000636] [WHQL][MT5931 Driver] 2c_PMHibernate (hang on 2h) -+ * 1) add API for glue layer to query ACPI state -+ * 2) Windows glue should not access to hardware after switched into D3 state -+ * -+ * 04 15 2011 cp.wu -+ * [WCXRP00000654] [MT6620 Wi-Fi][Driver] Add loop termination criterion for wlanAdapterStop(). -+ * add loop termination criteria for wlanAdapterStop(). -+ * -+ * 04 12 2011 eddie.chen -+ * [WCXRP00000617] [MT6620 Wi-Fi][DRV/FW] Fix for sigma -+ * Fix the sta index in processing security frame -+ * Simple flow control for TC4 to avoid mgt frames for PS STA to occupy the TC4 -+ * Add debug message. -+ * -+ * 04 12 2011 cp.wu -+ * [WCXRP00000631] [MT6620 Wi-Fi][Driver] Add an API for QM to retrieve current TC counter value and processing -+ * frame dropping cases for TC4 path -+ * 1. add nicTxGetResource() API for QM to make decisions. -+ * 2. if management frames is decided by QM for dropping, the call back is invoked to indicate such a case. -+ * -+ * 04 06 2011 cp.wu -+ * [WCXRP00000616] [MT6620 Wi-Fi][Driver] Free memory to pool and kernel in case any unexpected failure -+ * happend inside wlanAdapterStart invoke nicReleaseAdapterMemory() as failure handling in case -+ * wlanAdapterStart() failed unexpectedly -+ * -+ * 03 29 2011 wh.su -+ * [WCXRP00000248] [MT6620 Wi-Fi][FW]Fixed the Klockwork error -+ * fixed the kclocwork error. -+ * -+ * 03 15 2011 cp.wu -+ * [WCXRP00000559] [MT6620 Wi-Fi][Driver] Combine TX/RX DMA buffers into a single one to reduce physically -+ * continuous memory consumption -+ * 1. deprecate CFG_HANDLE_IST_IN_SDIO_CALLBACK -+ * 2. Use common coalescing buffer for both TX/RX directions -+ * -+ * -+ * 03 10 2011 cp.wu -+ * [WCXRP00000532] [MT6620 Wi-Fi][Driver] Migrate NVRAM configuration procedures from MT6620 E2 to MT6620 E3 -+ * deprecate configuration used by MT6620 E2 -+ * -+ * 03 07 2011 terry.wu -+ * [WCXRP00000521] [MT6620 Wi-Fi][Driver] Remove non-standard debug message -+ * Toggle non-standard debug messages to comments. -+ * -+ * 02 25 2011 cp.wu -+ * [WCXRP00000496] [MT5931][Driver] Apply host-triggered chip reset before initializing firmware download procedures -+ * apply host-triggered chip reset mechanism before initializing firmware download procedures. -+ * -+ * 02 17 2011 eddie.chen -+ * [WCXRP00000458] [MT6620 Wi-Fi][Driver] BOW Concurrent - ProbeResp was exist in other channel -+ * 1) Change GetFrameAction decision when BSS is absent. -+ * 2) Check channel and resource in processing ProbeRequest -+ * -+ * 02 16 2011 cm.chang -+ * [WCXRP00000447] [MT6620 Wi-Fi][FW] Support new NVRAM update mechanism -+ * . -+ * -+ * 02 01 2011 george.huang -+ * [WCXRP00000333] [MT5931][FW] support SRAM power control drivers -+ * init variable for CTIA. -+ * -+ * 01 27 2011 george.huang -+ * [WCXRP00000355] [MT6620 Wi-Fi] Set WMM-PS related setting with qualifying AP capability -+ * Support current measure mode, assigned by registry (XP only). -+ * -+ * 01 24 2011 cp.wu -+ * [WCXRP00000382] [MT6620 Wi-Fi][Driver] Track forwarding packet number with notifying tx thread for serving -+ * 1. add an extra counter for tracking pending forward frames. -+ * 2. notify TX service thread as well when there is pending forward frame -+ * 3. correct build errors leaded by introduction of Wi-Fi direct separation module -+ * -+ * 01 12 2011 cm.chang -+ * [WCXRP00000354] [MT6620 Wi-Fi][Driver][FW] Follow NVRAM bandwidth setting -+ * User-defined bandwidth is for 2.4G and 5G individually -+ * -+ * 01 10 2011 cp.wu -+ * [WCXRP00000351] [MT6620 Wi-Fi][Driver] remove from scanning result in OID handling layer when the -+ * corresponding BSS is disconnected due to beacon timeout remove from scanning result when the BSS -+ * is disconnected due to beacon timeout. -+ * -+ * 01 04 2011 cp.wu -+ * [WCXRP00000338] [MT6620 Wi-Fi][Driver] Separate kalMemAlloc into kmalloc and vmalloc implementations to -+ * ease physically continuous memory demands separate kalMemAlloc() into virtually-continuous -+ * and physically-continuous type to ease slab system pressure -+ * -+ * 12 31 2010 cp.wu -+ * [WCXRP00000327] [MT6620 Wi-Fi][Driver] Improve HEC WHQA 6972 workaround coverage in driver side -+ * while being unloaded, clear all pending interrupt then set LP-own to firmware -+ * -+ * 12 31 2010 cp.wu -+ * [WCXRP00000335] [MT6620 Wi-Fi][Driver] change to use milliseconds sleep instead of delay -+ * to avoid blocking to system scheduling change to use msleep() and shorten waiting interval -+ * to reduce blocking to other task while Wi-Fi driver is being loaded -+ * -+ * 12 28 2010 cp.wu -+ * [WCXRP00000269] [MT6620 Wi-Fi][Driver][Firmware] Prepare for v1.1 branch release -+ * report EEPROM used flag via NIC_CAPABILITY -+ * -+ * 12 28 2010 cp.wu -+ * [WCXRP00000269] [MT6620 Wi-Fi][Driver][Firmware] Prepare for v1.1 branch release -+ * integrate with 'EEPROM used' flag for reporting correct capability to Engineer Mode/META and other tools -+ * -+ * 12 22 2010 eddie.chen -+ * [WCXRP00000218] [MT6620 Wi-Fi][Driver] Add auto rate window control in registry -+ * Remove controling auto rate from initial setting. The initial setting is defined by FW code. -+ * -+ * 12 15 2010 cp.wu -+ * NULL -+ * sync. with ALPS code by enabling interrupt just before leaving wlanAdapterStart() -+ * -+ * 12 08 2010 yuche.tsai -+ * [WCXRP00000245] [MT6620][Driver] Invitation & Provision Discovery Feature Check-in -+ * Change Param name for invitation connection. -+ * -+ * 12 07 2010 cm.chang -+ * [WCXRP00000238] MT6620 Wi-Fi][Driver][FW] Support regulation domain setting from NVRAM and supplicant -+ * 1. Country code is from NVRAM or supplicant -+ * 2. Change band definition in CMD/EVENT. -+ * -+ * 11 03 2010 cp.wu -+ * [WCXRP00000083] [MT5931][Driver][FW] Add necessary logic for MT5931 first connection -+ * 1) use 8 buffers for MT5931 which is equipped with less memory -+ * 2) modify MT5931 debug level to TRACE when download is successful -+ * -+ * 11 02 2010 cp.wu -+ * [WCXRP00000083] [MT5931][Driver][FW] Add necessary logic for MT5931 first connection -+ * for MT5931, adapter initialization is done *after* firmware is downloaded. -+ * -+ * 11 02 2010 cp.wu -+ * [WCXRP00000083] [MT5931][Driver][FW] Add necessary logic for MT5931 first connection -+ * correct MT5931 firmware download procedure: -+ * MT5931 will download firmware first then acquire LP-OWN -+ * -+ * 11 02 2010 cp.wu -+ * [WCXRP00000083] [MT5931][Driver][FW] Add necessary logic for MT5931 first connection -+ * 1) update MT5931 firmware encryption tool. (using 64-bytes unit) -+ * 2) update MT5931 firmware download procedure -+ * -+ * 11 01 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version -+ * Check[WCXRP00000150] [MT6620 Wi-Fi][Driver] Add implementation for querying -+ * current TX rate from firmware auto rate module -+ * 1) Query link speed (TX rate) from firmware directly with buffering mechanism to reduce overhead -+ * 2) Remove CNM CH-RECOVER event handling -+ * 3) cfg read/write API renamed with kal prefix for unified naming rules. -+ * -+ * 11 01 2010 yarco.yang -+ * [WCXRP00000149] [MT6620 WI-Fi][Driver]Fine tune performance on MT6516 platform -+ * Add code to run WlanIST in SDIO callback. -+ * -+ * 10 27 2010 george.huang -+ * [WCXRP00000127] [MT6620 Wi-Fi][Driver] Add a registry to disable Beacon Timeout function -+ * for SQA test by using E1 EVB -+ * Support registry option for disable beacon lost detection. -+ * -+ * 10 26 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version -+ * Check[WCXRP00000137] [MT6620 Wi-Fi] [FW] Support NIC capability query command -+ * 1) update NVRAM content template to ver 1.02 -+ * 2) add compile option for querying NIC capability (default: off) -+ * 3) modify AIS 5GHz support to run-time option, which could be turned on by registry or NVRAM setting -+ * 4) correct auto-rate compiler error under linux (treat warning as error) -+ * 5) simplify usage of NVRAM and REG_INFO_T -+ * 6) add version checking between driver and firmware -+ * -+ * 10 26 2010 eddie.chen -+ * [WCXRP00000134] [MT6620 Wi-Fi][Driver] Add a registry to enable auto rate for SQA test by using E1 EVB -+ * Add auto rate parameter in registry. -+ * -+ * 10 25 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check -+ * add option for enable/disable TX PWR gain adjustment (default: off) -+ * -+ * 10 18 2010 cp.wu -+ * [WCXRP00000117] [MT6620 Wi-Fi][Driver] Add logic for suspending driver when MT6620 is not responding anymore -+ * 1. when wlanAdapterStop() failed to send POWER CTRL command to firmware, do not poll for ready bit dis-assertion -+ * 2. shorten polling count for shorter response time -+ * 3. if bad I/O operation is detected during TX resource polling, then further operation is aborted as well -+ * -+ * 10 18 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version -+ * Check[WCXRP00000086] [MT6620 Wi-Fi][Driver] The mac address is all zero at android -+ * complete implementation of Android NVRAM access -+ * -+ * 10 15 2010 cp.wu -+ * [WCXRP00000103] [MT6620 Wi-Fi][Driver] Driver crashed when using WZC to connect to AP#B with connection with AP#A -+ * bugfix: always reset pointer to IEbuf to zero when keeping scanning result for the connected AP -+ * -+ * 10 08 2010 cp.wu -+ * [WCXRP00000084] [MT6620 Wi-Fi][Driver][FW] Add fixed rate support for distance test -+ * adding fixed rate support for distance test. (from registry setting) -+ * -+ * 10 07 2010 cp.wu -+ * [WCXRP00000083] [MT5931][Driver][FW] Add necessary logic for MT5931 first connection -+ * add firmware download for MT5931. -+ * -+ * 10 06 2010 cp.wu -+ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning -+ * divide a single function into 2 part to surpress a weird compiler warning from gcc-4.4.0 -+ * -+ * 10 06 2010 cp.wu -+ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning -+ * code reorganization to improve isolation between GLUE and CORE layers. -+ * -+ * 10 05 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check -+ * load manufacture data when CFG_SUPPORT_NVRAM is set to 1 -+ * -+ * 10 04 2010 cp.wu -+ * [WCXRP00000077] [MT6620 Wi-Fi][Driver][FW] Eliminate use of ENUM_NETWORK_TYPE_T and replaced -+ * by ENUM_NETWORK_TYPE_INDEX_T only -+ * remove ENUM_NETWORK_TYPE_T definitions -+ * -+ * 09 29 2010 wh.su -+ * [WCXRP00000072] [MT6620 Wi-Fi][Driver] Fix TKIP Counter Measure EAPoL callback register issue -+ * [MT6620 Wi-Fi][Driver] Fix TKIP Counter Measure EAPoL callback register issue. -+ * -+ * 09 24 2010 cp.wu -+ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning -+ * eliminate unused variables which lead gcc to argue -+ * -+ * 09 24 2010 cp.wu -+ * [WCXRP00000057] [MT6620 Wi-Fi][Driver] Modify online scan to a run-time switchable feature -+ * Modify online scan as a run-time adjustable option (for Windows, in registry) -+ * -+ * 09 23 2010 cp.wu -+ * [WCXRP00000051] [MT6620 Wi-Fi][Driver] WHQL test fail in MAC address changed item -+ * use firmware reported mac address right after wlanAdapterStart() as permanent address -+ * -+ * 09 23 2010 cp.wu -+ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning -+ * eliminate reference of CFG_RESPONSE_MAX_PKT_SIZE -+ * -+ * 09 21 2010 cp.wu -+ * [WCXRP00000053] [MT6620 Wi-Fi][Driver] Reset incomplete and might leads to BSOD when entering RF test with -+ * AIS associated -+ * Do a complete reset with STA-REC null checking for RF test re-entry -+ * -+ * 09 21 2010 kevin.huang -+ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning -+ * Eliminate Linux Compile Warning -+ * -+ * 09 13 2010 cp.wu -+ * NULL -+ * acquire & release power control in oid handing wrapper. -+ * -+ * 09 09 2010 cp.wu -+ * NULL -+ * move IE to buffer head when the IE pointer is not pointed at head. -+ * -+ * 09 08 2010 cp.wu -+ * NULL -+ * use static memory pool for storing IEs of scanning result. -+ * -+ * 09 01 2010 cp.wu -+ * NULL -+ * HIFSYS Clock Source Workaround -+ * -+ * 09 01 2010 wh.su -+ * NULL -+ * adding the wapi support for integration test. -+ * -+ * 09 01 2010 cp.wu -+ * NULL -+ * move HIF CR initialization from where after sdioSetupCardFeature() to wlanAdapterStart() -+ * -+ * 08 30 2010 cp.wu -+ * NULL -+ * eliminate klockwork errors -+ * -+ * 08 26 2010 yuche.tsai -+ * NULL -+ * Add AT GO test configure mode under WinXP. -+ * Please enable 1. CFG_ENABLE_WIFI_DIRECT, 2. CFG_TEST_WIFI_DIRECT_GO, 3. CFG_SUPPORT_AAA -+ * -+ * 08 25 2010 george.huang -+ * NULL -+ * update OID/ registry control path for PM related settings -+ * -+ * 08 24 2010 cp.wu -+ * NULL -+ * 1) initialize variable for enabling short premable/short time slot. -+ * 2) add compile option for disabling online scan -+ * -+ * 08 13 2010 cp.wu -+ * NULL -+ * correction issue: desired phy type not initialized as ABGN mode. -+ * -+ * 08 12 2010 cp.wu -+ * NULL -+ * [AIS-FSM] honor registry setting for adhoc running mode. (A/B/G) -+ * -+ * 08 10 2010 cm.chang -+ * NULL -+ * Support EEPROM read/write in RF test mode -+ * -+ * 08 03 2010 cp.wu -+ * NULL -+ * surpress compilation warning. -+ * -+ * 08 03 2010 cp.wu -+ * NULL -+ * Centralize mgmt/system service procedures into independent calls. -+ * -+ * 07 30 2010 cp.wu -+ * NULL -+ * 1) BoW wrapper: use definitions instead of hard-coded constant for error code -+ * 2) AIS-FSM: eliminate use of desired RF parameters, use prTargetBssDesc instead -+ * 3) add handling for RX_PKT_DESTINATION_HOST_WITH_FORWARD for GO-broadcast frames -+ * -+ * 07 29 2010 cp.wu -+ * NULL -+ * eliminate u4FreqInKHz usage, combined into rConnections.ucAdHoc* -+ * -+ * 07 28 2010 cp.wu -+ * NULL -+ * 1) eliminate redundant variable eOPMode in prAdapter->rWlanInfo -+ * 2) change nicMediaStateChange() API prototype -+ * -+ * 07 21 2010 cp.wu -+ * -+ * 1) change BG_SCAN to ONLINE_SCAN for consistent term -+ * 2) only clear scanning result when scan is permitted to do -+ * -+ * 07 19 2010 cm.chang -+ * -+ * Set RLM parameters and enable CNM channel manager -+ * -+ * 07 19 2010 jeffrey.chang -+ * -+ * Linux port modification -+ * -+ * 07 13 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration. -+ * Reduce unnecessary type casting -+ * -+ * 07 13 2010 cp.wu -+ * -+ * use multiple queues to keep 1x/MMPDU/CMD's strict order even when there is incoming 1x frames. -+ * -+ * 07 13 2010 cp.wu -+ * -+ * 1) MMPDUs are now sent to MT6620 by CMD queue for keeping strict order of 1X/MMPDU/CMD packets -+ * 2) integrate with qmGetFrameAction() for deciding which MMPDU/1X could pass checking for sending -+ * 2) enhance CMD_INFO_T descriptor number from 10 to 32 to avoid descriptor underflow under concurrent -+ * network operation -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 07 05 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) ignore RSN checking when RSN is not turned on. -+ * 2) set STA-REC deactivation callback as NULL -+ * 3) add variable initialization API based on PHY configuration -+ * -+ * 07 02 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) for event packet, no need to fill RFB. -+ * 2) when wlanAdapterStart() failed, no need to initialize state machines -+ * 3) after Beacon/ProbeResp parsing, corresponding BSS_DESC_T should be marked as IE-parsed -+ * -+ * 07 01 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Support sync command of STA_REC -+ * -+ * 07 01 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add scan uninitialization procedure -+ * -+ * 06 25 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add API in que_mgt to retrieve sta-rec index for security frames. -+ * -+ * 06 24 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 802.1x and bluetooth-over-Wi-Fi security frames are now delievered to firmware via command path instead of data path. -+ * -+ * 06 23 2010 yarco.yang -+ * [WPD00003837][MT6620]Data Path Refine -+ * Merge g_arStaRec[] into adapter->arStaRec[] -+ * -+ * 06 21 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * initialize mbox & ais_fsm in wlanAdapterStart() -+ * -+ * 06 21 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * change MAC address updating logic. -+ * -+ * 06 21 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * simplify timer usage. -+ * -+ * 06 11 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) migrate assoc.c. -+ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness -+ * 3) add configuration options for CNM_MEM and RSN modules -+ * 4) add data path for management frames -+ * 5) eliminate rPacketInfo of MSDU_INFO_T -+ * -+ * 06 10 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) eliminate CFG_CMD_EVENT_VERSION_0_9 -+ * 2) when disconnected, indicate nic directly (no event is needed) -+ * -+ * 06 08 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * cnm_timer has been migrated. -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 05 28 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * disable interrupt then send power control command packet. -+ * -+ * 05 24 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) when stopping adapter, wait til RDY bit has been cleaerd. -+ * 2) set TASK_OFFLOAD as driver-core OIDs -+ * -+ * 05 20 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) integrate OID_GEN_NETWORK_LAYER_ADDRESSES with CMD_ID_SET_IP_ADDRESS -+ * 2) buffer statistics data for 2 seconds -+ * 3) use default value for adhoc parameters instead of 0 -+ * -+ * 05 19 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) do not take timeout mechanism for power mode oids -+ * 2) retrieve network type from connection status -+ * 3) after disassciation, set radio state to off -+ * 4) TCP option over IPv6 is supported -+ * -+ * 05 17 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * add CFG_STARTUP_DEBUG for debugging starting up issue. -+ * -+ * 05 17 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * 1) add timeout handler mechanism for pending command packets -+ * 2) add p2p add/removal key -+ * -+ * 04 23 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * surpress compiler warning -+ * -+ * 04 20 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * roll-back to rev.60. -+ * -+ * 04 20 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) remove redundant firmware image unloading -+ * 2) use compile-time macros to separate logic related to accquiring own -+ * -+ * 04 16 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * treat BUS access failure as kind of card removal. -+ * -+ * 04 14 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * always set fw-own before driver is unloaded. -+ * -+ * 04 13 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * add framework for BT-over-Wi-Fi support. -+ * * * 1) prPendingCmdInfo is replaced by queue for multiple handler capability -+ * * * 2) command sequence number is now increased atomically -+ * * * 3) private data could be hold and taken use for other purpose -+ * -+ * 04 07 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * finish non-glue layer access to glue variables -+ * -+ * 04 07 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * rWlanInfo should be placed at adapter rather than glue due to most operations -+ * are done in adapter layer. -+ * -+ * 04 06 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * ePowerCtrl is not necessary as a glue variable. -+ * -+ * 04 06 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * add timeout check in the kalOidComplete -+ * -+ * 04 06 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * improve none-glue code portability -+ * -+ * 04 06 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * improve none-glue code portability -+ * -+ * 04 06 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * code refine: fgTestMode should be at adapter rather than glue due to the device/fw is also involved -+ * -+ * 04 06 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * eliminate direct access for prGlueInfo->fgIsCardRemoved in non-glue layer -+ * -+ * 04 06 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) for some OID, never do timeout expiration -+ * 2) add 2 kal API for later integration -+ * -+ * 04 06 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) eliminate unused definitions -+ * 2) ready bit will be polled for limited iteration -+ * -+ * 04 06 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * kalOidComplete is not necessary in linux -+ * -+ * 04 01 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * change to use pass-in prRegInfo instead of accessing prGlueInfo directly -+ * -+ * 04 01 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * change to use WIFI_TCM_ALWAYS_ON as firmware image -+ * -+ * 04 01 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * . -+ * -+ * 03 31 2010 wh.su -+ * [WPD00003816][MT6620 Wi-Fi] Adding the security support -+ * modify the wapi related code for new driver's design. -+ * -+ * 03 30 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * adding none-glue code portability -+ * -+ * 03 30 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * adding non-glue code portability -+ * -+ * 03 29 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * improve non-glue code portability -+ * -+ * 03 25 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * firmware download load address & start address are now configured from config.h -+ * due to the different configurations on FPGA and ASIC -+ * -+ * 03 24 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * [WPD00003826] Initial import for Linux port -+ * initial import for Linux port -+ * -+ * 03 24 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * initial import for Linux port -+ * -+ * 03 22 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * only send CMD_NIC_POWER_CTRL in wlanAdapterStop() when card is not removed and is not in D3 state -+ * -+ * 03 22 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * always send CMD_NIC_POWER_CTRL packet when nic is being halted -+ * -+ * 03 19 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) add ACPI D0/D3 state switching support -+ * 2) use more formal way to handle interrupt when the status is retrieved from enhanced RX response -+ * -+* 03 12 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * add two option for ACK and ENCRYPTION for firmware download -+ * -+ * 03 11 2010 cp.wu -+ * [WPD00003821][BUG] Host driver stops processing RX packets from HIF RX0 -+ * add RX starvation warning debug message controlled by CFG_HIF_RX_STARVATION_WARNING -+ * -+ * 03 08 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) add another spin-lock to protect MsduInfoList due to it might be accessed by different thread. -+ * 2) change own-back acquiring procedure to wait for up to 16.67 seconds -+ * -+ * 03 03 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * when starting adapter, read local adminsitrated address from registry and send to firmware via CMD_BASIC_CONFIG. -+ * -+ * 03 02 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) the use of prPendingOid revised, all accessing are now protected by spin lock -+ * 2) ensure wlanReleasePendingOid will clear all command queues -+ * -+ * 03 02 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * add mutex to avoid multiple access to qmTxQueue simultaneously. -+ * -+ * 03 01 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * add command/event definitions for initial states -+ * -+ * 02 24 2010 tehuang.liu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * Added code for QM_TEST_MODE -+ * -+ * 02 24 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * correct function name .. -+ * -+ * 02 24 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * separate wlanProcesQueuePacket() into 2 APIs upon request -+ * -+ * 02 23 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * add new API: wlanProcessQueuedPackets() -+ * -+ * 02 11 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * correct wlanAdapterStart -+ * -+ * 02 11 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1. add logic for firmware download -+ * 2. firmware image filename and start/load address are now retrieved from registry -+ * -+ * 02 10 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * implement host-side firmware download logic -+ * -+ * 02 10 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) remove unused function in nic_rx.c [which has been handled in que_mgt.c] -+ * 2) firmware image length is now retrieved via NdisFileOpen -+ * 3) firmware image is not structured by (P_IMG_SEC_HDR_T) anymore -+ * 4) nicRxWaitResponse() revised -+ * 5) another set of TQ counter default value is added for fw-download state -+ * 6) Wi-Fi load address is now retrieved from registry too -+ * -+ * 02 09 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1. Permanent and current MAC address are now retrieved by CMD/EVENT packets instead of hard-coded address -+ * 2. follow MSDN defined behavior when associates to another AP -+ * 3. for firmware download, packet size could be up to 2048 bytes -+ * -+ * 02 08 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * prepare for implementing fw download logic -+ * -+ * 02 03 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * wlanoidSetFrequency is now implemented by RF test command. -+ * -+ * 02 03 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * QueryRssi is no longer w/o hardware access, it is now implemented by command/event handling loop -+ * -+ * 02 03 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1. clear prPendingCmdInfo properly -+ * 2. while allocating memory for cmdinfo, no need to add extra 4 bytes. -+ * -+ * 01 28 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * allow MCR read/write OIDs in RF test mode -+ * -+ * 01 27 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) implement timeout mechanism when OID is pending for longer than 1 second -+ * 2) allow OID_802_11_CONFIGURATION to be executed when RF test mode is turned on -+ * -+ * 01 27 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1. eliminate improper variable in rHifInfo -+ * 2. block TX/ordinary OID when RF test mode is engaged -+ * 3. wait until firmware finish operation when entering into and leaving from RF test mode -+ * 4. correct some HAL implementation -+ * -+ * 01 26 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * Under WinXP with SDIO, use prGlueInfo->rHifInfo.pvInformationBuffer instead of prGlueInfo->pvInformationBuffer -+** \main\maintrunk.MT6620WiFiDriver_Prj\36 2009-12-10 16:54:36 GMT mtk02752 -+** code clean -+** \main\maintrunk.MT6620WiFiDriver_Prj\35 2009-12-09 20:04:59 GMT mtk02752 -+** only report as connected when CFG_HIF_EMULATION_TEST is set to 1 -+** \main\maintrunk.MT6620WiFiDriver_Prj\34 2009-12-08 17:39:41 GMT mtk02752 -+** wlanoidRftestQueryAutoTest could be executed without touching hardware -+** \main\maintrunk.MT6620WiFiDriver_Prj\33 2009-12-03 16:10:26 GMT mtk01461 -+** Add debug message -+** \main\maintrunk.MT6620WiFiDriver_Prj\32 2009-12-02 22:05:33 GMT mtk02752 -+** kalOidComplete() will decrease i4OidPendingCount -+** \main\maintrunk.MT6620WiFiDriver_Prj\31 2009-12-01 23:02:36 GMT mtk02752 -+** remove unnecessary spinlock -+** \main\maintrunk.MT6620WiFiDriver_Prj\30 2009-12-01 22:50:38 GMT mtk02752 -+** use TC4 for command, maintein i4OidPendingCount -+** \main\maintrunk.MT6620WiFiDriver_Prj\29 2009-11-27 12:45:34 GMT mtk02752 -+** prCmdInfo should be freed when invoking wlanReleasePendingOid() to clear pending oid -+** \main\maintrunk.MT6620WiFiDriver_Prj\28 2009-11-24 19:55:51 GMT mtk02752 -+** wlanSendPacket & wlanRetransmitOfPendingFrames is only used in old data path -+** \main\maintrunk.MT6620WiFiDriver_Prj\27 2009-11-23 17:59:55 GMT mtk02752 -+** clear prPendingOID inside wlanSendCommand() when the OID didn't need to be replied. -+** \main\maintrunk.MT6620WiFiDriver_Prj\26 2009-11-23 14:45:29 GMT mtk02752 -+** add another version of wlanSendCommand() for command-sending only without blocking for response -+** \main\maintrunk.MT6620WiFiDriver_Prj\25 2009-11-17 22:40:44 GMT mtk01084 -+** \main\maintrunk.MT6620WiFiDriver_Prj\24 2009-11-11 10:14:56 GMT mtk01084 -+** modify place to invoke wlanIst -+** \main\maintrunk.MT6620WiFiDriver_Prj\23 2009-10-30 18:17:07 GMT mtk01084 -+** fix compiler warning -+** \main\maintrunk.MT6620WiFiDriver_Prj\22 2009-10-29 19:46:15 GMT mtk01084 -+** invoke interrupt process routine -+** \main\maintrunk.MT6620WiFiDriver_Prj\21 2009-10-13 21:58:24 GMT mtk01084 -+** modify for new HW architecture -+** \main\maintrunk.MT6620WiFiDriver_Prj\20 2009-09-09 17:26:01 GMT mtk01084 -+** \main\maintrunk.MT6620WiFiDriver_Prj\19 2009-05-20 12:21:27 GMT mtk01461 -+** Add SeqNum check when process Event Packet -+** \main\maintrunk.MT6620WiFiDriver_Prj\18 2009-05-19 10:38:44 GMT mtk01461 -+** Add wlanReleasePendingOid() for mpReset() if there is a pending OID and no available TX resource to send it. -+** \main\maintrunk.MT6620WiFiDriver_Prj\17 2009-04-29 15:41:34 GMT mtk01461 -+** Add handle of EVENT of CMD Result in wlanSendCommand() -+** \main\maintrunk.MT6620WiFiDriver_Prj\16 2009-04-22 09:11:23 GMT mtk01461 -+** Fix wlanSendCommand() for Driver Domain CR -+** \main\maintrunk.MT6620WiFiDriver_Prj\15 2009-04-21 09:33:56 GMT mtk01461 -+** Update wlanSendCommand() for Driver Domain Response and handle Event Packet, -+** wlanQuery/SetInformation() for enqueue CMD_INFO_T -+** \main\maintrunk.MT6620WiFiDriver_Prj\14 2009-04-17 20:00:08 GMT mtk01461 -+** Update wlanImageSectionDownload for optimized CMD process -+** \main\maintrunk.MT6620WiFiDriver_Prj\13 2009-04-14 20:50:51 GMT mtk01426 -+** Fixed compile error -+** \main\maintrunk.MT6620WiFiDriver_Prj\12 2009-04-13 16:38:40 GMT mtk01084 -+** add wifi start function -+** \main\maintrunk.MT6620WiFiDriver_Prj\11 2009-04-13 14:26:44 GMT mtk01084 -+** modify a parameter about FW download length -+** \main\maintrunk.MT6620WiFiDriver_Prj\10 2009-04-10 21:53:42 GMT mtk01461 -+** Update wlanSendCommand() -+** \main\maintrunk.MT6620WiFiDriver_Prj\9 2009-04-08 16:51:04 GMT mtk01084 -+** Update for the image download part -+** \main\maintrunk.MT6620WiFiDriver_Prj\8 2009-04-01 10:32:47 GMT mtk01461 -+** Add wlanSendLeftClusteredFrames() for SDIO_TX_ENHANCE -+** \main\maintrunk.MT6620WiFiDriver_Prj\7 2009-03-23 21:44:13 GMT mtk01461 -+** Refine TC assignment for WmmAssoc flag -+** \main\maintrunk.MT6620WiFiDriver_Prj\6 2009-03-23 16:51:57 GMT mtk01084 -+** modify the input argument of caller to RECLAIM_POWER_CONTROL_TO_PM() -+** \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-03-23 00:27:13 GMT mtk01461 -+** Add reference code of FW Image Download -+** \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-03-19 18:32:37 GMT mtk01084 -+** update for basic power management functions -+** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-03-16 09:09:08 GMT mtk01461 -+** Update TX PATH API -+** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 16:28:45 GMT mtk01426 -+** Init develop -+** -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "precomp.h" -+#include "mgmt/ais_fsm.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+/* 6.1.1.2 Interpretation of priority parameter in MAC service primitives */ -+/* Static convert the Priority Parameter/TID(User Priority/TS Identifier) to Traffic Class */ -+const UINT_8 aucPriorityParam2TC[] = { -+ TC1_INDEX, -+ TC0_INDEX, -+ TC0_INDEX, -+ TC1_INDEX, -+ TC2_INDEX, -+ TC2_INDEX, -+ TC3_INDEX, -+ TC3_INDEX -+}; -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+typedef struct _CODE_MAPPING_T { -+ UINT_32 u4RegisterValue; -+ INT_32 i4TxpowerOffset; -+} CODE_MAPPING_T, *P_CODE_MAPPING_T; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+BOOLEAN fgIsBusAccessFailed = FALSE; -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+#define SIGNED_EXTEND(n, _sValue) \ -+ (((_sValue) & BIT((n)-1)) ? ((_sValue) | BITS(n, 31)) : \ -+ ((_sValue) & ~BITS(n, 31))) -+ -+/* TODO: Check */ -+/* OID set handlers without the need to access HW register */ -+PFN_OID_HANDLER_FUNC apfnOidSetHandlerWOHwAccess[] = { -+ wlanoidSetChannel, -+ wlanoidSetBeaconInterval, -+ wlanoidSetAtimWindow, -+ wlanoidSetFrequency, -+}; -+ -+/* TODO: Check */ -+/* OID query handlers without the need to access HW register */ -+PFN_OID_HANDLER_FUNC apfnOidQueryHandlerWOHwAccess[] = { -+ wlanoidQueryBssid, -+ wlanoidQuerySsid, -+ wlanoidQueryInfrastructureMode, -+ wlanoidQueryAuthMode, -+ wlanoidQueryEncryptionStatus, -+ wlanoidQueryPmkid, -+ wlanoidQueryNetworkTypeInUse, -+ wlanoidQueryBssidList, -+ wlanoidQueryAcpiDevicePowerState, -+ wlanoidQuerySupportedRates, -+ wlanoidQueryDesiredRates, -+ wlanoidQuery802dot11PowerSaveProfile, -+ wlanoidQueryBeaconInterval, -+ wlanoidQueryAtimWindow, -+ wlanoidQueryFrequency, -+}; -+ -+/* OID set handlers allowed in RF test mode */ -+PFN_OID_HANDLER_FUNC apfnOidSetHandlerAllowedInRFTest[] = { -+ wlanoidRftestSetTestMode, -+ wlanoidRftestSetAbortTestMode, -+ wlanoidRftestSetAutoTest, -+ wlanoidSetMcrWrite, -+ wlanoidSetEepromWrite -+}; -+ -+/* OID query handlers allowed in RF test mode */ -+PFN_OID_HANDLER_FUNC apfnOidQueryHandlerAllowedInRFTest[] = { -+ wlanoidRftestQueryAutoTest, -+ wlanoidQueryMcrRead, -+ wlanoidQueryEepromRead -+} -+ -+; -+ -+PFN_OID_HANDLER_FUNC apfnOidWOTimeoutCheck[] = { -+ wlanoidRftestSetTestMode, -+ wlanoidRftestSetAbortTestMode, -+ wlanoidSetAcpiDevicePowerState, -+}; -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+#if 0 /* no use */ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This is a private routine, which is used to check if HW access is needed -+* for the OID query/ set handlers. -+* -+* \param[IN] pfnOidHandler Pointer to the OID handler. -+* \param[IN] fgSetInfo It is a Set information handler. -+* -+* \retval TRUE This function needs HW access -+* \retval FALSE This function does not need HW access -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN wlanIsHandlerNeedHwAccess(IN PFN_OID_HANDLER_FUNC pfnOidHandler, IN BOOLEAN fgSetInfo) -+{ -+ PFN_OID_HANDLER_FUNC *apfnOidHandlerWOHwAccess; -+ UINT_32 i; -+ UINT_32 u4NumOfElem; -+ -+ if (fgSetInfo) { -+ apfnOidHandlerWOHwAccess = apfnOidSetHandlerWOHwAccess; -+ u4NumOfElem = sizeof(apfnOidSetHandlerWOHwAccess) / sizeof(PFN_OID_HANDLER_FUNC); -+ } else { -+ apfnOidHandlerWOHwAccess = apfnOidQueryHandlerWOHwAccess; -+ u4NumOfElem = sizeof(apfnOidQueryHandlerWOHwAccess) / sizeof(PFN_OID_HANDLER_FUNC); -+ } -+ -+ for (i = 0; i < u4NumOfElem; i++) { -+ if (apfnOidHandlerWOHwAccess[i] == pfnOidHandler) -+ return FALSE; -+ } -+ -+ return TRUE; -+} /* wlanIsHandlerNeedHwAccess */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to set flag for later handling card -+* ejected event. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* -+* \return (none) -+* -+* \note When surprised removal happens, Glue layer should invoke this -+* function to notify WPDD not to do any hw access. -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID wlanCardEjected(IN P_ADAPTER_T prAdapter) -+{ -+ DEBUGFUNC("wlanCardEjected"); -+ /* INITLOG(("\n")); */ -+ -+ ASSERT(prAdapter); -+ -+ /* mark that the card is being ejected, NDIS will shut us down soon */ -+ nicTxRelease(prAdapter); -+ -+} /* wlanCardEjected */ -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Create adapter object -+* -+* \param prAdapter This routine is call to allocate the driver software objects. -+* If fails, return NULL. -+* \retval NULL If it fails, NULL is returned. -+* \retval NOT NULL If the adapter was initialized successfully. -+*/ -+/*----------------------------------------------------------------------------*/ -+P_ADAPTER_T wlanAdapterCreate(IN P_GLUE_INFO_T prGlueInfo) -+{ -+ P_ADAPTER_T prAdpater = (P_ADAPTER_T) NULL; -+ -+ DEBUGFUNC("wlanAdapterCreate"); -+ -+ do { -+ prAdpater = (P_ADAPTER_T) kalMemAlloc(sizeof(ADAPTER_T), VIR_MEM_TYPE); -+ -+ if (!prAdpater) { -+ DBGLOG(INIT, ERROR, "Allocate ADAPTER memory ==> FAILED\n"); -+ break; -+ } -+ -+ kalMemZero(prAdpater, sizeof(ADAPTER_T)); -+ prAdpater->prGlueInfo = prGlueInfo; -+ -+ } while (FALSE); -+ -+ return prAdpater; -+} /* wlanAdapterCreate */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Destroy adapter object -+* -+* \param prAdapter This routine is call to destroy the driver software objects. -+* If fails, return NULL. -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID wlanAdapterDestroy(IN P_ADAPTER_T prAdapter) -+{ -+ -+ if (!prAdapter) -+ return; -+ -+ kalMemFree(prAdapter, VIR_MEM_TYPE, sizeof(ADAPTER_T)); -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Initialize the adapter. The sequence is -+* 1. Disable interrupt -+* 2. Read adapter configuration from EEPROM and registry, verify chip ID. -+* 3. Create NIC Tx/Rx resource. -+* 4. Initialize the chip -+* 5. Initialize the protocol -+* 6. Enable Interrupt -+* -+* \param prAdapter Pointer of Adapter Data Structure -+* -+* \retval WLAN_STATUS_SUCCESS: Success -+* \retval WLAN_STATUS_FAILURE: Failed -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanAdapterStart(IN P_ADAPTER_T prAdapter, -+ IN P_REG_INFO_T prRegInfo, IN PVOID pvFwImageMapFile, IN UINT_32 u4FwImageFileLength) -+{ -+ WLAN_STATUS u4Status = WLAN_STATUS_SUCCESS; -+ UINT_32 i, u4Value = 0; -+ UINT_32 u4WHISR = 0; -+ UINT_8 aucTxCount[8]; -+#if CFG_ENABLE_FW_DOWNLOAD -+ UINT_32 u4FwLoadAddr, u4ImgSecSize; -+#if CFG_ENABLE_FW_DIVIDED_DOWNLOAD -+ UINT_32 j; -+ P_FIRMWARE_DIVIDED_DOWNLOAD_T prFwHead; -+ BOOLEAN fgValidHead; -+ const UINT_32 u4CRCOffset = offsetof(FIRMWARE_DIVIDED_DOWNLOAD_T, u4NumOfEntries); -+#endif -+#endif -+ enum Adapter_Start_Fail_Reason { -+ ALLOC_ADAPTER_MEM_FAIL, -+ DRIVER_OWN_FAIL, -+ INIT_ADAPTER_FAIL, -+ RAM_CODE_DOWNLOAD_FAIL, -+ WAIT_FIRMWARE_READY_FAIL, -+ FAIL_REASON_MAX -+ } eFailReason; -+ ASSERT(prAdapter); -+ -+ DEBUGFUNC("wlanAdapterStart"); -+ -+ eFailReason = FAIL_REASON_MAX; -+ /* 4 <0> Reset variables in ADAPTER_T */ -+ prAdapter->fgIsFwOwn = TRUE; -+ prAdapter->fgIsEnterD3ReqIssued = FALSE; -+ -+ QUEUE_INITIALIZE(&(prAdapter->rPendingCmdQueue)); -+ -+ /* Initialize rWlanInfo */ -+ kalMemSet(&(prAdapter->rWlanInfo), 0, sizeof(WLAN_INFO_T)); -+ -+ /* 4 <0.1> reset fgIsBusAccessFailed */ -+ fgIsBusAccessFailed = FALSE; -+ prAdapter->ulSuspendFlag = 0; -+ -+ do { -+ u4Status = nicAllocateAdapterMemory(prAdapter); -+ if (u4Status != WLAN_STATUS_SUCCESS) { -+ DBGLOG(INIT, ERROR, "nicAllocateAdapterMemory Error!\n"); -+ u4Status = WLAN_STATUS_FAILURE; -+ eFailReason = ALLOC_ADAPTER_MEM_FAIL; -+ break; -+ } -+ -+ prAdapter->u4OsPacketFilter = PARAM_PACKET_FILTER_SUPPORTED; -+ -+ DBGLOG(INIT, TRACE, "wlanAdapterStart(): Acquiring LP-OWN %d\n", fgIsResetting); -+ ACQUIRE_POWER_CONTROL_FROM_PM(prAdapter); -+ -+#if !CFG_ENABLE_FULL_PM -+ nicpmSetDriverOwn(prAdapter); -+#endif -+ -+ if (prAdapter->fgIsFwOwn == TRUE) { -+ DBGLOG(INIT, ERROR, "nicpmSetDriverOwn() failed!\n"); -+ u4Status = WLAN_STATUS_FAILURE; -+ eFailReason = DRIVER_OWN_FAIL; -+ break; -+ } -+ /* 4 <1> Initialize the Adapter */ -+ u4Status = nicInitializeAdapter(prAdapter); -+ if (u4Status != WLAN_STATUS_SUCCESS) { -+ DBGLOG(INIT, ERROR, "nicInitializeAdapter failed!\n"); -+ u4Status = WLAN_STATUS_FAILURE; -+ eFailReason = INIT_ADAPTER_FAIL; -+ break; -+ } -+ -+ /* init wake lock before interrupt enable and tx thread */ -+ KAL_WAKE_LOCK_INIT(prAdapter, &prAdapter->rTxThreadWakeLock, "WLAN TX THREAD"); -+ -+ /* 4 <2> Initialize System Service (MGMT Memory pool and STA_REC) */ -+ nicInitSystemService(prAdapter); -+ -+ /* 4 <3> Initialize Tx */ -+ nicTxInitialize(prAdapter); -+ wlanDefTxPowerCfg(prAdapter); -+ -+ /* 4 <4> Initialize Rx */ -+ nicRxInitialize(prAdapter); -+ -+#if CFG_ENABLE_FW_DOWNLOAD -+ if (pvFwImageMapFile == NULL) { -+ DBGLOG(INIT, ERROR, "No Firmware found!\n"); -+ u4Status = WLAN_STATUS_FAILURE; -+ eFailReason = RAM_CODE_DOWNLOAD_FAIL; -+ break; -+ } -+ -+ /* 1. disable interrupt, download is done by polling mode only */ -+ nicDisableInterrupt(prAdapter); -+ -+ /* 2. Initialize Tx Resource to fw download state */ -+ nicTxInitResetResource(prAdapter); -+ -+ /* 3. FW download here */ -+ u4FwLoadAddr = prRegInfo->u4LoadAddress; -+ -+#if CFG_ENABLE_FW_DIVIDED_DOWNLOAD -+ /* 3a. parse file header for decision of divided firmware download or not */ -+ prFwHead = (P_FIRMWARE_DIVIDED_DOWNLOAD_T) pvFwImageMapFile; -+ -+ if (prFwHead->u4Signature == MTK_WIFI_SIGNATURE && -+ prFwHead->u4CRC == wlanCRC32((PUINT_8) pvFwImageMapFile + u4CRCOffset, -+ u4FwImageFileLength - u4CRCOffset)) { -+ fgValidHead = TRUE; -+ } else { -+ fgValidHead = FALSE; -+ } -+ -+ /* 3b. engage divided firmware downloading */ -+ if (fgValidHead == TRUE) { -+ DBGLOG(INIT, TRACE, "wlanAdapterStart(): fgValidHead == TRUE\n"); -+ -+ for (i = 0; i < prFwHead->u4NumOfEntries; i++) { -+ -+#if CFG_START_ADDRESS_IS_1ST_SECTION_ADDR -+ if (i == 0) { -+ prRegInfo->u4StartAddress = prFwHead->arSection[i].u4DestAddr; -+ DBGLOG(INIT, TRACE, -+ "wlanAdapterStart(): FW start address 0x%08x\n", -+ prRegInfo->u4StartAddress); -+ } -+#endif -+ -+#if CFG_ENABLE_FW_DOWNLOAD_AGGREGATION -+ if (wlanImageSectionDownloadAggregated(prAdapter, -+ prFwHead->arSection[i].u4DestAddr, -+ prFwHead->arSection[i].u4Length, -+ (PUINT_8) pvFwImageMapFile + -+ prFwHead->arSection[i].u4Offset) != -+ WLAN_STATUS_SUCCESS) { -+ DBGLOG(INIT, ERROR, "Firmware scatter download failed!\n"); -+ u4Status = WLAN_STATUS_FAILURE; -+ } -+#else -+ for (j = 0; j < prFwHead->arSection[i].u4Length; j += CMD_PKT_SIZE_FOR_IMAGE) { -+ if (j + CMD_PKT_SIZE_FOR_IMAGE < prFwHead->arSection[i].u4Length) -+ u4ImgSecSize = CMD_PKT_SIZE_FOR_IMAGE; -+ else -+ u4ImgSecSize = prFwHead->arSection[i].u4Length - j; -+ -+ if (wlanImageSectionDownload(prAdapter, -+ prFwHead->arSection[i].u4DestAddr + j, -+ u4ImgSecSize, -+ (PUINT_8) pvFwImageMapFile + -+ prFwHead->arSection[i].u4Offset + j) != -+ WLAN_STATUS_SUCCESS) { -+ DBGLOG(INIT, ERROR, -+ "Firmware scatter download failed %d!\n", (int)i); -+ u4Status = WLAN_STATUS_FAILURE; -+ break; -+ } -+ } -+#endif -+ -+ /* escape from loop if any pending error occurs */ -+ if (u4Status == WLAN_STATUS_FAILURE) -+ break; -+ } -+ } else -+#endif -+#if CFG_ENABLE_FW_DOWNLOAD_AGGREGATION -+ if (wlanImageSectionDownloadAggregated(prAdapter, -+ u4FwLoadAddr, -+ u4FwImageFileLength, -+ (PUINT_8) pvFwImageMapFile) != -+ WLAN_STATUS_SUCCESS) { -+ DBGLOG(INIT, ERROR, "Firmware scatter download failed!\n"); -+ u4Status = WLAN_STATUS_FAILURE; -+ } -+#else -+ for (i = 0; i < u4FwImageFileLength; i += CMD_PKT_SIZE_FOR_IMAGE) { -+ if (i + CMD_PKT_SIZE_FOR_IMAGE < u4FwImageFileLength) -+ u4ImgSecSize = CMD_PKT_SIZE_FOR_IMAGE; -+ else -+ u4ImgSecSize = u4FwImageFileLength - i; -+ -+ if (wlanImageSectionDownload(prAdapter, -+ u4FwLoadAddr + i, -+ u4ImgSecSize, -+ (PUINT_8) pvFwImageMapFile + i) != -+ WLAN_STATUS_SUCCESS) { -+ DBGLOG(INIT, ERROR, "Firmware scatter download failed!\n"); -+ u4Status = WLAN_STATUS_FAILURE; -+ break; -+ } -+ } -+#endif -+ -+ if (u4Status != WLAN_STATUS_SUCCESS) { -+ eFailReason = RAM_CODE_DOWNLOAD_FAIL; -+ break; -+ } -+#if !CFG_ENABLE_FW_DOWNLOAD_ACK -+ /* Send INIT_CMD_ID_QUERY_PENDING_ERROR command and wait for response */ -+ if (wlanImageQueryStatus(prAdapter) != WLAN_STATUS_SUCCESS) { -+ DBGLOG(INIT, ERROR, "Firmware download failed!\n"); -+ u4Status = WLAN_STATUS_FAILURE; -+ break; -+ } -+#endif -+ -+ /* 4. send Wi-Fi Start command */ -+ DBGLOG(INIT, INFO, " send Wi-Fi Start command\n"); -+#if CFG_OVERRIDE_FW_START_ADDRESS -+ wlanConfigWifiFunc(prAdapter, TRUE, prRegInfo->u4StartAddress); -+#else -+ wlanConfigWifiFunc(prAdapter, FALSE, 0); -+#endif -+#endif -+ -+ DBGLOG(INIT, TRACE, "wlanAdapterStart(): Waiting for Ready bit..\n"); -+ /* 4 <5> check Wi-Fi FW asserts ready bit */ -+ i = 0; -+ while (1) { -+ HAL_MCR_RD(prAdapter, MCR_WCIR, &u4Value); -+ -+ if (u4Value & WCIR_WLAN_READY) { -+ DBGLOG(INIT, TRACE, "Ready bit asserted\n"); -+ break; -+ } else if (kalIsCardRemoved(prAdapter->prGlueInfo) == TRUE || fgIsBusAccessFailed == TRUE) { -+ u4Status = WLAN_STATUS_FAILURE; -+ eFailReason = WAIT_FIRMWARE_READY_FAIL; -+ break; -+ } else if (i >= CFG_RESPONSE_POLLING_TIMEOUT) { -+ UINT_32 u4MailBox0; -+ -+ nicGetMailbox(prAdapter, 0, &u4MailBox0); -+ DBGLOG(INIT, ERROR, "Waiting for Ready bit: Timeout, ID=%u\n", -+ (u4MailBox0 & 0x0000FFFF)); -+ u4Status = WLAN_STATUS_FAILURE; -+ eFailReason = WAIT_FIRMWARE_READY_FAIL; -+ break; -+ } -+ i++; -+ kalMsleep(10); -+ } -+ -+ if (u4Status == WLAN_STATUS_SUCCESS) { -+ /* 1. reset interrupt status */ -+ HAL_READ_INTR_STATUS(prAdapter, 4, (PUINT_8)&u4WHISR); -+ if (HAL_IS_TX_DONE_INTR(u4WHISR)) -+ HAL_READ_TX_RELEASED_COUNT(prAdapter, aucTxCount); -+ -+ /* 2. reset TX Resource for normal operation */ -+ nicTxResetResource(prAdapter); -+ -+ /* 3. query for permanent address by polling */ -+ wlanQueryPermanentAddress(prAdapter); -+ -+#if (CFG_SUPPORT_NIC_CAPABILITY == 1) -+ /* 4. query for NIC capability */ -+ wlanQueryNicCapability(prAdapter); -+#endif -+ /* 4.1 query for compiler flags */ -+ wlanQueryCompileFlags(prAdapter); -+ -+ /* 5. Override network address */ -+ wlanUpdateNetworkAddress(prAdapter); -+ -+ /* 6. indicate disconnection as default status */ -+ kalIndicateStatusAndComplete(prAdapter->prGlueInfo, WLAN_STATUS_MEDIA_DISCONNECT, NULL, 0); -+ } -+ -+ RECLAIM_POWER_CONTROL_TO_PM(prAdapter, FALSE); -+ -+ if (u4Status != WLAN_STATUS_SUCCESS) { -+ eFailReason = WAIT_FIRMWARE_READY_FAIL; -+ break; -+ } -+ -+ /* OID timeout timer initialize */ -+ cnmTimerInitTimer(prAdapter, -+ &prAdapter->rOidTimeoutTimer, -+ (PFN_MGMT_TIMEOUT_FUNC) wlanReleasePendingOid, (ULONG) NULL); -+ -+ /* Return Indicated Rfb list timer */ -+ cnmTimerInitTimer(prAdapter, -+ &prAdapter->rReturnIndicatedRfbListTimer, -+ (PFN_MGMT_TIMEOUT_FUNC) wlanReturnIndicatedPacketsTimeOut, (ULONG) NULL); -+ -+ /* Power state initialization */ -+ prAdapter->fgWiFiInSleepyState = FALSE; -+ prAdapter->rAcpiState = ACPI_STATE_D0; -+ -+ /* Online scan option */ -+ if (prRegInfo->fgDisOnlineScan == 0) -+ prAdapter->fgEnOnlineScan = TRUE; -+ else -+ prAdapter->fgEnOnlineScan = FALSE; -+ -+ /* Beacon lost detection option */ -+ if (prRegInfo->fgDisBcnLostDetection != 0) -+ prAdapter->fgDisBcnLostDetection = TRUE; -+ -+ /* Load compile time constant */ -+ prAdapter->rWlanInfo.u2BeaconPeriod = CFG_INIT_ADHOC_BEACON_INTERVAL; -+ prAdapter->rWlanInfo.u2AtimWindow = CFG_INIT_ADHOC_ATIM_WINDOW; -+ -+#if 1 /* set PM parameters */ -+ prAdapter->fgEnArpFilter = prRegInfo->fgEnArpFilter; -+ prAdapter->u4PsCurrentMeasureEn = prRegInfo->u4PsCurrentMeasureEn; -+ -+ prAdapter->u4UapsdAcBmp = prRegInfo->u4UapsdAcBmp; -+ -+ prAdapter->u4MaxSpLen = prRegInfo->u4MaxSpLen; -+ -+ DBGLOG(INIT, TRACE, "[1] fgEnArpFilter:0x%x, u4UapsdAcBmp:0x%x, u4MaxSpLen:0x%x", -+ prAdapter->fgEnArpFilter, prAdapter->u4UapsdAcBmp, prAdapter->u4MaxSpLen); -+ -+ prAdapter->fgEnCtiaPowerMode = FALSE; -+ -+#if CFG_SUPPORT_DBG_POWERMODE -+ prAdapter->fgEnDbgPowerMode = FALSE; -+#endif -+ -+#endif -+ -+ /* MGMT Initialization */ -+ nicInitMGMT(prAdapter, prRegInfo); -+ -+ /* Enable WZC Disassociation */ -+ prAdapter->rWifiVar.fgSupportWZCDisassociation = TRUE; -+ -+ /* Apply Rate Setting */ -+ if ((ENUM_REGISTRY_FIXED_RATE_T) (prRegInfo->u4FixedRate) < FIXED_RATE_NUM) -+ prAdapter->rWifiVar.eRateSetting = (ENUM_REGISTRY_FIXED_RATE_T) (prRegInfo->u4FixedRate); -+ else -+ prAdapter->rWifiVar.eRateSetting = FIXED_RATE_NONE; -+ -+ if (prAdapter->rWifiVar.eRateSetting == FIXED_RATE_NONE) { -+ /* Enable Auto (Long/Short) Preamble */ -+ prAdapter->rWifiVar.ePreambleType = PREAMBLE_TYPE_AUTO; -+ } else if ((prAdapter->rWifiVar.eRateSetting >= FIXED_RATE_MCS0_20M_400NS && -+ prAdapter->rWifiVar.eRateSetting <= FIXED_RATE_MCS7_20M_400NS) -+ || (prAdapter->rWifiVar.eRateSetting >= FIXED_RATE_MCS0_40M_400NS && -+ prAdapter->rWifiVar.eRateSetting <= FIXED_RATE_MCS32_400NS)) { -+ /* Force Short Preamble */ -+ prAdapter->rWifiVar.ePreambleType = PREAMBLE_TYPE_SHORT; -+ } else { -+ /* Force Long Preamble */ -+ prAdapter->rWifiVar.ePreambleType = PREAMBLE_TYPE_LONG; -+ } -+ -+ /* Disable Hidden SSID Join */ -+ prAdapter->rWifiVar.fgEnableJoinToHiddenSSID = FALSE; -+ -+ /* Enable Short Slot Time */ -+ prAdapter->rWifiVar.fgIsShortSlotTimeOptionEnable = TRUE; -+ -+ /* configure available PHY type set */ -+ nicSetAvailablePhyTypeSet(prAdapter); -+ -+#if 1 /* set PM parameters */ -+ { -+#if CFG_SUPPORT_PWR_MGT -+ prAdapter->u4PowerMode = prRegInfo->u4PowerMode; -+ prAdapter->rWlanInfo.arPowerSaveMode[NETWORK_TYPE_P2P_INDEX].ucNetTypeIndex = -+ NETWORK_TYPE_P2P_INDEX; -+ prAdapter->rWlanInfo.arPowerSaveMode[NETWORK_TYPE_P2P_INDEX].ucPsProfile = ENUM_PSP_FAST_SWITCH; -+#else -+ prAdapter->u4PowerMode = ENUM_PSP_CONTINUOUS_ACTIVE; -+#endif -+ -+ nicConfigPowerSaveProfile(prAdapter, NETWORK_TYPE_AIS_INDEX, /* FIXIT */ -+ prAdapter->u4PowerMode, FALSE); -+ } -+ -+#endif -+ -+#if CFG_SUPPORT_NVRAM -+ /* load manufacture data */ -+ wlanLoadManufactureData(prAdapter, prRegInfo); -+#endif -+ -+#ifdef CONFIG_MTK_TC1_FEATURE /* 1 //keep alive packet time change from default 30secs to 20secs. //TC01// */ -+ { -+ CMD_SW_DBG_CTRL_T rCmdSwCtrl; -+ -+ rCmdSwCtrl.u4Id = 0x90100000; -+ rCmdSwCtrl.u4Data = 30; -+ DBGLOG(INIT, TRACE, "wlanAdapterStart Keepaliveapcket 0x%x, %d\n", -+ rCmdSwCtrl.u4Id, rCmdSwCtrl.u4Data); -+ wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SW_DBG_CTRL, -+ TRUE, -+ FALSE, -+ FALSE, -+ NULL, NULL, sizeof(CMD_SW_DBG_CTRL_T), (PUINT_8) (&rCmdSwCtrl), NULL, 0); -+ } -+#endif -+ -+#if 0 -+ /* Update Auto rate parameters in FW */ -+ nicRlmArUpdateParms(prAdapter, -+ prRegInfo->u4ArSysParam0, -+ prRegInfo->u4ArSysParam1, prRegInfo->u4ArSysParam2, prRegInfo->u4ArSysParam3); -+#endif -+ -+#if (MT6620_E1_ASIC_HIFSYS_WORKAROUND == 1) -+ /* clock gating workaround */ -+ prAdapter->fgIsClockGatingEnabled = FALSE; -+#endif -+ -+ } while (FALSE); -+ -+ if (u4Status == WLAN_STATUS_SUCCESS) { -+ /* restore to hardware default */ -+ HAL_SET_INTR_STATUS_READ_CLEAR(prAdapter); -+ HAL_SET_MAILBOX_READ_CLEAR(prAdapter, FALSE); -+ -+ /* Enable interrupt */ -+ nicEnableInterrupt(prAdapter); -+ -+ } else { -+ /* release allocated memory */ -+ switch (eFailReason) { -+ case WAIT_FIRMWARE_READY_FAIL: -+ DBGLOG(INIT, ERROR, "Wait firmware ready fail, FailReason: %d\n", -+ eFailReason); -+ g_IsNeedDoChipReset = 1; -+ kalSendAeeWarning("[Wait firmware ready fail!]", __func__); -+ KAL_WAKE_LOCK_DESTROY(prAdapter, &prAdapter->rTxThreadWakeLock); -+ nicRxUninitialize(prAdapter); -+ nicTxRelease(prAdapter); -+ /* System Service Uninitialization */ -+ nicUninitSystemService(prAdapter); -+ nicReleaseAdapterMemory(prAdapter); -+ break; -+ case RAM_CODE_DOWNLOAD_FAIL: -+ DBGLOG(INIT, ERROR, "Ram code download fail, FailReason: %d\n", -+ eFailReason); -+ g_IsNeedDoChipReset = 1; -+ kalSendAeeWarning("[Ram code download fail!]", __func__); -+ KAL_WAKE_LOCK_DESTROY(prAdapter, &prAdapter->rTxThreadWakeLock); -+ nicRxUninitialize(prAdapter); -+ nicTxRelease(prAdapter); -+ /* System Service Uninitialization */ -+ nicUninitSystemService(prAdapter); -+ nicReleaseAdapterMemory(prAdapter); -+ break; -+ case INIT_ADAPTER_FAIL: -+ nicReleaseAdapterMemory(prAdapter); -+ break; -+ case DRIVER_OWN_FAIL: -+ nicReleaseAdapterMemory(prAdapter); -+ break; -+ case ALLOC_ADAPTER_MEM_FAIL: -+ break; -+ default: -+ break; -+ } -+ } -+ -+ return u4Status; -+} /* wlanAdapterStart */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Uninitialize the adapter -+* -+* \param prAdapter Pointer of Adapter Data Structure -+* -+* \retval WLAN_STATUS_SUCCESS: Success -+* \retval WLAN_STATUS_FAILURE: Failed -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS wlanAdapterStop(IN P_ADAPTER_T prAdapter) -+{ -+ UINT_32 i, u4Value = 0; -+ WLAN_STATUS u4Status = WLAN_STATUS_SUCCESS; -+ -+ ASSERT(prAdapter); -+ -+#if (MT6620_E1_ASIC_HIFSYS_WORKAROUND == 1) -+ if (prAdapter->fgIsClockGatingEnabled == TRUE) -+ nicDisableClockGating(prAdapter); -+#endif -+ -+ /* MGMT - unitialization */ -+ nicUninitMGMT(prAdapter); -+ -+ if (prAdapter->rAcpiState == ACPI_STATE_D0 && -+#if (CFG_CHIP_RESET_SUPPORT == 1) -+ kalIsResetting() == FALSE && -+#endif -+ kalIsCardRemoved(prAdapter->prGlueInfo) == FALSE) { -+ -+ /* 0. Disable interrupt, this can be done without Driver own */ -+ nicDisableInterrupt(prAdapter); -+ -+ ACQUIRE_POWER_CONTROL_FROM_PM(prAdapter); -+ -+ /* 1. Set CMD to FW to tell WIFI to stop (enter power off state) */ -+ /* the command must be issue to firmware even in wlanRemove() */ -+ if (prAdapter->fgIsFwOwn == FALSE && wlanSendNicPowerCtrlCmd(prAdapter, 1) == WLAN_STATUS_SUCCESS) { -+ /* 2. Clear pending interrupt */ -+ i = 0; -+ while (i < CFG_IST_LOOP_COUNT && nicProcessIST(prAdapter) != WLAN_STATUS_NOT_INDICATING) { -+ i++; -+ }; -+ -+ /* 3. Wait til RDY bit has been cleaerd */ -+ i = 0; -+ while (1) { -+ HAL_MCR_RD(prAdapter, MCR_WCIR, &u4Value); -+ -+ if ((u4Value & WCIR_WLAN_READY) == 0) -+ break; -+ else if (kalIsCardRemoved(prAdapter->prGlueInfo) == TRUE -+ || fgIsBusAccessFailed == TRUE || i >= CFG_RESPONSE_POLLING_TIMEOUT) { -+ g_IsNeedDoChipReset = 1; -+ kalSendAeeWarning("[Read WCIR_WLAN_READY fail!]", __func__); -+ break; -+ } -+ i++; -+ kalMsleep(10); -+ } -+ } -+ -+ /* 4. Set Onwership to F/W */ -+ nicpmSetFWOwn(prAdapter, FALSE); -+ -+#if CFG_FORCE_RESET_UNDER_BUS_ERROR -+ if (HAL_TEST_FLAG(prAdapter, ADAPTER_FLAG_HW_ERR) == TRUE) { -+ /* force acquire firmware own */ -+ kalDevRegWrite(prAdapter->prGlueInfo, MCR_WHLPCR, WHLPCR_FW_OWN_REQ_CLR); -+ -+ /* delay for 10ms */ -+ kalMdelay(10); -+ -+ /* force firmware reset via software interrupt */ -+ kalDevRegWrite(prAdapter->prGlueInfo, MCR_WSICR, WSICR_H2D_SW_INT_SET); -+ -+ /* force release firmware own */ -+ kalDevRegWrite(prAdapter->prGlueInfo, MCR_WHLPCR, WHLPCR_FW_OWN_REQ_SET); -+ } -+#endif -+ -+ RECLAIM_POWER_CONTROL_TO_PM(prAdapter, FALSE); -+ } -+ -+ nicRxUninitialize(prAdapter); -+ -+ nicTxRelease(prAdapter); -+ -+ /* System Service Uninitialization */ -+ nicUninitSystemService(prAdapter); -+ -+ nicReleaseAdapterMemory(prAdapter); -+ -+#if defined(_HIF_SPI) -+ /* Note: restore the SPI Mode Select from 32 bit to default */ -+ nicRestoreSpiDefMode(prAdapter); -+#endif -+ -+ return u4Status; -+} /* wlanAdapterStop */ -+ -+#if 0 -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is called by ISR (interrupt). -+* -+* \param prAdapter Pointer of Adapter Data Structure -+* -+* \retval TRUE: NIC's interrupt -+* \retval FALSE: Not NIC's interrupt -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN wlanISR(IN P_ADAPTER_T prAdapter, IN BOOLEAN fgGlobalIntrCtrl) -+{ -+ ASSERT(prAdapter); -+ -+ if (fgGlobalIntrCtrl) { -+ nicDisableInterrupt(prAdapter); -+ -+ /* wlanIST(prAdapter); */ -+ } -+ -+ return TRUE; -+} -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is called by IST (task_let). -+* -+* \param prAdapter Pointer of Adapter Data Structure -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID wlanIST(IN P_ADAPTER_T prAdapter) -+{ -+ ASSERT(prAdapter); -+ -+ /* wake up CONNSYS */ -+ ACQUIRE_POWER_CONTROL_FROM_PM(prAdapter); -+ -+ /* handle interrupts */ -+ nicProcessIST(prAdapter); -+ -+ /* re-enable HIF interrupts */ -+ nicEnableInterrupt(prAdapter); -+ -+ /* CONNSYS can decide to sleep */ -+ RECLAIM_POWER_CONTROL_TO_PM(prAdapter, FALSE); -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will check command queue to find out if any could be dequeued -+* and/or send to HIF to MT6620 -+* -+* \param prAdapter Pointer of Adapter Data Structure -+* \param prCmdQue Pointer of Command Queue (in Glue Layer) -+* -+* \retval WLAN_STATUS_SUCCESS -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS wlanProcessCommandQueue(IN P_ADAPTER_T prAdapter, IN P_QUE_T prCmdQue) -+{ -+ WLAN_STATUS rStatus; -+ QUE_T rTempCmdQue, rMergeCmdQue, rStandInCmdQue; -+ P_QUE_T prTempCmdQue, prMergeCmdQue, prStandInCmdQue; -+ P_QUE_ENTRY_T prQueueEntry; -+ P_CMD_INFO_T prCmdInfo; -+ P_MSDU_INFO_T prMsduInfo; -+ ENUM_FRAME_ACTION_T eFrameAction = FRAME_ACTION_DROP_PKT; -+ -+ KAL_SPIN_LOCK_DECLARATION(); -+ -+ /* sanity check */ -+ ASSERT(prAdapter); -+ ASSERT(prCmdQue); -+ -+ /* init */ -+ prTempCmdQue = &rTempCmdQue; -+ prMergeCmdQue = &rMergeCmdQue; -+ prStandInCmdQue = &rStandInCmdQue; -+ -+ QUEUE_INITIALIZE(prTempCmdQue); -+ QUEUE_INITIALIZE(prMergeCmdQue); -+ QUEUE_INITIALIZE(prStandInCmdQue); -+ -+ /* 4 <1> Move whole list of CMD_INFO to the temp queue */ -+ /* copy all commands to prTempCmdQue and empty prCmdQue */ -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_QUE); -+ QUEUE_MOVE_ALL(prTempCmdQue, prCmdQue); -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_QUE); -+ -+ /* 4 <2> Dequeue from head and check it is able to be sent */ -+ /* remove the first one */ -+ QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T); -+ -+ while (prQueueEntry) { -+ prCmdInfo = (P_CMD_INFO_T) prQueueEntry; -+ -+ /* check how to handle the command: drop, queue, or tx */ -+ switch (prCmdInfo->eCmdType) { -+ case COMMAND_TYPE_GENERAL_IOCTL: -+ case COMMAND_TYPE_NETWORK_IOCTL: -+ /* command packet will be always sent */ -+ eFrameAction = FRAME_ACTION_TX_PKT; -+ break; -+ -+ case COMMAND_TYPE_SECURITY_FRAME: -+ /* inquire with QM */ -+ eFrameAction = qmGetFrameAction(prAdapter, -+ prCmdInfo->eNetworkType, -+ prCmdInfo->ucStaRecIndex, NULL, FRAME_TYPE_802_1X); -+ break; -+ -+ case COMMAND_TYPE_MANAGEMENT_FRAME: -+ /* inquire with QM */ -+ prMsduInfo = (P_MSDU_INFO_T) (prCmdInfo->prPacket); -+ -+ eFrameAction = qmGetFrameAction(prAdapter, -+ prMsduInfo->ucNetworkType, -+ prMsduInfo->ucStaRecIndex, prMsduInfo, FRAME_TYPE_MMPDU); -+ break; -+ -+ default: -+ ASSERT(0); -+ break; -+ } -+ -+ /* 4 <3> handling upon dequeue result */ -+ if (eFrameAction == FRAME_ACTION_DROP_PKT) { -+ if (prCmdInfo->eCmdType == COMMAND_TYPE_SECURITY_FRAME) -+ DBGLOG(TX, WARN, "Drop Security frame seqNo=%d\n", -+ prCmdInfo->ucCmdSeqNum); -+ wlanReleaseCommand(prAdapter, prCmdInfo); -+ } else if (eFrameAction == FRAME_ACTION_QUEUE_PKT) { -+ if (prCmdInfo->eCmdType == COMMAND_TYPE_SECURITY_FRAME) -+ DBGLOG(TX, INFO, "Queue Security frame seqNo=%d\n", -+ prCmdInfo->ucCmdSeqNum); -+ QUEUE_INSERT_TAIL(prMergeCmdQue, prQueueEntry); -+ } else if (eFrameAction == FRAME_ACTION_TX_PKT) { -+ /* 4 <4> Send the command */ -+ rStatus = wlanSendCommand(prAdapter, prCmdInfo); -+ -+ if (rStatus == WLAN_STATUS_RESOURCES) { -+ /* no more TC4 resource for further transmission */ -+ QUEUE_INSERT_TAIL(prMergeCmdQue, prQueueEntry); -+ DBGLOG(TX, EVENT, "No TC4 resource to send cmd, CID=%d, SEQ=%d, CMD type=%d, OID=%d\n", -+ prCmdInfo->ucCID, prCmdInfo->ucCmdSeqNum, -+ prCmdInfo->eCmdType, prCmdInfo->fgIsOid); -+ break; -+ } else if (rStatus == WLAN_STATUS_PENDING) { -+ /* command packet which needs further handling upon response */ -+ /* i.e. we need to wait for FW's response */ -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_PENDING); -+ QUEUE_INSERT_TAIL(&(prAdapter->rPendingCmdQueue), prQueueEntry); -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_PENDING); -+ } else { -+ /* send success or fail */ -+ P_CMD_INFO_T prCmdInfo = (P_CMD_INFO_T) prQueueEntry; -+ -+ if (rStatus == WLAN_STATUS_SUCCESS) { -+ /* send success */ -+ if (prCmdInfo->pfCmdDoneHandler) { -+ prCmdInfo->pfCmdDoneHandler(prAdapter, prCmdInfo, -+ prCmdInfo->pucInfoBuffer); -+ } -+ } else { -+ /* send fail */ -+ if (prCmdInfo->fgIsOid) { -+ kalOidComplete(prAdapter->prGlueInfo, prCmdInfo->fgSetQuery, -+ prCmdInfo->u4SetInfoLen, rStatus); -+ } -+ DBGLOG(TX, WARN, "Send CMD, status=%u, CID=%d, SEQ=%d, CMD type=%d, OID=%d\n", -+ rStatus, prCmdInfo->ucCID, prCmdInfo->ucCmdSeqNum, -+ prCmdInfo->eCmdType, prCmdInfo->fgIsOid); -+ } -+ -+ /* free the command memory */ -+ cmdBufFreeCmdInfo(prAdapter, prCmdInfo); -+ } -+ } else { -+ -+ /* impossible, wrong eFrameAction */ -+ ASSERT(0); -+ } -+ -+ QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T); -+ } -+ -+ /* 4 <3> Merge back to original queue */ -+ /* 4 <3.1> Merge prMergeCmdQue & prTempCmdQue */ -+ QUEUE_CONCATENATE_QUEUES(prMergeCmdQue, prTempCmdQue); -+ -+ /* 4 <3.2> Move prCmdQue to prStandInQue, due to prCmdQue might differ due to incoming 802.1X frames */ -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_QUE); -+ -+ /* ??? here, prCmdQue shall be empty, why QUEUE_MOVE_ALL ??? */ -+ QUEUE_MOVE_ALL(prStandInCmdQue, prCmdQue); -+ -+ /* 4 <3.3> concatenate prStandInQue to prMergeCmdQue */ -+ QUEUE_CONCATENATE_QUEUES(prMergeCmdQue, prStandInCmdQue); -+ -+ /* 4 <3.4> then move prMergeCmdQue to prCmdQue */ -+ QUEUE_MOVE_ALL(prCmdQue, prMergeCmdQue); -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_QUE); -+ -+ return WLAN_STATUS_SUCCESS; -+} /* end of wlanProcessCommandQueue() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will take CMD_INFO_T which carry some information of -+* incoming OID and notify the NIC_TX to send CMD. -+* -+* \param prAdapter Pointer of Adapter Data Structure -+* \param prCmdInfo Pointer of P_CMD_INFO_T -+* -+* \retval WLAN_STATUS_SUCCESS : CMD was written to HIF and be freed(CMD Done) immediately. -+* \retval WLAN_STATUS_RESOURCE : No resource for current command, need to wait for previous -+* frame finishing their transmission. -+* \retval WLAN_STATUS_FAILURE : Get failure while access HIF or been rejected. -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS wlanSendCommand(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo) -+{ -+ P_TX_CTRL_T prTxCtrl; -+ UINT_8 ucTC; /* "Traffic Class" SW(Driver) resource classification */ -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ BOOLEAN pfgIsSecOrMgmt = FALSE; -+ -+ /* sanity check */ -+ ASSERT(prAdapter); -+ ASSERT(prCmdInfo); -+ -+ /* init */ -+ prTxCtrl = &prAdapter->rTxCtrl; -+ -+ /* DbgPrint("wlanSendCommand()\n"); */ -+ /* */ -+ /* */ -+#if DBG && 0 -+ LOG_FUNC("wlanSendCommand()\n"); -+ LOG_FUNC("CmdType %u NetworkType %u StaRecIndex %u Oid %u CID 0x%x SetQuery %u NeedResp %u CmdSeqNum %u\n", -+ prCmdInfo->eCmdType, -+ prCmdInfo->eNetworkType, -+ prCmdInfo->ucStaRecIndex, -+ prCmdInfo->fgIsOid, -+ prCmdInfo->ucCID, prCmdInfo->fgSetQuery, prCmdInfo->fgNeedResp, prCmdInfo->ucCmdSeqNum); -+#endif -+ -+#if (MT6620_E1_ASIC_HIFSYS_WORKAROUND == 1) -+ if (prAdapter->fgIsClockGatingEnabled == TRUE) -+ nicDisableClockGating(prAdapter); -+#endif -+ -+ do { -+ /* <0> card removal check */ -+ if (kalIsCardRemoved(prAdapter->prGlueInfo) == TRUE || fgIsBusAccessFailed == TRUE) { -+ rStatus = WLAN_STATUS_FAILURE; -+ break; -+ } -+ /* <1> Normal case of sending CMD Packet */ -+ if (!prCmdInfo->fgDriverDomainMCR) { -+ /* <1.1> Assign Traffic Class(TC) = TC4. */ -+ ucTC = TC4_INDEX; -+ -+ if ((prCmdInfo->eCmdType == COMMAND_TYPE_SECURITY_FRAME) || -+ (prCmdInfo->eCmdType == COMMAND_TYPE_MANAGEMENT_FRAME)) -+ pfgIsSecOrMgmt = TRUE; -+ -+ /* <1.2> Check if pending packet or resource was exhausted */ -+ rStatus = nicTxAcquireResource(prAdapter, ucTC, pfgIsSecOrMgmt); -+ if (rStatus == WLAN_STATUS_RESOURCES) { -+ DbgPrint("NO Resource:%d\n", ucTC); -+ break; -+ } -+ /* <1.3> Forward CMD_INFO_T to NIC Layer */ -+ rStatus = nicTxCmd(prAdapter, prCmdInfo, ucTC); -+ -+ /* <1.4> Set Pending in response to Query Command/Need Response */ -+ if (rStatus == WLAN_STATUS_SUCCESS) { -+ if ((!prCmdInfo->fgSetQuery) || (prCmdInfo->fgNeedResp)) -+ rStatus = WLAN_STATUS_PENDING; -+ } -+ } -+ /* <2> "Special case" for access Driver Domain MCR */ -+ else { -+ -+ P_CMD_ACCESS_REG prCmdAccessReg; -+ -+ prCmdAccessReg = (P_CMD_ACCESS_REG) (prCmdInfo->pucInfoBuffer + CMD_HDR_SIZE); -+ -+ if (prCmdInfo->fgSetQuery) { -+ /* address is in DWORD unit */ -+ HAL_MCR_WR(prAdapter, (prCmdAccessReg->u4Address & BITS(2, 31)), -+ prCmdAccessReg->u4Data); -+ } else { -+ P_CMD_ACCESS_REG prEventAccessReg; -+ UINT_32 u4Address; -+ -+ u4Address = prCmdAccessReg->u4Address; -+ prEventAccessReg = (P_CMD_ACCESS_REG) prCmdInfo->pucInfoBuffer; -+ prEventAccessReg->u4Address = u4Address; -+ /* address is in DWORD unit */ -+ HAL_MCR_RD(prAdapter, prEventAccessReg->u4Address & BITS(2, 31), -+ &prEventAccessReg->u4Data); -+ } -+ } -+ -+ } while (FALSE); -+ -+#if (MT6620_E1_ASIC_HIFSYS_WORKAROUND == 1) -+ if (prAdapter->fgIsClockGatingEnabled == FALSE) -+ nicEnableClockGating(prAdapter); -+#endif -+ -+ return rStatus; -+} /* end of wlanSendCommand() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * \brief This function will release thd CMD_INFO upon its attribution -+ * -+ * \param prAdapter Pointer of Adapter Data Structure -+ * \param prCmdInfo Pointer of CMD_INFO_T -+ * -+ * \return (none) -+ */ -+/*----------------------------------------------------------------------------*/ -+VOID wlanReleaseCommand(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo) -+{ -+ P_TX_CTRL_T prTxCtrl; -+ P_MSDU_INFO_T prMsduInfo; -+ -+ ASSERT(prAdapter); -+ ASSERT(prCmdInfo); -+ -+ prTxCtrl = &prAdapter->rTxCtrl; -+ -+ switch (prCmdInfo->eCmdType) { -+ case COMMAND_TYPE_GENERAL_IOCTL: -+ case COMMAND_TYPE_NETWORK_IOCTL: -+ if (prCmdInfo->fgIsOid) { -+ /* for OID command, we need to do complete() to wake up kalIoctl() */ -+ kalOidComplete(prAdapter->prGlueInfo, -+ prCmdInfo->fgSetQuery, prCmdInfo->u4SetInfoLen, WLAN_STATUS_FAILURE); -+ } -+ break; -+ -+ case COMMAND_TYPE_SECURITY_FRAME: -+ /* free packets in kalSecurityFrameSendComplete() */ -+ kalSecurityFrameSendComplete(prAdapter->prGlueInfo, prCmdInfo->prPacket, WLAN_STATUS_FAILURE); -+ break; -+ -+ case COMMAND_TYPE_MANAGEMENT_FRAME: -+ prMsduInfo = (P_MSDU_INFO_T) prCmdInfo->prPacket; -+ -+ /* invoke callbacks */ -+ if (prMsduInfo->pfTxDoneHandler != NULL) -+ prMsduInfo->pfTxDoneHandler(prAdapter, prMsduInfo, TX_RESULT_DROPPED_IN_DRIVER); -+ -+ GLUE_DEC_REF_CNT(prTxCtrl->i4TxMgmtPendingNum); -+ cnmMgtPktFree(prAdapter, prMsduInfo); -+ break; -+ -+ default: -+ /* impossible, shall not be here */ -+ ASSERT(0); -+ break; -+ } -+ -+ /* free command buffer and return the command header to command pool */ -+ cmdBufFreeCmdInfo(prAdapter, prCmdInfo); -+ -+} /* end of wlanReleaseCommand() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will search the CMD Queue to look for the pending OID and -+* compelete it immediately when system request a reset. -+* -+* \param prAdapter ointer of Adapter Data Structure -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID wlanReleasePendingOid(IN P_ADAPTER_T prAdapter, IN ULONG ulData) -+{ -+ P_QUE_T prCmdQue; -+ QUE_T rTempCmdQue; -+ P_QUE_T prTempCmdQue = &rTempCmdQue; -+ P_QUE_ENTRY_T prQueueEntry = (P_QUE_ENTRY_T) NULL; -+ P_CMD_INFO_T prCmdInfo = (P_CMD_INFO_T) NULL; -+ -+ KAL_SPIN_LOCK_DECLARATION(); -+ -+ DEBUGFUNC("wlanReleasePendingOid"); -+ -+ ASSERT(prAdapter); -+ -+ DBGLOG(OID, ERROR, "OID Timeout! Releasing pending OIDs ..\n"); -+ -+ do { -+ /* 1: Handle OID commands in pending queue */ -+ /* Clear Pending OID in prAdapter->rPendingCmdQueue */ -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_PENDING); -+ -+ /* move all pending commands to prTempCmdQue and empty prCmdQue */ -+ prCmdQue = &prAdapter->rPendingCmdQueue; -+ QUEUE_MOVE_ALL(prTempCmdQue, prCmdQue); -+ -+ /* get first pending command */ -+ QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T); -+ -+ while (prQueueEntry) { -+ prCmdInfo = (P_CMD_INFO_T) prQueueEntry; -+ -+ if (prCmdInfo->fgIsOid) { -+ if (prCmdInfo->pfCmdTimeoutHandler) { -+ prCmdInfo->pfCmdTimeoutHandler(prAdapter, prCmdInfo); -+ } else { -+ /* send complete() to wake up kalIoctl() */ -+ kalOidComplete(prAdapter->prGlueInfo, -+ prCmdInfo->fgSetQuery, 0, WLAN_STATUS_FAILURE); -+ } -+ -+ /* free command memory */ -+ cmdBufFreeCmdInfo(prAdapter, prCmdInfo); -+ } else { -+ /* nothing to do so re-queue it to prCmdQue */ -+ QUEUE_INSERT_TAIL(prCmdQue, prQueueEntry); -+ } -+ -+ QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T); -+ } -+ -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_PENDING); -+ -+ /* 2: Clear pending OID staying in command queue */ -+ kalOidCmdClearance(prAdapter->prGlueInfo); -+ -+ /* 3: Do complete(), do we need this? because we have completed in kalOidComplete */ -+ kalOidClearance(prAdapter->prGlueInfo); -+ -+ } while (FALSE); -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will search the CMD Queue to look for the pending CMD/OID for specific -+* NETWORK TYPE and compelete it immediately when system request a reset. -+* -+* \param prAdapter ointer of Adapter Data Structure -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID wlanReleasePendingCMDbyNetwork(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkType) -+{ -+ P_QUE_T prCmdQue; -+ QUE_T rTempCmdQue; -+ P_QUE_T prTempCmdQue = &rTempCmdQue; -+ P_QUE_ENTRY_T prQueueEntry = (P_QUE_ENTRY_T) NULL; -+ P_CMD_INFO_T prCmdInfo = (P_CMD_INFO_T) NULL; -+ -+ KAL_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(prAdapter); -+ -+ /* only free commands from the network interface, AIS, P2P, or BOW */ -+ -+ do { -+ /* 1: Clear Pending OID in prAdapter->rPendingCmdQueue */ -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_PENDING); -+ -+ prCmdQue = &prAdapter->rPendingCmdQueue; -+ QUEUE_MOVE_ALL(prTempCmdQue, prCmdQue); -+ -+ QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T); -+ while (prQueueEntry) { -+ prCmdInfo = (P_CMD_INFO_T) prQueueEntry; -+ -+ DBGLOG(P2P, TRACE, "Pending CMD for Network Type:%d\n", prCmdInfo->eNetworkType); -+ -+ if (prCmdInfo->eNetworkType == eNetworkType) { -+ if (prCmdInfo->pfCmdTimeoutHandler) { -+ prCmdInfo->pfCmdTimeoutHandler(prAdapter, prCmdInfo); -+ } else -+ kalOidComplete(prAdapter->prGlueInfo, -+ prCmdInfo->fgSetQuery, 0, WLAN_STATUS_FAILURE); -+ -+ cmdBufFreeCmdInfo(prAdapter, prCmdInfo); -+ } else { -+ QUEUE_INSERT_TAIL(prCmdQue, prQueueEntry); -+ } -+ -+ QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T); -+ } -+ -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_PENDING); -+ -+ } while (FALSE); -+ -+} /* wlanReleasePendingCMDbyNetwork */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Return the packet buffer and reallocate one to the RFB -+* -+* \param prAdapter Pointer of Adapter Data Structure -+* \param pvPacket Pointer of returned packet -+* -+* \retval WLAN_STATUS_SUCCESS: Success -+* \retval WLAN_STATUS_FAILURE: Failed -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID wlanReturnPacket(IN P_ADAPTER_T prAdapter, IN PVOID pvPacket) -+{ -+ P_RX_CTRL_T prRxCtrl; -+ P_SW_RFB_T prSwRfb = NULL; -+ -+ KAL_SPIN_LOCK_DECLARATION(); -+ -+ DEBUGFUNC("wlanReturnPacket"); -+ -+ ASSERT(prAdapter); -+ -+ prRxCtrl = &prAdapter->rRxCtrl; -+ ASSERT(prRxCtrl); -+ -+ /* free the packet */ -+ if (pvPacket) { -+ kalPacketFree(prAdapter->prGlueInfo, pvPacket); -+ RX_ADD_CNT(prRxCtrl, RX_DATA_RETURNED_COUNT, 1); -+#if CFG_NATIVE_802_11 -+ if (GLUE_TEST_FLAG(prAdapter->prGlueInfo, GLUE_FLAG_HALT)) { -+ /*Todo:: nothing*/ -+ /*Todo:: nothing*/ -+ } -+#endif -+ } -+ -+ /* free the packet control block */ -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); -+ QUEUE_REMOVE_HEAD(&prRxCtrl->rIndicatedRfbList, prSwRfb, P_SW_RFB_T); -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); -+ if (!prSwRfb) { -+ ASSERT(0); -+ return; -+ } -+ -+ if (nicRxSetupRFB(prAdapter, prSwRfb)) { -+ ASSERT(0); -+ /* return; // Don't return here or it would lost SwRfb --kc */ -+ if (!timerPendingTimer(&prAdapter->rReturnIndicatedRfbListTimer)) { -+ DBGLOG(RX, WARN, -+ "wlanReturnPacket, Start ReturnIndicatedRfbList Timer (%ds)\n", -+ RX_RETURN_INDICATED_RFB_TIMEOUT_SEC); -+ cnmTimerStartTimer(prAdapter, &prAdapter->rReturnIndicatedRfbListTimer, -+ SEC_TO_MSEC(RX_RETURN_INDICATED_RFB_TIMEOUT_SEC)); -+ } -+ } -+ nicRxReturnRFB(prAdapter, prSwRfb); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Return the indicated packet buffer and reallocate one to the RFB -+* -+* \param prAdapter Pointer of Adapter Data Structure -+* \param pvPacket Pointer of returned packet -+* -+* \retval WLAN_STATUS_SUCCESS: Success -+* \retval WLAN_STATUS_FAILURE: Failed -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID wlanReturnIndicatedPacketsTimeOut(IN P_ADAPTER_T prAdapter, IN ULONG ulData) -+{ -+ P_RX_CTRL_T prRxCtrl; -+ P_SW_RFB_T prSwRfb = NULL; -+ -+ KAL_SPIN_LOCK_DECLARATION(); -+ WLAN_STATUS status = WLAN_STATUS_SUCCESS; -+ P_QUE_T prQueList; -+ -+ DEBUGFUNC("wlanReturnIndicatedPacketsTimeOut"); -+ DBGLOG(RX, WARN, "wlanReturnIndicatedPacketsTimeOut"); -+ -+ ASSERT(prAdapter); -+ -+ prRxCtrl = &prAdapter->rRxCtrl; -+ ASSERT(prRxCtrl); -+ -+ prQueList = &prRxCtrl->rIndicatedRfbList; -+ DBGLOG(RX, WARN, "IndicatedRfbList num = %u\n", (unsigned int)prQueList->u4NumElem); -+ -+ while (QUEUE_IS_NOT_EMPTY(&prRxCtrl->rIndicatedRfbList)) { -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); -+ QUEUE_REMOVE_HEAD(&prRxCtrl->rIndicatedRfbList, prSwRfb, P_SW_RFB_T); -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); -+ -+ if (nicRxSetupRFB(prAdapter, prSwRfb)) { -+ status = WLAN_STATUS_RESOURCES; -+ ASSERT(0); -+ } -+ nicRxReturnRFB(prAdapter, prSwRfb); -+ if (status == WLAN_STATUS_RESOURCES) -+ break; -+ } -+ if (status == WLAN_STATUS_RESOURCES) { -+ DBGLOG(RX, WARN, "Start ReturnIndicatedRfbList Timer (%ds)\n", RX_RETURN_INDICATED_RFB_TIMEOUT_SEC); -+ /* restart timer */ -+ cnmTimerStartTimer(prAdapter, -+ &prAdapter->rReturnIndicatedRfbListTimer, -+ SEC_TO_MSEC(RX_RETURN_INDICATED_RFB_TIMEOUT_SEC)); -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is a required function that returns information about -+* the capabilities and status of the driver and/or its network adapter. -+* -+* \param[IN] prAdapter Pointer to the Adapter structure. -+* \param[IN] pfnOidQryHandler Function pointer for the OID query handler. -+* \param[IN] pvInfoBuf Points to a buffer for return the query information. -+* \param[IN] u4QueryBufferLen Specifies the number of bytes at pvInfoBuf. -+* \param[OUT] pu4QueryInfoLen Points to the number of bytes it written or is needed. -+* -+* \retval WLAN_STATUS_xxx Different WLAN_STATUS code returned by different handlers. -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanQueryInformation(IN P_ADAPTER_T prAdapter, -+ IN PFN_OID_HANDLER_FUNC pfnOidQryHandler, -+ IN PVOID pvInfoBuf, IN UINT_32 u4InfoBufLen, OUT PUINT_32 pu4QryInfoLen) -+{ -+ WLAN_STATUS status = WLAN_STATUS_FAILURE; -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4QryInfoLen); -+ -+ /* ignore any OID request after connected, under PS current measurement mode */ -+ /* note: return WLAN_STATUS_FAILURE or WLAN_STATUS_SUCCESS for -+ * blocking OIDs during current measurement -+ */ -+ if (prAdapter->u4PsCurrentMeasureEn && -+ (prAdapter->prGlueInfo->eParamMediaStateIndicated == PARAM_MEDIA_STATE_CONNECTED)) -+ return WLAN_STATUS_SUCCESS; -+#if 1 -+ /* most OID handler will just queue a command packet */ -+ status = pfnOidQryHandler(prAdapter, pvInfoBuf, u4InfoBufLen, pu4QryInfoLen); -+#else -+ if (wlanIsHandlerNeedHwAccess(pfnOidQryHandler, FALSE)) { -+ ACQUIRE_POWER_CONTROL_FROM_PM(prAdapter); -+ -+ /* Reset sleepy state */ -+ if (prAdapter->fgWiFiInSleepyState == TRUE) -+ prAdapter->fgWiFiInSleepyState = FALSE; -+ -+ status = pfnOidQryHandler(prAdapter, pvInfoBuf, u4InfoBufLen, pu4QryInfoLen); -+ -+ RECLAIM_POWER_CONTROL_TO_PM(prAdapter, FALSE); -+ } else -+ status = pfnOidQryHandler(prAdapter, pvInfoBuf, u4InfoBufLen, pu4QryInfoLen); -+#endif -+ -+ return status; -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is a required function that allows bound protocol drivers, -+* or NDIS, to request changes in the state information that the miniport -+* maintains for particular object identifiers, such as changes in multicast -+* addresses. -+* -+* \param[IN] prAdapter Pointer to the Glue info structure. -+* \param[IN] pfnOidSetHandler Points to the OID set handlers. -+* \param[IN] pvInfoBuf Points to a buffer containing the OID-specific data for the set. -+* \param[IN] u4InfoBufLen Specifies the number of bytes at prSetBuffer. -+* \param[OUT] pu4SetInfoLen Points to the number of bytes it read or is needed. -+* -+* \retval WLAN_STATUS_xxx Different WLAN_STATUS code returned by different handlers. -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanSetInformation(IN P_ADAPTER_T prAdapter, -+ IN PFN_OID_HANDLER_FUNC pfnOidSetHandler, -+ IN PVOID pvInfoBuf, IN UINT_32 u4InfoBufLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ WLAN_STATUS status = WLAN_STATUS_FAILURE; -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ /* ignore any OID request after connected, under PS current measurement mode */ -+ /* note: return WLAN_STATUS_FAILURE or WLAN_STATUS_SUCCESS for blocking -+ * OIDs during current measurement -+ */ -+ if (prAdapter->u4PsCurrentMeasureEn && -+ (prAdapter->prGlueInfo->eParamMediaStateIndicated == PARAM_MEDIA_STATE_CONNECTED)) -+ return WLAN_STATUS_SUCCESS; -+#if 1 -+ /* most OID handler will just queue a command packet -+ * for power state transition OIDs, handler will acquire power control by itself -+ */ -+ status = pfnOidSetHandler(prAdapter, pvInfoBuf, u4InfoBufLen, pu4SetInfoLen); -+#else -+ if (wlanIsHandlerNeedHwAccess(pfnOidSetHandler, TRUE)) { -+ ACQUIRE_POWER_CONTROL_FROM_PM(prAdapter); -+ -+ /* Reset sleepy state */ -+ if (prAdapter->fgWiFiInSleepyState == TRUE) -+ prAdapter->fgWiFiInSleepyState = FALSE; -+ -+ status = pfnOidSetHandler(prAdapter, pvInfoBuf, u4InfoBufLen, pu4SetInfoLen); -+ -+ RECLAIM_POWER_CONTROL_TO_PM(prAdapter, FALSE); -+ } else { -+ status = pfnOidSetHandler(prAdapter, pvInfoBuf, u4InfoBufLen, pu4SetInfoLen); -+ } -+#endif -+ -+ return status; -+} -+ -+#if CFG_SUPPORT_WAPI -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is a used to query driver's config wapi mode or not -+* -+* \param[IN] prAdapter Pointer to the Glue info structure. -+* -+* \retval TRUE for use wapi mode -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN wlanQueryWapiMode(IN P_ADAPTER_T prAdapter) -+{ -+ ASSERT(prAdapter); -+ -+ return prAdapter->rWifiVar.rConnSettings.fgWapiMode; -+} -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is called to set RX filter to Promiscuous Mode. -+* -+* \param[IN] prAdapter Pointer to the Adapter structure. -+* \param[IN] fgEnablePromiscuousMode Enable/ disable RX Promiscuous Mode. -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID wlanSetPromiscuousMode(IN P_ADAPTER_T prAdapter, IN BOOLEAN fgEnablePromiscuousMode) -+{ -+ ASSERT(prAdapter); -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is called to set RX filter to allow to receive -+* broadcast address packets. -+* -+* \param[IN] prAdapter Pointer to the Adapter structure. -+* \param[IN] fgEnableBroadcast Enable/ disable broadcast packet to be received. -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID wlanRxSetBroadcast(IN P_ADAPTER_T prAdapter, IN BOOLEAN fgEnableBroadcast) -+{ -+ ASSERT(prAdapter); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is called to send out CMD_NIC_POWER_CTRL command packet -+* -+* \param[IN] prAdapter Pointer to the Adapter structure. -+* \param[IN] ucPowerMode refer to CMD/EVENT document -+* -+* \return WLAN_STATUS_SUCCESS -+* \return WLAN_STATUS_FAILURE -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS wlanSendNicPowerCtrlCmd(IN P_ADAPTER_T prAdapter, IN UINT_8 ucPowerMode) -+{ -+ WLAN_STATUS status = WLAN_STATUS_SUCCESS; -+ P_GLUE_INFO_T prGlueInfo; -+ P_CMD_INFO_T prCmdInfo; -+ P_WIFI_CMD_T prWifiCmd; -+ UINT_8 ucTC, ucCmdSeqNum; -+ -+ ASSERT(prAdapter); -+ -+ prGlueInfo = prAdapter->prGlueInfo; -+ -+ /* 1. Prepare CMD */ -+ prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, (CMD_HDR_SIZE + sizeof(CMD_NIC_POWER_CTRL))); -+ if (!prCmdInfo) { -+ DBGLOG(INIT, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); -+ return WLAN_STATUS_FAILURE; -+ } -+ -+ /* 2.1 increase command sequence number */ -+ ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter); -+ DBGLOG(REQ, TRACE, "ucCmdSeqNum =%d\n", ucCmdSeqNum); -+ -+ /* 2.2 Setup common CMD Info Packet */ -+ prCmdInfo->eCmdType = COMMAND_TYPE_GENERAL_IOCTL; -+ prCmdInfo->u2InfoBufLen = (UINT_16) (CMD_HDR_SIZE + sizeof(CMD_NIC_POWER_CTRL)); -+ prCmdInfo->pfCmdDoneHandler = NULL; -+ prCmdInfo->pfCmdTimeoutHandler = NULL; -+ prCmdInfo->fgIsOid = TRUE; -+ prCmdInfo->ucCID = CMD_ID_NIC_POWER_CTRL; -+ prCmdInfo->fgSetQuery = TRUE; -+ prCmdInfo->fgNeedResp = FALSE; -+ prCmdInfo->fgDriverDomainMCR = FALSE; -+ prCmdInfo->ucCmdSeqNum = ucCmdSeqNum; -+ prCmdInfo->u4SetInfoLen = sizeof(CMD_NIC_POWER_CTRL); -+ -+ /* 2.3 Setup WIFI_CMD_T */ -+ prWifiCmd = (P_WIFI_CMD_T) (prCmdInfo->pucInfoBuffer); -+ prWifiCmd->u2TxByteCount_UserPriority = prCmdInfo->u2InfoBufLen; -+ prWifiCmd->ucCID = prCmdInfo->ucCID; -+ prWifiCmd->ucSetQuery = prCmdInfo->fgSetQuery; -+ prWifiCmd->ucSeqNum = prCmdInfo->ucCmdSeqNum; -+ -+ kalMemZero(prWifiCmd->aucBuffer, sizeof(CMD_NIC_POWER_CTRL)); -+ ((P_CMD_NIC_POWER_CTRL) (prWifiCmd->aucBuffer))->ucPowerMode = ucPowerMode; -+ -+ /* 3. Issue CMD for entering specific power mode */ -+ ucTC = TC4_INDEX; -+ -+ while (1) { -+ /* 3.0 Removal check */ -+ if (kalIsCardRemoved(prAdapter->prGlueInfo) == TRUE || fgIsBusAccessFailed == TRUE) { -+ status = WLAN_STATUS_FAILURE; -+ break; -+ } -+ /* 3.1 Acquire TX Resource */ -+ if (nicTxAcquireResource(prAdapter, ucTC, FALSE) == WLAN_STATUS_RESOURCES) { -+ -+ /* wait and poll tx resource */ -+ if (nicTxPollingResource(prAdapter, ucTC) != WLAN_STATUS_SUCCESS) { -+ DBGLOG(INIT, ERROR, "Fail to get TX resource return within timeout\n"); -+ status = WLAN_STATUS_FAILURE; -+ break; -+ } -+ continue; -+ } -+ /* 3.2 Send CMD Info Packet */ -+ if (nicTxCmd(prAdapter, prCmdInfo, ucTC) != WLAN_STATUS_SUCCESS) { -+ DBGLOG(INIT, ERROR, "Fail to transmit CMD_NIC_POWER_CTRL command\n"); -+ status = WLAN_STATUS_FAILURE; -+ } -+ -+ break; -+ }; -+ -+ /* 4. Free CMD Info Packet. */ -+ cmdBufFreeCmdInfo(prAdapter, prCmdInfo); -+ -+ /* 5. Add flag */ -+ if (ucPowerMode == 1) -+ prAdapter->fgIsEnterD3ReqIssued = TRUE; -+ -+ return status; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is called to check if it is RF test mode and -+* the OID is allowed to be called or not -+* -+* \param[IN] prAdapter Pointer to the Adapter structure. -+* \param[IN] fgEnableBroadcast Enable/ disable broadcast packet to be received. -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN wlanIsHandlerAllowedInRFTest(IN PFN_OID_HANDLER_FUNC pfnOidHandler, IN BOOLEAN fgSetInfo) -+{ -+ PFN_OID_HANDLER_FUNC *apfnOidHandlerAllowedInRFTest; -+ UINT_32 i; -+ UINT_32 u4NumOfElem; -+ -+ if (fgSetInfo) { -+ apfnOidHandlerAllowedInRFTest = apfnOidSetHandlerAllowedInRFTest; -+ u4NumOfElem = sizeof(apfnOidSetHandlerAllowedInRFTest) / sizeof(PFN_OID_HANDLER_FUNC); -+ } else { -+ apfnOidHandlerAllowedInRFTest = apfnOidQueryHandlerAllowedInRFTest; -+ u4NumOfElem = sizeof(apfnOidQueryHandlerAllowedInRFTest) / sizeof(PFN_OID_HANDLER_FUNC); -+ } -+ -+ for (i = 0; i < u4NumOfElem; i++) { -+ if (apfnOidHandlerAllowedInRFTest[i] == pfnOidHandler) -+ return TRUE; -+ } -+ -+ return FALSE; -+} -+ -+#if CFG_ENABLE_FW_DOWNLOAD -+#if CFG_ENABLE_FW_DOWNLOAD_AGGREGATION -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is called to download FW image in an aggregated way -+* -+* @param prAdapter Pointer to the Adapter structure. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanImageSectionDownloadAggregated(IN P_ADAPTER_T prAdapter, -+ IN UINT_32 u4DestAddr, IN UINT_32 u4ImgSecSize, IN PUINT_8 pucImgSecBuf) -+{ -+#if defined(MT6620) || defined(MT6628) -+ P_CMD_INFO_T prCmdInfo; -+ P_INIT_HIF_TX_HEADER_T prInitHifTxHeader; -+ P_INIT_CMD_DOWNLOAD_BUF prInitCmdDownloadBuf; -+ UINT_8 ucTC, ucCmdSeqNum; -+ WLAN_STATUS u4Status = WLAN_STATUS_SUCCESS; -+ PUINT_8 pucOutputBuf = (PUINT_8) NULL; /* Pointer to Transmit Data Structure Frame */ -+ UINT_32 u4PktCnt, u4Offset, u4Length; -+ UINT_32 u4TotalLength; -+ -+ ASSERT(prAdapter); -+ ASSERT(pucImgSecBuf); -+ -+ pucOutputBuf = prAdapter->rTxCtrl.pucTxCoalescingBufPtr; -+ -+ DEBUGFUNC("wlanImageSectionDownloadAggregated"); -+ -+ if (u4ImgSecSize == 0) -+ return WLAN_STATUS_SUCCESS; -+ /* 1. Allocate CMD Info Packet and Pre-fill Headers */ -+ prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, -+ sizeof(INIT_HIF_TX_HEADER_T) + sizeof(INIT_CMD_DOWNLOAD_BUF) + -+ CMD_PKT_SIZE_FOR_IMAGE); -+ -+ if (!prCmdInfo) { -+ DBGLOG(INIT, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); -+ return WLAN_STATUS_FAILURE; -+ } -+ -+ prCmdInfo->u2InfoBufLen = sizeof(INIT_HIF_TX_HEADER_T) + sizeof(INIT_CMD_DOWNLOAD_BUF) + CMD_PKT_SIZE_FOR_IMAGE; -+ -+ /* 2. Use TC0's resource to download image. (only TC0 is allowed) */ -+ ucTC = TC0_INDEX; -+ -+ /* 3. Setup common CMD Info Packet */ -+ prInitHifTxHeader = (P_INIT_HIF_TX_HEADER_T) (prCmdInfo->pucInfoBuffer); -+ prInitHifTxHeader->ucEtherTypeOffset = 0; -+ prInitHifTxHeader->ucCSflags = 0; -+ prInitHifTxHeader->rInitWifiCmd.ucCID = INIT_CMD_ID_DOWNLOAD_BUF; -+ -+ /* 4. Setup CMD_DOWNLOAD_BUF */ -+ prInitCmdDownloadBuf = (P_INIT_CMD_DOWNLOAD_BUF) (prInitHifTxHeader->rInitWifiCmd.aucBuffer); -+ prInitCmdDownloadBuf->u4DataMode = 0 -+#if CFG_ENABLE_FW_ENCRYPTION -+ | DOWNLOAD_BUF_ENCRYPTION_MODE -+#endif -+ ; -+ -+ /* 5.0 reset loop control variable */ -+ u4TotalLength = 0; -+ u4Offset = u4PktCnt = 0; -+ -+ /* 5.1 main loop for maximize transmission count per access */ -+ while (u4Offset < u4ImgSecSize) { -+ if (nicTxAcquireResource(prAdapter, ucTC, FALSE) == WLAN_STATUS_SUCCESS) { -+ /* 5.1.1 calculate u4Length */ -+ if (u4Offset + CMD_PKT_SIZE_FOR_IMAGE < u4ImgSecSize) -+ u4Length = CMD_PKT_SIZE_FOR_IMAGE; -+ else -+ u4Length = u4ImgSecSize - u4Offset; -+ -+ /* 5.1.1 increase command sequence number */ -+ ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter); -+ prInitHifTxHeader->rInitWifiCmd.ucSeqNum = ucCmdSeqNum; -+ -+ /* 5.1.2 update HIF TX hardware header */ -+ prInitHifTxHeader->u2TxByteCount = -+ ALIGN_4(sizeof(INIT_HIF_TX_HEADER_T) + sizeof(INIT_CMD_DOWNLOAD_BUF) + (UINT_16) u4Length); -+ -+ /* 5.1.3 fill command header */ -+ prInitCmdDownloadBuf->u4Address = u4DestAddr + u4Offset; -+ prInitCmdDownloadBuf->u4Length = u4Length; -+ prInitCmdDownloadBuf->u4CRC32 = wlanCRC32(pucImgSecBuf + u4Offset, u4Length); -+ -+ /* 5.1.4.1 copy header to coalescing buffer */ -+ kalMemCopy(pucOutputBuf + u4TotalLength, -+ (PVOID) prCmdInfo->pucInfoBuffer, -+ sizeof(INIT_HIF_TX_HEADER_T) + sizeof(INIT_CMD_DOWNLOAD_BUF)); -+ -+ /* 5.1.4.2 copy payload to coalescing buffer */ -+ kalMemCopy(pucOutputBuf + u4TotalLength + sizeof(INIT_HIF_TX_HEADER_T) + -+ sizeof(INIT_CMD_DOWNLOAD_BUF), pucImgSecBuf + u4Offset, u4Length); -+ -+ /* 5.1.4.3 update length and other variables */ -+ u4TotalLength += -+ ALIGN_4(sizeof(INIT_HIF_TX_HEADER_T) + sizeof(INIT_CMD_DOWNLOAD_BUF) + u4Length); -+ u4Offset += u4Length; -+ u4PktCnt++; -+ -+ if (u4Offset < u4ImgSecSize) -+ continue; -+ } else if (u4PktCnt == 0) { -+ /* no resource, so get some back */ -+ if (nicTxPollingResource(prAdapter, ucTC) != WLAN_STATUS_SUCCESS) { -+ u4Status = WLAN_STATUS_FAILURE; -+ DBGLOG(INIT, ERROR, "Fail to get TX resource return within timeout\n"); -+ break; -+ } -+ } -+ -+ if (u4PktCnt != 0) { -+ /* start transmission */ -+ HAL_WRITE_TX_PORT(prAdapter, -+ 0, -+ u4TotalLength, (PUINT_8) pucOutputBuf, prAdapter->u4CoalescingBufCachedSize); -+ -+ /* reset varaibles */ -+ u4PktCnt = 0; -+ u4TotalLength = 0; -+ } -+ } -+ -+ /* 8. Free CMD Info Packet. */ -+ cmdBufFreeCmdInfo(prAdapter, prCmdInfo); -+ -+ return u4Status; -+ -+#else -+#error "Only MT6620/MT6628/MT6582 supports firmware download in an aggregated way" -+ -+ return WLAN_STATUS_FAILURE; -+ -+#endif -+} -+ -+#endif -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is called to download FW image. -+* -+* @param prAdapter Pointer to the Adapter structure. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanImageSectionDownload(IN P_ADAPTER_T prAdapter, -+ IN UINT_32 u4DestAddr, IN UINT_32 u4ImgSecSize, IN PUINT_8 pucImgSecBuf) -+{ -+ P_CMD_INFO_T prCmdInfo; -+ P_INIT_HIF_TX_HEADER_T prInitHifTxHeader; -+ P_INIT_CMD_DOWNLOAD_BUF prInitCmdDownloadBuf; -+ UINT_8 ucTC, ucCmdSeqNum; -+ WLAN_STATUS u4Status = WLAN_STATUS_SUCCESS; -+ -+ ASSERT(prAdapter); -+ ASSERT(pucImgSecBuf); -+ ASSERT(u4ImgSecSize <= CMD_PKT_SIZE_FOR_IMAGE); -+ -+ DEBUGFUNC("wlanImageSectionDownload"); -+ -+ if (u4ImgSecSize == 0) -+ return WLAN_STATUS_SUCCESS; -+ /* 1. Allocate CMD Info Packet and its Buffer. */ -+ prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, -+ sizeof(INIT_HIF_TX_HEADER_T) + sizeof(INIT_CMD_DOWNLOAD_BUF) + u4ImgSecSize); -+ -+ if (!prCmdInfo) { -+ DBGLOG(INIT, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); -+ return WLAN_STATUS_FAILURE; -+ } -+ -+ prCmdInfo->u2InfoBufLen = sizeof(INIT_HIF_TX_HEADER_T) + sizeof(INIT_CMD_DOWNLOAD_BUF) + (UINT_16) u4ImgSecSize; -+ -+ /* 2. Use TC0's resource to download image. (only TC0 is allowed) */ -+ ucTC = TC0_INDEX; -+ -+ /* 3. increase command sequence number */ -+ ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter); -+ -+ /* 4. Setup common CMD Info Packet */ -+ prInitHifTxHeader = (P_INIT_HIF_TX_HEADER_T) (prCmdInfo->pucInfoBuffer); -+ prInitHifTxHeader->rInitWifiCmd.ucCID = INIT_CMD_ID_DOWNLOAD_BUF; -+ prInitHifTxHeader->rInitWifiCmd.ucSeqNum = ucCmdSeqNum; -+ -+ /* 5. Setup CMD_DOWNLOAD_BUF */ -+ prInitCmdDownloadBuf = (P_INIT_CMD_DOWNLOAD_BUF) (prInitHifTxHeader->rInitWifiCmd.aucBuffer); -+ prInitCmdDownloadBuf->u4Address = u4DestAddr; -+ prInitCmdDownloadBuf->u4Length = u4ImgSecSize; -+ prInitCmdDownloadBuf->u4CRC32 = wlanCRC32(pucImgSecBuf, u4ImgSecSize); -+ -+ prInitCmdDownloadBuf->u4DataMode = 0 -+#if CFG_ENABLE_FW_DOWNLOAD_ACK -+ | DOWNLOAD_BUF_ACK_OPTION /* ACK needed */ -+#endif -+#if CFG_ENABLE_FW_ENCRYPTION -+ | DOWNLOAD_BUF_ENCRYPTION_MODE -+#endif -+ ; -+ -+ kalMemCopy(prInitCmdDownloadBuf->aucBuffer, pucImgSecBuf, u4ImgSecSize); -+ -+ /* 6. Send FW_Download command */ -+ while (1) { -+ /* 6.1 Acquire TX Resource */ -+ if (nicTxAcquireResource(prAdapter, ucTC, FALSE) == WLAN_STATUS_RESOURCES) { -+ if (nicTxPollingResource(prAdapter, ucTC) != WLAN_STATUS_SUCCESS) { -+ u4Status = WLAN_STATUS_FAILURE; -+ DBGLOG(INIT, ERROR, "Fail to get TX resource return within timeout\n"); -+ break; -+ } -+ continue; -+ } -+ /* 6.2 Send CMD Info Packet */ -+ if (nicTxInitCmd(prAdapter, prCmdInfo, ucTC) != WLAN_STATUS_SUCCESS) { -+ u4Status = WLAN_STATUS_FAILURE; -+ DBGLOG(INIT, ERROR, "Fail to transmit image download command\n"); -+ } -+ -+ break; -+ }; -+ -+#if CFG_ENABLE_FW_DOWNLOAD_ACK -+ /* 7. Wait for INIT_EVENT_ID_CMD_RESULT */ -+ u4Status = wlanImageSectionDownloadStatus(prAdapter, ucCmdSeqNum); -+#endif -+ -+ /* 8. Free CMD Info Packet. */ -+ cmdBufFreeCmdInfo(prAdapter, prCmdInfo); -+ -+ return u4Status; -+} -+ -+#if !CFG_ENABLE_FW_DOWNLOAD_ACK -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is called to confirm previously firmware download is done without error -+* -+* @param prAdapter Pointer to the Adapter structure. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS wlanImageQueryStatus(IN P_ADAPTER_T prAdapter) -+{ -+ P_CMD_INFO_T prCmdInfo; -+ P_INIT_HIF_TX_HEADER_T prInitHifTxHeader; -+ UINT_8 aucBuffer[sizeof(INIT_HIF_RX_HEADER_T) + sizeof(INIT_EVENT_PENDING_ERROR)]; -+ UINT_32 u4RxPktLength; -+ P_INIT_HIF_RX_HEADER_T prInitHifRxHeader; -+ P_INIT_EVENT_PENDING_ERROR prEventPendingError; -+ WLAN_STATUS u4Status = WLAN_STATUS_SUCCESS; -+ UINT_8 ucTC, ucCmdSeqNum; -+ -+ ASSERT(prAdapter); -+ -+ DEBUGFUNC("wlanImageQueryStatus"); -+ -+ /* 1. Allocate CMD Info Packet and it Buffer. */ -+ prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, sizeof(INIT_HIF_TX_HEADER_T)); -+ -+ if (!prCmdInfo) { -+ DBGLOG(INIT, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); -+ return WLAN_STATUS_FAILURE; -+ } -+ -+ kalMemZero(prCmdInfo, sizeof(INIT_HIF_TX_HEADER_T)); -+ prCmdInfo->u2InfoBufLen = sizeof(INIT_HIF_TX_HEADER_T); -+ -+ /* 2. Use TC0's resource to download image. (only TC0 is allowed) */ -+ ucTC = TC0_INDEX; -+ -+ /* 3. increase command sequence number */ -+ ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter); -+ -+ /* 4. Setup common CMD Info Packet */ -+ prInitHifTxHeader = (P_INIT_HIF_TX_HEADER_T) (prCmdInfo->pucInfoBuffer); -+ prInitHifTxHeader->rInitWifiCmd.ucCID = INIT_CMD_ID_QUERY_PENDING_ERROR; -+ prInitHifTxHeader->rInitWifiCmd.ucSeqNum = ucCmdSeqNum; -+ -+ /* 5. Send command */ -+ while (1) { -+ /* 5.1 Acquire TX Resource */ -+ if (nicTxAcquireResource(prAdapter, ucTC, FALSE) == WLAN_STATUS_RESOURCES) { -+ if (nicTxPollingResource(prAdapter, ucTC) != WLAN_STATUS_SUCCESS) { -+ u4Status = WLAN_STATUS_FAILURE; -+ DBGLOG(INIT, ERROR, "Fail to get TX resource return within timeout\n"); -+ break; -+ } -+ continue; -+ } -+ /* 5.2 Send CMD Info Packet */ -+ if (nicTxInitCmd(prAdapter, prCmdInfo, ucTC) != WLAN_STATUS_SUCCESS) { -+ u4Status = WLAN_STATUS_FAILURE; -+ DBGLOG(INIT, ERROR, "Fail to transmit image download command\n"); -+ } -+ -+ break; -+ }; -+ -+ /* 6. Wait for INIT_EVENT_ID_PENDING_ERROR */ -+ do { -+ if (kalIsCardRemoved(prAdapter->prGlueInfo) == TRUE || fgIsBusAccessFailed == TRUE) { -+ u4Status = WLAN_STATUS_FAILURE; -+ } else if (nicRxWaitResponse(prAdapter, -+ 0, -+ aucBuffer, -+ sizeof(INIT_HIF_RX_HEADER_T) + sizeof(INIT_EVENT_PENDING_ERROR), -+ &u4RxPktLength) != WLAN_STATUS_SUCCESS) { -+ u4Status = WLAN_STATUS_FAILURE; -+ } else { -+ prInitHifRxHeader = (P_INIT_HIF_RX_HEADER_T) aucBuffer; -+ -+ /* EID / SeqNum check */ -+ if (prInitHifRxHeader->rInitWifiEvent.ucEID != INIT_EVENT_ID_PENDING_ERROR) { -+ u4Status = WLAN_STATUS_FAILURE; -+ } else if (prInitHifRxHeader->rInitWifiEvent.ucSeqNum != ucCmdSeqNum) { -+ u4Status = WLAN_STATUS_FAILURE; -+ } else { -+ prEventPendingError = -+ (P_INIT_EVENT_PENDING_ERROR) (prInitHifRxHeader->rInitWifiEvent.aucBuffer); -+ if (prEventPendingError->ucStatus != 0) { /* 0 for download success */ -+ u4Status = WLAN_STATUS_FAILURE; -+ } else { -+ u4Status = WLAN_STATUS_SUCCESS; -+ } -+ } -+ } -+ } while (FALSE); -+ -+ /* 7. Free CMD Info Packet. */ -+ cmdBufFreeCmdInfo(prAdapter, prCmdInfo); -+ -+ return u4Status; -+} -+ -+#else -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is called to confirm the status of -+* previously downloaded firmware scatter -+* -+* @param prAdapter Pointer to the Adapter structure. -+* ucCmdSeqNum Sequence number of previous firmware scatter -+* -+* @return WLAN_STATUS_SUCCESS -+* WLAN_STATUS_FAILURE -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS wlanImageSectionDownloadStatus(IN P_ADAPTER_T prAdapter, IN UINT_8 ucCmdSeqNum) -+{ -+ UINT_8 aucBuffer[sizeof(INIT_HIF_RX_HEADER_T) + sizeof(INIT_EVENT_CMD_RESULT)]; -+ P_INIT_HIF_RX_HEADER_T prInitHifRxHeader; -+ P_INIT_EVENT_CMD_RESULT prEventCmdResult; -+ UINT_32 u4RxPktLength; -+ WLAN_STATUS u4Status; -+ -+ ASSERT(prAdapter); -+ -+ do { -+ if (kalIsCardRemoved(prAdapter->prGlueInfo) == TRUE || fgIsBusAccessFailed == TRUE) { -+ DBGLOG(INIT, ERROR, "kalIsCardRemoved or fgIsBusAccessFailed\n"); -+ u4Status = WLAN_STATUS_FAILURE; -+ } else if (nicRxWaitResponse(prAdapter, -+ 0, -+ aucBuffer, -+ sizeof(INIT_HIF_RX_HEADER_T) + sizeof(INIT_EVENT_CMD_RESULT),/* 4B + 4B */ -+ &u4RxPktLength) != WLAN_STATUS_SUCCESS) { -+ DBGLOG(INIT, ERROR, "nicRxWaitResponse fail\n"); -+ u4Status = WLAN_STATUS_FAILURE; -+ } else { -+ prInitHifRxHeader = (P_INIT_HIF_RX_HEADER_T) aucBuffer; -+ -+ /* EID / SeqNum check */ -+ if (prInitHifRxHeader->rInitWifiEvent.ucEID != INIT_EVENT_ID_CMD_RESULT) { -+ DBGLOG(INIT, ERROR, "rInitWifiEvent.ucEID != INIT_EVENT_ID_CMD_RESULT\n"); -+ u4Status = WLAN_STATUS_FAILURE; -+ g_IsNeedDoChipReset = 1; -+ kalSendAeeWarning("[Check EID error!]", __func__); -+ } else if (prInitHifRxHeader->rInitWifiEvent.ucSeqNum != ucCmdSeqNum) { -+ DBGLOG(INIT, ERROR, "rInitWifiEvent.ucSeqNum != ucCmdSeqNum\n"); -+ u4Status = WLAN_STATUS_FAILURE; -+ g_IsNeedDoChipReset = 1; -+ kalSendAeeWarning("[Check SeqNum error!]", __func__); -+ } else { -+ prEventCmdResult = -+ (P_INIT_EVENT_CMD_RESULT) (prInitHifRxHeader->rInitWifiEvent.aucBuffer); -+ if (prEventCmdResult->ucStatus != 0) { /* 0 for download success */ -+ /* -+ 0: success -+ 1: rejected by invalid param -+ 2: rejected by incorrect CRC -+ 3: rejected by decryption failure -+ 4: unknown CMD -+ */ -+ DBGLOG(INIT, ERROR, "Read Response status error = %d\n", -+ prEventCmdResult->ucStatus); -+ u4Status = WLAN_STATUS_FAILURE; -+ } else { -+ u4Status = WLAN_STATUS_SUCCESS; -+ } -+ } -+ } -+ } while (FALSE); -+ -+ return u4Status; -+} -+ -+#endif -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is called to start FW normal operation. -+* -+* @param prAdapter Pointer to the Adapter structure. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS wlanConfigWifiFunc(IN P_ADAPTER_T prAdapter, IN BOOLEAN fgEnable, IN UINT_32 u4StartAddress) -+{ -+ P_CMD_INFO_T prCmdInfo; -+ P_INIT_HIF_TX_HEADER_T prInitHifTxHeader; -+ P_INIT_CMD_WIFI_START prInitCmdWifiStart; -+ UINT_8 ucTC, ucCmdSeqNum; -+ WLAN_STATUS u4Status = WLAN_STATUS_SUCCESS; -+ -+ ASSERT(prAdapter); -+ -+ DEBUGFUNC("wlanConfigWifiFunc"); -+ -+ /* 1. Allocate CMD Info Packet and its Buffer. */ -+ prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, sizeof(INIT_HIF_TX_HEADER_T) + sizeof(INIT_CMD_WIFI_START)); -+ -+ if (!prCmdInfo) { -+ DBGLOG(INIT, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); -+ return WLAN_STATUS_FAILURE; -+ } -+ -+ kalMemZero(prCmdInfo->pucInfoBuffer, sizeof(INIT_HIF_TX_HEADER_T) + sizeof(INIT_CMD_WIFI_START)); -+ prCmdInfo->u2InfoBufLen = sizeof(INIT_HIF_TX_HEADER_T) + sizeof(INIT_CMD_WIFI_START); -+ -+ /* 2. Always use TC0 */ -+ ucTC = TC0_INDEX; -+ -+ /* 3. increase command sequence number */ -+ ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter); -+ -+ /* 4. Setup common CMD Info Packet */ -+ prInitHifTxHeader = (P_INIT_HIF_TX_HEADER_T) (prCmdInfo->pucInfoBuffer); -+ prInitHifTxHeader->rInitWifiCmd.ucCID = INIT_CMD_ID_WIFI_START; -+ prInitHifTxHeader->rInitWifiCmd.ucSeqNum = ucCmdSeqNum; -+ -+ prInitCmdWifiStart = (P_INIT_CMD_WIFI_START) (prInitHifTxHeader->rInitWifiCmd.aucBuffer); -+ prInitCmdWifiStart->u4Override = (fgEnable == TRUE ? 1 : 0); -+ prInitCmdWifiStart->u4Address = u4StartAddress; -+ -+ /* 5. Seend WIFI start command */ -+ while (1) { -+ /* 5.1 Acquire TX Resource */ -+ if (nicTxAcquireResource(prAdapter, ucTC, FALSE) == WLAN_STATUS_RESOURCES) { -+ -+ /* wait and poll tx resource */ -+ if (nicTxPollingResource(prAdapter, ucTC) != WLAN_STATUS_SUCCESS) { -+ u4Status = WLAN_STATUS_FAILURE; -+ DBGLOG(INIT, ERROR, "Fail to get TX resource return within timeout\n"); -+ break; -+ } -+ -+ continue; -+ } -+ /* 5.2 Send CMD Info Packet */ -+ if (nicTxInitCmd(prAdapter, prCmdInfo, ucTC) != WLAN_STATUS_SUCCESS) { -+ u4Status = WLAN_STATUS_FAILURE; -+ DBGLOG(INIT, ERROR, "Fail to transmit WIFI start command\n"); -+ } -+ -+ break; -+ }; -+ -+ /* 6. Free CMD Info Packet. */ -+ cmdBufFreeCmdInfo(prAdapter, prCmdInfo); -+ -+ return u4Status; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is used to generate CRC32 checksum -+* -+* @param buf Pointer to the data. -+* @param len data length -+* -+* @return crc32 value -+*/ -+/*----------------------------------------------------------------------------*/ -+static const UINT_32 crc32_ccitt_table[256] = { -+ 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, -+ 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, -+ 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, -+ 0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, -+ 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856, -+ 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, -+ 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, -+ 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, -+ 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, -+ 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a, -+ 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, -+ 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, -+ 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, -+ 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, -+ 0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e, -+ 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, -+ 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, -+ 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, -+ 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, -+ 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, -+ 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, -+ 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, -+ 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010, -+ 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, -+ 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, -+ 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, -+ 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, -+ 0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, -+ 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344, -+ 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, -+ 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, -+ 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, -+ 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, -+ 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c, -+ 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, -+ 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, -+ 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, -+ 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, -+ 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c, -+ 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, -+ 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, -+ 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, -+ 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, -+ 0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, -+ 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278, -+ 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, -+ 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66, -+ 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, -+ 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, -+ 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, -+ 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, -+ 0x2d02ef8d -+ }; -+ -+UINT_32 wlanCRC32(PUINT_8 buf, UINT_32 len) -+{ -+ UINT_32 i, crc32 = 0xFFFFFFFF; -+ -+ for (i = 0; i < len; i++) -+ crc32 = crc32_ccitt_table[(crc32 ^ buf[i]) & 0xff] ^ (crc32 >> 8); -+ -+ return ~crc32; -+} -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is called to process queued RX packets -+* -+* @param prAdapter Pointer to the Adapter structure. -+* prSwRfbListHead Pointer to head of RX packets link list -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS wlanProcessQueuedSwRfb(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfbListHead) -+{ -+ P_SW_RFB_T prSwRfb, prNextSwRfb; -+ P_TX_CTRL_T prTxCtrl; -+ P_RX_CTRL_T prRxCtrl; -+ -+ ASSERT(prAdapter); -+ ASSERT(prSwRfbListHead); -+ -+ prTxCtrl = &prAdapter->rTxCtrl; -+ prRxCtrl = &prAdapter->rRxCtrl; -+ -+ prSwRfb = prSwRfbListHead; -+ -+ do { -+ /* save next first */ -+ prNextSwRfb = (P_SW_RFB_T) QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T) prSwRfb); -+ -+ switch (prSwRfb->eDst) { -+ case RX_PKT_DESTINATION_HOST: -+ /* to host */ -+ nicRxProcessPktWithoutReorder(prAdapter, prSwRfb); -+ break; -+ -+ case RX_PKT_DESTINATION_FORWARD: -+ /* need ot forward */ -+ nicRxProcessForwardPkt(prAdapter, prSwRfb); -+ break; -+ -+ case RX_PKT_DESTINATION_HOST_WITH_FORWARD: -+ /* to host and forward */ -+ nicRxProcessGOBroadcastPkt(prAdapter, prSwRfb); -+ break; -+ -+ case RX_PKT_DESTINATION_NULL: -+ /* free it */ -+ nicRxReturnRFB(prAdapter, prSwRfb); -+ break; -+ -+ default: -+ break; -+ } -+ -+#if CFG_HIF_RX_STARVATION_WARNING -+ prRxCtrl->u4DequeuedCnt++; -+#endif -+ -+ /* check next queued packet */ -+ prSwRfb = prNextSwRfb; -+ } while (prSwRfb); -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is called to purge queued TX packets -+* by indicating failure to OS and returned to free list -+* -+* @param prAdapter Pointer to the Adapter structure. -+* prMsduInfoListHead Pointer to head of TX packets link list -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS wlanProcessQueuedMsduInfo(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfoListHead) -+{ -+ ASSERT(prAdapter); -+ ASSERT(prMsduInfoListHead); -+ -+ nicTxFreeMsduInfoPacket(prAdapter, prMsduInfoListHead); -+ nicTxReturnMsduInfo(prAdapter, prMsduInfoListHead); -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is called to check if the OID handler needs timeout -+* -+* @param prAdapter Pointer to the Adapter structure. -+* pfnOidHandler Pointer to the OID handler -+* -+* @return TRUE -+* FALSE -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN wlanoidTimeoutCheck(IN P_ADAPTER_T prAdapter, IN PFN_OID_HANDLER_FUNC pfnOidHandler) -+{ -+ PFN_OID_HANDLER_FUNC *apfnOidHandlerWOTimeoutCheck; -+ UINT_32 i; -+ UINT_32 u4NumOfElem; -+ -+ apfnOidHandlerWOTimeoutCheck = apfnOidWOTimeoutCheck; -+ u4NumOfElem = sizeof(apfnOidWOTimeoutCheck) / sizeof(PFN_OID_HANDLER_FUNC); -+ -+ /* skip some OID timeout checks ? */ -+ for (i = 0; i < u4NumOfElem; i++) { -+ if (apfnOidHandlerWOTimeoutCheck[i] == pfnOidHandler) -+ return FALSE; -+ } -+ -+ /* set timer if need timeout check */ -+ /* cnmTimerStartTimer(prAdapter, */ -+ /* &(prAdapter->rOidTimeoutTimer), */ -+ /* 1000); */ -+ cnmTimerStartTimer(prAdapter, &(prAdapter->rOidTimeoutTimer), 2000); -+ -+ return TRUE; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is called to clear any pending OID timeout check -+* -+* @param prAdapter Pointer to the Adapter structure. -+* -+* @return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID wlanoidClearTimeoutCheck(IN P_ADAPTER_T prAdapter) -+{ -+ ASSERT(prAdapter); -+ -+ cnmTimerStopTimer(prAdapter, &(prAdapter->rOidTimeoutTimer)); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is called to update network address in firmware domain -+* -+* @param prAdapter Pointer to the Adapter structure. -+* -+* @return WLAN_STATUS_FAILURE The request could not be processed -+* WLAN_STATUS_PENDING The request has been queued for later processing -+* WLAN_STATUS_SUCCESS The request has been processed -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS wlanUpdateNetworkAddress(IN P_ADAPTER_T prAdapter) -+{ -+ const UINT_8 aucZeroMacAddr[] = NULL_MAC_ADDR; -+ PARAM_MAC_ADDRESS rMacAddr = {0}; -+ UINT_8 ucCmdSeqNum; -+ P_CMD_INFO_T prCmdInfo; -+ P_WIFI_CMD_T prWifiCmd; -+ P_CMD_BASIC_CONFIG prCmdBasicConfig; -+ UINT_32 u4SysTime; -+ -+ DEBUGFUNC("wlanUpdateNetworkAddress"); -+ -+ ASSERT(prAdapter); -+ -+ if (kalRetrieveNetworkAddress(prAdapter->prGlueInfo, &rMacAddr) == FALSE || IS_BMCAST_MAC_ADDR(rMacAddr) -+ || EQUAL_MAC_ADDR(aucZeroMacAddr, rMacAddr)) { -+ /* eFUSE has a valid address, don't do anything */ -+ if (prAdapter->fgIsEmbbededMacAddrValid == TRUE) { -+#if CFG_SHOW_MACADDR_SOURCE -+ DBGLOG(INIT, INFO, "Using embedded MAC address"); -+#endif -+ return WLAN_STATUS_SUCCESS; -+ } -+#if CFG_SHOW_MACADDR_SOURCE -+ DBGLOG(INIT, TRACE, "Using dynamically generated MAC address"); -+#endif -+ /* dynamic generate */ -+ u4SysTime = kalGetTimeTick(); -+ -+ rMacAddr[0] = 0x00; -+ rMacAddr[1] = 0x08; -+ rMacAddr[2] = 0x22; -+ -+ kalMemCopy(&rMacAddr[3], &u4SysTime, 3); -+ } else { -+#if CFG_SHOW_MACADDR_SOURCE -+ DBGLOG(INIT, INFO, "Using host-supplied MAC address"); -+#endif -+ } -+ -+ /* allocate command memory */ -+ prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, CMD_HDR_SIZE + sizeof(CMD_BASIC_CONFIG)); -+ -+ if (!prCmdInfo) { -+ DBGLOG(INIT, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); -+ return WLAN_STATUS_FAILURE; -+ } -+ /* increase command sequence number */ -+ ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter); -+ -+ /* compose CMD_BUILD_CONNECTION cmd pkt */ -+ prCmdInfo->eCmdType = COMMAND_TYPE_GENERAL_IOCTL; -+ prCmdInfo->u2InfoBufLen = CMD_HDR_SIZE + sizeof(CMD_BASIC_CONFIG); -+ prCmdInfo->pfCmdDoneHandler = NULL; -+ prCmdInfo->pfCmdTimeoutHandler = NULL; -+ prCmdInfo->fgIsOid = FALSE; -+ prCmdInfo->ucCID = CMD_ID_BASIC_CONFIG; -+ prCmdInfo->fgSetQuery = TRUE; -+ prCmdInfo->fgNeedResp = FALSE; -+ prCmdInfo->fgDriverDomainMCR = FALSE; -+ prCmdInfo->ucCmdSeqNum = ucCmdSeqNum; -+ prCmdInfo->u4SetInfoLen = sizeof(CMD_BASIC_CONFIG); -+ -+ /* Setup WIFI_CMD_T */ -+ prWifiCmd = (P_WIFI_CMD_T) (prCmdInfo->pucInfoBuffer); -+ prWifiCmd->u2TxByteCount_UserPriority = prCmdInfo->u2InfoBufLen; -+ prWifiCmd->ucCID = prCmdInfo->ucCID; -+ prWifiCmd->ucSetQuery = prCmdInfo->fgSetQuery; -+ prWifiCmd->ucSeqNum = prCmdInfo->ucCmdSeqNum; -+ -+ /* configure CMD_BASIC_CONFIG */ -+ prCmdBasicConfig = (P_CMD_BASIC_CONFIG) (prWifiCmd->aucBuffer); -+ kalMemCopy(&(prCmdBasicConfig->rMyMacAddr), &rMacAddr, PARAM_MAC_ADDR_LEN); -+ prCmdBasicConfig->ucNative80211 = 0; -+ prCmdBasicConfig->rCsumOffload.u2RxChecksum = 0; -+ prCmdBasicConfig->rCsumOffload.u2TxChecksum = 0; -+ -+#if CFG_TCP_IP_CHKSUM_OFFLOAD -+ if (prAdapter->u4CSUMFlags & CSUM_OFFLOAD_EN_TX_TCP) -+ prCmdBasicConfig->rCsumOffload.u2TxChecksum |= BIT(2); -+ -+ if (prAdapter->u4CSUMFlags & CSUM_OFFLOAD_EN_TX_UDP) -+ prCmdBasicConfig->rCsumOffload.u2TxChecksum |= BIT(1); -+ -+ if (prAdapter->u4CSUMFlags & CSUM_OFFLOAD_EN_TX_IP) -+ prCmdBasicConfig->rCsumOffload.u2TxChecksum |= BIT(0); -+ -+ if (prAdapter->u4CSUMFlags & CSUM_OFFLOAD_EN_RX_TCP) -+ prCmdBasicConfig->rCsumOffload.u2RxChecksum |= BIT(2); -+ -+ if (prAdapter->u4CSUMFlags & CSUM_OFFLOAD_EN_RX_UDP) -+ prCmdBasicConfig->rCsumOffload.u2RxChecksum |= BIT(1); -+ -+ if (prAdapter->u4CSUMFlags & (CSUM_OFFLOAD_EN_RX_IPv4 | CSUM_OFFLOAD_EN_RX_IPv6)) -+ prCmdBasicConfig->rCsumOffload.u2RxChecksum |= BIT(0); -+#endif -+ -+ /* send the command to FW */ -+ if (wlanSendCommand(prAdapter, prCmdInfo) == WLAN_STATUS_RESOURCES) { -+ -+ /* backup the command to wait response */ -+ prCmdInfo->pfCmdDoneHandler = nicCmdEventQueryAddress; -+ kalEnqueueCommand(prAdapter->prGlueInfo, (P_QUE_ENTRY_T) prCmdInfo); -+ -+ return WLAN_STATUS_PENDING; -+ } -+ /* send ok without response */ -+ nicCmdEventQueryAddress(prAdapter, prCmdInfo, (PUINT_8) prCmdBasicConfig); -+ cmdBufFreeCmdInfo(prAdapter, prCmdInfo); -+ -+ return WLAN_STATUS_SUCCESS; -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is called to check if the device is in RF test mode -+* -+* @param pfnOidHandler Pointer to the OID handler -+* -+* @return TRUE -+* FALSE -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN wlanQueryTestMode(IN P_ADAPTER_T prAdapter) -+{ -+ ASSERT(prAdapter); -+ -+ return prAdapter->fgTestMode; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is called to identify 802.1x and Bluetooth-over-Wi-Fi -+* security frames, and queued into command queue for strict ordering -+* due to 802.1x frames before add-key OIDs are not to be encrypted -+* -+* @param prAdapter Pointer of Adapter Data Structure -+* @param prPacket Pointer of native packet -+* -+* @return TRUE -+* FALSE -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN wlanProcessSecurityFrame(IN P_ADAPTER_T prAdapter, IN P_NATIVE_PACKET prPacket) -+{ -+ UINT_8 ucPriorityParam; -+ UINT_8 aucEthDestAddr[PARAM_MAC_ADDR_LEN]; -+ BOOLEAN fgIs1x = FALSE; -+ BOOLEAN fgIsPAL = FALSE; -+ UINT_32 u4PacketLen; -+ ULONG u4SysTime; -+ UINT_8 ucNetworkType; -+ P_CMD_INFO_T prCmdInfo; -+ UINT_8 ucCmdSeqNo = 0; -+ -+ /* 1x data packets */ -+ KAL_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(prAdapter); -+ ASSERT(prPacket); -+ -+ /* retrieve some information for packet classification */ -+ if (kalQoSFrameClassifierAndPacketInfo(prAdapter->prGlueInfo, -+ prPacket, -+ &ucPriorityParam, -+ &u4PacketLen, -+ aucEthDestAddr, -+ &fgIs1x, -+ &fgIsPAL, -+ &ucNetworkType, -+ &ucCmdSeqNo) == TRUE) { -+ /* almost TRUE except frame length < 14B */ -+ -+ if (fgIs1x == FALSE) -+ return FALSE; -+ -+ /* get a free command entry */ -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_RESOURCE); -+ QUEUE_REMOVE_HEAD(&prAdapter->rFreeCmdList, prCmdInfo, P_CMD_INFO_T); -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_RESOURCE); -+ -+ if (prCmdInfo) { -+ P_STA_RECORD_T prStaRec; -+ -+ /* fill arrival time */ -+ u4SysTime = (OS_SYSTIME) kalGetTimeTick(); -+ GLUE_SET_PKT_ARRIVAL_TIME(prPacket, u4SysTime); -+ -+ kalMemZero(prCmdInfo, sizeof(CMD_INFO_T)); -+ -+ prCmdInfo->eCmdType = COMMAND_TYPE_SECURITY_FRAME; -+ prCmdInfo->u2InfoBufLen = (UINT_16) u4PacketLen; -+ prCmdInfo->pucInfoBuffer = NULL; -+ prCmdInfo->prPacket = prPacket; -+ prCmdInfo->ucCmdSeqNum = ucCmdSeqNo; -+#if 0 -+ prCmdInfo->ucStaRecIndex = qmGetStaRecIdx(prAdapter, -+ aucEthDestAddr, -+ (ENUM_NETWORK_TYPE_INDEX_T) ucNetworkType); -+#endif -+ prStaRec = cnmGetStaRecByAddress(prAdapter, -+ (ENUM_NETWORK_TYPE_INDEX_T) ucNetworkType, -+ aucEthDestAddr); -+ if (prStaRec) -+ prCmdInfo->ucStaRecIndex = prStaRec->ucIndex; -+ else -+ prCmdInfo->ucStaRecIndex = STA_REC_INDEX_NOT_FOUND; -+ -+ prCmdInfo->eNetworkType = (ENUM_NETWORK_TYPE_INDEX_T) ucNetworkType; -+ prCmdInfo->pfCmdDoneHandler = wlanSecurityFrameTxDone; -+ prCmdInfo->pfCmdTimeoutHandler = wlanSecurityFrameTxTimeout; -+ prCmdInfo->fgIsOid = FALSE; -+ prCmdInfo->fgSetQuery = TRUE; -+ prCmdInfo->fgNeedResp = FALSE; -+ -+ /* -+ queue the 1x packet and we will send the packet to CONNSYS by -+ using command queue -+ */ -+ kalEnqueueCommand(prAdapter->prGlueInfo, (P_QUE_ENTRY_T) prCmdInfo); -+ -+ /* TRUE: means we have already handled it in the function */ -+ return TRUE; -+ } -+ -+ /* no memory, why assert ? can skip the packet ? */ -+ ASSERT(0); -+ return FALSE; -+ } -+ return FALSE; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is called when 802.1x or Bluetooth-over-Wi-Fi -+* security frames has been sent to firmware -+* -+* @param prAdapter Pointer of Adapter Data Structure -+* @param prCmdInfo Pointer of CMD_INFO_T -+* @param pucEventBuf meaningless, only for API compatibility -+* -+* @return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID wlanSecurityFrameTxDone(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) -+{ -+ ASSERT(prAdapter); -+ ASSERT(prCmdInfo); -+ -+ if (prCmdInfo->eNetworkType == NETWORK_TYPE_AIS_INDEX && -+ prAdapter->rWifiVar.rAisSpecificBssInfo.fgCounterMeasure) { -+ -+ /* AIS counter measure so change RSN FSM to SEND_DEAUTH state */ -+ P_STA_RECORD_T prSta = cnmGetStaRecByIndex(prAdapter, prCmdInfo->ucStaRecIndex); -+ -+ if (prSta) { -+ kalMsleep(10); -+ secFsmEventEapolTxDone(prAdapter, prSta, TX_RESULT_SUCCESS); -+ } -+ } -+ -+ /* free the packet */ -+ kalSecurityFrameSendComplete(prAdapter->prGlueInfo, prCmdInfo->prPacket, WLAN_STATUS_SUCCESS); -+ DBGLOG(TX, INFO, "Security frame tx done, SeqNum: %d\n", prCmdInfo->ucCmdSeqNum); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is called when 802.1x or Bluetooth-over-Wi-Fi -+* security frames has failed sending to firmware -+* -+* @param prAdapter Pointer of Adapter Data Structure -+* @param prCmdInfo Pointer of CMD_INFO_T -+* -+* @return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID wlanSecurityFrameTxTimeout(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo) -+{ -+ ASSERT(prAdapter); -+ ASSERT(prCmdInfo); -+ -+ /* free the packet */ -+ kalSecurityFrameSendComplete(prAdapter->prGlueInfo, prCmdInfo->prPacket, WLAN_STATUS_FAILURE); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is called before AIS is starting a new scan -+* -+* @param prAdapter Pointer of Adapter Data Structure -+* -+* @return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID wlanClearScanningResult(IN P_ADAPTER_T prAdapter) -+{ -+ BOOLEAN fgKeepCurrOne = FALSE; -+ UINT_32 i; -+ -+ ASSERT(prAdapter); -+ -+ /* clear scanning result except current one */ -+ /* copy current one to prAdapter->rWlanInfo.arScanResult[0] */ -+ if (kalGetMediaStateIndicated(prAdapter->prGlueInfo) == PARAM_MEDIA_STATE_CONNECTED) { -+ for (i = 0; i < prAdapter->rWlanInfo.u4ScanResultNum; i++) { -+ -+ if (EQUAL_MAC_ADDR(prAdapter->rWlanInfo.rCurrBssId.arMacAddress, -+ prAdapter->rWlanInfo.arScanResult[i].arMacAddress)) { -+ fgKeepCurrOne = TRUE; -+ -+ if (i != 0) { -+ /* copy structure */ -+ kalMemCopy(&(prAdapter->rWlanInfo.arScanResult[0]), -+ &(prAdapter->rWlanInfo.arScanResult[i]), -+ OFFSET_OF(PARAM_BSSID_EX_T, aucIEs)); -+ } -+ -+ if (prAdapter->rWlanInfo.arScanResult[i].u4IELength > 0) { -+ if (prAdapter->rWlanInfo.apucScanResultIEs[i] != -+ &(prAdapter->rWlanInfo.aucScanIEBuf[0])) { -+ /* move IEs to head */ -+ kalMemCopy(prAdapter->rWlanInfo.aucScanIEBuf, -+ prAdapter->rWlanInfo.apucScanResultIEs[i], -+ prAdapter->rWlanInfo.arScanResult[i].u4IELength); -+ } -+ /* modify IE pointer */ -+ prAdapter->rWlanInfo.apucScanResultIEs[0] = -+ &(prAdapter->rWlanInfo.aucScanIEBuf[0]); -+ } else { -+ prAdapter->rWlanInfo.apucScanResultIEs[0] = NULL; -+ } -+ -+ break; -+ } -+ } -+ } -+ -+ if (fgKeepCurrOne == TRUE) { -+ prAdapter->rWlanInfo.u4ScanResultNum = 1; -+ prAdapter->rWlanInfo.u4ScanIEBufferUsage = ALIGN_4(prAdapter->rWlanInfo.arScanResult[0].u4IELength); -+ } else { -+ prAdapter->rWlanInfo.u4ScanResultNum = 0; -+ prAdapter->rWlanInfo.u4ScanIEBufferUsage = 0; -+ } -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is called when AIS received a beacon timeout event -+* -+* @param prAdapter Pointer of Adapter Data Structure -+* @param arBSSID MAC address of the specified BSS -+* -+* @return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID wlanClearBssInScanningResult(IN P_ADAPTER_T prAdapter, IN PUINT_8 arBSSID) -+{ -+ UINT_32 i, j, u4IELength = 0, u4IEMoveLength; -+ PUINT_8 pucIEPtr; -+ -+ ASSERT(prAdapter); -+ -+ /* clear the scanning result for arBSSID */ -+ i = 0; -+ while (1) { -+ if (i >= prAdapter->rWlanInfo.u4ScanResultNum) -+ break; -+ -+ if (EQUAL_MAC_ADDR(arBSSID, prAdapter->rWlanInfo.arScanResult[i].arMacAddress)) { -+ -+ /* backup current IE length */ -+ u4IELength = ALIGN_4(prAdapter->rWlanInfo.arScanResult[i].u4IELength); -+ pucIEPtr = prAdapter->rWlanInfo.apucScanResultIEs[i]; -+ -+ /* removed from middle */ -+ for (j = i + 1; j < prAdapter->rWlanInfo.u4ScanResultNum; j++) { -+ kalMemCopy(&(prAdapter->rWlanInfo.arScanResult[j - 1]), -+ &(prAdapter->rWlanInfo.arScanResult[j]), -+ OFFSET_OF(PARAM_BSSID_EX_T, aucIEs)); -+ -+ prAdapter->rWlanInfo.apucScanResultIEs[j - 1] = -+ prAdapter->rWlanInfo.apucScanResultIEs[j]; -+ } -+ -+ prAdapter->rWlanInfo.u4ScanResultNum--; -+ -+ /* remove IE buffer if needed := move rest of IE buffer */ -+ if (u4IELength > 0) { -+ u4IEMoveLength = prAdapter->rWlanInfo.u4ScanIEBufferUsage - -+ (((ULONG) pucIEPtr) + (ULONG) u4IELength - -+ ((ULONG) (&(prAdapter->rWlanInfo.aucScanIEBuf[0])))); -+ -+ kalMemCopy(pucIEPtr, pucIEPtr + u4IELength, u4IEMoveLength); -+ -+ prAdapter->rWlanInfo.u4ScanIEBufferUsage -= u4IELength; -+ -+ /* correction of pointers to IE buffer */ -+ for (j = 0; j < prAdapter->rWlanInfo.u4ScanResultNum; j++) { -+ if (prAdapter->rWlanInfo.apucScanResultIEs[j] > pucIEPtr) { -+ prAdapter->rWlanInfo.apucScanResultIEs[j] = -+ (PUINT_8) ((ULONG) (prAdapter->rWlanInfo.apucScanResultIEs[j]) - -+ u4IELength); -+ } -+ } -+ } -+ } -+ -+ i++; -+ } -+ -+} -+ -+#if CFG_TEST_WIFI_DIRECT_GO -+VOID wlanEnableP2pFunction(IN P_ADAPTER_T prAdapter) -+{ -+#if 0 -+ P_MSG_P2P_FUNCTION_SWITCH_T prMsgFuncSwitch = (P_MSG_P2P_FUNCTION_SWITCH_T) NULL; -+ -+ prMsgFuncSwitch = -+ (P_MSG_P2P_FUNCTION_SWITCH_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_P2P_FUNCTION_SWITCH_T)); -+ if (!prMsgFuncSwitch) { -+ ASSERT(FALSE); -+ return; -+ } -+ -+ prMsgFuncSwitch->rMsgHdr.eMsgId = MID_MNY_P2P_FUN_SWITCH; -+ prMsgFuncSwitch->fgIsFuncOn = TRUE; -+ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgFuncSwitch, MSG_SEND_METHOD_BUF); -+#endif -+ -+} -+ -+VOID wlanEnableATGO(IN P_ADAPTER_T prAdapter) -+{ -+ -+ P_MSG_P2P_CONNECTION_REQUEST_T prMsgConnReq = (P_MSG_P2P_CONNECTION_REQUEST_T) NULL; -+ UINT_8 aucTargetDeviceID[MAC_ADDR_LEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; -+ -+ prMsgConnReq = -+ (P_MSG_P2P_CONNECTION_REQUEST_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_P2P_CONNECTION_REQUEST_T)); -+ if (!prMsgConnReq) { -+ ASSERT(FALSE); -+ return; -+ } -+ -+ prMsgConnReq->rMsgHdr.eMsgId = MID_MNY_P2P_CONNECTION_REQ; -+ -+ /*=====Param Modified for test=====*/ -+ COPY_MAC_ADDR(prMsgConnReq->aucDeviceID, aucTargetDeviceID); -+ prMsgConnReq->fgIsTobeGO = TRUE; -+ prMsgConnReq->fgIsPersistentGroup = FALSE; -+ -+ /*=====Param Modified for test=====*/ -+ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgConnReq, MSG_SEND_METHOD_BUF); -+ -+} -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is called to retrieve permanent address from firmware -+* -+* @param prAdapter Pointer of Adapter Data Structure -+* -+* @return WLAN_STATUS_SUCCESS -+* WLAN_STATUS_FAILURE -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS wlanQueryPermanentAddress(IN P_ADAPTER_T prAdapter) -+{ -+ UINT_8 ucCmdSeqNum; -+ P_CMD_INFO_T prCmdInfo; -+ P_WIFI_CMD_T prWifiCmd; -+ UINT_32 u4RxPktLength; -+ UINT_8 aucBuffer[sizeof(WIFI_EVENT_T) + sizeof(EVENT_BASIC_CONFIG)]; -+ P_HIF_RX_HEADER_T prHifRxHdr; -+ P_WIFI_EVENT_T prEvent; -+ P_EVENT_BASIC_CONFIG prEventBasicConfig; -+ -+ ASSERT(prAdapter); -+ -+ DEBUGFUNC("wlanQueryPermanentAddress"); -+ -+ /* 1. Allocate CMD Info Packet and its Buffer */ -+ prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, CMD_HDR_SIZE + sizeof(CMD_BASIC_CONFIG)); -+ if (!prCmdInfo) { -+ DBGLOG(INIT, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); -+ return WLAN_STATUS_FAILURE; -+ } -+ /* increase command sequence number */ -+ ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter); -+ -+ /* compose CMD_BUILD_CONNECTION cmd pkt */ -+ prCmdInfo->eCmdType = COMMAND_TYPE_GENERAL_IOCTL; -+ prCmdInfo->u2InfoBufLen = CMD_HDR_SIZE + sizeof(CMD_BASIC_CONFIG); -+ prCmdInfo->pfCmdDoneHandler = NULL; -+ prCmdInfo->fgIsOid = FALSE; -+ prCmdInfo->ucCID = CMD_ID_BASIC_CONFIG; -+ prCmdInfo->fgSetQuery = FALSE; -+ prCmdInfo->fgNeedResp = TRUE; -+ prCmdInfo->fgDriverDomainMCR = FALSE; -+ prCmdInfo->ucCmdSeqNum = ucCmdSeqNum; -+ prCmdInfo->u4SetInfoLen = sizeof(CMD_BASIC_CONFIG); -+ -+ /* Setup WIFI_CMD_T */ -+ prWifiCmd = (P_WIFI_CMD_T) (prCmdInfo->pucInfoBuffer); -+ prWifiCmd->u2TxByteCount_UserPriority = prCmdInfo->u2InfoBufLen; -+ prWifiCmd->ucCID = prCmdInfo->ucCID; -+ prWifiCmd->ucSetQuery = prCmdInfo->fgSetQuery; -+ prWifiCmd->ucSeqNum = prCmdInfo->ucCmdSeqNum; -+ -+ /* send the command */ -+ wlanSendCommand(prAdapter, prCmdInfo); -+ cmdBufFreeCmdInfo(prAdapter, prCmdInfo); -+ -+ /* wait for response */ -+ if (nicRxWaitResponse(prAdapter, -+ 1, -+ aucBuffer, -+ sizeof(WIFI_EVENT_T) + sizeof(EVENT_BASIC_CONFIG), /* 8B + 12B */ -+ &u4RxPktLength) != WLAN_STATUS_SUCCESS) -+ return WLAN_STATUS_FAILURE; -+ /* header checking .. */ -+ prHifRxHdr = (P_HIF_RX_HEADER_T) aucBuffer; -+ if ((prHifRxHdr->u2PacketType & HIF_RX_HDR_PACKET_TYPE_MASK) != HIF_RX_PKT_TYPE_EVENT) -+ return WLAN_STATUS_FAILURE; -+ -+ prEvent = (P_WIFI_EVENT_T) aucBuffer; -+ if (prEvent->ucEID != EVENT_ID_BASIC_CONFIG) -+ return WLAN_STATUS_FAILURE; -+ -+ prEventBasicConfig = (P_EVENT_BASIC_CONFIG) (prEvent->aucBuffer); -+ -+ COPY_MAC_ADDR(prAdapter->rWifiVar.aucPermanentAddress, &(prEventBasicConfig->rMyMacAddr)); -+ COPY_MAC_ADDR(prAdapter->rWifiVar.aucMacAddress, &(prEventBasicConfig->rMyMacAddr)); -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is called to retrieve NIC capability from firmware -+* -+* @param prAdapter Pointer of Adapter Data Structure -+* -+* @return WLAN_STATUS_SUCCESS -+* WLAN_STATUS_FAILURE -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS wlanQueryNicCapability(IN P_ADAPTER_T prAdapter) -+{ -+ UINT_8 ucCmdSeqNum; -+ P_CMD_INFO_T prCmdInfo; -+ P_WIFI_CMD_T prWifiCmd; -+ UINT_32 u4RxPktLength; -+ UINT_32 u4FwIDVersion = 0; -+ UINT_8 aucBuffer[sizeof(WIFI_EVENT_T) + sizeof(EVENT_NIC_CAPABILITY)]; -+ P_HIF_RX_HEADER_T prHifRxHdr; -+ P_WIFI_EVENT_T prEvent; -+ P_EVENT_NIC_CAPABILITY prEventNicCapability; -+ -+ ASSERT(prAdapter); -+ -+ DEBUGFUNC("wlanQueryNicCapability"); -+ -+ /* 1. Allocate CMD Info Packet and its Buffer */ -+ prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, CMD_HDR_SIZE + sizeof(EVENT_NIC_CAPABILITY)); -+ if (!prCmdInfo) { -+ DBGLOG(INIT, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); -+ return WLAN_STATUS_FAILURE; -+ } -+ /* increase command sequence number */ -+ ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter); -+ -+ /* compose CMD_BUILD_CONNECTION cmd pkt */ -+ prCmdInfo->eCmdType = COMMAND_TYPE_GENERAL_IOCTL; -+ prCmdInfo->u2InfoBufLen = CMD_HDR_SIZE + sizeof(EVENT_NIC_CAPABILITY); -+ prCmdInfo->pfCmdDoneHandler = NULL; -+ prCmdInfo->fgIsOid = FALSE; -+ prCmdInfo->ucCID = CMD_ID_GET_NIC_CAPABILITY; -+ prCmdInfo->fgSetQuery = FALSE; -+ prCmdInfo->fgNeedResp = TRUE; -+ prCmdInfo->fgDriverDomainMCR = FALSE; -+ prCmdInfo->ucCmdSeqNum = ucCmdSeqNum; -+ prCmdInfo->u4SetInfoLen = 0; -+ -+ /* Setup WIFI_CMD_T */ -+ prWifiCmd = (P_WIFI_CMD_T) (prCmdInfo->pucInfoBuffer); -+ prWifiCmd->u2TxByteCount_UserPriority = prCmdInfo->u2InfoBufLen; -+ prWifiCmd->ucCID = prCmdInfo->ucCID; -+ prWifiCmd->ucSetQuery = prCmdInfo->fgSetQuery; -+ prWifiCmd->ucSeqNum = prCmdInfo->ucCmdSeqNum; -+ -+ /* send the command */ -+ wlanSendCommand(prAdapter, prCmdInfo); -+ cmdBufFreeCmdInfo(prAdapter, prCmdInfo); -+ -+ /* wait for FW response */ -+ if (nicRxWaitResponse(prAdapter, -+ 1, -+ aucBuffer, -+ sizeof(WIFI_EVENT_T) + sizeof(EVENT_NIC_CAPABILITY), -+ &u4RxPktLength) != WLAN_STATUS_SUCCESS) -+ return WLAN_STATUS_FAILURE; -+ /* header checking .. */ -+ prHifRxHdr = (P_HIF_RX_HEADER_T) aucBuffer; -+ if ((prHifRxHdr->u2PacketType & HIF_RX_HDR_PACKET_TYPE_MASK) != HIF_RX_PKT_TYPE_EVENT) -+ return WLAN_STATUS_FAILURE; -+ -+ prEvent = (P_WIFI_EVENT_T) aucBuffer; -+ if (prEvent->ucEID != EVENT_ID_NIC_CAPABILITY) -+ return WLAN_STATUS_FAILURE; -+ -+ prEventNicCapability = (P_EVENT_NIC_CAPABILITY) (prEvent->aucBuffer); -+ -+ prAdapter->rVerInfo.u2FwProductID = prEventNicCapability->u2ProductID; -+ prAdapter->rVerInfo.u2FwOwnVersion = prEventNicCapability->u2FwVersion; -+ prAdapter->rVerInfo.u2FwPeerVersion = prEventNicCapability->u2DriverVersion; -+ prAdapter->fgIsHw5GBandDisabled = (BOOLEAN) prEventNicCapability->ucHw5GBandDisabled; -+ prAdapter->fgIsEepromUsed = (BOOLEAN) prEventNicCapability->ucEepromUsed; -+ prAdapter->fgIsEfuseValid = (BOOLEAN) prEventNicCapability->ucEfuseValid; -+ prAdapter->fgIsEmbbededMacAddrValid = (BOOLEAN) prEventNicCapability->ucMacAddrValid; -+ -+ u4FwIDVersion = (prAdapter->rVerInfo.u2FwProductID << 16) | (prAdapter->rVerInfo.u2FwOwnVersion); -+ mtk_wcn_wmt_set_wifi_ver(u4FwIDVersion); -+#if (CFG_SUPPORT_TDLS == 1) -+ if (prEventNicCapability->ucFeatureSet & (1 << FEATURE_SET_OFFSET_TDLS)) -+ prAdapter->fgTdlsIsSup = TRUE; -+ DBGLOG(TDLS, TRACE, " support flag: 0x%x\n", prEventNicCapability->ucFeatureSet); -+#else -+ prAdapter->fgTdlsIsSup = 0; -+#endif /* CFG_SUPPORT_TDLS */ -+ -+ if (!(prEventNicCapability->ucFeatureSet & (1 << FEATURE_SET_OFFSET_5G_SUPPORT))) -+ prAdapter->fgEnable5GBand = FALSE; /* firmware does not support */ -+ -+#if CFG_ENABLE_CAL_LOG -+ DBGLOG(INIT, LOUD, " RF CAL FAIL = (%d),BB CAL FAIL = (%d)\n", -+ prEventNicCapability->ucRfCalFail, prEventNicCapability->ucBbCalFail); -+#endif -+ return WLAN_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is called to retrieve NIC capability from firmware -+* -+* @param prAdapter Pointer of Adapter Data Structure -+* -+* @return WLAN_STATUS_SUCCESS -+* WLAN_STATUS_FAILURE -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS wlanQueryDebugCode(IN P_ADAPTER_T prAdapter) -+{ -+ UINT_8 ucCmdSeqNum; -+ P_CMD_INFO_T prCmdInfo; -+ P_WIFI_CMD_T prWifiCmd; -+ -+ ASSERT(prAdapter); -+ -+ DEBUGFUNC("wlanQueryDebugCode"); -+ -+ /* 1. Allocate CMD Info Packet and its Buffer */ -+ prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, CMD_HDR_SIZE); -+ if (!prCmdInfo) { -+ DBGLOG(INIT, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); -+ return WLAN_STATUS_FAILURE; -+ } -+ /* increase command sequence number */ -+ ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter); -+ -+ /* compose CMD_BUILD_CONNECTION cmd pkt */ -+ prCmdInfo->eCmdType = COMMAND_TYPE_GENERAL_IOCTL; -+ prCmdInfo->u2InfoBufLen = CMD_HDR_SIZE; -+ prCmdInfo->pfCmdDoneHandler = NULL; -+ prCmdInfo->fgIsOid = FALSE; -+ prCmdInfo->ucCID = CMD_ID_GET_DEBUG_CODE; -+ prCmdInfo->fgSetQuery = FALSE; -+ prCmdInfo->fgNeedResp = FALSE; -+ prCmdInfo->fgDriverDomainMCR = FALSE; -+ prCmdInfo->ucCmdSeqNum = ucCmdSeqNum; -+ prCmdInfo->u4SetInfoLen = 0; -+ -+ /* Setup WIFI_CMD_T */ -+ prWifiCmd = (P_WIFI_CMD_T) (prCmdInfo->pucInfoBuffer); -+ prWifiCmd->u2TxByteCount_UserPriority = prCmdInfo->u2InfoBufLen; -+ prWifiCmd->ucCID = prCmdInfo->ucCID; -+ prWifiCmd->ucSetQuery = prCmdInfo->fgSetQuery; -+ prWifiCmd->ucSeqNum = prCmdInfo->ucCmdSeqNum; -+ -+ /* send the command */ -+ wlanSendCommand(prAdapter, prCmdInfo); -+ cmdBufFreeCmdInfo(prAdapter, prCmdInfo); -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is called to retrieve compiler flag from firmware -+* -+* @param prAdapter Pointer of Adapter Data Structure -+* -+* @return WLAN_STATUS_SUCCESS -+* WLAN_STATUS_FAILURE -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS wlanQueryCompileFlag(IN P_ADAPTER_T prAdapter, IN UINT_32 u4QueryID, OUT PUINT_32 pu4CompilerFlag) -+{ -+ UINT_8 ucCmdSeqNum; -+ P_CMD_INFO_T prCmdInfo; -+ P_WIFI_CMD_T prWifiCmd; -+ UINT_32 u4RxPktLength; -+ UINT_8 aucBuffer[sizeof(WIFI_EVENT_T) + sizeof(CMD_SW_DBG_CTRL_T)]; -+ P_HIF_RX_HEADER_T prHifRxHdr; -+ P_WIFI_EVENT_T prEvent; -+ P_CMD_SW_DBG_CTRL_T prCmdNicCompileFlag, prEventNicCompileFlag; -+ -+ ASSERT(prAdapter); -+ -+ DEBUGFUNC(__func__); -+ -+ /* 1. Allocate CMD Info Packet and its Buffer */ -+ prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, CMD_HDR_SIZE + sizeof(CMD_SW_DBG_CTRL_T)); -+ if (!prCmdInfo) { -+ DBGLOG(INIT, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); -+ return WLAN_STATUS_FAILURE; -+ } -+ /* increase command sequence number */ -+ ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter); -+ -+ /* compose CMD_BUILD_CONNECTION cmd pkt */ -+ prCmdInfo->eCmdType = COMMAND_TYPE_GENERAL_IOCTL; -+ prCmdInfo->u2InfoBufLen = CMD_HDR_SIZE + sizeof(CMD_SW_DBG_CTRL_T); -+ prCmdInfo->pfCmdDoneHandler = NULL; -+ prCmdInfo->fgIsOid = FALSE; -+ prCmdInfo->ucCID = CMD_ID_SW_DBG_CTRL; -+ prCmdInfo->fgSetQuery = FALSE; -+ prCmdInfo->fgNeedResp = TRUE; -+ prCmdInfo->fgDriverDomainMCR = FALSE; -+ prCmdInfo->ucCmdSeqNum = ucCmdSeqNum; -+ prCmdInfo->u4SetInfoLen = 0; -+ -+ /* Setup WIFI_CMD_T */ -+ prWifiCmd = (P_WIFI_CMD_T) (prCmdInfo->pucInfoBuffer); -+ prWifiCmd->u2TxByteCount_UserPriority = prCmdInfo->u2InfoBufLen; -+ prWifiCmd->ucCID = prCmdInfo->ucCID; -+ prWifiCmd->ucSetQuery = prCmdInfo->fgSetQuery; -+ prWifiCmd->ucSeqNum = prCmdInfo->ucCmdSeqNum; -+ -+ /* Fill up SW CR */ -+ prCmdNicCompileFlag = (P_CMD_SW_DBG_CTRL_T) (prWifiCmd->aucBuffer); -+ -+ prCmdNicCompileFlag->u4Id = u4QueryID; -+ -+ wlanSendCommand(prAdapter, prCmdInfo); -+ cmdBufFreeCmdInfo(prAdapter, prCmdInfo); -+ -+ if (nicRxWaitResponse(prAdapter, -+ 1, -+ aucBuffer, -+ sizeof(WIFI_EVENT_T) + sizeof(CMD_SW_DBG_CTRL_T), -+ &u4RxPktLength) != WLAN_STATUS_SUCCESS) -+ return WLAN_STATUS_FAILURE; -+ /* header checking .. */ -+ prHifRxHdr = (P_HIF_RX_HEADER_T) aucBuffer; -+ if ((prHifRxHdr->u2PacketType & HIF_RX_HDR_PACKET_TYPE_MASK) != HIF_RX_PKT_TYPE_EVENT) -+ return WLAN_STATUS_FAILURE; -+ -+ prEvent = (P_WIFI_EVENT_T) aucBuffer; -+ if (prEvent->ucEID != EVENT_ID_SW_DBG_CTRL) -+ return WLAN_STATUS_FAILURE; -+ -+ prEventNicCompileFlag = (P_CMD_SW_DBG_CTRL_T) (prEvent->aucBuffer); -+ -+ *pu4CompilerFlag = prEventNicCompileFlag->u4Data; -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+WLAN_STATUS wlanQueryCompileFlags(IN P_ADAPTER_T prAdapter) -+{ -+ wlanQueryCompileFlag(prAdapter, 0xA0240000, &prAdapter->u4FwCompileFlag0); -+ wlanQueryCompileFlag(prAdapter, 0xA0240001, &prAdapter->u4FwCompileFlag1); -+ -+ DBGLOG(INIT, TRACE, -+ "Compile Flags: 0x%08x 0x%08x\n", prAdapter->u4FwCompileFlag0, prAdapter->u4FwCompileFlag1); -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+#if defined(MT6628) -+static INT_32 wlanChangeCodeWord(INT_32 au4Input) -+{ -+ -+ UINT_16 i; -+#if TXPWR_USE_PDSLOPE -+ CODE_MAPPING_T arCodeTable[] = { -+ {0X100, -40}, -+ {0X104, -35}, -+ {0X128, -30}, -+ {0X14C, -25}, -+ {0X170, -20}, -+ {0X194, -15}, -+ {0X1B8, -10}, -+ {0X1DC, -5}, -+ {0, 0}, -+ {0X24, 5}, -+ {0X48, 10}, -+ {0X6C, 15}, -+ {0X90, 20}, -+ {0XB4, 25}, -+ {0XD8, 30}, -+ {0XFC, 35}, -+ {0XFF, 40}, -+ -+ }; -+#else -+ CODE_MAPPING_T arCodeTable[] = { -+ {0X100, 0x80}, -+ {0X104, 0x80}, -+ {0X128, 0x80}, -+ {0X14C, 0x80}, -+ {0X170, 0x80}, -+ {0X194, 0x94}, -+ {0X1B8, 0XB8}, -+ {0X1DC, 0xDC}, -+ {0, 0}, -+ {0X24, 0x24}, -+ {0X48, 0x48}, -+ {0X6C, 0x6c}, -+ {0X90, 0x7F}, -+ {0XB4, 0x7F}, -+ {0XD8, 0x7F}, -+ {0XFC, 0x7F}, -+ {0XFF, 0x7F}, -+ -+ }; -+#endif -+ -+ for (i = 0; i < sizeof(arCodeTable) / sizeof(CODE_MAPPING_T); i++) { -+ -+ if (arCodeTable[i].u4RegisterValue == au4Input) -+ return arCodeTable[i].i4TxpowerOffset; -+ } -+ -+ return 0; -+} -+#endif -+ -+#if TXPWR_USE_PDSLOPE -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief -+* -+* @param prAdapter Pointer of Adapter Data Structure -+* -+* @return WLAN_STATUS_SUCCESS -+* WLAN_STATUS_FAILURE -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS wlanQueryPdMcr(IN P_ADAPTER_T prAdapter, P_PARAM_MCR_RW_STRUCT_T prMcrRdInfo) -+{ -+ UINT_8 ucCmdSeqNum; -+ P_CMD_INFO_T prCmdInfo; -+ P_WIFI_CMD_T prWifiCmd; -+ UINT_32 u4RxPktLength; -+ UINT_8 aucBuffer[sizeof(WIFI_EVENT_T) + sizeof(CMD_ACCESS_REG)]; -+ P_HIF_RX_HEADER_T prHifRxHdr; -+ P_WIFI_EVENT_T prEvent; -+ P_CMD_ACCESS_REG prCmdMcrQuery; -+ -+ ASSERT(prAdapter); -+ -+ /* 1. Allocate CMD Info Packet and its Buffer */ -+ prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, CMD_HDR_SIZE + sizeof(CMD_ACCESS_REG)); -+ -+ if (!prCmdInfo) { -+ DBGLOG(INIT, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); -+ return WLAN_STATUS_FAILURE; -+ } -+ /* increase command sequence number */ -+ ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter); -+ -+ /* compose CMD_BUILD_CONNECTION cmd pkt */ -+ prCmdInfo->eCmdType = COMMAND_TYPE_GENERAL_IOCTL; -+ prCmdInfo->u2InfoBufLen = (UINT_16) (CMD_HDR_SIZE + sizeof(CMD_ACCESS_REG)); -+ prCmdInfo->pfCmdDoneHandler = NULL; -+ prCmdInfo->pfCmdTimeoutHandler = nicOidCmdTimeoutCommon; -+ prCmdInfo->fgIsOid = FALSE; -+ prCmdInfo->ucCID = CMD_ID_ACCESS_REG; -+ prCmdInfo->fgSetQuery = FALSE; -+ prCmdInfo->fgNeedResp = TRUE; -+ prCmdInfo->fgDriverDomainMCR = FALSE; -+ prCmdInfo->ucCmdSeqNum = ucCmdSeqNum; -+ prCmdInfo->u4SetInfoLen = sizeof(CMD_ACCESS_REG); -+ -+ /* Setup WIFI_CMD_T */ -+ prWifiCmd = (P_WIFI_CMD_T) (prCmdInfo->pucInfoBuffer); -+ prWifiCmd->u2TxByteCount_UserPriority = prCmdInfo->u2InfoBufLen; -+ prWifiCmd->ucCID = prCmdInfo->ucCID; -+ prWifiCmd->ucSetQuery = prCmdInfo->fgSetQuery; -+ prWifiCmd->ucSeqNum = prCmdInfo->ucCmdSeqNum; -+ kalMemCopy(prWifiCmd->aucBuffer, prMcrRdInfo, sizeof(CMD_ACCESS_REG)); -+ -+ wlanSendCommand(prAdapter, prCmdInfo); -+ cmdBufFreeCmdInfo(prAdapter, prCmdInfo); -+ -+ if (nicRxWaitResponse(prAdapter, -+ 1, -+ aucBuffer, -+ sizeof(WIFI_EVENT_T) + sizeof(CMD_ACCESS_REG), &u4RxPktLength) != WLAN_STATUS_SUCCESS) -+ return WLAN_STATUS_FAILURE; -+ /* header checking .. */ -+ prHifRxHdr = (P_HIF_RX_HEADER_T) aucBuffer; -+ if ((prHifRxHdr->u2PacketType & HIF_RX_HDR_PACKET_TYPE_MASK) != HIF_RX_PKT_TYPE_EVENT) -+ return WLAN_STATUS_FAILURE; -+ -+ prEvent = (P_WIFI_EVENT_T) aucBuffer; -+ -+ if (prEvent->ucEID != EVENT_ID_ACCESS_REG) -+ return WLAN_STATUS_FAILURE; -+ -+ prCmdMcrQuery = (P_CMD_ACCESS_REG) (prEvent->aucBuffer); -+ prMcrRdInfo->u4McrOffset = prCmdMcrQuery->u4Address; -+ prMcrRdInfo->u4McrData = prCmdMcrQuery->u4Data; -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+static INT_32 wlanIntRound(INT_32 au4Input) -+{ -+ -+ if (au4Input >= 0) { -+ if ((au4Input % 10) == 5) { -+ au4Input = au4Input + 5; -+ return au4Input; -+ } -+ } -+ -+ if (au4Input < 0) { -+ if ((au4Input % 10) == -5) { -+ au4Input = au4Input - 5; -+ return au4Input; -+ } -+ } -+ -+ return au4Input; -+} -+ -+static INT_32 wlanCal6628EfuseForm(IN P_ADAPTER_T prAdapter, INT_32 au4Input) -+{ -+ -+ PARAM_MCR_RW_STRUCT_T rMcrRdInfo; -+ INT_32 au4PdSlope, au4TxPwrOffset, au4TxPwrOffset_Round; -+ INT_8 auTxPwrOffset_Round; -+ -+ rMcrRdInfo.u4McrOffset = 0x60205c68; -+ rMcrRdInfo.u4McrData = 0; -+ au4TxPwrOffset = au4Input; -+ wlanQueryPdMcr(prAdapter, &rMcrRdInfo); -+ -+ au4PdSlope = (rMcrRdInfo.u4McrData) & BITS(0, 6); -+ au4TxPwrOffset_Round = wlanIntRound((au4TxPwrOffset * au4PdSlope)) / 10; -+ -+ au4TxPwrOffset_Round = -au4TxPwrOffset_Round; -+ -+ if (au4TxPwrOffset_Round < -128) -+ au4TxPwrOffset_Round = 128; -+ else if (au4TxPwrOffset_Round < 0) -+ au4TxPwrOffset_Round += 256; -+ else if (au4TxPwrOffset_Round > 127) -+ au4TxPwrOffset_Round = 127; -+ -+ auTxPwrOffset_Round = (UINT8) au4TxPwrOffset_Round; -+ -+ return au4TxPwrOffset_Round; -+} -+ -+#endif -+ -+#if defined(MT6628) -+static VOID wlanChangeNvram6620to6628(PUINT_8 pucEFUSE) -+{ -+ -+#define EFUSE_CH_OFFSET1_L_MASK_6620 BITS(0, 8) -+#define EFUSE_CH_OFFSET1_L_SHIFT_6620 0 -+#define EFUSE_CH_OFFSET1_M_MASK_6620 BITS(9, 17) -+#define EFUSE_CH_OFFSET1_M_SHIFT_6620 9 -+#define EFUSE_CH_OFFSET1_H_MASK_6620 BITS(18, 26) -+#define EFUSE_CH_OFFSET1_H_SHIFT_6620 18 -+#define EFUSE_CH_OFFSET1_VLD_MASK_6620 BIT(27) -+#define EFUSE_CH_OFFSET1_VLD_SHIFT_6620 27 -+ -+#define EFUSE_CH_OFFSET1_L_MASK_5931 BITS(0, 7) -+#define EFUSE_CH_OFFSET1_L_SHIFT_5931 0 -+#define EFUSE_CH_OFFSET1_M_MASK_5931 BITS(8, 15) -+#define EFUSE_CH_OFFSET1_M_SHIFT_5931 8 -+#define EFUSE_CH_OFFSET1_H_MASK_5931 BITS(16, 23) -+#define EFUSE_CH_OFFSET1_H_SHIFT_5931 16 -+#define EFUSE_CH_OFFSET1_VLD_MASK_5931 BIT(24) -+#define EFUSE_CH_OFFSET1_VLD_SHIFT_5931 24 -+#define EFUSE_ALL_CH_OFFSET1_MASK_5931 BITS(25, 27) -+#define EFUSE_ALL_CH_OFFSET1_SHIFT_5931 25 -+ -+ INT_32 au4ChOffset; -+ INT_16 au2ChOffsetL, au2ChOffsetM, au2ChOffsetH; -+ -+ au4ChOffset = *(UINT_32 *) (pucEFUSE + 72); -+ -+ if ((au4ChOffset & EFUSE_CH_OFFSET1_VLD_MASK_6620) && ((*(UINT_32 *) (pucEFUSE + 28)) == 0)) { -+ -+ au2ChOffsetL = ((au4ChOffset & EFUSE_CH_OFFSET1_L_MASK_6620) >> EFUSE_CH_OFFSET1_L_SHIFT_6620); -+ -+ au2ChOffsetM = ((au4ChOffset & EFUSE_CH_OFFSET1_M_MASK_6620) >> EFUSE_CH_OFFSET1_M_SHIFT_6620); -+ -+ au2ChOffsetH = ((au4ChOffset & EFUSE_CH_OFFSET1_H_MASK_6620) >> EFUSE_CH_OFFSET1_H_SHIFT_6620); -+ -+ au2ChOffsetL = wlanChangeCodeWord(au2ChOffsetL); -+ au2ChOffsetM = wlanChangeCodeWord(au2ChOffsetM); -+ au2ChOffsetH = wlanChangeCodeWord(au2ChOffsetH); -+ -+ au4ChOffset = 0; -+ au4ChOffset |= *(UINT_32 *) (pucEFUSE + 72) -+ >> (EFUSE_CH_OFFSET1_VLD_SHIFT_6620 - -+ EFUSE_CH_OFFSET1_VLD_SHIFT_5931) & EFUSE_CH_OFFSET1_VLD_MASK_5931; -+ -+ au4ChOffset |= -+ ((((UINT_32) au2ChOffsetL) << EFUSE_CH_OFFSET1_L_SHIFT_5931) & EFUSE_CH_OFFSET1_L_MASK_5931); -+ au4ChOffset |= -+ ((((UINT_32) au2ChOffsetM) << EFUSE_CH_OFFSET1_M_SHIFT_5931) & EFUSE_CH_OFFSET1_M_MASK_5931); -+ au4ChOffset |= -+ ((((UINT_32) au2ChOffsetH) << EFUSE_CH_OFFSET1_H_SHIFT_5931) & EFUSE_CH_OFFSET1_H_MASK_5931); -+ -+ *((INT_32 *) ((pucEFUSE + 28))) = au4ChOffset; -+ -+ } -+ -+} -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is called to load manufacture data from NVRAM -+* if available and valid -+* -+* @param prAdapter Pointer of Adapter Data Structure -+* @param prRegInfo Pointer of REG_INFO_T -+* -+* @return WLAN_STATUS_SUCCESS -+* WLAN_STATUS_FAILURE -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS wlanLoadManufactureData(IN P_ADAPTER_T prAdapter, IN P_REG_INFO_T prRegInfo) -+{ -+#if CFG_SUPPORT_RDD_TEST_MODE -+ CMD_RDD_CH_T rRddParam; -+#endif -+ -+ ASSERT(prAdapter); -+ -+ /* 1. Version Check */ -+ kalGetConfigurationVersion(prAdapter->prGlueInfo, -+ &(prAdapter->rVerInfo.u2Part1CfgOwnVersion), -+ &(prAdapter->rVerInfo.u2Part1CfgPeerVersion), -+ &(prAdapter->rVerInfo.u2Part2CfgOwnVersion), -+ &(prAdapter->rVerInfo.u2Part2CfgPeerVersion)); -+ -+#if (CFG_SW_NVRAM_VERSION_CHECK == 1) -+ if (CFG_DRV_OWN_VERSION < prAdapter->rVerInfo.u2Part1CfgPeerVersion -+ || CFG_DRV_OWN_VERSION < prAdapter->rVerInfo.u2Part2CfgPeerVersion -+ || prAdapter->rVerInfo.u2Part1CfgOwnVersion <= CFG_DRV_PEER_VERSION -+ || prAdapter->rVerInfo.u2Part2CfgOwnVersion <= CFG_DRV_PEER_VERSION) { -+ return WLAN_STATUS_FAILURE; -+ } -+#endif -+ -+ /* MT6620 E1/E2 would be ignored directly */ -+ if (prAdapter->rVerInfo.u2Part1CfgOwnVersion == 0x0001) { -+ prRegInfo->ucTxPwrValid = 1; -+ } else { -+ /* 2. Load TX power gain parameters if valid */ -+ if (prRegInfo->ucTxPwrValid != 0) { -+ /* send to F/W */ -+ nicUpdateTxPower(prAdapter, (P_CMD_TX_PWR_T) (&(prRegInfo->rTxPwr))); -+ } -+ } -+ -+ /* Workaround for supporting 5G */ -+ prRegInfo->ucEnable5GBand = 1; -+ prRegInfo->ucSupport5GBand = 1; -+ -+ /* 3. Check if needs to support 5GHz */ -+ /* if(prRegInfo->ucEnable5GBand) { // Frank workaround */ -+ if (1) { -+ /* check if it is disabled by hardware */ -+ if (prAdapter->fgIsHw5GBandDisabled || prRegInfo->ucSupport5GBand == 0) -+ prAdapter->fgEnable5GBand = FALSE; -+ else -+ prAdapter->fgEnable5GBand = TRUE; -+ } else -+ prAdapter->fgEnable5GBand = FALSE; -+ /* Workaround for supporting 5G */ -+ prAdapter->fgEnable5GBand = TRUE; -+/* -+ DBGLOG(INIT, INFO, "NVRAM 5G Enable(%d) SW_En(%d) HW_Dis(%d)\n", -+ prRegInfo->ucEnable5GBand, prRegInfo->ucSupport5GBand, prAdapter->fgIsHw5GBandDisabled); -+*/ -+ /* 4. Send EFUSE data */ -+#if defined(MT6628) -+ wlanChangeNvram6620to6628(prRegInfo->aucEFUSE); -+#endif -+ -+ wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SET_PHY_PARAM, -+ TRUE, -+ FALSE, -+ FALSE, NULL, NULL, sizeof(CMD_PHY_PARAM_T), (PUINT_8) (prRegInfo->aucEFUSE), NULL, 0); -+ -+#if CFG_SUPPORT_RDD_TEST_MODE -+ rRddParam.ucRddTestMode = (UINT_8) prRegInfo->u4RddTestMode; -+ rRddParam.ucRddShutCh = (UINT_8) prRegInfo->u4RddShutFreq; -+ rRddParam.ucRddStartCh = (UINT_8) nicFreq2ChannelNum(prRegInfo->u4RddStartFreq); -+ rRddParam.ucRddStopCh = (UINT_8) nicFreq2ChannelNum(prRegInfo->u4RddStopFreq); -+ rRddParam.ucRddDfs = (UINT_8) prRegInfo->u4RddDfs; -+ prAdapter->ucRddStatus = 0; -+ nicUpdateRddTestMode(prAdapter, (P_CMD_RDD_CH_T) (&rRddParam)); -+#endif -+ -+ /* 5. Get 16-bits Country Code and Bandwidth */ -+ prAdapter->rWifiVar.rConnSettings.u2CountryCode = -+ (((UINT_16) prRegInfo->au2CountryCode[0]) << 8) | (((UINT_16) prRegInfo->au2CountryCode[1]) & BITS(0, 7)); -+ -+ DBGLOG(INIT, INFO, "NVRAM 5G Enable(%d) SW_En(%d) HW_Dis(%d) CountryCode(0x%x 0x%x)\n", -+ prRegInfo->ucEnable5GBand, prRegInfo->ucSupport5GBand, prAdapter->fgIsHw5GBandDisabled, -+ prRegInfo->au2CountryCode[0], prRegInfo->au2CountryCode[1]); -+ -+#if 0 /* Bandwidth control will be controlled by GUI. 20110930 -+ * So ignore the setting from registry/NVRAM -+ */ -+ prAdapter->rWifiVar.rConnSettings.uc2G4BandwidthMode = -+ prRegInfo->uc2G4BwFixed20M ? CONFIG_BW_20M : CONFIG_BW_20_40M; -+ prAdapter->rWifiVar.rConnSettings.uc5GBandwidthMode = -+ prRegInfo->uc5GBwFixed20M ? CONFIG_BW_20M : CONFIG_BW_20_40M; -+#endif -+ -+ /* 6. Set domain and channel information to chip */ -+ rlmDomainSendCmd(prAdapter, FALSE); -+ /* Update supported channel list in channel table */ -+ wlanUpdateChannelTable(prAdapter->prGlueInfo); -+ -+ /* 7. Set band edge tx power if available */ -+ if (prRegInfo->fg2G4BandEdgePwrUsed) { -+ CMD_EDGE_TXPWR_LIMIT_T rCmdEdgeTxPwrLimit; -+ -+ rCmdEdgeTxPwrLimit.cBandEdgeMaxPwrCCK = prRegInfo->cBandEdgeMaxPwrCCK; -+ rCmdEdgeTxPwrLimit.cBandEdgeMaxPwrOFDM20 = prRegInfo->cBandEdgeMaxPwrOFDM20; -+ rCmdEdgeTxPwrLimit.cBandEdgeMaxPwrOFDM40 = prRegInfo->cBandEdgeMaxPwrOFDM40; -+ -+ DBGLOG(INIT, TRACE, "NVRAM 2G Bandedge CCK(%d) HT20(%d)HT40(%d)\n", -+ rCmdEdgeTxPwrLimit.cBandEdgeMaxPwrCCK, -+ rCmdEdgeTxPwrLimit.cBandEdgeMaxPwrOFDM20, rCmdEdgeTxPwrLimit.cBandEdgeMaxPwrOFDM40); -+ -+ wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SET_EDGE_TXPWR_LIMIT, -+ TRUE, -+ FALSE, -+ FALSE, -+ NULL, -+ NULL, sizeof(CMD_EDGE_TXPWR_LIMIT_T), (PUINT_8)&rCmdEdgeTxPwrLimit, NULL, 0); -+ } -+ /* 8. set 5G band edge tx power if available (add for 6625) */ -+ if (prAdapter->fgEnable5GBand) { -+#define NVRAM_5G_TX_BANDEDGE_VALID_OFFSET 10 -+#define NVRAM_5G_TX_BANDEDGE_OFDM20_OFFSET 11 -+#define NVRAM_5G_TX_BANDEDGE_OFDM40_OFFSET 12 -+ -+ if (prRegInfo->aucEFUSE[NVRAM_5G_TX_BANDEDGE_VALID_OFFSET]) { -+ CMD_EDGE_TXPWR_LIMIT_T rCmdEdgeTxPwrLimit; -+ -+ rCmdEdgeTxPwrLimit.cBandEdgeMaxPwrOFDM20 -+ = prRegInfo->aucEFUSE[NVRAM_5G_TX_BANDEDGE_OFDM20_OFFSET]; -+ rCmdEdgeTxPwrLimit.cBandEdgeMaxPwrOFDM40 -+ = prRegInfo->aucEFUSE[NVRAM_5G_TX_BANDEDGE_OFDM40_OFFSET]; -+ -+ DBGLOG(INIT, TRACE, "NVRAM 5G Bandedge HT20(%d)HT40(%d)\n", -+ rCmdEdgeTxPwrLimit.cBandEdgeMaxPwrOFDM20, rCmdEdgeTxPwrLimit.cBandEdgeMaxPwrOFDM40); -+ -+ wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SET_5G_EDGE_TXPWR_LIMIT, -+ TRUE, -+ FALSE, -+ FALSE, -+ NULL, -+ NULL, -+ sizeof(CMD_EDGE_TXPWR_LIMIT_T), (PUINT_8)&rCmdEdgeTxPwrLimit, NULL, 0); -+ } -+ } -+ /* 9. set RSSI compensation */ -+ /* DBGLOG(INIT, INFO, ("[frank] RSSI valid(%d) 2G(%d) 5G(%d)", -+ prRegInfo->fgRssiCompensationValidbit, -+ prRegInfo->uc2GRssiCompensation, -+ prRegInfo->uc5GRssiCompensation)); */ -+ if (prRegInfo->fgRssiCompensationValidbit) { -+ CMD_RSSI_COMPENSATE_T rCmdRssiCompensate; -+ -+ rCmdRssiCompensate.uc2GRssiCompensation = prRegInfo->uc2GRssiCompensation; -+ rCmdRssiCompensate.uc5GRssiCompensation = prRegInfo->uc5GRssiCompensation; -+ -+ DBGLOG(INIT, LOUD, "NVRAM RSSI Comp. 2G(%d)5G(%d)\n", -+ rCmdRssiCompensate.uc2GRssiCompensation, rCmdRssiCompensate.uc5GRssiCompensation); -+ wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SET_RSSI_COMPENSATE, -+ TRUE, -+ FALSE, -+ FALSE, -+ NULL, NULL, sizeof(CMD_RSSI_COMPENSATE_T), (PUINT_8)&rCmdRssiCompensate, NULL, 0); -+ } -+ /* 10. notify FW Band Support 5G */ -+ if (prAdapter->fgEnable5GBand) { -+ CMD_BAND_SUPPORT_T rCmdBandSupport; -+ -+ rCmdBandSupport.uc5GBandSupport = TRUE; -+ DBGLOG(INIT, TRACE, "NVRAM 5G BandSupport\n"); -+ wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SET_BAND_SUPPORT, -+ TRUE, -+ FALSE, -+ FALSE, -+ NULL, NULL, sizeof(CMD_BAND_SUPPORT_T), (PUINT_8)&rCmdBandSupport, NULL, 0); -+ -+ } -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is called to check -+* Media Stream Mode is set to non-default value or not, -+* and clear to default value if above criteria is met -+* -+* @param prAdapter Pointer of Adapter Data Structure -+* -+* @return TRUE -+* The media stream mode was non-default value and has been reset -+* FALSE -+* The media stream mode is default value -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN wlanResetMediaStreamMode(IN P_ADAPTER_T prAdapter) -+{ -+ ASSERT(prAdapter); -+ -+ if (prAdapter->rWlanInfo.eLinkAttr.ucMediaStreamMode != 0) { -+ prAdapter->rWlanInfo.eLinkAttr.ucMediaStreamMode = 0; -+ -+ return TRUE; -+ } else { -+ return FALSE; -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is called to check if any pending timer has expired -+* -+* @param prAdapter Pointer of Adapter Data Structure -+* -+* @return WLAN_STATUS_SUCCESS -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS wlanTimerTimeoutCheck(IN P_ADAPTER_T prAdapter) -+{ -+ ASSERT(prAdapter); -+ -+ /* check timer status */ -+ cnmTimerDoTimeOutCheck(prAdapter); -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is called to check if any pending mailbox message -+* to be handled -+* -+* @param prAdapter Pointer of Adapter Data Structure -+* -+* @return WLAN_STATUS_SUCCESS -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS wlanProcessMboxMessage(IN P_ADAPTER_T prAdapter) -+{ -+ UINT_32 i; -+ -+ ASSERT(prAdapter); -+ -+ for (i = 0; i < MBOX_ID_TOTAL_NUM; i++) { /* MBOX_ID_TOTAL_NUM = 1 */ -+ mboxRcvAllMsg(prAdapter, (ENUM_MBOX_ID_T) i); -+ } -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is called to enqueue a single TX packet into CORE -+* -+* @param prAdapter Pointer of Adapter Data Structure -+* prNativePacket Pointer of Native Packet -+* -+* @return WLAN_STATUS_SUCCESS -+* WLAN_STATUS_RESOURCES -+* WLAN_STATUS_INVALID_PACKET -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS wlanEnqueueTxPacket(IN P_ADAPTER_T prAdapter, IN P_NATIVE_PACKET prNativePacket) -+{ -+ P_TX_CTRL_T prTxCtrl; -+ P_MSDU_INFO_T prMsduInfo; -+ -+ KAL_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(prAdapter); -+ -+ prTxCtrl = &prAdapter->rTxCtrl; -+ -+ /* get a free packet header */ -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_MSDU_INFO_LIST); -+ QUEUE_REMOVE_HEAD(&prTxCtrl->rFreeMsduInfoList, prMsduInfo, P_MSDU_INFO_T); -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_MSDU_INFO_LIST); -+ -+ if (prMsduInfo == NULL) -+ return WLAN_STATUS_RESOURCES; -+ -+ prMsduInfo->eSrc = TX_PACKET_OS; -+ -+ if (nicTxFillMsduInfo(prAdapter, prMsduInfo, prNativePacket) == FALSE) { -+ /* packet is not extractable */ -+ -+ /* fill fails */ -+ kalSendComplete(prAdapter->prGlueInfo, prNativePacket, WLAN_STATUS_INVALID_PACKET); -+ -+ nicTxReturnMsduInfo(prAdapter, prMsduInfo); -+ -+ return WLAN_STATUS_INVALID_PACKET; -+ } -+ /* enqueue to QM */ -+ nicTxEnqueueMsdu(prAdapter, prMsduInfo); -+ return WLAN_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is called to flush pending TX packets in CORE -+* -+* @param prAdapter Pointer of Adapter Data Structure -+* -+* @return WLAN_STATUS_SUCCESS -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS wlanFlushTxPendingPackets(IN P_ADAPTER_T prAdapter) -+{ -+ ASSERT(prAdapter); -+ -+ return nicTxFlush(prAdapter); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief this function sends pending MSDU_INFO_T to MT6620 -+* -+* @param prAdapter Pointer to the Adapter structure. -+* @param pfgHwAccess Pointer for tracking LP-OWN status -+* -+* @retval WLAN_STATUS_SUCCESS Reset is done successfully. -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS wlanTxPendingPackets(IN P_ADAPTER_T prAdapter, IN OUT PBOOLEAN pfgHwAccess) -+{ -+ P_TX_CTRL_T prTxCtrl; -+ P_MSDU_INFO_T prMsduInfo; -+ -+ KAL_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(prAdapter); -+ prTxCtrl = &prAdapter->rTxCtrl; -+ -+ ASSERT(pfgHwAccess); -+ -+ /* <1> dequeue packets by txDequeuTxPackets() */ -+ /* Note: prMsduInfo is a packet list queue */ -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_QM_TX_QUEUE); -+ prMsduInfo = qmDequeueTxPackets(prAdapter, &prTxCtrl->rTc); -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_QM_TX_QUEUE); -+ -+ if (prMsduInfo != NULL) { -+ if (kalIsCardRemoved(prAdapter->prGlueInfo) == FALSE) { -+ /* <2> Acquire LP-OWN if necessary */ -+ if (*pfgHwAccess == FALSE) { -+ *pfgHwAccess = TRUE; -+ -+ wlanAcquirePowerControl(prAdapter); -+ } -+#if (MT6620_E1_ASIC_HIFSYS_WORKAROUND == 1) -+ if (prAdapter->fgIsClockGatingEnabled == TRUE) -+ nicDisableClockGating(prAdapter); -+#endif -+ /* <3> send packet"s" to HIF */ -+ nicTxMsduInfoList(prAdapter, prMsduInfo); -+ -+ /* <4> update TC by txAdjustTcQuotas() */ -+ nicTxAdjustTcq(prAdapter); -+ } else -+ wlanProcessQueuedMsduInfo(prAdapter, prMsduInfo); /* free the packet */ -+ } -+#if (MT6620_E1_ASIC_HIFSYS_WORKAROUND == 1) -+ if (prAdapter->fgIsClockGatingEnabled == FALSE) -+ nicEnableClockGating(prAdapter); -+#endif -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is called to acquire power control from firmware -+* -+* @param prAdapter Pointer of Adapter Data Structure -+* -+* @return WLAN_STATUS_SUCCESS -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS wlanAcquirePowerControl(IN P_ADAPTER_T prAdapter) -+{ -+ ASSERT(prAdapter); -+ -+ /* do driver own */ -+ ACQUIRE_POWER_CONTROL_FROM_PM(prAdapter); -+ -+ /* Reset sleepy state *//* no use */ -+ if (prAdapter->fgWiFiInSleepyState == TRUE) -+ prAdapter->fgWiFiInSleepyState = FALSE; -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is called to release power control to firmware -+* -+* @param prAdapter Pointer of Adapter Data Structure -+* -+* @return WLAN_STATUS_SUCCESS -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS wlanReleasePowerControl(IN P_ADAPTER_T prAdapter) -+{ -+ ASSERT(prAdapter); -+ -+ /* do FW own */ -+ RECLAIM_POWER_CONTROL_TO_PM(prAdapter, FALSE); -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is called to report currently pending TX frames count -+* (command packets are not included) -+* -+* @param prAdapter Pointer of Adapter Data Structure -+* -+* @return number of pending TX frames -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT_32 wlanGetTxPendingFrameCount(IN P_ADAPTER_T prAdapter) -+{ -+ P_TX_CTRL_T prTxCtrl; -+ UINT_32 u4Num; -+ -+ ASSERT(prAdapter); -+ prTxCtrl = &prAdapter->rTxCtrl; -+ -+ /* number in prTxQueue + number in RX forward */ -+ u4Num = kalGetTxPendingFrameCount(prAdapter->prGlueInfo) + (UINT_32) (prTxCtrl->i4PendingFwdFrameCount); -+ -+ return u4Num; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is to report current ACPI state -+* -+* @param prAdapter Pointer of Adapter Data Structure -+* -+* @return ACPI_STATE_D0 Normal Operation Mode -+* ACPI_STATE_D3 Suspend Mode -+*/ -+/*----------------------------------------------------------------------------*/ -+ENUM_ACPI_STATE_T wlanGetAcpiState(IN P_ADAPTER_T prAdapter) -+{ -+ ASSERT(prAdapter); -+ -+ return prAdapter->rAcpiState; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is to update current ACPI state only -+* -+* @param prAdapter Pointer of Adapter Data Structure -+* @param ePowerState ACPI_STATE_D0 Normal Operation Mode -+* ACPI_STATE_D3 Suspend Mode -+* -+* @return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID wlanSetAcpiState(IN P_ADAPTER_T prAdapter, IN ENUM_ACPI_STATE_T ePowerState) -+{ -+ ASSERT(prAdapter); -+ ASSERT(ePowerState <= ACPI_STATE_D3); -+ -+ prAdapter->rAcpiState = ePowerState; -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is to query ECO version from HIFSYS CR -+* -+* @param prAdapter Pointer of Adapter Data Structure -+* -+* @return zero Unable to retrieve ECO version information -+* non-zero ECO version (1-based) -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT_8 wlanGetEcoVersion(IN P_ADAPTER_T prAdapter) -+{ -+ ASSERT(prAdapter); -+ -+ if (nicVerifyChipID(prAdapter) == TRUE) -+ return prAdapter->ucRevID + 1; -+ else -+ return 0; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is to setting the default Tx Power configuration -+* -+* @param prAdapter Pointer of Adapter Data Structure -+* -+* @return zero Unable to retrieve ECO version information -+* non-zero ECO version (1-based) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID wlanDefTxPowerCfg(IN P_ADAPTER_T prAdapter) -+{ -+ UINT_8 i; -+ P_GLUE_INFO_T prGlueInfo = prAdapter->prGlueInfo; -+ P_SET_TXPWR_CTRL_T prTxpwr; -+ -+ ASSERT(prGlueInfo); -+ -+ prTxpwr = &prGlueInfo->rTxPwr; -+ -+ prTxpwr->c2GLegacyStaPwrOffset = 0; -+ prTxpwr->c2GHotspotPwrOffset = 0; -+ prTxpwr->c2GP2pPwrOffset = 0; -+ prTxpwr->c2GBowPwrOffset = 0; -+ prTxpwr->c5GLegacyStaPwrOffset = 0; -+ prTxpwr->c5GHotspotPwrOffset = 0; -+ prTxpwr->c5GP2pPwrOffset = 0; -+ prTxpwr->c5GBowPwrOffset = 0; -+ prTxpwr->ucConcurrencePolicy = 0; -+ for (i = 0; i < 3; i++) -+ prTxpwr->acReserved1[i] = 0; -+ -+ for (i = 0; i < 14; i++) -+ prTxpwr->acTxPwrLimit2G[i] = 63; -+ -+ for (i = 0; i < 4; i++) -+ prTxpwr->acTxPwrLimit5G[i] = 63; -+ -+ for (i = 0; i < 2; i++) -+ prTxpwr->acReserved2[i] = 0; -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is to -+* set preferred band configuration corresponding to network type -+* -+* @param prAdapter Pointer of Adapter Data Structure -+* @param eBand Given band -+* @param eNetTypeIndex Given Network Type -+* -+* @return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+wlanSetPreferBandByNetwork(IN P_ADAPTER_T prAdapter, IN ENUM_BAND_T eBand, IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex) -+{ -+ ASSERT(prAdapter); -+ ASSERT(eBand <= BAND_NUM); -+ ASSERT(eNetTypeIndex <= NETWORK_TYPE_INDEX_NUM); -+ -+ /* 1. set prefer band according to network type */ -+ prAdapter->aePreferBand[eNetTypeIndex] = eBand; -+ -+ /* 2. remove buffered BSS descriptors correspondingly */ -+ if (eBand == BAND_2G4) -+ scanRemoveBssDescByBandAndNetwork(prAdapter, BAND_5G, eNetTypeIndex); -+ else if (eBand == BAND_5G) -+ scanRemoveBssDescByBandAndNetwork(prAdapter, BAND_2G4, eNetTypeIndex); -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is to -+* get channel information corresponding to specified network type -+* -+* @param prAdapter Pointer of Adapter Data Structure -+* @param eNetTypeIndex Given Network Type -+* -+* @return channel number -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT_8 wlanGetChannelNumberByNetwork(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex) -+{ -+ P_BSS_INFO_T prBssInfo; -+ -+ ASSERT(prAdapter); -+ ASSERT(eNetTypeIndex <= NETWORK_TYPE_INDEX_NUM); -+ -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[eNetTypeIndex]); -+ -+ return prBssInfo->ucPrimaryChannel; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is to -+* get BSS descriptor information corresponding to specified network type -+* -+* @param prAdapter Pointer of Adapter Data Structure -+* @param eNetTypeIndex Given Network Type -+* -+* @return pointer to BSS_DESC_T -+*/ -+/*----------------------------------------------------------------------------*/ -+P_BSS_DESC_T wlanGetTargetBssDescByNetwork(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex) -+{ -+ ASSERT(prAdapter); -+ ASSERT(eNetTypeIndex <= NETWORK_TYPE_INDEX_NUM); -+ -+ switch (eNetTypeIndex) { -+ case NETWORK_TYPE_AIS_INDEX: -+ return prAdapter->rWifiVar.rAisFsmInfo.prTargetBssDesc; -+ -+ case NETWORK_TYPE_P2P_INDEX: -+ return NULL; -+ -+ case NETWORK_TYPE_BOW_INDEX: -+ return prAdapter->rWifiVar.rBowFsmInfo.prTargetBssDesc; -+ -+ default: -+ return NULL; -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is to -+* check unconfigured system properties and generate related message on -+* scan list to notify users -+* -+* @param prAdapter Pointer of Adapter Data Structure -+* -+* @return WLAN_STATUS_SUCCESS -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS wlanCheckSystemConfiguration(IN P_ADAPTER_T prAdapter) -+{ -+#if (CFG_NVRAM_EXISTENCE_CHECK == 1) || (CFG_SW_NVRAM_VERSION_CHECK == 1) -+ const UINT_8 aucZeroMacAddr[] = NULL_MAC_ADDR; -+ const UINT_8 aucBCAddr[] = BC_MAC_ADDR; -+ BOOLEAN fgIsConfExist = TRUE; -+ BOOLEAN fgGenErrMsg = FALSE; -+ P_REG_INFO_T prRegInfo = NULL; -+ P_WLAN_BEACON_FRAME_T prBeacon = NULL; -+ P_IE_SSID_T prSsid = NULL; -+ UINT_32 u4ErrCode = 0; -+ UINT_8 aucErrMsg[32]; -+ PARAM_SSID_T rSsid; -+ PARAM_802_11_CONFIG_T rConfiguration; -+ PARAM_RATES_EX rSupportedRates; -+#endif -+ -+ DEBUGFUNC("wlanCheckSystemConfiguration"); -+ -+ ASSERT(prAdapter); -+ -+#if (CFG_NVRAM_EXISTENCE_CHECK == 1) -+ if (kalIsConfigurationExist(prAdapter->prGlueInfo) == FALSE) { -+ fgIsConfExist = FALSE; -+ fgGenErrMsg = TRUE; -+ } -+#endif -+ -+#if (CFG_SW_NVRAM_VERSION_CHECK == 1) -+ prRegInfo = kalGetConfiguration(prAdapter->prGlueInfo); -+ -+ if (fgIsConfExist == TRUE && (CFG_DRV_OWN_VERSION < prAdapter->rVerInfo.u2Part1CfgPeerVersion -+ || CFG_DRV_OWN_VERSION < prAdapter->rVerInfo.u2Part2CfgPeerVersion -+ || prAdapter->rVerInfo.u2Part1CfgOwnVersion <= CFG_DRV_PEER_VERSION -+ || prAdapter->rVerInfo.u2Part2CfgOwnVersion <= CFG_DRV_PEER_VERSION /* NVRAM */ -+ || CFG_DRV_OWN_VERSION < prAdapter->rVerInfo.u2FwPeerVersion -+ || prAdapter->rVerInfo.u2FwOwnVersion <= CFG_DRV_PEER_VERSION -+#if CFG_SUPPORT_PWR_LIMIT_COUNTRY -+ || prAdapter->fgIsPowerLimitTableValid == FALSE -+#endif -+ || (prAdapter->fgIsEmbbededMacAddrValid == FALSE && -+ (IS_BMCAST_MAC_ADDR(prRegInfo->aucMacAddr) -+ || EQUAL_MAC_ADDR(aucZeroMacAddr, prRegInfo->aucMacAddr))) -+ || prRegInfo->ucTxPwrValid == 0)) -+ fgGenErrMsg = TRUE; -+#endif -+ -+ if (fgGenErrMsg == TRUE) { -+ prBeacon = cnmMemAlloc(prAdapter, RAM_TYPE_BUF, sizeof(WLAN_BEACON_FRAME_T) + sizeof(IE_SSID_T)); -+ if (!prBeacon) { -+ ASSERT(FALSE); -+ return WLAN_STATUS_FAILURE; -+ } -+ -+ /* initialization */ -+ kalMemZero(prBeacon, sizeof(WLAN_BEACON_FRAME_T) + sizeof(IE_SSID_T)); -+ -+ /* prBeacon initialization */ -+ prBeacon->u2FrameCtrl = MAC_FRAME_BEACON; -+ COPY_MAC_ADDR(prBeacon->aucDestAddr, aucBCAddr); -+ COPY_MAC_ADDR(prBeacon->aucSrcAddr, aucZeroMacAddr); -+ COPY_MAC_ADDR(prBeacon->aucBSSID, aucZeroMacAddr); -+ prBeacon->u2BeaconInterval = 100; -+ prBeacon->u2CapInfo = CAP_INFO_ESS; -+ -+ /* prSSID initialization */ -+ prSsid = (P_IE_SSID_T) (&prBeacon->aucInfoElem[0]); -+ prSsid->ucId = ELEM_ID_SSID; -+ -+ /* rConfiguration initialization */ -+ rConfiguration.u4Length = sizeof(PARAM_802_11_CONFIG_T); -+ rConfiguration.u4BeaconPeriod = 100; -+ rConfiguration.u4ATIMWindow = 1; -+ rConfiguration.u4DSConfig = 2412; -+ rConfiguration.rFHConfig.u4Length = sizeof(PARAM_802_11_CONFIG_FH_T); -+ -+ /* rSupportedRates initialization */ -+ kalMemZero(rSupportedRates, sizeof(PARAM_RATES_EX)); -+ } -+#if (CFG_NVRAM_EXISTENCE_CHECK == 1) -+#define NVRAM_ERR_MSG "NVRAM WARNING: Err = 0x01" -+ if ((kalIsConfigurationExist(prAdapter->prGlueInfo) == FALSE) && (prBeacon) && (prSsid)) { -+ COPY_SSID(prSsid->aucSSID, prSsid->ucLength, NVRAM_ERR_MSG, strlen(NVRAM_ERR_MSG)); -+ -+ kalIndicateBssInfo(prAdapter->prGlueInfo, -+ (PUINT_8) prBeacon, -+ OFFSET_OF(WLAN_BEACON_FRAME_T, aucInfoElem) + OFFSET_OF(IE_SSID_T, -+ aucSSID) + prSsid->ucLength, -+ 1, 0); -+ COPY_SSID(rSsid.aucSsid, rSsid.u4SsidLen, NVRAM_ERR_MSG, strlen(NVRAM_ERR_MSG)); -+ nicAddScanResult(prAdapter, -+ prBeacon->aucBSSID, -+ &rSsid, -+ 0, -+ 0, -+ PARAM_NETWORK_TYPE_FH, -+ &rConfiguration, -+ NET_TYPE_INFRA, -+ rSupportedRates, -+ OFFSET_OF(WLAN_BEACON_FRAME_T, aucInfoElem) + OFFSET_OF(IE_SSID_T, -+ aucSSID) + prSsid->ucLength - -+ WLAN_MAC_MGMT_HEADER_LEN, (PUINT_8) ((ULONG) (prBeacon) + WLAN_MAC_MGMT_HEADER_LEN)); -+ } -+#endif -+ -+#if (CFG_SW_NVRAM_VERSION_CHECK == 1) -+#define VER_ERR_MSG "NVRAM WARNING: Err = 0x%02X" -+ if ((fgIsConfExist == TRUE) && (prBeacon) && (prSsid)) { -+ if ((CFG_DRV_OWN_VERSION < prAdapter->rVerInfo.u2Part1CfgPeerVersion -+ || CFG_DRV_OWN_VERSION < prAdapter->rVerInfo.u2Part2CfgPeerVersion -+ || prAdapter->rVerInfo.u2Part1CfgOwnVersion <= CFG_DRV_PEER_VERSION -+ || prAdapter->rVerInfo.u2Part2CfgOwnVersion <= CFG_DRV_PEER_VERSION /* NVRAM */ -+ || CFG_DRV_OWN_VERSION < prAdapter->rVerInfo.u2FwPeerVersion -+ || prAdapter->rVerInfo.u2FwOwnVersion <= CFG_DRV_PEER_VERSION)) -+ u4ErrCode |= NVRAM_ERROR_VERSION_MISMATCH; -+ -+ if (prRegInfo->ucTxPwrValid == 0) -+ u4ErrCode |= NVRAM_ERROR_INVALID_TXPWR; -+ -+ if (prAdapter->fgIsEmbbededMacAddrValid == FALSE && (IS_BMCAST_MAC_ADDR(prRegInfo->aucMacAddr) -+ || EQUAL_MAC_ADDR(aucZeroMacAddr, -+ prRegInfo->aucMacAddr))) -+ u4ErrCode |= NVRAM_ERROR_INVALID_MAC_ADDR; -+ -+#if CFG_SUPPORT_PWR_LIMIT_COUNTRY -+ if (prAdapter->fgIsPowerLimitTableValid == FALSE) -+ u4ErrCode |= NVRAM_POWER_LIMIT_TABLE_INVALID; -+#endif -+ if (u4ErrCode != 0) { -+ sprintf(aucErrMsg, VER_ERR_MSG, (unsigned int)u4ErrCode); -+ COPY_SSID(prSsid->aucSSID, prSsid->ucLength, aucErrMsg, strlen(aucErrMsg)); -+ -+ kalIndicateBssInfo(prAdapter->prGlueInfo, -+ (PUINT_8) prBeacon, -+ OFFSET_OF(WLAN_BEACON_FRAME_T, aucInfoElem) + OFFSET_OF(IE_SSID_T, -+ aucSSID) + -+ prSsid->ucLength, 1, 0); -+ -+ COPY_SSID(rSsid.aucSsid, rSsid.u4SsidLen, NVRAM_ERR_MSG, strlen(NVRAM_ERR_MSG)); -+ nicAddScanResult(prAdapter, -+ prBeacon->aucBSSID, -+ &rSsid, -+ 0, -+ 0, -+ PARAM_NETWORK_TYPE_FH, -+ &rConfiguration, -+ NET_TYPE_INFRA, -+ rSupportedRates, -+ OFFSET_OF(WLAN_BEACON_FRAME_T, aucInfoElem) + OFFSET_OF(IE_SSID_T, -+ aucSSID) + -+ prSsid->ucLength - WLAN_MAC_MGMT_HEADER_LEN, -+ (PUINT_8) ((ULONG) (prBeacon) + WLAN_MAC_MGMT_HEADER_LEN)); -+ } -+ } -+#endif -+ -+ if (fgGenErrMsg == TRUE) -+ cnmMemFree(prAdapter, prBeacon); -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+WLAN_STATUS -+wlanoidQueryStaStatistics(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ WLAN_STATUS rResult = WLAN_STATUS_FAILURE; -+ P_STA_RECORD_T prStaRec, prTempStaRec; -+ P_PARAM_GET_STA_STATISTICS prQueryStaStatistics; -+ UINT_8 ucStaRecIdx; -+ P_QUE_MGT_T prQM = &prAdapter->rQM; -+ CMD_GET_STA_STATISTICS_T rQueryCmdStaStatistics; -+ UINT_8 ucIdx; -+ P_GLUE_INFO_T prGlueInfo = prAdapter->prGlueInfo; -+ -+ do { -+ ASSERT(pvQueryBuffer); -+ -+ /* 4 1. Sanity test */ -+ if ((prAdapter == NULL) || (pu4QueryInfoLen == NULL)) -+ break; -+ -+ if ((u4QueryBufferLen) && (pvQueryBuffer == NULL)) -+ break; -+ -+ if (u4QueryBufferLen < sizeof(PARAM_GET_STA_STA_STATISTICS)) { -+ *pu4QueryInfoLen = sizeof(PARAM_GET_STA_STA_STATISTICS); -+ rResult = WLAN_STATUS_BUFFER_TOO_SHORT; -+ break; -+ } -+ -+ prQueryStaStatistics = (P_PARAM_GET_STA_STATISTICS) pvQueryBuffer; -+ *pu4QueryInfoLen = sizeof(PARAM_GET_STA_STA_STATISTICS); -+ -+ /* 4 5. Get driver global QM counter */ -+ for (ucIdx = TC0_INDEX; ucIdx <= TC3_INDEX; ucIdx++) { -+ prQueryStaStatistics->au4TcAverageQueLen[ucIdx] = prQM->au4AverageQueLen[ucIdx]; -+ prQueryStaStatistics->au4TcCurrentQueLen[ucIdx] = prQM->au4CurrentTcResource[ucIdx]; -+ } -+ -+ /* 4 2. Get StaRec by MAC address */ -+ prStaRec = NULL; -+ -+ for (ucStaRecIdx = 0; ucStaRecIdx < CFG_NUM_OF_STA_RECORD; ucStaRecIdx++) { -+ prTempStaRec = &(prAdapter->arStaRec[ucStaRecIdx]); -+ if (prTempStaRec->fgIsValid && prTempStaRec->fgIsInUse) { -+ if (EQUAL_MAC_ADDR(prTempStaRec->aucMacAddr, prQueryStaStatistics->aucMacAddr)) { -+ prStaRec = prTempStaRec; -+ break; -+ } -+ } -+ } -+ -+ if (!prStaRec) { -+ rResult = WLAN_STATUS_INVALID_DATA; -+ break; -+ } -+ -+ prQueryStaStatistics->u4Flag |= BIT(0); -+ -+#if CFG_ENABLE_PER_STA_STATISTICS -+ /* 4 3. Get driver statistics */ -+ DBGLOG(TX, INFO, "skbToDriver %lld, skbFreed: %lld\n", -+ prAdapter->prGlueInfo->u8SkbToDriver, -+ prAdapter->prGlueInfo->u8SkbFreed); -+ prAdapter->prGlueInfo->u8SkbFreed = 0; -+ prAdapter->prGlueInfo->u8SkbToDriver = 0; -+ -+ prQueryStaStatistics->u4TxTotalCount = prStaRec->u4TotalTxPktsNumber; -+ prQueryStaStatistics->u4TxExceedThresholdCount = prStaRec->u4ThresholdCounter; -+ prQueryStaStatistics->u4TxMaxTime = prStaRec->u4MaxTxPktsTime; -+ prQueryStaStatistics->u4TxMaxHifTime = prStaRec->u4MaxTxPktsHifTime; -+ if (prStaRec->u4TotalTxPktsNumber) { -+ prQueryStaStatistics->u4TxAverageProcessTime = -+ (prStaRec->u4TotalTxPktsTime / prStaRec->u4TotalTxPktsNumber); -+ prQueryStaStatistics->u4TxAverageHifTime = -+ (prStaRec->u4TotalTxPktsHifTime / prStaRec->u4TotalTxPktsNumber); -+ } else -+ prQueryStaStatistics->u4TxAverageProcessTime = 0; -+ -+ for (ucIdx = TC0_INDEX; ucIdx <= TC3_INDEX; ucIdx++) { -+ prQueryStaStatistics->au4TcResourceEmptyCount[ucIdx] = -+ prQM->au4QmTcResourceEmptyCounter[prStaRec->ucNetTypeIndex][ucIdx]; -+ /* Reset */ -+ prQM->au4QmTcResourceEmptyCounter[prStaRec->ucNetTypeIndex][ucIdx] = 0; -+ prQueryStaStatistics->au4TcResourceBackCount[ucIdx] = -+ prQM->au4QmTcResourceBackCounter[ucIdx]; -+ prQM->au4QmTcResourceBackCounter[ucIdx] = 0; -+ -+ prQueryStaStatistics->au4DequeueNoTcResource[ucIdx] = -+ prQM->au4DequeueNoTcResourceCounter[ucIdx]; -+ prQM->au4DequeueNoTcResourceCounter[ucIdx] = 0; -+ prQueryStaStatistics->au4TcResourceUsedCount[ucIdx] = -+ prQM->au4ResourceUsedCounter[ucIdx]; -+ prQM->au4ResourceUsedCounter[ucIdx] = 0; -+ prQueryStaStatistics->au4TcResourceWantedCount[ucIdx] = -+ prQM->au4ResourceWantedCounter[ucIdx]; -+ prQM->au4ResourceWantedCounter[ucIdx] = 0; -+ } -+ -+ prQueryStaStatistics->u4EnqueueCounter = prQM->u4EnqeueuCounter; -+ prQueryStaStatistics->u4DequeueCounter = prQM->u4DequeueCounter; -+ prQueryStaStatistics->u4EnqueueStaCounter = prStaRec->u4EnqeueuCounter; -+ prQueryStaStatistics->u4DequeueStaCounter = prStaRec->u4DeqeueuCounter; -+ -+ prQueryStaStatistics->IsrCnt = prGlueInfo->IsrCnt - prGlueInfo->IsrPreCnt; -+ prQueryStaStatistics->IsrPassCnt = prGlueInfo->IsrPassCnt - prGlueInfo->IsrPrePassCnt; -+ prQueryStaStatistics->TaskIsrCnt = prGlueInfo->TaskIsrCnt - prGlueInfo->TaskPreIsrCnt; -+ -+ prQueryStaStatistics->IsrAbnormalCnt = prGlueInfo->IsrAbnormalCnt; -+ prQueryStaStatistics->IsrSoftWareCnt = prGlueInfo->IsrSoftWareCnt; -+ prQueryStaStatistics->IsrRxCnt = prGlueInfo->IsrRxCnt; -+ prQueryStaStatistics->IsrTxCnt = prGlueInfo->IsrTxCnt; -+ -+ /* 4 4.1 Reset statistics */ -+ prStaRec->u4ThresholdCounter = 0; -+ prStaRec->u4TotalTxPktsNumber = 0; -+ prStaRec->u4TotalTxPktsTime = 0; -+ prStaRec->u4MaxTxPktsTime = 0; -+ prStaRec->u4MaxTxPktsHifTime = 0; -+ -+ prStaRec->u4EnqeueuCounter = 0; -+ prStaRec->u4DeqeueuCounter = 0; -+ -+ prQM->u4EnqeueuCounter = 0; -+ prQM->u4DequeueCounter = 0; -+ -+ prGlueInfo->IsrPreCnt = prGlueInfo->IsrCnt; -+ prGlueInfo->IsrPrePassCnt = prGlueInfo->IsrPassCnt; -+ prGlueInfo->TaskPreIsrCnt = prGlueInfo->TaskIsrCnt; -+ prGlueInfo->IsrAbnormalCnt = 0; -+ prGlueInfo->IsrSoftWareCnt = 0; -+ prGlueInfo->IsrRxCnt = 0; -+ prGlueInfo->IsrTxCnt = 0; -+#endif -+ -+ for (ucIdx = TC0_INDEX; ucIdx <= TC3_INDEX; ucIdx++) -+ prQueryStaStatistics->au4TcQueLen[ucIdx] = prStaRec->arTxQueue[ucIdx].u4NumElem; -+ -+ rResult = WLAN_STATUS_SUCCESS; -+ -+ /* 4 6. Ensure FW supports get station link status */ -+ if (prAdapter->u4FwCompileFlag0 & COMPILE_FLAG0_GET_STA_LINK_STATUS) { -+ -+ rQueryCmdStaStatistics.ucIndex = prStaRec->ucIndex; -+ COPY_MAC_ADDR(rQueryCmdStaStatistics.aucMacAddr, prQueryStaStatistics->aucMacAddr); -+ rQueryCmdStaStatistics.ucReadClear = TRUE; -+ -+ rResult = wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_GET_STA_STATISTICS, -+ FALSE, -+ TRUE, -+ TRUE, -+ nicCmdEventQueryStaStatistics, -+ nicOidCmdTimeoutCommon, -+ sizeof(CMD_GET_STA_STATISTICS_T), -+ (PUINT_8)&rQueryCmdStaStatistics, -+ pvQueryBuffer, u4QueryBufferLen); -+ -+ prQueryStaStatistics->u4Flag |= BIT(1); -+ } else { -+ rResult = WLAN_STATUS_NOT_SUPPORTED; -+ } -+ -+ } while (FALSE); -+ -+ return rResult; -+} /* wlanoidQueryP2pVersion */ -+ -+#if CFG_AUTO_CHANNEL_SEL_SUPPORT -+ -+/* 4 Auto Channel Selection */ -+WLAN_STATUS -+wlanoidQueryACSChannelList(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ WLAN_STATUS rResult = WLAN_STATUS_FAILURE; -+ /* P_PARAM_GET_CHN_LOAD prQueryChnLoad; */ -+ P_PARAM_GET_LTE_MODE prLteMode; -+ CMD_GET_LTE_SAFE_CHN_T rQuery_LTE_SAFE_CHN; -+ -+ DBGLOG(P2P, INFO, "[Auto Channel]wlanoidQueryACSChannelList\n"); -+ do { -+ ASSERT(pvQueryBuffer); -+ -+ /* 4 1. Sanity test */ -+ if ((prAdapter == NULL) || (pu4QueryInfoLen == NULL)) -+ break; -+ -+ if ((u4QueryBufferLen) && (pvQueryBuffer == NULL)) -+ break; -+ -+ prLteMode = (P_PARAM_GET_LTE_MODE) pvQueryBuffer; -+ -+ /* 4 3. Ensure FW supports get station link status */ -+#if 0 -+ if (prAdapter->u4FwCompileFlag0 & COMPILE_FLAG0_GET_STA_LINK_STATUS) { -+ CMD_ACCESS_REG rCmdAccessReg; -+ -+ rCmdAccessReg.u4Address = 0xFFFFFFFF; -+ rCmdAccessReg.u4Data = ELEM_RM_TYPE_ACS_CHN; -+ -+ rResult = wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_ACCESS_REG, -+ TRUE, -+ TRUE, -+ TRUE, -+ /* The handler to receive firmware notification */ -+ nicCmdEventQueryChannelLoad, -+ nicOidCmdTimeoutCommon, -+ sizeof(CMD_ACCESS_REG), -+ (PUINT_8)&rCmdAccessReg, pvQueryBuffer, u4QueryBufferLen); -+ -+ prQueryChnLoad->u4Flag |= BIT(1); -+ } else { -+ rResult = WLAN_STATUS_NOT_SUPPORTED; -+ } -+#endif -+ /* 4 4.Avoid LTE Channels */ -+ prLteMode->u4Flags &= BIT(0); -+ /*if(prAdapter->u4FwCompileFlag0 & COMPILE_FLAG0_GET_STA_LINK_STATUS) */ { -+ -+ rResult = wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_GET_LTE_CHN, -+ FALSE, -+ TRUE, -+ /* Query ID */ -+ TRUE, -+ /* The handler to receive firmware notification */ -+ nicCmdEventQueryLTESafeChn, -+ nicOidCmdTimeoutCommon, -+ sizeof(CMD_GET_LTE_SAFE_CHN_T), -+ (PUINT_8)&rQuery_LTE_SAFE_CHN, -+ pvQueryBuffer, u4QueryBufferLen); -+ -+ DBGLOG(P2P, INFO, "[Auto Channel] Get LTE Channels\n"); -+ prLteMode->u4Flags |= BIT(1); -+ } -+ -+ /* 4 5. Calc the value */ -+ -+ DBGLOG(P2P, INFO, "[Auto Channel] Candidated Channels\n"); -+ } while (FALSE); -+ -+ return rResult; -+} /* wlanoidQueryP2pVersion */ -+#endif -+#if CFG_SUPPORT_CFG_FILE -+ -+P_WLAN_CFG_ENTRY_T wlanCfgGetEntry(IN P_ADAPTER_T prAdapter, const PCHAR pucKey) -+{ -+ -+ P_WLAN_CFG_ENTRY_T prWlanCfgEntry; -+ P_WLAN_CFG_T prWlanCfg; -+ UINT_32 i; -+ -+ prWlanCfg = prAdapter->prWlanCfg; -+ -+ ASSERT(prWlanCfg); -+ ASSERT(pucKey); -+ -+ prWlanCfgEntry = NULL; -+ -+ for (i = 0; i < WLAN_CFG_ENTRY_NUM_MAX; i++) { -+ prWlanCfgEntry = &prWlanCfg->arWlanCfgBuf[i]; -+ if (prWlanCfgEntry->aucKey[0] != '\0') { -+ DBGLOG(INIT, LOUD, "compare key %s saved key %s\n", pucKey, prWlanCfgEntry->aucKey); -+ if (kalStrniCmp(pucKey, prWlanCfgEntry->aucKey, WLAN_CFG_KEY_LEN_MAX - 1) == 0) -+ return prWlanCfgEntry; -+ } -+ } -+ -+ DBGLOG(INIT, LOUD, "wifi config there is no entry \'%s\'\n", pucKey); -+ return NULL; -+ -+} -+ -+WLAN_STATUS wlanCfgGet(IN P_ADAPTER_T prAdapter, const PCHAR pucKey, PCHAR pucValue, PCHAR pucValueDef, UINT_32 u4Flags) -+{ -+ -+ P_WLAN_CFG_ENTRY_T prWlanCfgEntry; -+ P_WLAN_CFG_T prWlanCfg; -+ -+ prWlanCfg = prAdapter->prWlanCfg; -+ -+ ASSERT(prWlanCfg); -+ ASSERT(pucValue); -+ -+ /* Find the exist */ -+ prWlanCfgEntry = wlanCfgGetEntry(prAdapter, pucKey); -+ -+ if (prWlanCfgEntry) { -+ kalStrnCpy(pucValue, prWlanCfgEntry->aucValue, WLAN_CFG_VALUE_LEN_MAX - 1); -+ return WLAN_STATUS_SUCCESS; -+ } -+ if (pucValueDef) -+ kalStrnCpy(pucValue, pucValueDef, WLAN_CFG_VALUE_LEN_MAX - 1); -+ return WLAN_STATUS_FAILURE; -+ -+} -+ -+UINT_32 wlanCfgGetUint32(IN P_ADAPTER_T prAdapter, const PCHAR pucKey, UINT_32 u4ValueDef) -+{ -+ P_WLAN_CFG_ENTRY_T prWlanCfgEntry; -+ P_WLAN_CFG_T prWlanCfg; -+ UINT_32 u4Value; -+ INT_32 u4Ret; -+ -+ prWlanCfg = prAdapter->prWlanCfg; -+ -+ ASSERT(prWlanCfg); -+ -+ u4Value = u4ValueDef; -+ /* Find the exist */ -+ prWlanCfgEntry = wlanCfgGetEntry(prAdapter, pucKey); -+ -+ if (prWlanCfgEntry) { -+ u4Ret = kalkStrtou32(prWlanCfgEntry->aucValue, 0, &u4Value); -+ if (u4Ret) -+ DBGLOG(INIT, ERROR, "parse prWlanCfgEntry->aucValue u4Ret=%u\n", u4Ret); -+ /* u4Value = kalStrtoul(prWlanCfgEntry->aucValue, NULL, 0); */ -+ } -+ -+ return u4Value; -+} -+ -+INT_32 wlanCfgGetInt32(IN P_ADAPTER_T prAdapter, const PCHAR pucKey, INT_32 i4ValueDef) -+{ -+ P_WLAN_CFG_ENTRY_T prWlanCfgEntry; -+ P_WLAN_CFG_T prWlanCfg; -+ INT_32 i4Value; -+ INT_32 i4Ret; -+ -+ prWlanCfg = prAdapter->prWlanCfg; -+ -+ ASSERT(prWlanCfg); -+ -+ i4Value = i4ValueDef; -+ /* Find the exist */ -+ prWlanCfgEntry = wlanCfgGetEntry(prAdapter, pucKey); -+ -+ if (prWlanCfgEntry) { -+ i4Ret = kalkStrtos32(prWlanCfgEntry->aucValue, 0, &i4Value); -+ /* i4Ret = kalStrtol(prWlanCfgEntry->aucValue, NULL, 0); */ -+ if (i4Ret) -+ DBGLOG(INIT, ERROR, "parse prWlanCfgEntry->aucValue i4Ret=%u\n\r", i4Ret); -+ } -+ -+ return i4Value; -+} -+ -+WLAN_STATUS wlanCfgSet(IN P_ADAPTER_T prAdapter, const PCHAR pucKey, PCHAR pucValue, UINT_32 u4Flags) -+{ -+ -+ P_WLAN_CFG_ENTRY_T prWlanCfgEntry; -+ P_WLAN_CFG_T prWlanCfg; -+ UINT_32 u4EntryIndex; -+ UINT_32 i; -+ UINT_8 ucExist; -+ -+ prWlanCfg = prAdapter->prWlanCfg; -+ ASSERT(prWlanCfg); -+ ASSERT(pucKey); -+ -+ /* Find the exist */ -+ ucExist = 0; -+ prWlanCfgEntry = wlanCfgGetEntry(prAdapter, pucKey); -+ -+ if (!prWlanCfgEntry) { -+ /* Find the empty */ -+ for (i = 0; i < WLAN_CFG_ENTRY_NUM_MAX; i++) { -+ prWlanCfgEntry = &prWlanCfg->arWlanCfgBuf[i]; -+ if (prWlanCfgEntry->aucKey[0] == '\0') -+ break; -+ } -+ -+ u4EntryIndex = i; -+ if (u4EntryIndex < WLAN_CFG_ENTRY_NUM_MAX) { -+ prWlanCfgEntry = &prWlanCfg->arWlanCfgBuf[u4EntryIndex]; -+ kalMemZero(prWlanCfgEntry, sizeof(WLAN_CFG_ENTRY_T)); -+ } else { -+ prWlanCfgEntry = NULL; -+ DBGLOG(INIT, ERROR, "wifi config there is no empty entry\n"); -+ } -+ } /* !prWlanCfgEntry */ -+ else -+ ucExist = 1; -+ -+ if (prWlanCfgEntry) { -+ if (ucExist == 0) { -+ kalStrnCpy(prWlanCfgEntry->aucKey, pucKey, WLAN_CFG_KEY_LEN_MAX - 1); -+ prWlanCfgEntry->aucKey[WLAN_CFG_KEY_LEN_MAX - 1] = '\0'; -+ } -+ -+ if (pucValue && pucValue[0] != '\0') { -+ kalStrnCpy(prWlanCfgEntry->aucValue, pucValue, WLAN_CFG_VALUE_LEN_MAX - 1); -+ prWlanCfgEntry->aucValue[WLAN_CFG_VALUE_LEN_MAX - 1] = '\0'; -+ -+ if (ucExist) { -+ if (prWlanCfgEntry->pfSetCb) -+ prWlanCfgEntry->pfSetCb(prAdapter, -+ prWlanCfgEntry->aucKey, -+ prWlanCfgEntry->aucValue, prWlanCfgEntry->pPrivate, 0); -+ } -+ } else { -+ /* Call the pfSetCb if value is empty ? */ -+ /* remove the entry if value is empty */ -+ kalMemZero(prWlanCfgEntry, sizeof(WLAN_CFG_ENTRY_T)); -+ } -+ -+ } -+ /* prWlanCfgEntry */ -+ if (prWlanCfgEntry) { -+ DBGLOG(INIT, LOUD, "Set wifi config exist %u \'%s\' \'%s\'\n", -+ ucExist, prWlanCfgEntry->aucKey, prWlanCfgEntry->aucValue); -+ return WLAN_STATUS_SUCCESS; -+ } -+ if (pucKey) -+ DBGLOG(INIT, ERROR, "Set wifi config error key \'%s\'\n", pucKey); -+ if (pucValue) -+ DBGLOG(INIT, ERROR, "Set wifi config error value \'%s\'\n", pucValue); -+ return WLAN_STATUS_FAILURE; -+ -+} -+ -+WLAN_STATUS -+wlanCfgSetCb(IN P_ADAPTER_T prAdapter, const PCHAR pucKey, WLAN_CFG_SET_CB pfSetCb, void *pPrivate, UINT_32 u4Flags) -+{ -+ -+ P_WLAN_CFG_ENTRY_T prWlanCfgEntry; -+ P_WLAN_CFG_T prWlanCfg; -+ -+ prWlanCfg = prAdapter->prWlanCfg; -+ ASSERT(prWlanCfg); -+ -+ /* Find the exist */ -+ prWlanCfgEntry = wlanCfgGetEntry(prAdapter, pucKey); -+ -+ if (prWlanCfgEntry) { -+ prWlanCfgEntry->pfSetCb = pfSetCb; -+ prWlanCfgEntry->pPrivate = pPrivate; -+ } -+ -+ if (prWlanCfgEntry) -+ return WLAN_STATUS_SUCCESS; -+ else -+ return WLAN_STATUS_FAILURE; -+ -+} -+ -+WLAN_STATUS wlanCfgSetUint32(IN P_ADAPTER_T prAdapter, const PCHAR pucKey, UINT_32 u4Value) -+{ -+ -+ P_WLAN_CFG_T prWlanCfg; -+ UINT_8 aucBuf[WLAN_CFG_VALUE_LEN_MAX]; -+ -+ prWlanCfg = prAdapter->prWlanCfg; -+ -+ ASSERT(prWlanCfg); -+ -+ kalMemZero(aucBuf, sizeof(aucBuf)); -+ -+ kalSnprintf(aucBuf, WLAN_CFG_VALUE_LEN_MAX, "0x%x", (unsigned int)u4Value); -+ -+ return wlanCfgSet(prAdapter, pucKey, aucBuf, 0); -+} -+ -+enum { -+ STATE_EOF = 0, -+ STATE_TEXT = 1, -+ STATE_NEWLINE = 2 -+}; -+ -+struct WLAN_CFG_PARSE_STATE_S { -+ CHAR *ptr; -+ CHAR *text; -+ INT_32 nexttoken; -+ UINT_32 maxSize; -+}; -+ -+INT_32 wlanCfgFindNextToken(struct WLAN_CFG_PARSE_STATE_S *state) -+{ -+ CHAR *x = state->ptr; -+ CHAR *s; -+ -+ if (state->nexttoken) { -+ INT_32 t = state->nexttoken; -+ -+ state->nexttoken = 0; -+ return t; -+ } -+ -+ for (;;) { -+ switch (*x) { -+ case 0: -+ state->ptr = x; -+ return STATE_EOF; -+ case '\n': -+ x++; -+ state->ptr = x; -+ return STATE_NEWLINE; -+ case ' ': -+ case '\t': -+ case '\r': -+ x++; -+ continue; -+ case '#': -+ while (*x && (*x != '\n')) -+ x++; -+ if (*x == '\n') { -+ state->ptr = x + 1; -+ return STATE_NEWLINE; -+ } -+ state->ptr = x; -+ return STATE_EOF; -+ default: -+ goto text; -+ } -+ } -+ -+textdone: -+ state->ptr = x; -+ *s = 0; -+ return STATE_TEXT; -+text: -+ state->text = s = x; -+textresume: -+ for (;;) { -+ switch (*x) { -+ case 0: -+ goto textdone; -+ case ' ': -+ case '\t': -+ case '\r': -+ x++; -+ goto textdone; -+ case '\n': -+ state->nexttoken = STATE_NEWLINE; -+ x++; -+ goto textdone; -+ case '"': -+ x++; -+ for (;;) { -+ switch (*x) { -+ case 0: -+ /* unterminated quoted thing */ -+ state->ptr = x; -+ return STATE_EOF; -+ case '"': -+ x++; -+ goto textresume; -+ default: -+ *s++ = *x++; -+ } -+ } -+ break; -+ case '\\': -+ x++; -+ switch (*x) { -+ case 0: -+ goto textdone; -+ case 'n': -+ *s++ = '\n'; -+ break; -+ case 'r': -+ *s++ = '\r'; -+ break; -+ case 't': -+ *s++ = '\t'; -+ break; -+ case '\\': -+ *s++ = '\\'; -+ break; -+ case '\r': -+ /* \ -> line continuation */ -+ if (x[1] != '\n') { -+ x++; -+ continue; -+ } -+ case '\n': -+ /* \ -> line continuation */ -+ x++; -+ /* eat any extra whitespace */ -+ while ((*x == ' ') || (*x == '\t')) -+ x++; -+ continue; -+ default: -+ /* unknown escape -- just copy */ -+ *s++ = *x++; -+ } -+ continue; -+ default: -+ *s++ = *x++; -+ } -+ } -+ return STATE_EOF; -+} -+ -+WLAN_STATUS wlanCfgParseArgument(CHAR *cmdLine, INT_32 *argc, CHAR *argv[]) -+{ -+ struct WLAN_CFG_PARSE_STATE_S state; -+ CHAR **args; -+ INT_32 nargs; -+ -+ if (cmdLine == NULL || argc == NULL || argv == NULL) { -+ ASSERT(0); -+ return WLAN_STATUS_FAILURE; -+ } -+ args = argv; -+ nargs = 0; -+ state.ptr = cmdLine; -+ state.nexttoken = 0; -+ state.maxSize = 0; -+ -+ if (kalStrnLen(cmdLine, 512) >= 512) { -+ ASSERT(0); -+ return WLAN_STATUS_FAILURE; -+ } -+ -+ for (;;) { -+ switch (wlanCfgFindNextToken(&state)) { -+ case STATE_EOF: -+ goto exit; -+ case STATE_NEWLINE: -+ goto exit; -+ case STATE_TEXT: -+ if (nargs < WLAN_CFG_ARGV_MAX) -+ args[nargs++] = state.text; -+ break; -+ } -+ } -+ -+exit: -+ *argc = nargs; -+ return WLAN_STATUS_SUCCESS; -+} -+ -+WLAN_STATUS -+wlanCfgParseAddEntry(IN P_ADAPTER_T prAdapter, -+ PUINT_8 pucKeyHead, PUINT_8 pucKeyTail, PUINT_8 pucValueHead, PUINT_8 pucValueTail) -+{ -+ -+ UINT_8 aucKey[WLAN_CFG_KEY_LEN_MAX]; -+ UINT_8 aucValue[WLAN_CFG_VALUE_LEN_MAX]; -+ UINT_32 u4Len; -+ -+ kalMemZero(aucKey, sizeof(aucKey)); -+ kalMemZero(aucValue, sizeof(aucValue)); -+ -+ if ((pucKeyHead == NULL) -+ || (pucValueHead == NULL) -+ ) -+ return WLAN_STATUS_FAILURE; -+ -+ if (pucKeyTail) { -+ if (pucKeyHead > pucKeyTail) -+ return WLAN_STATUS_FAILURE; -+ u4Len = pucKeyTail - pucKeyHead + 1; -+ } else -+ u4Len = kalStrnLen(pucKeyHead, WLAN_CFG_KEY_LEN_MAX - 1); -+ -+ if (u4Len >= WLAN_CFG_KEY_LEN_MAX) -+ u4Len = WLAN_CFG_KEY_LEN_MAX - 1; -+ -+ if (u4Len < WLAN_CFG_VALUE_LEN_MAX) -+ kalStrnCpy(aucKey, pucKeyHead, u4Len); -+ else -+ DBGLOG(INIT, ERROR, "wifi entry parse error: Data len > %d\n", u4Len); -+ -+ if (pucValueTail) { -+ if (pucValueHead > pucValueTail) -+ return WLAN_STATUS_FAILURE; -+ u4Len = pucValueTail - pucValueHead + 1; -+ } else -+ u4Len = kalStrnLen(pucValueHead, WLAN_CFG_VALUE_LEN_MAX - 1); -+ -+ if (u4Len >= WLAN_CFG_VALUE_LEN_MAX) -+ u4Len = WLAN_CFG_VALUE_LEN_MAX - 1; -+ -+ if (u4Len < WLAN_CFG_VALUE_LEN_MAX) -+ kalStrnCpy(aucValue, pucValueHead, u4Len); -+ else -+ DBGLOG(INIT, ERROR, "wifi entry parse error: Data len > %d\n", u4Len); -+ -+ return wlanCfgSet(prAdapter, aucKey, aucValue, 0); -+} -+ -+enum { -+ WAIT_KEY_HEAD = 0, -+ WAIT_KEY_TAIL, -+ WAIT_VALUE_HEAD, -+ WAIT_VALUE_TAIL, -+ WAIT_COMMENT_TAIL -+}; -+ -+WLAN_STATUS wlanCfgParse(IN P_ADAPTER_T prAdapter, PUINT_8 pucConfigBuf, UINT_32 u4ConfigBufLen) -+{ -+ -+ struct WLAN_CFG_PARSE_STATE_S state; -+ PCHAR apcArgv[WLAN_CFG_ARGV_MAX]; -+ CHAR **args; -+ INT_32 nargs; -+ -+ if (pucConfigBuf == NULL) { -+ ASSERT(0); -+ return WLAN_STATUS_FAILURE; -+ } -+ if (kalStrnLen(pucConfigBuf, 4000) >= 4000) { -+ ASSERT(0); -+ return WLAN_STATUS_FAILURE; -+ } -+ if (u4ConfigBufLen == 0) -+ return WLAN_STATUS_FAILURE; -+ args = apcArgv; -+ nargs = 0; -+ state.ptr = pucConfigBuf; -+ state.nexttoken = 0; -+ state.maxSize = u4ConfigBufLen; -+ -+ for (;;) { -+ switch (wlanCfgFindNextToken(&state)) { -+ case STATE_EOF: -+ if (nargs > 1) -+ wlanCfgParseAddEntry(prAdapter, args[0], NULL, args[1], NULL); -+ goto exit; -+ case STATE_NEWLINE: -+ if (nargs > 1) -+ wlanCfgParseAddEntry(prAdapter, args[0], NULL, args[1], NULL); -+ nargs = 0; -+ break; -+ case STATE_TEXT: -+ if (nargs < WLAN_CFG_ARGV_MAX) -+ args[nargs++] = state.text; -+ break; -+ } -+ } -+ -+exit: -+ return WLAN_STATUS_SUCCESS; -+ -+#if 0 -+ /* Old version */ -+ UINT_32 i; -+ UINT_8 c; -+ PUINT_8 pbuf; -+ UINT_8 ucState; -+ PUINT_8 pucKeyTail = NULL; -+ PUINT_8 pucKeyHead = NULL; -+ PUINT_8 pucValueHead = NULL; -+ PUINT_8 pucValueTail = NULL; -+ -+ ucState = WAIT_KEY_HEAD; -+ pbuf = pucConfigBuf; -+ -+ for (i = 0; i < u4ConfigBufLen; i++) { -+ c = pbuf[i]; -+ if (c == '\r' || c == '\n') { -+ -+ if (ucState == WAIT_VALUE_TAIL) { -+ /* Entry found */ -+ if (pucValueHead) -+ wlanCfgParseAddEntry(prAdapter, pucKeyHead, pucKeyTail, -+ pucValueHead, pucValueTail); -+ } -+ ucState = WAIT_KEY_HEAD; -+ pucKeyTail = NULL; -+ pucKeyHead = NULL; -+ pucValueHead = NULL; -+ pucValueTail = NULL; -+ -+ } else if (c == '=') { -+ if (ucState == WAIT_KEY_TAIL) { -+ pucKeyTail = &pbuf[i - 1]; -+ ucState = WAIT_VALUE_HEAD; -+ } -+ } else if (c == ' ' || c == '\t') { -+ if (ucState == WAIT_KEY_HEAD) -+ ; -+ else if (ucState == WAIT_KEY_TAIL) { -+ pucKeyTail = &pbuf[i - 1]; -+ ucState = WAIT_VALUE_HEAD; -+ } -+ } else { -+ -+ if (c == '#') { -+ /* comments */ -+ if (ucState == WAIT_KEY_HEAD) -+ ucState = WAIT_COMMENT_TAIL; -+ else if (ucState == WAIT_VALUE_TAIL) -+ pucValueTail = &pbuf[i]; -+ -+ } else { -+ if (ucState == WAIT_KEY_HEAD) { -+ pucKeyHead = &pbuf[i]; -+ pucKeyTail = &pbuf[i]; -+ ucState = WAIT_KEY_TAIL; -+ } else if (ucState == WAIT_VALUE_HEAD) { -+ pucValueHead = &pbuf[i]; -+ pucValueTail = &pbuf[i]; -+ ucState = WAIT_VALUE_TAIL; -+ } else if (ucState == WAIT_VALUE_TAIL) -+ pucValueTail = &pbuf[i]; -+ } -+ } -+ -+ } /* for */ -+ -+ if (ucState == WAIT_VALUE_TAIL) { -+ /* Entry found */ -+ if (pucValueTail) -+ wlanCfgParseAddEntry(prAdapter, pucKeyHead, pucKeyTail, pucValueHead, pucValueTail); -+ } -+#endif -+ -+ return WLAN_STATUS_SUCCESS; -+} -+#endif -+ -+#if CFG_SUPPORT_CFG_FILE -+WLAN_STATUS wlanCfgInit(IN P_ADAPTER_T prAdapter, PUINT_8 pucConfigBuf, UINT_32 u4ConfigBufLen, UINT_32 u4Flags) -+{ -+ P_WLAN_CFG_T prWlanCfg; -+ /* P_WLAN_CFG_ENTRY_T prWlanCfgEntry; */ -+ prAdapter->prWlanCfg = &prAdapter->rWlanCfg; -+ prWlanCfg = prAdapter->prWlanCfg; -+ -+ kalMemZero(prWlanCfg, sizeof(WLAN_CFG_T)); -+ ASSERT(prWlanCfg); -+ prWlanCfg->u4WlanCfgEntryNumMax = WLAN_CFG_ENTRY_NUM_MAX; -+ prWlanCfg->u4WlanCfgKeyLenMax = WLAN_CFG_KEY_LEN_MAX; -+ prWlanCfg->u4WlanCfgValueLenMax = WLAN_CFG_VALUE_LEN_MAX; -+#if 0 -+ DBGLOG(INIT, INFO, "Init wifi config len %u max entry %u\n", u4ConfigBufLen, prWlanCfg->u4WlanCfgEntryNumMax); -+#endif -+ /* self test */ -+ wlanCfgSet(prAdapter, "ConfigValid", "0x123", 0); -+ if (wlanCfgGetUint32(prAdapter, "ConfigValid", 0) != 0x123) -+ DBGLOG(INIT, ERROR, "wifi config error %u\n", __LINE__); -+ wlanCfgSet(prAdapter, "ConfigValid", "1", 0); -+ if (wlanCfgGetUint32(prAdapter, "ConfigValid", 0) != 1) -+ DBGLOG(INIT, ERROR, "wifi config error %u\n", __LINE__); -+#if 0 /* soc chip didn't support these parameters now */ -+ /* Add initil config */ -+ /* use g,wlan,p2p,ap as prefix */ -+ /* Don't set cb here , overwrite by another api */ -+ wlanCfgSet(prAdapter, "TxLdpc", "1", 0); -+ wlanCfgSet(prAdapter, "RxLdpc", "1", 0); -+ wlanCfgSet(prAdapter, "RxBeamformee", "1", 0); -+ wlanCfgSet(prAdapter, "RoamTh1", "100", 0); -+ wlanCfgSet(prAdapter, "RoamTh2", "150", 0); -+ wlanCfgSet(prAdapter, "wlanRxLdpc", "1", 0); -+ wlanCfgSet(prAdapter, "apRxLdpc", "1", 0); -+ wlanCfgSet(prAdapter, "p2pRxLdpc", "1", 0); -+#endif -+ /* Parse the pucConfigBuff */ -+ -+ if (pucConfigBuf && (u4ConfigBufLen > 0)) -+ wlanCfgParse(prAdapter, pucConfigBuf, u4ConfigBufLen); -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is to initialize WLAN feature options -+* -+* @param prAdapter Pointer of ADAPTER_T -+* -+* @return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID wlanCfgApply(IN P_ADAPTER_T prAdapter) -+{ -+#define STR2BYTE(s) (((((PUINT_8)s)[0]-'0')*10)+(((PUINT_8)s)[1]-'0')) -+ CHAR aucValue[WLAN_CFG_VALUE_LEN_MAX]; -+ P_WIFI_VAR_T prWifiVar = &prAdapter->rWifiVar; -+ P_REG_INFO_T prRegInfo = &prAdapter->prGlueInfo->rRegInfo; -+ P_TX_PWR_PARAM_T prTxPwr = &prRegInfo->rTxPwr; -+ -+ kalMemZero(aucValue, sizeof(aucValue)); -+ DBGLOG(INIT, LOUD, "CFG_FILE: Apply Config File\n"); -+ /* Apply COUNTRY Config */ -+ if (wlanCfgGet(prAdapter, "country", aucValue, "", 0) == WLAN_STATUS_SUCCESS) { -+ DBGLOG(INIT, LOUD, "CFG_FILE: Found Country Key, Value=%s\n", aucValue); -+ prAdapter->rWifiVar.rConnSettings.u2CountryCode = -+ (((UINT_16) aucValue[0]) << 8) | ((UINT_16) aucValue[1]); -+ prRegInfo->au2CountryCode[0] = aucValue[0]; -+ prRegInfo->au2CountryCode[1] = aucValue[1]; -+ } -+ prWifiVar->ucApWpsMode = (UINT_8) wlanCfgGetUint32(prAdapter, "ApWpsMode", 0); -+ prWifiVar->ucCert11nMode = (UINT_8)wlanCfgGetUint32(prAdapter, "Cert11nMode", 0); -+ DBGLOG(INIT, LOUD, "CFG_FILE: ucApWpsMode = %u, ucCert11nMode = %u\n", -+ prWifiVar->ucApWpsMode, prWifiVar->ucCert11nMode); -+ if (prWifiVar->ucCert11nMode == 1) -+ nicWriteMcr(prAdapter, 0x11111115 , 1); -+ -+ if (wlanCfgGet(prAdapter, "5G_support", aucValue, "", 0) == WLAN_STATUS_SUCCESS) -+ prRegInfo->ucSupport5GBand = (*aucValue == 'y') ? 1 : 0; -+ if (wlanCfgGet(prAdapter, "TxPower2G4CCK", aucValue, "", 0) == WLAN_STATUS_SUCCESS -+ && kalStrLen(aucValue) == 2) { -+ prTxPwr->cTxPwr2G4Cck = STR2BYTE(aucValue); -+ DBGLOG(INIT, LOUD, "2.4G cck=%d\n", prTxPwr->cTxPwr2G4Cck); -+ } -+ if (wlanCfgGet(prAdapter, "TxPower2G4OFDM", aucValue, "", 0) == WLAN_STATUS_SUCCESS && -+ kalStrLen(aucValue) == 10) { -+ prTxPwr->cTxPwr2G4OFDM_BPSK = STR2BYTE(aucValue); -+ prTxPwr->cTxPwr2G4OFDM_QPSK = STR2BYTE(aucValue + 2); -+ prTxPwr->cTxPwr2G4OFDM_16QAM = STR2BYTE(aucValue + 4); -+ prTxPwr->cTxPwr2G4OFDM_48Mbps = STR2BYTE(aucValue + 6); -+ prTxPwr->cTxPwr2G4OFDM_54Mbps = STR2BYTE(aucValue + 8); -+ DBGLOG(INIT, LOUD, "2.4G OFDM=%d,%d,%d,%d,%d\n", -+ prTxPwr->cTxPwr2G4OFDM_BPSK, prTxPwr->cTxPwr2G4OFDM_QPSK, -+ prTxPwr->cTxPwr2G4OFDM_16QAM, prTxPwr->cTxPwr2G4OFDM_48Mbps, -+ prTxPwr->cTxPwr2G4OFDM_54Mbps); -+ } -+ if (wlanCfgGet(prAdapter, "TxPower2G4HT20", aucValue, "", 0) == WLAN_STATUS_SUCCESS && -+ kalStrLen(aucValue) == 12) { -+ prTxPwr->cTxPwr2G4HT20_BPSK = STR2BYTE(aucValue); -+ prTxPwr->cTxPwr2G4HT20_QPSK = STR2BYTE(aucValue + 2); -+ prTxPwr->cTxPwr2G4HT20_16QAM = STR2BYTE(aucValue + 4); -+ prTxPwr->cTxPwr2G4HT20_MCS5 = STR2BYTE(aucValue + 6); -+ prTxPwr->cTxPwr2G4HT20_MCS6 = STR2BYTE(aucValue + 8); -+ prTxPwr->cTxPwr2G4HT20_MCS7 = STR2BYTE(aucValue + 10); -+ DBGLOG(INIT, LOUD, "2.4G HT20=%d,%d,%d,%d,%d,%d\n", -+ prTxPwr->cTxPwr2G4HT20_BPSK, prTxPwr->cTxPwr2G4HT20_QPSK, -+ prTxPwr->cTxPwr2G4HT20_16QAM, prTxPwr->cTxPwr2G4HT20_MCS5, -+ prTxPwr->cTxPwr2G4HT20_MCS6, prTxPwr->cTxPwr2G4HT20_MCS7); -+ } -+ if (wlanCfgGet(prAdapter, "TxPower2G4HT40", aucValue, "", 0) == WLAN_STATUS_SUCCESS && -+ kalStrLen(aucValue) == 12) { -+ prTxPwr->cTxPwr2G4HT40_BPSK = STR2BYTE(aucValue); -+ prTxPwr->cTxPwr2G4HT40_QPSK = STR2BYTE(aucValue + 2); -+ prTxPwr->cTxPwr2G4HT40_16QAM = STR2BYTE(aucValue + 4); -+ prTxPwr->cTxPwr2G4HT40_MCS5 = STR2BYTE(aucValue + 6); -+ prTxPwr->cTxPwr2G4HT40_MCS6 = STR2BYTE(aucValue + 8); -+ prTxPwr->cTxPwr2G4HT40_MCS7 = STR2BYTE(aucValue + 10); -+ DBGLOG(INIT, LOUD, "2.4G HT40=%d,%d,%d,%d,%d,%d\n", -+ prTxPwr->cTxPwr2G4HT40_BPSK, prTxPwr->cTxPwr2G4HT40_QPSK, -+ prTxPwr->cTxPwr2G4HT40_16QAM, prTxPwr->cTxPwr2G4HT40_MCS5, -+ prTxPwr->cTxPwr2G4HT40_MCS6, prTxPwr->cTxPwr2G4HT40_MCS7); -+ } -+ if (wlanCfgGet(prAdapter, "TxPower5GOFDM", aucValue, "", 0) == WLAN_STATUS_SUCCESS -+ && kalStrLen(aucValue) == 10) { -+ prTxPwr->cTxPwr5GOFDM_BPSK = STR2BYTE(aucValue); -+ prTxPwr->cTxPwr5GOFDM_QPSK = STR2BYTE(aucValue + 2); -+ prTxPwr->cTxPwr5GOFDM_16QAM = STR2BYTE(aucValue + 4); -+ prTxPwr->cTxPwr5GOFDM_48Mbps = STR2BYTE(aucValue + 6); -+ prTxPwr->cTxPwr5GOFDM_54Mbps = STR2BYTE(aucValue + 8); -+ DBGLOG(INIT, LOUD, "5G OFDM=%d,%d,%d,%d,%d\n", -+ prTxPwr->cTxPwr5GOFDM_BPSK, prTxPwr->cTxPwr5GOFDM_QPSK, -+ prTxPwr->cTxPwr5GOFDM_16QAM, prTxPwr->cTxPwr5GOFDM_48Mbps, -+ prTxPwr->cTxPwr5GOFDM_54Mbps); -+ } -+ if (wlanCfgGet(prAdapter, "TxPower5GHT20", aucValue, "", 0) == WLAN_STATUS_SUCCESS -+ && kalStrLen(aucValue) == 12) { -+ prTxPwr->cTxPwr5GHT20_BPSK = STR2BYTE(aucValue); -+ prTxPwr->cTxPwr5GHT20_QPSK = STR2BYTE(aucValue + 2); -+ prTxPwr->cTxPwr5GHT20_16QAM = STR2BYTE(aucValue + 4); -+ prTxPwr->cTxPwr5GHT20_MCS5 = STR2BYTE(aucValue + 6); -+ prTxPwr->cTxPwr5GHT20_MCS6 = STR2BYTE(aucValue + 8); -+ prTxPwr->cTxPwr5GHT20_MCS7 = STR2BYTE(aucValue + 10); -+ DBGLOG(INIT, LOUD, "5G HT20=%d,%d,%d,%d,%d,%d\n", -+ prTxPwr->cTxPwr5GHT20_BPSK, prTxPwr->cTxPwr5GHT20_QPSK, -+ prTxPwr->cTxPwr5GHT20_16QAM, prTxPwr->cTxPwr5GHT20_MCS5, prTxPwr->cTxPwr5GHT20_MCS6, -+ prTxPwr->cTxPwr5GHT20_MCS7); -+ } -+ if (wlanCfgGet(prAdapter, "TxPower5GHT40", aucValue, "", 0) == WLAN_STATUS_SUCCESS -+ && kalStrLen(aucValue) == 12) { -+ prTxPwr->cTxPwr5GHT40_BPSK = STR2BYTE(aucValue); -+ prTxPwr->cTxPwr5GHT40_QPSK = STR2BYTE(aucValue + 2); -+ prTxPwr->cTxPwr5GHT40_16QAM = STR2BYTE(aucValue + 4); -+ prTxPwr->cTxPwr5GHT40_MCS5 = STR2BYTE(aucValue + 6); -+ prTxPwr->cTxPwr5GHT40_MCS6 = STR2BYTE(aucValue + 8); -+ prTxPwr->cTxPwr5GHT40_MCS7 = STR2BYTE(aucValue + 10); -+ DBGLOG(INIT, LOUD, "5G HT40=%d,%d,%d,%d,%d,%d\n", -+ prTxPwr->cTxPwr5GHT40_BPSK, prTxPwr->cTxPwr5GHT40_QPSK, -+ prTxPwr->cTxPwr5GHT40_16QAM, prTxPwr->cTxPwr5GHT40_MCS5, prTxPwr->cTxPwr5GHT40_MCS6, -+ prTxPwr->cTxPwr5GHT40_MCS7); -+ } -+ /* TODO: Apply other Config */ -+} -+#endif /* CFG_SUPPORT_CFG_FILE */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/common/wlan_oid.c b/drivers/misc/mediatek/connectivity/wlan/gen2/common/wlan_oid.c -new file mode 100644 -index 000000000000..993ff061ed20 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/common/wlan_oid.c -@@ -0,0 +1,11050 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/common/wlan_oid.c#5 -+*/ -+ -+/*! \file wlanoid.c -+ \brief This file contains the WLAN OID processing routines of Windows driver for -+ MediaTek Inc. 802.11 Wireless LAN Adapters. -+*/ -+ -+/* -+** Log: wlan_oid.c -+** -+** 09 05 2013 cp.wu -+** isolate logic regarding roaming & reassociation -+** -+** 09 03 2013 cp.wu -+** add path for reassociation -+** -+** 09 02 2013 cp.wu -+** add path to handle reassociation request -+** -+** 07 19 2012 yuche.tsai -+** NULL -+** Code update for JB. -+ * -+ * 07 17 2012 yuche.tsai -+ * NULL -+ * Let netdev bring up. -+ * -+ * 07 17 2012 yuche.tsai -+ * NULL -+ * Compile no error before trial run. -+ * -+ * 03 02 2012 terry.wu -+ * NULL -+ * Sync CFG80211 modification from branch 2,2. -+ * -+ * 01 06 2012 wh.su -+ * [WCXRP00001153] [MT6620 Wi-Fi][Driver] Adding the get_ch_list and set_tx_power proto type function -+ * using the wlanSendSetQueryCmd to set the tx power control cmd. -+ * -+ * 01 06 2012 wh.su -+ * [WCXRP00001153] [MT6620 Wi-Fi][Driver] Adding the get_ch_list and set_tx_power proto type function -+ * change the set tx power cmd name. -+ * -+ * 01 05 2012 wh.su -+ * [WCXRP00001153] [MT6620 Wi-Fi][Driver] Adding the get_ch_list and set_tx_power proto type function -+ * Adding the related ioctl / wlan oid function to set the Tx power cfg. -+ * -+ * 12 20 2011 cp.wu -+ * [WCXRP00001144] [MT6620 Wi-Fi][Driver][Firmware] Add RF_FUNC_ID for exposing device and related version information -+ * add driver implementations for RF_AT_FUNCID_FW_INFO & RF_AT_FUNCID_DRV_INFO -+ * to expose version information -+ * -+ * 12 05 2011 cp.wu -+ * [WCXRP00001131] [MT6620 Wi-Fi][Driver][AIS] Implement connect-by-BSSID path -+ * add CONNECT_BY_BSSID policy -+ * -+ * 11 22 2011 cp.wu -+ * [WCXRP00001120] [MT6620 Wi-Fi][Driver] Modify roaming to AIS state transition from synchronous to -+ * asynchronous approach to avoid incomplete state termination -+ * 1. change RDD related compile option brace position. -+ * 2. when roaming is triggered, ask AIS to transit immediately only when AIS is in Normal TR state -+ * without join timeout timer ticking -+ * 3. otherwise, insert AIS_REQUEST into pending request queue -+ * -+ * 11 21 2011 cp.wu -+ * [WCXRP00001118] [MT6620 Wi-Fi][Driver] Corner case protections to pass Monkey testing -+ * 1. wlanoidQueryBssIdList might be passed with a non-zero length but a NULL pointer of buffer -+ * add more checking for such cases -+ * -+ * 2. kalSendComplete() might be invoked with a packet belongs to P2P network right after P2P is unregistered. -+ * add some tweaking to protect such cases because that net device has become invalid. -+ * -+ * 11 15 2011 cm.chang -+ * NULL -+ * Fix compiling warning -+ * -+ * 11 11 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * modify the xlog related code. -+ * -+ * 11 11 2011 tsaiyuan.hsu -+ * [WCXRP00001083] [MT6620 Wi-Fi][DRV]] dump debug counter or frames when debugging is triggered -+ * add debug counters of bb and ar for xlog. -+ * -+ * 11 10 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * change the debug module level. -+ * -+ * 11 09 2011 george.huang -+ * [WCXRP00000871] [MT6620 Wi-Fi][FW] Include additional wakeup condition, which is by -+ * consequent DTIM unicast indication add XLOG for Set PS mode entry -+ * -+ * 11 08 2011 tsaiyuan.hsu -+ * [WCXRP00001083] [MT6620 Wi-Fi][DRV]] dump debug counter or frames when debugging is triggered -+ * check if CFG_SUPPORT_SWCR is defined to aoid compiler error. -+ * -+ * 11 07 2011 tsaiyuan.hsu -+ * [WCXRP00001083] [MT6620 Wi-Fi][DRV]] dump debug counter or frames when debugging is triggered -+ * add debug counters and periodically dump counters for debugging. -+ * -+ * 11 03 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * change the DBGLOG for "\n" and "\r\n". LABEL to LOUD for XLOG -+ * -+ * 11 02 2011 chinghwa.yu -+ * [WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm -+ * Add RDD certification features. -+ * -+ * 10 21 2011 eddie.chen -+ * [WCXRP00001051] [MT6620 Wi-Fi][Driver/Fw] Adjust the STA aging timeout -+ * Add switch to ignore the STA aging timeout. -+ * -+ * 10 12 2011 wh.su -+ * [WCXRP00001036] [MT6620 Wi-Fi][Driver][FW] Adding the 802.11w code for MFP -+ * adding the 802.11w related function and define . -+ * -+ * 09 15 2011 tsaiyuan.hsu -+ * [WCXRP00000938] [MT6620 Wi-Fi][FW] add system config for CTIA -+ * correct fifo full control from query to set operation for CTIA. -+ * -+ * 08 31 2011 cm.chang -+ * [WCXRP00000969] [MT6620 Wi-Fi][Driver][FW] Channel list for 5G band based on country code -+ * . -+ * -+ * 08 17 2011 tsaiyuan.hsu -+ * [WCXRP00000938] [MT6620 Wi-Fi][FW] add system config for CTIA -+ * add system config for CTIA. -+ * -+ * 08 15 2011 george.huang -+ * [MT6620 Wi-Fi][FW] handle TSF drift for connection detection -+ * . -+ * -+ * 07 28 2011 chinghwa.yu -+ * [WCXRP00000063] Update BCM CoEx design and settings -+ * Add BWCS cmd and event. -+ * -+ * 07 18 2011 chinghwa.yu -+ * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm -+ * Add CMD/Event for RDD and BWCS. -+ * -+ * 07 11 2011 wh.su -+ * [WCXRP00000849] [MT6620 Wi-Fi][Driver] Remove some of the WAPI define for make sure the value is initialize, -+ * for customer not enable WAPI -+ * For make sure wapi initial value is set. -+ * -+ * 06 23 2011 cp.wu -+ * [WCXRP00000812] [MT6620 Wi-Fi][Driver] not show NVRAM when there is no valid MAC address in NVRAM content -+ * check with firmware for valid MAC address. -+ * -+ * 05 02 2011 eddie.chen -+ * [WCXRP00000373] [MT6620 Wi-Fi][FW] SW debug control -+ * Fix compile warning. -+ * -+ * 04 29 2011 george.huang -+ * [WCXRP00000684] [MT6620 Wi-Fi][Driver] Support P2P setting ARP filter -+ * . -+ * -+ * 04 27 2011 george.huang -+ * [WCXRP00000684] [MT6620 Wi-Fi][Driver] Support P2P setting ARP filter -+ * add more debug message -+ * -+ * 04 26 2011 eddie.chen -+ * [WCXRP00000373] [MT6620 Wi-Fi][FW] SW debug control -+ * Add rx path profiling. -+ * -+ * 04 12 2011 eddie.chen -+ * [WCXRP00000617] [MT6620 Wi-Fi][DRV/FW] Fix for sigma -+ * Fix the sta index in processing security frame -+ * Simple flow control for TC4 to avoid mgt frames for PS STA to occupy the TC4 -+ * Add debug message. -+ * -+ * 04 08 2011 george.huang -+ * [WCXRP00000621] [MT6620 Wi-Fi][Driver] Support P2P supplicant to set power mode -+ * separate settings of P2P and AIS -+ * -+ * 03 31 2011 puff.wen -+ * NULL -+ * . -+ * -+ * 03 29 2011 puff.wen -+ * NULL -+ * Add chennel switch for stress test -+ * -+ * 03 29 2011 cp.wu -+ * [WCXRP00000604] [MT6620 Wi-Fi][Driver] Surpress Klockwork Warning -+ * surpress klock warning with code path rewritten -+ * -+ * 03 24 2011 wh.su -+ * [WCXRP00000595] [MT6620 Wi-Fi][Driver] at CTIA indicate disconnect to make the ps profile can apply -+ * use disconnect event instead of ais abort for CTIA testing. -+ * -+ * 03 23 2011 george.huang -+ * [WCXRP00000586] [MT6620 Wi-Fi][FW] Modify for blocking absence request right after connected -+ * revise for CTIA power mode setting -+ * -+ * 03 22 2011 george.huang -+ * [WCXRP00000504] [MT6620 Wi-Fi][FW] Support Sigma CAPI for power saving related command -+ * link with supplicant commands -+ * -+ * 03 17 2011 chinglan.wang -+ * [WCXRP00000570] [MT6620 Wi-Fi][Driver] Add Wi-Fi Protected Setup v2.0 feature -+ * . -+ * -+ * 03 17 2011 yarco.yang -+ * [WCXRP00000569] [MT6620 Wi-Fi][F/W][Driver] Set multicast address support current network usage -+ * . -+ * -+ * 03 15 2011 george.huang -+ * [WCXRP00000557] [MT6620 Wi-Fi] Support current consumption test mode commands -+ * Support current consumption measurement mode command -+ * -+ * 03 15 2011 eddie.chen -+ * [WCXRP00000554] [MT6620 Wi-Fi][DRV] Add sw control debug counter -+ * Add sw debug counter for QM. -+ * -+ * 03 10 2011 cp.wu -+ * [WCXRP00000532] [MT6620 Wi-Fi][Driver] Migrate NVRAM configuration procedures from MT6620 E2 to MT6620 E3 -+ * deprecate configuration used by MT6620 E2 -+ * -+ * 03 07 2011 terry.wu -+ * [WCXRP00000521] [MT6620 Wi-Fi][Driver] Remove non-standard debug message -+ * Toggle non-standard debug messages to comments. -+ * -+ * 03 04 2011 cp.wu -+ * [WCXRP00000515] [MT6620 Wi-Fi][Driver] Surpress compiler warning which is identified by GNU compiler collection -+ * surpress compile warning occurred when compiled by GNU compiler collection. -+ * -+ * 03 03 2011 wh.su -+ * [WCXRP00000510] [MT6620 Wi-Fi] [Driver] Fixed the CTIA enter test mode issue -+ * fixed the enter ctia test mode issue. -+ * -+ * 03 02 2011 george.huang -+ * [WCXRP00000504] [MT6620 Wi-Fi][FW] Support Sigma CAPI for power saving related command -+ * Update sigma CAPI for U-APSD setting -+ * -+ * 03 02 2011 george.huang -+ * [WCXRP00000504] [MT6620 Wi-Fi][FW] Support Sigma CAPI for power saving related command -+ * Support UAPSD/OppPS/NoA parameter setting -+ * -+ * 03 02 2011 cp.wu -+ * [WCXRP00000503] [MT6620 Wi-Fi][Driver] Take RCPI brought by association response as -+ * initial RSSI right after connection is built. -+ * use RCPI brought by ASSOC-RESP after connection is built as initial RCPI to avoid using a uninitialized MAC-RX RCPI. -+ * -+ * 01 27 2011 george.huang -+ * [WCXRP00000400] [MT6620 Wi-Fi] support CTIA power mode setting -+ * Support CTIA power mode setting. -+ * -+ * 01 26 2011 wh.su -+ * [WCXRP00000396] [MT6620 Wi-Fi][Driver] Support Sw Ctrl ioctl at linux -+ * adding the SW cmd ioctl support, use set/get structure ioctl. -+ * -+ * 01 25 2011 cp.wu -+ * [WCXRP00000394] [MT6620 Wi-Fi][Driver] Count space needed for generating error message in -+ * scanning list into buffer size checking -+ * when doing size prechecking, check illegal MAC address as well -+ * -+ * 01 20 2011 eddie.chen -+ * [WCXRP00000374] [MT6620 Wi-Fi][DRV] SW debug control -+ * Add Oid for sw control debug command -+ * -+ * 01 15 2011 puff.wen -+ * NULL -+ * Add Stress test -+ * -+ * 01 12 2011 cp.wu -+ * [WCXRP00000358] [MT6620 Wi-Fi][Driver] Provide concurrent information for each module -+ * check if allow to switch to IBSS mode via concurrent module before setting to IBSS mode -+ * -+ * 01 12 2011 cm.chang -+ * [WCXRP00000354] [MT6620 Wi-Fi][Driver][FW] Follow NVRAM bandwidth setting -+ * User-defined bandwidth is for 2.4G and 5G individually -+ * -+ * 01 04 2011 cp.wu -+ * [WCXRP00000342] [MT6620 Wi-Fi][Driver] show error code in scanning list when MAC address is not -+ * correctly configured in NVRAM -+ * show error code 0x10 when MAC address in NVRAM is not configured correctly. -+ * -+ * 01 04 2011 cp.wu -+ * [WCXRP00000338] [MT6620 Wi-Fi][Driver] Separate kalMemAlloc into kmalloc and vmalloc implementations -+ * to ease physically continuous memory demands -+ * separate kalMemAlloc() into virtually-continuous and physically-continuous type to ease slab system pressure -+ * -+ * 12 28 2010 george.huang -+ * [WCXRP00000232] [MT5931 Wi-Fi][FW] Modifications for updated HW power on sequence and related design -+ * support WMM-PS U-APSD AC assignment. -+ * -+ * 12 28 2010 cp.wu -+ * [WCXRP00000269] [MT6620 Wi-Fi][Driver][Firmware] Prepare for v1.1 branch release -+ * report EEPROM used flag via NIC_CAPABILITY -+ * -+ * 12 28 2010 cp.wu -+ * [WCXRP00000269] [MT6620 Wi-Fi][Driver][Firmware] Prepare for v1.1 branch release -+ * integrate with 'EEPROM used' flag for reporting correct capability to Engineer Mode/META and other tools -+ * -+ * 12 16 2010 cp.wu -+ * [WCXRP00000268] [MT6620 Wi-Fi][Driver] correction for WHQL failed items -+ * correction for OID_802_11_NETWORK_TYPES_SUPPORTED handlers -+ * -+ * 12 13 2010 cp.wu -+ * [WCXRP00000256] [MT6620 Wi-Fi][Driver] Eliminate potential issues which is identified by Klockwork -+ * suppress warning reported by Klockwork. -+ * -+ * 12 07 2010 cm.chang -+ * [WCXRP00000239] MT6620 Wi-Fi][Driver][FW] Merge concurrent branch back to maintrunk -+ * 1. BSSINFO include RLM parameter -+ * 2. free all sta records when network is disconnected -+ * -+ * 12 07 2010 cm.chang -+ * [WCXRP00000238] MT6620 Wi-Fi][Driver][FW] Support regulation domain setting from NVRAM and supplicant -+ * 1. Country code is from NVRAM or supplicant -+ * 2. Change band definition in CMD/EVENT. -+ * -+ * 11 30 2010 cp.wu -+ * [WCXRP00000213] [MT6620 Wi-Fi][Driver] Implement scanning with specified SSID for wpa_supplicant with ap_scan=1 -+ * . -+ * -+ * 11 26 2010 cp.wu -+ * [WCXRP00000209] [MT6620 Wi-Fi][Driver] Modify NVRAM checking mechanism to warning only -+ * with necessary data field checking -+ * 1. NVRAM error is now treated as warning only, thus normal operation is still available -+ * but extra scan result used to indicate user is attached -+ * 2. DPD and TX-PWR are needed fields from now on, if these 2 fields are not available then warning message is shown -+ * -+ * 11 25 2010 cp.wu -+ * [WCXRP00000208] [MT6620 Wi-Fi][Driver] Add scanning with specified SSID to AIS FSM -+ * add scanning with specified SSID facility to AIS-FSM -+ * -+ * 11 21 2010 wh.su -+ * [WCXRP00000192] [MT6620 Wi-Fi][Driver] Fixed fail trying to build connection with Security -+ * AP while enable WAPI message check -+ * Not set the wapi mode while the wapi assoc info set non-wapi ie. -+ * -+ * 11 05 2010 wh.su -+ * [WCXRP00000165] [MT6620 Wi-Fi] [Pre-authentication] Assoc req rsn ie use wrong pmkid value -+ * fixed the.pmkid value mismatch issue -+ * -+ * 11 01 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version -+ * Check[WCXRP00000150] [MT6620 Wi-Fi][Driver] Add implementation for querying -+ * current TX rate from firmware auto rate module -+ * 1) Query link speed (TX rate) from firmware directly with buffering mechanism to reduce overhead -+ * 2) Remove CNM CH-RECOVER event handling -+ * 3) cfg read/write API renamed with kal prefix for unified naming rules. -+ * -+ * 10 26 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version -+ * Check[WCXRP00000137] [MT6620 Wi-Fi] [FW] Support NIC capability query command -+ * 1) update NVRAM content template to ver 1.02 -+ * 2) add compile option for querying NIC capability (default: off) -+ * 3) modify AIS 5GHz support to run-time option, which could be turned on by registry or NVRAM setting -+ * 4) correct auto-rate compiler error under linux (treat warning as error) -+ * 5) simplify usage of NVRAM and REG_INFO_T -+ * 6) add version checking between driver and firmware -+ * -+ * 10 22 2010 cp.wu -+ * [WCXRP00000122] [MT6620 Wi-Fi][Driver] Preparation for YuSu source tree integration -+ * dos2unix conversion. -+ * -+ * 10 20 2010 cp.wu -+ * [WCXRP00000117] [MT6620 Wi-Fi][Driver] Add logic for suspending driver when MT6620 is not responding anymore -+ * use OID_CUSTOM_TEST_MODE as indication for driver reset -+ * by dropping pending TX packets -+ * -+ * 10 18 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version -+ * Check[WCXRP00000086] [MT6620 Wi-Fi][Driver] The mac address is all zero at android complete -+ * implementation of Android NVRAM access -+ * -+ * 10 06 2010 yuche.tsai -+ * NULL -+ * Update SLT 5G Test Channel Set. -+ * -+ * 10 06 2010 cp.wu -+ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning -+ * code reorganization to improve isolation between GLUE and CORE layers. -+ * -+ * 10 06 2010 yuche.tsai -+ * NULL -+ * Update For SLT 5G Test Channel Selection Rule. -+ * -+ * 10 05 2010 cp.wu -+ * [WCXRP00000075] [MT6620 Wi-Fi][Driver] Fill query buffer for OID_802_11_BSSID_LIST in 4-bytes aligned form -+ * Query buffer size needs to be enlarged due to result is filled in 4-bytes alignment boundary -+ * -+ * 10 05 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check -+ * 1) add NVRAM access API -+ * 2) fake scanning result when NVRAM doesn't exist and/or version mismatch. (off by compiler option) -+ * 3) add OID implementation for NVRAM read/write service -+ * -+ * 10 04 2010 cp.wu -+ * [WCXRP00000077] [MT6620 Wi-Fi][Driver][FW] Eliminate use of ENUM_NETWORK_TYPE_T and -+ * replaced by ENUM_NETWORK_TYPE_INDEX_T only remove ENUM_NETWORK_TYPE_T definitions -+ * -+ * 10 04 2010 cp.wu -+ * [WCXRP00000075] [MT6620 Wi-Fi][Driver] Fill query buffer for OID_802_11_BSSID_LIST in 4-bytes aligned form -+ * Extend result length to multiples of 4-bytes -+ * -+ * 09 24 2010 cp.wu -+ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning -+ * eliminate unused variables which lead gcc to argue -+ * -+ * 09 24 2010 cp.wu -+ * [WCXRP00000057] [MT6620 Wi-Fi][Driver] Modify online scan to a run-time switchable feature -+ * Modify online scan as a run-time adjustable option (for Windows, in registry) -+ * -+ * 09 23 2010 cp.wu -+ * [WCXRP00000051] [MT6620 Wi-Fi][Driver] WHQL test fail in MAC address changed item -+ * use firmware reported mac address right after wlanAdapterStart() as permanent address -+ * -+ * 09 23 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check -+ * add skeleton for NVRAM integration -+ * -+ * 09 08 2010 cp.wu -+ * NULL -+ * use static memory pool for storing IEs of scanning result. -+ * -+ * 09 07 2010 yuche.tsai -+ * NULL -+ * Update SLT due to API change of SCAN module. -+ * -+ * 09 06 2010 cp.wu -+ * NULL -+ * Androi/Linux: return current operating channel information -+ * -+ * 09 06 2010 cp.wu -+ * NULL -+ * 1) initialize for correct parameter even for disassociation. -+ * 2) AIS-FSM should have a limit on trials to build connection -+ * -+ * 09 03 2010 yuche.tsai -+ * NULL -+ * Refine SLT IO control handler. -+ * -+ * 09 03 2010 kevin.huang -+ * NULL -+ * Refine #include sequence and solve recursive/nested #include issue -+ * -+ * 09 01 2010 wh.su -+ * NULL -+ * adding the wapi support for integration test. -+ * -+ * 08 30 2010 chinglan.wang -+ * NULL -+ * Modify the rescan condition. -+ * -+ * 08 29 2010 yuche.tsai -+ * NULL -+ * Finish SLT TX/RX & Rate Changing Support. -+ * -+ * 08 27 2010 chinglan.wang -+ * NULL -+ * Update configuration for MT6620_E1_PRE_ALPHA_1832_0827_2010 -+ * -+ * 08 25 2010 george.huang -+ * NULL -+ * update OID/ registry control path for PM related settings -+ * -+ * 08 24 2010 cp.wu -+ * NULL -+ * 1) initialize variable for enabling short premable/short time slot. -+ * 2) add compile option for disabling online scan -+ * -+ * 08 16 2010 george.huang -+ * NULL -+ * . -+ * -+ * 08 16 2010 george.huang -+ * NULL -+ * update params defined in CMD_SET_NETWORK_ADDRESS_LIST -+ * -+ * 08 04 2010 cp.wu -+ * NULL -+ * fix for check build WHQL testing: -+ * 1) do not assert query buffer if indicated buffer length is zero -+ * 2) sdio.c has bugs which cause freeing same pointer twice -+ * -+ * 08 04 2010 cp.wu -+ * NULL -+ * revert changelist #15371, efuse read/write access will be done by RF test approach -+ * -+ * 08 04 2010 cp.wu -+ * NULL -+ * add OID definitions for EFUSE read/write access. -+ * -+ * 08 04 2010 george.huang -+ * NULL -+ * handle change PS mode OID/ CMD -+ * -+ * 08 04 2010 cp.wu -+ * NULL -+ * add an extra parameter to rftestQueryATInfo 'cause it's necessary to pass u4FuncData for query request. -+ * -+ * 08 04 2010 cp.wu -+ * NULL -+ * bypass u4FuncData for RF-Test query request as well. -+ * -+ * 08 04 2010 yarco.yang -+ * NULL -+ * Add TX_AMPDU and ADDBA_REJECT command -+ * -+ * 08 03 2010 cp.wu -+ * NULL -+ * surpress compilation warning. -+ * -+ * 08 02 2010 george.huang -+ * NULL -+ * add WMM-PS test related OID/ CMD handlers -+ * -+ * 07 29 2010 cp.wu -+ * NULL -+ * eliminate u4FreqInKHz usage, combined into rConnections.ucAdHoc* -+ * -+ * 07 28 2010 cp.wu -+ * NULL -+ * 1) eliminate redundant variable eOPMode in prAdapter->rWlanInfo -+ * 2) change nicMediaStateChange() API prototype -+ * -+ * 07 26 2010 cp.wu -+ * -+ * re-commit code logic being overwriten. -+ * -+ * 07 24 2010 wh.su -+ * -+ * .support the Wi-Fi RSN -+ * -+ * 07 21 2010 cp.wu -+ * -+ * 1) change BG_SCAN to ONLINE_SCAN for consistent term -+ * 2) only clear scanning result when scan is permitted to do -+ * -+ * 07 20 2010 cp.wu -+ * -+ * 1) [AIS] when new scan is issued, clear currently available scanning result except the connected one -+ * 2) refine disconnection behaviour when issued during BG-SCAN process -+ * -+ * 07 19 2010 wh.su -+ * -+ * modify the auth and encry status variable. -+ * -+ * 07 16 2010 cp.wu -+ * -+ * remove work-around in case SCN is not available. -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 07 05 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) change fake BSS_DESC from channel 6 to channel 1 due to channel switching is not done yet. -+ * 2) after MAC address is queried from firmware, all related variables in driver domain should be updated as well -+ * -+ * 07 01 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * AIS-FSM integration with CNM channel request messages -+ * -+ * 07 01 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * implementation of DRV-SCN and related mailbox message handling. -+ * -+ * 06 29 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) sync to. CMD/EVENT document v0.03 -+ * 2) simplify DTIM period parsing in scan.c only, bss.c no longer parses it again. -+ * 3) send command packet to indicate FW-PM after -+ * a) 1st beacon is received after AIS has connected to an AP -+ * b) IBSS-ALONE has been created -+ * c) IBSS-MERGE has occurred -+ * -+ * 06 25 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add API in que_mgt to retrieve sta-rec index for security frames. -+ * -+ * 06 24 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 802.1x and bluetooth-over-Wi-Fi security frames are now delievered to firmware via command path instead of data path. -+ * -+ * 06 23 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) add SCN compilation option. -+ * 2) when SCN is not turned on, BSSID_SCAN will generate a fake entry for 1st connection -+ * -+ * 06 23 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * implement SCAN-REQUEST oid as mailbox message dispatching. -+ * -+ * 06 23 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * integrate . -+ * -+ * 06 22 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) add command warpper for STA-REC/BSS-INFO sync. -+ * 2) enhance command packet sending procedure for non-oid part -+ * 3) add command packet definitions for STA-REC/BSS-INFO sync. -+ * -+ * 06 21 2010 wh.su -+ * [WPD00003840][MT6620 5931] Security migration -+ * remove duplicate variable for migration. -+ * -+ * 06 21 2010 wh.su -+ * [WPD00003840][MT6620 5931] Security migration -+ * adding the compiling flag for oid pmkid. -+ * -+ * 06 21 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * enable RX management frame handling. -+ * -+ * 06 18 2010 wh.su -+ * [WPD00003840][MT6620 5931] Security migration -+ * migration the security related function from firmware. -+ * -+ * 06 11 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) migrate assoc.c. -+ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness -+ * 3) add configuration options for CNM_MEM and RSN modules -+ * 4) add data path for management frames -+ * 5) eliminate rPacketInfo of MSDU_INFO_T -+ * -+ * 06 10 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) eliminate CFG_CMD_EVENT_VERSION_0_9 -+ * 2) when disconnected, indicate nic directly (no event is needed) -+ * -+ * 06 07 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * merge wlan_def.h. -+ * -+ * 06 07 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * merge wifi_var.h, precomp.h, cnm_timer.h (data type only) -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 06 03 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * move timer callback to glue layer. -+ * -+ * 05 28 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * simplify cmd packet sending for RF test and MCR access OIDs -+ * -+ * 05 27 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * disable radio even when STA is not associated. -+ * -+ * 05 27 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * correct 2 OID behaviour to meet WHQL requirement. -+ * -+ * 05 26 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * 1) Modify set mac address code -+ * 2) remove power management macro -+ * -+ * 05 25 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * correct BSSID_LIST oid when radio if turned off. -+ * -+ * 05 24 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) when acquiring LP-own, write for clr-own with lower frequency compared to read poll -+ * 2) correct address list parsing -+ * -+ * 05 24 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * disable wlanoidSetNetworkAddress() temporally. -+ * -+ * 05 22 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * some OIDs should be DRIVER_CORE instead of GLUE_EXTENSION -+ * -+ * 05 22 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) disable NETWORK_LAYER_ADDRESSES handling temporally. -+ * 2) finish statistics OIDs -+ * -+ * 05 22 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * change OID behavior to meet WHQL requirement. -+ * -+ * 05 20 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) integrate OID_GEN_NETWORK_LAYER_ADDRESSES with CMD_ID_SET_IP_ADDRESS -+ * 2) buffer statistics data for 2 seconds -+ * 3) use default value for adhoc parameters instead of 0 -+ * -+ * 05 19 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) do not take timeout mechanism for power mode oids -+ * 2) retrieve network type from connection status -+ * 3) after disassciation, set radio state to off -+ * 4) TCP option over IPv6 is supported -+ * -+ * 05 18 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * implement Wakeup-on-LAN except firmware integration part -+ * -+ * 05 17 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * correct wlanoidSet802dot11PowerSaveProfile implementation. -+ * -+ * 05 17 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) enable CMD/EVENT ver 0.9 definition. -+ * 2) abandon use of ENUM_MEDIA_STATE -+ * -+ * 05 17 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * correct OID_802_11_DISASSOCIATE handling. -+ * -+ * 05 17 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * 1) add timeout handler mechanism for pending command packets -+ * 2) add p2p add/removal key -+ * -+ * 05 14 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * Add dissassocation support for wpa supplicant -+ * -+ * 05 14 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * correct return value. -+ * -+ * 05 13 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * add NULL OID implementation for WOL-related OIDs. -+ * -+ * 05 06 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * for disassociation, still use parameter with current setting. -+ * -+ * 05 06 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * for disassociation, generate a WZC-compatible invalid SSID. -+ * -+ * 05 06 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * associate to illegal SSID when handling OID_802_11_DISASSOCIATE -+ * -+ * 04 27 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * reserve field of privacy filter and RTS threshold setting. -+ * -+ * 04 23 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * surpress compiler warning -+ * -+ * 04 23 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * . -+ * -+ * 04 22 2010 cp.wu -+ * [WPD00003830]add OID_802_11_PRIVACY_FILTER support -+ * enable RX filter OID -+ * -+ * 04 19 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * Add ioctl of power management -+ * -+ * 04 14 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * information buffer for query oid/ioctl is now buffered in prCmdInfo -+ * * instead of glue-layer variable to improve multiple oid/ioctl capability -+ * -+ * 04 13 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * add framework for BT-over-Wi-Fi support. -+ * * * * 1) prPendingCmdInfo is replaced by queue for multiple handler capability -+ * * * * 2) command sequence number is now increased atomically -+ * * * * 3) private data could be hold and taken use for other purpose -+ * -+ * 04 12 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * correct OID_802_11_CONFIGURATION query for infrastructure mode. -+ * -+ * 04 09 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * 1) remove unused spin lock declaration -+ * -+ * 04 07 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * finish non-glue layer access to glue variables -+ * -+ * 04 07 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * rWlanInfo should be placed at adapter rather than glue due to most operations -+ * * are done in adapter layer. -+ * -+ * 04 07 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * (1)improve none-glue code portability -+ * (2) disable set Multicast address during atomic context -+ * -+ * 04 07 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * eliminate direct access to prGlueInfo->eParamMediaStateIndicated from non-glue layer -+ * -+ * 04 06 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * ePowerCtrl is not necessary as a glue variable. -+ * -+ * 04 06 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * eliminate direct access to prGlueInfo->rWlanInfo.eLinkAttr.ucMediaStreamMode from non-glue layer. -+ * -+ * 04 06 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * improve none-glue code portability -+ * -+ * 04 06 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * code refine: fgTestMode should be at adapter rather than glue due to the device/fw is also involved -+ * -+ * 04 01 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * . -+ * -+ * 03 31 2010 wh.su -+ * [WPD00003816][MT6620 Wi-Fi] Adding the security support -+ * modify the wapi related code for new driver's design. -+ * -+ * 03 30 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * statistics information OIDs are now handled by querying from firmware domain -+ * -+ * 03 28 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * improve glue code portability -+ * -+ * 03 26 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * indicate media stream mode after set is done -+ * -+ * 03 26 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * add a temporary flag for integration with CMD/EVENT v0.9. -+ * -+ * 03 25 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) correct OID_802_11_CONFIGURATION with frequency setting behavior. -+ * the frequency is used for adhoc connection only -+ * 2) update with SD1 v0.9 CMD/EVENT documentation -+ * -+ * 03 24 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * [WPD00003826] Initial import for Linux port -+ * initial import for Linux port -+ * -+ * 03 24 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * initial import for Linux port -+ * -+ * 03 24 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * generate information for OID_GEN_RCV_OK & OID_GEN_XMIT_OK -+ * -+ * -+ * 03 22 2010 cp.wu -+ * [WPD00003824][MT6620 Wi-Fi][New Feature] Add support of large scan list -+ * Implement feature needed by CR: WPD00003824: refining association command by pasting scanning result -+ * -+ * 03 19 2010 wh.su -+ * [WPD00003820][MT6620 Wi-Fi] Modify the code for meet the WHQL test -+ * adding the check for pass WHQL test item. -+ * -+ * 03 19 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) add ACPI D0/D3 state switching support -+ * * 2) use more formal way to handle interrupt when the status is retrieved from enhanced RX response -+ * -+* 03 16 2010 wh.su -+ * [WPD00003820][MT6620 Wi-Fi] Modify the code for meet the WHQL test -+ * fixed some whql pre-test fail case. -+ * -+ * 03 03 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * implement custom OID: EEPROM read/write access -+ * -+ * 03 03 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * implement OID_802_3_MULTICAST_LIST oid handling -+ * -+ * 03 02 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) the use of prPendingOid revised, all accessing are now protected by spin lock -+ * * 2) ensure wlanReleasePendingOid will clear all command queues -+ * -+ * 02 25 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * send CMD_ID_INFRASTRUCTURE when handling OID_802_11_INFRASTRUCTURE_MODE set. -+ * -+ * 02 24 2010 wh.su -+ * [WPD00003820][MT6620 Wi-Fi] Modify the code for meet the WHQL test -+ * Don't needed to check the auth mode, WHQL testing not specific at auth wpa2. -+ * -+ * 02 23 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * do not check SSID validity anymore. -+ * -+ * 02 23 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * add checksum offloading support. -+ * -+ * 02 09 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1. Permanent and current MAC address are now retrieved by CMD/EVENT packets instead of hard-coded address -+ * * 2. follow MSDN defined behavior when associates to another AP -+ * * 3. for firmware download, packet size could be up to 2048 bytes -+ * -+ * 02 09 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * move ucCmdSeqNum as instance variable -+ * -+ * 02 04 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * when OID_CUSTOM_OID_INTERFACE_VERSION is queried, do modify connection states -+ * -+ * 01 27 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) implement timeout mechanism when OID is pending for longer than 1 second -+ * * 2) allow OID_802_11_CONFIGURATION to be executed when RF test mode is turned on -+ * -+ * 01 27 2010 wh.su -+ * [WPD00003816][MT6620 Wi-Fi] Adding the security support -+ * . -+ * -+ * 01 27 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1. eliminate improper variable in rHifInfo -+ * * 2. block TX/ordinary OID when RF test mode is engaged -+ * * 3. wait until firmware finish operation when entering into and leaving from RF test mode -+ * * 4. correct some HAL implementation -+ * -+ * 01 22 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * implement following 802.11 OIDs: -+ * OID_802_11_RSSI, -+ * OID_802_11_RSSI_TRIGGER, -+ * OID_802_11_STATISTICS, -+ * OID_802_11_DISASSOCIATE, -+ * OID_802_11_POWER_MODE -+ * -+ * 01 21 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * implement OID_802_11_MEDIA_STREAM_MODE -+ * -+ * 01 21 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * implement OID_802_11_SUPPORTED_RATES / OID_802_11_DESIRED_RATES -+ * -+ * 01 21 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * do not fill ucJoinOnly currently -+ * -+ * 01 14 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * enable to connect to ad-hoc network -+ * -+ * 01 07 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * .implement Set/Query BeaconInterval/AtimWindow -+ * -+ * 01 07 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * .Set/Get AT Info is not blocked even when driver is not in fg test mode -+ * -+ * 12 30 2009 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) According to CMD/EVENT documentation v0.8, -+ * OID_CUSTOM_TEST_RX_STATUS & OID_CUSTOM_TEST_TX_STATUS is no longer used, -+ * and result is retrieved by get ATInfo instead -+ * 2) add 4 counter for recording aggregation statistics -+ * -+ * 12 28 2009 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * eliminate redundant variables for connection_state -+** \main\maintrunk.MT6620WiFiDriver_Prj\32 2009-12-16 22:13:36 GMT mtk02752 -+** change hard-coded MAC address to match with FW (temporally) -+** \main\maintrunk.MT6620WiFiDriver_Prj\31 2009-12-10 16:49:50 GMT mtk02752 -+** code clean -+** \main\maintrunk.MT6620WiFiDriver_Prj\30 2009-12-08 17:38:49 GMT mtk02752 -+** + add OID for RF test -+** * MCR RD/WR are modified to match with cmd/event definition -+** \main\maintrunk.MT6620WiFiDriver_Prj\29 2009-12-08 11:32:20 GMT mtk02752 -+** add skeleton for RF test implementation -+** \main\maintrunk.MT6620WiFiDriver_Prj\28 2009-12-03 16:43:24 GMT mtk01461 -+** Modify query SCAN list oid by adding prEventScanResult -+** -+** \main\maintrunk.MT6620WiFiDriver_Prj\27 2009-12-03 16:39:27 GMT mtk01461 -+** Sync CMD data structure in set ssid oid -+** \main\maintrunk.MT6620WiFiDriver_Prj\26 2009-12-03 16:28:22 GMT mtk01461 -+** Add invalid check of set SSID oid and fix query scan list oid -+** \main\maintrunk.MT6620WiFiDriver_Prj\25 2009-11-30 17:33:08 GMT mtk02752 -+** implement wlanoidSetInfrastructureMode/wlanoidQueryInfrastructureMode -+** \main\maintrunk.MT6620WiFiDriver_Prj\24 2009-11-30 10:53:49 GMT mtk02752 -+** 1st DW of WIFI_CMD_T is shared with HIF_TX_HEADER_T -+** \main\maintrunk.MT6620WiFiDriver_Prj\23 2009-11-30 09:22:48 GMT mtk02752 -+** correct wifi cmd length mismatch -+** \main\maintrunk.MT6620WiFiDriver_Prj\22 2009-11-25 21:34:33 GMT mtk02752 -+** sync EVENT_SCAN_RESULT_T with firmware -+** \main\maintrunk.MT6620WiFiDriver_Prj\21 2009-11-25 21:03:27 GMT mtk02752 -+** implement wlanoidQueryBssidList() -+** \main\maintrunk.MT6620WiFiDriver_Prj\20 2009-11-25 18:17:17 GMT mtk02752 -+** refine GL_WLAN_INFO_T for buffering scan result -+** \main\maintrunk.MT6620WiFiDriver_Prj\19 2009-11-23 20:28:51 GMT mtk02752 -+** some OID will be set to WLAN_STATUS_PENDING until it is sent via wlanSendCommand() -+** \main\maintrunk.MT6620WiFiDriver_Prj\18 2009-11-23 17:56:36 GMT mtk02752 -+** implement wlanoidSetBssidListScan(), wlanoidSetBssid() and wlanoidSetSsid() -+** -+** \main\maintrunk.MT6620WiFiDriver_Prj\17 2009-11-13 17:20:53 GMT mtk02752 -+** add Set BSSID/SSID path but disabled temporally due to FW is not ready yet -+** \main\maintrunk.MT6620WiFiDriver_Prj\16 2009-11-13 12:28:58 GMT mtk02752 -+** add wlanoidSetBssidListScan -> cmd_info path -+** \main\maintrunk.MT6620WiFiDriver_Prj\15 2009-11-09 22:48:07 GMT mtk01084 -+** modify test cases entry -+** \main\maintrunk.MT6620WiFiDriver_Prj\14 2009-11-04 14:10:58 GMT mtk01084 -+** add new test interfaces -+** \main\maintrunk.MT6620WiFiDriver_Prj\13 2009-10-30 18:17:10 GMT mtk01084 -+** fix compiler warning -+** \main\maintrunk.MT6620WiFiDriver_Prj\12 2009-10-29 19:46:26 GMT mtk01084 -+** add test functions -+** \main\maintrunk.MT6620WiFiDriver_Prj\11 2009-10-23 16:07:56 GMT mtk01084 -+** include new file -+** \main\maintrunk.MT6620WiFiDriver_Prj\10 2009-10-13 21:58:29 GMT mtk01084 -+** modify for new HW architecture -+** \main\maintrunk.MT6620WiFiDriver_Prj\9 2009-10-02 13:48:49 GMT mtk01725 -+** \main\maintrunk.MT6620WiFiDriver_Prj\8 2009-09-09 17:26:04 GMT mtk01084 -+** \main\maintrunk.MT6620WiFiDriver_Prj\7 2009-04-21 12:09:50 GMT mtk01461 -+** Update for MCR Write OID -+** \main\maintrunk.MT6620WiFiDriver_Prj\6 2009-04-21 09:35:18 GMT mtk01461 -+** Update wlanoidQueryMcrRead() for composing CMD_INFO_T -+** \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-04-17 18:09:51 GMT mtk01426 -+** Remove kalIndicateStatusAndComplete() in wlanoidQueryOidInterfaceVersion() -+** \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-04-14 15:51:50 GMT mtk01426 -+** Add MCR read/write support -+** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-03-19 18:32:40 GMT mtk01084 -+** update for basic power management functions -+** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 20:06:31 GMT mtk01426 -+** Init for develop -+** -+*/ -+ -+/****************************************************************************** -+* C O M P I L E R F L A G S -+******************************************************************************* -+*/ -+ -+/****************************************************************************** -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************* -+*/ -+#include "precomp.h" -+#include "mgmt/rsn.h" -+ -+#include -+ -+/****************************************************************************** -+* C O N S T A N T S -+******************************************************************************* -+*/ -+ -+/****************************************************************************** -+* D A T A T Y P E S -+******************************************************************************* -+*/ -+ -+/****************************************************************************** -+* P U B L I C D A T A -+******************************************************************************* -+*/ -+ -+/****************************************************************************** -+* P R I V A T E D A T A -+******************************************************************************* -+*/ -+ -+/****************************************************************************** -+* M A C R O S -+******************************************************************************* -+*/ -+ -+/****************************************************************************** -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************* -+*/ -+ -+/****************************************************************************** -+* F U N C T I O N S -+******************************************************************************* -+*/ -+#if CFG_ENABLE_STATISTICS_BUFFERING -+static BOOLEAN IsBufferedStatisticsUsable(P_ADAPTER_T prAdapter) -+{ -+ ASSERT(prAdapter); -+ -+ if (prAdapter->fgIsStatValid == TRUE && -+ (kalGetTimeTick() - prAdapter->rStatUpdateTime) <= CFG_STATISTICS_VALID_CYCLE) -+ return TRUE; -+ else -+ return FALSE; -+} -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to query the supported physical layer network -+* type that can be used by the driver. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[out] pvQueryBuffer A pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufferLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryNetworkTypesSupported(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ UINT_32 u4NumItem = 0; -+ ENUM_PARAM_NETWORK_TYPE_T eSupportedNetworks[PARAM_NETWORK_TYPE_NUM]; -+ PPARAM_NETWORK_TYPE_LIST prSupported; -+ -+ /* The array of all physical layer network subtypes that the driver supports. */ -+ -+ DEBUGFUNC("wlanoidQueryNetworkTypesSupported"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4QueryInfoLen); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ -+ /* Init. */ -+ for (u4NumItem = 0; u4NumItem < PARAM_NETWORK_TYPE_NUM; u4NumItem++) -+ eSupportedNetworks[u4NumItem] = 0; -+ -+ u4NumItem = 0; -+ -+ eSupportedNetworks[u4NumItem] = PARAM_NETWORK_TYPE_DS; -+ u4NumItem++; -+ -+ eSupportedNetworks[u4NumItem] = PARAM_NETWORK_TYPE_OFDM24; -+ u4NumItem++; -+ -+ *pu4QueryInfoLen = -+ (UINT_32) OFFSET_OF(PARAM_NETWORK_TYPE_LIST, eNetworkType) + -+ (u4NumItem * sizeof(ENUM_PARAM_NETWORK_TYPE_T)); -+ -+ if (u4QueryBufferLen < *pu4QueryInfoLen) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ prSupported = (PPARAM_NETWORK_TYPE_LIST) pvQueryBuffer; -+ prSupported->NumberOfItems = u4NumItem; -+ kalMemCopy(prSupported->eNetworkType, eSupportedNetworks, u4NumItem * sizeof(ENUM_PARAM_NETWORK_TYPE_T)); -+ -+ DBGLOG(OID, TRACE, "NDIS supported network type list: %u\n", prSupported->NumberOfItems); -+ DBGLOG_MEM8(OID, TRACE, prSupported, *pu4QueryInfoLen); -+ -+ return WLAN_STATUS_SUCCESS; -+} /* wlanoidQueryNetworkTypesSupported */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to query the current physical layer network -+* type used by the driver. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[out] pvQueryBuffer A pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufferLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the -+* call failed due to invalid length of the query -+* buffer, returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_BUFFER_TOO_SHORT -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryNetworkTypeInUse(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ /* TODO: need to check the OID handler content again!! */ -+ -+ ENUM_PARAM_NETWORK_TYPE_T rCurrentNetworkTypeInUse = PARAM_NETWORK_TYPE_OFDM24; -+ -+ DEBUGFUNC("wlanoidQueryNetworkTypeInUse"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4QueryInfoLen); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ -+ if (u4QueryBufferLen < sizeof(ENUM_PARAM_NETWORK_TYPE_T)) { -+ *pu4QueryInfoLen = sizeof(ENUM_PARAM_NETWORK_TYPE_T); -+ return WLAN_STATUS_BUFFER_TOO_SHORT; -+ } -+ -+ if (kalGetMediaStateIndicated(prAdapter->prGlueInfo) == PARAM_MEDIA_STATE_CONNECTED) -+ rCurrentNetworkTypeInUse = (ENUM_PARAM_NETWORK_TYPE_T) (prAdapter->rWlanInfo.ucNetworkType); -+ else -+ rCurrentNetworkTypeInUse = (ENUM_PARAM_NETWORK_TYPE_T) (prAdapter->rWlanInfo.ucNetworkTypeInUse); -+ -+ *(P_ENUM_PARAM_NETWORK_TYPE_T) pvQueryBuffer = rCurrentNetworkTypeInUse; -+ *pu4QueryInfoLen = sizeof(ENUM_PARAM_NETWORK_TYPE_T); -+ -+ DBGLOG(OID, TRACE, "Network type in use: %d\n", rCurrentNetworkTypeInUse); -+ -+ return WLAN_STATUS_SUCCESS; -+} /* wlanoidQueryNetworkTypeInUse */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to set the physical layer network type used -+* by the driver. -+* -+* \param[in] pvAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns the -+* amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS The given network type is supported and accepted. -+* \retval WLAN_STATUS_INVALID_DATA The given network type is not in the -+* supported list. -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetNetworkTypeInUse(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ /* TODO: need to check the OID handler content again!! */ -+ -+ ENUM_PARAM_NETWORK_TYPE_T eNewNetworkType; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ -+ DEBUGFUNC("wlanoidSetNetworkTypeInUse"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pvSetBuffer); -+ ASSERT(pu4SetInfoLen); -+ -+ if (u4SetBufferLen < sizeof(ENUM_PARAM_NETWORK_TYPE_T)) { -+ *pu4SetInfoLen = sizeof(ENUM_PARAM_NETWORK_TYPE_T); -+ return WLAN_STATUS_INVALID_LENGTH; -+ } -+ -+ eNewNetworkType = *(P_ENUM_PARAM_NETWORK_TYPE_T) pvSetBuffer; -+ *pu4SetInfoLen = sizeof(ENUM_PARAM_NETWORK_TYPE_T); -+ -+ DBGLOG(OID, INFO, "New network type: %d mode\n", eNewNetworkType); -+ -+ switch (eNewNetworkType) { -+ -+ case PARAM_NETWORK_TYPE_DS: -+ prAdapter->rWlanInfo.ucNetworkTypeInUse = (UINT_8) PARAM_NETWORK_TYPE_DS; -+ break; -+ -+ case PARAM_NETWORK_TYPE_OFDM5: -+ prAdapter->rWlanInfo.ucNetworkTypeInUse = (UINT_8) PARAM_NETWORK_TYPE_OFDM5; -+ break; -+ -+ case PARAM_NETWORK_TYPE_OFDM24: -+ prAdapter->rWlanInfo.ucNetworkTypeInUse = (UINT_8) PARAM_NETWORK_TYPE_OFDM24; -+ break; -+ -+ case PARAM_NETWORK_TYPE_AUTOMODE: -+ prAdapter->rWlanInfo.ucNetworkTypeInUse = (UINT_8) PARAM_NETWORK_TYPE_AUTOMODE; -+ break; -+ -+ case PARAM_NETWORK_TYPE_FH: -+ DBGLOG(OID, INFO, "Not support network type: %d\n", eNewNetworkType); -+ rStatus = WLAN_STATUS_NOT_SUPPORTED; -+ break; -+ -+ default: -+ DBGLOG(OID, INFO, "Unknown network type: %d\n", eNewNetworkType); -+ rStatus = WLAN_STATUS_INVALID_DATA; -+ break; -+ } -+ -+ /* Verify if we support the new network type. */ -+ if (rStatus != WLAN_STATUS_SUCCESS) -+ DBGLOG(OID, WARN, "Unknown network type: %d\n", eNewNetworkType); -+ -+ return rStatus; -+} /* wlanoidSetNetworkTypeInUse */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to query the current BSSID. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[out] pvQueryBuffer A pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufferLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_ADAPTER_NOT_READY -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryBssid(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ -+ DEBUGFUNC("wlanoidQueryBssid"); -+ -+ ASSERT(prAdapter); -+ -+ if (u4QueryBufferLen < MAC_ADDR_LEN) { -+ ASSERT(pu4QueryInfoLen); -+ *pu4QueryInfoLen = MAC_ADDR_LEN; -+ return WLAN_STATUS_BUFFER_TOO_SHORT; -+ } -+ -+ ASSERT(u4QueryBufferLen >= MAC_ADDR_LEN); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ ASSERT(pu4QueryInfoLen); -+ -+ if (kalGetMediaStateIndicated(prAdapter->prGlueInfo) == PARAM_MEDIA_STATE_CONNECTED) -+ kalMemCopy(pvQueryBuffer, prAdapter->rWlanInfo.rCurrBssId.arMacAddress, MAC_ADDR_LEN); -+ else if (prAdapter->rWifiVar.rConnSettings.eOPMode == NET_TYPE_IBSS) { -+ PARAM_MAC_ADDRESS aucTemp; /*!< BSSID */ -+ -+ COPY_MAC_ADDR(aucTemp, prAdapter->rWlanInfo.rCurrBssId.arMacAddress); -+ aucTemp[0] &= ~BIT(0); -+ aucTemp[1] |= BIT(1); -+ COPY_MAC_ADDR(pvQueryBuffer, aucTemp); -+ } else -+ rStatus = WLAN_STATUS_ADAPTER_NOT_READY; -+ -+ *pu4QueryInfoLen = MAC_ADDR_LEN; -+ return rStatus; -+} /* wlanoidQueryBssid */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to query the list of all BSSIDs detected by -+* the driver. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[out] pvQueryBuffer A pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufferLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+* \retval WLAN_STATUS_ADAPTER_NOT_READY -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryBssidList(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ P_GLUE_INFO_T prGlueInfo; -+ UINT_32 i, u4BssidListExLen; -+ P_PARAM_BSSID_LIST_EX_T prList; -+ P_PARAM_BSSID_EX_T prBssidEx; -+ PUINT_8 cp; -+ -+ DEBUGFUNC("wlanoidQueryBssidList"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4QueryInfoLen); -+ -+ if (u4QueryBufferLen) { -+ ASSERT(pvQueryBuffer); -+ -+ if (!pvQueryBuffer) -+ return WLAN_STATUS_INVALID_DATA; -+ } -+ -+ prGlueInfo = prAdapter->prGlueInfo; -+ -+ if (prAdapter->rAcpiState == ACPI_STATE_D3) { -+ DBGLOG(OID, WARN, "Fail in qeury BSSID list! (Adapter not ready). ACPI=D%d, Radio=%d\n", -+ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); -+ return WLAN_STATUS_ADAPTER_NOT_READY; -+ } -+ -+ u4BssidListExLen = 0; -+ -+ if (prAdapter->fgIsRadioOff == FALSE) { -+ for (i = 0; i < prAdapter->rWlanInfo.u4ScanResultNum; i++) -+ u4BssidListExLen += ALIGN_4(prAdapter->rWlanInfo.arScanResult[i].u4Length); -+ } -+ -+ if (u4BssidListExLen) -+ u4BssidListExLen += 4; /* u4NumberOfItems. */ -+ else -+ u4BssidListExLen = sizeof(PARAM_BSSID_LIST_EX_T); -+ -+ *pu4QueryInfoLen = u4BssidListExLen; -+ -+ if (u4QueryBufferLen < *pu4QueryInfoLen) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ /* Clear the buffer */ -+ kalMemZero(pvQueryBuffer, u4BssidListExLen); -+ -+ prList = (P_PARAM_BSSID_LIST_EX_T) pvQueryBuffer; -+ cp = (PUINT_8) &prList->arBssid[0]; -+ -+ if (prAdapter->fgIsRadioOff == FALSE && prAdapter->rWlanInfo.u4ScanResultNum > 0) { -+ /* fill up for each entry */ -+ for (i = 0; i < prAdapter->rWlanInfo.u4ScanResultNum; i++) { -+ prBssidEx = (P_PARAM_BSSID_EX_T) cp; -+ -+ /* copy structure */ -+ kalMemCopy(prBssidEx, -+ &(prAdapter->rWlanInfo.arScanResult[i]), OFFSET_OF(PARAM_BSSID_EX_T, aucIEs)); -+ -+ /*For WHQL test, Rssi should be in range -10 ~ -200 dBm */ -+ if (prBssidEx->rRssi > PARAM_WHQL_RSSI_MAX_DBM) -+ prBssidEx->rRssi = PARAM_WHQL_RSSI_MAX_DBM; -+ -+ if (prAdapter->rWlanInfo.arScanResult[i].u4IELength > 0) { -+ /* copy IEs */ -+ kalMemCopy(prBssidEx->aucIEs, -+ prAdapter->rWlanInfo.apucScanResultIEs[i], -+ prAdapter->rWlanInfo.arScanResult[i].u4IELength); -+ } -+ /* 4-bytes alignement */ -+ prBssidEx->u4Length = ALIGN_4(prBssidEx->u4Length); -+ -+ cp += prBssidEx->u4Length; -+ prList->u4NumberOfItems++; -+ } -+ } -+ -+ return WLAN_STATUS_SUCCESS; -+} /* wlanoidQueryBssidList */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to request the driver to perform -+* scanning. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer Pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_ADAPTER_NOT_READY -+* \retval WLAN_STATUS_FAILURE -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetBssidListScan(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ P_PARAM_SSID_T prSsid; -+ PARAM_SSID_T rSsid; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ -+ DEBUGFUNC("wlanoidSetBssidListScan()"); -+ -+ if (prAdapter->rAcpiState == ACPI_STATE_D3) { -+ DBGLOG(OID, WARN, "Fail in set BSSID list scan! (Adapter not ready). ACPI=D%d, Radio=%d\n", -+ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); -+ return WLAN_STATUS_ADAPTER_NOT_READY; -+ } -+ -+ ASSERT(pu4SetInfoLen); -+ *pu4SetInfoLen = 0; -+ -+ if (prAdapter->fgIsRadioOff) { -+ DBGLOG(OID, WARN, "Return from BSSID list scan! (radio off). ACPI=D%d, Radio=%d\n", -+ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); -+ return WLAN_STATUS_SUCCESS; -+ } -+ -+ DBGLOG(OID, TRACE, "Scan\n"); -+ -+ if (pvSetBuffer != NULL && u4SetBufferLen != 0) { -+ COPY_SSID(rSsid.aucSsid, rSsid.u4SsidLen, pvSetBuffer, u4SetBufferLen); -+ prSsid = &rSsid; -+ } else { -+ prSsid = NULL; -+ } -+ -+#if CFG_SUPPORT_RDD_TEST_MODE -+ if (prAdapter->prGlueInfo->rRegInfo.u4RddTestMode) { -+ if ((prAdapter->fgEnOnlineScan == TRUE) && (prAdapter->ucRddStatus)) { -+ if (kalGetMediaStateIndicated(prAdapter->prGlueInfo) != PARAM_MEDIA_STATE_CONNECTED) { -+ aisFsmScanRequest(prAdapter, prSsid, NULL, 0); -+ } else { -+ /* reject the scan request */ -+ rStatus = WLAN_STATUS_FAILURE; -+ } -+ } else { -+ /* reject the scan request */ -+ rStatus = WLAN_STATUS_FAILURE; -+ } -+ } else -+#endif -+ { -+ if (prAdapter->fgEnOnlineScan == TRUE) { -+ aisFsmScanRequest(prAdapter, prSsid, NULL, 0); -+ } else if (kalGetMediaStateIndicated(prAdapter->prGlueInfo) != PARAM_MEDIA_STATE_CONNECTED) { -+ aisFsmScanRequest(prAdapter, prSsid, NULL, 0); -+ } else { -+ /* reject the scan request */ -+ rStatus = WLAN_STATUS_FAILURE; -+ } -+ } -+ -+ return rStatus; -+} /* wlanoidSetBssidListScan */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to request the driver to perform -+* scanning with attaching information elements(IEs) specified from user space -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer Pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_ADAPTER_NOT_READY -+* \retval WLAN_STATUS_FAILURE -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetBssidListScanExt(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ P_PARAM_SCAN_REQUEST_EXT_T prScanRequest; -+ P_AIS_FSM_INFO_T prAisFsmInfo; -+ P_PARAM_SSID_T prSsid; -+ PUINT_8 pucIe; -+ UINT_32 u4IeLength; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ UINT_8 ucScanTime = AIS_SCN_DONE_TIMEOUT_SEC; -+ -+ DEBUGFUNC("wlanoidSetBssidListScanExt()"); -+ -+ if (prAdapter->rAcpiState == ACPI_STATE_D3) { -+ DBGLOG(OID, ERROR, "Fail in set BSSID list scan! (Adapter not ready). ACPI=D%d, Radio=%d\n", -+ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); -+ return WLAN_STATUS_ADAPTER_NOT_READY; -+ } else if (prAdapter->fgTestMode) { -+ DBGLOG(OID, WARN, "didn't support Scan in test mode\n"); -+ return WLAN_STATUS_FAILURE; -+ } -+ -+ ASSERT(pu4SetInfoLen); -+ *pu4SetInfoLen = 0; -+ -+ if (u4SetBufferLen != sizeof(PARAM_SCAN_REQUEST_EXT_T)) { -+ DBGLOG(OID, ERROR, "u4SetBufferLen != sizeof(PARAM_SCAN_REQUEST_EXT_T)\n"); -+ return WLAN_STATUS_INVALID_LENGTH; -+ } -+ -+ if (prAdapter->fgIsRadioOff) { -+ DBGLOG(OID, INFO, "Return from BSSID list scan! (radio off). ACPI=D%d, Radio=%d\n", -+ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); -+ return WLAN_STATUS_SUCCESS; -+ } -+ -+ DBGLOG(OID, TRACE, "ScanEx\n"); -+ -+ /* clear old scan backup results if exists */ -+ { -+ P_SCAN_INFO_T prScanInfo; -+ P_LINK_T prBSSDescList; -+ P_BSS_DESC_T prBssDesc; -+ -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ prBSSDescList = &prScanInfo->rBSSDescList; -+ LINK_FOR_EACH_ENTRY(prBssDesc, prBSSDescList, rLinkEntry, BSS_DESC_T) { -+ if (prBssDesc->eBSSType == BSS_TYPE_INFRASTRUCTURE) { -+ kalMemZero(prBssDesc->aucRawBuf, CFG_RAW_BUFFER_SIZE); -+ prBssDesc->u2RawLength = 0; -+ } -+ } -+ } -+ -+ if (pvSetBuffer != NULL && u4SetBufferLen != 0) { -+ prScanRequest = (P_PARAM_SCAN_REQUEST_EXT_T) pvSetBuffer; -+ prSsid = &(prScanRequest->rSsid); -+ pucIe = prScanRequest->pucIE; -+ u4IeLength = prScanRequest->u4IELength; -+ } else { -+ prScanRequest = NULL; -+ prSsid = NULL; -+ pucIe = NULL; -+ u4IeLength = 0; -+ } -+ -+/* P_AIS_FSM_INFO_T prAisFsmInfo; */ -+ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); -+ -+/* #if CFG_SUPPORT_WFD */ -+#if 0 -+ if ((prAdapter->rWifiVar.prP2pFsmInfo->rWfdConfigureSettings.ucWfdEnable) && -+ ((prAdapter->rWifiVar.prP2pFsmInfo->rWfdConfigureSettings.u4WfdFlag & WFD_FLAGS_DEV_INFO_VALID))) { -+ -+ if (prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX].eConnectionState == -+ PARAM_MEDIA_STATE_CONNECTED) { -+ DBGLOG(OID, TRACE, "Twice the Scan Time for WFD\n"); -+ ucScanTime *= 2; -+ } -+ } -+#endif /* CFG_SUPPORT_WFD */ -+ cnmTimerStartTimer(prAdapter, &prAisFsmInfo->rScanDoneTimer, SEC_TO_MSEC(ucScanTime)); -+ -+#if CFG_SUPPORT_RDD_TEST_MODE -+ if (prAdapter->prGlueInfo->rRegInfo.u4RddTestMode) { -+ if ((prAdapter->fgEnOnlineScan == TRUE) && (prAdapter->ucRddStatus)) { -+ if (kalGetMediaStateIndicated(prAdapter->prGlueInfo) != PARAM_MEDIA_STATE_CONNECTED) { -+ aisFsmScanRequest(prAdapter, prSsid, pucIe, u4IeLength); -+ } else { -+ /* reject the scan request */ -+ cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rScanDoneTimer); -+ rStatus = WLAN_STATUS_FAILURE; -+ } -+ } else { -+ /* reject the scan request */ -+ cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rScanDoneTimer); -+ rStatus = WLAN_STATUS_FAILURE; -+ } -+ } else -+#endif -+ { -+ if (prAdapter->fgEnOnlineScan == TRUE) { -+ aisFsmScanRequest(prAdapter, prSsid, pucIe, u4IeLength); -+ } else if (kalGetMediaStateIndicated(prAdapter->prGlueInfo) != PARAM_MEDIA_STATE_CONNECTED) { -+ aisFsmScanRequest(prAdapter, prSsid, pucIe, u4IeLength); -+ } else { -+ /* reject the scan request */ -+ cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rScanDoneTimer); -+ rStatus = WLAN_STATUS_FAILURE; -+ DBGLOG(OID, WARN, "ScanEx fail %d!\n", prAdapter->fgEnOnlineScan); -+ } -+ } -+ -+ return rStatus; -+} /* wlanoidSetBssidListScanWithIE */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine will initiate the join procedure to attempt to associate -+* with the specified BSSID. -+* -+* \param[in] pvAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+* \retval WLAN_STATUS_INVALID_DATA -+* \retval WLAN_STATUS_ADAPTER_NOT_READY -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetBssid(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ P_GLUE_INFO_T prGlueInfo; -+ P_UINT_8 pAddr; -+ UINT_32 i; -+ INT_32 i4Idx = -1; -+ P_MSG_AIS_ABORT_T prAisAbortMsg; -+ UINT_8 ucReasonOfDisconnect; -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ *pu4SetInfoLen = MAC_ADDR_LEN; -+ if (u4SetBufferLen != MAC_ADDR_LEN) { -+ *pu4SetInfoLen = MAC_ADDR_LEN; -+ return WLAN_STATUS_INVALID_LENGTH; -+ } else if (prAdapter->rAcpiState == ACPI_STATE_D3) { -+ DBGLOG(OID, WARN, "Fail in set ssid! (Adapter not ready). ACPI=D%d, Radio=%d\n", -+ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); -+ return WLAN_STATUS_ADAPTER_NOT_READY; -+ } -+ -+ prGlueInfo = prAdapter->prGlueInfo; -+ pAddr = (P_UINT_8) pvSetBuffer; -+ -+ /* re-association check */ -+ if (kalGetMediaStateIndicated(prGlueInfo) == PARAM_MEDIA_STATE_CONNECTED) { -+ if (EQUAL_MAC_ADDR(prAdapter->rWlanInfo.rCurrBssId.arMacAddress, pAddr)) { -+ kalSetMediaStateIndicated(prGlueInfo, PARAM_MEDIA_STATE_TO_BE_INDICATED); -+ ucReasonOfDisconnect = DISCONNECT_REASON_CODE_REASSOCIATION; -+ } else { -+ DBGLOG(OID, TRACE, "DisByBssid\n"); -+ kalIndicateStatusAndComplete(prGlueInfo, WLAN_STATUS_MEDIA_DISCONNECT, NULL, 0); -+ ucReasonOfDisconnect = DISCONNECT_REASON_CODE_NEW_CONNECTION; -+ } -+ } else { -+ ucReasonOfDisconnect = DISCONNECT_REASON_CODE_NEW_CONNECTION; -+ } -+ -+ /* check if any scanned result matchs with the BSSID */ -+ for (i = 0; i < prAdapter->rWlanInfo.u4ScanResultNum; i++) { -+ if (EQUAL_MAC_ADDR(prAdapter->rWlanInfo.arScanResult[i].arMacAddress, pAddr)) { -+ i4Idx = (INT_32) i; -+ break; -+ } -+ } -+ -+ /* prepare message to AIS */ -+ if (prAdapter->rWifiVar.rConnSettings.eOPMode == NET_TYPE_IBSS -+ || prAdapter->rWifiVar.rConnSettings.eOPMode == NET_TYPE_DEDICATED_IBSS) { -+ /* IBSS *//* beacon period */ -+ prAdapter->rWifiVar.rConnSettings.u2BeaconPeriod = prAdapter->rWlanInfo.u2BeaconPeriod; -+ prAdapter->rWifiVar.rConnSettings.u2AtimWindow = prAdapter->rWlanInfo.u2AtimWindow; -+ } -+ -+ /* Set Connection Request Issued Flag */ -+ prAdapter->rWifiVar.rConnSettings.fgIsConnReqIssued = TRUE; -+ prAdapter->rWifiVar.rConnSettings.eConnectionPolicy = CONNECT_BY_BSSID; -+ -+ /* Send AIS Abort Message */ -+ prAisAbortMsg = (P_MSG_AIS_ABORT_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_AIS_ABORT_T)); -+ if (!prAisAbortMsg) { -+ ASSERT(0); -+ return WLAN_STATUS_FAILURE; -+ } -+ -+ prAisAbortMsg->rMsgHdr.eMsgId = MID_OID_AIS_FSM_JOIN_REQ; -+ prAisAbortMsg->ucReasonOfDisconnect = ucReasonOfDisconnect; -+ -+ /* Update the information to CONNECTION_SETTINGS_T */ -+ prAdapter->rWifiVar.rConnSettings.ucSSIDLen = 0; -+ prAdapter->rWifiVar.rConnSettings.aucSSID[0] = '\0'; -+ -+ COPY_MAC_ADDR(prAdapter->rWifiVar.rConnSettings.aucBSSID, pAddr); -+ -+ if (EQUAL_MAC_ADDR(prAdapter->rWlanInfo.rCurrBssId.arMacAddress, pAddr)) -+ prAisAbortMsg->fgDelayIndication = TRUE; -+ else -+ prAisAbortMsg->fgDelayIndication = FALSE; -+ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prAisAbortMsg, MSG_SEND_METHOD_BUF); -+ -+ DBGLOG(OID, INFO, "SetBssid\n"); -+ return WLAN_STATUS_SUCCESS; -+} /* end of wlanoidSetBssid() */ -+ -+WLAN_STATUS -+wlanoidSetConnect(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ P_GLUE_INFO_T prGlueInfo; -+ P_PARAM_CONNECT_T pParamConn; -+ P_CONNECTION_SETTINGS_T prConnSettings; -+ UINT_32 i; -+ /*INT_32 i4Idx = -1, i4MaxRSSI = INT_MIN;*/ -+ P_MSG_AIS_ABORT_T prAisAbortMsg; -+ BOOLEAN fgIsValidSsid = TRUE; -+ BOOLEAN fgEqualSsid = FALSE; -+ BOOLEAN fgEqualBssid = FALSE; -+ const UINT_8 aucZeroMacAddr[] = NULL_MAC_ADDR; -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ /* MSDN: -+ * Powering on the radio if the radio is powered off through a setting of OID_802_11_DISASSOCIATE -+ */ -+ if (prAdapter->fgIsRadioOff == TRUE) -+ prAdapter->fgIsRadioOff = FALSE; -+ -+ if (u4SetBufferLen != sizeof(PARAM_CONNECT_T)) -+ return WLAN_STATUS_INVALID_LENGTH; -+ else if (prAdapter->rAcpiState == ACPI_STATE_D3) { -+ DBGLOG(OID, WARN, "Fail in set ssid! (Adapter not ready). ACPI=D%d, Radio=%d\n", -+ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); -+ return WLAN_STATUS_ADAPTER_NOT_READY; -+ } -+ prAisAbortMsg = (P_MSG_AIS_ABORT_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_AIS_ABORT_T)); -+ if (!prAisAbortMsg) { -+ ASSERT(0); -+ return WLAN_STATUS_FAILURE; -+ } -+ prAisAbortMsg->rMsgHdr.eMsgId = MID_OID_AIS_FSM_JOIN_REQ; -+ -+ pParamConn = (P_PARAM_CONNECT_T) pvSetBuffer; -+ prConnSettings = &prAdapter->rWifiVar.rConnSettings; -+ -+ if (pParamConn->u4SsidLen > 32) { -+ cnmMemFree(prAdapter, prAisAbortMsg); -+ return WLAN_STATUS_INVALID_LENGTH; -+ } else if (!pParamConn->pucBssid && !pParamConn->pucSsid) { -+ cnmMemFree(prAdapter, prAisAbortMsg); -+ return WLAN_STATUS_INVALID_LENGTH; -+ } -+ -+ prGlueInfo = prAdapter->prGlueInfo; -+ kalMemZero(prConnSettings->aucSSID, sizeof(prConnSettings->aucSSID)); -+ kalMemZero(prConnSettings->aucBSSID, sizeof(prConnSettings->aucBSSID)); -+ prConnSettings->eConnectionPolicy = CONNECT_BY_SSID_ANY; -+ prConnSettings->fgIsConnByBssidIssued = FALSE; -+ -+ if (pParamConn->pucSsid) { -+ prConnSettings->eConnectionPolicy = CONNECT_BY_SSID_BEST_RSSI; -+ COPY_SSID(prConnSettings->aucSSID, -+ prConnSettings->ucSSIDLen, pParamConn->pucSsid, (UINT_8) pParamConn->u4SsidLen); -+ if (EQUAL_SSID(prAdapter->rWlanInfo.rCurrBssId.rSsid.aucSsid, -+ prAdapter->rWlanInfo.rCurrBssId.rSsid.u4SsidLen, -+ pParamConn->pucSsid, pParamConn->u4SsidLen)) -+ fgEqualSsid = TRUE; -+ } -+ if (pParamConn->pucBssid) { -+ if (!EQUAL_MAC_ADDR(aucZeroMacAddr, pParamConn->pucBssid) && IS_UCAST_MAC_ADDR(pParamConn->pucBssid)) { -+ prConnSettings->eConnectionPolicy = CONNECT_BY_BSSID; -+ prConnSettings->fgIsConnByBssidIssued = TRUE; -+ COPY_MAC_ADDR(prConnSettings->aucBSSID, pParamConn->pucBssid); -+ if (EQUAL_MAC_ADDR(prAdapter->rWlanInfo.rCurrBssId.arMacAddress, pParamConn->pucBssid)) -+ fgEqualBssid = TRUE; -+ } else -+ DBGLOG(OID, TRACE, "wrong bssid %pM to connect\n", pParamConn->pucBssid); -+ } else -+ DBGLOG(OID, TRACE, "No Bssid set\n"); -+ prConnSettings->u4FreqInKHz = pParamConn->u4CenterFreq; -+ -+ /* prepare for CMD_BUILD_CONNECTION & CMD_GET_CONNECTION_STATUS */ -+ /* re-association check */ -+ if (kalGetMediaStateIndicated(prGlueInfo) == PARAM_MEDIA_STATE_CONNECTED) { -+ if (fgEqualSsid) { -+ prAisAbortMsg->ucReasonOfDisconnect = DISCONNECT_REASON_CODE_ROAMING; -+ if (fgEqualBssid) { -+ kalSetMediaStateIndicated(prGlueInfo, PARAM_MEDIA_STATE_TO_BE_INDICATED); -+ prAisAbortMsg->ucReasonOfDisconnect = DISCONNECT_REASON_CODE_REASSOCIATION; -+ } -+ } else { -+ DBGLOG(OID, TRACE, "DisBySsid\n"); -+ kalIndicateStatusAndComplete(prGlueInfo, WLAN_STATUS_MEDIA_DISCONNECT, NULL, 0); -+ prAisAbortMsg->ucReasonOfDisconnect = DISCONNECT_REASON_CODE_NEW_CONNECTION; -+ } -+ } else -+ prAisAbortMsg->ucReasonOfDisconnect = DISCONNECT_REASON_CODE_NEW_CONNECTION; -+#if 0 -+ /* check if any scanned result matchs with the SSID */ -+ for (i = 0; i < prAdapter->rWlanInfo.u4ScanResultNum; i++) { -+ PUINT_8 aucSsid = prAdapter->rWlanInfo.arScanResult[i].rSsid.aucSsid; -+ UINT_8 ucSsidLength = (UINT_8) prAdapter->rWlanInfo.arScanResult[i].rSsid.u4SsidLen; -+ INT_32 i4RSSI = prAdapter->rWlanInfo.arScanResult[i].rRssi; -+ -+ if (EQUAL_SSID(aucSsid, ucSsidLength, pParamConn->pucSsid, pParamConn->u4SsidLen) && -+ i4RSSI >= i4MaxRSSI) { -+ i4Idx = (INT_32) i; -+ i4MaxRSSI = i4RSSI; -+ } -+ if (EQUAL_MAC_ADDR(prAdapter->rWlanInfo.arScanResult[i].arMacAddress, pAddr)) { -+ i4Idx = (INT_32) i; -+ break; -+ } -+ } -+#endif -+ /* prepare message to AIS */ -+ if (prConnSettings->eOPMode == NET_TYPE_IBSS || prConnSettings->eOPMode == NET_TYPE_DEDICATED_IBSS) { -+ /* IBSS *//* beacon period */ -+ prConnSettings->u2BeaconPeriod = prAdapter->rWlanInfo.u2BeaconPeriod; -+ prConnSettings->u2AtimWindow = prAdapter->rWlanInfo.u2AtimWindow; -+ } -+ -+ if (prAdapter->rWifiVar.fgSupportWZCDisassociation) { -+ if (pParamConn->u4SsidLen == ELEM_MAX_LEN_SSID) { -+ fgIsValidSsid = FALSE; -+ -+ for (i = 0; i < ELEM_MAX_LEN_SSID; i++) { -+ if (pParamConn->pucSsid) { -+ if (!((0 < pParamConn->pucSsid[i]) && (pParamConn->pucSsid[i] <= 0x1F))) { -+ fgIsValidSsid = TRUE; -+ break; -+ } -+ } -+ } -+ } -+ } -+ -+ /* Set Connection Request Issued Flag */ -+ if (fgIsValidSsid) -+ prConnSettings->fgIsConnReqIssued = TRUE; -+ else -+ prConnSettings->fgIsConnReqIssued = FALSE; -+ -+ if (fgEqualSsid || fgEqualBssid) -+ prAisAbortMsg->fgDelayIndication = TRUE; -+ else -+ /* Update the information to CONNECTION_SETTINGS_T */ -+ prAisAbortMsg->fgDelayIndication = FALSE; -+ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prAisAbortMsg, MSG_SEND_METHOD_BUF); -+ -+ DBGLOG(OID, INFO, "ssid %s, bssid %pM, conn policy %d, disc reason %d\n", -+ prConnSettings->aucSSID, prConnSettings->aucBSSID, -+ prConnSettings->eConnectionPolicy, prAisAbortMsg->ucReasonOfDisconnect); -+ return WLAN_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine will initiate the join procedure to attempt -+* to associate with the new SSID. If the previous scanning -+* result is aged, we will scan the channels at first. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer Pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_DATA -+* \retval WLAN_STATUS_ADAPTER_NOT_READY -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetSsid(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ P_GLUE_INFO_T prGlueInfo; -+ P_PARAM_SSID_T pParamSsid; -+ UINT_32 i; -+ INT_32 i4Idx = -1, i4MaxRSSI = INT_MIN; -+ P_MSG_AIS_ABORT_T prAisAbortMsg; -+ BOOLEAN fgIsValidSsid = TRUE; -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ /* MSDN: -+ * Powering on the radio if the radio is powered off through a setting of OID_802_11_DISASSOCIATE -+ */ -+ if (prAdapter->fgIsRadioOff == TRUE) -+ prAdapter->fgIsRadioOff = FALSE; -+ -+ if (u4SetBufferLen < sizeof(PARAM_SSID_T) || u4SetBufferLen > sizeof(PARAM_SSID_T)) { -+ return WLAN_STATUS_INVALID_LENGTH; -+ } else if (prAdapter->rAcpiState == ACPI_STATE_D3) { -+ DBGLOG(OID, WARN, "Fail in set ssid! (Adapter not ready). ACPI=D%d, Radio=%d\n", -+ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); -+ return WLAN_STATUS_ADAPTER_NOT_READY; -+ } -+ -+ pParamSsid = (P_PARAM_SSID_T) pvSetBuffer; -+ -+ if (pParamSsid->u4SsidLen > 32) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ prGlueInfo = prAdapter->prGlueInfo; -+ -+ /* prepare for CMD_BUILD_CONNECTION & CMD_GET_CONNECTION_STATUS */ -+ /* re-association check */ -+ if (kalGetMediaStateIndicated(prGlueInfo) == PARAM_MEDIA_STATE_CONNECTED) { -+ if (EQUAL_SSID(prAdapter->rWlanInfo.rCurrBssId.rSsid.aucSsid, -+ prAdapter->rWlanInfo.rCurrBssId.rSsid.u4SsidLen, -+ pParamSsid->aucSsid, pParamSsid->u4SsidLen)) { -+ kalSetMediaStateIndicated(prGlueInfo, PARAM_MEDIA_STATE_TO_BE_INDICATED); -+ } else { -+ DBGLOG(OID, TRACE, "DisBySsid\n"); -+ kalIndicateStatusAndComplete(prGlueInfo, WLAN_STATUS_MEDIA_DISCONNECT, NULL, 0); -+ } -+ } -+ /* check if any scanned result matchs with the SSID */ -+ for (i = 0; i < prAdapter->rWlanInfo.u4ScanResultNum; i++) { -+ PUINT_8 aucSsid = prAdapter->rWlanInfo.arScanResult[i].rSsid.aucSsid; -+ UINT_8 ucSsidLength = (UINT_8) prAdapter->rWlanInfo.arScanResult[i].rSsid.u4SsidLen; -+ INT_32 i4RSSI = prAdapter->rWlanInfo.arScanResult[i].rRssi; -+ -+ if (EQUAL_SSID(aucSsid, ucSsidLength, pParamSsid->aucSsid, pParamSsid->u4SsidLen) && -+ i4RSSI >= i4MaxRSSI) { -+ i4Idx = (INT_32) i; -+ i4MaxRSSI = i4RSSI; -+ } -+ } -+ -+ /* prepare message to AIS */ -+ if (prAdapter->rWifiVar.rConnSettings.eOPMode == NET_TYPE_IBSS -+ || prAdapter->rWifiVar.rConnSettings.eOPMode == NET_TYPE_DEDICATED_IBSS) { -+ /* IBSS *//* beacon period */ -+ prAdapter->rWifiVar.rConnSettings.u2BeaconPeriod = prAdapter->rWlanInfo.u2BeaconPeriod; -+ prAdapter->rWifiVar.rConnSettings.u2AtimWindow = prAdapter->rWlanInfo.u2AtimWindow; -+ } -+ -+ if (prAdapter->rWifiVar.fgSupportWZCDisassociation) { -+ if (pParamSsid->u4SsidLen == ELEM_MAX_LEN_SSID) { -+ fgIsValidSsid = FALSE; -+ -+ for (i = 0; i < ELEM_MAX_LEN_SSID; i++) { -+ if (!((0 < pParamSsid->aucSsid[i]) && (pParamSsid->aucSsid[i] <= 0x1F))) { -+ fgIsValidSsid = TRUE; -+ break; -+ } -+ } -+ } -+ } -+ -+ /* Set Connection Request Issued Flag */ -+ if (fgIsValidSsid) { -+ prAdapter->rWifiVar.rConnSettings.fgIsConnReqIssued = TRUE; -+ -+ if (pParamSsid->u4SsidLen) { -+ prAdapter->rWifiVar.rConnSettings.eConnectionPolicy = CONNECT_BY_SSID_BEST_RSSI; -+ } else { -+ /* wildcard SSID */ -+ prAdapter->rWifiVar.rConnSettings.eConnectionPolicy = CONNECT_BY_SSID_ANY; -+ } -+ } else { -+ prAdapter->rWifiVar.rConnSettings.fgIsConnReqIssued = FALSE; -+ } -+ -+ /* Send AIS Abort Message */ -+ prAisAbortMsg = (P_MSG_AIS_ABORT_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_AIS_ABORT_T)); -+ if (!prAisAbortMsg) { -+ ASSERT(0); -+ return WLAN_STATUS_FAILURE; -+ } -+ -+ prAisAbortMsg->rMsgHdr.eMsgId = MID_OID_AIS_FSM_JOIN_REQ; -+ prAisAbortMsg->ucReasonOfDisconnect = DISCONNECT_REASON_CODE_NEW_CONNECTION; -+ -+ COPY_SSID(prAdapter->rWifiVar.rConnSettings.aucSSID, -+ prAdapter->rWifiVar.rConnSettings.ucSSIDLen, pParamSsid->aucSsid, (UINT_8) pParamSsid->u4SsidLen); -+ -+ prAdapter->rWifiVar.rConnSettings.u4FreqInKHz = pParamSsid->u4CenterFreq; -+ if (EQUAL_SSID(prAdapter->rWlanInfo.rCurrBssId.rSsid.aucSsid, -+ prAdapter->rWlanInfo.rCurrBssId.rSsid.u4SsidLen, pParamSsid->aucSsid, pParamSsid->u4SsidLen)) { -+ prAisAbortMsg->fgDelayIndication = TRUE; -+ } else { -+ /* Update the information to CONNECTION_SETTINGS_T */ -+ prAisAbortMsg->fgDelayIndication = FALSE; -+ } -+ DBGLOG(SCN, INFO, "SSID %s\n", prAdapter->rWifiVar.rConnSettings.aucSSID); -+ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prAisAbortMsg, MSG_SEND_METHOD_BUF); -+ -+ return WLAN_STATUS_SUCCESS; -+ -+} /* end of wlanoidSetSsid() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to query the currently associated SSID. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvQueryBuffer Pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufferLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQuerySsid(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ P_PARAM_SSID_T prAssociatedSsid; -+ -+ DEBUGFUNC("wlanoidQuerySsid"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4QueryInfoLen); -+ -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ -+ *pu4QueryInfoLen = sizeof(PARAM_SSID_T); -+ -+ /* Check for query buffer length */ -+ if (u4QueryBufferLen < *pu4QueryInfoLen) { -+ DBGLOG(OID, WARN, "Invalid length %u\n", u4QueryBufferLen); -+ return WLAN_STATUS_INVALID_LENGTH; -+ } -+ -+ prAssociatedSsid = (P_PARAM_SSID_T) pvQueryBuffer; -+ -+ kalMemZero(prAssociatedSsid->aucSsid, sizeof(prAssociatedSsid->aucSsid)); -+ -+ if (kalGetMediaStateIndicated(prAdapter->prGlueInfo) == PARAM_MEDIA_STATE_CONNECTED) { -+ prAssociatedSsid->u4SsidLen = prAdapter->rWlanInfo.rCurrBssId.rSsid.u4SsidLen; -+ -+ if (prAssociatedSsid->u4SsidLen) { -+ kalMemCopy(prAssociatedSsid->aucSsid, -+ prAdapter->rWlanInfo.rCurrBssId.rSsid.aucSsid, prAssociatedSsid->u4SsidLen); -+ } -+ } else { -+ prAssociatedSsid->u4SsidLen = 0; -+ -+ DBGLOG(OID, TRACE, "Null SSID\n"); -+ } -+ -+ return WLAN_STATUS_SUCCESS; -+} /* wlanoidQuerySsid */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to query the current 802.11 network type. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvQueryBuffer Pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufferLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_BUFFER_TOO_SHORT -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryInfrastructureMode(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ DEBUGFUNC("wlanoidQueryInfrastructureMode"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4QueryInfoLen); -+ -+ *pu4QueryInfoLen = sizeof(ENUM_PARAM_OP_MODE_T); -+ -+ if (u4QueryBufferLen < sizeof(ENUM_PARAM_OP_MODE_T)) -+ return WLAN_STATUS_BUFFER_TOO_SHORT; -+ -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ -+ *(P_ENUM_PARAM_OP_MODE_T) pvQueryBuffer = prAdapter->rWifiVar.rConnSettings.eOPMode; -+ -+ /* -+ ** According to OID_802_11_INFRASTRUCTURE_MODE -+ ** If there is no prior OID_802_11_INFRASTRUCTURE_MODE, -+ ** NDIS_STATUS_ADAPTER_NOT_READY shall be returned. -+ */ -+#if DBG -+ switch (*(P_ENUM_PARAM_OP_MODE_T) pvQueryBuffer) { -+ case NET_TYPE_IBSS: -+ DBGLOG(OID, INFO, "IBSS mode\n"); -+ break; -+ case NET_TYPE_INFRA: -+ DBGLOG(OID, INFO, "Infrastructure mode\n"); -+ break; -+ default: -+ DBGLOG(OID, INFO, "Automatic mode\n"); -+ } -+#endif -+ -+ return WLAN_STATUS_SUCCESS; -+} /* wlanoidQueryInfrastructureMode */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to set mode to infrastructure or -+* IBSS, or automatic switch between the two. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer Pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed due to invalid -+* length of the set buffer, returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_DATA -+* \retval WLAN_STATUS_ADAPTER_NOT_READY -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetInfrastructureMode(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ P_GLUE_INFO_T prGlueInfo; -+ ENUM_PARAM_OP_MODE_T eOpMode; -+ -+ DEBUGFUNC("wlanoidSetInfrastructureMode"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pvSetBuffer); -+ ASSERT(pu4SetInfoLen); -+ -+ prGlueInfo = prAdapter->prGlueInfo; -+ -+ if (u4SetBufferLen < sizeof(ENUM_PARAM_OP_MODE_T)) -+ return WLAN_STATUS_BUFFER_TOO_SHORT; -+ -+ *pu4SetInfoLen = sizeof(ENUM_PARAM_OP_MODE_T); -+ -+ if (prAdapter->rAcpiState == ACPI_STATE_D3) { -+ DBGLOG(OID, WARN, "Fail in set infrastructure mode! (Adapter not ready). ACPI=D%d, Radio=%d\n", -+ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); -+ return WLAN_STATUS_ADAPTER_NOT_READY; -+ } -+ -+ eOpMode = *(P_ENUM_PARAM_OP_MODE_T) pvSetBuffer; -+ /* Verify the new infrastructure mode. */ -+ if (eOpMode >= NET_TYPE_NUM) { -+ DBGLOG(OID, TRACE, "Invalid mode value %d\n", eOpMode); -+ return WLAN_STATUS_INVALID_DATA; -+ } -+ -+ /* check if possible to switch to AdHoc mode */ -+ if (eOpMode == NET_TYPE_IBSS || eOpMode == NET_TYPE_DEDICATED_IBSS) { -+ if (cnmAisIbssIsPermitted(prAdapter) == FALSE) { -+ DBGLOG(OID, TRACE, "Mode value %d unallowed\n", eOpMode); -+ return WLAN_STATUS_FAILURE; -+ } -+ } -+ -+ /* Save the new infrastructure mode setting. */ -+ prAdapter->rWifiVar.rConnSettings.eOPMode = eOpMode; -+ -+ /* Clean up the Tx key flag */ -+ prAdapter->rWifiVar.rAisSpecificBssInfo.fgTransmitKeyExist = FALSE; -+ -+ prAdapter->rWifiVar.rConnSettings.fgWapiMode = FALSE; -+#if CFG_SUPPORT_WAPI -+ prAdapter->prGlueInfo->u2WapiAssocInfoIESz = 0; -+ kalMemZero(&prAdapter->prGlueInfo->aucWapiAssocInfoIEs, 42); -+#endif -+ -+#if CFG_SUPPORT_802_11W -+ prAdapter->rWifiVar.rAisSpecificBssInfo.fgMgmtProtection = FALSE; -+ prAdapter->rWifiVar.rAisSpecificBssInfo.fgBipKeyInstalled = FALSE; -+#endif -+ -+#if CFG_SUPPORT_WPS2 -+ kalMemZero(&prAdapter->prGlueInfo->aucWSCAssocInfoIE, 200); -+ prAdapter->prGlueInfo->u2WSCAssocInfoIELen = 0; -+#endif -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_INFRASTRUCTURE, -+ TRUE, -+ FALSE, -+ TRUE, -+ nicCmdEventSetCommon, nicOidCmdTimeoutCommon, 0, NULL, pvSetBuffer, u4SetBufferLen); -+ -+} /* wlanoidSetInfrastructureMode */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to query the current 802.11 authentication -+* mode. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[out] pvQueryBuffer A pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufferLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_BUFFER_TOO_SHORT -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryAuthMode(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ DEBUGFUNC("wlanoidQueryAuthMode"); -+ -+ ASSERT(prAdapter); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ ASSERT(pu4QueryInfoLen); -+ -+ *pu4QueryInfoLen = sizeof(ENUM_PARAM_AUTH_MODE_T); -+ -+ if (u4QueryBufferLen < sizeof(ENUM_PARAM_AUTH_MODE_T)) -+ return WLAN_STATUS_BUFFER_TOO_SHORT; -+ -+ *(P_ENUM_PARAM_AUTH_MODE_T) pvQueryBuffer = prAdapter->rWifiVar.rConnSettings.eAuthMode; -+ -+#if DBG -+ switch (*(P_ENUM_PARAM_AUTH_MODE_T) pvQueryBuffer) { -+ case AUTH_MODE_OPEN: -+ DBGLOG(OID, INFO, "Current auth mode: Open\n"); -+ break; -+ -+ case AUTH_MODE_SHARED: -+ DBGLOG(OID, INFO, "Current auth mode: Shared\n"); -+ break; -+ -+ case AUTH_MODE_AUTO_SWITCH: -+ DBGLOG(OID, INFO, "Current auth mode: Auto-switch\n"); -+ break; -+ -+ case AUTH_MODE_WPA: -+ DBGLOG(OID, INFO, "Current auth mode: WPA\n"); -+ break; -+ -+ case AUTH_MODE_WPA_PSK: -+ DBGLOG(OID, INFO, "Current auth mode: WPA PSK\n"); -+ break; -+ -+ case AUTH_MODE_WPA_NONE: -+ DBGLOG(OID, INFO, "Current auth mode: WPA None\n"); -+ break; -+ -+ case AUTH_MODE_WPA2: -+ DBGLOG(OID, INFO, "Current auth mode: WPA2\n"); -+ break; -+ -+ case AUTH_MODE_WPA2_PSK: -+ DBGLOG(OID, INFO, "Current auth mode: WPA2 PSK\n"); -+ break; -+ -+ default: -+ DBGLOG(OID, INFO, "Current auth mode: %d\n", *(P_ENUM_PARAM_AUTH_MODE_T) pvQueryBuffer); -+ break; -+ } -+#endif -+ return WLAN_STATUS_SUCCESS; -+} /* wlanoidQueryAuthMode */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to set the IEEE 802.11 authentication mode -+* to the driver. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_DATA -+* \retval WLAN_STATUS_INVALID_LENGTH -+* \retval WLAN_STATUS_ADAPTER_NOT_READY -+* \retval WLAN_STATUS_NOT_ACCEPTED -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetAuthMode(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ P_GLUE_INFO_T prGlueInfo; -+ UINT_32 i, u4AkmSuite; -+ P_DOT11_RSNA_CONFIG_AUTHENTICATION_SUITES_ENTRY prEntry; -+ -+ DEBUGFUNC("wlanoidSetAuthMode"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ ASSERT(pvSetBuffer); -+ -+ prGlueInfo = prAdapter->prGlueInfo; -+ -+ *pu4SetInfoLen = sizeof(ENUM_PARAM_AUTH_MODE_T); -+ -+ if (u4SetBufferLen < sizeof(ENUM_PARAM_AUTH_MODE_T)) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ /* RF Test */ -+ /* if (IS_ARB_IN_RFTEST_STATE(prAdapter)) { */ -+ /* return WLAN_STATUS_SUCCESS; */ -+ /* } */ -+ -+ if (prAdapter->rAcpiState == ACPI_STATE_D3) { -+ DBGLOG(OID, WARN, "Fail in set Authentication mode! (Adapter not ready). ACPI=D%d, Radio=%d\n", -+ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); -+ return WLAN_STATUS_ADAPTER_NOT_READY; -+ } -+ -+ /* Check if the new authentication mode is valid. */ -+ if (*(P_ENUM_PARAM_AUTH_MODE_T) pvSetBuffer >= AUTH_MODE_NUM) { -+ DBGLOG(OID, TRACE, "Invalid auth mode %d\n", *(P_ENUM_PARAM_AUTH_MODE_T) pvSetBuffer); -+ return WLAN_STATUS_INVALID_DATA; -+ } -+ -+ switch (*(P_ENUM_PARAM_AUTH_MODE_T) pvSetBuffer) { -+ case AUTH_MODE_WPA: -+ case AUTH_MODE_WPA_PSK: -+ case AUTH_MODE_WPA2: -+ case AUTH_MODE_WPA2_PSK: -+ /* infrastructure mode only */ -+ if (prAdapter->rWifiVar.rConnSettings.eOPMode != NET_TYPE_INFRA) -+ return WLAN_STATUS_NOT_ACCEPTED; -+ break; -+ -+ case AUTH_MODE_WPA_NONE: -+ /* ad hoc mode only */ -+ if (prAdapter->rWifiVar.rConnSettings.eOPMode != NET_TYPE_IBSS) -+ return WLAN_STATUS_NOT_ACCEPTED; -+ break; -+ -+ default: -+ break; -+ } -+ -+ /* Save the new authentication mode. */ -+ prAdapter->rWifiVar.rConnSettings.eAuthMode = *(P_ENUM_PARAM_AUTH_MODE_T) pvSetBuffer; -+ -+#if DBG -+ switch (prAdapter->rWifiVar.rConnSettings.eAuthMode) { -+ case AUTH_MODE_OPEN: -+ DBGLOG(RSN, TRACE, "New auth mode: open\n"); -+ break; -+ -+ case AUTH_MODE_SHARED: -+ DBGLOG(RSN, TRACE, "New auth mode: shared\n"); -+ break; -+ -+ case AUTH_MODE_AUTO_SWITCH: -+ DBGLOG(RSN, TRACE, "New auth mode: auto-switch\n"); -+ break; -+ -+ case AUTH_MODE_WPA: -+ DBGLOG(RSN, TRACE, "New auth mode: WPA\n"); -+ break; -+ -+ case AUTH_MODE_WPA_PSK: -+ DBGLOG(RSN, TRACE, "New auth mode: WPA PSK\n"); -+ break; -+ -+ case AUTH_MODE_WPA_NONE: -+ DBGLOG(RSN, TRACE, "New auth mode: WPA None\n"); -+ break; -+ -+ case AUTH_MODE_WPA2: -+ DBGLOG(RSN, TRACE, "New auth mode: WPA2\n"); -+ break; -+ -+ case AUTH_MODE_WPA2_PSK: -+ DBGLOG(RSN, TRACE, "New auth mode: WPA2 PSK\n"); -+ break; -+ -+ default: -+ DBGLOG(RSN, TRACE, "New auth mode: unknown (%d)\n", prAdapter->rWifiVar.rConnSettings.eAuthMode); -+ } -+#endif -+ -+ if (prAdapter->rWifiVar.rConnSettings.eAuthMode >= AUTH_MODE_WPA) { -+ switch (prAdapter->rWifiVar.rConnSettings.eAuthMode) { -+ case AUTH_MODE_WPA: -+ u4AkmSuite = WPA_AKM_SUITE_802_1X; -+ break; -+ -+ case AUTH_MODE_WPA_PSK: -+ u4AkmSuite = WPA_AKM_SUITE_PSK; -+ break; -+ -+ case AUTH_MODE_WPA_NONE: -+ u4AkmSuite = WPA_AKM_SUITE_NONE; -+ break; -+ -+ case AUTH_MODE_WPA2: -+ u4AkmSuite = RSN_AKM_SUITE_802_1X; -+ break; -+ -+ case AUTH_MODE_WPA2_PSK: -+ u4AkmSuite = RSN_AKM_SUITE_PSK; -+ break; -+ -+ default: -+ u4AkmSuite = 0; -+ } -+ } else { -+ u4AkmSuite = 0; -+ } -+ -+ /* Enable the specific AKM suite only. */ -+ for (i = 0; i < MAX_NUM_SUPPORTED_AKM_SUITES; i++) { -+ prEntry = &prAdapter->rMib.dot11RSNAConfigAuthenticationSuitesTable[i]; -+ -+ if (prEntry->dot11RSNAConfigAuthenticationSuite == u4AkmSuite) -+ prEntry->dot11RSNAConfigAuthenticationSuiteEnabled = TRUE; -+ else -+ prEntry->dot11RSNAConfigAuthenticationSuiteEnabled = FALSE; -+#if CFG_SUPPORT_802_11W -+ if (kalGetMfpSetting(prAdapter->prGlueInfo) != RSN_AUTH_MFP_DISABLED) { -+ if ((u4AkmSuite == RSN_AKM_SUITE_PSK) && -+ prEntry->dot11RSNAConfigAuthenticationSuite == RSN_AKM_SUITE_PSK_SHA256) { -+ DBGLOG(RSN, TRACE, "Enable RSN_AKM_SUITE_PSK_SHA256 AKM support\n"); -+ prEntry->dot11RSNAConfigAuthenticationSuiteEnabled = TRUE; -+ -+ } -+ if ((u4AkmSuite == RSN_AKM_SUITE_802_1X) && -+ prEntry->dot11RSNAConfigAuthenticationSuite == RSN_AKM_SUITE_802_1X_SHA256) { -+ DBGLOG(RSN, TRACE, "Enable RSN_AKM_SUITE_802_1X_SHA256 AKM support\n"); -+ prEntry->dot11RSNAConfigAuthenticationSuiteEnabled = TRUE; -+ } -+ } -+#endif -+ } -+ -+ return WLAN_STATUS_SUCCESS; -+ -+} /* wlanoidSetAuthMode */ -+ -+#if 0 -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to query the current 802.11 privacy filter -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[out] pvQueryBuffer A pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufferLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_BUFFER_TOO_SHORT -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryPrivacyFilter(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ DEBUGFUNC("wlanoidQueryPrivacyFilter"); -+ -+ ASSERT(prAdapter); -+ -+ ASSERT(pvQueryBuffer); -+ ASSERT(pu4QueryInfoLen); -+ -+ *pu4QueryInfoLen = sizeof(ENUM_PARAM_PRIVACY_FILTER_T); -+ -+ if (u4QueryBufferLen < sizeof(ENUM_PARAM_PRIVACY_FILTER_T)) -+ return WLAN_STATUS_BUFFER_TOO_SHORT; -+ -+ *(P_ENUM_PARAM_PRIVACY_FILTER_T) pvQueryBuffer = prAdapter->rWlanInfo.ePrivacyFilter; -+ -+#if DBG -+ switch (*(P_ENUM_PARAM_PRIVACY_FILTER_T) pvQueryBuffer) { -+ case PRIVACY_FILTER_ACCEPT_ALL: -+ DBGLOG(OID, INFO, "Current privacy mode: open mode\n"); -+ break; -+ -+ case PRIVACY_FILTER_8021xWEP: -+ DBGLOG(OID, INFO, "Current privacy mode: filtering mode\n"); -+ break; -+ -+ default: -+ DBGLOG(OID, INFO, "Current auth mode: %d\n", *(P_ENUM_PARAM_AUTH_MODE_T) pvQueryBuffer); -+ } -+#endif -+ return WLAN_STATUS_SUCCESS; -+} /* wlanoidQueryPrivacyFilter */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to set the IEEE 802.11 privacy filter -+* to the driver. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_DATA -+* \retval WLAN_STATUS_INVALID_LENGTH -+* \retval WLAN_STATUS_ADAPTER_NOT_READY -+* \retval WLAN_STATUS_NOT_ACCEPTED -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetPrivacyFilter(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ P_GLUE_INFO_T prGlueInfo; -+ -+ DEBUGFUNC("wlanoidSetPrivacyFilter"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ ASSERT(pvSetBuffer); -+ -+ prGlueInfo = prAdapter->prGlueInfo; -+ -+ *pu4SetInfoLen = sizeof(ENUM_PARAM_PRIVACY_FILTER_T); -+ -+ if (u4SetBufferLen < sizeof(ENUM_PARAM_PRIVACY_FILTER_T)) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ if (prAdapter->rAcpiState == ACPI_STATE_D3) { -+ DBGLOG(OID, WARN, "Fail in set Authentication mode! (Adapter not ready). ACPI=D%d, Radio=%d\n", -+ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); -+ return WLAN_STATUS_ADAPTER_NOT_READY; -+ } -+ -+ /* Check if the new authentication mode is valid. */ -+ if (*(P_ENUM_PARAM_PRIVACY_FILTER_T) pvSetBuffer >= PRIVACY_FILTER_NUM) { -+ DBGLOG(OID, TRACE, "Invalid privacy filter %d\n", *(P_ENUM_PARAM_PRIVACY_FILTER_T) pvSetBuffer); -+ return WLAN_STATUS_INVALID_DATA; -+ } -+ -+ switch (*(P_ENUM_PARAM_PRIVACY_FILTER_T) pvSetBuffer) { -+ default: -+ break; -+ } -+ -+ /* Save the new authentication mode. */ -+ prAdapter->rWlanInfo.ePrivacyFilter = *(ENUM_PARAM_PRIVACY_FILTER_T) pvSetBuffer; -+ -+ return WLAN_STATUS_SUCCESS; -+ -+} /* wlanoidSetPrivacyFilter */ -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to reload the available default settings for -+* the specified type field. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_ADAPTER_NOT_READY -+* \retval WLAN_STATUS_INVALID_DATA -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetReloadDefaults(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ ENUM_PARAM_NETWORK_TYPE_T eNetworkType; -+ UINT_32 u4Len; -+ UINT_8 ucCmdSeqNum; -+ -+ DEBUGFUNC("wlanoidSetReloadDefaults"); -+ -+ ASSERT(prAdapter); -+ -+ ASSERT(pu4SetInfoLen); -+ *pu4SetInfoLen = sizeof(PARAM_RELOAD_DEFAULTS); -+ -+ /* if (IS_ARB_IN_RFTEST_STATE(prAdapter)) { */ -+ /* return WLAN_STATUS_SUCCESS; */ -+ /* } */ -+ -+ if (prAdapter->rAcpiState == ACPI_STATE_D3) { -+ DBGLOG(OID, WARN, "Fail in set Reload default! (Adapter not ready). ACPI=D%d, Radio=%d\n", -+ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); -+ return WLAN_STATUS_ADAPTER_NOT_READY; -+ } -+ -+ ASSERT(pvSetBuffer); -+ /* Verify the available reload options and reload the settings. */ -+ switch (*(P_PARAM_RELOAD_DEFAULTS) pvSetBuffer) { -+ case ENUM_RELOAD_WEP_KEYS: -+ /* Reload available default WEP keys from the permanent -+ storage. */ -+ prAdapter->rWifiVar.rConnSettings.eAuthMode = AUTH_MODE_OPEN; -+ /* ENUM_ENCRYPTION_DISABLED; */ -+ prAdapter->rWifiVar.rConnSettings.eEncStatus = ENUM_ENCRYPTION1_KEY_ABSENT; -+ { -+ P_GLUE_INFO_T prGlueInfo; -+ P_CMD_INFO_T prCmdInfo; -+ P_WIFI_CMD_T prWifiCmd; -+ P_CMD_802_11_KEY prCmdKey; -+ UINT_8 aucBCAddr[] = BC_MAC_ADDR; -+ -+ prGlueInfo = prAdapter->prGlueInfo; -+ prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, (CMD_HDR_SIZE + sizeof(CMD_802_11_KEY))); -+ -+ if (!prCmdInfo) { -+ DBGLOG(OID, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); -+ return WLAN_STATUS_FAILURE; -+ } -+ /* increase command sequence number */ -+ ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter); -+ -+ /* compose CMD_802_11_KEY cmd pkt */ -+ prCmdInfo->eCmdType = COMMAND_TYPE_NETWORK_IOCTL; -+ prCmdInfo->eNetworkType = NETWORK_TYPE_AIS_INDEX; -+ prCmdInfo->u2InfoBufLen = CMD_HDR_SIZE + sizeof(CMD_802_11_KEY); -+ prCmdInfo->pfCmdDoneHandler = nicCmdEventSetCommon; -+ prCmdInfo->pfCmdTimeoutHandler = nicOidCmdTimeoutCommon; -+ prCmdInfo->fgIsOid = TRUE; -+ prCmdInfo->ucCID = CMD_ID_ADD_REMOVE_KEY; -+ prCmdInfo->fgSetQuery = TRUE; -+ prCmdInfo->fgNeedResp = FALSE; -+ prCmdInfo->fgDriverDomainMCR = FALSE; -+ prCmdInfo->ucCmdSeqNum = ucCmdSeqNum; -+ prCmdInfo->u4SetInfoLen = sizeof(PARAM_REMOVE_KEY_T); -+ prCmdInfo->pvInformationBuffer = pvSetBuffer; -+ prCmdInfo->u4InformationBufferLength = u4SetBufferLen; -+ -+ /* Setup WIFI_CMD_T */ -+ prWifiCmd = (P_WIFI_CMD_T) (prCmdInfo->pucInfoBuffer); -+ prWifiCmd->u2TxByteCount_UserPriority = prCmdInfo->u2InfoBufLen; -+ prWifiCmd->ucCID = prCmdInfo->ucCID; -+ prWifiCmd->ucSetQuery = prCmdInfo->fgSetQuery; -+ prWifiCmd->ucSeqNum = prCmdInfo->ucCmdSeqNum; -+ -+ prCmdKey = (P_CMD_802_11_KEY) (prWifiCmd->aucBuffer); -+ -+ kalMemZero((PUINT_8) prCmdKey, sizeof(CMD_802_11_KEY)); -+ -+ prCmdKey->ucAddRemove = 0; /* Remove */ -+ prCmdKey->ucKeyId = 0; /* (UINT_8)(prRemovedKey->u4KeyIndex & 0x000000ff); */ -+ kalMemCopy(prCmdKey->aucPeerAddr, aucBCAddr, MAC_ADDR_LEN); -+ -+ ASSERT(prCmdKey->ucKeyId < MAX_KEY_NUM); -+ -+ prCmdKey->ucKeyType = 0; -+ -+ /* insert into prCmdQueue */ -+ kalEnqueueCommand(prGlueInfo, (P_QUE_ENTRY_T) prCmdInfo); -+ -+ /* wakeup txServiceThread later */ -+ GLUE_SET_EVENT(prGlueInfo); -+ -+ return WLAN_STATUS_PENDING; -+ } -+ -+ break; -+ -+ default: -+ DBGLOG(OID, TRACE, "Invalid reload option %d\n", *(P_PARAM_RELOAD_DEFAULTS) pvSetBuffer); -+ rStatus = WLAN_STATUS_INVALID_DATA; -+ } -+ -+ /* OID_802_11_RELOAD_DEFAULTS requiest to reset to auto mode */ -+ eNetworkType = PARAM_NETWORK_TYPE_AUTOMODE; -+ wlanoidSetNetworkTypeInUse(prAdapter, &eNetworkType, sizeof(eNetworkType), &u4Len); -+ -+ return rStatus; -+} /* wlanoidSetReloadDefaults */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to set a WEP key to the driver. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+* \retval WLAN_STATUS_INVALID_DATA -+* \retval WLAN_STATUS_ADAPTER_NOT_READY -+* \retval WLAN_STATUS_BUFFER_TOO_SHORT -+*/ -+/*----------------------------------------------------------------------------*/ -+#ifdef LINUX -+UINT_8 keyBuffer[sizeof(PARAM_KEY_T) + 16 /* LEGACY_KEY_MAX_LEN */]; -+UINT_8 aucBCAddr[] = BC_MAC_ADDR; -+#endif -+WLAN_STATUS -+wlanoidSetAddWep(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+#ifndef LINUX -+ UINT_8 keyBuffer[sizeof(PARAM_KEY_T) + 16 /* LEGACY_KEY_MAX_LEN */]; -+ UINT_8 aucBCAddr[] = BC_MAC_ADDR; -+#endif -+ P_PARAM_WEP_T prNewWepKey; -+ P_PARAM_KEY_T prParamKey = (P_PARAM_KEY_T) keyBuffer; -+ UINT_32 u4KeyId, u4SetLen; -+ -+ DEBUGFUNC("wlanoidSetAddWep"); -+ -+ ASSERT(prAdapter); -+ -+ *pu4SetInfoLen = OFFSET_OF(PARAM_WEP_T, aucKeyMaterial); -+ -+ if (u4SetBufferLen < OFFSET_OF(PARAM_WEP_T, aucKeyMaterial)) { -+ ASSERT(pu4SetInfoLen); -+ return WLAN_STATUS_BUFFER_TOO_SHORT; -+ } -+ -+ ASSERT(pvSetBuffer); -+ ASSERT(pu4SetInfoLen); -+ -+ if (prAdapter->rAcpiState == ACPI_STATE_D3) { -+ DBGLOG(OID, WARN, "Fail in set add WEP! (Adapter not ready). ACPI=D%d, Radio=%d\n", -+ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); -+ return WLAN_STATUS_ADAPTER_NOT_READY; -+ } -+ -+ prNewWepKey = (P_PARAM_WEP_T) pvSetBuffer; -+ -+ /* Verify the total buffer for minimum length. */ -+ if (u4SetBufferLen < OFFSET_OF(PARAM_WEP_T, aucKeyMaterial) + prNewWepKey->u4KeyLength) { -+ DBGLOG(OID, WARN, "Invalid total buffer length (%d) than minimum length (%d)\n", -+ (UINT_8) u4SetBufferLen, (UINT_8) OFFSET_OF(PARAM_WEP_T, aucKeyMaterial)); -+ -+ *pu4SetInfoLen = OFFSET_OF(PARAM_WEP_T, aucKeyMaterial); -+ return WLAN_STATUS_INVALID_DATA; -+ } -+ -+ /* Verify the key structure length. */ -+ if (prNewWepKey->u4Length > u4SetBufferLen) { -+ DBGLOG(OID, WARN, "Invalid key structure length (%d) greater than total buffer length (%d)\n", -+ (UINT_8) prNewWepKey->u4Length, (UINT_8) u4SetBufferLen); -+ -+ *pu4SetInfoLen = u4SetBufferLen; -+ return WLAN_STATUS_INVALID_DATA; -+ } -+ -+ /* Verify the key material length for maximum key material length:16 */ -+ if (prNewWepKey->u4KeyLength > 16 /* LEGACY_KEY_MAX_LEN */) { -+ DBGLOG(OID, WARN, "Invalid key material length (%d) greater than maximum key material length (16)\n", -+ (UINT_8) prNewWepKey->u4KeyLength); -+ -+ *pu4SetInfoLen = u4SetBufferLen; -+ return WLAN_STATUS_INVALID_DATA; -+ } -+ -+ *pu4SetInfoLen = u4SetBufferLen; -+ -+ u4KeyId = prNewWepKey->u4KeyIndex & BITS(0, 29) /* WEP_KEY_ID_FIELD */; -+ -+ /* Verify whether key index is valid or not, current version -+ driver support only 4 global WEP keys setting by this OID */ -+ if (u4KeyId > MAX_KEY_NUM - 1) { -+ DBGLOG(OID, ERROR, "Error, invalid WEP key ID: %d\n", (UINT_8) u4KeyId); -+ return WLAN_STATUS_INVALID_DATA; -+ } -+ -+ prParamKey->u4KeyIndex = u4KeyId; -+ -+ /* Transmit key */ -+ if (prNewWepKey->u4KeyIndex & IS_TRANSMIT_KEY) -+ prParamKey->u4KeyIndex |= IS_TRANSMIT_KEY; -+ -+ /* Per client key */ -+ if (prNewWepKey->u4KeyIndex & IS_UNICAST_KEY) -+ prParamKey->u4KeyIndex |= IS_UNICAST_KEY; -+ -+ prParamKey->u4KeyLength = prNewWepKey->u4KeyLength; -+ -+ kalMemCopy(prParamKey->arBSSID, aucBCAddr, MAC_ADDR_LEN); -+ -+ kalMemCopy(prParamKey->aucKeyMaterial, prNewWepKey->aucKeyMaterial, prNewWepKey->u4KeyLength); -+ -+ prParamKey->u4Length = OFFSET_OF(PARAM_KEY_T, aucKeyMaterial) + prNewWepKey->u4KeyLength; -+ -+ wlanoidSetAddKey(prAdapter, (PVOID) prParamKey, prParamKey->u4Length, &u4SetLen); -+ -+ return WLAN_STATUS_PENDING; -+} /* wlanoidSetAddWep */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to request the driver to remove the WEP key -+* at the specified key index. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_DATA -+* \retval WLAN_STATUS_INVALID_LENGTH -+* \retval WLAN_STATUS_ADAPTER_NOT_READY -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetRemoveWep(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ UINT_32 u4KeyId, u4SetLen; -+ PARAM_REMOVE_KEY_T rRemoveKey; -+ UINT_8 aucBCAddr[] = BC_MAC_ADDR; -+ -+ DEBUGFUNC("wlanoidSetRemoveWep"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ *pu4SetInfoLen = sizeof(PARAM_KEY_INDEX); -+ -+ if (u4SetBufferLen < sizeof(PARAM_KEY_INDEX)) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ ASSERT(pvSetBuffer); -+ u4KeyId = *(PUINT_32) pvSetBuffer; -+ -+ /* Dump PARAM_WEP content. */ -+ DBGLOG(OID, INFO, "Set: Dump PARAM_KEY_INDEX content\n"); -+ DBGLOG(OID, INFO, "Index : 0x%08x\n", u4KeyId); -+ -+ if (prAdapter->rAcpiState == ACPI_STATE_D3) { -+ DBGLOG(OID, WARN, "Fail in set remove WEP! (Adapter not ready). ACPI=D%d, Radio=%d\n", -+ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); -+ return WLAN_STATUS_ADAPTER_NOT_READY; -+ } -+ -+ if (u4KeyId & IS_TRANSMIT_KEY) { -+ /* Bit 31 should not be set */ -+ DBGLOG(OID, ERROR, "Invalid WEP key index: 0x%08x\n", u4KeyId); -+ return WLAN_STATUS_INVALID_DATA; -+ } -+ -+ u4KeyId &= BITS(0, 7); -+ -+ /* Verify whether key index is valid or not. Current version -+ driver support only 4 global WEP keys. */ -+ if (u4KeyId > MAX_KEY_NUM - 1) { -+ DBGLOG(OID, ERROR, "invalid WEP key ID %u\n", u4KeyId); -+ return WLAN_STATUS_INVALID_DATA; -+ } -+ -+ rRemoveKey.u4Length = sizeof(PARAM_REMOVE_KEY_T); -+ rRemoveKey.u4KeyIndex = *(PUINT_32) pvSetBuffer; -+ -+ kalMemCopy(rRemoveKey.arBSSID, aucBCAddr, MAC_ADDR_LEN); -+ -+ wlanoidSetRemoveKey(prAdapter, (PVOID)&rRemoveKey, sizeof(PARAM_REMOVE_KEY_T), &u4SetLen); -+ -+ return WLAN_STATUS_PENDING; -+} /* wlanoidSetRemoveWep */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to set a key to the driver. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_ADAPTER_NOT_READY -+* \retval WLAN_STATUS_INVALID_LENGTH -+* \retval WLAN_STATUS_INVALID_DATA -+* -+* \note The setting buffer PARAM_KEY_T, which is set by NDIS, is unpacked. -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+_wlanoidSetAddKey(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, -+ IN UINT_32 u4SetBufferLen, IN BOOLEAN fgIsOid, IN UINT_8 ucAlgorithmId, OUT PUINT_32 pu4SetInfoLen) -+{ -+ P_GLUE_INFO_T prGlueInfo; -+ P_CMD_INFO_T prCmdInfo; -+ P_WIFI_CMD_T prWifiCmd; -+ P_PARAM_KEY_T prNewKey; -+ P_CMD_802_11_KEY prCmdKey; -+ UINT_8 ucCmdSeqNum; -+ -+#if 0 -+ DEBUGFUNC("wlanoidSetAddKey"); -+ DBGLOG(OID, LOUD, "\n"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pvSetBuffer); -+ ASSERT(pu4SetInfoLen); -+ -+ if (prAdapter->rAcpiState == ACPI_STATE_D3) { -+ DBGLOG(OID, WARN, "Fail in set add key! (Adapter not ready). ACPI=D%d, Radio=%d\n", -+ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); -+ return WLAN_STATUS_ADAPTER_NOT_READY; -+ } -+#endif -+ -+ prNewKey = (P_PARAM_KEY_T) pvSetBuffer; -+ -+#if 0 -+ /* Verify the key structure length. */ -+ if (prNewKey->u4Length > u4SetBufferLen) { -+ DBGLOG(OID, WARN, "Invalid key structure length (%d) greater than total buffer length (%d)\n", -+ (UINT_8) prNewKey->u4Length, (UINT_8) u4SetBufferLen); -+ -+ *pu4SetInfoLen = u4SetBufferLen; -+ return WLAN_STATUS_INVALID_LENGTH; -+ } -+ -+ /* Verify the key material length for key material buffer */ -+ if (prNewKey->u4KeyLength > prNewKey->u4Length - OFFSET_OF(PARAM_KEY_T, aucKeyMaterial)) { -+ DBGLOG(OID, WARN, "Invalid key material length (%d)\n", (UINT_8) prNewKey->u4KeyLength); -+ *pu4SetInfoLen = u4SetBufferLen; -+ return WLAN_STATUS_INVALID_DATA; -+ } -+ -+ /* Exception check */ -+ if (prNewKey->u4KeyIndex & 0x0fffff00) -+ return WLAN_STATUS_INVALID_DATA; -+ -+ /* Exception check, pairwise key must with transmit bit enabled */ -+ if ((prNewKey->u4KeyIndex & BITS(30, 31)) == IS_UNICAST_KEY) -+ return WLAN_STATUS_INVALID_DATA; -+ -+ if (!(prNewKey->u4KeyLength == WEP_40_LEN || prNewKey->u4KeyLength == WEP_104_LEN || -+ prNewKey->u4KeyLength == CCMP_KEY_LEN || prNewKey->u4KeyLength == TKIP_KEY_LEN)) { -+ return WLAN_STATUS_INVALID_DATA; -+ } -+ -+ /* Exception check, pairwise key must with transmit bit enabled */ -+ if ((prNewKey->u4KeyIndex & BITS(30, 31)) == BITS(30, 31)) { -+ if (((prNewKey->u4KeyIndex & 0xff) != 0) || -+ ((prNewKey->arBSSID[0] == 0xff) && (prNewKey->arBSSID[1] == 0xff) && (prNewKey->arBSSID[2] == 0xff) -+ && (prNewKey->arBSSID[3] == 0xff) && (prNewKey->arBSSID[4] == 0xff) -+ && (prNewKey->arBSSID[5] == 0xff))) { -+ return WLAN_STATUS_INVALID_DATA; -+ } -+ } -+ -+ *pu4SetInfoLen = u4SetBufferLen; -+#endif -+ -+ /* Dump PARAM_KEY content. */ -+ DBGLOG(OID, TRACE, "Set: PARAM_KEY Length: 0x%08x, Key Index: 0x%08x, Key Length: 0x%08x\n", -+ prNewKey->u4Length, prNewKey->u4KeyIndex, prNewKey->u4KeyLength); -+ DBGLOG(OID, TRACE, "BSSID:\n"); -+ DBGLOG_MEM8(OID, TRACE, prNewKey->arBSSID, sizeof(PARAM_MAC_ADDRESS)); -+ DBGLOG(OID, TRACE, "Key RSC:\n"); -+ DBGLOG_MEM8(OID, TRACE, &prNewKey->rKeyRSC, sizeof(PARAM_KEY_RSC)); -+ DBGLOG(OID, TRACE, "Key Material:\n"); -+ DBGLOG_MEM8(OID, TRACE, prNewKey->aucKeyMaterial, prNewKey->u4KeyLength); -+ -+ if (prAdapter->rWifiVar.rConnSettings.eAuthMode < AUTH_MODE_WPA) { -+ /* Todo:: Store the legacy wep key for OID_802_11_RELOAD_DEFAULTS */ -+ /* Todo:: Nothing */ -+ } -+ -+ if (prNewKey->u4KeyIndex & IS_TRANSMIT_KEY) -+ prAdapter->rWifiVar.rAisSpecificBssInfo.fgTransmitKeyExist = TRUE; -+ -+ prGlueInfo = prAdapter->prGlueInfo; -+ prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, (CMD_HDR_SIZE + sizeof(CMD_802_11_KEY))); -+ -+ if (!prCmdInfo) { -+ DBGLOG(OID, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); -+ return WLAN_STATUS_FAILURE; -+ } -+ /* increase command sequence number */ -+ ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter); -+ DBGLOG(OID, TRACE, "ucCmdSeqNum = %d\n", ucCmdSeqNum); -+ -+ /* compose CMD_802_11_KEY cmd pkt */ -+ prCmdInfo->eCmdType = COMMAND_TYPE_NETWORK_IOCTL; -+ prCmdInfo->eNetworkType = NETWORK_TYPE_AIS_INDEX; -+ prCmdInfo->u2InfoBufLen = CMD_HDR_SIZE + sizeof(CMD_802_11_KEY); -+ prCmdInfo->pfCmdDoneHandler = nicCmdEventSetCommon; -+ prCmdInfo->pfCmdTimeoutHandler = nicOidCmdTimeoutCommon; -+ prCmdInfo->fgIsOid = fgIsOid; -+ prCmdInfo->ucCID = CMD_ID_ADD_REMOVE_KEY; -+ prCmdInfo->fgSetQuery = TRUE; -+ prCmdInfo->fgNeedResp = FALSE; -+ prCmdInfo->fgDriverDomainMCR = FALSE; -+ prCmdInfo->ucCmdSeqNum = ucCmdSeqNum; -+ prCmdInfo->u4SetInfoLen = u4SetBufferLen; -+ prCmdInfo->pvInformationBuffer = pvSetBuffer; -+ prCmdInfo->u4InformationBufferLength = u4SetBufferLen; -+ -+ /* Setup WIFI_CMD_T */ -+ prWifiCmd = (P_WIFI_CMD_T) (prCmdInfo->pucInfoBuffer); -+ prWifiCmd->u2TxByteCount_UserPriority = prCmdInfo->u2InfoBufLen; -+ prWifiCmd->ucCID = prCmdInfo->ucCID; -+ prWifiCmd->ucSetQuery = prCmdInfo->fgSetQuery; -+ prWifiCmd->ucSeqNum = prCmdInfo->ucCmdSeqNum; -+ -+ prCmdKey = (P_CMD_802_11_KEY) (prWifiCmd->aucBuffer); -+ -+ kalMemZero(prCmdKey, sizeof(CMD_802_11_KEY)); -+ -+ prCmdKey->ucAddRemove = 1; /* Add */ -+ -+ prCmdKey->ucTxKey = ((prNewKey->u4KeyIndex & IS_TRANSMIT_KEY) == IS_TRANSMIT_KEY) ? 1 : 0; -+ prCmdKey->ucKeyType = ((prNewKey->u4KeyIndex & IS_UNICAST_KEY) == IS_UNICAST_KEY) ? 1 : 0; -+ prCmdKey->ucIsAuthenticator = ((prNewKey->u4KeyIndex & IS_AUTHENTICATOR) == IS_AUTHENTICATOR) ? 1 : 0; -+ -+ kalMemCopy(prCmdKey->aucPeerAddr, (PUINT_8) prNewKey->arBSSID, MAC_ADDR_LEN); -+ -+ prCmdKey->ucNetType = 0; /* AIS */ -+ -+ prCmdKey->ucKeyId = (UINT_8) (prNewKey->u4KeyIndex & 0xff); -+ -+ /* Note: adjust the key length for WPA-None */ -+ prCmdKey->ucKeyLen = (UINT_8) prNewKey->u4KeyLength; -+ -+ kalMemCopy(prCmdKey->aucKeyMaterial, (PUINT_8) prNewKey->aucKeyMaterial, prCmdKey->ucKeyLen); -+ -+ if (prNewKey->u4KeyLength == 5) { -+ prCmdKey->ucAlgorithmId = CIPHER_SUITE_WEP40; -+ } else if (prNewKey->u4KeyLength == 13) { -+ prCmdKey->ucAlgorithmId = CIPHER_SUITE_WEP104; -+ } else if (prNewKey->u4KeyLength == 16) { -+ if ((ucAlgorithmId != CIPHER_SUITE_CCMP) && -+ (prAdapter->rWifiVar.rConnSettings.eAuthMode < AUTH_MODE_WPA)) -+ prCmdKey->ucAlgorithmId = CIPHER_SUITE_WEP128; -+ else { -+#if CFG_SUPPORT_802_11W -+ if (prCmdKey->ucKeyId >= 4) { -+ prCmdKey->ucAlgorithmId = CIPHER_SUITE_BIP; -+ P_AIS_SPECIFIC_BSS_INFO_T prAisSpecBssInfo; -+ -+ prAisSpecBssInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo; -+ prAisSpecBssInfo->fgBipKeyInstalled = TRUE; -+ } else -+#endif -+ prCmdKey->ucAlgorithmId = CIPHER_SUITE_CCMP; -+ if (rsnCheckPmkidCandicate(prAdapter)) { -+ P_AIS_SPECIFIC_BSS_INFO_T prAisSpecBssInfo; -+ -+ prAisSpecBssInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo; -+ DBGLOG(RSN, TRACE, -+ "Add key: Prepare a timer to indicate candidate PMKID Candidate\n"); -+ cnmTimerStopTimer(prAdapter, &prAisSpecBssInfo->rPreauthenticationTimer); -+ cnmTimerStartTimer(prAdapter, &prAisSpecBssInfo->rPreauthenticationTimer, -+ SEC_TO_MSEC(WAIT_TIME_IND_PMKID_CANDICATE_SEC)); -+ } -+ } -+ } else if (prNewKey->u4KeyLength == 32) { -+ if (prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA_NONE) { -+ if (prAdapter->rWifiVar.rConnSettings.eEncStatus == ENUM_ENCRYPTION2_ENABLED) -+ prCmdKey->ucAlgorithmId = CIPHER_SUITE_TKIP; -+ else if (prAdapter->rWifiVar.rConnSettings.eEncStatus == ENUM_ENCRYPTION3_ENABLED) { -+ prCmdKey->ucAlgorithmId = CIPHER_SUITE_CCMP; -+ prCmdKey->ucKeyLen = CCMP_KEY_LEN; -+ } -+ } else -+ prCmdKey->ucAlgorithmId = CIPHER_SUITE_TKIP; -+ } -+ -+ DBGLOG(RSN, TRACE, "prCmdKey->ucAlgorithmId=%d, key len=%d\n", -+ prCmdKey->ucAlgorithmId, (UINT32) prNewKey->u4KeyLength); -+ -+ /* insert into prCmdQueue */ -+ kalEnqueueCommand(prGlueInfo, (P_QUE_ENTRY_T) prCmdInfo); -+ -+ /* wakeup txServiceThread later */ -+ GLUE_SET_EVENT(prGlueInfo); -+ -+ return WLAN_STATUS_PENDING; -+} -+ -+WLAN_STATUS -+wlanoidSetAddKey(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ P_PARAM_KEY_T prNewKey; -+ -+ DEBUGFUNC("wlanoidSetAddKey"); -+ DBGLOG(OID, LOUD, "\n"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pvSetBuffer); -+ ASSERT(pu4SetInfoLen); -+ -+ if (prAdapter->rAcpiState == ACPI_STATE_D3) { -+ DBGLOG(OID, WARN, "Fail in set add key! (Adapter not ready). ACPI=D%d, Radio=%d\n", -+ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); -+ return WLAN_STATUS_ADAPTER_NOT_READY; -+ } -+ -+ prNewKey = (P_PARAM_KEY_T) pvSetBuffer; -+ -+ /* Verify the key structure length. */ -+ if (prNewKey->u4Length > u4SetBufferLen) { -+ DBGLOG(OID, WARN, "Invalid key structure length (%d) greater than total buffer length (%d)\n", -+ (UINT_8) prNewKey->u4Length, (UINT_8) u4SetBufferLen); -+ -+ *pu4SetInfoLen = u4SetBufferLen; -+ return WLAN_STATUS_INVALID_LENGTH; -+ } -+ -+ /* Verify the key material length for key material buffer */ -+ if (prNewKey->u4KeyLength > prNewKey->u4Length - OFFSET_OF(PARAM_KEY_T, aucKeyMaterial)) { -+ DBGLOG(OID, WARN, "Invalid key material length (%d)\n", (UINT_8) prNewKey->u4KeyLength); -+ *pu4SetInfoLen = u4SetBufferLen; -+ return WLAN_STATUS_INVALID_DATA; -+ } -+ -+ /* Exception check */ -+ if (prNewKey->u4KeyIndex & 0x0fffff00) -+ return WLAN_STATUS_INVALID_DATA; -+ -+ /* Exception check, pairwise key must with transmit bit enabled */ -+ if ((prNewKey->u4KeyIndex & BITS(30, 31)) == BITS(30, 31)) { -+ if (((prNewKey->u4KeyLength == CCMP_KEY_LEN || prNewKey->u4KeyLength == TKIP_KEY_LEN) && -+ (prNewKey->u4KeyIndex & 0xff) != 0) || -+ EQUAL_MAC_ADDR(prNewKey->arBSSID, "\xff\xff\xff\xff\xff\xff")) { -+ return WLAN_STATUS_INVALID_DATA; -+ } -+ } else if ((prNewKey->u4KeyIndex & BITS(30, 31)) == IS_UNICAST_KEY) -+ return WLAN_STATUS_INVALID_DATA; -+ -+ if (!(prNewKey->u4KeyLength == WEP_40_LEN || prNewKey->u4KeyLength == WEP_104_LEN || -+ prNewKey->u4KeyLength == CCMP_KEY_LEN || prNewKey->u4KeyLength == TKIP_KEY_LEN)) { -+ return WLAN_STATUS_INVALID_DATA; -+ } -+ -+ *pu4SetInfoLen = u4SetBufferLen; -+ -+#if (CFG_SUPPORT_TDLS == 1) -+ /* -+ supplicant will set key before updating station & enabling the link so we need to -+ backup the key information and set key when link is enabled -+ */ -+ if (TdlsexKeyHandle(prAdapter, prNewKey) == TDLS_STATUS_SUCCESS) -+ return WLAN_STATUS_SUCCESS; -+#endif /* CFG_SUPPORT_TDLS */ -+ -+ return _wlanoidSetAddKey(prAdapter, pvSetBuffer, u4SetBufferLen, TRUE, CIPHER_SUITE_NONE, pu4SetInfoLen); -+} /* wlanoidSetAddKey */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to request the driver to remove the key at -+* the specified key index. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_DATA -+* \retval WLAN_STATUS_INVALID_LENGTH -+* \retval WLAN_STATUS_ADAPTER_NOT_READY -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetRemoveKey(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ P_GLUE_INFO_T prGlueInfo; -+ P_CMD_INFO_T prCmdInfo; -+ P_WIFI_CMD_T prWifiCmd; -+ P_PARAM_REMOVE_KEY_T prRemovedKey; -+ P_CMD_802_11_KEY prCmdKey; -+ UINT_8 ucCmdSeqNum; -+ -+ DEBUGFUNC("wlanoidSetRemoveKey"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ *pu4SetInfoLen = sizeof(PARAM_REMOVE_KEY_T); -+ -+ if (u4SetBufferLen < sizeof(PARAM_REMOVE_KEY_T)) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ if (prAdapter->rAcpiState == ACPI_STATE_D3) { -+ DBGLOG(OID, WARN, "Fail in set remove key! (Adapter not ready). ACPI=D%d, Radio=%d\n", -+ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); -+ return WLAN_STATUS_ADAPTER_NOT_READY; -+ } -+ -+ ASSERT(pvSetBuffer); -+ prRemovedKey = (P_PARAM_REMOVE_KEY_T) pvSetBuffer; -+ -+ /* Dump PARAM_REMOVE_KEY content. */ -+ DBGLOG(OID, TRACE, "Set: Dump PARAM_REMOVE_KEY content\n"); -+ DBGLOG(OID, TRACE, "Length : 0x%08x\n", prRemovedKey->u4Length); -+ DBGLOG(OID, TRACE, "Key Index : 0x%08x\n", prRemovedKey->u4KeyIndex); -+ DBGLOG(OID, TRACE, "BSSID:\n"); -+ DBGLOG_MEM8(OID, TRACE, prRemovedKey->arBSSID, MAC_ADDR_LEN); -+ -+ /* Check bit 31: this bit should always 0 */ -+ if (prRemovedKey->u4KeyIndex & IS_TRANSMIT_KEY) { -+ /* Bit 31 should not be set */ -+ DBGLOG(OID, ERROR, "invalid key index: 0x%08x\n", prRemovedKey->u4KeyIndex); -+ return WLAN_STATUS_INVALID_DATA; -+ } -+ -+ /* Check bits 8 ~ 29 should always be 0 */ -+ if (prRemovedKey->u4KeyIndex & BITS(8, 29)) { -+ /* Bit 31 should not be set */ -+ DBGLOG(OID, ERROR, "invalid key index: 0x%08x\n", prRemovedKey->u4KeyIndex); -+ return WLAN_STATUS_INVALID_DATA; -+ } -+ -+ /* Clean up the Tx key flag */ -+ if (prRemovedKey->u4KeyIndex & IS_UNICAST_KEY) -+ prAdapter->rWifiVar.rAisSpecificBssInfo.fgTransmitKeyExist = FALSE; -+ -+ prGlueInfo = prAdapter->prGlueInfo; -+ prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, (CMD_HDR_SIZE + sizeof(CMD_802_11_KEY))); -+ -+ if (!prCmdInfo) { -+ DBGLOG(OID, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); -+ return WLAN_STATUS_FAILURE; -+ } -+ /* increase command sequence number */ -+ ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter); -+ -+ /* compose CMD_802_11_KEY cmd pkt */ -+ prCmdInfo->eCmdType = COMMAND_TYPE_NETWORK_IOCTL; -+ prCmdInfo->eNetworkType = NETWORK_TYPE_AIS_INDEX; -+ prCmdInfo->u2InfoBufLen = CMD_HDR_SIZE + sizeof(CMD_802_11_KEY); -+ prCmdInfo->pfCmdDoneHandler = nicCmdEventSetCommon; -+ prCmdInfo->pfCmdTimeoutHandler = nicOidCmdTimeoutCommon; -+ prCmdInfo->fgIsOid = TRUE; -+ prCmdInfo->ucCID = CMD_ID_ADD_REMOVE_KEY; -+ prCmdInfo->fgSetQuery = TRUE; -+ prCmdInfo->fgNeedResp = FALSE; -+ prCmdInfo->fgDriverDomainMCR = FALSE; -+ prCmdInfo->ucCmdSeqNum = ucCmdSeqNum; -+ prCmdInfo->u4SetInfoLen = sizeof(PARAM_REMOVE_KEY_T); -+ prCmdInfo->pvInformationBuffer = pvSetBuffer; -+ prCmdInfo->u4InformationBufferLength = u4SetBufferLen; -+ -+ /* Setup WIFI_CMD_T */ -+ prWifiCmd = (P_WIFI_CMD_T) (prCmdInfo->pucInfoBuffer); -+ prWifiCmd->u2TxByteCount_UserPriority = prCmdInfo->u2InfoBufLen; -+ prWifiCmd->ucCID = prCmdInfo->ucCID; -+ prWifiCmd->ucSetQuery = prCmdInfo->fgSetQuery; -+ prWifiCmd->ucSeqNum = prCmdInfo->ucCmdSeqNum; -+ -+ prCmdKey = (P_CMD_802_11_KEY) (prWifiCmd->aucBuffer); -+ -+ kalMemZero((PUINT_8) prCmdKey, sizeof(CMD_802_11_KEY)); -+ -+ prCmdKey->ucAddRemove = 0; /* Remove */ -+ prCmdKey->ucKeyId = (UINT_8) (prRemovedKey->u4KeyIndex & 0x000000ff); -+ kalMemCopy(prCmdKey->aucPeerAddr, (PUINT_8) prRemovedKey->arBSSID, MAC_ADDR_LEN); -+ -+#if CFG_SUPPORT_802_11W -+ ASSERT(prCmdKey->ucKeyId < MAX_KEY_NUM + 2); -+#else -+ /* ASSERT(prCmdKey->ucKeyId < MAX_KEY_NUM); */ -+#endif -+ -+ if (prRemovedKey->u4KeyIndex & IS_UNICAST_KEY) -+ prCmdKey->ucKeyType = 1; -+ /* insert into prCmdQueue */ -+ kalEnqueueCommand(prGlueInfo, (P_QUE_ENTRY_T) prCmdInfo); -+ -+ /* wakeup txServiceThread later */ -+ GLUE_SET_EVENT(prGlueInfo); -+ -+ return WLAN_STATUS_PENDING; -+} /* wlanoidSetRemoveKey */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to query the current encryption status. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[out] pvQueryBuffer A pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufferLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryEncryptionStatus(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ BOOLEAN fgTransmitKeyAvailable = TRUE; -+ ENUM_PARAM_ENCRYPTION_STATUS_T eEncStatus = 0; -+ -+ DEBUGFUNC("wlanoidQueryEncryptionStatus"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4QueryInfoLen); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ -+ *pu4QueryInfoLen = sizeof(ENUM_PARAM_ENCRYPTION_STATUS_T); -+ -+ fgTransmitKeyAvailable = prAdapter->rWifiVar.rAisSpecificBssInfo.fgTransmitKeyExist; -+ -+ switch (prAdapter->rWifiVar.rConnSettings.eEncStatus) { -+ case ENUM_ENCRYPTION3_ENABLED: -+ if (fgTransmitKeyAvailable) -+ eEncStatus = ENUM_ENCRYPTION3_ENABLED; -+ else -+ eEncStatus = ENUM_ENCRYPTION3_KEY_ABSENT; -+ break; -+ -+ case ENUM_ENCRYPTION2_ENABLED: -+ if (fgTransmitKeyAvailable) { -+ eEncStatus = ENUM_ENCRYPTION2_ENABLED; -+ break; -+ } -+ eEncStatus = ENUM_ENCRYPTION2_KEY_ABSENT; -+ break; -+ -+ case ENUM_ENCRYPTION1_ENABLED: -+ if (fgTransmitKeyAvailable) -+ eEncStatus = ENUM_ENCRYPTION1_ENABLED; -+ else -+ eEncStatus = ENUM_ENCRYPTION1_KEY_ABSENT; -+ break; -+ -+ case ENUM_ENCRYPTION_DISABLED: -+ eEncStatus = ENUM_ENCRYPTION_DISABLED; -+ break; -+ -+ default: -+ DBGLOG(OID, ERROR, "Unknown Encryption Status Setting:%d\n", -+ prAdapter->rWifiVar.rConnSettings.eEncStatus); -+ } -+ -+#if DBG -+ DBGLOG(OID, INFO, -+ "Encryption status: %d Return:%d\n", prAdapter->rWifiVar.rConnSettings.eEncStatus, eEncStatus); -+#endif -+ -+ *(P_ENUM_PARAM_ENCRYPTION_STATUS_T) pvQueryBuffer = eEncStatus; -+ -+ return WLAN_STATUS_SUCCESS; -+} /* wlanoidQueryEncryptionStatus */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to set the encryption status to the driver. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_ADAPTER_NOT_READY -+* \retval WLAN_STATUS_NOT_SUPPORTED -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetEncryptionStatus(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ P_GLUE_INFO_T prGlueInfo; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ ENUM_PARAM_ENCRYPTION_STATUS_T eEewEncrypt; -+ -+ DEBUGFUNC("wlanoidSetEncryptionStatus"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pvSetBuffer); -+ ASSERT(pu4SetInfoLen); -+ -+ prGlueInfo = prAdapter->prGlueInfo; -+ -+ *pu4SetInfoLen = sizeof(ENUM_PARAM_ENCRYPTION_STATUS_T); -+ -+ /* if (IS_ARB_IN_RFTEST_STATE(prAdapter)) { */ -+ /* return WLAN_STATUS_SUCCESS; */ -+ /* } */ -+ -+ if (prAdapter->rAcpiState == ACPI_STATE_D3) { -+ DBGLOG(OID, WARN, "Fail in set encryption status! (Adapter not ready). ACPI=D%d, Radio=%d\n", -+ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); -+ return WLAN_STATUS_ADAPTER_NOT_READY; -+ } -+ -+ eEewEncrypt = *(P_ENUM_PARAM_ENCRYPTION_STATUS_T) pvSetBuffer; -+ DBGLOG(OID, TRACE, "ENCRYPTION_STATUS %d\n", eEewEncrypt); -+ -+ switch (eEewEncrypt) { -+ case ENUM_ENCRYPTION_DISABLED: /* Disable WEP, TKIP, AES */ -+ DBGLOG(RSN, TRACE, "Disable Encryption\n"); -+ secSetCipherSuite(prAdapter, CIPHER_FLAG_WEP40 | CIPHER_FLAG_WEP104 | CIPHER_FLAG_WEP128); -+ break; -+ -+ case ENUM_ENCRYPTION1_ENABLED: /* Enable WEP. Disable TKIP, AES */ -+ DBGLOG(RSN, TRACE, "Enable Encryption1\n"); -+ secSetCipherSuite(prAdapter, CIPHER_FLAG_WEP40 | CIPHER_FLAG_WEP104 | CIPHER_FLAG_WEP128); -+ break; -+ -+ case ENUM_ENCRYPTION2_ENABLED: /* Enable WEP, TKIP. Disable AES */ -+ secSetCipherSuite(prAdapter, -+ CIPHER_FLAG_WEP40 | CIPHER_FLAG_WEP104 | CIPHER_FLAG_WEP128 | CIPHER_FLAG_TKIP); -+ DBGLOG(RSN, TRACE, "Enable Encryption2\n"); -+ break; -+ -+ case ENUM_ENCRYPTION3_ENABLED: /* Enable WEP, TKIP, AES */ -+ secSetCipherSuite(prAdapter, -+ CIPHER_FLAG_WEP40 | -+ CIPHER_FLAG_WEP104 | CIPHER_FLAG_WEP128 | CIPHER_FLAG_TKIP | CIPHER_FLAG_CCMP); -+ DBGLOG(RSN, TRACE, "Enable Encryption3\n"); -+ break; -+ -+ default: -+ DBGLOG(RSN, WARN, "Unacceptible encryption status: %d\n", -+ *(P_ENUM_PARAM_ENCRYPTION_STATUS_T) pvSetBuffer); -+ -+ rStatus = WLAN_STATUS_NOT_SUPPORTED; -+ } -+ -+ if (rStatus == WLAN_STATUS_SUCCESS) { -+ /* Save the new encryption status. */ -+ prAdapter->rWifiVar.rConnSettings.eEncStatus = *(P_ENUM_PARAM_ENCRYPTION_STATUS_T) pvSetBuffer; -+ -+ DBGLOG(RSN, TRACE, "wlanoidSetEncryptionStatus to %d\n", -+ prAdapter->rWifiVar.rConnSettings.eEncStatus); -+ } -+ -+ return rStatus; -+} /* wlanoidSetEncryptionStatus */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to test the driver. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+* \retval WLAN_STATUS_INVALID_DATA -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetTest(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ P_PARAM_802_11_TEST_T prTest; -+ PVOID pvTestData; -+ PVOID pvStatusBuffer; -+ UINT_32 u4StatusBufferSize; -+ -+ DEBUGFUNC("wlanoidSetTest"); -+ -+ ASSERT(prAdapter); -+ -+ ASSERT(pu4SetInfoLen); -+ ASSERT(pvSetBuffer); -+ -+ *pu4SetInfoLen = u4SetBufferLen; -+ -+ prTest = (P_PARAM_802_11_TEST_T) pvSetBuffer; -+ -+ DBGLOG(OID, TRACE, "Test - Type %u\n", prTest->u4Type); -+ -+ switch (prTest->u4Type) { -+ case 1: /* Type 1: generate an authentication event */ -+ pvTestData = (PVOID) &prTest->u.AuthenticationEvent; -+ pvStatusBuffer = (PVOID) prAdapter->aucIndicationEventBuffer; -+ u4StatusBufferSize = prTest->u4Length - 8; -+ if (u4StatusBufferSize > sizeof(PARAM_AUTH_EVENT_T)) { -+ DBGLOG(OID, TRACE, "prTest->u4Length error %u\n", u4StatusBufferSize); -+ ASSERT(FALSE); -+ } -+ break; -+ -+ case 2: /* Type 2: generate an RSSI status indication */ -+ pvTestData = (PVOID) &prTest->u.RssiTrigger; -+ pvStatusBuffer = (PVOID) &prAdapter->rWlanInfo.rCurrBssId.rRssi; -+ u4StatusBufferSize = sizeof(PARAM_RSSI); -+ break; -+ -+ default: -+ return WLAN_STATUS_INVALID_DATA; -+ } -+ -+ ASSERT(u4StatusBufferSize <= 180); -+ if (u4StatusBufferSize > 180) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ /* Get the contents of the StatusBuffer from the test structure. */ -+ kalMemCopy(pvStatusBuffer, pvTestData, u4StatusBufferSize); -+ -+ kalIndicateStatusAndComplete(prAdapter->prGlueInfo, -+ WLAN_STATUS_MEDIA_SPECIFIC_INDICATION, pvStatusBuffer, u4StatusBufferSize); -+ -+ return WLAN_STATUS_SUCCESS; -+} /* wlanoidSetTest */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to query the driver's WPA2 status. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[out] pvQueryBuffer A pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufferLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryCapability(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ P_PARAM_CAPABILITY_T prCap; -+ P_PARAM_AUTH_ENCRYPTION_T prAuthenticationEncryptionSupported; -+ -+ DEBUGFUNC("wlanoidQueryCapability"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4QueryInfoLen); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ -+ *pu4QueryInfoLen = 4 * sizeof(UINT_32) + 14 * sizeof(PARAM_AUTH_ENCRYPTION_T); -+ -+ if (u4QueryBufferLen < *pu4QueryInfoLen) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ prCap = (P_PARAM_CAPABILITY_T) pvQueryBuffer; -+ -+ prCap->u4Length = *pu4QueryInfoLen; -+ prCap->u4Version = 2; /* WPA2 */ -+ prCap->u4NoOfPMKIDs = CFG_MAX_PMKID_CACHE; -+ prCap->u4NoOfAuthEncryptPairsSupported = 14; -+ -+ prAuthenticationEncryptionSupported = &prCap->arAuthenticationEncryptionSupported[0]; -+ -+ /* fill 14 entries of supported settings */ -+ prAuthenticationEncryptionSupported[0].eAuthModeSupported = AUTH_MODE_OPEN; -+ -+ prAuthenticationEncryptionSupported[0].eEncryptStatusSupported = ENUM_ENCRYPTION_DISABLED; -+ -+ prAuthenticationEncryptionSupported[1].eAuthModeSupported = AUTH_MODE_OPEN; -+ prAuthenticationEncryptionSupported[1].eEncryptStatusSupported = ENUM_ENCRYPTION1_ENABLED; -+ -+ prAuthenticationEncryptionSupported[2].eAuthModeSupported = AUTH_MODE_SHARED; -+ prAuthenticationEncryptionSupported[2].eEncryptStatusSupported = ENUM_ENCRYPTION_DISABLED; -+ -+ prAuthenticationEncryptionSupported[3].eAuthModeSupported = AUTH_MODE_SHARED; -+ prAuthenticationEncryptionSupported[3].eEncryptStatusSupported = ENUM_ENCRYPTION1_ENABLED; -+ -+ prAuthenticationEncryptionSupported[4].eAuthModeSupported = AUTH_MODE_WPA; -+ prAuthenticationEncryptionSupported[4].eEncryptStatusSupported = ENUM_ENCRYPTION2_ENABLED; -+ -+ prAuthenticationEncryptionSupported[5].eAuthModeSupported = AUTH_MODE_WPA; -+ prAuthenticationEncryptionSupported[5].eEncryptStatusSupported = ENUM_ENCRYPTION3_ENABLED; -+ -+ prAuthenticationEncryptionSupported[6].eAuthModeSupported = AUTH_MODE_WPA_PSK; -+ prAuthenticationEncryptionSupported[6].eEncryptStatusSupported = ENUM_ENCRYPTION2_ENABLED; -+ -+ prAuthenticationEncryptionSupported[7].eAuthModeSupported = AUTH_MODE_WPA_PSK; -+ prAuthenticationEncryptionSupported[7].eEncryptStatusSupported = ENUM_ENCRYPTION3_ENABLED; -+ -+ prAuthenticationEncryptionSupported[8].eAuthModeSupported = AUTH_MODE_WPA_NONE; -+ prAuthenticationEncryptionSupported[8].eEncryptStatusSupported = ENUM_ENCRYPTION2_ENABLED; -+ -+ prAuthenticationEncryptionSupported[9].eAuthModeSupported = AUTH_MODE_WPA_NONE; -+ prAuthenticationEncryptionSupported[9].eEncryptStatusSupported = ENUM_ENCRYPTION3_ENABLED; -+ -+ prAuthenticationEncryptionSupported[10].eAuthModeSupported = AUTH_MODE_WPA2; -+ prAuthenticationEncryptionSupported[10].eEncryptStatusSupported = ENUM_ENCRYPTION2_ENABLED; -+ -+ prAuthenticationEncryptionSupported[11].eAuthModeSupported = AUTH_MODE_WPA2; -+ prAuthenticationEncryptionSupported[11].eEncryptStatusSupported = ENUM_ENCRYPTION3_ENABLED; -+ -+ prAuthenticationEncryptionSupported[12].eAuthModeSupported = AUTH_MODE_WPA2_PSK; -+ prAuthenticationEncryptionSupported[12].eEncryptStatusSupported = ENUM_ENCRYPTION2_ENABLED; -+ -+ prAuthenticationEncryptionSupported[13].eAuthModeSupported = AUTH_MODE_WPA2_PSK; -+ prAuthenticationEncryptionSupported[13].eEncryptStatusSupported = ENUM_ENCRYPTION3_ENABLED; -+ -+ return WLAN_STATUS_SUCCESS; -+ -+} /* wlanoidQueryCapability */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to query the PMKID in the PMK cache. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[out] pvQueryBuffer A pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufferLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryPmkid(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ UINT_32 i; -+ P_PARAM_PMKID_T prPmkid; -+ P_AIS_SPECIFIC_BSS_INFO_T prAisSpecBssInfo; -+ -+ DEBUGFUNC("wlanoidQueryPmkid"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4QueryInfoLen); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ -+ prAisSpecBssInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo; -+ -+ *pu4QueryInfoLen = OFFSET_OF(PARAM_PMKID_T, arBSSIDInfo) + -+ prAisSpecBssInfo->u4PmkidCacheCount * sizeof(PARAM_BSSID_INFO_T); -+ -+ if (u4QueryBufferLen < *pu4QueryInfoLen) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ prPmkid = (P_PARAM_PMKID_T) pvQueryBuffer; -+ -+ prPmkid->u4Length = *pu4QueryInfoLen; -+ prPmkid->u4BSSIDInfoCount = prAisSpecBssInfo->u4PmkidCacheCount; -+ -+ for (i = 0; i < prAisSpecBssInfo->u4PmkidCacheCount; i++) { -+ kalMemCopy(prPmkid->arBSSIDInfo[i].arBSSID, -+ prAisSpecBssInfo->arPmkidCache[i].rBssidInfo.arBSSID, sizeof(PARAM_MAC_ADDRESS)); -+ kalMemCopy(prPmkid->arBSSIDInfo[i].arPMKID, -+ prAisSpecBssInfo->arPmkidCache[i].rBssidInfo.arPMKID, sizeof(PARAM_PMKID_VALUE)); -+ } -+ -+ return WLAN_STATUS_SUCCESS; -+ -+} /* wlanoidQueryPmkid */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to set the PMKID to the PMK cache in the driver. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_BUFFER_TOO_SHORT -+* \retval WLAN_STATUS_INVALID_DATA -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetPmkid(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ UINT_32 i, j; -+ P_PARAM_PMKID_T prPmkid; -+ P_AIS_SPECIFIC_BSS_INFO_T prAisSpecBssInfo; -+ -+ DEBUGFUNC("wlanoidSetPmkid"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ *pu4SetInfoLen = u4SetBufferLen; -+ -+ /* It's possibble BSSIDInfoCount is zero, because OS wishes to clean PMKID */ -+ if (u4SetBufferLen < OFFSET_OF(PARAM_PMKID_T, arBSSIDInfo)) -+ return WLAN_STATUS_BUFFER_TOO_SHORT; -+ -+ ASSERT(pvSetBuffer); -+ prPmkid = (P_PARAM_PMKID_T) pvSetBuffer; -+ -+ if (u4SetBufferLen < -+ ((prPmkid->u4BSSIDInfoCount * sizeof(PARAM_BSSID_INFO_T)) + OFFSET_OF(PARAM_PMKID_T, arBSSIDInfo))) -+ return WLAN_STATUS_INVALID_DATA; -+ -+ if (prPmkid->u4BSSIDInfoCount > CFG_MAX_PMKID_CACHE) -+ return WLAN_STATUS_INVALID_DATA; -+ -+ DBGLOG(OID, TRACE, "Count %u\n", prPmkid->u4BSSIDInfoCount); -+ -+ prAisSpecBssInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo; -+ -+ /* This OID replace everything in the PMKID cache. */ -+ if (prPmkid->u4BSSIDInfoCount == 0) { -+ prAisSpecBssInfo->u4PmkidCacheCount = 0; -+ kalMemZero(prAisSpecBssInfo->arPmkidCache, sizeof(PMKID_ENTRY_T) * CFG_MAX_PMKID_CACHE); -+ } -+ if ((prAisSpecBssInfo->u4PmkidCacheCount + prPmkid->u4BSSIDInfoCount > CFG_MAX_PMKID_CACHE)) { -+ prAisSpecBssInfo->u4PmkidCacheCount = 0; -+ kalMemZero(prAisSpecBssInfo->arPmkidCache, sizeof(PMKID_ENTRY_T) * CFG_MAX_PMKID_CACHE); -+ } -+ -+ /* -+ The driver can only clear its PMKID cache whenever it make a media disconnect -+ indication. Otherwise, it must change the PMKID cache only when set through this OID. -+ */ -+#if CFG_RSN_MIGRATION -+ for (i = 0; i < prPmkid->u4BSSIDInfoCount; i++) { -+ /* Search for desired BSSID. If desired BSSID is found, -+ then set the PMKID */ -+ if (!rsnSearchPmkidEntry(prAdapter, (PUINT_8) prPmkid->arBSSIDInfo[i].arBSSID, &j)) { -+ /* No entry found for the specified BSSID, so add one entry */ -+ if (prAisSpecBssInfo->u4PmkidCacheCount < CFG_MAX_PMKID_CACHE - 1) { -+ j = prAisSpecBssInfo->u4PmkidCacheCount; -+ kalMemCopy(prAisSpecBssInfo->arPmkidCache[j].rBssidInfo.arBSSID, -+ prPmkid->arBSSIDInfo[i].arBSSID, sizeof(PARAM_MAC_ADDRESS)); -+ prAisSpecBssInfo->u4PmkidCacheCount++; -+ } else { -+ j = CFG_MAX_PMKID_CACHE; -+ } -+ } -+ -+ if (j < CFG_MAX_PMKID_CACHE) { -+ kalMemCopy(prAisSpecBssInfo->arPmkidCache[j].rBssidInfo.arPMKID, -+ prPmkid->arBSSIDInfo[i].arPMKID, sizeof(PARAM_PMKID_VALUE)); -+ DBGLOG(RSN, TRACE, "Add BSSID %pM idx=%d PMKID value %pM\n", -+ (prAisSpecBssInfo->arPmkidCache[j].rBssidInfo.arBSSID), (UINT_32) j, -+ (prAisSpecBssInfo->arPmkidCache[j].rBssidInfo.arPMKID)); -+ prAisSpecBssInfo->arPmkidCache[j].fgPmkidExist = TRUE; -+ } -+ } -+#endif -+ return WLAN_STATUS_SUCCESS; -+ -+} /* wlanoidSetPmkid */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to query the set of supported data rates that -+* the radio is capable of running -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* \param[out] pvQueryBuffer A pointer to the buffer that holds the result of -+* the query -+* \param[in] u4QueryBufferLen The length of the query buffer -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number -+* of bytes written into the query buffer. If the -+* call failed due to invalid length of the query -+* buffer, returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQuerySupportedRates(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ PARAM_RATES eRate = { -+ /* BSSBasicRateSet for 802.11n Non-HT rates */ -+ 0x8C, /* 6M */ -+ 0x92, /* 9M */ -+ 0x98, /* 12M */ -+ 0xA4, /* 18M */ -+ 0xB0, /* 24M */ -+ 0xC8, /* 36M */ -+ 0xE0, /* 48M */ -+ 0xEC /* 54M */ -+ }; -+ -+ DEBUGFUNC("wlanoidQuerySupportedRates"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4QueryInfoLen); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ -+ *pu4QueryInfoLen = sizeof(PARAM_RATES_EX); -+ -+ if (u4QueryBufferLen < *pu4QueryInfoLen) { -+ DBGLOG(OID, WARN, "Invalid length %u\n", u4QueryBufferLen); -+ return WLAN_STATUS_INVALID_LENGTH; -+ } -+ -+ kalMemCopy(pvQueryBuffer, (PVOID) &eRate, sizeof(PARAM_RATES)); -+ -+ return WLAN_STATUS_SUCCESS; -+} /* end of wlanoidQuerySupportedRates() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to query current desired rates. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvQueryBuffer Pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufferLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryDesiredRates(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ DEBUGFUNC("wlanoidQueryDesiredRates"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4QueryInfoLen); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ -+ *pu4QueryInfoLen = sizeof(PARAM_RATES_EX); -+ -+ if (u4QueryBufferLen < *pu4QueryInfoLen) { -+ DBGLOG(OID, WARN, "Invalid length %u\n", u4QueryBufferLen); -+ return WLAN_STATUS_INVALID_LENGTH; -+ } -+ -+ kalMemCopy(pvQueryBuffer, (PVOID) &(prAdapter->rWlanInfo.eDesiredRates), sizeof(PARAM_RATES)); -+ -+ return WLAN_STATUS_SUCCESS; -+ -+} /* end of wlanoidQueryDesiredRates() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to Set the desired rates. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer Pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+* \retval WLAN_STATUS_INVALID_DATA -+* \retval WLAN_STATUS_ADAPTER_NOT_READY -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetDesiredRates(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ UINT_32 i; -+ -+ DEBUGFUNC("wlanoidSetDesiredRates"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pvSetBuffer); -+ ASSERT(pu4SetInfoLen); -+ -+ if (u4SetBufferLen < sizeof(PARAM_RATES)) { -+ DBGLOG(OID, WARN, "Invalid length %u\n", u4SetBufferLen); -+ return WLAN_STATUS_INVALID_LENGTH; -+ } -+ -+ *pu4SetInfoLen = sizeof(PARAM_RATES); -+ -+ if (u4SetBufferLen < sizeof(PARAM_RATES)) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ kalMemCopy((PVOID) &(prAdapter->rWlanInfo.eDesiredRates), pvSetBuffer, sizeof(PARAM_RATES)); -+ -+ prAdapter->rWlanInfo.eLinkAttr.ucDesiredRateLen = PARAM_MAX_LEN_RATES; -+ for (i = 0; i < PARAM_MAX_LEN_RATES; i++) -+ prAdapter->rWlanInfo.eLinkAttr.u2DesiredRate[i] = (UINT_16) (prAdapter->rWlanInfo.eDesiredRates[i]); -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_LINK_ATTRIB, -+ TRUE, -+ FALSE, -+ TRUE, -+ nicCmdEventSetCommon, -+ nicOidCmdTimeoutCommon, -+ sizeof(CMD_LINK_ATTRIB), -+ (PUINT_8) &(prAdapter->rWlanInfo.eLinkAttr), pvSetBuffer, u4SetBufferLen); -+ -+} /* end of wlanoidSetDesiredRates() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to query the maximum frame size in bytes, -+* not including the header. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[out] pvQueryBuffer A pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufferLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the -+* call failed due to invalid length of the query -+* buffer, returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryMaxFrameSize(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ DEBUGFUNC("wlanoidQueryMaxFrameSize"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4QueryInfoLen); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ -+ if (u4QueryBufferLen < sizeof(UINT_32)) { -+ *pu4QueryInfoLen = sizeof(UINT_32); -+ return WLAN_STATUS_INVALID_LENGTH; -+ } -+ -+ *(PUINT_32) pvQueryBuffer = ETHERNET_MAX_PKT_SZ - ETHERNET_HEADER_SZ; -+ *pu4QueryInfoLen = sizeof(UINT_32); -+ -+ return WLAN_STATUS_SUCCESS; -+} /* wlanoidQueryMaxFrameSize */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to query the maximum total packet length -+* in bytes. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[out] pvQueryBuffer A pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufferLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryMaxTotalSize(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ DEBUGFUNC("wlanoidQueryMaxTotalSize"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4QueryInfoLen); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ -+ if (u4QueryBufferLen < sizeof(UINT_32)) { -+ *pu4QueryInfoLen = sizeof(UINT_32); -+ return WLAN_STATUS_INVALID_LENGTH; -+ } -+ -+ *(PUINT_32) pvQueryBuffer = ETHERNET_MAX_PKT_SZ; -+ *pu4QueryInfoLen = sizeof(UINT_32); -+ -+ return WLAN_STATUS_SUCCESS; -+} /* wlanoidQueryMaxTotalSize */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to query the vendor ID of the NIC. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[out] pvQueryBuffer A pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufferLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryVendorId(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+#if DBG -+ PUINT_8 cp; -+#endif -+ DEBUGFUNC("wlanoidQueryVendorId"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4QueryInfoLen); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ -+ if (u4QueryBufferLen < sizeof(UINT_32)) { -+ *pu4QueryInfoLen = sizeof(UINT_32); -+ return WLAN_STATUS_INVALID_LENGTH; -+ } -+ -+ kalMemCopy(pvQueryBuffer, prAdapter->aucMacAddress, 3); -+ *((PUINT_8) pvQueryBuffer + 3) = 1; -+ *pu4QueryInfoLen = sizeof(UINT_32); -+ -+#if DBG -+ cp = (PUINT_8) pvQueryBuffer; -+ DBGLOG(OID, LOUD, "Vendor ID=%02x-%02x-%02x-%02x\n", cp[0], cp[1], cp[2], cp[3]); -+#endif -+ -+ return WLAN_STATUS_SUCCESS; -+} /* wlanoidQueryVendorId */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to query the current RSSI value. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvQueryBuffer Pointer to the buffer that holds the result of the query. -+* \param[in] u4QueryBufferLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call failed due to invalid length of -+* the query buffer, returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_BUFFER_TOO_SHORT -+* \retval WLAN_STATUS_ADAPTER_NOT_READY -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryRssi(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ DEBUGFUNC("wlanoidQueryRssi"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4QueryInfoLen); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ -+ *pu4QueryInfoLen = sizeof(PARAM_RSSI); -+ -+ /* Check for query buffer length */ -+ if (u4QueryBufferLen < *pu4QueryInfoLen) { -+ DBGLOG(OID, WARN, "Too short length %u\n", u4QueryBufferLen); -+ return WLAN_STATUS_BUFFER_TOO_SHORT; -+ } -+ -+ if (kalGetMediaStateIndicated(prAdapter->prGlueInfo) == PARAM_MEDIA_STATE_DISCONNECTED) { -+ return WLAN_STATUS_ADAPTER_NOT_READY; -+ } else if (prAdapter->fgIsLinkQualityValid == TRUE && -+ (kalGetTimeTick() - prAdapter->rLinkQualityUpdateTime) <= CFG_LINK_QUALITY_VALID_PERIOD) { -+ PARAM_RSSI rRssi; -+ -+ rRssi = (PARAM_RSSI) prAdapter->rLinkQuality.cRssi; /* ranged from (-128 ~ 30) in unit of dBm */ -+ -+ if (rRssi > PARAM_WHQL_RSSI_MAX_DBM) -+ rRssi = PARAM_WHQL_RSSI_MAX_DBM; -+ else if (rRssi < PARAM_WHQL_RSSI_MIN_DBM) -+ rRssi = PARAM_WHQL_RSSI_MIN_DBM; -+ -+ kalMemCopy(pvQueryBuffer, &rRssi, sizeof(PARAM_RSSI)); -+ return WLAN_STATUS_SUCCESS; -+ } -+#ifdef LINUX -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_GET_LINK_QUALITY, -+ FALSE, -+ TRUE, -+ TRUE, -+ nicCmdEventQueryLinkQuality, -+ nicOidCmdTimeoutCommon, -+ *pu4QueryInfoLen, pvQueryBuffer, pvQueryBuffer, u4QueryBufferLen); -+#else -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_GET_LINK_QUALITY, -+ FALSE, -+ TRUE, -+ TRUE, -+ nicCmdEventQueryLinkQuality, -+ nicOidCmdTimeoutCommon, 0, NULL, pvQueryBuffer, u4QueryBufferLen); -+ -+#endif -+} /* end of wlanoidQueryRssi() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to query the current RSSI trigger value. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvQueryBuffer Pointer to the buffer that holds the result of the query. -+* \param[in] u4QueryBufferLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call failed due to invalid length of -+* the query buffer, returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_BUFFER_TOO_SHORT -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryRssiTrigger(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ DEBUGFUNC("wlanoidQueryRssiTrigger"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4QueryInfoLen); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ -+ if (prAdapter->rWlanInfo.eRssiTriggerType == ENUM_RSSI_TRIGGER_NONE) -+ return WLAN_STATUS_ADAPTER_NOT_READY; -+ -+ *pu4QueryInfoLen = sizeof(PARAM_RSSI); -+ -+ /* Check for query buffer length */ -+ if (u4QueryBufferLen < *pu4QueryInfoLen) { -+ DBGLOG(OID, WARN, "Too short length %u\n", u4QueryBufferLen); -+ return WLAN_STATUS_BUFFER_TOO_SHORT; -+ } -+ -+ *(PARAM_RSSI *) pvQueryBuffer = prAdapter->rWlanInfo.rRssiTriggerValue; -+ DBGLOG(OID, INFO, "RSSI trigger: %d dBm\n", *(PARAM_RSSI *) pvQueryBuffer); -+ -+ return WLAN_STATUS_SUCCESS; -+} /* wlanoidQueryRssiTrigger */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to set a trigger value of the RSSI event. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns the -+* amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetRssiTrigger(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ PARAM_RSSI rRssiTriggerValue; -+ -+ DEBUGFUNC("wlanoidSetRssiTrigger"); -+ ASSERT(prAdapter); -+ ASSERT(pvSetBuffer); -+ ASSERT(pu4SetInfoLen); -+ -+ *pu4SetInfoLen = sizeof(PARAM_RSSI); -+ rRssiTriggerValue = *(PARAM_RSSI *) pvSetBuffer; -+ -+ if (rRssiTriggerValue > PARAM_WHQL_RSSI_MAX_DBM || rRssiTriggerValue < PARAM_WHQL_RSSI_MIN_DBM) -+ return -+ /* Save the RSSI trigger value to the Adapter structure */ -+ prAdapter->rWlanInfo.rRssiTriggerValue = rRssiTriggerValue; -+ -+ /* If the RSSI trigger value is equal to the current RSSI value, the -+ * indication triggers immediately. We need to indicate the protocol -+ * that an RSSI status indication event triggers. */ -+ if (rRssiTriggerValue == (PARAM_RSSI) (prAdapter->rLinkQuality.cRssi)) { -+ prAdapter->rWlanInfo.eRssiTriggerType = ENUM_RSSI_TRIGGER_TRIGGERED; -+ -+ kalIndicateStatusAndComplete(prAdapter->prGlueInfo, -+ WLAN_STATUS_MEDIA_SPECIFIC_INDICATION, -+ (PVOID) &prAdapter->rWlanInfo.rRssiTriggerValue, sizeof(PARAM_RSSI)); -+ } else if (rRssiTriggerValue < (PARAM_RSSI) (prAdapter->rLinkQuality.cRssi)) -+ prAdapter->rWlanInfo.eRssiTriggerType = ENUM_RSSI_TRIGGER_GREATER; -+ else if (rRssiTriggerValue > (PARAM_RSSI) (prAdapter->rLinkQuality.cRssi)) -+ prAdapter->rWlanInfo.eRssiTriggerType = ENUM_RSSI_TRIGGER_LESS; -+ -+ return WLAN_STATUS_SUCCESS; -+} /* wlanoidSetRssiTrigger */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to set a suggested value for the number of -+* bytes of received packet data that will be indicated to the protocol -+* driver. We just accept the set and ignore this value. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetCurrentLookahead(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ DEBUGFUNC("wlanoidSetCurrentLookahead"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pvSetBuffer); -+ ASSERT(pu4SetInfoLen); -+ -+ if (u4SetBufferLen < sizeof(UINT_32)) { -+ *pu4SetInfoLen = sizeof(UINT_32); -+ return WLAN_STATUS_INVALID_LENGTH; -+ } -+ -+ *pu4SetInfoLen = sizeof(UINT_32); -+ return WLAN_STATUS_SUCCESS; -+} /* wlanoidSetCurrentLookahead */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to query the number of frames that the driver -+* receives but does not indicate to the protocols due to errors. -+* -+* \param[in] pvAdapter Pointer to the Adapter structure. -+* \param[out] pvQueryBuf A pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+* \retval WLAN_STATUS_ADAPTER_NOT_READY -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryRcvError(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ DEBUGFUNC("wlanoidQueryRcvError"); -+ DBGLOG(OID, LOUD, "\n"); -+ -+ ASSERT(prAdapter); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ ASSERT(pu4QueryInfoLen); -+ -+ if (prAdapter->rAcpiState == ACPI_STATE_D3) { -+ DBGLOG(OID, WARN, "Fail in query receive error! (Adapter not ready). ACPI=D%d, Radio=%d\n", -+ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); -+ *pu4QueryInfoLen = sizeof(UINT_32); -+ return WLAN_STATUS_ADAPTER_NOT_READY; -+ } else if (u4QueryBufferLen < sizeof(UINT_32) -+ || (u4QueryBufferLen > sizeof(UINT_32) && u4QueryBufferLen < sizeof(UINT_64))) { -+ *pu4QueryInfoLen = sizeof(UINT_64); -+ return WLAN_STATUS_INVALID_LENGTH; -+ } -+#if CFG_ENABLE_STATISTICS_BUFFERING -+ if (IsBufferedStatisticsUsable(prAdapter) == TRUE) { -+ /* @FIXME, RX_ERROR_DROP_COUNT/RX_FIFO_FULL_DROP_COUNT is not calculated */ -+ if (u4QueryBufferLen == sizeof(UINT_32)) { -+ *pu4QueryInfoLen = sizeof(UINT_32); -+ *(PUINT_32) pvQueryBuffer = (UINT_32) prAdapter->rStatStruct.rFCSErrorCount.QuadPart; -+ } else { -+ *pu4QueryInfoLen = sizeof(UINT_64); -+ *(PUINT_64) pvQueryBuffer = (UINT_64) prAdapter->rStatStruct.rFCSErrorCount.QuadPart; -+ } -+ -+ return WLAN_STATUS_SUCCESS; -+ } -+#endif -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_GET_STATISTICS, -+ FALSE, -+ TRUE, -+ TRUE, -+ nicCmdEventQueryRecvError, -+ nicOidCmdTimeoutCommon, 0, NULL, pvQueryBuffer, u4QueryBufferLen); -+ -+} /* wlanoidQueryRcvError */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to query the number of frames that the NIC -+* cannot receive due to lack of NIC receive buffer space. -+* -+* \param[in] pvAdapter Pointer to the Adapter structure -+* \param[in] pvQueryBuf A pointer to the buffer that holds the result of the -+* query buffer -+* \param[in] u4QueryBufLen The length of the query buffer -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS If success; -+* \retval WLAN_STATUS_INVALID_LENGTH -+* \retval WLAN_STATUS_ADAPTER_NOT_READY -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryRcvNoBuffer(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ DEBUGFUNC("wlanoidQueryRcvNoBuffer"); -+ DBGLOG(OID, LOUD, "\n"); -+ -+ ASSERT(prAdapter); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ ASSERT(pu4QueryInfoLen); -+ -+ if (prAdapter->rAcpiState == ACPI_STATE_D3) { -+ DBGLOG(OID, WARN, "Fail in query receive error! (Adapter not ready). ACPI=D%d, Radio=%d\n", -+ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); -+ *pu4QueryInfoLen = sizeof(UINT_32); -+ return WLAN_STATUS_ADAPTER_NOT_READY; -+ } else if (u4QueryBufferLen < sizeof(UINT_32) -+ || (u4QueryBufferLen > sizeof(UINT_32) && u4QueryBufferLen < sizeof(UINT_64))) { -+ *pu4QueryInfoLen = sizeof(UINT_64); -+ return WLAN_STATUS_INVALID_LENGTH; -+ } -+#if CFG_ENABLE_STATISTICS_BUFFERING -+ if (IsBufferedStatisticsUsable(prAdapter) == TRUE) { -+ if (u4QueryBufferLen == sizeof(UINT_32)) { -+ *pu4QueryInfoLen = sizeof(UINT_32); -+ *(PUINT_32) pvQueryBuffer = (UINT_32) 0; /* @FIXME */ -+ } else { -+ *pu4QueryInfoLen = sizeof(UINT_64); -+ *(PUINT_64) pvQueryBuffer = (UINT_64) 0; /* @FIXME */ -+ } -+ -+ return WLAN_STATUS_SUCCESS; -+ } -+#endif -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_GET_STATISTICS, -+ FALSE, -+ TRUE, -+ TRUE, -+ nicCmdEventQueryRecvNoBuffer, -+ nicOidCmdTimeoutCommon, 0, NULL, pvQueryBuffer, u4QueryBufferLen); -+ -+} /* wlanoidQueryRcvNoBuffer */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to query the number of frames that the NIC -+* received and it is CRC error. -+* -+* \param[in] pvAdapter Pointer to the Adapter structure -+* \param[in] pvQueryBuf A pointer to the buffer that holds the result of the -+* query buffer -+* \param[in] u4QueryBufLen The length of the query buffer -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS If success; -+* \retval WLAN_STATUS_INVALID_LENGTH -+* \retval WLAN_STATUS_ADAPTER_NOT_READY -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryRcvCrcError(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ DEBUGFUNC("wlanoidQueryRcvCrcError"); -+ DBGLOG(OID, LOUD, "\n"); -+ -+ ASSERT(prAdapter); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ ASSERT(pu4QueryInfoLen); -+ -+ if (prAdapter->rAcpiState == ACPI_STATE_D3) { -+ DBGLOG(OID, WARN, "Fail in query receive error! (Adapter not ready). ACPI=D%d, Radio=%d\n", -+ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); -+ *pu4QueryInfoLen = sizeof(UINT_32); -+ return WLAN_STATUS_ADAPTER_NOT_READY; -+ } else if (u4QueryBufferLen < sizeof(UINT_32) -+ || (u4QueryBufferLen > sizeof(UINT_32) && u4QueryBufferLen < sizeof(UINT_64))) { -+ *pu4QueryInfoLen = sizeof(UINT_64); -+ return WLAN_STATUS_INVALID_LENGTH; -+ } -+#if CFG_ENABLE_STATISTICS_BUFFERING -+ if (IsBufferedStatisticsUsable(prAdapter) == TRUE) { -+ if (u4QueryBufferLen == sizeof(UINT_32)) { -+ *pu4QueryInfoLen = sizeof(UINT_32); -+ *(PUINT_32) pvQueryBuffer = (UINT_32) prAdapter->rStatStruct.rFCSErrorCount.QuadPart; -+ } else { -+ *pu4QueryInfoLen = sizeof(UINT_64); -+ *(PUINT_64) pvQueryBuffer = (UINT_64) prAdapter->rStatStruct.rFCSErrorCount.QuadPart; -+ } -+ -+ return WLAN_STATUS_SUCCESS; -+ } -+#endif -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_GET_STATISTICS, -+ FALSE, -+ TRUE, -+ TRUE, -+ nicCmdEventQueryRecvCrcError, -+ nicOidCmdTimeoutCommon, 0, NULL, pvQueryBuffer, u4QueryBufferLen); -+ -+} /* wlanoidQueryRcvCrcError */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to query the current 802.11 statistics. -+* -+* \param[in] pvAdapter Pointer to the Adapter structure -+* \param[in] pvQueryBuf A pointer to the buffer that holds the result of the -+* query buffer -+* \param[in] u4QueryBufLen The length of the query buffer -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryStatisticsPL(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ DBGLOG(OID, LOUD, "\n"); -+ -+ ASSERT(prAdapter); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ ASSERT(pu4QueryInfoLen); -+ -+ *pu4QueryInfoLen = sizeof(PARAM_802_11_STATISTICS_STRUCT_T); -+ -+ if (prAdapter->rAcpiState == ACPI_STATE_D3) { -+ DBGLOG(OID, WARN, "Fail in query receive error! (Adapter not ready). ACPI=D%d, Radio=%d\n", -+ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); -+ *pu4QueryInfoLen = sizeof(UINT_32); -+ return WLAN_STATUS_ADAPTER_NOT_READY; -+ } else if (u4QueryBufferLen < sizeof(PARAM_802_11_STATISTICS_STRUCT_T)) { -+ DBGLOG(OID, WARN, "Too short length %u\n", u4QueryBufferLen); -+ return WLAN_STATUS_INVALID_LENGTH; -+ } -+#if CFG_ENABLE_STATISTICS_BUFFERING -+ if (IsBufferedStatisticsUsable(prAdapter) == TRUE) { -+ P_PARAM_802_11_STATISTICS_STRUCT_T prStatistics; -+ -+ *pu4QueryInfoLen = sizeof(PARAM_802_11_STATISTICS_STRUCT_T); -+ prStatistics = (P_PARAM_802_11_STATISTICS_STRUCT_T) pvQueryBuffer; -+ -+ prStatistics->u4Length = sizeof(PARAM_802_11_STATISTICS_STRUCT_T); -+ prStatistics->rTransmittedFragmentCount = prAdapter->rStatStruct.rTransmittedFragmentCount; -+ prStatistics->rMulticastTransmittedFrameCount = prAdapter->rStatStruct.rMulticastTransmittedFrameCount; -+ prStatistics->rFailedCount = prAdapter->rStatStruct.rFailedCount; -+ prStatistics->rRetryCount = prAdapter->rStatStruct.rRetryCount; -+ prStatistics->rMultipleRetryCount = prAdapter->rStatStruct.rMultipleRetryCount; -+ prStatistics->rRTSSuccessCount = prAdapter->rStatStruct.rRTSSuccessCount; -+ prStatistics->rRTSFailureCount = prAdapter->rStatStruct.rRTSFailureCount; -+ prStatistics->rACKFailureCount = prAdapter->rStatStruct.rACKFailureCount; -+ prStatistics->rFrameDuplicateCount = prAdapter->rStatStruct.rFrameDuplicateCount; -+ prStatistics->rReceivedFragmentCount = prAdapter->rStatStruct.rReceivedFragmentCount; -+ prStatistics->rMulticastReceivedFrameCount = prAdapter->rStatStruct.rMulticastReceivedFrameCount; -+ prStatistics->rFCSErrorCount = prAdapter->rStatStruct.rFCSErrorCount; -+ prStatistics->rTKIPLocalMICFailures.QuadPart = 0; -+ prStatistics->rTKIPICVErrors.QuadPart = 0; -+ prStatistics->rTKIPCounterMeasuresInvoked.QuadPart = 0; -+ prStatistics->rTKIPReplays.QuadPart = 0; -+ prStatistics->rCCMPFormatErrors.QuadPart = 0; -+ prStatistics->rCCMPReplays.QuadPart = 0; -+ prStatistics->rCCMPDecryptErrors.QuadPart = 0; -+ prStatistics->rFourWayHandshakeFailures.QuadPart = 0; -+ prStatistics->rWEPUndecryptableCount.QuadPart = 0; -+ prStatistics->rWEPICVErrorCount.QuadPart = 0; -+ prStatistics->rDecryptSuccessCount.QuadPart = 0; -+ prStatistics->rDecryptFailureCount.QuadPart = 0; -+ return WLAN_STATUS_SUCCESS; -+ } -+#endif -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_GET_STATISTICS_PL, -+ FALSE, -+ TRUE, -+ TRUE, -+ nicCmdEventQueryStatistics, -+ nicOidCmdTimeoutCommon, 0, NULL, pvQueryBuffer, u4QueryBufferLen); -+ -+} /* wlanoidQueryStatistics */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to query the current 802.11 statistics. -+* -+* \param[in] pvAdapter Pointer to the Adapter structure -+* \param[in] pvQueryBuf A pointer to the buffer that holds the result of the -+* query buffer -+* \param[in] u4QueryBufLen The length of the query buffer -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryStatistics(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ DEBUGFUNC("wlanoidQueryStatistics"); -+ DBGLOG(OID, LOUD, "\n"); -+ -+ ASSERT(prAdapter); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ ASSERT(pu4QueryInfoLen); -+ -+ *pu4QueryInfoLen = sizeof(PARAM_802_11_STATISTICS_STRUCT_T); -+ -+ if (prAdapter->rAcpiState == ACPI_STATE_D3) { -+ DBGLOG(OID, WARN, "Fail in query receive error! (Adapter not ready). ACPI=D%d, Radio=%d\n", -+ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); -+ *pu4QueryInfoLen = sizeof(UINT_32); -+ return WLAN_STATUS_ADAPTER_NOT_READY; -+ } else if (u4QueryBufferLen < sizeof(PARAM_802_11_STATISTICS_STRUCT_T)) { -+ DBGLOG(OID, WARN, "Too short length %u\n", u4QueryBufferLen); -+ return WLAN_STATUS_INVALID_LENGTH; -+ } -+#if CFG_ENABLE_STATISTICS_BUFFERING -+ if (IsBufferedStatisticsUsable(prAdapter) == TRUE) { -+ P_PARAM_802_11_STATISTICS_STRUCT_T prStatistics; -+ -+ *pu4QueryInfoLen = sizeof(PARAM_802_11_STATISTICS_STRUCT_T); -+ prStatistics = (P_PARAM_802_11_STATISTICS_STRUCT_T) pvQueryBuffer; -+ -+ prStatistics->u4Length = sizeof(PARAM_802_11_STATISTICS_STRUCT_T); -+ prStatistics->rTransmittedFragmentCount = prAdapter->rStatStruct.rTransmittedFragmentCount; -+ prStatistics->rMulticastTransmittedFrameCount = prAdapter->rStatStruct.rMulticastTransmittedFrameCount; -+ prStatistics->rFailedCount = prAdapter->rStatStruct.rFailedCount; -+ prStatistics->rRetryCount = prAdapter->rStatStruct.rRetryCount; -+ prStatistics->rMultipleRetryCount = prAdapter->rStatStruct.rMultipleRetryCount; -+ prStatistics->rRTSSuccessCount = prAdapter->rStatStruct.rRTSSuccessCount; -+ prStatistics->rRTSFailureCount = prAdapter->rStatStruct.rRTSFailureCount; -+ prStatistics->rACKFailureCount = prAdapter->rStatStruct.rACKFailureCount; -+ prStatistics->rFrameDuplicateCount = prAdapter->rStatStruct.rFrameDuplicateCount; -+ prStatistics->rReceivedFragmentCount = prAdapter->rStatStruct.rReceivedFragmentCount; -+ prStatistics->rMulticastReceivedFrameCount = prAdapter->rStatStruct.rMulticastReceivedFrameCount; -+ prStatistics->rFCSErrorCount = prAdapter->rStatStruct.rFCSErrorCount; -+ prStatistics->rTKIPLocalMICFailures.QuadPart = 0; -+ prStatistics->rTKIPICVErrors.QuadPart = 0; -+ prStatistics->rTKIPCounterMeasuresInvoked.QuadPart = 0; -+ prStatistics->rTKIPReplays.QuadPart = 0; -+ prStatistics->rCCMPFormatErrors.QuadPart = 0; -+ prStatistics->rCCMPReplays.QuadPart = 0; -+ prStatistics->rCCMPDecryptErrors.QuadPart = 0; -+ prStatistics->rFourWayHandshakeFailures.QuadPart = 0; -+ prStatistics->rWEPUndecryptableCount.QuadPart = 0; -+ prStatistics->rWEPICVErrorCount.QuadPart = 0; -+ prStatistics->rDecryptSuccessCount.QuadPart = 0; -+ prStatistics->rDecryptFailureCount.QuadPart = 0; -+ -+ return WLAN_STATUS_SUCCESS; -+ } -+#endif -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_GET_STATISTICS, -+ FALSE, -+ TRUE, -+ TRUE, -+ nicCmdEventQueryStatistics, -+ nicOidCmdTimeoutCommon, 0, NULL, pvQueryBuffer, u4QueryBufferLen); -+ -+} /* wlanoidQueryStatistics */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to query current media streaming status. -+* -+* \param[in] pvAdapter Pointer to the Adapter structure -+* \param[in] pvQueryBuf A pointer to the buffer that holds the result of the -+* query buffer -+* \param[in] u4QueryBufLen The length of the query buffer -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryMediaStreamMode(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ DEBUGFUNC("wlanoidQueryMediaStreamMode"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4QueryInfoLen); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ -+ *pu4QueryInfoLen = sizeof(ENUM_MEDIA_STREAM_MODE); -+ -+ if (u4QueryBufferLen < *pu4QueryInfoLen) { -+ DBGLOG(OID, WARN, "Invalid length %u\n", u4QueryBufferLen); -+ return WLAN_STATUS_INVALID_LENGTH; -+ } -+ -+ *(P_ENUM_MEDIA_STREAM_MODE) pvQueryBuffer = -+ prAdapter->rWlanInfo.eLinkAttr.ucMediaStreamMode == 0 ? ENUM_MEDIA_STREAM_OFF : ENUM_MEDIA_STREAM_ON; -+ -+ return WLAN_STATUS_SUCCESS; -+ -+} /* wlanoidQueryMediaStreamMode */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to enter media streaming mode or exit media streaming mode -+* -+* \param[in] pvAdapter Pointer to the Adapter structure -+* \param[in] pvQueryBuf A pointer to the buffer that holds the result of the -+* query buffer -+* \param[in] u4QueryBufLen The length of the query buffer -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetMediaStreamMode(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ ENUM_MEDIA_STREAM_MODE eStreamMode; -+ -+ DEBUGFUNC("wlanoidSetMediaStreamMode"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pvSetBuffer); -+ ASSERT(pu4SetInfoLen); -+ -+ if (u4SetBufferLen < sizeof(ENUM_MEDIA_STREAM_MODE)) { -+ DBGLOG(OID, WARN, "Invalid length %u\n", u4SetBufferLen); -+ return WLAN_STATUS_INVALID_LENGTH; -+ } -+ -+ *pu4SetInfoLen = sizeof(ENUM_MEDIA_STREAM_MODE); -+ -+ eStreamMode = *(P_ENUM_MEDIA_STREAM_MODE) pvSetBuffer; -+ -+ if (eStreamMode == ENUM_MEDIA_STREAM_OFF) -+ prAdapter->rWlanInfo.eLinkAttr.ucMediaStreamMode = 0; -+ else -+ prAdapter->rWlanInfo.eLinkAttr.ucMediaStreamMode = 1; -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_LINK_ATTRIB, -+ TRUE, -+ FALSE, -+ TRUE, -+ nicCmdEventSetMediaStreamMode, -+ nicOidCmdTimeoutCommon, -+ sizeof(CMD_LINK_ATTRIB), -+ (PUINT_8) &(prAdapter->rWlanInfo.eLinkAttr), pvSetBuffer, u4SetBufferLen); -+} /* wlanoidSetMediaStreamMode */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to query the permanent MAC address of the NIC. -+* -+* \param[in] pvAdapter Pointer to the Adapter structure -+* \param[in] pvQueryBuf A pointer to the buffer that holds the result of the -+* query buffer -+* \param[in] u4QueryBufLen The length of the query buffer -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryPermanentAddr(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ DEBUGFUNC("wlanoidQueryPermanentAddr"); -+ DBGLOG(OID, LOUD, "\n"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4QueryInfoLen); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ -+ if (u4QueryBufferLen < MAC_ADDR_LEN) -+ return WLAN_STATUS_BUFFER_TOO_SHORT; -+ -+ COPY_MAC_ADDR(pvQueryBuffer, prAdapter->rWifiVar.aucPermanentAddress); -+ *pu4QueryInfoLen = MAC_ADDR_LEN; -+ -+ return WLAN_STATUS_SUCCESS; -+} /* wlanoidQueryPermanentAddr */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to query the MAC address the NIC is currently using. -+* -+* \param[in] pvAdapter Pointer to the Adapter structure -+* \param[in] pvQueryBuf A pointer to the buffer that holds the result of the -+* query buffer -+* \param[in] u4QueryBufLen The length of the query buffer -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_BUFFER_TOO_SHORT -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryCurrentAddr(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ CMD_BASIC_CONFIG rCmdBasicConfig; -+ -+ DEBUGFUNC("wlanoidQueryCurrentAddr"); -+ DBGLOG(OID, LOUD, "\n"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4QueryInfoLen); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ -+ if (u4QueryBufferLen < MAC_ADDR_LEN) -+ return WLAN_STATUS_BUFFER_TOO_SHORT; -+ -+ kalMemZero(&rCmdBasicConfig, sizeof(CMD_BASIC_CONFIG)); -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_BASIC_CONFIG, -+ FALSE, -+ TRUE, -+ TRUE, -+ nicCmdEventQueryAddress, -+ nicOidCmdTimeoutCommon, -+ sizeof(CMD_BASIC_CONFIG), -+ (PUINT_8) &rCmdBasicConfig, pvQueryBuffer, u4QueryBufferLen); -+ -+} /* wlanoidQueryCurrentAddr */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to query NIC link speed. -+* -+* \param[in] pvAdapter Pointer to the Adapter structure -+* \param[in] pvQueryBuf A pointer to the buffer that holds the result of the -+* query buffer -+* \param[in] u4QueryBufLen The length of the query buffer -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_BUFFER_TOO_SHORT -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryLinkSpeed(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ DEBUGFUNC("wlanoidQueryLinkSpeed"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4QueryInfoLen); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ -+ *pu4QueryInfoLen = sizeof(UINT_32); -+ -+ if (u4QueryBufferLen < sizeof(UINT_32)) -+ return WLAN_STATUS_BUFFER_TOO_SHORT; -+ -+ if (kalGetMediaStateIndicated(prAdapter->prGlueInfo) != PARAM_MEDIA_STATE_CONNECTED) { -+ return WLAN_STATUS_ADAPTER_NOT_READY; -+ } else if (prAdapter->fgIsLinkRateValid == TRUE && -+ (kalGetTimeTick() - prAdapter->rLinkRateUpdateTime) <= CFG_LINK_QUALITY_VALID_PERIOD) { -+ *(PUINT_32) pvQueryBuffer = prAdapter->rLinkQuality.u2LinkSpeed * 5000; /* change to unit of 100bps */ -+ return WLAN_STATUS_SUCCESS; -+ } else { -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_GET_LINK_QUALITY, -+ FALSE, -+ TRUE, -+ TRUE, -+ nicCmdEventQueryLinkSpeed, -+ nicOidCmdTimeoutCommon, 0, NULL, pvQueryBuffer, u4QueryBufferLen); -+ } -+} /* end of wlanoidQueryLinkSpeed() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to query MCR value. -+* -+* \param[in] pvAdapter Pointer to the Adapter structure. -+* \param[out] pvQueryBuf A pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryMcrRead(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ P_PARAM_CUSTOM_MCR_RW_STRUCT_T prMcrRdInfo; -+ CMD_ACCESS_REG rCmdAccessReg; -+ -+ DEBUGFUNC("wlanoidQueryMcrRead"); -+ DBGLOG(OID, LOUD, "\n"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4QueryInfoLen); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ -+ *pu4QueryInfoLen = sizeof(PARAM_CUSTOM_MCR_RW_STRUCT_T); -+ -+ if (u4QueryBufferLen < sizeof(PARAM_CUSTOM_MCR_RW_STRUCT_T)) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ prMcrRdInfo = (P_PARAM_CUSTOM_MCR_RW_STRUCT_T) pvQueryBuffer; -+ -+ /* 0x9000 - 0x9EFF reserved for FW */ -+#if CFG_SUPPORT_SWCR -+ if ((prMcrRdInfo->u4McrOffset >> 16) == 0x9F00) { -+ swCrReadWriteCmd(prAdapter, -+ SWCR_READ, -+ (UINT_16) (prMcrRdInfo->u4McrOffset & BITS(0, 15)), &prMcrRdInfo->u4McrData); -+ return WLAN_STATUS_SUCCESS; -+ } -+#endif /* CFG_SUPPORT_SWCR */ -+ -+ /* Check if access F/W Domain MCR (due to WiFiSYS is placed from 0x6000-0000 */ -+ if (prMcrRdInfo->u4McrOffset & 0xFFFF0000) { -+ /* fill command */ -+ rCmdAccessReg.u4Address = prMcrRdInfo->u4McrOffset; -+ rCmdAccessReg.u4Data = 0; -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_ACCESS_REG, -+ FALSE, -+ TRUE, -+ TRUE, -+ nicCmdEventQueryMcrRead, -+ nicOidCmdTimeoutCommon, -+ sizeof(CMD_ACCESS_REG), -+ (PUINT_8) &rCmdAccessReg, pvQueryBuffer, u4QueryBufferLen); -+ } else { -+ HAL_MCR_RD(prAdapter, prMcrRdInfo->u4McrOffset & BITS(2, 31), /* address is in DWORD unit */ -+ &prMcrRdInfo->u4McrData); -+ -+ DBGLOG(OID, TRACE, "MCR Read: Offset = %#08x, Data = %#08x\n", -+ prMcrRdInfo->u4McrOffset, prMcrRdInfo->u4McrData); -+ return WLAN_STATUS_SUCCESS; -+ } -+} /* end of wlanoidQueryMcrRead() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to write MCR and enable specific function. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetMcrWrite(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ P_PARAM_CUSTOM_MCR_RW_STRUCT_T prMcrWrInfo; -+ CMD_ACCESS_REG rCmdAccessReg; -+ -+#if CFG_STRESS_TEST_SUPPORT -+ P_AIS_FSM_INFO_T prAisFsmInfo; -+ P_BSS_INFO_T prBssInfo = &(prAdapter->rWifiVar.arBssInfo[(NETWORK_TYPE_AIS_INDEX)]); -+ P_STA_RECORD_T prStaRec = prBssInfo->prStaRecOfAP; -+ UINT_32 u4McrOffset, u4McrData; -+#endif -+ -+ DEBUGFUNC("wlanoidSetMcrWrite"); -+ DBGLOG(OID, LOUD, "\n"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ *pu4SetInfoLen = sizeof(PARAM_CUSTOM_MCR_RW_STRUCT_T); -+ -+ if (u4SetBufferLen < sizeof(PARAM_CUSTOM_MCR_RW_STRUCT_T)) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ ASSERT(pvSetBuffer); -+ -+ prMcrWrInfo = (P_PARAM_CUSTOM_MCR_RW_STRUCT_T) pvSetBuffer; -+ -+ /* 0x9000 - 0x9EFF reserved for FW */ -+ /* 0xFFFE reserved for FW */ -+ -+ /* -- Puff Stress Test Begin */ -+#if CFG_STRESS_TEST_SUPPORT -+ -+ /* 0xFFFFFFFE for Control Rate */ -+ if (prMcrWrInfo->u4McrOffset == 0xFFFFFFFE) { -+ if (prMcrWrInfo->u4McrData < FIXED_RATE_NUM && prMcrWrInfo->u4McrData > 0) -+ prAdapter->rWifiVar.eRateSetting = (ENUM_REGISTRY_FIXED_RATE_T) (prMcrWrInfo->u4McrData); -+ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); -+ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_3); -+ DEBUGFUNC("[Stress Test]Complete Rate is Changed...\n"); -+ DBGLOG(OID, TRACE, -+ "[Stress Test] Rate is Changed to index %d...\n", prAdapter->rWifiVar.eRateSetting); -+ } -+ /* 0xFFFFFFFD for Switch Channel */ -+ else if (prMcrWrInfo->u4McrOffset == 0xFFFFFFFD) { -+ if (prMcrWrInfo->u4McrData <= 11 && prMcrWrInfo->u4McrData >= 1) -+ prBssInfo->ucPrimaryChannel = prMcrWrInfo->u4McrData; -+ nicUpdateBss(prAdapter, prBssInfo->ucNetTypeIndex); -+ DBGLOG(OID, TRACE, "[Stress Test] Channel is switched to %d ...\n", prBssInfo->ucPrimaryChannel); -+ -+ return WLAN_STATUS_SUCCESS; -+ } -+ /* 0xFFFFFFFFC for Control RF Band and SCO */ -+ else if (prMcrWrInfo->u4McrOffset == 0xFFFFFFFC) { -+ /* Band */ -+ if (prMcrWrInfo->u4McrData & 0x80000000) { -+ /* prBssInfo->eBand = BAND_5G; */ -+ /* prBssInfo->ucPrimaryChannel = 52; // Bond to Channel 52 */ -+ } else { -+ prBssInfo->eBand = BAND_2G4; -+ prBssInfo->ucPrimaryChannel = 8; /* Bond to Channel 6 */ -+ } -+ -+ /* Bandwidth */ -+ if (prMcrWrInfo->u4McrData & 0x00010000) { -+ prStaRec->u2HtCapInfo |= HT_CAP_INFO_SUP_CHNL_WIDTH; -+ prStaRec->ucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; -+ -+ if (prMcrWrInfo->u4McrData == 0x00010002) { -+ prBssInfo->eBssSCO = CHNL_EXT_SCB; /* U20 */ -+ prBssInfo->ucPrimaryChannel += 2; -+ } else if (prMcrWrInfo->u4McrData == 0x00010001) { -+ prBssInfo->eBssSCO = CHNL_EXT_SCA; /* L20 */ -+ prBssInfo->ucPrimaryChannel -= 2; -+ } else { -+ prBssInfo->eBssSCO = CHNL_EXT_SCA; /* 40 */ -+ } -+ } -+ -+ if (prMcrWrInfo->u4McrData & 0x00000000) { -+ prStaRec->u2HtCapInfo &= ~HT_CAP_INFO_SUP_CHNL_WIDTH; -+ prBssInfo->eBssSCO = CHNL_EXT_SCN; -+ } -+ rlmBssInitForAPandIbss(prAdapter, prBssInfo); -+ } -+ /* 0xFFFFFFFB for HT Capability */ -+ else if (prMcrWrInfo->u4McrOffset == 0xFFFFFFFB) { -+ /* Enable HT Capability */ -+ if (prMcrWrInfo->u4McrData & 0x00000001) { -+ prStaRec->u2HtCapInfo |= HT_CAP_INFO_HT_GF; -+ DEBUGFUNC("[Stress Test]Enable HT capability...\n"); -+ } else { -+ prStaRec->u2HtCapInfo &= (~HT_CAP_INFO_HT_GF); -+ DEBUGFUNC("[Stress Test]Disable HT capability...\n"); -+ } -+ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); -+ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_3); -+ } -+ /* 0xFFFFFFFA for Enable Random Rx Reset */ -+ else if (prMcrWrInfo->u4McrOffset == 0xFFFFFFFA) { -+ rCmdAccessReg.u4Address = prMcrWrInfo->u4McrOffset; -+ rCmdAccessReg.u4Data = prMcrWrInfo->u4McrData; -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_RANDOM_RX_RESET_EN, -+ TRUE, -+ FALSE, -+ TRUE, -+ nicCmdEventSetCommon, -+ nicOidCmdTimeoutCommon, -+ sizeof(CMD_ACCESS_REG), -+ (PUINT_8) &rCmdAccessReg, pvSetBuffer, u4SetBufferLen); -+ } -+ /* 0xFFFFFFF9 for Disable Random Rx Reset */ -+ else if (prMcrWrInfo->u4McrOffset == 0xFFFFFFF9) { -+ rCmdAccessReg.u4Address = prMcrWrInfo->u4McrOffset; -+ rCmdAccessReg.u4Data = prMcrWrInfo->u4McrData; -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_RANDOM_RX_RESET_DE, -+ TRUE, -+ FALSE, -+ TRUE, -+ nicCmdEventSetCommon, -+ nicOidCmdTimeoutCommon, -+ sizeof(CMD_ACCESS_REG), -+ (PUINT_8) &rCmdAccessReg, pvSetBuffer, u4SetBufferLen); -+ } -+ /* 0xFFFFFFF8 for Enable SAPP */ -+ else if (prMcrWrInfo->u4McrOffset == 0xFFFFFFF8) { -+ rCmdAccessReg.u4Address = prMcrWrInfo->u4McrOffset; -+ rCmdAccessReg.u4Data = prMcrWrInfo->u4McrData; -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SAPP_EN, -+ TRUE, -+ FALSE, -+ TRUE, -+ nicCmdEventSetCommon, -+ nicOidCmdTimeoutCommon, -+ sizeof(CMD_ACCESS_REG), -+ (PUINT_8) &rCmdAccessReg, pvSetBuffer, u4SetBufferLen); -+ } -+ /* 0xFFFFFFF7 for Disable SAPP */ -+ else if (prMcrWrInfo->u4McrOffset == 0xFFFFFFF7) { -+ rCmdAccessReg.u4Address = prMcrWrInfo->u4McrOffset; -+ rCmdAccessReg.u4Data = prMcrWrInfo->u4McrData; -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SAPP_DE, -+ TRUE, -+ FALSE, -+ TRUE, -+ nicCmdEventSetCommon, -+ nicOidCmdTimeoutCommon, -+ sizeof(CMD_ACCESS_REG), -+ (PUINT_8) &rCmdAccessReg, pvSetBuffer, u4SetBufferLen); -+ } -+ -+ else -+#endif -+ /* -- Puff Stress Test End */ -+ -+ /* Check if access F/W Domain MCR */ -+ if (prMcrWrInfo->u4McrOffset & 0xFFFF0000) { -+ -+ /* 0x9000 - 0x9EFF reserved for FW */ -+#if CFG_SUPPORT_SWCR -+ if ((prMcrWrInfo->u4McrOffset >> 16) == 0x9F00) { -+ swCrReadWriteCmd(prAdapter, -+ SWCR_WRITE, -+ (UINT_16) (prMcrWrInfo->u4McrOffset & BITS(0, 15)), &prMcrWrInfo->u4McrData); -+ return WLAN_STATUS_SUCCESS; -+ } -+#endif /* CFG_SUPPORT_SWCR */ -+ -+#if 1 -+ /* low power test special command */ -+ if (prMcrWrInfo->u4McrOffset == 0x11111110) { -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ /* DbgPrint("Enter test mode\n"); */ -+ prAdapter->fgTestMode = TRUE; -+ return rStatus; -+ } -+ if (prMcrWrInfo->u4McrOffset == 0x11111111) { -+ /* DbgPrint("nicpmSetAcpiPowerD3\n"); */ -+ -+ nicpmSetAcpiPowerD3(prAdapter); -+ kalDevSetPowerState(prAdapter->prGlueInfo, (UINT_32) ParamDeviceStateD3); -+ return WLAN_STATUS_SUCCESS; -+ } -+ if (prMcrWrInfo->u4McrOffset == 0x11111112) { -+ -+ /* DbgPrint("LP enter sleep\n"); */ -+ -+ /* fill command */ -+ rCmdAccessReg.u4Address = prMcrWrInfo->u4McrOffset; -+ rCmdAccessReg.u4Data = prMcrWrInfo->u4McrData; -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_ACCESS_REG, -+ TRUE, -+ FALSE, -+ TRUE, -+ nicCmdEventSetCommon, -+ nicOidCmdTimeoutCommon, -+ sizeof(CMD_ACCESS_REG), -+ (PUINT_8) &rCmdAccessReg, pvSetBuffer, u4SetBufferLen); -+ } -+#endif -+ -+#if 1 -+ /* low power test special command */ -+ if (prMcrWrInfo->u4McrOffset == 0x11111110) { -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ /* DbgPrint("Enter test mode\n"); */ -+ prAdapter->fgTestMode = TRUE; -+ return rStatus; -+ } -+ if (prMcrWrInfo->u4McrOffset == 0x11111111) { -+ /* DbgPrint("nicpmSetAcpiPowerD3\n"); */ -+ -+ nicpmSetAcpiPowerD3(prAdapter); -+ kalDevSetPowerState(prAdapter->prGlueInfo, (UINT_32) ParamDeviceStateD3); -+ return WLAN_STATUS_SUCCESS; -+ } -+ if (prMcrWrInfo->u4McrOffset == 0x11111112) { -+ -+ /* DbgPrint("LP enter sleep\n"); */ -+ -+ /* fill command */ -+ rCmdAccessReg.u4Address = prMcrWrInfo->u4McrOffset; -+ rCmdAccessReg.u4Data = prMcrWrInfo->u4McrData; -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_ACCESS_REG, -+ TRUE, -+ FALSE, -+ TRUE, -+ nicCmdEventSetCommon, -+ nicOidCmdTimeoutCommon, -+ sizeof(CMD_ACCESS_REG), -+ (PUINT_8) &rCmdAccessReg, pvSetBuffer, u4SetBufferLen); -+ } -+#endif -+ /* fill command */ -+ rCmdAccessReg.u4Address = prMcrWrInfo->u4McrOffset; -+ rCmdAccessReg.u4Data = prMcrWrInfo->u4McrData; -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_ACCESS_REG, -+ TRUE, -+ FALSE, -+ TRUE, -+ nicCmdEventSetCommon, -+ nicOidCmdTimeoutCommon, -+ sizeof(CMD_ACCESS_REG), -+ (PUINT_8) &rCmdAccessReg, pvSetBuffer, u4SetBufferLen); -+ } else { -+ HAL_MCR_WR(prAdapter, (prMcrWrInfo->u4McrOffset & BITS(2, 31)), /* address is in DWORD unit */ -+ prMcrWrInfo->u4McrData); -+ -+ DBGLOG(OID, TRACE, "MCR Write: Offset = %#08x, Data = %#08x\n", -+ prMcrWrInfo->u4McrOffset, prMcrWrInfo->u4McrData); -+ -+ return WLAN_STATUS_SUCCESS; -+ } -+} /* wlanoidSetMcrWrite */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to query SW CTRL -+* -+* \param[in] pvAdapter Pointer to the Adapter structure. -+* \param[out] pvQueryBuf A pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQuerySwCtrlRead(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ P_PARAM_CUSTOM_SW_CTRL_STRUCT_T prSwCtrlInfo; -+ WLAN_STATUS rWlanStatus; -+ UINT_16 u2Id, u2SubId; -+ UINT_32 u4Data; -+ -+ CMD_SW_DBG_CTRL_T rCmdSwCtrl; -+ -+ DEBUGFUNC("wlanoidQuerySwCtrlRead"); -+ DBGLOG(OID, LOUD, "\n"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4QueryInfoLen); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ -+ *pu4QueryInfoLen = sizeof(PARAM_CUSTOM_SW_CTRL_STRUCT_T); -+ -+ if (u4QueryBufferLen < sizeof(PARAM_CUSTOM_SW_CTRL_STRUCT_T)) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ prSwCtrlInfo = (P_PARAM_CUSTOM_SW_CTRL_STRUCT_T) pvQueryBuffer; -+ -+ u2Id = (UINT_16) (prSwCtrlInfo->u4Id >> 16); -+ u2SubId = (UINT_16) (prSwCtrlInfo->u4Id & BITS(0, 15)); -+ u4Data = 0; -+ rWlanStatus = WLAN_STATUS_SUCCESS; -+ -+ switch (u2Id) { -+ /* 0x9000 - 0x9EFF reserved for FW */ -+ /* 0xFFFE reserved for FW */ -+ -+#if CFG_SUPPORT_SWCR -+ case 0x9F00: -+ swCrReadWriteCmd(prAdapter, SWCR_READ /* Read */ , -+ (UINT_16) u2SubId, &u4Data); -+ break; -+#endif /* CFG_SUPPORT_SWCR */ -+ -+ case 0xFFFF: -+ { -+ u4Data = 0x5AA56620; -+ } -+ break; -+ -+ case 0x9000: -+ default: -+ { -+ rCmdSwCtrl.u4Id = prSwCtrlInfo->u4Id; -+ rCmdSwCtrl.u4Data = 0; -+ rWlanStatus = wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SW_DBG_CTRL, -+ FALSE, -+ TRUE, -+ TRUE, -+ nicCmdEventQuerySwCtrlRead, -+ nicOidCmdTimeoutCommon, -+ sizeof(CMD_SW_DBG_CTRL_T), -+ (PUINT_8) &rCmdSwCtrl, pvQueryBuffer, u4QueryBufferLen); -+ } -+ } /* switch(u2Id) */ -+ -+ prSwCtrlInfo->u4Data = u4Data; -+ -+ return rWlanStatus; -+ -+} -+ -+ /* end of wlanoidQuerySwCtrlRead() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to write SW CTRL -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetSwCtrlWrite(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ P_PARAM_CUSTOM_SW_CTRL_STRUCT_T prSwCtrlInfo; -+ CMD_SW_DBG_CTRL_T rCmdSwCtrl; -+ WLAN_STATUS rWlanStatus; -+ UINT_16 u2Id, u2SubId; -+ UINT_32 u4Data; -+#if CFG_SUPPORT_HOTSPOT_OPTIMIZATION -+ P_GLUE_INFO_T prGlueInfo; -+ CMD_HOTSPOT_OPTIMIZATION_CONFIG arHotspotOptimizationCfg; -+#endif -+ -+ DEBUGFUNC("wlanoidSetSwCtrlWrite"); -+ DBGLOG(OID, LOUD, "\n"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+#if CFG_SUPPORT_HOTSPOT_OPTIMIZATION -+ prGlueInfo = prAdapter->prGlueInfo; -+#endif -+ -+ *pu4SetInfoLen = sizeof(PARAM_CUSTOM_SW_CTRL_STRUCT_T); -+ -+ if (u4SetBufferLen < sizeof(PARAM_CUSTOM_SW_CTRL_STRUCT_T)) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ ASSERT(pvSetBuffer); -+ -+ prSwCtrlInfo = (P_PARAM_CUSTOM_SW_CTRL_STRUCT_T) pvSetBuffer; -+ -+ u2Id = (UINT_16) (prSwCtrlInfo->u4Id >> 16); -+ u2SubId = (UINT_16) (prSwCtrlInfo->u4Id & BITS(0, 15)); -+ u4Data = prSwCtrlInfo->u4Data; -+ rWlanStatus = WLAN_STATUS_SUCCESS; -+ -+ switch (u2Id) { -+ -+ /* 0x9000 - 0x9EFF reserved for FW */ -+ /* 0xFFFE reserved for FW */ -+ -+#if CFG_SUPPORT_SWCR -+ case 0x9F00: -+ swCrReadWriteCmd(prAdapter, SWCR_WRITE, (UINT_16) u2SubId, &u4Data); -+ break; -+#endif /* CFG_SUPPORT_SWCR */ -+ -+ case 0x1000: -+ if (u2SubId == 0x8000) { -+ /* CTIA power save mode setting (code: 0x10008000) */ -+ prAdapter->u4CtiaPowerMode = u4Data; -+ prAdapter->fgEnCtiaPowerMode = TRUE; -+ -+ /* */ -+ { -+ PARAM_POWER_MODE ePowerMode; -+ -+ if (prAdapter->u4CtiaPowerMode == 0) -+ /* force to keep in CAM mode */ -+ ePowerMode = Param_PowerModeCAM; -+ else if (prAdapter->u4CtiaPowerMode == 1) -+ ePowerMode = Param_PowerModeMAX_PSP; -+ else -+ ePowerMode = Param_PowerModeFast_PSP; -+ -+ rWlanStatus = nicConfigPowerSaveProfile(prAdapter, -+ NETWORK_TYPE_AIS_INDEX, ePowerMode, TRUE); -+ } -+ } -+ break; -+ case 0x1001: -+ if (u2SubId == 0x0) -+ prAdapter->fgEnOnlineScan = (BOOLEAN) u4Data; -+ else if (u2SubId == 0x1) -+ prAdapter->fgDisBcnLostDetection = (BOOLEAN) u4Data; -+ else if (u2SubId == 0x2) -+ prAdapter->rWifiVar.fgSupportUAPSD = (BOOLEAN) u4Data; -+ else if (u2SubId == 0x3) { -+ prAdapter->u4UapsdAcBmp = u4Data & BITS(0, 15); -+ prAdapter->rWifiVar.arBssInfo[u4Data >> 16].rPmProfSetupInfo.ucBmpDeliveryAC = -+ (UINT_8) prAdapter->u4UapsdAcBmp; -+ prAdapter->rWifiVar.arBssInfo[u4Data >> 16].rPmProfSetupInfo.ucBmpTriggerAC = -+ (UINT_8) prAdapter->u4UapsdAcBmp; -+ } else if (u2SubId == 0x4) -+ prAdapter->fgDisStaAgingTimeoutDetection = (BOOLEAN) u4Data; -+ else if (u2SubId == 0x5) -+ prAdapter->rWifiVar.rConnSettings.uc2G4BandwidthMode = (UINT_8) u4Data; -+ else if (u2SubId == 0x0100) -+ prAdapter->rWifiVar.u8SupportRxGf = (UINT_8) u4Data; -+ else if (u2SubId == 0x0101) { -+ prAdapter->rWifiVar.u8SupportRxSgi20 = (UINT_8) u4Data; -+ prAdapter->rWifiVar.u8SupportRxSgi40 = (UINT_8) u4Data; -+ } else if (u2SubId == 0x0102) -+ prAdapter->rWifiVar.u8SupportRxSTBC = (UINT_8) u4Data; -+ break; -+ -+#if CFG_SUPPORT_SWCR -+ case 0x1002: -+ if (u2SubId == 0x0) { -+ if (u4Data) -+ u4Data = BIT(HIF_RX_PKT_TYPE_MANAGEMENT); -+ swCrFrameCheckEnable(prAdapter, u4Data); -+ } else if (u2SubId == 0x1) { -+ BOOLEAN fgIsEnable; -+ UINT_8 ucType; -+ UINT_32 u4Timeout; -+ -+ fgIsEnable = (BOOLEAN) (u4Data & 0xff); -+ ucType = 0; /* ((u4Data>>4) & 0xf); */ -+ u4Timeout = ((u4Data >> 8) & 0xff); -+ swCrDebugCheckEnable(prAdapter, fgIsEnable, ucType, u4Timeout); -+ } -+ break; -+#endif -+ -+#if CFG_SUPPORT_802_11W -+ case 0x2000: -+ DBGLOG(RSN, TRACE, "802.11w test 0x%x\n", u2SubId); -+ if (u2SubId == 0x0) -+ rsnStartSaQuery(prAdapter); -+ if (u2SubId == 0x1) -+ rsnStopSaQuery(prAdapter); -+ if (u2SubId == 0x2) -+ rsnSaQueryRequest(prAdapter, NULL); -+ if (u2SubId == 0x3) { -+ P_BSS_INFO_T prBssInfo = &(prAdapter->rWifiVar.arBssInfo[(NETWORK_TYPE_AIS_INDEX)]); -+ -+ authSendDeauthFrame(prAdapter, prBssInfo->prStaRecOfAP, NULL, 7, NULL); -+ } -+ /* wext_set_mode */ -+ /* -+ if (u2SubId == 0x3) { -+ prAdapter->prGlueInfo->rWpaInfo.u4Mfp = RSN_AUTH_MFP_DISABLED; -+ } -+ if (u2SubId == 0x4) { -+ //prAdapter->rWifiVar.rAisSpecificBssInfo.fgMgmtProtection = TRUE; -+ prAdapter->prGlueInfo->rWpaInfo.u4Mfp = RSN_AUTH_MFP_OPTIONAL; -+ } -+ if (u2SubId == 0x5) { -+ //prAdapter->rWifiVar.rAisSpecificBssInfo.fgMgmtProtection = TRUE; -+ prAdapter->prGlueInfo->rWpaInfo.u4Mfp = RSN_AUTH_MFP_REQUIRED; -+ } -+ */ -+ break; -+#endif -+ case 0xFFFF: -+ { -+/* CMD_ACCESS_REG rCmdAccessReg; */ -+#if 1 /* CFG_MT6573_SMT_TEST */ -+ if (u2SubId == 0x0123) { -+ -+ DBGLOG(HAL, TRACE, "set smt fixed rate: %u\n", u4Data); -+ -+ if ((ENUM_REGISTRY_FIXED_RATE_T) (u4Data) < FIXED_RATE_NUM) -+ prAdapter->rWifiVar.eRateSetting = (ENUM_REGISTRY_FIXED_RATE_T) (u4Data); -+ else -+ prAdapter->rWifiVar.eRateSetting = FIXED_RATE_NONE; -+ -+ if (prAdapter->rWifiVar.eRateSetting == FIXED_RATE_NONE) -+ /* Enable Auto (Long/Short) Preamble */ -+ prAdapter->rWifiVar.ePreambleType = PREAMBLE_TYPE_AUTO; -+ else if ((prAdapter->rWifiVar.eRateSetting >= FIXED_RATE_MCS0_20M_400NS && -+ prAdapter->rWifiVar.eRateSetting <= FIXED_RATE_MCS7_20M_400NS) -+ || (prAdapter->rWifiVar.eRateSetting >= FIXED_RATE_MCS0_40M_400NS && -+ prAdapter->rWifiVar.eRateSetting <= FIXED_RATE_MCS32_400NS)) -+ /* Force Short Preamble */ -+ prAdapter->rWifiVar.ePreambleType = PREAMBLE_TYPE_SHORT; -+ else -+ /* Force Long Preamble */ -+ prAdapter->rWifiVar.ePreambleType = PREAMBLE_TYPE_LONG; -+ -+ /* abort to re-connect */ -+#if 1 -+ DBGLOG(OID, TRACE, "DisBySwC\n"); -+ kalIndicateStatusAndComplete(prAdapter->prGlueInfo, -+ WLAN_STATUS_MEDIA_DISCONNECT, NULL, 0); -+#else -+ aisBssBeaconTimeout(prAdapter); -+#endif -+ -+ return WLAN_STATUS_SUCCESS; -+ -+ } else if (u2SubId == 0x1234) { -+ /* 1. Disable On-Lin Scan */ -+ /* 3. Disable FIFO FULL no ack */ -+ /* 4. Disable Roaming */ -+ /* Disalbe auto tx power */ -+ /* 2. Keep at CAM mode */ -+ /* 5. Disable Beacon Timeout Detection */ -+ rWlanStatus = nicEnterCtiaMode(prAdapter, TRUE, TRUE); -+ } else if (u2SubId == 0x1235) { -+ /* 1. Enaable On-Lin Scan */ -+ /* 3. Enable FIFO FULL no ack */ -+ /* 4. Enable Roaming */ -+ /* Enable auto tx power */ -+ /* 2. Keep at Fast PS */ -+ /* 5. Enable Beacon Timeout Detection */ -+ rWlanStatus = nicEnterCtiaMode(prAdapter, FALSE, TRUE); -+ } -+#if CFG_SUPPORT_HOTSPOT_OPTIMIZATION -+ else if (u2SubId == 0x1240) { -+ DBGLOG(P2P, TRACE, "Disable Hotspot Optimization!\n"); -+ -+ arHotspotOptimizationCfg.fgHotspotOptimizationEn = FALSE; -+ arHotspotOptimizationCfg.u4Level = 0; -+ wlanoidSendSetQueryP2PCmd(prAdapter, -+ CMD_ID_SET_HOTSPOT_OPTIMIZATION, -+ TRUE, -+ FALSE, -+ TRUE, -+ NULL, -+ NULL, -+ sizeof(CMD_HOTSPOT_OPTIMIZATION_CONFIG), -+ (PUINT_8) &arHotspotOptimizationCfg, NULL, 0); -+ } else if (u2SubId == 0x1241) { -+ DBGLOG(P2P, TRACE, "Enable Hotspot Optimization!\n"); -+ -+ arHotspotOptimizationCfg.fgHotspotOptimizationEn = TRUE; -+ arHotspotOptimizationCfg.u4Level = 5; -+ wlanoidSendSetQueryP2PCmd(prAdapter, -+ CMD_ID_SET_HOTSPOT_OPTIMIZATION, -+ TRUE, -+ FALSE, -+ TRUE, -+ NULL, -+ NULL, -+ sizeof(CMD_HOTSPOT_OPTIMIZATION_CONFIG), -+ (PUINT_8) &arHotspotOptimizationCfg, NULL, 0); -+ } -+#endif /* CFG_SUPPORT_HOTSPOT_OPTIMIZATION */ -+ else if (u2SubId == 0x1250) { -+ DBGLOG(OID, TRACE, "LTE_COEX: SW SET DUAL BAND\n"); -+ prAdapter->aePreferBand[NETWORK_TYPE_AIS_INDEX] = BAND_NULL; -+ } else if (u2SubId == 0x1251) { -+ DBGLOG(OID, TRACE, "LTE_COEX: SW SET 2.4G BAND\n"); -+ prAdapter->aePreferBand[NETWORK_TYPE_AIS_INDEX] = BAND_2G4; -+ } else if (u2SubId == 0x1252) { -+ DBGLOG(OID, TRACE, "LTE_COEX: SW SET 5G BAND\n"); -+ prAdapter->aePreferBand[NETWORK_TYPE_AIS_INDEX] = BAND_5G; -+ } -+#endif -+ } -+ break; -+ -+ case 0x9000: -+ default: -+ { -+ rCmdSwCtrl.u4Id = prSwCtrlInfo->u4Id; -+ rCmdSwCtrl.u4Data = prSwCtrlInfo->u4Data; -+ rWlanStatus = wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SW_DBG_CTRL, -+ TRUE, -+ FALSE, -+ TRUE, -+ nicCmdEventSetCommon, -+ nicOidCmdTimeoutCommon, -+ sizeof(CMD_SW_DBG_CTRL_T), -+ (PUINT_8) &rCmdSwCtrl, pvSetBuffer, u4SetBufferLen); -+ } -+ } /* switch(u2Id) */ -+ -+ return rWlanStatus; -+} -+ -+ /* wlanoidSetSwCtrlWrite */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to query EEPROM value. -+* -+* \param[in] pvAdapter Pointer to the Adapter structure. -+* \param[out] pvQueryBuf A pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_FAILURE -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryEepromRead(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ P_PARAM_CUSTOM_EEPROM_RW_STRUCT_T prEepromRwInfo; -+ CMD_ACCESS_EEPROM rCmdAccessEeprom; -+ -+ DEBUGFUNC("wlanoidQueryEepromRead"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4QueryInfoLen); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ -+ *pu4QueryInfoLen = sizeof(PARAM_CUSTOM_EEPROM_RW_STRUCT_T); -+ -+ if (u4QueryBufferLen < sizeof(PARAM_CUSTOM_EEPROM_RW_STRUCT_T)) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ prEepromRwInfo = (P_PARAM_CUSTOM_EEPROM_RW_STRUCT_T) pvQueryBuffer; -+ -+ kalMemZero(&rCmdAccessEeprom, sizeof(CMD_ACCESS_EEPROM)); -+ rCmdAccessEeprom.u2Offset = prEepromRwInfo->ucEepromIndex; -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_ACCESS_EEPROM, -+ FALSE, -+ TRUE, -+ TRUE, -+ nicCmdEventQueryEepromRead, -+ nicOidCmdTimeoutCommon, -+ sizeof(CMD_ACCESS_EEPROM), -+ (PUINT_8) &rCmdAccessEeprom, pvQueryBuffer, u4QueryBufferLen); -+ -+} /* wlanoidQueryEepromRead */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to write EEPROM value. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_FAILURE -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetEepromWrite(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ P_PARAM_CUSTOM_EEPROM_RW_STRUCT_T prEepromRwInfo; -+ CMD_ACCESS_EEPROM rCmdAccessEeprom; -+ -+ DEBUGFUNC("wlanoidSetEepromWrite"); -+ DBGLOG(OID, LOUD, "\n"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ *pu4SetInfoLen = sizeof(PARAM_CUSTOM_EEPROM_RW_STRUCT_T); -+ -+ if (u4SetBufferLen < sizeof(PARAM_CUSTOM_EEPROM_RW_STRUCT_T)) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ ASSERT(pvSetBuffer); -+ -+ prEepromRwInfo = (P_PARAM_CUSTOM_EEPROM_RW_STRUCT_T) pvSetBuffer; -+ -+ kalMemZero(&rCmdAccessEeprom, sizeof(CMD_ACCESS_EEPROM)); -+ rCmdAccessEeprom.u2Offset = prEepromRwInfo->ucEepromIndex; -+ rCmdAccessEeprom.u2Data = prEepromRwInfo->u2EepromData; -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_ACCESS_EEPROM, -+ TRUE, -+ FALSE, -+ TRUE, -+ nicCmdEventSetCommon, -+ nicOidCmdTimeoutCommon, -+ sizeof(CMD_ACCESS_EEPROM), -+ (PUINT_8) &rCmdAccessEeprom, pvSetBuffer, u4SetBufferLen); -+ -+} /* wlanoidSetEepromWrite */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to query the number of the successfully transmitted -+* packets. -+* -+* \param[in] pvAdapter Pointer to the Adapter structure. -+* \param[out] pvQueryBuf A pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryXmitOk(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ DEBUGFUNC("wlanoidQueryXmitOk"); -+ DBGLOG(OID, LOUD, "\n"); -+ -+ ASSERT(prAdapter); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ ASSERT(pu4QueryInfoLen); -+ -+ if (prAdapter->rAcpiState == ACPI_STATE_D3) { -+ DBGLOG(OID, WARN, "Fail in query receive error! (Adapter not ready). ACPI=D%d, Radio=%d\n", -+ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); -+ *pu4QueryInfoLen = sizeof(UINT_32); -+ return WLAN_STATUS_ADAPTER_NOT_READY; -+ } else if (u4QueryBufferLen < sizeof(UINT_32) -+ || (u4QueryBufferLen > sizeof(UINT_32) && u4QueryBufferLen < sizeof(UINT_64))) { -+ *pu4QueryInfoLen = sizeof(UINT_64); -+ return WLAN_STATUS_INVALID_LENGTH; -+ } -+#if CFG_ENABLE_STATISTICS_BUFFERING -+ if (IsBufferedStatisticsUsable(prAdapter) == TRUE) { -+ if (u4QueryBufferLen == sizeof(UINT_32)) { -+ *pu4QueryInfoLen = sizeof(UINT_32); -+ *(PUINT_32) pvQueryBuffer = (UINT_32) prAdapter->rStatStruct.rTransmittedFragmentCount.QuadPart; -+ } else { -+ *pu4QueryInfoLen = sizeof(UINT_64); -+ *(PUINT_64) pvQueryBuffer = (UINT_64) prAdapter->rStatStruct.rTransmittedFragmentCount.QuadPart; -+ } -+ -+ return WLAN_STATUS_SUCCESS; -+ } -+#endif -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_GET_STATISTICS, -+ FALSE, -+ TRUE, -+ TRUE, -+ nicCmdEventQueryXmitOk, -+ nicOidCmdTimeoutCommon, 0, NULL, pvQueryBuffer, u4QueryBufferLen); -+ -+} /* wlanoidQueryXmitOk */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to query the number of the successfully received -+* packets. -+* -+* \param[in] pvAdapter Pointer to the Adapter structure. -+* \param[out] pvQueryBuf A pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryRcvOk(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ DEBUGFUNC("wlanoidQueryRcvOk"); -+ DBGLOG(OID, LOUD, "\n"); -+ -+ ASSERT(prAdapter); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ ASSERT(pu4QueryInfoLen); -+ -+ if (prAdapter->rAcpiState == ACPI_STATE_D3) { -+ DBGLOG(OID, WARN, "Fail in query receive error! (Adapter not ready). ACPI=D%d, Radio=%d\n", -+ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); -+ *pu4QueryInfoLen = sizeof(UINT_32); -+ return WLAN_STATUS_ADAPTER_NOT_READY; -+ } else if (u4QueryBufferLen < sizeof(UINT_32) -+ || (u4QueryBufferLen > sizeof(UINT_32) && u4QueryBufferLen < sizeof(UINT_64))) { -+ *pu4QueryInfoLen = sizeof(UINT_64); -+ return WLAN_STATUS_INVALID_LENGTH; -+ } -+#if CFG_ENABLE_STATISTICS_BUFFERING -+ if (IsBufferedStatisticsUsable(prAdapter) == TRUE) { -+ if (u4QueryBufferLen == sizeof(UINT_32)) { -+ *pu4QueryInfoLen = sizeof(UINT_32); -+ *(PUINT_32) pvQueryBuffer = (UINT_32) prAdapter->rStatStruct.rReceivedFragmentCount.QuadPart; -+ } else { -+ *pu4QueryInfoLen = sizeof(UINT_64); -+ *(PUINT_64) pvQueryBuffer = (UINT_64) prAdapter->rStatStruct.rReceivedFragmentCount.QuadPart; -+ } -+ -+ return WLAN_STATUS_SUCCESS; -+ } -+#endif -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_GET_STATISTICS, -+ FALSE, -+ TRUE, -+ TRUE, -+ nicCmdEventQueryRecvOk, -+ nicOidCmdTimeoutCommon, 0, NULL, pvQueryBuffer, u4QueryBufferLen); -+ -+} /* wlanoidQueryRcvOk */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to query the number of frames that the driver -+* fails to transmit. -+* -+* \param[in] pvAdapter Pointer to the Adapter structure. -+* \param[out] pvQueryBuf A pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryXmitError(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ DEBUGFUNC("wlanoidQueryXmitError"); -+ DBGLOG(OID, LOUD, "\n"); -+ -+ ASSERT(prAdapter); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ ASSERT(pu4QueryInfoLen); -+ -+ if (prAdapter->rAcpiState == ACPI_STATE_D3) { -+ DBGLOG(OID, WARN, "Fail in query receive error! (Adapter not ready). ACPI=D%d, Radio=%d\n", -+ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); -+ *pu4QueryInfoLen = sizeof(UINT_32); -+ return WLAN_STATUS_ADAPTER_NOT_READY; -+ } else if (u4QueryBufferLen < sizeof(UINT_32) -+ || (u4QueryBufferLen > sizeof(UINT_32) && u4QueryBufferLen < sizeof(UINT_64))) { -+ *pu4QueryInfoLen = sizeof(UINT_64); -+ return WLAN_STATUS_INVALID_LENGTH; -+ } -+#if CFG_ENABLE_STATISTICS_BUFFERING -+ if (IsBufferedStatisticsUsable(prAdapter) == TRUE) { -+ if (u4QueryBufferLen == sizeof(UINT_32)) { -+ *pu4QueryInfoLen = sizeof(UINT_32); -+ *(PUINT_32) pvQueryBuffer = (UINT_32) prAdapter->rStatStruct.rFailedCount.QuadPart; -+ } else { -+ *pu4QueryInfoLen = sizeof(UINT_64); -+ *(PUINT_64) pvQueryBuffer = (UINT_64) prAdapter->rStatStruct.rFailedCount.QuadPart; -+ } -+ -+ return WLAN_STATUS_SUCCESS; -+ } -+#endif -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_GET_STATISTICS, -+ FALSE, -+ TRUE, -+ TRUE, -+ nicCmdEventQueryXmitError, -+ nicOidCmdTimeoutCommon, 0, NULL, pvQueryBuffer, u4QueryBufferLen); -+ -+} /* wlanoidQueryXmitError */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to query the number of frames successfully -+* transmitted after exactly one collision. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[out] pvQueryBuf A pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryXmitOneCollision(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ DEBUGFUNC("wlanoidQueryXmitOneCollision"); -+ DBGLOG(OID, LOUD, "\n"); -+ -+ ASSERT(prAdapter); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ ASSERT(pu4QueryInfoLen); -+ -+ if (prAdapter->rAcpiState == ACPI_STATE_D3) { -+ DBGLOG(OID, WARN, "Fail in query receive error! (Adapter not ready). ACPI=D%d, Radio=%d\n", -+ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); -+ *pu4QueryInfoLen = sizeof(UINT_32); -+ return WLAN_STATUS_ADAPTER_NOT_READY; -+ } else if (u4QueryBufferLen < sizeof(UINT_32) -+ || (u4QueryBufferLen > sizeof(UINT_32) && u4QueryBufferLen < sizeof(UINT_64))) { -+ *pu4QueryInfoLen = sizeof(UINT_64); -+ return WLAN_STATUS_INVALID_LENGTH; -+ } -+#if CFG_ENABLE_STATISTICS_BUFFERING -+ if (IsBufferedStatisticsUsable(prAdapter) == TRUE) { -+ if (u4QueryBufferLen == sizeof(UINT_32)) { -+ *pu4QueryInfoLen = sizeof(UINT_32); -+ *(PUINT_32) pvQueryBuffer = (UINT_32) -+ (prAdapter->rStatStruct.rMultipleRetryCount.QuadPart - -+ prAdapter->rStatStruct.rRetryCount.QuadPart); -+ } else { -+ *pu4QueryInfoLen = sizeof(UINT_64); -+ *(PUINT_64) pvQueryBuffer = (UINT_64) -+ (prAdapter->rStatStruct.rMultipleRetryCount.QuadPart - -+ prAdapter->rStatStruct.rRetryCount.QuadPart); -+ } -+ -+ return WLAN_STATUS_SUCCESS; -+ } -+#endif -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_GET_STATISTICS, -+ FALSE, -+ TRUE, -+ TRUE, -+ nicCmdEventQueryXmitOneCollision, -+ nicOidCmdTimeoutCommon, 0, NULL, pvQueryBuffer, u4QueryBufferLen); -+ -+} /* wlanoidQueryXmitOneCollision */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to query the number of frames successfully -+* transmitted after more than one collision. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[out] pvQueryBuf A pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryXmitMoreCollisions(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ DEBUGFUNC("wlanoidQueryXmitMoreCollisions"); -+ DBGLOG(OID, LOUD, "\n"); -+ -+ ASSERT(prAdapter); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ ASSERT(pu4QueryInfoLen); -+ -+ if (prAdapter->rAcpiState == ACPI_STATE_D3) { -+ DBGLOG(OID, WARN, "Fail in query receive error! (Adapter not ready). ACPI=D%d, Radio=%d\n", -+ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); -+ *pu4QueryInfoLen = sizeof(UINT_32); -+ return WLAN_STATUS_ADAPTER_NOT_READY; -+ } else if (u4QueryBufferLen < sizeof(UINT_32) -+ || (u4QueryBufferLen > sizeof(UINT_32) && u4QueryBufferLen < sizeof(UINT_64))) { -+ *pu4QueryInfoLen = sizeof(UINT_64); -+ return WLAN_STATUS_INVALID_LENGTH; -+ } -+#if CFG_ENABLE_STATISTICS_BUFFERING -+ if (IsBufferedStatisticsUsable(prAdapter) == TRUE) { -+ if (u4QueryBufferLen == sizeof(UINT_32)) { -+ *pu4QueryInfoLen = sizeof(UINT_32); -+ *(PUINT_32) pvQueryBuffer = (UINT_32) (prAdapter->rStatStruct.rMultipleRetryCount.QuadPart); -+ } else { -+ *pu4QueryInfoLen = sizeof(UINT_64); -+ *(PUINT_64) pvQueryBuffer = (UINT_64) (prAdapter->rStatStruct.rMultipleRetryCount.QuadPart); -+ } -+ -+ return WLAN_STATUS_SUCCESS; -+ } -+#endif -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_GET_STATISTICS, -+ FALSE, -+ TRUE, -+ TRUE, -+ nicCmdEventQueryXmitMoreCollisions, -+ nicOidCmdTimeoutCommon, 0, NULL, pvQueryBuffer, u4QueryBufferLen); -+} /* wlanoidQueryXmitMoreCollisions */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to query the number of frames -+* not transmitted due to excessive collisions. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvQueryBuffer Pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufferLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryXmitMaxCollisions(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ DEBUGFUNC("wlanoidQueryXmitMaxCollisions"); -+ DBGLOG(OID, LOUD, "\n"); -+ -+ ASSERT(prAdapter); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ ASSERT(pu4QueryInfoLen); -+ -+ if (prAdapter->rAcpiState == ACPI_STATE_D3) { -+ DBGLOG(OID, WARN, "Fail in query receive error! (Adapter not ready). ACPI=D%d, Radio=%d\n", -+ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); -+ *pu4QueryInfoLen = sizeof(UINT_32); -+ return WLAN_STATUS_ADAPTER_NOT_READY; -+ } else if (u4QueryBufferLen < sizeof(UINT_32) -+ || (u4QueryBufferLen > sizeof(UINT_32) && u4QueryBufferLen < sizeof(UINT_64))) { -+ *pu4QueryInfoLen = sizeof(UINT_64); -+ return WLAN_STATUS_INVALID_LENGTH; -+ } -+#if CFG_ENABLE_STATISTICS_BUFFERING -+ if (IsBufferedStatisticsUsable(prAdapter) == TRUE) { -+ if (u4QueryBufferLen == sizeof(UINT_32)) { -+ *pu4QueryInfoLen = sizeof(UINT_32); -+ *(PUINT_32) pvQueryBuffer = (UINT_32) prAdapter->rStatStruct.rFailedCount.QuadPart; -+ } else { -+ *pu4QueryInfoLen = sizeof(UINT_64); -+ *(PUINT_64) pvQueryBuffer = (UINT_64) prAdapter->rStatStruct.rFailedCount.QuadPart; -+ } -+ -+ return WLAN_STATUS_SUCCESS; -+ } -+#endif -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_GET_STATISTICS, -+ FALSE, -+ TRUE, -+ TRUE, -+ nicCmdEventQueryXmitMaxCollisions, -+ nicOidCmdTimeoutCommon, 0, NULL, pvQueryBuffer, u4QueryBufferLen); -+} /* wlanoidQueryXmitMaxCollisions */ -+ -+#define MTK_CUSTOM_OID_INTERFACE_VERSION 0x00006620 /* for WPDWifi DLL */ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to query current the OID interface version, -+* which is the interface between the application and driver. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvQueryBuffer Pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufferLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryOidInterfaceVersion(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ DEBUGFUNC("wlanoidQueryOidInterfaceVersion"); -+ -+ ASSERT(prAdapter); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ ASSERT(pu4QueryInfoLen); -+ -+ *(PUINT_32) pvQueryBuffer = MTK_CUSTOM_OID_INTERFACE_VERSION; -+ *pu4QueryInfoLen = sizeof(UINT_32); -+ -+ DBGLOG(OID, WARN, "Custom OID interface version: %#08X\n", *(PUINT_32) pvQueryBuffer); -+ -+ return WLAN_STATUS_SUCCESS; -+} /* wlanoidQueryOidInterfaceVersion */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to query current Multicast Address List. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvQueryBuffer Pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufferLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_BUFFER_TOO_SHORT -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryMulticastList(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+#ifndef LINUX -+ ASSERT(prAdapter); -+ ASSERT(pu4QueryInfoLen); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_MAC_MCAST_ADDR, -+ FALSE, -+ TRUE, -+ TRUE, -+ nicCmdEventQueryMcastAddr, -+ nicOidCmdTimeoutCommon, 0, NULL, pvQueryBuffer, u4QueryBufferLen); -+#else -+ return WLAN_STATUS_SUCCESS; -+#endif -+} /* end of wlanoidQueryMulticastList() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to set Multicast Address List. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer Pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+* \retval WLAN_STATUS_ADAPTER_NOT_READY -+* \retval WLAN_STATUS_MULTICAST_FULL -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetMulticastList(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ UINT_8 ucNetTypeIndex = NETWORK_TYPE_AIS_INDEX; /* Caller should provide this information */ -+ CMD_MAC_MCAST_ADDR rCmdMacMcastAddr; -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ /* The data must be a multiple of the Ethernet address size. */ -+ if ((u4SetBufferLen % MAC_ADDR_LEN)) { -+ DBGLOG(OID, WARN, "Invalid MC list length %u\n", u4SetBufferLen); -+ -+ *pu4SetInfoLen = (((u4SetBufferLen + MAC_ADDR_LEN) - 1) / MAC_ADDR_LEN) * MAC_ADDR_LEN; -+ -+ return WLAN_STATUS_INVALID_LENGTH; -+ } -+ -+ *pu4SetInfoLen = u4SetBufferLen; -+ -+ /* Verify if we can support so many multicast addresses. */ -+ if ((u4SetBufferLen / MAC_ADDR_LEN) > MAX_NUM_GROUP_ADDR) { -+ DBGLOG(OID, WARN, "Too many MC addresses\n"); -+ -+ return WLAN_STATUS_MULTICAST_FULL; -+ } -+ -+ /* NOTE(Kevin): Windows may set u4SetBufferLen == 0 && -+ * pvSetBuffer == NULL to clear exist Multicast List. -+ */ -+ if (u4SetBufferLen) -+ ASSERT(pvSetBuffer); -+ -+ if (prAdapter->rAcpiState == ACPI_STATE_D3) { -+ DBGLOG(OID, WARN, "Fail in set multicast list! (Adapter not ready). ACPI=D%d, Radio=%d\n", -+ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); -+ return WLAN_STATUS_ADAPTER_NOT_READY; -+ } -+ -+ rCmdMacMcastAddr.u4NumOfGroupAddr = u4SetBufferLen / MAC_ADDR_LEN; -+ rCmdMacMcastAddr.ucNetTypeIndex = ucNetTypeIndex; -+ kalMemCopy(rCmdMacMcastAddr.arAddress, pvSetBuffer, u4SetBufferLen); -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_MAC_MCAST_ADDR, -+ TRUE, -+ FALSE, -+ TRUE, -+ nicCmdEventSetCommon, -+ nicOidCmdTimeoutCommon, -+ sizeof(CMD_MAC_MCAST_ADDR), -+ (PUINT_8) &rCmdMacMcastAddr, pvSetBuffer, u4SetBufferLen); -+} /* end of wlanoidSetMulticastList() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to set Packet Filter. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer Pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+* \retval WLAN_STATUS_NOT_SUPPORTED -+* \retval WLAN_STATUS_ADAPTER_NOT_READY -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetCurrentPacketFilter(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ UINT_32 u4NewPacketFilter; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ if (u4SetBufferLen < sizeof(UINT_32)) { -+ *pu4SetInfoLen = sizeof(UINT_32); -+ DBGLOG(OID, INFO, "iput buffer is too small"); -+ return WLAN_STATUS_INVALID_LENGTH; -+ } -+ ASSERT(pvSetBuffer); -+ -+ /* Set the new packet filter. */ -+ u4NewPacketFilter = *(PUINT_32) pvSetBuffer; -+ -+ DBGLOG(OID, TRACE, "New packet filter: %#08x\n", u4NewPacketFilter); -+ -+ if (prAdapter->rAcpiState == ACPI_STATE_D3) { -+ DBGLOG(OID, WARN, "Fail in set current packet filter! (Adapter not ready). ACPI=D%d, Radio=%d\n", -+ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); -+ return WLAN_STATUS_ADAPTER_NOT_READY; -+ } -+ -+ do { -+ /* Verify the bits of the new packet filter. If any bits are set that -+ we don't support, leave. */ -+ if (u4NewPacketFilter & ~(PARAM_PACKET_FILTER_SUPPORTED)) { -+ rStatus = WLAN_STATUS_NOT_SUPPORTED; -+ break; -+ } -+#if DBG -+ /* Need to enable or disable promiscuous support depending on the new -+ filter. */ -+ if (u4NewPacketFilter & PARAM_PACKET_FILTER_PROMISCUOUS) -+ DBGLOG(OID, TRACE, "Enable promiscuous mode\n"); -+ else -+ DBGLOG(OID, TRACE, "Disable promiscuous mode\n"); -+ -+ if (u4NewPacketFilter & PARAM_PACKET_FILTER_ALL_MULTICAST) -+ DBGLOG(OID, TRACE, "Enable all-multicast mode\n"); -+ else if (u4NewPacketFilter & PARAM_PACKET_FILTER_MULTICAST) -+ DBGLOG(OID, TRACE, "Enable multicast\n"); -+ else -+ DBGLOG(OID, TRACE, "Disable multicast\n"); -+ -+ if (u4NewPacketFilter & PARAM_PACKET_FILTER_BROADCAST) -+ DBGLOG(OID, TRACE, "Enable Broadcast\n"); -+ else -+ DBGLOG(OID, TRACE, "Disable Broadcast\n"); -+#endif -+ } while (FALSE); -+ -+ if (rStatus == WLAN_STATUS_SUCCESS) { -+ /* Store the packet filter */ -+ -+ prAdapter->u4OsPacketFilter &= PARAM_PACKET_FILTER_P2P_MASK; -+ prAdapter->u4OsPacketFilter |= u4NewPacketFilter; -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SET_RX_FILTER, -+ TRUE, -+ FALSE, -+ TRUE, -+ nicCmdEventSetCommon, -+ nicOidCmdTimeoutCommon, -+ sizeof(UINT_32), -+ (PUINT_8) &prAdapter->u4OsPacketFilter, pvSetBuffer, u4SetBufferLen); -+ } else { -+ return rStatus; -+ } -+} /* wlanoidSetCurrentPacketFilter */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to query current packet filter. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvQueryBuffer Pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufferLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryCurrentPacketFilter(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ DEBUGFUNC("wlanoidQueryCurrentPacketFilter"); -+ ASSERT(prAdapter); -+ ASSERT(pu4QueryInfoLen); -+ -+ *pu4QueryInfoLen = sizeof(UINT_32); -+ -+ if (u4QueryBufferLen >= sizeof(UINT_32)) { -+ ASSERT(pvQueryBuffer); -+ *(PUINT_32) pvQueryBuffer = prAdapter->u4OsPacketFilter; -+ } -+ -+ return WLAN_STATUS_SUCCESS; -+} /* wlanoidQueryCurrentPacketFilter */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to query ACPI device power state. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvQueryBuffer Pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufferLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryAcpiDevicePowerState(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+#if DBG -+ PPARAM_DEVICE_POWER_STATE prPowerState; -+#endif -+ -+ DEBUGFUNC("wlanoidQueryAcpiDevicePowerState"); -+ ASSERT(prAdapter); -+ ASSERT(pu4QueryInfoLen); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ -+ *pu4QueryInfoLen = sizeof(PARAM_DEVICE_POWER_STATE); -+ -+#if DBG -+ prPowerState = (PPARAM_DEVICE_POWER_STATE) pvQueryBuffer; -+ switch (*prPowerState) { -+ case ParamDeviceStateD0: -+ DBGLOG(OID, INFO, "Query Power State: D0\n"); -+ break; -+ case ParamDeviceStateD1: -+ DBGLOG(OID, INFO, "Query Power State: D1\n"); -+ break; -+ case ParamDeviceStateD2: -+ DBGLOG(OID, INFO, "Query Power State: D2\n"); -+ break; -+ case ParamDeviceStateD3: -+ DBGLOG(OID, INFO, "Query Power State: D3\n"); -+ break; -+ default: -+ break; -+ } -+#endif -+ -+ /* Since we will disconnect the newwork, therefore we do not -+ need to check queue empty */ -+ *(PPARAM_DEVICE_POWER_STATE) pvQueryBuffer = ParamDeviceStateD3; -+ /* WARNLOG(("Ready to transition to D3\n")); */ -+ return WLAN_STATUS_SUCCESS; -+ -+} /* pwrmgtQueryPower */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to set ACPI device power state. -+* -+* \param[in] pvAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetAcpiDevicePowerState(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ PPARAM_DEVICE_POWER_STATE prPowerState; -+ BOOLEAN fgRetValue = TRUE; -+ -+ DEBUGFUNC("wlanoidSetAcpiDevicePowerState"); -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ *pu4SetInfoLen = sizeof(PARAM_DEVICE_POWER_STATE); -+ -+ ASSERT(pvSetBuffer); -+ prPowerState = (PPARAM_DEVICE_POWER_STATE) pvSetBuffer; -+ switch (*prPowerState) { -+ case ParamDeviceStateD0: -+ DBGLOG(OID, INFO, "Set Power State: D0\n"); -+ kalDevSetPowerState(prAdapter->prGlueInfo, (UINT_32) ParamDeviceStateD0); -+ fgRetValue = nicpmSetAcpiPowerD0(prAdapter); -+ break; -+ case ParamDeviceStateD1: -+ DBGLOG(OID, INFO, "Set Power State: D1\n"); -+ /* no break here */ -+ case ParamDeviceStateD2: -+ DBGLOG(OID, INFO, "Set Power State: D2\n"); -+ /* no break here */ -+ case ParamDeviceStateD3: -+ DBGLOG(OID, INFO, "Set Power State: D3\n"); -+ fgRetValue = nicpmSetAcpiPowerD3(prAdapter); -+ kalDevSetPowerState(prAdapter->prGlueInfo, (UINT_32) ParamDeviceStateD3); -+ break; -+ default: -+ break; -+ } -+ -+ if (fgRetValue == TRUE) -+ return WLAN_STATUS_SUCCESS; -+ else -+ return WLAN_STATUS_FAILURE; -+} /* end of wlanoidSetAcpiDevicePowerState() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to query the current fragmentation threshold. -+* -+* \param[in] pvAdapter Pointer to the Adapter structure. -+* \param[out] pvQueryBuffer A pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufferLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_BUFFER_TOO_SHORT -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryFragThreshold(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ DEBUGFUNC("wlanoidQueryFragThreshold"); -+ -+ ASSERT(prAdapter); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ ASSERT(pu4QueryInfoLen); -+ -+ DBGLOG(OID, LOUD, "\n"); -+ -+#if CFG_TX_FRAGMENT -+ -+ return WLAN_STATUS_SUCCESS; -+ -+#else -+ -+ return WLAN_STATUS_NOT_SUPPORTED; -+#endif /* CFG_TX_FRAGMENT */ -+ -+} /* end of wlanoidQueryFragThreshold() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to set a new fragmentation threshold to the -+* driver. -+* -+* \param[in] pvAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_DATA -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetFragThreshold(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+#if CFG_TX_FRAGMENT -+ -+ return WLAN_STATUS_SUCCESS; -+ -+#else -+ -+ return WLAN_STATUS_NOT_SUPPORTED; -+#endif /* CFG_TX_FRAGMENT */ -+ -+} /* end of wlanoidSetFragThreshold() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to query the current RTS threshold. -+* -+* \param[in] pvAdapter Pointer to the Adapter structure. -+* \param[out] pvQueryBuffer A pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufferLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_BUFFER_TOO_SHORT -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryRtsThreshold(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ DEBUGFUNC("wlanoidQueryRtsThreshold"); -+ -+ ASSERT(prAdapter); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ ASSERT(pu4QueryInfoLen); -+ -+ DBGLOG(OID, LOUD, "\n"); -+ -+ if (u4QueryBufferLen < sizeof(PARAM_RTS_THRESHOLD)) { -+ *pu4QueryInfoLen = sizeof(PARAM_RTS_THRESHOLD); -+ return WLAN_STATUS_BUFFER_TOO_SHORT; -+ } -+ -+ *((PARAM_RTS_THRESHOLD *) pvQueryBuffer) = prAdapter->rWlanInfo.eRtsThreshold; -+ -+ return WLAN_STATUS_SUCCESS; -+ -+} /* wlanoidQueryRtsThreshold */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to set a new RTS threshold to the driver. -+* -+* \param[in] pvAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_DATA -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetRtsThreshold(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ PARAM_RTS_THRESHOLD *prRtsThreshold; -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ *pu4SetInfoLen = sizeof(PARAM_RTS_THRESHOLD); -+ if (u4SetBufferLen < sizeof(PARAM_RTS_THRESHOLD)) { -+ DBGLOG(OID, WARN, "Invalid length %u\n", u4SetBufferLen); -+ return WLAN_STATUS_INVALID_LENGTH; -+ } -+ -+ prRtsThreshold = (PARAM_RTS_THRESHOLD *) pvSetBuffer; -+ *prRtsThreshold = prAdapter->rWlanInfo.eRtsThreshold; -+ -+ return WLAN_STATUS_SUCCESS; -+ -+} /* wlanoidSetRtsThreshold */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is used to turn radio off. -+* -+* \param[in] pvAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_ADAPTER_NOT_READY -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetDisassociate(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ P_MSG_AIS_ABORT_T prAisAbortMsg; -+ -+ DEBUGFUNC("wlanoidSetDisassociate"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ *pu4SetInfoLen = 0; -+ -+ if (prAdapter->rAcpiState == ACPI_STATE_D3) { -+ DBGLOG(OID, WARN, "Fail in set disassociate! (Adapter not ready). ACPI=D%d, Radio=%d\n", -+ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); -+ return WLAN_STATUS_ADAPTER_NOT_READY; -+ } -+ -+ /* prepare message to AIS */ -+ prAdapter->rWifiVar.rConnSettings.fgIsConnReqIssued = FALSE; -+ -+ /* Send AIS Abort Message */ -+ prAisAbortMsg = (P_MSG_AIS_ABORT_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_AIS_ABORT_T)); -+ if (!prAisAbortMsg) { -+ ASSERT(0); -+ return WLAN_STATUS_FAILURE; -+ } -+ -+ prAisAbortMsg->rMsgHdr.eMsgId = MID_OID_AIS_FSM_JOIN_REQ; -+ prAisAbortMsg->ucReasonOfDisconnect = DISCONNECT_REASON_CODE_NEW_CONNECTION; -+ prAisAbortMsg->fgDelayIndication = FALSE; -+ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prAisAbortMsg, MSG_SEND_METHOD_BUF); -+ -+ /* indicate for disconnection */ -+ if (kalGetMediaStateIndicated(prAdapter->prGlueInfo) == PARAM_MEDIA_STATE_CONNECTED) { -+ DBGLOG(OID, INFO, "DisconnectByOid\n"); -+ kalIndicateStatusAndComplete(prAdapter->prGlueInfo, WLAN_STATUS_MEDIA_DISCONNECT_LOCALLY, NULL, 0); -+ } -+#if !defined(LINUX) -+ prAdapter->fgIsRadioOff = TRUE; -+#endif -+ -+ return WLAN_STATUS_SUCCESS; -+} /* wlanoidSetDisassociate */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is used to query the power save profile. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[out] pvQueryBuf A pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \return WLAN_STATUS_SUCCESS -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQuery802dot11PowerSaveProfile(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ DEBUGFUNC("wlanoidQuery802dot11PowerSaveProfile"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4QueryInfoLen); -+ -+ if (u4QueryBufferLen != 0) { -+ ASSERT(pvQueryBuffer); -+ -+/* *(PPARAM_POWER_MODE) pvQueryBuffer = (PARAM_POWER_MODE)(prAdapter->rWlanInfo.ePowerSaveMode.ucPsProfile); */ -+ *(PPARAM_POWER_MODE) pvQueryBuffer = -+ (PARAM_POWER_MODE) (prAdapter->rWlanInfo.arPowerSaveMode[NETWORK_TYPE_AIS_INDEX].ucPsProfile); -+ *pu4QueryInfoLen = sizeof(PARAM_POWER_MODE); -+ -+ /* hack for CTIA power mode setting function */ -+ if (prAdapter->fgEnCtiaPowerMode) { -+ /* set to non-zero value (to prevent MMI query 0, before it intends to set 0, */ -+ /* which will skip its following state machine) */ -+ *(PPARAM_POWER_MODE) pvQueryBuffer = (PARAM_POWER_MODE) 2; -+ } -+ } -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is used to set the power save profile. -+* -+* \param[in] pvAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSet802dot11PowerSaveProfile(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ WLAN_STATUS status; -+ PARAM_POWER_MODE ePowerMode; -+ -+ DEBUGFUNC("wlanoidSet802dot11PowerSaveProfile"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ *pu4SetInfoLen = sizeof(PARAM_POWER_MODE); -+ if (u4SetBufferLen < sizeof(PARAM_POWER_MODE)) { -+ DBGLOG(OID, WARN, "Invalid length %u\n", u4SetBufferLen); -+ return WLAN_STATUS_INVALID_LENGTH; -+ } else if (*(PPARAM_POWER_MODE) pvSetBuffer >= Param_PowerModeMax) { -+ /* WARNLOG(("Invalid power mode %d\n", */ -+ /* *(PPARAM_POWER_MODE) pvSetBuffer)); */ -+ return WLAN_STATUS_INVALID_DATA; -+ } -+ -+ ePowerMode = *(PPARAM_POWER_MODE) pvSetBuffer; -+ -+ if (prAdapter->fgEnCtiaPowerMode) { -+ if (ePowerMode == Param_PowerModeCAM) -+ ; -+ else { -+ /* User setting to PS mode (Param_PowerModeMAX_PSP or Param_PowerModeFast_PSP) */ -+ -+ if (prAdapter->u4CtiaPowerMode == 0) -+ /* force to keep in CAM mode */ -+ ePowerMode = Param_PowerModeCAM; -+ else if (prAdapter->u4CtiaPowerMode == 1) -+ ePowerMode = Param_PowerModeMAX_PSP; -+ else if (prAdapter->u4CtiaPowerMode == 2) -+ ePowerMode = Param_PowerModeFast_PSP; -+ } -+ } -+ -+ status = nicConfigPowerSaveProfile(prAdapter, NETWORK_TYPE_AIS_INDEX, ePowerMode, TRUE); -+ -+ switch (ePowerMode) { -+ case Param_PowerModeCAM: -+ DBGLOG(OID, INFO, "Set Wi-Fi PS mode to CAM (%d)\n", ePowerMode); -+ break; -+ case Param_PowerModeMAX_PSP: -+ DBGLOG(OID, INFO, "Set Wi-Fi PS mode to MAX PS (%d)\n", ePowerMode); -+ break; -+ case Param_PowerModeFast_PSP: -+ DBGLOG(OID, INFO, "Set Wi-Fi PS mode to FAST PS (%d)\n", ePowerMode); -+ break; -+ default: -+ DBGLOG(OID, INFO, "invalid Wi-Fi PS mode setting (%d)\n", ePowerMode); -+ break; -+ } -+ -+ return status; -+ -+} /* end of wlanoidSetAcpiDevicePowerStateMode() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to query current status of AdHoc Mode. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvQueryBuffer Pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufferLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_BUFFER_TOO_SHORT -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryAdHocMode(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ return WLAN_STATUS_SUCCESS; -+} /* end of wlanoidQueryAdHocMode() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to set AdHoc Mode. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer Pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+* \retval WLAN_STATUS_INVALID_DATA -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetAdHocMode(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ return WLAN_STATUS_SUCCESS; -+} /* end of wlanoidSetAdHocMode() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to query RF frequency. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvQueryBuffer Pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufferLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_BUFFER_TOO_SHORT -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryFrequency(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ DEBUGFUNC("wlanoidQueryFrequency"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4QueryInfoLen); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ -+ if (u4QueryBufferLen < sizeof(UINT_32)) -+ return WLAN_STATUS_BUFFER_TOO_SHORT; -+ -+ if (prAdapter->rWifiVar.rConnSettings.eOPMode == NET_TYPE_INFRA) { -+ if (kalGetMediaStateIndicated(prAdapter->prGlueInfo) == PARAM_MEDIA_STATE_CONNECTED) { -+ *(PUINT_32) pvQueryBuffer = -+ nicChannelNum2Freq(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX].ucPrimaryChannel); -+ } else { -+ *(PUINT_32) pvQueryBuffer = 0; -+ } -+ } else { -+ *(PUINT_32) pvQueryBuffer = nicChannelNum2Freq(prAdapter->rWifiVar.rConnSettings.ucAdHocChannelNum); -+ } -+ -+ return WLAN_STATUS_SUCCESS; -+} /* end of wlanoidQueryFrequency() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to set RF frequency by User Settings. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvQueryBuffer Pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufferLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+* \retval WLAN_STATUS_INVALID_DATA -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetFrequency(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ PUINT_32 pu4FreqInKHz; -+ -+ DEBUGFUNC("wlanoidSetFrequency"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ *pu4SetInfoLen = sizeof(UINT_32); -+ -+ if (u4SetBufferLen < sizeof(UINT_32)) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ ASSERT(pvSetBuffer); -+ pu4FreqInKHz = (PUINT_32) pvSetBuffer; -+ -+ prAdapter->rWifiVar.rConnSettings.ucAdHocChannelNum = (UINT_8) nicFreq2ChannelNum(*pu4FreqInKHz); -+ prAdapter->rWifiVar.rConnSettings.eAdHocBand = *pu4FreqInKHz < 5000000 ? BAND_2G4 : BAND_5G; -+ -+ return WLAN_STATUS_SUCCESS; -+} /* end of wlanoidSetFrequency() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to set 802.11 channel of the radio frequency. -+* This is a proprietary function call to Lunux currently. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+* \retval WLAN_STATUS_INVALID_DATA -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetChannel(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ ASSERT(0); /* // */ -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to query the Beacon Interval from User Settings. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvQueryBuffer Pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufferLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_BUFFER_TOO_SHORT -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryBeaconInterval(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ DEBUGFUNC("wlanoidQueryBeaconInterval"); -+ ASSERT(prAdapter); -+ ASSERT(pu4QueryInfoLen); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ -+ *pu4QueryInfoLen = sizeof(UINT_32); -+ -+ if (u4QueryBufferLen < sizeof(UINT_32)) -+ return WLAN_STATUS_BUFFER_TOO_SHORT; -+ -+ if (kalGetMediaStateIndicated(prAdapter->prGlueInfo) == PARAM_MEDIA_STATE_CONNECTED) { -+ if (prAdapter->rWifiVar.rConnSettings.eOPMode == NET_TYPE_INFRA) -+ *(PUINT_32) pvQueryBuffer = prAdapter->rWlanInfo.rCurrBssId.rConfiguration.u4BeaconPeriod; -+ else -+ *(PUINT_32) pvQueryBuffer = (UINT_32) prAdapter->rWlanInfo.u2BeaconPeriod; -+ } else { -+ if (prAdapter->rWifiVar.rConnSettings.eOPMode == NET_TYPE_INFRA) -+ *(PUINT_32) pvQueryBuffer = 0; -+ else -+ *(PUINT_32) pvQueryBuffer = (UINT_32) prAdapter->rWlanInfo.u2BeaconPeriod; -+ } -+ -+ return WLAN_STATUS_SUCCESS; -+} /* end of wlanoidQueryBeaconInterval() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to set the Beacon Interval to User Settings. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer Pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+* \retval WLAN_STATUS_INVALID_DATA -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetBeaconInterval(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ PUINT_32 pu4BeaconInterval; -+ -+ DEBUGFUNC("wlanoidSetBeaconInterval"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ *pu4SetInfoLen = sizeof(UINT_32); -+ if (u4SetBufferLen < sizeof(UINT_32)) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ ASSERT(pvSetBuffer); -+ pu4BeaconInterval = (PUINT_32) pvSetBuffer; -+ -+ if ((*pu4BeaconInterval < DOT11_BEACON_PERIOD_MIN) || (*pu4BeaconInterval > DOT11_BEACON_PERIOD_MAX)) { -+ DBGLOG(OID, TRACE, "Invalid Beacon Interval = %u\n", *pu4BeaconInterval); -+ return WLAN_STATUS_INVALID_DATA; -+ } -+ -+ prAdapter->rWlanInfo.u2BeaconPeriod = (UINT_16) *pu4BeaconInterval; -+ -+ DBGLOG(OID, INFO, "Set beacon interval: %d\n", prAdapter->rWlanInfo.u2BeaconPeriod); -+ -+ return WLAN_STATUS_SUCCESS; -+} /* end of wlanoidSetBeaconInterval() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to query the ATIM window from User Settings. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvQueryBuffer Pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufferLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_BUFFER_TOO_SHORT -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryAtimWindow(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ DEBUGFUNC("wlanoidQueryAtimWindow"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4QueryInfoLen); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ -+ *pu4QueryInfoLen = sizeof(UINT_32); -+ -+ if (u4QueryBufferLen < sizeof(UINT_32)) -+ return WLAN_STATUS_BUFFER_TOO_SHORT; -+ -+ if (prAdapter->rWifiVar.rConnSettings.eOPMode == NET_TYPE_INFRA) -+ *(PUINT_32) pvQueryBuffer = 0; -+ else -+ *(PUINT_32) pvQueryBuffer = (UINT_32) prAdapter->rWlanInfo.u2AtimWindow; -+ -+ return WLAN_STATUS_SUCCESS; -+ -+} /* end of wlanoidQueryAtimWindow() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to set the ATIM window to User Settings. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer Pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+* \retval WLAN_STATUS_INVALID_DATA -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetAtimWindow(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ PUINT_32 pu4AtimWindow; -+ -+ DEBUGFUNC("wlanoidSetAtimWindow"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ *pu4SetInfoLen = sizeof(UINT_32); -+ -+ if (u4SetBufferLen < sizeof(UINT_32)) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ ASSERT(pvSetBuffer); -+ pu4AtimWindow = (PUINT_32) pvSetBuffer; -+ -+ prAdapter->rWlanInfo.u2AtimWindow = (UINT_16) *pu4AtimWindow; -+ -+ return WLAN_STATUS_SUCCESS; -+} /* end of wlanoidSetAtimWindow() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to Set the MAC address which is currently used by the NIC. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer Pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+* \retval WLAN_STATUS_INVALID_DATA -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetCurrentAddr(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ ASSERT(0); /* // */ -+ -+ return WLAN_STATUS_SUCCESS; -+} /* end of wlanoidSetCurrentAddr() */ -+ -+#if CFG_TCP_IP_CHKSUM_OFFLOAD -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Setting the checksum offload function. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer Pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+* \retval WLAN_STATUS_ADAPTER_NOT_READY -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetCSUMOffload(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ UINT_32 i, u4CSUMFlags; -+ CMD_BASIC_CONFIG rCmdBasicConfig; -+ -+ DEBUGFUNC("wlanoidSetCSUMOffload"); -+ DBGLOG(OID, LOUD, "\n"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ *pu4SetInfoLen = sizeof(UINT_32); -+ -+ if (u4SetBufferLen < sizeof(UINT_32)) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ ASSERT(pvSetBuffer); -+ u4CSUMFlags = *(PUINT_32) pvSetBuffer; -+ -+ kalMemZero(&rCmdBasicConfig, sizeof(CMD_BASIC_CONFIG)); -+ -+ for (i = 0; i < 6; i++) { /* set to broadcast address for not-specified */ -+ rCmdBasicConfig.rMyMacAddr[i] = 0xff; -+ } -+ -+ rCmdBasicConfig.ucNative80211 = 0; /* @FIXME: for Vista */ -+ -+ if (u4CSUMFlags & CSUM_OFFLOAD_EN_TX_TCP) -+ rCmdBasicConfig.rCsumOffload.u2TxChecksum |= BIT(2); -+ -+ if (u4CSUMFlags & CSUM_OFFLOAD_EN_TX_UDP) -+ rCmdBasicConfig.rCsumOffload.u2TxChecksum |= BIT(1); -+ -+ if (u4CSUMFlags & CSUM_OFFLOAD_EN_TX_IP) -+ rCmdBasicConfig.rCsumOffload.u2TxChecksum |= BIT(0); -+ -+ if (u4CSUMFlags & CSUM_OFFLOAD_EN_RX_TCP) -+ rCmdBasicConfig.rCsumOffload.u2RxChecksum |= BIT(2); -+ -+ if (u4CSUMFlags & CSUM_OFFLOAD_EN_RX_UDP) -+ rCmdBasicConfig.rCsumOffload.u2RxChecksum |= BIT(1); -+ -+ if (u4CSUMFlags & (CSUM_OFFLOAD_EN_RX_IPv4 | CSUM_OFFLOAD_EN_RX_IPv6)) -+ rCmdBasicConfig.rCsumOffload.u2RxChecksum |= BIT(0); -+ -+ prAdapter->u4CSUMFlags = u4CSUMFlags; -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_BASIC_CONFIG, -+ TRUE, -+ FALSE, -+ TRUE, -+ nicCmdEventSetCommon, -+ nicOidCmdTimeoutCommon, -+ sizeof(CMD_BASIC_CONFIG), (PUINT_8) &rCmdBasicConfig, pvSetBuffer, u4SetBufferLen); -+} -+#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Setting the IP address for pattern search function. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \return WLAN_STATUS_SUCCESS -+* \return WLAN_STATUS_ADAPTER_NOT_READY -+* \return WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetNetworkAddress(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ UINT_32 i, j; -+ P_CMD_SET_NETWORK_ADDRESS_LIST prCmdNetworkAddressList; -+ P_PARAM_NETWORK_ADDRESS_LIST prNetworkAddressList = (P_PARAM_NETWORK_ADDRESS_LIST) pvSetBuffer; -+ P_PARAM_NETWORK_ADDRESS prNetworkAddress; -+ P_PARAM_NETWORK_ADDRESS_IP prNetAddrIp; -+ UINT_32 u4IpAddressCount, u4CmdSize; -+ PUINT_8 pucBuf = (PUINT_8) pvSetBuffer; -+#if CFG_ENABLE_GTK_FRAME_FILTER -+ UINT_32 u4IpV4AddrListSize; -+ P_BSS_INFO_T prBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]; -+#endif -+ -+ DEBUGFUNC("wlanoidSetNetworkAddress"); -+ DBGLOG(OID, LOUD, "\n"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ *pu4SetInfoLen = 4; -+ -+ if (u4SetBufferLen < sizeof(PARAM_NETWORK_ADDRESS_LIST)) -+ return WLAN_STATUS_INVALID_DATA; -+ -+ *pu4SetInfoLen = 0; -+ u4IpAddressCount = 0; -+ -+ prNetworkAddress = prNetworkAddressList->arAddress; -+ for (i = 0; i < prNetworkAddressList->u4AddressCount; i++) { -+ if (prNetworkAddress->u2AddressType == PARAM_PROTOCOL_ID_TCP_IP && -+ prNetworkAddress->u2AddressLength == sizeof(PARAM_NETWORK_ADDRESS_IP)) { -+ u4IpAddressCount++; -+ } -+ -+ prNetworkAddress = (P_PARAM_NETWORK_ADDRESS) (prNetworkAddress + -+ (ULONG) (prNetworkAddress->u2AddressLength + -+ OFFSET_OF(PARAM_NETWORK_ADDRESS, aucAddress))); -+ } -+ -+ /* construct payload of command packet */ -+ u4CmdSize = OFFSET_OF(CMD_SET_NETWORK_ADDRESS_LIST, arNetAddress) + -+ sizeof(IPV4_NETWORK_ADDRESS) * u4IpAddressCount; -+ if (u4IpAddressCount == 0) -+ u4CmdSize = sizeof(CMD_SET_NETWORK_ADDRESS_LIST); -+ -+ prCmdNetworkAddressList = (P_CMD_SET_NETWORK_ADDRESS_LIST) kalMemAlloc(u4CmdSize, VIR_MEM_TYPE); -+ -+ if (prCmdNetworkAddressList == NULL) -+ return WLAN_STATUS_FAILURE; -+ -+#if CFG_ENABLE_GTK_FRAME_FILTER -+ u4IpV4AddrListSize = OFFSET_OF(IPV4_NETWORK_ADDRESS_LIST, arNetAddr) + -+ (u4IpAddressCount * sizeof(IPV4_NETWORK_ADDRESS)); -+ if (prBssInfo->prIpV4NetAddrList) -+ FREE_IPV4_NETWORK_ADDR_LIST(prBssInfo->prIpV4NetAddrList); -+ prBssInfo->prIpV4NetAddrList = (P_IPV4_NETWORK_ADDRESS_LIST) kalMemAlloc(u4IpV4AddrListSize, VIR_MEM_TYPE); -+ if (prBssInfo->prIpV4NetAddrList == NULL) { -+ kalMemFree(prCmdNetworkAddressList, VIR_MEM_TYPE, u4CmdSize); -+ return WLAN_STATUS_FAILURE; -+ } -+ prBssInfo->prIpV4NetAddrList->ucAddrCount = (UINT_8) u4IpAddressCount; -+#endif -+ -+ /* fill P_CMD_SET_NETWORK_ADDRESS_LIST */ -+ prCmdNetworkAddressList->ucNetTypeIndex = NETWORK_TYPE_AIS_INDEX; -+ -+ /* only to set IP address to FW once ARP filter is enabled */ -+ if (prAdapter->fgEnArpFilter) { -+ prCmdNetworkAddressList->ucAddressCount = (UINT_8) u4IpAddressCount; -+ prNetworkAddress = prNetworkAddressList->arAddress; -+ -+ DBGLOG(OID, INFO, "u4IpAddressCount (%u)\n", u4IpAddressCount); -+ -+ for (i = 0, j = 0; i < prNetworkAddressList->u4AddressCount; i++) { -+ if (prNetworkAddress->u2AddressType == PARAM_PROTOCOL_ID_TCP_IP && -+ prNetworkAddress->u2AddressLength == sizeof(PARAM_NETWORK_ADDRESS_IP)) { -+ prNetAddrIp = (P_PARAM_NETWORK_ADDRESS_IP) prNetworkAddress->aucAddress; -+ -+ kalMemCopy(prCmdNetworkAddressList->arNetAddress[j].aucIpAddr, -+ &(prNetAddrIp->in_addr), sizeof(UINT_32)); -+ -+#if CFG_ENABLE_GTK_FRAME_FILTER -+ kalMemCopy(prBssInfo->prIpV4NetAddrList->arNetAddr[j].aucIpAddr, -+ &(prNetAddrIp->in_addr), sizeof(UINT_32)); -+#endif -+ -+ j++; -+ -+ pucBuf = (PUINT_8) &prNetAddrIp->in_addr; -+ DBGLOG(OID, INFO, -+ "prNetAddrIp->in_addr:%d:%d:%d:%d\n", pucBuf[0], pucBuf[1], pucBuf[2], -+ pucBuf[3]); -+ } -+ -+ prNetworkAddress = (P_PARAM_NETWORK_ADDRESS) (prNetworkAddress + -+ (ULONG) (prNetworkAddress->u2AddressLength + -+ OFFSET_OF(PARAM_NETWORK_ADDRESS, -+ aucAddress))); -+ } -+ -+ } else { -+ prCmdNetworkAddressList->ucAddressCount = 0; -+ } -+ -+ rStatus = wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SET_IP_ADDRESS, -+ TRUE, -+ FALSE, -+ TRUE, -+ nicCmdEventSetIpAddress, -+ nicOidCmdTimeoutCommon, -+ u4CmdSize, (PUINT_8) prCmdNetworkAddressList, pvSetBuffer, u4SetBufferLen); -+ -+ kalMemFree(prCmdNetworkAddressList, VIR_MEM_TYPE, u4CmdSize); -+ return rStatus; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Set driver to switch into RF test mode -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set, -+* should be NULL -+* \param[in] u4SetBufferLen The length of the set buffer, should be 0 -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \return WLAN_STATUS_SUCCESS -+* \return WLAN_STATUS_ADAPTER_NOT_READY -+* \return WLAN_STATUS_INVALID_DATA -+* \return WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidRftestSetTestMode(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ WLAN_STATUS rStatus; -+ CMD_TEST_CTRL_T rCmdTestCtrl; -+ -+ DEBUGFUNC("wlanoidRftestSetTestMode"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pvSetBuffer); -+ ASSERT(pu4SetInfoLen); -+ -+ *pu4SetInfoLen = 0; -+ -+ if (u4SetBufferLen == 0) { -+ if (prAdapter->fgTestMode == FALSE) { -+ /* switch to RF Test mode */ -+ rCmdTestCtrl.ucAction = 0; /* Switch mode */ -+ rCmdTestCtrl.u.u4OpMode = 1; /* RF test mode */ -+ -+ rStatus = wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_TEST_MODE, -+ TRUE, -+ TRUE, -+ TRUE, -+ nicCmdEventEnterRfTest, -+ nicOidCmdEnterRFTestTimeout, -+ sizeof(CMD_TEST_CTRL_T), -+ (PUINT_8) &rCmdTestCtrl, pvSetBuffer, u4SetBufferLen); -+ } else { -+ /* already in test mode .. */ -+ rStatus = WLAN_STATUS_SUCCESS; -+ } -+ } else { -+ rStatus = WLAN_STATUS_INVALID_DATA; -+ } -+ DBGLOG(OID, INFO, "Enter TestMode, setBufLen %u, InTestMode %d, rStatus %u\n", -+ u4SetBufferLen, prAdapter->fgTestMode, rStatus); -+ return rStatus; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Set driver to switch into normal operation mode from RF test mode -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set -+* should be NULL -+* \param[in] u4SetBufferLen The length of the set buffer, should be 0 -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \return WLAN_STATUS_SUCCESS -+* \return WLAN_STATUS_ADAPTER_NOT_READY -+* \return WLAN_STATUS_INVALID_DATA -+* \return WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidRftestSetAbortTestMode(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ WLAN_STATUS rStatus; -+ CMD_TEST_CTRL_T rCmdTestCtrl; -+ -+ DEBUGFUNC("wlanoidRftestSetTestMode"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pvSetBuffer); -+ ASSERT(pu4SetInfoLen); -+ -+ *pu4SetInfoLen = 0; -+ -+ if (u4SetBufferLen == 0) { -+ if (prAdapter->fgTestMode == TRUE) { -+ /* switch to normal mode */ -+ rCmdTestCtrl.ucAction = 0; /* Switch mode */ -+ rCmdTestCtrl.u.u4OpMode = 0; /* normal mode */ -+ -+ rStatus = wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_TEST_MODE, -+ TRUE, -+ FALSE, -+ TRUE, -+ nicCmdEventLeaveRfTest, -+ nicOidCmdTimeoutCommon, -+ sizeof(CMD_TEST_CTRL_T), -+ (PUINT_8) &rCmdTestCtrl, pvSetBuffer, u4SetBufferLen); -+ } else { -+ /* already in normal mode .. */ -+ rStatus = WLAN_STATUS_SUCCESS; -+ } -+ } else { -+ rStatus = WLAN_STATUS_INVALID_DATA; -+ } -+ DBGLOG(OID, INFO, "Abort TestMode, setBufLen %u, InTestMode %d, rStatus %u\n", -+ u4SetBufferLen, prAdapter->fgTestMode, rStatus); -+ return rStatus; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief query for RF test parameter -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvQueryBuffer Pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufferLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_BUFFER_TOO_SHORT -+* \retval WLAN_STATUS_NOT_SUPPORTED -+* \retval WLAN_STATUS_NOT_ACCEPTED -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidRftestQueryAutoTest(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ P_PARAM_MTK_WIFI_TEST_STRUCT_T prRfATInfo; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ -+ DEBUGFUNC("wlanoidRftestQueryAutoTest"); -+ -+ ASSERT(prAdapter); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ ASSERT(pu4QueryInfoLen); -+ -+ *pu4QueryInfoLen = sizeof(PARAM_MTK_WIFI_TEST_STRUCT_T); -+ -+ if (u4QueryBufferLen != sizeof(PARAM_MTK_WIFI_TEST_STRUCT_T)) { -+ DBGLOG(OID, ERROR, "Invalid data. QueryBufferLen: %u.\n", u4QueryBufferLen); -+ return WLAN_STATUS_INVALID_LENGTH; -+ } -+ -+ prRfATInfo = (P_PARAM_MTK_WIFI_TEST_STRUCT_T) pvQueryBuffer; -+ rStatus = rftestQueryATInfo(prAdapter, -+ prRfATInfo->u4FuncIndex, prRfATInfo->u4FuncData, pvQueryBuffer, u4QueryBufferLen); -+ -+ return rStatus; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Set RF test parameter -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \return WLAN_STATUS_SUCCESS -+* \return WLAN_STATUS_ADAPTER_NOT_READY -+* \return WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidRftestSetAutoTest(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ P_PARAM_MTK_WIFI_TEST_STRUCT_T prRfATInfo; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ -+ DEBUGFUNC("wlanoidRftestSetAutoTest"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pvSetBuffer); -+ ASSERT(pu4SetInfoLen); -+ -+ *pu4SetInfoLen = sizeof(PARAM_MTK_WIFI_TEST_STRUCT_T); -+ -+ if (u4SetBufferLen != sizeof(PARAM_MTK_WIFI_TEST_STRUCT_T)) { -+ DBGLOG(OID, ERROR, "Invalid data. SetBufferLen: %u.\n", u4SetBufferLen); -+ return WLAN_STATUS_INVALID_LENGTH; -+ } -+ -+ prRfATInfo = (P_PARAM_MTK_WIFI_TEST_STRUCT_T) pvSetBuffer; -+ rStatus = rftestSetATInfo(prAdapter, prRfATInfo->u4FuncIndex, prRfATInfo->u4FuncData); -+ -+ return rStatus; -+} -+ -+/* RF test OID set handler */ -+WLAN_STATUS rftestSetATInfo(IN P_ADAPTER_T prAdapter, UINT_32 u4FuncIndex, UINT_32 u4FuncData) -+{ -+ P_GLUE_INFO_T prGlueInfo; -+ P_CMD_INFO_T prCmdInfo; -+ P_WIFI_CMD_T prWifiCmd; -+ P_CMD_TEST_CTRL_T pCmdTestCtrl; -+ UINT_8 ucCmdSeqNum; -+ -+ ASSERT(prAdapter); -+ -+ prGlueInfo = prAdapter->prGlueInfo; -+ prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, (CMD_HDR_SIZE + sizeof(CMD_TEST_CTRL_T))); -+ -+ if (!prCmdInfo) { -+ DBGLOG(OID, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); -+ return WLAN_STATUS_FAILURE; -+ } -+ /* increase command sequence number */ -+ ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter); -+ -+ /* Setup common CMD Info Packet */ -+ prCmdInfo->eCmdType = COMMAND_TYPE_GENERAL_IOCTL; -+ prCmdInfo->u2InfoBufLen = CMD_HDR_SIZE + sizeof(CMD_TEST_CTRL_T); -+ prCmdInfo->pfCmdDoneHandler = nicCmdEventSetCommon; -+ prCmdInfo->pfCmdTimeoutHandler = nicOidCmdTimeoutCommon; -+ prCmdInfo->fgIsOid = TRUE; -+ prCmdInfo->ucCID = CMD_ID_TEST_MODE; -+ prCmdInfo->fgSetQuery = TRUE; -+ prCmdInfo->fgNeedResp = FALSE; -+ prCmdInfo->fgDriverDomainMCR = FALSE; -+ prCmdInfo->ucCmdSeqNum = ucCmdSeqNum; -+ prCmdInfo->u4SetInfoLen = sizeof(CMD_TEST_CTRL_T); -+ prCmdInfo->pvInformationBuffer = NULL; -+ prCmdInfo->u4InformationBufferLength = 0; -+ -+ /* Setup WIFI_CMD_T (payload = CMD_TEST_CTRL_T) */ -+ prWifiCmd = (P_WIFI_CMD_T) (prCmdInfo->pucInfoBuffer); -+ prWifiCmd->u2TxByteCount_UserPriority = prCmdInfo->u2InfoBufLen; -+ prWifiCmd->ucCID = prCmdInfo->ucCID; -+ prWifiCmd->ucSetQuery = prCmdInfo->fgSetQuery; -+ prWifiCmd->ucSeqNum = prCmdInfo->ucCmdSeqNum; -+ -+ pCmdTestCtrl = (P_CMD_TEST_CTRL_T) (prWifiCmd->aucBuffer); -+ pCmdTestCtrl->ucAction = 1; /* Set ATInfo */ -+ pCmdTestCtrl->u.rRfATInfo.u4FuncIndex = u4FuncIndex; -+ pCmdTestCtrl->u.rRfATInfo.u4FuncData = u4FuncData; -+ -+ /* insert into prCmdQueue */ -+ kalEnqueueCommand(prGlueInfo, (P_QUE_ENTRY_T) prCmdInfo); -+ -+ /* wakeup txServiceThread later */ -+ GLUE_SET_EVENT(prAdapter->prGlueInfo); -+ -+ return WLAN_STATUS_PENDING; -+} -+ -+WLAN_STATUS -+rftestQueryATInfo(IN P_ADAPTER_T prAdapter, -+ UINT_32 u4FuncIndex, UINT_32 u4FuncData, OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen) -+{ -+ P_GLUE_INFO_T prGlueInfo; -+ P_CMD_INFO_T prCmdInfo; -+ P_WIFI_CMD_T prWifiCmd; -+ P_CMD_TEST_CTRL_T pCmdTestCtrl; -+ UINT_8 ucCmdSeqNum; -+ P_EVENT_TEST_STATUS prTestStatus; -+ -+ ASSERT(prAdapter); -+ -+ prGlueInfo = prAdapter->prGlueInfo; -+ -+ if (u4FuncIndex == RF_AT_FUNCID_FW_INFO) { -+ /* driver implementation */ -+ prTestStatus = (P_EVENT_TEST_STATUS) pvQueryBuffer; -+ -+ prTestStatus->rATInfo.u4FuncData = -+ (prAdapter->rVerInfo.u2FwProductID << 16) | (prAdapter->rVerInfo.u2FwOwnVersion); -+ u4QueryBufferLen = sizeof(EVENT_TEST_STATUS); -+ -+ return WLAN_STATUS_SUCCESS; -+ } else if (u4FuncIndex == RF_AT_FUNCID_DRV_INFO) { -+ /* driver implementation */ -+ prTestStatus = (P_EVENT_TEST_STATUS) pvQueryBuffer; -+ -+ prTestStatus->rATInfo.u4FuncData = CFG_DRV_OWN_VERSION; -+ u4QueryBufferLen = sizeof(EVENT_TEST_STATUS); -+ -+ return WLAN_STATUS_SUCCESS; -+ } -+ prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, (CMD_HDR_SIZE + sizeof(CMD_TEST_CTRL_T))); -+ -+ if (!prCmdInfo) { -+ DBGLOG(OID, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); -+ return WLAN_STATUS_FAILURE; -+ } -+ /* increase command sequence number */ -+ ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter); -+ -+ /* Setup common CMD Info Packet */ -+ prCmdInfo->eCmdType = COMMAND_TYPE_GENERAL_IOCTL; -+ prCmdInfo->u2InfoBufLen = CMD_HDR_SIZE + sizeof(CMD_TEST_CTRL_T); -+ prCmdInfo->pfCmdDoneHandler = nicCmdEventQueryRfTestATInfo; -+ prCmdInfo->pfCmdTimeoutHandler = nicOidCmdTimeoutCommon; -+ prCmdInfo->fgIsOid = TRUE; -+ prCmdInfo->ucCID = CMD_ID_TEST_MODE; -+ prCmdInfo->fgSetQuery = FALSE; -+ prCmdInfo->fgNeedResp = TRUE; -+ prCmdInfo->fgDriverDomainMCR = FALSE; -+ prCmdInfo->ucCmdSeqNum = ucCmdSeqNum; -+ prCmdInfo->u4SetInfoLen = sizeof(CMD_TEST_CTRL_T); -+ prCmdInfo->pvInformationBuffer = pvQueryBuffer; -+ prCmdInfo->u4InformationBufferLength = u4QueryBufferLen; -+ -+ /* Setup WIFI_CMD_T (payload = CMD_TEST_CTRL_T) */ -+ prWifiCmd = (P_WIFI_CMD_T) (prCmdInfo->pucInfoBuffer); -+ prWifiCmd->u2TxByteCount_UserPriority = prCmdInfo->u2InfoBufLen; -+ prWifiCmd->ucCID = prCmdInfo->ucCID; -+ prWifiCmd->ucSetQuery = prCmdInfo->fgSetQuery; -+ prWifiCmd->ucSeqNum = prCmdInfo->ucCmdSeqNum; -+ -+ pCmdTestCtrl = (P_CMD_TEST_CTRL_T) (prWifiCmd->aucBuffer); -+ pCmdTestCtrl->ucAction = 2; /* Get ATInfo */ -+ pCmdTestCtrl->u.rRfATInfo.u4FuncIndex = u4FuncIndex; -+ pCmdTestCtrl->u.rRfATInfo.u4FuncData = u4FuncData; -+ -+ /* insert into prCmdQueue */ -+ kalEnqueueCommand(prGlueInfo, (P_QUE_ENTRY_T) prCmdInfo); -+ -+ /* wakeup txServiceThread later */ -+ GLUE_SET_EVENT(prAdapter->prGlueInfo); -+ -+ return WLAN_STATUS_PENDING; -+} -+ -+WLAN_STATUS rftestSetFrequency(IN P_ADAPTER_T prAdapter, IN UINT_32 u4FreqInKHz, IN PUINT_32 pu4SetInfoLen) -+{ -+ CMD_TEST_CTRL_T rCmdTestCtrl; -+ -+ ASSERT(prAdapter); -+ -+ rCmdTestCtrl.ucAction = 5; /* Set Channel Frequency */ -+ rCmdTestCtrl.u.u4ChannelFreq = u4FreqInKHz; -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_TEST_MODE, -+ TRUE, -+ FALSE, -+ TRUE, -+ nicCmdEventSetCommon, -+ nicOidCmdTimeoutCommon, sizeof(CMD_TEST_CTRL_T), (PUINT_8) &rCmdTestCtrl, NULL, 0); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief command packet generation utility -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] ucCID Command ID -+* \param[in] fgSetQuery Set or Query -+* \param[in] fgNeedResp Need for response -+* \param[in] pfCmdDoneHandler Function pointer when command is done -+* \param[in] u4SetQueryInfoLen The length of the set/query buffer -+* \param[in] pucInfoBuffer Pointer to set/query buffer -+* -+* -+* \retval WLAN_STATUS_PENDING -+* \retval WLAN_STATUS_FAILURE -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanSendSetQueryCmd(IN P_ADAPTER_T prAdapter, -+ UINT_8 ucCID, -+ BOOLEAN fgSetQuery, -+ BOOLEAN fgNeedResp, -+ BOOLEAN fgIsOid, -+ PFN_CMD_DONE_HANDLER pfCmdDoneHandler, -+ PFN_CMD_TIMEOUT_HANDLER pfCmdTimeoutHandler, -+ UINT_32 u4SetQueryInfoLen, -+ PUINT_8 pucInfoBuffer, OUT PVOID pvSetQueryBuffer, IN UINT_32 u4SetQueryBufferLen) -+{ -+ P_GLUE_INFO_T prGlueInfo; -+ P_CMD_INFO_T prCmdInfo; -+ P_WIFI_CMD_T prWifiCmd; -+ UINT_8 ucCmdSeqNum; -+ -+ prGlueInfo = prAdapter->prGlueInfo; -+ prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, (CMD_HDR_SIZE + u4SetQueryInfoLen)); -+ -+ DEBUGFUNC("wlanSendSetQueryCmd"); -+ -+ if (!prCmdInfo) { -+ DBGLOG(OID, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); -+ return WLAN_STATUS_FAILURE; -+ } -+ /* increase command sequence number */ -+ ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter); -+ DBGLOG(OID, TRACE, "ucCmdSeqNum =%d, ucCID =%d\n", ucCmdSeqNum, ucCID); -+ -+ /* Setup common CMD Info Packet */ -+ prCmdInfo->eCmdType = COMMAND_TYPE_NETWORK_IOCTL; -+ prCmdInfo->eNetworkType = NETWORK_TYPE_AIS_INDEX; -+ prCmdInfo->u2InfoBufLen = (UINT_16) (CMD_HDR_SIZE + u4SetQueryInfoLen); -+ prCmdInfo->pfCmdDoneHandler = pfCmdDoneHandler; -+ prCmdInfo->pfCmdTimeoutHandler = pfCmdTimeoutHandler; -+ prCmdInfo->fgIsOid = fgIsOid; -+ prCmdInfo->ucCID = ucCID; -+ prCmdInfo->fgSetQuery = fgSetQuery; -+ prCmdInfo->fgNeedResp = fgNeedResp; -+ prCmdInfo->fgDriverDomainMCR = FALSE; -+ prCmdInfo->ucCmdSeqNum = ucCmdSeqNum; -+ prCmdInfo->u4SetInfoLen = u4SetQueryInfoLen; -+ prCmdInfo->pvInformationBuffer = pvSetQueryBuffer; -+ prCmdInfo->u4InformationBufferLength = u4SetQueryBufferLen; -+ -+ /* Setup WIFI_CMD_T (no payload) */ -+ prWifiCmd = (P_WIFI_CMD_T) (prCmdInfo->pucInfoBuffer); -+ prWifiCmd->u2TxByteCount_UserPriority = prCmdInfo->u2InfoBufLen; -+ prWifiCmd->ucCID = prCmdInfo->ucCID; -+ prWifiCmd->ucSetQuery = prCmdInfo->fgSetQuery; -+ prWifiCmd->ucSeqNum = prCmdInfo->ucCmdSeqNum; -+ -+ if (u4SetQueryInfoLen > 0 && pucInfoBuffer != NULL) -+ kalMemCopy(prWifiCmd->aucBuffer, pucInfoBuffer, u4SetQueryInfoLen); -+ /* insert into prCmdQueue */ -+ kalEnqueueCommand(prGlueInfo, (P_QUE_ENTRY_T) prCmdInfo); -+ -+ /* wakeup txServiceThread later */ -+ GLUE_SET_EVENT(prGlueInfo); -+ return WLAN_STATUS_PENDING; -+} -+ -+#if CFG_SUPPORT_WAPI -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called by WAPI ui to set wapi mode, which is needed to info the the driver -+* to operation at WAPI mode while driver initialize. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set -+* \param[in] u4SetBufferLen The length of the set buffer -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed due to invalid length of -+* the set buffer, returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_DATA If new setting value is wrong. -+* \retval WLAN_STATUS_INVALID_LENGTH -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetWapiMode(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ DEBUGFUNC("wlanoidSetWapiMode"); -+ DBGLOG(OID, LOUD, "\r\n"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ ASSERT(pvSetBuffer); -+ -+ /* Todo:: For support WAPI and Wi-Fi at same driver, use the set wapi assoc ie at the check point */ -+ /* The Adapter Connection setting fgUseWapi will cleat whil oid set mode (infra), */ -+ /* And set fgUseWapi True while set wapi assoc ie */ -+ /* policay selection, add key all depend on this flag, */ -+ /* The fgUseWapi may remove later */ -+ if (*(PUINT_32) pvSetBuffer) -+ prAdapter->fgUseWapi = TRUE; -+ else -+ prAdapter->fgUseWapi = FALSE; -+ -+#if 0 -+ prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, (CMD_HDR_SIZE + 4)); -+ -+ if (!prCmdInfo) { -+ DBGLOG(OID, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); -+ return WLAN_STATUS_FAILURE; -+ } -+ /* increase command sequence number */ -+ ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter); -+ -+ /* compose CMD_BUILD_CONNECTION cmd pkt */ -+ prCmdInfo->eCmdType = COMMAND_TYPE_NETWORK_IOCTL; -+ prCmdInfo->eNetworkType = NETWORK_TYPE_AIS_INDEX; -+ prCmdInfo->u2InfoBufLen = CMD_HDR_SIZE + 4; -+ prCmdInfo->pfCmdDoneHandler = nicCmdEventSetCommon; -+ prCmdInfo->pfCmdTimeoutHandler = NULL; -+ prCmdInfo->fgIsOid = TRUE; -+ prCmdInfo->ucCID = CMD_ID_WAPI_MODE; -+ prCmdInfo->fgSetQuery = TRUE; -+ prCmdInfo->fgNeedResp = FALSE; -+ prCmdInfo->fgDriverDomainMCR = FALSE; -+ prCmdInfo->ucCmdSeqNum = ucCmdSeqNum; -+ prCmdInfo->u4SetInfoLen = u4SetBufferLen; -+ prCmdInfo->pvInformationBuffer = pvSetBuffer; -+ prCmdInfo->u4InformationBufferLength = u4SetBufferLen; -+ -+ /* Setup WIFI_CMD_T */ -+ prWifiCmd = (P_WIFI_CMD_T) (prCmdInfo->pucInfoBuffer); -+ prWifiCmd->u2TxByteCount_UserPriority = prCmdInfo->u2InfoBufLen; -+ prWifiCmd->ucCID = prCmdInfo->ucCID; -+ prWifiCmd->ucSetQuery = prCmdInfo->fgSetQuery; -+ prWifiCmd->ucSeqNum = prCmdInfo->ucCmdSeqNum; -+ -+ cp = (PUINT_8) (prWifiCmd->aucBuffer); -+ -+ kalMemCopy(cp, (PUINT_8) pvSetBuffer, 4); -+ -+ /* insert into prCmdQueue */ -+ kalEnqueueCommand(prGlueInfo, (P_QUE_ENTRY_T) prCmdInfo); -+ -+ /* wakeup txServiceThread later */ -+ GLUE_SET_EVENT(prGlueInfo); -+ -+ return WLAN_STATUS_PENDING; -+#else -+ return WLAN_STATUS_SUCCESS; -+#endif -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called by WAPI to set the assoc info, which is needed to add to -+* Association request frame while join WAPI AP. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set -+* \param[in] u4SetBufferLen The length of the set buffer -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed due to invalid length of -+* the set buffer, returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_DATA If new setting value is wrong. -+* \retval WLAN_STATUS_INVALID_LENGTH -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetWapiAssocInfo(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ P_WAPI_INFO_ELEM_T prWapiInfo; -+ PUINT_8 cp; -+ UINT_16 u2AuthSuiteCount = 0; -+ UINT_16 u2PairSuiteCount = 0; -+ UINT_32 u4AuthKeyMgtSuite = 0; -+ UINT_32 u4PairSuite = 0; -+ UINT_32 u4GroupSuite = 0; -+ -+ ASSERT(prAdapter); -+ ASSERT(pvSetBuffer); -+ ASSERT(pu4SetInfoLen); -+ -+ DEBUGFUNC("wlanoidSetWapiAssocInfo"); -+ DBGLOG(OID, LOUD, "\r\n"); -+ -+ if (u4SetBufferLen < 20 /* From EID to Group cipher */) { -+ prAdapter->rWifiVar.rConnSettings.fgWapiMode = FALSE; -+ DBGLOG(SEC, INFO, "fgWapiMode = FALSE due to u4SetBufferLen %u < 20!\n", u4SetBufferLen); -+ return WLAN_STATUS_INVALID_LENGTH; -+ } -+ -+ prAdapter->rWifiVar.rConnSettings.fgWapiMode = TRUE; -+ -+ /* if (prWapiInfo->ucElemId != ELEM_ID_WAPI) */ -+ /* DBGLOG(SEC, TRACE, ("Not WAPI IE ?!\n")); */ -+ -+ /* if (prWapiInfo->ucLength < 18) */ -+ /* return WLAN_STATUS_INVALID_LENGTH; */ -+ -+ *pu4SetInfoLen = u4SetBufferLen; -+ -+ prWapiInfo = (P_WAPI_INFO_ELEM_T) pvSetBuffer; -+ -+ if (prWapiInfo->ucElemId != ELEM_ID_WAPI) { -+ DBGLOG(SEC, INFO, "Not WAPI IE ?! u4SetBufferLen = %u\n", u4SetBufferLen); -+ prAdapter->rWifiVar.rConnSettings.fgWapiMode = FALSE; -+ return WLAN_STATUS_INVALID_LENGTH; -+ } -+ -+ if (prWapiInfo->ucLength < 18) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ /* Skip Version check */ -+ cp = (PUINT_8) &prWapiInfo->u2AuthKeyMgtSuiteCount; -+ -+ WLAN_GET_FIELD_16(cp, &u2AuthSuiteCount); -+ -+ if (u2AuthSuiteCount > 1) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ cp = (PUINT_8) &prWapiInfo->aucAuthKeyMgtSuite1[0]; -+ WLAN_GET_FIELD_32(cp, &u4AuthKeyMgtSuite); -+ -+ DBGLOG(SEC, TRACE, "WAPI: Assoc Info auth mgt suite [%d]: %02x-%02x-%02x-%02x\n", -+ u2AuthSuiteCount, -+ (UCHAR) (u4AuthKeyMgtSuite & 0x000000FF), -+ (UCHAR) ((u4AuthKeyMgtSuite >> 8) & 0x000000FF), -+ (UCHAR) ((u4AuthKeyMgtSuite >> 16) & 0x000000FF), -+ (UCHAR) ((u4AuthKeyMgtSuite >> 24) & 0x000000FF)); -+ -+ if (u4AuthKeyMgtSuite != WAPI_AKM_SUITE_802_1X && u4AuthKeyMgtSuite != WAPI_AKM_SUITE_PSK) -+ ASSERT(FALSE); -+ -+ cp += 4; -+ WLAN_GET_FIELD_16(cp, &u2PairSuiteCount); -+ if (u2PairSuiteCount > 1) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ cp += 2; -+ WLAN_GET_FIELD_32(cp, &u4PairSuite); -+ DBGLOG(SEC, TRACE, "WAPI: Assoc Info pairwise cipher suite [%d]: %02x-%02x-%02x-%02x\n", -+ u2PairSuiteCount, -+ (UCHAR) (u4PairSuite & 0x000000FF), -+ (UCHAR) ((u4PairSuite >> 8) & 0x000000FF), -+ (UCHAR) ((u4PairSuite >> 16) & 0x000000FF), (UCHAR) ((u4PairSuite >> 24) & 0x000000FF)); -+ -+ if (u4PairSuite != WAPI_CIPHER_SUITE_WPI) -+ ASSERT(FALSE); -+ -+ cp += 4; -+ WLAN_GET_FIELD_32(cp, &u4GroupSuite); -+ DBGLOG(SEC, TRACE, "WAPI: Assoc Info group cipher suite : %02x-%02x-%02x-%02x\n", -+ (UCHAR) (u4GroupSuite & 0x000000FF), -+ (UCHAR) ((u4GroupSuite >> 8) & 0x000000FF), -+ (UCHAR) ((u4GroupSuite >> 16) & 0x000000FF), (UCHAR) ((u4GroupSuite >> 24) & 0x000000FF)); -+ -+ if (u4GroupSuite != WAPI_CIPHER_SUITE_WPI) -+ ASSERT(FALSE); -+ -+ prAdapter->rWifiVar.rConnSettings.u4WapiSelectedAKMSuite = u4AuthKeyMgtSuite; -+ prAdapter->rWifiVar.rConnSettings.u4WapiSelectedPairwiseCipher = u4PairSuite; -+ prAdapter->rWifiVar.rConnSettings.u4WapiSelectedGroupCipher = u4GroupSuite; -+ -+ kalMemCopy(prAdapter->prGlueInfo->aucWapiAssocInfoIEs, pvSetBuffer, u4SetBufferLen); -+ prAdapter->prGlueInfo->u2WapiAssocInfoIESz = (UINT_16) u4SetBufferLen; -+ DBGLOG(SEC, TRACE, "Assoc Info IE sz %u\n", u4SetBufferLen); -+ -+ return WLAN_STATUS_SUCCESS; -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to set the wpi key to the driver. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_ADAPTER_NOT_READY -+* \retval WLAN_STATUS_INVALID_LENGTH -+* \retval WLAN_STATUS_INVALID_DATA -+* -+* \note The setting buffer P_PARAM_WPI_KEY, which is set by NDIS, is unpacked. -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetWapiKey(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ P_GLUE_INFO_T prGlueInfo; -+ P_CMD_INFO_T prCmdInfo; -+ P_WIFI_CMD_T prWifiCmd; -+ P_PARAM_WPI_KEY_T prNewKey; -+ P_CMD_802_11_KEY prCmdKey; -+ PUINT_8 pc; -+ UINT_8 ucCmdSeqNum; -+ -+ DEBUGFUNC("wlanoidSetWapiKey"); -+ DBGLOG(OID, LOUD, "\r\n"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pvSetBuffer); -+ ASSERT(pu4SetInfoLen); -+ -+ if (prAdapter->rAcpiState == ACPI_STATE_D3) { -+ DBGLOG(OID, WARN, "Fail in set add key! (Adapter not ready). ACPI=D%d, Radio=%d\r\n", -+ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); -+ return WLAN_STATUS_ADAPTER_NOT_READY; -+ } -+ -+ prNewKey = (P_PARAM_WPI_KEY_T) pvSetBuffer; -+ -+ DBGLOG_MEM8(OID, TRACE, (PUINT_8) pvSetBuffer, 560); -+ pc = (PUINT_8) pvSetBuffer; -+ -+ *pu4SetInfoLen = u4SetBufferLen; -+ -+ /* Exception check */ -+ if (prNewKey->ucKeyID != 0x1 || prNewKey->ucKeyID != 0x0) { -+ prNewKey->ucKeyID = prNewKey->ucKeyID & BIT(0); -+ /* DBGLOG(SEC, INFO, ("Invalid WAPI key ID (%d)\r\n", prNewKey->ucKeyID)); */ -+ } -+ -+ /* Dump P_PARAM_WPI_KEY_T content. */ -+ DBGLOG(OID, TRACE, "Set: Dump P_PARAM_WPI_KEY_T content\r\n"); -+ DBGLOG(OID, TRACE, "TYPE : %d\r\n", prNewKey->eKeyType); -+ DBGLOG(OID, TRACE, "Direction : %d\r\n", prNewKey->eDirection); -+ DBGLOG(OID, TRACE, "KeyID : %d\r\n", prNewKey->ucKeyID); -+ DBGLOG(OID, TRACE, "AddressIndex:\r\n"); -+ DBGLOG_MEM8(OID, TRACE, prNewKey->aucAddrIndex, 12); -+ prNewKey->u4LenWPIEK = 16; -+ -+ DBGLOG_MEM8(OID, TRACE, (PUINT_8) prNewKey->aucWPIEK, (UINT_8) prNewKey->u4LenWPIEK); -+ prNewKey->u4LenWPICK = 16; -+ -+ DBGLOG(OID, TRACE, "CK Key(%d):\r\n", (UINT_8) prNewKey->u4LenWPICK); -+ DBGLOG_MEM8(OID, TRACE, (PUINT_8) prNewKey->aucWPICK, (UINT_8) prNewKey->u4LenWPICK); -+ DBGLOG(OID, TRACE, "PN:\r\n"); -+ if (prNewKey->eKeyType == 0) { -+ prNewKey->aucPN[0] = 0x5c; -+ prNewKey->aucPN[1] = 0x36; -+ prNewKey->aucPN[2] = 0x5c; -+ prNewKey->aucPN[3] = 0x36; -+ prNewKey->aucPN[4] = 0x5c; -+ prNewKey->aucPN[5] = 0x36; -+ prNewKey->aucPN[6] = 0x5c; -+ prNewKey->aucPN[7] = 0x36; -+ prNewKey->aucPN[8] = 0x5c; -+ prNewKey->aucPN[9] = 0x36; -+ prNewKey->aucPN[10] = 0x5c; -+ prNewKey->aucPN[11] = 0x36; -+ prNewKey->aucPN[12] = 0x5c; -+ prNewKey->aucPN[13] = 0x36; -+ prNewKey->aucPN[14] = 0x5c; -+ prNewKey->aucPN[15] = 0x36; -+ } -+ -+ DBGLOG_MEM8(OID, TRACE, (PUINT_8) prNewKey->aucPN, 16); -+ -+ prGlueInfo = prAdapter->prGlueInfo; -+ -+ prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, (CMD_HDR_SIZE + u4SetBufferLen)); -+ -+ if (!prCmdInfo) { -+ DBGLOG(OID, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); -+ return WLAN_STATUS_FAILURE; -+ } -+ /* increase command sequence number */ -+ ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter); -+ -+ /* compose CMD_ID_ADD_REMOVE_KEY cmd pkt */ -+ prCmdInfo->eCmdType = COMMAND_TYPE_NETWORK_IOCTL; -+ prCmdInfo->eNetworkType = NETWORK_TYPE_AIS_INDEX; -+ prCmdInfo->u2InfoBufLen = CMD_HDR_SIZE + sizeof(CMD_802_11_KEY); -+ prCmdInfo->pfCmdDoneHandler = nicCmdEventSetCommon; -+ prCmdInfo->pfCmdTimeoutHandler = nicOidCmdTimeoutCommon; -+ prCmdInfo->fgIsOid = TRUE; -+ prCmdInfo->ucCID = CMD_ID_ADD_REMOVE_KEY; -+ prCmdInfo->fgSetQuery = TRUE; -+ prCmdInfo->fgNeedResp = FALSE; -+ prCmdInfo->fgDriverDomainMCR = FALSE; -+ prCmdInfo->ucCmdSeqNum = ucCmdSeqNum; -+ prCmdInfo->u4SetInfoLen = u4SetBufferLen; -+ prCmdInfo->pvInformationBuffer = pvSetBuffer; -+ prCmdInfo->u4InformationBufferLength = u4SetBufferLen; -+ -+ /* Setup WIFI_CMD_T */ -+ prWifiCmd = (P_WIFI_CMD_T) (prCmdInfo->pucInfoBuffer); -+ prWifiCmd->u2TxByteCount_UserPriority = prCmdInfo->u2InfoBufLen; -+ prWifiCmd->ucCID = prCmdInfo->ucCID; -+ prWifiCmd->ucSetQuery = prCmdInfo->fgSetQuery; -+ prWifiCmd->ucSeqNum = prCmdInfo->ucCmdSeqNum; -+ -+ prCmdKey = (P_CMD_802_11_KEY) (prWifiCmd->aucBuffer); -+ -+ kalMemZero(prCmdKey, sizeof(CMD_802_11_KEY)); -+ -+ prCmdKey->ucAddRemove = 1; /* Add */ -+ -+ if (prNewKey->eKeyType == ENUM_WPI_PAIRWISE_KEY) { -+ prCmdKey->ucTxKey = 1; -+ prCmdKey->ucKeyType = 1; -+ } -+ -+ kalMemCopy(prCmdKey->aucPeerAddr, (PUINT_8) prNewKey->aucAddrIndex, MAC_ADDR_LEN); -+ -+ prCmdKey->ucNetType = 0; /* AIS */ -+ -+ prCmdKey->ucKeyId = prNewKey->ucKeyID; -+ -+ prCmdKey->ucKeyLen = 32; -+ -+ prCmdKey->ucAlgorithmId = CIPHER_SUITE_WPI; -+ -+ kalMemCopy(prCmdKey->aucKeyMaterial, (PUINT_8) prNewKey->aucWPIEK, 16); -+ -+ kalMemCopy(prCmdKey->aucKeyMaterial + 16, (PUINT_8) prNewKey->aucWPICK, 16); -+ -+ kalMemCopy(prCmdKey->aucKeyRsc, (PUINT_8) prNewKey->aucPN, 16); -+ -+ /* insert into prCmdQueue */ -+ kalEnqueueCommand(prGlueInfo, (P_QUE_ENTRY_T) prCmdInfo); -+ -+ /* wakeup txServiceThread later */ -+ GLUE_SET_EVENT(prGlueInfo); -+ -+ return WLAN_STATUS_PENDING; -+} /* wlanoidSetAddKey */ -+#endif -+ -+#if CFG_SUPPORT_WPS2 -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called by WSC to set the assoc info, which is needed to add to -+* Association request frame while join WPS AP. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set -+* \param[in] u4SetBufferLen The length of the set buffer -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed due to invalid length of -+* the set buffer, returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_DATA If new setting value is wrong. -+* \retval WLAN_STATUS_INVALID_LENGTH -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetWSCAssocInfo(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ ASSERT(prAdapter); -+ ASSERT(pvSetBuffer); -+ ASSERT(pu4SetInfoLen); -+ -+ DEBUGFUNC("wlanoidSetWSCAssocInfo"); -+ DBGLOG(OID, LOUD, "\r\n"); -+ -+ if (u4SetBufferLen == 0) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ *pu4SetInfoLen = u4SetBufferLen; -+ -+ kalMemCopy(prAdapter->prGlueInfo->aucWSCAssocInfoIE, pvSetBuffer, u4SetBufferLen); -+ prAdapter->prGlueInfo->u2WSCAssocInfoIELen = (UINT_16) u4SetBufferLen; -+ DBGLOG(SEC, TRACE, "Assoc Info IE sz %u\n", u4SetBufferLen); -+ -+ return WLAN_STATUS_SUCCESS; -+ -+} -+#endif -+ -+#if CFG_ENABLE_WAKEUP_ON_LAN -+WLAN_STATUS -+wlanoidSetAddWakeupPattern(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ P_PARAM_PM_PACKET_PATTERN prPacketPattern; -+ -+ DEBUGFUNC("wlanoidSetAddWakeupPattern"); -+ DBGLOG(OID, LOUD, "\r\n"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ *pu4SetInfoLen = sizeof(PARAM_PM_PACKET_PATTERN); -+ -+ if (u4SetBufferLen < sizeof(PARAM_PM_PACKET_PATTERN)) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ ASSERT(pvSetBuffer); -+ -+ prPacketPattern = (P_PARAM_PM_PACKET_PATTERN) pvSetBuffer; -+ -+ /* FIXME: -+ * Send the struct to firmware */ -+ -+ return WLAN_STATUS_FAILURE; -+} -+ -+WLAN_STATUS -+wlanoidSetRemoveWakeupPattern(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ P_PARAM_PM_PACKET_PATTERN prPacketPattern; -+ -+ DEBUGFUNC("wlanoidSetAddWakeupPattern"); -+ DBGLOG(OID, LOUD, "\r\n"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ *pu4SetInfoLen = sizeof(PARAM_PM_PACKET_PATTERN); -+ -+ if (u4SetBufferLen < sizeof(PARAM_PM_PACKET_PATTERN)) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ ASSERT(pvSetBuffer); -+ -+ prPacketPattern = (P_PARAM_PM_PACKET_PATTERN) pvSetBuffer; -+ -+ /* FIXME: -+ * Send the struct to firmware */ -+ -+ return WLAN_STATUS_FAILURE; -+} -+ -+WLAN_STATUS -+wlanoidQueryEnableWakeup(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ PUINT_32 pu4WakeupEventEnable; -+ -+ DEBUGFUNC("wlanoidQueryEnableWakeup"); -+ DBGLOG(OID, LOUD, "\r\n"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4QueryInfoLen); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ -+ *pu4QueryInfoLen = sizeof(UINT_32); -+ -+ if (u4QueryBufferLen < sizeof(UINT_32)) -+ return WLAN_STATUS_BUFFER_TOO_SHORT; -+ -+ pu4WakeupEventEnable = (PUINT_32) pvQueryBuffer; -+ -+ *pu4WakeupEventEnable = prAdapter->u4WakeupEventEnable; -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+WLAN_STATUS -+wlanoidSetEnableWakeup(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ PUINT_32 pu4WakeupEventEnable; -+ -+ DEBUGFUNC("wlanoidSetEnableWakup"); -+ DBGLOG(OID, LOUD, "\r\n"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ *pu4SetInfoLen = sizeof(UINT_32); -+ -+ if (u4SetBufferLen < sizeof(UINT_32)) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ ASSERT(pvSetBuffer); -+ -+ pu4WakeupEventEnable = (PUINT_32) pvSetBuffer; -+ prAdapter->u4WakeupEventEnable = *pu4WakeupEventEnable; -+ -+ /* FIXME: -+ * Send Command Event for setting wakeup-pattern / Magic Packet to firmware -+ * */ -+ -+ return WLAN_STATUS_FAILURE; -+} -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to configure PS related settings for WMM-PS test. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetWiFiWmmPsTest(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ P_PARAM_CUSTOM_WMM_PS_TEST_STRUCT_T prWmmPsTestInfo; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ CMD_SET_WMM_PS_TEST_STRUCT_T rSetWmmPsTestParam; -+ UINT_16 u2CmdBufLen; -+ P_PM_PROFILE_SETUP_INFO_T prPmProfSetupInfo; -+ P_BSS_INFO_T prBssInfo; -+ -+ DEBUGFUNC("wlanoidSetWiFiWmmPsTest"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pvSetBuffer); -+ ASSERT(pu4SetInfoLen); -+ -+ *pu4SetInfoLen = sizeof(PARAM_CUSTOM_WMM_PS_TEST_STRUCT_T); -+ -+ prWmmPsTestInfo = (P_PARAM_CUSTOM_WMM_PS_TEST_STRUCT_T) pvSetBuffer; -+ -+ rSetWmmPsTestParam.ucNetTypeIndex = NETWORK_TYPE_AIS_INDEX; -+ rSetWmmPsTestParam.bmfgApsdEnAc = prWmmPsTestInfo->bmfgApsdEnAc; -+ rSetWmmPsTestParam.ucIsEnterPsAtOnce = prWmmPsTestInfo->ucIsEnterPsAtOnce; -+ rSetWmmPsTestParam.ucIsDisableUcTrigger = prWmmPsTestInfo->ucIsDisableUcTrigger; -+ -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[rSetWmmPsTestParam.ucNetTypeIndex]); -+ prPmProfSetupInfo = &prBssInfo->rPmProfSetupInfo; -+ prPmProfSetupInfo->ucBmpDeliveryAC = (rSetWmmPsTestParam.bmfgApsdEnAc >> 4) & BITS(0, 3); -+ prPmProfSetupInfo->ucBmpTriggerAC = rSetWmmPsTestParam.bmfgApsdEnAc & BITS(0, 3); -+ -+ u2CmdBufLen = sizeof(CMD_SET_WMM_PS_TEST_STRUCT_T); -+ -+#if 0 -+ /* it will apply the disable trig or not immediately */ -+ if (prPmInfo->ucWmmPsDisableUcPoll && prPmInfo->ucWmmPsConnWithTrig) -+ ; /* NIC_PM_WMM_PS_DISABLE_UC_TRIG(prAdapter, TRUE); */ -+ else -+ ; /* NIC_PM_WMM_PS_DISABLE_UC_TRIG(prAdapter, FALSE); */ -+#endif -+ -+ rStatus = wlanSendSetQueryCmd(prAdapter, CMD_ID_SET_WMM_PS_TEST_PARMS, TRUE, FALSE, TRUE, NULL, /* TODO? */ -+ NULL, u2CmdBufLen, (PUINT_8) &rSetWmmPsTestParam, NULL, 0); -+ -+ return rStatus; -+} /* wlanoidSetWiFiWmmPsTest */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to configure enable/disable TX A-MPDU feature. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetTxAmpdu(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ CMD_TX_AMPDU_T rTxAmpdu; -+ UINT_16 u2CmdBufLen; -+ PBOOLEAN pfgEnable; -+ -+ DEBUGFUNC("wlanoidSetTxAmpdu"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pvSetBuffer); -+ ASSERT(pu4SetInfoLen); -+ -+ *pu4SetInfoLen = sizeof(BOOLEAN); -+ -+ pfgEnable = (PBOOLEAN) pvSetBuffer; -+ -+ rTxAmpdu.fgEnable = *pfgEnable; -+ -+ u2CmdBufLen = sizeof(CMD_TX_AMPDU_T); -+ -+ rStatus = wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_TX_AMPDU, -+ TRUE, FALSE, TRUE, NULL, NULL, u2CmdBufLen, (PUINT_8) &rTxAmpdu, NULL, 0); -+ -+ return rStatus; -+} /* wlanoidSetTxAmpdu */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to configure reject/accept ADDBA Request. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetAddbaReject(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ CMD_ADDBA_REJECT_T rAddbaReject; -+ UINT_16 u2CmdBufLen; -+ PBOOLEAN pfgEnable; -+ -+ DEBUGFUNC("wlanoidSetAddbaReject"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pvSetBuffer); -+ ASSERT(pu4SetInfoLen); -+ -+ *pu4SetInfoLen = sizeof(BOOLEAN); -+ -+ pfgEnable = (PBOOLEAN) pvSetBuffer; -+ -+ rAddbaReject.fgEnable = *pfgEnable; -+ -+ u2CmdBufLen = sizeof(CMD_ADDBA_REJECT_T); -+ -+ rStatus = wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_ADDBA_REJECT, -+ TRUE, FALSE, TRUE, NULL, NULL, u2CmdBufLen, (PUINT_8) &rAddbaReject, NULL, 0); -+ -+ return rStatus; -+} /* wlanoidSetAddbaReject */ -+ -+#if CFG_SLT_SUPPORT -+ -+WLAN_STATUS -+wlanoidQuerySLTStatus(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ WLAN_STATUS rWlanStatus = WLAN_STATUS_SUCCESS; -+ P_PARAM_MTK_SLT_TEST_STRUCT_T prMtkSltInfo = (P_PARAM_MTK_SLT_TEST_STRUCT_T) NULL; -+ P_SLT_INFO_T prSltInfo = (P_SLT_INFO_T) NULL; -+ -+ DEBUGFUNC("wlanoidQuerySLTStatus"); -+ DBGLOG(OID, LOUD, "\r\n"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4QueryInfoLen); -+ -+ *pu4QueryInfoLen = sizeof(PARAM_MTK_SLT_TEST_STRUCT_T); -+ -+ if (u4QueryBufferLen < sizeof(PARAM_MTK_SLT_TEST_STRUCT_T)) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ ASSERT(pvQueryBuffer); -+ -+ prMtkSltInfo = (P_PARAM_MTK_SLT_TEST_STRUCT_T) pvQueryBuffer; -+ -+ prSltInfo = &(prAdapter->rWifiVar.rSltInfo); -+ -+ switch (prMtkSltInfo->rSltFuncIdx) { -+ case ENUM_MTK_SLT_FUNC_LP_SET: -+ { -+ P_PARAM_MTK_SLT_LP_TEST_STRUCT_T prLpSetting = (P_PARAM_MTK_SLT_LP_TEST_STRUCT_T) NULL; -+ -+ ASSERT(prMtkSltInfo->u4FuncInfoLen == sizeof(PARAM_MTK_SLT_LP_TEST_STRUCT_T)); -+ -+ prLpSetting = (P_PARAM_MTK_SLT_LP_TEST_STRUCT_T) &prMtkSltInfo->unFuncInfoContent; -+ -+ prLpSetting->u4BcnRcvNum = prSltInfo->u4BeaconReceiveCnt; -+ } -+ break; -+ default: -+ /* TBD... */ -+ break; -+ } -+ -+ return rWlanStatus; -+} /* wlanoidQuerySLTStatus */ -+ -+WLAN_STATUS -+wlanoidUpdateSLTMode(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ WLAN_STATUS rWlanStatus = WLAN_STATUS_SUCCESS; -+ P_PARAM_MTK_SLT_TEST_STRUCT_T prMtkSltInfo = (P_PARAM_MTK_SLT_TEST_STRUCT_T) NULL; -+ P_SLT_INFO_T prSltInfo = (P_SLT_INFO_T) NULL; -+ P_BSS_DESC_T prBssDesc = (P_BSS_DESC_T) NULL; -+ P_STA_RECORD_T prStaRec = (P_STA_RECORD_T) NULL; -+ P_BSS_INFO_T prBssInfo = (P_BSS_INFO_T) NULL; -+ -+ /* 1. Action: Update or Initial Set -+ * 2. Role. -+ * 3. Target MAC address. -+ * 4. RF BW & Rate Settings -+ */ -+ -+ DEBUGFUNC("wlanoidUpdateSLTMode"); -+ DBGLOG(OID, LOUD, "\r\n"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ *pu4SetInfoLen = sizeof(PARAM_MTK_SLT_TEST_STRUCT_T); -+ -+ if (u4SetBufferLen < sizeof(PARAM_MTK_SLT_TEST_STRUCT_T)) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ ASSERT(pvSetBuffer); -+ -+ prMtkSltInfo = (P_PARAM_MTK_SLT_TEST_STRUCT_T) pvSetBuffer; -+ -+ prSltInfo = &(prAdapter->rWifiVar.rSltInfo); -+ prBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]; -+ -+ switch (prMtkSltInfo->rSltFuncIdx) { -+ case ENUM_MTK_SLT_FUNC_INITIAL: /* Initialize */ -+ { -+ P_PARAM_MTK_SLT_INITIAL_STRUCT_T prMtkSltInit = (P_PARAM_MTK_SLT_INITIAL_STRUCT_T) NULL; -+ -+ ASSERT(prMtkSltInfo->u4FuncInfoLen == sizeof(PARAM_MTK_SLT_INITIAL_STRUCT_T)); -+ -+ prMtkSltInit = (P_PARAM_MTK_SLT_INITIAL_STRUCT_T) &prMtkSltInfo->unFuncInfoContent; -+ -+ if (prSltInfo->prPseudoStaRec != NULL) { -+ /* The driver has been initialized. */ -+ prSltInfo->prPseudoStaRec = NULL; -+ } -+ -+ prSltInfo->prPseudoBssDesc = scanSearchExistingBssDesc(prAdapter, -+ BSS_TYPE_IBSS, -+ prMtkSltInit->aucTargetMacAddr, -+ prMtkSltInit->aucTargetMacAddr); -+ -+ prSltInfo->u2SiteID = prMtkSltInit->u2SiteID; -+ -+ /* Bandwidth 2.4G: Channel 1~14 -+ * Bandwidth 5G: *36, 40, 44, 48, 52, 56, 60, 64, -+ * *100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, -+ * 149, 153, *157, 161, -+ * 184, 188, 192, 196, 200, 204, 208, 212, *216 -+ */ -+ prSltInfo->ucChannel2G4 = 1 + (prSltInfo->u2SiteID % 4) * 5; -+ -+ switch (prSltInfo->ucChannel2G4) { -+ case 1: -+ prSltInfo->ucChannel5G = 36; -+ break; -+ case 6: -+ prSltInfo->ucChannel5G = 52; -+ break; -+ case 11: -+ prSltInfo->ucChannel5G = 104; -+ break; -+ case 16: -+ prSltInfo->ucChannel2G4 = 14; -+ prSltInfo->ucChannel5G = 161; -+ break; -+ default: -+ ASSERT(FALSE); -+ } -+ -+ if (prSltInfo->prPseudoBssDesc == NULL) { -+ do { -+ prSltInfo->prPseudoBssDesc = scanAllocateBssDesc(prAdapter); -+ -+ if (prSltInfo->prPseudoBssDesc == NULL) { -+ rWlanStatus = WLAN_STATUS_FAILURE; -+ break; -+ } -+ prBssDesc = prSltInfo->prPseudoBssDesc; -+ } while (FALSE); -+ } else { -+ prBssDesc = prSltInfo->prPseudoBssDesc; -+ } -+ -+ if (prBssDesc) { -+ prBssDesc->eBSSType = BSS_TYPE_IBSS; -+ -+ COPY_MAC_ADDR(prBssDesc->aucSrcAddr, prMtkSltInit->aucTargetMacAddr); -+ COPY_MAC_ADDR(prBssDesc->aucBSSID, prBssInfo->aucOwnMacAddr); -+ -+ prBssDesc->u2BeaconInterval = 100; -+ prBssDesc->u2ATIMWindow = 0; -+ prBssDesc->ucDTIMPeriod = 1; -+ -+ prBssDesc->u2IELength = 0; -+ -+ prBssDesc->fgIsERPPresent = TRUE; -+ prBssDesc->fgIsHTPresent = TRUE; -+ -+ prBssDesc->u2OperationalRateSet = BIT(RATE_36M_INDEX); -+ prBssDesc->u2BSSBasicRateSet = BIT(RATE_36M_INDEX); -+ prBssDesc->fgIsUnknownBssBasicRate = FALSE; -+ -+ prBssDesc->fgIsLargerTSF = TRUE; -+ -+ prBssDesc->eBand = BAND_2G4; -+ -+ prBssDesc->ucChannelNum = prSltInfo->ucChannel2G4; -+ -+ prBssDesc->ucPhyTypeSet = PHY_TYPE_SET_802_11ABGN; -+ -+ GET_CURRENT_SYSTIME(&prBssDesc->rUpdateTime); -+ } -+ } -+ break; -+ case ENUM_MTK_SLT_FUNC_RATE_SET: /* Update RF Settings. */ -+ if (prSltInfo->prPseudoStaRec == NULL) { -+ rWlanStatus = WLAN_STATUS_FAILURE; -+ break; -+ } -+ -+ P_PARAM_MTK_SLT_TR_TEST_STRUCT_T prTRSetting = (P_PARAM_MTK_SLT_TR_TEST_STRUCT_T) NULL; -+ -+ ASSERT(prMtkSltInfo->u4FuncInfoLen == sizeof(PARAM_MTK_SLT_TR_TEST_STRUCT_T)); -+ -+ prStaRec = prSltInfo->prPseudoStaRec; -+ prTRSetting = (P_PARAM_MTK_SLT_TR_TEST_STRUCT_T) &prMtkSltInfo->unFuncInfoContent; -+ -+ if (prTRSetting->rNetworkType == PARAM_NETWORK_TYPE_OFDM5) { -+ prBssInfo->eBand = BAND_5G; -+ prBssInfo->ucPrimaryChannel = prSltInfo->ucChannel5G; -+ } -+ if (prTRSetting->rNetworkType == PARAM_NETWORK_TYPE_OFDM24) { -+ prBssInfo->eBand = BAND_2G4; -+ prBssInfo->ucPrimaryChannel = prSltInfo->ucChannel2G4; -+ } -+ -+ if ((prTRSetting->u4FixedRate & FIXED_BW_DL40) != 0) { -+ /* RF 40 */ -+ /* It would controls RFBW capability in WTBL. */ -+ prStaRec->u2HtCapInfo |= HT_CAP_INFO_SUP_CHNL_WIDTH; -+ /* This controls RF BW, RF BW would be 40 only if */ -+ /* 1. PHY_TYPE_BIT_HT is TRUE. */ -+ /* 2. SCO is SCA/SCB. */ -+ prStaRec->ucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; -+ -+ /* U20/L20 Control. */ -+ switch (prTRSetting->u4FixedRate & 0xC000) { -+ case FIXED_EXT_CHNL_U20: -+ prBssInfo->eBssSCO = CHNL_EXT_SCB; /* +2 */ -+ if (prTRSetting->rNetworkType == PARAM_NETWORK_TYPE_OFDM5) -+ prBssInfo->ucPrimaryChannel += 2; -+ else { -+ /* For channel 1, testing L20 at channel 8. */ -+ if (prBssInfo->ucPrimaryChannel < 5) -+ prBssInfo->ucPrimaryChannel = 8; -+ } -+ break; -+ case FIXED_EXT_CHNL_L20: -+ default: /* 40M */ -+ prBssInfo->eBssSCO = CHNL_EXT_SCA; /* -2 */ -+ if (prTRSetting->rNetworkType == PARAM_NETWORK_TYPE_OFDM5) { -+ prBssInfo->ucPrimaryChannel -= 2; -+ } else { -+ /* For channel 11 / 14. testing U20 at channel 3. */ -+ if (prBssInfo->ucPrimaryChannel > 10) -+ prBssInfo->ucPrimaryChannel = 3; -+ } -+ break; -+ } -+ } else { -+ /* RF 20 */ -+ prStaRec->u2HtCapInfo &= ~HT_CAP_INFO_SUP_CHNL_WIDTH; -+ prBssInfo->eBssSCO = CHNL_EXT_SCN; -+ } -+ -+ prBssInfo->fgErpProtectMode = FALSE; -+ prBssInfo->eHtProtectMode = HT_PROTECT_MODE_NONE; -+ prBssInfo->eGfOperationMode = GF_MODE_NORMAL; -+ -+ nicUpdateBss(prAdapter, prBssInfo->ucNetTypeIndex); -+ -+ prStaRec->u2HtCapInfo &= ~(HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M); -+ -+ switch (prTRSetting->u4FixedRate & 0xFF) { -+ case RATE_OFDM_54M: -+ prStaRec->u2DesiredNonHTRateSet = BIT(RATE_54M_INDEX); -+ break; -+ case RATE_OFDM_48M: -+ prStaRec->u2DesiredNonHTRateSet = BIT(RATE_48M_INDEX); -+ break; -+ case RATE_OFDM_36M: -+ prStaRec->u2DesiredNonHTRateSet = BIT(RATE_36M_INDEX); -+ break; -+ case RATE_OFDM_24M: -+ prStaRec->u2DesiredNonHTRateSet = BIT(RATE_24M_INDEX); -+ break; -+ case RATE_OFDM_6M: -+ prStaRec->u2DesiredNonHTRateSet = BIT(RATE_6M_INDEX); -+ break; -+ case RATE_CCK_11M_LONG: -+ prStaRec->u2DesiredNonHTRateSet = BIT(RATE_11M_INDEX); -+ break; -+ case RATE_CCK_1M_LONG: -+ prStaRec->u2DesiredNonHTRateSet = BIT(RATE_1M_INDEX); -+ break; -+ case RATE_GF_MCS_0: -+ prStaRec->u2DesiredNonHTRateSet = BIT(RATE_HT_PHY_INDEX); -+ prStaRec->u2HtCapInfo |= HT_CAP_INFO_HT_GF; -+ break; -+ case RATE_MM_MCS_7: -+ prStaRec->u2DesiredNonHTRateSet = BIT(RATE_HT_PHY_INDEX); -+ prStaRec->u2HtCapInfo &= ~HT_CAP_INFO_HT_GF; -+#if 0 /* Only for Current Measurement Mode. */ -+ prStaRec->u2HtCapInfo |= (HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M); -+#endif -+ break; -+ case RATE_GF_MCS_7: -+ prStaRec->u2DesiredNonHTRateSet = BIT(RATE_HT_PHY_INDEX); -+ prStaRec->u2HtCapInfo |= HT_CAP_INFO_HT_GF; -+ break; -+ default: -+ prStaRec->u2DesiredNonHTRateSet = BIT(RATE_36M_INDEX); -+ break; -+ } -+ -+ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); -+ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_3); -+ -+ break; -+ case ENUM_MTK_SLT_FUNC_LP_SET: /* Reset LP Test Result. */ -+ { -+ P_PARAM_MTK_SLT_LP_TEST_STRUCT_T prLpSetting = (P_PARAM_MTK_SLT_LP_TEST_STRUCT_T) NULL; -+ -+ ASSERT(prMtkSltInfo->u4FuncInfoLen == sizeof(PARAM_MTK_SLT_LP_TEST_STRUCT_T)); -+ -+ prLpSetting = (P_PARAM_MTK_SLT_LP_TEST_STRUCT_T) &prMtkSltInfo->unFuncInfoContent; -+ -+ if (prSltInfo->prPseudoBssDesc == NULL) { -+ /* Please initial SLT Mode first. */ -+ break; -+ } -+ prBssDesc = prSltInfo->prPseudoBssDesc; -+ -+ switch (prLpSetting->rLpTestMode) { -+ case ENUM_MTK_LP_TEST_NORMAL: -+ /* In normal mode, we would use target MAC address to be the BSSID. */ -+ COPY_MAC_ADDR(prBssDesc->aucBSSID, prBssInfo->aucOwnMacAddr); -+ prSltInfo->fgIsDUT = FALSE; -+ break; -+ case ENUM_MTK_LP_TEST_GOLDEN_SAMPLE: -+ /* 1. Lower AIFS of BCN queue. -+ * 2. Fixed Random Number tobe 0. -+ */ -+ prSltInfo->fgIsDUT = FALSE; -+ /* In LP test mode, we would use MAC address of Golden Sample to be the BSSID. */ -+ COPY_MAC_ADDR(prBssDesc->aucBSSID, prBssInfo->aucOwnMacAddr); -+ break; -+ case ENUM_MTK_LP_TEST_DUT: -+ /* 1. Enter Sleep Mode. -+ * 2. Fix random number a large value & enlarge AIFN of BCN queue. -+ */ -+ COPY_MAC_ADDR(prBssDesc->aucBSSID, prBssDesc->aucSrcAddr); -+ prSltInfo->u4BeaconReceiveCnt = 0; -+ prSltInfo->fgIsDUT = TRUE; -+ break; -+ } -+ -+ } -+ -+ break; -+ default: -+ break; -+ } -+ -+ return WLAN_STATUS_FAILURE; -+ -+ return rWlanStatus; -+} /* wlanoidUpdateSLTMode */ -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to query NVRAM value. -+* -+* \param[in] pvAdapter Pointer to the Adapter structure. -+* \param[out] pvQueryBuf A pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_FAILURE -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryNvramRead(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ P_PARAM_CUSTOM_NVRAM_RW_STRUCT_T prNvramRwInfo; -+ UINT_16 u2Data; -+ BOOLEAN fgStatus; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ -+ DEBUGFUNC("wlanoidQueryNvramRead"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4QueryInfoLen); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ -+ *pu4QueryInfoLen = sizeof(PARAM_CUSTOM_NVRAM_RW_STRUCT_T); -+ -+ if (u4QueryBufferLen < sizeof(PARAM_CUSTOM_NVRAM_RW_STRUCT_T)) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ prNvramRwInfo = (P_PARAM_CUSTOM_NVRAM_RW_STRUCT_T) pvQueryBuffer; -+ -+ if (prNvramRwInfo->ucEepromMethod == PARAM_EEPROM_READ_METHOD_READ) { -+ /* change to byte offset */ -+ fgStatus = kalCfgDataRead16(prAdapter->prGlueInfo, -+ prNvramRwInfo->ucEepromIndex << 1, -+ &u2Data); -+ -+ if (fgStatus) { -+ prNvramRwInfo->u2EepromData = u2Data; -+ DBGLOG(OID, INFO, "NVRAM Read: index=%#X, data=%#02X\r\n", -+ prNvramRwInfo->ucEepromIndex, u2Data); -+ } else { -+ DBGLOG(OID, ERROR, "NVRAM Read Failed: index=%#x.\r\n", prNvramRwInfo->ucEepromIndex); -+ rStatus = WLAN_STATUS_FAILURE; -+ } -+ } else if (prNvramRwInfo->ucEepromMethod == PARAM_EEPROM_READ_METHOD_GETSIZE) { -+ prNvramRwInfo->u2EepromData = CFG_FILE_WIFI_REC_SIZE; -+ DBGLOG(OID, INFO, "EEPROM size =%d\r\n", prNvramRwInfo->u2EepromData); -+ } -+ -+ *pu4QueryInfoLen = sizeof(PARAM_CUSTOM_EEPROM_RW_STRUCT_T); -+ -+ return rStatus; -+} /* wlanoidQueryNvramRead */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to write NVRAM value. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_FAILURE -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetNvramWrite(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ P_PARAM_CUSTOM_NVRAM_RW_STRUCT_T prNvramRwInfo; -+ BOOLEAN fgStatus; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ -+ DEBUGFUNC("wlanoidSetNvramWrite"); -+ DBGLOG(OID, LOUD, "\n"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ *pu4SetInfoLen = sizeof(PARAM_CUSTOM_NVRAM_RW_STRUCT_T); -+ -+ if (u4SetBufferLen < sizeof(PARAM_CUSTOM_NVRAM_RW_STRUCT_T)) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ ASSERT(pvSetBuffer); -+ -+ prNvramRwInfo = (P_PARAM_CUSTOM_NVRAM_RW_STRUCT_T) pvSetBuffer; -+ -+ /* change to byte offset */ -+ fgStatus = kalCfgDataWrite16(prAdapter->prGlueInfo, -+ prNvramRwInfo->ucEepromIndex << 1, -+ prNvramRwInfo->u2EepromData); -+ -+ if (fgStatus == FALSE) { -+ DBGLOG(OID, ERROR, "NVRAM Write Failed.\r\n"); -+ rStatus = WLAN_STATUS_FAILURE; -+ } -+ -+ return rStatus; -+} /* wlanoidSetNvramWrite */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to get the config data source type. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_FAILURE -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryCfgSrcType(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ ASSERT(prAdapter); -+ -+ *pu4QueryInfoLen = sizeof(ENUM_CFG_SRC_TYPE_T); -+ -+ if (kalIsConfigurationExist(prAdapter->prGlueInfo) == TRUE) -+ *(P_ENUM_CFG_SRC_TYPE_T) pvQueryBuffer = CFG_SRC_TYPE_NVRAM; -+ else -+ *(P_ENUM_CFG_SRC_TYPE_T) pvQueryBuffer = CFG_SRC_TYPE_EEPROM; -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to get the config data source type. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_FAILURE -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryEepromType(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ ASSERT(prAdapter); -+ -+ *pu4QueryInfoLen = sizeof(P_ENUM_EEPROM_TYPE_T); -+ -+#if CFG_SUPPORT_NIC_CAPABILITY -+ if (prAdapter->fgIsEepromUsed == TRUE) -+ *(P_ENUM_EEPROM_TYPE_T) pvQueryBuffer = EEPROM_TYPE_PRESENT; -+ else -+ *(P_ENUM_EEPROM_TYPE_T) pvQueryBuffer = EEPROM_TYPE_NO; -+#else -+ *(P_ENUM_EEPROM_TYPE_T) pvQueryBuffer = EEPROM_TYPE_NO; -+#endif -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to get the config data source type. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_FAILURE -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetCountryCode(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ PUINT_8 pucCountry; -+ UINT_16 u2CountryCode; -+ -+ ASSERT(prAdapter); -+ ASSERT(pvSetBuffer); -+ ASSERT(u4SetBufferLen == 2); -+ -+ *pu4SetInfoLen = 2; -+ -+ pucCountry = pvSetBuffer; -+ u2CountryCode = (((UINT_16) pucCountry[0]) << 8) | ((UINT_16) pucCountry[1]); -+ -+ /* previous country code == FF : ignore country code, current country code == FE : resume */ -+ if (prAdapter->rWifiVar.rConnSettings.u2CountryCodeBakup == COUNTRY_CODE_FF) { -+ if (u2CountryCode != COUNTRY_CODE_FE) { -+ DBGLOG(OID, INFO, "Skip country code cmd (0x%04x)\n", u2CountryCode); -+ return WLAN_STATUS_SUCCESS; -+ } -+ DBGLOG(OID, INFO, "Resume handle country code cmd (0x%04x)\n", u2CountryCode); -+ } -+ -+ prAdapter->rWifiVar.rConnSettings.u2CountryCode = u2CountryCode; -+ prAdapter->rWifiVar.rConnSettings.u2CountryCodeBakup = prAdapter->rWifiVar.rConnSettings.u2CountryCode; -+ DBGLOG(OID, LOUD, "u2CountryCodeBakup=0x%04x\n", prAdapter->rWifiVar.rConnSettings.u2CountryCodeBakup); -+ -+ /* Force to re-search country code in country domains */ -+ prAdapter->prDomainInfo = NULL; -+ rlmDomainSendCmd(prAdapter, TRUE); -+ -+ /* Update supported channel list in channel table based on current country domain */ -+ wlanUpdateChannelTable(prAdapter->prGlueInfo); -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+#if 0 -+WLAN_STATUS -+wlanoidSetNoaParam(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ P_PARAM_CUSTOM_NOA_PARAM_STRUCT_T prNoaParam; -+ CMD_CUSTOM_NOA_PARAM_STRUCT_T rCmdNoaParam; -+ -+ DEBUGFUNC("wlanoidSetNoaParam"); -+ DBGLOG(OID, LOUD, "\n"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ *pu4SetInfoLen = sizeof(PARAM_CUSTOM_NOA_PARAM_STRUCT_T); -+ -+ if (u4SetBufferLen < sizeof(PARAM_CUSTOM_NOA_PARAM_STRUCT_T)) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ ASSERT(pvSetBuffer); -+ -+ prNoaParam = (P_PARAM_CUSTOM_NOA_PARAM_STRUCT_T) pvSetBuffer; -+ -+ kalMemZero(&rCmdNoaParam, sizeof(CMD_CUSTOM_NOA_PARAM_STRUCT_T)); -+ rCmdNoaParam.u4NoaDurationMs = prNoaParam->u4NoaDurationMs; -+ rCmdNoaParam.u4NoaIntervalMs = prNoaParam->u4NoaIntervalMs; -+ rCmdNoaParam.u4NoaCount = prNoaParam->u4NoaCount; -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SET_NOA_PARAM, -+ TRUE, -+ FALSE, -+ TRUE, -+ nicCmdEventSetCommon, -+ nicOidCmdTimeoutCommon, -+ sizeof(CMD_CUSTOM_NOA_PARAM_STRUCT_T), -+ (PUINT_8) &rCmdNoaParam, pvSetBuffer, u4SetBufferLen); -+} -+ -+WLAN_STATUS -+wlanoidSetOppPsParam(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ P_PARAM_CUSTOM_OPPPS_PARAM_STRUCT_T prOppPsParam; -+ CMD_CUSTOM_OPPPS_PARAM_STRUCT_T rCmdOppPsParam; -+ -+ DEBUGFUNC("wlanoidSetOppPsParam"); -+ DBGLOG(OID, LOUD, "\n"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ *pu4SetInfoLen = sizeof(PARAM_CUSTOM_OPPPS_PARAM_STRUCT_T); -+ -+ if (u4SetBufferLen < sizeof(PARAM_CUSTOM_OPPPS_PARAM_STRUCT_T)) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ ASSERT(pvSetBuffer); -+ -+ prOppPsParam = (P_PARAM_CUSTOM_OPPPS_PARAM_STRUCT_T) pvSetBuffer; -+ -+ kalMemZero(&rCmdOppPsParam, sizeof(CMD_CUSTOM_OPPPS_PARAM_STRUCT_T)); -+ rCmdOppPsParam.u4CTwindowMs = prOppPsParam->u4CTwindowMs; -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SET_OPPPS_PARAM, -+ TRUE, -+ FALSE, -+ TRUE, -+ nicCmdEventSetCommon, -+ nicOidCmdTimeoutCommon, -+ sizeof(CMD_CUSTOM_OPPPS_PARAM_STRUCT_T), -+ (PUINT_8) &rCmdOppPsParam, pvSetBuffer, u4SetBufferLen); -+} -+ -+WLAN_STATUS -+wlanoidSetUApsdParam(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ P_PARAM_CUSTOM_UAPSD_PARAM_STRUCT_T prUapsdParam; -+ CMD_CUSTOM_UAPSD_PARAM_STRUCT_T rCmdUapsdParam; -+ P_PM_PROFILE_SETUP_INFO_T prPmProfSetupInfo; -+ P_BSS_INFO_T prBssInfo; -+ -+ DEBUGFUNC("wlanoidSetUApsdParam"); -+ DBGLOG(OID, LOUD, "\n"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ *pu4SetInfoLen = sizeof(PARAM_CUSTOM_UAPSD_PARAM_STRUCT_T); -+ -+ if (u4SetBufferLen < sizeof(PARAM_CUSTOM_UAPSD_PARAM_STRUCT_T)) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ ASSERT(pvSetBuffer); -+ -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); -+ prPmProfSetupInfo = &prBssInfo->rPmProfSetupInfo; -+ -+ prUapsdParam = (P_PARAM_CUSTOM_UAPSD_PARAM_STRUCT_T) pvSetBuffer; -+ -+ kalMemZero(&rCmdUapsdParam, sizeof(CMD_CUSTOM_OPPPS_PARAM_STRUCT_T)); -+ rCmdUapsdParam.fgEnAPSD = prUapsdParam->fgEnAPSD; -+ prAdapter->rWifiVar.fgSupportUAPSD = prUapsdParam->fgEnAPSD; -+ -+ rCmdUapsdParam.fgEnAPSD_AcBe = prUapsdParam->fgEnAPSD_AcBe; -+ rCmdUapsdParam.fgEnAPSD_AcBk = prUapsdParam->fgEnAPSD_AcBk; -+ rCmdUapsdParam.fgEnAPSD_AcVo = prUapsdParam->fgEnAPSD_AcVo; -+ rCmdUapsdParam.fgEnAPSD_AcVi = prUapsdParam->fgEnAPSD_AcVi; -+ prPmProfSetupInfo->ucBmpDeliveryAC = -+ ((prUapsdParam->fgEnAPSD_AcBe << 0) | -+ (prUapsdParam->fgEnAPSD_AcBk << 1) | -+ (prUapsdParam->fgEnAPSD_AcVi << 2) | (prUapsdParam->fgEnAPSD_AcVo << 3)); -+ prPmProfSetupInfo->ucBmpTriggerAC = -+ ((prUapsdParam->fgEnAPSD_AcBe << 0) | -+ (prUapsdParam->fgEnAPSD_AcBk << 1) | -+ (prUapsdParam->fgEnAPSD_AcVi << 2) | (prUapsdParam->fgEnAPSD_AcVo << 3)); -+ -+ rCmdUapsdParam.ucMaxSpLen = prUapsdParam->ucMaxSpLen; -+ prPmProfSetupInfo->ucUapsdSp = prUapsdParam->ucMaxSpLen; -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SET_UAPSD_PARAM, -+ TRUE, -+ FALSE, -+ TRUE, -+ nicCmdEventSetCommon, -+ nicOidCmdTimeoutCommon, -+ sizeof(CMD_CUSTOM_OPPPS_PARAM_STRUCT_T), -+ (PUINT_8) &rCmdUapsdParam, pvSetBuffer, u4SetBufferLen); -+} -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to set BT profile or BT information and the -+* driver will set the built-in PTA configuration into chip. -+* -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetBT(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ -+ P_PTA_IPC_T prPtaIpc; -+ -+ DEBUGFUNC("wlanoidSetBT.\n"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ *pu4SetInfoLen = sizeof(PTA_IPC_T); -+ if (u4SetBufferLen != sizeof(PTA_IPC_T)) { -+ WARNLOG(("Invalid length %u\n", u4SetBufferLen)); -+ return WLAN_STATUS_INVALID_LENGTH; -+ } -+ -+ if (prAdapter->rAcpiState == ACPI_STATE_D3) { -+ DBGLOG(OID, WARN, "Fail to set BT profile because of ACPI_D3\n"); -+ return WLAN_STATUS_ADAPTER_NOT_READY; -+ } -+ -+ ASSERT(pvSetBuffer); -+ prPtaIpc = (P_PTA_IPC_T) pvSetBuffer; -+ -+#if CFG_SUPPORT_BCM && CFG_SUPPORT_BCM_BWCS && CFG_SUPPORT_BCM_BWCS_DEBUG -+ DBGLOG(OID, INFO, -+ "BCM BWCS CMD: BTPParams[0]=%02x, BTPParams[1]=%02x, BTPParams[2]=%02x, BTPParams[3]=%02x.\n", -+ prPtaIpc->u.aucBTPParams[0], prPtaIpc->u.aucBTPParams[1], prPtaIpc->u.aucBTPParams[2], -+ prPtaIpc->u.aucBTPParams[3]; -+ -+#endif -+ -+ wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SET_BWCS, -+ TRUE, FALSE, FALSE, NULL, NULL, sizeof(PTA_IPC_T), (PUINT_8) prPtaIpc, NULL, 0); -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to query current BT profile and BTCR values -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvQueryBuffer Pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufferLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryBT(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+/* P_PARAM_PTA_IPC_T prPtaIpc; */ -+/* UINT_32 u4QueryBuffLen; */ -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4QueryInfoLen); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ -+ *pu4QueryInfoLen = sizeof(PTA_IPC_T); -+ -+ /* Check for query buffer length */ -+ if (u4QueryBufferLen != sizeof(PTA_IPC_T)) { -+ DBGLOG(OID, WARN, "Invalid length %u\n", u4QueryBufferLen); -+ return WLAN_STATUS_INVALID_LENGTH; -+ } -+ -+ ASSERT(pvQueryBuffer); -+/* prPtaIpc = (P_PTA_IPC_T)pvQueryBuffer; */ -+/* prPtaIpc->ucCmd = BT_CMD_PROFILE; */ -+/* prPtaIpc->ucLen = sizeof(prPtaIpc->u); */ -+/* nicPtaGetProfile(prAdapter, (PUINT_8)&prPtaIpc->u, &u4QueryBuffLen); */ -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+#if 0 -+WLAN_STATUS -+wlanoidQueryBtSingleAntenna(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ P_PTA_INFO_T prPtaInfo; -+ PUINT_32 pu4SingleAntenna; -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4QueryInfoLen); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ -+ *pu4QueryInfoLen = sizeof(UINT_32); -+ -+ /* Check for query buffer length */ -+ if (u4QueryBufferLen != sizeof(UINT_32)) { -+ DBGLOG(OID, WARN, "Invalid length %u\n", u4QueryBufferLen); -+ return WLAN_STATUS_INVALID_LENGTH; -+ } -+ -+ ASSERT(pvQueryBuffer); -+ -+ prPtaInfo = &prAdapter->rPtaInfo; -+ pu4SingleAntenna = (PUINT_32) pvQueryBuffer; -+ -+ if (prPtaInfo->fgSingleAntenna) { -+ /* DBGLOG(OID, INFO, (KERN_WARNING DRV_NAME"Q Single Ant = 1\r\n")); */ -+ *pu4SingleAntenna = 1; -+ } else { -+ /* DBGLOG(OID, INFO, (KERN_WARNING DRV_NAME"Q Single Ant = 0\r\n")); */ -+ *pu4SingleAntenna = 0; -+ } -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+WLAN_STATUS -+wlanoidSetBtSingleAntenna(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ -+ PUINT_32 pu4SingleAntenna; -+ UINT_32 u4SingleAntenna; -+ P_PTA_INFO_T prPtaInfo; -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ prPtaInfo = &prAdapter->rPtaInfo; -+ -+ *pu4SetInfoLen = sizeof(UINT_32); -+ if (u4SetBufferLen != sizeof(UINT_32)) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ if (IS_ARB_IN_RFTEST_STATE(prAdapter)) -+ return WLAN_STATUS_SUCCESS; -+ -+ if (prAdapter->rAcpiState == ACPI_STATE_D3) { -+ DBGLOG(OID, WARN, "Fail to set antenna because of ACPI_D3\n"); -+ return WLAN_STATUS_ADAPTER_NOT_READY; -+ } -+ -+ ASSERT(pvSetBuffer); -+ pu4SingleAntenna = (PUINT_32) pvSetBuffer; -+ u4SingleAntenna = *pu4SingleAntenna; -+ -+ if (u4SingleAntenna == 0) { -+ /* DBGLOG(OID, INFO, (KERN_WARNING DRV_NAME"Set Single Ant = 0\r\n")); */ -+ prPtaInfo->fgSingleAntenna = FALSE; -+ } else { -+ /* DBGLOG(OID, INFO, (KERN_WARNING DRV_NAME"Set Single Ant = 1\r\n")); */ -+ prPtaInfo->fgSingleAntenna = TRUE; -+ } -+ ptaFsmRunEventSetConfig(prAdapter, &prPtaInfo->rPtaParam); -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+#if CFG_SUPPORT_BCM && CFG_SUPPORT_BCM_BWCS -+WLAN_STATUS -+wlanoidQueryPta(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ P_PTA_INFO_T prPtaInfo; -+ PUINT_32 pu4Pta; -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4QueryInfoLen); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ -+ *pu4QueryInfoLen = sizeof(UINT_32); -+ -+ /* Check for query buffer length */ -+ if (u4QueryBufferLen != sizeof(UINT_32)) { -+ DBGLOG(OID, WARN, "Invalid length %u\n", u4QueryBufferLen); -+ return WLAN_STATUS_INVALID_LENGTH; -+ } -+ -+ ASSERT(pvQueryBuffer); -+ -+ prPtaInfo = &prAdapter->rPtaInfo; -+ pu4Pta = (PUINT_32) pvQueryBuffer; -+ -+ if (prPtaInfo->fgEnabled) { -+ /* DBGLOG(OID, INFO, (KERN_WARNING DRV_NAME"PTA = 1\r\n")); */ -+ *pu4Pta = 1; -+ } else { -+ /* DBGLOG(OID, INFO, (KERN_WARNING DRV_NAME"PTA = 0\r\n")); */ -+ *pu4Pta = 0; -+ } -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+WLAN_STATUS -+wlanoidSetPta(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ PUINT_32 pu4PtaCtrl; -+ UINT_32 u4PtaCtrl; -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ *pu4SetInfoLen = sizeof(UINT_32); -+ if (u4SetBufferLen != sizeof(UINT_32)) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ if (IS_ARB_IN_RFTEST_STATE(prAdapter)) -+ return WLAN_STATUS_SUCCESS; -+ -+ if (prAdapter->rAcpiState == ACPI_STATE_D3) { -+ DBGLOG(OID, WARN, "Fail to set BT setting because of ACPI_D3\n"); -+ return WLAN_STATUS_ADAPTER_NOT_READY; -+ } -+ -+ ASSERT(pvSetBuffer); -+ pu4PtaCtrl = (PUINT_32) pvSetBuffer; -+ u4PtaCtrl = *pu4PtaCtrl; -+ -+ if (u4PtaCtrl == 0) { -+ /* DBGLOG(OID, INFO, (KERN_WARNING DRV_NAME"Set Pta= 0\r\n")); */ -+ nicPtaSetFunc(prAdapter, FALSE); -+ } else { -+ /* DBGLOG(OID, INFO, (KERN_WARNING DRV_NAME"Set Pta= 1\r\n")); */ -+ nicPtaSetFunc(prAdapter, TRUE); -+ } -+ -+ return WLAN_STATUS_SUCCESS; -+} -+#endif -+ -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to set Tx power profile. -+* -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetTxPower(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ /* P_SET_TXPWR_CTRL_T pTxPwr = (P_SET_TXPWR_CTRL_T)pvSetBuffer; */ -+ /* UINT_32 i; */ -+ WLAN_STATUS rStatus; -+ -+ DEBUGFUNC("wlanoidSetTxPower"); -+ DBGLOG(OID, LOUD, "\r\n"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pvSetBuffer); -+ -+#if 0 -+ DBGLOG(OID, INFO, "c2GLegacyStaPwrOffset=%d\n", pTxPwr->c2GLegacyStaPwrOffset); -+ DBGLOG(OID, INFO, "c2GHotspotPwrOffset=%d\n", pTxPwr->c2GHotspotPwrOffset); -+ DBGLOG(OID, INFO, "c2GP2pPwrOffset=%d\n", pTxPwr->c2GP2pPwrOffset); -+ DBGLOG(OID, INFO, "c2GBowPwrOffset=%d\n", pTxPwr->c2GBowPwrOffset); -+ DBGLOG(OID, INFO, "c5GLegacyStaPwrOffset=%d\n", pTxPwr->c5GLegacyStaPwrOffset); -+ DBGLOG(OID, INFO, "c5GHotspotPwrOffset=%d\n", pTxPwr->c5GHotspotPwrOffset); -+ DBGLOG(OID, INFO, "c5GP2pPwrOffset=%d\n", pTxPwr->c5GP2pPwrOffset); -+ DBGLOG(OID, INFO, "c5GBowPwrOffset=%d\n", pTxPwr->c5GBowPwrOffset); -+ DBGLOG(OID, INFO, "ucConcurrencePolicy=%d\n", pTxPwr->ucConcurrencePolicy); -+ -+ for (i = 0; i < 14; i++) -+ DBGLOG(OID, INFO, "acTxPwrLimit2G[%d]=%d\n", i, pTxPwr->acTxPwrLimit2G[i]); -+ -+ for (i = 0; i < 4; i++) -+ DBGLOG(OID, INFO, "acTxPwrLimit5G[%d]=%d\n", i, pTxPwr->acTxPwrLimit5G[i]); -+#endif -+ -+ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ -+ CMD_ID_SET_TXPWR_CTRL, /* ucCID */ -+ TRUE, /* fgSetQuery */ -+ FALSE, /* fgNeedResp */ -+ TRUE, /* fgIsOid */ -+ NULL, /* pfCmdDoneHandler */ -+ NULL, /* pfCmdTimeoutHandler */ -+ u4SetBufferLen, /* u4SetQueryInfoLen */ -+ (PUINT_8) pvSetBuffer, /* pucInfoBuffer */ -+ NULL, /* pvSetQueryBuffer */ -+ 0 /* u4SetQueryBufferLen */ -+ ); -+ -+ ASSERT(rStatus == WLAN_STATUS_PENDING); -+ -+ return rStatus; -+ -+} -+ -+WLAN_STATUS wlanSendMemDumpCmd(IN P_ADAPTER_T prAdapter, IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen) -+{ -+ P_PARAM_CUSTOM_MEM_DUMP_STRUCT_T prMemDumpInfo; -+ P_CMD_DUMP_MEM prCmdDumpMem; -+ CMD_DUMP_MEM rCmdDumpMem; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ UINT_32 u4MemSize = PARAM_MEM_DUMP_MAX_SIZE; -+ -+ UINT_32 u4RemainLeng = 0; -+ UINT_32 u4CurAddr = 0; -+ UINT_8 ucFragNum = 0; -+ -+ prCmdDumpMem = &rCmdDumpMem; -+ prMemDumpInfo = (P_PARAM_CUSTOM_MEM_DUMP_STRUCT_T) pvQueryBuffer; -+ -+ u4RemainLeng = prMemDumpInfo->u4RemainLength; -+ u4CurAddr = prMemDumpInfo->u4Address + prMemDumpInfo->u4Length; -+ ucFragNum = prMemDumpInfo->ucFragNum + 1; -+ -+ /* Query. If request length is larger than max length, do it as ping pong. -+ * Send a command and wait for a event. Send next command while the event is received. -+ * -+ */ -+ do { -+ UINT_32 u4CurLeng = 0; -+ -+ if (u4RemainLeng > u4MemSize) { -+ u4CurLeng = u4MemSize; -+ u4RemainLeng -= u4MemSize; -+ } else { -+ u4CurLeng = u4RemainLeng; -+ u4RemainLeng = 0; -+ } -+ -+ prCmdDumpMem->u4Address = u4CurAddr; -+ prCmdDumpMem->u4Length = u4CurLeng; -+ prCmdDumpMem->u4RemainLength = u4RemainLeng; -+ prCmdDumpMem->ucFragNum = ucFragNum; -+ -+ DBGLOG(OID, TRACE, "[%d] 0x%X, len %u, remain len %u\n", -+ ucFragNum, -+ prCmdDumpMem->u4Address, prCmdDumpMem->u4Length, prCmdDumpMem->u4RemainLength); -+ -+ rStatus = wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_DUMP_MEM, -+ FALSE, -+ TRUE, -+ TRUE, -+ nicCmdEventQueryMemDump, -+ nicOidCmdTimeoutCommon, -+ sizeof(CMD_DUMP_MEM), -+ (PUINT_8) prCmdDumpMem, pvQueryBuffer, u4QueryBufferLen); -+ -+ } while (FALSE); -+ -+ return rStatus; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to dump memory. -+* -+* \param[in] pvAdapter Pointer to the Adapter structure. -+* \param[out] pvQueryBuf A pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryMemDump(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ P_PARAM_CUSTOM_MEM_DUMP_STRUCT_T prMemDumpInfo; -+ -+ DEBUGFUNC("wlanoidQueryMemDump"); -+ DBGLOG(OID, LOUD, "\n"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4QueryInfoLen); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ -+ *pu4QueryInfoLen = sizeof(UINT_32); -+ -+ prMemDumpInfo = (P_PARAM_CUSTOM_MEM_DUMP_STRUCT_T) pvQueryBuffer; -+ DBGLOG(OID, TRACE, "Dump 0x%X, len %u\n", prMemDumpInfo->u4Address, prMemDumpInfo->u4Length); -+ -+ prMemDumpInfo->u4RemainLength = prMemDumpInfo->u4Length; -+ prMemDumpInfo->u4Length = 0; -+ prMemDumpInfo->ucFragNum = 0; -+ -+ return wlanSendMemDumpCmd(prAdapter, pvQueryBuffer, u4QueryBufferLen); -+ -+} /* end of wlanoidQueryMcrRead() */ -+ -+#if CFG_ENABLE_WIFI_DIRECT -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is used to set the p2p mode. -+* -+* \param[in] pvAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetP2pMode(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ WLAN_STATUS status = WLAN_STATUS_SUCCESS; -+ P_PARAM_CUSTOM_P2P_SET_STRUCT_T prSetP2P = (P_PARAM_CUSTOM_P2P_SET_STRUCT_T) NULL; -+ /* P_MSG_P2P_NETDEV_REGISTER_T prP2pNetdevRegMsg = (P_MSG_P2P_NETDEV_REGISTER_T)NULL; */ -+ DEBUGFUNC("wlanoidSetP2pMode"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ *pu4SetInfoLen = sizeof(PARAM_CUSTOM_P2P_SET_STRUCT_T); -+ if (u4SetBufferLen < sizeof(PARAM_CUSTOM_P2P_SET_STRUCT_T)) { -+ DBGLOG(OID, WARN, "Invalid length %u\n", u4SetBufferLen); -+ return WLAN_STATUS_INVALID_LENGTH; -+ } -+ -+ prSetP2P = (P_PARAM_CUSTOM_P2P_SET_STRUCT_T) pvSetBuffer; -+ -+ DBGLOG(P2P, INFO, "Set P2P enable %p [%u] mode[%u]\n", prSetP2P, prSetP2P->u4Enable, prSetP2P->u4Mode); -+ -+ /* -+ * enable = 1, mode = 0 => init P2P network -+ * enable = 1, mode = 1 => init Soft AP network -+ * enable = 0 => uninit P2P/AP network -+ */ -+ -+ if (prSetP2P->u4Enable) { -+ p2pSetMode((prSetP2P->u4Mode == 1) ? TRUE : FALSE); -+ -+ if (p2pLaunch(prAdapter->prGlueInfo)) -+ ASSERT(prAdapter->fgIsP2PRegistered); -+ -+ } else { -+ DBGLOG(P2P, TRACE, "prAdapter->fgIsP2PRegistered = %d\n", prAdapter->fgIsP2PRegistered); -+ -+ if (prAdapter->fgIsP2PRegistered) { -+ DBGLOG(P2P, INFO, "p2pRemove\n"); -+ p2pRemove(prAdapter->prGlueInfo); -+ } -+ -+ } -+ -+#if 0 -+ prP2pNetdevRegMsg = (P_MSG_P2P_NETDEV_REGISTER_T) cnmMemAlloc(prAdapter, -+ RAM_TYPE_MSG, -+ (sizeof(MSG_P2P_NETDEV_REGISTER_T))); -+ -+ if (prP2pNetdevRegMsg == NULL) { -+ ASSERT(FALSE); -+ status = WLAN_STATUS_RESOURCES; -+ return status; -+ } -+ -+ prP2pNetdevRegMsg->rMsgHdr.eMsgId = MID_MNY_P2P_NET_DEV_REGISTER; -+ prP2pNetdevRegMsg->fgIsEnable = (prSetP2P->u4Enable == 1) ? TRUE : FALSE; -+ prP2pNetdevRegMsg->ucMode = (UINT_8) prSetP2P->u4Mode; -+ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prP2pNetdevRegMsg, MSG_SEND_METHOD_BUF); -+#endif -+ -+ return status; -+} -+#endif -+ -+#if CFG_SUPPORT_BUILD_DATE_CODE -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is used to query build date code information from firmware -+* -+* \param[in] pvAdapter Pointer to the Adapter structure. -+* \param[out] pvQueryBuffer A pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufferLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryBuildDateCode(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ CMD_GET_BUILD_DATE_CODE rCmdGetBuildDateCode; -+ -+ DEBUGFUNC("wlanoidQueryBuildDateCode"); -+ DBGLOG(OID, LOUD, "\n"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4QueryInfoLen); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ -+ *pu4QueryInfoLen = sizeof(UINT_8) * 16; -+ -+ if (u4QueryBufferLen < sizeof(UINT_8) * 16) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_GET_BUILD_DATE_CODE, -+ FALSE, -+ TRUE, -+ TRUE, -+ nicCmdEventBuildDateCode, -+ nicOidCmdTimeoutCommon, -+ sizeof(CMD_GET_BUILD_DATE_CODE), -+ (PUINT_8) &rCmdGetBuildDateCode, pvQueryBuffer, u4QueryBufferLen); -+ -+} /* end of wlanoidQueryBuildDateCode() */ -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is used to query BSS info from firmware -+* -+* \param[in] pvAdapter Pointer to the Adapter structure. -+* \param[out] pvQueryBuffer A pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufferLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryBSSInfo(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ EVENT_AIS_BSS_INFO_T rCmdBSSInfo; -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4QueryInfoLen); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ -+ *pu4QueryInfoLen = sizeof(EVENT_AIS_BSS_INFO_T); -+ -+ if (u4QueryBufferLen < sizeof(EVENT_AIS_BSS_INFO_T)) -+ return WLAN_STATUS_INVALID_LENGTH; -+ kalMemZero(&rCmdBSSInfo, sizeof(EVENT_AIS_BSS_INFO_T)); -+ /* -+ rStatus = wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_GET_BSS_INFO, -+ FALSE, -+ TRUE, -+ TRUE, -+ nicCmdEventGetBSSInfo, -+ nicOidCmdTimeoutCommon, -+ sizeof(P_EVENT_AIS_BSS_INFO_T), -+ (PUINT_8) &rCmdBSSInfo, pvQueryBuffer, u4QueryBufferLen); -+ */ -+ rStatus = wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_GET_BSS_INFO, -+ FALSE, -+ TRUE, -+ TRUE, -+ nicCmdEventGetBSSInfo, -+ nicOidCmdTimeoutCommon, -+ sizeof(EVENT_AIS_BSS_INFO_T), -+ (PUINT_8) & rCmdBSSInfo, pvQueryBuffer, u4QueryBufferLen); -+ -+ return rStatus; -+} /* wlanoidSetWiFiWmmPsTest */ -+ -+#if CFG_SUPPORT_BATCH_SCAN -+ -+#define CMD_WLS_BATCHING "WLS_BATCHING" -+ -+#define BATCHING_SET "SET" -+#define BATCHING_GET "GET" -+#define BATCHING_STOP "STOP" -+ -+#define PARAM_SCANFREQ "SCANFREQ" -+#define PARAM_MSCAN "MSCAN" -+#define PARAM_BESTN "BESTN" -+#define PARAM_CHANNEL "CHANNEL" -+#define PARAM_RTT "RTT" -+ -+WLAN_STATUS -+batchSetCmd(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4WritenLen) -+{ -+ P_CHANNEL_INFO_T prRfChannelInfo; -+ CMD_BATCH_REQ_T rCmdBatchReq; -+ -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ PCHAR head, p, p2; -+ UINT_32 tokens; -+ INT_32 scanfreq, mscan, bestn, rtt; -+ -+ DBGLOG(SCN, TRACE, "[BATCH] command=%s, len=%u\n", (PCHAR) pvSetBuffer, (UINT_32) u4SetBufferLen); -+ -+ if (!pu4WritenLen) -+ return -EINVAL; -+ *pu4WritenLen = 0; -+ -+ if (u4SetBufferLen < kalStrLen(CMD_WLS_BATCHING)) { -+ DBGLOG(SCN, TRACE, "[BATCH] invalid len %u\n", (UINT_32) u4SetBufferLen); -+ return -EINVAL; -+ } -+ -+ head = pvSetBuffer + kalStrLen(CMD_WLS_BATCHING) + 1; -+ kalMemSet(&rCmdBatchReq, 0, sizeof(CMD_BATCH_REQ_T)); -+ -+ if (!kalStrnCmp(head, BATCHING_SET, kalStrLen(BATCHING_SET))) { -+ -+ DBGLOG(SCN, TRACE, "XXX Start Batch Scan XXX\n"); -+ -+ head += kalStrLen(BATCHING_SET) + 1; -+ -+ /* SCANFREQ, MSCAN, BESTN */ -+ tokens = kalSScanf(head, "SCANFREQ=%d MSCAN=%d BESTN=%d", &scanfreq, &mscan, &bestn); -+ if (tokens != 3) { -+ DBGLOG(SCN, TRACE, "[BATCH] Parse fail: tokens=%u, SCANFREQ=%d MSCAN=%d BESTN=%d\n", -+ (UINT_32) tokens, scanfreq, mscan, bestn); -+ return -EINVAL; -+ } -+ /* RTT */ -+ p = kalStrStr(head, PARAM_RTT); -+ if (!p) { -+ DBGLOG(SCN, TRACE, "[BATCH] Parse RTT fail. head=%s\n", head); -+ return -EINVAL; -+ } -+ tokens = kalSScanf(p, "RTT=%d", &rtt); -+ if (tokens != 1) { -+ DBGLOG(SCN, TRACE, "[BATCH] Parse fail: tokens=%u, rtt=%d\n", (UINT_32) tokens, rtt); -+ return -EINVAL; -+ } -+ /* CHANNEL */ -+ p = kalStrStr(head, PARAM_CHANNEL); -+ if (!p) { -+ DBGLOG(SCN, TRACE, "[BATCH] Parse CHANNEL fail(1)\n"); -+ return -EINVAL; -+ } -+ head = p; -+ p = kalStrChr(head, '>'); -+ if (!p) { -+ DBGLOG(SCN, TRACE, "[BATCH] Parse CHANNEL fail(2)\n"); -+ return -EINVAL; -+ } -+ /* else { -+ *p = '.'; // remove '>' because sscanf can not parse <%s> -+ }*/ -+ /*tokens = kalSScanf(head, "CHANNEL=<%s", c_channel); -+ if (tokens != 1) { -+ DBGLOG(SCN, TRACE, ("[BATCH] Parse fail: tokens=%d, CHANNEL=<%s>\n", -+ tokens, c_channel)); -+ return -EINVAL; -+ } */ -+ rCmdBatchReq.ucChannelType = SCAN_CHANNEL_SPECIFIED; -+ rCmdBatchReq.ucChannelListNum = 0; -+ prRfChannelInfo = &rCmdBatchReq.arChannelList[0]; -+ p = head + kalStrLen(PARAM_CHANNEL) + 2; /* c_channel; */ -+ while ((p2 = kalStrSep((char **)&p, ",")) != NULL) { -+ if (p2 == NULL || *p2 == 0) -+ break; -+ if (*p2 == '\0') -+ continue; -+ if (*p2 == 'A') { -+ rCmdBatchReq.ucChannelType = -+ rCmdBatchReq.ucChannelType == -+ SCAN_CHANNEL_2G4 ? SCAN_CHANNEL_FULL : SCAN_CHANNEL_5G; -+ } else if (*p2 == 'B') { -+ rCmdBatchReq.ucChannelType = -+ rCmdBatchReq.ucChannelType == -+ SCAN_CHANNEL_5G ? SCAN_CHANNEL_FULL : SCAN_CHANNEL_2G4; -+ } else { -+ -+ /* Translate Freq from MHz to channel number. */ -+ prRfChannelInfo->ucChannelNum = kalStrtol(p2, NULL, 0); -+ DBGLOG(SCN, TRACE, "Scanning Channel:%u, freq: %d\n", -+ (UINT_32) prRfChannelInfo->ucChannelNum, -+ (UINT_32) nicChannelNum2Freq(prRfChannelInfo->ucChannelNum)); -+ prRfChannelInfo->ucBand = prRfChannelInfo->ucChannelNum < 15 ? BAND_2G4 : BAND_5G; -+ -+ rCmdBatchReq.ucChannelListNum++; -+ if (rCmdBatchReq.ucChannelListNum >= 32) -+ break; -+ prRfChannelInfo++; -+ } -+ } -+ -+ /* set channel for test */ -+#if 0 -+ rCmdBatchReq.ucChannelType = 4; /* SCAN_CHANNEL_SPECIFIED; */ -+ rCmdBatchReq.ucChannelListNum = 0; -+ prRfChannelInfo = &rCmdBatchReq.arChannelList[0]; -+ for (i = 1; i <= 14; i++) { -+ -+ /* filter out some */ -+ if (i == 1 || i == 5 || i == 11) -+ continue; -+ -+ /* Translate Freq from MHz to channel number. */ -+ prRfChannelInfo->ucChannelNum = i; -+ DBGLOG(SCN, TRACE, "Scanning Channel:%d, freq: %d\n", -+ prRfChannelInfo->ucChannelNum, -+ nicChannelNum2Freq(prRfChannelInfo->ucChannelNum)); -+ prRfChannelInfo->ucBand = BAND_2G4; -+ -+ rCmdBatchReq.ucChannelListNum++; -+ prRfChannelInfo++; -+ } -+#endif -+#if 0 -+ rCmdBatchReq.ucChannelType = 0; /* SCAN_CHANNEL_FULL; */ -+#endif -+ -+ rCmdBatchReq.u4Scanfreq = scanfreq; -+ rCmdBatchReq.ucMScan = mscan > CFG_BATCH_MAX_MSCAN ? CFG_BATCH_MAX_MSCAN : mscan; -+ rCmdBatchReq.ucBestn = bestn; -+ rCmdBatchReq.ucRtt = rtt; -+ DBGLOG(SCN, TRACE, "[BATCH] SCANFREQ=%u MSCAN=%u BESTN=%u RTT=%u\n", -+ (UINT_32) rCmdBatchReq.u4Scanfreq, -+ (UINT_32) rCmdBatchReq.ucMScan, -+ (UINT_32) rCmdBatchReq.ucBestn, (UINT_32) rCmdBatchReq.ucRtt; -+ -+ if (rCmdBatchReq.ucChannelType != SCAN_CHANNEL_SPECIFIED) { -+ DBGLOG(SCN, TRACE, "[BATCH] CHANNELS = %s\n", -+ rCmdBatchReq.ucChannelType == SCAN_CHANNEL_FULL ? "FULL" : -+ rCmdBatchReq.ucChannelType == SCAN_CHANNEL_2G4 ? "2.4G all" : "5G all"); -+ } else { -+ DBGLOG(SCN, TRACE, "[BATCH] CHANNEL list\n"); -+ prRfChannelInfo = &rCmdBatchReq.arChannelList[0]; -+ for (tokens = 0; tokens < rCmdBatchReq.ucChannelListNum; tokens++) { -+ DBGLOG(SCN, TRACE, "[BATCH] %s, %d\n", -+ prRfChannelInfo->ucBand == BAND_2G4 ? "2.4G" : "5G", -+ prRfChannelInfo->ucChannelNum); -+ prRfChannelInfo++; -+ } -+ } -+ -+ rCmdBatchReq.ucSeqNum = 1; -+ rCmdBatchReq.ucNetTypeIndex = NETWORK_TYPE_AIS_INDEX; -+ rCmdBatchReq.ucCmd = SCAN_BATCH_REQ_START; -+ -+ *pu4WritenLen = kalSnprintf(pvSetBuffer, 3, "%d", rCmdBatchReq.ucMScan); -+ -+ } else if (!kalStrnCmp(head, BATCHING_STOP, kalStrLen(BATCHING_STOP))) { -+ -+ DBGLOG(SCN, TRACE, "XXX Stop Batch Scan XXX\n"); -+ -+ rCmdBatchReq.ucSeqNum = 1; -+ rCmdBatchReq.ucNetTypeIndex = NETWORK_TYPE_AIS_INDEX; -+ rCmdBatchReq.ucCmd = SCAN_BATCH_REQ_STOP; -+ } else { -+ return -EINVAL; -+ } -+ -+ wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SET_BATCH_REQ, -+ TRUE, FALSE, TRUE, NULL, NULL, sizeof(CMD_BATCH_REQ_T), (PUINT_8) &rCmdBatchReq, NULL, 0); -+ -+ /* kalMemSet(pvSetBuffer, 0, u4SetBufferLen); */ -+ /* rStatus = kalSnprintf(pvSetBuffer, 2, "%s", "OK"); */ -+ -+ return rStatus; -+} -+ -+WLAN_STATUS -+batchGetCmd(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ CMD_BATCH_REQ_T rCmdBatchReq; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ P_EVENT_BATCH_RESULT_T prEventBatchResult; -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4QueryInfoLen); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ prEventBatchResult = (P_EVENT_BATCH_RESULT_T) pvQueryBuffer; -+ -+ DBGLOG(SCN, TRACE, "XXX Get Batch Scan Result (%u) XXX\n", (UINT_32) prEventBatchResult->ucScanCount); -+ -+ *pu4QueryInfoLen = sizeof(EVENT_BATCH_RESULT_T); -+ -+ rCmdBatchReq.ucSeqNum = 2; -+ rCmdBatchReq.ucCmd = SCAN_BATCH_REQ_RESULT; -+ rCmdBatchReq.ucMScan = prEventBatchResult->ucScanCount; /* Get which round result */ -+ -+ rStatus = wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SET_BATCH_REQ, -+ FALSE, -+ TRUE, -+ TRUE, -+ nicCmdEventBatchScanResult, -+ nicOidCmdTimeoutCommon, -+ sizeof(CMD_BATCH_REQ_T), -+ (PUINT_8) &rCmdBatchReq, (PVOID) pvQueryBuffer, u4QueryBufferLen); -+ -+ return rStatus; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set -+* \param[in] u4SetBufferLen The length of the set buffer -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed due to invalid length of -+* the set buffer, returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_DATA If new setting value is wrong. -+* \retval WLAN_STATUS_INVALID_LENGTH -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetBatchScanReq(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ return batchSetCmd(prAdapter, pvSetBuffer, u4SetBufferLen, pu4SetInfoLen); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] pvAdapter Pointer to the Adapter structure. -+* \param[out] pvQueryBuffer A pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufferLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryBatchScanResult(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ return batchGetCmd(prAdapter, pvQueryBuffer, u4QueryBufferLen, pu4QueryInfoLen); -+ -+} /* end of wlanoidQueryBatchScanResult() */ -+ -+#endif /* CFG_SUPPORT_BATCH_SCAN */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to request starting of schedule scan -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_ADAPTER_NOT_READY -+* \retval WLAN_STATUS_INVALID_LENGTH -+* \retval WLAN_STATUS_INVALID_DATA -+* -+* \note The setting buffer PARAM_SCHED_SCAN_REQUEST_EXT_T -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetStartSchedScan(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ P_PARAM_SCHED_SCAN_REQUEST prSchedScanRequest; -+ -+ DEBUGFUNC("wlanoidSetStartSchedScan()"); -+ -+ if (prAdapter->rAcpiState == ACPI_STATE_D3) { -+ DBGLOG(SCN, WARN, "Fail in set scheduled scan! (Adapter not ready). ACPI=D%d, Radio=%d\n", -+ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); -+ return WLAN_STATUS_ADAPTER_NOT_READY; -+ } -+ -+ ASSERT(pu4SetInfoLen); -+ *pu4SetInfoLen = 0; -+ -+ if (u4SetBufferLen != sizeof(PARAM_SCHED_SCAN_REQUEST)) { -+ return WLAN_STATUS_INVALID_LENGTH; -+ } else if (pvSetBuffer == NULL) { -+ return WLAN_STATUS_INVALID_DATA; -+ } else if (kalGetMediaStateIndicated(prAdapter->prGlueInfo) == PARAM_MEDIA_STATE_CONNECTED && -+ prAdapter->fgEnOnlineScan == FALSE) { -+ return WLAN_STATUS_FAILURE; -+ } -+ -+ if (prAdapter->fgIsRadioOff) { -+ DBGLOG(SCN, WARN, "Return from BSSID list scan! (radio off). ACPI=D%d, Radio=%d\n", -+ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); -+ return WLAN_STATUS_SUCCESS; -+ } -+ -+ prSchedScanRequest = (P_PARAM_SCHED_SCAN_REQUEST) pvSetBuffer; -+ -+ if (scnFsmSchedScanRequest(prAdapter, -+ (UINT_8) (prSchedScanRequest->u4SsidNum), -+ prSchedScanRequest->arSsid, -+ prSchedScanRequest->u4IELength, -+ prSchedScanRequest->pucIE, prSchedScanRequest->u2ScanInterval) == TRUE) { -+ return WLAN_STATUS_SUCCESS; -+ } else { -+ return WLAN_STATUS_FAILURE; -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to request termination of schedule scan -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_ADAPTER_NOT_READY -+* \retval WLAN_STATUS_INVALID_LENGTH -+* \retval WLAN_STATUS_INVALID_DATA -+* -+* \note The setting buffer PARAM_SCHED_SCAN_REQUEST_EXT_T -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetStopSchedScan(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ ASSERT(prAdapter); -+ -+ /* ask SCN module to stop scan request */ -+ if (scnFsmSchedScanStopRequest(prAdapter) == TRUE) -+ return WLAN_STATUS_SUCCESS; -+ else -+ return WLAN_STATUS_FAILURE; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to set a periodically scan action -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_ADAPTER_NOT_READY -+* \retval WLAN_STATUS_INVALID_LENGTH -+* \retval WLAN_STATUS_INVALID_DATA -+* -+* \note The setting buffer PARAM_SCHED_SCAN_REQUEST_EXT_T -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetGSCNAction(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ P_CMD_SET_PSCAN_ENABLE prCmdPscnAction; -+ P_SCAN_INFO_T prScanInfo; -+ -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ DBGLOG(SCN, TRACE, "wlanoidSetGSCNAction\n"); -+ -+ if (prAdapter->rAcpiState == ACPI_STATE_D3) { -+ DBGLOG(SCN, WARN, "Fail in set Periodically Scan! (Adapter not ready). ACPI=D%d, Radio=%d\n", -+ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); -+ return WLAN_STATUS_ADAPTER_NOT_READY; -+ } -+ -+ if (u4SetBufferLen != sizeof(CMD_SET_PSCAN_ENABLE)) -+ return WLAN_STATUS_INVALID_LENGTH; -+ else if (pvSetBuffer == NULL) -+ return WLAN_STATUS_INVALID_DATA; -+ -+ if (prAdapter->fgIsRadioOff) { -+ DBGLOG(SCN, WARN, "Return from BSSID list scan! (radio off). ACPI=D%d, Radio=%d\n", -+ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); -+ return WLAN_STATUS_SUCCESS; -+ } -+ -+ prCmdPscnAction = (P_CMD_SET_PSCAN_ENABLE) pvSetBuffer; -+ -+ if (prCmdPscnAction->ucPscanAct == ENABLE) { -+#if 0 -+ DBGLOG(OID, INFO, "set PCSN ENABLE\n"); -+ if (scnFsmPSCNAction(prAdapter, (UINT_8) (prCmdPscnAction->ucPscanAct)) == TRUE) { -+ -+ DBGLOG(OID, INFO, "wlanoidSetGSCNAction < ---\n"); -+ return WLAN_STATUS_PENDING; -+ } -+ DBGLOG(OID, INFO, "wlanoidSetGSCNAction < ---\n"); -+ return WLAN_STATUS_FAILURE; -+ -+#endif -+ scnPSCNFsm(prAdapter, PSCN_SCANNING, NULL, NULL, NULL, NULL, FALSE, FALSE, FALSE, TRUE); -+ } else if (prCmdPscnAction->ucPscanAct == DISABLE) { -+#if 0 -+ DBGLOG(OID, INFO, "disable PCSN\n"); -+ scnFsmPSCNAction(prAdapter, (UINT_8) DISABLE); -+ -+ DBGLOG(OID, TRACE, "set new PCSN\n"); -+ scnCombineParamsIntoPSCN(prAdapter, NULL, NULL, NULL, NULL, FALSE, FALSE, TRUE); -+ -+ DBGLOG(OID, INFO, "ENABLE or disable PCSN\n"); -+ if (!prScanInfo->fgPscnOnnning) { -+ DBGLOG(OID, INFO, "ENABLE PCSN\n"); -+ scnFsmPSCNAction(prAdapter, ENABLE); -+ } else { -+ DBGLOG(OID, INFO, "All PCSN is disabled...\n"); -+ } -+#endif -+ scnPSCNFsm(prAdapter, PSCN_RESET, NULL, NULL, NULL, NULL, FALSE, FALSE, TRUE, FALSE); -+ } -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to set a periodically scan action -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_ADAPTER_NOT_READY -+* \retval WLAN_STATUS_INVALID_LENGTH -+* \retval WLAN_STATUS_INVALID_DATA -+* -+* \note The setting buffer PARAM_SCHED_SCAN_REQUEST_EXT_T -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetGSCNAParam(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ P_PARAM_WIFI_GSCAN_CMD_PARAMS prCmdGscnParam; -+ /*UINT_8 i, j = 0;*/ -+ DBGLOG(SCN, INFO, "wlanoidSetGSCNAParam v1\n"); -+ -+ if (prAdapter->rAcpiState == ACPI_STATE_D3) { -+ DBGLOG(SCN, WARN, "Fail in set Periodically Scan! (Adapter not ready). ACPI=D%d, Radio=%d\n", -+ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); -+ return WLAN_STATUS_ADAPTER_NOT_READY; -+ } -+ if (u4SetBufferLen != sizeof(PARAM_WIFI_GSCAN_CMD_PARAMS)) { -+ DBGLOG(SCN, WARN, "(u4SetBufferLen != sizeof(P_PARAM_WIFI_GSCAN_CMD_PARAMS))\n"); -+ return WLAN_STATUS_INVALID_LENGTH; -+ } else if (pvSetBuffer == NULL) { -+ DBGLOG(SCN, WARN, "(pvSetBuffer == NULL)\n"); -+ return WLAN_STATUS_INVALID_DATA; -+ } -+ if (prAdapter->fgIsRadioOff) { -+ DBGLOG(SCN, INFO, "Return from BSSID list scan! (radio off). ACPI=D%d, Radio=%d\n", -+ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); -+ return WLAN_STATUS_SUCCESS; -+ } -+ -+ prCmdGscnParam = (P_PARAM_WIFI_GSCAN_CMD_PARAMS) pvSetBuffer; -+ /* KC-XXX memcpy(prCmdGscnParam, */ -+ /* (P_PARAM_WIFI_GSCAN_CMD_PARAMS)pvSetBuffer, */ -+ /* sizeof(PARAM_WIFI_GSCAN_CMD_PARAMS) ); */ -+ DBGLOG(SCN, INFO, -+ "prCmdGscnParam : base_period[%u], max_ap_per_scan[%u] num_buckets[%u], report_threshold[%u]\n", -+ prCmdGscnParam->base_period, prCmdGscnParam->max_ap_per_scan, prCmdGscnParam->num_buckets, -+ prCmdGscnParam->report_threshold); -+#if 0 -+ for (i = 0; i < prCmdGscnParam->num_buckets; i++) { -+ -+ DBGLOG(OID, INFO, -+ "prCmdGscnParam->buckets : band[%u], bucket[%u] num_buckets[%u], period[%u] report_events[%u]\n", -+ prCmdGscnParam->buckets[i].band, prCmdGscnParam->buckets[i].bucket, -+ prCmdGscnParam->buckets[i].num_channels, prCmdGscnParam->buckets[i].period, -+ prCmdGscnParam->buckets[i].report_events)); -+ DBGLOG(OID, INFO, "prCmdGscnParam->buckets[%d] has channel: ", i); -+ for (j = 0; j < prCmdGscnParam->buckets[i].num_channels; j++) -+ DBGLOG(OID, INFO, " %d, ", prCmdGscnParam->buckets[i].channels[j].channel); -+ DBGLOG(OID, INFO, "\n"); -+ } -+#endif -+ if (scnSetGSCNParam(prAdapter, prCmdGscnParam) == TRUE) { -+ DBGLOG(SCN, INFO, "wlanoidSetGSCNAParam --->scnSetGSCNParam\n"); -+ return WLAN_STATUS_PENDING; -+ } else { -+ return WLAN_STATUS_FAILURE; -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to set configure gscan PARAMs -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_ADAPTER_NOT_READY -+* \retval WLAN_STATUS_INVALID_LENGTH -+* \retval WLAN_STATUS_INVALID_DATA -+* -+* \note The setting buffer PARAM_SCHED_SCAN_REQUEST_EXT_T -+*/ -+/*----------------------------------------------------------------------------*/ -+ -+WLAN_STATUS -+wlanoidSetGSCNAConfig(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ P_PARAM_WIFI_GSCAN_CMD_PARAMS prCmdGscnScnConfigParam; -+ CMD_GSCN_SCN_COFIG_T rCmdGscnScnConfig; -+ -+ DBGLOG(SCN, INFO, "wlanoidSetGSCNAConfig v1\n"); -+ -+ if (prAdapter->rAcpiState == ACPI_STATE_D3) { -+ DBGLOG(SCN, WARN, "Fail in set Periodically Scan! (Adapter not ready). ACPI=D%d, Radio=%d\n", -+ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); -+ return WLAN_STATUS_ADAPTER_NOT_READY; -+ } -+ if (u4SetBufferLen != sizeof(PARAM_WIFI_GSCAN_CMD_PARAMS)) { -+ DBGLOG(SCN, WARN, "(u4SetBufferLen != sizeof(CMD_GSCN_SCN_COFIG_T))\n"); -+ return WLAN_STATUS_INVALID_LENGTH; -+ } else if (pvSetBuffer == NULL) { -+ DBGLOG(SCN, WARN, "(pvSetBuffer == NULL)\n"); -+ return WLAN_STATUS_INVALID_DATA; -+ } -+ if (prAdapter->fgIsRadioOff) { -+ DBGLOG(SCN, INFO, "Return from BSSID list scan! (radio off). ACPI=D%d, Radio=%d\n", -+ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); -+ return WLAN_STATUS_SUCCESS; -+ } -+ -+ DBGLOG(SCN, INFO, "prCmdGscnScnConfigParam = (P_PARAM_WIFI_GSCAN_CMD_PARAMS)pvSetBuffer\n"); -+ prCmdGscnScnConfigParam = (P_PARAM_WIFI_GSCAN_CMD_PARAMS) pvSetBuffer; -+ memcpy(prCmdGscnScnConfigParam, (P_PARAM_WIFI_GSCAN_CMD_PARAMS) pvSetBuffer, -+ sizeof(PARAM_WIFI_GSCAN_CMD_PARAMS)); -+ DBGLOG(SCN, INFO, "prCmdGscnScnConfigParam assign prCmdGscnScnConfig\n"); -+ rCmdGscnScnConfig.u4BufferThreshold = prCmdGscnScnConfigParam->report_threshold; -+ rCmdGscnScnConfig.ucNumApPerScn = prCmdGscnScnConfigParam->max_ap_per_scan; -+ rCmdGscnScnConfig.u4NumScnToCache = prCmdGscnScnConfigParam->num_scans; -+ DBGLOG(SCN, INFO, " report_threshold %d report_threshold %d num_scans %d\n", -+ rCmdGscnScnConfig.u4BufferThreshold, -+ rCmdGscnScnConfig.ucNumApPerScn, rCmdGscnScnConfig.u4NumScnToCache); -+ if (scnFsmSetGSCNConfig(prAdapter, &rCmdGscnScnConfig) == TRUE) { -+ DBGLOG(SCN, INFO, "wlanoidSetGSCNAParam --->scnSetGSCNParam\n"); -+ return WLAN_STATUS_PENDING; -+ } else { -+ return WLAN_STATUS_FAILURE; -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to get a gscan result -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_ADAPTER_NOT_READY -+* \retval WLAN_STATUS_INVALID_LENGTH -+* \retval WLAN_STATUS_INVALID_DATA -+* -+* \note The setting buffer PARAM_SCHED_SCAN_REQUEST_EXT_T -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidGetGSCNResult(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ P_PARAM_WIFI_GSCAN_GET_RESULT_PARAMS prGetGscnScnResultParm; -+ CMD_GET_GSCAN_RESULT_T rGetGscnScnResultCmd; -+ -+ DEBUGFUNC("wlanoidGetGSCNResult()"); -+ DBGLOG(SCN, INFO, "wlanoidGetGSCNResult v1\n"); -+ if (prAdapter->rAcpiState == ACPI_STATE_D3) { -+ DBGLOG(SCN, WARN, "Fail in set Periodically Scan! (Adapter not ready). ACPI=D%d, Radio=%d\n", -+ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); -+ return WLAN_STATUS_ADAPTER_NOT_READY; -+ } -+ -+ if (u4SetBufferLen != sizeof(PARAM_WIFI_GSCAN_GET_RESULT_PARAMS)) { -+ DBGLOG(SCN, WARN, "(u4SetBufferLen != sizeof(CMD_GSCN_SCN_COFIG_T))\n"); -+ return WLAN_STATUS_INVALID_LENGTH; -+ } else if (pvSetBuffer == NULL) { -+ DBGLOG(SCN, WARN, "(pvSetBuffer == NULL)\n"); -+ return WLAN_STATUS_INVALID_DATA; -+ } -+ -+ if (prAdapter->fgIsRadioOff) { -+ DBGLOG(SCN, INFO, "Return from BSSID list scan! (radio off). ACPI=D%d, Radio=%d\n", -+ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); -+ return WLAN_STATUS_SUCCESS; -+ } -+ -+ prGetGscnScnResultParm = (P_PARAM_WIFI_GSCAN_GET_RESULT_PARAMS) pvSetBuffer; -+ /* memcpy(&rGetGscnScnResultCmd, prGetGscnScnResultParm, sizeof(PARAM_WIFI_GSCAN_GET_RESULT_PARAMS) ); */ -+ -+ rGetGscnScnResultCmd.u4Num = prGetGscnScnResultParm->get_num; -+ rGetGscnScnResultCmd.ucFlush = prGetGscnScnResultParm->flush; -+ rGetGscnScnResultCmd.ucVersion = PSCAN_VERSION; -+ kalMemZero(rGetGscnScnResultCmd.aucReserved, sizeof(rGetGscnScnResultCmd.aucReserved)); -+ -+ if (scnFsmGetGSCNResult(prAdapter, &rGetGscnScnResultCmd) == TRUE) { -+ DBGLOG(SCN, INFO, "wlanoidGetGSCNResult --->scnFsmGetGSCNResult\n"); -+ return WLAN_STATUS_PENDING; -+ } else { -+ return WLAN_STATUS_FAILURE; -+ } -+ -+} -+ -+#if CFG_SUPPORT_HOTSPOT_2_0 -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called by HS2.0 to set the assoc info, which is needed to add to -+* Association request frame while join HS2.0 AP. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set -+* \param[in] u4SetBufferLen The length of the set buffer -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed due to invalid length of -+* the set buffer, returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_DATA If new setting value is wrong. -+* \retval WLAN_STATUS_INVALID_LENGTH -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetHS20Info(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ P_IE_HS20_INDICATION_T prHS20IndicationIe; -+ -+ ASSERT(prAdapter); -+ ASSERT(pvSetBuffer); -+ ASSERT(pu4SetInfoLen); -+ -+ DEBUGFUNC("wlanoidSetHS20AssocInfo"); -+ DBGLOG(OID, LOUD, "\r\n"); -+ -+ if (u4SetBufferLen == 0) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ *pu4SetInfoLen = u4SetBufferLen; -+ -+ prHS20IndicationIe = (P_IE_HS20_INDICATION_T) pvSetBuffer; -+ -+ prAdapter->prGlueInfo->ucHotspotConfig = prHS20IndicationIe->ucHotspotConfig; -+ prAdapter->prGlueInfo->fgConnectHS20AP = TRUE; -+ -+ DBGLOG(SEC, TRACE, "HS20 IE sz %u\n", u4SetBufferLen); -+ -+ kalMemCopy(prAdapter->prGlueInfo->aucHS20AssocInfoIE, pvSetBuffer, u4SetBufferLen); -+ prAdapter->prGlueInfo->u2HS20AssocInfoIELen = (UINT_16) u4SetBufferLen; -+ DBGLOG(SEC, TRACE, "HS20 Assoc Info IE sz %u\n", u4SetBufferLen); -+ -+ return WLAN_STATUS_SUCCESS; -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called by WSC to set the assoc info, which is needed to add to -+* Association request frame while join WPS AP. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set -+* \param[in] u4SetBufferLen The length of the set buffer -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed due to invalid length of -+* the set buffer, returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_DATA If new setting value is wrong. -+* \retval WLAN_STATUS_INVALID_LENGTH -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetInterworkingInfo(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+#if 0 -+ P_HS20_INFO_T prHS20Info = NULL; -+ P_IE_INTERWORKING_T prInterWorkingIe; -+ -+ ASSERT(prAdapter); -+ ASSERT(pvSetBuffer); -+ ASSERT(pu4SetInfoLen); -+ -+ prHS20Info = &(prAdapter->rWifiVar.rHS20Info); -+ -+ DEBUGFUNC("wlanoidSetInterworkingInfo"); -+ DBGLOG(OID, TRACE, "\r\n"); -+ -+ if (u4SetBufferLen == 0) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ *pu4SetInfoLen = u4SetBufferLen; -+ prInterWorkingIe = (P_IE_INTERWORKING_T) pvSetBuffer; -+ -+ prHS20Info->ucAccessNetworkOptions = prInterWorkingIe->ucAccNetOpt; -+ prHS20Info->ucVenueGroup = prInterWorkingIe->ucVenueGroup; -+ prHS20Info->ucVenueType = prInterWorkingIe->ucVenueType; -+ COPY_MAC_ADDR(prHS20Info->aucHESSID, prInterWorkingIe->aucHESSID); -+ -+ DBGLOG(SEC, TRACE, "IW IE sz %ld\n", u4SetBufferLen); -+#endif -+ return WLAN_STATUS_SUCCESS; -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called by WSC to set the Roaming Consortium IE info, which is needed to -+* add to Association request frame while join WPS AP. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set -+* \param[in] u4SetBufferLen The length of the set buffer -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed due to invalid length of -+* the set buffer, returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_DATA If new setting value is wrong. -+* \retval WLAN_STATUS_INVALID_LENGTH -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetRoamingConsortiumIEInfo(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+#if 0 -+ P_HS20_INFO_T prHS20Info = NULL; -+ P_PARAM_HS20_ROAMING_CONSORTIUM_INFO prRCInfo; -+ -+ ASSERT(prAdapter); -+ ASSERT(pvSetBuffer); -+ ASSERT(pu4SetInfoLen); -+ -+ prHS20Info = &(prAdapter->rWifiVar.rHS20Info); -+ -+ /* DEBUGFUNC("wlanoidSetRoamingConsortiumInfo"); */ -+ /* DBGLOG(HS2, TRACE, ("\r\n")); */ -+ -+ if (u4SetBufferLen == 0) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ *pu4SetInfoLen = u4SetBufferLen; -+ prRCInfo = (P_PARAM_HS20_ROAMING_CONSORTIUM_INFO) pvSetBuffer; -+ -+ kalMemCopy(&(prHS20Info->rRCInfo), prRCInfo, sizeof(PARAM_HS20_ROAMING_CONSORTIUM_INFO)); -+ -+ /* DBGLOG(HS2, TRACE, ("RoamingConsortium IE sz %ld\n", u4SetBufferLen)); */ -+#endif -+ return WLAN_STATUS_SUCCESS; -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to set_bssid_pool -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer Pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+* \retval WLAN_STATUS_ADAPTER_NOT_READY -+* \retval WLAN_STATUS_MULTICAST_FULL -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetHS20BssidPool(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ WLAN_STATUS rWlanStatus = WLAN_STATUS_SUCCESS; -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ if (u4SetBufferLen) -+ ASSERT(pvSetBuffer); -+ -+ if (u4SetBufferLen < sizeof(PARAM_HS20_SET_BSSID_POOL)) { -+ *pu4SetInfoLen = sizeof(PARAM_HS20_SET_BSSID_POOL); -+ return WLAN_STATUS_BUFFER_TOO_SHORT; -+ } -+ -+ rWlanStatus = hs20SetBssidPool(prAdapter, pvSetBuffer, NETWORK_TYPE_AIS_INDEX); -+ -+ return rWlanStatus; -+} /* end of wlanoidSendHS20GASRequest() */ -+ -+#endif -+ -+#if CFG_SUPPORT_ROAMING_ENC -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to query the MAC address the NIC is currently using. -+* -+* \param[in] pvAdapter Pointer to the Adapter structure -+* \param[in] pvQueryBuf A pointer to the buffer that holds the result of the -+* query buffer -+* \param[in] u4QueryBufLen The length of the query buffer -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_BUFFER_TOO_SHORT -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetRoamingInfo(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ CMD_ROAMING_INFO_T *prCmdRoamingInfo; -+ -+ DEBUGFUNC("wlanoidSetRoamingInfo"); -+ DBGLOG(OID, LOUD, "\n"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ *pu4SetInfoLen = sizeof(CMD_ROAMING_INFO_T); -+ -+ if (u4SetBufferLen < sizeof(CMD_ROAMING_INFO_T)) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ ASSERT(pvSetBuffer); -+ prCmdRoamingInfo = (CMD_ROAMING_INFO_T *) pvSetBuffer; -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SET_ROAMING_INFO, -+ TRUE, -+ FALSE, -+ TRUE, -+ nicCmdEventSetCommon, -+ nicOidCmdTimeoutCommon, -+ sizeof(CMD_ROAMING_INFO_T), (PUINT_8) prCmdRoamingInfo, NULL, 0); -+} -+#endif /* CFG_SUPPORT_ROAMING_ENC */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to set chip -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetChipConfig(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ P_PARAM_CUSTOM_CHIP_CONFIG_STRUCT_T prChipConfigInfo; -+ CMD_CHIP_CONFIG_T rCmdChipConfig; -+ WLAN_STATUS rWlanStatus = WLAN_STATUS_SUCCESS; -+ -+ DATA_STRUCT_INSPECTING_ASSERT(sizeof(prChipConfigInfo->aucCmd) == CHIP_CONFIG_RESP_SIZE); -+ DEBUGFUNC("wlanoidSetChipConfig"); -+ DBGLOG(OID, LOUD, "\n"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ *pu4SetInfoLen = sizeof(PARAM_CUSTOM_CHIP_CONFIG_STRUCT_T); -+ -+ if (u4SetBufferLen < sizeof(PARAM_CUSTOM_CHIP_CONFIG_STRUCT_T)) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ ASSERT(pvSetBuffer); -+ -+ prChipConfigInfo = (P_PARAM_CUSTOM_CHIP_CONFIG_STRUCT_T) pvSetBuffer; -+ kalMemZero(&rCmdChipConfig, sizeof(rCmdChipConfig)); -+ -+ rCmdChipConfig.u2Id = prChipConfigInfo->u2Id; -+ rCmdChipConfig.ucType = prChipConfigInfo->ucType; -+ rCmdChipConfig.ucRespType = prChipConfigInfo->ucRespType; -+ rCmdChipConfig.u2MsgSize = prChipConfigInfo->u2MsgSize; -+ if (rCmdChipConfig.u2MsgSize > CHIP_CONFIG_RESP_SIZE) { -+ DBGLOG(OID, INFO, "Chip config Msg Size %u is not valid (set)\n", rCmdChipConfig.u2MsgSize); -+ rCmdChipConfig.u2MsgSize = CHIP_CONFIG_RESP_SIZE; -+ } -+ kalMemCopy(rCmdChipConfig.aucCmd, prChipConfigInfo->aucCmd, rCmdChipConfig.u2MsgSize); -+ -+ DBGLOG(OID, TRACE, "rCmdChipConfig.aucCmd=%s\n", rCmdChipConfig.aucCmd); -+#if 1 -+ rWlanStatus = wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_CHIP_CONFIG, -+ TRUE, -+ FALSE, -+ TRUE, -+ nicCmdEventSetCommon, -+ nicOidCmdTimeoutCommon, -+ sizeof(CMD_CHIP_CONFIG_T), -+ (PUINT_8) &rCmdChipConfig, pvSetBuffer, u4SetBufferLen); -+#endif -+ return rWlanStatus; -+} /* wlanoidSetChipConfig */ -+ -+WLAN_STATUS -+wlanoidSetWfdDebugMode(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ P_CMD_WFD_DEBUG_MODE_INFO_T prCmdWfdDebugModeInfo; -+ -+ DEBUGFUNC("wlanoidSetWFDDebugMode"); -+ DBGLOG(OID, LOUD, "\n"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ *pu4SetInfoLen = sizeof(CMD_WFD_DEBUG_MODE_INFO_T); -+ -+ if (u4SetBufferLen < sizeof(CMD_WFD_DEBUG_MODE_INFO_T)) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ ASSERT(pvSetBuffer); -+ prCmdWfdDebugModeInfo = (CMD_WFD_DEBUG_MODE_INFO_T *) pvSetBuffer; -+ -+ DBGLOG(OID, INFO, "New WFD Debug: %d mode and period=0x%x\n", prCmdWfdDebugModeInfo->ucDebugMode, -+ prCmdWfdDebugModeInfo->u2PeriodInteval); -+ -+ prAdapter->rWifiVar.prP2pFsmInfo->rWfdDebugSetting.ucWfdDebugMode = (UINT_8) prCmdWfdDebugModeInfo->ucDebugMode; -+ prAdapter->rWifiVar.prP2pFsmInfo->rWfdDebugSetting.u2WfdSNShowPeiroid = -+ (UINT_16) prCmdWfdDebugModeInfo->u2PeriodInteval; -+ -+ return WLAN_STATUS_SUCCESS; -+} /*wlanoidSetWfdDebugMode */ -+ -+ -+#if (CFG_SUPPORT_TXR_ENC == 1) -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to query the MAC address the NIC is currently using. -+* -+* \param[in] pvAdapter Pointer to the Adapter structure -+* \param[in] pvQueryBuf A pointer to the buffer that holds the result of the -+* query buffer -+* \param[in] u4QueryBufLen The length of the query buffer -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_BUFFER_TOO_SHORT -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetTxRateInfo( -+ IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, -+ IN UINT_32 u4SetBufferLen, -+ OUT PUINT_32 pu4SetInfoLen) -+{ -+ CMD_RLM_INFO_T *prCmdTxRInfo; -+ -+ DEBUGFUNC("wlanoidSetTxRateInfo"); -+ DBGLOG(OID, LOUD, "\n"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ *pu4SetInfoLen = sizeof(CMD_RLM_INFO_T); -+ -+ if (u4SetBufferLen < sizeof(CMD_RLM_INFO_T)) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ ASSERT(pvSetBuffer); -+ prCmdTxRInfo = (CMD_RLM_INFO_T *)pvSetBuffer; -+ -+ DBGLOG(OID, INFO, " command = %u %u %u %u %d %u %u\n", -+ prCmdTxRInfo->u4Version, -+ prCmdTxRInfo->fgIsErrRatioEnhanceApplied, -+ prCmdTxRInfo->ucErrRatio2LimitMinRate, -+ prCmdTxRInfo->ucMinLegacyRateIdx, -+ prCmdTxRInfo->cMinRssiThreshold, -+ prCmdTxRInfo->fgIsRtsApplied, -+ prCmdTxRInfo->ucRecoverTime)); -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_TX_AR_ERR_CONFIG, -+ TRUE, -+ FALSE, -+ TRUE, -+ nicCmdEventSetCommon, -+ nicOidCmdTimeoutCommon, -+ sizeof(CMD_RLM_INFO_T), -+ (PUINT_8)prCmdTxRInfo, -+ NULL, -+ 0 -+ ); -+} -+#endif /* CFG_SUPPORT_TXR_ENC */ -+ -+WLAN_STATUS -+wlanoidNotifyFwSuspend(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ WIFI_SYSTEM_SUSPEND_CMD_T rSuspendCmd; -+ -+ if (!prAdapter || !pvSetBuffer) -+ return WLAN_STATUS_INVALID_DATA; -+ -+ rSuspendCmd.fgIsSystemSuspend = *(PBOOLEAN)pvSetBuffer; -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SET_SYSTEM_SUSPEND, -+ TRUE, -+ FALSE, -+ TRUE, -+ nicCmdEventSetCommon, -+ nicOidCmdTimeoutCommon, -+ sizeof(BOOLEAN), -+ (PUINT_8)&rSuspendCmd, -+ NULL, -+ 0); -+} -+ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/common/wlan_p2p.c b/drivers/misc/mediatek/connectivity/wlan/gen2/common/wlan_p2p.c -new file mode 100644 -index 000000000000..7ca7ee48922e ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/common/wlan_p2p.c -@@ -0,0 +1,1654 @@ -+/* -+** Id: //Department/DaVinci/TRUNK/WiFi_P2P_Driver/common/wlan_p2p.c#8 -+*/ -+ -+/*! \file wlan_bow.c -+ \brief This file contains the Wi-Fi Direct commands processing routines for -+ MediaTek Inc. 802.11 Wireless LAN Adapters. -+*/ -+ -+/* -+** Log: wlan_p2p.c -+ * -+ * 07 17 2012 yuche.tsai -+ * NULL -+ * Compile no error before trial run. -+ * -+ * 11 24 2011 yuche.tsai -+ * NULL -+ * Fix P2P IOCTL of multicast address bug, add low power driver stop control. -+ * -+ * 11 22 2011 yuche.tsai -+ * NULL -+ * Update RSSI link quality of P2P Network query method. (Bug fix) -+ * -+ * 11 19 2011 yuche.tsai -+ * NULL -+ * Add RSSI support for P2P network. -+ * -+ * 11 08 2011 yuche.tsai -+ * [WCXRP00001094] [Volunteer Patch][Driver] Driver version & supplicant version query & set support -+ * for service discovery version check. -+ * Add support for driver version query & p2p supplicant verseion set. -+ * For new service discovery mechanism sync. -+ * -+ * 10 18 2011 yuche.tsai -+ * [WCXRP00001045] [WiFi Direct][Driver] Check 2.1 branch. -+ * Support Channel Query. -+ * -+ * 10 18 2011 yuche.tsai -+ * [WCXRP00001045] [WiFi Direct][Driver] Check 2.1 branch. -+ * New 2.1 branch -+ -+ * -+ * 08 23 2011 yuche.tsai -+ * NULL -+ * Fix Multicast Issue of P2P. -+ * -+ * 04 27 2011 george.huang -+ * [WCXRP00000684] [MT6620 Wi-Fi][Driver] Support P2P setting ARP filter -+ * Support P2P ARP filter setting on early suspend/ late resume -+ * -+ * 04 08 2011 george.huang -+ * [WCXRP00000621] [MT6620 Wi-Fi][Driver] Support P2P supplicant to set power mode -+ * separate settings of P2P and AIS -+ * -+ * 03 22 2011 george.huang -+ * [WCXRP00000504] [MT6620 Wi-Fi][FW] Support Sigma CAPI for power saving related command -+ * link with supplicant commands -+ * -+ * 03 17 2011 wh.su -+ * [WCXRP00000571] [MT6620 Wi-Fi] [Driver] Not check the p2p role during set key -+ * Skip the p2p role for adding broadcast key issue. -+ * -+ * 03 16 2011 wh.su -+ * [WCXRP00000530] [MT6620 Wi-Fi] [Driver] skip doing p2pRunEventAAAComplete after send assoc response Tx Done -+ * fixed compiling error while enable dbg. -+ * -+ * 03 08 2011 yuche.tsai -+ * [WCXRP00000480] [Volunteer Patch][MT6620][Driver] WCS IE format -+ * issue[WCXRP00000509] [Volunteer Patch][MT6620][Driver] Kernal panic when remove p2p module. -+ * . -+ * -+ * 03 07 2011 terry.wu -+ * [WCXRP00000521] [MT6620 Wi-Fi][Driver] Remove non-standard debug message -+ * Toggle non-standard debug messages to comments. -+ * -+ * 03 07 2011 wh.su -+ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code -+ * rename the define to anti_pviracy. -+ * -+ * 03 05 2011 wh.su -+ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code -+ * add the code to get the check rsponse and indicate to app. -+ * -+ * 03 02 2011 wh.su -+ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code -+ * Add Security check related code. -+ * -+ * 03 02 2011 yuche.tsai -+ * [WCXRP00000245] 1. Invitation Request/Response. -+2. Provision Discovery Request/Response -+ -+ * Fix SD Request Query Length issue. -+ * -+ * 03 02 2011 yuche.tsai -+ * [WCXRP00000245] 1. Invitation Request/Response. -+2. Provision Discovery Request/Response -+ -+ * Service Discovery Request. -+ * -+ * 03 01 2011 yuche.tsai -+ * [WCXRP00000245] 1. Invitation Request/Response. -+2. Provision Discovery Request/Response -+ -+ * Update Service Discovery Wlan OID related function. -+ * -+ * 03 01 2011 yuche.tsai -+ * [WCXRP00000245] 1. Invitation Request/Response. -+2. Provision Discovery Request/Response -+ -+ * Update Service Discovery Related wlanoid function. -+ * -+ * 02 09 2011 yuche.tsai -+ * [WCXRP00000245] 1. Invitation Request/Response. -+2. Provision Discovery Request/Response -+ -+ * Add Service Discovery Indication Related code. -+ * -+ * 01 26 2011 yuche.tsai -+ * [WCXRP00000245] 1. Invitation Request/Response. -+2. Provision Discovery Request/Response -+ -+ * Add Service Discovery Function. -+ * -+ * 01 05 2011 cp.wu -+ * [WCXRP00000283] [MT6620 Wi-Fi][Driver][Wi-Fi Direct] Implementation of interface -+ * for supporting Wi-Fi Direct Service Discovery ioctl implementations for P2P Service Discovery -+ * -+ * 01 04 2011 cp.wu -+ * [WCXRP00000338] [MT6620 Wi-Fi][Driver] Separate kalMemAlloc into kmalloc and vmalloc implementations to -+ * ease physically continuous memory demands separate kalMemAlloc() into virtually-continuous -+ * and physically-continuous type to ease slab system pressure -+ * -+ * 12 22 2010 cp.wu -+ * [WCXRP00000283] [MT6620 Wi-Fi][Driver][Wi-Fi Direct] Implementation of interface -+ * for supporting Wi-Fi Direct Service Discovery -+ * 1. header file restructure for more clear module isolation -+ * 2. add function interface definition for implementing Service Discovery callbacks -+ * -+ * 10 04 2010 cp.wu -+ * [WCXRP00000077] [MT6620 Wi-Fi][Driver][FW] Eliminate use of ENUM_NETWORK_TYPE_T -+ * and replaced by ENUM_NETWORK_TYPE_INDEX_T only remove ENUM_NETWORK_TYPE_T definitions -+ * -+ * 09 28 2010 wh.su -+ * NULL -+ * [WCXRP00000069][MT6620 Wi-Fi][Driver] Fix some code for phase 1 P2P Demo. -+ * -+ * 09 21 2010 kevin.huang -+ * [WCXRP00000054] [MT6620 Wi-Fi][Driver] Restructure driver for second Interface -+ * Isolate P2P related function for Hardware Software Bundle -+ * -+ * 09 03 2010 kevin.huang -+ * NULL -+ * Refine #include sequence and solve recursive/nested #include issue -+ * -+ * 08 23 2010 cp.wu -+ * NULL -+ * revise constant definitions to be matched with implementation (original cmd-event definition is deprecated) -+ * -+ * 08 16 2010 cp.wu -+ * NULL -+ * add subroutines for P2P to set multicast list. -+ * -+ * 08 16 2010 george.huang -+ * NULL -+ * . -+ * -+ * 08 16 2010 george.huang -+ * NULL -+ * support wlanoidSetP2pPowerSaveProfile() in P2P -+ * -+ * 08 16 2010 george.huang -+ * NULL -+ * Support wlanoidSetNetworkAddress() for P2P -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 25 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add API in que_mgt to retrieve sta-rec index for security frames. -+ * -+ * 06 24 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 802.1x and bluetooth-over-Wi-Fi security frames are now delievered to firmware via command path instead of data path. -+ * -+ * 06 11 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) migrate assoc.c. -+ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness -+ * 3) add configuration options for CNM_MEM and RSN modules -+ * 4) add data path for management frames -+ * 5) eliminate rPacketInfo of MSDU_INFO_T -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 05 17 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * 1) add timeout handler mechanism for pending command packets -+ * 2) add p2p add/removal key -+ * -+** -+*/ -+ -+/****************************************************************************** -+* C O M P I L E R F L A G S -+******************************************************************************* -+*/ -+ -+/****************************************************************************** -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************* -+*/ -+#include "precomp.h" -+#include "gl_p2p_ioctl.h" -+ -+/****************************************************************************** -+* C O N S T A N T S -+******************************************************************************* -+*/ -+ -+/****************************************************************************** -+* D A T A T Y P E S -+******************************************************************************* -+*/ -+ -+/****************************************************************************** -+* P U B L I C D A T A -+******************************************************************************* -+*/ -+ -+/****************************************************************************** -+* P R I V A T E D A T A -+******************************************************************************* -+*/ -+ -+/****************************************************************************** -+* M A C R O S -+******************************************************************************* -+*/ -+ -+/****************************************************************************** -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************* -+*/ -+ -+/****************************************************************************** -+* F U N C T I O N S -+******************************************************************************* -+*/ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief command packet generation utility -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] ucCID Command ID -+* \param[in] fgSetQuery Set or Query -+* \param[in] fgNeedResp Need for response -+* \param[in] pfCmdDoneHandler Function pointer when command is done -+* \param[in] u4SetQueryInfoLen The length of the set/query buffer -+* \param[in] pucInfoBuffer Pointer to set/query buffer -+* -+* -+* \retval WLAN_STATUS_PENDING -+* \retval WLAN_STATUS_FAILURE -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSendSetQueryP2PCmd(IN P_ADAPTER_T prAdapter, -+ UINT_8 ucCID, -+ BOOLEAN fgSetQuery, -+ BOOLEAN fgNeedResp, -+ BOOLEAN fgIsOid, -+ PFN_CMD_DONE_HANDLER pfCmdDoneHandler, -+ PFN_CMD_TIMEOUT_HANDLER pfCmdTimeoutHandler, -+ UINT_32 u4SetQueryInfoLen, -+ PUINT_8 pucInfoBuffer, OUT PVOID pvSetQueryBuffer, IN UINT_32 u4SetQueryBufferLen) -+{ -+ P_GLUE_INFO_T prGlueInfo; -+ P_CMD_INFO_T prCmdInfo; -+ P_WIFI_CMD_T prWifiCmd; -+ UINT_8 ucCmdSeqNum; -+ -+ ASSERT(prAdapter); -+ -+ prGlueInfo = prAdapter->prGlueInfo; -+ ASSERT(prGlueInfo); -+ -+ DEBUGFUNC("wlanoidSendSetQueryP2PCmd"); -+ DBGLOG(REQ, TRACE, "Command ID = 0x%08X\n", ucCID); -+ -+ prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, (CMD_HDR_SIZE + u4SetQueryInfoLen)); -+ -+ if (!prCmdInfo) { -+ DBGLOG(P2P, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); -+ return WLAN_STATUS_FAILURE; -+ } -+ /* increase command sequence number */ -+ ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter); -+ DBGLOG(REQ, TRACE, "ucCmdSeqNum =%d\n", ucCmdSeqNum); -+ -+ /* Setup common CMD Info Packet */ -+ prCmdInfo->eCmdType = COMMAND_TYPE_NETWORK_IOCTL; -+ prCmdInfo->eNetworkType = NETWORK_TYPE_P2P_INDEX; -+ prCmdInfo->u2InfoBufLen = (UINT_16) (CMD_HDR_SIZE + u4SetQueryInfoLen); -+ prCmdInfo->pfCmdDoneHandler = pfCmdDoneHandler; -+ prCmdInfo->pfCmdTimeoutHandler = pfCmdTimeoutHandler; -+ prCmdInfo->fgIsOid = fgIsOid; -+ prCmdInfo->ucCID = ucCID; -+ prCmdInfo->fgSetQuery = fgSetQuery; -+ prCmdInfo->fgNeedResp = fgNeedResp; -+ prCmdInfo->fgDriverDomainMCR = FALSE; -+ prCmdInfo->ucCmdSeqNum = ucCmdSeqNum; -+ prCmdInfo->u4SetInfoLen = u4SetQueryInfoLen; -+ prCmdInfo->pvInformationBuffer = pvSetQueryBuffer; -+ prCmdInfo->u4InformationBufferLength = u4SetQueryBufferLen; -+ -+ /* Setup WIFI_CMD_T (no payload) */ -+ prWifiCmd = (P_WIFI_CMD_T) (prCmdInfo->pucInfoBuffer); -+ prWifiCmd->u2TxByteCount_UserPriority = prCmdInfo->u2InfoBufLen; -+ prWifiCmd->ucCID = prCmdInfo->ucCID; -+ prWifiCmd->ucSetQuery = prCmdInfo->fgSetQuery; -+ prWifiCmd->ucSeqNum = prCmdInfo->ucCmdSeqNum; -+ -+ if (u4SetQueryInfoLen > 0 && pucInfoBuffer != NULL) -+ kalMemCopy(prWifiCmd->aucBuffer, pucInfoBuffer, u4SetQueryInfoLen); -+ /* insert into prCmdQueue */ -+ kalEnqueueCommand(prGlueInfo, (P_QUE_ENTRY_T) prCmdInfo); -+ -+ /* wakeup txServiceThread later */ -+ GLUE_SET_EVENT(prGlueInfo); -+ return WLAN_STATUS_PENDING; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to set a key to Wi-Fi Direct driver -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_ADAPTER_NOT_READY -+* \retval WLAN_STATUS_INVALID_LENGTH -+* \retval WLAN_STATUS_INVALID_DATA -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetAddP2PKey(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ CMD_802_11_KEY rCmdKey; -+ P_PARAM_KEY_T prNewKey; -+ -+ DEBUGFUNC("wlanoidSetAddP2PKey"); -+ DBGLOG(REQ, INFO, "\n"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pvSetBuffer); -+ ASSERT(pu4SetInfoLen); -+ -+ prNewKey = (P_PARAM_KEY_T) pvSetBuffer; -+ -+ /* Verify the key structure length. */ -+ if (prNewKey->u4Length > u4SetBufferLen) { -+ DBGLOG(REQ, WARN, "Invalid key structure length (%d) greater than total buffer length (%d)\n", -+ (UINT_8) prNewKey->u4Length, (UINT_8) u4SetBufferLen); -+ -+ *pu4SetInfoLen = u4SetBufferLen; -+ return WLAN_STATUS_INVALID_LENGTH; -+ } -+ /* Verify the key material length for key material buffer */ -+ else if (prNewKey->u4KeyLength > prNewKey->u4Length - OFFSET_OF(PARAM_KEY_T, aucKeyMaterial)) { -+ DBGLOG(REQ, WARN, "Invalid key material length (%d)\n", (UINT_8) prNewKey->u4KeyLength); -+ *pu4SetInfoLen = u4SetBufferLen; -+ return WLAN_STATUS_INVALID_DATA; -+ } -+ /* Exception check */ -+ else if (prNewKey->u4KeyIndex & 0x0fffff00) -+ return WLAN_STATUS_INVALID_DATA; -+ /* Exception check, pairwise key must with transmit bit enabled */ -+ else if ((prNewKey->u4KeyIndex & BITS(30, 31)) == IS_UNICAST_KEY) { -+ return WLAN_STATUS_INVALID_DATA; -+ } else if (!(prNewKey->u4KeyLength == CCMP_KEY_LEN) && !(prNewKey->u4KeyLength == TKIP_KEY_LEN)) { -+ return WLAN_STATUS_INVALID_DATA; -+ } -+ /* Exception check, pairwise key must with transmit bit enabled */ -+ else if ((prNewKey->u4KeyIndex & BITS(30, 31)) == BITS(30, 31)) { -+ if (((prNewKey->u4KeyIndex & 0xff) != 0) || -+ ((prNewKey->arBSSID[0] == 0xff) && (prNewKey->arBSSID[1] == 0xff) && (prNewKey->arBSSID[2] == 0xff) -+ && (prNewKey->arBSSID[3] == 0xff) && (prNewKey->arBSSID[4] == 0xff) -+ && (prNewKey->arBSSID[5] == 0xff))) { -+ return WLAN_STATUS_INVALID_DATA; -+ } -+ } -+ -+ *pu4SetInfoLen = u4SetBufferLen; -+ -+ /* fill CMD_802_11_KEY */ -+ kalMemZero(&rCmdKey, sizeof(CMD_802_11_KEY)); -+ rCmdKey.ucAddRemove = 1; /* add */ -+ rCmdKey.ucTxKey = ((prNewKey->u4KeyIndex & IS_TRANSMIT_KEY) == IS_TRANSMIT_KEY) ? 1 : 0; -+ rCmdKey.ucKeyType = ((prNewKey->u4KeyIndex & IS_UNICAST_KEY) == IS_UNICAST_KEY) ? 1 : 0; -+ if (kalP2PGetRole(prAdapter->prGlueInfo) == 1) { /* group client */ -+ rCmdKey.ucIsAuthenticator = 0; -+ } else { /* group owner */ -+ rCmdKey.ucIsAuthenticator = 1; -+ } -+ COPY_MAC_ADDR(rCmdKey.aucPeerAddr, prNewKey->arBSSID); -+ rCmdKey.ucNetType = NETWORK_TYPE_P2P_INDEX; -+ if (prNewKey->u4KeyLength == CCMP_KEY_LEN) -+ rCmdKey.ucAlgorithmId = CIPHER_SUITE_CCMP; /* AES */ -+ else if (prNewKey->u4KeyLength == TKIP_KEY_LEN) -+ rCmdKey.ucAlgorithmId = CIPHER_SUITE_TKIP; /* TKIP */ -+ rCmdKey.ucKeyId = (UINT_8) (prNewKey->u4KeyIndex & 0xff); -+ rCmdKey.ucKeyLen = (UINT_8) prNewKey->u4KeyLength; -+ kalMemCopy(rCmdKey.aucKeyMaterial, (PUINT_8) prNewKey->aucKeyMaterial, rCmdKey.ucKeyLen); -+ -+ return wlanoidSendSetQueryP2PCmd(prAdapter, -+ CMD_ID_ADD_REMOVE_KEY, -+ TRUE, -+ FALSE, -+ TRUE, -+ nicCmdEventSetCommon, -+ NULL, -+ sizeof(CMD_802_11_KEY), (PUINT_8) &rCmdKey, pvSetBuffer, u4SetBufferLen); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to request Wi-Fi Direct driver to remove keys -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_DATA -+* \retval WLAN_STATUS_INVALID_LENGTH -+* \retval WLAN_STATUS_INVALID_DATA -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetRemoveP2PKey(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ CMD_802_11_KEY rCmdKey; -+ P_PARAM_REMOVE_KEY_T prRemovedKey; -+ -+ DEBUGFUNC("wlanoidSetRemoveP2PKey"); -+ ASSERT(prAdapter); -+ -+ if (u4SetBufferLen < sizeof(PARAM_REMOVE_KEY_T)) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ ASSERT(pvSetBuffer); -+ prRemovedKey = (P_PARAM_REMOVE_KEY_T) pvSetBuffer; -+ -+ /* Check bit 31: this bit should always 0 */ -+ if (prRemovedKey->u4KeyIndex & IS_TRANSMIT_KEY) { -+ /* Bit 31 should not be set */ -+ DBGLOG(REQ, ERROR, "invalid key index: 0x%08x\n", prRemovedKey->u4KeyIndex); -+ return WLAN_STATUS_INVALID_DATA; -+ } -+ -+ /* Check bits 8 ~ 29 should always be 0 */ -+ if (prRemovedKey->u4KeyIndex & BITS(8, 29)) { -+ /* Bit 31 should not be set */ -+ DBGLOG(REQ, ERROR, "invalid key index: 0x%08x\n", prRemovedKey->u4KeyIndex); -+ return WLAN_STATUS_INVALID_DATA; -+ } -+ -+ /* There should not be any key operation for P2P Device */ -+ if (kalP2PGetRole(prAdapter->prGlueInfo) == 0) -+ ; /* return WLAN_STATUS_NOT_ACCEPTED; */ -+ -+ kalMemZero((PUINT_8) &rCmdKey, sizeof(CMD_802_11_KEY)); -+ -+ rCmdKey.ucAddRemove = 0; /* remove */ -+ if (kalP2PGetRole(prAdapter->prGlueInfo) == 1) { /* group client */ -+ rCmdKey.ucIsAuthenticator = 0; -+ } else { /* group owner */ -+ rCmdKey.ucIsAuthenticator = 1; -+ } -+ kalMemCopy(rCmdKey.aucPeerAddr, (PUINT_8) prRemovedKey->arBSSID, MAC_ADDR_LEN); -+ rCmdKey.ucNetType = NETWORK_TYPE_P2P_INDEX; -+ rCmdKey.ucKeyId = (UINT_8) (prRemovedKey->u4KeyIndex & 0x000000ff); -+ -+ return wlanoidSendSetQueryP2PCmd(prAdapter, -+ CMD_ID_ADD_REMOVE_KEY, -+ TRUE, -+ FALSE, -+ TRUE, -+ nicCmdEventSetCommon, -+ NULL, -+ sizeof(CMD_802_11_KEY), (PUINT_8) &rCmdKey, pvSetBuffer, u4SetBufferLen); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Setting the IP address for pattern search function. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \return WLAN_STATUS_SUCCESS -+* \return WLAN_STATUS_ADAPTER_NOT_READY -+* \return WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetP2pNetworkAddress(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ UINT_32 i, j; -+ P_CMD_SET_NETWORK_ADDRESS_LIST prCmdNetworkAddressList; -+ P_PARAM_NETWORK_ADDRESS_LIST prNetworkAddressList = (P_PARAM_NETWORK_ADDRESS_LIST) pvSetBuffer; -+ P_PARAM_NETWORK_ADDRESS prNetworkAddress; -+ P_PARAM_NETWORK_ADDRESS_IP prNetAddrIp; -+ UINT_32 u4IpAddressCount, u4CmdSize; -+ -+ DEBUGFUNC("wlanoidSetP2pNetworkAddress"); -+ DBGLOG(P2P, TRACE, "\n"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ *pu4SetInfoLen = 4; -+ -+ if (u4SetBufferLen < sizeof(PARAM_NETWORK_ADDRESS_LIST)) -+ return WLAN_STATUS_INVALID_DATA; -+ -+ *pu4SetInfoLen = 0; -+ u4IpAddressCount = 0; -+ -+ prNetworkAddress = prNetworkAddressList->arAddress; -+ for (i = 0; i < prNetworkAddressList->u4AddressCount; i++) { -+ if (prNetworkAddress->u2AddressType == PARAM_PROTOCOL_ID_TCP_IP && -+ prNetworkAddress->u2AddressLength == sizeof(PARAM_NETWORK_ADDRESS_IP)) { -+ u4IpAddressCount++; -+ } -+ -+ prNetworkAddress = (P_PARAM_NETWORK_ADDRESS) ((ULONG) prNetworkAddress + -+ (ULONG) (prNetworkAddress->u2AddressLength + -+ OFFSET_OF(PARAM_NETWORK_ADDRESS, aucAddress))); -+ } -+ -+ /* construct payload of command packet */ -+ u4CmdSize = OFFSET_OF(CMD_SET_NETWORK_ADDRESS_LIST, arNetAddress) + -+ sizeof(IPV4_NETWORK_ADDRESS) * u4IpAddressCount; -+ -+ prCmdNetworkAddressList = (P_CMD_SET_NETWORK_ADDRESS_LIST) kalMemAlloc(u4CmdSize, VIR_MEM_TYPE); -+ -+ if (prCmdNetworkAddressList == NULL) -+ return WLAN_STATUS_FAILURE; -+ -+ /* fill P_CMD_SET_NETWORK_ADDRESS_LIST */ -+ prCmdNetworkAddressList->ucNetTypeIndex = NETWORK_TYPE_P2P_INDEX; -+ prCmdNetworkAddressList->ucAddressCount = (UINT_8) u4IpAddressCount; -+ prNetworkAddress = prNetworkAddressList->arAddress; -+ for (i = 0, j = 0; i < prNetworkAddressList->u4AddressCount; i++) { -+ if (prNetworkAddress->u2AddressType == PARAM_PROTOCOL_ID_TCP_IP && -+ prNetworkAddress->u2AddressLength == sizeof(PARAM_NETWORK_ADDRESS_IP)) { -+ prNetAddrIp = (P_PARAM_NETWORK_ADDRESS_IP) prNetworkAddress->aucAddress; -+ -+ kalMemCopy(prCmdNetworkAddressList->arNetAddress[j].aucIpAddr, -+ &(prNetAddrIp->in_addr), sizeof(UINT_32)); -+ -+ j++; -+ } -+ -+ prNetworkAddress = (P_PARAM_NETWORK_ADDRESS) ((ULONG) prNetworkAddress + -+ (ULONG) (prNetworkAddress->u2AddressLength + -+ OFFSET_OF(PARAM_NETWORK_ADDRESS, aucAddress))); -+ } -+ -+ rStatus = wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SET_IP_ADDRESS, -+ TRUE, -+ FALSE, -+ TRUE, -+ nicCmdEventSetIpAddress, -+ nicOidCmdTimeoutCommon, -+ u4CmdSize, (PUINT_8) prCmdNetworkAddressList, pvSetBuffer, u4SetBufferLen); -+ -+ kalMemFree(prCmdNetworkAddressList, VIR_MEM_TYPE, u4CmdSize); -+ return rStatus; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is used to query the power save profile. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[out] pvQueryBuf A pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \return WLAN_STATUS_SUCCESS -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryP2pPowerSaveProfile(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ DEBUGFUNC("wlanoidQueryP2pPowerSaveProfile"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4QueryInfoLen); -+ -+ if (u4QueryBufferLen != 0) { -+ ASSERT(pvQueryBuffer); -+ -+ *(PPARAM_POWER_MODE) pvQueryBuffer = -+ (PARAM_POWER_MODE) (prAdapter->rWlanInfo.arPowerSaveMode[NETWORK_TYPE_P2P_INDEX].ucPsProfile); -+ *pu4QueryInfoLen = sizeof(PARAM_POWER_MODE); -+ } -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is used to set the power save profile. -+* -+* \param[in] pvAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetP2pPowerSaveProfile(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ WLAN_STATUS status; -+ PARAM_POWER_MODE ePowerMode; -+ -+ DEBUGFUNC("wlanoidSetP2pPowerSaveProfile"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ *pu4SetInfoLen = sizeof(PARAM_POWER_MODE); -+ if (u4SetBufferLen < sizeof(PARAM_POWER_MODE)) { -+ DBGLOG(REQ, WARN, "Invalid length %u\n", u4SetBufferLen); -+ return WLAN_STATUS_INVALID_LENGTH; -+ } else if (*(PPARAM_POWER_MODE) pvSetBuffer >= Param_PowerModeMax) { -+ WARNLOG(("Invalid power mode %d\n", *(PPARAM_POWER_MODE) pvSetBuffer)); -+ return WLAN_STATUS_INVALID_DATA; -+ } -+ -+ ePowerMode = *(PPARAM_POWER_MODE) pvSetBuffer; -+ -+ if (prAdapter->fgEnCtiaPowerMode) { -+ if (ePowerMode == Param_PowerModeCAM) { -+ /*Todo:: Nothing*/ -+ /*Todo:: Nothing*/ -+ } else { -+ /* User setting to PS mode (Param_PowerModeMAX_PSP or Param_PowerModeFast_PSP) */ -+ -+ if (prAdapter->u4CtiaPowerMode == 0) { -+ /* force to keep in CAM mode */ -+ ePowerMode = Param_PowerModeCAM; -+ } else if (prAdapter->u4CtiaPowerMode == 1) { -+ ePowerMode = Param_PowerModeMAX_PSP; -+ } else if (prAdapter->u4CtiaPowerMode == 2) { -+ ePowerMode = Param_PowerModeFast_PSP; -+ } -+ } -+ } -+ -+ status = nicConfigPowerSaveProfile(prAdapter, NETWORK_TYPE_P2P_INDEX, ePowerMode, TRUE); -+ return status; -+} /* end of wlanoidSetP2pPowerSaveProfile() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is used to set the power save profile. -+* -+* \param[in] pvAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetP2pSetNetworkAddress(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ UINT_32 i, j; -+ P_CMD_SET_NETWORK_ADDRESS_LIST prCmdNetworkAddressList; -+ P_PARAM_NETWORK_ADDRESS_LIST prNetworkAddressList = (P_PARAM_NETWORK_ADDRESS_LIST) pvSetBuffer; -+ P_PARAM_NETWORK_ADDRESS prNetworkAddress; -+ P_PARAM_NETWORK_ADDRESS_IP prNetAddrIp; -+ UINT_32 u4IpAddressCount, u4CmdSize; -+ PUINT_8 pucBuf = (PUINT_8) pvSetBuffer; -+ -+ DEBUGFUNC("wlanoidSetP2pSetNetworkAddress"); -+ DBGLOG(P2P, TRACE, "\n"); -+ DBGLOG(P2P, INFO, "wlanoidSetP2pSetNetworkAddress (%d)\n", (INT_16) u4SetBufferLen); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ *pu4SetInfoLen = 4; -+ -+ if (u4SetBufferLen < sizeof(PARAM_NETWORK_ADDRESS_LIST)) -+ return WLAN_STATUS_INVALID_DATA; -+ -+ *pu4SetInfoLen = 0; -+ u4IpAddressCount = 0; -+ -+ prNetworkAddress = prNetworkAddressList->arAddress; -+ for (i = 0; i < prNetworkAddressList->u4AddressCount; i++) { -+ if (prNetworkAddress->u2AddressType == PARAM_PROTOCOL_ID_TCP_IP && -+ prNetworkAddress->u2AddressLength == sizeof(PARAM_NETWORK_ADDRESS_IP)) { -+ u4IpAddressCount++; -+ } -+ -+ prNetworkAddress = (P_PARAM_NETWORK_ADDRESS) ((ULONG) prNetworkAddress + -+ (ULONG) (prNetworkAddress->u2AddressLength + -+ OFFSET_OF(PARAM_NETWORK_ADDRESS, aucAddress))); -+ } -+ -+ /* construct payload of command packet */ -+ u4CmdSize = OFFSET_OF(CMD_SET_NETWORK_ADDRESS_LIST, arNetAddress) + -+ sizeof(IPV4_NETWORK_ADDRESS) * u4IpAddressCount; -+ -+ if (u4IpAddressCount == 0) -+ u4CmdSize = sizeof(CMD_SET_NETWORK_ADDRESS_LIST); -+ -+ prCmdNetworkAddressList = (P_CMD_SET_NETWORK_ADDRESS_LIST) kalMemAlloc(u4CmdSize, VIR_MEM_TYPE); -+ -+ if (prCmdNetworkAddressList == NULL) -+ return WLAN_STATUS_FAILURE; -+ -+ /* fill P_CMD_SET_NETWORK_ADDRESS_LIST */ -+ prCmdNetworkAddressList->ucNetTypeIndex = NETWORK_TYPE_P2P_INDEX; -+ -+ /* only to set IP address to FW once ARP filter is enabled */ -+ if (prAdapter->fgEnArpFilter) { -+ prCmdNetworkAddressList->ucAddressCount = (UINT_8) u4IpAddressCount; -+ prNetworkAddress = prNetworkAddressList->arAddress; -+ -+ DBGLOG(P2P, INFO, "u4IpAddressCount (%u)\n", u4IpAddressCount); -+ for (i = 0, j = 0; i < prNetworkAddressList->u4AddressCount; i++) { -+ if (prNetworkAddress->u2AddressType == PARAM_PROTOCOL_ID_TCP_IP && -+ prNetworkAddress->u2AddressLength == sizeof(PARAM_NETWORK_ADDRESS_IP)) { -+ prNetAddrIp = (P_PARAM_NETWORK_ADDRESS_IP) prNetworkAddress->aucAddress; -+ -+ kalMemCopy(prCmdNetworkAddressList->arNetAddress[j].aucIpAddr, -+ &(prNetAddrIp->in_addr), sizeof(UINT_32)); -+ -+ j++; -+ -+ pucBuf = (PUINT_8) &prNetAddrIp->in_addr; -+ DBGLOG(P2P, INFO, "prNetAddrIp->in_addr:%d:%d:%d:%d\n", -+ (UINT_8) pucBuf[0], (UINT_8) pucBuf[1], -+ (UINT_8) pucBuf[2], (UINT_8) pucBuf[3]); -+ } -+ -+ prNetworkAddress = (P_PARAM_NETWORK_ADDRESS) ((ULONG) prNetworkAddress + -+ (ULONG) (prNetworkAddress->u2AddressLength + -+ OFFSET_OF(PARAM_NETWORK_ADDRESS, -+ aucAddress))); -+ } -+ -+ } else { -+ prCmdNetworkAddressList->ucAddressCount = 0; -+ } -+ -+ rStatus = wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SET_IP_ADDRESS, -+ TRUE, -+ FALSE, -+ TRUE, -+ nicCmdEventSetIpAddress, -+ nicOidCmdTimeoutCommon, -+ u4CmdSize, (PUINT_8) prCmdNetworkAddressList, pvSetBuffer, u4SetBufferLen); -+ -+ kalMemFree(prCmdNetworkAddressList, VIR_MEM_TYPE, u4CmdSize); -+ return rStatus; -+} /* end of wlanoidSetP2pSetNetworkAddress() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to set Multicast Address List. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer Pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+* \retval WLAN_STATUS_ADAPTER_NOT_READY -+* \retval WLAN_STATUS_MULTICAST_FULL -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetP2PMulticastList(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ CMD_MAC_MCAST_ADDR rCmdMacMcastAddr; -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ /* The data must be a multiple of the Ethernet address size. */ -+ if ((u4SetBufferLen % MAC_ADDR_LEN)) { -+ DBGLOG(REQ, WARN, "Invalid MC list length %u\n", u4SetBufferLen); -+ -+ *pu4SetInfoLen = (((u4SetBufferLen + MAC_ADDR_LEN) - 1) / MAC_ADDR_LEN) * MAC_ADDR_LEN; -+ -+ return WLAN_STATUS_INVALID_LENGTH; -+ } -+ -+ *pu4SetInfoLen = u4SetBufferLen; -+ -+ /* Verify if we can support so many multicast addresses. */ -+ if ((u4SetBufferLen / MAC_ADDR_LEN) > MAX_NUM_GROUP_ADDR) { -+ DBGLOG(REQ, WARN, "Too many MC addresses\n"); -+ -+ return WLAN_STATUS_MULTICAST_FULL; -+ } -+ -+ /* NOTE(Kevin): Windows may set u4SetBufferLen == 0 && -+ * pvSetBuffer == NULL to clear exist Multicast List. -+ */ -+ if (u4SetBufferLen) -+ ASSERT(pvSetBuffer); -+ -+ if (prAdapter->rAcpiState == ACPI_STATE_D3) { -+ DBGLOG(REQ, WARN, "Fail in set multicast list! (Adapter not ready). ACPI=D%d, Radio=%d\n", -+ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); -+ return WLAN_STATUS_ADAPTER_NOT_READY; -+ } -+ -+ rCmdMacMcastAddr.u4NumOfGroupAddr = u4SetBufferLen / MAC_ADDR_LEN; -+ rCmdMacMcastAddr.ucNetTypeIndex = NETWORK_TYPE_P2P_INDEX; -+ kalMemCopy(rCmdMacMcastAddr.arAddress, pvSetBuffer, u4SetBufferLen); -+ -+ /* This CMD response is no need to complete the OID. Or the event would unsync. */ -+ return wlanoidSendSetQueryP2PCmd(prAdapter, CMD_ID_MAC_MCAST_ADDR, TRUE, FALSE, FALSE, -+ nicCmdEventSetCommon, -+ nicOidCmdTimeoutCommon, -+ sizeof(CMD_MAC_MCAST_ADDR), -+ (PUINT_8) &rCmdMacMcastAddr, pvSetBuffer, u4SetBufferLen); -+ -+} /* end of wlanoidSetP2PMulticastList() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to send GAS frame for P2P Service Discovery Request -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer Pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+* \retval WLAN_STATUS_ADAPTER_NOT_READY -+* \retval WLAN_STATUS_MULTICAST_FULL -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSendP2PSDRequest(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ WLAN_STATUS rWlanStatus = WLAN_STATUS_SUCCESS; -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ if (u4SetBufferLen) -+ ASSERT(pvSetBuffer); -+ -+ if (u4SetBufferLen < sizeof(PARAM_P2P_SEND_SD_REQUEST)) { -+ *pu4SetInfoLen = sizeof(PARAM_P2P_SEND_SD_REQUEST); -+ return WLAN_STATUS_BUFFER_TOO_SHORT; -+ } -+/* rWlanStatus = p2pFsmRunEventSDRequest(prAdapter, (P_PARAM_P2P_SEND_SD_REQUEST)pvSetBuffer); */ -+ -+ return rWlanStatus; -+} /* end of wlanoidSendP2PSDRequest() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to send GAS frame for P2P Service Discovery Response -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer Pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+* \retval WLAN_STATUS_ADAPTER_NOT_READY -+* \retval WLAN_STATUS_MULTICAST_FULL -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSendP2PSDResponse(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ WLAN_STATUS rWlanStatus = WLAN_STATUS_SUCCESS; -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ if (u4SetBufferLen) -+ ASSERT(pvSetBuffer); -+ -+ if (u4SetBufferLen < sizeof(PARAM_P2P_SEND_SD_RESPONSE)) { -+ *pu4SetInfoLen = sizeof(PARAM_P2P_SEND_SD_RESPONSE); -+ return WLAN_STATUS_BUFFER_TOO_SHORT; -+ } -+/* rWlanStatus = p2pFsmRunEventSDResponse(prAdapter, (P_PARAM_P2P_SEND_SD_RESPONSE)pvSetBuffer); */ -+ -+ return rWlanStatus; -+} /* end of wlanoidGetP2PSDRequest() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to get GAS frame for P2P Service Discovery Request -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[out] pvQueryBuffer A pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufferLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+* \retval WLAN_STATUS_ADAPTER_NOT_READY -+* \retval WLAN_STATUS_MULTICAST_FULL -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidGetP2PSDRequest(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ WLAN_STATUS rWlanStatus = WLAN_STATUS_SUCCESS; -+ /*PUINT_8 pucPacketBuffer = NULL, pucTA = NULL;*/ -+/* PUINT_8 pucChannelNum = NULL; */ -+ /*PUINT_16 pu2PacketLength = NULL;*/ -+ /*P_WLAN_MAC_HEADER_T prWlanHdr = (P_WLAN_MAC_HEADER_T) NULL;*/ -+ /*UINT_8 ucVersionNum = 0;*/ -+/* UINT_8 ucChannelNum = 0, ucSeqNum = 0; */ -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4QueryInfoLen); -+ -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ -+ if (u4QueryBufferLen < sizeof(PARAM_P2P_GET_SD_REQUEST)) { -+ *pu4QueryInfoLen = sizeof(PARAM_P2P_GET_SD_REQUEST); -+ return WLAN_STATUS_BUFFER_TOO_SHORT; -+ } -+ -+ DBGLOG(P2P, TRACE, "Get Service Discovery Request\n"); -+#if 0 -+ ucVersionNum = p2pFuncGetVersionNumOfSD(prAdapter); -+ if (ucVersionNum == 0) { -+ P_PARAM_P2P_GET_SD_REQUEST prP2pGetSdReq = (P_PARAM_P2P_GET_SD_REQUEST) pvQueryBuffer; -+ -+ pucPacketBuffer = prP2pGetSdReq->aucPacketContent; -+ pu2PacketLength = &prP2pGetSdReq->u2PacketLength; -+ pucTA = &prP2pGetSdReq->rTransmitterAddr; -+ } else { -+ P_PARAM_P2P_GET_SD_REQUEST_EX prP2pGetSdReqEx = (P_PARAM_P2P_GET_SD_REQUEST_EX) NULL; -+ -+ prP2pGetSdReqEx = (P_PARAM_P2P_GET_SD_REQUEST) pvQueryBuffer; -+ pucPacketBuffer = prP2pGetSdReqEx->aucPacketContent; -+ pu2PacketLength = &prP2pGetSdReqEx->u2PacketLength; -+ pucTA = &prP2pGetSdReqEx->rTransmitterAddr; -+ pucChannelNum = &prP2pGetSdReqEx->ucChannelNum; -+ ucSeqNum = prP2pGetSdReqEx->ucSeqNum; -+ } -+ -+ rWlanStatus = p2pFuncGetServiceDiscoveryFrame(prAdapter, -+ pucPacketBuffer, -+ (u4QueryBufferLen - sizeof(PARAM_P2P_GET_SD_REQUEST)), -+ (PUINT_32) pu2PacketLength, pucChannelNum, ucSeqNum); -+#else -+ *pu4QueryInfoLen = 0; -+ return rWlanStatus; -+#endif -+ /* -+ prWlanHdr = (P_WLAN_MAC_HEADER_T) pucPacketBuffer; -+ -+ kalMemCopy(pucTA, prWlanHdr->aucAddr2, MAC_ADDR_LEN); -+ -+ if (pu4QueryInfoLen) { -+ if (ucVersionNum == 0) -+ *pu4QueryInfoLen = (UINT_32) (sizeof(PARAM_P2P_GET_SD_REQUEST) + (*pu2PacketLength)); -+ else -+ *pu4QueryInfoLen = (UINT_32) (sizeof(PARAM_P2P_GET_SD_REQUEST_EX) + (*pu2PacketLength)); -+ -+ } -+ -+ return rWlanStatus; -+ */ -+} /* end of wlanoidGetP2PSDRequest() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to get GAS frame for P2P Service Discovery Response -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[out] pvQueryBuffer A pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufferLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+* \retval WLAN_STATUS_ADAPTER_NOT_READY -+* \retval WLAN_STATUS_MULTICAST_FULL -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidGetP2PSDResponse(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ WLAN_STATUS rWlanStatus = WLAN_STATUS_SUCCESS; -+ /*P_WLAN_MAC_HEADER_T prWlanHdr = (P_WLAN_MAC_HEADER_T) NULL;*/ -+ /* UINT_8 ucSeqNum = 0, */ -+ /*UINT_8 ucVersionNum = 0;*/ -+ /*PUINT_8 pucPacketContent = (PUINT_8) NULL, pucTA = (PUINT_8) NULL;*/ -+ /*PUINT_16 pu2PacketLength = (PUINT_16) NULL;*/ -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4QueryInfoLen); -+ -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ -+ if (u4QueryBufferLen < sizeof(PARAM_P2P_GET_SD_RESPONSE)) { -+ *pu4QueryInfoLen = sizeof(PARAM_P2P_GET_SD_RESPONSE); -+ return WLAN_STATUS_BUFFER_TOO_SHORT; -+ } -+ -+ DBGLOG(P2P, TRACE, "Get Service Discovery Response\n"); -+ -+#if 0 -+ ucVersionNum = p2pFuncGetVersionNumOfSD(prAdapter); -+ if (ucVersionNum == 0) { -+ P_PARAM_P2P_GET_SD_RESPONSE prP2pGetSdRsp = (P_PARAM_P2P_GET_SD_RESPONSE) NULL; -+ -+ prP2pGetSdRsp = (P_PARAM_P2P_GET_SD_REQUEST) pvQueryBuffer; -+ pucPacketContent = prP2pGetSdRsp->aucPacketContent; -+ pucTA = &prP2pGetSdRsp->rTransmitterAddr; -+ pu2PacketLength = &prP2pGetSdRsp->u2PacketLength; -+ } else { -+ P_PARAM_P2P_GET_SD_RESPONSE_EX prP2pGetSdRspEx = (P_PARAM_P2P_GET_SD_RESPONSE_EX) NULL; -+ -+ prP2pGetSdRspEx = (P_PARAM_P2P_GET_SD_RESPONSE_EX) pvQueryBuffer; -+ pucPacketContent = prP2pGetSdRspEx->aucPacketContent; -+ pucTA = &prP2pGetSdRspEx->rTransmitterAddr; -+ pu2PacketLength = &prP2pGetSdRspEx->u2PacketLength; -+ ucSeqNum = prP2pGetSdRspEx->ucSeqNum; -+ } -+ -+/* rWlanStatus = p2pFuncGetServiceDiscoveryFrame(prAdapter, */ -+/* pucPacketContent, */ -+/* (u4QueryBufferLen - sizeof(PARAM_P2P_GET_SD_RESPONSE)), */ -+/* (PUINT_32)pu2PacketLength, */ -+/* NULL, */ -+/* ucSeqNum); */ -+#else -+ *pu4QueryInfoLen = 0; -+ return rWlanStatus; -+#endif -+ /* -+ prWlanHdr = (P_WLAN_MAC_HEADER_T) pucPacketContent; -+ -+ kalMemCopy(pucTA, prWlanHdr->aucAddr2, MAC_ADDR_LEN); -+ -+ if (pu4QueryInfoLen) { -+ if (ucVersionNum == 0) -+ *pu4QueryInfoLen = (UINT_32) (sizeof(PARAM_P2P_GET_SD_RESPONSE) + *pu2PacketLength); -+ else -+ *pu4QueryInfoLen = (UINT_32) (sizeof(PARAM_P2P_GET_SD_RESPONSE_EX) + *pu2PacketLength); -+ } -+ -+ return rWlanStatus; -+ */ -+} /* end of wlanoidGetP2PSDResponse() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to terminate P2P Service Discovery Phase -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer Pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+* \retval WLAN_STATUS_ADAPTER_NOT_READY -+* \retval WLAN_STATUS_MULTICAST_FULL -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetP2PTerminateSDPhase(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ WLAN_STATUS rWlanStatus = WLAN_STATUS_SUCCESS; -+ P_PARAM_P2P_TERMINATE_SD_PHASE prP2pTerminateSD = (P_PARAM_P2P_TERMINATE_SD_PHASE) NULL; -+ UINT_8 aucNullAddr[] = NULL_MAC_ADDR; -+ -+ do { -+ if ((prAdapter == NULL) || (pu4SetInfoLen == NULL)) -+ break; -+ -+ if ((u4SetBufferLen) && (pvSetBuffer == NULL)) -+ break; -+ -+ if (u4SetBufferLen < sizeof(PARAM_P2P_TERMINATE_SD_PHASE)) { -+ *pu4SetInfoLen = sizeof(PARAM_P2P_TERMINATE_SD_PHASE); -+ rWlanStatus = WLAN_STATUS_BUFFER_TOO_SHORT; -+ break; -+ } -+ -+ prP2pTerminateSD = (P_PARAM_P2P_TERMINATE_SD_PHASE) pvSetBuffer; -+ -+ if (EQUAL_MAC_ADDR(prP2pTerminateSD->rPeerAddr, aucNullAddr)) { -+ DBGLOG(P2P, TRACE, "Service Discovery Version 2.0\n"); -+/* p2pFuncSetVersionNumOfSD(prAdapter, 2); */ -+ } -+ /* rWlanStatus = p2pFsmRunEventSDAbort(prAdapter); */ -+ -+ } while (FALSE); -+ -+ return rWlanStatus; -+} /* end of wlanoidSetP2PTerminateSDPhase() */ -+ -+#if CFG_SUPPORT_ANTI_PIRACY -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer Pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+* \retval WLAN_STATUS_ADAPTER_NOT_READY -+* \retval WLAN_STATUS_MULTICAST_FULL -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetSecCheckRequest(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ if (u4SetBufferLen) -+ ASSERT(pvSetBuffer); -+ -+ return wlanoidSendSetQueryP2PCmd(prAdapter, -+ CMD_ID_SEC_CHECK, -+ FALSE, -+ TRUE, -+ TRUE, -+ NULL, -+ nicOidCmdTimeoutCommon, -+ u4SetBufferLen, (PUINT_8) pvSetBuffer, pvSetBuffer, u4SetBufferLen); -+ -+} /* end of wlanoidSetSecCheckRequest() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[out] pvQueryBuffer A pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufferLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+* \retval WLAN_STATUS_ADAPTER_NOT_READY -+* \retval WLAN_STATUS_MULTICAST_FULL -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidGetSecCheckResponse(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ WLAN_STATUS rWlanStatus = WLAN_STATUS_SUCCESS; -+ /* P_WLAN_MAC_HEADER_T prWlanHdr = (P_WLAN_MAC_HEADER_T)NULL; */ -+ P_GLUE_INFO_T prGlueInfo; -+ -+ prGlueInfo = prAdapter->prGlueInfo; -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4QueryInfoLen); -+ -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ -+ if (u4QueryBufferLen > 256) -+ u4QueryBufferLen = 256; -+ -+ *pu4QueryInfoLen = u4QueryBufferLen; -+ -+#if DBG -+ DBGLOG_MEM8(SEC, LOUD, prGlueInfo->prP2PInfo->aucSecCheckRsp, u4QueryBufferLen); -+#endif -+ kalMemCopy((PUINT_8) (pvQueryBuffer + OFFSET_OF(IW_P2P_TRANSPORT_STRUCT, aucBuffer)), -+ prGlueInfo->prP2PInfo->aucSecCheckRsp, u4QueryBufferLen); -+ -+ return rWlanStatus; -+} /* end of wlanoidGetSecCheckResponse() */ -+#endif -+ -+WLAN_STATUS -+wlanoidSetNoaParam(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ P_PARAM_CUSTOM_NOA_PARAM_STRUCT_T prNoaParam; -+ CMD_CUSTOM_NOA_PARAM_STRUCT_T rCmdNoaParam; -+ -+ DEBUGFUNC("wlanoidSetNoaParam"); -+ DBGLOG(P2P, TRACE, "\n"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ *pu4SetInfoLen = sizeof(PARAM_CUSTOM_NOA_PARAM_STRUCT_T); -+ -+ if (u4SetBufferLen < sizeof(PARAM_CUSTOM_NOA_PARAM_STRUCT_T)) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ ASSERT(pvSetBuffer); -+ -+ prNoaParam = (P_PARAM_CUSTOM_NOA_PARAM_STRUCT_T) pvSetBuffer; -+ -+ kalMemZero(&rCmdNoaParam, sizeof(CMD_CUSTOM_NOA_PARAM_STRUCT_T)); -+ rCmdNoaParam.u4NoaDurationMs = prNoaParam->u4NoaDurationMs; -+ rCmdNoaParam.u4NoaIntervalMs = prNoaParam->u4NoaIntervalMs; -+ rCmdNoaParam.u4NoaCount = prNoaParam->u4NoaCount; -+ -+#if 0 -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SET_NOA_PARAM, -+ TRUE, -+ FALSE, -+ TRUE, -+ nicCmdEventSetCommon, -+ nicOidCmdTimeoutCommon, -+ sizeof(CMD_CUSTOM_NOA_PARAM_STRUCT_T), -+ (PUINT_8) &rCmdNoaParam, pvSetBuffer, u4SetBufferLen); -+#else -+ return wlanoidSendSetQueryP2PCmd(prAdapter, -+ CMD_ID_SET_NOA_PARAM, -+ TRUE, -+ FALSE, -+ TRUE, -+ NULL, -+ nicOidCmdTimeoutCommon, -+ sizeof(CMD_CUSTOM_NOA_PARAM_STRUCT_T), -+ (PUINT_8) &rCmdNoaParam, pvSetBuffer, u4SetBufferLen); -+ -+#endif -+ -+} -+ -+WLAN_STATUS -+wlanoidSetOppPsParam(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ P_PARAM_CUSTOM_OPPPS_PARAM_STRUCT_T prOppPsParam; -+ CMD_CUSTOM_OPPPS_PARAM_STRUCT_T rCmdOppPsParam; -+ -+ DEBUGFUNC("wlanoidSetOppPsParam"); -+ DBGLOG(P2P, TRACE, "\n"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ *pu4SetInfoLen = sizeof(PARAM_CUSTOM_OPPPS_PARAM_STRUCT_T); -+ -+ if (u4SetBufferLen < sizeof(PARAM_CUSTOM_OPPPS_PARAM_STRUCT_T)) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ ASSERT(pvSetBuffer); -+ -+ prOppPsParam = (P_PARAM_CUSTOM_OPPPS_PARAM_STRUCT_T) pvSetBuffer; -+ -+ kalMemZero(&rCmdOppPsParam, sizeof(CMD_CUSTOM_OPPPS_PARAM_STRUCT_T)); -+ rCmdOppPsParam.u4CTwindowMs = prOppPsParam->u4CTwindowMs; -+ -+#if 0 -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SET_OPPPS_PARAM, -+ TRUE, -+ FALSE, -+ TRUE, -+ nicCmdEventSetCommon, -+ nicOidCmdTimeoutCommon, -+ sizeof(CMD_CUSTOM_OPPPS_PARAM_STRUCT_T), -+ (PUINT_8) &rCmdOppPsParam, pvSetBuffer, u4SetBufferLen); -+#else -+ return wlanoidSendSetQueryP2PCmd(prAdapter, -+ CMD_ID_SET_NOA_PARAM, -+ TRUE, -+ FALSE, -+ TRUE, -+ NULL, -+ nicOidCmdTimeoutCommon, -+ sizeof(CMD_CUSTOM_OPPPS_PARAM_STRUCT_T), -+ (PUINT_8) &rCmdOppPsParam, pvSetBuffer, u4SetBufferLen); -+ -+#endif -+ -+} -+ -+WLAN_STATUS -+wlanoidSetUApsdParam(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ P_PARAM_CUSTOM_UAPSD_PARAM_STRUCT_T prUapsdParam; -+ CMD_CUSTOM_UAPSD_PARAM_STRUCT_T rCmdUapsdParam; -+ P_PM_PROFILE_SETUP_INFO_T prPmProfSetupInfo; -+ P_BSS_INFO_T prBssInfo; -+ -+ DEBUGFUNC("wlanoidSetUApsdParam"); -+ DBGLOG(P2P, TRACE, "\n"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ *pu4SetInfoLen = sizeof(PARAM_CUSTOM_UAPSD_PARAM_STRUCT_T); -+ -+ if (u4SetBufferLen < sizeof(PARAM_CUSTOM_UAPSD_PARAM_STRUCT_T)) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ ASSERT(pvSetBuffer); -+ -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); -+ prPmProfSetupInfo = &prBssInfo->rPmProfSetupInfo; -+ -+ prUapsdParam = (P_PARAM_CUSTOM_UAPSD_PARAM_STRUCT_T) pvSetBuffer; -+ -+ kalMemZero(&rCmdUapsdParam, sizeof(CMD_CUSTOM_OPPPS_PARAM_STRUCT_T)); -+ rCmdUapsdParam.fgEnAPSD = prUapsdParam->fgEnAPSD; -+ prAdapter->rWifiVar.fgSupportUAPSD = prUapsdParam->fgEnAPSD; -+ -+ rCmdUapsdParam.fgEnAPSD_AcBe = prUapsdParam->fgEnAPSD_AcBe; -+ rCmdUapsdParam.fgEnAPSD_AcBk = prUapsdParam->fgEnAPSD_AcBk; -+ rCmdUapsdParam.fgEnAPSD_AcVo = prUapsdParam->fgEnAPSD_AcVo; -+ rCmdUapsdParam.fgEnAPSD_AcVi = prUapsdParam->fgEnAPSD_AcVi; -+ prPmProfSetupInfo->ucBmpDeliveryAC = -+ ((prUapsdParam->fgEnAPSD_AcBe << 0) | -+ (prUapsdParam->fgEnAPSD_AcBk << 1) | -+ (prUapsdParam->fgEnAPSD_AcVi << 2) | (prUapsdParam->fgEnAPSD_AcVo << 3)); -+ prPmProfSetupInfo->ucBmpTriggerAC = -+ ((prUapsdParam->fgEnAPSD_AcBe << 0) | -+ (prUapsdParam->fgEnAPSD_AcBk << 1) | -+ (prUapsdParam->fgEnAPSD_AcVi << 2) | (prUapsdParam->fgEnAPSD_AcVo << 3)); -+ -+ rCmdUapsdParam.ucMaxSpLen = prUapsdParam->ucMaxSpLen; -+ prPmProfSetupInfo->ucUapsdSp = prUapsdParam->ucMaxSpLen; -+ -+#if 0 -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SET_UAPSD_PARAM, -+ TRUE, -+ FALSE, -+ TRUE, -+ nicCmdEventSetCommon, -+ nicOidCmdTimeoutCommon, -+ sizeof(CMD_CUSTOM_OPPPS_PARAM_STRUCT_T), -+ (PUINT_8) &rCmdUapsdParam, pvSetBuffer, u4SetBufferLen); -+#else -+ return wlanoidSendSetQueryP2PCmd(prAdapter, -+ CMD_ID_SET_UAPSD_PARAM, -+ TRUE, -+ FALSE, -+ TRUE, -+ NULL, -+ nicOidCmdTimeoutCommon, -+ sizeof(CMD_CUSTOM_OPPPS_PARAM_STRUCT_T), -+ (PUINT_8) &rCmdUapsdParam, pvSetBuffer, u4SetBufferLen); -+ -+#endif -+} -+ -+WLAN_STATUS -+wlanoidQueryP2pOpChannel(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ -+ WLAN_STATUS rResult = WLAN_STATUS_FAILURE; -+/* PUINT_8 pucOpChnl = (PUINT_8)pvQueryBuffer; */ -+ -+ do { -+ if ((prAdapter == NULL) || (pu4QueryInfoLen == NULL)) -+ break; -+ -+ if ((u4QueryBufferLen) && (pvQueryBuffer == NULL)) -+ break; -+ -+ if (u4QueryBufferLen < sizeof(UINT_8)) { -+ *pu4QueryInfoLen = sizeof(UINT_8); -+ rResult = WLAN_STATUS_BUFFER_TOO_SHORT; -+ break; -+ } -+#if 0 -+ if (!p2pFuncGetCurrentOpChnl(prAdapter, pucOpChnl)) { -+ rResult = WLAN_STATUS_INVALID_DATA; -+ break; -+ } -+#else -+ rResult = WLAN_STATUS_INVALID_DATA; -+ break; -+#endif -+ /* -+ *pu4QueryInfoLen = sizeof(UINT_8); -+ rResult = WLAN_STATUS_SUCCESS; -+ */ -+ -+ } while (FALSE); -+ -+ return rResult; -+} /* wlanoidQueryP2pOpChannel */ -+ -+WLAN_STATUS -+wlanoidQueryP2pVersion(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ WLAN_STATUS rResult = WLAN_STATUS_FAILURE; -+/* PUINT_8 pucVersionNum = (PUINT_8)pvQueryBuffer; */ -+ -+ do { -+ if ((prAdapter == NULL) || (pu4QueryInfoLen == NULL)) -+ break; -+ -+ if ((u4QueryBufferLen) && (pvQueryBuffer == NULL)) -+ break; -+ -+ if (u4QueryBufferLen < sizeof(UINT_8)) { -+ *pu4QueryInfoLen = sizeof(UINT_8); -+ rResult = WLAN_STATUS_BUFFER_TOO_SHORT; -+ break; -+ } -+ -+ } while (FALSE); -+ -+ return rResult; -+} /* wlanoidQueryP2pVersion */ -+ -+WLAN_STATUS -+wlanoidSetP2pSupplicantVersion(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ WLAN_STATUS rResult = WLAN_STATUS_FAILURE; -+ UINT_8 ucVersionNum; -+ -+ do { -+ if ((prAdapter == NULL) || (pu4SetInfoLen == NULL)) { -+ -+ rResult = WLAN_STATUS_INVALID_DATA; -+ break; -+ } -+ -+ if ((u4SetBufferLen) && (pvSetBuffer == NULL)) { -+ rResult = WLAN_STATUS_INVALID_DATA; -+ break; -+ } -+ -+ *pu4SetInfoLen = sizeof(UINT_8); -+ -+ if (u4SetBufferLen < sizeof(UINT_8)) { -+ rResult = WLAN_STATUS_INVALID_LENGTH; -+ break; -+ } -+ -+ ucVersionNum = *((PUINT_8) pvSetBuffer); -+ -+ rResult = WLAN_STATUS_SUCCESS; -+ } while (FALSE); -+ -+ return rResult; -+} /* wlanoidSetP2pSupplicantVersion */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is used to set the WPS mode. -+* -+* \param[in] pvAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetP2pWPSmode(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ WLAN_STATUS status; -+ UINT_32 u4IsWPSmode = 0; -+ -+ DEBUGFUNC("wlanoidSetP2pWPSmode"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ if (pvSetBuffer) -+ u4IsWPSmode = *(PUINT_32) pvSetBuffer; -+ else -+ u4IsWPSmode = 0; -+ -+ if (u4IsWPSmode) -+ prAdapter->rWifiVar.prP2pFsmInfo->fgIsWPSMode = 1; -+ else -+ prAdapter->rWifiVar.prP2pFsmInfo->fgIsWPSMode = 0; -+ -+ status = nicUpdateBss(prAdapter, NETWORK_TYPE_P2P_INDEX); -+ -+ return status; -+} /* end of wlanoidSetP2pWPSmode() */ -+ -+#if CFG_SUPPORT_P2P_RSSI_QUERY -+WLAN_STATUS -+wlanoidQueryP2pRssi(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ DEBUGFUNC("wlanoidQueryP2pRssi"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4QueryInfoLen); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ -+ *pu4QueryInfoLen = sizeof(PARAM_RSSI); -+ -+ /* Check for query buffer length */ -+ if (u4QueryBufferLen < *pu4QueryInfoLen) { -+ DBGLOG(REQ, WARN, "Too short length %u\n", u4QueryBufferLen); -+ return WLAN_STATUS_BUFFER_TOO_SHORT; -+ } -+ -+ if (prAdapter->fgIsP2pLinkQualityValid == TRUE && -+ (kalGetTimeTick() - prAdapter->rP2pLinkQualityUpdateTime) <= CFG_LINK_QUALITY_VALID_PERIOD) { -+ PARAM_RSSI rRssi; -+ -+ rRssi = (PARAM_RSSI) prAdapter->rP2pLinkQuality.cRssi; /* ranged from (-128 ~ 30) in unit of dBm */ -+ -+ if (rRssi > PARAM_WHQL_RSSI_MAX_DBM) -+ rRssi = PARAM_WHQL_RSSI_MAX_DBM; -+ else if (rRssi < PARAM_WHQL_RSSI_MIN_DBM) -+ rRssi = PARAM_WHQL_RSSI_MIN_DBM; -+ -+ kalMemCopy(pvQueryBuffer, &rRssi, sizeof(PARAM_RSSI)); -+ return WLAN_STATUS_SUCCESS; -+ } -+#ifdef LINUX -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_GET_LINK_QUALITY, -+ FALSE, -+ TRUE, -+ TRUE, -+ nicCmdEventQueryLinkQuality, -+ nicOidCmdTimeoutCommon, -+ *pu4QueryInfoLen, pvQueryBuffer, pvQueryBuffer, u4QueryBufferLen); -+#else -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_GET_LINK_QUALITY, -+ FALSE, -+ TRUE, -+ TRUE, -+ nicCmdEventQueryLinkQuality, -+ nicOidCmdTimeoutCommon, 0, NULL, pvQueryBuffer, u4QueryBufferLen); -+ -+#endif -+} /* wlanoidQueryP2pRssi */ -+#endif -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/CFG_Wifi_File.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/CFG_Wifi_File.h -new file mode 100644 -index 000000000000..89de18c89c1c ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/CFG_Wifi_File.h -@@ -0,0 +1,238 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/CFG_Wifi_File.h#1 -+*/ -+ -+/*! \file CFG_Wifi_File.h -+ \brief Collection of NVRAM structure used for YuSu project -+ -+ In this file we collect all compiler flags and detail the driver behavior if -+ enable/disable such switch or adjust numeric parameters. -+*/ -+ -+/* -+** Log: CFG_Wifi_File.h -+ * -+ * 09 08 2011 cm.chang -+ * [WCXRP00000969] [MT6620 Wi-Fi][Driver][FW] Channel list for 5G band based on country code -+ * Use new fields ucChannelListMap and ucChannelListIndex in NVRAM -+ * -+ * 08 31 2011 cm.chang -+ * [WCXRP00000969] [MT6620 Wi-Fi][Driver][FW] Channel list for 5G band based on country code -+ * . -+ * -+ * 08 15 2011 cp.wu -+ * [WCXRP00000851] [MT6628 Wi-Fi][Driver] Add HIFSYS related definition to driver source tree -+ * add MT6628-specific definitions. -+ * -+ * 08 09 2011 cp.wu -+ * [WCXRP00000702] [MT5931][Driver] Modify initialization sequence for E1 ASIC -+ * [WCXRP00000913] [MT6620 Wi-Fi] create repository of source code dedicated for MT6620 E6 ASIC -+ * add CCK-DSSS TX-PWR control field in NVRAM and CMD definition for MT5931-MP -+ * -+ * 05 27 2011 cp.wu -+ * [WCXRP00000749] [MT6620 Wi-Fi][Driver] Add band edge tx power control to Wi-Fi NVRAM -+ * update NVRAM data structure definition. -+ * -+ * 03 10 2011 cp.wu -+ * [WCXRP00000532] [MT6620 Wi-Fi][Driver] Migrate NVRAM configuration procedures from MT6620 E2 to MT6620 E3 -+ * deprecate configuration used by MT6620 E2 -+ * -+ * 10 26 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check -+ * [WCXRP00000137] [MT6620 Wi-Fi] [FW] Support NIC capability query command -+ * 1) update NVRAM content template to ver 1.02 -+ * 2) add compile option for querying NIC capability (default: off) -+ * 3) modify AIS 5GHz support to run-time option, which could be turned on by registry or NVRAM setting -+ * 4) correct auto-rate compiler error under linux (treat warning as error) -+ * 5) simplify usage of NVRAM and REG_INFO_T -+ * 6) add version checking between driver and firmware -+ * -+ * 10 25 2010 cp.wu -+ * [WCXRP00000133] [MT6620 Wi-Fi] [FW][Driver] Change TX power offset band definition -+ * follow-up for CMD_5G_PWR_OFFSET_T definition change -+ * -+ * 10 05 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check -+ * 1) add NVRAM access API -+ * 2) fake scanning result when NVRAM doesn't exist and/or version mismatch. (off by compiler option) -+ * 3) add OID implementation for NVRAM read/write service -+ * -+ * 09 23 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check -+ * add skeleton for NVRAM integration -+ * -+*/ -+ -+#ifndef _CFG_WIFI_FILE_H -+#define _CFG_WIFI_FILE_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "gl_typedef.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+/* duplicated from nic_cmd_event.h to avoid header dependency */ -+typedef struct _TX_PWR_PARAM_T { -+ INT_8 cTxPwr2G4Cck; /* signed, in unit of 0.5dBm */ -+ INT_8 acReserved[3]; /* form MT6628 acReserved[0]=cTxPwr2G4Dsss */ -+ INT_8 cTxPwr2G4OFDM_BPSK; -+ INT_8 cTxPwr2G4OFDM_QPSK; -+ INT_8 cTxPwr2G4OFDM_16QAM; -+ INT_8 cTxPwr2G4OFDM_Reserved; -+ INT_8 cTxPwr2G4OFDM_48Mbps; -+ INT_8 cTxPwr2G4OFDM_54Mbps; -+ -+ INT_8 cTxPwr2G4HT20_BPSK; -+ INT_8 cTxPwr2G4HT20_QPSK; -+ INT_8 cTxPwr2G4HT20_16QAM; -+ INT_8 cTxPwr2G4HT20_MCS5; -+ INT_8 cTxPwr2G4HT20_MCS6; -+ INT_8 cTxPwr2G4HT20_MCS7; -+ -+ INT_8 cTxPwr2G4HT40_BPSK; -+ INT_8 cTxPwr2G4HT40_QPSK; -+ INT_8 cTxPwr2G4HT40_16QAM; -+ INT_8 cTxPwr2G4HT40_MCS5; -+ INT_8 cTxPwr2G4HT40_MCS6; -+ INT_8 cTxPwr2G4HT40_MCS7; -+ -+ INT_8 cTxPwr5GOFDM_BPSK; -+ INT_8 cTxPwr5GOFDM_QPSK; -+ INT_8 cTxPwr5GOFDM_16QAM; -+ INT_8 cTxPwr5GOFDM_Reserved; -+ INT_8 cTxPwr5GOFDM_48Mbps; -+ INT_8 cTxPwr5GOFDM_54Mbps; -+ -+ INT_8 cTxPwr5GHT20_BPSK; -+ INT_8 cTxPwr5GHT20_QPSK; -+ INT_8 cTxPwr5GHT20_16QAM; -+ INT_8 cTxPwr5GHT20_MCS5; -+ INT_8 cTxPwr5GHT20_MCS6; -+ INT_8 cTxPwr5GHT20_MCS7; -+ -+ INT_8 cTxPwr5GHT40_BPSK; -+ INT_8 cTxPwr5GHT40_QPSK; -+ INT_8 cTxPwr5GHT40_16QAM; -+ INT_8 cTxPwr5GHT40_MCS5; -+ INT_8 cTxPwr5GHT40_MCS6; -+ INT_8 cTxPwr5GHT40_MCS7; -+} TX_PWR_PARAM_T, *P_TX_PWR_PARAM_T; -+ -+typedef struct _PWR_5G_OFFSET_T { -+ INT_8 cOffsetBand0; /* 4.915-4.980G */ -+ INT_8 cOffsetBand1; /* 5.000-5.080G */ -+ INT_8 cOffsetBand2; /* 5.160-5.180G */ -+ INT_8 cOffsetBand3; /* 5.200-5.280G */ -+ INT_8 cOffsetBand4; /* 5.300-5.340G */ -+ INT_8 cOffsetBand5; /* 5.500-5.580G */ -+ INT_8 cOffsetBand6; /* 5.600-5.680G */ -+ INT_8 cOffsetBand7; /* 5.700-5.825G */ -+} PWR_5G_OFFSET_T, *P_PWR_5G_OFFSET_T; -+ -+typedef struct _PWR_PARAM_T { -+ UINT_32 au4Data[28]; -+ UINT_32 u4RefValue1; -+ UINT_32 u4RefValue2; -+} PWR_PARAM_T, *P_PWR_PARAM_T; -+ -+typedef struct _MT6620_CFG_PARAM_STRUCT { -+ /* 256 bytes of MP data */ -+ UINT_16 u2Part1OwnVersion; -+ UINT_16 u2Part1PeerVersion; -+ UINT_8 aucMacAddress[6]; -+ UINT_8 aucCountryCode[2]; -+ TX_PWR_PARAM_T rTxPwr; -+ UINT_8 aucEFUSE[144]; -+ UINT_8 ucTxPwrValid; -+ UINT_8 ucSupport5GBand; -+ UINT_8 fg2G4BandEdgePwrUsed; -+ INT_8 cBandEdgeMaxPwrCCK; -+ INT_8 cBandEdgeMaxPwrOFDM20; -+ INT_8 cBandEdgeMaxPwrOFDM40; -+ -+ UINT_8 ucRegChannelListMap; -+ UINT_8 ucRegChannelListIndex; -+ UINT_8 aucRegSubbandInfo[36]; -+ -+ UINT_8 aucReserved2[256 - 240]; -+ -+ /* 256 bytes of function data */ -+ UINT_16 u2Part2OwnVersion; -+ UINT_16 u2Part2PeerVersion; -+ UINT_8 uc2G4BwFixed20M; -+ UINT_8 uc5GBwFixed20M; -+ UINT_8 ucEnable5GBand; -+ UINT_8 aucPreTailReserved; -+ UINT_8 uc2GRssiCompensation; -+ UINT_8 uc5GRssiCompensation; -+ UINT_8 fgRssiCompensationValidbit; -+ UINT_8 ucRxAntennanumber; -+ UINT_8 aucTailReserved[256 - 12]; -+} MT6620_CFG_PARAM_STRUCT, *P_MT6620_CFG_PARAM_STRUCT, WIFI_CFG_PARAM_STRUCT, *P_WIFI_CFG_PARAM_STRUCT; -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+#ifndef DATA_STRUCT_INSPECTING_ASSERT -+#define DATA_STRUCT_INSPECTING_ASSERT(expr) \ -+{ \ -+ switch (0) {case 0: case (expr): default:; } \ -+} -+#endif -+ -+#define CFG_FILE_WIFI_REC_SIZE sizeof(WIFI_CFG_PARAM_STRUCT) -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+#ifndef _lint -+/* We don't have to call following function to inspect the data structure. -+ * It will check automatically while at compile time. -+ * We'll need this to guarantee the same member order in different structures -+ * to simply handling effort in some functions. -+ */ -+static inline VOID nvramOffsetCheck(VOID) -+{ -+ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(WIFI_CFG_PARAM_STRUCT, u2Part2OwnVersion) == 256); -+ -+ DATA_STRUCT_INSPECTING_ASSERT(sizeof(WIFI_CFG_PARAM_STRUCT) == 512); -+ -+ DATA_STRUCT_INSPECTING_ASSERT((OFFSET_OF(WIFI_CFG_PARAM_STRUCT, aucEFUSE) & 0x0001) == 0); -+ -+ DATA_STRUCT_INSPECTING_ASSERT((OFFSET_OF(WIFI_CFG_PARAM_STRUCT, aucRegSubbandInfo) & 0x0001) == 0); -+} -+#endif -+ -+#endif /* _CFG_WIFI_FILE_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/config.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/config.h -new file mode 100644 -index 000000000000..a52053d5752d ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/config.h -@@ -0,0 +1,1628 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/config.h#2 -+*/ -+ -+/*! \file "config.h" -+ \brief This file includes the various configurable parameters for customers -+ -+ This file ncludes the configurable parameters except the parameters indicate the turning-on/off of some features -+*/ -+ -+/* -+** Log: config.h -+ * -+ * 07 13 2012 cp.wu -+ * [WCXRP00001259] [MT6620 Wi-Fi][Driver][Firmware] Send a signal to firmware for -+ * termination after SDIO error has happened -+ * [driver domain] add force reset by host-to-device interrupt mechanism -+ * -+ * 06 13 2012 yuche.tsai -+ * NULL -+ * Update maintrunk driver. -+ * Add support for driver compose assoc request frame. -+ * -+ * 06 05 2012 tsaiyuan.hsu -+ * [WCXRP00001249] [ALPS.ICS] Daily build warning on "wlan/mgmt/swcr.c#1" -+ * resolve build waring for "WNM_UNIT_TEST not defined".. -+ * -+ * 06 04 2012 cp.wu -+ * [WCXRP00001245] [MT6620 Wi-Fi][Driver][Firmware] NPS Software Development -+ * discussed with WH, privacy bit in associate response is not necessary to be checked, -+ * and identified as association failure when mismatching with beacon/probe response -+ * -+ * 05 11 2012 cp.wu -+ * [WCXRP00001237] [MT6620 Wi-Fi][Driver] Show MAC address and MAC address source for ACS's convenience -+ * show MAC address & source while initiliazation -+ * -+ * 04 20 2012 cp.wu -+ * [WCXRP00000913] [MT6620 Wi-Fi] create repository of source code dedicated for MT6620 E6 ASIC -+ * correct macro -+ * -+ * 04 12 2012 terry.wu -+ * NULL -+ * Add AEE message support -+ * 1) Show AEE warning(red screen) if SDIO access error occurs -+ * -+ * 03 29 2012 eason.tsai -+ * [WCXRP00001216] [MT6628 Wi-Fi][Driver]add conditional define -+ * add conditional define. -+ * -+ * 03 02 2012 terry.wu -+ * NULL -+ * Enable CFG80211 Support. -+ * -+ * 01 05 2012 tsaiyuan.hsu -+ * [WCXRP00001157] [MT6620 Wi-Fi][FW][DRV] add timing measurement support for 802.11v -+ * add timing measurement support for 802.11v. -+ * -+ * 11 23 2011 cp.wu -+ * [WCXRP00001123] [MT6620 Wi-Fi][Driver] Add option to disable beacon content change detection -+ * add compile option to disable beacon content change detection. -+ * -+ * 11 18 2011 yuche.tsai -+ * NULL -+ * CONFIG P2P support RSSI query, default turned off. -+ * -+ * 10 28 2011 cp.wu -+ * [MT6620 Wi-Fi][Win32 Driver] Enable 5GHz support as default -+ * enable 5GHz as default for DaVinci trunk and V2.1 driver release . -+ * -+ * 10 18 2011 cp.wu -+ * [WCXRP00001022] [MT6628 Driver][Firmware Download] Add multi section independent download functionality -+ * surpress compiler warning for MT6628 build -+ * -+ * 10 12 2011 wh.su -+ * [WCXRP00001036] [MT6620 Wi-Fi][Driver][FW] Adding the 802.11w code for MFP -+ * adding the 802.11w related function and define . -+ * -+ * 10 03 2011 cp.wu -+ * [WCXRP00001022] [MT6628 Driver][Firmware Download] Add multi section independent download functionality -+ * enable divided firmware downloading. -+ * -+ * 10 03 2011 cp.wu -+ * [WCXRP00001022] [MT6628 Driver][Firmware Download] Add multi section independent download functionality -+ * add firmware download path in divided scatters. -+ * -+ * 10 03 2011 cp.wu -+ * [MT6628 Driver][Firmware Download] Add multi section independent download functionality -+ * add firmware downloading aggregated path. -+ * -+ * 09 28 2011 tsaiyuan.hsu -+ * [WCXRP00000900] [MT5931 Wi-Fi] Improve balance of TX and RX -+ * enlarge window size only by 4. -+ * -+ * 08 15 2011 cp.wu -+ * [WCXRP00000851] [MT6628 Wi-Fi][Driver] Add HIFSYS related definition to driver source tree -+ * reuse firmware download logic of MT6620 for MT6628. -+ * -+ * 08 15 2011 cp.wu -+ * [WCXRP00000851] [MT6628 Wi-Fi][Driver] Add HIFSYS related definition to driver source tree -+ * add MT6628-specific definitions. -+ * -+ * 08 15 2011 cp.wu -+ * [WCXRP00000913] [MT6620 Wi-Fi] create repository of source code dedicated for MT6620 E6 ASIC -+ * support to load different firmware image for E3/E4/E5 and E6 ASIC on win32 platforms. -+ * -+ * 08 12 2011 cp.wu -+ * [WCXRP00000913] [MT6620 Wi-Fi] create repository of source code dedicated for MT6620 E6 ASIC -+ * load WIFI_RAM_CODE_E6 for MT6620 E6 ASIC. -+ * -+ * 08 09 2011 chinghwa.yu -+ * [WCXRP00000063] Update BCM CoEx design and settings -+ * Add BWCS definition for MT6620. -+ * -+ * 07 28 2011 chinghwa.yu -+ * [WCXRP00000063] Update BCM CoEx design and settings -+ * Add BWCS cmd and event. -+ * -+ * 07 22 2011 jeffrey.chang -+ * [WCXRP00000864] [MT5931] Add command to adjust OSC stable time -+ * modify driver to set OSC stable time after f/w download -+ * -+ * 07 18 2011 chinghwa.yu -+ * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm -+ * Add CMD/Event for RDD and BWCS. -+ * -+ * 07 05 2011 yuche.tsai -+ * [WCXRP00000821] [Volunteer Patch][WiFi Direct][Driver] WiFi Direct Connection Speed Issue -+ * Refine compile flag. -+ * -+ * 07 05 2011 yuche.tsai -+ * [WCXRP00000821] [Volunteer Patch][WiFi Direct][Driver] WiFi Direct Connection Speed Issue -+ * Add wifi direct connection enhancement method I, II & VI. -+ * -+ * 06 24 2011 cp.wu -+ * [WCXRP00000702] [MT5931][Driver] Modify initialization sequence for E1 ASIC -+ * [WCXRP00000812] [MT6620 Wi-Fi][Driver] not show NVRAM when there is no valid MAC address in NVRAM content -+ * increase RX buffer number to have a 2:1 ping-pong ratio -+ * -+ * 06 23 2011 eddie.chen -+ * [WCXRP00000810] [MT5931][DRV/FW] Adjust TxRx Buffer number and Rx buffer size -+ * 1. Different TX RX buffer -+ * 2. Enlarge RX buffer and increase the number 8->11 -+ * 3. Separate the WINSZIE and RX buffer number -+ * 4. Fix RX maximum size in MAC -+ * -+ * 06 20 2011 terry.wu -+ * NULL -+ * Add BoW Rate Limitation. -+ * -+ * 06 17 2011 terry.wu -+ * NULL -+ * . -+ * -+ * 06 17 2011 terry.wu -+ * NULL -+ * Add BoW 11N support. -+ * -+ * 06 07 2011 yuche.tsai -+ * [WCXRP00000763] [Volunteer Patch][MT6620][Driver] RX Service Discovery Frame under AP mode Issue -+ * Add compile flag for persistent group support. -+ * -+ * 06 01 2011 cm.chang -+ * [WCXRP00000756] [MT6620 Wi-Fi][Driver] 1. AIS follow channel of BOW 2. Provide legal channel function -+ * Limit AIS to fixed channel same with BOW -+ * -+ * 04 18 2011 terry.wu -+ * [WCXRP00000660] [MT6620 Wi-Fi][Driver] Remove flag CFG_WIFI_DIRECT_MOVED -+ * Remove flag CFG_WIFI_DIRECT_MOVED. -+ * -+ * 04 14 2011 cm.chang -+ * [WCXRP00000634] [MT6620 Wi-Fi][Driver][FW] 2nd BSS will not support 40MHz bandwidth for concurrency -+ * Enable RX STBC capability -+ * -+ * 04 11 2011 george.huang -+ * [WCXRP00000628] [MT6620 Wi-Fi][FW][Driver] Modify U-APSD setting to default OFF -+ * . -+ * -+ * 04 08 2011 pat.lu -+ * [WCXRP00000623] [MT6620 Wi-Fi][Driver] use ARCH define to distinguish PC Linux driver -+ * Use CONFIG_X86 instead of PC_LINUX_DRIVER_USE option to have proper compile setting for PC Linux driver -+ * -+ * 04 08 2011 cp.wu -+ * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer -+ * 1. correction: RX aggregation is not limited to SDIO but for all host interface options -+ * 2. add forward declarations for DBG-only symbols -+ * -+ * 04 06 2011 cp.wu -+ * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer -+ * 1. do not check for pvData inside wlanNetCreate() due to it is NULL for eHPI port -+ * 2. update perm_addr as well for MAC address -+ * 3. not calling check_mem_region() anymore for eHPI -+ * 4. correct MSC_CS macro for 0-based notation -+ * -+ * 04 01 2011 cp.wu -+ * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer -+ * 1. simplify config.h due to aggregation options could be also applied for eHPI/SPI interface -+ * 2. use spin-lock instead of semaphore for protecting eHPI access because of possible access from ISR -+ * 3. request_irq() API has some changes between linux kernel 2.6.12 and 2.6.26 -+ * -+ * 03 29 2011 cp.wu -+ * [WCXRP00000598] [MT6620 Wi-Fi][Driver] Implementation of interface for communicating with -+ * user space process for RESET_START and RESET_END events -+ * implement kernel-to-userspace communication via generic netlink socket for whole-chip resetting mechanism -+ * -+ * 03 22 2011 pat.lu -+ * [WCXRP00000592] [MT6620 Wi-Fi][Driver] Support PC Linux Environment Driver Build -+ * Add a compiler option "PC_LINUX_DRIVER_USE" for building driver in PC Linux environment. -+ * -+ * 03 18 2011 wh.su -+ * [WCXRP00000530] [MT6620 Wi-Fi] [Driver] skip doing p2pRunEventAAAComplete after send assoc response Tx Done -+ * enable the Anti_piracy check at driver . -+ * -+ * 03 17 2011 tsaiyuan.hsu -+ * [WCXRP00000517] [MT6620 Wi-Fi][Driver][FW] Fine Tune Performance of Roaming -+ * enable roaming feature. -+ * -+ * 03 17 2011 chinglan.wang -+ * [WCXRP00000570] [MT6620 Wi-Fi][Driver] Add Wi-Fi Protected Setup v2.0 feature -+ * . -+ * -+ * 03 15 2011 cp.wu -+ * [WCXRP00000559] [MT6620 Wi-Fi][Driver] Combine TX/RX DMA buffers into a single one -+ * to reduce physically continuous memory consumption -+ * 1. deprecate CFG_HANDLE_IST_IN_SDIO_CALLBACK -+ * 2. Use common coalescing buffer for both TX/RX directions -+ * -+ * -+ * 03 15 2011 eddie.chen -+ * [WCXRP00000554] [MT6620 Wi-Fi][DRV] Add sw control debug counter -+ * Add sw debug counter for QM. -+ * -+ * 03 07 2011 wh.su -+ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code -+ * rename the define to anti_pviracy. -+ * -+ * 03 06 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Sync BOW Driver to latest person development branch version.. -+ * -+ * 03 02 2011 wh.su -+ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code -+ * Add security check code. -+ * -+ * 03 01 2011 george.huang -+ * [WCXRP00000495] [MT6620 Wi-Fi][FW] Support pattern filter for unwanted ARP frames -+ * Fix compile issue -+ * -+ * 02 25 2011 george.huang -+ * [WCXRP00000497] [MT6620 Wi-Fi][FW] Change default UAPSD AC assignment -+ * Assign all AC default to be U-APSD enabled. -+ * -+ * 02 14 2011 wh.su -+ * [WCXRP00000432] [MT6620 Wi-Fi][Driver] Add STA privacy check at hotspot mode -+ * Let the privacy check at hotspot mode default enable. -+ * -+ * 02 09 2011 wh.su -+ * [WCXRP00000432] [MT6620 Wi-Fi][Driver] Add STA privacy check at hotspot mode -+ * adding the code for check STA privacy bit at AP mode, . -+ * -+ * 02 08 2011 cp.wu -+ * [WCXRP00000427] [MT6620 Wi-Fi][Driver] Modify veresion information to match with release revision number -+ * change version number to v1.2.0.0 for preparing v1.2 software package release. -+ * -+ * 02 01 2011 yarco.yang -+ * [WCXRP00000417] [MT6620 Driver] Change CFG_HANDLE_IST_IN_SDIO_CALLBACK from 1 to 0 for Interoperability -+ * . -+ * -+ * 01 27 2011 tsaiyuan.hsu -+ * [WCXRP00000392] [MT6620 Wi-Fi][Driver] Add Roaming Support -+ * add roaming fsm -+ * 1. not support 11r, only use strength of signal to determine roaming. -+ * 2. not enable CFG_SUPPORT_ROAMING until completion of full test. -+ * 3. in 6620, adopt work-around to avoid sign extension problem of cck of hw -+ * 4. assume that change of link quality in smooth way. -+ * -+ * 01 19 2011 wh.su -+ * [WCXRP00000370] [MT6620 Wi-Fi][Driver] Disable Rx RDG for workaround pre-N ccmp issue -+ * Not announce support Rx RDG for wokaround pre-N ccmp construct AAD issue.. -+ * -+ * 01 15 2011 puff.wen -+ * NULL -+ * Add Stress test -+ * -+ * 01 12 2011 cp.wu -+ * [WCXRP00000356] [MT6620 Wi-Fi][Driver] fill mac header length for security frames 'cause -+ * hardware header translation needs such information -+ * fill mac header length information for 802.1x frames. -+ * -+ * 01 11 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Support BOW only for Linux. -+ * -+ * 01 10 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Enable BOW and 4 physical links. -+ * -+ * 01 08 2011 yuche.tsai -+ * [WCXRP00000345] [MT6620][Volunteer Patch] P2P may issue a SSID specified scan request, -+ * but the SSID length is still invalid. -+ * Modify CFG_SLT_SUPPORT default value. -+ * -+ * 01 08 2011 yuche.tsai -+ * [WCXRP00000341] [MT6620][SLT] Create Branch for SLT SW. -+ * Update configure flag. -+ * -+ * 12 28 2010 cp.wu -+ * [WCXRP00000269] [MT6620 Wi-Fi][Driver][Firmware] Prepare for v1.1 branch release -+ * report EEPROM used flag via NIC_CAPABILITY -+ * -+ * 12 28 2010 cp.wu -+ * [WCXRP00000269] [MT6620 Wi-Fi][Driver][Firmware] Prepare for v1.1 branch release -+ * integrate with 'EEPROM used' flag for reporting correct capability to Engineer Mode/META and other tools -+ * -+ * 12 15 2010 yuche.tsai -+ * NULL -+ * Update SLT Descriptor number configure in driver. -+ * -+ * 12 13 2010 chinglan.wang -+ * NULL -+ * Add WPS 1.0 feature flag to enable the WPS 1.0 function. -+ * -+ * 11 23 2010 george.huang -+ * [WCXRP00000127] [MT6620 Wi-Fi][Driver] Add a registry to disable Beacon Timeout function for SQA test by using E1 EVB -+ * Enable PM function by default -+ * -+ * 11 15 2010 wh.su -+ * [WCXRP00000171] [MT6620 Wi-Fi][Driver] Add message check code same behavior as mt5921 -+ * use config.mk WAPI config define. -+ * -+ * 11 08 2010 wh.su -+ * [WCXRP00000171] [MT6620 Wi-Fi][Driver] Add message check code same behavior as mt5921 -+ * use the config.mk define. -+ * -+ * 11 01 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check -+ * [WCXRP00000150] [MT6620 Wi-Fi][Driver] Add implementation for querying current TX rate from firmware auto rate module -+ * 1) Query link speed (TX rate) from firmware directly with buffering mechanism to reduce overhead -+ * 2) Remove CNM CH-RECOVER event handling -+ * 3) cfg read/write API renamed with kal prefix for unified naming rules. -+ * -+ * 11 01 2010 yarco.yang -+ * [WCXRP00000149] [MT6620 WI-Fi][Driver]Fine tune performance on MT6516 platform -+ * Add code to run WlanIST in SDIO callback. -+ * -+ * 10 26 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check -+ * [WCXRP00000137] [MT6620 Wi-Fi] [FW] Support NIC capability query command -+ * 1) update NVRAM content template to ver 1.02 -+ * 2) add compile option for querying NIC capability (default: off) -+ * 3) modify AIS 5GHz support to run-time option, which could be turned on by registry or NVRAM setting -+ * 4) correct auto-rate compiler error under linux (treat warning as error) -+ * 5) simplify usage of NVRAM and REG_INFO_T -+ * 6) add version checking between driver and firmware -+ * -+ * 10 25 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check -+ * add option for enable/disable TX PWR gain adjustment (default: off) -+ * -+ * 10 20 2010 wh.su -+ * [WCXRP00000067] [MT6620 Wi-Fi][Driver] Support the android+ WAPI function -+ * enable the WAPI compiling flag as default -+ * -+ * 10 19 2010 cp.wu -+ * [WCXRP00000122] [MT6620 Wi-Fi][Driver] Preparation for YuSu source tree integration -+ * remove HIF_SDIO_ONE flags because the settings could be merged for runtime detection instead of compile-time. -+ * -+ * 10 18 2010 cp.wu -+ * [WCXRP00000117] [MT6620 Wi-Fi][Driver] Add logic for suspending driver when MT6620 is not responding anymore -+ * 1. when wlanAdapterStop() failed to send POWER CTRL command to firmware, do not poll for ready bit dis-assertion -+ * 2. shorten polling count for shorter response time -+ * 3. if bad I/O operation is detected during TX resource polling, then further operation is aborted as well -+ * -+ * 10 18 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check -+ * [WCXRP00000086] [MT6620 Wi-Fi][Driver] The mac address is all zero at android -+ * complete implementation of Android NVRAM access -+ * -+ * 10 14 2010 wh.su -+ * [WCXRP00000102] [MT6620 Wi-Fi] [FW] Add a compiling flag and code for support Direct GO at Android -+ * Add a define CFG_TEST_ANDROID_DIRECT_GO compiling flag -+ * -+ * 10 08 2010 cm.chang -+ * NULL -+ * Remove unused compiling flags (TX_RDG and TX_SGI) -+ * -+ * 10 07 2010 cp.wu -+ * [WCXRP00000083] [MT5931][Driver][FW] Add necessary logic for MT5931 first connection -+ * add firmware download for MT5931. -+ * -+ * 10 05 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check -+ * load manufacture data when CFG_SUPPORT_NVRAM is set to 1 -+ * -+ * 10 05 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check -+ * 1) add NVRAM access API -+ * 2) fake scanning result when NVRAM doesn't exist and/or version mismatch. (off by compiler option) -+ * 3) add OID implementation for NVRAM read/write service -+ * -+ * 10 05 2010 yarco.yang -+ * [WCXRP00000082] [MT6620 Wi-Fi][Driver]High throughput performance tuning -+ * Change CFG_IST_LOOP_COUNT from 2 to 1 to reduce unnecessary SDIO bus access -+ * -+ * 09 24 2010 cp.wu -+ * [WCXRP00000057] [MT6620 Wi-Fi][Driver] Modify online scan to a run-time switchable feature -+ * Modify online scan as a run-time adjustable option (for Windows, in registry) -+ * -+ * 09 23 2010 cp.wu -+ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning -+ * eliminate reference of CFG_RESPONSE_MAX_PKT_SIZE -+ * -+ * 09 20 2010 cm.chang -+ * NULL -+ * Disable RX STBC by BB HEC based on MT6620E1_PHY_BUG v05.docx -+ * -+ * 09 17 2010 chinglan.wang -+ * NULL -+ * Add performance test option -+ * -+ * 09 10 2010 chinglan.wang -+ * NULL -+ * Modify for Software Migration Phase 2.10 for E2 FPGA -+ * -+ * 09 07 2010 yuche.tsai -+ * NULL -+ * Add a CFG for max common IE buffer size. -+ * -+ * 09 01 2010 cp.wu -+ * NULL -+ * restore configuration as before. -+ * -+ * 09 01 2010 cp.wu -+ * NULL -+ * HIFSYS Clock Source Workaround -+ * -+ * 08 31 2010 kevin.huang -+ * NULL -+ * Use LINK LIST operation to process SCAN result -+ * -+ * 08 30 2010 chinglan.wang -+ * NULL -+ * Enable the MT6620_FPGA_BWCS value. -+ * -+ * 08 30 2010 chinglan.wang -+ * NULL -+ * Disable the FW encryption. -+ * -+ * 08 27 2010 chinglan.wang -+ * NULL -+ * Update configuration for MT6620_E1_PRE_ALPHA_1832_0827_2010 -+ * -+ * 08 26 2010 yuche.tsai -+ * NULL -+ * Add AT GO test configure mode under WinXP. -+ * Please enable 1. CFG_ENABLE_WIFI_DIRECT, 2. CFG_TEST_WIFI_DIRECT_GO, 3. CFG_SUPPORT_AAA -+ * -+ * 08 25 2010 cp.wu -+ * NULL -+ * add option for enabling AIS 5GHz scan -+ * -+ * 08 25 2010 george.huang -+ * NULL -+ * update OID/ registry control path for PM related settings -+ * -+ * 08 24 2010 cp.wu -+ * NULL -+ * 1) initialize variable for enabling short premable/short time slot. -+ * 2) add compile option for disabling online scan -+ * -+ * 08 24 2010 cm.chang -+ * NULL -+ * Support RLM initail channel of Ad-hoc, P2P and BOW -+ * -+ * 08 23 2010 cp.wu -+ * NULL -+ * revise constant definitions to be matched with implementation (original cmd-event definition is deprecated) -+ * -+ * 08 23 2010 chinghwa.yu -+ * NULL -+ * Disable BOW Test. -+ * -+ * 08 23 2010 jeffrey.chang -+ * NULL -+ * fix config.h typo -+ * -+ * 08 23 2010 chinghwa.yu -+ * NULL -+ * Update for BOW. -+ * -+ * 08 21 2010 jeffrey.chang -+ * NULL -+ * 1) add sdio two setting -+ * 2) bug fix of sdio glue -+ * -+ * 08 09 2010 wh.su -+ * NULL -+ * let the firmware download default enabled. -+ * -+ * 08 07 2010 wh.su -+ * NULL -+ * adding the privacy related code for P2P network -+ * -+ * 08 05 2010 yuche.tsai -+ * NULL -+ * Add a configure flag for P2P unitest. -+ * -+ * 07 23 2010 cp.wu -+ * -+ * 1) re-enable AIS-FSM beacon timeout handling. -+ * 2) scan done API revised -+ * -+ * 07 23 2010 cp.wu -+ * -+ * 1) enable Ad-Hoc -+ * 2) disable beacon timeout handling temporally due to unexpected beacon timeout event. -+ * -+ * 07 19 2010 wh.su -+ * -+ * update for security supporting. -+ * -+ * 07 19 2010 yuche.tsai -+ * -+ * Add for SLT support. -+ * -+ * 07 16 2010 cp.wu -+ * -+ * remove work-around in case SCN is not available. -+ * -+ * 07 14 2010 yarco.yang -+ * -+ * 1. Remove CFG_MQM_MIGRATION -+ * 2. Add CMD_UPDATE_WMM_PARMS command -+ * -+ * 07 13 2010 cp.wu -+ * -+ * 1) MMPDUs are now sent to MT6620 by CMD queue for keeping strict order of 1X/MMPDU/CMD packets -+ * 2) integrate with qmGetFrameAction() for deciding which MMPDU/1X could pass checking for sending -+ * 2) enhance CMD_INFO_T descriptor number from 10 to 32 to avoid descriptor -+ * underflow under concurrent network operation -+ * -+ * 07 09 2010 yarco.yang -+ * -+ * [MT6620 and MT5931] SW Migration: Add ADDBA support -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 07 08 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * take use of RLM module for parsing/generating HT IEs for 11n capability -+ * -+ * 07 07 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * for first connection, if connecting failed do not enter into scan state. -+ * -+ * 06 25 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * modify Beacon/ProbeResp to complete parsing, -+ * because host software has looser memory usage restriction -+ * -+ * 06 23 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) add SCN compilation option. -+ * 2) when SCN is not turned on, BSSID_SCAN will generate a fake entry for 1st connection -+ * -+ * 06 22 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) add command warpper for STA-REC/BSS-INFO sync. -+ * 2) enhance command packet sending procedure for non-oid part -+ * 3) add command packet definitions for STA-REC/BSS-INFO sync. -+ * -+ * 06 21 2010 wh.su -+ * [WPD00003840][MT6620 5931] Security migration -+ * set default compiling flag for security disable. -+ * -+ * 06 21 2010 yarco.yang -+ * [WPD00003837][MT6620]Data Path Refine -+ * Support CFG_MQM_MIGRATION flag -+ * -+ * 06 21 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * enable RX management frame handling. -+ * -+ * 06 21 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add scan_fsm into building. -+ * -+ * 06 18 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Provide cnmMgtPktAlloc() and alloc/free function of msg/buf -+ * -+ * 06 15 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add scan.c. -+ * -+ * 06 14 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add management dispatching function table. -+ * -+ * 06 11 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * auth.c is migrated. -+ * -+ * 06 11 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add bss.c. -+ * -+ * 06 11 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) migrate assoc.c. -+ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness -+ * 3) add configuration options for CNM_MEM and RSN modules -+ * 4) add data path for management frames -+ * 5) eliminate rPacketInfo of MSDU_INFO_T -+ * -+ * 06 10 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) eliminate CFG_CMD_EVENT_VERSION_0_9 -+ * 2) when disconnected, indicate nic directly (no event is needed) -+ * -+ * 06 07 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add aa_fsm.h, ais_fsm.h, bss.h, mib.h and scan.h. -+ * -+ * 06 07 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * merge wlan_def.h. -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 05 31 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * add config option for cfg80211. -+ * -+ * 05 26 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * set ATIMwindow default value to zero. -+ * -+ * 05 21 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * add option for FPGA_BWCS & FPGA_V5 -+ * -+ * 05 20 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) integrate OID_GEN_NETWORK_LAYER_ADDRESSES with CMD_ID_SET_IP_ADDRESS -+ * 2) buffer statistics data for 2 seconds -+ * 3) use default value for adhoc parameters instead of 0 -+ * -+ * 05 17 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) enable CMD/EVENT ver 0.9 definition. -+ * 2) abandon use of ENUM_MEDIA_STATE -+ * -+ * 05 17 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * add CFG_STARTUP_DEBUG for debugging starting up issue. -+ * -+ * 05 17 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * add basic handling framework for wireless extension ioctls. -+ * -+ * 05 11 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * change firmware name to WIFI_RAM_CODE. -+ * -+ * 05 07 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * disable bt-over-wifi configuration, turn it on after firmware finished implementation -+ * -+ * 04 27 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * add multiple physical link support -+ * -+ * 04 23 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * surpress compiler warning -+ * -+ * 04 22 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * re-enable power management -+ * -+ * 04 22 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * -+ * 1) modify rx path code for supporting Wi-Fi direct -+ * 2) modify config.h since Linux dont need to consider retaining packet -+ * -+ * 04 22 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * enable TCP/IP checksum offloading by default. -+ * -+ * 04 19 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * set CFG_ENABLE_FULL_PM to 1 as default to -+ * 1) acquire own before hardware access -+ * 2) set own back after hardware access -+ * -+ * 04 15 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * change firmware name -+ * -+ * 04 07 2010 cp.wu -+ * [WPD00003827][MT6620 Wi-Fi] Chariot fail and following ping fail, no pkt send from driver -+ * disable RX-enhanced response temporally, it seems the CQ is not resolved yet. -+ * -+ * 04 06 2010 cp.wu -+ * [WPD00003827][MT6620 Wi-Fi] Chariot fail and following ping fail, no pkt send from driver -+ * re-enable RX enhanced mode as WPD00003827 is resolved. -+ * -+ * 04 06 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * turn off RX_ENHANCE mode by default. -+ * -+ * 04 06 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) eliminate unused definitions -+ * * 2) ready bit will be polled for limited iteration -+ * -+ * 04 02 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * firmware download: Linux uses different firmware path -+ * -+ * 04 01 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * change to use WIFI_TCM_ALWAYS_ON as firmware image -+ * -+ * 03 31 2010 wh.su -+ * [WPD00003816][MT6620 Wi-Fi] Adding the security support -+ * modify the wapi related code for new driver's design. -+ * -+ * 03 26 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * add a temporary flag for integration with CMD/EVENT v0.9. -+ * -+ * 03 25 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * firmware download load address & start address are now configured from config.h -+ * * due to the different configurations on FPGA and ASIC -+ * -+ * 03 24 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * add options for full PM support. -+ * -+ * 03 24 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * [WPD00003826] Initial import for Linux port -+ * initial import for Linux port -+ * -+ * 03 24 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * [WPD00003826] Initial import for Linux port -+ * initial import for Linux port -+ * -+ * 03 24 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * initial import for Linux port -+ * -+ * 03 16 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * turn on FW-DOWNLOAD as default for release. -+ * -+ * 03 16 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * build up basic data structure and definitions to support BT-over-WiFi -+ * -+ * 03 12 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * add two option for ACK and ENCRYPTION for firmware download -+ * -+ * 03 11 2010 cp.wu -+ * [WPD00003821][BUG] Host driver stops processing RX packets from HIF RX0 -+ * add RX starvation warning debug message controlled by CFG_HIF_RX_STARVATION_WARNING -+ * -+ * 03 10 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * code clean: removing unused variables and structure definitions -+ * -+ * 03 05 2010 cp.wu -+ * [WPD00003821][BUG] Host driver stops processing RX packets from HIF RX0 -+ * change CFG_NUM_OF_QM_RX_PKT_NUM to 120 -+ * -+ * 03 04 2010 cp.wu -+ * [WPD00003821][BUG] Host driver stops processing RX packets from HIF RX0 -+ * . -+ * -+ * 03 04 2010 cp.wu -+ * [WPD00003821][BUG] Host driver stops processing RX packets from HIF RX0 -+ * increase RX buffer number to avoid RX buffer starvation. -+ * -+ * 02 24 2010 tehuang.liu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * Changed the number of STA_RECs to 20 -+ * -+ * 02 23 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * add checksum offloading support. -+ * -+ * 02 11 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1. add logic for firmware download -+ * * 2. firmware image filename and start/load address are now retrieved from registry -+ * -+ * 02 08 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * prepare for implementing fw download logic -+ * -+ * 12 30 2009 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) According to CMD/EVENT documentation v0.8, -+ * * OID_CUSTOM_TEST_RX_STATUS & OID_CUSTOM_TEST_TX_STATUS is no longer used, -+ * * and result is retrieved by get ATInfo instead -+ * * 2) add 4 counter for recording aggregation statistics -+** \main\maintrunk.MT6620WiFiDriver_Prj\25 2009-12-16 22:12:28 GMT mtk02752 -+** enable interrupt enhanced response, TX/RX Aggregation as default -+** \main\maintrunk.MT6620WiFiDriver_Prj\24 2009-12-10 16:38:43 GMT mtk02752 -+** eliminate compile options which are obsolete or for emulation purpose -+** \main\maintrunk.MT6620WiFiDriver_Prj\23 2009-12-09 13:56:26 GMT MTK02468 -+** Added RX buffer reordering configurations -+** \main\maintrunk.MT6620WiFiDriver_Prj\22 2009-12-04 12:09:09 GMT mtk02752 -+** once enhanced intr/rx response is taken, RX must be access in aggregated basis -+** \main\maintrunk.MT6620WiFiDriver_Prj\21 2009-11-23 17:54:50 GMT mtk02752 -+** correct a typo -+** \main\maintrunk.MT6620WiFiDriver_Prj\20 2009-11-17 22:40:47 GMT mtk01084 -+** add defines -+** \main\maintrunk.MT6620WiFiDriver_Prj\19 2009-11-17 17:33:37 GMT mtk02752 -+** add coalescing buffer definition for SD1_SD3_DATAPATH_INTEGRATION -+** \main\maintrunk.MT6620WiFiDriver_Prj\18 2009-11-16 20:32:40 GMT mtk02752 -+** add CFG_TX_MAX_PKT_NUM for limiting queued TX packet -+** \main\maintrunk.MT6620WiFiDriver_Prj\17 2009-11-16 13:34:44 GMT mtk02752 -+** add SD1_SD3_DATAPATH_INTEGRATION define for source control -+** \main\maintrunk.MT6620WiFiDriver_Prj\16 2009-11-13 13:54:11 GMT mtk01084 -+** enable INT enhance mode by default -+** \main\maintrunk.MT6620WiFiDriver_Prj\15 2009-10-30 18:17:14 GMT mtk01084 -+** add new define -+** \main\maintrunk.MT6620WiFiDriver_Prj\14 2009-10-29 19:47:36 GMT mtk01084 -+** not use HIF loopback mode -+** \main\maintrunk.MT6620WiFiDriver_Prj\13 2009-10-13 21:58:33 GMT mtk01084 -+** update for new macro define -+** \main\maintrunk.MT6620WiFiDriver_Prj\12 2009-09-09 17:26:08 GMT mtk01084 -+** add CFG_TEST_WITH_MT5921 -+** \main\maintrunk.MT6620WiFiDriver_Prj\11 2009-05-18 21:02:30 GMT mtk01426 -+** Update CFG_RX_COALESCING_BUFFER_SIZE -+** \main\maintrunk.MT6620WiFiDriver_Prj\10 2009-04-21 09:35:51 GMT mtk01461 -+** Add CFG_TX_DBG_MGT_BUF to debug MGMT Buffer depth -+** \main\maintrunk.MT6620WiFiDriver_Prj\9 2009-04-14 15:52:21 GMT mtk01426 -+** Add OOB_DATA_PRE_FIXED_LEN define -+** \main\maintrunk.MT6620WiFiDriver_Prj\8 2009-04-08 16:51:08 GMT mtk01084 -+** update for FW download part -+** \main\maintrunk.MT6620WiFiDriver_Prj\7 2009-04-01 10:33:37 GMT mtk01461 -+** Add SW pre test flag CFG_HIF_LOOPBACK_PRETEST -+** \main\maintrunk.MT6620WiFiDriver_Prj\6 2009-03-23 00:29:18 GMT mtk01461 -+** Fix CFG_COALESCING_BUFFER_SIZE if enable the CFG_TX_FRAGMENT -+** \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-03-18 20:58:34 GMT mtk01426 -+** Add CFG_HIF_LOOPBACK and CFG_SDIO_RX_ENHANCE -+** \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-03-17 20:17:36 GMT mtk01426 -+** Add CMD/Response related configure -+** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-03-16 09:08:21 GMT mtk01461 -+** Update TX PATH API -+** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 20:11:21 GMT mtk01426 -+** Init for develop -+** -+*/ -+ -+#ifndef _CONFIG_H -+#define _CONFIG_H -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+#ifdef MT6620 -+#undef MT6620 -+#endif -+ -+#ifndef MT6628 -+#define MT6628 -+#endif -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+/* 2 Flags for OS capability */ -+ -+#define MTK_WCN_SINGLE_MODULE 0 /* 1: without WMT */ -+ -+#ifdef LINUX -+#ifdef CONFIG_X86 -+#define MTK_WCN_HIF_SDIO 0 -+#else -+#define MTK_WCN_HIF_SDIO 0 /* samp */ -+#endif -+#else -+#define MTK_WCN_HIF_SDIO 0 -+#endif -+ -+#if (CFG_SUPPORT_AEE == 1) -+#define CFG_ENABLE_AEE_MSG 1 -+#else -+#define CFG_ENABLE_AEE_MSG 0 -+#endif -+ -+#if CFG_ENABLE_AEE_MSG -+#include -+#endif -+ -+/* 2 Flags for Driver Features */ -+#define CFG_TX_FRAGMENT 1 /*!< 1: Enable TX fragmentation -+ 0: Disable */ -+#define CFG_SUPPORT_PERFORMANCE_TEST 0 /*Only for performance Test */ -+ -+#define CFG_COUNTRY_CODE NULL /* "US" */ -+ -+#ifndef LINUX -+#define CFG_FW_FILENAME L"WIFI_RAM_CODE" -+#define CFG_FW_FILENAME_E6 L"WIFI_RAM_CODE_E6" -+#else -+#define CFG_FW_FILENAME "WIFI_RAM_CODE" -+#endif -+#ifndef LINUX -+#define CFG_SUPPORT_CFG_FILE 0 -+#else -+#define CFG_SUPPORT_CFG_FILE 1 -+#endif -+ -+#define CFG_SUPPORT_CE_FCC_TXPWR_LIMIT 0 /* Support CE FCC Tx Power limit */ -+ -+#define CFG_SUPPORT_802_11D 1 /*!< 1(default): Enable 802.11d -+ 0: Disable */ -+ -+#define CFG_SUPPORT_RRM 0 /* Radio Reasource Measurement (802.11k) */ -+#define CFG_SUPPORT_DFS 1 /* DFS (802.11h) */ -+ -+#if (CFG_SUPPORT_DFS == 1) /* Add by Enlai */ -+#define CFG_SUPPORT_QUIET 1 /* Quiet (802.11h) */ -+#define CFG_SUPPORT_SPEC_MGMT 1 /* Spectrum Management (802.11h): TPC and DFS */ -+#else -+#define CFG_SUPPORT_QUIET 0 /* Quiet (802.11h) */ -+#define CFG_SUPPORT_SPEC_MGMT 0 /* Spectrum Management (802.11h): TPC and DFS */ -+#endif -+ -+#define CFG_SUPPORT_RX_RDG 0 /* 11n feature. RX RDG capability */ -+#define CFG_SUPPORT_MFB 0 /* 802.11n MCS Feedback responder */ -+#define CFG_SUPPORT_RX_STBC 1 /* 802.11n RX STBC (1SS) */ -+#define CFG_SUPPORT_RX_SGI 1 /* 802.11n RX short GI for both 20M and 40M BW */ -+#define CFG_SUPPORT_RX_HT_GF 1 /* 802.11n RX HT green-field capability */ -+ -+#define CFG_SUPPORT_ROAMING_ENC 0 /* enahnced roaming */ -+ -+#define CFG_SUPPORT_TDLS 1 /* IEEE802.11z TDLS */ -+#define CFG_SUPPORT_TDLS_DBG 0 /* TDLS debug */ -+#define CFG_SUPPORT_STATISTICS 1 -+#define CFG_SUPPORT_DBG_POWERMODE 1 /* for debugging power always active mode */ -+ -+#define CFG_SUPPORT_GSCN 1 -+ -+#define CFG_SUPPORT_TXR_ENC 0 /* enhanced tx rate switch */ -+ -+#define CFG_SUPPORT_PERSIST_NETDEV 0 /* create NETDEV when system bootup */ -+ -+#define CFG_FORCE_USE_20BW 1 -+/*------------------------------------------------------------------------------ -+ * SLT Option -+ *------------------------------------------------------------------------------ -+ */ -+#define CFG_SLT_SUPPORT 0 -+ -+#define MTK_AUTO_CHANNEL_SEL_SUPPORT_ENABLE 0 -+ -+#if defined(MTK_AUTO_CHANNEL_SEL_SUPPORT_ENABLE) -+#define CFG_AUTO_CHANNEL_SEL_SUPPORT 1 -+#else -+#define CFG_AUTO_CHANNEL_SEL_SUPPORT 0 -+#endif -+ -+#ifdef NDIS60_MINIPORT -+#define CFG_NATIVE_802_11 1 -+ -+#define CFG_TX_MAX_PKT_SIZE 2304 -+#define CFG_TCP_IP_CHKSUM_OFFLOAD_NDIS_60 0 /* !< 1: Enable TCP/IP header checksum offload -+ 0: Disable */ -+#define CFG_TCP_IP_CHKSUM_OFFLOAD 0 -+#define CFG_WHQL_DOT11_STATISTICS 1 -+#define CFG_WHQL_ADD_REMOVE_KEY 1 -+#define CFG_WHQL_CUSTOM_IE 1 -+#define CFG_WHQL_SAFE_MODE_ENABLED 1 -+ -+#else -+#define CFG_TCP_IP_CHKSUM_OFFLOAD 1 /* !< 1: Enable TCP/IP header checksum offload -+ 0: Disable */ -+#define CFG_TCP_IP_CHKSUM_OFFLOAD_NDIS_60 0 -+#define CFG_TX_MAX_PKT_SIZE 1600 -+#define CFG_NATIVE_802_11 0 -+#endif -+ -+/* 2 Flags for Driver Parameters */ -+/*------------------------------------------------------------------------------ -+ * Flags for EHPI Interface in Colibri Platform -+ *------------------------------------------------------------------------------ -+ */ -+#define CFG_EHPI_FASTER_BUS_TIMING 0 /*!< 1: Do workaround for faster bus timing -+ 0(default): Disable */ -+ -+/*------------------------------------------------------------------------------ -+ * Flags for HIFSYS Interface -+ *------------------------------------------------------------------------------ -+ */ -+#ifdef _lint -+#define _HIF_SDIO 0 /* samp */ -+#endif -+ -+#define CFG_SDIO_INTR_ENHANCE 1 /*!< 1(default): Enable SDIO ISR & TX/RX status enhance mode -+ 0: Disable */ -+#define CFG_SDIO_RX_ENHANCE 0 /*!< 1(default): Enable SDIO ISR & TX/RX status enhance mode -+ 0: Disable */ -+#define CFG_SDIO_TX_AGG 1 /*!< 1: Enable SDIO TX enhance -+ mode(Multiple frames in single BLOCK CMD) -+ 0(default): Disable */ -+ -+#define CFG_SDIO_RX_AGG 1 /*!< 1: Enable SDIO RX enhance -+ mode(Multiple frames in single BLOCK CMD) -+ 0(default): Disable */ -+ -+#if (CFG_SDIO_RX_AGG == 1) && (CFG_SDIO_INTR_ENHANCE == 0) -+#error "CFG_SDIO_INTR_ENHANCE should be 1 once CFG_SDIO_RX_AGG equals to 1" -+#elif (CFG_SDIO_INTR_ENHANCE == 1 || CFG_SDIO_RX_ENHANCE == 1) && (CFG_SDIO_RX_AGG == 0) -+#error "CFG_SDIO_RX_AGG should be 1 once CFG_SDIO_INTR_ENHANCE and/or CFG_SDIO_RX_ENHANCE equals to 1" -+#endif -+ -+#define CFG_SDIO_MAX_RX_AGG_NUM 0 /*!< 1: Setting the maximum RX aggregation number -+ 0(default): no limited */ -+ -+#ifdef WINDOWS_CE -+#define CFG_SDIO_PATHRU_MODE 1 /*!< 1: Support pass through (PATHRU) mode -+ 0: Disable */ -+#else -+#define CFG_SDIO_PATHRU_MODE 0 /*!< 0: Always disable if WINDOWS_CE is not defined */ -+#endif -+ -+#define CFG_MAX_RX_ENHANCE_LOOP_COUNT 3 -+ -+/*------------------------------------------------------------------------------ -+ * Flags and Parameters for Integration -+ *------------------------------------------------------------------------------ -+ */ -+#if defined(MT6620) -+#define MT6620_FPGA_BWCS 0 -+#define MT6620_FPGA_V5 0 -+ -+#if (MT6620_FPGA_BWCS == 1) && (MT6620_FPGA_V5 == 1) -+#error -+#endif -+ -+#if (MTK_WCN_HIF_SDIO == 1) -+#define CFG_MULTI_ECOVER_SUPPORT 1 -+#elif !defined(LINUX) -+#define CFG_MULTI_ECOVER_SUPPORT 1 -+#else -+#define CFG_MULTI_ECOVER_SUPPORT 0 -+#endif -+ -+#define CFG_ENABLE_CAL_LOG 0 -+#define CFG_REPORT_RFBB_VERSION 0 -+ -+#elif defined(MT6628) -+ -+#define CFG_MULTI_ECOVER_SUPPORT 0 -+ -+#define CFG_ENABLE_CAL_LOG 1 -+#define CFG_REPORT_RFBB_VERSION 1 -+ -+#endif -+ -+#define CFG_CHIP_RESET_SUPPORT 1 -+ -+#if defined(MT6628) -+#define CFG_EMBED_FIRMWARE_BUILD_DATE_CODE 1 -+#endif -+ -+/*------------------------------------------------------------------------------ -+ * Flags for workaround -+ *------------------------------------------------------------------------------ -+ */ -+#if defined(MT6620) && (MT6620_FPGA_BWCS == 0) && (MT6620_FPGA_V5 == 0) -+#define MT6620_E1_ASIC_HIFSYS_WORKAROUND 0 -+#else -+#define MT6620_E1_ASIC_HIFSYS_WORKAROUND 0 -+#endif -+ -+/* SPM issue: suspend current is higher than deep idle */ -+#define CFG_SPM_WORKAROUND_FOR_HOTSPOT 1 -+ -+/*------------------------------------------------------------------------------ -+ * Flags for driver version -+ *------------------------------------------------------------------------------ -+ */ -+#define CFG_DRV_OWN_VERSION \ -+ ((UINT_16)((NIC_DRIVER_MAJOR_VERSION << 8) | (NIC_DRIVER_MINOR_VERSION))) -+#define CFG_DRV_PEER_VERSION ((UINT_16)0x0000) -+ -+/*------------------------------------------------------------------------------ -+ * Flags for TX path which are OS dependent -+ *------------------------------------------------------------------------------ -+ */ -+/*! NOTE(Kevin): If the Network buffer is non-scatter-gather like structure(without -+ * NETIF_F_FRAGLIST in LINUX), then we can set CFG_TX_BUFFER_IS_SCATTER_LIST to "0" -+ * for zero copy TX packets. -+ * For scatter-gather like structure, we set "1", driver will do copy frame to -+ * internal coalescing buffer before write it to FIFO. -+ */ -+#if defined(LINUX) -+#define CFG_TX_BUFFER_IS_SCATTER_LIST 1 /*!< 1: Do frame copy before write to TX FIFO. -+ Used when Network buffer is scatter-gather. -+ 0(default): Do not copy frame */ -+#else /* WINDOWS/WINCE */ -+#define CFG_TX_BUFFER_IS_SCATTER_LIST 1 -+#endif /* LINUX */ -+ -+#if CFG_SDIO_TX_AGG || CFG_TX_BUFFER_IS_SCATTER_LIST -+#define CFG_COALESCING_BUFFER_SIZE (CFG_TX_MAX_PKT_SIZE * NIC_TX_BUFF_SUM) -+#else -+#define CFG_COALESCING_BUFFER_SIZE (CFG_TX_MAX_PKT_SIZE) -+#endif /* CFG_SDIO_TX_AGG || CFG_TX_BUFFER_IS_SCATTER_LIST */ -+ -+/*------------------------------------------------------------------------------ -+ * Flags and Parameters for TX path -+ *------------------------------------------------------------------------------ -+ */ -+ -+/*! Maximum number of SW TX packet queue */ -+#define CFG_TX_MAX_PKT_NUM 512 /* 256 must >= CFG_TX_STOP_NETIF_PER_QUEUE_THRESHOLD * 2; -+ or wmm will fail when queue is full */ -+ -+/*! Maximum number of SW TX CMD packet buffer */ -+#define CFG_TX_MAX_CMD_PKT_NUM 32 -+ -+/*! Maximum number of associated STAs */ -+#define CFG_NUM_OF_STA_RECORD 20 -+ -+/*------------------------------------------------------------------------------ -+ * Flags and Parameters for RX path -+ *------------------------------------------------------------------------------ -+ */ -+ -+/*! Max. descriptor number - sync. with firmware */ -+#if CFG_SLT_SUPPORT -+#define CFG_NUM_OF_RX0_HIF_DESC 42 -+#else -+#define CFG_NUM_OF_RX0_HIF_DESC 16 -+#endif -+#define CFG_NUM_OF_RX1_HIF_DESC 2 -+ -+/*! Max. buffer hold by QM */ -+#define CFG_NUM_OF_QM_RX_PKT_NUM 120 -+ -+/*! Maximum number of SW RX packet buffer */ -+#define CFG_RX_MAX_PKT_NUM ((CFG_NUM_OF_RX0_HIF_DESC + CFG_NUM_OF_RX1_HIF_DESC) * 3 \ -+ + CFG_NUM_OF_QM_RX_PKT_NUM) -+ -+#define CFG_RX_REORDER_Q_THRESHOLD 8 -+ -+#ifndef LINUX -+#define CFG_RX_RETAINED_PKT_THRESHOLD \ -+ (CFG_NUM_OF_RX0_HIF_DESC + CFG_NUM_OF_RX1_HIF_DESC + CFG_NUM_OF_QM_RX_PKT_NUM) -+#else -+#define CFG_RX_RETAINED_PKT_THRESHOLD 0 -+#endif -+ -+/*! Maximum RX packet size, if exceed this value, drop incoming packet */ -+/* 7.2.3 Maganement frames */ -+#define CFG_RX_MAX_PKT_SIZE (28 + 2312 + 12 /*HIF_RX_HEADER_T*/) /* TODO: it should be -+ 4096 under emulation mode */ -+ -+/*! Minimum RX packet size, if lower than this value, drop incoming packet */ -+#define CFG_RX_MIN_PKT_SIZE 10 /*!< 802.11 Control Frame is 10 bytes */ -+ -+#if CFG_SDIO_RX_AGG -+ /* extra size for CS_STATUS and enhanced response */ -+#define CFG_RX_COALESCING_BUFFER_SIZE ((CFG_NUM_OF_RX0_HIF_DESC + 1) \ -+ * CFG_RX_MAX_PKT_SIZE) -+#else -+#define CFG_RX_COALESCING_BUFFER_SIZE (CFG_RX_MAX_PKT_SIZE) -+#endif -+ -+/*! RX BA capability */ -+#define CFG_NUM_OF_RX_BA_AGREEMENTS 8 -+#define CFG_RX_BA_MAX_WINSIZE 16 -+#define CFG_RX_BA_INC_SIZE 4 -+#define CFG_RX_MAX_BA_TID_NUM 8 -+#define CFG_RX_REORDERING_ENABLED 1 -+ -+/*------------------------------------------------------------------------------ -+ * Flags and Parameters for CMD/RESPONSE -+ *------------------------------------------------------------------------------ -+ */ -+#define CFG_RESPONSE_POLLING_TIMEOUT 512 -+ -+/*------------------------------------------------------------------------------ -+ * Flags and Parameters for Protocol Stack -+ *------------------------------------------------------------------------------ -+ */ -+/*! Maximum number of BSS in the SCAN list */ -+#define CFG_MAX_NUM_BSS_LIST 64 -+ -+#define CFG_MAX_COMMON_IE_BUF_LEN ((1500 * CFG_MAX_NUM_BSS_LIST) / 3) -+ -+/*! Maximum size of Header buffer of each SCAN record */ -+#define CFG_RAW_BUFFER_SIZE 1024 -+ -+/*! Maximum size of IE buffer of each SCAN record */ -+#define CFG_IE_BUFFER_SIZE 512 -+ -+/*! Maximum number of STA records */ -+#define CFG_MAX_NUM_STA_RECORD 32 -+ -+/*------------------------------------------------------------------------------ -+ * Flags and Parameters for Power management -+ *------------------------------------------------------------------------------ -+ */ -+#define CFG_ENABLE_FULL_PM 1 -+#define CFG_ENABLE_WAKEUP_ON_LAN 0 -+#if defined(CONFIG_ARCH_MT6755) || defined(CONFIG_ARCH_MT6735) || defined(CONFIG_ARCH_MT6735M) || \ -+ defined(CONFIG_ARCH_MT6753) || defined(CONFIG_ARCH_MT6580) -+#define CFG_SUPPORT_WAKEUP_REASON_DEBUG 1 /* debug which packet wake up host */ -+#else -+#define CFG_SUPPORT_WAKEUP_REASON_DEBUG 0 /* debug which packet wake up host */ -+#endif -+#define CFG_INIT_POWER_SAVE_PROF ENUM_PSP_FAST_SWITCH -+ -+#define CFG_INIT_ENABLE_PATTERN_FILTER_ARP 0 -+ -+#define CFG_INIT_UAPSD_AC_BMP 0 /* (BIT(3) | BIT(2) | BIT(1) | BIT(0)) */ -+ -+/* #define CFG_SUPPORT_WAPI 0 */ -+#define CFG_SUPPORT_WPS 1 -+#define CFG_SUPPORT_WPS2 1 -+ -+/*------------------------------------------------------------------------------ -+ * 802.11i RSN Pre-authentication PMKID cahce maximun number -+ *------------------------------------------------------------------------------ -+ */ -+#define CFG_MAX_PMKID_CACHE 16 /*!< max number of PMKID cache -+ 16(default) : The Max PMKID cache */ -+/*------------------------------------------------------------------------------ -+ * Auto Channel Selection Maximun Channel Number -+ *------------------------------------------------------------------------------ -+ */ -+ -+#define MAX_AUTO_CHAL_NUM 23 /* Ch1~Ch14,Ch36,Ch40,Ch44, -+ Ch48,Ch149,Ch153,Ch157,Ch161 */ -+/*------------------------------------------------------------------------------ -+ * FAST SCAN -+ *------------------------------------------------------------------------------ -+ */ -+#define CFG_ENABLE_FAST_SCAN 0 -+#define CFG_CN_SUPPORT_CLASS121 0 /* Add Class 121, 5470-5725MHz, support for China domain */ -+#if CFG_ENABLE_FAST_SCAN -+ #define CFG_FAST_SCAN_DWELL_TIME 40 -+ #define CFG_FAST_SCAN_REG_DOMAIN_DEF_IDX 10 -+#endif -+/*------------------------------------------------------------------------------ -+ * Flags and Parameters for Ad-Hoc -+ *------------------------------------------------------------------------------ -+ */ -+#define CFG_INIT_ADHOC_FREQ (2462000) -+#define CFG_INIT_ADHOC_MODE AD_HOC_MODE_MIXED_11BG -+#define CFG_INIT_ADHOC_BEACON_INTERVAL (100) -+#define CFG_INIT_ADHOC_ATIM_WINDOW (0) -+ -+/*------------------------------------------------------------------------------ -+ * Flags and Parameters for Maximum Scan SSID number -+ *------------------------------------------------------------------------------ -+ */ -+#define CFG_SCAN_SSID_MAX_NUM (4) -+#define CFG_SCAN_SSID_MATCH_MAX_NUM (16) -+ -+/*------------------------------------------------------------------------------ -+ * Flags and Parameters for Load Setup Default -+ *------------------------------------------------------------------------------ -+ */ -+ -+/*------------------------------------------------------------------------------ -+ * Flags for enable 802.11A Band setting -+ *------------------------------------------------------------------------------ -+ */ -+ -+/*------------------------------------------------------------------------------ -+ * Flags and Parameters for Interrupt Process -+ *------------------------------------------------------------------------------ -+ */ -+#if defined(_HIF_SDIO) && defined(WINDOWS_CE) -+#define CFG_IST_LOOP_COUNT 8 -+#else -+#define CFG_IST_LOOP_COUNT 8 -+#endif /* _HIF_SDIO */ -+ -+#define CFG_INT_WRITE_CLEAR 0 -+ -+#if defined(LINUX) -+#define CFG_DBG_GPIO_PINS 0 /* if 1, use MT6516 GPIO pin to log TX behavior */ -+#endif -+ -+/* 2 Flags for Driver Debug Options */ -+/*------------------------------------------------------------------------------ -+ * Flags of TX Debug Option. NOTE(Kevin): Confirm with SA before modifying following flags. -+ *------------------------------------------------------------------------------ -+ */ -+#define CFG_DBG_MGT_BUF 1 /*!< 1: Debug statistics usage of MGMT Buffer -+ 0: Disable */ -+ -+#define CFG_HIF_STATISTICS 0 -+ -+#define CFG_HIF_RX_STARVATION_WARNING 0 -+ -+#define CFG_STARTUP_DEBUG 0 -+ -+#define CFG_RX_PKTS_DUMP 1 -+ -+/*------------------------------------------------------------------------------ -+ * Flags of Firmware Download Option. -+ *------------------------------------------------------------------------------ -+ */ -+#define CFG_ENABLE_FW_DOWNLOAD 1 -+ -+#define CFG_ENABLE_FW_DOWNLOAD_ACK 1 -+#define CFG_ENABLE_FW_ENCRYPTION 1 -+ -+#if defined(MT6628) -+#define CFG_ENABLE_FW_DOWNLOAD_AGGREGATION 0 -+#define CFG_ENABLE_FW_DIVIDED_DOWNLOAD 1 -+#endif -+ -+#if defined(MT6620) -+#if MT6620_FPGA_BWCS -+#define CFG_FW_LOAD_ADDRESS 0x10014000 -+#define CFG_OVERRIDE_FW_START_ADDRESS 0 -+#define CFG_FW_START_ADDRESS 0x10014001 -+#elif MT6620_FPGA_V5 -+#define CFG_FW_LOAD_ADDRESS 0x10008000 -+#define CFG_OVERRIDE_FW_START_ADDRESS 0 -+#define CFG_FW_START_ADDRESS 0x10008001 -+#else -+#define CFG_FW_LOAD_ADDRESS 0x10008000 -+#define CFG_OVERRIDE_FW_START_ADDRESS 0 -+#define CFG_FW_START_ADDRESS 0x10008001 -+#endif -+#elif defined(MT6628) -+#define CFG_FW_LOAD_ADDRESS 0x00060000 -+#define CFG_OVERRIDE_FW_START_ADDRESS 1 -+#define CFG_FW_START_ADDRESS 0x00060000 -+#define CFG_START_ADDRESS_IS_1ST_SECTION_ADDR 1 -+#endif -+ -+/*------------------------------------------------------------------------------ -+ * Flags of Bluetooth-over-WiFi (BT 3.0 + HS) support -+ *------------------------------------------------------------------------------ -+ */ -+ -+#ifdef LINUX -+#ifdef CONFIG_X86 -+#define CFG_ENABLE_BT_OVER_WIFI 0 -+#else -+#define CFG_ENABLE_BT_OVER_WIFI 1 -+#endif -+#else -+#define CFG_ENABLE_BT_OVER_WIFI 0 -+#endif -+ -+#define CFG_BOW_SEPARATE_DATA_PATH 1 -+ -+#define CFG_BOW_PHYSICAL_LINK_NUM 4 -+ -+#define CFG_BOW_TEST 0 -+ -+#define CFG_BOW_LIMIT_AIS_CHNL 1 -+ -+#define CFG_BOW_SUPPORT_11N 0 -+ -+#define CFG_BOW_RATE_LIMITATION 1 -+ -+/*------------------------------------------------------------------------------ -+ * Flags of Wi-Fi Direct support -+ *------------------------------------------------------------------------------ -+ */ -+#ifdef LINUX -+#ifdef CONFIG_X86 -+#define CFG_ENABLE_WIFI_DIRECT 0 -+#define CFG_SUPPORT_802_11W 0 -+#else -+#define CFG_ENABLE_WIFI_DIRECT 1 -+#define CFG_SUPPORT_802_11W 0 /*!< 0(default): Disable 802.11W */ -+#endif -+#else -+#define CFG_ENABLE_WIFI_DIRECT 0 -+#define CFG_SUPPORT_802_11W 0 /* Not support at WinXP */ -+#endif -+ -+#define CFG_SUPPORT_PERSISTENT_GROUP 0 -+ -+#define CFG_TEST_WIFI_DIRECT_GO 0 -+ -+#define CFG_TEST_ANDROID_DIRECT_GO 0 -+ -+#define CFG_UNITEST_P2P 0 -+ -+/* -+ * Enable cfg80211 option after Android 2.2(Froyo) is suggested, -+ * cfg80211 on linux 2.6.29 is not mature yet -+ */ -+#define CFG_ENABLE_WIFI_DIRECT_CFG_80211 1 -+ -+#define CFG_SUPPORT_HOTSPOT_OPTIMIZATION 1 -+#define CFG_HOTSPOT_OPTIMIZATION_BEACON_INTERVAL 300 -+#define CFG_HOTSPOT_OPTIMIZATION_DTIM 1 -+ -+/*------------------------------------------------------------------------------ -+ * Configuration Flags (Linux Only) -+ *------------------------------------------------------------------------------ -+ */ -+#define CFG_SUPPORT_EXT_CONFIG 0 -+ -+/*------------------------------------------------------------------------------ -+ * Statistics Buffering Mechanism -+ *------------------------------------------------------------------------------ -+ */ -+#if CFG_SUPPORT_PERFORMANCE_TEST -+#define CFG_ENABLE_STATISTICS_BUFFERING 1 -+#else -+#define CFG_ENABLE_STATISTICS_BUFFERING 0 -+#endif -+#define CFG_STATISTICS_VALID_CYCLE 2000 -+#define CFG_LINK_QUALITY_VALID_PERIOD 5000 -+ -+/*------------------------------------------------------------------------------ -+ * Migration Option -+ *------------------------------------------------------------------------------ -+ */ -+#define CFG_SUPPORT_ADHOC 0 -+#define CFG_SUPPORT_AAA 1 -+ -+#define CFG_SUPPORT_BCM 0 -+#define CFG_SUPPORT_BCM_BWCS 0 -+#define CFG_SUPPORT_BCM_BWCS_DEBUG 0 -+ -+#define CFG_SUPPORT_RDD_TEST_MODE 0 -+ -+#define CFG_SUPPORT_PWR_MGT 1 -+ -+#define CFG_RSN_MIGRATION 1 -+ -+#define CFG_PRIVACY_MIGRATION 1 -+ -+#define CFG_ENABLE_HOTSPOT_PRIVACY_CHECK 1 -+ -+#define CFG_MGMT_FRAME_HANDLING 1 -+ -+#define CFG_MGMT_HW_ACCESS_REPLACEMENT 0 -+ -+#if CFG_SUPPORT_PERFORMANCE_TEST -+ -+#else -+ -+#endif -+ -+#define CFG_SUPPORT_AIS_5GHZ 1 -+#define CFG_SUPPORT_BEACON_CHANGE_DETECTION 0 -+ -+/*------------------------------------------------------------------------------ -+ * Option for NVRAM and Version Checking -+ *------------------------------------------------------------------------------ -+ */ -+#define CFG_SUPPORT_NVRAM 1 -+#define CFG_NVRAM_EXISTENCE_CHECK 1 -+#define CFG_SW_NVRAM_VERSION_CHECK 1 -+#define CFG_SUPPORT_NIC_CAPABILITY 1 -+ -+/*------------------------------------------------------------------------------ -+ * CONFIG_TITLE : Stress Test Option -+ * OWNER : Puff Wen -+ * Description : For stress test only. DO NOT enable it while normal operation -+ *------------------------------------------------------------------------------ -+ */ -+#define CFG_STRESS_TEST_SUPPORT 0 -+ -+/*------------------------------------------------------------------------------ -+ * Flags for LINT -+ *------------------------------------------------------------------------------ -+ */ -+#define LINT_SAVE_AND_DISABLE /*lint -save -e* */ -+ -+#define LINT_RESTORE /*lint -restore */ -+ -+#define LINT_EXT_HEADER_BEGIN LINT_SAVE_AND_DISABLE -+ -+#define LINT_EXT_HEADER_END LINT_RESTORE -+ -+/*------------------------------------------------------------------------------ -+ * Flags of Features -+ *------------------------------------------------------------------------------ -+ */ -+ -+#define CFG_SUPPORT_QOS 1 /* Enable/disable QoS TX, AMPDU */ -+#define CFG_SUPPORT_AMPDU_TX 1 -+#define CFG_SUPPORT_AMPDU_RX 1 -+#define CFG_SUPPORT_TSPEC 0 /* Enable/disable TS-related Action frames handling */ -+#define CFG_SUPPORT_UAPSD 1 -+#define CFG_SUPPORT_UL_PSMP 0 -+ -+#define CFG_SUPPORT_ROAMING 1 /* Roaming System */ -+#define CFG_SUPPORT_SWCR 1 -+ -+#define CFG_SUPPORT_ANTI_PIRACY 1 -+ -+#define CFG_SUPPORT_OSC_SETTING 1 -+ -+#define CFG_SUPPORT_P2P_RSSI_QUERY 0 -+ -+#define CFG_SHOW_MACADDR_SOURCE 1 -+ -+#define CFG_SUPPORT_802_11V 0 /* Support 802.11v Wireless Network Management */ -+#define CFG_SUPPORT_802_11V_TIMING_MEASUREMENT 0 -+#if (CFG_SUPPORT_802_11V_TIMING_MEASUREMENT == 1) && (CFG_SUPPORT_802_11V == 0) -+#error "CFG_SUPPORT_802_11V should be 1 once CFG_SUPPORT_802_11V_TIMING_MEASUREMENT equals to 1" -+#endif -+#if (CFG_SUPPORT_802_11V == 0) -+#define WNM_UNIT_TEST 0 -+#endif -+ -+#define CFG_DRIVER_COMPOSE_ASSOC_REQ 1 -+ -+#define CFG_STRICT_CHECK_CAPINFO_PRIVACY 0 -+ -+#define CFG_SUPPORT_WFD 1 -+ -+#define CFG_SUPPORT_WFD_COMPOSE_IE 1 -+ -+/*------------------------------------------------------------------------------ -+ * Flags of Packet Lifetime Profiling Mechanism -+ *------------------------------------------------------------------------------ -+ */ -+#define CFG_ENABLE_PKT_LIFETIME_PROFILE 1 -+ -+#define CFG_ENABLE_PER_STA_STATISTICS 1 -+ -+#define CFG_PRINT_RTP_PROFILE 0 /* If want to enable WFD Debug, please change it to 1. */ -+#define CFG_PRINT_RTP_SN_SKIP 0 -+ -+#define CFG_SUPPORT_PWR_LIMIT_COUNTRY 1 -+/*------------------------------------------------------------------------------ -+ * Flags of bus error tolerance -+ *------------------------------------------------------------------------------ -+ */ -+#define CFG_FORCE_RESET_UNDER_BUS_ERROR 0 -+ -+/*------------------------------------------------------------------------------ -+ * Build Date Code Integration -+ *------------------------------------------------------------------------------ -+ */ -+#define CFG_SUPPORT_BUILD_DATE_CODE 1 -+ -+/*------------------------------------------------------------------------------ -+ * Flags for prepare the FW compile flag -+ *------------------------------------------------------------------------------ -+ */ -+#define COMPILE_FLAG0_GET_STA_LINK_STATUS (1<<0) -+#define COMPILE_FLAG0_WFD_ENHANCEMENT_PROTECT (1<<1) -+ -+/*------------------------------------------------------------------------------ -+ * Flags of Batch Scan SUPPORT -+ *------------------------------------------------------------------------------ -+ */ -+#define CFG_SUPPORT_BATCH_SCAN 0 -+#define CFG_BATCH_MAX_MSCAN 2 -+ -+/*------------------------------------------------------------------------------ -+ * Flags of Channel Environment SUPPORT -+ *------------------------------------------------------------------------------ -+ */ -+#define CFG_SUPPORT_GET_CH_ENV 1 -+ -+/*------------------------------------------------------------------------------ -+ * Flags of THERMO_THROTTLING SUPPORT -+ *------------------------------------------------------------------------------ -+ */ -+ -+#define CFG_SUPPORT_THERMO_THROTTLING 1 -+#define WLAN_INCLUDE_PROC 1 -+ -+#define CFG_SUPPORT_DETECT_SECURITY_MODE_CHANGE 1 -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif /* _CONFIG_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/debug.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/debug.h -new file mode 100644 -index 000000000000..af586063c21a ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/debug.h -@@ -0,0 +1,466 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/debug.h#1 -+*/ -+ -+/*! \file debug.h -+ \brief Definition of SW debugging level. -+ -+ In this file, it describes the definition of various SW debugging levels and -+ assert functions. -+*/ -+ -+/* -+** Log: debug.h -+ * -+ * 12 16 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * fixed the Windows DDK free build compiling error. -+ * -+ * 11 24 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * Adjust code for DBG and CONFIG_XLOG. -+ * -+ * 11 11 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * modify the xlog related code. -+ * -+ * 11 10 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * Using the new XLOG define for dum Memory. -+ * -+ * 11 03 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * Add dumpMemory8 at XLOG support. -+ * -+ * 11 02 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * adding the code for XLOG. -+ * -+ * 08 31 2011 cm.chang -+ * [WCXRP00000969] [MT6620 Wi-Fi][Driver][FW] Channel list for 5G band based on country code -+ * . -+ * -+ * 01 27 2011 tsaiyuan.hsu -+ * [WCXRP00000392] [MT6620 Wi-Fi][Driver] Add Roaming Support -+ * add roaming fsm -+ * 1. not support 11r, only use strength of signal to determine roaming. -+ * 2. not enable CFG_SUPPORT_ROAMING until completion of full test. -+ * 3. in 6620, adopt work-around to avoid sign extension problem of cck of hw -+ * 4. assume that change of link quality in smooth way. -+ * -+ * 01 07 2011 wh.su -+ * [WCXRP00000326] [MT6620][Wi-Fi][Driver] check in the binary format gl_sec.o.new instead of use change type!!! -+ * . -+ * -+ * 09 23 2010 cp.wu -+ * NULL -+ * add BOW index for debugging message and passing compilation -+ * -+ * 07 20 2010 wh.su -+ * -+ * adding the wapi code. -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 21 2010 yarco.yang -+ * [WPD00003837][MT6620]Data Path Refine -+ * Support CFG_MQM_MIGRATION flag -+ * -+ * 06 17 2010 yuche.tsai -+ * [WPD00003839][MT6620 5931][P2P] Feature migration -+ * Add one more debug moduel for P2P. -+ * -+ * 06 14 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add management dispatching function table. -+ * -+ * 06 11 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add bss.c. -+ * -+ * 06 11 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) migrate assoc.c. -+ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness -+ * 3) add configuration options for CNM_MEM and RSN modules -+ * 4) add data path for management frames -+ * 5) eliminate rPacketInfo of MSDU_INFO_T -+ * -+ * 06 10 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add debug module index for cnm and ais. -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 05 17 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * add CFG_STARTUP_DEBUG for debugging starting up issue. -+ * -+ * 04 26 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) surpress compiler warning -+ * 2) when acqruing LP-own, keep writing WHLPCR whenever OWN is not acquired yet -+** \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-10-29 19:47:50 GMT mtk01084 -+** add emu category -+** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-04-17 18:12:04 GMT mtk01426 -+** Don't use dynamic memory allocate for debug message -+** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 20:11:29 GMT mtk01426 -+** Init for develop -+** -+*/ -+ -+#ifndef _DEBUG_H -+#define _DEBUG_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+#ifndef BUILD_QA_DBG -+#define BUILD_QA_DBG 0 -+#endif -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "gl_typedef.h" -+ -+extern UINT_8 aucDebugModule[]; -+extern UINT_32 u4DebugModule; -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+/* Define debug category (class): -+ * (1) ERROR (2) WARN (3) STATE (4) EVENT (5) TRACE (6) INFO (7) LOUD (8) TEMP -+ */ -+#define DBG_CLASS_ERROR BIT(0) -+#define DBG_CLASS_WARN BIT(1) -+#define DBG_CLASS_STATE BIT(2) -+#define DBG_CLASS_EVENT BIT(3) -+#define DBG_CLASS_TRACE BIT(4) -+#define DBG_CLASS_INFO BIT(5) -+#define DBG_CLASS_LOUD BIT(6) -+#define DBG_CLASS_TEMP BIT(7) -+#define DBG_CLASS_MASK BITS(0, 7) -+ -+#if defined(LINUX) -+#define DBG_PRINTF_64BIT_DEC "lld" -+ -+#else /* Windows */ -+#define DBG_PRINTF_64BIT_DEC "I64d" -+ -+#endif -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+/* Define debug module index */ -+typedef enum _ENUM_DBG_MODULE_T { -+ DBG_INIT_IDX = 0, /* For driver initial */ -+ DBG_HAL_IDX, /* For HAL(HW) Layer */ -+ DBG_INTR_IDX, /* For Interrupt */ -+ DBG_REQ_IDX, -+ DBG_TX_IDX, -+ DBG_RX_IDX, -+ DBG_RFTEST_IDX, /* For RF test mode */ -+ DBG_EMU_IDX, /* Developer specific */ -+ -+ DBG_SW1_IDX, /* Developer specific */ -+ DBG_SW2_IDX, /* Developer specific */ -+ DBG_SW3_IDX, /* Developer specific */ -+ DBG_SW4_IDX, /* Developer specific */ -+ -+ DBG_HEM_IDX, /* HEM */ -+ DBG_AIS_IDX, /* AIS */ -+ DBG_RLM_IDX, /* RLM */ -+ DBG_MEM_IDX, /* RLM */ -+ DBG_CNM_IDX, /* CNM */ -+ DBG_RSN_IDX, /* RSN */ -+ DBG_BSS_IDX, /* BSS */ -+ DBG_SCN_IDX, /* SCN */ -+ DBG_SAA_IDX, /* SAA */ -+ DBG_AAA_IDX, /* AAA */ -+ DBG_P2P_IDX, /* P2P */ -+ DBG_QM_IDX, /* QUE_MGT */ -+ DBG_SEC_IDX, /* SEC */ -+ DBG_BOW_IDX, /* BOW */ -+ DBG_WAPI_IDX, /* WAPI */ -+ DBG_ROAMING_IDX, /* ROAMING */ -+ DBG_TDLS_IDX, /* TDLS *//* CFG_SUPPORT_TDLS */ -+ DBG_OID_IDX, -+ DBG_NIC_IDX, -+ -+ DBG_MODULE_NUM /* Notice the XLOG check */ -+} ENUM_DBG_MODULE_T; -+ -+/* XLOG */ -+/* #define XLOG_DBG_MODULE_IDX 28 */ /* DBG_MODULE_NUM */ -+/* #if (XLOG_DBG_MODULE_IDX != XLOG_DBG_MODULE_IDX) */ -+/* #error "Please modify the DBG_MODULE_NUM and make sure this include at XLOG" */ -+/* #endif */ -+ -+/* Define who owns developer specific index */ -+#define DBG_YARCO_IDX DBG_SW1_IDX -+#define DBG_KEVIN_IDX DBG_SW2_IDX -+#define DBG_CMC_IDX DBG_SW3_IDX -+#define DBG_GEORGE_IDX DBG_SW4_IDX -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+/* Debug print format string for the OS system time */ -+#define OS_SYSTIME_DBG_FORMAT "0x%08x" -+ -+/* Debug print argument for the OS system time */ -+#define OS_SYSTIME_DBG_ARGUMENT(systime) (systime) -+ -+/* Debug print format string for the MAC Address */ -+#define MACSTR "%pM" -+/* "%02x:%02x:%02x:%02x:%02x:%02x" */ -+ -+/* Debug print argument for the MAC Address */ -+#define MAC2STR(a) a -+/* ((PUINT_8)a)[0], ((PUINT_8)a)[1], ((PUINT_8)a)[2], ((PUINT_8)a)[3], ((PUINT_8)a)[4], ((PUINT_8)a)[5] */ -+ -+/* The pre-defined format to dump the value of a varaible with its name shown. */ -+#define DUMPVAR(variable, format) (#variable " = " format "\n", variable) -+ -+/* The pre-defined format to dump the MAC type value with its name shown. */ -+#define DUMPMACADDR(addr) (#addr " = %pM\n", (addr)) -+ -+/* Basiclly, we just do renaming of KAL functions although they should -+ * be defined as "Nothing to do" if DBG=0. But in some compiler, the macro -+ * syntax does not support #define LOG_FUNC(x,...) -+ * -+ * A caller shall not invoke these three macros when DBG=0. -+ */ -+ -+/*LOG_FUNC("[wlan]%s:(" #_Module " " #_Class ") "_Fmt, __func__, ##__VA_ARGS__);*/ -+ -+#define LOG_FUNC kalPrint -+ -+#if defined(LINUX) -+#define DBGLOG(_Module, _Class, _Fmt, ...) \ -+ do { \ -+ if ((aucDebugModule[DBG_##_Module##_IDX] & DBG_CLASS_##_Class) == 0) \ -+ break; \ -+ LOG_FUNC("%s:(" #_Module " " #_Class ")"_Fmt, __func__, ##__VA_ARGS__); \ -+ } while (0) -+#else -+#define DBGLOG(_Module, _Class, _Fmt) -+#endif -+ -+#if DBG -+ -+#define TMP_BUF_LEN 256 -+#define TMP_WBUF_LEN (TMP_BUF_LEN * 2) -+ -+extern PINT_16 g_wbuf_p; -+extern PINT_8 g_buf_p; -+ -+ /* If __FUNCTION__ is already defined by compiler, we just use it. */ -+#if defined(__func__) -+#define DEBUGFUNC(_Func) -+#else -+#define DEBUGFUNC(_Func) \ -+ static const char __func__[] = _Func -+#endif -+ -+#define DBGLOG_MEM8(_Module, _Class, _StartAddr, _Length) \ -+ { \ -+ if (aucDebugModule[DBG_##_Module##_IDX] & DBG_CLASS_##_Class) { \ -+ LOG_FUNC("%s: (" #_Module " " #_Class ")\n", __func__); \ -+ dumpMemory8((PUINT_8) (_StartAddr), (UINT_32) (_Length)); \ -+ } \ -+ } -+ -+#define DBGLOG_MEM32(_Module, _Class, _StartAddr, _Length) \ -+ { \ -+ if (aucDebugModule[DBG_##_Module##_IDX] & DBG_CLASS_##_Class) { \ -+ LOG_FUNC("%s: (" #_Module " " #_Class ")\n", __func__); \ -+ dumpMemory32((PUINT_32) (_StartAddr), (UINT_32) (_Length)); \ -+ } \ -+ } -+ /*lint -restore */ -+ -+ /*lint -save -e961 use of '#undef' is discouraged */ -+#undef ASSERT -+ /*lint -restore */ -+ -+#ifdef _lint -+#define ASSERT(_exp) \ -+ { \ -+ if (!(_exp)) { \ -+ do {} while (1); \ -+ } \ -+ } -+#else -+#define ASSERT(_exp) \ -+ { \ -+ if (!(_exp) && !fgIsBusAccessFailed) { \ -+ LOG_FUNC("Assertion failed: %s:%d %s\n", __FILE__, __LINE__, #_exp); \ -+ kalBreakPoint(); \ -+ } \ -+ } -+#endif /* _lint */ -+ -+#define ASSERT_REPORT(_exp, _fmt) \ -+ { \ -+ if (!(_exp) && !fgIsBusAccessFailed) { \ -+ LOG_FUNC("Assertion failed: %s:%d %s\n", __FILE__, __LINE__, #_exp); \ -+ LOG_FUNC _fmt; \ -+ kalBreakPoint(); \ -+ } \ -+ } -+ -+#define DISP_STRING(_str) _str -+ -+#else /* !DBG */ -+ -+#define DEBUGFUNC(_Func) -+#define INITLOG(_Fmt) -+#define ERRORLOG(_Fmt) -+#define WARNLOG(_Fmt) -+ -+#define DBGLOG_MEM8(_Module, _Class, _StartAddr, _Length) -+#define DBGLOG_MEM32(_Module, _Class, _StartAddr, _Length) -+ -+#undef ASSERT -+ -+#if BUILD_QA_DBG -+#if defined(LINUX) /* For debugging in Linux w/o GDB */ -+#define ASSERT(_exp) \ -+ { \ -+ if (!(_exp) && !fgIsBusAccessFailed) { \ -+ LOG_FUNC("Assertion failed: %s:%d (%s)\n", __FILE__, __LINE__, #_exp); \ -+ kalBreakPoint(); \ -+ } \ -+ } -+ -+#define ASSERT_REPORT(_exp, _fmt) \ -+ { \ -+ if (!(_exp) && !fgIsBusAccessFailed) { \ -+ LOG_FUNC("Assertion failed: %s:%d (%s)\n", __FILE__, __LINE__, #_exp); \ -+ LOG_FUNC _fmt; \ -+ kalBreakPoint(); \ -+ } \ -+ } -+#else -+#ifdef WINDOWS_CE -+#define UNICODE_TEXT(_msg) TEXT(_msg) -+#define ASSERT(_exp) \ -+ { \ -+ if (!(_exp) && !fgIsBusAccessFailed) { \ -+ TCHAR rUbuf[256]; \ -+ kalBreakPoint(); \ -+ _stprintf(rUbuf, TEXT("Assertion failed: %s:%d %s\n"), \ -+ UNICODE_TEXT(__FILE__), \ -+ __LINE__, \ -+ UNICODE_TEXT(#_exp)); \ -+ MessageBox(NULL, rUbuf, TEXT("ASSERT!"), MB_OK); \ -+ } \ -+ } -+ -+#define ASSERT_REPORT(_exp, _fmt) \ -+ { \ -+ if (!(_exp) && !fgIsBusAccessFailed) { \ -+ TCHAR rUbuf[256]; \ -+ kalBreakPoint(); \ -+ _stprintf(rUbuf, TEXT("Assertion failed: %s:%d %s\n"), \ -+ UNICODE_TEXT(__FILE__), \ -+ __LINE__, \ -+ UNICODE_TEXT(#_exp)); \ -+ MessageBox(NULL, rUbuf, TEXT("ASSERT!"), MB_OK); \ -+ } \ -+ } -+#else -+#define ASSERT(_exp) \ -+ { \ -+ if (!(_exp) && !fgIsBusAccessFailed) { \ -+ kalBreakPoint(); \ -+ } \ -+ } -+ -+#define ASSERT_REPORT(_exp, _fmt) \ -+ { \ -+ if (!(_exp) && !fgIsBusAccessFailed) { \ -+ kalBreakPoint(); \ -+ } \ -+ } -+#endif /* WINDOWS_CE */ -+#endif /* LINUX */ -+#else -+#define ASSERT(_exp) \ -+ { \ -+ if (!(_exp) && !fgIsBusAccessFailed) { \ -+ LOG_FUNC("Warning at %s:%d (%s)\n", __func__, __LINE__, #_exp); \ -+ } \ -+ } -+ -+#define ASSERT_REPORT(_exp, _fmt) \ -+ { \ -+ if (!(_exp) && !fgIsBusAccessFailed) { \ -+ LOG_FUNC("Warning at %s:%d (%s)\n", __func__, __LINE__, #_exp); \ -+ LOG_FUNC _fmt; \ -+ } \ -+ } -+#endif /* BUILD_QA_DBG */ -+ -+#define DISP_STRING(_str) "" -+ -+#endif /* DBG */ -+ -+#if CFG_STARTUP_DEBUG -+#if defined(LINUX) -+#define DBGPRINTF kalPrint -+#else -+#define DBGPRINTF DbgPrint -+#endif -+#else -+#define DBGPRINTF(...) -+#endif -+ -+/* The following macro is used for debugging packed structures. */ -+#ifndef DATA_STRUCT_INSPECTING_ASSERT -+#define DATA_STRUCT_INSPECTING_ASSERT(expr) \ -+{ \ -+ switch (0) {case 0: case (expr): default:; } \ -+} -+#endif -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+VOID dumpMemory8(IN PUINT_8 pucStartAddr, IN UINT_32 u4Length); -+ -+VOID dumpMemory32(IN PUINT_32 pu4StartAddr, IN UINT_32 u4Length); -+ -+VOID wlanDebugInit(VOID); -+VOID wlanDebugUninit(VOID); -+VOID wlanTraceReleaseTcRes(P_ADAPTER_T prAdapter, PUINT_8 aucTxRlsCnt, UINT_8 ucAvailable); -+VOID wlanTraceTxCmd(P_CMD_INFO_T prCmd); -+VOID wlanDumpTcResAndTxedCmd(PUINT_8 pucBuf, UINT_32 maxLen); -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+#endif /* _DEBUG_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/link.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/link.h -new file mode 100644 -index 000000000000..108860c80e2d ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/link.h -@@ -0,0 +1,368 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/link.h#1 -+*/ -+ -+/*! \file link.h -+ \brief Definition for simple doubly linked list operations. -+ -+ In this file we define the simple doubly linked list data structure and its -+ operation MACROs and INLINE functions. -+*/ -+ -+/* -+** Log: link.h -+ * -+ * 08 05 2010 yuche.tsai -+ * NULL -+ * Modify a MACRO of LINK_FOR_EACH_SAFE for compile error. -+ * -+ * 07 19 2010 cm.chang -+ * -+ * Set RLM parameters and enable CNM channel manager -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 07 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * [WPD00003833] [MT6620 and MT5931] Driver migration -+ * . -+ * -+ * -+ * -+ * -+ * May 4 2009 mtk01084 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * add WIFI to BORA source control -+** \main\maintrunk.MT5921\8 2008-10-16 15:57:11 GMT mtk01461 -+** Update driver to fix lint warning -+** \main\maintrunk.MT5921\7 2008-08-10 18:47:53 GMT mtk01461 -+** Update for Driver Review -+** \main\maintrunk.MT5921\6 2007-12-11 00:09:00 GMT mtk01461 -+** Add macro for checking valid list -+** \main\maintrunk.MT5921\5 2007-11-13 14:27:01 GMT mtk01461 -+** Add LINK_IS_INVALID macro -+** Revision 1.1.1.1 2007/06/22 08:09:05 MTK01461 -+** no message -+** -+*/ -+ -+#ifndef _LINK_H -+#define _LINK_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "gl_typedef.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+/* May cause page fault & unalignment issue (data abort) */ -+#define INVALID_LINK_POISON1 ((VOID *) 0x00100101) -+/* Used to verify that nonbody uses non-initialized link entries. */ -+#define INVALID_LINK_POISON2 ((VOID *) 0x00100201) -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+/* Simple Doubly Linked List Structures - Entry Part */ -+typedef struct _LINK_ENTRY_T { -+ struct _LINK_ENTRY_T *prNext, *prPrev; -+} LINK_ENTRY_T, *P_LINK_ENTRY_T; -+ -+/* Simple Doubly Linked List Structures - List Part */ -+typedef struct _LINK_T { -+ P_LINK_ENTRY_T prNext; -+ P_LINK_ENTRY_T prPrev; -+ UINT_32 u4NumElem; -+} LINK_T, *P_LINK_T; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+#if 0 /* No one use it, temporarily mark it for [Lint - Info 773] */ -+#define LINK_ADDR(rLink) { (P_LINK_ENTRY_T)(&(rLink)), (P_LINK_ENTRY_T)(&(rLink)), 0 } -+ -+#define LINK_DECLARATION(rLink) \ -+ struct _LINK_T rLink = LINK_ADDR(rLink) -+#endif -+ -+#define LINK_INITIALIZE(prLink) \ -+ do { \ -+ ((P_LINK_T)(prLink))->prNext = (P_LINK_ENTRY_T)(prLink); \ -+ ((P_LINK_T)(prLink))->prPrev = (P_LINK_ENTRY_T)(prLink); \ -+ ((P_LINK_T)(prLink))->u4NumElem = 0; \ -+ } while (0) -+ -+#define LINK_ENTRY_INITIALIZE(prEntry) \ -+ do { \ -+ ((P_LINK_ENTRY_T)(prEntry))->prNext = (P_LINK_ENTRY_T)NULL; \ -+ ((P_LINK_ENTRY_T)(prEntry))->prPrev = (P_LINK_ENTRY_T)NULL; \ -+ } while (0) -+ -+#define LINK_ENTRY_INVALID(prEntry) \ -+ do { \ -+ ((P_LINK_ENTRY_T)(prEntry))->prNext = (P_LINK_ENTRY_T)INVALID_LINK_POISON1; \ -+ ((P_LINK_ENTRY_T)(prEntry))->prPrev = (P_LINK_ENTRY_T)INVALID_LINK_POISON2; \ -+ } while (0) -+ -+#define LINK_IS_EMPTY(prLink) (((P_LINK_T)(prLink))->prNext == (P_LINK_ENTRY_T)(prLink)) -+ -+/* NOTE: We should do memory zero before any LINK been initiated, so we can check -+ * if it is valid before parsing the LINK. -+ */ -+#define LINK_IS_INVALID(prLink) (((P_LINK_T)(prLink))->prNext == (P_LINK_ENTRY_T)NULL) -+ -+#define LINK_IS_VALID(prLink) (((P_LINK_T)(prLink))->prNext != (P_LINK_ENTRY_T)NULL) -+ -+#define LINK_ENTRY(ptr, type, member) ENTRY_OF(ptr, type, member) -+ -+/* Insert an entry into a link list's head */ -+#define LINK_INSERT_HEAD(prLink, prEntry) \ -+ { \ -+ linkAdd(prEntry, prLink); \ -+ ((prLink)->u4NumElem)++; \ -+ } -+ -+/* Append an entry into a link list's tail */ -+#define LINK_INSERT_TAIL(prLink, prEntry) \ -+ { \ -+ linkAddTail(prEntry, prLink); \ -+ ((prLink)->u4NumElem)++; \ -+ } -+ -+/* Peek head entry, but keep still in link list */ -+#define LINK_PEEK_HEAD(prLink, _type, _member) \ -+ ( \ -+ LINK_IS_EMPTY(prLink) ? \ -+ NULL : LINK_ENTRY((prLink)->prNext, _type, _member) \ -+ ) -+ -+/* Peek tail entry, but keep still in link list */ -+#define LINK_PEEK_TAIL(prLink, _type, _member) \ -+ ( \ -+ LINK_IS_EMPTY(prLink) ? \ -+ NULL : LINK_ENTRY((prLink)->prPrev, _type, _member) \ -+ ) -+ -+/* Get first entry from a link list */ -+/* NOTE: We assume the link entry located at the beginning of "prEntry Type", -+ * so that we can cast the link entry to other data type without doubts. -+ * And this macro also decrease the total entry count at the same time. -+ */ -+#define LINK_REMOVE_HEAD(prLink, prEntry, _P_TYPE) \ -+ { \ -+ ASSERT(prLink); \ -+ if (LINK_IS_EMPTY(prLink)) { \ -+ prEntry = (_P_TYPE)NULL; \ -+ } \ -+ else { \ -+ prEntry = (_P_TYPE)(((P_LINK_T)(prLink))->prNext); \ -+ linkDel((P_LINK_ENTRY_T)prEntry); \ -+ ((prLink)->u4NumElem)--; \ -+ } \ -+ } -+ -+/* Assume the link entry located at the beginning of prEntry Type. -+ * And also decrease the total entry count. -+ */ -+#define LINK_REMOVE_KNOWN_ENTRY(prLink, prEntry) \ -+ { \ -+ ASSERT(prLink); \ -+ ASSERT(prEntry); \ -+ linkDel((P_LINK_ENTRY_T)prEntry); \ -+ ((prLink)->u4NumElem)--; \ -+ } -+ -+/* Iterate over a link list */ -+#define LINK_FOR_EACH(prEntry, prLink) \ -+ for (prEntry = (prLink)->prNext; \ -+ prEntry != (P_LINK_ENTRY_T)(prLink); \ -+ prEntry = (P_LINK_ENTRY_T)prEntry->prNext) -+ -+/* Iterate over a link list backwards */ -+#define LINK_FOR_EACH_PREV(prEntry, prLink) \ -+ for (prEntry = (prLink)->prPrev; \ -+ prEntry != (P_LINK_ENTRY_T)(prLink); \ -+ prEntry = (P_LINK_ENTRY_T)prEntry->prPrev) -+ -+/* Iterate over a link list safe against removal of link entry */ -+#define LINK_FOR_EACH_SAFE(prEntry, prNextEntry, prLink) \ -+ for (prEntry = (prLink)->prNext, prNextEntry = prEntry->prNext; \ -+ prEntry != (P_LINK_ENTRY_T)(prLink); \ -+ prEntry = prNextEntry, prNextEntry = prEntry->prNext) -+ -+/* Iterate over a link list of given type */ -+#define LINK_FOR_EACH_ENTRY(prObj, prLink, rMember, _TYPE) \ -+ for (prObj = LINK_ENTRY((prLink)->prNext, _TYPE, rMember); \ -+ &prObj->rMember != (P_LINK_ENTRY_T)(prLink); \ -+ prObj = LINK_ENTRY(prObj->rMember.prNext, _TYPE, rMember)) -+ -+/* Iterate backwards over a link list of given type */ -+#define LINK_FOR_EACH_ENTRY_PREV(prObj, prLink, rMember, _TYPE) \ -+ for (prObj = LINK_ENTRY((prLink)->prPrev, _TYPE, rMember); \ -+ &prObj->rMember != (P_LINK_ENTRY_T)(prLink); \ -+ prObj = LINK_ENTRY(prObj->rMember.prPrev, _TYPE, rMember)) -+ -+/* Iterate over a link list of given type safe against removal of link entry */ -+#define LINK_FOR_EACH_ENTRY_SAFE(prObj, prNextObj, prLink, rMember, _TYPE) \ -+ for (prObj = LINK_ENTRY((prLink)->prNext, _TYPE, rMember), \ -+ prNextObj = LINK_ENTRY(prObj->rMember.prNext, _TYPE, rMember); \ -+ &prObj->rMember != (P_LINK_ENTRY_T)(prLink); \ -+ prObj = prNextObj, \ -+ prNextObj = LINK_ENTRY(prNextObj->rMember.prNext, _TYPE, rMember)) -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is only for internal link list manipulation. -+* -+* \param[in] prNew Pointer of new link head -+* \param[in] prPrev Pointer of previous link head -+* \param[in] prNext Pointer of next link head -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+static inline VOID __linkAdd(IN P_LINK_ENTRY_T prNew, IN P_LINK_ENTRY_T prPrev, IN P_LINK_ENTRY_T prNext) -+{ -+ prNext->prPrev = prNew; -+ prNew->prNext = prNext; -+ prNew->prPrev = prPrev; -+ prPrev->prNext = prNew; -+ -+} /* end of __linkAdd() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will add a new entry after the specified link head. -+* -+* \param[in] prNew New entry to be added -+* \param[in] prHead Specified link head to add it after -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+static inline VOID linkAdd(IN P_LINK_ENTRY_T prNew, IN P_LINK_T prLink) -+{ -+ __linkAdd(prNew, (P_LINK_ENTRY_T) prLink, prLink->prNext); -+ -+} /* end of linkAdd() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will add a new entry before the specified link head. -+* -+* \param[in] prNew New entry to be added -+* \param[in] prHead Specified link head to add it before -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+static inline VOID linkAddTail(IN P_LINK_ENTRY_T prNew, IN P_LINK_T prLink) -+{ -+ __linkAdd(prNew, prLink->prPrev, (P_LINK_ENTRY_T) prLink); -+ -+} /* end of linkAddTail() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is only for internal link list manipulation. -+* -+* \param[in] prPrev Pointer of previous link head -+* \param[in] prNext Pointer of next link head -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+static inline VOID __linkDel(IN P_LINK_ENTRY_T prPrev, IN P_LINK_ENTRY_T prNext) -+{ -+ prNext->prPrev = prPrev; -+ prPrev->prNext = prNext; -+ -+} /* end of __linkDel() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will delete a specified entry from link list. -+* NOTE: the entry is in an initial state. -+* -+* \param prEntry Specified link head(entry) -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+static inline VOID linkDel(IN P_LINK_ENTRY_T prEntry) -+{ -+ __linkDel(prEntry->prPrev, prEntry->prNext); -+ -+ LINK_ENTRY_INITIALIZE(prEntry); -+ -+} /* end of linkDel() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will delete a specified entry from link list and then add it -+* after the specified link head. -+* -+* \param[in] prEntry Specified link head(entry) -+* \param[in] prOtherHead Another link head to add it after -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+static inline VOID linkMove(IN P_LINK_ENTRY_T prEntry, IN P_LINK_T prLink) -+{ -+ __linkDel(prEntry->prPrev, prEntry->prNext); -+ linkAdd(prEntry, prLink); -+ -+} /* end of linkMove() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will delete a specified entry from link list and then add it -+* before the specified link head. -+* -+* \param[in] prEntry Specified link head(entry) -+* \param[in] prOtherHead Another link head to add it before -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+static inline VOID linkMoveTail(IN P_LINK_ENTRY_T prEntry, IN P_LINK_T prLink) -+{ -+ __linkDel(prEntry->prPrev, prEntry->prNext); -+ linkAddTail(prEntry, prLink); -+ -+} /* end of linkMoveTail() */ -+ -+#endif /* _LINK_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/aa_fsm.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/aa_fsm.h -new file mode 100644 -index 000000000000..fd83c79ffe10 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/aa_fsm.h -@@ -0,0 +1,188 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/mgmt/aa_fsm.h#1 -+*/ -+ -+/*! \file aa_fsm.h -+ \brief Declaration of functions and finite state machine for SAA/AAA Module. -+ -+ Declaration of functions and finite state machine for SAA/AAA Module. -+*/ -+ -+/* -+** Log: aa_fsm.h -+ * -+ * 10 13 2011 cp.wu -+ * [MT6620 Wi-Fi][Driver] Reduce join failure count limit to 2 for faster re-join for other BSS -+ * 1. short join failure count limit to 2 -+ * 2. treat join timeout as kind of join failure as well -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 21 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * refine TX-DONE callback. -+ * -+ * 06 11 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) migrate assoc.c. -+ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness -+ * 3) add configuration options for CNM_MEM and RSN modules -+ * 4) add data path for management frames -+ * 5) eliminate rPacketInfo of MSDU_INFO_T -+ * -+ * 06 10 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add buildable & linkable ais_fsm.c -+ * -+ * related reference are still waiting to be resolved -+ * -+ * 06 07 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add aa_fsm.h, ais_fsm.h, bss.h, mib.h and scan.h. -+ * -+ * 03 10 2010 kevin.huang -+ * [BORA00000654][WIFISYS][New Feature] CNM Module - Ch Manager Support -+ * -+ * Add Channel Manager for arbitration of JOIN and SCAN Req -+ * -+ * 02 04 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Add AAA Module Support, Revise Net Type to Net Type Index for array lookup -+ * -+ * 01 11 2010 kevin.huang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Add Deauth and Disassoc Handler -+ * -+ * Nov 24 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Revise MGMT Handler with Retain Status -+ * -+ * Nov 23 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * -+*/ -+ -+#ifndef _AA_FSM_H -+#define _AA_FSM_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+/* Retry interval for retransmiting authentication-request MMPDU. */ -+#define TX_AUTHENTICATION_RETRY_TIMEOUT_TU 100 /* TU. */ -+ -+/* Retry interval for retransmiting association-request MMPDU. */ -+#define TX_ASSOCIATION_RETRY_TIMEOUT_TU 100 /* TU. */ -+ -+/* Wait for a response to a transmitted authentication-request MMPDU. */ -+#define DOT11_AUTHENTICATION_RESPONSE_TIMEOUT_TU 512 /* TU. */ -+ -+/* Wait for a response to a transmitted association-request MMPDU. */ -+#define DOT11_ASSOCIATION_RESPONSE_TIMEOUT_TU 512 /* TU. */ -+ -+/* The maximum time to wait for JOIN process complete. */ -+#define JOIN_FAILURE_TIMEOUT_BEACON_INTERVAL 20 /* Beacon Interval, 20 * 100TU = 2 sec. */ -+ -+/* Retry interval for next JOIN request. */ -+#define JOIN_RETRY_INTERVAL_SEC 10 /* Seconds */ -+ -+/* Maximum Retry Count for accept a JOIN request. */ -+#define JOIN_MAX_RETRY_FAILURE_COUNT 2 /* Times */ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+typedef enum _ENUM_AA_STATE_T { -+ AA_STATE_IDLE = 0, -+ SAA_STATE_SEND_AUTH1, -+ SAA_STATE_WAIT_AUTH2, -+ SAA_STATE_SEND_AUTH3, -+ SAA_STATE_WAIT_AUTH4, -+ SAA_STATE_SEND_ASSOC1, -+ SAA_STATE_WAIT_ASSOC2, -+ AAA_STATE_SEND_AUTH2, -+ AAA_STATE_SEND_AUTH4, /* We may not use, because P2P GO didn't support WEP and 11r */ -+ AAA_STATE_SEND_ASSOC2, -+ AA_STATE_RESOURCE, /* A state for debugging the case of out of msg buffer. */ -+ AA_STATE_NUM -+} ENUM_AA_STATE_T; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+/*----------------------------------------------------------------------------*/ -+/* Routines in saa_fsm.c */ -+/*----------------------------------------------------------------------------*/ -+VOID -+saaFsmSteps(IN P_ADAPTER_T prAdapter, -+ IN P_STA_RECORD_T prStaRec, IN ENUM_AA_STATE_T eNextState, IN P_SW_RFB_T prRetainedSwRfb); -+ -+WLAN_STATUS -+saaFsmSendEventJoinComplete(IN P_ADAPTER_T prAdapter, -+ WLAN_STATUS rJoinStatus, P_STA_RECORD_T prStaRec, P_SW_RFB_T prSwRfb); -+ -+VOID saaFsmRunEventStart(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); -+ -+WLAN_STATUS -+saaFsmRunEventTxDone(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus); -+ -+VOID saaFsmRunEventTxReqTimeOut(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec); -+ -+VOID saaFsmRunEventRxRespTimeOut(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec); -+ -+VOID saaFsmRunEventRxAuth(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); -+ -+WLAN_STATUS saaFsmRunEventRxAssoc(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); -+ -+WLAN_STATUS saaFsmRunEventRxDeauth(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); -+ -+WLAN_STATUS saaFsmRunEventRxDisassoc(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); -+ -+VOID saaFsmRunEventAbort(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); -+ -+/*----------------------------------------------------------------------------*/ -+/* Routines in aaa_fsm.c */ -+/*----------------------------------------------------------------------------*/ -+VOID aaaFsmRunEventRxAuth(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); -+ -+WLAN_STATUS aaaFsmRunEventRxAssoc(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); -+ -+WLAN_STATUS -+aaaFsmRunEventTxDone(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus); -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif /* _AA_FSM_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/ais_fsm.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/ais_fsm.h -new file mode 100644 -index 000000000000..b771bdacf2c6 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/ais_fsm.h -@@ -0,0 +1,573 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/mgmt/ais_fsm.h#1 -+*/ -+ -+/*! \file ais_fsm.h -+ \brief Declaration of functions and finite state machine for AIS Module. -+ -+ Declaration of functions and finite state machine for AIS Module. -+*/ -+ -+/* -+** Log: ais_fsm.h -+ * -+ * 11 22 2011 cp.wu -+ * [WCXRP00001120] [MT6620 Wi-Fi][Driver] Modify roaming to AIS state transition -+ * from synchronous to asynchronous approach to avoid incomplete state termination -+ * 1. change RDD related compile option brace position. -+ * 2. when roaming is triggered, ask AIS to transit immediately only when AIS -+ * is in Normal TR state without join timeout timer ticking -+ * 3. otherwise, insert AIS_REQUEST into pending request queue -+ * -+ * 04 25 2011 cp.wu -+ * [WCXRP00000676] [MT6620 Wi-Fi][Driver] AIS to reduce request channel period from 5 seconds to 2 seconds -+ * channel interval for joining is shortened to 2 seconds to avoid interruption of concurrent operating network. -+ * -+ * 02 26 2011 tsaiyuan.hsu -+ * [WCXRP00000391] [MT6620 Wi-Fi][FW] Add Roaming Support -+ * not send disassoc or deauth to leaving AP so as to improve performace of roaming. -+ * -+ * 02 22 2011 cp.wu -+ * [WCXRP00000487] [MT6620 Wi-Fi][Driver][AIS] Serve scan and connect request with -+ * a queue-based approach to improve response time for scanning request -+ * handle SCAN and RECONNECT with a FIFO approach. -+ * -+ * 01 27 2011 tsaiyuan.hsu -+ * [WCXRP00000392] [MT6620 Wi-Fi][Driver] Add Roaming Support -+ * add roaming fsm -+ * 1. not support 11r, only use strength of signal to determine roaming. -+ * 2. not enable CFG_SUPPORT_ROAMING until completion of full test. -+ * 3. in 6620, adopt work-around to avoid sign extension problem of cck of hw -+ * 4. assume that change of link quality in smooth way. -+ * -+ * 01 14 2011 cp.wu -+ * [WCXRP00000359] [MT6620 Wi-Fi][Driver] add an extra state to ensure DEAUTH frame is always sent -+ * Add an extra state to guarantee DEAUTH frame is sent then connect to new BSS. -+ * This change is due to WAPI AP needs DEAUTH frame as a necessary step in handshaking protocol. -+ * -+ * 11 25 2010 cp.wu -+ * [WCXRP00000208] [MT6620 Wi-Fi][Driver] Add scanning with specified SSID to AIS FSM -+ * add scanning with specified SSID facility to AIS-FSM -+ * -+ * 11 01 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check -+ * [WCXRP00000150] [MT6620 Wi-Fi][Driver] Add implementation for querying current TX rate from firmware auto rate module -+ * 1) Query link speed (TX rate) from firmware directly with buffering mechanism to reduce overhead -+ * 2) Remove CNM CH-RECOVER event handling -+ * 3) cfg read/write API renamed with kal prefix for unified naming rules. -+ * -+ * 09 06 2010 cp.wu -+ * NULL -+ * 1) initialize for correct parameter even for disassociation. -+ * 2) AIS-FSM should have a limit on trials to build connection -+ * -+ * 09 03 2010 kevin.huang -+ * NULL -+ * Refine #include sequence and solve recursive/nested #include issue -+ * -+ * 08 25 2010 cp.wu -+ * NULL -+ * [AIS-FSM] IBSS no longer needs to acquire channel for beaconing, RLM/CNM will handle -+ * the channel switching when BSS information is updated -+ * -+ * 08 12 2010 kevin.huang -+ * NULL -+ * Refine bssProcessProbeRequest() and bssSendBeaconProbeResponse() -+ * -+ * 08 12 2010 cp.wu -+ * NULL -+ * [AIS-FSM] honor registry setting for adhoc running mode. (A/B/G) -+ * -+ * 08 03 2010 cp.wu -+ * NULL -+ * surpress compilation warning. -+ * -+ * 07 30 2010 cp.wu -+ * NULL -+ * 1) BoW wrapper: use definitions instead of hard-coded constant for error code -+ * 2) AIS-FSM: eliminate use of desired RF parameters, use prTargetBssDesc instead -+ * 3) add handling for RX_PKT_DESTINATION_HOST_WITH_FORWARD for GO-broadcast frames -+ * -+ * 07 26 2010 cp.wu -+ * -+ * AIS-FSM: when scan request is coming in the 1st 5 seconds of channel privilege period, -+ * just pend it til 5-sec. period finishes -+ * -+ * 07 26 2010 cp.wu -+ * -+ * AIS-FSM FIX: return channel privilege even when the privilege is not granted yet -+ * QM: qmGetFrameAction() won't assert when corresponding STA-REC index is not found -+ * -+ * 07 23 2010 cp.wu -+ * -+ * add AIS-FSM handling for beacon timeout event. -+ * -+ * 07 21 2010 cp.wu -+ * -+ * separate AIS-FSM states into different cases of channel request. -+ * -+ * 07 21 2010 cp.wu -+ * -+ * 1) change BG_SCAN to ONLINE_SCAN for consistent term -+ * 2) only clear scanning result when scan is permitted to do -+ * -+ * 07 19 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration. -+ * Add Ad-Hoc support to AIS-FSM -+ * -+ * 07 14 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration. -+ * Refine AIS-FSM by divided into more states -+ * -+ * 07 09 2010 cp.wu -+ * -+ * 1) separate AIS_FSM state for two kinds of scanning. (OID triggered scan, and scan-for-connection) -+ * 2) eliminate PRE_BSS_DESC_T, Beacon/PrebResp is now parsed in single pass -+ * 3) implment DRV-SCN module, currently only accepts single scan request, -+ * other request will be directly dropped by returning BUSY -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 07 01 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * AIS-FSM integration with CNM channel request messages -+ * -+ * 07 01 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * implementation of DRV-SCN and related mailbox message handling. -+ * -+ * 06 10 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add buildable & linkable ais_fsm.c -+ * -+ * related reference are still waiting to be resolved -+ * -+ * 06 09 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add definitions for module migration. -+ * -+ * 06 07 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add aa_fsm.h, ais_fsm.h, bss.h, mib.h and scan.h. -+ * -+ * 05 12 2010 kevin.huang -+ * [BORA00000794][WIFISYS][New Feature]Power Management Support -+ * Add Power Management - Legacy PS-POLL support. -+ * -+ * 04 23 2010 wh.su -+ * [BORA00000605][WIFISYS] Phase3 Integration -+ * reduce the background ssid idle time min and max value -+ * -+ * 04 19 2010 kevin.huang -+ * [BORA00000714][WIFISYS][New Feature]Beacon Timeout Support -+ * Add Beacon Timeout Support -+ * * and will send Null frame to diagnose connection -+ * -+ * 03 16 2010 kevin.huang -+ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support -+ * Add AdHoc Mode -+ * -+ * 03 10 2010 kevin.huang -+ * [BORA00000654][WIFISYS][New Feature] CNM Module - Ch Manager Support -+ * -+ * * Add Channel Manager for arbitration of JOIN and SCAN Req -+ * -+ * 02 26 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Remove CFG_TEST_VIRTUAL_CMD and add support of Driver STA_RECORD_T activation -+ * -+ * 02 23 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Support dynamic channel selection -+ * -+ * 02 04 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Add AAA Module Support, Revise Net Type to Net Type Index for array lookup -+ * -+ * 01 11 2010 kevin.huang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Add Deauth and Disassoc Handler -+ * -+ * 01 07 2010 kevin.huang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Add Media disconnect indication and related postpone functions -+ * -+ * Dec 3 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Add aisFsmRunEventJoinComplete() -+ * -+ * Nov 25 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Add Virtual CMD & RESP for testing CMD PATH -+ * -+ * Nov 23 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * add aisFsmInitializeConnectionSettings() -+ * -+ * Nov 20 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Add CFG_TEST_MGMT_FSM for aisFsmTest() -+ * -+ * Nov 18 2009 mtk01104 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Add function prototype of aisFsmInit() -+ * -+ * Nov 16 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * -+*/ -+ -+#ifndef _AIS_FSM_H -+#define _AIS_FSM_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+#define AIS_BG_SCAN_INTERVAL_MIN_SEC 2 /* 30 // exponential to 960 */ -+#define AIS_BG_SCAN_INTERVAL_MAX_SEC 2 /* 960 // 16min */ -+ -+#define AIS_DELAY_TIME_OF_DISC_SEC_ONLY_2G4 2 /* 2.4G scan need about 0.5s, so delay 2s to reconnect is enough */ -+#define AIS_DELAY_TIME_OF_DISC_SEC_DUALBAND 5 /* 2.4G scan need about 3.3s, so delay 5s to reconnect is enough */ -+ -+#define AIS_IBSS_ALONE_TIMEOUT_SEC 20 /* seconds */ -+ -+#define AIS_BEACON_TIMEOUT_COUNT_ADHOC 30 -+#define AIS_BEACON_TIMEOUT_COUNT_INFRA 10 -+#define AIS_BEACON_TIMEOUT_GUARD_TIME_SEC 1 /* Second */ -+ -+#define AIS_BEACON_MAX_TIMEOUT_TU 100 -+#define AIS_BEACON_MIN_TIMEOUT_TU 5 -+#define AIS_BEACON_MAX_TIMEOUT_VALID TRUE -+#define AIS_BEACON_MIN_TIMEOUT_VALID TRUE -+ -+#define AIS_BMC_MAX_TIMEOUT_TU 100 -+#define AIS_BMC_MIN_TIMEOUT_TU 5 -+#define AIS_BMC_MAX_TIMEOUT_VALID TRUE -+#define AIS_BMC_MIN_TIMEOUT_VALID TRUE -+ -+#define AIS_JOIN_CH_GRANT_THRESHOLD 10 -+#define AIS_JOIN_CH_REQUEST_INTERVAL 3000 -+ -+#define AIS_SCN_DONE_TIMEOUT_SEC 30 /* 15 for 2.4G + 5G */ /* 5 */ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+typedef enum _ENUM_AIS_STATE_T { -+ AIS_STATE_IDLE = 0, -+ AIS_STATE_SEARCH, -+ AIS_STATE_SCAN, -+ AIS_STATE_ONLINE_SCAN, -+ AIS_STATE_LOOKING_FOR, -+ AIS_STATE_WAIT_FOR_NEXT_SCAN, -+ AIS_STATE_REQ_CHANNEL_JOIN, -+ AIS_STATE_JOIN, -+ AIS_STATE_IBSS_ALONE, -+ AIS_STATE_IBSS_MERGE, -+ AIS_STATE_NORMAL_TR, -+ AIS_STATE_DISCONNECTING, -+ AIS_STATE_REQ_REMAIN_ON_CHANNEL, -+ AIS_STATE_REMAIN_ON_CHANNEL, -+ AIS_STATE_NUM -+} ENUM_AIS_STATE_T; -+ -+typedef struct _MSG_AIS_ABORT_T { -+ MSG_HDR_T rMsgHdr; /* Must be the first member */ -+ UINT_8 ucReasonOfDisconnect; -+ BOOLEAN fgDelayIndication; -+} MSG_AIS_ABORT_T, *P_MSG_AIS_ABORT_T; -+ -+typedef struct _MSG_AIS_IBSS_PEER_FOUND_T { -+ MSG_HDR_T rMsgHdr; /* Must be the first member */ -+ UINT_8 ucNetTypeIndex; -+ BOOLEAN fgIsMergeIn; /* TRUE: Merge In, FALSE: Merge Out */ -+ P_STA_RECORD_T prStaRec; -+} MSG_AIS_IBSS_PEER_FOUND_T, *P_MSG_AIS_IBSS_PEER_FOUND_T; -+ -+typedef enum _ENUM_AIS_REQUEST_TYPE_T { -+ AIS_REQUEST_SCAN, -+ AIS_REQUEST_RECONNECT, -+ AIS_REQUEST_ROAMING_SEARCH, -+ AIS_REQUEST_ROAMING_CONNECT, -+ AIS_REQUEST_REMAIN_ON_CHANNEL, -+ AIS_REQUEST_NUM -+} ENUM_AIS_REQUEST_TYPE_T; -+ -+typedef struct _AIS_REQ_HDR_T { -+ LINK_ENTRY_T rLinkEntry; -+ ENUM_AIS_REQUEST_TYPE_T eReqType; -+} AIS_REQ_HDR_T, *P_AIS_REQ_HDR_T; -+ -+typedef struct _AIS_REQ_CHNL_INFO { -+ ENUM_BAND_T eBand; -+ ENUM_CHNL_EXT_T eSco; -+ UINT_8 ucChannelNum; -+ UINT_32 u4DurationMs; -+ UINT_64 u8Cookie; -+} AIS_REQ_CHNL_INFO, *P_AIS_REQ_CHNL_INFO; -+ -+typedef struct _AIS_MGMT_TX_REQ_INFO_T { -+ BOOLEAN fgIsMgmtTxRequested; -+ P_MSDU_INFO_T prMgmtTxMsdu; -+ UINT_64 u8Cookie; -+} AIS_MGMT_TX_REQ_INFO_T, *P_AIS_MGMT_TX_REQ_INFO_T; -+ -+typedef struct _AIS_FSM_INFO_T { -+ ENUM_AIS_STATE_T ePreviousState; -+ ENUM_AIS_STATE_T eCurrentState; -+ -+ BOOLEAN fgTryScan; -+ -+ BOOLEAN fgIsInfraChannelFinished; -+ BOOLEAN fgIsChannelRequested; -+ BOOLEAN fgIsChannelGranted; -+ -+#if CFG_SUPPORT_ROAMING -+ BOOLEAN fgIsRoamingScanPending; -+#endif /* CFG_SUPPORT_ROAMING */ -+ -+ UINT_8 ucAvailableAuthTypes; /* Used for AUTH_MODE_AUTO_SWITCH */ -+ -+ P_BSS_DESC_T prTargetBssDesc; /* For destination */ -+ -+ P_STA_RECORD_T prTargetStaRec; /* For JOIN Abort */ -+ -+ UINT_32 u4SleepInterval; -+ -+ TIMER_T rBGScanTimer; -+ -+ TIMER_T rIbssAloneTimer; -+ -+ TIMER_T rIndicationOfDisconnectTimer; -+ -+ TIMER_T rJoinTimeoutTimer; -+ -+ TIMER_T rChannelTimeoutTimer; -+ -+ TIMER_T rScanDoneTimer; -+ -+ TIMER_T rDeauthDoneTimer; -+ -+ UINT_8 ucSeqNumOfReqMsg; -+ UINT_8 ucSeqNumOfChReq; -+ UINT_8 ucSeqNumOfScanReq; -+ -+ UINT_32 u4ChGrantedInterval; -+ -+ UINT_8 ucConnTrialCount; -+ -+ UINT_8 ucScanSSIDLen; -+ UINT_8 aucScanSSID[ELEM_MAX_LEN_SSID]; -+ -+ UINT_32 u4ScanIELength; -+ UINT_8 aucScanIEBuf[MAX_IE_LENGTH]; -+ -+ /* Pending Request List */ -+ LINK_T rPendingReqList; -+ -+ /* Join Request Timestamp */ -+ OS_SYSTIME rJoinReqTime; -+ -+ /* for cfg80211 REMAIN_ON_CHANNEL support */ -+ AIS_REQ_CHNL_INFO rChReqInfo; -+ -+ /* Mgmt tx related. */ -+ AIS_MGMT_TX_REQ_INFO_T rMgmtTxInfo; -+ -+ /* Packet filter for AIS module. */ -+ UINT_32 u4AisPacketFilter; -+ -+} AIS_FSM_INFO_T, *P_AIS_FSM_INFO_T; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+#define aisChangeMediaState(_prAdapter, _eNewMediaState) \ -+ (_prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX].eConnectionState = (_eNewMediaState)) -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+VOID aisInitializeConnectionSettings(IN P_ADAPTER_T prAdapter, IN P_REG_INFO_T prRegInfo); -+ -+VOID aisFsmInit(IN P_ADAPTER_T prAdapter); -+ -+VOID aisFsmUninit(IN P_ADAPTER_T prAdapter); -+ -+VOID aisFsmStateInit_JOIN(IN P_ADAPTER_T prAdapter, P_BSS_DESC_T prBssDesc); -+ -+BOOLEAN aisFsmStateInit_RetryJOIN(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec); -+ -+VOID aisFsmStateInit_IBSS_ALONE(IN P_ADAPTER_T prAdapter); -+ -+VOID aisFsmStateInit_IBSS_MERGE(IN P_ADAPTER_T prAdapter, P_BSS_DESC_T prBssDesc); -+ -+VOID aisFsmStateAbort(IN P_ADAPTER_T prAdapter, UINT_8 ucReasonOfDisconnect, BOOLEAN fgDelayIndication); -+ -+VOID aisFsmStateAbort_JOIN(IN P_ADAPTER_T prAdapter); -+ -+VOID aisFsmStateAbort_SCAN(IN P_ADAPTER_T prAdapter); -+ -+VOID aisFsmStateAbort_NORMAL_TR(IN P_ADAPTER_T prAdapter); -+ -+VOID aisFsmStateAbort_IBSS(IN P_ADAPTER_T prAdapter); -+#if 0 -+VOID aisFsmSetChannelInfo(IN P_ADAPTER_T prAdapter, IN P_MSG_SCN_SCAN_REQ ScanReqMsg, IN ENUM_AIS_STATE_T CurrentState); -+#endif -+VOID aisFsmSteps(IN P_ADAPTER_T prAdapter, ENUM_AIS_STATE_T eNextState); -+ -+/*----------------------------------------------------------------------------*/ -+/* Mailbox Message Handling */ -+/*----------------------------------------------------------------------------*/ -+VOID aisFsmRunEventScanDone(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); -+ -+VOID aisFsmRunEventAbort(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); -+ -+VOID aisFsmRunEventJoinComplete(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); -+ -+VOID aisFsmRunEventFoundIBSSPeer(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); -+ -+VOID aisFsmRunEventRemainOnChannel(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); -+ -+VOID aisFsmRunEventCancelRemainOnChannel(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); -+ -+/*----------------------------------------------------------------------------*/ -+/* Handling for Ad-Hoc Network */ -+/*----------------------------------------------------------------------------*/ -+VOID aisFsmCreateIBSS(IN P_ADAPTER_T prAdapter); -+ -+VOID aisFsmMergeIBSS(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec); -+ -+/*----------------------------------------------------------------------------*/ -+/* Handling of Incoming Mailbox Message from CNM */ -+/*----------------------------------------------------------------------------*/ -+VOID aisFsmRunEventChGrant(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); -+ -+/*----------------------------------------------------------------------------*/ -+/* Generating Outgoing Mailbox Message to CNM */ -+/*----------------------------------------------------------------------------*/ -+VOID aisFsmReleaseCh(IN P_ADAPTER_T prAdapter); -+ -+/*----------------------------------------------------------------------------*/ -+/* Event Indication */ -+/*----------------------------------------------------------------------------*/ -+VOID -+aisIndicationOfMediaStateToHost(IN P_ADAPTER_T prAdapter, -+ ENUM_PARAM_MEDIA_STATE_T eConnectionState, BOOLEAN fgDelayIndication); -+ -+VOID aisPostponedEventOfDisconnTimeout(IN P_ADAPTER_T prAdapter, ULONG ulParam); -+ -+VOID aisUpdateBssInfoForJOIN(IN P_ADAPTER_T prAdapter, P_STA_RECORD_T prStaRec, P_SW_RFB_T prAssocRspSwRfb); -+ -+VOID aisUpdateBssInfoForCreateIBSS(IN P_ADAPTER_T prAdapter); -+ -+VOID aisUpdateBssInfoForMergeIBSS(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec); -+ -+BOOLEAN aisValidateProbeReq(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, OUT PUINT_32 pu4ControlFlags); -+ -+WLAN_STATUS -+aisFsmRunEventMgmtFrameTxDone(IN P_ADAPTER_T prAdapter, -+ IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus); -+ -+/*----------------------------------------------------------------------------*/ -+/* Disconnection Handling */ -+/*----------------------------------------------------------------------------*/ -+VOID aisFsmDisconnect(IN P_ADAPTER_T prAdapter, IN BOOLEAN fgDelayIndication); -+ -+/*----------------------------------------------------------------------------*/ -+/* Event Handling */ -+/*----------------------------------------------------------------------------*/ -+VOID aisBssBeaconTimeout(IN P_ADAPTER_T prAdapter); -+ -+VOID aisBssSecurityChanged(IN P_ADAPTER_T prAdapter); -+ -+WLAN_STATUS -+aisDeauthXmitComplete(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus); -+ -+#if CFG_SUPPORT_ROAMING -+VOID aisFsmRunEventRoamingDiscovery(IN P_ADAPTER_T prAdapter, UINT_32 u4ReqScan); -+ -+ENUM_AIS_STATE_T aisFsmRoamingScanResultsUpdate(IN P_ADAPTER_T prAdapter); -+ -+VOID aisFsmRoamingDisconnectPrevAP(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prTargetStaRec); -+ -+VOID aisUpdateBssInfoForRoamingAP(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN P_SW_RFB_T prAssocRspSwRfb); -+#endif /*CFG_SUPPORT_ROAMING */ -+ -+/*----------------------------------------------------------------------------*/ -+/* Timeout Handling */ -+/*----------------------------------------------------------------------------*/ -+VOID aisFsmRunEventBGSleepTimeOut(IN P_ADAPTER_T prAdapter, ULONG ulParam); -+ -+VOID aisFsmRunEventIbssAloneTimeOut(IN P_ADAPTER_T prAdapter, ULONG ulParam); -+ -+VOID aisFsmRunEventJoinTimeout(IN P_ADAPTER_T prAdapter, ULONG ulParam); -+ -+VOID aisFsmRunEventChannelTimeout(IN P_ADAPTER_T prAdapter, ULONG ulParam); -+ -+VOID aisFsmRunEventScanDoneTimeOut(IN P_ADAPTER_T prAdapter, ULONG ulParam); -+ -+VOID aisFsmRunEventDeauthTimeout(IN P_ADAPTER_T prAdapter, ULONG ulParam); -+ -+/*----------------------------------------------------------------------------*/ -+/* OID/IOCTL Handling */ -+/*----------------------------------------------------------------------------*/ -+VOID aisFsmScanRequest(IN P_ADAPTER_T prAdapter, IN P_PARAM_SSID_T prSsid, IN PUINT_8 pucIe, IN UINT_32 u4IeLength); -+ -+/*----------------------------------------------------------------------------*/ -+/* Internal State Checking */ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN aisFsmIsRequestPending(IN P_ADAPTER_T prAdapter, IN ENUM_AIS_REQUEST_TYPE_T eReqType, IN BOOLEAN bRemove); -+ -+P_AIS_REQ_HDR_T aisFsmGetNextRequest(IN P_ADAPTER_T prAdapter); -+ -+BOOLEAN aisFsmInsertRequest(IN P_ADAPTER_T prAdapter, IN ENUM_AIS_REQUEST_TYPE_T eReqType); -+ -+VOID aisFsmFlushRequest(IN P_ADAPTER_T prAdapter); -+ -+WLAN_STATUS -+aisFuncTxMgmtFrame(IN P_ADAPTER_T prAdapter, -+ IN P_AIS_MGMT_TX_REQ_INFO_T prMgmtTxReqInfo, IN P_MSDU_INFO_T prMgmtTxMsdu, IN UINT_64 u8Cookie); -+ -+VOID aisFsmRunEventMgmtFrameTx(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); -+ -+VOID aisFuncValidateRxActionFrame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); -+ -+#if defined(CFG_TEST_MGMT_FSM) && (CFG_TEST_MGMT_FSM != 0) -+VOID aisTest(VOID); -+#endif /* CFG_TEST_MGMT_FSM */ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif /* _AIS_FSM_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/assoc.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/assoc.h -new file mode 100644 -index 000000000000..70b32bca102b ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/assoc.h -@@ -0,0 +1,112 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/mgmt/assoc.h#1 -+*/ -+ -+/*! \file assoc.h -+ \brief This file contains the ASSOC REQ/RESP of -+ IEEE 802.11 family for MediaTek 802.11 Wireless LAN Adapters. -+*/ -+ -+/* -+** Log: assoc.h -+ * -+ * 09 03 2010 kevin.huang -+ * NULL -+ * Refine #include sequence and solve recursive/nested #include issue -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 17 2010 yuche.tsai -+ * [WPD00003839][MT6620 5931][P2P] Feature migration -+ * Add assocCheckTxReAssocRespFrame() proto type for P2P usage. -+ * -+ * 06 11 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) migrate assoc.c. -+ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness -+ * 3) add configuration options for CNM_MEM and RSN modules -+ * 4) add data path for management frames -+ * 5) eliminate rPacketInfo of MSDU_INFO_T -+ * -+ * 06 10 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add buildable & linkable ais_fsm.c -+ * -+ * related reference are still waiting to be resolved -+ * -+*/ -+ -+#ifndef _ASSOC_H -+#define _ASSOC_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+/*----------------------------------------------------------------------------*/ -+/* Routines in assoc.c */ -+/*----------------------------------------------------------------------------*/ -+UINT_16 assocBuildCapabilityInfo(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec); -+ -+WLAN_STATUS assocSendReAssocReqFrame(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec); -+ -+WLAN_STATUS assocCheckTxReAssocReqFrame(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); -+ -+WLAN_STATUS assocCheckTxReAssocRespFrame(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); -+ -+WLAN_STATUS -+assocCheckRxReAssocRspFrameStatus(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, OUT PUINT_16 pu2StatusCode); -+ -+WLAN_STATUS assocSendDisAssocFrame(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN UINT_16 u2ReasonCode); -+ -+WLAN_STATUS -+assocProcessRxDisassocFrame(IN P_ADAPTER_T prAdapter, -+ IN P_SW_RFB_T prSwRfb, IN UINT_8 aucBSSID[], OUT PUINT_16 pu2ReasonCode); -+ -+WLAN_STATUS assocProcessRxAssocReqFrame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, OUT PUINT_16 pu2StatusCode); -+ -+WLAN_STATUS assocSendReAssocRespFrame(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec); -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif /* _ASSOC_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/auth.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/auth.h -new file mode 100644 -index 000000000000..4f76f03324dd ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/auth.h -@@ -0,0 +1,125 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/mgmt/auth.h#1 -+*/ -+ -+/*! \file auth.h -+ \brief This file contains the authentication REQ/RESP of -+ IEEE 802.11 family for MediaTek 802.11 Wireless LAN Adapters. -+*/ -+ -+/* -+** Log: auth.h -+ * -+ * 04 21 2011 terry.wu -+ * [WCXRP00000674] [MT6620 Wi-Fi][Driver] Refine AAA authSendAuthFrame -+ * Add network type parameter to authSendAuthFrame. -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 14 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add management dispatching function table. -+ * -+ * 06 11 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * auth.c is migrated. -+ * -+ * 06 10 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add buildable & linkable ais_fsm.c -+ * -+ * related reference are still waiting to be resolved -+ * -+*/ -+ -+#ifndef _AUTH_H -+#define _AUTH_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+/*----------------------------------------------------------------------------*/ -+/* Routines in auth.c */ -+/*----------------------------------------------------------------------------*/ -+VOID authAddIEChallengeText(IN P_ADAPTER_T prAdapter, IN OUT P_MSDU_INFO_T prMsduInfo); -+ -+#if !CFG_SUPPORT_AAA -+WLAN_STATUS authSendAuthFrame(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN UINT_16 u2TransactionSeqNum); -+#else -+WLAN_STATUS -+authSendAuthFrame(IN P_ADAPTER_T prAdapter, -+ IN P_STA_RECORD_T prStaRec, -+ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, -+ IN P_SW_RFB_T prFalseAuthSwRfb, IN UINT_16 u2TransactionSeqNum, IN UINT_16 u2StatusCode); -+#endif /* CFG_SUPPORT_AAA */ -+ -+WLAN_STATUS authCheckTxAuthFrame(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo, IN UINT_16 u2TransactionSeqNum); -+ -+WLAN_STATUS authCheckRxAuthFrameTransSeq(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); -+ -+WLAN_STATUS -+authCheckRxAuthFrameStatus(IN P_ADAPTER_T prAdapter, -+ IN P_SW_RFB_T prSwRfb, IN UINT_16 u2TransactionSeqNum, OUT PUINT_16 pu2StatusCode); -+ -+VOID authHandleIEChallengeText(P_ADAPTER_T prAdapter, P_SW_RFB_T prSwRfb, P_IE_HDR_T prIEHdr); -+ -+WLAN_STATUS authProcessRxAuth2_Auth4Frame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); -+ -+WLAN_STATUS -+authSendDeauthFrame(IN P_ADAPTER_T prAdapter, -+ IN P_STA_RECORD_T prStaRec, -+ IN P_SW_RFB_T prClassErrSwRfb, IN UINT_16 u2ReasonCode, IN PFN_TX_DONE_HANDLER pfTxDoneHandler); -+ -+WLAN_STATUS authProcessRxDeauthFrame(IN P_SW_RFB_T prSwRfb, IN UINT_8 aucBSSID[], OUT PUINT_16 pu2ReasonCode); -+ -+WLAN_STATUS -+authProcessRxAuth1Frame(IN P_ADAPTER_T prAdapter, -+ IN P_SW_RFB_T prSwRfb, -+ IN UINT_8 aucExpectedBSSID[], -+ IN UINT_16 u2ExpectedAuthAlgNum, -+ IN UINT_16 u2ExpectedTransSeqNum, OUT PUINT_16 pu2ReturnStatusCode); -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif /* _AUTH_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/bow_fsm.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/bow_fsm.h -new file mode 100644 -index 000000000000..5995d133a6cd ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/bow_fsm.h -@@ -0,0 +1,184 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/mgmt/bow_fsm.h#1 -+*/ -+ -+/*! \file bow_fsm.h -+ \brief Declaration of functions and finite state machine for BOW Module. -+ -+ Declaration of functions and finite state machine for BOW Module. -+*/ -+ -+/* -+** Log: bow_fsm.h -+ * -+ * 05 22 2011 terry.wu -+ * [WCXRP00000735] [MT6620 Wi-Fi][BoW][FW/Driver] Protect BoW connection establishment -+ * Submit missing BoW header files. -+ * -+ * 03 27 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Support multiple physical link. -+ * -+ * 02 16 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Add bowNotifyAllLinkDisconnected interface and change channel grant procedure for bow starting.. -+ * -+ * 02 15 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Add channel previledge into _BOW_FSM_INFO_T. -+ * -+ * 09 16 2010 chinghwa.yu -+ * NULL -+ * update bowChangeMediaState. -+ * -+ * 08 24 2010 chinghwa.yu -+ * NULL -+ * Update BOW for the 1st time. -+ */ -+ -+#ifndef _BOW_FSM_H -+#define _BOW_FSM_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+#define BOW_BG_SCAN_INTERVAL_MIN_SEC 2 /* 30 // exponential to 960 */ -+#define BOW_BG_SCAN_INTERVAL_MAX_SEC 2 /* 960 // 16min */ -+ -+#define BOW_DELAY_TIME_OF_DISCONNECT_SEC 10 -+ -+#define BOW_BEACON_TIMEOUT_COUNT_STARTING 10 -+#define BOW_BEACON_TIMEOUT_GUARD_TIME_SEC 1 /* Second */ -+ -+#define BOW_BEACON_MAX_TIMEOUT_TU 100 -+#define BOW_BEACON_MIN_TIMEOUT_TU 5 -+#define BOW_BEACON_MAX_TIMEOUT_VALID TRUE -+#define BOW_BEACON_MIN_TIMEOUT_VALID TRUE -+ -+#define BOW_BMC_MAX_TIMEOUT_TU 100 -+#define BOW_BMC_MIN_TIMEOUT_TU 5 -+#define BOW_BMC_MAX_TIMEOUT_VALID TRUE -+#define BOW_BMC_MIN_TIMEOUT_VALID TRUE -+ -+#define BOW_JOIN_CH_GRANT_THRESHOLD 10 -+#define BOW_JOIN_CH_REQUEST_INTERVAL 2000 -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+typedef enum _ENUM_BOW_STATE_T { -+ BOW_STATE_IDLE = 0, -+ BOW_STATE_SEARCH, -+ BOW_STATE_SCAN, -+ BOW_STATE_ONLINE_SCAN, -+ BOW_STATE_LOOKING_FOR, -+ BOW_STATE_WAIT_FOR_NEXT_SCAN, -+ BOW_STATE_REQ_CHANNEL_JOIN, -+ BOW_STATE_REQ_CHANNEL_ALONE, -+ BOW_STATE_REQ_CHANNEL_MERGE, -+ BOW_STATE_JOIN, -+ BOW_STATE_IBSS_ALONE, -+ BOW_STATE_IBSS_MERGE, -+ BOW_STATE_NORMAL_TR, -+ BOW_STATE_NUM -+} ENUM_BOW_STATE_T; -+ -+typedef struct _BOW_FSM_INFO_T { -+ ENUM_BOW_STATE_T ePreviousState; -+ ENUM_BOW_STATE_T eCurrentState; -+ -+ BOOLEAN fgTryScan; -+ -+ /* Channel Privilege */ -+ -+ BOOLEAN fgIsInfraChannelFinished; -+ BOOLEAN fgIsChannelRequested; -+ BOOLEAN fgIsChannelGranted; -+ BOOLEAN fgIsScanPending; -+ UINT_32 u4ChGrantedInterval; -+ -+ UINT_8 ucPrimaryChannel; -+ ENUM_BAND_T eBand; -+ UINT_16 u2BeaconInterval; -+ -+ ENUM_BOW_STATE_T eReturnState; /* Return state after current activity finished or abort. */ -+ ENUM_BOW_STATE_T eForwardState; /* Step to next state if ACTION frame is TX successfully. */ -+ -+ P_BSS_DESC_T prTargetBss; /* BSS of target P2P Device. For Connection/Service Discovery */ -+ -+ P_STA_RECORD_T prTargetStaRec; -+ P_BSS_DESC_T prTargetBssDesc; /* For destination */ -+ -+ UINT_8 aucPeerAddress[6]; -+ -+ UINT_8 ucRole; -+ -+ BOOLEAN fgSupportQoS; -+ -+ BOOLEAN fgIsRsponseProbe; /* Indicate if BOW can response probe request frame. */ -+ -+ /* Sequence number of requested message. */ -+ UINT_8 ucSeqNumOfChReq; -+ UINT_8 ucSeqNumOfReqMsg; -+ UINT_8 ucSeqNumOfScnMsg; -+ UINT_8 ucSeqNumOfScanReq; -+ -+ UINT_8 ucSeqNumOfCancelMsg; -+ -+ UINT_8 ucDialogToken; -+ -+ /* Timer */ -+ TIMER_T rStartingBeaconTimer; /* For device discovery time of each discovery request from user. */ -+ TIMER_T rStartingDiscoveryTimer; -+ TIMER_T rOperationListenTimer; /* For Find phase under operational state. */ -+ TIMER_T rFSMTimer; /* A timer used for Action frame timeout usage. */ -+ TIMER_T rIndicationOfDisconnectTimer; -+ TIMER_T rChGrantedTimer; -+ -+ UINT_8 ucAvailableAuthTypes; /* Used for AUTH_MODE_AUTO_SWITCH */ -+ -+} BOW_FSM_INFO_T, *P_BOW_FSM_INFO_T; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+#define bowChangeMediaState(_prAdapter, _eNewMediaState) \ -+ (_prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_BOW_INDEX].eConnectionState = (_eNewMediaState)) -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/bss.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/bss.h -new file mode 100644 -index 000000000000..0597132b970e ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/bss.h -@@ -0,0 +1,265 @@ -+/* -+** Id: @(#) bss.h -+*/ -+ -+/*! \file "bss.h" -+ \brief In this file we define the function prototype used in BSS/IBSS. -+ -+ The file contains the function declarations and defines for used in BSS/IBSS. -+*/ -+ -+/* -+** Log: bss.h -+ * -+ * 07 17 2012 yuche.tsai -+ * NULL -+ * Let netdev bring up. -+ * -+ * 07 17 2012 yuche.tsai -+ * NULL -+ * Compile no error before trial run. -+ * -+ * 03 02 2012 terry.wu -+ * NULL -+ * Sync CFG80211 modification from branch 2,2. -+ * -+ * 09 14 2011 yuche.tsai -+ * NULL -+ * Add P2P IE in assoc response. -+ * -+ * 03 19 2011 yuche.tsai -+ * [WCXRP00000581] [Volunteer Patch][MT6620][Driver] P2P IE in Assoc Req Issue -+ * Make assoc req to append P2P IE if wifi direct is enabled. -+ * -+ * 03 02 2011 wh.su -+ * [WCXRP00000448] [MT6620 Wi-Fi][Driver] Fixed WSC IE not send out at probe request -+ * Add code to send beacon and probe response WSC IE at Auto GO. -+ * -+ * 02 23 2011 eddie.chen -+ * [WCXRP00000463] [MT6620 Wi-Fi][FW/Driver][Hotspot] Cannot update WMM PS STA's partital bitmap -+ * Fix parsing WMM INFO and bmp delivery bitmap definition. -+ * -+ * 01 31 2011 george.huang -+ * [WCXRP00000333] [MT5931][FW] support SRAM power control drivers -+ * Extend TIM PVB, from 2 to 3 octets. -+ * -+ * 11 29 2010 cp.wu -+ * [WCXRP00000210] [MT6620 Wi-Fi][Driver][FW] Set RCPI value in STA_REC for -+ * initial TX rate selection of auto-rate algorithm -+ * update ucRcpi of STA_RECORD_T for AIS when -+ * 1) Beacons for IBSS merge is received -+ * 2) Associate Response for a connecting peer is received -+ * -+ * 09 03 2010 kevin.huang -+ * NULL -+ * Refine #include sequence and solve recursive/nested #include issue -+ * -+ * 08 12 2010 kevin.huang -+ * NULL -+ * Update bssProcessProbeRequest() and bssSendBeaconProbeResponse() declarations -+ * -+ * 07 19 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration. -+ * when IBSS is being merged-in, send command packet to PM for connected indication -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 25 2010 george.huang -+ * [WPD00001556]Basic power managemenet function -+ * Create beacon update path, with expose bssUpdateBeaconContent() -+ * -+ * 06 17 2010 yuche.tsai -+ * [WPD00003839][MT6620 5931][P2P] Feature migration -+ * Add CTRL FLAGS for Probe Response. -+ * -+ * 06 09 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add necessary changes to driver data paths. -+ * -+ * 06 07 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add aa_fsm.h, ais_fsm.h, bss.h, mib.h and scan.h. -+ * -+ * 06 04 2010 george.huang -+ * [BORA00000678][MT6620]WiFi LP integration -+ * [PM] Support U-APSD for STA mode -+ * -+ * 05 28 2010 kevin.huang -+ * [BORA00000794][WIFISYS][New Feature]Power Management Support -+ * Add ClientList handling API - bssClearClientList, bssAddStaRecToClientList -+ * -+ * 05 14 2010 kevin.huang -+ * [BORA00000794][WIFISYS][New Feature]Power Management Support -+ * Remove unused typedef. -+ * -+ * 05 12 2010 kevin.huang -+ * [BORA00000794][WIFISYS][New Feature]Power Management Support -+ * Fix file merge error -+ * -+ * 05 12 2010 kevin.huang -+ * [BORA00000794][WIFISYS][New Feature]Power Management Support -+ * Add Power Management - Legacy PS-POLL support. -+ * -+ * 04 19 2010 kevin.huang -+ * [BORA00000714][WIFISYS][New Feature]Beacon Timeout Support -+ * Add Beacon Timeout Support -+ * * * and will send Null frame to diagnose connection -+ * -+ * 03 16 2010 kevin.huang -+ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support -+ * Add AdHoc Mode -+ * -+ * 02 23 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Add DTIM count update while TX Beacon -+ * -+ * 02 04 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Add AAA Module Support, Revise Net Type to Net Type Index for array lookup -+*/ -+ -+#ifndef _BSS_H -+#define _BSS_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+/* NOTE(Kevin): change define for george */ -+/* #define MAX_LEN_TIM_PARTIAL_BMP (((MAX_ASSOC_ID + 1) + 7) / 8) */ /* Required bits = (MAX_ASSOC_ID + 1) */ -+#define MAX_LEN_TIM_PARTIAL_BMP ((CFG_STA_REC_NUM + 7) / 8) -+/* reserve length greater than maximum size of STA_REC */ /* obsoleted: Assume we only use AID:1~15 */ -+ -+/* CTRL FLAGS for Probe Response */ -+#define BSS_PROBE_RESP_USE_P2P_DEV_ADDR BIT(0) -+#define BSS_PROBE_RESP_INCLUDE_P2P_IE BIT(1) -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+#define bssAssignAssocID(_prStaRec) ((_prStaRec)->ucIndex + 1) -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+/*----------------------------------------------------------------------------*/ -+/* Routines for all Operation Modes */ -+/*----------------------------------------------------------------------------*/ -+P_STA_RECORD_T -+bssCreateStaRecFromBssDesc(IN P_ADAPTER_T prAdapter, -+ IN ENUM_STA_TYPE_T eStaType, -+ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_BSS_DESC_T prBssDesc); -+ -+VOID bssComposeNullFrame(IN P_ADAPTER_T prAdapter, IN PUINT_8 pucBuffer, IN P_STA_RECORD_T prStaRec); -+ -+VOID -+bssComposeQoSNullFrame(IN P_ADAPTER_T prAdapter, -+ IN PUINT_8 pucBuffer, IN P_STA_RECORD_T prStaRec, IN UINT_8 ucUP, IN BOOLEAN fgSetEOSP); -+ -+WLAN_STATUS -+bssSendNullFrame(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN PFN_TX_DONE_HANDLER pfTxDoneHandler); -+ -+WLAN_STATUS -+bssSendQoSNullFrame(IN P_ADAPTER_T prAdapter, -+ IN P_STA_RECORD_T prStaRec, IN UINT_8 ucUP, IN PFN_TX_DONE_HANDLER pfTxDoneHandler); -+ -+/*----------------------------------------------------------------------------*/ -+/* Routines for both IBSS(AdHoc) and BSS(AP) */ -+/*----------------------------------------------------------------------------*/ -+VOID bssGenerateExtSuppRate_IE(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); -+ -+VOID -+bssBuildBeaconProbeRespFrameCommonIEs(IN P_MSDU_INFO_T prMsduInfo, IN P_BSS_INFO_T prBssInfo, IN PUINT_8 pucDestAddr); -+ -+VOID -+bssComposeBeaconProbeRespFrameHeaderAndFF(IN PUINT_8 pucBuffer, -+ IN PUINT_8 pucDestAddr, -+ IN PUINT_8 pucOwnMACAddress, -+ IN PUINT_8 pucBSSID, IN UINT_16 u2BeaconInterval, IN UINT_16 u2CapInfo); -+ -+WLAN_STATUS -+bssSendBeaconProbeResponse(IN P_ADAPTER_T prAdapter, -+ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, -+ IN PUINT_8 pucDestAddr, IN UINT_32 u4ControlFlags); -+ -+WLAN_STATUS bssProcessProbeRequest(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); -+ -+VOID bssClearClientList(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prBssInfo); -+ -+VOID bssAddStaRecToClientList(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prBssInfo, IN P_STA_RECORD_T prStaRec); -+ -+VOID bssRemoveStaRecFromClientList(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prBssInfo, IN P_STA_RECORD_T prStaRec); -+ -+/*----------------------------------------------------------------------------*/ -+/* Routines for IBSS(AdHoc) only */ -+/*----------------------------------------------------------------------------*/ -+VOID -+ibssProcessMatchedBeacon(IN P_ADAPTER_T prAdapter, -+ IN P_BSS_INFO_T prBssInfo, IN P_BSS_DESC_T prBssDesc, IN UINT_8 ucRCPI); -+ -+WLAN_STATUS ibssCheckCapabilityForAdHocMode(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBssDesc); -+ -+VOID ibssInitForAdHoc(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prBssInfo); -+ -+WLAN_STATUS bssUpdateBeaconContent(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex); -+ -+/*----------------------------------------------------------------------------*/ -+/* Routines for BSS(AP) only */ -+/*----------------------------------------------------------------------------*/ -+VOID bssInitForAP(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prBssInfo, IN BOOLEAN fgIsRateUpdate); -+ -+VOID bssUpdateDTIMCount(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex); -+ -+VOID bssSetTIMBitmap(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prBssInfo, IN UINT_16 u2AssocId); -+ -+P_STA_RECORD_T bssGetClientByAddress(IN P_BSS_INFO_T prBssInfo, PUINT_8 pucMacAddr); -+ -+/*link function to p2p module for txBcnIETable*/ -+ -+/* WMM-2.2.2 WMM ACI to AC coding */ -+typedef enum _ENUM_ACI_T { -+ ACI_BE = 0, -+ ACI_BK = 1, -+ ACI_VI = 2, -+ ACI_VO = 3, -+ ACI_NUM -+} ENUM_ACI_T, *P_ENUM_ACI_T; -+ -+typedef enum _ENUM_AC_PRIORITY_T { -+ AC_BK_PRIORITY = 0, -+ AC_BE_PRIORITY, -+ AC_VI_PRIORITY, -+ AC_VO_PRIORITY -+} ENUM_AC_PRIORITY_T, *P_ENUM_AC_PRIORITY_T; -+ -+#endif /* _BSS_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/cnm.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/cnm.h -new file mode 100644 -index 000000000000..81b16b588867 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/cnm.h -@@ -0,0 +1,258 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/mgmt/cnm.h#1 -+*/ -+ -+/*! \file "cnm.h" -+ \brief -+*/ -+ -+/* -+** Log: cnm.h -+ * -+ * 06 23 2011 cp.wu -+ * [WCXRP00000798] [MT6620 Wi-Fi][Firmware] Follow-ups for WAPI frequency offset workaround in firmware SCN module -+ * change parameter name from PeerAddr to BSSID -+ * -+ * 06 20 2011 cp.wu -+ * [WCXRP00000798] [MT6620 Wi-Fi][Firmware] Follow-ups for WAPI frequency offset workaround in firmware SCN module -+ * 1. specify target's BSSID when requesting channel privilege. -+ * 2. pass BSSID information to firmware domain -+ * -+ * 04 12 2011 cm.chang -+ * [WCXRP00000634] [MT6620 Wi-Fi][Driver][FW] 2nd BSS will not support 40MHz bandwidth for concurrency -+ * . -+ * -+ * 03 10 2011 cm.chang -+ * [WCXRP00000358] [MT6620 Wi-Fi][Driver] Provide concurrent information for each module -+ * Add some functions to let AIS/Tethering or AIS/BOW be the same channel -+ * -+ * 01 12 2011 cm.chang -+ * [WCXRP00000358] [MT6620 Wi-Fi][Driver] Provide concurrent information for each module -+ * Provide function to decide if BSS can be activated or not -+ * -+ * 12 07 2010 cm.chang -+ * [WCXRP00000239] MT6620 Wi-Fi][Driver][FW] Merge concurrent branch back to maintrunk -+ * 1. BSSINFO include RLM parameter -+ * 2. free all sta records when network is disconnected -+ * -+ * 08 24 2010 cm.chang -+ * NULL -+ * Support RLM initail channel of Ad-hoc, P2P and BOW -+ * -+ * 07 19 2010 cm.chang -+ * -+ * Set RLM parameters and enable CNM channel manager -+ * -+ * 07 13 2010 cm.chang -+ * -+ * Rename MSG_CH_RELEASE_T to MSG_CH_ABORT_T -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 07 08 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Rename MID_MNY_CNM_CH_RELEASE to MID_MNY_CNM_CH_ABORT -+ * -+ * 07 01 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Need bandwidth info when requesting channel privilege -+ * -+ * 07 01 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Modify CNM message handler for new flow -+ * -+ * 05 12 2010 kevin.huang -+ * [BORA00000794][WIFISYS][New Feature]Power Management Support -+ * Add Power Management - Legacy PS-POLL support. -+ * -+ * 05 05 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Add a new function to send abort message -+ * -+ * 03 16 2010 kevin.huang -+ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support -+ * Add AdHoc Mode -+ * -+ * 03 10 2010 kevin.huang -+ * [BORA00000654][WIFISYS][New Feature] CNM Module - Ch Manager Support -+ * Add Channel Manager for arbitration of JOIN and SCAN Req -+ * -+ * 02 08 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Support partial part about cmd basic configuration -+ * -+ * Nov 18 2009 mtk01104 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Add prototype of cnmFsmEventInit() -+ * -+ * Nov 2 2009 mtk01104 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * -+** -+*/ -+ -+#ifndef _CNM_H -+#define _CNM_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+typedef enum _ENUM_CH_REQ_TYPE_T { -+ CH_REQ_TYPE_JOIN, -+ CH_REQ_TYPE_P2P_LISTEN, -+ -+ CH_REQ_TYPE_NUM -+} ENUM_CH_REQ_TYPE_T, *P_ENUM_CH_REQ_TYPE_T; -+ -+typedef struct _MSG_CH_REQ_T { -+ MSG_HDR_T rMsgHdr; /* Must be the first member */ -+ UINT_8 ucNetTypeIndex; -+ UINT_8 ucTokenID; -+ UINT_8 ucPrimaryChannel; -+ ENUM_CHNL_EXT_T eRfSco; -+ ENUM_BAND_T eRfBand; -+ ENUM_CH_REQ_TYPE_T eReqType; -+ UINT_32 u4MaxInterval; /* In unit of ms */ -+ UINT_8 aucBSSID[6]; -+ UINT_8 aucReserved[2]; -+} MSG_CH_REQ_T, *P_MSG_CH_REQ_T; -+ -+typedef struct _MSG_CH_ABORT_T { -+ MSG_HDR_T rMsgHdr; /* Must be the first member */ -+ UINT_8 ucNetTypeIndex; -+ UINT_8 ucTokenID; -+} MSG_CH_ABORT_T, *P_MSG_CH_ABORT_T; -+ -+typedef struct _MSG_CH_GRANT_T { -+ MSG_HDR_T rMsgHdr; /* Must be the first member */ -+ UINT_8 ucNetTypeIndex; -+ UINT_8 ucTokenID; -+ UINT_8 ucPrimaryChannel; -+ ENUM_CHNL_EXT_T eRfSco; -+ ENUM_BAND_T eRfBand; -+ ENUM_CH_REQ_TYPE_T eReqType; -+ UINT_32 u4GrantInterval; /* In unit of ms */ -+} MSG_CH_GRANT_T, *P_MSG_CH_GRANT_T; -+ -+typedef struct _MSG_CH_REOCVER_T { -+ MSG_HDR_T rMsgHdr; /* Must be the first member */ -+ UINT_8 ucNetTypeIndex; -+ UINT_8 ucTokenID; -+ UINT_8 ucPrimaryChannel; -+ ENUM_CHNL_EXT_T eRfSco; -+ ENUM_BAND_T eRfBand; -+ ENUM_CH_REQ_TYPE_T eReqType; -+} MSG_CH_RECOVER_T, *P_MSG_CH_RECOVER_T; -+ -+typedef struct _CNM_INFO_T { -+ UINT_32 u4Reserved; -+} CNM_INFO_T, *P_CNM_INFO_T; -+ -+#if CFG_ENABLE_WIFI_DIRECT -+/* Moved from p2p_fsm.h */ -+typedef struct _DEVICE_TYPE_T { -+ UINT_16 u2CategoryId; /* Category ID */ -+ UINT_8 aucOui[4]; /* OUI */ -+ UINT_16 u2SubCategoryId; /* Sub Category ID */ -+} __KAL_ATTRIB_PACKED__ DEVICE_TYPE_T, *P_DEVICE_TYPE_T; -+#endif -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+VOID cnmInit(P_ADAPTER_T prAdapter); -+ -+VOID cnmUninit(P_ADAPTER_T prAdapter); -+ -+VOID cnmChMngrRequestPrivilege(P_ADAPTER_T prAdapter, P_MSG_HDR_T prMsgHdr); -+ -+VOID cnmChMngrAbortPrivilege(P_ADAPTER_T prAdapter, P_MSG_HDR_T prMsgHdr); -+ -+VOID cnmChMngrHandleChEvent(P_ADAPTER_T prAdapter, P_WIFI_EVENT_T prEvent); -+ -+BOOLEAN -+cnmPreferredChannel(P_ADAPTER_T prAdapter, P_ENUM_BAND_T prBand, PUINT_8 pucPrimaryChannel, P_ENUM_CHNL_EXT_T prBssSCO); -+ -+BOOLEAN cnmAisInfraChannelFixed(P_ADAPTER_T prAdapter, P_ENUM_BAND_T prBand, PUINT_8 pucPrimaryChannel); -+ -+VOID cnmAisInfraConnectNotify(P_ADAPTER_T prAdapter); -+ -+BOOLEAN cnmAisIbssIsPermitted(P_ADAPTER_T prAdapter); -+ -+BOOLEAN cnmP2PIsPermitted(P_ADAPTER_T prAdapter); -+ -+BOOLEAN cnmBowIsPermitted(P_ADAPTER_T prAdapter); -+ -+BOOLEAN cnmBss40mBwPermitted(P_ADAPTER_T prAdapter, ENUM_NETWORK_TYPE_INDEX_T eNetTypeIdx); -+#if CFG_P2P_LEGACY_COEX_REVISE -+BOOLEAN cnmAisDetectP2PChannel(P_ADAPTER_T prAdapter, P_ENUM_BAND_T prBand, PUINT_8 pucPrimaryChannel); -+#endif -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+#ifndef _lint -+/* We don't have to call following function to inspect the data structure. -+ * It will check automatically while at compile time. -+ * We'll need this to guarantee the same member order in different structures -+ * to simply handling effort in some functions. -+ */ -+static inline VOID cnmMsgDataTypeCheck(VOID) -+{ -+ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSG_CH_GRANT_T, rMsgHdr) == 0); -+ -+ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSG_CH_GRANT_T, rMsgHdr) == OFFSET_OF(MSG_CH_RECOVER_T, rMsgHdr)); -+ -+ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSG_CH_GRANT_T, ucNetTypeIndex) == -+ OFFSET_OF(MSG_CH_RECOVER_T, ucNetTypeIndex)); -+ -+ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSG_CH_GRANT_T, ucTokenID) == OFFSET_OF(MSG_CH_RECOVER_T, ucTokenID)); -+ -+ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSG_CH_GRANT_T, ucPrimaryChannel) == -+ OFFSET_OF(MSG_CH_RECOVER_T, ucPrimaryChannel)); -+ -+ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSG_CH_GRANT_T, eRfSco) == OFFSET_OF(MSG_CH_RECOVER_T, eRfSco)); -+ -+ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSG_CH_GRANT_T, eRfBand) == OFFSET_OF(MSG_CH_RECOVER_T, eRfBand)); -+ -+ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSG_CH_GRANT_T, eReqType) == OFFSET_OF(MSG_CH_RECOVER_T, eReqType)); -+ -+} -+#endif /* _lint */ -+ -+#endif /* _CNM_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/cnm_mem.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/cnm_mem.h -new file mode 100644 -index 000000000000..c8f25b1b29a9 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/cnm_mem.h -@@ -0,0 +1,1164 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/mgmt/cnm_mem.h#1 -+*/ -+ -+/*! \file "cnm_mem.h" -+ \brief In this file we define the structure of the control unit of -+ packet buffer and MGT/MSG Memory Buffer. -+*/ -+ -+/* -+** Log: cnm_mem.h -+ * -+ * 03 02 2012 terry.wu -+ * NULL -+ * Snc CFG80211 modification for ICS migration from branch 2.2. -+ * -+ * 01 05 2012 tsaiyuan.hsu -+ * [WCXRP00001157] [MT6620 Wi-Fi][FW][DRV] add timing measurement support for 802.11v -+ * add timing measurement support for 802.11v. -+ * -+ * 03 17 2011 yuche.tsai -+ * NULL -+ * Resize the Secondary Device Type array when WiFi Direct is enabled. -+ * -+ * 03 16 2011 wh.su -+ * [WCXRP00000530] [MT6620 Wi-Fi] [Driver] skip doing p2pRunEventAAAComplete after send assoc response Tx Done -+ * enable the protected while at P2P start GO, and skip some security check . -+ * -+ * 01 26 2011 cm.chang -+ * [WCXRP00000395] [MT6620 Wi-Fi][Driver][FW] Search STA_REC with additional net type index argument -+ * . -+ * -+ * 01 11 2011 eddie.chen -+ * [WCXRP00000322] Add WMM IE in beacon, -+ -+Add per station flow control when STA is in PS -+ -+ * Add per STA flow control when STA is in PS mode -+ * -+ * 12 29 2010 eddie.chen -+ * [WCXRP00000322] Add WMM IE in beacon, -+Add per station flow control when STA is in PS -+ -+ * 1) PS flow control event -+ * -+ * 2) WMM IE in beacon, assoc resp, probe resp -+ * -+ * 12 23 2010 george.huang -+ * [WCXRP00000152] [MT6620 Wi-Fi] AP mode power saving function -+ * 1. update WMM IE parsing, with ASSOC REQ handling -+ * 2. extend U-APSD parameter passing from driver to FW -+ * -+ * 12 07 2010 cm.chang -+ * [WCXRP00000239] MT6620 Wi-Fi][Driver][FW] Merge concurrent branch back to maintrunk -+ * 1. BSSINFO include RLM parameter -+ * 2. free all sta records when network is disconnected -+ * -+ * 11 29 2010 cm.chang -+ * [WCXRP00000210] [MT6620 Wi-Fi][Driver][FW] Set RCPI value in STA_REC for -+ * initial TX rate selection of auto-rate algorithm -+ * Sync RCPI of STA_REC to FW as reference of initial TX rate -+ * -+ * 10 18 2010 cp.wu -+ * [WCXRP00000053] [MT6620 Wi-Fi][Driver] Reset incomplete and might leads to BSOD -+ * when entering RF test with AIS associated -+ * 1. remove redundant variables in STA_REC structure -+ * 2. add STA-REC uninitialization routine for clearing pending events -+ * -+ * 09 21 2010 kevin.huang -+ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning -+ * Eliminate Linux Compile Warning -+ * -+ * 09 03 2010 kevin.huang -+ * NULL -+ * Refine #include sequence and solve recursive/nested #include issue -+ * -+ * 07 12 2010 cp.wu -+ * -+ * SAA will take a record for tracking request sequence number. -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 07 07 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Support state of STA record change from 1 to 1 -+ * -+ * 07 01 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Support sync command of STA_REC -+ * -+ * 06 21 2010 wh.su -+ * [WPD00003840][MT6620 5931] Security migration -+ * modify some code for concurrent network. -+ * -+ * 06 21 2010 yuche.tsai -+ * [WPD00003839][MT6620 5931][P2P] Feature migration -+ * Fix compile error for P2P related defination. -+ * -+ * 06 18 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Provide cnmMgtPktAlloc() and alloc/free function of msg/buf -+ * -+ * 06 17 2010 yuche.tsai -+ * [WPD00003839][MT6620 5931][P2P] Feature migration -+ * Add P2P related fields. -+ * -+ * 06 14 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * saa_fsm.c is migrated. -+ * -+ * 06 14 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * restore utility function invoking via hem_mbox to direct calls -+ * -+ * 06 10 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add buildable & linkable ais_fsm.c -+ * -+ * related reference are still waiting to be resolved -+ * -+ * 06 08 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * hem_mbox is migrated. -+ * -+ * 06 08 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add hem_mbox.c and cnm_mem.h (but disabled some feature) for further migration -+ * -+ * 06 04 2010 george.huang -+ * [BORA00000678][MT6620]WiFi LP integration -+ * [BORA00000678] [MT6620]WiFi LP integration -+ * 1. add u8TimeStamp in MSDU_INFO -+ * 2. move fgIsRxTSFUpdated/fgIsTxTSFUpdated from static to BSS_INFO -+ * 3. add new member for supporting PM in STA_RECORD, which is for AP PS mode -+ * -+ * 05 31 2010 yarco.yang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Add RX TSF Log Feature and ADDBA Rsp with DECLINE handling -+ * -+ * 05 28 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Support checking of duplicated buffer free -+ * -+ * 05 28 2010 kevin.huang -+ * [BORA00000794][WIFISYS][New Feature]Power Management Support -+ * Move define of STA_REC_NUM to config.h and rename to CFG_STA_REC_NUM -+ * -+ * 05 21 2010 kevin.huang -+ * [BORA00000794][WIFISYS][New Feature]Power Management Support -+ * Refine txmInitWtblTxRateTable() - set TX initial rate according to AP's operation rate set -+ * -+ * 05 19 2010 yarco.yang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Fixed MAC RX Desc be overwritten issue -+ * -+ * 05 12 2010 kevin.huang -+ * [BORA00000794][WIFISYS][New Feature]Power Management Support -+ * Add Power Management - Legacy PS-POLL support. -+ * -+ * 05 10 2010 yarco.yang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Support Rx header translation for A-MSDU subframe -+ * -+ * 05 07 2010 george.huang -+ * [BORA00000678][MT6620]WiFi LP integration -+ * add more sanity check about setting timer -+ * -+ * 04 29 2010 george.huang -+ * [BORA00000678][MT6620]WiFi LP integration -+ * modify the compiling flag for RAM usage -+ * -+ * 04 28 2010 tehuang.liu -+ * [BORA00000605][WIFISYS] Phase3 Integration -+ * Modified some MQM-related data structures (SN counter, TX/RX BA table) -+ * -+ * 04 27 2010 tehuang.liu -+ * [BORA00000605][WIFISYS] Phase3 Integration -+ * Added new TX/RX BA tables in STA_REC -+ * -+ * 04 19 2010 kevin.huang -+ * [BORA00000714][WIFISYS][New Feature]Beacon Timeout Support -+ * Add Beacon Timeout Support and will send Null frame to diagnose connection -+ * -+ * 04 09 2010 tehuang.liu -+ * [BORA00000605][WIFISYS] Phase3 Integration -+ * [BORA00000644] WiFi phase 4 integration -+ * Added per-TID SN cache in STA_REC -+ * -+ * 03 24 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Support power control -+ * -+ * 03 16 2010 kevin.huang -+ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support -+ * Add AdHoc Mode -+ * -+ * 03 11 2010 yuche.tsai -+ * [BORA00000343][MT6620] Emulation For TX -+ * . -+ * -+ * 03 05 2010 yarco.yang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Remove Emulation definition -+ * -+ * 03 04 2010 cp.wu -+ * [BORA00000368]Integrate HIF part into BORA -+ * eliminate HIF_EMULATION in cnm_mem.h -+ * -+ * 03 04 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Add cnmStaRecChangeState() declaration. -+ * -+ * 03 03 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Remove compiling warning for some emulation flags -+ * -+ * 03 03 2010 wh.su -+ * [BORA00000637][MT6620 Wi-Fi] [Bug] WPA2 pre-authentication timer not correctly initialize -+ * move the AIS specific variable for security to AIS specific structure. -+ * -+ * 03 03 2010 wh.su -+ * [BORA00000637][MT6620 Wi-Fi] [Bug] WPA2 pre-authentication timer not correctly initialize -+ * Fixed the pre-authentication timer not correctly init issue, -+ * and modify the security related callback function prototype. -+ * -+ * 03 01 2010 tehuang.liu -+ * [BORA00000569][WIFISYS] Phase 2 Integration Test -+ * To store field AMPDU Parameters in STA_REC -+ * -+ * 02 26 2010 tehuang.liu -+ * [BORA00000569][WIFISYS] Phase 2 Integration Test -+ * Added fgIsWmmSupported in STA_RECORD_T. -+ * -+ * 02 26 2010 tehuang.liu -+ * [BORA00000569][WIFISYS] Phase 2 Integration Test -+ * Added fgIsUapsdSupported in STA_RECORD_T -+ * -+ * 02 13 2010 tehuang.liu -+ * [BORA00000569][WIFISYS] Phase 2 Integration Test -+ * Added arTspecTable in STA_REC for TSPEC management -+ * -+ * 02 12 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Enable mgmt buffer debug by default -+ * -+ * 02 12 2010 tehuang.liu -+ * [BORA00000569][WIFISYS] Phase 2 Integration Test -+ * Added BUFFER_SOURCE_BCN -+ * -+ * 02 10 2010 tehuang.liu -+ * [BORA00000569][WIFISYS] Phase 2 Integration Test -+ * Renamed MSDU_INFO.ucFixedRateIndex as MSDU_INFO.ucFixedRateCode -+ * -+ * 02 04 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Add AAA Module Support, Revise Net Type to Net Type Index for array lookup -+ * -+ * 02 02 2010 tehuang.liu -+ * [BORA00000569][WIFISYS] Phase 2 Integration Test -+ * Added SN info in MSDU_INFO_T -+ * -+ * 01 27 2010 wh.su -+ * [BORA00000476][Wi-Fi][firmware] Add the security module initialize code -+ * add and fixed some security function. -+ * -+ * 01 11 2010 kevin.huang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Add Deauth and Disassoc Handler -+ * -+ * 01 08 2010 cp.wu -+ * [BORA00000368]Integrate HIF part into BORA -+ * 1) separate wifi_var_emu.c/.h from wifi_var.c/.h -+ * 2) eliminate HIF_EMULATION code sections appeared in wifi_var/cnm_mem -+ * 3) use cnmMemAlloc() instead to allocate SRAM buffer -+ * -+ * 12 31 2009 cp.wu -+ * [BORA00000368]Integrate HIF part into BORA -+ * 1) surpress debug message emitted from hal_hif.c -+ * 2) add two set of field for recording buffer process time -+ * -+ * 12 31 2009 cp.wu -+ * [BORA00000368]Integrate HIF part into BORA -+ * 1. move wifi task initialization from wifi_task.c(rom) to wifi_init.c (TCM) for integrating F/W download later -+ * * * * * 2. WIFI_Event_Dispatcher() prototype changed to return to suspend mode from normal operation mode -+ * * * * * 2. HIF emulation logic revised -+ * -+ * 12 29 2009 yuche.tsai -+ * [BORA00000343][MT6620] Emulation For TX -+ * .Using global buffer declaring by SD1 instead of using another one. -+ * -+ * 12 25 2009 tehuang.liu -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Integrated modifications for 1st connection (mainly on FW modules MQM, TXM, and RXM) -+ * * MQM: BA handling -+ * * TXM: Macros updates -+ * * RXM: Macros/Duplicate Removal updates -+ * -+ * 12 24 2009 yarco.yang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * . -+ * -+ * 12 23 2009 cp.wu -+ * [BORA00000368]Integrate HIF part into BORA -+ * allocating SRAM for emulation purpose by ruducing MEM_BANK3_BUF_SZ -+ * -+ * 12 21 2009 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Remove individual DATA_BUF_BLOCK_NUM definition for emulation compiling flagsu1rwduu`wvpghlqg|fh+fmdkb -+ * -+ * 12 21 2009 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Support several data buffer banks. -+ * -+ * 12 18 2009 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * .For new FPGA memory size -+ * -+ * 12 18 2009 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * . -+ * -+ * 12 17 2009 george.huang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * . -+ * -+ * Dec 17 2009 MTK02468 -+ * [BORA00000337] To check in codes for FPGA emulation -+ * Modified the DATA_BLOCK_SIZE from 1620 to 2048 -+ * -+ * Dec 16 2009 mtk01426 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Add CFG_TEST_SEC_EMULATION flag -+ * -+ * Dec 9 2009 mtk01104 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Add HT cap to sta record -+ * -+ * Dec 9 2009 mtk02752 -+ * [BORA00000368] Integrate HIF part into BORA -+ * add cnmDataPktFree() for emulation loopback purpose -+ * -+ * Dec 8 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * add the buffer for key handshake 1x and cmd key order issue -+ * -+ * Dec 7 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * move the tx call back function proto type to typedef.h -+ * -+ * Dec 3 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Add cnmGetStaRecByAddress() and modify variable in STA_RECORD_T -+ * -+ * Dec 1 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * rename the port block flag -+ * -+ * Nov 23 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Add variables to STA_RECORD_T for assoc/auth -+ * -+ * Nov 23 2009 mtk02468 -+ * [BORA00000337] To check in codes for FPGA emulation -+ * Fixed the value of STA_WAIT_QUEUE_NUM (from 7 to 5) -+ * -+ * Nov 20 2009 mtk02468 -+ * [BORA00000337] To check in codes for FPGA emulation -+ * Removed u2FrameLength from SW_RFB -+ * -+ * Nov 20 2009 mtk02468 -+ * [BORA00000337] To check in codes for FPGA emulation -+ * Fixed indenting -+ * -+ * Nov 20 2009 mtk02468 -+ * [BORA00000337] To check in codes for FPGA emulation -+ * Updated MSDU_INFO and SW_RFB -+ * -+ * Nov 19 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * update the variable for security -+ * -+ * Nov 18 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * remove the variable to make the compiler ok -+ * -+ * Nov 18 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * add the variable for security module -+ * -+ * Nov 16 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Fix typo in define of MSG_BUF_BLOCK_SIZE -+ * -+ * Nov 13 2009 mtk02468 -+ * [BORA00000337] To check in codes for FPGA emulation -+ * Let typedef STA_REC_T precede typedef MSDU_INFO_T and SW_RFB_T -+ * -+ * Nov 13 2009 mtk02468 -+ * [BORA00000337] To check in codes for FPGA emulation -+ * Modified MSDU_INFO and STA_REC for TXM and MQM -+ * -+ * Nov 12 2009 mtk01104 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Rename STA_REC_T to STA_RECORD_T and add ucIndex member -+ * -+ * Nov 9 2009 mtk01104 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Make sure ucBufferSource the same offset in MSDU_INFO and SW_RFB -+ * -+ * Nov 6 2009 mtk01426 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * -+ * -+ * Nov 5 2009 mtk01426 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * -+ * -+ * Nov 5 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Update comment -+ * -+ * Oct 30 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Add draft content of MSDU_INFO_T and SW_RFB_T -+ * -+ * Oct 30 2009 mtk01084 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * -+ * -+ * Oct 28 2009 mtk01104 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * -+ * -+ * Oct 23 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Fix lint warning -+ * -+ * Oct 21 2009 mtk01426 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Add CFG_TEST_RX_EMULATION flag -+ * -+ * Oct 20 2009 mtk01426 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * -+ * -+ * Oct 9 2009 mtk02468 -+ * [BORA00000337] To check in codes for FPGA emulation -+ * Added field ucTC to MSDU_INFO_T and field pucHifRxPacket to SW_RFB_T -+ * -+ * Oct 8 2009 mtk01104 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * -+** -+*/ -+ -+#ifndef _CNM_MEM_H -+#define _CNM_MEM_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+#ifndef POWER_OF_2 -+#define POWER_OF_2(n) BIT(n) -+#endif -+ -+/* Size of a basic management buffer block in power of 2 */ -+#define MGT_BUF_BLOCK_SIZE_IN_POWER_OF_2 7 /* 7 to the power of 2 = 128 */ -+#define MSG_BUF_BLOCK_SIZE_IN_POWER_OF_2 5 /* 5 to the power of 2 = 32 */ -+ -+/* Size of a basic management buffer block */ -+#define MGT_BUF_BLOCK_SIZE POWER_OF_2(MGT_BUF_BLOCK_SIZE_IN_POWER_OF_2) -+#define MSG_BUF_BLOCK_SIZE POWER_OF_2(MSG_BUF_BLOCK_SIZE_IN_POWER_OF_2) -+ -+/* Total size of (n) basic management buffer blocks */ -+#define MGT_BUF_BLOCKS_SIZE(n) ((UINT_32)(n) << MGT_BUF_BLOCK_SIZE_IN_POWER_OF_2) -+#define MSG_BUF_BLOCKS_SIZE(n) ((UINT_32)(n) << MSG_BUF_BLOCK_SIZE_IN_POWER_OF_2) -+ -+/* Number of management buffer block */ -+#define MAX_NUM_OF_BUF_BLOCKS 32 /* Range: 1~32 */ -+ -+/* Size of overall management frame buffer */ -+#define MGT_BUFFER_SIZE (MAX_NUM_OF_BUF_BLOCKS * MGT_BUF_BLOCK_SIZE) -+#define MSG_BUFFER_SIZE (MAX_NUM_OF_BUF_BLOCKS * MSG_BUF_BLOCK_SIZE) -+ -+/* STA_REC related definitions */ -+#define STA_REC_INDEX_BMCAST 0xFF -+#define STA_REC_INDEX_NOT_FOUND 0xFE -+#define STA_WAIT_QUEUE_NUM 5 /* Number of SW queues in each STA_REC: AC0~AC4 */ -+#define SC_CACHE_INDEX_NUM 5 /* Number of SC caches in each STA_REC: AC0~AC4 */ -+ -+/* P2P related definitions */ -+#ifdef CFG_ENABLE_WIFI_DIRECT -+/* Moved from p2p_fsm.h */ -+#define WPS_ATTRI_MAX_LEN_DEVICE_NAME 32 /* 0x1011 */ -+#define P2P_GC_MAX_CACHED_SEC_DEV_TYPE_COUNT 8 /* NOTE(Kevin): Shall <= 16 */ -+#endif -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+#if ((MAX_NUM_OF_BUF_BLOCKS > 32) || (MAX_NUM_OF_BUF_BLOCKS <= 0)) -+#error > #define MAX_NUM_OF_MGT_BUF_BLOCKS : Out of boundary ! -+#elif MAX_NUM_OF_BUF_BLOCKS > 16 -+typedef UINT_32 BUF_BITMAP; -+#elif MAX_NUM_OF_BUF_BLOCKS > 8 -+typedef UINT_16 BUF_BITMAP; -+#else -+typedef UINT_8 BUF_BITMAP; -+#endif /* MAX_NUM_OF_MGT_BUF_BLOCKS */ -+ -+/* Control variable of TX management memory pool */ -+typedef struct _BUF_INFO_T { -+ PUINT_8 pucBuf; -+ -+#if CFG_DBG_MGT_BUF -+ UINT_32 u4AllocCount; -+ UINT_32 u4FreeCount; -+ UINT_32 u4AllocNullCount; -+#endif /* CFG_DBG_MGT_BUF */ -+ -+ BUF_BITMAP rFreeBlocksBitmap; -+ UINT_8 aucAllocatedBlockNum[MAX_NUM_OF_BUF_BLOCKS]; -+} BUF_INFO_T, *P_BUF_INFO_T; -+ -+/* Wi-Fi divides RAM into three types -+ * MSG: Mailbox message (Small size) -+ * BUF: HW DMA buffers (HIF/MAC) -+ */ -+typedef enum _ENUM_RAM_TYPE_T { -+ RAM_TYPE_MSG = 0, -+ RAM_TYPE_BUF -+} ENUM_RAM_TYPE_T, P_ENUM_RAM_TYPE_T; -+ -+typedef enum _ENUM_BUFFER_SOURCE_T { -+ BUFFER_SOURCE_HIF_TX0 = 0, -+ BUFFER_SOURCE_HIF_TX1, -+ BUFFER_SOURCE_MAC_RX, -+ BUFFER_SOURCE_MNG, -+ BUFFER_SOURCE_BCN, -+ BUFFER_SOURCE_NUM -+} ENUM_BUFFER_SOURCE_T, *P_ENUM_BUFFER_SOURCE_T; -+ -+typedef enum _ENUM_SEC_STATE_T { -+ SEC_STATE_INIT, -+ SEC_STATE_INITIATOR_PORT_BLOCKED, -+ SEC_STATE_RESPONDER_PORT_BLOCKED, -+ SEC_STATE_CHECK_OK, -+ SEC_STATE_SEND_EAPOL, -+ SEC_STATE_SEND_DEAUTH, -+ SEC_STATE_COUNTERMEASURE, -+ SEC_STATE_NUM -+} ENUM_SEC_STATE_T; -+ -+typedef struct _TSPEC_ENTRY_T { -+ UINT_8 ucStatus; -+ UINT_8 ucToken; /* Dialog Token in ADDTS_REQ or ADDTS_RSP */ -+ UINT_16 u2MediumTime; -+ UINT_32 u4TsInfo; -+ /* PARAM_QOS_TS_INFO rParamTsInfo; */ -+ /* Add other retained QoS parameters below */ -+} TSPEC_ENTRY_T, *P_TSPEC_ENTRY_T, TSPEC_TABLE_ENTRY_T, *P_TSPEC_TABLE_ENTRY_T; -+ -+typedef struct _SEC_INFO_T { -+ -+ ENUM_SEC_STATE_T ePreviousState; -+ ENUM_SEC_STATE_T eCurrentState; -+ -+ BOOLEAN fg2nd1xSend; -+ BOOLEAN fgKeyStored; -+ -+ UINT_8 aucStoredKey[64]; -+ -+ BOOLEAN fgAllowOnly1x; -+} SEC_INFO_T, *P_SEC_INFO_T; -+ -+#define MAX_NUM_CONCURRENT_FRAGMENTED_MSDUS 3 -+ -+#define UPDATE_BSS_RSSI_INTERVAL_SEC 3 /* Seconds */ -+ -+/* Fragment information structure */ -+typedef struct _FRAG_INFO_T { -+ UINT_16 u2NextFragSeqCtrl; -+ PUINT_8 pucNextFragStart; -+ P_SW_RFB_T pr1stFrag; -+ OS_SYSTIME rReceiveLifetimeLimit; /* The receive time of 1st fragment */ -+} FRAG_INFO_T, *P_FRAG_INFO_T; -+ -+typedef struct _STAT_CNT_INFO_FW_T { -+ UINT32 u4NumOfTx; /* number of packets sent from host */ -+ UINT32 u4NumOfTxOK; /* number of packets sent to air OK */ -+ UINT32 u4NumOfTxRetry; /* number of packets sent to air RETRY */ -+ UINT32 u4TxDoneAirTimeMax; /* maximum tx done air time */ -+ -+ UINT32 u4NumOfPtiRspTxOk; /* number of PTI RSP sent to air OK */ -+ UINT32 u4NumOfPtiRspTxErr; /* number of PTI RSP sent to air ERROR */ -+ -+ UINT32 u4NumOfTxErr; /* number of packets sent to air ERROR */ -+ -+ UINT32 u4NumOfRx; /* number of received packets */ -+ UINT32 u4NumOfPtiRspRx; /* number of PTI RSP rcv */ -+ -+#define STAT_CNT_INFO_TX_ERR_FLUSHED 0x00000001 -+#define STAT_CNT_INFO_TX_ERR_AGE_TIMEOUT 0x00000002 -+#define STAT_CNT_INFO_TX_ERR_MPDU 0x00000004 -+#define STAT_CNT_INFO_TX_ERR_RTS 0x00000010 -+#define STAT_CNT_INFO_TX_ERR_LIFETIME 0x00000020 -+#define STAT_CNT_INFO_TX_ERR_UNKNOWN 0x80000000 -+ UINT32 u4TxErrBitmap; /* TX error type */ -+ -+#define STAT_CNT_INFO_MAX_TX_RATE_OK_HIS_NUM 10 /* TX OK history */ -+ UINT8 aucTxRateOkHis[STAT_CNT_INFO_MAX_TX_RATE_OK_HIS_NUM][2]; -+ UINT32 u4TxRateOkHisId; -+ -+#define STAT_CNT_INFO_MAX_RATE_ID (32) /* MCS0 ~ MCS31 */ -+ UINT32 aucTxRateMap[STAT_CNT_INFO_MAX_RATE_ID]; -+ UINT32 aucRxRateMap[STAT_CNT_INFO_MAX_RATE_ID]; -+ -+ UINT8 aucStateHis[100][3]; /* State history */ -+ UINT32 u4StateHisId; /* history ID */ -+} STAT_CNT_INFO_FW_T; -+ -+typedef struct _STAT_CNT_INFO_DRV_T { -+ -+ UINT32 u4NumOfTxFromOs; /* number of packets sent from OS */ -+ UINT32 u4NumOfTxQueFull; /* number of packets dropped due to queue full */ -+ UINT32 u4NumOfTxToFw; /* number of packets sent to firmware */ -+ -+ STAT_CNT_INFO_FW_T rFw; -+} STAT_CNT_INFO_DRV_T; -+ -+/* Define STA record structure */ -+struct _STA_RECORD_T { -+ LINK_ENTRY_T rLinkEntry; -+ UINT_8 ucIndex; /* Not modify it except initializing */ -+ -+ BOOLEAN fgIsInUse; /* Indicate if this entry is in use or not */ -+ UINT_8 aucMacAddr[MAC_ADDR_LEN]; /* MAC address */ -+ -+ /* SAA/AAA */ -+ ENUM_AA_STATE_T eAuthAssocState; /* Store STATE Value used in SAA/AAA */ -+ UINT_8 ucAuthAssocReqSeqNum; -+ -+ ENUM_STA_TYPE_T eStaType; /* Indicate the role of this STA in -+ * the network (for example, P2P GO) -+ */ -+ -+ UINT_8 ucNetTypeIndex; /* ENUM_NETWORK_TYPE_INDEX_T */ -+ -+ UINT_8 ucStaState; /* STATE_1,2,3 */ -+ -+ UINT_8 ucPhyTypeSet; /* Available PHY Type Set of this peer -+ * (may deduced from received BSS_DESC_T) -+ */ -+ UINT_8 ucDesiredPhyTypeSet; /* The match result by AND operation of peer's -+ * PhyTypeSet and ours. -+ */ -+ BOOLEAN fgHasBasicPhyType; /* A flag to indicate a Basic Phy Type which -+ * is used to generate some Phy Attribute IE -+ * (e.g. capability, MIB) during association. -+ */ -+ UINT_8 ucNonHTBasicPhyType; /* The Basic Phy Type chosen among the -+ * ucDesiredPhyTypeSet. -+ */ -+ -+ UINT_16 u2CapInfo; /* For Infra Mode, to store Capability Info. from Association Resp(SAA). -+ * For AP Mode, to store Capability Info. from Association Req(AAA). -+ */ -+ UINT_16 u2AssocId; /* For Infra Mode, to store AID from Association Resp(SAA). -+ * For AP Mode, to store the Assigned AID(AAA). -+ */ -+ -+ UINT_16 u2ListenInterval; /* Listen Interval from STA(AAA) */ -+ -+ UINT_16 u2DesiredNonHTRateSet; /* Our Current Desired Rate Set after -+ * match with STA's Operational Rate Set -+ */ -+ -+ UINT_16 u2OperationalRateSet; /* Operational Rate Set of peer BSS */ -+ UINT_16 u2BSSBasicRateSet; /* Basic Rate Set of peer BSS */ -+ -+ BOOLEAN fgIsMerging; /* For IBSS Mode, to indicate that Merge is ongoing */ -+ -+ BOOLEAN fgDiagnoseConnection; /* For Infra/AP Mode, to diagnose the Connection with -+ * this peer by sending ProbeReq/Null frame */ -+ -+ /*------------------------------------------------------------------------------------------*/ -+ /* 802.11n HT capabilities when (prStaRec->ucPhyTypeSet & PHY_TYPE_BIT_HT) is true */ -+ /* They have the same definition with fields of information element */ -+ /*------------------------------------------------------------------------------------------*/ -+ UINT_8 ucMcsSet; /* MCS0~7 rate set of peer BSS */ -+ BOOLEAN fgSupMcs32; /* MCS32 is supported by peer BSS */ -+ UINT_16 u2HtCapInfo; /* HT cap info field by HT cap IE */ -+ UINT_8 ucAmpduParam; /* Field A-MPDU Parameters in HT cap IE */ -+ UINT_16 u2HtExtendedCap; /* HT extended cap field by HT cap IE */ -+ UINT_32 u4TxBeamformingCap; /* TX beamforming cap field by HT cap IE */ -+ UINT_8 ucAselCap; /* ASEL cap field by HT cap IE */ -+ -+ UINT_8 ucRCPI; /* RCPI of peer */ -+ -+ UINT_8 ucDTIMPeriod; /* Target BSS's DTIM Period, we use this -+ * value for setup Listen Interval -+ * TODO(Kevin): TBD -+ */ -+ UINT_8 ucAuthAlgNum; /* For Infra/AP Mode, the Auth Algorithm Num used in Authentication(SAA/AAA) */ -+ BOOLEAN fgIsReAssoc; /* For Infra/AP Mode, to indicate ReAssoc Frame was in used(SAA/AAA) */ -+ -+ UINT_8 ucTxAuthAssocRetryCount; /* For Infra Mode, the Retry Count of TX Auth/Assod Frame(SAA) */ -+ UINT_8 ucTxAuthAssocRetryLimit; /* For Infra Mode, the Retry Limit of TX Auth/Assod Frame(SAA) */ -+ -+ UINT_16 u2StatusCode; /* Status of Auth/Assoc Req */ -+ UINT_16 u2ReasonCode; /* Reason that been Deauth/Disassoc */ -+ -+ P_IE_CHALLENGE_TEXT_T prChallengeText; /* Point to an allocated buffer for storing Challenge Text -+ * for Shared Key Authentication -+ */ -+ -+ TIMER_T rTxReqDoneOrRxRespTimer; /* For Infra Mode, a timer used to send a timeout event -+ * while waiting for TX request done or RX response. -+ */ -+ -+ /*------------------------------------------------------------------------------------------*/ -+ /* Power Management related fields (for STA/ AP/ P2P/ BOW power saving mode) */ -+ /*------------------------------------------------------------------------------------------*/ -+ BOOLEAN fgSetPwrMgtBit; /* For Infra Mode, to indicate that outgoing frame need toggle -+ * the Pwr Mgt Bit in its Frame Control Field. -+ */ -+ -+ BOOLEAN fgIsInPS; /* For AP Mode, to indicate the client PS state(PM). -+ * TRUE: In PS Mode; FALSE: In Active Mode. */ -+ -+ BOOLEAN fgIsInPsPollSP; /* For Infra Mode, to indicate we've sent a PS POLL to AP and start -+ * the PS_POLL Service Period(LP) -+ */ -+ -+ BOOLEAN fgIsInTriggerSP; /* For Infra Mode, to indicate we've sent a Trigger Frame to AP and start -+ * the Delivery Service Period(LP) -+ */ -+ -+ UINT_8 ucBmpDeliveryAC; /* 0: AC0, 1: AC1, 2: AC2, 3: AC3 */ -+ -+ UINT_8 ucBmpTriggerAC; /* 0: AC0, 1: AC1, 2: AC2, 3: AC3 */ -+ -+ UINT_8 ucUapsdSp; /* Max SP length */ -+ -+ /*------------------------------------------------------------------------------------------*/ -+ -+ BOOLEAN fgIsRtsEnabled; -+ -+ OS_SYSTIME rUpdateTime; /* (4) System Timestamp of Successful TX and RX */ -+ -+ OS_SYSTIME rLastJoinTime; /* (4) System Timestamp of latest JOIN process */ -+ -+ UINT_8 ucJoinFailureCount; /* Retry Count of JOIN process */ -+ -+ LINK_T arStaWaitQueue[STA_WAIT_QUEUE_NUM]; /* For TXM to defer pkt forwarding to MAC TX DMA */ -+ -+ UINT_16 au2CachedSeqCtrl[TID_NUM + 1]; /* Duplicate removal for HT STA on a per-TID basis -+ * ("+1" is for MMPDU and non-QoS) -+ */ -+ -+#if 0 -+ /* RXM */ -+ P_RX_BA_ENTRY_T aprRxBaTable[TID_NUM]; -+ -+ /* TXM */ -+ P_TX_BA_ENTRY_T aprTxBaTable[TID_NUM]; -+#endif -+ -+ FRAG_INFO_T rFragInfo[MAX_NUM_CONCURRENT_FRAGMENTED_MSDUS]; -+ -+ SEC_INFO_T rSecInfo; /* The security state machine */ -+ -+ BOOLEAN fgPortBlock; /* The 802.1x Port Control flag */ -+ -+ BOOLEAN fgTransmitKeyExist; /* Unicast key exist for this STA */ -+ -+ UINT_8 ucWTEntry; -+ -+ BOOLEAN fgTxAmpduEn; /* Enable TX AMPDU for this Peer */ -+ BOOLEAN fgRxAmpduEn; /* Enable RX AMPDU for this Peer */ -+ -+ PUINT_8 pucAssocReqIe; -+ UINT_16 u2AssocReqIeLen; -+ /*------------------------------------------------------------------------------------------*/ -+ /* WMM/QoS related fields */ -+ /*------------------------------------------------------------------------------------------*/ -+ BOOLEAN fgIsQoS; /* If the STA is associated as a QSTA or QAP (for TX/RX) */ -+ BOOLEAN fgIsWmmSupported; /* If the peer supports WMM, set to TRUE (for association) */ -+ BOOLEAN fgIsUapsdSupported; /* Set according to the scan result (for association) */ -+ -+ /*------------------------------------------------------------------------------------------*/ -+ /* P2P related fields */ -+ /*------------------------------------------------------------------------------------------*/ -+#if CFG_ENABLE_WIFI_DIRECT -+ UINT_8 u2DevNameLen; -+ UINT_8 aucDevName[WPS_ATTRI_MAX_LEN_DEVICE_NAME]; -+ -+ UINT_8 aucDevAddr[MAC_ADDR_LEN]; /* P2P Device Address */ -+ -+ UINT_16 u2ConfigMethods; -+ -+ UINT_8 ucDeviceCap; -+ -+ UINT_8 ucSecondaryDevTypeCount; -+ -+ DEVICE_TYPE_T rPrimaryDevTypeBE; -+ -+ DEVICE_TYPE_T arSecondaryDevTypeBE[P2P_GC_MAX_CACHED_SEC_DEV_TYPE_COUNT]; -+#endif /* CFG_SUPPORT_P2P */ -+ -+ /*------------------------------------------------------------------------------------------*/ -+ /* QM related fields */ -+ /*------------------------------------------------------------------------------------------*/ -+ -+ UINT_8 ucFreeQuota; /* Per Sta flow controal. Valid when fgIsInPS is TRUE. -+ Change it for per Queue flow control */ -+ /* UINT_8 aucFreeQuotaPerQueue[NUM_OF_PER_STA_TX_QUEUES]; */ /* used in future */ -+ UINT_8 ucFreeQuotaForDelivery; -+ UINT_8 ucFreeQuotaForNonDelivery; -+#if CFG_ENABLE_PKT_LIFETIME_PROFILE && CFG_ENABLE_PER_STA_STATISTICS -+ UINT_32 u4TotalTxPktsNumber; -+ UINT_32 u4TotalTxPktsTime; -+ UINT_32 u4TotalTxPktsHifTime; -+ -+ UINT_32 u4MaxTxPktsTime; -+ UINT_32 u4MaxTxPktsHifTime; -+ -+ UINT_32 u4ThresholdCounter; -+ UINT_32 u4EnqeueuCounter; -+ UINT_32 u4DeqeueuCounter; -+ UINT_32 u4PrevIntCount; -+ UINT_32 u4ThisIntCount; -+ UINT_32 u4NoTcResource; -+#endif -+ -+#if 1 -+ /*------------------------------------------------------------------------------------------*/ -+ /* To be removed, this is to make que_mgt compilation success only */ -+ /*------------------------------------------------------------------------------------------*/ -+ /* When this STA_REC is in use, set to TRUE. */ -+ BOOLEAN fgIsValid; -+ -+ /* Per-STA Queues: [0] AC0, [1] AC1, [2] AC2, [3] AC3, [4] 802.1x */ -+ QUE_T arTxQueue[NUM_OF_PER_STA_TX_QUEUES]; -+ -+ /* When this STA is in PS Mode, set to TRUE. */ -+ /* BOOLEAN fgIsPS; */ -+ -+ /* When this STA enters Power-Saving, FW will notify the driver with a Session ID */ -+ UINT_8 ucPsSessionID; -+ -+ BOOLEAN fgIsAp; -+ -+ /* Reorder Parameter reference table */ -+ P_RX_BA_ENTRY_T aprRxReorderParamRefTbl[CFG_RX_MAX_BA_TID_NUM]; -+#endif -+ -+#if CFG_SUPPORT_802_11V_TIMING_MEASUREMENT -+ TIMINGMSMT_PARAM_T rWNMTimingMsmt; -+#endif -+ -+#if (CFG_SUPPORT_TDLS == 1) -+ BOOLEAN fgTdlsIsProhibited; /* TRUE: AP prohibits TDLS links */ -+ BOOLEAN fgTdlsIsChSwProhibited; /* TRUE: AP prohibits TDLS chan switch */ -+ -+ BOOLEAN flgTdlsIsInitiator; /* TRUE: the peer is the initiator */ -+ IE_HT_CAP_T rTdlsHtCap; /* temp to queue HT capability element */ -+ BOOLEAN fgTdlsInSecurityMode; /* TRUE: security mode */ -+ PARAM_KEY_T rTdlsKeyTemp; /* temp to queue the key information */ -+ -+#define TDLS_SETUP_TIMEOUT_SEC 5 /* unit: second */ -+ OS_SYSTIME rTdlsSetupStartTime; /* time when link setup is started */ -+ -+ OS_SYSTIME rTdlsTxQuotaEmptyTime; /* time when TX quota is 0 */ -+ -+ STAT_CNT_INFO_DRV_T rTdlsStatistics; -+#endif /* CFG_SUPPORT_TDLS */ -+ -+#if (CFG_SUPPORT_STATISTICS == 1) -+#define STATS_ENV_TIMEOUT_SEC 10 /* unit: second */ -+ OS_SYSTIME rStatsEnvTxPeriodLastTime; -+ -+#define STATS_ENV_TX_CNT_REPORT_TRIGGER 2500 /* 6Mbps */ -+#define STATS_ENV_TX_CNT_REPORT_TRIGGER_SEC 5 /* unit: second */ -+ OS_SYSTIME rStatsEnvTxLastTime; -+ UINT32 u4StatsEnvTxCnt; -+ -+ UINT32 u4NumOfNoTxQuota; -+ -+ UINT32 u4RxReorderFallAheadCnt; -+ UINT32 u4RxReorderFallBehindCnt; -+ UINT32 u4RxReorderHoleCnt; -+ UINT32 u4RxReorderHoleTimeoutCnt; -+ -+ UINT32 u4StatsRxPassToOsCnt; -+ -+ /* delay from HIF to pass to OS: us */ -+#define STATS_STAY_INT_BYTE_THRESHOLD 500 -+ UINT32 u4StayIntMaxRx[3], u4StayIntMinRx[3], u4StayIntAvgRx[3]; -+ -+ UINT8 ucStatsGenDisplayCnt; -+#endif /* CFG_SUPPORT_STATISTICS */ -+}; -+ -+#if 0 -+/* use nic_tx.h instead */ -+/* MSDU_INFO and SW_RFB structure */ -+typedef struct _MSDU_INFO_T { -+ -+ /* 4 ----------------MSDU_INFO and SW_RFB Common Fields------------------ */ -+ -+ LINK_ENTRY_T rLinkEntry; -+ PUINT_8 pucBuffer; /* Pointer to the associated buffer */ -+ -+ UINT_8 ucBufferSource; /* HIF TX0, HIF TX1, MAC RX, or MNG Pool */ -+ UINT_8 ucNetworkTypeIndex; /* Network type index that this TX packet is assocaited with */ -+ UINT_8 ucTC; /* 0 to 5 (used by HIF TX to increment the corresponding TC counter) */ -+ UINT_8 ucTID; /* Traffic Identification */ -+ -+ BOOLEAN fgIs802_11Frame; /* Set to TRUE for 802.11 frame */ -+ UINT_8 ucMacHeaderLength; -+ UINT_16 u2PayloadLength; -+ PUINT_8 pucMacHeader; /* 802.11 header */ -+ PUINT_8 pucPayload; /* 802.11 payload */ -+ -+ OS_SYSTIME rArrivalTime; /* System Timestamp (4) */ -+ P_STA_RECORD_T prStaRec; -+ -+#if CFG_PROFILE_BUFFER_TRACING -+ ENUM_BUFFER_ACTIVITY_TYPE_T eActivity[2]; -+ UINT_32 rActivityTime[2]; -+#endif -+#if DBG && CFG_BUFFER_FREE_CHK -+ BOOLEAN fgBufferInSource; -+#endif -+ -+ UINT_8 ucControlFlag; /* For specify some Control Flags, e.g. Basic Rate */ -+ -+ /* 4 -----------------------Non-Common ------------------------- */ -+ /* TODO: move flags to ucControlFlag */ -+ -+ BOOLEAN fgIs1xFrame; /* Set to TRUE for 802.1x frame */ -+ -+ /* TXM: For TX Done handling, callback function & parameter (5) */ -+ BOOLEAN fgIsTxFailed; /* Set to TRUE if transmission failure */ -+ -+ PFN_TX_DONE_HANDLER pfTxDoneHandler; -+ -+ UINT_64 u8TimeStamp; /* record the TX timestamp */ -+ -+ /* TXM: For PS forwarding control (per-STA flow control) */ -+ UINT_8 ucPsForwardingType; /* Delivery-enabled, non-delivery-enabled, non-PS */ -+ UINT_8 ucPsSessionID; /* The Power Save session id for PS forwarding control */ -+ -+ /* TXM: For MAC TX DMA operations */ -+ UINT_8 ucMacTxQueIdx; /* MAC TX queue: AC0-AC6, BCM, or BCN */ -+ BOOLEAN fgNoAck; /* Set to true if Ack is not required for this packet */ -+ BOOLEAN fgBIP; /* Set to true if BIP is used for this packet */ -+ UINT_8 ucFragTotalCount; -+ UINT_8 ucFragFinishedCount; -+ UINT_16 u2FragThreshold; /* Fragmentation threshold without WLAN Header & FCS */ -+ BOOLEAN fgFixedRate; /* If a fixed rate is used, set to TRUE. */ -+ UINT_8 ucFixedRateCode; /* The rate code copied to MAC TX Desc */ -+ UINT_8 ucFixedRateRetryLimit; /* The retry limit when a fixed rate is used */ -+ BOOLEAN fgIsBmcQueueEnd; /* Set to true if this packet is the end of BMC */ -+ -+ /* TXM: For flushing ACL frames */ -+ UINT_16 u2PalLLH; /* 802.11 PAL LLH */ -+ /* UINT_16 u2LLH; */ -+ UINT_16 u2ACLSeq; /* u2LLH+u2ACLSeq for AM HCI flush ACL frame */ -+ -+ /* TXM for retransmitting a flushed packet */ -+ BOOLEAN fgIsSnAssigned; -+ UINT_16 u2SequenceNumber; /* To remember the Sequence Control field of this MPDU */ -+ -+} MSDU_INFO_T, *P_MSDU_INFO_T; -+#endif -+ -+#if 0 -+/* nic_rx.h */ -+typedef struct _SW_RFB_T { -+ -+ /* 4 ----------------MSDU_INFO and SW_RFB Common Fields------------------ */ -+ -+ LINK_ENTRY_T rLinkEntry; -+ PUINT_8 pucBuffer; /* Pointer to the associated buffer */ -+ -+ UINT_8 ucBufferSource; /* HIF TX0, HIF TX1, MAC RX, or MNG Pool */ -+ UINT_8 ucNetworkTypeIndex; /* Network type index that this TX packet is assocaited with */ -+ UINT_8 ucTC; /* 0 to 5 (used by HIF TX to increment the corresponding TC counter) */ -+ UINT_8 ucTID; /* Traffic Identification */ -+ -+ BOOLEAN fgIs802_11Frame; /* Set to TRUE for 802.11 frame */ -+ UINT_8 ucMacHeaderLength; -+ UINT_16 u2PayloadLength; -+ PUINT_8 pucMacHeader; /* 802.11 header */ -+ PUINT_8 pucPayload; /* 802.11 payload */ -+ -+ OS_SYSTIME rArrivalTime; /* System Timestamp (4) */ -+ P_STA_RECORD_T prStaRec; -+ -+#if CFG_PROFILE_BUFFER_TRACING -+ ENUM_BUFFER_ACTIVITY_TYPE_T eActivity[2]; -+ UINT_32 rActivityTime[2]; -+#endif -+#if DBG && CFG_BUFFER_FREE_CHK -+ BOOLEAN fgBufferInSource; -+#endif -+ -+ UINT_8 ucControlFlag; /* For specify some Control Flags, e.g. Basic Rate */ -+ -+ /* 4 -----------------------Non-Common ------------------------- */ -+ -+ /* For composing the HIF RX Header (TODO: move flags to ucControlFlag) */ -+ PUINT_8 pucHifRxPacket; /* Pointer to the Response packet to HIF RX0 or RX1 */ -+ UINT_16 u2HifRxPacketLength; -+ UINT_8 ucHeaderOffset; -+ UINT_8 ucHifRxPortIndex; -+ -+ UINT_16 u2SequenceControl; -+ BOOLEAN fgIsA4Frame; /* (For MAC RX packet parsing) set to TRUE if 4 addresses are present */ -+ BOOLEAN fgIsBAR; -+ BOOLEAN fgIsQoSData; -+ BOOLEAN fgIsAmsduSubframe; /* Set to TRUE for A-MSDU Subframe */ -+ -+ /* For HIF RX DMA Desc */ -+ BOOLEAN fgTUChecksumCheckRequired; -+ BOOLEAN fgIPChecksumCheckRequired; -+ UINT_8 ucEtherTypeOffset; -+ -+} SW_RFB_T, *P_SW_RFB_T; -+#endif -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+P_MSDU_INFO_T cnmMgtPktAlloc(IN P_ADAPTER_T prAdapter, IN UINT_32 u4Length); -+ -+VOID cnmMgtPktFree(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); -+ -+VOID cnmMemInit(IN P_ADAPTER_T prAdapter); -+ -+PVOID cnmMemAlloc(IN P_ADAPTER_T prAdapter, IN ENUM_RAM_TYPE_T eRamType, IN UINT_32 u4Length); -+ -+VOID cnmMemFree(IN P_ADAPTER_T prAdapter, IN PVOID pvMemory); -+ -+VOID cnmStaRecInit(IN P_ADAPTER_T prAdapter); -+ -+VOID cnmStaRecUninit(IN P_ADAPTER_T prAdapter); -+ -+P_STA_RECORD_T cnmStaRecAlloc(IN P_ADAPTER_T prAdapter, IN UINT_8 ucNetTypeIndex); -+ -+VOID cnmStaRecFree(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN BOOLEAN fgSyncToChip); -+ -+VOID cnmStaFreeAllStaByNetType(P_ADAPTER_T prAdapter, ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, BOOLEAN fgSyncToChip); -+ -+P_STA_RECORD_T cnmGetStaRecByIndex(IN P_ADAPTER_T prAdapter, IN UINT_8 ucIndex); -+ -+P_STA_RECORD_T cnmGetStaRecByAddress(IN P_ADAPTER_T prAdapter, IN UINT_8 ucNetTypeIndex, IN UINT_8 aucPeerMACAddress[]); -+ -+VOID cnmStaRecResetStatus(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex); -+ -+VOID cnmStaRecChangeState(IN P_ADAPTER_T prAdapter, IN OUT P_STA_RECORD_T prStaRec, IN UINT_8 ucNewState); -+ -+P_STA_RECORD_T -+cnmStaTheTypeGet(P_ADAPTER_T prAdapter, -+ ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, ENUM_STA_TYPE_T eStaType, UINT32 *pu4StartIdx); -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+#ifndef _lint -+/* Kevin: we don't have to call following function to inspect the data structure. -+ * It will check automatically while at compile time. -+ * We'll need this for porting driver to different RTOS. -+ */ -+static inline VOID cnmMemDataTypeCheck(VOID) -+{ -+#if 0 -+ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSDU_INFO_T, rLinkEntry) == 0); -+ -+ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSDU_INFO_T, rLinkEntry) == OFFSET_OF(SW_RFB_T, rLinkEntry)); -+ -+ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSDU_INFO_T, pucBuffer) == OFFSET_OF(SW_RFB_T, pucBuffer)); -+ -+ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSDU_INFO_T, ucBufferSource) == OFFSET_OF(SW_RFB_T, ucBufferSource)); -+ -+ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSDU_INFO_T, pucMacHeader) == OFFSET_OF(SW_RFB_T, pucMacHeader)); -+ -+ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSDU_INFO_T, ucMacHeaderLength) == -+ OFFSET_OF(SW_RFB_T, ucMacHeaderLength)); -+ -+ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSDU_INFO_T, pucPayload) == OFFSET_OF(SW_RFB_T, pucPayload)); -+ -+ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSDU_INFO_T, u2PayloadLength) == OFFSET_OF(SW_RFB_T, u2PayloadLength)); -+ -+ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSDU_INFO_T, prStaRec) == OFFSET_OF(SW_RFB_T, prStaRec)); -+ -+ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSDU_INFO_T, ucNetworkTypeIndex) == -+ OFFSET_OF(SW_RFB_T, ucNetworkTypeIndex)); -+ -+ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSDU_INFO_T, ucTID) == OFFSET_OF(SW_RFB_T, ucTID)); -+ -+ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSDU_INFO_T, fgIs802_11Frame) == OFFSET_OF(SW_RFB_T, fgIs802_11Frame)); -+ -+ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSDU_INFO_T, ucControlFlag) == OFFSET_OF(SW_RFB_T, ucControlFlag)); -+ -+ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSDU_INFO_T, rArrivalTime) == OFFSET_OF(SW_RFB_T, rArrivalTime)); -+ -+ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSDU_INFO_T, ucTC) == OFFSET_OF(SW_RFB_T, ucTC)); -+ -+#if CFG_PROFILE_BUFFER_TRACING -+ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSDU_INFO_T, eActivity[0]) == OFFSET_OF(SW_RFB_T, eActivity[0])); -+ -+ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSDU_INFO_T, rActivityTime[0]) == -+ OFFSET_OF(SW_RFB_T, rActivityTime[0])); -+#endif -+ -+#if DBG && CFG_BUFFER_FREE_CHK -+ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSDU_INFO_T, fgBufferInSource) == -+ OFFSET_OF(SW_RFB_T, fgBufferInSource)); -+#endif -+ -+ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(STA_RECORD_T, rLinkEntry) == 0); -+ -+ return; -+#endif -+} -+#endif /* _lint */ -+ -+#endif /* _CNM_MEM_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/cnm_scan.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/cnm_scan.h -new file mode 100644 -index 000000000000..cc5d0fa1adfc ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/cnm_scan.h -@@ -0,0 +1,169 @@ -+/* -+** Id: @(#) -+*/ -+ -+/*! \file "cnm_scan.h" -+ \brief -+ -+*/ -+ -+/* -+** Log: cnm_scan.h -+ * -+ * 09 03 2010 kevin.huang -+ * NULL -+ * Refine #include sequence and solve recursive/nested #include issue -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 07 05 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * remove unused definitions. -+ * -+ * 07 01 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * implementation of DRV-SCN and related mailbox message handling. -+ * -+ * 06 07 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * merge cnm_scan.h and hem_mbox.h -+ * -+ * 05 12 2010 kevin.huang -+ * [BORA00000794][WIFISYS][New Feature]Power Management Support -+ * Add Power Management - Legacy PS-POLL support. -+ * -+ * 03 30 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Support 2.4G OBSS scan -+ * -+ * 03 16 2010 kevin.huang -+ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support -+ * Add AdHoc Mode -+ * -+ * 03 10 2010 kevin.huang -+ * [BORA00000654][WIFISYS][New Feature] CNM Module - Ch Manager Support -+ * -+ * * * * Add Channel Manager for arbitration of JOIN and SCAN Req -+ * -+ * 02 23 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Add support scan channel 1~14 and update scan result's frequency infou1rwduu`wvpghlqg|n`slk+mpdkb -+ * -+ * 02 04 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Add AAA Module Support, Revise Net Type to Net Type Index for array lookup -+ * -+ * Nov 18 2009 mtk01104 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Add function prototype of cnmScanInit() -+ * -+ * Nov 5 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * -+** -+*/ -+ -+#ifndef _CNM_SCAN_H -+#define _CNM_SCAN_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+#define SCN_CHANNEL_DWELL_TIME_MIN_MSEC 12 -+#define SCN_CHANNEL_DWELL_TIME_EXT_MSEC 98 -+ -+#define SCN_TOTAL_PROBEREQ_NUM_FOR_FULL 3 -+#define SCN_SPECIFIC_PROBEREQ_NUM_FOR_FULL 1 -+ -+#define SCN_TOTAL_PROBEREQ_NUM_FOR_PARTIAL 2 -+#define SCN_SPECIFIC_PROBEREQ_NUM_FOR_PARTIAL 1 -+ -+#define SCN_INTERLACED_CHANNEL_GROUPS_NUM 3 /* Used by partial scan */ -+ -+#define SCN_PARTIAL_SCAN_NUM 3 -+ -+#define SCN_PARTIAL_SCAN_IDLE_MSEC 100 -+ -+#define MAXIMUM_OPERATION_CHANNEL_LIST 46 -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+/* The type of Scan Source */ -+typedef enum _ENUM_SCN_REQ_SOURCE_T { -+ SCN_REQ_SOURCE_HEM = 0, -+ SCN_REQ_SOURCE_NET_FSM, -+ SCN_REQ_SOURCE_ROAMING, /* ROAMING Module is independent of AIS FSM */ -+ SCN_REQ_SOURCE_OBSS, /* 2.4G OBSS scan */ -+ SCN_REQ_SOURCE_NUM -+} ENUM_SCN_REQ_SOURCE_T, *P_ENUM_SCN_REQ_SOURCE_T; -+ -+typedef enum _ENUM_SCAN_PROFILE_T { -+ SCAN_PROFILE_FULL = 0, -+ SCAN_PROFILE_PARTIAL, -+ SCAN_PROFILE_VOIP, -+ SCAN_PROFILE_FULL_2G4, -+ SCAN_PROFILE_NUM -+} ENUM_SCAN_PROFILE_T, *P_ENUM_SCAN_PROFILE_T; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+#if 0 -+VOID cnmScanInit(VOID); -+ -+VOID cnmScanRunEventScanRequest(IN P_MSG_HDR_T prMsgHdr); -+ -+BOOLEAN cnmScanRunEventScanAbort(IN P_MSG_HDR_T prMsgHdr); -+ -+VOID cnmScanProfileSelection(VOID); -+ -+VOID cnmScanProcessStart(VOID); -+ -+VOID cnmScanProcessStop(VOID); -+ -+VOID cnmScanRunEventReqAISAbsDone(IN P_MSG_HDR_T prMsgHdr); -+ -+VOID cnmScanRunEventCancelAISAbsDone(IN P_MSG_HDR_T prMsgHdr); -+ -+VOID cnmScanPartialScanTimeout(UINT_32 u4Param); -+ -+VOID cnmScanRunEventScnFsmComplete(IN P_MSG_HDR_T prMsgHdr); -+#endif -+ -+#endif /* _CNM_SCAN_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/cnm_timer.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/cnm_timer.h -new file mode 100644 -index 000000000000..a2ed9cd02fed ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/cnm_timer.h -@@ -0,0 +1,235 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/mgmt/cnm_timer.h#1 -+*/ -+ -+/*! \file cnm_timer.h -+ \brief Declaration of timer obj and related timer macro for setup time out -+ event. -+ -+ In this file we declare the timer object and provide several macro for -+ Protocol functional blocks to setup their own time out event. -+*/ -+ -+/* -+** Log: cnm_timer.h -+ * -+ * 12 13 2011 cm.chang -+ * [WCXRP00001136] [All Wi-Fi][Driver] Add wake lock for pending timer -+ * Add wake lock if timer timeout value is smaller than 5 seconds -+ * -+ * 09 03 2010 kevin.huang -+ * NULL -+ * Refine #include sequence and solve recursive/nested #include issue -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 08 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * cnm_timer has been migrated. -+ * -+ * 06 08 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add hem_mbox.c and cnm_mem.h (but disabled some feature) for further migration -+ * -+ * 06 07 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * merge cnm_scan.h and hem_mbox.h -+ * -+ * 06 07 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * merge wifi_var.h, precomp.h, cnm_timer.h (data type only) -+ * -+ * 06 04 2010 george.huang -+ * [BORA00000678][MT6620]WiFi LP integration -+ * [PM] Support U-APSD for STA mode -+ * -+ * 04 24 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Return timer token back to COS when entering wait off state -+ * -+ * 01 08 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Support longer timeout interval to 45 days from 65secu1rwduu`wvpghlqg|fh+fmdkb -+ * -+ * 01 06 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Fix system time is 32KHz instead of 1ms -+ * -+ * Nov 23 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * add the copy time function -+ * -+ * Nov 5 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Fix LINT warnning -+ * -+ * Oct 28 2009 mtk01104 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * -+** -+*/ -+ -+#ifndef _CNM_TIMER_H -+#define _CNM_TIMER_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+#undef MSEC_PER_SEC -+#define MSEC_PER_SEC 1000 -+#undef USEC_PER_MSEC -+#define USEC_PER_MSEC 1000 -+#define USEC_PER_TU 1024 /* microsecond */ -+ -+#define MSEC_PER_MIN (60 * MSEC_PER_SEC) -+ -+#define MGMT_MAX_TIMEOUT_INTERVAL ((UINT_32)0x7fffffff) -+ -+#define WAKE_LOCK_MAX_TIME 5 /* Unit: sec */ -+ -+/* If WAKE_LOCK_MAX_TIME is too large, the whole system may always keep awake -+ * because of periodic timer of OBSS scanning -+ */ -+#if (WAKE_LOCK_MAX_TIME >= OBSS_SCAN_MIN_INTERVAL) -+#error WAKE_LOCK_MAX_TIME is too large -+#endif -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+typedef VOID(*PFN_MGMT_TIMEOUT_FUNC) (P_ADAPTER_T, ULONG); -+ -+typedef struct _TIMER_T { -+ LINK_ENTRY_T rLinkEntry; -+ OS_SYSTIME rExpiredSysTime; -+ UINT_16 u2Minutes; -+ UINT_16 u2Reserved; -+ ULONG ulData; -+ PFN_MGMT_TIMEOUT_FUNC pfMgmtTimeOutFunc; -+} TIMER_T, *P_TIMER_T; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+/* Check if time "a" is before time "b" */ -+/* In 32-bit variable, 0x00000001~0x7fffffff -> positive number, -+ * 0x80000000~0xffffffff -> negative number -+ */ -+#define TIME_BEFORE_64bit(a, b) (a < b) -+ -+#define TIME_BEFORE(a, b) ((UINT_32)((UINT_32)(a) - (UINT_32)(b)) > 0x7fffffff) -+ -+/* #define TIME_BEFORE(a,b) ((INT_32)((INT_32)(b) - (INT_32)(a)) > 0) -+ * may cause UNexpect result between Free build and Check build for WinCE -+ */ -+ -+#define TIME_AFTER(a, b) TIME_BEFORE(b, a) -+ -+#define SYSTIME_TO_SEC(_systime) ((_systime) / KAL_HZ) -+#define SEC_TO_SYSTIME(_sec) ((_sec) * KAL_HZ) -+ -+/* The macros to convert second & millisecond */ -+#define MSEC_TO_SEC(_msec) ((_msec) / MSEC_PER_SEC) -+#define SEC_TO_MSEC(_sec) ((UINT_32)(_sec) * MSEC_PER_SEC) -+ -+/* The macros to convert millisecond & microsecond */ -+#define USEC_TO_MSEC(_usec) ((_usec) / USEC_PER_MSEC) -+#define MSEC_TO_USEC(_msec) ((UINT_32)(_msec) * USEC_PER_MSEC) -+ -+/* The macros to convert TU & microsecond, TU & millisecond */ -+#define TU_TO_USEC(_tu) ((_tu) * USEC_PER_TU) -+#define TU_TO_MSEC(_tu) USEC_TO_MSEC(TU_TO_USEC(_tu)) -+ -+/* The macros to convert TU & & OS system time, round up by 0.5 */ -+#define TU_TO_SYSTIME(_tu) MSEC_TO_SYSTIME(TU_TO_MSEC(_tu)) -+#define SYSTIME_TO_TU(_systime) \ -+ ((SYSTIME_TO_USEC(_systime) + ((USEC_PER_TU / 2) - 1)) / USEC_PER_TU) -+ -+/* The macros to convert OS system time & microsecond */ -+#define SYSTIME_TO_USEC(_systime) (SYSTIME_TO_MSEC(_systime) * USEC_PER_MSEC) -+ -+/* The macro to get the current OS system time */ -+#define GET_CURRENT_SYSTIME(_systime_p) {*(_systime_p) = kalGetTimeTick(); } -+ -+/* The macro to copy the system time */ -+#define COPY_SYSTIME(_destTime, _srcTime) {(_destTime) = (_srcTime); } -+ -+/* The macro to get the system time difference between t1 and t2 (t1 - t2) */ -+/* #define GET_SYSTIME_DIFFERENCE(_time1, _time2, _diffTime) \ -+ (_diffTime) = (_time1) - (_time2) */ -+ -+/* The macro to check for the expiration, if TRUE means _currentTime >= _expirationTime */ -+#define CHECK_FOR_EXPIRATION(_currentTime, _expirationTime) \ -+ (((UINT_32)(_currentTime) - (UINT_32)(_expirationTime)) <= 0x7fffffffUL) -+ -+/* The macro to check for the timeout */ -+#define CHECK_FOR_TIMEOUT(_currentTime, _timeoutStartingTime, _timeout) \ -+ CHECK_FOR_EXPIRATION((_currentTime), ((_timeoutStartingTime) + (_timeout))) -+ -+/* The macro to set the expiration time with a specified timeout *//* Watch out for round up. */ -+#define SET_EXPIRATION_TIME(_expirationTime, _timeout) \ -+ { \ -+ GET_CURRENT_SYSTIME(&(_expirationTime)); \ -+ (_expirationTime) += (OS_SYSTIME)(_timeout); \ -+ } -+ -+#define timerRenewTimer(adapter, tmr, interval) \ -+ timerStartTimer(adapter, tmr, interval, (tmr)->function, (tmr)->data) -+ -+#define MGMT_INIT_TIMER(_adapter_p, _timer, _callbackFunc) \ -+ timerInitTimer(_adapter_p, &(_timer), (ULONG)(_callbackFunc)) -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+VOID cnmTimerInitialize(IN P_ADAPTER_T prAdapter); -+ -+VOID cnmTimerDestroy(IN P_ADAPTER_T prAdapter); -+ -+VOID -+cnmTimerInitTimer(IN P_ADAPTER_T prAdapter, IN P_TIMER_T prTimer, IN PFN_MGMT_TIMEOUT_FUNC pfFunc, IN ULONG ulData); -+ -+VOID cnmTimerStopTimer(IN P_ADAPTER_T prAdapter, IN P_TIMER_T prTimer); -+ -+VOID cnmTimerStartTimer(IN P_ADAPTER_T prAdapter, IN P_TIMER_T prTimer, IN UINT_32 u4TimeoutMs); -+ -+VOID cnmTimerDoTimeOutCheck(IN P_ADAPTER_T prAdapter); -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+static inline INT_32 timerPendingTimer(IN P_TIMER_T prTimer) -+{ -+ ASSERT(prTimer); -+ -+ return prTimer->rLinkEntry.prNext != NULL; -+} -+ -+#endif /* _CNM_TIMER_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/hem_mbox.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/hem_mbox.h -new file mode 100644 -index 000000000000..868de4a6c40a ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/hem_mbox.h -@@ -0,0 +1,446 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/mgmt/hem_mbox.h#2 -+*/ -+ -+/*! \file hem_mbox.h -+ \brief -+ -+*/ -+ -+/* -+** Log: hem_mbox.h -+** -+** 07 26 2012 yuche.tsai -+** [ALPS00324337] [ALPS.JB][Hot-Spot] Driver update for Hot-Spot -+** Update driver code of ALPS.JB for hot-spot. -+** -+** 07 19 2012 yuche.tsai -+** NULL -+** Code update for JB. -+ * -+ * 03 02 2012 terry.wu -+ * NULL -+ * Sync CFG80211 modification from branch 2,2. -+ * -+ * 07 18 2011 cp.wu -+ * [WCXRP00000858] [MT5931][Driver][Firmware] Add support for scan to search for -+ * more than one SSID in a single scanning request -+ * add framework in driver domain for supporting new SCAN_REQ_V2 for more than 1 SSID -+ * support as well as uProbeDelay in NDIS 6.x driver model -+ * -+ * 06 07 2011 yuche.tsai -+ * [WCXRP00000696] [Volunteer Patch][MT6620][Driver] Infinite loop issue when RX invitation response. -+ * cnm_timer[WCXRP00000763] [Volunteer Patch][MT6620][Driver] RX Service Discovery Frame under AP mode Issue -+ * Add invitation support. -+ * -+ * 06 02 2011 cp.wu -+ * [WCXRP00000681] [MT5931][Firmware] HIF code size reduction -+ * eliminate unused parameters for SAA-FSM -+ * -+ * 01 26 2011 cm.chang -+ * [WCXRP00000395] [MT6620 Wi-Fi][Driver][FW] Search STA_REC with additional net type index argument -+ * Allocate system RAM if fixed message or mgmt buffer is not available -+ * -+ * 11 08 2010 cm.chang -+ * [WCXRP00000169] [MT6620 Wi-Fi][Driver][FW] Remove unused CNM recover message ID -+ * Remove CNM channel reover message ID -+ * -+ * 09 16 2010 cm.chang -+ * NULL -+ * Remove unused message ID -+ * -+ * 09 03 2010 kevin.huang -+ * NULL -+ * Refine #include sequence and solve recursive/nested #include issue -+ * -+ * 08 30 2010 cp.wu -+ * NULL -+ * eliminate klockwork errors -+ * -+ * 08 25 2010 george.huang -+ * NULL -+ * update OID/ registry control path for PM related settings -+ * -+ * 08 23 2010 chinghwa.yu -+ * NULL -+ * Update for BOW. -+ * -+ * 08 16 2010 cp.wu -+ * NULL -+ * add interface for RLM to trigger OBSS-SCAN. -+ * -+ * 08 11 2010 yuche.tsai -+ * NULL -+ * Add some message ID for P2P FSM under provisioning phase. -+ * -+ * 08 11 2010 yuche.tsai -+ * NULL -+ * Add Message Event ID for P2P Module. -+ * -+ * 08 05 2010 yuche.tsai -+ * NULL -+ * Check-in P2P Device Discovery Feature. -+ * -+ * 08 04 2010 cp.wu -+ * NULL -+ * remove unused mailbox message definitions. -+ * -+ * 08 02 2010 yuche.tsai -+ * NULL -+ * P2P Group Negotiation Code Check in. -+ * -+ * 07 19 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration. -+ * message table should not be commented out by compilation option without modifying header file -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 07 08 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Rename MID_MNY_CNM_CH_RELEASE to MID_MNY_CNM_CH_ABORT -+ * -+ * 07 01 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * AIS-FSM integration with CNM channel request messages -+ * -+ * 07 01 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * implementation of DRV-SCN and related mailbox message handling. -+ * -+ * 07 01 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Modify CNM message handler for new flow -+ * -+ * 06 18 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Provide cnmMgtPktAlloc() and alloc/free function of msg/buf -+ * -+ * 06 14 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * restore utility function invoking via hem_mbox to direct calls -+ * -+ * 06 11 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * auth.c is migrated. -+ * -+ * 06 10 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add buildable & linkable ais_fsm.c -+ * -+ * related reference are still waiting to be resolved -+ * -+ * 06 09 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add definitions for module migration. -+ * -+ * 06 08 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * hem_mbox is migrated. -+ * -+ * 06 07 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * merge cnm_scan.h and hem_mbox.h -+ * -+ * 05 12 2010 kevin.huang -+ * [BORA00000794][WIFISYS][New Feature]Power Management Support -+ * Add Power Management - Legacy PS-POLL support. -+ * -+ * 04 29 2010 tehuang.liu -+ * [BORA00000605][WIFISYS] Phase3 Integration -+ * Removed MID_RXM_MQM_QOS_ACTION_FRAME -+ * -+ * 04 29 2010 tehuang.liu -+ * [BORA00000605][WIFISYS] Phase3 Integration -+ * Removed MID_RXM_MQM_BA_ACTION_FRAME -+ * -+ * 03 30 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Support 2.4G OBSS scan -+ * -+ * 03 16 2010 kevin.huang -+ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support -+ * Add AdHoc Mode -+ * -+ * 03 10 2010 kevin.huang -+ * [BORA00000654][WIFISYS][New Feature] CNM Module - Ch Manager Support -+ * -+ * * * * * Add Channel Manager for arbitration of JOIN and SCAN Req -+ * -+ * 03 05 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Develop partial DPD code -+ * -+ * 02 11 2010 tehuang.liu -+ * [BORA00000569][WIFISYS] Phase 2 Integration Test -+ * Added MID_RXM_MQM_QOS_ACTION_FRAME for RXM to indicate QoS Action frames to MQM -+ * -+ * 01 11 2010 kevin.huang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Add Deauth and Disassoc Handler -+ * -+ * Dec 7 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Rename the parameter of mboxDummy() -+ * -+ * Dec 2 2009 MTK02468 -+ * [BORA00000337] To check in codes for FPGA emulation -+ * Added MID_RXM_MQM_BA_ACTION_FRAME -+ * -+ * Nov 24 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Remove Dummy MSG ID -+ * -+ * Nov 23 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Add JOIN REQ related MSG ID -+ * -+ * Nov 16 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Add AIS ABORT MSG ID -+ * -+ * Nov 5 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Add SCN MSG IDs -+ * -+ * Oct 28 2009 mtk01104 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * -+*/ -+ -+#ifndef _HEM_MBOX_H -+#define _HEM_MBOX_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+/* Message IDs */ -+typedef enum _ENUM_MSG_ID_T { -+ MID_MNY_CNM_CH_REQ, /* MANY notify CNM to obtain channel privilege */ -+ MID_MNY_CNM_CH_ABORT, /* MANY notify CNM to abort/release channel privilege */ -+ -+ MID_CNM_AIS_CH_GRANT, /* CNM notify AIS for indicating channel granted */ -+ MID_CNM_P2P_CH_GRANT, /* CNM notify P2P for indicating channel granted */ -+ MID_CNM_BOW_CH_GRANT, /* CNM notify BOW for indicating channel granted */ -+ -+ /*--------------------------------------------------*/ -+ /* SCN Module Mailbox Messages */ -+ /*--------------------------------------------------*/ -+ MID_AIS_SCN_SCAN_REQ, /* AIS notify SCN for starting scan */ -+ MID_AIS_SCN_SCAN_REQ_V2, /* AIS notify SCN for starting scan with multiple SSID support */ -+ MID_AIS_SCN_SCAN_CANCEL, /* AIS notify SCN for cancelling scan */ -+ MID_P2P_SCN_SCAN_REQ, /* P2P notify SCN for starting scan */ -+ MID_P2P_SCN_SCAN_REQ_V2, /* P2P notify SCN for starting scan with multiple SSID support */ -+ MID_P2P_SCN_SCAN_CANCEL, /* P2P notify SCN for cancelling scan */ -+ MID_BOW_SCN_SCAN_REQ, /* BOW notify SCN for starting scan */ -+ MID_BOW_SCN_SCAN_REQ_V2, /* BOW notify SCN for starting scan with multiple SSID support */ -+ MID_BOW_SCN_SCAN_CANCEL, /* BOW notify SCN for cancelling scan */ -+ MID_RLM_SCN_SCAN_REQ, /* RLM notify SCN for starting scan (OBSS-SCAN) */ -+ MID_RLM_SCN_SCAN_REQ_V2, /* RLM notify SCN for starting scan (OBSS-SCAN) with multiple SSID support */ -+ MID_RLM_SCN_SCAN_CANCEL, /* RLM notify SCN for cancelling scan (OBSS-SCAN) */ -+ MID_SCN_AIS_SCAN_DONE, /* SCN notify AIS for scan completion */ -+ MID_SCN_P2P_SCAN_DONE, /* SCN notify P2P for scan completion */ -+ MID_SCN_BOW_SCAN_DONE, /* SCN notify BOW for scan completion */ -+ MID_SCN_RLM_SCAN_DONE, /* SCN notify RLM for scan completion (OBSS-SCAN) */ -+ -+ /*--------------------------------------------------*/ -+ /* AIS Module Mailbox Messages */ -+ /*--------------------------------------------------*/ -+ MID_OID_AIS_FSM_JOIN_REQ, /* OID/IOCTL notify AIS for join */ -+ MID_OID_AIS_FSM_ABORT, /* OID/IOCTL notify AIS for abort */ -+ MID_AIS_SAA_FSM_START, /* AIS notify SAA for Starting authentication/association fsm */ -+ MID_AIS_SAA_FSM_ABORT, /* AIS notify SAA for Aborting authentication/association fsm */ -+ MID_SAA_AIS_JOIN_COMPLETE, /* SAA notify AIS for indicating join complete */ -+ -+#if CFG_ENABLE_BT_OVER_WIFI -+ /*--------------------------------------------------*/ -+ /* BOW Module Mailbox Messages */ -+ /*--------------------------------------------------*/ -+ MID_BOW_SAA_FSM_START, /* BOW notify SAA for Starting authentication/association fsm */ -+ MID_BOW_SAA_FSM_ABORT, /* BOW notify SAA for Aborting authentication/association fsm */ -+ MID_SAA_BOW_JOIN_COMPLETE, /* SAA notify BOW for indicating join complete */ -+#endif -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ /*--------------------------------------------------*/ -+ /* P2P Module Mailbox Messages */ -+ /*--------------------------------------------------*/ -+ MID_P2P_SAA_FSM_START, /* P2P notify SAA for Starting authentication/association fsm */ -+ MID_P2P_SAA_FSM_ABORT, /* P2P notify SAA for Aborting authentication/association fsm */ -+ MID_SAA_P2P_JOIN_COMPLETE, /* SAA notify P2P for indicating join complete */ -+ -+ MID_MNY_P2P_FUN_SWITCH, /* Enable P2P FSM. */ -+ MID_MNY_P2P_DEVICE_DISCOVERY, /* Start device discovery. */ -+ MID_MNY_P2P_CONNECTION_REQ, /* Connection request. */ -+ MID_MNY_P2P_CONNECTION_ABORT, /* Abort connection request, P2P FSM return to IDLE. */ -+ MID_MNY_P2P_BEACON_UPDATE, -+ MID_MNY_P2P_STOP_AP, -+ MID_MNY_P2P_CHNL_REQ, -+ MID_MNY_P2P_CHNL_ABORT, -+ MID_MNY_P2P_MGMT_TX, -+ MID_MNY_P2P_GROUP_DISSOLVE, -+ MID_MNY_P2P_MGMT_FRAME_REGISTER, -+ MID_MNY_P2P_NET_DEV_REGISTER, -+ MID_MNY_P2P_START_AP, -+ MID_MNY_P2P_MGMT_FRAME_UPDATE, -+ MID_MNY_P2P_EXTEND_LISTEN_INTERVAL, -+#if CFG_SUPPORT_WFD -+ MID_MNY_P2P_WFD_CFG_UPDATE, -+#endif -+#endif -+ -+#if CFG_SUPPORT_ADHOC -+ MID_SCN_AIS_FOUND_IBSS, /* SCN notify AIS that an IBSS Peer has been found and can merge into */ -+#endif /* CFG_SUPPORT_ADHOC */ -+ -+ MID_SAA_AIS_FSM_ABORT, /* SAA notify AIS for indicating deauthentication/disassociation */ -+ -+ /*--------------------------------------------------*/ -+ /* AIS MGMT-TX Support */ -+ /*--------------------------------------------------*/ -+ MID_MNY_AIS_REMAIN_ON_CHANNEL, -+ MID_MNY_AIS_CANCEL_REMAIN_ON_CHANNEL, -+ MID_MNY_AIS_MGMT_TX, -+ -+ MID_TOTAL_NUM -+} ENUM_MSG_ID_T, *P_ENUM_MSG_ID_T; -+ -+/* Message header of inter-components */ -+struct _MSG_HDR_T { -+ LINK_ENTRY_T rLinkEntry; -+ ENUM_MSG_ID_T eMsgId; -+}; -+ -+typedef VOID(*PFN_MSG_HNDL_FUNC) (P_ADAPTER_T, P_MSG_HDR_T); -+ -+typedef struct _MSG_HNDL_ENTRY { -+ ENUM_MSG_ID_T eMsgId; -+ PFN_MSG_HNDL_FUNC pfMsgHndl; -+} MSG_HNDL_ENTRY_T, *P_MSG_HNDL_ENTRY_T; -+ -+typedef enum _EUNM_MSG_SEND_METHOD_T { -+ MSG_SEND_METHOD_BUF = 0, /* Message is put in the queue and will be -+ executed when mailbox is checked. */ -+ MSG_SEND_METHOD_UNBUF /* The handler function is called immediately -+ in the same context of the sender */ -+} EUNM_MSG_SEND_METHOD_T, *P_EUNM_MSG_SEND_METHOD_T; -+ -+typedef enum _ENUM_MBOX_ID_T { -+ MBOX_ID_0 = 0, -+ MBOX_ID_TOTAL_NUM -+} ENUM_MBOX_ID_T, *P_ENUM_MBOX_ID_T; -+ -+/* Define Mailbox structure */ -+typedef struct _MBOX_T { -+ LINK_T rLinkHead; -+} MBOX_T, *P_MBOX_T; -+ -+typedef struct _MSG_SAA_FSM_START_T { -+ MSG_HDR_T rMsgHdr; /* Must be the first member */ -+ UINT_8 ucSeqNum; -+ P_STA_RECORD_T prStaRec; -+} MSG_SAA_FSM_START_T, *P_MSG_SAA_FSM_START_T; -+ -+typedef struct _MSG_SAA_FSM_COMP_T { -+ MSG_HDR_T rMsgHdr; /* Must be the first member */ -+ UINT_8 ucSeqNum; -+ WLAN_STATUS rJoinStatus; -+ P_STA_RECORD_T prStaRec; -+ P_SW_RFB_T prSwRfb; -+} MSG_SAA_FSM_COMP_T, *P_MSG_SAA_FSM_COMP_T; -+ -+typedef struct _MSG_SAA_FSM_ABORT_T { -+ MSG_HDR_T rMsgHdr; /* Must be the first member */ -+ UINT_8 ucSeqNum; -+ P_STA_RECORD_T prStaRec; -+} MSG_SAA_FSM_ABORT_T, *P_MSG_SAA_FSM_ABORT_T; -+ -+typedef struct _MSG_CONNECTION_ABORT_T { -+ MSG_HDR_T rMsgHdr; /* Must be the first member */ -+ UINT_8 ucNetTypeIndex; -+} MSG_CONNECTION_ABORT_T, *P_MSG_CONNECTION_ABORT_T; -+ -+typedef struct _MSG_REMAIN_ON_CHANNEL_T { -+ MSG_HDR_T rMsgHdr; /* Must be the first member */ -+ ENUM_BAND_T eBand; -+ ENUM_CHNL_EXT_T eSco; -+ UINT_8 ucChannelNum; -+ UINT_32 u4DurationMs; -+ UINT_64 u8Cookie; -+} MSG_REMAIN_ON_CHANNEL_T, *P_MSG_REMAIN_ON_CHANNEL_T; -+ -+typedef struct _MSG_CANCEL_REMAIN_ON_CHANNEL_T { -+ MSG_HDR_T rMsgHdr; /* Must be the first member */ -+ UINT_64 u8Cookie; -+} MSG_CANCEL_REMAIN_ON_CHANNEL_T, *P_MSG_CANCEL_REMAIN_ON_CHANNEL_T; -+ -+typedef struct _MSG_MGMT_TX_REQUEST_T { -+ MSG_HDR_T rMsgHdr; -+ P_MSDU_INFO_T prMgmtMsduInfo; -+ UINT_64 u8Cookie; /* For indication. */ -+ BOOLEAN fgNoneCckRate; -+ BOOLEAN fgIsWaitRsp; -+} MSG_MGMT_TX_REQUEST_T, *P_MSG_MGMT_TX_REQUEST_T; -+ -+/* specific message data types */ -+typedef MSG_SAA_FSM_START_T MSG_JOIN_REQ_T, *P_MSG_JOIN_REQ_T; -+typedef MSG_SAA_FSM_COMP_T MSG_JOIN_COMP_T, *P_MSG_JOIN_COMP_T; -+typedef MSG_SAA_FSM_ABORT_T MSG_JOIN_ABORT_T, *P_MSG_JOIN_ABORT_T; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+VOID mboxSetup(IN P_ADAPTER_T prAdapter, IN ENUM_MBOX_ID_T eMboxId); -+ -+VOID -+mboxSendMsg(IN P_ADAPTER_T prAdapter, -+ IN ENUM_MBOX_ID_T eMboxId, IN P_MSG_HDR_T prMsg, IN EUNM_MSG_SEND_METHOD_T eMethod); -+ -+VOID mboxRcvAllMsg(IN P_ADAPTER_T prAdapter, IN ENUM_MBOX_ID_T eMboxId); -+ -+VOID mboxInitialize(IN P_ADAPTER_T prAdapter); -+ -+VOID mboxDestroy(IN P_ADAPTER_T prAdapter); -+ -+VOID mboxDummy(IN P_ADAPTER_T prAdapter, P_MSG_HDR_T prMsgHdr); -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif /* _HEM_MBOX_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/hs20.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/hs20.h -new file mode 100644 -index 000000000000..88b99222133f ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/hs20.h -@@ -0,0 +1,148 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/HS2_DEV_SW/MT6620_WIFI_DRIVER_V2_1_HS_2_0/include/mgmt/hs20.h#2 -+*/ -+ -+/*! \file hs20.h -+ \brief This file contains the function declaration for hs20.c. -+*/ -+ -+/* -+** Log: -+ * -+ */ -+ -+#ifndef _HS20_H -+#define _HS20_H -+ -+#if CFG_SUPPORT_HOTSPOT_2_0 -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+#define BSSID_POOL_MAX_SIZE 8 -+#define HS20_SIGMA_SCAN_RESULT_TIMEOUT 30 /* sec */ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+#if CFG_ENABLE_GTK_FRAME_FILTER -+/*For GTK Frame Filter*/ -+typedef struct _IPV4_NETWORK_ADDRESS_LIST { -+ UINT_8 ucAddrCount; -+ IPV4_NETWORK_ADDRESS arNetAddr[1]; -+} IPV4_NETWORK_ADDRESS_LIST, *P_IPV4_NETWORK_ADDRESS_LIST; -+#endif -+ -+/* Entry of BSSID Pool - For SIGMA Test */ -+typedef struct _BSSID_ENTRY_T { -+ UINT_8 aucBSSID[MAC_ADDR_LEN]; -+} BSSID_ENTRY_T, P_HS20_BSSID_POOL_ENTRY_T; -+ -+struct _HS20_INFO_T { -+ -+ /*Hotspot 2.0 Information */ -+ UINT_8 aucHESSID[MAC_ADDR_LEN]; -+ UINT_8 ucAccessNetworkOptions; -+ UINT_8 ucVenueGroup; /* VenueInfo - Group */ -+ UINT_8 ucVenueType; -+ UINT_8 ucHotspotConfig; -+ -+ /*Roaming Consortium Information */ -+ /* PARAM_HS20_ROAMING_CONSORTIUM_INFO rRCInfo; */ -+ -+ /*Hotspot 2.0 dummy AP Info */ -+ -+ /*Time Advertisement Information */ -+ /* UINT_32 u4UTCOffsetTime; */ -+ /* UINT_8 aucTimeZone[ELEM_MAX_LEN_TIME_ZONE]; */ -+ /* UINT_8 ucLenTimeZone; */ -+ -+ /* For SIGMA Test */ -+ /* BSSID Pool */ -+ BSSID_ENTRY_T arBssidPool[BSSID_POOL_MAX_SIZE]; -+ UINT_8 ucNumBssidPoolEntry; -+ BOOLEAN fgIsHS2SigmaMode; -+ -+}; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/*For GTK Frame Filter*/ -+#if DBG -+#define FREE_IPV4_NETWORK_ADDR_LIST(_prAddrList) \ -+ { \ -+ UINT_32 u4Size = OFFSET_OF(IPV4_NETWORK_ADDRESS_LIST, arNetAddr) + \ -+ (((_prAddrList)->ucAddrCount) * sizeof(IPV4_NETWORK_ADDRESS)); \ -+ kalMemFree((_prAddrList), VIR_MEM_TYPE, u4Size); \ -+ (_prAddrList) = NULL; \ -+ } -+#else -+#define FREE_IPV4_NETWORK_ADDR_LIST(_prAddrList) \ -+ { \ -+ kalMemFree((_prAddrList), VIR_MEM_TYPE, 0); \ -+ (_prAddrList) = NULL; \ -+ } -+#endif -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+VOID hs20GenerateInterworkingIE(IN P_ADAPTER_T prAdapter, OUT P_MSDU_INFO_T prMsduInfo); -+ -+VOID hs20GenerateRoamingConsortiumIE(IN P_ADAPTER_T prAdapter, OUT P_MSDU_INFO_T prMsduInfo); -+ -+VOID hs20GenerateHS20IE(IN P_ADAPTER_T prAdapter, OUT P_MSDU_INFO_T prMsduInfo); -+ -+VOID hs20FillExtCapIE(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo, P_MSDU_INFO_T prMsduInfo); -+ -+VOID hs20FillProreqExtCapIE(IN P_ADAPTER_T prAdapter, OUT PUINT_8 pucIE); -+ -+VOID hs20FillHS20IE(IN P_ADAPTER_T prAdapter, OUT PUINT_8 pucIE); -+ -+UINT_32 hs20CalculateHS20RelatedIEForProbeReq(IN P_ADAPTER_T prAdapter, IN PUINT_8 pucTargetBSSID); -+ -+WLAN_STATUS hs20GenerateHS20RelatedIEForProbeReq(IN P_ADAPTER_T prAdapter, IN PUINT_8 pucTargetBSSID, OUT PUINT_8 prIE); -+ -+BOOLEAN hs20IsGratuitousArp(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prCurrSwRfb); -+ -+BOOLEAN hs20IsUnsolicitedNeighborAdv(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prCurrSwRfb); -+ -+#if CFG_ENABLE_GTK_FRAME_FILTER -+BOOLEAN hs20IsForgedGTKFrame(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prBssInfo, IN P_SW_RFB_T prCurrSwRfb); -+#endif -+ -+BOOLEAN hs20IsUnsecuredFrame(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prBssInfo, IN P_SW_RFB_T prCurrSwRfb); -+ -+BOOLEAN hs20IsFrameFilterEnabled(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prBssInfo); -+ -+WLAN_STATUS hs20SetBssidPool(IN P_ADAPTER_T prAdapter, IN PVOID pvBuffer, IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIdx); -+ -+#endif -+#endif -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/mib.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/mib.h -new file mode 100644 -index 000000000000..cb89fd8793ee ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/mib.h -@@ -0,0 +1,153 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/mgmt/mib.h#1 -+*/ -+ -+/*! \file mib.h -+ \brief This file contains the IEEE 802.11 family related MIB definition -+ for MediaTek 802.11 Wireless LAN Adapters. -+*/ -+ -+/* -+** Log: mib.h -+ * -+ * 11 08 2010 wh.su -+ * [WCXRP00000171] [MT6620 Wi-Fi][Driver] Add message check code same behavior as mt5921 -+ * add the message check code from mt5921. -+ * -+ * 07 24 2010 wh.su -+ * -+ * .support the Wi-Fi RSN -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 07 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add aa_fsm.h, ais_fsm.h, bss.h, mib.h and scan.h. -+ * -+ * 02 04 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Add AAA Module Support, Revise Net Type to Net Type Index for array lookup -+ * -+ * Nov 23 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * -+*/ -+ -+#ifndef _MIB_H -+#define _MIB_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+/* Entry in SMT AuthenticationAlgorithms Table: dot11AuthenticationAlgorithmsEntry */ -+typedef struct _DOT11_AUTHENTICATION_ALGORITHMS_ENTRY { -+ BOOLEAN dot11AuthenticationAlgorithmsEnable; /* dot11AuthenticationAlgorithmsEntry 3 */ -+} DOT11_AUTHENTICATION_ALGORITHMS_ENTRY, *P_DOT11_AUTHENTICATION_ALGORITHMS_ENTRY; -+ -+/* Entry in SMT dot11RSNAConfigPairwiseCiphersTalbe Table: dot11RSNAConfigPairwiseCiphersEntry */ -+typedef struct _DOT11_RSNA_CONFIG_PAIRWISE_CIPHERS_ENTRY { -+ UINT_32 dot11RSNAConfigPairwiseCipher; /* dot11RSNAConfigPairwiseCiphersEntry 2 */ -+ BOOLEAN dot11RSNAConfigPairwiseCipherEnabled; /* dot11RSNAConfigPairwiseCiphersEntry 3 */ -+} DOT11_RSNA_CONFIG_PAIRWISE_CIPHERS_ENTRY, *P_DOT11_RSNA_CONFIG_PAIRWISE_CIPHERS_ENTRY; -+ -+/* Entry in SMT dot11RSNAConfigAuthenticationSuitesTalbe Table: dot11RSNAConfigAuthenticationSuitesEntry */ -+typedef struct _DOT11_RSNA_CONFIG_AUTHENTICATION_SUITES_ENTRY { -+ UINT_32 dot11RSNAConfigAuthenticationSuite; /* dot11RSNAConfigAuthenticationSuitesEntry 2 */ -+ BOOLEAN dot11RSNAConfigAuthenticationSuiteEnabled; /* dot11RSNAConfigAuthenticationSuitesEntry 3 */ -+} DOT11_RSNA_CONFIG_AUTHENTICATION_SUITES_ENTRY, *P_DOT11_RSNA_CONFIG_AUTHENTICATION_SUITES_ENTRY; -+ -+/* ----- IEEE 802.11 MIB Major sections ----- */ -+typedef struct _IEEE_802_11_MIB_T { -+ /* dot11PrivacyTable (dot11smt 5) */ -+ UINT_8 dot11WEPDefaultKeyID; /* dot11PrivacyEntry 2 */ -+ BOOLEAN dot11TranmitKeyAvailable; -+ UINT_32 dot11WEPICVErrorCount; /* dot11PrivacyEntry 5 */ -+ UINT_32 dot11WEPExcludedCount; /* dot11PrivacyEntry 6 */ -+ -+ /* dot11RSNAConfigTable (dot11smt 8) */ -+ UINT_32 dot11RSNAConfigGroupCipher; /* dot11RSNAConfigEntry 4 */ -+ -+ /* dot11RSNAConfigPairwiseCiphersTable (dot11smt 9) */ -+ DOT11_RSNA_CONFIG_PAIRWISE_CIPHERS_ENTRY dot11RSNAConfigPairwiseCiphersTable[MAX_NUM_SUPPORTED_CIPHER_SUITES]; -+ -+ /* dot11RSNAConfigAuthenticationSuitesTable (dot11smt 10) */ -+ DOT11_RSNA_CONFIG_AUTHENTICATION_SUITES_ENTRY -+ dot11RSNAConfigAuthenticationSuitesTable[MAX_NUM_SUPPORTED_AKM_SUITES]; -+ -+#if 0 /* SUPPORT_WAPI */ -+ BOOLEAN fgWapiKeyInstalled; -+ PARAM_WPI_KEY_T rWapiPairwiseKey[2]; -+ BOOLEAN fgPairwiseKeyUsed[2]; -+ UINT_8 ucWpiActivedPWKey; /* Must be 0 or 1, by wapi spec */ -+ PARAM_WPI_KEY_T rWapiGroupKey[2]; -+ BOOLEAN fgGroupKeyUsed[2]; -+#endif -+} IEEE_802_11_MIB_T, *P_IEEE_802_11_MIB_T; -+ -+/* ------------------ IEEE 802.11 non HT PHY characteristics ---------------- */ -+typedef const struct _NON_HT_PHY_ATTRIBUTE_T { -+ UINT_16 u2SupportedRateSet; -+ -+ BOOLEAN fgIsShortPreambleOptionImplemented; -+ -+ BOOLEAN fgIsShortSlotTimeOptionImplemented; -+ -+} NON_HT_PHY_ATTRIBUTE_T, *P_NON_HT_PHY_ATTRIBUTE_T; -+ -+typedef const struct _NON_HT_ADHOC_MODE_ATTRIBUTE_T { -+ -+ ENUM_PHY_TYPE_INDEX_T ePhyTypeIndex; -+ -+ UINT_16 u2BSSBasicRateSet; -+ -+} NON_HT_ADHOC_MODE_ATTRIBUTE_T, *P_NON_HT_ADHOC_MODE_ATTRIBUTE_T; -+ -+typedef NON_HT_ADHOC_MODE_ATTRIBUTE_T NON_HT_AP_MODE_ATTRIBUTE_T; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+extern NON_HT_PHY_ATTRIBUTE_T rNonHTPhyAttributes[]; -+extern NON_HT_ADHOC_MODE_ATTRIBUTE_T rNonHTAdHocModeAttributes[]; -+extern NON_HT_AP_MODE_ATTRIBUTE_T rNonHTApModeAttributes[]; -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif /* _MIB_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_assoc.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_assoc.h -new file mode 100644 -index 000000000000..11145c31dbfa ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_assoc.h -@@ -0,0 +1,55 @@ -+/* -+** Id: //Department/DaVinci/TRUNK/WiFi_P2P_Driver/include/mgmt/p2p_assoc.h#1 -+*/ -+ -+/*! \file p2p_assoc.h -+ \brief This file contains the Wi-Fi Direct ASSOC REQ/RESP of -+ IEEE 802.11 family for MediaTek 802.11 Wireless LAN Adapters. -+*/ -+ -+#ifndef _P2P_ASSOC_H -+#define _P2P_ASSOC_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+PUINT_8 p2pBuildReAssocReqFrameCommonIEs(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo, IN PUINT_8 pucBuffer); -+ -+#endif -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_bss.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_bss.h -new file mode 100644 -index 000000000000..869d7bf0ee61 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_bss.h -@@ -0,0 +1,56 @@ -+/* -+** Id: //Department/DaVinci/TRUNK/WiFi_P2P_Driver/include/mgmt/p2p_bss.h#2 -+*/ -+ -+/*! \file "p2p_bss.h" -+ \brief In this file we define the function prototype used in p2p BSS/IBSS. -+ -+ The file contains the function declarations and defines for used in BSS/IBSS. -+*/ -+ -+#ifndef _P2P_BSS_H -+#define _P2P_BSS_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+UINT_32 p2pGetTxProbRspIeTableSize(VOID); -+ -+#endif -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_fsm.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_fsm.h -new file mode 100644 -index 000000000000..2541e1d2883e ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_fsm.h -@@ -0,0 +1,2190 @@ -+/* -+** Id: //Department/DaVinci/TRUNK/WiFi_P2P_Driver/include/mgmt/p2p_fsm.h#23 -+*/ -+ -+/*! \file p2p_fsm.h -+ \brief Declaration of functions and finite state machine for P2P Module. -+ -+ Declaration of functions and finite state machine for P2P Module. -+*/ -+ -+/* -+** Log: p2p_fsm.h -+** -+** 09 12 2012 wcpadmin -+** [ALPS00276400] Remove MTK copyright and legal header on GPL/LGPL related packages -+** . -+** -+** 08 14 2012 yuche.tsai -+** NULL -+** Fix compile error. -+** -+** 07 26 2012 yuche.tsai -+** [ALPS00324337] [ALPS.JB][Hot-Spot] Driver update for Hot-Spot -+** Update driver code of ALPS.JB for hot-spot. -+** -+** 07 19 2012 yuche.tsai -+** NULL -+** Code update for JB. -+ * -+ * 07 18 2012 yuche.tsai -+ * NULL -+ * add one file. -+ * -+ * 12 02 2011 yuche.tsai -+ * NULL -+ * Resolve class 3 error issue under AP mode. -+ * -+ * data frame may TX before Assoc Response TX. -+ * -+ * 11 11 2011 yuche.tsai -+ * NULL -+ * Fix work thread cancel issue. -+ * -+ * 11 11 2011 yuche.tsai -+ * NULL -+ * Fix default device name issue. -+ * -+ * 11 09 2011 yuche.tsai -+ * [WCXRP00001093] [Need Patch][Volunteer Patch] Service Discovery 2.0 state transition issue. -+ * Fix SD2.0 issue which may cause KE. (Monkey test) -+ * -+ * 11 08 2011 yuche.tsai -+ * [WCXRP00001094] [Volunteer Patch][Driver] Driver version & supplicant version -+ * query & set support for service discovery version check. -+ * Add support for driver version query & p2p supplicant verseion set. -+ * For new service discovery mechanism sync. -+ * -+ * 10 18 2011 yuche.tsai -+ * [WCXRP00001045] [WiFi Direct][Driver] Check 2.1 branch. -+ * Support Channel Query. -+ * -+ * 10 18 2011 yuche.tsai -+ * [WCXRP00001045] [WiFi Direct][Driver] Check 2.1 branch. -+ * New 2.1 branch -+ -+ * -+ * 09 01 2011 yuche.tsai -+ * NULL -+ * Fix channel stay interval. -+ * Sync channel stay interval & channel request interval under AP mode.. -+ * -+ * 08 30 2011 yuche.tsai -+ * [WCXRP00000953] [Volunteer Patch][Driver] Hot Spot Channel ASSERT issue. -+ * Fix hot spot FW assert issue when under concurrent case. (DBG enable only) -+ * -+ * 08 16 2011 cp.wu -+ * [WCXRP00000934] [MT6620 Wi-Fi][Driver][P2P] Wi-Fi hot spot with auto sparse channel residence -+ * auto channel decision for 2.4GHz hot spot mode -+ * -+ * 08 16 2011 yuche.tsai -+ * NULL -+ * Fix scan policy for Active LISTEN scan. -+ * -+ * 08 09 2011 yuche.tsai -+ * [WCXRP00000919] [Volunteer Patch][WiFi Direct][Driver] Invitation New Feature. -+ * Invitation Feature add on. -+ * -+ * 08 02 2011 yuche.tsai -+ * [WCXRP00000896] [Volunteer Patch][WiFi Direct][Driver] GO with multiple client, -+ * TX deauth to a disconnecting device issue. -+ * Support TX Deauth Issue. -+ * -+ * 07 26 2011 yuche.tsai -+ * [WCXRP00000875] [Volunteer Patch][WiFi Direct][Driver] MT6620 IOT issue with realtek test bed solution. -+ * Turn off persistent group support for V2.0 release. -+ * -+ * 07 18 2011 yuche.tsai -+ * [WCXRP00000856] [Volunteer Patch][WiFi Direct][Driver] MT6620 WiFi Direct IOT Issue with BCM solution. -+ * Fix compile error. -+ * -+ * 07 18 2011 yuche.tsai -+ * [WCXRP00000856] [Volunteer Patch][WiFi Direct][Driver] MT6620 WiFi Direct IOT Issue with BCM solution. -+ * Fix MT6620 WiFi Direct IOT Issue with BCM solution. -+ * -+ * 07 11 2011 yuche.tsai -+ * [WCXRP00000845] [Volunteer Patch][WiFi Direct] WiFi Direct Device Connection Robustness -+ * Enhance Connection Robustness. -+ * -+ * 07 08 2011 yuche.tsai -+ * [WCXRP00000841] [Volunteer Patch][WiFi Direct] Group Owner Setting. -+ * Update GO configure parameter. -+ * -+ * 07 05 2011 yuche.tsai -+ * [WCXRP00000821] [Volunteer Patch][WiFi Direct][Driver] WiFi Direct Connection Speed Issue -+ * Disable enhancement II for debugging. -+ * -+ * 07 05 2011 yuche.tsai -+ * [WCXRP00000821] [Volunteer Patch][WiFi Direct][Driver] WiFi Direct Connection Speed Issue -+ * Refine compile flag. -+ * -+ * 07 05 2011 yuche.tsai -+ * [WCXRP00000821] [Volunteer Patch][WiFi Direct][Driver] WiFi Direct Connection Speed Issue -+ * Add wifi direct connection enhancement method I, II & VI. -+ * -+ * 06 20 2011 yuche.tsai -+ * [WCXRP00000799] [Volunteer Patch][MT6620][Driver] Connection Indication Twice Issue. -+ * Fix connection indication twice issue. -+ * -+ * 06 07 2011 yuche.tsai -+ * [WCXRP00000763] [Volunteer Patch][MT6620][Driver] RX Service Discovery Frame under AP mode Issue -+ * Fix RX SD request under AP mode issue. -+ * -+ * 05 04 2011 yuche.tsai -+ * NULL -+ * Support partial persistent group function. -+ * -+ * 04 20 2011 terry.wu -+ * [WCXRP00000660] [MT6620 Wi-Fi][Driver] Remove flag CFG_WIFI_DIRECT_MOVED -+ * Remove CFG_WIFI_DIRECT_MOVED. -+ * -+ * 04 08 2011 yuche.tsai -+ * [WCXRP00000624] [Volunteer Patch][MT6620][Driver] Add device discoverability support for GO. -+ * Add device discoverability support. -+ * -+ * 03 25 2011 yuche.tsai -+ * NULL -+ * Improve some error handleing. -+ * -+ * 03 22 2011 george.huang -+ * [WCXRP00000504] [MT6620 Wi-Fi][FW] Support Sigma CAPI for power saving related command -+ * link with supplicant commands -+ * -+ * 03 22 2011 yuche.tsai -+ * NULL -+ * 1.Shorten the LISTEN interval. -+ * 2. Fix IF address issue when we are GO -+ * 3. Fix LISTEN channel issue. -+ * -+ * 03 21 2011 yuche.tsai -+ * NULL -+ * Change P2P Connection Request Flow. -+ * -+ * 03 19 2011 yuche.tsai -+ * [WCXRP00000584] [Volunteer Patch][MT6620][Driver] Add beacon timeout support for WiFi Direct. -+ * Add beacon timeout support. -+ * -+ * 03 19 2011 yuche.tsai -+ * [WCXRP00000581] [Volunteer Patch][MT6620][Driver] P2P IE in Assoc Req Issue -+ * Append P2P IE in Assoc Req, so that GC can be discovered in probe response of GO. -+ * -+ * 03 18 2011 yuche.tsai -+ * [WCXRP00000574] [Volunteer Patch][MT6620][Driver] Modify P2P FSM Connection Flow -+ * Modify connection flow after Group Formation Complete, or device connect to a GO. -+ * Instead of request channel & connect directly, we use scan to allocate channel bandwidth & connect after RX BCN. -+ * -+ * 03 15 2011 yuche.tsai -+ * [WCXRP00000560] [Volunteer Patch][MT6620][Driver] P2P Connection from UI using KEY/DISPLAY issue -+ * Fix some configure method issue. -+ * -+ * 03 10 2011 yuche.tsai -+ * NULL -+ * Add P2P API. -+ * -+ * 03 07 2011 yuche.tsai -+ * [WCXRP00000502] [Volunteer Patch][MT6620][Driver] Fix group ID issue when doing Group Formation. -+ * . -+ * -+ * 03 07 2011 wh.su -+ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code -+ * rename the define to anti_pviracy. -+ * -+ * 03 05 2011 wh.su -+ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code -+ * add the code to get the check rsponse and indicate to app. -+ * -+ * 03 01 2011 yuche.tsai -+ * [WCXRP00000501] [Volunteer Patch][MT6620][Driver] No common channel issue when doing GO formation -+ * Update channel issue when doing GO formation.. -+ * -+ * 03 01 2011 yuche.tsai -+ * [WCXRP00000245] 1. Invitation Request/Response. -+2. Provision Discovery Request/Response -+ -+ * Update Service Discovery Related wlanoid function. -+ * -+ * 02 18 2011 wh.su -+ * [WCXRP00000471] [MT6620 Wi-Fi][Driver] Add P2P Provison discovery append Config Method attribute at WSC IE -+ * fixed the ioctl setting that index not map to spec defined config method. -+ * -+ * 02 18 2011 yuche.tsai -+ * [WCXRP00000480] [Volunteer Patch][MT6620][Driver] WCS IE format issue -+ * Fix WSC IE BE format issue. -+ * -+ * 02 17 2011 wh.su -+ * [WCXRP00000471] [MT6620 Wi-Fi][Driver] Add P2P Provison discovery append Config Method attribute at WSC IE -+ * append the WSC IE config method attribute at provision discovery request. -+ * -+ * 02 11 2011 yuche.tsai -+ * [WCXRP00000431] [Volunteer Patch][MT6620][Driver] Add MLME support for deauthentication under AP(Hot-Spot) mode. -+ * Add two function prototype. -+ * -+ * 02 10 2011 yuche.tsai -+ * [WCXRP00000431] [Volunteer Patch][MT6620][Driver] Add MLME support for deauthentication under AP(Hot-Spot) mode. -+ * Support Disassoc & Deauthentication for Hot-Spot. -+ * -+ * 02 09 2011 yuche.tsai -+ * [WCXRP00000245] 1. Invitation Request/Response. -+ -+2. Provision Discovery Request/Response -+ -+ * Add Service Discovery Indication Related code. -+ * -+ * 02 09 2011 yuche.tsai -+ * [WCXRP00000431] [Volunteer Patch][MT6620][Driver] Add MLME support for deauthentication under AP(Hot-Spot) mode. -+ * Add Support for MLME deauthentication for Hot-Spot. -+ * -+ * 02 09 2011 yuche.tsai -+ * [WCXRP00000429] [Volunteer Patch][MT6620][Driver] Hot Spot Client Limit Issue -+ * Fix Client Limit Issue. -+ * -+ * 01 26 2011 yuche.tsai -+ * [WCXRP00000245] 1. Invitation Request/Response. -+ -+2. Provision Discovery Request/Response -+ -+ * Add Service Discovery Function. -+ * -+ * 01 25 2011 terry.wu -+ * [WCXRP00000393] [MT6620 Wi-Fi][Driver] Add new module insert parameter -+ * Add a new module parameter to indicate current runnig mode, P2P or AP. -+ * -+ * 01 19 2011 george.huang -+ * [WCXRP00000355] [MT6620 Wi-Fi] Set WMM-PS related setting with qualifying AP capability -+ * Null NOA attribute setting when no related parameters. -+ * -+ * 01 12 2011 yuche.tsai -+ * [WCXRP00000352] [Volunteer Patch][MT6620][Driver] P2P Statsion Record Client List Issue -+ * Modify some behavior of AP mode. -+ * -+ * 12 22 2010 yuche.tsai -+ * [WCXRP00000245] 1. Invitation Request/Response. -+2. Provision Discovery Request/Response -+ -+ * Fix Compile Error. -+ * -+ * 12 15 2010 yuche.tsai -+ * [WCXRP00000245] 1. Invitation Request/Response. -+2. Provision Discovery Request/Response -+ -+ * Refine Connection Flow. -+ * -+ * 12 08 2010 yuche.tsai -+ * [WCXRP00000244] [MT6620][Driver] Add station record type for each client when in AP mode. -+ * Change STA Type under AP mode. We would tell if client is a P2P device or a legacy client -+ * by checking the P2P IE in assoc req frame. -+ * -+ * 12 02 2010 yuche.tsai -+ * NULL -+ * Update P2P Connection Policy for Invitation. -+ * -+ * 12 02 2010 yuche.tsai -+ * NULL -+ * Update P2P Connection Policy for Invitation & Provision Discovery. -+ * -+ * 11 30 2010 yuche.tsai -+ * NULL -+ * Invitation & Provision Discovery Indication. -+ * -+ * 11 30 2010 yuche.tsai -+ * NULL -+ * Update Configure Method indication & selection for Provision Discovery & GO_NEGO_REQ -+ * -+ * 11 29 2010 yuche.tsai -+ * NULL -+ * Update P2P related function for INVITATION & PROVISION DISCOVERY. -+ * -+ * 11 26 2010 george.huang -+ * [WCXRP00000152] [MT6620 Wi-Fi] AP mode power saving function -+ * Update P2P PS for NOA function. -+ * -+ * 11 25 2010 yuche.tsai -+ * NULL -+ * Update Code for Invitation Related Function. -+ * -+ * 11 17 2010 wh.su -+ * [WCXRP00000164] [MT6620 Wi-Fi][Driver] Support the p2p random SSID[WCXRP00000179] [MT6620 Wi-Fi][FW] -+ * Set the Tx lowest rate at wlan table for normal operation -+ * fixed some ASSERT check. -+ * -+ * 11 04 2010 wh.su -+ * [WCXRP00000164] [MT6620 Wi-Fi][Driver] Support the p2p random SSID -+ * adding the p2p random ssid support. -+ * -+ * 10 20 2010 wh.su -+ * [WCXRP00000124] [MT6620 Wi-Fi] [Driver] Support the dissolve P2P Group -+ * Add the code to support disconnect p2p group -+ * -+ * 10 08 2010 wh.su -+ * [WCXRP00000085] [MT6620 Wif-Fi] [Driver] update the modified p2p state machine -+ * update the frog's new p2p state machine. -+ * -+ * 10 04 2010 wh.su -+ * [WCXRP00000081] [MT6620][Driver] Fix the compiling error at WinXP while enable P2P -+ * fixed compiling error while enable p2p. -+ * -+ * 09 21 2010 kevin.huang -+ * [WCXRP00000054] [MT6620 Wi-Fi][Driver] Restructure driver for second Interface -+ * Isolate P2P related function for Hardware Software Bundle -+ * -+ * 09 10 2010 wh.su -+ * NULL -+ * fixed the compiling error at WinXP. -+ * -+ * 09 07 2010 wh.su -+ * NULL -+ * adding the code for beacon/probe req/ probe rsp wsc ie at p2p. -+ * -+ * 09 03 2010 kevin.huang -+ * NULL -+ * Refine #include sequence and solve recursive/nested #include issue -+ * -+ * 08 26 2010 yuche.tsai -+ * NULL -+ * Add connection abort message event prototype. -+ * -+ * 08 20 2010 kevin.huang -+ * NULL -+ * Modify AAA Module for changing STA STATE 3 at p2p/bowRunEventAAAComplete() -+ * -+ * 08 16 2010 yuche.tsai -+ * NULL -+ * Fix P2P Intended Interface Address Bug. -+ * Extend GO Nego Timeout Time. -+ * -+ * 08 16 2010 yuche.tsai -+ * NULL -+ * Extend Listen Interval default value & remove deprecated variable. -+ * -+ * 08 16 2010 kevin.huang -+ * NULL -+ * Refine AAA functions -+ * -+ * 08 12 2010 kevin.huang -+ * NULL -+ * Refine bssProcessProbeRequest() and bssSendBeaconProbeResponse() -+ * -+ * 08 12 2010 yuche.tsai -+ * NULL -+ * Add function prototype for join complete. -+ * -+ * 08 11 2010 yuche.tsai -+ * NULL -+ * Add some function proto type for P2P FSM under provisioning phase.. -+ * -+ * 08 11 2010 yuche.tsai -+ * NULL -+ * Change P2P data structure for supporting -+ * 1. P2P Device discovery. -+ * 2. P2P Group Negotiation. -+ * 3. P2P JOIN -+ * -+ * 08 05 2010 yuche.tsai -+ * NULL -+ * Check-in P2P Device Discovery Feature. -+ * -+ * 08 03 2010 george.huang -+ * NULL -+ * handle event for updating NOA parameters indicated from FW -+ * -+ * 08 02 2010 yuche.tsai -+ * NULL -+ * P2P Group Negotiation Code Check in. -+ * -+ * 07 26 2010 yuche.tsai -+ * -+ * Update P2P FSM header file. -+ * -+ * 07 23 2010 cp.wu -+ * -+ * P2P/RSN/WAPI IEs need to be declared with compact structure. -+ * -+ * 07 21 2010 yuche.tsai -+ * -+ * Add for P2P Scan Result Parsing & Saving. -+ * -+ * 07 19 2010 yuche.tsai -+ * -+ * Update P2P FSM header file. -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 21 2010 yuche.tsai -+ * [WPD00003839][MT6620 5931][P2P] Feature migration -+ * Fix some P2P function prototype. -+ * -+ * 06 17 2010 yuche.tsai -+ * [WPD00003839][MT6620 5931][P2P] Feature migration -+ * First draft for migration P2P FSM from FW to Driver. -+ * -+ * 03 18 2010 kevin.huang -+ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support -+ * Rename CFG flag for P2P -+ * -+ * 02 26 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Modify parameter of p2pStartGO -+ * -+ * 02 23 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Add Wi-Fi Direct SSID and P2P GO Test Mode -+ * -+ * 02 04 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Add AAA Module Support, Revise Net Type to Net Type Index for array lookup -+*/ -+ -+#ifndef _P2P_FSM_H -+#define _P2P_FSM_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+#define CID52_53_54 0 -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+typedef enum _ENUM_P2P_STATE_T { -+ P2P_STATE_IDLE = 0, -+ P2P_STATE_SCAN, -+ P2P_STATE_AP_CHANNEL_DETECT, -+ P2P_STATE_REQING_CHANNEL, -+ P2P_STATE_CHNL_ON_HAND, /* Requesting Channel to Send Specific Frame. */ -+ P2P_STATE_GC_JOIN, /* Sending Specific Frame. May extending channel by other event. */ -+ P2P_STATE_NUM -+} ENUM_P2P_STATE_T, *P_ENUM_P2P_STATE_T; -+ -+enum _ENUM_P2P_DEV_EXT_LISTEN_T { -+ P2P_DEV_NOT_EXT_LISTEN, -+ P2P_DEV_EXT_LISTEN_ING, -+ P2P_DEV_EXT_LISTEN_WAITFOR_TIMEOUT, -+ P2P_DEV_EXT_LISTEN_NUM -+}; -+ -+typedef enum _ENUM_CHANNEL_REQ_TYPE_T { -+ CHANNEL_REQ_TYPE_REMAIN_ON_CHANNEL, -+ CHANNEL_REQ_TYPE_GC_JOIN_REQ, -+ CHANNEL_REQ_TYPE_GO_START_BSS -+} ENUM_CHANNEL_REQ_TYPE_T, *P_ENUM_CHANNEL_REQ_TYPE_T; -+ -+typedef enum _ENUM_BUFFER_TYPE_T { -+ ENUM_FRAME_TYPE_EXTRA_IE_BEACON, -+ ENUM_FRAME_TYPE_EXTRA_IE_ASSOC_RSP, -+ ENUM_FRAME_TYPE_EXTRA_IE_PROBE_RSP, -+ ENUM_FRAME_TYPE_PROBE_RSP_TEMPLATE, -+ ENUM_FRAME_TYPE_BEACON_TEMPLATE, -+ ENUM_FRAME_IE_NUM -+} ENUM_BUFFER_TYPE_T, *P_ENUM_BUFFER_TYPE_T; -+ -+typedef enum _ENUM_HIDDEN_SSID_TYPE_T { -+ ENUM_HIDDEN_SSID_NONE, -+ ENUM_HIDDEN_SSID_LEN, -+ ENUM_HIDDEN_SSID_ZERO_CONTENT, -+ ENUM_HIDDEN_SSID_NUM -+} ENUM_HIDDEN_SSID_TYPE_T, *P_ENUM_HIDDEN_SSID_TYPE_T; -+ -+typedef struct _P2P_SSID_STRUCT_T { -+ UINT_8 aucSsid[32]; -+ UINT_8 ucSsidLen; -+} P2P_SSID_STRUCT_T, *P_P2P_SSID_STRUCT_T; -+ -+typedef struct _P2P_STATION_INFO_T { -+ UINT_32 u4InactiveTime; -+ UINT_32 u4RxBytes; /* TODO: */ -+ UINT_32 u4TxBytes; /* TODO: */ -+ UINT_32 u4RxPackets; /* TODO: */ -+ UINT_32 u4TxPackets; /* TODO: */ -+ /* TODO: Add more for requirement. */ -+} P2P_STATION_INFO_T, *P_P2P_STATION_INFO_T; -+ -+typedef struct _AP_CRYPTO_SETTINGS_T { -+ UINT_32 u4WpaVersion; -+ UINT_32 u4CipherGroup; -+ INT_32 i4NumOfCiphers; -+ UINT_32 aucCiphersPairwise[5]; -+ INT_32 i4NumOfAkmSuites; -+ UINT_32 aucAkmSuites[2]; -+ BOOLEAN fgIsControlPort; -+ UINT_16 u2ControlPortBE; -+ BOOLEAN fgIsControlPortEncrypt; -+} AP_CRYPTO_SETTINGS_T, *P_AP_CRYPTO_SETTINGS_T; -+ -+/*-------------------- P2P FSM ACTION STRUCT ---------------------*/ -+typedef struct _P2P_CHNL_REQ_INFO_T { -+ BOOLEAN fgIsChannelRequested; -+ UINT_8 ucSeqNumOfChReq; -+ UINT_64 u8Cookie; -+ UINT_8 ucReqChnlNum; -+ ENUM_BAND_T eBand; -+ ENUM_CHNL_EXT_T eChnlSco; -+ UINT_32 u4MaxInterval; -+ ENUM_CHANNEL_REQ_TYPE_T eChannelReqType; -+ -+ UINT_8 ucOriChnlNum; -+ ENUM_BAND_T eOriBand; -+ ENUM_CHNL_EXT_T eOriChnlSco; -+ UINT_32 NFC_BEAM; /*NFC Beam + Indication */ -+} P2P_CHNL_REQ_INFO_T, *P_P2P_CHNL_REQ_INFO_T; -+ -+typedef struct _P2P_SCAN_REQ_INFO_T { -+ ENUM_SCAN_TYPE_T eScanType; -+ ENUM_SCAN_CHANNEL eChannelSet; -+ UINT_16 u2PassiveDewellTime; -+ UINT_8 ucSeqNumOfScnMsg; -+ BOOLEAN fgIsAbort; -+ BOOLEAN fgIsScanRequest; -+ UINT_8 ucNumChannelList; -+ RF_CHANNEL_INFO_T arScanChannelList[MAXIMUM_OPERATION_CHANNEL_LIST]; -+ UINT_32 u4BufLength; -+ UINT_8 aucIEBuf[MAX_IE_LENGTH]; -+ P2P_SSID_STRUCT_T rSsidStruct; /* Currently we can only take one SSID scan request */ -+ BOOLEAN fgIsGOInitialDone; -+} P2P_SCAN_REQ_INFO_T, *P_P2P_SCAN_REQ_INFO_T; -+ -+typedef struct _P2P_CONNECTION_REQ_INFO_T { -+ -+ BOOLEAN fgIsConnRequest; -+ P2P_SSID_STRUCT_T rSsidStruct; -+ UINT_8 aucBssid[MAC_ADDR_LEN]; -+ /* For ASSOC Req. */ -+ UINT_32 u4BufLength; -+ UINT_8 aucIEBuf[MAX_IE_LENGTH]; -+} P2P_CONNECTION_REQ_INFO_T, *P_P2P_CONNECTION_REQ_INFO_T; -+ -+typedef struct _P2P_MGMT_TX_REQ_INFO_T { -+ BOOLEAN fgIsMgmtTxRequested; -+ P_MSDU_INFO_T prMgmtTxMsdu; -+ UINT_64 u8Cookie; -+} P2P_MGMT_TX_REQ_INFO_T, *P_P2P_MGMT_TX_REQ_INFO_T; -+ -+struct _MSG_P2P_EXTEND_LISTEN_INTERVAL_T { -+ MSG_HDR_T rMsgHdr; -+ UINT_32 wait; /* interval supplicant expected to stay in listen interval */ -+}; -+ -+typedef struct _P2P_BEACON_UPDATE_INFO_T { -+ PUINT_8 pucBcnHdr; -+ UINT_32 u4BcnHdrLen; -+ PUINT_8 pucBcnBody; -+ UINT_32 u4BcnBodyLen; -+} P2P_BEACON_UPDATE_INFO_T, *P_P2P_BEACON_UPDATE_INFO_T; -+ -+typedef struct _P2P_PROBE_RSP_UPDATE_INFO_T { -+ P_MSDU_INFO_T prProbeRspMsduTemplate; -+} P2P_PROBE_RSP_UPDATE_INFO_T, *P_P2P_PROBE_RSP_UPDATE_INFO_T; -+ -+typedef struct _P2P_ASSOC_RSP_UPDATE_INFO_T { -+ PUINT_8 pucAssocRspExtIE; -+ UINT_16 u2AssocIELen; -+} P2P_ASSOC_RSP_UPDATE_INFO_T, *P_P2P_ASSOC_RSP_UPDATE_INFO_T; -+ -+typedef struct _P2P_JOIN_INFO_T { -+ UINT_32 ucSeqNumOfReqMsg; -+ UINT_8 ucAvailableAuthTypes; -+ P_STA_RECORD_T prTargetStaRec; -+ P2P_SSID_STRUCT_T rSsidStruct; -+ BOOLEAN fgIsJoinComplete; -+ /* For ASSOC Rsp. */ -+ UINT_32 u4BufLength; -+ UINT_8 aucIEBuf[MAX_IE_LENGTH]; -+} P2P_JOIN_INFO_T, *P_P2P_JOIN_INFO_T; -+ -+#if CFG_SUPPORT_WFD -+ -+#define WFD_FLAGS_DEV_INFO_VALID BIT(0) /* 1. WFD_DEV_INFO, 2. WFD_CTRL_PORT, 3. WFD_MAT_TP. */ -+#define WFD_FLAGS_SINK_INFO_VALID BIT(1) /* 1. WFD_SINK_STATUS, 2. WFD_SINK_MAC. */ -+#define WFD_FLAGS_ASSOC_MAC_VALID BIT(2) /* 1. WFD_ASSOC_MAC. */ -+#define WFD_FLAGS_EXT_CAPABILITY_VALID BIT(3) /* 1. WFD_EXTEND_CAPABILITY. */ -+ -+struct _WFD_CFG_SETTINGS_T { -+ UINT_32 u4WfdCmdType; -+ UINT_8 ucWfdEnable; -+ UINT_8 ucWfdCoupleSinkStatus; -+ UINT_8 ucWfdSessionAvailable; /* 0: NA 1:Set 2:Clear */ -+ UINT_8 ucWfdSigmaMode; -+ UINT_16 u2WfdDevInfo; -+ UINT_16 u2WfdControlPort; -+ UINT_16 u2WfdMaximumTp; -+ UINT_16 u2WfdExtendCap; -+ UINT_8 aucWfdCoupleSinkAddress[MAC_ADDR_LEN]; -+ UINT_8 aucWfdAssociatedBssid[MAC_ADDR_LEN]; -+ UINT_8 aucWfdVideoIp[4]; -+ UINT_8 aucWfdAudioIp[4]; -+ UINT_16 u2WfdVideoPort; -+ UINT_16 u2WfdAudioPort; -+ UINT_32 u4WfdFlag; -+ UINT_32 u4WfdPolicy; -+ UINT_32 u4WfdState; -+ UINT_8 aucWfdSessionInformationIE[24 * 8]; -+ UINT_16 u2WfdSessionInformationIELen; -+ UINT_8 aucReserved1[2]; -+ UINT_8 aucWfdPrimarySinkMac[MAC_ADDR_LEN]; -+ UINT_8 aucWfdSecondarySinkMac[MAC_ADDR_LEN]; -+ UINT_32 u4WfdAdvancedFlag; -+ /* Group 1 64 bytes */ -+ UINT_8 aucWfdLocalIp[4]; -+ UINT_16 u2WfdLifetimeAc2; /* Unit is 2 TU */ -+ UINT_16 u2WfdLifetimeAc3; /* Unit is 2 TU */ -+ UINT_16 u2WfdCounterThreshold; /* Unit is ms */ -+ UINT_8 aucReverved2[54]; -+ /* Group 2 64 bytes */ -+ UINT_8 aucReverved3[64]; -+ /* Group 3 64 bytes */ -+ UINT_8 aucReverved4[64]; -+ -+}; -+ -+struct _WFD_DBG_CFG_SETTINGS_T { -+ UINT_8 ucWfdDebugMode; -+ UINT_16 u2WfdSNShowPeiroid; -+ UINT_8 Reserved; -+ -+}; -+ -+#endif -+ -+struct _P2P_FSM_INFO_T { -+ /* State related. */ -+ ENUM_P2P_STATE_T ePreviousState; -+ ENUM_P2P_STATE_T eCurrentState; -+ -+ /* Channel related. */ -+ P2P_CHNL_REQ_INFO_T rChnlReqInfo; -+ -+ /* Scan related. */ -+ P2P_SCAN_REQ_INFO_T rScanReqInfo; -+ -+ /* Connection related. */ -+ P2P_CONNECTION_REQ_INFO_T rConnReqInfo; -+ -+ /* Mgmt tx related. */ -+ P2P_MGMT_TX_REQ_INFO_T rMgmtTxInfo; -+ -+ /* Beacon related. */ -+ P2P_BEACON_UPDATE_INFO_T rBcnContentInfo; -+ -+ /* Probe Response related. */ -+ P2P_PROBE_RSP_UPDATE_INFO_T rProbeRspContentInfo; -+ -+ /* Assoc Rsp related. */ -+ P2P_ASSOC_RSP_UPDATE_INFO_T rAssocRspContentInfo; -+ -+ /* GC Join related. */ -+ P2P_JOIN_INFO_T rJoinInfo; -+ -+ /* FSM Timer */ -+/* TIMER_T rP2pFsmTimeoutTimer; */ -+ -+ /* GC Target BSS. */ -+ P_BSS_DESC_T prTargetBss; -+ -+ /* GC Connection Request. */ -+ BOOLEAN fgIsConnectionRequested; -+ -+ BOOLEAN fgIsApMode; -+ -+ /* Channel grant interval. */ -+ UINT_32 u4GrantInterval; -+ -+ /* Packet filter for P2P module. */ -+ UINT_32 u4P2pPacketFilter; -+ -+ /* vvvvvvvvvvvvvvvvvvvvvvvvvvvvvv Prepare for use vvvvvvvvvvvvvvvvvvvvvvvvvvvvvv */ -+ /* Msg event queue. */ -+ LINK_T rMsgEventQueue; -+ -+#if CFG_SUPPORT_WFD -+ WFD_CFG_SETTINGS_T rWfdConfigureSettings; -+ WFD_DBG_CFG_SETTINGS_T rWfdDebugSetting; -+#endif -+ -+ BOOLEAN fgIsWPSMode; -+ -+ enum _ENUM_P2P_DEV_EXT_LISTEN_T eListenExted; -+}; -+ -+/*---------------- Messages -------------------*/ -+typedef struct _MSG_P2P_SCAN_REQUEST_T { -+ MSG_HDR_T rMsgHdr; /* Must be the first member */ -+ P_P2P_SSID_STRUCT_T prSSID; -+ INT_32 i4SsidNum; -+ UINT_32 u4NumChannel; -+ PUINT_8 pucIEBuf; -+ UINT_32 u4IELen; -+ BOOLEAN fgIsAbort; -+ RF_CHANNEL_INFO_T arChannelListInfo[1]; -+} MSG_P2P_SCAN_REQUEST_T, *P_MSG_P2P_SCAN_REQUEST_T; -+ -+typedef struct _MSG_P2P_CHNL_REQUEST_T { -+ MSG_HDR_T rMsgHdr; /* Must be the first member */ -+ UINT_64 u8Cookie; -+ UINT_32 u4Duration; -+ ENUM_CHNL_EXT_T eChnlSco; -+ RF_CHANNEL_INFO_T rChannelInfo; -+} MSG_P2P_CHNL_REQUEST_T, *P_MSG_P2P_CHNL_REQUEST_T; -+ -+typedef struct _MSG_P2P_CHNL_ABORT_T { -+ MSG_HDR_T rMsgHdr; /* Must be the first member */ -+ UINT_64 u8Cookie; -+} MSG_P2P_CHNL_ABORT_T, *P_MSG_P2P_CHNL_ABORT_T; -+ -+typedef struct _MSG_P2P_CONNECTION_REQUEST_T { -+ MSG_HDR_T rMsgHdr; /* Must be the first member */ -+ P2P_SSID_STRUCT_T rSsid; -+ UINT_8 aucBssid[MAC_ADDR_LEN]; -+ ENUM_CHNL_EXT_T eChnlSco; -+ RF_CHANNEL_INFO_T rChannelInfo; -+ UINT_32 u4IELen; -+ UINT_8 aucIEBuf[1]; -+ /* TODO: Auth Type, OPEN, SHARED, FT, EAP... */ -+} MSG_P2P_CONNECTION_REQUEST_T, *P_MSG_P2P_CONNECTION_REQUEST_T; -+ -+typedef struct _MSG_P2P_CONNECTION_ABORT_T { -+ MSG_HDR_T rMsgHdr; /* Must be the first member. */ -+ UINT_8 aucTargetID[MAC_ADDR_LEN]; -+ UINT_16 u2ReasonCode; -+ BOOLEAN fgSendDeauth; -+} MSG_P2P_CONNECTION_ABORT_T, *P_MSG_P2P_CONNECTION_ABORT_T; -+ -+typedef struct _MSG_P2P_MGMT_TX_REQUEST_T { -+ MSG_HDR_T rMsgHdr; -+ P_MSDU_INFO_T prMgmtMsduInfo; -+ UINT_64 u8Cookie; /* For indication. */ -+ BOOLEAN fgNoneCckRate; -+ BOOLEAN fgIsWaitRsp; -+} MSG_P2P_MGMT_TX_REQUEST_T, *P_MSG_P2P_MGMT_TX_REQUEST_T; -+ -+typedef struct _MSG_P2P_START_AP_T { -+ MSG_HDR_T rMsgHdr; -+ UINT_32 u4DtimPeriod; -+ UINT_32 u4BcnInterval; -+ UINT_8 aucSsid[32]; -+ UINT_16 u2SsidLen; -+ UINT_8 ucHiddenSsidType; -+ BOOLEAN fgIsPrivacy; -+ AP_CRYPTO_SETTINGS_T rEncryptionSettings; -+ INT_32 i4InactiveTimeout; -+} MSG_P2P_START_AP_T, *P_MSG_P2P_START_AP_T; -+ -+typedef struct _MSG_P2P_BEACON_UPDATE_T { -+ MSG_HDR_T rMsgHdr; -+ UINT_32 u4BcnHdrLen; -+ UINT_32 u4BcnBodyLen; -+ PUINT_8 pucBcnHdr; -+ PUINT_8 pucBcnBody; -+ UINT_8 aucBuffer[1]; /* Header & Body are put here. */ -+} MSG_P2P_BEACON_UPDATE_T, *P_MSG_P2P_BEACON_UPDATE_T; -+ -+typedef struct _MSG_P2P_MGMT_FRAME_UPDATE_T { -+ MSG_HDR_T rMsgHdr; -+ ENUM_BUFFER_TYPE_T eBufferType; -+ UINT_32 u4BufferLen; -+ UINT_8 aucBuffer[1]; -+} MSG_P2P_MGMT_FRAME_UPDATE_T, *P_MSG_P2P_MGMT_FRAME_UPDATE_T; -+ -+typedef struct _MSG_P2P_SWITCH_OP_MODE_T { -+ MSG_HDR_T rMsgHdr; /* Must be the first member */ -+ ENUM_OP_MODE_T eOpMode; -+} MSG_P2P_SWITCH_OP_MODE_T, *P_MSG_P2P_SWITCH_OP_MODE_T; -+ -+typedef struct _MSG_P2P_MGMT_FRAME_REGISTER_T { -+ MSG_HDR_T rMsgHdr; /* Must be the first member */ -+ UINT_16 u2FrameType; -+ BOOLEAN fgIsRegister; -+} MSG_P2P_MGMT_FRAME_REGISTER_T, *P_MSG_P2P_MGMT_FRAME_REGISTER_T; -+ -+typedef struct _MSG_P2P_NETDEV_REGISTER_T { -+ MSG_HDR_T rMsgHdr; /* Must be the first member */ -+ BOOLEAN fgIsEnable; -+ UINT_8 ucMode; -+} MSG_P2P_NETDEV_REGISTER_T, *P_MSG_P2P_NETDEV_REGISTER_T; -+ -+#if CFG_SUPPORT_WFD -+typedef struct _MSG_WFD_CONFIG_SETTINGS_CHANGED_T { -+ MSG_HDR_T rMsgHdr; /* Must be the first member */ -+ P_WFD_CFG_SETTINGS_T prWfdCfgSettings; -+} MSG_WFD_CONFIG_SETTINGS_CHANGED_T, *P_MSG_WFD_CONFIG_SETTINGS_CHANGED_T; -+#endif -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+VOID p2pFsmStateTransition(IN P_ADAPTER_T prAdapter, IN P_P2P_FSM_INFO_T prP2pFsmInfo, IN ENUM_P2P_STATE_T eNextState); -+ -+VOID p2pFsmRunEventAbort(IN P_ADAPTER_T prAdapter, IN P_P2P_FSM_INFO_T prP2pFsmInfo); -+ -+VOID p2pFsmRunEventScanRequest(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); -+ -+VOID p2pFsmRunEventMgmtFrameTx(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); -+ -+VOID p2pFsmRunEventStartAP(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); -+ -+VOID p2pFsmRunEventNetDeviceRegister(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); -+ -+VOID p2pFsmRunEventUpdateMgmtFrame(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); -+ -+VOID p2pFsmRunEventExtendListen(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); -+ -+VOID p2pFsmRunEventBeaconUpdate(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); -+ -+VOID p2pFsmRunEventStopAP(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); -+ -+VOID p2pFsmRunEventChannelRequest(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); -+ -+VOID p2pFsmRunEventChannelAbort(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); -+ -+VOID p2pFsmRunEventDissolve(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); -+ -+VOID p2pFsmRunEventSwitchOPMode(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); -+ -+WLAN_STATUS -+p2pFsmRunEventMgmtFrameTxDone(IN P_ADAPTER_T prAdapter, -+ IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus); -+ -+VOID p2pFsmRunEventMgmtFrameRegister(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); -+ -+#if CFG_SUPPORT_WFD -+VOID p2pFsmRunEventWfdSettingUpdate(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); -+#endif -+ -+#if 0 -+/* ////////////////////////////////////////////////////////////////////////////////////////////////////// */ -+/* ///////////////////////////////////////////////////////////////////////////////////// */ -+/* ///////////////////////////////////////////////////////////////////////////////////// */ -+/* ///////////////////////////////////////////////////////////////////////////////////// */ -+/* ///////////////////////////////////////////////////////////////////////////////////// */ -+/* ////////////////////////////////////////////////////////////////////////////////////////////////////// */ -+#endif -+ -+/* 3 --------------- WFA P2P DEFAULT PARAMETERS --------------- */ -+#define P2P_WILDCARD_SSID "DIRECT-" -+#define P2P_WILDCARD_SSID_LEN 7 -+#define P2P_GROUP_ID_LEN 9 -+ -+#define P2P_DRIVER_VERSION 2 /* Update when needed. */ -+ -+#define P2P_DEFAULT_DEV_NAME "Wireless Client" -+#define P2P_DEFAULT_DEV_NAME_LEN 15 -+#define P2P_DEFAULT_PRIMARY_CATEGORY_ID 10 -+#define P2P_DEFAULT_PRIMARY_SUB_CATEGORY_ID 5 -+#define P2P_DEFAULT_CONFIG_METHOD \ -+ (WPS_ATTRI_CFG_METHOD_PUSH_BUTTON | WPS_ATTRI_CFG_METHOD_KEYPAD | WPS_ATTRI_CFG_METHOD_DISPLAY) -+#define P2P_DEFAULT_LISTEN_CHANNEL 1 -+ -+#define P2P_MAX_SUPPORTED_SEC_DEV_TYPE_COUNT 0 /* NOTE(Kevin): Shall <= 16 */ -+#define P2P_MAX_SUPPORTED_CHANNEL_LIST_COUNT 13 -+ -+#define P2P_MAX_SUPPORTED_CHANNEL_LIST_SIZE 51 /* Contains 6 sub-band. */ -+ -+#define P2P_GC_MAX_CACHED_SEC_DEV_TYPE_COUNT 8 /* NOTE(Kevin): Shall <= 16 */ -+ -+#define P2P_MAXIMUM_CLIENT_COUNT 8 -+#define P2P_MAXIMUM_NOA_COUNT 8 -+ -+#define P2P_MAXIMUM_ATTRIBUTE_LEN 251 -+ -+#define P2P_CTWINDOW_DEFAULT 25 /* in TU=(1024usec) */ -+ -+#define P2P_MAXIMUM_ATTRIBUTES_CACHE_SIZE 768 -+ -+/* P2P 3.1.2.1.3 - Find Phase */ -+#define P2P_MAX_DISCOVERABLE_INTERVAL 8 /* 3 */ -+#define P2P_MIN_DISCOVERABLE_INTERVAL 5 /* 1 */ -+ -+#define P2P_LISTEN_SCAN_UNIT 100 /* MS */ -+ -+/* FSM Time Related constrain. */ -+#define P2P_SERACH_STATE_PERIOD_MS 1000 /* Deprecated. */ -+ -+#define P2P_GO_CHANNEL_STAY_INTERVAL 1000 -+ -+#define P2P_GO_NEGO_TIMEOUT_MS 500 -+#define P2P_CONNECTION_TIMEOUT_SEC 120 -+ -+#define P2P_INVITAION_TIMEOUT_MS 500 /* Timeout Wait Invitation Resonse. */ -+#define P2P_PROVISION_DISCOVERY_TIMEOUT_MS 500 /* Timeout Wait Provision Discovery Resonse. */ -+ -+/* 3 --------------- WFA P2P IE --------------- */ -+/* P2P 4.1.1 - P2P IE format */ -+#define P2P_OUI_TYPE_LEN 4 -+#define P2P_IE_OUI_HDR (ELEM_HDR_LEN + P2P_OUI_TYPE_LEN) /* == OFFSET_OF(IE_P2P_T, -+ aucP2PAttributes[0]) */ -+ -+/* P2P 4.1.1 - General P2P Attribute */ -+#define P2P_ATTRI_HDR_LEN 3 /* ID(1 octet) + Length(2 octets) */ -+#define P2P_ATTRI_LEN_NOTICE_OF_ABSENCE (P2P_ATTRI_HDR_LEN + 2) /* 5 */ -+ -+/* P2P 4.1.1 - P2P Attribute ID definitions */ -+#define P2P_ATTRI_ID_STATUS 0 -+#define P2P_ATTRI_ID_REASON_CODE 1 -+#define P2P_ATTRI_ID_P2P_CAPABILITY 2 -+#define P2P_ATTRI_ID_P2P_DEV_ID 3 -+#define P2P_ATTRI_ID_GO_INTENT 4 -+#define P2P_ATTRI_ID_CFG_TIMEOUT 5 -+#define P2P_ATTRI_ID_LISTEN_CHANNEL 6 -+#define P2P_ATTRI_ID_P2P_GROUP_BSSID 7 -+#define P2P_ATTRI_ID_EXT_LISTEN_TIMING 8 -+#define P2P_ATTRI_ID_INTENDED_P2P_IF_ADDR 9 -+#define P2P_ATTRI_ID_P2P_MANAGEABILITY 10 -+#define P2P_ATTRI_ID_CHANNEL_LIST 11 -+#define P2P_ATTRI_ID_NOTICE_OF_ABSENCE 12 -+#define P2P_ATTRI_ID_P2P_DEV_INFO 13 -+#define P2P_ATTRI_ID_P2P_GROUP_INFO 14 -+#define P2P_ATTRI_ID_P2P_GROUP_ID 15 -+#define P2P_ATTRI_ID_P2P_INTERFACE 16 -+#define P2P_ATTRI_ID_OPERATING_CHANNEL 17 -+#define P2P_ATTRI_ID_INVITATION_FLAG 18 -+#define P2P_ATTRI_ID_VENDOR_SPECIFIC 221 -+ -+/* Maximum Length of P2P Attributes */ -+#define P2P_ATTRI_MAX_LEN_STATUS 1 /* 0 */ -+#define P2P_ATTRI_MAX_LEN_REASON_CODE 1 /* 1 */ -+#define P2P_ATTRI_MAX_LEN_P2P_CAPABILITY 2 /* 2 */ -+#define P2P_ATTRI_MAX_LEN_P2P_DEV_ID 6 /* 3 */ -+#define P2P_ATTRI_MAX_LEN_GO_INTENT 1 /* 4 */ -+#define P2P_ATTRI_MAX_LEN_CFG_TIMEOUT 2 /* 5 */ -+#if CID52_53_54 -+#define P2P_ATTRI_MAX_LEN_LISTEN_CHANNEL 5 /* 6 */ -+#else -+#define P2P_ATTRI_MAX_LEN_LISTEN_CHANNEL 5 /* 6 */ -+#endif -+#define P2P_ATTRI_MAX_LEN_P2P_GROUP_BSSID 6 /* 7 */ -+#define P2P_ATTRI_MAX_LEN_EXT_LISTEN_TIMING 4 /* 8 */ -+#define P2P_ATTRI_MAX_LEN_INTENDED_P2P_IF_ADDR 6 /* 9 */ -+#define P2P_ATTRI_MAX_LEN_P2P_MANAGEABILITY 1 /* 10 */ -+/* #define P2P_ATTRI_MAX_LEN_CHANNEL_LIST 3 + (n* (2 + num_of_ch)) */ /* 11 */ -+#define P2P_ATTRI_LEN_CHANNEL_LIST 3 /* 11 */ -+#define P2P_ATTRI_LEN_CHANNEL_ENTRY 2 /* 11 */ -+ -+/* #define P2P_ATTRI_MAX_LEN_NOTICE_OF_ABSENCE 2 + (n* (13)) */ /* 12 */ -+#define P2P_ATTRI_MAX_LEN_NOTICE_OF_ABSENCE (2 + (P2P_MAXIMUM_NOA_COUNT*(13))) /* 12 */ -+ -+#define P2P_ATTRI_MAX_LEN_P2P_DEV_INFO (17 + (8 * (8)) + 36) /* 13 */ -+/* #define P2P_ATTRI_MAX_LEN_P2P_GROUP_INFO n* (25 + (m* (8)) + 32) */ /* 14 */ -+#define P2P_ATTRI_MAX_LEN_P2P_GROUP_ID 38 /* 15 */ -+#define P2P_ATTRI_MAX_LEN_P2P_INTERFACE 253 /* 7 + 6* [0~41] */ /* 16 */ -+#if CID52_53_54 -+#define P2P_ATTRI_MAX_LEN_OPERATING_CHANNEL 5 /* 17 */ -+#else -+#define P2P_ATTRI_MAX_LEN_OPERATING_CHANNEL 5 /* 17 */ -+#endif -+#define P2P_ATTRI_MAX_LEN_INVITATION_FLAGS 1 /* 18 */ -+ -+/* P2P 4.1.2 - P2P Status definitions */ -+#define P2P_STATUS_SUCCESS 0 -+#define P2P_STATUS_FAIL_INFO_IS_CURRENTLY_UNAVAILABLE 1 -+#define P2P_STATUS_FAIL_INCOMPATIBLE_PARAM 2 -+#define P2P_STATUS_FAIL_LIMIT_REACHED 3 -+#define P2P_STATUS_FAIL_INVALID_PARAM 4 -+#define P2P_STATUS_FAIL_UNABLE_ACCOMMODATE_REQ 5 -+#define P2P_STATUS_FAIL_PREVIOUS_PROTOCOL_ERR 6 -+#define P2P_STATUS_FAIL_NO_COMMON_CHANNELS 7 -+#define P2P_STATUS_FAIL_UNKNOWN_P2P_GROUP 8 -+#define P2P_STATUS_FAIL_SAME_INTENT_VALUE_15 9 -+#define P2P_STATUS_FAIL_INCOMPATIBLE_PROVISION_METHOD 10 -+#define P2P_STATUS_FAIL_REJECTED_BY_USER 11 -+ -+/* P2P 4.1.3 - P2P Minor Reason Code definitions */ -+#define P2P_REASON_SUCCESS 0 -+#define P2P_REASON_DISASSOCIATED_DUE_CROSS_CONNECTION 1 -+#define P2P_REASON_DISASSOCIATED_DUE_UNMANAGEABLE 2 -+#define P2P_REASON_DISASSOCIATED_DUE_NO_P2P_COEXIST_PARAM 3 -+#define P2P_REASON_DISASSOCIATED_DUE_MANAGEABLE 4 -+ -+/* P2P 4.1.4 - Device Capability Bitmap definitions */ -+#define P2P_DEV_CAPABILITY_SERVICE_DISCOVERY BIT(0) -+#define P2P_DEV_CAPABILITY_CLIENT_DISCOVERABILITY BIT(1) -+#define P2P_DEV_CAPABILITY_CONCURRENT_OPERATION BIT(2) -+#define P2P_DEV_CAPABILITY_P2P_INFRA_MANAGED BIT(3) -+#define P2P_DEV_CAPABILITY_P2P_DEVICE_LIMIT BIT(4) -+#define P2P_DEV_CAPABILITY_P2P_INVITATION_PROCEDURE BIT(5) -+ -+/* P2P 4.1.4 - Group Capability Bitmap definitions */ -+#define P2P_GROUP_CAPABILITY_P2P_GROUP_OWNER BIT(0) -+#define P2P_GROUP_CAPABILITY_PERSISTENT_P2P_GROUP BIT(1) -+#define P2P_GROUP_CAPABILITY_P2P_GROUP_LIMIT BIT(2) -+#define P2P_GROUP_CAPABILITY_INTRA_BSS_DISTRIBUTION BIT(3) -+#define P2P_GROUP_CAPABILITY_CROSS_CONNECTION BIT(4) -+#define P2P_GROUP_CAPABILITY_PERSISTENT_RECONNECT BIT(5) -+#define P2P_GROUP_CAPABILITY_GROUP_FORMATION BIT(6) -+ -+/* P2P 4.1.6 - GO Intent field definitions */ -+#define P2P_GO_INTENT_TIE_BREAKER_FIELD BIT(0) -+#define P2P_GO_INTENT_VALUE_MASK BITS(1, 7) -+#define P2P_GO_INTENT_VALUE_OFFSET 1 -+ -+/* P2P 4.1.12 - Manageability Bitmap definitions */ -+#define P2P_DEVICE_MANAGEMENT BIT(0) -+ -+/* P2P 4.1.14 - CTWindow and OppPS Parameters definitions */ -+#define P2P_CTW_OPPPS_PARAM_OPPPS_FIELD BIT(7) -+#define P2P_CTW_OPPPS_PARAM_CTWINDOW_MASK BITS(0, 6) -+ -+#define ELEM_MAX_LEN_P2P_FOR_PROBE_REQ \ -+ (P2P_OUI_TYPE_LEN + \ -+ (P2P_ATTRI_HDR_LEN + P2P_ATTRI_MAX_LEN_P2P_CAPABILITY) + \ -+ (P2P_ATTRI_HDR_LEN + P2P_ATTRI_MAX_LEN_P2P_DEV_ID) + \ -+ (P2P_ATTRI_HDR_LEN + P2P_ATTRI_MAX_LEN_LISTEN_CHANNEL) + \ -+ (P2P_ATTRI_HDR_LEN + P2P_ATTRI_MAX_LEN_OPERATING_CHANNEL)) -+ -+#define ELEM_MAX_LEN_P2P_FOR_ASSOC_REQ \ -+ (P2P_OUI_TYPE_LEN + \ -+ (P2P_ATTRI_HDR_LEN + P2P_ATTRI_MAX_LEN_P2P_CAPABILITY) + \ -+ (P2P_ATTRI_HDR_LEN + P2P_ATTRI_MAX_LEN_EXT_LISTEN_TIMING) + \ -+ (P2P_ATTRI_HDR_LEN + P2P_ATTRI_MAX_LEN_P2P_DEV_INFO)) -+ -+/* P2P 4.1.16 - P2P Client Infor Descriptor */ -+#define P2P_CLIENT_INFO_DESC_HDR_LEN 1 /* Length(1 octets) */ -+ -+/* P2P 4.1.20 - P2P Invitation Flags Attribute*/ -+#define P2P_INVITATION_FLAGS_INVITATION_TYPE BIT(0) -+#define P2P_INVITATION_TYPE_INVITATION 0 -+#define P2P_INVITATION_TYPE_REINVOKE 1 -+/* 3 --------------- WPS Data Element Definitions --------------- */ -+/* P2P 4.2.2 - General WSC Attribute */ -+#define WSC_ATTRI_HDR_LEN 4 /* ID(2 octet) + Length(2 octets) */ -+#define WSC_ATTRI_MAX_LEN_VERSION 1 -+#define WSC_ATTRI_MAX_LEN_DEVICE_PASSWORD_ID 2 -+#define WSC_ATTRI_LEN_CONFIG_METHOD 2 -+ -+/* WPS 11 - Data Element Definitions */ -+#define WPS_ATTRI_ID_VERSION 0x104A -+#define WPS_ATTRI_ID_CONFIGURATION_METHODS 0x1008 -+#define WPS_ATTRI_ID_DEVICE_PASSWORD 0x1012 -+#define WPS_ATTRI_ID_DEVICE_NAME 0x1011 -+#define WPS_ATTRI_ID_PRI_DEVICE_TYPE 0x1054 -+#define WPS_ATTRI_ID_SEC_DEVICE_TYPE 0x1055 -+ -+#define WPS_MAXIMUM_ATTRIBUTES_CACHE_SIZE 300 -+ -+#define WPS_ATTRI_MAX_LEN_DEVICE_NAME 32 /* 0x1011 */ -+ -+#define WPS_ATTRI_CFG_METHOD_USBA BIT(0) -+#define WPS_ATTRI_CFG_METHOD_ETHERNET BIT(1) -+#define WPS_ATTRI_CFG_METHOD_LABEL BIT(2) -+#define WPS_ATTRI_CFG_METHOD_DISPLAY BIT(3) -+#define WPS_ATTRI_CFG_METHOD_EXT_NFC BIT(4) -+#define WPS_ATTRI_CFG_METHOD_INT_NFC BIT(5) -+#define WPS_ATTRI_CFG_METHOD_NFC_IF BIT(6) -+#define WPS_ATTRI_CFG_METHOD_PUSH_BUTTON BIT(7) -+#define WPS_ATTRI_CFG_METHOD_KEYPAD BIT(8) -+ -+#define P2P_FLAGS_PROVISION_COMPLETE 0x00000001 -+#define P2P_FLAGS_PROVISION_DISCOVERY_COMPLETE 0x00000002 -+#define P2P_FLAGS_PROVISION_DISCOVERY_WAIT_RESPONSE 0x00000004 -+#define P2P_FLAGS_PROVISION_DISCOVERY_RESPONSE_WAIT 0x00000008 -+#define P2P_FLAGS_MASK_PROVISION 0x00000017 -+#define P2P_FLAGS_MASK_PROVISION_COMPLETE 0x00000015 -+#define P2P_FLAGS_PROVISION_DISCOVERY_INDICATED 0x00000010 -+#define P2P_FLAGS_INVITATION_TOBE_GO 0x00000100 -+#define P2P_FLAGS_INVITATION_TOBE_GC 0x00000200 -+#define P2P_FLAGS_INVITATION_SUCCESS 0x00000400 -+#define P2P_FLAGS_INVITATION_WAITING_TARGET 0x00000800 -+#define P2P_FLAGS_MASK_INVITATION 0x00000F00 -+#define P2P_FLAGS_FORMATION_ON_GOING 0x00010000 -+#define P2P_FLAGS_FORMATION_LOCAL_PWID_RDY 0x00020000 -+#define P2P_FLAGS_FORMATION_TARGET_PWID_RDY 0x00040000 -+#define P2P_FLAGS_FORMATION_COMPLETE 0x00080000 -+#define P2P_FLAGS_MASK_FORMATION 0x000F0000 -+#define P2P_FLAGS_DEVICE_DISCOVER_REQ 0x00100000 -+#define P2P_FLAGS_DEVICE_DISCOVER_DONE 0x00200000 -+#define P2P_FLAGS_DEVICE_INVITATION_WAIT 0x00400000 -+#define P2P_FLAGS_DEVICE_SERVICE_DISCOVER_WAIT 0x00800000 -+#define P2P_FLAGS_MASK_DEVICE_DISCOVER 0x00F00000 -+ -+#define P2P_FLAGS_DEVICE_FORMATION_REQUEST 0x01000000 -+ -+/* MACRO for flag operation */ -+#define SET_FLAGS(_FlagsVar, _BitsToSet) \ -+ {(_FlagsVar) = ((_FlagsVar) | (_BitsToSet))} -+ -+#define TEST_FLAGS(_FlagsVar, _BitsToCheck) \ -+ (((_FlagsVar) & (_BitsToCheck)) == (_BitsToCheck)) -+ -+#define CLEAR_FLAGS(_FlagsVar, _BitsToClear) \ -+ {(_FlagsVar) &= ~(_BitsToClear)} -+ -+#define CFG_DISABLE_WIFI_DIRECT_ENHANCEMENT_I 0 -+ -+#define CFG_DISABLE_WIFI_DIRECT_ENHANCEMENT_II 0 -+ -+#define CFG_DISABLE_WIFI_DIRECT_ENHANCEMENT_III 0 -+ -+#define CFG_DISABLE_WIFI_DIRECT_ENHANCEMENT_IV 0 -+ -+#define CFG_DISABLE_DELAY_PROVISION_DISCOVERY 0 -+ -+#define CFG_CONNECTION_POLICY_2_0 0 -+ -+/* Device Password ID */ -+enum wps_dev_password_id { -+ DEV_PW_DEFAULT = 0x0000, -+ DEV_PW_USER_SPECIFIED = 0x0001, -+ DEV_PW_MACHINE_SPECIFIED = 0x0002, -+ DEV_PW_REKEY = 0x0003, -+ DEV_PW_PUSHBUTTON = 0x0004, -+ DEV_PW_REGISTRAR_SPECIFIED = 0x0005 -+}; -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+#if defined(WINDOWS_DDK) || defined(WINDOWS_CE) -+#pragma pack(1) -+#endif -+ -+/* 3 --------------- WFA P2P IE and Attributes --------------- */ -+ -+/* P2P 4.1.1 - P2P Information Element */ -+typedef struct _IE_P2P_T { -+ UINT_8 ucId; /* Element ID */ -+ UINT_8 ucLength; /* Length */ -+ UINT_8 aucOui[3]; /* OUI */ -+ UINT_8 ucOuiType; /* OUI Type */ -+ UINT_8 aucP2PAttributes[1]; /* P2P Attributes */ -+} __KAL_ATTRIB_PACKED__ IE_P2P_T, *P_IE_P2P_T; -+ -+/* P2P 4.1.1 - General P2P Attribute */ -+typedef struct _P2P_ATTRIBUTE_T { -+ UINT_8 ucId; /* Attribute ID */ -+ UINT_16 u2Length; /* Length */ -+ UINT_8 aucBody[1]; /* Body field */ -+} __KAL_ATTRIB_PACKED__ P2P_ATTRIBUTE_T, ATTRIBUTE_HDR_T, *P_P2P_ATTRIBUTE_T, *P_ATTRIBUTE_HDR_T; -+ -+/* P2P 4.1.2 - P2P Status Attribute */ -+typedef struct _P2P_ATTRI_STATUS_T { -+ UINT_8 ucId; /* Attribute ID */ -+ UINT_16 u2Length; /* Length */ -+ UINT_8 ucStatusCode; /* Status Code */ -+} __KAL_ATTRIB_PACKED__ P2P_ATTRI_STATUS_T, *P_P2P_ATTRI_STATUS_T; -+ -+/* P2P 4.1.3 - P2P Minor Reason Code Attribute */ -+typedef struct _P2P_ATTRI_REASON_T { -+ UINT_8 ucId; /* Attribute ID */ -+ UINT_16 u2Length; /* Length */ -+ UINT_8 ucMinorReasonCode; /* Minor Reason Code */ -+} __KAL_ATTRIB_PACKED__ P2P_ATTRI_REASON_T, *P_P2P_ATTRI_REASON_T; -+ -+/* P2P 4.1.4 - P2P Capability Attribute */ -+typedef struct _P2P_ATTRI_CAPABILITY_T { -+ UINT_8 ucId; /* Attribute ID */ -+ UINT_16 u2Length; /* Length */ -+ UINT_8 ucDeviceCap; /* Device Capability Bitmap */ -+ UINT_8 ucGroupCap; /* Group Capability Bitmap */ -+} __KAL_ATTRIB_PACKED__ P2P_ATTRI_CAPABILITY_T, *P_P2P_ATTRI_CAPABILITY_T; -+ -+/* P2P 4.1.5 - P2P Device ID Attribute */ -+typedef struct _P2P_ATTRI_DEV_ID_T { -+ UINT_8 ucId; /* Attribute ID */ -+ UINT_16 u2Length; /* Length */ -+ UINT_8 aucDevAddr[MAC_ADDR_LEN]; /* P2P Device Address */ -+} __KAL_ATTRIB_PACKED__ P2P_ATTRI_DEV_ID_T, *P_P2P_ATTRI_DEV_ID_T; -+ -+/* P2P 4.1.6 - Group Owner Intent Attribute */ -+typedef struct _P2P_ATTRI_GO_INTENT_T { -+ UINT_8 ucId; /* Attribute ID */ -+ UINT_16 u2Length; /* Length */ -+ UINT_8 ucGOIntent; /* Group Owner Intent */ -+} __KAL_ATTRIB_PACKED__ P2P_ATTRI_GO_INTENT_T, *P_P2P_ATTRI_GO_INTENT_T; -+ -+/* P2P 4.1.7 - Configuration Timeout Attribute */ -+typedef struct _P2P_ATTRI_CFG_TIMEOUT_T { -+ UINT_8 ucId; /* Attribute ID */ -+ UINT_16 u2Length; /* Length */ -+ UINT_8 ucGOCfgTimeout; /* GO Configuration Timeout */ -+ UINT_8 ucClientCfgTimeout; /* Client Configuration Timeout */ -+} __KAL_ATTRIB_PACKED__ P2P_ATTRI_CFG_TIMEOUT_T, *P_P2P_ATTRI_CFG_TIMEOUT_T; -+ -+/* P2P 4.1.8 - Listen Channel Attribute */ -+typedef struct _P2P_ATTRI_LISTEN_CHANNEL_T { -+ UINT_8 ucId; /* Attribute ID */ -+ UINT_16 u2Length; /* Length */ -+ UINT_8 aucCountryString[3]; /* Country String */ -+ UINT_8 ucOperatingClass; /* Operating Class from 802.11 Annex J/P802.11 REVmb 3.0 */ -+ UINT_8 ucChannelNumber; /* Channel Number */ -+} __KAL_ATTRIB_PACKED__ P2P_ATTRI_LISTEN_CHANNEL_T, *P_P2P_ATTRI_LISTEN_CHANNEL_T; -+ -+/* P2P 4.1.9 - P2P Group BSSID Attribute */ -+typedef struct _P2P_ATTRI_GROUP_BSSID_T { -+ UINT_8 ucId; /* Attribute ID */ -+ UINT_16 u2Length; /* Length */ -+ UINT_8 aucBssid[MAC_ADDR_LEN]; /* P2P Group BSSID */ -+} __KAL_ATTRIB_PACKED__ P2P_ATTRI_GROUP_BSSID_T, *P_P2P_ATTRI_GROUP_BSSID_T; -+ -+/* P2P 4.1.10 - Extended Listen Timing Attribute */ -+typedef struct _P2P_ATTRI_EXT_LISTEN_TIMING_T { -+ UINT_8 ucId; /* Attribute ID */ -+ UINT_16 u2Length; /* Length */ -+ UINT_16 u2AvailPeriod; /* Availability Period */ -+ UINT_16 u2AvailInterval; /* Availability Interval */ -+} __KAL_ATTRIB_PACKED__ P2P_ATTRI_EXT_LISTEN_TIMING_T, *P_P2P_ATTRI_EXT_LISTEN_TIMING_T; -+ -+/* P2P 4.1.11 - Intended P2P Interface Address Attribute */ -+typedef struct _P2P_ATTRI_INTENDED_IF_ADDR_T { -+ UINT_8 ucId; /* Attribute ID */ -+ UINT_16 u2Length; /* Length */ -+ UINT_8 aucIfAddr[MAC_ADDR_LEN]; /* P2P Interface Address */ -+} __KAL_ATTRIB_PACKED__ P2P_ATTRI_INTENDED_IF_ADDR_T, *P_P2P_ATTRI_INTENDED_IF_ADDR_T; -+ -+/* P2P 4.1.12 - P2P Manageability Attribute */ -+typedef struct _P2P_ATTRI_MANAGEABILITY_T { -+ UINT_8 ucId; /* Attribute ID */ -+ UINT_16 u2Length; /* Length */ -+ UINT_8 ucManageability; /* P2P Manageability Bitmap */ -+} __KAL_ATTRIB_PACKED__ P2P_ATTRI_MANAGEABILITY_T, *P_P2P_ATTRI_MANAGEABILITY_T; -+ -+/* P2P 4.1.13 - Channel List Attribute */ -+typedef struct _P2P_ATTRI_CHANNEL_LIST_T { -+ UINT_8 ucId; /* Attribute ID */ -+ UINT_16 u2Length; /* Length */ -+ UINT_8 aucCountryString[3]; /* Country String */ -+ UINT_8 aucChannelEntry[1]; /* Channel Entry List */ -+} __KAL_ATTRIB_PACKED__ P2P_ATTRI_CHANNEL_T, *P_P2P_ATTRI_CHANNEL_T; -+ -+typedef struct _CHANNEL_ENTRY_FIELD_T { -+ UINT_8 ucRegulatoryClass; /* Regulatory Class */ -+ UINT_8 ucNumberOfChannels; /* Number Of Channels */ -+ UINT_8 aucChannelList[1]; /* Channel List */ -+} __KAL_ATTRIB_PACKED__ CHANNEL_ENTRY_FIELD_T, *P_CHANNEL_ENTRY_FIELD_T; -+ -+/* P2P 4.1.14 - Notice of Absence Attribute */ -+typedef struct _P2P_ATTRI_NOA_T { -+ UINT_8 ucId; /* Attribute ID */ -+ UINT_16 u2Length; /* Length */ -+ UINT_8 ucIndex; /* Index */ -+ UINT_8 ucCTWOppPSParam; /* CTWindow and OppPS Parameters */ -+ UINT_8 aucNoADesc[1]; /* NoA Descriptor */ -+} __KAL_ATTRIB_PACKED__ P2P_ATTRI_NOA_T, *P_P2P_ATTRI_NOA_T; -+ -+typedef struct _NOA_DESCRIPTOR_T { -+ UINT_8 ucCountType; /* Count/Type */ -+ UINT_32 u4Duration; /* Duration */ -+ UINT_32 u4Interval; /* Interval */ -+ UINT_32 u4StartTime; /* Start Time */ -+} __KAL_ATTRIB_PACKED__ NOA_DESCRIPTOR_T, *P_NOA_DESCRIPTOR_T; -+ -+typedef struct _P2P_ATTRI_DEV_INFO_T { -+ UINT_8 ucId; /* Attribute ID */ -+ UINT_16 u2Length; /* Length */ -+ UINT_8 aucDevAddr[MAC_ADDR_LEN]; /* P2P Device Address */ -+ UINT_16 u2ConfigMethodsBE; /* Config Method */ -+ DEVICE_TYPE_T rPrimaryDevTypeBE; /* Primary Device Type */ -+ UINT_8 ucNumOfSecondaryDevType; /* Number of Secondary Device Types */ -+ DEVICE_TYPE_T arSecondaryDevTypeListBE[1]; /* Secondary Device Type List */ -+} __KAL_ATTRIB_PACKED__ P2P_ATTRI_DEV_INFO_T, *P_P2P_ATTRI_DEV_INFO_T; -+ -+/* WPS 7.1 & 11 WPS TLV Data Format - Device Name */ -+typedef struct _DEVICE_NAME_TLV_T { -+ UINT_16 u2Id; /* WPS Attribute Type */ -+ UINT_16 u2Length; /* Data Length */ -+ UINT_8 aucName[32]; /* Device Name */ /* TODO: Fixme */ -+} __KAL_ATTRIB_PACKED__ DEVICE_NAME_TLV_T, *P_DEVICE_NAME_TLV_T; -+ -+/* P2P 4.1.16 - P2P Group Info Attribute */ -+typedef struct _P2P_CLIENT_INFO_DESC_T { -+ UINT_8 ucLength; /* Length */ -+ UINT_8 aucDevAddr[MAC_ADDR_LEN]; /* P2P Device Address */ -+ UINT_8 aucIfAddr[MAC_ADDR_LEN]; /* P2P Interface Address */ -+ UINT_8 ucDeviceCap; /* Device Capability Bitmap */ -+ UINT_16 u2ConfigMethodsBE; /* Config Method */ -+ DEVICE_TYPE_T rPrimaryDevTypeBE; /* Primary Device Type */ -+ UINT_8 ucNumOfSecondaryDevType; /* Number of Secondary Device Types */ -+ DEVICE_TYPE_T arSecondaryDevTypeListBE[1]; /* Secondary Device Type List */ -+} __KAL_ATTRIB_PACKED__ P2P_CLIENT_INFO_DESC_T, *P_P2P_CLIENT_INFO_DESC_T; -+ -+typedef struct _P2P_ATTRI_GROUP_INFO_T { -+ UINT_8 ucId; /* Attribute ID */ -+ UINT_16 u2Length; /* Length */ -+ P2P_CLIENT_INFO_DESC_T arClientDesc[1]; /* P2P Client Info Descriptors */ -+} __KAL_ATTRIB_PACKED__ P2P_ATTRI_GROUP_INFO_T, *P_P2P_ATTRI_GROUP_INFO_T; -+ -+/* P2P 4.1.17 - P2P Group ID Attribute */ -+typedef struct _P2P_ATTRI_GROUP_ID_T { -+ UINT_8 ucId; /* Attribute ID */ -+ UINT_16 u2Length; /* Length */ -+ UINT_8 aucDevAddr[MAC_ADDR_LEN]; /* P2P Device Address */ -+ UINT_8 aucSSID[ELEM_MAX_LEN_SSID]; /* SSID */ -+} __KAL_ATTRIB_PACKED__ P2P_ATTRI_GROUP_ID_T, *P_P2P_ATTRI_GROUP_ID_T; -+ -+/* P2P 4.1.18 - P2P Interface Attribute */ -+typedef struct _P2P_ATTRI_INTERFACE_T { -+ UINT_8 ucId; /* Attribute ID */ -+ UINT_16 u2Length; /* Length */ -+ UINT_8 aucDevAddr[MAC_ADDR_LEN]; /* P2P Device Address */ -+ UINT_8 ucIfAddrCount; /* P2P Interface Address Count */ -+ UINT_8 aucIfAddrList[MAC_ADDR_LEN]; /* P2P Interface Address List */ -+} __KAL_ATTRIB_PACKED__ P2P_ATTRI_INTERFACE_T, *P_P2P_ATTRI_INTERFACE_T; -+ -+/* P2P 4.1.19 - Operating Channel Attribute */ -+typedef struct _P2P_ATTRI_OPERATING_CHANNEL_T { -+ UINT_8 ucId; /* Attribute ID */ -+ UINT_16 u2Length; /* Length */ -+ UINT_8 aucCountryString[3]; /* Country String */ -+ UINT_8 ucOperatingClass; /* Operating Class from 802.11 Annex J/P802.11 REVmb 3.0 */ -+ UINT_8 ucChannelNumber; /* Channel Number */ -+} __KAL_ATTRIB_PACKED__ P2P_ATTRI_OPERATING_CHANNEL_T, *P_P2P_ATTRI_OPERATING_CHANNEL_T; -+ -+/* P2P 4.1.20 - Invitation Flags Attribute */ -+typedef struct _P2P_ATTRI_INVITATION_FLAG_T { -+ UINT_8 ucId; /* Attribute ID */ -+ UINT_16 u2Length; /* Length */ -+ UINT_8 ucInviteFlagsBitmap; /* Invitation Flags Bitmap */ -+} __KAL_ATTRIB_PACKED__ P2P_ATTRI_INVITATION_FLAG_T, *P_P2P_ATTRI_INVITATION_FLAG_T; -+ -+/* P2P 4.1.1 - General WSC Attribute */ -+typedef struct _WSC_ATTRIBUTE_T { -+ UINT_16 u2Id; /* Attribute ID */ -+ UINT_16 u2Length; /* Length */ -+ UINT_8 aucBody[1]; /* Body field */ -+} __KAL_ATTRIB_PACKED__ WSC_ATTRIBUTE_T, *P_WSC_ATTRIBUTE_T; -+ -+/* WSC 1.0 Table 28 */ -+typedef struct _WSC_ATTRI_VERSION_T { -+ UINT_16 u2Id; /* Attribute ID */ -+ UINT_16 u2Length; /* Length */ -+ UINT_8 ucVersion; /* Version 1.0 or 1.1 */ -+} __KAL_ATTRIB_PACKED__ WSC_ATTRI_VERSION_T, *P_WSC_ATTRI_VERSION_T; -+ -+typedef struct _WSC_ATTRI_DEVICE_PASSWORD_ID_T { -+ UINT_16 u2Id; /* Attribute ID */ -+ UINT_16 u2Length; /* Length */ -+ UINT_16 u2DevPasswordId; /* Device Password ID */ -+} __KAL_ATTRIB_PACKED__ WSC_ATTRI_DEVICE_PASSWORD_ID_T, *P_WSC_ATTRI_DEVICE_PASSWORD_ID_T; -+ -+typedef struct _WSC_ATTRI_CONFIGURATION_METHOD_T { -+ UINT_16 u2Id; /* Attribute ID */ -+ UINT_16 u2Length; /* Length */ -+ UINT_16 u2ConfigMethods; /* Configure Methods */ -+} __KAL_ATTRIB_PACKED__ WSC_ATTRI_CONFIGURATION_METHOD_T, *P_WSC_ATTRI_CONFIGURATION_METHOD_T; -+ -+#if defined(WINDOWS_DDK) || defined(WINDOWS_CE) -+#pragma pack() -+#endif -+ -+/* 3 --------------- WFA P2P Attributes Handler prototype --------------- */ -+typedef UINT_32(*PFN_APPEND_ATTRI_FUNC) (P_ADAPTER_T, BOOLEAN, PUINT_16, PUINT_8, UINT_16); -+ -+typedef VOID(*PFN_HANDLE_ATTRI_FUNC) (P_SW_RFB_T, P_P2P_ATTRIBUTE_T); -+ -+typedef VOID(*PFN_VERIFY_ATTRI_FUNC) (P_SW_RFB_T, P_P2P_ATTRIBUTE_T, PUINT_16); -+ -+typedef UINT_32(*PFN_CALCULATE_VAR_ATTRI_LEN_FUNC) (P_ADAPTER_T, P_STA_RECORD_T); -+ -+typedef struct _APPEND_VAR_ATTRI_ENTRY_T { -+ UINT_16 u2EstimatedFixedAttriLen; /* For fixed length */ -+ PFN_CALCULATE_VAR_ATTRI_LEN_FUNC pfnCalculateVariableAttriLen; -+ PFN_APPEND_ATTRI_FUNC pfnAppendAttri; -+} APPEND_VAR_ATTRI_ENTRY_T, *P_APPEND_VAR_ATTRI_ENTRY_T; -+ -+typedef enum _ENUM_CONFIG_METHOD_SEL { -+ ENUM_CONFIG_METHOD_SEL_AUTO, -+ ENUM_CONFIG_METHOD_SEL_USER, -+ ENUM_CONFIG_METHOD_SEL_NUM -+} ENUM_CONFIG_METHOD_SEL, *P_ENUM_CONFIG_METHOD_SEL; -+ -+typedef enum _ENUM_P2P_FORMATION_POLICY { -+ ENUM_P2P_FORMATION_POLICY_AUTO = 0, -+ ENUM_P2P_FORMATION_POLICY_PASSIVE, /* Device would wait GO NEGO REQ instead of sending it actively. */ -+ ENUM_P2P_FORMATION_POLICY_NUM -+} ENUM_P2P_FORMATION_POLICY, P_ENUM_P2P_FORMATION_POLICY; -+ -+typedef enum _ENUM_P2P_INVITATION_POLICY { -+ ENUM_P2P_INVITATION_POLICY_USER = 0, -+ ENUM_P2P_INVITATION_POLICY_ACCEPT_FIRST, -+ ENUM_P2P_INVITATION_POLICY_DENY_ALL, -+ ENUM_P2P_INVITATION_POLICY_NUM -+} ENUM_P2P_INVITATION_POLICY, P_ENUM_P2P_INVITATION_POLICY; -+ -+/* 3 --------------- Data Structure for P2P Operation --------------- */ -+/* 3 Session for CONNECTION SETTINGS of P2P */ -+struct _P2P_CONNECTION_SETTINGS_T { -+ UINT_8 ucDevNameLen; -+ UINT_8 aucDevName[WPS_ATTRI_MAX_LEN_DEVICE_NAME]; -+ -+ DEVICE_TYPE_T rPrimaryDevTypeBE; -+ -+ ENUM_P2P_FORMATION_POLICY eFormationPolicy; /* Formation Policy. */ -+ -+ /*------------WSC Related Param---------------*/ -+ UINT_16 u2ConfigMethodsSupport; /* Preferred configure method. -+ * Some device may not have keypad. -+ */ -+ ENUM_CONFIG_METHOD_SEL eConfigMethodSelType; -+ UINT_16 u2TargetConfigMethod; /* Configure method selected by user or auto. */ -+ UINT_16 u2LocalConfigMethod; /* Configure method of target. */ -+ BOOLEAN fgIsPasswordIDRdy; -+ /*------------WSC Related Param---------------*/ -+ -+ UINT_8 ucClientConfigTimeout; -+ UINT_8 ucGoConfigTimeout; -+ -+ UINT_8 ucSecondaryDevTypeCount; -+#if P2P_MAX_SUPPORTED_SEC_DEV_TYPE_COUNT -+ DEVICE_TYPE_T arSecondaryDevTypeBE[P2P_MAX_SUPPORTED_SEC_DEV_TYPE_COUNT]; -+#endif -+ -+#if 0 -+ UINT_8 ucRfChannelListCount; -+#if P2P_MAX_SUPPORTED_CHANNEL_LIST_COUNT -+ UINT_8 aucChannelList[P2P_MAX_SUPPORTED_CHANNEL_LIST_COUNT]; /* Channel Numbering -+ depends on 802.11mb Annex J. */ -+ -+#endif -+#else -+ UINT_8 ucRfChannelListSize; -+#if P2P_MAX_SUPPORTED_CHANNEL_LIST_SIZE -+ UINT_8 aucChannelEntriesField[P2P_MAX_SUPPORTED_CHANNEL_LIST_SIZE]; -+#endif -+#endif -+ -+ /* Go Intent */ -+ UINT_8 ucTieBreaker; -+ UINT_8 ucGoIntent; -+ -+ /* For Device Capability */ -+ BOOLEAN fgSupportServiceDiscovery; -+ BOOLEAN fgSupportClientDiscoverability; -+ BOOLEAN fgSupportConcurrentOperation; -+ BOOLEAN fgSupportInfraManaged; -+ BOOLEAN fgSupportInvitationProcedure; -+ -+ /* For Group Capability */ -+ BOOLEAN fgSupportPersistentP2PGroup; -+ BOOLEAN fgSupportIntraBSSDistribution; -+ BOOLEAN fgSupportCrossConnection; -+ BOOLEAN fgSupportPersistentReconnect; -+ -+ BOOLEAN fgP2pGroupLimit; -+ -+ BOOLEAN fgSupportOppPS; -+ UINT_16 u2CTWindow; -+ -+ BOOLEAN fgIsScanReqIssued; -+ BOOLEAN fgIsServiceDiscoverIssued; -+ -+ /*============ Target Device Connection Settings ============*/ -+ -+ /* Discover Target Device Info. */ -+ BOOLEAN fgIsDevId; -+ BOOLEAN fgIsDevType; -+ -+ /* Encryption mode of Target Device */ -+ ENUM_PARAM_AUTH_MODE_T eAuthMode; -+ -+ /* SSID -+ * 1. AP Mode, this is the desired SSID user specified. -+ * 2. Client Mode, this is the target SSID to be connected to. -+ */ -+ UINT_8 aucSSID[ELEM_MAX_LEN_SSID]; -+ UINT_8 ucSSIDLen; -+ -+ /* Operating channel requested. */ -+ UINT_8 ucOperatingChnl; -+ ENUM_BAND_T eBand; -+ -+ /* Linten channel requested. */ -+ UINT_8 ucListenChnl; -+ -+ /* For device discover address/type. */ -+ UINT_8 aucTargetDevAddr[MAC_ADDR_LEN]; /* P2P Device Address, for P2P Device Discovery & P2P Connection. */ -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ P_P2P_DEVICE_DESC_T prTargetP2pDesc; -+#endif -+ -+ UINT_8 ucLastStatus; /* P2P FSM would append status attribute according to this field. */ -+ -+#if !CFG_DISABLE_DELAY_PROVISION_DISCOVERY -+ UINT_8 ucLastDialogToken; -+ UINT_8 aucIndicateDevAddr[MAC_ADDR_LEN]; -+#endif -+ -+#if 0 -+ UINT_8 ucTargetRfChannelListCount; -+#if P2P_MAX_SUPPORTED_CHANNEL_LIST_COUNT -+ UINT_8 aucTargetChannelList[P2P_MAX_SUPPORTED_CHANNEL_LIST_COUNT]; /* Channel Numbering -+ depends on 802.11mb Annex J. */ -+#endif -+#endif -+ -+}; -+ -+typedef struct _NOA_TIMING_T { -+ BOOLEAN fgIsInUse; /* Indicate if this entry is in use or not */ -+ UINT_8 ucCount; /* Count */ -+ -+ UINT_8 aucReserved[2]; -+ -+ UINT_32 u4Duration; /* Duration */ -+ UINT_32 u4Interval; /* Interval */ -+ UINT_32 u4StartTime; /* Start Time */ -+} NOA_TIMING_T, *P_NOA_TIMING_T; -+ -+typedef enum _ENUM_P2P_IOCTL_T { -+ P2P_IOCTL_IDLE = 0, -+ P2P_IOCTL_DEV_DISCOVER, -+ P2P_IOCTL_INVITATION_REQ, -+ P2P_IOCTL_SERV_DISCOVER, -+ P2P_IOCTL_WAITING, -+ P2P_IOCTL_NUM -+} ENUM_P2P_IOCTL_T; -+ -+/*---------------- Service Discovery Related -------------------*/ -+typedef enum _ENUM_SERVICE_TX_TYPE_T { -+ ENUM_SERVICE_TX_TYPE_BY_DA, -+ ENUM_SERVICE_TX_TYPE_BY_CHNL, -+ ENUM_SERVICE_TX_TYPE_NUM -+} ENUM_SERVICE_TX_TYPE_T; -+ -+typedef struct _SERVICE_DISCOVERY_FRAME_DATA_T { -+ QUE_ENTRY_T rQueueEntry; -+ P_MSDU_INFO_T prSDFrame; -+ ENUM_SERVICE_TX_TYPE_T eServiceType; -+ UINT_8 ucSeqNum; -+ union { -+ -+ UINT_8 ucChannelNum; -+ UINT_8 aucPeerAddr[MAC_ADDR_LEN]; -+ } uTypeData; -+ BOOLEAN fgIsTxDoneIndicate; -+} SERVICE_DISCOVERY_FRAME_DATA_T, *P_SERVICE_DISCOVERY_FRAME_DATA_T; -+ -+struct _P2P_FSM_INFO_T_DEPRECATED { -+ /* P2P FSM State */ -+ ENUM_P2P_STATE_T eCurrentState; -+ -+ /* Channel */ -+ BOOLEAN fgIsChannelRequested; -+ -+ ENUM_P2P_STATE_T ePreviousState; -+ -+ ENUM_P2P_STATE_T eReturnState; /* Return state after current activity finished or abort. */ -+ -+ UINT_8 aucTargetIfAddr[PARAM_MAC_ADDR_LEN]; -+ P_BSS_DESC_T prTargetBss; /* BSS of target P2P Device. For Connection/Service Discovery */ -+ -+ P_STA_RECORD_T prTargetStaRec; -+ -+ BOOLEAN fgIsRsponseProbe; /* Indicate if P2P FSM can response probe request frame. */ -+ -+ /* Sequence number of requested message. */ -+ UINT_8 ucSeqNumOfReqMsg; /* Used for SAA FSM request message. */ -+ -+ /* Channel Privilege */ -+ UINT_8 ucSeqNumOfChReq; /* Used for Channel Request message. */ -+ -+ UINT_8 ucSeqNumOfScnMsg; /* Used for SCAN FSM request message. */ -+ UINT_8 ucSeqNumOfCancelMsg; -+ -+ UINT_8 ucDialogToken; -+ UINT_8 ucRxDialogToken; -+ -+ /* Timer */ -+ TIMER_T rDeviceDiscoverTimer; /* For device discovery time of each discovery request from user. */ -+ TIMER_T rOperationListenTimer; /* For Find phase under operational state. */ -+ TIMER_T rFSMTimer; /* A timer used for Action frame timeout usage. */ -+ -+ TIMER_T rRejoinTimer; /* A timer used for Action frame timeout usage. */ -+ -+ /* Flag to indicate Provisioning */ -+ BOOLEAN fgIsConnectionRequested; -+ -+ /* Current IOCTL. */ -+ ENUM_P2P_IOCTL_T eP2pIOCTL; -+ -+ UINT_8 ucAvailableAuthTypes; /* Used for AUTH_MODE_AUTO_SWITCH */ -+ -+ /*--------SERVICE DISCOVERY--------*/ -+ QUE_T rQueueGASRx; /* Input Request/Response. */ -+ QUE_T rQueueGASTx; /* Output Response. */ -+ P_SERVICE_DISCOVERY_FRAME_DATA_T prSDRequest; -+ UINT_8 ucVersionNum; /* GAS packet sequence number for...Action Frame? */ -+ UINT_8 ucGlobalSeqNum; /* Sequence Number of RX SD packet. */ -+ /*--------Service DISCOVERY--------*/ -+ -+ /*--------DEVICE DISCOVERY---------*/ -+ UINT_8 aucTargetGroupID[PARAM_MAC_ADDR_LEN]; -+ UINT_16 u2TargetGroupSsidLen; -+ UINT_8 aucTargetSsid[32]; -+ UINT_8 aucSearchingP2pDevice[PARAM_MAC_ADDR_LEN]; -+ UINT_8 ucDLToken; -+ /*----------------------------------*/ -+ -+ /* Indicating Peer Status. */ -+ UINT_32 u4Flags; -+ -+ /*Indicating current running mode. */ -+ BOOLEAN fgIsApMode; -+ -+ /*------------INVITATION------------*/ -+ ENUM_P2P_INVITATION_POLICY eInvitationRspPolicy; -+ /*----------------------------------*/ -+ -+}; -+ -+struct _P2P_SPECIFIC_BSS_INFO_T { -+ /* For GO(AP) Mode - Compose TIM IE */ -+ UINT_16 u2SmallestAID; -+ UINT_16 u2LargestAID; -+ UINT_8 ucBitmapCtrl; -+ /* UINT_8 aucPartialVirtualBitmap[MAX_LEN_TIM_PARTIAL_BMP]; */ -+ -+ /* For GC/GO OppPS */ -+ BOOLEAN fgEnableOppPS; -+ UINT_16 u2CTWindow; -+ -+ /* For GC/GO NOA */ -+ UINT_8 ucNoAIndex; -+ UINT_8 ucNoATimingCount; /* Number of NoA Timing */ -+ NOA_TIMING_T arNoATiming[P2P_MAXIMUM_NOA_COUNT]; -+ -+ BOOLEAN fgIsNoaAttrExisted; -+ -+ /* For P2P Device */ -+ UINT_8 ucRegClass; /* Regulatory Class for channel. */ -+ UINT_8 ucListenChannel; /* Linten Channel only on channels 1, 6 and 11 in the 2.4 GHz. */ -+ -+ UINT_8 ucPreferredChannel; /* Operating Channel, should be one of channel list -+ in p2p connection settings. */ -+ ENUM_CHNL_EXT_T eRfSco; -+ ENUM_BAND_T eRfBand; -+ -+ /* Extended Listen Timing. */ -+ UINT_16 u2AvailabilityPeriod; -+ UINT_16 u2AvailabilityInterval; -+ -+#if 0 /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0) */ -+ UINT_16 u2IELenForBCN; -+ UINT_8 aucBeaconIECache[P2P_MAXIMUM_ATTRIBUTES_CACHE_SIZE + WPS_MAXIMUM_ATTRIBUTES_CACHE_SIZE]; -+ -+/* UINT_16 u2IELenForProbeRsp; */ -+/* UINT_8 aucProbeRspIECache[P2P_MAXIMUM_ATTRIBUTES_CACHE_SIZE + WPS_MAXIMUM_ATTRIBUTES_CACHE_SIZE]; */ -+ -+ UINT_16 u2IELenForAssocRsp; -+ UINT_8 aucAssocRspIECache[P2P_MAXIMUM_ATTRIBUTES_CACHE_SIZE + WPS_MAXIMUM_ATTRIBUTES_CACHE_SIZE]; -+ -+#else -+ UINT_16 u2AttributeLen; -+ UINT_8 aucAttributesCache[P2P_MAXIMUM_ATTRIBUTES_CACHE_SIZE]; -+ -+ UINT_16 u2WscAttributeLen; -+ UINT_8 aucWscAttributesCache[WPS_MAXIMUM_ATTRIBUTES_CACHE_SIZE]; -+#endif -+ UINT_8 aucGroupID[MAC_ADDR_LEN]; -+ UINT_16 u2GroupSsidLen; -+ UINT_8 aucGroupSsid[ELEM_MAX_LEN_SSID]; -+ -+ PARAM_CUSTOM_NOA_PARAM_STRUCT_T rNoaParam; -+ PARAM_CUSTOM_OPPPS_PARAM_STRUCT_T rOppPsParam; -+ -+ UINT_16 u2WpaIeLen; -+ UINT_8 aucWpaIeBuffer[ELEM_HDR_LEN + ELEM_MAX_LEN_WPA]; -+}; -+ -+typedef struct _MSG_P2P_DEVICE_DISCOVER_T { -+ MSG_HDR_T rMsgHdr; /* Must be the first member */ -+ UINT_32 u4DevDiscoverTime; /* 0: Infinite, 1~X: in unit of MS. */ -+ BOOLEAN fgIsSpecificType; -+#if CFG_ENABLE_WIFI_DIRECT -+ P2P_DEVICE_TYPE_T rTargetDeviceType; -+#endif -+ UINT_8 aucTargetDeviceID[MAC_ADDR_LEN]; -+} MSG_P2P_DEVICE_DISCOVER_T, *P_MSG_P2P_DEVICE_DISCOVER_T; -+ -+typedef struct _MSG_P2P_INVITATION_REQUEST_T { -+ MSG_HDR_T rMsgHdr; /* Must be the first member */ -+ UINT_8 aucDeviceID[MAC_ADDR_LEN]; /* Target Device ID to be invited. */ -+} MSG_P2P_INVITATION_REQUEST_T, *P_MSG_P2P_INVITATION_REQUEST_T; -+ -+typedef struct _MSG_P2P_FUNCTION_SWITCH_T { -+ MSG_HDR_T rMsgHdr; /* Must be the first member */ -+ BOOLEAN fgIsFuncOn; -+} MSG_P2P_FUNCTION_SWITCH_T, *P_MSG_P2P_FUNCTION_SWITCH_T; -+ -+typedef struct _MSG_P2P_SERVICE_DISCOVERY_REQUEST_T { -+ MSG_HDR_T rMsgHdr; /* Must be the first member */ -+ UINT_8 aucDeviceID[MAC_ADDR_LEN]; -+ BOOLEAN fgNeedTxDoneIndicate; -+ UINT_8 ucSeqNum; -+} MSG_P2P_SERVICE_DISCOVERY_REQUEST_T, *P_MSG_P2P_SERVICE_DISCOVERY_REQUEST_T; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+#define p2pChangeMediaState(_prAdapter, _eNewMediaState) \ -+do { \ -+ (_prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX].eConnectionState = (_eNewMediaState));\ -+ wfdChangeMediaState((_prAdapter), NETWORK_TYPE_P2P_INDEX, (_eNewMediaState)); \ -+} while (0) -+ -+#define ATTRI_ID(_fp) (((P_P2P_ATTRIBUTE_T) _fp)->ucId) -+#define ATTRI_LEN(_fp) \ -+ (((UINT_16) ((PUINT_8)&((P_P2P_ATTRIBUTE_T) _fp)->u2Length)[0]) | \ -+ ((UINT_16) ((PUINT_8)&((P_P2P_ATTRIBUTE_T) _fp)->u2Length)[1] << 8)) -+ -+#define ATTRI_SIZE(_fp) (P2P_ATTRI_HDR_LEN + ATTRI_LEN(_fp)) -+ -+#define P2P_ATTRI_FOR_EACH(_pucAttriBuf, _u2AttriBufLen, _u2Offset) \ -+ for ((_u2Offset) = 0; ((_u2Offset) < (_u2AttriBufLen)); \ -+ (_u2Offset) += ATTRI_SIZE(_pucAttriBuf), ((_pucAttriBuf) += ATTRI_SIZE(_pucAttriBuf))) -+ -+#define P2P_IE(_fp) ((P_IE_P2P_T) _fp) -+ -+#define WSC_ATTRI_ID(_fp) \ -+ (((UINT_16) ((PUINT_8)&((P_WSC_ATTRIBUTE_T) _fp)->u2Id)[0] << 8) | \ -+ ((UINT_16) ((PUINT_8)&((P_WSC_ATTRIBUTE_T) _fp)->u2Id)[1])) -+ -+#define WSC_ATTRI_LEN(_fp) \ -+ (((UINT_16) ((PUINT_8)&((P_WSC_ATTRIBUTE_T) _fp)->u2Length)[0] << 8) | \ -+ ((UINT_16) ((PUINT_8)&((P_WSC_ATTRIBUTE_T) _fp)->u2Length)[1])) -+ -+#define WSC_ATTRI_SIZE(_fp) (WSC_ATTRI_HDR_LEN + WSC_ATTRI_LEN(_fp)) -+ -+#define WSC_ATTRI_FOR_EACH(_pucAttriBuf, _u2AttriBufLen, _u2Offset) \ -+ for ((_u2Offset) = 0; ((_u2Offset) < (_u2AttriBufLen)); \ -+ (_u2Offset) += WSC_ATTRI_SIZE(_pucAttriBuf), ((_pucAttriBuf) += WSC_ATTRI_SIZE(_pucAttriBuf))) -+ -+#define WSC_IE(_fp) ((P_IE_P2P_T) _fp) -+ -+#define WFD_ATTRI_ID(_fp) (((P_WFD_ATTRIBUTE_T) _fp)->ucElemID) -+ -+#define WFD_ATTRI_LEN(_fp) \ -+ (((UINT_16) ((PUINT_8)&((P_WFD_ATTRIBUTE_T) _fp)->u2Length)[0] << 8) | \ -+ ((UINT_16) ((PUINT_8)&((P_WFD_ATTRIBUTE_T) _fp)->u2Length)[1])) -+ -+#define WFD_ATTRI_SIZE(_fp) (WFD_ATTRI_HDR_LEN + WFD_ATTRI_LEN(_fp)) -+ -+#define WFD_ATTRI_FOR_EACH(_pucAttriBuf, _u2AttriBufLen, _u2Offset) \ -+ for ((_u2Offset) = 0; ((_u2Offset) < (_u2AttriBufLen)); \ -+ (_u2Offset) += WFD_ATTRI_SIZE(_pucAttriBuf), ((_pucAttriBuf) += WFD_ATTRI_SIZE(_pucAttriBuf))) -+ -+#if DBG -+#define ASSERT_BREAK(_exp) \ -+ { \ -+ if (!(_exp)) { \ -+ ASSERT(FALSE); \ -+ break; \ -+ } \ -+ } -+ -+#else -+#define ASSERT_BREAK(_exp) -+#endif -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/*======P2P State======*/ -+VOID -+p2pStateInit_LISTEN(IN P_ADAPTER_T prAdapter, -+ IN P_P2P_FSM_INFO_T prP2pFsmInfo, -+ IN P_P2P_SPECIFIC_BSS_INFO_T prSP2pBssInfo, IN UINT_8 ucListenChannel); -+ -+VOID p2pStateAbort_LISTEN(IN P_ADAPTER_T prAdapter, IN BOOLEAN fgIsChannelExtenstion); -+ -+VOID p2pStateAbort_SEARCH_SCAN(IN P_ADAPTER_T prAdapter, IN BOOLEAN fgIsChannelExtenstion); -+ -+VOID p2pStateAbort_GO_OPERATION(IN P_ADAPTER_T prAdapter); -+ -+VOID p2pStateAbort_GC_OPERATION(IN P_ADAPTER_T prAdapter); -+ -+VOID -+p2pStateInit_CONFIGURATION(IN P_ADAPTER_T prAdapter, -+ IN P_P2P_FSM_INFO_T prP2pFsmInfo, -+ IN P_BSS_INFO_T prP2pBssInfo, IN P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecBssInfo); -+ -+VOID p2pStateAbort_CONFIGURATION(IN P_ADAPTER_T prAdapter); -+ -+VOID p2pStateInit_JOIN(IN P_ADAPTER_T prAdapter); -+ -+VOID p2pStateAbort_JOIN(IN P_ADAPTER_T prAdapter); -+ -+/*====== P2P Functions ======*/ -+ -+VOID p2pFuncInitGO(IN P_ADAPTER_T prAdapter); -+ -+VOID -+p2pFuncDisconnect(IN P_ADAPTER_T prAdapter, -+ IN P_STA_RECORD_T prStaRec, IN BOOLEAN fgSendDeauth, IN UINT_16 u2ReasonCode); -+ -+VOID -+p2pFuncSwitchOPMode(IN P_ADAPTER_T prAdapter, -+ IN P_BSS_INFO_T prP2pBssInfo, IN ENUM_OP_MODE_T eOpMode, IN BOOLEAN fgSyncToFW); -+ -+VOID p2pFuncRunEventProvisioningComplete(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); -+ -+WLAN_STATUS p2pFuncSetGroupID(IN P_ADAPTER_T prAdapter, IN PUINT_8 pucGroupID, IN PUINT_8 pucSsid, IN UINT_8 ucSsidLen); -+ -+WLAN_STATUS -+p2pFuncSendDeviceDiscoverabilityReqFrame(IN P_ADAPTER_T prAdapter, IN UINT_8 aucDestAddr[], IN UINT_8 ucDialogToken); -+ -+WLAN_STATUS -+p2pFuncSendDeviceDiscoverabilityRspFrame(IN P_ADAPTER_T prAdapter, IN UINT_8 aucDestAddr[], IN UINT_8 ucDialogToken); -+ -+UINT_8 p2pFuncGetVersionNumOfSD(IN P_ADAPTER_T prAdapter); -+ -+/*====== P2P FSM ======*/ -+VOID p2pFsmRunEventConnectionRequest(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); -+ -+VOID p2pFsmRunEventDeviceDiscoveryRequest(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); -+ -+VOID p2pFsmRunEventDeviceDiscoveryAbort(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); -+ -+VOID p2pFsmRunEventRxGroupNegotiationReqFrame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); -+ -+WLAN_STATUS -+p2pFsmRunEventGroupNegotiationRequestTxDone(IN P_ADAPTER_T prAdapter, -+ IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus); -+ -+WLAN_STATUS -+p2pFsmRunEventGroupNegotiationResponseTxDone(IN P_ADAPTER_T prAdapter, -+ IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus); -+ -+WLAN_STATUS -+p2pFsmRunEventGroupNegotiationConfirmTxDone(IN P_ADAPTER_T prAdapter, -+ IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus); -+ -+WLAN_STATUS -+p2pFsmRunEventProvisionDiscoveryRequestTxDone(IN P_ADAPTER_T prAdapter, -+ IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus); -+ -+WLAN_STATUS -+p2pFsmRunEventProvisionDiscoveryResponseTxDone(IN P_ADAPTER_T prAdapter, -+ IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus); -+ -+WLAN_STATUS -+p2pFsmRunEventInvitationRequestTxDone(IN P_ADAPTER_T prAdapter, -+ IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus); -+ -+VOID p2pFsmRunEventRxDeauthentication(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN P_SW_RFB_T prSwRfb); -+ -+VOID p2pFsmRunEventRxDisassociation(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN P_SW_RFB_T prSwRfb); -+ -+VOID p2pFsmRunEventBeaconTimeout(IN P_ADAPTER_T prAdapter); -+ -+WLAN_STATUS -+p2pFsmRunEventDeauthTxDone(IN P_ADAPTER_T prAdapter, -+ IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus); -+ -+#if 1 -+#endif -+ -+/* //////////////////////////////////////////////////////////////////////// */ -+/* //////////////////////////////////////////////////////////////////////// */ -+/* //////////////////////////////////////////////////////////////////////// */ -+/* //////////////////////////////////////////////////////////////////////// */ -+/* //////////////////////////////////////////////////////////////////////// */ -+/* //////////////////////////////////////////////////////////////////////// */ -+/* //////////////////////////////////////////////////////////////////////// */ -+/* //////////////////////////////////////////////////////////////////////// */ -+/* //////////////////////////////////////////////////////////////////////// */ -+/* //////////////////////////////////////////////////////////////////////// */ -+/* //////////////////////////////////////////////////////////////////////// */ -+/*======Mail Box Event Message=====*/ -+ -+VOID p2pFsmRunEventConnectionAbort(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); -+ -+VOID p2pFsmRunEventConnectionTrigger(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); -+ -+VOID p2pFsmRunEventP2PFunctionSwitch(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); -+ -+VOID p2pFsmRunEventChGrant(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); -+ -+VOID p2pFsmRunEventJoinComplete(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); -+ -+VOID p2pFsmRunEventConnectionPause(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); -+ -+VOID -+p2pIndicationOfMediaStateToHost(IN P_ADAPTER_T prAdapter, -+ IN ENUM_PARAM_MEDIA_STATE_T eConnectionState, IN UINT_8 aucTargetAddr[]); -+ -+VOID p2pUpdateBssInfoForJOIN(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN P_SW_RFB_T prAssocRspSwRfb); -+ -+/*======Mail Box Event Message=====*/ -+ -+VOID p2pFsmInit(IN P_ADAPTER_T prAdapter); -+ -+VOID p2pFsmUninit(IN P_ADAPTER_T prAdapter); -+ -+VOID p2pFsmSteps(IN P_ADAPTER_T prAdapter, IN ENUM_P2P_STATE_T eNextState); -+ -+VOID p2pStartGO(IN P_ADAPTER_T prAdapter); -+ -+VOID p2pAssignSsid(IN PUINT_8 pucSsid, IN PUINT_8 pucSsidLen); -+ -+VOID p2pFsmRunEventScanDone(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); -+ -+VOID p2pFsmRunEventIOReqTimeout(IN P_ADAPTER_T prAdapter, IN UINT_32 u4Param); -+ -+VOID p2pFsmRunEventSearchPeriodTimeout(IN P_ADAPTER_T prAdapter, IN UINT_32 u4Param); -+ -+VOID p2pFsmRunEventFsmTimeout(IN P_ADAPTER_T prAdapter, IN ULONG u4Param); -+ -+VOID p2pFsmRunEventRejoinTimeout(IN P_ADAPTER_T prAdapter, IN UINT_32 u4Parm); -+ -+/*=============== P2P Function Related ================*/ -+ -+/*=============== P2P Function Related ================*/ -+ -+#if CFG_TEST_WIFI_DIRECT_GO -+VOID p2pTest(IN P_ADAPTER_T prAdapter); -+#endif /* CFG_TEST_WIFI_DIRECT_GO */ -+ -+VOID p2pGenerateP2P_IEForBeacon(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); -+ -+VOID p2pGenerateP2P_IEForAssocReq(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); -+ -+VOID p2pGenerateP2P_IEForAssocRsp(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); -+ -+VOID -+p2pGenerateP2P_IEForProbeReq(IN P_ADAPTER_T prAdapter, IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); -+ -+UINT_32 -+p2pCalculateP2P_IELenForBeacon(IN P_ADAPTER_T prAdapter, -+ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec); -+ -+UINT_32 -+p2pCalculateP2P_IELenForAssocRsp(IN P_ADAPTER_T prAdapter, -+ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec); -+ -+UINT_32 -+p2pCalculateP2P_IELenForProbeReq(IN P_ADAPTER_T prAdapter, -+ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec); -+ -+VOID p2pGenerateWSC_IEForProbeResp(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); -+ -+VOID -+p2pGenerateWSC_IEForProbeReq(IN P_ADAPTER_T prAdapter, IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); -+ -+UINT_16 p2pCalculateWSC_IELenForProbeReq(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex); -+ -+UINT_32 -+p2pCalculateWSC_IELenForProbeResp(IN P_ADAPTER_T prAdapter, -+ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec); -+ -+UINT_32 -+p2pAppendAttriStatus(IN P_ADAPTER_T prAdapter, -+ IN BOOLEAN fgIsAssocFrame, IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); -+ -+UINT_32 -+p2pAppendAttriCapability(IN P_ADAPTER_T prAdapter, -+ IN BOOLEAN fgIsAssocFrame, IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); -+ -+UINT_32 -+p2pAppendAttriGoIntent(IN P_ADAPTER_T prAdapter, -+ IN BOOLEAN fgIsAssocFrame, IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); -+ -+UINT_32 -+p2pAppendAttriCfgTimeout(IN P_ADAPTER_T prAdapter, -+ IN BOOLEAN fgIsAssocFrame, IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); -+ -+UINT_32 -+p2pAppendAttriGroupBssid(IN P_ADAPTER_T prAdapter, -+ IN BOOLEAN fgIsAssocFrame, IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); -+ -+UINT_32 -+p2pAppendAttriDeviceIDForBeacon(IN P_ADAPTER_T prAdapter, -+ IN BOOLEAN fgIsAssocFrame, -+ IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); -+ -+UINT_32 -+p2pAppendAttriDeviceIDForProbeReq(IN P_ADAPTER_T prAdapter, -+ IN BOOLEAN fgIsAssocFrame, -+ IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); -+ -+UINT_32 -+p2pAppendAttriDeviceIDForDeviceDiscoveryReq(IN P_ADAPTER_T prAdapter, -+ IN BOOLEAN fgIsAssocFrame, -+ IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); -+ -+UINT_32 -+p2pAppendAttriListenChannel(IN P_ADAPTER_T prAdapter, -+ IN BOOLEAN fgIsAssocFrame, IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); -+ -+UINT_32 -+p2pAppendAttriIntendP2pIfAddr(IN P_ADAPTER_T prAdapter, -+ IN BOOLEAN fgIsAssocFrame, -+ IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); -+ -+UINT_32 -+p2pAppendAttriChannelList(IN P_ADAPTER_T prAdapter, -+ IN BOOLEAN fgIsAssocFrame, IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); -+ -+UINT_32 p2pCalculateAttriLenChannelList(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec); -+ -+UINT_32 -+p2pAppendAttriNoA(IN P_ADAPTER_T prAdapter, -+ IN BOOLEAN fgIsAssocFrame, IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); -+ -+UINT_32 -+p2pAppendAttriDeviceInfo(IN P_ADAPTER_T prAdapter, -+ IN BOOLEAN fgIsAssocFrame, IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); -+ -+UINT_32 p2pCalculateAttriLenDeviceInfo(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec); -+ -+UINT_32 -+p2pAppendAttriGroupInfo(IN P_ADAPTER_T prAdapter, -+ IN BOOLEAN fgIsAssocFrame, IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); -+ -+UINT_32 p2pCalculateAttriLenGroupInfo(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec); -+ -+UINT_32 -+p2pAppendAttriP2pGroupID(IN P_ADAPTER_T prAdapter, -+ IN BOOLEAN fgIsAssocFrame, IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); -+ -+UINT_32 -+p2pAppendAttriOperatingChannel(IN P_ADAPTER_T prAdapter, -+ IN BOOLEAN fgIsAssocFrame, -+ IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); -+ -+UINT_32 -+p2pAppendAttriInvitationFlag(IN P_ADAPTER_T prAdapter, -+ IN BOOLEAN fgIsAssocFrame, IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); -+ -+VOID -+p2pGenerateWscIE(IN P_ADAPTER_T prAdapter, -+ IN UINT_8 ucOuiType, -+ IN BOOLEAN fgIsAssocFrame, -+ IN PUINT_16 pu2Offset, -+ IN PUINT_8 pucBuf, -+ IN UINT_16 u2BufSize, IN APPEND_VAR_ATTRI_ENTRY_T arAppendAttriTable[], IN UINT_32 u4AttriTableSize); -+ -+UINT_32 -+p2pAppendAttriWSCConfigMethod(IN P_ADAPTER_T prAdapter, -+ IN BOOLEAN fgIsAssocFrame, -+ IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); -+ -+UINT_32 -+p2pAppendAttriWSCVersion(IN P_ADAPTER_T prAdapter, -+ IN BOOLEAN fgIsAssocFrame, IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); -+ -+UINT_32 -+p2pAppendAttriWSCGONegReqDevPasswordId(IN P_ADAPTER_T prAdapter, -+ IN BOOLEAN fgIsAssocFrame, -+ IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); -+ -+UINT_32 -+p2pAppendAttriWSCGONegRspDevPasswordId(IN P_ADAPTER_T prAdapter, -+ IN BOOLEAN fgIsAssocFrame, -+ IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); -+ -+WLAN_STATUS -+p2pGetWscAttriList(IN P_ADAPTER_T prAdapter, -+ IN UINT_8 ucOuiType, -+ IN PUINT_8 pucIE, IN UINT_16 u2IELength, OUT PPUINT_8 ppucAttriList, OUT PUINT_16 pu2AttriListLen); -+ -+WLAN_STATUS -+p2pGetAttriList(IN P_ADAPTER_T prAdapter, -+ IN UINT_8 ucOuiType, -+ IN PUINT_8 pucIE, IN UINT_16 u2IELength, OUT PPUINT_8 ppucAttriList, OUT PUINT_16 pu2AttriListLen); -+ -+VOID p2pRunEventAAATxFail(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec); -+ -+WLAN_STATUS p2pRunEventAAASuccess(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec); -+ -+WLAN_STATUS p2pRunEventAAAComplete(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec); -+ -+WLAN_STATUS p2pSendProbeResponseFrame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); -+ -+BOOLEAN p2pFsmRunEventRxProbeRequestFrame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); -+ -+VOID p2pFsmRunEventRxProbeResponseFrame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, IN P_BSS_DESC_T prBssDesc); -+ -+WLAN_STATUS p2pRxPublicActionFrame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); -+ -+WLAN_STATUS p2pRxActionFrame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); -+ -+VOID p2pFsmRunEventRxGroupNegotiationRspFrame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); -+ -+VOID p2pFsmRunEventRxGroupNegotiationCfmFrame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); -+ -+#if 0 /* frog */ -+BOOLEAN scanMatchFilterOfP2P(IN P_SW_RFB_T prSWRfb, IN PP_BSS_DESC_T pprBssDesc); -+#endif /* frog */ -+ -+VOID -+p2pProcessEvent_UpdateNOAParam(IN P_ADAPTER_T prAdapter, -+ UINT_8 ucNetTypeIndex, P_EVENT_UPDATE_NOA_PARAMS_T prEventUpdateNoaParam); -+ -+VOID p2pFuncCompleteIOCTL(IN P_ADAPTER_T prAdapter, IN WLAN_STATUS rWlanStatus); -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+#ifndef _lint -+/* Kevin: we don't have to call following function to inspect the data structure. -+ * It will check automatically while at compile time. -+ * We'll need this for porting driver to different RTOS. -+ */ -+static inline VOID p2pDataTypeCheck(VOID) -+{ -+ DATA_STRUCT_INSPECTING_ASSERT(sizeof(IE_P2P_T) == (2 + 4 + 1)); /* all UINT_8 */ -+ DATA_STRUCT_INSPECTING_ASSERT(sizeof(P2P_ATTRIBUTE_T) == (3 + 1)); -+ DATA_STRUCT_INSPECTING_ASSERT(sizeof(P2P_ATTRI_STATUS_T) == (3 + 1)); -+ DATA_STRUCT_INSPECTING_ASSERT(sizeof(P2P_ATTRI_REASON_T) == (3 + 1)); -+ DATA_STRUCT_INSPECTING_ASSERT(sizeof(P2P_ATTRI_CAPABILITY_T) == (3 + 2)); -+ DATA_STRUCT_INSPECTING_ASSERT(sizeof(P2P_ATTRI_DEV_ID_T) == (3 + 6)); -+ DATA_STRUCT_INSPECTING_ASSERT(sizeof(P2P_ATTRI_GO_INTENT_T) == (3 + 1)); -+ DATA_STRUCT_INSPECTING_ASSERT(sizeof(P2P_ATTRI_CFG_TIMEOUT_T) == (3 + 2)); -+#if CID52_53_54 -+ DATA_STRUCT_INSPECTING_ASSERT(sizeof(P2P_ATTRI_LISTEN_CHANNEL_T) == (3 + 5)); -+#else -+ DATA_STRUCT_INSPECTING_ASSERT(sizeof(P2P_ATTRI_LISTEN_CHANNEL_T) == (3 + 5)); -+#endif -+ DATA_STRUCT_INSPECTING_ASSERT(sizeof(P2P_ATTRI_GROUP_BSSID_T) == (3 + 6)); -+ DATA_STRUCT_INSPECTING_ASSERT(sizeof(P2P_ATTRI_EXT_LISTEN_TIMING_T) == (3 + 4)); -+ DATA_STRUCT_INSPECTING_ASSERT(sizeof(P2P_ATTRI_INTENDED_IF_ADDR_T) == (3 + 6)); -+ DATA_STRUCT_INSPECTING_ASSERT(sizeof(P2P_ATTRI_MANAGEABILITY_T) == (3 + 1)); -+ -+ DATA_STRUCT_INSPECTING_ASSERT(sizeof(P2P_ATTRI_CHANNEL_T) == (3 + 4)); -+ DATA_STRUCT_INSPECTING_ASSERT(sizeof(CHANNEL_ENTRY_FIELD_T) == 3); -+ DATA_STRUCT_INSPECTING_ASSERT(sizeof(P2P_ATTRI_NOA_T) == (3 + 3)); -+ DATA_STRUCT_INSPECTING_ASSERT(sizeof(NOA_DESCRIPTOR_T) == 13); -+ DATA_STRUCT_INSPECTING_ASSERT(sizeof(DEVICE_TYPE_T) == 8); -+ DATA_STRUCT_INSPECTING_ASSERT(sizeof(P2P_ATTRI_DEV_INFO_T) == (3 + 6 + 2 + 8 + 1 + 8)); -+ DATA_STRUCT_INSPECTING_ASSERT(sizeof(DEVICE_NAME_TLV_T) == (4 + 32)); -+ DATA_STRUCT_INSPECTING_ASSERT(sizeof(P2P_CLIENT_INFO_DESC_T) == (1 + 6 + 6 + 1 + 2 + 8 + 1 + 8)); -+ DATA_STRUCT_INSPECTING_ASSERT(sizeof(P2P_ATTRI_GROUP_INFO_T) == (3 + (1 + 6 + 6 + 1 + 2 + 8 + 1 + 8))); -+ DATA_STRUCT_INSPECTING_ASSERT(sizeof(P2P_ATTRI_GROUP_ID_T) == (3 + 38)); -+ DATA_STRUCT_INSPECTING_ASSERT(sizeof(P2P_ATTRI_INTERFACE_T) == (3 + 13)); -+#if CID52_53_54 -+ DATA_STRUCT_INSPECTING_ASSERT(sizeof(P2P_ATTRI_OPERATING_CHANNEL_T) == (3 + 5)); -+#else -+ DATA_STRUCT_INSPECTING_ASSERT(sizeof(P2P_ATTRI_OPERATING_CHANNEL_T) == (3 + 5)); -+#endif -+ -+} -+#endif /* _lint */ -+ -+#endif /* _P2P_FSM_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_func.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_func.h -new file mode 100644 -index 000000000000..1ac1770debca ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_func.h -@@ -0,0 +1,155 @@ -+#ifndef _P2P_FUNC_H -+#define _P2P_FUNC_H -+ -+#define P2P_EXT_LISTEN_TIME_MS 600 -+#define P2P_OFF_CHNL_TX_DEFAULT_TIME_MS 1000 -+ -+VOID p2pFuncRequestScan(IN P_ADAPTER_T prAdapter, IN P_P2P_SCAN_REQ_INFO_T prScanReqInfo); -+ -+VOID p2pFuncCancelScan(IN P_ADAPTER_T prAdapter, IN P_P2P_SCAN_REQ_INFO_T prScanReqInfo); -+ -+VOID -+p2pFuncStartGO(IN P_ADAPTER_T prAdapter, -+ IN P_BSS_INFO_T prBssInfo, -+ IN PUINT_8 pucSsidBuf, -+ IN UINT_8 ucSsidLen, -+ IN UINT_8 ucChannelNum, IN ENUM_BAND_T eBand, IN ENUM_CHNL_EXT_T eSco, IN BOOLEAN fgIsPureAP); -+ -+VOID p2pFuncAcquireCh(IN P_ADAPTER_T prAdapter, IN P_P2P_CHNL_REQ_INFO_T prChnlReqInfo); -+ -+VOID p2pFuncReleaseCh(IN P_ADAPTER_T prAdapter, IN P_P2P_CHNL_REQ_INFO_T prChnlReqInfo); -+ -+VOID p2pFuncSetChannel(IN P_ADAPTER_T prAdapter, IN P_RF_CHANNEL_INFO_T prRfChannelInfo); -+ -+BOOLEAN p2pFuncRetryJOIN(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN P_P2P_JOIN_INFO_T prJoinInfo); -+ -+VOID -+p2pFuncUpdateBssInfoForJOIN(IN P_ADAPTER_T prAdapter, -+ IN P_BSS_DESC_T prBssDesc, IN P_STA_RECORD_T prStaRec, IN P_SW_RFB_T prAssocRspSwRfb); -+ -+WLAN_STATUS -+p2pFuncTxMgmtFrame(IN P_ADAPTER_T prAdapter, -+ IN P_P2P_MGMT_TX_REQ_INFO_T prMgmtTxReqInfo, IN P_MSDU_INFO_T prMgmtTxMsdu, IN UINT_64 u8Cookie); -+ -+WLAN_STATUS -+p2pFuncBeaconUpdate(IN P_ADAPTER_T prAdapter, -+ IN P_BSS_INFO_T prP2pBssInfo, -+ IN P_P2P_BEACON_UPDATE_INFO_T prBcnUpdateInfo, -+ IN PUINT_8 pucNewBcnHdr, IN UINT_32 u4NewHdrLen, IN PUINT_8 pucNewBcnBody, IN UINT_32 u4NewBodyLen); -+ -+BOOLEAN -+p2pFuncValidateAuth(IN P_ADAPTER_T prAdapter, -+ IN P_SW_RFB_T prSwRfb, IN PP_STA_RECORD_T pprStaRec, OUT PUINT_16 pu2StatusCode); -+ -+BOOLEAN p2pFuncValidateAssocReq(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, OUT PUINT_16 pu2StatusCode); -+ -+VOID p2pFuncResetStaRecStatus(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec); -+ -+VOID p2pFuncInitConnectionSettings(IN P_ADAPTER_T prAdapter, IN P_P2P_CONNECTION_SETTINGS_T prP2PConnSettings); -+ -+BOOLEAN p2pFuncParseCheckForP2PInfoElem(IN P_ADAPTER_T prAdapter, IN PUINT_8 pucBuf, OUT PUINT_8 pucOuiType); -+ -+BOOLEAN p2pFuncValidateProbeReq(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, OUT PUINT_32 pu4ControlFlags); -+ -+VOID p2pFuncValidateRxActionFrame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); -+ -+BOOLEAN p2pFuncIsAPMode(IN P_P2P_FSM_INFO_T prP2pFsmInfo); -+ -+VOID -+p2pFuncParseBeaconContent(IN P_ADAPTER_T prAdapter, -+ IN P_BSS_INFO_T prP2pBssInfo, IN PUINT_8 pucIEInfo, IN UINT_32 u4IELen); -+ -+P_BSS_DESC_T -+p2pFuncKeepOnConnection(IN P_ADAPTER_T prAdapter, -+ IN P_P2P_CONNECTION_REQ_INFO_T prConnReqInfo, -+ IN P_P2P_CHNL_REQ_INFO_T prChnlReqInfo, IN P_P2P_SCAN_REQ_INFO_T prScanReqInfo); -+ -+VOID p2pFuncStoreAssocRspIEBuffer(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); -+ -+VOID -+p2pFuncMgmtFrameRegister(IN P_ADAPTER_T prAdapter, -+ IN UINT_16 u2FrameType, IN BOOLEAN fgIsRegistered, OUT PUINT_32 pu4P2pPacketFilter); -+ -+VOID p2pFuncUpdateMgmtFrameRegister(IN P_ADAPTER_T prAdapter, IN UINT_32 u4OsFilter); -+ -+VOID p2pFuncGetStationInfo(IN P_ADAPTER_T prAdapter, IN PUINT_8 pucMacAddr, OUT P_P2P_STATION_INFO_T prStaInfo); -+ -+BOOLEAN -+p2pFuncGetAttriList(IN P_ADAPTER_T prAdapter, -+ IN UINT_8 ucOuiType, -+ IN PUINT_8 pucIE, IN UINT_16 u2IELength, OUT PPUINT_8 ppucAttriList, OUT PUINT_16 pu2AttriListLen); -+ -+P_MSDU_INFO_T p2pFuncProcessP2pProbeRsp(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMgmtTxMsdu); -+ -+#if 0 /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0) */ -+UINT_32 -+p2pFuncCalculateExtra_IELenForBeacon(IN P_ADAPTER_T prAdapter, -+ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec); -+ -+VOID p2pFuncGenerateExtra_IEForBeacon(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); -+ -+#else -+UINT_32 -+p2pFuncCalculateP2p_IELenForBeacon(IN P_ADAPTER_T prAdapter, -+ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec); -+ -+VOID p2pFuncGenerateP2p_IEForBeacon(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); -+ -+UINT_32 -+p2pFuncCalculateWSC_IELenForBeacon(IN P_ADAPTER_T prAdapter, -+ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec); -+ -+VOID p2pFuncGenerateWSC_IEForBeacon(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); -+#endif -+UINT_32 -+p2pFuncCalculateP2p_IELenForAssocRsp(IN P_ADAPTER_T prAdapter, -+ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec); -+ -+VOID p2pFuncGenerateP2p_IEForAssocRsp(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); -+ -+UINT_32 -+p2pFuncCalculateWSC_IELenForAssocRsp(IN P_ADAPTER_T prAdapter, -+ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec); -+ -+VOID p2pFuncGenerateWSC_IEForAssocRsp(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); -+ -+UINT_32 -+p2pFuncCalculateP2P_IELen(IN P_ADAPTER_T prAdapter, -+ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, -+ IN P_STA_RECORD_T prStaRec, -+ IN APPEND_VAR_ATTRI_ENTRY_T arAppendAttriTable[], IN UINT_32 u4AttriTableSize); -+ -+VOID -+p2pFuncGenerateP2P_IE(IN P_ADAPTER_T prAdapter, -+ IN BOOLEAN fgIsAssocFrame, -+ IN PUINT_16 pu2Offset, -+ IN PUINT_8 pucBuf, -+ IN UINT_16 u2BufSize, -+ IN APPEND_VAR_ATTRI_ENTRY_T arAppendAttriTable[], IN UINT_32 u4AttriTableSize); -+ -+UINT_32 -+p2pFuncAppendAttriStatusForAssocRsp(IN P_ADAPTER_T prAdapter, -+ IN BOOLEAN fgIsAssocFrame, -+ IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); -+ -+UINT_32 -+p2pFuncAppendAttriExtListenTiming(IN P_ADAPTER_T prAdapter, -+ IN BOOLEAN fgIsAssocFrame, -+ IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); -+ -+VOID -+p2pFuncDissolve(IN P_ADAPTER_T prAdapter, -+ IN P_BSS_INFO_T prP2pBssInfo, IN BOOLEAN fgSendDeauth, IN UINT_16 u2ReasonCode); -+ -+P_IE_HDR_T -+p2pFuncGetSpecIE(IN P_ADAPTER_T prAdapter, -+ IN PUINT_8 pucIEBuf, IN UINT_16 u2BufferLen, IN UINT_8 ucElemID, IN PBOOLEAN pfgIsMore); -+ -+P_ATTRIBUTE_HDR_T -+p2pFuncGetSpecAttri(IN P_ADAPTER_T prAdapter, -+ IN UINT_8 ucOuiType, IN PUINT_8 pucIEBuf, IN UINT_16 u2BufferLen, IN UINT_16 u2AttriID); -+ -+WLAN_STATUS wfdChangeMediaState(IN P_ADAPTER_T prAdapter, -+ IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx, -+ IN ENUM_PARAM_MEDIA_STATE_T eConnectionState); -+#endif -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_ie.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_ie.h -new file mode 100644 -index 000000000000..efb75855695f ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_ie.h -@@ -0,0 +1,156 @@ -+#ifndef _P2P_IE_H -+#define _P2P_IE_H -+ -+#if CFG_SUPPORT_WFD -+ -+#define ELEM_MAX_LEN_WFD 62 /* TODO: Move to appropriate place */ -+ -+/*---------------- WFD Data Element Definitions ----------------*/ -+/* WFD 4.1.1 - WFD IE format */ -+#define WFD_OUI_TYPE_LEN 4 -+#define WFD_IE_OUI_HDR (ELEM_HDR_LEN + WFD_OUI_TYPE_LEN) /* == OFFSET_OF(IE_P2P_T, -+ aucP2PAttributes[0]) */ -+ -+/* WFD 4.1.1 - General WFD Attribute */ -+#define WFD_ATTRI_HDR_LEN 3 /* ID(1 octet) + Length(2 octets) */ -+ -+/* WFD Attribute Code */ -+#define WFD_ATTRI_ID_DEV_INFO 0 -+#define WFD_ATTRI_ID_ASSOC_BSSID 1 -+#define WFD_ATTRI_ID_COUPLED_SINK_INFO 6 -+#define WFD_ATTRI_ID_EXT_CAPABILITY 7 -+#define WFD_ATTRI_ID_SESSION_INFO 9 -+#define WFD_ATTRI_ID_ALTER_MAC_ADDRESS 10 -+ -+/* Maximum Length of WFD Attributes */ -+#define WFD_ATTRI_MAX_LEN_DEV_INFO 6 /* 0 */ -+#define WFD_ATTRI_MAX_LEN_ASSOC_BSSID 6 /* 1 */ -+#define WFD_ATTRI_MAX_LEN_COUPLED_SINK_INFO 7 /* 6 */ -+#define WFD_ATTRI_MAX_LEN_EXT_CAPABILITY 2 /* 7 */ -+#define WFD_ATTRI_MAX_LEN_SESSION_INFO 0 /* 9 */ /* 24 * #Clients */ -+#define WFD_ATTRI_MAX_LEN_ALTER_MAC_ADDRESS 6 /* 10 */ -+ -+/* WFD 1.10 5.1.1 */ -+typedef struct _IE_WFD_T { -+ UINT_8 ucId; /* Element ID */ -+ UINT_8 ucLength; /* Length */ -+ UINT_8 aucOui[3]; /* OUI */ -+ UINT_8 ucOuiType; /* OUI Type */ -+ UINT_8 aucWFDAttributes[1]; /* WFD Subelement */ -+} __KAL_ATTRIB_PACKED__ IE_WFD_T, *P_IE_WFD_T; -+ -+typedef struct _WFD_ATTRIBUTE_T { -+ UINT_8 ucElemID; /* Subelement ID */ -+ UINT_16 u2Length; /* Length */ -+ UINT_8 aucBody[1]; /* Body field */ -+} __KAL_ATTRIB_PACKED__ WFD_ATTRIBUTE_T, *P_WFD_ATTRIBUTE_T; -+ -+typedef struct _WFD_DEVICE_INFORMATION_IE_T { -+ UINT_8 ucElemID; -+ UINT_16 u2Length; -+ UINT_16 u2WfdDevInfo; -+ UINT_16 u2SessionMgmtCtrlPort; -+ UINT_16 u2WfdDevMaxSpeed; -+} __KAL_ATTRIB_PACKED__ WFD_DEVICE_INFORMATION_IE_T, *P_WFD_DEVICE_INFORMATION_IE_T; -+ -+typedef struct _WFD_ASSOCIATED_BSSID_IE_T { -+ UINT_8 ucElemID; -+ UINT_16 u2Length; -+ UINT_8 aucAssocBssid[MAC_ADDR_LEN]; -+} __KAL_ATTRIB_PACKED__ WFD_ASSOCIATED_BSSID_IE_T, *P_WFD_ASSOCIATED_BSSID_IE_T; -+ -+typedef struct _WFD_COUPLE_SINK_INFORMATION_IE_T { -+ UINT_8 ucElemID; -+ UINT_16 u2Length; -+ UINT_8 ucCoupleSinkStatusBp; -+ UINT_8 aucCoupleSinkMac[MAC_ADDR_LEN]; -+} __KAL_ATTRIB_PACKED__ WFD_COUPLE_SINK_INFORMATION_IE_T, *P_WFD_COUPLE_SINK_INFORMATION_IE_T; -+ -+typedef struct _WFD_EXTENDED_CAPABILITY_IE_T { -+ UINT_8 ucElemID; -+ UINT_16 u2Length; -+ UINT_16 u2WfdExtCapabilityBp; -+} __KAL_ATTRIB_PACKED__ WFD_EXTENDED_CAPABILITY_IE_T, *P_WFD_EXTENDED_CAPABILITY_IE_T; -+ -+typedef struct _WFD_SESSION_INFORMATION_IE_T { -+ UINT_8 ucElemID; -+ UINT_16 u2Length; -+ PUINT_8 pucWfdDevInfoDesc[1]; -+} __KAL_ATTRIB_PACKED__ WFD_SESSION_INFORMATION_IE_T, *P_WFD_SESSION_INFORMATION_IE_T; -+ -+typedef struct _WFD_DEVICE_INFORMATION_DESCRIPTOR_T { -+ UINT_8 ucLength; -+ UINT_8 aucDevAddr[MAC_ADDR_LEN]; -+ UINT_8 aucAssocBssid[MAC_ADDR_LEN]; -+ UINT_16 u2WfdDevInfo; -+ UINT_16 u2WfdDevMaxSpeed; -+ UINT_8 ucCoupleSinkStatusBp; -+ UINT_8 aucCoupleSinkMac[MAC_ADDR_LEN]; -+} __KAL_ATTRIB_PACKED__ WFD_DEVICE_INFORMATION_DESCRIPTOR_T, *P_WFD_DEVICE_INFORMATION_DESCRIPTOR_T; -+ -+#endif -+ -+UINT_32 -+p2pCalculate_IEForAssocReq(IN P_ADAPTER_T prAdapter, -+ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec); -+ -+VOID p2pGenerate_IEForAssocReq(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); -+ -+#if CFG_SUPPORT_WFD -+ -+UINT_32 -+wfdFuncAppendAttriDevInfo(IN P_ADAPTER_T prAdapter, -+ IN BOOLEAN fgIsAssocFrame, IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); -+ -+UINT_32 -+wfdFuncAppendAttriAssocBssid(IN P_ADAPTER_T prAdapter, -+ IN BOOLEAN fgIsAssocFrame, IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); -+ -+UINT_32 -+wfdFuncAppendAttriCoupledSinkInfo(IN P_ADAPTER_T prAdapter, -+ IN BOOLEAN fgIsAssocFrame, -+ IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); -+ -+UINT_32 -+wfdFuncAppendAttriExtCapability(IN P_ADAPTER_T prAdapter, -+ IN BOOLEAN fgIsAssocFrame, -+ IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); -+ -+UINT_32 wfdFuncCalculateAttriLenSessionInfo(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec); -+ -+UINT_32 -+wfdFuncAppendAttriSessionInfo(IN P_ADAPTER_T prAdapter, -+ IN BOOLEAN fgIsAssocFrame, -+ IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); -+ -+UINT_32 -+wfdFuncCalculateWfdIELenForProbeResp(IN P_ADAPTER_T prAdapter, -+ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec); -+ -+VOID wfdFuncGenerateWfdIEForProbeResp(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); -+ -+UINT_32 -+wfdFuncCalculateWfdIELenForAssocReq(IN P_ADAPTER_T prAdapter, -+ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec); -+ -+VOID wfdFuncGenerateWfdIEForAssocReq(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); -+ -+UINT_32 -+wfdFuncCalculateWfdIELenForAssocRsp(IN P_ADAPTER_T prAdapter, -+ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec); -+ -+VOID wfdFuncGenerateWfdIEForAssocRsp(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); -+ -+UINT_32 -+wfdFuncCalculateWfdIELenForBeacon(IN P_ADAPTER_T prAdapter, -+ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec); -+ -+VOID wfdFuncGenerateWfdIEForBeacon(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); -+ -+#endif -+ -+UINT_32 p2pFuncCalculateP2P_IE_NoA(IN P_ADAPTER_T prAdapter, IN UINT_32 ucBssIdx, IN P_STA_RECORD_T prStaRec); -+ -+VOID p2pFuncGenerateP2P_IE_NoA(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); -+ -+#endif -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_rlm.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_rlm.h -new file mode 100644 -index 000000000000..32bc14c10959 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_rlm.h -@@ -0,0 +1,74 @@ -+/* -+** Id: //Department/DaVinci/TRUNK/WiFi_P2P_Driver/include/mgmt/p2p_rlm.h#1 -+*/ -+ -+/*! \file "rlm.h" -+ \brief -+*/ -+ -+#ifndef _P2P_RLM_H -+#define _P2P_RLM_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+extern VOID rlmSyncOperationParams(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo); -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+VOID rlmBssInitForAP(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo); -+ -+BOOLEAN rlmUpdateBwByChListForAP(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo); -+ -+VOID rlmUpdateParamsForAP(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo, BOOLEAN fgUpdateBeacon); -+ -+VOID rlmFuncInitialChannelList(IN P_ADAPTER_T prAdapter); -+ -+VOID -+rlmFuncCommonChannelList(IN P_ADAPTER_T prAdapter, -+ IN P_CHANNEL_ENTRY_FIELD_T prChannelEntryII, IN UINT_8 ucChannelListSize); -+ -+UINT_8 rlmFuncFindOperatingClass(IN P_ADAPTER_T prAdapter, IN UINT_8 ucChannelNum); -+ -+BOOLEAN -+rlmFuncFindAvailableChannel(IN P_ADAPTER_T prAdapter, -+ IN UINT_8 ucCheckChnl, -+ IN PUINT_8 pucSuggestChannel, IN BOOLEAN fgIsSocialChannel, IN BOOLEAN fgIsDefaultChannel); -+ -+ENUM_CHNL_EXT_T rlmDecideScoForAP(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo); -+ -+#endif -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_rlm_obss.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_rlm_obss.h -new file mode 100644 -index 000000000000..5b6e756f48dd ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_rlm_obss.h -@@ -0,0 +1,64 @@ -+/* -+** Id: //Department/DaVinci/TRUNK/WiFi_P2P_Driver/include/mgmt/p2p_rlm_obss.h#1 -+*/ -+ -+/*! \file "rlm_obss.h" -+ \brief -+*/ -+ -+#ifndef _P2P_RLM_OBSS_H -+#define _P2P_RLM_OBSS_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+VOID rlmRspGenerateObssScanIE(P_ADAPTER_T prAdapter, P_MSDU_INFO_T prMsduInfo); -+ -+VOID rlmProcessPublicAction(P_ADAPTER_T prAdapter, P_SW_RFB_T prSwRfb); -+ -+VOID rlmProcessHtAction(P_ADAPTER_T prAdapter, P_SW_RFB_T prSwRfb); -+ -+VOID rlmHandleObssStatusEventPkt(P_ADAPTER_T prAdapter, P_EVENT_AP_OBSS_STATUS_T prObssStatus); -+ -+UINT_8 rlmObssChnlLevel(P_BSS_INFO_T prBssInfo, ENUM_BAND_T eBand, UINT_8 ucPriChannel, ENUM_CHNL_EXT_T eExtend); -+ -+VOID rlmObssScanExemptionRsp(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo, P_SW_RFB_T prSwRfb); -+ -+#endif -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_scan.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_scan.h -new file mode 100644 -index 000000000000..8db6aa5c31e0 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_scan.h -@@ -0,0 +1,81 @@ -+/* -+** Id: //Department/DaVinci/TRUNK/WiFi_P2P_Driver/include/mgmt/p2p_scan.h#1 -+*/ -+ -+/*! \file "scan.h" -+ \brief -+ -+*/ -+ -+#ifndef _P2P_SCAN_H -+#define _P2P_SCAN_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+WLAN_STATUS scanSendDeviceDiscoverEvent(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBssDesc, IN P_SW_RFB_T prSwRfb); -+ -+P_P2P_DEVICE_DESC_T -+scanSearchTargetP2pDesc(IN P_ADAPTER_T prAdapter, IN UINT_8 aucDeviceID[], IN PP_BSS_DESC_T pprBssDesc); -+ -+P_P2P_DEVICE_DESC_T -+scanFindP2pDeviceDesc(IN P_ADAPTER_T prAdapter, -+ IN P_BSS_DESC_T prBssDesc, -+ IN UINT_8 aucMacAddr[], IN BOOLEAN fgIsDeviceAddr, IN BOOLEAN fgAddIfNoFound); -+ -+P_P2P_DEVICE_DESC_T scanGetP2pDeviceDesc(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBssDesc); -+ -+VOID scnEventReturnChannel(IN P_ADAPTER_T prAdapter, IN UINT_8 ucScnSeqNum); -+ -+BOOLEAN scanUpdateP2pDeviceDesc(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBssDesc); -+ -+VOID -+scanP2pProcessBeaconAndProbeResp(IN P_ADAPTER_T prAdapter, -+ IN P_SW_RFB_T prSwRfb, -+ IN P_WLAN_STATUS prStatus, -+ IN P_BSS_DESC_T prBssDesc, IN P_WLAN_BEACON_FRAME_T prWlanBeaconFrame); -+ -+VOID scanRemoveAllP2pBssDesc(P_ADAPTER_T prAdapter); -+ -+VOID scanRemoveP2pBssDesc(P_ADAPTER_T prAdapter, P_BSS_DESC_T prBssDesc); -+ -+P_BSS_DESC_T -+scanP2pSearchDesc(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prP2pBssInfo, IN P_P2P_CONNECTION_REQ_INFO_T prConnReqInfo); -+ -+#endif -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_state.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_state.h -new file mode 100644 -index 000000000000..8f0c4c1564a8 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_state.h -@@ -0,0 +1,43 @@ -+#ifndef _P2P_STATE_H -+#define _P2P_STATE_H -+ -+BOOLEAN -+p2pStateInit_IDLE(IN P_ADAPTER_T prAdapter, -+ IN P_P2P_FSM_INFO_T prP2pFsmInfo, IN P_BSS_INFO_T prP2pBssInfo, OUT P_ENUM_P2P_STATE_T peNextState); -+ -+VOID p2pStateAbort_IDLE(IN P_ADAPTER_T prAdapter, IN P_P2P_FSM_INFO_T prP2pFsmInfo, IN ENUM_P2P_STATE_T eNextState); -+ -+VOID p2pStateInit_SCAN(IN P_ADAPTER_T prAdapter, IN P_P2P_FSM_INFO_T prP2pFsmInfo); -+ -+VOID p2pStateAbort_SCAN(IN P_ADAPTER_T prAdapter, IN P_P2P_FSM_INFO_T prP2pFsmInfo, IN ENUM_P2P_STATE_T eNextState); -+ -+VOID p2pStateInit_AP_CHANNEL_DETECT(IN P_ADAPTER_T prAdapter, IN P_P2P_FSM_INFO_T prP2pFsmInfo); -+ -+VOID -+p2pStateAbort_AP_CHANNEL_DETECT(IN P_ADAPTER_T prAdapter, -+ IN P_P2P_FSM_INFO_T prP2pFsmInfo, -+ IN P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo, IN ENUM_P2P_STATE_T eNextState); -+ -+VOID -+p2pStateInit_CHNL_ON_HAND(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prP2pBssInfo, IN P_P2P_FSM_INFO_T prP2pFsmInfo); -+ -+VOID -+p2pStateAbort_CHNL_ON_HAND(IN P_ADAPTER_T prAdapter, -+ IN P_P2P_FSM_INFO_T prP2pFsmInfo, -+ IN P_BSS_INFO_T prP2pBssInfo, IN ENUM_P2P_STATE_T eNextState); -+ -+VOID -+p2pStateAbort_REQING_CHANNEL(IN P_ADAPTER_T prAdapter, -+ IN P_P2P_FSM_INFO_T prP2pFsmInfo, IN ENUM_P2P_STATE_T eNextState); -+ -+VOID -+p2pStateInit_GC_JOIN(IN P_ADAPTER_T prAdapter, -+ IN P_P2P_FSM_INFO_T prP2pFsmInfo, -+ IN P_BSS_INFO_T prP2pBssInfo, IN P_P2P_JOIN_INFO_T prJoinInfo, IN P_BSS_DESC_T prBssDesc); -+ -+VOID -+p2pStateAbort_GC_JOIN(IN P_ADAPTER_T prAdapter, -+ IN P_P2P_FSM_INFO_T prP2pFsmInfo, -+ IN P_P2P_JOIN_INFO_T prJoinInfo, IN ENUM_P2P_STATE_T eNextState); -+ -+#endif -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/privacy.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/privacy.h -new file mode 100644 -index 000000000000..c80430ae4eb5 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/privacy.h -@@ -0,0 +1,230 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/mgmt/privacy.h#1 -+*/ -+ -+/*! \file privacy.h -+ \brief This file contains the function declaration for privacy.c. -+*/ -+ -+/* -+** Log: privacy.h -+ * -+ * 07 24 2010 wh.su -+ * -+ * .support the Wi-Fi RSN -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 21 2010 wh.su -+ * [WPD00003840][MT6620 5931] Security migration -+ * modify some code for concurrent network. -+ * -+ * 06 19 2010 wh.su -+ * [WPD00003840][MT6620 5931] Security migration -+ * consdier the concurrent network setting. -+ * -+ * 06 18 2010 wh.su -+ * [WPD00003840][MT6620 5931] Security migration -+ * migration the security related function from firmware. -+ * -+ * 03 01 2010 wh.su -+ * [BORA00000605][WIFISYS] Phase3 Integration -+ * Refine the variable and parameter for security. -+ * -+ * 02 25 2010 wh.su -+ * [BORA00000626][MT6620] Refine the remove key flow for WHQL testing -+ * For support the WHQL test, do the remove key code refine. -+ * -+ * Dec 10 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * change the cmd return type -+ * -+ * Dec 8 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * adding the function declaration for auth mode and encryption status setting from build connection command -+ * -+ * Dec 7 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * adding the function declaration for wapi -+ * -+ * Dec 7 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * adding the tx done callback handle function -+ * -+ * Dec 7 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * adding the function declaration for mac header privacy bit setting -+ * -+ * Dec 4 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * adding the structure for parsing the EAPoL frame -+ * -+ * Dec 3 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * adjust the class error function parameter -+ * -+ * Dec 1 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * adding some security function declaration -+ * -+ * Nov 19 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * adding the ap selection structure -+ * -+ * Nov 18 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * -+** -+*/ -+ -+#ifndef _PRIVACY_H -+#define _PRIVACY_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+#define MAX_KEY_NUM 4 -+#define WEP_40_LEN 5 -+#define WEP_104_LEN 13 -+#define LEGACY_KEY_MAX_LEN 16 -+#define CCMP_KEY_LEN 16 -+#define TKIP_KEY_LEN 32 -+#define MAX_KEY_LEN 32 -+#define MIC_RX_KEY_OFFSET 16 -+#define MIC_TX_KEY_OFFSET 24 -+#define MIC_KEY_LEN 8 -+ -+#define WEP_KEY_ID_FIELD BITS(0, 29) -+#define KEY_ID_FIELD BITS(0, 7) -+ -+#define IS_TRANSMIT_KEY BIT(31) -+#define IS_UNICAST_KEY BIT(30) -+#define IS_AUTHENTICATOR BIT(28) -+ -+#define CIPHER_SUITE_NONE 0 -+#define CIPHER_SUITE_WEP40 1 -+#define CIPHER_SUITE_TKIP 2 -+#define CIPHER_SUITE_TKIP_WO_MIC 3 -+#define CIPHER_SUITE_CCMP 4 -+#define CIPHER_SUITE_WEP104 5 -+#define CIPHER_SUITE_BIP 6 -+#define CIPHER_SUITE_WEP128 7 -+#define CIPHER_SUITE_WPI 8 -+ -+#define WPA_KEY_INFO_KEY_TYPE BIT(3) /* 1 = Pairwise, 0 = Group key */ -+#define WPA_KEY_INFO_MIC BIT(8) -+#define WPA_KEY_INFO_SECURE BIT(9) -+ -+#define MASK_2ND_EAPOL (WPA_KEY_INFO_KEY_TYPE | WPA_KEY_INFO_MIC) -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+typedef struct _IEEE_802_1X_HDR { -+ UINT_8 ucVersion; -+ UINT_8 ucType; -+ UINT_16 u2Length; -+ /* followed by length octets of data */ -+} IEEE_802_1X_HDR, *P_IEEE_802_1X_HDR; -+ -+typedef struct _EAPOL_KEY { -+ UINT_8 ucType; -+ /* Note: key_info, key_length, and key_data_length are unaligned */ -+ UINT_8 aucKeyInfo[2]; /* big endian */ -+ UINT_8 aucKeyLength[2]; /* big endian */ -+ UINT_8 aucReplayCounter[8]; -+ UINT_8 aucKeyNonce[16]; -+ UINT_8 aucKeyIv[16]; -+ UINT_8 aucKeyRsc[8]; -+ UINT_8 aucKeyId[8]; /* Reserved in IEEE 802.11i/RSN */ -+ UINT_8 aucKeyMic[16]; -+ UINT_8 aucKeyDataLength[2]; /* big endian */ -+ /* followed by key_data_length bytes of key_data */ -+} EAPOL_KEY, *P_EAPOL_KEY; -+ -+/* WPA2 PMKID candicate structure */ -+typedef struct _PMKID_CANDICATE_T { -+ UINT_8 aucBssid[MAC_ADDR_LEN]; -+ UINT_32 u4PreAuthFlags; -+} PMKID_CANDICATE_T, *P_PMKID_CANDICATE_T; -+ -+#if 0 -+/* WPA2 PMKID cache structure */ -+typedef struct _PMKID_ENTRY_T { -+ PARAM_BSSID_INFO_T rBssidInfo; -+ BOOLEAN fgPmkidExist; -+} PMKID_ENTRY_T, *P_PMKID_ENTRY_T; -+#endif -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+VOID secInit(IN P_ADAPTER_T prAdapter, IN UINT_8 ucNetTypeIdx); -+ -+VOID secSetPortBlocked(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta, IN BOOLEAN fgPort); -+ -+BOOLEAN secCheckClassError(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, IN P_STA_RECORD_T prStaRec); -+ -+BOOLEAN secTxPortControlCheck(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo, IN P_STA_RECORD_T prStaRec); -+ -+BOOLEAN secRxPortControlCheck(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSWRfb); -+ -+VOID secSetCipherSuite(IN P_ADAPTER_T prAdapter, IN UINT_32 u4CipherSuitesFlags); -+ -+BOOLEAN -+secProcessEAPOL(IN P_ADAPTER_T prAdapter, -+ IN P_MSDU_INFO_T prMsduInfo, -+ IN P_STA_RECORD_T prStaRec, IN PUINT_8 pucPayload, IN UINT_16 u2PayloadLen); -+ -+VOID -+secHandleTxDoneCallback(IN P_ADAPTER_T prAdapter, -+ IN P_MSDU_INFO_T pMsduInfo, IN P_STA_RECORD_T prStaRec, IN WLAN_STATUS rStatus); -+ -+BOOLEAN secIsProtectedFrame(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsdu, IN P_STA_RECORD_T prStaRec); -+ -+VOID secClearPmkid(IN P_ADAPTER_T prAdapter); -+ -+BOOLEAN secRsnKeyHandshakeEnabled(IN P_ADAPTER_T prAdapter); -+ -+BOOLEAN secTransmitKeyExist(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta); -+ -+BOOLEAN secEnabledInAis(IN P_ADAPTER_T prAdapter); -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif /* _PRIVACY_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rate.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rate.h -new file mode 100644 -index 000000000000..123dbebdacaf ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rate.h -@@ -0,0 +1,93 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/mgmt/rate.h#1 -+*/ -+ -+/*! \file rate.h -+ \brief This file contains the rate utility function of -+ IEEE 802.11 family for MediaTek 802.11 Wireless LAN Adapters. -+*/ -+ -+/* -+** Log: rate.h -+ * -+ * 09 03 2010 kevin.huang -+ * NULL -+ * Refine #include sequence and solve recursive/nested #include issue -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 10 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add buildable & linkable ais_fsm.c -+ * -+ * related reference are still waiting to be resolved -+ * -+*/ -+ -+#ifndef _RATE_H -+#define _RATE_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+/*----------------------------------------------------------------------------*/ -+/* Routines in rate.c */ -+/*----------------------------------------------------------------------------*/ -+VOID -+rateGetRateSetFromIEs(IN P_IE_SUPPORTED_RATE_T prIeSupportedRate, -+ IN P_IE_EXT_SUPPORTED_RATE_T prIeExtSupportedRate, -+ OUT PUINT_16 pu2OperationalRateSet, -+ OUT PUINT_16 pu2BSSBasicRateSet, OUT PBOOLEAN pfgIsUnknownBSSBasicRate); -+ -+VOID -+rateGetDataRatesFromRateSet(IN UINT_16 u2OperationalRateSet, -+ IN UINT_16 u2BSSBasicRateSet, OUT PUINT_8 pucDataRates, OUT PUINT_8 pucDataRatesLen); -+ -+BOOLEAN rateGetHighestRateIndexFromRateSet(IN UINT_16 u2RateSet, OUT PUINT_8 pucHighestRateIndex); -+ -+BOOLEAN rateGetLowestRateIndexFromRateSet(IN UINT_16 u2RateSet, OUT PUINT_8 pucLowestRateIndex); -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif /* _RATE_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rlm.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rlm.h -new file mode 100644 -index 000000000000..1af3841ecec2 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rlm.h -@@ -0,0 +1,396 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/mgmt/rlm.h#2 -+*/ -+ -+/*! \file "rlm.h" -+ \brief -+*/ -+ -+/* -+** Log: rlm.h -+ * -+ * 07 17 2012 yuche.tsai -+ * NULL -+ * Compile no error before trial run. -+ * -+ * 09 30 2011 cm.chang -+ * [WCXRP00001020] [MT6620 Wi-Fi][Driver] Handle secondary channel offset of AP in 5GHz band -+ * . -+ * -+ * 04 12 2011 cm.chang -+ * [WCXRP00000634] [MT6620 Wi-Fi][Driver][FW] 2nd BSS will not support 40MHz bandwidth for concurrency -+ * . -+ * -+ * 01 13 2011 cm.chang -+ * [WCXRP00000358] [MT6620 Wi-Fi][Driver] Provide concurrent information for each module -+ * Refine function when rcv a 20/40M public action frame -+ * -+ * 01 13 2011 cm.chang -+ * [WCXRP00000354] [MT6620 Wi-Fi][Driver][FW] Follow NVRAM bandwidth setting -+ * Use SCO of BSS_INFO to replace user-defined setting variables -+ * -+ * 01 12 2011 cm.chang -+ * [WCXRP00000354] [MT6620 Wi-Fi][Driver][FW] Follow NVRAM bandwidth setting -+ * User-defined bandwidth is for 2.4G and 5G individually -+ * -+ * 12 07 2010 cm.chang -+ * [WCXRP00000239] MT6620 Wi-Fi][Driver][FW] Merge concurrent branch back to maintrunk -+ * 1. BSSINFO include RLM parameter -+ * 2. free all sta records when network is disconnected -+ * -+ * 12 07 2010 cm.chang -+ * [WCXRP00000238] MT6620 Wi-Fi][Driver][FW] Support regulation domain setting from NVRAM and supplicant -+ * 1. Country code is from NVRAM or supplicant -+ * 2. Change band definition in CMD/EVENT. -+ * -+ * 10 18 2010 cm.chang -+ * [WCXRP00000114] [MT6620 Wi-Fi] [Driver] Fix compiling warning in Linux about RLM network index checking -+ * Enum member cannot be used as compiling option decision in Linux -+ * -+ * 09 10 2010 cm.chang -+ * NULL -+ * Always update Beacon content if FW sync OBSS info -+ * -+ * 08 31 2010 kevin.huang -+ * NULL -+ * Use LINK LIST operation to process SCAN result -+ * -+ * 08 24 2010 cm.chang -+ * NULL -+ * Support RLM initail channel of Ad-hoc, P2P and BOW -+ * -+ * 08 23 2010 chinghwa.yu -+ * NULL -+ * Update for BOW. -+ * -+ * 08 20 2010 cm.chang -+ * NULL -+ * Migrate RLM code to host from FW -+ * -+ * 08 16 2010 cp.wu -+ * NULL -+ * Replace CFG_SUPPORT_BOW by CFG_ENABLE_BT_OVER_WIFI. -+ * There is no CFG_SUPPORT_BOW in driver domain source. -+ * -+ * 08 02 2010 yuche.tsai -+ * NULL -+ * P2P Group Negotiation Code Check in. -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 07 08 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Check draft RLM code for HT cap -+ * -+ * 06 28 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * 1st draft code for RLM module -+ * -+ * 06 02 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Add RX HT GF compiling option -+ * -+ * 06 02 2010 chinghwa.yu -+ * [BORA00000563]Add WiFi CoEx BCM module -+ * Roll back to remove CFG_SUPPORT_BCM_TEST. -+ * -+ * 06 01 2010 chinghwa.yu -+ * [BORA00000563]Add WiFi CoEx BCM module -+ * Update BCM Test and RW configuration. -+ * -+ * 05 31 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Add some compiling options to control 11n functions -+ * -+ * 05 18 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Ad-hoc Beacon should not carry HT OP and OBSS IEs -+ * -+ * 05 17 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * MT6620 does not support L-SIG TXOP -+ * -+ * 05 05 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * First draft support for 20/40M bandwidth for AP mode -+ * -+ * 04 24 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * g_aprBssInfo[] depends on CFG_SUPPORT_P2P and CFG_SUPPORT_BOW -+ * -+ * 04 22 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * First draft code to support protection in AP mode -+ * -+ * 04 07 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Different invoking order for WTBL entry of associated AP -+ * -+ * 03 24 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Not carry HT cap when being associated with b/g only AP -+ * -+ * 03 03 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Move default value of HT capability to rlm.h -+ * -+ * 02 12 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Use bss info array for concurrent handle -+ * -+ * 01 22 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Support protection and bandwidth switch -+ * -+ * 01 08 2010 kevin.huang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * -+ * Modify the prototype of rlmRecAssocRspHtInfo() -+ * -+ * Dec 9 2009 mtk01104 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Add several function prototypes for HT operation -+ * -+ * Nov 18 2009 mtk01104 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * -+ * -+** -+*/ -+ -+#ifndef _RLM_H -+#define _RLM_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+#define ELEM_EXT_CAP_DEFAULT_VAL \ -+ (ELEM_EXT_CAP_20_40_COEXIST_SUPPORT /*| ELEM_EXT_CAP_PSMP_CAP*/) -+ -+#if CFG_SUPPORT_RX_STBC -+#define FIELD_HT_CAP_INFO_RX_STBC HT_CAP_INFO_RX_STBC_1_SS -+#else -+#define FIELD_HT_CAP_INFO_RX_STBC HT_CAP_INFO_RX_STBC_NO_SUPPORTED -+#endif -+ -+#if CFG_SUPPORT_RX_SGI -+#define FIELD_HT_CAP_INFO_SGI_20M HT_CAP_INFO_SHORT_GI_20M -+#define FIELD_HT_CAP_INFO_SGI_40M HT_CAP_INFO_SHORT_GI_40M -+#else -+#define FIELD_HT_CAP_INFO_SGI_20M 0 -+#define FIELD_HT_CAP_INFO_SGI_40M 0 -+#endif -+ -+#if CFG_SUPPORT_RX_HT_GF -+#define FIELD_HT_CAP_INFO_HT_GF HT_CAP_INFO_HT_GF -+#else -+#define FIELD_HT_CAP_INFO_HT_GF 0 -+#endif -+ -+#define HT_CAP_INFO_DEFAULT_VAL \ -+ (HT_CAP_INFO_SUP_CHNL_WIDTH | FIELD_HT_CAP_INFO_HT_GF | \ -+ FIELD_HT_CAP_INFO_SGI_20M | FIELD_HT_CAP_INFO_SGI_40M | \ -+ FIELD_HT_CAP_INFO_RX_STBC | HT_CAP_INFO_DSSS_CCK_IN_40M) -+ -+#define AMPDU_PARAM_DEFAULT_VAL \ -+ (AMPDU_PARAM_MAX_AMPDU_LEN_64K | AMPDU_PARAM_MSS_NO_RESTRICIT) -+ -+#define SUP_MCS_TX_DEFAULT_VAL \ -+ SUP_MCS_TX_SET_DEFINED /* TX defined and TX/RX equal (TBD) */ -+ -+#if CFG_SUPPORT_MFB -+#define FIELD_HT_EXT_CAP_MFB HT_EXT_CAP_MCS_FEEDBACK_BOTH -+#else -+#define FIELD_HT_EXT_CAP_MFB HT_EXT_CAP_MCS_FEEDBACK_NO_FB -+#endif -+ -+#if CFG_SUPPORT_RX_RDG -+#define FIELD_HT_EXT_CAP_RDR HT_EXT_CAP_RD_RESPONDER -+#else -+#define FIELD_HT_EXT_CAP_RDR 0 -+#endif -+ -+#if CFG_SUPPORT_MFB || CFG_SUPPORT_RX_RDG -+#define FIELD_HT_EXT_CAP_HTC HT_EXT_CAP_HTC_SUPPORT -+#else -+#define FIELD_HT_EXT_CAP_HTC 0 -+#endif -+ -+#define HT_EXT_CAP_DEFAULT_VAL \ -+ (HT_EXT_CAP_PCO | HT_EXT_CAP_PCO_TRANS_TIME_NONE | \ -+ FIELD_HT_EXT_CAP_MFB | FIELD_HT_EXT_CAP_HTC | \ -+ FIELD_HT_EXT_CAP_RDR) -+ -+#define TX_BEAMFORMING_CAP_DEFAULT_VAL 0 -+#define ASEL_CAP_DEFAULT_VAL 0 -+ -+/* Define bandwidth from user setting */ -+#define CONFIG_BW_20_40M 0 -+#define CONFIG_BW_20M 1 /* 20MHz only */ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/* It is used for RLM module to judge if specific network is valid -+ * Note: Ad-hoc mode of AIS is not included now. (TBD) -+ */ -+#define RLM_NET_PARAM_VALID(_prBssInfo) \ -+ (IS_BSS_ACTIVE(_prBssInfo) && \ -+ ((_prBssInfo)->eConnectionState == PARAM_MEDIA_STATE_CONNECTED || \ -+ (_prBssInfo)->eCurrentOPMode == OP_MODE_ACCESS_POINT || \ -+ (_prBssInfo)->eCurrentOPMode == OP_MODE_IBSS || \ -+ RLM_NET_IS_BOW(_prBssInfo)) \ -+ ) -+ -+#define RLM_NET_IS_11N(_prBssInfo) \ -+ ((_prBssInfo)->ucPhyTypeSet & PHY_TYPE_SET_802_11N) -+#define RLM_NET_IS_11GN(_prBssInfo) \ -+ ((_prBssInfo)->ucPhyTypeSet & PHY_TYPE_SET_802_11GN) -+ -+/* This macro is used to sweep all 3 networks */ -+#define RLM_NET_FOR_EACH(_ucNetIdx) \ -+ for ((_ucNetIdx) = 0; \ -+ (_ucNetIdx) < NETWORK_TYPE_INDEX_NUM; \ -+ (_ucNetIdx)++) -+ -+/* This macro is used to sweep all networks excluding BOW */ -+#if CFG_ENABLE_BT_OVER_WIFI -+ /* Note: value of enum NETWORK_TYPE_BOW_INDEX is validated in -+ * rlmStuctureCheck(). -+ */ -+#define RLM_NET_FOR_EACH_NO_BOW(_ucNetIdx) \ -+ for ((_ucNetIdx) = 0; \ -+ (_ucNetIdx) < NETWORK_TYPE_BOW_INDEX; \ -+ (_ucNetIdx)++) -+ -+#define RLM_NET_IS_BOW(_prBssInfo) \ -+ ((_prBssInfo)->ucNetTypeIndex == NETWORK_TYPE_BOW_INDEX) -+ -+#else -+#define RLM_NET_FOR_EACH_NO_BOW(_ucNetIdx) RLM_NET_FOR_EACH(_ucNetIdx) -+#define RLM_NET_IS_BOW(_prBssInfo) (FALSE) -+ -+#endif /* end of CFG_ENABLE_BT_OVER_WIFI */ -+ -+/* The bandwidth modes are not used anymore. They represent if AP -+ * can use 20/40 bandwidth, not all modes. (20110411) -+ */ -+#define RLM_AP_IS_BW_40_ALLOWED(_prAdapter, _prBssInfo) \ -+ (((_prBssInfo)->eBand == BAND_2G4 && \ -+ (_prAdapter)->rWifiVar.rConnSettings.uc2G4BandwidthMode \ -+ == CONFIG_BW_20_40M) || \ -+ ((_prBssInfo)->eBand == BAND_5G && \ -+ (_prAdapter)->rWifiVar.rConnSettings.uc5GBandwidthMode \ -+ == CONFIG_BW_20_40M)) -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+VOID rlmFsmEventInit(P_ADAPTER_T prAdapter); -+ -+VOID rlmFsmEventUninit(P_ADAPTER_T prAdapter); -+ -+VOID rlmReqGenerateHtCapIE(P_ADAPTER_T prAdapter, P_MSDU_INFO_T prMsduInfo); -+ -+VOID rlmReqGenerateExtCapIE(P_ADAPTER_T prAdapter, P_MSDU_INFO_T prMsduInfo); -+ -+VOID rlmRspGenerateHtCapIE(P_ADAPTER_T prAdapter, P_MSDU_INFO_T prMsduInfo); -+ -+VOID rlmRspGenerateExtCapIE(P_ADAPTER_T prAdapter, P_MSDU_INFO_T prMsduInfo); -+ -+VOID rlmRspGenerateHtOpIE(P_ADAPTER_T prAdapter, P_MSDU_INFO_T prMsduInfo); -+ -+VOID rlmRspGenerateErpIE(P_ADAPTER_T prAdapter, P_MSDU_INFO_T prMsduInfo); -+ -+VOID rlmProcessBcn(P_ADAPTER_T prAdapter, P_SW_RFB_T prSwRfb, PUINT_8 pucIE, UINT_16 u2IELength); -+ -+VOID rlmProcessAssocRsp(P_ADAPTER_T prAdapter, P_SW_RFB_T prSwRfb, PUINT_8 pucIE, UINT_16 u2IELength); -+ -+VOID rlmFillSyncCmdParam(P_CMD_SET_BSS_RLM_PARAM_T prCmdBody, P_BSS_INFO_T prBssInfo); -+ -+VOID rlmSyncOperationParams(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo); -+ -+VOID rlmBssInitForAPandIbss(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo); -+ -+VOID rlmProcessAssocReq(P_ADAPTER_T prAdapter, P_SW_RFB_T prSwRfb, PUINT_8 pucIE, UINT_16 u2IELength); -+ -+VOID rlmBssAborted(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo); -+ -+UINT32 -+rlmFillHtCapIEByParams(BOOLEAN fg40mAllowed, -+ BOOLEAN fgShortGIDisabled, -+ UINT_8 u8SupportRxSgi20, -+ UINT_8 u8SupportRxSgi40, -+ UINT_8 u8SupportRxGf, UINT_8 u8SupportRxSTBC, ENUM_OP_MODE_T eCurrentOPMode, UINT_8 *pOutBuf); -+ -+UINT32 rlmFillHtOpIeBody(P_BSS_INFO_T prBssInfo, UINT_8 *pFme); -+ -+#if CFG_SUPPORT_DFS /* Add by Enlai */ -+VOID rlmProcessSpecMgtAction(P_ADAPTER_T prAdapter, P_SW_RFB_T prSwRfb); -+ -+VOID rlmProcessChannelSwitchIE(P_ADAPTER_T prAdapter, P_IE_CHANNEL_SWITCH_T prChannelSwitchIE); -+#endif -+ -+VOID -+rlmTxRateEnhanceConfig( -+ P_ADAPTER_T prAdapter -+ ); -+ -+VOID -+rlmCmd( -+ P_GLUE_INFO_T prGlueInfo, -+ UINT_8 *prInBuf, -+ UINT_32 u4InBufLen -+ ); -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#ifndef _lint -+static inline VOID rlmDataTypeCheck(VOID) -+{ -+#if CFG_ENABLE_BT_OVER_WIFI -+ DATA_STRUCT_INSPECTING_ASSERT(NETWORK_TYPE_AIS_INDEX < NETWORK_TYPE_BOW_INDEX); -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ DATA_STRUCT_INSPECTING_ASSERT(NETWORK_TYPE_P2P_INDEX < NETWORK_TYPE_BOW_INDEX); -+#endif -+#endif -+ -+} -+#endif /* _lint */ -+ -+#endif /* _RLM_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rlm_domain.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rlm_domain.h -new file mode 100644 -index 000000000000..65e907041a28 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rlm_domain.h -@@ -0,0 +1,557 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/mgmt/rlm_domain.h#1 -+*/ -+ -+/*! \file "rlm_domain.h" -+ \brief -+*/ -+ -+/* -+** Log: rlm_domain.h -+ * -+ * 09 29 2011 cm.chang -+ * NULL -+ * Change the function prototype of rlmDomainGetChnlList() -+ * -+ * 09 08 2011 cm.chang -+ * [WCXRP00000969] [MT6620 Wi-Fi][Driver][FW] Channel list for 5G band based on country code -+ * Use new fields ucChannelListMap and ucChannelListIndex in NVRAM -+ * -+ * 08 31 2011 cm.chang -+ * [WCXRP00000969] [MT6620 Wi-Fi][Driver][FW] Channel list for 5G band based on country code -+ * . -+ * -+ * 06 01 2011 cm.chang -+ * [WCXRP00000756] [MT6620 Wi-Fi][Driver] 1. AIS follow channel of BOW 2. Provide legal channel function -+ * Provide legal channel function based on domain -+ * -+ * 12 07 2010 cm.chang -+ * [WCXRP00000238] MT6620 Wi-Fi][Driver][FW] Support regulation domain setting from NVRAM and supplicant -+ * 1. Country code is from NVRAM or supplicant -+ * 2. Change band definition in CMD/EVENT. -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 28 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * 1st draft code for RLM module -+ * -+ * 02 23 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Add support scan channel 1~14 and update scan result's frequency infou1rwduu`wvpghlqg|n`slk+mpdkb -+ * -+ * 01 13 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Provide query function about full channel list. -+ * -+ * Dec 1 2009 mtk01104 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Declare public rDomainInfo -+ * -+** -+*/ -+ -+#ifndef _RLM_DOMAIN_H -+#define _RLM_DOMAIN_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+#define MAX_SUBBAND_NUM 6 -+#define MAX_SUBBAND_NUM_5G 8 -+ -+#define COUNTRY_CODE_NULL ((UINT_16)0x0) -+ -+/* ISO/IEC 3166-1 two-character country codes */ -+ -+#define COUNTRY_CODE_AD (((UINT_16) 'A' << 8) | (UINT_16) 'D') /* Andorra */ -+#define COUNTRY_CODE_AE (((UINT_16) 'A' << 8) | (UINT_16) 'E') /* UAE */ -+#define COUNTRY_CODE_AF (((UINT_16) 'A' << 8) | (UINT_16) 'F') /* Afghanistan */ -+#define COUNTRY_CODE_AG (((UINT_16) 'A' << 8) | (UINT_16) 'G') /* Antigua & Barbuda */ -+#define COUNTRY_CODE_AI (((UINT_16) 'A' << 8) | (UINT_16) 'I') /* Anguilla */ -+#define COUNTRY_CODE_AL (((UINT_16) 'A' << 8) | (UINT_16) 'L') /* Albania */ -+#define COUNTRY_CODE_AM (((UINT_16) 'A' << 8) | (UINT_16) 'M') /* Armenia */ -+#define COUNTRY_CODE_AN (((UINT_16) 'A' << 8) | (UINT_16) 'N') /* Netherlands Antilles */ -+#define COUNTRY_CODE_AO (((UINT_16) 'A' << 8) | (UINT_16) 'O') /* Angola */ -+#define COUNTRY_CODE_AR (((UINT_16) 'A' << 8) | (UINT_16) 'R') /* Argentina */ -+#define COUNTRY_CODE_AS (((UINT_16) 'A' << 8) | (UINT_16) 'S') /* American Samoa (USA) */ -+#define COUNTRY_CODE_AT (((UINT_16) 'A' << 8) | (UINT_16) 'T') /* Austria */ -+#define COUNTRY_CODE_AU (((UINT_16) 'A' << 8) | (UINT_16) 'U') /* Australia */ -+#define COUNTRY_CODE_AW (((UINT_16) 'A' << 8) | (UINT_16) 'W') /* Aruba */ -+#define COUNTRY_CODE_AZ (((UINT_16) 'A' << 8) | (UINT_16) 'Z') /* Azerbaijan */ -+#define COUNTRY_CODE_BA (((UINT_16) 'B' << 8) | (UINT_16) 'A') /* Bosnia and Herzegovina */ -+#define COUNTRY_CODE_BB (((UINT_16) 'B' << 8) | (UINT_16) 'B') /* Barbados */ -+#define COUNTRY_CODE_BD (((UINT_16) 'B' << 8) | (UINT_16) 'D') /* Bangladesh */ -+#define COUNTRY_CODE_BE (((UINT_16) 'B' << 8) | (UINT_16) 'E') /* Belgium */ -+#define COUNTRY_CODE_BF (((UINT_16) 'B' << 8) | (UINT_16) 'F') /* Burkina Faso */ -+#define COUNTRY_CODE_BG (((UINT_16) 'B' << 8) | (UINT_16) 'G') /* Bulgaria */ -+#define COUNTRY_CODE_BH (((UINT_16) 'B' << 8) | (UINT_16) 'H') /* Bahrain */ -+#define COUNTRY_CODE_BI (((UINT_16) 'B' << 8) | (UINT_16) 'I') /* Burundi */ -+#define COUNTRY_CODE_BJ (((UINT_16) 'B' << 8) | (UINT_16) 'J') /* Benin */ -+#define COUNTRY_CODE_BM (((UINT_16) 'B' << 8) | (UINT_16) 'M') /* Bermuda */ -+#define COUNTRY_CODE_BN (((UINT_16) 'B' << 8) | (UINT_16) 'N') /* Brunei */ -+#define COUNTRY_CODE_BO (((UINT_16) 'B' << 8) | (UINT_16) 'O') /* Bolivia */ -+#define COUNTRY_CODE_BR (((UINT_16) 'B' << 8) | (UINT_16) 'R') /* Brazil */ -+#define COUNTRY_CODE_BS (((UINT_16) 'B' << 8) | (UINT_16) 'S') /* Bahamas */ -+#define COUNTRY_CODE_BT (((UINT_16) 'B' << 8) | (UINT_16) 'T') /* Bhutan */ -+#define COUNTRY_CODE_BW (((UINT_16) 'B' << 8) | (UINT_16) 'W') /* Botswana */ -+#define COUNTRY_CODE_BY (((UINT_16) 'B' << 8) | (UINT_16) 'Y') /* Belarus */ -+#define COUNTRY_CODE_BZ (((UINT_16) 'B' << 8) | (UINT_16) 'Z') /* Belize */ -+#define COUNTRY_CODE_CA (((UINT_16) 'C' << 8) | (UINT_16) 'A') /* Canada */ -+#define COUNTRY_CODE_CD (((UINT_16) 'C' << 8) | (UINT_16) 'D') /* Congo. Democratic Republic of the */ -+#define COUNTRY_CODE_CF (((UINT_16) 'C' << 8) | (UINT_16) 'F') /* Central African Republic */ -+#define COUNTRY_CODE_CG (((UINT_16) 'C' << 8) | (UINT_16) 'G') /* Congo. Republic of the */ -+#define COUNTRY_CODE_CH (((UINT_16) 'C' << 8) | (UINT_16) 'H') /* Switzerland */ -+#define COUNTRY_CODE_CI (((UINT_16) 'C' << 8) | (UINT_16) 'I') /* Cote d'lvoire */ -+#define COUNTRY_CODE_CK (((UINT_16) 'C' << 8) | (UINT_16) 'K') /* Cook Island */ -+#define COUNTRY_CODE_CL (((UINT_16) 'C' << 8) | (UINT_16) 'L') /* Chile */ -+#define COUNTRY_CODE_CM (((UINT_16) 'C' << 8) | (UINT_16) 'M') /* Cameroon */ -+#define COUNTRY_CODE_CN (((UINT_16) 'C' << 8) | (UINT_16) 'N') /* China */ -+#define COUNTRY_CODE_CO (((UINT_16) 'C' << 8) | (UINT_16) 'O') /* Columbia */ -+#define COUNTRY_CODE_CR (((UINT_16) 'C' << 8) | (UINT_16) 'R') /* Costa Rica */ -+#define COUNTRY_CODE_CU (((UINT_16) 'C' << 8) | (UINT_16) 'U') /* Cuba */ -+#define COUNTRY_CODE_CV (((UINT_16) 'C' << 8) | (UINT_16) 'V') /* Cape Verde */ -+#define COUNTRY_CODE_CX (((UINT_16) 'C' << 8) | (UINT_16) 'X') /* "Christmas Island(Australia) */ -+#define COUNTRY_CODE_CY (((UINT_16) 'C' << 8) | (UINT_16) 'Y') /* Cyprus */ -+#define COUNTRY_CODE_CZ (((UINT_16) 'C' << 8) | (UINT_16) 'Z') /* Czech */ -+#define COUNTRY_CODE_DE (((UINT_16) 'D' << 8) | (UINT_16) 'E') /* Germany */ -+#define COUNTRY_CODE_DJ (((UINT_16) 'D' << 8) | (UINT_16) 'J') /* Djibouti */ -+#define COUNTRY_CODE_DK (((UINT_16) 'D' << 8) | (UINT_16) 'K') /* Denmark */ -+#define COUNTRY_CODE_DM (((UINT_16) 'D' << 8) | (UINT_16) 'M') /* Dominica */ -+#define COUNTRY_CODE_DO (((UINT_16) 'D' << 8) | (UINT_16) 'O') /* Dominican Republic */ -+#define COUNTRY_CODE_DZ (((UINT_16) 'D' << 8) | (UINT_16) 'Z') /* Algeria */ -+#define COUNTRY_CODE_EC (((UINT_16) 'E' << 8) | (UINT_16) 'C') /* Ecuador */ -+#define COUNTRY_CODE_EE (((UINT_16) 'E' << 8) | (UINT_16) 'E') /* Estonia */ -+#define COUNTRY_CODE_EG (((UINT_16) 'E' << 8) | (UINT_16) 'G') /* Egypt */ -+#define COUNTRY_CODE_EH (((UINT_16) 'E' << 8) | (UINT_16) 'H') /* Western Sahara (Morocco) */ -+#define COUNTRY_CODE_ER (((UINT_16) 'E' << 8) | (UINT_16) 'R') /* Eritrea */ -+#define COUNTRY_CODE_ES (((UINT_16) 'E' << 8) | (UINT_16) 'S') /* Spain */ -+#define COUNTRY_CODE_ET (((UINT_16) 'E' << 8) | (UINT_16) 'T') /* Ethiopia */ -+#define COUNTRY_CODE_EU (((UINT_16) 'E' << 8) | (UINT_16) 'U') /* Europe */ -+#define COUNTRY_CODE_FI (((UINT_16) 'F' << 8) | (UINT_16) 'I') /* Finland */ -+#define COUNTRY_CODE_FJ (((UINT_16) 'F' << 8) | (UINT_16) 'J') /* Fiji */ -+#define COUNTRY_CODE_FK (((UINT_16) 'F' << 8) | (UINT_16) 'K') /* Falkland Island */ -+#define COUNTRY_CODE_FM (((UINT_16) 'F' << 8) | (UINT_16) 'M') /* Micronesia */ -+#define COUNTRY_CODE_FO (((UINT_16) 'F' << 8) | (UINT_16) 'O') /* Faroe Island */ -+#define COUNTRY_CODE_FR (((UINT_16) 'F' << 8) | (UINT_16) 'R') /* France */ -+#define COUNTRY_CODE_FR (((UINT_16) 'F' << 8) | (UINT_16) 'R') /* Wallis and Futuna (France) */ -+#define COUNTRY_CODE_GA (((UINT_16) 'G' << 8) | (UINT_16) 'A') /* Gabon */ -+#define COUNTRY_CODE_GB (((UINT_16) 'G' << 8) | (UINT_16) 'B') /* United Kingdom */ -+#define COUNTRY_CODE_GD (((UINT_16) 'G' << 8) | (UINT_16) 'D') /* Grenada */ -+#define COUNTRY_CODE_GE (((UINT_16) 'G' << 8) | (UINT_16) 'E') /* Georgia */ -+#define COUNTRY_CODE_GF (((UINT_16) 'G' << 8) | (UINT_16) 'F') /* French Guiana */ -+#define COUNTRY_CODE_GG (((UINT_16) 'G' << 8) | (UINT_16) 'G') /* Guernsey */ -+#define COUNTRY_CODE_GH (((UINT_16) 'G' << 8) | (UINT_16) 'H') /* Ghana */ -+#define COUNTRY_CODE_GI (((UINT_16) 'G' << 8) | (UINT_16) 'I') /* Gibraltar */ -+#define COUNTRY_CODE_GM (((UINT_16) 'G' << 8) | (UINT_16) 'M') /* Gambia */ -+#define COUNTRY_CODE_GN (((UINT_16) 'G' << 8) | (UINT_16) 'N') /* Guinea */ -+#define COUNTRY_CODE_GP (((UINT_16) 'G' << 8) | (UINT_16) 'P') /* Guadeloupe */ -+#define COUNTRY_CODE_GQ (((UINT_16) 'G' << 8) | (UINT_16) 'Q') /* Equatorial Guinea */ -+#define COUNTRY_CODE_GR (((UINT_16) 'G' << 8) | (UINT_16) 'R') /* Greece */ -+#define COUNTRY_CODE_GT (((UINT_16) 'G' << 8) | (UINT_16) 'T') /* Guatemala */ -+#define COUNTRY_CODE_GU (((UINT_16) 'G' << 8) | (UINT_16) 'U') /* Guam */ -+#define COUNTRY_CODE_GW (((UINT_16) 'G' << 8) | (UINT_16) 'W') /* Guinea-Bissau */ -+#define COUNTRY_CODE_GY (((UINT_16) 'G' << 8) | (UINT_16) 'Y') /* Guyana */ -+#define COUNTRY_CODE_HK (((UINT_16) 'H' << 8) | (UINT_16) 'K') /* Hong Kong */ -+#define COUNTRY_CODE_HN (((UINT_16) 'H' << 8) | (UINT_16) 'N') /* Honduras */ -+#define COUNTRY_CODE_HR (((UINT_16) 'H' << 8) | (UINT_16) 'R') /* Croatia */ -+#define COUNTRY_CODE_HT (((UINT_16) 'H' << 8) | (UINT_16) 'T') /* Haiti */ -+#define COUNTRY_CODE_HU (((UINT_16) 'H' << 8) | (UINT_16) 'U') /* Hungary */ -+#define COUNTRY_CODE_ID (((UINT_16) 'I' << 8) | (UINT_16) 'D') /* Indonesia */ -+#define COUNTRY_CODE_IE (((UINT_16) 'I' << 8) | (UINT_16) 'E') /* Ireland */ -+#define COUNTRY_CODE_IL (((UINT_16) 'I' << 8) | (UINT_16) 'L') /* Israel */ -+#define COUNTRY_CODE_IM (((UINT_16) 'I' << 8) | (UINT_16) 'M') /* Isle of Man */ -+#define COUNTRY_CODE_IN (((UINT_16) 'I' << 8) | (UINT_16) 'N') /* India */ -+#define COUNTRY_CODE_IQ (((UINT_16) 'I' << 8) | (UINT_16) 'Q') /* Iraq */ -+#define COUNTRY_CODE_IR (((UINT_16) 'I' << 8) | (UINT_16) 'R') /* Iran */ -+#define COUNTRY_CODE_IS (((UINT_16) 'I' << 8) | (UINT_16) 'S') /* Iceland */ -+#define COUNTRY_CODE_IT (((UINT_16) 'I' << 8) | (UINT_16) 'T') /* Italy */ -+#define COUNTRY_CODE_JE (((UINT_16) 'J' << 8) | (UINT_16) 'E') /* Jersey */ -+#define COUNTRY_CODE_JM (((UINT_16) 'J' << 8) | (UINT_16) 'M') /* Jameica */ -+#define COUNTRY_CODE_JO (((UINT_16) 'J' << 8) | (UINT_16) 'O') /* Jordan */ -+#define COUNTRY_CODE_JP (((UINT_16) 'J' << 8) | (UINT_16) 'P') /* Japan */ -+#define COUNTRY_CODE_KE (((UINT_16) 'K' << 8) | (UINT_16) 'E') /* Kenya */ -+#define COUNTRY_CODE_KG (((UINT_16) 'K' << 8) | (UINT_16) 'G') /* Kyrgyzstan */ -+#define COUNTRY_CODE_KH (((UINT_16) 'K' << 8) | (UINT_16) 'H') /* Cambodia */ -+#define COUNTRY_CODE_KI (((UINT_16) 'K' << 8) | (UINT_16) 'I') /* Kiribati */ -+#define COUNTRY_CODE_KM (((UINT_16) 'K' << 8) | (UINT_16) 'M') /* Comoros */ -+#define COUNTRY_CODE_KN (((UINT_16) 'K' << 8) | (UINT_16) 'N') /* Saint Kitts and Nevis */ -+#define COUNTRY_CODE_KP (((UINT_16) 'K' << 8) | (UINT_16) 'P') /* North Korea */ -+#define COUNTRY_CODE_KR (((UINT_16) 'K' << 8) | (UINT_16) 'R') /* South Korea */ -+#define COUNTRY_CODE_KW (((UINT_16) 'K' << 8) | (UINT_16) 'W') /* Kuwait */ -+#define COUNTRY_CODE_KY (((UINT_16) 'K' << 8) | (UINT_16) 'Y') /* Cayman Islands */ -+#define COUNTRY_CODE_KZ (((UINT_16) 'K' << 8) | (UINT_16) 'Z') /* Kazakhstan */ -+#define COUNTRY_CODE_LA (((UINT_16) 'L' << 8) | (UINT_16) 'A') /* Laos */ -+#define COUNTRY_CODE_LB (((UINT_16) 'L' << 8) | (UINT_16) 'B') /* Lebanon */ -+#define COUNTRY_CODE_LC (((UINT_16) 'L' << 8) | (UINT_16) 'C') /* Saint Lucia */ -+#define COUNTRY_CODE_LI (((UINT_16) 'L' << 8) | (UINT_16) 'I') /* Liechtenstein */ -+#define COUNTRY_CODE_LK (((UINT_16) 'L' << 8) | (UINT_16) 'K') /* Sri Lanka */ -+#define COUNTRY_CODE_LR (((UINT_16) 'L' << 8) | (UINT_16) 'R') /* Liberia */ -+#define COUNTRY_CODE_LS (((UINT_16) 'L' << 8) | (UINT_16) 'S') /* Lesotho */ -+#define COUNTRY_CODE_LT (((UINT_16) 'L' << 8) | (UINT_16) 'T') /* Lithuania */ -+#define COUNTRY_CODE_LU (((UINT_16) 'L' << 8) | (UINT_16) 'U') /* Luxemburg */ -+#define COUNTRY_CODE_LV (((UINT_16) 'L' << 8) | (UINT_16) 'V') /* Latvia */ -+#define COUNTRY_CODE_LY (((UINT_16) 'L' << 8) | (UINT_16) 'Y') /* Libya */ -+#define COUNTRY_CODE_MA (((UINT_16) 'M' << 8) | (UINT_16) 'A') /* Morocco */ -+#define COUNTRY_CODE_MC (((UINT_16) 'M' << 8) | (UINT_16) 'C') /* Monaco */ -+#define COUNTRY_CODE_MD (((UINT_16) 'M' << 8) | (UINT_16) 'D') /* Moldova */ -+#define COUNTRY_CODE_ME (((UINT_16) 'M' << 8) | (UINT_16) 'E') /* Montenegro */ -+#define COUNTRY_CODE_MF (((UINT_16) 'M' << 8) | (UINT_16) 'F') /* Saint Martin / Sint Marteen -+ (Added on window's list) */ -+#define COUNTRY_CODE_MG (((UINT_16) 'M' << 8) | (UINT_16) 'G') /* Madagascar */ -+#define COUNTRY_CODE_MH (((UINT_16) 'M' << 8) | (UINT_16) 'H') /* Marshall Islands */ -+#define COUNTRY_CODE_MK (((UINT_16) 'M' << 8) | (UINT_16) 'K') /* Macedonia */ -+#define COUNTRY_CODE_ML (((UINT_16) 'M' << 8) | (UINT_16) 'L') /* Mali */ -+#define COUNTRY_CODE_MM (((UINT_16) 'M' << 8) | (UINT_16) 'M') /* Myanmar */ -+#define COUNTRY_CODE_MN (((UINT_16) 'M' << 8) | (UINT_16) 'N') /* Mongolia */ -+#define COUNTRY_CODE_MO (((UINT_16) 'M' << 8) | (UINT_16) 'O') /* Macao */ -+#define COUNTRY_CODE_MP (((UINT_16) 'M' << 8) | (UINT_16) 'P') /* Northern Mariana Islands (Rota Island. -+ Saipan and Tinian Island) */ -+#define COUNTRY_CODE_MQ (((UINT_16) 'M' << 8) | (UINT_16) 'Q') /* Martinique (France) */ -+#define COUNTRY_CODE_MR (((UINT_16) 'M' << 8) | (UINT_16) 'R') /* Mauritania */ -+#define COUNTRY_CODE_MS (((UINT_16) 'M' << 8) | (UINT_16) 'S') /* Montserrat (UK) */ -+#define COUNTRY_CODE_MT (((UINT_16) 'M' << 8) | (UINT_16) 'T') /* Malta */ -+#define COUNTRY_CODE_MU (((UINT_16) 'M' << 8) | (UINT_16) 'U') /* Mauritius */ -+#define COUNTRY_CODE_MV (((UINT_16) 'M' << 8) | (UINT_16) 'V') /* Maldives */ -+#define COUNTRY_CODE_MW (((UINT_16) 'M' << 8) | (UINT_16) 'W') /* Malawi */ -+#define COUNTRY_CODE_MX (((UINT_16) 'M' << 8) | (UINT_16) 'X') /* Mexico */ -+#define COUNTRY_CODE_MY (((UINT_16) 'M' << 8) | (UINT_16) 'Y') /* Malaysia */ -+#define COUNTRY_CODE_MZ (((UINT_16) 'M' << 8) | (UINT_16) 'Z') /* Mozambique */ -+#define COUNTRY_CODE_NA (((UINT_16) 'N' << 8) | (UINT_16) 'A') /* Namibia */ -+#define COUNTRY_CODE_NC (((UINT_16) 'N' << 8) | (UINT_16) 'C') /* New Caledonia */ -+#define COUNTRY_CODE_NE (((UINT_16) 'N' << 8) | (UINT_16) 'E') /* Niger */ -+#define COUNTRY_CODE_NF (((UINT_16) 'N' << 8) | (UINT_16) 'F') /* Norfolk Island */ -+#define COUNTRY_CODE_NG (((UINT_16) 'N' << 8) | (UINT_16) 'G') /* Nigeria */ -+#define COUNTRY_CODE_NI (((UINT_16) 'N' << 8) | (UINT_16) 'I') /* Nicaragua */ -+#define COUNTRY_CODE_NL (((UINT_16) 'N' << 8) | (UINT_16) 'L') /* Netherlands */ -+#define COUNTRY_CODE_NO (((UINT_16) 'N' << 8) | (UINT_16) 'O') /* Norway */ -+#define COUNTRY_CODE_NP (((UINT_16) 'N' << 8) | (UINT_16) 'P') /* Nepal */ -+#define COUNTRY_CODE_NR (((UINT_16) 'N' << 8) | (UINT_16) 'R') /* Nauru */ -+#define COUNTRY_CODE_NU (((UINT_16) 'N' << 8) | (UINT_16) 'U') /* Niue */ -+#define COUNTRY_CODE_NZ (((UINT_16) 'N' << 8) | (UINT_16) 'Z') /* New Zealand */ -+#define COUNTRY_CODE_OM (((UINT_16) 'O' << 8) | (UINT_16) 'M') /* Oman */ -+#define COUNTRY_CODE_PA (((UINT_16) 'P' << 8) | (UINT_16) 'A') /* Panama */ -+#define COUNTRY_CODE_PE (((UINT_16) 'P' << 8) | (UINT_16) 'E') /* Peru */ -+#define COUNTRY_CODE_PF (((UINT_16) 'P' << 8) | (UINT_16) 'F') /* "French Polynesia */ -+#define COUNTRY_CODE_PG (((UINT_16) 'P' << 8) | (UINT_16) 'G') /* Papua New Guinea */ -+#define COUNTRY_CODE_PH (((UINT_16) 'P' << 8) | (UINT_16) 'H') /* Philippines */ -+#define COUNTRY_CODE_PK (((UINT_16) 'P' << 8) | (UINT_16) 'K') /* Pakistan */ -+#define COUNTRY_CODE_PL (((UINT_16) 'P' << 8) | (UINT_16) 'L') /* Poland */ -+#define COUNTRY_CODE_PM (((UINT_16) 'P' << 8) | (UINT_16) 'M') /* Saint Pierre and Miquelon */ -+#define COUNTRY_CODE_PN (((UINT_16) 'P' << 8) | (UINT_16) 'N') /* Pitcairn Islands */ -+#define COUNTRY_CODE_PR (((UINT_16) 'P' << 8) | (UINT_16) 'R') /* Puerto Rico (USA) */ -+#define COUNTRY_CODE_PS (((UINT_16) 'P' << 8) | (UINT_16) 'S') /* Palestinian Authority */ -+#define COUNTRY_CODE_PT (((UINT_16) 'P' << 8) | (UINT_16) 'T') /* Portugal */ -+#define COUNTRY_CODE_PW (((UINT_16) 'P' << 8) | (UINT_16) 'W') /* Palau */ -+#define COUNTRY_CODE_PY (((UINT_16) 'P' << 8) | (UINT_16) 'Y') /* Paraguay */ -+#define COUNTRY_CODE_QA (((UINT_16) 'Q' << 8) | (UINT_16) 'A') /* Qatar */ -+#define COUNTRY_CODE_RE (((UINT_16) 'R' << 8) | (UINT_16) 'E') /* Reunion (France) */ -+#define COUNTRY_CODE_RKS (((UINT_16) 'R' << 8) | (UINT_16) 'K') /* Kosvo (Added on window's list) */ -+#define COUNTRY_CODE_RO (((UINT_16) 'R' << 8) | (UINT_16) 'O') /* Romania */ -+#define COUNTRY_CODE_RS (((UINT_16) 'R' << 8) | (UINT_16) 'S') /* Serbia */ -+#define COUNTRY_CODE_RU (((UINT_16) 'R' << 8) | (UINT_16) 'U') /* Russia */ -+#define COUNTRY_CODE_RW (((UINT_16) 'R' << 8) | (UINT_16) 'W') /* Rwanda */ -+#define COUNTRY_CODE_SA (((UINT_16) 'S' << 8) | (UINT_16) 'A') /* Saudi Arabia */ -+#define COUNTRY_CODE_SB (((UINT_16) 'S' << 8) | (UINT_16) 'B') /* Solomon Islands */ -+#define COUNTRY_CODE_SC (((UINT_16) 'S' << 8) | (UINT_16) 'C') /* Seychelles */ -+#define COUNTRY_CODE_SD (((UINT_16) 'S' << 8) | (UINT_16) 'D') /* Sudan */ -+#define COUNTRY_CODE_SE (((UINT_16) 'S' << 8) | (UINT_16) 'E') /* Sweden */ -+#define COUNTRY_CODE_SG (((UINT_16) 'S' << 8) | (UINT_16) 'G') /* Singapole */ -+#define COUNTRY_CODE_SI (((UINT_16) 'S' << 8) | (UINT_16) 'I') /* Slovenia */ -+#define COUNTRY_CODE_SK (((UINT_16) 'S' << 8) | (UINT_16) 'K') /* Slovakia */ -+#define COUNTRY_CODE_SL (((UINT_16) 'S' << 8) | (UINT_16) 'L') /* Sierra Leone */ -+#define COUNTRY_CODE_SM (((UINT_16) 'S' << 8) | (UINT_16) 'M') /* San Marino */ -+#define COUNTRY_CODE_SN (((UINT_16) 'S' << 8) | (UINT_16) 'N') /* Senegal */ -+#define COUNTRY_CODE_SO (((UINT_16) 'S' << 8) | (UINT_16) 'O') /* Somalia */ -+#define COUNTRY_CODE_SR (((UINT_16) 'S' << 8) | (UINT_16) 'R') /* Suriname */ -+#define COUNTRY_CODE_SS (((UINT_16) 'S' << 8) | (UINT_16) 'S') /* South_Sudan */ -+#define COUNTRY_CODE_ST (((UINT_16) 'S' << 8) | (UINT_16) 'T') /* Sao Tome and Principe */ -+#define COUNTRY_CODE_SV (((UINT_16) 'S' << 8) | (UINT_16) 'V') /* El Salvador */ -+#define COUNTRY_CODE_SY (((UINT_16) 'S' << 8) | (UINT_16) 'Y') /* Syria */ -+#define COUNTRY_CODE_SZ (((UINT_16) 'S' << 8) | (UINT_16) 'Z') /* Swaziland */ -+#define COUNTRY_CODE_TC (((UINT_16) 'T' << 8) | (UINT_16) 'C') /* Turks and Caicos Islands (UK) */ -+#define COUNTRY_CODE_TD (((UINT_16) 'T' << 8) | (UINT_16) 'D') /* Chad */ -+#define COUNTRY_CODE_TF (((UINT_16) 'T' << 8) | (UINT_16) 'F') /* French Southern and Antarctic Lands */ -+#define COUNTRY_CODE_TG (((UINT_16) 'T' << 8) | (UINT_16) 'G') /* Togo */ -+#define COUNTRY_CODE_TH (((UINT_16) 'T' << 8) | (UINT_16) 'H') /* Thailand */ -+#define COUNTRY_CODE_TJ (((UINT_16) 'T' << 8) | (UINT_16) 'J') /* Tajikistan */ -+#define COUNTRY_CODE_TL (((UINT_16) 'T' << 8) | (UINT_16) 'L') /* East Timor */ -+#define COUNTRY_CODE_TM (((UINT_16) 'T' << 8) | (UINT_16) 'M') /* Turkmenistan */ -+#define COUNTRY_CODE_TN (((UINT_16) 'T' << 8) | (UINT_16) 'N') /* Tunisia */ -+#define COUNTRY_CODE_TO (((UINT_16) 'T' << 8) | (UINT_16) 'O') /* Tonga */ -+#define COUNTRY_CODE_TR (((UINT_16) 'T' << 8) | (UINT_16) 'R') /* Turkey */ -+#define COUNTRY_CODE_TT (((UINT_16) 'T' << 8) | (UINT_16) 'T') /* Trinidad and Tobago */ -+#define COUNTRY_CODE_TV (((UINT_16) 'T' << 8) | (UINT_16) 'V') /* Tuvalu */ -+#define COUNTRY_CODE_TW (((UINT_16) 'T' << 8) | (UINT_16) 'W') /* Taiwan */ -+#define COUNTRY_CODE_TZ (((UINT_16) 'T' << 8) | (UINT_16) 'Z') /* Tanzania */ -+#define COUNTRY_CODE_UA (((UINT_16) 'U' << 8) | (UINT_16) 'A') /* Ukraine */ -+#define COUNTRY_CODE_UG (((UINT_16) 'U' << 8) | (UINT_16) 'G') /* Ugnada */ -+#define COUNTRY_CODE_US (((UINT_16) 'U' << 8) | (UINT_16) 'S') /* US */ -+#define COUNTRY_CODE_UY (((UINT_16) 'U' << 8) | (UINT_16) 'Y') /* Uruguay */ -+#define COUNTRY_CODE_UZ (((UINT_16) 'U' << 8) | (UINT_16) 'Z') /* Uzbekistan */ -+#define COUNTRY_CODE_VA (((UINT_16) 'V' << 8) | (UINT_16) 'A') /* Vatican (Holy See) */ -+#define COUNTRY_CODE_VC (((UINT_16) 'V' << 8) | (UINT_16) 'C') /* Saint Vincent and the Grenadines */ -+#define COUNTRY_CODE_VE (((UINT_16) 'V' << 8) | (UINT_16) 'E') /* Venezuela */ -+#define COUNTRY_CODE_VG (((UINT_16) 'V' << 8) | (UINT_16) 'G') /* British Virgin Islands */ -+#define COUNTRY_CODE_VI (((UINT_16) 'V' << 8) | (UINT_16) 'I') /* US Virgin Islands */ -+#define COUNTRY_CODE_VN (((UINT_16) 'V' << 8) | (UINT_16) 'N') /* Vietnam */ -+#define COUNTRY_CODE_VU (((UINT_16) 'V' << 8) | (UINT_16) 'U') /* Vanuatu */ -+#define COUNTRY_CODE_WS (((UINT_16) 'W' << 8) | (UINT_16) 'S') /* Samoa */ -+#define COUNTRY_CODE_YE (((UINT_16) 'Y' << 8) | (UINT_16) 'E') /* Yemen */ -+#define COUNTRY_CODE_YT (((UINT_16) 'Y' << 8) | (UINT_16) 'T') /* Mayotte (France) */ -+#define COUNTRY_CODE_ZA (((UINT_16) 'Z' << 8) | (UINT_16) 'A') /* South Africa */ -+#define COUNTRY_CODE_ZM (((UINT_16) 'Z' << 8) | (UINT_16) 'M') /* Zambia */ -+#define COUNTRY_CODE_ZW (((UINT_16) 'Z' << 8) | (UINT_16) 'W') /* Zimbabwe */ -+ -+#define COUNTRY_CODE_DF (((UINT_16) 'D' << 8) | (UINT_16) 'F') /* Default country domain */ -+#define COUNTRY_CODE_UDF (((UINT_16) 'U' << 8) | (UINT_16) 'D') /* User defined supported channel list -+ and passive scan channel list */ -+ -+#define COUNTRY_CODE_FF (((UINT_16) 'F' << 8) | (UINT_16) 'F') /* enable open for all channel for Certification */ -+#define COUNTRY_CODE_FE (((UINT_16) 'F' << 8) | (UINT_16) 'E') /* disable open for all channel for Certification */ -+ -+/* dot11RegDomainsSupportValue */ -+#define MIB_REG_DOMAIN_FCC 0x10 /* FCC (US) */ -+#define MIB_REG_DOMAIN_IC 0x20 /* IC or DOC (Canada) */ -+#define MIB_REG_DOMAIN_ETSI 0x30 /* ETSI (Europe) */ -+#define MIB_REG_DOMAIN_SPAIN 0x31 /* Spain */ -+#define MIB_REG_DOMAIN_FRANCE 0x32 /* France */ -+#define MIB_REG_DOMAIN_JAPAN 0x40 /* MPHPT (Japan) */ -+#define MIB_REG_DOMAIN_OTHER 0x00 /* other */ -+ -+/*2.4G*/ -+#define BAND_2G4_LOWER_BOUND 1 -+#define BAND_2G4_UPPER_BOUND 14 -+/*5G SubBand FCC spec*/ -+#define UNII1_LOWER_BOUND 36 -+#define UNII1_UPPER_BOUND 48 -+#define UNII2A_LOWER_BOUND 52 -+#define UNII2A_UPPER_BOUND 64 -+#define UNII2C_LOWER_BOUND 100 -+#define UNII2C_UPPER_BOUND 144 -+#define UNII3_LOWER_BOUND 149 -+#define UNII3_UPPER_BOUND 173 -+ -+#if CFG_SUPPORT_PWR_LIMIT_COUNTRY -+ -+#define POWER_LIMIT_TABLE_NULL 0xFFFF -+#define MAX_TX_POWER 63 -+#define MIN_TX_POWER -64 -+#define MAX_CMD_SUPPORT_CHANNEL_NUM 64 -+ -+#endif -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+#if CFG_SUPPORT_PWR_LIMIT_COUNTRY -+ -+typedef enum _ENUM_POWER_LIMIT_T { -+ PWR_LIMIT_CCK, -+ PWR_LIMIT_20M, -+ PWR_LIMIT_40M, -+ PWR_LIMIT_80M, -+ PWR_LIMIT_160M, -+ PWR_LIMIT_NUM -+} ENUM_POWER_LIMIT_T, *P_ENUM_POWER_LIMIT_T; -+ -+#endif -+ -+typedef enum _ENUM_POWER_LIMIT_SUBBAND_T { -+ POWER_LIMIT_2G4, -+ POWER_LIMIT_UNII1, -+ POWER_LIMIT_UNII2A, -+ POWER_LIMIT_UNII2C, -+ POWER_LIMIT_UNII3, -+ POWER_LIMIT_SUBAND_NUM -+} ENUM_POWER_LIMIT_SUBBAND_T, *P_ENUM_POWER_LIMIT_SUBBAND_T; -+ -+/* Define channel offset in unit of 5MHz bandwidth */ -+typedef enum _ENUM_CHNL_SPAN_T { -+ CHNL_SPAN_5 = 1, -+ CHNL_SPAN_10 = 2, -+ CHNL_SPAN_20 = 4, -+ CHNL_SPAN_40 = 8 -+} ENUM_CHNL_SPAN_T, *P_ENUM_CHNL_SPAN_T; -+ -+/* Define BSS operating bandwidth */ -+typedef enum _ENUM_CHNL_BW_T { -+ CHNL_BW_20, -+ CHNL_BW_20_40, -+ CHNL_BW_10, -+ CHNL_BW_5 -+} ENUM_CHNL_BW_T, *P_ENUM_CHNL_BW_T; -+ -+/* In all bands, the first channel will be SCA and the second channel is SCB, -+ * then iteratively. -+ * Note the final channel will not be SCA. -+ */ -+typedef struct _DOMAIN_SUBBAND_INFO { -+ /* Note1: regulation class depends on operation bandwidth and RF band. -+ * For example: 2.4GHz, 1~13, 20MHz ==> regulation class = 81 -+ * 2.4GHz, 1~13, SCA ==> regulation class = 83 -+ * 2.4GHz, 1~13, SCB ==> regulation class = 84 -+ * Note2: TX power limit is not specified here because path loss is unknown -+ */ -+ UINT_8 ucRegClass; /* Regulation class for 20MHz */ -+ UINT_8 ucBand; /* Type: ENUM_BAND_T */ -+ UINT_8 ucChannelSpan; /* Type: ENUM_CHNL_SPAN_T */ -+ UINT_8 ucFirstChannelNum; -+ UINT_8 ucNumChannels; -+ UINT_8 fgDfs; /* Type: BOOLEAN */ -+} DOMAIN_SUBBAND_INFO, *P_DOMAIN_SUBBAND_INFO; -+ -+/* Use it as all available channel list for STA */ -+typedef struct _DOMAIN_INFO_ENTRY { -+ PUINT_16 pu2CountryGroup; -+ UINT_32 u4CountryNum; -+ -+ /* If different attributes, put them into different rSubBands. -+ * For example, DFS shall be used or not. -+ */ -+ DOMAIN_SUBBAND_INFO rSubBand[MAX_SUBBAND_NUM]; -+} DOMAIN_INFO_ENTRY, *P_DOMAIN_INFO_ENTRY; -+ -+ -+#if CFG_SUPPORT_PWR_LIMIT_COUNTRY -+ -+typedef struct _CHANNEL_POWER_LIMIT { -+ UINT_8 ucCentralCh; -+ INT_8 cPwrLimitCCK; -+ INT_8 cPwrLimit20; -+ INT_8 cPwrLimit40; -+ INT_8 cPwrLimit80; -+ INT_8 cPwrLimit160; -+ UINT_8 ucFlag; -+ UINT_8 aucReserved[1]; -+} CHANNEL_POWER_LIMIT, *P_CHANNEL_POWER_LIMIT; -+ -+typedef struct _COUNTRY_CHANNEL_POWER_LIMIT { -+ UINT_8 aucCountryCode[2]; -+ UINT_8 ucCountryFlag; -+ UINT_8 ucChannelNum; -+ UINT_8 aucReserved[4]; -+ CHANNEL_POWER_LIMIT rChannelPowerLimit[80]; -+} COUNTRY_CHANNEL_POWER_LIMIT, *P_COUNTRY_CHANNEL_POWER_LIMIT; -+ -+#define CHANNEL_PWR_LIMIT(_channel, _pwrLimit_cck, _pwrLimit_bw20, \ -+ _pwrLimit_bw40, _pwrLimit_bw80, _pwrLimit_bw160, _ucFlag) \ -+ { \ -+ .ucCentralCh = (_channel), \ -+ .cPwrLimitCCK = (_pwrLimit_cck), \ -+ .cPwrLimit20 = (_pwrLimit_bw20), \ -+ .cPwrLimit40 = (_pwrLimit_bw40), \ -+ .cPwrLimit80 = (_pwrLimit_bw80), \ -+ .cPwrLimit160 = (_pwrLimit_bw160), \ -+ .ucFlag = (_ucFlag), \ -+ .aucReserved = {0} \ -+} -+ -+typedef struct _COUNTRY_POWER_LIMIT_TABLE_DEFAULT { -+ UINT_8 aucCountryCode[2]; -+ /* 0: ch 1 ~14 , 1: ch 36 ~48, 2: ch 52 ~64, 3: ch 100 ~144, 4: ch 149 ~165 */ -+ INT_8 aucPwrLimitSubBand[POWER_LIMIT_SUBAND_NUM]; -+ /* bit0: cPwrLimit2G4, bit1: cPwrLimitUnii1; bit2: cPwrLimitUnii2A; -+ * bit3: cPwrLimitUnii2C; bit4: cPwrLimitUnii3; mW: 0, mW\MHz : 1 */ -+ UINT_8 ucPwrUnit; -+} COUNTRY_POWER_LIMIT_TABLE_DEFAULT, *P_COUNTRY_POWER_LIMIT_TABLE_DEFAULT; -+ -+typedef struct _COUNTRY_POWER_LIMIT_TABLE_CONFIGURATION { -+ UINT_8 aucCountryCode[2]; -+ UINT_8 ucCentralCh; -+ INT_8 aucPwrLimit[PWR_LIMIT_NUM]; -+} COUNTRY_POWER_LIMIT_TABLE_CONFIGURATION, *P_COUNTRY_POWER_LIMIT_TABLE_CONFIGURATION; -+ -+typedef struct _SUBBAND_CHANNEL_T { -+ UINT_8 ucStartCh; -+ UINT_8 ucEndCh; -+ UINT_8 ucInterval; -+ UINT_8 ucReserved; -+} SUBBAND_CHANNEL_T, *P_SUBBAND_CHANNEL_T; -+ -+#endif -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+#define CAL_CH_OFFSET_80M(_PRIMARY_CH, _CENTRAL_CH) \ -+ (((_PRIMARY_CH - _CENTRAL_CH) + 6) >> 2) -+ -+#define CAL_CH_OFFSET_160M(_PRIMARY_CH, _CENTRAL_CH) \ -+ (((_PRIMARY_CH - _CENTRAL_CH) + 14) >> 2) -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+P_DOMAIN_INFO_ENTRY rlmDomainGetDomainInfo(P_ADAPTER_T prAdapter); -+ -+VOID -+rlmDomainGetChnlList(P_ADAPTER_T prAdapter, -+ ENUM_BAND_T eSpecificBand, BOOLEAN fgNoDfs, -+ UINT_8 ucMaxChannelNum, PUINT_8 pucNumOfChannel, P_RF_CHANNEL_INFO_T paucChannelList); -+ -+VOID rlmDomainSendCmd(P_ADAPTER_T prAdapter, BOOLEAN fgIsOid); -+ -+VOID rlmDomainSendDomainInfoCmd(P_ADAPTER_T prAdapter, BOOLEAN fgIsOid); -+ -+VOID rlmDomainSendPassiveScanInfoCmd(P_ADAPTER_T prAdapter, BOOLEAN fgIsOid); -+ -+BOOLEAN rlmDomainIsLegalChannel(P_ADAPTER_T prAdapter, ENUM_BAND_T eBand, UINT_8 ucChannel); -+ -+UINT_32 rlmDomainSupOperatingClassIeFill(PUINT_8 pBuf); -+ -+BOOLEAN rlmDomainCheckChannelEntryValid(P_ADAPTER_T prAdapter, UINT_8 ucCentralCh); -+ -+UINT_8 rlmDomainGetCenterChannel(ENUM_BAND_T eBand, UINT_8 ucPriChannel, ENUM_CHNL_EXT_T eExtend); -+ -+BOOLEAN rlmDomainIsValidRfSetting(P_ADAPTER_T prAdapter, ENUM_BAND_T eBand, -+ UINT_8 ucPriChannel, ENUM_CHNL_EXT_T eExtend, -+ ENUM_CHANNEL_WIDTH_T eChannelWidth, UINT_8 ucChannelS1, UINT_8 ucChannelS2); -+ -+#if CFG_SUPPORT_PWR_LIMIT_COUNTRY -+ -+BOOLEAN -+rlmDomainCheckPowerLimitValid(P_ADAPTER_T prAdapter, -+ COUNTRY_POWER_LIMIT_TABLE_CONFIGURATION rPowerLimitTableConfiguration, -+ UINT_8 ucPwrLimitNum); -+ -+VOID rlmDomainCheckCountryPowerLimitTable(P_ADAPTER_T prAdapter); -+ -+UINT_16 rlmDomainPwrLimitDefaultTableDecision(P_ADAPTER_T prAdapter, UINT_16 u2CountryCode); -+ -+VOID rlmDomainSendPwrLimitCmd(P_ADAPTER_T prAdapter); -+#endif -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif /* _RLM_DOMAIN_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rlm_obss.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rlm_obss.h -new file mode 100644 -index 000000000000..7f29dba4ce06 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rlm_obss.h -@@ -0,0 +1,150 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/mgmt/rlm_obss.h#1 -+*/ -+ -+/*! \file "rlm_obss.h" -+ \brief -+*/ -+ -+/* -+** Log: rlm_obss.h -+ * -+ * 01 24 2011 cm.chang -+ * [WCXRP00000384] [MT6620 Wi-Fi][Driver][FW] Handle 20/40 action frame in AP mode and stop -+ * ampdu timer when sta_rec is freed -+ * Process received 20/40 coexistence action frame for AP mode -+ * -+ * 01 13 2011 cm.chang -+ * [WCXRP00000358] [MT6620 Wi-Fi][Driver] Provide concurrent information for each module -+ * Refine function when rcv a 20/40M public action frame -+ * -+ * 01 12 2011 cm.chang -+ * [WCXRP00000354] [MT6620 Wi-Fi][Driver][FW] Follow NVRAM bandwidth setting -+ * User-defined bandwidth is for 2.4G and 5G individually -+ * -+ * 08 24 2010 cm.chang -+ * NULL -+ * Support RLM initail channel of Ad-hoc, P2P and BOW -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 28 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * 1st draft code for RLM module -+ * -+ * 05 07 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Process 20/40 coexistence public action frame in AP mode -+ * -+ * 05 05 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * First draft support for 20/40M bandwidth for AP mode -+ * -+ * 04 07 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Add virtual test for OBSS scan -+ * -+ * 03 30 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Support 2.4G OBSS scan -+ * -+ * 02 13 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Support PCO in STA mode -+ * -+ * 02 12 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Use bss info array for concurrent handle -+ * -+ * 01 25 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Support protection and bandwidth switch -+*/ -+ -+#ifndef _RLM_OBSS_H -+#define _RLM_OBSS_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+#define CHNL_LIST_SZ_2G 14 -+#define CHNL_LIST_SZ_5G 14 -+ -+#define CHNL_LEVEL0 0 -+#define CHNL_LEVEL1 1 -+#define CHNL_LEVEL2 2 -+ -+#define AFFECTED_CHNL_OFFSET 5 -+ -+#define OBSS_SCAN_MIN_INTERVAL 10 /* In unit of sec */ -+ -+#define PUBLIC_ACTION_MAX_LEN 200 /* In unit of byte */ -+ -+/* P2P GO only */ -+/* Define default OBSS Scan parameters (from MIB in spec.) */ -+#define dot11OBSSScanPassiveDwell 20 -+#define dot11OBSSScanActiveDwell 10 -+#define dot11OBSSScanPassiveTotalPerChannel 200 -+#define dot11OBSSScanActiveTotalPerChannel 20 -+#define dot11BSSWidthTriggerScanInterval 300 /* Unit: sec */ -+#define dot11BSSWidthChannelTransitionDelayFactor 5 -+#define dot11OBSSScanActivityThreshold 25 -+ -+#define OBSS_20_40M_TIMEOUT (dot11BSSWidthTriggerScanInterval + 10) -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/* Control MAC PCO function */ -+typedef enum _ENUM_SYS_PCO_PHASE_T { -+ SYS_PCO_PHASE_DISABLED = 0, -+ SYS_PCO_PHASE_20M, -+ SYS_PCO_PHASE_40M -+} ENUM_SYS_PCO_PHASE_T, *P_ENUM_SYS_PCO_PHASE_T; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+VOID rlmObssInit(P_ADAPTER_T prAdapter); -+ -+VOID rlmObssScanDone(P_ADAPTER_T prAdapter, P_MSG_HDR_T prMsgHdr); -+ -+VOID rlmObssTriggerScan(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo); -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif /* _RLM_OBSS_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rlm_protection.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rlm_protection.h -new file mode 100644 -index 000000000000..8665e48569ba ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rlm_protection.h -@@ -0,0 +1,122 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/mgmt/rlm_protection.h#1 -+*/ -+ -+/*! \file "rlm_protection.h" -+ \brief -+*/ -+ -+/* -+** Log: rlm_protection.h -+ * -+ * 08 20 2010 cm.chang -+ * NULL -+ * Migrate RLM code to host from FW -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 28 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * 1st draft code for RLM module -+ * -+ * 04 22 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * First draft code to support protection in AP mode -+ * -+ * 02 13 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Support PCO in STA mode -+ * -+ * 02 12 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Use bss info array for concurrent handle -+ * -+ * 01 25 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Support protection and bandwidth switch -+*/ -+ -+#ifndef _RLM_PROTECTION_H -+#define _RLM_PROTECTION_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+typedef enum _ENUM_SYS_PROTECT_MODE_T { -+ SYS_PROTECT_MODE_NONE = 0, /* Mode 0 */ -+ SYS_PROTECT_MODE_ERP, /* Mode 1 */ -+ SYS_PROTECT_MODE_NON_HT, /* Mode 2 */ -+ SYS_PROTECT_MODE_20M, /* Mode 3 */ -+ -+ SYS_PROTECT_MODE_NUM -+} ENUM_SYS_PROTECT_MODE_T, *P_ENUM_SYS_PROTECT_MODE_T; -+ -+/* This definition follows HT Protection field of HT Operation IE */ -+typedef enum _ENUM_HT_PROTECT_MODE_T { -+ HT_PROTECT_MODE_NONE = 0, -+ HT_PROTECT_MODE_NON_MEMBER, -+ HT_PROTECT_MODE_20M, -+ HT_PROTECT_MODE_NON_HT, -+ -+ HT_PROTECT_MODE_NUM -+} ENUM_HT_PROTECT_MODE_T, *P_ENUM_HT_PROTECT_MODE_T; -+ -+typedef enum _ENUM_GF_MODE_T { -+ GF_MODE_NORMAL = 0, -+ GF_MODE_PROTECT, -+ GF_MODE_DISALLOWED, -+ -+ GF_MODE_NUM -+} ENUM_GF_MODE_T, *P_ENUM_GF_MODE_T; -+ -+typedef enum _ENUM_RIFS_MODE_T { -+ RIFS_MODE_NORMAL = 0, -+ RIFS_MODE_DISALLOWED, -+ -+ RIFS_MODE_NUM -+} ENUM_RIFS_MODE_T, *P_ENUM_RIFS_MODE_T; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif /* _RLM_PROTECTION_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rlm_txpwr_init.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rlm_txpwr_init.h -new file mode 100644 -index 000000000000..d01c6e01e83f ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rlm_txpwr_init.h -@@ -0,0 +1,1213 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/mgmt/rlm_txpwr_init.h#1 -+*/ -+ -+/*! \file "rlm_txpwr_init.h" -+ \brief -+*/ -+ -+/* -+** Log: rlm_txpwr_init.h -+*/ -+ -+ -+#ifndef _RLM_TXPWR_INIT_H -+#define _RLM_TXPWR_INIT_H -+ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+/*Support Tx Power Range : 63~ -64 (unit : 0.5dBm)*/ -+ -+#define PWR_LIMIT_2G4_IN_MW_MHZ BIT(0) -+#define PWR_LIMIT_UNII1_IN_MW_MHZ BIT(1) -+#define PWR_LIMIT_UNII2A_IN_MW_MHZ BIT(2) -+#define PWR_LIMIT_UNII2C_IN_MW_MHZ BIT(3) -+#define PWR_LIMIT_UNII3_IN_MW_MHZ BIT(4) -+ -+#if CFG_SUPPORT_CE_FCC_TXPWR_LIMIT -+#define CE_FCC_TXPWR_LIMIT_CCK 30 /* 15 dBm */ -+#define CE_FCC_TXPWR_LIMIT_OFDM 20 /* 10 dBm */ -+#define CE_FCC_TXPWR_LIMIT_HT40 18 /* 9 dBm */ -+#endif -+ -+ -+#if CFG_SUPPORT_PWR_LIMIT_COUNTRY -+ -+COUNTRY_POWER_LIMIT_TABLE_DEFAULT g_rRlmPowerLimitDefault[] = { -+ -+ {{'A', 'O'} -+ , {40, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'B', 'Z'} -+ , {40, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'B', 'J'} -+ , {40, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'B', 'T'} -+ , {40, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'B', 'O'} -+ , {40, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'B', 'I'} -+ , {40, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'C', 'M'} -+ , {40, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'C', 'F'} -+ , {40, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'T', 'D'} -+ , {40, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'K', 'M'} -+ , {40, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'C', 'D'} -+ , {40, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'C', 'G'} -+ , {40, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'C', 'I'} -+ , {40, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'D', 'J'} -+ , {40, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'G', 'Q'} -+ , {40, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'E', 'R'} -+ , {40, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'F', 'J'} -+ , {40, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'G', 'A'} -+ , {40, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'G', 'M'} -+ , {40, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'G', 'N'} -+ , {40, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'G', 'W'} -+ , {40, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'R', 'K'} -+ , {40, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'K', 'G'} -+ , {40, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'L', 'Y'} -+ , {40, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'M', 'G'} -+ , {40, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'M', 'L'} -+ , {40, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'N', 'R'} -+ , {40, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'N', 'C'} -+ , {40, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'S', 'T'} -+ , {40, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'S', 'C'} -+ , {40, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'S', 'L'} -+ , {40, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'S', 'B'} -+ , {40, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'S', 'O'} -+ , {40, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'S', 'R'} -+ , {40, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'S', 'Z'} -+ , {40, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'T', 'J'} -+ , {40, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'T', 'G'} -+ , {40, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'T', 'O'} -+ , {40, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'T', 'M'} -+ , {40, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'T', 'V'} -+ , {40, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'V', 'U'} -+ , {40, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'Y', 'E'} -+ , {40, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'A', 'S'} -+ , {60, 34, 46, 48, 60} -+ , 0} -+ , -+ {{'A', 'I'} -+ , {60, 34, 48, 60, 60} -+ , 0} -+ , -+ {{'B', 'M'} -+ , {60, 34, 48, 48, 60} -+ , 0} -+ , -+ {{'C', 'A'} -+ , {60, 46, 48, 48, 60} -+ , 0} -+ , -+ {{'K', 'Y'} -+ , {60, 34, 48, 60, 60} -+ , 0} -+ , -+ {{'G', 'U'} -+ , {60, 34, 48, 48, 60} -+ , 0} -+ , -+ {{'F', 'M'} -+ , {60, 34, 48, 48, 60} -+ , 0} -+ , -+ {{'P', 'R'} -+ , {60, 34, 46, 48, 60} -+ , 0} -+ , -+ {{'U', 'S'} -+ , {60, 34, 48, 48, 60} -+ , 0} -+ , -+ {{'V', 'I'} -+ , {60, 34, 48, 48, 60} -+ , 0} -+ , -+ {{'A', 'R'} -+ , {60, 34, 48, 48, 60} -+ , 0} -+ , -+ {{'A', 'U'} -+ , {63, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'A', 'Z'} -+ , {40, 34, 48, 60, 60} -+ , 0} -+ , -+ {{'B', 'W'} -+ , {40, 46, 46, 60, 60} -+ , 0} -+ , -+ {{'K', 'H'} -+ , {40, 46, 46, 48, 60} -+ , 0} -+ , -+ {{'C', 'X'} -+ , {63, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'C', 'O'} -+ , {60, 34, 48, 48, 60} -+ , 0} -+ , -+ {{'C', 'R'} -+ , {60, 34, 48, 48, 60} -+ , 0} -+ , -+ {{'E', 'C'} -+ , {60, 34, 48, 48, 60} -+ , 0} -+ , -+ {{'G', 'D'} -+ , {40, 46, 46, 60, 60} -+ , 0} -+ , -+ {{'G', 'T'} -+ , {40, 34, 48, 48, 60} -+ , 0} -+ , -+ {{'H', 'K'} -+ , {63, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'K', 'I'} -+ , {63, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'L', 'B'} -+ , {40, 46, 46, 46, 46} -+ , 0} -+ , -+ {{'L', 'R'} -+ , {60, 46, 60, 63, 63} -+ , 0} -+ , -+ {{'M', 'N'} -+ , {46, 32, 46, 46, 58} -+ , 0} -+ , -+ {{'A', 'N'} -+ , {60, 34, 48, 48, 60} -+ , 0} -+ , -+ {{'N', 'Z'} -+ , {63, 46, 60, 48, 63} -+ , 0} -+ , -+ {{'N', 'I'} -+ , {60, 34, 48, 48, 60} -+ , 0} -+ , -+ {{'P', 'W'} -+ , {60, 60, 60, 60, 60} -+ , 0} -+ , -+ {{'P', 'Y'} -+ , {60, 46, 46, 48, 60} -+ , 0} -+ , -+ {{'P', 'E'} -+ , {54, 46, 48, 42, 48} -+ , 0} -+ , -+ {{'P', 'H'} -+ , {40, 46, 46, 48, 48} -+ , 0} -+ , -+ {{'W', 'S'} -+ , {40, 40, 40, 40, 60} -+ , 0} -+ , -+ {{'S', 'G'} -+ , {46, 46, 46, 60, 60} -+ , 0} -+ , -+ {{'L', 'K'} -+ , {46, 46, 46, 46, 46} -+ , 0} -+ , -+ {{'T', 'H'} -+ , {40, 46, 46, 60, 60} -+ , 0} -+ , -+ {{'T', 'T'} -+ , {60, 46, 46, 60, 60} -+ , 0} -+ , -+ {{'U', 'Y'} -+ , {63, 46, 46, 46, 46} -+ , 0} -+ , -+ {{'V', 'N'} -+ , {46, 46, 46, 60, 60} -+ , 0} -+ , -+ {{'A', 'W'} -+ , {60, 46, 60, 60, 63} -+ , 0} -+ , -+ {{'L', 'A'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'S', 'A'} -+ , {40, 46, 46, 60, 60} -+ , 0} -+ , -+ {{'A', 'E'} -+ , {40, 46, 46, 60, 46} -+ , 0} -+ , -+ {{'U', 'G'} -+ , {40, 46, 46, 48, 60} -+ , 0} -+ , -+ {{'M', 'M'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'A', 'L'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'D', 'Z'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'A', 'D'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'A', 'T'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'B', 'Y'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'B', 'E'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'B', 'A'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'V', 'G'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'B', 'G'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'C', 'V'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'H', 'R'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'C', 'Y'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'C', 'Z'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'D', 'K'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'E', 'E'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'E', 'T'} -+ , {40, 40, 40, 40, 63} -+ , 0} -+ , -+ {{'F', 'I'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'F', 'R'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'G', 'F'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'P', 'F'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'T', 'F'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'G', 'E'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'D', 'E'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'G', 'H'} -+ , {40, 34, 48, 60, 63} -+ , 0} -+ , -+ {{'G', 'R'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'G', 'P'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'H', 'U'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'I', 'S'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'I', 'Q'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'I', 'E'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'I', 'T'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'K', 'E'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'L', 'V'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'L', 'S'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'L', 'I'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'L', 'T'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'L', 'U'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'M', 'K'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'M', 'T'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'M', 'Q'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'M', 'R'} -+ , {40, 46, 46, 46, 63} -+ , 0} -+ , -+ {{'M', 'U'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'Y', 'T'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'M', 'D'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'M', 'C'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'M', 'E'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'M', 'S'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'N', 'L'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'N', 'O'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'O', 'M'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'P', 'L'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'P', 'T'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'R', 'E'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'R', 'O'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'M', 'F'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'S', 'M'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'S', 'N'} -+ , {40, 40, 40, 60, 63} -+ , 0} -+ , -+ {{'R', 'S'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'S', 'K'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'S', 'I'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'Z', 'A'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'E', 'S'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'S', 'E'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'C', 'H'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'T', 'R'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'T', 'C'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'G', 'B'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'V', 'A'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'A', 'M'} -+ , {40, 40, 40, 63, 63} -+ , 0} -+ , -+ {{'I', 'L'} -+ , {40, 46, 46, 63, 63} -+ , 0} -+ , -+ {{'K', 'W'} -+ , {40, 46, 46, 63, 63} -+ , 0} -+ , -+ {{'M', 'A'} -+ , {40, 46, 46, 63, 63} -+ , 0} -+ , -+ {{'N', 'E'} -+ , {40, 46, 46, 63, 63} -+ , 0} -+ , -+ {{'T', 'N'} -+ , {40, 46, 46, 63, 63} -+ , 0} -+ , -+ {{'E', 'H'} -+ , {40, 46, 46, 63, 63} -+ , 0} -+ , -+ {{'N', 'P'} -+ , {60, 46, 46, 63, 60} -+ , 0} -+ , -+ {{'A', 'F'} -+ , {40, 46, 63, 63, 63} -+ , 0} -+ , -+ {{'A', 'G'} -+ , {40, 46, 48, 63, 54} -+ , 0} -+ , -+ {{'B', 'S'} -+ , {63, 46, 60, 63, 63} -+ , 0} -+ , -+ {{'B', 'H'} -+ , {40, 46, 46, 63, 63} -+ , 0} -+ , -+ {{'B', 'B'} -+ , {40, 46, 48, 63, 54} -+ , 0} -+ , -+ {{'B', 'N'} -+ , {46, 46, 46, 63, 60} -+ , 0} -+ , -+ {{'C', 'L'} -+ , {40, 44, 44, 63, 44} -+ , 0} -+ , -+ {{'C', 'N'} -+ , {40, 46, 46, 63, 54} -+ , 0} -+ , -+ {{'E', 'G'} -+ , {40, 46, 46, 63, 46} -+ , 0} -+ , -+ {{'S', 'V'} -+ , {60, 34, 48, 63, 60} -+ , 0} -+ , -+ {{'I', 'N'} -+ , {60, 46, 46, 63, 60} -+ , 0} -+ , -+ {{'M', 'Y'} -+ , {54, 60, 60, 63, 60} -+ , 0} -+ , -+ {{'M', 'V'} -+ , {40, 46, 46, 63, 40} -+ , 0} -+ , -+ {{'P', 'A'} -+ , {60, 34, 48, 63, 60} -+ , 0} -+ , -+ {{'V', 'E'} -+ , {60, 46, 46, 63, 60} -+ , 0} -+ , -+ {{'Z', 'M'} -+ , {60, 46, 46, 63, 60} -+ , 0} -+ , -+ {{'J', 'O'} -+ , {40, 46, 63, 63, 46} -+ , 0} -+ , -+ {{'P', 'G'} -+ , {40, 46, 63, 63, 60} -+ , 0} -+ , -+ {{'B', 'F'} -+ , {40, 63, 63, 63, 60} -+ , 0} -+ , -+ {{'G', 'Y'} -+ , {60, 63, 63, 63, 60} -+ , 0} -+ , -+ {{'H', 'T'} -+ , {40, 63, 63, 63, 60} -+ , 0} -+ , -+ {{'H', 'N'} -+ , {60, 63, 63, 63, 60} -+ , 0} -+ , -+ {{'J', 'M'} -+ , {54, 63, 63, 63, 57} -+ , 0} -+ , -+ {{'M', 'O'} -+ , {40, 63, 63, 63, 40} -+ , 0} -+ , -+ {{'M', 'W'} -+ , {60, 63, 63, 63, 60} -+ , 0} -+ , -+ {{'P', 'K'} -+ , {40, 63, 63, 63, 40} -+ , 0} -+ , -+ {{'Q', 'A'} -+ , {40, 63, 63, 63, 40} -+ , 0} -+ , -+ {{'R', 'W'} -+ , {40, 63, 63, 63, 60} -+ , 0} -+ , -+ {{'K', 'N'} -+ , {40, 63, 63, 63, 60} -+ , 0} -+ , -+ {{'T', 'Z'} -+ , {40, 63, 63, 63, 40} -+ , 0} -+ , -+ {{'I', 'D'} -+ , {46, 63, 63, 63, 60} -+ , 0} -+ , -+ {{'N', 'G'} -+ , {40, 63, 46, 63, 60} -+ , 0} -+ , -+ {{'B', 'D'} -+ , {40, 46, 46, 60, 28} -+ , 0} -+ , -+ {{'B', 'R'} -+ , {52, 46, 46, 60, 60} -+ , 0} -+ , -+ {{'D', 'M'} -+ , {60, 34, 46, 48, 60} -+ , 0} -+ , -+ {{'D', 'O'} -+ , {63, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'F', 'K'} -+ , {40, 46, 46, 60, 28} -+ , 0} -+ , -+ {{'K', 'Z'} -+ , {40, 34, 48, 60, 60} -+ , 0} -+ , -+ {{'M', 'X'} -+ , {60, 34, 48, 60, 63} -+ , 0} -+ , -+ {{'M', 'Z'} -+ , {40, 34, 46, 48, 60} -+ , 0} -+ , -+ {{'N', 'A'} -+ , {40, 34, 46, 48, 60} -+ , 0} -+ , -+ {{'R', 'U'} -+ , {40, 34, 48, 60, 60} -+ , 0} -+ , -+ {{'L', 'C'} -+ , {40, 34, 48, 48, 60} -+ , 0} -+ , -+ {{'V', 'C'} -+ , {40, 34, 46, 48, 60} -+ , 0} -+ , -+ {{'U', 'A'} -+ , {40, 46, 46, 46, 48} -+ , 0} -+ , -+ {{'U', 'Z'} -+ , {40, 48, 48, 48, 60} -+ , 0} -+ , -+ {{'Z', 'W'} -+ , {40, 34, 46, 48, 60} -+ , 0} -+ , -+ {{'M', 'P'} -+ , {60, 34, 46, 48, 60} -+ , 0} -+ , -+ {{'T', 'W'} -+ , {60, 63, 34, 48, 60} -+ , 0} -+ , -+ {{'C', 'K'} -+ , {63, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'C', 'U'} -+ , {63, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'T', 'L'} -+ , {63, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'F', 'O'} -+ , {63, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'G', 'I'} -+ , {63, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'G', 'G'} -+ , {63, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'I', 'R'} -+ , {63, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'I', 'M'} -+ , {63, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'J', 'E'} -+ , {63, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'K', 'P'} -+ , {63, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'M', 'H'} -+ , {63, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'N', 'U'} -+ , {63, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'N', 'F'} -+ , {63, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'P', 'S'} -+ , {63, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'P', 'N'} -+ , {63, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'P', 'M'} -+ , {63, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'S', 'S'} -+ , {63, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'S', 'D'} -+ , {63, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'S', 'Y'} -+ , {63, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'J', 'P'} -+ , {46, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'K', 'R'} -+ , {46, 34, 46, 46, 46} -+ , PWR_LIMIT_UNII1_IN_MW_MHZ} -+ , -+ -+/*Default*/ -+ {{0, 0} -+ , {63, 63, 63, 63, 63} -+ , 0} -+}; -+ -+COUNTRY_POWER_LIMIT_TABLE_CONFIGURATION g_rRlmPowerLimitConfiguration[] = { -+ -+ {{'A', 'I'} -+ , 144, {48, 48, 48, 48, 48} -+ } -+ , -+ {{'A', 'Z'} -+ , 144, {48, 48, 48, 48, 48} -+ } -+ , -+ {{'B', 'W'} -+ , 144, {48, 48, 48, 48, 48} -+ } -+ , -+ {{'G', 'D'} -+ , 144, {48, 48, 48, 48, 48} -+ } -+ , -+ {{'L', 'B'} -+ , 144, {48, 48, 48, 48, 48} -+ } -+ , -+ {{'L', 'R'} -+ , 144, {48, 48, 48, 48, 48} -+ } -+ , -+ {{'W', 'S'} -+ , 165, {40, 40, 40, 40, 40} -+ } -+ , -+ {{'V', 'N'} -+ , 144, {48, 48, 48, 48, 48} -+ } -+ , -+ {{'U', 'S'} -+ , 1, {38, 30, 60, 60, 60} -+ } -+ , -+ {{'U', 'S'} -+ , 3, {60, 60, 26, 60, 60} -+ } -+ , -+ {{'U', 'S'} -+ , 9, {60, 60, 26, 60, 60} -+ } -+ , -+ {{'U', 'S'} -+ , 11, {38, 30, 60, 60, 60} -+ } -+ , -+ {{'U', 'S'} -+ , 36, {34, 34, 34, 34, 34} -+ } -+ , -+ {{'U', 'S'} -+ , 38, {34, 34, 34, 34, 34} -+ } -+ , -+ {{'U', 'S'} -+ , 42, {34, 34, 34, 31, 34} -+ } -+ , -+ {{'U', 'S'} -+ , 58, {48, 48, 48, 31, 48} -+ } -+ , -+ {{'U', 'S'} -+ , 62, {48, 48, 34, 48, 48} -+ } -+ , -+ {{'U', 'S'} -+ , 64, {37, 37, 48, 48, 48} -+ } -+ , -+ {{'U', 'S'} -+ , 100, {37, 37, 48, 48, 48} -+ } -+ , -+ {{'U', 'S'} -+ , 102, {48, 48, 34, 48, 48} -+ } -+ , -+ {{'U', 'S'} -+ , 106, {48, 48, 48, 31, 48} -+ } -+ , -+ {{'U', 'S'} -+ , 155, {60, 60, 60, 31, 60} -+ } -+ , -+ {{'U', 'S'} -+ , 159, {60, 60, 34, 60, 60} -+ } -+ , -+ {{'U', 'S'} -+ , 165, {37, 37, 60, 60, 60} -+ } -+ , -+ -+/*Default*/ -+ {{0, 0} -+ , 165, {63, 63, 63, 63, 63} -+ } -+}; -+ -+#if 0 -+COUNTRY_CHANNEL_POWER_LIMIT g_rRlmCountryPowerLimitTable[] = { -+ { -+ {'A', 'O'} -+ , 0, 0, {0, 0, 0, 0} -+ , -+ { -+ CHANNEL_PWR_LIMIT(1, 40, 40, 40, 40, 40, 0), -+ CHANNEL_PWR_LIMIT(2, 40, 40, 40, 40, 40, 0), -+ CHANNEL_PWR_LIMIT(3, 40, 40, 40, 40, 40, 0), -+ CHANNEL_PWR_LIMIT(4, 40, 40, 40, 40, 40, 0), -+ CHANNEL_PWR_LIMIT(5, 40, 40, 40, 40, 40, 0), -+ CHANNEL_PWR_LIMIT(6, 40, 40, 40, 40, 40, 0), -+ CHANNEL_PWR_LIMIT(7, 40, 40, 40, 40, 40, 0), -+ CHANNEL_PWR_LIMIT(8, 40, 40, 40, 40, 40, 0), -+ CHANNEL_PWR_LIMIT(9, 40, 40, 40, 40, 40, 0), -+ CHANNEL_PWR_LIMIT(10, 40, 40, 40, 40, 40, 0), -+ CHANNEL_PWR_LIMIT(11, 40, 40, 40, 40, 40, 0), -+ CHANNEL_PWR_LIMIT(12, 40, 40, 40, 40, 40, 0), -+ CHANNEL_PWR_LIMIT(13, 40, 40, 40, 40, 40, 0), -+ CHANNEL_PWR_LIMIT(14, 40, 40, 40, 40, 40, 0), -+ -+ CHANNEL_PWR_LIMIT(36, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(38, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(40, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(42, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(44, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(46, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(48, 63, 63, 63, 63, 63, 0), -+ -+ CHANNEL_PWR_LIMIT(52, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(54, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(56, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(58, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(60, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(62, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(64, 63, 63, 63, 63, 63, 0), -+ -+ CHANNEL_PWR_LIMIT(100, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(102, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(104, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(106, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(108, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(110, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(112, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(114, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(116, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(118, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(120, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(122, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(124, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(126, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(128, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(130, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(132, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(134, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(136, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(138, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(140, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(142, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(144, 63, 63, 63, 63, 63, 0), -+ -+ CHANNEL_PWR_LIMIT(149, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(151, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(153, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(155, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(157, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(159, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(161, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(163, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(165, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(167, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(169, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(171, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(173, 63, 63, 63, 63, 63, 0) -+ } -+ } -+ , -+ { -+ /*Used to check the end of country entry */ -+ {0, 0} -+ , 0, 0, {0, 0, 0, 0} -+ , -+ { -+ /*Used to check the end of channel power limit */ -+ CHANNEL_PWR_LIMIT(ENDCH, 0, 0, 0, 0, 0, 0) -+ } -+ } /*end of CountryTable */ -+}; -+#endif -+#endif -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+#endif /* _RLM_TXPWR_INIT_H */ -+ -+ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/roaming_fsm.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/roaming_fsm.h -new file mode 100644 -index 000000000000..0df4ec3e0828 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/roaming_fsm.h -@@ -0,0 +1,171 @@ -+/* -+** Id: -+*/ -+ -+/*! \file "roaming_fsm.h" -+ \brief This file defines the FSM for Roaming MODULE. -+ -+ This file defines the FSM for Roaming MODULE. -+*/ -+ -+/* -+** Log: roaming_fsm.h -+ * -+ * 08 31 2011 tsaiyuan.hsu -+ * [WCXRP00000931] [MT5931 Wi-Fi][DRV/FW] add swcr to disable roaming from driver -+ * remove obsolete code. -+ * -+ * 08 15 2011 tsaiyuan.hsu -+ * [WCXRP00000931] [MT5931 Wi-Fi][DRV/FW] add swcr to disable roaming from driver -+ * add swcr in driver reg, 0x9fxx0000, to disable roaming . -+ * -+ * 03 16 2011 tsaiyuan.hsu -+ * [WCXRP00000517] [MT6620 Wi-Fi][Driver][FW] Fine Tune Performance of Roaming -+ * remove obsolete definition and unused variables. -+ * -+ * 02 26 2011 tsaiyuan.hsu -+ * [WCXRP00000391] [MT6620 Wi-Fi][FW] Add Roaming Support -+ * not send disassoc or deauth to leaving AP so as to improve performace of roaming. -+ * -+ * 01 27 2011 tsaiyuan.hsu -+ * [WCXRP00000392] [MT6620 Wi-Fi][Driver] Add Roaming Support -+ * add roaming fsm -+ * 1. not support 11r, only use strength of signal to determine roaming. -+ * 2. not enable CFG_SUPPORT_ROAMING until completion of full test. -+ * 3. in 6620, adopt work-around to avoid sign extension problem of cck of hw -+ * 4. assume that change of link quality in smooth way. -+ * -+ * 01 27 2011 tsaiyuan.hsu -+ * [WCXRP00000392] [MT6620 Wi-Fi][Driver] Add Roaming Support -+ * add roaming fsm -+ * 1. not support 11r, only use strength of signal to determine roaming. -+ * 2. not enable CFG_SUPPORT_ROAMING until completion of full test. -+ * 3. in 6620, adopt work-around to avoid sign extension problem of cck of hw -+ * 4. assume that change of link quality in smooth way. -+ * -+*/ -+ -+#ifndef _ROAMING_FSM_H -+#define _ROAMING_FSM_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+/* Roaming Discovery interval, SCAN result need to be updated */ -+#define ROAMING_DISCOVERY_TIMEOUT_SEC 5 /* Seconds. */ -+ -+/* #define ROAMING_NO_SWING_RCPI_STEP 5 //rcpi */ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+typedef enum _ENUM_ROAMING_FAIL_REASON_T { -+ ROAMING_FAIL_REASON_CONNLIMIT = 0, -+ ROAMING_FAIL_REASON_NOCANDIDATE, -+ ROAMING_FAIL_REASON_NUM -+} ENUM_ROAMING_FAIL_REASON_T; -+ -+/* events of roaming between driver and firmware */ -+typedef enum _ENUM_ROAMING_EVENT_T { -+ ROAMING_EVENT_START = 0, -+ ROAMING_EVENT_DISCOVERY, -+ ROAMING_EVENT_ROAM, -+ ROAMING_EVENT_FAIL, -+ ROAMING_EVENT_ABORT, -+ ROAMING_EVENT_NUM -+} ENUM_ROAMING_EVENT_T; -+ -+#define ROAMING_EVENT_REASON_TX_ERR BIT(0) -+#define ROAMING_EVENT_REASON_RCPI BIT(1) -+ -+typedef struct _ROAMING_PARAM_T { -+ UINT_16 u2Event; -+ UINT_16 u2Data; -+ UINT_16 u2Reason; -+} ROAMING_PARAM_T, *P_ROAMING_PARAM_T; -+ -+ /**/ typedef enum _ENUM_ROAMING_STATE_T { -+ ROAMING_STATE_IDLE = 0, -+ ROAMING_STATE_DECISION, -+ ROAMING_STATE_DISCOVERY, -+ ROAMING_STATE_ROAM, -+ ROAMING_STATE_NUM -+} ENUM_ROAMING_STATE_T; -+ -+typedef struct _ROAMING_INFO_T { -+ BOOLEAN fgIsEnableRoaming; -+ -+ ENUM_ROAMING_STATE_T eCurrentState; -+ -+ OS_SYSTIME rRoamingDiscoveryUpdateTime; -+ -+#define ROAMING_ENTRY_TIMEOUT_SKIP_COUNT_MAX 2 -+ UINT_32 RoamingEntryTimeoutSkipCount; -+ -+} ROAMING_INFO_T, *P_ROAMING_INFO_T; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+#if CFG_SUPPORT_ROAMING -+#define IS_ROAMING_ACTIVE(prAdapter) \ -+ (prAdapter->rWifiVar.rRoamingInfo.eCurrentState == ROAMING_STATE_ROAM) -+#else -+#define IS_ROAMING_ACTIVE(prAdapter) FALSE -+#endif /* CFG_SUPPORT_ROAMING */ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+VOID roamingFsmInit(IN P_ADAPTER_T prAdapter); -+ -+VOID roamingFsmUninit(IN P_ADAPTER_T prAdapter); -+ -+VOID roamingFsmSendCmd(IN P_ADAPTER_T prAdapter, IN P_ROAMING_PARAM_T prParam); -+ -+VOID roamingFsmScanResultsUpdate(IN P_ADAPTER_T prAdapter); -+ -+VOID roamingFsmSteps(IN P_ADAPTER_T prAdapter, IN ENUM_ROAMING_STATE_T eNextState); -+ -+VOID roamingFsmRunEventStart(IN P_ADAPTER_T prAdapter); -+ -+VOID roamingFsmRunEventDiscovery(IN P_ADAPTER_T prAdapter, IN P_ROAMING_PARAM_T prParam); -+ -+VOID roamingFsmRunEventRoam(IN P_ADAPTER_T prAdapter); -+ -+VOID roamingFsmRunEventFail(IN P_ADAPTER_T prAdapter, IN UINT_32 u4Reason); -+ -+VOID roamingFsmRunEventAbort(IN P_ADAPTER_T prAdapter); -+ -+WLAN_STATUS roamingFsmProcessEvent(IN P_ADAPTER_T prAdapter, IN P_ROAMING_PARAM_T prParam); -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif /* _ROAMING_FSM_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rsn.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rsn.h -new file mode 100644 -index 000000000000..20ab14251f65 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rsn.h -@@ -0,0 +1,271 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/mgmt/rsn.h#1 -+*/ -+ -+/*! \file rsn.h -+ \brief The wpa/rsn related define, macro and structure are described here. -+*/ -+ -+/* -+** Log: rsn.h -+ * -+ * 10 12 2011 wh.su -+ * [WCXRP00001036] [MT6620 Wi-Fi][Driver][FW] Adding the 802.11w code for MFP -+ * adding the 802.11w related function and define . -+ * -+ * 06 22 2011 wh.su -+ * [WCXRP00000806] [MT6620 Wi-Fi][Driver] Move the WPA/RSN IE and WAPI IE structure to mac.h -+ * and let the sw structure not align at byte -+ * Move the WAPI/RSN IE to mac.h and SW structure not align to byte, -+ * Notice needed update P2P.ko. -+ * -+ * 03 17 2011 chinglan.wang -+ * [WCXRP00000570] [MT6620 Wi-Fi][Driver] Add Wi-Fi Protected Setup v2.0 feature -+ * . -+ * -+ * 02 09 2011 wh.su -+ * [WCXRP00000432] [MT6620 Wi-Fi][Driver] Add STA privacy check at hotspot mode -+ * adding the code for check STA privacy bit at AP mode, . -+ * -+ * 11 05 2010 wh.su -+ * [WCXRP00000165] [MT6620 Wi-Fi] [Pre-authentication] Assoc req rsn ie use wrong pmkid value -+ * fixed the.pmkid value mismatch issue -+ * -+ * 10 04 2010 wh.su -+ * [WCXRP00000081] [MT6620][Driver] Fix the compiling error at WinXP while enable P2P -+ * add a kal function for set cipher. -+ * -+ * 09 01 2010 wh.su -+ * NULL -+ * adding the wapi support for integration test. -+ * -+ * 08 30 2010 wh.su -+ * NULL -+ * remove non-used code. -+ * -+ * 08 19 2010 wh.su -+ * NULL -+ * adding the tx pkt call back handle for countermeasure. -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 18 2010 wh.su -+ * [WPD00003840][MT6620 5931] Security migration -+ * migration from MT6620 firmware. -+ * -+ * 03 03 2010 wh.su -+ * [BORA00000637][MT6620 Wi-Fi] [Bug] WPA2 pre-authentication timer not correctly initialize -+ * Fixed the pre-authentication timer not correctly init issue, and modify -+ * the security related callback function prototype. -+ * -+ * 01 27 2010 wh.su -+ * [BORA00000476][Wi-Fi][firmware] Add the security module initialize code -+ * add and fixed some security function. -+ * -+ * Dec 4 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * adjust the function prototype for generate wap/rsn ie -+ * -+ * Dec 3 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * adjust the function input parameter -+ * -+ * Dec 1 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * adding some event function declaration -+ * -+ * Nov 26 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * move the internal data structure for pmkid to rsn.h -+ * -+ * Nov 23 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * adding the port control and class error function -+ * -+ * Nov 19 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * adding the pmkid candidate -+ * -+ * Nov 18 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * -+** -+*/ -+ -+#ifndef _RSN_H -+#define _RSN_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+/* ----- Definitions for Cipher Suite Selectors ----- */ -+#define RSN_CIPHER_SUITE_USE_GROUP_KEY 0x00AC0F00 -+#define RSN_CIPHER_SUITE_WEP40 0x01AC0F00 -+#define RSN_CIPHER_SUITE_TKIP 0x02AC0F00 -+#define RSN_CIPHER_SUITE_CCMP 0x04AC0F00 -+#define RSN_CIPHER_SUITE_WEP104 0x05AC0F00 -+#if CFG_SUPPORT_802_11W -+#define RSN_CIPHER_SUITE_AES_128_CMAC 0x06AC0F00 -+#endif -+ -+#define WPA_CIPHER_SUITE_NONE 0x00F25000 -+#define WPA_CIPHER_SUITE_WEP40 0x01F25000 -+#define WPA_CIPHER_SUITE_TKIP 0x02F25000 -+#define WPA_CIPHER_SUITE_CCMP 0x04F25000 -+#define WPA_CIPHER_SUITE_WEP104 0x05F25000 -+ -+/* ----- Definitions for Authentication and Key Management Suite Selectors ----- */ -+#define RSN_AKM_SUITE_NONE 0x00AC0F00 -+#define RSN_AKM_SUITE_802_1X 0x01AC0F00 -+#define RSN_AKM_SUITE_PSK 0x02AC0F00 -+#if CFG_SUPPORT_802_11W -+#define RSN_AKM_SUITE_802_1X_SHA256 0x05AC0F00 -+#define RSN_AKM_SUITE_PSK_SHA256 0x06AC0F00 -+#endif -+ -+#define WPA_AKM_SUITE_NONE 0x00F25000 -+#define WPA_AKM_SUITE_802_1X 0x01F25000 -+#define WPA_AKM_SUITE_PSK 0x02F25000 -+ -+#define ELEM_ID_RSN_LEN_FIXED 20 /* The RSN IE len for associate request */ -+ -+#define ELEM_ID_WPA_LEN_FIXED 22 /* The RSN IE len for associate request */ -+ -+#define MASK_RSNIE_CAP_PREAUTH BIT(0) -+ -+#define GET_SELECTOR_TYPE(x) ((UINT_8)(((x) >> 24) & 0x000000FF)) -+#define SET_SELECTOR_TYPE(x, y) {x = (((x) & 0x00FFFFFF) | (((UINT_32)(y) << 24) & 0xFF000000))} -+ -+#define AUTH_CIPHER_CCMP 0x00000008 -+ -+/* Cihpher suite flags */ -+#define CIPHER_FLAG_NONE 0x00000000 -+#define CIPHER_FLAG_WEP40 0x00000001 /* BIT 1 */ -+#define CIPHER_FLAG_TKIP 0x00000002 /* BIT 2 */ -+#define CIPHER_FLAG_CCMP 0x00000008 /* BIT 4 */ -+#define CIPHER_FLAG_WEP104 0x00000010 /* BIT 5 */ -+#define CIPHER_FLAG_WEP128 0x00000020 /* BIT 6 */ -+ -+#define WAIT_TIME_IND_PMKID_CANDICATE_SEC 6 /* seconds */ -+#define TKIP_COUNTERMEASURE_SEC 60 /* seconds */ -+ -+#if CFG_SUPPORT_802_11W -+#define RSN_AUTH_MFP_DISABLED 0 /* MFP disabled */ -+#define RSN_AUTH_MFP_OPTIONAL 1 /* MFP optional */ -+#define RSN_AUTH_MFP_REQUIRED 2 /* MFP required */ -+#endif -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/* Flags for PMKID Candidate list structure */ -+#define EVENT_PMKID_CANDIDATE_PREAUTH_ENABLED 0x01 -+ -+#define CONTROL_FLAG_UC_MGMT_NO_ENC BIT(5) -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+#define RSN_IE(fp) ((P_RSN_INFO_ELEM_T) fp) -+#define WPA_IE(fp) ((P_WPA_INFO_ELEM_T) fp) -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+BOOLEAN rsnParseRsnIE(IN P_ADAPTER_T prAdapter, IN P_RSN_INFO_ELEM_T prInfoElem, OUT P_RSN_INFO_T prRsnInfo); -+ -+BOOLEAN rsnParseWpaIE(IN P_ADAPTER_T prAdapter, IN P_WPA_INFO_ELEM_T prInfoElem, OUT P_RSN_INFO_T prWpaInfo); -+ -+BOOLEAN rsnSearchSupportedCipher(IN P_ADAPTER_T prAdapter, IN UINT_32 u4Cipher, OUT PUINT_32 pu4Index); -+ -+BOOLEAN rsnSearchAKMSuite(IN P_ADAPTER_T prAdapter, IN UINT_32 u4AkmSuite, OUT PUINT_32 pu4Index); -+ -+BOOLEAN rsnPerformPolicySelection(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBss); -+ -+VOID rsnGenerateWpaNoneIE(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); -+ -+VOID rsnGenerateWPAIE(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); -+ -+VOID rsnGenerateRSNIE(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); -+ -+BOOLEAN -+rsnParseCheckForWFAInfoElem(IN P_ADAPTER_T prAdapter, -+ IN PUINT_8 pucBuf, OUT PUINT_8 pucOuiType, OUT PUINT_16 pu2SubTypeVersion); -+ -+BOOLEAN rsnIsSuitableBSS(IN P_ADAPTER_T prAdapter, IN P_RSN_INFO_T prBssRsnInfo); -+ -+#if CFG_SUPPORT_AAA -+void rsnParserCheckForRSNCCMPPSK(P_ADAPTER_T prAdapter, P_RSN_INFO_ELEM_T prIe, PUINT_16 pu2StatusCode); -+#endif -+ -+VOID rsnTkipHandleMICFailure(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta, IN BOOLEAN fgErrorKeyType); -+ -+VOID rsnSelectPmkidCandidateList(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBssDesc); -+ -+VOID rsnUpdatePmkidCandidateList(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBssDesc); -+ -+BOOLEAN rsnSearchPmkidEntry(IN P_ADAPTER_T prAdapter, IN PUINT_8 pucBssid, OUT PUINT_32 pu4EntryIndex); -+ -+BOOLEAN rsnCheckPmkidCandicate(IN P_ADAPTER_T prAdapter); -+ -+VOID rsnCheckPmkidCache(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBss); -+ -+VOID rsnGeneratePmkidIndication(IN P_ADAPTER_T prAdapter); -+ -+VOID rsnIndicatePmkidCand(IN P_ADAPTER_T prAdapter, IN ULONG ulParm); -+#if CFG_SUPPORT_WPS2 -+VOID rsnGenerateWSCIE(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); -+#endif -+ -+#if CFG_SUPPORT_802_11W -+UINT_32 rsnCheckBipKeyInstalled(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec); -+ -+UINT_8 rsnCheckSaQueryTimeout(IN P_ADAPTER_T prAdapter); -+ -+void rsnStartSaQueryTimer(IN P_ADAPTER_T prAdapter); -+ -+void rsnStartSaQuery(IN P_ADAPTER_T prAdapter); -+ -+void rsnStopSaQuery(IN P_ADAPTER_T prAdapter); -+ -+void rsnSaQueryRequest(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); -+ -+void rsnSaQueryAction(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); -+ -+BOOLEAN rsnCheckRxMgmt(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, IN UINT_8 ucSubtype); -+#endif -+BOOLEAN rsnCheckSecurityModeChanged(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo, P_BSS_DESC_T prBssDesc); -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif /* _RSN_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/scan.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/scan.h -new file mode 100644 -index 000000000000..c08b2244be6c ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/scan.h -@@ -0,0 +1,988 @@ -+/* -+** Id: @(#) -+*/ -+ -+/*! \file "scan.h" -+ \brief -+ -+*/ -+ -+/* -+** Log: scan.h -+ * -+ * 01 16 2012 cp.wu -+ * [MT6620 Wi-Fi][Driver] API and behavior modification for preferred band configuration -+ * with corresponding network configuration -+ * add wlanSetPreferBandByNetwork() for glue layer to invoke for setting -+ * preferred band configuration corresponding to network type. -+ * -+ * 08 11 2011 cp.wu -+ * [WCXRP00000830] [MT6620 Wi-Fi][Firmware] Use MDRDY counter to detect empty channel for shortening scan time -+ * sparse channel detection: -+ * driver: collect sparse channel information with scan-done event -+ * -+ * 07 18 2011 cp.wu -+ * [WCXRP00000858] [MT5931][Driver][Firmware] Add support for scan to search for more than one SSID -+ * in a single scanning request -+ * add framework in driver domain for supporting new SCAN_REQ_V2 for more than 1 SSID -+ * support as well as uProbeDelay in NDIS 6.x driver model -+ * -+ * 06 27 2011 cp.wu -+ * [WCXRP00000815] [MT6620 Wi-Fi][Driver] allow single BSSID with multiple SSID settings -+ * to work around some tricky AP which use space character as hidden SSID -+ * allow to have a single BSSID with multiple SSID to be presented in scanning result -+ * -+ * 04 18 2011 terry.wu -+ * [WCXRP00000660] [MT6620 Wi-Fi][Driver] Remove flag CFG_WIFI_DIRECT_MOVED -+ * Remove flag CFG_WIFI_DIRECT_MOVED. -+ * -+ * 02 09 2011 wh.su -+ * [WCXRP00000433] [MT6620 Wi-Fi][Driver] Remove WAPI structure define for avoid P2P module -+ * with structure miss-align pointer issue -+ * always pre-allio WAPI related structure for align p2p module. -+ * -+ * 01 14 2011 yuche.tsai -+ * [WCXRP00000352] [Volunteer Patch][MT6620][Driver] P2P Statsion Record Client List Issue -+ * Fix compile error. -+ * -+ * 09 08 2010 cp.wu -+ * NULL -+ * use static memory pool for storing IEs of scanning result. -+ * -+ * 09 03 2010 kevin.huang -+ * NULL -+ * Refine #include sequence and solve recursive/nested #include issue -+ * -+ * 08 31 2010 kevin.huang -+ * NULL -+ * Use LINK LIST operation to process SCAN result -+ * -+ * 08 30 2010 cp.wu -+ * NULL -+ * eliminate klockwork errors -+ * -+ * 08 16 2010 cp.wu -+ * NULL -+ * add interface for RLM to trigger OBSS-SCAN. -+ * -+ * 08 12 2010 yuche.tsai -+ * NULL -+ * Add a functio prototype to find p2p descriptor of a bss descriptor directly. -+ * -+ * 08 11 2010 yuche.tsai -+ * NULL -+ * Add function prototype for return channel. -+ * modify data structure for scan specific device ID or TYPE. (Move from P2P Connection Settings to Scan Param) -+ * -+ * 08 05 2010 yuche.tsai -+ * NULL -+ * Check-in P2P Device Discovery Feature. -+ * -+ * 08 02 2010 yuche.tsai -+ * NULL -+ * P2P Group Negotiation Code Check in. -+ * -+ * 07 26 2010 yuche.tsai -+ * -+ * Add a option for channel time extension in scan abort command. -+ * -+ * 07 21 2010 yuche.tsai -+ * -+ * Add for P2P Scan Result Parsing & Saving. -+ * -+ * 07 19 2010 yuche.tsai -+ * -+ * Scan status "FIND" is used for P2P FSM find state. -+ * -+ * 07 19 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration. -+ * SCN module is now able to handle multiple concurrent scanning requests -+ * -+ * 07 14 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration. -+ * pass band with channel number information as scan parameter -+ * -+ * 07 14 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration. -+ * remove timer in DRV-SCN. -+ * -+ * 07 09 2010 cp.wu -+ * -+ * 1) separate AIS_FSM state for two kinds of scanning. (OID triggered scan, and scan-for-connection) -+ * 2) eliminate PRE_BSS_DESC_T, Beacon/PrebResp is now parsed in single pass -+ * 3) implment DRV-SCN module, currently only accepts single scan request, other request -+ * will be directly dropped by returning BUSY -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 07 01 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add scan uninitialization procedure -+ * -+ * 07 01 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * implementation of DRV-SCN and related mailbox message handling. -+ * -+ * 06 25 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * modify Beacon/ProbeResp to complete parsing, -+ * because host software has looser memory usage restriction -+ * -+ * 06 17 2010 yuche.tsai -+ * [WPD00003839][MT6620 5931][P2P] Feature migration -+ * Add P2P related field in SCAN_PARAM_T. -+ * -+ * 06 14 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * saa_fsm.c is migrated. -+ * -+ * 06 14 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add management dispatching function table. -+ * -+ * 06 14 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * restore utility function invoking via hem_mbox to direct calls -+ * -+ * 06 11 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * auth.c is migrated. -+ * -+ * 06 10 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add buildable & linkable ais_fsm.c -+ * -+ * related reference are still waiting to be resolved -+ * -+ * 06 07 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add aa_fsm.h, ais_fsm.h, bss.h, mib.h and scan.h. -+ * -+ * 05 12 2010 kevin.huang -+ * [BORA00000794][WIFISYS][New Feature]Power Management Support -+ * Add Power Management - Legacy PS-POLL support. -+ * -+ * 04 13 2010 kevin.huang -+ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support -+ * -+ * Add new HW CH macro support -+ * -+ * 03 16 2010 kevin.huang -+ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support -+ * Add AdHoc Mode -+ * -+ * 03 10 2010 kevin.huang -+ * [BORA00000654][WIFISYS][New Feature] CNM Module - Ch Manager Support -+ * -+ * * * * * * Add Channel Manager for arbitration of JOIN and SCAN Req -+ * -+ * 02 26 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Modify scanBuildProbeReqFrameCommonIEs() to support P2P SCAN -+ * -+ * 02 23 2010 wh.su -+ * [BORA00000592][MT6620 Wi-Fi] Adding the security related code for driver -+ * refine the scan procedure, reduce the WPA and WAPI IE parsing, and move the parsing to the time for join. -+ * -+ * 02 23 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Add support scan channel 1~14 and update scan result's frequency infou1rwduu`wvpghlqg|n`slk+mpdkb -+ * -+ * 02 04 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Add AAA Module Support, Revise Net Type to Net Type Index for array lookup -+ * -+ * 01 27 2010 wh.su -+ * [BORA00000476][Wi-Fi][firmware] Add the security module initialize code -+ * add and fixed some security function. -+ * -+ * 01 07 2010 kevin.huang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * -+ * Simplify the process of Beacon during SCAN and remove redundant variable in PRE_BSS_DESC_T -+ * -+ * Dec 7 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * adding variable for wapi ap -+ * -+ * Dec 4 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * remove non-used secuirty variavle -+ * -+ * Dec 3 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Refine data structure of BSS_DESC_T and PRE_BSS_DESC_T -+ * -+ * Nov 24 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Add eNetType to rScanParam and revise MGMT Handler with Retain Status -+ * -+ * Nov 23 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Add ucAvailablePhyTypeSet to BSS_DESC_T -+ * -+ * Nov 20 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Add aucSrcAddress to SCAN_PARAM_T for P2P's Device Address -+ * -+ * Nov 19 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * adding the security related variable -+ * -+ * Nov 18 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * adding the security ie filed for scan parsing -+ * -+ * Nov 16 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Add scanSearchBssDescByPolicy() -+ * -+ * Nov 5 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Add function declarations of scan_fsm.c -+ * -+ * Oct 30 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Add scan.h to source control -+** -+*/ -+ -+#ifndef _SCAN_H -+#define _SCAN_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+#include "gl_vendor.h" -+ -+/* TDLS test purpose */ -+extern BOOLEAN flgTdlsTestExtCapElm; -+extern UINT8 aucTdlsTestExtCapElm[]; -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+/*! Maximum buffer size of SCAN list */ -+#define SCN_MAX_BUFFER_SIZE (CFG_MAX_NUM_BSS_LIST * ALIGN_4(sizeof(BSS_DESC_T))) -+ -+#define SCN_RM_POLICY_EXCLUDE_CONNECTED BIT(0) /* Remove SCAN result except the connected one. */ -+#define SCN_RM_POLICY_TIMEOUT BIT(1) /* Remove the timeout one */ -+#define SCN_RM_POLICY_OLDEST_HIDDEN BIT(2) /* Remove the oldest one with hidden ssid */ -+#define SCN_RM_POLICY_SMART_WEAKEST BIT(3) /* If there are more than half BSS which has the -+ * same ssid as connection setting, remove the -+ * weakest one from them -+ * Else remove the weakest one. -+ */ -+#define SCN_RM_POLICY_ENTIRE BIT(4) /* Remove entire SCAN result */ -+ -+#define SCN_BSS_DESC_SAME_SSID_THRESHOLD 3 /* This is used by POLICY SMART WEAKEST, -+ * If exceed this value, remove weakest BSS_DESC_T -+ * with same SSID first in large network. -+ */ -+ -+/* the scan time in WFD mode + 2.4G/5G is about 9s so we need to enlarge the value */ -+#define SCN_BSS_DESC_REMOVE_TIMEOUT_SEC 15 /* Second. */ -+ /* This is used by POLICY TIMEOUT, -+ * If exceed this value, remove timeout BSS_DESC_T. -+ */ -+ -+#define SCN_PROBE_DELAY_MSEC 0 -+ -+#define SCN_ADHOC_BSS_DESC_TIMEOUT_SEC 5 /* Second. */ -+ -+#define SCN_NLO_NETWORK_CHANNEL_NUM (4) -+ -+/*----------------------------------------------------------------------------*/ -+/* MSG_SCN_SCAN_REQ */ -+/*----------------------------------------------------------------------------*/ -+#define SCAN_REQ_SSID_WILDCARD BIT(0) -+#define SCAN_REQ_SSID_P2P_WILDCARD BIT(1) -+#define SCAN_REQ_SSID_SPECIFIED BIT(2) -+ -+/*----------------------------------------------------------------------------*/ -+/* Support Multiple SSID SCAN */ -+/*----------------------------------------------------------------------------*/ -+#define SCN_SSID_MAX_NUM CFG_SCAN_SSID_MAX_NUM -+#define SCN_SSID_MATCH_MAX_NUM CFG_SCAN_SSID_MATCH_MAX_NUM -+ -+#define SWC_NUM_BSSID_THRESHOLD_DEFAULT 8 -+#define SWC_RSSI_WINDSIZE_DEFAULT 8 -+#define LOST_AP_WINDOW 16 -+#define MAX_CHANNEL_NUM_PER_BUCKETS 8 -+ -+#define SCN_BSS_JOIN_FAIL_THRESOLD 4 -+#define SCN_BSS_JOIN_FAIL_CNT_RESET_SEC 15 -+#define SCN_BSS_JOIN_FAIL_RESET_STEP 2 -+ -+#if CFG_SUPPORT_BATCH_SCAN -+/*----------------------------------------------------------------------------*/ -+/* SCAN_BATCH_REQ */ -+/*----------------------------------------------------------------------------*/ -+#define SCAN_BATCH_REQ_START BIT(0) -+#define SCAN_BATCH_REQ_STOP BIT(1) -+#define SCAN_BATCH_REQ_RESULT BIT(2) -+#endif -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+typedef enum _ENUM_SCAN_TYPE_T { -+ SCAN_TYPE_PASSIVE_SCAN = 0, -+ SCAN_TYPE_ACTIVE_SCAN, -+ SCAN_TYPE_NUM -+} ENUM_SCAN_TYPE_T, *P_ENUM_SCAN_TYPE_T; -+ -+typedef enum _ENUM_SCAN_STATE_T { -+ SCAN_STATE_IDLE = 0, -+ SCAN_STATE_SCANNING, -+ SCAN_STATE_NUM -+} ENUM_SCAN_STATE_T; -+ -+typedef enum _ENUM_SCAN_CHANNEL_T { -+ SCAN_CHANNEL_FULL = 0, -+ SCAN_CHANNEL_2G4, -+ SCAN_CHANNEL_5G, -+ SCAN_CHANNEL_P2P_SOCIAL, -+ SCAN_CHANNEL_SPECIFIED, -+ SCAN_CHANNEL_NUM -+} ENUM_SCAN_CHANNEL, *P_ENUM_SCAN_CHANNEL; -+ -+typedef struct _MSG_SCN_FSM_T { -+ MSG_HDR_T rMsgHdr; /* Must be the first member */ -+ UINT_32 u4Dummy; -+} MSG_SCN_FSM_T, *P_MSG_SCN_FSM_T; -+ -+typedef enum _ENUM_PSCAN_STATE_T { -+ PSCN_IDLE = 1, -+ PSCN_SCANNING, -+ PSCN_RESET, -+ PSCAN_STATE_T_NUM -+} ENUM_PSCAN_STATE_T; -+ -+/*----------------------------------------------------------------------------*/ -+/* BSS Descriptors */ -+/*----------------------------------------------------------------------------*/ -+struct _BSS_DESC_T { -+ LINK_ENTRY_T rLinkEntry; -+ -+ UINT_8 aucBSSID[MAC_ADDR_LEN]; -+ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* For IBSS, the SrcAddr is different from BSSID */ -+ -+ BOOLEAN fgIsConnecting; /* If we are going to connect to this BSS -+ * (JOIN or ROAMING to another BSS), don't -+ * remove this record from BSS List. -+ */ -+ BOOLEAN fgIsConnected; /* If we have connected to this BSS (NORMAL_TR), -+ * don't removed this record from BSS list. -+ */ -+ -+ BOOLEAN fgIsHiddenSSID; /* When this flag is TRUE, means the SSID -+ * of this BSS is not known yet. -+ */ -+ UINT_8 ucSSIDLen; -+ UINT_8 aucSSID[ELEM_MAX_LEN_SSID]; -+ -+ OS_SYSTIME rUpdateTime; -+ -+ ENUM_BSS_TYPE_T eBSSType; -+ -+ UINT_16 u2CapInfo; -+ -+ UINT_16 u2BeaconInterval; -+ UINT_16 u2ATIMWindow; -+ -+ UINT_16 u2OperationalRateSet; -+ UINT_16 u2BSSBasicRateSet; -+ BOOLEAN fgIsUnknownBssBasicRate; -+ -+ BOOLEAN fgIsERPPresent; -+ BOOLEAN fgIsHTPresent; -+ -+ UINT_8 ucPhyTypeSet; /* Available PHY Type Set of this BSS */ -+ -+ UINT_8 ucChannelNum; -+ -+ ENUM_CHNL_EXT_T eSco; /* Record bandwidth for association process -+ Some AP will send association resp by 40MHz BW */ -+ ENUM_BAND_T eBand; -+ -+ UINT_8 ucDTIMPeriod; -+ -+ BOOLEAN fgIsLargerTSF; /* This BSS's TimeStamp is larger than us(TCL == 1 in RX_STATUS_T) */ -+ -+ UINT_8 ucRCPI; -+ -+ UINT_8 ucWmmFlag; /* A flag to indicate this BSS's WMM capability */ -+ -+ /*! \brief The srbiter Search State will matched the scan result, -+ and saved the selected cipher and akm, and report the score, -+ for arbiter join state, join module will carry this target BSS -+ to rsn generate ie function, for gen wpa/rsn ie */ -+ UINT_32 u4RsnSelectedGroupCipher; -+ UINT_32 u4RsnSelectedPairwiseCipher; -+ UINT_32 u4RsnSelectedAKMSuite; -+ -+ UINT_16 u2RsnCap; -+ -+ RSN_INFO_T rRSNInfo; -+ RSN_INFO_T rWPAInfo; -+#if 1 /* CFG_SUPPORT_WAPI */ -+ WAPI_INFO_T rIEWAPI; -+ BOOLEAN fgIEWAPI; -+#endif -+ BOOLEAN fgIERSN; -+ BOOLEAN fgIEWPA; -+ -+ /*! \brief RSN parameters selected for connection */ -+ /*! \brief The Select score for final AP selection, -+ 0, no sec, 1,2,3 group cipher is WEP, TKIP, CCMP */ -+ UINT_8 ucEncLevel; -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ BOOLEAN fgIsP2PPresent; -+ BOOLEAN fgIsP2PReport; /* TRUE: report to upper layer */ -+ P_P2P_DEVICE_DESC_T prP2pDesc; -+ -+ UINT_8 aucIntendIfAddr[MAC_ADDR_LEN]; /* For IBSS, the SrcAddr is different from BSSID */ -+/* UINT_8 ucDevCapabilityBitmap; */ /* Device Capability Attribute. (P2P_DEV_CAPABILITY_XXXX) */ -+/* UINT_8 ucGroupCapabilityBitmap; */ /* Group Capability Attribute. (P2P_GROUP_CAPABILITY_XXXX) */ -+ -+ LINK_T rP2pDeviceList; -+ -+/* P_LINK_T prP2pDeviceList; */ -+ -+ /* For -+ * 1. P2P Capability. -+ * 2. P2P Device ID. ( in aucSrcAddr[] ) -+ * 3. NOA (TODO:) -+ * 4. Extend Listen Timing. (Probe Rsp) (TODO:) -+ * 5. P2P Device Info. (Probe Rsp) -+ * 6. P2P Group Info. (Probe Rsp) -+ */ -+#endif -+ -+ BOOLEAN fgIsIEOverflow; /* The received IE length exceed the maximum IE buffer size */ -+ UINT_16 u2RawLength; /* The byte count of aucRawBuf[] */ -+ UINT_16 u2IELength; /* The byte count of aucIEBuf[] */ -+ -+ ULARGE_INTEGER u8TimeStamp; /* Place u8TimeStamp before aucIEBuf[1] to force DW align */ -+ UINT_8 aucRawBuf[CFG_RAW_BUFFER_SIZE]; -+ UINT_8 aucIEBuf[CFG_IE_BUFFER_SIZE]; -+ UINT_8 ucJoinFailureCount; -+ OS_SYSTIME rJoinFailTime; -+}; -+ -+typedef struct _SCAN_PARAM_T { /* Used by SCAN FSM */ -+ /* Active or Passive */ -+ ENUM_SCAN_TYPE_T eScanType; -+ -+ /* Network Type */ -+ ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex; -+ -+ /* Specified SSID Type */ -+ UINT_8 ucSSIDType; -+ UINT_8 ucSSIDNum; -+ -+ /* Length of Specified SSID */ -+ UINT_8 ucSpecifiedSSIDLen[SCN_SSID_MAX_NUM]; -+ -+ /* Specified SSID */ -+ UINT_8 aucSpecifiedSSID[SCN_SSID_MAX_NUM][ELEM_MAX_LEN_SSID]; -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ BOOLEAN fgFindSpecificDev; /* P2P: Discovery Protocol */ -+ UINT_8 aucDiscoverDevAddr[MAC_ADDR_LEN]; -+ BOOLEAN fgIsDevType; -+ P2P_DEVICE_TYPE_T rDiscoverDevType; -+ -+ UINT_16 u2PassiveListenInterval; -+ /* TODO: Find Specific Device Type. */ -+#endif /* CFG_SUPPORT_P2P */ -+ -+ BOOLEAN fgIsObssScan; -+ BOOLEAN fgIsScanV2; -+ -+ /* Run time flags */ -+ UINT_16 u2ProbeDelayTime; -+ -+ /* channel information */ -+ ENUM_SCAN_CHANNEL eScanChannel; -+ UINT_8 ucChannelListNum; -+ RF_CHANNEL_INFO_T arChnlInfoList[MAXIMUM_OPERATION_CHANNEL_LIST]; -+ -+ /* Feedback information */ -+ UINT_8 ucSeqNum; -+ -+ /* Information Element */ -+ UINT_16 u2IELen; -+ UINT_8 aucIE[MAX_IE_LENGTH]; -+ -+} SCAN_PARAM_T, *P_SCAN_PARAM_T; -+ -+typedef struct _NLO_PARAM_T { /* Used by SCAN FSM */ -+ SCAN_PARAM_T rScanParam; -+ -+ /* NLO */ -+ BOOLEAN fgStopAfterIndication; -+ UINT_8 ucFastScanIteration; -+ UINT_16 u2FastScanPeriod; -+ UINT_16 u2SlowScanPeriod; -+ -+ /* Match SSID */ -+ UINT_8 ucMatchSSIDNum; -+ UINT_8 ucMatchSSIDLen[SCN_SSID_MATCH_MAX_NUM]; -+ UINT_8 aucMatchSSID[SCN_SSID_MATCH_MAX_NUM][ELEM_MAX_LEN_SSID]; -+ -+ UINT_8 aucCipherAlgo[SCN_SSID_MATCH_MAX_NUM]; -+ UINT_16 au2AuthAlgo[SCN_SSID_MATCH_MAX_NUM]; -+ UINT_8 aucChannelHint[SCN_SSID_MATCH_MAX_NUM][SCN_NLO_NETWORK_CHANNEL_NUM]; -+ P_BSS_DESC_T aprPendingBssDescToInd[SCN_SSID_MATCH_MAX_NUM]; -+} NLO_PARAM_T, *P_NLO_PARAM_T; -+ -+#if 1 -+ -+typedef struct _GSCN_CHANNEL_INFO_T { -+ UINT_8 ucBand; -+ UINT_8 ucChannel; /* frequency */ -+ UINT_8 ucPassive; /* 0 => active, 1 => passive scan; ignored for DFS */ -+ UINT_8 aucReserved[1]; -+ -+ UINT_32 u4DwellTimeMs; /* dwell time hint */ -+ /* Add channel class */ -+} GSCN_CHANNEL_INFO_T, *P_GSCN_CHANNEL_INFO_T; -+ -+typedef struct _GSCAN_CHANNEL_BUCKET_T { -+ -+ UINT_16 u2BucketIndex; /* bucket index, 0 based */ -+ UINT_8 ucBucketFreqMultiple; /* desired period, in millisecond; -+ * if this is too low, the firmware should choose to generate -+ * results as fast as it can instead of failing the command */ -+ /* report_events semantics - -+ * 0 => report only when scan history is % full -+ * 1 => same as 0 + report a scan completion event after scanning this bucket -+ * 2 => same as 1 + forward scan results (beacons/probe responses + IEs) in real time to HAL -+ * 3 => same as 2 + forward scan results (beacons/probe responses + IEs) in real time to -+ supplicant as well (optional) . */ -+ UINT_8 ucReportFlag; -+ UINT_8 ucNumChannels; -+ UINT_8 aucReserved[3]; -+ WIFI_BAND eBand; /* when UNSPECIFIED, use channel list */ -+ GSCN_CHANNEL_INFO_T arChannelList[GSCAN_MAX_CHANNELS]; /* channels to scan; these may include DFS channels */ -+} GSCAN_CHANNEL_BUCKET_T, *P_GSCAN_CHANNEL_BUCKET_T; -+ -+typedef struct _CMD_GSCN_REQ_T { -+ UINT_8 ucFlags; -+ UINT_8 ucNumScnToCache; -+ UINT_8 aucReserved[2]; -+ UINT_32 u4BufferThreshold; -+ UINT_32 u4BasePeriod; /* base timer period in ms */ -+ UINT_32 u4NumBuckets; -+ UINT_32 u4MaxApPerScan; /* number of APs to store in each scan in the */ -+ /* BSSID/RSSI history buffer (keep the highest RSSI APs) */ -+ -+ GSCAN_CHANNEL_BUCKET_T arChannelBucket[GSCAN_MAX_BUCKETS]; -+} CMD_GSCN_REQ_T, *P_CMD_GSCN_REQ_T; -+ -+#endif -+ -+typedef struct _CMD_GSCN_SCN_COFIG_T { -+ UINT_8 ucNumApPerScn; /* GSCAN_ATTRIBUTE_NUM_AP_PER_SCAN */ -+ UINT_32 u4NumScnToCache; /* GSCAN_ATTRIBUTE_NUM_SCANS_TO_CACHE */ -+ UINT_32 u4BufferThreshold; /* GSCAN_ATTRIBUTE_REPORT_THRESHOLD */ -+} CMD_GSCN_SCN_COFIG_T, *P_CMD_GSCN_SCN_COFIG_T; -+ -+typedef struct _CMD_GET_GSCAN_RESULT { -+ UINT_8 ucVersion; -+ UINT_8 aucReserved[2]; -+ UINT_8 ucFlush; -+ UINT_32 u4Num; -+} CMD_GET_GSCAN_RESULT_T, *P_CMD_GET_GSCAN_RESULT_T; -+ -+typedef struct _CMD_BATCH_REQ_T { -+ UINT_8 ucSeqNum; -+ UINT_8 ucNetTypeIndex; -+ UINT_8 ucCmd; /* Start/ Stop */ -+ UINT_8 ucMScan; /* an integer number of scans per batch */ -+ UINT_8 ucBestn; /* an integer number of the max AP to remember per scan */ -+ UINT_8 ucRtt; /* an integer number of highest-strength AP for which we'd like -+ approximate distance reported */ -+ UINT_8 ucChannel; /* channels */ -+ UINT_8 ucChannelType; -+ UINT_8 ucChannelListNum; -+ UINT_8 aucReserved[3]; -+ UINT_32 u4Scanfreq; /* an integer number of seconds between scans */ -+ CHANNEL_INFO_T arChannelList[32]; /* channels */ -+} CMD_BATCH_REQ_T, *P_CMD_BATCH_REQ_T; -+ -+typedef struct _PSCN_PARAM_T { -+ UINT_8 ucVersion; -+ CMD_NLO_REQ rCurrentCmdNloReq; -+ CMD_BATCH_REQ_T rCurrentCmdBatchReq; -+ CMD_GSCN_REQ_T rCurrentCmdGscnReq; -+ BOOLEAN fgNLOScnEnable; -+ BOOLEAN fgBatchScnEnable; -+ BOOLEAN fgGScnEnable; -+ UINT_32 u4BasePeriod; /* GSCAN_ATTRIBUTE_BASE_PERIOD */ -+} PSCN_PARAM_T, *P_PSCN_PARAM_T; -+ -+typedef struct _SCAN_INFO_T { -+ ENUM_SCAN_STATE_T eCurrentState; /* Store the STATE variable of SCAN FSM */ -+ -+ OS_SYSTIME rLastScanCompletedTime; -+ -+ SCAN_PARAM_T rScanParam; -+ NLO_PARAM_T rNloParam; -+ -+ UINT_32 u4NumOfBssDesc; -+ -+ UINT_8 aucScanBuffer[SCN_MAX_BUFFER_SIZE]; -+ -+ LINK_T rBSSDescList; -+ -+ LINK_T rFreeBSSDescList; -+ -+ LINK_T rPendingMsgList; -+ -+ /* Sparse Channel Detection */ -+ BOOLEAN fgIsSparseChannelValid; -+ RF_CHANNEL_INFO_T rSparseChannel; -+ -+ /* NLO scanning state tracking */ -+ BOOLEAN fgNloScanning; -+ BOOLEAN fgPscnOnnning; -+ BOOLEAN fgGScnConfigSet; -+ BOOLEAN fgGScnParamSet; -+ P_PSCN_PARAM_T prPscnParam; -+ ENUM_PSCAN_STATE_T eCurrentPSCNState; -+ -+} SCAN_INFO_T, *P_SCAN_INFO_T; -+ -+/* Incoming Mailbox Messages */ -+typedef struct _MSG_SCN_SCAN_REQ_T { -+ MSG_HDR_T rMsgHdr; /* Must be the first member */ -+ UINT_8 ucSeqNum; -+ UINT_8 ucNetTypeIndex; -+ ENUM_SCAN_TYPE_T eScanType; -+ UINT_8 ucSSIDType; /* BIT(0) wildcard / BIT(1) P2P-wildcard / BIT(2) specific */ -+ UINT_8 ucSSIDLength; -+ UINT_8 aucSSID[PARAM_MAX_LEN_SSID]; -+#if CFG_ENABLE_WIFI_DIRECT -+ UINT_16 u2ChannelDwellTime; /* In TU. 1024us. */ -+#endif -+ ENUM_SCAN_CHANNEL eScanChannel; -+ UINT_8 ucChannelListNum; -+ RF_CHANNEL_INFO_T arChnlInfoList[MAXIMUM_OPERATION_CHANNEL_LIST]; -+ UINT_16 u2IELen; -+ UINT_8 aucIE[MAX_IE_LENGTH]; -+} MSG_SCN_SCAN_REQ, *P_MSG_SCN_SCAN_REQ; -+ -+typedef struct _MSG_SCN_SCAN_REQ_V2_T { -+ MSG_HDR_T rMsgHdr; /* Must be the first member */ -+ UINT_8 ucSeqNum; -+ UINT_8 ucNetTypeIndex; -+ ENUM_SCAN_TYPE_T eScanType; -+ UINT_8 ucSSIDType; /* BIT(0) wildcard / BIT(1) P2P-wildcard / BIT(2) specific */ -+ UINT_8 ucSSIDNum; -+ P_PARAM_SSID_T prSsid; -+ UINT_16 u2ProbeDelay; -+ UINT_16 u2ChannelDwellTime; /* In TU. 1024us. */ -+ ENUM_SCAN_CHANNEL eScanChannel; -+ UINT_8 ucChannelListNum; -+ RF_CHANNEL_INFO_T arChnlInfoList[MAXIMUM_OPERATION_CHANNEL_LIST]; -+ UINT_16 u2IELen; -+ UINT_8 aucIE[MAX_IE_LENGTH]; -+} MSG_SCN_SCAN_REQ_V2, *P_MSG_SCN_SCAN_REQ_V2; -+ -+typedef struct _MSG_SCN_SCAN_CANCEL_T { -+ MSG_HDR_T rMsgHdr; /* Must be the first member */ -+ UINT_8 ucSeqNum; -+ UINT_8 ucNetTypeIndex; -+#if CFG_ENABLE_WIFI_DIRECT -+ BOOLEAN fgIsChannelExt; -+#endif -+} MSG_SCN_SCAN_CANCEL, *P_MSG_SCN_SCAN_CANCEL; -+ -+/* Outgoing Mailbox Messages */ -+typedef enum _ENUM_SCAN_STATUS_T { -+ SCAN_STATUS_DONE = 0, -+ SCAN_STATUS_CANCELLED, -+ SCAN_STATUS_FAIL, -+ SCAN_STATUS_BUSY, -+ SCAN_STATUS_NUM -+} ENUM_SCAN_STATUS, *P_ENUM_SCAN_STATUS; -+ -+typedef struct _MSG_SCN_SCAN_DONE_T { -+ MSG_HDR_T rMsgHdr; /* Must be the first member */ -+ UINT_8 ucSeqNum; -+ UINT_8 ucNetTypeIndex; -+ ENUM_SCAN_STATUS eScanStatus; -+} MSG_SCN_SCAN_DONE, *P_MSG_SCN_SCAN_DONE; -+ -+#if CFG_SUPPORT_AGPS_ASSIST -+typedef enum { -+ AGPS_PHY_A, -+ AGPS_PHY_B, -+ AGPS_PHY_G, -+} AP_PHY_TYPE; -+ -+typedef struct _AGPS_AP_INFO_T { -+ UINT_8 aucBSSID[6]; -+ INT_16 i2ApRssi; /* -127..128 */ -+ UINT_16 u2Channel; /* 0..256 */ -+ AP_PHY_TYPE ePhyType; -+} AGPS_AP_INFO_T, *P_AGPS_AP_INFO_T; -+ -+typedef struct _AGPS_AP_LIST_T { -+ UINT_8 ucNum; -+ AGPS_AP_INFO_T arApInfo[32]; -+} AGPS_AP_LIST_T, *P_AGPS_AP_LIST_T; -+#endif -+ -+typedef struct _CMD_SET_PSCAN_PARAM { -+ UINT_8 ucVersion; -+ CMD_NLO_REQ rCmdNloReq; -+ CMD_BATCH_REQ_T rCmdBatchReq; -+ CMD_GSCN_REQ_T rCmdGscnReq; -+ BOOLEAN fgNLOScnEnable; -+ BOOLEAN fgBatchScnEnable; -+ BOOLEAN fgGScnEnable; -+ UINT_32 u4BasePeriod; -+} CMD_SET_PSCAN_PARAM, *P_CMD_SET_PSCAN_PARAM; -+ -+typedef struct _CMD_SET_PSCAN_ADD_HOTLIST_BSSID { -+ UINT_8 aucMacAddr[6]; -+ UINT_8 ucFlags; -+ UINT_8 aucReserved[5]; -+} CMD_SET_PSCAN_ADD_HOTLIST_BSSID, *P_CMD_SET_PSCAN_ADD_HOTLIST_BSSID; -+ -+typedef struct _CMD_SET_PSCAN_ADD_SWC_BSSID { -+ INT_32 i4RssiLowThreshold; -+ INT_32 i4RssiHighThreshold; -+ UINT_8 aucMacAddr[6]; -+ UINT_8 aucReserved[6]; -+} CMD_SET_PSCAN_ADD_SWC_BSSID, *P_CMD_SET_PSCAN_ADD_SWC_BSSID; -+ -+typedef struct _CMD_SET_PSCAN_MAC_ADDR { -+ UINT_8 ucVersion; -+ UINT_8 ucFlags; -+ UINT_8 aucMacAddr[6]; -+ UINT_8 aucReserved[8]; -+} CMD_SET_PSCAN_MAC_ADDR, *P_CMD_SET_PSCAN_MAC_ADDR; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+/*----------------------------------------------------------------------------*/ -+/* Routines in scan.c */ -+/*----------------------------------------------------------------------------*/ -+VOID scnInit(IN P_ADAPTER_T prAdapter); -+ -+VOID scnUninit(IN P_ADAPTER_T prAdapter); -+ -+/* BSS-DESC Search */ -+P_BSS_DESC_T scanSearchBssDescByBssid(IN P_ADAPTER_T prAdapter, IN UINT_8 aucBSSID[]); -+ -+P_BSS_DESC_T -+scanSearchBssDescByBssidAndSsid(IN P_ADAPTER_T prAdapter, -+ IN UINT_8 aucBSSID[], IN BOOLEAN fgCheckSsid, IN P_PARAM_SSID_T prSsid); -+ -+P_BSS_DESC_T scanSearchBssDescByTA(IN P_ADAPTER_T prAdapter, IN UINT_8 aucSrcAddr[]); -+ -+P_BSS_DESC_T -+scanSearchBssDescByTAAndSsid(IN P_ADAPTER_T prAdapter, -+ IN UINT_8 aucSrcAddr[], IN BOOLEAN fgCheckSsid, IN P_PARAM_SSID_T prSsid); -+ -+#if CFG_SUPPORT_HOTSPOT_2_0 -+P_BSS_DESC_T scanSearchBssDescByBssidAndLatestUpdateTime(IN P_ADAPTER_T prAdapter, IN UINT_8 aucBSSID[]); -+#endif -+ -+/* BSS-DESC Search - Alternative */ -+P_BSS_DESC_T -+scanSearchExistingBssDesc(IN P_ADAPTER_T prAdapter, -+ IN ENUM_BSS_TYPE_T eBSSType, IN UINT_8 aucBSSID[], IN UINT_8 aucSrcAddr[]); -+ -+P_BSS_DESC_T -+scanSearchExistingBssDescWithSsid(IN P_ADAPTER_T prAdapter, -+ IN ENUM_BSS_TYPE_T eBSSType, -+ IN UINT_8 aucBSSID[], -+ IN UINT_8 aucSrcAddr[], IN BOOLEAN fgCheckSsid, IN P_PARAM_SSID_T prSsid); -+ -+/* BSS-DESC Allocation */ -+P_BSS_DESC_T scanAllocateBssDesc(IN P_ADAPTER_T prAdapter); -+ -+/* BSS-DESC Removal */ -+VOID scanRemoveBssDescsByPolicy(IN P_ADAPTER_T prAdapter, IN UINT_32 u4RemovePolicy); -+ -+VOID scanRemoveBssDescByBssid(IN P_ADAPTER_T prAdapter, IN UINT_8 aucBSSID[]); -+ -+VOID -+scanRemoveBssDescByBandAndNetwork(IN P_ADAPTER_T prAdapter, -+ IN ENUM_BAND_T eBand, IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex); -+ -+/* BSS-DESC State Change */ -+VOID scanRemoveConnFlagOfBssDescByBssid(IN P_ADAPTER_T prAdapter, IN UINT_8 aucBSSID[]); -+ -+#if 0 -+/* BSS-DESC Insertion */ -+P_BSS_DESC_T scanAddToInternalScanResult(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSWRfb, IN P_BSS_DESC_T prBssDesc); -+#endif -+ -+/* BSS-DESC Insertion - ALTERNATIVE */ -+P_BSS_DESC_T scanAddToBssDesc(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); -+ -+WLAN_STATUS scanProcessBeaconAndProbeResp(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSWRfb); -+ -+VOID -+scanBuildProbeReqFrameCommonIEs(IN P_MSDU_INFO_T prMsduInfo, -+ IN PUINT_8 pucDesiredSsid, IN UINT_32 u4DesiredSsidLen, IN UINT_16 u2SupportedRateSet); -+ -+WLAN_STATUS scanSendProbeReqFrames(IN P_ADAPTER_T prAdapter, IN P_SCAN_PARAM_T prScanParam); -+ -+VOID scanUpdateBssDescForSearch(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBssDesc); -+ -+P_BSS_DESC_T scanSearchBssDescByPolicy(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex); -+ -+WLAN_STATUS scanAddScanResult(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBssDesc, IN P_SW_RFB_T prSwRfb); -+ -+VOID scanReportBss2Cfg80211(IN P_ADAPTER_T prAdapter, IN ENUM_BSS_TYPE_T eBSSType, IN P_BSS_DESC_T SpecificprBssDesc); -+ -+/*----------------------------------------------------------------------------*/ -+/* Routines in scan_fsm.c */ -+/*----------------------------------------------------------------------------*/ -+VOID scnFsmSteps(IN P_ADAPTER_T prAdapter, IN ENUM_SCAN_STATE_T eNextState); -+ -+/*----------------------------------------------------------------------------*/ -+/* Command Routines */ -+/*----------------------------------------------------------------------------*/ -+VOID scnSendScanReqExtCh(IN P_ADAPTER_T prAdapter); -+ -+VOID scnSendScanReq(IN P_ADAPTER_T prAdapter); -+ -+VOID scnSendScanReqV2ExtCh(IN P_ADAPTER_T prAdapter); -+ -+VOID scnSendScanReqV2(IN P_ADAPTER_T prAdapter); -+ -+/*----------------------------------------------------------------------------*/ -+/* RX Event Handling */ -+/*----------------------------------------------------------------------------*/ -+VOID scnEventScanDone(IN P_ADAPTER_T prAdapter, IN P_EVENT_SCAN_DONE prScanDone); -+ -+VOID scnEventNloDone(IN P_ADAPTER_T prAdapter, IN P_EVENT_NLO_DONE_T prNloDone); -+ -+/*----------------------------------------------------------------------------*/ -+/* Mailbox Message Handling */ -+/*----------------------------------------------------------------------------*/ -+VOID scnFsmMsgStart(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); -+ -+VOID scnFsmMsgAbort(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); -+ -+VOID scnFsmHandleScanMsg(IN P_ADAPTER_T prAdapter, IN P_MSG_SCN_SCAN_REQ prScanReqMsg); -+ -+VOID scnFsmHandleScanMsgV2(IN P_ADAPTER_T prAdapter, IN P_MSG_SCN_SCAN_REQ_V2 prScanReqMsg); -+ -+VOID scnFsmRemovePendingMsg(IN P_ADAPTER_T prAdapter, IN UINT_8 ucSeqNum, IN UINT_8 ucNetTypeIndex); -+ -+/*----------------------------------------------------------------------------*/ -+/* Mailbox Message Generation */ -+/*----------------------------------------------------------------------------*/ -+VOID -+scnFsmGenerateScanDoneMsg(IN P_ADAPTER_T prAdapter, -+ IN UINT_8 ucSeqNum, IN UINT_8 ucNetTypeIndex, IN ENUM_SCAN_STATUS eScanStatus); -+ -+/*----------------------------------------------------------------------------*/ -+/* Query for sparse channel */ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN scnQuerySparseChannel(IN P_ADAPTER_T prAdapter, P_ENUM_BAND_T prSparseBand, PUINT_8 pucSparseChannel); -+ -+/*----------------------------------------------------------------------------*/ -+/* OID/IOCTL Handling */ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN -+scnFsmSchedScanRequest(IN P_ADAPTER_T prAdapter, -+ IN UINT_8 ucSsidNum, -+ IN P_PARAM_SSID_T prSsid, IN UINT_32 u4IeLength, IN PUINT_8 pucIe, IN UINT_16 u2Interval); -+ -+BOOLEAN scnFsmSchedScanStopRequest(IN P_ADAPTER_T prAdapter); -+ -+BOOLEAN scnFsmPSCNAction(IN P_ADAPTER_T prAdapter, IN UINT_8 ucPscanAct); -+ -+BOOLEAN scnFsmPSCNSetParam(IN P_ADAPTER_T prAdapter, IN P_CMD_SET_PSCAN_PARAM prCmdPscnParam); -+ -+BOOLEAN scnFsmGSCNSetHotlist(IN P_ADAPTER_T prAdapter, IN P_CMD_SET_PSCAN_PARAM prCmdPscnParam); -+ -+#if 0 -+ -+BOOLEAN scnFsmGSCNSetRssiSignificatn(IN P_ADAPTER_T prAdapter, IN P_CMD_SET_PSCAN_PARAM prCmdPscnParam); -+#endif -+ -+BOOLEAN scnFsmPSCNAddSWCBssId(IN P_ADAPTER_T prAdapter, IN P_CMD_SET_PSCAN_ADD_SWC_BSSID prCmdPscnAddSWCBssId); -+ -+BOOLEAN scnFsmPSCNSetMacAddr(IN P_ADAPTER_T prAdapter, IN P_CMD_SET_PSCAN_MAC_ADDR prCmdPscnSetMacAddr); -+ -+#if 1 /* CFG_SUPPORT_GSCN_NONSYNC_BROADCOM */ -+BOOLEAN scnSetGSCNParam(IN P_ADAPTER_T prAdapter, IN P_PARAM_WIFI_GSCAN_CMD_PARAMS prCmdGscnParam); -+ -+#else -+BOOLEAN scnSetGSCNParam(IN P_ADAPTER_T prAdapter, IN P_CMD_GSCN_REQ_T prCmdGscnParam); -+ -+#endif -+ -+BOOLEAN -+scnCombineParamsIntoPSCN(IN P_ADAPTER_T prAdapter, -+ IN P_CMD_NLO_REQ prCmdNloReq, -+ IN P_CMD_BATCH_REQ_T prCmdBatchReq, -+ IN P_CMD_GSCN_REQ_T prCmdGscnReq, -+ IN P_CMD_GSCN_SCN_COFIG_T prNewCmdGscnConfig, -+ IN BOOLEAN fgRemoveNLOfromPSCN, -+ IN BOOLEAN fgRemoveBatchSCNfromPSCN, IN BOOLEAN fgRemoveGSCNfromPSCN); -+ -+BOOLEAN scnFsmSetGSCNConfig(IN P_ADAPTER_T prAdapter, IN P_CMD_GSCN_SCN_COFIG_T prCmdGscnScnConfig); -+ -+BOOLEAN scnFsmGetGSCNResult(IN P_ADAPTER_T prAdapter, IN P_CMD_GET_GSCAN_RESULT_T prGetGscnScnResultCmd); -+ -+VOID -+scnPSCNFsm(IN P_ADAPTER_T prAdapter, -+ ENUM_PSCAN_STATE_T eNextPSCNState, -+ IN P_CMD_NLO_REQ prCmdNloReq, -+ IN P_CMD_BATCH_REQ_T prCmdBatchReq, -+ IN P_CMD_GSCN_REQ_T prCmdGscnReq, -+ IN P_CMD_GSCN_SCN_COFIG_T prNewCmdGscnConfig, -+ IN BOOLEAN fgRemoveNLOfromPSCN, -+ IN BOOLEAN fgRemoveBatchSCNfromPSCN, IN BOOLEAN fgRemoveGSCNfromPSCN, IN BOOLEAN fgEnableGSCN); -+ -+#endif /* _SCAN_H */ -+ -+#if CFG_SUPPORT_AGPS_ASSIST -+VOID scanReportScanResultToAgps(P_ADAPTER_T prAdapter); -+#endif -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/sec_fsm.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/sec_fsm.h -new file mode 100644 -index 000000000000..c6c468e06c4a ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/sec_fsm.h -@@ -0,0 +1,233 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/mgmt/sec_fsm.h#1 -+*/ -+ -+/*! \file sec_fsm.h -+ \brief Declaration of functions and finite state machine for SECURITY Module. -+ -+ Function declaration for privacy.c and SEC_STATE for SECURITY FSM. -+*/ -+ -+/* -+** Log: sec_fsm.h -+ * -+ * 09 29 2010 wh.su -+ * [WCXRP00000072] [MT6620 Wi-Fi][Driver] Fix TKIP Counter Measure EAPoL callback register issue -+ * [MT6620 Wi-Fi][Driver] Fix TKIP Counter Measure EAPoL callback register issue. -+ * -+ * 09 21 2010 kevin.huang -+ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning -+ * Eliminate Linux Compile Warning -+ * -+ * 09 03 2010 kevin.huang -+ * NULL -+ * Refine #include sequence and solve recursive/nested #include issue -+ * -+ * 08 20 2010 wh.su -+ * NULL -+ * adding the eapol callback setting. -+ * -+ * 08 19 2010 wh.su -+ * NULL -+ * adding the tx pkt call back handle for countermeasure. -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 21 2010 wh.su -+ * [WPD00003840][MT6620 5931] Security migration -+ * modify some code for concurrent network. -+ * -+ * 06 19 2010 wh.su -+ * [WPD00003840][MT6620 5931] Security migration -+ * consdier the concurrent network setting. -+ * -+ * 03 04 2010 wh.su -+ * [BORA00000605][WIFISYS] Phase3 Integration -+ * Code refine, and remove non-used code. -+ * -+ * 03 03 2010 wh.su -+ * [BORA00000637][MT6620 Wi-Fi] [Bug] WPA2 pre-authentication timer not correctly initialize -+ * Fixed the pre-authentication timer not correctly init issue, and modify the security -+ * related callback function prototype. -+ * -+ * 03 01 2010 wh.su -+ * [BORA00000605][WIFISYS] Phase3 Integration -+ * Refine the variable and parameter for security. -+ * -+ * 12 18 2009 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * . -+ * -+ * Dec 7 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * fixed the deauth Tx done callback parameter -+ * -+ * Dec 4 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * adding the reference function declaration -+ * -+ * Dec 3 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * delete non-used code -+ * -+ * Dec 1 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * adjust the function prototype -+ * -+ * Nov 23 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * adjust the function declaration -+ * -+ * Nov 19 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * adding the security variable -+ * -+ * Nov 18 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * -+** \main\maintrunk.MT5921\14 2009-04-06 15:35:47 GMT mtk01088 -+** add the variable to set the disable AP selection for privacy check, for wps open networking. -+** \main\maintrunk.MT5921\13 2008-11-19 11:46:01 GMT mtk01088 -+** rename some variable with pre-fix to avoid the misunderstanding -+** \main\maintrunk.MT5921\12 2008-08-28 20:37:11 GMT mtk01088 -+** remove non-used code -+** -+** \main\maintrunk.MT5921\11 2008-03-18 09:51:52 GMT mtk01088 -+** Add function declaration for timer to indicate pmkid candidate -+** \main\maintrunk.MT5921\10 2008-02-29 15:12:08 GMT mtk01088 -+** add variable for sw port control -+** \main\maintrunk.MT5921\9 2008-02-29 12:37:30 GMT mtk01088 -+** rename the security related function declaration -+** \main\maintrunk.MT5921\8 2007-12-27 13:59:08 GMT mtk01088 -+** adjust the wlan table and sec fsm init timing -+** \main\maintrunk.MT5921\7 2007-11-20 10:39:49 GMT mtk01088 -+** add function timer for wait EAPoL Error timeout -+** \main\maintrunk.MT5921\6 2007-11-06 20:39:08 GMT mtk01088 -+** rename the counter measure timer -+** \main\maintrunk.MT5921\5 2007-11-06 20:14:31 GMT mtk01088 -+** add a abort function -+** Revision 1.5 2007/07/16 02:33:42 MTK01088 -+** change the ENUM declaration structure prefix from r to e -+** -+** Revision 1.4 2007/07/09 06:23:10 MTK01088 -+** update -+** -+** Revision 1.3 2007/07/04 10:09:04 MTK01088 -+** adjust the state for security fsm -+** change function name -+** -+** Revision 1.2 2007/07/03 08:13:22 MTK01088 -+** change the sec fsm state -+** add the event for sec fsm -+** -+** Revision 1.1 2007/06/27 06:20:35 MTK01088 -+** add the sec fsm header file -+** -+** -+*/ -+#ifndef _SEC_FSM_H -+#define _SEC_FSM_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/* TKIP CounterMeasure interval for Rejoin to Network. */ -+#define COUNTER_MEASURE_TIMEOUT_INTERVAL_SEC 60 -+ -+/* Timeout to wait the EAPoL Error Report frame Send out. */ -+#define EAPOL_REPORT_SEND_TIMEOUT_INTERVAL_SEC 1 -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+typedef UINT_32 SEC_STATUS, *P_SEC_STATUS; -+ -+#if 0 -+/* WPA2 PMKID candicate structure */ -+typedef struct _PMKID_CANDICATE_T { -+ UINT_8 aucBssid[MAC_ADDR_LEN]; /* MAC address */ -+ UINT_32 u4PreAuthFlags; -+} PMKID_CANDICATE_T, *P_PMKID_CANDICATE_T; -+#endif -+ -+typedef SEC_STATUS(*PFN_SEC_FSM_STATE_HANDLER) (VOID); -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+#define SEC_STATE_TRANSITION_FLAG fgIsTransition -+#define SEC_NEXT_STATE_VAR eNextState -+ -+#define SEC_STATE_TRANSITION(prAdapter, prSta, eFromState, eToState) \ -+ { secFsmTrans_ ## eFromState ## _to_ ## eToState(prAdapter, prSta); \ -+ SEC_NEXT_STATE_VAR = SEC_STATE_ ## eToState; \ -+ SEC_STATE_TRANSITION_FLAG = (BOOLEAN)TRUE; \ -+ } -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/*--------------------------------------------------------------*/ -+/* Routines to handle the sec check */ -+/*--------------------------------------------------------------*/ -+/***** Routines in sec_fsm.c *****/ -+VOID secFsmInit(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta); -+ -+VOID secFsmEventInit(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta); -+ -+VOID secFsmEventStart(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta); -+ -+VOID secFsmEventAbort(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta); -+ -+BOOLEAN secFsmEventPTKInstalled(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta); -+ -+VOID secFsmEvent2ndEapolTx(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta); -+ -+VOID secFsmEvent4ndEapolTxDone(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta); -+ -+VOID -+secFsmEventEapolTxDone(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus); -+ -+VOID secFsmEventEapolTxTimeout(IN P_ADAPTER_T prAdapter, IN ULONG ulParm); -+ -+VOID -+secFsmEventDeauthTxDone(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus); -+ -+VOID secFsmEventStartCounterMeasure(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta); -+ -+VOID secFsmEventEndOfCounterMeasure(IN P_ADAPTER_T prAdapter, IN ULONG ulParm); -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+#endif /* _SEC_FSM_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/stats.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/stats.h -new file mode 100644 -index 000000000000..1c0f9a76e119 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/stats.h -@@ -0,0 +1,368 @@ -+/* -+** Id: stats.h#1 -+*/ -+ -+/*! \file stats.h -+ \brief This file includes statistics support. -+*/ -+ -+/* -+** Log: stats.h -+ * -+ * 07 17 2014 samp.lin -+ * NULL -+ * Initial version. -+ */ -+ -+/******************************************************************************* -+ * C O M P I L E R F L A G S -+ ******************************************************************************** -+ */ -+ -+/******************************************************************************* -+ * E X T E R N A L R E F E R E N C E S -+ ******************************************************************************** -+ */ -+extern UINT_64 u8DrvOwnStart, u8DrvOwnEnd; -+extern UINT32 u4DrvOwnMax; -+extern BOOLEAN fgIsUnderSuspend; -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/* Command to TDLS core module */ -+typedef enum _STATS_CMD_CORE_ID { -+ STATS_CORE_CMD_ENV_REQUEST = 0x00 -+} STATS_CMD_CORE_ID; -+ -+typedef enum _STATS_EVENT_HOST_ID { -+ STATS_HOST_EVENT_ENV_REPORT = 0x00, -+ STATS_HOST_EVENT_RX_DROP -+} STATS_EVENT_HOST_ID; -+ -+#define CFG_ARP BIT(0) -+#define CFG_DNS BIT(1) -+#define CFG_TCP BIT(2) -+#define CFG_UDP BIT(3) -+#define CFG_EAPOL BIT(4) -+#define CFG_DHCP BIT(5) -+#define CFG_ICMP BIT(6) -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+typedef struct _STATS_CMD_CORE_T { -+ -+ UINT32 u4Command; /* STATS_CMD_CORE_ID */ -+ -+ UINT8 ucStaRecIdx; -+ UINT8 ucReserved[3]; -+ -+ UINT32 u4Reserved[4]; -+ -+#define STATS_CMD_CORE_RESERVED_SIZE 50 -+ union { -+ UINT8 Reserved[STATS_CMD_CORE_RESERVED_SIZE]; -+ } Content; -+ -+} STATS_CMD_CORE_T; -+ -+typedef struct _STATS_INFO_ENV_T { -+ -+ BOOLEAN fgIsUsed; /* TRUE: used */ -+ -+ /* ------------------- TX ------------------- */ -+ BOOLEAN fgTxIsRtsUsed; /* TRUE: we use RTS/CTS currently */ -+ BOOLEAN fgTxIsRtsEverUsed; /* TRUE: we ever use RTS/CTS */ -+ BOOLEAN fgTxIsCtsSelfUsed; /* TRUE: we use CTS-self */ -+ -+#define STATS_INFO_TX_PARAM_HW_BW40_OFFSET 0 -+#define STATS_INFO_TX_PARAM_HW_SHORT_GI20_OFFSET 1 -+#define STATS_INFO_TX_PARAM_HW_SHORT_GI40_OFFSET 2 -+#define STATS_INFO_TX_PARAM_USE_BW40_OFFSET 3 -+#define STATS_INFO_TX_PARAM_USE_SHORT_GI_OFFSET 4 -+#define STATS_INFO_TX_PARAM_NO_ACK_OFFSET 5 -+ UINT_8 ucTxParam; -+ -+ UINT_8 ucStaRecIdx; -+ UINT_8 ucReserved1[2]; -+ -+ UINT32 u4TxDataCntAll; /* total tx count from host */ -+ UINT32 u4TxDataCntOK; /* total tx ok count to air */ -+ UINT32 u4TxDataCntErr; /* total tx err count to air */ -+ -+ /* WLAN_STATUS_BUFFER_RETAINED ~ WLAN_STATUS_PACKET_LIFETIME_ERROR */ -+ UINT32 u4TxDataCntErrType[6]; /* total tx err count for different type to air */ -+ -+ UINT_8 ucTxRate1NonHTMax; -+ UINT_8 ucTxRate1HTMax; -+ UINT32 u4TxRateCntNonHT[16]; /* tx done rate */ -+ UINT32 u4TxRateCntHT[16]; /* tx done rate */ -+ -+ UINT_8 ucTxAggBitmap; /* TX BA sessions TID0 ~ TID7 */ -+ UINT_8 ucTxPeerAggMaxSize; -+ -+ /* ------------------- RX ------------------- */ -+ BOOLEAN fgRxIsRtsUsed; /* TRUE: peer uses RTS/CTS currently */ -+ BOOLEAN fgRxIsRtsEverUsed; /* TRUE: peer ever uses RTS/CTS */ -+ -+ UINT_8 ucRcvRcpi; -+ UINT_8 ucHwChanNum; -+ BOOLEAN fgRxIsShortGI; -+ UINT_8 ucReserved2[1]; -+ -+ UINT32 u4RxDataCntAll; /* total rx count from peer */ -+ UINT32 u4RxDataCntErr; /* total rx err count */ -+ UINT32 u4RxRateCnt[3][16]; /* [0]:CCK, [1]:OFDM, [2]:MIXED (skip green mode) */ -+ -+ UINT_8 ucRxAggBitmap; /* RX BA sessions TID0 ~ TID7 */ -+ UINT_8 ucRxAggMaxSize; -+ -+#define STATS_INFO_PHY_MODE_CCK 0 -+#define STATS_INFO_PHY_MODE_OFDM 1 -+#define STATS_INFO_PHY_MODE_HT 2 -+#define STATS_INFO_PHY_MODE_VHT 3 -+ UINT_8 ucBssSupPhyMode; /* CCK, OFDM, HT, or VHT BSS */ -+ -+ UINT_8 ucVersion; /* the version of statistics info environment */ -+ -+ /* ------------------- Delay ------------------- */ -+#define STATS_AIR_DELAY_INT 500 /* 500 byte */ -+ -+ /* delay in firmware from host to MAC */ -+ /* unit: us, for 500B, 1000B, max */ -+ UINT32 u4StayIntMaxH2M[3], u4StayIntMinH2M[3], u4StayIntAvgH2M[3]; -+ -+ /* delay in firmware from MAC to TX done */ -+ /* unit: 32us, for 500B, 1000B, max */ -+ UINT32 u4AirDelayMax[3], u4AirDelayMin[3], u4AirDelayAvg[3]; -+ -+ /* delay in firmware from host to TX done */ -+ /* unit: us, for 500B, 1000B, max */ -+ UINT32 u4StayIntMax[3], u4StayIntMin[3], u4StayIntAvg[3]; -+ UINT32 u4StayIntMaxSysTime[3]; -+ -+ /* delay in firmware from driver to TX done */ -+ /* unit: us, for 500B, 1000B, max */ -+ UINT32 u4StayIntMaxD2T[3], u4StayIntMinD2T[3], u4StayIntAvgD2T[3]; -+ -+ /* delay count in firmware from host to TX done */ -+ /* u4StayIntByConst: divide 4 fix partitions to count each delay in firmware */ -+#define STATS_STAY_INT_CONST 1 /* 1ms */ -+#define STATS_STAY_INT_CONST_2 5 -+#define STATS_STAY_INT_CONST_3 10 -+#define STATS_STAY_INT_CONST_4 15 -+#define STATS_STAY_INT_CONST_NUM 4 -+ UINT32 u4StayIntByConst[STATS_STAY_INT_CONST_NUM]; -+ -+ /* -+ u4StayIntMaxPast: past maximum delay in firmware -+ u4StayIntCnt[]: divide 4 partitions to count each delay in firmware -+ */ -+#define STATS_STAY_INT_NUM 4 -+ UINT32 u4StayIntMaxPast; -+ UINT32 u4StayIntCnt[STATS_STAY_INT_NUM + 1]; -+ -+ /* delay count in firmware from driver to HIF */ -+ /* u4StayIntD2HByConst: divide 4 fix partitions to count each delay in firmware */ -+#define STATS_STAY_INT_D2H_CONST 10 /* 10ms */ -+#define STATS_STAY_INT_D2H_CONST_2 20 -+#define STATS_STAY_INT_D2H_CONST_3 30 -+#define STATS_STAY_INT_D2H_CONST_4 40 -+#define STATS_STAY_INT_D2H_CONST_NUM 4 -+ UINT32 u4StayIntD2HByConst[STATS_STAY_INT_D2H_CONST_NUM]; -+ -+ /* unit: us, for 500B, 1000B, max */ -+ UINT32 u4StayIntMaxRx[3], u4StayIntMinRx[3], u4StayIntAvgRx[3]; -+ -+ /* ------------------- Others ------------------- */ -+ UINT32 u4NumOfChanChange; /* total channel change count */ -+ UINT32 u4NumOfRetryCnt; /* total TX retry count */ -+ UINT32 u4RxFifoFullCnt; /* counter of the number of the packets which -+ pass RFCR but are dropped due to FIFO full. */ -+ UINT32 u4PsIntMax; /* maximum time from ps to active */ -+ UINT_8 ucNumOfPsChange; /* peer power save change count */ -+ UINT_8 ucReserved3[3]; -+ -+ UINT32 u4ReportSysTime; /* firmware system time */ -+ UINT32 u4RxDataCntOk; /* total rx count to hif */ -+ -+ /* V4 */ -+ UINT32 u4RxRateRetryCnt[3][16]; /* [0]:CCK, [1]:OFDM, [2]:MIXED (skip green mode) */ -+ UINT32 au4ChanIdleCnt[10]; /* past Channel idle count in unit of slot */ -+ -+ /* V5 */ -+ UINT32 u4BtContUseTime; /* the air time that BT continuous occypy */ -+ -+ /* V6 */ -+ UINT32 u4LastTxOkTime; /* last time we tx ok to the station */ -+ -+ /* V7 */ -+ UINT_8 ucBtWfCoexGrantCnt[8]; /* [0]:WF Rx Grant Cnt[1]: WF Tx Grant Cnt[2]: WF Grant with Priority1 */ -+ /* [4]:BT Rx Grant Cnt[5]: BT Tx Grant Cnt[6]: BT Grant with Priority1 */ -+ -+ /* V8 */ -+ UINT_32 u4RxMacFreeDescCnt[6]; -+ UINT_32 u4RxHifFreeDescCnt[6]; -+ -+ /* V9 */ -+#define STATS_MAX_RX_DROP_TYPE 20 -+ UINT32 u4NumOfRxDrop[STATS_MAX_RX_DROP_TYPE]; -+ -+ /* V10 */ -+ UINT_32 u4NumOfTxDone; /* number of all packets (data/man/ctrl) tx done */ -+ UINT_32 u4NumOfTxDoneFixRate; /* number of done rate = 0 */ -+ UINT_32 u4NumOfTxDoneErrRate; /* number of error done rate */ -+ UINT_32 u4NumOfNullTxDone; /* number of null tx done */ -+ UINT_32 u4NumOfQoSNullTxDone; /* number of QoS-null tx done */ -+ -+ /* V11 */ -+ /* delay in firmware from HIF RX to HIF RX Done */ -+ /* unit: us, for 500B, 1000B, max */ -+ UINT32 u4StayIntMaxHR2HRD[3], u4StayIntMinHR2HRD[3], u4StayIntAvgHR2HRD[3]; -+ -+ /* V12 */ -+ UINT32 u4AirDelayTotal; /* agg all the air delay */ -+ -+ /* V13 */ -+ UINT32 u4CurrChnlInfo; /* add current channel information */ -+ -+ UINT_8 ucReserved_rate[4]; /* the field must be the last one */ -+} STATS_INFO_ENV_T; -+ -+/******************************************************************************* -+* M A C R O D E C L A R A T I O N S -+******************************************************************************** -+*/ -+#if (CFG_SUPPORT_STATISTICS == 1) -+ -+#define STATS_ENV_REPORT_DETECT statsEnvReportDetect -+ -+#define STATS_RX_REORDER_FALL_AHEAD_INC(__StaRec__) \ -+{ \ -+ (__StaRec__)->u4RxReorderFallAheadCnt++; \ -+} -+ -+#define STATS_RX_REORDER_FALL_BEHIND_INC(__StaRec__) \ -+{ \ -+ (__StaRec__)->u4RxReorderFallBehindCnt++; \ -+} -+ -+#define STATS_RX_REORDER_HOLE_INC(__StaRec__) \ -+{ \ -+ (__StaRec__)->u4RxReorderHoleCnt++; \ -+} -+ -+#define STATS_RX_REORDER_HOLE_TIMEOUT_INC(__StaRec__, __IsTimeout__) \ -+{ \ -+ if ((__IsTimeout__) == TRUE) \ -+ (__StaRec__)->u4RxReorderHoleTimeoutCnt++; \ -+} -+ -+#define STATS_RX_ARRIVE_TIME_RECORD(__SwRfb__) \ -+{ \ -+ (__SwRfb__)->rRxTime = StatsEnvTimeGet(); \ -+} -+ -+#define STATS_RX_PASS2OS_INC StatsEnvRxDone -+ -+#define STATS_RX_PKT_INFO_DISPLAY StatsRxPktInfoDisplay -+ -+#define STATS_TX_TIME_ARRIVE(__Skb__) \ -+do { \ -+ UINT_64 __SysTime; \ -+ __SysTime = StatsEnvTimeGet(); /* us */ \ -+ GLUE_SET_PKT_XTIME(__Skb__, __SysTime); \ -+} while (FALSE) -+ -+#define STATS_TX_TIME_TO_HIF StatsEnvTxTime2Hif -+ -+#define STATS_TX_PKT_CALLBACK StatsTxPktCallBack -+#define STATS_TX_PKT_DONE_INFO_DISPLAY StatsTxPktDoneInfoDisplay -+ -+#define STATS_DRIVER_OWN_RESET() \ -+{ \ -+ u4DrvOwnMax = 0; \ -+} -+#define STATS_DRIVER_OWN_START_RECORD() \ -+{ \ -+ u8DrvOwnStart = StatsEnvTimeGet(); \ -+} -+#define STATS_DRIVER_OWN_END_RECORD() \ -+{ \ -+ u8DrvOwnEnd = StatsEnvTimeGet(); \ -+} -+#define STATS_DRIVER_OWN_STOP() \ -+do { \ -+ UINT32 __Diff; \ -+ __Diff = (UINT32)(u8DrvOwnEnd - u8DrvOwnStart); \ -+ if (__Diff > u4DrvOwnMax) \ -+ u4DrvOwnMax = __Diff; \ -+} while (FALSE) -+ -+#else -+ -+#define STATS_ENV_REPORT_DETECT(__Adapter__, __StaRecIndex__) -+ -+#define STATS_RX_REORDER_FALL_AHEAD_INC(__StaRec__) -+#define STATS_RX_REORDER_FALL_BEHIND_INC(__StaRec__) -+#define STATS_RX_REORDER_HOLE_INC(__StaRec__) -+#define STATS_RX_REORDER_HOLE_TIMEOUT_INC(__StaRec__, __IsTimeout__) -+#define STATS_RX_PASS2OS_INC(__StaRec__, __SwRfb__) -+#define STATS_RX_PKT_INFO_DISPLAY(__Pkt__) -+ -+#define STATS_TX_TIME_ARRIVE(__Skb__) -+#define STATS_TX_TIME_TO_HIF(__MsduInfo__, __HwTxHeader__) -+#define STATS_TX_PKT_CALLBACK(__Pkt__, __fgIsNeedAck__) -+#define STATS_TX_PKT_DONE_INFO_DISPLAY(__Adapter__, __Event__) -+ -+#define STATS_DRIVER_OWN_RESET() -+#define STATS_DRIVER_OWN_START_RECORD() -+#define STATS_DRIVER_OWN_END_RECORD() -+#define STATS_DRIVER_OWN_STOP() -+#endif /* CFG_SUPPORT_STATISTICS */ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E F U N C T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C F U N C T I O N S -+******************************************************************************** -+*/ -+ -+VOID statsEnvReportDetect(ADAPTER_T *prAdapter, UINT8 ucStaRecIndex); -+ -+VOID StatsEnvRxDone(STA_RECORD_T *prStaRec, SW_RFB_T *prSwRfb); -+ -+UINT_64 StatsEnvTimeGet(VOID); -+ -+VOID StatsEnvTxTime2Hif(MSDU_INFO_T *prMsduInfo, HIF_TX_HEADER_T *prHwTxHeader); -+ -+VOID statsEventHandle(GLUE_INFO_T *prGlueInfo, UINT8 *prInBuf, UINT32 u4InBufLen); -+ -+VOID StatsRxPktInfoDisplay(UINT_8 *pPkt); -+ -+VOID StatsTxPktCallBack(UINT_8 *pPkt, P_MSDU_INFO_T prMsduInfo); -+ -+VOID StatsTxPktDoneInfoDisplay(ADAPTER_T *prAdapter, UINT_8 *pucEvtBuf); -+ -+VOID StatsSetCfgTxDone(UINT_16 u2Cfg, BOOLEAN fgSet); -+ -+UINT_16 StatsGetCfgTxDone(VOID); -+ -+/* End of stats.h */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/swcr.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/swcr.h -new file mode 100644 -index 000000000000..50c4b558c2cd ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/swcr.h -@@ -0,0 +1,187 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/mgmt/swcr.h#1 -+*/ -+ -+/*! \file "swcr.h" -+ \brief -+*/ -+ -+/* -+ * -+ */ -+ -+#ifndef _SWCR_H -+#define _SWCR_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "nic_cmd_event.h" -+ -+#if 0 -+extern SWCR_MAP_ENTRY_T g_arRlmArSwCrMap[]; -+#endif -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+#define SWCR_VAR(x) ((VOID *)&x) -+#define SWCR_FUNC(x) ((VOID *)x) -+ -+#define SWCR_T_FUNC BIT(7) -+ -+#define SWCR_L_32 3 -+#define SWCR_L_16 2 -+#define SWCR_L_8 1 -+ -+#define SWCR_READ 0 -+#define SWCR_WRITE 1 -+ -+#define SWCR_MAP_NUM(x) (sizeof(x)/sizeof(x[0])) -+ -+#define SWCR_CR_NUM 7 -+ -+#define SWCR_GET_RW_INDEX(action, rw, index) \ -+do { \ -+ index = action & 0x7F; \ -+ rw = action >> 7; \ -+} while (0) -+ -+extern UINT_32 g_au4SwCr[]; /*: 0: command other: data */ -+ -+typedef VOID(*PFN_SWCR_RW_T) (P_ADAPTER_T prAdapter, UINT_8 ucRead, UINT_16 u2Addr, UINT_32 *pu4Data); -+typedef VOID(*PFN_CMD_RW_T) (P_ADAPTER_T prAdapter, UINT_8 ucCate, UINT_8 ucAction, UINT_8 ucOpt0, UINT_8 ucOpt1); -+ -+typedef struct _SWCR_MAP_ENTRY_T { -+ UINT_16 u2Type; -+ PVOID u4Addr; -+} SWCR_MAP_ENTRY_T, *P_SWCR_MAP_ENTRY_T; -+ -+typedef struct _SWCR_MOD_MAP_ENTRY_T { -+ UINT_8 ucMapNum; -+ P_SWCR_MAP_ENTRY_T prSwCrMap; -+} SWCR_MOD_MAP_ENTRY_T, *P_SWCR_MOD_MAP_ENTRY_T; -+ -+typedef enum _ENUM_SWCR_DBG_TYPE_T { -+ SWCR_DBG_TYPE_ALL = 0, -+ SWCR_DBG_TYPE_TXRX, -+ SWCR_DBG_TYPE_RX_RATES, -+ SWCR_DBG_TYPE_PS, -+ SWCR_DBG_TYPE_NUM -+} ENUM_SWCR_DBG_TYPE_T; -+ -+typedef enum _ENUM_SWCR_DBG_ALL_T { -+ SWCR_DBG_ALL_TX_CNT = 0, -+ SWCR_DBG_ALL_TX_BCN_CNT, -+ SWCR_DBG_ALL_TX_FAILED_CNT, -+ SWCR_DBG_ALL_TX_RETRY_CNT, -+ SWCR_DBG_ALL_TX_AGING_TIMEOUT_CNT, -+ SWCR_DBG_ALL_TX_PS_OVERFLOW_CNT, -+ SWCR_DBG_ALL_TX_MGNT_DROP_CNT, -+ SWCR_DBG_ALL_TX_ERROR_CNT, -+ -+ SWCR_DBG_ALL_RX_CNT, -+ SWCR_DBG_ALL_RX_DROP_CNT, -+ SWCR_DBG_ALL_RX_DUP_DROP_CNT, -+ SWCR_DBG_ALL_RX_TYPE_ERROR_DROP_CNT, -+ SWCR_DBG_ALL_RX_CLASS_ERROR_DROP_CNT, -+ SWCR_DBG_ALL_RX_AMPDU_ERROR_DROP_CNT, -+ -+ SWCR_DBG_ALL_RX_STATUS_ERROR_DROP_CNT, -+ SWCR_DBG_ALL_RX_FORMAT_ERROR_DROP_CNT, -+ SWCR_DBG_ALL_RX_ICV_ERROR_DROP_CNT, -+ SWCR_DBG_ALL_RX_KEY_ERROR_DROP_CNT, -+ SWCR_DBG_ALL_RX_TKIP_ERROR_DROP_CNT, -+ SWCR_DBG_ALL_RX_MIC_ERROR_DROP_CNT, -+ SWCR_DBG_ALL_RX_BIP_ERROR_DROP_CNT, -+ -+ SWCR_DBG_ALL_RX_FCSERR_CNT, -+ SWCR_DBG_ALL_RX_FIFOFULL_CNT, -+ SWCR_DBG_ALL_RX_PFDROP_CNT, -+ -+ SWCR_DBG_ALL_PWR_PS_POLL_CNT, -+ SWCR_DBG_ALL_PWR_TRIGGER_NULL_CNT, -+ SWCR_DBG_ALL_PWR_BCN_IND_CNT, -+ SWCR_DBG_ALL_PWR_BCN_TIMEOUT_CNT, -+ SWCR_DBG_ALL_PWR_PM_STATE0, -+ SWCR_DBG_ALL_PWR_PM_STATE1, -+ SWCR_DBG_ALL_PWR_CUR_PS_PROF0, -+ SWCR_DBG_ALL_PWR_CUR_PS_PROF1, -+ -+ SWCR_DBG_ALL_AR_STA0_RATE, -+ SWCR_DBG_ALL_AR_STA0_BWGI, -+ SWCR_DBG_ALL_AR_STA0_RX_RATE_RCPI, -+ -+ SWCR_DBG_ALL_ROAMING_ENABLE, -+ SWCR_DBG_ALL_ROAMING_ROAM_CNT, -+ SWCR_DBG_ALL_ROAMING_INT_CNT, -+ -+ SWCR_DBG_ALL_BB_RX_MDRDY_CNT, -+ SWCR_DBG_ALL_BB_RX_FCSERR_CNT, -+ SWCR_DBG_ALL_BB_CCK_PD_CNT, -+ SWCR_DBG_ALL_BB_OFDM_PD_CNT, -+ SWCR_DBG_ALL_BB_CCK_SFDERR_CNT, -+ SWCR_DBG_ALL_BB_CCK_SIGERR_CNT, -+ SWCR_DBG_ALL_BB_OFDM_TAGERR_CNT, -+ SWCR_DBG_ALL_BB_OFDM_SIGERR_CNT, -+ -+ SWCR_DBG_ALL_NUM -+} ENUM_SWCR_DBG_ALL_T; -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+VOID swCtrlCmdCategory0(P_ADAPTER_T prAdapter, UINT_8 ucCate, UINT_8 ucAction, UINT_8 ucOpt0, UINT_8 ucOpt1); -+VOID swCtrlCmdCategory1(P_ADAPTER_T prAdapter, UINT_8 ucCate, UINT_8 ucAction, UINT_8 ucOpt0, UINT_8 ucOpt1); -+VOID testPsCmdCategory0(P_ADAPTER_T prAdapter, UINT_8 ucCate, UINT_8 ucAction, UINT_8 ucOpt0, UINT_8 ucOpt1); -+VOID testPsCmdCategory1(P_ADAPTER_T prAdapter, UINT_8 ucCate, UINT_8 ucAction, UINT_8 ucOpt0, UINT_8 ucOpt1); -+void testWNMCmdCategory0(P_ADAPTER_T prAdapter, UINT_8 ucCate, UINT_8 ucAction, UINT_8 ucOpt0, UINT_8 ucOpt1); -+VOID swCtrlSwCr(P_ADAPTER_T prAdapter, UINT_8 ucRead, UINT_16 u2Addr, UINT_32 *pu4Data); -+ -+/* Support Debug */ -+VOID swCrDebugCheck(P_ADAPTER_T prAdapter, P_CMD_SW_DBG_CTRL_T prCmdSwCtrl); -+VOID swCrDebugCheckTimeout(IN P_ADAPTER_T prAdapter, ULONG ulParam); -+VOID swCrDebugQuery(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); -+VOID swCrDebugQueryTimeout(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo); -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+VOID swCrReadWriteCmd(P_ADAPTER_T prAdapter, UINT_8 ucRead, UINT_16 u2Addr, UINT_32 *pu4Data); -+ -+/* Debug Support */ -+VOID swCrFrameCheckEnable(P_ADAPTER_T prAdapter, UINT_32 u4DumpType); -+VOID swCrDebugInit(P_ADAPTER_T prAdapter); -+VOID swCrDebugCheckEnable(P_ADAPTER_T prAdapter, BOOLEAN fgIsEnable, UINT_8 ucType, UINT_32 u4Timeout); -+VOID swCrDebugUninit(P_ADAPTER_T prAdapter); -+ -+#endif -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/tdls.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/tdls.h -new file mode 100644 -index 000000000000..3b6991131d05 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/tdls.h -@@ -0,0 +1,262 @@ -+/* -+** Id: include/tdls.h#1 -+*/ -+ -+/*! \file "tdls.h" -+ \brief This file contains the internal used in TDLS modules -+ for MediaTek Inc. 802.11 Wireless LAN Adapters. -+*/ -+ -+/* -+** Log: tdls.h -+ * -+ * 11 18 2013 vend_samp.lin -+ * NULL -+ * Initial version. -+ * -+ ** -+ */ -+ -+#ifndef _TDLS_H -+#define _TDLS_H -+ -+#if (CFG_SUPPORT_TDLS == 1) -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+#define TDLS_CFG_CMD_TEST 1 -+#define TDLS_CFG_HT_SUP 1 -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+extern int wlanHardStartXmit(struct sk_buff *prSkb, struct net_device *prDev); -+extern BOOLEAN flgTdlsTestExtCapElm; -+extern UINT8 aucTdlsTestExtCapElm[]; -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+typedef struct _TDLS_LINK_HIS_OTHERS_T { -+ BOOLEAN fgIsHt; /* TRUE: HT device */ -+ -+} TDLS_LINK_HIS_OTHERS_T; -+ -+/* command */ -+typedef enum _TDLS_CMD_ID { -+ TDLS_CMD_TEST_TX_FRAME = 0x00, -+ TDLS_CMD_TEST_RCV_FRAME = 0x01, -+ TDLS_CMD_TEST_PEER_ADD = 0x02, -+ TDLS_CMD_TEST_PEER_UPDATE = 0x03, -+ TDLS_CMD_TEST_DATA_FRAME = 0x04, -+ TDLS_CMD_TEST_RCV_NULL = 0x05, -+ TDLS_CMD_MIB_UPDATE = 0x06, -+ TDLS_CMD_TEST_SKIP_TX_FAIL = 0x07, -+ TDLS_CMD_UAPSD_CONF = 0x08, -+ TDLS_CMD_CH_SW_CONF = 0x09, -+ TDLS_CMD_TEST_SKIP_KEEP_ALIVE = 0x0a, -+ TDLS_CMD_TEST_SKIP_CHSW_TIMEOUT = 0x0b, -+ TDLS_CMD_TEST_TX_TDLS_FRAME = 0x0c, -+ TDLS_CMD_TEST_PROHIBIT_SET_IN_AP = 0x0d, -+ TDLS_CMD_TEST_SCAN_DISABLE = 0x0e, -+ TDLS_CMD_TEST_DATA_FRAME_CONT = 0x0f, -+ TDLS_CMD_TEST_CH_SW_PROHIBIT_SET_IN_AP = 0x10, -+ TDLS_CMD_SETUP_CONF = 0x11, -+ TDLS_CMD_INFO = 0x12, -+ TDLS_CMD_TEST_DELAY = 0x13, -+ TDLS_CMD_KEY_INFO = 0x14, -+ TDLS_CMD_TEST_PTI_TX_FAIL = 0x15 -+} TDLS_CMD_ID; -+ -+typedef enum _TDLS_EVENT_HOST_ID { -+ TDLS_HOST_EVENT_TEAR_DOWN = 0x00, /* TDLS_EVENT_HOST_SUBID_TEAR_DOWN */ -+ TDLS_HOST_EVENT_TX_DONE, -+ TDLS_HOST_EVENT_FME_STATUS, /* TDLS_EVENT_HOST_SUBID_SPECIFIC_FRAME */ -+ TDLS_HOST_EVENT_STATISTICS -+} TDLS_EVENT_HOST_ID; -+ -+typedef enum _TDLS_EVENT_HOST_SUBID_TEAR_DOWN { -+ TDLS_HOST_EVENT_TD_PTI_TIMEOUT = 0x00, -+ TDLS_HOST_EVENT_TD_AGE_TIMEOUT, -+ TDLS_HOST_EVENT_TD_PTI_SEND_FAIL, -+ TDLS_HOST_EVENT_TD_PTI_SEND_MAX_FAIL, -+ TDLS_HOST_EVENT_TD_WRONG_NETWORK_IDX, -+ TDLS_HOST_EVENT_TD_NON_STATE3, -+ TDLS_HOST_EVENT_TD_LOST_TEAR_DOWN -+} TDLS_EVENT_HOST_SUBID_TEAR_DOWN; -+ -+typedef enum _TDLS_EVENT_HOST_SUBID_SPECIFIC_FRAME { -+ TDLS_HOST_EVENT_SF_BA, -+ TDLS_HOST_EVENT_SF_BA_OK, -+ TDLS_HOST_EVENT_SF_BA_DECLINE, -+ TDLS_HOST_EVENT_SF_BA_PEER, -+ TDLS_HOST_EVENT_SF_BA_RSP_OK, -+ TDLS_HOST_EVENT_SF_BA_RSP_DECLINE -+} TDLS_EVENT_HOST_SUBID_SPECIFIC_FRAME; -+ -+/* payload specific type in the LLC/SNAP header */ -+#define TDLS_FRM_PAYLOAD_TYPE 2 -+ -+#define TDLS_FRM_CATEGORY 12 -+ -+typedef enum _TDLS_FRM_ACTION_ID { -+ TDLS_FRM_ACTION_SETUP_REQ = 0x00, -+ TDLS_FRM_ACTION_SETUP_RSP, -+ TDLS_FRM_ACTION_CONFIRM, -+ TDLS_FRM_ACTION_TEARDOWN, -+ TDLS_FRM_ACTION_PTI, -+ TDLS_FRM_ACTION_CHAN_SWITCH_REQ, -+ TDLS_FRM_ACTION_CHAN_SWITCH_RSP, -+ TDLS_FRM_ACTION_PEER_PSM_REQ, -+ TDLS_FRM_ACTION_PEER_PSM_RSP, -+ TDLS_FRM_ACTION_PTI_RSP, /* 0x09 */ -+ TDLS_FRM_ACTION_DISCOVERY_REQ, -+ -+ TDLS_FRM_ACTION_EVENT_TEAR_DOWN_TO_SUPPLICANT = 0x30, -+ -+ TDLS_FRM_DATA_TEST_DATA = 0x80 -+} TDLS_FRM_ACTION_ID; -+ -+#define TDLS_FRM_ACTION_DISCOVERY_RESPONSE 14 -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+/* 7.3.2.62 Link Identifier element */ -+#define ELEM_ID_LINK_IDENTIFIER 101 -+#define ELEM_LEN_LINK_IDENTIFIER 18 -+ -+typedef struct _IE_LINK_IDENTIFIER_T { -+ UINT_8 ucId; -+ UINT_8 ucLength; -+ UINT_8 aBSSID[6]; -+ UINT_8 aInitiator[6]; -+ UINT_8 aResponder[6]; -+} __KAL_ATTRIB_PACKED__ IE_LINK_IDENTIFIER_T; -+ -+#define TDLS_LINK_IDENTIFIER_IE(__ie__) ((IE_LINK_IDENTIFIER_T *)(__ie__)) -+ -+/* test command use */ -+typedef struct _PARAM_CUSTOM_TDLS_CMD_STRUCT_T { -+ -+ UINT_8 ucFmeType; /* TDLS_FRM_ACTION_ID */ -+ -+ UINT_8 ucToken; -+ UINT_16 u2Cap; -+ -+ /* bit0: TDLS, bit1: Peer U-APSD Buffer, bit2: Channel Switching */ -+#define TDLS_EX_CAP_PEER_UAPSD BIT(0) -+#define TDLS_EX_CAP_CHAN_SWITCH BIT(1) -+#define TDLS_EX_CAP_TDLS BIT(2) -+ UINT_8 ucExCap; -+ -+ UINT_8 arSupRate[4]; -+ UINT_8 arSupChan[4]; -+ -+ UINT_32 u4Timeout; -+ -+#define TDLS_FME_MAC_ADDR_LEN 6 -+ UINT_8 arRspAddr[TDLS_FME_MAC_ADDR_LEN]; -+ UINT_8 arBssid[TDLS_FME_MAC_ADDR_LEN]; -+ -+/* -+ Linux Kernel-3.10 -+ struct station_parameters { -+ const u8 *supported_rates; -+ struct net_device *vlan; -+ u32 sta_flags_mask, sta_flags_set; -+ u32 sta_modify_mask; -+ int listen_interval; -+ u16 aid; -+ u8 supported_rates_len; -+ u8 plink_action; -+ u8 plink_state; -+ const struct ieee80211_ht_cap *ht_capa; -+ const struct ieee80211_vht_cap *vht_capa; -+ u8 uapsd_queues; -+ u8 max_sp; -+ enum nl80211_mesh_power_mode local_pm; -+ u16 capability; -+ const u8 *ext_capab; -+ u8 ext_capab_len; -+ }; -+*/ -+ struct ieee80211_ht_cap rHtCapa; -+ struct ieee80211_vht_cap rVhtCapa; /* LINUX_KERNEL_VERSION >= 3.10.0 */ -+ struct station_parameters rPeerInfo; -+ -+} PARAM_CUSTOM_TDLS_CMD_STRUCT_T; -+ -+typedef struct _TDLS_MGMT_TX_INFO { -+ UINT8 aucPeer[6]; -+ UINT8 ucActionCode; -+ UINT8 ucDialogToken; -+ UINT16 u2StatusCode; -+ UINT32 u4SecBufLen; -+ UINT8 aucSecBuf[1000]; -+} TDLS_MGMT_TX_INFO; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/* check any TDLS link */ -+#define TDLS_IS_NO_LINK_GOING(__GlueInfo__) \ -+ ((__GlueInfo__)->rTdlsLink.cLinkCnt == 0) -+ -+/* increase TDLS link count */ -+#define TDLS_LINK_INCREASE(__GlueInfo__) \ -+ ((__GlueInfo__)->rTdlsLink.cLinkCnt++) -+ -+/* decrease TDLS link count */ -+#define TDLS_LINK_DECREASE(__GlueInfo__) \ -+do { \ -+ if ((__GlueInfo__)->rTdlsLink.cLinkCnt > 0) \ -+ (__GlueInfo__)->rTdlsLink.cLinkCnt--; \ -+} while (0) -+ -+/* get TDLS link count */ -+#define TDLS_LINK_COUNT(__GlueInfo__) \ -+ ((__GlueInfo__)->rTdlsLink.cLinkCnt) -+ -+/* reset TDLS link count */ -+#define TDLS_LINK_COUNT_RESET(__GlueInfo__) \ -+ ((__GlueInfo__)->rTdlsLink.cLinkCnt = 0) -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+/* Note: these functions are used only in tdls module, not other modules */ -+UINT_32 TdlsFrameGeneralIeAppend(ADAPTER_T *prAdapter, STA_RECORD_T *prStaRec, UINT_16 u2StatusCode, UINT_8 *pPkt); -+ -+TDLS_STATUS -+TdlsDataFrameSend(ADAPTER_T *prAdapter, -+ STA_RECORD_T *prStaRec, -+ UINT_8 *pPeerMac, -+ UINT_8 ucActionCode, -+ UINT_8 ucDialogToken, UINT_16 u2StatusCode, UINT_8 *pAppendIe, UINT_32 AppendIeLen); -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif /* CFG_SUPPORT_TDLS */ -+ -+#endif /* _TDLS_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/wapi.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/wapi.h -new file mode 100644 -index 000000000000..12c9359f2e8f ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/wapi.h -@@ -0,0 +1,104 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/mgmt/wapi.h#1 -+*/ -+ -+/*! \file wapi.h -+ \brief The wapi related define, macro and structure are described here. -+*/ -+ -+/* -+** Log: wapi.h -+ * -+ * 07 20 2010 wh.su -+ * -+ * . -+ * -+ * 01 27 2010 wh.su -+ * [BORA00000476][Wi-Fi][firmware] Add the security module initialize code -+ * add and fixed some security function. -+ * -+ * Dec 8 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * change the wapi function name and adding the generate wapi ie function -+ * -+ * Dec 7 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * adding some wapi structure define -+ * -+ * Nov 23 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * -+** \main\maintrunk.MT5921\1 2009-10-09 17:06:29 GMT mtk01088 -+** -+*/ -+ -+#ifndef _WAPI_H -+#define _WAPI_H -+ -+#if CFG_SUPPORT_WAPI -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+#define WAPI_CIPHER_SUITE_WPI 0x01721400 /* WPI_SMS4 */ -+#define WAPI_AKM_SUITE_802_1X 0x01721400 /* WAI */ -+#define WAPI_AKM_SUITE_PSK 0x02721400 /* WAI_PSK */ -+ -+#define ELEM_ID_WAPI 68 /* WAPI IE */ -+ -+#define WAPI_IE(fp) ((P_WAPI_INFO_ELEM_T) fp) -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+VOID wapiGenerateWAPIIE(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); -+ -+BOOLEAN wapiParseWapiIE(IN P_WAPI_INFO_ELEM_T prInfoElem, OUT P_WAPI_INFO_T prWapiInfo); -+ -+BOOLEAN wapiPerformPolicySelection(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBss); -+ -+/* BOOLEAN */ -+/* wapiUpdateTxKeyIdx ( */ -+/* IN P_STA_RECORD_T prStaRec, */ -+/* IN UINT_8 ucWlanIdx */ -+/* ); */ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+#endif -+#endif /* _WAPI_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/wlan_typedef.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/wlan_typedef.h -new file mode 100644 -index 000000000000..5dc969f1cc05 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/wlan_typedef.h -@@ -0,0 +1,87 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/mgmt/wlan_typedef.h#1 -+*/ -+ -+/*! \file wlan_typedef.h -+ \brief Declaration of data type and return values of internal protocol stack. -+ -+ In this file we declare the data type and return values which will be exported -+ to all MGMT Protocol Stack. -+*/ -+ -+/* -+** Log: wlan_typedef.h -+*/ -+ -+#ifndef _WLAN_TYPEDEF_H -+#define _WLAN_TYPEDEF_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+/* Type definition for BSS_INFO_T structure, to describe the attributes used in a -+ * common BSS. -+ */ -+typedef struct _BSS_INFO_T BSS_INFO_T, *P_BSS_INFO_T; -+ -+typedef BSS_INFO_T AIS_BSS_INFO_T, *P_AIS_BSS_INFO_T; -+typedef BSS_INFO_T P2P_BSS_INFO_T, *P_P2P_BSS_INFO_T; -+typedef BSS_INFO_T BOW_BSS_INFO_T, *P_BOW_BSS_INFO_T; -+ -+typedef struct _AIS_SPECIFIC_BSS_INFO_T AIS_SPECIFIC_BSS_INFO_T, *P_AIS_SPECIFIC_BSS_INFO_T; -+typedef struct _P2P_SPECIFIC_BSS_INFO_T P2P_SPECIFIC_BSS_INFO_T, *P_P2P_SPECIFIC_BSS_INFO_T; -+typedef struct _BOW_SPECIFIC_BSS_INFO_T BOW_SPECIFIC_BSS_INFO_T, *P_BOW_SPECIFIC_BSS_INFO_T; -+/* CFG_SUPPORT_WFD */ -+typedef struct _WFD_CFG_SETTINGS_T WFD_CFG_SETTINGS_T, *P_WFD_CFG_SETTINGS_T; -+ -+typedef struct _WFD_DBG_CFG_SETTINGS_T WFD_DBG_CFG_SETTINGS_T, *P_WFD_DBG_CFG_SETTINGS_T; -+ -+/* BSS related structures */ -+/* Type definition for BSS_DESC_T structure, to describe parameter sets of a particular BSS */ -+typedef struct _BSS_DESC_T BSS_DESC_T, *P_BSS_DESC_T, **PP_BSS_DESC_T; -+ -+#if CFG_SUPPORT_HOTSPOT_2_0 -+typedef struct _HS20_INFO_T HS20_INFO_T, *P_HS20_INFO_T; -+#endif /* CFG_SUPPORT_HOTSPOT_2_0 */ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+#endif /* _WLAN_TYPEDEF_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/wnm.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/wnm.h -new file mode 100644 -index 000000000000..09bc0b5d5151 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/wnm.h -@@ -0,0 +1,95 @@ -+/* -+** Id: //Department/DaVinci/TRUNK/MT6620_5931_WiFi_Driver/include/mgmt/wnm.h#1 -+*/ -+ -+/*! \file wnm.h -+ \brief This file contains the IEEE 802.11 family related 802.11v network management -+ for MediaTek 802.11 Wireless LAN Adapters. -+*/ -+ -+/* -+** Log: wnm.h -+ * -+ * 01 05 2012 tsaiyuan.hsu -+ * [WCXRP00001157] [MT6620 Wi-Fi][FW][DRV] add timing measurement support for 802.11v -+ * add timing measurement support for 802.11v. -+ * -+ * -+*/ -+ -+#ifndef _WNM_H -+#define _WNM_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+typedef struct _TIMINGMSMT_PARAM_T { -+ BOOLEAN fgInitiator; -+ UINT_8 ucTrigger; -+ UINT_8 ucDialogToken; /* Dialog Token */ -+ UINT_8 ucFollowUpDialogToken; /* Follow Up Dialog Token */ -+ UINT_32 u4ToD; /* Timestamp of Departure [10ns] */ -+ UINT_32 u4ToA; /* Timestamp of Arrival [10ns] */ -+} TIMINGMSMT_PARAM_T, *P_TIMINGMSMT_PARAM_T; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+WLAN_STATUS -+wnmRunEventTimgingMeasTxDone(IN P_ADAPTER_T prAdapter, -+ IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus); -+ -+VOID -+wnmComposeTimingMeasFrame(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN PFN_TX_DONE_HANDLER pfTxDoneHandler); -+ -+VOID wnmTimingMeasRequest(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); -+ -+VOID wnmWNMAction(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); -+ -+VOID wnmReportTimingMeas(IN P_ADAPTER_T prAdapter, IN UINT_8 ucStaRecIndex, IN UINT_32 u4ToD, IN UINT_32 u4ToA); -+ -+#define WNM_UNIT_TEST 1 -+ -+#if WNM_UNIT_TEST -+VOID wnmTimingMeasUnitTest1(P_ADAPTER_T prAdapter, UINT_8 ucStaRecIndex); -+#endif -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif /* _WNM_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/adapter.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/adapter.h -new file mode 100644 -index 000000000000..d34f2c9c36a8 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/adapter.h -@@ -0,0 +1,1506 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/nic/adapter.h#3 -+*/ -+ -+/*! \file adapter.h -+ \brief Definition of internal data structure for driver manipulation. -+ -+ In this file we define the internal data structure - ADAPTER_T which stands -+ for MiniPort ADAPTER(From Windows point of view) or stands for Network ADAPTER. -+*/ -+ -+/* -+** Log: adapter.h -+** -+** 08 31 2012 yuche.tsai -+** [ALPS00349585] [6577JB][WiFi direct][KE]Establish p2p connection while both device have -+** connected to AP previously,one device reboots automatically with KE -+** Fix possible KE when concurrent & disconnect. -+** -+** 07 26 2012 yuche.tsai -+** [ALPS00324337] [ALPS.JB][Hot-Spot] Driver update for Hot-Spot -+** Update driver code of ALPS.JB for hot-spot. -+ * -+ * 07 17 2012 yuche.tsai -+ * NULL -+ * Let netdev bring up. -+ * -+ * 07 17 2012 yuche.tsai -+ * NULL -+ * Compile no error before trial run. -+ * -+ * 06 13 2012 yuche.tsai -+ * NULL -+ * Update maintrunk driver. -+ * Add support for driver compose assoc request frame. -+ * -+ * 03 02 2012 terry.wu -+ * NULL -+ * Snc CFG80211 modification for ICS migration from branch 2.2. -+ * -+ * 03 02 2012 terry.wu -+ * NULL -+ * Sync CFG80211 modification from branch 2,2. -+ * -+ * 01 16 2012 cp.wu -+ * [MT6620 Wi-Fi][Driver] API and behavior modification for preferred band configuration -+ * with corresponding network configuration -+ * add wlanSetPreferBandByNetwork() for glue layer to invoke for setting preferred band configuration -+ * corresponding to network type. -+ * -+ * 12 13 2011 cm.chang -+ * [WCXRP00001136] [All Wi-Fi][Driver] Add wake lock for pending timer -+ * Add wake lock if timer timeout value is smaller than 5 seconds -+ * -+ * 12 02 2011 yuche.tsai -+ * NULL -+ * Resolve inorder issue under AP mode. -+ * -+ * data frame may TX before assoc response frame. -+ * -+ * 11 19 2011 yuche.tsai -+ * NULL -+ * Update RSSI for P2P. -+ * -+ * 11 18 2011 yuche.tsai -+ * NULL -+ * CONFIG P2P support RSSI query, default turned off. -+ * -+ * 11 11 2011 yuche.tsai -+ * NULL -+ * Fix work thread cancel issue. -+ * -+ * 10 21 2011 eddie.chen -+ * [WCXRP00001051] [MT6620 Wi-Fi][Driver/Fw] Adjust the STA aging timeout -+ * Add switch to ignore the STA aging timeout. -+ * -+ * 10 12 2011 wh.su -+ * [WCXRP00001036] [MT6620 Wi-Fi][Driver][FW] Adding the 802.11w code for MFP -+ * adding the 802.11w related function and define . -+ * -+ * 09 20 2011 cm.chang -+ * [WCXRP00000997] [MT6620 Wi-Fi][Driver][FW] Handle change of BSS preamble type and slot time -+ * Remove ERP member in adapter structure -+ * -+ * 09 14 2011 yuche.tsai -+ * NULL -+ * Add P2P IE in assoc response. -+ * -+ * 08 31 2011 cm.chang -+ * [WCXRP00000969] [MT6620 Wi-Fi][Driver][FW] Channel list for 5G band based on country code -+ * . -+ * -+ * 07 18 2011 chinghwa.yu -+ * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm -+ * Add CMD/Event for RDD and BWCS. -+ * -+ * 06 23 2011 cp.wu -+ * [WCXRP00000812] [MT6620 Wi-Fi][Driver] not show NVRAM when there is no valid MAC address in NVRAM content -+ * check with firmware for valid MAC address. -+ * -+ * 04 18 2011 terry.wu -+ * [WCXRP00000660] [MT6620 Wi-Fi][Driver] Remove flag CFG_WIFI_DIRECT_MOVED -+ * Remove flag CFG_WIFI_DIRECT_MOVED. -+ * -+ * 04 12 2011 cm.chang -+ * [WCXRP00000634] [MT6620 Wi-Fi][Driver][FW] 2nd BSS will not support 40MHz bandwidth for concurrency -+ * . -+ * -+ * 04 08 2011 yuche.tsai -+ * [WCXRP00000624] [Volunteer Patch][MT6620][Driver] Add device discoverability support for GO. -+ * Add device discoverability support. -+ * Action frame callback for GO Device Discoverability Req. -+ * -+ * 04 08 2011 george.huang -+ * [WCXRP00000621] [MT6620 Wi-Fi][Driver] Support P2P supplicant to set power mode -+ * separate settings of P2P and AIS -+ * -+ * 04 08 2011 eddie.chen -+ * [WCXRP00000617] [MT6620 Wi-Fi][DRV/FW] Fix for sigma -+ * Fix for sigma -+ * -+ * 03 19 2011 yuche.tsai -+ * [WCXRP00000584] [Volunteer Patch][MT6620][Driver] Add beacon timeout support for WiFi Direct. -+ * Add beacon timeout support for WiFi Direct Network. -+ * -+ * 03 19 2011 yuche.tsai -+ * [WCXRP00000581] [Volunteer Patch][MT6620][Driver] P2P IE in Assoc Req Issue -+ * Make assoc req to append P2P IE if wifi direct is enabled. -+ * -+ * 03 17 2011 cp.wu -+ * [WCXRP00000562] [MT6620 Wi-Fi][Driver] I/O buffer pre-allocation to avoid physically -+ * continuous memory shortage after system running for a long period -+ * use pre-allocated buffer for storing enhanced interrupt response as well -+ * -+ * 03 15 2011 cp.wu -+ * [WCXRP00000559] [MT6620 Wi-Fi][Driver] Combine TX/RX DMA buffers into a single one to reduce -+ * physically continuous memory consumption -+ * 1. deprecate CFG_HANDLE_IST_IN_SDIO_CALLBACK -+ * 2. Use common coalescing buffer for both TX/RX directions -+ * -+ * -+ * 03 10 2011 yuche.tsai -+ * [WCXRP00000533] [Volunteer Patch][MT6620][Driver] Provide a P2P function API for Legacy WiFi to query AP mode. -+ * Provide an API for Legacy WiFi to query the operation mode.. -+ * -+ * 03 05 2011 wh.su -+ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code -+ * add the code to get the check rsponse and indicate to app. -+ * -+ * 03 02 2011 wh.su -+ * [WCXRP00000448] [MT6620 Wi-Fi][Driver] Fixed WSC IE not send out at probe request -+ * Add code to send beacon and probe response WSC IE at Auto GO. -+ * -+ * 03 02 2011 cp.wu -+ * [WCXRP00000503] [MT6620 Wi-Fi][Driver] Take RCPI brought by association response as -+ * initial RSSI right after connection is built. -+ * use RCPI brought by ASSOC-RESP after connection is built as initial RCPI to avoid -+ * using a uninitialized MAC-RX RCPI. -+ * -+ * 02 21 2011 terry.wu -+ * [WCXRP00000476] [MT6620 Wi-Fi][Driver] Clean P2P scan list while removing P2P -+ * Clean P2P scan list while removing P2P. -+ * -+ * 02 17 2011 eddie.chen -+ * [WCXRP00000458] [MT6620 Wi-Fi][Driver] BOW Concurrent - ProbeResp was exist in other channel -+ * 1) Change GetFrameAction decision when BSS is absent. -+ * 2) Check channel and resource in processing ProbeRequest -+ * -+ * 02 16 2011 cm.chang -+ * [WCXRP00000447] [MT6620 Wi-Fi][FW] Support new NVRAM update mechanism -+ * . -+ * -+ * 02 10 2011 yuche.tsai -+ * [WCXRP00000431] [Volunteer Patch][MT6620][Driver] Add MLME support for deauthentication under AP(Hot-Spot) mode. -+ * Add RX deauthentication & disassociation process under Hot-Spot mode. -+ * -+ * 02 09 2011 wh.su -+ * [WCXRP00000433] [MT6620 Wi-Fi][Driver] Remove WAPI structure define for avoid P2P module -+ * with structure miss-align pointer issue -+ * always pre-allio WAPI related structure for align p2p module. -+ * -+ * 02 08 2011 yuche.tsai -+ * [WCXRP00000419] [Volunteer Patch][MT6620/MT5931][Driver] Provide function of disconnect to -+ * target station for AAA module. -+ * Provide disconnect function for AAA module. -+ * -+ * 02 01 2011 cm.chang -+ * [WCXRP00000415] [MT6620 Wi-Fi][Driver] Check if any memory leakage happens when uninitializing in DGB mode -+ * . -+ * -+ * 01 27 2011 tsaiyuan.hsu -+ * [WCXRP00000392] [MT6620 Wi-Fi][Driver] Add Roaming Support -+ * add roaming fsm -+ * 1. not support 11r, only use strength of signal to determine roaming. -+ * 2. not enable CFG_SUPPORT_ROAMING until completion of full test. -+ * 3. in 6620, adopt work-around to avoid sign extension problem of cck of hw -+ * 4. assume that change of link quality in smooth way. -+ * -+ * 01 27 2011 george.huang -+ * [WCXRP00000400] [MT6620 Wi-Fi] support CTIA power mode setting -+ * Support CTIA power mode setting. -+ * -+ * 01 27 2011 george.huang -+ * [WCXRP00000355] [MT6620 Wi-Fi] Set WMM-PS related setting with qualifying AP capability -+ * Support current measure mode, assigned by registry (XP only). -+ * -+ * 01 24 2011 cp.wu -+ * [WCXRP00000382] [MT6620 Wi-Fi][Driver] Track forwarding packet number with notifying tx thread for serving -+ * 1. add an extra counter for tracking pending forward frames. -+ * 2. notify TX service thread as well when there is pending forward frame -+ * 3. correct build errors leaded by introduction of Wi-Fi direct separation module -+ * -+ * 01 12 2011 cm.chang -+ * [WCXRP00000354] [MT6620 Wi-Fi][Driver][FW] Follow NVRAM bandwidth setting -+ * User-defined bandwidth is for 2.4G and 5G individually -+ * -+ * 12 29 2010 eddie.chen -+ * [WCXRP00000322] Add WMM IE in beacon, -+ -+Add per station flow control when STA is in PS -+ -+ * Add WMM parameter for broadcast. -+ * -+ * 12 29 2010 eddie.chen -+ * [WCXRP00000322] Add WMM IE in beacon, -+ -+Add per station flow control when STA is in PS -+ -+ * Add CWMin CWMax for AP to generate IE. -+ * -+ * 12 29 2010 eddie.chen -+ * [WCXRP00000322] Add WMM IE in beacon, -+Add per station flow control when STA is in PS -+ -+ * 1) PS flow control event -+ * -+ * 2) WMM IE in beacon, assoc resp, probe resp -+ * -+ * 12 28 2010 cp.wu -+ * [WCXRP00000269] [MT6620 Wi-Fi][Driver][Firmware] Prepare for v1.1 branch release -+ * report EEPROM used flag via NIC_CAPABILITY -+ * -+ * 12 28 2010 cp.wu -+ * [WCXRP00000269] [MT6620 Wi-Fi][Driver][Firmware] Prepare for v1.1 branch release -+ * integrate with 'EEPROM used' flag for reporting correct capability to Engineer Mode/META and other tools -+ * -+ * 12 07 2010 cm.chang -+ * [WCXRP00000238] MT6620 Wi-Fi][Driver][FW] Support regulation domain setting from NVRAM and supplicant -+ * 1. Country code is from NVRAM or supplicant -+ * 2. Change band definition in CMD/EVENT. -+ * -+ * 11 01 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000150] [MT6620 Wi-Fi][Driver] -+ * Add implementation for querying current TX rate from firmware auto rate module -+ * 1) Query link speed (TX rate) from firmware directly with buffering mechanism to reduce overhead -+ * 2) Remove CNM CH-RECOVER event handling -+ * 3) cfg read/write API renamed with kal prefix for unified naming rules. -+ * -+ * 10 27 2010 george.huang -+ * [WCXRP00000127] [MT6620 Wi-Fi][Driver] Add a registry to disable Beacon Timeout function for SQA test by using E1 EVB -+ * Support registry option for disable beacon lost detection. -+ * -+ * 10 26 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000137] [MT6620 Wi-Fi] [FW] -+ * Support NIC capability query command -+ * 1) update NVRAM content template to ver 1.02 -+ * 2) add compile option for querying NIC capability (default: off) -+ * 3) modify AIS 5GHz support to run-time option, which could be turned on by registry or NVRAM setting -+ * 4) correct auto-rate compiler error under linux (treat warning as error) -+ * 5) simplify usage of NVRAM and REG_INFO_T -+ * 6) add version checking between driver and firmware -+ * -+ * 10 08 2010 cp.wu -+ * [WCXRP00000084] [MT6620 Wi-Fi][Driver][FW] Add fixed rate support for distance test -+ * adding fixed rate support for distance test. (from registry setting) -+ * -+ * 10 06 2010 cp.wu -+ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning -+ * code reorganization to improve isolation between GLUE and CORE layers. -+ * -+ * 10 05 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check -+ * 1) add NVRAM access API -+ * 2) fake scanning result when NVRAM doesn't exist and/or version mismatch. (off by compiler option) -+ * 3) add OID implementation for NVRAM read/write service -+ * -+ * 09 27 2010 chinghwa.yu -+ * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000065] Update BoW design and settings -+ * Update BCM/BoW design and settings. -+ * -+ * 09 24 2010 cp.wu -+ * [WCXRP00000057] [MT6620 Wi-Fi][Driver] Modify online scan to a run-time switchable feature -+ * Modify online scan as a run-time adjustable option (for Windows, in registry) -+ * -+ * 09 23 2010 cp.wu -+ * [WCXRP00000051] [MT6620 Wi-Fi][Driver] WHQL test fail in MAC address changed item -+ * use firmware reported mac address right after wlanAdapterStart() as permanent address -+ * -+ * 09 08 2010 cp.wu -+ * NULL -+ * use static memory pool for storing IEs of scanning result. -+ * -+ * 09 07 2010 yuche.tsai -+ * NULL -+ * Add a common IE buffer in P2P INFO structure. -+ * -+ * 09 03 2010 kevin.huang -+ * NULL -+ * Refine #include sequence and solve recursive/nested #include issue -+ * -+ * 09 01 2010 cp.wu -+ * NULL -+ * restore configuration as before. -+ * -+ * 09 01 2010 wh.su -+ * NULL -+ * adding the wapi support for integration test. -+ * -+ * 08 31 2010 kevin.huang -+ * NULL -+ * Use LINK LIST operation to process SCAN result -+ * -+ * 08 29 2010 yuche.tsai -+ * NULL -+ * Finish SLT TX/RX & Rate Changing Support. -+ * -+ * 08 25 2010 george.huang -+ * NULL -+ * update OID/ registry control path for PM related settings -+ * -+ * 08 24 2010 cm.chang -+ * NULL -+ * Support RLM initail channel of Ad-hoc, P2P and BOW -+ * -+ * 08 23 2010 chinghwa.yu -+ * NULL -+ * Update for BOW. -+ * -+ * 08 20 2010 cm.chang -+ * NULL -+ * Migrate RLM code to host from FW -+ * -+ * 08 16 2010 yuche.tsai -+ * NULL -+ * Add an intend mode for BSS info. -+ * It is used to let P2P BSS Info to know which OP Mode it is going to become. -+ * -+ * 08 04 2010 george.huang -+ * NULL -+ * handle change PS mode OID/ CMD -+ * -+ * 08 02 2010 cp.wu -+ * NULL -+ * comment out deprecated members in BSS_INFO, which are only used by firmware rather than driver. -+ * -+ * 07 29 2010 cp.wu -+ * NULL -+ * eliminate u4FreqInKHz usage, combined into rConnections.ucAdHoc* -+ * -+ * 07 28 2010 cp.wu -+ * NULL -+ * 1) eliminate redundant variable eOPMode in prAdapter->rWlanInfo -+ * 2) change nicMediaStateChange() API prototype -+ * -+ * 07 24 2010 wh.su -+ * -+ * .support the Wi-Fi RSN -+ * -+ * 07 21 2010 yuche.tsai -+ * -+ * Add for P2P Scan Result Parsing & Saving. -+ * -+ * 07 19 2010 wh.su -+ * -+ * update for security supporting. -+ * -+ * 07 19 2010 cm.chang -+ * -+ * Set RLM parameters and enable CNM channel manager -+ * -+ * 07 19 2010 yuche.tsai -+ * -+ * Remove BSS info which is redonedent in Wifi Var.. -+ * -+ * 07 16 2010 yarco.yang -+ * -+ * 1. Support BSS Absence/Presence Event -+ * 2. Support STA change PS mode Event -+ * 3. Support BMC forwarding for AP mode. -+ * -+ * 07 14 2010 yarco.yang -+ * -+ * 1. Remove CFG_MQM_MIGRATION -+ * 2. Add CMD_UPDATE_WMM_PARMS command -+ * -+ * 07 09 2010 george.huang -+ * -+ * [WPD00001556] Migrate PM variables from FW to driver: for composing QoS Info -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 07 08 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Check draft RLM code for HT cap -+ * -+ * 06 29 2010 yarco.yang -+ * [WPD00003837][MT6620]Data Path Refine -+ * replace g_rQM with Adpater->rQM -+ * -+ * 06 28 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * 1st draft code for RLM module -+ * -+ * 06 21 2010 wh.su -+ * [WPD00003840][MT6620 5931] Security migration -+ * remove duplicate variable for migration. -+ * -+ * 06 21 2010 wh.su -+ * [WPD00003840][MT6620 5931] Security migration -+ * modify some code for concurrent network. -+ * -+ * 06 21 2010 yuche.tsai -+ * [WPD00003839][MT6620 5931][P2P] Feature migration -+ * Add P2P FSM Info in adapter. -+ * -+ * 06 21 2010 yarco.yang -+ * [WPD00003837][MT6620]Data Path Refine -+ * Support CFG_MQM_MIGRATION flag -+ * -+ * 06 18 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Provide cnmMgtPktAlloc() and alloc/free function of msg/buf -+ * -+ * 06 18 2010 wh.su -+ * [WPD00003840][MT6620 5931] Security migration -+ * migration the security related function from firmware. -+ * -+ * 06 17 2010 yuche.tsai -+ * [WPD00003839][MT6620 5931][P2P] Feature migration -+ * Add P2P related field, additional include p2p_fsm.h if p2p is enabled. -+ * -+ * 06 15 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add scan.c. -+ * -+ * 06 14 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add management dispatching function table. -+ * -+ * 06 11 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * auth.c is migrated. -+ * -+ * 06 11 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) migrate assoc.c. -+ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness -+ * 3) add configuration options for CNM_MEM and RSN modules -+ * 4) add data path for management frames -+ * 5) eliminate rPacketInfo of MSDU_INFO_T -+ * -+ * 06 10 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add buildable & linkable ais_fsm.c -+ * -+ * related reference are still waiting to be resolved -+ * -+ * 06 09 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add definitions for module migration. -+ * -+ * 06 08 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * cnm_timer has been migrated. -+ * -+ * 06 08 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * hem_mbox is migrated. -+ * -+ * 06 07 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * merge wifi_var.h, precomp.h, cnm_timer.h (data type only) -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 05 22 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * change OID behavior to meet WHQL requirement. -+ * -+ * 05 20 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) integrate OID_GEN_NETWORK_LAYER_ADDRESSES with CMD_ID_SET_IP_ADDRESS -+ * 2) buffer statistics data for 2 seconds -+ * 3) use default value for adhoc parameters instead of 0 -+ * -+ * 05 19 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) do not take timeout mechanism for power mode oids -+ * 2) retrieve network type from connection status -+ * 3) after disassciation, set radio state to off -+ * 4) TCP option over IPv6 is supported -+ * -+ * 05 18 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * implement Wakeup-on-LAN except firmware integration part -+ * -+ * 04 27 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * reserve field of privacy filter and RTS threshold setting. -+ * -+ * 04 13 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * add framework for BT-over-Wi-Fi support. -+ * * * * * * 1) prPendingCmdInfo is replaced by queue for multiple handler capability -+ * * * * * * 2) command sequence number is now increased atomically -+ * * * * * * 3) private data could be hold and taken use for other purpose -+ * -+ * 04 07 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * rWlanInfo should be placed at adapter rather than glue due to most operations -+ * * * are done in adapter layer. -+ * -+ * 04 06 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * code refine: fgTestMode should be at adapter rather than glue due to the device/fw is also involved -+ * -+ * 03 31 2010 wh.su -+ * [WPD00003816][MT6620 Wi-Fi] Adding the security support -+ * modify the wapi related code for new driver's design. -+ * -+ * 03 19 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) add ACPI D0/D3 state switching support -+ * * * 2) use more formal way to handle interrupt when the status is retrieved from enhanced RX response -+ * -+ * 03 03 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * implement OID_802_3_MULTICAST_LIST oid handling -+ * -+ * 03 02 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) the use of prPendingOid revised, all accessing are now protected by spin lock -+ * * * 2) ensure wlanReleasePendingOid will clear all command queues -+ * -+ * 02 09 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * move ucCmdSeqNum as instance variable -+ * -+ * 01 27 2010 wh.su -+ * [WPD00003816][MT6620 Wi-Fi] Adding the security support -+ * . -+ * -+ * 01 27 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1. eliminate improper variable in rHifInfo -+ * * * 2. block TX/ordinary OID when RF test mode is engaged -+ * * * 3. wait until firmware finish operation when entering into and leaving from RF test mode -+ * * * 4. correct some HAL implementation -+ * -+ * 12 30 2009 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) According to CMD/EVENT documentation v0.8, -+ * * * OID_CUSTOM_TEST_RX_STATUS & OID_CUSTOM_TEST_TX_STATUS is no longer used, -+ * * * and result is retrieved by get ATInfo instead -+ * * * 2) add 4 counter for recording aggregation statistics -+ * -+ * 12 28 2009 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * eliminate redundant variables for connection_state -+** \main\maintrunk.MT6620WiFiDriver_Prj\13 2009-12-16 18:02:03 GMT mtk02752 -+** add external reference to avoid compilation error -+** \main\maintrunk.MT6620WiFiDriver_Prj\12 2009-12-10 16:40:26 GMT mtk02752 -+** eliminate unused member -+** \main\maintrunk.MT6620WiFiDriver_Prj\11 2009-12-08 17:36:08 GMT mtk02752 -+** add RF test data members into P_ADAPTER_T -+** \main\maintrunk.MT6620WiFiDriver_Prj\10 2009-10-13 21:58:45 GMT mtk01084 -+** update for new HW architecture design -+** \main\maintrunk.MT6620WiFiDriver_Prj\9 2009-04-28 10:29:57 GMT mtk01461 -+** Add read WTSR for SDIO_STATUS_ENHANCE mode -+** \main\maintrunk.MT6620WiFiDriver_Prj\8 2009-04-21 09:37:35 GMT mtk01461 -+** Add prPendingCmdInfoOfOID for temporarily saving the CMD_INFO_T before en-queue to rCmdQueue -+** \main\maintrunk.MT6620WiFiDriver_Prj\7 2009-04-17 19:57:51 GMT mtk01461 -+** Add MGMT Buffer Info -+** \main\maintrunk.MT6620WiFiDriver_Prj\6 2009-04-01 10:34:12 GMT mtk01461 -+** Add SW pre test CFG_HIF_LOOPBACK_PRETEST -+** \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-03-23 21:41:48 GMT mtk01461 -+** Add fgIsWmmAssoc flag for TC assignment -+** \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-03-19 18:32:51 GMT mtk01084 -+** update for basic power management functions -+** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-03-18 20:51:52 GMT mtk01426 -+** Add #if CFG_SDIO_RX_ENHANCE related data structure -+** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 20:16:17 GMT mtk01426 -+** Init for develop -+** -+*/ -+ -+#ifndef _ADAPTER_H -+#define _ADAPTER_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#if CFG_SUPPORT_HOTSPOT_2_0 -+#include "hs20.h" -+#endif -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+typedef struct _ENHANCE_MODE_DATA_STRUCT_T SDIO_CTRL_T, *P_SDIO_CTRL_T; -+ -+typedef struct _WLAN_INFO_T { -+ PARAM_BSSID_EX_T rCurrBssId; -+ -+ /* Scan Result */ -+ PARAM_BSSID_EX_T arScanResult[CFG_MAX_NUM_BSS_LIST]; -+ PUINT_8 apucScanResultIEs[CFG_MAX_NUM_BSS_LIST]; -+ UINT_32 u4ScanResultNum; -+ -+ /* IE pool for Scanning Result */ -+ UINT_8 aucScanIEBuf[CFG_MAX_COMMON_IE_BUF_LEN]; -+ UINT_32 u4ScanIEBufferUsage; -+ -+ OS_SYSTIME u4SysTime; -+ -+ /* connection parameter (for Ad-Hoc) */ -+ UINT_16 u2BeaconPeriod; -+ UINT_16 u2AtimWindow; -+ -+ PARAM_RATES eDesiredRates; -+ CMD_LINK_ATTRIB eLinkAttr; -+/* CMD_PS_PROFILE_T ePowerSaveMode; */ -+ CMD_PS_PROFILE_T arPowerSaveMode[NETWORK_TYPE_INDEX_NUM]; -+ -+ /* trigger parameter */ -+ ENUM_RSSI_TRIGGER_TYPE eRssiTriggerType; -+ PARAM_RSSI rRssiTriggerValue; -+ -+ /* Privacy Filter */ -+ ENUM_PARAM_PRIVACY_FILTER_T ePrivacyFilter; -+ -+ /* RTS Threshold */ -+ PARAM_RTS_THRESHOLD eRtsThreshold; -+ -+ /* Network Type */ -+ UINT_8 ucNetworkType; -+ -+ /* Network Type In Use */ -+ UINT_8 ucNetworkTypeInUse; -+ -+} WLAN_INFO_T, *P_WLAN_INFO_T; -+ -+/* Session for CONNECTION SETTINGS */ -+typedef struct _CONNECTION_SETTINGS_T { -+ -+ UINT_8 aucMacAddress[MAC_ADDR_LEN]; -+ -+ UINT_8 ucDelayTimeOfDisconnectEvent; -+ -+ BOOLEAN fgIsConnByBssidIssued; -+ UINT_8 aucBSSID[MAC_ADDR_LEN]; -+ -+ BOOLEAN fgIsConnReqIssued; -+ BOOLEAN fgIsDisconnectedByNonRequest; -+ -+ UINT_8 ucSSIDLen; -+ UINT_8 aucSSID[ELEM_MAX_LEN_SSID]; -+ -+ ENUM_PARAM_OP_MODE_T eOPMode; -+ -+ ENUM_PARAM_CONNECTION_POLICY_T eConnectionPolicy; -+ -+ ENUM_PARAM_AD_HOC_MODE_T eAdHocMode; -+ -+ ENUM_PARAM_AUTH_MODE_T eAuthMode; -+ -+ ENUM_PARAM_ENCRYPTION_STATUS_T eEncStatus; -+ -+ BOOLEAN fgIsScanReqIssued; -+ -+ /* MIB attributes */ -+ UINT_16 u2BeaconPeriod; -+ -+ UINT_16 u2RTSThreshold; /* User desired setting */ -+ -+ UINT_16 u2DesiredNonHTRateSet; /* User desired setting */ -+ -+ UINT_8 ucAdHocChannelNum; /* For AdHoc */ -+ -+ ENUM_BAND_T eAdHocBand; /* For AdHoc */ -+ -+ UINT_32 u4FreqInKHz; /* Center frequency */ -+ -+ /* ATIM windows using for IBSS power saving function */ -+ UINT_16 u2AtimWindow; -+ -+ /* Features */ -+ BOOLEAN fgIsEnableRoaming; -+ -+ BOOLEAN fgIsAdHocQoSEnable; -+ -+ ENUM_PARAM_PHY_CONFIG_T eDesiredPhyConfig; -+ -+ /* Used for AP mode for desired channel and bandwidth */ -+ UINT_16 u2CountryCode; -+ UINT_16 u2CountryCodeBakup; -+ UINT_8 uc2G4BandwidthMode; /* 20/40M or 20M only */ -+ UINT_8 uc5GBandwidthMode; /* 20/40M or 20M only */ -+ -+ BOOLEAN fgTxShortGIDisabled; -+ BOOLEAN fgRxShortGIDisabled; -+ -+#if CFG_SUPPORT_802_11D -+ BOOLEAN fgMultiDomainCapabilityEnabled; -+#endif /* CFG_SUPPORT_802_11D */ -+ -+#if 1 /* CFG_SUPPORT_WAPI */ -+ BOOLEAN fgWapiMode; -+ UINT_32 u4WapiSelectedGroupCipher; -+ UINT_32 u4WapiSelectedPairwiseCipher; -+ UINT_32 u4WapiSelectedAKMSuite; -+#endif -+ -+ /* CR1486, CR1640 */ -+ /* for WPS, disable the privacy check for AP selection policy */ -+ BOOLEAN fgPrivacyCheckDisable; -+ -+ /* b0~3: trigger-en AC0~3. b4~7: delivery-en AC0~3 */ -+ UINT_8 bmfgApsdEnAc; -+ -+ /* for RSN info store, when upper layer set rsn info */ -+ RSN_INFO_T rRsnInfo; -+ -+} CONNECTION_SETTINGS_T, *P_CONNECTION_SETTINGS_T; -+ -+struct _BSS_INFO_T { -+ -+ ENUM_PARAM_MEDIA_STATE_T eConnectionState; /* Connected Flag used in AIS_NORMAL_TR */ -+ ENUM_PARAM_MEDIA_STATE_T eConnectionStateIndicated; /* The Media State that report to HOST */ -+ -+ ENUM_OP_MODE_T eCurrentOPMode; /* Current Operation Mode - Infra/IBSS */ -+#if CFG_ENABLE_WIFI_DIRECT -+ ENUM_OP_MODE_T eIntendOPMode; -+#endif -+ -+ BOOLEAN fgIsNetActive; /* TRUE if this network has been activated */ -+ -+ UINT_8 ucNetTypeIndex; /* ENUM_NETWORK_TYPE_INDEX_T */ -+ -+ UINT_8 ucReasonOfDisconnect; /* Used by media state indication */ -+ -+ UINT_8 ucSSIDLen; /* Length of SSID */ -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ ENUM_HIDDEN_SSID_TYPE_T eHiddenSsidType; /* For Hidden SSID usage. */ -+#endif -+ -+ UINT_8 aucSSID[ELEM_MAX_LEN_SSID]; /* SSID used in this BSS */ -+ -+ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* The BSSID of the associated BSS */ -+ -+ UINT_8 aucOwnMacAddr[MAC_ADDR_LEN]; /* Owned MAC Address used in this BSS */ -+ -+ P_STA_RECORD_T prStaRecOfAP; /* For Infra Mode, and valid only if -+ * eConnectionState == MEDIA_STATE_CONNECTED -+ */ -+ LINK_T rStaRecOfClientList; /* For IBSS/AP Mode, all known STAs in current BSS */ -+ -+ UINT_16 u2CapInfo; /* Change Detection */ -+ -+ UINT_16 u2BeaconInterval; /* The Beacon Interval of this BSS */ -+ -+ UINT_16 u2ATIMWindow; /* For IBSS Mode */ -+ -+ UINT_16 u2AssocId; /* For Infra Mode, it is the Assoc ID assigned by AP. -+ */ -+ -+ UINT_8 ucDTIMPeriod; /* For Infra/AP Mode */ -+ -+ UINT_8 ucDTIMCount; /* For AP Mode, it is the DTIM value we should carried in -+ * the Beacon of next TBTT. -+ */ -+ -+ UINT_8 ucPhyTypeSet; /* Available PHY Type Set of this peer -+ * (This is deduced from received BSS_DESC_T) -+ */ -+ -+ UINT_8 ucNonHTBasicPhyType; /* The Basic PHY Type Index, used to setup Phy Capability */ -+ -+ UINT_8 ucConfigAdHocAPMode; /* The configuration of AdHoc/AP Mode. e.g. 11g or 11b */ -+ -+ UINT_8 ucBeaconTimeoutCount; /* For Infra/AP Mode, it is a threshold of Beacon Lost Count to -+ confirm connection was lost */ -+ -+ BOOLEAN fgHoldSameBssidForIBSS; /* For IBSS Mode, to keep use same BSSID to extend the life cycle of an IBSS */ -+ -+ BOOLEAN fgIsBeaconActivated; /* For AP/IBSS Mode, it is used to indicate that Beacon is sending */ -+ -+ P_MSDU_INFO_T prBeacon; /* For AP/IBSS Mode - Beacon Frame */ -+ -+ BOOLEAN fgIsIBSSMaster; /* For IBSS Mode - To indicate that we can reply ProbeResp Frame. -+ In current TBTT interval */ -+ -+ BOOLEAN fgIsShortPreambleAllowed; /* From Capability Info. of AssocResp Frame -+ AND of Beacon/ProbeResp Frame */ -+ BOOLEAN fgUseShortPreamble; /* Short Preamble is enabled in current BSS. */ -+ BOOLEAN fgUseShortSlotTime; /* Short Slot Time is enabled in current BSS. */ -+ -+ UINT_16 u2OperationalRateSet; /* Operational Rate Set of current BSS */ -+ UINT_16 u2BSSBasicRateSet; /* Basic Rate Set of current BSS */ -+ -+ UINT_8 ucAllSupportedRatesLen; /* Used for composing Beacon Frame in AdHoc or AP Mode */ -+ UINT_8 aucAllSupportedRates[RATE_NUM]; -+ -+ UINT_8 ucAssocClientCnt; /* TODO(Kevin): Number of associated clients */ -+ -+ BOOLEAN fgIsProtection; -+ BOOLEAN fgIsQBSS; /* fgIsWmmBSS; *//* For Infra/AP/IBSS Mode, it is used to indicate if we support WMM in -+ * current BSS. */ -+ BOOLEAN fgIsNetAbsent; /* TRUE: BSS is absent, FALSE: BSS is present */ -+ -+ UINT_32 u4RsnSelectedGroupCipher; -+ UINT_32 u4RsnSelectedPairwiseCipher; -+ UINT_32 u4RsnSelectedAKMSuite; -+ UINT_16 u2RsnSelectedCapInfo; -+ -+ /*------------------------------------------------------------------------*/ -+ /* Power Management related information */ -+ /*------------------------------------------------------------------------*/ -+ PM_PROFILE_SETUP_INFO_T rPmProfSetupInfo; -+ -+ /*------------------------------------------------------------------------*/ -+ /* WMM/QoS related information */ -+ /*------------------------------------------------------------------------*/ -+ UINT_8 ucWmmParamSetCount; /* Used to detect the change of EDCA parameters. For AP mode, -+ the value is used in WMM IE */ -+ -+ AC_QUE_PARMS_T arACQueParms[WMM_AC_INDEX_NUM]; -+ -+ UINT_8 aucCWminLog2ForBcast[WMM_AC_INDEX_NUM]; /* For AP mode, broadcast the CWminLog2 */ -+ UINT_8 aucCWmaxLog2ForBcast[WMM_AC_INDEX_NUM]; /* For AP mode, broadcast the CWmaxLog2 */ -+ AC_QUE_PARMS_T arACQueParmsForBcast[WMM_AC_INDEX_NUM]; /* For AP mode, broadcast the value */ -+ -+ /*------------------------------------------------------------------------*/ -+ /* 802.11n HT operation IE when (prStaRec->ucPhyTypeSet & PHY_TYPE_BIT_HT) */ -+ /* is true. They have the same definition with fields of */ -+ /* information element (CM) */ -+ /*------------------------------------------------------------------------*/ -+ ENUM_BAND_T eBand; -+ UINT_8 ucPrimaryChannel; -+ UINT_8 ucHtOpInfo1; -+ UINT_16 u2HtOpInfo2; -+ UINT_16 u2HtOpInfo3; -+ -+ /*------------------------------------------------------------------------*/ -+ /* Required protection modes (CM) */ -+ /*------------------------------------------------------------------------*/ -+ BOOLEAN fgErpProtectMode; -+ ENUM_HT_PROTECT_MODE_T eHtProtectMode; -+ ENUM_GF_MODE_T eGfOperationMode; -+ ENUM_RIFS_MODE_T eRifsOperationMode; -+ -+ BOOLEAN fgObssErpProtectMode; /* GO only */ -+ ENUM_HT_PROTECT_MODE_T eObssHtProtectMode; /* GO only */ -+ ENUM_GF_MODE_T eObssGfOperationMode; /* GO only */ -+ BOOLEAN fgObssRifsOperationMode; /* GO only */ -+ -+ /*------------------------------------------------------------------------*/ -+ /* OBSS to decide if 20/40M bandwidth is permitted. */ -+ /* The first member indicates the following channel list length. */ -+ /*------------------------------------------------------------------------*/ -+ BOOLEAN fgAssoc40mBwAllowed; -+ BOOLEAN fg40mBwAllowed; -+ ENUM_CHNL_EXT_T eBssSCO; /* Real setting for HW -+ * 20/40M AP mode will always set 40M, -+ * but its OP IE can be changed. -+ */ -+ UINT_8 auc2G_20mReqChnlList[CHNL_LIST_SZ_2G + 1]; -+ UINT_8 auc2G_NonHtChnlList[CHNL_LIST_SZ_2G + 1]; -+ UINT_8 auc2G_PriChnlList[CHNL_LIST_SZ_2G + 1]; -+ UINT_8 auc2G_SecChnlList[CHNL_LIST_SZ_2G + 1]; -+ -+ UINT_8 auc5G_20mReqChnlList[CHNL_LIST_SZ_5G + 1]; -+ UINT_8 auc5G_NonHtChnlList[CHNL_LIST_SZ_5G + 1]; -+ UINT_8 auc5G_PriChnlList[CHNL_LIST_SZ_5G + 1]; -+ UINT_8 auc5G_SecChnlList[CHNL_LIST_SZ_5G + 1]; -+ -+ TIMER_T rObssScanTimer; -+ UINT_16 u2ObssScanInterval; /* in unit of sec */ -+ -+ BOOLEAN fgObssActionForcedTo20M; /* GO only */ -+ BOOLEAN fgObssBeaconForcedTo20M; /* GO only */ -+ -+ /*------------------------------------------------------------------------*/ -+ /* HW Related Fields (Kevin) */ -+ /*------------------------------------------------------------------------*/ -+ UINT_8 ucHwDefaultFixedRateCode; /* The default rate code copied to MAC TX Desc */ -+ UINT_16 u2HwLPWakeupGuardTimeUsec; -+ -+ UINT_8 ucBssFreeQuota; /* The value is updated from FW */ -+#if CFG_ENABLE_GTK_FRAME_FILTER -+ P_IPV4_NETWORK_ADDRESS_LIST prIpV4NetAddrList; -+#endif -+ UINT_16 u2DeauthReason; -+ -+#if (CFG_SUPPORT_TDLS == 1) -+ BOOLEAN fgTdlsIsProhibited; /* TRUE: AP prohibits TDLS links */ -+ BOOLEAN fgTdlsIsChSwProhibited; /* TRUE: AP prohibits TDLS chan switch */ -+#endif /* CFG_SUPPORT_TDLS */ -+}; -+ -+struct _AIS_SPECIFIC_BSS_INFO_T { -+ UINT_8 ucRoamingAuthTypes; /* This value indicate the roaming type used in AIS_JOIN */ -+ -+ BOOLEAN fgIsIBSSActive; -+ -+ /*! \brief Global flag to let arbiter stay at standby and not connect to any network */ -+ BOOLEAN fgCounterMeasure; -+ UINT_8 ucWEPDefaultKeyID; -+ BOOLEAN fgTransmitKeyExist; /* Legacy wep Transmit key exist or not */ -+ -+ /* While Do CounterMeasure procedure, check the EAPoL Error report have send out */ -+ BOOLEAN fgCheckEAPoLTxDone; -+ -+ UINT_32 u4RsnaLastMICFailTime; -+ -+ /* Stored the current bss wpa rsn cap filed, used for roaming policy */ -+ /* UINT_16 u2RsnCap; */ -+ TIMER_T rPreauthenticationTimer; -+ -+ /* By the flow chart of 802.11i, -+ wait 60 sec before associating to same AP -+ or roaming to a new AP -+ or sending data in IBSS, -+ keep a timer for handle the 60 sec counterMeasure */ -+ TIMER_T rRsnaBlockTrafficTimer; -+ TIMER_T rRsnaEAPoLReportTimeoutTimer; -+ -+ /* For Keep the Tx/Rx Mic key for TKIP SW Calculate Mic */ -+ /* This is only one for AIS/AP */ -+ UINT_8 aucTxMicKey[8]; -+ UINT_8 aucRxMicKey[8]; -+ -+ /* Buffer for WPA2 PMKID */ -+ /* The PMKID cache lifetime is expire by media_disconnect_indication */ -+ UINT_32 u4PmkidCandicateCount; -+ PMKID_CANDICATE_T arPmkidCandicate[CFG_MAX_PMKID_CACHE]; -+ UINT_32 u4PmkidCacheCount; -+ PMKID_ENTRY_T arPmkidCache[CFG_MAX_PMKID_CACHE]; -+ BOOLEAN fgIndicatePMKID; -+#if CFG_SUPPORT_802_11W -+ BOOLEAN fgMgmtProtection; -+ UINT_32 u4SaQueryStart; -+ UINT_32 u4SaQueryCount; -+ UINT_8 ucSaQueryTimedOut; -+ PUINT_8 pucSaQueryTransId; -+ TIMER_T rSaQueryTimer; -+ BOOLEAN fgBipKeyInstalled; -+#endif -+}; -+ -+struct _BOW_SPECIFIC_BSS_INFO_T { -+ UINT_16 u2Reserved; /* Reserved for Data Type Check */ -+}; -+ -+#if CFG_SLT_SUPPORT -+typedef struct _SLT_INFO_T { -+ -+ P_BSS_DESC_T prPseudoBssDesc; -+ UINT_16 u2SiteID; -+ UINT_8 ucChannel2G4; -+ UINT_8 ucChannel5G; -+ BOOLEAN fgIsDUT; -+ UINT_32 u4BeaconReceiveCnt; -+ /* ///////Deprecated///////// */ -+ P_STA_RECORD_T prPseudoStaRec; -+} SLT_INFO_T, *P_SLT_INFO_T; -+#endif -+ -+/* Major member variables for WiFi FW operation. -+ Variables within this region will be ready for access after WIFI function is enabled. -+*/ -+typedef struct _WIFI_VAR_T { -+ BOOLEAN fgIsRadioOff; -+ -+ BOOLEAN fgIsEnterD3ReqIssued; -+ -+ BOOLEAN fgDebugCmdResp; -+ -+ CONNECTION_SETTINGS_T rConnSettings; -+ -+ SCAN_INFO_T rScanInfo; -+ -+#if CFG_SUPPORT_ROAMING -+ ROAMING_INFO_T rRoamingInfo; -+#endif /* CFG_SUPPORT_ROAMING */ -+ -+ AIS_FSM_INFO_T rAisFsmInfo; -+ -+ ENUM_PWR_STATE_T aePwrState[NETWORK_TYPE_INDEX_NUM]; -+ -+ BSS_INFO_T arBssInfo[NETWORK_TYPE_INDEX_NUM]; -+ -+ AIS_SPECIFIC_BSS_INFO_T rAisSpecificBssInfo; -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ P_P2P_CONNECTION_SETTINGS_T prP2PConnSettings; -+ -+ P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo; -+ -+ P_P2P_FSM_INFO_T prP2pFsmInfo; -+#endif /* CFG_ENABLE_WIFI_DIRECT */ -+ -+#if CFG_ENABLE_BT_OVER_WIFI -+ BOW_SPECIFIC_BSS_INFO_T rBowSpecificBssInfo; -+ BOW_FSM_INFO_T rBowFsmInfo; -+#endif /* CFG_ENABLE_BT_OVER_WIFI */ -+ -+ DEAUTH_INFO_T arDeauthInfo[MAX_DEAUTH_INFO_COUNT]; -+ -+ /* Current Wi-Fi Settings and Flags */ -+ UINT_8 aucPermanentAddress[MAC_ADDR_LEN]; -+ UINT_8 aucMacAddress[MAC_ADDR_LEN]; -+ UINT_8 aucDeviceAddress[MAC_ADDR_LEN]; -+ UINT_8 aucInterfaceAddress[MAC_ADDR_LEN]; -+ -+ UINT_8 ucAvailablePhyTypeSet; -+ -+ ENUM_PHY_TYPE_INDEX_T eNonHTBasicPhyType2G4; /* Basic Phy Type used by SCN according -+ * to the set of Available PHY Types -+ */ -+ -+ ENUM_PARAM_PREAMBLE_TYPE_T ePreambleType; -+ ENUM_REGISTRY_FIXED_RATE_T eRateSetting; -+ -+ BOOLEAN fgIsShortSlotTimeOptionEnable; -+ /* User desired setting, but will honor the capability of AP */ -+ -+ BOOLEAN fgEnableJoinToHiddenSSID; -+ BOOLEAN fgSupportWZCDisassociation; -+ -+ BOOLEAN fgSupportQoS; -+ BOOLEAN fgSupportAmpduTx; -+ BOOLEAN fgSupportAmpduRx; -+ BOOLEAN fgSupportTspec; -+ BOOLEAN fgSupportUAPSD; -+ BOOLEAN fgSupportULPSMP; -+ UINT_8 u8SupportRxSgi20; /* 0: default 1: enable 2:disble */ -+ UINT_8 u8SupportRxSgi40; -+ UINT_8 u8SupportRxGf; -+ UINT_8 u8SupportRxSTBC; -+#if CFG_SUPPORT_CFG_FILE -+ UINT_8 ucApWpsMode; -+ UINT_8 ucCert11nMode; -+#endif -+#if CFG_SUPPORT_CE_FCC_TXPWR_LIMIT -+ UINT_8 ucCeFccTxPwrLimit; -+ UINT_8 ucCeFccTxPwrLimitCck; -+ UINT_8 ucCeFccTxPwrLimitOfdmHt20; -+ UINT_8 ucCeFccTxPwrLimitHt40; -+#endif -+ -+#if CFG_SLT_SUPPORT -+ SLT_INFO_T rSltInfo; -+#endif -+ -+#if CFG_SUPPORT_HOTSPOT_2_0 -+ HS20_INFO_T rHS20Info; -+#endif -+#if CFG_AUTO_CHANNEL_SEL_SUPPORT -+ PARAM_GET_CHN_LOAD rChnLoadInfo; -+#endif -+ -+} WIFI_VAR_T, *P_WIFI_VAR_T; /* end of _WIFI_VAR_T */ -+ -+/* cnm_timer module */ -+typedef struct { -+ LINK_T rLinkHead; -+ OS_SYSTIME rNextExpiredSysTime; -+ KAL_WAKE_LOCK_T rWakeLock; -+ BOOLEAN fgWakeLocked; -+} ROOT_TIMER, *P_ROOT_TIMER; -+ -+/* FW/DRV/NVRAM version information */ -+typedef struct { -+ -+ /* NVRAM or Registry */ -+ UINT_16 u2Part1CfgOwnVersion; -+ UINT_16 u2Part1CfgPeerVersion; -+ UINT_16 u2Part2CfgOwnVersion; -+ UINT_16 u2Part2CfgPeerVersion; -+ -+ /* Firmware */ -+ UINT_16 u2FwProductID; -+ UINT_16 u2FwOwnVersion; -+ UINT_16 u2FwPeerVersion; -+ -+} WIFI_VER_INFO_T, *P_WIFI_VER_INFO_T; -+ -+#if CFG_ENABLE_WIFI_DIRECT -+/* -+* p2p function pointer structure -+*/ -+ -+typedef struct _P2P_FUNCTION_LINKER { -+ P2P_REMOVE prP2pRemove; -+/* NIC_P2P_MEDIA_STATE_CHANGE prNicP2pMediaStateChange; */ -+/* SCAN_UPDATE_P2P_DEVICE_DESC prScanUpdateP2pDeviceDesc; */ -+/* P2P_FSM_RUN_EVENT_RX_PROBE_RESPONSE_FRAME prP2pFsmRunEventRxProbeResponseFrame; */ -+ P2P_GENERATE_P2P_IE prP2pGenerateWSC_IEForBeacon; -+/* P2P_CALCULATE_WSC_IE_LEN_FOR_PROBE_RSP prP2pCalculateWSC_IELenForProbeRsp; */ -+/* P2P_GENERATE_WSC_IE_FOR_PROBE_RSP prP2pGenerateWSC_IEForProbeRsp; */ -+/* SCAN_REMOVE_P2P_BSS_DESC prScanRemoveP2pBssDesc; */ -+/* P2P_HANDLE_SEC_CHECK_RSP prP2pHandleSecCheckRsp; */ -+ P2P_NET_REGISTER prP2pNetRegister; -+ P2P_NET_UNREGISTER prP2pNetUnregister; -+ P2P_CALCULATE_P2P_IE_LEN prP2pCalculateP2p_IELenForAssocReq; /* All IEs generated from supplicant. */ -+ P2P_GENERATE_P2P_IE prP2pGenerateP2p_IEForAssocReq; /* All IEs generated from supplicant. */ -+} P2P_FUNCTION_LINKER, *P_P2P_FUNCTION_LINKER; -+ -+#endif -+ -+/* -+ *State Machine: -+ *-->STOP: Turn on/off WiFi -+ *-->DISABLE: Screen was off (wlanHandleSystemSuspend) -+ *-->ENABLE: Screen was on (wlanHandleSystemResume) -+ *----->clear DISABLE -+ *-->RUNNING: Screen was on && Tx/Rx was ongoing (wlanHardStartXmit/kalRxIndicatePkts) -+*/ -+struct GL_PER_MON_T { -+ TIMER_T rPerfMonTimer; -+ ULONG ulPerfMonFlag; -+ ULONG ulLastTxBytes; -+ ULONG ulLastRxBytes; -+ ULONG ulP2PLastTxBytes; -+ ULONG ulP2PLastRxBytes; -+ /*in bps*/ -+ ULONG ulThroughput; -+ /*in ms*/ -+ UINT32 u4UpdatePeriod; -+ UINT32 u4TarPerfLevel; -+ UINT32 u4CurrPerfLevel; -+}; -+ -+/* -+ * Major ADAPTER structure -+ * Major data structure for driver operation -+ */ -+struct _ADAPTER_T { -+ UINT_8 ucRevID; -+ -+ UINT_16 u2NicOpChnlNum; -+ -+ BOOLEAN fgIsEnableWMM; -+ BOOLEAN fgIsWmmAssoc; /* This flag is used to indicate that WMM is enable in current BSS */ -+ -+ UINT_32 u4OsPacketFilter; /* packet filter used by OS */ -+ -+#if CFG_TCP_IP_CHKSUM_OFFLOAD -+ UINT_32 u4CSUMFlags; -+#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */ -+ -+ ENUM_BAND_T aePreferBand[NETWORK_TYPE_INDEX_NUM]; -+ -+ /* ADAPTER flags */ -+ UINT_32 u4Flags; -+ UINT_32 u4HwFlags; -+ -+ BOOLEAN fgIsRadioOff; -+ -+ BOOLEAN fgIsEnterD3ReqIssued; -+ -+ UINT_8 aucMacAddress[MAC_ADDR_LEN]; -+ -+ ENUM_PHY_TYPE_INDEX_T eCurrentPhyType; /* Current selection basing on the set of Available PHY Types */ -+ -+#if CFG_COALESCING_BUFFER_SIZE || CFG_SDIO_RX_AGG -+ UINT_32 u4CoalescingBufCachedSize; -+ PUINT_8 pucCoalescingBufCached; -+#endif /* CFG_COALESCING_BUFFER_SIZE */ -+ -+ /* Buffer for CMD_INFO_T, Mgt packet and mailbox message */ -+ BUF_INFO_T rMgtBufInfo; -+ BUF_INFO_T rMsgBufInfo; -+ PUINT_8 pucMgtBufCached; -+ UINT_32 u4MgtBufCachedSize; -+ UINT_8 aucMsgBuf[MSG_BUFFER_SIZE]; -+#if CFG_DBG_MGT_BUF -+ UINT_32 u4MemAllocDynamicCount; /* Debug only */ -+ UINT_32 u4MemFreeDynamicCount; /* Debug only */ -+#endif -+ -+ STA_RECORD_T arStaRec[CFG_STA_REC_NUM]; -+ -+ /* Element for TX PATH */ -+ TX_CTRL_T rTxCtrl; -+ QUE_T rFreeCmdList; -+ CMD_INFO_T arHifCmdDesc[CFG_TX_MAX_CMD_PKT_NUM]; -+ -+ /* Element for RX PATH */ -+ RX_CTRL_T rRxCtrl; -+ -+ P_SDIO_CTRL_T prSDIOCtrl; -+ -+#if (MT6620_E1_ASIC_HIFSYS_WORKAROUND == 1) -+ /* Element for MT6620 E1 HIFSYS workaround */ -+ BOOLEAN fgIsClockGatingEnabled; -+#endif -+ -+ /* Buffer for Authentication Event */ -+ /* Move to glue layer and refine the kal function */ -+ /* Reference to rsnGeneratePmkidIndication function at rsn.c */ -+ UINT_8 aucIndicationEventBuffer[(CFG_MAX_PMKID_CACHE * 20) + 8]; -+ -+ UINT_32 u4IntStatus; -+ -+ ENUM_ACPI_STATE_T rAcpiState; -+ -+ BOOLEAN fgIsIntEnable; -+ BOOLEAN fgIsIntEnableWithLPOwnSet; -+ -+ BOOLEAN fgIsFwOwn; -+ BOOLEAN fgWiFiInSleepyState; -+ -+ UINT_32 u4PwrCtrlBlockCnt; -+ -+ QUE_T rPendingCmdQueue; -+ -+ P_GLUE_INFO_T prGlueInfo; -+ -+ UINT_8 ucCmdSeqNum; -+ UINT_8 ucTxSeqNum; -+ -+#if 1 /* CFG_SUPPORT_WAPI */ -+ BOOLEAN fgUseWapi; -+#endif -+ -+ /* RF Test flags */ -+ BOOLEAN fgTestMode; -+ -+ /* WLAN Info for DRIVER_CORE OID query */ -+ WLAN_INFO_T rWlanInfo; -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ BOOLEAN fgIsP2PRegistered; -+ ENUM_NET_REG_STATE_T rP2PNetRegState; -+ BOOLEAN fgIsWlanLaunched; -+ P_P2P_INFO_T prP2pInfo; -+#if CFG_SUPPORT_P2P_RSSI_QUERY -+ OS_SYSTIME rP2pLinkQualityUpdateTime; -+ BOOLEAN fgIsP2pLinkQualityValid; -+ EVENT_LINK_QUALITY rP2pLinkQuality; -+#endif -+ -+ /* FSM Timer */ -+ TIMER_T rP2pFsmTimeoutTimer; -+#endif -+ -+ /* Online Scan Option */ -+ BOOLEAN fgEnOnlineScan; -+ -+ /* Online Scan Option */ -+ BOOLEAN fgDisBcnLostDetection; -+ -+ /* MAC address */ -+ PARAM_MAC_ADDRESS rMyMacAddr; -+ -+ /* Wake-up Event for WOL */ -+ UINT_32 u4WakeupEventEnable; -+ -+ /* Event Buffering */ -+ EVENT_STATISTICS rStatStruct; -+ OS_SYSTIME rStatUpdateTime; -+ BOOLEAN fgIsStatValid; -+ -+ EVENT_LINK_QUALITY rLinkQuality; -+ OS_SYSTIME rLinkQualityUpdateTime; -+ BOOLEAN fgIsLinkQualityValid; -+ OS_SYSTIME rLinkRateUpdateTime; -+ BOOLEAN fgIsLinkRateValid; -+ -+ /* WIFI_VAR_T */ -+ WIFI_VAR_T rWifiVar; -+ -+ /* MTK WLAN NIC driver IEEE 802.11 MIB */ -+ IEEE_802_11_MIB_T rMib; -+ -+ /* Mailboxs for inter-module communication */ -+ MBOX_T arMbox[MBOX_ID_TOTAL_NUM]; -+ -+ /* Timers for OID Pending Handling */ -+ TIMER_T rOidTimeoutTimer; -+ -+ TIMER_T rReturnIndicatedRfbListTimer; -+ -+ /* Root Timer for cnm_timer module */ -+ ROOT_TIMER rRootTimer; -+ -+ /* RLM maintenance */ -+ ENUM_CHNL_EXT_T eRfSco; -+ ENUM_SYS_PROTECT_MODE_T eSysProtectMode; -+ ENUM_GF_MODE_T eSysHtGfMode; -+ ENUM_RIFS_MODE_T eSysTxRifsMode; -+ ENUM_SYS_PCO_PHASE_T eSysPcoPhase; -+ -+ P_DOMAIN_INFO_ENTRY prDomainInfo; -+ -+ /* QM */ -+ QUE_MGT_T rQM; -+ -+ CNM_INFO_T rCnmInfo; -+ -+ UINT_32 u4PowerMode; -+ -+ UINT_32 u4CtiaPowerMode; -+ BOOLEAN fgEnCtiaPowerMode; -+ -+ UINT_32 fgEnArpFilter; -+ -+ UINT_32 u4UapsdAcBmp; -+ -+ UINT_32 u4MaxSpLen; -+ -+ UINT_32 u4PsCurrentMeasureEn; -+ -+ /* Version Information */ -+ WIFI_VER_INFO_T rVerInfo; -+ -+ /* 5GHz support (from F/W) */ -+ BOOLEAN fgIsHw5GBandDisabled; -+ BOOLEAN fgEnable5GBand; -+ BOOLEAN fgIsEepromUsed; -+ BOOLEAN fgIsEfuseValid; -+ BOOLEAN fgIsEmbbededMacAddrValid; -+ -+#if CFG_SUPPORT_PWR_LIMIT_COUNTRY -+ BOOLEAN fgIsPowerLimitTableValid; -+#endif -+ -+ /* Packet Forwarding Tracking */ -+ INT_32 i4PendingFwdFrameCount; -+ -+#if CFG_SUPPORT_RDD_TEST_MODE -+ UINT_8 ucRddStatus; -+#endif -+ -+ BOOLEAN fgDisStaAgingTimeoutDetection; -+#if CFG_SUPPORT_CFG_FILE -+ P_WLAN_CFG_T prWlanCfg; -+ WLAN_CFG_T rWlanCfg; -+#endif -+#if CFG_SPM_WORKAROUND_FOR_HOTSPOT -+ KAL_WAKE_LOCK_T rApWakeLock; -+#endif -+ UINT_32 u4FwCompileFlag0; -+ UINT_32 u4FwCompileFlag1; -+ KAL_WAKE_LOCK_T rTxThreadWakeLock; -+ KAL_WAKE_LOCK_T rAhbIsrWakeLock; -+ -+#if CFG_SUPPORT_ROAMING_ENC -+ BOOLEAN fgIsRoamingEncEnabled; -+#endif /* CFG_SUPPORT_ROAMING_ENC */ -+ -+#if (CFG_SUPPORT_TDLS == 1) -+ BOOLEAN fgTdlsIsSup; -+#endif /* CFG_SUPPORT_TDLS */ -+ -+ UINT_8 ucScanTime; -+ -+#if CFG_SUPPORT_DBG_POWERMODE -+ BOOLEAN fgEnDbgPowerMode; /* dbg privilege power mode, always keep in active */ -+#endif -+ -+ UINT_32 u4AirDelayTotal; /* dbg privilege power mode, always keep in active */ -+ ULONG ulSuspendFlag; -+ struct GL_PER_MON_T rPerMonitor; -+}; /* end of _ADAPTER_T */ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+#define SUSPEND_FLAG_FOR_WAKEUP_REASON (0) -+#define SUSPEND_FLAG_CLEAR_WHEN_RESUME (1) -+ -+/*----------------------------------------------------------------------------*/ -+/* Macros for BSS_INFO_T - Flag of Net Active */ -+/*----------------------------------------------------------------------------*/ -+#define IS_NET_ACTIVE(_prAdapter, _NetTypeIndex) \ -+ (_prAdapter->rWifiVar.arBssInfo[(_NetTypeIndex)].fgIsNetActive) -+#define IS_BSS_ACTIVE(_prBssInfo) ((_prBssInfo)->fgIsNetActive) -+ -+#define IS_AIS_ACTIVE(_prAdapter) IS_NET_ACTIVE(_prAdapter, NETWORK_TYPE_AIS_INDEX) -+#define IS_P2P_ACTIVE(_prAdapter) IS_NET_ACTIVE(_prAdapter, NETWORK_TYPE_P2P_INDEX) -+#define IS_BOW_ACTIVE(_prAdapter) IS_NET_ACTIVE(_prAdapter, NETWORK_TYPE_BOW_INDEX) -+ -+#define SET_NET_ACTIVE(_prAdapter, _NetTypeIndex) \ -+ {_prAdapter->rWifiVar.arBssInfo[(_NetTypeIndex)].fgIsNetActive = TRUE; } -+ -+#define UNSET_NET_ACTIVE(_prAdapter, _NetTypeIndex) \ -+ {_prAdapter->rWifiVar.arBssInfo[(_NetTypeIndex)].fgIsNetActive = FALSE; } -+ -+#define BSS_INFO_INIT(_prAdapter, _NetTypeIndex) \ -+ { UINT_8 _aucZeroMacAddr[] = NULL_MAC_ADDR; \ -+ P_BSS_INFO_T _prBssInfo = &(_prAdapter->rWifiVar.arBssInfo[(_NetTypeIndex)]); \ -+ \ -+ _prBssInfo->eConnectionState = PARAM_MEDIA_STATE_DISCONNECTED; \ -+ _prBssInfo->eConnectionStateIndicated = PARAM_MEDIA_STATE_DISCONNECTED; \ -+ _prBssInfo->eCurrentOPMode = OP_MODE_INFRASTRUCTURE; \ -+ _prBssInfo->fgIsNetActive = FALSE; \ -+ _prBssInfo->ucNetTypeIndex = (_NetTypeIndex); \ -+ _prBssInfo->ucReasonOfDisconnect = DISCONNECT_REASON_CODE_RESERVED; \ -+ COPY_MAC_ADDR(_prBssInfo->aucBSSID, _aucZeroMacAddr); \ -+ LINK_INITIALIZE(&_prBssInfo->rStaRecOfClientList); \ -+ _prBssInfo->fgIsBeaconActivated = FALSE; \ -+ _prBssInfo->ucHwDefaultFixedRateCode = RATE_CCK_1M_LONG; \ -+ _prBssInfo->fgIsNetAbsent = FALSE; \ -+ } -+ -+#if CFG_ENABLE_BT_OVER_WIFI -+#define BOW_BSS_INFO_INIT(_prAdapter, _NetTypeIndex) \ -+ { \ -+ P_BSS_INFO_T _prBssInfo = &(_prAdapter->rWifiVar.arBssInfo[(_NetTypeIndex)]); \ -+ \ -+ _prBssInfo->eConnectionState = PARAM_MEDIA_STATE_DISCONNECTED; \ -+ _prBssInfo->eConnectionStateIndicated = PARAM_MEDIA_STATE_DISCONNECTED; \ -+ _prBssInfo->eCurrentOPMode = OP_MODE_BOW; \ -+ _prBssInfo->ucNetTypeIndex = (_NetTypeIndex); \ -+ _prBssInfo->ucReasonOfDisconnect = DISCONNECT_REASON_CODE_RESERVED; \ -+ LINK_INITIALIZE(&_prBssInfo->rStaRecOfClientList); \ -+ _prBssInfo->fgIsBeaconActivated = TRUE; \ -+ _prBssInfo->ucHwDefaultFixedRateCode = RATE_CCK_1M_LONG; \ -+ _prBssInfo->fgIsNetAbsent = FALSE; \ -+ } -+#endif -+ -+#define PERF_MON_DISABLE_BIT_OFF (0) -+#define PERF_MON_STOP_BIT_OFF (1) -+#define PERF_MON_RUNNING_BIT_OFF (2) -+ -+#define THROUGHPUT_L1_THRESHOLD (20*1024*1024) -+#define THROUGHPUT_L2_THRESHOLD (60*1024*1024) -+#define THROUGHPUT_L3_THRESHOLD (135*1024*1024) -+ -+/*----------------------------------------------------------------------------*/ -+/* Macros for Power State */ -+/*----------------------------------------------------------------------------*/ -+#define SET_NET_PWR_STATE_IDLE(_prAdapter, _NetTypeIndex) \ -+ {_prAdapter->rWifiVar.aePwrState[(_NetTypeIndex)] = PWR_STATE_IDLE; } -+ -+#define SET_NET_PWR_STATE_ACTIVE(_prAdapter, _NetTypeIndex) \ -+ {_prAdapter->rWifiVar.aePwrState[(_NetTypeIndex)] = PWR_STATE_ACTIVE; } -+ -+#define SET_NET_PWR_STATE_PS(_prAdapter, _NetTypeIndex) \ -+ {_prAdapter->rWifiVar.aePwrState[(_NetTypeIndex)] = PWR_STATE_PS; } -+ -+#define IS_NET_PWR_STATE_ACTIVE(_prAdapter, _NetTypeIndex) \ -+ (_prAdapter->rWifiVar.aePwrState[(_NetTypeIndex)] == PWR_STATE_ACTIVE) -+ -+#define IS_NET_PWR_STATE_IDLE(_prAdapter, _NetTypeIndex) \ -+ (_prAdapter->rWifiVar.aePwrState[(_NetTypeIndex)] == PWR_STATE_IDLE) -+ -+#define IS_SCN_PWR_STATE_ACTIVE(_prAdapter) \ -+ (_prAdapter->rWifiVar.rScanInfo.eScanPwrState == SCAN_PWR_STATE_ACTIVE) -+ -+#define IS_SCN_PWR_STATE_IDLE(_prAdapter) \ -+ (_prAdapter->rWifiVar.rScanInfo.eScanPwrState == SCAN_PWR_STATE_IDLE) -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif /* _ADAPTER_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/bow.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/bow.h -new file mode 100644 -index 000000000000..6c4c1b76622b ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/bow.h -@@ -0,0 +1,322 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/nic/bow.h#1 -+*/ -+ -+/* -+** Log: bow.h -+ * -+ * 01 16 2012 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Support BOW for 5GHz band. -+ * -+ * 05 25 2011 terry.wu -+ * [WCXRP00000735] [MT6620 Wi-Fi][BoW][FW/Driver] Protect BoW connection establishment -+ * Add BoW Cancel Scan Request and Turn On deactive network function. -+ * -+ * 05 22 2011 terry.wu -+ * [WCXRP00000735] [MT6620 Wi-Fi][BoW][FW/Driver] Protect BoW connection establishment -+ * Submit missing BoW header files. -+ * -+ * 03 27 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Support multiple physical link. -+ * -+ * 03 06 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Sync BOW Driver to latest person development branch version.. -+ * -+ * 02 10 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Fix kernel API change issue. -+ * Before ALPS 2.2 (2.2 included), kfifo_alloc() is -+ * struct kfifo *kfifo_alloc(unsigned int size, gfp_t gfp_mask, spinlock_t *lock); -+ * After ALPS 2.3, kfifo_alloc() is changed to -+ * int kfifo_alloc(struct kfifo *fifo, unsigned int size, gfp_t gfp_mask); -+ * -+ * 02 10 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Update BOW structure. -+ * -+ * 02 09 2011 cp.wu -+ * [WCXRP00000430] [MT6620 Wi-Fi][Firmware][Driver] Create V1.2 branch for MT6620E1 and MT6620E3 -+ * create V1.2 driver branch based on label MT6620_WIFI_DRIVER_V1_2_110209_1031 -+ * with BOW and P2P enabled as default -+ * -+ * 02 08 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Replace kfifo_get and kfifo_put with kfifo_out and kfifo_in. -+ * Update BOW get MAC status, remove returning event for AIS network type. -+ * -+ * 01 11 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Add Activity Report definition. -+ * -+ * 10 18 2010 chinghwa.yu -+ * [WCXRP00000110] [MT6620 Wi-Fi] [Driver] Fix BoW Connected event size -+ * Fix wrong BoW event size. -+ * -+ * 07 15 2010 cp.wu -+ * -+ * sync. bluetooth-over-Wi-Fi interface to driver interface document v0.2.6. -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 05 13 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * 1) all BT physical handles shares the same RSSI/Link Quality. -+ * 2) simplify BT command composing -+ * -+ * 04 28 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * change prefix for data structure used to communicate with 802.11 PAL -+ * to avoid ambiguous naming with firmware interface -+ * -+ * 04 27 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * basic implementation for EVENT_BT_OVER_WIFI -+ * -+ * 04 13 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * add framework for BT-over-Wi-Fi support. -+ * * * * * * * 1) prPendingCmdInfo is replaced by queue for multiple handler capability -+ * * * * * * * 2) command sequence number is now increased atomically -+ * * * * * * * 3) private data could be hold and taken use for other purpose -+ * -+ * 04 09 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * sync. with design document for interface change. -+ * -+ * 04 02 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * Wi-Fi driver no longer needs to implement 802.11 PAL, thus replaced by wrapping command/event definitions -+ * -+ * 03 16 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * correct typo. -+ * -+ * 03 16 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * update for all command/event needed to be supported by 802.11 PAL. -+ * -+ * 03 16 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * build up basic data structure and definitions to support BT-over-WiFi -+ * -+*/ -+ -+#ifndef _BOW_H_ -+#define _BOW_H_ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+#define BOWDEVNAME "bow0" -+ -+#define MAX_BOW_NUMBER_OF_CHANNEL_2G4 14 -+#define MAX_BOW_NUMBER_OF_CHANNEL_5G 4 -+/* (MAX_BOW_NUMBER_OF_CHANNEL_2G4 + MAX_BOW_NUMBER_OF_CHANNEL_5G) */ -+#define MAX_BOW_NUMBER_OF_CHANNEL 18 -+ -+#define MAX_ACTIVITY_REPORT 2 -+#define MAX_ACTIVITY_REPROT_TIME 660 -+ -+#define ACTIVITY_REPORT_STATUS_SUCCESS 0 -+#define ACTIVITY_REPORT_STATUS_FAILURE 1 -+#define ACTIVITY_REPORT_STATUS_TIME_INVALID 2 -+#define ACTIVITY_REPORT_STATUS_OTHERS 3 -+ -+#define ACTIVITY_REPORT_SCHEDULE_UNKNOWN 0 /* Does not know the schedule of the interference */ -+#define ACTIVITY_REPORT_SCHEDULE_KNOWN 1 -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+typedef struct _BT_OVER_WIFI_COMMAND_HEADER_T { -+ UINT_8 ucCommandId; -+ UINT_8 ucSeqNumber; -+ UINT_16 u2PayloadLength; -+} AMPC_COMMAND_HEADER_T, *P_AMPC_COMMAND_HEADER_T; -+ -+typedef struct _BT_OVER_WIFI_COMMAND { -+ AMPC_COMMAND_HEADER_T rHeader; -+ UINT_8 aucPayload[0]; -+} AMPC_COMMAND, *P_AMPC_COMMAND; -+ -+typedef struct _BT_OVER_WIFI_EVENT_HEADER_T { -+ UINT_8 ucEventId; -+ UINT_8 ucSeqNumber; -+ UINT_16 u2PayloadLength; -+} AMPC_EVENT_HEADER_T, *P_AMPC_EVENT_HEADER_T; -+ -+typedef struct _BT_OVER_WIFI_EVENT { -+ AMPC_EVENT_HEADER_T rHeader; -+ UINT_8 aucPayload[0]; -+} AMPC_EVENT, *P_AMPC_EVENT; -+ -+typedef struct _CHANNEL_DESC_T { -+ UINT_8 ucChannelBand; -+ UINT_8 ucChannelNum; -+} CHANNEL_DESC, P_CHANNEL_DESC; -+ -+/* Command Structures */ -+typedef struct _BOW_SETUP_CONNECTION { -+/* Fixed to 2.4G */ -+ UINT_8 ucChannelNum; -+ UINT_8 ucReserved1; -+ UINT_8 aucPeerAddress[6]; -+ UINT_16 u2BeaconInterval; -+ UINT_8 ucTimeoutDiscovery; -+ UINT_8 ucTimeoutInactivity; -+ UINT_8 ucRole; -+ UINT_8 ucPAL_Capabilities; -+ INT_8 cMaxTxPower; -+ UINT_8 ucReserved2; -+ -+/* Pending, for future BOW 5G supporting. */ -+/* UINT_8 aucPeerAddress[6]; -+ UINT_16 u2BeaconInterval; -+ UINT_8 ucTimeoutDiscovery; -+ UINT_8 ucTimeoutInactivity; -+ UINT_8 ucRole; -+ UINT_8 ucPAL_Capabilities; -+ INT_8 cMaxTxPower; -+ UINT_8 ucChannelListNum; -+ CHANNEL_DESC arChannelList[1]; -+*/ -+} BOW_SETUP_CONNECTION, *P_BOW_SETUP_CONNECTION; -+ -+typedef struct _BOW_DESTROY_CONNECTION { -+ UINT_8 aucPeerAddress[6]; -+ UINT_8 aucReserved[2]; -+} BOW_DESTROY_CONNECTION, *P_BOW_DESTROY_CONNECTION; -+ -+typedef struct _BOW_SET_PTK { -+ UINT_8 aucPeerAddress[6]; -+ UINT_8 aucReserved[2]; -+ UINT_8 aucTemporalKey[16]; -+} BOW_SET_PTK, *P_BOW_SET_PTK; -+ -+typedef struct _BOW_READ_RSSI { -+ UINT_8 aucPeerAddress[6]; -+ UINT_8 aucReserved[2]; -+} BOW_READ_RSSI, *P_BOW_READ_RSSI; -+ -+typedef struct _BOW_READ_LINK_QUALITY { -+ UINT_8 aucPeerAddress[6]; -+ UINT_8 aucReserved[2]; -+} BOW_READ_LINK_QUALITY, *P_BOW_READ_LINK_QUALITY; -+ -+typedef struct _BOW_SHORT_RANGE_MODE { -+ UINT_8 aucPeerAddress[6]; -+ INT_8 cTxPower; -+ UINT_8 ucReserved; -+} BOW_SHORT_RANGE_MODE, *P_BOW_SHORT_RANGE_MODE; -+ -+/* Event Structures */ -+typedef struct _BOW_COMMAND_STATUS { -+ UINT_8 ucStatus; -+ UINT_8 ucReserved[3]; -+} BOW_COMMAND_STATUS, *P_BOW_COMMAND_STATUS; -+ -+typedef struct _BOW_MAC_STATUS { -+ UINT_8 aucMacAddr[6]; -+ UINT_8 ucAvailability; -+ UINT_8 ucNumOfChannel; -+ CHANNEL_DESC arChannelList[MAX_BOW_NUMBER_OF_CHANNEL]; -+} BOW_MAC_STATUS, *P_BOW_MAC_STATUS; -+ -+typedef struct _BOW_LINK_CONNECTED { -+ CHANNEL_DESC rChannel; -+ UINT_8 aucReserved; -+ UINT_8 aucPeerAddress[6]; -+} BOW_LINK_CONNECTED, *P_BOW_LINK_CONNECTED; -+ -+typedef struct _BOW_LINK_DISCONNECTED { -+ UINT_8 ucReason; -+ UINT_8 aucReserved; -+ UINT_8 aucPeerAddress[6]; -+} BOW_LINK_DISCONNECTED, *P_BOW_LINK_DISCONNECTED; -+ -+typedef struct _BOW_RSSI { -+ INT_8 cRssi; -+ UINT_8 aucReserved[3]; -+} BOW_RSSI, *P_BOW_RSSI; -+ -+typedef struct _BOW_LINK_QUALITY { -+ UINT_8 ucLinkQuality; -+ UINT_8 aucReserved[3]; -+} BOW_LINK_QUALITY, *P_BOW_LINK_QUALITY; -+ -+typedef enum _ENUM_BOW_CMD_ID_T { -+ BOW_CMD_ID_GET_MAC_STATUS = 1, -+ BOW_CMD_ID_SETUP_CONNECTION, -+ BOW_CMD_ID_DESTROY_CONNECTION, -+ BOW_CMD_ID_SET_PTK, -+ BOW_CMD_ID_READ_RSSI, -+ BOW_CMD_ID_READ_LINK_QUALITY, -+ BOW_CMD_ID_SHORT_RANGE_MODE, -+ BOW_CMD_ID_GET_CHANNEL_LIST, -+} ENUM_BOW_CMD_ID_T, *P_ENUM_BOW_CMD_ID_T; -+ -+typedef enum _ENUM_BOW_EVENT_ID_T { -+ BOW_EVENT_ID_COMMAND_STATUS = 1, -+ BOW_EVENT_ID_MAC_STATUS, -+ BOW_EVENT_ID_LINK_CONNECTED, -+ BOW_EVENT_ID_LINK_DISCONNECTED, -+ BOW_EVENT_ID_RSSI, -+ BOW_EVENT_ID_LINK_QUALITY, -+ BOW_EVENT_ID_CHANNEL_LIST, -+ BOW_EVENT_ID_CHANNEL_SELECTED, -+} ENUM_BOW_EVENT_ID_T, *P_ENUM_BOW_EVENT_ID_T; -+ -+typedef enum _ENUM_BOW_DEVICE_STATE { -+ BOW_DEVICE_STATE_DISCONNECTED = 0, -+ BOW_DEVICE_STATE_DISCONNECTING, -+ BOW_DEVICE_STATE_ACQUIRING_CHANNEL, -+ BOW_DEVICE_STATE_STARTING, -+ BOW_DEVICE_STATE_SCANNING, -+ BOW_DEVICE_STATE_CONNECTING, -+ BOW_DEVICE_STATE_CONNECTED, -+ BOW_DEVICE_STATE_NUM -+} ENUM_BOW_DEVICE_STATE, *P_ENUM_BOW_DEVICE_STATE; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+#endif /*_BOW_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/cmd_buf.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/cmd_buf.h -new file mode 100644 -index 000000000000..c1ecb303b877 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/cmd_buf.h -@@ -0,0 +1,150 @@ -+/* -+** Id: -+*/ -+ -+/*! \file "cmd_buf.h" -+ \brief In this file we define the structure for Command Packet. -+ -+ In this file we define the structure for Command Packet and the control unit -+ of MGMT Memory Pool. -+*/ -+ -+/* -+** Log: cmd_buf.h -+ * -+ * 10 04 2010 cp.wu -+ * [WCXRP00000077] [MT6620 Wi-Fi][Driver][FW] Eliminate use of ENUM_NETWORK_TYPE_T and replaced by -+ * ENUM_NETWORK_TYPE_INDEX_T only -+ * remove ENUM_NETWORK_TYPE_T definitions -+ * -+ * 09 03 2010 kevin.huang -+ * NULL -+ * Refine #include sequence and solve recursive/nested #include issue -+ * -+ * 07 13 2010 cp.wu -+ * -+ * 1) MMPDUs are now sent to MT6620 by CMD queue for keeping strict order of 1X/MMPDU/CMD packets -+ * 2) integrate with qmGetFrameAction() for deciding which MMPDU/1X could pass checking for sending -+ * 2) enhance CMD_INFO_T descriptor number from 10 to 32 to avoid descriptor underflow -+ * under concurrent network operation -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 07 01 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Enable change log -+*/ -+ -+#ifndef _CMD_BUF_H -+#define _CMD_BUF_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+typedef enum _COMMAND_TYPE { -+ COMMAND_TYPE_GENERAL_IOCTL, -+ COMMAND_TYPE_NETWORK_IOCTL, -+ COMMAND_TYPE_SECURITY_FRAME, -+ COMMAND_TYPE_MANAGEMENT_FRAME, -+ COMMAND_TYPE_NUM -+} COMMAND_TYPE, *P_COMMAND_TYPE; -+ -+typedef VOID(*PFN_CMD_DONE_HANDLER) (IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); -+ -+typedef VOID(*PFN_CMD_TIMEOUT_HANDLER) (IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo); -+ -+struct _CMD_INFO_T { -+ QUE_ENTRY_T rQueEntry; -+ -+ COMMAND_TYPE eCmdType; -+ -+ UINT_16 u2InfoBufLen; /* This is actual CMD buffer length */ -+ PUINT_8 pucInfoBuffer; /* May pointer to structure in prAdapter */ -+ P_NATIVE_PACKET prPacket; /* only valid when it's a security frame */ -+ -+ ENUM_NETWORK_TYPE_INDEX_T eNetworkType; -+ UINT_8 ucStaRecIndex; /* only valid when it's a security frame */ -+ -+ PFN_CMD_DONE_HANDLER pfCmdDoneHandler; -+ PFN_CMD_TIMEOUT_HANDLER pfCmdTimeoutHandler; -+ -+ BOOLEAN fgIsOid; /* Used to check if we need indicate */ -+ -+ UINT_8 ucCID; -+ BOOLEAN fgSetQuery; -+ BOOLEAN fgNeedResp; -+ BOOLEAN fgDriverDomainMCR; /* Access Driver Domain MCR, for CMD_ID_ACCESS_REG only */ -+ UINT_8 ucCmdSeqNum; -+ UINT_32 u4SetInfoLen; /* Indicate how many byte we read for Set OID */ -+ -+ /* information indicating by OID/ioctl */ -+ PVOID pvInformationBuffer; -+ UINT_32 u4InformationBufferLength; -+ -+ /* private data */ -+ UINT_32 u4PrivateData; -+}; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+VOID cmdBufInitialize(IN P_ADAPTER_T prAdapter); -+ -+P_CMD_INFO_T cmdBufAllocateCmdInfo(IN P_ADAPTER_T prAdapter, IN UINT_32 u4Length); -+ -+VOID cmdBufFreeCmdInfo(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo); -+ -+/*----------------------------------------------------------------------------*/ -+/* Routines for CMDs */ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanSendSetQueryCmd(IN P_ADAPTER_T prAdapter, -+ UINT_8 ucCID, -+ BOOLEAN fgSetQuery, -+ BOOLEAN fgNeedResp, -+ BOOLEAN fgIsOid, -+ PFN_CMD_DONE_HANDLER pfCmdDoneHandler, -+ PFN_CMD_TIMEOUT_HANDLER pfCmdTimeoutHandler, -+ UINT_32 u4SetQueryInfoLen, -+ PUINT_8 pucInfoBuffer, OUT PVOID pvSetQueryBuffer, IN UINT_32 u4SetQueryBufferLen); -+VOID cmdBufDumpCmdQueue(P_QUE_T prQueue, CHAR *queName); -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+#endif /* _CMD_BUF_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/hal.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/hal.h -new file mode 100644 -index 000000000000..0fdb9dcadeef ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/hal.h -@@ -0,0 +1,618 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/nic/hal.h#1 -+*/ -+ -+/*! \file "hal.h" -+ \brief The declaration of hal functions -+ -+ N/A -+*/ -+ -+/* -+** Log: hal.h -+ * -+ * 04 01 2011 tsaiyuan.hsu -+ * [WCXRP00000615] [MT 6620 Wi-Fi][Driver] Fix klocwork issues -+ * fix the klocwork issues, 57500, 57501, 57502 and 57503. -+ * -+ * 03 21 2011 cp.wu -+ * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer -+ * portability improvement -+ * -+ * 03 07 2011 terry.wu -+ * [WCXRP00000521] [MT6620 Wi-Fi][Driver] Remove non-standard debug message -+ * Toggle non-standard debug messages to comments. -+ * -+ * 11 08 2010 cp.wu -+ * [WCXRP00000166] [MT6620 Wi-Fi][Driver] use SDIO CMD52 for enabling/disabling interrupt to reduce transaction period -+ * change to use CMD52 for enabling/disabling interrupt to reduce SDIO transaction time -+ * -+ * 09 01 2010 cp.wu -+ * NULL -+ * move HIF CR initialization from where after sdioSetupCardFeature() to wlanAdapterStart() -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 15 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * change zero-padding for TX port access to HAL. -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 04 06 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * eliminate direct access for prGlueInfo->fgIsCardRemoved in non-glue layer -+ * -+ * 01 27 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1. eliminate improper variable in rHifInfo -+ * * * * 2. block TX/ordinary OID when RF test mode is engaged -+ * * * * 3. wait until firmware finish operation when entering into and leaving from RF test mode -+ * * * * 4. correct some HAL implementation -+** \main\maintrunk.MT6620WiFiDriver_Prj\17 2009-12-16 18:02:26 GMT mtk02752 -+** include precomp.h -+** \main\maintrunk.MT6620WiFiDriver_Prj\16 2009-12-10 16:43:16 GMT mtk02752 -+** code clean -+** \main\maintrunk.MT6620WiFiDriver_Prj\15 2009-11-13 13:54:15 GMT mtk01084 -+** \main\maintrunk.MT6620WiFiDriver_Prj\14 2009-11-11 10:36:01 GMT mtk01084 -+** modify HAL functions -+** \main\maintrunk.MT6620WiFiDriver_Prj\13 2009-11-09 22:56:28 GMT mtk01084 -+** modify HW access routines -+** \main\maintrunk.MT6620WiFiDriver_Prj\12 2009-10-29 19:50:09 GMT mtk01084 -+** add new macro HAL_TX_PORT_WR -+** \main\maintrunk.MT6620WiFiDriver_Prj\11 2009-10-23 16:08:10 GMT mtk01084 -+** \main\maintrunk.MT6620WiFiDriver_Prj\10 2009-10-13 21:58:50 GMT mtk01084 -+** update for new HW architecture design -+** \main\maintrunk.MT6620WiFiDriver_Prj\9 2009-05-18 14:28:10 GMT mtk01084 -+** fix issue in HAL_DRIVER_OWN_BY_SDIO_CMD52() -+** \main\maintrunk.MT6620WiFiDriver_Prj\8 2009-05-11 17:26:33 GMT mtk01084 -+** modify the bit definition to check driver own status -+** \main\maintrunk.MT6620WiFiDriver_Prj\7 2009-04-28 10:30:22 GMT mtk01461 -+** Fix typo -+** \main\maintrunk.MT6620WiFiDriver_Prj\6 2009-04-01 10:50:34 GMT mtk01461 -+** Redefine HAL_PORT_RD/WR macro for SW pre test -+** \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-03-24 09:46:49 GMT mtk01084 -+** fix LINT error -+** \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-03-23 16:53:38 GMT mtk01084 -+** add HAL_DRIVER_OWN_BY_SDIO_CMD52() -+** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-03-18 20:53:13 GMT mtk01426 -+** Fixed lint warn -+** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 20:16:20 GMT mtk01426 -+** Init for develop -+** -+*/ -+ -+#ifndef _HAL_H -+#define _HAL_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/* Macros for flag operations for the Adapter structure */ -+#define HAL_SET_FLAG(_M, _F) ((_M)->u4HwFlags |= (_F)) -+#define HAL_CLEAR_FLAG(_M, _F) ((_M)->u4HwFlags &= ~(_F)) -+#define HAL_TEST_FLAG(_M, _F) ((_M)->u4HwFlags & (_F)) -+#define HAL_TEST_FLAGS(_M, _F) (((_M)->u4HwFlags & (_F)) == (_F)) -+ -+#if defined(_HIF_SDIO) -+#define HAL_MCR_RD(_prAdapter, _u4Offset, _pu4Value) \ -+do { \ -+ if (HAL_TEST_FLAG(_prAdapter, ADAPTER_FLAG_HW_ERR) == FALSE) { \ -+ if (_prAdapter->rAcpiState == ACPI_STATE_D3) { \ -+ ASSERT(0); \ -+ } \ -+ if (kalDevRegRead(_prAdapter->prGlueInfo, _u4Offset, _pu4Value) == FALSE) {\ -+ HAL_SET_FLAG(_prAdapter, ADAPTER_FLAG_HW_ERR); \ -+ fgIsBusAccessFailed = TRUE; \ -+ /* DBGLOG(HAL, ERROR, ("HAL_MCR_RD access fail! 0x%x: 0x%x\n", */ \ -+ /* (UINT32)_u4Offset, (UINT32)*_pu4Value)); */ \ -+ } \ -+ } else { \ -+ /* DBGLOG(HAL, WARN, ("ignore HAL_MCR_RD access! 0x%x\n", (UINT32)_u4Offset)); */ \ -+ } \ -+} while (0) -+ -+#define HAL_MCR_WR(_prAdapter, _u4Offset, _u4Value) \ -+do { \ -+ if (HAL_TEST_FLAG(_prAdapter, ADAPTER_FLAG_HW_ERR) == FALSE) { \ -+ if (_prAdapter->rAcpiState == ACPI_STATE_D3) { \ -+ ASSERT(0); \ -+ } \ -+ if (kalDevRegWrite(_prAdapter->prGlueInfo, _u4Offset, _u4Value) == FALSE) {\ -+ HAL_SET_FLAG(_prAdapter, ADAPTER_FLAG_HW_ERR); \ -+ fgIsBusAccessFailed = TRUE; \ -+ /* DBGLOG(HAL, ERROR, ("HAL_MCR_WR access fail! 0x%x: 0x%x\n", */ \ -+ /* (UINT32)_u4Offset, (UINT32)_u4Value)); */ \ -+ } \ -+ } else { \ -+ /* DBGLOG(HAL, WARN, ("ignore HAL_MCR_WR access! 0x%x: 0x%x\n", */ \ -+ /* (UINT32)_u4Offset, (UINT32)_u4Value)); */ \ -+ } \ -+} while (0) -+ -+#define HAL_PORT_RD(_prAdapter, _u4Port, _u4Len, _pucBuf, _u4ValidBufSize) \ -+{ \ -+ /*fgResult = FALSE; */\ -+ if (_prAdapter->rAcpiState == ACPI_STATE_D3) { \ -+ ASSERT(0); \ -+ } \ -+ if (HAL_TEST_FLAG(_prAdapter, ADAPTER_FLAG_HW_ERR) == FALSE) { \ -+ if (kalDevPortRead(_prAdapter->prGlueInfo, _u4Port, _u4Len, _pucBuf, _u4ValidBufSize) \ -+ == FALSE) {\ -+ HAL_SET_FLAG(_prAdapter, ADAPTER_FLAG_HW_ERR); \ -+ fgIsBusAccessFailed = TRUE; \ -+ DBGLOG(HAL, ERROR, "HAL_PORT_RD access fail! 0x%x\n", _u4Port); \ -+ } \ -+ else { \ -+ /*fgResult = TRUE;*/ } \ -+ } else { \ -+ DBGLOG(HAL, WARN, "ignore HAL_PORT_RD access! 0x%x\n", _u4Port); \ -+ } \ -+} -+ -+#define HAL_PORT_WR(_prAdapter, _u4Port, _u4Len, _pucBuf, _u4ValidBufSize) \ -+{ \ -+ /*fgResult = FALSE; */\ -+ if (_prAdapter->rAcpiState == ACPI_STATE_D3) { \ -+ ASSERT(0); \ -+ } \ -+ if (HAL_TEST_FLAG(_prAdapter, ADAPTER_FLAG_HW_ERR) == FALSE) { \ -+ if (kalDevPortWrite(_prAdapter->prGlueInfo, _u4Port, _u4Len, _pucBuf, _u4ValidBufSize) \ -+ == FALSE) {\ -+ HAL_SET_FLAG(_prAdapter, ADAPTER_FLAG_HW_ERR); \ -+ fgIsBusAccessFailed = TRUE; \ -+ DBGLOG(HAL, ERROR, "HAL_PORT_WR access fail! 0x%x\n", _u4Port); \ -+ } \ -+ else { \ -+ /*fgResult = TRUE;*/ } \ -+ } else { \ -+ DBGLOG(HAL, WARN, "ignore HAL_PORT_WR access! 0x%x\n", _u4Port); \ -+ } \ -+} -+ -+#if 0 /* only for SDIO */ -+#define HAL_BYTE_WR(_prAdapter, _u4Port, _ucBuf) \ -+{ \ -+ if (_prAdapter->rAcpiState == ACPI_STATE_D3) { \ -+ ASSERT(0); \ -+ } \ -+ if (HAL_TEST_FLAG(_prAdapter, ADAPTER_FLAG_HW_ERR) == FALSE) { \ -+ if (kalDevWriteWithSdioCmd52(_prAdapter->prGlueInfo, _u4Port, _ucBuf) == FALSE) {\ -+ HAL_SET_FLAG(_prAdapter, ADAPTER_FLAG_HW_ERR); \ -+ fgIsBusAccessFailed = TRUE; \ -+ DBGLOG(HAL, ERROR, "HAL_BYTE_WR access fail! 0x%x\n", _u4Port); \ -+ } \ -+ else { \ -+ /* Todo:: Nothing*/ \ -+ } \ -+ } \ -+ else { \ -+ DBGLOG(HAL, WARN, "ignore HAL_BYTE_WR access! 0x%x\n", _u4Port); \ -+ } \ -+} -+#endif -+ -+#define HAL_DRIVER_OWN_BY_SDIO_CMD52(_prAdapter, _pfgDriverIsOwnReady) \ -+{ \ -+ UINT_8 ucBuf = BIT(1); \ -+ if (_prAdapter->rAcpiState == ACPI_STATE_D3) { \ -+ ASSERT(0); \ -+ } \ -+ if (HAL_TEST_FLAG(_prAdapter, ADAPTER_FLAG_HW_ERR) == FALSE) { \ -+ if (kalDevReadAfterWriteWithSdioCmd52(_prAdapter->prGlueInfo, MCR_WHLPCR_BYTE1, &ucBuf, 1) \ -+ == FALSE) {\ -+ HAL_SET_FLAG(_prAdapter, ADAPTER_FLAG_HW_ERR); \ -+ fgIsBusAccessFailed = TRUE; \ -+ DBGLOG(HAL, ERROR, "kalDevReadAfterWriteWithSdioCmd52 access fail!\n"); \ -+ } \ -+ else { \ -+ *_pfgDriverIsOwnReady = (ucBuf & BIT(0)) ? TRUE : FALSE; \ -+ } \ -+ } else { \ -+ DBGLOG(HAL, WARN, "ignore HAL_DRIVER_OWN_BY_SDIO_CMD52 access!\n"); \ -+ } \ -+} -+ -+#else /* #if defined(_HIF_SDIO) */ -+#define HAL_MCR_RD(_prAdapter, _u4Offset, _pu4Value) \ -+{ \ -+ if (_prAdapter->rAcpiState == ACPI_STATE_D3) { \ -+ ASSERT(0); \ -+ } \ -+ if (kalDevRegRead(_prAdapter->prGlueInfo, _u4Offset, _pu4Value) \ -+ == FALSE) \ -+ fgIsBusAccessFailed = TRUE; \ -+} -+ -+#define HAL_MCR_WR(_prAdapter, _u4Offset, _u4Value) \ -+{ \ -+ if (_prAdapter->rAcpiState == ACPI_STATE_D3) { \ -+ ASSERT(0); \ -+ } \ -+ if (kalDevRegWrite(_prAdapter->prGlueInfo, _u4Offset, _u4Value) \ -+ == FALSE) \ -+ fgIsBusAccessFailed = TRUE; \ -+} -+ -+#define HAL_PORT_RD(_prAdapter, _u4Port, _u4Len, _pucBuf, _u4ValidBufSize) \ -+{ \ -+ if (_prAdapter->rAcpiState == ACPI_STATE_D3) { \ -+ ASSERT(0); \ -+ } \ -+ if (kalDevPortRead(_prAdapter->prGlueInfo, _u4Port, _u4Len, _pucBuf, _u4ValidBufSize) \ -+ == FALSE) \ -+ fgIsBusAccessFailed = TRUE; \ -+} -+ -+#define HAL_PORT_WR(_prAdapter, _u4Port, _u4Len, _pucBuf, _u4ValidBufSize) \ -+{ \ -+ if (_prAdapter->rAcpiState == ACPI_STATE_D3) { \ -+ ASSERT(0); \ -+ } \ -+ if (kalDevPortWrite(_prAdapter->prGlueInfo, _u4Port, _u4Len, _pucBuf, _u4ValidBufSize) \ -+ == FALSE) \ -+ fgIsBusAccessFailed = TRUE; \ -+} -+ -+#if 0 /* only for SDIO */ -+#define HAL_BYTE_WR(_prAdapter, _u4Port, _ucBuf) \ -+{ \ -+ if (_prAdapter->rAcpiState == ACPI_STATE_D3) { \ -+ ASSERT(0); \ -+ } \ -+kalDevWriteWithSdioCmd52(_prAdapter->prGlueInfo, _u4Port, _ucBuf); \ -+} -+#endif -+ -+#endif /* #if defined(_HIF_SDIO) */ -+ -+#define HAL_READ_RX_PORT(prAdapter, u4PortId, u4Len, pvBuf, _u4ValidBufSize) \ -+{ \ -+ ASSERT(u4PortId < 2); \ -+ HAL_PORT_RD(prAdapter, \ -+ ((u4PortId == 0) ? MCR_WRDR0 : MCR_WRDR1), \ -+ u4Len, \ -+ pvBuf, \ -+ _u4ValidBufSize/*temp!!*//*4Kbyte*/); \ -+} -+ -+#define HAL_WRITE_TX_PORT(_prAdapter, _ucTxPortIdx, _u4Len, _pucBuf, _u4ValidBufSize) \ -+{ \ -+ ASSERT(_ucTxPortIdx < 2); \ -+ if ((_u4ValidBufSize - _u4Len) >= sizeof(UINT_32)) { \ -+ /* fill with single dword of zero as TX-aggregation termination */ \ -+ *(PUINT_32) (&((_pucBuf)[ALIGN_4(_u4Len)])) = 0; \ -+ } \ -+ HAL_PORT_WR(_prAdapter, \ -+ (_ucTxPortIdx == 0) ? MCR_WTDR0 : MCR_WTDR1, \ -+ _u4Len, \ -+ _pucBuf, \ -+ _u4ValidBufSize/*temp!!*//*4KByte*/); \ -+} -+ -+/* The macro to read the given MCR several times to check if the wait -+ condition come true. */ -+#define HAL_MCR_RD_AND_WAIT(_pAdapter, _offset, _pReadValue, _waitCondition, _waitDelay, _waitCount, _status) \ -+{ \ -+ UINT_32 count; \ -+ (_status) = FALSE; \ -+ for (count = 0; count < (_waitCount); count++) { \ -+ HAL_MCR_RD((_pAdapter), (_offset), (_pReadValue)); \ -+ if ((_waitCondition)) { \ -+ (_status) = TRUE; \ -+ break; \ -+ } \ -+ kalUdelay((_waitDelay)); \ -+ } \ -+} -+ -+/* The macro to write 1 to a R/S bit and read it several times to check if the -+ command is done */ -+#define HAL_MCR_WR_AND_WAIT(_pAdapter, _offset, _writeValue, _busyMask, _waitDelay, _waitCount, _status) \ -+{ \ -+ UINT_32 u4Temp; \ -+ UINT_32 u4Count = _waitCount; \ -+ (_status) = FALSE; \ -+ HAL_MCR_WR((_pAdapter), (_offset), (_writeValue)); \ -+ do { \ -+ kalUdelay((_waitDelay)); \ -+ HAL_MCR_RD((_pAdapter), (_offset), &u4Temp); \ -+ if (!(u4Temp & (_busyMask))) { \ -+ (_status) = TRUE; \ -+ break; \ -+ } \ -+ u4Count--; \ -+ } while (u4Count); \ -+} -+ -+#define HAL_GET_CHIP_ID_VER(_prAdapter, pu2ChipId, pu2Version) \ -+{ \ -+ UINT_32 u4Value; \ -+ HAL_MCR_RD(_prAdapter, \ -+ MCR_WCIR, \ -+ &u4Value); \ -+ *pu2ChipId = (UINT_16)(u4Value & WCIR_CHIP_ID); \ -+ *pu2Version = (UINT_16)(u4Value & WCIR_REVISION_ID) >> 16; \ -+} -+ -+#define HAL_WAIT_WIFI_FUNC_READY(_prAdapter) \ -+{ \ -+ UINT_32 u4Value; \ -+ UINT_32 i; \ -+ for (i = 0; i < 100; i++) { \ -+ HAL_MCR_RD(_prAdapter, \ -+ MCR_WCIR, \ -+ &u4Value); \ -+ if (u4Value & WCIR_WLAN_READY) { \ -+ break; \ -+ } \ -+ NdisMSleep(10); \ -+ } \ -+} -+ -+#define HAL_INTR_DISABLE(_prAdapter) \ -+ HAL_MCR_WR(_prAdapter, \ -+ MCR_WHLPCR, \ -+ WHLPCR_INT_EN_CLR) -+ -+#define HAL_INTR_ENABLE(_prAdapter) \ -+ HAL_MCR_WR(_prAdapter, \ -+ MCR_WHLPCR, \ -+ WHLPCR_INT_EN_SET) -+ -+#define HAL_INTR_ENABLE_AND_LP_OWN_SET(_prAdapter) \ -+ HAL_MCR_WR(_prAdapter, \ -+ MCR_WHLPCR, \ -+ (WHLPCR_INT_EN_SET | WHLPCR_FW_OWN_REQ_SET)) -+ -+#define HAL_LP_OWN_SET(_prAdapter) \ -+ HAL_MCR_WR(_prAdapter, \ -+ MCR_WHLPCR, \ -+ WHLPCR_FW_OWN_REQ_SET) -+ -+#define HAL_LP_OWN_CLR_OK(_prAdapter, _pfgResult) \ -+{ \ -+ UINT_32 i; \ -+ UINT_32 u4RegValue; \ -+ UINT_32 u4LoopCnt = 2048 / 8; \ -+ *_pfgResult = TRUE; \ -+ /* Software get LP ownership */ \ -+ HAL_MCR_WR(_prAdapter, \ -+ MCR_WHLPCR, \ -+ WHLPCR_FW_OWN_REQ_CLR) \ -+ for (i = 0; i < u4LoopCnt; i++) { \ -+ HAL_MCR_RD(_prAdapter, MCR_WHLPCR, &u4RegValue); \ -+ if (u4RegValue & WHLPCR_IS_DRIVER_OWN) { \ -+ break; \ -+ } \ -+ else { \ -+ kalUdelay(8); \ -+ } \ -+ } \ -+ if (i == u4LoopCnt) { \ -+ *_pfgResult = FALSE; \ -+ /*ERRORLOG(("LP cannot be own back (%ld)", u4LoopCnt));*/ \ -+ /* check the time of LP instructions need to perform from Sleep to On */ \ -+ /*ASSERT(0); */ \ -+ } \ -+} -+ -+#define HAL_GET_ABNORMAL_INTERRUPT_REASON_CODE(_prAdapter, pu4AbnormalReason) \ -+{ \ -+ HAL_MCR_RD(_prAdapter, \ -+ MCR_WASR, \ -+ pu4AbnormalReason); \ -+} -+ -+#define HAL_DISABLE_RX_ENHANCE_MODE(_prAdapter) \ -+{ \ -+ UINT_32 u4Value; \ -+ HAL_MCR_RD(_prAdapter, \ -+ MCR_WHCR, \ -+ &u4Value); \ -+ HAL_MCR_WR(_prAdapter, \ -+ MCR_WHCR, \ -+ u4Value & ~WHCR_RX_ENHANCE_MODE_EN); \ -+} -+ -+#define HAL_ENABLE_RX_ENHANCE_MODE(_prAdapter) \ -+{ \ -+ UINT_32 u4Value; \ -+ HAL_MCR_RD(_prAdapter, \ -+ MCR_WHCR, \ -+ &u4Value); \ -+ HAL_MCR_WR(_prAdapter, \ -+ MCR_WHCR, \ -+ u4Value | WHCR_RX_ENHANCE_MODE_EN); \ -+} -+ -+#define HAL_CFG_MAX_HIF_RX_LEN_NUM(_prAdapter, _ucNumOfRxLen) \ -+{ \ -+ UINT_32 u4Value, ucNum; \ -+ ucNum = ((_ucNumOfRxLen >= 16) ? 0 : _ucNumOfRxLen); \ -+ u4Value = 0; \ -+ HAL_MCR_RD(_prAdapter, \ -+ MCR_WHCR, \ -+ &u4Value); \ -+ u4Value &= ~WHCR_MAX_HIF_RX_LEN_NUM; \ -+ u4Value |= ((((UINT_32)ucNum) << 4) & WHCR_MAX_HIF_RX_LEN_NUM); \ -+ HAL_MCR_WR(_prAdapter, \ -+ MCR_WHCR, \ -+ u4Value); \ -+} -+ -+#define HAL_SET_INTR_STATUS_READ_CLEAR(prAdapter) \ -+{ \ -+ UINT_32 u4Value; \ -+ HAL_MCR_RD(prAdapter, \ -+ MCR_WHCR, \ -+ &u4Value); \ -+ HAL_MCR_WR(prAdapter, \ -+ MCR_WHCR, \ -+ u4Value & ~WHCR_W_INT_CLR_CTRL); \ -+ prAdapter->prGlueInfo->rHifInfo.fgIntReadClear = TRUE;\ -+} -+ -+#define HAL_SET_INTR_STATUS_WRITE_1_CLEAR(prAdapter) \ -+{ \ -+ UINT_32 u4Value; \ -+ HAL_MCR_RD(prAdapter, \ -+ MCR_WHCR, \ -+ &u4Value); \ -+ HAL_MCR_WR(prAdapter, \ -+ MCR_WHCR, \ -+ u4Value | WHCR_W_INT_CLR_CTRL); \ -+ prAdapter->prGlueInfo->rHifInfo.fgIntReadClear = FALSE;\ -+} -+ -+/* Note: enhance mode structure may also carried inside the buffer, -+ if the length of the buffer is long enough */ -+#define HAL_READ_INTR_STATUS(prAdapter, length, pvBuf) \ -+ HAL_PORT_RD(prAdapter, \ -+ MCR_WHISR, \ -+ length, \ -+ pvBuf, \ -+ length) -+ -+#define HAL_READ_TX_RELEASED_COUNT(_prAdapter, aucTxReleaseCount) \ -+{ \ -+ PUINT_32 pu4Value = (PUINT_32)aucTxReleaseCount; \ -+ HAL_MCR_RD(_prAdapter, \ -+ MCR_WTSR0, \ -+ &pu4Value[0]); \ -+ HAL_MCR_RD(_prAdapter, \ -+ MCR_WTSR1, \ -+ &pu4Value[1]); \ -+} -+ -+#define HAL_READ_RX_LENGTH(prAdapter, pu2Rx0Len, pu2Rx1Len) \ -+{ \ -+ UINT_32 u4Value; \ -+ u4Value = 0; \ -+ HAL_MCR_RD(prAdapter, \ -+ MCR_WRPLR, \ -+ &u4Value); \ -+ *pu2Rx0Len = (UINT_16)u4Value; \ -+ *pu2Rx1Len = (UINT_16)(u4Value >> 16); \ -+} -+ -+#define HAL_GET_INTR_STATUS_FROM_ENHANCE_MODE_STRUCT(pvBuf, u2Len, pu4Status) \ -+{ \ -+ PUINT_32 pu4Buf = (PUINT_32)pvBuf; \ -+ *pu4Status = pu4Buf[0]; \ -+} -+ -+#define HAL_GET_TX_STATUS_FROM_ENHANCE_MODE_STRUCT(pvInBuf, pu4BufOut, u4LenBufOut) \ -+{ \ -+ PUINT_32 pu4Buf = (PUINT_32)pvInBuf; \ -+ ASSERT(u4LenBufOut >= 8); \ -+ pu4BufOut[0] = pu4Buf[1]; \ -+ pu4BufOut[1] = pu4Buf[2]; \ -+} -+ -+#define HAL_GET_RX_LENGTH_FROM_ENHANCE_MODE_STRUCT(pvInBuf, pu2Rx0Num, au2Rx0Len, pu2Rx1Num, au2Rx1Len) \ -+{ \ -+ PUINT_32 pu4Buf = (PUINT_32)pvInBuf; \ -+ ASSERT((sizeof(au2Rx0Len) / sizeof(UINT_16)) >= 16); \ -+ ASSERT((sizeof(au2Rx1Len) / sizeof(UINT_16)) >= 16); \ -+ *pu2Rx0Num = (UINT_16)pu4Buf[3]; \ -+ *pu2Rx1Num = (UINT_16)(pu4Buf[3] >> 16); \ -+ kalMemCopy(au2Rx0Len, &pu4Buf[4], 8); \ -+ kalMemCopy(au2Rx1Len, &pu4Buf[12], 8); \ -+} -+ -+#define HAL_GET_MAILBOX_FROM_ENHANCE_MODE_STRUCT(pvInBuf, pu4Mailbox0, pu4Mailbox1) \ -+{ \ -+ PUINT_32 pu4Buf = (PUINT_32)pvInBuf; \ -+ *pu4Mailbox0 = (UINT_16)pu4Buf[21]; \ -+ *pu4Mailbox1 = (UINT_16)pu4Buf[22]; \ -+} -+ -+#define HAL_IS_TX_DONE_INTR(u4IntrStatus) \ -+ ((u4IntrStatus & WHISR_TX_DONE_INT) ? TRUE : FALSE) -+ -+#define HAL_IS_RX_DONE_INTR(u4IntrStatus) \ -+ ((u4IntrStatus & (WHISR_RX0_DONE_INT | WHISR_RX1_DONE_INT)) ? TRUE : FALSE) -+ -+#define HAL_IS_ABNORMAL_INTR(u4IntrStatus) \ -+ ((u4IntrStatus & WHISR_ABNORMAL_INT) ? TRUE : FALSE) -+ -+#define HAL_IS_FW_OWNBACK_INTR(u4IntrStatus) \ -+ ((u4IntrStatus & WHISR_FW_OWN_BACK_INT) ? TRUE : FALSE) -+ -+#define HAL_PUT_MAILBOX(prAdapter, u4MboxId, u4Data) \ -+{ \ -+ ASSERT(u4MboxId < 2); \ -+ HAL_MCR_WR(prAdapter, \ -+ ((u4MboxId == 0) ? MCR_H2DSM0R : MCR_H2DSM1R), \ -+ u4Data); \ -+} -+ -+#define HAL_GET_MAILBOX(prAdapter, u4MboxId, pu4Data) \ -+{ \ -+ ASSERT(u4MboxId < 2); \ -+ HAL_MCR_RD(prAdapter, \ -+ ((u4MboxId == 0) ? MCR_D2HRM0R : MCR_D2HRM1R), \ -+ pu4Data); \ -+} -+ -+#define HAL_SET_MAILBOX_READ_CLEAR(prAdapter, fgEnableReadClear) \ -+{ \ -+ UINT_32 u4Value; \ -+ HAL_MCR_RD(prAdapter, MCR_WHCR, &u4Value);\ -+ HAL_MCR_WR(prAdapter, MCR_WHCR, \ -+ (fgEnableReadClear) ? \ -+ (u4Value | WHCR_W_MAILBOX_RD_CLR_EN) : \ -+ (u4Value & ~WHCR_W_MAILBOX_RD_CLR_EN)); \ -+ prAdapter->prGlueInfo->rHifInfo.fgMbxReadClear = fgEnableReadClear;\ -+} -+ -+#define HAL_GET_MAILBOX_READ_CLEAR(prAdapter) (prAdapter->prGlueInfo->rHifInfo.fgMbxReadClear) -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif /* _HAL_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/hif_rx.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/hif_rx.h -new file mode 100644 -index 000000000000..b9aa154b097e ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/hif_rx.h -@@ -0,0 +1,220 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/nic/hif_rx.h#1 -+*/ -+ -+/*! \file "hif_rx.h" -+ \brief Provide HIF RX Header Information between F/W and Driver -+ -+ N/A -+*/ -+ -+/* -+** Log: hif_rx.h -+ * -+ * 09 01 2010 kevin.huang -+ * NULL -+ * Use LINK LIST operation to process SCAN result -+ * -+ * 07 16 2010 yarco.yang -+ * -+ * 1. Support BSS Absence/Presence Event -+ * 2. Support STA change PS mode Event -+ * 3. Support BMC forwarding for AP mode. -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 14 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * follow-ups for HIF_RX_HEADER_T update: -+ * 1) add TCL -+ * 2) add RCPI -+ * 3) add ChannelNumber -+ * -+ * 06 11 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) migrate assoc.c. -+ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness -+ * 3) add configuration options for CNM_MEM and RSN modules -+ * 4) add data path for management frames -+ * 5) eliminate rPacketInfo of MSDU_INFO_T -+ * -+ * 06 09 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add necessary changes to driver data paths. -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+** \main\maintrunk.MT6620WiFiDriver_Prj\10 2009-12-10 16:44:00 GMT mtk02752 -+** code clean -+** \main\maintrunk.MT6620WiFiDriver_Prj\9 2009-12-09 13:59:20 GMT MTK02468 -+** Added HIF_RX_HDR parsing macros -+** \main\maintrunk.MT6620WiFiDriver_Prj\8 2009-11-24 19:54:54 GMT mtk02752 -+** adopt HIF_RX_HEADER_T in new data path -+** \main\maintrunk.MT6620WiFiDriver_Prj\7 2009-10-29 19:51:19 GMT mtk01084 -+** modify FW/ driver interface -+** \main\maintrunk.MT6620WiFiDriver_Prj\6 2009-04-28 10:33:58 GMT mtk01461 -+** Add define of HW_APPENED_LEN -+** \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-04-01 10:51:02 GMT mtk01461 -+** Rename ENUM_HIF_RX_PKT_TYPE_T -+** \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-03-19 12:05:03 GMT mtk01426 -+** Remove __KAL_ATTRIB_PACKED__ and add hifDataTypeCheck() -+** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-03-17 20:18:52 GMT mtk01426 -+** Add comment to HIF_RX_HEADER_T -+** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 20:16:23 GMT mtk01426 -+** Init for develop -+** -+*/ -+ -+#ifndef _HIF_RX_H -+#define _HIF_RX_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+/*! HIF_RX_HEADER_T */ -+/* DW 0, Byte 1 */ -+#define HIF_RX_HDR_PACKET_TYPE_MASK BITS(0, 1) -+#define HIF_RX_HDR_SEC_MODE_MASK BITS(2, 5) -+#define HIF_RX_HDR_SEC_MODE_OFFSET 2 -+ -+/* DW 1, Byte 0 */ -+#define HIF_RX_HDR_HEADER_LEN BITS(2, 7) -+#define HIF_RX_HDR_HEADER_LEN_OFFSET 2 -+#define HIF_RX_HDR_HEADER_OFFSET_MASK BITS(0, 1) -+ -+/* DW 1, Byte 1 */ -+#define HIF_RX_HDR_80211_HEADER_FORMAT BIT(0) -+#define HIF_RX_HDR_DO_REORDER BIT(1) -+#define HIF_RX_HDR_PAL BIT(2) -+#define HIF_RX_HDR_TCL BIT(3) -+#define HIF_RX_HDR_NETWORK_IDX_MASK BITS(4, 7) -+#define HIF_RX_HDR_NETWORK_IDX_OFFSET 4 -+ -+/* DW 1, Byte 2, 3 */ -+#define HIF_RX_HDR_SEQ_NO_MASK BITS(0, 11) -+#define HIF_RX_HDR_TID_MASK BITS(12, 14) -+#define HIF_RX_HDR_TID_OFFSET 12 -+#define HIF_RX_HDR_BAR_FRAME BIT(15) -+ -+#define HIF_RX_HDR_FLAG_AMP_WDS BIT(0) -+#define HIF_RX_HDR_FLAG_802_11_FORMAT BIT(1) -+#define HIF_RX_HDR_FLAG_BAR_FRAME BIT(2) -+#define HIF_RX_HDR_FLAG_DO_REORDERING BIT(3) -+#define HIF_RX_HDR_FLAG_CTRL_WARPPER_FRAME BIT(4) -+ -+#define HIF_RX_HW_APPENDED_LEN 4 -+ -+/* For DW 2, Byte 3 - ucHwChannelNum */ -+#define HW_CHNL_NUM_MAX_2G4 14 -+#define HW_CHNL_NUM_MAX_4G_5G (255 - HW_CHNL_NUM_MAX_2G4) -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+typedef struct _HIF_RX_HEADER_T { -+ UINT_16 u2PacketLen; -+ UINT_16 u2PacketType; -+ UINT_8 ucHerderLenOffset; -+ UINT_8 uc80211_Reorder_PAL_TCL; -+ UINT_16 u2SeqNoTid; -+ UINT_8 ucStaRecIdx; -+ UINT_8 ucRcpi; -+ UINT_8 ucHwChannelNum; -+ UINT_8 ucReserved; -+} HIF_RX_HEADER_T, *P_HIF_RX_HEADER_T; -+ -+typedef enum _ENUM_HIF_RX_PKT_TYPE_T { -+ HIF_RX_PKT_TYPE_DATA = 0, -+ HIF_RX_PKT_TYPE_EVENT, -+ HIF_RX_PKT_TYPE_TX_LOOPBACK, -+ HIF_RX_PKT_TYPE_MANAGEMENT, -+ HIF_RX_PKT_TYPE_NUM -+} ENUM_HIF_RX_PKT_TYPE_T, *P_ENUM_HIF_RX_PKT_TYPE_T; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+#define HIF_RX_HDR_SIZE sizeof(HIF_RX_HEADER_T) -+ -+#define HIF_RX_HDR_GET_80211_FLAG(_prHifRxHdr) \ -+ (((((_prHifRxHdr)->uc80211_Reorder_PAL_TCL) & HIF_RX_HDR_80211_HEADER_FORMAT) ? TRUE : FALSE)) -+#define HIF_RX_HDR_GET_REORDER_FLAG(_prHifRxHdr) \ -+ (((((_prHifRxHdr)->uc80211_Reorder_PAL_TCL) & HIF_RX_HDR_DO_REORDER) ? TRUE : FALSE)) -+#define HIF_RX_HDR_GET_PAL_FLAG(_prHifRxHdr) \ -+ (((((_prHifRxHdr)->uc80211_Reorder_PAL_TCL) & HIF_RX_HDR_PAL) ? TRUE : FALSE)) -+#define HIF_RX_HDR_GET_TCL_FLAG(_prHifRxHdr) \ -+ (((((_prHifRxHdr)->uc80211_Reorder_PAL_TCL) & HIF_RX_HDR_TCL) ? TRUE : FALSE)) -+#define HIF_RX_HDR_GET_NETWORK_IDX(_prHifRxHdr) \ -+ ((((_prHifRxHdr)->uc80211_Reorder_PAL_TCL) & HIF_RX_HDR_NETWORK_IDX_MASK)\ -+ >> HIF_RX_HDR_NETWORK_IDX_OFFSET) -+ -+#define HIF_RX_HDR_GET_SEC_MODE(_prHifRxHdr) \ -+ ((((_prHifRxHdr)->u2PacketType) & HIF_RX_HDR_SEC_MODE_MASK) >> HIF_RX_HDR_SEC_MODE_OFFSET) -+ -+#define HIF_RX_HDR_GET_TID(_prHifRxHdr) \ -+ ((((_prHifRxHdr)->u2SeqNoTid) & HIF_RX_HDR_TID_MASK)\ -+ >> HIF_RX_HDR_TID_OFFSET) -+#define HIF_RX_HDR_GET_SN(_prHifRxHdr) \ -+ (((_prHifRxHdr)->u2SeqNoTid) & HIF_RX_HDR_SEQ_NO_MASK) -+#define HIF_RX_HDR_GET_BAR_FLAG(_prHifRxHdr) \ -+ (((((_prHifRxHdr)->u2SeqNoTid) & HIF_RX_HDR_BAR_FRAME) ? TRUE : FALSE)) -+ -+#define HIF_RX_HDR_GET_CHNL_NUM(_prHifRxHdr) \ -+ ((((_prHifRxHdr)->ucHwChannelNum) > HW_CHNL_NUM_MAX_4G_5G) ? \ -+ (((_prHifRxHdr)->ucHwChannelNum) - HW_CHNL_NUM_MAX_4G_5G) : \ -+ ((_prHifRxHdr)->ucHwChannelNum)) -+ -+/* To do: support more bands other than 2.4G and 5G */ -+#define HIF_RX_HDR_GET_RF_BAND(_prHifRxHdr) \ -+ ((((_prHifRxHdr)->ucHwChannelNum) <= HW_CHNL_NUM_MAX_2G4) ? \ -+ BAND_2G4 : BAND_5G) -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+static inline VOID hifDataTypeCheck(VOID); -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+/* Kevin: we don't have to call following function to inspect the data structure. -+ * It will check automatically while at compile time. -+ * We'll need this for porting driver to different RTOS. -+ */ -+static inline VOID hifDataTypeCheck(VOID) -+{ -+ DATA_STRUCT_INSPECTING_ASSERT(sizeof(HIF_RX_HEADER_T) == 12); -+ -+} -+ -+#endif -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/hif_tx.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/hif_tx.h -new file mode 100644 -index 000000000000..17252f2c7760 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/hif_tx.h -@@ -0,0 +1,214 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/nic/hif_tx.h#1 -+*/ -+ -+/* -+** Log: hif_tx.h -+ * -+ * 10 07 2010 cp.wu -+ * [WCXRP00000083] [MT5931][Driver][FW] Add necessary logic for MT5931 first connection -+ * add firmware download for MT5931. -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 14 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * fill extra information for revised HIF_TX_HEADER. -+ * -+ * 06 10 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) add flag on MSDU_INFO_T for indicating BIP frame and forceBasicRate -+ * 2) add packet type for indicating management frames -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 03 10 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * code clean: removing unused variables and structure definitions -+ * -+ * 02 09 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1. Permanent and current MAC address are now retrieved by CMD/EVENT packets instead of hard-coded address -+ * * * 2. follow MSDN defined behavior when associates to another AP -+ * * * 3. for firmware download, packet size could be up to 2048 bytes -+ * -+ * 01 13 2010 tehuang.liu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * Enabled the Burst_End Indication mechanism -+ * -+ * 01 13 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * TX: fill ucWlanHeaderLength/ucPktFormtId_Flags according to info provided by prMsduInfo -+** \main\maintrunk.MT6620WiFiDriver_Prj\16 2009-12-10 16:43:40 GMT mtk02752 -+** code clean -+** \main\maintrunk.MT6620WiFiDriver_Prj\15 2009-11-24 19:55:11 GMT mtk02752 -+** adopt HIF_TX_HEADER_T in new data path -+** \main\maintrunk.MT6620WiFiDriver_Prj\14 2009-11-23 17:54:13 GMT mtk02752 -+** CMD_HDR_SIZE = (sizeof(WIFI_CMD_T)) to follow up CM's CMD/EVENT documentation -+** -+** \main\maintrunk.MT6620WiFiDriver_Prj\13 2009-11-17 22:41:10 GMT mtk01084 -+** \main\maintrunk.MT6620WiFiDriver_Prj\12 2009-11-17 17:34:07 GMT mtk02752 -+** remove HIF_TX_BUFF_COUNT_TC0 (move to nic_tx.h) -+** \main\maintrunk.MT6620WiFiDriver_Prj\11 2009-11-17 12:14:12 GMT mtk02752 -+** add initial value for HIF_TX_BUFF_COUNT_TC5 -+** \main\maintrunk.MT6620WiFiDriver_Prj\10 2009-11-13 13:54:18 GMT mtk01084 -+** \main\maintrunk.MT6620WiFiDriver_Prj\9 2009-11-04 14:11:14 GMT mtk01084 -+** modify SW TX data format -+** \main\maintrunk.MT6620WiFiDriver_Prj\8 2009-10-29 19:51:53 GMT mtk01084 -+** modify FW/ driver interface -+** \main\maintrunk.MT6620WiFiDriver_Prj\7 2009-05-20 12:22:46 GMT mtk01461 -+** Add SeqNum field to CMD Header -+** \main\maintrunk.MT6620WiFiDriver_Prj\6 2009-04-17 19:40:52 GMT mtk01461 -+** Update the Log Sign -+*/ -+ -+#ifndef _HIF_TX_H -+#define _HIF_TX_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+/* Maximum buffer size for individual HIF TCQ Buffer */ -+#define HIF_TX_BUFF_MAX_SIZE 1552 /* Reserved field was not included */ -+ -+/* Maximum buffer count for individual HIF TCQ */ -+#define HIF_TX_BUFF_COUNT_TC0 3 -+#define HIF_TX_BUFF_COUNT_TC1 3 -+#define HIF_TX_BUFF_COUNT_TC2 3 -+#define HIF_TX_BUFF_COUNT_TC3 3 -+#define HIF_TX_BUFF_COUNT_TC4 2 -+ -+#define TX_HDR_SIZE sizeof(HIF_TX_HEADER_T) -+ -+#define CMD_HDR_SIZE sizeof(WIFI_CMD_T) -+ -+#define CMD_PKT_SIZE_FOR_IMAGE 2048 /* !< 2048 Bytes CMD payload buffer */ -+ -+/*! NIC_HIF_TX_HEADER_T */ -+/* DW 0, Byte 0,1 */ -+#define HIF_TX_HDR_TX_BYTE_COUNT_MASK BITS(0, 11) -+#define HIF_TX_HDR_USER_PRIORITY_OFFSET 12 -+ -+/* DW 0, Byte 2 */ -+#define HIF_TX_HDR_ETHER_TYPE_OFFSET_MASK BITS(0, 7) -+ -+/* DW 0, Byte 3 */ -+#define HIF_TX_HDR_IP_CSUM BIT(0) -+#define HIF_TX_HDR_TCP_CSUM BIT(1) -+#define HIF_TX_HDR_RESOURCE_MASK BITS(2, 5) -+#define HIF_TX_HDR_RESOURCE_OFFSET 2 -+#define HIF_TX_HDR_PACKET_TYPE_MASK BITS(6, 7) -+#define HIF_TX_HDR_PACKET_TYPE_OFFSET 6 -+ -+/* DW 1, Byte 0 */ -+#define HIF_TX_HDR_WLAN_HEADER_LEN_MASK BITS(0, 5) -+ -+/* DW 1, Byte 1 */ -+#define HIF_TX_HDR_FORMAT_ID_MASK BITS(0, 2) -+#define HIF_TX_HDR_NETWORK_TYPE_MASK BITS(4, 5) -+#define HIF_TX_HDR_NETWORK_TYPE_OFFSET 4 -+#define HIF_TX_HDR_FLAG_1X_FRAME_MASK BIT(6) -+#define HIF_TX_HDR_FLAG_1X_FRAME_OFFSET 6 -+#define HIF_TX_HDR_FLAG_802_11_FORMAT_MASK BIT(7) -+#define HIF_TX_HDR_FLAG_802_11_FORMAT_OFFSET 7 -+ -+/* DW2, Byte 3 */ -+#define HIF_TX_HDR_PS_FORWARDING_TYPE_MASK BITS(0, 1) -+#define HIF_TX_HDR_PS_SESSION_ID_MASK BITS(2, 4) -+#define HIF_TX_HDR_PS_SESSION_ID_OFFSET 2 -+#define HIF_TX_HDR_BURST_END_MASK BIT(5) -+#define HIF_TX_HDR_BURST_END_OFFSET 5 -+ -+/* DW3, Byte 1 */ -+#define HIF_TX_HDR_NEED_ACK BIT(0) -+#define HIF_TX_HDR_BIP BIT(1) -+#define HIF_TX_HDR_BASIC_RATE BIT(2) -+#define HIF_TX_HDR_NEED_TX_DONE_STATUS BIT(3) -+#define HIF_TX_HDR_RTS BIT(4) -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+typedef struct _HIF_HW_TX_HEADER_T { -+ UINT_16 u2TxByteCount; -+ UINT_8 ucEtherTypeOffset; -+ UINT_8 ucCSflags; -+ UINT_8 aucBuffer[0]; -+} HIF_HW_TX_HEADER_T, *P_HIF_HW_TX_HEADER_T; -+ -+typedef struct _HIF_TX_HEADER_T { -+ UINT_16 u2TxByteCount_UserPriority; -+ UINT_8 ucEtherTypeOffset; -+ UINT_8 ucResource_PktType_CSflags; -+ UINT_8 ucWlanHeaderLength; -+ UINT_8 ucPktFormtId_Flags; -+ UINT_16 u2LLH; /* for BOW */ -+ UINT_16 u2SeqNo; /* for BOW */ -+ UINT_8 ucStaRecIdx; -+ UINT_8 ucForwardingType_SessionID_Reserved; -+ UINT_8 ucPacketSeqNo; -+ UINT_8 ucAck_BIP_BasicRate; -+ UINT_8 aucReserved[2]; -+} HIF_TX_HEADER_T, *P_HIF_TX_HEADER_T; -+ -+typedef enum _ENUM_HIF_TX_PKT_TYPE_T { -+ HIF_TX_PKT_TYPE_DATA = 0, -+ HIF_TX_PKT_TYPE_CMD, -+ HIF_TX_PKT_TYPE_HIF_LOOPBACK, -+ HIF_TX_PKT_TYPE_MANAGEMENT, -+ HIF_TX_PKT_TYPE_NUM -+} ENUM_HIF_TX_PKT_TYPE_T, *P_ENUM_HIF_TX_PKT_TYPE_T; -+ -+typedef enum _ENUM_HIF_OOB_CTRL_PKT_TYPE_T { -+ HIF_OOB_CTRL_PKT_TYPE_LOOPBACK = 1, -+ HIF_OOB_CTRL_PKT_TYP_NUM -+} ENUM_HIF_OOB_CTRL_PKT_TYPE_T, *P_ENUM_HIF_OOB_CTRL_PKT_TYPE_T; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+#define TFCB_FRAME_PAD_TO_DW(u2Length) ALIGN_4(u2Length) -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+/* Kevin: we don't have to call following function to inspect the data structure. -+ * It will check automatically while at compile time. -+ */ -+static inline VOID hif_txDataTypeCheck(VOID); -+ -+static inline VOID hif_txDataTypeCheck(VOID) -+{ -+ DATA_STRUCT_INSPECTING_ASSERT(sizeof(HIF_TX_HEADER_T) == 16); -+ -+} -+ -+#endif /*_HIF_TX_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/mac.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/mac.h -new file mode 100644 -index 000000000000..ff38d30c3cf2 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/mac.h -@@ -0,0 +1,2323 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/nic/mac.h#1 -+*/ -+ -+/*! \file "mac.h" -+ \brief Brief description. -+ -+ Detail description. -+*/ -+ -+/* -+** Log: mac.h -+ * -+ * 03 02 2012 terry.wu -+ * NULL -+ * Sync CFG80211 modification from branch 2,2. -+ * -+ * 01 05 2012 tsaiyuan.hsu -+ * [WCXRP00001157] [MT6620 Wi-Fi][FW][DRV] add timing measurement support for 802.11v -+ * add timing measurement support for 802.11v. -+ * -+ * 10 12 2011 wh.su -+ * [WCXRP00001036] [MT6620 Wi-Fi][Driver][FW] Adding the 802.11w code for MFP -+ * adding the 802.11w related function and define . -+ * -+ * 06 22 2011 wh.su -+ * [WCXRP00000806] [MT6620 Wi-Fi][Driver] Move the WPA/RSN IE and WAPI IE structure to mac.h -+ * and let the sw structure not align at byte -+ * Move the WAPI/RSN IE to mac.h and SW structure not align to byte, -+ * Notice needed update P2P.ko. -+ * -+ * 05 06 2011 wh.su -+ * [WCXRP00000699] [MT6620 Wi-Fi][Driver] Add the ie pointer check for avoid TP-LINK AP send -+ * the wrong beacon make driver got incorrect support rate set -+ * Add the length check before access the ie length filed. -+ * -+ * 05 06 2011 wh.su -+ * [WCXRP00000699] [MT6620 Wi-Fi][Driver] Add the ie pointer check for avoid TP-LINK AP send -+ * the wrong beacon make driver got incorrect support rate set -+ * adding the length check before processing next ie.. -+ * -+ * 04 18 2011 terry.wu -+ * [WCXRP00000660] [MT6620 Wi-Fi][Driver] Remove flag CFG_WIFI_DIRECT_MOVED -+ * Remove flag CFG_WIFI_DIRECT_MOVED. -+ * -+ * 04 12 2011 cm.chang -+ * [WCXRP00000634] [MT6620 Wi-Fi][Driver][FW] 2nd BSS will not support 40MHz bandwidth for concurrency -+ * . -+ * -+ * 04 08 2011 yuche.tsai -+ * [WCXRP00000624] [Volunteer Patch][MT6620][Driver] Add device discoverability support for GO. -+ * Add device discover ability support. -+ * -+ * 03 17 2011 chinglan.wang -+ * [WCXRP00000570] [MT6620 Wi-Fi][Driver] Add Wi-Fi Protected Setup v2.0 feature -+ * . -+ * -+ * 01 25 2011 yuche.tsai -+ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record. -+ * Some action frame define is not belong to P2P. -+ * -+ * 01 25 2011 yuche.tsai -+ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record. -+ * Add some service discovery MAC define, phase I. -+ * -+ * 12 13 2010 cp.wu -+ * [WCXRP00000260] [MT6620 Wi-Fi][Driver][Firmware] Create V1.1 branch for both firmware and driver -+ * create branch for Wi-Fi driver v1.1 -+ * -+ * 12 13 2010 cp.wu -+ * [WCXRP00000256] [MT6620 Wi-Fi][Driver] Eliminate potential issues which is identified by Klockwork -+ * suppress warning reported by Klockwork. -+ * -+ * 11 01 2010 cp.wu -+ * [WCXRP00000122] [MT6620 Wi-Fi][Driver] Preparation for YuSu source tree integration -+ * revert to previous revision. (this file is not necessary to be changed) -+ * -+ * 08 20 2010 cm.chang -+ * NULL -+ * Migrate RLM code to host from FW -+ * -+ * 08 02 2010 yuche.tsai -+ * NULL -+ * 1. Add P2P MAC define. -+ * 2. Add scan device found event -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 21 2010 yuche.tsai -+ * [WPD00003839][MT6620 5931][P2P] Feature migration -+ * Add WFA specific OUI. -+ * -+ * 06 17 2010 yuche.tsai -+ * [WPD00003839][MT6620 5931][P2P] Feature migration -+ * Add P2P IE ID & Vendor OUI TYPE for P2P. -+ * -+ * 06 07 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * merge MAC.h. -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 01 13 2010 tehuang.liu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * Added OFFSET_BAR_SSC_SN -+** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-12-09 14:00:24 GMT MTK02468 -+** Added offsets and masks for the BA Parameter Set filed -+** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 20:16:26 GMT mtk01426 -+** Init for develop -+** -+*/ -+ -+#ifndef _MAC_H -+#define _MAC_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+/* 3 --------------- Constants for Ethernet/802.11 MAC --------------- */ -+/* MAC Address */ -+#define MAC_ADDR_LEN 6 -+ -+#define MAC_ADDR_LOCAL_ADMIN BIT(1) -+ -+#define ETH_P_IPV4 0x0800 -+#define ETH_P_IPX 0x8137 /* Novell IPX */ -+#define ETH_P_AARP 0x80F3 /* AppleTalk Address Resolution Protocol (AARP) */ -+#define ETH_P_IPV6 0x86DD -+ -+#define IP_VERSION_4 4 -+#define IP_VERSION_6 6 -+ -+#define IP_PROTOCOL_TCP 6 -+#define IP_PROTOCOL_UDP 17 -+ -+#define IPV4_HDR_IP_IDENTIFICATION_OFFSET 4 -+#define IPV4_HDR_IP_PROTOCOL_OFFSET 9 -+#define IPV4_HDR_IP_CSUM_OFFSET 10 -+#define IPV4_HDR_IP_SRC_ADDR_OFFSET 12 -+#define IPV4_HDR_IP_DST_ADDR_OFFSET 16 -+ -+#define IPV6_HDR_IP_PROTOCOL_OFFSET 6 -+#define IPV6_HDR_IP_SRC_ADDR_OFFSET 8 -+#define IPV6_HDR_IP_DST_ADDR_OFFSET 24 -+#define IPV6_HDR_IP_DST_ADDR_MAC_HIGH_OFFSET 32 -+#define IPV6_HDR_IP_DST_ADDR_MAC_LOW_OFFSET 37 -+#define IPV6_PROTOCOL_ICMPV6 0x3A -+#define IPV6_ADDR_LEN 16 -+#define IPV6_HDR_LEN 40 -+ -+#define ARP_OPERATION_OFFSET 6 -+#define ARP_SNEDER_MAC_OFFSET 8 -+#define ARP_SENDER_IP_OFFSET 14 -+#define ARP_TARGET_MAC_OFFSET 18 -+#define ARP_TARGET_IP_OFFSET 24 -+#define ARP_OPERATION_REQUEST 0x0001 -+#define ARP_OPERATION_RESPONSE 0x0002 -+ -+#define ICMPV6_TYPE_OFFSET 0 -+#define ICMPV6_FLAG_OFFSET 4 -+#define ICMPV6_TARGET_ADDR_OFFSET 8 -+#define ICMPV6_TARGET_LL_ADDR_TYPE_OFFSET 24 -+#define ICMPV6_TARGET_LL_ADDR_LEN_OFFSET 25 -+#define ICMPV6_TARGET_LL_ADDR_TA_OFFSET 26 -+ -+#define ICMPV6_FLAG_ROUTER_BIT BIT(7) -+#define ICMPV6_FLAG_SOLICITED_BIT BIT(6) -+#define ICMPV6_FLAG_OVERWRITE_BIT BIT(5) -+#define ICMPV6_TYPE_NEIGHBOR_SOLICITATION 0x87 -+#define ICMPV6_TYPE_NEIGHBOR_ADVERTISEMENT 0x88 -+ -+#define TCP_HDR_TCP_CSUM_OFFSET 16 -+#define UDP_HDR_UDP_CSUM_OFFSET 6 -+ -+#define LLC_LEN 8 /* LLC(3) + SNAP(3) + EtherType(2) */ -+ -+#define NULL_MAC_ADDR {0x00, 0x00, 0x00, 0x00, 0x00, 0x00} -+#define BC_MAC_ADDR {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF} -+ -+/* Ethernet Frame Field Size, in byte */ -+#define ETHER_HEADER_LEN 14 -+#define ETHER_TYPE_LEN 2 -+#define ETHER_MIN_PKT_SZ 60 -+#define ETHER_MAX_PKT_SZ 1514 -+ -+/* IEEE 802.11 WLAN Frame Field Size, in byte */ -+#define WLAN_MAC_HEADER_LEN 24 /* Address 4 excluded */ -+#define WLAN_MAC_HEADER_A4_LEN 30 /* Address 4 included */ -+#define WLAN_MAC_HEADER_QOS_LEN 26 /* QoS Control included */ -+#define WLAN_MAC_HEADER_QOS_HTC_LEN 30 /* QoS Control and HTC included */ -+#define WLAN_MAC_HEADER_A4_QOS_LEN 32 /* Address 4 and QoS Control included */ -+#define WLAN_MAC_HEADER_A4_QOS_HTC_LEN 36 /* Address 4, QoS Control and HTC included */ -+#define WLAN_MAC_MGMT_HEADER_LEN 24 /* Address 4 excluded */ -+#define WLAN_MAC_MGMT_HEADER_HTC_LEN 28 /* HTC included */ -+ -+#define QOS_CTRL_LEN 2 -+#define HT_CTRL_LEN 4 -+ -+#define WLAN_MAC_CTS_ACK_LEN (WLAN_MAC_CTS_ACK_FRAME_HEADER_LEN + FCS_LEN) -+ -+/* 6.2.1.1.2 Semantics of the service primitive */ -+#define MSDU_MAX_LENGTH 2304 -+ -+/* 7.1.3.3.3 Broadcast BSSID */ -+#define BC_BSSID BC_MAC_ADDR -+ -+/* 7.1.3.7 FCS field */ -+#define FCS_LEN 4 -+ -+/* 7.3.1.6 Listen Interval field */ -+#define DEFAULT_LISTEN_INTERVAL_BY_DTIM_PERIOD 2 /* In unit of AP's DTIM interval, */ -+#define DEFAULT_LISTEN_INTERVAL 10 -+ -+/* 7.3.2.1 Broadcast(Wildcard) SSID */ -+#define BC_SSID "" -+#define BC_SSID_LEN 0 -+ -+/* 7.3.2.2 Data Rate Value */ -+#define RATE_1M 2 /* 1M in unit of 500kb/s */ -+#define RATE_2M 4 /* 2M */ -+#define RATE_5_5M 11 /* 5.5M */ -+#define RATE_11M 22 /* 11M */ -+#define RATE_22M 44 /* 22M */ -+#define RATE_33M 66 /* 33M */ -+#define RATE_6M 12 /* 6M */ -+#define RATE_9M 18 /* 9M */ -+#define RATE_12M 24 /* 12M */ -+#define RATE_18M 36 /* 18M */ -+#define RATE_24M 48 /* 24M */ -+#define RATE_36M 72 /* 36M */ -+#define RATE_48M 96 /* 48M */ -+#define RATE_54M 108 /* 54M */ -+/* 7.3.2.14 BSS membership selector */ -+#define RATE_HT_PHY 127 /* BSS Selector - Clause 20. HT PHY */ -+#define RATE_MASK BITS(0, 6) /* mask bits for the rate */ -+#define RATE_BASIC_BIT BIT(7) /* mask bit for the rate belonging to the BSSBasicRateSet */ -+ -+/* 8.3.2.2 TKIP MPDU formats */ -+#define TKIP_MIC_LEN 8 -+ -+/* 9.2.10 DIFS */ -+#define DIFS 2 /* 2 x aSlotTime */ -+ -+/* 11.3 STA Authentication and Association */ -+#define STA_STATE_1 0 /* Accept Class 1 frames */ -+#define STA_STATE_2 1 /* Accept Class 1 & 2 frames */ -+#define STA_STATE_3 2 /* Accept Class 1,2 & 3 frames */ -+ -+/* 15.4.8.5 802.11k RCPI-dBm mapping*/ -+#define NDBM_LOW_BOUND_FOR_RCPI 110 -+#define RCPI_LOW_BOUND 0 -+#define RCPI_HIGH_BOUND 220 -+#define RCPI_MEASUREMENT_NOT_AVAILABLE 255 -+ -+/* PHY characteristics */ -+/* 17.4.4/18.3.3/19.8.4 Slot Time (aSlotTime) */ -+#define SLOT_TIME_LONG 20 /* Long Slot Time */ -+#define SLOT_TIME_SHORT 9 /* Short Slot Time */ -+ -+#define SLOT_TIME_HR_DSSS SLOT_TIME_LONG /* 802.11b aSlotTime */ -+#define SLOT_TIME_OFDM SLOT_TIME_SHORT /* 802.11a aSlotTime(20M Spacing) */ -+#define SLOT_TIME_OFDM_10M_SPACING 13 /* 802.11a aSlotTime(10M Spacing) */ -+#define SLOT_TIME_ERP_LONG SLOT_TIME_LONG /* 802.11g aSlotTime(Long) */ -+#define SLOT_TIME_ERP_SHORT SLOT_TIME_SHORT /* 802.11g aSlotTime(Short) */ -+ -+/* 17.4.4/18.3.3/19.8.4 Contention Window (aCWmin & aCWmax) */ -+#define CWMIN_OFDM 15 /* 802.11a aCWmin */ -+#define CWMAX_OFDM 1023 /* 802.11a aCWmax */ -+ -+#define CWMIN_HR_DSSS 31 /* 802.11b aCWmin */ -+#define CWMAX_HR_DSSS 1023 /* 802.11b aCWmax */ -+ -+#define CWMIN_ERP_0 31 /* 802.11g aCWmin(0) - for only have 1/2/5/11Mbps Rates */ -+#define CWMIN_ERP_1 15 /* 802.11g aCWmin(1) */ -+#define CWMAX_ERP 1023 /* 802.11g aCWmax */ -+ -+/* Short Inter-Frame Space (aSIFSTime) */ -+/* 15.3.3 802.11b aSIFSTime */ -+#define SIFS_TIME_HR_DSSS 10 -+/* 17.4.4 802.11a aSIFSTime */ -+#define SIFS_TIME_OFDM 16 -+/* 19.8.4 802.11g aSIFSTime */ -+#define SIFS_TIME_ERP 10 -+ -+/* 15.4.6.2 Number of operating channels */ -+#define CH_1 0x1 -+#define CH_2 0x2 -+#define CH_3 0x3 -+#define CH_4 0x4 -+#define CH_5 0x5 -+#define CH_6 0x6 -+#define CH_7 0x7 -+#define CH_8 0x8 -+#define CH_9 0x9 -+#define CH_10 0xa -+#define CH_11 0xb -+#define CH_12 0xc -+#define CH_13 0xd -+#define CH_14 0xe -+ -+#define MAXIMUM_OPERATION_CHANNEL_LIST 46 -+ -+/* 3 --------------- IEEE 802.11 PICS --------------- */ -+/* Annex D - dot11OperationEntry 2 */ -+#define DOT11_RTS_THRESHOLD_MIN 0 -+#define DOT11_RTS_THRESHOLD_MAX 2347 /* from Windows DDK */ -+/* #define DOT11_RTS_THRESHOLD_MAX 3000 // from Annex D */ -+ -+#define DOT11_RTS_THRESHOLD_DEFAULT \ -+ DOT11_RTS_THRESHOLD_MAX -+ -+/* Annex D - dot11OperationEntry 5 */ -+#define DOT11_FRAGMENTATION_THRESHOLD_MIN 256 -+#define DOT11_FRAGMENTATION_THRESHOLD_MAX 2346 /* from Windows DDK */ -+/* #define DOT11_FRAGMENTATION_THRESHOLD_MAX 3000 // from Annex D */ -+ -+#define DOT11_FRAGMENTATION_THRESHOLD_DEFAULT \ -+ DOT11_FRAGMENTATION_THRESHOLD_MAX -+ -+/* Annex D - dot11OperationEntry 6 */ -+#define DOT11_TRANSMIT_MSDU_LIFETIME_TU_MIN 1 -+#define DOT11_TRANSMIT_MSDU_LIFETIME_TU_MAX 0xFFFFffff -+#define DOT11_TRANSMIT_MSDU_LIFETIME_TU_DEFAULT 4095 /* 802.11 define 512 */ -+ /* MT5921 only aceept N <= 4095 */ -+ -+/* Annex D - dot11OperationEntry 7 */ -+#define DOT11_RECEIVE_LIFETIME_TU_MIN 1 -+#define DOT11_RECEIVE_LIFETIME_TU_MAX 0xFFFFffff -+#define DOT11_RECEIVE_LIFETIME_TU_DEFAULT 4096 /* 802.11 define 512 */ -+ -+/* Annex D - dot11StationConfigEntry 12 */ -+#define DOT11_BEACON_PERIOD_MIN 1 /* TU. */ -+#define DOT11_BEACON_PERIOD_MAX 0xffff /* TU. */ -+#define DOT11_BEACON_PERIOD_DEFAULT 100 /* TU. */ -+ -+/* Annex D - dot11StationConfigEntry 13 */ -+#define DOT11_DTIM_PERIOD_MIN 1 /* TU. */ -+#define DOT11_DTIM_PERIOD_MAX 255 /* TU. */ -+#define DOT11_DTIM_PERIOD_DEFAULT 1 /* TU. */ -+ -+/* Annex D - dot11RegDomainsSupportValue */ -+#define REGULATION_DOMAIN_FCC 0x10 /* FCC (US) */ -+#define REGULATION_DOMAIN_IC 0x20 /* IC or DOC (Canada) */ -+#define REGULATION_DOMAIN_ETSI 0x30 /* ETSI (Europe) */ -+#define REGULATION_DOMAIN_SPAIN 0x31 /* Spain */ -+#define REGULATION_DOMAIN_FRANCE 0x32 /* France */ -+#define REGULATION_DOMAIN_JAPAN 0x40 /* MKK (Japan) */ -+#define REGULATION_DOMAIN_CHINA 0x50 /* China */ -+#define REGULATION_DOMAIN_OTHER 0x00 /* Other */ -+ -+/* 3 --------------- IEEE 802.11 MAC header fields --------------- */ -+/* 7.1.3.1 Masks for the subfields in the Frame Control field */ -+#define MASK_FC_PROTOCOL_VER BITS(0, 1) -+#define MASK_FC_TYPE BITS(2, 3) -+#define MASK_FC_SUBTYPE BITS(4, 7) -+#define MASK_FC_SUBTYPE_QOS_DATA BIT(7) -+#define MASK_FC_TO_DS BIT(8) -+#define MASK_FC_FROM_DS BIT(9) -+#define MASK_FC_MORE_FRAG BIT(10) -+#define MASK_FC_RETRY BIT(11) -+#define MASK_FC_PWR_MGT BIT(12) -+#define MASK_FC_MORE_DATA BIT(13) -+#define MASK_FC_PROTECTED_FRAME BIT(14) -+#define MASK_FC_ORDER BIT(15) -+ -+#define MASK_FRAME_TYPE (MASK_FC_TYPE | MASK_FC_SUBTYPE) -+#define MASK_TO_DS_FROM_DS (MASK_FC_TO_DS | MASK_FC_FROM_DS) -+ -+#define MAX_NUM_OF_FC_SUBTYPES 16 -+#define OFFSET_OF_FC_SUBTYPE 4 -+ -+/* 7.1.3.1.2 MAC frame types and subtypes */ -+#define MAC_FRAME_TYPE_MGT 0 -+#define MAC_FRAME_TYPE_CTRL BIT(2) -+#define MAC_FRAME_TYPE_DATA BIT(3) -+#define MAC_FRAME_TYPE_QOS_DATA (MAC_FRAME_TYPE_DATA | MASK_FC_SUBTYPE_QOS_DATA) -+ -+#define MAC_FRAME_ASSOC_REQ (MAC_FRAME_TYPE_MGT | 0x0000) -+#define MAC_FRAME_ASSOC_RSP (MAC_FRAME_TYPE_MGT | 0x0010) -+#define MAC_FRAME_REASSOC_REQ (MAC_FRAME_TYPE_MGT | 0x0020) -+#define MAC_FRAME_REASSOC_RSP (MAC_FRAME_TYPE_MGT | 0x0030) -+#define MAC_FRAME_PROBE_REQ (MAC_FRAME_TYPE_MGT | 0x0040) -+#define MAC_FRAME_PROBE_RSP (MAC_FRAME_TYPE_MGT | 0x0050) -+#define MAC_FRAME_BEACON (MAC_FRAME_TYPE_MGT | 0x0080) -+#define MAC_FRAME_ATIM (MAC_FRAME_TYPE_MGT | 0x0090) -+#define MAC_FRAME_DISASSOC (MAC_FRAME_TYPE_MGT | 0x00A0) -+#define MAC_FRAME_AUTH (MAC_FRAME_TYPE_MGT | 0x00B0) -+#define MAC_FRAME_DEAUTH (MAC_FRAME_TYPE_MGT | 0x00C0) -+#define MAC_FRAME_ACTION (MAC_FRAME_TYPE_MGT | 0x00D0) -+#define MAC_FRAME_ACTION_NO_ACK (MAC_FRAME_TYPE_MGT | 0x00E0) -+ -+#define MAC_FRAME_CONTRL_WRAPPER (MAC_FRAME_TYPE_CTRL | 0x0070) -+#define MAC_FRAME_BLOCK_ACK_REQ (MAC_FRAME_TYPE_CTRL | 0x0080) -+#define MAC_FRAME_BLOCK_ACK (MAC_FRAME_TYPE_CTRL | 0x0090) -+#define MAC_FRAME_PS_POLL (MAC_FRAME_TYPE_CTRL | 0x00A0) -+#define MAC_FRAME_RTS (MAC_FRAME_TYPE_CTRL | 0x00B0) -+#define MAC_FRAME_CTS (MAC_FRAME_TYPE_CTRL | 0x00C0) -+#define MAC_FRAME_ACK (MAC_FRAME_TYPE_CTRL | 0x00D0) -+#define MAC_FRAME_CF_END (MAC_FRAME_TYPE_CTRL | 0x00E0) -+#define MAC_FRAME_CF_END_CF_ACK (MAC_FRAME_TYPE_CTRL | 0x00F0) -+ -+#define MAC_FRAME_DATA (MAC_FRAME_TYPE_DATA | 0x0000) -+#define MAC_FRAME_DATA_CF_ACK (MAC_FRAME_TYPE_DATA | 0x0010) -+#define MAC_FRAME_DATA_CF_POLL (MAC_FRAME_TYPE_DATA | 0x0020) -+#define MAC_FRAME_DATA_CF_ACK_CF_POLL (MAC_FRAME_TYPE_DATA | 0x0030) -+#define MAC_FRAME_NULL (MAC_FRAME_TYPE_DATA | 0x0040) -+#define MAC_FRAME_CF_ACK (MAC_FRAME_TYPE_DATA | 0x0050) -+#define MAC_FRAME_CF_POLL (MAC_FRAME_TYPE_DATA | 0x0060) -+#define MAC_FRAME_CF_ACK_CF_POLL (MAC_FRAME_TYPE_DATA | 0x0070) -+#define MAC_FRAME_QOS_DATA (MAC_FRAME_TYPE_DATA | 0x0080) -+#define MAC_FRAME_QOS_DATA_CF_ACK (MAC_FRAME_TYPE_DATA | 0x0090) -+#define MAC_FRAME_QOS_DATA_CF_POLL (MAC_FRAME_TYPE_DATA | 0x00A0) -+#define MAC_FRAME_QOS_DATA_CF_ACK_CF_POLL (MAC_FRAME_TYPE_DATA | 0x00B0) -+#define MAC_FRAME_QOS_NULL (MAC_FRAME_TYPE_DATA | 0x00C0) -+#define MAC_FRAME_QOS_CF_POLL (MAC_FRAME_TYPE_DATA | 0x00E0) -+#define MAC_FRAME_QOS_CF_ACK_CF_POLL (MAC_FRAME_TYPE_DATA | 0x00F0) -+ -+/* 7.1.3.2 Mask for the AID value in the Duration/ID field */ -+#define MASK_DI_DURATION BITS(0, 14) -+#define MASK_DI_AID BITS(0, 13) -+#define MASK_DI_AID_MSB BITS(14, 15) -+#define MASK_DI_CFP_FIXED_VALUE BIT(15) -+ -+/* 7.1.3.4 Masks for the subfields in the Sequence Control field */ -+#define MASK_SC_SEQ_NUM BITS(4, 15) -+#define MASK_SC_SEQ_NUM_OFFSET 4 -+#define MASK_SC_FRAG_NUM BITS(0, 3) -+#define INVALID_SEQ_CTRL_NUM 0x000F /* According to 6.2.1.1.2 -+ * FRAG_NUM won't equal to 15 -+ */ -+ -+/* 7.1.3.5 QoS Control field */ -+#define TID_NUM 16 -+#define TID_MASK BITS(0, 3) -+#define EOSP BIT(4) -+#define ACK_POLICY BITS(5, 6) -+#define A_MSDU_PRESENT BIT(7) -+ -+#define MASK_QC_TID BITS(0, 3) -+#define MASK_QC_EOSP BIT(4) -+#define MASK_QC_EOSP_OFFSET 4 -+#define MASK_QC_ACK_POLICY BITS(5, 6) -+#define MASK_QC_ACK_POLICY_OFFSET 5 -+#define MASK_QC_A_MSDU_PRESENT BIT(7) -+ -+/* 7.1.3.5a HT Control field */ -+#define HT_CTRL_LINK_ADAPTATION_CTRL BITS(0, 15) -+#define HT_CTRL_CALIBRATION_POSITION BITS(16, 17) -+#define HT_CTRL_CALIBRATION_SEQUENCE BITS(18, 19) -+#define HT_CTRL_CSI_STEERING BITS(22, 23) -+#define HT_CTRL_NDP_ANNOUNCEMENT BIT(24) -+#define HT_CTRL_AC_CONSTRAINT BIT(30) -+#define HT_CTRL_RDG_MORE_PPDU BIT(31) -+ -+#define LINK_ADAPTATION_CTRL_TRQ BIT(1) -+#define LINK_ADAPTATION_CTRL_MAI_MRQ BIT(2) -+#define LINK_ADAPTATION_CTRL_MAI_MSI BITS(3, 5) -+#define LINK_ADAPTATION_CTRL_MFSI BITS(6, 8) -+#define LINK_ADAPTATION_CTRL_MFB_ASELC_CMD BITS(9, 11) -+#define LINK_ADAPTATION_CTRL_MFB_ASELC_DATA BITS(12, 15) -+ -+/* 7.1.3.5.3 Ack Policy subfield*/ -+#define ACK_POLICY_NORMAL_ACK_IMPLICIT_BA_REQ 0 -+#define ACK_POLICY_NO_ACK 1 -+#define ACK_POLICY_NO_EXPLICIT_ACK_PSMP_ACK 2 -+#define ACK_POLICY_BA 3 -+ -+/* 7.1.3.7 FCS field */ -+#define FCS_LEN 4 -+ -+/* 7.2.1.4 WLAN Control Frame - PS-POLL Frame */ -+#define PSPOLL_FRAME_LEN 16 /* w/o FCS */ -+ -+/* 7.2.7.1 BAR */ -+#define OFFSET_BAR_SSC_SN 4 -+ -+/* 8.3.2.2 TKIP MPDU formats */ -+#define TKIP_MIC_LEN 8 -+ -+/* 2009.11.30 mtk02468: Moved these definitions to the right place */ -+#if 0 -+/* Block Ack Parameter Set field */ -+#define BA_PARM_BA_POLICY BIT(1) -+#define BA_PARM_TID BITS(2, 5) -+#define BA_PARM_BUFFER_SIZE BITS(6, 15) -+#endif -+ -+#define BA_POLICY_IMMEDIATE BIT(1) -+ -+/* Block Ack Starting Sequence Control field */ -+#define BA_START_SEQ_CTL_FRAG_NUM BITS(0, 3) -+#define BA_START_SEQ_CTL_SSN BITS(4, 15) -+ -+/* BAR Control field */ -+#define BAR_CONTROL_NO_ACK_POLICY BIT(0) -+#define BAR_CONTROL_MULTI_TID BIT(1) -+#define BAR_CONTROL_COMPRESSED_BA BIT(2) -+#define BAR_CONTROL_TID_INFO BITS(12, 15) -+#define BAR_CONTROL_TID_INFO_OFFSET 12 -+ -+/* TID Value */ -+#define BAR_INFO_TID_VALUE BITS(12, 15) -+ -+#define BAR_COMPRESSED_VARIANT_FRAME_LEN (16 + 4) -+ -+/* 3 --------------- IEEE 802.11 frame body fields --------------- */ -+/* 3 Management frame body components (I): Fixed Fields. */ -+/* 7.3.1.1 Authentication Algorithm Number field */ -+#define AUTH_ALGORITHM_NUM_FIELD_LEN 2 -+ -+#define AUTH_ALGORITHM_NUM_OPEN_SYSTEM 0 /* Open System */ -+#define AUTH_ALGORITHM_NUM_SHARED_KEY 1 /* Shared Key */ -+#define AUTH_ALGORITHM_NUM_FAST_BSS_TRANSITION 2 /* Fast BSS Transition */ -+ -+/* 7.3.1.2 Authentication Transaction Sequence Number field */ -+#define AUTH_TRANSACTION_SEQENCE_NUM_FIELD_LEN 2 -+#define AUTH_TRANSACTION_SEQ_1 1 -+#define AUTH_TRANSACTION_SEQ_2 2 -+#define AUTH_TRANSACTION_SEQ_3 3 -+#define AUTH_TRANSACTION_SEQ_4 4 -+ -+/* 7.3.1.3 Beacon Interval field */ -+#define BEACON_INTERVAL_FIELD_LEN 2 -+ -+/* 7.3.1.4 Capability Information field */ -+#define CAP_INFO_FIELD_LEN 2 -+#define CAP_INFO_ESS BIT(0) -+#define CAP_INFO_IBSS BIT(1) -+#define CAP_INFO_BSS_TYPE (CAP_INFO_ESS | CAP_INFO_IBSS) -+#define CAP_INFO_CF_POLLABLE BIT(2) -+#define CAP_INFO_CF_POLL_REQ BIT(3) -+#define CAP_INFO_CF (CAP_INFO_CF_POLLABLE | CAP_INFO_CF_POLL_REQ) -+#define CAP_INFO_PRIVACY BIT(4) -+#define CAP_INFO_SHORT_PREAMBLE BIT(5) -+#define CAP_INFO_PBCC BIT(6) -+#define CAP_INFO_CH_AGILITY BIT(7) -+#define CAP_INFO_SPEC_MGT BIT(8) -+#define CAP_INFO_QOS BIT(9) -+#define CAP_INFO_SHORT_SLOT_TIME BIT(10) -+#define CAP_INFO_APSD BIT(11) -+#define CAP_INFO_RESERVED BIT(12) -+#define CAP_INFO_DSSS_OFDM BIT(13) -+#define CAP_INFO_DELAYED_BLOCK_ACK BIT(14) -+#define CAP_INFO_IMM_BLOCK_ACK BIT(15) -+/* STA usage of CF-Pollable and CF-Poll Request subfields */ -+/* STA: not CF-Pollable */ -+#define CAP_CF_STA_NOT_POLLABLE 0x0000 -+/* STA: CF-Pollable, not requesting on the CF-Polling list */ -+#define CAP_CF_STA_NOT_ON_LIST CAP_INFO_CF_POLL_REQ -+/* STA: CF-Pollable, requesting on the CF-Polling list */ -+#define CAP_CF_STA_ON_LIST CAP_INFO_CF_POLLABLE -+/* STA: CF-Pollable, requesting never to be polled */ -+#define CAP_CF_STA_NEVER_POLLED (CAP_INFO_CF_POLLABLE | CAP_INFO_CF_POLL_REQ) -+ -+/* AP usage of CF-Pollable and CF-Poll Request subfields */ -+/* AP: No point coordinator (PC) */ -+#define CAP_CF_AP_NO_PC 0x0000 -+/* AP: PC at AP for delivery only (no polling) */ -+#define CAP_CF_AP_DELIVERY_ONLY CAP_INFO_CF_POLL_REQ -+/* AP: PC at AP for delivery and polling */ -+#define CAP_CF_AP_DELIVERY_POLLING CAP_INFO_CF_POLLABLE -+ -+/* 7.3.1.5 Current AP Address field */ -+#define CURR_AP_ADDR_FIELD_LEN MAC_ADDR_LEN -+ -+/* 7.3.1.6 Listen Interval field */ -+#define LISTEN_INTERVAL_FIELD_LEN 2 -+ -+/* 7.3.1.7 Reason Code field */ -+#define REASON_CODE_FIELD_LEN 2 -+ -+#define REASON_CODE_RESERVED 0 /* Reseved */ -+#define REASON_CODE_UNSPECIFIED 1 /* Unspecified reason */ -+#define REASON_CODE_PREV_AUTH_INVALID 2 /* Previous auth no longer valid */ -+#define REASON_CODE_DEAUTH_LEAVING_BSS 3 /* Deauth because sending STA is leaving BSS */ -+#define REASON_CODE_DISASSOC_INACTIVITY 4 /* Disassoc due to inactivity */ -+#define REASON_CODE_DISASSOC_AP_OVERLOAD 5 /* Disassoc because AP is unable to handle all assoc STAs */ -+#define REASON_CODE_CLASS_2_ERR 6 /* Class 2 frame rx from nonauth STA */ -+#define REASON_CODE_CLASS_3_ERR 7 /* Class 3 frame rx from nonassoc STA */ -+#define REASON_CODE_DISASSOC_LEAVING_BSS 8 /* Disassoc because sending STA is leaving BSS */ -+#define REASON_CODE_ASSOC_BEFORE_AUTH 9 /* STA requesting (re)assoc is not auth with responding STA */ -+#define REASON_CODE_DISASSOC_PWR_CAP_UNACCEPTABLE 10 /* Disassoc because the info in Power Capability is -+ unacceptable */ -+#define REASON_CODE_DISASSOC_SUP_CHS_UNACCEPTABLE 11 /* Disassoc because the info in Supported Channels is -+ unacceptable */ -+#define REASON_CODE_INVALID_INFO_ELEM 13 /* Invalid information element */ -+#define REASON_CODE_MIC_FAILURE 14 /* MIC failure */ -+#define REASON_CODE_4_WAY_HANDSHAKE_TIMEOUT 15 /* 4-way handshake timeout */ -+#define REASON_CODE_GROUP_KEY_UPDATE_TIMEOUT 16 /* Group key update timeout */ -+#define REASON_CODE_DIFFERENT_INFO_ELEM 17 /* Info element in 4-way handshake different from -+ (Re-)associate request/Probe response/Beacon */ -+#define REASON_CODE_MULTICAST_CIPHER_NOT_VALID 18 /* Multicast Cipher is not valid */ -+#define REASON_CODE_UNICAST_CIPHER_NOT_VALID 19 /* Unicast Cipher is not valid */ -+#define REASON_CODE_AKMP_NOT_VALID 20 /* AKMP is not valid */ -+#define REASON_CODE_UNSUPPORTED_RSNE_VERSION 21 /* Unsupported RSNE version */ -+#define REASON_CODE_INVALID_RSNE_CAPABILITIES 22 /* Invalid RSNE Capabilities */ -+#define REASON_CODE_IEEE_802_1X_AUTH_FAILED 23 /* IEEE 802.1X Authentication failed */ -+#define REASON_CODE_CIPHER_REJECT_SEC_POLICY 24 /* Cipher suite rejected because of the security policy */ -+#define REASON_CODE_DISASSOC_UNSPECIFIED_QOS 32 /* Disassoc for unspecified, QoS-related reason */ -+#define REASON_CODE_DISASSOC_LACK_OF_BANDWIDTH 33 /* Disassoc because QAP lacks sufficient bandwidth -+ for this QSTA */ -+#define REASON_CODE_DISASSOC_ACK_LOST_POOR_CHANNEL 34 /* Disassoc because of too many ACKs lost for AP transmissions -+ and/or poor channel conditions */ -+#define REASON_CODE_DISASSOC_TX_OUTSIDE_TXOP_LIMIT 35 /* Disassoc because QSTA is transmitting outside the limits of -+ its TXOPs */ -+#define REASON_CODE_PEER_WHILE_LEAVING 36 /* QSTA is leaving the QBSS or resetting */ -+#define REASON_CODE_PEER_REFUSE_DLP 37 /* Peer does not want to use this mechanism */ -+#define REASON_CODE_PEER_SETUP_REQUIRED 38 /* Frames received but a setup is reqired */ -+#define REASON_CODE_PEER_TIME_OUT 39 /* Time out */ -+#define REASON_CODE_PEER_CIPHER_UNSUPPORTED 45 /* Peer does not support the requested cipher suite */ -+#define REASON_CODE_BEACON_TIMEOUT 100 /* for beacon timeout, defined by mediatek */ -+#define REASON_CODE_BSS_SECURITY_CHANGE 101 /* for BSS security change, defined by mediatek */ -+/* 7.3.1.8 AID field */ -+#define AID_FIELD_LEN 2 -+#define AID_MASK BITS(0, 13) -+#define AID_MSB BITS(14, 15) -+#define AID_MIN_VALUE 1 -+#define AID_MAX_VALUE 2007 -+ -+/* 7.3.1.9 Status Code field */ -+#define STATUS_CODE_FIELD_LEN 2 -+ -+#define STATUS_CODE_RESERVED 0 /* Reserved - Used by TX Auth */ -+#define STATUS_CODE_SUCCESSFUL 0 /* Successful */ -+#define STATUS_CODE_UNSPECIFIED_FAILURE 1 /* Unspecified failure */ -+#define STATUS_CODE_CAP_NOT_SUPPORTED 10 /* Cannot support all requested cap in the Cap Info field */ -+#define STATUS_CODE_REASSOC_DENIED_WITHOUT_ASSOC 11 /* Reassoc denied due to inability to confirm that -+ assoc exists */ -+#define STATUS_CODE_ASSOC_DENIED_OUTSIDE_STANDARD 12 /* Assoc denied due to reason outside the scope of this std. */ -+#define STATUS_CODE_AUTH_ALGORITHM_NOT_SUPPORTED 13 /* Responding STA does not support the specified -+ auth algorithm */ -+#define STATUS_CODE_AUTH_OUT_OF_SEQ 14 /* Rx an auth frame with auth transaction seq num -+ out of expected seq */ -+#define STATUS_CODE_AUTH_REJECTED_CHAL_FAIL 15 /* Auth rejected because of challenge failure */ -+#define STATUS_CODE_AUTH_REJECTED_TIMEOUT 16 /* Auth rejected due to timeout waiting for next frame -+ in sequence */ -+#define STATUS_CODE_ASSOC_DENIED_AP_OVERLOAD 17 /* Assoc denied because AP is unable to handle additional -+ assoc STAs */ -+#define STATUS_CODE_ASSOC_DENIED_RATE_NOT_SUPPORTED 18 /* Assoc denied due to requesting STA not supporting -+ all of basic rates */ -+#define STATUS_CODE_ASSOC_DENIED_NO_SHORT_PREAMBLE 19 /* Assoc denied due to requesting STA not supporting short -+ preamble */ -+#define STATUS_CODE_ASSOC_DENIED_NO_PBCC 20 /* Assoc denied due to requesting STA not supporting PBCC */ -+#define STATUS_CODE_ASSOC_DENIED_NO_CH_AGILITY 21 /* Assoc denied due to requesting STA not supporting channel -+ agility */ -+#define STATUS_CODE_ASSOC_REJECTED_NO_SPEC_MGT 22 /* Assoc rejected because Spectrum Mgt capability is required */ -+#define STATUS_CODE_ASSOC_REJECTED_PWR_CAP 23 /* Assoc rejected because the info in Power Capability -+ is unacceptable */ -+#define STATUS_CODE_ASSOC_REJECTED_SUP_CHS 24 /* Assoc rejected because the info in Supported Channels -+ is unacceptable */ -+#define STATUS_CODE_ASSOC_DENIED_NO_SHORT_SLOT_TIME 25 /* Assoc denied due to requesting STA not supporting -+ short slot time */ -+#define STATUS_CODE_ASSOC_DENIED_NO_DSSS_OFDM 26 /* Assoc denied due to requesting STA not supporting -+ DSSS-OFDM */ -+#if CFG_SUPPORT_802_11W -+#define STATUS_CODE_ASSOC_REJECTED_TEMPORARILY 30 /* IEEE 802.11w, Assoc denied due to the SA query */ -+#define STATUS_CODE_ROBUST_MGMT_FRAME_POLICY_VIOLATION 31 /* IEEE 802.11w, Assoc denied due to the MFP select -+ policy */ -+#endif -+#define STATUS_CODE_UNSPECIFIED_QOS_FAILURE 32 /* Unspecified, QoS-related failure */ -+#define STATUS_CODE_ASSOC_DENIED_BANDWIDTH 33 /* Assoc denied due to insufficient bandwidth to handle another -+ QSTA */ -+#define STATUS_CODE_ASSOC_DENIED_POOR_CHANNEL 34 /* Assoc denied due to excessive frame loss rates and/or poor -+ channel conditions */ -+#define STATUS_CODE_ASSOC_DENIED_NO_QOS_FACILITY 35 /* Assoc denied due to requesting STA not supporting QoS -+ facility */ -+#define STATUS_CODE_REQ_DECLINED 37 /* Request has been declined */ -+#define STATUS_CODE_REQ_INVALID_PARAMETER_VALUE 38 /* Request has not been successful as one or more parameters -+ have invalid values */ -+#define STATUS_CODE_REQ_NOT_HONORED_TSPEC 39 /* TS not created because request cannot be honored. -+ Suggested TSPEC provided. */ -+#define STATUS_CODE_INVALID_INFO_ELEMENT 40 /* Invalid information element */ -+#define STATUS_CODE_INVALID_GROUP_CIPHER 41 /* Invalid group cipher */ -+#define STATUS_CODE_INVALID_PAIRWISE_CIPHER 42 /* Invalid pairwise cipher */ -+#define STATUS_CODE_INVALID_AKMP 43 /* Invalid AKMP */ -+#define STATUS_CODE_UNSUPPORTED_RSN_IE_VERSION 44 /* Unsupported RSN information element version */ -+#define STATUS_CODE_INVALID_RSN_IE_CAP 45 /* Invalid RSN information element capabilities */ -+#define STATUS_CODE_CIPHER_SUITE_REJECTED 46 /* Cipher suite rejected because of security policy */ -+#define STATUS_CODE_REQ_NOT_HONORED_TS_DELAY 47 /* TS not created because request cannot be honored. -+ Attempt to create a TS later. */ -+#define STATUS_CODE_DIRECT_LINK_NOT_ALLOWED 48 /* Direct Link is not allowed in the BSS by policy */ -+#define STATUS_CODE_DESTINATION_STA_NOT_PRESENT 49 /* Destination STA is not present within this QBSS */ -+#define STATUS_CODE_DESTINATION_STA_NOT_QSTA 50 /* Destination STA is not a QSTA */ -+#define STATUS_CODE_ASSOC_DENIED_LARGE_LIS_INTERVAL 51 /* Association denied because the ListenInterval is too large */ -+ -+/* proprietary definition of reserved field of Status Code */ -+#define STATUS_CODE_JOIN_FAILURE 0xFFF0 /* Join failure */ -+#define STATUS_CODE_JOIN_TIMEOUT 0xFFF1 /* Join timeout */ -+#define STATUS_CODE_AUTH_TIMEOUT 0xFFF2 /* Authentication timeout */ -+#define STATUS_CODE_ASSOC_TIMEOUT 0xFFF3 /* (Re)Association timeout */ -+#define STATUS_CODE_CCX_CCKM_REASSOC_FAILURE 0xFFF4 /* CCX CCKM reassociation failure */ -+ -+/* 7.3.1.10 Timestamp field */ -+#define TIMESTAMP_FIELD_LEN 8 -+ -+/* 7.3.1.11 Category of Action field */ -+#define CATEGORY_SPEC_MGT 0 -+#define CATEGORY_QOS_ACTION 1 /* QoS action */ -+#define CATEGORY_DLS_ACTION 2 /* Direct Link Protocol (DLP) action */ -+#define CATEGORY_BLOCK_ACK_ACTION 3 /* Block ack action */ -+#define CATEGORY_PUBLIC_ACTION 4 /* Public action */ -+#define CATEGORY_RM_ACTION 5 /* Radio measurement action */ -+#define CATEGORY_HT_ACTION 7 -+#if CFG_SUPPORT_802_11W -+#define CATEGORY_SA_QUERT_ACTION 8 -+#endif -+#define CATEGORY_WNM_ACTION 10 /* 802.11v Wireless Network Management */ -+#define CATEGORY_UNPROTECTED_WNM_ACTION 11 /* 802.11v Wireless Network Management */ -+#define CATEGORY_WME_MGT_NOTIFICATION 17 /* WME management notification */ -+#define CATEGORY_VENDOR_SPECIFIC_ACTION 127 -+ -+/* 7.3.1.14 Block Ack Parameter Set field */ -+#define BA_PARAM_SET_ACK_POLICY_MASK BIT(1) -+#define BA_PARAM_SET_ACK_POLICY_MASK_OFFSET 1 -+#define BA_PARAM_SET_TID_MASK BITS(2, 5) -+#define BA_PARAM_SET_TID_MASK_OFFSET 2 -+#define BA_PARAM_SET_BUFFER_SIZE_MASK BITS(6, 15) -+#define BA_PARAM_SET_BUFFER_SIZE_MASK_OFFSET 6 -+ -+#define BA_PARAM_SET_ACK_POLICY_IMMEDIATE_BA 1 -+#define BA_PARAM_SET_ACK_POLICY_DELAYED_BA 0 -+ -+/* 3 Management frame body components (II): Information Elements. */ -+/* 7.3.2 Element IDs of information elements */ -+#define ELEM_HDR_LEN 2 -+ -+#define ELEM_ID_SSID 0 /* SSID */ -+#define ELEM_ID_SUP_RATES 1 /* Supported rates */ -+#define ELEM_ID_FH_PARAM_SET 2 /* FH parameter set */ -+#define ELEM_ID_DS_PARAM_SET 3 /* DS parameter set */ -+#define ELEM_ID_CF_PARAM_SET 4 /* CF parameter set */ -+#define ELEM_ID_TIM 5 /* TIM */ -+#define ELEM_ID_IBSS_PARAM_SET 6 /* IBSS parameter set */ -+#define ELEM_ID_COUNTRY_INFO 7 /* Country information */ -+#define ELEM_ID_HOPPING_PATTERN_PARAM 8 /* Hopping pattern parameters */ -+#define ELEM_ID_HOPPING_PATTERN_TABLE 9 /* Hopping pattern table */ -+#define ELEM_ID_REQUEST 10 /* Request */ -+#define ELEM_ID_BSS_LOAD 11 /* BSS load */ -+#define ELEM_ID_EDCA_PARAM_SET 12 /* EDCA parameter set */ -+#define ELEM_ID_TSPEC 13 /* Traffic specification (TSPEC) */ -+#define ELEM_ID_TCLAS 14 /* Traffic classification (TCLAS) */ -+#define ELEM_ID_SCHEDULE 15 /* Schedule */ -+#define ELEM_ID_CHALLENGE_TEXT 16 /* Challenge text */ -+ -+#define ELEM_ID_PWR_CONSTRAINT 32 /* Power constraint */ -+#define ELEM_ID_PWR_CAP 33 /* Power capability */ -+#define ELEM_ID_TPC_REQ 34 /* TPC request */ -+#define ELEM_ID_TPC_REPORT 35 /* TPC report */ -+#define ELEM_ID_SUP_CHS 36 /* Supported channels */ -+#define ELEM_ID_CH_SW_ANNOUNCEMENT 37 /* Channel switch announcement */ -+#define ELEM_ID_MEASUREMENT_REQ 38 /* Measurement request */ -+#define ELEM_ID_MEASUREMENT_REPORT 39 /* Measurement report */ -+#define ELEM_ID_QUIET 40 /* Quiet */ -+#define ELEM_ID_IBSS_DFS 41 /* IBSS DFS */ -+#define ELEM_ID_ERP_INFO 42 /* ERP information */ -+#define ELEM_ID_TS_DELAY 43 /* TS delay */ -+#define ELEM_ID_TCLAS_PROCESSING 44 /* TCLAS processing */ -+#define ELEM_ID_HT_CAP 45 /* HT Capabilities subelement */ -+#define ELEM_ID_QOS_CAP 46 /* QoS capability */ -+#define ELEM_ID_RSN 48 /* RSN IE */ -+#define ELEM_ID_EXTENDED_SUP_RATES 50 /* Extended supported rates */ -+#define ELEM_ID_TIMEOUT_INTERVAL 56 /* 802.11w SA Timeout interval */ -+#define ELEM_ID_SUP_OPERATING_CLASS 59 /* Supported Operating Classes */ -+#define ELEM_ID_HT_OP 61 /* HT Operation */ -+#define ELEM_ID_SCO 62 /* Secondary Channel Offset */ -+#define ELEM_ID_RRM_ENABLED_CAP 70 /* Radio Resource Management Enabled Capabilities */ -+#define ELEM_ID_20_40_BSS_COEXISTENCE 72 /* 20/40 BSS Coexistence */ -+#define ELEM_ID_20_40_INTOLERANT_CHNL_REPORT 73 /* 20/40 BSS Intolerant Channel Report */ -+#define ELEM_ID_OBSS_SCAN_PARAMS 74 /* Overlapping BSS Scan Parameters */ -+#define ELEM_ID_INTERWORKING 107 /* Interworking with External Network */ -+#define ELEM_ID_ADVERTISEMENT_PROTOCOL 108 /* Advertisement Protocol */ -+#define ELEM_ID_ROAMING_CONSORTIUM 111 /* Roaming Consortium */ -+#define ELEM_ID_EXTENDED_CAP 127 /* Extended capabilities */ -+ -+#define ELEM_ID_VENDOR 221 /* Vendor specific IE */ -+#define ELEM_ID_WPA ELEM_ID_VENDOR /* WPA IE */ -+#define ELEM_ID_WMM ELEM_ID_VENDOR /* WMM IE */ -+#define ELEM_ID_P2P ELEM_ID_VENDOR /* WiFi Direct */ -+#define ELEM_ID_WFD ELEM_ID_VENDOR /* WiFi Direct */ -+#define ELEM_ID_WSC ELEM_ID_VENDOR /* WSC IE */ -+ -+#define ELEM_ID_RESERVED 255 /* Reserved */ -+ -+/* 7.3.2.1 SSID element */ -+#define ELEM_MAX_LEN_SSID 32 -+ -+/* 7.3.2.2 Supported Rates */ -+#define ELEM_MAX_LEN_SUP_RATES 8 -+ -+/* 7.3.2.4 DS Parameter Set */ -+#define ELEM_MAX_LEN_DS_PARAMETER_SET 1 -+ -+/* 7.3.2.5 CF Parameter Set */ -+#define ELEM_CF_PARM_LEN 8 -+ -+/* 7.3.2.6 TIM */ -+#define ELEM_MIX_LEN_TIM 4 -+#define ELEM_MAX_LEN_TIM 254 -+ -+/* 7.3.2.7 IBSS Parameter Set element */ -+#define ELEM_MAX_LEN_IBSS_PARAMETER_SET 2 -+ -+/* 7.3.2.8 Challenge Text element */ -+#define ELEM_MIN_LEN_CHALLENGE_TEXT 1 -+#define ELEM_MAX_LEN_CHALLENGE_TEXT 253 -+ -+/* 7.3.2.9 Country Information element */ -+/* Country IE should contain at least 3-bytes country code string and one subband triplet. */ -+#define ELEM_MIN_LEN_COUNTRY_INFO 6 -+ -+#define ELEM_ID_COUNTRY_INFO_TRIPLET_LEN_FIXED 3 -+#define ELEM_ID_COUNTRY_INFO_SUBBAND_TRIPLET_LEN_FIXED 3 -+#define ELEM_ID_COUNTRY_INFO_REGULATORY_TRIPLET_LEN_FIXED 3 -+ -+/* 7.3.2.13 ERP Information element */ -+#define ELEM_MAX_LEN_ERP 1 -+/* -- bits in the ERP Information element */ -+#define ERP_INFO_NON_ERP_PRESENT BIT(0) /* NonERP_Present bit */ -+#define ERP_INFO_USE_PROTECTION BIT(1) /* Use_Protection bit */ -+#define ERP_INFO_BARKER_PREAMBLE_MODE BIT(2) /* Barker_Preamble_Mode bit */ -+ -+/* 7.3.2.14 Extended Supported Rates */ -+#define ELEM_MAX_LEN_EXTENDED_SUP_RATES 255 -+ -+#if CFG_SUPPORT_DFS -+/* 7.3.2.19 Supported Channels element */ -+#define ELEM_MAX_LEN_SUPPORTED_CHANNELS 7 -+#endif -+ -+/* 7.3.2.21 Measurement Request element */ -+#define ELEM_RM_TYPE_BASIC_REQ 0 -+#define ELEM_RM_TYPE_CCA_REQ 1 -+#define ELEM_RM_TYPE_RPI_HISTOGRAM_REQ 2 -+#define ELEM_RM_TYPE_CHNL_LOAD_REQ 3 -+#define ELEM_RM_TYPE_NOISE_HISTOGRAM_REQ 4 -+#define ELEM_RM_TYPE_BEACON_REQ 5 -+#define ELEM_RM_TYPE_FRAME_REQ 6 -+#define ELEM_RM_TYPE_STA_STATISTICS_REQ 7 -+#define ELEM_RM_TYPE_LCI_REQ 8 -+#define ELEM_RM_TYPE_TS_REQ 9 -+#define ELEM_RM_TYPE_MEASURE_PAUSE_REQ 255 -+ -+/* 7.3.2.22 Measurement Report element */ -+#define ELEM_RM_TYPE_BASIC_REPORT 0 -+#define ELEM_RM_TYPE_CCA_REPORT 1 -+#define ELEM_RM_TYPE_RPI_HISTOGRAM_REPORT 2 -+#define ELEM_RM_TYPE_CHNL_LOAD_REPORT 3 -+#define ELEM_RM_TYPE_NOISE_HISTOGRAM_REPORT 4 -+#define ELEM_RM_TYPE_BEACON_REPORT 5 -+#define ELEM_RM_TYPE_FRAME_REPORT 6 -+#define ELEM_RM_TYPE_STA_STATISTICS_REPORT 7 -+#define ELEM_RM_TYPE_LCI_REPORT 8 -+#define ELEM_RM_TYPE_TS_REPORT 9 -+/*Auto Channel Selection*/ -+#if CFG_AUTO_CHANNEL_SEL_SUPPORT -+#define ELEM_RM_TYPE_ACS_CHN 1 -+#define ELEM_RM_TYPE_LTE_CHN 2 -+#endif -+ -+/* 7.3.2.25 RSN information element */ -+#define ELEM_MAX_LEN_WPA 34 /* one pairwise, one AKM suite, one PMKID */ -+#define ELEM_MAX_LEN_RSN 38 /* one pairwise, one AKM suite, one PMKID */ -+#define ELEM_MAX_LEN_WAPI 38 /* one pairwise, one AKM suite, one BKID */ -+#define ELEM_MAX_LEN_WSC 200 /* one pairwise, one AKM suite, one BKID */ -+ -+#if CFG_SUPPORT_802_11W -+#define ELEM_WPA_CAP_MFPR BIT(6) -+#define ELEM_WPA_CAP_MFPC BIT(7) -+#endif -+ -+/* 7.3.2.27 Extended Capabilities information element */ -+#define ELEM_EXT_CAP_20_40_COEXIST_SUPPORT BIT(0) -+#define ELEM_EXT_CAP_PSMP_CAP BIT(4) -+#define ELEM_EXT_CAP_SERVICE_INTERVAL_GRANULARITY BIT(5) -+#define ELEM_EXT_CAP_SCHEDULE_PSMP BIT(6) -+ -+#define ELEM_EXT_CAP_BSS_TRANSITION_BIT 19 -+#define ELEM_EXT_CAP_UTC_TSF_OFFSET_BIT 27 -+#define ELEM_EXT_CAP_INTERWORKING_BIT 31 -+#define ELEM_EXT_CAP_WNM_NOTIFICATION_BIT 46 -+ -+#if CFG_SUPPORT_HOTSPOT_2_0 -+#define ELEM_MAX_LEN_EXT_CAP (6) -+#else -+#define ELEM_MAX_LEN_EXT_CAP (3 - ELEM_HDR_LEN) -+#endif -+ -+/* 7.3.2.30 TSPEC element */ -+#define TS_INFO_TRAFFIC_TYPE_MASK BIT(0) /* WMM: 0 (Asynchronous TS of low-duty cycles) */ -+#define TS_INFO_TID_OFFSET 1 -+#define TS_INFO_TID_MASK BITS(1, 4) -+#define TS_INFO_DIRECTION_OFFSET 5 -+#define TS_INFO_DIRECTION_MASK BITS(5, 6) -+#define TS_INFO_ACCESS_POLICY_OFFSET 7 -+#define TS_INFO_ACCESS_POLICY_MASK BITS(7, 8) -+#define TS_INFO_AGGREGATION_MASK BIT(9) /* WMM: 0 */ -+#define TS_INFO_APSD_MASK BIT(10) -+#define TS_INFO_UP_OFFSET 11 -+#define TS_INFO_UP_MASK BITS(11, 13) -+#define TS_INFO_ACK_POLICY_OFFSET 14 -+#define TS_INFO_ACK_POLICY_MASK BITS(14, 15) -+#define TS_INFO_SCHEDULE_MASK 16 -+ -+/* 7.3.2.56 HT capabilities element */ -+#define ELEM_MAX_LEN_HT_CAP (28 - ELEM_HDR_LEN) /* sizeof(IE_HT_CAP_T)-2 */ -+ -+/* 7.3.2.56.2 HT capabilities Info field */ -+#define HT_CAP_INFO_LDPC_CAP BIT(0) -+#define HT_CAP_INFO_SUP_CHNL_WIDTH BIT(1) -+#define HT_CAP_INFO_SM_POWER_SAVE BITS(2, 3) -+#define HT_CAP_INFO_HT_GF BIT(4) -+#define HT_CAP_INFO_SHORT_GI_20M BIT(5) -+#define HT_CAP_INFO_SHORT_GI_40M BIT(6) -+#define HT_CAP_INFO_TX_STBC BIT(7) -+#define HT_CAP_INFO_RX_STBC BITS(8, 9) -+#define HT_CAP_INFO_HT_DELAYED_BA BIT(10) -+#define HT_CAP_INFO_MAX_AMSDU_LEN BIT(11) -+#define HT_CAP_INFO_DSSS_CCK_IN_40M BIT(12) -+#define HT_CAP_INFO_40M_INTOLERANT BIT(14) -+#define HT_CAP_INFO_LSIG_TXOP_SUPPORT BIT(15) -+ -+#define HT_CAP_INFO_RX_STBC_NO_SUPPORTED 0 -+#define HT_CAP_INFO_RX_STBC_1_SS BIT(8) -+#define HT_CAP_INFO_RX_STBC_2_SS BIT(9) -+#define HT_CAP_INFO_RX_STBC_3_SS HT_CAP_INFO_RX_STBC -+ -+/* 7.3.2.56.3 A-MPDU Parameters field */ -+#define AMPDU_PARAM_MAX_AMPDU_LEN_EXP BITS(0, 1) -+#define AMPDU_PARAM_MIN_START_SPACING BITS(2, 4) -+ -+#define AMPDU_PARAM_MAX_AMPDU_LEN_8K 0 -+#define AMPDU_PARAM_MAX_AMPDU_LEN_16K BIT(0) -+#define AMPDU_PARAM_MAX_AMPDU_LEN_32K BIT(1) -+#define AMPDU_PARAM_MAX_AMPDU_LEN_64K BITS(0, 1) -+ -+#define AMPDU_PARAM_MSS_NO_RESTRICIT 0 -+#define AMPDU_PARAM_MSS_1_4_US BIT(2) -+#define AMPDU_PARAM_MSS_1_2_US BIT(3) -+#define AMPDU_PARAM_MSS_1_US BITS(2, 3) -+#define AMPDU_PARAM_MSS_2_US BIT(4) -+#define AMPDU_PARAM_MSS_4_US (BIT(4) | BIT(2)) -+#define AMPDU_PARAM_MSS_8_US (BIT(4) | BIT(3)) -+#define AMPDU_PARAM_MSS_16_US BITS(2, 4) -+ -+/* 7.3.2.56.4 Supported MCS Set field (TX rate: octects 12~15) */ -+#define SUP_MCS_TX_SET_DEFINED BIT(0) -+#define SUP_MCS_TX_RX_SET_NOT_EQUAL BIT(1) -+#define SUP_MCS_TX_MAX_NUM_SS BITS(2, 3) -+#define SUP_MCS_TX_UNEQUAL_MODULATION BIT(4) -+ -+#define SUP_MCS_TX_MAX_NUM_1_SS 0 -+#define SUP_MCS_TX_MAX_NUM_2_SS BIT(2) -+#define SUP_MCS_TX_MAX_NUM_3_SS BIT(3) -+#define SUP_MCS_TX_MAX_NUM_4_SS BITS(2, 3) -+ -+#define SUP_MCS_RX_BITMASK_OCTET_NUM 10 -+#define SUP_MCS_RX_DEFAULT_HIGHEST_RATE 0 /* Not specify */ -+ -+/* 7.3.2.56.5 HT Extended Capabilities field */ -+#define HT_EXT_CAP_PCO BIT(0) -+#define HT_EXT_CAP_PCO_TRANSITION_TIME BITS(1, 2) -+#define HT_EXT_CAP_MCS_FEEDBACK BITS(8, 9) -+#define HT_EXT_CAP_HTC_SUPPORT BIT(10) -+#define HT_EXT_CAP_RD_RESPONDER BIT(11) -+ -+#define HT_EXT_CAP_PCO_TRANS_TIME_NONE 0 -+#define HT_EXT_CAP_PCO_TRANS_TIME_400US BIT(1) -+#define HT_EXT_CAP_PCO_TRANS_TIME_1_5MS BIT(2) -+#define HT_EXT_CAP_PCO_TRANS_TIME_5MS BITS(1, 2) -+ -+#define HT_EXT_CAP_MCS_FEEDBACK_NO_FB 0 -+#define HT_EXT_CAP_MCS_FEEDBACK_UNSOLICITED BIT(9) -+#define HT_EXT_CAP_MCS_FEEDBACK_BOTH BITS(8, 9) -+ -+/* 7.3.2.56.6 Transmit Beamforming Capabilities field */ -+ -+/* 7.3.2.56.7 Antenna Selection Capability field */ -+#define ASEL_CAP_CAPABLE BIT(0) -+#define ASEL_CAP_CSI_FB_BY_TX_ASEL_CAPABLE BIT(1) -+#define ASEL_CAP_ANT_INDICES_FB_BY_TX_ASEL_CAPABLE BIT(2) -+#define ASEL_CAP_EXPLICIT_CSI_FB_CAPABLE BIT(3) -+#define ASEL_CAP_ANT_INDICES_CAPABLE BIT(4) -+#define ASEL_CAP_RX_ASEL_CAPABLE BIT(5) -+#define ASEL_CAP_TX_SOUNDING_CAPABLE BIT(6) -+ -+/* 7.3.2.57 HT Operation element */ -+#define ELEM_MAX_LEN_HT_OP (24 - ELEM_HDR_LEN) /* sizeof(IE_HT_OP_T)-2 */ -+ -+#define HT_OP_INFO1_SCO BITS(0, 1) -+#define HT_OP_INFO1_STA_CHNL_WIDTH BIT(2) -+#define HT_OP_INFO1_RIFS_MODE BIT(3) -+ -+#define HT_OP_INFO2_HT_PROTECTION BITS(0, 1) -+#define HT_OP_INFO2_NON_GF_HT_STA_PRESENT BIT(2) -+#define HT_OP_INFO2_OBSS_NON_HT_STA_PRESENT BIT(4) -+ -+#define HT_OP_INFO3_DUAL_BEACON BIT(6) -+#define HT_OP_INFO3_DUAL_CTS_PROTECTION BIT(7) -+#define HT_OP_INFO3_STBC_BEACON BIT(8) -+#define HT_OP_INFO3_LSIG_TXOP_FULL_SUPPORT BIT(9) -+#define HT_OP_INFO3_PCO_ACTIVE BIT(10) -+#define HT_OP_INFO3_PCO_PHASE BIT(11) -+ -+/* 7.3.2.59 OBSS Scan Parameter element */ -+#define ELEM_MAX_LEN_OBSS_SCAN (16 - ELEM_HDR_LEN) -+ -+/* 7.3.2.60 20/40 BSS Coexistence element */ -+#define ELEM_MAX_LEN_20_40_BSS_COEXIST (3 - ELEM_HDR_LEN) -+ -+#define BSS_COEXIST_INFO_REQ BIT(0) -+#define BSS_COEXIST_40M_INTOLERANT BIT(1) -+#define BSS_COEXIST_20M_REQ BIT(2) -+#define BSS_COEXIST_OBSS_SCAN_EXEMPTION_REQ BIT(3) -+#define BSS_COEXIST_OBSS_SCAN_EXEMPTION_GRANT BIT(4) -+ -+/* 802.11u 7.3.2.92 Interworking IE */ -+#define ELEM_MAX_LEN_INTERWORKING (11 - ELEM_HDR_LEN) -+ -+/* 802.11u 7.3.2.93 Advertisement Protocol IE */ -+#define ELEM_MAX_LEN_ADV_PROTOCOL (4 - ELEM_HDR_LEN) -+ -+/* 802.11u 7.3.2.96 Roaming Consortium IE */ -+#define ELEM_MAX_LEN_ROAMING_CONSORTIUM (19 - ELEM_HDR_LEN) -+ -+#define IW_IE_LENGTH_ANO 1 -+#define IW_IE_LENGTH_ANO_VENUE 3 -+#define IW_IE_LENGTH_ANO_HESSID 7 -+#define IW_IE_LENGTH_ANO_VENUE_HESSID 9 -+ -+/* 3 Management frame body components (III): 7.4 Action frame format details. */ -+/* 7.4.1 Spectrum Measurement Action frame details */ -+#define ACTION_MEASUREMENT_REQ 0 /* Spectrum measurement request */ -+#define ACTION_MEASUREMENT_REPORT 1 /* Spectrum measurement report */ -+#define ACTION_TPC_REQ 2 /* TPC request */ -+#define ACTION_TPC_REPORT 3 /* TPC report */ -+#define ACTION_CHNL_SWITCH 4 /* Channel Switch Announcement */ -+ -+/* 7.4.2 QoS Action frame details */ -+#define ACTION_ADDTS_REQ 0 /* ADDTS request */ -+#define ACTION_ADDTS_RSP 1 /* ADDTS response */ -+#define ACTION_DELTS 2 /* DELTS */ -+#define ACTION_SCHEDULE 3 /* Schedule */ -+ -+#define ACTION_ADDTS_REQ_FRAME_LEN (24+3+63) /* WMM TSPEC IE: 63 */ -+#define ACTION_ADDTS_RSP_FRAME_LEN (24+4+63) /* WMM Status Code: 1; WMM TSPEC IE: 63 */ -+ -+/* 7.4.3 DLS Action frame details */ -+#define ACTION_DLS_REQ 0 /* DLS request */ -+#define ACTION_DLS_RSP 1 /* DLS response */ -+#define ACTION_DLS_TEARDOWN 2 /* DLS teardown */ -+ -+/* 7.4.4 Block ack Action frame details */ -+#define ACTION_ADDBA_REQ 0 /* ADDBA request */ -+#define ACTION_ADDBA_RSP 1 /* ADDBA response */ -+#define ACTION_DELBA 2 /* DELBA */ -+ -+#define ACTION_ADDBA_REQ_FRAME_LEN (24+9) -+#define ACTION_ADDBA_RSP_FRAME_LEN (24+9) -+ -+#define ACTION_DELBA_INITIATOR_MASK BIT(11) -+#define ACTION_DELBA_TID_MASK BITS(12, 15) -+#define ACTION_DELBA_TID_OFFSET 12 -+#define ACTION_DELBA_FRAME_LEN (24+6) -+ -+/* 7.4.6 Radio Measurement Action frame details */ -+#define ACTION_RM_REQ 0 /* Radio measurement request */ -+#define ACTION_RM_REPORT 1 /* Radio measurement report */ -+#define ACTION_LM_REQ 2 /* Link measurement request */ -+#define ACTION_LM_REPORT 3 /* Link measurement report */ -+#define ACTION_NEIGHBOR_REPORT_REQ 4 /* Neighbor report request */ -+#define ACTION_NEIGHBOR_REPORT_RSP 5 /* Neighbor report response */ -+ -+/* 7.4.7 Public Action frame details */ -+#define ACTION_PUBLIC_20_40_COEXIST 0 /* 20/40 BSS coexistence */ -+ -+#if CFG_SUPPORT_802_11W -+/* SA Query Action frame (IEEE 802.11w/D8.0, 7.4.9) */ -+#define ACTION_SA_QUERY_REQUEST 0 -+#define ACTION_SA_QUERY_RESPONSE 1 -+ -+#define ACTION_SA_QUERY_TR_ID_LEN 2 -+ -+/* Timeout Interval Type */ -+#define ACTION_SA_TIMEOUT_REASSOC_DEADLINE 1 -+#define ACTION_SA_TIMEOUT_KEY_LIFETIME 2 -+#define ACTION_SA_TIMEOUT_ASSOC_COMEBACK 3 -+#endif -+ -+/* 7.4.10.1 HT action frame details */ -+#define ACTION_HT_NOTIFY_CHANNEL_WIDTH 0 /* Notify Channel Width */ -+#define ACTION_HT_SM_POWER_SAVE 1 /* SM Power Save */ -+#define ACTION_HT_PSMP 2 /* PSMP */ -+#define ACTION_HT_SET_PCO_PHASE 3 /* Set PCO Phase */ -+#define ACTION_HT_CSI 4 /* CSI */ -+#define ACTION_HT_NON_COMPRESSED_BEAMFORM 5 /* Non-compressed Beamforming */ -+#define ACTION_HT_COMPRESSED_BEAMFORM 6 /* Compressed Beamforming */ -+#define ACTION_HT_ANT_SEL_INDICES_FB 7 /* Antenna Selection Indices Feedback */ -+ -+/* 802.11v Wireless Network Management */ -+#define ACTION_WNM_TIMING_MEASUREMENT_REQUEST 27 -+ -+#define ACTION_UNPROTECTED_WNM_TIM 0 -+#define ACTION_UNPROTECTED_WNM_TIMING_MEASUREMENT 1 -+ -+#define ACTION_UNPROTECTED_WNM_TIMING_MEAS_LEN 12 -+ -+/* 3 --------------- WFA frame body fields --------------- */ -+#define VENDOR_OUI_WFA { 0x00, 0x50, 0xF2 } -+#define VENDOR_OUI_WFA_SPECIFIC { 0x50, 0x6F, 0x9A } -+#define VENDOR_OUI_TYPE_WPA 1 -+#define VENDOR_OUI_TYPE_WMM 2 -+#define VENDOR_OUI_TYPE_WPS 4 -+#define VENDOR_OUI_TYPE_P2P 9 -+#define VENDOR_OUI_TYPE_WFD 10 -+#define VENDOR_OUI_TYPE_HS20 16 -+ -+#define VENDOR_OUI_TYPE_LEN 4 /* Length of OUI and Type */ -+ -+/* VERSION(2 octets for WPA) / SUBTYPE(1 octet)-VERSION(1 octet) fields for WMM in WFA IE */ -+#define VERSION_WPA 0x0001 /* Little Endian Format */ -+#define VENDOR_OUI_SUBTYPE_VERSION_WMM_INFO 0x0100 -+#define VENDOR_OUI_SUBTYPE_VERSION_WMM_PARAM 0x0101 -+ -+/* SUBTYPE(1 octet) for WMM */ -+#define VENDOR_OUI_SUBTYPE_WMM_INFO 0x00 /* WMM Spec version 1.1 */ -+#define VENDOR_OUI_SUBTYPE_WMM_PARAM 0x01 -+#define VENDOR_OUI_SUBTYPE_WMM_TSPEC 0x02 -+ -+/* VERSION(1 octet) for WMM */ -+#define VERSION_WMM 0x01 /* WMM Spec version 1.1 */ -+ -+/* WMM-2.1.6 QoS Control Field */ -+#define WMM_QC_UP_MASK BITS(0, 2) -+#define WMM_QC_EOSP BIT(4) -+#define WMM_QC_ACK_POLICY_MASK BITS(5, 6) -+#define WMM_QC_ACK_POLICY_OFFSET 5 -+#define WMM_QC_ACK_POLICY_ACKNOWLEDGE 0 -+#define WMM_QC_ACK_POLICY_NOT_ACKNOWLEDGE (1 << WMM_QC_ACK_POLICY_OFFSET) -+ -+/* WMM-2.2.1 WMM Information Element */ -+#define ELEM_MIN_LEN_WFA_OUI_TYPE_SUBTYPE 6 -+ -+/* HOTSPOT 2.0 Indication IE*/ -+#define ELEM_MAX_LEN_HS20_INDICATION 5 -+#define ELEM_MIN_LEN_HS20_INDICATION 4 -+ -+/* Hotspot Configuration*/ -+#define ELEM_HS_CONFIG_DGAF_DISABLED_MASK BIT(0) /* Downstream Group-Addressed Forwarding */ -+ -+/* 3 Control frame body */ -+/* 7.2.1.7 BlockAckReq */ -+#define CTRL_BAR_BAR_CONTROL_OFFSET 16 -+#define CTRL_BAR_BAR_INFORMATION_OFFSET 18 -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+#if defined(WINDOWS_DDK) || defined(WINDOWS_CE) -+#pragma pack(1) -+#endif -+ -+typedef struct _LLC_SNAP_HEADER_T { -+ UINT_8 ucDSAP; -+ UINT_8 ucSSAP; -+ UINT_8 ucControl; -+ UINT_8 aucCode[3]; -+ UINT_16 u2Type; -+} __KAL_ATTRIB_PACKED__ LLC_SNAP_HEADER_T, *P_LLC_SNAP_HEADER_T; -+ -+/* 3 MAC Header. */ -+/* Ethernet Frame Header */ -+typedef struct _ETH_FRAME_HEADER_T { -+ UINT_8 aucDestAddr[MAC_ADDR_LEN]; -+ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; -+ UINT_16 u2TypeLen; -+} __KAL_ATTRIB_PACKED__ ETH_FRAME_HEADER_T, *P_ETH_FRAME_HEADER_T; -+ -+/* Ethernet Frame Structure */ -+typedef struct _ETH_FRAME_T { -+ UINT_8 aucDestAddr[MAC_ADDR_LEN]; -+ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; -+ UINT_16 u2TypeLen; -+ UINT_8 aucData[1]; -+} __KAL_ATTRIB_PACKED__ ETH_FRAME_T, *P_ETH_FRAME_T; -+ -+/* IEEE 802.11 WLAN Frame Structure */ -+/* WLAN MAC Header (without Address 4 and QoS Control fields) */ -+typedef struct _WLAN_MAC_HEADER_T { -+ UINT_16 u2FrameCtrl; -+ UINT_16 u2DurationID; -+ UINT_8 aucAddr1[MAC_ADDR_LEN]; -+ UINT_8 aucAddr2[MAC_ADDR_LEN]; -+ UINT_8 aucAddr3[MAC_ADDR_LEN]; -+ UINT_16 u2SeqCtrl; -+} __KAL_ATTRIB_PACKED__ WLAN_MAC_HEADER_T, *P_WLAN_MAC_HEADER_T; -+ -+/* WLAN MAC Header (QoS Control fields included) */ -+typedef struct _WLAN_MAC_HEADER_QOS_T { -+ UINT_16 u2FrameCtrl; -+ UINT_16 u2DurationID; -+ UINT_8 aucAddr1[MAC_ADDR_LEN]; -+ UINT_8 aucAddr2[MAC_ADDR_LEN]; -+ UINT_8 aucAddr3[MAC_ADDR_LEN]; -+ UINT_16 u2SeqCtrl; -+ UINT_16 u2QosCtrl; -+} __KAL_ATTRIB_PACKED__ WLAN_MAC_HEADER_QOS_T, *P_WLAN_MAC_HEADER_QOS_T; -+ -+/* WLAN MAC Header (HT Control fields included) */ -+typedef struct _WLAN_MAC_HEADER_HT_T { -+ UINT_16 u2FrameCtrl; -+ UINT_16 u2DurationID; -+ UINT_8 aucAddr1[MAC_ADDR_LEN]; -+ UINT_8 aucAddr2[MAC_ADDR_LEN]; -+ UINT_8 aucAddr3[MAC_ADDR_LEN]; -+ UINT_16 u2SeqCtrl; -+ UINT_16 u2QosCtrl; -+ UINT_32 u4HtCtrl; -+} __KAL_ATTRIB_PACKED__ WLAN_MAC_HEADER_HT_T, *P_WLAN_MAC_HEADER_HT_T; -+ -+/* WLAN MAC Header (Address 4 included) */ -+typedef struct _WLAN_MAC_HEADER_A4_T { -+ UINT_16 u2FrameCtrl; -+ UINT_16 u2DurationID; -+ UINT_8 aucAddr1[MAC_ADDR_LEN]; -+ UINT_8 aucAddr2[MAC_ADDR_LEN]; -+ UINT_8 aucAddr3[MAC_ADDR_LEN]; -+ UINT_16 u2SeqCtrl; -+ UINT_8 aucAddr4[MAC_ADDR_LEN]; -+} __KAL_ATTRIB_PACKED__ WLAN_MAC_HEADER_A4_T, *P_WLAN_MAC_HEADER_A4_T; -+ -+/* WLAN MAC Header (Address 4 and QoS Control fields included) */ -+typedef struct _WLAN_MAC_HEADER_A4_QOS_T { -+ UINT_16 u2FrameCtrl; -+ UINT_16 u2DurationID; -+ UINT_8 aucAddr1[MAC_ADDR_LEN]; -+ UINT_8 aucAddr2[MAC_ADDR_LEN]; -+ UINT_8 aucAddr3[MAC_ADDR_LEN]; -+ UINT_16 u2SeqCtrl; -+ UINT_8 aucAddr4[MAC_ADDR_LEN]; -+ UINT_16 u2QosCtrl; -+} __KAL_ATTRIB_PACKED__ WLAN_MAC_HEADER_A4_QOS_T, *P_WLAN_MAC_HEADER_A4_QOS_T; -+ -+typedef struct _WLAN_MAC_HEADER_A4_HT_T { -+ UINT_16 u2FrameCtrl; -+ UINT_16 u2DurationID; -+ UINT_8 aucAddr1[MAC_ADDR_LEN]; -+ UINT_8 aucAddr2[MAC_ADDR_LEN]; -+ UINT_8 aucAddr3[MAC_ADDR_LEN]; -+ UINT_16 u2SeqCtrl; -+ UINT_8 aucAddr4[MAC_ADDR_LEN]; -+ UINT_16 u2QosCtrl; -+ UINT_32 u4HtCtrl; -+} __KAL_ATTRIB_PACKED__ WLAN_MAC_HEADER_A4_HT_T, *P_WLAN_MAC_HEADER_A4_HT_T; -+ -+/* 7.2.3 WLAN MAC Header for Management Frame - MMPDU */ -+typedef struct _WLAN_MAC_MGMT_HEADER_T { -+ UINT_16 u2FrameCtrl; -+ UINT_16 u2Duration; -+ UINT_8 aucDestAddr[MAC_ADDR_LEN]; -+ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; -+ UINT_8 aucBSSID[MAC_ADDR_LEN]; -+ UINT_16 u2SeqCtrl; -+} __KAL_ATTRIB_PACKED__ WLAN_MAC_MGMT_HEADER_T, *P_WLAN_MAC_MGMT_HEADER_T; -+ -+/* WLAN MAC Header for Management Frame (HT Control fields included) */ -+typedef struct _WLAN_MAC_MGMT_HEADER_HT_T { -+ UINT_16 u2FrameCtrl; -+ UINT_16 u2DurationID; -+ UINT_8 aucAddr1[MAC_ADDR_LEN]; -+ UINT_8 aucAddr2[MAC_ADDR_LEN]; -+ UINT_8 aucAddr3[MAC_ADDR_LEN]; -+ UINT_16 u2SeqCtrl; -+ UINT_32 u4HtCtrl; -+} __KAL_ATTRIB_PACKED__ WLAN_MAC_MGMT_HEADER_HT_T, *P_WLAN_MAC_MGMT_HEADER_HT_T; -+ -+/* 3 WLAN CONTROL Frame */ -+/* 7.2.1.4 WLAN Control Frame - PS-POLL Frame */ -+typedef struct _CTRL_PSPOLL_FRAME_T { -+ UINT_16 u2FrameCtrl; /* Frame Control */ -+ UINT_16 u2AID; /* AID */ -+ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ -+ UINT_8 aucTA[MAC_ADDR_LEN]; /* TA */ -+} __KAL_ATTRIB_PACKED__ CTRL_PSPOLL_FRAME_T, *P_CTRL_PSPOLL_FRAME_T; -+ -+/* BAR */ -+typedef struct _CTRL_BAR_FRAME_T { -+ UINT_16 u2FrameCtrl; /* Frame Control */ -+ UINT_16 u2DurationID; /* Duration */ -+ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* RA */ -+ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* TA */ -+ UINT_16 u2BarControl; -+ UINT_8 aucBarInfo[2]; /* Variable size */ -+} __KAL_ATTRIB_PACKED__ CTRL_BAR_FRAME_T, *P_CTRL_BAR_FRAME_T; -+ -+/* 3 WLAN Management Frame. */ -+/* 7.2.3.1 WLAN Management Frame - Beacon Frame */ -+typedef struct _WLAN_BEACON_FRAME_T { -+ /* Beacon header */ -+ UINT_16 u2FrameCtrl; /* Frame Control */ -+ UINT_16 u2DurationID; /* Duration */ -+ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ -+ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ -+ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ -+ UINT_16 u2SeqCtrl; /* Sequence Control */ -+ /* Beacon frame body */ -+ UINT_32 au4Timestamp[2]; /* Timestamp */ -+ UINT_16 u2BeaconInterval; /* Beacon Interval */ -+ UINT_16 u2CapInfo; /* Capability */ -+ UINT_8 aucInfoElem[1]; /* Various IEs, start from SSID */ -+} __KAL_ATTRIB_PACKED__ WLAN_BEACON_FRAME_T, *P_WLAN_BEACON_FRAME_T; -+ -+typedef struct _WLAN_BEACON_FRAME_BODY_T { -+ /* Beacon frame body */ -+ UINT_32 au4Timestamp[2]; /* Timestamp */ -+ UINT_16 u2BeaconInterval; /* Beacon Interval */ -+ UINT_16 u2CapInfo; /* Capability */ -+ UINT_8 aucInfoElem[1]; /* Various IEs, start from SSID */ -+} __KAL_ATTRIB_PACKED__ WLAN_BEACON_FRAME_BODY_T, *P_WLAN_BEACON_FRAME_BODY_T; -+ -+/* 7.2.3.3 WLAN Management Frame - Disassociation Frame */ -+typedef struct _WLAN_DISASSOC_FRAME_T { -+ /* Authentication MAC header */ -+ UINT_16 u2FrameCtrl; /* Frame Control */ -+ UINT_16 u2DurationID; /* Duration */ -+ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ -+ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ -+ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ -+ UINT_16 u2SeqCtrl; /* Sequence Control */ -+ /* Disassociation frame body */ -+ UINT_16 u2ReasonCode; /* Reason code */ -+ UINT_8 aucInfoElem[1]; /* Various IEs, possible no. */ -+} __KAL_ATTRIB_PACKED__ WLAN_DISASSOC_FRAME_T, *P_WLAN_DISASSOC_FRAME_T; -+ -+/* 7.2.3.4 WLAN Management Frame - Association Request frame */ -+typedef struct _WLAN_ASSOC_REQ_FRAME_T { -+ /* Association Request MAC header */ -+ UINT_16 u2FrameCtrl; /* Frame Control */ -+ UINT_16 u2DurationID; /* Duration */ -+ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ -+ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ -+ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ -+ UINT_16 u2SeqCtrl; /* Sequence Control */ -+ /* Association Request frame body */ -+ UINT_16 u2CapInfo; /* Capability information */ -+ UINT_16 u2ListenInterval; /* Listen interval */ -+ UINT_8 aucInfoElem[1]; /* Information elements, include WPA IE */ -+} __KAL_ATTRIB_PACKED__ WLAN_ASSOC_REQ_FRAME_T, *P_WLAN_ASSOC_REQ_FRAME_T; -+ -+/* 7.2.3.5 WLAN Management Frame - Association Response frame */ -+typedef struct _WLAN_ASSOC_RSP_FRAME_T { -+ /* Association Response MAC header */ -+ UINT_16 u2FrameCtrl; /* Frame Control */ -+ UINT_16 u2DurationID; /* Duration */ -+ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ -+ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ -+ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ -+ UINT_16 u2SeqCtrl; /* Sequence Control */ -+ /* Association Response frame body */ -+ UINT_16 u2CapInfo; /* Capability information */ -+ UINT_16 u2StatusCode; /* Status code */ -+ UINT_16 u2AssocId; /* Association ID */ -+ UINT_8 aucInfoElem[1]; /* Information elements, such as -+ supported rates, and etc. */ -+} __KAL_ATTRIB_PACKED__ WLAN_ASSOC_RSP_FRAME_T, *P_WLAN_ASSOC_RSP_FRAME_T; -+ -+/* 7.2.3.6 WLAN Management Frame - Reassociation Request frame */ -+typedef struct _WLAN_REASSOC_REQ_FRAME_T { -+ /* Reassociation Request MAC header */ -+ UINT_16 u2FrameCtrl; /* Frame Control */ -+ UINT_16 u2DurationID; /* Duration */ -+ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ -+ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ -+ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ -+ UINT_16 u2SeqCtrl; /* Sequence Control */ -+ /* Reassociation Request frame body */ -+ UINT_16 u2CapInfo; /* Capability information */ -+ UINT_16 u2ListenInterval; /* Listen interval */ -+ UINT_8 aucCurrentAPAddr[MAC_ADDR_LEN]; /* Current AP address */ -+ UINT_8 aucInfoElem[1]; /* Information elements, include WPA IE */ -+} __KAL_ATTRIB_PACKED__ WLAN_REASSOC_REQ_FRAME_T, *P_WLAN_REASSOC_REQ_FRAME_T; -+ -+/* 7.2.3.7 WLAN Management Frame - Reassociation Response frame -+ (the same as Association Response frame) */ -+typedef WLAN_ASSOC_RSP_FRAME_T WLAN_REASSOC_RSP_FRAME_T, *P_WLAN_REASSOC_RSP_FRAME_T; -+ -+/* 7.2.3.9 WLAN Management Frame - Probe Response Frame */ -+typedef WLAN_BEACON_FRAME_T WLAN_PROBE_RSP_FRAME_T, *P_WLAN_PROBE_RSP_FRAME_T; -+ -+/* 7.2.3.10 WLAN Management Frame - Authentication Frame */ -+typedef struct _WLAN_AUTH_FRAME_T { -+ /* Authentication MAC header */ -+ UINT_16 u2FrameCtrl; /* Frame Control */ -+ UINT_16 u2DurationID; /* Duration */ -+ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ -+ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ -+ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ -+ UINT_16 u2SeqCtrl; /* Sequence Control */ -+ /* Authentication frame body */ -+ UINT_16 u2AuthAlgNum; /* Authentication algorithm number */ -+ UINT_16 u2AuthTransSeqNo; /* Authentication transaction sequence number */ -+ UINT_16 u2StatusCode; /* Status code */ -+ UINT_8 aucInfoElem[1]; /* Various IEs for Fast BSS Transition */ -+} __KAL_ATTRIB_PACKED__ WLAN_AUTH_FRAME_T, *P_WLAN_AUTH_FRAME_T; -+ -+/* 7.2.3.11 WLAN Management Frame - Deauthentication Frame */ -+typedef struct _WLAN_DEAUTH_FRAME_T { -+ /* Authentication MAC header */ -+ UINT_16 u2FrameCtrl; /* Frame Control */ -+ UINT_16 u2DurationID; /* Duration */ -+ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ -+ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ -+ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ -+ UINT_16 u2SeqCtrl; /* Sequence Control */ -+ /* Deauthentication frame body */ -+ UINT_16 u2ReasonCode; /* Reason code */ -+ UINT_8 aucInfoElem[1]; /* Various IEs, possible no. */ -+} __KAL_ATTRIB_PACKED__ WLAN_DEAUTH_FRAME_T, *P_WLAN_DEAUTH_FRAME_T; -+ -+/* 3 Information Elements. */ -+/* 7.3.2 Generic element format */ -+typedef struct _IE_HDR_T { -+ UINT_8 ucId; -+ UINT_8 ucLength; -+ UINT_8 aucInfo[1]; -+} __KAL_ATTRIB_PACKED__ IE_HDR_T, *P_IE_HDR_T; -+ -+/* 7.3.2.1 SSID element */ -+typedef struct _IE_SSID_T { -+ UINT_8 ucId; -+ UINT_8 ucLength; -+ UINT_8 aucSSID[ELEM_MAX_LEN_SSID]; -+} __KAL_ATTRIB_PACKED__ IE_SSID_T, *P_IE_SSID_T; -+ -+/* 7.3.2.2 Supported Rates element */ -+typedef struct _IE_SUPPORTED_RATE_T { -+ UINT_8 ucId; -+ UINT_8 ucLength; -+ UINT_8 aucSupportedRates[ELEM_MAX_LEN_SUP_RATES]; -+} __KAL_ATTRIB_PACKED__ IE_SUPPORTED_RATE_T, *P_IE_SUPPORTED_RATE_T; -+ -+/* 7.3.2.4 DS Parameter Set element */ -+typedef struct _IE_DS_PARAM_SET_T { -+ UINT_8 ucId; -+ UINT_8 ucLength; -+ UINT_8 ucCurrChnl; -+} __KAL_ATTRIB_PACKED__ IE_DS_PARAM_SET_T, *P_IE_DS_PARAM_SET_T; -+ -+/* 7.3.2.5 CF Parameter Set element */ -+typedef struct _IE_CF_PARAM_SET_T { -+ UINT_8 ucId; -+ UINT_8 ucLength; -+ UINT_8 ucCFPCount; -+ UINT_8 ucCFPPeriod; -+ UINT_16 u2CFPMaxDur; -+ UINT_16 u2DurRemaining; -+} __KAL_ATTRIB_PACKED__ IE_CF_PARAM_SET_T, *P_IE_CF_PARAM_SET_T; -+ -+/* 7.3.2.6 TIM */ -+typedef struct _IE_TIM_T { -+ UINT_8 ucId; -+ UINT_8 ucLength; -+ UINT_8 ucDTIMCount; -+ UINT_8 ucDTIMPeriod; -+ UINT_8 ucBitmapControl; -+ UINT_8 aucPartialVirtualMap[1]; -+} __KAL_ATTRIB_PACKED__ IE_TIM_T, *P_IE_TIM_T; -+ -+/* 7.3.2.7 IBSS Parameter Set element */ -+typedef struct _IE_IBSS_PARAM_SET_T { -+ UINT_8 ucId; -+ UINT_8 ucLength; -+ UINT_16 u2ATIMWindow; -+} __KAL_ATTRIB_PACKED__ IE_IBSS_PARAM_SET_T, *P_IE_IBSS_PARAM_SET_T; -+ -+/* 7.3.2.8 Challenge Text element */ -+typedef struct _IE_CHALLENGE_TEXT_T { -+ UINT_8 ucId; -+ UINT_8 ucLength; -+ UINT_8 aucChallengeText[ELEM_MAX_LEN_CHALLENGE_TEXT]; -+} __KAL_ATTRIB_PACKED__ IE_CHALLENGE_TEXT_T, *P_IE_CHALLENGE_TEXT_T; -+ -+/* 7.3.2.9 Country information element */ -+#if CFG_SUPPORT_802_11D -+/*! \brief COUNTRY_INFO_TRIPLET is defined for the COUNTRY_INFO_ELEM structure. */ -+typedef struct _COUNTRY_INFO_TRIPLET_T { -+ UINT_8 ucParam1; /*!< If param1 >= 201, this triplet is referred to as -+ Regulatory Triplet in 802_11J. */ -+ UINT_8 ucParam2; -+ UINT_8 ucParam3; -+} __KAL_ATTRIB_PACKED__ COUNTRY_INFO_TRIPLET_T, *P_COUNTRY_INFO_TRIPLET_T; -+ -+typedef struct _COUNTRY_INFO_SUBBAND_TRIPLET_T { -+ UINT_8 ucFirstChnlNum; /*!< First Channel Number */ -+ UINT_8 ucNumOfChnl; /*!< Number of Channels */ -+ INT_8 cMaxTxPwrLv; /*!< Maximum Transmit Power Level */ -+} __KAL_ATTRIB_PACKED__ COUNTRY_INFO_SUBBAND_TRIPLET_T, *P_COUNTRY_INFO_SUBBAND_TRIPLET_T; -+ -+typedef struct _COUNTRY_INFO_REGULATORY_TRIPLET_T { -+ UINT_8 ucRegExtId; /*!< Regulatory Extension Identifier, should -+ be greater than or equal to 201 */ -+ UINT_8 ucRegClass; /*!< Regulatory Class */ -+ UINT_8 ucCoverageClass; /*!< Coverage Class, unsigned 1-octet value 0~31 -+ , 32~255 reserved */ -+} __KAL_ATTRIB_PACKED__ COUNTRY_INFO_REGULATORY_TRIPLET_T, *P_COUNTRY_INFO_REGULATORY_TRIPLET_T; -+ -+typedef struct _IE_COUNTRY_T { -+ UINT_8 ucId; -+ UINT_8 ucLength; -+ UINT_8 aucCountryStr[3]; -+ COUNTRY_INFO_SUBBAND_TRIPLET_T arCountryStr[1]; -+} __KAL_ATTRIB_PACKED__ IE_COUNTRY_T, *P_IE_COUNTRY_T; -+#endif /* CFG_SUPPORT_802_11D */ -+ -+/* 7.3.2.13 ERP element */ -+typedef struct _IE_ERP_T { -+ UINT_8 ucId; -+ UINT_8 ucLength; -+ UINT_8 ucERP; -+} __KAL_ATTRIB_PACKED__ IE_ERP_T, *P_IE_ERP_T; -+ -+/* 7.3.2.14 Extended Supported Rates element */ -+typedef struct _IE_EXT_SUPPORTED_RATE_T { -+ UINT_8 ucId; -+ UINT_8 ucLength; -+ UINT_8 aucExtSupportedRates[ELEM_MAX_LEN_EXTENDED_SUP_RATES]; -+} __KAL_ATTRIB_PACKED__ IE_EXT_SUPPORTED_RATE_T, *P_IE_EXT_SUPPORTED_RATE_T; -+ -+/* 7.3.2.15 Power Constraint element */ -+typedef struct _IE_POWER_CONSTRAINT_T { -+ UINT_8 ucId; -+ UINT_8 ucLength; -+ UINT_8 ucLocalPowerConstraint; /* Unit: dBm */ -+} __KAL_ATTRIB_PACKED__ IE_POWER_CONSTRAINT_T, *P_IE_POWER_CONSTRAINT_T; -+ -+/* 7.3.2.16 Power Capability element */ -+typedef struct _IE_POWER_CAP_T { -+ UINT_8 ucId; -+ UINT_8 ucLength; -+ INT_8 cMinTxPowerCap; /* Unit: dBm */ -+ INT_8 cMaxTxPowerCap; /* Unit: dBm */ -+} __KAL_ATTRIB_PACKED__ IE_POWER_CAP_T, *P_IE_POWER_CAP_T; -+ -+/* 7.3.2.17 TPC request element */ -+typedef struct _IE_TPC_REQ_T { -+ UINT_8 ucId; -+ UINT_8 ucLength; -+} __KAL_ATTRIB_PACKED__ IE_TPC_REQ_T, *P_IE_TPC_REQ_T; -+ -+/* 7.3.2.18 TPC report element */ -+typedef struct _IE_TPC_REPORT_T { -+ UINT_8 ucId; -+ UINT_8 ucLength; -+ INT_8 cTxPower; /* Unit: dBm */ -+ INT_8 cLinkMargin; /* Unit: dB */ -+} __KAL_ATTRIB_PACKED__ IE_TPC_REPORT_T, *P_IE_TPC_REPORT_T; -+ -+#if CFG_SUPPORT_DFS /* Add by Enlai */ -+/* 7.3.2.19 Supported Channels element*/ -+typedef struct _IE_SUPPORTED_CHANNELS_T { -+ UINT_8 ucId; -+ UINT_8 ucLength; -+ UINT_8 ucChannelNum[ELEM_MAX_LEN_SUPPORTED_CHANNELS * 2]; -+} __KAL_ATTRIB_PACKED__ IE_SUPPORTED_CHANNELS_T, *P_IE_SUPPORTED_CHANNELS_T; -+ -+/* 7.3.2.20 Channel Switch Announcement element*/ -+typedef struct _IE_CHANNEL_SWITCH_T { -+ UINT_8 ucId; -+ UINT_8 ucLength; -+ UINT_8 ucChannelSwitchMode; -+ UINT_8 ucNewChannelNum; -+ UINT_8 ucChannelSwitchCount; -+} __KAL_ATTRIB_PACKED__ IE_CHANNEL_SWITCH_T, *P_IE_CHANNEL_SWITCH_T; -+#endif -+ -+/* 7.3.2.21 Measurement Request element */ -+typedef struct _IE_MEASUREMENT_REQ_T { -+ UINT_8 ucId; -+ UINT_8 ucLength; -+ UINT_8 ucToken; -+ UINT_8 ucRequestMode; -+ UINT_8 ucMeasurementType; -+ UINT_8 aucRequestFields[1]; -+} __KAL_ATTRIB_PACKED__ IE_MEASUREMENT_REQ_T, *P_IE_MEASUREMENT_REQ_T; -+ -+typedef struct _SM_BASIC_REQ_T { -+ UINT_8 ucChannel; -+ UINT_32 au4StartTime[2]; -+ UINT_16 u2Duration; -+} __KAL_ATTRIB_PACKED__ SM_BASIC_REQ_T, *P_SM_BASIC_REQ_T; -+ -+/* SM_COMMON_REQ_T is not specified in Spec. Use it as common structure of SM */ -+typedef SM_BASIC_REQ_T SM_REQ_COMMON_T, *P_SM_REQ_COMMON_T; -+typedef SM_BASIC_REQ_T SM_CCA_REQ_T, *P_SM_CCA_REQ_T; -+typedef SM_BASIC_REQ_T SM_RPI_HISTOGRAM_REQ_T, *P_SM_RPI_HISTOGRAM_REQ_T; -+ -+typedef struct _RM_CHNL_LOAD_REQ_T { -+ UINT_8 ucRegulatoryClass; -+ UINT_8 ucChannel; -+ UINT_16 u2RandomInterval; -+ UINT_16 u2Duration; -+ UINT_8 aucSubElements[1]; -+} __KAL_ATTRIB_PACKED__ RM_CHNL_LOAD_REQ_T, *P_RM_CHNL_LOAD_REQ_T; -+ -+typedef RM_CHNL_LOAD_REQ_T RM_NOISE_HISTOGRAM_REQ_T, *P_RM_NOISE_HISTOGRAM_REQ_T; -+ -+typedef struct _RM_BCN_REQ_T { -+ UINT_8 ucRegulatoryClass; -+ UINT_8 ucChannel; -+ UINT_16 u2RandomInterval; -+ UINT_16 u2Duration; -+ UINT_8 ucMeasurementMode; -+ UINT_8 aucBssid[6]; -+ UINT_8 aucSubElements[1]; -+} __KAL_ATTRIB_PACKED__ RM_BCN_REQ_T, *P_RM_BCN_REQ_T; -+ -+typedef struct _RM_FRAME_REQ_T { -+ UINT_8 ucRegulatoryClass; -+ UINT_8 ucChannel; -+ UINT_16 u2RandomInterval; -+ UINT_16 u2Duration; -+ UINT_8 ucFrameReqType; -+ UINT_8 aucMacAddr[6]; -+ UINT_8 aucSubElements[1]; -+} __KAL_ATTRIB_PACKED__ RM_FRAME_REQ_T, *P_RM_FRAME_REQ_T; -+ -+typedef struct _RM_STA_STATS_REQ_T { -+ UINT_8 aucPeerMacAddr[6]; -+ UINT_16 u2RandomInterval; -+ UINT_16 u2Duration; -+ UINT_8 ucGroupID; -+ UINT_8 aucSubElements[1]; -+} __KAL_ATTRIB_PACKED__ RM_STA_STATS_REQ_T, *P_RM_STA_STATS_REQ_T; -+ -+typedef struct _RM_LCI_REQ_T { -+ UINT_8 ucLocationSubject; -+ UINT_8 ucLatitudeResolution; -+ UINT_8 ucLongitudeResolution; -+ UINT_8 ucAltitudeResolution; -+ UINT_8 aucSubElements[1]; -+} __KAL_ATTRIB_PACKED__ RM_LCI_REQ_T, *P_RM_LCI_REQ_T; -+ -+typedef struct _RM_TS_MEASURE_REQ_T { -+ UINT_16 u2RandomInterval; -+ UINT_16 u2Duration; -+ UINT_8 aucPeerStaAddr[6]; -+ UINT_8 ucTrafficID; -+ UINT_8 ucBin0Range; -+ UINT_8 aucSubElements[1]; -+} __KAL_ATTRIB_PACKED__ RM_TS_MEASURE_REQ_T, *P_RM_TS_MEASURE_REQ_T; -+ -+typedef struct _RM_MEASURE_PAUSE_REQ_T { -+ UINT_16 u2PauseTime; -+ UINT_8 aucSubElements[1]; -+} __KAL_ATTRIB_PACKED__ RM_MEASURE_PAUSE_REQ_T, *P_RM_MEASURE_PAUSE_REQ_T; -+ -+/* 7.3.2.22 Measurement Report element */ -+typedef struct _IE_MEASUREMENT_REPORT_T { -+ UINT_8 ucId; -+ UINT_8 ucLength; -+ UINT_8 ucToken; -+ UINT_8 ucReportMode; -+ UINT_8 ucMeasurementType; -+ UINT_8 aucReportFields[1]; -+} __KAL_ATTRIB_PACKED__ IE_MEASUREMENT_REPORT_T, *P_IE_MEASUREMENT_REPORT_T; -+ -+typedef struct _SM_BASIC_REPORT_T { -+ UINT_8 ucChannel; -+ UINT_32 u4StartTime[2]; -+ UINT_16 u2Duration; -+ UINT_8 ucMap; -+} __KAL_ATTRIB_PACKED__ SM_BASIC_REPORT_T, *P_SM_BASIC_REPORT_T; -+ -+typedef struct _SM_CCA_REPORT_T { -+ UINT_8 ucChannel; -+ UINT_32 u4StartTime[2]; -+ UINT_16 u2Duration; -+ UINT_8 ucCcaBusyFraction; -+} __KAL_ATTRIB_PACKED__ SM_CCA_REPORT_T, *P_SM_CCA_REPORT_T; -+ -+typedef struct _SM_RPI_REPORT_T { -+ UINT_8 ucChannel; -+ UINT_32 u4StartTime[2]; -+ UINT_16 u2Duration; -+ UINT_8 aucRPI[8]; -+} __KAL_ATTRIB_PACKED__ SM_RPI_REPORT_T, *P_SM_RPI_REPORT_T; -+ -+typedef struct _RM_CHNL_LOAD_REPORT_T { -+ UINT_8 ucRegulatoryClass; -+ UINT_8 ucChannel; -+ UINT_32 u4StartTime[2]; -+ UINT_16 u2Duration; -+ UINT_8 ucChnlLoad; -+} __KAL_ATTRIB_PACKED__ RM_CHNL_LOAD_REPORT_T, *P_RM_CHNL_LOAD_REPORT_T; -+ -+typedef struct _RM_IPI_REPORT_T { -+ UINT_8 ucRegulatoryClass; -+ UINT_8 ucChannel; -+ UINT_32 u4StartTime[2]; -+ UINT_16 u2Duration; -+ UINT_8 ucAntennaId; -+ INT_8 cANPI; -+ UINT_8 aucIPI[11]; -+} __KAL_ATTRIB_PACKED__ RM_IPI_REPORT_T, *P_RM_IPI_REPORT_T; -+ -+/* 7.3.2.23 Quiet element */ -+typedef struct _IE_QUIET_T { -+ UINT_8 ucId; -+ UINT_8 ucLength; -+ UINT_8 ucCount; -+ UINT_8 ucPeriod; -+ UINT_16 u2Duration; -+ UINT_16 u2Offset; -+} __KAL_ATTRIB_PACKED__ IE_QUIET_T, *P_IE_QUIET_T; -+ -+/* 7.3.2.27 Extended Capabilities element */ -+typedef struct _IE_EXT_CAP_T { -+ UINT_8 ucId; -+ UINT_8 ucLength; -+ UINT_8 aucCapabilities[5]; -+} __KAL_ATTRIB_PACKED__ IE_EXT_CAP_T, *P_EXT_CAP_T; -+ -+/* 7.3.2.27 hs20 Extended Capabilities element */ -+typedef struct _IE_HS20_EXT_CAP_T { -+ UINT_8 ucId; -+ UINT_8 ucLength; -+ UINT_8 aucCapabilities[6]; -+} __KAL_ATTRIB_PACKED__ IE_HS20_EXT_CAP_T, *P_HS20_EXT_CAP_T; -+ -+ -+/* 7.3.2.27 Extended Capabilities element */ -+typedef struct _IE_RRM_ENABLED_CAP_T { -+ UINT_8 ucId; -+ UINT_8 ucLength; -+ UINT_8 aucCap[5]; -+} __KAL_ATTRIB_PACKED__ IE_RRM_ENABLED_CAP_T, *P_IE_RRM_ENABLED_CAP_T; -+ -+/* 7.3.2.51 Timeout Interval element (TIE) */ -+typedef struct _IE_TIMEOUT_INTERVAL_T { -+ UINT_8 ucId; -+ UINT_8 ucLength; -+#define IE_TIMEOUT_INTERVAL_TYPE_RESERVED 0 -+#define IE_TIMEOUT_INTERVAL_TYPE_REASSOC 1 -+#define IE_TIMEOUT_INTERVAL_TYPE_KEY_LIFETIME 2 -+#define IE_TIMEOUT_INTERVAL_TYPE_ASSOC_COMEBACK 3 -+ UINT_8 ucType; -+ UINT_32 u4Value; -+} __KAL_ATTRIB_PACKED__ IE_TIMEOUT_INTERVAL_T; -+ -+/* 7.3.2.56 HT Capabilities element */ -+typedef struct _SUP_MCS_SET_FIELD { -+ UINT_8 aucRxMcsBitmask[SUP_MCS_RX_BITMASK_OCTET_NUM]; -+ UINT_16 u2RxHighestSupportedRate; -+ UINT_32 u4TxRateInfo; -+} __KAL_ATTRIB_PACKED__ SUP_MCS_SET_FIELD, *P_SUP_MCS_SET_FIELD; -+ -+typedef struct _IE_HT_CAP_T { -+ UINT_8 ucId; -+ UINT_8 ucLength; -+ UINT_16 u2HtCapInfo; -+ UINT_8 ucAmpduParam; -+ SUP_MCS_SET_FIELD rSupMcsSet; -+ UINT_16 u2HtExtendedCap; -+ UINT_32 u4TxBeamformingCap; -+ UINT_8 ucAselCap; -+} __KAL_ATTRIB_PACKED__ IE_HT_CAP_T, *P_IE_HT_CAP_T; -+ -+/* 7.3.2.57 HT Operation element */ -+typedef struct _IE_HT_OP_T { -+ UINT_8 ucId; -+ UINT_8 ucLength; -+ UINT_8 ucPrimaryChannel; -+ UINT_8 ucInfo1; -+ UINT_16 u2Info2; -+ UINT_16 u2Info3; -+ UINT_8 aucBasicMcsSet[16]; -+} __KAL_ATTRIB_PACKED__ IE_HT_OP_T, *P_IE_HT_OP_T; -+ -+/* 7.3.2.25 RSN Information element format */ -+typedef struct _RSN_INFO_ELEM_T { -+ UCHAR ucElemId; -+ UCHAR ucLength; -+ UINT_16 u2Version; -+ UINT_32 u4GroupKeyCipherSuite; -+ UINT_16 u2PairwiseKeyCipherSuiteCount; -+ UCHAR aucPairwiseKeyCipherSuite1[4]; -+} __KAL_ATTRIB_PACKED__ RSN_INFO_ELEM_T, *P_RSN_INFO_ELEM_T; -+ -+/* 7.3.2.26 WPA Information element format */ -+typedef struct _WPA_INFO_ELEM_T { -+ UCHAR ucElemId; -+ UCHAR ucLength; -+ UCHAR aucOui[3]; -+ UCHAR ucOuiType; -+ UINT_16 u2Version; -+ UINT_32 u4GroupKeyCipherSuite; -+ UINT_16 u2PairwiseKeyCipherSuiteCount; -+ UCHAR aucPairwiseKeyCipherSuite1[4]; -+} __KAL_ATTRIB_PACKED__ WPA_INFO_ELEM_T, *P_WPA_INFO_ELEM_T; -+ -+/* 7.3.2.58 20/40 BSS Intolerant Channel Report element */ -+typedef struct _IE_INTOLERANT_CHNL_REPORT_T { -+ UINT_8 ucId; -+ UINT_8 ucLength; -+ UINT_8 ucRegulatoryClass; -+ UINT_8 aucChannelList[1]; -+} __KAL_ATTRIB_PACKED__ IE_INTOLERANT_CHNL_REPORT_T, *P_IE_INTOLERANT_CHNL_REPORT_T; -+ -+/* 7.3.2.59 OBSS Scan Parameters element */ -+typedef struct _IE_OBSS_SCAN_PARAM_T { -+ UINT_8 ucId; -+ UINT_8 ucLength; -+ UINT_16 u2ScanPassiveDwell; -+ UINT_16 u2ScanActiveDwell; -+ UINT_16 u2TriggerScanInterval; -+ UINT_16 u2ScanPassiveTotalPerChnl; -+ UINT_16 u2ScanActiveTotalPerChnl; -+ UINT_16 u2WidthTransDelayFactor; -+ UINT_16 u2ScanActivityThres; -+} __KAL_ATTRIB_PACKED__ IE_OBSS_SCAN_PARAM_T, *P_IE_OBSS_SCAN_PARAM_T; -+ -+/* 7.3.2.60 20/40 BSS Coexistence element */ -+typedef struct _IE_20_40_COEXIST_T { -+ UINT_8 ucId; -+ UINT_8 ucLength; -+ UINT_8 ucData; -+} __KAL_ATTRIB_PACKED__ IE_20_40_COEXIST_T, *P_IE_20_40_COEXIST_T; -+ -+/* 7.3.2.60 20/40 BSS Coexistence element */ -+typedef struct _IE_SUP_OPERATING_CLASS_T { -+ UINT_8 ucId; -+ UINT_8 ucLength; -+ UINT_8 ucCur; -+ UINT_8 ucSup[255]; -+} __KAL_ATTRIB_PACKED__ IE_SUP_OPERATING_CLASS_T, *P_IE_SUP_OPERATING_CLASS_T; -+ -+/* 3 7.4 Action Frame. */ -+/* 7.4 Action frame format */ -+typedef struct _WLAN_ACTION_FRAME { -+ /* Action MAC header */ -+ UINT_16 u2FrameCtrl; /* Frame Control */ -+ UINT_16 u2DurationID; /* Duration */ -+ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ -+ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ -+ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ -+ UINT_16 u2SeqCtrl; /* Sequence Control */ -+ /* Action frame body */ -+ UINT_8 ucCategory; /* Category */ -+ UINT_8 ucAction; /* Action Value */ -+ UINT_8 ucActionDetails[1]; /* Action details */ -+} __KAL_ATTRIB_PACKED__ WLAN_ACTION_FRAME, *P_WLAN_ACTION_FRAME; -+ -+/* 7.4.1.1 Spectrum Measurement Request frame format */ -+typedef struct _ACTION_SM_REQ_FRAME { -+ /* ADDTS Request MAC header */ -+ UINT_16 u2FrameCtrl; /* Frame Control */ -+ UINT_16 u2Duration; /* Duration */ -+ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ -+ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ -+ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ -+ UINT_16 u2SeqCtrl; /* Sequence Control */ -+ /* ADDTS Request frame body */ -+ UINT_8 ucCategory; /* Category */ -+ UINT_8 ucAction; /* Action Value */ -+ UINT_8 ucDialogToken; /* Dialog Token */ -+ UINT_8 aucInfoElem[1]; /* Information elements */ -+} __KAL_ATTRIB_PACKED__ ACTION_SM_REQ_FRAME, *P_ACTION_SM_REQ_FRAME; -+ -+/* 7.4.1.2 Spectrum Measurement Report frame format */ -+typedef ACTION_SM_REQ_FRAME ACTION_SM_REPORT_FRAME, *P_ACTION_SM_REPORT_FRAME; -+ -+/* 7.4.1.5 Channel Switch Announcement frame format */ -+typedef struct _ACTION_CHANNEL_SWITCH_FRAME { -+ /* ADDTS Request MAC header */ -+ UINT_16 u2FrameCtrl; /* Frame Control */ -+ UINT_16 u2Duration; /* Duration */ -+ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ -+ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ -+ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ -+ UINT_16 u2SeqCtrl; /* Sequence Control */ -+ /* ADDTS Request frame body */ -+ UINT_8 ucCategory; /* Category */ -+ UINT_8 ucAction; /* Action Value */ -+ UINT_8 aucInfoElem[5]; /* Information elements */ -+} __KAL_ATTRIB_PACKED__ _ACTION_CHANNEL_SWITCH_FRAME, *P_ACTION_CHANNEL_SWITCH_FRAME; -+ -+/* 7.4.2.1 ADDTS Request frame format */ -+typedef struct _ACTION_ADDTS_REQ_FRAME { -+ /* ADDTS Request MAC header */ -+ UINT_16 u2FrameCtrl; /* Frame Control */ -+ UINT_16 u2Duration; /* Duration */ -+ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ -+ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ -+ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ -+ UINT_16 u2SeqCtrl; /* Sequence Control */ -+ /* ADDTS Request frame body */ -+ UINT_8 ucCategory; /* Category */ -+ UINT_8 ucAction; /* Action Value */ -+ UINT_8 ucDialogToken; /* Dialog Token */ -+ UINT_8 aucInfoElem[1]; /* Information elements, such as -+ TS Delay, and etc. */ -+} __KAL_ATTRIB_PACKED__ ACTION_ADDTS_REQ_FRAME, *P_ACTION_ADDTS_REQ_FRAME; -+ -+/* 7.4.2.2 ADDTS Response frame format */ -+typedef struct _ACTION_ADDTS_RSP_FRAME { -+ /* ADDTS Response MAC header */ -+ UINT_16 u2FrameCtrl; /* Frame Control */ -+ UINT_16 u2Duration; /* Duration */ -+ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ -+ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ -+ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ -+ UINT_16 u2SeqCtrl; /* Sequence Control */ -+ /* ADDTS Response frame body */ -+ UINT_8 ucCategory; /* Category */ -+ UINT_8 ucAction; /* Action Value */ -+ UINT_8 ucDialogToken; /* Dialog Token */ -+ UINT_8 ucStatusCode; /* WMM Status Code is of one byte */ -+ UINT_8 aucInfoElem[1]; /* Information elements, such as -+ TS Delay, and etc. */ -+} __KAL_ATTRIB_PACKED__ ACTION_ADDTS_RSP_FRAME, *P_ACTION_ADDTS_RSP_FRAME; -+ -+/* 7.4.2.3 DELTS frame format */ -+typedef struct _ACTION_DELTS_FRAME { -+ /* DELTS MAC header */ -+ UINT_16 u2FrameCtrl; /* Frame Control */ -+ UINT_16 u2DurationID; /* Duration */ -+ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ -+ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ -+ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ -+ UINT_16 u2SeqCtrl; /* Sequence Control */ -+ /* DELTS frame body */ -+ UINT_8 ucCategory; /* Category */ -+ UINT_8 ucAction; /* Action Value */ -+ UINT_8 aucTsInfo[3]; /* TS Info */ -+} __KAL_ATTRIB_PACKED__ ACTION_DELTS_FRAME, *P_ACTION_DELTS_FRAME; -+ -+/* 7.4.4.1 ADDBA Request frame format */ -+typedef struct _ACTION_ADDBA_REQ_FRAME_T { -+ /* Action MAC header */ -+ UINT_16 u2FrameCtrl; /* Frame Control */ -+ UINT_16 u2DurationID; /* Duration */ -+ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ -+ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ -+ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ -+ UINT_16 u2SeqCtrl; /* Sequence Control */ -+ /* Action frame body */ -+ UINT_8 ucCategory; /* Category */ -+ UINT_8 ucAction; /* Action Value */ -+ UINT_8 ucDialogToken; /* Dialog Token chosen by the sender */ -+ UINT_8 aucBAParameterSet[2]; /* BA policy, TID, buffer size */ -+ UINT_8 aucBATimeoutValue[2]; -+ UINT_8 aucBAStartSeqCtrl[2]; /* SSN */ -+} __KAL_ATTRIB_PACKED__ ACTION_ADDBA_REQ_FRAME_T, *P_ACTION_ADDBA_REQ_FRAME_T; -+ -+typedef struct _ACTION_ADDBA_REQ_BODY_T { -+ UINT_16 u2BAParameterSet; /* BA policy, TID, buffer size */ -+ UINT_16 u2BATimeoutValue; -+ UINT_16 u2BAStartSeqCtrl; /* SSN */ -+} __KAL_ATTRIB_PACKED__ ACTION_ADDBA_REQ_BODY_T, *P_ACTION_ADDBA_REQ_BODY_T; -+ -+/* 7.4.4.2 ADDBA Response frame format */ -+typedef struct _ACTION_ADDBA_RSP_FRAME_T { -+ /* Action MAC header */ -+ UINT_16 u2FrameCtrl; /* Frame Control */ -+ UINT_16 u2DurationID; /* Duration */ -+ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ -+ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ -+ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ -+ UINT_16 u2SeqCtrl; /* Sequence Control */ -+ /* Action frame body */ -+ UINT_8 ucCategory; /* Category */ -+ UINT_8 ucAction; /* Action Value */ -+ UINT_8 ucDialogToken; /* Dialog Token chosen by the sender */ -+ UINT_8 aucStatusCode[2]; -+ UINT_8 aucBAParameterSet[2]; /* BA policy, TID, buffer size */ -+ UINT_8 aucBATimeoutValue[2]; -+} __KAL_ATTRIB_PACKED__ ACTION_ADDBA_RSP_FRAME_T, *P_ACTION_ADDBA_RSP_FRAME_T; -+ -+typedef struct _ACTION_ADDBA_RSP_BODY_T { -+ UINT_16 u2StatusCode; -+ UINT_16 u2BAParameterSet; /* BA policy, TID, buffer size */ -+ UINT_16 u2BATimeoutValue; -+} __KAL_ATTRIB_PACKED__ ACTION_ADDBA_RSP_BODY_T, *P_ACTION_ADDBA_RSP_BODY_T; -+ -+/* 7.4.4.3 DELBA frame format */ -+typedef struct _ACTION_DELBA_FRAME_T { -+ /* Action MAC header */ -+ UINT_16 u2FrameCtrl; /* Frame Control */ -+ UINT_16 u2DurationID; /* Duration */ -+ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ -+ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ -+ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ -+ UINT_16 u2SeqCtrl; /* Sequence Control */ -+ /* Action frame body */ -+ UINT_8 ucCategory; /* Category */ -+ UINT_8 ucAction; /* Action Value */ -+ UINT_16 u2DelBaParameterSet; /* Bit 11 Initiator, Bits 12-15 TID */ -+ UINT_16 u2ReasonCode; /* 7.3.1.7 */ -+} __KAL_ATTRIB_PACKED__ ACTION_DELBA_FRAME_T, *P_ACTION_DELBA_FRAME_T; -+ -+/* 7.4.6.1 Radio Measurement Request frame format */ -+typedef struct _ACTION_RM_REQ_FRAME { -+ /* MAC header */ -+ UINT_16 u2FrameCtrl; /* Frame Control */ -+ UINT_16 u2Duration; /* Duration */ -+ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ -+ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ -+ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ -+ UINT_16 u2SeqCtrl; /* Sequence Control */ -+ /* Radio Measurement Request frame body */ -+ UINT_8 ucCategory; /* Category */ -+ UINT_8 ucAction; /* Action Value */ -+ UINT_8 ucDialogToken; /* Dialog Token */ -+ UINT_16 u2Repetitions; /* Number of repetitions */ -+ UINT_8 aucInfoElem[1]; /* Measurement Request elements, such as -+ channel load request, and etc. */ -+} __KAL_ATTRIB_PACKED__ ACTION_RM_REQ_FRAME, *P_ACTION_RM_REQ_FRAME; -+ -+/* 7.4.6.2 Radio Measurement Report frame format */ -+typedef struct _ACTION_RM_REPORT_FRAME { -+ /* MAC header */ -+ UINT_16 u2FrameCtrl; /* Frame Control */ -+ UINT_16 u2Duration; /* Duration */ -+ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ -+ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ -+ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ -+ UINT_16 u2SeqCtrl; /* Sequence Control */ -+ /* Radio Measurement Report frame body */ -+ UINT_8 ucCategory; /* Category */ -+ UINT_8 ucAction; /* Action Value */ -+ UINT_8 ucDialogToken; /* Dialog Token */ -+ UINT_8 aucInfoElem[1]; /* Measurement Report elements, such as -+ channel load report, and etc. */ -+} __KAL_ATTRIB_PACKED__ ACTION_RM_REPORT_FRAME, *P_ACTION_RM_REPORT_FRAME; -+ -+/* 7.4.7.1a 20/40 BSS Coexistence Management frame format */ -+typedef struct _ACTION_20_40_COEXIST_FRAME { -+ /* MAC header */ -+ UINT_16 u2FrameCtrl; /* Frame Control */ -+ UINT_16 u2Duration; /* Duration */ -+ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ -+ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ -+ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ -+ UINT_16 u2SeqCtrl; /* Sequence Control */ -+ /* BSS Coexistence Management frame body */ -+ UINT_8 ucCategory; /* Category */ -+ UINT_8 ucAction; /* Action Value */ -+ -+ IE_20_40_COEXIST_T rBssCoexist; /* 20/40 BSS coexistence element */ -+ IE_INTOLERANT_CHNL_REPORT_T rChnlReport; /* Intolerant channel report */ -+ -+} __KAL_ATTRIB_PACKED__ ACTION_20_40_COEXIST_FRAME, *P_ACTION_20_40_COEXIST_FRAME; -+ -+#if CFG_SUPPORT_802_11W -+/* 7.4.9 SA Query Management frame format */ -+typedef struct _ACTION_SA_QUERY_FRAME { -+ /* MAC header */ -+ UINT_16 u2FrameCtrl; /* Frame Control */ -+ UINT_16 u2Duration; /* Duration */ -+ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ -+ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ -+ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ -+ UINT_16 u2SeqCtrl; /* Sequence Control */ -+ /* BSS Coexistence Management frame body */ -+ UINT_8 ucCategory; /* Category */ -+ UINT_8 ucAction; /* Action Value */ -+ -+ UINT_8 ucTransId[ACTION_SA_QUERY_TR_ID_LEN]; /* Transaction id */ -+ -+} __KAL_ATTRIB_PACKED__ ACTION_SA_QUERY_FRAME, *P_ACTION_SA_QUERY_FRAME; -+#endif -+ -+/* 7.4.10 Notify Channel Width Management frame format */ -+typedef struct _ACTION_NOTIFY_CHNL_WIDTH_FRAME { -+ /* MAC header */ -+ UINT_16 u2FrameCtrl; /* Frame Control */ -+ UINT_16 u2Duration; /* Duration */ -+ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ -+ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ -+ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ -+ UINT_16 u2SeqCtrl; /* Sequence Control */ -+ /* BSS Coexistence Management frame body */ -+ UINT_8 ucCategory; /* Category */ -+ UINT_8 ucAction; /* Action Value */ -+ UINT_8 ucChannelWidth; /* Channel Width */ -+} __KAL_ATTRIB_PACKED__ ACTION_NOTIFY_CHNL_WIDTH_FRAME, *P_ACTION_NOTIFY_CHNL_WIDTH_FRAME; -+ -+/* 802.11v Wireless Network Management: Timing Measurement Request */ -+typedef struct _ACTION_WNM_TIMING_MEAS_REQ_FRAME { -+ /* MAC header */ -+ UINT_16 u2FrameCtrl; /* Frame Control */ -+ UINT_16 u2Duration; /* Duration */ -+ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ -+ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ -+ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ -+ UINT_16 u2SeqCtrl; /* Sequence Control */ -+ /* Timing Measurement Request Management frame body */ -+ UINT_8 ucCategory; /* Category */ -+ UINT_8 ucAction; /* Action Value */ -+ UINT_8 ucTrigger; /* Trigger */ -+} __KAL_ATTRIB_PACKED__ ACTION_WNM_TIMING_MEAS_REQ_FRAME, *P_ACTION_WNM_TIMING_MEAS_REQ_FRAME; -+ -+/* 802.11v Wireless Network Management: Timing Measurement */ -+typedef struct _ACTION_UNPROTECTED_WNM_TIMING_MEAS_FRAME { -+ /* MAC header */ -+ UINT_16 u2FrameCtrl; /* Frame Control */ -+ UINT_16 u2Duration; /* Duration */ -+ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ -+ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ -+ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ -+ UINT_16 u2SeqCtrl; /* Sequence Control */ -+ /* Timing Measurement Management frame body */ -+ UINT_8 ucCategory; /* Category */ -+ UINT_8 ucAction; /* Action Value */ -+ UINT_8 ucDialogToken; /* Dialog Token */ -+ UINT_8 ucFollowUpDialogToken; /* Follow Up Dialog Token */ -+ UINT_32 u4ToD; /* Timestamp of Departure [10ns] */ -+ UINT_32 u4ToA; /* Timestamp of Arrival [10ns] */ -+ UINT_8 ucMaxToDErr; /* Maximum of ToD Error [10ns] */ -+ UINT_8 ucMaxToAErr; /* Maximum of ToA Error [10ns] */ -+} __KAL_ATTRIB_PACKED__ ACTION_UNPROTECTED_WNM_TIMING_MEAS_FRAME, *P_ACTION_UNPROTECTED_WNM_TIMING_MEAS_FRAME; -+ -+/* 3 Information Elements from WFA. */ -+typedef struct _IE_WFA_T { -+ UINT_8 ucId; -+ UINT_8 ucLength; -+ UINT_8 aucOui[3]; -+ UINT_8 ucOuiType; -+ UINT_8 aucOuiSubTypeVersion[2]; -+ /*!< Please be noted. WPA defines a 16 bit field version -+ instead of one subtype field and one version field */ -+} __KAL_ATTRIB_PACKED__ IE_WFA_T, *P_IE_WFA_T; -+ -+/* HS20 3.1 - HS 2.0 Indication Information Element */ -+typedef struct _IE_HS20_INDICATION_T { -+ UINT_8 ucId; /* Element ID */ -+ UINT_8 ucLength; /* Length */ -+ UINT_8 aucOui[3]; /* OUI */ -+ UINT_8 ucType; /* Type */ -+ UINT_8 ucHotspotConfig; /* Hotspot Configuration */ -+} __KAL_ATTRIB_PACKED__ IE_HS20_INDICATION_T, *P_IE_HS20_INDICATION_T; -+ -+/* WAPI Information element format */ -+typedef struct _WAPI_INFO_ELEM_T { -+ UCHAR ucElemId; -+ UCHAR ucLength; -+ UINT_16 u2Version; -+ UINT_16 u2AuthKeyMgtSuiteCount; -+ UCHAR aucAuthKeyMgtSuite1[4]; -+} __KAL_ATTRIB_PACKED__ WAPI_INFO_ELEM_T, *P_WAPI_INFO_ELEM_T; -+ -+#if defined(WINDOWS_DDK) || defined(WINDOWS_CE) -+#pragma pack() -+#endif -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+/* Convert the ECWmin(max) to CWmin(max) */ -+#define ECW_TO_CW(_ECW) ((1 << (_ECW)) - 1) -+ -+/* Convert the RCPI to dBm */ -+#define RCPI_TO_dBm(_rcpi) \ -+ ((PARAM_RSSI)(((_rcpi) > RCPI_HIGH_BOUND ? RCPI_HIGH_BOUND : (_rcpi)) >> 1) - NDBM_LOW_BOUND_FOR_RCPI) -+ -+/* Convert the dBm to RCPI */ -+#define dBm_TO_RCPI(_dbm) \ -+ (RCPI)(((((PARAM_RSSI)(_dbm) + NDBM_LOW_BOUND_FOR_RCPI) << 1) > RCPI_HIGH_BOUND) ? RCPI_HIGH_BOUND : \ -+ ((((PARAM_RSSI)(_dbm) + NDBM_LOW_BOUND_FOR_RCPI) << 1) < RCPI_LOW_BOUND ? RCPI_LOW_BOUND : \ -+ (((PARAM_RSSI)(_dbm) + NDBM_LOW_BOUND_FOR_RCPI) << 1))) -+ -+/* Convert an unsigned char pointer to an information element pointer */ -+#define IE_ID(fp) (((P_IE_HDR_T) fp)->ucId) -+#define IE_LEN(fp) (((P_IE_HDR_T) fp)->ucLength) -+#define IE_SIZE(fp) (ELEM_HDR_LEN + IE_LEN(fp)) -+ -+#define SSID_IE(fp) ((P_IE_SSID_T) fp) -+ -+#define SUP_RATES_IE(fp) ((P_IE_SUPPORTED_RATE_T) fp) -+ -+#define DS_PARAM_IE(fp) ((P_IE_DS_PARAM_SET_T) fp) -+ -+#define TIM_IE(fp) ((P_IE_TIM_T) fp) -+ -+#define IBSS_PARAM_IE(fp) ((P_IE_IBSS_PARAM_SET_T) fp) -+ -+#define ERP_INFO_IE(fp) ((P_IE_ERP_T) fp) -+ -+#define EXT_SUP_RATES_IE(fp) ((P_IE_EXT_SUPPORTED_RATE_T) fp) -+ -+#define WFA_IE(fp) ((P_IE_WFA_T) fp) -+ -+#if CFG_SUPPORT_802_11D -+#define COUNTRY_IE(fp) ((P_IE_COUNTRY_T) fp) -+#endif -+ -+#define EXT_CAP_IE(fp) ((P_EXT_CAP_T) fp) -+ -+#define HT_CAP_IE(fp) ((P_IE_HT_CAP_T) fp) -+ -+#define HT_OP_IE(fp) ((P_IE_HT_OP_T) fp) -+ -+#define OBSS_SCAN_PARAM_IE(fp) ((P_IE_OBSS_SCAN_PARAM_T) fp) -+ -+#define BSS_20_40_COEXIST_IE(fp) ((P_IE_20_40_COEXIST_T) fp) -+ -+#define SUP_OPERATING_CLASS_IE(fp) ((P_IE_SUP_OPERATING_CLASS_T) fp) -+ -+#define QUIET_IE(fp) ((P_IE_QUIET_T) fp) -+ -+#if CFG_SUPPORT_DFS /* Add by Enlai */ -+#define SUPPORTED_CHANNELS_IE(fp) ((P_IE_SUPPORTED_CHANNELS_T)fp) -+#endif -+ -+#define TIMEOUT_INTERVAL_IE(fp) ((IE_TIMEOUT_INTERVAL_T *)fp) -+ -+/* The macro to check if the MAC address is B/MCAST Address */ -+#define IS_BMCAST_MAC_ADDR(_pucDestAddr) \ -+ ((BOOLEAN) (((PUINT_8)(_pucDestAddr))[0] & BIT(0))) -+ -+/* The macro to check if the MAC address is UCAST Address */ -+#define IS_UCAST_MAC_ADDR(_pucDestAddr) \ -+ ((BOOLEAN) !(((PUINT_8)(_pucDestAddr))[0] & BIT(0))) -+ -+/* The macro to copy the MAC address */ -+#define COPY_MAC_ADDR(_pucDestAddr, _pucSrcAddr) \ -+ kalMemCopy(_pucDestAddr, _pucSrcAddr, MAC_ADDR_LEN) -+ -+/* The macro to check if two MAC addresses are equal */ -+#define EQUAL_MAC_ADDR(_pucDestAddr, _pucSrcAddr) \ -+ (!kalMemCmp(_pucDestAddr, _pucSrcAddr, MAC_ADDR_LEN)) -+ -+/* The macro to check if two MAC addresses are not equal */ -+#define UNEQUAL_MAC_ADDR(_pucDestAddr, _pucSrcAddr) \ -+ (kalMemCmp(_pucDestAddr, _pucSrcAddr, MAC_ADDR_LEN)) -+ -+/* The macro to check whether two SSIDs are equal */ -+#define EQUAL_SSID(pucSsid1, ucSsidLen1, pucSsid2, ucSsidLen2) \ -+ ((ucSsidLen1 <= ELEM_MAX_LEN_SSID) && \ -+ (ucSsidLen2 <= ELEM_MAX_LEN_SSID) && \ -+ ((ucSsidLen1) == (ucSsidLen2)) && \ -+ !kalMemCmp(pucSsid1, pucSsid2, ucSsidLen1)) -+ -+/* The macro to check whether two SSIDs are equal */ -+#define UNEQUAL_SSID(pucSsid1, ucSsidLen1, pucSsid2, ucSsidLen2) \ -+ ((ucSsidLen1 > ELEM_MAX_LEN_SSID) || \ -+ (ucSsidLen2 > ELEM_MAX_LEN_SSID) || \ -+ ((ucSsidLen1) != (ucSsidLen2)) || \ -+ kalMemCmp(pucSsid1, pucSsid2, ucSsidLen1)) -+ -+/* The macro to copy the SSID, the length of pucDestSsid should have at least 32 bytes */ -+#define COPY_SSID(pucDestSsid, ucDestSsidLen, pucSrcSsid, ucSrcSsidLen) \ -+ do { \ -+ ucDestSsidLen = ucSrcSsidLen; \ -+ if (ucSrcSsidLen) { \ -+ ASSERT(ucSrcSsidLen <= ELEM_MAX_LEN_SSID); \ -+ kalMemCopy(pucDestSsid, \ -+ pucSrcSsid, \ -+ ((ucSrcSsidLen > ELEM_MAX_LEN_SSID) ? ELEM_MAX_LEN_SSID : ucSrcSsidLen)); \ -+ } \ -+ } while (FALSE) -+ -+/* The macro to copy the IE */ -+#define COPY_IE(pucDestIE, pucSrcIE) \ -+ do { \ -+ kalMemCopy((PUINT_8)pucDestIE, \ -+ (PUINT_8)pucSrcIE,\ -+ IE_SIZE(pucSrcIE)); \ -+ } while (FALSE) -+ -+#define IE_FOR_EACH(_pucIEsBuf, _u2IEsBufLen, _u2Offset) \ -+ for ((_u2Offset) = 0;\ -+ ((((_u2Offset) + 2) <= (_u2IEsBufLen)) && (((_u2Offset) + IE_SIZE(_pucIEsBuf)) <= (_u2IEsBufLen))); \ -+ (_u2Offset) += IE_SIZE(_pucIEsBuf), (_pucIEsBuf) += IE_SIZE(_pucIEsBuf)) -+ -+#define SET_EXT_CAP(_aucField, _ucFieldLength, _ucBit) \ -+ do { \ -+ if ((_ucBit) < ((_ucFieldLength) * 8)) { \ -+ PUINT_8 aucExtCap = (PUINT_8)(_aucField); \ -+ ((aucExtCap)[(_ucBit) / 8]) |= BIT((_ucBit) % 8); \ -+ } \ -+ } while (FALSE) -+ -+#define TEST_EXT_CAP(_aucField, _ucFieldLength, _ucBit) \ -+ ((((_ucFieldLength) * 8) > (_ucBit)) && (((_aucField)[(_ucBit) / 8]) & BIT((_ucBit) % 8))) -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif /* _MAC_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/mtreg.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/mtreg.h -new file mode 100644 -index 000000000000..583923aed010 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/mtreg.h -@@ -0,0 +1,272 @@ -+/* -+** Id: //Department/DaVinci/TRUNK/MT6620_5931_WiFi_Driver/include/nic/mtreg.h#2 -+*/ -+ -+/*! \file "mtreg.h" -+ \brief The common register definition of mt5931 -+ -+ N/A -+*/ -+ -+/* -+** Log: mtreg.h -+ * -+ * 01 28 2013 samp.lin -+ * [WCXRP00000851] [MT6582 Wi-Fi][Driver] Add HIFSYS related definition to driver source tree -+ * add MT6582-specific definitions. -+ * -+ * 08 15 2011 cp.wu -+ * [WCXRP00000851] [MT6628 Wi-Fi][Driver] Add HIFSYS related definition to driver source tree -+ * add MT6628-specific definitions. -+ * -+ * 07 13 2011 cp.wu -+ * [WCXRP00000851] [MT6628 Wi-Fi][Driver] Add HIFSYS related definition to driver source tree -+ * add initial version for MT6628 driver support. -+ * -+*/ -+ -+#ifndef _MTREG_H -+#define _MTREG_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+/* 1 MT6628 MCR Definition */ -+ -+/* 2 Host Interface */ -+ -+/* 4 CHIP ID Register */ -+#define MCR_WCIR 0x0000 -+ -+/* 4 HIF Low Power Control Register */ -+#define MCR_WHLPCR 0x0004 -+ -+/* 4 Control Status Register */ -+#define MCR_WSDIOCSR 0x0008 -+#define MCR_WSPICSR 0x0008 -+ -+/* 4 HIF Control Register */ -+#define MCR_WHCR 0x000C -+ -+/* 4 HIF Interrupt Status Register */ -+#define MCR_WHISR 0x0010 -+ -+/* 4 HIF Interrupt Enable Register */ -+#define MCR_WHIER 0x0014 -+ -+/* 4 Abnormal Status Register */ -+#define MCR_WASR 0x0018 -+ -+/* 4 WLAN Software Interrupt Control Register */ -+#define MCR_WSICR 0x001C -+ -+/* 4 WLAN TX Status Register */ -+#define MCR_WTSR0 0x0020 -+ -+/* 4 WLAN TX Status Register */ -+#define MCR_WTSR1 0x0024 -+ -+/* 4 WLAN TX Data Register 0 */ -+#define MCR_WTDR0 0x0028 -+ -+/* 4 WLAN TX Data Register 1 */ -+#define MCR_WTDR1 0x002C -+ -+/* 4 WLAN RX Data Register 0 */ -+#define MCR_WRDR0 0x0030 -+ -+/* 4 WLAN RX Data Register 1 */ -+#define MCR_WRDR1 0x0034 -+ -+/* 4 Host to Device Send Mailbox 0 Register */ -+#define MCR_H2DSM0R 0x0038 -+ -+/* 4 Host to Device Send Mailbox 1 Register */ -+#define MCR_H2DSM1R 0x003c -+ -+/* 4 Device to Host Receive Mailbox 0 Register */ -+#define MCR_D2HRM0R 0x0040 -+ -+/* 4 Device to Host Receive Mailbox 1 Register */ -+#define MCR_D2HRM1R 0x0044 -+ -+/* 4 Device to Host Receive Mailbox 2 Register */ -+#define MCR_D2HRM2R 0x0048 -+ -+/* 4 WLAN RX Packet Length Register */ -+#define MCR_WRPLR 0x0050 -+ -+/* 4 HSIF Transaction Count Register */ -+#define MCR_HSTCR 0x0058 -+ -+/* #if CFG_SDIO_INTR_ENHANCE */ -+typedef struct _ENHANCE_MODE_DATA_STRUCT_T { -+ UINT_32 u4WHISR; -+ union { -+ struct { -+ UINT_8 ucTQ0Cnt; -+ UINT_8 ucTQ1Cnt; -+ UINT_8 ucTQ2Cnt; -+ UINT_8 ucTQ3Cnt; -+ UINT_8 ucTQ4Cnt; -+ UINT_8 ucTQ5Cnt; -+ UINT_16 u2Rsrv; -+ } u; -+ UINT_32 au4WTSR[2]; -+ } rTxInfo; -+ union { -+ struct { -+ UINT_16 u2NumValidRx0Len; -+ UINT_16 u2NumValidRx1Len; -+ UINT_16 au2Rx0Len[16]; -+ UINT_16 au2Rx1Len[16]; -+ } u; -+ UINT_32 au4RxStatusRaw[17]; -+ } rRxInfo; -+ UINT_32 u4RcvMailbox0; -+ UINT_32 u4RcvMailbox1; -+} ENHANCE_MODE_DATA_STRUCT_T, *P_ENHANCE_MODE_DATA_STRUCT_T; -+/* #endif */ /* ENHANCE_MODE_DATA_STRUCT_T */ -+ -+/* 2 Definition in each register */ -+/* 3 WCIR 0x0000 */ -+#define WCIR_WLAN_READY BIT(21) -+#define WCIR_POR_INDICATOR BIT(20) -+#define WCIR_REVISION_ID BITS(16, 19) -+#define WCIR_CHIP_ID BITS(0, 15) -+ -+#define MTK_CHIP_REV_72 0x00006572 -+#define MTK_CHIP_REV_82 0x00006582 -+#define MTK_CHIP_REV_92 0x00006592 -+#define MTK_CHIP_MP_REVERSION_ID 0x0 -+ -+/* 3 WHLPCR 0x0004 */ -+#define WHLPCR_FW_OWN_REQ_CLR BIT(9) -+#define WHLPCR_FW_OWN_REQ_SET BIT(8) -+#define WHLPCR_IS_DRIVER_OWN BIT(8) -+#define WHLPCR_INT_EN_CLR BIT(1) -+#define WHLPCR_INT_EN_SET BIT(0) -+ -+/* 3 WSDIOCSR 0x0008 */ -+#define WSDIOCSR_SDIO_RE_INIT_EN BIT(0) -+ -+/* 3 WSPICSR 0x0008 */ -+#define WCSR_SPI_MODE_SEL BITS(3, 4) -+#define WCSR_SPI_ENDIAN_BIG BIT(2) -+#define WCSR_SPI_INT_OUT_MODE BIT(1) -+#define WCSR_SPI_DATA_OUT_MODE BIT(0) -+ -+/* 3 WHCR 0x000C */ -+#define WHCR_RX_ENHANCE_MODE_EN BIT(16) -+#define WHCR_MAX_HIF_RX_LEN_NUM BITS(4, 7) -+#define WHCR_W_MAILBOX_RD_CLR_EN BIT(2) -+#define WHCR_W_INT_CLR_CTRL BIT(1) -+#define WHCR_MCU_DBG_EN BIT(0) -+#define WHCR_OFFSET_MAX_HIF_RX_LEN_NUM 4 -+ -+/* 3 WHISR 0x0010 */ -+#define WHISR_D2H_SW_INT BITS(8, 31) -+#define WHISR_D2H_SW_ASSERT_INFO_INT BIT(31) -+#define WHISR_FW_OWN_BACK_INT BIT(4) -+#define WHISR_ABNORMAL_INT BIT(3) -+#define WHISR_RX1_DONE_INT BIT(2) -+#define WHISR_RX0_DONE_INT BIT(1) -+#define WHISR_TX_DONE_INT BIT(0) -+ -+/* 3 WHIER 0x0014 */ -+#define WHIER_D2H_SW_INT BITS(8, 31) -+#define WHIER_FW_OWN_BACK_INT_EN BIT(4) -+#define WHIER_ABNORMAL_INT_EN BIT(3) -+#define WHIER_RX1_DONE_INT_EN BIT(2) -+#define WHIER_RX0_DONE_INT_EN BIT(1) -+#define WHIER_TX_DONE_INT_EN BIT(0) -+#define WHIER_DEFAULT (WHIER_RX0_DONE_INT_EN | \ -+ WHIER_RX1_DONE_INT_EN | \ -+ WHIER_TX_DONE_INT_EN | \ -+ WHIER_ABNORMAL_INT_EN | \ -+ WHIER_D2H_SW_INT \ -+ ) -+ -+/* 3 WASR 0x0018 */ -+#define WASR_FW_OWN_INVALID_ACCESS BIT(4) -+#define WASR_RX1_UNDER_FLOW BIT(3) -+#define WASR_RX0_UNDER_FLOW BIT(2) -+#define WASR_TX1_OVER_FLOW BIT(1) -+#define WASR_TX0_OVER_FLOW BIT(0) -+ -+/* 3 WSICR 0x001C */ -+#define WSICR_H2D_SW_INT_SET BITS(16, 31) -+ -+/* 3 WRPLR 0x0050 */ -+#define WRPLR_RX1_PACKET_LENGTH BITS(16, 31) -+#define WRPLR_RX0_PACKET_LENGTH BITS(0, 15) -+ -+/* 3 HSTCR 0x0058 */ -+#define HSTCR_AFF_BURST_LEN BITS(24, 25) -+#define HSTCR_AFF_BURST_LEN_OFFSET 24 -+#define HSTCR_TRANS_TARGET BITS(20, 22) -+#define HSTCR_TRANS_TARGET_OFFSET 20 -+#define HSTCR_HSIF_TRANS_CNT BITS(2, 19) -+#define HSTCR_HSIF_TRANS_CNT_OFFSET 2 -+ -+/* HSTCR_TRANS_TARGET */ -+typedef enum _eTransTarget { -+ TRANS_TARGET_TXD0 = 0, -+ TRANS_TARGET_TXD1, -+ TRANS_TARGET_RXD0, -+ TRANS_TARGET_RXD1, -+ TRANS_TARGET_WHISR, -+ NUM_TRANS_TARGET -+} E_TRANS_TARGET_T; -+ -+typedef enum _E_AFF_BURST_LEN { -+ BURST_1_DW = 0, -+ BURST_4_DW, -+ BURST_8_DW, -+ BURST_RSV, -+ NUM_AFF_BURST_LEN -+} E_AFF_BURST_LEN; -+ -+#endif /* _MTREG_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/nic.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/nic.h -new file mode 100644 -index 000000000000..c059b707aee8 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/nic.h -@@ -0,0 +1,498 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/nic/nic.h#1 -+*/ -+ -+/*! \file "nic.h" -+ \brief The declaration of nic functions -+ -+ Detail description. -+*/ -+ -+/* -+** Log: nic.h -+ * -+ * 11 01 2011 chinglan.wang -+ * NULL -+ * Modify the Wi-Fi method of the flush TX queue when disconnect the AP. -+ * If disconnect the AP and flush all the data frame in the TX queue, WPS -+ * cannot do the 4-way handshake to connect to the AP.. -+ * -+ * 07 18 2011 chinghwa.yu -+ * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm -+ * Add CMD/Event for RDD and BWCS. -+ * -+ * 05 11 2011 cp.wu -+ * [WCXRP00000718] [MT6620 Wi-Fi] modify the behavior of setting tx power -+ * ACPI APIs migrate to wlan_lib.c for glue layer to invoke. -+ * -+ * 04 11 2011 yuche.tsai -+ * [WCXRP00000627] [Volunteer Patch][MT6620][Driver] Pending MMPUD of P2P Network may crash system issue. -+ * Fix kernel panic issue when MMPDU of P2P is pending in driver. -+ * -+ * 03 02 2011 cp.wu -+ * [WCXRP00000503] [MT6620 Wi-Fi][Driver] Take RCPI brought by association response as initial RSSI right -+ * after connection is built. -+ * use RCPI brought by ASSOC-RESP after connection is built as initial RCPI to avoid using a uninitialized MAC-RX RCPI. -+ * -+ * 02 01 2011 cm.chang -+ * [WCXRP00000415] [MT6620 Wi-Fi][Driver] Check if any memory leakage happens when uninitializing in DGB mode -+ * . -+ * -+ * 01 27 2011 tsaiyuan.hsu -+ * [WCXRP00000392] [MT6620 Wi-Fi][Driver] Add Roaming Support -+ * add roaming fsm -+ * 1. not support 11r, only use strength of signal to determine roaming. -+ * 2. not enable CFG_SUPPORT_ROAMING until completion of full test. -+ * 3. in 6620, adopt work-around to avoid sign extension problem of cck of hw -+ * 4. assume that change of link quality in smooth way. -+ * -+ * 10 26 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000137] [MT6620 Wi-Fi] [FW] -+ * Support NIC capability query command -+ * 1) update NVRAM content template to ver 1.02 -+ * 2) add compile option for querying NIC capability (default: off) -+ * 3) modify AIS 5GHz support to run-time option, which could be turned on by registry or NVRAM setting -+ * 4) correct auto-rate compiler error under linux (treat warning as error) -+ * 5) simplify usage of NVRAM and REG_INFO_T -+ * 6) add version checking between driver and firmware -+ * -+ * 10 26 2010 eddie.chen -+ * [WCXRP00000134] [MT6620 Wi-Fi][Driver] Add a registry to enable auto rate for SQA test by using E1 EVB -+ * Add auto rate parameter in registry. -+ * -+ * 10 12 2010 cp.wu -+ * [WCXRP00000084] [MT6620 Wi-Fi][Driver][FW] Add fixed rate support for distance test -+ * add HT (802.11n) fixed rate support. -+ * -+ * 10 08 2010 cp.wu -+ * [WCXRP00000084] [MT6620 Wi-Fi][Driver][FW] Add fixed rate support for distance test -+ * adding fixed rate support for distance test. (from registry setting) -+ * -+ * 10 05 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check -+ * 1) add NVRAM access API -+ * 2) fake scanning result when NVRAM doesn't exist and/or version mismatch. (off by compiler option) -+ * 3) add OID implementation for NVRAM read/write service -+ * -+ * 10 04 2010 cp.wu -+ * [WCXRP00000077] [MT6620 Wi-Fi][Driver][FW] Eliminate use of ENUM_NETWORK_TYPE_T and replaced -+ * by ENUM_NETWORK_TYPE_INDEX_T only -+ * remove ENUM_NETWORK_TYPE_T definitions -+ * -+ * 09 21 2010 cp.wu -+ * [WCXRP00000053] [MT6620 Wi-Fi][Driver] Reset incomplete and might leads to BSOD when entering RF test -+ * with AIS associated -+ * Do a complete reset with STA-REC null checking for RF test re-entry -+ * -+ * 09 08 2010 cp.wu -+ * NULL -+ * use static memory pool for storing IEs of scanning result. -+ * -+ * 09 01 2010 cp.wu -+ * NULL -+ * HIFSYS Clock Source Workaround -+ * -+ * 08 25 2010 george.huang -+ * NULL -+ * update OID/ registry control path for PM related settings -+ * -+ * 08 12 2010 cp.wu -+ * NULL -+ * [AIS-FSM] honor registry setting for adhoc running mode. (A/B/G) -+ * -+ * 08 03 2010 cp.wu -+ * NULL -+ * Centralize mgmt/system service procedures into independent calls. -+ * -+ * 07 28 2010 cp.wu -+ * NULL -+ * 1) eliminate redundant variable eOPMode in prAdapter->rWlanInfo -+ * 2) change nicMediaStateChange() API prototype -+ * -+ * 07 14 2010 yarco.yang -+ * -+ * 1. Remove CFG_MQM_MIGRATION -+ * 2. Add CMD_UPDATE_WMM_PARMS command -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 07 06 2010 george.huang -+ * [WPD00001556]Basic power managemenet function -+ * Update arguments for nicUpdateBeaconIETemplate() -+ * -+ * 07 06 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * STA-REC is maintained by CNM only. -+ * -+ * 07 05 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) ignore RSN checking when RSN is not turned on. -+ * 2) set STA-REC deactivation callback as NULL -+ * 3) add variable initialization API based on PHY configuration -+ * -+ * 06 30 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * sync. with CMD/EVENT document ver0.07. -+ * -+ * 06 29 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) sync to. CMD/EVENT document v0.03 -+ * 2) simplify DTIM period parsing in scan.c only, bss.c no longer parses it again. -+ * 3) send command packet to indicate FW-PM after -+ * a) 1st beacon is received after AIS has connected to an AP -+ * b) IBSS-ALONE has been created -+ * c) IBSS-MERGE has occurred -+ * -+ * 06 25 2010 george.huang -+ * [WPD00001556]Basic power managemenet function -+ * Create beacon update path, with expose bssUpdateBeaconContent() -+ * -+ * 06 22 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) add command warpper for STA-REC/BSS-INFO sync. -+ * 2) enhance command packet sending procedure for non-oid part -+ * 3) add command packet definitions for STA-REC/BSS-INFO sync. -+ * -+ * 06 21 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * implement TX_DONE callback path. -+ * -+ * 06 11 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) migrate assoc.c. -+ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness -+ * 3) add configuration options for CNM_MEM and RSN modules -+ * 4) add data path for management frames -+ * 5) eliminate rPacketInfo of MSDU_INFO_T -+ * -+ * 06 10 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) eliminate CFG_CMD_EVENT_VERSION_0_9 -+ * 2) when disconnected, indicate nic directly (no event is needed) -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 04 26 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) surpress compiler warning -+ * 2) when acqruing LP-own, keep writing WHLPCR whenever OWN is not acquired yet -+ * -+ * 04 13 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * add framework for BT-over-Wi-Fi support. -+ * * * * * * * * * 1) prPendingCmdInfo is replaced by queue for multiple handler capability -+ * * * * * * * * * 2) command sequence number is now increased atomically -+ * * * * * * * * * 3) private data could be hold and taken use for other purpose -+ * -+ * 04 12 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * add channel frequency <-> number conversion -+ * -+ * 03 19 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) add ACPI D0/D3 state switching support -+ * * * * * 2) use more formal way to handle interrupt when the status is retrieved from enhanced RX response -+ * -+ * 03 17 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * always process TX interrupt first then RX interrupt. -+ * -+ * 02 25 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * correct behavior to prevent duplicated RX handling for RX0_DONE and RX1_DONE -+ * -+ * 02 23 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * add checksum offloading support. -+** \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-10-13 21:58:58 GMT mtk01084 -+** update for new HW architecture design -+** \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-04-24 21:12:55 GMT mtk01104 -+** Add function prototype nicRestoreSpiDefMode() -+** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-03-19 18:32:54 GMT mtk01084 -+** update for basic power management functions -+** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 20:16:32 GMT mtk01426 -+** Init for develop -+** -+*/ -+ -+#ifndef _NIC_H -+#define _NIC_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+struct _REG_ENTRY_T { -+ UINT_32 u4Offset; -+ UINT_32 u4Value; -+}; -+ -+struct _TABLE_ENTRY_T { -+ P_REG_ENTRY_T pu4TablePtr; -+ UINT_16 u2Size; -+}; -+ -+/*! INT status to event map */ -+typedef struct _INT_EVENT_MAP_T { -+ UINT_32 u4Int; -+ UINT_32 u4Event; -+} INT_EVENT_MAP_T, *P_INT_EVENT_MAP_T; -+ -+enum ENUM_INT_EVENT_T { -+ INT_EVENT_ABNORMAL, -+ INT_EVENT_SW_INT, -+ INT_EVENT_TX, -+ INT_EVENT_RX, -+ INT_EVENT_NUM -+}; -+ -+typedef enum _ENUM_IE_UPD_METHOD_T { -+ IE_UPD_METHOD_UPDATE_RANDOM, -+ IE_UPD_METHOD_UPDATE_ALL, -+ IE_UPD_METHOD_DELETE_ALL, -+} ENUM_IE_UPD_METHOD_T, *P_ENUM_IE_UPD_METHOD_T; -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+extern BOOLEAN fgIsResetting; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+/*----------------------------------------------------------------------------*/ -+/* Routines in nic.c */ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS nicAllocateAdapterMemory(IN P_ADAPTER_T prAdapter); -+ -+VOID nicReleaseAdapterMemory(IN P_ADAPTER_T prAdapter); -+ -+VOID nicDisableInterrupt(IN P_ADAPTER_T prAdapter); -+ -+VOID nicEnableInterrupt(IN P_ADAPTER_T prAdapter); -+ -+WLAN_STATUS nicProcessIST(IN P_ADAPTER_T prAdapter); -+ -+WLAN_STATUS nicProcessIST_impl(IN P_ADAPTER_T prAdapter, IN UINT_32 u4IntStatus); -+ -+WLAN_STATUS nicInitializeAdapter(IN P_ADAPTER_T prAdapter); -+ -+VOID nicMCRInit(IN P_ADAPTER_T prAdapter); -+ -+BOOLEAN nicVerifyChipID(IN P_ADAPTER_T prAdapter); -+ -+#if CFG_SDIO_INTR_ENHANCE -+VOID nicSDIOInit(IN P_ADAPTER_T prAdapter); -+ -+VOID nicSDIOReadIntStatus(IN P_ADAPTER_T prAdapter, OUT PUINT_32 pu4IntStatus); -+#endif -+ -+BOOLEAN nicpmSetDriverOwn(IN P_ADAPTER_T prAdapter); -+ -+VOID nicpmSetFWOwn(IN P_ADAPTER_T prAdapter, IN BOOLEAN fgEnableGlobalInt); -+ -+BOOLEAN nicpmSetAcpiPowerD0(IN P_ADAPTER_T prAdapter); -+ -+BOOLEAN nicpmSetAcpiPowerD3(IN P_ADAPTER_T prAdapter); -+ -+#if defined(_HIF_SPI) -+void nicRestoreSpiDefMode(IN P_ADAPTER_T prAdapter); -+#endif -+ -+VOID nicProcessSoftwareInterrupt(IN P_ADAPTER_T prAdapter); -+ -+VOID nicProcessAbnormalInterrupt(IN P_ADAPTER_T prAdapter); -+ -+VOID nicPutMailbox(IN P_ADAPTER_T prAdapter, IN UINT_32 u4MailboxNum, IN UINT_32 u4Data); -+ -+VOID nicGetMailbox(IN P_ADAPTER_T prAdapter, IN UINT_32 u4MailboxNum, OUT PUINT_32 pu4Data); -+ -+VOID nicSetSwIntr(IN P_ADAPTER_T prAdapter, IN UINT_32 u4SwIntrBitmap); -+ -+P_CMD_INFO_T nicGetPendingCmdInfo(IN P_ADAPTER_T prAdapter, IN UINT_8 ucSeqNum); -+ -+P_MSDU_INFO_T nicGetPendingTxMsduInfo(IN P_ADAPTER_T prAdapter, IN UINT_8 ucSeqNum); -+ -+P_MSDU_INFO_T nicGetPendingStaMMPDU(IN P_ADAPTER_T prAdapter, IN UINT_8 ucStaRecIdx); -+ -+VOID nicFreePendingTxMsduInfoByNetwork(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkType); -+ -+UINT_8 nicIncreaseCmdSeqNum(IN P_ADAPTER_T prAdapter); -+ -+UINT_8 nicIncreaseTxSeqNum(IN P_ADAPTER_T prAdapter); -+ -+/* Media State Change */ -+WLAN_STATUS -+nicMediaStateChange(IN P_ADAPTER_T prAdapter, -+ IN ENUM_NETWORK_TYPE_INDEX_T eNetworkType, IN P_EVENT_CONNECTION_STATUS prConnectionStatus); -+ -+/* Utility function for channel number conversion */ -+UINT_32 nicChannelNum2Freq(IN UINT_32 u4ChannelNum); -+ -+UINT_32 nicFreq2ChannelNum(IN UINT_32 u4FreqInKHz); -+ -+/* firmware command wrapper */ -+ /* NETWORK (WIFISYS) */ -+WLAN_STATUS nicActivateNetwork(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx); -+ -+WLAN_STATUS nicDeactivateNetwork(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx); -+ -+ /* BSS-INFO */ -+WLAN_STATUS nicUpdateBss(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx); -+ -+ /* BSS-INFO Indication (PM) */ -+WLAN_STATUS nicPmIndicateBssCreated(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx); -+ -+WLAN_STATUS nicPmIndicateBssConnected(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx); -+ -+WLAN_STATUS nicPmIndicateBssAbort(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx); -+ -+ /* Beacon Template Update */ -+WLAN_STATUS -+nicUpdateBeaconIETemplate(IN P_ADAPTER_T prAdapter, -+ IN ENUM_IE_UPD_METHOD_T eIeUpdMethod, -+ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, -+ IN UINT_16 u2Capability, IN PUINT_8 aucIe, IN UINT_16 u2IELen); -+ -+WLAN_STATUS nicQmUpdateWmmParms(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx); -+ -+WLAN_STATUS nicSetAutoTxPower(IN P_ADAPTER_T prAdapter, IN P_CMD_AUTO_POWER_PARAM_T prAutoPwrParam); -+ -+/*----------------------------------------------------------------------------*/ -+/* Calibration Control */ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS nicUpdateTxPower(IN P_ADAPTER_T prAdapter, IN P_CMD_TX_PWR_T prTxPwrParam); -+ -+WLAN_STATUS nicUpdate5GOffset(IN P_ADAPTER_T prAdapter, IN P_CMD_5G_PWR_OFFSET_T pr5GPwrOffset); -+ -+WLAN_STATUS nicUpdateDPD(IN P_ADAPTER_T prAdapter, IN P_CMD_PWR_PARAM_T prDpdCalResult); -+ -+/*----------------------------------------------------------------------------*/ -+/* PHY configuration */ -+/*----------------------------------------------------------------------------*/ -+VOID nicSetAvailablePhyTypeSet(IN P_ADAPTER_T prAdapter); -+ -+/*----------------------------------------------------------------------------*/ -+/* MGMT and System Service Control */ -+/*----------------------------------------------------------------------------*/ -+VOID nicInitSystemService(IN P_ADAPTER_T prAdapter); -+ -+VOID nicResetSystemService(IN P_ADAPTER_T prAdapter); -+ -+VOID nicUninitSystemService(IN P_ADAPTER_T prAdapter); -+ -+VOID nicInitMGMT(IN P_ADAPTER_T prAdapter, IN P_REG_INFO_T prRegInfo); -+ -+VOID nicUninitMGMT(IN P_ADAPTER_T prAdapter); -+ -+WLAN_STATUS -+nicConfigPowerSaveProfile(IN P_ADAPTER_T prAdapter, -+ ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, PARAM_POWER_MODE ePwrMode, BOOLEAN fgEnCmdEvent); -+ -+WLAN_STATUS nicEnterCtiaMode(IN P_ADAPTER_T prAdapter, BOOLEAN fgEnterCtia, BOOLEAN fgEnCmdEvent); -+/*----------------------------------------------------------------------------*/ -+/* Scan Result Processing */ -+/*----------------------------------------------------------------------------*/ -+VOID -+nicAddScanResult(IN P_ADAPTER_T prAdapter, -+ IN PARAM_MAC_ADDRESS rMacAddr, -+ IN P_PARAM_SSID_T prSsid, -+ IN UINT_32 u4Privacy, -+ IN PARAM_RSSI rRssi, -+ IN ENUM_PARAM_NETWORK_TYPE_T eNetworkType, -+ IN P_PARAM_802_11_CONFIG_T prConfiguration, -+ IN ENUM_PARAM_OP_MODE_T eOpMode, -+ IN PARAM_RATES_EX rSupportedRates, IN UINT_16 u2IELength, IN PUINT_8 pucIEBuf); -+ -+VOID nicFreeScanResultIE(IN P_ADAPTER_T prAdapter, IN UINT_32 u4Idx); -+ -+#if (MT6620_E1_ASIC_HIFSYS_WORKAROUND == 1) -+/*----------------------------------------------------------------------------*/ -+/* Workaround Control */ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS nicEnableClockGating(IN P_ADAPTER_T prAdapter); -+ -+WLAN_STATUS nicDisableClockGating(IN P_ADAPTER_T prAdapter); -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/* Fixed Rate Hacking */ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+nicUpdateRateParams(IN P_ADAPTER_T prAdapter, -+ IN ENUM_REGISTRY_FIXED_RATE_T eRateSetting, -+ IN PUINT_8 pucDesiredPhyTypeSet, -+ IN PUINT_16 pu2DesiredNonHTRateSet, -+ IN PUINT_16 pu2BSSBasicRateSet, -+ IN PUINT_8 pucMcsSet, IN PUINT_8 pucSupMcs32, IN PUINT_16 u2HtCapInfo); -+ -+/*----------------------------------------------------------------------------*/ -+/* Write registers */ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS nicWriteMcr(IN P_ADAPTER_T prAdapter, IN UINT_32 u4Address, IN UINT_32 u4Value); -+ -+/*----------------------------------------------------------------------------*/ -+/* Update auto rate */ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+nicRlmArUpdateParms(IN P_ADAPTER_T prAdapter, -+ IN UINT_32 u4ArSysParam0, -+ IN UINT_32 u4ArSysParam1, IN UINT_32 u4ArSysParam2, IN UINT_32 u4ArSysParam3); -+ -+/*----------------------------------------------------------------------------*/ -+/* Enable/Disable Roaming */ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS nicRoamingUpdateParams(IN P_ADAPTER_T prAdapter, IN UINT_32 u4EnableRoaming); -+ -+VOID nicPrintFirmwareAssertInfo(IN P_ADAPTER_T prAdapter); -+ -+/*----------------------------------------------------------------------------*/ -+/* Link Quality Updating */ -+/*----------------------------------------------------------------------------*/ -+VOID -+nicUpdateLinkQuality(IN P_ADAPTER_T prAdapter, -+ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIdx, IN P_EVENT_LINK_QUALITY prEventLinkQuality); -+ -+VOID -+nicUpdateRSSI(IN P_ADAPTER_T prAdapter, -+ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIdx, IN INT_8 cRssi, IN INT_8 cLinkQuality); -+ -+VOID nicUpdateLinkSpeed(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIdx, IN UINT_16 u2LinkSpeed); -+ -+#if CFG_SUPPORT_RDD_TEST_MODE -+WLAN_STATUS nicUpdateRddTestMode(IN P_ADAPTER_T prAdapter, IN P_CMD_RDD_CH_T prRddChParam); -+#endif -+ -+#endif /* _NIC_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/nic_rx.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/nic_rx.h -new file mode 100644 -index 000000000000..86e2c84b07ff ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/nic_rx.h -@@ -0,0 +1,420 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/nic/nic_rx.h#1 -+*/ -+ -+/*! \file "nic_rx.h" -+ \brief The declaration of the nic rx functions -+ -+*/ -+ -+/* -+** Log: nic_rx.h -+ * -+ * 11 07 2011 tsaiyuan.hsu -+ * [WCXRP00001083] [MT6620 Wi-Fi][DRV]] dump debug counter or frames when debugging is triggered -+ * add debug counters and periodically dump counters for debugging. -+ * -+ * 05 05 2011 cp.wu -+ * [WCXRP00000702] [MT5931][Driver] Modify initialization sequence for E1 ASIC -+ * add delay after whole-chip resetting for MT5931 E1 ASIC. -+ * -+ * 04 18 2011 terry.wu -+ * [WCXRP00000660] [MT6620 Wi-Fi][Driver] Remove flag CFG_WIFI_DIRECT_MOVED -+ * Remove flag CFG_WIFI_DIRECT_MOVED. -+ * -+ * 01 24 2011 cm.chang -+ * [WCXRP00000384] [MT6620 Wi-Fi][Driver][FW] Handle 20/40 action frame in AP mode -+ * and stop ampdu timer when sta_rec is freed -+ * Process received 20/40 coexistence action frame for AP mode -+ * -+ * 09 08 2010 cp.wu -+ * NULL -+ * use static memory pool for storing IEs of scanning result. -+ * -+ * 09 07 2010 yuche.tsai -+ * NULL -+ * Change prototype of API of adding P2P device to scan result. -+ * Additional IE buffer is saved. -+ * -+ * 09 03 2010 kevin.huang -+ * NULL -+ * Refine #include sequence and solve recursive/nested #include issue -+ * -+ * 08 05 2010 yuche.tsai -+ * NULL -+ * Modify data structure for P2P Scan result. -+ * -+ * 08 03 2010 cp.wu -+ * NULL -+ * newly added P2P API should be declared in header file. -+ * -+ * 07 30 2010 cp.wu -+ * NULL -+ * 1) BoW wrapper: use definitions instead of hard-coded constant for error code -+ * 2) AIS-FSM: eliminate use of desired RF parameters, use prTargetBssDesc instead -+ * 3) add handling for RX_PKT_DESTINATION_HOST_WITH_FORWARD for GO-broadcast frames -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 14 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * saa_fsm.c is migrated. -+ * -+ * 06 14 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add management dispatching function table. -+ * -+ * 06 11 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) migrate assoc.c. -+ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness -+ * 3) add configuration options for CNM_MEM and RSN modules -+ * 4) add data path for management frames -+ * 5) eliminate rPacketInfo of MSDU_INFO_T -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 03 30 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * remove driver-land statistics. -+ * -+ * 03 24 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * generate information for OID_GEN_RCV_OK & OID_GEN_XMIT_OK -+ * * -+ * -+ * 03 11 2010 cp.wu -+ * [WPD00003821][BUG] Host driver stops processing RX packets from HIF RX0 -+ * add RX starvation warning debug message controlled by CFG_HIF_RX_STARVATION_WARNING -+ * -+ * 03 10 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * code clean: removing unused variables and structure definitions -+ * -+ * 02 25 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * correct behavior to prevent duplicated RX handling for RX0_DONE and RX1_DONE -+ * -+ * 02 10 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * implement host-side firmware download logic -+ * -+ * 02 10 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) remove unused function in nic_rx.c [which has been handled in que_mgt.c] -+ * * 2) firmware image length is now retrieved via NdisFileOpen -+ * * 3) firmware image is not structured by (P_IMG_SEC_HDR_T) anymore -+ * * 4) nicRxWaitResponse() revised -+ * * 5) another set of TQ counter default value is added for fw-download state -+ * * 6) Wi-Fi load address is now retrieved from registry too -+ * -+ * 12 30 2009 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) According to CMD/EVENT documentation v0.8, -+ * * * * OID_CUSTOM_TEST_RX_STATUS & OID_CUSTOM_TEST_TX_STATUS is no longer used, -+ * * * * and result is retrieved by get ATInfo instead -+ * * * * 2) add 4 counter for recording aggregation statistics -+** \main\maintrunk.MT6620WiFiDriver_Prj\24 2009-12-10 16:49:09 GMT mtk02752 -+** code clean -+** \main\maintrunk.MT6620WiFiDriver_Prj\23 2009-12-09 14:02:37 GMT MTK02468 -+** Added ucStaRecIdx in SW_RFB_T and HALF_SEQ_NO_COUNT definition (to replace HALF_SEQ_NO_CNOUT) -+** \main\maintrunk.MT6620WiFiDriver_Prj\22 2009-11-27 11:07:54 GMT mtk02752 -+** add flush for reset -+** \main\maintrunk.MT6620WiFiDriver_Prj\21 2009-11-25 18:18:09 GMT mtk02752 -+** modify nicRxAddScanResult() -+** \main\maintrunk.MT6620WiFiDriver_Prj\20 2009-11-24 22:42:22 GMT mtk02752 -+** add nicRxAddScanResult() to prepare to handle SCAN_RESULT event -+** \main\maintrunk.MT6620WiFiDriver_Prj\19 2009-11-24 19:57:06 GMT mtk02752 -+** adopt P_HIF_RX_HEADER_T -+** \main\maintrunk.MT6620WiFiDriver_Prj\18 2009-11-16 21:43:04 GMT mtk02752 -+** correct ENUM_RX_PKT_DESTINATION_T definitions -+** \main\maintrunk.MT6620WiFiDriver_Prj\17 2009-11-16 15:28:25 GMT mtk02752 -+** add ucQueuedPacketNum for indicating how many packet are queued by RX reordering buffer/forwarding path -+** \main\maintrunk.MT6620WiFiDriver_Prj\16 2009-11-16 15:05:01 GMT mtk02752 -+** add eTC for SW_RFB_T and structure RX_MAILBOX -+** \main\maintrunk.MT6620WiFiDriver_Prj\15 2009-11-13 21:16:57 GMT mtk02752 -+** \main\maintrunk.MT6620WiFiDriver_Prj\14 2009-11-13 16:59:30 GMT mtk02752 -+** add handler for event packet -+** \main\maintrunk.MT6620WiFiDriver_Prj\13 2009-11-13 13:45:50 GMT mtk02752 -+** add port param for nicRxEnhanceReadBuffer() -+** \main\maintrunk.MT6620WiFiDriver_Prj\12 2009-11-11 10:12:31 GMT mtk02752 -+** nicSDIOReadIntStatus() always read sizeof(ENHANCE_MODE_DATA_STRUCT_T) for int response, -+** thus the number should be set to 0(:=16) instead of 10 -+** \main\maintrunk.MT6620WiFiDriver_Prj\11 2009-10-29 19:53:32 GMT mtk01084 -+** modify structure naming -+** \main\maintrunk.MT6620WiFiDriver_Prj\10 2009-10-23 16:08:23 GMT mtk01084 -+** \main\maintrunk.MT6620WiFiDriver_Prj\9 2009-10-13 21:59:01 GMT mtk01084 -+** update for new HW architecture design -+** \main\maintrunk.MT6620WiFiDriver_Prj\8 2009-05-20 12:23:33 GMT mtk01461 -+** Add u4MaxEventBufferLen parameter to nicRxWaitResponse() -+** \main\maintrunk.MT6620WiFiDriver_Prj\7 2009-05-18 21:00:48 GMT mtk01426 -+** Update SDIO_MAXIMUM_RX_STATUS value -+** \main\maintrunk.MT6620WiFiDriver_Prj\6 2009-04-28 10:36:15 GMT mtk01461 -+** Remove unused define - SDIO_MAXIMUM_TX_STATUS -+** \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-04-01 10:53:17 GMT mtk01461 -+** Add function for HIF_LOOPBACK_PRE_TEST -+** \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-03-18 20:56:19 GMT mtk01426 -+** Add to support CFG_HIF_LOOPBACK and CFG_SDIO_RX_ENHANCE -+** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-03-17 20:19:56 GMT mtk01426 -+** Add nicRxWaitResponse function proto type -+** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 20:16:35 GMT mtk01426 -+** Init for develop -+** -+*/ -+ -+#ifndef _NIC_RX_H -+#define _NIC_RX_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+extern P_SW_RFB_T g_arGscnResultsTempBuffer[]; -+extern UINT_8 g_GscanResultsTempBufferIndex; -+extern UINT_8 g_arGscanResultsIndicateNumber[]; -+extern UINT_8 g_GetResultsBufferedCnt; -+extern UINT_8 g_GetResultsCmdCnt; -+extern void kalDevLoopbkRxHandle(IN P_ADAPTER_T prAdapter, IN OUT P_SW_RFB_T prSwRfb); -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+#define MAX_SEQ_NO 4095 -+#define MAX_SEQ_NO_COUNT 4096 -+#define HALF_SEQ_NO_CNOUT 2048 -+ -+#define HALF_SEQ_NO_COUNT 2048 -+ -+#define MT6620_FIXED_WIN_SIZE 64 -+#define CFG_RX_MAX_BA_ENTRY 4 -+#define CFG_RX_MAX_BA_TID_NUM 8 -+ -+#define RX_STATUS_FLAG_MORE_PACKET BIT(30) -+#define RX_STATUS_CHKSUM_MASK BITS(0, 10) -+ -+#define RX_RFB_LEN_FIELD_LEN 4 -+#define RX_HEADER_OFFSET 2 -+ -+#define RX_RETURN_INDICATED_RFB_TIMEOUT_SEC 3 -+ -+#if defined(_HIF_SDIO) && defined(WINDOWS_DDK) -+/*! On XP, maximum Tx+Rx Statue <= 64-4(HISR)*/ -+#define SDIO_MAXIMUM_RX_LEN_NUM 0 /*!< 0~15 (0: un-limited) */ -+#else -+#define SDIO_MAXIMUM_RX_LEN_NUM 0 /*!< 0~15 (0: un-limited) */ -+#endif -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+typedef enum _ENUM_RX_STATISTIC_COUNTER_T { -+ RX_MPDU_TOTAL_COUNT = 0, -+ RX_SIZE_ERR_DROP_COUNT, -+ -+ RX_DATA_INDICATION_COUNT, -+ RX_DATA_RETURNED_COUNT, -+ RX_DATA_RETAINED_COUNT, -+ -+ RX_DROP_TOTAL_COUNT, -+ RX_TYPE_ERR_DROP_COUNT, -+ RX_CLASS_ERR_DROP_COUNT, -+ RX_DST_NULL_DROP_COUNT, -+ -+#if CFG_TCP_IP_CHKSUM_OFFLOAD || CFG_TCP_IP_CHKSUM_OFFLOAD_NDIS_60 -+ RX_CSUM_TCP_FAILED_COUNT, -+ RX_CSUM_UDP_FAILED_COUNT, -+ RX_CSUM_IP_FAILED_COUNT, -+ RX_CSUM_TCP_SUCCESS_COUNT, -+ RX_CSUM_UDP_SUCCESS_COUNT, -+ RX_CSUM_IP_SUCCESS_COUNT, -+ RX_CSUM_UNKNOWN_L4_PKT_COUNT, -+ RX_CSUM_UNKNOWN_L3_PKT_COUNT, -+ RX_IP_V6_PKT_CCOUNT, -+#endif -+ RX_STATISTIC_COUNTER_NUM -+} ENUM_RX_STATISTIC_COUNTER_T; -+ -+typedef enum _ENUM_RX_PKT_DESTINATION_T { -+ RX_PKT_DESTINATION_HOST, /* to OS */ -+ RX_PKT_DESTINATION_FORWARD, /* to TX queue for forward, AP mode */ -+ RX_PKT_DESTINATION_HOST_WITH_FORWARD, /* to both TX and OS, AP mode broadcast packet */ -+ RX_PKT_DESTINATION_NULL, /* packet to be freed */ -+ RX_PKT_DESTINATION_NUM -+} ENUM_RX_PKT_DESTINATION_T; -+ -+struct _SW_RFB_T { -+ QUE_ENTRY_T rQueEntry; -+ PVOID pvPacket; /*!< ptr to rx Packet Descriptor */ -+ PUINT_8 pucRecvBuff; /*!< ptr to receive data buffer */ -+ P_HIF_RX_HEADER_T prHifRxHdr; -+ UINT_32 u4HifRxHdrFlag; -+ PVOID pvHeader; -+ UINT_16 u2PacketLen; -+ UINT_16 u2HeaderLen; -+ UINT_16 u2SSN; -+ UINT_8 ucTid; -+ UINT_8 ucWlanIdx; -+ UINT_8 ucPacketType; -+ UINT_8 ucStaRecIdx; -+ -+ ENUM_CSUM_RESULT_T aeCSUM[CSUM_TYPE_NUM]; -+ ENUM_RX_PKT_DESTINATION_T eDst; -+ ENUM_TRAFFIC_CLASS_INDEX_T eTC; /* only valid when eDst == FORWARD */ -+ -+ UINT_64 rRxTime; -+}; -+ -+/*! RX configuration type structure */ -+typedef struct _RX_CTRL_T { -+ UINT_32 u4RxCachedSize; -+ PUINT_8 pucRxCached; -+ QUE_T rFreeSwRfbList; -+ QUE_T rReceivedRfbList; -+ QUE_T rIndicatedRfbList; -+ -+#if CFG_SDIO_RX_AGG -+ PUINT_8 pucRxCoalescingBufPtr; -+#endif -+ -+ PVOID apvIndPacket[CFG_RX_MAX_PKT_NUM]; -+ PVOID apvRetainedPacket[CFG_RX_MAX_PKT_NUM]; -+ -+ UINT_8 ucNumIndPacket; -+ UINT_8 ucNumRetainedPacket; -+ UINT_64 au8Statistics[RX_STATISTIC_COUNTER_NUM]; /*!< RX Counters */ -+ -+#if CFG_HIF_STATISTICS -+ UINT_32 u4TotalRxAccessNum; -+ UINT_32 u4TotalRxPacketNum; -+#endif -+ -+#if CFG_HIF_RX_STARVATION_WARNING -+ UINT_32 u4QueuedCnt; -+ UINT_32 u4DequeuedCnt; -+#endif -+ -+#if CFG_RX_PKTS_DUMP -+ UINT_32 u4RxPktsDumpTypeMask; -+#endif -+ -+} RX_CTRL_T, *P_RX_CTRL_T; -+ -+typedef struct _RX_MAILBOX_T { -+ UINT_32 u4RxMailbox[2]; /* for Device-to-Host Mailbox */ -+} RX_MAILBOX_T, *P_RX_MAILBOX_T; -+ -+typedef WLAN_STATUS(*PROCESS_RX_MGT_FUNCTION) (P_ADAPTER_T, P_SW_RFB_T); -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+#define RX_INC_CNT(prRxCtrl, eCounter) \ -+ {((P_RX_CTRL_T)prRxCtrl)->au8Statistics[eCounter]++; } -+ -+#define RX_ADD_CNT(prRxCtrl, eCounter, u8Amount) \ -+ {((P_RX_CTRL_T)prRxCtrl)->au8Statistics[eCounter] += (UINT_64)u8Amount; } -+ -+#define RX_GET_CNT(prRxCtrl, eCounter) \ -+ (((P_RX_CTRL_T)prRxCtrl)->au8Statistics[eCounter]) -+ -+#define RX_RESET_ALL_CNTS(prRxCtrl) \ -+ {kalMemZero(&prRxCtrl->au8Statistics[0], sizeof(prRxCtrl->au8Statistics)); } -+ -+#define RX_STATUS_TEST_MORE_FLAG(flag) \ -+ ((BOOLEAN)((flag & RX_STATUS_FLAG_MORE_PACKET) ? TRUE : FALSE)) -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+VOID nicRxInitialize(IN P_ADAPTER_T prAdapter); -+ -+VOID nicRxUninitialize(IN P_ADAPTER_T prAdapter); -+ -+VOID nicRxProcessRFBs(IN P_ADAPTER_T prAdapter); -+ -+#if !CFG_SDIO_INTR_ENHANCE -+VOID nicRxReceiveRFBs(IN P_ADAPTER_T prAdapter); -+ -+WLAN_STATUS nicRxReadBuffer(IN P_ADAPTER_T prAdapter, IN OUT P_SW_RFB_T prSwRfb); -+ -+#else -+VOID nicRxSDIOReceiveRFBs(IN P_ADAPTER_T prAdapter); -+ -+WLAN_STATUS -+nicRxEnhanceReadBuffer(IN P_ADAPTER_T prAdapter, -+ IN UINT_32 u4DataPort, IN UINT_16 u2RxLength, IN OUT P_SW_RFB_T prSwRfb); -+#endif /* CFG_SDIO_INTR_ENHANCE */ -+ -+#if CFG_SDIO_RX_AGG -+VOID nicRxSDIOAggReceiveRFBs(IN P_ADAPTER_T prAdapter); -+#endif -+ -+WLAN_STATUS nicRxSetupRFB(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prRfb); -+ -+VOID nicRxReturnRFB(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prRfb); -+ -+VOID nicProcessRxInterrupt(IN P_ADAPTER_T prAdapter); -+ -+VOID nicRxProcessPktWithoutReorder(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); -+ -+VOID nicRxProcessForwardPkt(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); -+ -+VOID nicRxProcessGOBroadcastPkt(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); -+ -+VOID nicRxFillRFB(IN P_ADAPTER_T prAdapter, IN OUT P_SW_RFB_T prSwRfb); -+ -+VOID nicRxProcessDataPacket(IN P_ADAPTER_T prAdapter, IN OUT P_SW_RFB_T prSwRfb); -+ -+VOID nicRxProcessEventPacket(IN P_ADAPTER_T prAdapter, IN OUT P_SW_RFB_T prSwRfb); -+ -+VOID nicRxProcessMgmtPacket(IN P_ADAPTER_T prAdapter, IN OUT P_SW_RFB_T prSwRfb); -+ -+#if CFG_TCP_IP_CHKSUM_OFFLOAD -+VOID nicRxFillChksumStatus(IN P_ADAPTER_T prAdapter, IN OUT P_SW_RFB_T prSwRfb, IN UINT_32 u4TcpUdpIpCksStatus); -+ -+VOID nicRxUpdateCSUMStatistics(IN P_ADAPTER_T prAdapter, IN const ENUM_CSUM_RESULT_T aeCSUM[]); -+#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */ -+ -+VOID nicRxQueryStatus(IN P_ADAPTER_T prAdapter, IN PUINT_8 pucBuffer, OUT PUINT_32 pu4Count); -+ -+VOID nicRxClearStatistics(IN P_ADAPTER_T prAdapter); -+ -+VOID nicRxQueryStatistics(IN P_ADAPTER_T prAdapter, IN PUINT_8 pucBuffer, OUT PUINT_32 pu4Count); -+ -+WLAN_STATUS -+nicRxWaitResponse(IN P_ADAPTER_T prAdapter, -+ IN UINT_8 ucPortIdx, OUT PUINT_8 pucRspBuffer, IN UINT_32 u4MaxRespBufferLen, OUT PUINT_32 pu4Length); -+ -+VOID nicRxEnablePromiscuousMode(IN P_ADAPTER_T prAdapter); -+ -+VOID nicRxDisablePromiscuousMode(IN P_ADAPTER_T prAdapter); -+ -+WLAN_STATUS nicRxFlush(IN P_ADAPTER_T prAdapter); -+ -+WLAN_STATUS nicRxProcessActionFrame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); -+ -+#endif /* _NIC_RX_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/nic_tx.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/nic_tx.h -new file mode 100644 -index 000000000000..e516468fcb16 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/nic_tx.h -@@ -0,0 +1,642 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/nic/nic_tx.h#1 -+*/ -+ -+/*! \file nic_tx.h -+ \brief Functions that provide TX operation in NIC's point of view. -+ -+ This file provides TX functions which are responsible for both Hardware and -+ Software Resource Management and keep their Synchronization. -+ -+*/ -+ -+/* -+** Log: nic_tx.h -+ * -+ * 11 18 2011 eddie.chen -+ * [WCXRP00001096] [MT6620 Wi-Fi][Driver/FW] Enhance the log function (xlog) -+ * Add log counter for tx -+ * -+ * 11 10 2011 eddie.chen -+ * [WCXRP00001096] [MT6620 Wi-Fi][Driver/FW] Enhance the log function (xlog) -+ * Add TX_DONE status detail information. -+ * -+ * 08 15 2011 cp.wu -+ * [WCXRP00000851] [MT6628 Wi-Fi][Driver] Add HIFSYS related definition to driver source tree -+ * add MT6628-specific definitions. -+ * -+ * 04 12 2011 cp.wu -+ * [WCXRP00000631] [MT6620 Wi-Fi][Driver] Add an API for QM to retrieve current TC counter value and processing -+ * frame dropping cases for TC4 path -+ * 1. add nicTxGetResource() API for QM to make decisions. -+ * 2. if management frames is decided by QM for dropping, the call back is invoked to indicate such a case. -+ * -+ * 03 21 2011 cp.wu -+ * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer -+ * portability improvement -+ * -+ * 02 16 2011 cp.wu -+ * [WCXRP00000449] [MT6620 Wi-Fi][Driver] Refine CMD queue handling by adding an extra API for checking -+ * available count and modify behavior -+ * 1. add new API: nicTxGetFreeCmdCount() -+ * 2. when there is insufficient command descriptor, nicTxEnqueueMsdu() will drop command packets directly -+ * -+ * 01 24 2011 cp.wu -+ * [WCXRP00000382] [MT6620 Wi-Fi][Driver] Track forwarding packet number with notifying tx thread for serving -+ * 1. add an extra counter for tracking pending forward frames. -+ * 2. notify TX service thread as well when there is pending forward frame -+ * 3. correct build errors leaded by introduction of Wi-Fi direct separation module -+ * -+ * 12 15 2010 yuche.tsai -+ * NULL -+ * Update SLT Descriptor number configure in driver. -+ * -+ * 11 16 2010 yarco.yang -+ * [WCXRP00000177] [MT5931 F/W] Performance tuning for 1st connection -+ * Update TX buffer count -+ * -+ * 11 03 2010 cp.wu -+ * [WCXRP00000083] [MT5931][Driver][FW] Add necessary logic for MT5931 first connection -+ * 1) use 8 buffers for MT5931 which is equipped with less memory -+ * 2) modify MT5931 debug level to TRACE when download is successful -+ * -+ * 10 18 2010 cp.wu -+ * [WCXRP00000117] [MT6620 Wi-Fi][Driver] Add logic for suspending driver when MT6620 is not responding anymore -+ * 1. when wlanAdapterStop() failed to send POWER CTRL command to firmware, do not poll for ready bit dis-assertion -+ * 2. shorten polling count for shorter response time -+ * 3. if bad I/O operation is detected during TX resource polling, then further operation is aborted as well -+ * -+ * 10 06 2010 cp.wu -+ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning -+ * code reorganization to improve isolation between GLUE and CORE layers. -+ * -+ * 09 03 2010 kevin.huang -+ * NULL -+ * Refine #include sequence and solve recursive/nested #include issue -+ * -+ * 08 30 2010 cp.wu -+ * NULL -+ * API added: nicTxPendingPackets(), for simplifying porting layer -+ * -+ * 07 26 2010 cp.wu -+ * -+ * change TC4 initial value from 2 to 4. -+ * -+ * 07 13 2010 cp.wu -+ * -+ * 1) MMPDUs are now sent to MT6620 by CMD queue for keeping strict order of 1X/MMPDU/CMD packets -+ * 2) integrate with qmGetFrameAction() for deciding which MMPDU/1X could pass checking for sending -+ * 2) enhance CMD_INFO_T descriptor number from 10 to 32 to avoid descriptor underflow under -+ * concurrent network operation -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 07 06 2010 yarco.yang -+ * [WPD00003837][MT6620]Data Path Refine -+ * Add MGMT Packet type for HIF_TX_HEADER -+ * -+ * 06 23 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * integrate . -+ * -+ * 06 21 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * refine TX-DONE callback. -+ * -+ * 06 21 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * TX descriptors are now allocated once for reducing allocation overhead -+ * -+ * 06 21 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * specify correct value for management frames. -+ * -+ * 06 11 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) migrate assoc.c. -+ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness -+ * 3) add configuration options for CNM_MEM and RSN modules -+ * 4) add data path for management frames -+ * 5) eliminate rPacketInfo of MSDU_INFO_T -+ * -+ * 06 10 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) add flag on MSDU_INFO_T for indicating BIP frame and forceBasicRate -+ * 2) add packet type for indicating management frames -+ * -+ * 06 09 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add necessary changes to driver data paths. -+ * -+ * 06 09 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add TX_PACKET_MGMT to indicate the frame is coming from management modules -+ * -+ * 06 07 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * merge wlan_def.h. -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 03 30 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * remove driver-land statistics. -+ * -+ * 03 24 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * generate information for OID_GEN_RCV_OK & OID_GEN_XMIT_OK -+ * * * -+ * -+ * 03 10 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * code clean: removing unused variables and structure definitions -+ * -+ * 03 02 2010 tehuang.liu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * Redistributed the initial TC resources for normal operation -+ * -+ * 03 02 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * add mutex to avoid multiple access to qmTxQueue simultaneously. -+ * -+ * 02 23 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * add new API: wlanProcessQueuedPackets() -+ * -+ * 02 10 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) remove unused function in nic_rx.c [which has been handled in que_mgt.c] -+ * * * 2) firmware image length is now retrieved via NdisFileOpen -+ * * * 3) firmware image is not structured by (P_IMG_SEC_HDR_T) anymore -+ * * * 4) nicRxWaitResponse() revised -+ * * * 5) another set of TQ counter default value is added for fw-download state -+ * * * 6) Wi-Fi load address is now retrieved from registry too -+ * -+ * 02 09 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1. Permanent and current MAC address are now retrieved by CMD/EVENT packets instead of hard-coded address -+ * * * * 2. follow MSDN defined behavior when associates to another AP -+ * * * * 3. for firmware download, packet size could be up to 2048 bytes -+ * -+ * 01 27 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1. eliminate improper variable in rHifInfo -+ * * * * * 2. block TX/ordinary OID when RF test mode is engaged -+ * * * * * 3. wait until firmware finish operation when entering into and leaving from RF test mode -+ * * * * * 4. correct some HAL implementation -+ * -+ * 01 13 2010 tehuang.liu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * Enabled the Burst_End Indication mechanism -+ * -+ * 12 30 2009 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) According to CMD/EVENT documentation v0.8, -+ * * * * * OID_CUSTOM_TEST_RX_STATUS & OID_CUSTOM_TEST_TX_STATUS is no longer used, -+ * * * * * and result is retrieved by get ATInfo instead -+ * * * * * 2) add 4 counter for recording aggregation statistics -+** \main\maintrunk.MT6620WiFiDriver_Prj\24 2009-12-10 16:53:28 GMT mtk02752 -+** remove unused API -+** \main\maintrunk.MT6620WiFiDriver_Prj\23 2009-11-27 11:08:00 GMT mtk02752 -+** add flush for reset -+** \main\maintrunk.MT6620WiFiDriver_Prj\22 2009-11-24 19:56:49 GMT mtk02752 -+** remove redundant eTC -+** \main\maintrunk.MT6620WiFiDriver_Prj\21 2009-11-23 22:01:08 GMT mtk02468 -+** Added MSDU_INFO fields for composing HIF TX header -+** \main\maintrunk.MT6620WiFiDriver_Prj\20 2009-11-17 22:40:51 GMT mtk01084 -+** \main\maintrunk.MT6620WiFiDriver_Prj\19 2009-11-17 17:35:05 GMT mtk02752 -+** + nicTxMsduInfoList() for sending MsduInfoList -+** + NIC_TX_BUFF_COUNT_TC[0~5] -+** \main\maintrunk.MT6620WiFiDriver_Prj\18 2009-11-17 11:07:00 GMT mtk02752 -+** add nicTxAdjustTcq() API -+** \main\maintrunk.MT6620WiFiDriver_Prj\17 2009-11-16 22:28:30 GMT mtk02752 -+** move aucFreeBufferCount/aucMaxNumOfBuffer into another structure -+** \main\maintrunk.MT6620WiFiDriver_Prj\16 2009-11-16 21:44:50 GMT mtk02752 -+** + nicTxReturnMsduInfo() -+** + nicTxFillMsduInfo() -+** + rFreeMsduInfoList field in TX_CTRL -+** \main\maintrunk.MT6620WiFiDriver_Prj\15 2009-11-16 18:00:43 GMT mtk02752 -+** use P_PACKET_INFO_T for prPacket to avoid inventing another new structure for packet -+** \main\maintrunk.MT6620WiFiDriver_Prj\14 2009-11-16 15:28:49 GMT mtk02752 -+** add ucQueuedPacketNum for indicating how many packets are queued by per STA/AC queue -+** \main\maintrunk.MT6620WiFiDriver_Prj\13 2009-11-16 10:52:01 GMT mtk02752 -+** \main\maintrunk.MT6620WiFiDriver_Prj\12 2009-11-14 23:39:24 GMT mtk02752 -+** interface structure redefine -+** \main\maintrunk.MT6620WiFiDriver_Prj\11 2009-11-13 21:17:03 GMT mtk02752 -+** \main\maintrunk.MT6620WiFiDriver_Prj\10 2009-10-29 19:53:10 GMT mtk01084 -+** remove strange code by Frog -+** \main\maintrunk.MT6620WiFiDriver_Prj\9 2009-10-13 21:59:04 GMT mtk01084 -+** update for new HW architecture design -+** \main\maintrunk.MT6620WiFiDriver_Prj\8 2009-10-02 13:53:03 GMT mtk01725 -+** \main\maintrunk.MT6620WiFiDriver_Prj\7 2009-04-28 10:36:50 GMT mtk01461 -+** Add declaration of nicTxReleaseResource() -+** \main\maintrunk.MT6620WiFiDriver_Prj\6 2009-04-17 19:58:39 GMT mtk01461 -+** Move CMD_INFO_T related define and function to cmd_buf.h -+** \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-04-01 10:53:53 GMT mtk01461 -+** Add function for SDIO_TX_ENHANCE -+** \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-03-23 00:33:27 GMT mtk01461 -+** Define constants for TX PATH and add nicTxPollingResource -+** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-03-16 09:09:32 GMT mtk01461 -+** Update TX PATH API -+** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 20:16:38 GMT mtk01426 -+** Init for develop -+** -+*/ -+ -+#ifndef _NIC_TX_H -+#define _NIC_TX_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+#define NIC_TX_RESOURCE_POLLING_TIMEOUT 256 -+#define NIC_TX_RESOURCE_POLLING_DELAY_MSEC 50 -+ -+/* Maximum buffer count for individual HIF TCQ */ -+ -+#if defined(MT6620) -+#if CFG_SLT_SUPPORT -+ /* 20101215 mtk01725 Redistributed the initial TC resources for SLT operation */ -+#define NIC_TX_BUFF_COUNT_TC0 0 /* First connection: 0 */ -+#define NIC_TX_BUFF_COUNT_TC1 16 /* First connection: 32 */ -+#define NIC_TX_BUFF_COUNT_TC2 0 /* First connection: 0 */ -+#define NIC_TX_BUFF_COUNT_TC3 0 /* First connection: 0 */ -+#define NIC_TX_BUFF_COUNT_TC4 4 /* First connection: 2 */ -+#define NIC_TX_BUFF_COUNT_TC5 0 /* First connection: 0 */ -+#else -+ /* 20100302 mtk02468 Redistributed the initial TC resources for normal operation */ -+#define NIC_TX_BUFF_COUNT_TC0 6 /* First connection: 0 */ -+#define NIC_TX_BUFF_COUNT_TC1 8 /* First connection: 32 */ -+#define NIC_TX_BUFF_COUNT_TC2 8 /* First connection: 0 */ -+#define NIC_TX_BUFF_COUNT_TC3 8 /* First connection: 0 */ -+#define NIC_TX_BUFF_COUNT_TC4 4 /* First connection: 2 */ -+#define NIC_TX_BUFF_COUNT_TC5 2 /* First connection: 0 */ -+#endif -+#elif defined(MT6628) -+#if (CFG_SRAM_SIZE_OPTION == 0) -+#define NIC_TX_BUFF_COUNT_TC0 1 /* First connection: 0 */ -+#define NIC_TX_BUFF_COUNT_TC1 20 /* First connection: 32 */ -+#define NIC_TX_BUFF_COUNT_TC2 1 /* First connection: 0 */ -+#define NIC_TX_BUFF_COUNT_TC3 1 /* First connection: 0 */ -+#define NIC_TX_BUFF_COUNT_TC4 4 /* First connection: 2 */ -+#define NIC_TX_BUFF_COUNT_TC5 1 /* First connection: 0 */ -+#elif (CFG_SRAM_SIZE_OPTION == 1) -+#define NIC_TX_BUFF_COUNT_TC0 1 /* First connection: 0 */ -+#define NIC_TX_BUFF_COUNT_TC1 36 /* First connection: 32 */ -+#define NIC_TX_BUFF_COUNT_TC2 1 /* First connection: 0 */ -+#define NIC_TX_BUFF_COUNT_TC3 1 /* First connection: 0 */ -+#define NIC_TX_BUFF_COUNT_TC4 4 /* First connection: 2 */ -+#define NIC_TX_BUFF_COUNT_TC5 1 /* First connection: 0 */ -+#elif (CFG_SRAM_SIZE_OPTION == 2) -+#define NIC_TX_BUFF_COUNT_TC0 1 /* First connection: 0 */ -+#define NIC_TX_BUFF_COUNT_TC1 48 /* First connection: 32 */ -+#define NIC_TX_BUFF_COUNT_TC2 1 /* First connection: 0 */ -+#define NIC_TX_BUFF_COUNT_TC3 1 /* First connection: 0 */ -+#define NIC_TX_BUFF_COUNT_TC4 4 /* First connection: 2 */ -+#define NIC_TX_BUFF_COUNT_TC5 1 /* First connection: 0 */ -+#else -+#error "> Set TX_BUFF_COUNT_TC error!" -+#endif -+#endif -+ -+#define NIC_TX_BUFF_SUM (NIC_TX_BUFF_COUNT_TC0 + \ -+ NIC_TX_BUFF_COUNT_TC1 + \ -+ NIC_TX_BUFF_COUNT_TC2 + \ -+ NIC_TX_BUFF_COUNT_TC3 + \ -+ NIC_TX_BUFF_COUNT_TC4 + \ -+ NIC_TX_BUFF_COUNT_TC5) -+#if CFG_ENABLE_FW_DOWNLOAD -+ -+#define NIC_TX_INIT_BUFF_COUNT_TC0 8 -+#define NIC_TX_INIT_BUFF_COUNT_TC1 0 -+#define NIC_TX_INIT_BUFF_COUNT_TC2 0 -+#define NIC_TX_INIT_BUFF_COUNT_TC3 0 -+#define NIC_TX_INIT_BUFF_COUNT_TC4 0 -+#define NIC_TX_INIT_BUFF_COUNT_TC5 0 -+ -+#define NIC_TX_INIT_BUFF_SUM (NIC_TX_INIT_BUFF_COUNT_TC0 + \ -+ NIC_TX_INIT_BUFF_COUNT_TC1 + \ -+ NIC_TX_INIT_BUFF_COUNT_TC2 + \ -+ NIC_TX_INIT_BUFF_COUNT_TC3 + \ -+ NIC_TX_INIT_BUFF_COUNT_TC4 + \ -+ NIC_TX_INIT_BUFF_COUNT_TC5) -+ -+#endif -+ -+#if CFG_ENABLE_PKT_LIFETIME_PROFILE -+#define NIC_TX_TIME_THRESHOLD 100 /* in unit of ms */ -+#endif -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+/* 3 Session for TX QUEUES */ -+/* The definition in this ENUM is used to categorize packet's Traffic Class according -+ * to the their TID(User Priority). -+ * In order to achieve QoS goal, a particular TC should not block the process of -+ * another packet with different TC. -+ * In current design we will have 5 categories(TCs) of SW resource. -+ */ -+typedef enum _ENUM_TRAFFIC_CLASS_INDEX_T { -+ TC0_INDEX = 0, /* HIF TX0: AC0 packets */ -+ TC1_INDEX, /* HIF TX0: AC1 packets & non-QoS packets */ -+ TC2_INDEX, /* HIF TX0: AC2 packets */ -+ TC3_INDEX, /* HIF TX0: AC3 packets */ -+ TC4_INDEX, /* HIF TX1: Command packets or 802.1x packets */ -+ TC5_INDEX, /* HIF TX0: BMCAST packets */ -+ TC_NUM /* Maximum number of Traffic Classes. */ -+} ENUM_TRAFFIC_CLASS_INDEX_T; -+ -+typedef enum _ENUM_TX_STATISTIC_COUNTER_T { -+ TX_MPDU_TOTAL_COUNT = 0, -+ TX_INACTIVE_BSS_DROP, -+ TX_INACTIVE_STA_DROP, -+ TX_FORWARD_OVERFLOW_DROP, -+ TX_AP_BORADCAST_DROP, -+ TX_STATISTIC_COUNTER_NUM -+} ENUM_TX_STATISTIC_COUNTER_T; -+ -+typedef struct _TX_TCQ_STATUS_T { -+ UINT_8 aucFreeBufferCount[TC_NUM]; -+ UINT_8 aucMaxNumOfBuffer[TC_NUM]; -+} TX_TCQ_STATUS_T, *P_TX_TCQ_STATUS_T; -+ -+typedef struct _TX_TCQ_ADJUST_T { -+ INT_8 acVariation[TC_NUM]; -+} TX_TCQ_ADJUST_T, *P_TX_TCQ_ADJUST_T; -+ -+typedef struct _TX_CTRL_T { -+ UINT_32 u4TxCachedSize; -+ PUINT_8 pucTxCached; -+ -+/* Elements below is classified according to TC (Traffic Class) value. */ -+ -+ TX_TCQ_STATUS_T rTc; -+ -+ PUINT_8 pucTxCoalescingBufPtr; -+ -+ QUE_T rFreeMsduInfoList; -+ -+ /* Management Frame Tracking */ -+ /* number of management frames to be sent */ -+ INT_32 i4TxMgmtPendingNum; -+ -+ /* to tracking management frames need TX done callback */ -+ QUE_T rTxMgmtTxingQueue; -+ -+#if CFG_HIF_STATISTICS -+ UINT_32 u4TotalTxAccessNum; -+ UINT_32 u4TotalTxPacketNum; -+#endif -+ UINT_32 au4Statistics[TX_STATISTIC_COUNTER_NUM]; -+ -+ /* Number to track forwarding frames */ -+ INT_32 i4PendingFwdFrameCount; -+ -+} TX_CTRL_T, *P_TX_CTRL_T; -+ -+typedef enum _ENUM_TX_PACKET_SRC_T { -+ TX_PACKET_OS, -+ TX_PACKET_OS_OID, -+ TX_PACKET_FORWARDING, -+ TX_PACKET_MGMT, -+ TX_PACKET_NUM -+} ENUM_TX_PACKET_SRC_T; -+ -+typedef enum _ENUM_HIF_TX_PACKET_TYPE_T { -+ HIF_TX_PACKET_TYPE_DATA = 0, -+ HIF_TX_PACKET_TYPE_COMMAND, -+ HIF_TX_PACKET_TYPE_HIF_LB, -+ HIF_TX_PACKET_TYPE_MGMT -+} ENUM_HIF_TX_PACKET_TYPE_T, *P_ENUM_HIF_TX_PACKET_TYPE_T; -+ -+typedef enum _ENUM_TX_RESULT_CODE_T { -+ TX_RESULT_SUCCESS = 0, -+ TX_RESULT_LIFE_TIMEOUT, -+ TX_RESULT_RTS_ERROR, -+ TX_RESULT_MPDU_ERROR, -+ TX_RESULT_AGING_TIMEOUT, -+ TX_RESULT_FLUSHED, -+ TX_RESULT_DROPPED_IN_DRIVER = 32, -+ TX_RESULT_NUM -+} ENUM_TX_RESULT_CODE_T, *P_ENUM_TX_RESULT_CODE_T; -+ -+struct _WLAN_CFG_ENTRY_T { -+ UINT_8 aucKey[WLAN_CFG_KEY_LEN_MAX]; -+ UINT_8 aucValue[WLAN_CFG_VALUE_LEN_MAX]; -+ WLAN_CFG_SET_CB pfSetCb; -+ PVOID pPrivate; -+ UINT_32 u4Flags; -+}; -+ -+struct _WLAN_CFG_T { -+ UINT_32 u4WlanCfgEntryNumMax; -+ UINT_32 u4WlanCfgKeyLenMax; -+ UINT_32 u4WlanCfgValueLenMax; -+ WLAN_CFG_ENTRY_T arWlanCfgBuf[WLAN_CFG_ENTRY_NUM_MAX]; -+}; -+ -+/* TX Call Back Function */ -+typedef WLAN_STATUS(*PFN_TX_DONE_HANDLER) (IN P_ADAPTER_T prAdapter, -+ IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus); -+ -+#if CFG_ENABLE_PKT_LIFETIME_PROFILE -+typedef struct _PKT_PROFILE_T { -+ BOOLEAN fgIsValid; -+#if CFG_PRINT_RTP_PROFILE -+ BOOLEAN fgIsPrinted; -+ UINT_16 u2IpSn; -+ UINT_16 u2RtpSn; -+ UINT_8 ucTcxFreeCount; -+#endif -+ OS_SYSTIME rHardXmitArrivalTimestamp; -+ OS_SYSTIME rEnqueueTimestamp; -+ OS_SYSTIME rDequeueTimestamp; -+ OS_SYSTIME rHifTxDoneTimestamp; -+} PKT_PROFILE_T, *P_PKT_PROFILE_T; -+#endif -+ -+/* TX transactions could be divided into 4 kinds: -+ * -+ * 1) 802.1X / Bluetooth-over-Wi-Fi Security Frames -+ * [CMD_INFO_T] - [prPacket] - in skb or NDIS_PACKET form -+ * -+ * 2) MMPDU -+ * [CMD_INFO_T] - [prPacket] - [MSDU_INFO_T] - [prPacket] - direct buffer for frame body -+ * -+ * 3) Command Packets -+ * [CMD_INFO_T] - [pucInfoBuffer] - direct buffer for content of command packet -+ * -+ * 4) Normal data frame -+ * [MSDU_INFO_T] - [prPacket] - in skb or NDIS_PACKET form -+ */ -+ -+/* PS_FORWARDING_TYPE_NON_PS means that the receiving STA is in Active Mode -+* from the perspective of host driver (maybe not synchronized with FW --> SN is needed) -+*/ -+ -+struct _MSDU_INFO_T { -+ QUE_ENTRY_T rQueEntry; -+ P_NATIVE_PACKET prPacket; -+ -+ ENUM_TX_PACKET_SRC_T eSrc; /* specify OS/FORWARD packet */ -+ UINT_8 ucUserPriority; -+ -+ /* For composing HIF TX header */ -+ UINT_8 ucTC; /* Traffic Class: 0~4 (HIF TX0), 5 (HIF TX1) */ -+ UINT_8 ucPacketType; /* 0: Data, 1: Command, 2: HIF Loopback 3: Management Frame */ -+ UINT_8 ucStaRecIndex; -+ UINT_8 ucNetworkType; /* See ENUM_NETWORK_TYPE_T */ -+ UINT_8 ucFormatID; /* 0: MAUI, Linux, Windows NDIS 5.1 */ -+ BOOLEAN fgIs802_1x; /* TRUE: 802.1x frame */ -+ BOOLEAN fgIs802_11; /* TRUE: 802.11 header is present */ -+ UINT_16 u2PalLLH; /* PAL Logical Link Header (for BOW network) */ -+ UINT_16 u2AclSN; /* ACL Sequence Number (for BOW network) */ -+ UINT_8 ucPsForwardingType; /* See ENUM_PS_FORWARDING_TYPE_T */ -+ UINT_8 ucPsSessionID; /* PS Session ID specified by the FW for the STA */ -+ BOOLEAN fgIsBurstEnd; /* TRUE means this is the last packet of the burst for (STA, TID) */ -+ BOOLEAN fgIsBIP; /* Management Frame Protection */ -+ BOOLEAN fgIsBasicRate; /* Force Basic Rate Transmission */ -+ -+ /* flattened from PACKET_INFO_T */ -+ UINT_8 ucMacHeaderLength; -+ UINT_8 ucLlcLength; /* w/o EtherType */ -+ UINT_16 u2FrameLength; -+ UINT_8 aucEthDestAddr[MAC_ADDR_LEN]; /* Ethernet Destination Address */ -+ -+ /* for TX done tracking */ -+ UINT_8 ucTxSeqNum; -+ PFN_TX_DONE_HANDLER pfTxDoneHandler; -+ BOOLEAN fgNeedTxDoneStatus; -+ -+#if CFG_ENABLE_PKT_LIFETIME_PROFILE -+ PKT_PROFILE_T rPktProfile; -+#endif -+ COMMAND_TYPE eCmdType; -+ UINT_8 ucCID; -+ UINT_32 u4InqueTime; -+}; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+#define TX_INC_CNT(prTxCtrl, eCounter) \ -+ {((P_TX_CTRL_T)prTxCtrl)->au4Statistics[eCounter]++; } -+ -+#define TX_ADD_CNT(prTxCtrl, eCounter, u8Amount) \ -+ {((P_TX_CTRL_T)prTxCtrl)->au4Statistics[eCounter] += (UINT_32)u8Amount; } -+ -+#define TX_GET_CNT(prTxCtrl, eCounter) \ -+ (((P_TX_CTRL_T)prTxCtrl)->au4Statistics[eCounter]) -+ -+#define TX_RESET_ALL_CNTS(prTxCtrl) \ -+ {kalMemZero(&prTxCtrl->au4Statistics[0], sizeof(prTxCtrl->au4Statistics)); } -+ -+#if CFG_ENABLE_PKT_LIFETIME_PROFILE -+#define PRINT_PKT_PROFILE(_pkt_profile, _note) \ -+{ \ -+ if (!(_pkt_profile)->fgIsPrinted) { \ -+ DBGLOG(TX, TRACE, "X[%u] E[%u] D[%u] HD[%u] B[%d] RTP[%d] %s\n", \ -+ (UINT_32)((_pkt_profile)->rHardXmitArrivalTimestamp), \ -+ (UINT_32)((_pkt_profile)->rEnqueueTimestamp), \ -+ (UINT_32)((_pkt_profile)->rDequeueTimestamp), \ -+ (UINT_32)((_pkt_profile)->rHifTxDoneTimestamp), \ -+ (UINT_8)((_pkt_profile)->ucTcxFreeCount), \ -+ (UINT_16)((_pkt_profile)->u2RtpSn), \ -+ (_note)); \ -+ (_pkt_profile)->fgIsPrinted = TRUE; \ -+ } \ -+} -+ -+#define CHK_PROFILES_DELTA(_pkt1, _pkt2, _delta) \ -+ (CHECK_FOR_TIMEOUT((_pkt1)->rHardXmitArrivalTimestamp, (_pkt2)->rHardXmitArrivalTimestamp, (_delta)) || \ -+ CHECK_FOR_TIMEOUT((_pkt1)->rEnqueueTimestamp, (_pkt2)->rEnqueueTimestamp, (_delta)) || \ -+ CHECK_FOR_TIMEOUT((_pkt1)->rDequeueTimestamp, (_pkt2)->rDequeueTimestamp, (_delta)) || \ -+ CHECK_FOR_TIMEOUT((_pkt1)->rHifTxDoneTimestamp, (_pkt2)->rHifTxDoneTimestamp, (_delta))) -+ -+#define CHK_PROFILE_DELTA(_pkt, _delta) \ -+ (CHECK_FOR_TIMEOUT((_pkt)->rEnqueueTimestamp, (_pkt)->rHardXmitArrivalTimestamp, (_delta)) || \ -+ CHECK_FOR_TIMEOUT((_pkt)->rDequeueTimestamp, (_pkt)->rEnqueueTimestamp, (_delta)) || \ -+ CHECK_FOR_TIMEOUT((_pkt)->rHifTxDoneTimestamp, (_pkt)->rDequeueTimestamp, (_delta))) -+#endif -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+VOID nicTxInitialize(IN P_ADAPTER_T prAdapter); -+ -+WLAN_STATUS nicTxAcquireResource(IN P_ADAPTER_T prAdapter, IN UINT_8 ucTC, IN BOOLEAN pfgIsSecOrMgmt); -+ -+WLAN_STATUS nicTxPollingResource(IN P_ADAPTER_T prAdapter, IN UINT_8 ucTC); -+ -+BOOLEAN nicTxReleaseResource(IN P_ADAPTER_T prAdapter, IN UINT_8 *aucTxRlsCnt); -+ -+WLAN_STATUS nicTxResetResource(IN P_ADAPTER_T prAdapter); -+ -+UINT_8 nicTxGetResource(IN P_ADAPTER_T prAdapter, IN UINT_8 ucTC); -+ -+WLAN_STATUS nicTxMsduInfoList(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfoListHead); -+ -+WLAN_STATUS nicTxMsduQueue(IN P_ADAPTER_T prAdapter, UINT_8 ucPortIdx, P_QUE_T prQue); -+ -+WLAN_STATUS nicTxCmd(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN UINT_8 ucTC); -+ -+VOID nicTxRelease(IN P_ADAPTER_T prAdapter); -+ -+VOID nicProcessTxInterrupt(IN P_ADAPTER_T prAdapter); -+ -+VOID nicTxFreeMsduInfoPacket(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfoListHead); -+ -+VOID nicTxReturnMsduInfo(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfoListHead); -+ -+BOOLEAN nicTxFillMsduInfo(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo, IN P_NATIVE_PACKET prNdisPacket); -+ -+WLAN_STATUS nicTxAdjustTcq(IN P_ADAPTER_T prAdapter); -+ -+WLAN_STATUS nicTxFlush(IN P_ADAPTER_T prAdapter); -+ -+#if CFG_ENABLE_FW_DOWNLOAD -+WLAN_STATUS nicTxInitCmd(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN UINT_8 ucTC); -+ -+WLAN_STATUS nicTxInitResetResource(IN P_ADAPTER_T prAdapter); -+#endif -+ -+WLAN_STATUS nicTxEnqueueMsdu(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); -+ -+UINT_32 nicTxGetFreeCmdCount(IN P_ADAPTER_T prAdapter); -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif /* _NIC_TX_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/p2p.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/p2p.h -new file mode 100644 -index 000000000000..d518aaf10eb5 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/p2p.h -@@ -0,0 +1,192 @@ -+/* -+** Id: //Department/DaVinci/TRUNK/WiFi_P2P_Driver/include/nic/p2p.h#3 -+*/ -+ -+/* -+** Log: p2p.h -+ * -+ * 07 17 2012 yuche.tsai -+ * NULL -+ * Compile no error before trial run. -+ * -+ * 10 20 2010 wh.su -+ * [WCXRP00000124] [MT6620 Wi-Fi] [Driver] Support the dissolve P2P Group -+ * Add the code to support disconnect p2p group -+ * -+ * 09 21 2010 kevin.huang -+ * [WCXRP00000054] [MT6620 Wi-Fi][Driver] Restructure driver for second Interface -+ * Isolate P2P related function for Hardware Software Bundle -+ * -+ * 08 03 2010 cp.wu -+ * NULL -+ * [Wi-Fi Direct] add framework for driver hooks -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 23 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * p2p interface revised to be sync. with HAL -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 05 18 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * add parameter to control: -+ * 1) auto group owner -+ * 2) P2P-PS parameter (CTWindow, NoA descriptors) -+ * -+ * 05 18 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * correct WPS Device Password ID definition. -+ * -+ * 05 17 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * implement get scan result. -+ * -+ * 05 17 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * add basic handling framework for wireless extension ioctls. -+ * -+ * 05 14 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * add ioctl framework for Wi-Fi Direct by reusing wireless extension ioctls as well -+ * -+ * 05 11 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * p2p ioctls revised. -+ * -+ * 05 10 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * implement basic wi-fi direct framework -+ * -+ * 05 07 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * add basic framework for implementating P2P driver hook. -+ * -+ * -+*/ -+ -+#ifndef _P2P_H -+#define _P2P_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/* refer to 'Config Methods' in WPS */ -+#define WPS_CONFIG_USBA 0x0001 -+#define WPS_CONFIG_ETHERNET 0x0002 -+#define WPS_CONFIG_LABEL 0x0004 -+#define WPS_CONFIG_DISPLAY 0x0008 -+#define WPS_CONFIG_EXT_NFC 0x0010 -+#define WPS_CONFIG_INT_NFC 0x0020 -+#define WPS_CONFIG_NFC 0x0040 -+#define WPS_CONFIG_PBC 0x0080 -+#define WPS_CONFIG_KEYPAD 0x0100 -+ -+/* refer to 'Device Password ID' in WPS */ -+#define WPS_DEV_PASSWORD_ID_PIN 0x0000 -+#define WPS_DEV_PASSWORD_ID_USER 0x0001 -+#define WPS_DEV_PASSWORD_ID_MACHINE 0x0002 -+#define WPS_DEV_PASSWORD_ID_REKEY 0x0003 -+#define WPS_DEV_PASSWORD_ID_PUSHBUTTON 0x0004 -+#define WPS_DEV_PASSWORD_ID_REGISTRAR 0x0005 -+ -+#define P2P_DEVICE_TYPE_NUM 2 -+#define P2P_DEVICE_NAME_LENGTH 32 -+#define P2P_NETWORK_NUM 8 -+#define P2P_MEMBER_NUM 8 -+ -+#define P2P_WILDCARD_SSID "DIRECT-" -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+struct _P2P_INFO_T { -+ UINT_32 u4DeviceNum; -+ EVENT_P2P_DEV_DISCOVER_RESULT_T arP2pDiscoverResult[CFG_MAX_NUM_BSS_LIST]; -+ PUINT_8 pucCurrIePtr; -+ UINT_8 aucCommIePool[CFG_MAX_COMMON_IE_BUF_LEN]; /* A common pool for IE of all scan results. */ -+}; -+ -+typedef enum { -+ ENUM_P2P_PEER_GROUP, -+ ENUM_P2P_PEER_DEVICE, -+ ENUM_P2P_PEER_NUM -+} ENUM_P2P_PEER_TYPE, *P_ENUM_P2P_PEER_TYPE; -+ -+typedef struct _P2P_DEVICE_INFO { -+ UINT_8 aucDevAddr[PARAM_MAC_ADDR_LEN]; -+ UINT_8 aucIfAddr[PARAM_MAC_ADDR_LEN]; -+ UINT_8 ucDevCapabilityBitmap; -+ INT_32 i4ConfigMethod; -+ UINT_8 aucPrimaryDeviceType[8]; -+ UINT_8 aucSecondaryDeviceType[8]; -+ UINT_8 aucDeviceName[P2P_DEVICE_NAME_LENGTH]; -+} P2P_DEVICE_INFO, *P_P2P_DEVICE_INFO; -+ -+typedef struct _P2P_GROUP_INFO { -+ PARAM_SSID_T rGroupID; -+ P2P_DEVICE_INFO rGroupOwnerInfo; -+ UINT_8 ucMemberNum; -+ P2P_DEVICE_INFO arMemberInfo[P2P_MEMBER_NUM]; -+} P2P_GROUP_INFO, *P_P2P_GROUP_INFO; -+ -+typedef struct _P2P_NETWORK_INFO { -+ ENUM_P2P_PEER_TYPE eNodeType; -+ -+ union { -+ P2P_GROUP_INFO rGroupInfo; -+ P2P_DEVICE_INFO rDeviceInfo; -+ } node; -+ -+} P2P_NETWORK_INFO, *P_P2P_NETWORK_INFO; -+ -+typedef struct _P2P_NETWORK_LIST { -+ UINT_8 ucNetworkNum; -+ P2P_NETWORK_INFO rP2PNetworkInfo[P2P_NETWORK_NUM]; -+} P2P_NETWORK_LIST, *P_P2P_NETWORK_LIST; -+ -+typedef struct _P2P_DISCONNECT_INFO { -+ UINT_8 ucRole; -+ UINT_8 ucRsv[3]; -+} P2P_DISCONNECT_INFO, *P_P2P_DISCONNECT_INFO; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+#endif /*_P2P_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/p2p_cmd_buf.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/p2p_cmd_buf.h -new file mode 100644 -index 000000000000..7f7a92584c7c ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/p2p_cmd_buf.h -@@ -0,0 +1,83 @@ -+/* -+** Id: -+*/ -+ -+/*! \file "p2p_cmd_buf.h" -+ \brief In this file we define the structure for Command Packet. -+ -+ In this file we define the structure for Command Packet and the control unit -+ of MGMT Memory Pool. -+*/ -+ -+/* -+** Log: p2p_cmd_buf.h -+ * -+ * 07 17 2012 yuche.tsai -+ * NULL -+ * Compile no error before trial run. -+ * -+ * 12 22 2010 cp.wu -+ * [WCXRP00000283] [MT6620 Wi-Fi][Driver][Wi-Fi Direct] Implementation of interface -+ * for supporting Wi-Fi Direct Service Discovery -+ * 1. header file restructure for more clear module isolation -+ * 2. add function interface definition for implementing Service Discovery callbacks -+*/ -+ -+#ifndef _P2P_CMD_BUF_H -+#define _P2P_CMD_BUF_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/*--------------------------------------------------------------*/ -+/* Firmware Command Packer */ -+/*--------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSendSetQueryP2PCmd(IN P_ADAPTER_T prAdapter, -+ UINT_8 ucCID, -+ BOOLEAN fgSetQuery, -+ BOOLEAN fgNeedResp, -+ BOOLEAN fgIsOid, -+ PFN_CMD_DONE_HANDLER pfCmdDoneHandler, -+ PFN_CMD_TIMEOUT_HANDLER pfCmdTimeoutHandler, -+ UINT_32 u4SetQueryInfoLen, -+ PUINT_8 pucInfoBuffer, OUT PVOID pvSetQueryBuffer, IN UINT_32 u4SetQueryBufferLen); -+ -+#endif /* _P2P_CMD_BUF_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/p2p_mac.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/p2p_mac.h -new file mode 100644 -index 000000000000..76115dabe1a1 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/p2p_mac.h -@@ -0,0 +1,207 @@ -+/* -+** Id: //Department/DaVinci/TRUNK/WiFi_P2P_Driver/include/nic/p2p_mac.h#2 -+*/ -+ -+/*! \file "p2p_mac.h" -+ \brief Brief description. -+ -+ Detail description. -+*/ -+ -+#ifndef _P2P_MAC_H -+#define _P2P_MAC_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+#define ACTION_PUBLIC_WIFI_DIRECT 9 -+#define ACTION_GAS_INITIAL_REQUEST 10 -+#define ACTION_GAS_INITIAL_RESPONSE 11 -+#define ACTION_GAS_COMEBACK_REQUEST 12 -+#define ACTION_GAS_COMEBACK_RESPONSE 13 -+ -+/* P2P 4.2.8.1 - P2P Public Action Frame Type. */ -+#define P2P_PUBLIC_ACTION_GO_NEGO_REQ 0 -+#define P2P_PUBLIC_ACTION_GO_NEGO_RSP 1 -+#define P2P_PUBLIC_ACTION_GO_NEGO_CFM 2 -+#define P2P_PUBLIC_ACTION_INVITATION_REQ 3 -+#define P2P_PUBLIC_ACTION_INVITATION_RSP 4 -+#define P2P_PUBLIC_ACTION_DEV_DISCOVER_REQ 5 -+#define P2P_PUBLIC_ACTION_DEV_DISCOVER_RSP 6 -+#define P2P_PUBLIC_ACTION_PROV_DISCOVERY_REQ 7 -+#define P2P_PUBLIC_ACTION_PROV_DISCOVERY_RSP 8 -+ -+/* P2P 4.2.9.1 - P2P Action Frame Type */ -+#define P2P_ACTION_NOTICE_OF_ABSENCE 0 -+#define P2P_ACTION_P2P_PRESENCE_REQ 1 -+#define P2P_ACTION_P2P_PRESENCE_RSP 2 -+#define P2P_ACTION_GO_DISCOVER_REQ 3 -+ -+#define P2P_PUBLIC_ACTION_FRAME_LEN (WLAN_MAC_MGMT_HEADER_LEN+8) -+#define P2P_ACTION_FRAME_LEN (WLAN_MAC_MGMT_HEADER_LEN+7) -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/* P2P 4.2.8.2 P2P Public Action Frame Format */ -+typedef struct _P2P_PUBLIC_ACTION_FRAME_T { -+ /* MAC header */ -+ UINT_16 u2FrameCtrl; /* Frame Control */ -+ UINT_16 u2Duration; /* Duration */ -+ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ -+ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ -+ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ -+ UINT_16 u2SeqCtrl; /* Sequence Control */ -+ /* P2P Public Action Frame Body */ -+ UINT_8 ucCategory; /* Category, 0x04 */ -+ UINT_8 ucAction; /* Action Value, 0x09 */ -+ UINT_8 aucOui[3]; /* 0x50, 0x6F, 0x9A */ -+ UINT_8 ucOuiType; /* 0x09 */ -+ UINT_8 ucOuiSubtype; /* GO Nego Req/Rsp/Cfm, P2P Invittion Req/Rsp, Device Discoverability Req/Rsp */ -+ UINT_8 ucDialogToken; /* Dialog Token. */ -+ UINT_8 aucInfoElem[1]; /* P2P IE, WSC IE. */ -+} __KAL_ATTRIB_PACKED__ P2P_PUBLIC_ACTION_FRAME_T, *P_P2P_PUBLIC_ACTION_FRAME_T; -+ -+/* P2P 4.2.9.1 - General Action Frame Format. */ -+typedef struct _P2P_ACTION_FRAME_T { -+ /* MAC header */ -+ UINT_16 u2FrameCtrl; /* Frame Control */ -+ UINT_16 u2Duration; /* Duration */ -+ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ -+ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ -+ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ -+ UINT_16 u2SeqCtrl; /* Sequence Control */ -+ /* P2P Action Frame Body */ -+ UINT_8 ucCategory; /* 0x7F */ -+ UINT_8 aucOui[3]; /* 0x50, 0x6F, 0x9A */ -+ UINT_8 ucOuiType; /* 0x09 */ -+ UINT_8 ucOuiSubtype; /* */ -+ UINT_8 ucDialogToken; -+ UINT_8 aucInfoElem[1]; -+} __KAL_ATTRIB_PACKED__ P2P_ACTION_FRAME_T, *P_P2P_ACTION_FRAME_T; -+ -+/* P2P C.1 GAS Public Action Initial Request Frame Format */ -+typedef struct _GAS_PUBLIC_ACTION_INITIAL_REQUEST_FRAME_T { -+ /* MAC header */ -+ UINT_16 u2FrameCtrl; /* Frame Control */ -+ UINT_16 u2Duration; /* Duration */ -+ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ -+ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ -+ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ -+ UINT_16 u2SeqCtrl; /* Sequence Control */ -+ /* P2P Public Action Frame Body */ -+ UINT_8 ucCategory; /* Category, 0x04 */ -+ UINT_8 ucAction; /* Action Value, 0x09 */ -+ UINT_8 ucDialogToken; /* Dialog Token. */ -+ UINT_8 aucInfoElem[1]; /* Advertisement IE. */ -+} __KAL_ATTRIB_PACKED__ GAS_PUBLIC_ACTION_INITIAL_REQUEST_FRAME_T, *P_GAS_PUBLIC_ACTION_INITIAL_REQUEST_FRAME_T; -+ -+/* P2P C.2 GAS Public Action Initial Response Frame Format */ -+typedef struct _GAS_PUBLIC_ACTION_INITIAL_RESPONSE_FRAME_T { -+ /* MAC header */ -+ UINT_16 u2FrameCtrl; /* Frame Control */ -+ UINT_16 u2Duration; /* Duration */ -+ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ -+ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ -+ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ -+ UINT_16 u2SeqCtrl; /* Sequence Control */ -+ /* P2P Public Action Frame Body */ -+ UINT_8 ucCategory; /* Category, 0x04 */ -+ UINT_8 ucAction; /* Action Value, 0x09 */ -+ UINT_8 ucDialogToken; /* Dialog Token. */ -+ UINT_16 u2StatusCode; /* Initial Response. */ -+ UINT_16 u2ComebackDelay; /* Initial Response. *//* In unit of TU. */ -+ UINT_8 aucInfoElem[1]; /* Advertisement IE. */ -+} __KAL_ATTRIB_PACKED__ GAS_PUBLIC_ACTION_INITIAL_RESPONSE_FRAME_T, *P_GAS_PUBLIC_ACTION_INITIAL_RESPONSE_FRAME_T; -+ -+/* P2P C.3-1 GAS Public Action Comeback Request Frame Format */ -+typedef struct _GAS_PUBLIC_ACTION_COMEBACK_REQUEST_FRAME_T { -+ /* MAC header */ -+ UINT_16 u2FrameCtrl; /* Frame Control */ -+ UINT_16 u2Duration; /* Duration */ -+ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ -+ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ -+ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ -+ UINT_16 u2SeqCtrl; /* Sequence Control */ -+ /* P2P Public Action Frame Body */ -+ UINT_8 ucCategory; /* Category, 0x04 */ -+ UINT_8 ucAction; /* Action Value, 0x09 */ -+ UINT_8 ucDialogToken; /* Dialog Token. */ -+} __KAL_ATTRIB_PACKED__ GAS_PUBLIC_ACTION_COMEBACK_REQUEST_FRAME_T, *P_GAS_PUBLIC_ACTION_COMEBACK_REQUEST_FRAME_T; -+ -+/* P2P C.3-2 GAS Public Action Comeback Response Frame Format */ -+typedef struct _GAS_PUBLIC_ACTION_COMEBACK_RESPONSE_FRAME_T { -+ /* MAC header */ -+ UINT_16 u2FrameCtrl; /* Frame Control */ -+ UINT_16 u2Duration; /* Duration */ -+ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ -+ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ -+ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ -+ UINT_16 u2SeqCtrl; /* Sequence Control */ -+ /* P2P Public Action Frame Body */ -+ UINT_8 ucCategory; /* Category, 0x04 */ -+ UINT_8 ucAction; /* Action Value, 0x09 */ -+ UINT_8 ucDialogToken; /* Dialog Token. */ -+ UINT_16 u2StatusCode; /* Comeback Response. */ -+ UINT_8 ucFragmentID; /*Comeback Response. */ -+ UINT_16 u2ComebackDelay; /* Comeback Response. */ -+ UINT_8 aucInfoElem[1]; /* Advertisement IE. */ -+} __KAL_ATTRIB_PACKED__ GAS_PUBLIC_ACTION_COMEBACK_RESPONSE_FRAME_T, *P_GAS_PUBLIC_ACTION_COMEBACK_RESPONSE_FRAME_T; -+ -+typedef struct _P2P_SD_VENDER_SPECIFIC_CONTENT_T { -+ /* Service Discovery Vendor-specific Content. */ -+ UINT_8 ucOuiSubtype; /* 0x09 */ -+ UINT_16 u2ServiceUpdateIndicator; -+ UINT_8 aucServiceTLV[1]; -+} __KAL_ATTRIB_PACKED__ P2P_SD_VENDER_SPECIFIC_CONTENT_T, *P_P2P_SD_VENDER_SPECIFIC_CONTENT_T; -+ -+typedef struct _P2P_SERVICE_REQUEST_TLV_T { -+ UINT_16 u2Length; -+ UINT_8 ucServiceProtocolType; -+ UINT_8 ucServiceTransID; -+ UINT_8 aucQueryData[1]; -+} __KAL_ATTRIB_PACKED__ P2P_SERVICE_REQUEST_TLV_T, *P_P2P_SERVICE_REQUEST_TLV_T; -+ -+typedef struct _P2P_SERVICE_RESPONSE_TLV_T { -+ UINT_16 u2Length; -+ UINT_8 ucServiceProtocolType; -+ UINT_8 ucServiceTransID; -+ UINT_8 ucStatusCode; -+ UINT_8 aucResponseData[1]; -+} __KAL_ATTRIB_PACKED__ P2P_SERVICE_RESPONSE_TLV_T, *P_P2P_SERVICE_RESPONSE_TLV_T; -+ -+#endif -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/p2p_nic.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/p2p_nic.h -new file mode 100644 -index 000000000000..0a87bd457a92 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/p2p_nic.h -@@ -0,0 +1,62 @@ -+/* -+** Id: //Department/DaVinci/TRUNK/WiFi_P2P_Driver/include/nic/p2p_nic.h#1 -+*/ -+ -+/*! \file "p2p_nic.h" -+ \brief The declaration of nic functions -+ -+ Detail description. -+*/ -+ -+#ifndef _P2P_NIC_H -+#define _P2P_NIC_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+VOID -+nicP2pMediaStateChange(IN P_ADAPTER_T prAdapter, -+ IN ENUM_NETWORK_TYPE_INDEX_T eNetworkType, IN P_EVENT_CONNECTION_STATUS prConnectionStatus); -+ -+VOID -+nicRxAddP2pDevice(IN P_ADAPTER_T prAdapter, -+ IN P_EVENT_P2P_DEV_DISCOVER_RESULT_T prP2pResult, IN PUINT_8 pucRxIEBuf, IN UINT_16 u2RxIELength); -+ -+#endif -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/p2p_nic_cmd_event.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/p2p_nic_cmd_event.h -new file mode 100644 -index 000000000000..cea77414ce35 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/p2p_nic_cmd_event.h -@@ -0,0 +1,70 @@ -+/* -+** Id: //Department/DaVinci/TRUNK/WiFi_P2P_Driver/include/nic/p2p_nic_cmd_event.h#1 -+*/ -+ -+/*! \file p2p_nic_cmd_event.h -+ \brief -+*/ -+ -+#ifndef _P2P_NIC_CMD_EVENT_H -+#define _P2P_NIC_CMD_EVENT_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+typedef struct _EVENT_P2P_DEV_DISCOVER_RESULT_T { -+/* UINT_8 aucCommunicateAddr[MAC_ADDR_LEN]; // Deprecated. */ -+ UINT_8 aucDeviceAddr[MAC_ADDR_LEN]; /* Device Address. */ -+ UINT_8 aucInterfaceAddr[MAC_ADDR_LEN]; /* Device Address. */ -+ UINT_8 ucDeviceCapabilityBitmap; -+ UINT_8 ucGroupCapabilityBitmap; -+ UINT_16 u2ConfigMethod; /* Configure Method. */ -+ P2P_DEVICE_TYPE_T rPriDevType; -+ UINT_8 ucSecDevTypeNum; -+ P2P_DEVICE_TYPE_T arSecDevType[2]; -+ UINT_16 u2NameLength; -+ UINT_8 aucName[32]; -+ PUINT_8 pucIeBuf; -+ UINT_16 u2IELength; -+ UINT_8 aucBSSID[MAC_ADDR_LEN]; -+ /* TODO: Service Information or PasswordID valid? */ -+} EVENT_P2P_DEV_DISCOVER_RESULT_T, *P_EVENT_P2P_DEV_DISCOVER_RESULT_T; -+ -+#endif -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/que_mgt.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/que_mgt.h -new file mode 100644 -index 000000000000..dbfb90d94ee4 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/que_mgt.h -@@ -0,0 +1,971 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/nic/que_mgt.h#1 -+*/ -+ -+/*! \file "que_mgt.h" -+ \brief TX/RX queues management header file -+ -+ The main tasks of queue management include TC-based HIF TX flow control, -+ adaptive TC quota adjustment, HIF TX grant scheduling, Power-Save -+ forwarding control, RX packet reordering, and RX BA agreement management. -+*/ -+ -+/* -+** Log: que_mgt.h -+ * -+ * 08 15 2011 cp.wu -+ * [WCXRP00000851] [MT6628 Wi-Fi][Driver] Add HIFSYS related definition to driver source tree -+ * add MT6628-specific definitions. -+ * -+ * 07 26 2011 eddie.chen -+ * [WCXRP00000874] [MT5931][DRV] API for query the RX reorder queued packets counter -+ * API for query the RX reorder queued packets counter. -+ * -+ * 06 14 2011 eddie.chen -+ * [WCXRP00000753] [MT5931 Wi-Fi][DRV] Adjust QM for MT5931 -+ * Change the parameter for WMM pass. -+ * -+ * 05 31 2011 eddie.chen -+ * [WCXRP00000753] [MT5931 Wi-Fi][DRV] Adjust QM for MT5931 -+ * Fix the QM quota in MT5931. -+ * -+ * 05 09 2011 eddie.chen -+ * [WCXRP00000709] [MT6620 Wi-Fi][Driver] Check free number before copying broadcast packet -+ * Check free number before copying broadcast packet. -+ * -+ * 04 14 2011 eddie.chen -+ * [WCXRP00000603] [MT6620 Wi-Fi][DRV] Fix Klocwork warning -+ * Check the SW RFB free. Fix the compile warning.. -+ * -+ * 04 08 2011 eddie.chen -+ * [WCXRP00000617] [MT6620 Wi-Fi][DRV/FW] Fix for sigma -+ * Fix for sigma -+ * -+ * 03 28 2011 eddie.chen -+ * [WCXRP00000602] [MT6620 Wi-Fi][DRV] Fix wmm parameters in beacon for BOW -+ * Fix wmm parameters in beacon for BOW. -+ * -+ * 03 15 2011 eddie.chen -+ * [WCXRP00000554] [MT6620 Wi-Fi][DRV] Add sw control debug counter -+ * Add sw debug counter for QM. -+ * -+ * 02 17 2011 eddie.chen -+ * [WCXRP00000458] [MT6620 Wi-Fi][Driver] BOW Concurrent - ProbeResp was exist in other channel -+ * 1) Change GetFrameAction decision when BSS is absent. -+ * 2) Check channel and resource in processing ProbeRequest -+ * -+ * 01 12 2011 eddie.chen -+ * [WCXRP00000322] Add WMM IE in beacon, -+ -+Add per station flow control when STA is in PS -+ -+ * 1) Check Bss if support QoS before adding WMMIE -+ * 2) Check if support prAdapter->rWifiVar QoS and uapsd in flow control -+ * -+ * 12 29 2010 eddie.chen -+ * [WCXRP00000322] Add WMM IE in beacon, -+ -+Add per station flow control when STA is in PS -+ -+ * 1) PS flow control event -+ * -+ * 2) WMM IE in beacon, assoc resp, probe resp -+ * -+ * 12 23 2010 george.huang -+ * [WCXRP00000152] [MT6620 Wi-Fi] AP mode power saving function -+ * 1. update WMM IE parsing, with ASSOC REQ handling -+ * 2. extend U-APSD parameter passing from driver to FW -+ * -+ * 10 04 2010 cp.wu -+ * [WCXRP00000077] [MT6620 Wi-Fi][Driver][FW] Eliminate use of ENUM_NETWORK_TYPE_T -+ * and replaced by ENUM_NETWORK_TYPE_INDEX_T only remove ENUM_NETWORK_TYPE_T definitions -+ * -+ * 09 21 2010 kevin.huang -+ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning -+ * Eliminate Linux Compile Warning -+ * -+ * 08 04 2010 yarco.yang -+ * NULL -+ * Add TX_AMPDU and ADDBA_REJECT command -+ * -+ * 07 22 2010 george.huang -+ * -+ * Update fgIsQoS information in BSS INFO by CMD -+ * -+ * 07 16 2010 yarco.yang -+ * -+ * 1. Support BSS Absence/Presence Event -+ * 2. Support STA change PS mode Event -+ * 3. Support BMC forwarding for AP mode. -+ * -+ * 07 14 2010 yarco.yang -+ * -+ * 1. Remove CFG_MQM_MIGRATION -+ * 2. Add CMD_UPDATE_WMM_PARMS command -+ * -+ * 07 13 2010 yarco.yang -+ * -+ * [WPD00003849] -+ * [MT6620 and MT5931] SW Migration, add qmGetFrameAction() API for CMD Queue Processing -+ * -+ * 07 09 2010 yarco.yang -+ * -+ * [MT6620 and MT5931] SW Migration: Add ADDBA support -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 29 2010 yarco.yang -+ * [WPD00003837][MT6620]Data Path Refine -+ * replace g_rQM with Adpater->rQM -+ * -+ * 06 25 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add API in que_mgt to retrieve sta-rec index for security frames. -+ * -+ * 06 23 2010 yarco.yang -+ * [WPD00003837][MT6620]Data Path Refine -+ * Merge g_arStaRec[] into adapter->arStaRec[] -+ * -+ * 06 21 2010 yarco.yang -+ * [WPD00003837][MT6620]Data Path Refine -+ * Support CFG_MQM_MIGRATION flag -+ * -+ * 06 18 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Provide cnmMgtPktAlloc() and alloc/free function of msg/buf -+ * -+ * 06 08 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add hem_mbox.c and cnm_mem.h (but disabled some feature) for further migration -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 03 30 2010 tehuang.liu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * Enabled adaptive TC resource control -+ * -+ * 03 24 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * initial import for Linux port -+ * -+ * 03 19 2010 tehuang.liu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * By default enabling dynamic STA_REC activation and decactivation -+ * -+ * 03 17 2010 tehuang.liu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * Changed STA_REC index determination rules (DA=BMCAST always --> STA_REC_INDEX_BMCAST) -+ * -+ * 03 11 2010 tehuang.liu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * Fixed buffer leak when processing BAR frames -+ * -+ * 02 25 2010 tehuang.liu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * Enabled multi-STA TX path with fairness -+ * -+ * 02 24 2010 tehuang.liu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * Enabled dynamically activating and deactivating STA_RECs -+ * -+ * 02 24 2010 tehuang.liu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * Added code for dynamic activating and deactivating STA_RECs. -+ * -+ * 01 13 2010 tehuang.liu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * Enabled the Burst_End Indication mechanism -+** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-12-09 14:04:53 GMT MTK02468 -+** Added RX buffer reordering function prototypes -+** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-12-02 22:08:44 GMT MTK02468 -+** Added macro QM_INIT_STA_REC for initialize a STA_REC -+** \main\maintrunk.MT6620WiFiDriver_Prj\1 2009-11-23 21:58:43 GMT mtk02468 -+** Initial version -+** -+*/ -+ -+#ifndef _QUE_MGT_H -+#define _QUE_MGT_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/* Queue Manager Features */ -+/* 1: Indicate the last TX packet to the FW for each burst */ -+#define QM_BURST_END_INFO_ENABLED 1 -+/* 1: To fairly share TX resource among active STAs */ -+#define QM_FORWARDING_FAIRNESS 1 -+/* 1: To adaptively adjust resource for each TC */ -+#define QM_ADAPTIVE_TC_RESOURCE_CTRL 1 -+/* 1: To print TC resource adjustment results */ -+#define QM_PRINT_TC_RESOURCE_CTRL 0 -+/* 1: If pkt with SSN is missing, auto advance the RX reordering window */ -+#define QM_RX_WIN_SSN_AUTO_ADVANCING 1 -+/* 1: Indicate the packets falling behind to OS before the frame with SSN is received */ -+#define QM_RX_INIT_FALL_BEHIND_PASS 1 -+/* 1: Count times of TC resource empty happened */ -+#define QM_TC_RESOURCE_EMPTY_COUNTER 1 -+/* Parameters */ -+ -+/* -+ In TDLS or AP mode, peer maybe enter "sleep mode". -+ -+ If QM_INIT_TIME_TO_UPDATE_QUE_LEN = 60 when peer is in sleep mode, -+ we need to wait 60 * u4TimeToAdjustTcResource = 180 packets -+ u4TimeToAdjustTcResource = 3, -+ then we will adjust TC resouce for VI or VO. -+ -+ But in TDLS test case, the throughput is very low, only 0.8Mbps in 5.7, -+ we will to wait about 12 seconds to collect 180 packets. -+ but the test time is only 20 seconds. -+*/ -+#define QM_INIT_TIME_TO_UPDATE_QUE_LEN 60 /* p: Update queue lengths when p TX packets are enqueued */ -+#define QM_INIT_TIME_TO_UPDATE_QUE_LEN_MIN 5 -+ -+#define QM_INIT_TIME_TO_ADJUST_TC_RSC 3 /* s: Adjust the TC resource every s updates of queue lengths */ -+#define QM_QUE_LEN_MOVING_AVE_FACTOR 3 /* Factor for Que Len averaging */ -+ -+#define QM_MIN_RESERVED_TC0_RESOURCE 1 -+#define QM_MIN_RESERVED_TC1_RESOURCE 1 -+#define QM_MIN_RESERVED_TC2_RESOURCE 1 -+#define QM_MIN_RESERVED_TC3_RESOURCE 1 -+#define QM_MIN_RESERVED_TC4_RESOURCE 2 /* Resource for TC4 is not adjustable */ -+#define QM_MIN_RESERVED_TC5_RESOURCE 1 -+ -+#if defined(MT6620) -+ -+#define QM_GUARANTEED_TC0_RESOURCE 4 -+#define QM_GUARANTEED_TC1_RESOURCE 4 -+#define QM_GUARANTEED_TC2_RESOURCE 9 -+#define QM_GUARANTEED_TC3_RESOURCE 11 -+#define QM_GUARANTEED_TC4_RESOURCE 2 /* Resource for TC4 is not adjustable */ -+#define QM_GUARANTEED_TC5_RESOURCE 4 -+ -+#elif defined(MT6628) -+ -+#define QM_GUARANTEED_TC0_RESOURCE 4 -+#define QM_GUARANTEED_TC1_RESOURCE 4 -+#define QM_GUARANTEED_TC2_RESOURCE 6 -+#define QM_GUARANTEED_TC3_RESOURCE 6 -+#define QM_GUARANTEED_TC4_RESOURCE 2 /* Resource for TC4 is not adjustable */ -+#define QM_GUARANTEED_TC5_RESOURCE 4 -+ -+#else -+#error -+#endif -+ -+#define QM_EXTRA_RESERVED_RESOURCE_WHEN_BUSY 0 -+ -+#define QM_TOTAL_TC_RESOURCE (\ -+ NIC_TX_BUFF_COUNT_TC0 + NIC_TX_BUFF_COUNT_TC1 +\ -+ NIC_TX_BUFF_COUNT_TC2 + NIC_TX_BUFF_COUNT_TC3 +\ -+ NIC_TX_BUFF_COUNT_TC5) -+#define QM_AVERAGE_TC_RESOURCE 6 -+ -+/* Note: QM_INITIAL_RESIDUAL_TC_RESOURCE shall not be less than 0 */ -+/* for 6628: QM_TOTAL_TC_RESOURCE = 28, RESIDUAL = 4 4 6 6 2 4 = 26 */ -+#define QM_INITIAL_RESIDUAL_TC_RESOURCE (QM_TOTAL_TC_RESOURCE - \ -+ (QM_GUARANTEED_TC0_RESOURCE +\ -+ QM_GUARANTEED_TC1_RESOURCE +\ -+ QM_GUARANTEED_TC2_RESOURCE +\ -+ QM_GUARANTEED_TC3_RESOURCE +\ -+ QM_GUARANTEED_TC5_RESOURCE \ -+ )) -+ -+/* Hard-coded network type for Phase 3: NETWORK_TYPE_AIS/P2P/BOW */ -+#define QM_OPERATING_NETWORK_TYPE NETWORK_TYPE_AIS -+ -+#define QM_TEST_MODE 0 -+#define QM_TEST_TRIGGER_TX_COUNT 50 -+#define QM_TEST_STA_REC_DETERMINATION 0 -+#define QM_TEST_STA_REC_DEACTIVATION 0 -+#define QM_TEST_FAIR_FORWARDING 0 -+ -+#define QM_DEBUG_COUNTER 0 -+ -+/* Per-STA Queues: [0] AC0, [1] AC1, [2] AC2, [3] AC3, [4] 802.1x */ -+/* Per-Type Queues: [0] BMCAST */ -+#define NUM_OF_PER_STA_TX_QUEUES 5 -+#define NUM_OF_PER_TYPE_TX_QUEUES 1 -+ -+/* These two constants are also used for FW to verify the STA_REC index */ -+#define STA_REC_INDEX_BMCAST 0xFF -+#define STA_REC_INDEX_NOT_FOUND 0xFE -+ -+/* TX Queue Index */ -+#define TX_QUEUE_INDEX_BMCAST 0 -+#define TX_QUEUE_INDEX_NO_STA_REC 0 -+#define TX_QUEUE_INDEX_AC0 0 -+#define TX_QUEUE_INDEX_AC1 1 -+#define TX_QUEUE_INDEX_AC2 2 -+#define TX_QUEUE_INDEX_AC3 3 -+#define TX_QUEUE_INDEX_802_1X 4 -+#define TX_QUEUE_INDEX_NON_QOS 1 -+ -+/* 1 WMM-related */ -+/* WMM FLAGS */ -+#define WMM_FLAG_SUPPORT_WMM BIT(0) -+#define WMM_FLAG_SUPPORT_WMMSA BIT(1) -+#define WMM_FLAG_AC_PARAM_PRESENT BIT(2) -+#define WMM_FLAG_SUPPORT_UAPSD BIT(3) -+ -+/* WMM Admission Control Mandatory FLAGS */ -+#define ACM_FLAG_ADM_NOT_REQUIRED 0 -+#define ACM_FLAG_ADM_GRANTED BIT(0) -+#define ACM_FLAG_ADM_REQUIRED BIT(1) -+ -+/* WMM Power Saving FLAGS */ -+#define AC_FLAG_TRIGGER_ENABLED BIT(1) -+#define AC_FLAG_DELIVERY_ENABLED BIT(2) -+ -+/* WMM-2.2.1 WMM Information Element */ -+#define ELEM_MAX_LEN_WMM_INFO 7 -+ -+/* WMM-2.2.2 WMM Parameter Element */ -+#define ELEM_MAX_LEN_WMM_PARAM 24 -+ -+/* WMM-2.2.1 WMM QoS Info field */ -+#define WMM_QOS_INFO_PARAM_SET_CNT BITS(0, 3) /* Sent by AP */ -+#define WMM_QOS_INFO_UAPSD BIT(7) -+ -+#define WMM_QOS_INFO_VO_UAPSD BIT(0) /* Sent by non-AP STA */ -+#define WMM_QOS_INFO_VI_UAPSD BIT(1) -+#define WMM_QOS_INFO_BK_UAPSD BIT(2) -+#define WMM_QOS_INFO_BE_UAPSD BIT(3) -+#define WMM_QOS_INFO_MAX_SP_LEN_MASK BITS(5, 6) -+#define WMM_QOS_INFO_MAX_SP_ALL 0 -+#define WMM_QOS_INFO_MAX_SP_2 BIT(5) -+#define WMM_QOS_INFO_MAX_SP_4 BIT(6) -+#define WMM_QOS_INFO_MAX_SP_6 BITS(5, 6) -+ -+/* -- definitions for Max SP length field */ -+#define WMM_MAX_SP_LENGTH_ALL 0 -+#define WMM_MAX_SP_LENGTH_2 2 -+#define WMM_MAX_SP_LENGTH_4 4 -+#define WMM_MAX_SP_LENGTH_6 6 -+ -+/* WMM-2.2.2 WMM ACI/AIFSN field */ -+/* -- subfields in the ACI/AIFSN field */ -+#define WMM_ACIAIFSN_AIFSN BITS(0, 3) -+#define WMM_ACIAIFSN_ACM BIT(4) -+#define WMM_ACIAIFSN_ACI BITS(5, 6) -+#define WMM_ACIAIFSN_ACI_OFFSET 5 -+ -+/* -- definitions for ACI field */ -+#define WMM_ACI_AC_BE 0 -+#define WMM_ACI_AC_BK BIT(5) -+#define WMM_ACI_AC_VI BIT(6) -+#define WMM_ACI_AC_VO BITS(5, 6) -+ -+#define WMM_ACI(_AC) (_AC << WMM_ACIAIFSN_ACI_OFFSET) -+ -+/* -- definitions for ECWmin/ECWmax field */ -+#define WMM_ECW_WMIN_MASK BITS(0, 3) -+#define WMM_ECW_WMAX_MASK BITS(4, 7) -+#define WMM_ECW_WMAX_OFFSET 4 -+ -+#define TXM_DEFAULT_FLUSH_QUEUE_GUARD_TIME 0 /* Unit: 64 us */ -+ -+#define QM_RX_BA_ENTRY_MISS_TIMEOUT_MS (1000) -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+enum { -+ QM_DBG_CNT_00 = 0, -+ QM_DBG_CNT_01, -+ QM_DBG_CNT_02, -+ QM_DBG_CNT_03, -+ QM_DBG_CNT_04, -+ QM_DBG_CNT_05, -+ QM_DBG_CNT_06, -+ QM_DBG_CNT_07, -+ QM_DBG_CNT_08, -+ QM_DBG_CNT_09, -+ QM_DBG_CNT_10, -+ QM_DBG_CNT_11, -+ QM_DBG_CNT_12, -+ QM_DBG_CNT_13, -+ QM_DBG_CNT_14, -+ QM_DBG_CNT_15, -+ QM_DBG_CNT_16, -+ QM_DBG_CNT_17, -+ QM_DBG_CNT_18, -+ QM_DBG_CNT_19, -+ QM_DBG_CNT_20, -+ QM_DBG_CNT_21, -+ QM_DBG_CNT_22, -+ QM_DBG_CNT_23, -+ QM_DBG_CNT_24, -+ QM_DBG_CNT_25, -+ QM_DBG_CNT_26, -+ QM_DBG_CNT_27, -+ QM_DBG_CNT_28, -+ QM_DBG_CNT_29, -+ QM_DBG_CNT_30, -+ QM_DBG_CNT_31, -+ QM_DBG_CNT_NUM -+}; -+ -+/* Used for MAC TX */ -+typedef enum _ENUM_MAC_TX_QUEUE_INDEX_T { -+ MAC_TX_QUEUE_AC0_INDEX = 0, -+ MAC_TX_QUEUE_AC1_INDEX, -+ MAC_TX_QUEUE_AC2_INDEX, -+ MAC_TX_QUEUE_AC3_INDEX, -+ MAC_TX_QUEUE_AC4_INDEX, -+ MAC_TX_QUEUE_AC5_INDEX, -+ MAC_TX_QUEUE_AC6_INDEX, -+ MAC_TX_QUEUE_BCN_INDEX, -+ MAC_TX_QUEUE_BMC_INDEX, -+ MAC_TX_QUEUE_NUM -+} ENUM_MAC_TX_QUEUE_INDEX_T; -+ -+typedef struct _RX_BA_ENTRY_T { -+ BOOLEAN fgIsValid; -+ QUE_T rReOrderQue; -+ UINT_16 u2WinStart; -+ UINT_16 u2WinEnd; -+ UINT_16 u2WinSize; -+ -+ /* For identifying the RX BA agreement */ -+ UINT_8 ucStaRecIdx; -+ UINT_8 ucTid; -+ -+ BOOLEAN fgIsWaitingForPktWithSsn; -+ -+ /* UINT_8 ucTxBufferSize; */ -+ /* BOOL fgIsAcConstrain; */ -+ /* BOOL fgIsBaEnabled; */ -+} RX_BA_ENTRY_T, *P_RX_BA_ENTRY_T; -+ -+/* The mailbox message (could be used for Host-To-Device or Device-To-Host Mailbox) */ -+typedef struct _MAILBOX_MSG_T { -+ UINT_32 u4Msg[2]; /* [0]: D2HRM0R or H2DRM0R, [1]: D2HRM1R or H2DRM1R */ -+} MAILBOX_MSG_T, *P_MAILBOX_MSG_T; -+ -+/* Used for adaptively adjusting TC resources */ -+typedef struct _TC_RESOURCE_CTRL_T { -+ /* TC0, TC1, TC2, TC3, TC5 */ -+ UINT_32 au4AverageQueLen[TC_NUM - 1]; -+} TC_RESOURCE_CTRL_T, *P_TC_RESOURCE_CTRL_T; -+ -+typedef struct _QUE_MGT_T { /* Queue Management Control Info */ -+ -+ /* Per-Type Queues: [0] BMCAST or UNKNOWN-STA packets */ -+ QUE_T arTxQueue[NUM_OF_PER_TYPE_TX_QUEUES]; -+ -+#if 0 -+ /* For TX Scheduling */ -+ UINT_8 arRemainingTxOppt[NUM_OF_PER_STA_TX_QUEUES]; -+ UINT_8 arCurrentTxStaIndex[NUM_OF_PER_STA_TX_QUEUES]; -+ -+#endif -+ -+ /* Reordering Queue Parameters */ -+ RX_BA_ENTRY_T arRxBaTable[CFG_NUM_OF_RX_BA_AGREEMENTS]; -+ -+ /* Current number of activated RX BA agreements <= CFG_NUM_OF_RX_BA_AGREEMENTS */ -+ UINT_8 ucRxBaCount; -+ -+#if QM_TEST_MODE -+ UINT_32 u4PktCount; -+ P_ADAPTER_T prAdapter; -+ -+#if QM_TEST_FAIR_FORWARDING -+ UINT_32 u4CurrentStaRecIndexToEnqueue; -+#endif -+ -+#endif -+ -+#if QM_FORWARDING_FAIRNESS -+ /* The current TX count for a STA with respect to a TC index */ -+ UINT_32 au4ForwardCount[NUM_OF_PER_STA_TX_QUEUES]; -+ -+ /* The current serving STA with respect to a TC index */ -+ UINT_32 au4HeadStaRecIndex[NUM_OF_PER_STA_TX_QUEUES]; -+#endif -+ -+#if QM_ADAPTIVE_TC_RESOURCE_CTRL -+ UINT_32 au4AverageQueLen[TC_NUM]; -+ UINT_32 au4CurrentTcResource[TC_NUM]; -+ UINT_32 au4MinReservedTcResource[TC_NUM]; /* The minimum amount of resource no matter busy or idle */ -+ UINT_32 au4GuaranteedTcResource[TC_NUM]; /* The minimum amount of resource when extremely busy */ -+ -+ UINT_32 u4TimeToAdjustTcResource; -+ UINT_32 u4TimeToUpdateQueLen; -+ UINT_32 u4TxNumOfVi, u4TxNumOfVo; /* number of VI/VO packets */ -+ -+ /* Set to TRUE if the last TC adjustment has not been completely applied (i.e., waiting more TX-Done events -+ to align the TC quotas to the TC resource assignment) */ -+ BOOLEAN fgTcResourcePostAnnealing; -+ -+#endif -+ -+#if QM_DEBUG_COUNTER -+ UINT_32 au4QmDebugCounters[QM_DBG_CNT_NUM]; -+#endif -+#if QM_TC_RESOURCE_EMPTY_COUNTER -+ UINT_32 au4QmTcResourceEmptyCounter[NET_TYPE_NUM][TC_NUM]; -+ UINT_32 au4QmTcResourceBackCounter[TC_NUM]; -+ UINT_32 au4DequeueNoTcResourceCounter[TC_NUM]; -+ -+ UINT_32 au4ResourceUsedCounter[TC_NUM]; -+ -+ UINT_32 au4ResourceWantedCounter[TC_NUM]; -+ -+ UINT_32 u4EnqeueuCounter; -+ UINT_32 u4DequeueCounter; -+#endif -+} QUE_MGT_T, *P_QUE_MGT_T; -+ -+typedef struct _EVENT_RX_ADDBA_T { -+ /* Event header */ -+ UINT_16 u2Length; -+ UINT_16 u2Reserved1; /* Must be filled with 0x0001 (EVENT Packet) */ -+ UINT_8 ucEID; -+ UINT_8 ucSeqNum; -+ UINT_8 aucReserved2[2]; -+ -+ /* Fields not present in the received ADDBA_REQ */ -+ UINT_8 ucStaRecIdx; -+ -+ /* Fields that are present in the received ADDBA_REQ */ -+ UINT_8 ucDialogToken; /* Dialog Token chosen by the sender */ -+ UINT_16 u2BAParameterSet; /* BA policy, TID, buffer size */ -+ UINT_16 u2BATimeoutValue; -+ UINT_16 u2BAStartSeqCtrl; /* SSN */ -+ -+} EVENT_RX_ADDBA_T, *P_EVENT_RX_ADDBA_T; -+ -+typedef struct _EVENT_RX_DELBA_T { -+ /* Event header */ -+ UINT_16 u2Length; -+ UINT_16 u2Reserved1; /* Must be filled with 0x0001 (EVENT Packet) */ -+ UINT_8 ucEID; -+ UINT_8 ucSeqNum; -+ UINT_8 aucReserved2[2]; -+ -+ /* Fields not present in the received ADDBA_REQ */ -+ UINT_8 ucStaRecIdx; -+ UINT_8 ucTid; -+} EVENT_RX_DELBA_T, *P_EVENT_RX_DELBA_T; -+ -+typedef struct _EVENT_BSS_ABSENCE_PRESENCE_T { -+ /* Event header */ -+ UINT_16 u2Length; -+ UINT_16 u2Reserved1; /* Must be filled with 0x0001 (EVENT Packet) */ -+ UINT_8 ucEID; -+ UINT_8 ucSeqNum; -+ UINT_8 aucReserved2[2]; -+ -+ /* Event Body */ -+ UINT_8 ucNetTypeIdx; -+ BOOLEAN fgIsAbsent; -+ UINT_8 ucBssFreeQuota; -+ UINT_8 aucReserved[1]; -+} EVENT_BSS_ABSENCE_PRESENCE_T, *P_EVENT_BSS_ABSENCE_PRESENCE_T; -+ -+typedef struct _EVENT_STA_CHANGE_PS_MODE_T { -+ /* Event header */ -+ UINT_16 u2Length; -+ UINT_16 u2Reserved1; /* Must be filled with 0x0001 (EVENT Packet) */ -+ UINT_8 ucEID; -+ UINT_8 ucSeqNum; -+ UINT_8 aucReserved2[2]; -+ -+ /* Event Body */ -+ UINT_8 ucStaRecIdx; -+ BOOLEAN fgIsInPs; -+ UINT_8 ucUpdateMode; -+ UINT_8 ucFreeQuota; -+} EVENT_STA_CHANGE_PS_MODE_T, *P_EVENT_STA_CHANGE_PS_MODE_T; -+ -+/* The free quota is used by PS only now */ -+/* The event may be used by per STA flow conttrol in general */ -+typedef struct _EVENT_STA_UPDATE_FREE_QUOTA_T { -+ /* Event header */ -+ UINT_16 u2Length; -+ UINT_16 u2Reserved1; /* Must be filled with 0x0001 (EVENT Packet) */ -+ UINT_8 ucEID; -+ UINT_8 ucSeqNum; -+ UINT_8 aucReserved2[2]; -+ -+ /* Event Body */ -+ UINT_8 ucStaRecIdx; -+ UINT_8 ucUpdateMode; -+ UINT_8 ucFreeQuota; -+ UINT_8 aucReserved[1]; -+} EVENT_STA_UPDATE_FREE_QUOTA_T, *P_EVENT_STA_UPDATE_FREE_QUOTA_T; -+ -+/* WMM-2.2.1 WMM Information Element */ -+typedef struct _IE_WMM_INFO_T { -+ UINT_8 ucId; /* Element ID */ -+ UINT_8 ucLength; /* Length */ -+ UINT_8 aucOui[3]; /* OUI */ -+ UINT_8 ucOuiType; /* OUI Type */ -+ UINT_8 ucOuiSubtype; /* OUI Subtype */ -+ UINT_8 ucVersion; /* Version */ -+ UINT_8 ucQosInfo; /* QoS Info field */ -+ UINT_8 ucDummy[3]; /* Dummy for pack */ -+} IE_WMM_INFO_T, *P_IE_WMM_INFO_T; -+ -+/* WMM-2.2.2 WMM Parameter Element */ -+typedef struct _IE_WMM_PARAM_T { -+ UINT_8 ucId; /* Element ID */ -+ UINT_8 ucLength; /* Length */ -+ -+ /* IE Body */ -+ UINT_8 aucOui[3]; /* OUI */ -+ UINT_8 ucOuiType; /* OUI Type */ -+ UINT_8 ucOuiSubtype; /* OUI Subtype */ -+ UINT_8 ucVersion; /* Version */ -+ -+ /* WMM IE Body */ -+ UINT_8 ucQosInfo; /* QoS Info field */ -+ UINT_8 ucReserved; -+ -+ /* AC Parameters */ -+ UINT_8 ucAciAifsn_BE; -+ UINT_8 ucEcw_BE; -+ UINT_8 aucTxopLimit_BE[2]; -+ -+ UINT_8 ucAciAifsn_BG; -+ UINT_8 ucEcw_BG; -+ UINT_8 aucTxopLimit_BG[2]; -+ -+ UINT_8 ucAciAifsn_VI; -+ UINT_8 ucEcw_VI; -+ UINT_8 aucTxopLimit_VI[2]; -+ -+ UINT_8 ucAciAifsn_VO; -+ UINT_8 ucEcw_VO; -+ UINT_8 aucTxopLimit_VO[2]; -+ -+} IE_WMM_PARAM_T, *P_IE_WMM_PARAM_T; -+ -+typedef struct _IE_WMM_TSPEC_T { -+ UINT_8 ucId; /* Element ID */ -+ UINT_8 ucLength; /* Length */ -+ UINT_8 aucOui[3]; /* OUI */ -+ UINT_8 ucOuiType; /* OUI Type */ -+ UINT_8 ucOuiSubtype; /* OUI Subtype */ -+ UINT_8 ucVersion; /* Version */ -+ /* WMM TSPEC body */ -+ UINT_8 aucTsInfo[3]; /* TS Info */ -+ UINT_8 aucTspecBodyPart[1]; /* Note: Utilize PARAM_QOS_TSPEC to fill (memory copy) */ -+} IE_WMM_TSPEC_T, *P_IE_WMM_TSPEC_T; -+ -+typedef struct _IE_WMM_HDR_T { -+ UINT_8 ucId; /* Element ID */ -+ UINT_8 ucLength; /* Length */ -+ UINT_8 aucOui[3]; /* OUI */ -+ UINT_8 ucOuiType; /* OUI Type */ -+ UINT_8 ucOuiSubtype; /* OUI Subtype */ -+ UINT_8 ucVersion; /* Version */ -+ UINT_8 aucBody[1]; /* IE body */ -+} IE_WMM_HDR_T, *P_IE_WMM_HDR_T; -+ -+typedef struct _AC_QUE_PARMS_T { -+ UINT_16 u2CWmin; /*!< CWmin */ -+ UINT_16 u2CWmax; /*!< CWmax */ -+ UINT_16 u2TxopLimit; /*!< TXOP limit */ -+ UINT_16 u2Aifsn; /*!< AIFSN */ -+ UINT_8 ucGuradTime; /*!< GuardTime for STOP/FLUSH. */ -+ BOOLEAN fgIsACMSet; -+} AC_QUE_PARMS_T, *P_AC_QUE_PARMS_T; -+ -+/* WMM ACI (AC index) */ -+typedef enum _ENUM_WMM_ACI_T { -+ WMM_AC_BE_INDEX = 0, -+ WMM_AC_BK_INDEX, -+ WMM_AC_VI_INDEX, -+ WMM_AC_VO_INDEX, -+ WMM_AC_INDEX_NUM -+} ENUM_WMM_ACI_T, *P_ENUM_WMM_ACI_T; -+ -+/* Used for CMD Queue Operation */ -+typedef enum _ENUM_FRAME_ACTION_T { -+ FRAME_ACTION_DROP_PKT = 0, -+ FRAME_ACTION_QUEUE_PKT, -+ FRAME_ACTION_TX_PKT, -+ FRAME_ACTION_NUM -+} ENUM_FRAME_ACTION_T; -+ -+typedef enum _ENUM_FRAME_TYPE_IN_CMD_Q_T { -+ FRAME_TYPE_802_1X = 0, -+ FRAME_TYPE_MMPDU, -+ FRAME_TYPE_NUM -+} ENUM_FRAME_TYPE_IN_CMD_Q_T; -+ -+typedef enum _ENUM_FREE_QUOTA_MODET_T { -+ FREE_QUOTA_UPDATE_MODE_INIT = 0, -+ FREE_QUOTA_UPDATE_MODE_OVERWRITE, -+ FREE_QUOTA_UPDATE_MODE_INCREASE, -+ FREE_QUOTA_UPDATE_MODE_DECREASE -+} ENUM_FREE_QUOTA_MODET_T, *P_ENUM_FREE_QUOTA_MODET_T; -+ -+typedef struct _CMD_UPDATE_WMM_PARMS_T { -+ AC_QUE_PARMS_T arACQueParms[AC_NUM]; -+ UINT_8 ucNetTypeIndex; -+ UINT_8 fgIsQBSS; -+ UINT_8 aucReserved[2]; -+} CMD_UPDATE_WMM_PARMS_T, *P_CMD_UPDATE_WMM_PARMS_T; -+ -+typedef struct _CMD_TX_AMPDU_T { -+ BOOLEAN fgEnable; -+ UINT_8 aucReserved[3]; -+} CMD_TX_AMPDU_T, *P_CMD_TX_AMPDU_T; -+ -+typedef struct _CMD_ADDBA_REJECT { -+ BOOLEAN fgEnable; -+ UINT_8 aucReserved[3]; -+} CMD_ADDBA_REJECT_T, *P_CMD_ADDBA_REJECT_T; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+#define QM_TX_SET_NEXT_MSDU_INFO(_prMsduInfoPreceding, _prMsduInfoNext) \ -+ ((((_prMsduInfoPreceding)->rQueEntry).prNext) = (P_QUE_ENTRY_T)(_prMsduInfoNext)) -+ -+#define QM_TX_SET_NEXT_SW_RFB(_prSwRfbPreceding, _prSwRfbNext) \ -+ ((((_prSwRfbPreceding)->rQueEntry).prNext) = (P_QUE_ENTRY_T)(_prSwRfbNext)) -+ -+#define QM_TX_GET_NEXT_MSDU_INFO(_prMsduInfo) \ -+ ((P_MSDU_INFO_T)(((_prMsduInfo)->rQueEntry).prNext)) -+ -+#define QM_RX_SET_NEXT_SW_RFB(_prSwRfbPreceding, _prSwRfbNext) \ -+ ((((_prSwRfbPreceding)->rQueEntry).prNext) = (P_QUE_ENTRY_T)(_prSwRfbNext)) -+ -+#define QM_RX_GET_NEXT_SW_RFB(_prSwRfb) \ -+ ((P_SW_RFB_T)(((_prSwRfb)->rQueEntry).prNext)) -+ -+#if 0 -+#define QM_GET_STA_REC_PTR_FROM_INDEX(_prAdapter, _ucIndex) \ -+ ((((_ucIndex) != STA_REC_INDEX_BMCAST) && ((_ucIndex) != STA_REC_INDEX_NOT_FOUND)) ?\ -+ &(_prAdapter->arStaRec[_ucIndex]) : NULL) -+#endif -+ -+#define QM_GET_STA_REC_PTR_FROM_INDEX(_prAdapter, _ucIndex) \ -+ cnmGetStaRecByIndex(_prAdapter, _ucIndex) -+ -+#define QM_TX_SET_MSDU_INFO_FOR_DATA_PACKET(\ -+ _prMsduInfo,\ -+ _ucTC,\ -+ _ucPacketType,\ -+ _ucFormatID,\ -+ _fgIs802_1x,\ -+ _fgIs802_11,\ -+ _u2PalLLH,\ -+ _u2AclSN,\ -+ _ucPsForwardingType,\ -+ _ucPsSessionID\ -+ ) \ -+{\ -+ ASSERT(_prMsduInfo);\ -+ (_prMsduInfo)->ucTC = (_ucTC);\ -+ (_prMsduInfo)->ucPacketType = (_ucPacketType);\ -+ (_prMsduInfo)->ucFormatID = (_ucFormatID);\ -+ (_prMsduInfo)->fgIs802_1x = (_fgIs802_1x);\ -+ (_prMsduInfo)->fgIs802_11 = (_fgIs802_11);\ -+ (_prMsduInfo)->u2PalLLH = (_u2PalLLH);\ -+ (_prMsduInfo)->u2AclSN = (_u2AclSN);\ -+ (_prMsduInfo)->ucPsForwardingType = (_ucPsForwardingType);\ -+ (_prMsduInfo)->ucPsSessionID = (_ucPsSessionID);\ -+ (_prMsduInfo)->fgIsBurstEnd = (FALSE);\ -+} -+ -+#define QM_INIT_STA_REC(\ -+ _prStaRec,\ -+ _fgIsValid,\ -+ _fgIsQoS,\ -+ _pucMacAddr\ -+ )\ -+{\ -+ ASSERT(_prStaRec);\ -+ (_prStaRec)->fgIsValid = (_fgIsValid);\ -+ (_prStaRec)->fgIsQoS = (_fgIsQoS);\ -+ (_prStaRec)->fgIsInPS = FALSE; \ -+ (_prStaRec)->ucPsSessionID = 0xFF;\ -+ COPY_MAC_ADDR((_prStaRec)->aucMacAddr, (_pucMacAddr));\ -+} -+ -+#if QM_ADAPTIVE_TC_RESOURCE_CTRL -+#define QM_GET_TX_QUEUE_LEN(_prAdapter, _u4QueIdx) \ -+ ((_prAdapter->rQM.au4AverageQueLen[(_u4QueIdx)] >> QM_QUE_LEN_MOVING_AVE_FACTOR)) -+#endif -+ -+#define WMM_IE_OUI_TYPE(fp) (((P_IE_WMM_HDR_T)(fp))->ucOuiType) -+#define WMM_IE_OUI_SUBTYPE(fp) (((P_IE_WMM_HDR_T)(fp))->ucOuiSubtype) -+#define WMM_IE_OUI(fp) (((P_IE_WMM_HDR_T)(fp))->aucOui) -+ -+#if QM_DEBUG_COUNTER -+#define QM_DBG_CNT_INC(_prQM, _index) { (_prQM)->au4QmDebugCounters[(_index)]++; } -+#else -+#define QM_DBG_CNT_INC(_prQM, _index) {} -+#endif -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+/*----------------------------------------------------------------------------*/ -+/* Queue Management and STA_REC Initialization */ -+/*----------------------------------------------------------------------------*/ -+ -+VOID qmInit(IN P_ADAPTER_T prAdapter); -+ -+#if QM_TEST_MODE -+VOID qmTestCases(IN P_ADAPTER_T prAdapter); -+#endif -+ -+VOID qmActivateStaRec(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec); -+ -+VOID qmDeactivateStaRec(IN P_ADAPTER_T prAdapter, IN UINT_32 u4StaRecIdx); -+ -+/*----------------------------------------------------------------------------*/ -+/* TX-Related Queue Management */ -+/*----------------------------------------------------------------------------*/ -+ -+P_MSDU_INFO_T qmFlushTxQueues(IN P_ADAPTER_T prAdapter); -+ -+P_MSDU_INFO_T qmFlushStaTxQueues(IN P_ADAPTER_T prAdapter, IN UINT_32 u4StaRecIdx); -+ -+P_MSDU_INFO_T qmEnqueueTxPackets(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfoListHead); -+ -+P_MSDU_INFO_T qmDequeueTxPackets(IN P_ADAPTER_T prAdapter, IN P_TX_TCQ_STATUS_T prTcqStatus); -+ -+VOID qmAdjustTcQuotas(IN P_ADAPTER_T prAdapter, OUT P_TX_TCQ_ADJUST_T prTcqAdjust, IN P_TX_TCQ_STATUS_T prTcqStatus); -+ -+#if QM_ADAPTIVE_TC_RESOURCE_CTRL -+VOID qmReassignTcResource(IN P_ADAPTER_T prAdapter); -+ -+VOID qmUpdateAverageTxQueLen(IN P_ADAPTER_T prAdapter); -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/* RX-Related Queue Management */ -+/*----------------------------------------------------------------------------*/ -+ -+VOID qmInitRxQueues(IN P_ADAPTER_T prAdapter); -+ -+P_SW_RFB_T qmFlushRxQueues(IN P_ADAPTER_T prAdapter); -+ -+P_SW_RFB_T qmHandleRxPackets(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfbListHead); -+ -+VOID qmProcessPktWithReordering(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, OUT P_QUE_T prReturnedQue); -+ -+VOID qmProcessBarFrame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, OUT P_QUE_T prReturnedQue); -+ -+VOID -+qmInsertFallWithinReorderPkt(IN P_SW_RFB_T prSwRfb, IN P_RX_BA_ENTRY_T prReorderQueParm, OUT P_QUE_T prReturnedQue); -+ -+VOID qmInsertFallAheadReorderPkt(IN P_SW_RFB_T prSwRfb, IN P_RX_BA_ENTRY_T prReorderQueParm, OUT P_QUE_T prReturnedQue); -+ -+BOOLEAN -+qmPopOutDueToFallWithin(IN P_RX_BA_ENTRY_T prReorderQueParm, OUT P_QUE_T prReturnedQue, OUT BOOLEAN *fgIsTimeout); -+ -+VOID qmPopOutDueToFallAhead(IN P_RX_BA_ENTRY_T prReorderQueParm, OUT P_QUE_T prReturnedQue); -+ -+VOID qmHandleMailboxRxMessage(IN MAILBOX_MSG_T prMailboxRxMsg); -+ -+BOOLEAN qmCompareSnIsLessThan(IN UINT_32 u4SnLess, IN UINT_32 u4SnGreater); -+ -+VOID qmHandleEventRxAddBa(IN P_ADAPTER_T prAdapter, IN P_WIFI_EVENT_T prEvent); -+ -+VOID qmHandleEventRxDelBa(IN P_ADAPTER_T prAdapter, IN P_WIFI_EVENT_T prEvent); -+ -+P_RX_BA_ENTRY_T qmLookupRxBaEntry(IN P_ADAPTER_T prAdapter, IN UINT_8 ucStaRecIdx, IN UINT_8 ucTid); -+ -+BOOLEAN -+qmAddRxBaEntry(IN P_ADAPTER_T prAdapter, -+ IN UINT_8 ucStaRecIdx, IN UINT_8 ucTid, IN UINT_16 u2WinStart, IN UINT_16 u2WinSize); -+ -+VOID qmDelRxBaEntry(IN P_ADAPTER_T prAdapter, IN UINT_8 ucStaRecIdx, IN UINT_8 ucTid, IN BOOLEAN fgFlushToHost); -+ -+VOID mqmProcessAssocRsp(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, IN PUINT_8 pucIE, IN UINT_16 u2IELength); -+ -+VOID -+mqmParseEdcaParameters(IN P_ADAPTER_T prAdapter, -+ IN P_SW_RFB_T prSwRfb, IN PUINT_8 pucIE, IN UINT_16 u2IELength, IN BOOLEAN fgForceOverride); -+ -+VOID mqmFillAcQueParam(IN P_IE_WMM_PARAM_T prIeWmmParam, IN UINT_32 u4AcOffset, OUT P_AC_QUE_PARMS_T prAcQueParams); -+ -+VOID mqmProcessScanResult(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prScanResult, OUT P_STA_RECORD_T prStaRec); -+ -+/* Utility function: for deciding STA-REC index */ -+UINT_8 qmGetStaRecIdx(IN P_ADAPTER_T prAdapter, IN PUINT_8 pucEthDestAddr, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkType); -+ -+UINT_32 -+mqmGenerateWmmInfoIEByParam(BOOLEAN fgSupportUAPSD, -+ UINT_8 ucBmpDeliveryAC, UINT_8 ucBmpTriggerAC, UINT_8 ucUapsdSp, UINT_8 *pOutBuf); -+ -+VOID mqmGenerateWmmInfoIE(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); -+ -+UINT_32 mqmGenerateWmmParamIEByParam(P_ADAPTER_T prAdapter, -+ P_BSS_INFO_T prBssInfo, UINT_8 *pOutBuf, ENUM_OP_MODE_T ucOpMode); -+ -+VOID mqmGenerateWmmParamIE(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); -+ -+ENUM_FRAME_ACTION_T -+qmGetFrameAction(IN P_ADAPTER_T prAdapter, -+ IN ENUM_NETWORK_TYPE_INDEX_T eNetworkType, -+ IN UINT_8 ucStaRecIdx, IN P_MSDU_INFO_T prMsduInfo, IN ENUM_FRAME_TYPE_IN_CMD_Q_T eFrameType); -+ -+VOID qmHandleEventBssAbsencePresence(IN P_ADAPTER_T prAdapter, IN P_WIFI_EVENT_T prEvent); -+ -+VOID qmHandleEventStaChangePsMode(IN P_ADAPTER_T prAdapter, IN P_WIFI_EVENT_T prEvent); -+ -+VOID mqmProcessAssocReq(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, IN PUINT_8 pucIE, IN UINT_16 u2IELength); -+ -+VOID qmHandleEventStaUpdateFreeQuota(IN P_ADAPTER_T prAdapter, IN P_WIFI_EVENT_T prEvent); -+ -+VOID -+qmUpdateFreeQuota(IN P_ADAPTER_T prAdapter, -+ IN P_STA_RECORD_T prStaRec, IN UINT_8 ucUpdateMode, IN UINT_8 ucFreeQuota, IN UINT_8 ucNumOfTxDone); -+ -+VOID qmFreeAllByNetType(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx); -+ -+UINT_32 qmGetRxReorderQueuedBufferCount(IN P_ADAPTER_T prAdapter); -+ -+#if ARP_MONITER_ENABLE -+VOID qmDetectArpNoResponse(P_ADAPTER_T prAdapter, P_MSDU_INFO_T prMsduInfo); -+VOID qmResetArpDetect(VOID); -+VOID qmHandleRxArpPackets(P_ADAPTER_T prAdapter, P_SW_RFB_T prSwRfb); -+#endif -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif /* _QUE_MGT_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/wlan_def.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/wlan_def.h -new file mode 100644 -index 000000000000..2804b0387f5f ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/wlan_def.h -@@ -0,0 +1,1010 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/nic/wlan_def.h#1 -+*/ -+ -+/*! \file "wlan_def.h" -+ \brief This file includes the basic definition of WLAN -+ -+*/ -+ -+/* -+** Log: wlan_def.h -+** -+** 09 02 2013 cp.wu -+** add path to handle reassociation request -+ * -+ * 12 05 2011 cp.wu -+ * [WCXRP00001131] [MT6620 Wi-Fi][Driver][AIS] Implement connect-by-BSSID path -+ * add CONNECT_BY_BSSID policy -+ * -+ * 10 12 2011 wh.su -+ * [WCXRP00001036] [MT6620 Wi-Fi][Driver][FW] Adding the 802.11w code for MFP -+ * adding the 802.11w related function and define . -+ * -+ * 06 22 2011 wh.su -+ * [WCXRP00000806] [MT6620 Wi-Fi][Driver] Move the WPA/RSN IE and WAPI IE structure to mac.h and let the sw -+ * structure not align at byte -+ * Move the WAPI/RSN IE to mac.h and SW structure not align to byte, -+ * Notice needed update P2P.ko. -+ * -+ * 04 08 2011 eddie.chen -+ * [WCXRP00000617] [MT6620 Wi-Fi][DRV/FW] Fix for sigma -+ * Fix for sigma -+ * -+ * 03 17 2011 yuche.tsai -+ * NULL -+ * Resize the Secondary Device Type array when WiFi Direct is enabled. -+ * -+ * 01 25 2011 yuche.tsai -+ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record. -+ * Change Station Type in Station Record, Modify MACRO definition for getting station type & network type index & Role. -+ * -+ * 01 25 2011 yuche.tsai -+ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record. -+ * Add new station type MACRO. -+ * -+ * 12 07 2010 cm.chang -+ * [WCXRP00000238] MT6620 Wi-Fi][Driver][FW] Support regulation domain setting from NVRAM and supplicant -+ * 1. Country code is from NVRAM or supplicant -+ * 2. Change band definition in CMD/EVENT. -+ * -+ * 10 11 2010 kevin.huang -+ * [WCXRP00000068] [MT6620 Wi-Fi][Driver][FW] Fix STA RECORD sync issue and remove unused code -+ * Update ENUM_STA_ROLE_INDEX_T by using a fixed base value -+ * -+ * 10 04 2010 cp.wu -+ * [WCXRP00000077] [MT6620 Wi-Fi][Driver][FW] Eliminate use of ENUM_NETWORK_TYPE_T and replaced by -+ * ENUM_NETWORK_TYPE_INDEX_T only -+ * remove ENUM_NETWORK_TYPE_T definitions -+ * -+ * 09 14 2010 chinghwa.yu -+ * NULL -+ * Update OP_MODE_BOW and include bow_fsm.h. -+ * -+ * 09 03 2010 kevin.huang -+ * NULL -+ * Refine #include sequence and solve recursive/nested #include issue -+ * -+ * 08 31 2010 kevin.huang -+ * NULL -+ * Use LINK LIST operation to process SCAN result -+ * -+ * 08 29 2010 yuche.tsai -+ * NULL -+ * Change P2P Descriptor List to a pointer and allocate it dynamically to avoid structure corrupt by BssDescriptor free. -+ * -+ * 08 16 2010 kevin.huang -+ * NULL -+ * Refine AAA functions -+ * -+ * 08 12 2010 kevin.huang -+ * NULL -+ * Refine bssProcessProbeRequest() and bssSendBeaconProbeResponse() -+ * -+ * 08 12 2010 yuche.tsai -+ * NULL -+ * Add a pointer in BSS Descriptor for P2P Descriptor. -+ * -+ * 08 11 2010 yuche.tsai -+ * NULL -+ * Add an Interface in BSS Descriptor. -+ * -+ * 08 05 2010 yuche.tsai -+ * NULL -+ * Modify data structure for P2P Scan result. -+ * -+ * 07 26 2010 yuche.tsai -+ * -+ * Add an operation mode for P2P device. -+ * -+ * 07 23 2010 cp.wu -+ * -+ * P2P/RSN/WAPI IEs need to be declared with compact structure. -+ * -+ * 07 21 2010 yuche.tsai -+ * -+ * Add for P2P Scan Result Parsing & Saving. -+ * -+ * 07 20 2010 wh.su -+ * -+ * adding the wapi code. -+ * -+ * 07 09 2010 cp.wu -+ * -+ * 1) separate AIS_FSM state for two kinds of scanning. (OID triggered scan, and scan-for-connection) -+ * 2) eliminate PRE_BSS_DESC_T, Beacon/PrebResp is now parsed in single pass -+ * 3) implment DRV-SCN module, currently only accepts single scan request, other request will be directly -+ * dropped by returning BUSY -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 28 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * 1st draft code for RLM module -+ * -+ * 06 25 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * modify Beacon/ProbeResp to complete parsing, -+ * because host software has looser memory usage restriction -+ * -+ * 06 21 2010 yuche.tsai -+ * [WPD00003839][MT6620 5931][P2P] Feature migration -+ * Add P2P present boolean flag in BSS & Pre-BSS descriptor. -+ * -+ * 06 18 2010 wh.su -+ * [WPD00003840][MT6620 5931] Security migration -+ * migration the security related function from firmware. -+ * -+ * 06 11 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * auth.c is migrated. -+ * -+ * 06 11 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) migrate assoc.c. -+ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness -+ * 3) add configuration options for CNM_MEM and RSN modules -+ * 4) add data path for management frames -+ * 5) eliminate rPacketInfo of MSDU_INFO_T -+ * -+ * 06 10 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add buildable & linkable ais_fsm.c -+ * -+ * related reference are still waiting to be resolved -+ * -+ * 06 09 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add definitions for module migration. -+ * -+ * 06 07 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * move bss related data types to wlan_def.h to avoid recursive dependency. -+ * -+ * 06 07 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * merge wlan_def.h. -+ * -+ * 06 07 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * merge cnm_scan.h and hem_mbox.h -+ * -+ * 06 07 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * merge wifi_var.h, precomp.h, cnm_timer.h (data type only) -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 20:16:40 GMT mtk01426 -+** Init for develop -+** -+*/ -+ -+#ifndef _WLAN_DEF_H -+#define _WLAN_DEF_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+/* disconnect reason */ -+#define DISCONNECT_REASON_CODE_RESERVED 0 -+#define DISCONNECT_REASON_CODE_RADIO_LOST 1 -+#define DISCONNECT_REASON_CODE_DEAUTHENTICATED 2 -+#define DISCONNECT_REASON_CODE_DISASSOCIATED 3 -+#define DISCONNECT_REASON_CODE_NEW_CONNECTION 4 -+#define DISCONNECT_REASON_CODE_REASSOCIATION 5 -+#define DISCONNECT_REASON_CODE_ROAMING 6 -+ -+/* The rate definitions */ -+#define TX_MODE_CCK 0x00 -+#define TX_MODE_OFDM 0x40 -+#define TX_MODE_HT_MM 0x80 -+#define TX_MODE_HT_GF 0xC0 -+ -+#define RATE_CCK_SHORT_PREAMBLE 0x10 -+#define RATE_OFDM 0x20 -+ -+#define PHY_RATE_1M 0x0 -+#define PHY_RATE_2M 0x1 -+#define PHY_RATE_5_5M 0x2 -+#define PHY_RATE_11M 0x3 -+#define PHY_RATE_6M 0xB -+#define PHY_RATE_9M 0xF -+#define PHY_RATE_12M 0xA -+#define PHY_RATE_18M 0xE -+#define PHY_RATE_24M 0x9 -+#define PHY_RATE_36M 0xD -+#define PHY_RATE_48M 0x8 -+#define PHY_RATE_54M 0xC -+#define PHY_RATE_MCS0 0x0 -+#define PHY_RATE_MCS1 0x1 -+#define PHY_RATE_MCS2 0x2 -+#define PHY_RATE_MCS3 0x3 -+#define PHY_RATE_MCS4 0x4 -+#define PHY_RATE_MCS5 0x5 -+#define PHY_RATE_MCS6 0x6 -+#define PHY_RATE_MCS7 0x7 -+#define PHY_RATE_MCS32 0x20 -+ -+#define RATE_CCK_1M_LONG (TX_MODE_CCK | PHY_RATE_1M) -+#define RATE_CCK_2M_LONG (TX_MODE_CCK | PHY_RATE_2M) -+#define RATE_CCK_5_5M_LONG (TX_MODE_CCK | PHY_RATE_5_5M) -+#define RATE_CCK_11M_LONG (TX_MODE_CCK | PHY_RATE_11M) -+#define RATE_CCK_2M_SHORT (TX_MODE_CCK | PHY_RATE_2M | RATE_CCK_SHORT_PREAMBLE) -+#define RATE_CCK_5_5M_SHORT (TX_MODE_CCK | PHY_RATE_5_5M | RATE_CCK_SHORT_PREAMBLE) -+#define RATE_CCK_11M_SHORT (TX_MODE_CCK | PHY_RATE_11M | RATE_CCK_SHORT_PREAMBLE) -+#define RATE_OFDM_6M (TX_MODE_OFDM | RATE_OFDM | PHY_RATE_6M) -+#define RATE_OFDM_9M (TX_MODE_OFDM | RATE_OFDM | PHY_RATE_9M) -+#define RATE_OFDM_12M (TX_MODE_OFDM | RATE_OFDM | PHY_RATE_12M) -+#define RATE_OFDM_18M (TX_MODE_OFDM | RATE_OFDM | PHY_RATE_18M) -+#define RATE_OFDM_24M (TX_MODE_OFDM | RATE_OFDM | PHY_RATE_24M) -+#define RATE_OFDM_36M (TX_MODE_OFDM | RATE_OFDM | PHY_RATE_36M) -+#define RATE_OFDM_48M (TX_MODE_OFDM | RATE_OFDM | PHY_RATE_48M) -+#define RATE_OFDM_54M (TX_MODE_OFDM | RATE_OFDM | PHY_RATE_54M) -+ -+#define RATE_MM_MCS_0 (TX_MODE_HT_MM | PHY_RATE_MCS0) -+#define RATE_MM_MCS_1 (TX_MODE_HT_MM | PHY_RATE_MCS1) -+#define RATE_MM_MCS_2 (TX_MODE_HT_MM | PHY_RATE_MCS2) -+#define RATE_MM_MCS_3 (TX_MODE_HT_MM | PHY_RATE_MCS3) -+#define RATE_MM_MCS_4 (TX_MODE_HT_MM | PHY_RATE_MCS4) -+#define RATE_MM_MCS_5 (TX_MODE_HT_MM | PHY_RATE_MCS5) -+#define RATE_MM_MCS_6 (TX_MODE_HT_MM | PHY_RATE_MCS6) -+#define RATE_MM_MCS_7 (TX_MODE_HT_MM | PHY_RATE_MCS7) -+#define RATE_MM_MCS_32 (TX_MODE_HT_MM | PHY_RATE_MCS32) -+ -+#define RATE_GF_MCS_0 (TX_MODE_HT_GF | PHY_RATE_MCS0) -+#define RATE_GF_MCS_1 (TX_MODE_HT_GF | PHY_RATE_MCS1) -+#define RATE_GF_MCS_2 (TX_MODE_HT_GF | PHY_RATE_MCS2) -+#define RATE_GF_MCS_3 (TX_MODE_HT_GF | PHY_RATE_MCS3) -+#define RATE_GF_MCS_4 (TX_MODE_HT_GF | PHY_RATE_MCS4) -+#define RATE_GF_MCS_5 (TX_MODE_HT_GF | PHY_RATE_MCS5) -+#define RATE_GF_MCS_6 (TX_MODE_HT_GF | PHY_RATE_MCS6) -+#define RATE_GF_MCS_7 (TX_MODE_HT_GF | PHY_RATE_MCS7) -+#define RATE_GF_MCS_32 (TX_MODE_HT_GF | PHY_RATE_MCS32) -+ -+#define RATE_TX_MODE_MASK BITS(6, 7) -+#define RATE_TX_MODE_OFFSET 6 -+#define RATE_CODE_GET_TX_MODE(_ucRateCode) ((_ucRateCode & RATE_TX_MODE_MASK) >> RATE_TX_MODE_OFFSET) -+#define RATE_PHY_RATE_MASK BITS(0, 5) -+#define RATE_PHY_RATE_OFFSET 0 -+#define RATE_CODE_GET_PHY_RATE(_ucRateCode) ((_ucRateCode & RATE_PHY_RATE_MASK) >> RATE_PHY_RATE_OFFSET) -+#define RATE_PHY_RATE_SHORT_PREAMBLE BIT(4) -+#define RATE_CODE_IS_SHORT_PREAMBLE(_ucRateCode) ((_ucRateCode & RATE_PHY_RATE_SHORT_PREAMBLE)?TRUE:FALSE) -+ -+#define CHNL_LIST_SZ_2G 14 -+#define CHNL_LIST_SZ_5G 14 -+ -+/*! CNM(STA_RECORD_T) related definition */ -+#define CFG_STA_REC_NUM 20 -+ -+/* PHY TYPE bit definitions */ -+#define PHY_TYPE_BIT_HR_DSSS BIT(PHY_TYPE_HR_DSSS_INDEX) /* HR/DSSS PHY (clause 18) */ -+#define PHY_TYPE_BIT_ERP BIT(PHY_TYPE_ERP_INDEX) /* ERP PHY (clause 19) */ -+#define PHY_TYPE_BIT_OFDM BIT(PHY_TYPE_OFDM_INDEX) /* OFDM 5 GHz PHY (clause 17) */ -+#define PHY_TYPE_BIT_HT BIT(PHY_TYPE_HT_INDEX) /* HT PHY (clause 20) */ -+ -+/* PHY TYPE set definitions */ -+#define PHY_TYPE_SET_802_11ABGN (PHY_TYPE_BIT_OFDM | \ -+ PHY_TYPE_BIT_HR_DSSS | \ -+ PHY_TYPE_BIT_ERP | \ -+ PHY_TYPE_BIT_HT) -+ -+#define PHY_TYPE_SET_802_11BGN (PHY_TYPE_BIT_HR_DSSS | \ -+ PHY_TYPE_BIT_ERP | \ -+ PHY_TYPE_BIT_HT) -+ -+#define PHY_TYPE_SET_802_11GN (PHY_TYPE_BIT_ERP | \ -+ PHY_TYPE_BIT_HT) -+ -+#define PHY_TYPE_SET_802_11AN (PHY_TYPE_BIT_OFDM | \ -+ PHY_TYPE_BIT_HT) -+ -+#define PHY_TYPE_SET_802_11ABG (PHY_TYPE_BIT_OFDM | \ -+ PHY_TYPE_BIT_HR_DSSS | \ -+ PHY_TYPE_BIT_ERP) -+ -+#define PHY_TYPE_SET_802_11BG (PHY_TYPE_BIT_HR_DSSS | \ -+ PHY_TYPE_BIT_ERP) -+ -+#define PHY_TYPE_SET_802_11A (PHY_TYPE_BIT_OFDM) -+ -+#define PHY_TYPE_SET_802_11G (PHY_TYPE_BIT_ERP) -+ -+#define PHY_TYPE_SET_802_11B (PHY_TYPE_BIT_HR_DSSS) -+ -+#define PHY_TYPE_SET_802_11N (PHY_TYPE_BIT_HT) -+ -+/* Rate set bit definitions */ -+#define RATE_SET_BIT_1M BIT(RATE_1M_INDEX) /* Bit 0: 1M */ -+#define RATE_SET_BIT_2M BIT(RATE_2M_INDEX) /* Bit 1: 2M */ -+#define RATE_SET_BIT_5_5M BIT(RATE_5_5M_INDEX) /* Bit 2: 5.5M */ -+#define RATE_SET_BIT_11M BIT(RATE_11M_INDEX) /* Bit 3: 11M */ -+#define RATE_SET_BIT_22M BIT(RATE_22M_INDEX) /* Bit 4: 22M */ -+#define RATE_SET_BIT_33M BIT(RATE_33M_INDEX) /* Bit 5: 33M */ -+#define RATE_SET_BIT_6M BIT(RATE_6M_INDEX) /* Bit 6: 6M */ -+#define RATE_SET_BIT_9M BIT(RATE_9M_INDEX) /* Bit 7: 9M */ -+#define RATE_SET_BIT_12M BIT(RATE_12M_INDEX) /* Bit 8: 12M */ -+#define RATE_SET_BIT_18M BIT(RATE_18M_INDEX) /* Bit 9: 18M */ -+#define RATE_SET_BIT_24M BIT(RATE_24M_INDEX) /* Bit 10: 24M */ -+#define RATE_SET_BIT_36M BIT(RATE_36M_INDEX) /* Bit 11: 36M */ -+#define RATE_SET_BIT_48M BIT(RATE_48M_INDEX) /* Bit 12: 48M */ -+#define RATE_SET_BIT_54M BIT(RATE_54M_INDEX) /* Bit 13: 54M */ -+#define RATE_SET_BIT_HT_PHY BIT(RATE_HT_PHY_INDEX) /* Bit 14: BSS Selector */ -+ -+/* Rate set definitions */ -+#define RATE_SET_HR_DSSS (RATE_SET_BIT_1M | \ -+ RATE_SET_BIT_2M | \ -+ RATE_SET_BIT_5_5M | \ -+ RATE_SET_BIT_11M) -+ -+#define RATE_SET_ERP (RATE_SET_BIT_1M | \ -+ RATE_SET_BIT_2M | \ -+ RATE_SET_BIT_5_5M | \ -+ RATE_SET_BIT_11M | \ -+ RATE_SET_BIT_6M | \ -+ RATE_SET_BIT_9M | \ -+ RATE_SET_BIT_12M | \ -+ RATE_SET_BIT_18M | \ -+ RATE_SET_BIT_24M | \ -+ RATE_SET_BIT_36M | \ -+ RATE_SET_BIT_48M | \ -+ RATE_SET_BIT_54M) -+ -+#define RATE_SET_ERP_P2P (RATE_SET_BIT_6M | \ -+ RATE_SET_BIT_9M | \ -+ RATE_SET_BIT_12M | \ -+ RATE_SET_BIT_18M | \ -+ RATE_SET_BIT_24M | \ -+ RATE_SET_BIT_36M | \ -+ RATE_SET_BIT_48M | \ -+ RATE_SET_BIT_54M) -+ -+#define RATE_SET_OFDM (RATE_SET_BIT_6M | \ -+ RATE_SET_BIT_9M | \ -+ RATE_SET_BIT_12M | \ -+ RATE_SET_BIT_18M | \ -+ RATE_SET_BIT_24M | \ -+ RATE_SET_BIT_36M | \ -+ RATE_SET_BIT_48M | \ -+ RATE_SET_BIT_54M) -+ -+#define RATE_SET_HT (RATE_SET_ERP) -+/* #define RATE_SET_HT (RATE_SET_ERP | RATE_SET_BIT_HT_PHY) *//* NOTE(Kevin): TBD */ -+ -+#define RATE_SET_ALL_ABG RATE_SET_ERP -+ -+#define BASIC_RATE_SET_HR_DSSS (RATE_SET_BIT_1M | \ -+ RATE_SET_BIT_2M) -+ -+#define BASIC_RATE_SET_HR_DSSS_ERP (RATE_SET_BIT_1M | \ -+ RATE_SET_BIT_2M | \ -+ RATE_SET_BIT_5_5M | \ -+ RATE_SET_BIT_11M) -+ -+#define BASIC_RATE_SET_ERP (RATE_SET_BIT_1M | \ -+ RATE_SET_BIT_2M | \ -+ RATE_SET_BIT_5_5M | \ -+ RATE_SET_BIT_11M | \ -+ RATE_SET_BIT_6M | \ -+ RATE_SET_BIT_12M | \ -+ RATE_SET_BIT_24M) -+ -+#define BASIC_RATE_SET_OFDM (RATE_SET_BIT_6M | \ -+ RATE_SET_BIT_12M | \ -+ RATE_SET_BIT_24M) -+ -+#define BASIC_RATE_SET_ERP_P2P (RATE_SET_BIT_6M | \ -+ RATE_SET_BIT_12M | \ -+ RATE_SET_BIT_24M) -+ -+#define INITIAL_RATE_SET_RCPI_100 RATE_SET_ALL_ABG -+ -+#define INITIAL_RATE_SET_RCPI_80 (RATE_SET_BIT_1M | \ -+ RATE_SET_BIT_2M | \ -+ RATE_SET_BIT_5_5M | \ -+ RATE_SET_BIT_11M | \ -+ RATE_SET_BIT_6M | \ -+ RATE_SET_BIT_9M | \ -+ RATE_SET_BIT_12M | \ -+ RATE_SET_BIT_24M) -+ -+#define INITIAL_RATE_SET_RCPI_60 (RATE_SET_BIT_1M | \ -+ RATE_SET_BIT_2M | \ -+ RATE_SET_BIT_5_5M | \ -+ RATE_SET_BIT_11M | \ -+ RATE_SET_BIT_6M) -+ -+#define INITIAL_RATE_SET(_rcpi) (INITIAL_RATE_SET_ ## _rcpi) -+ -+#define RCPI_100 100 /* -60 dBm */ -+#define RCPI_80 80 /* -70 dBm */ -+#define RCPI_60 60 /* -80 dBm */ -+ -+/* The number of RCPI records used to calculate their average value */ -+#define MAX_NUM_RCPI_RECORDS 10 -+ -+/* The number of RCPI records used to calculate their average value */ -+#define NO_RCPI_RECORDS -128 -+#define MAX_RCPI_DBM 0 -+#define MIN_RCPI_DBM -100 -+ -+#define MAC_TX_RESERVED_FIELD 0 /* NOTE(Kevin): Should defined in tx.h */ -+ -+#define MAX_ASSOC_ID (CFG_STA_REC_NUM) /* Available AID: 1 ~ 20(STA_REC_NUM) */ -+ -+#define MAX_DEAUTH_INFO_COUNT 4 /* NOTE(Kevin): Used in auth.c */ -+#define MIN_DEAUTH_INTERVAL_MSEC 500 /* The minimum interval if continuously send Deauth Frame */ -+ -+/* Authentication Type */ -+#define AUTH_TYPE_OPEN_SYSTEM BIT(AUTH_ALGORITHM_NUM_OPEN_SYSTEM) -+#define AUTH_TYPE_SHARED_KEY BIT(AUTH_ALGORITHM_NUM_SHARED_KEY) -+#define AUTH_TYPE_FAST_BSS_TRANSITION BIT(AUTH_ALGORITHM_NUM_FAST_BSS_TRANSITION) -+ -+/* Authentication Retry Limit */ -+#define TX_AUTH_ASSOCI_RETRY_LIMIT 2 -+#define TX_AUTH_ASSOCI_RETRY_LIMIT_FOR_ROAMING 1 -+ -+/* WMM-2.2.1 WMM Information Element */ -+#define ELEM_MAX_LEN_WMM_INFO 7 -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+typedef UINT_16 PHY_TYPE, *P_PHY_TYPE; -+typedef UINT_8 RCPI, *P_RCPI; -+typedef UINT_8 ALC_VAL, *P_ALC_VAL; -+ -+typedef enum _ENUM_HW_BSSID_T { -+ BSSID_0 = 0, -+ BSSID_1, -+ BSSID_NUM -+} ENUM_HW_BSSID_T; -+ -+typedef enum _ENUM_HW_MAC_ADDR_T { -+ MAC_ADDR_0 = 0, -+ MAC_ADDR_1, -+ MAC_ADDR_NUM -+} ENUM_HW_MAC_ADDR_T; -+ -+typedef enum _ENUM_HW_OP_MODE_T { -+ HW_OP_MODE_STA = 0, -+ HW_OP_MODE_AP, -+ HW_OP_MODE_ADHOC, -+ HW_OP_MODE_NUM -+} ENUM_HW_OP_MODE_T; -+ -+typedef enum _ENUM_TSF_T { -+ ENUM_LOCAL_TSF_0, -+ ENUM_LOCAL_TSF_1, -+ ENUM_LOCAL_TSF_NUM -+} ENUM_LOCAL_TSF_T, *P_ENUM_LOCAL_TSF_T; -+ -+typedef enum _HAL_TS_HW_UPDATE_MODE { -+ HAL_TSF_HW_UPDATE_BY_TICK_AND_RECEIVED_FRAME, -+ HAL_TSF_HW_UPDATE_BY_TICK_ONLY, -+ HAL_TSF_HW_UPDATE_BY_RECEIVED_FRAME_ONLY, -+ HAL_TSF_HW_UPDATE_BY_TICK_AND_RECEIVED_FRAME_AD_HOC -+} HAL_TSF_HW_UPDATE_MODE; -+ -+typedef enum _ENUM_AC_T { -+ AC0 = 0, -+ AC1, -+ AC2, -+ AC3, -+ AC_NUM -+} ENUM_AC_T, *P_ENUM_AC_T; -+ -+/* The Type of Network been activated */ -+typedef enum _ENUM_NETWORK_TYPE_INDEX_T { -+ NETWORK_TYPE_AIS_INDEX = 0, -+ NETWORK_TYPE_P2P_INDEX, -+ NETWORK_TYPE_BOW_INDEX, -+ NETWORK_TYPE_INDEX_NUM -+} ENUM_NETWORK_TYPE_INDEX_T; -+ -+/* The Type of STA Type. */ -+typedef enum _ENUM_STA_TYPE_INDEX_T { -+ STA_TYPE_LEGACY_INDEX = 0, -+ STA_TYPE_P2P_INDEX, -+ STA_TYPE_BOW_INDEX, -+ STA_TYPE_INDEX_NUM -+} ENUM_STA_TYPE_INDEX_T; -+ -+#define STA_ROLE_BASE_INDEX 4 -+ -+typedef enum _ENUM_STA_ROLE_INDEX_T { -+ STA_ROLE_ADHOC_INDEX = STA_ROLE_BASE_INDEX, /* 4 */ -+ STA_ROLE_CLIENT_INDEX, -+ STA_ROLE_AP_INDEX, -+ STA_ROLE_TDLS_INDEX, -+ STA_ROLE_DLS_INDEX /* Note: need to extend P_CMD_UPDATE_STA_RECORD_T */ -+} ENUM_STA_ROLE_INDEX_T; -+ -+/* The Power State of a specific Network */ -+typedef enum _ENUM_PWR_STATE_T { -+ PWR_STATE_IDLE = 0, -+ PWR_STATE_ACTIVE, -+ PWR_STATE_PS, -+ PWR_STATE_NUM -+} ENUM_PWR_STATE_T; -+ -+typedef enum _ENUM_PHY_TYPE_INDEX_T { -+ /* PHY_TYPE_DSSS_INDEX, *//* DSSS PHY (clause 15) -- Not used anymore */ -+ PHY_TYPE_HR_DSSS_INDEX = 0, /* HR/DSSS PHY (clause 18) */ -+ PHY_TYPE_ERP_INDEX, /* ERP PHY (clause 19) */ -+ PHY_TYPE_ERP_P2P_INDEX, /* ERP PHY (clause 19) w/o HR/DSSS */ -+ PHY_TYPE_OFDM_INDEX, /* OFDM 5 GHz PHY (clause 17) */ -+ PHY_TYPE_HT_INDEX, /* HT PHY (clause 20) */ -+ PHY_TYPE_INDEX_NUM /* 5 */ -+} ENUM_PHY_TYPE_INDEX_T, *P_ENUM_PHY_TYPE_INDEX_T; -+ -+typedef enum _ENUM_ACPI_STATE_T { -+ ACPI_STATE_D0 = 0, -+ ACPI_STATE_D1, -+ ACPI_STATE_D2, -+ ACPI_STATE_D3 -+} ENUM_ACPI_STATE_T; -+ -+/* The operation mode of a specific Network */ -+typedef enum _ENUM_OP_MODE_T { -+ OP_MODE_INFRASTRUCTURE = 0, /* Infrastructure/GC */ -+ OP_MODE_IBSS, /* AdHoc */ -+ OP_MODE_ACCESS_POINT, /* For GO */ -+ OP_MODE_P2P_DEVICE, /* P2P Device */ -+ OP_MODE_BOW, -+ OP_MODE_NUM -+} ENUM_OP_MODE_T, *P_ENUM_OP_MODE_T; -+ -+typedef enum _ENUM_CHNL_EXT_T { -+ CHNL_EXT_SCN = 0, -+ CHNL_EXT_SCA = 1, -+ CHNL_EXT_RES = 2, -+ CHNL_EXT_SCB = 3 -+} ENUM_CHNL_EXT_T, *P_ENUM_CHNL_EXT_T; -+ -+/* This starting freq of the band is unit of kHz */ -+typedef enum _ENUM_BAND_T { -+ BAND_NULL, -+ BAND_2G4, -+ BAND_5G, -+ BAND_NUM -+} ENUM_BAND_T, *P_ENUM_BAND_T; -+ -+/* Provide supported channel list to other components in array format */ -+typedef struct _RF_CHANNEL_INFO_T { -+ ENUM_BAND_T eBand; -+ UINT_8 ucChannelNum; -+} RF_CHANNEL_INFO_T, *P_RF_CHANNEL_INFO_T; -+ -+typedef enum _ENUM_RATE_INDEX_T { -+ RATE_1M_INDEX = 0, /* 1M */ -+ RATE_2M_INDEX, /* 2M */ -+ RATE_5_5M_INDEX, /* 5.5M */ -+ RATE_11M_INDEX, /* 11M */ -+ RATE_22M_INDEX, /* 22M */ -+ RATE_33M_INDEX, /* 33M */ -+ RATE_6M_INDEX, /* 6M */ -+ RATE_9M_INDEX, /* 9M */ -+ RATE_12M_INDEX, /* 12M */ -+ RATE_18M_INDEX, /* 18M */ -+ RATE_24M_INDEX, /* 24M */ -+ RATE_36M_INDEX, /* 36M */ -+ RATE_48M_INDEX, /* 48M */ -+ RATE_54M_INDEX, /* 54M */ -+ RATE_HT_PHY_INDEX, /* BSS Selector - HT PHY */ -+ RATE_NUM /* 15 */ -+} ENUM_RATE_INDEX_T, *P_ENUM_RATE_INDEX_T; -+ -+typedef enum _ENUM_HT_RATE_INDEX_T { -+ HT_RATE_MCS0_INDEX = 0, -+ HT_RATE_MCS1_INDEX, -+ HT_RATE_MCS2_INDEX, -+ HT_RATE_MCS3_INDEX, -+ HT_RATE_MCS4_INDEX, -+ HT_RATE_MCS5_INDEX, -+ HT_RATE_MCS6_INDEX, -+ HT_RATE_MCS7_INDEX, -+ HT_RATE_MCS32_INDEX, -+ HT_RATE_NUM /* 9 */ -+} ENUM_HT_RATE_INDEX_T, *P_ENUM_HT_RATE_INDEX_T; -+ -+typedef enum _ENUM_PREMABLE_OPTION_T { -+ PREAMBLE_DEFAULT_LONG_NONE = 0, /* LONG for PHY_TYPE_HR_DSSS, NONE for PHY_TYPE_OFDM */ -+ PREAMBLE_OPTION_SHORT, /* SHORT mandatory for PHY_TYPE_ERP, SHORT option for PHY_TYPE_HR_DSSS */ -+ PREAMBLE_HT_MIXED_MODE, -+ PREAMBLE_HT_GREEN_FIELD, -+ PREAMBLE_OPTION_NUM -+} ENUM_PREMABLE_OPTION_T, *P_ENUM_PREMABLE_OPTION_T; -+ -+typedef enum _ENUM_CHANNEL_WIDTH_T { -+ CW_20_40MHZ = 0, -+ CW_80MHZ = 1, -+ CW_160MHZ = 2, -+ CW_80P80MHZ = 3 -+} ENUM_CHANNEL_WIDTH_T, *P_ENUM_CHANNEL_WIDTH_P; -+ -+typedef enum _ENUM_MODULATION_SYSTEM_T { -+ MODULATION_SYSTEM_CCK = 0, -+ MODULATION_SYSTEM_OFDM, -+ MODULATION_SYSTEM_HT20, -+ MODULATION_SYSTEM_HT40, -+ MODULATION_SYSTEM_NUM -+} ENUM_MODULATION_SYSTEM_T, *P_ENUM_MODULATION_SYSTEM_T; -+ -+typedef enum _ENUM_MODULATION_TYPE_T { -+ MODULATION_TYPE_CCK_BPSK = 0, -+ MODULATION_TYPE_QPSK, -+ MODULATION_TYPE_16QAM, -+ MODULATION_TYPE_64QAM, -+ MODULATION_TYPE_NUM -+} ENUM_MODULATION_TYPE_T, *P_ENUM_MODULATION_TYPE_T; -+ -+typedef enum _ENUM_PS_FORWARDING_TYPE_T { -+ PS_FORWARDING_TYPE_NON_PS = 0, -+ PS_FORWARDING_TYPE_DELIVERY_ENABLED, -+ PS_FORWARDING_TYPE_NON_DELIVERY_ENABLED, -+ PS_FORWARDING_MORE_DATA_ENABLED, -+ PS_FORWARDING_TYPE_NUM -+} ENUM_PS_FORWARDING_TYPE_T, *P_ENUM_PS_FORWARDING_TYPE_T; -+ -+typedef struct _DEAUTH_INFO_T { -+ UINT_8 aucRxAddr[MAC_ADDR_LEN]; -+ OS_SYSTIME rLastSendTime; -+} DEAUTH_INFO_T, *P_DEAUTH_INFO_T; -+ -+/*----------------------------------------------------------------------------*/ -+/* Information Element (IE) handlers */ -+/*----------------------------------------------------------------------------*/ -+typedef VOID(*PFN_APPEND_IE_FUNC) (P_ADAPTER_T, P_MSDU_INFO_T); -+typedef VOID(*PFN_HANDLE_IE_FUNC) (P_ADAPTER_T, P_SW_RFB_T, P_IE_HDR_T); -+typedef VOID(*PFN_VERIFY_IE_FUNC) (P_ADAPTER_T, P_SW_RFB_T, P_IE_HDR_T, PUINT_16); -+typedef UINT_32(*PFN_CALCULATE_VAR_IE_LEN_FUNC) (P_ADAPTER_T, ENUM_NETWORK_TYPE_INDEX_T, P_STA_RECORD_T); -+ -+typedef struct _APPEND_IE_ENTRY_T { -+ UINT_16 u2EstimatedIELen; -+ PFN_APPEND_IE_FUNC pfnAppendIE; -+} APPEND_IE_ENTRY_T, *P_APPEND_IE_ENTRY_T; -+ -+typedef struct _APPEND_VAR_IE_ENTRY_T { -+ UINT_16 u2EstimatedFixedIELen; /* For Fixed Length */ -+ PFN_CALCULATE_VAR_IE_LEN_FUNC pfnCalculateVariableIELen; -+ PFN_APPEND_IE_FUNC pfnAppendIE; -+} APPEND_VAR_IE_ENTRY_T, *P_APPEND_VAR_IE_ENTRY_T; -+ -+typedef struct _HANDLE_IE_ENTRY_T { -+ UINT_8 ucElemID; -+ PFN_HANDLE_IE_FUNC pfnHandleIE; -+} HANDLE_IE_ENTRY_T, *P_HANDLE_IE_ENTRY_T; -+ -+typedef struct _VERIFY_IE_ENTRY_T { -+ UINT_8 ucElemID; -+ PFN_VERIFY_IE_FUNC pfnVarifyIE; -+} VERIFY_IE_ENTRY_T, *P_VERIFY_IE_ENTRY_T; -+ -+/*----------------------------------------------------------------------------*/ -+/* Parameters of User Configuration */ -+/*----------------------------------------------------------------------------*/ -+typedef enum _ENUM_PARAM_CONNECTION_POLICY_T { -+ CONNECT_BY_SSID_BEST_RSSI = 0, -+ CONNECT_BY_SSID_GOOD_RSSI_MIN_CH_LOAD, -+ CONNECT_BY_SSID_ANY, /* NOTE(Kevin): Needed by WHQL */ -+ CONNECT_BY_BSSID, -+ CONNECT_BY_CUSTOMIZED_RULE /* NOTE(Kevin): TBD */ -+} ENUM_PARAM_CONNECTION_POLICY_T, *P_ENUM_PARAM_CONNECTION_POLICY_T; -+ -+typedef enum _ENUM_PARAM_PREAMBLE_TYPE_T { -+ PREAMBLE_TYPE_LONG = 0, -+ PREAMBLE_TYPE_SHORT, -+ PREAMBLE_TYPE_AUTO /*!< Try preamble short first, if fail tray preamble long. */ -+} ENUM_PARAM_PREAMBLE_TYPE_T, *P_ENUM_PARAM_PREAMBLE_TYPE_T; -+ -+/* This is enum defined for user to select a phy config listed in combo box */ -+typedef enum _ENUM_PARAM_PHY_CONFIG_T { -+ /*!< Can associated with 802.11abg AP but without n capability, Scan dual band. */ -+ PHY_CONFIG_802_11ABG = 0, -+ PHY_CONFIG_802_11BG, /*!< Can associated with 802_11bg AP, Scan single band and not report 5G BSSs. */ -+ PHY_CONFIG_802_11G, /*!< Can associated with 802_11g only AP, Scan single band and not report 5G BSSs. */ -+ PHY_CONFIG_802_11A, /*!< Can associated with 802_11a only AP, Scan single band and not report 2.4G BSSs. */ -+ PHY_CONFIG_802_11B, /*!< Can associated with 802_11b only AP, Scan single band and not report 5G BSSs. */ -+ PHY_CONFIG_802_11ABGN, /*!< Can associated with 802.11abgn AP, Scan dual band. */ -+ PHY_CONFIG_802_11BGN, /*!< Can associated with 802_11bgn AP, Scan single band and not report 5G BSSs. */ -+ PHY_CONFIG_802_11AN, /*!< Can associated with 802_11an AP, Scan single band and not report 2.4G BSSs. */ -+ PHY_CONFIG_802_11GN, /*!< Can associated with 802_11gn AP, Scan single band and not report 5G BSSs. */ -+ PHY_CONFIG_NUM /* 9 */ -+} ENUM_PARAM_PHY_CONFIG_T, *P_ENUM_PARAM_PHY_CONFIG_T; -+ -+/* This is enum defined for user to select an AP Mode */ -+typedef enum _ENUM_PARAM_AP_MODE_T { -+ AP_MODE_11B = 0, /*!< Create 11b BSS if we support 802.11abg/802.11bg. */ -+ AP_MODE_MIXED_11BG, /*!< Create 11bg mixed BSS if we support 802.11abg/802.11bg/802.11g. */ -+ AP_MODE_11G, /*!< Create 11g only BSS if we support 802.11abg/802.11bg/802.11g. */ -+ AP_MODE_11G_P2P, /*!< Create 11g only BSS for P2P if we support 802.11abg/802.11bg/802.11g. */ -+ AP_MODE_11A, /*!< Create 11a only BSS if we support 802.11abg. */ -+ AP_MODE_NUM /* 4 */ -+} ENUM_PARAM_AP_MODE_T, *P_ENUM_PARAM_AP_MODE_T; -+ -+/* Masks for determining the Network Type or the Station Role, given the ENUM_STA_TYPE_T */ -+#define NETWORK_TYPE_AIS_MASK BIT(NETWORK_TYPE_AIS_INDEX) -+#define NETWORK_TYPE_P2P_MASK BIT(NETWORK_TYPE_P2P_INDEX) -+#define NETWORK_TYPE_BOW_MASK BIT(NETWORK_TYPE_BOW_INDEX) -+#define STA_TYPE_LEGACY_MASK BIT(STA_TYPE_LEGACY_INDEX) -+#define STA_TYPE_P2P_MASK BIT(STA_TYPE_P2P_INDEX) -+#define STA_TYPE_BOW_MASK BIT(STA_TYPE_BOW_INDEX) -+#define STA_TYPE_ADHOC_MASK BIT(STA_ROLE_ADHOC_INDEX) -+#define STA_TYPE_CLIENT_MASK BIT(STA_ROLE_CLIENT_INDEX) -+#define STA_TYPE_AP_MASK BIT(STA_ROLE_AP_INDEX) -+#define STA_TYPE_DLS_MASK BIT(STA_ROLE_DLS_INDEX) -+#define STA_TYPE_TDLS_MASK BIT(STA_ROLE_TDLS_INDEX) -+ -+/* Macros for obtaining the Network Type or the Station Role, given the ENUM_STA_TYPE_T */ -+#define IS_STA_IN_AIS(_prStaRec) ((_prStaRec)->ucNetTypeIndex == NETWORK_TYPE_AIS_INDEX) -+#define IS_STA_IN_P2P(_prStaRec) ((_prStaRec)->ucNetTypeIndex == NETWORK_TYPE_P2P_INDEX) -+#define IS_STA_IN_BOW(_prStaRec) ((_prStaRec)->ucNetTypeIndex == NETWORK_TYPE_BOW_INDEX) -+#define IS_STA_LEGACY_TYPE(_prStaRec) ((_prStaRec->eStaType) & STA_TYPE_LEGACY_MASK) -+#define IS_STA_P2P_TYPE(_prStaRec) ((_prStaRec->eStaType) & STA_TYPE_P2P_MASK) -+#define IS_STA_BOW_TYPE(_prStaRec) ((_prStaRec->eStaType) & STA_TYPE_BOW_MASK) -+#define IS_ADHOC_STA(_prStaRec) ((_prStaRec->eStaType) & STA_TYPE_ADHOC_MASK) -+#define IS_CLIENT_STA(_prStaRec) ((_prStaRec->eStaType) & STA_TYPE_CLIENT_MASK) -+#define IS_AP_STA(_prStaRec) ((_prStaRec->eStaType) & STA_TYPE_AP_MASK) -+#define IS_DLS_STA(_prStaRec) ((_prStaRec->eStaType) & STA_TYPE_DLS_MASK) -+#define IS_TDLS_STA(_prStaRec) ((_prStaRec->eStaType) & STA_TYPE_TDLS_MASK) -+ -+/* The ENUM_STA_TYPE_T accounts for ENUM_NETWORK_TYPE_T and ENUM_STA_ROLE_INDEX_T. -+ * * It is a merged version of Network Type and STA Role. -+ * */ -+typedef enum _ENUM_STA_TYPE_T { -+ STA_TYPE_LEGACY_AP = (STA_TYPE_LEGACY_MASK | STA_TYPE_AP_MASK), -+ STA_TYPE_LEGACY_CLIENT = (STA_TYPE_LEGACY_MASK | STA_TYPE_CLIENT_MASK), -+ STA_TYPE_ADHOC_PEER = (STA_TYPE_LEGACY_MASK | STA_TYPE_ADHOC_MASK), -+#if CFG_ENABLE_WIFI_DIRECT -+ STA_TYPE_P2P_GO = (STA_TYPE_P2P_MASK | STA_TYPE_AP_MASK), -+ STA_TYPE_P2P_GC = (STA_TYPE_P2P_MASK | STA_TYPE_CLIENT_MASK), -+#endif -+#if CFG_ENABLE_BT_OVER_WIFI -+ STA_TYPE_BOW_AP = (STA_TYPE_BOW_MASK | STA_TYPE_AP_MASK), -+ STA_TYPE_BOW_CLIENT = (STA_TYPE_BOW_MASK | STA_TYPE_CLIENT_MASK), -+#endif -+ STA_TYPE_DLS_PEER = (STA_TYPE_LEGACY_MASK | STA_TYPE_DLS_MASK), -+ STA_TYPE_TDLS_PEER = (STA_TYPE_LEGACY_MASK | STA_TYPE_TDLS_MASK) -+} ENUM_STA_TYPE_T, *P_ENUM_STA_TYPE_T; -+ -+/* The type of BSS we discovered */ -+typedef enum _ENUM_BSS_TYPE_T { -+ BSS_TYPE_INFRASTRUCTURE = 1, -+ BSS_TYPE_IBSS, -+ BSS_TYPE_P2P_DEVICE, -+ BSS_TYPE_BOW_DEVICE, -+ BSS_TYPE_NUM -+} ENUM_BSS_TYPE_T, *P_ENUM_BSS_TYPE_T; -+ -+/*----------------------------------------------------------------------------*/ -+/* RSN structures */ -+/*----------------------------------------------------------------------------*/ -+/* #if defined(WINDOWS_DDK) || defined(WINDOWS_CE) */ -+/* #pragma pack(1) */ -+/* #endif */ -+ -+#define MAX_NUM_SUPPORTED_CIPHER_SUITES 8 /* max number of supported cipher suites */ -+#if CFG_SUPPORT_802_11W -+#define MAX_NUM_SUPPORTED_AKM_SUITES 8 /* max number of supported AKM suites */ -+#else -+#define MAX_NUM_SUPPORTED_AKM_SUITES 6 /* max number of supported AKM suites */ -+#endif -+ -+/* Structure of RSN Information */ -+typedef struct _RSN_INFO_T { -+ UINT_8 ucElemId; -+ UINT_16 u2Version; -+ UINT_32 u4GroupKeyCipherSuite; -+ UINT_32 u4PairwiseKeyCipherSuiteCount; -+ UINT_32 au4PairwiseKeyCipherSuite[MAX_NUM_SUPPORTED_CIPHER_SUITES]; -+ UINT_32 u4AuthKeyMgtSuiteCount; -+ UINT_32 au4AuthKeyMgtSuite[MAX_NUM_SUPPORTED_AKM_SUITES]; -+ UINT_16 u2RsnCap; -+ BOOLEAN fgRsnCapPresent; -+} /*__KAL_ATTRIB_PACKED__*/ RSN_INFO_T, *P_RSN_INFO_T; -+ -+#define MAX_NUM_SUPPORTED_WAPI_AKM_SUITES 1 /* max number of supported AKM suites */ -+#define MAX_NUM_SUPPORTED_WAPI_CIPHER_SUITES 1 /* max number of supported cipher suites */ -+ -+/* Structure of WAPI Information */ -+typedef struct _WAPI_INFO_T { -+ UINT_8 ucElemId; -+ UCHAR ucLength; -+ UINT_16 u2Version; -+ UINT_32 u4AuthKeyMgtSuiteCount; -+ UINT_32 au4AuthKeyMgtSuite[MAX_NUM_SUPPORTED_WAPI_AKM_SUITES]; -+ UINT_32 u4PairwiseKeyCipherSuiteCount; -+ UINT_32 au4PairwiseKeyCipherSuite[MAX_NUM_SUPPORTED_WAPI_CIPHER_SUITES]; -+ UINT_32 u4GroupKeyCipherSuite; -+ UINT_16 u2WapiCap; -+ UINT_16 u2Bkid; -+ UINT_8 aucBkid[1][16]; -+} /* __KAL_ATTRIB_PACKED__ */ WAPI_INFO_T, *P_WAPI_INFO_T; -+ -+/* #if defined(WINDOWS_DDK) || defined(WINDOWS_CE) */ -+/* #pragma pack() */ -+/* #endif */ -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ -+typedef struct _P2P_DEVICE_TYPE_T { -+ UINT_16 u2CategoryID; -+ UINT_16 u2SubCategoryID; -+} P2P_DEVICE_TYPE_T, *P_P2P_DEVICE_TYPE_T; -+ -+typedef struct _P2P_DEVICE_DESC_T { -+ LINK_ENTRY_T rLinkEntry; -+ BOOLEAN fgDevInfoValid; -+ UINT_8 aucDeviceAddr[MAC_ADDR_LEN]; /* Device Address. */ -+ UINT_8 aucInterfaceAddr[MAC_ADDR_LEN]; /* Interface Address. */ -+ UINT_8 ucDeviceCapabilityBitmap; -+ UINT_8 ucGroupCapabilityBitmap; -+ UINT_16 u2ConfigMethod; /* Configure Method support. */ -+ P2P_DEVICE_TYPE_T rPriDevType; -+ UINT_8 ucSecDevTypeNum; -+ P2P_DEVICE_TYPE_T arSecDevType[8]; /* Reference to P2P_GC_MAX_CACHED_SEC_DEV_TYPE_COUNT */ -+ UINT_16 u2NameLength; -+ UINT_8 aucName[32]; /* Reference to WPS_ATTRI_MAX_LEN_DEVICE_NAME */ -+ /* TODO: Service Information or PasswordID valid? */ -+} P2P_DEVICE_DESC_T, *P_P2P_DEVICE_DESC_T; -+ -+#endif -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+static const UINT_8 aucRateIndex2RateCode[PREAMBLE_OPTION_NUM][RATE_NUM] = { -+ { /* Long Preamble */ -+ RATE_CCK_1M_LONG, /* RATE_1M_INDEX = 0 */ -+ RATE_CCK_2M_LONG, /* RATE_2M_INDEX */ -+ RATE_CCK_5_5M_LONG, /* RATE_5_5M_INDEX */ -+ RATE_CCK_11M_LONG, /* RATE_11M_INDEX */ -+ RATE_CCK_1M_LONG, /* RATE_22M_INDEX - Not supported */ -+ RATE_CCK_1M_LONG, /* RATE_33M_INDEX - Not supported */ -+ RATE_OFDM_6M, /* RATE_6M_INDEX */ -+ RATE_OFDM_9M, /* RATE_9M_INDEX */ -+ RATE_OFDM_12M, /* RATE_12M_INDEX */ -+ RATE_OFDM_18M, /* RATE_18M_INDEX */ -+ RATE_OFDM_24M, /* RATE_24M_INDEX */ -+ RATE_OFDM_36M, /* RATE_36M_INDEX */ -+ RATE_OFDM_48M, /* RATE_48M_INDEX */ -+ RATE_OFDM_54M, /* RATE_54M_INDEX */ -+ }, -+ { /* Short Preamble */ -+ RATE_CCK_1M_LONG, /* RATE_1M_INDEX = 0 */ -+ RATE_CCK_2M_SHORT, /* RATE_2M_INDEX */ -+ RATE_CCK_5_5M_SHORT, /* RATE_5_5M_INDEX */ -+ RATE_CCK_11M_SHORT, /* RATE_11M_INDEX */ -+ RATE_CCK_1M_LONG, /* RATE_22M_INDEX - Not supported */ -+ RATE_CCK_1M_LONG, /* RATE_33M_INDEX - Not supported */ -+ RATE_OFDM_6M, /* RATE_6M_INDEX */ -+ RATE_OFDM_9M, /* RATE_9M_INDEX */ -+ RATE_OFDM_12M, /* RATE_12M_INDEX */ -+ RATE_OFDM_18M, /* RATE_18M_INDEX */ -+ RATE_OFDM_24M, /* RATE_24M_INDEX */ -+ RATE_OFDM_36M, /* RATE_36M_INDEX */ -+ RATE_OFDM_48M, /* RATE_48M_INDEX */ -+ RATE_OFDM_54M, /* RATE_54M_INDEX */ -+ }, -+ { /* Mixed Mode(Option) */ -+ RATE_MM_MCS_0, /* RATE_MCS0_INDEX, */ -+ RATE_MM_MCS_1, /* RATE_MCS1_INDEX, */ -+ RATE_MM_MCS_2, /* RATE_MCS2_INDEX, */ -+ RATE_MM_MCS_3, /* RATE_MCS3_INDEX, */ -+ RATE_MM_MCS_4, /* RATE_MCS4_INDEX, */ -+ RATE_MM_MCS_5, /* RATE_MCS5_INDEX, */ -+ RATE_MM_MCS_6, /* RATE_MCS6_INDEX, */ -+ RATE_MM_MCS_7, /* RATE_MCS7_INDEX, */ -+ RATE_MM_MCS_32 /* RATE_MCS32_INDEX, */ -+ }, -+ { /* Green Field(Option) */ -+ RATE_GF_MCS_0, /* RATE_MCS0_INDEX, */ -+ RATE_GF_MCS_1, /* RATE_MCS1_INDEX, */ -+ RATE_GF_MCS_2, /* RATE_MCS2_INDEX, */ -+ RATE_GF_MCS_3, /* RATE_MCS3_INDEX, */ -+ RATE_GF_MCS_4, /* RATE_MCS4_INDEX, */ -+ RATE_GF_MCS_5, /* RATE_MCS5_INDEX, */ -+ RATE_GF_MCS_6, /* RATE_MCS6_INDEX, */ -+ RATE_GF_MCS_7, /* RATE_MCS7_INDEX, */ -+ RATE_GF_MCS_32 /* RATE_MCS32_INDEX, */ -+ } -+}; -+ -+static const UINT_8 aucRateTableSize[PREAMBLE_OPTION_NUM] = { -+ RATE_HT_PHY_INDEX, -+ RATE_HT_PHY_INDEX, -+ HT_RATE_NUM, -+ HT_RATE_NUM -+}; -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+/* Macros to get and set the wireless LAN frame fields those are 16/32 bits in -+ length. */ -+#define WLAN_GET_FIELD_16(_memAddr_p, _value_p) \ -+ { \ -+ PUINT_8 __cp = (PUINT_8) (_memAddr_p); \ -+ *(PUINT_16)(_value_p) = ((UINT_16) __cp[0]) | ((UINT_16) __cp[1] << 8); \ -+ } -+ -+#define WLAN_GET_FIELD_BE16(_memAddr_p, _value_p) \ -+ { \ -+ PUINT_8 __cp = (PUINT_8) (_memAddr_p); \ -+ *(PUINT_16)(_value_p) = ((UINT_16) __cp[0] << 8) | ((UINT_16) __cp[1]); \ -+ } -+ -+#define WLAN_GET_FIELD_32(_memAddr_p, _value_p) \ -+ { \ -+ PUINT_8 __cp = (PUINT_8) (_memAddr_p); \ -+ *(PUINT_32)(_value_p) = ((UINT_32) __cp[0]) | ((UINT_32) __cp[1] << 8) | \ -+ ((UINT_32) __cp[2] << 16) | ((UINT_32) __cp[3] << 24); \ -+ } -+ -+#define WLAN_GET_FIELD_64(_memAddr_p, _value_p) \ -+ { \ -+ PUINT_8 __cp = (PUINT_8) (_memAddr_p); \ -+ *(PUINT_64)(_value_p) = \ -+ ((UINT_64) __cp[0]) | ((UINT_64) __cp[1] << 8) | \ -+ ((UINT_64) __cp[2] << 16) | ((UINT_64) __cp[3] << 24) | \ -+ ((UINT_64) __cp[4] << 32) | ((UINT_64) __cp[5] << 40) | \ -+ ((UINT_64) __cp[6] << 48) | ((UINT_64) __cp[7] << 56); \ -+ } -+ -+#define WLAN_SET_FIELD_16(_memAddr_p, _value) \ -+ { \ -+ PUINT_8 __cp = (PUINT_8) (_memAddr_p); \ -+ __cp[0] = (UINT_8) (_value); \ -+ __cp[1] = (UINT_8) ((_value) >> 8); \ -+ } -+ -+#define WLAN_SET_FIELD_BE16(_memAddr_p, _value) \ -+ { \ -+ PUINT_8 __cp = (PUINT_8) (_memAddr_p); \ -+ __cp[0] = (UINT_8) ((_value) >> 8); \ -+ __cp[1] = (UINT_8) (_value); \ -+ } -+ -+#define WLAN_SET_FIELD_32(_memAddr_p, _value) \ -+ { \ -+ PUINT_8 __cp = (PUINT_8) (_memAddr_p); \ -+ __cp[0] = (UINT_8) (_value); \ -+ __cp[1] = (UINT_8) ((_value) >> 8); \ -+ __cp[2] = (UINT_8) ((_value) >> 16); \ -+ __cp[3] = (UINT_8) ((_value) >> 24); \ -+ } -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif /* _WLAN_DEF_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic_cmd_event.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic_cmd_event.h -new file mode 100644 -index 000000000000..aba2e040c194 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic_cmd_event.h -@@ -0,0 +1,2290 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/nic_cmd_event.h#1 -+*/ -+ -+/*! \file "nic_cmd_event.h" -+ \brief This file contains the declairation file of the WLAN OID processing routines -+ of Windows driver for MediaTek Inc. 802.11 Wireless LAN Adapters. -+*/ -+ -+/* -+** Log: nic_cmd_event.h -+ * -+ * 03 29 2012 eason.tsai -+ * [WCXRP00001216] [MT6628 Wi-Fi][Driver]add conditional define -+ * add conditional define. -+ * -+ * 03 04 2012 eason.tsai -+ * NULL -+ * modify the cal fail report code. -+ * -+ * 01 06 2012 wh.su -+ * [WCXRP00001153] [MT6620 Wi-Fi][Driver] Adding the get_ch_list and set_tx_power proto type function -+ * redefine the CMD_ID_SET_TXPWR_CTRL value. -+ * -+ * 01 05 2012 wh.su -+ * [WCXRP00001153] [MT6620 Wi-Fi][Driver] Adding the get_ch_list and set_tx_power proto type function -+ * Adding the related ioctl / wlan oid function to set the Tx power cfg. -+ * -+ * 11 30 2011 cm.chang -+ * [WCXRP00001128] [MT5931 Wi-Fi][FW] Update BB/RF setting based on RF doc v0.7 for LGE spec -+ * 1. Add a new CMD for driver to set device mode -+ * 2. Update calibration parameters -+ * -+ * 11 19 2011 yuche.tsai -+ * NULL -+ * Update RSSI for P2P. -+ * -+ * 11 18 2011 yuche.tsai -+ * NULL -+ * CONFIG P2P support RSSI query, default turned off. -+ * -+ * 11 10 2011 eddie.chen -+ * [WCXRP00001096] [MT6620 Wi-Fi][Driver/FW] Enhance the log function (xlog) -+ * Add TX_DONE status detail information. -+ * -+ * 11 08 2011 tsaiyuan.hsu -+ * [WCXRP00001083] [MT6620 Wi-Fi][DRV]] dump debug counter or frames when debugging is triggered -+ * check if CFG_SUPPORT_SWCR is defined to aoid compiler error. -+ * -+ * 11 07 2011 tsaiyuan.hsu -+ * [WCXRP00001083] [MT6620 Wi-Fi][DRV]] dump debug counter or frames when debugging is triggered -+ * add debug counters and periodically dump counters for debugging. -+ * -+ * 10 26 2011 cp.wu -+ * [WCXRP00001065] [MT6620 Wi-Fi][MT5931][FW][DRV] Adding parameter for controlling -+ * minimum channel dwell time for scanning -+ * add interface for control minimum channel dwell time for scanning. -+ * -+ * 09 20 2011 cm.chang -+ * [WCXRP00000997] [MT6620 Wi-Fi][Driver][FW] Handle change of BSS preamble type and slot time -+ * New CMD definition about RLM parameters -+ * -+ * 08 31 2011 cm.chang -+ * [WCXRP00000969] [MT6620 Wi-Fi][Driver][FW] Channel list for 5G band based on country code -+ * . -+ * -+ * 08 25 2011 chinghwa.yu -+ * [WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm -+ * Add DFS switch. -+ * -+ * 08 24 2011 chinghwa.yu -+ * [WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm -+ * Update RDD test mode cases. -+ * -+ * 08 15 2011 cp.wu -+ * [WCXRP00000851] [MT6628 Wi-Fi][Driver] Add HIFSYS related definition to driver source tree -+ * add MT6628-specific definitions. -+ * -+ * 08 11 2011 cp.wu -+ * [WCXRP00000830] [MT6620 Wi-Fi][Firmware] Use MDRDY counter to detect empty channel for shortening scan time -+ * sparse channel detection: -+ * driver: collect sparse channel information with scan-done event -+ * -+ * 08 09 2011 cp.wu -+ * [WCXRP00000702] [MT5931][Driver] Modify initialization sequence for E1 ASIC -+ * [WCXRP00000913] [MT6620 Wi-Fi] create repository of source code dedicated for MT6620 E6 ASIC -+ * add CCK-DSSS TX-PWR control field in NVRAM and CMD definition for MT5931-MP -+ * -+ * 08 03 2011 terry.wu -+ * [WCXRP00000899] [MT6620] [FW] Reply probe rsp in FW for hotspot mode -+ * Reply Probe Rsp in FW for Hotspot Mode. -+ * -+ * -+ * -+ * 08 03 2011 terry.wu -+ * [WCXRP00000899] [MT6620] [FW] Reply probe rsp in FW for hotspot mode -+ * Reply Probe Rsp in FW for Hotspot Mode. -+ * -+ * -+ * 08 03 2011 terry.wu -+ * [WCXRP00000899] [MT6620] [FW] Reply probe rsp in FW for hotspot mode -+ * Reply Probe Rsp in FW for Hotspot Mode. -+ * -+ * 08 03 2011 terry.wu -+ * [WCXRP00000899] [MT6620] [FW] Reply probe rsp in FW for hotspot mode -+ * Reply Probe Rsp in FW for Hotspot Mode. -+ * -+ * 07 28 2011 chinghwa.yu -+ * [WCXRP00000063] Update BCM CoEx design and settings -+ * Add BWCS cmd and event. -+ * -+ * 07 22 2011 jeffrey.chang -+ * [WCXRP00000864] [MT5931] Add command to adjust OSC stable time -+ * add osc stable time command structure -+ * -+ * 07 22 2011 jeffrey.chang -+ * [WCXRP00000864] [MT5931] Add command to adjust OSC stable time -+ * modify driver to set OSC stable time after f/w download -+ * -+ * 07 18 2011 chinghwa.yu -+ * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm -+ * Add CMD/Event for RDD and BWCS. -+ * -+ * 07 18 2011 cp.wu -+ * [WCXRP00000858] [MT5931][Driver][Firmware] Add support for scan to search for more than -+ * one SSID in a single scanning request -+ * add framework in driver domain for supporting new SCAN_REQ_V2 for more than 1 SSID -+ * support as well as uProbeDelay in NDIS 6.x driver model -+ * -+ * 06 23 2011 cp.wu -+ * [WCXRP00000812] [MT6620 Wi-Fi][Driver] not show NVRAM when there is no valid MAC address in NVRAM content -+ * check with firmware for valid MAC address. -+ * -+ * 06 23 2011 cp.wu -+ * [WCXRP00000798] [MT6620 Wi-Fi][Firmware] Follow-ups for WAPI frequency offset workaround in firmware SCN module -+ * change parameter name from PeerAddr to BSSID -+ * -+ * 06 20 2011 cp.wu -+ * [WCXRP00000798] [MT6620 Wi-Fi][Firmware] Follow-ups for WAPI frequency offset workaround in firmware SCN module -+ * 1. specify target's BSSID when requesting channel privilege. -+ * 2. pass BSSID information to firmware domain -+ * -+ * 06 09 2011 tsaiyuan.hsu -+ * [WCXRP00000760] [MT5931 Wi-Fi][FW] Refine rxmHandleMacRxDone to reduce code size -+ * move send_auth at rxmHandleMacRxDone in firmware to driver to reduce code size. -+ * -+ * 05 27 2011 cp.wu -+ * [WCXRP00000749] [MT6620 Wi-Fi][Driver] Add band edge tx power control to Wi-Fi NVRAM -+ * invoke CMD_ID_SET_EDGE_TXPWR_LIMIT when there is valid data exist in NVRAM content. -+ * -+ * 04 18 2011 terry.wu -+ * [WCXRP00000660] [MT6620 Wi-Fi][Driver] Remove flag CFG_WIFI_DIRECT_MOVED -+ * Remove flag CFG_WIFI_DIRECT_MOVED. -+ * -+ * 03 31 2011 chinglan.wang -+ * [WCXRP00000613] [MT6620 Wi-Fi] [FW] [Driver] BssInfo can get the security mode which is WPA/WPA2/WAPI or not. -+ * . -+ * -+ * 03 18 2011 cm.chang -+ * [WCXRP00000576] [MT6620 Wi-Fi][Driver][FW] Remove P2P compile option in scan req/cancel command -+ * As CR title -+ * -+ * 03 17 2011 yarco.yang -+ * [WCXRP00000569] [MT6620 Wi-Fi][F/W][Driver] Set multicast address support current network usage -+ * . -+ * -+ * 03 07 2011 wh.su -+ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code -+ * rename the define to anti_pviracy. -+ * -+ * 03 05 2011 wh.su -+ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code -+ * add the code to get the check rsponse and indicate to app. -+ * -+ * 03 02 2011 wh.su -+ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code -+ * Add Security check related code. -+ * -+ * 03 02 2011 george.huang -+ * [WCXRP00000504] [MT6620 Wi-Fi][FW] Support Sigma CAPI for power saving related command -+ * Support UAPSD/OppPS/NoA parameter setting -+ * -+ * 02 16 2011 cm.chang -+ * [WCXRP00000447] [MT6620 Wi-Fi][FW] Support new NVRAM update mechanism -+ * . -+ * -+ * 02 10 2011 cp.wu -+ * [WCXRP00000434] [MT6620 Wi-Fi][Driver] Obsolete unused event packet handlers -+ * EVENT_ID_CONNECTION_STATUS has been obsoleted and no need to handle. -+ * -+ * 02 08 2011 eddie.chen -+ * [WCXRP00000426] [MT6620 Wi-Fi][FW/Driver] Add STA aging timeout and defualtHwRatein AP mode -+ * Add event STA agint timeout -+ * -+ * 01 27 2011 tsaiyuan.hsu -+ * [WCXRP00000392] [MT6620 Wi-Fi][Driver] Add Roaming Support -+ * add roaming fsm -+ * 1. not support 11r, only use strength of signal to determine roaming. -+ * 2. not enable CFG_SUPPORT_ROAMING until completion of full test. -+ * 3. in 6620, adopt work-around to avoid sign extension problem of cck of hw -+ * 4. assume that change of link quality in smooth way. -+ * -+ * 01 25 2011 yuche.tsai -+ * [WCXRP00000352] [Volunteer Patch][MT6620][Driver] P2P Statsion Record Client List Issue -+ * Update cmd format of BSS INFO, always sync OwnMac to FW no matter P2P is enabled or not.. -+ * -+ * 01 20 2011 eddie.chen -+ * [WCXRP00000374] [MT6620 Wi-Fi][DRV] SW debug control -+ * Add Oid for sw control debug command -+ * -+ * 01 15 2011 puff.wen -+ * NULL -+ * Add Stress test -+ * -+ * 01 12 2011 cm.chang -+ * [WCXRP00000354] [MT6620 Wi-Fi][Driver][FW] Follow NVRAM bandwidth setting -+ * Sync HT operation element information from host to FW -+ * -+ * 01 12 2011 cm.chang -+ * [WCXRP00000354] [MT6620 Wi-Fi][Driver][FW] Follow NVRAM bandwidth setting -+ * User-defined bandwidth is for 2.4G and 5G individually -+ * -+ * 12 29 2010 eddie.chen -+ * [WCXRP00000322] Add WMM IE in beacon, -+ -+Add per station flow control when STA is in PS -+ -+ * 1) PS flow control event -+ * -+ * 2) WMM IE in beacon, assoc resp, probe resp -+ * -+ * 12 28 2010 cp.wu -+ * [WCXRP00000269] [MT6620 Wi-Fi][Driver][Firmware] Prepare for v1.1 branch release -+ * report EEPROM used flag via NIC_CAPABILITY -+ * -+ * 12 28 2010 cp.wu -+ * [WCXRP00000269] [MT6620 Wi-Fi][Driver][Firmware] Prepare for v1.1 branch release -+ * integrate with 'EEPROM used' flag for reporting correct capability to Engineer Mode/META and other tools -+ * -+ * 12 23 2010 george.huang -+ * [WCXRP00000152] [MT6620 Wi-Fi] AP mode power saving function -+ * 1. update WMM IE parsing, with ASSOC REQ handling -+ * 2. extend U-APSD parameter passing from driver to FW -+ * -+ * 12 07 2010 cm.chang -+ * [WCXRP00000239] MT6620 Wi-Fi][Driver][FW] Merge concurrent branch back to maintrunk -+ * 1. BSSINFO include RLM parameter -+ * 2. free all sta records when network is disconnected -+ * -+ * 12 07 2010 cm.chang -+ * [WCXRP00000238] MT6620 Wi-Fi][Driver][FW] Support regulation domain setting from NVRAM and supplicant -+ * 1. Country code is from NVRAM or supplicant -+ * 2. Change band definition in CMD/EVENT. -+ * -+ * 11 29 2010 cm.chang -+ * [WCXRP00000210] [MT6620 Wi-Fi][Driver][FW] Set RCPI value in STA_REC for -+ * initial TX rate selection of auto-rate algorithm -+ * Sync RCPI of STA_REC to FW as reference of initial TX rate -+ * -+ * 11 08 2010 cm.chang -+ * [WCXRP00000169] [MT6620 Wi-Fi][Driver][FW] Remove unused CNM recover message ID -+ * Remove CNM channel reover message ID -+ * -+ * 11 01 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check -+ * [WCXRP00000150] [MT6620 Wi-Fi][Driver] Add implementation for querying current TX rate from firmware auto rate module -+ * 1) Query link speed (TX rate) from firmware directly with buffering mechanism to reduce overhead -+ * 2) Remove CNM CH-RECOVER event handling -+ * 3) cfg read/write API renamed with kal prefix for unified naming rules. -+ * -+ * 10 26 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check -+ * [WCXRP00000137] [MT6620 Wi-Fi] [FW] Support NIC capability query command -+ * 1) update NVRAM content template to ver 1.02 -+ * 2) add compile option for querying NIC capability (default: off) -+ * 3) modify AIS 5GHz support to run-time option, which could be turned on by registry or NVRAM setting -+ * 4) correct auto-rate compiler error under linux (treat warning as error) -+ * 5) simplify usage of NVRAM and REG_INFO_T -+ * 6) add version checking between driver and firmware -+ * -+ * 10 25 2010 cp.wu -+ * [WCXRP00000133] [MT6620 Wi-Fi] [FW][Driver] Change TX power offset band definition -+ * follow-up for CMD_5G_PWR_OFFSET_T definition change -+ * -+ * 10 20 2010 cp.wu -+ * [WCXRP00000117] [MT6620 Wi-Fi][Driver] Add logic for suspending driver when MT6620 is not responding anymore -+ * use OID_CUSTOM_TEST_MODE as indication for driver reset -+ * by dropping pending TX packets -+ * -+ * 10 20 2010 wh.su -+ * [WCXRP00000124] [MT6620 Wi-Fi] [Driver] Support the dissolve P2P Group -+ * Add the code to support disconnect p2p group -+ * -+ * 09 15 2010 cm.chang -+ * NULL -+ * Add new CMD for TX power, 5G power offset and power parameters -+ * -+ * 09 07 2010 yuche.tsai -+ * NULL -+ * Add a pointer in P2P SCAN RESULT structure. This pointer -+ * is pointed to a IE buffer for this P2p device. -+ * -+ * 09 07 2010 wh.su -+ * NULL -+ * adding the code for beacon/probe req/ probe rsp wsc ie at p2p. -+ * -+ * 09 03 2010 kevin.huang -+ * NULL -+ * Refine #include sequence and solve recursive/nested #include issue -+ * -+ * 08 23 2010 chinghwa.yu -+ * NULL -+ * Update for BOW. -+ * -+ * 08 20 2010 cm.chang -+ * NULL -+ * Migrate RLM code to host from FW -+ * -+ * 08 16 2010 george.huang -+ * NULL -+ * add new CMD ID definition -+ * -+ * 08 16 2010 yuche.tsai -+ * NULL -+ * Add a field in BSS INFO cmd to change interface address for P2P. (switching between Device Addr & Interface Addr) -+ * -+ * 08 12 2010 yuche.tsai -+ * NULL -+ * Add interface address indication when indicate connection status. -+ * It is requested by supplicant to do 4 way handshake. -+ * -+ * 08 07 2010 wh.su -+ * NULL -+ * adding the privacy related code for P2P network -+ * -+ * 08 05 2010 yuche.tsai -+ * NULL -+ * Change data structure for P2P Device scan result, all channel time for scan command. -+ * -+ * 08 04 2010 george.huang -+ * NULL -+ * handle change PS mode OID/ CMD -+ * -+ * 08 04 2010 yarco.yang -+ * NULL -+ * Add TX_AMPDU and ADDBA_REJECT command -+ * -+ * 08 03 2010 george.huang -+ * NULL -+ * handle event for updating NOA parameters indicated from FW -+ * -+ * 08 02 2010 george.huang -+ * NULL -+ * add WMM-PS test related OID/ CMD handlers -+ * -+ * 07 28 2010 cp.wu -+ * NULL -+ * sync. CMD_BSS_INFO structure change to CMD-EVENT v0.15. -+ * -+ * 07 26 2010 yuche.tsai -+ * -+ * Add P2P Device Found Event. -+ * Channel extension option in scan abort command. -+ * -+ * 07 23 2010 cp.wu -+ * -+ * add AIS-FSM handling for beacon timeout event. -+ * -+ * 07 21 2010 yuche.tsai -+ * -+ * Add for P2P Scan Result Parsing & Saving. -+ * -+ * 07 20 2010 george.huang -+ * -+ * DWORD align for the CMD data structure -+ * -+ * 07 20 2010 cp.wu -+ * -+ * pass band information for scan in an efficient way by mapping ENUM_BAND_T into UINT_8.. -+ * -+ * 07 19 2010 wh.su -+ * -+ * update for security supporting. -+ * -+ * 07 19 2010 cm.chang -+ * -+ * Set RLM parameters and enable CNM channel manager -+ * -+ * 07 16 2010 yarco.yang -+ * -+ * 1. Support BSS Absence/Presence Event -+ * 2. Support STA change PS mode Event -+ * 3. Support BMC forwarding for AP mode. -+ * -+ * 07 14 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration. -+ * pass band with channel number information as scan parameter -+ * -+ * 07 14 2010 yarco.yang -+ * -+ * 1. Remove CFG_MQM_MIGRATION -+ * 2. Add CMD_UPDATE_WMM_PARMS command -+ * -+ * 07 09 2010 cp.wu -+ * -+ * reorder members of CMD_SET_BSS_INFO. -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 07 07 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * update prStaRecOfAP with BSS-INFO. -+ * -+ * 07 07 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Support state of STA record change from 1 to 1 -+ * -+ * 07 01 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Support sync command of STA_REC -+ * -+ * 07 01 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * implementation of DRV-SCN and related mailbox message handling. -+ * -+ * 06 30 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * sync. with CMD/EVENT document ver0.07. -+ * -+ * 06 29 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * correct variable naming for 8-bit variable used in CMD_BEACON_TEMPLATE_UPDATE. -+ * -+ * 06 29 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) sync to. CMD/EVENT document v0.03 -+ * 2) simplify DTIM period parsing in scan.c only, bss.c no longer parses it again. -+ * 3) send command packet to indicate FW-PM after -+ * a) 1st beacon is received after AIS has connected to an AP -+ * b) IBSS-ALONE has been created -+ * c) IBSS-MERGE has occurred -+ * -+ * 06 28 2010 george.huang -+ * [WPD00001556]Basic power managemenet function -+ * Create beacon update path, with expose bssUpdateBeaconContent() -+ * -+ * 06 22 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) add command warpper for STA-REC/BSS-INFO sync. -+ * 2) enhance command packet sending procedure for non-oid part -+ * 3) add command packet definitions for STA-REC/BSS-INFO sync. -+ * -+ * 06 21 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add BSS/STA_REC commands for integration. -+ * -+ * 06 21 2010 yarco.yang -+ * [WPD00003837][MT6620]Data Path Refine -+ * Add TX Done Event handle entry -+ * -+ * 06 10 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) eliminate CFG_CMD_EVENT_VERSION_0_9 -+ * 2) when disconnected, indicate nic directly (no event is needed) -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 05 20 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) integrate OID_GEN_NETWORK_LAYER_ADDRESSES with CMD_ID_SET_IP_ADDRESS -+ * 2) buffer statistics data for 2 seconds -+ * 3) use default value for adhoc parameters instead of 0 -+ * -+ * 05 19 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) do not take timeout mechanism for power mode oids -+ * 2) retrieve network type from connection status -+ * 3) after disassciation, set radio state to off -+ * 4) TCP option over IPv6 is supported -+ * -+ * 05 17 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * correct OID_802_11_DISASSOCIATE handling. -+ * -+ * 05 17 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * 1) add timeout handler mechanism for pending command packets -+ * 2) add p2p add/removal key -+ * -+ * 04 13 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * add framework for BT-over-Wi-Fi support. -+ * * * * * * * * * * 1) prPendingCmdInfo is replaced by queue for multiple handler capability -+ * * * * * * * * * * 2) command sequence number is now increased atomically -+ * * * * * * * * * * 3) private data could be hold and taken use for other purpose -+ * -+ * 04 06 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * sync statistics data structure definition with firmware implementation -+ * -+ * 03 30 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * statistics information OIDs are now handled by querying from firmware domain -+ * -+ * 03 26 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * indicate media stream mode after set is done -+ * -+ * 03 26 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * add a temporary flag for integration with CMD/EVENT v0.9. -+ * -+ * 03 25 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) correct OID_802_11_CONFIGURATION with frequency setting behavior. -+ * * the frequency is used for adhoc connection only -+ * * 2) update with SD1 v0.9 CMD/EVENT documentation -+ * -+ * 03 24 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * initial import for Linux port -+ * -+ * 03 22 2010 cp.wu -+ * [WPD00003824][MT6620 Wi-Fi][New Feature] Add support of large scan list -+ * Implement feature needed by CR: WPD00003824: refining association command by pasting scanning result -+ * -+ * 03 19 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) add ACPI D0/D3 state switching support -+ * * * * * * 2) use more formal way to handle interrupt when the status is retrieved from enhanced RX response -+ * -+ * 03 15 2010 kevin.huang -+ * [WPD00003820][MT6620 Wi-Fi] Modify the code for meet the WHQL test -+ * Add event for activate STA_RECORD_T -+ * -+ * 03 03 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * implement custom OID: EEPROM read/write access -+ * -+ * 03 03 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * implement OID_802_3_MULTICAST_LIST oid handling -+ * -+ * 02 26 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * move EVENT_ID_ASSOC_INFO from nic_rx.c to gl_kal_ndis_51.c -+ * 'cause it involves OS dependent data structure handling -+ * -+ * 02 25 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * send CMD_ID_INFRASTRUCTURE when handling OID_802_11_INFRASTRUCTURE_MODE set. -+ * -+ * 02 09 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1. Permanent and current MAC address are now retrieved by CMD/EVENT packets instead of hard-coded address -+ * * * * * 2. follow MSDN defined behavior when associates to another AP -+ * * * * * 3. for firmware download, packet size could be up to 2048 bytes -+ * -+ * 01 27 2010 wh.su -+ * [WPD00003816][MT6620 Wi-Fi] Adding the security support -+ * . -+ * -+ * 01 27 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1. eliminate improper variable in rHifInfo -+ * * * * * * 2. block TX/ordinary OID when RF test mode is engaged -+ * * * * * * 3. wait until firmware finish operation when entering into and leaving from RF test mode -+ * * * * * * 4. correct some HAL implementation -+ * -+ * 01 22 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * implement following 802.11 OIDs: -+ * * * OID_802_11_RSSI, -+ * * * OID_802_11_RSSI_TRIGGER, -+ * * * OID_802_11_STATISTICS, -+ * * * OID_802_11_DISASSOCIATE, -+ * * * OID_802_11_POWER_MODE -+ * -+ * 01 21 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * implement OID_802_11_MEDIA_STREAM_MODE -+ * -+ * 01 21 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * implement OID_802_11_SUPPORTED_RATES / OID_802_11_DESIRED_RATES -+ * -+ * 12 30 2009 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) According to CMD/EVENT documentation v0.8, -+ * * * * * * OID_CUSTOM_TEST_RX_STATUS & OID_CUSTOM_TEST_TX_STATUS is no longer used, -+ * * * * * * and result is retrieved by get ATInfo instead -+ * * * * * * 2) add 4 counter for recording aggregation statistics -+** \main\maintrunk.MT6620WiFiDriver_Prj\20 2009-12-11 18:35:07 GMT mtk02752 -+** add CMD added in CMD/EVEN document v0.8 -+** \main\maintrunk.MT6620WiFiDriver_Prj\19 2009-12-10 16:39:37 GMT mtk02752 -+** eliminate unused definitions -+** \main\maintrunk.MT6620WiFiDriver_Prj\18 2009-12-10 09:55:11 GMT mtk02752 -+** command ID/event ID revised -+** \main\maintrunk.MT6620WiFiDriver_Prj\17 2009-12-09 13:57:37 GMT MTK02468 -+** Added event ids (EVENT_ID_RX_ADDBA and EVENT_ID_RX_DELBA) -+** \main\maintrunk.MT6620WiFiDriver_Prj\16 2009-12-08 17:35:39 GMT mtk02752 -+** + add event ID for EVENT_ID_TEST_STATUS (rf test) -+** \main\maintrunk.MT6620WiFiDriver_Prj\15 2009-12-07 23:01:09 GMT mtk02752 -+** add data structure for RF_TEST -+** \main\maintrunk.MT6620WiFiDriver_Prj\14 2009-12-03 16:22:56 GMT mtk01461 -+** Modify the element - i4RSSI in EVENT of SCAN RESULT -+** \main\maintrunk.MT6620WiFiDriver_Prj\13 2009-11-30 10:54:44 GMT mtk02752 -+** 1st DW of WIFI_CMD_T is shared with HIF_TX_HEADER_T, while 1st DW of WIFI_EVENT_T is shared with HIF_RX_HEADER_T -+** \main\maintrunk.MT6620WiFiDriver_Prj\12 2009-11-26 10:16:58 GMT mtk02752 -+** resync EVENT_CONNECTION_STATUS -+** \main\maintrunk.MT6620WiFiDriver_Prj\11 2009-11-25 21:34:01 GMT mtk02752 -+** sync. EVENT_SCAN_RESULT_T with firmware -+** \main\maintrunk.MT6620WiFiDriver_Prj\10 2009-11-25 21:03:48 GMT mtk02752 -+** refine MGMT_FRAME -+** \main\maintrunk.MT6620WiFiDriver_Prj\9 2009-11-25 18:17:47 GMT mtk02752 -+** refine GL_WLAN_INFO_T for buffering scan result and presume max. ie length = 600 bytes -+** \main\maintrunk.MT6620WiFiDriver_Prj\8 2009-11-24 22:41:20 GMT mtk02752 -+** add EVENT_SCAN_RESULT_T definition -+** \main\maintrunk.MT6620WiFiDriver_Prj\7 2009-11-23 20:29:16 GMT mtk02752 -+** fix typo -+** \main\maintrunk.MT6620WiFiDriver_Prj\6 2009-11-23 14:46:01 GMT mtk02752 -+** add new command/event structure upon CM@SD1's documentation -+** \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-11-13 15:13:40 GMT mtk02752 -+** add command definition for CMD_BUILD_CONNECTION and EVENT_CONNECTION_STATUS -+** \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-05-20 12:22:22 GMT mtk01461 -+** Add SeqNum field to Event Header -+** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-04-29 15:42:11 GMT mtk01461 -+** Update structure of HIF_EVENT_HEADER_T and EVENT_HDR_SIZE -+** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-04-21 12:10:36 GMT mtk01461 -+** Add Common Set CMD Callback for MCR Write and other Set OID -+** \main\maintrunk.MT6620WiFiDriver_Prj\1 2009-04-21 01:40:17 GMT mtk01461 -+** Command Done Handler -+*/ -+#ifndef _NIC_CMD_EVENT_H -+#define _NIC_CMD_EVENT_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+#define CMD_STATUS_SUCCESS 0 -+#define CMD_STATUS_REJECTED 1 -+#define CMD_STATUS_UNKNOWN 2 -+ -+#define EVENT_HDR_SIZE OFFSET_OF(WIFI_EVENT_T, aucBuffer[0]) -+ -+#define MAX_IE_LENGTH (600) -+#define MAX_WSC_IE_LENGTH (400) -+ -+/* Action field in structure CMD_CH_PRIVILEGE_T */ -+#define CMD_CH_ACTION_REQ 0 -+#define CMD_CH_ACTION_ABORT 1 -+ -+/* Status field in structure EVENT_CH_PRIVILEGE_T */ -+#define EVENT_CH_STATUS_GRANT 0 -+ -+#define SCN_PSCAN_SWC_RSSI_WIN_MAX 75 -+#define SCN_PSCAN_SWC_MAX_NUM 8 -+#define SCN_PSCAN_HOTLIST_REPORT_MAX_NUM 8 -+ -+typedef enum _ENUM_CMD_ID_T { -+ CMD_ID_TEST_MODE = 1, /* 0x01 (Set) */ -+ CMD_ID_RESET_REQUEST, /* 0x02 (Set) */ -+ CMD_ID_BUILD_CONNECTION, /* 0x03 (Set) */ -+ CMD_ID_SCAN_REQ_V2, /* 0x04 (Set) */ -+ CMD_ID_NIC_POWER_CTRL, /* 0x05 (Set) */ -+ CMD_ID_POWER_SAVE_MODE, /* 0x06 (Set) */ -+ CMD_ID_LINK_ATTRIB, /* 0x07 (Set) */ -+ CMD_ID_ADD_REMOVE_KEY, /* 0x08 (Set) */ -+ CMD_ID_DEFAULT_KEY_ID, /* 0x09 (Set) */ -+ CMD_ID_INFRASTRUCTURE, /* 0x0a (Set) */ -+ CMD_ID_SET_RX_FILTER, /* 0x0b (Set) */ -+ CMD_ID_DOWNLOAD_BUF, /* 0x0c (Set) */ -+ CMD_ID_WIFI_START, /* 0x0d (Set) */ -+ CMD_ID_CMD_BT_OVER_WIFI, /* 0x0e (Set) */ -+ CMD_ID_SET_MEDIA_CHANGE_DELAY_TIME, /* 0x0f (Set) */ -+ CMD_ID_SEND_ADDBA_RSP, /* 0x10 (Set) */ -+ CMD_ID_WAPI_MODE, /* 0x11 (Set) (obsolete) */ -+ CMD_ID_WAPI_ASSOC_INFO, /* 0x12 (Set) (obsolete) */ -+ CMD_ID_SET_DOMAIN_INFO, /* 0x13 (Set) */ -+ CMD_ID_SET_IP_ADDRESS, /* 0x14 (Set) */ -+ CMD_ID_BSS_ACTIVATE_CTRL, /* 0x15 (Set) */ -+ CMD_ID_SET_BSS_INFO, /* 0x16 (Set) */ -+ CMD_ID_UPDATE_STA_RECORD, /* 0x17 (Set) */ -+ CMD_ID_REMOVE_STA_RECORD, /* 0x18 (Set) */ -+ CMD_ID_INDICATE_PM_BSS_CREATED, /* 0x19 (Set) */ -+ CMD_ID_INDICATE_PM_BSS_CONNECTED, /* 0x1a (Set) */ -+ CMD_ID_INDICATE_PM_BSS_ABORT, /* 0x1b (Set) */ -+ CMD_ID_UPDATE_BEACON_CONTENT, /* 0x1c (Set) */ -+ CMD_ID_SET_BSS_RLM_PARAM, /* 0x1d (Set) */ -+ CMD_ID_SCAN_REQ, /* 0x1e (Set) */ -+ CMD_ID_SCAN_CANCEL, /* 0x1f (Set) */ -+ CMD_ID_CH_PRIVILEGE, /* 0x20 (Set) */ -+ CMD_ID_UPDATE_WMM_PARMS, /* 0x21 (Set) */ -+ CMD_ID_SET_WMM_PS_TEST_PARMS, /* 0x22 (Set) */ -+ CMD_ID_TX_AMPDU, /* 0x23 (Set) */ -+ CMD_ID_ADDBA_REJECT, /* 0x24 (Set) */ -+ CMD_ID_SET_PS_PROFILE_ADV, /* 0x25 (Set) */ -+ CMD_ID_SET_RAW_PATTERN, /* 0x26 (Set) */ -+ CMD_ID_CONFIG_PATTERN_FUNC, /* 0x27 (Set) */ -+ CMD_ID_SET_TX_PWR, /* 0x28 (Set) */ -+ CMD_ID_SET_5G_PWR_OFFSET, /* 0x29 (Set) */ -+ CMD_ID_SET_PWR_PARAM, /* 0x2A (Set) */ -+ CMD_ID_P2P_ABORT, /* 0x2B (Set) */ -+#if CFG_STRESS_TEST_SUPPORT -+ CMD_ID_RANDOM_RX_RESET_EN = 0x2C, /* 0x2C (Set ) */ -+ CMD_ID_RANDOM_RX_RESET_DE = 0x2D, /* 0x2D (Set ) */ -+ CMD_ID_SAPP_EN = 0x2E, /* 0x2E (Set ) */ -+ CMD_ID_SAPP_DE = 0x2F, /* 0x2F (Set ) */ -+#endif -+ CMD_ID_ROAMING_TRANSIT = 0x30, /* 0x30 (Set) */ -+ CMD_ID_SET_PHY_PARAM, /* 0x31 (Set) */ -+ CMD_ID_SET_NOA_PARAM, /* 0x32 (Set) */ -+ CMD_ID_SET_OPPPS_PARAM, /* 0x33 (Set) */ -+ CMD_ID_SET_UAPSD_PARAM, /* 0x34 (Set) */ -+ CMD_ID_SET_SIGMA_STA_SLEEP, /* 0x35 (Set) */ -+ CMD_ID_SET_EDGE_TXPWR_LIMIT, /* 0x36 (Set) */ -+ CMD_ID_SET_DEVICE_MODE, /* 0x37 (Set) */ -+ CMD_ID_SET_TXPWR_CTRL, /* 0x38 (Set) */ -+ CMD_ID_SET_AUTOPWR_CTRL, /* 0x39 (Set) */ -+ CMD_ID_SET_WFD_CTRL, /* 0x3A (Set) */ -+ CMD_ID_SET_5G_EDGE_TXPWR_LIMIT, /* 0x3B (Set) */ -+ CMD_ID_SET_RSSI_COMPENSATE, /* 0x3C (Set) */ -+ CMD_ID_SET_BAND_SUPPORT = 0x3D, /* 0x3D (Set) */ -+ CMD_ID_SET_NLO_REQ, /* 0x3E (Set) */ -+ CMD_ID_SET_NLO_CANCEL, /* 0x3F (Set) */ -+ CMD_ID_SET_BATCH_REQ, /* 0x40 (Set) */ -+ CMD_ID_SET_WOWLAN, /* 0x41 (Set) */ /*CFG_SUPPORT_WOWLAN */ -+ CMD_ID_GET_PSCAN_CAPABILITY = 0x42, /* 0x42 (Set) */ -+ CMD_ID_SET_PSCN_ENABLE = 0x43, /* 0x43 (Set) */ -+ CMD_ID_SET_PSCAN_PARAM = 0x44, /* 0x44 (Set) */ -+ CMD_ID_SET_PSCN_ADD_HOTLIST_BSSID = 0x45, /* 0x45 (Set) */ -+ CMD_ID_SET_PSCN_ADD_SW_BSSID = 0x46, /* 0x46 (Set) */ -+ CMD_ID_SET_PSCN_MAC_ADDR = 0x47, /* 0x47 (Set) */ -+ CMD_ID_GET_GSCN_SCN_RESULT = 0x48, /* 0x48 (Get) */ -+ CMD_ID_SET_COUNTRY_POWER_LIMIT = 0x4A, /* 0x4A (Set) */ -+ CMD_ID_SET_SYSTEM_SUSPEND = 0x60, /* 0x60 (Set) */ -+ CMD_ID_GET_NIC_CAPABILITY = 0x80, /* 0x80 (Query) */ -+ CMD_ID_GET_LINK_QUALITY, /* 0x81 (Query) */ -+ CMD_ID_GET_STATISTICS, /* 0x82 (Query) */ -+ CMD_ID_GET_CONNECTION_STATUS, /* 0x83 (Query) */ -+ CMD_ID_GET_ASSOC_INFO, /* 0x84 (Query) (obsolete) */ -+ CMD_ID_GET_STA_STATISTICS = 0x85, /* 0x85 (Query) */ -+ CMD_ID_GET_DEBUG_CODE = 0x86, /* 0x86 (Query) */ -+ CMD_ID_GET_LTE_CHN = 0x87, /* 0x87 (Query) */ -+ CMD_ID_GET_CHN_LOADING = 0x88, /* 0x88 (Query) */ -+ CMD_ID_GET_STATISTICS_PL = 0x89, /* 0x87 (Query) */ -+ CMD_ID_BASIC_CONFIG = 0xc1, /* 0xc1 (Set / Query) */ -+ CMD_ID_ACCESS_REG, /* 0xc2 (Set / Query) */ -+ CMD_ID_MAC_MCAST_ADDR, /* 0xc3 (Set / Query) */ -+ CMD_ID_802_11_PMKID, /* 0xc4 (Set / Query) */ -+ CMD_ID_ACCESS_EEPROM, /* 0xc5 (Set / Query) */ -+ CMD_ID_SW_DBG_CTRL, /* 0xc6 (Set / Query) */ -+#if 1 /* CFG_SUPPORT_ANTI_PIRACY */ -+ CMD_ID_SEC_CHECK, /* 0xc7 (Set / Query) */ -+#endif -+ CMD_ID_DUMP_MEM, /* 0xc8 (Query) */ -+ -+ CMD_ID_CHIP_CONFIG = 0xCA, /* 0xca (Set / Query) */ -+ -+#if CFG_SUPPORT_RDD_TEST_MODE -+ CMD_ID_SET_RDD_CH = 0xE1, -+#endif -+ -+ CMD_ID_SET_BWCS = 0xF1, -+ CMD_ID_SET_ROAMING_INFO = 0xF3, -+ -+#if CFG_SUPPORT_BUILD_DATE_CODE -+ CMD_ID_GET_BUILD_DATE_CODE = 0xF8, -+#endif -+ CMD_ID_GET_BSS_INFO = 0xF9, -+#if 1 /* CFG_SUPPORT_HOTSPOT_OPTIMIZATION */ -+ CMD_ID_SET_HOTSPOT_OPTIMIZATION = 0xFA, /* 0xFA (Set) */ -+#endif -+ -+ CMD_ID_TDLS_CORE = 0xFC, -+ CMD_ID_STATS = 0xFD, -+ CMD_ID_TX_AR_ERR_CONFIG = 0xFF -+} ENUM_CMD_ID_T, *P_ENUM_CMD_ID_T; -+ -+typedef enum _ENUM_EVENT_ID_T { -+ EVENT_ID_CMD_RESULT = 1, /* 0x01 (Query) */ -+ EVENT_ID_NIC_CAPABILITY, /* 0x02 (Query) */ -+ EVENT_ID_CONNECTION_STATUS, /* 0x03 (Query / Unsolicited) (obsolete) */ -+ EVENT_ID_SCAN_RESULT, /* 0x04 (Query / Unsolicited) (obselete) */ -+ EVENT_ID_LINK_QUALITY, /* 0x05 (Query / Unsolicited) */ -+ EVENT_ID_STATISTICS, /* 0x06 (Query) */ -+ EVENT_ID_MIC_ERR_INFO, /* 0x07 (Unsolicited) */ -+ EVENT_ID_ASSOC_INFO, /* 0x08 (Query - CMD_ID_GET_ASSOC_INFO) */ -+ EVENT_ID_BASIC_CONFIG, /* 0x09 (Query - CMD_ID_BASIC_CONFIG) */ -+ EVENT_ID_ACCESS_REG, /* 0x0a (Query - CMD_ID_ACCESS_REG) */ -+ EVENT_ID_MAC_MCAST_ADDR, /* 0x0b (Query - CMD_ID_MAC_MCAST_ADDR) */ -+ EVENT_ID_802_11_PMKID, /* 0x0c (Query - CMD_ID_802_11_PMKID) */ -+ EVENT_ID_ACCESS_EEPROM, /* 0x0d (Query - CMD_ID_ACCESS_EEPROM) */ -+ EVENT_ID_SLEEPY_NOTIFY, /* 0x0e (Query) */ -+ EVENT_ID_BT_OVER_WIFI, /* 0x0f (Unsolicited) */ -+ EVENT_ID_TEST_STATUS, /* 0x10 (Query - CMD_ID_TEST_MODE) */ -+ EVENT_ID_RX_ADDBA, /* 0x11 (Unsolicited) (obsolete) */ -+ EVENT_ID_RX_DELBA, /* 0x12 (Unsolicited) (obsolete) */ -+ EVENT_ID_ACTIVATE_STA_REC_T, /* 0x13 (Unsolicited) */ -+ EVENT_ID_DEACTIVATE_STA_REC_T, /* 0x14 (Unsolicited) */ -+ EVENT_ID_SCAN_DONE, /* 0x15 (Unsoiicited) */ -+ EVENT_ID_RX_FLUSH, /* 0x16 (Unsolicited) */ -+ EVENT_ID_TX_DONE, /* 0x17 (Unsolicited) */ -+ EVENT_ID_CH_PRIVILEGE, /* 0x18 (Unsolicited) */ -+ EVENT_ID_BSS_ABSENCE_PRESENCE = 0x19, /* 0x19 (Unsolicited) */ -+ EVENT_ID_STA_CHANGE_PS_MODE, /* 0x1A (Unsolicited) */ -+ EVENT_ID_BSS_BEACON_TIMEOUT, /* 0x1B (Unsolicited) */ -+ EVENT_ID_UPDATE_NOA_PARAMS, /* 0x1C (Unsolicited) */ -+ EVENT_ID_AP_OBSS_STATUS, /* 0x1D (Unsolicited) */ -+ EVENT_ID_STA_UPDATE_FREE_QUOTA, /* 0x1E (Unsolicited) */ -+ EVENT_ID_SW_DBG_CTRL, /* 0x1F (Query - CMD_ID_SW_DBG_CTRL) */ -+ EVENT_ID_ROAMING_STATUS, /* 0x20 (Unsolicited) */ -+ EVENT_ID_STA_AGING_TIMEOUT, /* 0x21 (Unsolicited) */ -+#if 1 /* CFG_SUPPORT_ANTI_PIRACY */ -+ EVENT_ID_SEC_CHECK_RSP, /* 0x22 (Unsolicited) */ -+#endif -+ EVENT_ID_SEND_DEAUTH, /* 0x23 (Unsolicited) */ -+ -+#if CFG_SUPPORT_RDD_TEST_MODE -+ EVENT_ID_UPDATE_RDD_STATUS, /* 0x24 (Unsolicited) */ -+#endif -+ -+#if CFG_SUPPORT_BCM && CFG_SUPPORT_BCM_BWCS -+ EVENT_ID_UPDATE_BWCS_STATUS = 0x25, /* 0x25 (Unsolicited) */ -+ EVENT_ID_UPDATE_BCM_DEBUG, /* 0x26 (Unsolicited) */ -+#endif -+ EVENT_ID_RX_ERR, -+ EVENT_ID_DUMP_MEM, -+ EVENT_ID_STA_STATISTICS = 0x29, /* 0x29 (Query ) */ -+ EVENT_ID_STA_STATISTICS_UPDATE, /* 0x2A (Unsolicited) */ -+ EVENT_ID_NLO_DONE = 0x2b, -+ -+ EVENT_ID_GSCAN_CAPABILITY = 0x30, -+ EVENT_ID_GSCAN_SCAN_COMPLETE = 0x31, -+ EVENT_ID_GSCAN_FULL_RESULT = 0x32, -+ EVENT_ID_GSCAN_SIGNIFICANT_CHANGE = 0x33, -+ EVENT_ID_GSCAN_GEOFENCE_FOUND = 0x34, -+ EVENT_ID_GSCAN_SCAN_AVAILABLE = 0x35, -+ EVENT_ID_GSCAN_RESULT = 0x36, -+ EVENT_ID_BATCH_RESULT = 0x37, -+ -+ EVENT_ID_TDLS = 0x80, -+ EVENT_ID_STATS_ENV = 0x81, -+ -+#if CFG_SUPPORT_BUILD_DATE_CODE -+ EVENT_ID_BUILD_DATE_CODE = 0xF8, -+#endif -+ EVENT_ID_GET_AIS_BSS_INFO = 0xF9, -+ EVENT_ID_DEBUG_CODE = 0xFB, -+ EVENT_ID_RFTEST_READY = 0xFC, /* 0xFC */ -+ EVENT_ID_TX_DONE_STATUS = 0xFD, -+ EVENT_ID_FW_LOG_ENV = 0xFE, /* 0xFE, FW real time debug log */ -+} ENUM_EVENT_ID_T, *P_ENUM_EVENT_ID_T; -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+#ifndef LINUX -+typedef UINT_8 CMD_STATUS; -+#endif -+ -+typedef struct _EVENT_TX_DONE_STATUS_T { -+ UINT_8 ucPacketSeq; -+ UINT_8 ucStatus; -+ UINT_16 u2SequenceNumber; -+ UINT_32 au4Reserved1; -+ UINT_32 au4Reserved2; -+ UINT_32 au4Reserved3; -+ UINT_32 u4PktBufInfo; -+ UINT_8 aucPktBuf[200]; -+} EVENT_TX_DONE_STATUS_T, *P_EVENT_TX_DONE_STATUS_T; -+ -+/* for Event Packet (via HIF-RX) */ -+ /* following CM's documentation v0.7 */ -+typedef struct _WIFI_CMD_T { -+ UINT_16 u2TxByteCount_UserPriority; -+ UINT_8 ucEtherTypeOffset; -+ UINT_8 ucResource_PktType_CSflags; -+ UINT_8 ucCID; -+ UINT_8 ucSetQuery; -+ UINT_8 ucSeqNum; -+ UINT_8 aucReserved2; -+ -+ UINT_8 aucBuffer[0]; -+} WIFI_CMD_T, *P_WIFI_CMD_T; -+ -+/* for Command Packet (via HIF-TX) */ -+ /* following CM's documentation v0.7 */ -+typedef struct _WIFI_EVENT_T { -+ UINT_16 u2PacketLen; -+ UINT_16 u2PacketType; -+ UINT_8 ucEID; -+ UINT_8 ucSeqNum; -+ UINT_8 aucReserved2[2]; -+ -+ UINT_8 aucBuffer[0]; -+} WIFI_EVENT_T, *P_WIFI_EVENT_T; -+ -+/* CMD_ID_TEST_MODE */ -+typedef struct _CMD_TEST_CTRL_T { -+ UINT_8 ucAction; -+ UINT_8 aucReserved[3]; -+ union { -+ UINT_32 u4OpMode; -+ UINT_32 u4ChannelFreq; -+ PARAM_MTK_WIFI_TEST_STRUCT_T rRfATInfo; -+ } u; -+} CMD_TEST_CTRL_T, *P_CMD_TEST_CTRL_T; -+ -+/* EVENT_TEST_STATUS */ -+typedef struct _PARAM_CUSTOM_RFTEST_TX_STATUS_STRUCT_T { -+ UINT_32 u4PktSentStatus; -+ UINT_32 u4PktSentCount; -+ UINT_16 u2AvgAlc; -+ UINT_8 ucCckGainControl; -+ UINT_8 ucOfdmGainControl; -+} PARAM_CUSTOM_RFTEST_TX_STATUS_STRUCT_T, *P_PARAM_CUSTOM_RFTEST_TX_STATUS_STRUCT_T; -+ -+typedef struct _PARAM_CUSTOM_RFTEST_RX_STATUS_STRUCT_T { -+ UINT_32 u4IntRxOk; /*!< number of packets that Rx ok from interrupt */ -+ UINT_32 u4IntCrcErr; /*!< number of packets that CRC error from interrupt */ -+ UINT_32 u4IntShort; /*!< number of packets that is short preamble from interrupt */ -+ UINT_32 u4IntLong; /*!< number of packets that is long preamble from interrupt */ -+ UINT_32 u4PauRxPktCount; /*!< number of packets that Rx ok from PAU */ -+ UINT_32 u4PauCrcErrCount; /*!< number of packets that CRC error from PAU */ -+ UINT_32 u4PauRxFifoFullCount; /*!< number of packets that is short preamble from PAU */ -+ UINT_32 u4PauCCACount; /*!< CCA rising edge count */ -+} PARAM_CUSTOM_RFTEST_RX_STATUS_STRUCT_T, *P_PARAM_CUSTOM_RFTEST_RX_STATUS_STRUCT_T; -+ -+typedef union _EVENT_TEST_STATUS { -+ PARAM_MTK_WIFI_TEST_STRUCT_T rATInfo; -+/* PARAM_CUSTOM_RFTEST_TX_STATUS_STRUCT_T rTxStatus; */ -+/* PARAM_CUSTOM_RFTEST_RX_STATUS_STRUCT_T rRxStatus; */ -+} EVENT_TEST_STATUS, *P_EVENT_TEST_STATUS; -+ -+/* CMD_BUILD_CONNECTION */ -+typedef struct _CMD_BUILD_CONNECTION { -+ UINT_8 ucInfraMode; -+ UINT_8 ucAuthMode; -+ UINT_8 ucEncryptStatus; -+ UINT_8 ucSsidLen; -+ UINT_8 aucSsid[PARAM_MAX_LEN_SSID]; -+ UINT_8 aucBssid[PARAM_MAC_ADDR_LEN]; -+ -+ /* Ad-hoc mode */ -+ UINT_16 u2BeaconPeriod; -+ UINT_16 u2ATIMWindow; -+ UINT_8 ucJoinOnly; -+ UINT_8 ucReserved; -+ UINT_32 u4FreqInKHz; -+ -+ /* for faster connection */ -+ UINT_8 aucScanResult[0]; -+} CMD_BUILD_CONNECTION, *P_CMD_BUILD_CONNECTION; -+ -+/* CMD_ADD_REMOVE_KEY */ -+typedef struct _CMD_802_11_KEY { -+ UINT_8 ucAddRemove; -+ UINT_8 ucTxKey; -+ UINT_8 ucKeyType; -+ UINT_8 ucIsAuthenticator; -+ UINT_8 aucPeerAddr[6]; -+ UINT_8 ucNetType; -+ UINT_8 ucAlgorithmId; -+ UINT_8 ucKeyId; -+ UINT_8 ucKeyLen; -+ UINT_8 aucReverved[2]; -+ UINT_8 aucKeyMaterial[32]; -+ UINT_8 aucKeyRsc[16]; -+} CMD_802_11_KEY, *P_CMD_802_11_KEY; -+ -+/* WPA2 PMKID cache structure */ -+typedef struct _PMKID_ENTRY_T { -+ PARAM_BSSID_INFO_T rBssidInfo; -+ BOOLEAN fgPmkidExist; -+} PMKID_ENTRY_T, *P_PMKID_ENTRY_T; -+ -+typedef struct _CMD_802_11_PMKID { -+ ULONG u4BSSIDInfoCount; -+ P_PMKID_ENTRY_T arPMKIDInfo[1]; -+} CMD_802_11_PMKID, *P_CMD_802_11_PMKID; -+ -+/* CMD_BASIC_CONFIG */ -+typedef struct _CMD_CSUM_OFFLOAD { -+ UINT_16 u2RxChecksum; /* bit0: IP, bit1: UDP, bit2: TCP */ -+ UINT_16 u2TxChecksum; /* bit0: IP, bit1: UDP, bit2: TCP */ -+} CMD_CSUM_OFFLOAD, *P_CMD_CSUM_OFFLOAD; -+ -+typedef struct _CMD_BASIC_CONFIG { -+ PARAM_MAC_ADDRESS rMyMacAddr; -+ UINT_8 ucNative80211; -+ UINT_8 aucReserved[1]; -+ -+ CMD_CSUM_OFFLOAD rCsumOffload; -+} CMD_BASIC_CONFIG, *P_CMD_BASIC_CONFIG, EVENT_BASIC_CONFIG, *P_EVENT_BASIC_CONFIG; -+ -+/* CMD_MAC_MCAST_ADDR */ -+typedef struct _CMD_MAC_MCAST_ADDR { -+ UINT_32 u4NumOfGroupAddr; -+ UINT_8 ucNetTypeIndex; -+ UINT_8 aucReserved[3]; -+ PARAM_MAC_ADDRESS arAddress[MAX_NUM_GROUP_ADDR]; -+} CMD_MAC_MCAST_ADDR, *P_CMD_MAC_MCAST_ADDR, EVENT_MAC_MCAST_ADDR, *P_EVENT_MAC_MCAST_ADDR; -+ -+/* CMD_ACCESS_EEPROM */ -+typedef struct _CMD_ACCESS_EEPROM { -+ UINT_16 u2Offset; -+ UINT_16 u2Data; -+} CMD_ACCESS_EEPROM, *P_CMD_ACCESS_EEPROM, EVENT_ACCESS_EEPROM, *P_EVENT_ACCESS_EEPROM; -+ -+typedef struct _CMD_CUSTOM_NOA_PARAM_STRUCT_T { -+ UINT_32 u4NoaDurationMs; -+ UINT_32 u4NoaIntervalMs; -+ UINT_32 u4NoaCount; -+} CMD_CUSTOM_NOA_PARAM_STRUCT_T, *P_CMD_CUSTOM_NOA_PARAM_STRUCT_T; -+ -+typedef struct _CMD_CUSTOM_OPPPS_PARAM_STRUCT_T { -+ UINT_32 u4CTwindowMs; -+} CMD_CUSTOM_OPPPS_PARAM_STRUCT_T, *P_CMD_CUSTOM_OPPPS_PARAM_STRUCT_T; -+ -+typedef struct _CMD_CUSTOM_UAPSD_PARAM_STRUCT_T { -+ UINT_8 fgEnAPSD; -+ UINT_8 fgEnAPSD_AcBe; -+ UINT_8 fgEnAPSD_AcBk; -+ UINT_8 fgEnAPSD_AcVo; -+ UINT_8 fgEnAPSD_AcVi; -+ UINT_8 ucMaxSpLen; -+ UINT_8 aucResv[2]; -+} CMD_CUSTOM_UAPSD_PARAM_STRUCT_T, *P_CMD_CUSTOM_UAPSD_PARAM_STRUCT_T; -+ -+/* EVENT_CONNECTION_STATUS */ -+typedef struct _EVENT_CONNECTION_STATUS { -+ UINT_8 ucMediaStatus; -+ UINT_8 ucReasonOfDisconnect; -+ -+ UINT_8 ucInfraMode; -+ UINT_8 ucSsidLen; -+ UINT_8 aucSsid[PARAM_MAX_LEN_SSID]; -+ UINT_8 aucBssid[PARAM_MAC_ADDR_LEN]; -+ UINT_8 ucAuthenMode; -+ UINT_8 ucEncryptStatus; -+ UINT_16 u2BeaconPeriod; -+ UINT_16 u2AID; -+ UINT_16 u2ATIMWindow; -+ UINT_8 ucNetworkType; -+ UINT_8 aucReserved[1]; -+ UINT_32 u4FreqInKHz; -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ UINT_8 aucInterfaceAddr[PARAM_MAC_ADDR_LEN]; -+#endif -+ -+} EVENT_CONNECTION_STATUS, *P_EVENT_CONNECTION_STATUS; -+ -+/* EVENT_NIC_CAPABILITY */ -+typedef struct _EVENT_NIC_CAPABILITY { -+ UINT_16 u2ProductID; -+ UINT_16 u2FwVersion; -+ UINT_16 u2DriverVersion; -+ UINT_8 ucHw5GBandDisabled; -+ UINT_8 ucEepromUsed; -+ UINT_8 ucEfuseValid; -+ UINT_8 ucMacAddrValid; -+#if CFG_REPORT_RFBB_VERSION -+ UINT_8 ucRfVersion; -+ UINT_8 ucPhyVersion; -+#endif -+#if CFG_ENABLE_CAL_LOG -+ UINT_8 ucRfCalFail; -+ UINT_8 ucBbCalFail; -+#endif -+ -+#define FEATURE_SET_OFFSET_TDLS 0 -+#define FEATURE_SET_OFFSET_5G_SUPPORT 1 -+ UINT_8 ucFeatureSet; /* bit0: TDLS */ -+ -+ UINT_8 aucReserved[1]; -+#if CFG_EMBED_FIRMWARE_BUILD_DATE_CODE -+ UINT_8 aucDateCode[16]; -+#endif -+} EVENT_NIC_CAPABILITY, *P_EVENT_NIC_CAPABILITY; -+ -+/* modified version of WLAN_BEACON_FRAME_BODY_T for simplier buffering */ -+typedef struct _WLAN_BEACON_FRAME_BODY_T_LOCAL { -+ /* Beacon frame body */ -+ UINT_32 au4Timestamp[2]; /* Timestamp */ -+ UINT_16 u2BeaconInterval; /* Beacon Interval */ -+ UINT_16 u2CapInfo; /* Capability */ -+ UINT_8 aucInfoElem[MAX_IE_LENGTH]; /* Various IEs, start from SSID */ -+ UINT_16 u2IELength; /* This field is *NOT* carried by F/W but caculated by nic_rx */ -+} WLAN_BEACON_FRAME_BODY_T_LOCAL, *P_WLAN_BEACON_FRAME_BODY_T_LOCAL; -+ -+/* EVENT_SCAN_RESULT */ -+typedef struct _EVENT_SCAN_RESULT_T { -+ INT_32 i4RSSI; -+ UINT_32 u4LinkQuality; -+ UINT_32 u4DSConfig; /* Center frequency */ -+ UINT_32 u4DomainInfo; /* Require CM opinion */ -+ UINT_32 u4Reserved; -+ UINT_8 ucNetworkType; -+ UINT_8 ucOpMode; -+ UINT_8 aucBssid[MAC_ADDR_LEN]; -+ UINT_8 aucRatesEx[PARAM_MAX_LEN_RATES_EX]; -+ WLAN_BEACON_FRAME_BODY_T_LOCAL rBeaconFrameBody; -+} EVENT_SCAN_RESULT_T, *P_EVENT_SCAN_RESULT_T; -+ -+/* event of tkip mic error */ -+typedef struct _EVENT_MIC_ERR_INFO { -+ UINT_32 u4Flags; -+} EVENT_MIC_ERR_INFO, *P_EVENT_MIC_ERR_INFO; -+ -+typedef struct _EVENT_PMKID_CANDIDATE_LIST_T { -+ UINT_32 u4Version; /*!< Version */ -+ UINT_32 u4NumCandidates; /*!< How many candidates follow */ -+ PARAM_PMKID_CANDIDATE_T arCandidateList[1]; -+} EVENT_PMKID_CANDIDATE_LIST_T, *P_EVENT_PMKID_CANDIDATE_LIST_T; -+ -+typedef struct _EVENT_CMD_RESULT { -+ UINT_8 ucCmdID; -+ UINT_8 ucStatus; -+ UINT_8 aucReserved[2]; -+} EVENT_CMD_RESULT, *P_EVENT_CMD_RESULT; -+ -+/* CMD_ID_ACCESS_REG & EVENT_ID_ACCESS_REG */ -+typedef struct _CMD_ACCESS_REG { -+ UINT_32 u4Address; -+ UINT_32 u4Data; -+} CMD_ACCESS_REG, *P_CMD_ACCESS_REG; -+ -+/* CMD_ID_ACCESS_REG & EVENT_ID_ACCESS_REG */ -+#if CFG_AUTO_CHANNEL_SEL_SUPPORT -+ -+typedef struct _CMD_ACCESS_CHN_LOAD { -+ UINT_32 u4Address; -+ UINT_32 u4Data; -+ UINT_16 u2Channel; -+ UINT_8 aucReserved[2]; -+} CMD_ACCESS_CHN_LOAD, *P_ACCESS_CHN_LOAD; -+ -+#endif -+/* CMD_DUMP_MEMORY */ -+typedef struct _CMD_DUMP_MEM { -+ UINT_32 u4Address; -+ UINT_32 u4Length; -+ UINT_32 u4RemainLength; -+ UINT_8 ucFragNum; -+} CMD_DUMP_MEM, *P_CMD_DUMP_MEM; -+ -+typedef struct _EVENT_DUMP_MEM_T { -+ UINT_32 u4Address; -+ UINT_32 u4Length; -+ UINT_32 u4RemainLength; -+ UINT_8 ucFragNum; -+ UINT_8 aucBuffer[1]; -+} EVENT_DUMP_MEM_T, *P_EVENT_DUMP_MEM_T; -+ -+typedef struct _CMD_SW_DBG_CTRL_T { -+ UINT_32 u4Id; -+ UINT_32 u4Data; -+ /* Debug Support */ -+ UINT_32 u4DebugCnt[64]; -+} CMD_SW_DBG_CTRL_T, *P_CMD_SW_DBG_CTRL_T; -+ -+/* CMD_ID_LINK_ATTRIB */ -+typedef struct _CMD_LINK_ATTRIB { -+ INT_8 cRssiTrigger; -+ UINT_8 ucDesiredRateLen; -+ UINT_16 u2DesiredRate[32]; -+ UINT_8 ucMediaStreamMode; -+ UINT_8 aucReserved[1]; -+} CMD_LINK_ATTRIB, *P_CMD_LINK_ATTRIB; -+ -+/* CMD_ID_NIC_POWER_CTRL */ -+typedef struct _CMD_NIC_POWER_CTRL { -+ UINT_8 ucPowerMode; -+ UINT_8 aucReserved[3]; -+} CMD_NIC_POWER_CTRL, *P_CMD_NIC_POWER_CTRL; -+ -+/* CMD_ID_POWER_SAVE_MODE */ -+typedef struct _CMD_PS_PROFILE_T { -+ UINT_8 ucNetTypeIndex; -+ UINT_8 ucPsProfile; -+ UINT_8 aucReserved[2]; -+} CMD_PS_PROFILE_T, *P_CMD_PS_PROFILE_T; -+ -+/* EVENT_LINK_QUALITY */ -+typedef struct _EVENT_LINK_QUALITY { -+ INT_8 cRssi; -+ INT_8 cLinkQuality; -+ UINT_16 u2LinkSpeed; -+ UINT_8 ucMediumBusyPercentage; -+} EVENT_LINK_QUALITY, *P_EVENT_LINK_QUALITY; -+ -+#if CFG_SUPPORT_P2P_RSSI_QUERY -+/* EVENT_LINK_QUALITY */ -+typedef struct _EVENT_LINK_QUALITY_EX { -+ INT_8 cRssi; -+ INT_8 cLinkQuality; -+ UINT_16 u2LinkSpeed; -+ UINT_8 ucMediumBusyPercentage; -+ UINT_8 ucIsLQ0Rdy; -+ INT_8 cRssiP2P; /* For P2P Network. */ -+ INT_8 cLinkQualityP2P; -+ UINT_16 u2LinkSpeedP2P; -+ UINT_8 ucMediumBusyPercentageP2P; -+ UINT_8 ucIsLQ1Rdy; -+} EVENT_LINK_QUALITY_EX, *P_EVENT_LINK_QUALITY_EX; -+#endif -+ -+/* EVENT_ID_STATISTICS */ -+typedef struct _EVENT_STATISTICS { -+ LARGE_INTEGER rTransmittedFragmentCount; -+ LARGE_INTEGER rMulticastTransmittedFrameCount; -+ LARGE_INTEGER rFailedCount; -+ LARGE_INTEGER rRetryCount; -+ LARGE_INTEGER rMultipleRetryCount; -+ LARGE_INTEGER rRTSSuccessCount; -+ LARGE_INTEGER rRTSFailureCount; -+ LARGE_INTEGER rACKFailureCount; -+ LARGE_INTEGER rFrameDuplicateCount; -+ LARGE_INTEGER rReceivedFragmentCount; -+ LARGE_INTEGER rMulticastReceivedFrameCount; -+ LARGE_INTEGER rFCSErrorCount; -+} EVENT_STATISTICS, *P_EVENT_STATISTICS; -+ -+/* EVENT_ID_FW_SLEEPY_NOTIFY */ -+typedef struct _EVENT_SLEEPY_NOTIFY { -+ UINT_8 ucSleepyState; -+ UINT_8 aucReserved[3]; -+} EVENT_SLEEPY_NOTIFY, *P_EVENT_SLEEPY_NOTIFY; -+ -+typedef struct _EVENT_ACTIVATE_STA_REC_T { -+ UINT_8 aucMacAddr[6]; -+ UINT_8 ucStaRecIdx; -+ UINT_8 ucNetworkTypeIndex; -+ BOOLEAN fgIsQoS; -+ BOOLEAN fgIsAP; -+ UINT_8 aucReserved[2]; -+} EVENT_ACTIVATE_STA_REC_T, *P_EVENT_ACTIVATE_STA_REC_T; -+ -+typedef struct _EVENT_DEACTIVATE_STA_REC_T { -+ UINT_8 ucStaRecIdx; -+ UINT_8 aucReserved[3]; -+} EVENT_DEACTIVATE_STA_REC_T, *P_EVENT_DEACTIVATE_STA_REC_T; -+ -+/* CMD_BT_OVER_WIFI */ -+typedef struct _CMD_BT_OVER_WIFI { -+ UINT_8 ucAction; /* 0: query, 1: setup, 2: destroy */ -+ UINT_8 ucChannelNum; -+ PARAM_MAC_ADDRESS rPeerAddr; -+ UINT_16 u2BeaconInterval; -+ UINT_8 ucTimeoutDiscovery; -+ UINT_8 ucTimeoutInactivity; -+ UINT_8 ucRole; -+ UINT_8 PAL_Capabilities; -+ UINT_8 cMaxTxPower; -+ UINT_8 ucChannelBand; -+ UINT_8 ucReserved[1]; -+} CMD_BT_OVER_WIFI, *P_CMD_BT_OVER_WIFI; -+ -+/* EVENT_BT_OVER_WIFI */ -+typedef struct _EVENT_BT_OVER_WIFI { -+ UINT_8 ucLinkStatus; -+ UINT_8 ucSelectedChannel; -+ INT_8 cRSSI; -+ UINT_8 ucReserved[1]; -+} EVENT_BT_OVER_WIFI, *P_EVENT_BT_OVER_WIFI; -+ -+/* Same with DOMAIN_SUBBAND_INFO */ -+typedef struct _CMD_SUBBAND_INFO { -+ UINT_8 ucRegClass; -+ UINT_8 ucBand; -+ UINT_8 ucChannelSpan; -+ UINT_8 ucFirstChannelNum; -+ UINT_8 ucNumChannels; -+ UINT_8 aucReserved[3]; -+} CMD_SUBBAND_INFO, *P_CMD_SUBBAND_INFO; -+ -+/* CMD_SET_DOMAIN_INFO */ -+typedef struct _CMD_SET_DOMAIN_INFO_T { -+ UINT_16 u2CountryCode; -+ UINT_16 u2IsSetPassiveScan; /* 0: set channel domain; 1: set passive scan channel domain */ -+ CMD_SUBBAND_INFO rSubBand[6]; -+ -+ UINT_8 uc2G4Bandwidth; /* CONFIG_BW_20_40M or CONFIG_BW_20M */ -+ UINT_8 uc5GBandwidth; /* CONFIG_BW_20_40M or CONFIG_BW_20M */ -+ UINT_8 aucReserved[2]; -+} CMD_SET_DOMAIN_INFO_T, *P_CMD_SET_DOMAIN_INFO_T; -+ -+#if CFG_SUPPORT_PWR_LIMIT_COUNTRY -+ -+/* CMD_SET_PWR_LIMIT_TABLE */ -+typedef struct _CMD_CHANNEL_POWER_LIMIT { -+ UINT_8 ucCentralCh; -+ INT_8 cPwrLimitCCK; -+ INT_8 cPwrLimit20; -+ INT_8 cPwrLimit40; -+ INT_8 cPwrLimit80; -+ INT_8 cPwrLimit160; -+ UINT_8 ucFlag; -+ UINT_8 aucReserved[1]; -+} CMD_CHANNEL_POWER_LIMIT, *P_CMD_CHANNEL_POWER_LIMIT; -+ -+typedef struct _CMD_SET_COUNTRY_CHANNEL_POWER_LIMIT_T { -+ UINT_16 u2CountryCode; -+ UINT_8 ucCountryFlag; -+ UINT_8 ucNum; -+ UINT_8 aucReserved[4]; -+ CMD_CHANNEL_POWER_LIMIT rChannelPowerLimit[1]; -+} CMD_SET_COUNTRY_CHANNEL_POWER_LIMIT_T, *P_CMD_SET_COUNTRY_CHANNEL_POWER_LIMIT_T; -+ -+#endif -+ -+/* CMD_SET_IP_ADDRESS */ -+typedef struct _IPV4_NETWORK_ADDRESS { -+ UINT_8 aucIpAddr[4]; -+} IPV4_NETWORK_ADDRESS, *P_IPV4_NETWORK_ADDRESS; -+ -+typedef struct _CMD_SET_NETWORK_ADDRESS_LIST { -+ UINT_8 ucNetTypeIndex; -+ UINT_8 ucAddressCount; -+ UINT_8 ucReserved[2]; -+ IPV4_NETWORK_ADDRESS arNetAddress[1]; -+} CMD_SET_NETWORK_ADDRESS_LIST, *P_CMD_SET_NETWORK_ADDRESS_LIST; -+ -+typedef struct _PATTERN_DESCRIPTION { -+ UINT_8 fgCheckBcA1; -+ UINT_8 fgCheckMcA1; -+ UINT_8 ePatternHeader; -+ UINT_8 fgAndOp; -+ UINT_8 fgNotOp; -+ UINT_8 ucPatternMask; -+ UINT_16 ucPatternOffset; -+ UINT_8 aucPattern[8]; -+} PATTERN_DESCRIPTION, *P_PATTERN_DESCRIPTION; -+ -+typedef struct _CMD_RAW_PATTERN_CONFIGURATION_T { -+ PATTERN_DESCRIPTION arPatternDesc[4]; -+} CMD_RAW_PATTERN_CONFIGURATION_T, *P_CMD_RAW_PATTERN_CONFIGURATION_T; -+ -+typedef struct _CMD_PATTERN_FUNC_CONFIG { -+ BOOLEAN fgBcA1En; -+ BOOLEAN fgMcA1En; -+ BOOLEAN fgBcA1MatchDrop; -+ BOOLEAN fgMcA1MatchDrop; -+} CMD_PATTERN_FUNC_CONFIG, *P_CMD_PATTERN_FUNC_CONFIG; -+ -+typedef struct _EVENT_TX_DONE_T { -+ UINT_8 ucPacketSeq; -+ UINT_8 ucStatus; -+ UINT_16 u2SequenceNumber; -+ UINT_32 au4Reserved1; -+ UINT_32 au4Reserved2; -+ UINT_32 au4Reserved3; -+} EVENT_TX_DONE_T, *P_EVENT_TX_DONE_T; -+ -+typedef struct _CMD_BSS_ACTIVATE_CTRL { -+ UINT_8 ucNetTypeIndex; -+ UINT_8 ucActive; -+ UINT_8 aucReserved[2]; -+} CMD_BSS_ACTIVATE_CTRL, *P_CMD_BSS_ACTIVATE_CTRL; -+ -+typedef struct _CMD_SET_BSS_RLM_PARAM_T { -+ UINT_8 ucNetTypeIndex; -+ UINT_8 ucRfBand; -+ UINT_8 ucPrimaryChannel; -+ UINT_8 ucRfSco; -+ UINT_8 ucErpProtectMode; -+ UINT_8 ucHtProtectMode; -+ UINT_8 ucGfOperationMode; -+ UINT_8 ucTxRifsMode; -+ UINT_16 u2HtOpInfo3; -+ UINT_16 u2HtOpInfo2; -+ UINT_8 ucHtOpInfo1; -+ UINT_8 ucUseShortPreamble; -+ UINT_8 ucUseShortSlotTime; -+ UINT_8 ucCheckId; /* Fixed value: 0x72 */ -+} CMD_SET_BSS_RLM_PARAM_T, *P_CMD_SET_BSS_RLM_PARAM_T; -+ -+typedef struct _CMD_SET_BSS_INFO { -+ UINT_8 ucNetTypeIndex; -+ UINT_8 ucConnectionState; -+ UINT_8 ucCurrentOPMode; -+ UINT_8 ucSSIDLen; -+ UINT_8 aucSSID[32]; -+ UINT_8 aucBSSID[6]; -+ UINT_8 ucIsQBSS; -+ UINT_8 ucReserved1; -+ UINT_16 u2OperationalRateSet; -+ UINT_16 u2BSSBasicRateSet; -+ UINT_8 ucStaRecIdxOfAP; -+ UINT_8 ucReserved2; -+ UINT_8 ucReserved3; -+ UINT_8 ucNonHTBasicPhyType; /* For Slot Time and CWmin */ -+ UINT_8 ucAuthMode; -+ UINT_8 ucEncStatus; -+ UINT_8 ucPhyTypeSet; -+ UINT_8 aucOwnMac[6]; -+ UINT_8 fgWapiMode; -+ UINT_8 fgIsApMode; -+ UINT_8 fgHiddenSsidMode; -+ CMD_SET_BSS_RLM_PARAM_T rBssRlmParam; -+} CMD_SET_BSS_INFO, *P_CMD_SET_BSS_INFO; -+ -+typedef struct _CMD_UPDATE_STA_RECORD_T { -+ UINT_8 ucIndex; -+ UINT_8 ucStaType; -+ UINT_8 aucMacAddr[MAC_ADDR_LEN]; -+ UINT_16 u2AssocId; -+ UINT_16 u2ListenInterval; -+ UINT_8 ucNetTypeIndex; -+ UINT_8 ucDesiredPhyTypeSet; -+ UINT_16 u2DesiredNonHTRateSet; -+ UINT_16 u2BSSBasicRateSet; -+ UINT_8 ucIsQoS; -+ UINT_8 ucIsUapsdSupported; -+ UINT_8 ucStaState; -+ UINT_8 ucMcsSet; -+ UINT_8 ucSupMcs32; -+ UINT_8 ucAmpduParam; -+ UINT_16 u2HtCapInfo; -+ UINT_16 u2HtExtendedCap; -+ UINT_32 u4TxBeamformingCap; -+ UINT_8 ucAselCap; -+ UINT_8 ucRCPI; -+ UINT_8 ucNeedResp; -+ UINT_8 ucUapsdAc; /* b0~3: Trigger enabled, b4~7: Delivery enabled */ -+ UINT_8 ucUapsdSp; /* 0: all, 1: max 2, 2: max 4, 3: max 6 */ -+ UINT_8 aucReserved[3]; -+ /* TBD */ -+} CMD_UPDATE_STA_RECORD_T, *P_CMD_UPDATE_STA_RECORD_T; -+ -+typedef struct _CMD_REMOVE_STA_RECORD_T { -+ UINT_8 ucIndex; -+ UINT_8 ucReserved; -+ UINT_8 aucMacAddr[MAC_ADDR_LEN]; -+} CMD_REMOVE_STA_RECORD_T, *P_CMD_REMOVE_STA_RECORD_T; -+ -+typedef struct _CMD_INDICATE_PM_BSS_CREATED_T { -+ UINT_8 ucNetTypeIndex; -+ UINT_8 ucDtimPeriod; -+ UINT_16 u2BeaconInterval; -+ UINT_16 u2AtimWindow; -+ UINT_8 aucReserved[2]; -+} CMD_INDICATE_PM_BSS_CREATED, *P_CMD_INDICATE_PM_BSS_CREATED; -+ -+typedef struct _CMD_INDICATE_PM_BSS_CONNECTED_T { -+ UINT_8 ucNetTypeIndex; -+ UINT_8 ucDtimPeriod; -+ UINT_16 u2AssocId; -+ UINT_16 u2BeaconInterval; -+ UINT_16 u2AtimWindow; -+ UINT_8 fgIsUapsdConnection; -+ UINT_8 ucBmpDeliveryAC; -+ UINT_8 ucBmpTriggerAC; -+ UINT_8 aucReserved[1]; -+} CMD_INDICATE_PM_BSS_CONNECTED, *P_CMD_INDICATE_PM_BSS_CONNECTED; -+ -+typedef struct _CMD_INDICATE_PM_BSS_ABORT { -+ UINT_8 ucNetTypeIndex; -+ UINT_8 aucReserved[3]; -+} CMD_INDICATE_PM_BSS_ABORT, *P_CMD_INDICATE_PM_BSS_ABORT; -+ -+typedef struct _CMD_BEACON_TEMPLATE_UPDATE { -+ UINT_8 ucUpdateMethod; /* 0: update randomly, -+ * 1: update all, -+ * 2: delete all (1 and 2 will update directly without search) -+ */ -+ UINT_8 ucNetTypeIndex; -+ UINT_8 aucReserved[2]; -+ UINT_16 u2Capability; -+ UINT_16 u2IELen; -+ UINT_8 aucIE[MAX_IE_LENGTH]; -+} CMD_BEACON_TEMPLATE_UPDATE, *P_CMD_BEACON_TEMPLATE_UPDATE; -+ -+typedef struct _CMD_SET_WMM_PS_TEST_STRUCT_T { -+ UINT_8 ucNetTypeIndex; -+ UINT_8 bmfgApsdEnAc; /* b0~3: trigger-en AC0~3. b4~7: delivery-en AC0~3 */ -+ UINT_8 ucIsEnterPsAtOnce; /* enter PS immediately without 5 second guard after connected */ -+ UINT_8 ucIsDisableUcTrigger; /* not to trigger UC on beacon TIM is matched (under U-APSD) */ -+} CMD_SET_WMM_PS_TEST_STRUCT_T, *P_CMD_SET_WMM_PS_TEST_STRUCT_T; -+ -+/* Definition for CHANNEL_INFO.ucBand: -+ * 0: Reserved -+ * 1: BAND_2G4 -+ * 2: BAND_5G -+ * Others: Reserved -+ */ -+typedef struct _CHANNEL_INFO_T { -+ UINT_8 ucBand; -+ UINT_8 ucChannelNum; -+} CHANNEL_INFO_T, *P_CHANNEL_INFO_T; -+ -+typedef struct _CMD_SCAN_REQ_EXT_CH_T { -+ UINT_8 ucSeqNum; -+ UINT_8 ucNetworkType; -+ UINT_8 ucScanType; -+ UINT_8 ucSSIDType; /* BIT(0) wildcard / BIT(1) P2P-wildcard / BIT(2) specific */ -+ UINT_8 ucSSIDLength; -+ UINT_8 aucReserved[1]; -+ UINT_16 u2ChannelMinDwellTime; -+ UINT_8 aucSSID[32]; -+ UINT_16 u2ChannelDwellTime; /* For P2P */ -+ UINT_8 ucChannelType; -+ UINT_8 ucChannelListNum; -+ CHANNEL_INFO_T arChannelList[MAXIMUM_OPERATION_CHANNEL_LIST]; -+ UINT_16 u2IELen; -+ UINT_8 aucIE[MAX_IE_LENGTH]; -+} CMD_SCAN_REQ_EXT_CH, *P_CMD_SCAN_REQ_EXT_CH; -+ -+typedef struct _CMD_SCAN_REQ_T { -+ UINT_8 ucSeqNum; -+ UINT_8 ucNetworkType; -+ UINT_8 ucScanType; -+ UINT_8 ucSSIDType; /* BIT(0) wildcard / BIT(1) P2P-wildcard / BIT(2) specific */ -+ UINT_8 ucSSIDLength; -+ UINT_8 aucReserved[1]; -+ UINT_16 u2ChannelMinDwellTime; -+ UINT_8 aucSSID[32]; -+ UINT_16 u2ChannelDwellTime; /* For P2P */ -+ UINT_8 ucChannelType; -+ UINT_8 ucChannelListNum; -+ CHANNEL_INFO_T arChannelList[32]; -+ UINT_16 u2IELen; -+ UINT_8 aucIE[MAX_IE_LENGTH]; -+} CMD_SCAN_REQ, *P_CMD_SCAN_REQ; -+ -+typedef struct _CMD_SCAN_REQ_V2_EXT_CH_T { -+ UINT_8 ucSeqNum; -+ UINT_8 ucNetworkType; -+ UINT_8 ucScanType; -+ UINT_8 ucSSIDType; -+ PARAM_SSID_T arSSID[4]; -+ UINT_16 u2ProbeDelayTime; -+ UINT_16 u2ChannelDwellTime; /* For P2P */ -+ UINT_8 ucChannelType; -+ UINT_8 ucChannelListNum; -+ CHANNEL_INFO_T arChannelList[MAXIMUM_OPERATION_CHANNEL_LIST]; -+ UINT_16 u2IELen; -+ UINT_8 aucIE[MAX_IE_LENGTH]; -+} CMD_SCAN_REQ_V2_EXT_CH, *P_CMD_SCAN_REQ_V2_EXT_CH; -+ -+typedef struct _CMD_SCAN_REQ_V2_T { -+ UINT_8 ucSeqNum; -+ UINT_8 ucNetworkType; -+ UINT_8 ucScanType; -+ UINT_8 ucSSIDType; -+ PARAM_SSID_T arSSID[4]; -+ UINT_16 u2ProbeDelayTime; -+ UINT_16 u2ChannelDwellTime; /* For P2P */ -+ UINT_8 ucChannelType; -+ UINT_8 ucChannelListNum; -+ CHANNEL_INFO_T arChannelList[32]; -+ UINT_16 u2IELen; -+ UINT_8 aucIE[MAX_IE_LENGTH]; -+} CMD_SCAN_REQ_V2, *P_CMD_SCAN_REQ_V2; -+ -+typedef struct _CMD_SCAN_CANCEL_T { -+ UINT_8 ucSeqNum; -+ UINT_8 ucIsExtChannel; /* For P2P channel extension. */ -+ UINT_8 aucReserved[2]; -+} CMD_SCAN_CANCEL, *P_CMD_SCAN_CANCEL; -+ -+typedef struct _EVENT_SCAN_DONE_T { -+ UINT_8 ucSeqNum; -+ UINT_8 ucSparseChannelValid; -+ CHANNEL_INFO_T rSparseChannel; -+} EVENT_SCAN_DONE, *P_EVENT_SCAN_DONE; -+ -+#if CFG_SUPPORT_GET_CH_ENV -+typedef struct _CH_ENV_T { -+ UINT_8 ucChNum; -+ UINT_8 ucApNum; -+} CH_ENV_T, *P_CH_ENV_T; -+#endif -+ -+#if 0 /* CFG_SUPPORT_BATCH_SCAN */ -+typedef struct _CMD_BATCH_REQ_T { -+ UINT_8 ucSeqNum; -+ UINT_8 ucNetTypeIndex; -+ UINT_8 ucCmd; /* Start/ Stop */ -+ UINT_8 ucMScan; /* an integer number of scans per batch */ -+ UINT_8 ucBestn; /* an integer number of the max AP to remember per scan */ -+ UINT_8 ucRtt; /* an integer number of highest-strength AP for which we'd -+ like approximate distance reported */ -+ UINT_8 ucChannel; /* channels */ -+ UINT_8 ucChannelType; -+ UINT_8 ucChannelListNum; -+ UINT_8 aucReserved[3]; -+ UINT_32 u4Scanfreq; /* an integer number of seconds between scans */ -+ CHANNEL_INFO_T arChannelList[32]; /* channels */ -+} CMD_BATCH_REQ_T, *P_CMD_BATCH_REQ_T; -+ -+typedef struct _EVENT_BATCH_RESULT_ENTRY_T { -+ UINT_8 aucBssid[MAC_ADDR_LEN]; -+ UINT_8 aucSSID[ELEM_MAX_LEN_SSID]; -+ UINT_8 ucSSIDLen; -+ INT_8 cRssi; -+ UINT_32 ucFreq; -+ UINT_32 u4Age; -+ UINT_32 u4Dist; -+ UINT_32 u4Distsd; -+} EVENT_BATCH_RESULT_ENTRY_T, *P_EVENT_BATCH_RESULT_ENTRY_T; -+ -+typedef struct _EVENT_BATCH_RESULT_T { -+ UINT_8 ucScanCount; -+ UINT_8 aucReserved[3]; -+ EVENT_BATCH_RESULT_ENTRY_T arBatchResult[12]; /* Must be the same with SCN_BATCH_STORE_MAX_NUM */ -+} EVENT_BATCH_RESULT_T, *P_EVENT_BATCH_RESULT_T; -+#endif -+ -+typedef struct _CMD_CH_PRIVILEGE_T { -+ UINT_8 ucNetTypeIndex; -+ UINT_8 ucTokenID; -+ UINT_8 ucAction; -+ UINT_8 ucPrimaryChannel; -+ UINT_8 ucRfSco; -+ UINT_8 ucRfBand; -+ UINT_8 ucReqType; -+ UINT_8 ucReserved; -+ UINT_32 u4MaxInterval; /* In unit of ms */ -+ UINT_8 aucBSSID[6]; -+ UINT_8 aucReserved[2]; -+} CMD_CH_PRIVILEGE_T, *P_CMD_CH_PRIVILEGE_T; -+ -+typedef struct _CMD_TX_PWR_T { -+ INT_8 cTxPwr2G4Cck; /* signed, in unit of 0.5dBm */ -+#if defined(MT6620) -+ INT_8 acReserved[3]; -+#elif defined(MT6628) -+ INT_8 cTxPwr2G4Dsss; /* signed, in unit of 0.5dBm */ -+ INT_8 acReserved[2]; -+#else -+#error "No valid definition!" -+#endif -+ -+ INT_8 cTxPwr2G4OFDM_BPSK; -+ INT_8 cTxPwr2G4OFDM_QPSK; -+ INT_8 cTxPwr2G4OFDM_16QAM; -+ INT_8 cTxPwr2G4OFDM_Reserved; -+ INT_8 cTxPwr2G4OFDM_48Mbps; -+ INT_8 cTxPwr2G4OFDM_54Mbps; -+ -+ INT_8 cTxPwr2G4HT20_BPSK; -+ INT_8 cTxPwr2G4HT20_QPSK; -+ INT_8 cTxPwr2G4HT20_16QAM; -+ INT_8 cTxPwr2G4HT20_MCS5; -+ INT_8 cTxPwr2G4HT20_MCS6; -+ INT_8 cTxPwr2G4HT20_MCS7; -+ -+ INT_8 cTxPwr2G4HT40_BPSK; -+ INT_8 cTxPwr2G4HT40_QPSK; -+ INT_8 cTxPwr2G4HT40_16QAM; -+ INT_8 cTxPwr2G4HT40_MCS5; -+ INT_8 cTxPwr2G4HT40_MCS6; -+ INT_8 cTxPwr2G4HT40_MCS7; -+ -+ INT_8 cTxPwr5GOFDM_BPSK; -+ INT_8 cTxPwr5GOFDM_QPSK; -+ INT_8 cTxPwr5GOFDM_16QAM; -+ INT_8 cTxPwr5GOFDM_Reserved; -+ INT_8 cTxPwr5GOFDM_48Mbps; -+ INT_8 cTxPwr5GOFDM_54Mbps; -+ -+ INT_8 cTxPwr5GHT20_BPSK; -+ INT_8 cTxPwr5GHT20_QPSK; -+ INT_8 cTxPwr5GHT20_16QAM; -+ INT_8 cTxPwr5GHT20_MCS5; -+ INT_8 cTxPwr5GHT20_MCS6; -+ INT_8 cTxPwr5GHT20_MCS7; -+ -+ INT_8 cTxPwr5GHT40_BPSK; -+ INT_8 cTxPwr5GHT40_QPSK; -+ INT_8 cTxPwr5GHT40_16QAM; -+ INT_8 cTxPwr5GHT40_MCS5; -+ INT_8 cTxPwr5GHT40_MCS6; -+ INT_8 cTxPwr5GHT40_MCS7; -+} CMD_TX_PWR_T, *P_CMD_TX_PWR_T; -+ -+typedef struct _CMD_5G_PWR_OFFSET_T { -+ INT_8 cOffsetBand0; /* 4.915-4.980G */ -+ INT_8 cOffsetBand1; /* 5.000-5.080G */ -+ INT_8 cOffsetBand2; /* 5.160-5.180G */ -+ INT_8 cOffsetBand3; /* 5.200-5.280G */ -+ INT_8 cOffsetBand4; /* 5.300-5.340G */ -+ INT_8 cOffsetBand5; /* 5.500-5.580G */ -+ INT_8 cOffsetBand6; /* 5.600-5.680G */ -+ INT_8 cOffsetBand7; /* 5.700-5.825G */ -+} CMD_5G_PWR_OFFSET_T, *P_CMD_5G_PWR_OFFSET_T; -+ -+typedef struct _CMD_PWR_PARAM_T { -+ UINT_32 au4Data[28]; -+ UINT_32 u4RefValue1; -+ UINT_32 u4RefValue2; -+} CMD_PWR_PARAM_T, *P_CMD_PWR_PARAM_T; -+ -+typedef struct _CMD_PHY_PARAM_T { -+ UINT_8 aucData[144]; /* eFuse content */ -+} CMD_PHY_PARAM_T, *P_CMD_PHY_PARAM_T; -+ -+typedef struct _CMD_AUTO_POWER_PARAM_T { -+ UINT_8 ucType; /* 0: Disable 1: Enalbe 0x10: Change parameters */ -+ UINT_8 ucNetTypeIndex; -+ UINT_8 aucReserved[2]; -+ UINT_8 aucLevelRcpiTh[3]; -+ UINT_8 aucReserved2[1]; -+ INT_8 aicLevelPowerOffset[3]; /* signed, in unit of 0.5dBm */ -+ UINT_8 aucReserved3[1]; -+ UINT_8 aucReserved4[8]; -+} CMD_AUTO_POWER_PARAM_T, *P_CMD_AUTO_POWER_PARAM_T; -+ -+typedef struct _EVENT_CH_PRIVILEGE_T { -+ UINT_8 ucNetTypeIndex; -+ UINT_8 ucTokenID; -+ UINT_8 ucStatus; -+ UINT_8 ucPrimaryChannel; -+ UINT_8 ucRfSco; -+ UINT_8 ucRfBand; -+ UINT_8 ucReqType; -+ UINT_8 ucReserved; -+ UINT_32 u4GrantInterval; /* In unit of ms */ -+} EVENT_CH_PRIVILEGE_T, *P_EVENT_CH_PRIVILEGE_T; -+ -+typedef enum _ENUM_BEACON_TIMEOUT_TYPE_T { -+ BEACON_TIMEOUT_LOST_BEACON = 0, -+ BEACON_TIMEOUT_AGE, -+ BEACON_TIMEOUT_CONNECT, -+ BEACON_TIMEOUT_BEACON_INTERVAL, -+ BEACON_TIMEOUT_ABORT, -+ BEACON_TIMEOUT_TX_ERROR, -+ BEACON_TIMEOUT_TYPE_NUM -+} ENUM_BEACON_TIMEOUT_TYPE_T, *P_ENUM_BEACON_TIMEOUT_TYPE_T; -+ -+typedef struct _EVENT_BSS_BEACON_TIMEOUT_T { -+ UINT_8 ucNetTypeIndex; -+ UINT_8 ucReason; /* ENUM_BEACON_TIMEOUT_TYPE_T */ -+ UINT_8 aucReserved[2]; -+} EVENT_BSS_BEACON_TIMEOUT_T, *P_EVENT_BSS_BEACON_TIMEOUT_T; -+ -+typedef struct _EVENT_STA_AGING_TIMEOUT_T { -+ UINT_8 ucStaRecIdx; -+ UINT_8 aucReserved[3]; -+} EVENT_STA_AGING_TIMEOUT_T, *P_EVENT_STA_AGING_TIMEOUT_T; -+ -+typedef struct _EVENT_NOA_TIMING_T { -+ UINT_8 fgIsInUse; /* Indicate if this entry is in use or not */ -+ UINT_8 ucCount; /* Count */ -+ UINT_8 aucReserved[2]; -+ -+ UINT_32 u4Duration; /* Duration */ -+ UINT_32 u4Interval; /* Interval */ -+ UINT_32 u4StartTime; /* Start Time */ -+} EVENT_NOA_TIMING_T, *P_EVENT_NOA_TIMING_T; -+ -+typedef struct _EVENT_UPDATE_NOA_PARAMS_T { -+ UINT_8 ucNetTypeIndex; -+ UINT_8 aucReserved[2]; -+ UINT_8 fgEnableOppPS; -+ UINT_16 u2CTWindow; -+ -+ UINT_8 ucNoAIndex; -+ UINT_8 ucNoATimingCount; /* Number of NoA Timing */ -+ EVENT_NOA_TIMING_T arEventNoaTiming[8 /*P2P_MAXIMUM_NOA_COUNT */]; -+} EVENT_UPDATE_NOA_PARAMS_T, *P_EVENT_UPDATE_NOA_PARAMS_T; -+ -+typedef struct _EVENT_AP_OBSS_STATUS_T { -+ UINT_8 ucNetTypeIndex; -+ UINT_8 ucObssErpProtectMode; -+ UINT_8 ucObssHtProtectMode; -+ UINT_8 ucObssGfOperationMode; -+ UINT_8 ucObssRifsOperationMode; -+ UINT_8 ucObssBeaconForcedTo20M; -+ UINT_8 aucReserved[2]; -+} EVENT_AP_OBSS_STATUS_T, *P_EVENT_AP_OBSS_STATUS_T; -+ -+typedef struct _CMD_EDGE_TXPWR_LIMIT_T { -+ INT_8 cBandEdgeMaxPwrCCK; -+ INT_8 cBandEdgeMaxPwrOFDM20; -+ INT_8 cBandEdgeMaxPwrOFDM40; -+ INT_8 cReserved; -+} CMD_EDGE_TXPWR_LIMIT_T, *P_CMD_EDGE_TXPWR_LIMIT_T; -+ -+typedef struct _CMD_RSSI_COMPENSATE_T { -+ UINT_8 uc2GRssiCompensation; -+ UINT_8 uc5GRssiCompensation; -+ UINT_8 ucRssiCompensationValidbit; -+ UINT_8 cReserved; -+} CMD_RSSI_COMPENSATE_T, *P_CMD_RSSI_COMPENSATE_T; -+ -+typedef struct _CMD_BAND_SUPPORT_T { -+ UINT_8 uc5GBandSupport; -+ UINT_8 cReserved[3]; -+} CMD_BAND_SUPPORT_T, *P_CMD_BAND_SUPPORT_T; -+ -+typedef struct _CMD_TX_PWR_CE_T { -+ INT_8 cTxPwrCckLmt; /* signed, in unit of 0.5dBm */ -+ INT_8 cTxPwrOfdmLmt; /* signed, in unit of 0.5dBm */ -+ INT_8 cTxPwrHt20Lmt; -+ INT_8 cTxPwrHt40Lmt; -+} CMD_TX_PWR_CE_T, *P_CMD_TX_PWR_CE_T; -+ -+typedef struct _CMD_SET_DEVICE_MODE_T { -+ UINT_16 u2ChipID; -+ UINT_16 u2Mode; -+} CMD_SET_DEVICE_MODE_T, *P_CMD_SET_DEVICE_MODE_T; -+ -+#if CFG_SUPPORT_RDD_TEST_MODE -+typedef struct _CMD_RDD_CH_T { -+ UINT_8 ucRddTestMode; -+ UINT_8 ucRddShutCh; -+ UINT_8 ucRddStartCh; -+ UINT_8 ucRddStopCh; -+ UINT_8 ucRddDfs; -+ UINT_8 ucReserved; -+ UINT_8 ucReserved1; -+ UINT_8 ucReserved2; -+} CMD_RDD_CH_T, *P_CMD_RDD_CH_T; -+ -+typedef struct _EVENT_RDD_STATUS_T { -+ UINT_8 ucRddStatus; -+ UINT_8 aucReserved[3]; -+} EVENT_RDD_STATUS_T, *P_EVENT_RDD_STATUS_T; -+#endif -+ -+typedef struct _EVENT_AIS_BSS_INFO_T { -+ ENUM_PARAM_MEDIA_STATE_T eConnectionState; /* Connected Flag used in AIS_NORMAL_TR */ -+ ENUM_OP_MODE_T eCurrentOPMode; /* Current Operation Mode - Infra/IBSS */ -+ BOOLEAN fgIsNetActive; /* TRUE if this network has been actived */ -+ UINT_8 ucReserved[3]; -+} EVENT_AIS_BSS_INFO_T, *P_EVENT_AIS_BSS_INFO_T; -+ -+typedef struct _CMD_SET_TXPWR_CTRL_T { -+ INT_8 c2GLegacyStaPwrOffset; /* Unit: 0.5dBm, default: 0 */ -+ INT_8 c2GHotspotPwrOffset; -+ INT_8 c2GP2pPwrOffset; -+ INT_8 c2GBowPwrOffset; -+ INT_8 c5GLegacyStaPwrOffset; /* Unit: 0.5dBm, default: 0 */ -+ INT_8 c5GHotspotPwrOffset; -+ INT_8 c5GP2pPwrOffset; -+ INT_8 c5GBowPwrOffset; -+ UINT_8 ucConcurrencePolicy; /* TX power policy when concurrence -+ in the same channel -+ 0: Highest power has priority -+ 1: Lowest power has priority */ -+ INT_8 acReserved1[3]; /* Must be zero */ -+ -+ /* Power limit by channel for all data rates */ -+ INT_8 acTxPwrLimit2G[14]; /* Channel 1~14, Unit: 0.5dBm */ -+ INT_8 acTxPwrLimit5G[4]; /* UNII 1~4 */ -+ INT_8 acReserved2[2]; /* Must be zero */ -+} CMD_SET_TXPWR_CTRL_T, *P_CMD_SET_TXPWR_CTRL_T; -+ -+#if CFG_SUPPORT_BUILD_DATE_CODE -+typedef struct _CMD_GET_BUILD_DATE_CODE { -+ UINT_8 aucReserved[4]; -+} CMD_GET_BUILD_DATE_CODE, *P_CMD_GET_BUILD_DATE_CODE; -+ -+typedef struct _EVENT_BUILD_DATE_CODE { -+ UINT_8 aucDateCode[16]; -+} EVENT_BUILD_DATE_CODE, *P_EVENT_BUILD_DATE_CODE; -+#endif -+ -+typedef struct _CMD_GET_STA_STATISTICS_T { -+ UINT_8 ucIndex; -+ UINT_8 ucFlags; -+ UINT_8 ucReadClear; -+ UINT_8 aucReserved0[1]; -+ UINT_8 aucMacAddr[MAC_ADDR_LEN]; -+ UINT_8 aucReserved1[2]; -+ UINT_8 aucReserved2[16]; -+} CMD_GET_STA_STATISTICS_T, *P_CMD_GET_STA_STATISTICS_T; -+ -+/* CFG_SUPPORT_WFD */ -+typedef struct _EVENT_STA_STATISTICS_T { -+ /* Event header */ -+ /* UINT_16 u2Length; */ -+ /* UINT_16 u2Reserved1; *//* Must be filled with 0x0001 (EVENT Packet) */ -+ /* UINT_8 ucEID; */ -+ /* UINT_8 ucSeqNum; */ -+ /* UINT_8 aucReserved2[2]; */ -+ -+ /* Event Body */ -+ UINT_8 ucVersion; -+ UINT_8 aucReserved1[3]; -+ UINT_32 u4Flags; /* Bit0: valid */ -+ -+ UINT_8 ucStaRecIdx; -+ UINT_8 ucNetworkTypeIndex; -+ UINT_8 ucWTEntry; -+ UINT_8 aucReserved4[1]; -+ -+ UINT_8 ucMacAddr[MAC_ADDR_LEN]; -+ UINT_8 ucPer; /* base: 128 */ -+ UINT_8 ucRcpi; -+ -+ UINT_32 u4PhyMode; /* SGI BW */ -+ UINT_16 u2LinkSpeed; /* unit is 0.5 Mbits */ -+ UINT_8 ucLinkQuality; -+ UINT_8 ucLinkReserved; -+ -+ UINT_32 u4TxCount; -+ UINT_32 u4TxFailCount; -+ UINT_32 u4TxLifeTimeoutCount; -+ UINT_32 u4TxDoneAirTime; -+ -+ UINT_8 aucReserved[64]; -+} EVENT_STA_STATISTICS_T, *P_EVENT_STA_STATISTICS_T; -+ -+#if CFG_SUPPORT_HOTSPOT_OPTIMIZATION -+typedef struct _CMD_HOTSPOT_OPTIMIZATION_CONFIG { -+ UINT_32 fgHotspotOptimizationEn; -+ UINT_32 u4Level; -+} CMD_HOTSPOT_OPTIMIZATION_CONFIG, *P_HOTSPOT_OPTIMIZATION_CONFIG; -+#endif -+#if CFG_AUTO_CHANNEL_SEL_SUPPORT -+ -+/* 4 Auto Channel Selection */ -+ -+typedef struct _CMD_GET_CHN_LOAD_T { -+ UINT_8 ucIndex; -+ UINT_8 ucFlags; -+ UINT_8 ucReadClear; -+ UINT_8 aucReserved0[1]; -+ -+ UINT_8 ucChannel; -+ UINT_16 u2ChannelLoad; -+ UINT_8 aucReserved1[1]; -+ UINT_8 aucReserved2[16]; -+} CMD_GET_CHN_LOAD_T, *P_CMD_GET_CHN_LOAD_T; -+/* 4 Auto Channel Selection */ -+ -+typedef struct _EVENT_CHN_LOAD_T { -+ /* Event Body */ -+ UINT_8 ucVersion; -+ UINT_8 aucReserved1[3]; -+ UINT_32 u4Flags; /* Bit0: valid */ -+ -+ UINT_8 ucChannel; -+ UINT_16 u2ChannelLoad; -+ UINT_8 aucReserved4[1]; -+ -+ UINT_8 aucReserved[64]; -+ -+} EVENT_CHN_LOAD_T, *P_EVENT_CHN_LOAD_T; -+typedef struct _CMD_GET_LTE_SAFE_CHN_T { -+ UINT_8 ucIndex; -+ UINT_8 ucFlags; -+ UINT_8 aucReserved0[2]; -+ -+ UINT_8 aucReserved2[16]; -+} CMD_GET_LTE_SAFE_CHN_T, *P_CMD_GET_LTE_SAFE_CHN_T; -+ -+typedef struct _EVENT_LTE_MODE_T { -+ /* Event Body */ -+ UINT_8 ucVersion; -+ UINT_8 aucReserved1[3]; -+ UINT_32 u4Flags; /* Bit0: valid */ -+ -+ LTE_SAFE_CH_INFO_T rLteSafeChn; -+ UINT_8 aucReserved4[3]; -+ -+ UINT_8 aucReserved[4]; -+ -+} EVENT_LTE_MODE_T, *P_EVENT_LTE_MODE_T; -+#endif -+typedef struct _CMD_ROAMING_INFO_T { -+ UINT_32 fgIsFastRoamingApplied; -+ UINT_32 Reserved[9]; -+} CMD_ROAMING_INFO_T; -+ -+typedef struct _CMD_WFD_DEBUG_MODE_INFO_T { -+ UINT_8 ucDebugMode; -+ UINT_16 u2PeriodInteval; -+ UINT_8 Reserved; -+} CMD_WFD_DEBUG_MODE_INFO_T, *P_CMD_WFD_DEBUG_MODE_INFO_T; -+ -+typedef struct _EVENT_FW_LOG_T { -+ UINT_8 fileName[64]; -+ UINT_32 lineNo; -+ UINT_32 WifiUpTime; -+ UINT_8 log[896]; /* total size is aucBuffer in WIFI_EVENT_T */ -+} EVENT_FW_LOG_T, *P_EVENT_FW_LOG_T; -+ -+typedef enum _ENUM_NLO_CIPHER_ALGORITHM { -+ NLO_CIPHER_ALGO_NONE = 0x00, -+ NLO_CIPHER_ALGO_WEP40 = 0x01, -+ NLO_CIPHER_ALGO_TKIP = 0x02, -+ NLO_CIPHER_ALGO_CCMP = 0x04, -+ NLO_CIPHER_ALGO_WEP104 = 0x05, -+ NLO_CIPHER_ALGO_WPA_USE_GROUP = 0x100, -+ NLO_CIPHER_ALGO_RSN_USE_GROUP = 0x100, -+ NLO_CIPHER_ALGO_WEP = 0x101, -+} ENUM_NLO_CIPHER_ALGORITHM, *P_ENUM_NLO_CIPHER_ALGORITHM; -+ -+typedef enum _ENUM_NLO_AUTH_ALGORITHM { -+ NLO_AUTH_ALGO_80211_OPEN = 1, -+ NLO_AUTH_ALGO_80211_SHARED_KEY = 2, -+ NLO_AUTH_ALGO_WPA = 3, -+ NLO_AUTH_ALGO_WPA_PSK = 4, -+ NLO_AUTH_ALGO_WPA_NONE = 5, -+ NLO_AUTH_ALGO_RSNA = 6, -+ NLO_AUTH_ALGO_RSNA_PSK = 7, -+} ENUM_NLO_AUTH_ALGORITHM, *P_ENUM_NLO_AUTH_ALGORITHM; -+ -+typedef struct _NLO_NETWORK { -+ UINT_8 ucNumChannelHint[4]; -+ UINT_8 ucSSIDLength; -+ UINT_8 ucCipherAlgo; -+ UINT_16 u2AuthAlgo; -+ UINT_8 aucSSID[32]; -+} NLO_NETWORK, *P_NLO_NETWORK; -+ -+typedef struct _CMD_NLO_REQ { -+ UINT_8 ucSeqNum; -+ UINT_8 ucBssIndex; -+ UINT_8 ucNetworkType; -+ UINT_8 fgStopAfterIndication; -+ UINT_8 ucFastScanIteration; -+ UINT_16 u2FastScanPeriod; -+ UINT_16 u2SlowScanPeriod; -+ UINT_8 ucEntryNum; -+ UINT_8 ucReserved; -+ UINT_16 u2IELen; -+ NLO_NETWORK arNetworkList[16]; -+ UINT_8 aucIE[0]; -+ UINT_8 ucScanType; -+} CMD_NLO_REQ, *P_CMD_NLO_REQ; -+ -+typedef struct _CMD_NLO_CANCEL_T { -+ UINT_8 ucSeqNum; -+ UINT_8 aucReserved[3]; -+} CMD_NLO_CANCEL, *P_CMD_NLO_CANCEL; -+ -+typedef struct _EVENT_NLO_DONE_T { -+ UINT_8 ucSeqNum; -+ UINT_8 ucStatus; -+ UINT_8 aucReserved[2]; -+} EVENT_NLO_DONE_T, *P_EVENT_NLO_DONE_T; -+ -+typedef struct _EVENT_GSCAN_CAPABILITY_T { -+ UINT_8 ucVersion; -+ UINT_8 aucReserved1[3]; -+ UINT_32 u4MaxScanCacheSize; -+ UINT_32 u4MaxScanBuckets; -+ UINT_32 u4MaxApCachePerScan; -+ UINT_32 u4MaxRssiSampleSize; -+ UINT_32 u4MaxScanReportingThreshold; -+ UINT_32 u4MaxHotlistAps; -+ UINT_32 u4MaxSignificantWifiChangeAps; -+ UINT_32 au4Reserved[4]; -+} EVENT_GSCAN_CAPABILITY_T, *P_EVENT_GSCAN_CAPABILITY_T; -+ -+typedef struct _EVENT_GSCAN_SCAN_AVAILABLE_T { -+ UINT_16 u2Num; -+ UINT_8 aucReserved[2]; -+} EVENT_GSCAN_SCAN_AVAILABLE_T, *P_EVENT_GSCAN_SCAN_AVAILABLE_T; -+ -+typedef struct _EVENT_GSCAN_SCAN_COMPLETE_T { -+ UINT_8 ucScanState; -+ UINT_8 aucReserved[3]; -+} EVENT_GSCAN_SCAN_COMPLETE_T, *P_EVENT_GSCAN_SCAN_COMPLETE_T; -+ -+typedef struct WIFI_GSCAN_RESULT { -+ UINT_64 u8Ts; /* Time of discovery */ -+ UINT_8 arSsid[ELEM_MAX_LEN_SSID + 1]; /* null terminated */ -+ UINT_8 arMacAddr[6]; /* BSSID */ -+ UINT_32 u4Channel; /* channel frequency in MHz */ -+ INT_32 i4Rssi; /* in db */ -+ UINT_64 u8Rtt; /* in nanoseconds */ -+ UINT_64 u8RttSd; /* standard deviation in rtt */ -+ UINT_16 u2BeaconPeriod; /* units are Kusec */ -+ UINT_16 u2Capability; /* Capability information */ -+ UINT_32 u4IeLength; /* byte length of Information Elements */ -+ UINT_8 ucIeData[1]; /* IE data to follow */ -+} WIFI_GSCAN_RESULT_T, *P_WIFI_GSCAN_RESULT_T; -+ -+typedef struct _EVENT_GSCAN_RESULT_T { -+ UINT_8 ucVersion; -+ UINT_8 aucReserved[3]; -+ UINT_16 u2ScanId; -+ UINT_16 u2ScanFlags; -+ UINT_16 u2NumOfResults; -+ WIFI_GSCAN_RESULT_T rResult[1]; -+} EVENT_GSCAN_RESULT_T, *P_EVENT_GSCAN_RESULT_T; -+ -+typedef struct _EVENT_GSCAN_FULL_RESULT_T { -+ UINT_8 ucVersion; -+ UINT_8 aucReserved[3]; -+ WIFI_GSCAN_RESULT_T rResult; -+} EVENT_GSCAN_FULL_RESULT_T, *P_EVENT_GSCAN_FULL_RESULT_T; -+ -+typedef struct GSCAN_SWC_NET { -+ UINT_16 u2Flags; -+ UINT_16 u2Channel; -+ UINT_8 arBssid[6]; -+ INT_8 aicRssi[SCN_PSCAN_SWC_RSSI_WIN_MAX]; -+} GSCAN_SWC_NET_T, P_GSCAN_SWC_NET_T; -+ -+typedef struct _EVENT_GSCAN_SIGNIFICANT_CHANGE_T { -+ UINT_8 ucVersion; -+ UINT_8 aucReserved[3]; -+ GSCAN_SWC_NET_T arNet[SCN_PSCAN_SWC_MAX_NUM]; -+} EVENT_GSCAN_SIGNIFICANT_CHANGE_T, *P_EVENT_GSCAN_SIGNIFICANT_CHANGE_T; -+ -+typedef struct _EVENT_GSCAN_GEOFENCE_FOUND_T { -+ UINT_8 ucVersion; -+ UINT_8 aucReserved[3]; -+ WIFI_GSCAN_RESULT_T rResult[SCN_PSCAN_HOTLIST_REPORT_MAX_NUM]; -+} EVENT_GSCAN_GEOFENCE_FOUND_T, *P_EVENT_GSCAN_GEOFENCE_FOUND_T; -+ -+#if CFG_SUPPORT_BATCH_SCAN -+ -+#if 0 /* !CFG_SUPPORT_GSCN */ -+typedef struct _CMD_BATCH_REQ_T { -+ UINT_8 ucSeqNum; -+ UINT_8 ucNetTypeIndex; -+ UINT_8 ucCmd; /* Start/ Stop */ -+ UINT_8 ucMScan; /* an integer number of scans per batch */ -+ UINT_8 ucBestn; /* an integer number of the max AP to remember per scan */ -+ UINT_8 ucRtt; /* an integer number of highest-strength AP for which -+ we'd like approximate distance reported */ -+ UINT_8 ucChannel; /* channels */ -+ UINT_8 ucChannelType; -+ UINT_8 ucChannelListNum; -+ UINT_8 aucReserved[3]; -+ UINT_32 u4Scanfreq; /* an integer number of seconds between scans */ -+ CHANNEL_INFO_T arChannelList[32]; /* channels */ -+} CMD_BATCH_REQ_T, *P_CMD_BATCH_REQ_T; -+ -+#endif -+ -+typedef struct _EVENT_BATCH_RESULT_ENTRY_T { -+ UINT_8 aucBssid[MAC_ADDR_LEN]; -+ UINT_8 aucSSID[ELEM_MAX_LEN_SSID]; -+ UINT_8 ucSSIDLen; -+ INT_8 cRssi; -+ UINT_32 ucFreq; -+ UINT_32 u4Age; -+ UINT_32 u4Dist; -+ UINT_32 u4Distsd; -+} EVENT_BATCH_RESULT_ENTRY_T, *P_EVENT_BATCH_RESULT_ENTRY_T; -+ -+typedef struct _EVENT_BATCH_RESULT_T { -+ UINT_8 ucScanCount; -+ UINT_8 aucReserved[3]; -+ EVENT_BATCH_RESULT_ENTRY_T arBatchResult[12]; /* Must be the same with SCN_BATCH_STORE_MAX_NUM */ -+} EVENT_BATCH_RESULT_T, *P_EVENT_BATCH_RESULT_T; -+#endif -+ -+typedef struct _CMD_RLM_INFO_T { -+ UINT_32 u4Version; -+ UINT_32 fgIsErrRatioEnhanceApplied; -+ UINT_8 ucErrRatio2LimitMinRate; -+ /* -+ 0:1M, 1:2M, 2:5.5M, 3:11M, 6:6M, 7:9M, 8:12M, 9:18M, 10:24M, 11:36M, 12:48M, 13:54M -+ */ -+ UINT_8 ucMinLegacyRateIdx; -+ INT_8 cMinRssiThreshold; -+ BOOLEAN fgIsRtsApplied; -+ UINT_8 ucRecoverTime; -+ -+ UINT_32 u4Reserved[0]; -+} CMD_RLM_INFO_T; -+ -+typedef struct _WIFI_SYSTEM_SUSPEND_CMD_T { -+ BOOLEAN fgIsSystemSuspend; -+ UINT_8 reserved[3]; -+} WIFI_SYSTEM_SUSPEND_CMD_T, *P_WIFI_SYSTEM_SUSPEND_CMD_T; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+VOID nicCmdEventQueryMcrRead(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); -+ -+VOID nicCmdEventQueryMemDump(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); -+ -+VOID nicCmdEventQuerySwCtrlRead(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); -+ -+VOID nicCmdEventQueryRfTestATInfo(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); -+ -+VOID nicCmdEventSetCommon(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); -+ -+VOID nicCmdEventSetDisassociate(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); -+ -+VOID nicCmdEventSetIpAddress(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); -+ -+VOID nicCmdEventQueryLinkQuality(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); -+ -+VOID nicCmdEventQueryLinkSpeed(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); -+ -+VOID nicCmdEventQueryStatistics(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); -+ -+VOID nicCmdEventEnterRfTest(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); -+ -+VOID nicCmdEventLeaveRfTest(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); -+ -+VOID nicCmdEventQueryAddress(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); -+ -+VOID nicCmdEventQueryMcastAddr(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); -+ -+VOID nicCmdEventQueryEepromRead(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); -+ -+VOID nicCmdEventSetMediaStreamMode(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); -+ -+/* Statistics responder */ -+VOID nicCmdEventQueryXmitOk(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); -+ -+VOID nicCmdEventQueryRecvOk(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); -+ -+VOID nicCmdEventQueryXmitError(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); -+ -+VOID nicCmdEventQueryRecvError(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); -+ -+VOID nicCmdEventQueryRecvNoBuffer(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); -+ -+VOID nicCmdEventQueryRecvCrcError(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); -+ -+VOID nicCmdEventQueryRecvErrorAlignment(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); -+ -+VOID nicCmdEventQueryXmitOneCollision(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); -+ -+VOID nicCmdEventQueryXmitMoreCollisions(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); -+ -+VOID nicCmdEventQueryXmitMaxCollisions(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); -+ -+/* for timeout check */ -+VOID nicOidCmdTimeoutCommon(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo); -+ -+VOID nicCmdTimeoutCommon(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo); -+ -+VOID nicOidCmdEnterRFTestTimeout(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo); -+ -+#if CFG_SUPPORT_BUILD_DATE_CODE -+VOID nicCmdEventBuildDateCode(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); -+#endif -+ -+VOID nicCmdEventQueryStaStatistics(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); -+ -+#if CFG_AUTO_CHANNEL_SEL_SUPPORT -+/* 4 Auto Channel Selection */ -+VOID nicCmdEventQueryChannelLoad(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); -+ -+VOID nicCmdEventQueryLTESafeChn(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); -+#endif -+ -+#if CFG_SUPPORT_BATCH_SCAN -+VOID nicCmdEventBatchScanResult(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); -+#endif -+ -+VOID nicCmdEventGetBSSInfo(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif /* _NIC_CMD_EVENT_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic_init_cmd_event.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic_init_cmd_event.h -new file mode 100644 -index 000000000000..994c589190de ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic_init_cmd_event.h -@@ -0,0 +1,177 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/nic_init_cmd_event.h#1 -+*/ -+ -+/*! \file "nic_init_cmd_event.h" -+ \brief This file contains the declairation file of the WLAN initialization routines -+ for MediaTek Inc. 802.11 Wireless LAN Adapters. -+*/ -+ -+/* -+** Log: nic_init_cmd_event.h -+ * -+ * 09 26 2011 cp.wu -+ * [WCXRP00001011] [MT6628 Wi-Fi] Firmware Download Agent: make CRC validation as an optional feature -+ * add definition for disabling CRC32 validation (for MT6628 only) -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 03 12 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * add two option for ACK and ENCRYPTION for firmware download -+ * -+ * 03 01 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * add command/event definitions for initial states -+ * -+ * 02 10 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * implement host-side firmware download logic -+ * -+ * 02 08 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * prepare for implementing fw download logic -+ * -+*/ -+#ifndef _NIC_INIT_CMD_EVENT_H -+#define _NIC_INIT_CMD_EVENT_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+#include "gl_typedef.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+#define INIT_CMD_STATUS_SUCCESS 0 -+#define INIT_CMD_STATUS_REJECTED_INVALID_PARAMS 1 -+#define INIT_CMD_STATUS_REJECTED_CRC_ERROR 2 -+#define INIT_CMD_STATUS_REJECTED_DECRYPT_FAIL 3 -+#define INIT_CMD_STATUS_UNKNOWN 4 -+ -+#define EVENT_HDR_SIZE OFFSET_OF(WIFI_EVENT_T, aucBuffer[0]) -+ -+typedef enum _ENUM_INIT_CMD_ID { -+ INIT_CMD_ID_DOWNLOAD_BUF = 1, -+ INIT_CMD_ID_WIFI_START, -+ INIT_CMD_ID_ACCESS_REG, -+ INIT_CMD_ID_QUERY_PENDING_ERROR -+} ENUM_INIT_CMD_ID, *P_ENUM_INIT_CMD_ID; -+ -+typedef enum _ENUM_INIT_EVENT_ID { -+ INIT_EVENT_ID_CMD_RESULT = 1, -+ INIT_EVENT_ID_ACCESS_REG, -+ INIT_EVENT_ID_PENDING_ERROR -+} ENUM_INIT_EVENT_ID, *P_ENUM_INIT_EVENT_ID; -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+typedef UINT_8 CMD_STATUS; -+ -+/* commands */ -+typedef struct _INIT_WIFI_CMD_T { -+ UINT_8 ucCID; -+ UINT_8 ucSeqNum; -+ UINT_16 u2Reserved; -+ UINT_8 aucBuffer[0]; -+} INIT_WIFI_CMD_T, *P_INIT_WIFI_CMD_T; -+ -+typedef struct _INIT_HIF_TX_HEADER_T { -+ UINT_16 u2TxByteCount; -+ UINT_8 ucEtherTypeOffset; -+ UINT_8 ucCSflags; -+ INIT_WIFI_CMD_T rInitWifiCmd; -+} INIT_HIF_TX_HEADER_T, *P_INIT_HIF_TX_HEADER_T; -+ -+#define DOWNLOAD_BUF_ENCRYPTION_MODE BIT(0) -+#define DOWNLOAD_BUF_NO_CRC_CHECKING BIT(30) -+#define DOWNLOAD_BUF_ACK_OPTION BIT(31) -+typedef struct _INIT_CMD_DOWNLOAD_BUF { -+ UINT_32 u4Address; -+ UINT_32 u4Length; -+ UINT_32 u4CRC32; -+ UINT_32 u4DataMode; -+ UINT_8 aucBuffer[0]; -+} INIT_CMD_DOWNLOAD_BUF, *P_INIT_CMD_DOWNLOAD_BUF; -+ -+typedef struct _INIT_CMD_WIFI_START { -+ UINT_32 u4Override; -+ UINT_32 u4Address; -+} INIT_CMD_WIFI_START, *P_INIT_CMD_WIFI_START; -+ -+typedef struct _INIT_CMD_ACCESS_REG { -+ UINT_8 ucSetQuery; -+ UINT_8 aucReserved[3]; -+ UINT_32 u4Address; -+ UINT_32 u4Data; -+} INIT_CMD_ACCESS_REG, *P_INIT_CMD_ACCESS_REG; -+ -+/* Events */ -+typedef struct _INIT_WIFI_EVENT_T { -+ UINT_16 u2RxByteCount; -+ UINT_8 ucEID; -+ UINT_8 ucSeqNum; -+ UINT_8 aucBuffer[0]; -+} INIT_WIFI_EVENT_T, *P_INIT_WIFI_EVENT_T; -+ -+typedef struct _INIT_HIF_RX_HEADER_T { -+ INIT_WIFI_EVENT_T rInitWifiEvent; -+} INIT_HIF_RX_HEADER_T, *P_INIT_HIF_RX_HEADER_T; -+ -+typedef struct _INIT_EVENT_CMD_RESULT { -+ UINT_8 ucStatus; /* 0: success */ -+ /* 1: rejected by invalid param */ -+ /* 2: rejected by incorrect CRC */ -+ /* 3: rejected by decryption failure */ -+ /* 4: unknown CMD */ -+ UINT_8 aucReserved[3]; -+} INIT_EVENT_CMD_RESULT, *P_INIT_EVENT_CMD_RESULT, INIT_EVENT_PENDING_ERROR, *P_INIT_EVENT_PENDING_ERROR; -+ -+typedef struct _INIT_EVENT_ACCESS_REG { -+ UINT_32 u4Address; -+ UINT_32 u4Data; -+} INIT_EVENT_ACCESS_REG, *P_INIT_EVENT_ACCESS_REG; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif /* _NIC_INIT_CMD_EVENT_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/p2p_precomp.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/p2p_precomp.h -new file mode 100644 -index 000000000000..85af819f4e62 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/p2p_precomp.h -@@ -0,0 +1,201 @@ -+/* -+** Id: //Department/DaVinci/TRUNK/WiFi_P2P_Driver/include/p2p_precomp.h#1 -+*/ -+ -+/*! \file p2p_precomp.h -+ \brief Collection of most compiler flags for p2p driver are described here. -+ -+ In this file we collect all compiler flags and detail the p2p driver behavior if -+ enable/disable such switch or adjust numeric parameters. -+*/ -+ -+#ifndef _P2P_PRECOMP_H -+#define _P2P_PRECOMP_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "gl_os.h" /* Include "config.h" */ -+ -+#include "gl_p2p_os.h" -+ -+#include "debug.h" -+ -+#include "link.h" -+#include "queue.h" -+ -+/*------------------------------------------------------------------------------ -+ * .\include\mgmt -+ *------------------------------------------------------------------------------ -+ */ -+#include "wlan_typedef.h" -+ -+#include "mac.h" -+ -+/* Dependency: mac.h (MAC_ADDR_LEN) */ -+#include "wlan_def.h" -+ -+#include "roaming_fsm.h" -+ -+/*------------------------------------------------------------------------------ -+ * .\include\nic -+ *------------------------------------------------------------------------------ -+ */ -+/* Dependency: wlan_def.h (ENUM_NETWORK_TYPE_T) */ -+#include "cmd_buf.h" -+ -+/* Dependency: mac.h (MAC_ADDR_LEN) */ -+#include "nic_cmd_event.h" -+ -+/* Dependency: nic_cmd_event.h (P_EVENT_CONNECTION_STATUS) */ -+#include "nic.h" -+ -+#include "nic_init_cmd_event.h" -+ -+#include "hif_rx.h" -+#include "hif_tx.h" -+ -+#include "nic_tx.h" -+ -+/* Dependency: hif_rx.h (P_HIF_RX_HEADER_T) */ -+#include "nic_rx.h" -+ -+#include "que_mgt.h" -+ -+#if CFG_ENABLE_WIFI_DIRECT -+#include "p2p_typedef.h" -+#include "p2p_cmd_buf.h" -+#include "p2p_nic_cmd_event.h" -+#include "p2p_mac.h" -+#include "p2p_nic.h" -+#endif -+ -+/*------------------------------------------------------------------------------ -+ * .\include\mgmt -+ *------------------------------------------------------------------------------ -+ */ -+ -+#include "hem_mbox.h" -+ -+#include "scan.h" -+#include "bss.h" -+ -+#include "wlan_lib.h" -+#include "wlan_oid.h" -+#include "wlan_bow.h" -+ -+#include "wlan_p2p.h" -+ -+#include "hal.h" -+ -+#if defined(MT6620) -+#include "mt6620_reg.h" -+#endif -+ -+#include "rlm.h" -+#include "rlm_domain.h" -+#include "rlm_protection.h" -+#include "rlm_obss.h" -+#include "rate.h" -+ -+#include "aa_fsm.h" -+ -+#include "cnm_timer.h" -+ -+#if CFG_ENABLE_BT_OVER_WIFI -+#include "bow.h" -+#include "bow_fsm.h" -+#endif -+ -+#include "pwr_mgt.h" -+ -+#include "cnm.h" -+/* Dependency: aa_fsm.h (ENUM_AA_STATE_T), p2p_fsm.h (WPS_ATTRI_MAX_LEN_DEVICE_NAME) */ -+#include "cnm_mem.h" -+#include "cnm_scan.h" -+ -+#include "p2p_rlm_obss.h" -+#include "p2p_bss.h" -+#include "p2p.h" -+/* Dependency: cnm_timer.h (TIMER_T) */ -+#include "p2p_fsm.h" -+#include "p2p_scan.h" -+#include "p2p_state.h" -+#include "p2p_func.h" -+#include "p2p_rlm.h" -+#include "p2p_assoc.h" -+#include "p2p_ie.h" -+ -+#include "privacy.h" -+ -+#include "mib.h" -+ -+#include "auth.h" -+#include "assoc.h" -+ -+#include "ais_fsm.h" -+ -+#include "adapter.h" -+ -+#include "que_mgt.h" -+#include "rftest.h" -+ -+#if CFG_RSN_MIGRATION -+#include "rsn.h" -+#include "sec_fsm.h" -+#endif -+ -+#if CFG_SUPPORT_WAPI -+#include "wapi.h" -+#endif -+ -+/*------------------------------------------------------------------------------ -+ * NVRAM structure -+ *------------------------------------------------------------------------------ -+ */ -+#include "CFG_Wifi_File.h" -+ -+#include "gl_p2p_kal.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif /*_P2P_PRECOMP_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/p2p_typedef.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/p2p_typedef.h -new file mode 100644 -index 000000000000..a02d391d3643 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/p2p_typedef.h -@@ -0,0 +1,165 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/p2p_typedef.h#1 -+*/ -+ -+/*! \file p2p_typedef.h -+ \brief Declaration of data type and return values of internal protocol stack. -+ -+ In this file we declare the data type and return values which will be exported -+ to all MGMT Protocol Stack. -+*/ -+ -+#ifndef _P2P_TYPEDEF_H -+#define _P2P_TYPEDEF_H -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/* -+* type definition of pointer to p2p structure -+*/ -+/* typedef struct _GL_P2P_INFO_T GL_P2P_INFO_T, *P_GL_P2P_INFO_T; */ -+typedef struct _P2P_INFO_T P2P_INFO_T, *P_P2P_INFO_T; -+ -+typedef struct _P2P_FSM_INFO_T P2P_FSM_INFO_T, *P_P2P_FSM_INFO_T; -+ -+typedef struct _P2P_CONNECTION_SETTINGS_T P2P_CONNECTION_SETTINGS_T, *P_P2P_CONNECTION_SETTINGS_T; -+ -+/* Type definition for function pointer to p2p function*/ -+typedef BOOLEAN(*P2P_LAUNCH) (P_GLUE_INFO_T prGlueInfo); -+ -+typedef BOOLEAN(*P2P_REMOVE) (P_GLUE_INFO_T prGlueInfo, BOOLEAN fgIsWlanLaunched); -+ -+typedef BOOLEAN(*KAL_P2P_GET_CIPHER) (IN P_GLUE_INFO_T prGlueInfo); -+ -+typedef BOOLEAN(*KAL_P2P_GET_TKIP_CIPHER) (IN P_GLUE_INFO_T prGlueInfo); -+ -+typedef BOOLEAN(*KAL_P2P_GET_CCMP_CIPHER) (IN P_GLUE_INFO_T prGlueInfo); -+ -+typedef BOOLEAN(*KAL_P2P_GET_WSC_MODE) (IN P_GLUE_INFO_T prGlueInfo); -+ -+typedef struct net_device *(*KAL_P2P_GET_DEV_HDLR) (P_GLUE_INFO_T prGlueInfo); -+ -+typedef VOID(*KAL_P2P_SET_MULTICAST_WORK_ITEM) (P_GLUE_INFO_T prGlueInfo); -+ -+typedef VOID(*P2P_NET_REGISTER) (P_GLUE_INFO_T prGlueInfo); -+ -+typedef VOID(*P2P_NET_UNREGISTER) (P_GLUE_INFO_T prGlueInfo); -+ -+typedef VOID(*KAL_P2P_UPDATE_ASSOC_INFO) (IN P_GLUE_INFO_T prGlueInfo, -+ IN PUINT_8 pucFrameBody, -+ IN UINT_32 u4FrameBodyLen, IN BOOLEAN fgReassocRequest); -+ -+typedef BOOLEAN(*P2P_VALIDATE_AUTH) (IN P_ADAPTER_T prAdapter, -+ IN P_SW_RFB_T prSwRfb, IN PP_STA_RECORD_T pprStaRec, OUT PUINT_16 pu2StatusCode); -+ -+typedef BOOLEAN(*P2P_VALIDATE_ASSOC_REQ) (IN P_ADAPTER_T prAdapter, -+ IN P_SW_RFB_T prSwRfb, OUT PUINT_16 pu4ControlFlags); -+ -+typedef VOID(*P2P_RUN_EVENT_AAA_TX_FAIL) (IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec); -+ -+typedef BOOLEAN(*P2P_PARSE_CHECK_FOR_P2P_INFO_ELEM) (IN P_ADAPTER_T prAdapter, -+ IN PUINT_8 pucBuf, OUT PUINT_8 pucOuiType); -+ -+typedef WLAN_STATUS(*P2P_RUN_EVENT_AAA_COMPLETE) (IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec); -+ -+typedef VOID(*P2P_PROCESS_EVENT_UPDATE_NOA_PARAM) (IN P_ADAPTER_T prAdapter, -+ UINT_8 ucNetTypeIndex, -+ P_EVENT_UPDATE_NOA_PARAMS_T prEventUpdateNoaParam); -+ -+typedef VOID(*SCAN_P2P_PROCESS_BEACON_AND_PROBE_RESP) (IN P_ADAPTER_T prAdapter, -+ IN P_SW_RFB_T prSwRfb, -+ IN P_WLAN_STATUS prStatus, -+ IN P_BSS_DESC_T prBssDesc, -+ IN P_WLAN_BEACON_FRAME_T prWlanBeaconFrame); -+ -+typedef VOID(*P2P_RX_PUBLIC_ACTION_FRAME) (P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); -+ -+typedef VOID(*RLM_RSP_GENERATE_OBSS_SCAN_IE) (P_ADAPTER_T prAdapter, P_MSDU_INFO_T prMsduInfo); -+ -+typedef VOID(*RLM_UPDATE_BW_BY_CH_LIST_FOR_AP) (P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo); -+ -+typedef VOID(*RLM_PROCESS_PUBLIC_ACTION) (P_ADAPTER_T prAdapter, P_SW_RFB_T prSwRfb); -+ -+typedef VOID(*RLM_PROCESS_HT_ACTION) (P_ADAPTER_T prAdapter, P_SW_RFB_T prSwRfb); -+ -+typedef VOID(*RLM_UPDATE_PARAMS_FOR_AP) (P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo, BOOLEAN fgUpdateBeacon); -+ -+typedef VOID(*RLM_HANDLE_OBSS_STATUS_EVENT_PKT) (P_ADAPTER_T prAdapter, P_EVENT_AP_OBSS_STATUS_T prObssStatus); -+ -+typedef BOOLEAN(*P2P_FUNC_VALIDATE_PROBE_REQ) (IN P_ADAPTER_T prAdapter, -+ IN P_SW_RFB_T prSwRfb, OUT PUINT_32 pu4ControlFlags); -+ -+typedef VOID(*RLM_BSS_INIT_FOR_AP) (P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo); -+ -+typedef UINT_32(*P2P_GET_PROB_RSP_IE_TABLE_SIZE) (VOID); -+ -+typedef PUINT_8(*P2P_BUILD_REASSOC_REQ_FRAME_COMMON_IES) (IN P_ADAPTER_T prAdapter, -+ IN P_MSDU_INFO_T prMsduInfo, IN PUINT_8 pucBuffer); -+ -+typedef VOID(*P2P_FUNC_DISCONNECT) (IN P_ADAPTER_T prAdapter, -+ IN P_STA_RECORD_T prStaRec, IN BOOLEAN fgSendDeauth, IN UINT_16 u2ReasonCode); -+ -+typedef VOID(*P2P_FSM_RUN_EVENT_RX_DEAUTH) (IN P_ADAPTER_T prAdapter, -+ IN P_STA_RECORD_T prStaRec, IN P_SW_RFB_T prSwRfb); -+ -+typedef VOID(*P2P_FSM_RUN_EVENT_RX_DISASSOC) (IN P_ADAPTER_T prAdapter, -+ IN P_STA_RECORD_T prStaRec, IN P_SW_RFB_T prSwRfb); -+ -+typedef BOOLEAN(*P2P_FUN_IS_AP_MODE) (IN P_P2P_FSM_INFO_T prP2pFsmInfo); -+ -+typedef VOID(*P2P_FSM_RUN_EVENT_BEACON_TIMEOUT) (IN P_ADAPTER_T prAdapter); -+ -+typedef VOID(*P2P_FUNC_STORE_ASSOC_RSP_IE_BUFFER) (IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); -+ -+typedef VOID(*P2P_GENERATE_P2P_IE) (IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); -+ -+typedef UINT_32(*P2P_CALCULATE_P2P_IE_LEN) (IN P_ADAPTER_T prAdapter, -+ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec); -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+#endif /*CFG_ENABLE_WIFI_DIRECT */ -+ -+#endif /* _P2P_TYPEDEF_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/precomp.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/precomp.h -new file mode 100644 -index 000000000000..1b7e7ede66e1 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/precomp.h -@@ -0,0 +1,388 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/precomp.h#2 -+*/ -+ -+/*! \file precomp.h -+ \brief Collection of most compiler flags are described here. -+ -+ In this file we collect all compiler flags and detail the driver behavior if -+ enable/disable such switch or adjust numeric parameters. -+*/ -+ -+/* -+** Log: precomp.h -+ * -+ * 07 17 2012 yuche.tsai -+ * NULL -+ * Compile no error before trial run. -+ * -+ * 01 05 2012 tsaiyuan.hsu -+ * [WCXRP00001157] [MT6620 Wi-Fi][FW][DRV] add timing measurement support for 802.11v -+ * add timing measurement support for 802.11v. -+ * -+ * 08 15 2011 cp.wu -+ * [WCXRP00000851] [MT6628 Wi-Fi][Driver] Add HIFSYS related definition to driver source tree -+ * add MT6628-specific definitions. -+ * -+ * 04 18 2011 terry.wu -+ * [WCXRP00000660] [MT6620 Wi-Fi][Driver] Remove flag CFG_WIFI_DIRECT_MOVED -+ * Remove flag CFG_WIFI_DIRECT_MOVED. -+ * -+ * 03 15 2011 eddie.chen -+ * [WCXRP00000554] [MT6620 Wi-Fi][DRV] Add sw control debug counter -+ * Add sw debug counter for QM. -+ * -+ * 01 27 2011 tsaiyuan.hsu -+ * [WCXRP00000392] [MT6620 Wi-Fi][Driver] Add Roaming Support -+ * add roaming fsm -+ * 1. not support 11r, only use strength of signal to determine roaming. -+ * 2. not enable CFG_SUPPORT_ROAMING until completion of full test. -+ * 3. in 6620, adopt work-around to avoid sign extension problem of cck of hw -+ * 4. assume that change of link quality in smooth way. -+ * -+ * 12 13 2010 cp.wu -+ * [WCXRP00000260] [MT6620 Wi-Fi][Driver][Firmware] Create V1.1 branch for both firmware and driver -+ * create branch for Wi-Fi driver v1.1 -+ * -+ * 10 07 2010 cp.wu -+ * [WCXRP00000083] [MT5931][Driver][FW] Add necessary logic for MT5931 first connection -+ * add firmware download for MT5931. -+ * -+ * 10 05 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check -+ * 1) add NVRAM access API -+ * 2) fake scanning result when NVRAM doesn't exist and/or version mismatch. (off by compiler option) -+ * 3) add OID implementation for NVRAM read/write service -+ * -+ * 09 21 2010 kevin.huang -+ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning -+ * Isolate P2P related function for Hardware Software Bundle -+ * -+ * 09 14 2010 chinghwa.yu -+ * NULL -+ * Fix BOW_FSM_INFO_T dependence. -+ * -+ * 09 03 2010 kevin.huang -+ * NULL -+ * Refine #include sequence and solve recursive/nested #include issue -+ * -+ * 07 20 2010 wh.su -+ * -+ * adding the wapi code. -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 07 08 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Check draft RLM code for HT cap -+ * -+ * 07 01 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Modify CNM message handler for new flow -+ * -+ * 06 28 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * 1st draft code for RLM module -+ * -+ * 06 19 2010 wh.su -+ * [WPD00003840][MT6620 5931] Security migration -+ * consdier the concurrent network setting. -+ * -+ * 06 18 2010 wh.su -+ * [WPD00003840][MT6620 5931] Security migration -+ * migration the security related function from firmware. -+ * -+ * 06 18 2010 wh.su -+ * [WPD00003840][MT6620 5931] Security migration -+ * migration from MT6620 firmware. -+ * -+ * 06 08 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add hem_mbox.c and cnm_mem.h (but disabled some feature) for further migration -+ * -+ * 06 07 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * merge cnm_scan.h and hem_mbox.h -+ * -+ * 06 07 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * merge wifi_var.h, precomp.h, cnm_timer.h (data type only) -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 05 17 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * 1) add timeout handler mechanism for pending command packets -+ * 2) add p2p add/removal key -+ * -+ * 04 13 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * add framework for BT-over-Wi-Fi support. -+ * * * * * * * * * * * 1) prPendingCmdInfo is replaced by queue for multiple handler capability -+ * * * * * * * * * * * 2) command sequence number is now increased atomically -+ * * * * * * * * * * * 3) private data could be hold and taken use for other purpose -+ * -+ * 03 16 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * build up basic data structure and definitions to support BT-over-WiFi -+ * -+ * 02 08 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * prepare for implementing fw download logic -+ * -+ * 01 27 2010 wh.su -+ * [WPD00003816][MT6620 Wi-Fi] Adding the security support -+ * . -+** \main\maintrunk.MT6620WiFiDriver_Prj\9 2009-12-08 11:30:58 GMT mtk02752 -+** add rftest.h for implementing RF test mode in driver land -+** \main\maintrunk.MT6620WiFiDriver_Prj\8 2009-11-23 22:02:00 GMT mtk02468 -+** Added que_mgt.h -+** \main\maintrunk.MT6620WiFiDriver_Prj\7 2009-10-13 21:58:36 GMT mtk01084 -+** update for new macro define -+** \main\maintrunk.MT6620WiFiDriver_Prj\6 2009-04-21 09:40:11 GMT mtk01461 -+** Add nic_cmd_event.h -+** \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-04-17 20:00:26 GMT mtk01461 -+** Add cmd_buf.h -+** \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-03-19 18:32:44 GMT mtk01084 -+** update for basic power management functions -+** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-03-16 09:08:25 GMT mtk01461 -+** Update TX PATH API -+** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 20:11:38 GMT mtk01426 -+** Init for develop -+** -+*/ -+ -+#ifndef _PRECOMP_H -+#define _PRECOMP_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "gl_os.h" /* Include "config.h" */ -+ -+#if CFG_ENABLE_WIFI_DIRECT -+#include "gl_p2p_os.h" -+#endif -+ -+#include "debug.h" -+ -+#include "link.h" -+#include "queue.h" -+ -+/*------------------------------------------------------------------------------ -+ * .\include\mgmt -+ *------------------------------------------------------------------------------ -+ */ -+#include "wlan_typedef.h" -+ -+#include "mac.h" -+ -+/* Dependency: mac.h (MAC_ADDR_LEN) */ -+#include "wlan_def.h" -+ -+#if CFG_SUPPORT_SWCR -+#include "swcr.h" -+#endif -+ -+/*------------------------------------------------------------------------------ -+ * .\include\nic -+ *------------------------------------------------------------------------------ -+ */ -+/* Dependency: wlan_def.h (ENUM_NETWORK_TYPE_T) */ -+#include "cmd_buf.h" -+ -+/* Dependency: mac.h (MAC_ADDR_LEN) */ -+#include "nic_cmd_event.h" -+ -+/* Dependency: nic_cmd_event.h (P_EVENT_CONNECTION_STATUS) */ -+#include "nic.h" -+ -+#include "nic_init_cmd_event.h" -+ -+#include "hif_rx.h" -+#include "hif_tx.h" -+ -+#include "nic_tx.h" -+ -+/* Dependency: hif_rx.h (P_HIF_RX_HEADER_T) */ -+#include "nic_rx.h" -+ -+#include "que_mgt.h" -+ -+#if CFG_ENABLE_WIFI_DIRECT -+#include "p2p_typedef.h" -+#include "p2p_cmd_buf.h" -+#include "p2p_nic_cmd_event.h" -+#include "p2p_mac.h" -+#include "p2p_nic.h" -+#endif -+ -+/*------------------------------------------------------------------------------ -+ * .\include\mgmt -+ *------------------------------------------------------------------------------ -+ */ -+ -+#include "hem_mbox.h" -+ -+#include "scan.h" -+#include "bss.h" -+ -+#include "wlan_lib.h" -+#include "wlan_oid.h" -+#include "wlan_bow.h" -+ -+#if CFG_ENABLE_WIFI_DIRECT -+#include "wlan_p2p.h" -+#endif -+ -+#include "hal.h" -+ -+#if defined(MT6620) -+#include "mt6620_reg.h" -+#elif defined(MT6628) -+/* #include "mt6628_reg.h" */ -+#include "mtreg.h" -+#endif -+ -+#include "rlm.h" -+#include "rlm_domain.h" -+#include "rlm_protection.h" -+#include "rlm_obss.h" -+#include "rate.h" -+#if CFG_SUPPORT_802_11V -+#include "wnm.h" -+#endif -+ -+#include "aa_fsm.h" -+ -+#include "cnm_timer.h" -+ -+#if CFG_ENABLE_BT_OVER_WIFI -+#include "bow.h" -+#include "bow_fsm.h" -+#endif -+ -+#include "pwr_mgt.h" -+ -+#if (CFG_SUPPORT_STATISTICS == 1) -+#include "stats.h" -+#endif /* CFG_SUPPORT_STATISTICS */ -+ -+#include "cnm.h" -+/* Dependency: aa_fsm.h (ENUM_AA_STATE_T), p2p_fsm.h (WPS_ATTRI_MAX_LEN_DEVICE_NAME) */ -+#include "cnm_mem.h" -+#include "cnm_scan.h" -+ -+#if CFG_ENABLE_WIFI_DIRECT -+#include "p2p_rlm_obss.h" -+#include "p2p_bss.h" -+#include "p2p.h" -+#include "p2p_fsm.h" -+#include "p2p_scan.h" -+#include "p2p_state.h" -+#include "p2p_func.h" -+#include "p2p_rlm.h" -+#include "p2p_assoc.h" -+#include "p2p_ie.h" -+#endif -+ -+#include "privacy.h" -+ -+#include "mib.h" -+ -+#include "auth.h" -+#include "assoc.h" -+ -+#if CFG_SUPPORT_ROAMING -+#include "roaming_fsm.h" -+#endif /* CFG_SUPPORT_ROAMING */ -+ -+#include "ais_fsm.h" -+ -+#include "adapter.h" -+ -+#include "que_mgt.h" -+#include "rftest.h" -+ -+#if CFG_RSN_MIGRATION -+#include "rsn.h" -+#include "sec_fsm.h" -+#endif -+ -+#if CFG_SUPPORT_WAPI -+#include "wapi.h" -+#endif -+ -+/*------------------------------------------------------------------------------ -+ * NVRAM structure -+ *------------------------------------------------------------------------------ -+ */ -+#include "CFG_Wifi_File.h" -+ -+#if CFG_ENABLE_WIFI_DIRECT -+#include "gl_p2p_kal.h" -+#endif -+ -+typedef int (*set_p2p_mode) (struct net_device *netdev, PARAM_CUSTOM_P2P_SET_STRUCT_T p2pmode); -+typedef void (*set_dbg_level) (unsigned char modules[DBG_MODULE_NUM]); -+ -+extern void wlanRegisterNotifier(void); -+extern void wlanUnregisterNotifier(void); -+extern void register_set_p2p_mode_handler(set_p2p_mode handler); -+extern void register_set_dbg_level_handler(set_dbg_level handler); -+ -+#if CFG_TC1_FEATURE -+#define NIC_INF_NAME_IN_AP_MODE "legacy%d" -+extern volatile int wlan_if_changed; -+#endif -+extern BOOLEAN fgIsResetting; -+ -+extern UINT_8 g_aucBufIpAddr[32]; -+extern UINT_8 aucDebugModule[]; -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif /* _PRECOMP_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/pwr_mgt.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/pwr_mgt.h -new file mode 100644 -index 000000000000..40f52dcc9d68 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/pwr_mgt.h -@@ -0,0 +1,141 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/pwr_mgt.h#1 -+*/ -+ -+/*! \file "pwr_mgt.h" -+ \brief In this file we define the STATE and EVENT for Power Management FSM. -+ -+ The SCAN FSM is responsible for performing SCAN behavior when the Arbiter enter -+ ARB_STATE_SCAN. The STATE and EVENT for SCAN FSM are defined here with detail -+ description. -+*/ -+ -+/* -+** Log: pwr_mgt.h -+ * -+ * 07 09 2010 george.huang -+ * -+ * [WPD00001556] Migrate PM variables from FW to driver: for composing QoS Info -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 04 20 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * don't need SPIN_LOCK_PWR_CTRL anymore, it will raise IRQL -+ * and cause SdBusSubmitRequest running at DISPATCH_LEVEL as well. -+ -+ * -+ * 03 25 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * firmware download load address & start address are now configured from config.h -+ * * * due to the different configurations on FPGA and ASIC -+** \main\maintrunk.MT6620WiFiDriver_Prj\7 2009-12-10 16:39:10 GMT mtk02752 -+** disable PM macros temporally -+** \main\maintrunk.MT6620WiFiDriver_Prj\6 2009-10-29 19:48:37 GMT mtk01084 -+** temp remove power management macro -+** \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-04-08 16:51:11 GMT mtk01084 -+** update for power management control macro -+** \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-04-03 14:59:58 GMT mtk01426 -+** Add #if CFG_HIF_LOOPBACK_PRETEST -+** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-03-23 16:53:10 GMT mtk01084 -+** modify ACQUIRE_POWER_CONTROL_FROM_PM() and RECLAIM_POWER_CONTROL_TO_PM() macro -+** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-19 18:32:47 GMT mtk01084 -+** update for basic power management functions -+** \main\maintrunk.MT6620WiFiDriver_Prj\1 2009-03-19 15:05:20 GMT mtk01084 -+** Initial version -+** -+*/ -+ -+#ifndef _PWR_MGT_H -+#define _PWR_MGT_H -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+#define PM_UAPSD_AC0 (BIT(0)) -+#define PM_UAPSD_AC1 (BIT(1)) -+#define PM_UAPSD_AC2 (BIT(2)) -+#define PM_UAPSD_AC3 (BIT(3)) -+ -+#define PM_UAPSD_ALL (PM_UAPSD_AC0 | PM_UAPSD_AC1 | PM_UAPSD_AC2 | PM_UAPSD_AC3) -+#define PM_UAPSD_NONE 0 -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+typedef struct _PM_PROFILE_SETUP_INFO_T { -+ /* Profile setup */ -+ UINT_8 ucBmpDeliveryAC; /* 0: AC_BE, 1: AC_BK, 2: AC_VI, 3: AC_VO */ -+ UINT_8 ucBmpTriggerAC; /* 0: AC_BE, 1: AC_BK, 2: AC_VI, 3: AC_VO */ -+ -+ UINT_8 ucUapsdSp; /* Number of triggered packets in UAPSD */ -+ -+} PM_PROFILE_SETUP_INFO_T, *P_PM_PROFILE_SETUP_INFO_T; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+#if !CFG_ENABLE_FULL_PM -+#define ACQUIRE_POWER_CONTROL_FROM_PM(_prAdapter) -+#define RECLAIM_POWER_CONTROL_TO_PM(_prAdapter, _fgEnableGINT_in_IST) -+#else -+#define ACQUIRE_POWER_CONTROL_FROM_PM(_prAdapter) \ -+ { \ -+ if (_prAdapter->fgIsFwOwn) { \ -+ nicpmSetDriverOwn(_prAdapter); \ -+ } \ -+ /* Increase Block to Enter Low Power Semaphore count */ \ -+ GLUE_INC_REF_CNT(_prAdapter->u4PwrCtrlBlockCnt); \ -+ } -+ -+#define RECLAIM_POWER_CONTROL_TO_PM(_prAdapter, _fgEnableGINT_in_IST) \ -+ { \ -+ ASSERT(_prAdapter->u4PwrCtrlBlockCnt != 0); \ -+ /* Decrease Block to Enter Low Power Semaphore count */ \ -+ GLUE_DEC_REF_CNT(_prAdapter->u4PwrCtrlBlockCnt); \ -+ if (_prAdapter->fgWiFiInSleepyState && (_prAdapter->u4PwrCtrlBlockCnt == 0)) { \ -+ nicpmSetFWOwn(_prAdapter, _fgEnableGINT_in_IST); \ -+ } \ -+ } -+#endif -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif /* _PWR_MGT_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/queue.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/queue.h -new file mode 100644 -index 000000000000..a9e74b58a8c9 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/queue.h -@@ -0,0 +1,195 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/queue.h#1 -+*/ -+ -+/*! \file queue.h -+ \brief Definition for singly queue operations. -+ -+ In this file we define the singly queue data structure and its -+ queue operation MACROs. -+*/ -+ -+/* -+** Log: queue.h -+ * -+ * 07 16 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration. -+ * bugfix for SCN migration -+ * 1) modify QUEUE_CONCATENATE_QUEUES() so it could be used to concatence with an empty queue -+ * 2) before AIS issues scan request, network(BSS) needs to be activated first -+ * 3) only invoke COPY_SSID when using specified SSID for scan -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 04 20 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * . -+** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 20:11:46 GMT mtk01426 -+** Init for develop -+** -+*/ -+ -+#ifndef _QUEUE_H -+#define _QUEUE_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "gl_typedef.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+/* Singly Queue Structures - Entry Part */ -+typedef struct _QUE_ENTRY_T { -+ struct _QUE_ENTRY_T *prNext; -+ struct _QUE_ENTRY_T *prPrev; /* For Rx buffer reordering used only */ -+} QUE_ENTRY_T, *P_QUE_ENTRY_T; -+ -+/* Singly Queue Structures - Queue Part */ -+typedef struct _QUE_T { -+ P_QUE_ENTRY_T prHead; -+ P_QUE_ENTRY_T prTail; -+ UINT_32 u4NumElem; -+} QUE_T, *P_QUE_T; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/* -+ * To resolve compiler warning of address check -Waddress -+ * Redefine a ASSERT dedicate for queue operation -+ */ -+#if DBG -+#define QUE_ASSERT ASSERT -+#else -+#define QUE_ASSERT(_exp) -+#endif -+ -+#define QUEUE_INITIALIZE(prQueue) \ -+ { \ -+ (prQueue)->prHead = (P_QUE_ENTRY_T)NULL; \ -+ (prQueue)->prTail = (P_QUE_ENTRY_T)NULL; \ -+ (prQueue)->u4NumElem = 0; \ -+ } -+ -+#define QUEUE_IS_EMPTY(prQueue) (((P_QUE_T)(prQueue))->prHead == (P_QUE_ENTRY_T)NULL) -+ -+#define QUEUE_IS_NOT_EMPTY(prQueue) ((prQueue)->u4NumElem > 0) -+ -+#define QUEUE_GET_HEAD(prQueue) ((prQueue)->prHead) -+ -+#define QUEUE_GET_TAIL(prQueue) ((prQueue)->prTail) -+ -+#define QUEUE_GET_NEXT_ENTRY(prQueueEntry) ((prQueueEntry)->prNext) -+ -+#define QUEUE_INSERT_HEAD(prQueue, prQueueEntry) \ -+ { \ -+ QUE_ASSERT(prQueue); \ -+ QUE_ASSERT(prQueueEntry); \ -+ (prQueueEntry)->prNext = (prQueue)->prHead; \ -+ (prQueue)->prHead = (prQueueEntry); \ -+ if ((prQueue)->prTail == (P_QUE_ENTRY_T)NULL) { \ -+ (prQueue)->prTail = (prQueueEntry); \ -+ } \ -+ ((prQueue)->u4NumElem)++; \ -+ } -+ -+#define QUEUE_INSERT_TAIL(prQueue, prQueueEntry) \ -+ { \ -+ QUE_ASSERT(prQueue); \ -+ QUE_ASSERT(prQueueEntry); \ -+ (prQueueEntry)->prNext = (P_QUE_ENTRY_T)NULL; \ -+ if ((prQueue)->prTail) { \ -+ ((prQueue)->prTail)->prNext = (prQueueEntry); \ -+ } else { \ -+ (prQueue)->prHead = (prQueueEntry); \ -+ } \ -+ (prQueue)->prTail = (prQueueEntry); \ -+ ((prQueue)->u4NumElem)++; \ -+ } -+ -+/* NOTE: We assume the queue entry located at the beginning of "prQueueEntry Type", -+ * so that we can cast the queue entry to other data type without doubts. -+ * And this macro also decrease the total entry count at the same time. -+ */ -+#define QUEUE_REMOVE_HEAD(prQueue, prQueueEntry, _P_TYPE) \ -+ { \ -+ QUE_ASSERT(prQueue); \ -+ prQueueEntry = (_P_TYPE)((prQueue)->prHead); \ -+ if (prQueueEntry) { \ -+ (prQueue)->prHead = ((P_QUE_ENTRY_T)(prQueueEntry))->prNext; \ -+ if ((prQueue)->prHead == (P_QUE_ENTRY_T)NULL) { \ -+ (prQueue)->prTail = (P_QUE_ENTRY_T)NULL; \ -+ } \ -+ ((P_QUE_ENTRY_T)(prQueueEntry))->prNext = (P_QUE_ENTRY_T)NULL; \ -+ ((prQueue)->u4NumElem)--; \ -+ } \ -+ } -+ -+#define QUEUE_MOVE_ALL(prDestQueue, prSrcQueue) \ -+ { \ -+ QUE_ASSERT(prDestQueue); \ -+ QUE_ASSERT(prSrcQueue); \ -+ *(P_QUE_T)prDestQueue = *(P_QUE_T)prSrcQueue; \ -+ QUEUE_INITIALIZE(prSrcQueue); \ -+ } -+ -+#define QUEUE_CONCATENATE_QUEUES(prDestQueue, prSrcQueue) \ -+ { \ -+ QUE_ASSERT(prDestQueue); \ -+ QUE_ASSERT(prSrcQueue); \ -+ if (prSrcQueue->u4NumElem > 0) { \ -+ if ((prDestQueue)->prTail) { \ -+ ((prDestQueue)->prTail)->prNext = (prSrcQueue)->prHead; \ -+ } else { \ -+ (prDestQueue)->prHead = (prSrcQueue)->prHead; \ -+ } \ -+ (prDestQueue)->prTail = (prSrcQueue)->prTail; \ -+ ((prDestQueue)->u4NumElem) += ((prSrcQueue)->u4NumElem); \ -+ QUEUE_INITIALIZE(prSrcQueue); \ -+ } \ -+ } -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif /* _QUEUE_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/rftest.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/rftest.h -new file mode 100644 -index 000000000000..4489e5601302 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/rftest.h -@@ -0,0 +1,294 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/rftest.h#1 -+*/ -+ -+/*! \file "rftest.h" -+ \brief definitions for RF Productino test -+ -+*/ -+ -+/* -+** Log: rftest.h -+ * -+ * 12 20 2011 cp.wu -+ * [WCXRP00001144] [MT6620 Wi-Fi][Driver][Firmware] Add RF_FUNC_ID for exposing device and related version information -+ * add driver implementations for RF_AT_FUNCID_FW_INFO & RF_AT_FUNCID_DRV_INFO -+ * to expose version information -+ * -+ * 08 04 2010 cp.wu -+ * NULL -+ * add an extra parameter to rftestQueryATInfo 'cause it's necessary to pass u4FuncData for query request. -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 04 14 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * information buffer for query oid/ioctl is now buffered in prCmdInfo -+ * * * * instead of glue-layer variable to improve multiple oid/ioctl capability -+ * -+ * 12 30 2009 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) According to CMD/EVENT documentation v0.8, -+ * * * * * * * OID_CUSTOM_TEST_RX_STATUS & OID_CUSTOM_TEST_TX_STATUS is no longer used, -+ * * * * * * * and result is retrieved by get ATInfo instead -+ * * * * * * * 2) add 4 counter for recording aggregation statistics -+** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-12-08 17:35:11 GMT mtk02752 -+** * comment out RF test which is not supported on MT6620 -+** + API decalre for rftest -+** \main\maintrunk.MT6620WiFiDriver_Prj\1 2009-12-08 11:29:07 GMT mtk02752 -+** definitions for RF test mode -+** -+*/ -+#ifndef _RFTEST_H -+#define _RFTEST_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+/* Table Version */ -+#define RF_AUTO_TEST_FUNCTION_TABLE_VERSION 0x01000001 -+ -+/* Power */ -+#define RF_AT_PARAM_POWER_MASK BITS(0, 7) -+#define RF_AT_PARAM_POWER_MAX RF_AT_PARAM_POWER_MASK -+ -+/* Rate */ -+#define RF_AT_PARAM_RATE_MCS_MASK BIT(31) -+#define RF_AT_PARAM_RATE_MASK BITS(0, 7) -+#define RF_AT_PARAM_RATE_CCK_MAX 3 -+#define RF_AT_PARAM_RATE_1M 0 -+#define RF_AT_PARAM_RATE_2M 1 -+#define RF_AT_PARAM_RATE_5_5M 2 -+#define RF_AT_PARAM_RATE_11M 3 -+#define RF_AT_PARAM_RATE_6M 4 -+#define RF_AT_PARAM_RATE_9M 5 -+#define RF_AT_PARAM_RATE_12M 6 -+#define RF_AT_PARAM_RATE_18M 7 -+#define RF_AT_PARAM_RATE_24M 8 -+#define RF_AT_PARAM_RATE_36M 9 -+#define RF_AT_PARAM_RATE_48M 10 -+#define RF_AT_PARAM_RATE_54M 11 -+ -+/* Antenna */ -+#define RF_AT_PARAM_ANTENNA_ID_MASK BITS(0, 7) -+#define RF_AT_PARAM_ANTENNA_ID_MAX 1 -+ -+/* Packet Length */ -+#define RF_AT_PARAM_TX_80211HDR_BYTE_MAX (32) -+#define RF_AT_PARAM_TX_80211PAYLOAD_BYTE_MAX (2048) -+ -+#define RF_AT_PARAM_TX_PKTLEN_BYTE_DEFAULT 1024 -+#define RF_AT_PARAM_TX_PKTLEN_BYTE_MAX \ -+ ((UINT_16)(RF_AT_PARAM_TX_80211HDR_BYTE_MAX + RF_AT_PARAM_TX_80211PAYLOAD_BYTE_MAX)) -+ -+/* Packet Count */ -+#define RF_AT_PARAM_TX_PKTCNT_DEFAULT 1000 -+#define RF_AT_PARAM_TX_PKTCNT_UNLIMITED 0 -+ -+/* Packet Interval */ -+#define RF_AT_PARAM_TX_PKT_INTERVAL_US_DEFAULT 50 -+ -+/* ALC */ -+#define RF_AT_PARAM_ALC_DISABLE 0 -+#define RF_AT_PARAM_ALC_ENABLE 1 -+ -+/* TXOP */ -+#define RF_AT_PARAM_TXOP_DEFAULT 0 -+#define RF_AT_PARAM_TXOPQUE_QMASK BITS(16, 31) -+#define RF_AT_PARAM_TXOPQUE_TMASK BITS(0, 15) -+#define RF_AT_PARAM_TXOPQUE_AC0 (0<<16) -+#define RF_AT_PARAM_TXOPQUE_AC1 (1<<16) -+#define RF_AT_PARAM_TXOPQUE_AC2 (2<<16) -+#define RF_AT_PARAM_TXOPQUE_AC3 (3<<16) -+#define RF_AT_PARAM_TXOPQUE_AC4 (4<<16) -+#define RF_AT_PARAM_TXOPQUE_QOFFSET 16 -+ -+/* Retry Limit */ -+#define RF_AT_PARAM_TX_RETRY_DEFAULT 0 -+#define RF_AT_PARAM_TX_RETRY_MAX 6 -+ -+/* QoS Queue */ -+#define RF_AT_PARAM_QOSQUE_AC0 0 -+#define RF_AT_PARAM_QOSQUE_AC1 1 -+#define RF_AT_PARAM_QOSQUE_AC2 2 -+#define RF_AT_PARAM_QOSQUE_AC3 3 -+#define RF_AT_PARAM_QOSQUE_AC4 4 -+#define RF_AT_PARAM_QOSQUE_DEFAULT RF_AT_PARAM_QOSQUE_AC0 -+ -+/* Bandwidth */ -+#define RF_AT_PARAM_BANDWIDTH_20MHZ 0 -+#define RF_AT_PARAM_BANDWIDTH_40MHZ 1 -+#define RF_AT_PARAM_BANDWIDTH_U20_IN_40MHZ 2 -+#define RF_AT_PARAM_BANDWIDTH_D20_IN_40MHZ 3 -+#define RF_AT_PARAM_BANDWIDTH_DEFAULT RF_AT_PARAM_BANDWIDTH_20MHZ -+ -+/* GI (Guard Interval) */ -+#define RF_AT_PARAM_GI_800NS 0 -+#define RF_AT_PARAM_GI_400NS 1 -+#define RF_AT_PARAM_GI_DEFAULT RF_AT_PARAM_GI_800NS -+ -+/* STBC */ -+#define RF_AT_PARAM_STBC_DISABLE 0 -+#define RF_AT_PARAM_STBC_ENABLE 1 -+ -+/* RIFS */ -+#define RF_AT_PARAM_RIFS_DISABLE 0 -+#define RF_AT_PARAM_RIFS_ENABLE 1 -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+/* Function ID List */ -+typedef enum _ENUM_RF_AT_FUNCID_T { -+ RF_AT_FUNCID_VERSION = 0, -+ RF_AT_FUNCID_COMMAND, -+ RF_AT_FUNCID_POWER, -+ RF_AT_FUNCID_RATE, -+ RF_AT_FUNCID_PREAMBLE, -+ RF_AT_FUNCID_ANTENNA, -+ RF_AT_FUNCID_PKTLEN, -+ RF_AT_FUNCID_PKTCNT, -+ RF_AT_FUNCID_PKTINTERVAL, -+ RF_AT_FUNCID_TEMP_COMPEN, -+ RF_AT_FUNCID_TXOPLIMIT, -+ RF_AT_FUNCID_ACKPOLICY, -+ RF_AT_FUNCID_PKTCONTENT, -+ RF_AT_FUNCID_RETRYLIMIT, -+ RF_AT_FUNCID_QUEUE, -+ RF_AT_FUNCID_BANDWIDTH, -+ RF_AT_FUNCID_GI, -+ RF_AT_FUNCID_STBC, -+ RF_AT_FUNCID_CHNL_FREQ, -+ RF_AT_FUNCID_RIFS, -+ RF_AT_FUNCID_TRSW_TYPE, -+ RF_AT_FUNCID_RF_SX_SHUTDOWN, -+ RF_AT_FUNCID_PLL_SHUTDOWN, -+ RF_AT_FUNCID_SLOW_CLK_MODE, -+ RF_AT_FUNCID_ADC_CLK_MODE, -+ RF_AT_FUNCID_MEASURE_MODE, -+ RF_AT_FUNCID_VOLT_COMPEN, -+ RF_AT_FUNCID_DPD_TX_GAIN, -+ RF_AT_FUNCID_DPD_MODE, -+ RF_AT_FUNCID_TSSI_MODE, -+ RF_AT_FUNCID_TX_GAIN_CODE, -+ RF_AT_FUNCID_TX_PWR_MODE, -+ -+ /* Query command */ -+ RF_AT_FUNCID_TXED_COUNT = 32, -+ RF_AT_FUNCID_TXOK_COUNT, -+ RF_AT_FUNCID_RXOK_COUNT, -+ RF_AT_FUNCID_RXERROR_COUNT, -+ RF_AT_FUNCID_RESULT_INFO, -+ RF_AT_FUNCID_TRX_IQ_RESULT, -+ RF_AT_FUNCID_TSSI_RESULT, -+ RF_AT_FUNCID_DPD_RESULT, -+ RF_AT_FUNCID_RXV_DUMP, -+ RF_AT_FUNCID_RX_PHY_STATIS, -+ RF_AT_FUNCID_MEASURE_RESULT, -+ RF_AT_FUNCID_TEMP_SENSOR, -+ RF_AT_FUNCID_VOLT_SENSOR, -+ RF_AT_FUNCID_READ_EFUSE, -+ RF_AT_FUNCID_RX_RSSI, -+ RF_AT_FUNCID_FW_INFO, -+ RF_AT_FUNCID_DRV_INFO, -+ -+ /* Set command */ -+ RF_AT_FUNCID_SET_DPD_RESULT = 64, -+ RF_AT_FUNCID_SET_CW_MODE, -+ RF_AT_FUNCID_SET_JAPAN_CH14_FILTER, -+ RF_AT_FUNCID_WRITE_EFUSE, -+ RF_AT_FUNCID_SET_MAC_ADDRESS -+} ENUM_RF_AT_FUNCID_T; -+ -+/* Command */ -+typedef enum _ENUM_RF_AT_COMMAND_T { -+ RF_AT_COMMAND_STOPTEST = 0, -+ RF_AT_COMMAND_STARTTX, -+ RF_AT_COMMAND_STARTRX, -+ RF_AT_COMMAND_RESET, -+ RF_AT_COMMAND_OUTPUT_POWER, /* Payload */ -+ RF_AT_COMMAND_LO_LEAKAGE, /* Local freq is renamed to Local leakage */ -+ RF_AT_COMMAND_CARRIER_SUPPR, /* OFDM (LTF/STF), CCK (PI,PI/2) */ -+ RF_AT_COMMAND_TRX_IQ_CAL, -+ RF_AT_COMMAND_TSSI_CAL, -+ RF_AT_COMMAND_DPD_CAL, -+ RF_AT_COMMAND_CW, -+ RF_AT_COMMAND_NUM -+} ENUM_RF_AT_COMMAND_T; -+ -+/* Preamble */ -+typedef enum _ENUM_RF_AT_PREAMBLE_T { -+ RF_AT_PREAMBLE_NORMAL = 0, -+ RF_AT_PREAMBLE_CCK_SHORT, -+ RF_AT_PREAMBLE_11N_MM, -+ RF_AT_PREAMBLE_11N_GF, -+ RF_AT_PREAMBLE_NUM -+} ENUM_RF_AT_PREAMBLE_T; -+ -+/* Ack Policy */ -+typedef enum _ENUM_RF_AT_ACK_POLICY_T { -+ RF_AT_ACK_POLICY_NORMAL = 0, -+ RF_AT_ACK_POLICY_NOACK, -+ RF_AT_ACK_POLICY_NOEXPLICTACK, -+ RF_AT_ACK_POLICY_BLOCKACK, -+ RF_AT_ACK_POLICY_NUM -+} ENUM_RF_AT_ACK_POLICY_T; -+ -+typedef enum _ENUM_RF_AUTOTEST_STATE_T { -+ RF_AUTOTEST_STATE_STANDBY = 0, -+ RF_AUTOTEST_STATE_TX, -+ RF_AUTOTEST_STATE_RX, -+ RF_AUTOTEST_STATE_RESET, -+ RF_AUTOTEST_STATE_OUTPUT_POWER, -+ RF_AUTOTEST_STATE_LOCA_FREQUENCY, -+ RF_AUTOTEST_STATE_CARRIER_SUPRRESION, -+ RF_AUTOTEST_STATE_NUM -+} ENUM_RF_AUTOTEST_STATE_T; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+WLAN_STATUS rftestSetATInfo(IN P_ADAPTER_T prAdapter, UINT_32 u4FuncIndex, UINT_32 u4FuncData); -+ -+WLAN_STATUS -+rftestQueryATInfo(IN P_ADAPTER_T prAdapter, -+ UINT_32 u4FuncIndex, UINT_32 u4FuncData, OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen); -+ -+WLAN_STATUS rftestSetFrequency(IN P_ADAPTER_T prAdapter, IN UINT_32 u4FreqInKHz, IN PUINT_32 pu4SetInfoLen); -+ -+#endif /* _RFTEST_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/tdls_extr.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/tdls_extr.h -new file mode 100644 -index 000000000000..8ee184591fc2 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/tdls_extr.h -@@ -0,0 +1,427 @@ -+/* -+** Id: include/tdls_extr.h#1 -+*/ -+ -+/*! \file "tdls_extr.h" -+ \brief This file contains the external used in other modules -+ for MediaTek Inc. 802.11 Wireless LAN Adapters. -+*/ -+ -+/* -+** Log: tdls_extr.h -+ * -+ * 11 18 2013 vend_samp.lin -+ * NULL -+ * Initial version. -+ * -+ ** -+ */ -+ -+#ifndef _TDLS_EXTR_H -+#define _TDLS_EXTR_H -+ -+#if (CFG_SUPPORT_TDLS == 1) -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#define TDLS_TX_QUOTA_EMPTY_TIMEOUT 10 -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+/* protocol */ -+#define TDLS_FRM_PROT_TYPE 0x890d -+ -+/* TDLS uses Ethertype 89-0d frames. The UP shall be AC_VI, unless otherwise specified. */ -+#define USER_PRIORITY_TDLS 5 -+ -+/* Status code */ -+#define TDLS_STATUS WLAN_STATUS -+ -+#define TDLS_STATUS_SUCCESS WLAN_STATUS_SUCCESS -+#define TDLS_STATUS_FAILURE WLAN_STATUS_FAILURE -+#define TDLS_STATUS_INVALID_LENGTH WLAN_STATUS_INVALID_LENGTH -+#define TDLS_STATUS_RESOURCES WLAN_STATUS_RESOURCES -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+#define TDLS_U32 UINT32 -+#define TDLS_U16 UINT16 -+#define TDLS_U8 UINT8 -+ -+typedef enum _TDLS_REASON_CODE { -+ TDLS_REASON_CODE_UNREACHABLE = 25, -+ TDLS_REASON_CODE_UNSPECIFIED = 26, -+ -+ TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_UNKNOWN = 0x80, /* 128 */ -+ TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_WIFI_OFF = 0x81, /* 129 */ -+ TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_ROAMING = 0x82, /* 130 */ -+ TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_PTI_TIMEOUT = 0x83, /* 131 */ -+ TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_AGE_TIMEOUT = 0x84, /* 132 */ -+ TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_REKEY = 0x85, /* 133 */ -+ TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_PTI_SEND_FAIL = 0x86, /* 134 */ -+ TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_PTI_SEND_MAX_FAIL = 0x87, /* 135 */ -+ TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_WRONG_NETWORK_IDX = 0x88, /* 136 */ -+ TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_NON_STATE3 = 0x89, /* 137 */ -+ TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_TX_QUOTA_EMPTY = 0x8a, /* 138 */ -+ TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_LOST_TEAR_DOWN = 0x8b /* 139 */ -+} TDLS_REASON_CODE; -+ -+/* TDLS FSM */ -+typedef struct _TDLS_CMD_PEER_ADD_T { -+ -+ TDLS_U8 aucPeerMac[6]; -+ -+#if 0 -+ ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex; -+ UINT_16 u2CapInfo; -+ -+ UINT_16 u2OperationalRateSet; -+ UINT_16 u2BSSBasicRateSet; -+ BOOLEAN fgIsUnknownBssBasicRate; -+ -+ UINT_8 ucPhyTypeSet; -+#endif -+} TDLS_CMD_PEER_ADD_T; -+ -+typedef struct _TDLS_CMD_LINK_T { -+ -+ TDLS_U8 aucPeerMac[6]; -+ BOOLEAN fgIsEnabled; -+} TDLS_CMD_LINK_T; -+ -+typedef struct _TDLS_CMD_PEER_UPDATE_HT_CAP_MCS_INFO_T { -+ TDLS_U8 arRxMask[10]; -+ TDLS_U16 u2RxHighest; -+ TDLS_U8 ucTxParams; -+ TDLS_U8 Reserved[3]; -+} TDLS_CMD_PEER_UPDATE_HT_CAP_MCS_INFO_T; -+ -+typedef struct _TDLS_CMD_PEER_UPDATE_HT_CAP_T { -+ TDLS_U16 u2CapInfo; -+ TDLS_U8 ucAmpduParamsInfo; -+ -+ /* 16 bytes MCS information */ -+ TDLS_CMD_PEER_UPDATE_HT_CAP_MCS_INFO_T rMCS; -+ -+ TDLS_U16 u2ExtHtCapInfo; -+ TDLS_U32 u4TxBfCapInfo; -+ TDLS_U8 ucAntennaSelInfo; -+} TDLS_CMD_PEER_UPDATE_HT_CAP_T; -+ -+typedef struct _TDLS_CMD_PEER_UPDATE_T { -+ -+ TDLS_U8 aucPeerMac[6]; -+ -+#define TDLS_CMD_PEER_UPDATE_SUP_CHAN_MAX 50 -+ TDLS_U8 aucSupChan[TDLS_CMD_PEER_UPDATE_SUP_CHAN_MAX]; -+ -+ TDLS_U16 u2StatusCode; -+ -+#define TDLS_CMD_PEER_UPDATE_SUP_RATE_MAX 50 -+ TDLS_U8 aucSupRate[TDLS_CMD_PEER_UPDATE_SUP_RATE_MAX]; -+ TDLS_U16 u2SupRateLen; -+ -+ TDLS_U8 UapsdBitmap; -+ TDLS_U8 UapsdMaxSp; /* MAX_SP */ -+ -+ TDLS_U16 u2Capability; -+#define TDLS_CMD_PEER_UPDATE_EXT_CAP_MAXLEN 5 -+ TDLS_U8 aucExtCap[TDLS_CMD_PEER_UPDATE_EXT_CAP_MAXLEN]; -+ TDLS_U16 u2ExtCapLen; -+ -+ TDLS_CMD_PEER_UPDATE_HT_CAP_T rHtCap; -+ BOOLEAN fgIsSupHt; -+ -+} TDLS_CMD_PEER_UPDATE_T; -+ -+/* Command to TDLS core module */ -+typedef enum _TDLS_CMD_CORE_ID { -+ TDLS_CORE_CMD_TEST_NULL_RCV = 0x00, -+ TDLS_CORE_CMD_TEST_PTI_RSP = 0x01, -+ TDLS_CORE_CMD_MIB_UPDATE = 0x02, -+ TDLS_CORE_CMD_TEST_TX_FAIL_SKIP = 0x03, -+ TDLS_CORE_CMD_UAPSD_CONF = 0x04, -+ TDLS_CORE_CMD_TEST_DATA_RCV = 0x05, -+ TDLS_CORE_CMD_TEST_PTI_REQ = 0x06, -+ TDLS_CORE_CMD_TEST_CHSW_REQ = 0x07, -+ TDLS_CORE_CMD_CHSW_CONF = 0x08, -+ TDLS_CORE_CMD_TEST_KEEP_ALIVE_SKIP = 0x09, -+ TDLS_CORE_CMD_TEST_CHSW_TIMEOUT_SKIP = 0x0a, -+ TDLS_CORE_CMD_TEST_CHSW_RSP = 0x0b, -+ TDLS_CORE_CMD_TEST_SCAN_SKIP = 0x0c, -+ TDLS_CORE_CMD_SETUP_CONF = 0x0d, -+ TDLS_CORE_CMD_TEST_TEAR_DOWN = 0x0e, -+ TDLS_CORE_CMD_KEY_INFO = 0x0f, -+ TDLS_CORE_CMD_TEST_PTI_TX_FAIL = 0x10 -+} TDLS_CMD_CORE_ID; -+ -+typedef struct _TDLS_CMD_CORE_TEST_NULL_RCV_T { -+ -+ TDLS_U32 u4PM; -+} TDLS_CMD_CORE_TEST_NULL_RCV_T; -+ -+typedef struct _TDLS_CMD_CORE_TEST_PTI_REQ_RCV_T { -+ -+ TDLS_U32 u4DialogToken; -+} TDLS_CMD_CORE_TEST_PTI_REQ_RCV_T; -+ -+typedef struct _TDLS_CMD_CORE_TEST_PTI_RSP_RCV_T { -+ -+ TDLS_U32 u4DialogToken; -+ TDLS_U32 u4PM; -+} TDLS_CMD_CORE_TEST_PTI_RSP_RCV_T; -+ -+typedef struct _TDLS_CMD_CORE_TEST_TEAR_DOWN_RCV_T { -+ -+ TDLS_U32 u4ReasonCode; -+} TDLS_CMD_CORE_TEST_TEAR_DOWN_RCV_T; -+ -+typedef struct _TDLS_CMD_CORE_TEST_CHST_REQ_RCV_T { -+ -+ TDLS_U32 u4Chan; -+ TDLS_U32 u4RegClass; -+ TDLS_U32 u4SecChanOff; -+ TDLS_U32 u4SwitchTime; -+ TDLS_U32 u4SwitchTimeout; -+} TDLS_CMD_CORE_TEST_CHST_REQ_RCV_T; -+ -+typedef struct _TDLS_CMD_CORE_TEST_CHST_RSP_RCV_T { -+ -+ TDLS_U32 u4Chan; -+ TDLS_U32 u4SwitchTime; -+ TDLS_U32 u4SwitchTimeout; -+ TDLS_U32 u4StatusCode; -+} TDLS_CMD_CORE_TEST_CHST_RSP_RCV_T; -+ -+typedef struct _TDLS_CMD_CORE_TEST_DATA_RCV_T { -+ -+ TDLS_U32 u4PM; -+ TDLS_U32 u4UP; -+ TDLS_U32 u4EOSP; -+ TDLS_U32 u4IsNull; -+} TDLS_CMD_CORE_TEST_DATA_RCV_T; -+ -+typedef struct _TDLS_CMD_CORE_MIB_PARAM_UPDATE_T { -+ -+ BOOLEAN Tdlsdot11TunneledDirectLinkSetupImplemented; -+ BOOLEAN Tdlsdot11TDLSPeerUAPSDBufferSTAActivated; -+ BOOLEAN Tdlsdot11TDLSPeerPSMActivated; -+ TDLS_U16 Tdlsdot11TDLSPeerUAPSDIndicationWindow; -+ BOOLEAN Tdlsdot11TDLSChannelSwitchingActivated; -+ TDLS_U8 Tdlsdot11TDLSPeerSTAMissingAckRetryLimit; -+ TDLS_U8 Tdlsdot11TDLSResponseTimeout; -+ TDLS_U16 Tdlsdot11TDLSProbeDelay; -+ TDLS_U8 Tdlsdot11TDLSDiscoveryRequestWindow; -+ TDLS_U8 Tdlsdot11TDLSACDeterminationInterval; -+} TDLS_CMD_CORE_MIB_PARAM_UPDATE_T; -+ -+typedef struct _TDLS_CMD_CORE_TEST_TX_FAIL_SKIP_T { -+ -+ BOOLEAN fgIsEnable; -+} TDLS_CMD_CORE_TEST_TX_FAIL_SKIP_T; -+ -+typedef struct _TDLS_CMD_CORE_UAPSD_CONFIG_T { -+ -+ BOOLEAN fgIsSpTimeoutSkip; -+ BOOLEAN fgIsPtiTimeoutSkip; -+} TDLS_CMD_CORE_UAPSD_CONFIG_T; -+ -+typedef struct _TDLS_CMD_CORE_SETUP_CONFIG_T { -+ -+ BOOLEAN fgIs2040Supported; -+} TDLS_CMD_CORE_SETUP_CONFIG_T; -+ -+typedef struct _TDLS_CMD_CORE_CHSW_CONFIG_T { -+ -+ TDLS_U8 ucNetTypeIndex; -+ BOOLEAN fgIsChSwEnabled; -+ BOOLEAN fgIsChSwStarted; -+ TDLS_U8 ucRegClass; -+ TDLS_U8 ucTargetChan; -+ TDLS_U8 ucSecChanOff; -+ BOOLEAN fgIsChSwRegular; -+} TDLS_CMD_CORE_CHSW_CONFIG_T; -+ -+typedef struct _TDLS_CMD_CORE_TEST_KEEP_ALIVE_SKIP_T { -+ -+ BOOLEAN fgIsEnable; -+} TDLS_CMD_CORE_TEST_KEEP_ALIVE_SKIP_T; -+ -+typedef struct _TDLS_CMD_CORE_TEST_CHSW_TIMEOUT_SKIP_T { -+ -+ BOOLEAN fgIsEnable; -+} TDLS_CMD_CORE_TEST_CHSW_TIMEOUT_SKIP_T; -+ -+typedef struct _TDLS_CMD_CORE_TEST_PROHIBIT_T { -+ -+ BOOLEAN fgIsEnable; -+ BOOLEAN fgIsSet; -+} TDLS_CMD_CORE_TEST_PROHIBIT_T; -+ -+typedef struct _TDLS_CMD_CORE_TEST_SCAN_SKIP_T { -+ -+ BOOLEAN fgIsEnable; -+} TDLS_CMD_CORE_TEST_SCAN_SKIP_T; -+ -+typedef struct _TDLS_CMD_CORE_INFO_DISPLAY_T { -+ -+ BOOLEAN fgIsToClearAllHistory; -+} TDLS_CMD_CORE_INFO_DISPLAY_T; -+ -+typedef struct _TDLS_CMD_CORE_TEST_PTI_TX_FAIL_T { -+ -+ BOOLEAN fgIsEnable; -+} TDLS_CMD_CORE_TEST_PTI_TX_FAIL_T; -+ -+typedef struct _TDLS_CMD_CORE_T { -+ -+ TDLS_U32 u4Command; /* TDLS_CMD_CORE_ID */ -+ -+ TDLS_U8 aucPeerMac[6]; -+ TDLS_U8 ucNetTypeIndex; -+ -+#define TDLS_CMD_CORE_RESERVED_SIZE 50 -+ union { -+ TDLS_CMD_CORE_TEST_NULL_RCV_T rCmdNullRcv; -+ TDLS_CMD_CORE_TEST_PTI_REQ_RCV_T rCmdPtiReqRcv; -+ TDLS_CMD_CORE_TEST_PTI_RSP_RCV_T rCmdPtiRspRcv; -+ TDLS_CMD_CORE_TEST_TEAR_DOWN_RCV_T rCmdTearDownRcv; -+ TDLS_CMD_CORE_TEST_CHST_REQ_RCV_T rCmdChStReqRcv; -+ TDLS_CMD_CORE_TEST_CHST_RSP_RCV_T rCmdChStRspRcv; -+ TDLS_CMD_CORE_TEST_DATA_RCV_T rCmdDatRcv; -+ TDLS_CMD_CORE_TEST_TX_FAIL_SKIP_T rCmdTxFailSkip; -+ TDLS_CMD_CORE_TEST_KEEP_ALIVE_SKIP_T rCmdKeepAliveSkip; -+ TDLS_CMD_CORE_TEST_CHSW_TIMEOUT_SKIP_T rCmdChSwTimeoutSkip; -+ TDLS_CMD_CORE_TEST_PROHIBIT_T rCmdProhibit; -+ TDLS_CMD_CORE_TEST_SCAN_SKIP_T rCmdScanSkip; -+ TDLS_CMD_CORE_TEST_PTI_TX_FAIL_T rCmdPtiTxFail; -+ -+ TDLS_CMD_CORE_MIB_PARAM_UPDATE_T rCmdMibUpdate; -+ TDLS_CMD_CORE_UAPSD_CONFIG_T rCmdUapsdConf; -+ TDLS_CMD_CORE_CHSW_CONFIG_T rCmdChSwConf; -+ TDLS_CMD_CORE_SETUP_CONFIG_T rCmdSetupConf; -+ TDLS_CMD_CORE_INFO_DISPLAY_T rCmdInfoDisplay; -+ TDLS_U8 Reserved[TDLS_CMD_CORE_RESERVED_SIZE]; -+ } Content; -+} TDLS_CMD_CORE_T; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+/* -+ assign station record idx for the packet only when STA_STATE_3 -+ Or we will try to send data frame when the TDLS peer's state is STA_STATE_1 -+ EX: -+ 1. mtk_cfg80211_add_station: First create the STA_RECORD_T; -+ 2. TdlsexCfg80211TdlsMgmt: Send a TDLS request frame. -+ 3. mtk_cfg80211_add_station: Change state to STA_STATE_1. -+ 4. TdlsexCfg80211TdlsMgmt: Send a TDLS request frame. -+*/ -+#define TDLSEX_STA_REC_IDX_GET(__prAdapter__, __MsduInfo__) \ -+{ \ -+ STA_RECORD_T *__StaRec__; \ -+ __MsduInfo__->ucStaRecIndex = STA_REC_INDEX_NOT_FOUND; \ -+ __StaRec__ = cnmGetStaRecByAddress(__prAdapter__, \ -+ (UINT_8) NETWORK_TYPE_AIS_INDEX, \ -+ __MsduInfo__->aucEthDestAddr); \ -+ if ((__StaRec__ != NULL) && \ -+ ((__StaRec__)->ucStaState == STA_STATE_3) && \ -+ (IS_TDLS_STA(__StaRec__))) { \ -+ __MsduInfo__->ucStaRecIndex = __StaRec__->ucIndex; \ -+ } \ -+} -+ -+/* fill wiphy flag */ -+#define TDLSEX_WIPHY_FLAGS_INIT(__fgFlag__)\ -+{ \ -+ __fgFlag__ |= (WIPHY_FLAG_SUPPORTS_TDLS | WIPHY_FLAG_TDLS_EXTERNAL_SETUP);\ -+} -+ -+/* assign user priority of a TDLS action frame */ -+/* -+ According to 802.11z: Setup req/resp are sent in AC_BK, otherwise we should default -+ to AC_VI. -+*/ -+#define TDLSEX_UP_ASSIGN(__UserPriority__) \ -+{ \ -+ __UserPriority__ = USER_PRIORITY_TDLS; \ -+} -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+int -+TdlsexCfg80211TdlsMgmt(struct wiphy *wiphy, struct net_device *dev, -+ const u8 *peer, u8 action_code, u8 dialog_token, -+ u16 status_code, u32 peer_capability, -+ bool initiator, const u8 *buf, size_t len); -+ -+int TdlsexCfg80211TdlsOper(struct wiphy *wiphy, struct net_device *dev, -+ const u8 *peer, enum nl80211_tdls_operation oper); -+ -+VOID TdlsexCmd(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); -+ -+VOID TdlsexBssExtCapParse(STA_RECORD_T *prStaRec, UINT_8 *pucIE); -+ -+VOID TdlsexEventHandle(P_GLUE_INFO_T prGlueInfo, UINT8 *prInBuf, UINT32 u4InBufLen); -+ -+TDLS_STATUS TdlsexKeyHandle(ADAPTER_T *prAdapter, PARAM_KEY_T *prNewKey); -+ -+VOID TdlsexInit(ADAPTER_T *prAdapter); -+ -+BOOLEAN TdlsexIsAnyPeerInPowerSave(ADAPTER_T *prAdapter); -+ -+TDLS_STATUS TdlsexLinkCtrl(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen); -+ -+VOID -+TdlsexLinkHistoryRecord(GLUE_INFO_T *prGlueInfo, -+ BOOLEAN fgIsTearDown, UINT8 *pucPeerMac, BOOLEAN fgIsFromUs, UINT16 u2ReasonCode); -+ -+TDLS_STATUS TdlsexMgmtCtrl(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen); -+ -+TDLS_STATUS TdlsexPeerAdd(P_ADAPTER_T prAdapter, PVOID pvSetBuffer, UINT_32 u4SetBufferLen, PUINT_32 pu4SetInfoLen); -+ -+TDLS_STATUS TdlsexPeerUpdate(P_ADAPTER_T prAdapter, PVOID pvSetBuffer, UINT_32 u4SetBufferLen, PUINT_32 pu4SetInfoLen); -+ -+BOOLEAN TdlsexRxFrameDrop(GLUE_INFO_T *prGlueInfo, UINT_8 *pPkt); -+ -+VOID TdlsexRxFrameHandle(GLUE_INFO_T *prGlueInfo, UINT8 *pPkt, UINT16 u2PktLen); -+ -+TDLS_STATUS TdlsexStaRecIdxGet(ADAPTER_T *prAdapter, MSDU_INFO_T *prMsduInfo); -+ -+VOID TdlsexTxQuotaCheck(GLUE_INFO_T *prGlueInfo, STA_RECORD_T *prStaRec, UINT8 FreeQuota); -+ -+VOID TdlsexUninit(ADAPTER_T *prAdapter); -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif /* CFG_SUPPORT_TDLS */ -+ -+#endif /* _TDLS_EXTR_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/typedef.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/typedef.h -new file mode 100644 -index 000000000000..7ab62dae8813 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/typedef.h -@@ -0,0 +1,244 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/typedef.h#1 -+*/ -+ -+/*! \file typedef.h -+ \brief Declaration of data type and return values of internal protocol stack. -+ -+ In this file we declare the data type and return values which will be exported -+ to the GLUE Layer. -+*/ -+ -+/* -+** Log: typedef.h -+ * -+ * 07 18 2011 chinghwa.yu -+ * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm -+ * Add CMD/Event for RDD and BWCS. -+ * -+ * 12 30 2010 cp.wu -+ * [WCXRP00000327] [MT6620 Wi-Fi][Driver] Improve HEC WHQA 6972 workaround coverage in driver side -+ * host driver not to set FW-own when there is still pending interrupts -+ * -+ * 09 03 2010 kevin.huang -+ * NULL -+ * Refine #include sequence and solve recursive/nested #include issue -+ * -+ * 08 16 2010 kevin.huang -+ * NULL -+ * Refine AAA functions -+ * -+ * 07 19 2010 jeffrey.chang -+ * -+ * Linux port modification -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 23 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * integrate . -+ * -+ * 06 18 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Provide cnmMgtPktAlloc() and alloc/free function of msg/buf -+ * -+ * 06 11 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) migrate assoc.c. -+ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness -+ * 3) add configuration options for CNM_MEM and RSN modules -+ * 4) add data path for management frames -+ * 5) eliminate rPacketInfo of MSDU_INFO_T -+ * -+ * 06 09 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add necessary changes to driver data paths. -+ * -+ * 06 09 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add definitions for module migration. -+ * -+ * 06 07 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add aa_fsm.h, ais_fsm.h, bss.h, mib.h and scan.h. -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 06 03 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * move timer callback to glue layer. -+ * -+ * 05 31 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * add cfg80211 interface, which is to replace WE, for further extension -+ * -+ * 03 24 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * initial import for Linux port -+ * -+ * 02 24 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * add Ethernet destination address information in packet info for TX -+ * -+ * 02 23 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * add new API: wlanProcessQueuedPackets() -+** \main\maintrunk.MT6620WiFiDriver_Prj\6 2009-03-23 21:41:37 GMT mtk01461 -+** Update PACKET_INFO_INIT for TX Path -+** \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-03-23 00:30:17 GMT mtk01461 -+** Add parameter in PACKET_INFO_T for HIF Loopback -+** \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-03-18 20:25:22 GMT mtk01461 -+** Fix LINT warning -+** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-03-16 09:08:28 GMT mtk01461 -+** Update TX PATH API -+** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 20:11:54 GMT mtk01426 -+** Init for develop -+** -+*/ -+ -+#ifndef _TYPEDEF_H -+#define _TYPEDEF_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/* ieee80211.h of linux has duplicated definitions */ -+#if defined(WLAN_STATUS_SUCCESS) -+#undef WLAN_STATUS_SUCCESS -+#endif -+ -+#define WLAN_STATUS_SUCCESS ((WLAN_STATUS) 0x00000000L) -+#define WLAN_STATUS_PENDING ((WLAN_STATUS) 0x00000103L) -+#define WLAN_STATUS_NOT_ACCEPTED ((WLAN_STATUS) 0x00010003L) -+ -+#define WLAN_STATUS_MEDIA_CONNECT ((WLAN_STATUS) 0x4001000BL) -+#define WLAN_STATUS_MEDIA_DISCONNECT ((WLAN_STATUS) 0x4001000CL) -+#define WLAN_STATUS_MEDIA_DISCONNECT_LOCALLY ((WLAN_STATUS) 0x4001000DL) -+ -+#define WLAN_STATUS_MEDIA_SPECIFIC_INDICATION ((WLAN_STATUS) 0x40010012L) -+ -+#define WLAN_STATUS_SCAN_COMPLETE ((WLAN_STATUS) 0x60010001L) -+#define WLAN_STATUS_MSDU_OK ((WLAN_STATUS) 0x60010002L) -+ -+/* TODO(Kevin): double check if 0x60010001 & 0x60010002 is proprietary */ -+#define WLAN_STATUS_ROAM_OUT_FIND_BEST ((WLAN_STATUS) 0x60010101L) -+#define WLAN_STATUS_ROAM_DISCOVERY ((WLAN_STATUS) 0x60010102L) -+ -+#define WLAN_STATUS_FAILURE ((WLAN_STATUS) 0xC0000001L) -+#define WLAN_STATUS_RESOURCES ((WLAN_STATUS) 0xC000009AL) -+#define WLAN_STATUS_NOT_SUPPORTED ((WLAN_STATUS) 0xC00000BBL) -+ -+#define WLAN_STATUS_MULTICAST_FULL ((WLAN_STATUS) 0xC0010009L) -+#define WLAN_STATUS_INVALID_PACKET ((WLAN_STATUS) 0xC001000FL) -+#define WLAN_STATUS_ADAPTER_NOT_READY ((WLAN_STATUS) 0xC0010011L) -+#define WLAN_STATUS_NOT_INDICATING ((WLAN_STATUS) 0xC0010013L) -+#define WLAN_STATUS_INVALID_LENGTH ((WLAN_STATUS) 0xC0010014L) -+#define WLAN_STATUS_INVALID_DATA ((WLAN_STATUS) 0xC0010015L) -+#define WLAN_STATUS_BUFFER_TOO_SHORT ((WLAN_STATUS) 0xC0010016L) -+ -+#define WLAN_STATUS_BWCS_UPDATE ((WLAN_STATUS) 0xC0010017L) -+ -+#define WLAN_STATUS_CONNECT_INDICATION ((WLAN_STATUS) 0xC0010018L) -+ -+/* NIC status flags */ -+#define ADAPTER_FLAG_HW_ERR 0x00400000 -+ -+/* Type Length */ -+#define TL_IPV4 0x0008 -+#define TL_IPV6 0xDD86 -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+/* Type definition for GLUE_INFO structure */ -+typedef struct _GLUE_INFO_T GLUE_INFO_T, *P_GLUE_INFO_T; -+ -+/* Type definition for WLAN STATUS */ -+typedef UINT_32 WLAN_STATUS, *P_WLAN_STATUS; -+ -+/* Type definition for ADAPTER structure */ -+typedef struct _ADAPTER_T ADAPTER_T, *P_ADAPTER_T; -+ -+/* Type definition for MESSAGE HEADER structure */ -+typedef struct _MSG_HDR_T MSG_HDR_T, *P_MSG_HDR_T; -+ -+/* Type definition for WLAN configuration */ -+typedef struct _WLAN_CFG_T WLAN_CFG_T, *P_WLAN_CFG_T; -+ -+/* Type definition for WLAN configuration entry */ -+typedef struct _WLAN_CFG_ENTRY_T WLAN_CFG_ENTRY_T, *P_WLAN_CFG_ENTRY_T; -+ -+/* Type definition for WLAN configuration callback */ -+typedef WLAN_STATUS(*WLAN_CFG_SET_CB) (P_ADAPTER_T prAdapter, -+ PUINT_8 pucKey, PUINT_8 pucValue, PVOID pPrivate, UINT_32 u4Flags); -+ -+/* Type definition for Pointer to OS Native Packet */ -+typedef void *P_NATIVE_PACKET; -+ -+/* Type definition for STA_RECORD_T structure to handle the connectivity and packet reception -+ * for a particular STA. -+ */ -+typedef struct _STA_RECORD_T STA_RECORD_T, *P_STA_RECORD_T, **PP_STA_RECORD_T; -+ -+/* CMD_INFO_T is used by Glue Layer to send a cluster of Command(OID) information to -+ * the TX Path to reduce the parameters of a function call. -+ */ -+typedef struct _CMD_INFO_T CMD_INFO_T, *P_CMD_INFO_T; -+ -+/* Following typedef should be removed later, because Glue Layer should not -+ * be aware of following data type. -+ */ -+typedef struct _SW_RFB_T SW_RFB_T, *P_SW_RFB_T, **PP_SW_RFB_T; -+ -+typedef struct _MSDU_INFO_T MSDU_INFO_T, *P_MSDU_INFO_T; -+ -+typedef struct _REG_ENTRY_T REG_ENTRY_T, *P_REG_ENTRY_T; -+ -+/* IST handler definition */ -+typedef VOID(*IST_EVENT_FUNCTION) (P_ADAPTER_T); -+ -+/* Type definition for function pointer of timer handler */ -+typedef VOID(*PFN_TIMER_CALLBACK) (IN P_GLUE_INFO_T); -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+#endif /* _TYPEDEF_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/wlan_bow.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/wlan_bow.h -new file mode 100644 -index 000000000000..e8937166dc4f ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/wlan_bow.h -@@ -0,0 +1,352 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/wlan_bow.h#1 -+*/ -+ -+/*! \file "wlan_bow.h" -+ \brief This file contains the declairations of 802.11 PAL -+ command processing routines for -+ MediaTek Inc. 802.11 Wireless LAN Adapters. -+*/ -+ -+/* -+** Log: wlan_bow.h -+ * -+ * 05 25 2011 terry.wu -+ * [WCXRP00000735] [MT6620 Wi-Fi][BoW][FW/Driver] Protect BoW connection establishment -+ * Add BoW Cancel Scan Request and Turn On deactive network function. -+ * -+ * 05 23 2011 terry.wu -+ * [WCXRP00000735] [MT6620 Wi-Fi][BoW][FW/Driver] Protect BoW connection establishment -+ * Add some BoW error handling. -+ * -+ * 05 21 2011 terry.wu -+ * [WCXRP00000735] [MT6620 Wi-Fi][BoW][FW/Driver] Protect BoW connection establishment -+ * Protect BoW connection establishment. -+ * -+ * 05 17 2011 terry.wu -+ * [WCXRP00000730] [MT6620 Wi-Fi][BoW] Send deauth while disconnecting -+ * Send deauth while disconnecting BoW link. -+ * -+ * 05 06 2011 terry.wu -+ * [WCXRP00000707] [MT6620 Wi-Fi][Driver] Fix BoW Multiple Physical Link connect/disconnect issue -+ * Fix BoW Multiple Physical Link connect/disconnect issue. -+ * -+ * 04 15 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Add BOW short range mode. -+ * -+ * 03 27 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Support multiple physical link. -+ * -+ * 03 10 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Add BOW table. -+ * -+ * 02 16 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Add bowNotifyAllLinkDisconnected interface and change channel grant procedure for bow starting.. -+ * -+ * 02 15 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Update bowString and channel grant. -+ * -+ * 01 11 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Update BOW Activity Report structure and bug fix. -+ * -+ * 09 27 2010 chinghwa.yu -+ * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000065] Update BoW design and settings -+ * Update BCM/BoW design and settings. -+ * -+ * 09 14 2010 chinghwa.yu -+ * NULL -+ * Add bowRunEventAAAComplete. -+ * -+ * 08 24 2010 chinghwa.yu -+ * NULL -+ * Update BOW for the 1st time. -+ * -+ * 07 30 2010 cp.wu -+ * NULL -+ * 1) BoW wrapper: use definitions instead of hard-coded constant for error code -+ * 2) AIS-FSM: eliminate use of desired RF parameters, use prTargetBssDesc instead -+ * 3) add handling for RX_PKT_DESTINATION_HOST_WITH_FORWARD for GO-broadcast frames -+ * -+ * 07 15 2010 cp.wu -+ * -+ * sync. bluetooth-over-Wi-Fi interface to driver interface document v0.2.6. -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 05 17 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * 1) add timeout handler mechanism for pending command packets -+ * 2) add p2p add/removal key -+ * -+ * 05 13 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * 1) all BT physical handles shares the same RSSI/Link Quality. -+ * 2) simplify BT command composing -+ * -+ * 04 28 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * change prefix for data structure used to communicate with 802.11 PAL -+ * to avoid ambiguous naming with firmware interface -+ * -+ * 04 27 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * add multiple physical link support -+ * -+ * 04 13 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * add framework for BT-over-Wi-Fi support. -+ * * * * * * * * * * * * 1) prPendingCmdInfo is replaced by queue for multiple handler capability -+ * * * * * * * * * * * * 2) command sequence number is now increased atomically -+ * * * * * * * * * * * * 3) private data could be hold and taken use for other purpose -+** -+*/ -+ -+#ifndef _WLAN_BOW_H -+#define _WLAN_BOW_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "nic/bow.h" -+#include "nic/cmd_buf.h" -+ -+#if CFG_ENABLE_BT_OVER_WIFI -+ -+#if CFG_BOW_TEST -+extern UINT_32 g_arBowRevPalPacketTime[32]; -+#endif -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+#define BOWCMD_STATUS_SUCCESS 0 -+#define BOWCMD_STATUS_FAILURE 1 -+#define BOWCMD_STATUS_UNACCEPTED 2 -+#define BOWCMD_STATUS_INVALID 3 -+#define BOWCMD_STATUS_TIMEOUT 4 -+ -+#define BOW_WILDCARD_SSID "AMP" -+#define BOW_WILDCARD_SSID_LEN 3 -+#define BOW_SSID_LEN 21 -+ -+ /* 0: query, 1: setup, 2: destroy */ -+#define BOW_QUERY_CMD 0 -+#define BOW_SETUP_CMD 1 -+#define BOW_DESTROY_CMD 2 -+ -+#define BOW_INITIATOR 0 -+#define BOW_RESPONDER 1 -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+typedef struct _BOW_TABLE_T { -+ UINT_8 ucAcquireID; -+ BOOLEAN fgIsValid; -+ ENUM_BOW_DEVICE_STATE eState; -+ UINT_8 aucPeerAddress[6]; -+ /* UINT_8 ucRole; */ -+ /* UINT_8 ucChannelNum; */ -+ UINT_16 u2Reserved; -+} BOW_TABLE_T, *P_BOW_TABLE_T; -+ -+typedef WLAN_STATUS(*PFN_BOW_CMD_HANDLE) (P_ADAPTER_T, P_AMPC_COMMAND); -+ -+typedef struct _BOW_CMD_T { -+ UINT_8 uCmdID; -+ PFN_BOW_CMD_HANDLE pfCmdHandle; -+} BOW_CMD_T, *P_BOW_CMD_T; -+ -+typedef struct _BOW_EVENT_ACTIVITY_REPORT_T { -+ UINT_8 ucReason; -+ UINT_8 aucReserved; -+ UINT_8 aucPeerAddress[6]; -+} BOW_EVENT_ACTIVITY_REPORT_T, *P_BOW_EVENT_ACTIVITY_REPORT_T; -+ -+/* -+ucReason: 0: success -+ 1: general failure -+ 2: too much time (> 2/3 second totally) requested for scheduling. -+ Others: reserved. -+*/ -+ -+typedef struct _BOW_EVENT_SYNC_TSF_T { -+ UINT_64 u4TsfTime; -+ UINT_32 u4TsfSysTime; -+ UINT_32 u4ScoTime; -+ UINT_32 u4ScoSysTime; -+} BOW_EVENT_SYNC_TSF_T, *P_BOW_EVENT_SYNC_TSF_T; -+ -+typedef struct _BOW_ACTIVITY_REPORT_BODY_T { -+ UINT_32 u4StartTime; -+ UINT_32 u4Duration; -+ UINT_32 u4Periodicity; -+} BOW_ACTIVITY_REPORT_BODY_T, *P_BOW_ACTIVITY_REPORT_BODY_T; -+ -+typedef struct _BOW_ACTIVITY_REPORT_T { -+ UINT_8 aucPeerAddress[6]; -+ UINT_8 ucScheduleKnown; -+ UINT_8 ucNumReports; -+ BOW_ACTIVITY_REPORT_BODY_T arBowActivityReportBody[MAX_ACTIVITY_REPORT]; -+} BOW_ACTIVITY_REPORT_T, *P_BOW_ACTIVITY_REPORT_T; -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+/*--------------------------------------------------------------*/ -+/* Firmware Command Packer */ -+/*--------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSendSetQueryBowCmd(IN P_ADAPTER_T prAdapter, -+ UINT_8 ucCID, -+ BOOLEAN fgSetQuery, -+ BOOLEAN fgNeedResp, -+ PFN_CMD_DONE_HANDLER pfCmdDoneHandler, -+ PFN_CMD_TIMEOUT_HANDLER pfCmdTimeoutHandler, -+ UINT_32 u4SetQueryInfoLen, PUINT_8 pucInfoBuffer, IN UINT_8 ucSeqNumber); -+ -+/*--------------------------------------------------------------*/ -+/* Command Dispatcher */ -+/*--------------------------------------------------------------*/ -+WLAN_STATUS wlanbowHandleCommand(IN P_ADAPTER_T prAdapter, IN P_AMPC_COMMAND prCmd); -+ -+/*--------------------------------------------------------------*/ -+/* Routines to handle command */ -+/*--------------------------------------------------------------*/ -+WLAN_STATUS bowCmdGetMacStatus(IN P_ADAPTER_T prAdapter, IN P_AMPC_COMMAND prCmd); -+ -+WLAN_STATUS bowCmdSetupConnection(IN P_ADAPTER_T prAdapter, IN P_AMPC_COMMAND prCmd); -+ -+WLAN_STATUS bowCmdDestroyConnection(IN P_ADAPTER_T prAdapter, IN P_AMPC_COMMAND prCmd); -+ -+WLAN_STATUS bowCmdSetPTK(IN P_ADAPTER_T prAdapter, IN P_AMPC_COMMAND prCmd); -+ -+WLAN_STATUS bowCmdReadRSSI(IN P_ADAPTER_T prAdapter, IN P_AMPC_COMMAND prCmd); -+ -+WLAN_STATUS bowCmdReadLinkQuality(IN P_ADAPTER_T prAdapter, IN P_AMPC_COMMAND prCmd); -+ -+WLAN_STATUS bowCmdShortRangeMode(IN P_ADAPTER_T prAdapter, IN P_AMPC_COMMAND prCmd); -+ -+WLAN_STATUS bowCmdGetChannelList(IN P_ADAPTER_T prAdapter, IN P_AMPC_COMMAND prCmd); -+ -+VOID wlanbowCmdEventSetStatus(IN P_ADAPTER_T prAdapter, IN P_AMPC_COMMAND prCmd, IN UINT_8 ucEventBuf); -+ -+/*--------------------------------------------------------------*/ -+/* Callbacks for event indication */ -+/*--------------------------------------------------------------*/ -+VOID wlanbowCmdEventSetCommon(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); -+ -+VOID wlanbowCmdEventLinkConnected(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); -+ -+VOID wlanbowCmdEventLinkDisconnected(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); -+ -+VOID wlanbowCmdEventSetSetupConnection(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); -+ -+VOID wlanbowCmdEventReadLinkQuality(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); -+ -+VOID wlanbowCmdEventReadRssi(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); -+ -+VOID wlanbowCmdTimeoutHandler(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo); -+ -+VOID bowStopping(IN P_ADAPTER_T prAdapter); -+ -+VOID bowStarting(IN P_ADAPTER_T prAdapter); -+ -+VOID bowAssignSsid(IN PUINT_8 pucSsid, IN PUINT_8 pucSsidLen); -+ -+BOOLEAN bowValidateProbeReq(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, OUT PUINT_32 pu4ControlFlags); -+ -+VOID bowSendBeacon(IN P_ADAPTER_T prAdapter, ULONG ulParam); -+ -+VOID bowResponderScan(IN P_ADAPTER_T prAdapter); -+ -+VOID bowResponderScanDone(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); -+ -+VOID bowResponderCancelScan(IN P_ADAPTER_T prAdapter, IN BOOLEAN fgIsChannelExtention); -+ -+VOID bowResponderJoin(IN P_ADAPTER_T prAdapter, P_BSS_DESC_T prBssDesc); -+ -+VOID bowFsmRunEventJoinComplete(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); -+ -+VOID -+bowIndicationOfMediaStateToHost(IN P_ADAPTER_T prAdapter, -+ ENUM_PARAM_MEDIA_STATE_T eConnectionState, BOOLEAN fgDelayIndication); -+ -+VOID bowRunEventAAATxFail(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec); -+ -+WLAN_STATUS bowRunEventAAAComplete(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec); -+ -+WLAN_STATUS bowRunEventRxDeAuth(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN P_SW_RFB_T prSwRfb); -+ -+VOID bowDisconnectLink(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus); -+ -+BOOLEAN bowValidateAssocReq(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, OUT PUINT_16 pu2StatusCode); -+ -+BOOLEAN -+bowValidateAuth(IN P_ADAPTER_T prAdapter, -+ IN P_SW_RFB_T prSwRfb, IN PP_STA_RECORD_T pprStaRec, OUT PUINT_16 pu2StatusCode); -+ -+VOID bowRunEventChGrant(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); -+ -+VOID bowRequestCh(IN P_ADAPTER_T prAdapter); -+ -+VOID bowReleaseCh(IN P_ADAPTER_T prAdapter); -+ -+VOID bowChGrantedTimeout(IN P_ADAPTER_T prAdapter, IN ULONG ulParam); -+ -+BOOLEAN bowNotifyAllLinkDisconnected(IN P_ADAPTER_T prAdapter); -+ -+BOOLEAN bowCheckBowTableIfVaild(IN P_ADAPTER_T prAdapter, IN UINT_8 aucPeerAddress[6]); -+ -+BOOLEAN bowGetBowTableContent(IN P_ADAPTER_T prAdapter, IN UINT_8 ucBowTableIdx, OUT P_BOW_TABLE_T prBowTable); -+ -+BOOLEAN -+bowGetBowTableEntryByPeerAddress(IN P_ADAPTER_T prAdapter, IN UINT_8 aucPeerAddress[6], OUT PUINT_8 pucBowTableIdx); -+ -+BOOLEAN bowGetBowTableFreeEntry(IN P_ADAPTER_T prAdapter, OUT PUINT_8 pucBowTableIdx); -+ -+ENUM_BOW_DEVICE_STATE bowGetBowTableState(IN P_ADAPTER_T prAdapter, IN UINT_8 aucPeerAddress[6]); -+ -+BOOLEAN bowSetBowTableState(IN P_ADAPTER_T prAdapter, IN UINT_8 aucPeerAddress[6], IN ENUM_BOW_DEVICE_STATE eState); -+ -+BOOLEAN bowSetBowTableContent(IN P_ADAPTER_T prAdapter, IN UINT_8 ucBowTableIdx, IN P_BOW_TABLE_T prBowTable); -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif -+#endif /* _WLAN_BOW_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/wlan_lib.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/wlan_lib.h -new file mode 100644 -index 000000000000..87259397a93d ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/wlan_lib.h -@@ -0,0 +1,1001 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/wlan_lib.h#1 -+*/ -+ -+/*! \file "wlan_lib.h" -+ \brief The declaration of the functions of the wlanAdpater objects -+ -+ Detail description. -+*/ -+ -+/* -+** Log: wlan_lib.h -+ * -+ * 06 08 2012 eason.tsai -+ * NULL -+ * Nvram context covert from 6620 to 6628 for old 6620 meta tool -+ * -+ * 01 16 2012 cp.wu -+ * [MT6620 Wi-Fi][Driver] API and behavior modification for -+ * preferred band configuration with corresponding network configuration -+ * add wlanSetPreferBandByNetwork() for glue layer to invoke for -+ * setting preferred band configuration corresponding to network type. -+ * -+ * 01 05 2012 wh.su -+ * [WCXRP00001153] [MT6620 Wi-Fi][Driver] Adding the get_ch_list and set_tx_power proto type function -+ * Adding the related ioctl / wlan oid function to set the Tx power cfg. -+ * -+ * 10 03 2011 cp.wu -+ * [WCXRP00001022] [MT6628 Driver][Firmware Download] Add multi section independent download functionality -+ * eliminate win32 native data types. -+ * -+ * 10 03 2011 cp.wu -+ * [WCXRP00001022] [MT6628 Driver][Firmware Download] Add multi section independent download functionality -+ * add firmware download path in divided scatters. -+ * -+ * 10 03 2011 cp.wu -+ * [MT6628 Driver][Firmware Download] Add multi section independent download functionality -+ * add firmware downloading aggregated path. -+ * -+ * 09 20 2011 tsaiyuan.hsu -+ * [WCXRP00000931] [MT5931 Wi-Fi][DRV/FW] add swcr to disable roaming from driver -+ * change window registry of driver for roaming. -+ * -+ * 09 08 2011 cm.chang -+ * [WCXRP00000969] [MT6620 Wi-Fi][Driver][FW] Channel list for 5G band based on country code -+ * Use new fields ucChannelListMap and ucChannelListIndex in NVRAM -+ * -+ * 08 31 2011 cm.chang -+ * [WCXRP00000969] [MT6620 Wi-Fi][Driver][FW] Channel list for 5G band based on country code -+ * . -+ * -+ * 08 25 2011 chinghwa.yu -+ * [WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm -+ * Add DFS switch. -+ * -+ * 08 24 2011 chinghwa.yu -+ * [WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm -+ * Update RDD test mode cases. -+ * -+ * 08 15 2011 cp.wu -+ * [WCXRP00000913] [MT6620 Wi-Fi] create repository of source code dedicated for MT6620 E6 ASIC -+ * support to load different firmware image for E3/E4/E5 and E6 ASIC on win32 platforms. -+ * -+ * 08 02 2011 yuche.tsai -+ * [WCXRP00000896] [Volunteer Patch][WiFi Direct][Driver] GO with multiple client, -+ * TX deauth to a disconnecting device issue. -+ * Fix GO send deauth frame issue. -+ * -+ * 07 22 2011 jeffrey.chang -+ * [WCXRP00000864] [MT5931] Add command to adjust OSC stable time -+ * modify driver to set OSC stable time after f/w download -+ * -+ * 07 18 2011 chinghwa.yu -+ * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm -+ * Add CMD/Event for RDD and BWCS. -+ * -+ * 05 27 2011 cp.wu -+ * [WCXRP00000749] [MT6620 Wi-Fi][Driver] Add band edge tx power control to Wi-Fi NVRAM -+ * invoke CMD_ID_SET_EDGE_TXPWR_LIMIT when there is valid data exist in NVRAM content. -+ * -+ * 05 11 2011 cp.wu -+ * [WCXRP00000718] [MT6620 Wi-Fi] modify the behavior of setting tx power -+ * ACPI APIs migrate to wlan_lib.c for glue layer to invoke. -+ * -+ * 04 18 2011 cp.wu -+ * [WCXRP00000636] [WHQL][MT5931 Driver] 2c_PMHibernate (hang on 2h) -+ * 1) add API for glue layer to query ACPI state -+ * 2) Windows glue should not access to hardware after switched into D3 state -+ * -+ * 03 10 2011 cp.wu -+ * [WCXRP00000532] [MT6620 Wi-Fi][Driver] Migrate NVRAM configuration procedures from MT6620 E2 to MT6620 E3 -+ * deprecate configuration used by MT6620 E2 -+ * -+ * 01 27 2011 tsaiyuan.hsu -+ * [WCXRP00000392] [MT6620 Wi-Fi][Driver] Add Roaming Support -+ * add roaming fsm -+ * 1. not support 11r, only use strength of signal to determine roaming. -+ * 2. not enable CFG_SUPPORT_ROAMING until completion of full test. -+ * 3. in 6620, adopt work-around to avoid sign extension problem of cck of hw -+ * 4. assume that change of link quality in smooth way. -+ * -+ * 01 27 2011 george.huang -+ * [WCXRP00000355] [MT6620 Wi-Fi] Set WMM-PS related setting with qualifying AP capability -+ * Support current measure mode, assigned by registry (XP only). -+ * -+ * 01 24 2011 cp.wu -+ * [WCXRP00000382] [MT6620 Wi-Fi][Driver] Track forwarding packet number with notifying tx thread for serving -+ * 1. add an extra counter for tracking pending forward frames. -+ * 2. notify TX service thread as well when there is pending forward frame -+ * 3. correct build errors leaded by introduction of Wi-Fi direct separation module -+ * -+ * 01 10 2011 cp.wu -+ * [WCXRP00000351] [MT6620 Wi-Fi][Driver] remove from scanning result -+ * in OID handling layer when the corresponding BSS is disconnected due to beacon timeout -+ * remove from scanning result when the BSS is disconnected due to beacon timeout. -+ * -+ * 10 27 2010 george.huang -+ * [WCXRP00000127] [MT6620 Wi-Fi][Driver] Add a registry to -+ * disable Beacon Timeout function for SQA test by using E1 EVB -+ * Support registry option for disable beacon lost detection. -+ * -+ * 10 26 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check -+ * [WCXRP00000137] [MT6620 Wi-Fi] [FW] Support NIC capability query command -+ * 1) update NVRAM content template to ver 1.02 -+ * 2) add compile option for querying NIC capability (default: off) -+ * 3) modify AIS 5GHz support to run-time option, which could be turned on by registry or NVRAM setting -+ * 4) correct auto-rate compiler error under linux (treat warning as error) -+ * 5) simplify usage of NVRAM and REG_INFO_T -+ * 6) add version checking between driver and firmware -+ * -+ * 10 26 2010 eddie.chen -+ * [WCXRP00000134] [MT6620 Wi-Fi][Driver] Add a registry to enable auto rate for SQA test by using E1 EVB -+ * Add auto rate parameter in registry. -+ * -+ * 10 18 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check -+ * [WCXRP00000086] [MT6620 Wi-Fi][Driver] The mac address is all zero at android -+ * complete implementation of Android NVRAM access -+ * -+ * 10 08 2010 cp.wu -+ * [WCXRP00000084] [MT6620 Wi-Fi][Driver][FW] Add fixed rate support for distance test -+ * adding fixed rate support for distance test. (from registry setting) -+ * -+ * 10 06 2010 cp.wu -+ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning -+ * divide a single function into 2 part to surpress a weird compiler warning from gcc-4.4.0 -+ * -+ * 10 06 2010 cp.wu -+ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning -+ * code reorganization to improve isolation between GLUE and CORE layers. -+ * -+ * 10 05 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check -+ * load manufacture data when CFG_SUPPORT_NVRAM is set to 1 -+ * -+ * 09 24 2010 cp.wu -+ * [WCXRP00000057] [MT6620 Wi-Fi][Driver] Modify online scan to a run-time switchable feature -+ * Modify online scan as a run-time adjustable option (for Windows, in registry) -+ * -+ * 09 23 2010 cp.wu -+ * [WCXRP00000051] [MT6620 Wi-Fi][Driver] WHQL test fail in MAC address changed item -+ * use firmware reported mac address right after wlanAdapterStart() as permanent address -+ * -+ * 09 23 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check -+ * add skeleton for NVRAM integration -+ * -+ * 08 26 2010 yuche.tsai -+ * NULL -+ * Add AT GO test configure mode under WinXP. -+ * Please enable 1. CFG_ENABLE_WIFI_DIRECT, 2. CFG_TEST_WIFI_DIRECT_GO, 3. CFG_SUPPORT_AAA -+ * -+ * 08 25 2010 george.huang -+ * NULL -+ * . -+ * -+ * 07 21 2010 cp.wu -+ * -+ * 1) change BG_SCAN to ONLINE_SCAN for consistent term -+ * 2) only clear scanning result when scan is permitted to do -+ * -+ * 07 13 2010 cp.wu -+ * -+ * 1) MMPDUs are now sent to MT6620 by CMD queue for keeping strict order of 1X/MMPDU/CMD packets -+ * 2) integrate with qmGetFrameAction() for deciding which MMPDU/1X could pass checking for sending -+ * 2) enhance CMD_INFO_T descriptor number from 10 to 32 to avoid -+ * descriptor underflow under concurrent network operation -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 24 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 802.1x and bluetooth-over-Wi-Fi security frames are now delievered to firmware via command path instead of data path. -+ * -+ * 06 21 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * change MAC address updating logic. -+ * -+ * 06 21 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * simplify timer usage. -+ * -+ * 06 11 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) migrate assoc.c. -+ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness -+ * 3) add configuration options for CNM_MEM and RSN modules -+ * 4) add data path for management frames -+ * 5) eliminate rPacketInfo of MSDU_INFO_T -+ * -+ * 06 08 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * cnm_timer has been migrated. -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 05 20 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) integrate OID_GEN_NETWORK_LAYER_ADDRESSES with CMD_ID_SET_IP_ADDRESS -+ * 2) buffer statistics data for 2 seconds -+ * 3) use default value for adhoc parameters instead of 0 -+ * -+ * 05 12 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * add extra 64 adjustable parameters for CoEX scenario. -+ * -+ * 04 06 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * code refine: fgTestMode should be at adapter rather than glue due to the device/fw is also involved -+ * -+ * 04 06 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) for some OID, never do timeout expiration -+ * * 2) add 2 kal API for later integration -+ * -+ * 04 01 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * change to use WIFI_TCM_ALWAYS_ON as firmware image -+ * -+ * 03 31 2010 wh.su -+ * [WPD00003816][MT6620 Wi-Fi] Adding the security support -+ * modify the wapi related code for new driver's design. -+ * -+ * 03 22 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * always send CMD_NIC_POWER_CTRL packet when nic is being halted -+ * -+ * 03 12 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * add two option for ACK and ENCRYPTION for firmware download -+ * -+ * 02 24 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * separate wlanProcesQueuePacket() into 2 APIs upon request -+ * -+ * 02 23 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * add new API: wlanProcessQueuedPackets() -+ * -+ * 02 11 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1. add logic for firmware download -+ * * * 2. firmware image filename and start/load address are now retrieved from registry -+ * -+ * 02 10 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) remove unused function in nic_rx.c [which has been handled in que_mgt.c] -+ * * * * 2) firmware image length is now retrieved via NdisFileOpen -+ * * * * 3) firmware image is not structured by (P_IMG_SEC_HDR_T) anymore -+ * * * * 4) nicRxWaitResponse() revised -+ * * * * 5) another set of TQ counter default value is added for fw-download state -+ * * * * 6) Wi-Fi load address is now retrieved from registry too -+ * -+ * 02 08 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * prepare for implementing fw download logic -+ * -+ * 01 27 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1. eliminate improper variable in rHifInfo -+ * * * * * * * 2. block TX/ordinary OID when RF test mode is engaged -+ * * * * * * * 3. wait until firmware finish operation when entering into and leaving from RF test mode -+ * * * * * * * 4. correct some HAL implementation -+** \main\maintrunk.MT6620WiFiDriver_Prj\10 2009-12-10 16:39:55 GMT mtk02752 -+** eliminate unused API -+** \main\maintrunk.MT6620WiFiDriver_Prj\9 2009-10-13 21:58:41 GMT mtk01084 -+** update for new macro define -+** \main\maintrunk.MT6620WiFiDriver_Prj\8 2009-05-19 10:43:06 GMT mtk01461 -+** Add wlanReleasePendingOid() -+** \main\maintrunk.MT6620WiFiDriver_Prj\7 2009-04-13 16:38:44 GMT mtk01084 -+** add WIFI start function -+** \main\maintrunk.MT6620WiFiDriver_Prj\6 2009-04-08 16:51:14 GMT mtk01084 -+** Update for the image download part -+** \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-04-01 10:57:38 GMT mtk01461 -+** Add wlanSendLeftClusteredFrames() for SDIO_TX_ENHANCE -+** \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-03-23 00:31:02 GMT mtk01461 -+** Add declaration of FW Image download reference code -+** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-03-16 09:08:31 GMT mtk01461 -+** Update TX PATH API -+** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 20:12:04 GMT mtk01426 -+** Init for develop -+** -+*/ -+ -+#ifndef _WLAN_LIB_H -+#define _WLAN_LIB_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "CFG_Wifi_File.h" -+#include "rlm_domain.h" -+#include "wlan_typedef.h" -+ -+ -+extern BOOLEAN fgIsResetting; -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+#define MAX_NUM_GROUP_ADDR 32 /* max number of group addresses */ -+ -+#define TX_CS_TCP_UDP_GEN BIT(1) -+#define TX_CS_IP_GEN BIT(0) -+ -+#define CSUM_OFFLOAD_EN_TX_TCP BIT(0) -+#define CSUM_OFFLOAD_EN_TX_UDP BIT(1) -+#define CSUM_OFFLOAD_EN_TX_IP BIT(2) -+#define CSUM_OFFLOAD_EN_RX_TCP BIT(3) -+#define CSUM_OFFLOAD_EN_RX_UDP BIT(4) -+#define CSUM_OFFLOAD_EN_RX_IPv4 BIT(5) -+#define CSUM_OFFLOAD_EN_RX_IPv6 BIT(6) -+#define CSUM_OFFLOAD_EN_TX_MASK BITS(0, 2) -+#define CSUM_OFFLOAD_EN_ALL BITS(0, 6) -+ -+/* TCP, UDP, IP Checksum */ -+#define RX_CS_TYPE_UDP BIT(7) -+#define RX_CS_TYPE_TCP BIT(6) -+#define RX_CS_TYPE_IPv6 BIT(5) -+#define RX_CS_TYPE_IPv4 BIT(4) -+ -+#define RX_CS_STATUS_UDP BIT(3) -+#define RX_CS_STATUS_TCP BIT(2) -+#define RX_CS_STATUS_IP BIT(0) -+ -+#define CSUM_NOT_SUPPORTED 0x0 -+ -+#define TXPWR_USE_PDSLOPE 0 -+ -+/* NVRAM error code definitions */ -+#define NVRAM_ERROR_VERSION_MISMATCH BIT(1) -+#define NVRAM_ERROR_INVALID_TXPWR BIT(2) -+#define NVRAM_ERROR_INVALID_DPD BIT(3) -+#define NVRAM_ERROR_INVALID_MAC_ADDR BIT(4) -+#if CFG_SUPPORT_PWR_LIMIT_COUNTRY -+#define NVRAM_POWER_LIMIT_TABLE_INVALID BIT(5) -+#endif -+ -+#define NUM_TC_RESOURCE_TO_STATISTICS 4 -+ -+#define WLAN_CFG_ARGV_MAX 8 -+#define WLAN_CFG_ENTRY_NUM_MAX 128 -+#define WLAN_CFG_KEY_LEN_MAX 32 /* include \x00 EOL */ -+#define WLAN_CFG_VALUE_LEN_MAX 32 /* include \x00 EOL */ -+#define WLAN_CFG_FLAG_SKIP_CB BIT(0) -+#define WLAN_CFG_FILE_BUF_SIZE 2048 -+ -+#define WLAN_CFG_SET_CHIP_LEN_MAX 10 -+#define WLAN_CFG_SET_DEBUG_LEVEL_LEN_MAX 10 -+#define WLAN_CFG_SET_SW_CTRL_LEN_MAX 10 -+ -+#define WLAN_OID_TIMEOUT_THRESHOLD 2000 /* OID timeout (in ms) */ -+#define WLAN_OID_TIMEOUT_THRESHOLD_IN_RESETTING 300 /* OID timeout during chip-resetting (in ms) */ -+ -+#define WLAN_OID_NO_ACK_THRESHOLD 3 -+ -+#define WLAN_TX_THREAD_TASK_PRIORITY 0 /* If not setting the priority, 0 is the default */ -+#define WLAN_TX_THREAD_TASK_NICE (-10) /* If not setting the nice, -10 is the default */ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+typedef WLAN_STATUS(*PFN_OID_HANDLER_FUNC) (IN P_ADAPTER_T prAdapter, -+ IN PVOID pvBuf, IN UINT_32 u4BufLen, OUT PUINT_32 pu4OutInfoLen); -+ -+typedef enum _ENUM_CSUM_TYPE_T { -+ CSUM_TYPE_IPV4, -+ CSUM_TYPE_IPV6, -+ CSUM_TYPE_TCP, -+ CSUM_TYPE_UDP, -+ CSUM_TYPE_NUM -+} ENUM_CSUM_TYPE_T, *P_ENUM_CSUM_TYPE_T; -+ -+typedef enum _ENUM_CSUM_RESULT_T { -+ CSUM_RES_NONE, -+ CSUM_RES_SUCCESS, -+ CSUM_RES_FAILED, -+ CSUM_RES_NUM -+} ENUM_CSUM_RESULT_T, *P_ENUM_CSUM_RESULT_T; -+ -+typedef enum _ENUM_PHY_MODE_T { -+ ENUM_PHY_2G4_CCK, -+ ENUM_PHY_2G4_OFDM_BPSK, -+ ENUM_PHY_2G4_OFDM_QPSK, -+ ENUM_PHY_2G4_OFDM_16QAM, -+ ENUM_PHY_2G4_OFDM_48M, -+ ENUM_PHY_2G4_OFDM_54M, -+ ENUM_PHY_2G4_HT20_BPSK, -+ ENUM_PHY_2G4_HT20_QPSK, -+ ENUM_PHY_2G4_HT20_16QAM, -+ ENUM_PHY_2G4_HT20_MCS5, -+ ENUM_PHY_2G4_HT20_MCS6, -+ ENUM_PHY_2G4_HT20_MCS7, -+ ENUM_PHY_2G4_HT40_BPSK, -+ ENUM_PHY_2G4_HT40_QPSK, -+ ENUM_PHY_2G4_HT40_16QAM, -+ ENUM_PHY_2G4_HT40_MCS5, -+ ENUM_PHY_2G4_HT40_MCS6, -+ ENUM_PHY_2G4_HT40_MCS7, -+ ENUM_PHY_5G_OFDM_BPSK, -+ ENUM_PHY_5G_OFDM_QPSK, -+ ENUM_PHY_5G_OFDM_16QAM, -+ ENUM_PHY_5G_OFDM_48M, -+ ENUM_PHY_5G_OFDM_54M, -+ ENUM_PHY_5G_HT20_BPSK, -+ ENUM_PHY_5G_HT20_QPSK, -+ ENUM_PHY_5G_HT20_16QAM, -+ ENUM_PHY_5G_HT20_MCS5, -+ ENUM_PHY_5G_HT20_MCS6, -+ ENUM_PHY_5G_HT20_MCS7, -+ ENUM_PHY_5G_HT40_BPSK, -+ ENUM_PHY_5G_HT40_QPSK, -+ ENUM_PHY_5G_HT40_16QAM, -+ ENUM_PHY_5G_HT40_MCS5, -+ ENUM_PHY_5G_HT40_MCS6, -+ ENUM_PHY_5G_HT40_MCS7, -+ ENUM_PHY_MODE_NUM -+} ENUM_PHY_MODE_T, *P_ENUM_PHY_MODE_T; -+ -+typedef enum _ENUM_POWER_SAVE_POLL_MODE_T { -+ ENUM_POWER_SAVE_POLL_DISABLE, -+ ENUM_POWER_SAVE_POLL_LEGACY_NULL, -+ ENUM_POWER_SAVE_POLL_QOS_NULL, -+ ENUM_POWER_SAVE_POLL_NUM -+} ENUM_POWER_SAVE_POLL_MODE_T, *P_ENUM_POWER_SAVE_POLL_MODE_T; -+ -+typedef enum _ENUM_AC_TYPE_T { -+ ENUM_AC_TYPE_AC0, -+ ENUM_AC_TYPE_AC1, -+ ENUM_AC_TYPE_AC2, -+ ENUM_AC_TYPE_AC3, -+ ENUM_AC_TYPE_AC4, -+ ENUM_AC_TYPE_AC5, -+ ENUM_AC_TYPE_AC6, -+ ENUM_AC_TYPE_BMC, -+ ENUM_AC_TYPE_NUM -+} ENUM_AC_TYPE_T, *P_ENUM_AC_TYPE_T; -+ -+typedef enum _ENUM_ADV_AC_TYPE_T { -+ ENUM_ADV_AC_TYPE_RX_NSW, -+ ENUM_ADV_AC_TYPE_RX_PTA, -+ ENUM_ADV_AC_TYPE_RX_SP, -+ ENUM_ADV_AC_TYPE_TX_PTA, -+ ENUM_ADV_AC_TYPE_TX_RSP, -+ ENUM_ADV_AC_TYPE_NUM -+} ENUM_ADV_AC_TYPE_T, *P_ENUM_ADV_AC_TYPE_T; -+ -+typedef enum _ENUM_REG_CH_MAP_T { -+ REG_CH_MAP_COUNTRY_CODE, -+ REG_CH_MAP_TBL_IDX, -+ REG_CH_MAP_CUSTOMIZED, -+ REG_CH_MAP_NUM -+} ENUM_REG_CH_MAP_T, *P_ENUM_REG_CH_MAP_T; -+ -+#define CHIP_CONFIG_RESP_SIZE 320 -+enum { -+ CHIP_CONFIG_TYPE_WO_RESPONSE = 0x00, -+ CHIP_CONFIG_TYPE_MEM8 = 0x01, -+ CHIP_CONFIG_TYPE_MEM32 = 0x02, -+ CHIP_CONFIG_TYPE_ASCII = 0x03, -+ CHIP_CONFIG_TYPE_BINARY = 0x04, -+ CHIP_CONFIG_TYPE_DRV_PASSTHROUGH = 0x05, -+ CHIP_CONFIG_TYPE_END -+}; -+ -+typedef struct _SET_TXPWR_CTRL_T { -+ INT_8 c2GLegacyStaPwrOffset; /* Unit: 0.5dBm, default: 0 */ -+ INT_8 c2GHotspotPwrOffset; -+ INT_8 c2GP2pPwrOffset; -+ INT_8 c2GBowPwrOffset; -+ INT_8 c5GLegacyStaPwrOffset; /* Unit: 0.5dBm, default: 0 */ -+ INT_8 c5GHotspotPwrOffset; -+ INT_8 c5GP2pPwrOffset; -+ INT_8 c5GBowPwrOffset; -+ UINT_8 ucConcurrencePolicy; /* TX power policy when concurrence -+ in the same channel -+ 0: Highest power has priority -+ 1: Lowest power has priority */ -+ INT_8 acReserved1[3]; /* Must be zero */ -+ -+ /* Power limit by channel for all data rates */ -+ INT_8 acTxPwrLimit2G[14]; /* Channel 1~14, Unit: 0.5dBm */ -+ INT_8 acTxPwrLimit5G[4]; /* UNII 1~4 */ -+ INT_8 acReserved2[2]; /* Must be zero */ -+} SET_TXPWR_CTRL_T, *P_SET_TXPWR_CTRL_T; -+ -+/* For storing driver initialization value from glue layer */ -+typedef struct _REG_INFO_T { -+ UINT_32 u4SdBlockSize; /* SDIO block size */ -+ UINT_32 u4SdBusWidth; /* SDIO bus width. 1 or 4 */ -+ UINT_32 u4SdClockRate; /* SDIO clock rate. (in unit of HZ) */ -+ UINT_32 u4StartAddress; /* Starting address of Wi-Fi Firmware */ -+ UINT_32 u4LoadAddress; /* Load address of Wi-Fi Firmware */ -+ UINT_16 aucFwImgFilename[65]; /* Firmware filename */ -+ UINT_16 aucFwImgFilenameE6[65]; /* Firmware filename for E6 */ -+ UINT_32 u4StartFreq; /* Start Frequency for Ad-Hoc network : in unit of KHz */ -+ UINT_32 u4AdhocMode; /* Default mode for Ad-Hoc network : ENUM_PARAM_AD_HOC_MODE_T */ -+ UINT_32 u4RddStartFreq; -+ UINT_32 u4RddStopFreq; -+ UINT_32 u4RddTestMode; -+ UINT_32 u4RddShutFreq; -+ UINT_32 u4RddDfs; -+ INT_32 i4HighRssiThreshold; -+ INT_32 i4MediumRssiThreshold; -+ INT_32 i4LowRssiThreshold; -+ INT_32 au4TxPriorityTag[ENUM_AC_TYPE_NUM]; -+ INT_32 au4RxPriorityTag[ENUM_AC_TYPE_NUM]; -+ INT_32 au4AdvPriorityTag[ENUM_ADV_AC_TYPE_NUM]; -+ UINT_32 u4FastPSPoll; -+ UINT_32 u4PTA; /* 0: disable, 1: enable */ -+ UINT_32 u4TXLimit; /* 0: disable, 1: enable */ -+ UINT_32 u4SilenceWindow; /* range: 100 - 625, unit: us */ -+ UINT_32 u4TXLimitThreshold; /* range: 250 - 1250, unit: us */ -+ UINT_32 u4PowerMode; -+ UINT_32 fgEnArpFilter; -+ UINT_32 u4PsCurrentMeasureEn; -+ UINT_32 u4UapsdAcBmp; -+ UINT_32 u4MaxSpLen; -+ UINT_32 fgDisOnlineScan; /* 0: enable online scan, non-zero: disable online scan */ -+ UINT_32 fgDisBcnLostDetection; /* 0: enable online scan, non-zero: disable online scan */ -+ UINT_32 u4FixedRate; /* 0: automatic, non-zero: fixed rate */ -+ UINT_32 u4ArSysParam0; -+ UINT_32 u4ArSysParam1; -+ UINT_32 u4ArSysParam2; -+ UINT_32 u4ArSysParam3; -+ UINT_32 fgDisRoaming; /* 0:enable roaming 1:disable */ -+ -+ /* NVRAM - MP Data -START- */ -+ UINT_8 aucMacAddr[6]; -+ UINT_16 au2CountryCode[4]; /* Country code (in ISO 3166-1 expression, ex: "US", "TW") */ -+ TX_PWR_PARAM_T rTxPwr; -+ UINT_8 aucEFUSE[144]; -+ UINT_8 ucTxPwrValid; -+ UINT_8 ucSupport5GBand; -+ UINT_8 fg2G4BandEdgePwrUsed; -+ INT_8 cBandEdgeMaxPwrCCK; -+ INT_8 cBandEdgeMaxPwrOFDM20; -+ INT_8 cBandEdgeMaxPwrOFDM40; -+ ENUM_REG_CH_MAP_T eRegChannelListMap; -+ UINT_8 ucRegChannelListIndex; -+ DOMAIN_INFO_ENTRY rDomainInfo; -+ /* NVRAM - MP Data -END- */ -+ -+ /* NVRAM - Functional Data -START- */ -+ UINT_8 uc2G4BwFixed20M; -+ UINT_8 uc5GBwFixed20M; -+ UINT_8 ucEnable5GBand; -+ UINT_8 uc2GRssiCompensation; -+ UINT_8 uc5GRssiCompensation; -+ UINT_8 fgRssiCompensationValidbit; -+ UINT_8 ucRxAntennanumber; -+ /* NVRAM - Functional Data -END- */ -+ -+} REG_INFO_T, *P_REG_INFO_T; -+ -+/* for divided firmware loading */ -+typedef struct _FWDL_SECTION_INFO_T { -+ UINT_32 u4Offset; -+ UINT_32 u4Reserved; -+ UINT_32 u4Length; -+ UINT_32 u4DestAddr; -+} FWDL_SECTION_INFO_T, *P_FWDL_SECTION_INFO_T; -+ -+typedef struct _FIRMWARE_DIVIDED_DOWNLOAD_T { -+ UINT_32 u4Signature; -+ UINT_32 u4CRC; /* CRC calculated without first 8 bytes included */ -+ UINT_32 u4NumOfEntries; -+ UINT_32 u4Reserved; -+ FWDL_SECTION_INFO_T arSection[]; -+} FIRMWARE_DIVIDED_DOWNLOAD_T, *P_FIRMWARE_DIVIDED_DOWNLOAD_T; -+ -+typedef struct _PARAM_MCR_RW_STRUCT_T { -+ UINT_32 u4McrOffset; -+ UINT_32 u4McrData; -+} PARAM_MCR_RW_STRUCT_T, *P_PARAM_MCR_RW_STRUCT_T; -+ -+typedef struct _PARAM_GET_STA_STATISTICS { -+ UINT_8 ucInvalid; -+ UINT_8 ucVersion; -+ /* Per-STA statistic */ -+ UINT_8 aucMacAddr[MAC_ADDR_LEN]; -+ UINT_32 u4LinkScore; -+ UINT_32 u4Flag; -+ -+ /* From FW */ -+ UINT_8 ucPer; /* base: 128 */ -+ UINT_8 ucRcpi; -+ UINT_32 u4PhyMode; -+ UINT_16 u2LinkSpeed; /* unit is 0.5 Mbits */ -+ -+ UINT_32 u4TxFailCount; -+ UINT_32 u4TxLifeTimeoutCount; -+ UINT_32 u4TxAverageAirTime; -+ -+ /* From driver */ -+ UINT_32 u4TxTotalCount; -+ UINT_32 u4TxExceedThresholdCount; -+ UINT_32 u4TxAverageProcessTime; -+ -+ UINT_32 u4TxMaxTime; -+ UINT_32 u4TxMaxHifTime; -+ UINT_32 u4TxAverageHifTime; -+ -+ /* -+ * How many packages Enqueue/Deqeue during statistics interval -+ */ -+ UINT_32 u4EnqueueCounter; -+ UINT_32 u4DequeueCounter; -+ -+ UINT_32 u4EnqueueStaCounter; -+ UINT_32 u4DequeueStaCounter; -+ -+ UINT_32 IsrCnt; -+ UINT_32 IsrPassCnt; -+ UINT_32 TaskIsrCnt; -+ -+ UINT_32 IsrAbnormalCnt; -+ UINT_32 IsrSoftWareCnt; -+ UINT_32 IsrRxCnt; -+ UINT_32 IsrTxCnt; -+ -+ UINT_32 au4TcResourceEmptyCount[NUM_TC_RESOURCE_TO_STATISTICS]; -+ UINT_32 au4DequeueNoTcResource[NUM_TC_RESOURCE_TO_STATISTICS]; -+ UINT_32 au4TcResourceBackCount[NUM_TC_RESOURCE_TO_STATISTICS]; -+ -+ UINT_32 au4TcResourceUsedCount[NUM_TC_RESOURCE_TO_STATISTICS]; -+ UINT_32 au4TcResourceWantedCount[NUM_TC_RESOURCE_TO_STATISTICS]; -+ -+ UINT_32 au4TcQueLen[NUM_TC_RESOURCE_TO_STATISTICS]; -+ /* Global queue management statistic */ -+ UINT_32 au4TcAverageQueLen[NUM_TC_RESOURCE_TO_STATISTICS]; -+ UINT_32 au4TcCurrentQueLen[NUM_TC_RESOURCE_TO_STATISTICS]; -+ -+ /* Reserved fields */ -+ UINT_8 au4Reserved[32]; -+} PARAM_GET_STA_STA_STATISTICS, *P_PARAM_GET_STA_STATISTICS; -+ -+#if CFG_AUTO_CHANNEL_SEL_SUPPORT -+typedef enum _ENUM_TESTMODE_AVAILABLE_CHAN_ATTR { -+ NL80211_TESTMODE_AVAILABLE_CHAN_INVALID = 0, -+ NL80211_TESTMODE_AVAILABLE_CHAN_2G_BASE_1, -+ NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_34, -+ NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_149, -+ NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_184, -+ -+ NL80211_TESTMODE_AVAILABLE_CHAN_NUM, -+} ENUM_TESTMODE_AVAILABLE_CHAN_ATTR; -+ -+typedef struct _LTE_SAFE_CH_INFO_T { -+ UINT_32 au4SafeChannelBitmask[NL80211_TESTMODE_AVAILABLE_CHAN_NUM - 1]; -+} LTE_SAFE_CH_INFO_T, *P_CMD_LTE_SAFE_CH_INFO_T; -+ -+ /* Record Each CH Load */ -+typedef struct _PARAM_CHN_LOAD_INFO { -+ /* Per-CHN Load */ -+ UINT_32 u4Flag; -+ -+ UINT_8 ucChannel; -+ UINT_16 u2ChannelLoad; -+ UINT_8 au4Reserved[1]; -+ -+ UINT_16 u2APNum; -+ UINT_16 u2APNumTmpCountingBuf; -+ -+ /* Reserved fields */ -+ UINT_8 au4Reserved1[8]; -+} PARAM_CHN_LOAD_INFO, *P_PARAM_CHN_LOAD_INFO; -+ -+typedef struct _PARAM_GET_CHN_LOAD { -+ LTE_SAFE_CH_INFO_T rLteSafeChnList; -+ PARAM_CHN_LOAD_INFO rEachChnLoad[MAX_AUTO_CHAL_NUM]; -+ BOOLEAN fgDataReadyBit; -+ UINT_8 au4Reserved1[3]; -+} PARAM_GET_CHN_LOAD, *P_PARAM_GET_CHN_LOAD; -+ -+typedef struct _PARAM_PREFER_CHN_INFO { -+ -+ UINT_8 ucChannel; -+ UINT_16 u2APNum; -+ UINT_8 au4Reserved1[1]; -+} PARAM_PREFER_CHN_INFO, *P_PARAM_PREFER_CHN_INFO; -+ -+typedef struct _PARAM_GET_LTE_MODE { -+ /* Event Body */ -+ UINT_8 ucVersion; -+ UINT_8 aucReserved1[3]; -+ UINT_32 u4Flags; /* Bit0: valid */ -+ -+ LTE_SAFE_CH_INFO_T LTE_MODE; -+ UINT_8 aucReserved4[3]; -+ -+ UINT_8 aucReserved[4]; -+ -+} PARAM_GET_LTE_MODE, *P_PARAM_GET_LTE_MODE; -+ -+#endif -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+#define BUILD_SIGN(ch0, ch1, ch2, ch3) \ -+ ((UINT_32)(UINT_8)(ch0) | ((UINT_32)(UINT_8)(ch1) << 8) | \ -+ ((UINT_32)(UINT_8)(ch2) << 16) | ((UINT_32)(UINT_8)(ch3) << 24)) -+ -+#define MTK_WIFI_SIGNATURE BUILD_SIGN('M', 'T', 'K', 'W') -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+P_ADAPTER_T wlanAdapterCreate(IN P_GLUE_INFO_T prGlueInfo); -+ -+VOID wlanAdapterDestroy(IN P_ADAPTER_T prAdapter); -+ -+VOID wlanCardEjected(IN P_ADAPTER_T prAdapter); -+ -+VOID wlanIST(IN P_ADAPTER_T prAdapter); -+ -+BOOLEAN wlanISR(IN P_ADAPTER_T prAdapter, IN BOOLEAN fgGlobalIntrCtrl); -+ -+WLAN_STATUS wlanProcessCommandQueue(IN P_ADAPTER_T prAdapter, IN P_QUE_T prCmdQue); -+ -+WLAN_STATUS wlanSendCommand(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo); -+ -+VOID wlanReleaseCommand(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo); -+ -+VOID wlanReleasePendingOid(IN P_ADAPTER_T prAdapter, IN ULONG ulData); -+ -+VOID wlanReleasePendingCMDbyNetwork(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkType); -+ -+VOID wlanReturnPacket(IN P_ADAPTER_T prAdapter, IN PVOID pvPacket); -+ -+VOID wlanReturnIndicatedPacketsTimeOut(IN P_ADAPTER_T prAdapter, IN ULONG ulData); -+ -+WLAN_STATUS -+wlanQueryInformation(IN P_ADAPTER_T prAdapter, -+ IN PFN_OID_HANDLER_FUNC pfOidQryHandler, -+ IN PVOID pvInfoBuf, IN UINT_32 u4InfoBufLen, OUT PUINT_32 pu4QryInfoLen); -+ -+WLAN_STATUS -+wlanSetInformation(IN P_ADAPTER_T prAdapter, -+ IN PFN_OID_HANDLER_FUNC pfOidSetHandler, -+ IN PVOID pvInfoBuf, IN UINT_32 u4InfoBufLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanAdapterStart(IN P_ADAPTER_T prAdapter, -+ IN P_REG_INFO_T prRegInfo, IN PVOID pvFwImageMapFile, IN UINT_32 u4FwImageFileLength); -+ -+WLAN_STATUS wlanAdapterStop(IN P_ADAPTER_T prAdapter); -+ -+#if CFG_SUPPORT_WAPI -+BOOLEAN wlanQueryWapiMode(IN P_ADAPTER_T prAdapter); -+#endif -+ -+VOID wlanReturnRxPacket(IN PVOID pvAdapter, IN PVOID pvPacket); -+ -+VOID wlanRxSetBroadcast(IN P_ADAPTER_T prAdapter, IN BOOLEAN fgEnableBroadcast); -+ -+BOOLEAN wlanIsHandlerNeedHwAccess(IN PFN_OID_HANDLER_FUNC pfnOidHandler, IN BOOLEAN fgSetInfo); -+ -+VOID wlanSetPromiscuousMode(IN P_ADAPTER_T prAdapter, IN BOOLEAN fgEnablePromiscuousMode); -+ -+#if CFG_ENABLE_FW_DOWNLOAD -+#if CFG_ENABLE_FW_DOWNLOAD_AGGREGATION -+WLAN_STATUS -+wlanImageSectionDownloadAggregated(IN P_ADAPTER_T prAdapter, -+ IN UINT_32 u4DestAddr, IN UINT_32 u4ImgSecSize, IN PUINT_8 pucImgSecBuf); -+#endif -+ -+WLAN_STATUS -+wlanImageSectionDownload(IN P_ADAPTER_T prAdapter, -+ IN UINT_32 u4DestAddr, IN UINT_32 u4ImgSecSize, IN PUINT_8 pucImgSecBuf); -+ -+#if !CFG_ENABLE_FW_DOWNLOAD_ACK -+WLAN_STATUS wlanImageQueryStatus(IN P_ADAPTER_T prAdapter); -+#else -+WLAN_STATUS wlanImageSectionDownloadStatus(IN P_ADAPTER_T prAdapter, IN UINT_8 ucCmdSeqNum); -+#endif -+ -+WLAN_STATUS wlanConfigWifiFunc(IN P_ADAPTER_T prAdapter, IN BOOLEAN fgEnable, IN UINT_32 u4StartAddress); -+ -+UINT_32 wlanCRC32(PUINT_8 buf, UINT_32 len); -+ -+#endif -+ -+WLAN_STATUS wlanSendNicPowerCtrlCmd(IN P_ADAPTER_T prAdapter, IN UINT_8 ucPowerMode); -+ -+BOOLEAN wlanIsHandlerAllowedInRFTest(IN PFN_OID_HANDLER_FUNC pfnOidHandler, IN BOOLEAN fgSetInfo); -+ -+WLAN_STATUS wlanProcessQueuedSwRfb(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfbListHead); -+ -+WLAN_STATUS wlanProcessQueuedMsduInfo(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfoListHead); -+ -+BOOLEAN wlanoidTimeoutCheck(IN P_ADAPTER_T prAdapter, IN PFN_OID_HANDLER_FUNC pfnOidHandler); -+ -+VOID wlanoidClearTimeoutCheck(IN P_ADAPTER_T prAdapter); -+ -+WLAN_STATUS wlanUpdateNetworkAddress(IN P_ADAPTER_T prAdapter); -+ -+BOOLEAN wlanQueryTestMode(IN P_ADAPTER_T prAdapter); -+ -+/* Security Frame Handling */ -+BOOLEAN wlanProcessSecurityFrame(IN P_ADAPTER_T prAdapter, IN P_NATIVE_PACKET prPacket); -+ -+VOID wlanSecurityFrameTxDone(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); -+ -+VOID wlanSecurityFrameTxTimeout(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo); -+ -+/*----------------------------------------------------------------------------*/ -+/* OID/IOCTL Handling */ -+/*----------------------------------------------------------------------------*/ -+VOID wlanClearScanningResult(IN P_ADAPTER_T prAdapter); -+ -+VOID wlanClearBssInScanningResult(IN P_ADAPTER_T prAdapter, IN PUINT_8 arBSSID); -+ -+#if CFG_TEST_WIFI_DIRECT_GO -+VOID wlanEnableP2pFunction(IN P_ADAPTER_T prAdapter); -+ -+VOID wlanEnableATGO(IN P_ADAPTER_T prAdapter); -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/* Address Retrieve by Polling */ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS wlanQueryPermanentAddress(IN P_ADAPTER_T prAdapter); -+ -+/*----------------------------------------------------------------------------*/ -+/* NIC Capability Retrieve by Polling */ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS wlanQueryNicCapability(IN P_ADAPTER_T prAdapter); -+ -+/*----------------------------------------------------------------------------*/ -+/* NIC Capability Retrieve by Polling */ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS wlanQueryDebugCode(IN P_ADAPTER_T prAdapter); -+ -+/*----------------------------------------------------------------------------*/ -+/* Compiler Flags Retrieve by Polling */ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS wlanQueryCompileFlags(IN P_ADAPTER_T prAdapter); -+ -+/*----------------------------------------------------------------------------*/ -+/* PD MCR Retrieve by Polling */ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS wlanQueryPdMcr(IN P_ADAPTER_T prAdapter, IN P_PARAM_MCR_RW_STRUCT_T prMcrRdInfo); -+/*----------------------------------------------------------------------------*/ -+/* Loading Manufacture Data */ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS wlanLoadManufactureData(IN P_ADAPTER_T prAdapter, IN P_REG_INFO_T prRegInfo); -+ -+/*----------------------------------------------------------------------------*/ -+/* Media Stream Mode */ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN wlanResetMediaStreamMode(IN P_ADAPTER_T prAdapter); -+ -+/*----------------------------------------------------------------------------*/ -+/* Timer Timeout Check (for Glue Layer) */ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS wlanTimerTimeoutCheck(IN P_ADAPTER_T prAdapter); -+ -+/*----------------------------------------------------------------------------*/ -+/* Mailbox Message Check (for Glue Layer) */ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS wlanProcessMboxMessage(IN P_ADAPTER_T prAdapter); -+ -+/*----------------------------------------------------------------------------*/ -+/* TX Pending Packets Handling (for Glue Layer) */ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS wlanEnqueueTxPacket(IN P_ADAPTER_T prAdapter, IN P_NATIVE_PACKET prNativePacket); -+ -+WLAN_STATUS wlanFlushTxPendingPackets(IN P_ADAPTER_T prAdapter); -+ -+WLAN_STATUS wlanTxPendingPackets(IN P_ADAPTER_T prAdapter, IN OUT PBOOLEAN pfgHwAccess); -+ -+/*----------------------------------------------------------------------------*/ -+/* Low Power Acquire/Release (for Glue Layer) */ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS wlanAcquirePowerControl(IN P_ADAPTER_T prAdapter); -+ -+WLAN_STATUS wlanReleasePowerControl(IN P_ADAPTER_T prAdapter); -+ -+/*----------------------------------------------------------------------------*/ -+/* Pending Packets Number Reporting (for Glue Layer) */ -+/*----------------------------------------------------------------------------*/ -+UINT_32 wlanGetTxPendingFrameCount(IN P_ADAPTER_T prAdapter); -+ -+/*----------------------------------------------------------------------------*/ -+/* ACPI state inquiry (for Glue Layer) */ -+/*----------------------------------------------------------------------------*/ -+ENUM_ACPI_STATE_T wlanGetAcpiState(IN P_ADAPTER_T prAdapter); -+ -+VOID wlanSetAcpiState(IN P_ADAPTER_T prAdapter, IN ENUM_ACPI_STATE_T ePowerState); -+ -+VOID wlanDefTxPowerCfg(IN P_ADAPTER_T prAdapter); -+ -+/*----------------------------------------------------------------------------*/ -+/* get ECO version from Revision ID register (for Win32) */ -+/*----------------------------------------------------------------------------*/ -+UINT_8 wlanGetEcoVersion(IN P_ADAPTER_T prAdapter); -+ -+/*----------------------------------------------------------------------------*/ -+/* set preferred band configuration corresponding to network type */ -+/*----------------------------------------------------------------------------*/ -+VOID -+wlanSetPreferBandByNetwork(IN P_ADAPTER_T prAdapter, IN ENUM_BAND_T eBand, IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex); -+ -+/*----------------------------------------------------------------------------*/ -+/* get currently operating channel information */ -+/*----------------------------------------------------------------------------*/ -+UINT_8 wlanGetChannelNumberByNetwork(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex); -+ -+/*----------------------------------------------------------------------------*/ -+/* get BSS Descriptor information */ -+/*----------------------------------------------------------------------------*/ -+P_BSS_DESC_T wlanGetTargetBssDescByNetwork(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex); -+ -+/*----------------------------------------------------------------------------*/ -+/* check for system configuration to generate message on scan list */ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS wlanCheckSystemConfiguration(IN P_ADAPTER_T prAdapter); -+ -+/*----------------------------------------------------------------------------*/ -+/* query sta statistics information from driver and firmware */ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryStaStatistics(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS wlanCfgParseArgument(CHAR *cmdLine, INT_32 *argc, CHAR *argv[]); -+ -+P_WLAN_CFG_ENTRY_T wlanCfgGetEntry(IN P_ADAPTER_T prAdapter, const PCHAR pucKey); -+ -+WLAN_STATUS -+wlanCfgGet(IN P_ADAPTER_T prAdapter, const PCHAR pucKey, PCHAR pucValue, PCHAR pucValueDef, UINT_32 u4Flags); -+ -+UINT_32 wlanCfgGetUint32(IN P_ADAPTER_T prAdapter, const PCHAR pucKey, UINT_32 u4ValueDef); -+ -+INT_32 wlanCfgGetInt32(IN P_ADAPTER_T prAdapter, const PCHAR pucKey, INT_32 i4ValueDef); -+ -+WLAN_STATUS wlanCfgSetUint32(IN P_ADAPTER_T prAdapter, const PCHAR pucKey, UINT_32 u4Value); -+ -+WLAN_STATUS wlanCfgSet(IN P_ADAPTER_T prAdapter, const PCHAR pucKey, PCHAR pucValue, UINT_32 u4Flags); -+ -+WLAN_STATUS -+wlanCfgSetCb(IN P_ADAPTER_T prAdapter, const PCHAR pucKey, WLAN_CFG_SET_CB pfSetCb, void *pPrivate, UINT_32 u4Flags); -+ -+#if CFG_SUPPORT_CFG_FILE -+WLAN_STATUS wlanCfgInit(IN P_ADAPTER_T prAdapter, PUINT_8 pucConfigBuf, UINT_32 u4ConfigBufLen, UINT_32 u4Flags); -+ -+VOID wlanCfgApply(IN P_ADAPTER_T prAdapter); -+#endif /* CFG_SUPPORT_CFG_FILE */ -+ -+extern VOID mtk_wcn_wmt_set_wifi_ver(UINT_32 Value); -+ -+#endif /* _WLAN_LIB_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/wlan_oid.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/wlan_oid.h -new file mode 100644 -index 000000000000..45919df996e9 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/wlan_oid.h -@@ -0,0 +1,1715 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/wlan_oid.h#2 -+*/ -+ -+/*! \file "wlan_oid.h" -+ \brief This file contains the declairation file of the WLAN OID processing routines -+ of Windows driver for MediaTek Inc. 802.11 Wireless LAN Adapters. -+*/ -+ -+/* -+** Log: wlan_oid.h -+ * -+ * 03 02 2012 terry.wu -+ * NULL -+ * Sync CFG80211 modification from branch 2,2. -+ * -+ * 01 05 2012 wh.su -+ * [WCXRP00001153] [MT6620 Wi-Fi][Driver] Adding the get_ch_list and set_tx_power proto type function -+ * Adding the related ioctl / wlan oid function to set the Tx power cfg. -+ * -+ * 07 18 2011 chinghwa.yu -+ * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm -+ * Add CMD/Event for RDD and BWCS. -+ * -+ * 03 22 2011 george.huang -+ * [WCXRP00000504] [MT6620 Wi-Fi][FW] Support Sigma CAPI for power saving related command -+ * link with supplicant commands -+ * -+ * 03 17 2011 chinglan.wang -+ * [WCXRP00000570] [MT6620 Wi-Fi][Driver] Add Wi-Fi Protected Setup v2.0 feature -+ * . -+ * -+ * 03 02 2011 george.huang -+ * [WCXRP00000504] [MT6620 Wi-Fi][FW] Support Sigma CAPI for power saving related command -+ * Support UAPSD/OppPS/NoA parameter setting -+ * -+ * 01 20 2011 eddie.chen -+ * [WCXRP00000374] [MT6620 Wi-Fi][DRV] SW debug control -+ * Add Oid for sw control debug command -+ * -+ * 12 07 2010 cm.chang -+ * [WCXRP00000238] MT6620 Wi-Fi][Driver][FW] Support regulation domain setting from NVRAM and supplicant -+ * 1. Country code is from NVRAM or supplicant -+ * 2. Change band definition in CMD/EVENT. -+ * -+ * 10 18 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check -+ * [WCXRP00000086] [MT6620 Wi-Fi][Driver] The mac address is all zero at android -+ * complete implementation of Android NVRAM access -+ * -+ * 10 08 2010 cp.wu -+ * [WCXRP00000084] [MT6620 Wi-Fi][Driver][FW] Add fixed rate support for distance test -+ * adding fixed rate support for distance test. (from registry setting) -+ * -+ * 09 23 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check -+ * add skeleton for NVRAM integration -+ * -+ * 09 08 2010 cp.wu -+ * NULL -+ * use static memory pool for storing IEs of scanning result. -+ * -+ * 09 03 2010 kevin.huang -+ * NULL -+ * Refine #include sequence and solve recursive/nested #include issue -+ * -+ * 08 29 2010 yuche.tsai -+ * NULL -+ * Finish SLT TX/RX & Rate Changing Support. -+ * -+ * 08 04 2010 cp.wu -+ * NULL -+ * revert changelist #15371, efuse read/write access will be done by RF test approach -+ * -+ * 08 04 2010 cp.wu -+ * NULL -+ * add OID definitions for EFUSE read/write access. -+ * -+ * 08 04 2010 yarco.yang -+ * NULL -+ * Add TX_AMPDU and ADDBA_REJECT command -+ * -+ * 08 02 2010 george.huang -+ * NULL -+ * add WMM-PS test related OID/ CMD handlers -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 22 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) add command warpper for STA-REC/BSS-INFO sync. -+ * 2) enhance command packet sending procedure for non-oid part -+ * 3) add command packet definitions for STA-REC/BSS-INFO sync. -+ * -+ * 06 18 2010 wh.su -+ * [WPD00003840][MT6620 5931] Security migration -+ * migration from MT6620 firmware. -+ * -+ * 06 07 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * merge wlan_def.h. -+ * -+ * 06 07 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * merge wifi_var.h, precomp.h, cnm_timer.h (data type only) -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 06 03 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * move timer callback to glue layer. -+ * -+ * 05 20 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) integrate OID_GEN_NETWORK_LAYER_ADDRESSES with CMD_ID_SET_IP_ADDRESS -+ * 2) buffer statistics data for 2 seconds -+ * 3) use default value for adhoc parameters instead of 0 -+ * -+ * 05 18 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * implement Wakeup-on-LAN except firmware integration part -+ * -+ * 05 17 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * MT6620 is not supporting NDIS_PACKET_TYPE_PROMISCUOUS. -+ * -+ -+ * -+ * 05 17 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * 1) add timeout handler mechanism for pending command packets -+ * 2) add p2p add/removal key -+ * -+ * 05 13 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * add NULL OID implementation for WOL-related OIDs. -+ * -+ * 04 22 2010 cp.wu -+ * [WPD00003830]add OID_802_11_PRIVACY_FILTER support -+ * enable RX filter OID -+ * -+ * 04 14 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * information buffer for query oid/ioctl is now buffered in prCmdInfo -+ * * * * * instead of glue-layer variable to improve multiple oid/ioctl capability -+ * -+ * 03 31 2010 wh.su -+ * [WPD00003816][MT6620 Wi-Fi] Adding the security support -+ * modify the wapi related code for new driver's design. -+ * -+ * 03 26 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * indicate media stream mode after set is done -+ * -+ * 03 24 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * initial import for Linux port -+ * -+ * 03 03 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * implement custom OID: EEPROM read/write access -+ * -+ * 02 09 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1. Permanent and current MAC address are now retrieved by CMD/EVENT packets instead of hard-coded address -+ * * * * * * 2. follow MSDN defined behavior when associates to another AP -+ * * * * * * 3. for firmware download, packet size could be up to 2048 bytes -+ * -+ * 01 27 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) implement timeout mechanism when OID is pending for longer than 1 second -+ * * * 2) allow OID_802_11_CONFIGURATION to be executed when RF test mode is turned on -+ * -+ * 01 27 2010 wh.su -+ * [WPD00003816][MT6620 Wi-Fi] Adding the security support -+ * . -+ * -+ * 01 22 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * implement following 802.11 OIDs: -+ * * * * OID_802_11_RSSI, -+ * * * * OID_802_11_RSSI_TRIGGER, -+ * * * * OID_802_11_STATISTICS, -+ * * * * OID_802_11_DISASSOCIATE, -+ * * * * OID_802_11_POWER_MODE -+ * -+ * 01 21 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * implement OID_802_11_MEDIA_STREAM_MODE -+ * -+ * 01 21 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * implement OID_802_11_SUPPORTED_RATES / OID_802_11_DESIRED_RATES -+** \main\maintrunk.MT6620WiFiDriver_Prj\6 2009-12-08 11:38:11 GMT mtk02752 -+** add declares for RF test related APIs -+** \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-11-24 22:41:53 GMT mtk02752 -+** remove u4SysTime, MSDN 10-second will be implemented in FW side -+** \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-11-23 20:30:13 GMT mtk02752 -+** add u4SysTime field in PARAM_BSSID_EX_T -+** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-11-12 19:48:35 GMT mtk02752 -+** allow upper layer to set a packet filter with PROMISCUOUS mode -+** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 20:12:12 GMT mtk01426 -+** Init for develop -+** -+*/ -+ -+#ifndef _WLAN_OID_H -+#define _WLAN_OID_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#if DBG -+extern UINT_8 aucDebugModule[DBG_MODULE_NUM]; -+extern UINT_32 u4DebugModule; -+UINT_32 u4DebugModuleTemp; -+#endif /* DBG */ -+extern int sprintf(char *buf, const char *fmt, ...); -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+#define PARAM_MAX_LEN_SSID 32 -+ -+#define PARAM_MAC_ADDR_LEN 6 -+ -+#define ETHERNET_HEADER_SZ 14 -+#define ETHERNET_MIN_PKT_SZ 60 -+#define ETHERNET_MAX_PKT_SZ 1514 -+ -+#define PARAM_MAX_LEN_RATES 8 -+#define PARAM_MAX_LEN_RATES_EX 16 -+ -+#define PARAM_AUTH_REQUEST_REAUTH 0x01 -+#define PARAM_AUTH_REQUEST_KEYUPDATE 0x02 -+#define PARAM_AUTH_REQUEST_PAIRWISE_ERROR 0x06 -+#define PARAM_AUTH_REQUEST_GROUP_ERROR 0x0E -+ -+#define PARAM_EEPROM_READ_METHOD_READ 1 -+#define PARAM_EEPROM_READ_METHOD_GETSIZE 0 -+ -+#define PARAM_WHQL_RSSI_MAX_DBM (-10) -+#define PARAM_WHQL_RSSI_MIN_DBM (-200) -+ -+#define PARAM_DEVICE_WAKE_UP_ENABLE 0x00000001 -+#define PARAM_DEVICE_WAKE_ON_PATTERN_MATCH_ENABLE 0x00000002 -+#define PARAM_DEVICE_WAKE_ON_MAGIC_PACKET_ENABLE 0x00000004 -+ -+#define PARAM_WAKE_UP_MAGIC_PACKET 0x00000001 -+#define PARAM_WAKE_UP_PATTERN_MATCH 0x00000002 -+#define PARAM_WAKE_UP_LINK_CHANGE 0x00000004 -+ -+/* Packet filter bit definitioin (UINT_32 bit-wise definition) */ -+#define PARAM_PACKET_FILTER_DIRECTED 0x00000001 -+#define PARAM_PACKET_FILTER_MULTICAST 0x00000002 -+#define PARAM_PACKET_FILTER_ALL_MULTICAST 0x00000004 -+#define PARAM_PACKET_FILTER_BROADCAST 0x00000008 -+#define PARAM_PACKET_FILTER_PROMISCUOUS 0x00000020 -+#define PARAM_PACKET_FILTER_ALL_LOCAL 0x00000080 -+#if CFG_ENABLE_WIFI_DIRECT_CFG_80211 -+#define PARAM_PACKET_FILTER_P2P_MASK 0xC0000000 -+#define PARAM_PACKET_FILTER_PROBE_REQ 0x80000000 -+#define PARAM_PACKET_FILTER_ACTION_FRAME 0x40000000 -+#endif -+ -+#if CFG_SLT_SUPPORT -+#define PARAM_PACKET_FILTER_SUPPORTED (PARAM_PACKET_FILTER_DIRECTED | \ -+ PARAM_PACKET_FILTER_MULTICAST | \ -+ PARAM_PACKET_FILTER_BROADCAST | \ -+ PARAM_PACKET_FILTER_ALL_MULTICAST) -+#else -+#define PARAM_PACKET_FILTER_SUPPORTED (PARAM_PACKET_FILTER_DIRECTED | \ -+ PARAM_PACKET_FILTER_MULTICAST | \ -+ PARAM_PACKET_FILTER_BROADCAST) -+#endif -+ -+#define PARAM_MEM_DUMP_MAX_SIZE 2048 -+ -+#define BT_PROFILE_PARAM_LEN 8 -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+/*----------------------------------------------------------------------------*/ -+/* Parameters of User Configuration which match to NDIS5.1 */ -+/*----------------------------------------------------------------------------*/ -+/* NDIS_802_11_AUTHENTICATION_MODE */ -+typedef enum _ENUM_PARAM_AUTH_MODE_T { -+ AUTH_MODE_OPEN, /*!< Open system */ -+ AUTH_MODE_SHARED, /*!< Shared key */ -+ AUTH_MODE_AUTO_SWITCH, /*!< Either open system or shared key */ -+ AUTH_MODE_WPA, -+ AUTH_MODE_WPA_PSK, -+ AUTH_MODE_WPA_NONE, /*!< For Ad hoc */ -+ AUTH_MODE_WPA2, -+ AUTH_MODE_WPA2_PSK, -+ AUTH_MODE_NUM /*!< Upper bound, not real case */ -+} ENUM_PARAM_AUTH_MODE_T, *P_ENUM_PARAM_AUTH_MODE_T; -+ -+/* NDIS_802_11_ENCRYPTION_STATUS *//* Encryption types */ -+typedef enum _ENUM_WEP_STATUS_T { -+ ENUM_WEP_ENABLED, -+ ENUM_ENCRYPTION1_ENABLED = ENUM_WEP_ENABLED, -+ ENUM_WEP_DISABLED, -+ ENUM_ENCRYPTION_DISABLED = ENUM_WEP_DISABLED, -+ ENUM_WEP_KEY_ABSENT, -+ ENUM_ENCRYPTION1_KEY_ABSENT = ENUM_WEP_KEY_ABSENT, -+ ENUM_WEP_NOT_SUPPORTED, -+ ENUM_ENCRYPTION_NOT_SUPPORTED = ENUM_WEP_NOT_SUPPORTED, -+ ENUM_ENCRYPTION2_ENABLED, -+ ENUM_ENCRYPTION2_KEY_ABSENT, -+ ENUM_ENCRYPTION3_ENABLED, -+ ENUM_ENCRYPTION3_KEY_ABSENT -+} ENUM_PARAM_ENCRYPTION_STATUS_T, *P_ENUM_PARAM_ENCRYPTION_STATUS_T; -+ -+typedef UINT_8 PARAM_MAC_ADDRESS[PARAM_MAC_ADDR_LEN]; -+ -+typedef UINT_32 PARAM_KEY_INDEX; -+typedef UINT_64 PARAM_KEY_RSC; -+typedef INT_32 PARAM_RSSI; -+ -+typedef UINT_32 PARAM_FRAGMENTATION_THRESHOLD; -+typedef UINT_32 PARAM_RTS_THRESHOLD; -+ -+typedef UINT_8 PARAM_RATES[PARAM_MAX_LEN_RATES]; -+typedef UINT_8 PARAM_RATES_EX[PARAM_MAX_LEN_RATES_EX]; -+ -+typedef enum _ENUM_PARAM_PHY_TYPE_T { -+ PHY_TYPE_802_11ABG = 0, /*!< Can associated with 802.11abg AP, -+ Scan dual band. */ -+ PHY_TYPE_802_11BG, /*!< Can associated with 802_11bg AP, -+ Scan single band and not report 802_11a BSSs. */ -+ PHY_TYPE_802_11G, /*!< Can associated with 802_11g only AP, -+ Scan single band and not report 802_11ab BSSs. */ -+ PHY_TYPE_802_11A, /*!< Can associated with 802_11a only AP, -+ Scan single band and not report 802_11bg BSSs. */ -+ PHY_TYPE_802_11B, /*!< Can associated with 802_11b only AP, -+ Scan single band and not report 802_11ag BSSs. */ -+ PHY_TYPE_NUM /* 5 */ -+} ENUM_PARAM_PHY_TYPE_T, *P_ENUM_PARAM_PHY_TYPE_T; -+ -+typedef enum _ENUM_PARAM_OP_MODE_T { -+ NET_TYPE_IBSS = 0, /*!< Try to merge/establish an AdHoc, do periodic SCAN for merging. */ -+ NET_TYPE_INFRA, /*!< Try to join an Infrastructure, do periodic SCAN for joining. */ -+ NET_TYPE_AUTO_SWITCH, /*!< Try to join an Infrastructure, if fail then try to merge or -+ establish an AdHoc, do periodic SCAN for joining or merging. */ -+ NET_TYPE_DEDICATED_IBSS, /*!< Try to merge an AdHoc first, -+ if fail then establish AdHoc permanently, no more SCAN. */ -+ NET_TYPE_NUM /* 4 */ -+} ENUM_PARAM_OP_MODE_T, *P_ENUM_PARAM_OP_MODE_T; -+ -+typedef struct _PARAM_SSID_T { -+ UINT_32 u4SsidLen; /*!< SSID length in bytes. Zero length is broadcast(any) SSID */ -+ UINT_8 aucSsid[PARAM_MAX_LEN_SSID]; -+ UINT_32 u4CenterFreq; -+} PARAM_SSID_T, *P_PARAM_SSID_T; -+ -+typedef struct _PARAM_CONNECT_T { -+ UINT_32 u4SsidLen; /*!< SSID length in bytes. Zero length is broadcast(any) SSID */ -+ UINT_8 *pucSsid; -+ UINT_8 *pucBssid; -+ UINT_32 u4CenterFreq; -+} PARAM_CONNECT_T, *P_PARAM_CONNECT_T; -+ -+/* This is enum defined for user to select an AdHoc Mode */ -+typedef enum _ENUM_PARAM_AD_HOC_MODE_T { -+ AD_HOC_MODE_11B = 0, /*!< Create 11b IBSS if we support 802.11abg/802.11bg. */ -+ AD_HOC_MODE_MIXED_11BG, /*!< Create 11bg mixed IBSS if we support 802.11abg/802.11bg/802.11g. */ -+ AD_HOC_MODE_11G, /*!< Create 11g only IBSS if we support 802.11abg/802.11bg/802.11g. */ -+ AD_HOC_MODE_11A, /*!< Create 11a only IBSS if we support 802.11abg. */ -+ AD_HOC_MODE_NUM /* 4 */ -+} ENUM_PARAM_AD_HOC_MODE_T, *P_ENUM_PARAM_AD_HOC_MODE_T; -+ -+typedef enum _ENUM_PARAM_MEDIA_STATE_T { -+ PARAM_MEDIA_STATE_CONNECTED, -+ PARAM_MEDIA_STATE_DISCONNECTED, -+ PARAM_MEDIA_STATE_TO_BE_INDICATED /* for following MSDN re-association behavior */ -+} ENUM_PARAM_MEDIA_STATE_T, *P_ENUM_PARAM_MEDIA_STATE_T; -+ -+typedef enum _ENUM_PARAM_NETWORK_TYPE_T { -+ PARAM_NETWORK_TYPE_FH, -+ PARAM_NETWORK_TYPE_DS, -+ PARAM_NETWORK_TYPE_OFDM5, -+ PARAM_NETWORK_TYPE_OFDM24, -+ PARAM_NETWORK_TYPE_AUTOMODE, -+ PARAM_NETWORK_TYPE_NUM /*!< Upper bound, not real case */ -+} ENUM_PARAM_NETWORK_TYPE_T, *P_ENUM_PARAM_NETWORK_TYPE_T; -+ -+typedef struct _PARAM_NETWORK_TYPE_LIST { -+ UINT_32 NumberOfItems; /*!< At least 1 */ -+ ENUM_PARAM_NETWORK_TYPE_T eNetworkType[1]; -+} PARAM_NETWORK_TYPE_LIST, *PPARAM_NETWORK_TYPE_LIST; -+ -+typedef enum _ENUM_PARAM_PRIVACY_FILTER_T { -+ PRIVACY_FILTER_ACCEPT_ALL, -+ PRIVACY_FILTER_8021xWEP, -+ PRIVACY_FILTER_NUM -+} ENUM_PARAM_PRIVACY_FILTER_T, *P_ENUM_PARAM_PRIVACY_FILTER_T; -+ -+typedef enum _ENUM_RELOAD_DEFAULTS { -+ ENUM_RELOAD_WEP_KEYS -+} PARAM_RELOAD_DEFAULTS, *P_PARAM_RELOAD_DEFAULTS; -+ -+typedef struct _PARAM_PM_PACKET_PATTERN { -+ UINT_32 Priority; /* Importance of the given pattern. */ -+ UINT_32 Reserved; /* Context information for transports. */ -+ UINT_32 MaskSize; /* Size in bytes of the pattern mask. */ -+ UINT_32 PatternOffset; /* Offset from beginning of this */ -+ /* structure to the pattern bytes. */ -+ UINT_32 PatternSize; /* Size in bytes of the pattern. */ -+ UINT_32 PatternFlags; /* Flags (TBD). */ -+} PARAM_PM_PACKET_PATTERN, *P_PARAM_PM_PACKET_PATTERN; -+ -+/*--------------------------------------------------------------*/ -+/*! \brief Struct definition to indicate specific event. */ -+/*--------------------------------------------------------------*/ -+typedef enum _ENUM_STATUS_TYPE_T { -+ ENUM_STATUS_TYPE_AUTHENTICATION, -+ ENUM_STATUS_TYPE_MEDIA_STREAM_MODE, -+ ENUM_STATUS_TYPE_CANDIDATE_LIST, -+ ENUM_STATUS_TYPE_NUM /*!< Upper bound, not real case */ -+} ENUM_STATUS_TYPE_T, *P_ENUM_STATUS_TYPE_T; -+ -+typedef struct _PARAM_802_11_CONFIG_FH_T { -+ UINT_32 u4Length; /*!< Length of structure */ -+ UINT_32 u4HopPattern; /*!< Defined as 802.11 */ -+ UINT_32 u4HopSet; /*!< to one if non-802.11 */ -+ UINT_32 u4DwellTime; /*!< In unit of Kusec */ -+} PARAM_802_11_CONFIG_FH_T, *P_PARAM_802_11_CONFIG_FH_T; -+ -+typedef struct _PARAM_802_11_CONFIG_T { -+ UINT_32 u4Length; /*!< Length of structure */ -+ UINT_32 u4BeaconPeriod; /*!< In unit of Kusec */ -+ UINT_32 u4ATIMWindow; /*!< In unit of Kusec */ -+ UINT_32 u4DSConfig; /*!< Channel frequency in unit of kHz */ -+ PARAM_802_11_CONFIG_FH_T rFHConfig; -+} PARAM_802_11_CONFIG_T, *P_PARAM_802_11_CONFIG_T; -+ -+typedef struct _PARAM_STATUS_INDICATION_T { -+ ENUM_STATUS_TYPE_T eStatusType; -+} PARAM_STATUS_INDICATION_T, *P_PARAM_STATUS_INDICATION_T; -+ -+typedef struct _PARAM_AUTH_REQUEST_T { -+ UINT_32 u4Length; /*!< Length of this struct */ -+ PARAM_MAC_ADDRESS arBssid; -+ UINT_32 u4Flags; /*!< Definitions are as follows */ -+} PARAM_AUTH_REQUEST_T, *P_PARAM_AUTH_REQUEST_T; -+ -+typedef struct _PARAM_AUTH_EVENT_T { -+ PARAM_STATUS_INDICATION_T rStatus; -+ PARAM_AUTH_REQUEST_T arRequest[1]; -+} PARAM_AUTH_EVENT_T, *P_PARAM_AUTH_EVENT_T; -+ -+/*! \brief Capabilities, privacy, rssi and IEs of each BSSID */ -+typedef struct _PARAM_BSSID_EX_T { -+ UINT_32 u4Length; /*!< Length of structure */ -+ PARAM_MAC_ADDRESS arMacAddress; /*!< BSSID */ -+ UINT_8 Reserved[2]; -+ PARAM_SSID_T rSsid; /*!< SSID */ -+ UINT_32 u4Privacy; /*!< Need WEP encryption */ -+ PARAM_RSSI rRssi; /*!< in dBm */ -+ ENUM_PARAM_NETWORK_TYPE_T eNetworkTypeInUse; -+ PARAM_802_11_CONFIG_T rConfiguration; -+ ENUM_PARAM_OP_MODE_T eOpMode; -+ PARAM_RATES_EX rSupportedRates; -+ UINT_32 u4IELength; -+ UINT_8 aucIEs[1]; -+} PARAM_BSSID_EX_T, *P_PARAM_BSSID_EX_T; -+ -+typedef struct _PARAM_BSSID_LIST_EX { -+ UINT_32 u4NumberOfItems; /*!< at least 1 */ -+ PARAM_BSSID_EX_T arBssid[1]; -+} PARAM_BSSID_LIST_EX_T, *P_PARAM_BSSID_LIST_EX_T; -+ -+typedef struct _PARAM_WEP_T { -+ UINT_32 u4Length; /*!< Length of structure */ -+ UINT_32 u4KeyIndex; /*!< 0: pairwise key, others group keys */ -+ UINT_32 u4KeyLength; /*!< Key length in bytes */ -+ UINT_8 aucKeyMaterial[32]; /*!< Key content by above setting */ -+} PARAM_WEP_T, *P_PARAM_WEP_T; -+ -+/*! \brief Key mapping of BSSID */ -+typedef struct _PARAM_KEY_T { -+ UINT_32 u4Length; /*!< Length of structure */ -+ UINT_32 u4KeyIndex; /*!< KeyID */ -+ UINT_32 u4KeyLength; /*!< Key length in bytes */ -+ PARAM_MAC_ADDRESS arBSSID; /*!< MAC address */ -+ PARAM_KEY_RSC rKeyRSC; -+ UINT_8 aucKeyMaterial[32]; /*!< Key content by above setting */ -+} PARAM_KEY_T, *P_PARAM_KEY_T; -+ -+typedef struct _PARAM_REMOVE_KEY_T { -+ UINT_32 u4Length; /*!< Length of structure */ -+ UINT_32 u4KeyIndex; /*!< KeyID */ -+ PARAM_MAC_ADDRESS arBSSID; /*!< MAC address */ -+} PARAM_REMOVE_KEY_T, *P_PARAM_REMOVE_KEY_T; -+ -+#if CFG_SUPPORT_WAPI -+typedef enum _ENUM_KEY_TYPE { -+ ENUM_WPI_PAIRWISE_KEY = 0, -+ ENUM_WPI_GROUP_KEY -+} ENUM_KEY_TYPE; -+ -+typedef enum _ENUM_WPI_PROTECT_TYPE { -+ ENUM_WPI_NONE, -+ ENUM_WPI_RX, -+ ENUM_WPI_TX, -+ ENUM_WPI_RX_TX -+} ENUM_WPI_PROTECT_TYPE; -+ -+typedef struct _PARAM_WPI_KEY_T { -+ ENUM_KEY_TYPE eKeyType; -+ ENUM_WPI_PROTECT_TYPE eDirection; -+ UINT_8 ucKeyID; -+ UINT_8 aucRsv[3]; -+ UINT_8 aucAddrIndex[12]; -+ UINT_32 u4LenWPIEK; -+ UINT_8 aucWPIEK[256]; -+ UINT_32 u4LenWPICK; -+ UINT_8 aucWPICK[256]; -+ UINT_8 aucPN[16]; -+} PARAM_WPI_KEY_T, *P_PARAM_WPI_KEY_T; -+#endif -+ -+typedef enum _PARAM_POWER_MODE { -+ Param_PowerModeCAM, -+ Param_PowerModeMAX_PSP, -+ Param_PowerModeFast_PSP, -+#if CFG_SUPPORT_DBG_POWERMODE -+ Param_PowerModeKeepActiveOn, /* privilege mode, always active */ -+ Param_PowerModeKeepActiveOff, /* to leave privilege mode */ -+#endif -+ Param_PowerModeMax /* Upper bound, not real case */ -+} PARAM_POWER_MODE, *PPARAM_POWER_MODE; -+ -+typedef enum _PARAM_DEVICE_POWER_STATE { -+ ParamDeviceStateUnspecified = 0, -+ ParamDeviceStateD0, -+ ParamDeviceStateD1, -+ ParamDeviceStateD2, -+ ParamDeviceStateD3, -+ ParamDeviceStateMaximum -+} PARAM_DEVICE_POWER_STATE, *PPARAM_DEVICE_POWER_STATE; -+ -+#if CFG_SUPPORT_802_11D -+ -+/*! \brief The enumeration definitions for OID_IPN_MULTI_DOMAIN_CAPABILITY */ -+typedef enum _PARAM_MULTI_DOMAIN_CAPABILITY { -+ ParamMultiDomainCapDisabled, -+ ParamMultiDomainCapEnabled -+} PARAM_MULTI_DOMAIN_CAPABILITY, *P_PARAM_MULTI_DOMAIN_CAPABILITY; -+#endif -+ -+typedef struct _COUNTRY_STRING_ENTRY { -+ UINT_8 aucCountryCode[2]; -+ UINT_8 aucEnvironmentCode[2]; -+} COUNTRY_STRING_ENTRY, *P_COUNTRY_STRING_ENTRY; -+ -+/* Power management related definition and enumerations */ -+#define UAPSD_NONE 0 -+#define UAPSD_AC0 (BIT(0) | BIT(4)) -+#define UAPSD_AC1 (BIT(1) | BIT(5)) -+#define UAPSD_AC2 (BIT(2) | BIT(6)) -+#define UAPSD_AC3 (BIT(3) | BIT(7)) -+#define UAPSD_ALL (UAPSD_AC0 | UAPSD_AC1 | UAPSD_AC2 | UAPSD_AC3) -+ -+typedef enum _ENUM_POWER_SAVE_PROFILE_T { -+ ENUM_PSP_CONTINUOUS_ACTIVE = 0, -+ ENUM_PSP_CONTINUOUS_POWER_SAVE, -+ ENUM_PSP_FAST_SWITCH, -+ ENUM_PSP_NUM -+} ENUM_POWER_SAVE_PROFILE_T, *PENUM_POWER_SAVE_PROFILE_T; -+ -+/*--------------------------------------------------------------*/ -+/*! \brief Set/Query testing type. */ -+/*--------------------------------------------------------------*/ -+typedef struct _PARAM_802_11_TEST_T { -+ UINT_32 u4Length; -+ UINT_32 u4Type; -+ union { -+ PARAM_AUTH_EVENT_T AuthenticationEvent; -+ PARAM_RSSI RssiTrigger; -+ } u; -+} PARAM_802_11_TEST_T, *P_PARAM_802_11_TEST_T; -+ -+/*--------------------------------------------------------------*/ -+/*! \brief Set/Query authentication and encryption capability. */ -+/*--------------------------------------------------------------*/ -+typedef struct _PARAM_AUTH_ENCRYPTION_T { -+ ENUM_PARAM_AUTH_MODE_T eAuthModeSupported; -+ ENUM_PARAM_ENCRYPTION_STATUS_T eEncryptStatusSupported; -+} PARAM_AUTH_ENCRYPTION_T, *P_PARAM_AUTH_ENCRYPTION_T; -+ -+typedef struct _PARAM_CAPABILITY_T { -+ UINT_32 u4Length; -+ UINT_32 u4Version; -+ UINT_32 u4NoOfPMKIDs; -+ UINT_32 u4NoOfAuthEncryptPairsSupported; -+ PARAM_AUTH_ENCRYPTION_T arAuthenticationEncryptionSupported[1]; -+} PARAM_CAPABILITY_T, *P_PARAM_CAPABILITY_T; -+ -+typedef UINT_8 PARAM_PMKID_VALUE[16]; -+ -+typedef struct _PARAM_BSSID_INFO_T { -+ PARAM_MAC_ADDRESS arBSSID; -+ PARAM_PMKID_VALUE arPMKID; -+} PARAM_BSSID_INFO_T, *P_PARAM_BSSID_INFO_T; -+ -+typedef struct _PARAM_PMKID_T { -+ UINT_32 u4Length; -+ UINT_32 u4BSSIDInfoCount; -+ PARAM_BSSID_INFO_T arBSSIDInfo[1]; -+} PARAM_PMKID_T, *P_PARAM_PMKID_T; -+ -+/*! \brief PMKID candidate lists. */ -+typedef struct _PARAM_PMKID_CANDIDATE_T { -+ PARAM_MAC_ADDRESS arBSSID; -+ UINT_32 u4Flags; -+} PARAM_PMKID_CANDIDATE_T, *P_PARAM_PMKID_CANDIDATE_T; -+ -+/* #ifdef LINUX */ -+typedef struct _PARAM_PMKID_CANDIDATE_LIST_T { -+ UINT_32 u4Version; /*!< Version */ -+ UINT_32 u4NumCandidates; /*!< How many candidates follow */ -+ PARAM_PMKID_CANDIDATE_T arCandidateList[1]; -+} PARAM_PMKID_CANDIDATE_LIST_T, *P_PARAM_PMKID_CANDIDATE_LIST_T; -+/* #endif */ -+ -+typedef struct _PARAM_CUSTOM_MCR_RW_STRUCT_T { -+ UINT_32 u4McrOffset; -+ UINT_32 u4McrData; -+} PARAM_CUSTOM_MCR_RW_STRUCT_T, *P_PARAM_CUSTOM_MCR_RW_STRUCT_T; -+ -+typedef struct _PARAM_CUSTOM_MEM_DUMP_STRUCT_T { -+ UINT_32 u4Address; -+ UINT_32 u4Length; -+ UINT_32 u4RemainLength; -+ UINT_8 ucFragNum; -+} PARAM_CUSTOM_MEM_DUMP_STRUCT_T, *P_PARAM_CUSTOM_MEM_DUMP_STRUCT_T; -+ -+typedef struct _PARAM_CUSTOM_SW_CTRL_STRUCT_T { -+ UINT_32 u4Id; -+ UINT_32 u4Data; -+} PARAM_CUSTOM_SW_CTRL_STRUCT_T, *P_PARAM_CUSTOM_SW_CTRL_STRUCT_T; -+ -+typedef struct _CMD_CHIP_CONFIG_T { -+ UINT_16 u2Id; -+ UINT_8 ucType; -+ UINT_8 ucRespType; -+ UINT_16 u2MsgSize; -+ UINT_8 aucReserved0[2]; -+ UINT_8 aucCmd[CHIP_CONFIG_RESP_SIZE]; -+} CMD_CHIP_CONFIG_T, *P_CMD_CHIP_CONFIG_T; -+ -+typedef struct _PARAM_CUSTOM_CHIP_CONFIG_STRUCT_T { -+ UINT_16 u2Id; -+ UINT_8 ucType; -+ UINT_8 ucRespType; -+ UINT_16 u2MsgSize; -+ UINT_8 aucReserved0[2]; -+ UINT_8 aucCmd[CHIP_CONFIG_RESP_SIZE]; -+} PARAM_CUSTOM_CHIP_CONFIG_STRUCT_T, *P_PARAM_CUSTOM_CHIP_CONFIG_STRUCT_T; -+ -+typedef struct _PARAM_CUSTOM_KEY_CFG_STRUCT_T { -+ UINT_8 aucKey[WLAN_CFG_KEY_LEN_MAX]; -+ UINT_8 aucValue[WLAN_CFG_VALUE_LEN_MAX]; -+} PARAM_CUSTOM_KEY_CFG_STRUCT_T, *P_PARAM_CUSTOM_KEY_CFG_STRUCT_T; -+ -+typedef struct _PARAM_CUSTOM_EEPROM_RW_STRUCT_T { -+ UINT_8 ucEepromMethod; /* For read only read: 1, query size: 0 */ -+ UINT_8 ucEepromIndex; -+ UINT_8 reserved; -+ UINT_16 u2EepromData; -+} PARAM_CUSTOM_EEPROM_RW_STRUCT_T, *P_PARAM_CUSTOM_EEPROM_RW_STRUCT_T, -+PARAM_CUSTOM_NVRAM_RW_STRUCT_T, *P_PARAM_CUSTOM_NVRAM_RW_STRUCT_T; -+ -+typedef struct _PARAM_CUSTOM_WMM_PS_TEST_STRUCT_T { -+ UINT_8 bmfgApsdEnAc; /* b0~3: trigger-en AC0~3. b4~7: delivery-en AC0~3 */ -+ UINT_8 ucIsEnterPsAtOnce; /* enter PS immediately without 5 second guard after connected */ -+ UINT_8 ucIsDisableUcTrigger; /* not to trigger UC on beacon TIM is matched (under U-APSD) */ -+ UINT_8 reserved; -+} PARAM_CUSTOM_WMM_PS_TEST_STRUCT_T, *P_PARAM_CUSTOM_WMM_PS_TEST_STRUCT_T; -+ -+typedef struct _PARAM_CUSTOM_NOA_PARAM_STRUCT_T { -+ UINT_32 u4NoaDurationMs; -+ UINT_32 u4NoaIntervalMs; -+ UINT_32 u4NoaCount; -+} PARAM_CUSTOM_NOA_PARAM_STRUCT_T, *P_PARAM_CUSTOM_NOA_PARAM_STRUCT_T; -+ -+typedef struct _PARAM_CUSTOM_OPPPS_PARAM_STRUCT_T { -+ UINT_32 u4CTwindowMs; -+} PARAM_CUSTOM_OPPPS_PARAM_STRUCT_T, *P_PARAM_CUSTOM_OPPPS_PARAM_STRUCT_T; -+ -+typedef struct _PARAM_CUSTOM_UAPSD_PARAM_STRUCT_T { -+ UINT_8 fgEnAPSD; -+ UINT_8 fgEnAPSD_AcBe; -+ UINT_8 fgEnAPSD_AcBk; -+ UINT_8 fgEnAPSD_AcVo; -+ UINT_8 fgEnAPSD_AcVi; -+ UINT_8 ucMaxSpLen; -+ UINT_8 aucResv[2]; -+} PARAM_CUSTOM_UAPSD_PARAM_STRUCT_T, *P_PARAM_CUSTOM_UAPSD_PARAM_STRUCT_T; -+ -+typedef struct _PARAM_CUSTOM_P2P_SET_STRUCT_T { -+ UINT_32 u4Enable; -+ UINT_32 u4Mode; -+} PARAM_CUSTOM_P2P_SET_STRUCT_T, *P_PARAM_CUSTOM_P2P_SET_STRUCT_T; -+ -+typedef enum _ENUM_CFG_SRC_TYPE_T { -+ CFG_SRC_TYPE_EEPROM, -+ CFG_SRC_TYPE_NVRAM, -+ CFG_SRC_TYPE_UNKNOWN, -+ CFG_SRC_TYPE_NUM -+} ENUM_CFG_SRC_TYPE_T, *P_ENUM_CFG_SRC_TYPE_T; -+ -+typedef enum _ENUM_EEPROM_TYPE_T { -+ EEPROM_TYPE_NO, -+ EEPROM_TYPE_PRESENT, -+ EEPROM_TYPE_NUM -+} ENUM_EEPROM_TYPE_T, *P_ENUM_EEPROM_TYPE_T; -+ -+typedef struct _PARAM_QOS_TSINFO { -+ UINT_8 ucTrafficType; /* Traffic Type: 1 for isochronous 0 for asynchronous */ -+ UINT_8 ucTid; /* TSID: must be between 8 ~ 15 */ -+ UINT_8 ucDirection; /* direction */ -+ UINT_8 ucAccessPolicy; /* access policy */ -+ UINT_8 ucAggregation; /* aggregation */ -+ UINT_8 ucApsd; /* APSD */ -+ UINT_8 ucuserPriority; /* user priority */ -+ UINT_8 ucTsInfoAckPolicy; /* TSINFO ACK policy */ -+ UINT_8 ucSchedule; /* Schedule */ -+} PARAM_QOS_TSINFO, *P_PARAM_QOS_TSINFO; -+ -+typedef struct _PARAM_QOS_TSPEC { -+ PARAM_QOS_TSINFO rTsInfo; /* TS info field */ -+ UINT_16 u2NominalMSDUSize; /* nominal MSDU size */ -+ UINT_16 u2MaxMSDUsize; /* maximum MSDU size */ -+ UINT_32 u4MinSvcIntv; /* minimum service interval */ -+ UINT_32 u4MaxSvcIntv; /* maximum service interval */ -+ UINT_32 u4InactIntv; /* inactivity interval */ -+ UINT_32 u4SpsIntv; /* suspension interval */ -+ UINT_32 u4SvcStartTime; /* service start time */ -+ UINT_32 u4MinDataRate; /* minimum Data rate */ -+ UINT_32 u4MeanDataRate; /* mean data rate */ -+ UINT_32 u4PeakDataRate; /* peak data rate */ -+ UINT_32 u4MaxBurstSize; /* maximum burst size */ -+ UINT_32 u4DelayBound; /* delay bound */ -+ UINT_32 u4MinPHYRate; /* minimum PHY rate */ -+ UINT_16 u2Sba; /* surplus bandwidth allowance */ -+ UINT_16 u2MediumTime; /* medium time */ -+} PARAM_QOS_TSPEC, *P_PARAM_QOS_TSPEC; -+ -+typedef struct _PARAM_QOS_ADDTS_REQ_INFO { -+ PARAM_QOS_TSPEC rTspec; -+} PARAM_QOS_ADDTS_REQ_INFO, *P_PARAM_QOS_ADDTS_REQ_INFO; -+ -+typedef struct _PARAM_VOIP_CONFIG { -+ UINT_32 u4VoipTrafficInterval; /* 0: disable VOIP configuration */ -+} PARAM_VOIP_CONFIG, *P_PARAM_VOIP_CONFIG; -+ -+/*802.11 Statistics Struct*/ -+typedef struct _PARAM_802_11_STATISTICS_STRUCT_T { -+ UINT_32 u4Length; /* Length of structure */ -+ LARGE_INTEGER rTransmittedFragmentCount; -+ LARGE_INTEGER rMulticastTransmittedFrameCount; -+ LARGE_INTEGER rFailedCount; -+ LARGE_INTEGER rRetryCount; -+ LARGE_INTEGER rMultipleRetryCount; -+ LARGE_INTEGER rRTSSuccessCount; -+ LARGE_INTEGER rRTSFailureCount; -+ LARGE_INTEGER rACKFailureCount; -+ LARGE_INTEGER rFrameDuplicateCount; -+ LARGE_INTEGER rReceivedFragmentCount; -+ LARGE_INTEGER rMulticastReceivedFrameCount; -+ LARGE_INTEGER rFCSErrorCount; -+ LARGE_INTEGER rTKIPLocalMICFailures; -+ LARGE_INTEGER rTKIPICVErrors; -+ LARGE_INTEGER rTKIPCounterMeasuresInvoked; -+ LARGE_INTEGER rTKIPReplays; -+ LARGE_INTEGER rCCMPFormatErrors; -+ LARGE_INTEGER rCCMPReplays; -+ LARGE_INTEGER rCCMPDecryptErrors; -+ LARGE_INTEGER rFourWayHandshakeFailures; -+ LARGE_INTEGER rWEPUndecryptableCount; -+ LARGE_INTEGER rWEPICVErrorCount; -+ LARGE_INTEGER rDecryptSuccessCount; -+ LARGE_INTEGER rDecryptFailureCount; -+} PARAM_802_11_STATISTICS_STRUCT_T, *P_PARAM_802_11_STATISTICS_STRUCT_T; -+ -+/* Linux Network Device Statistics Struct */ -+typedef struct _PARAM_LINUX_NETDEV_STATISTICS_T { -+ UINT_32 u4RxPackets; -+ UINT_32 u4TxPackets; -+ UINT_32 u4RxBytes; -+ UINT_32 u4TxBytes; -+ UINT_32 u4RxErrors; -+ UINT_32 u4TxErrors; -+ UINT_32 u4Multicast; -+} PARAM_LINUX_NETDEV_STATISTICS_T, *P_PARAM_LINUX_NETDEV_STATISTICS_T; -+ -+typedef struct _PARAM_MTK_WIFI_TEST_STRUCT_T { -+ UINT_32 u4FuncIndex; -+ UINT_32 u4FuncData; -+} PARAM_MTK_WIFI_TEST_STRUCT_T, *P_PARAM_MTK_WIFI_TEST_STRUCT_T; -+ -+/* 802.11 Media stream constraints */ -+typedef enum _ENUM_MEDIA_STREAM_MODE { -+ ENUM_MEDIA_STREAM_OFF, -+ ENUM_MEDIA_STREAM_ON -+} ENUM_MEDIA_STREAM_MODE, *P_ENUM_MEDIA_STREAM_MODE; -+ -+/* for NDIS 5.1 Media Streaming Change */ -+typedef struct _PARAM_MEDIA_STREAMING_INDICATION { -+ PARAM_STATUS_INDICATION_T rStatus; -+ ENUM_MEDIA_STREAM_MODE eMediaStreamMode; -+} PARAM_MEDIA_STREAMING_INDICATION, *P_PARAM_MEDIA_STREAMING_INDICATION; -+ -+#define PARAM_PROTOCOL_ID_DEFAULT 0x00 -+#define PARAM_PROTOCOL_ID_TCP_IP 0x02 -+#define PARAM_PROTOCOL_ID_IPX 0x06 -+#define PARAM_PROTOCOL_ID_NBF 0x07 -+#define PARAM_PROTOCOL_ID_MAX 0x0F -+#define PARAM_PROTOCOL_ID_MASK 0x0F -+ -+/* for NDIS OID_GEN_NETWORK_LAYER_ADDRESSES */ -+typedef struct _PARAM_NETWORK_ADDRESS_IP { -+ UINT_16 sin_port; -+ UINT_32 in_addr; -+ UINT_8 sin_zero[8]; -+} PARAM_NETWORK_ADDRESS_IP, *P_PARAM_NETWORK_ADDRESS_IP; -+ -+typedef struct _PARAM_NETWORK_ADDRESS { -+ UINT_16 u2AddressLength; /* length in bytes of Address[] in this */ -+ UINT_16 u2AddressType; /* type of this address (PARAM_PROTOCOL_ID_XXX above) */ -+ UINT_8 aucAddress[1]; /* actually AddressLength bytes long */ -+} PARAM_NETWORK_ADDRESS, *P_PARAM_NETWORK_ADDRESS; -+ -+/* The following is used with OID_GEN_NETWORK_LAYER_ADDRESSES to set network layer addresses on an interface */ -+ -+typedef struct _PARAM_NETWORK_ADDRESS_LIST { -+ UINT_32 u4AddressCount; /* number of addresses following */ -+ UINT_16 u2AddressType; /* type of this address (NDIS_PROTOCOL_ID_XXX above) */ -+ PARAM_NETWORK_ADDRESS arAddress[1]; /* actually AddressCount elements long */ -+} PARAM_NETWORK_ADDRESS_LIST, *P_PARAM_NETWORK_ADDRESS_LIST; -+ -+#if CFG_SLT_SUPPORT -+ -+#define FIXED_BW_LG20 0x0000 -+#define FIXED_BW_UL20 0x2000 -+#define FIXED_BW_DL40 0x3000 -+ -+#define FIXED_EXT_CHNL_U20 0x4000 /* For AGG register. */ -+#define FIXED_EXT_CHNL_L20 0xC000 /* For AGG regsiter. */ -+ -+typedef enum _ENUM_MTK_LP_TEST_MODE_T { -+ ENUM_MTK_LP_TEST_NORMAL, -+ ENUM_MTK_LP_TEST_GOLDEN_SAMPLE, -+ ENUM_MTK_LP_TEST_DUT, -+ ENUM_MTK_LP_TEST_MODE_NUM -+} ENUM_MTK_LP_TEST_MODE_T, *P_ENUM_MTK_LP_TEST_MODE_T; -+ -+typedef enum _ENUM_MTK_SLT_FUNC_IDX_T { -+ ENUM_MTK_SLT_FUNC_DO_NOTHING, -+ ENUM_MTK_SLT_FUNC_INITIAL, -+ ENUM_MTK_SLT_FUNC_RATE_SET, -+ ENUM_MTK_SLT_FUNC_LP_SET, -+ ENUM_MTK_SLT_FUNC_NUM -+} ENUM_MTK_SLT_FUNC_IDX_T, *P_ENUM_MTK_SLT_FUNC_IDX_T; -+ -+typedef struct _PARAM_MTK_SLT_LP_TEST_STRUCT_T { -+ ENUM_MTK_LP_TEST_MODE_T rLpTestMode; -+ UINT_32 u4BcnRcvNum; -+} PARAM_MTK_SLT_LP_TEST_STRUCT_T, *P_PARAM_MTK_SLT_LP_TEST_STRUCT_T; -+ -+typedef struct _PARAM_MTK_SLT_TR_TEST_STRUCT_T { -+ ENUM_PARAM_NETWORK_TYPE_T rNetworkType; /* Network Type OFDM5G or OFDM2.4G */ -+ UINT_32 u4FixedRate; /* Fixed Rate including BW */ -+} PARAM_MTK_SLT_TR_TEST_STRUCT_T, *P_PARAM_MTK_SLT_TR_TEST_STRUCT_T; -+ -+typedef struct _PARAM_MTK_SLT_INITIAL_STRUCT_T { -+ UINT_8 aucTargetMacAddr[PARAM_MAC_ADDR_LEN]; -+ UINT_16 u2SiteID; -+} PARAM_MTK_SLT_INITIAL_STRUCT_T, *P_PARAM_MTK_SLT_INITIAL_STRUCT_T; -+ -+typedef struct _PARAM_MTK_SLT_TEST_STRUCT_T { -+ ENUM_MTK_SLT_FUNC_IDX_T rSltFuncIdx; -+ UINT_32 u4Length; /* Length of structure, -+ including myself */ -+ UINT_32 u4FuncInfoLen; /* Include following content -+ field and myself */ -+ union { -+ PARAM_MTK_SLT_INITIAL_STRUCT_T rMtkInitTest; -+ PARAM_MTK_SLT_LP_TEST_STRUCT_T rMtkLpTest; -+ PARAM_MTK_SLT_TR_TEST_STRUCT_T rMtkTRTest; -+ } unFuncInfoContent; -+ -+} PARAM_MTK_SLT_TEST_STRUCT_T, *P_PARAM_MTK_SLT_TEST_STRUCT_T; -+ -+#endif -+ -+/*--------------------------------------------------------------*/ -+/*! \brief For Fixed Rate Configuration (Registry) */ -+/*--------------------------------------------------------------*/ -+typedef enum _ENUM_REGISTRY_FIXED_RATE_T { -+ FIXED_RATE_NONE, -+ FIXED_RATE_1M, -+ FIXED_RATE_2M, -+ FIXED_RATE_5_5M, -+ FIXED_RATE_11M, -+ FIXED_RATE_6M, -+ FIXED_RATE_9M, -+ FIXED_RATE_12M, -+ FIXED_RATE_18M, -+ FIXED_RATE_24M, -+ FIXED_RATE_36M, -+ FIXED_RATE_48M, -+ FIXED_RATE_54M, -+ FIXED_RATE_MCS0_20M_800NS, -+ FIXED_RATE_MCS1_20M_800NS, -+ FIXED_RATE_MCS2_20M_800NS, -+ FIXED_RATE_MCS3_20M_800NS, -+ FIXED_RATE_MCS4_20M_800NS, -+ FIXED_RATE_MCS5_20M_800NS, -+ FIXED_RATE_MCS6_20M_800NS, -+ FIXED_RATE_MCS7_20M_800NS, -+ FIXED_RATE_MCS0_20M_400NS, -+ FIXED_RATE_MCS1_20M_400NS, -+ FIXED_RATE_MCS2_20M_400NS, -+ FIXED_RATE_MCS3_20M_400NS, -+ FIXED_RATE_MCS4_20M_400NS, -+ FIXED_RATE_MCS5_20M_400NS, -+ FIXED_RATE_MCS6_20M_400NS, -+ FIXED_RATE_MCS7_20M_400NS, -+ FIXED_RATE_MCS0_40M_800NS, -+ FIXED_RATE_MCS1_40M_800NS, -+ FIXED_RATE_MCS2_40M_800NS, -+ FIXED_RATE_MCS3_40M_800NS, -+ FIXED_RATE_MCS4_40M_800NS, -+ FIXED_RATE_MCS5_40M_800NS, -+ FIXED_RATE_MCS6_40M_800NS, -+ FIXED_RATE_MCS7_40M_800NS, -+ FIXED_RATE_MCS32_800NS, -+ FIXED_RATE_MCS0_40M_400NS, -+ FIXED_RATE_MCS1_40M_400NS, -+ FIXED_RATE_MCS2_40M_400NS, -+ FIXED_RATE_MCS3_40M_400NS, -+ FIXED_RATE_MCS4_40M_400NS, -+ FIXED_RATE_MCS5_40M_400NS, -+ FIXED_RATE_MCS6_40M_400NS, -+ FIXED_RATE_MCS7_40M_400NS, -+ FIXED_RATE_MCS32_400NS, -+ FIXED_RATE_NUM -+} ENUM_REGISTRY_FIXED_RATE_T, *P_ENUM_REGISTRY_FIXED_RATE_T; -+ -+typedef enum _ENUM_BT_CMD_T { -+ BT_CMD_PROFILE = 0, -+ BT_CMD_UPDATE, -+ BT_CMD_NUM -+} ENUM_BT_CMD_T; -+ -+typedef enum _ENUM_BT_PROFILE_T { -+ BT_PROFILE_CUSTOM = 0, -+ BT_PROFILE_SCO, -+ BT_PROFILE_ACL, -+ BT_PROFILE_MIXED, -+ BT_PROFILE_NO_CONNECTION, -+ BT_PROFILE_NUM -+} ENUM_BT_PROFILE_T; -+ -+typedef struct _PTA_PROFILE_T { -+ ENUM_BT_PROFILE_T eBtProfile; -+ union { -+ UINT_8 aucBTPParams[BT_PROFILE_PARAM_LEN]; -+ /* 0: sco reserved slot time, -+ 1: sco idle slot time, -+ 2: acl throughput, -+ 3: bt tx power, -+ 4: bt rssi -+ 5: VoIP interval -+ 6: BIT(0) Use this field, BIT(1) 0 apply single/ 1 dual PTA setting. -+ */ -+ UINT_32 au4Btcr[4]; -+ } u; -+} PTA_PROFILE_T, *P_PTA_PROFILE_T; -+ -+typedef struct _PTA_IPC_T { -+ UINT_8 ucCmd; -+ UINT_8 ucLen; -+ union { -+ PTA_PROFILE_T rProfile; -+ UINT_8 aucBTPParams[BT_PROFILE_PARAM_LEN]; -+ } u; -+} PARAM_PTA_IPC_T, *P_PARAM_PTA_IPC_T, PTA_IPC_T, *P_PTA_IPC_T; -+ -+/*--------------------------------------------------------------*/ -+/*! \brief CFG80211 Scan Request Container */ -+/*--------------------------------------------------------------*/ -+ -+typedef struct _PARAM_SCAN_REQUEST_EXT_T { -+ PARAM_SSID_T rSsid; -+ UINT_32 u4IELength; -+ PUINT_8 pucIE; -+} PARAM_SCAN_REQUEST_EXT_T, *P_PARAM_SCAN_REQUEST_EXT_T; -+ -+/*--------------------------------------------------------------*/ -+/*! \brief CFG80211 Scheduled Scan Request Container */ -+/*--------------------------------------------------------------*/ -+typedef struct _PARAM_SCHED_SCAN_REQUEST_T { -+ UINT_32 u4SsidNum; -+ PARAM_SSID_T arSsid[CFG_SCAN_SSID_MATCH_MAX_NUM]; -+ UINT_32 u4IELength; -+ PUINT_8 pucIE; -+ UINT_16 u2ScanInterval; /* in milliseconds */ -+} PARAM_SCHED_SCAN_REQUEST, *P_PARAM_SCHED_SCAN_REQUEST; -+ -+#if CFG_SUPPORT_HOTSPOT_2_0 -+typedef struct _PARAM_HS20_SET_BSSID_POOL { -+ BOOLEAN fgIsEnable; -+ UINT_8 ucNumBssidPool; -+ PARAM_MAC_ADDRESS arBSSID[8]; -+} PARAM_HS20_SET_BSSID_POOL, *P_PARAM_HS20_SET_BSSID_POOL; -+ -+#endif -+ -+typedef struct _PARAM_CUSTOM_WFD_DEBUG_STRUCT_T { -+ UINT_8 ucWFDDebugMode; /* 0: Disable -+ 1:Enable but only show inqueue skb ether SN -+ 2.show skb ether SN and the statistics of skb inqueue time */ -+ UINT_16 u2SNPeriod; /* The Ether SN Period */ -+ -+ UINT_8 reserved; -+} PARAM_CUSTOM_WFD_DEBUG_STRUCT_T, *P_PARAM_CUSTOM_WFD_DEBUG_STRUCT_T; -+ -+typedef struct _CMD_GET_PSCAN_CAPABILITY { -+/* TBD */ -+} CMD_GET_GSCAN_CAPABILITY, *P_CMD_GET_GSCAN_CAPABILITY; -+ -+typedef struct _CMD_SET_PSCAN_ENABLE { -+ UINT_8 ucPscanAct; -+ UINT_8 aucReserved[3]; -+} CMD_SET_PSCAN_ENABLE, *P_CMD_SET_PSCAN_ENABLE; -+ -+typedef enum _ENUM_PSCAN_ACT_T { -+ ENABLE, -+ DISABLE, -+ SUSPEND, -+ CLEAR -+} ENUM_PSCAN_ACT_T, *P_ENUM_PSCAN_ACT_T; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+/*--------------------------------------------------------------*/ -+/* Routines to set parameters or query information. */ -+/*--------------------------------------------------------------*/ -+/***** Routines in wlan_oid.c *****/ -+WLAN_STATUS -+wlanoidQueryNetworkTypesSupported(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryNetworkTypeInUse(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidSetNetworkTypeInUse(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryBssid(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidSetBssidListScan(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidSetBssidListScanExt(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryBssidList(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidSetBssid(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidSetSsid(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidSetConnect(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidQuerySsid(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryInfrastructureMode(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidSetInfrastructureMode(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryAuthMode(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidSetAuthMode(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+#if 0 -+WLAN_STATUS -+wlanoidQueryPrivacyFilter(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidSetPrivacyFilter(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+#endif -+ -+WLAN_STATUS -+wlanoidSetEncryptionStatus(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryEncryptionStatus(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidSetAddWep(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidSetRemoveWep(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+_wlanoidSetAddKey(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, -+ IN UINT_32 u4SetBufferLen, IN BOOLEAN fgIsOid, IN UINT_8 ucAlgorithmId, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidSetAddKey(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidSetRemoveKey(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidSetReloadDefaults(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidSetTest(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryCapability(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryFrequency(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidSetFrequency(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryAtimWindow(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidSetAtimWindow(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidSetChannel(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryRssi(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryRssiTrigger(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidSetRssiTrigger(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryRtsThreshold(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidSetRtsThreshold(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidQuery802dot11PowerSaveProfile(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidSet802dot11PowerSaveProfile(IN P_ADAPTER_T prAdapter, -+ IN PVOID prSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryPmkid(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidSetPmkid(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidQuerySupportedRates(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryDesiredRates(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidSetDesiredRates(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryPermanentAddr(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuf, IN UINT_32 u4QueryBufLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryCurrentAddr(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuf, IN UINT_32 u4QueryBufLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryPermanentAddr(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuf, IN UINT_32 u4QueryBufLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryLinkSpeed(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryMcrRead(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryMemDump(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidSetMcrWrite(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidQuerySwCtrlRead(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidSetSwCtrlWrite(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryEepromRead(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidSetEepromWrite(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryRfTestRxStatus(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryRfTestTxStatus(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryOidInterfaceVersion(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryVendorId(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryMulticastList(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidSetMulticastList(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryRcvError(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryRcvNoBuffer(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryRcvCrcError(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryStatistics(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+WLAN_STATUS -+wlanoidQueryStatisticsPL(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+#ifdef LINUX -+ -+WLAN_STATUS -+wlanoidQueryStatisticsForLinux(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+#endif -+ -+WLAN_STATUS -+wlanoidQueryMediaStreamMode(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidSetMediaStreamMode(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryRcvOk(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryXmitOk(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryXmitError(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryXmitOneCollision(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryXmitMoreCollisions(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryXmitMaxCollisions(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidSetCurrentPacketFilter(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryCurrentPacketFilter(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidSetAcpiDevicePowerState(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryAcpiDevicePowerState(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidSetDisassociate(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryFragThreshold(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidSetFragThreshold(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryAdHocMode(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidSetAdHocMode(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryBeaconInterval(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidSetBeaconInterval(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidSetCurrentAddr(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+#if CFG_TCP_IP_CHKSUM_OFFLOAD -+WLAN_STATUS -+wlanoidSetCSUMOffload(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */ -+ -+WLAN_STATUS -+wlanoidSetNetworkAddress(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryMaxFrameSize(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryMaxTotalSize(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidSetCurrentLookahead(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+/* RF Test related APIs */ -+WLAN_STATUS -+wlanoidRftestSetTestMode(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidRftestSetAbortTestMode(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidRftestQueryAutoTest(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidRftestSetAutoTest(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+#if CFG_SUPPORT_WAPI -+WLAN_STATUS -+wlanoidSetWapiMode(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidSetWapiAssocInfo(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidSetWapiKey(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+#endif -+ -+#if CFG_SUPPORT_WPS2 -+WLAN_STATUS -+wlanoidSetWSCAssocInfo(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+#endif -+ -+#if CFG_ENABLE_WAKEUP_ON_LAN -+WLAN_STATUS -+wlanoidSetAddWakeupPattern(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidSetRemoveWakeupPattern(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryEnableWakeup(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 u4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidSetEnableWakeup(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+#endif -+ -+WLAN_STATUS -+wlanoidSetWiFiWmmPsTest(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidSetTxAmpdu(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryBSSInfo(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidSetAddbaReject(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryNvramRead(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidSetNvramWrite(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryCfgSrcType(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryEepromType(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidSetCountryCode(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS wlanSendMemDumpCmd(IN P_ADAPTER_T prAdapter, IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen); -+ -+#if CFG_SLT_SUPPORT -+ -+WLAN_STATUS -+wlanoidQuerySLTStatus(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidUpdateSLTMode(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+#endif -+ -+#if 0 -+WLAN_STATUS -+wlanoidSetNoaParam(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidSetOppPsParam(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidSetUApsdParam(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetBT(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryBT(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidSetTxPower(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+#if CFG_SUPPORT_BUILD_DATE_CODE -+WLAN_STATUS -+wlanoidQueryBuildDateCode(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+#endif -+ -+/* -+WLAN_STATUS -+wlanoidQueryBtSingleAntenna ( -+ IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, -+ IN UINT_32 u4QueryBufferLen, -+ OUT PUINT_32 pu4QueryInfoLen -+ ); -+ -+WLAN_STATUS -+wlanoidSetBtSingleAntenna ( -+ IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, -+ IN UINT_32 u4SetBufferLen, -+ OUT PUINT_32 pu4SetInfoLen -+ ); -+ -+WLAN_STATUS -+wlanoidSetPta ( -+ IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, -+ IN UINT_32 u4SetBufferLen, -+ OUT PUINT_32 pu4SetInfoLen -+ ); -+ -+WLAN_STATUS -+wlanoidQueryPta ( -+ IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, -+ IN UINT_32 u4QueryBufferLen, -+ OUT PUINT_32 pu4QueryInfoLen -+ ); -+*/ -+ -+#if CFG_ENABLE_WIFI_DIRECT -+WLAN_STATUS -+wlanoidSetP2pMode(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+#endif -+ -+#if CFG_SUPPORT_BATCH_SCAN -+WLAN_STATUS -+wlanoidSetBatchScanReq(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryBatchScanResult(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+#endif -+ -+#if CFG_SUPPORT_HOTSPOT_2_0 -+WLAN_STATUS -+wlanoidSetHS20Info(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidSetInterworkingInfo(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidSetRoamingConsortiumIEInfo(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidSetHS20BssidPool(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+#endif -+ -+WLAN_STATUS -+wlanoidSetRoamingInfo(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidSetWfdDebugMode(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidSetStartSchedScan(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidSetStopSchedScan(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidSetGSCNAction(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidSetGSCNAParam(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidSetGSCNAConfig(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidGetGSCNResult(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidSetTxRateInfo( -+ IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, -+ IN UINT_32 u4SetBufferLen, -+ OUT PUINT_32 pu4SetInfoLen -+ ); -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+WLAN_STATUS -+wlanoidSetChipConfig(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+WLAN_STATUS -+wlanoidNotifyFwSuspend(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, -+ IN UINT_32 u4SetBufferLen, -+ OUT PUINT_32 pu4SetInfoLen); -+ -+#endif /* _WLAN_OID_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/wlan_p2p.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/wlan_p2p.h -new file mode 100644 -index 000000000000..0b558d64034d ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/wlan_p2p.h -@@ -0,0 +1,307 @@ -+/* -+** Id: //Department/DaVinci/TRUNK/WiFi_P2P_Driver/include/wlan_p2p.h#3 -+*/ -+ -+/*! \file "wlan_p2p.h" -+ \brief This file contains the declairations of Wi-Fi Direct command -+ processing routines for MediaTek Inc. 802.11 Wireless LAN Adapters. -+*/ -+ -+/* -+** Log: wlan_p2p.h -+ * -+ * 07 17 2012 yuche.tsai -+ * NULL -+ * Compile no error before trial run. -+ * -+ * 11 19 2011 yuche.tsai -+ * NULL -+ * Add RSSI support for P2P network. -+ * -+ * 11 08 2011 yuche.tsai -+ * [WCXRP00001094] [Volunteer Patch][Driver] Driver version & supplicant version -+ * query & set support for service discovery version check. -+ * Add support for driver version query & p2p supplicant verseion set. -+ * For new service discovery mechanism sync. -+ * -+ * 10 18 2011 yuche.tsai -+ * [WCXRP00001045] [WiFi Direct][Driver] Check 2.1 branch. -+ * Support Channel Query. -+ * -+ * 10 18 2011 yuche.tsai -+ * [WCXRP00001045] [WiFi Direct][Driver] Check 2.1 branch. -+ * New 2.1 branch -+ -+ * -+ * 04 27 2011 george.huang -+ * [WCXRP00000684] [MT6620 Wi-Fi][Driver] Support P2P setting ARP filter -+ * Support P2P ARP filter setting on early suspend/ late resume -+ * -+ * 04 08 2011 george.huang -+ * [WCXRP00000621] [MT6620 Wi-Fi][Driver] Support P2P supplicant to set power mode -+ * separate settings of P2P and AIS -+ * -+ * 03 22 2011 george.huang -+ * [WCXRP00000504] [MT6620 Wi-Fi][FW] Support Sigma CAPI for power saving related command -+ * link with supplicant commands -+ * -+ * 03 07 2011 wh.su -+ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code -+ * rename the define to anti_pviracy. -+ * -+ * 03 02 2011 wh.su -+ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code -+ * Add Security check related code. -+ * -+ * 01 05 2011 cp.wu -+ * [WCXRP00000283] [MT6620 Wi-Fi][Driver][Wi-Fi Direct] Implementation of interface -+ * for supporting Wi-Fi Direct Service Discovery -+ * ioctl implementations for P2P Service Discovery -+ * -+ * 12 22 2010 cp.wu -+ * [WCXRP00000283] [MT6620 Wi-Fi][Driver][Wi-Fi Direct] Implementation of interface -+ * for supporting Wi-Fi Direct Service Discovery -+ * 1. header file restructure for more clear module isolation -+ * 2. add function interface definition for implementing Service Discovery callbacks -+ * -+ * 09 21 2010 kevin.huang -+ * [WCXRP00000054] [MT6620 Wi-Fi][Driver] Restructure driver for second Interface -+ * Isolate P2P related function for Hardware Software Bundle -+ * -+ * 08 16 2010 cp.wu -+ * NULL -+ * add subroutines for P2P to set multicast list. -+ * -+ * 08 16 2010 george.huang -+ * NULL -+ * support wlanoidSetP2pPowerSaveProfile() in P2P -+ * -+ * 08 16 2010 george.huang -+ * NULL -+ * Support wlanoidSetNetworkAddress() for P2P -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 05 17 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * MT6620 is not supporting NDIS_PACKET_TYPE_PROMISCUOUS. -+ * -+ -+ * -+** -+*/ -+ -+#ifndef _WLAN_P2P_H -+#define _WLAN_P2P_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+#if CFG_ENABLE_WIFI_DIRECT -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/* Service Discovery */ -+typedef struct _PARAM_P2P_SEND_SD_RESPONSE { -+ PARAM_MAC_ADDRESS rReceiverAddr; -+ UINT_8 fgNeedTxDoneIndication; -+ UINT_8 ucChannelNum; -+ UINT_16 u2PacketLength; -+ UINT_8 aucPacketContent[0]; /*native 802.11 */ -+} PARAM_P2P_SEND_SD_RESPONSE, *P_PARAM_P2P_SEND_SD_RESPONSE; -+ -+typedef struct _PARAM_P2P_GET_SD_REQUEST { -+ PARAM_MAC_ADDRESS rTransmitterAddr; -+ UINT_16 u2PacketLength; -+ UINT_8 aucPacketContent[0]; /*native 802.11 */ -+} PARAM_P2P_GET_SD_REQUEST, *P_PARAM_P2P_GET_SD_REQUEST; -+ -+typedef struct _PARAM_P2P_GET_SD_REQUEST_EX { -+ PARAM_MAC_ADDRESS rTransmitterAddr; -+ UINT_16 u2PacketLength; -+ UINT_8 ucChannelNum; /* Channel Number Where SD Request is received. */ -+ UINT_8 ucSeqNum; /* Get SD Request by sequence number. */ -+ UINT_8 aucPacketContent[0]; /*native 802.11 */ -+} PARAM_P2P_GET_SD_REQUEST_EX, *P_PARAM_P2P_GET_SD_REQUEST_EX; -+ -+typedef struct _PARAM_P2P_SEND_SD_REQUEST { -+ PARAM_MAC_ADDRESS rReceiverAddr; -+ UINT_8 fgNeedTxDoneIndication; -+ UINT_8 ucVersionNum; /* Indicate the Service Discovery Supplicant Version. */ -+ UINT_16 u2PacketLength; -+ UINT_8 aucPacketContent[0]; /*native 802.11 */ -+} PARAM_P2P_SEND_SD_REQUEST, *P_PARAM_P2P_SEND_SD_REQUEST; -+ -+/* Service Discovery 1.0. */ -+typedef struct _PARAM_P2P_GET_SD_RESPONSE { -+ PARAM_MAC_ADDRESS rTransmitterAddr; -+ UINT_16 u2PacketLength; -+ UINT_8 aucPacketContent[0]; /*native 802.11 */ -+} PARAM_P2P_GET_SD_RESPONSE, *P_PARAM_P2P_GET_SD_RESPONSE; -+ -+/* Service Discovery 2.0. */ -+typedef struct _PARAM_P2P_GET_SD_RESPONSE_EX { -+ PARAM_MAC_ADDRESS rTransmitterAddr; -+ UINT_16 u2PacketLength; -+ UINT_8 ucSeqNum; /* Get SD Response by sequence number. */ -+ UINT_8 aucPacketContent[0]; /*native 802.11 */ -+} PARAM_P2P_GET_SD_RESPONSE_EX, *P_PARAM_P2P_GET_SD_RESPONSE_EX; -+ -+typedef struct _PARAM_P2P_TERMINATE_SD_PHASE { -+ PARAM_MAC_ADDRESS rPeerAddr; -+} PARAM_P2P_TERMINATE_SD_PHASE, *P_PARAM_P2P_TERMINATE_SD_PHASE; -+ -+/*! \brief Key mapping of BSSID */ -+typedef struct _P2P_PARAM_KEY_T { -+ UINT_32 u4Length; /*!< Length of structure */ -+ UINT_32 u4KeyIndex; /*!< KeyID */ -+ UINT_32 u4KeyLength; /*!< Key length in bytes */ -+ PARAM_MAC_ADDRESS arBSSID; /*!< MAC address */ -+ PARAM_KEY_RSC rKeyRSC; -+ UINT_8 aucKeyMaterial[32]; /*!< Key content by above setting */ -+} P2P_PARAM_KEY_T, *P_P2P_PARAM_KEY_T; -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/*--------------------------------------------------------------*/ -+/* Routines to handle command */ -+/*--------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetAddP2PKey(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidSetRemoveP2PKey(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidSetNetworkAddress(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidSetP2PMulticastList(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+/*--------------------------------------------------------------*/ -+/* Service Discovery Subroutines */ -+/*--------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSendP2PSDRequest(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidSendP2PSDResponse(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidGetP2PSDRequest(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidGetP2PSDResponse(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 puQueryInfoLen); -+ -+WLAN_STATUS -+wlanoidSetP2PTerminateSDPhase(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+#if CFG_SUPPORT_ANTI_PIRACY -+WLAN_STATUS -+wlanoidSetSecCheckRequest(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidGetSecCheckResponse(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+#endif -+ -+WLAN_STATUS -+wlanoidSetNoaParam(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidSetOppPsParam(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidSetUApsdParam(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryP2pPowerSaveProfile(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidSetP2pPowerSaveProfile(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidSetP2pSetNetworkAddress(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryP2pOpChannel(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryP2pVersion(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidSetP2pSupplicantVersion(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidSetP2pWPSmode(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+#if CFG_SUPPORT_P2P_RSSI_QUERY -+WLAN_STATUS -+wlanoidQueryP2pRssi(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+#endif -+ -+/*--------------------------------------------------------------*/ -+/* Callbacks for event indication */ -+/*--------------------------------------------------------------*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif -+#endif /* _WLAN_P2P_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/aaa_fsm.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/aaa_fsm.c -new file mode 100644 -index 000000000000..f2324f13280e ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/aaa_fsm.c -@@ -0,0 +1,1303 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/aaa_fsm.c#2 -+*/ -+ -+/*! \file "aaa_fsm.c" -+ \brief This file defines the FSM for AAA MODULE. -+ -+ This file defines the FSM for AAA MODULE. -+*/ -+ -+/* -+** Log: aaa_fsm.c -+ * -+ * 07 17 2012 yuche.tsai -+ * NULL -+ * Compile no error before trial run. -+ * -+ * 06 13 2012 yuche.tsai -+ * NULL -+ * Update maintrunk driver. -+ * Add support for driver compose assoc request frame. -+ * -+ * 03 02 2012 terry.wu -+ * NULL -+ * Sync CFG80211 modification from branch 2,2. -+ * -+ * 02 22 2012 yuche.tsai -+ * NULL -+ * Solve sigma test 5.1.3 issue, assoc response should have P2P IE. -+ * -+ * 12 02 2011 yuche.tsai -+ * NULL -+ * Resolve inorder issue under AP mode. -+ * -+ * data frame may TX before assoc response frame. -+ * -+ * 11 18 2011 yuche.tsai -+ * NULL -+ * CONFIG P2P support RSSI query, default turned off. -+ * -+ * 06 17 2011 terry.wu -+ * NULL -+ * Add BoW 11N support. -+ * -+ * 06 02 2011 eddie.chen -+ * [WCXRP00000759] [MT6620 Wi-Fi][DRV] Update RCPI in AAA -+ * Update RCPI when receiving Assoc request. -+ * -+ * 04 21 2011 terry.wu -+ * [WCXRP00000674] [MT6620 Wi-Fi][Driver] Refine AAA authSendAuthFrame -+ * Add network type parameter to authSendAuthFrame. -+ * -+ * 04 15 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Add BOW short range mode. -+ * -+ * 04 09 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Change Link connection event procedure and change skb length check to 1512 bytes. -+ * -+ * 03 09 2011 wh.su -+ * [WCXRP00000530] [MT6620 Wi-Fi] [Driver] skip doing p2pRunEventAAAComplete after send assoc response Tx Done -+ * Skip to call p2pRunEventAAAComplete to avoid indicate STA connect twice. -+ * -+ * 03 04 2011 terry.wu -+ * [WCXRP00000515] [MT6620 Wi-Fi][Driver] Surpress compiler warning which is identified by GNU compiler collection -+ * Remove unused variable. -+ * -+ * 02 16 2011 yuche.tsai -+ * [WCXRP00000429] [Volunteer Patch][MT6620][Driver] Hot Spot Client Limit Issue -+ * Add more check after RX assoc frame under Hot-Spot mode. -+ * -+ * 02 09 2011 yuche.tsai -+ * [WCXRP00000429] [Volunteer Patch][MT6620][Driver] Hot Spot Client Limit Issue -+ * Fix Client Limit Issue. -+ * -+ * 01 25 2011 yuche.tsai -+ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record. -+ * Change Station Type in Station Record, Modify MACRO definition for getting station type & network type index & Role. -+ * -+ * 01 15 2011 puff.wen -+ * NULL -+ * [On behalf of Frog] Add CFG_ENABLE_WIFI_DIRECT to p2pRunEventAAAComplete -+ * -+ * 01 14 2011 yuche.tsai -+ * [WCXRP00000352] [Volunteer Patch][MT6620][Driver] P2P Statsion Record Client List Issue -+ * Modify AAA flow according to CM's comment. -+ * -+ * 09 03 2010 kevin.huang -+ * NULL -+ * Refine #include sequence and solve recursive/nested #include issue -+ * -+ * 08 29 2010 yuche.tsai -+ * NULL -+ * Fix Compile warning, type cast from UINT_32 to UINT_16. -+ * -+ * 08 26 2010 yuche.tsai -+ * NULL -+ * In P2P AT GO test mode under WinXP, we would not indicate connected event to host. -+ * -+ * 08 24 2010 cm.chang -+ * NULL -+ * Support RLM initail channel of Ad-hoc, P2P and BOW -+ * -+ * 08 23 2010 chinghwa.yu -+ * NULL -+ * Update for BOW. -+ * -+ * 08 20 2010 kevin.huang -+ * NULL -+ * Modify AAA Module for changing STA STATE 3 at p2p/bowRunEventAAAComplete() -+ * -+ * 08 17 2010 yuche.tsai -+ * NULL -+ * Fix bug while enabling P2P GO. -+ * -+ * 08 16 2010 kevin.huang -+ * NULL -+ * Refine AAA functions -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 21 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * refine TX-DONE callback. -+ * -+ * 06 21 2010 yuche.tsai -+ * [WPD00003839][MT6620 5931][P2P] Feature migration -+ * modify due to P2P functino call prototype change. -+ * -+ * 06 17 2010 yuche.tsai -+ * [WPD00003839][MT6620 5931][P2P] Feature migration -+ * First draft for migration P2P FSM from FW to Driver. -+ * -+ * 04 02 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Modify CFG flags -+ * -+ * 02 26 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * add support of Driver STA_RECORD_T activation -+ * -+ * 02 04 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Add AAA Module Support, Revise Net Type to Net Type Index for array lookup -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "precomp.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+#if 0 -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will send Event to AIS/BOW/P2P -+* -+* @param[in] rJoinStatus To indicate JOIN success or failure. -+* @param[in] prStaRec Pointer to the STA_RECORD_T -+* @param[in] prSwRfb Pointer to the SW_RFB_T -+ -+* @return none -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS aaaFsmSendEventJoinComplete(WLAN_STATUS rJoinStatus, P_STA_RECORD_T prStaRec, P_SW_RFB_T prSwRfb) -+{ -+ P_MSG_SAA_JOIN_COMP_T prJoinCompMsg; -+ -+ ASSERT(prStaRec); -+ -+ prJoinCompMsg = cnmMemAlloc(RAM_TYPE_TCM, sizeof(MSG_SAA_JOIN_COMP_T)); -+ if (!prJoinCompMsg) -+ return WLAN_STATUS_RESOURCES; -+ -+ if (IS_STA_IN_AIS(prStaRec)) -+ prJoinCompMsg->rMsgHdr.eMsgId = MID_SAA_AIS_JOIN_COMPLETE; -+ else if (IS_STA_IN_P2P(prStaRec)) -+ prJoinCompMsg->rMsgHdr.eMsgId = MID_SAA_P2P_JOIN_COMPLETE; -+ else if (IS_STA_IN_BOW(prStaRec)) -+ prJoinCompMsg->rMsgHdr.eMsgId = MID_SAA_BOW_JOIN_COMPLETE; -+ else -+ ASSERT(0); -+ -+ prJoinCompMsg->rJoinStatus = rJoinStatus; -+ prJoinCompMsg->prStaRec = prStaRec; -+ prJoinCompMsg->prSwRfb = prSwRfb; -+ -+ mboxSendMsg(MBOX_ID_0, (P_MSG_HDR_T) prJoinCompMsg, MSG_SEND_METHOD_BUF); -+ -+ return WLAN_STATUS_SUCCESS; -+ -+} /* end of saaFsmSendEventJoinComplete() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will handle the Start Event to AAA FSM. -+* -+* @param[in] prMsgHdr Message of Join Request for a particular STA. -+* -+* @return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID aaaFsmRunEventStart(IN P_MSG_HDR_T prMsgHdr) -+{ -+ P_MSG_SAA_JOIN_REQ_T prJoinReqMsg; -+ P_STA_RECORD_T prStaRec; -+ P_AIS_BSS_INFO_T prAisBssInfo; -+ -+ ASSERT(prMsgHdr); -+ -+ prJoinReqMsg = (P_MSG_SAA_JOIN_REQ_T) prMsgHdr; -+ prStaRec = prJoinReqMsg->prStaRec; -+ -+ ASSERT(prStaRec); -+ -+ DBGLOG(SAA, LOUD, "EVENT-START: Trigger SAA FSM\n"); -+ -+ cnmMemFree(prMsgHdr); -+ -+ /* 4 <1> Validation of SAA Start Event */ -+ if (!IS_AP_STA(prStaRec->eStaType)) { -+ -+ DBGLOG(SAA, ERROR, "EVENT-START: STA Type - %d was not supported.\n", prStaRec->eStaType); -+ -+ /* Ignore the return value because don't care the prSwRfb */ -+ saaFsmSendEventJoinComplete(WLAN_STATUS_FAILURE, prStaRec, NULL); -+ -+ return; -+ } -+ /* 4 <2> The previous JOIN process is not completed ? */ -+ if (prStaRec->eAuthAssocState != AA_STATE_IDLE) { -+ DBGLOG(SAA, ERROR, "EVENT-START: Reentry of SAA Module.\n"); -+ prStaRec->eAuthAssocState = AA_STATE_IDLE; -+ } -+ /* 4 <3> Reset Status Code and Time */ -+ /* Update Station Record - Status/Reason Code */ -+ prStaRec->u2StatusCode = STATUS_CODE_SUCCESSFUL; -+ -+ /* Update the record join time. */ -+ GET_CURRENT_SYSTIME(&prStaRec->rLastJoinTime); -+ -+ prStaRec->ucTxAuthAssocRetryCount = 0; -+ -+ if (prStaRec->prChallengeText) { -+ cnmMemFree(prStaRec->prChallengeText); -+ prStaRec->prChallengeText = (P_IE_CHALLENGE_TEXT_T) NULL; -+ } -+ -+ cnmTimerStopTimer(&prStaRec->rTxReqDoneOrRxRespTimer); -+ -+ prStaRec->ucStaState = STA_STATE_1; -+ -+ /* Trigger SAA MODULE */ -+ saaFsmSteps(prStaRec, SAA_STATE_SEND_AUTH1, (P_SW_RFB_T) NULL); -+ -+} /* end of saaFsmRunEventStart() */ -+#endif -+ -+#if CFG_SUPPORT_AAA -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will process the Rx Auth Request Frame and then -+* trigger AAA FSM. -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* @param[in] prSwRfb Pointer to the SW_RFB_T structure. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID aaaFsmRunEventRxAuth(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb) -+{ -+ P_BSS_INFO_T prBssInfo; -+ P_STA_RECORD_T prStaRec = (P_STA_RECORD_T) NULL; -+ UINT_16 u2StatusCode; -+ BOOLEAN fgReplyAuth = FALSE; -+ ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex; -+ -+ ASSERT(prAdapter); -+ -+ do { -+ -+ /* 4 <1> Check P2P network conditions */ -+#if CFG_ENABLE_WIFI_DIRECT -+ if (prAdapter->fgIsP2PRegistered) { -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); -+ -+ if (prBssInfo->fgIsNetActive) { -+ -+ /* 4 <1.1> Validate Auth Frame by Auth Algorithm/Transation Seq */ -+ if (WLAN_STATUS_SUCCESS == -+ authProcessRxAuth1Frame(prAdapter, -+ prSwRfb, -+ prBssInfo->aucBSSID, -+ AUTH_ALGORITHM_NUM_OPEN_SYSTEM, -+ AUTH_TRANSACTION_SEQ_1, &u2StatusCode)) { -+ -+ if (STATUS_CODE_SUCCESSFUL == u2StatusCode) { -+ /* 4 <1.2> Validate Auth Frame for Network Specific Conditions */ -+ fgReplyAuth = p2pFuncValidateAuth(prAdapter, -+ prSwRfb, &prStaRec, &u2StatusCode); -+ } else { -+ fgReplyAuth = TRUE; -+ } -+ eNetTypeIndex = NETWORK_TYPE_P2P_INDEX; -+ break; -+ } -+ } -+ } -+#endif /* CFG_ENABLE_WIFI_DIRECT */ -+ -+ /* 4 <2> Check BOW network conditions */ -+#if CFG_ENABLE_BT_OVER_WIFI -+ { -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_BOW_INDEX]); -+ -+ if ((prBssInfo->fgIsNetActive) && (OP_MODE_BOW == prBssInfo->eCurrentOPMode)) { -+ -+ /* 4 <2.1> Validate Auth Frame by Auth Algorithm/Transation Seq */ -+ /* Check if for this BSSID */ -+ if (WLAN_STATUS_SUCCESS == -+ authProcessRxAuth1Frame(prAdapter, -+ prSwRfb, -+ prBssInfo->aucBSSID, -+ AUTH_ALGORITHM_NUM_OPEN_SYSTEM, -+ AUTH_TRANSACTION_SEQ_1, &u2StatusCode)) { -+ -+ if (STATUS_CODE_SUCCESSFUL == u2StatusCode) { -+ -+ /* 4 <2.2> Validate Auth Frame for Network Specific Conditions */ -+ fgReplyAuth = -+ bowValidateAuth(prAdapter, prSwRfb, &prStaRec, &u2StatusCode); -+ -+ } else { -+ -+ fgReplyAuth = TRUE; -+ } -+ eNetTypeIndex = NETWORK_TYPE_BOW_INDEX; -+ /* TODO(Kevin): Allocate a STA_RECORD_T for new client */ -+ break; -+ } -+ } -+ } -+#endif /* CFG_ENABLE_BT_OVER_WIFI */ -+ -+ return; -+ } while (FALSE); -+ -+ if (prStaRec) { -+ /* update RCPI */ -+ prStaRec->ucRCPI = prSwRfb->prHifRxHdr->ucRcpi; -+ } -+ /* 4 <3> Update STA_RECORD_T and reply Auth_2(Response to Auth_1) Frame */ -+ if (fgReplyAuth) { -+ -+ if (prStaRec) { -+ -+ if (u2StatusCode == STATUS_CODE_SUCCESSFUL) { -+ if (prStaRec->eAuthAssocState != AA_STATE_IDLE) { -+ DBGLOG(AAA, WARN, "Previous AuthAssocState (%d) != IDLE.\n", -+ prStaRec->eAuthAssocState); -+ } -+ -+ prStaRec->eAuthAssocState = AAA_STATE_SEND_AUTH2; -+ } else { -+ prStaRec->eAuthAssocState = AA_STATE_IDLE; -+ -+ /* NOTE(Kevin): Change to STATE_1 */ -+ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); -+ } -+ -+ /* Update the record join time. */ -+ GET_CURRENT_SYSTIME(&prStaRec->rUpdateTime); -+ -+ /* Update Station Record - Status/Reason Code */ -+ prStaRec->u2StatusCode = u2StatusCode; -+ -+ prStaRec->ucAuthAlgNum = AUTH_ALGORITHM_NUM_OPEN_SYSTEM; -+ } else { -+ /* NOTE(Kevin): We should have STA_RECORD_T if the status code was successful */ -+ ASSERT(!(u2StatusCode == STATUS_CODE_SUCCESSFUL)); -+ } -+ -+ /* NOTE: Ignore the return status for AAA */ -+ /* 4 <4> Reply Auth */ -+ authSendAuthFrame(prAdapter, prStaRec, eNetTypeIndex, prSwRfb, AUTH_TRANSACTION_SEQ_2, u2StatusCode); -+ -+ } -+ -+} /* end of aaaFsmRunEventRxAuth() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will process the Rx (Re)Association Request Frame and then -+* trigger AAA FSM. -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* @param[in] prSwRfb Pointer to the SW_RFB_T structure. -+* -+* @retval WLAN_STATUS_SUCCESS Always return success -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS aaaFsmRunEventRxAssoc(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb) -+{ -+ P_BSS_INFO_T prBssInfo; -+ P_STA_RECORD_T prStaRec = (P_STA_RECORD_T) NULL; -+ UINT_16 u2StatusCode = STATUS_CODE_RESERVED; -+ BOOLEAN fgReplyAssocResp = FALSE; -+ -+ ASSERT(prAdapter); -+ -+ do { -+ -+ /* 4 <1> Check if we have the STA_RECORD_T for incoming Assoc Req */ -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); -+ -+ /* We should have the corresponding Sta Record. */ -+ if ((!prStaRec) || (!prStaRec->fgIsInUse)) { -+ ASSERT(0); /* Only for debug phase */ -+ break; -+ } -+ -+ if (!IS_CLIENT_STA(prStaRec)) -+ break; -+ -+ if (prStaRec->ucStaState == STA_STATE_3) { -+ /* Do Reassocation */ -+ } else if ((prStaRec->ucStaState == STA_STATE_2) && -+ (prStaRec->eAuthAssocState == AAA_STATE_SEND_AUTH2)) { -+ /* Normal case */ -+ } else { -+ DBGLOG(AAA, INFO, "Previous AuthAssocState (%d) != SEND_AUTH2, ucStaState:%d.\n", -+ prStaRec->eAuthAssocState, -+ prStaRec->ucStaState); -+ /* TODO: Why assoc req event is faster than tx done of auth */ -+ if (prStaRec->eAuthAssocState != AAA_STATE_SEND_AUTH2) -+ break; -+ } -+ -+ /* update RCPI */ -+ prStaRec->ucRCPI = prSwRfb->prHifRxHdr->ucRcpi; -+ -+ /* 4 <2> Check P2P network conditions */ -+#if CFG_ENABLE_WIFI_DIRECT -+ if ((prAdapter->fgIsP2PRegistered) && (IS_STA_IN_P2P(prStaRec))) { -+ -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); -+ -+ if (prBssInfo->fgIsNetActive) { -+ -+ /* 4 <2.1> Validate Assoc Req Frame and get Status Code */ -+ /* Check if for this BSSID */ -+ if (WLAN_STATUS_SUCCESS == -+ assocProcessRxAssocReqFrame(prAdapter, prSwRfb, &u2StatusCode)) { -+ -+ if (STATUS_CODE_SUCCESSFUL == u2StatusCode) { -+ /* 4 <2.2> Validate Assoc Req Frame for Network Specific Conditions */ -+ fgReplyAssocResp = p2pFuncValidateAssocReq(prAdapter, -+ prSwRfb, -+ (PUINT_16)&u2StatusCode); -+ } else { -+ fgReplyAssocResp = TRUE; -+ } -+ -+ break; -+ } -+ } -+ } -+#endif /* CFG_ENABLE_WIFI_DIRECT */ -+ -+ /* 4 <3> Check BOW network conditions */ -+#if CFG_ENABLE_BT_OVER_WIFI -+ if (IS_STA_IN_BOW(prStaRec)) { -+ -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_BOW_INDEX]); -+ -+ if ((prBssInfo->fgIsNetActive) && (OP_MODE_BOW == prBssInfo->eCurrentOPMode)) { -+ -+ /* 4 <3.1> Validate Auth Frame by Auth Algorithm/Transation Seq */ -+ /* Check if for this BSSID */ -+ if (WLAN_STATUS_SUCCESS == -+ assocProcessRxAssocReqFrame(prAdapter, prSwRfb, &u2StatusCode)) { -+ -+ if (STATUS_CODE_SUCCESSFUL == u2StatusCode) { -+ -+ /* 4 <3.2> Validate Auth Frame for Network Specific Conditions */ -+ fgReplyAssocResp = -+ bowValidateAssocReq(prAdapter, prSwRfb, &u2StatusCode); -+ -+ } else { -+ -+ fgReplyAssocResp = TRUE; -+ } -+ -+ /* TODO(Kevin): Allocate a STA_RECORD_T for new client */ -+ break; -+ } -+ } -+ } -+#endif /* CFG_ENABLE_BT_OVER_WIFI */ -+ -+ return WLAN_STATUS_SUCCESS; /* To release the SW_RFB_T */ -+ } while (FALSE); -+ -+ /* 4 <4> Update STA_RECORD_T and reply Assoc Resp Frame */ -+ if (fgReplyAssocResp) { -+ UINT_16 u2IELength; -+ PUINT_8 pucIE; -+ -+ if ((((P_WLAN_ASSOC_REQ_FRAME_T) (prSwRfb->pvHeader))->u2FrameCtrl & MASK_FRAME_TYPE) == -+ MAC_FRAME_REASSOC_REQ) { -+ -+ u2IELength = prSwRfb->u2PacketLen - -+ (UINT_16) OFFSET_OF(WLAN_REASSOC_REQ_FRAME_T, aucInfoElem[0]); -+ -+ pucIE = ((P_WLAN_REASSOC_REQ_FRAME_T) (prSwRfb->pvHeader))->aucInfoElem; -+ } else { -+ u2IELength = prSwRfb->u2PacketLen - (UINT_16) OFFSET_OF(WLAN_ASSOC_REQ_FRAME_T, aucInfoElem[0]); -+ -+ pucIE = ((P_WLAN_ASSOC_REQ_FRAME_T) (prSwRfb->pvHeader))->aucInfoElem; -+ } -+ -+ rlmProcessAssocReq(prAdapter, prSwRfb, pucIE, u2IELength); -+ -+ /* 4 <4.1> Assign Association ID */ -+ if (u2StatusCode == STATUS_CODE_SUCCESSFUL) { -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ if ((prAdapter->fgIsP2PRegistered) && (IS_STA_IN_P2P(prStaRec))) { -+ if (p2pRunEventAAAComplete(prAdapter, prStaRec) == WLAN_STATUS_SUCCESS) { -+ prStaRec->u2AssocId = bssAssignAssocID(prStaRec); -+ /* prStaRec->eAuthAssocState = AA_STATE_IDLE; */ -+ prStaRec->eAuthAssocState = AAA_STATE_SEND_ASSOC2;/* NOTE(Kevin): for TX done */ -+ -+ /* NOTE(Kevin): Method A: Change to STATE_3 before handle TX Done */ -+ /* cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_3); */ -+ } else { -+ /* Client List FULL. */ -+ u2StatusCode = STATUS_CODE_REQ_DECLINED; -+ -+ prStaRec->u2AssocId = 0; /* Invalid Association ID */ -+ -+ /* If (Re)association fail, the peer can try Association w/o Auth immediately */ -+ prStaRec->eAuthAssocState = AAA_STATE_SEND_AUTH2; -+ -+ /* NOTE(Kevin): Better to change state here, not at TX Done */ -+ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_2); -+ } -+ } -+#endif -+ -+#if CFG_ENABLE_BT_OVER_WIFI -+ if ((IS_STA_IN_BOW(prStaRec))) { -+ /* if (bowRunEventAAAComplete(prAdapter, prStaRec) == WLAN_STATUS_SUCCESS) { */ -+ prStaRec->u2AssocId = bssAssignAssocID(prStaRec); -+ prStaRec->eAuthAssocState = AAA_STATE_SEND_ASSOC2; /* NOTE(Kevin): for TX done */ -+ -+ /* NOTE(Kevin): Method A: Change to STATE_3 before handle TX Done */ -+ /* cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_3); */ -+ } -+#if 0 -+ else { -+ /* Client List FULL. */ -+ u2StatusCode = STATUS_CODE_REQ_DECLINED; -+ -+ prStaRec->u2AssocId = 0; /* Invalid Association ID */ -+ -+ /* If (Re)association fail, the peer can try Association w/o Auth immediately */ -+ prStaRec->eAuthAssocState = AAA_STATE_SEND_AUTH2; -+ -+ /* NOTE(Kevin): Better to change state here, not at TX Done */ -+ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_2); -+ } -+ } -+#endif -+#endif -+ } else { -+ prStaRec->u2AssocId = 0; /* Invalid Association ID */ -+ -+ /* If (Re)association fail, the peer can try Association w/o Auth immediately */ -+ prStaRec->eAuthAssocState = AAA_STATE_SEND_AUTH2; -+ -+ /* NOTE(Kevin): Better to change state here, not at TX Done */ -+ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_2); -+ } -+ -+ /* Update the record join time. */ -+ GET_CURRENT_SYSTIME(&prStaRec->rUpdateTime); -+ -+ /* Update Station Record - Status/Reason Code */ -+ prStaRec->u2StatusCode = u2StatusCode; -+ -+ /* NOTE: Ignore the return status for AAA */ -+ /* 4 <4.2> Reply Assoc Resp */ -+ assocSendReAssocRespFrame(prAdapter, prStaRec); -+ -+} -+ -+return WLAN_STATUS_SUCCESS; -+ -+} /* end of aaaFsmRunEventRxAssoc() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will handle TxDone(Auth2/AssocReq) Event of AAA FSM. -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* @param[in] prMsduInfo Pointer to the MSDU_INFO_T. -+* @param[in] rTxDoneStatus Return TX status of the Auth1/Auth3/AssocReq frame. -+* -+* @retval WLAN_STATUS_SUCCESS -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+aaaFsmRunEventTxDone(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus) -+{ -+ P_STA_RECORD_T prStaRec; -+ P_BSS_INFO_T prBssInfo; -+ -+ ASSERT(prAdapter); -+ ASSERT(prMsduInfo); -+ -+ DBGLOG(AAA, LOUD, "EVENT-TX DONE: Current Time = %lu\n", (unsigned long)kalGetTimeTick()); -+ -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); -+ -+ if ((!prStaRec) || (!prStaRec->fgIsInUse)) { -+ DBGLOG(AAA, INFO, "EVENT-TX DONE: Invalid StaRec"); -+ return WLAN_STATUS_SUCCESS; /* For the case of replying ERROR STATUS CODE */ -+ } -+ -+ ASSERT(prStaRec->ucNetTypeIndex < NETWORK_TYPE_INDEX_NUM); -+ -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]); -+ DBGLOG(AAA, INFO, "TX DONE status: %d, AuthAssocState: %d, SeqNo: %d\n", -+ rTxDoneStatus, prStaRec->eAuthAssocState, -+ prMsduInfo->ucTxSeqNum); -+ -+ switch (prStaRec->eAuthAssocState) { -+ case AAA_STATE_SEND_AUTH2: -+ { -+ /* Strictly check the outgoing frame is matched with current AA STATE */ -+ if (authCheckTxAuthFrame(prAdapter, prMsduInfo, AUTH_TRANSACTION_SEQ_2) != WLAN_STATUS_SUCCESS) -+ break; -+ -+ if (STATUS_CODE_SUCCESSFUL == prStaRec->u2StatusCode) { -+ if (TX_RESULT_SUCCESS == rTxDoneStatus) { -+ -+ /* NOTE(Kevin): Change to STATE_2 at TX Done */ -+ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_2); -+ } else { -+ -+ prStaRec->eAuthAssocState = AA_STATE_IDLE; -+ -+ /* NOTE(Kevin): Change to STATE_1 */ -+ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ if ((prAdapter->fgIsP2PRegistered) && (IS_STA_IN_P2P(prStaRec))) -+ p2pRunEventAAATxFail(prAdapter, prStaRec); -+#endif /* CFG_ENABLE_WIFI_DIRECT */ -+ -+#if CFG_ENABLE_BT_OVER_WIFI -+ if (IS_STA_IN_BOW(prStaRec)) -+ bowRunEventAAATxFail(prAdapter, prStaRec); -+#endif /* CFG_ENABLE_BT_OVER_WIFI */ -+ } -+ -+ } -+ /* NOTE(Kevin): Ignore the TX Done Event of Auth Frame with Error Status Code */ -+ -+ } -+ break; -+ -+ case AAA_STATE_SEND_ASSOC2: -+ { -+ /* Strictly check the outgoing frame is matched with current SAA STATE */ -+ if (assocCheckTxReAssocRespFrame(prAdapter, prMsduInfo) != WLAN_STATUS_SUCCESS) -+ break; -+ -+ if (STATUS_CODE_SUCCESSFUL == prStaRec->u2StatusCode) { -+ if (TX_RESULT_SUCCESS == rTxDoneStatus) { -+ -+ prStaRec->eAuthAssocState = AA_STATE_IDLE; -+ -+ /* NOTE(Kevin): Change to STATE_3 at TX Done */ -+#if CFG_ENABLE_WIFI_DIRECT -+ if ((prAdapter->fgIsP2PRegistered) && (IS_STA_IN_P2P(prStaRec))) -+ p2pRunEventAAASuccess(prAdapter, prStaRec); -+#endif /* CFG_ENABLE_WIFI_DIRECT */ -+ -+#if CFG_ENABLE_BT_OVER_WIFI -+ -+ if (IS_STA_IN_BOW(prStaRec)) -+ bowRunEventAAAComplete(prAdapter, prStaRec); -+#endif /* CFG_ENABLE_BT_OVER_WIFI */ -+ -+ } else { -+ -+ prStaRec->eAuthAssocState = AAA_STATE_SEND_AUTH2; -+ -+ /* NOTE(Kevin): Change to STATE_2 */ -+ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_2); -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ if ((prAdapter->fgIsP2PRegistered) && (IS_STA_IN_P2P(prStaRec))) -+ p2pRunEventAAATxFail(prAdapter, prStaRec); -+#endif /* CFG_ENABLE_WIFI_DIRECT */ -+ -+#if CFG_ENABLE_BT_OVER_WIFI -+ if (IS_STA_IN_BOW(prStaRec)) -+ bowRunEventAAATxFail(prAdapter, prStaRec); -+#endif /* CFG_ENABLE_BT_OVER_WIFI */ -+ -+ } -+ } -+ /* NOTE(Kevin): Ignore the TX Done Event of Auth Frame with Error Status Code */ -+ } -+ break; -+ -+ default: -+ break; /* Ignore other cases */ -+ } -+ -+ return WLAN_STATUS_SUCCESS; -+ -+} /* end of aaaFsmRunEventTxDone() */ -+#endif /* CFG_SUPPORT_AAA */ -+ -+#if 0 /* TODO(Kevin): for abort event, just reset the STA_RECORD_T. */ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will send ABORT Event to JOIN FSM. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID saaFsmRunEventAbort(IN P_MSG_HDR_T prMsgHdr) -+{ -+ P_JOIN_INFO_T prJoinInfo; -+ P_STA_RECORD_T prStaRec; -+ -+ DEBUGFUNC("joinFsmRunEventAbort"); -+ -+ ASSERT(prAdapter); -+ prJoinInfo = &prAdapter->rJoinInfo; -+ -+ DBGLOG(JOIN, EVENT, "JOIN EVENT: ABORT\n"); -+ -+ /* NOTE(Kevin): when reach here, the ARB_STATE should be in ARB_STATE_JOIN. */ -+ ASSERT(prJoinInfo->prBssDesc); -+ -+ /* 4 <1> Update Flags and Elements of JOIN Module. */ -+ /* Reset Send Auth/(Re)Assoc Frame Count */ -+ prJoinInfo->ucTxAuthAssocRetryCount = 0; -+ -+ /* Cancel all JOIN relative Timer */ -+ ARB_CANCEL_TIMER(prAdapter, prJoinInfo->rTxRequestTimer); -+ -+ ARB_CANCEL_TIMER(prAdapter, prJoinInfo->rRxResponseTimer); -+ -+ ARB_CANCEL_TIMER(prAdapter, prJoinInfo->rJoinTimer); -+ -+ /* 4 <2> Update the associated STA_RECORD_T during JOIN. */ -+ /* Get a Station Record if possible, TA == BSSID for AP */ -+ prStaRec = staRecGetStaRecordByAddr(prAdapter, prJoinInfo->prBssDesc->aucBSSID); -+ if (prStaRec) -+ prStaRec->ucStaState = STA_STATE_1; /* Update Station Record - Class 1 Flag */ -+#if DBG -+ else -+ ASSERT(0); /* Shouldn't happened, because we already add this STA_RECORD_T at JOIN_STATE_INIT */ -+#endif /* DBG */ -+ -+ /* 4 <3> Pull back to IDLE. */ -+ joinFsmSteps(prAdapter, JOIN_STATE_IDLE); -+ -+ /* 4 <4> If we are in Roaming, recover the settings of previous BSS. */ -+ /* NOTE: JOIN FAIL - -+ * Restore original setting from current BSS_INFO_T. -+ */ -+ if (prAdapter->eConnectionState == MEDIA_STATE_CONNECTED) -+ joinAdoptParametersFromCurrentBss(prAdapter); -+ -+} /* end of joinFsmRunEventAbort() */ -+#endif -+ -+/* TODO(Kevin): following code will be modified and move to AIS FSM */ -+#if 0 -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will send Join Timeout Event to JOIN FSM. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* -+* \retval WLAN_STATUS_FAILURE Fail because of Join Timeout -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS joinFsmRunEventJoinTimeOut(IN P_ADAPTER_T prAdapter) -+{ -+ P_JOIN_INFO_T prJoinInfo; -+ P_STA_RECORD_T prStaRec; -+ -+ DEBUGFUNC("joinFsmRunEventJoinTimeOut"); -+ -+ ASSERT(prAdapter); -+ prJoinInfo = &prAdapter->rJoinInfo; -+ -+ DBGLOG(JOIN, EVENT, "JOIN EVENT: JOIN TIMEOUT\n"); -+ -+ /* Get a Station Record if possible, TA == BSSID for AP */ -+ prStaRec = staRecGetStaRecordByAddr(prAdapter, prJoinInfo->prBssDesc->aucBSSID); -+ -+ /* We have renew this Sta Record when in JOIN_STATE_INIT */ -+ ASSERT(prStaRec); -+ -+ /* Record the Status Code of Authentication Request */ -+ prStaRec->u2StatusCode = STATUS_CODE_JOIN_TIMEOUT; -+ -+ /* Increase Failure Count */ -+ prStaRec->ucJoinFailureCount++; -+ -+ /* Reset Send Auth/(Re)Assoc Frame Count */ -+ prJoinInfo->ucTxAuthAssocRetryCount = 0; -+ -+ /* Cancel other JOIN relative Timer */ -+ ARB_CANCEL_TIMER(prAdapter, prJoinInfo->rTxRequestTimer); -+ -+ ARB_CANCEL_TIMER(prAdapter, prJoinInfo->rRxResponseTimer); -+ -+ /* Restore original setting from current BSS_INFO_T */ -+ if (prAdapter->eConnectionState == MEDIA_STATE_CONNECTED) -+ joinAdoptParametersFromCurrentBss(prAdapter); -+ -+ /* Pull back to IDLE */ -+ joinFsmSteps(prAdapter, JOIN_STATE_IDLE); -+ -+ return WLAN_STATUS_FAILURE; -+ -+} /* end of joinFsmRunEventJoinTimeOut() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will adopt the parameters from Peer BSS. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID joinAdoptParametersFromPeerBss(IN P_ADAPTER_T prAdapter) -+{ -+ P_JOIN_INFO_T prJoinInfo; -+ P_BSS_DESC_T prBssDesc; -+ -+ DEBUGFUNC("joinAdoptParametersFromPeerBss"); -+ -+ ASSERT(prAdapter); -+ prJoinInfo = &prAdapter->rJoinInfo; -+ prBssDesc = prJoinInfo->prBssDesc; -+ -+ /* 4 <1> Adopt Peer BSS' PHY TYPE */ -+ prAdapter->eCurrentPhyType = prBssDesc->ePhyType; -+ -+ DBGLOG(JOIN, INFO, "Target BSS[%s]'s PhyType = %s\n", -+ prBssDesc->aucSSID, (prBssDesc->ePhyType == PHY_TYPE_ERP_INDEX) ? "ERP" : "HR_DSSS"); -+ -+ /* 4 <2> Adopt Peer BSS' Frequency(Band/Channel) */ -+ DBGLOG(JOIN, INFO, "Target BSS's Channel = %d, Band = %d\n", prBssDesc->ucChannelNum, prBssDesc->eBand); -+ -+ nicSwitchChannel(prAdapter, prBssDesc->eBand, prBssDesc->ucChannelNum, 10); -+ -+ prJoinInfo->fgIsParameterAdopted = TRUE; -+ -+} /* end of joinAdoptParametersFromPeerBss() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will adopt the parameters from current associated BSS. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID joinAdoptParametersFromCurrentBss(IN P_ADAPTER_T prAdapter) -+{ -+ /* P_JOIN_INFO_T prJoinInfo = &prAdapter->rJoinInfo; */ -+ P_BSS_INFO_T prBssInfo; -+ -+ ASSERT(prAdapter); -+ prBssInfo = &prAdapter->rBssInfo; -+ -+ /* 4 <1> Adopt current BSS' PHY TYPE */ -+ prAdapter->eCurrentPhyType = prBssInfo->ePhyType; -+ -+ /* 4 <2> Adopt current BSS' Frequency(Band/Channel) */ -+ DBGLOG(JOIN, INFO, "Current BSS's Channel = %d, Band = %d\n", prBssInfo->ucChnl, prBssInfo->eBand); -+ -+ nicSwitchChannel(prAdapter, prBssInfo->eBand, prBssInfo->ucChnl, 10); -+ -+} /* end of joinAdoptParametersFromCurrentBss() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will update all the SW variables and HW MCR registers after -+* the association with target BSS. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID joinComplete(IN P_ADAPTER_T prAdapter) -+{ -+ P_JOIN_INFO_T prJoinInfo; -+ P_BSS_DESC_T prBssDesc; -+ P_PEER_BSS_INFO_T prPeerBssInfo; -+ P_BSS_INFO_T prBssInfo; -+ P_CONNECTION_SETTINGS_T prConnSettings; -+ P_STA_RECORD_T prStaRec; -+ P_TX_CTRL_T prTxCtrl; -+#if CFG_SUPPORT_802_11D -+ P_IE_COUNTRY_T prIECountry; -+#endif -+ -+ DEBUGFUNC("joinComplete"); -+ -+ ASSERT(prAdapter); -+ prJoinInfo = &prAdapter->rJoinInfo; -+ prBssDesc = prJoinInfo->prBssDesc; -+ prPeerBssInfo = &prAdapter->rPeerBssInfo; -+ prBssInfo = &prAdapter->rBssInfo; -+ prConnSettings = &prAdapter->rConnSettings; -+ prTxCtrl = &prAdapter->rTxCtrl; -+ -+/* 4 <1> Update Connecting & Connected Flag of BSS_DESC_T. */ -+ /* Remove previous AP's Connection Flags if have */ -+ scanRemoveConnectionFlagOfBssDescByBssid(prAdapter, prBssInfo->aucBSSID); -+ -+ prBssDesc->fgIsConnected = TRUE; /* Mask as Connected */ -+ -+ if (prBssDesc->fgIsHiddenSSID) { -+ /* NOTE(Kevin): This is for the case of Passive Scan and the target BSS didn't -+ * broadcast SSID on its Beacon Frame. -+ */ -+ COPY_SSID(prBssDesc->aucSSID, -+ prBssDesc->ucSSIDLen, prAdapter->rConnSettings.aucSSID, prAdapter->rConnSettings.ucSSIDLen); -+ -+ if (prBssDesc->ucSSIDLen) -+ prBssDesc->fgIsHiddenSSID = FALSE; -+#if DBG -+ else -+ ASSERT(0); -+#endif /* DBG */ -+ -+ DBGLOG(JOIN, INFO, "Hidden SSID! - Update SSID : %s\n", prBssDesc->aucSSID); -+ } -+/* 4 <2> Update BSS_INFO_T from BSS_DESC_T */ -+ /* 4 <2.A> PHY Type */ -+ prBssInfo->ePhyType = prBssDesc->ePhyType; -+ -+ /* 4 <2.B> BSS Type */ -+ prBssInfo->eBSSType = BSS_TYPE_INFRASTRUCTURE; -+ -+ /* 4 <2.C> BSSID */ -+ COPY_MAC_ADDR(prBssInfo->aucBSSID, prBssDesc->aucBSSID); -+ -+ DBGLOG(JOIN, INFO, "JOIN to BSSID: [%pM]\n", prBssDesc->aucBSSID); -+ -+ /* 4 <2.D> SSID */ -+ COPY_SSID(prBssInfo->aucSSID, prBssInfo->ucSSIDLen, prBssDesc->aucSSID, prBssDesc->ucSSIDLen); -+ -+ /* 4 <2.E> Channel / Band information. */ -+ prBssInfo->eBand = prBssDesc->eBand; -+ prBssInfo->ucChnl = prBssDesc->ucChannelNum; -+ -+ /* 4 <2.F> RSN/WPA information. */ -+ secFsmRunEventStart(prAdapter); -+ prBssInfo->u4RsnSelectedPairwiseCipher = prBssDesc->u4RsnSelectedPairwiseCipher; -+ prBssInfo->u4RsnSelectedGroupCipher = prBssDesc->u4RsnSelectedGroupCipher; -+ prBssInfo->u4RsnSelectedAKMSuite = prBssDesc->u4RsnSelectedAKMSuite; -+ -+ if (secRsnKeyHandshakeEnabled()) -+ prBssInfo->fgIsWPAorWPA2Enabled = TRUE; -+ else -+ prBssInfo->fgIsWPAorWPA2Enabled = FALSE; -+ -+ /* 4 <2.G> Beacon interval. */ -+ prBssInfo->u2BeaconInterval = prBssDesc->u2BeaconInterval; -+ -+ /* 4 <2.H> DTIM period. */ -+ prBssInfo->ucDtimPeriod = prBssDesc->ucDTIMPeriod; -+ -+ /* 4 <2.I> ERP Information */ -+ if ((prBssInfo->ePhyType == PHY_TYPE_ERP_INDEX) && /* Our BSS's PHY_TYPE is ERP now. */ -+ (prBssDesc->fgIsERPPresent)) { -+ -+ prBssInfo->fgIsERPPresent = TRUE; -+ prBssInfo->ucERP = prBssDesc->ucERP; /* Save the ERP for later check */ -+ } else { /* Some AP, may send ProbeResp without ERP IE. Thus prBssDesc->fgIsERPPresent is FALSE. */ -+ prBssInfo->fgIsERPPresent = FALSE; -+ prBssInfo->ucERP = 0; -+ } -+ -+#if CFG_SUPPORT_802_11D -+ /* 4 <2.J> Country inforamtion of the associated AP */ -+ if (prConnSettings->fgMultiDomainCapabilityEnabled) { -+ DOMAIN_INFO_ENTRY rDomainInfo; -+ -+ if (domainGetDomainInfoByScanResult(prAdapter, &rDomainInfo)) { -+ if (prBssDesc->prIECountry) { -+ prIECountry = prBssDesc->prIECountry; -+ -+ domainParseCountryInfoElem(prIECountry, &prBssInfo->rDomainInfo); -+ -+ /* use the domain get from the BSS info */ -+ prBssInfo->fgIsCountryInfoPresent = TRUE; -+ nicSetupOpChnlList(prAdapter, prBssInfo->rDomainInfo.u2CountryCode, FALSE); -+ } else { -+ /* use the domain get from the scan result */ -+ prBssInfo->fgIsCountryInfoPresent = TRUE; -+ nicSetupOpChnlList(prAdapter, rDomainInfo.u2CountryCode, FALSE); -+ } -+ } -+ } -+#endif -+ -+ /* 4 <2.K> Signal Power of the associated AP */ -+ prBssInfo->rRcpi = prBssDesc->rRcpi; -+ prBssInfo->rRssi = RCPI_TO_dBm(prBssInfo->rRcpi); -+ GET_CURRENT_SYSTIME(&prBssInfo->rRssiLastUpdateTime); -+ -+ /* 4 <2.L> Capability Field of the associated AP */ -+ prBssInfo->u2CapInfo = prBssDesc->u2CapInfo; -+ -+ DBGLOG(JOIN, INFO, "prBssInfo-> fgIsERPPresent = %d, ucERP = %02x, rRcpi = %d, rRssi = %ld\n", -+ prBssInfo->fgIsERPPresent, prBssInfo->ucERP, prBssInfo->rRcpi, prBssInfo->rRssi); -+ -+/* 4 <3> Update BSS_INFO_T from PEER_BSS_INFO_T & NIC RATE FUNC */ -+ /* 4 <3.A> Association ID */ -+ prBssInfo->u2AssocId = prPeerBssInfo->u2AssocId; -+ -+ /* 4 <3.B> WMM Information */ -+ if (prAdapter->fgIsEnableWMM && (prPeerBssInfo->rWmmInfo.ucWmmFlag & WMM_FLAG_SUPPORT_WMM)) { -+ -+ prBssInfo->fgIsWmmAssoc = TRUE; -+ prTxCtrl->rTxQForVoipAccess = TXQ_AC3; -+ -+ qosWmmInfoInit(&prBssInfo->rWmmInfo, (prBssInfo->ePhyType == PHY_TYPE_HR_DSSS_INDEX) ? TRUE : FALSE); -+ -+ if (prPeerBssInfo->rWmmInfo.ucWmmFlag & WMM_FLAG_AC_PARAM_PRESENT) { -+ kalMemCopy(&prBssInfo->rWmmInfo, &prPeerBssInfo->rWmmInfo, sizeof(WMM_INFO_T)); -+ } else { -+ kalMemCopy(&prBssInfo->rWmmInfo, -+ &prPeerBssInfo->rWmmInfo, -+ sizeof(WMM_INFO_T) - sizeof(prPeerBssInfo->rWmmInfo.arWmmAcParams)); -+ } -+ } else { -+ prBssInfo->fgIsWmmAssoc = FALSE; -+ prTxCtrl->rTxQForVoipAccess = TXQ_AC1; -+ -+ kalMemZero(&prBssInfo->rWmmInfo, sizeof(WMM_INFO_T)); -+ } -+ -+ /* 4 <3.C> Operational Rate Set & BSS Basic Rate Set */ -+ prBssInfo->u2OperationalRateSet = prPeerBssInfo->u2OperationalRateSet; -+ prBssInfo->u2BSSBasicRateSet = prPeerBssInfo->u2BSSBasicRateSet; -+ -+ /* 4 <3.D> Short Preamble */ -+ if (prBssInfo->fgIsERPPresent) { -+ -+ /* NOTE(Kevin 2007/12/24): Truth Table. -+ * Short Preamble Bit in -+ * Final Driver Setting(Short) -+ * TRUE FALSE FALSE FALSE(shouldn't have such case, -+ * use the AssocResp) -+ * TRUE FALSE TRUE FALSE -+ * FALSE FALSE FALSE FALSE(shouldn't have such case, -+ * use the AssocResp) -+ * FALSE FALSE TRUE FALSE -+ * TRUE TRUE FALSE TRUE(follow ERP) -+ * TRUE TRUE TRUE FALSE(follow ERP) -+ * FALSE TRUE FALSE FALSE(shouldn't have such case, -+ * and we should set to FALSE) -+ * FALSE TRUE TRUE FALSE(we should set to FALSE) -+ */ -+ if ((prPeerBssInfo->fgIsShortPreambleAllowed) && -+ ((prConnSettings->ePreambleType == PREAMBLE_TYPE_SHORT) || /* Short Preamble Option Enable is TRUE */ -+ ((prConnSettings->ePreambleType == PREAMBLE_TYPE_AUTO) && -+ (prBssDesc->u2CapInfo & CAP_INFO_SHORT_PREAMBLE)))) { -+ -+ prBssInfo->fgIsShortPreambleAllowed = TRUE; -+ -+ if (prBssInfo->ucERP & ERP_INFO_BARKER_PREAMBLE_MODE) -+ prBssInfo->fgUseShortPreamble = FALSE; -+ else -+ prBssInfo->fgUseShortPreamble = TRUE; -+ } else { -+ prBssInfo->fgIsShortPreambleAllowed = FALSE; -+ prBssInfo->fgUseShortPreamble = FALSE; -+ } -+ } else { -+ /* NOTE(Kevin 2007/12/24): Truth Table. -+ * Short Preamble Bit in -+ * Final Driver Setting(Short) -+ * TRUE FALSE FALSE -+ * FALSE FALSE FALSE -+ * TRUE TRUE TRUE -+ * FALSE TRUE(status success) TRUE -+ * --> Honor the result of prPeerBssInfo. -+ */ -+ -+ prBssInfo->fgIsShortPreambleAllowed = prBssInfo->fgUseShortPreamble = -+ prPeerBssInfo->fgIsShortPreambleAllowed; -+ } -+ -+ DBGLOG(JOIN, INFO, "prBssInfo->fgIsShortPreambleAllowed = %d, prBssInfo->fgUseShortPreamble = %d\n", -+ prBssInfo->fgIsShortPreambleAllowed, prBssInfo->fgUseShortPreamble); -+ -+ /* 4 <3.E> Short Slot Time */ -+ prBssInfo->fgUseShortSlotTime = prPeerBssInfo->fgUseShortSlotTime; /* AP support Short Slot Time */ -+ -+ DBGLOG(JOIN, INFO, "prBssInfo->fgUseShortSlotTime = %d\n", prBssInfo->fgUseShortSlotTime); -+ -+ nicSetSlotTime(prAdapter, -+ prBssInfo->ePhyType, -+ ((prConnSettings->fgIsShortSlotTimeOptionEnable && -+ prBssInfo->fgUseShortSlotTime) ? TRUE : FALSE)); -+ -+ /* 4 <3.F> Update Tx Rate for Control Frame */ -+ bssUpdateTxRateForControlFrame(prAdapter); -+ -+ /* 4 <3.G> Save the available Auth Types during Roaming (Design for Fast BSS Transition). */ -+ /* if (prAdapter->fgIsEnableRoaming) */ /* NOTE(Kevin): Always prepare info for roaming */ -+ { -+ -+ if (prJoinInfo->ucCurrAuthAlgNum == AUTH_ALGORITHM_NUM_OPEN_SYSTEM) -+ prJoinInfo->ucRoamingAuthTypes |= AUTH_TYPE_OPEN_SYSTEM; -+ else if (prJoinInfo->ucCurrAuthAlgNum == AUTH_ALGORITHM_NUM_SHARED_KEY) -+ prJoinInfo->ucRoamingAuthTypes |= AUTH_TYPE_SHARED_KEY; -+ -+ prBssInfo->ucRoamingAuthTypes = prJoinInfo->ucRoamingAuthTypes; -+ -+ /* Set the stable time of the associated BSS. We won't do roaming decision -+ * during the stable time. -+ */ -+ SET_EXPIRATION_TIME(prBssInfo->rRoamingStableExpirationTime, -+ SEC_TO_SYSTIME(ROAMING_STABLE_TIMEOUT_SEC)); -+ } -+ -+ /* 4 <3.H> Update Parameter for TX Fragmentation Threshold */ -+#if CFG_TX_FRAGMENT -+ txFragInfoUpdate(prAdapter); -+#endif /* CFG_TX_FRAGMENT */ -+ -+/* 4 <4> Update STA_RECORD_T */ -+ /* Get a Station Record if possible */ -+ prStaRec = staRecGetStaRecordByAddr(prAdapter, prBssDesc->aucBSSID); -+ -+ if (prStaRec) { -+ UINT_16 u2OperationalRateSet, u2DesiredRateSet; -+ -+ /* 4 <4.A> Desired Rate Set */ -+ u2OperationalRateSet = (rPhyAttributes[prBssInfo->ePhyType].u2SupportedRateSet & -+ prBssInfo->u2OperationalRateSet); -+ -+ u2DesiredRateSet = (u2OperationalRateSet & prConnSettings->u2DesiredRateSet); -+ if (u2DesiredRateSet) { -+ prStaRec->u2DesiredRateSet = u2DesiredRateSet; -+ } else { -+ /* For Error Handling - The Desired Rate Set is not covered in Operational Rate Set. */ -+ prStaRec->u2DesiredRateSet = u2OperationalRateSet; -+ } -+ -+ /* Try to set the best initial rate for this entry */ -+ if (!rateGetBestInitialRateIndex(prStaRec->u2DesiredRateSet, -+ prStaRec->rRcpi, &prStaRec->ucCurrRate1Index)) { -+ -+ if (!rateGetLowestRateIndexFromRateSet(prStaRec->u2DesiredRateSet, &prStaRec->ucCurrRate1Index)) -+ ASSERT(0); -+ } -+ -+ DBGLOG(JOIN, INFO, "prStaRec->ucCurrRate1Index = %d\n", prStaRec->ucCurrRate1Index); -+ -+ /* 4 <4.B> Preamble Mode */ -+ prStaRec->fgIsShortPreambleOptionEnable = prBssInfo->fgUseShortPreamble; -+ -+ /* 4 <4.C> QoS Flag */ -+ prStaRec->fgIsQoS = prBssInfo->fgIsWmmAssoc; -+ } -+#if DBG -+ else -+ ASSERT(0); -+#endif /* DBG */ -+ -+/* 4 <5> Update NIC */ -+ /* 4 <5.A> Update BSSID & Operation Mode */ -+ nicSetupBSS(prAdapter, prBssInfo); -+ -+ /* 4 <5.B> Update WLAN Table. */ -+ if (nicSetHwBySta(prAdapter, prStaRec) == FALSE) -+ ASSERT(FALSE); -+ /* 4 <5.C> Update Desired Rate Set for BT. */ -+#if CFG_TX_FRAGMENT -+ if (prConnSettings->fgIsEnableTxAutoFragmentForBT) -+ txRateSetInitForBT(prAdapter, prStaRec); -+#endif /* CFG_TX_FRAGMENT */ -+ -+ /* 4 <5.D> TX AC Parameter and TX/RX Queue Control */ -+ if (prBssInfo->fgIsWmmAssoc) { -+ -+#if CFG_TX_AGGREGATE_HW_FIFO -+ nicTxAggregateTXQ(prAdapter, FALSE); -+#endif /* CFG_TX_AGGREGATE_HW_FIFO */ -+ -+ qosUpdateWMMParametersAndAssignAllowedACI(prAdapter, &prBssInfo->rWmmInfo); -+ } else { -+ -+#if CFG_TX_AGGREGATE_HW_FIFO -+ nicTxAggregateTXQ(prAdapter, TRUE); -+#endif /* CFG_TX_AGGREGATE_HW_FIFO */ -+ -+ nicTxNonQoSAssignDefaultAdmittedTXQ(prAdapter); -+ -+ nicTxNonQoSUpdateTXQParameters(prAdapter, prBssInfo->ePhyType); -+ } -+ -+#if CFG_TX_STOP_WRITE_TX_FIFO_UNTIL_JOIN -+ { -+ prTxCtrl->fgBlockTxDuringJoin = FALSE; -+ -+#if !CFG_TX_AGGREGATE_HW_FIFO /* TX FIFO AGGREGATE already do flush once */ -+ nicTxFlushStopQueues(prAdapter, (UINT_8) TXQ_DATA_MASK, (UINT_8) NULL); -+#endif /* CFG_TX_AGGREGATE_HW_FIFO */ -+ -+ nicTxRetransmitOfSendWaitQue(prAdapter); -+ -+ if (prTxCtrl->fgIsPacketInOsSendQueue) -+ nicTxRetransmitOfOsSendQue(prAdapter); -+#if CFG_SDIO_TX_ENHANCE -+ halTxLeftClusteredMpdu(prAdapter); -+#endif /* CFG_SDIO_TX_ENHANCE */ -+ -+ } -+#endif /* CFG_TX_STOP_WRITE_TX_FIFO_UNTIL_JOIN */ -+ -+/* 4 <6> Setup CONNECTION flag. */ -+ prAdapter->eConnectionState = MEDIA_STATE_CONNECTED; -+ prAdapter->eConnectionStateIndicated = MEDIA_STATE_CONNECTED; -+ -+ if (prJoinInfo->fgIsReAssoc) -+ prAdapter->fgBypassPortCtrlForRoaming = TRUE; -+ else -+ prAdapter->fgBypassPortCtrlForRoaming = FALSE; -+ -+ kalIndicateStatusAndComplete(prAdapter->prGlueInfo, WLAN_STATUS_MEDIA_CONNECT, (PVOID) NULL, 0); -+ -+} /* end of joinComplete() */ -+#endif -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/ais_fsm.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/ais_fsm.c -new file mode 100644 -index 000000000000..7b5a49a5ba63 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/ais_fsm.c -@@ -0,0 +1,5039 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/ais_fsm.c#1 -+*/ -+ -+/*! \file "aa_fsm.c" -+ \brief This file defines the FSM for SAA and AAA MODULE. -+ -+ This file defines the FSM for SAA and AAA MODULE. -+*/ -+ -+/* -+** Log: ais_fsm.c -+** -+** 09 06 2013 cp.wu -+** always paste SSID information to SAA-FSM -+** -+** 09 06 2013 cp.wu -+** add error handling when reassociation request failed to locate bss descriptor -+** -+** 09 05 2013 cp.wu -+** isolate logic regarding roaming & reassociation -+** -+** 09 04 2013 cp.wu -+** fix typo -+** -+** 09 03 2013 cp.wu -+** add path for reassociation -+ * -+ * 04 20 2012 cp.wu -+ * [WCXRP00000913] [MT6620 Wi-Fi] create repository of source code dedicated for MT6620 E6 ASIC -+ * correct macro -+ * -+ * 01 16 2012 cp.wu -+ * [MT6620 Wi-Fi][Driver] API and behavior modification for preferred band configuration with -+ * corresponding network configuration -+ * add wlanSetPreferBandByNetwork() for glue layer to invoke for setting preferred band configuration -+ * corresponding to network type. -+ * -+ * 11 24 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * Adjust code for DBG and CONFIG_XLOG. -+ * -+ * 11 22 2011 cp.wu -+ * [WCXRP00001120] [MT6620 Wi-Fi][Driver] Modify roaming to AIS state transition from synchronous -+ * to asynchronous approach to avoid incomplete state termination -+ * 1. change RDD related compile option brace position. -+ * 2. when roaming is triggered, ask AIS to transit immediately only when AIS is in Normal TR state -+ * without join timeout timer ticking -+ * 3. otherwise, insert AIS_REQUEST into pending request queue -+ * -+ * 11 11 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * modify the xlog related code. -+ * -+ * 11 04 2011 cp.wu -+ * [WCXRP00001086] [MT6620 Wi-Fi][Driver] On Android, indicate an extra DISCONNECT for REASSOCIATED -+ * cases as an explicit trigger for Android framework -+ * correct reference to BSSID field in Association-Response frame. -+ * -+ * 11 04 2011 cp.wu -+ * [WCXRP00001086] [MT6620 Wi-Fi][Driver] On Android, indicate an extra DISCONNECT for REASSOCIATED -+ * cases as an explicit trigger for Android framework -+ * 1. for DEAUTH/DISASSOC cases, indicate for DISCONNECTION immediately. -+ * 2. (Android only) when reassociation-and-non-roaming cases happened, indicate an extra DISCONNECT -+ * indication to Android Wi-Fi framework -+ * -+ * 11 02 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * adding the code for XLOG. -+ * -+ * 10 26 2011 tsaiyuan.hsu -+ * [WCXRP00001064] [MT6620 Wi-Fi][DRV]] add code with roaming awareness when disconnecting AIS network -+ * be aware roaming when disconnecting AIS network. -+ * -+ * 10 25 2011 cm.chang -+ * [WCXRP00001058] [All Wi-Fi][Driver] Fix sta_rec's phyTypeSet and OBSS scan in AP mode -+ * STA_REC shall be NULL for Beacon's MSDU -+ * -+ * 10 13 2011 cp.wu -+ * [MT6620 Wi-Fi][Driver] Reduce join failure count limit to 2 for faster re-join for other BSS -+ * 1. short join failure count limit to 2 -+ * 2. treat join timeout as kind of join failure as well -+ * -+ * 10 12 2011 wh.su -+ * [WCXRP00001036] [MT6620 Wi-Fi][Driver][FW] Adding the 802.11w code for MFP -+ * adding the 802.11w related function and define . -+ * -+ * 09 30 2011 cm.chang -+ * [WCXRP00001020] [MT6620 Wi-Fi][Driver] Handle secondary channel offset of AP in 5GHz band -+ * . -+ * -+ * 09 20 2011 tsaiyuan.hsu -+ * [WCXRP00000931] [MT5931 Wi-Fi][DRV/FW] add swcr to disable roaming from driver -+ * change window registry of driver for roaming. -+ * -+ * 09 20 2011 cm.chang -+ * [WCXRP00000997] [MT6620 Wi-Fi][Driver][FW] Handle change of BSS preamble type and slot time -+ * Handle client mode about preamble type and slot time -+ * -+ * 09 08 2011 tsaiyuan.hsu -+ * [WCXRP00000972] [MT6620 Wi-Fi][DRV]] check if roaming occurs after join failure to avoid state incosistence. -+ * check if roaming occurs after join failure to avoid deactivation of network. -+ * -+ * 08 24 2011 chinghwa.yu -+ * [WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm -+ * Update RDD test mode cases. -+ * -+ * 08 16 2011 tsaiyuan.hsu -+ * [WCXRP00000931] [MT5931 Wi-Fi][DRV/FW] add swcr to disable roaming from driver -+ * EnableRoaming in registry is deprecated. -+ * -+ * 08 16 2011 tsaiyuan.hsu -+ * [WCXRP00000931] [MT5931 Wi-Fi][DRV/FW] add swcr to disable roaming from driver -+ * use registry to enable or disable roaming. -+ * -+ * 07 07 2011 cp.wu -+ * [WCXRP00000840] [MT6620 Wi-Fi][Driver][AIS] Stop timer for joining when channel is released -+ * due to join failure count exceeding limit -+ * stop timer when joining operation is failed due to try count exceeds limitation -+ * -+ * 06 28 2011 cp.wu -+ * [WCXRP00000815] [MT6620 Wi-Fi][Driver] allow single BSSID with multiple SSID settings to work -+ * around some tricky AP which use space character as hidden SSID -+ * do not handle SCAN request immediately after connected to increase the probability of receiving 1st beacon frame. -+ * -+ * 06 23 2011 cp.wu -+ * [WCXRP00000798] [MT6620 Wi-Fi][Firmware] Follow-ups for WAPI frequency offset workaround in firmware SCN module -+ * change parameter name from PeerAddr to BSSID -+ * -+ * 06 20 2011 cp.wu -+ * [WCXRP00000798] [MT6620 Wi-Fi][Firmware] Follow-ups for WAPI frequency offset workaround in firmware SCN module -+ * 1. specify target's BSSID when requesting channel privilege. -+ * 2. pass BSSID information to firmware domain -+ * -+ * 06 16 2011 cp.wu -+ * [WCXRP00000782] [MT6620 Wi-Fi][AIS] Treat connection at higher priority over scanning to avoid WZC connection timeout -+ * ensure DEAUTH is always sent before establish a new connection -+ * -+ * 06 16 2011 cp.wu -+ * [WCXRP00000782] [MT6620 Wi-Fi][AIS] Treat connection at higher priority over scanning to avoid WZC connection timeout -+ * typo fix: a right brace is missed. -+ * -+ * 06 16 2011 cp.wu -+ * [WCXRP00000782] [MT6620 Wi-Fi][AIS] Treat connection at higher priority over scanning to avoid WZC connection timeout -+ * When RECONNECT request is identified as disconnected, it is necessary to check for pending scan request. -+ * -+ * 06 16 2011 cp.wu -+ * [WCXRP00000757] [MT6620 Wi-Fi][Driver][SCN] take use of RLM API to filter out BSS in disallowed channels -+ * mark fgIsTransition as TRUE for state rolling. -+ * -+ * 06 16 2011 cp.wu -+ * [WCXRP00000782] [MT6620 Wi-Fi][AIS] Treat connection at higher priority over scanning to avoid WZC connection timeout -+ * always check for pending scan after switched into NORMAL_TR state. -+ * -+ * 06 14 2011 cp.wu -+ * [WCXRP00000782] [MT6620 Wi-Fi][AIS] Treat connection at higher priority over scanning to avoid WZC connection timeout -+ * always treat connection request at higher priority over scanning request -+ * -+ * 06 09 2011 tsaiyuan.hsu -+ * [WCXRP00000760] [MT5931 Wi-Fi][FW] Refine rxmHandleMacRxDone to reduce code size -+ * move send_auth at rxmHandleMacRxDone in firmware to driver to reduce code size. -+ * -+ * 06 02 2011 cp.wu -+ * [WCXRP00000681] [MT5931][Firmware] HIF code size reduction -+ * eliminate unused parameters for SAA-FSM -+ * -+ * 05 18 2011 cp.wu -+ * [WCXRP00000732] [MT6620 Wi-Fi][AIS] No need to switch back to IDLE state -+ * when DEAUTH frame is dropped due to bss disconnection -+ * change SCAN handling behavior when followed by a CONNECT/DISCONNECT requests by pending instead of dropping. -+ * -+ * 05 17 2011 cp.wu -+ * [WCXRP00000732] [MT6620 Wi-Fi][AIS] No need to switch back to IDLE state -+ * when DEAUTH frame is dropped due to bss disconnection -+ * when TX DONE status is TX_RESULT_DROPPED_IN_DRIVER, no need to switch back to IDLE state. -+ * -+ * 04 14 2011 cm.chang -+ * [WCXRP00000634] [MT6620 Wi-Fi][Driver][FW] 2nd BSS will not support 40MHz bandwidth for concurrency -+ * . -+ * -+ * 04 13 2011 george.huang -+ * [WCXRP00000628] [MT6620 Wi-Fi][FW][Driver] Modify U-APSD setting to default OFF -+ * remove assert -+ * -+ * 03 18 2011 cp.wu -+ * [WCXRP00000575] [MT6620 Wi-Fi][Driver][AIS] reduce memory usage when generating mailbox message for scan request -+ * when there is no IE needed for probe request, then request a smaller memory for mailbox message -+ * -+ * 03 17 2011 chinglan.wang -+ * [WCXRP00000570] [MT6620 Wi-Fi][Driver] Add Wi-Fi Protected Setup v2.0 feature -+ * . -+ * -+ * 03 17 2011 chinglan.wang -+ * [WCXRP00000570] [MT6620 Wi-Fi][Driver] Add Wi-Fi Protected Setup v2.0 feature -+ * . -+ * -+ * 03 16 2011 tsaiyuan.hsu -+ * [WCXRP00000517] [MT6620 Wi-Fi][Driver][FW] Fine Tune Performance of Roaming -+ * remove obsolete definition and unused variables. -+ * -+ * 03 11 2011 cp.wu -+ * [WCXRP00000535] [MT6620 Wi-Fi][Driver] Fixed channel operation when AIS and Tethering are operating concurrently -+ * When fixed channel operation is necessary, AIS-FSM would scan and only connect for BSS on the specific channel -+ * -+ * 03 09 2011 tsaiyuan.hsu -+ * [WCXRP00000517] [MT6620 Wi-Fi][Driver][FW] Fine Tune Performance of Roaming -+ * avoid clearing fgIsScanReqIssued so as to add scan results. -+ * -+ * 03 07 2011 terry.wu -+ * [WCXRP00000521] [MT6620 Wi-Fi][Driver] Remove non-standard debug message -+ * Toggle non-standard debug messages to comments. -+ * -+ * 03 04 2011 tsaiyuan.hsu -+ * [WCXRP00000517] [MT6620 Wi-Fi][Driver][FW] Fine Tune Performance of Roaming -+ * reset retry conter of attemp to connect to ap after completion of join. -+ * -+ * 03 04 2011 cp.wu -+ * [WCXRP00000515] [MT6620 Wi-Fi][Driver] Surpress compiler warning which is identified by GNU compiler collection -+ * surpress compile warning occurred when compiled by GNU compiler collection. -+ * -+ * 03 02 2011 cp.wu -+ * [WCXRP00000503] [MT6620 Wi-Fi][Driver] Take RCPI brought by association response as initial RSSI right -+ * after connection is built. -+ * use RCPI brought by ASSOC-RESP after connection is built as initial RCPI to avoid using a uninitialized MAC-RX RCPI. -+ * -+ * 02 26 2011 tsaiyuan.hsu -+ * [WCXRP00000391] [MT6620 Wi-Fi][FW] Add Roaming Support -+ * not send disassoc or deauth to leaving AP so as to improve performace of roaming. -+ * -+ * 02 23 2011 cp.wu -+ * [WCXRP00000487] [MT6620 Wi-Fi][Driver][AIS] Serve scan and connect request with a queue-based approach to -+ * improve response time for scanning request -+ * when handling reconnect request, set fgTryScan as TRUE -+ * -+ * 02 22 2011 cp.wu -+ * [WCXRP00000487] [MT6620 Wi-Fi][Driver][AIS] Serve scan and connect request with a queue-based approach -+ * to improve response time for scanning request -+ * handle SCAN and RECONNECT with a FIFO approach. -+ * -+ * 02 09 2011 tsaiyuan.hsu -+ * [WCXRP00000392] [MT6620 Wi-Fi][Driver] Add Roaming Support -+ * Check if prRegInfo is null or not before initializing roaming parameters. -+ * -+ * 02 01 2011 cp.wu -+ * [WCXRP00000416] [MT6620 Wi-Fi][Driver] treat "unable to find BSS" as connection trial -+ * to prevent infinite reconnection trials -+ * treat "unable to find BSS" as connection trial to prevent infinite reconnection trials. -+ * -+ * 01 27 2011 tsaiyuan.hsu -+ * [WCXRP00000392] [MT6620 Wi-Fi][Driver] Add Roaming Support -+ * add roaming fsm -+ * 1. not support 11r, only use strength of signal to determine roaming. -+ * 2. not enable CFG_SUPPORT_ROAMING until completion of full test. -+ * 3. in 6620, adopt work-around to avoid sign extension problem of cck of hw -+ * 4. assume that change of link quality in smooth way. -+ * -+ * 01 26 2011 yuche.tsai -+ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record. -+ * . -+ * -+ * 01 25 2011 yuche.tsai -+ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record. -+ * Fix Compile Error when DBG is disabled. -+ * -+ * 01 25 2011 yuche.tsai -+ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record. -+ * Change Station Type in Station Record, Modify MACRO definition for getting station type & network type index & Role. -+ * -+ * 01 14 2011 cp.wu -+ * [WCXRP00000359] [MT6620 Wi-Fi][Driver] add an extra state to ensure DEAUTH frame is always sent -+ * Add an extra state to guarantee DEAUTH frame is sent then connect to new BSS. -+ * This change is due to WAPI AP needs DEAUTH frame as a necessary step in handshaking protocol. -+ * -+ * 01 11 2011 cp.wu -+ * [WCXRP00000307] [MT6620 Wi-Fi][SQA]WHQL test .2c_wlan_adhoc case fail. -+ * [IBSS] when merged in, the bss state should be updated to firmware to pass WHQL adhoc failed item -+ * -+ * 01 10 2011 cp.wu -+ * [WCXRP00000351] [MT6620 Wi-Fi][Driver] remove from scanning result in OID handling layer -+ * when the corresponding BSS is disconnected due to beacon timeout -+ * remove from scanning result when the BSS is disconnected due to beacon timeout. -+ * -+ * 01 03 2011 cp.wu -+ * [WCXRP00000337] [MT6620 Wi-FI][Driver] AIS-FSM not to invoke cnmStaRecResetStatus -+ * directly 'cause it frees all belonging STA-RECs -+ * do not invoke cnmStaRecResetStatus() directly, nicUpdateBss will do the things after bss is disconnected -+ * -+ * 12 30 2010 cp.wu -+ * [WCXRP00000270] [MT6620 Wi-Fi][Driver] Clear issues after concurrent networking support has been merged -+ * do not need to manipulate prStaRec after indicating BSS disconnection to firmware, -+ * 'cause all STA-RECs belongs to BSS has been freed already -+ * -+ * 12 27 2010 cp.wu -+ * [WCXRP00000269] [MT6620 Wi-Fi][Driver][Firmware] Prepare for v1.1 branch release -+ * add DEBUGFUNC() macro invoking for more detailed debugging information -+ * -+ * 12 23 2010 george.huang -+ * [WCXRP00000152] [MT6620 Wi-Fi] AP mode power saving function -+ * 1. update WMM IE parsing, with ASSOC REQ handling -+ * 2. extend U-APSD parameter passing from driver to FW -+ * -+ * 12 17 2010 cp.wu -+ * [WCXRP00000270] [MT6620 Wi-Fi][Driver] Clear issues after concurrent networking support has been merged -+ * before BSS disconnection is indicated to firmware, all correlated peer should be cleared and freed -+ * -+ * 12 07 2010 cm.chang -+ * [WCXRP00000239] MT6620 Wi-Fi][Driver][FW] Merge concurrent branch back to maintrunk -+ * 1. BSSINFO include RLM parameter -+ * 2. free all sta records when network is disconnected -+ * -+ * 11 25 2010 yuche.tsai -+ * NULL -+ * Update SLT Function for QoS Support and not be affected by fixed rate function. -+ * -+ * 11 25 2010 cp.wu -+ * [WCXRP00000208] [MT6620 Wi-Fi][Driver] Add scanning with specified SSID to AIS FSM -+ * add scanning with specified SSID facility to AIS-FSM -+ * -+ * 11 01 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with -+ * Version Check[WCXRP00000150] [MT6620 Wi-Fi][Driver] Add implementation for querying current TX rate -+ * from firmware auto rate module -+ * 1) Query link speed (TX rate) from firmware directly with buffering mechanism to reduce overhead -+ * 2) Remove CNM CH-RECOVER event handling -+ * 3) cfg read/write API renamed with kal prefix for unified naming rules. -+ * -+ * 10 26 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000137] [MT6620 Wi-Fi] [FW] -+ * Support NIC capability query command -+ * 1) update NVRAM content template to ver 1.02 -+ * 2) add compile option for querying NIC capability (default: off) -+ * 3) modify AIS 5GHz support to run-time option, which could be turned on by registry or NVRAM setting -+ * 4) correct auto-rate compiler error under linux (treat warning as error) -+ * 5) simplify usage of NVRAM and REG_INFO_T -+ * 6) add version checking between driver and firmware -+ * -+ * 10 14 2010 wh.su -+ * [WCXRP00000097] [MT6620 Wi-Fi] [Driver] Fixed the P2P not setting the fgIsChannelExt value make scan not abort -+ * initial the fgIsChannelExt value. -+ * -+ * 10 08 2010 cp.wu -+ * [WCXRP00000087] [MT6620 Wi-Fi][Driver] Cannot connect to 5GHz AP, driver will cause FW assert. -+ * correct erroneous logic: specifying eBand with incompatible eSco -+ * -+ * 10 04 2010 cp.wu -+ * [WCXRP00000077] [MT6620 Wi-Fi][Driver][FW] Eliminate use of ENUM_NETWORK_TYPE_T -+ * and replaced by ENUM_NETWORK_TYPE_INDEX_T only -+ * remove ENUM_NETWORK_TYPE_T definitions -+ * -+ * 09 27 2010 chinghwa.yu -+ * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000065] Update BoW design and settings -+ * Update BCM/BoW design and settings. -+ * -+ * 09 23 2010 cp.wu -+ * [WCXRP00000049] [MT6620 Wi-Fi][Driver] Adhoc cannot be created successfully. -+ * keep IBSS-ALONE state retrying until further instruction is received -+ * -+ * 09 21 2010 cp.wu -+ * [WCXRP00000053] [MT6620 Wi-Fi][Driver] Reset incomplete and might leads to BSOD -+ * when entering RF test with AIS associated -+ * Do a complete reset with STA-REC null checking for RF test re-entry -+ * -+ * 09 09 2010 yuche.tsai -+ * NULL -+ * Fix NULL IE Beacon issue. Sync Beacon Content to FW before enable beacon. -+ * Both in IBSS Create & IBSS Merge -+ * -+ * 09 09 2010 cp.wu -+ * NULL -+ * frequency is in unit of KHz thus no need to divide 1000 once more. -+ * -+ * 09 06 2010 cp.wu -+ * NULL -+ * 1) initialize for correct parameter even for disassociation. -+ * 2) AIS-FSM should have a limit on trials to build connection -+ * -+ * 09 03 2010 kevin.huang -+ * NULL -+ * Refine #include sequence and solve recursive/nested #include issue -+ * -+ * 08 30 2010 cp.wu -+ * NULL -+ * eliminate klockwork errors -+ * -+ * 08 29 2010 yuche.tsai -+ * NULL -+ * Finish SLT TX/RX & Rate Changing Support. -+ * -+ * 08 25 2010 cp.wu -+ * NULL -+ * add option for enabling AIS 5GHz scan -+ * -+ * 08 25 2010 cp.wu -+ * NULL -+ * [AIS-FSM] IBSS no longer needs to acquire channel for beaconing, -+ * RLM/CNM will handle the channel switching when BSS information is updated -+ * -+ * 08 25 2010 george.huang -+ * NULL -+ * update OID/ registry control path for PM related settings -+ * -+ * 08 24 2010 cm.chang -+ * NULL -+ * Support RLM initail channel of Ad-hoc, P2P and BOW -+ * -+ * 08 20 2010 cm.chang -+ * NULL -+ * Migrate RLM code to host from FW -+ * -+ * 08 12 2010 cp.wu -+ * NULL -+ * check-in missed files. -+ * -+ * 08 12 2010 kevin.huang -+ * NULL -+ * Refine bssProcessProbeRequest() and bssSendBeaconProbeResponse() -+ * -+ * 08 09 2010 cp.wu -+ * NULL -+ * reset fgIsScanReqIssued when abort request is received right after join completion. -+ * -+ * 08 03 2010 cp.wu -+ * NULL -+ * surpress compilation warning. -+ * -+ * 08 02 2010 cp.wu -+ * NULL -+ * comment out deprecated members in BSS_INFO, which are only used by firmware rather than driver. -+ * -+ * 07 30 2010 cp.wu -+ * NULL -+ * 1) BoW wrapper: use definitions instead of hard-coded constant for error code -+ * 2) AIS-FSM: eliminate use of desired RF parameters, use prTargetBssDesc instead -+ * 3) add handling for RX_PKT_DESTINATION_HOST_WITH_FORWARD for GO-broadcast frames -+ * -+ * 07 29 2010 cp.wu -+ * NULL -+ * eliminate u4FreqInKHz usage, combined into rConnections.ucAdHoc* -+ * -+ * 07 29 2010 cp.wu -+ * NULL -+ * allocate on MGMT packet for IBSS beaconing. -+ * -+ * 07 29 2010 cp.wu -+ * NULL -+ * [AIS-FSM] fix: when join failed, release channel privilege as well -+ * -+ * 07 28 2010 cp.wu -+ * NULL -+ * reuse join-abort sub-procedure to reduce code size. -+ * -+ * 07 28 2010 cp.wu -+ * NULL -+ * 1) eliminate redundant variable eOPMode in prAdapter->rWlanInfo -+ * 2) change nicMediaStateChange() API prototype -+ * -+ * 07 26 2010 cp.wu -+ * -+ * AIS-FSM: when scan request is coming in the 1st 5 seconds of channel privilege period, -+ * just pend it til 5-sec. period finishes -+ * -+ * 07 26 2010 cp.wu -+ * -+ * AIS-FSM FIX: return channel privilege even when the privilege is not granted yet -+ * QM: qmGetFrameAction() won't assert when corresponding STA-REC index is not found -+ * -+ * 07 26 2010 cp.wu -+ * -+ * re-commit code logic being overwriten. -+ * -+ * 07 24 2010 wh.su -+ * -+ * .support the Wi-Fi RSN -+ * -+ * 07 23 2010 cp.wu -+ * -+ * 1) re-enable AIS-FSM beacon timeout handling. -+ * 2) scan done API revised -+ * -+ * 07 23 2010 cp.wu -+ * -+ * 1) enable Ad-Hoc -+ * 2) disable beacon timeout handling temporally due to unexpected beacon timeout event. -+ * -+ * 07 23 2010 cp.wu -+ * -+ * indicate scan done for linux wireless extension -+ * -+ * 07 23 2010 cp.wu -+ * -+ * add AIS-FSM handling for beacon timeout event. -+ * -+ * 07 22 2010 cp.wu -+ * -+ * 1) refine AIS-FSM indent. -+ * 2) when entering RF Test mode, flush 802.1X frames as well -+ * 3) when entering D3 state, flush 802.1X frames as well -+ * -+ * 07 21 2010 cp.wu -+ * -+ * separate AIS-FSM states into different cases of channel request. -+ * -+ * 07 21 2010 cp.wu -+ * -+ * 1) change BG_SCAN to ONLINE_SCAN for consistent term -+ * 2) only clear scanning result when scan is permitted to do -+ * -+ * 07 20 2010 cp.wu -+ * -+ * 1) [AIS] when new scan is issued, clear currently available scanning result except the connected one -+ * 2) refine disconnection behaviour when issued during BG-SCAN process -+ * -+ * 07 20 2010 cp.wu -+ * -+ * 1) bugfix: do not stop timer for join after switched into normal_tr state, -+ * for providing chance for DHCP handshasking -+ * 2) modify rsnPerformPolicySelection() invoking -+ * -+ * 07 19 2010 cp.wu -+ * -+ * 1) init AIS_BSS_INFO as channel number = 1 with band = 2.4GHz -+ * 2) correct typo -+ * -+ * 07 19 2010 wh.su -+ * -+ * update for security supporting. -+ * -+ * 07 19 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration. -+ * when IBSS is being merged-in, send command packet to PM for connected indication -+ * -+ * 07 19 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration. -+ * Add Ad-Hoc support to AIS-FSM -+ * -+ * 07 19 2010 jeffrey.chang -+ * -+ * Linux port modification -+ * -+ * 07 16 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration. -+ * bugfix for SCN migration -+ * 1) modify QUEUE_CONCATENATE_QUEUES() so it could be used to concatence with an empty queue -+ * 2) before AIS issues scan request, network(BSS) needs to be activated first -+ * 3) only invoke COPY_SSID when using specified SSID for scan -+ * -+ * 07 15 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration. -+ * for AIS scanning, driver specifies no extra IE for probe request -+ * -+ * 07 15 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration. -+ * driver no longer generates probe request frames -+ * -+ * 07 14 2010 yarco.yang -+ * -+ * Remove CFG_MQM_MIGRATION -+ * -+ * 07 14 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration. -+ * Refine AIS-FSM by divided into more states -+ * -+ * 07 13 2010 cm.chang -+ * -+ * Rename MSG_CH_RELEASE_T to MSG_CH_ABORT_T -+ * -+ * 07 09 2010 cp.wu -+ * -+ * 1) separate AIS_FSM state for two kinds of scanning. (OID triggered scan, and scan-for-connection) -+ * 2) eliminate PRE_BSS_DESC_T, Beacon/PrebResp is now parsed in single pass -+ * 3) implment DRV-SCN module, currently only accepts single scan request, -+ * other request will be directly dropped by returning BUSY -+ * -+ * 07 09 2010 george.huang -+ * -+ * [WPD00001556] Migrate PM variables from FW to driver: for composing QoS Info -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 07 08 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * take use of RLM module for parsing/generating HT IEs for 11n capability -+ * -+ * 07 08 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Rename MID_MNY_CNM_CH_RELEASE to MID_MNY_CNM_CH_ABORT -+ * -+ * 07 07 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * for first connection, if connecting failed do not enter into scan state. -+ * -+ * 07 06 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * once STA-REC is allocated and updated, invoke cnmStaRecChangeState() to sync. with firmware. -+ * -+ * 07 06 2010 george.huang -+ * [WPD00001556]Basic power managemenet function -+ * Update arguments for nicUpdateBeaconIETemplate() -+ * -+ * 07 06 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * STA-REC is maintained by CNM only. -+ * -+ * 07 05 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * remove unused definitions. -+ * -+ * 07 01 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * AIS-FSM integration with CNM channel request messages -+ * -+ * 07 01 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * implementation of DRV-SCN and related mailbox message handling. -+ * -+ * 06 30 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * sync. with CMD/EVENT document ver0.07. -+ * -+ * 06 29 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) sync to. CMD/EVENT document v0.03 -+ * 2) simplify DTIM period parsing in scan.c only, bss.c no longer parses it again. -+ * 3) send command packet to indicate FW-PM after -+ * a) 1st beacon is received after AIS has connected to an AP -+ * b) IBSS-ALONE has been created -+ * c) IBSS-MERGE has occurred -+ * -+ * 06 25 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * modify Beacon/ProbeResp to complete parsing, -+ * because host software has looser memory usage restriction -+ * -+ * 06 23 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * integrate . -+ * -+ * 06 22 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * comment out RLM APIs by CFG_RLM_MIGRATION. -+ * -+ * 06 22 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) add command warpper for STA-REC/BSS-INFO sync. -+ * 2) enhance command packet sending procedure for non-oid part -+ * 3) add command packet definitions for STA-REC/BSS-INFO sync. -+ * -+ * 06 21 2010 yarco.yang -+ * [WPD00003837][MT6620]Data Path Refine -+ * Support CFG_MQM_MIGRATION flag -+ * -+ * 06 21 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add scan_fsm into building. -+ * -+ * 06 21 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * RSN/PRIVACY compilation flag awareness correction -+ * -+ * 06 18 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Provide cnmMgtPktAlloc() and alloc/free function of msg/buf -+ * -+ * 06 18 2010 wh.su -+ * [WPD00003840][MT6620 5931] Security migration -+ * migration from MT6620 firmware. -+ * -+ * 06 15 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add scan.c. -+ * -+ * 06 14 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * restore utility function invoking via hem_mbox to direct calls -+ * -+ * 06 11 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * auth.c is migrated. -+ * -+ * 06 11 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add bss.c. -+ * -+ * 06 11 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) migrate assoc.c. -+ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness -+ * 3) add configuration options for CNM_MEM and RSN modules -+ * 4) add data path for management frames -+ * 5) eliminate rPacketInfo of MSDU_INFO_T -+ * -+ * 06 10 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * change to enqueue TX frame infinitely. -+ * -+ * 06 10 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) eliminate CFG_CMD_EVENT_VERSION_0_9 -+ * 2) when disconnected, indicate nic directly (no event is needed) -+ * -+ * 06 10 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add buildable & linkable ais_fsm.c -+ * -+ * related reference are still waiting to be resolved -+ * -+ * 06 01 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Add conditionial compiling flag to choose default available bandwidth -+ * -+ * 05 28 2010 kevin.huang -+ * [BORA00000794][WIFISYS][New Feature]Power Management Support -+ * Add ClientList handling API - bssClearClientList, bssAddStaRecToClientList -+ * -+ * 05 24 2010 kevin.huang -+ * [BORA00000794][WIFISYS][New Feature]Power Management Support -+ * Refine authSendAuthFrame() for NULL STA_RECORD_T case and minimum deauth interval. -+ * -+ * 05 21 2010 kevin.huang -+ * [BORA00000794][WIFISYS][New Feature]Power Management Support -+ * Fix compile error if CFG_CMD_EVENT_VER_009 == 0 for prEventConnStatus->ucNetworkType. -+ * -+ * 05 21 2010 kevin.huang -+ * [BORA00000794][WIFISYS][New Feature]Power Management Support -+ * Refine txmInitWtblTxRateTable() - set TX initial rate according to AP's operation rate set -+ * -+ * 05 17 2010 kevin.huang -+ * [BORA00000794][WIFISYS][New Feature]Power Management Support -+ * Call pmAbort() and add ucNetworkType field in EVENT_CONNECTION_STATUS -+ * -+ * 05 14 2010 kevin.huang -+ * [BORA00000794][WIFISYS][New Feature]Power Management Support -+ * Fix compile warning - define of MQM_WMM_PARSING was removed -+ * -+ * 05 12 2010 kevin.huang -+ * [BORA00000794][WIFISYS][New Feature]Power Management Support -+ * Add Power Management - Legacy PS-POLL support. -+ * -+ * 04 28 2010 tehuang.liu -+ * [BORA00000605][WIFISYS] Phase3 Integration -+ * Removed the use of compiling flag MQM_WMM_PARSING -+ * -+ * 04 27 2010 kevin.huang -+ * [BORA00000714][WIFISYS][New Feature]Beacon Timeout Support -+ * -+ * Fix typo -+ * -+ * 04 27 2010 kevin.huang -+ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support -+ * Add Set Slot Time and Beacon Timeout Support for AdHoc Mode -+ * -+ * 04 19 2010 kevin.huang -+ * [BORA00000714][WIFISYS][New Feature]Beacon Timeout Support -+ * Add Send Deauth for Class 3 Error and Leave Network Support -+ * -+ * 04 15 2010 wh.su -+ * [BORA00000680][MT6620] Support the statistic for Micxxsoft os query -+ * fixed the protected bit at cap info for ad-hoc. -+ * -+ * 04 13 2010 kevin.huang -+ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support -+ * Add new HW CH macro support -+ * -+ * 04 07 2010 chinghwa.yu -+ * [BORA00000563]Add WiFi CoEx BCM module -+ * Add TX Power Control RCPI function. -+ * -+ * 03 29 2010 wh.su -+ * [BORA00000605][WIFISYS] Phase3 Integration -+ * move the wlan table alloc / free to change state function. -+ * -+ * 03 25 2010 wh.su -+ * [BORA00000676][MT6620] Support the frequency setting and query at build connection / connection event -+ * modify the build connection and status event structure bu CMD_EVENT doc 0.09 draft, default is disable. -+ * -+ * 03 24 2010 wh.su -+ * [BORA00000605][WIFISYS] Phase3 Integration -+ * fixed some WHQL testing error. -+ * -+ * 03 24 2010 kevin.huang -+ * [BORA00000654][WIFISYS][New Feature] CNM Module - Ch Manager Support -+ * Add Set / Unset POWER STATE in AIS Network -+ * -+ * 03 16 2010 kevin.huang -+ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support -+ * Add AdHoc Mode -+ * -+ * 03 10 2010 kevin.huang -+ * [BORA00000654][WIFISYS][New Feature] CNM Module - Ch Manager Support -+ * Add Channel Manager for arbitration of JOIN and SCAN Req -+ * -+ * 03 03 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Add PHY_CONFIG to change Phy Type -+ * -+ * 03 03 2010 chinghwa.yu -+ * [BORA00000563]Add WiFi CoEx BCM module -+ * Use bcmWiFiNotify to replace wifi_send_msg to pass information to BCM module. -+ * -+ * 03 03 2010 chinghwa.yu -+ * [BORA00000563]Add WiFi CoEx BCM module -+ * Remove wmt_task definition and add PTA function. -+ * -+ * 03 02 2010 tehuang.liu -+ * [BORA00000569][WIFISYS] Phase 2 Integration Test -+ * Init TXM and MQM testing procedures in aisFsmRunEventJoinComplete() -+ * -+ * 03 01 2010 tehuang.liu -+ * [BORA00000569][WIFISYS] Phase 2 Integration Test -+ * Modified aisUpdateBssInfo() to call TXM's functions for setting WTBL TX parameters -+ * -+ * 03 01 2010 wh.su -+ * [BORA00000605][WIFISYS] Phase3 Integration -+ * clear the pmkid cache while indicate media disconnect. -+ * -+ * 02 26 2010 tehuang.liu -+ * [BORA00000569][WIFISYS] Phase 2 Integration Test -+ * . -+ * -+ * 02 26 2010 tehuang.liu -+ * [BORA00000569][WIFISYS] Phase 2 Integration Test -+ * Enabled MQM parsing WMM IEs for non-AP mode -+ * -+ * 02 26 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Remove CFG_TEST_VIRTUAL_CMD and add support of Driver STA_RECORD_T activation -+ * -+ * 02 25 2010 wh.su -+ * [BORA00000605][WIFISYS] Phase3 Integration -+ * use the Rx0 dor event indicate. -+ * -+ * 02 23 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Support dynamic channel selection -+ * -+ * 02 23 2010 wh.su -+ * [BORA00000621][MT6620 Wi-Fi] Add the RSSI indicate to avoid XP stalled for query rssi value -+ * Adding the RSSI event support, -+ * using the HAL function to get the rcpi value and tranlsate to RSSI and indicate to driver -+ * -+ * 02 12 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Use bss info array for concurrent handle -+ * -+ * 02 05 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Revise data structure to share the same BSS_INFO_T for avoiding coding error -+ * -+ * 02 04 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Add AAA Module Support, Revise Net Type to Net Type Index for array lookup -+ * -+ * 01 27 2010 tehuang.liu -+ * [BORA00000569][WIFISYS] Phase 2 Integration Test -+ * Set max AMDPU size supported by the peer to 64 KB, -+ * removed mqmInit() and mqmTxSendAddBaReq() function calls in aisUpdateBssInfo() -+ * -+ * 01 27 2010 wh.su -+ * [BORA00000476][Wi-Fi][firmware] Add the security module initialize code -+ * add and fixed some security function. -+ * -+ * 01 22 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Support protection and bandwidth switch -+ * -+ * 01 20 2010 kevin.huang -+ * [BORA00000569][WIFISYS] Phase 2 Integration Test -+ * Add PHASE_2_INTEGRATION_WORK_AROUND and CFG_SUPPORT_BCM flags -+ * -+ * 01 15 2010 tehuang.liu -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Configured the AMPDU factor to 3 for the APu1rwduu`wvpghlqg|q`mpdkb+ilp -+ * -+ * 01 14 2010 chinghwa.yu -+ * [BORA00000563]Add WiFi CoEx BCM module -+ * Add WiFi BCM module for the 1st time. -+ * -+ * 01 11 2010 kevin.huang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Add Deauth and Disassoc Handler -+ * -+ * 01 07 2010 kevin.huang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * -+ * Refine JOIN Complete and separate the function of Media State indication -+ * -+ * 01 04 2010 tehuang.liu -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * For working out the first connection Chariot-verified version -+ * -+ * 12 18 2009 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * . -+ * -+ * Dec 10 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * adding the sample code to update the wlan table rate, -+ * -+ * Dec 10 2009 mtk01104 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Different function prototype of wifi_send_msg() -+ * -+ * Dec 9 2009 mtk01104 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Call rlm related function to process HT info when join complete -+ * -+ * Dec 9 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * default the acquired wlan table entry code off -+ * -+ * Dec 9 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * adding the code to acquired the wlan table entry, and a sample code to update the BA bit at table -+ * -+ * Dec 7 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Fix the problem of prSwRfb overwrited by event packet in aisFsmRunEventJoinComplete() -+ * -+ * Dec 4 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * adding the code to integrate the security related code -+ * -+ * Dec 3 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Remove redundant declaration -+ * -+ * Dec 3 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Add code for JOIN init and JOIN complete -+ * -+ * Nov 30 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Rename u4RSSI to i4RSSI -+ * -+ * Nov 30 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Revise ENUM_MEDIA_STATE to ENUM_PARAM_MEDIA_STATE -+ * -+ * Nov 30 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Add fgIsScanReqIssued to CONNECTION_SETTINGS_T -+ * -+ * Nov 26 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Revise Virtual CMD handler due to structure changed -+ * -+ * Nov 25 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Add Virtual CMD & RESP for testing CMD PATH -+ * -+ * Nov 23 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Add aisFsmInitializeConnectionSettings() -+ * -+ * Nov 20 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Add CFG_TEST_MGMT_FSM flag for aisFsmTest() -+ * -+ * Nov 16 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "precomp.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+#define AIS_ROAMING_CONNECTION_TRIAL_LIMIT 2 -+#define AIS_ROAMING_SCAN_CHANNEL_DWELL_TIME 80 -+ -+#define CTIA_MAGIC_SSID "ctia_test_only_*#*#3646633#*#*" -+#define CTIA_MAGIC_SSID_LEN 30 -+ -+#define AIS_JOIN_TIMEOUT 7 -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+#if DBG -+/*lint -save -e64 Type mismatch */ -+static PUINT_8 apucDebugAisState[AIS_STATE_NUM] = { -+ (PUINT_8) DISP_STRING("AIS_STATE_IDLE"), -+ (PUINT_8) DISP_STRING("AIS_STATE_SEARCH"), -+ (PUINT_8) DISP_STRING("AIS_STATE_SCAN"), -+ (PUINT_8) DISP_STRING("AIS_STATE_ONLINE_SCAN"), -+ (PUINT_8) DISP_STRING("AIS_STATE_LOOKING_FOR"), -+ (PUINT_8) DISP_STRING("AIS_STATE_WAIT_FOR_NEXT_SCAN"), -+ (PUINT_8) DISP_STRING("AIS_STATE_REQ_CHANNEL_JOIN"), -+ (PUINT_8) DISP_STRING("AIS_STATE_JOIN"), -+ (PUINT_8) DISP_STRING("AIS_STATE_IBSS_ALONE"), -+ (PUINT_8) DISP_STRING("AIS_STATE_IBSS_MERGE"), -+ (PUINT_8) DISP_STRING("AIS_STATE_NORMAL_TR"), -+ (PUINT_8) DISP_STRING("AIS_STATE_DISCONNECTING"), -+ (PUINT_8) DISP_STRING("AIS_STATE_REQ_REMAIN_ON_CHANNEL"), -+ (PUINT_8) DISP_STRING("AIS_STATE_REMAIN_ON_CHANNEL") -+}; -+ -+/*lint -restore */ -+#endif /* DBG */ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief the function is used to initialize the value of the connection settings for -+* AIS network -+* -+* @param (none) -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID aisInitializeConnectionSettings(IN P_ADAPTER_T prAdapter, IN P_REG_INFO_T prRegInfo) -+{ -+ P_CONNECTION_SETTINGS_T prConnSettings; -+ UINT_8 aucAnyBSSID[] = BC_BSSID; -+ UINT_8 aucZeroMacAddr[] = NULL_MAC_ADDR; -+ int i = 0; -+ -+ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); -+ -+ /* Setup default values for operation */ -+ COPY_MAC_ADDR(prConnSettings->aucMacAddress, aucZeroMacAddr); -+ -+ if (prRegInfo) -+ prConnSettings->ucDelayTimeOfDisconnectEvent = -+ (!prAdapter->fgIsHw5GBandDisabled && prRegInfo->ucSupport5GBand) ? -+ AIS_DELAY_TIME_OF_DISC_SEC_DUALBAND : AIS_DELAY_TIME_OF_DISC_SEC_ONLY_2G4; -+ else -+ prConnSettings->ucDelayTimeOfDisconnectEvent = AIS_DELAY_TIME_OF_DISC_SEC_ONLY_2G4; -+ -+ COPY_MAC_ADDR(prConnSettings->aucBSSID, aucAnyBSSID); -+ prConnSettings->fgIsConnByBssidIssued = FALSE; -+ -+ prConnSettings->fgIsConnReqIssued = FALSE; -+ prConnSettings->fgIsDisconnectedByNonRequest = FALSE; -+ -+ prConnSettings->ucSSIDLen = 0; -+ -+ prConnSettings->eOPMode = NET_TYPE_INFRA; -+ -+ prConnSettings->eConnectionPolicy = CONNECT_BY_SSID_BEST_RSSI; -+ -+ if (prRegInfo) { -+ prConnSettings->ucAdHocChannelNum = (UINT_8) nicFreq2ChannelNum(prRegInfo->u4StartFreq); -+ prConnSettings->eAdHocBand = prRegInfo->u4StartFreq < 5000000 ? BAND_2G4 : BAND_5G; -+ prConnSettings->eAdHocMode = (ENUM_PARAM_AD_HOC_MODE_T) (prRegInfo->u4AdhocMode); -+ } -+ -+ prConnSettings->eAuthMode = AUTH_MODE_OPEN; -+ -+ prConnSettings->eEncStatus = ENUM_ENCRYPTION_DISABLED; -+ -+ prConnSettings->fgIsScanReqIssued = FALSE; -+ -+ /* MIB attributes */ -+ prConnSettings->u2BeaconPeriod = DOT11_BEACON_PERIOD_DEFAULT; -+ -+ prConnSettings->u2RTSThreshold = DOT11_RTS_THRESHOLD_DEFAULT; -+ -+ prConnSettings->u2DesiredNonHTRateSet = RATE_SET_ALL_ABG; -+ -+ /* prConnSettings->u4FreqInKHz; */ /* Center frequency */ -+ -+ /* Set U-APSD AC */ -+ prConnSettings->bmfgApsdEnAc = PM_UAPSD_NONE; -+ -+ secInit(prAdapter, NETWORK_TYPE_AIS_INDEX); -+ -+ /* Features */ -+ prConnSettings->fgIsEnableRoaming = FALSE; -+#if CFG_SUPPORT_ROAMING -+ if (prRegInfo) -+ prConnSettings->fgIsEnableRoaming = ((prRegInfo->fgDisRoaming > 0) ? (FALSE) : (TRUE)); -+#endif /* CFG_SUPPORT_ROAMING */ -+ -+ prConnSettings->fgIsAdHocQoSEnable = FALSE; -+ -+ prConnSettings->eDesiredPhyConfig = PHY_CONFIG_802_11ABGN; -+ -+ /* Set default bandwidth modes */ -+ prConnSettings->uc2G4BandwidthMode = CONFIG_BW_20M; -+ prConnSettings->uc5GBandwidthMode = CONFIG_BW_20_40M; -+ -+ prConnSettings->rRsnInfo.ucElemId = 0x30; -+ prConnSettings->rRsnInfo.u2Version = 0x0001; -+ prConnSettings->rRsnInfo.u4GroupKeyCipherSuite = 0; -+ prConnSettings->rRsnInfo.u4PairwiseKeyCipherSuiteCount = 0; -+ for (i = 0; i < MAX_NUM_SUPPORTED_CIPHER_SUITES; i++) -+ prConnSettings->rRsnInfo.au4PairwiseKeyCipherSuite[i] = 0; -+ prConnSettings->rRsnInfo.u4AuthKeyMgtSuiteCount = 0; -+ for (i = 0; i < MAX_NUM_SUPPORTED_AKM_SUITES; i++) -+ prConnSettings->rRsnInfo.au4AuthKeyMgtSuite[i] = 0; -+ prConnSettings->rRsnInfo.u2RsnCap = 0; -+ prConnSettings->rRsnInfo.fgRsnCapPresent = FALSE; -+ -+} /* end of aisFsmInitializeConnectionSettings() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief the function is used to initialize the value in AIS_FSM_INFO_T for -+* AIS FSM operation -+* -+* @param (none) -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT_32 ucScanTimeoutTimes = 0; -+VOID aisFsmInit(IN P_ADAPTER_T prAdapter) -+{ -+ P_AIS_FSM_INFO_T prAisFsmInfo; -+ P_BSS_INFO_T prAisBssInfo; -+ P_AIS_SPECIFIC_BSS_INFO_T prAisSpecificBssInfo; -+ -+ DEBUGFUNC("aisFsmInit()"); -+ DBGLOG(SW1, TRACE, "->aisFsmInit()\n"); -+ -+ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); -+ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ prAisSpecificBssInfo = &(prAdapter->rWifiVar.rAisSpecificBssInfo); -+ -+ /* 4 <1> Initiate FSM */ -+ prAisFsmInfo->ePreviousState = AIS_STATE_IDLE; -+ prAisFsmInfo->eCurrentState = AIS_STATE_IDLE; -+ -+ prAisFsmInfo->ucAvailableAuthTypes = 0; -+ -+ prAisFsmInfo->prTargetBssDesc = (P_BSS_DESC_T) NULL; -+ -+ prAisFsmInfo->ucSeqNumOfReqMsg = 0; -+ prAisFsmInfo->ucSeqNumOfChReq = 0; -+ prAisFsmInfo->ucSeqNumOfScanReq = 0; -+ -+ prAisFsmInfo->fgIsInfraChannelFinished = TRUE; -+#if CFG_SUPPORT_ROAMING -+ prAisFsmInfo->fgIsRoamingScanPending = FALSE; -+#endif /* CFG_SUPPORT_ROAMING */ -+ prAisFsmInfo->fgIsChannelRequested = FALSE; -+ prAisFsmInfo->fgIsChannelGranted = FALSE; -+ -+ /* 4 <1.1> Initiate FSM - Timer INIT */ -+ cnmTimerInitTimer(prAdapter, -+ &prAisFsmInfo->rBGScanTimer, -+ (PFN_MGMT_TIMEOUT_FUNC) aisFsmRunEventBGSleepTimeOut, (ULONG) NULL); -+ -+ cnmTimerInitTimer(prAdapter, -+ &prAisFsmInfo->rIbssAloneTimer, -+ (PFN_MGMT_TIMEOUT_FUNC) aisFsmRunEventIbssAloneTimeOut, (ULONG) NULL); -+ -+ cnmTimerInitTimer(prAdapter, -+ &prAisFsmInfo->rIndicationOfDisconnectTimer, -+ (PFN_MGMT_TIMEOUT_FUNC) aisPostponedEventOfDisconnTimeout, (ULONG) NULL); -+ -+ cnmTimerInitTimer(prAdapter, -+ &prAisFsmInfo->rJoinTimeoutTimer, -+ (PFN_MGMT_TIMEOUT_FUNC) aisFsmRunEventJoinTimeout, (ULONG) NULL); -+ -+ cnmTimerInitTimer(prAdapter, -+ &prAisFsmInfo->rScanDoneTimer, -+ (PFN_MGMT_TIMEOUT_FUNC) aisFsmRunEventScanDoneTimeOut, (ULONG) NULL); -+ -+ cnmTimerInitTimer(prAdapter, -+ &prAisFsmInfo->rChannelTimeoutTimer, -+ (PFN_MGMT_TIMEOUT_FUNC) aisFsmRunEventChannelTimeout, (ULONG) NULL); -+ -+ cnmTimerInitTimer(prAdapter, -+ &prAisFsmInfo->rDeauthDoneTimer, -+ (PFN_MGMT_TIMEOUT_FUNC) aisFsmRunEventDeauthTimeout, (ULONG) NULL); -+ -+ /* 4 <1.2> Initiate PWR STATE */ -+ SET_NET_PWR_STATE_IDLE(prAdapter, NETWORK_TYPE_AIS_INDEX); -+ -+ /* 4 <2> Initiate BSS_INFO_T - common part */ -+ BSS_INFO_INIT(prAdapter, NETWORK_TYPE_AIS_INDEX); -+ COPY_MAC_ADDR(prAisBssInfo->aucOwnMacAddr, prAdapter->rWifiVar.aucMacAddress); -+ -+ /* 4 <3> Initiate BSS_INFO_T - private part */ -+ /* TODO */ -+ prAisBssInfo->eBand = BAND_2G4; -+ prAisBssInfo->ucPrimaryChannel = 1; -+ prAisBssInfo->prStaRecOfAP = (P_STA_RECORD_T) NULL; -+ -+ /* 4 <4> Allocate MSDU_INFO_T for Beacon */ -+ prAisBssInfo->prBeacon = cnmMgtPktAlloc(prAdapter, -+ OFFSET_OF(WLAN_BEACON_FRAME_T, aucInfoElem[0]) + MAX_IE_LENGTH); -+ -+ if (prAisBssInfo->prBeacon) { -+ prAisBssInfo->prBeacon->eSrc = TX_PACKET_MGMT; -+ prAisBssInfo->prBeacon->ucStaRecIndex = 0xFF; /* NULL STA_REC */ -+ } else { -+ ASSERT(0); -+ } -+ -+#if 0 -+ prAisBssInfo->rPmProfSetupInfo.ucBmpDeliveryAC = PM_UAPSD_ALL; -+ prAisBssInfo->rPmProfSetupInfo.ucBmpTriggerAC = PM_UAPSD_ALL; -+ prAisBssInfo->rPmProfSetupInfo.ucUapsdSp = WMM_MAX_SP_LENGTH_2; -+#else -+ if (prAdapter->u4UapsdAcBmp == 0) { -+ prAdapter->u4UapsdAcBmp = CFG_INIT_UAPSD_AC_BMP; -+ /* ASSERT(prAdapter->u4UapsdAcBmp); */ -+ } -+ prAisBssInfo->rPmProfSetupInfo.ucBmpDeliveryAC = (UINT_8) prAdapter->u4UapsdAcBmp; -+ prAisBssInfo->rPmProfSetupInfo.ucBmpTriggerAC = (UINT_8) prAdapter->u4UapsdAcBmp; -+ prAisBssInfo->rPmProfSetupInfo.ucUapsdSp = (UINT_8) prAdapter->u4MaxSpLen; -+#endif -+ -+ /* request list initialization */ -+ LINK_INITIALIZE(&prAisFsmInfo->rPendingReqList); -+ -+ /* DBGPRINTF("[2] ucBmpDeliveryAC:0x%x, ucBmpTriggerAC:0x%x, ucUapsdSp:0x%x", */ -+ /* prAisBssInfo->rPmProfSetupInfo.ucBmpDeliveryAC, */ -+ /* prAisBssInfo->rPmProfSetupInfo.ucBmpTriggerAC, */ -+ /* prAisBssInfo->rPmProfSetupInfo.ucUapsdSp); */ -+ -+ /*reset ucScanTimeoutTimes value*/ -+ ucScanTimeoutTimes = 0; -+ -+} /* end of aisFsmInit() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief the function is used to uninitialize the value in AIS_FSM_INFO_T for -+* AIS FSM operation -+* -+* @param (none) -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID aisFsmUninit(IN P_ADAPTER_T prAdapter) -+{ -+ P_AIS_FSM_INFO_T prAisFsmInfo; -+ P_BSS_INFO_T prAisBssInfo; -+ P_AIS_SPECIFIC_BSS_INFO_T prAisSpecificBssInfo; -+ -+ DEBUGFUNC("aisFsmUninit()"); -+ DBGLOG(SW1, INFO, "->aisFsmUninit()\n"); -+ -+ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); -+ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ prAisSpecificBssInfo = &(prAdapter->rWifiVar.rAisSpecificBssInfo); -+ -+ /* 4 <1> Stop all timers */ -+ cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rBGScanTimer); -+ cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rIbssAloneTimer); -+ cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rIndicationOfDisconnectTimer); -+ cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rJoinTimeoutTimer); -+ cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rScanDoneTimer); /* Add by Enlai */ -+ cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rChannelTimeoutTimer); -+ -+ /* 4 <2> flush pending request */ -+ aisFsmFlushRequest(prAdapter); -+ -+ /* 4 <3> Reset driver-domain BSS-INFO */ -+ if (prAisBssInfo->prBeacon) { -+ cnmMgtPktFree(prAdapter, prAisBssInfo->prBeacon); -+ prAisBssInfo->prBeacon = NULL; -+ } -+#if CFG_SUPPORT_802_11W -+ rsnStopSaQuery(prAdapter); -+#endif -+ -+} /* end of aisFsmUninit() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Initialization of JOIN STATE -+* -+* @param[in] prBssDesc The pointer of BSS_DESC_T which is the BSS we will try to join with. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID aisFsmStateInit_JOIN(IN P_ADAPTER_T prAdapter, P_BSS_DESC_T prBssDesc) -+{ -+ P_AIS_FSM_INFO_T prAisFsmInfo; -+ P_BSS_INFO_T prAisBssInfo; -+ P_AIS_SPECIFIC_BSS_INFO_T prAisSpecificBssInfo; -+ P_CONNECTION_SETTINGS_T prConnSettings; -+ P_STA_RECORD_T prStaRec; -+ P_MSG_JOIN_REQ_T prJoinReqMsg; -+ -+ DEBUGFUNC("aisFsmStateInit_JOIN()"); -+ -+ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); -+ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ prAisSpecificBssInfo = &(prAdapter->rWifiVar.rAisSpecificBssInfo); -+ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); -+ -+ ASSERT(prBssDesc); -+ -+ /* 4 <1> We are going to connect to this BSS. */ -+ prBssDesc->fgIsConnecting = TRUE; -+ -+ /* 4 <2> Setup corresponding STA_RECORD_T */ -+ prStaRec = bssCreateStaRecFromBssDesc(prAdapter, STA_TYPE_LEGACY_AP, NETWORK_TYPE_AIS_INDEX, prBssDesc); -+ if (prStaRec == NULL) { -+ DBGLOG(AIS, WARN, "Create station record fail\n"); -+ return; -+ } -+ -+ prAisFsmInfo->prTargetStaRec = prStaRec; -+ -+ /* 4 <2.1> sync. to firmware domain */ -+ if (prStaRec->ucStaState == STA_STATE_1) -+ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); -+ /* 4 <3> Update ucAvailableAuthTypes which we can choice during SAA */ -+ if (prAisBssInfo->eConnectionState == PARAM_MEDIA_STATE_DISCONNECTED) { -+ -+ prStaRec->fgIsReAssoc = FALSE; -+ -+ switch (prConnSettings->eAuthMode) { -+ case AUTH_MODE_OPEN: /* Note: Omit break here. */ -+ case AUTH_MODE_WPA: -+ case AUTH_MODE_WPA_PSK: -+ case AUTH_MODE_WPA2: -+ case AUTH_MODE_WPA2_PSK: -+ prAisFsmInfo->ucAvailableAuthTypes = (UINT_8) AUTH_TYPE_OPEN_SYSTEM; -+ break; -+ -+ case AUTH_MODE_SHARED: -+ prAisFsmInfo->ucAvailableAuthTypes = (UINT_8) AUTH_TYPE_SHARED_KEY; -+ break; -+ -+ case AUTH_MODE_AUTO_SWITCH: -+ DBGLOG(AIS, LOUD, "JOIN INIT: eAuthMode == AUTH_MODE_AUTO_SWITCH\n"); -+ prAisFsmInfo->ucAvailableAuthTypes = (UINT_8) (AUTH_TYPE_OPEN_SYSTEM | AUTH_TYPE_SHARED_KEY); -+ break; -+ -+ default: -+ ASSERT(!(prConnSettings->eAuthMode == AUTH_MODE_WPA_NONE)); -+ DBGLOG(AIS, ERROR, "JOIN INIT: Auth Algorithm : %d was not supported by JOIN\n", -+ prConnSettings->eAuthMode); -+ /* TODO(Kevin): error handling ? */ -+ return; -+ } -+ -+ /* TODO(tyhsu): Assume that Roaming Auth Type is equal to ConnSettings eAuthMode */ -+ prAisSpecificBssInfo->ucRoamingAuthTypes = prAisFsmInfo->ucAvailableAuthTypes; -+ -+ prStaRec->ucTxAuthAssocRetryLimit = TX_AUTH_ASSOCI_RETRY_LIMIT; -+ -+ } else { -+ ASSERT(prBssDesc->eBSSType == BSS_TYPE_INFRASTRUCTURE); -+ ASSERT(!prBssDesc->fgIsConnected); -+ -+ DBGLOG(AIS, LOUD, "JOIN INIT: AUTH TYPE = %d for Roaming\n", -+ prAisSpecificBssInfo->ucRoamingAuthTypes); -+ -+ prStaRec->fgIsReAssoc = TRUE; /* We do roaming while the medium is connected */ -+ -+ /* TODO(Kevin): We may call a sub function to acquire the Roaming Auth Type */ -+ prAisFsmInfo->ucAvailableAuthTypes = prAisSpecificBssInfo->ucRoamingAuthTypes; -+ -+ prStaRec->ucTxAuthAssocRetryLimit = TX_AUTH_ASSOCI_RETRY_LIMIT_FOR_ROAMING; -+ } -+ -+ /* 4 <4> Use an appropriate Authentication Algorithm Number among the ucAvailableAuthTypes */ -+ if (prAisFsmInfo->ucAvailableAuthTypes & (UINT_8) AUTH_TYPE_OPEN_SYSTEM) { -+ -+ DBGLOG(AIS, LOUD, "JOIN INIT: Try to do Authentication with AuthType == OPEN_SYSTEM.\n"); -+ prAisFsmInfo->ucAvailableAuthTypes &= ~(UINT_8) AUTH_TYPE_OPEN_SYSTEM; -+ -+ prStaRec->ucAuthAlgNum = (UINT_8) AUTH_ALGORITHM_NUM_OPEN_SYSTEM; -+ } else if (prAisFsmInfo->ucAvailableAuthTypes & (UINT_8) AUTH_TYPE_SHARED_KEY) { -+ -+ DBGLOG(AIS, LOUD, "JOIN INIT: Try to do Authentication with AuthType == SHARED_KEY.\n"); -+ -+ prAisFsmInfo->ucAvailableAuthTypes &= ~(UINT_8) AUTH_TYPE_SHARED_KEY; -+ -+ prStaRec->ucAuthAlgNum = (UINT_8) AUTH_ALGORITHM_NUM_SHARED_KEY; -+ } else if (prAisFsmInfo->ucAvailableAuthTypes & (UINT_8) AUTH_TYPE_FAST_BSS_TRANSITION) { -+ -+ DBGLOG(AIS, LOUD, "JOIN INIT: Try to do Authentication with AuthType == FAST_BSS_TRANSITION.\n"); -+ -+ prAisFsmInfo->ucAvailableAuthTypes &= ~(UINT_8) AUTH_TYPE_FAST_BSS_TRANSITION; -+ -+ prStaRec->ucAuthAlgNum = (UINT_8) AUTH_ALGORITHM_NUM_FAST_BSS_TRANSITION; -+ } else { -+ ASSERT(0); -+ } -+ -+ /* 4 <5> Overwrite Connection Setting for eConnectionPolicy == ANY (Used by Assoc Req) */ -+ if (prBssDesc->ucSSIDLen) -+ COPY_SSID(prConnSettings->aucSSID, prConnSettings->ucSSIDLen, prBssDesc->aucSSID, prBssDesc->ucSSIDLen); -+ /* 4 <6> Send a Msg to trigger SAA to start JOIN process. */ -+ prJoinReqMsg = (P_MSG_JOIN_REQ_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_JOIN_REQ_T)); -+ if (!prJoinReqMsg) { -+ -+ ASSERT(0); /* Can't trigger SAA FSM */ -+ return; -+ } -+ -+ prJoinReqMsg->rMsgHdr.eMsgId = MID_AIS_SAA_FSM_START; -+ prJoinReqMsg->ucSeqNum = ++prAisFsmInfo->ucSeqNumOfReqMsg; -+ prJoinReqMsg->prStaRec = prStaRec; -+ -+ if (1) { -+ int j; -+ P_FRAG_INFO_T prFragInfo; -+ -+ for (j = 0; j < MAX_NUM_CONCURRENT_FRAGMENTED_MSDUS; j++) { -+ prFragInfo = &prStaRec->rFragInfo[j]; -+ -+ if (prFragInfo->pr1stFrag) { -+ /* nicRxReturnRFB(prAdapter, prFragInfo->pr1stFrag); */ -+ prFragInfo->pr1stFrag = (P_SW_RFB_T) NULL; -+ } -+ } -+ } -+ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prJoinReqMsg, MSG_SEND_METHOD_BUF); -+ -+} /* end of aisFsmInit_JOIN() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Retry JOIN for AUTH_MODE_AUTO_SWITCH -+* -+* @param[in] prStaRec Pointer to the STA_RECORD_T -+* -+* @retval TRUE We will retry JOIN -+* @retval FALSE We will not retry JOIN -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN aisFsmStateInit_RetryJOIN(IN P_ADAPTER_T prAdapter, P_STA_RECORD_T prStaRec) -+{ -+ P_AIS_FSM_INFO_T prAisFsmInfo; -+ P_MSG_JOIN_REQ_T prJoinReqMsg; -+ -+ DEBUGFUNC("aisFsmStateInit_RetryJOIN()"); -+ -+ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); -+ -+ /* Retry other AuthType if possible */ -+ if (!prAisFsmInfo->ucAvailableAuthTypes) -+ return FALSE; -+ -+ if (prAisFsmInfo->ucAvailableAuthTypes & (UINT_8) AUTH_TYPE_SHARED_KEY) { -+ -+ DBGLOG(AIS, INFO, "RETRY JOIN INIT: Retry Authentication with AuthType == SHARED_KEY.\n"); -+ -+ prAisFsmInfo->ucAvailableAuthTypes &= ~(UINT_8) AUTH_TYPE_SHARED_KEY; -+ -+ prStaRec->ucAuthAlgNum = (UINT_8) AUTH_ALGORITHM_NUM_SHARED_KEY; -+ } else { -+ DBGLOG(AIS, ERROR, "RETRY JOIN INIT: Retry Authentication with Unexpected AuthType.\n"); -+ ASSERT(0); -+ } -+ -+ prAisFsmInfo->ucAvailableAuthTypes = 0; /* No more available Auth Types */ -+ -+ /* Trigger SAA to start JOIN process. */ -+ prJoinReqMsg = (P_MSG_JOIN_REQ_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_JOIN_REQ_T)); -+ if (!prJoinReqMsg) { -+ -+ ASSERT(0); /* Can't trigger SAA FSM */ -+ return FALSE; -+ } -+ -+ prJoinReqMsg->rMsgHdr.eMsgId = MID_AIS_SAA_FSM_START; -+ prJoinReqMsg->ucSeqNum = ++prAisFsmInfo->ucSeqNumOfReqMsg; -+ prJoinReqMsg->prStaRec = prStaRec; -+ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prJoinReqMsg, MSG_SEND_METHOD_BUF); -+ -+ return TRUE; -+ -+} /* end of aisFsmRetryJOIN() */ -+ -+#if CFG_SUPPORT_ADHOC -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief State Initialization of AIS_STATE_IBSS_ALONE -+* -+* @param (none) -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID aisFsmStateInit_IBSS_ALONE(IN P_ADAPTER_T prAdapter) -+{ -+ P_AIS_FSM_INFO_T prAisFsmInfo; -+ P_CONNECTION_SETTINGS_T prConnSettings; -+ P_BSS_INFO_T prAisBssInfo; -+ -+ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); -+ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); -+ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ -+ /* 4 <1> Check if IBSS was created before ? */ -+ if (prAisBssInfo->fgIsBeaconActivated) { -+ -+ /* 4 <2> Start IBSS Alone Timer for periodic SCAN and then SEARCH */ -+#if !CFG_SLT_SUPPORT -+ cnmTimerStartTimer(prAdapter, &prAisFsmInfo->rIbssAloneTimer, SEC_TO_MSEC(AIS_IBSS_ALONE_TIMEOUT_SEC)); -+#endif -+ } -+ -+ aisFsmCreateIBSS(prAdapter); -+ -+} /* end of aisFsmStateInit_IBSS_ALONE() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief State Initialization of AIS_STATE_IBSS_MERGE -+* -+* @param[in] prBssDesc The pointer of BSS_DESC_T which is the IBSS we will try to merge with. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID aisFsmStateInit_IBSS_MERGE(IN P_ADAPTER_T prAdapter, P_BSS_DESC_T prBssDesc) -+{ -+ P_AIS_FSM_INFO_T prAisFsmInfo; -+ P_CONNECTION_SETTINGS_T prConnSettings; -+ P_BSS_INFO_T prAisBssInfo; -+ P_STA_RECORD_T prStaRec = (P_STA_RECORD_T) NULL; -+ -+ ASSERT(prBssDesc); -+ -+ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); -+ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); -+ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ -+ /* 4 <1> We will merge with to this BSS immediately. */ -+ prBssDesc->fgIsConnecting = FALSE; -+ prBssDesc->fgIsConnected = TRUE; -+ -+ /* 4 <2> Setup corresponding STA_RECORD_T */ -+ prStaRec = bssCreateStaRecFromBssDesc(prAdapter, STA_TYPE_ADHOC_PEER, NETWORK_TYPE_AIS_INDEX, prBssDesc); -+ if (prStaRec == NULL) { -+ DBGLOG(AIS, WARN, "Create station record fail\n"); -+ return; -+ } -+ -+ prStaRec->fgIsMerging = TRUE; -+ -+ prAisFsmInfo->prTargetStaRec = prStaRec; -+ -+ /* 4 <2.1> sync. to firmware domain */ -+ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); -+ -+ /* 4 <3> IBSS-Merge */ -+ aisFsmMergeIBSS(prAdapter, prStaRec); -+ -+} /* end of aisFsmStateInit_IBSS_MERGE() */ -+ -+#endif /* CFG_SUPPORT_ADHOC */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Process of JOIN Abort -+* -+* @param (none) -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID aisFsmStateAbort_JOIN(IN P_ADAPTER_T prAdapter) -+{ -+ P_AIS_FSM_INFO_T prAisFsmInfo; -+ P_MSG_JOIN_ABORT_T prJoinAbortMsg; -+ -+ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); -+ -+ /* 1. Abort JOIN process */ -+ prJoinAbortMsg = (P_MSG_JOIN_ABORT_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_JOIN_ABORT_T)); -+ if (!prJoinAbortMsg) { -+ -+ ASSERT(0); /* Can't abort SAA FSM */ -+ return; -+ } -+ -+ prJoinAbortMsg->rMsgHdr.eMsgId = MID_AIS_SAA_FSM_ABORT; -+ prJoinAbortMsg->ucSeqNum = prAisFsmInfo->ucSeqNumOfReqMsg; -+ prJoinAbortMsg->prStaRec = prAisFsmInfo->prTargetStaRec; -+ -+ scanRemoveConnFlagOfBssDescByBssid(prAdapter, prAisFsmInfo->prTargetStaRec->aucMacAddr); -+ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prJoinAbortMsg, MSG_SEND_METHOD_BUF); -+ -+ /* 2. Return channel privilege */ -+ aisFsmReleaseCh(prAdapter); -+ -+ /* 3.1 stop join timeout timer */ -+ cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rJoinTimeoutTimer); -+ -+ /* 3.2 reset local variable */ -+ prAisFsmInfo->fgIsInfraChannelFinished = TRUE; -+ prAdapter->rWifiVar.rConnSettings.fgIsConnReqIssued = FALSE; -+ -+} /* end of aisFsmAbortJOIN() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Process of SCAN Abort -+* -+* @param (none) -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID aisFsmStateAbort_SCAN(IN P_ADAPTER_T prAdapter) -+{ -+ P_AIS_FSM_INFO_T prAisFsmInfo; -+ P_MSG_SCN_SCAN_CANCEL prScanCancelMsg; -+ -+ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); -+ -+ /* Abort JOIN process. */ -+ prScanCancelMsg = (P_MSG_SCN_SCAN_CANCEL) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_SCN_SCAN_CANCEL)); -+ if (!prScanCancelMsg) { -+ -+ ASSERT(0); /* Can't abort SCN FSM */ -+ return; -+ } -+ -+ prScanCancelMsg->rMsgHdr.eMsgId = MID_AIS_SCN_SCAN_CANCEL; -+ prScanCancelMsg->ucSeqNum = prAisFsmInfo->ucSeqNumOfScanReq; -+ prScanCancelMsg->ucNetTypeIndex = (UINT_8) NETWORK_TYPE_AIS_INDEX; -+#if CFG_ENABLE_WIFI_DIRECT -+ if (prAdapter->fgIsP2PRegistered) -+ prScanCancelMsg->fgIsChannelExt = FALSE; -+#endif -+ -+ /* unbuffered message to guarantee scan is cancelled in sequence */ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prScanCancelMsg, MSG_SEND_METHOD_UNBUF); -+ -+} /* end of aisFsmAbortSCAN() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Process of NORMAL_TR Abort -+* -+* @param (none) -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID aisFsmStateAbort_NORMAL_TR(IN P_ADAPTER_T prAdapter) -+{ -+ P_AIS_FSM_INFO_T prAisFsmInfo; -+ -+ ASSERT(prAdapter); -+ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); -+ -+ DBGLOG(AIS, TRACE, "aisFsmStateAbort_NORMAL_TR\n"); -+ -+ /* TODO(Kevin): Do abort other MGMT func */ -+ -+ /* 1. Release channel to CNM */ -+ aisFsmReleaseCh(prAdapter); -+ -+ /* 2.1 stop join timeout timer */ -+ cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rJoinTimeoutTimer); -+ -+ /* 2.2 reset local variable */ -+ prAisFsmInfo->fgIsInfraChannelFinished = TRUE; -+ -+} /* end of aisFsmAbortNORMAL_TR() */ -+ -+#if CFG_SUPPORT_ADHOC -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Process of NORMAL_TR Abort -+* -+* @param (none) -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID aisFsmStateAbort_IBSS(IN P_ADAPTER_T prAdapter) -+{ -+ P_AIS_FSM_INFO_T prAisFsmInfo; -+ P_BSS_DESC_T prBssDesc; -+ -+ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); -+ -+ /* reset BSS-DESC */ -+ if (prAisFsmInfo->prTargetStaRec) { -+ prBssDesc = scanSearchBssDescByTA(prAdapter, prAisFsmInfo->prTargetStaRec->aucMacAddr); -+ -+ if (prBssDesc) { -+ prBssDesc->fgIsConnected = FALSE; -+ prBssDesc->fgIsConnecting = FALSE; -+ } -+ } -+ /* release channel privilege */ -+ aisFsmReleaseCh(prAdapter); -+ -+} -+#endif /* CFG_SUPPORT_ADHOC */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief The Core FSM engine of AIS(Ad-hoc, Infra STA) -+* -+* @param[in] eNextState Enum value of next AIS STATE -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID aisFsmSteps(IN P_ADAPTER_T prAdapter, ENUM_AIS_STATE_T eNextState) -+{ -+ P_AIS_FSM_INFO_T prAisFsmInfo; -+ P_BSS_INFO_T prAisBssInfo; -+ P_CONNECTION_SETTINGS_T prConnSettings; -+ P_BSS_DESC_T prBssDesc; -+ P_MSG_CH_REQ_T prMsgChReq; -+ P_MSG_SCN_SCAN_REQ prScanReqMsg; -+ P_AIS_REQ_HDR_T prAisReq; -+ ENUM_BAND_T eBand; -+ UINT_8 ucChannel; -+ UINT_16 u2ScanIELen; -+ ENUM_AIS_STATE_T eOriPreState; -+ -+ BOOLEAN fgIsTransition = (BOOLEAN) FALSE; -+ -+ DEBUGFUNC("aisFsmSteps()"); -+ -+ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); -+ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); -+ eOriPreState = prAisFsmInfo->ePreviousState; -+ -+ do { -+ -+ /* Do entering Next State */ -+ prAisFsmInfo->ePreviousState = prAisFsmInfo->eCurrentState; -+ -+#if DBG -+ DBGLOG(AIS, STATE, "TRANSITION: [%s] -> [%s]\n", -+ apucDebugAisState[prAisFsmInfo->eCurrentState], apucDebugAisState[eNextState]); -+#else -+ DBGLOG(AIS, STATE, "[%d] TRANSITION: [%d] -> [%d]\n", -+ DBG_AIS_IDX, prAisFsmInfo->eCurrentState, eNextState); -+#endif -+ /* NOTE(Kevin): This is the only place to change the eCurrentState(except initial) */ -+ prAisFsmInfo->eCurrentState = eNextState; -+ -+ fgIsTransition = (BOOLEAN) FALSE; -+ -+ /* Do tasks of the State that we just entered */ -+ switch (prAisFsmInfo->eCurrentState) { -+ /* NOTE(Kevin): we don't have to rearrange the sequence of following -+ * switch case. Instead I would like to use a common lookup table of array -+ * of function pointer to speed up state search. -+ */ -+ case AIS_STATE_IDLE: -+ -+ prAisReq = aisFsmGetNextRequest(prAdapter); -+ -+ cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rScanDoneTimer); -+ -+ if (prAisReq == NULL || prAisReq->eReqType == AIS_REQUEST_RECONNECT) { -+ if (prConnSettings->fgIsConnReqIssued == TRUE && -+ prConnSettings->fgIsDisconnectedByNonRequest == FALSE) { -+ -+ prAisFsmInfo->fgTryScan = TRUE; -+ -+ SET_NET_ACTIVE(prAdapter, NETWORK_TYPE_AIS_INDEX); -+ SET_NET_PWR_STATE_ACTIVE(prAdapter, NETWORK_TYPE_AIS_INDEX); -+ -+ /* sync with firmware */ -+ nicActivateNetwork(prAdapter, NETWORK_TYPE_AIS_INDEX); -+ -+ /* reset trial count */ -+ prAisFsmInfo->ucConnTrialCount = 0; -+ -+ eNextState = AIS_STATE_SEARCH; -+ fgIsTransition = TRUE; -+ } else { -+ UNSET_NET_ACTIVE(prAdapter, NETWORK_TYPE_AIS_INDEX); -+ SET_NET_PWR_STATE_IDLE(prAdapter, NETWORK_TYPE_AIS_INDEX); -+ -+ /* sync with firmware */ -+ nicDeactivateNetwork(prAdapter, NETWORK_TYPE_AIS_INDEX); -+ -+ /* check for other pending request */ -+ if (prAisReq && -+ (aisFsmIsRequestPending(prAdapter, AIS_REQUEST_SCAN, TRUE) == TRUE)) { -+ -+ wlanClearScanningResult(prAdapter); -+ eNextState = AIS_STATE_SCAN; -+ -+ fgIsTransition = TRUE; -+ } -+ } -+ -+ if (prAisReq) { -+ /* free the message */ -+ cnmMemFree(prAdapter, prAisReq); -+ } -+ } else if (prAisReq->eReqType == AIS_REQUEST_SCAN) { -+#if CFG_SUPPORT_ROAMING -+ prAisFsmInfo->fgIsRoamingScanPending = FALSE; -+#endif /* CFG_SUPPORT_ROAMING */ -+ wlanClearScanningResult(prAdapter); -+ -+ eNextState = AIS_STATE_SCAN; -+ fgIsTransition = TRUE; -+ -+ /* free the message */ -+ cnmMemFree(prAdapter, prAisReq); -+ } else if (prAisReq->eReqType == AIS_REQUEST_ROAMING_CONNECT -+ || prAisReq->eReqType == AIS_REQUEST_ROAMING_SEARCH) { -+ /* ignore */ -+ /* free the message */ -+ cnmMemFree(prAdapter, prAisReq); -+ } else if (prAisReq->eReqType == AIS_REQUEST_REMAIN_ON_CHANNEL) { -+ eNextState = AIS_STATE_REQ_REMAIN_ON_CHANNEL; -+ fgIsTransition = TRUE; -+ -+ /* free the message */ -+ cnmMemFree(prAdapter, prAisReq); -+ } -+ -+ prAisFsmInfo->u4SleepInterval = AIS_BG_SCAN_INTERVAL_MIN_SEC; -+ -+ break; -+ -+ case AIS_STATE_SEARCH: -+ /* 4 <1> Search for a matched candidate and save it to prTargetBssDesc. */ -+#if CFG_SLT_SUPPORT -+ prBssDesc = prAdapter->rWifiVar.rSltInfo.prPseudoBssDesc; -+#else -+ prBssDesc = scanSearchBssDescByPolicy(prAdapter, NETWORK_TYPE_AIS_INDEX); -+#endif -+ /* every time BSS join failure count is integral multiples of SCN_BSS_JOIN_FAIL_THRESOLD, -+ we need to scan again to find if a new BSS is here in the ESS, -+ this can also avoid too frequency to retry the rejected AP */ -+ if (prAisFsmInfo->ePreviousState == AIS_STATE_LOOKING_FOR || -+ ((eOriPreState == AIS_STATE_ONLINE_SCAN || -+ eOriPreState == AIS_STATE_SCAN) && prAisFsmInfo->ePreviousState != eOriPreState)) { -+ /* if previous state is scan/online scan/looking for, don't try to scan again */ -+ } else if (prBssDesc && prBssDesc->ucJoinFailureCount >= SCN_BSS_JOIN_FAIL_THRESOLD && -+ ((prBssDesc->ucJoinFailureCount - SCN_BSS_JOIN_FAIL_THRESOLD) % -+ SCN_BSS_JOIN_FAIL_THRESOLD) == 0) -+ prBssDesc = NULL; -+ -+ /* we are under Roaming Condition. */ -+ if (prAisBssInfo->eConnectionState == PARAM_MEDIA_STATE_CONNECTED) { -+ if (prAisFsmInfo->ucConnTrialCount > AIS_ROAMING_CONNECTION_TRIAL_LIMIT) { -+#if CFG_SUPPORT_ROAMING -+ roamingFsmRunEventFail(prAdapter, ROAMING_FAIL_REASON_CONNLIMIT); -+#endif /* CFG_SUPPORT_ROAMING */ -+ /* reset retry count */ -+ prAisFsmInfo->ucConnTrialCount = 0; -+ -+ /* abort connection trial */ -+ prConnSettings->fgIsConnReqIssued = FALSE; -+ -+ eNextState = AIS_STATE_NORMAL_TR; -+ fgIsTransition = TRUE; -+ -+ break; -+ } -+ } -+ /* 4 <2> We are not under Roaming Condition. */ -+ if (prAisBssInfo->eConnectionState == PARAM_MEDIA_STATE_DISCONNECTED) { -+ -+ /* 4 <2.a> If we have the matched one */ -+ if (prBssDesc) { -+ -+ /* 4 Stored the Selected BSS security cipher. -+ For later asoc req compose IE */ -+ prAisBssInfo->u4RsnSelectedGroupCipher = prBssDesc->u4RsnSelectedGroupCipher; -+ prAisBssInfo->u4RsnSelectedPairwiseCipher = -+ prBssDesc->u4RsnSelectedPairwiseCipher; -+ prAisBssInfo->u4RsnSelectedAKMSuite = prBssDesc->u4RsnSelectedAKMSuite; -+ -+ /* 4 Do STATE transition and update current Operation Mode. */ -+ if (prBssDesc->eBSSType == BSS_TYPE_INFRASTRUCTURE) { -+ -+ prAisBssInfo->eCurrentOPMode = OP_MODE_INFRASTRUCTURE; -+ -+ /* Record the target BSS_DESC_T for next STATE. */ -+ prAisFsmInfo->prTargetBssDesc = prBssDesc; -+ -+ /* Transit to channel acquire */ -+ eNextState = AIS_STATE_REQ_CHANNEL_JOIN; -+ fgIsTransition = TRUE; -+ -+ /* increase connection trial count */ -+ prAisFsmInfo->ucConnTrialCount++; -+ } -+#if CFG_SUPPORT_ADHOC -+ else if (prBssDesc->eBSSType == BSS_TYPE_IBSS) { -+ -+ prAisBssInfo->eCurrentOPMode = OP_MODE_IBSS; -+ -+ /* Record the target BSS_DESC_T for next STATE. */ -+ prAisFsmInfo->prTargetBssDesc = prBssDesc; -+ -+ eNextState = AIS_STATE_IBSS_MERGE; -+ fgIsTransition = TRUE; -+ } -+#endif /* CFG_SUPPORT_ADHOC */ -+ else { -+ ASSERT(0); -+ eNextState = AIS_STATE_WAIT_FOR_NEXT_SCAN; -+ fgIsTransition = TRUE; -+ } -+ } -+ /* 4 <2.b> If we don't have the matched one */ -+ else { -+ -+ /* increase connection trial count for infrastructure connection */ -+ if (prConnSettings->eOPMode == NET_TYPE_INFRA) -+ prAisFsmInfo->ucConnTrialCount++; -+ /* 4 Try to SCAN */ -+ if (prAisFsmInfo->fgTryScan) { -+ eNextState = AIS_STATE_LOOKING_FOR; -+ -+ fgIsTransition = TRUE; -+ break; -+ } -+ /* 4 We've do SCAN already, now wait in some STATE. */ -+ if (prConnSettings->eOPMode == NET_TYPE_INFRA) { -+ -+ /* issue reconnect request, -+ * and retreat to idle state for scheduling */ -+ aisFsmInsertRequest(prAdapter, AIS_REQUEST_RECONNECT); -+ -+ eNextState = AIS_STATE_IDLE; -+ fgIsTransition = TRUE; -+ } -+#if CFG_SUPPORT_ADHOC -+ else if ((prConnSettings->eOPMode == NET_TYPE_IBSS) -+ || (prConnSettings->eOPMode == NET_TYPE_AUTO_SWITCH) -+ || (prConnSettings->eOPMode == NET_TYPE_DEDICATED_IBSS)) { -+ -+ prAisBssInfo->eCurrentOPMode = OP_MODE_IBSS; -+ prAisFsmInfo->prTargetBssDesc = NULL; -+ -+ eNextState = AIS_STATE_IBSS_ALONE; -+ fgIsTransition = TRUE; -+ } -+#endif /* CFG_SUPPORT_ADHOC */ -+ else { -+ ASSERT(0); -+ eNextState = AIS_STATE_WAIT_FOR_NEXT_SCAN; -+ fgIsTransition = TRUE; -+ } -+ } -+ } -+ /* 4 <3> We are under Roaming Condition. */ -+ else { /* prAdapter->eConnectionState == MEDIA_STATE_CONNECTED. */ -+ -+ /* 4 <3.a> This BSS_DESC_T is our AP. */ -+ /* NOTE(Kevin 2008/05/16): Following cases will go back to NORMAL_TR. -+ * CASE I: During Roaming, APP(WZC/NDISTEST) change the connection -+ * settings. That make we can NOT match the original AP, so the -+ * prBssDesc is NULL. -+ * CASE II: The same reason as CASE I. Because APP change the -+ * eOPMode to other network type in connection setting -+ * (e.g. NET_TYPE_IBSS), so the BssDesc become the IBSS node. -+ * (For CASE I/II, before WZC/NDISTEST set the OID_SSID, it will change -+ * other parameters in connection setting first. So if we do roaming -+ * at the same time, it will hit these cases.) -+ * -+ * CASE III: Normal case, we can't find other candidate to roam -+ * out, so only the current AP will be matched. -+ * -+ * CASE IV: Timestamp of the current AP might be reset -+ */ -+ if (prAisBssInfo->ucReasonOfDisconnect != DISCONNECT_REASON_CODE_REASSOCIATION && -+ ((!prBssDesc) || /* CASE I */ -+ (prBssDesc->eBSSType != BSS_TYPE_INFRASTRUCTURE) || /* CASE II */ -+ (prBssDesc->fgIsConnected) || /* CASE III */ -+ (EQUAL_MAC_ADDR(prBssDesc->aucBSSID, prAisBssInfo->aucBSSID))) /* CASE IV */) { -+#if DBG -+ if ((prBssDesc) && (prBssDesc->fgIsConnected)) -+ ASSERT(EQUAL_MAC_ADDR(prBssDesc->aucBSSID, prAisBssInfo->aucBSSID)); -+#endif /* DBG */ -+ /* We already associated with it, go back to NORMAL_TR */ -+ /* TODO(Kevin): Roaming Fail */ -+#if CFG_SUPPORT_ROAMING -+ roamingFsmRunEventFail(prAdapter, ROAMING_FAIL_REASON_NOCANDIDATE); -+#endif /* CFG_SUPPORT_ROAMING */ -+ -+ /* Retreat to NORMAL_TR state */ -+ eNextState = AIS_STATE_NORMAL_TR; -+ fgIsTransition = TRUE; -+ break; -+ } -+ -+ /* 4 <3.b> Try to roam out for JOIN this BSS_DESC_T. */ -+ if (prBssDesc == NULL) { -+ /* increase connection trial count for infrastructure connection */ -+ if (prConnSettings->eOPMode == NET_TYPE_INFRA) -+ prAisFsmInfo->ucConnTrialCount++; -+ /* 4 Try to SCAN */ -+ if (prAisFsmInfo->fgTryScan) { -+ eNextState = AIS_STATE_LOOKING_FOR; -+ -+ fgIsTransition = TRUE; -+ break; -+ } -+ -+ /* 4 We've do SCAN already, now wait in some STATE. */ -+ if (prConnSettings->eOPMode == NET_TYPE_INFRA) { -+ -+ /* issue reconnect request, and retreat to idle state -+ * for scheduling */ -+ aisFsmInsertRequest(prAdapter, AIS_REQUEST_RECONNECT); -+ -+ eNextState = AIS_STATE_IDLE; -+ fgIsTransition = TRUE; -+ } -+#if CFG_SUPPORT_ADHOC -+ else if ((prConnSettings->eOPMode == NET_TYPE_IBSS) -+ || (prConnSettings->eOPMode == NET_TYPE_AUTO_SWITCH) -+ || (prConnSettings->eOPMode == -+ NET_TYPE_DEDICATED_IBSS)) { -+ -+ prAisBssInfo->eCurrentOPMode = OP_MODE_IBSS; -+ prAisFsmInfo->prTargetBssDesc = NULL; -+ -+ eNextState = AIS_STATE_IBSS_ALONE; -+ fgIsTransition = TRUE; -+ } -+#endif /* CFG_SUPPORT_ADHOC */ -+ else { -+ ASSERT(0); -+ eNextState = AIS_STATE_WAIT_FOR_NEXT_SCAN; -+ fgIsTransition = TRUE; -+ } -+ } else { -+#if DBG -+ if (prAisBssInfo->ucReasonOfDisconnect != -+ DISCONNECT_REASON_CODE_REASSOCIATION) { -+ ASSERT(UNEQUAL_MAC_ADDR -+ (prBssDesc->aucBSSID, prAisBssInfo->aucBSSID)); -+ } -+#endif /* DBG */ -+ -+ /* 4 Record the target BSS_DESC_T for next STATE. */ -+ prAisFsmInfo->prTargetBssDesc = prBssDesc; -+ -+ /* tyhsu: increase connection trial count */ -+ prAisFsmInfo->ucConnTrialCount++; -+ -+ /* Transit to channel acquire */ -+ eNextState = AIS_STATE_REQ_CHANNEL_JOIN; -+ fgIsTransition = TRUE; -+ } -+ } -+ -+ break; -+ -+ case AIS_STATE_WAIT_FOR_NEXT_SCAN: -+ -+ DBGLOG(AIS, LOUD, "SCAN: Idle Begin - Current Time = %u\n", kalGetTimeTick()); -+ -+ cnmTimerStartTimer(prAdapter, -+ &prAisFsmInfo->rBGScanTimer, SEC_TO_MSEC(prAisFsmInfo->u4SleepInterval)); -+ -+ SET_NET_PWR_STATE_IDLE(prAdapter, NETWORK_TYPE_AIS_INDEX); -+ -+ if (prAisFsmInfo->u4SleepInterval < AIS_BG_SCAN_INTERVAL_MAX_SEC) -+ prAisFsmInfo->u4SleepInterval <<= 1; -+ break; -+ -+ case AIS_STATE_SCAN: -+ case AIS_STATE_ONLINE_SCAN: -+ case AIS_STATE_LOOKING_FOR: -+ -+ if (!IS_NET_ACTIVE(prAdapter, NETWORK_TYPE_AIS_INDEX)) { -+ SET_NET_ACTIVE(prAdapter, NETWORK_TYPE_AIS_INDEX); -+ -+ /* sync with firmware */ -+ nicActivateNetwork(prAdapter, NETWORK_TYPE_AIS_INDEX); -+ } -+ -+ /* IE length decision */ -+ if (prAisFsmInfo->u4ScanIELength > 0) { -+ u2ScanIELen = (UINT_16) prAisFsmInfo->u4ScanIELength; -+ } else { -+#if CFG_SUPPORT_WPS2 -+ u2ScanIELen = prAdapter->prGlueInfo->u2WSCIELen; -+#else -+ u2ScanIELen = 0; -+#endif -+ } -+ -+ prScanReqMsg = (P_MSG_SCN_SCAN_REQ) cnmMemAlloc(prAdapter, -+ RAM_TYPE_MSG, -+ OFFSET_OF(MSG_SCN_SCAN_REQ, -+ aucIE) + u2ScanIELen); -+ if (!prScanReqMsg) { -+ ASSERT(0); /* Can't trigger SCAN FSM */ -+ return; -+ } -+ -+ prScanReqMsg->rMsgHdr.eMsgId = MID_AIS_SCN_SCAN_REQ; -+ prScanReqMsg->ucSeqNum = ++prAisFsmInfo->ucSeqNumOfScanReq; -+ prScanReqMsg->ucNetTypeIndex = (UINT_8) NETWORK_TYPE_AIS_INDEX; -+ -+#if CFG_SUPPORT_RDD_TEST_MODE -+ prScanReqMsg->eScanType = SCAN_TYPE_PASSIVE_SCAN; -+#else -+ prScanReqMsg->eScanType = SCAN_TYPE_ACTIVE_SCAN; -+#endif -+ -+#if CFG_SUPPORT_ROAMING_ENC -+ if (prAdapter->fgIsRoamingEncEnabled == TRUE) { -+ if (prAisFsmInfo->eCurrentState == AIS_STATE_LOOKING_FOR && -+ prAisBssInfo->eConnectionState == PARAM_MEDIA_STATE_CONNECTED) { -+ prScanReqMsg->u2ChannelDwellTime = AIS_ROAMING_SCAN_CHANNEL_DWELL_TIME; -+ } -+ } -+#endif /* CFG_SUPPORT_ROAMING_ENC */ -+ -+ if (prAisFsmInfo->eCurrentState == AIS_STATE_SCAN -+ || prAisFsmInfo->eCurrentState == AIS_STATE_ONLINE_SCAN) { -+ if (prAisFsmInfo->ucScanSSIDLen == 0) { -+ /* Scan for all available SSID */ -+ prScanReqMsg->ucSSIDType = SCAN_REQ_SSID_WILDCARD; -+ } else { -+ prScanReqMsg->ucSSIDType = SCAN_REQ_SSID_SPECIFIED; -+ COPY_SSID(prScanReqMsg->aucSSID, -+ prScanReqMsg->ucSSIDLength, -+ prAisFsmInfo->aucScanSSID, prAisFsmInfo->ucScanSSIDLen); -+ } -+ } else { -+ /* Scan for determined SSID */ -+ prScanReqMsg->ucSSIDType = SCAN_REQ_SSID_SPECIFIED; -+ COPY_SSID(prScanReqMsg->aucSSID, -+ prScanReqMsg->ucSSIDLength, -+ prConnSettings->aucSSID, prConnSettings->ucSSIDLen); -+ } -+ -+ /* check if tethering is running and need to fix on specific channel */ -+ if (cnmAisInfraChannelFixed(prAdapter, &eBand, &ucChannel) == TRUE) { -+ prScanReqMsg->eScanChannel = SCAN_CHANNEL_SPECIFIED; -+ prScanReqMsg->ucChannelListNum = 1; -+ prScanReqMsg->arChnlInfoList[0].eBand = eBand; -+ prScanReqMsg->arChnlInfoList[0].ucChannelNum = ucChannel; -+ } else { -+#if 0 -+ aisFsmSetChannelInfo(prAdapter, prScanReqMsg, prAisFsmInfo->eCurrentState); -+#endif -+ if (prAdapter->aePreferBand[NETWORK_TYPE_AIS_INDEX] -+ == BAND_NULL) { -+ if (prAdapter->fgEnable5GBand == TRUE) -+ prScanReqMsg->eScanChannel = SCAN_CHANNEL_FULL; -+ else -+ prScanReqMsg->eScanChannel = SCAN_CHANNEL_2G4; -+ } else if (prAdapter->aePreferBand[NETWORK_TYPE_AIS_INDEX] -+ == BAND_2G4) { -+ prScanReqMsg->eScanChannel = SCAN_CHANNEL_2G4; -+ } else if (prAdapter->aePreferBand[NETWORK_TYPE_AIS_INDEX] -+ == BAND_5G) { -+ prScanReqMsg->eScanChannel = SCAN_CHANNEL_5G; -+ } else { -+ prScanReqMsg->eScanChannel = SCAN_CHANNEL_FULL; -+ ASSERT(0); -+ } -+ -+ } -+ -+ if (prAisFsmInfo->u4ScanIELength > 0) { -+ kalMemCopy(prScanReqMsg->aucIE, prAisFsmInfo->aucScanIEBuf, -+ prAisFsmInfo->u4ScanIELength); -+ } else { -+#if CFG_SUPPORT_WPS2 -+ if (prAdapter->prGlueInfo->u2WSCIELen > 0) { -+ kalMemCopy(prScanReqMsg->aucIE, &prAdapter->prGlueInfo->aucWSCIE, -+ prAdapter->prGlueInfo->u2WSCIELen); -+ } -+ } -+#endif -+ -+ prScanReqMsg->u2IELen = u2ScanIELen; -+ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prScanReqMsg, MSG_SEND_METHOD_BUF); -+ DBGLOG(AIS, TRACE, "SendSR%d\n", prScanReqMsg->ucSeqNum); -+ prAisFsmInfo->fgTryScan = FALSE; /* Will enable background sleep for infrastructure */ -+ -+ prAdapter->ucScanTime++; -+ break; -+ -+ case AIS_STATE_REQ_CHANNEL_JOIN: -+ /* send message to CNM for acquiring channel */ -+ prMsgChReq = (P_MSG_CH_REQ_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_CH_REQ_T)); -+ if (!prMsgChReq) { -+ ASSERT(0); /* Can't indicate CNM for channel acquiring */ -+ return; -+ } -+ -+ prMsgChReq->rMsgHdr.eMsgId = MID_MNY_CNM_CH_REQ; -+ prMsgChReq->ucNetTypeIndex = NETWORK_TYPE_AIS_INDEX; -+ prMsgChReq->ucTokenID = ++prAisFsmInfo->ucSeqNumOfChReq; -+ prMsgChReq->eReqType = CH_REQ_TYPE_JOIN; -+ prMsgChReq->u4MaxInterval = AIS_JOIN_CH_REQUEST_INTERVAL; -+ -+ if (prAisFsmInfo->prTargetBssDesc != NULL) { -+ prMsgChReq->ucPrimaryChannel = prAisFsmInfo->prTargetBssDesc->ucChannelNum; -+ prMsgChReq->eRfSco = prAisFsmInfo->prTargetBssDesc->eSco; -+ prMsgChReq->eRfBand = prAisFsmInfo->prTargetBssDesc->eBand; -+ COPY_MAC_ADDR(prMsgChReq->aucBSSID, prAisFsmInfo->prTargetBssDesc->aucBSSID); -+ } -+ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgChReq, MSG_SEND_METHOD_BUF); -+ -+ prAisFsmInfo->fgIsChannelRequested = TRUE; -+ break; -+ -+ case AIS_STATE_JOIN: -+ aisFsmStateInit_JOIN(prAdapter, prAisFsmInfo->prTargetBssDesc); -+ break; -+ -+#if CFG_SUPPORT_ADHOC -+ case AIS_STATE_IBSS_ALONE: -+ aisFsmStateInit_IBSS_ALONE(prAdapter); -+ break; -+ -+ case AIS_STATE_IBSS_MERGE: -+ aisFsmStateInit_IBSS_MERGE(prAdapter, prAisFsmInfo->prTargetBssDesc); -+ break; -+#endif /* CFG_SUPPORT_ADHOC */ -+ -+ case AIS_STATE_NORMAL_TR: -+ if (prAisFsmInfo->fgIsInfraChannelFinished == FALSE) { -+ /* Don't do anything when rJoinTimeoutTimer is still ticking */ -+ } else { -+ /* 1. Process for pending scan */ -+ if (aisFsmIsRequestPending(prAdapter, AIS_REQUEST_SCAN, TRUE) == TRUE) { -+ wlanClearScanningResult(prAdapter); -+ eNextState = AIS_STATE_ONLINE_SCAN; -+ fgIsTransition = TRUE; -+ } -+ /* 2. Process for pending roaming scan */ -+ else if (aisFsmIsRequestPending(prAdapter, AIS_REQUEST_ROAMING_SEARCH, TRUE) == TRUE) { -+ eNextState = AIS_STATE_LOOKING_FOR; -+ fgIsTransition = TRUE; -+ } -+ /* 3. Process for pending roaming scan */ -+ else if (aisFsmIsRequestPending(prAdapter, AIS_REQUEST_ROAMING_CONNECT, TRUE) == TRUE) { -+ eNextState = AIS_STATE_SEARCH; -+ fgIsTransition = TRUE; -+ } else if (aisFsmIsRequestPending(prAdapter, AIS_REQUEST_REMAIN_ON_CHANNEL, TRUE) == -+ TRUE) { -+ eNextState = AIS_STATE_REQ_REMAIN_ON_CHANNEL; -+ fgIsTransition = TRUE; -+ } -+ } -+ -+ break; -+ -+ case AIS_STATE_DISCONNECTING: -+ /* send for deauth frame for disconnection */ -+ authSendDeauthFrame(prAdapter, -+ prAisBssInfo->prStaRecOfAP, -+ (P_SW_RFB_T) NULL, REASON_CODE_DEAUTH_LEAVING_BSS, aisDeauthXmitComplete); -+ cnmTimerStartTimer(prAdapter, &prAisFsmInfo->rDeauthDoneTimer, 100); -+ break; -+ -+ case AIS_STATE_REQ_REMAIN_ON_CHANNEL: -+ /* send message to CNM for acquiring channel */ -+ prMsgChReq = (P_MSG_CH_REQ_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_CH_REQ_T)); -+ if (!prMsgChReq) { -+ ASSERT(0); /* Can't indicate CNM for channel acquiring */ -+ return; -+ } -+ -+ /* zero-ize */ -+ kalMemZero(prMsgChReq, sizeof(MSG_CH_REQ_T)); -+ -+ /* filling */ -+ prMsgChReq->rMsgHdr.eMsgId = MID_MNY_CNM_CH_REQ; -+ prMsgChReq->ucNetTypeIndex = NETWORK_TYPE_AIS_INDEX; -+ prMsgChReq->ucTokenID = ++prAisFsmInfo->ucSeqNumOfChReq; -+ prMsgChReq->eReqType = CH_REQ_TYPE_JOIN; -+ prMsgChReq->u4MaxInterval = prAisFsmInfo->rChReqInfo.u4DurationMs; -+ prMsgChReq->ucPrimaryChannel = prAisFsmInfo->rChReqInfo.ucChannelNum; -+ prMsgChReq->eRfSco = prAisFsmInfo->rChReqInfo.eSco; -+ prMsgChReq->eRfBand = prAisFsmInfo->rChReqInfo.eBand; -+ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgChReq, MSG_SEND_METHOD_BUF); -+ -+ prAisFsmInfo->fgIsChannelRequested = TRUE; -+ -+ break; -+ -+ case AIS_STATE_REMAIN_ON_CHANNEL: -+ SET_NET_ACTIVE(prAdapter, NETWORK_TYPE_AIS_INDEX); -+ /* sync with firmware */ -+ nicActivateNetwork(prAdapter, NETWORK_TYPE_AIS_INDEX); -+ break; -+ -+ default: -+ ASSERT(0); /* Make sure we have handle all STATEs */ -+ break; -+ -+ } -+ } while (fgIsTransition); -+ -+ return; -+ -+} /* end of aisFsmSteps() */ -+#if 0 -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID aisFsmSetChannelInfo(IN P_ADAPTER_T prAdapter, IN P_MSG_SCN_SCAN_REQ ScanReqMsg, IN ENUM_AIS_STATE_T CurrentState) -+{ -+ /*get scan channel infro from prAdapter->prGlueInfo->prScanRequest*/ -+ struct cfg80211_scan_request *scan_req_t = NULL; -+ struct ieee80211_channel *channel_tmp = NULL; -+ int i = 0; -+ int j = 0; -+ UINT_8 channel_num = 0; -+ UINT_8 channel_counts = 0; -+ -+ if ((prAdapter == NULL) || (ScanReqMsg == NULL)) -+ return; -+ if ((CurrentState == AIS_STATE_SCAN) || (CurrentState == AIS_STATE_ONLINE_SCAN)) { -+ if (prAdapter->prGlueInfo->prScanRequest != NULL) { -+ scan_req_t = prAdapter->prGlueInfo->prScanRequest; -+ if ((scan_req_t != NULL) && (scan_req_t->n_channels != 0) && -+ (scan_req_t->channels != NULL)) { -+ channel_counts = scan_req_t->n_channels; -+ DBGLOG(AIS, TRACE, "channel_counts=%d\n", channel_counts); -+ -+ while (j < channel_counts) { -+ channel_tmp = scan_req_t->channels[j]; -+ if (channel_tmp == NULL) -+ break; -+ -+ DBGLOG(AIS, TRACE, "set channel band=%d\n", channel_tmp->band); -+ if (channel_tmp->band >= IEEE80211_BAND_60GHZ) { -+ j++; -+ continue; -+ } -+ if (i >= MAXIMUM_OPERATION_CHANNEL_LIST) -+ break; -+ if (channel_tmp->band == IEEE80211_BAND_2GHZ) -+ ScanReqMsg->arChnlInfoList[i].eBand = BAND_2G4; -+ else if (channel_tmp->band == IEEE80211_BAND_5GHZ) -+ ScanReqMsg->arChnlInfoList[i].eBand = BAND_5G; -+ -+ DBGLOG(AIS, TRACE, "set channel channel_rer =%d\n", -+ channel_tmp->center_freq); -+ -+ channel_num = (UINT_8)nicFreq2ChannelNum( -+ channel_tmp->center_freq * 1000); -+ -+ DBGLOG(AIS, TRACE, "set channel channel_num=%d\n", -+ channel_num); -+ ScanReqMsg->arChnlInfoList[i].ucChannelNum = channel_num; -+ -+ j++; -+ i++; -+ } -+ } -+ } -+ } -+ -+ DBGLOG(AIS, INFO, "set channel i=%d\n", i); -+ if (i > 0) { -+ ScanReqMsg->ucChannelListNum = i; -+ ScanReqMsg->eScanChannel = SCAN_CHANNEL_SPECIFIED; -+ -+ return; -+ } -+ -+ if (prAdapter->aePreferBand[NETWORK_TYPE_AIS_INDEX] -+ == BAND_NULL) { -+ if (prAdapter->fgEnable5GBand == TRUE) -+ ScanReqMsg->eScanChannel = SCAN_CHANNEL_FULL; -+ else -+ ScanReqMsg->eScanChannel = SCAN_CHANNEL_2G4; -+ } else if (prAdapter->aePreferBand[NETWORK_TYPE_AIS_INDEX] -+ == BAND_2G4) { -+ ScanReqMsg->eScanChannel = SCAN_CHANNEL_2G4; -+ } else if (prAdapter->aePreferBand[NETWORK_TYPE_AIS_INDEX] -+ == BAND_5G) { -+ ScanReqMsg->eScanChannel = SCAN_CHANNEL_5G; -+ } else { -+ ScanReqMsg->eScanChannel = SCAN_CHANNEL_FULL; -+ ASSERT(0); -+ } -+ -+ -+} -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+ -+VOID aisFsmRunEventScanDone(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) -+{ -+ P_MSG_SCN_SCAN_DONE prScanDoneMsg; -+ P_AIS_FSM_INFO_T prAisFsmInfo; -+ ENUM_AIS_STATE_T eNextState; -+ UINT_8 ucSeqNumOfCompMsg; -+ P_CONNECTION_SETTINGS_T prConnSettings; -+ -+ DEBUGFUNC("aisFsmRunEventScanDone()"); -+ -+ ASSERT(prAdapter); -+ ASSERT(prMsgHdr); -+ -+ ucScanTimeoutTimes = 0; -+ -+ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); -+ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); -+ -+ prScanDoneMsg = (P_MSG_SCN_SCAN_DONE) prMsgHdr; -+ ASSERT(prScanDoneMsg->ucNetTypeIndex == (UINT_8) NETWORK_TYPE_AIS_INDEX); -+ -+ ucSeqNumOfCompMsg = prScanDoneMsg->ucSeqNum; -+ cnmMemFree(prAdapter, prMsgHdr); -+ -+ eNextState = prAisFsmInfo->eCurrentState; -+ -+ if (ucSeqNumOfCompMsg != prAisFsmInfo->ucSeqNumOfScanReq) { -+ DBGLOG(AIS, WARN, "SEQ NO of AIS SCN DONE MSG is not matched %d %d.\n", -+ ucSeqNumOfCompMsg, prAisFsmInfo->ucSeqNumOfScanReq); -+ } else { -+ switch (prAisFsmInfo->eCurrentState) { -+ case AIS_STATE_SCAN: -+ prConnSettings->fgIsScanReqIssued = FALSE; -+ -+ /* reset scan IE buffer */ -+ prAisFsmInfo->u4ScanIELength = 0; -+ -+ kalScanDone(prAdapter->prGlueInfo, KAL_NETWORK_TYPE_AIS_INDEX, WLAN_STATUS_SUCCESS); -+ eNextState = AIS_STATE_IDLE; -+#if CFG_SUPPORT_AGPS_ASSIST -+ scanReportScanResultToAgps(prAdapter); -+#endif -+ break; -+ -+ case AIS_STATE_ONLINE_SCAN: -+ prConnSettings->fgIsScanReqIssued = FALSE; -+ -+ /* reset scan IE buffer */ -+ prAisFsmInfo->u4ScanIELength = 0; -+ -+ kalScanDone(prAdapter->prGlueInfo, KAL_NETWORK_TYPE_AIS_INDEX, WLAN_STATUS_SUCCESS); -+#if CFG_SUPPORT_ROAMING -+ eNextState = aisFsmRoamingScanResultsUpdate(prAdapter); -+#else -+ eNextState = AIS_STATE_NORMAL_TR; -+#endif /* CFG_SUPPORT_ROAMING */ -+#if CFG_SUPPORT_AGPS_ASSIST -+ scanReportScanResultToAgps(prAdapter); -+#endif -+ break; -+ -+ case AIS_STATE_LOOKING_FOR: -+ cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rScanDoneTimer); -+ scanReportBss2Cfg80211(prAdapter, BSS_TYPE_INFRASTRUCTURE, NULL); -+#if CFG_SUPPORT_ROAMING -+ eNextState = aisFsmRoamingScanResultsUpdate(prAdapter); -+#else -+ eNextState = AIS_STATE_SEARCH; -+#endif /* CFG_SUPPORT_ROAMING */ -+ break; -+ -+ default: -+ cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rScanDoneTimer); -+ break; -+ -+ } -+ } -+ -+ if (eNextState != prAisFsmInfo->eCurrentState) -+ aisFsmSteps(prAdapter, eNextState); -+ -+} /* end of aisFsmRunEventScanDone() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID aisFsmRunEventAbort(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) -+{ -+ P_MSG_AIS_ABORT_T prAisAbortMsg; -+ P_AIS_FSM_INFO_T prAisFsmInfo; -+ UINT_8 ucReasonOfDisconnect; -+ BOOLEAN fgDelayIndication; -+ P_CONNECTION_SETTINGS_T prConnSettings; -+ -+ DEBUGFUNC("aisFsmRunEventAbort()"); -+ -+ ASSERT(prAdapter); -+ ASSERT(prMsgHdr); -+ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); -+ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); -+ -+ /* 4 <1> Extract information of Abort Message and then free memory. */ -+ prAisAbortMsg = (P_MSG_AIS_ABORT_T) prMsgHdr; -+ ucReasonOfDisconnect = prAisAbortMsg->ucReasonOfDisconnect; -+ fgDelayIndication = prAisAbortMsg->fgDelayIndication; -+ -+ cnmMemFree(prAdapter, prMsgHdr); -+ -+#if DBG -+ DBGLOG(AIS, STATE, "EVENT-ABORT: Current State %s %d\n", -+ apucDebugAisState[prAisFsmInfo->eCurrentState], ucReasonOfDisconnect); -+#else -+ DBGLOG(AIS, STATE, "[%d] EVENT-ABORT: Current State [%d %d]\n", -+ DBG_AIS_IDX, prAisFsmInfo->eCurrentState, ucReasonOfDisconnect); -+#endif -+ -+ GET_CURRENT_SYSTIME(&(prAisFsmInfo->rJoinReqTime)); -+ -+ /* 4 <2> clear previous pending connection request and insert new one */ -+ if (ucReasonOfDisconnect == DISCONNECT_REASON_CODE_DEAUTHENTICATED -+ || ucReasonOfDisconnect == DISCONNECT_REASON_CODE_DISASSOCIATED) { -+ prConnSettings->fgIsDisconnectedByNonRequest = TRUE; -+ } else { -+ prConnSettings->fgIsDisconnectedByNonRequest = FALSE; -+ } -+ /* to support user space triggered roaming */ -+ if (ucReasonOfDisconnect == DISCONNECT_REASON_CODE_ROAMING && -+ prAisFsmInfo->eCurrentState != AIS_STATE_DISCONNECTING) { -+ -+ if (prAisFsmInfo->eCurrentState == AIS_STATE_NORMAL_TR && -+ prAisFsmInfo->fgIsInfraChannelFinished == TRUE) { -+ aisFsmSteps(prAdapter, AIS_STATE_SEARCH); -+ } else { -+ aisFsmIsRequestPending(prAdapter, AIS_REQUEST_ROAMING_SEARCH, TRUE); -+ aisFsmIsRequestPending(prAdapter, AIS_REQUEST_ROAMING_CONNECT, TRUE); -+ aisFsmInsertRequest(prAdapter, AIS_REQUEST_ROAMING_CONNECT); -+ } -+ return; -+ } -+ -+ aisFsmIsRequestPending(prAdapter, AIS_REQUEST_RECONNECT, TRUE); -+ aisFsmInsertRequest(prAdapter, AIS_REQUEST_RECONNECT); -+ -+ if (prAisFsmInfo->eCurrentState != AIS_STATE_DISCONNECTING) { -+ /* 4 <3> invoke abort handler */ -+ aisFsmStateAbort(prAdapter, ucReasonOfDisconnect, fgDelayIndication); -+ } -+ -+} /* end of aisFsmRunEventAbort() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function handles AIS-FSM abort event/command -+* -+* \param[in] prAdapter Pointer of ADAPTER_T -+* ucReasonOfDisconnect Reason for disonnection -+* fgDelayIndication Option to delay disconnection indication -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID aisFsmStateAbort(IN P_ADAPTER_T prAdapter, UINT_8 ucReasonOfDisconnect, BOOLEAN fgDelayIndication) -+{ -+ P_AIS_FSM_INFO_T prAisFsmInfo; -+ P_BSS_INFO_T prAisBssInfo; -+ P_CONNECTION_SETTINGS_T prConnSettings; -+ BOOLEAN fgIsCheckConnected; -+ -+ ASSERT(prAdapter); -+ -+ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); -+ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); -+ fgIsCheckConnected = FALSE; -+ -+ /* 4 <1> Save information of Abort Message and then free memory. */ -+ prAisBssInfo->ucReasonOfDisconnect = ucReasonOfDisconnect; -+ -+ /* 4 <2> Abort current job. */ -+ switch (prAisFsmInfo->eCurrentState) { -+ case AIS_STATE_IDLE: -+ case AIS_STATE_SEARCH: -+ break; -+ -+ case AIS_STATE_WAIT_FOR_NEXT_SCAN: -+ /* Do cancel timer */ -+ cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rBGScanTimer); -+ -+ /* in case roaming is triggered */ -+ fgIsCheckConnected = TRUE; -+ break; -+ -+ case AIS_STATE_SCAN: -+ /* Do abort SCAN */ -+ aisFsmStateAbort_SCAN(prAdapter); -+ -+ /* queue for later handling */ -+ if (aisFsmIsRequestPending(prAdapter, AIS_REQUEST_SCAN, FALSE) == FALSE) -+ aisFsmInsertRequest(prAdapter, AIS_REQUEST_SCAN); -+ -+ break; -+ -+ case AIS_STATE_LOOKING_FOR: -+ /* Do abort SCAN */ -+ aisFsmStateAbort_SCAN(prAdapter); -+ -+ /* in case roaming is triggered */ -+ fgIsCheckConnected = TRUE; -+ break; -+ -+ case AIS_STATE_REQ_CHANNEL_JOIN: -+ /* Release channel to CNM */ -+ aisFsmReleaseCh(prAdapter); -+ -+ /* in case roaming is triggered */ -+ fgIsCheckConnected = TRUE; -+ break; -+ -+ case AIS_STATE_JOIN: -+ /* Do abort JOIN */ -+ aisFsmStateAbort_JOIN(prAdapter); -+ -+ /* in case roaming is triggered */ -+ fgIsCheckConnected = TRUE; -+ break; -+ -+#if CFG_SUPPORT_ADHOC -+ case AIS_STATE_IBSS_ALONE: -+ case AIS_STATE_IBSS_MERGE: -+ aisFsmStateAbort_IBSS(prAdapter); -+ break; -+#endif /* CFG_SUPPORT_ADHOC */ -+ -+ case AIS_STATE_ONLINE_SCAN: -+ /* Do abort SCAN */ -+ aisFsmStateAbort_SCAN(prAdapter); -+ -+ /* queue for later handling */ -+ if (aisFsmIsRequestPending(prAdapter, AIS_REQUEST_SCAN, FALSE) == FALSE) -+ aisFsmInsertRequest(prAdapter, AIS_REQUEST_SCAN); -+ -+ fgIsCheckConnected = TRUE; -+ break; -+ -+ case AIS_STATE_NORMAL_TR: -+ fgIsCheckConnected = TRUE; -+ break; -+ -+ case AIS_STATE_DISCONNECTING: -+ /* Do abort NORMAL_TR */ -+ aisFsmStateAbort_NORMAL_TR(prAdapter); -+ -+ break; -+ -+ case AIS_STATE_REQ_REMAIN_ON_CHANNEL: -+ /* release channel */ -+ aisFsmReleaseCh(prAdapter); -+ break; -+ -+ case AIS_STATE_REMAIN_ON_CHANNEL: -+ /* 1. release channel */ -+ aisFsmReleaseCh(prAdapter); -+ -+ /* 2. stop channel timeout timer */ -+ cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rChannelTimeoutTimer); -+ -+ break; -+ -+ default: -+ break; -+ } -+ -+ if (fgIsCheckConnected && (PARAM_MEDIA_STATE_CONNECTED == prAisBssInfo->eConnectionState)) { -+ -+ /* switch into DISCONNECTING state for sending DEAUTH if necessary */ -+ if (prAisBssInfo->eCurrentOPMode == OP_MODE_INFRASTRUCTURE && -+ prAisBssInfo->ucReasonOfDisconnect == DISCONNECT_REASON_CODE_NEW_CONNECTION && -+ prAisBssInfo->prStaRecOfAP && prAisBssInfo->prStaRecOfAP->fgIsInUse) { -+ aisFsmSteps(prAdapter, AIS_STATE_DISCONNECTING); -+ -+ return; -+ } -+ /* Do abort NORMAL_TR */ -+ aisFsmStateAbort_NORMAL_TR(prAdapter); -+ -+ } -+ -+ aisFsmDisconnect(prAdapter, fgDelayIndication); -+ -+ -+} /* end of aisFsmStateAbort() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will handle the Join Complete Event from SAA FSM for AIS FSM -+* -+* @param[in] prMsgHdr Message of Join Complete of SAA FSM. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID aisFsmRunEventJoinComplete(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) -+{ -+ P_MSG_JOIN_COMP_T prJoinCompMsg; -+ P_AIS_FSM_INFO_T prAisFsmInfo; -+ ENUM_AIS_STATE_T eNextState; -+ P_STA_RECORD_T prStaRec; -+ P_SW_RFB_T prAssocRspSwRfb; -+ P_BSS_INFO_T prAisBssInfo; -+ UINT_8 aucP2pSsid[] = CTIA_MAGIC_SSID; -+ OS_SYSTIME rCurrentTime; -+ -+ DEBUGFUNC("aisFsmRunEventJoinComplete()"); -+ -+ ASSERT(prMsgHdr); -+ -+ GET_CURRENT_SYSTIME(&rCurrentTime); -+ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); -+ prJoinCompMsg = (P_MSG_JOIN_COMP_T) prMsgHdr; -+ prStaRec = prJoinCompMsg->prStaRec; -+ prAssocRspSwRfb = prJoinCompMsg->prSwRfb; -+ -+ eNextState = prAisFsmInfo->eCurrentState; -+ -+ DBGLOG(AIS, TRACE, "AISOK\n"); -+ -+ /* Check State and SEQ NUM */ -+ do { -+ if (prAisFsmInfo->eCurrentState != AIS_STATE_JOIN) -+ break; -+ -+ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ -+ /* Check SEQ NUM */ -+ if (prJoinCompMsg->ucSeqNum == prAisFsmInfo->ucSeqNumOfReqMsg) { -+ -+ /* 4 <1> JOIN was successful */ -+ if (prJoinCompMsg->rJoinStatus == WLAN_STATUS_SUCCESS) { -+ -+ /* 1. Reset retry count */ -+ prAisFsmInfo->ucConnTrialCount = 0; -+ -+ /* Completion of roaming */ -+ if (prAisBssInfo->eConnectionState == PARAM_MEDIA_STATE_CONNECTED) { -+ -+#if CFG_SUPPORT_ROAMING -+ /* 2. Deactivate previous BSS */ -+ aisFsmRoamingDisconnectPrevAP(prAdapter, prStaRec); -+ -+ /* 3. Update bss based on roaming staRec */ -+ aisUpdateBssInfoForRoamingAP(prAdapter, prStaRec, prAssocRspSwRfb); -+#endif /* CFG_SUPPORT_ROAMING */ -+ } else { -+ /* 4 <1.1> Change FW's Media State immediately. */ -+ aisChangeMediaState(prAdapter, PARAM_MEDIA_STATE_CONNECTED); -+ -+ /* 4 <1.2> Deactivate previous AP's STA_RECORD_T in Driver if have. */ -+ if ((prAisBssInfo->prStaRecOfAP) && -+ (prAisBssInfo->prStaRecOfAP != prStaRec) && -+ (prAisBssInfo->prStaRecOfAP->fgIsInUse)) { -+ -+ cnmStaRecChangeState(prAdapter, prAisBssInfo->prStaRecOfAP, -+ STA_STATE_1); -+ } -+ /* 4 <1.3> Update BSS_INFO_T */ -+ aisUpdateBssInfoForJOIN(prAdapter, prStaRec, prAssocRspSwRfb); -+ -+ /* 4 <1.4> Activate current AP's STA_RECORD_T in Driver. */ -+ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_3); -+ -+ /* 4 <1.5> Update RSSI if necessary */ -+ nicUpdateRSSI(prAdapter, NETWORK_TYPE_AIS_INDEX, -+ (INT_8) (RCPI_TO_dBm(prStaRec->ucRCPI)), 0); -+ -+ /* 4 <1.6> Indicate Connected Event to Host immediately. */ -+ /* Require BSSID, Association ID, Beacon Interval.. */ -+ /* from AIS_BSS_INFO_T */ -+ aisIndicationOfMediaStateToHost(prAdapter, PARAM_MEDIA_STATE_CONNECTED, -+ FALSE); -+ -+ /* add for ctia mode */ -+ if (EQUAL_SSID -+ (aucP2pSsid, CTIA_MAGIC_SSID_LEN, prAisBssInfo->aucSSID, -+ prAisBssInfo->ucSSIDLen)) { -+ nicEnterCtiaMode(prAdapter, TRUE, FALSE); -+ } -+ } -+ -+#if CFG_SUPPORT_ROAMING -+ /* if bssid is given, it means we no need fw roaming */ -+ if (prAdapter->rWifiVar.rConnSettings.eConnectionPolicy != CONNECT_BY_BSSID) -+ roamingFsmRunEventStart(prAdapter); -+#endif /* CFG_SUPPORT_ROAMING */ -+ -+ /* 4 <1.7> Set the Next State of AIS FSM */ -+ eNextState = AIS_STATE_NORMAL_TR; -+ } -+ /* 4 <2> JOIN was not successful */ -+ else { -+ /* 4 <2.1> Redo JOIN process with other Auth Type if possible */ -+ if (aisFsmStateInit_RetryJOIN(prAdapter, prStaRec) == FALSE) { -+ P_BSS_DESC_T prBssDesc; -+ -+ /* 1. Increase Failure Count */ -+ prStaRec->ucJoinFailureCount++; -+ -+ /* 2. release channel */ -+ aisFsmReleaseCh(prAdapter); -+ -+ /* 3.1 stop join timeout timer */ -+ cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rJoinTimeoutTimer); -+ -+ /* 3.2 reset local variable */ -+ prAisFsmInfo->fgIsInfraChannelFinished = TRUE; -+ -+ prBssDesc = scanSearchBssDescByBssid(prAdapter, prStaRec->aucMacAddr); -+ -+ if (prBssDesc == NULL) { -+ /* it maybe NULL when wlanRemove */ -+ /* -+ (1) UI does wifi off during SAA does auth/assoc procedure. -+ (2) We will do LINK_INITIALIZE(&prScanInfo->rBSSDescList); -+ in nicUninitMGMT(). -+ (3) We will handle prMsduInfo->pfTxDoneHandler -+ in nicTxRelease(). -+ (4) prMsduInfo->pfTxDoneHandler will point to -+ saaFsmRunEventTxDone(). -+ (5) Then jump to saaFsmSteps() -> saaFsmSendEventJoinComplete() -+ (6) Finally mboxSendMsg() -> aisFsmRunEventJoinComplete(). -+ (7) In aisFsmRunEventJoinComplete(), we will check -+ "prBssDesc = scanSearchBssDescByBssid(prAdapter, -+ prStaRec->aucMacAddr);" -+ (8) And prBssDesc will be NULL and hangs in -+ "ASSERT(prBssDesc->fgIsConnecting);" when DBG=0. -+ ASSERT(prBssDesc); -+ ASSERT(prBssDesc->fgIsConnecting); -+ */ -+ break; -+ } -+ /* ASSERT(prBssDesc); */ -+ /* ASSERT(prBssDesc->fgIsConnecting); */ -+ prBssDesc->ucJoinFailureCount++; -+ if (prBssDesc->ucJoinFailureCount >= SCN_BSS_JOIN_FAIL_THRESOLD) { -+ GET_CURRENT_SYSTIME(&prBssDesc->rJoinFailTime); -+ DBGLOG(AIS, INFO, -+ "Bss %pM join fail %d times,temp disable it at time:%u\n", -+ prBssDesc->aucBSSID, -+ SCN_BSS_JOIN_FAIL_THRESOLD, prBssDesc->rJoinFailTime); -+ } -+ -+ if (prBssDesc) -+ prBssDesc->fgIsConnecting = FALSE; -+ -+ /* 3.3 Free STA-REC */ -+ if (prStaRec != prAisBssInfo->prStaRecOfAP) -+ cnmStaRecFree(prAdapter, prStaRec, FALSE); -+ -+ if (prAisBssInfo->eConnectionState == PARAM_MEDIA_STATE_CONNECTED) { -+#if CFG_SUPPORT_ROAMING -+ eNextState = AIS_STATE_WAIT_FOR_NEXT_SCAN; -+#endif /* CFG_SUPPORT_ROAMING */ -+ } else if (CHECK_FOR_TIMEOUT(rCurrentTime, prAisFsmInfo->rJoinReqTime, -+ SEC_TO_SYSTIME(AIS_JOIN_TIMEOUT))) { -+ /* abort connection trial */ -+ prAdapter->rWifiVar.rConnSettings.fgIsConnReqIssued = FALSE; -+ -+ kalIndicateStatusAndComplete(prAdapter->prGlueInfo, -+ WLAN_STATUS_CONNECT_INDICATION, NULL, 0); -+ -+ eNextState = AIS_STATE_IDLE; -+ } else { -+ /* 4.b send reconnect request */ -+ aisFsmInsertRequest(prAdapter, AIS_REQUEST_RECONNECT); -+ -+ eNextState = AIS_STATE_IDLE; -+ } -+ } -+ } -+ } -+#if DBG -+ else -+ DBGLOG(AIS, WARN, "SEQ NO of AIS JOIN COMP MSG is not matched.\n"); -+#endif /* DBG */ -+ -+ if (eNextState != prAisFsmInfo->eCurrentState) -+ aisFsmSteps(prAdapter, eNextState); -+ } while (FALSE); -+ -+ if (prAssocRspSwRfb) -+ nicRxReturnRFB(prAdapter, prAssocRspSwRfb); -+ -+ cnmMemFree(prAdapter, prMsgHdr); -+ -+} /* end of aisFsmRunEventJoinComplete() */ -+ -+#if CFG_SUPPORT_ADHOC -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will handle the Grant Msg of IBSS Create which was sent by -+* CNM to indicate that channel was changed for creating IBSS. -+* -+* @param[in] prAdapter Pointer of ADAPTER_T -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID aisFsmCreateIBSS(IN P_ADAPTER_T prAdapter) -+{ -+ P_AIS_FSM_INFO_T prAisFsmInfo; -+ -+ ASSERT(prAdapter); -+ -+ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); -+ -+ do { -+ /* Check State */ -+ if (prAisFsmInfo->eCurrentState == AIS_STATE_IBSS_ALONE) -+ aisUpdateBssInfoForCreateIBSS(prAdapter); -+ } while (FALSE); -+ -+} /* end of aisFsmCreateIBSS() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will handle the Grant Msg of IBSS Merge which was sent by -+* CNM to indicate that channel was changed for merging IBSS. -+* -+* @param[in] prAdapter Pointer of ADAPTER_T -+* @param[in] prStaRec Pointer of STA_RECORD_T for merge -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID aisFsmMergeIBSS(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec) -+{ -+ P_AIS_FSM_INFO_T prAisFsmInfo; -+ ENUM_AIS_STATE_T eNextState; -+ P_BSS_INFO_T prAisBssInfo; -+ -+ ASSERT(prAdapter); -+ ASSERT(prStaRec); -+ -+ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); -+ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ -+ do { -+ -+ eNextState = prAisFsmInfo->eCurrentState; -+ -+ switch (prAisFsmInfo->eCurrentState) { -+ case AIS_STATE_IBSS_MERGE: -+ { -+ P_BSS_DESC_T prBssDesc; -+ -+ /* 4 <1.1> Change FW's Media State immediately. */ -+ aisChangeMediaState(prAdapter, PARAM_MEDIA_STATE_CONNECTED); -+ -+ /* 4 <1.2> Deactivate previous Peers' STA_RECORD_T in Driver if have. */ -+ bssClearClientList(prAdapter, prAisBssInfo); -+ -+ /* 4 <1.3> Unmark connection flag of previous BSS_DESC_T. */ -+ prBssDesc = scanSearchBssDescByBssid(prAdapter, prAisBssInfo->aucBSSID); -+ if (prBssDesc != NULL) { -+ prBssDesc->fgIsConnecting = FALSE; -+ prBssDesc->fgIsConnected = FALSE; -+ } -+ /* 4 <1.4> Update BSS_INFO_T */ -+ aisUpdateBssInfoForMergeIBSS(prAdapter, prStaRec); -+ -+ /* 4 <1.5> Add Peers' STA_RECORD_T to Client List */ -+ bssAddStaRecToClientList(prAdapter, prAisBssInfo, prStaRec); -+ -+ /* 4 <1.6> Activate current Peer's STA_RECORD_T in Driver. */ -+ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_3); -+ prStaRec->fgIsMerging = FALSE; -+ -+ /* 4 <1.7> Enable other features */ -+ -+ /* 4 <1.8> Indicate Connected Event to Host immediately. */ -+ aisIndicationOfMediaStateToHost(prAdapter, PARAM_MEDIA_STATE_CONNECTED, FALSE); -+ -+ /* 4 <1.9> Set the Next State of AIS FSM */ -+ eNextState = AIS_STATE_NORMAL_TR; -+ -+ /* 4 <1.10> Release channel privilege */ -+ aisFsmReleaseCh(prAdapter); -+ -+#if CFG_SLT_SUPPORT -+ prAdapter->rWifiVar.rSltInfo.prPseudoStaRec = prStaRec; -+#endif -+ } -+ break; -+ -+ default: -+ break; -+ } -+ -+ if (eNextState != prAisFsmInfo->eCurrentState) -+ aisFsmSteps(prAdapter, eNextState); -+ -+ } while (FALSE); -+ -+} /* end of aisFsmMergeIBSS() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will handle the Notification of existing IBSS was found -+* from SCN. -+* -+* @param[in] prMsgHdr Message of Notification of an IBSS was present. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID aisFsmRunEventFoundIBSSPeer(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) -+{ -+ P_MSG_AIS_IBSS_PEER_FOUND_T prAisIbssPeerFoundMsg; -+ P_AIS_FSM_INFO_T prAisFsmInfo; -+ ENUM_AIS_STATE_T eNextState; -+ P_STA_RECORD_T prStaRec; -+ P_BSS_INFO_T prAisBssInfo; -+ P_BSS_DESC_T prBssDesc; -+ BOOLEAN fgIsMergeIn; -+ -+ ASSERT(prMsgHdr); -+ -+ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); -+ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ -+ prAisIbssPeerFoundMsg = (P_MSG_AIS_IBSS_PEER_FOUND_T) prMsgHdr; -+ -+ ASSERT(prAisIbssPeerFoundMsg->ucNetTypeIndex == NETWORK_TYPE_AIS_INDEX); -+ -+ prStaRec = prAisIbssPeerFoundMsg->prStaRec; -+ ASSERT(prStaRec); -+ -+ fgIsMergeIn = prAisIbssPeerFoundMsg->fgIsMergeIn; -+ -+ cnmMemFree(prAdapter, prMsgHdr); -+ -+ eNextState = prAisFsmInfo->eCurrentState; -+ switch (prAisFsmInfo->eCurrentState) { -+ case AIS_STATE_IBSS_ALONE: -+ { -+ /* 4 <1> An IBSS Peer 'merged in'. */ -+ if (fgIsMergeIn) { -+ -+ /* 4 <1.1> Change FW's Media State immediately. */ -+ aisChangeMediaState(prAdapter, PARAM_MEDIA_STATE_CONNECTED); -+ -+ /* 4 <1.2> Add Peers' STA_RECORD_T to Client List */ -+ bssAddStaRecToClientList(prAdapter, prAisBssInfo, prStaRec); -+ -+#if CFG_SLT_SUPPORT -+ /* 4 <1.3> Mark connection flag of BSS_DESC_T. */ -+ prBssDesc = scanSearchBssDescByTA(prAdapter, prStaRec->aucMacAddr); -+ if (prBssDesc != NULL) { -+ prBssDesc->fgIsConnecting = FALSE; -+ prBssDesc->fgIsConnected = TRUE; -+ } else { -+ ASSERT(0); /* Should be able to find a BSS_DESC_T here. */ -+ } -+ -+ /* 4 <1.4> Activate current Peer's STA_RECORD_T in Driver. */ -+ prStaRec->fgIsQoS = TRUE; /* TODO(Kevin): TBD */ -+#else -+ /* 4 <1.3> Mark connection flag of BSS_DESC_T. */ -+ prBssDesc = scanSearchBssDescByBssid(prAdapter, prAisBssInfo->aucBSSID); -+ if (prBssDesc != NULL) { -+ prBssDesc->fgIsConnecting = FALSE; -+ prBssDesc->fgIsConnected = TRUE; -+ } else { -+ ASSERT(0); /* Should be able to find a BSS_DESC_T here. */ -+ } -+ -+ /* 4 <1.4> Activate current Peer's STA_RECORD_T in Driver. */ -+ prStaRec->fgIsQoS = FALSE; /* TODO(Kevin): TBD */ -+ -+#endif -+ -+ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_3); -+ prStaRec->fgIsMerging = FALSE; -+ -+ /* 4 <1.6> sync. to firmware */ -+ nicUpdateBss(prAdapter, NETWORK_TYPE_AIS_INDEX); -+ -+ /* 4 <1.7> Indicate Connected Event to Host immediately. */ -+ aisIndicationOfMediaStateToHost(prAdapter, PARAM_MEDIA_STATE_CONNECTED, FALSE); -+ -+ /* 4 <1.8> indicate PM for connected */ -+ nicPmIndicateBssConnected(prAdapter, NETWORK_TYPE_AIS_INDEX); -+ -+ /* 4 <1.9> Set the Next State of AIS FSM */ -+ eNextState = AIS_STATE_NORMAL_TR; -+ -+ /* 4 <1.10> Release channel privilege */ -+ aisFsmReleaseCh(prAdapter); -+ } -+ /* 4 <2> We need 'merge out' to this IBSS */ -+ else { -+ -+ /* 4 <2.1> Get corresponding BSS_DESC_T */ -+ prBssDesc = scanSearchBssDescByTA(prAdapter, prStaRec->aucMacAddr); -+ -+ prAisFsmInfo->prTargetBssDesc = prBssDesc; -+ -+ /* 4 <2.2> Set the Next State of AIS FSM */ -+ eNextState = AIS_STATE_IBSS_MERGE; -+ } -+ } -+ break; -+ -+ case AIS_STATE_NORMAL_TR: -+ { -+ -+ /* 4 <3> An IBSS Peer 'merged in'. */ -+ if (fgIsMergeIn) { -+ -+ /* 4 <3.1> Add Peers' STA_RECORD_T to Client List */ -+ bssAddStaRecToClientList(prAdapter, prAisBssInfo, prStaRec); -+ -+#if CFG_SLT_SUPPORT -+ /* 4 <3.2> Activate current Peer's STA_RECORD_T in Driver. */ -+ prStaRec->fgIsQoS = TRUE; /* TODO(Kevin): TBD */ -+#else -+ /* 4 <3.2> Activate current Peer's STA_RECORD_T in Driver. */ -+ prStaRec->fgIsQoS = FALSE; /* TODO(Kevin): TBD */ -+#endif -+ -+ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_3); -+ prStaRec->fgIsMerging = FALSE; -+ -+ } -+ /* 4 <4> We need 'merge out' to this IBSS */ -+ else { -+ -+ /* 4 <4.1> Get corresponding BSS_DESC_T */ -+ prBssDesc = scanSearchBssDescByTA(prAdapter, prStaRec->aucMacAddr); -+ -+ prAisFsmInfo->prTargetBssDesc = prBssDesc; -+ -+ /* 4 <4.2> Set the Next State of AIS FSM */ -+ eNextState = AIS_STATE_IBSS_MERGE; -+ -+ } -+ } -+ break; -+ -+ default: -+ break; -+ } -+ -+ if (eNextState != prAisFsmInfo->eCurrentState) -+ aisFsmSteps(prAdapter, eNextState); -+ -+} /* end of aisFsmRunEventFoundIBSSPeer() */ -+#endif /* CFG_SUPPORT_ADHOC */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will indicate the Media State to HOST -+* -+* @param[in] eConnectionState Current Media State -+* @param[in] fgDelayIndication Set TRUE for postponing the Disconnect Indication. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+aisIndicationOfMediaStateToHost(IN P_ADAPTER_T prAdapter, -+ ENUM_PARAM_MEDIA_STATE_T eConnectionState, BOOLEAN fgDelayIndication) -+{ -+ EVENT_CONNECTION_STATUS rEventConnStatus; -+ P_CONNECTION_SETTINGS_T prConnSettings; -+ P_BSS_INFO_T prAisBssInfo; -+ P_AIS_FSM_INFO_T prAisFsmInfo; -+ -+ DEBUGFUNC("aisIndicationOfMediaStateToHost()"); -+ -+ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); -+ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); -+ -+ /* NOTE(Kevin): Move following line to aisChangeMediaState() macro per CM's request. */ -+ /* prAisBssInfo->eConnectionState = eConnectionState; */ -+ -+ /* For indicating the Disconnect Event only if current media state is -+ * disconnected and we didn't do indication yet. -+ */ -+ if (prAisBssInfo->eConnectionState == PARAM_MEDIA_STATE_DISCONNECTED) { -+ if (prAisBssInfo->eConnectionStateIndicated == eConnectionState) -+ return; -+ } -+ -+ if (!fgDelayIndication) { -+ /* 4 <0> Cancel Delay Timer */ -+ cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rIndicationOfDisconnectTimer); -+ -+ /* 4 <1> Fill EVENT_CONNECTION_STATUS */ -+ rEventConnStatus.ucMediaStatus = (UINT_8) eConnectionState; -+ -+ if (eConnectionState == PARAM_MEDIA_STATE_CONNECTED) { -+ rEventConnStatus.ucReasonOfDisconnect = DISCONNECT_REASON_CODE_RESERVED; -+ -+ if (prAisBssInfo->eCurrentOPMode == OP_MODE_INFRASTRUCTURE) { -+ rEventConnStatus.ucInfraMode = (UINT_8) NET_TYPE_INFRA; -+ rEventConnStatus.u2AID = prAisBssInfo->u2AssocId; -+ rEventConnStatus.u2ATIMWindow = 0; -+ } else if (prAisBssInfo->eCurrentOPMode == OP_MODE_IBSS) { -+ rEventConnStatus.ucInfraMode = (UINT_8) NET_TYPE_IBSS; -+ rEventConnStatus.u2AID = 0; -+ rEventConnStatus.u2ATIMWindow = prAisBssInfo->u2ATIMWindow; -+ } else { -+ ASSERT(0); -+ } -+ -+ COPY_SSID(rEventConnStatus.aucSsid, -+ rEventConnStatus.ucSsidLen, prConnSettings->aucSSID, prConnSettings->ucSSIDLen); -+ -+ COPY_MAC_ADDR(rEventConnStatus.aucBssid, prAisBssInfo->aucBSSID); -+ -+ rEventConnStatus.u2BeaconPeriod = prAisBssInfo->u2BeaconInterval; -+ rEventConnStatus.u4FreqInKHz = nicChannelNum2Freq(prAisBssInfo->ucPrimaryChannel); -+ -+ switch (prAisBssInfo->ucNonHTBasicPhyType) { -+ case PHY_TYPE_HR_DSSS_INDEX: -+ rEventConnStatus.ucNetworkType = (UINT_8) PARAM_NETWORK_TYPE_DS; -+ break; -+ -+ case PHY_TYPE_ERP_INDEX: -+ rEventConnStatus.ucNetworkType = (UINT_8) PARAM_NETWORK_TYPE_OFDM24; -+ break; -+ -+ case PHY_TYPE_OFDM_INDEX: -+ rEventConnStatus.ucNetworkType = (UINT_8) PARAM_NETWORK_TYPE_OFDM5; -+ break; -+ -+ default: -+ ASSERT(0); -+ rEventConnStatus.ucNetworkType = (UINT_8) PARAM_NETWORK_TYPE_DS; -+ break; -+ } -+ } else { -+ /* Deactivate previous Peers' STA_RECORD_T in Driver if have. */ -+ bssClearClientList(prAdapter, prAisBssInfo); -+ -+#if CFG_PRIVACY_MIGRATION -+ /* Clear the pmkid cache while media disconnect */ -+ secClearPmkid(prAdapter); -+#endif -+ -+ rEventConnStatus.ucReasonOfDisconnect = prAisBssInfo->ucReasonOfDisconnect; -+ } -+ -+ /* 4 <2> Indication */ -+ nicMediaStateChange(prAdapter, NETWORK_TYPE_AIS_INDEX, &rEventConnStatus); -+ prAisBssInfo->eConnectionStateIndicated = eConnectionState; -+ } else { -+ /* NOTE: Only delay the Indication of Disconnect Event */ -+ ASSERT(eConnectionState == PARAM_MEDIA_STATE_DISCONNECTED); -+ -+ DBGLOG(AIS, INFO, "Postpone the indication of Disconnect for %d seconds\n", -+ prConnSettings->ucDelayTimeOfDisconnectEvent); -+ -+ cnmTimerStartTimer(prAdapter, -+ &prAisFsmInfo->rIndicationOfDisconnectTimer, -+ SEC_TO_MSEC(prConnSettings->ucDelayTimeOfDisconnectEvent)); -+ } -+ -+} /* end of aisIndicationOfMediaStateToHost() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will indicate an Event of "Media Disconnect" to HOST -+* -+* @param[in] u4Param Unused timer parameter -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID aisPostponedEventOfDisconnTimeout(IN P_ADAPTER_T prAdapter, ULONG ulParam) -+{ -+ P_BSS_INFO_T prAisBssInfo; -+ P_CONNECTION_SETTINGS_T prConnSettings; -+ -+ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); -+ -+ /* 4 <1> Deactivate previous AP's STA_RECORD_T in Driver if have. */ -+ if (prAisBssInfo->prStaRecOfAP) { -+ /* cnmStaRecChangeState(prAdapter, prAisBssInfo->prStaRecOfAP, STA_STATE_1); */ -+ -+ prAisBssInfo->prStaRecOfAP = (P_STA_RECORD_T) NULL; -+ } -+ /* 4 <2> Remove pending connection request */ -+ aisFsmIsRequestPending(prAdapter, AIS_REQUEST_RECONNECT, TRUE); -+ prConnSettings->fgIsDisconnectedByNonRequest = TRUE; -+ prAisBssInfo->u2DeauthReason = REASON_CODE_BEACON_TIMEOUT; -+ /* 4 <3> Indicate Disconnected Event to Host immediately. */ -+ aisIndicationOfMediaStateToHost(prAdapter, PARAM_MEDIA_STATE_DISCONNECTED, FALSE); -+ -+} /* end of aisPostponedEventOfDisconnTimeout() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will update the contain of BSS_INFO_T for AIS network once -+* the association was completed. -+* -+* @param[in] prStaRec Pointer to the STA_RECORD_T -+* @param[in] prAssocRspSwRfb Pointer to SW RFB of ASSOC RESP FRAME. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID aisUpdateBssInfoForJOIN(IN P_ADAPTER_T prAdapter, P_STA_RECORD_T prStaRec, P_SW_RFB_T prAssocRspSwRfb) -+{ -+ P_AIS_FSM_INFO_T prAisFsmInfo; -+ P_BSS_INFO_T prAisBssInfo; -+ P_CONNECTION_SETTINGS_T prConnSettings; -+ P_WLAN_ASSOC_RSP_FRAME_T prAssocRspFrame; -+ P_BSS_DESC_T prBssDesc; -+ UINT_16 u2IELength; -+ PUINT_8 pucIE; -+ -+ DEBUGFUNC("aisUpdateBssInfoForJOIN()"); -+ -+ ASSERT(prStaRec); -+ ASSERT(prAssocRspSwRfb); -+ -+ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); -+ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); -+ prAssocRspFrame = (P_WLAN_ASSOC_RSP_FRAME_T) prAssocRspSwRfb->pvHeader; -+ -+ DBGLOG(AIS, TRACE, "Update AIS_BSS_INFO_T and apply settings to MAC\n"); -+ -+ /* 3 <1> Update BSS_INFO_T from AIS_FSM_INFO_T or User Settings */ -+ /* 4 <1.1> Setup Operation Mode */ -+ prAisBssInfo->eCurrentOPMode = OP_MODE_INFRASTRUCTURE; -+ -+ /* 4 <1.2> Setup SSID */ -+ COPY_SSID(prAisBssInfo->aucSSID, prAisBssInfo->ucSSIDLen, prConnSettings->aucSSID, prConnSettings->ucSSIDLen); -+ -+ /* 4 <1.3> Setup Channel, Band */ -+ prAisBssInfo->ucPrimaryChannel = prAisFsmInfo->prTargetBssDesc->ucChannelNum; -+ prAisBssInfo->eBand = prAisFsmInfo->prTargetBssDesc->eBand; -+ -+ /* 3 <2> Update BSS_INFO_T from STA_RECORD_T */ -+ /* 4 <2.1> Save current AP's STA_RECORD_T and current AID */ -+ prAisBssInfo->prStaRecOfAP = prStaRec; -+ prAisBssInfo->u2AssocId = prStaRec->u2AssocId; -+ -+ /* 4 <2.2> Setup Capability */ -+ prAisBssInfo->u2CapInfo = prStaRec->u2CapInfo; /* Use AP's Cap Info as BSS Cap Info */ -+ -+ if (prAisBssInfo->u2CapInfo & CAP_INFO_SHORT_PREAMBLE) -+ prAisBssInfo->fgIsShortPreambleAllowed = TRUE; -+ else -+ prAisBssInfo->fgIsShortPreambleAllowed = FALSE; -+ -+#if (CFG_SUPPORT_TDLS == 1) -+ /* init the TDLS flags */ -+ prAisBssInfo->fgTdlsIsProhibited = prStaRec->fgTdlsIsProhibited; -+ prAisBssInfo->fgTdlsIsChSwProhibited = prStaRec->fgTdlsIsChSwProhibited; -+#endif /* CFG_SUPPORT_TDLS */ -+ -+ /* 4 <2.3> Setup PHY Attributes and Basic Rate Set/Operational Rate Set */ -+ prAisBssInfo->ucPhyTypeSet = prStaRec->ucDesiredPhyTypeSet; -+ -+ prAisBssInfo->ucNonHTBasicPhyType = prStaRec->ucNonHTBasicPhyType; -+ -+ prAisBssInfo->u2OperationalRateSet = prStaRec->u2OperationalRateSet; -+ prAisBssInfo->u2BSSBasicRateSet = prStaRec->u2BSSBasicRateSet; -+ -+ /* 3 <3> Update BSS_INFO_T from SW_RFB_T (Association Resp Frame) */ -+ /* 4 <3.1> Setup BSSID */ -+ COPY_MAC_ADDR(prAisBssInfo->aucBSSID, prAssocRspFrame->aucBSSID); -+ -+ u2IELength = (UINT_16) ((prAssocRspSwRfb->u2PacketLen - prAssocRspSwRfb->u2HeaderLen) - -+ (OFFSET_OF(WLAN_ASSOC_RSP_FRAME_T, aucInfoElem[0]) - WLAN_MAC_MGMT_HEADER_LEN)); -+ pucIE = prAssocRspFrame->aucInfoElem; -+ -+ /* 4 <3.2> Parse WMM and setup QBSS flag */ -+ /* Parse WMM related IEs and configure HW CRs accordingly */ -+ mqmProcessAssocRsp(prAdapter, prAssocRspSwRfb, pucIE, u2IELength); -+ -+ prAisBssInfo->fgIsQBSS = prStaRec->fgIsQoS; -+ -+ /* 3 <4> Update BSS_INFO_T from BSS_DESC_T */ -+ prBssDesc = scanSearchBssDescByBssid(prAdapter, prAssocRspFrame->aucBSSID); -+ if (prBssDesc) { -+ prBssDesc->fgIsConnecting = FALSE; -+ prBssDesc->fgIsConnected = TRUE; -+ prBssDesc->ucJoinFailureCount = 0; -+ -+ /* 4 <4.1> Setup MIB for current BSS */ -+ prAisBssInfo->u2BeaconInterval = prBssDesc->u2BeaconInterval; -+ } else { -+ /* should never happen */ -+ ASSERT(0); -+ } -+ -+ /* NOTE: Defer ucDTIMPeriod updating to when beacon is received after connection */ -+ prAisBssInfo->ucDTIMPeriod = 0; -+ prAisBssInfo->u2ATIMWindow = 0; -+ -+ prAisBssInfo->ucBeaconTimeoutCount = AIS_BEACON_TIMEOUT_COUNT_INFRA; -+ -+ /* 4 <4.2> Update HT information and set channel */ -+ /* Record HT related parameters in rStaRec and rBssInfo -+ * Note: it shall be called before nicUpdateBss() -+ */ -+ rlmProcessAssocRsp(prAdapter, prAssocRspSwRfb, pucIE, u2IELength); -+ -+ /* 4 <4.3> Sync with firmware for BSS-INFO */ -+ nicUpdateBss(prAdapter, NETWORK_TYPE_AIS_INDEX); -+ -+ /* 4 <4.4> *DEFER OPERATION* nicPmIndicateBssConnected() will be invoked */ -+ /* inside scanProcessBeaconAndProbeResp() after 1st beacon is received */ -+ -+} /* end of aisUpdateBssInfoForJOIN() */ -+ -+#if CFG_SUPPORT_ADHOC -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will create an Ad-Hoc network and start sending Beacon Frames. -+* -+* @param (none) -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID aisUpdateBssInfoForCreateIBSS(IN P_ADAPTER_T prAdapter) -+{ -+ P_AIS_FSM_INFO_T prAisFsmInfo; -+ P_BSS_INFO_T prAisBssInfo; -+ P_CONNECTION_SETTINGS_T prConnSettings; -+ -+ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); -+ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); -+ -+ if (prAisBssInfo->fgIsBeaconActivated) -+ return; -+ /* 3 <1> Update BSS_INFO_T per Network Basis */ -+ /* 4 <1.1> Setup Operation Mode */ -+ prAisBssInfo->eCurrentOPMode = OP_MODE_IBSS; -+ -+ /* 4 <1.2> Setup SSID */ -+ COPY_SSID(prAisBssInfo->aucSSID, prAisBssInfo->ucSSIDLen, prConnSettings->aucSSID, prConnSettings->ucSSIDLen); -+ -+ /* 4 <1.3> Clear current AP's STA_RECORD_T and current AID */ -+ prAisBssInfo->prStaRecOfAP = (P_STA_RECORD_T) NULL; -+ prAisBssInfo->u2AssocId = 0; -+ -+ /* 4 <1.4> Setup Channel, Band and Phy Attributes */ -+ prAisBssInfo->ucPrimaryChannel = prConnSettings->ucAdHocChannelNum; -+ prAisBssInfo->eBand = prConnSettings->eAdHocBand; -+ -+ if (prAisBssInfo->eBand == BAND_2G4) { -+ /* Depend on eBand */ -+ prAisBssInfo->ucPhyTypeSet = prAdapter->rWifiVar.ucAvailablePhyTypeSet & PHY_TYPE_SET_802_11BGN; -+ /* Depend on eCurrentOPMode and ucPhyTypeSet */ -+ prAisBssInfo->ucConfigAdHocAPMode = AD_HOC_MODE_MIXED_11BG; -+ } else { -+ /* Depend on eBand */ -+ prAisBssInfo->ucPhyTypeSet = prAdapter->rWifiVar.ucAvailablePhyTypeSet & PHY_TYPE_SET_802_11AN; -+ /* Depend on eCurrentOPMode and ucPhyTypeSet */ -+ prAisBssInfo->ucConfigAdHocAPMode = AD_HOC_MODE_11A; -+ } -+ -+ /* 4 <1.5> Setup MIB for current BSS */ -+ prAisBssInfo->u2BeaconInterval = prConnSettings->u2BeaconPeriod; -+ prAisBssInfo->ucDTIMPeriod = 0; -+ prAisBssInfo->u2ATIMWindow = prConnSettings->u2AtimWindow; -+ -+ prAisBssInfo->ucBeaconTimeoutCount = AIS_BEACON_TIMEOUT_COUNT_ADHOC; -+ -+#if CFG_PRIVACY_MIGRATION -+ if (prConnSettings->eEncStatus == ENUM_ENCRYPTION1_ENABLED || -+ prConnSettings->eEncStatus == ENUM_ENCRYPTION2_ENABLED || -+ prConnSettings->eEncStatus == ENUM_ENCRYPTION3_ENABLED) { -+ prAisBssInfo->fgIsProtection = TRUE; -+ } else { -+ prAisBssInfo->fgIsProtection = FALSE; -+ } -+#else -+ prAisBssInfo->fgIsProtection = FALSE; -+#endif -+ -+ /* 3 <2> Update BSS_INFO_T common part */ -+ ibssInitForAdHoc(prAdapter, prAisBssInfo); -+ -+ /* 3 <3> Set MAC HW */ -+ /* 4 <3.1> Setup channel and bandwidth */ -+ rlmBssInitForAPandIbss(prAdapter, prAisBssInfo); -+ -+ /* 4 <3.2> use command packets to inform firmware */ -+ nicUpdateBss(prAdapter, NETWORK_TYPE_AIS_INDEX); -+ -+ /* 4 <3.3> enable beaconing */ -+ bssUpdateBeaconContent(prAdapter, NETWORK_TYPE_AIS_INDEX); -+ -+ /* 4 <3.4> Update AdHoc PM parameter */ -+ nicPmIndicateBssCreated(prAdapter, NETWORK_TYPE_AIS_INDEX); -+ -+ /* 3 <4> Set ACTIVE flag. */ -+ prAisBssInfo->fgIsBeaconActivated = TRUE; -+ prAisBssInfo->fgHoldSameBssidForIBSS = TRUE; -+ -+ /* 3 <5> Start IBSS Alone Timer */ -+ cnmTimerStartTimer(prAdapter, &prAisFsmInfo->rIbssAloneTimer, SEC_TO_MSEC(AIS_IBSS_ALONE_TIMEOUT_SEC)); -+ -+ return; -+ -+} /* end of aisCreateIBSS() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will update the contain of BSS_INFO_T for AIS network once -+* the existing IBSS was found. -+* -+* @param[in] prStaRec Pointer to the STA_RECORD_T -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID aisUpdateBssInfoForMergeIBSS(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec) -+{ -+ P_AIS_FSM_INFO_T prAisFsmInfo; -+ P_BSS_INFO_T prAisBssInfo; -+ P_CONNECTION_SETTINGS_T prConnSettings; -+ P_BSS_DESC_T prBssDesc; -+ /* UINT_16 u2IELength; */ -+ /* PUINT_8 pucIE; */ -+ -+ ASSERT(prStaRec); -+ -+ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); -+ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); -+ -+ cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rIbssAloneTimer); -+ -+ if (!prAisBssInfo->fgIsBeaconActivated) { -+ -+ /* 3 <1> Update BSS_INFO_T per Network Basis */ -+ /* 4 <1.1> Setup Operation Mode */ -+ prAisBssInfo->eCurrentOPMode = OP_MODE_IBSS; -+ -+ /* 4 <1.2> Setup SSID */ -+ COPY_SSID(prAisBssInfo->aucSSID, -+ prAisBssInfo->ucSSIDLen, prConnSettings->aucSSID, prConnSettings->ucSSIDLen); -+ -+ /* 4 <1.3> Clear current AP's STA_RECORD_T and current AID */ -+ prAisBssInfo->prStaRecOfAP = (P_STA_RECORD_T) NULL; -+ prAisBssInfo->u2AssocId = 0; -+ } -+ /* 3 <2> Update BSS_INFO_T from STA_RECORD_T */ -+ /* 4 <2.1> Setup Capability */ -+ prAisBssInfo->u2CapInfo = prStaRec->u2CapInfo; /* Use Peer's Cap Info as IBSS Cap Info */ -+ -+ if (prAisBssInfo->u2CapInfo & CAP_INFO_SHORT_PREAMBLE) { -+ prAisBssInfo->fgIsShortPreambleAllowed = TRUE; -+ prAisBssInfo->fgUseShortPreamble = TRUE; -+ } else { -+ prAisBssInfo->fgIsShortPreambleAllowed = FALSE; -+ prAisBssInfo->fgUseShortPreamble = FALSE; -+ } -+ -+ /* 7.3.1.4 For IBSS, the Short Slot Time subfield shall be set to 0. */ -+ prAisBssInfo->fgUseShortSlotTime = FALSE; /* Set to FALSE for AdHoc */ -+ prAisBssInfo->u2CapInfo &= ~CAP_INFO_SHORT_SLOT_TIME; -+ -+ if (prAisBssInfo->u2CapInfo & CAP_INFO_PRIVACY) -+ prAisBssInfo->fgIsProtection = TRUE; -+ else -+ prAisBssInfo->fgIsProtection = FALSE; -+ -+ /* 4 <2.2> Setup PHY Attributes and Basic Rate Set/Operational Rate Set */ -+ prAisBssInfo->ucPhyTypeSet = prStaRec->ucDesiredPhyTypeSet; -+ -+ prAisBssInfo->ucNonHTBasicPhyType = prStaRec->ucNonHTBasicPhyType; -+ -+ prAisBssInfo->u2OperationalRateSet = prStaRec->u2OperationalRateSet; -+ prAisBssInfo->u2BSSBasicRateSet = prStaRec->u2BSSBasicRateSet; -+ -+ rateGetDataRatesFromRateSet(prAisBssInfo->u2OperationalRateSet, -+ prAisBssInfo->u2BSSBasicRateSet, -+ prAisBssInfo->aucAllSupportedRates, &prAisBssInfo->ucAllSupportedRatesLen); -+ -+ /* 3 <3> X Update BSS_INFO_T from SW_RFB_T (Association Resp Frame) */ -+ -+ /* 3 <4> Update BSS_INFO_T from BSS_DESC_T */ -+ prBssDesc = scanSearchBssDescByTA(prAdapter, prStaRec->aucMacAddr); -+ if (prBssDesc) { -+ prBssDesc->fgIsConnecting = FALSE; -+ prBssDesc->fgIsConnected = TRUE; -+ -+ /* 4 <4.1> Setup BSSID */ -+ COPY_MAC_ADDR(prAisBssInfo->aucBSSID, prBssDesc->aucBSSID); -+ -+ /* 4 <4.2> Setup Channel, Band */ -+ prAisBssInfo->ucPrimaryChannel = prBssDesc->ucChannelNum; -+ prAisBssInfo->eBand = prBssDesc->eBand; -+ -+ /* 4 <4.3> Setup MIB for current BSS */ -+ prAisBssInfo->u2BeaconInterval = prBssDesc->u2BeaconInterval; -+ prAisBssInfo->ucDTIMPeriod = 0; -+ prAisBssInfo->u2ATIMWindow = 0; /* TBD(Kevin) */ -+ -+ prAisBssInfo->ucBeaconTimeoutCount = AIS_BEACON_TIMEOUT_COUNT_ADHOC; -+ } else { -+ /* should never happen */ -+ ASSERT(0); -+ } -+ -+ /* 3 <5> Set MAC HW */ -+ /* 4 <5.1> Find Lowest Basic Rate Index for default TX Rate of MMPDU */ -+ { -+ UINT_8 ucLowestBasicRateIndex; -+ -+ if (!rateGetLowestRateIndexFromRateSet(prAisBssInfo->u2BSSBasicRateSet, &ucLowestBasicRateIndex)) { -+ -+ if (prAisBssInfo->ucPhyTypeSet & PHY_TYPE_BIT_OFDM) -+ ucLowestBasicRateIndex = RATE_6M_INDEX; -+ else -+ ucLowestBasicRateIndex = RATE_1M_INDEX; -+ } -+ -+ prAisBssInfo->ucHwDefaultFixedRateCode = -+ aucRateIndex2RateCode[prAisBssInfo->fgUseShortPreamble][ucLowestBasicRateIndex]; -+ } -+ -+ /* 4 <5.2> Setup channel and bandwidth */ -+ rlmBssInitForAPandIbss(prAdapter, prAisBssInfo); -+ -+ /* 4 <5.3> use command packets to inform firmware */ -+ nicUpdateBss(prAdapter, NETWORK_TYPE_AIS_INDEX); -+ -+ /* 4 <5.4> enable beaconing */ -+ bssUpdateBeaconContent(prAdapter, NETWORK_TYPE_AIS_INDEX); -+ -+ /* 4 <5.5> Update AdHoc PM parameter */ -+ nicPmIndicateBssConnected(prAdapter, NETWORK_TYPE_AIS_INDEX); -+ -+ /* 3 <6> Set ACTIVE flag. */ -+ prAisBssInfo->fgIsBeaconActivated = TRUE; -+ prAisBssInfo->fgHoldSameBssidForIBSS = TRUE; -+ -+} /* end of aisUpdateBssInfoForMergeIBSS() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will validate the Rx Probe Request Frame and then return -+* result to BSS to indicate if need to send the corresponding Probe Response -+* Frame if the specified conditions were matched. -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* @param[in] prSwRfb Pointer to SW RFB data structure. -+* @param[out] pu4ControlFlags Control flags for replying the Probe Response -+* -+* @retval TRUE Reply the Probe Response -+* @retval FALSE Don't reply the Probe Response -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN aisValidateProbeReq(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, OUT PUINT_32 pu4ControlFlags) -+{ -+ P_WLAN_MAC_MGMT_HEADER_T prMgtHdr; -+ P_BSS_INFO_T prBssInfo; -+ P_IE_SSID_T prIeSsid = (P_IE_SSID_T) NULL; -+ PUINT_8 pucIE; -+ UINT_16 u2IELength; -+ UINT_16 u2Offset = 0; -+ BOOLEAN fgReplyProbeResp = FALSE; -+ -+ ASSERT(prSwRfb); -+ ASSERT(pu4ControlFlags); -+ -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ -+ /* 4 <1> Parse Probe Req IE and Get IE ptr (SSID, Supported Rate IE, ...) */ -+ prMgtHdr = (P_WLAN_MAC_MGMT_HEADER_T) prSwRfb->pvHeader; -+ -+ u2IELength = prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen; -+ pucIE = (PUINT_8) prSwRfb->pvHeader + prSwRfb->u2HeaderLen; -+ -+ IE_FOR_EACH(pucIE, u2IELength, u2Offset) { -+ if (ELEM_ID_SSID == IE_ID(pucIE)) { -+ if ((!prIeSsid) && (IE_LEN(pucIE) <= ELEM_MAX_LEN_SSID)) -+ prIeSsid = (P_IE_SSID_T) pucIE; -+ break; -+ } -+ } /* end of IE_FOR_EACH */ -+ -+ /* 4 <2> Check network conditions */ -+ -+ if (prBssInfo->eCurrentOPMode == OP_MODE_IBSS) { -+ -+ if ((prIeSsid) && ((prIeSsid->ucLength == BC_SSID_LEN) || /* WILDCARD SSID */ -+ EQUAL_SSID(prBssInfo->aucSSID, prBssInfo->ucSSIDLen, /* CURRENT SSID */ -+ prIeSsid->aucSSID, prIeSsid->ucLength))) { -+ fgReplyProbeResp = TRUE; -+ } -+ } -+ -+ return fgReplyProbeResp; -+ -+} /* end of aisValidateProbeReq() */ -+ -+#endif /* CFG_SUPPORT_ADHOC */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will modify and update necessary information to firmware -+* for disconnection handling -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* -+* @retval None -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID aisFsmDisconnect(IN P_ADAPTER_T prAdapter, IN BOOLEAN fgDelayIndication) -+{ -+ P_BSS_INFO_T prAisBssInfo; -+ -+ ASSERT(prAdapter); -+ -+ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ -+ nicPmIndicateBssAbort(prAdapter, NETWORK_TYPE_AIS_INDEX); -+ -+#if CFG_SUPPORT_ADHOC -+ if (prAisBssInfo->fgIsBeaconActivated) { -+ nicUpdateBeaconIETemplate(prAdapter, IE_UPD_METHOD_DELETE_ALL, NETWORK_TYPE_AIS_INDEX, 0, NULL, 0); -+ -+ prAisBssInfo->fgIsBeaconActivated = FALSE; -+ } -+#endif -+ -+ rlmBssAborted(prAdapter, prAisBssInfo); -+ -+ /* 4 <3> Unset the fgIsConnected flag of BSS_DESC_T and send Deauth if needed. */ -+ if (PARAM_MEDIA_STATE_CONNECTED == prAisBssInfo->eConnectionState) { -+ /* add for ctia mode */ -+ { -+ UINT_8 aucP2pSsid[] = CTIA_MAGIC_SSID; -+ -+ if (EQUAL_SSID(aucP2pSsid, CTIA_MAGIC_SSID_LEN, prAisBssInfo->aucSSID, prAisBssInfo->ucSSIDLen)) -+ nicEnterCtiaMode(prAdapter, FALSE, FALSE); -+ } -+ -+ if (prAisBssInfo->ucReasonOfDisconnect == DISCONNECT_REASON_CODE_RADIO_LOST) { -+ scanRemoveBssDescByBssid(prAdapter, prAisBssInfo->aucBSSID); -+ -+ /* remove from scanning results as well */ -+ wlanClearBssInScanningResult(prAdapter, prAisBssInfo->aucBSSID); -+ -+ /* trials for re-association */ -+ if (fgDelayIndication) { -+ DBGLOG(AIS, INFO, "try to do re-association due to radio lost!\n"); -+ aisFsmIsRequestPending(prAdapter, AIS_REQUEST_RECONNECT, TRUE); -+ aisFsmInsertRequest(prAdapter, AIS_REQUEST_RECONNECT); -+ } -+ } else { -+ scanRemoveConnFlagOfBssDescByBssid(prAdapter, prAisBssInfo->aucBSSID); -+ } -+ -+ if (fgDelayIndication) { -+ if (OP_MODE_IBSS != prAisBssInfo->eCurrentOPMode) -+ prAisBssInfo->fgHoldSameBssidForIBSS = FALSE; -+ } else { -+ prAisBssInfo->fgHoldSameBssidForIBSS = FALSE; -+ } -+ } else { -+ prAisBssInfo->fgHoldSameBssidForIBSS = FALSE; -+ } -+ -+ /* 4 <4> Change Media State immediately. */ -+ if (prAisBssInfo->ucReasonOfDisconnect != DISCONNECT_REASON_CODE_REASSOCIATION) { -+ aisChangeMediaState(prAdapter, PARAM_MEDIA_STATE_DISCONNECTED); -+ -+ /* 4 <4.1> sync. with firmware */ -+ nicUpdateBss(prAdapter, NETWORK_TYPE_AIS_INDEX); -+ } -+ -+ if (!fgDelayIndication) { -+ /* 4 <5> Deactivate previous AP's STA_RECORD_T or all Clients in Driver if have. */ -+ if (prAisBssInfo->prStaRecOfAP) { -+ /* cnmStaRecChangeState(prAdapter, prAisBssInfo->prStaRecOfAP, STA_STATE_1); */ -+ -+ prAisBssInfo->prStaRecOfAP = (P_STA_RECORD_T) NULL; -+ } -+ } -+#if CFG_SUPPORT_ROAMING -+ roamingFsmRunEventAbort(prAdapter); -+ -+ /* clear pending roaming connection request */ -+ aisFsmIsRequestPending(prAdapter, AIS_REQUEST_ROAMING_SEARCH, TRUE); -+ aisFsmIsRequestPending(prAdapter, AIS_REQUEST_ROAMING_CONNECT, TRUE); -+#endif /* CFG_SUPPORT_ROAMING */ -+ -+ /* 4 <6> Indicate Disconnected Event to Host */ -+ aisIndicationOfMediaStateToHost(prAdapter, PARAM_MEDIA_STATE_DISCONNECTED, fgDelayIndication); -+ -+ /* 4 <7> Trigger AIS FSM */ -+ aisFsmSteps(prAdapter, AIS_STATE_IDLE); -+ -+} /* end of aisFsmDisconnect() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will indicate an Event of Scan done Time-Out to AIS FSM. -+* -+* @param[in] u4Param Unused timer parameter -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT_32 IsrCnt = 0, IsrPassCnt = 0, TaskIsrCnt = 0; -+VOID aisFsmRunEventScanDoneTimeOut(IN P_ADAPTER_T prAdapter, ULONG ulParam) -+{ -+#define SCAN_DONE_TIMEOUT_TIMES_LIMIT 20 -+ -+ P_AIS_FSM_INFO_T prAisFsmInfo; -+ ENUM_AIS_STATE_T eNextState; -+ P_CONNECTION_SETTINGS_T prConnSettings; -+ GL_HIF_INFO_T *HifInfo; -+ UINT_32 u4FwCnt; -+ P_GLUE_INFO_T prGlueInfo; -+ -+ DEBUGFUNC("aisFsmRunEventScanDoneTimeOut()"); -+ -+ prGlueInfo = prAdapter->prGlueInfo; -+ -+ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); -+ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); -+ HifInfo = &prAdapter->prGlueInfo->rHifInfo; -+ -+ DBGLOG(AIS, WARN, "aisFsmRunEventScanDoneTimeOut Current[%d], ucScanTimeoutTimes=%d\n", -+ prAisFsmInfo->eCurrentState, ucScanTimeoutTimes); -+ DBGLOG(AIS, WARN, "Isr/task %u %u %u (0x%x)\n", prGlueInfo->IsrCnt, prGlueInfo->IsrPassCnt, -+ prGlueInfo->TaskIsrCnt, prAdapter->fgIsIntEnable); -+ -+ /* dump firmware program counter */ -+ DBGLOG(AIS, WARN, "CONNSYS FW CPUINFO:\n"); -+ for (u4FwCnt = 0; u4FwCnt < 16; u4FwCnt++) -+ DBGLOG(AIS, WARN, "0x%08x ", MCU_REG_READL(HifInfo, CONN_MCU_CPUPCR)); -+ -+ ucScanTimeoutTimes++; -+ if (ucScanTimeoutTimes > SCAN_DONE_TIMEOUT_TIMES_LIMIT) { -+ kalSendAeeWarning("[Scan done timeout more than 20 times!]", __func__); -+ glDoChipReset(); -+ } -+#if 0 /* ALPS02018734: remove trigger assert */ -+ if (prAdapter->fgTestMode == FALSE) { -+ /* Titus - xxx */ -+ /* assert if and only if in normal mode */ -+ mtk_wcn_wmt_assert(WMTDRV_TYPE_WIFI, 40); -+ } -+#endif -+ /* report all scanned frames to upper layer to avoid scanned frame is timeout */ -+ /* must be put before kalScanDone */ -+/* scanReportBss2Cfg80211(prAdapter,BSS_TYPE_INFRASTRUCTURE,NULL); */ -+ -+ prConnSettings->fgIsScanReqIssued = FALSE; -+ kalScanDone(prAdapter->prGlueInfo, KAL_NETWORK_TYPE_AIS_INDEX, WLAN_STATUS_SUCCESS); -+ eNextState = prAisFsmInfo->eCurrentState; -+ -+ switch (prAisFsmInfo->eCurrentState) { -+ case AIS_STATE_SCAN: -+ prAisFsmInfo->u4ScanIELength = 0; -+ eNextState = AIS_STATE_IDLE; -+ break; -+ case AIS_STATE_ONLINE_SCAN: -+ /* reset scan IE buffer */ -+ prAisFsmInfo->u4ScanIELength = 0; -+#if CFG_SUPPORT_ROAMING -+ eNextState = aisFsmRoamingScanResultsUpdate(prAdapter); -+#else -+ eNextState = AIS_STATE_NORMAL_TR; -+#endif /* CFG_SUPPORT_ROAMING */ -+ break; -+ default: -+ break; -+ } -+ -+ /* try to stop scan in CONNSYS */ -+ aisFsmStateAbort_SCAN(prAdapter); -+ -+ /* wlanQueryDebugCode(prAdapter); */ /* display current SCAN FSM in FW, debug use */ -+ -+ if (eNextState != prAisFsmInfo->eCurrentState) -+ aisFsmSteps(prAdapter, eNextState); -+ -+} /* end of aisFsmBGSleepTimeout() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will indicate an Event of "Background Scan Time-Out" to AIS FSM. -+* -+* @param[in] u4Param Unused timer parameter -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID aisFsmRunEventBGSleepTimeOut(IN P_ADAPTER_T prAdapter, ULONG ulParam) -+{ -+ P_AIS_FSM_INFO_T prAisFsmInfo; -+ ENUM_AIS_STATE_T eNextState; -+ -+ DEBUGFUNC("aisFsmRunEventBGSleepTimeOut()"); -+ -+ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); -+ -+ eNextState = prAisFsmInfo->eCurrentState; -+ -+ switch (prAisFsmInfo->eCurrentState) { -+ case AIS_STATE_WAIT_FOR_NEXT_SCAN: -+ DBGLOG(AIS, LOUD, "EVENT - SCAN TIMER: Idle End - Current Time = %u\n", kalGetTimeTick()); -+ -+ eNextState = AIS_STATE_LOOKING_FOR; -+ -+ SET_NET_PWR_STATE_ACTIVE(prAdapter, NETWORK_TYPE_AIS_INDEX); -+ -+ break; -+ -+ default: -+ break; -+ } -+ -+ /* Call aisFsmSteps() when we are going to change AIS STATE */ -+ if (eNextState != prAisFsmInfo->eCurrentState) -+ aisFsmSteps(prAdapter, eNextState); -+ -+} /* end of aisFsmBGSleepTimeout() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will indicate an Event of "IBSS ALONE Time-Out" to AIS FSM. -+* -+* @param[in] u4Param Unused timer parameter -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID aisFsmRunEventIbssAloneTimeOut(IN P_ADAPTER_T prAdapter, ULONG ulParam) -+{ -+ P_AIS_FSM_INFO_T prAisFsmInfo; -+ ENUM_AIS_STATE_T eNextState; -+ -+ DEBUGFUNC("aisFsmRunEventIbssAloneTimeOut()"); -+ -+ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); -+ eNextState = prAisFsmInfo->eCurrentState; -+ -+ switch (prAisFsmInfo->eCurrentState) { -+ case AIS_STATE_IBSS_ALONE: -+ -+ /* There is no one participate in our AdHoc during this TIMEOUT Interval -+ * so go back to search for a valid IBSS again. -+ */ -+ -+ DBGLOG(AIS, LOUD, "EVENT-IBSS ALONE TIMER: Start pairing\n"); -+ -+ prAisFsmInfo->fgTryScan = TRUE; -+ -+ /* abort timer */ -+ aisFsmReleaseCh(prAdapter); -+ -+ /* Pull back to SEARCH to find candidate again */ -+ eNextState = AIS_STATE_SEARCH; -+ -+ break; -+ -+ default: -+ break; -+ } -+ -+ /* Call aisFsmSteps() when we are going to change AIS STATE */ -+ if (eNextState != prAisFsmInfo->eCurrentState) -+ aisFsmSteps(prAdapter, eNextState); -+ -+} /* end of aisIbssAloneTimeOut() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will indicate an Event of "Join Time-Out" to AIS FSM. -+* -+* @param[in] u4Param Unused timer parameter -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID aisFsmRunEventJoinTimeout(IN P_ADAPTER_T prAdapter, ULONG ulParam) -+{ -+ P_BSS_INFO_T prAisBssInfo; -+ P_AIS_FSM_INFO_T prAisFsmInfo; -+ ENUM_AIS_STATE_T eNextState; -+ OS_SYSTIME rCurrentTime; -+ -+ DEBUGFUNC("aisFsmRunEventJoinTimeout()"); -+ prAisBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]; -+ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); -+ eNextState = prAisFsmInfo->eCurrentState; -+ -+ GET_CURRENT_SYSTIME(&rCurrentTime); -+ switch (prAisFsmInfo->eCurrentState) { -+ case AIS_STATE_JOIN: -+ DBGLOG(AIS, LOUD, "EVENT- JOIN TIMEOUT\n"); -+ -+ /* 1. Do abort JOIN */ -+ aisFsmStateAbort_JOIN(prAdapter); -+ -+ /* 2. Increase Join Failure Count */ -+ prAisFsmInfo->prTargetBssDesc->ucJoinFailureCount++; -+/* For JB nl802.11 */ -+ if (prAisFsmInfo->prTargetBssDesc->ucJoinFailureCount < JOIN_MAX_RETRY_FAILURE_COUNT) { -+ /* 3.1 Retreat to AIS_STATE_SEARCH state for next try */ -+ eNextState = AIS_STATE_SEARCH; -+ } else if (prAisBssInfo->eConnectionState == PARAM_MEDIA_STATE_CONNECTED) { -+ /* 3.2 Retreat to AIS_STATE_WAIT_FOR_NEXT_SCAN state for next try */ -+ eNextState = AIS_STATE_WAIT_FOR_NEXT_SCAN; -+ } else if (!CHECK_FOR_TIMEOUT(rCurrentTime, prAisFsmInfo->rJoinReqTime, -+ SEC_TO_SYSTIME(AIS_JOIN_TIMEOUT))) { -+ /* 3.3 Retreat to AIS_STATE_WAIT_FOR_NEXT_SCAN state for next try */ -+ eNextState = AIS_STATE_WAIT_FOR_NEXT_SCAN; -+ } else { -+ /* 3.4 Retreat to AIS_STATE_JOIN_FAILURE to terminate join operation */ -+ kalIndicateStatusAndComplete(prAdapter->prGlueInfo, WLAN_STATUS_CONNECT_INDICATION, NULL, 0); -+ eNextState = AIS_STATE_IDLE; -+ } -+ break; -+ -+ case AIS_STATE_NORMAL_TR: -+ /* 1. release channel */ -+ aisFsmReleaseCh(prAdapter); -+ prAisFsmInfo->fgIsInfraChannelFinished = TRUE; -+ -+ /* 2. process if there is pending scan */ -+ if (aisFsmIsRequestPending(prAdapter, AIS_REQUEST_SCAN, TRUE) == TRUE) { -+ wlanClearScanningResult(prAdapter); -+ eNextState = AIS_STATE_ONLINE_SCAN; -+ } -+ -+ break; -+ -+ default: -+ /* release channel */ -+ aisFsmReleaseCh(prAdapter); -+ break; -+ -+ } -+ -+ /* Call aisFsmSteps() when we are going to change AIS STATE */ -+ if (eNextState != prAisFsmInfo->eCurrentState) -+ aisFsmSteps(prAdapter, eNextState); -+ -+} /* end of aisFsmRunEventJoinTimeout() */ -+ -+VOID aisFsmRunEventDeauthTimeout(IN P_ADAPTER_T prAdapter, ULONG ulParam) -+{ -+ aisDeauthXmitComplete(prAdapter, NULL, TX_RESULT_LIFE_TIMEOUT); -+} -+ -+#if defined(CFG_TEST_MGMT_FSM) && (CFG_TEST_MGMT_FSM != 0) -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID aisTest(VOID) -+{ -+ P_MSG_AIS_ABORT_T prAisAbortMsg; -+ P_CONNECTION_SETTINGS_T prConnSettings; -+ UINT_8 aucSSID[] = "pci-11n"; -+ UINT_8 ucSSIDLen = 7; -+ -+ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); -+ -+ /* Set Connection Request Issued Flag */ -+ prConnSettings->fgIsConnReqIssued = TRUE; -+ prConnSettings->ucSSIDLen = ucSSIDLen; -+ kalMemCopy(prConnSettings->aucSSID, aucSSID, ucSSIDLen); -+ -+ prAisAbortMsg = (P_MSG_AIS_ABORT_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_AIS_ABORT_T)); -+ if (!prAisAbortMsg) { -+ -+ ASSERT(0); /* Can't trigger SCAN FSM */ -+ return; -+ } -+ -+ prAisAbortMsg->rMsgHdr.eMsgId = MID_HEM_AIS_FSM_ABORT; -+ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prAisAbortMsg, MSG_SEND_METHOD_BUF); -+ -+ wifi_send_msg(INDX_WIFI, MSG_ID_WIFI_IST, 0); -+ -+} -+#endif /* CFG_TEST_MGMT_FSM */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is used to handle OID_802_11_BSSID_LIST_SCAN -+* -+* \param[in] prAdapter Pointer of ADAPTER_T -+* \param[in] prSsid Pointer of SSID_T if specified -+* \param[in] pucIe Pointer to buffer of extra information elements to be attached -+* \param[in] u4IeLength Length of information elements -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID aisFsmScanRequest(IN P_ADAPTER_T prAdapter, IN P_PARAM_SSID_T prSsid, IN PUINT_8 pucIe, IN UINT_32 u4IeLength) -+{ -+ P_CONNECTION_SETTINGS_T prConnSettings; -+ P_BSS_INFO_T prAisBssInfo; -+ P_AIS_FSM_INFO_T prAisFsmInfo; -+ -+ DEBUGFUNC("aisFsmScanRequest()"); -+ -+ ASSERT(prAdapter); -+ ASSERT(u4IeLength <= MAX_IE_LENGTH); -+ -+ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); -+ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); -+ -+ if (!prConnSettings->fgIsScanReqIssued) { -+ prConnSettings->fgIsScanReqIssued = TRUE; -+ -+ if (prSsid == NULL) { -+ prAisFsmInfo->ucScanSSIDLen = 0; -+ } else { -+ COPY_SSID(prAisFsmInfo->aucScanSSID, -+ prAisFsmInfo->ucScanSSIDLen, prSsid->aucSsid, (UINT_8) prSsid->u4SsidLen); -+ } -+ -+ if (u4IeLength > 0 && u4IeLength <= MAX_IE_LENGTH) { -+ prAisFsmInfo->u4ScanIELength = u4IeLength; -+ kalMemCopy(prAisFsmInfo->aucScanIEBuf, pucIe, u4IeLength); -+ } else { -+ prAisFsmInfo->u4ScanIELength = 0; -+ } -+ -+ if (prAisFsmInfo->eCurrentState == AIS_STATE_NORMAL_TR) { -+ if (prAisBssInfo->eCurrentOPMode == OP_MODE_INFRASTRUCTURE -+ && prAisFsmInfo->fgIsInfraChannelFinished == FALSE) { -+ /* 802.1x might not finished yet, pend it for later handling .. */ -+ aisFsmInsertRequest(prAdapter, AIS_REQUEST_SCAN); -+ } else { -+ if (prAisFsmInfo->fgIsChannelGranted == TRUE) { -+ DBGLOG(AIS, WARN, -+ "Scan Request with channel granted for join operation: %d, %d", -+ prAisFsmInfo->fgIsChannelGranted, prAisFsmInfo->fgIsChannelRequested); -+ } -+ -+ /* start online scan */ -+ wlanClearScanningResult(prAdapter); -+ aisFsmSteps(prAdapter, AIS_STATE_ONLINE_SCAN); -+ } -+ } else if (prAisFsmInfo->eCurrentState == AIS_STATE_IDLE) { -+ wlanClearScanningResult(prAdapter); -+ aisFsmSteps(prAdapter, AIS_STATE_SCAN); -+ } else { -+ aisFsmInsertRequest(prAdapter, AIS_REQUEST_SCAN); -+ } -+ } else { -+ DBGLOG(AIS, WARN, "Scan Request dropped. (state: %d)\n", prAisFsmInfo->eCurrentState); -+ } -+ -+} /* end of aisFsmScanRequest() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is invoked when CNM granted channel privilege -+* -+* \param[in] prAdapter Pointer of ADAPTER_T -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID aisFsmRunEventChGrant(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) -+{ -+ P_BSS_INFO_T prAisBssInfo; -+ P_AIS_FSM_INFO_T prAisFsmInfo; -+ P_MSG_CH_GRANT_T prMsgChGrant; -+ UINT_8 ucTokenID; -+ UINT_32 u4GrantInterval; -+ -+ ASSERT(prAdapter); -+ ASSERT(prMsgHdr); -+ -+ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); -+ prMsgChGrant = (P_MSG_CH_GRANT_T) prMsgHdr; -+ -+ ucTokenID = prMsgChGrant->ucTokenID; -+ u4GrantInterval = prMsgChGrant->u4GrantInterval; -+ -+ /* 1. free message */ -+ cnmMemFree(prAdapter, prMsgHdr); -+ -+ if (prAisFsmInfo->eCurrentState == AIS_STATE_REQ_CHANNEL_JOIN && prAisFsmInfo->ucSeqNumOfChReq == ucTokenID) { -+ /* 2. channel privilege has been approved */ -+ prAisFsmInfo->u4ChGrantedInterval = u4GrantInterval; -+ -+ /* 3. state transition to join/ibss-alone/ibss-merge */ -+ /* 3.1 set timeout timer in cases join could not be completed */ -+ cnmTimerStartTimer(prAdapter, -+ &prAisFsmInfo->rJoinTimeoutTimer, -+ prAisFsmInfo->u4ChGrantedInterval - AIS_JOIN_CH_GRANT_THRESHOLD); -+ /* 3.2 set local variable to indicate join timer is ticking */ -+ prAisFsmInfo->fgIsInfraChannelFinished = FALSE; -+ -+ /* 3.3 switch to join state */ -+ aisFsmSteps(prAdapter, AIS_STATE_JOIN); -+ -+ prAisFsmInfo->fgIsChannelGranted = TRUE; -+ } else if (prAisFsmInfo->eCurrentState == AIS_STATE_REQ_REMAIN_ON_CHANNEL && -+ prAisFsmInfo->ucSeqNumOfChReq == ucTokenID) { -+ /* 2. channel privilege has been approved */ -+ prAisFsmInfo->u4ChGrantedInterval = u4GrantInterval; -+ -+ /* 3.1 set timeout timer in cases upper layer cancel_remain_on_channel never comes */ -+ cnmTimerStartTimer(prAdapter, &prAisFsmInfo->rChannelTimeoutTimer, prAisFsmInfo->u4ChGrantedInterval); -+ -+ /* 3.2 switch to remain_on_channel state */ -+ aisFsmSteps(prAdapter, AIS_STATE_REMAIN_ON_CHANNEL); -+ -+ /* 3.3. indicate upper layer for channel ready */ -+ kalReadyOnChannel(prAdapter->prGlueInfo, -+ prAisFsmInfo->rChReqInfo.u8Cookie, -+ prAisFsmInfo->rChReqInfo.eBand, -+ prAisFsmInfo->rChReqInfo.eSco, -+ prAisFsmInfo->rChReqInfo.ucChannelNum, prAisFsmInfo->rChReqInfo.u4DurationMs); -+ -+ prAisFsmInfo->fgIsChannelGranted = TRUE; -+ } else { /* mismatched grant */ -+ /* 2. return channel privilege to CNM immediately */ -+ aisFsmReleaseCh(prAdapter); -+ } -+ -+} /* end of aisFsmRunEventChGrant() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is to inform CNM that channel privilege -+* has been released -+* -+* \param[in] prAdapter Pointer of ADAPTER_T -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID aisFsmReleaseCh(IN P_ADAPTER_T prAdapter) -+{ -+ P_AIS_FSM_INFO_T prAisFsmInfo; -+ P_MSG_CH_ABORT_T prMsgChAbort; -+ -+ ASSERT(prAdapter); -+ -+ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); -+ -+ if (prAisFsmInfo->fgIsChannelGranted == TRUE || prAisFsmInfo->fgIsChannelRequested == TRUE) { -+ -+ prAisFsmInfo->fgIsChannelRequested = FALSE; -+ prAisFsmInfo->fgIsChannelGranted = FALSE; -+ -+ /* 1. return channel privilege to CNM immediately */ -+ prMsgChAbort = (P_MSG_CH_ABORT_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_CH_ABORT_T)); -+ if (!prMsgChAbort) { -+ ASSERT(0); /* Can't release Channel to CNM */ -+ return; -+ } -+ -+ prMsgChAbort->rMsgHdr.eMsgId = MID_MNY_CNM_CH_ABORT; -+ prMsgChAbort->ucNetTypeIndex = NETWORK_TYPE_AIS_INDEX; -+ prMsgChAbort->ucTokenID = prAisFsmInfo->ucSeqNumOfChReq; -+ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgChAbort, MSG_SEND_METHOD_BUF); -+ } -+ -+} /* end of aisFsmReleaseCh() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is to inform AIS that corresponding beacon has not -+* been received for a while and probing is not successful -+* -+* \param[in] prAdapter Pointer of ADAPTER_T -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID aisBssBeaconTimeout(IN P_ADAPTER_T prAdapter) -+{ -+ P_BSS_INFO_T prAisBssInfo; -+ BOOLEAN fgDoAbortIndication = FALSE; -+ -+ ASSERT(prAdapter); -+ -+ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ -+ /* 4 <1> Diagnose Connection for Beacon Timeout Event */ -+ if (PARAM_MEDIA_STATE_CONNECTED == prAisBssInfo->eConnectionState) { -+ if (OP_MODE_INFRASTRUCTURE == prAisBssInfo->eCurrentOPMode) { -+ P_STA_RECORD_T prStaRec = prAisBssInfo->prStaRecOfAP; -+ -+ if (prStaRec) -+ fgDoAbortIndication = TRUE; -+ } else if (OP_MODE_IBSS == prAisBssInfo->eCurrentOPMode) { -+ fgDoAbortIndication = TRUE; -+ } -+ } -+ /* 4 <2> invoke abort handler */ -+ if (fgDoAbortIndication) { -+#if 0 -+ P_CONNECTION_SETTINGS_T prConnSettings; -+ -+ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); -+ prConnSettings->fgIsDisconnectedByNonRequest = TRUE; -+#endif -+ -+ DBGLOG(AIS, INFO, "Beacon Timeout, Remove BSS [%pM]\n", prAisBssInfo->aucBSSID); -+ scanRemoveBssDescByBssid(prAdapter, prAisBssInfo->aucBSSID); -+ -+ /* -+ Note: Cannot change TRUE to FALSE; or you will suffer the problem in -+ ALPS01270257/ ALPS01804173 -+ */ -+ aisFsmStateAbort(prAdapter, DISCONNECT_REASON_CODE_RADIO_LOST, TRUE); -+ } -+ -+} /* end of aisBssBeaconTimeout() */ -+ -+VOID aisBssSecurityChanged(P_ADAPTER_T prAdapter) -+{ -+ P_BSS_INFO_T prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ -+ prAdapter->rWifiVar.rConnSettings.fgIsDisconnectedByNonRequest = TRUE; -+ prAisBssInfo->u2DeauthReason = REASON_CODE_BSS_SECURITY_CHANGE; -+ aisFsmStateAbort(prAdapter, DISCONNECT_REASON_CODE_DEAUTHENTICATED, FALSE); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is to inform AIS that DEAUTH frame has been -+* sent and thus state machine could go ahead -+* -+* \param[in] prAdapter Pointer of ADAPTER_T -+* \param[in] prMsduInfo Pointer of MSDU_INFO_T for DEAUTH frame -+* \param[in] prAdapter Pointer of ADAPTER_T -+* -+* \return WLAN_STATUS_SUCCESS -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+aisDeauthXmitComplete(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus) -+{ -+ P_AIS_FSM_INFO_T prAisFsmInfo; -+ -+ ASSERT(prAdapter); -+ -+ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); -+ -+ if (rTxDoneStatus == TX_RESULT_SUCCESS) -+ cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rDeauthDoneTimer); -+ -+ if (prAisFsmInfo->eCurrentState == AIS_STATE_DISCONNECTING) { -+ if (rTxDoneStatus != TX_RESULT_DROPPED_IN_DRIVER) -+ aisFsmStateAbort(prAdapter, DISCONNECT_REASON_CODE_NEW_CONNECTION, FALSE); -+ } else { -+ DBGLOG(AIS, WARN, "DEAUTH frame transmitted without further handling"); -+ } -+ -+ return WLAN_STATUS_SUCCESS; -+ -+} /* end of aisDeauthXmitComplete() */ -+ -+#if CFG_SUPPORT_ROAMING -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will indicate an Event of "Looking for a candidate due to weak signal" to AIS FSM. -+* -+* @param[in] u4ReqScan Requesting Scan or not -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID aisFsmRunEventRoamingDiscovery(IN P_ADAPTER_T prAdapter, UINT_32 u4ReqScan) -+{ -+ P_AIS_FSM_INFO_T prAisFsmInfo; -+ P_CONNECTION_SETTINGS_T prConnSettings; -+ ENUM_AIS_REQUEST_TYPE_T eAisRequest; -+ -+ DBGLOG(AIS, LOUD, "aisFsmRunEventRoamingDiscovery()\n"); -+ -+ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); -+ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); -+ -+ /* search candidates by best rssi */ -+ prConnSettings->eConnectionPolicy = CONNECT_BY_SSID_BEST_RSSI; -+ -+#if CFG_SUPPORT_WFD -+#if CFG_ENABLE_WIFI_DIRECT -+ { -+ /* Check WFD is running */ -+ P_BSS_INFO_T prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); -+ P_WFD_CFG_SETTINGS_T prWfdCfgSettings = (P_WFD_CFG_SETTINGS_T) NULL; -+ -+ if (prAdapter->fgIsP2PRegistered && -+ IS_BSS_ACTIVE(prP2pBssInfo) && -+ (prP2pBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT || -+ prP2pBssInfo->eCurrentOPMode == OP_MODE_INFRASTRUCTURE)) { -+ DBGLOG(ROAMING, INFO, "Handle roaming when P2P is GC or GO.\n"); -+ if (prAdapter->rWifiVar.prP2pFsmInfo) { -+ prWfdCfgSettings = &(prAdapter->rWifiVar.prP2pFsmInfo->rWfdConfigureSettings); -+ if ((prWfdCfgSettings->ucWfdEnable == 1) && -+ ((prWfdCfgSettings->u4WfdFlag & WFD_FLAGS_DEV_INFO_VALID))) { -+ DBGLOG(ROAMING, INFO, "WFD is running. Stop roaming.\n"); -+ roamingFsmRunEventRoam(prAdapter); -+ roamingFsmRunEventFail(prAdapter, ROAMING_FAIL_REASON_NOCANDIDATE); -+ return; -+ } -+ } else { -+ ASSERT(0); -+ } -+ } /* fgIsP2PRegistered */ -+ } -+#endif -+#endif -+ -+ /* results are still new */ -+ if (!u4ReqScan) { -+ roamingFsmRunEventRoam(prAdapter); -+ eAisRequest = AIS_REQUEST_ROAMING_CONNECT; -+ } else { -+ if (prAisFsmInfo->eCurrentState == AIS_STATE_ONLINE_SCAN -+ || prAisFsmInfo->eCurrentState == AIS_STATE_LOOKING_FOR) { -+ eAisRequest = AIS_REQUEST_ROAMING_CONNECT; -+ } else { -+ eAisRequest = AIS_REQUEST_ROAMING_SEARCH; -+ } -+ } -+ -+ if (prAisFsmInfo->eCurrentState == AIS_STATE_NORMAL_TR && prAisFsmInfo->fgIsInfraChannelFinished == TRUE) { -+ if (eAisRequest == AIS_REQUEST_ROAMING_SEARCH) -+ aisFsmSteps(prAdapter, AIS_STATE_LOOKING_FOR); -+ else -+ aisFsmSteps(prAdapter, AIS_STATE_SEARCH); -+ } else { -+ aisFsmIsRequestPending(prAdapter, AIS_REQUEST_ROAMING_SEARCH, TRUE); -+ aisFsmIsRequestPending(prAdapter, AIS_REQUEST_ROAMING_CONNECT, TRUE); -+ -+ aisFsmInsertRequest(prAdapter, eAisRequest); -+ } -+ -+} /* end of aisFsmRunEventRoamingDiscovery() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Update the time of ScanDone for roaming and transit to Roam state. -+* -+* @param (none) -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+ENUM_AIS_STATE_T aisFsmRoamingScanResultsUpdate(IN P_ADAPTER_T prAdapter) -+{ -+ P_AIS_FSM_INFO_T prAisFsmInfo; -+ P_ROAMING_INFO_T prRoamingFsmInfo; -+ ENUM_AIS_STATE_T eNextState; -+ -+ DBGLOG(AIS, LOUD, "->aisFsmRoamingScanResultsUpdate()\n"); -+ -+ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); -+ prRoamingFsmInfo = (P_ROAMING_INFO_T) &(prAdapter->rWifiVar.rRoamingInfo); -+ -+ roamingFsmScanResultsUpdate(prAdapter); -+ -+ eNextState = prAisFsmInfo->eCurrentState; -+ if (prRoamingFsmInfo->eCurrentState == ROAMING_STATE_DISCOVERY) { -+ roamingFsmRunEventRoam(prAdapter); -+ eNextState = AIS_STATE_SEARCH; -+ } else if (prAisFsmInfo->eCurrentState == AIS_STATE_LOOKING_FOR) { -+ eNextState = AIS_STATE_SEARCH; -+ } else if (prAisFsmInfo->eCurrentState == AIS_STATE_ONLINE_SCAN) { -+ eNextState = AIS_STATE_NORMAL_TR; -+ } -+ -+ return eNextState; -+} /* end of aisFsmRoamingScanResultsUpdate() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will modify and update necessary information to firmware -+* for disconnection of last AP before switching to roaming bss. -+* -+* @param IN prAdapter Pointer to the Adapter structure. -+* prTargetStaRec Target of StaRec of roaming -+* -+* @retval None -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID aisFsmRoamingDisconnectPrevAP(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prTargetStaRec) -+{ -+ P_BSS_INFO_T prAisBssInfo; -+ -+ DBGLOG(AIS, LOUD, "aisFsmRoamingDisconnectPrevAP()"); -+ -+ ASSERT(prAdapter); -+ -+ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ -+ nicPmIndicateBssAbort(prAdapter, NETWORK_TYPE_AIS_INDEX); -+ -+ /* Not invoke rlmBssAborted() here to avoid prAisBssInfo->fg40mBwAllowed -+ * to be reset. RLM related parameters will be reset again when handling -+ * association response in rlmProcessAssocRsp(). 20110413 -+ */ -+ /* rlmBssAborted(prAdapter, prAisBssInfo); */ -+ -+ /* 4 <3> Unset the fgIsConnected flag of BSS_DESC_T and send Deauth if needed. */ -+ if (PARAM_MEDIA_STATE_CONNECTED == prAisBssInfo->eConnectionState) -+ scanRemoveConnFlagOfBssDescByBssid(prAdapter, prAisBssInfo->aucBSSID); -+ /* 4 <4> Change Media State immediately. */ -+ aisChangeMediaState(prAdapter, PARAM_MEDIA_STATE_DISCONNECTED); -+ -+ /* 4 <4.1> sync. with firmware */ -+ prTargetStaRec->ucNetTypeIndex = 0xff; /* Virtial NetType */ -+ nicUpdateBss(prAdapter, NETWORK_TYPE_AIS_INDEX); -+ prTargetStaRec->ucNetTypeIndex = NETWORK_TYPE_AIS_INDEX; /* Virtial NetType */ -+ -+#if (CFG_SUPPORT_TDLS == 1) -+ TdlsexLinkHistoryRecord(prAdapter->prGlueInfo, TRUE, prAisBssInfo->aucBSSID, -+ TRUE, TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_ROAMING); -+#endif /* CFG_SUPPORT_TDLS */ -+ -+} /* end of aisFsmRoamingDisconnectPrevAP() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will update the contain of BSS_INFO_T for AIS network once -+* the roaming was completed. -+* -+* @param IN prAdapter Pointer to the Adapter structure. -+* prStaRec StaRec of roaming AP -+* prAssocRspSwRfb -+* -+* @retval None -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID aisUpdateBssInfoForRoamingAP(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN P_SW_RFB_T prAssocRspSwRfb) -+{ -+ P_BSS_INFO_T prAisBssInfo; -+ -+ DBGLOG(AIS, LOUD, "aisUpdateBssInfoForRoamingAP()"); -+ -+ ASSERT(prAdapter); -+ -+ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ -+ /* 4 <1.1> Change FW's Media State immediately. */ -+ aisChangeMediaState(prAdapter, PARAM_MEDIA_STATE_CONNECTED); -+ -+ /* 4 <1.2> Deactivate previous AP's STA_RECORD_T in Driver if have. */ -+ if ((prAisBssInfo->prStaRecOfAP) && -+ (prAisBssInfo->prStaRecOfAP != prStaRec) && (prAisBssInfo->prStaRecOfAP->fgIsInUse)) { -+ cnmStaRecChangeState(prAdapter, prAisBssInfo->prStaRecOfAP, STA_STATE_1); -+ } -+ /* 4 <1.3> Update BSS_INFO_T */ -+ aisUpdateBssInfoForJOIN(prAdapter, prStaRec, prAssocRspSwRfb); -+ -+ /* 4 <1.4> Activate current AP's STA_RECORD_T in Driver. */ -+ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_3); -+ -+ /* 4 <1.6> Indicate Connected Event to Host immediately. */ -+ /* Require BSSID, Association ID, Beacon Interval.. from AIS_BSS_INFO_T */ -+ aisIndicationOfMediaStateToHost(prAdapter, PARAM_MEDIA_STATE_CONNECTED, FALSE); -+ -+} /* end of aisFsmRoamingUpdateBss() */ -+ -+#endif /* CFG_SUPPORT_ROAMING */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Check if there is any pending request and remove it (optional) -+* -+* @param prAdapter -+* eReqType -+* bRemove -+* -+* @return TRUE -+* FALSE -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN aisFsmIsRequestPending(IN P_ADAPTER_T prAdapter, IN ENUM_AIS_REQUEST_TYPE_T eReqType, IN BOOLEAN bRemove) -+{ -+ P_AIS_FSM_INFO_T prAisFsmInfo; -+ P_AIS_REQ_HDR_T prPendingReqHdr, prPendingReqHdrNext; -+ -+ ASSERT(prAdapter); -+ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); -+ -+ /* traverse through pending request list */ -+ LINK_FOR_EACH_ENTRY_SAFE(prPendingReqHdr, -+ prPendingReqHdrNext, &(prAisFsmInfo->rPendingReqList), rLinkEntry, AIS_REQ_HDR_T) { -+ /* check for specified type */ -+ if (prPendingReqHdr->eReqType == eReqType) { -+ /* check if need to remove */ -+ if (bRemove == TRUE) { -+ LINK_REMOVE_KNOWN_ENTRY(&(prAisFsmInfo->rPendingReqList), -+ &(prPendingReqHdr->rLinkEntry)); -+ -+ cnmMemFree(prAdapter, prPendingReqHdr); -+ } -+ -+ return TRUE; -+ } -+ } -+ -+ return FALSE; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Get next pending request -+* -+* @param prAdapter -+* -+* @return P_AIS_REQ_HDR_T -+*/ -+/*----------------------------------------------------------------------------*/ -+P_AIS_REQ_HDR_T aisFsmGetNextRequest(IN P_ADAPTER_T prAdapter) -+{ -+ P_AIS_FSM_INFO_T prAisFsmInfo; -+ P_AIS_REQ_HDR_T prPendingReqHdr; -+ -+ ASSERT(prAdapter); -+ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); -+ -+ LINK_REMOVE_HEAD(&(prAisFsmInfo->rPendingReqList), prPendingReqHdr, P_AIS_REQ_HDR_T); -+ -+ return prPendingReqHdr; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Insert a new request -+* -+* @param prAdapter -+* eReqType -+* -+* @return TRUE -+* FALSE -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN aisFsmInsertRequest(IN P_ADAPTER_T prAdapter, IN ENUM_AIS_REQUEST_TYPE_T eReqType) -+{ -+ P_AIS_REQ_HDR_T prAisReq; -+ P_AIS_FSM_INFO_T prAisFsmInfo; -+ -+ ASSERT(prAdapter); -+ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); -+ -+ prAisReq = (P_AIS_REQ_HDR_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(AIS_REQ_HDR_T)); -+ -+ if (!prAisReq) { -+ ASSERT(0); /* Can't generate new message */ -+ return FALSE; -+ } -+ -+ prAisReq->eReqType = eReqType; -+ -+ /* attach request into pending request list */ -+ LINK_INSERT_TAIL(&prAisFsmInfo->rPendingReqList, &prAisReq->rLinkEntry); -+ -+ return TRUE; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Flush all pending requests -+* -+* @param prAdapter -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID aisFsmFlushRequest(IN P_ADAPTER_T prAdapter) -+{ -+ P_AIS_REQ_HDR_T prAisReq; -+ -+ ASSERT(prAdapter); -+ -+ while ((prAisReq = aisFsmGetNextRequest(prAdapter)) != NULL) -+ cnmMemFree(prAdapter, prAisReq); -+ -+} -+ -+VOID aisFsmRunEventRemainOnChannel(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) -+{ -+ P_MSG_REMAIN_ON_CHANNEL_T prRemainOnChannel; -+ P_AIS_FSM_INFO_T prAisFsmInfo; -+ P_CONNECTION_SETTINGS_T prConnSettings; -+ -+ DEBUGFUNC("aisFsmRunEventRemainOnChannel()"); -+ -+ ASSERT(prAdapter); -+ ASSERT(prMsgHdr); -+ -+ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); -+ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); -+ -+ prRemainOnChannel = (P_MSG_REMAIN_ON_CHANNEL_T) prMsgHdr; -+ -+ /* record parameters */ -+ prAisFsmInfo->rChReqInfo.eBand = prRemainOnChannel->eBand; -+ prAisFsmInfo->rChReqInfo.eSco = prRemainOnChannel->eSco; -+ prAisFsmInfo->rChReqInfo.ucChannelNum = prRemainOnChannel->ucChannelNum; -+ prAisFsmInfo->rChReqInfo.u4DurationMs = prRemainOnChannel->u4DurationMs; -+ prAisFsmInfo->rChReqInfo.u8Cookie = prRemainOnChannel->u8Cookie; -+ -+ if (prAisFsmInfo->eCurrentState == AIS_STATE_IDLE || prAisFsmInfo->eCurrentState == AIS_STATE_NORMAL_TR) { -+ /* transit to next state */ -+ aisFsmSteps(prAdapter, AIS_STATE_REQ_REMAIN_ON_CHANNEL); -+ } else { -+ aisFsmInsertRequest(prAdapter, AIS_REQUEST_REMAIN_ON_CHANNEL); -+ } -+ -+ /* free messages */ -+ cnmMemFree(prAdapter, prMsgHdr); -+ -+} -+ -+VOID aisFsmRunEventCancelRemainOnChannel(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) -+{ -+ P_AIS_FSM_INFO_T prAisFsmInfo; -+ P_BSS_INFO_T prAisBssInfo; -+ P_MSG_CANCEL_REMAIN_ON_CHANNEL_T prCancelRemainOnChannel; -+ -+ ASSERT(prAdapter); -+ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); -+ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ -+ prCancelRemainOnChannel = (P_MSG_CANCEL_REMAIN_ON_CHANNEL_T) prMsgHdr; -+ -+ /* 1. Check the cookie first */ -+ if (prCancelRemainOnChannel->u8Cookie == prAisFsmInfo->rChReqInfo.u8Cookie) { -+ -+ /* 2. release channel privilege/request */ -+ if (prAisFsmInfo->eCurrentState == AIS_STATE_REQ_REMAIN_ON_CHANNEL) { -+ /* 2.1 elease channel */ -+ aisFsmReleaseCh(prAdapter); -+ } else if (prAisFsmInfo->eCurrentState == AIS_STATE_REMAIN_ON_CHANNEL) { -+ /* 2.1 release channel */ -+ aisFsmReleaseCh(prAdapter); -+ -+ /* 2.2 stop channel timeout timer */ -+ cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rChannelTimeoutTimer); -+ } -+ -+ /* 3. clear pending request of remain_on_channel */ -+ aisFsmIsRequestPending(prAdapter, AIS_REQUEST_REMAIN_ON_CHANNEL, TRUE); -+ -+ /* 4. decide which state to retreat */ -+ if (prAisBssInfo->eConnectionState == PARAM_MEDIA_STATE_CONNECTED) -+ aisFsmSteps(prAdapter, AIS_STATE_NORMAL_TR); -+ else -+ aisFsmSteps(prAdapter, AIS_STATE_IDLE); -+ } -+ -+ /* 5. free message */ -+ cnmMemFree(prAdapter, prMsgHdr); -+ -+} -+ -+VOID aisFsmRunEventMgmtFrameTx(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) -+{ -+ P_AIS_FSM_INFO_T prAisFsmInfo; -+ P_MSG_MGMT_TX_REQUEST_T prMgmtTxMsg = (P_MSG_MGMT_TX_REQUEST_T) NULL; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prMsgHdr != NULL)); -+ -+ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); -+ /* prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); */ -+ -+ if (prAisFsmInfo == NULL) -+ break; -+ prMgmtTxMsg = (P_MSG_MGMT_TX_REQUEST_T) prMsgHdr; -+ -+ aisFuncTxMgmtFrame(prAdapter, -+ &prAisFsmInfo->rMgmtTxInfo, prMgmtTxMsg->prMgmtMsduInfo, prMgmtTxMsg->u8Cookie); -+ -+ } while (FALSE); -+ -+ if (prMsgHdr) -+ cnmMemFree(prAdapter, prMsgHdr); -+ -+} /* aisFsmRunEventMgmtFrameTx */ -+ -+VOID aisFsmRunEventChannelTimeout(IN P_ADAPTER_T prAdapter, ULONG ulParam) -+{ -+ P_AIS_FSM_INFO_T prAisFsmInfo; -+ P_BSS_INFO_T prAisBssInfo; -+ -+ DEBUGFUNC("aisFsmRunEventRemainOnChannel()"); -+ -+ ASSERT(prAdapter); -+ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); -+ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ -+ if (prAisFsmInfo->eCurrentState == AIS_STATE_REMAIN_ON_CHANNEL) { -+ /* 1. release channel */ -+ aisFsmReleaseCh(prAdapter); -+ -+ /* 2. stop channel timeout timer */ -+ cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rChannelTimeoutTimer); -+ -+ /* 3. expiration indication to upper layer */ -+ kalRemainOnChannelExpired(prAdapter->prGlueInfo, -+ prAisFsmInfo->rChReqInfo.u8Cookie, -+ prAisFsmInfo->rChReqInfo.eBand, -+ prAisFsmInfo->rChReqInfo.eSco, prAisFsmInfo->rChReqInfo.ucChannelNum); -+ -+ /* 4. decide which state to retreat */ -+ if (prAisBssInfo->eConnectionState == PARAM_MEDIA_STATE_CONNECTED) -+ aisFsmSteps(prAdapter, AIS_STATE_NORMAL_TR); -+ else -+ aisFsmSteps(prAdapter, AIS_STATE_IDLE); -+ } else { -+ DBGLOG(AIS, WARN, "Unexpected remain_on_channel timeout event\n"); -+#if DBG -+ DBGLOG(AIS, STATE, "CURRENT State: [%s]\n", apucDebugAisState[prAisFsmInfo->eCurrentState]); -+#else -+ DBGLOG(AIS, STATE, "[%d] CURRENT State: [%d]\n", DBG_AIS_IDX, prAisFsmInfo->eCurrentState); -+#endif -+ } -+ -+} -+ -+WLAN_STATUS -+aisFsmRunEventMgmtFrameTxDone(IN P_ADAPTER_T prAdapter, -+ IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus) -+{ -+ P_AIS_FSM_INFO_T prAisFsmInfo; -+ P_AIS_MGMT_TX_REQ_INFO_T prMgmtTxReqInfo = (P_AIS_MGMT_TX_REQ_INFO_T) NULL; -+ BOOLEAN fgIsSuccess = FALSE; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prMsduInfo != NULL)); -+ -+ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); -+ prMgmtTxReqInfo = &(prAisFsmInfo->rMgmtTxInfo); -+ -+ if (rTxDoneStatus != TX_RESULT_SUCCESS) { -+ DBGLOG(AIS, ERROR, "Mgmt Frame TX Fail, Status:%d.\n", rTxDoneStatus); -+ } else { -+ fgIsSuccess = TRUE; -+ /* printk("Mgmt Frame TX Done.\n"); */ -+ } -+ -+ if (prMgmtTxReqInfo->prMgmtTxMsdu == prMsduInfo) { -+ kalIndicateMgmtTxStatus(prAdapter->prGlueInfo, -+ prMgmtTxReqInfo->u8Cookie, -+ fgIsSuccess, prMsduInfo->prPacket, (UINT_32) prMsduInfo->u2FrameLength); -+ -+ prMgmtTxReqInfo->prMgmtTxMsdu = NULL; -+ } -+ -+ } while (FALSE); -+ -+ return WLAN_STATUS_SUCCESS; -+ -+} /* aisFsmRunEventMgmtFrameTxDone */ -+ -+WLAN_STATUS -+aisFuncTxMgmtFrame(IN P_ADAPTER_T prAdapter, -+ IN P_AIS_MGMT_TX_REQ_INFO_T prMgmtTxReqInfo, IN P_MSDU_INFO_T prMgmtTxMsdu, IN UINT_64 u8Cookie) -+{ -+ WLAN_STATUS rWlanStatus = WLAN_STATUS_SUCCESS; -+ P_MSDU_INFO_T prTxMsduInfo = (P_MSDU_INFO_T) NULL; -+ P_WLAN_MAC_HEADER_T prWlanHdr = (P_WLAN_MAC_HEADER_T) NULL; -+ P_STA_RECORD_T prStaRec = (P_STA_RECORD_T) NULL; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prMgmtTxReqInfo != NULL)); -+ -+ if (prMgmtTxReqInfo->fgIsMgmtTxRequested) { -+ -+ /* 1. prMgmtTxReqInfo->prMgmtTxMsdu != NULL */ -+ /* Packet on driver, not done yet, drop it. */ -+ prTxMsduInfo = prMgmtTxReqInfo->prMgmtTxMsdu; -+ if (prTxMsduInfo != NULL) { -+ -+ kalIndicateMgmtTxStatus(prAdapter->prGlueInfo, -+ prMgmtTxReqInfo->u8Cookie, -+ FALSE, -+ prTxMsduInfo->prPacket, (UINT_32) prTxMsduInfo->u2FrameLength); -+ -+ /* Leave it to TX Done handler. */ -+ /* cnmMgtPktFree(prAdapter, prTxMsduInfo); */ -+ prMgmtTxReqInfo->prMgmtTxMsdu = NULL; -+ } -+ /* 2. prMgmtTxReqInfo->prMgmtTxMsdu == NULL */ -+ /* Packet transmitted, wait tx done. (cookie issue) */ -+ } -+ -+ ASSERT(prMgmtTxReqInfo->prMgmtTxMsdu == NULL); -+ -+ prWlanHdr = (P_WLAN_MAC_HEADER_T) ((ULONG) prMgmtTxMsdu->prPacket + MAC_TX_RESERVED_FIELD); -+ prStaRec = cnmGetStaRecByAddress(prAdapter, NETWORK_TYPE_AIS_INDEX, prWlanHdr->aucAddr1); -+ prMgmtTxMsdu->ucNetworkType = (UINT_8) NETWORK_TYPE_AIS_INDEX; -+ -+ prMgmtTxReqInfo->u8Cookie = u8Cookie; -+ prMgmtTxReqInfo->prMgmtTxMsdu = prMgmtTxMsdu; -+ prMgmtTxReqInfo->fgIsMgmtTxRequested = TRUE; -+ -+ prMgmtTxMsdu->eSrc = TX_PACKET_MGMT; -+ prMgmtTxMsdu->ucPacketType = HIF_TX_PACKET_TYPE_MGMT; -+ prMgmtTxMsdu->ucStaRecIndex = (prStaRec != NULL) ? (prStaRec->ucIndex) : (0xFF); -+ if (prStaRec != NULL) { -+ /* Do nothing */ -+ /* printk("Mgmt with station record: %pM .\n", prStaRec->aucMacAddr); */ -+ } -+ -+ prMgmtTxMsdu->ucMacHeaderLength = WLAN_MAC_MGMT_HEADER_LEN; /* TODO: undcertain. */ -+ prMgmtTxMsdu->fgIs802_1x = FALSE; -+ prMgmtTxMsdu->fgIs802_11 = TRUE; -+ prMgmtTxMsdu->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter); -+ prMgmtTxMsdu->pfTxDoneHandler = aisFsmRunEventMgmtFrameTxDone; -+ prMgmtTxMsdu->fgIsBasicRate = TRUE; -+ DBGLOG(AIS, TRACE, "Mgmt seq NO. %d .\n", prMgmtTxMsdu->ucTxSeqNum); -+ -+ nicTxEnqueueMsdu(prAdapter, prMgmtTxMsdu); -+ -+ } while (FALSE); -+ -+ return rWlanStatus; -+} /* aisFuncTxMgmtFrame */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will validate the Rx Action Frame and indicate to uppoer layer -+* if the specified conditions were matched. -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* @param[in] prSwRfb Pointer to SW RFB data structure. -+* @param[out] pu4ControlFlags Control flags for replying the Probe Response -+* -+* @retval none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID aisFuncValidateRxActionFrame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb) -+{ -+ P_AIS_FSM_INFO_T prAisFsmInfo = (P_AIS_FSM_INFO_T) NULL; -+ -+ DEBUGFUNC("aisFuncValidateRxActionFrame"); -+ -+ do { -+ -+ ASSERT_BREAK((prAdapter != NULL) && (prSwRfb != NULL)); -+ -+ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); -+ -+ if (1 /* prAisFsmInfo->u4AisPacketFilter & PARAM_PACKET_FILTER_ACTION_FRAME */) { -+ /* Leave the action frame to wpa_supplicant. */ -+ kalIndicateRxMgmtFrame(prAdapter->prGlueInfo, prSwRfb); -+ } -+ -+ } while (FALSE); -+ -+ return; -+ -+} /* aisFuncValidateRxActionFrame */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/assoc.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/assoc.c -new file mode 100644 -index 000000000000..f02d7c3bb5b2 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/assoc.c -@@ -0,0 +1,1932 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/assoc.c#3 -+*/ -+ -+/*! \file "assoc.c" -+ \brief This file includes the association-related functions. -+ -+ This file includes the association-related functions. -+*/ -+ -+/*\ -+** Log: assoc.c -+** -+** 07 27 2012 yuche.tsai -+** [ALPS00324337] [ALPS.JB][Hot-Spot] Driver update for Hot-Spot -+** Fix wifi direct connection issue. -+ * -+ * 07 17 2012 yuche.tsai -+ * NULL -+ * Let netdev bring up. -+ * -+ * 07 17 2012 yuche.tsai -+ * NULL -+ * Compile no error before trial run. -+ * -+ * 06 13 2012 yuche.tsai -+ * NULL -+ * Update maintrunk driver. -+ * Add support for driver compose assoc request frame. -+ * -+ * 06 08 2012 cp.wu -+ * [WCXRP00001245] [MT6620 Wi-Fi][Driver][Firmware] NPS Software Development -+ * add a pair of brace for compilation success. -+ * -+ * 06 04 2012 cp.wu -+ * [WCXRP00001245] [MT6620 Wi-Fi][Driver][Firmware] NPS Software Development -+ * discussed with WH, privacy bit in associate response is not necessary to be checked, -+ * and identified as association failure when mismatching with beacon/probe response -+ * -+ * 03 14 2012 wh.su -+ * [WCXRP00001173] [MT6620 Wi-Fi][Driver] Adding the ICS Tethering WPA2-PSK supporting -+ * Add code from 2.2 -+ * -+ * 03 09 2012 terry.wu -+ * NULL -+ * Fix build error. -+ * -+ * 03 02 2012 terry.wu -+ * NULL -+ * Sync CFG80211 modification from branch 2,2. -+ * -+ * 01 16 2012 yuche.tsai -+ * NULL -+ * Update Driver for wifi driect gc join IE update issue. -+ * -+ * 11 10 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * change the debug module level. -+ * -+ * 10 25 2011 cm.chang -+ * [WCXRP00001058] [All Wi-Fi][Driver] Fix sta_rec's phyTypeSet and OBSS scan in AP mode -+ * Fix PhyTypeSet in STA_REC in AP mode -+ * -+ * 10 12 2011 wh.su -+ * [WCXRP00001036] [MT6620 Wi-Fi][Driver][FW] Adding the 802.11w code for MFP -+ * adding the 802.11w related function and define . -+ * -+ * 09 19 2011 yuche.tsai -+ * NULL -+ * Fix KE when enable hot-spot & any one client connect to this hot-spot. -+ * -+ * 09 14 2011 yuche.tsai -+ * NULL -+ * Add P2P IE in assoc response. -+ * -+ * 07 15 2011 terry.wu -+ * [WCXRP00000855] [MT6620 Wi-Fi] [Driver] Workaround for Kingnet 710 AP wrong AID assignment -+ * Update workaround for Kingnet AP. -+ * -+ * 07 15 2011 terry.wu -+ * [WCXRP00000855] [MT6620 Wi-Fi] [Driver] Workaround for Kingnet 710 AP wrong AID assignment -+ * Workaround for Kingnet 710 AP wrong AID assignment. -+ * -+ * 05 02 2011 eddie.chen -+ * [WCXRP00000603] [MT6620 Wi-Fi][DRV] Fix Klocwork warning[WCXRP00000672] [MT6620 Wi-Fi][FW] -+ * Fix the PS event allocation -+ * Check STA when rx assoc. -+ * -+ * 04 18 2011 terry.wu -+ * [WCXRP00000660] [MT6620 Wi-Fi][Driver] Remove flag CFG_WIFI_DIRECT_MOVED -+ * Remove flag CFG_WIFI_DIRECT_MOVED. -+ * -+ * 03 19 2011 yuche.tsai -+ * [WCXRP00000581] [Volunteer Patch][MT6620][Driver] P2P IE in Assoc Req Issue -+ * Make assoc req to append P2P IE if wifi direct is enabled. -+ * -+ * 03 17 2011 chinglan.wang -+ * [WCXRP00000570] [MT6620 Wi-Fi][Driver] Add Wi-Fi Protected Setup v2.0 feature -+ * . -+ * -+ * 03 16 2011 wh.su -+ * [WCXRP00000530] [MT6620 Wi-Fi] [Driver] skip doing p2pRunEventAAAComplete after send assoc response Tx Done -+ * enable the protected while at P2P start GO, and skip some security check . -+ * -+ * 03 14 2011 wh.su -+ * [WCXRP00000545] [MT6620 Wi-Fi] [Driver] Fixed the p2p not enable, received a assoc rsp -+ * cause the rx assoc execute a null function -+ * Modify file for avoid assert at BOW receive a assoc response frame but no p2p function. -+ * -+ * 03 08 2011 terry.wu -+ * [WCXRP00000524] [MT6620 Wi-Fi][Driver] Fix p2p assoc request containing wrong IE format -+ * Fix p2p assoc request containing wrong IE format. -+ * -+ * 03 02 2011 wh.su -+ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code -+ * add code to let the beacon and probe response for Auto GO WSC . -+ * -+ * 02 15 2011 yuche.tsai -+ * [WCXRP00000431] [Volunteer Patch][MT6620][Driver] Add MLME support for deauthentication under AP(Hot-Spot) mode. -+ * Fix RX disassoc issue under Hot-spot mode. -+ * -+ * 02 09 2011 wh.su -+ * [WCXRP00000432] [MT6620 Wi-Fi][Driver] Add STA privacy check at hotspot mode -+ * adding the code for check STA privacy bit at AP mode, . -+ * -+ * 02 08 2011 eddie.chen -+ * [WCXRP00000426] [MT6620 Wi-Fi][FW/Driver] Add STA aging timeout and defualtHwRatein AP mode -+ * Add event STA agint timeout -+ * -+ * 01 25 2011 yuche.tsai -+ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record. -+ * Change Station Type in Station Record, Modify MACRO definition for getting station type & network type index & Role. -+ * -+ * 01 12 2011 yuche.tsai -+ * [WCXRP00000353] [Volunteer Patch][MT6620][Driver] Desired Non-HT Rate Set update -+ * when STA record is created under AP Mode. -+ * Update Phy Type Set. When legacy client is connected, it can use 11b rate, -+ * but if the P2P device is connected, 11b rate is not allowed. -+ * -+ * 01 11 2011 yuche.tsai -+ * [WCXRP00000353] [Volunteer Patch][MT6620][Driver] Desired Non-HT Rate Set update -+ * when STA record is created under AP Mode. -+ * Update Desired Non-HT Rate Set. -+ * -+ * 12 30 2010 eddie.chen -+ * [WCXRP00000322] Add WMM IE in beacon, -+ -+Add per station flow control when STA is in PS -+ -+ * Recover the code that was coverwritted.. -+ * -+ * 12 29 2010 eddie.chen -+ * [WCXRP00000322] Add WMM IE in beacon, -+Add per station flow control when STA is in PS -+ -+ * 1) PS flow control event -+ * -+ * 2) WMM IE in beacon, assoc resp, probe resp -+ * -+ * 11 04 2010 wh.su -+ * [WCXRP00000164] [MT6620 Wi-Fi][Driver] Support the p2p random SSID -+ * adding the p2p random ssid support. -+ * -+ * 10 18 2010 cp.wu -+ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning -+ * use definition macro to replace hard-coded constant -+ * -+ * 09 28 2010 wh.su -+ * NULL -+ * [WCXRP00000069][MT6620 Wi-Fi][Driver] Fix some code for phase 1 P2P Demo. -+ * -+ * 09 27 2010 chinghwa.yu -+ * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000065] Update BoW design and settings -+ * Update BCM/BoW design and settings. -+ * -+ * 09 16 2010 cm.chang -+ * NULL -+ * Change conditional compiling options for BOW -+ * -+ * 09 03 2010 kevin.huang -+ * NULL -+ * Refine #include sequence and solve recursive/nested #include issue -+ * -+ * 09 01 2010 wh.su -+ * NULL -+ * adding the wapi support for integration test. -+ * -+ * 08 30 2010 cp.wu -+ * NULL -+ * eliminate klockwork errors -+ * -+ * 08 16 2010 yuche.tsai -+ * NULL -+ * Add SSID IE in assoc req frame which is sent by P2P GC. -+ * -+ * 08 16 2010 kevin.huang -+ * NULL -+ * Refine AAA functions -+ * -+ * 08 03 2010 cp.wu -+ * NULL -+ * surpress compilation warning. -+ * -+ * 07 20 2010 wh.su -+ * -+ * adding the wapi code. -+ * -+ * 07 09 2010 yarco.yang -+ * -+ * [MT6620 and MT5931] SW Migration: Add ADDBA support -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 07 08 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * take use of RLM module for parsing/generating HT IEs for 11n capability -+ * -+ * 07 01 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * comment out RSN IE generation by CFG_RSN_MIGRATION compilation flag. -+ * -+ * 06 28 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * send MMPDU in basic rate. -+ * -+ * 06 21 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add scan_fsm into building. -+ * -+ * 06 21 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * specify correct value for management frames. -+ * -+ * 06 18 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Provide cnmMgtPktAlloc() and alloc/free function of msg/buf -+ * -+ * 06 18 2010 wh.su -+ * [WPD00003840][MT6620 5931] Security migration -+ * migration from MT6620 firmware. -+ * -+ * 06 15 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * revised. -+ * -+ * 06 14 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add management dispatching function table. -+ * -+ * 06 11 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * auth.c is migrated. -+ * -+ * 06 11 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) migrate assoc.c. -+ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness -+ * 3) add configuration options for CNM_MEM and RSN modules -+ * 4) add data path for management frames -+ * 5) eliminate rPacketInfo of MSDU_INFO_T -+ * -+ * 05 24 2010 kevin.huang -+ * [BORA00000794][WIFISYS][New Feature]Power Management Support -+ * Update assocProcessRxAssocReqFrame() to avoid redundant SSID IE {0,0} for IOT. -+ * -+ * 05 14 2010 kevin.huang -+ * [BORA00000794][WIFISYS][New Feature]Power Management Support -+ * Fix compile warning - macro > 10 line, initial value of an array -+ * -+ * 04 24 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * g_aprBssInfo[] depends on CFG_SUPPORT_P2P and CFG_SUPPORT_BOW -+ * -+ * 04 22 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * First draft code to support protection in AP mode -+ * -+ * 04 19 2010 kevin.huang -+ * [BORA00000714][WIFISYS][New Feature]Beacon Timeout Support -+ * Add Beacon Timeout Support -+ * * * * * * * * and will send Null frame to diagnose connection -+ * -+ * 04 16 2010 wh.su -+ * [BORA00000680][MT6620] Support the statistic for Micxxsoft os query -+ * adding the wpa-none for ibss beacon. -+ * -+ * 03 25 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Remove compiling warning -+ * -+ * 03 24 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Not carry HT cap when being associated with b/g only AP -+ * -+ * 02 04 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Add AAA Module Support, Revise Net Type to Net Type Index for array lookup -+ * -+ * 01 28 2010 wh.su -+ * [BORA00000476][Wi-Fi][firmware] Add the security module initialize code -+ * fixed the compiling warning.u1rwduu`wvpghlqg|rm+vp -+ * -+ * 01 27 2010 wh.su -+ * [BORA00000476][Wi-Fi][firmware] Add the security module initialize code -+ * add and fixed some security function. -+ * -+ * 01 11 2010 kevin.huang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Add Deauth and Disassoc Handler -+ * -+ * 01 07 2010 kevin.huang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Update Assoc ID for PS -+ * -+ * 01 04 2010 tehuang.liu -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * For working out the first connection Chariot-verified version -+ * -+ * 12 18 2009 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * . -+ * -+ * Dec 12 2009 mtk01104 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Use new constant definition ELEM_MAX_LEN_EXT_CAP -+ * -+ * Dec 9 2009 mtk01104 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Modify assoc req IE talbe for HT cap IE -+ * -+ * Dec 7 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * update the assocComposeReAssocReqFrameHeader() and fix the u2EstimatedFrameLen in assocSendReAssocReqFrame() -+ * -+ * Dec 7 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * remove some space line -+ * -+ * Dec 7 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * adding the sending disassoc frame function -+ * -+ * Dec 4 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * adding the txassocReq IE table, adding for WPA/RSN -+ * -+ * Dec 3 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Fix eNetType not init in send AssocReq function -+ * -+ * Dec 3 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Integrate the send Assoc with TXM -+ * -+ * Dec 1 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * adding the code to indicate the assoc request and assoc response (now disable) -+ * -+ * Nov 24 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Remove unused variables -+ * -+ * Nov 23 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "precomp.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+APPEND_VAR_IE_ENTRY_T txAssocReqIETable[] = { -+ {(ELEM_HDR_LEN + ELEM_MAX_LEN_HT_CAP), NULL, rlmReqGenerateHtCapIE} -+ , /* 45 */ -+#if CFG_SUPPORT_WPS2 -+ {(ELEM_HDR_LEN + ELEM_MAX_LEN_WSC), NULL, rsnGenerateWSCIE} -+ , /* 221 */ -+#endif -+#if CFG_RSN_MIGRATION -+ {(ELEM_HDR_LEN + ELEM_MAX_LEN_RSN), NULL, rsnGenerateRSNIE} -+ , /* 48 */ -+#endif -+#if CFG_SUPPORT_WAPI -+ {(ELEM_HDR_LEN + ELEM_MAX_LEN_WAPI), NULL, wapiGenerateWAPIIE} -+ , /* 68 */ -+#endif -+#if CFG_SUPPORT_HOTSPOT_2_0 -+ {(ELEM_HDR_LEN + ELEM_MAX_LEN_INTERWORKING), NULL, hs20GenerateInterworkingIE} -+ , /* 107 */ -+ {(ELEM_HDR_LEN + ELEM_MAX_LEN_ROAMING_CONSORTIUM), NULL, hs20GenerateRoamingConsortiumIE} -+ , /* 111 */ -+#endif -+ {(ELEM_HDR_LEN + ELEM_MAX_LEN_EXT_CAP), NULL, rlmReqGenerateExtCapIE} -+ , /* 127 */ -+#if CFG_SUPPORT_HOTSPOT_2_0 -+ {(ELEM_HDR_LEN + ELEM_MAX_LEN_HS20_INDICATION), NULL, hs20GenerateHS20IE} -+ , /* 221 */ -+#endif -+ {(ELEM_HDR_LEN + ELEM_MAX_LEN_WMM_INFO), NULL, mqmGenerateWmmInfoIE} -+ , /* 221 */ -+#if CFG_RSN_MIGRATION -+ {(ELEM_HDR_LEN + ELEM_MAX_LEN_WPA), NULL, rsnGenerateWPAIE} -+ , /* 221 */ -+#endif -+}; -+ -+#if CFG_SUPPORT_AAA -+VERIFY_IE_ENTRY_T rxAssocReqIETable[] = { -+ {ELEM_ID_RESERVED, NULL} /* 255 */ -+}; -+ -+APPEND_VAR_IE_ENTRY_T txAssocRespIETable[] = { -+ {(ELEM_HDR_LEN + ELEM_MAX_LEN_ERP), NULL, rlmRspGenerateErpIE} -+ , /* 42 */ -+ {(ELEM_HDR_LEN + ELEM_MAX_LEN_HT_CAP), NULL, rlmRspGenerateHtCapIE} -+ , /* 45 */ -+ {(ELEM_HDR_LEN + ELEM_MAX_LEN_HT_OP), NULL, rlmRspGenerateHtOpIE} -+ , /* 61 */ -+#if CFG_ENABLE_WIFI_DIRECT -+ {(ELEM_HDR_LEN + ELEM_MAX_LEN_OBSS_SCAN), NULL, rlmRspGenerateObssScanIE} -+ , /* 74 */ -+ {(0), p2pFuncCalculateP2p_IELenForAssocRsp, p2pFuncGenerateP2p_IEForAssocRsp} -+ , /* 221 */ -+#if CFG_SUPPORT_WFD -+ {(0), wfdFuncCalculateWfdIELenForAssocRsp, wfdFuncGenerateWfdIEForAssocRsp} -+ , /* 221 */ -+#endif -+#endif -+ {(ELEM_HDR_LEN + ELEM_MAX_LEN_EXT_CAP), NULL, rlmRspGenerateExtCapIE} -+ , /* 127 */ -+ {(ELEM_HDR_LEN + ELEM_MAX_LEN_WMM_PARAM), NULL, mqmGenerateWmmParamIE} -+ , /* 221 */ -+ -+ {(0), p2pFuncCalculateWSC_IELenForAssocRsp, p2pFuncGenerateWSC_IEForAssocRsp} /* 221 */ -+ -+}; -+#endif -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is used to compose the Capability Info Field. -+* -+* @param[in] prStaRec Pointer to the STA_RECORD_T -+* -+* @retval Capability Info Field -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT_16 -+assocBuildCapabilityInfo(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec) -+{ -+ UINT_32 u4NonHTPhyType; -+ UINT_16 u2CapInfo; -+ -+ /* Set up our requested capabilities. */ -+ u2CapInfo = CAP_INFO_ESS; -+ u2CapInfo |= CAP_CF_STA_NOT_POLLABLE; -+ -+ if (prStaRec == NULL) -+ u2CapInfo |= CAP_INFO_PRIVACY; -+ else { -+ if (prStaRec->u2CapInfo & CAP_INFO_PRIVACY) -+ u2CapInfo |= CAP_INFO_PRIVACY; -+ } -+ -+ /* 7.3.1.4 */ -+ if (prStaRec == NULL) { -+ if ((prAdapter->rWifiVar.ePreambleType == PREAMBLE_TYPE_SHORT) ||/* ShortPreambleOptionEnable is TRUE */ -+ (prAdapter->rWifiVar.ePreambleType == PREAMBLE_TYPE_AUTO)) -+ u2CapInfo |= CAP_INFO_SHORT_PREAMBLE; -+ if (prAdapter->rWifiVar.fgIsShortSlotTimeOptionEnable) -+ u2CapInfo |= CAP_INFO_SHORT_SLOT_TIME; -+ } else if (prStaRec->fgHasBasicPhyType) { -+ u4NonHTPhyType = prStaRec->ucNonHTBasicPhyType; -+ -+ if ((rNonHTPhyAttributes[u4NonHTPhyType].fgIsShortPreambleOptionImplemented) && -+ /* Short Preamble Option Enable is TRUE */ -+ ((prAdapter->rWifiVar.ePreambleType == PREAMBLE_TYPE_SHORT) || -+ ((prAdapter->rWifiVar.ePreambleType == PREAMBLE_TYPE_AUTO) && -+ (prStaRec->u2CapInfo & CAP_INFO_SHORT_PREAMBLE)))) { -+ -+ /* Case I: Implemented == TRUE and Short Preamble Option Enable == TRUE. -+ * Case II: Implemented == TRUE and Short Preamble == AUTO (depends on -+ * BSS_DESC_T's capability) -+ */ -+ u2CapInfo |= CAP_INFO_SHORT_PREAMBLE; -+ } -+#if CFG_SUPPORT_SPEC_MGMT /*Add by Enlai */ -+ /* Support 802.11h */ -+ if (prStaRec->u2CapInfo & CAP_INFO_SPEC_MGT) { -+ /* -+ 1. The Power Capability element shall be present if -+ dot11SpectrumManagementRequired is true. -+ -+ 2. A STA shall set dot11SpectrumManagementRequired to TRUE before -+ associating with a BSS or IBSS in which the Spectrum Management -+ bit is set to 1 in the Capability Information field in Beacon frames -+ and Probe Response frames received from the BSS or IBSS. -+ */ -+ if (prAdapter->fgEnable5GBand == TRUE) -+ u2CapInfo |= CAP_INFO_SPEC_MGT; -+ } -+#endif -+ -+ if (rNonHTPhyAttributes[u4NonHTPhyType].fgIsShortSlotTimeOptionImplemented && -+ prAdapter->rWifiVar.fgIsShortSlotTimeOptionEnable) { -+ u2CapInfo |= CAP_INFO_SHORT_SLOT_TIME; -+ } -+ } -+ -+ if (prStaRec) { -+ DBGLOG(SAA, LOUD, "ASSOC REQ: Compose Capability = 0x%04x for Target BSS [%pM].\n", -+ u2CapInfo, prStaRec->aucMacAddr); -+ } -+ -+ return u2CapInfo; -+ -+} /* end of assocBuildCapabilityInfo() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is used to compose Common Information Elements for Association -+* Request Frame. -+* -+* @param[in] prMsduInfo Pointer to the composed MSDU_INFO_T. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+static inline VOID assocBuildReAssocReqFrameCommonIEs(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo) -+{ -+ P_CONNECTION_SETTINGS_T prConnSettings; -+ P_STA_RECORD_T prStaRec; -+ PUINT_8 pucBuffer; -+ UINT_16 u2SupportedRateSet; -+ UINT_8 aucAllSupportedRates[RATE_NUM] = { 0 }; -+ UINT_8 ucAllSupportedRatesLen; -+ UINT_8 ucSupRatesLen; -+ UINT_8 ucExtSupRatesLen; -+ -+ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); -+ ASSERT(prMsduInfo); -+ ASSERT(prMsduInfo->eSrc == TX_PACKET_MGMT); -+ -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); -+ ASSERT(prStaRec); -+ -+ if (!prStaRec) -+ return; -+ -+ pucBuffer = (PUINT_8) ((ULONG) prMsduInfo->prPacket + (ULONG) prMsduInfo->u2FrameLength); -+ ASSERT(pucBuffer); -+ -+ if (IS_STA_IN_AIS(prStaRec)) { -+ -+ /* Fill the SSID element. */ -+ SSID_IE(pucBuffer)->ucId = ELEM_ID_SSID; -+ -+ /* NOTE(Kevin): We copy the SSID from CONNECTION_SETTINGS for the case of -+ * Passive Scan and the target BSS didn't broadcast SSID on its Beacon Frame. -+ */ -+ -+ COPY_SSID(SSID_IE(pucBuffer)->aucSSID, -+ SSID_IE(pucBuffer)->ucLength, prConnSettings->aucSSID, prConnSettings->ucSSIDLen); -+ -+ prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer); -+ pucBuffer += IE_SIZE(pucBuffer); -+ -+ } -+#if CFG_ENABLE_WIFI_DIRECT -+ else if ((prAdapter->fgIsP2PRegistered) && (IS_STA_IN_P2P(prStaRec))) -+ pucBuffer = p2pBuildReAssocReqFrameCommonIEs(prAdapter, prMsduInfo, pucBuffer); -+#endif -+#if CFG_ENABLE_BT_OVER_WIFI -+ else if (IS_STA_IN_BOW(prStaRec)) { -+ -+ SSID_IE(pucBuffer)->ucId = ELEM_ID_SSID; -+ -+ /* NOTE(Kevin): We copy the SSID from CONNECTION_SETTINGS for the case of -+ * Passive Scan and the target BSS didn't broadcast SSID on its Beacon Frame. -+ */ -+ -+ COPY_SSID(SSID_IE(pucBuffer)->aucSSID, -+ SSID_IE(pucBuffer)->ucLength, prConnSettings->aucSSID, prConnSettings->ucSSIDLen); -+ -+ prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer); -+ pucBuffer += IE_SIZE(pucBuffer); -+ } -+#endif -+ else { -+ /* Do nothing */ -+ /* TODO(Kevin): For other network */ -+ } -+ -+ /* NOTE(Kevin 2008/12/19): 16.3.6.3 MLME-ASSOCIATE.indication - -+ * SupportedRates - The set of data rates that are supported by the STA -+ * that is requesting association. -+ * Original(Portable Driver): Only send the Rates that we'll support. -+ * New: Send the Phy Rates if the result of following & operation == NULL. -+ */ -+ /* rateGetDataRatesFromRateSet((prBssDesc->u2OperationalRateSet & */ -+ /* rPhyAttributes[prBssDesc->ePhyType].u2SupportedRateSet), */ -+ -+ if (prStaRec->fgHasBasicPhyType) { -+ UINT_32 u4NonHTPhyType; -+ -+ u4NonHTPhyType = prStaRec->ucNonHTBasicPhyType; -+ -+ u2SupportedRateSet = (prStaRec->u2OperationalRateSet & -+ rNonHTPhyAttributes[u4NonHTPhyType].u2SupportedRateSet); -+ -+ ASSERT(u2SupportedRateSet); -+ -+ if (!u2SupportedRateSet) -+ u2SupportedRateSet = rNonHTPhyAttributes[u4NonHTPhyType].u2SupportedRateSet; -+ -+ /* TODO(Kevin): For P2P, we shouldn't send support rate set which contains 11b rate */ -+ -+ rateGetDataRatesFromRateSet(u2SupportedRateSet, 0, aucAllSupportedRates, &ucAllSupportedRatesLen); -+ -+ ucSupRatesLen = ((ucAllSupportedRatesLen > ELEM_MAX_LEN_SUP_RATES) ? -+ ELEM_MAX_LEN_SUP_RATES : ucAllSupportedRatesLen); -+ -+ ucExtSupRatesLen = ucAllSupportedRatesLen - ucSupRatesLen; -+ -+ /* Fill the Supported Rates element. */ -+ if (ucSupRatesLen) { -+ SUP_RATES_IE(pucBuffer)->ucId = ELEM_ID_SUP_RATES; -+ SUP_RATES_IE(pucBuffer)->ucLength = ucSupRatesLen; -+ kalMemCopy(SUP_RATES_IE(pucBuffer)->aucSupportedRates, aucAllSupportedRates, ucSupRatesLen); -+ -+ prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer); -+ pucBuffer += IE_SIZE(pucBuffer); -+ } -+ -+ /* Fill the Extended Supported Rates element. */ -+ if (ucExtSupRatesLen) { -+ -+ EXT_SUP_RATES_IE(pucBuffer)->ucId = ELEM_ID_EXTENDED_SUP_RATES; -+ EXT_SUP_RATES_IE(pucBuffer)->ucLength = ucExtSupRatesLen; -+ -+ kalMemCopy(EXT_SUP_RATES_IE(pucBuffer)->aucExtSupportedRates, -+ &aucAllSupportedRates[ucSupRatesLen], ucExtSupRatesLen); -+ -+ prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer); -+ pucBuffer += IE_SIZE(pucBuffer); -+ } -+ -+ /* 7.3.2.19 Supported Channels element */ -+#if CFG_SUPPORT_DFS /* Add by Enlai */ -+ if (prAdapter->fgEnable5GBand == TRUE) { -+ SUPPORTED_CHANNELS_IE(pucBuffer)->ucId = ELEM_ID_SUP_CHS; -+ SUPPORTED_CHANNELS_IE(pucBuffer)->ucLength = 8; -+ -+ SUPPORTED_CHANNELS_IE(pucBuffer)->ucChannelNum[0] = 36; -+ SUPPORTED_CHANNELS_IE(pucBuffer)->ucChannelNum[1] = 4; -+ SUPPORTED_CHANNELS_IE(pucBuffer)->ucChannelNum[2] = 52; -+ SUPPORTED_CHANNELS_IE(pucBuffer)->ucChannelNum[3] = 4; -+/* Not China --- Start */ -+ /* SUPPORTED_CHANNELS_IE(pucBuffer)->ucChannelNum[4] = 100; */ -+ /* SUPPORTED_CHANNELS_IE(pucBuffer)->ucChannelNum[5] = 11; */ -+/* Not China --- End */ -+ SUPPORTED_CHANNELS_IE(pucBuffer)->ucChannelNum[4] = 149; -+ SUPPORTED_CHANNELS_IE(pucBuffer)->ucChannelNum[5] = 4; -+ SUPPORTED_CHANNELS_IE(pucBuffer)->ucChannelNum[6] = 165; -+ SUPPORTED_CHANNELS_IE(pucBuffer)->ucChannelNum[7] = 1; -+ -+ prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer); -+ pucBuffer += IE_SIZE(pucBuffer); -+ } -+#endif -+ } -+ -+} /* end of assocBuildReAssocReqFrameCommonIEs() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will compose the (Re)Association Request frame header and -+* its fixed fields -+* -+* @param[in] prStaRec Pointer to the STA_RECORD_T -+* @param[in] pucBuffer Pointer to the frame buffer. -+* @param[in] aucMACAddress Given Our MAC Address. -+* @param[in out] pu2PayloadLen Return the length of the composed fixed fields -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+static inline VOID -+assocComposeReAssocReqFrameHeaderAndFF(IN P_ADAPTER_T prAdapter, -+ IN P_STA_RECORD_T prStaRec, -+ IN PUINT_8 pucBuffer, IN UINT_8 aucMACAddress[], IN OUT PUINT_16 pu2PayloadLen) -+{ -+ P_WLAN_ASSOC_REQ_FRAME_T prAssocFrame; -+ BOOLEAN fgIsReAssoc; -+ -+ UINT_16 u2FrameCtrl; -+ UINT_16 u2CapInfo; -+ UINT_16 u2ListenInterval; -+ -+ ASSERT(prStaRec); -+ ASSERT(pucBuffer); -+ ASSERT(aucMACAddress); -+ ASSERT(pu2PayloadLen); -+ -+ prAssocFrame = (P_WLAN_ASSOC_REQ_FRAME_T) pucBuffer; -+ fgIsReAssoc = prStaRec->fgIsReAssoc; -+ -+ /* 4 <1> Compose the frame header of the (Re)Association Request frame. */ -+ /* Fill the Frame Control field. */ -+ if (fgIsReAssoc) -+ u2FrameCtrl = MAC_FRAME_REASSOC_REQ; -+ else -+ u2FrameCtrl = MAC_FRAME_ASSOC_REQ; -+ WLAN_SET_FIELD_16(&prAssocFrame->u2FrameCtrl, u2FrameCtrl); -+ -+ /* Fill the DA field with Target BSSID. */ -+ COPY_MAC_ADDR(prAssocFrame->aucDestAddr, prStaRec->aucMacAddr); -+ -+ /* Fill the SA field with our MAC Address. */ -+ COPY_MAC_ADDR(prAssocFrame->aucSrcAddr, aucMACAddress); -+ -+ /* Fill the BSSID field with Target BSSID. */ -+ COPY_MAC_ADDR(prAssocFrame->aucBSSID, prStaRec->aucMacAddr); -+ -+ /* Clear the SEQ/FRAG_NO field(HW won't overide the FRAG_NO, so we need to clear it). */ -+ prAssocFrame->u2SeqCtrl = 0; -+ -+ /* 4 <2> Compose the frame body's common fixed field part of the (Re)Association Request frame. */ -+ u2CapInfo = assocBuildCapabilityInfo(prAdapter, prStaRec); -+ -+ /* Fill the Capability Information field. */ -+ WLAN_SET_FIELD_16(&prAssocFrame->u2CapInfo, u2CapInfo); -+ -+ /* Calculate the listen interval for the maximum power mode. Currently, we -+ set it to the value 2 times DTIM period. */ -+ if (prStaRec->ucDTIMPeriod) { -+ u2ListenInterval = prStaRec->ucDTIMPeriod * DEFAULT_LISTEN_INTERVAL_BY_DTIM_PERIOD; -+ } else { -+ DBGLOG(SAA, TRACE, "Use default listen interval\n"); -+ u2ListenInterval = DEFAULT_LISTEN_INTERVAL; -+ } -+ prStaRec->u2ListenInterval = u2ListenInterval; -+ -+ /* Fill the Listen Interval field. */ -+ WLAN_SET_FIELD_16(&prAssocFrame->u2ListenInterval, u2ListenInterval); -+ -+ /* 4 <3> Compose the Current AP Address field for ReAssociation Request frame. */ -+ /* Fill the Current AP Address field. */ -+ if (prStaRec->fgIsReAssoc) { -+ if (IS_STA_IN_AIS(prStaRec)) { -+ -+ P_AIS_BSS_INFO_T prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ P_WLAN_REASSOC_REQ_FRAME_T prReAssocFrame = (P_WLAN_REASSOC_REQ_FRAME_T) prAssocFrame; -+ -+ COPY_MAC_ADDR(prReAssocFrame->aucCurrentAPAddr, prAisBssInfo->aucBSSID); -+ } else { -+ ASSERT(0); /* We don't support ReAssociation for other network */ -+ } -+ -+ *pu2PayloadLen = (CAP_INFO_FIELD_LEN + LISTEN_INTERVAL_FIELD_LEN + CURR_AP_ADDR_FIELD_LEN); -+ } else { -+ *pu2PayloadLen = (CAP_INFO_FIELD_LEN + LISTEN_INTERVAL_FIELD_LEN); -+ } -+ -+} /* end of assocComposeReAssocReqFrame() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will send the (Re)Association Request frame -+* -+* @param[in] prStaRec Pointer to the STA_RECORD_T -+* -+* @retval WLAN_STATUS_RESOURCES No available resource for frame composing. -+* @retval WLAN_STATUS_SUCCESS Successfully send frame to TX Module -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS assocSendReAssocReqFrame(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec) -+{ -+ P_MSDU_INFO_T prMsduInfo; -+ P_BSS_INFO_T prBssInfo; -+ -+ UINT_16 u2PayloadLen; -+ UINT_16 u2EstimatedFrameLen; -+ UINT_16 u2EstimatedExtraIELen; -+ BOOLEAN fgIsReAssoc; -+ UINT_32 i; -+ -+ ASSERT(prStaRec); -+ -+ /* 4 <1> Allocate a PKT_INFO_T for Authentication Frame */ -+ fgIsReAssoc = prStaRec->fgIsReAssoc; -+ -+ /* Init with MGMT Header Length + Length of Fixed Fields + Common IE Length */ -+ if (fgIsReAssoc) { -+ u2EstimatedFrameLen = MAC_TX_RESERVED_FIELD + -+ WLAN_MAC_MGMT_HEADER_LEN + -+ CAP_INFO_FIELD_LEN + -+ LISTEN_INTERVAL_FIELD_LEN + -+ CURR_AP_ADDR_FIELD_LEN + -+ (ELEM_HDR_LEN + ELEM_MAX_LEN_SSID) + -+ (ELEM_HDR_LEN + ELEM_MAX_LEN_SUP_RATES) + (ELEM_HDR_LEN + (RATE_NUM - ELEM_MAX_LEN_SUP_RATES)); -+ } else { -+ u2EstimatedFrameLen = MAC_TX_RESERVED_FIELD + -+ WLAN_MAC_MGMT_HEADER_LEN + -+ CAP_INFO_FIELD_LEN + -+ LISTEN_INTERVAL_FIELD_LEN + -+ (ELEM_HDR_LEN + ELEM_MAX_LEN_SSID) + -+ (ELEM_HDR_LEN + ELEM_MAX_LEN_SUP_RATES) + (ELEM_HDR_LEN + (RATE_NUM - ELEM_MAX_LEN_SUP_RATES)); -+ } -+ -+ /* + Extra IE Length */ -+ u2EstimatedExtraIELen = 0; -+ -+#if CFG_ENABLE_WIFI_DIRECT_CFG_80211 && CFG_ENABLE_WIFI_DIRECT -+ if (prStaRec->ucNetTypeIndex == NETWORK_TYPE_P2P_INDEX) { -+ if ((prAdapter->fgIsP2PRegistered)) { -+ u2EstimatedExtraIELen = p2pCalculate_IEForAssocReq(prAdapter, -+ prStaRec->ucNetTypeIndex, prStaRec); -+ } else { -+ DBGLOG(P2P, TRACE, "Function Linker Lost.\n"); -+ ASSERT(FALSE); -+ } -+ } else { -+ for (i = 0; i < sizeof(txAssocReqIETable) / sizeof(APPEND_VAR_IE_ENTRY_T); i++) { -+ if (txAssocReqIETable[i].u2EstimatedFixedIELen != 0) { -+ u2EstimatedExtraIELen += txAssocReqIETable[i].u2EstimatedFixedIELen; -+ } else { -+ u2EstimatedExtraIELen += -+ (UINT_16) txAssocReqIETable[i].pfnCalculateVariableIELen(prAdapter, -+ prStaRec->ucNetTypeIndex, -+ prStaRec); -+ } -+ } -+ } -+#else -+ for (i = 0; i < sizeof(txAssocReqIETable) / sizeof(APPEND_VAR_IE_ENTRY_T); i++) { -+ if (txAssocReqIETable[i].u2EstimatedFixedIELen != 0) { -+ u2EstimatedExtraIELen += txAssocReqIETable[i].u2EstimatedFixedIELen; -+ } else { -+ u2EstimatedExtraIELen += (UINT_16) txAssocReqIETable[i].pfnCalculateVariableIELen(prAdapter, -+ prStaRec->ucNetTypeIndex, -+ prStaRec); -+ } -+ } -+#endif -+ -+ u2EstimatedFrameLen += u2EstimatedExtraIELen; -+ -+ /* Allocate a MSDU_INFO_T */ -+ prMsduInfo = cnmMgtPktAlloc(prAdapter, u2EstimatedFrameLen); -+ if (prMsduInfo == NULL) { -+ DBGLOG(SAA, WARN, "No PKT_INFO_T for sending (Re)Assoc Request.\n"); -+ return WLAN_STATUS_RESOURCES; -+ } -+ /* 4 <2> Compose (Re)Association Request frame header and fixed fields in MSDU_INfO_T. */ -+ ASSERT(prStaRec->ucNetTypeIndex < NETWORK_TYPE_INDEX_NUM); -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]); -+ -+ /* Compose Header and Fixed Field */ -+ assocComposeReAssocReqFrameHeaderAndFF(prAdapter, -+ prStaRec, -+ (PUINT_8) ((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD), -+ prBssInfo->aucOwnMacAddr, &u2PayloadLen); -+ -+ /* 4 <3> Update information of MSDU_INFO_T */ -+ prMsduInfo->eSrc = TX_PACKET_MGMT; -+ prMsduInfo->ucPacketType = HIF_TX_PACKET_TYPE_MGMT; -+ prMsduInfo->ucStaRecIndex = prStaRec->ucIndex; -+ prMsduInfo->ucNetworkType = prStaRec->ucNetTypeIndex; -+ prMsduInfo->ucMacHeaderLength = WLAN_MAC_MGMT_HEADER_LEN; -+ prMsduInfo->fgIs802_1x = FALSE; -+ prMsduInfo->fgIs802_11 = TRUE; -+ prMsduInfo->u2FrameLength = WLAN_MAC_MGMT_HEADER_LEN + u2PayloadLen; -+ prMsduInfo->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter); -+ prMsduInfo->pfTxDoneHandler = saaFsmRunEventTxDone; -+ prMsduInfo->fgIsBasicRate = TRUE; -+ -+ /* 4 <4> Compose the frame body's IEs of the (Re)Association Request frame. */ -+ assocBuildReAssocReqFrameCommonIEs(prAdapter, prMsduInfo); -+ -+ /* 4 <5> Compose IEs in MSDU_INFO_T */ -+#if CFG_ENABLE_WIFI_DIRECT_CFG_80211 && CFG_ENABLE_WIFI_DIRECT -+ if (prStaRec->ucNetTypeIndex == NETWORK_TYPE_P2P_INDEX) { -+ if ((prAdapter->fgIsP2PRegistered)) { -+ p2pGenerate_IEForAssocReq(prAdapter, prMsduInfo); -+ } else { -+ DBGLOG(P2P, TRACE, "Function Linker Lost.\n"); -+ ASSERT(FALSE); -+ } -+ } else { -+ /* Append IE */ -+ for (i = 0; i < sizeof(txAssocReqIETable) / sizeof(APPEND_VAR_IE_ENTRY_T); i++) { -+ if (txAssocReqIETable[i].pfnAppendIE) -+ txAssocReqIETable[i].pfnAppendIE(prAdapter, prMsduInfo); -+ } -+ } -+#else -+ /* Append IE */ -+ for (i = 0; i < sizeof(txAssocReqIETable) / sizeof(APPEND_VAR_IE_ENTRY_T); i++) { -+ if (txAssocReqIETable[i].pfnAppendIE) -+ txAssocReqIETable[i].pfnAppendIE(prAdapter, prMsduInfo); -+ } -+#endif -+ -+ /* 4 <6> Update the (Re)association request information */ -+ if (IS_STA_IN_AIS(prStaRec)) { -+ P_WLAN_ASSOC_REQ_FRAME_T prAssocFrame; -+ -+ prAssocFrame = (P_WLAN_ASSOC_REQ_FRAME_T) ((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD); -+ -+#if CFG_RSN_MIGRATION -+ kalUpdateReAssocReqInfo(prAdapter->prGlueInfo, -+ (PUINT_8) &prAssocFrame->u2CapInfo, -+ prMsduInfo->u2FrameLength - offsetof(WLAN_ASSOC_REQ_FRAME_T, u2CapInfo), -+ fgIsReAssoc); -+#endif -+ } -+#if CFG_ENABLE_WIFI_DIRECT -+ if ((prAdapter->fgIsP2PRegistered) && (IS_STA_IN_P2P(prStaRec))) { -+ P_WLAN_ASSOC_REQ_FRAME_T prAssocFrame; -+ -+ prAssocFrame = (P_WLAN_ASSOC_REQ_FRAME_T) ((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD); -+ -+ kalP2PUpdateAssocInfo(prAdapter->prGlueInfo, -+ (PUINT_8) &prAssocFrame->u2CapInfo, -+ prMsduInfo->u2FrameLength - offsetof(WLAN_ASSOC_REQ_FRAME_T, u2CapInfo), -+ fgIsReAssoc); -+ } -+#endif -+ -+ /* TODO(Kevin): Also release the unused tail room of the composed MMPDU */ -+ -+ /* 4 <6> Enqueue the frame to send this (Re)Association request frame. */ -+ DBGLOG(SAA, INFO, "Sending (Re)Assoc Request, network: %d seqNo: %d\n", -+ prMsduInfo->ucNetworkType, prMsduInfo->ucTxSeqNum); -+ nicTxEnqueueMsdu(prAdapter, prMsduInfo); -+ -+ return WLAN_STATUS_SUCCESS; -+} /* end of assocSendReAssocReqFrame() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will strictly check the TX (Re)Association Request frame for -+* SAA event handling. -+* -+* @param[in] prMsduInfo Pointer of MSDU_INFO_T -+* -+* @retval WLAN_STATUS_FAILURE This is not the frame we should handle at current state. -+* @retval WLAN_STATUS_SUCCESS This is the frame we should handle. -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS assocCheckTxReAssocReqFrame(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo) -+{ -+ P_WLAN_ASSOC_REQ_FRAME_T prAssocReqFrame; -+ P_STA_RECORD_T prStaRec; -+ UINT_16 u2TxFrameCtrl; -+ -+ ASSERT(prMsduInfo); -+ ASSERT(prMsduInfo->eSrc == TX_PACKET_MGMT); -+ -+ prAssocReqFrame = (P_WLAN_ASSOC_REQ_FRAME_T) (prMsduInfo->prPacket); -+ ASSERT(prAssocReqFrame); -+ -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); -+ ASSERT(prStaRec); -+ -+ if (!prStaRec) -+ return WLAN_STATUS_INVALID_PACKET; -+ /* WLAN_GET_FIELD_16(&prAssocReqFrame->u2FrameCtrl, &u2TxFrameCtrl) */ -+ u2TxFrameCtrl = prAssocReqFrame->u2FrameCtrl; /* NOTE(Kevin): Optimized for ARM */ -+ u2TxFrameCtrl &= MASK_FRAME_TYPE; -+ if (prStaRec->fgIsReAssoc) { -+ if (u2TxFrameCtrl != MAC_FRAME_REASSOC_REQ) -+ return WLAN_STATUS_FAILURE; -+ } else { -+ if (u2TxFrameCtrl != MAC_FRAME_ASSOC_REQ) -+ return WLAN_STATUS_FAILURE; -+ } -+ -+ return WLAN_STATUS_SUCCESS; -+ -+} /* end of assocCheckTxReAssocReqFrame() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will strictly check the TX (Re)Association Response frame for -+* AAA event handling. -+* -+* @param[in] prMsduInfo Pointer of MSDU_INFO_T -+* -+* @retval WLAN_STATUS_FAILURE This is not the frame we should handle at current state. -+* @retval WLAN_STATUS_SUCCESS This is the frame we should handle. -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS assocCheckTxReAssocRespFrame(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo) -+{ -+ P_WLAN_ASSOC_RSP_FRAME_T prAssocRspFrame; -+ P_STA_RECORD_T prStaRec; -+ UINT_16 u2TxFrameCtrl; -+ -+ ASSERT(prMsduInfo); -+ ASSERT(prMsduInfo->eSrc == TX_PACKET_MGMT); -+ -+ prAssocRspFrame = (P_WLAN_ASSOC_RSP_FRAME_T) (prMsduInfo->prPacket); -+ ASSERT(prAssocRspFrame); -+ -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); -+ ASSERT(prStaRec); -+ -+ if (!prStaRec) -+ return WLAN_STATUS_INVALID_PACKET; -+ /* WLAN_GET_FIELD_16(&prAssocFrame->u2FrameCtrl, &u2TxFrameCtrl) */ -+ u2TxFrameCtrl = prAssocRspFrame->u2FrameCtrl; /* NOTE(Kevin): Optimized for ARM */ -+ u2TxFrameCtrl &= MASK_FRAME_TYPE; -+ if (prStaRec->fgIsReAssoc) { -+ if (u2TxFrameCtrl != MAC_FRAME_REASSOC_RSP) -+ return WLAN_STATUS_FAILURE; -+ } else { -+ if (u2TxFrameCtrl != MAC_FRAME_ASSOC_RSP) -+ return WLAN_STATUS_FAILURE; -+ } -+ -+ return WLAN_STATUS_SUCCESS; -+ -+} /* end of assocCheckTxReAssocRespFrame() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will validate the incoming (Re)Association Frame and take out -+* the status code. -+* -+* @param[in] prSwRfb Pointer to SW RFB data structure. -+* @param[out] pu2StatusCode Pointer to store the Status Code from Authentication. -+* -+* @retval WLAN_STATUS_FAILURE This is not the frame we should handle at current state. -+* @retval WLAN_STATUS_SUCCESS This is the frame we should handle. -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+assocCheckRxReAssocRspFrameStatus(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, OUT PUINT_16 pu2StatusCode) -+{ -+ P_STA_RECORD_T prStaRec; -+ P_WLAN_ASSOC_RSP_FRAME_T prAssocRspFrame; -+ UINT_16 u2RxFrameCtrl; -+ UINT_16 u2RxCapInfo; -+ UINT_16 u2RxStatusCode; -+ UINT_16 u2RxAssocId; -+ -+ ASSERT(prSwRfb); -+ ASSERT(pu2StatusCode); -+ -+ if ((prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen) < (CAP_INFO_FIELD_LEN + -+ STATUS_CODE_FIELD_LEN + AID_FIELD_LEN)) { -+ ASSERT(0); -+ return WLAN_STATUS_FAILURE; -+ } -+ -+ DBGLOG(SAA, LOUD, "prSwRfb->u2PayloadLength = %d\n", prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen); -+ -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); -+ ASSERT(prStaRec); -+ -+ if (!prStaRec) -+ return WLAN_STATUS_INVALID_PACKET; -+ /* 4 <1> locate the (Re)Association Resp Frame. */ -+ prAssocRspFrame = (P_WLAN_ASSOC_RSP_FRAME_T) prSwRfb->pvHeader; -+ -+ /* 4 <2> Parse the Header of (Re)Association Resp Frame. */ -+ /* WLAN_GET_FIELD_16(&prAssocRspFrame->u2FrameCtrl, &u2RxFrameCtrl); */ -+ u2RxFrameCtrl = prAssocRspFrame->u2FrameCtrl; /* NOTE(Kevin): Optimized for ARM */ -+ u2RxFrameCtrl &= MASK_FRAME_TYPE; -+ if (prStaRec->fgIsReAssoc) { -+ if (u2RxFrameCtrl != MAC_FRAME_REASSOC_RSP) -+ return WLAN_STATUS_FAILURE; -+ } else { -+ if (u2RxFrameCtrl != MAC_FRAME_ASSOC_RSP) -+ return WLAN_STATUS_FAILURE; -+ } -+ -+ /* 4 <3> Parse the Fixed Fields of (Re)Association Resp Frame Body. */ -+ /* WLAN_GET_FIELD_16(&prAssocRspFrame->u2CapInfo, &u2RxCapInfo); */ -+ u2RxCapInfo = prAssocRspFrame->u2CapInfo; /* NOTE(Kevin): Optimized for ARM */ -+ -+ /* WLAN_GET_FIELD_16(&prAssocRspFrame->u2StatusCode, &u2RxStatusCode); */ -+ u2RxStatusCode = prAssocRspFrame->u2StatusCode; /* NOTE(Kevin): Optimized for ARM */ -+ -+ /* 4 <4> Check CAP_INFO */ -+ /* NOTE(Kevin): CM suggest to add MGMT workaround for those APs didn't check -+ * the CAP Privacy Bit to overcome a corner case that the Privacy Bit -+ * of our SCAN result didn't consist with AP's Association Resp. -+ */ -+ if (u2RxStatusCode == STATUS_CODE_SUCCESSFUL) { -+#if CFG_SUPPORT_WAPI -+ if (prAdapter->rWifiVar.rConnSettings.fgWapiMode) { -+ /* WAPI AP allow the customer use WZC to join mode, the privacy bit is 0 */ -+ /* even at WAI & WAPI_PSK mode, but the assoc respose set the privacy bit set 1 */ -+ DBGLOG(SEC, TRACE, "Workaround the WAPI AP allow the customer to use WZC to join\n"); -+ } else -+#endif -+#if CFG_ENABLE_WIFI_DIRECT -+ if (prAdapter->fgIsP2PRegistered && 1) { -+ /* Todo:: Fixed this */ -+ } else -+#endif -+ { -+ } -+ -+#if CFG_STRICT_CHECK_CAPINFO_PRIVACY -+ if ((prStaRec->u2CapInfo & CAP_INFO_PRIVACY) ^ (u2RxCapInfo & CAP_INFO_PRIVACY)) -+ u2RxStatusCode = STATUS_CODE_CAP_NOT_SUPPORTED; -+#endif -+ } -+ -+ if (u2RxStatusCode == STATUS_CODE_SUCCESSFUL) { -+#if CFG_RSN_MIGRATION -+ /* Update the information in the structure used to query and set -+ OID_802_11_ASSOCIATION_INFORMATION. */ -+ kalUpdateReAssocRspInfo(prAdapter->prGlueInfo, -+ (PUINT_8) &prAssocRspFrame->u2CapInfo, (UINT_32) (prSwRfb->u2PacketLen)); -+#endif -+ } -+ /* 4 <5> Update CAP_INFO and ASSOC_ID */ -+ if (u2RxStatusCode == STATUS_CODE_SUCCESSFUL) { -+ prStaRec->u2CapInfo = u2RxCapInfo; -+ -+ /* WLAN_GET_FIELD_16(&prAssocRspFrame->u2AssocId, &u2RxAssocId); */ -+ u2RxAssocId = prAssocRspFrame->u2AssocId; /* NOTE(Kevin): Optimized for ARM */ -+ -+ /* 20110715 Workaround for Kingnet 710 AP (Realtek 8186) -+ * This AP raises the bit 6&7 not bit 14&15 in AID field. -+ * It cause wrong AID assignment. -+ * For AID = 2 -+ * Normal case: 0xC002(1100 0000 0000 0010) => 2 -+ * Kingnet 710: 0x00C2(0000 0000 1100 0010) => 194 -+ * workaround: mask bit 6&7 for this AP -+ */ -+ if ((u2RxAssocId & BIT(6)) && (u2RxAssocId & BIT(7)) && !(u2RxAssocId & BITS(8, 15))) { -+ prStaRec->u2AssocId = u2RxAssocId & ~BITS(6, 7); -+ } else { -+ prStaRec->u2AssocId = u2RxAssocId & ~AID_MSB; -+#if CFG_SUPPORT_802_11W -+ if (prStaRec->ucNetTypeIndex == NETWORK_TYPE_AIS_INDEX) { -+ P_AIS_SPECIFIC_BSS_INFO_T prBssSpecInfo; -+ -+ prBssSpecInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo; -+ ASSERT(prBssSpecInfo); -+ -+ prBssSpecInfo->ucSaQueryTimedOut = 0; -+ } -+#endif -+ } -+ } -+#if CFG_SUPPORT_802_11W -+ if (u2RxStatusCode == STATUS_CODE_AUTH_ALGORITHM_NOT_SUPPORTED) { -+ DBGLOG(SAA, INFO, "AP rejected due the authentication algorithm not support\n"); -+ } else if (u2RxStatusCode == STATUS_CODE_ASSOC_REJECTED_TEMPORARILY) { -+ PUINT_8 pucIE, pucTime; -+ UINT_16 u2IELength; -+ UINT_16 u2Offset = 0; -+ -+ u2IELength = prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen; -+ pucIE = (PUINT_8) ((ULONG) prSwRfb->pvHeader + prSwRfb->u2HeaderLen); -+ -+ IE_FOR_EACH(pucIE, u2IELength, u2Offset) { -+ if (ELEM_ID_TIMEOUT_INTERVAL == IE_ID(pucIE) && IE_LEN(pucIE) == 5) { -+ pucTime = ((P_IE_HDR_T) pucIE)->aucInfo; -+ if (pucTime[0] == ACTION_SA_TIMEOUT_ASSOC_COMEBACK) { -+ UINT_32 tu; -+ -+ WLAN_GET_FIELD_32(pucTime + 1, &tu); -+ DBGLOG(SAA, INFO, -+ "AP rejected association temporarily;comeback duration %u TU (%u ms)\n", -+ tu, TU_TO_MSEC(tu)); -+ if (tu > TX_ASSOCIATION_RETRY_TIMEOUT_TU) { -+ DBGLOG(SAA, INFO, "Update timer based on comeback duration\n"); -+ /* ieee80211_reschedule_timer(wpa_s, ms); */ -+ } -+ } -+ break; -+ } -+ } /* end of IE_FOR_EACH */ -+ } -+#endif -+ *pu2StatusCode = u2RxStatusCode; -+ -+ return WLAN_STATUS_SUCCESS; -+ -+} /* end of assocCheckRxReAssocRspFrameStatus() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will compose the Disassociation frame -+* -+* @param[in] prStaRec Pointer to the STA_RECORD_T -+* @param[in] pucBuffer Pointer to the frame buffer. -+* @param[in] aucMACAddress Given Our MAC Address. -+* @param[in] u2ReasonCode The reason code of disassociation -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+static inline VOID -+assocComposeDisassocFrame(IN P_STA_RECORD_T prStaRec, -+ IN PUINT_8 pucBuffer, IN UINT_8 aucMACAddress[], IN UINT_16 u2ReasonCode) -+{ -+ P_WLAN_DISASSOC_FRAME_T prDisAssocFrame; -+ UINT_16 u2FrameCtrl; -+ -+ ASSERT(pucBuffer); -+ ASSERT(pucBuffer); -+ ASSERT(aucMACAddress); -+ -+ prDisAssocFrame = (P_WLAN_DISASSOC_FRAME_T) pucBuffer; -+ -+ /* 4 <1> Compose the frame header of the DisAssociation frame. */ -+ /* Fill the Frame Control field. */ -+ u2FrameCtrl = MAC_FRAME_DISASSOC; -+ -+ WLAN_SET_FIELD_16(&prDisAssocFrame->u2FrameCtrl, u2FrameCtrl); -+ -+ /* Fill the DA field with Target BSSID. */ -+ COPY_MAC_ADDR(prDisAssocFrame->aucDestAddr, prStaRec->aucMacAddr); -+ -+ /* Fill the SA field with our MAC Address. */ -+ COPY_MAC_ADDR(prDisAssocFrame->aucSrcAddr, aucMACAddress); -+ -+ /* Fill the BSSID field with Target BSSID. */ -+ COPY_MAC_ADDR(prDisAssocFrame->aucBSSID, prStaRec->aucMacAddr); -+ -+ /* Clear the SEQ/FRAG_NO field(HW won't overide the FRAG_NO, so we need to clear it). */ -+ prDisAssocFrame->u2SeqCtrl = 0; -+ -+ /* 4 <2> Compose the frame body's fixed field part of the Disassociation frame. */ -+ /* Fill the Reason Code field. */ -+ WLAN_SET_FIELD_16(&prDisAssocFrame->u2ReasonCode, u2ReasonCode); -+ -+} /* end of assocComposeDisassocFrame() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will send the Disassociation frame -+* -+* @param[in] prStaRec Pointer to the STA_RECORD_T -+* @param[in] u2ReasonCode The reason code of disassociation -+* -+* @retval WLAN_STATUS_RESOURCES No available resource for frame composing. -+* @retval WLAN_STATUS_SUCCESS Successfully send frame to TX Module -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS assocSendDisAssocFrame(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN UINT_16 u2ReasonCode) -+{ -+ PUINT_8 pucMacAddress; -+ P_MSDU_INFO_T prMsduInfo; -+ UINT_16 u2PayloadLen; -+ UINT_16 u2EstimatedFrameLen; -+ /* UINT_32 u4Status = WLAN_STATUS_SUCCESS; */ -+ -+ ASSERT(prStaRec); -+ -+ /* 4 <1> Allocate a PKT_INFO_T for Disassociation Frame */ -+ /* Init with MGMT Header Length + Length of Fixed Fields + IE Length */ -+ u2EstimatedFrameLen = MAC_TX_RESERVED_FIELD + WLAN_MAC_MGMT_HEADER_LEN + REASON_CODE_FIELD_LEN; -+ -+ /* Allocate a MSDU_INFO_T */ -+ prMsduInfo = cnmMgtPktAlloc(prAdapter, u2EstimatedFrameLen); -+ if (prMsduInfo == NULL) { -+ DBGLOG(SAA, WARN, "No PKT_INFO_T for sending DisAssoc.\n"); -+ return WLAN_STATUS_RESOURCES; -+ } -+ /* 4 <2> Compose Disassociation frame header and fixed fields in MSDU_INfO_T. */ -+ ASSERT(prStaRec->ucNetTypeIndex < NETWORK_TYPE_INDEX_NUM); -+ -+ pucMacAddress = prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex].aucOwnMacAddr; -+ -+ /* Compose Header and Fixed Field */ -+ assocComposeDisassocFrame(prStaRec, -+ (PUINT_8) ((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD), -+ pucMacAddress, u2ReasonCode); -+ -+#if CFG_SUPPORT_802_11W -+ if (rsnCheckBipKeyInstalled(prAdapter, prStaRec)) { -+ P_WLAN_DISASSOC_FRAME_T prDisassocFrame; -+ -+ prDisassocFrame = -+ (P_WLAN_DEAUTH_FRAME_T) (PUINT_8) ((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD); -+ -+ prDisassocFrame->u2FrameCtrl |= MASK_FC_PROTECTED_FRAME; -+ DBGLOG(TX, WARN, "assocSendDisAssocFrame with protection\n"); -+ } -+#endif -+ -+ u2PayloadLen = REASON_CODE_FIELD_LEN; -+ -+ /* 4 <3> Update information of MSDU_INFO_T */ -+ ASSERT(prStaRec->ucNetTypeIndex < NETWORK_TYPE_INDEX_NUM); -+ -+ prMsduInfo->eSrc = TX_PACKET_MGMT; -+ prMsduInfo->ucPacketType = HIF_TX_PACKET_TYPE_MGMT; -+ prMsduInfo->ucStaRecIndex = prStaRec->ucIndex; -+ prMsduInfo->ucNetworkType = prStaRec->ucNetTypeIndex; -+ prMsduInfo->ucMacHeaderLength = WLAN_MAC_MGMT_HEADER_LEN; -+ prMsduInfo->fgIs802_1x = FALSE; -+ prMsduInfo->fgIs802_11 = TRUE; -+ prMsduInfo->u2FrameLength = WLAN_MAC_MGMT_HEADER_LEN + u2PayloadLen; -+ prMsduInfo->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter); -+ prMsduInfo->pfTxDoneHandler = NULL; -+ prMsduInfo->fgIsBasicRate = TRUE; -+ -+ /* 4 <4> Enqueue the frame to send this (Re)Association request frame. */ -+ nicTxEnqueueMsdu(prAdapter, prMsduInfo); -+ -+ return WLAN_STATUS_SUCCESS; -+} /* end of assocSendDisAssocFrame() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will parse and process the incoming Disassociation frame -+* if the given BSSID is matched. -+* -+* @param[in] prSwRfb Pointer to SW RFB data structure. -+* @param[in] aucBSSID Given BSSID -+* @param[out] pu2ReasonCode Pointer to store the Reason Code from Deauthentication. -+* -+* @retval WLAN_STATUS_FAILURE This is not the frame we should handle at current state. -+* @retval WLAN_STATUS_SUCCESS This is the frame we should handle. -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+assocProcessRxDisassocFrame(IN P_ADAPTER_T prAdapter, -+ IN P_SW_RFB_T prSwRfb, IN UINT_8 aucBSSID[], OUT PUINT_16 pu2ReasonCode) -+{ -+ P_WLAN_DISASSOC_FRAME_T prDisassocFrame; -+ UINT_16 u2RxReasonCode; -+ -+ ASSERT(prSwRfb); -+ ASSERT(aucBSSID); -+ ASSERT(pu2ReasonCode); -+ -+ /* 4 <1> locate the Disassociation Frame. */ -+ prDisassocFrame = (P_WLAN_DISASSOC_FRAME_T) prSwRfb->pvHeader; -+ -+ /* 4 <2> Parse the Header of Disassociation Frame. */ -+ if ((prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen) < REASON_CODE_FIELD_LEN) { -+ ASSERT(0); -+ return WLAN_STATUS_FAILURE; -+ } -+ -+ /* Check if this Disassoc Frame is coming from Target BSSID */ -+ if (UNEQUAL_MAC_ADDR(prDisassocFrame->aucBSSID, aucBSSID)) { -+ DBGLOG(SAA, LOUD, "Ignore Disassoc Frame from other BSS [ %pM ]\n", -+ prDisassocFrame->aucSrcAddr); -+ return WLAN_STATUS_FAILURE; -+ } -+ /* 4 <3> Parse the Fixed Fields of Deauthentication Frame Body. */ -+ WLAN_GET_FIELD_16(&prDisassocFrame->u2ReasonCode, &u2RxReasonCode); -+ *pu2ReasonCode = u2RxReasonCode; -+ -+ return WLAN_STATUS_SUCCESS; -+ -+} /* end of assocProcessRxDisassocFrame() */ -+ -+#if CFG_SUPPORT_AAA -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will parse and process the incoming Association Req frame -+* and return a Status Code. -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* @param[in] prSwRfb Pointer to SW RFB data structure. -+* @param[out] pu2StatusCode Pointer to store the Status Code for carried in Association Response. -+* -+* @retval WLAN_STATUS_FAILURE This is not the frame we should handle at current state. -+* @retval WLAN_STATUS_SUCCESS This is the frame we should handle. -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS assocProcessRxAssocReqFrame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, OUT PUINT_16 pu2StatusCode) -+{ -+ P_WLAN_ASSOC_REQ_FRAME_T prAssocReqFrame; -+ P_STA_RECORD_T prStaRec; -+ P_BSS_INFO_T prBssInfo; -+ P_IE_SSID_T prIeSsid = (P_IE_SSID_T) NULL; -+ P_RSN_INFO_ELEM_T prIeRsn = (P_RSN_INFO_ELEM_T) NULL; -+ P_IE_SUPPORTED_RATE_T prIeSupportedRate = (P_IE_SUPPORTED_RATE_T) NULL; -+ P_IE_EXT_SUPPORTED_RATE_T prIeExtSupportedRate = (P_IE_EXT_SUPPORTED_RATE_T) NULL; -+ PUINT_8 pucIE, pucIEStart; -+ UINT_16 u2IELength; -+ UINT_16 u2Offset = 0; -+ UINT_16 u2StatusCode = STATUS_CODE_SUCCESSFUL; -+ UINT_16 u2RxFrameCtrl; -+ UINT_16 u2BSSBasicRateSet; -+ BOOLEAN fgIsUnknownBssBasicRate; -+ UINT_32 i; -+ -+ ASSERT(prAdapter); -+ ASSERT(prSwRfb); -+ ASSERT(pu2StatusCode); -+ -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); -+ -+ if (prStaRec == NULL) -+ return WLAN_STATUS_FAILURE; -+ /* 4 <1> locate the Association Req Frame. */ -+ prAssocReqFrame = (P_WLAN_ASSOC_REQ_FRAME_T) prSwRfb->pvHeader; -+ -+ /* 4 <2> Parse the Header of Association Req Frame. */ -+ if ((prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen) < (CAP_INFO_FIELD_LEN + LISTEN_INTERVAL_FIELD_LEN)) { -+ ASSERT(0); -+ return WLAN_STATUS_FAILURE; -+ } -+ -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]); -+ -+ /* Check if this Disassoc Frame is coming from Target BSSID */ -+ if (UNEQUAL_MAC_ADDR(prAssocReqFrame->aucBSSID, prBssInfo->aucBSSID)) -+ return WLAN_STATUS_FAILURE; /* Just Ignore this MMPDU */ -+ /* WLAN_GET_FIELD_16(&prAssocReqFrame->u2FrameCtrl, &u2RxFrameCtrl); */ -+ u2RxFrameCtrl = prAssocReqFrame->u2FrameCtrl; /* NOTE(Kevin): Optimized for ARM */ -+ u2RxFrameCtrl &= MASK_FRAME_TYPE; -+ if (MAC_FRAME_REASSOC_REQ == u2RxFrameCtrl) { -+ prStaRec->fgIsReAssoc = TRUE; -+ -+ u2IELength = (prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen) - -+ (UINT_16) (OFFSET_OF(WLAN_REASSOC_REQ_FRAME_T, aucInfoElem[0]) - WLAN_MAC_MGMT_HEADER_LEN); -+ -+ pucIEStart = pucIE = ((P_WLAN_REASSOC_REQ_FRAME_T) (prSwRfb->pvHeader))->aucInfoElem; -+ } else { -+ prStaRec->fgIsReAssoc = FALSE; -+ -+ u2IELength = (prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen) - -+ (UINT_16) (OFFSET_OF(WLAN_ASSOC_REQ_FRAME_T, aucInfoElem[0]) - WLAN_MAC_MGMT_HEADER_LEN); -+ -+ pucIEStart = pucIE = prAssocReqFrame->aucInfoElem; -+ } -+ -+ /* 4 <3> Parse the Fixed Fields of Assoc Req Frame Body. */ -+ prStaRec->u2CapInfo = prAssocReqFrame->u2CapInfo; -+ -+#if CFG_ENABLE_WIFI_DIRECT && CFG_ENABLE_HOTSPOT_PRIVACY_CHECK -+ if (prAdapter->fgIsP2PRegistered && IS_STA_IN_P2P(prStaRec)) { -+ if (((prStaRec->u2CapInfo & CAP_INFO_PRIVACY) && !kalP2PGetCipher(prAdapter->prGlueInfo))) { -+ u2StatusCode = STATUS_CODE_CAP_NOT_SUPPORTED; -+ DBGLOG(RSN, TRACE, "STA Assoc req privacy bit check fail\n"); -+ return WLAN_STATUS_SUCCESS; -+ } -+ } -+#endif -+ -+ prStaRec->u2ListenInterval = prAssocReqFrame->u2ListenInterval; -+ prStaRec->ucPhyTypeSet = 0; -+ -+ /* Might be legacy client or p2p gc. */ -+ prStaRec->eStaType = STA_TYPE_LEGACY_CLIENT; -+ -+ /* 4 <4> Parse the IE of Assoc Req Frame Body. */ -+ IE_FOR_EACH(pucIE, u2IELength, u2Offset) { -+ switch (IE_ID(pucIE)) { -+ case ELEM_ID_SSID: -+ if ((!prIeSsid) && /* NOTE(Kevin): Get SSID once */ -+ (IE_LEN(pucIE) <= ELEM_MAX_LEN_SSID)) { -+ prIeSsid = (P_IE_SSID_T) pucIE; -+ } -+ break; -+ -+ case ELEM_ID_SUP_RATES: -+ if ((!prIeSupportedRate) && (IE_LEN(pucIE) <= RATE_NUM)) -+ prIeSupportedRate = SUP_RATES_IE(pucIE); -+ break; -+ -+ case ELEM_ID_EXTENDED_SUP_RATES: -+ if (!prIeExtSupportedRate) -+ prIeExtSupportedRate = EXT_SUP_RATES_IE(pucIE); -+ break; -+ case ELEM_ID_HT_CAP: -+ prStaRec->ucPhyTypeSet |= PHY_TYPE_BIT_HT; -+ kalMemCopy(&prStaRec->u2HtCapInfo, &(HT_CAP_IE(pucIE)->u2HtCapInfo), 2); -+ break; -+ case ELEM_ID_RSN: -+#if CFG_ENABLE_WIFI_DIRECT && CFG_ENABLE_HOTSPOT_PRIVACY_CHECK -+ if (prAdapter->fgIsP2PRegistered && IS_STA_IN_P2P(prStaRec)) { -+ prIeRsn = RSN_IE(pucIE); -+ rsnParserCheckForRSNCCMPPSK(prAdapter, prIeRsn, &u2StatusCode); -+ if (u2StatusCode != STATUS_CODE_SUCCESSFUL) { -+ *pu2StatusCode = u2StatusCode; -+ return WLAN_STATUS_SUCCESS; -+ } -+ } -+#endif -+ break; -+ case ELEM_ID_VENDOR: -+#if CFG_ENABLE_WIFI_DIRECT -+ { -+ if ((prAdapter->fgIsP2PRegistered)) { -+ UINT_8 ucOuiType = 0; -+ -+ p2pFuncParseCheckForP2PInfoElem(prAdapter, pucIE, &ucOuiType); -+ -+ if (ucOuiType == VENDOR_OUI_TYPE_P2P) { -+ DBGLOG(P2P, TRACE, "Target Client is a P2P group client\n"); -+ prStaRec->eStaType = STA_TYPE_P2P_GC; -+ } -+ } -+ } -+#endif -+ break; -+ default: -+ for (i = 0; i < (sizeof(rxAssocReqIETable) / sizeof(VERIFY_IE_ENTRY_T)); i++) { -+ -+ if ((IE_ID(pucIE)) == rxAssocReqIETable[i].ucElemID) { -+ rxAssocReqIETable[i].pfnVarifyIE(prAdapter, prSwRfb, (P_IE_HDR_T) pucIE, -+ &u2StatusCode); -+ -+ if (u2StatusCode != STATUS_CODE_SUCCESSFUL) { -+ *pu2StatusCode = u2StatusCode; -+ return WLAN_STATUS_SUCCESS; -+ } -+ } -+ } -+ -+ break; -+ } -+ } /* end of IE_FOR_EACH */ -+ -+ /* parsing for WMM related information (2010/12/21) */ -+ mqmProcessAssocReq(prAdapter, prSwRfb, pucIEStart, u2IELength); -+ -+ do { -+ if (prIeSsid) { -+ if (UNEQUAL_SSID(prBssInfo->aucSSID, prBssInfo->ucSSIDLen, -+ prIeSsid->aucSSID, prIeSsid->ucLength)) { -+ -+ u2StatusCode = STATUS_CODE_UNSPECIFIED_FAILURE; -+ break; -+ } -+ } else { -+ u2StatusCode = STATUS_CODE_UNSPECIFIED_FAILURE; -+ break; -+ } -+ -+ prStaRec->u2OperationalRateSet = 0; -+ prStaRec->u2BSSBasicRateSet = 0; -+ -+ if (prIeSupportedRate || prIeExtSupportedRate) { -+ rateGetRateSetFromIEs(prIeSupportedRate, prIeExtSupportedRate, &prStaRec->u2OperationalRateSet, -+ &u2BSSBasicRateSet, /* Ignore any Basic Bit */ -+ &fgIsUnknownBssBasicRate); -+ -+ if ((prBssInfo->u2BSSBasicRateSet & prStaRec->u2OperationalRateSet) != -+ prBssInfo->u2BSSBasicRateSet) { -+ -+ u2StatusCode = STATUS_CODE_ASSOC_DENIED_RATE_NOT_SUPPORTED; -+ break; -+ } -+ -+ /* Accpet the Sta, update BSSBasicRateSet from Bss */ -+ -+ prStaRec->u2BSSBasicRateSet = prBssInfo->u2BSSBasicRateSet; -+ -+ prStaRec->u2DesiredNonHTRateSet = (prStaRec->u2OperationalRateSet & RATE_SET_ALL_ABG); -+ -+ if (BAND_2G4 == HIF_RX_HDR_GET_RF_BAND(prSwRfb->prHifRxHdr)) { -+#if 0 /* Marked by CMC 20111024 */ -+ /* check if support 11n */ -+ if (!(u2BSSBasicRateSet & RATE_SET_BIT_HT_PHY)) { -+ -+ if (prStaRec->u2OperationalRateSet & RATE_SET_OFDM) -+ prStaRec->ucPhyTypeSet |= PHY_TYPE_BIT_ERP; -+ -+ if ((!(u2BSSBasicRateSet & RATE_SET_OFDM)) && -+ (prStaRec->u2OperationalRateSet & RATE_SET_HR_DSSS)) { -+ prStaRec->ucPhyTypeSet |= PHY_TYPE_BIT_HR_DSSS; -+ -+ } -+ -+ } -+#else -+ if (prStaRec->u2OperationalRateSet & RATE_SET_OFDM) -+ prStaRec->ucPhyTypeSet |= PHY_TYPE_BIT_ERP; -+ if (prStaRec->u2OperationalRateSet & RATE_SET_HR_DSSS) -+ prStaRec->ucPhyTypeSet |= PHY_TYPE_BIT_HR_DSSS; -+#endif -+ } else { /* (BAND_5G == prBssDesc->eBande) */ -+#if 0 /* Marked by CMC 20111024 */ -+ if (!(u2BSSBasicRateSet & RATE_SET_BIT_HT_PHY)) -+ prStaRec->ucPhyTypeSet |= PHY_TYPE_BIT_OFDM; -+ ASSERT((prStaRec->u2OperationalRateSet & RATE_SET_HR_DSSS) == 0); -+#else -+ if (prStaRec->u2OperationalRateSet & RATE_SET_OFDM) -+ prStaRec->ucPhyTypeSet |= PHY_TYPE_BIT_OFDM; -+#endif -+ } -+ -+ } else { -+ ASSERT(0); -+ u2StatusCode = STATUS_CODE_ASSOC_DENIED_RATE_NOT_SUPPORTED; -+ break; -+ } -+ -+#if CFG_ENABLE_WIFI_DIRECT && CFG_ENABLE_HOTSPOT_PRIVACY_CHECK -+ if (prAdapter->fgIsP2PRegistered && IS_STA_IN_P2P(prStaRec)) { -+ if (prIeRsn) { -+ if (!kalP2PGetCipher(prAdapter->prGlueInfo)) { -+ u2StatusCode = STATUS_CODE_CIPHER_SUITE_REJECTED; -+ break; -+ } -+ } else { -+ prStaRec->rSecInfo.fgAllowOnly1x = FALSE; -+ if (kalP2PGetCipher(prAdapter->prGlueInfo)) { -+ /* Only Allow 1x */ -+ prStaRec->rSecInfo.fgAllowOnly1x = TRUE; -+ break; -+ } -+ } -+ } -+#endif -+ -+ } while (FALSE); -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ if (prAdapter->fgIsP2PRegistered && IS_STA_IN_P2P(prStaRec)) { -+#if 1 /* ICS */ -+ { -+ PUINT_8 cp = (PUINT_8) &prAssocReqFrame->u2CapInfo; -+ P_UINT_8 prNewAssocReqIe = NULL; -+ -+ if (u2IELength) { -+ prNewAssocReqIe = kalMemAlloc(u2IELength, VIR_MEM_TYPE); -+ if (NULL == prNewAssocReqIe) { -+ DBGLOG(AIS, WARN, "allocate memory for (Re)assocReqIe fail!\n"); -+ u2StatusCode = STATUS_CODE_INVALID_INFO_ELEMENT; -+ return WLAN_STATUS_FAILURE; -+ } -+ } -+ -+ if (prStaRec->fgIsReAssoc) -+ cp += 10; -+ else -+ cp += 4; -+ if (prStaRec->pucAssocReqIe) { -+ kalMemFree(prStaRec->pucAssocReqIe, VIR_MEM_TYPE, prStaRec->u2AssocReqIeLen); -+ prStaRec->pucAssocReqIe = NULL; -+ } -+ prStaRec->u2AssocReqIeLen = u2IELength; -+ if (u2IELength) { -+ prStaRec->pucAssocReqIe = prNewAssocReqIe; /* kalMemAlloc(u2IELength, VIR_MEM_TYPE); */ -+ kalMemCopy(prStaRec->pucAssocReqIe, cp, u2IELength); -+ } -+ } -+#endif -+ kalP2PUpdateAssocInfo(prAdapter->prGlueInfo, (PUINT_8) &prAssocReqFrame->u2CapInfo, -+ u2IELength + (prStaRec->fgIsReAssoc ? 10 : 4), prStaRec->fgIsReAssoc); -+ } -+#endif -+ -+ *pu2StatusCode = u2StatusCode; -+ -+ return WLAN_STATUS_SUCCESS; -+ -+} /* end of assocProcessRxAssocReqFrame() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is used to compose Common Information Elements for Association -+* Response Frame. -+* -+* @param[in] prMsduInfo Pointer to the composed MSDU_INFO_T. -+* @param[in] prBssInfo Pointer to the BSS_INFO_T. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+static inline VOID -+assocBuildReAssocRespFrameCommonIEs(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo, IN P_BSS_INFO_T prBssInfo) -+{ -+ PUINT_8 pucBuffer; -+ P_STA_RECORD_T prStaRec; -+ UINT_8 ucSupRatesLen; -+ UINT_8 ucExtSupRatesLen; -+ -+ ASSERT(prMsduInfo); -+ ASSERT(prMsduInfo->eSrc == TX_PACKET_MGMT); -+ -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); -+ ASSERT(prStaRec); -+ -+ pucBuffer = (PUINT_8) ((ULONG) prMsduInfo->prPacket + (UINT_32) prMsduInfo->u2FrameLength); -+ ASSERT(pucBuffer); -+ -+ if (prBssInfo->ucAllSupportedRatesLen > ELEM_MAX_LEN_SUP_RATES) { -+ -+ ucSupRatesLen = ELEM_MAX_LEN_SUP_RATES; -+ ucExtSupRatesLen = prBssInfo->ucAllSupportedRatesLen - ELEM_MAX_LEN_SUP_RATES; -+ } else { -+ ucSupRatesLen = prBssInfo->ucAllSupportedRatesLen; -+ ucExtSupRatesLen = 0; -+ } -+ -+ /* Fill the Supported Rates element. */ -+ if (ucSupRatesLen) { -+ SUP_RATES_IE(pucBuffer)->ucId = ELEM_ID_SUP_RATES; -+ SUP_RATES_IE(pucBuffer)->ucLength = ucSupRatesLen; -+ kalMemCopy(SUP_RATES_IE(pucBuffer)->aucSupportedRates, prBssInfo->aucAllSupportedRates, ucSupRatesLen); -+ -+ prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer); -+ pucBuffer += IE_SIZE(pucBuffer); -+ } -+ -+ /* Fill the Extended Supported Rates element. */ -+ if (ucExtSupRatesLen) { -+ -+ EXT_SUP_RATES_IE(pucBuffer)->ucId = ELEM_ID_EXTENDED_SUP_RATES; -+ EXT_SUP_RATES_IE(pucBuffer)->ucLength = ucExtSupRatesLen; -+ -+ kalMemCopy(EXT_SUP_RATES_IE(pucBuffer)->aucExtSupportedRates, -+ &prBssInfo->aucAllSupportedRates[ucSupRatesLen], ucExtSupRatesLen); -+ -+ prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer); -+ } -+ -+} /* end of assocBuildReAssocRespFrameCommonIEs() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will compose the (Re)Association Response frame -+* -+* @param[in] prStaRec Pointer to the STA_RECORD_T -+* @param[in] pucBuffer Pointer to the frame buffer. -+* @param[in] aucBssid Given BSSID. -+* @param[in] u2CapInfo Capability Field of current BSS. -+* @param[in out] pu2PayloadLen Return the length of the composed fixed fields -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+static inline VOID -+assocComposeReAssocRespFrameHeaderAndFF(IN P_STA_RECORD_T prStaRec, -+ IN PUINT_8 pucBuffer, -+ IN UINT_8 aucBSSID[], IN UINT_16 u2CapInfo, IN OUT PUINT_16 pu2PayloadLen) -+{ -+ P_WLAN_ASSOC_RSP_FRAME_T prAssocRspFrame; -+ BOOLEAN fgIsReAssoc; -+ -+ UINT_16 u2FrameCtrl; -+ -+ ASSERT(prStaRec); -+ ASSERT(pucBuffer); -+ ASSERT(aucBSSID); -+ ASSERT(pu2PayloadLen); -+ -+ prAssocRspFrame = (P_WLAN_ASSOC_RSP_FRAME_T) pucBuffer; -+ fgIsReAssoc = prStaRec->fgIsReAssoc; -+ -+ /* 4 <1> Compose the frame header of the (Re)Association Request frame. */ -+ /* Fill the Frame Control field. */ -+ if (fgIsReAssoc) -+ u2FrameCtrl = MAC_FRAME_REASSOC_RSP; -+ else -+ u2FrameCtrl = MAC_FRAME_ASSOC_RSP; -+ /* WLAN_SET_FIELD_16(&prAssocFrame->u2FrameCtrl, u2FrameCtrl); */ -+ prAssocRspFrame->u2FrameCtrl = u2FrameCtrl; /* NOTE(Kevin): Optimized for ARM */ -+ -+ /* Fill the DA field with Target MAC Address. */ -+ COPY_MAC_ADDR(prAssocRspFrame->aucDestAddr, prStaRec->aucMacAddr); -+ -+ /* Fill the SA field with current BSSID. */ -+ COPY_MAC_ADDR(prAssocRspFrame->aucSrcAddr, aucBSSID); -+ -+ /* Fill the BSSID field with current BSSID. */ -+ COPY_MAC_ADDR(prAssocRspFrame->aucBSSID, aucBSSID); -+ -+ /* Clear the SEQ/FRAG_NO field(HW won't overide the FRAG_NO, so we need to clear it). */ -+ prAssocRspFrame->u2SeqCtrl = 0; -+ -+ /* 4 <2> Compose the frame body's common fixed field part of the (Re)Association Request frame. */ -+ /* Fill the Capability Information field. */ -+ /* WLAN_SET_FIELD_16(&prAssocFrame->u2CapInfo, u2CapInfo); */ -+ prAssocRspFrame->u2CapInfo = u2CapInfo; /* NOTE(Kevin): Optimized for ARM */ -+ -+ /* WLAN_SET_FIELD_16(&prAssocFrame->u2StatusCode, prStaRec->u2StatusCode); */ -+ prAssocRspFrame->u2StatusCode = prStaRec->u2StatusCode; /* NOTE(Kevin): Optimized for ARM */ -+ -+ /* WLAN_SET_FIELD_16(&prAssocFrame->u2AssocId, ((prStaRec->u2AssocId & AID_MASK) | AID_MSB)); */ -+ prAssocRspFrame->u2AssocId = ((prStaRec->u2AssocId & AID_MASK) | AID_MSB); /* NOTE(Kevin): Optimized for ARM */ -+ -+ *pu2PayloadLen = (CAP_INFO_FIELD_LEN + STATUS_CODE_FIELD_LEN + AID_FIELD_LEN); -+ -+} /* end of assocComposeReAssocRespFrameHeaderAndFF() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will send the (Re)Association Resp frame -+* -+* @param[in] prStaRec Pointer to the STA_RECORD_T -+* -+* @retval WLAN_STATUS_RESOURCES No available resource for frame composing. -+* @retval WLAN_STATUS_SUCCESS Successfully send frame to TX Module -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS assocSendReAssocRespFrame(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec) -+{ -+ P_BSS_INFO_T prBssInfo; -+ P_MSDU_INFO_T prMsduInfo; -+ -+ UINT_16 u2PayloadLen; -+ UINT_16 u2EstimatedFrameLen; -+ UINT_16 u2EstimatedExtraIELen; -+ BOOLEAN fgIsReAssoc; -+ UINT_32 i; -+ -+ ASSERT(prStaRec); -+ -+ /* 4 <1> Allocate a PKT_INFO_T for Authentication Frame */ -+ fgIsReAssoc = prStaRec->fgIsReAssoc; -+ -+ /* Init with MGMT Header Length + Length of Fixed Fields + Common IE Length */ -+ u2EstimatedFrameLen = MAC_TX_RESERVED_FIELD + -+ WLAN_MAC_MGMT_HEADER_LEN + -+ CAP_INFO_FIELD_LEN + -+ STATUS_CODE_FIELD_LEN + -+ AID_FIELD_LEN + -+ (ELEM_HDR_LEN + ELEM_MAX_LEN_SUP_RATES) + (ELEM_HDR_LEN + (RATE_NUM - ELEM_MAX_LEN_SUP_RATES)); -+ -+ /* + Extra IE Length */ -+ u2EstimatedExtraIELen = 0; -+ -+ for (i = 0; i < sizeof(txAssocRespIETable) / sizeof(APPEND_VAR_IE_ENTRY_T); i++) { -+ if (txAssocRespIETable[i].u2EstimatedFixedIELen != 0) { -+ u2EstimatedExtraIELen += txAssocRespIETable[i].u2EstimatedFixedIELen; -+ } else if (txAssocRespIETable[i].pfnCalculateVariableIELen != NULL) { -+ u2EstimatedExtraIELen += (UINT_16) txAssocRespIETable[i].pfnCalculateVariableIELen(prAdapter, -+ prStaRec->ucNetTypeIndex, -+ prStaRec); -+ } -+ -+ } -+ -+ u2EstimatedFrameLen += u2EstimatedExtraIELen; -+ -+ /* Allocate a MSDU_INFO_T */ -+ prMsduInfo = cnmMgtPktAlloc(prAdapter, u2EstimatedFrameLen); -+ if (prMsduInfo == NULL) { -+ DBGLOG(AAA, WARN, "No PKT_INFO_T for sending (Re)Assoc Response.\n"); -+ return WLAN_STATUS_RESOURCES; -+ } -+ /* 4 <2> Compose (Re)Association Request frame header and fixed fields in MSDU_INfO_T. */ -+ ASSERT(prStaRec->ucNetTypeIndex != NETWORK_TYPE_AIS_INDEX); -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]); -+ -+ /* Compose Header and Fixed Field */ -+ assocComposeReAssocRespFrameHeaderAndFF(prStaRec, -+ (PUINT_8) ((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD), -+ prBssInfo->aucBSSID, prBssInfo->u2CapInfo, &u2PayloadLen); -+ -+ /* 4 <3> Update information of MSDU_INFO_T */ -+ ASSERT(prStaRec->ucNetTypeIndex < NETWORK_TYPE_INDEX_NUM); -+ -+ prMsduInfo->eSrc = TX_PACKET_MGMT; -+ prMsduInfo->ucPacketType = HIF_TX_PACKET_TYPE_MGMT; -+ prMsduInfo->ucStaRecIndex = prStaRec->ucIndex; -+ prMsduInfo->ucNetworkType = prStaRec->ucNetTypeIndex; -+ prMsduInfo->ucMacHeaderLength = WLAN_MAC_MGMT_HEADER_LEN; -+ prMsduInfo->fgIs802_1x = FALSE; -+ prMsduInfo->fgIs802_11 = TRUE; -+ prMsduInfo->u2FrameLength = WLAN_MAC_MGMT_HEADER_LEN + u2PayloadLen; -+ prMsduInfo->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter); -+ prMsduInfo->pfTxDoneHandler = aaaFsmRunEventTxDone; -+ prMsduInfo->fgIsBasicRate = TRUE; -+ -+ /* 4 <4> Compose the frame body's IEs of the (Re)Association Request frame. */ -+ assocBuildReAssocRespFrameCommonIEs(prAdapter, prMsduInfo, prBssInfo); -+ -+ /* 4 <5> Compose IEs in MSDU_INFO_T */ -+ -+ /* Append IE */ -+ for (i = 0; i < sizeof(txAssocRespIETable) / sizeof(APPEND_VAR_IE_ENTRY_T); i++) { -+ if (txAssocRespIETable[i].pfnAppendIE) -+ txAssocRespIETable[i].pfnAppendIE(prAdapter, prMsduInfo); -+ } -+ -+ /* TODO(Kevin): Also release the unused tail room of the composed MMPDU */ -+ -+ /* 4 <6> Enqueue the frame to send this (Re)Association request frame. */ -+ DBGLOG(SAA, INFO, "Sending (Re)Assoc Response, network: %d seqNo: %d\n", -+ prMsduInfo->ucNetworkType, prMsduInfo->ucTxSeqNum); -+ nicTxEnqueueMsdu(prAdapter, prMsduInfo); -+ -+ return WLAN_STATUS_SUCCESS; -+ -+} /* end of assocSendReAssocRespFrame() */ -+#endif /* CFG_SUPPORT_AAA */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/auth.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/auth.c -new file mode 100644 -index 000000000000..43b91d72bd43 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/auth.c -@@ -0,0 +1,1211 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/auth.c#1 -+*/ -+ -+/*! \file "auth.c" -+ \brief This file includes the authentication-related functions. -+ -+ This file includes the authentication-related functions. -+*/ -+ -+/* -+** Log: auth.c -+ * -+ * 02 13 2012 cp.wu -+ * NULL -+ * show error message only instead of raise assertion when -+ * received authentication frame is carrying illegal parameters. -+ * -+ * 11 09 2011 yuche.tsai -+ * NULL -+ * Fix a network index & station record index issue when TX deauth frame. -+ * -+ * 10 12 2011 wh.su -+ * [WCXRP00001036] [MT6620 Wi-Fi][Driver][FW] Adding the 802.11w code for MFP -+ * adding the 802.11w related function and define . -+ * -+ * 06 22 2011 yuche.tsai -+ * NULL -+ * Fix coding error. -+ * -+ * 06 20 2011 yuche.tsai -+ * [WCXRP00000796] [Volunteer Patch][MT6620][Driver] Add BC deauth frame TX feature. -+ * BC deauth support. -+ * -+ * 04 21 2011 terry.wu -+ * [WCXRP00000674] [MT6620 Wi-Fi][Driver] Refine AAA authSendAuthFrame -+ * Add network type parameter to authSendAuthFrame. -+ * -+ * 04 15 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Add BOW short range mode. -+ * -+ * 02 08 2011 yuche.tsai -+ * [WCXRP00000245] 1. Invitation Request/Response. -+2. Provision Discovery Request/Response -+ -+ * 1. Fix Service Disocvery Logical issue. -+ * 2. Fix a NULL pointer access violation issue when sending deauthentication packet to a class error station. -+ * -+ * 01 24 2011 cp.wu -+ * [WCXRP00000382] [MT6620 Wi-Fi][Driver] Track forwarding packet number with notifying tx thread for serving -+ * 1. add an extra counter for tracking pending forward frames. -+ * 2. notify TX service thread as well when there is pending forward frame -+ * 3. correct build errors leaded by introduction of Wi-Fi direct separation module -+ * -+ * 01 21 2011 terry.wu -+ * [WCXRP00000381] [MT6620 Wi-Fi][Driver] Kernel panic when replying unaccept Auth in AP mode -+ * In AP mode, use STA_REC_INDEX_NOT_FOUND(0xFE) instead of StaRec index when replying an unaccept Auth frame. -+ * -+ * 10 18 2010 cp.wu -+ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning -+ * use definition macro to replace hard-coded constant -+ * -+ * 09 03 2010 kevin.huang -+ * NULL -+ * Refine #include sequence and solve recursive/nested #include issue -+ * -+ * 08 30 2010 cp.wu -+ * NULL -+ * eliminate klockwork errors -+ * -+ * 08 16 2010 cp.wu -+ * NULL -+ * Replace CFG_SUPPORT_BOW by CFG_ENABLE_BT_OVER_WIFI. -+ * There is no CFG_SUPPORT_BOW in driver domain source. -+ * -+ * 08 16 2010 kevin.huang -+ * NULL -+ * Refine AAA functions -+ * -+ * 08 03 2010 cp.wu -+ * NULL -+ * surpress compilation warning. -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 28 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * send MMPDU in basic rate. -+ * -+ * 06 21 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * specify correct value for management frames. -+ * -+ * 06 18 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Provide cnmMgtPktAlloc() and alloc/free function of msg/buf -+ * -+ * 06 14 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add management dispatching function table. -+ * -+ * 06 11 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * auth.c is migrated. -+ * -+ * 05 28 2010 kevin.huang -+ * [BORA00000794][WIFISYS][New Feature]Power Management Support -+ * Update authSendDeauthFrame() for correct the value of eNetTypeIndex in MSDU_INFO_T -+ * -+ * 05 24 2010 kevin.huang -+ * [BORA00000794][WIFISYS][New Feature]Power Management Support -+ * Check Net is active before sending Deauth frame. -+ * -+ * 05 24 2010 kevin.huang -+ * [BORA00000794][WIFISYS][New Feature]Power Management Support -+ * Refine authSendAuthFrame() for NULL STA_RECORD_T case and minimum deauth interval. -+ * -+ * 04 24 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * g_aprBssInfo[] depends on CFG_SUPPORT_P2P and CFG_SUPPORT_BOW -+ * -+ * 04 19 2010 kevin.huang -+ * [BORA00000714][WIFISYS][New Feature]Beacon Timeout Support -+ * Add Send Deauth for Class 3 Error and Leave Network Support -+ * -+ * 02 23 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Fix compile warning -+ * -+ * 02 05 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Add debug message for abnormal authentication frame from AP -+ * -+ * 02 04 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Add AAA Module Support, Revise Net Type to Net Type Index for array lookup -+ * -+ * 01 11 2010 kevin.huang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Add Deauth and Disassoc Handler -+ * -+ * 01 07 2010 kevin.huang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * -+ * Fix the Debug Label -+ * -+ * 12 18 2009 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * . -+ * -+ * Dec 7 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Update the authComposeAuthFrameHeader() -+ * -+ * Dec 7 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * adding the send deauth frame function -+ * -+ * Dec 3 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Integrate send Auth with TXM -+ * -+ * Nov 24 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Revise MGMT Handler with Retain Status -+ * -+ * Nov 23 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "precomp.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+APPEND_IE_ENTRY_T txAuthIETable[] = { -+ {(ELEM_HDR_LEN + ELEM_MAX_LEN_CHALLENGE_TEXT), authAddIEChallengeText} -+}; -+ -+HANDLE_IE_ENTRY_T rxAuthIETable[] = { -+ {ELEM_ID_CHALLENGE_TEXT, authHandleIEChallengeText} -+}; -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will compose the Authentication frame header and fixed fields. -+* -+* @param[in] pucBuffer Pointer to the frame buffer. -+* @param[in] aucPeerMACAddress Given Peer MAC Address. -+* @param[in] aucMACAddress Given Our MAC Address. -+* @param[in] u2AuthAlgNum Authentication Algorithm Number -+* @param[in] u2TransactionSeqNum Transaction Sequence Number -+* @param[in] u2StatusCode Status Code -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+static inline VOID -+authComposeAuthFrameHeaderAndFF(IN PUINT_8 pucBuffer, -+ IN UINT_8 aucPeerMACAddress[], -+ IN UINT_8 aucMACAddress[], -+ IN UINT_16 u2AuthAlgNum, IN UINT_16 u2TransactionSeqNum, IN UINT_16 u2StatusCode) -+{ -+ P_WLAN_AUTH_FRAME_T prAuthFrame; -+ UINT_16 u2FrameCtrl; -+ -+ ASSERT(pucBuffer); -+ ASSERT(aucPeerMACAddress); -+ ASSERT(aucMACAddress); -+ -+ prAuthFrame = (P_WLAN_AUTH_FRAME_T) pucBuffer; -+ -+ /* 4 <1> Compose the frame header of the Authentication frame. */ -+ /* Fill the Frame Control field. */ -+ u2FrameCtrl = MAC_FRAME_AUTH; -+ -+ /* If this frame is the third frame in the shared key authentication -+ * sequence, it shall be encrypted. -+ */ -+ if ((u2AuthAlgNum == AUTH_ALGORITHM_NUM_SHARED_KEY) && (u2TransactionSeqNum == AUTH_TRANSACTION_SEQ_3)) -+ u2FrameCtrl |= MASK_FC_PROTECTED_FRAME; /* HW will also detect this bit for applying encryption */ -+ /* WLAN_SET_FIELD_16(&prAuthFrame->u2FrameCtrl, u2FrameCtrl); */ -+ prAuthFrame->u2FrameCtrl = u2FrameCtrl; /* NOTE(Kevin): Optimized for ARM */ -+ -+ /* Fill the DA field with Target BSSID. */ -+ COPY_MAC_ADDR(prAuthFrame->aucDestAddr, aucPeerMACAddress); -+ -+ /* Fill the SA field with our MAC Address. */ -+ COPY_MAC_ADDR(prAuthFrame->aucSrcAddr, aucMACAddress); -+ -+ switch (u2TransactionSeqNum) { -+ case AUTH_TRANSACTION_SEQ_1: -+ case AUTH_TRANSACTION_SEQ_3: -+ -+ /* Fill the BSSID field with Target BSSID. */ -+ COPY_MAC_ADDR(prAuthFrame->aucBSSID, aucPeerMACAddress); -+ break; -+ -+ case AUTH_TRANSACTION_SEQ_2: -+ case AUTH_TRANSACTION_SEQ_4: -+ -+ /* Fill the BSSID field with Current BSSID. */ -+ COPY_MAC_ADDR(prAuthFrame->aucBSSID, aucMACAddress); -+ break; -+ -+ default: -+ ASSERT(0); -+ } -+ -+ /* Clear the SEQ/FRAG_NO field. */ -+ prAuthFrame->u2SeqCtrl = 0; -+ -+ /* 4 <2> Compose the frame body's fixed field part of the Authentication frame. */ -+ /* Fill the Authentication Algorithm Number field. */ -+ /* WLAN_SET_FIELD_16(&prAuthFrame->u2AuthAlgNum, u2AuthAlgNum); */ -+ prAuthFrame->u2AuthAlgNum = u2AuthAlgNum; /* NOTE(Kevin): Optimized for ARM */ -+ -+ /* Fill the Authentication Transaction Sequence Number field. */ -+ /* WLAN_SET_FIELD_16(&prAuthFrame->u2AuthTransSeqNo, u2TransactionSeqNum); */ -+ prAuthFrame->u2AuthTransSeqNo = u2TransactionSeqNum; /* NOTE(Kevin): Optimized for ARM */ -+ -+ /* Fill the Status Code field. */ -+ /* WLAN_SET_FIELD_16(&prAuthFrame->u2StatusCode, u2StatusCode); */ -+ prAuthFrame->u2StatusCode = u2StatusCode; /* NOTE(Kevin): Optimized for ARM */ -+ -+} /* end of authComposeAuthFrameHeaderAndFF() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will append Challenge Text IE to the Authentication frame -+* -+* @param[in] prMsduInfo Pointer to the composed MSDU_INFO_T. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID authAddIEChallengeText(IN P_ADAPTER_T prAdapter, IN OUT P_MSDU_INFO_T prMsduInfo) -+{ -+ P_WLAN_AUTH_FRAME_T prAuthFrame; -+ P_STA_RECORD_T prStaRec; -+ UINT_16 u2TransactionSeqNum; -+ -+ ASSERT(prMsduInfo); -+ -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); -+ -+ if (!prStaRec) -+ return; -+ -+ ASSERT(prStaRec); -+ -+ /* For Management, frame header and payload are in a continuous buffer */ -+ prAuthFrame = (P_WLAN_AUTH_FRAME_T) prMsduInfo->prPacket; -+ -+ WLAN_GET_FIELD_16(&prAuthFrame->u2AuthTransSeqNo, &u2TransactionSeqNum) -+ -+ /* Only consider SEQ_3 for Challenge Text */ -+ if ((u2TransactionSeqNum == AUTH_TRANSACTION_SEQ_3) && -+ (prStaRec->ucAuthAlgNum == AUTH_ALGORITHM_NUM_SHARED_KEY) && (prStaRec->prChallengeText != NULL)) { -+ -+ COPY_IE(((ULONG) (prMsduInfo->prPacket) + prMsduInfo->u2FrameLength), (prStaRec->prChallengeText)); -+ -+ prMsduInfo->u2FrameLength += IE_SIZE(prStaRec->prChallengeText); -+ } -+ -+ return; -+ -+} /* end of authAddIEChallengeText() */ -+ -+#if !CFG_SUPPORT_AAA -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will send the Authenticiation frame -+* -+* @param[in] prStaRec Pointer to the STA_RECORD_T -+* @param[in] u2TransactionSeqNum Transaction Sequence Number -+* -+* @retval WLAN_STATUS_RESOURCES No available resource for frame composing. -+* @retval WLAN_STATUS_SUCCESS Successfully send frame to TX Module -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS authSendAuthFrame(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN UINT_16 u2TransactionSeqNum) -+{ -+ P_MSDU_INFO_T prMsduInfo; -+ P_BSS_INFO_T prBssInfo; -+ UINT_16 u2EstimatedFrameLen; -+ UINT_16 u2EstimatedExtraIELen; -+ UINT_16 u2PayloadLen; -+ UINT_32 i; -+ -+ DBGLOG(SAA, LOUD, "Send Auth Frame\n"); -+ -+ ASSERT(prStaRec); -+ -+ /* 4 <1> Allocate a PKT_INFO_T for Authentication Frame */ -+ /* Init with MGMT Header Length + Length of Fixed Fields */ -+ u2EstimatedFrameLen = (MAC_TX_RESERVED_FIELD + -+ WLAN_MAC_MGMT_HEADER_LEN + -+ AUTH_ALGORITHM_NUM_FIELD_LEN + -+ AUTH_TRANSACTION_SEQENCE_NUM_FIELD_LEN + STATUS_CODE_FIELD_LEN); -+ -+ /* + Extra IE Length */ -+ u2EstimatedExtraIELen = 0; -+ -+ for (i = 0; i < sizeof(txAuthIETable) / sizeof(APPEND_IE_ENTRY_T); i++) -+ u2EstimatedExtraIELen += txAuthIETable[i].u2EstimatedIELen; -+ -+ u2EstimatedFrameLen += u2EstimatedExtraIELen; -+ -+ /* Allocate a MSDU_INFO_T */ -+ prMsduInfo = cnmMgtPktAlloc(prAdapter, u2EstimatedFrameLen); -+ if (prMsduInfo == NULL) { -+ DBGLOG(SAA, WARN, "No PKT_INFO_T for sending Auth Frame.\n"); -+ return WLAN_STATUS_RESOURCES; -+ } -+ /* 4 <2> Compose Authentication Request frame header and fixed fields in MSDU_INfO_T. */ -+ ASSERT(prStaRec->ucNetTypeIndex < NETWORK_TYPE_INDEX_NUM); -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]); -+ -+ /* Compose Header and some Fixed Fields */ -+ authComposeAuthFrameHeaderAndFF((PUINT_8) ((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD), -+ prStaRec->aucMacAddr, -+ prBssInfo->aucOwnMacAddr, -+ prStaRec->ucAuthAlgNum, u2TransactionSeqNum, STATUS_CODE_RESERVED); -+ -+ u2PayloadLen = (AUTH_ALGORITHM_NUM_FIELD_LEN + AUTH_TRANSACTION_SEQENCE_NUM_FIELD_LEN + STATUS_CODE_FIELD_LEN); -+ -+ /* 4 <3> Update information of MSDU_INFO_T */ -+ prMsduInfo->eSrc = TX_PACKET_MGMT; -+ prMsduInfo->ucPacketType = HIF_TX_PACKET_TYPE_MGMT; -+ prMsduInfo->ucStaRecIndex = prStaRec->ucIndex; -+ prMsduInfo->ucNetworkType = prStaRec->ucNetTypeIndex; -+ prMsduInfo->ucMacHeaderLength = WLAN_MAC_MGMT_HEADER_LEN; -+ prMsduInfo->fgIs802_1x = FALSE; -+ prMsduInfo->fgIs802_11 = TRUE; -+ prMsduInfo->u2FrameLength = WLAN_MAC_MGMT_HEADER_LEN + u2PayloadLen; -+ prMsduInfo->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter); -+ prMsduInfo->pfTxDoneHandler = saaFsmRunEventTxDone; -+ prMsduInfo->fgIsBasicRate = TRUE; -+ -+ /* 4 <4> Compose IEs in MSDU_INFO_T */ -+ for (i = 0; i < sizeof(txAuthIETable) / sizeof(APPEND_IE_ENTRY_T); i++) { -+ if (txAuthIETable[i].pfnAppendIE) -+ txAuthIETable[i].pfnAppendIE(prAdapter, prMsduInfo); -+ } -+ -+ /* TODO(Kevin): Also release the unused tail room of the composed MMPDU */ -+ -+ /* 4 <6> Inform TXM to send this Authentication frame. */ -+ nicTxEnqueueMsdu(prAdapter, prMsduInfo); -+ -+ return WLAN_STATUS_SUCCESS; -+} /* end of authSendAuthFrame() */ -+ -+#else -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will send the Authenticiation frame -+* -+* @param[in] prStaRec Pointer to the STA_RECORD_T -+* @param[in] u2TransactionSeqNum Transaction Sequence Number -+* -+* @retval WLAN_STATUS_RESOURCES No available resource for frame composing. -+* @retval WLAN_STATUS_SUCCESS Successfully send frame to TX Module -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+authSendAuthFrame(IN P_ADAPTER_T prAdapter, -+ IN P_STA_RECORD_T prStaRec, -+ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, -+ IN P_SW_RFB_T prFalseAuthSwRfb, IN UINT_16 u2TransactionSeqNum, IN UINT_16 u2StatusCode) -+{ -+ PUINT_8 pucReceiveAddr; -+ PUINT_8 pucTransmitAddr; -+ P_MSDU_INFO_T prMsduInfo; -+ P_BSS_INFO_T prBssInfo; -+ /*get from input parameter */ -+ /* ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex = NETWORK_TYPE_AIS_INDEX; */ -+ PFN_TX_DONE_HANDLER pfTxDoneHandler = (PFN_TX_DONE_HANDLER) NULL; -+ UINT_16 u2EstimatedFrameLen; -+ UINT_16 u2EstimatedExtraIELen; -+ UINT_16 u2PayloadLen; -+ UINT_16 ucAuthAlgNum; -+ UINT_32 i; -+ -+ DBGLOG(SAA, LOUD, "Send Auth Frame %d, Status Code = %d\n", u2TransactionSeqNum, u2StatusCode); -+ -+ /* 4 <1> Allocate a PKT_INFO_T for Authentication Frame */ -+ /* Init with MGMT Header Length + Length of Fixed Fields */ -+ u2EstimatedFrameLen = (MAC_TX_RESERVED_FIELD + -+ WLAN_MAC_MGMT_HEADER_LEN + -+ AUTH_ALGORITHM_NUM_FIELD_LEN + -+ AUTH_TRANSACTION_SEQENCE_NUM_FIELD_LEN + STATUS_CODE_FIELD_LEN); -+ -+ /* + Extra IE Length */ -+ u2EstimatedExtraIELen = 0; -+ -+ for (i = 0; i < sizeof(txAuthIETable) / sizeof(APPEND_IE_ENTRY_T); i++) -+ u2EstimatedExtraIELen += txAuthIETable[i].u2EstimatedIELen; -+ -+ u2EstimatedFrameLen += u2EstimatedExtraIELen; -+ -+ /* Allocate a MSDU_INFO_T */ -+ prMsduInfo = cnmMgtPktAlloc(prAdapter, u2EstimatedFrameLen); -+ if (prMsduInfo == NULL) { -+ DBGLOG(SAA, WARN, "No PKT_INFO_T for sending Auth Frame.\n"); -+ return WLAN_STATUS_RESOURCES; -+ } -+ /* 4 <2> Compose Authentication Request frame header and fixed fields in MSDU_INfO_T. */ -+ if (prStaRec) { -+ ASSERT(prStaRec->ucNetTypeIndex < NETWORK_TYPE_INDEX_NUM); -+ -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]); -+ -+ pucTransmitAddr = prBssInfo->aucOwnMacAddr; -+ -+ pucReceiveAddr = prStaRec->aucMacAddr; -+ -+ ucAuthAlgNum = prStaRec->ucAuthAlgNum; -+ -+ switch (u2TransactionSeqNum) { -+ case AUTH_TRANSACTION_SEQ_1: -+ case AUTH_TRANSACTION_SEQ_3: -+ pfTxDoneHandler = saaFsmRunEventTxDone; -+ break; -+ -+ case AUTH_TRANSACTION_SEQ_2: -+ case AUTH_TRANSACTION_SEQ_4: -+ pfTxDoneHandler = aaaFsmRunEventTxDone; -+ break; -+ } -+ -+ } else { /* For Error Status Code */ -+ P_WLAN_AUTH_FRAME_T prFalseAuthFrame; -+ -+ ASSERT(prFalseAuthSwRfb); -+ prFalseAuthFrame = (P_WLAN_AUTH_FRAME_T) prFalseAuthSwRfb->pvHeader; -+ -+ ASSERT(u2StatusCode != STATUS_CODE_SUCCESSFUL); -+ -+ pucTransmitAddr = prFalseAuthFrame->aucDestAddr; -+ -+ pucReceiveAddr = prFalseAuthFrame->aucSrcAddr; -+ -+ ucAuthAlgNum = prFalseAuthFrame->u2AuthAlgNum; -+ -+ u2TransactionSeqNum = (prFalseAuthFrame->u2AuthTransSeqNo + 1); -+ } -+ -+ /* Compose Header and some Fixed Fields */ -+ authComposeAuthFrameHeaderAndFF((PUINT_8) ((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD), -+ pucReceiveAddr, -+ pucTransmitAddr, ucAuthAlgNum, u2TransactionSeqNum, u2StatusCode); -+ -+ u2PayloadLen = (AUTH_ALGORITHM_NUM_FIELD_LEN + AUTH_TRANSACTION_SEQENCE_NUM_FIELD_LEN + STATUS_CODE_FIELD_LEN); -+ -+ /* 4 <3> Update information of MSDU_INFO_T */ -+ prMsduInfo->eSrc = TX_PACKET_MGMT; -+ prMsduInfo->ucPacketType = HIF_TX_PACKET_TYPE_MGMT; -+ if (prStaRec) -+ prMsduInfo->ucStaRecIndex = prStaRec->ucIndex; -+ else -+ prMsduInfo->ucStaRecIndex = STA_REC_INDEX_NOT_FOUND; /* false Auth frame */ -+ prMsduInfo->ucNetworkType = (UINT_8) eNetTypeIndex; -+ prMsduInfo->ucMacHeaderLength = WLAN_MAC_MGMT_HEADER_LEN; -+ prMsduInfo->fgIs802_1x = FALSE; -+ prMsduInfo->fgIs802_11 = TRUE; -+ prMsduInfo->u2FrameLength = WLAN_MAC_MGMT_HEADER_LEN + u2PayloadLen; -+ prMsduInfo->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter); -+ prMsduInfo->pfTxDoneHandler = pfTxDoneHandler; -+ prMsduInfo->fgIsBasicRate = TRUE; -+ -+ /* 4 <4> Compose IEs in MSDU_INFO_T */ -+ for (i = 0; i < sizeof(txAuthIETable) / sizeof(APPEND_IE_ENTRY_T); i++) { -+ if (txAuthIETable[i].pfnAppendIE) -+ txAuthIETable[i].pfnAppendIE(prAdapter, prMsduInfo); -+ } -+ -+ /* TODO(Kevin): Also release the unused tail room of the composed MMPDU */ -+ -+ /* 4 <6> Inform TXM to send this Authentication frame. */ -+ DBGLOG(SAA, INFO, "network: %d Send Auth Frame %d, Status Code = %d seq num %d\n", -+ eNetTypeIndex, u2TransactionSeqNum, u2StatusCode, prMsduInfo->ucTxSeqNum); -+ nicTxEnqueueMsdu(prAdapter, prMsduInfo); -+ -+ return WLAN_STATUS_SUCCESS; -+} /* end of authSendAuthFrame() */ -+ -+#endif /* CFG_SUPPORT_AAA */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will strictly check the TX Authentication frame for SAA/AAA event -+* handling. -+* -+* @param[in] prMsduInfo Pointer of MSDU_INFO_T -+* @param[in] u2TransactionSeqNum Transaction Sequence Number -+* -+* @retval WLAN_STATUS_FAILURE This is not the frame we should handle at current state. -+* @retval WLAN_STATUS_SUCCESS This is the frame we should handle. -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS authCheckTxAuthFrame(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo, IN UINT_16 u2TransactionSeqNum) -+{ -+ P_WLAN_AUTH_FRAME_T prAuthFrame; -+ P_STA_RECORD_T prStaRec; -+ UINT_16 u2TxFrameCtrl; -+ UINT_16 u2TxAuthAlgNum; -+ UINT_16 u2TxTransactionSeqNum; -+ -+ ASSERT(prMsduInfo); -+ -+ prAuthFrame = (P_WLAN_AUTH_FRAME_T) (prMsduInfo->prPacket); -+ ASSERT(prAuthFrame); -+ -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); -+ ASSERT(prStaRec); -+ -+ if (!prStaRec) -+ return WLAN_STATUS_INVALID_PACKET; -+ /* WLAN_GET_FIELD_16(&prAuthFrame->u2FrameCtrl, &u2TxFrameCtrl) */ -+ u2TxFrameCtrl = prAuthFrame->u2FrameCtrl; /* NOTE(Kevin): Optimized for ARM */ -+ u2TxFrameCtrl &= MASK_FRAME_TYPE; -+ if (u2TxFrameCtrl != MAC_FRAME_AUTH) -+ return WLAN_STATUS_FAILURE; -+ /* WLAN_GET_FIELD_16(&prAuthFrame->u2AuthAlgNum, &u2TxAuthAlgNum) */ -+ u2TxAuthAlgNum = prAuthFrame->u2AuthAlgNum; /* NOTE(Kevin): Optimized for ARM */ -+ if (u2TxAuthAlgNum != (UINT_16) (prStaRec->ucAuthAlgNum)) -+ return WLAN_STATUS_FAILURE; -+ /* WLAN_GET_FIELD_16(&prAuthFrame->u2AuthTransSeqNo, &u2TxTransactionSeqNum) */ -+ u2TxTransactionSeqNum = prAuthFrame->u2AuthTransSeqNo; /* NOTE(Kevin): Optimized for ARM */ -+ if (u2TxTransactionSeqNum != u2TransactionSeqNum) -+ return WLAN_STATUS_FAILURE; -+ -+ return WLAN_STATUS_SUCCESS; -+ -+} /* end of authCheckTxAuthFrame() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will check the incoming Auth Frame's Transaction Sequence -+* Number before delivering it to the corresponding SAA or AAA Module. -+* -+* @param[in] prSwRfb Pointer to the SW_RFB_T structure. -+* -+* @retval WLAN_STATUS_SUCCESS Always not retain authentication frames -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS authCheckRxAuthFrameTransSeq(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb) -+{ -+ P_WLAN_AUTH_FRAME_T prAuthFrame; -+ UINT_16 u2RxTransactionSeqNum; -+ -+ ASSERT(prSwRfb); -+ -+ /* 4 <1> locate the Authentication Frame. */ -+ prAuthFrame = (P_WLAN_AUTH_FRAME_T) prSwRfb->pvHeader; -+ -+ /* 4 <2> Parse the Header of Authentication Frame. */ -+ if ((prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen) < (AUTH_ALGORITHM_NUM_FIELD_LEN + -+ AUTH_TRANSACTION_SEQENCE_NUM_FIELD_LEN + -+ STATUS_CODE_FIELD_LEN)) { -+ ASSERT(0); -+ return WLAN_STATUS_SUCCESS; -+ } -+ /* 4 <3> Parse the Fixed Fields of Authentication Frame Body. */ -+ /* WLAN_GET_FIELD_16(&prAuthFrame->u2AuthTransSeqNo, &u2RxTransactionSeqNum); */ -+ u2RxTransactionSeqNum = prAuthFrame->u2AuthTransSeqNo; /* NOTE(Kevin): Optimized for ARM */ -+ -+ switch (u2RxTransactionSeqNum) { -+ case AUTH_TRANSACTION_SEQ_2: -+ case AUTH_TRANSACTION_SEQ_4: -+ saaFsmRunEventRxAuth(prAdapter, prSwRfb); -+ break; -+ -+ case AUTH_TRANSACTION_SEQ_1: -+ case AUTH_TRANSACTION_SEQ_3: -+#if CFG_SUPPORT_AAA -+ aaaFsmRunEventRxAuth(prAdapter, prSwRfb); -+#endif /* CFG_SUPPORT_AAA */ -+ break; -+ -+ default: -+ DBGLOG(SAA, WARN, "Strange Authentication Packet: Auth Trans Seq No = %d, Error Status Code = %d\n", -+ u2RxTransactionSeqNum, prAuthFrame->u2StatusCode); -+ break; -+ } -+ -+ return WLAN_STATUS_SUCCESS; -+ -+} /* end of authCheckRxAuthFrameTransSeq() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will validate the incoming Authentication Frame and take -+* the status code out. -+* -+* @param[in] prSwRfb Pointer to SW RFB data structure. -+* @param[in] u2TransactionSeqNum Transaction Sequence Number -+* @param[out] pu2StatusCode Pointer to store the Status Code from Authentication. -+* -+* @retval WLAN_STATUS_FAILURE This is not the frame we should handle at current state. -+* @retval WLAN_STATUS_SUCCESS This is the frame we should handle. -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+authCheckRxAuthFrameStatus(IN P_ADAPTER_T prAdapter, -+ IN P_SW_RFB_T prSwRfb, IN UINT_16 u2TransactionSeqNum, OUT PUINT_16 pu2StatusCode) -+{ -+ P_STA_RECORD_T prStaRec; -+ P_WLAN_AUTH_FRAME_T prAuthFrame; -+ UINT_16 u2RxAuthAlgNum; -+ UINT_16 u2RxTransactionSeqNum; -+ /* UINT_16 u2RxStatusCode; // NOTE(Kevin): Optimized for ARM */ -+ -+ ASSERT(prSwRfb); -+ ASSERT(pu2StatusCode); -+ -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); -+ ASSERT(prStaRec); -+ -+ if (!prStaRec) -+ return WLAN_STATUS_INVALID_PACKET; -+ /* 4 <1> locate the Authentication Frame. */ -+ prAuthFrame = (P_WLAN_AUTH_FRAME_T) prSwRfb->pvHeader; -+ -+ /* 4 <2> Parse the Fixed Fields of Authentication Frame Body. */ -+ /* WLAN_GET_FIELD_16(&prAuthFrame->u2AuthAlgNum, &u2RxAuthAlgNum); */ -+ u2RxAuthAlgNum = prAuthFrame->u2AuthAlgNum; /* NOTE(Kevin): Optimized for ARM */ -+ if (u2RxAuthAlgNum != (UINT_16) prStaRec->ucAuthAlgNum) { -+ DBGLOG(SAA, WARN, "Discard Auth frame with auth type = %d, current = %d\n", -+ u2RxAuthAlgNum, prStaRec->ucAuthAlgNum); -+ *pu2StatusCode = STATUS_CODE_AUTH_ALGORITHM_NOT_SUPPORTED; -+ return WLAN_STATUS_SUCCESS; -+ } -+ /* WLAN_GET_FIELD_16(&prAuthFrame->u2AuthTransSeqNo, &u2RxTransactionSeqNum); */ -+ u2RxTransactionSeqNum = prAuthFrame->u2AuthTransSeqNo; /* NOTE(Kevin): Optimized for ARM */ -+ if (u2RxTransactionSeqNum != u2TransactionSeqNum) { -+ DBGLOG(SAA, WARN, "Discard Auth frame with Transaction Seq No = %d\n", u2RxTransactionSeqNum); -+ *pu2StatusCode = STATUS_CODE_AUTH_OUT_OF_SEQ; -+ return WLAN_STATUS_SUCCESS; -+ } -+ /* 4 <3> Get the Status code */ -+ /* WLAN_GET_FIELD_16(&prAuthFrame->u2StatusCode, &u2RxStatusCode); */ -+ /* *pu2StatusCode = u2RxStatusCode; */ -+ *pu2StatusCode = prAuthFrame->u2StatusCode; /* NOTE(Kevin): Optimized for ARM */ -+ -+ return WLAN_STATUS_SUCCESS; -+ -+} /* end of authCheckRxAuthFrameStatus() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will handle the Challenge Text IE from the Authentication frame -+* -+* @param[in] prSwRfb Pointer to SW RFB data structure. -+* @param[in] prIEHdr Pointer to start address of IE -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID authHandleIEChallengeText(P_ADAPTER_T prAdapter, P_SW_RFB_T prSwRfb, P_IE_HDR_T prIEHdr) -+{ -+ P_WLAN_AUTH_FRAME_T prAuthFrame; -+ P_STA_RECORD_T prStaRec; -+ UINT_16 u2TransactionSeqNum; -+ -+ ASSERT(prSwRfb); -+ ASSERT(prIEHdr); -+ -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); -+ ASSERT(prStaRec); -+ -+ if (!prStaRec) -+ return; -+ -+ /* For Management, frame header and payload are in a continuous buffer */ -+ prAuthFrame = (P_WLAN_AUTH_FRAME_T) prSwRfb->pvHeader; -+ -+ /* WLAN_GET_FIELD_16(&prAuthFrame->u2AuthTransSeqNo, &u2TransactionSeqNum) */ -+ u2TransactionSeqNum = prAuthFrame->u2AuthTransSeqNo; /* NOTE(Kevin): Optimized for ARM */ -+ -+ /* Only consider SEQ_2 for Challenge Text */ -+ if ((u2TransactionSeqNum == AUTH_TRANSACTION_SEQ_2) && -+ (prStaRec->ucAuthAlgNum == AUTH_ALGORITHM_NUM_SHARED_KEY)) { -+ -+ /* Free previous allocated TCM memory */ -+ if (prStaRec->prChallengeText) { -+ ASSERT(0); -+ cnmMemFree(prAdapter, prStaRec->prChallengeText); -+ prStaRec->prChallengeText = (P_IE_CHALLENGE_TEXT_T) NULL; -+ } -+ -+ prStaRec->prChallengeText = cnmMemAlloc(prAdapter, RAM_TYPE_MSG, IE_SIZE(prIEHdr)); -+ if (prStaRec->prChallengeText == NULL) -+ return; -+ -+ /* Save the Challenge Text from Auth Seq 2 Frame, before sending Auth Seq 3 Frame */ -+ COPY_IE(prStaRec->prChallengeText, prIEHdr); -+ } -+ -+ return; -+ -+} /* end of authAddIEChallengeText() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will parse and process the incoming Authentication frame. -+* -+* @param[in] prSwRfb Pointer to SW RFB data structure. -+* -+* @retval WLAN_STATUS_SUCCESS This is the frame we should handle. -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS authProcessRxAuth2_Auth4Frame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb) -+{ -+ P_WLAN_AUTH_FRAME_T prAuthFrame; -+ PUINT_8 pucIEsBuffer; -+ UINT_16 u2IEsLen; -+ UINT_16 u2Offset; -+ UINT_8 ucIEID; -+ UINT_32 i; -+ -+ ASSERT(prSwRfb); -+ -+ prAuthFrame = (P_WLAN_AUTH_FRAME_T) prSwRfb->pvHeader; -+ -+ pucIEsBuffer = &prAuthFrame->aucInfoElem[0]; -+ u2IEsLen = (prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen) - -+ (AUTH_ALGORITHM_NUM_FIELD_LEN + AUTH_TRANSACTION_SEQENCE_NUM_FIELD_LEN + STATUS_CODE_FIELD_LEN); -+ -+ IE_FOR_EACH(pucIEsBuffer, u2IEsLen, u2Offset) { -+ ucIEID = IE_ID(pucIEsBuffer); -+ -+ for (i = 0; i < (sizeof(rxAuthIETable) / sizeof(HANDLE_IE_ENTRY_T)); i++) { -+ -+ if (ucIEID == rxAuthIETable[i].ucElemID) -+ rxAuthIETable[i].pfnHandleIE(prAdapter, prSwRfb, (P_IE_HDR_T) pucIEsBuffer); -+ } -+ } -+ -+ return WLAN_STATUS_SUCCESS; -+ -+} /* end of authProcessRxAuth2_Auth4Frame() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will compose the Deauthentication frame -+* -+* @param[in] pucBuffer Pointer to the frame buffer. -+* @param[in] aucPeerMACAddress Given Peer MAC Address. -+* @param[in] aucMACAddress Given Our MAC Address. -+* @param[in] u2StatusCode Status Code -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+static inline VOID -+authComposeDeauthFrameHeaderAndFF(IN PUINT_8 pucBuffer, -+ IN UINT_8 aucPeerMACAddress[], -+ IN UINT_8 aucMACAddress[], IN UINT_8 aucBssid[], IN UINT_16 u2ReasonCode) -+{ -+ P_WLAN_DEAUTH_FRAME_T prDeauthFrame; -+ UINT_16 u2FrameCtrl; -+ -+ ASSERT(pucBuffer); -+ ASSERT(aucPeerMACAddress); -+ ASSERT(aucMACAddress); -+ ASSERT(aucBssid); -+ -+ prDeauthFrame = (P_WLAN_DEAUTH_FRAME_T) pucBuffer; -+ -+ /* 4 <1> Compose the frame header of the Deauthentication frame. */ -+ /* Fill the Frame Control field. */ -+ u2FrameCtrl = MAC_FRAME_DEAUTH; -+ -+ /* WLAN_SET_FIELD_16(&prDeauthFrame->u2FrameCtrl, u2FrameCtrl); */ -+ prDeauthFrame->u2FrameCtrl = u2FrameCtrl; /* NOTE(Kevin): Optimized for ARM */ -+ -+ /* Fill the DA field with Target BSSID. */ -+ COPY_MAC_ADDR(prDeauthFrame->aucDestAddr, aucPeerMACAddress); -+ -+ /* Fill the SA field with our MAC Address. */ -+ COPY_MAC_ADDR(prDeauthFrame->aucSrcAddr, aucMACAddress); -+ -+ /* Fill the BSSID field with Target BSSID. */ -+ COPY_MAC_ADDR(prDeauthFrame->aucBSSID, aucBssid); -+ -+ /* Clear the SEQ/FRAG_NO field(HW won't overide the FRAG_NO, so we need to clear it). */ -+ prDeauthFrame->u2SeqCtrl = 0; -+ -+ /* 4 <2> Compose the frame body's fixed field part of the Authentication frame. */ -+ /* Fill the Status Code field. */ -+ /* WLAN_SET_FIELD_16(&prDeauthFrame->u2ReasonCode, u2ReasonCode); */ -+ prDeauthFrame->u2ReasonCode = u2ReasonCode; /* NOTE(Kevin): Optimized for ARM */ -+ -+} /* end of authComposeDeauthFrameHeaderAndFF() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will send the Deauthenticiation frame -+* -+* @param[in] prStaRec Pointer to the STA_RECORD_T -+* @param[in] prClassErrSwRfb Pointer to the SW_RFB_T which is Class Error. -+* @param[in] u2ReasonCode A reason code to indicate why to leave BSS. -+* @param[in] pfTxDoneHandler TX Done call back function -+* -+* @retval WLAN_STATUS_RESOURCES No available resource for frame composing. -+* @retval WLAN_STATUS_SUCCESS Successfully send frame to TX Module -+* @retval WLAN_STATUS_FAILURE Didn't send Deauth frame for various reasons. -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+authSendDeauthFrame(IN P_ADAPTER_T prAdapter, -+ IN P_STA_RECORD_T prStaRec, -+ IN P_SW_RFB_T prClassErrSwRfb, IN UINT_16 u2ReasonCode, IN PFN_TX_DONE_HANDLER pfTxDoneHandler) -+{ -+ P_WLAN_MAC_HEADER_A4_T prWlanMacHeader = NULL; -+ PUINT_8 pucReceiveAddr; -+ PUINT_8 pucTransmitAddr; -+ PUINT_8 pucBssid = NULL; -+ -+ ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex = NETWORK_TYPE_AIS_INDEX; -+ P_MSDU_INFO_T prMsduInfo; -+ UINT_16 u2EstimatedFrameLen; -+ UINT_16 u2RxFrameCtrl; -+ P_BSS_INFO_T prBssInfo; -+ -+ P_DEAUTH_INFO_T prDeauthInfo; -+ OS_SYSTIME rCurrentTime; -+ INT_32 i4NewEntryIndex, i; -+ UINT_8 ucStaRecIdx = STA_REC_INDEX_NOT_FOUND; -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ UINT_8 aucBMC[] = BC_MAC_ADDR; -+#endif -+ -+ /* NOTE(Kevin): The best way to reply the Deauth is according to the incoming data -+ * frame -+ */ -+ /* 4 <1> Find the Receiver Address first. */ -+ if (prClassErrSwRfb) { -+ BOOLEAN fgIsAbleToSendDeauth = FALSE; -+ -+ prWlanMacHeader = (P_WLAN_MAC_HEADER_A4_T) prClassErrSwRfb->pvHeader; -+ -+ /* WLAN_GET_FIELD_16(&prWlanMacHeader->u2FrameCtrl, &u2RxFrameCtrl); */ -+ u2RxFrameCtrl = prWlanMacHeader->u2FrameCtrl; /* NOTE(Kevin): Optimized for ARM */ -+ -+ /* TODO(Kevin): Currently we won't send Deauth for IBSS node. How about DLS ? */ -+ if ((prWlanMacHeader->u2FrameCtrl & MASK_TO_DS_FROM_DS) == 0) -+ return WLAN_STATUS_FAILURE; -+ -+ /* Check if corresponding BSS is able to send Deauth */ -+ for (i = NETWORK_TYPE_AIS_INDEX; i < NETWORK_TYPE_INDEX_NUM; i++) { -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[i]); -+ -+ if (IS_NET_ACTIVE(prAdapter, i) && -+ (EQUAL_MAC_ADDR(prWlanMacHeader->aucAddr1, prBssInfo->aucOwnMacAddr))) { -+ { -+ fgIsAbleToSendDeauth = TRUE; -+ eNetTypeIndex = (ENUM_NETWORK_TYPE_INDEX_T) i; -+ break; -+ } -+ } -+ } -+ -+ if (!fgIsAbleToSendDeauth) -+ return WLAN_STATUS_FAILURE; -+ -+ pucReceiveAddr = prWlanMacHeader->aucAddr2; -+ -+ } else if (prStaRec) { -+ -+ pucReceiveAddr = prStaRec->aucMacAddr; -+ } else { -+#if CFG_ENABLE_WIFI_DIRECT -+ pucReceiveAddr = aucBMC; -+#else -+ return WLAN_STATUS_FAILURE; -+#endif -+ } -+ -+ /* 4 <2> Check if already send a Deauth frame in MIN_DEAUTH_INTERVAL_MSEC */ -+ GET_CURRENT_SYSTIME(&rCurrentTime); -+ -+ i4NewEntryIndex = -1; -+ for (i = 0; i < MAX_DEAUTH_INFO_COUNT; i++) { -+ prDeauthInfo = &(prAdapter->rWifiVar.arDeauthInfo[i]); -+ -+ /* For continuously sending Deauth frame, the minimum interval is -+ * MIN_DEAUTH_INTERVAL_MSEC. -+ */ -+ if (CHECK_FOR_TIMEOUT(rCurrentTime, -+ prDeauthInfo->rLastSendTime, MSEC_TO_SYSTIME(MIN_DEAUTH_INTERVAL_MSEC))) { -+ -+ i4NewEntryIndex = i; -+ } else if (EQUAL_MAC_ADDR(pucReceiveAddr, prDeauthInfo->aucRxAddr) && (!pfTxDoneHandler)) { -+ -+ return WLAN_STATUS_FAILURE; -+ } -+ } -+ -+ /* 4 <3> Update information. */ -+ if (i4NewEntryIndex > 0) { -+ -+ prDeauthInfo = &(prAdapter->rWifiVar.arDeauthInfo[i4NewEntryIndex]); -+ -+ COPY_MAC_ADDR(prDeauthInfo->aucRxAddr, pucReceiveAddr); -+ prDeauthInfo->rLastSendTime = rCurrentTime; -+ } else { -+ /* NOTE(Kevin): for the case of AP mode, we may encounter this case -+ * if deauth all the associated clients. -+ */ -+ DBGLOG(SAA, WARN, "No unused DEAUTH_INFO_T !\n"); -+ } -+ -+ /* 4 <4> Allocate a PKT_INFO_T for Deauthentication Frame */ -+ /* Init with MGMT Header Length + Length of Fixed Fields + IE Length */ -+ u2EstimatedFrameLen = (MAC_TX_RESERVED_FIELD + WLAN_MAC_MGMT_HEADER_LEN + REASON_CODE_FIELD_LEN); -+ -+ /* Allocate a MSDU_INFO_T */ -+ prMsduInfo = cnmMgtPktAlloc(prAdapter, u2EstimatedFrameLen); -+ if (prMsduInfo == NULL) { -+ DBGLOG(SAA, WARN, "No PKT_INFO_T for sending Deauth Request.\n"); -+ return WLAN_STATUS_RESOURCES; -+ } -+ /* 4 <5> Find the Transmitter Address and BSSID. */ -+ if (prClassErrSwRfb) { -+ -+ /* The TA of Deauth is the A1 of RX frame */ -+ pucTransmitAddr = prWlanMacHeader->aucAddr1; -+ -+ switch (prWlanMacHeader->u2FrameCtrl & MASK_TO_DS_FROM_DS) { -+ -+ case MASK_FC_FROM_DS: -+ /* The BSSID of Deauth is the A2 of RX frame */ -+ pucBssid = prWlanMacHeader->aucAddr2; -+ break; -+ -+ case MASK_FC_TO_DS: -+ /* The BSSID of Deauth is the A1 of RX frame */ -+ pucBssid = prWlanMacHeader->aucAddr1; -+ break; -+ -+ case MASK_TO_DS_FROM_DS: -+ /* TODO(Kevin): Consider BOW, now we set the BSSID of Deauth -+ * to the A2 of RX frame for temporary solution. -+ */ -+ pucBssid = prWlanMacHeader->aucAddr2; -+ break; -+ -+ /* No Default */ -+ } -+ -+ } else if (prStaRec) { -+ eNetTypeIndex = prStaRec->ucNetTypeIndex; -+ -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[eNetTypeIndex]); -+ -+ pucTransmitAddr = prBssInfo->aucOwnMacAddr; -+ -+ pucBssid = prBssInfo->aucBSSID; -+ } -+#if CFG_ENABLE_WIFI_DIRECT -+ else { -+ if (prAdapter->fgIsP2PRegistered) { -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); -+ -+ ucStaRecIdx = STA_REC_INDEX_BMCAST; -+ -+ pucTransmitAddr = prBssInfo->aucOwnMacAddr; -+ -+ pucBssid = prBssInfo->aucBSSID; -+ -+ eNetTypeIndex = NETWORK_TYPE_P2P_INDEX; -+ } else { -+ /* 20130122: free packet by samplin */ -+ cnmMgtPktFree(prAdapter, prMsduInfo); -+ return WLAN_STATUS_FAILURE; -+ } -+ } -+ -+#endif -+ -+ /* 4 <6> compose Deauthentication frame header and some fixed fields */ -+ authComposeDeauthFrameHeaderAndFF((PUINT_8) ((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD), -+ pucReceiveAddr, pucTransmitAddr, pucBssid, u2ReasonCode); -+ -+#if CFG_SUPPORT_802_11W -+ if (rsnCheckBipKeyInstalled(prAdapter, prStaRec)) { -+ P_WLAN_DEAUTH_FRAME_T prDeauthFrame; -+ -+ prDeauthFrame = -+ (P_WLAN_DEAUTH_FRAME_T) (PUINT_8) ((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD); -+ -+ prDeauthFrame->u2FrameCtrl |= MASK_FC_PROTECTED_FRAME; -+ DBGLOG(TX, WARN, "authSendDeauthFrame with protection\n"); -+ } -+#endif -+ -+ /* 4 <7> Update information of MSDU_INFO_T */ -+ prMsduInfo->eSrc = TX_PACKET_MGMT; -+ prMsduInfo->ucPacketType = HIF_TX_PACKET_TYPE_MGMT; -+ prMsduInfo->ucStaRecIndex = ((prStaRec == NULL) ? ucStaRecIdx : prStaRec->ucIndex); -+ prMsduInfo->ucNetworkType = (UINT_8) eNetTypeIndex; -+ prMsduInfo->ucMacHeaderLength = WLAN_MAC_MGMT_HEADER_LEN; -+ prMsduInfo->fgIs802_1x = FALSE; -+ prMsduInfo->fgIs802_11 = TRUE; -+ prMsduInfo->u2FrameLength = WLAN_MAC_MGMT_HEADER_LEN + REASON_CODE_FIELD_LEN; -+ prMsduInfo->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter); -+ prMsduInfo->pfTxDoneHandler = pfTxDoneHandler; -+ prMsduInfo->fgIsBasicRate = TRUE; -+ DBGLOG(SAA, INFO, "Sending Deauth, network: %d, seqNo %d\n", -+ eNetTypeIndex, prMsduInfo->ucTxSeqNum); -+ -+ /* 4 <8> Inform TXM to send this Deauthentication frame. */ -+ nicTxEnqueueMsdu(prAdapter, prMsduInfo); -+ -+ return WLAN_STATUS_SUCCESS; -+} /* end of authSendDeauthFrame() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will parse and process the incoming Deauthentication frame -+* if the given BSSID is matched. -+* -+* @param[in] prSwRfb Pointer to SW RFB data structure. -+* @param[in] aucBSSID Given BSSID -+* @param[out] pu2ReasonCode Pointer to store the Reason Code from Deauthentication. -+* -+* @retval WLAN_STATUS_FAILURE This is not the frame we should handle at current state. -+* @retval WLAN_STATUS_SUCCESS This is the frame we should handle. -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS authProcessRxDeauthFrame(IN P_SW_RFB_T prSwRfb, IN UINT_8 aucBSSID[], OUT PUINT_16 pu2ReasonCode) -+{ -+ P_WLAN_DEAUTH_FRAME_T prDeauthFrame; -+ UINT_16 u2RxReasonCode; -+ -+ ASSERT(prSwRfb); -+ ASSERT(aucBSSID); -+ ASSERT(pu2ReasonCode); -+ -+ /* 4 <1> locate the Deauthentication Frame. */ -+ prDeauthFrame = (P_WLAN_DEAUTH_FRAME_T) prSwRfb->pvHeader; -+ -+ /* 4 <2> Parse the Header of Deauthentication Frame. */ -+#if 0 /* Kevin: Seems redundant */ -+ WLAN_GET_FIELD_16(&prDeauthFrame->u2FrameCtrl, &u2RxFrameCtrl) -+ u2RxFrameCtrl &= MASK_FRAME_TYPE; -+ if (u2RxFrameCtrl != MAC_FRAME_DEAUTH) -+ return WLAN_STATUS_FAILURE; -+#endif -+ -+ if ((prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen) < REASON_CODE_FIELD_LEN) { -+ ASSERT(0); -+ return WLAN_STATUS_FAILURE; -+ } -+ -+ /* Check if this Deauth Frame is coming from Target BSSID */ -+ if (UNEQUAL_MAC_ADDR(prDeauthFrame->aucBSSID, aucBSSID)) { -+ DBGLOG(SAA, LOUD, "Ignore Deauth Frame from other BSS [ %pM ]\n", -+ prDeauthFrame->aucSrcAddr); -+ return WLAN_STATUS_FAILURE; -+ } -+ /* 4 <3> Parse the Fixed Fields of Deauthentication Frame Body. */ -+ WLAN_GET_FIELD_16(&prDeauthFrame->u2ReasonCode, &u2RxReasonCode); -+ *pu2ReasonCode = u2RxReasonCode; -+ -+ return WLAN_STATUS_SUCCESS; -+ -+} /* end of authProcessRxDeauthFrame() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will parse and process the incoming Authentication frame. -+* -+* @param[in] prSwRfb Pointer to SW RFB data structure. -+* @param[in] aucExpectedBSSID Given Expected BSSID. -+* @param[in] u2ExpectedAuthAlgNum Given Expected Authentication Algorithm Number -+* @param[in] u2ExpectedTransSeqNum Given Expected Transaction Sequence Number. -+* @param[out] pu2ReturnStatusCode Return Status Code. -+* -+* @retval WLAN_STATUS_SUCCESS This is the frame we should handle. -+* @retval WLAN_STATUS_FAILURE The frame we will ignore. -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+authProcessRxAuth1Frame(IN P_ADAPTER_T prAdapter, -+ IN P_SW_RFB_T prSwRfb, -+ IN UINT_8 aucExpectedBSSID[], -+ IN UINT_16 u2ExpectedAuthAlgNum, -+ IN UINT_16 u2ExpectedTransSeqNum, OUT PUINT_16 pu2ReturnStatusCode) -+{ -+ P_WLAN_AUTH_FRAME_T prAuthFrame; -+ UINT_16 u2ReturnStatusCode = STATUS_CODE_SUCCESSFUL; -+ -+ ASSERT(prSwRfb); -+ ASSERT(aucExpectedBSSID); -+ ASSERT(pu2ReturnStatusCode); -+ -+ /* 4 <1> locate the Authentication Frame. */ -+ prAuthFrame = (P_WLAN_AUTH_FRAME_T) prSwRfb->pvHeader; -+ -+ /* 4 <2> Check the BSSID */ -+ if (UNEQUAL_MAC_ADDR(prAuthFrame->aucBSSID, aucExpectedBSSID)) -+ return WLAN_STATUS_FAILURE; /* Just Ignore this MMPDU */ -+ /* 4 <3> Check the SA, which should not be MC/BC */ -+ if (prAuthFrame->aucSrcAddr[0] & BIT(0)) { -+ DBGLOG(P2P, WARN, "Invalid STA MAC with MC/BC bit set: %pM\n", -+ prAuthFrame->aucSrcAddr); -+ return WLAN_STATUS_FAILURE; -+ } -+ /* 4 <4> Parse the Fixed Fields of Authentication Frame Body. */ -+ if (prAuthFrame->u2AuthAlgNum != u2ExpectedAuthAlgNum) -+ u2ReturnStatusCode = STATUS_CODE_AUTH_ALGORITHM_NOT_SUPPORTED; -+ -+ if (prAuthFrame->u2AuthTransSeqNo != u2ExpectedTransSeqNum) -+ u2ReturnStatusCode = STATUS_CODE_AUTH_OUT_OF_SEQ; -+ -+ *pu2ReturnStatusCode = u2ReturnStatusCode; -+ -+ return WLAN_STATUS_SUCCESS; -+ -+} /* end of authProcessRxAuth1Frame() */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/bss.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/bss.c -new file mode 100644 -index 000000000000..160779583655 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/bss.c -@@ -0,0 +1,2521 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/bss.c#3 -+*/ -+ -+/*! \file "bss.c" -+ \brief This file contains the functions for creating BSS(AP)/IBSS(AdHoc). -+ -+ This file contains the functions for BSS(AP)/IBSS(AdHoc). We may create a BSS/IBSS -+ network, or merge with exist IBSS network and sending Beacon Frame or reply -+ the Probe Response Frame for received Probe Request Frame. -+*/ -+ -+/* -+** Log: bss.c -+** -+** 09 03 2013 cp.wu -+** add path for reassociation -+** -+** 08 30 2012 chinglan.wang -+** [ALPS00349664] [6577JB][WIFI] Phone can not connect to AP secured with AES via WPS in 802.11n Only -+** . -+** -+** 07 26 2012 yuche.tsai -+** [ALPS00324337] [ALPS.JB][Hot-Spot] Driver update for Hot-Spot -+** Update driver code of ALPS.JB for hot-spot. -+ * -+ * 07 17 2012 yuche.tsai -+ * NULL -+ * Let netdev bring up. -+ * -+ * 07 17 2012 yuche.tsai -+ * NULL -+ * Compile no error before trial run. -+ * -+ * 06 14 2012 chinglan.wang -+ * NULL -+ * Fix the losing of the HT IE in assoc request.. -+ * -+ * 06 13 2012 yuche.tsai -+ * NULL -+ * Update maintrunk driver. -+ * Add support for driver compose assoc request frame. -+ * -+ * 03 08 2012 yuche.tsai -+ * NULL -+ * Fix FW assert when start Hot-Spot. -+ * -+ * 03 02 2012 terry.wu -+ * NULL -+ * Snc CFG80211 modification for ICS migration from branch 2.2. -+ * -+ * 01 20 2012 chinglan.wang -+ * 03 02 2012 terry.wu -+ * NULL -+ * Fix the WPA-PSK TKIP and WPA2-PSK AES security mode bug. -+ * -+ * NULL -+ * Sync CFG80211 modification from branch 2,2. -+ * -+ * 01 15 2012 yuche.tsai -+ * NULL -+ * Fix wrong basic rate issue. -+ * -+ * 01 13 2012 yuche.tsai -+ * NULL -+ * WiFi Hot Spot Tethering for ICS ALPHA testing version. -+ * -+ * 11 03 2011 cm.chang -+ * [WCXRP00000997] [MT6620 Wi-Fi][Driver][FW] Handle change of BSS preamble type and slot time -+ * Always set short slot time to TRUE initially in AP mode -+ * -+ * 11 03 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * change the DBGLOG for "\n" and "\r\n". LABEL to LOUD for XLOG -+ * -+ * 09 14 2011 yuche.tsai -+ * NULL -+ * Add P2P IE in assoc response. -+ * -+ * 04 18 2011 terry.wu -+ * [WCXRP00000660] [MT6620 Wi-Fi][Driver] Remove flag CFG_WIFI_DIRECT_MOVED -+ * Remove flag CFG_WIFI_DIRECT_MOVED. -+ * -+ * 04 12 2011 eddie.chen -+ * [WCXRP00000617] [MT6620 Wi-Fi][DRV/FW] Fix for sigma -+ * Fix the sta index in processing security frame -+ * Simple flow control for TC4 to avoid mgt frames for PS STA to occupy the TC4 -+ * Add debug message. -+ * -+ * 04 08 2011 eddie.chen -+ * [WCXRP00000617] [MT6620 Wi-Fi][DRV/FW] Fix for sigma -+ * Fix for sigma -+ * -+ * 03 29 2011 eddie.chen -+ * [WCXRP00000608] [MT6620 Wi-Fi][DRV] Change wmm parameters in beacon -+ * Change wmm parameters in beacon. -+ * -+ * 03 29 2011 yuche.tsai -+ * [WCXRP00000607] [Volunteer Patch][MT6620][Driver] Coding Style Fix for klocwork scan. -+ * Fix klocwork issue. -+ * -+ * 03 19 2011 yuche.tsai -+ * [WCXRP00000581] [Volunteer Patch][MT6620][Driver] P2P IE in Assoc Req Issue -+ * Make assoc req to append P2P IE if wifi direct is enabled. -+ * -+ * 03 11 2011 chinglan.wang -+ * [WCXRP00000537] [MT6620 Wi-Fi][Driver] Can not connect to 802.11b/g/n mixed AP with WEP security. -+ * . -+ * -+ * 03 03 2011 george.huang -+ * [WCXRP00000508] [MT6620 Wi-Fi][Driver] aware of beacon MSDU will be free, after BSS deactivated -+ * . -+ * -+ * 03 03 2011 george.huang -+ * [WCXRP00000508] [MT6620 Wi-Fi][Driver] aware of beacon MSDU will be free, after BSS deactivated -+ * modify to handle if beacon MSDU been released when BSS deactivated -+ * -+ * 03 02 2011 wh.su -+ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code -+ * add code to let the beacon and probe response for Auto GO WSC . -+ * -+ * 03 02 2011 wh.su -+ * [WCXRP00000448] [MT6620 Wi-Fi][Driver] Fixed WSC IE not send out at probe request -+ * Add code to send beacon and probe response WSC IE at Auto GO. -+ * -+ * 02 17 2011 eddie.chen -+ * [WCXRP00000458] [MT6620 Wi-Fi][Driver] BOW Concurrent - ProbeResp was exist in other channel -+ * 1) Change GetFrameAction decision when BSS is absent. -+ * 2) Check channel and resource in processing ProbeRequest -+ * -+ * 02 12 2011 yuche.tsai -+ * [WCXRP00000441] [Volunteer Patch][MT6620][Driver] BoW can not create desired station type when Hot Spot is enabled. -+ * bss should create station record type according to callers input. -+ * -+ * 02 11 2011 terry.wu -+ * [WCXRP00000383] [MT6620 Wi-Fi][Driver] Separate WiFi and P2P driver into two modules -+ * In p2p link function, check networktype before calling p2p function. -+ * -+ * 02 11 2011 terry.wu -+ * [WCXRP00000383] [MT6620 Wi-Fi][Driver] Separate WiFi and P2P driver into two modules -+ * Modify p2p link function to avoid assert. -+ * -+ * 01 26 2011 cm.chang -+ * [WCXRP00000395] [MT6620 Wi-Fi][Driver][FW] Search STA_REC with additional net type index argument -+ * . -+ * -+ * 01 25 2011 yuche.tsai -+ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record. -+ * Change Station Type in Station Record, Modify MACRO definition for getting station type & network type index & Role. -+ * -+ * 01 25 2011 eddie.chen -+ * [WCXRP00000385] [MT6620 Wi-Fi][DRV] Add destination decision for forwarding packets -+ * Fix the compile error in windows. -+ * -+ * 01 24 2011 eddie.chen -+ * [WCXRP00000385] [MT6620 Wi-Fi][DRV] Add destination decision for forwarding packets -+ * Add destination decision in AP mode. -+ * -+ * 01 24 2011 terry.wu -+ * [WCXRP00000383] [MT6620 Wi-Fi][Driver] Separate WiFi and P2P driver into two modules -+ * .Fix typo and missing entry -+ * -+ * 12 30 2010 eddie.chen -+ * [WCXRP00000322] Add WMM IE in beacon, -+ -+Add per station flow control when STA is in PS -+ -+ * Fix prBssInfo->aucCWminLog to prBssInfo->aucCWminLogForBcast -+ * -+ * 12 29 2010 eddie.chen -+ * [WCXRP00000322] Add WMM IE in beacon, -+ -+Add per station flow control when STA is in PS -+ -+ * Add WMM parameter for broadcast. -+ * -+ * 12 29 2010 eddie.chen -+ * [WCXRP00000322] Add WMM IE in beacon, -+Add per station flow control when STA is in PS -+ -+ * 1) PS flow control event -+ * -+ * 2) WMM IE in beacon, assoc resp, probe resp -+ * -+ * 11 29 2010 cp.wu -+ * [WCXRP00000210] [MT6620 Wi-Fi][Driver][FW] Set RCPI value in STA_REC -+ * for initial TX rate selection of auto-rate algorithm -+ * update ucRcpi of STA_RECORD_T for AIS when -+ * 1) Beacons for IBSS merge is received -+ * 2) Associate Response for a connecting peer is received -+ * -+ * 10 18 2010 cp.wu -+ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning -+ * use definition macro to replace hard-coded constant -+ * -+ * 10 08 2010 wh.su -+ * [WCXRP00000085] [MT6620 Wif-Fi] [Driver] update the modified p2p state machine -+ * update the frog's new p2p state machine. -+ * -+ * 09 28 2010 wh.su -+ * NULL -+ * [WCXRP00000069][MT6620 Wi-Fi][Driver] Fix some code for phase 1 P2P Demo. -+ * -+ * 09 27 2010 chinghwa.yu -+ * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000065] Update BoW design and settings -+ * Update BCM/BoW design and settings. -+ * -+ * 09 16 2010 cm.chang -+ * NULL -+ * Change conditional compiling options for BOW -+ * -+ * 09 10 2010 cm.chang -+ * NULL -+ * Always update Beacon content if FW sync OBSS info -+ * -+ * 09 07 2010 wh.su -+ * NULL -+ * adding the code for beacon/probe req/ probe rsp wsc ie at p2p. -+ * -+ * 09 03 2010 kevin.huang -+ * NULL -+ * Refine #include sequence and solve recursive/nested #include issue -+ * -+ * 08 31 2010 kevin.huang -+ * NULL -+ * Use LINK LIST operation to process SCAN result -+ * -+ * 08 30 2010 cp.wu -+ * NULL -+ * eliminate klockwork errors -+ * -+ * 08 29 2010 yuche.tsai -+ * NULL -+ * Finish SLT TX/RX & Rate Changing Support. -+ * -+ * 08 24 2010 cm.chang -+ * NULL -+ * Support RLM initail channel of Ad-hoc, P2P and BOW -+ * -+ * 08 16 2010 yuche.tsai -+ * NULL -+ * Before composing Beacon IE, assign network type index for msdu info, -+ * this information is needed by RLM module while composing some RLM related IE field. -+ * -+ * 08 16 2010 cp.wu -+ * NULL -+ * Replace CFG_SUPPORT_BOW by CFG_ENABLE_BT_OVER_WIFI. -+ * There is no CFG_SUPPORT_BOW in driver domain source. -+ * -+ * 08 16 2010 kevin.huang -+ * NULL -+ * Refine AAA functions -+ * -+ * 08 12 2010 kevin.huang -+ * NULL -+ * Fix undefined pucDestAddr in bssUpdateBeaconContent() -+ * -+ * 08 12 2010 kevin.huang -+ * NULL -+ * Refine bssProcessProbeRequest() and bssSendBeaconProbeResponse() -+ * -+ * 08 11 2010 cp.wu -+ * NULL -+ * 1) do not use in-stack variable for beacon updating. (for MAUI porting) -+ * 2) extending scanning result to 64 instead of 48 -+ * -+ * 08 02 2010 yuche.tsai -+ * NULL -+ * P2P Group Negotiation Code Check in. -+ * -+ * 08 02 2010 george.huang -+ * NULL -+ * add WMM-PS test related OID/ CMD handlers -+ * -+ * 07 26 2010 yuche.tsai -+ * -+ * Add support to RX probe response for P2P. -+ * -+ * 07 20 2010 cp.wu -+ * -+ * 1) bugfix: do not stop timer for join after switched into normal_tr state, for providing chance for DHCP handshasking -+ * 2) modify rsnPerformPolicySelection() invoking -+ * -+ * 07 19 2010 wh.su -+ * -+ * update for security supporting. -+ * -+ * 07 19 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration. -+ * when IBSS is being merged-in, send command packet to PM for connected indication -+ * -+ * 07 19 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration. -+ * Add Ad-Hoc support to AIS-FSM -+ * -+ * 07 14 2010 yarco.yang -+ * -+ * 1. Remove CFG_MQM_MIGRATION -+ * 2. Add CMD_UPDATE_WMM_PARMS command -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 07 06 2010 george.huang -+ * [WPD00001556]Basic power managemenet function -+ * Update arguments for nicUpdateBeaconIETemplate() -+ * -+ * 06 29 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) sync to. CMD/EVENT document v0.03 -+ * 2) simplify DTIM period parsing in scan.c only, bss.c no longer parses it again. -+ * 3) send command packet to indicate FW-PM after -+ * a) 1st beacon is received after AIS has connected to an AP -+ * b) IBSS-ALONE has been created -+ * c) IBSS-MERGE has occurred -+ * -+ * 06 28 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * send MMPDU in basic rate. -+ * -+ * 06 25 2010 george.huang -+ * [WPD00001556]Basic power managemenet function -+ * Create beacon update path, with expose bssUpdateBeaconContent() -+ * -+ * 06 21 2010 yuche.tsai -+ * [WPD00003839][MT6620 5931][P2P] Feature migration -+ * Fix compile error while enable WIFI_DIRECT support. -+ * -+ * 06 21 2010 yarco.yang -+ * [WPD00003837][MT6620]Data Path Refine -+ * Support CFG_MQM_MIGRATION flag -+ * -+ * 06 21 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * enable RX management frame handling. -+ * -+ * 06 21 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * specify correct value for management frames. -+ * -+ * 06 18 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Provide cnmMgtPktAlloc() and alloc/free function of msg/buf -+ * -+ * 06 15 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * correct when ADHOC support is turned on. -+ * -+ * 06 15 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add scan.c. -+ * -+ * 06 14 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add management dispatching function table. -+ * -+ * 06 11 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * auth.c is migrated. -+ * -+ * 06 11 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * fix compilation error when WIFI_DIRECT is turned on -+ * -+ * 06 11 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add bss.c. -+ * -+ * 06 04 2010 george.huang -+ * [BORA00000678][MT6620]WiFi LP integration -+ * [PM] Support U-APSD for STA mode -+ * -+ * 05 28 2010 kevin.huang -+ * [BORA00000794][WIFISYS][New Feature]Power Management Support -+ * Add ClientList handling API - bssClearClientList, bssAddStaRecToClientList -+ * -+ * 05 24 2010 kevin.huang -+ * [BORA00000794][WIFISYS][New Feature]Power Management Support -+ * Update bssProcessProbeRequest() to avoid redundant SSID IE {0,0} for IOT. -+ * -+ * 05 21 2010 kevin.huang -+ * [BORA00000794][WIFISYS][New Feature]Power Management Support -+ * Refine txmInitWtblTxRateTable() - set TX initial rate according to AP's operation rate set -+ * -+ * 05 18 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Ad-hoc Beacon should not carry HT OP and OBSS IEs -+ * -+ * 05 14 2010 kevin.huang -+ * [BORA00000794][WIFISYS][New Feature]Power Management Support -+ * Use TX MGMT Frame API for sending PS NULL frame to avoid the TX Burst Mechanism in TX FW Frame API -+ * -+ * 05 14 2010 kevin.huang -+ * [BORA00000794][WIFISYS][New Feature]Power Management Support -+ * Separate Beacon and ProbeResp IE array -+ * -+ * 05 12 2010 kevin.huang -+ * [BORA00000794][WIFISYS][New Feature]Power Management Support -+ * Add Power Management - Legacy PS-POLL support. -+ * -+ * 04 28 2010 tehuang.liu -+ * [BORA00000605][WIFISYS] Phase3 Integration -+ * Removed the use of compiling flag MQM_WMM_PARSING -+ * -+ * 04 27 2010 kevin.huang -+ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support -+ * Add Set Slot Time and Beacon Timeout Support for AdHoc Mode -+ * -+ * 04 24 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * g_aprBssInfo[] depends on CFG_SUPPORT_P2P and CFG_SUPPORT_BOW -+ * -+ * 04 22 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * First draft code to support protection in AP mode -+ * -+ * 04 20 2010 kevin.huang -+ * [BORA00000714][WIFISYS][New Feature]Beacon Timeout Support -+ * Fix restart Beacon Timeout Func after connection diagnosis -+ * -+ * 04 19 2010 kevin.huang -+ * [BORA00000714][WIFISYS][New Feature]Beacon Timeout Support -+ * Add Beacon Timeout Support and will send Null frame to diagnose connection -+ * -+ * 04 16 2010 wh.su -+ * [BORA00000680][MT6620] Support the statistic for Micxxsoft os query -+ * adding the wpa-none for ibss beacon. -+ * -+ * 04 15 2010 wh.su -+ * [BORA00000680][MT6620] Support the statistic for Micxxsoft os query -+ * fixed the protected bit at cap info for ad-hoc. -+ * -+ * 03 18 2010 kevin.huang -+ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support -+ * Rename the CFG flags -+ * -+ * 03 16 2010 kevin.huang -+ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support -+ * Add AdHoc Mode -+ * -+ * 02 26 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Update outgoing beacon's TX data rate -+ * -+ * 02 23 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Add DTIM count update while TX Beacon -+ * -+ * 02 05 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Modify code due to define - BAND_24G and specific BSS_INFO_T was changed -+ * -+ * 02 05 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Revise data structure to share the same BSS_INFO_T for avoiding coding error -+ * -+ * 02 04 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Add AAA Module Support, Revise Net Type to Net Type Index for array lookup -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "precomp.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+#if (CFG_SUPPORT_ADHOC) || (CFG_SUPPORT_AAA) -+APPEND_VAR_IE_ENTRY_T txBcnIETable[] = { -+ {(ELEM_HDR_LEN + (RATE_NUM - ELEM_MAX_LEN_SUP_RATES)), NULL, bssGenerateExtSuppRate_IE}, /* 50 */ -+ {(ELEM_HDR_LEN + ELEM_MAX_LEN_ERP), NULL, rlmRspGenerateErpIE}, /* 42 */ -+ {(ELEM_HDR_LEN + ELEM_MAX_LEN_HT_CAP), NULL, rlmRspGenerateHtCapIE}, /* 45 */ -+ {(ELEM_HDR_LEN + ELEM_MAX_LEN_HT_OP), NULL, rlmRspGenerateHtOpIE}, /* 61 */ -+#if CFG_ENABLE_WIFI_DIRECT -+ {(ELEM_HDR_LEN + ELEM_MAX_LEN_OBSS_SCAN), NULL, rlmRspGenerateObssScanIE}, /* 74 */ -+#endif -+ {(ELEM_HDR_LEN + ELEM_MAX_LEN_EXT_CAP), NULL, rlmRspGenerateExtCapIE}, /* 127 */ -+ {(ELEM_HDR_LEN + ELEM_MAX_LEN_WPA), NULL, rsnGenerateWpaNoneIE}, /* 221 */ -+ {(ELEM_HDR_LEN + ELEM_MAX_LEN_WMM_PARAM), NULL, mqmGenerateWmmParamIE}, /* 221 */ -+#if CFG_ENABLE_WIFI_DIRECT -+ {(ELEM_HDR_LEN + ELEM_MAX_LEN_WPA), NULL, rsnGenerateWPAIE}, /* 221 */ -+ {(ELEM_HDR_LEN + ELEM_MAX_LEN_RSN), NULL, rsnGenerateRSNIE}, /* 48 */ -+#if 0 /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0) */ -+ {0, p2pFuncCalculateExtra_IELenForBeacon, p2pFuncGenerateExtra_IEForBeacon}, /* 221 */ -+#else -+ {0, p2pFuncCalculateP2p_IELenForBeacon, p2pFuncGenerateP2p_IEForBeacon}, /* 221 */ -+ {0, p2pFuncCalculateWSC_IELenForBeacon, p2pFuncGenerateWSC_IEForBeacon}, /* 221 */ -+ {0, p2pFuncCalculateP2P_IE_NoA, p2pFuncGenerateP2P_IE_NoA}, /* 221 */ -+#endif -+#endif /* CFG_ENABLE_WIFI_DIRECT */ -+}; -+ -+APPEND_VAR_IE_ENTRY_T txProbRspIETable[] = { -+ {(ELEM_HDR_LEN + (RATE_NUM - ELEM_MAX_LEN_SUP_RATES)), NULL, bssGenerateExtSuppRate_IE}, /* 50 */ -+ {(ELEM_HDR_LEN + ELEM_MAX_LEN_ERP), NULL, rlmRspGenerateErpIE}, /* 42 */ -+ {(ELEM_HDR_LEN + ELEM_MAX_LEN_HT_CAP), NULL, rlmRspGenerateHtCapIE}, /* 45 */ -+ {(ELEM_HDR_LEN + ELEM_MAX_LEN_HT_OP), NULL, rlmRspGenerateHtOpIE}, /* 61 */ -+#if CFG_ENABLE_WIFI_DIRECT -+ {(ELEM_HDR_LEN + ELEM_MAX_LEN_RSN), NULL, rsnGenerateRSNIE}, /* 48 */ -+ {(ELEM_HDR_LEN + ELEM_MAX_LEN_OBSS_SCAN), NULL, rlmRspGenerateObssScanIE}, /* 74 */ -+#endif -+ {(ELEM_HDR_LEN + ELEM_MAX_LEN_EXT_CAP), NULL, rlmRspGenerateExtCapIE}, /* 127 */ -+ {(ELEM_HDR_LEN + ELEM_MAX_LEN_WPA), NULL, rsnGenerateWpaNoneIE}, /* 221 */ -+ {(ELEM_HDR_LEN + ELEM_MAX_LEN_WMM_PARAM), NULL, mqmGenerateWmmParamIE} /* 221 */ -+}; -+ -+#endif /* CFG_SUPPORT_ADHOC || CFG_SUPPORT_AAA */ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+/*----------------------------------------------------------------------------*/ -+/* Routines for all Operation Modes */ -+/*----------------------------------------------------------------------------*/ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will create or reset a STA_RECORD_T by given BSS_DESC_T for -+* Infrastructure or AdHoc Mode. -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* @param[in] eStaType Assign STA Type for this STA_RECORD_T -+* @param[in] eNetTypeIndex Assign Net Type Index for this STA_RECORD_T -+* @param[in] prBssDesc Received Beacon/ProbeResp from this STA -+* -+* @retval Pointer to STA_RECORD_T -+*/ -+/*----------------------------------------------------------------------------*/ -+P_STA_RECORD_T -+bssCreateStaRecFromBssDesc(IN P_ADAPTER_T prAdapter, -+ IN ENUM_STA_TYPE_T eStaType, -+ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_BSS_DESC_T prBssDesc) -+{ -+ P_STA_RECORD_T prStaRec; -+ UINT_8 ucNonHTPhyTypeSet; -+ -+ ASSERT(prBssDesc); -+ -+ /* 4 <1> Get a valid STA_RECORD_T */ -+ prStaRec = cnmGetStaRecByAddress(prAdapter, (UINT_8) eNetTypeIndex, prBssDesc->aucSrcAddr); -+ if (!prStaRec) { -+ -+ prStaRec = cnmStaRecAlloc(prAdapter, (UINT_8) eNetTypeIndex); -+ -+ /* TODO(Kevin): Error handling of allocation of STA_RECORD_T for -+ * exhausted case and do removal of unused STA_RECORD_T. -+ */ -+ -+ if (!prStaRec) { -+ ASSERT(FALSE); -+ return NULL; -+ } -+ -+ ASSERT(prStaRec); -+ -+ prStaRec->ucStaState = STA_STATE_1; -+ prStaRec->ucJoinFailureCount = 0; -+ /* TODO(Kevin): If this is an old entry, we may also reset the ucJoinFailureCount to 0. -+ */ -+ -+ COPY_MAC_ADDR(prStaRec->aucMacAddr, prBssDesc->aucSrcAddr); -+ } -+ /* 4 <2> Setup STA TYPE and NETWORK */ -+ prStaRec->eStaType = eStaType; -+ -+ prStaRec->ucNetTypeIndex = eNetTypeIndex; -+ -+ /* 4 <3> Update information from BSS_DESC_T to current P_STA_RECORD_T */ -+ prStaRec->u2CapInfo = prBssDesc->u2CapInfo; -+ -+ prStaRec->u2OperationalRateSet = prBssDesc->u2OperationalRateSet; -+ prStaRec->u2BSSBasicRateSet = prBssDesc->u2BSSBasicRateSet; -+ -+ prStaRec->ucPhyTypeSet = prBssDesc->ucPhyTypeSet; -+ if (IS_STA_IN_AIS(prStaRec)) { -+ if (!((prAdapter->rWifiVar.rConnSettings.eEncStatus == ENUM_ENCRYPTION3_ENABLED) || -+ (prAdapter->rWifiVar.rConnSettings.eEncStatus == ENUM_ENCRYPTION3_KEY_ABSENT) || -+ (prAdapter->rWifiVar.rConnSettings.eEncStatus == ENUM_ENCRYPTION_DISABLED) || -+ (prAdapter->prGlueInfo->u2WSCAssocInfoIELen) || (prAdapter->prGlueInfo->u2WapiAssocInfoIESz))) { -+ DBGLOG(BSS, TRACE, "Ignore the HT Bit for TKIP as pairwise cipher configured!\n"); -+ prStaRec->ucPhyTypeSet &= ~PHY_TYPE_BIT_HT; -+ } -+ } else { -+ DBGLOG(BSS, TRACE, "P2P skip TKIP limitation for HT Hit!\n"); -+ } -+ prStaRec->ucDesiredPhyTypeSet = prStaRec->ucPhyTypeSet & prAdapter->rWifiVar.ucAvailablePhyTypeSet; -+ -+ ucNonHTPhyTypeSet = prStaRec->ucDesiredPhyTypeSet & PHY_TYPE_SET_802_11ABG; -+ -+ /* Check for Target BSS's non HT Phy Types */ -+ if (ucNonHTPhyTypeSet) { -+ -+ if (ucNonHTPhyTypeSet & PHY_TYPE_BIT_ERP) { -+ prStaRec->ucNonHTBasicPhyType = PHY_TYPE_ERP_INDEX; -+ } else if (ucNonHTPhyTypeSet & PHY_TYPE_BIT_OFDM) { -+ prStaRec->ucNonHTBasicPhyType = PHY_TYPE_OFDM_INDEX; -+ } else { /* if (ucNonHTPhyTypeSet & PHY_TYPE_HR_DSSS_INDEX) */ -+ -+ prStaRec->ucNonHTBasicPhyType = PHY_TYPE_HR_DSSS_INDEX; -+ } -+ -+ prStaRec->fgHasBasicPhyType = TRUE; -+ } else { -+ /* Use mandatory for 11N only BSS */ -+ ASSERT(prStaRec->ucPhyTypeSet & PHY_TYPE_SET_802_11N); -+ -+ { -+ /* TODO(Kevin): which value should we set for 11n ? ERP ? */ -+ prStaRec->ucNonHTBasicPhyType = PHY_TYPE_HR_DSSS_INDEX; -+ } -+ -+ prStaRec->fgHasBasicPhyType = FALSE; -+ } -+ -+ /* Update non HT Desired Rate Set */ -+ { -+ P_CONNECTION_SETTINGS_T prConnSettings; -+ -+ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); -+ -+ prStaRec->u2DesiredNonHTRateSet = -+ (prStaRec->u2OperationalRateSet & prConnSettings->u2DesiredNonHTRateSet); -+ } -+ -+ /* 4 <4> Update information from BSS_DESC_T to current P_STA_RECORD_T */ -+ if (IS_AP_STA(prStaRec)) { -+ /* do not need to parse IE for DTIM, -+ * which have been parsed before inserting into BSS_DESC_T -+ */ -+ if (prBssDesc->ucDTIMPeriod) -+ prStaRec->ucDTIMPeriod = prBssDesc->ucDTIMPeriod; -+ else -+ prStaRec->ucDTIMPeriod = 0; /* Means that TIM was not parsed. */ -+ } -+ /* 4 <5> Update default value */ -+ prStaRec->fgDiagnoseConnection = FALSE; -+ -+ /* 4 <6> Update default value for other Modules */ -+ /* Determine fgIsWmmSupported and fgIsUapsdSupported in STA_REC */ -+ mqmProcessScanResult(prAdapter, prBssDesc, prStaRec); -+ -+ return prStaRec; -+ -+} /* end of bssCreateStaRecFromBssDesc() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will compose the Null Data frame. -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* @param[in] pucBuffer Pointer to the frame buffer. -+* @param[in] prStaRec Pointer to the STA_RECORD_T. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID bssComposeNullFrame(IN P_ADAPTER_T prAdapter, IN PUINT_8 pucBuffer, IN P_STA_RECORD_T prStaRec) -+{ -+ P_WLAN_MAC_HEADER_T prNullFrame; -+ P_BSS_INFO_T prBssInfo; -+ UINT_16 u2FrameCtrl; -+ -+ ASSERT(pucBuffer); -+ ASSERT(prStaRec); -+ ASSERT(prStaRec->ucNetTypeIndex < NETWORK_TYPE_INDEX_NUM); -+ -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]); -+ -+ ASSERT(prBssInfo); -+ -+ prNullFrame = (P_WLAN_MAC_HEADER_T) pucBuffer; -+ -+ /* 4 <1> Decide the Frame Control Field */ -+ u2FrameCtrl = MAC_FRAME_NULL; -+ -+ if (IS_AP_STA(prStaRec)) { -+ u2FrameCtrl |= MASK_FC_TO_DS; -+ -+ if (prStaRec->fgSetPwrMgtBit) -+ u2FrameCtrl |= MASK_FC_PWR_MGT; -+ } else if (IS_CLIENT_STA(prStaRec)) { -+ u2FrameCtrl |= MASK_FC_FROM_DS; -+ } else if (IS_DLS_STA(prStaRec)) { -+ /* TODO(Kevin) */ -+ } else { -+ /* NOTE(Kevin): We won't send Null frame for IBSS */ -+ ASSERT(0); -+ return; -+ } -+ -+ /* 4 <2> Compose the Null frame */ -+ /* Fill the Frame Control field. */ -+ /* WLAN_SET_FIELD_16(&prNullFrame->u2FrameCtrl, u2FrameCtrl); */ -+ prNullFrame->u2FrameCtrl = u2FrameCtrl; /* NOTE(Kevin): Optimized for ARM */ -+ -+ /* Fill the Address 1 field with Target Peer Address. */ -+ COPY_MAC_ADDR(prNullFrame->aucAddr1, prStaRec->aucMacAddr); -+ -+ /* Fill the Address 2 field with our MAC Address. */ -+ COPY_MAC_ADDR(prNullFrame->aucAddr2, prBssInfo->aucOwnMacAddr); -+ -+ /* Fill the Address 3 field with Target BSSID. */ -+ COPY_MAC_ADDR(prNullFrame->aucAddr3, prBssInfo->aucBSSID); -+ -+ /* Clear the SEQ/FRAG_NO field(HW won't overide the FRAG_NO, so we need to clear it). */ -+ prNullFrame->u2SeqCtrl = 0; -+ -+ return; -+ -+} /* end of bssComposeNullFrameHeader() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will compose the QoS Null Data frame. -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* @param[in] pucBuffer Pointer to the frame buffer. -+* @param[in] prStaRec Pointer to the STA_RECORD_T. -+* @param[in] ucUP User Priority. -+* @param[in] fgSetEOSP Set the EOSP bit. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+bssComposeQoSNullFrame(IN P_ADAPTER_T prAdapter, -+ IN PUINT_8 pucBuffer, IN P_STA_RECORD_T prStaRec, IN UINT_8 ucUP, IN BOOLEAN fgSetEOSP) -+{ -+ P_WLAN_MAC_HEADER_QOS_T prQoSNullFrame; -+ P_BSS_INFO_T prBssInfo; -+ UINT_16 u2FrameCtrl; -+ UINT_16 u2QosControl; -+ -+ ASSERT(pucBuffer); -+ ASSERT(prStaRec); -+ ASSERT(prStaRec->ucNetTypeIndex < NETWORK_TYPE_INDEX_NUM); -+ -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]); -+ -+ ASSERT(prBssInfo); -+ -+ prQoSNullFrame = (P_WLAN_MAC_HEADER_QOS_T) pucBuffer; -+ -+ /* 4 <1> Decide the Frame Control Field */ -+ u2FrameCtrl = MAC_FRAME_QOS_NULL; -+ -+ if (IS_AP_STA(prStaRec)) { -+ u2FrameCtrl |= MASK_FC_TO_DS; -+ -+ if (prStaRec->fgSetPwrMgtBit) -+ u2FrameCtrl |= MASK_FC_PWR_MGT; -+ } else if (IS_CLIENT_STA(prStaRec)) { -+ u2FrameCtrl |= MASK_FC_FROM_DS; -+ } else if (IS_DLS_STA(prStaRec)) { -+ /* TODO(Kevin) */ -+ } else { -+ /* NOTE(Kevin): We won't send QoS Null frame for IBSS */ -+ ASSERT(0); -+ return; -+ } -+ -+ /* 4 <2> Compose the QoS Null frame */ -+ /* Fill the Frame Control field. */ -+ /* WLAN_SET_FIELD_16(&prQoSNullFrame->u2FrameCtrl, u2FrameCtrl); */ -+ prQoSNullFrame->u2FrameCtrl = u2FrameCtrl; /* NOTE(Kevin): Optimized for ARM */ -+ -+ /* Fill the Address 1 field with Target Peer Address. */ -+ COPY_MAC_ADDR(prQoSNullFrame->aucAddr1, prStaRec->aucMacAddr); -+ -+ /* Fill the Address 2 field with our MAC Address. */ -+ COPY_MAC_ADDR(prQoSNullFrame->aucAddr2, prBssInfo->aucOwnMacAddr); -+ -+ /* Fill the Address 3 field with Target BSSID. */ -+ COPY_MAC_ADDR(prQoSNullFrame->aucAddr3, prBssInfo->aucBSSID); -+ -+ /* Clear the SEQ/FRAG_NO field(HW won't overide the FRAG_NO, so we need to clear it). */ -+ prQoSNullFrame->u2SeqCtrl = 0; -+ -+ u2QosControl = (UINT_16) (ucUP & WMM_QC_UP_MASK); -+ -+ if (fgSetEOSP) -+ u2QosControl |= WMM_QC_EOSP; -+ /* WLAN_SET_FIELD_16(&prQoSNullFrame->u2QosCtrl, u2QosControl); */ -+ prQoSNullFrame->u2QosCtrl = u2QosControl; /* NOTE(Kevin): Optimized for ARM */ -+ -+ return; -+ -+} /* end of bssComposeQoSNullFrameHeader() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Send the Null Frame -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* @param[in] prStaRec Pointer to the STA_RECORD_T -+* @param[in] pfTxDoneHandler TX Done call back function -+* -+* @retval WLAN_STATUS_RESOURCE No available resources to send frame. -+* @retval WLAN_STATUS_SUCCESS Succe]ss. -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+bssSendNullFrame(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN PFN_TX_DONE_HANDLER pfTxDoneHandler) -+{ -+ P_MSDU_INFO_T prMsduInfo; -+ UINT_16 u2EstimatedFrameLen; -+ -+ /* 4 <1> Allocate a PKT_INFO_T for Null Frame */ -+ /* Init with MGMT Header Length */ -+ u2EstimatedFrameLen = MAC_TX_RESERVED_FIELD + WLAN_MAC_HEADER_LEN; -+ -+ /* Allocate a MSDU_INFO_T */ -+ prMsduInfo = cnmMgtPktAlloc(prAdapter, u2EstimatedFrameLen); -+ if (prMsduInfo == NULL) { -+ DBGLOG(BSS, WARN, "No PKT_INFO_T for sending Null Frame.\n"); -+ return WLAN_STATUS_RESOURCES; -+ } -+ /* 4 <2> Compose Null frame in MSDU_INfO_T. */ -+ bssComposeNullFrame(prAdapter, (PUINT_8) ((ULONG) prMsduInfo->prPacket + MAC_TX_RESERVED_FIELD), prStaRec); -+#if 0 -+ /* 4 <3> Update information of MSDU_INFO_T */ -+ TXM_SET_DATA_PACKET( -+ /* STA_REC ptr */ prStaRec, -+ /* MSDU_INFO ptr */ prMsduInfo, -+ /* MAC HDR ptr */ (prMsduInfo->pucBuffer + MAC_TX_RESERVED_FIELD), -+ /* MAC HDR length */ WLAN_MAC_HEADER_LEN, -+ /* PAYLOAD ptr */ -+ (prMsduInfo->pucBuffer + MAC_TX_RESERVED_FIELD + WLAN_MAC_HEADER_LEN), -+ /* PAYLOAD length */ 0, -+ /* Network Type Index */ (UINT_8) prStaRec->ucNetTypeIndex, -+ /* TID */ 0 /* BE: AC1 */ , -+ /* Flag 802.11 */ TRUE, -+ /* Pkt arrival time */ 0 /* TODO: Obtain the system time */ , -+ /* Resource TC */ 0 /* Irrelevant */ , -+ /* Flag 802.1x */ FALSE, -+ /* TX-done callback */ pfTxDoneHandler, -+ /* PS forwarding type */ PS_FORWARDING_TYPE_NON_PS, -+ /* PS Session ID */ 0 /* Irrelevant */ , -+ /* Flag fixed rate */ TRUE, -+ /* Fixed tx rate */ g_aprBssInfo[prStaRec->ucNetTypeIndex]->ucHwDefaultFixedRateCode, -+ /* Fixed-rate retry */ BSS_DEFAULT_CONN_TEST_NULL_FRAME_RETRY_LIMIT, -+ /* PAL LLH */ 0 /* Irrelevant */ , -+ /* ACL SN */ 0 /* Irrelevant */ , -+ /* Flag No Ack */ FALSE -+ ); -+ -+ /* Terminate with a NULL pointer */ -+ NIC_HIF_TX_SET_NEXT_MSDU_INFO(prMsduInfo, NULL); -+ -+ /* TODO(Kevin): Also release the unused tail room of the composed MMPDU */ -+ -+ /* Indicate the packet to TXM */ -+ /* 4 <4> Inform TXM to send this Null frame. */ -+ txmSendFwDataPackets(prMsduInfo); -+#endif -+ -+ prMsduInfo->eSrc = TX_PACKET_MGMT; -+ prMsduInfo->ucPacketType = HIF_TX_PACKET_TYPE_DATA; -+ prMsduInfo->ucStaRecIndex = prStaRec->ucIndex; -+ prMsduInfo->ucNetworkType = prStaRec->ucNetTypeIndex; -+ prMsduInfo->ucMacHeaderLength = WLAN_MAC_HEADER_LEN; -+ prMsduInfo->fgIs802_1x = FALSE; -+ prMsduInfo->fgIs802_11 = TRUE; -+ prMsduInfo->u2FrameLength = WLAN_MAC_HEADER_LEN; -+ prMsduInfo->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter); -+ prMsduInfo->pfTxDoneHandler = pfTxDoneHandler; -+ prMsduInfo->fgIsBasicRate = FALSE; -+ -+ /* 4 <4> Inform TXM to send this Null frame. */ -+ nicTxEnqueueMsdu(prAdapter, prMsduInfo); -+ -+ return WLAN_STATUS_SUCCESS; -+ -+} /* end of bssSendNullFrame() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Send the QoS Null Frame -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* @param[in] prStaRec Pointer to the STA_RECORD_T -+* @param[in] pfTxDoneHandler TX Done call back function -+* -+* @retval WLAN_STATUS_RESOURCE No available resources to send frame. -+* @retval WLAN_STATUS_SUCCESS Success. -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+bssSendQoSNullFrame(IN P_ADAPTER_T prAdapter, -+ IN P_STA_RECORD_T prStaRec, IN UINT_8 ucUP, IN PFN_TX_DONE_HANDLER pfTxDoneHandler) -+{ -+ P_MSDU_INFO_T prMsduInfo; -+ UINT_16 u2EstimatedFrameLen; -+ -+ /* 4 <1> Allocate a PKT_INFO_T for Null Frame */ -+ /* Init with MGMT Header Length */ -+ u2EstimatedFrameLen = MAC_TX_RESERVED_FIELD + WLAN_MAC_HEADER_QOS_LEN; -+ -+ /* Allocate a MSDU_INFO_T */ -+ prMsduInfo = cnmMgtPktAlloc(prAdapter, u2EstimatedFrameLen); -+ if (prMsduInfo == NULL) { -+ DBGLOG(BSS, WARN, "No PKT_INFO_T for sending Null Frame.\n"); -+ return WLAN_STATUS_RESOURCES; -+ } -+ /* 4 <2> Compose Null frame in MSDU_INfO_T. */ -+ bssComposeQoSNullFrame(prAdapter, -+ (PUINT_8) ((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD), -+ prStaRec, ucUP, FALSE); -+#if 0 -+ /* 4 <3> Update information of MSDU_INFO_T */ -+ TXM_SET_DATA_PACKET( -+ /* STA_REC ptr */ prStaRec, -+ /* MSDU_INFO ptr */ prMsduInfo, -+ /* MAC HDR ptr */ (prMsduInfo->pucBuffer + MAC_TX_RESERVED_FIELD), -+ /* MAC HDR length */ WLAN_MAC_HEADER_QOS_LEN, -+ /* PAYLOAD ptr */ -+ (prMsduInfo->pucBuffer + MAC_TX_RESERVED_FIELD + WLAN_MAC_HEADER_QOS_LEN), -+ /* PAYLOAD length */ 0, -+ /* Network Type Index */ (UINT_8) prStaRec->ucNetTypeIndex, -+ /* TID */ 0 /* BE: AC1 */ , -+ /* Flag 802.11 */ TRUE, -+ /* Pkt arrival time */ 0 /* TODO: Obtain the system time */ , -+ /* Resource TC */ 0 /* Irrelevant */ , -+ /* Flag 802.1x */ FALSE, -+ /* TX-done callback */ pfTxDoneHandler, -+ /* PS forwarding type */ PS_FORWARDING_TYPE_NON_PS, -+ /* PS Session ID */ 0 /* Irrelevant */ , -+ /* Flag fixed rate */ TRUE, -+ /* Fixed tx rate */ g_aprBssInfo[prStaRec->ucNetTypeIndex]->ucHwDefaultFixedRateCode, -+ /* Fixed-rate retry */ TXM_DEFAULT_DATA_FRAME_RETRY_LIMIT, -+ /* PAL LLH */ 0 /* Irrelevant */ , -+ /* ACL SN */ 0 /* Irrelevant */ , -+ /* Flag No Ack */ FALSE -+ ); -+ -+ /* Terminate with a NULL pointer */ -+ NIC_HIF_TX_SET_NEXT_MSDU_INFO(prMsduInfo, NULL); -+ -+ /* TODO(Kevin): Also release the unused tail room of the composed MMPDU */ -+ -+ /* Indicate the packet to TXM */ -+ /* 4 <4> Inform TXM to send this Null frame. */ -+ txmSendFwDataPackets(prMsduInfo); -+#endif -+ -+ prMsduInfo->eSrc = TX_PACKET_MGMT; -+ prMsduInfo->ucPacketType = HIF_TX_PACKET_TYPE_MGMT; -+ prMsduInfo->ucStaRecIndex = prStaRec->ucIndex; -+ prMsduInfo->ucNetworkType = prStaRec->ucNetTypeIndex; -+ prMsduInfo->ucMacHeaderLength = WLAN_MAC_HEADER_QOS_LEN; -+ prMsduInfo->fgIs802_1x = FALSE; -+ prMsduInfo->fgIs802_11 = TRUE; -+ prMsduInfo->u2FrameLength = WLAN_MAC_HEADER_QOS_LEN; -+ prMsduInfo->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter); -+ prMsduInfo->pfTxDoneHandler = pfTxDoneHandler; -+ prMsduInfo->fgIsBasicRate = TRUE; -+ -+ /* 4 <4> Inform TXM to send this Null frame. */ -+ nicTxEnqueueMsdu(prAdapter, prMsduInfo); -+ -+ return WLAN_STATUS_SUCCESS; -+ -+} /* end of bssSendQoSNullFrame() */ -+ -+#if (CFG_SUPPORT_ADHOC) || (CFG_SUPPORT_AAA) -+/*----------------------------------------------------------------------------*/ -+/* Routines for both IBSS(AdHoc) and BSS(AP) */ -+/*----------------------------------------------------------------------------*/ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is used to generate Information Elements of Extended -+* Support Rate -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* @param[in] prMsduInfo Pointer to the composed MSDU_INFO_T. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID bssGenerateExtSuppRate_IE(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo) -+{ -+ P_BSS_INFO_T prBssInfo; -+ PUINT_8 pucBuffer; -+ UINT_8 ucExtSupRatesLen; -+ -+ ASSERT(prMsduInfo); -+ -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prMsduInfo->ucNetworkType]); -+ ASSERT(prBssInfo); -+ -+ pucBuffer = (PUINT_8) ((ULONG) prMsduInfo->prPacket + (UINT_32) prMsduInfo->u2FrameLength); -+ ASSERT(pucBuffer); -+ -+ if (prBssInfo->ucAllSupportedRatesLen > ELEM_MAX_LEN_SUP_RATES) -+ ucExtSupRatesLen = prBssInfo->ucAllSupportedRatesLen - ELEM_MAX_LEN_SUP_RATES; -+ else -+ ucExtSupRatesLen = 0; -+ -+ /* Fill the Extended Supported Rates element. */ -+ if (ucExtSupRatesLen) { -+ -+ EXT_SUP_RATES_IE(pucBuffer)->ucId = ELEM_ID_EXTENDED_SUP_RATES; -+ EXT_SUP_RATES_IE(pucBuffer)->ucLength = ucExtSupRatesLen; -+ -+ kalMemCopy(EXT_SUP_RATES_IE(pucBuffer)->aucExtSupportedRates, -+ &prBssInfo->aucAllSupportedRates[ELEM_MAX_LEN_SUP_RATES], ucExtSupRatesLen); -+ -+ prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer); -+ } -+ -+} /* end of bssGenerateExtSuppRate_IE() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is used to compose Common Information Elements for Beacon -+* or Probe Response Frame. -+* -+* @param[in] prMsduInfo Pointer to the composed MSDU_INFO_T. -+* @param[in] prBssInfo Pointer to the BSS_INFO_T. -+* @param[in] pucDestAddr Pointer to the Destination Address, if NULL, means Beacon. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+bssBuildBeaconProbeRespFrameCommonIEs(IN P_MSDU_INFO_T prMsduInfo, IN P_BSS_INFO_T prBssInfo, IN PUINT_8 pucDestAddr) -+{ -+ PUINT_8 pucBuffer; -+ UINT_8 ucSupRatesLen; -+ -+ ASSERT(prMsduInfo); -+ ASSERT(prBssInfo); -+ -+ pucBuffer = (PUINT_8) ((ULONG) prMsduInfo->prPacket + (UINT_32) prMsduInfo->u2FrameLength); -+ ASSERT(pucBuffer); -+ -+ /* Compose the frame body of the Probe Response frame. */ -+ /* 4 <1> Fill the SSID element. */ -+ SSID_IE(pucBuffer)->ucId = ELEM_ID_SSID; -+ if (prBssInfo->eHiddenSsidType == ENUM_HIDDEN_SSID_LEN) { -+ if ((!pucDestAddr) && /* For Beacon only */ -+ (prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT)) { -+ SSID_IE(pucBuffer)->ucLength = 0; -+ } else { /* Probe response */ -+ SSID_IE(pucBuffer)->ucLength = prBssInfo->ucSSIDLen; -+ if (prBssInfo->ucSSIDLen) -+ kalMemCopy(SSID_IE(pucBuffer)->aucSSID, prBssInfo->aucSSID, prBssInfo->ucSSIDLen); -+ } -+ } else { -+ SSID_IE(pucBuffer)->ucLength = prBssInfo->ucSSIDLen; -+ if (prBssInfo->ucSSIDLen) -+ kalMemCopy(SSID_IE(pucBuffer)->aucSSID, prBssInfo->aucSSID, prBssInfo->ucSSIDLen); -+ } -+ -+ prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer); -+ pucBuffer += IE_SIZE(pucBuffer); -+ -+ /* 4 <2> Fill the Supported Rates element. */ -+ if (prBssInfo->ucAllSupportedRatesLen > ELEM_MAX_LEN_SUP_RATES) -+ ucSupRatesLen = ELEM_MAX_LEN_SUP_RATES; -+ else -+ ucSupRatesLen = prBssInfo->ucAllSupportedRatesLen; -+ -+ if (ucSupRatesLen) { -+ SUP_RATES_IE(pucBuffer)->ucId = ELEM_ID_SUP_RATES; -+ SUP_RATES_IE(pucBuffer)->ucLength = ucSupRatesLen; -+ kalMemCopy(SUP_RATES_IE(pucBuffer)->aucSupportedRates, prBssInfo->aucAllSupportedRates, ucSupRatesLen); -+ -+ prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer); -+ pucBuffer += IE_SIZE(pucBuffer); -+ } -+ /* 4 <3> Fill the DS Parameter Set element. */ -+ if (prBssInfo->eBand == BAND_2G4) { -+ DS_PARAM_IE(pucBuffer)->ucId = ELEM_ID_DS_PARAM_SET; -+ DS_PARAM_IE(pucBuffer)->ucLength = ELEM_MAX_LEN_DS_PARAMETER_SET; -+ DS_PARAM_IE(pucBuffer)->ucCurrChnl = prBssInfo->ucPrimaryChannel; -+ -+ prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer); -+ pucBuffer += IE_SIZE(pucBuffer); -+ } -+ /* 4 <4> IBSS Parameter Set element, ID: 6 */ -+ if (prBssInfo->eCurrentOPMode == OP_MODE_IBSS) { -+ IBSS_PARAM_IE(pucBuffer)->ucId = ELEM_ID_IBSS_PARAM_SET; -+ IBSS_PARAM_IE(pucBuffer)->ucLength = ELEM_MAX_LEN_IBSS_PARAMETER_SET; -+ WLAN_SET_FIELD_16(&(IBSS_PARAM_IE(pucBuffer)->u2ATIMWindow), prBssInfo->u2ATIMWindow); -+ -+ prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer); -+ pucBuffer += IE_SIZE(pucBuffer); -+ } -+ /* 4 <5> TIM element, ID: 5 */ -+ if ((!pucDestAddr) && /* For Beacon only. */ -+ (prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT)) { -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ /*no fgIsP2PRegistered protect */ -+ if (prBssInfo->ucNetTypeIndex == NETWORK_TYPE_P2P_INDEX) { -+#if 0 -+ P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo; -+ UINT_8 ucBitmapControl = 0; -+ UINT_32 u4N1, u4N2; -+ -+ prP2pSpecificBssInfo = &(prAdapter->rWifiVar.rP2pSpecificBssInfo); -+ -+ /* Clear existing value. */ -+ prP2pSpecificBssInfo->ucBitmapCtrl = 0; -+ kalMemZero(prP2pSpecificBssInfo->aucPartialVirtualBitmap, -+ sizeof(prP2pSpecificBssInfo->aucPartialVirtualBitmap)); -+ -+ /* IEEE 802.11 2007 - 7.3.2.6 */ -+ TIM_IE(pucBuffer)->ucId = ELEM_ID_TIM; -+ TIM_IE(pucBuffer)->ucDTIMCount = prBssInfo->ucDTIMCount; -+ TIM_IE(pucBuffer)->ucDTIMPeriod = prBssInfo->ucDTIMPeriod; -+ -+ /* Setup DTIM Count for next TBTT. */ -+ if (prBssInfo->ucDTIMCount == 0) { -+ /*Do nothing*/ -+ /* 3 *** pmQueryBufferedBCAST(); */ -+ } -+ /* 3 *** pmQueryBufferedPSNode(); */ -+ /* TODO(Kevin): Call PM Module here to loop all STA_RECORD_Ts and it -+ * will call bssSetTIMBitmap to toggle the Bitmap. -+ */ -+ -+ /* Set Virtual Bitmap for UCAST */ -+ u4N1 = (prP2pSpecificBssInfo->u2SmallestAID >> 4) << 1; /* Find the largest even number. */ -+ u4N2 = prP2pSpecificBssInfo->u2LargestAID >> 3; /* Find the smallest number. */ -+ -+ ASSERT(u4N2 >= u4N1); -+ -+ kalMemCopy(TIM_IE(pucBuffer)->aucPartialVirtualMap, -+ &prP2pSpecificBssInfo->aucPartialVirtualBitmap[u4N1], ((u4N2 - u4N1) + 1)); -+ -+ /* Set Virtual Bitmap for BMCAST */ -+ /* BMC bit only indicated when DTIM count == 0. */ -+ if (prBssInfo->ucDTIMCount == 0) -+ ucBitmapControl = prP2pSpecificBssInfo->ucBitmapCtrl; -+ TIM_IE(pucBuffer)->ucBitmapControl = ucBitmapControl | (UINT_8) u4N1; -+ -+ TIM_IE(pucBuffer)->ucLength = ((u4N2 - u4N1) + 4); -+ -+ prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer); -+#else -+ -+ /* IEEE 802.11 2007 - 7.3.2.6 */ -+ TIM_IE(pucBuffer)->ucId = ELEM_ID_TIM; -+ /* NOTE: fixed PVB length (AID is allocated from 8 ~ 15 only) */ -+ TIM_IE(pucBuffer)->ucLength = (3 + MAX_LEN_TIM_PARTIAL_BMP); /*((u4N2 - u4N1) + 4) */ -+ /* will be overwrite by FW */ -+ TIM_IE(pucBuffer)->ucDTIMCount = 0; /*prBssInfo->ucDTIMCount */ -+ TIM_IE(pucBuffer)->ucDTIMPeriod = prBssInfo->ucDTIMPeriod; -+ /* will be overwrite by FW */ -+ TIM_IE(pucBuffer)->ucBitmapControl = 0; /*ucBitmapControl | (UINT_8)u4N1 */ -+ -+ prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer); -+ -+#endif -+ -+ } else -+#endif /* CFG_ENABLE_WIFI_DIRECT */ -+ { -+ /* NOTE(Kevin): 1. AIS - Didn't Support AP Mode. -+ * 2. BOW - Didn't Support BCAST and PS. -+ */ -+ } -+ -+ } -+ -+} /* end of bssBuildBeaconProbeRespFrameCommonIEs() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will compose the Beacon/Probe Response frame header and -+* its fixed fields. -+* -+* @param[in] pucBuffer Pointer to the frame buffer. -+* @param[in] pucDestAddr Pointer to the Destination Address, if NULL, means Beacon. -+* @param[in] pucOwnMACAddress Given Our MAC Address. -+* @param[in] pucBSSID Given BSSID of the BSS. -+* @param[in] u2BeaconInterval Given Beacon Interval. -+* @param[in] u2CapInfo Given Capability Info. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+bssComposeBeaconProbeRespFrameHeaderAndFF(IN PUINT_8 pucBuffer, -+ IN PUINT_8 pucDestAddr, -+ IN PUINT_8 pucOwnMACAddress, -+ IN PUINT_8 pucBSSID, IN UINT_16 u2BeaconInterval, IN UINT_16 u2CapInfo) -+{ -+ P_WLAN_BEACON_FRAME_T prBcnProbRspFrame; -+ UINT_8 aucBCAddr[] = BC_MAC_ADDR; -+ UINT_16 u2FrameCtrl; -+ -+ DEBUGFUNC("bssComposeBeaconProbeRespFrameHeaderAndFF"); -+ /* DBGLOG(INIT, LOUD, ("\n")); */ -+ -+ ASSERT(pucBuffer); -+ ASSERT(pucOwnMACAddress); -+ ASSERT(pucBSSID); -+ -+ prBcnProbRspFrame = (P_WLAN_BEACON_FRAME_T) pucBuffer; -+ -+ /* 4 <1> Compose the frame header of the Beacon /ProbeResp frame. */ -+ /* Fill the Frame Control field. */ -+ if (pucDestAddr) { -+ u2FrameCtrl = MAC_FRAME_PROBE_RSP; -+ } else { -+ u2FrameCtrl = MAC_FRAME_BEACON; -+ pucDestAddr = aucBCAddr; -+ } -+ /* WLAN_SET_FIELD_16(&prBcnProbRspFrame->u2FrameCtrl, u2FrameCtrl); */ -+ prBcnProbRspFrame->u2FrameCtrl = u2FrameCtrl; /* NOTE(Kevin): Optimized for ARM */ -+ -+ /* Fill the DA field with BCAST MAC ADDR or TA of ProbeReq. */ -+ COPY_MAC_ADDR(prBcnProbRspFrame->aucDestAddr, pucDestAddr); -+ -+ /* Fill the SA field with our MAC Address. */ -+ COPY_MAC_ADDR(prBcnProbRspFrame->aucSrcAddr, pucOwnMACAddress); -+ -+ /* Fill the BSSID field with current BSSID. */ -+ COPY_MAC_ADDR(prBcnProbRspFrame->aucBSSID, pucBSSID); -+ -+ /* Clear the SEQ/FRAG_NO field(HW won't overide the FRAG_NO, so we need to clear it). */ -+ prBcnProbRspFrame->u2SeqCtrl = 0; -+ -+ /* 4 <2> Compose the frame body's common fixed field part of the Beacon /ProbeResp frame. */ -+ /* MAC will update TimeStamp field */ -+ -+ /* Fill the Beacon Interval field. */ -+ /* WLAN_SET_FIELD_16(&prBcnProbRspFrame->u2BeaconInterval, u2BeaconInterval); */ -+ prBcnProbRspFrame->u2BeaconInterval = u2BeaconInterval; /* NOTE(Kevin): Optimized for ARM */ -+ -+ /* Fill the Capability Information field. */ -+ /* WLAN_SET_FIELD_16(&prBcnProbRspFrame->u2CapInfo, u2CapInfo); */ -+ prBcnProbRspFrame->u2CapInfo = u2CapInfo; /* NOTE(Kevin): Optimized for ARM */ -+ -+} /* end of bssComposeBeaconProbeRespFrameHeaderAndFF() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Update the Beacon Frame Template to FW for AIS AdHoc and P2P GO. -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* @param[in] eNetTypeIndex Specify which network reply the Probe Response. -+* -+* @retval WLAN_STATUS_SUCCESS Success. -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS bssUpdateBeaconContent(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex) -+{ -+ P_BSS_INFO_T prBssInfo; -+ P_MSDU_INFO_T prMsduInfo; -+ P_WLAN_BEACON_FRAME_T prBcnFrame; -+ UINT_32 i; -+ -+ DEBUGFUNC("bssUpdateBeaconContent"); -+ DBGLOG(BSS, LOUD, "\n"); -+ -+ ASSERT(eNetTypeIndex < NETWORK_TYPE_INDEX_NUM); -+ -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[eNetTypeIndex]); -+ -+ /* 4 <1> Allocate a PKT_INFO_T for Beacon Frame */ -+ /* Allocate a MSDU_INFO_T */ -+ /* For Beacon */ -+ prMsduInfo = prBssInfo->prBeacon; -+ -+ /* beacon prMsduInfo will be NULLify once BSS deactivated, so skip if it is */ -+ if (prMsduInfo == NULL) -+ return WLAN_STATUS_SUCCESS; -+ /* 4 <2> Compose header */ -+ bssComposeBeaconProbeRespFrameHeaderAndFF((PUINT_8) ((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD), -+ NULL, -+ prBssInfo->aucOwnMacAddr, -+ prBssInfo->aucBSSID, -+ prBssInfo->u2BeaconInterval, prBssInfo->u2CapInfo); -+ -+ prMsduInfo->u2FrameLength = (WLAN_MAC_MGMT_HEADER_LEN + -+ (TIMESTAMP_FIELD_LEN + BEACON_INTERVAL_FIELD_LEN + CAP_INFO_FIELD_LEN)); -+ -+ prMsduInfo->ucNetworkType = eNetTypeIndex; -+ -+ /* 4 <3> Compose the frame body's Common IEs of the Beacon frame. */ -+ bssBuildBeaconProbeRespFrameCommonIEs(prMsduInfo, prBssInfo, NULL); -+ -+ /* 4 <4> Compose IEs in MSDU_INFO_T */ -+ -+ /* Append IE for Beacon */ -+ for (i = 0; i < sizeof(txBcnIETable) / sizeof(APPEND_VAR_IE_ENTRY_T); i++) { -+ if (txBcnIETable[i].pfnAppendIE) -+ txBcnIETable[i].pfnAppendIE(prAdapter, prMsduInfo); -+ } -+ -+ prBcnFrame = (P_WLAN_BEACON_FRAME_T) prMsduInfo->prPacket; -+ -+ return nicUpdateBeaconIETemplate(prAdapter, -+ IE_UPD_METHOD_UPDATE_ALL, -+ eNetTypeIndex, -+ prBssInfo->u2CapInfo, -+ (PUINT_8) prBcnFrame->aucInfoElem, -+ prMsduInfo->u2FrameLength - OFFSET_OF(WLAN_BEACON_FRAME_T, aucInfoElem)); -+ -+} /* end of bssUpdateBeaconContent() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Send the Beacon Frame(for BOW) or Probe Response Frame according to the given -+* Destination Address. -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* @param[in] eNetTypeIndex Specify which network reply the Probe Response. -+* @param[in] pucDestAddr Pointer to the Destination Address to reply -+* @param[in] u4ControlFlags Control flags for information on Probe Response. -+* -+* @retval WLAN_STATUS_RESOURCE No available resources to send frame. -+* @retval WLAN_STATUS_SUCCESS Success. -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+bssSendBeaconProbeResponse(IN P_ADAPTER_T prAdapter, -+ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, -+ IN PUINT_8 pucDestAddr, IN UINT_32 u4ControlFlags) -+{ -+ P_BSS_INFO_T prBssInfo; -+ P_MSDU_INFO_T prMsduInfo; -+ UINT_16 u2EstimatedFrameLen; -+ UINT_16 u2EstimatedFixedIELen; -+ UINT_16 u2EstimatedExtraIELen; -+ P_APPEND_VAR_IE_ENTRY_T prIeArray = NULL; -+ UINT_32 u4IeArraySize = 0; -+ UINT_32 i; -+ -+ ASSERT(eNetTypeIndex < NETWORK_TYPE_INDEX_NUM); -+ -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[eNetTypeIndex]); -+ -+ if (!pucDestAddr) { /* For Beacon */ -+ prIeArray = &txBcnIETable[0]; -+ u4IeArraySize = sizeof(txBcnIETable) / sizeof(APPEND_VAR_IE_ENTRY_T); -+ } else { -+ prIeArray = &txProbRspIETable[0]; -+ u4IeArraySize = sizeof(txProbRspIETable) / sizeof(APPEND_VAR_IE_ENTRY_T); -+ } -+ -+ /* 4 <1> Allocate a PKT_INFO_T for Beacon /Probe Response Frame */ -+ /* Allocate a MSDU_INFO_T */ -+ -+ /* Init with MGMT Header Length + Length of Fixed Fields + Common IE Fields */ -+ u2EstimatedFrameLen = MAC_TX_RESERVED_FIELD + -+ WLAN_MAC_MGMT_HEADER_LEN + -+ TIMESTAMP_FIELD_LEN + -+ BEACON_INTERVAL_FIELD_LEN + -+ CAP_INFO_FIELD_LEN + -+ (ELEM_HDR_LEN + ELEM_MAX_LEN_SSID) + -+ (ELEM_HDR_LEN + ELEM_MAX_LEN_SUP_RATES) + -+ (ELEM_HDR_LEN + ELEM_MAX_LEN_DS_PARAMETER_SET) + -+ (ELEM_HDR_LEN + ELEM_MAX_LEN_IBSS_PARAMETER_SET) + (ELEM_HDR_LEN + (3 + MAX_LEN_TIM_PARTIAL_BMP)); -+ -+ /* + Extra IE Length */ -+ u2EstimatedExtraIELen = 0; -+ -+ for (i = 0; i < u4IeArraySize; i++) { -+ u2EstimatedFixedIELen = prIeArray[i].u2EstimatedFixedIELen; -+ -+ if (u2EstimatedFixedIELen) { -+ u2EstimatedExtraIELen += u2EstimatedFixedIELen; -+ } else { -+ ASSERT(prIeArray[i].pfnCalculateVariableIELen); -+ -+ u2EstimatedExtraIELen += (UINT_16) -+ prIeArray[i].pfnCalculateVariableIELen(prAdapter, eNetTypeIndex, NULL); -+ } -+ } -+ -+ u2EstimatedFrameLen += u2EstimatedExtraIELen; -+ prMsduInfo = cnmMgtPktAlloc(prAdapter, u2EstimatedFrameLen); -+ if (prMsduInfo == NULL) { -+ DBGLOG(BSS, WARN, "No PKT_INFO_T for sending %s.\n", ((!pucDestAddr) ? "Beacon" : "Probe Response")); -+ return WLAN_STATUS_RESOURCES; -+ } -+ /* 4 <2> Compose Beacon/Probe Response frame header and fixed fields in MSDU_INfO_T. */ -+ /* Compose Header and Fixed Field */ -+#if CFG_ENABLE_WIFI_DIRECT -+ if (u4ControlFlags & BSS_PROBE_RESP_USE_P2P_DEV_ADDR) { -+ if (prAdapter->fgIsP2PRegistered) { -+ bssComposeBeaconProbeRespFrameHeaderAndFF((PUINT_8) -+ ((ULONG) (prMsduInfo->prPacket) + -+ MAC_TX_RESERVED_FIELD), pucDestAddr, -+ prAdapter->rWifiVar.aucDeviceAddress, -+ prAdapter->rWifiVar.aucDeviceAddress, -+ DOT11_BEACON_PERIOD_DEFAULT, -+ (prBssInfo->u2CapInfo & -+ ~(CAP_INFO_ESS | CAP_INFO_IBSS))); -+ } -+ } else -+#endif /* CFG_ENABLE_WIFI_DIRECT */ -+ { -+ bssComposeBeaconProbeRespFrameHeaderAndFF((PUINT_8) -+ ((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD), -+ pucDestAddr, prBssInfo->aucOwnMacAddr, prBssInfo->aucBSSID, -+ prBssInfo->u2BeaconInterval, prBssInfo->u2CapInfo); -+ } -+ -+ /* 4 <3> Update information of MSDU_INFO_T */ -+ prMsduInfo->eSrc = TX_PACKET_MGMT; -+ prMsduInfo->ucPacketType = HIF_TX_PACKET_TYPE_MGMT; -+ prMsduInfo->ucStaRecIndex = 0xFF; -+ prMsduInfo->ucNetworkType = (UINT_8) eNetTypeIndex; -+ prMsduInfo->ucMacHeaderLength = WLAN_MAC_MGMT_HEADER_LEN; -+ prMsduInfo->fgIs802_1x = FALSE; -+ prMsduInfo->fgIs802_11 = TRUE; -+ prMsduInfo->u2FrameLength = (WLAN_MAC_MGMT_HEADER_LEN + -+ TIMESTAMP_FIELD_LEN + BEACON_INTERVAL_FIELD_LEN + CAP_INFO_FIELD_LEN); -+ prMsduInfo->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter); -+ prMsduInfo->pfTxDoneHandler = NULL; -+ prMsduInfo->fgIsBasicRate = TRUE; -+ -+ /* 4 <4> Compose the frame body's Common IEs of the Beacon/ProbeResp frame. */ -+ bssBuildBeaconProbeRespFrameCommonIEs(prMsduInfo, prBssInfo, pucDestAddr); -+ -+ /* 4 <5> Compose IEs in MSDU_INFO_T */ -+ -+ /* Append IE */ -+ for (i = 0; i < u4IeArraySize; i++) { -+ if (prIeArray[i].pfnAppendIE) -+ prIeArray[i].pfnAppendIE(prAdapter, prMsduInfo); -+ } -+ -+ /* TODO(Kevin): Also release the unused tail room of the composed MMPDU */ -+ -+ /* 4 <6> Inform TXM to send this Beacon /Probe Response frame. */ -+ nicTxEnqueueMsdu(prAdapter, prMsduInfo); -+ -+ return WLAN_STATUS_SUCCESS; -+ -+} /* end of bssSendBeaconProbeResponse() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will process the Rx Probe Request Frame and then send -+* back the corresponding Probe Response Frame if the specified conditions -+* were matched. -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* @param[in] prSwRfb Pointer to SW RFB data structure. -+* -+* @retval WLAN_STATUS_SUCCESS Always return success -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS bssProcessProbeRequest(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb) -+{ -+ P_WLAN_MAC_MGMT_HEADER_T prMgtHdr; -+ P_BSS_INFO_T prBssInfo; -+ ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex; -+ UINT_8 aucBCBSSID[] = BC_BSSID; -+ BOOLEAN fgIsBcBssid; -+ BOOLEAN fgReplyProbeResp; -+ UINT_32 u4CtrlFlagsForProbeResp = 0; -+ ENUM_BAND_T eBand; -+ UINT_8 ucHwChannelNum; -+ -+ ASSERT(prSwRfb); -+ -+ /* 4 <1> Parse Probe Req and Get BSSID */ -+ prMgtHdr = (P_WLAN_MAC_MGMT_HEADER_T) prSwRfb->pvHeader; -+ -+ if (EQUAL_MAC_ADDR(aucBCBSSID, prMgtHdr->aucBSSID)) -+ fgIsBcBssid = TRUE; -+ else -+ fgIsBcBssid = FALSE; -+ -+ /* 4 <2> Check network conditions before reply Probe Response Frame (Consider Concurrent) */ -+ for (eNetTypeIndex = NETWORK_TYPE_AIS_INDEX; eNetTypeIndex < NETWORK_TYPE_INDEX_NUM; eNetTypeIndex++) { -+ -+ if (!IS_NET_ACTIVE(prAdapter, eNetTypeIndex)) -+ continue; -+ -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[eNetTypeIndex]); -+ -+ if ((!fgIsBcBssid) && UNEQUAL_MAC_ADDR(prBssInfo->aucBSSID, prMgtHdr->aucBSSID)) -+ continue; -+ -+ eBand = HIF_RX_HDR_GET_RF_BAND(prSwRfb->prHifRxHdr); -+ ucHwChannelNum = HIF_RX_HDR_GET_CHNL_NUM(prSwRfb->prHifRxHdr); -+ -+ if (prBssInfo->eBand != eBand) -+ continue; -+ -+ if (prBssInfo->ucPrimaryChannel != ucHwChannelNum) -+ continue; -+ -+ fgReplyProbeResp = FALSE; -+ -+ if (NETWORK_TYPE_AIS_INDEX == eNetTypeIndex) { -+ -+#if CFG_SUPPORT_ADHOC -+ fgReplyProbeResp = aisValidateProbeReq(prAdapter, prSwRfb, &u4CtrlFlagsForProbeResp); -+#endif -+ } -+#if CFG_ENABLE_WIFI_DIRECT -+ else if ((prAdapter->fgIsP2PRegistered) && (NETWORK_TYPE_P2P_INDEX == eNetTypeIndex)) { -+ if (nicTxGetFreeCmdCount(prAdapter) > (CFG_TX_MAX_CMD_PKT_NUM / 2)) { -+ /* Resource margin is enough */ -+ fgReplyProbeResp = -+ p2pFuncValidateProbeReq(prAdapter, prSwRfb, &u4CtrlFlagsForProbeResp); -+ } -+ } -+#endif -+#if CFG_ENABLE_BT_OVER_WIFI -+ else if (NETWORK_TYPE_BOW_INDEX == eNetTypeIndex) -+ fgReplyProbeResp = bowValidateProbeReq(prAdapter, prSwRfb, &u4CtrlFlagsForProbeResp); -+#endif -+ -+ if (fgReplyProbeResp) { -+ if (nicTxGetFreeCmdCount(prAdapter) > (CFG_TX_MAX_CMD_PKT_NUM / 2)) { -+ /* Resource margin is enough */ -+ bssSendBeaconProbeResponse(prAdapter, eNetTypeIndex, prMgtHdr->aucSrcAddr, -+ u4CtrlFlagsForProbeResp); -+ } -+ } -+ } -+ -+ return WLAN_STATUS_SUCCESS; -+ -+} /* end of bssProcessProbeRequest() */ -+ -+#if 0 /* NOTE(Kevin): condition check should move to P2P_FSM.c */ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will process the Rx Probe Request Frame and then send -+* back the corresponding Probe Response Frame if the specified conditions -+* were matched. -+* -+* @param[in] prSwRfb Pointer to SW RFB data structure. -+* -+* @retval WLAN_STATUS_SUCCESS Always return success -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS bssProcessProbeRequest(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb) -+{ -+ P_WLAN_MAC_MGMT_HEADER_T prMgtHdr; -+ P_BSS_INFO_T prBssInfo; -+ P_IE_SSID_T prIeSsid = (P_IE_SSID_T) NULL; -+ P_IE_SUPPORTED_RATE_T prIeSupportedRate = (P_IE_SUPPORTED_RATE_T) NULL; -+ P_IE_EXT_SUPPORTED_RATE_T prIeExtSupportedRate = (P_IE_EXT_SUPPORTED_RATE_T) NULL; -+ PUINT_8 pucIE; -+ UINT_16 u2IELength; -+ UINT_16 u2Offset = 0; -+ UINT_8 aucBCBSSID[] = BC_BSSID; -+ ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex; -+ BOOLEAN fgReplyProbeResp; -+#if CFG_ENABLE_WIFI_DIRECT -+ BOOLEAN fgP2PTargetDeviceFound; -+ UINT_8 aucP2PWildcardSSID[] = P2P_WILDCARD_SSID; -+#endif -+ -+ ASSERT(prSwRfb); -+ -+ /* 4 <1> Parse Probe Req and Get SSID IE ptr */ -+ prMgtHdr = (P_WLAN_MAC_MGMT_HEADER_T) prSwRfb->pvHeader; -+ -+ u2IELength = prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen; -+ pucIE = (PUINT_8) ((UINT_32) prSwRfb->pvHeader + prSwRfb->u2HeaderLen); -+ -+ prIeSsid = (P_IE_SSID_T) NULL; -+ -+ IE_FOR_EACH(pucIE, u2IELength, u2Offset) { -+ switch (IE_ID(pucIE)) { -+ case ELEM_ID_SSID: -+ if ((!prIeSsid) && (IE_LEN(pucIE) <= ELEM_MAX_LEN_SSID)) -+ prIeSsid = (P_IE_SSID_T) pucIE; -+ break; -+ -+ case ELEM_ID_SUP_RATES: -+ /* NOTE(Kevin): Buffalo WHR-G54S's supported rate set IE exceed 8. -+ * IE_LEN(pucIE) == 12, "1(B), 2(B), 5.5(B), 6(B), 9(B), 11(B), -+ * 12(B), 18(B), 24(B), 36(B), 48(B), 54(B)" -+ */ -+ /* if (IE_LEN(pucIE) <= ELEM_MAX_LEN_SUP_RATES) { */ -+ if (IE_LEN(pucIE) <= RATE_NUM) -+ prIeSupportedRate = SUP_RATES_IE(pucIE); -+ break; -+ -+ case ELEM_ID_EXTENDED_SUP_RATES: -+ prIeExtSupportedRate = EXT_SUP_RATES_IE(pucIE); -+ break; -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ /* TODO: P2P IE & WCS IE parsing for P2P. */ -+ case ELEM_ID_P2P: -+ -+ break; -+#endif -+ -+ /* no default */ -+ } -+ } /* end of IE_FOR_EACH */ -+ -+ /* 4 <2> Check network conditions before reply Probe Response Frame (Consider Concurrent) */ -+ for (eNetTypeIndex = NETWORK_TYPE_AIS_INDEX; eNetTypeIndex < NETWORK_TYPE_INDEX_NUM; eNetTypeIndex++) { -+ -+ if (!IS_NET_ACTIVE(prAdapter, eNetTypeIndex)) -+ continue; -+ -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[eNetTypeIndex]); -+ -+ if (UNEQUAL_MAC_ADDR(aucBCBSSID, prMgtHdr->aucBSSID) && -+ UNEQUAL_MAC_ADDR(prBssInfo->aucBSSID, prMgtHdr->aucBSSID)) { -+ /* BSSID not Wildcard BSSID. */ -+ continue; -+ } -+ -+ fgReplyProbeResp = FALSE; -+ -+ if (NETWORK_TYPE_AIS_INDEX == eNetTypeIndex) { -+ -+ if (prBssInfo->eCurrentOPMode == OP_MODE_IBSS) { -+ -+ /* TODO(Kevin): Check if we are IBSS Master. */ -+ if (TRUE && prIeSsid) { -+ if ((prIeSsid->ucLength == BC_SSID_LEN) || /* WILDCARD SSID */ -+ EQUAL_SSID(prBssInfo->aucSSID, prBssInfo->ucSSIDLen, -+ prIeSsid->aucSSID, prIeSsid->ucLength)) { -+ fgReplyProbeResp = TRUE; -+ } -+ } -+ } -+ } -+#if CFG_ENABLE_WIFI_DIRECT -+ else if (NETWORK_TYPE_P2P_INDEX == eNetTypeIndex) { -+ -+ /* TODO(Kevin): Move following lines to p2p_fsm.c */ -+ -+ if ((prIeSsid) && -+ ((prIeSsid->ucLength == BC_SSID_LEN) || -+ (EQUAL_SSID(aucP2PWildcardSSID, -+ P2P_WILDCARD_SSID_LEN, prIeSsid->aucSSID, prIeSsid->ucLength)))) { -+ /* if (p2pFsmRunEventRxProbeRequestFrame(prAdapter, prMgtHdr->aucSrcAddr, -+ pucIE, u2IELength)) { */ -+ if (p2pFsmRunEventRxProbeRequestFrame(prAdapter, prSwRfb)) { -+ /* Extand channel request time & cancel scan request. */ -+ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; -+ -+ /* TODO: RX probe request may not caused by LISTEN state. */ -+ /* TODO: It can be GO. */ -+ /* Generally speaking, cancel a non-exist scan request is fine. -+ * We can check P2P FSM here for only LISTEN state. -+ */ -+ -+ P_MSG_SCN_SCAN_CANCEL prScanCancelMsg; -+ -+ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; -+ -+ /* Abort JOIN process. */ -+ prScanCancelMsg = -+ (P_MSG_SCN_SCAN_CANCEL) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, -+ sizeof(MSG_SCN_SCAN_CANCEL)); -+ if (!prScanCancelMsg) { -+ ASSERT(0); /* Can't abort SCN FSM */ -+ continue; -+ } -+ -+ prScanCancelMsg->rMsgHdr.eMsgId = MID_P2P_SCN_SCAN_CANCEL; -+ prScanCancelMsg->ucSeqNum = prP2pFsmInfo->ucSeqNumOfScnMsg; -+ prScanCancelMsg->ucNetTypeIndex = (UINT_8) NETWORK_TYPE_P2P_INDEX; -+ prScanCancelMsg->fgIsChannelExt = TRUE; -+ -+ mboxSendMsg(prAdapter, -+ MBOX_ID_0, (P_MSG_HDR_T) prScanCancelMsg, MSG_SEND_METHOD_BUF); -+ } -+ } else { -+ /* 1. Probe Request without SSID. -+ * 2. Probe Request with SSID not Wildcard SSID & not P2P Wildcard SSID. -+ */ -+ continue; -+ } -+ -+#if 0 /* Frog */ -+ if (prAdapter->rWifiVar.prP2pFsmInfo->eCurrentState == P2P_STATE_LISTEN) { -+ /* P2P 2.4.1 - P2P Devices shall not respond to Probe Request frames -+ which only contain 11b rates only. */ -+ if (prIeSupportedRate || prIeExtSupportedRate) { -+ UINT_16 u2OperationalRateSet, u2BSSBasicRateSet; -+ BOOLEAN fgIsUnknownBssBasicRate; -+ -+ rateGetRateSetFromIEs(prIeSupportedRate, prIeExtSupportedRate, -+ &u2OperationalRateSet, -+ &u2BSSBasicRateSet, /* Ignore any Basic Bit */ -+ &fgIsUnknownBssBasicRate); -+ -+ if (u2OperationalRateSet & ~RATE_SET_HR_DSSS) -+ continue; -+ } -+ } -+ /* TODO: Check channel time before first check point to: */ -+ /* If Target device is selected: -+ * 1. Send XXXX request frame. -+ * else -+ * 1. Send Probe Response frame. -+ */ -+ -+ if (prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT) { -+ /* TODO(Kevin): During PROVISION state, can we reply Probe Response ? */ -+ -+ /* TODO(Kevin): -+ * If we are GO, accept legacy client --> accept Wildcard SSID -+ * If we are in Listen State, accept only P2P Device --> check P2P IE and WPS IE -+ */ -+ if (TRUE /* We are GO */ && prIeSsid) { -+ UINT_8 aucSSID[] = P2P_WILDCARD_SSID; -+ -+ if ((prIeSsid->ucLength == BC_SSID_LEN) || /* WILDCARD SSID */ -+ EQUAL_SSID(prBssInfo->aucSSID, prBssInfo->ucSSIDLen, -+ prIeSsid->aucSSID, prIeSsid->ucLength) || -+ EQUAL_SSID(aucSSID, P2P_WILDCARD_SSID_LEN, -+ prIeSsid->aucSSID, prIeSsid->ucLength)) { -+ fgReplyProbeResp = TRUE; -+ } -+ } -+/* else if (FALSE) { */ /* We are in Listen State */ -+/* } */ -+ -+ /* TODO(Kevin): Check P2P IE and WPS IE */ -+ } -+#endif -+ } -+#endif -+#if CFG_ENABLE_BT_OVER_WIFI -+ else if (NETWORK_TYPE_BOW_INDEX == eNetTypeIndex) { -+ -+ if (prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT) { -+ /* Do nothing */ -+ /* TODO(Kevin): TBD */ -+ } -+ } -+#endif -+ else -+ ASSERT(eNetTypeIndex < NETWORK_TYPE_INDEX_NUM); -+ -+ if (fgReplyProbeResp) -+ bssSendBeaconProbeResponse(prAdapter, eNetTypeIndex, prMgtHdr->aucSrcAddr); -+ -+ } -+ -+ return WLAN_STATUS_SUCCESS; -+ -+} /* end of bssProcessProbeRequest() */ -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is used to clear the client list for AdHoc or AP Mode -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* @param[in] prBssInfo Given related BSS_INFO_T. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID bssClearClientList(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prBssInfo) -+{ -+ P_LINK_T prStaRecOfClientList; -+ -+ ASSERT(prBssInfo); -+ -+ prStaRecOfClientList = &prBssInfo->rStaRecOfClientList; -+ -+ if (!LINK_IS_EMPTY(prStaRecOfClientList)) { -+ P_STA_RECORD_T prPeerStaRec; -+ -+ LINK_FOR_EACH_ENTRY(prPeerStaRec, prStaRecOfClientList, rLinkEntry, STA_RECORD_T) { -+ cnmStaRecChangeState(prAdapter, prPeerStaRec, STA_STATE_1); -+ } -+ -+ LINK_INITIALIZE(prStaRecOfClientList); -+ } -+ -+} /* end of bssClearClientList() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is used to Add a STA_RECORD_T to the client list for AdHoc or AP Mode -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* @param[in] prBssInfo Given related BSS_INFO_T. -+* @param[in] prStaRec Pointer to the STA_RECORD_T -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID bssAddStaRecToClientList(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prBssInfo, IN P_STA_RECORD_T prStaRec) -+{ -+ P_LINK_T prStaRecOfClientList; -+ -+ ASSERT(prBssInfo); -+ -+ prStaRecOfClientList = &prBssInfo->rStaRecOfClientList; -+ -+ if (!LINK_IS_EMPTY(prStaRecOfClientList)) { -+ P_STA_RECORD_T prCurrStaRec; -+ -+ LINK_FOR_EACH_ENTRY(prCurrStaRec, prStaRecOfClientList, rLinkEntry, STA_RECORD_T) { -+ -+ if (prCurrStaRec == prStaRec) { -+ DBGLOG(BSS, WARN, -+ "Current Client List already contains that STA_RECORD_T[%pM]\n", -+ prStaRec->aucMacAddr); -+ return; -+ } -+ } -+ } -+ -+ LINK_INSERT_TAIL(prStaRecOfClientList, &prStaRec->rLinkEntry); -+ -+} /* end of bssAddStaRecToClientList() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is used to Remove a STA_RECORD_T from the client list for AdHoc or AP Mode -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* @param[in] prStaRec Pointer to the STA_RECORD_T -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID bssRemoveStaRecFromClientList(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prBssInfo, IN P_STA_RECORD_T prStaRec) -+{ -+ P_LINK_T prStaRecOfClientList; -+ -+ ASSERT(prBssInfo); -+ -+ prStaRecOfClientList = &prBssInfo->rStaRecOfClientList; -+ -+#if 0 -+ if (!LINK_IS_EMPTY(prStaRecOfClientList)) { -+ P_STA_RECORD_T prCurrStaRec; -+ -+ LINK_FOR_EACH_ENTRY(prCurrStaRec, prStaRecOfClientList, rLinkEntry, STA_RECORD_T) { -+ -+ if (prCurrStaRec == prStaRec) { -+ -+ LINK_REMOVE_KNOWN_ENTRY(prStaRecOfClientList, &prStaRec->rLinkEntry); -+ -+ return; -+ } -+ } -+ } -+#endif -+ if (!LINK_IS_EMPTY(prStaRecOfClientList)) { -+ -+ P_LINK_ENTRY_T prLinkEntry = (P_LINK_ENTRY_T) NULL; -+ -+ LINK_FOR_EACH(prLinkEntry, prStaRecOfClientList) { -+ if ((ULONG) prStaRec == (ULONG) prLinkEntry) { -+ LINK_REMOVE_KNOWN_ENTRY(prStaRecOfClientList, &prStaRec->rLinkEntry); -+ return; -+ } -+ } -+ } -+ -+ DBGLOG(BSS, INFO, "Current Client List didn't contain that STA_RECORD_T[%pM] before removing.\n", -+ prStaRec->aucMacAddr); -+ -+} /* end of bssRemoveStaRecFromClientList() */ -+#endif /* CFG_SUPPORT_ADHOC || CFG_SUPPORT_AAA */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Get station record by Address for AP mode -+* -+* @param[in] prBssInfo Pointer to BSS_INFO_T. -+* @param[in] pucMacAddr Pointer to target mac address -+* -+* @return pointer of STA_RECORD_T if found, otherwise, return NULL -+*/ -+/*----------------------------------------------------------------------------*/ -+ -+P_STA_RECORD_T bssGetClientByAddress(IN P_BSS_INFO_T prBssInfo, PUINT_8 pucMacAddr) -+{ -+ P_LINK_T prStaRecOfClientList; -+ -+ ASSERT(prBssInfo); -+ ASSERT(pucMacAddr); -+ -+ prStaRecOfClientList = &prBssInfo->rStaRecOfClientList; -+ if (!LINK_IS_EMPTY(prStaRecOfClientList)) { -+ P_STA_RECORD_T prCurrStaRec; -+ -+ LINK_FOR_EACH_ENTRY(prCurrStaRec, prStaRecOfClientList, rLinkEntry, STA_RECORD_T) { -+ if (EQUAL_MAC_ADDR(prCurrStaRec->aucMacAddr, pucMacAddr)) -+ return prCurrStaRec; -+ } -+ } -+ return NULL; -+} -+ -+#if CFG_SUPPORT_ADHOC -+/*----------------------------------------------------------------------------*/ -+/* Routines for IBSS(AdHoc) only */ -+/*----------------------------------------------------------------------------*/ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is used to process Beacons from current Ad-Hoc network peers. -+* We also process Beacons from other Ad-Hoc network during SCAN. If it has -+* the same SSID and we'll decide to merge into it if it has a larger TSF. -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* @param[in] prBssInfo Pointer to the BSS_INFO_T. -+* @param[in] prBSSDesc Pointer to the BSS Descriptor. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+ibssProcessMatchedBeacon(IN P_ADAPTER_T prAdapter, -+ IN P_BSS_INFO_T prBssInfo, IN P_BSS_DESC_T prBssDesc, IN UINT_8 ucRCPI) -+{ -+ P_STA_RECORD_T prStaRec = NULL; -+ -+ BOOLEAN fgIsCheckCapability = FALSE; -+ BOOLEAN fgIsCheckTSF = FALSE; -+ BOOLEAN fgIsGoingMerging = FALSE; -+ BOOLEAN fgIsSameBSSID; -+ -+ ASSERT(prBssInfo); -+ ASSERT(prBssDesc); -+ -+ /* 4 <1> Process IBSS Beacon only after we create or merge with other IBSS. */ -+ if (!prBssInfo->fgIsBeaconActivated) -+ return; -+ /* 4 <2> Get the STA_RECORD_T of TA. */ -+ prStaRec = cnmGetStaRecByAddress(prAdapter, (UINT_8) NETWORK_TYPE_AIS_INDEX, prBssDesc->aucSrcAddr); -+ -+ fgIsSameBSSID = UNEQUAL_MAC_ADDR(prBssInfo->aucBSSID, prBssDesc->aucBSSID) ? FALSE : TRUE; -+ -+ /* 4 <3> IBSS Merge Decision Flow for Processing Beacon. */ -+ if (fgIsSameBSSID) { -+ -+ /* Same BSSID: -+ * Case I. This is a new TA and it has decide to merged with us. -+ * a) If fgIsMerging == FALSE - we will send msg to notify AIS. -+ * b) If fgIsMerging == TRUE - already notify AIS. -+ * Case II. This is an old TA and we've already merged together. -+ */ -+ if (!prStaRec) { -+ -+ /* For Case I - Check this IBSS's capability first before adding this Sta Record. */ -+ fgIsCheckCapability = TRUE; -+ -+ /* If check is passed, then we perform merging with this new IBSS */ -+ fgIsGoingMerging = TRUE; -+ -+ } else { -+ -+ ASSERT((prStaRec->ucNetTypeIndex == NETWORK_TYPE_AIS_INDEX) && IS_ADHOC_STA(prStaRec)); -+ -+ if (prStaRec->ucStaState != STA_STATE_3) { -+ -+ if (!prStaRec->fgIsMerging) { -+ -+ /* For Case I - Check this IBSS's capability first -+ * before adding this Sta Record. */ -+ fgIsCheckCapability = TRUE; -+ -+ /* If check is passed, then we perform merging with this new IBSS */ -+ fgIsGoingMerging = TRUE; -+ } else { -+ /* For Case II - Update rExpirationTime of Sta Record */ -+ GET_CURRENT_SYSTIME(&prStaRec->rUpdateTime); -+ } -+ } else { -+ /* For Case II - Update rExpirationTime of Sta Record */ -+ GET_CURRENT_SYSTIME(&prStaRec->rUpdateTime); -+ } -+ -+ } -+ } else { -+ -+ /* Unequal BSSID: -+ * Case III. This is a new TA and we need to compare the TSF and get the winner. -+ * Case IV. This is an old TA and it merge into a new IBSS before we do the same thing. -+ * We need to compare the TSF to get the winner. -+ * Case V. This is an old TA and it restart a new IBSS. We also need to -+ * compare the TSF to get the winner. -+ */ -+ -+ /* For Case III, IV & V - We'll always check this new IBSS's capability first -+ * before merging into new IBSS. -+ */ -+ fgIsCheckCapability = TRUE; -+ -+ /* If check is passed, we need to perform TSF check to decide the major BSSID */ -+ fgIsCheckTSF = TRUE; -+ -+ /* For Case IV & V - We won't update rExpirationTime of Sta Record */ -+ } -+ -+ /* 4 <7> Check this BSS_DESC_T's capability. */ -+ if (fgIsCheckCapability) { -+ BOOLEAN fgIsCapabilityMatched = FALSE; -+ -+ do { -+ if (!(prBssDesc->ucPhyTypeSet & (prAdapter->rWifiVar.ucAvailablePhyTypeSet))) { -+ DBGLOG(BSS, LOUD, -+ "IBSS MERGE: Ignore Peer MAC: %pM - Unsupported Phy.\n", -+ prBssDesc->aucSrcAddr); -+ -+ break; -+ } -+ -+ if (prBssDesc->fgIsUnknownBssBasicRate) { -+ DBGLOG(BSS, LOUD, -+ "IBSS MERGE: Ignore Peer MAC: %pM - Unknown Basic Rate.\n", -+ prBssDesc->aucSrcAddr); -+ -+ break; -+ } -+ -+ if (ibssCheckCapabilityForAdHocMode(prAdapter, prBssDesc) == WLAN_STATUS_FAILURE) { -+ DBGLOG(BSS, LOUD, -+ "IBSS MERGE: Ignore Peer MAC: %pM - Capability is not matched.\n", -+ prBssDesc->aucSrcAddr); -+ -+ break; -+ } -+ -+ fgIsCapabilityMatched = TRUE; -+ } while (FALSE); -+ -+ if (!fgIsCapabilityMatched) { -+ -+ if (prStaRec) { -+ /* For Case II - We merge this STA_RECORD in RX Path. -+ * Case IV & V - They change their BSSID after we merge with them. -+ */ -+ -+ DBGLOG(BSS, LOUD, -+ "IBSS MERGE: Ignore Peer MAC: %pM - Capability is not matched.\n", -+ prBssDesc->aucSrcAddr); -+ } -+ -+ return; -+ } -+ -+ DBGLOG(BSS, LOUD, -+ "IBSS MERGE: Peer MAC: %pM - Check capability was passed.\n", -+ prBssDesc->aucSrcAddr); -+ } -+ -+ if (fgIsCheckTSF) { -+#if CFG_SLT_SUPPORT -+ fgIsGoingMerging = TRUE; -+#else -+ if (prBssDesc->fgIsLargerTSF) -+ fgIsGoingMerging = TRUE; -+ else -+ return; -+#endif -+ } -+ -+ if (fgIsGoingMerging) { -+ P_MSG_AIS_IBSS_PEER_FOUND_T prAisIbssPeerFoundMsg; -+ -+ /* 4 <1> We will merge with to this BSS immediately. */ -+ prBssDesc->fgIsConnecting = TRUE; -+ prBssDesc->fgIsConnected = FALSE; -+ -+ /* 4 <2> Setup corresponding STA_RECORD_T */ -+ prStaRec = bssCreateStaRecFromBssDesc(prAdapter, -+ STA_TYPE_ADHOC_PEER, NETWORK_TYPE_AIS_INDEX, prBssDesc); -+ -+ if (!prStaRec) { -+ /* no memory ? */ -+ return; -+ } -+ -+ prStaRec->fgIsMerging = TRUE; -+ -+ /* update RCPI */ -+ prStaRec->ucRCPI = ucRCPI; -+ -+ /* 4 <3> Send Merge Msg to CNM to obtain the channel privilege. */ -+ prAisIbssPeerFoundMsg = (P_MSG_AIS_IBSS_PEER_FOUND_T) -+ cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_AIS_IBSS_PEER_FOUND_T)); -+ -+ if (!prAisIbssPeerFoundMsg) { -+ -+ ASSERT(0); /* Can't send Merge Msg */ -+ return; -+ } -+ -+ prAisIbssPeerFoundMsg->rMsgHdr.eMsgId = MID_SCN_AIS_FOUND_IBSS; -+ prAisIbssPeerFoundMsg->ucNetTypeIndex = (UINT_8) NETWORK_TYPE_AIS_INDEX; -+ prAisIbssPeerFoundMsg->prStaRec = prStaRec; -+ -+ /* Inform AIS to do STATE TRANSITION -+ * For Case I - If AIS in IBSS_ALONE, let it jump to NORMAL_TR after we know the new member. -+ * For Case III, IV - Now this new BSSID wins the TSF, follow it. -+ */ -+ if (fgIsSameBSSID) { -+ prAisIbssPeerFoundMsg->fgIsMergeIn = TRUE; -+ } else { -+#if CFG_SLT_SUPPORT -+ prAisIbssPeerFoundMsg->fgIsMergeIn = TRUE; -+#else -+ prAisIbssPeerFoundMsg->fgIsMergeIn = (prBssDesc->fgIsLargerTSF) ? FALSE : TRUE; -+#endif -+ } -+ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prAisIbssPeerFoundMsg, MSG_SEND_METHOD_BUF); -+ -+ } -+ -+} /* end of ibssProcessMatchedBeacon() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will check the Capability for Ad-Hoc to decide if we are -+* able to merge with(same capability). -+* -+* @param[in] prBSSDesc Pointer to the BSS Descriptor. -+* -+* @retval WLAN_STATUS_FAILURE Can't pass the check of Capability. -+* @retval WLAN_STATUS_SUCCESS Pass the check of Capability. -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS ibssCheckCapabilityForAdHocMode(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBssDesc) -+{ -+ P_CONNECTION_SETTINGS_T prConnSettings; -+ WLAN_STATUS rStatus = WLAN_STATUS_FAILURE; -+ -+ ASSERT(prBssDesc); -+ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); -+ -+ do { -+ /* 4 <1> Check the BSS Basic Rate Set for current AdHoc Mode */ -+ if ((prConnSettings->eAdHocMode == AD_HOC_MODE_11B) && -+ (prBssDesc->u2BSSBasicRateSet & ~RATE_SET_HR_DSSS)) { -+ break; -+ } else if ((prConnSettings->eAdHocMode == AD_HOC_MODE_11A) && -+ (prBssDesc->u2BSSBasicRateSet & ~RATE_SET_OFDM)) { -+ break; -+ } -+ /* 4 <2> Check the Short Slot Time. */ -+#if 0 /* Do not check ShortSlotTime until Wi-Fi define such policy */ -+ if (prConnSettings->eAdHocMode == AD_HOC_MODE_11G) { -+ if (((prConnSettings->fgIsShortSlotTimeOptionEnable) && -+ !(prBssDesc->u2CapInfo & CAP_INFO_SHORT_SLOT_TIME)) || -+ (!(prConnSettings->fgIsShortSlotTimeOptionEnable) && -+ (prBssDesc->u2CapInfo & CAP_INFO_SHORT_SLOT_TIME))) { -+ break; -+ } -+ } -+#endif -+ -+ /* 4 <3> Check the ATIM window setting. */ -+ if (prBssDesc->u2ATIMWindow) { -+ DBGLOG(BSS, INFO, "AdHoc PS was not supported(ATIM Window: %d)\n", prBssDesc->u2ATIMWindow); -+ break; -+ } -+#if CFG_RSN_MIGRATION -+ /* 4 <4> Check the Security setting. */ -+ if (!rsnPerformPolicySelection(prAdapter, prBssDesc)) -+ break; -+#endif -+ -+ rStatus = WLAN_STATUS_SUCCESS; -+ } while (FALSE); -+ -+ return rStatus; -+ -+} /* end of ibssCheckCapabilityForAdHocMode() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will initial the BSS_INFO_T for IBSS Mode. -+* -+* @param[in] prBssInfo Pointer to the BSS_INFO_T. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID ibssInitForAdHoc(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prBssInfo) -+{ -+ UINT_8 ucLowestBasicRateIndex; -+ UINT_8 aucBSSID[MAC_ADDR_LEN]; -+ PUINT_16 pu2BSSID = (PUINT_16) &aucBSSID[0]; -+ UINT_32 i; -+ -+ ASSERT(prBssInfo); -+ ASSERT(prBssInfo->eCurrentOPMode == OP_MODE_IBSS); -+ -+ /* 4 <1> Setup PHY Attributes and Basic Rate Set/Operational Rate Set */ -+ prBssInfo->ucNonHTBasicPhyType = (UINT_8) -+ rNonHTAdHocModeAttributes[prBssInfo->ucConfigAdHocAPMode].ePhyTypeIndex; -+ prBssInfo->u2BSSBasicRateSet = rNonHTAdHocModeAttributes[prBssInfo->ucConfigAdHocAPMode].u2BSSBasicRateSet; -+ -+ prBssInfo->u2OperationalRateSet = rNonHTPhyAttributes[prBssInfo->ucNonHTBasicPhyType].u2SupportedRateSet; -+ -+ rateGetDataRatesFromRateSet(prBssInfo->u2OperationalRateSet, -+ prBssInfo->u2BSSBasicRateSet, -+ prBssInfo->aucAllSupportedRates, &prBssInfo->ucAllSupportedRatesLen); -+ -+ /* 4 <2> Setup BSSID */ -+ if (!prBssInfo->fgHoldSameBssidForIBSS) { -+ -+ for (i = 0; i < sizeof(aucBSSID) / sizeof(UINT_16); i++) -+ pu2BSSID[i] = (UINT_16) (kalRandomNumber() & 0xFFFF); -+ -+ aucBSSID[0] &= ~0x01; /* 7.1.3.3.3 - The individual/group bit of the address is set to 0. */ -+ aucBSSID[0] |= 0x02; /* 7.1.3.3.3 - The universal/local bit of the address is set to 1. */ -+ -+ COPY_MAC_ADDR(prBssInfo->aucBSSID, aucBSSID); -+ } -+ /* 4 <3> Setup Capability - Short Preamble */ -+ if (rNonHTPhyAttributes[prBssInfo->ucNonHTBasicPhyType].fgIsShortPreambleOptionImplemented && -+ ((prAdapter->rWifiVar.ePreambleType == PREAMBLE_TYPE_SHORT) || /* Short Preamble Option Enable is TRUE */ -+ (prAdapter->rWifiVar.ePreambleType == PREAMBLE_TYPE_AUTO))) { -+ prBssInfo->fgIsShortPreambleAllowed = TRUE; -+ prBssInfo->fgUseShortPreamble = TRUE; -+ } else { -+ prBssInfo->fgIsShortPreambleAllowed = FALSE; -+ prBssInfo->fgUseShortPreamble = FALSE; -+ } -+ -+ /* 4 <4> Setup Capability - Short Slot Time */ -+ /* 7.3.1.4 For IBSS, the Short Slot Time subfield shall be set to 0. */ -+ prBssInfo->fgUseShortSlotTime = FALSE; /* Set to FALSE for AdHoc */ -+ -+ /* 4 <5> Compoase Capability */ -+ prBssInfo->u2CapInfo = CAP_INFO_IBSS; -+ -+ if (prBssInfo->fgIsProtection) -+ prBssInfo->u2CapInfo |= CAP_INFO_PRIVACY; -+ -+ if (prBssInfo->fgIsShortPreambleAllowed) -+ prBssInfo->u2CapInfo |= CAP_INFO_SHORT_PREAMBLE; -+ -+ if (prBssInfo->fgUseShortSlotTime) -+ prBssInfo->u2CapInfo |= CAP_INFO_SHORT_SLOT_TIME; -+ /* 4 <6> Find Lowest Basic Rate Index for default TX Rate of MMPDU */ -+ rateGetLowestRateIndexFromRateSet(prBssInfo->u2BSSBasicRateSet, &ucLowestBasicRateIndex); -+ -+ prBssInfo->ucHwDefaultFixedRateCode = aucRateIndex2RateCode[PREAMBLE_DEFAULT_LONG_NONE][ucLowestBasicRateIndex]; -+ -+} /* end of ibssInitForAdHoc() */ -+ -+#endif /* CFG_SUPPORT_ADHOC */ -+ -+#if CFG_SUPPORT_AAA -+ -+/*----------------------------------------------------------------------------*/ -+/* Routines for BSS(AP) only */ -+/*----------------------------------------------------------------------------*/ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will initial the BSS_INFO_T for AP Mode. -+* -+* @param[in] prBssInfo Given related BSS_INFO_T. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID bssInitForAP(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prBssInfo, IN BOOLEAN fgIsRateUpdate) -+{ -+ UINT_8 ucLowestBasicRateIndex; -+ -+ P_AC_QUE_PARMS_T prACQueParms; -+ -+ ENUM_WMM_ACI_T eAci; -+ -+ UINT_8 auCWminLog2ForBcast[WMM_AC_INDEX_NUM] = { 4 /*BE*/, 4 /*BK*/, 3 /*VO*/, 2 /*VI*/ }; -+ UINT_8 auCWmaxLog2ForBcast[WMM_AC_INDEX_NUM] = { 10, 10, 4, 3 }; -+ UINT_8 auAifsForBcast[WMM_AC_INDEX_NUM] = { 3, 7, 2, 2 }; -+ UINT_8 auTxopForBcast[WMM_AC_INDEX_NUM] = { 0, 0, 94, 47 }; /* If the AP is OFDM */ -+ -+ UINT_8 auCWminLog2[WMM_AC_INDEX_NUM] = { 4 /*BE*/, 4 /*BK*/, 3 /*VO*/, 2 /*VI*/ }; -+ UINT_8 auCWmaxLog2[WMM_AC_INDEX_NUM] = { 7, 10, 4, 3 }; -+ UINT_8 auAifs[WMM_AC_INDEX_NUM] = { 3, 7, 1, 1 }; -+ UINT_8 auTxop[WMM_AC_INDEX_NUM] = { 0, 0, 94, 47 }; /* If the AP is OFDM */ -+ -+ DEBUGFUNC("bssInitForAP"); -+ DBGLOG(BSS, LOUD, "\n"); -+ -+ ASSERT(prBssInfo); -+ ASSERT((prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT) || (prBssInfo->eCurrentOPMode == OP_MODE_BOW)); -+ -+#if 0 -+ prAdapter->rWifiVar.rConnSettings.fgRxShortGIDisabled = TRUE; -+ prAdapter->rWifiVar.rConnSettings.uc2G4BandwidthMode = CONFIG_BW_20M; -+ prAdapter->rWifiVar.rConnSettings.uc5GBandwidthMode = CONFIG_BW_20M; -+#endif -+ -+ /* 4 <1> Setup PHY Attributes and Basic Rate Set/Operational Rate Set */ -+ prBssInfo->ucNonHTBasicPhyType = (UINT_8) -+ rNonHTApModeAttributes[prBssInfo->ucConfigAdHocAPMode].ePhyTypeIndex; -+ prBssInfo->u2BSSBasicRateSet = rNonHTApModeAttributes[prBssInfo->ucConfigAdHocAPMode].u2BSSBasicRateSet; -+ -+ prBssInfo->u2OperationalRateSet = rNonHTPhyAttributes[prBssInfo->ucNonHTBasicPhyType].u2SupportedRateSet; -+ -+ if (fgIsRateUpdate) { -+ rateGetDataRatesFromRateSet(prBssInfo->u2OperationalRateSet, -+ prBssInfo->u2BSSBasicRateSet, -+ prBssInfo->aucAllSupportedRates, &prBssInfo->ucAllSupportedRatesLen); -+ } -+ /* 4 <2> Setup BSSID */ -+ COPY_MAC_ADDR(prBssInfo->aucBSSID, prBssInfo->aucOwnMacAddr); -+ -+ /* 4 <3> Setup Capability - Short Preamble */ -+ if (rNonHTPhyAttributes[prBssInfo->ucNonHTBasicPhyType].fgIsShortPreambleOptionImplemented && -+ ((prAdapter->rWifiVar.ePreambleType == PREAMBLE_TYPE_SHORT) || /* Short Preamble Option Enable is TRUE */ -+ (prAdapter->rWifiVar.ePreambleType == PREAMBLE_TYPE_AUTO))) { -+ prBssInfo->fgIsShortPreambleAllowed = TRUE; -+ prBssInfo->fgUseShortPreamble = TRUE; -+ } else { -+ prBssInfo->fgIsShortPreambleAllowed = FALSE; -+ prBssInfo->fgUseShortPreamble = FALSE; -+ } -+ -+ /* 4 <4> Setup Capability - Short Slot Time */ -+ prBssInfo->fgUseShortSlotTime = TRUE; -+ -+ /* 4 <5> Compoase Capability */ -+ prBssInfo->u2CapInfo = CAP_INFO_ESS; -+ -+ if (prBssInfo->fgIsProtection) -+ prBssInfo->u2CapInfo |= CAP_INFO_PRIVACY; -+ -+ if (prBssInfo->fgIsShortPreambleAllowed) -+ prBssInfo->u2CapInfo |= CAP_INFO_SHORT_PREAMBLE; -+ -+ if (prBssInfo->fgUseShortSlotTime) -+ prBssInfo->u2CapInfo |= CAP_INFO_SHORT_SLOT_TIME; -+ /* 4 <6> Find Lowest Basic Rate Index for default TX Rate of MMPDU */ -+ rateGetLowestRateIndexFromRateSet(prBssInfo->u2BSSBasicRateSet, &ucLowestBasicRateIndex); -+ -+ prBssInfo->ucHwDefaultFixedRateCode = aucRateIndex2RateCode[PREAMBLE_DEFAULT_LONG_NONE][ucLowestBasicRateIndex]; -+ -+ /* 4 <7> Fill the EDCA */ -+ -+ prACQueParms = prBssInfo->arACQueParmsForBcast; -+ -+ for (eAci = 0; eAci < WMM_AC_INDEX_NUM; eAci++) { -+ -+ prACQueParms[eAci].fgIsACMSet = FALSE; -+ prACQueParms[eAci].u2Aifsn = auAifsForBcast[eAci]; -+ prACQueParms[eAci].u2CWmin = BIT(auCWminLog2ForBcast[eAci]) - 1; -+ prACQueParms[eAci].u2CWmax = BIT(auCWmaxLog2ForBcast[eAci]) - 1; -+ prACQueParms[eAci].u2TxopLimit = auTxopForBcast[eAci]; -+ -+ prBssInfo->aucCWminLog2ForBcast[eAci] = auCWminLog2ForBcast[eAci]; /* used to send WMM IE */ -+ prBssInfo->aucCWmaxLog2ForBcast[eAci] = auCWmaxLog2ForBcast[eAci]; -+ -+ DBGLOG(BSS, INFO, "Bcast: eAci = %d, ACM = %d, Aifsn = %d, CWmin = %d, CWmax = %d, TxopLimit = %d\n", -+ eAci, prACQueParms[eAci].fgIsACMSet, -+ prACQueParms[eAci].u2Aifsn, -+ prACQueParms[eAci].u2CWmin, -+ prACQueParms[eAci].u2CWmax, prACQueParms[eAci].u2TxopLimit); -+ -+ } -+ -+ prACQueParms = prBssInfo->arACQueParms; -+ -+ for (eAci = 0; eAci < WMM_AC_INDEX_NUM; eAci++) { -+ -+ prACQueParms[eAci].fgIsACMSet = FALSE; -+ prACQueParms[eAci].u2Aifsn = auAifs[eAci]; -+ prACQueParms[eAci].u2CWmin = BIT(auCWminLog2[eAci]) - 1; -+ prACQueParms[eAci].u2CWmax = BIT(auCWmaxLog2[eAci]) - 1; -+ prACQueParms[eAci].u2TxopLimit = auTxop[eAci]; -+ -+ DBGLOG(BSS, INFO, "eAci = %d, ACM = %d, Aifsn = %d, CWmin = %d, CWmax = %d, TxopLimit = %d\n", -+ eAci, prACQueParms[eAci].fgIsACMSet, -+ prACQueParms[eAci].u2Aifsn, -+ prACQueParms[eAci].u2CWmin, -+ prACQueParms[eAci].u2CWmax, prACQueParms[eAci].u2TxopLimit); -+ } -+ -+ /* Note: Caller should update the EDCA setting to HW by nicQmUpdateWmmParms() it there is no AIS network */ -+ /* Note: In E2, only 4 HW queues. The the Edca parameters should be folow by AIS network */ -+ /* Note: In E3, 8 HW queues. the Wmm parameters should be updated to right queues according to BSS */ -+ -+} /* end of bssInitForAP() */ -+ -+#if 0 -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Update DTIM Count -+* -+* @param[in] eNetTypeIndex Specify which network to update -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID bssUpdateDTIMCount(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex) -+{ -+ P_BSS_INFO_T prBssInfo; -+ -+ ASSERT(eNetTypeIndex < NETWORK_TYPE_INDEX_NUM); -+ -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[eNetTypeIndex]); -+ -+ if (prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT) { -+ -+ /* Setup DTIM Count for next TBTT. */ -+ if (prBssInfo->ucDTIMCount > 0) { -+ prBssInfo->ucDTIMCount--; -+ } else { -+ -+ ASSERT(prBssInfo->ucDTIMPeriod > 0); -+ -+ prBssInfo->ucDTIMCount = prBssInfo->ucDTIMPeriod - 1; -+ } -+ } -+ -+} /* end of bssUpdateDTIMIE() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is used to set the Virtual Bitmap in TIM Information Elements -+* -+* @param[in] prBssInfo Pointer to the BSS_INFO_T. -+* @param[in] u2AssocId The association id to set in Virtual Bitmap. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID bssSetTIMBitmap(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prBssInfo, IN UINT_16 u2AssocId) -+{ -+ -+ ASSERT(prBssInfo); -+ -+ if (prBssInfo->ucNetTypeIndex == NETWORK_TYPE_P2P_INDEX) { -+ P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo; -+ -+ prP2pSpecificBssInfo = &(prAdapter->rWifiVar.rP2pSpecificBssInfo); -+ -+ /* Use Association ID == 0 for BMCAST indication */ -+ if (u2AssocId == 0) { -+ -+ prP2pSpecificBssInfo->ucBitmapCtrl |= (UINT_8) BIT(0); -+ } else { -+ PUINT_8 pucPartialVirtualBitmap; -+ UINT_8 ucBitmapToSet; -+ -+ /* (u2AssocId / 8) */ -+ pucPartialVirtualBitmap = &prP2pSpecificBssInfo->aucPartialVirtualBitmap[(u2AssocId >> 3)]; -+ ucBitmapToSet = (UINT_8) BIT((u2AssocId % 8)); -+ -+ if (*pucPartialVirtualBitmap & ucBitmapToSet) { -+ /* The virtual bitmap has been set */ -+ return; -+ } -+ -+ *pucPartialVirtualBitmap |= ucBitmapToSet; -+ -+ /* Update u2SmallestAID and u2LargestAID */ -+ if ((u2AssocId < prP2pSpecificBssInfo->u2SmallestAID) || -+ (prP2pSpecificBssInfo->u2SmallestAID == 0)) { -+ prP2pSpecificBssInfo->u2SmallestAID = u2AssocId; -+ } -+ -+ if ((u2AssocId > prP2pSpecificBssInfo->u2LargestAID) || -+ (prP2pSpecificBssInfo->u2LargestAID == 0)) { -+ prP2pSpecificBssInfo->u2LargestAID = u2AssocId; -+ } -+ } -+ } -+ -+} /* end of bssSetTIMBitmap() */ -+#endif -+ -+#endif /* CFG_SUPPORT_AAA */ -+ -+VOID bssCreateStaRecFromAuth(IN P_ADAPTER_T prAdapter) -+{ -+ -+} -+ -+VOID bssUpdateStaRecFromAssocReq(IN P_ADAPTER_T prAdapter) -+{ -+ -+} -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/cnm.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/cnm.c -new file mode 100644 -index 000000000000..39af02df2af2 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/cnm.c -@@ -0,0 +1,738 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/cnm.c#2 -+*/ -+ -+/*! \file "cnm.c" -+ \brief Module of Concurrent Network Management -+ -+ Module of Concurrent Network Management -+*/ -+ -+/* -+** Log: cnm.c -+ * -+ * 07 17 2012 yuche.tsai -+ * NULL -+ * Compile no error before trial run. -+ * -+ * 11 15 2011 cm.chang -+ * NULL -+ * Fix possible wrong message when P2P is unregistered -+ * -+ * 11 14 2011 yuche.tsai -+ * [WCXRP00001107] [Volunteer Patch][Driver] Large Network Type index assert in FW issue. -+ * Fix large network type index assert in FW issue. -+ * -+ * 11 10 2011 cm.chang -+ * NULL -+ * Modify debug message for XLOG -+ * -+ * 11 08 2011 cm.chang -+ * NULL -+ * Add RLM and CNM debug message for XLOG -+ * -+ * 11 01 2011 cm.chang -+ * [WCXRP00001077] [All Wi-Fi][Driver] Fix wrong preferred channel for AP and BOW -+ * Only check AIS channel for P2P and BOW -+ * -+ * 10 25 2011 cm.chang -+ * [WCXRP00001058] [All Wi-Fi][Driver] Fix sta_rec's phyTypeSet and OBSS scan in AP mode -+ * Extension channel of some 5G AP will not follow regulation requirement -+ * -+ * 09 30 2011 cm.chang -+ * [WCXRP00001020] [MT6620 Wi-Fi][Driver] Handle secondary channel offset of AP in 5GHz band -+ * . -+ * -+ * 09 01 2011 cm.chang -+ * [WCXRP00000937] [MT6620 Wi-Fi][Driver][FW] cnm.c line #848 assert when doing monkey test -+ * Print message only in Linux platform for monkey testing -+ * -+ * 06 23 2011 cp.wu -+ * [WCXRP00000798] [MT6620 Wi-Fi][Firmware] Follow-ups for WAPI frequency offset workaround in firmware SCN module -+ * change parameter name from PeerAddr to BSSID -+ * -+ * 06 20 2011 cp.wu -+ * [WCXRP00000798] [MT6620 Wi-Fi][Firmware] Follow-ups for WAPI frequency offset workaround in firmware SCN module -+ * 1. specify target's BSSID when requesting channel privilege. -+ * 2. pass BSSID information to firmware domain -+ * -+ * 06 01 2011 cm.chang -+ * [WCXRP00000756] [MT6620 Wi-Fi][Driver] 1. AIS follow channel of BOW 2. Provide legal channel function -+ * Limit AIS to fixed channel same with BOW -+ * -+ * 04 12 2011 cm.chang -+ * [WCXRP00000634] [MT6620 Wi-Fi][Driver][FW] 2nd BSS will not support 40MHz bandwidth for concurrency -+ * . -+ * -+ * 03 10 2011 cm.chang -+ * [WCXRP00000358] [MT6620 Wi-Fi][Driver] Provide concurrent information for each module -+ * Check if P2P network index is Tethering AP -+ * -+ * 03 10 2011 cm.chang -+ * [WCXRP00000358] [MT6620 Wi-Fi][Driver] Provide concurrent information for each module -+ * Add some functions to let AIS/Tethering or AIS/BOW be the same channel -+ * -+ * 02 17 2011 cm.chang -+ * [WCXRP00000358] [MT6620 Wi-Fi][Driver] Provide concurrent information for each module -+ * When P2P registried, invoke BOW deactivate function -+ * -+ * 01 12 2011 cm.chang -+ * [WCXRP00000358] [MT6620 Wi-Fi][Driver] Provide concurrent information for each module -+ * Provide function to decide if BSS can be activated or not -+ * -+ * 12 07 2010 cm.chang -+ * [WCXRP00000239] MT6620 Wi-Fi][Driver][FW] Merge concurrent branch back to maintrunk -+ * 1. BSSINFO include RLM parameter -+ * 2. free all sta records when network is disconnected -+ * -+ * 12 07 2010 cm.chang -+ * [WCXRP00000238] MT6620 Wi-Fi][Driver][FW] Support regulation domain setting from NVRAM and supplicant -+ * 1. Country code is from NVRAM or supplicant -+ * 2. Change band definition in CMD/EVENT. -+ * -+ * 11 08 2010 cm.chang -+ * [WCXRP00000169] [MT6620 Wi-Fi][Driver][FW] Remove unused CNM recover message ID -+ * Remove CNM channel reover message ID -+ * -+ * 10 13 2010 cm.chang -+ * [WCXRP00000094] [MT6620 Wi-Fi][Driver] Connect to 2.4GHz AP, Driver crash. -+ * Add exception handle when cmd buffer is not available -+ * -+ * 08 24 2010 cm.chang -+ * NULL -+ * Support RLM initail channel of Ad-hoc, P2P and BOW -+ * -+ * 07 19 2010 wh.su -+ * -+ * update for security supporting. -+ * -+ * 07 19 2010 cm.chang -+ * -+ * Set RLM parameters and enable CNM channel manager -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 07 08 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Rename MID_MNY_CNM_CH_RELEASE to MID_MNY_CNM_CH_ABORT -+ * -+ * 07 01 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Fix wrong message ID for channel grant to requester -+ * -+ * 07 01 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Modify CNM message handler for new flow -+ * -+ * 06 07 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Set 20/40M bandwidth of AP HT OP before association process -+ * -+ * 05 31 2010 yarco.yang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Add RX TSF Log Feature and ADDBA Rsp with DECLINE handling -+ * -+ * 05 21 2010 yarco.yang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Support TCP/UDP/IP Checksum offload feature -+ * -+ * 05 12 2010 kevin.huang -+ * [BORA00000794][WIFISYS][New Feature]Power Management Support -+ * Add Power Management - Legacy PS-POLL support. -+ * -+ * 05 05 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Add a new function to send abort message -+ * -+ * 04 27 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * BMC mac address shall be ignored in basic config command -+ * -+ * 04 24 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * g_aprBssInfo[] depends on CFG_SUPPORT_P2P and CFG_SUPPORT_BOW -+ * -+ * 04 22 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Support change of MAC address by host command -+ * -+ * 04 16 2010 wh.su -+ * [BORA00000680][MT6620] Support the statistic for Micxxsoft os query -+ * adding the wpa-none for ibss beacon. -+ * -+ * 04 07 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Fix bug for OBSS scan -+ * -+ * 03 30 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Support 2.4G OBSS scan -+ * -+ * 03 16 2010 kevin.huang -+ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support -+ * Add AdHoc Mode -+ * -+ * 03 10 2010 kevin.huang -+ * [BORA00000654][WIFISYS][New Feature] CNM Module - Ch Manager Support -+ * -+ * * * * * * * * * * Add Channel Manager for arbitration of JOIN and SCAN Req -+ * -+ * 02 25 2010 wh.su -+ * [BORA00000605][WIFISYS] Phase3 Integration -+ * use the Rx0 dor event indicate. -+ * -+ * 02 08 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Support partial part about cmd basic configuration -+ * -+ * Dec 10 2009 mtk01104 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Remove conditional compiling FPGA_V5 -+ * -+ * Nov 18 2009 mtk01104 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Add function cnmFsmEventInit() -+ * -+ * Nov 2 2009 mtk01104 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * -+** -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "precomp.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is used to initialize variables in CNM_INFO_T. -+* -+* @param (none) -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID cnmInit(P_ADAPTER_T prAdapter) -+{ -+ -+} /* end of cnmInit() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is used to initialize variables in CNM_INFO_T. -+* -+* @param (none) -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID cnmUninit(P_ADAPTER_T prAdapter) -+{ -+ -+} /* end of cnmUninit() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Before handle the message from other module, it need to obtain -+* the Channel privilege from Channel Manager -+* -+* @param[in] prMsgHdr The message need to be handled. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID cnmChMngrRequestPrivilege(P_ADAPTER_T prAdapter, P_MSG_HDR_T prMsgHdr) -+{ -+ P_MSG_CH_REQ_T prMsgChReq; -+ P_CMD_CH_PRIVILEGE_T prCmdBody; -+ WLAN_STATUS rStatus; -+ -+ ASSERT(prAdapter); -+ ASSERT(prMsgHdr); -+ -+ prMsgChReq = (P_MSG_CH_REQ_T) prMsgHdr; -+ -+ prCmdBody = (P_CMD_CH_PRIVILEGE_T) -+ cnmMemAlloc(prAdapter, RAM_TYPE_BUF, sizeof(CMD_CH_PRIVILEGE_T)); -+ ASSERT(prCmdBody); -+ -+ /* To do: exception handle */ -+ if (!prCmdBody) { -+ DBGLOG(CNM, ERROR, "ChReq: fail to get buf (net=%d, token=%d)\n", -+ prMsgChReq->ucNetTypeIndex, prMsgChReq->ucTokenID); -+ -+ cnmMemFree(prAdapter, prMsgHdr); -+ return; -+ } -+ -+ DBGLOG(CNM, INFO, "ChReq net=%d token=%d b=%d c=%d s=%d\n", -+ prMsgChReq->ucNetTypeIndex, prMsgChReq->ucTokenID, -+ prMsgChReq->eRfBand, prMsgChReq->ucPrimaryChannel, prMsgChReq->eRfSco); -+ -+ prCmdBody->ucNetTypeIndex = prMsgChReq->ucNetTypeIndex; -+ prCmdBody->ucTokenID = prMsgChReq->ucTokenID; -+ prCmdBody->ucAction = CMD_CH_ACTION_REQ; /* Request */ -+ prCmdBody->ucPrimaryChannel = prMsgChReq->ucPrimaryChannel; -+ prCmdBody->ucRfSco = (UINT_8) prMsgChReq->eRfSco; -+ prCmdBody->ucRfBand = (UINT_8) prMsgChReq->eRfBand; -+ prCmdBody->ucReqType = (UINT_8) prMsgChReq->eReqType; -+ prCmdBody->ucReserved = 0; -+ prCmdBody->u4MaxInterval = prMsgChReq->u4MaxInterval; -+ COPY_MAC_ADDR(prCmdBody->aucBSSID, prMsgChReq->aucBSSID); -+ -+ ASSERT(prCmdBody->ucNetTypeIndex < NETWORK_TYPE_INDEX_NUM); -+ -+ /* For monkey testing 20110901 */ -+ if (prCmdBody->ucNetTypeIndex >= NETWORK_TYPE_INDEX_NUM) -+ DBGLOG(CNM, ERROR, "CNM: ChReq with wrong netIdx=%d\n\n", prCmdBody->ucNetTypeIndex); -+ -+ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ -+ CMD_ID_CH_PRIVILEGE, /* ucCID */ -+ TRUE, /* fgSetQuery */ -+ FALSE, /* fgNeedResp */ -+ FALSE, /* fgIsOid */ -+ NULL, /* pfCmdDoneHandler */ -+ NULL, /* pfCmdTimeoutHandler */ -+ sizeof(CMD_CH_PRIVILEGE_T), /* u4SetQueryInfoLen */ -+ (PUINT_8) prCmdBody, /* pucInfoBuffer */ -+ NULL, /* pvSetQueryBuffer */ -+ 0 /* u4SetQueryBufferLen */ -+ ); -+ -+ ASSERT(rStatus == WLAN_STATUS_PENDING); -+ -+ cnmMemFree(prAdapter, prCmdBody); -+ cnmMemFree(prAdapter, prMsgHdr); -+ -+} /* end of cnmChMngrRequestPrivilege() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Before deliver the message to other module, it need to release -+* the Channel privilege to Channel Manager. -+* -+* @param[in] prMsgHdr The message need to be delivered -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID cnmChMngrAbortPrivilege(P_ADAPTER_T prAdapter, P_MSG_HDR_T prMsgHdr) -+{ -+ P_MSG_CH_ABORT_T prMsgChAbort; -+ P_CMD_CH_PRIVILEGE_T prCmdBody; -+ WLAN_STATUS rStatus; -+ -+ ASSERT(prAdapter); -+ ASSERT(prMsgHdr); -+ -+ prMsgChAbort = (P_MSG_CH_ABORT_T) prMsgHdr; -+ -+ prCmdBody = (P_CMD_CH_PRIVILEGE_T) -+ cnmMemAlloc(prAdapter, RAM_TYPE_BUF, sizeof(CMD_CH_PRIVILEGE_T)); -+ ASSERT(prCmdBody); -+ -+ /* To do: exception handle */ -+ if (!prCmdBody) { -+ DBGLOG(CNM, ERROR, "ChAbort: fail to get buf (net=%d, token=%d)\n", -+ prMsgChAbort->ucNetTypeIndex, prMsgChAbort->ucTokenID); -+ -+ cnmMemFree(prAdapter, prMsgHdr); -+ return; -+ } -+ -+ DBGLOG(CNM, INFO, "ChAbort net=%d token=%d\n", prMsgChAbort->ucNetTypeIndex, prMsgChAbort->ucTokenID); -+ -+ prCmdBody->ucNetTypeIndex = prMsgChAbort->ucNetTypeIndex; -+ prCmdBody->ucTokenID = prMsgChAbort->ucTokenID; -+ prCmdBody->ucAction = CMD_CH_ACTION_ABORT; /* Abort */ -+ -+ ASSERT(prCmdBody->ucNetTypeIndex < NETWORK_TYPE_INDEX_NUM); -+ -+ /* For monkey testing 20110901 */ -+ if (prCmdBody->ucNetTypeIndex >= NETWORK_TYPE_INDEX_NUM) -+ DBGLOG(CNM, ERROR, "CNM: ChAbort with wrong netIdx=%d\n\n", prCmdBody->ucNetTypeIndex); -+ -+ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ -+ CMD_ID_CH_PRIVILEGE, /* ucCID */ -+ TRUE, /* fgSetQuery */ -+ FALSE, /* fgNeedResp */ -+ FALSE, /* fgIsOid */ -+ NULL, /* pfCmdDoneHandler */ -+ NULL, /* pfCmdTimeoutHandler */ -+ sizeof(CMD_CH_PRIVILEGE_T), /* u4SetQueryInfoLen */ -+ (PUINT_8) prCmdBody, /* pucInfoBuffer */ -+ NULL, /* pvSetQueryBuffer */ -+ 0 /* u4SetQueryBufferLen */ -+ ); -+ -+ ASSERT(rStatus == WLAN_STATUS_PENDING); -+ -+ cnmMemFree(prAdapter, prCmdBody); -+ cnmMemFree(prAdapter, prMsgHdr); -+ -+} /* end of cnmChMngrAbortPrivilege() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief -+* -+* @param (none) -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID cnmChMngrHandleChEvent(P_ADAPTER_T prAdapter, P_WIFI_EVENT_T prEvent) -+{ -+ P_EVENT_CH_PRIVILEGE_T prEventBody; -+ P_MSG_CH_GRANT_T prChResp; -+ -+ ASSERT(prAdapter); -+ ASSERT(prEvent); -+ -+ prEventBody = (P_EVENT_CH_PRIVILEGE_T) (prEvent->aucBuffer); -+ prChResp = (P_MSG_CH_GRANT_T) -+ cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_CH_GRANT_T)); -+ ASSERT(prChResp); -+ -+ /* To do: exception handle */ -+ if (!prChResp) { -+ DBGLOG(CNM, ERROR, "ChGrant: fail to get buf (net=%d, token=%d)\n", -+ prEventBody->ucNetTypeIndex, prEventBody->ucTokenID); -+ -+ return; -+ } -+ -+ DBGLOG(CNM, INFO, "ChGrant net=%d token=%d ch=%d sco=%d\n", -+ prEventBody->ucNetTypeIndex, prEventBody->ucTokenID, -+ prEventBody->ucPrimaryChannel, prEventBody->ucRfSco); -+ -+ ASSERT(prEventBody->ucNetTypeIndex < NETWORK_TYPE_INDEX_NUM); -+ ASSERT(prEventBody->ucStatus == EVENT_CH_STATUS_GRANT); -+ -+ /* Decide message ID based on network and response status */ -+ if (prEventBody->ucNetTypeIndex == NETWORK_TYPE_AIS_INDEX) -+ prChResp->rMsgHdr.eMsgId = MID_CNM_AIS_CH_GRANT; -+#if CFG_ENABLE_WIFI_DIRECT -+ else if ((prAdapter->fgIsP2PRegistered) && (prEventBody->ucNetTypeIndex == NETWORK_TYPE_P2P_INDEX)) -+ prChResp->rMsgHdr.eMsgId = MID_CNM_P2P_CH_GRANT; -+#endif -+#if CFG_ENABLE_BT_OVER_WIFI -+ else if (prEventBody->ucNetTypeIndex == NETWORK_TYPE_BOW_INDEX) -+ prChResp->rMsgHdr.eMsgId = MID_CNM_BOW_CH_GRANT; -+#endif -+ else { -+ cnmMemFree(prAdapter, prChResp); -+ return; -+ } -+ -+ prChResp->ucNetTypeIndex = prEventBody->ucNetTypeIndex; -+ prChResp->ucTokenID = prEventBody->ucTokenID; -+ prChResp->ucPrimaryChannel = prEventBody->ucPrimaryChannel; -+ prChResp->eRfSco = (ENUM_CHNL_EXT_T) prEventBody->ucRfSco; -+ prChResp->eRfBand = (ENUM_BAND_T) prEventBody->ucRfBand; -+ prChResp->eReqType = (ENUM_CH_REQ_TYPE_T) prEventBody->ucReqType; -+ prChResp->u4GrantInterval = prEventBody->u4GrantInterval; -+ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prChResp, MSG_SEND_METHOD_BUF); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is invoked for P2P or BOW networks -+* -+* @param (none) -+* -+* @return TRUE: suggest to adopt the returned preferred channel -+* FALSE: No suggestion. Caller should adopt its preference -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN -+cnmPreferredChannel(P_ADAPTER_T prAdapter, P_ENUM_BAND_T prBand, PUINT_8 pucPrimaryChannel, P_ENUM_CHNL_EXT_T prBssSCO) -+{ -+ P_BSS_INFO_T prBssInfo; -+ -+ ASSERT(prAdapter); -+ ASSERT(prBand); -+ ASSERT(pucPrimaryChannel); -+ ASSERT(prBssSCO); -+ -+ prBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]; -+ -+ if (RLM_NET_PARAM_VALID(prBssInfo)) { -+ *prBand = prBssInfo->eBand; -+ *pucPrimaryChannel = prBssInfo->ucPrimaryChannel; -+ *prBssSCO = prBssInfo->eBssSCO; -+ -+ return TRUE; -+ } -+ -+ return FALSE; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief -+* -+* @param (none) -+* -+* @return TRUE: available channel is limited to return value -+* FALSE: no limited -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN cnmAisInfraChannelFixed(P_ADAPTER_T prAdapter, P_ENUM_BAND_T prBand, PUINT_8 pucPrimaryChannel) -+{ -+#if CFG_ENABLE_WIFI_DIRECT || (CFG_ENABLE_BT_OVER_WIFI && CFG_BOW_LIMIT_AIS_CHNL) -+ P_BSS_INFO_T prBssInfo; -+#endif -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ if (IS_NET_ACTIVE(prAdapter, NETWORK_TYPE_P2P_INDEX) && p2pFuncIsAPMode(prAdapter->rWifiVar.prP2pFsmInfo)) { -+ -+ ASSERT(prAdapter->fgIsP2PRegistered); -+ -+ prBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]; -+ -+ *prBand = prBssInfo->eBand; -+ *pucPrimaryChannel = prBssInfo->ucPrimaryChannel; -+ -+ return TRUE; -+ } -+#endif -+ -+#if CFG_ENABLE_BT_OVER_WIFI && CFG_BOW_LIMIT_AIS_CHNL -+ if (IS_NET_ACTIVE(prAdapter, NETWORK_TYPE_BOW_INDEX)) { -+ -+ prBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_BOW_INDEX]; -+ -+ *prBand = prBssInfo->eBand; -+ *pucPrimaryChannel = prBssInfo->ucPrimaryChannel; -+ -+ return TRUE; -+ } -+#endif -+ -+ return FALSE; -+} -+ -+#if CFG_P2P_LEGACY_COEX_REVISE -+BOOLEAN cnmAisDetectP2PChannel(P_ADAPTER_T prAdapter, P_ENUM_BAND_T prBand, PUINT_8 pucPrimaryChannel) -+{ -+ P_WIFI_VAR_T prWifiVar = &prAdapter->rWifiVar; -+ P_BSS_INFO_T prP2PBssInfo = &prWifiVar->arBssInfo[NETWORK_TYPE_P2P_INDEX]; -+#if CFG_ENABLE_WIFI_DIRECT -+ if (IS_NET_ACTIVE(prAdapter, NETWORK_TYPE_P2P_INDEX) && -+ (prP2PBssInfo->eConnectionState == PARAM_MEDIA_STATE_CONNECTED || -+ (prP2PBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT && prP2PBssInfo->eIntendOPMode == OP_MODE_NUM))) { -+ *prBand = prP2PBssInfo->eBand; -+ *pucPrimaryChannel = prP2PBssInfo->ucPrimaryChannel; -+#if CFG_SUPPORT_MCC -+ if (nicFreq2ChannelNum(prWifiVar->rConnSettings.u4FreqInKHz * 1000) != *pucPrimaryChannel) { -+ DBGLOG(CNM, INFO, "p2p is running on Channel %d, but supplicant try to run as MCC\n", -+ *pucPrimaryChannel); -+ return FALSE; -+ } -+#endif -+ DBGLOG(CNM, INFO, "p2p is running on Channel %d, supplicant try to run as SCC\n", -+ *pucPrimaryChannel); -+ return TRUE; -+ } -+#endif -+ return FALSE; -+} -+#endif -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief -+* -+* @param (none) -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID cnmAisInfraConnectNotify(P_ADAPTER_T prAdapter) -+{ -+#if CFG_ENABLE_BT_OVER_WIFI -+ P_BSS_INFO_T prAisBssInfo, prBowBssInfo; -+ -+ prAisBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]; -+ prBowBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_BOW_INDEX]; -+ -+ if (RLM_NET_PARAM_VALID(prAisBssInfo) && RLM_NET_PARAM_VALID(prBowBssInfo)) { -+ if (prAisBssInfo->eBand != prBowBssInfo->eBand || -+ prAisBssInfo->ucPrimaryChannel != prBowBssInfo->ucPrimaryChannel) { -+ -+ /* Notify BOW to do deactivation */ -+ bowNotifyAllLinkDisconnected(prAdapter); -+ } -+ } -+#endif -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief -+* -+* @param (none) -+* -+* @return TRUE: permitted -+* FALSE: Not permitted -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN cnmAisIbssIsPermitted(P_ADAPTER_T prAdapter) -+{ -+#if CFG_ENABLE_WIFI_DIRECT -+ if (IS_NET_ACTIVE(prAdapter, NETWORK_TYPE_P2P_INDEX)) -+ return FALSE; -+#endif -+ -+#if CFG_ENABLE_BT_OVER_WIFI -+ if (IS_NET_ACTIVE(prAdapter, NETWORK_TYPE_BOW_INDEX)) -+ return FALSE; -+#endif -+ -+ return TRUE; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief -+* -+* @param (none) -+* -+* @return TRUE: permitted -+* FALSE: Not permitted -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN cnmP2PIsPermitted(P_ADAPTER_T prAdapter) -+{ -+ P_BSS_INFO_T prBssInfo; -+ -+ prBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]; -+ -+ if (IS_BSS_ACTIVE(prBssInfo) && prBssInfo->eCurrentOPMode == OP_MODE_IBSS) -+ return FALSE; -+#if CFG_ENABLE_BT_OVER_WIFI -+ if (IS_NET_ACTIVE(prAdapter, NETWORK_TYPE_BOW_INDEX)) { -+ /* Notify BOW to do deactivation */ -+ bowNotifyAllLinkDisconnected(prAdapter); -+ } -+#endif -+ -+ return TRUE; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief -+* -+* @param (none) -+* -+* @return TRUE: permitted -+* FALSE: Not permitted -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN cnmBowIsPermitted(P_ADAPTER_T prAdapter) -+{ -+ P_BSS_INFO_T prBssInfo; -+ -+ prBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]; -+ -+ if (IS_BSS_ACTIVE(prBssInfo) && prBssInfo->eCurrentOPMode == OP_MODE_IBSS) -+ return FALSE; -+#if CFG_ENABLE_WIFI_DIRECT -+ if (IS_NET_ACTIVE(prAdapter, NETWORK_TYPE_P2P_INDEX)) -+ return FALSE; -+#endif -+ -+ return TRUE; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief -+* -+* @param (none) -+* -+* @return TRUE: permitted -+* FALSE: Not permitted -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN cnmBss40mBwPermitted(P_ADAPTER_T prAdapter, ENUM_NETWORK_TYPE_INDEX_T eNetTypeIdx) -+{ -+ P_BSS_INFO_T prBssInfo; -+ UINT_8 i; -+ P_BSS_DESC_T prBssDesc = NULL; -+ -+ /* Note: To support real-time decision instead of current activated-time, -+ * the STA roaming case shall be considered about synchronization -+ * problem. Another variable fgAssoc40mBwAllowed is added to -+ * represent HT capability when association -+ */ -+ for (i = 0; i < NETWORK_TYPE_INDEX_NUM; i++) { -+ if (i != (UINT_8) eNetTypeIdx) { -+ prBssInfo = &prAdapter->rWifiVar.arBssInfo[i]; -+ -+ if (IS_BSS_ACTIVE(prBssInfo) && (prBssInfo->fg40mBwAllowed || prBssInfo->fgAssoc40mBwAllowed)) -+ return FALSE; -+ } -+ } -+ -+ if (eNetTypeIdx == NETWORK_TYPE_AIS_INDEX) -+ prBssDesc = prAdapter->rWifiVar.rAisFsmInfo.prTargetBssDesc; -+ else if ((eNetTypeIdx == NETWORK_TYPE_P2P_INDEX) && (prAdapter->rWifiVar.prP2pFsmInfo)) -+ prBssDesc = prAdapter->rWifiVar.prP2pFsmInfo->prTargetBss; -+ if (prBssDesc) { -+#if (CFG_FORCE_USE_20BW == 1) -+ if (prBssDesc->eBand == BAND_2G4) -+ return FALSE; -+#endif -+ if (prBssDesc->eSco == CHNL_EXT_SCN) -+ return FALSE; -+ } -+ -+ return TRUE; -+} -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/cnm_mem.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/cnm_mem.c -new file mode 100644 -index 000000000000..05bd0ff35f7a ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/cnm_mem.c -@@ -0,0 +1,1236 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/cnm_mem.c#2 -+*/ -+ -+/*! \file "cnm_mem.c" -+ \brief This file contain the management function of packet buffers and -+ generic memory alloc/free functioin for mailbox message. -+ -+ A data packet has a fixed size of buffer, but a management -+ packet can be equipped with a variable size of buffer. -+*/ -+ -+/* -+** Log: cnm_mem.c -+ * -+ * 07 17 2012 yuche.tsai -+ * NULL -+ * Compile no error before trial run. -+ * -+ * 03 14 2012 wh.su -+ * [WCXRP00001173] [MT6620 Wi-Fi][Driver] Adding the ICS Tethering WPA2-PSK supporting -+ * Add code from 2.2 -+ * -+ * 11 17 2011 tsaiyuan.hsu -+ * [WCXRP00001115] [MT6620 Wi-Fi][DRV] avoid deactivating staRec when changing state 3 to 3. -+ * initialize fgNeedResp. -+ * -+ * 11 17 2011 tsaiyuan.hsu -+ * [WCXRP00001115] [MT6620 Wi-Fi][DRV] avoid deactivating staRec when changing state 3 to 3. -+ * avoid deactivating staRec when changing state from 3 to 3. -+ * -+ * 02 01 2011 cm.chang -+ * [WCXRP00000415] [MT6620 Wi-Fi][Driver] Check if any memory leakage happens when uninitializing in DGB mode -+ * . -+ * -+ * 01 26 2011 cm.chang -+ * [WCXRP00000395] [MT6620 Wi-Fi][Driver][FW] Search STA_REC with additional net type index argument -+ * Allocate system RAM if fixed message or mgmt buffer is not available -+ * -+ * 01 26 2011 cm.chang -+ * [WCXRP00000395] [MT6620 Wi-Fi][Driver][FW] Search STA_REC with additional net type index argument -+ * . -+ * -+ * 01 25 2011 yuche.tsai -+ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record. -+ * Change Station Type in Station Record, Modify MACRO definition for getting station type & network type index & Role. -+ * -+ * 12 13 2010 cp.wu -+ * [WCXRP00000260] [MT6620 Wi-Fi][Driver][Firmware] Create V1.1 branch for both firmware and driver -+ * create branch for Wi-Fi driver v1.1 -+ * -+ * 12 07 2010 cm.chang -+ * [WCXRP00000239] MT6620 Wi-Fi][Driver][FW] Merge concurrent branch back to maintrunk -+ * 1. BSSINFO include RLM parameter -+ * 2. free all sta records when network is disconnected -+ * -+ * 11 29 2010 cm.chang -+ * [WCXRP00000210] [MT6620 Wi-Fi][Driver][FW] Set RCPI value in STA_REC -+ * for initial TX rate selection of auto-rate algorithm -+ * Sync RCPI of STA_REC to FW as reference of initial TX rate -+ * -+ * 11 25 2010 yuche.tsai -+ * NULL -+ * Update SLT Function for QoS Support and not be affected by fixed rate function. -+ * -+ * 10 18 2010 cp.wu -+ * [WCXRP00000053] [MT6620 Wi-Fi][Driver] Reset incomplete -+ * and might leads to BSOD when entering RF test with AIS associated -+ * 1. remove redundant variables in STA_REC structure -+ * 2. add STA-REC uninitialization routine for clearing pending events -+ * -+ * 10 13 2010 cm.chang -+ * [WCXRP00000094] [MT6620 Wi-Fi][Driver] Connect to 2.4GHz AP, Driver crash. -+ * Add exception handle when cmd buffer is not available -+ * -+ * 10 12 2010 cp.wu -+ * [WCXRP00000084] [MT6620 Wi-Fi][Driver][FW] Add fixed rate support for distance test -+ * add HT (802.11n) fixed rate support. -+ * -+ * 10 08 2010 cp.wu -+ * [WCXRP00000084] [MT6620 Wi-Fi][Driver][FW] Add fixed rate support for distance test -+ * adding fixed rate support for distance test. (from registry setting) -+ * -+ * 09 24 2010 wh.su -+ * NULL -+ * [WCXRP00005002][MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning. -+ * -+ * 09 21 2010 cp.wu -+ * [WCXRP00000053] [MT6620 Wi-Fi][Driver] Reset incomplete and might leads to BSOD -+ * when entering RF test with AIS associated -+ * Do a complete reset with STA-REC null checking for RF test re-entry -+ * -+ * 09 16 2010 cm.chang -+ * NULL -+ * Change conditional compiling options for BOW -+ * -+ * 09 10 2010 cm.chang -+ * NULL -+ * Always update Beacon content if FW sync OBSS info -+ * -+ * 08 24 2010 cm.chang -+ * NULL -+ * Support RLM initail channel of Ad-hoc, P2P and BOW -+ * -+ * 08 23 2010 chinghwa.yu -+ * NULL -+ * Update for BOW. -+ * -+ * 08 20 2010 cm.chang -+ * NULL -+ * Migrate RLM code to host from FW -+ * -+ * 08 19 2010 wh.su -+ * NULL -+ * adding the tx pkt call back handle for countermeasure. -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 07 08 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Check draft RLM code for HT cap -+ * -+ * 07 07 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Support state of STA record change from 1 to 1 -+ * -+ * 07 05 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Fix correct structure size in cnmStaSendDeactivateCmd() -+ * -+ * 07 05 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) ignore RSN checking when RSN is not turned on. -+ * 2) set STA-REC deactivation callback as NULL -+ * 3) add variable initialization API based on PHY configuration -+ * -+ * 07 02 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * spin lock target revised -+ * -+ * 07 02 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * change inner loop index from i to k. -+ * -+ * 07 01 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Support sync command of STA_REC -+ * -+ * 06 23 2010 yarco.yang -+ * [WPD00003837][MT6620]Data Path Refine -+ * Merge g_arStaRec[] into adapter->arStaRec[] -+ * -+ * 06 18 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Provide cnmMgtPktAlloc() and alloc/free function of msg/buf -+ * -+ * 05 31 2010 yarco.yang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Add RX TSF Log Feature and ADDBA Rsp with DECLINE handling -+ * -+ * 05 28 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Support checking of duplicated buffer free -+ * -+ * 05 28 2010 wh.su -+ * [BORA00000626][MT6620] Refine the remove key flow for WHQL testing -+ * fixed the ad-hoc wpa-none send non-encrypted frame issue. -+ * -+ * 05 28 2010 kevin.huang -+ * [BORA00000794][WIFISYS][New Feature]Power Management Support -+ * Move define of STA_REC_NUM to config.h and rename to CFG_STA_REC_NUM -+ * -+ * 05 12 2010 kevin.huang -+ * [BORA00000794][WIFISYS][New Feature]Power Management Support -+ * Add Power Management - Legacy PS-POLL support. -+ * -+ * 04 28 2010 tehuang.liu -+ * [BORA00000605][WIFISYS] Phase3 Integration -+ * Modified some MQM-related data structures (SN counter, TX/RX BA table) -+ * -+ * 04 27 2010 tehuang.liu -+ * [BORA00000605][WIFISYS] Phase3 Integration -+ * Added new TX/RX BA tables in STA_REC -+ * -+ * 04 27 2010 tehuang.liu -+ * [BORA00000605][WIFISYS] Phase3 Integration -+ * Notify MQM, TXM, and RXM upon disconnection . -+ * -+ * 04 26 2010 tehuang.liu -+ * [BORA00000605][WIFISYS] Phase3 Integration -+ * Call mqm, txm, rxm functions upon disconnection -+ * -+ * 04 24 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * g_aprBssInfo[] depends on CFG_SUPPORT_P2P and CFG_SUPPORT_BOW -+ * -+ * 04 22 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * First draft code to support protection in AP mode -+ * -+ * 04 19 2010 kevin.huang -+ * [BORA00000714][WIFISYS][New Feature]Beacon Timeout Support -+ * Add Beacon Timeout Support -+ * * * * * * * * * * and will send Null frame to diagnose connection -+ * -+ * 04 09 2010 tehuang.liu -+ * [BORA00000605][WIFISYS] Phase3 Integration -+ * [BORA00000644] WiFi phase 4 integration -+ * * Added per-TID SN cache in STA_REC -+ * -+ * 04 07 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Different invoking order for WTBL entry of associated AP -+ * -+ * 03 29 2010 wh.su -+ * [BORA00000605][WIFISYS] Phase3 Integration -+ * move the wlan table alloc / free to change state function. -+ * -+ * 03 24 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Support power control -+ * -+ * 03 03 2010 tehuang.liu -+ * [BORA00000569][WIFISYS] Phase 2 Integration Test -+ * Initialize StaRec->arStaWaitQueue -+ * -+ * 03 03 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Add debug message when no available pkt buffer -+ * -+ * 03 01 2010 tehuang.liu -+ * [BORA00000569][WIFISYS] Phase 2 Integration Test -+ * Fixed STA_REC initialization bug: prStaRec->au2CachedSeqCtrl[k] -+ * -+ * 02 26 2010 tehuang.liu -+ * [BORA00000569][WIFISYS] Phase 2 Integration Test -+ * Added fgIsWmmSupported in STA_RECORD_T. -+ * -+ * 02 26 2010 tehuang.liu -+ * [BORA00000569][WIFISYS] Phase 2 Integration Test -+ * Added fgIsUapsdSupported in STA_RECORD_T -+ * -+ * 02 26 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * add support of Driver STA_RECORD_T activation -+ * -+ * 02 13 2010 tehuang.liu -+ * [BORA00000569][WIFISYS] Phase 2 Integration Test -+ * Added arTspecTable in STA_REC for TSPEC management -+ * -+ * 02 12 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Enable mgmt buffer debug by default -+ * -+ * 02 12 2010 tehuang.liu -+ * [BORA00000569][WIFISYS] Phase 2 Integration Test -+ * Added BUFFER_SOURCE_BCN -+ * -+ * 02 04 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Add AAA Module Support, Revise Net Type to Net Type Index for array lookup -+ * -+ * 01 11 2010 kevin.huang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Add Deauth and Disassoc Handler -+ * -+ * 01 08 2010 cp.wu -+ * [BORA00000368]Integrate HIF part into BORA -+ * 1) separate wifi_var_emu.c/.h from wifi_var.c/.h -+ * * * * * * * * * 2) eliminate HIF_EMULATION code sections appeared in wifi_var/cnm_mem -+ * * * * * * * * * 3) use cnmMemAlloc() instead to allocate SRAM buffer -+ * -+ * 12 25 2009 tehuang.liu -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Integrated modifications for 1st connection (mainly on FW modules MQM, TXM, and RXM) -+ * * * * * * * MQM: BA handling -+ * * * * * * * TXM: Macros updates -+ * * * * * * * RXM: Macros/Duplicate Removal updates -+ * -+ * 12 24 2009 yarco.yang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * . -+ * -+ * 12 21 2009 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Support several data buffer banks. -+ * -+ * 12 18 2009 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * .For new FPGA memory size -+ * -+ * Dec 9 2009 MTK02468 -+ * [BORA00000337] To check in codes for FPGA emulation -+ * Removed DBGPRINT -+ * -+ * Dec 9 2009 mtk02752 -+ * [BORA00000368] Integrate HIF part into BORA -+ * add cnmDataPktFree() for emulation loopback purpose -+ * -+ * Dec 3 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Fix warning of null pointer -+ * -+ * Dec 3 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Add cnmGetStaRecByAddress() and add fgIsInUse flag in STA_RECORD_T -+ * -+ * Nov 23 2009 mtk01104 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Assign ucBufferSource in function cnmMgtPktAlloc() -+ * -+ * Nov 23 2009 mtk02468 -+ * [BORA00000337] To check in codes for FPGA emulation -+ * Added packet redispatch function calls -+ * -+ * Nov 13 2009 mtk01084 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * enable packet re-usable in current emulation driver -+ * -+ * Nov 12 2009 mtk01104 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * 1. Add new function cnmGetStaRecByIndex() -+ * 2. Rename STA_REC_T to STA_RECORD_T -+ * -+ * Nov 9 2009 mtk01104 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Call cnmDataPktDispatch() in cnmPktFree() -+ * -+ * Nov 2 2009 mtk01104 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Remove definition of pragma section code -+ * -+ * Oct 28 2009 mtk01104 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * -+ * -+ * Oct 23 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Fix lint warning -+ * -+ * Oct 23 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Fix typo -+ * -+ * Oct 12 2009 mtk01104 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * -+ * -+ * Oct 8 2009 mtk01104 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * -+** -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "precomp.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+static VOID cnmStaRecHandleEventPkt(P_ADAPTER_T prAdapter, P_CMD_INFO_T prCmdInfo, PUINT_8 pucEventBuf); -+ -+static VOID cnmStaSendUpdateCmd(P_ADAPTER_T prAdapter, P_STA_RECORD_T prStaRec, BOOLEAN fgNeedResp); -+ -+static VOID cnmStaSendRemoveCmd(P_ADAPTER_T prAdapter, P_STA_RECORD_T prStaRec); -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+P_MSDU_INFO_T cnmMgtPktAlloc(P_ADAPTER_T prAdapter, UINT_32 u4Length) -+{ -+ P_MSDU_INFO_T prMsduInfo; -+ P_QUE_T prQueList; -+ -+ KAL_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(prAdapter); -+ prQueList = &prAdapter->rTxCtrl.rFreeMsduInfoList; -+ -+ /* Get a free MSDU_INFO_T */ -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_MSDU_INFO_LIST); -+ QUEUE_REMOVE_HEAD(prQueList, prMsduInfo, P_MSDU_INFO_T); -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_MSDU_INFO_LIST); -+ -+ if (prMsduInfo) { -+ prMsduInfo->prPacket = cnmMemAlloc(prAdapter, RAM_TYPE_BUF, u4Length); -+ prMsduInfo->eSrc = TX_PACKET_MGMT; -+ -+ if (prMsduInfo->prPacket == NULL) { -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_MSDU_INFO_LIST); -+ QUEUE_INSERT_TAIL(prQueList, &prMsduInfo->rQueEntry); -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_MSDU_INFO_LIST); -+ prMsduInfo = NULL; -+ } -+ if (prMsduInfo) { -+ prMsduInfo->eCmdType = COMMAND_TYPE_NUM; -+ prMsduInfo->ucCID = 0xff; -+ prMsduInfo->u4InqueTime = 0; -+ prMsduInfo->ucPacketType = TX_PACKET_NUM; -+ } -+ } else { -+ P_QUE_T prTxingQue; -+ P_QUE_ENTRY_T prQueueEntry = (P_QUE_ENTRY_T) NULL; -+ P_MSDU_INFO_T prMsduInfo = (P_MSDU_INFO_T) NULL; -+ P_TX_TCQ_STATUS_T pTc = (P_TX_TCQ_STATUS_T) NULL; -+ -+ prTxingQue = &(prAdapter->rTxCtrl.rTxMgmtTxingQueue); -+ pTc = &(prAdapter->rTxCtrl.rTc); -+ -+ DBGLOG(MEM, LOUD, "++dump TxPendingMsdu=%u, Tc0=%d Tc1=%d Tc2=%d Tc3=%d, Tc4=%d Tc5=%d\n", -+ prTxingQue->u4NumElem, pTc->aucFreeBufferCount[TC0_INDEX], -+ pTc->aucFreeBufferCount[TC1_INDEX], pTc->aucFreeBufferCount[TC2_INDEX], -+ pTc->aucFreeBufferCount[TC3_INDEX], pTc->aucFreeBufferCount[TC4_INDEX], -+ pTc->aucFreeBufferCount[TC5_INDEX]); -+ -+ prQueueEntry = QUEUE_GET_HEAD(prTxingQue); -+ -+ while (prQueueEntry) { -+ prMsduInfo = (P_MSDU_INFO_T) prQueueEntry; -+ -+ DBGLOG(MEM, LOUD, -+ "msdu type=%u, ucid=%u, type=%d, time=%u, seq=%u, sta=%u\n", -+ prMsduInfo->ucPacketType, -+ prMsduInfo->ucCID, -+ prMsduInfo->eCmdType, -+ prMsduInfo->u4InqueTime, prMsduInfo->ucTxSeqNum, prMsduInfo->ucStaRecIndex); -+ prQueueEntry = QUEUE_GET_NEXT_ENTRY(prQueueEntry); -+ } -+ DBGLOG(MEM, LOUD, "--end dump\n"); -+ } -+ -+#if DBG -+ if (prMsduInfo == NULL) { -+ DBGLOG(MEM, WARN, "MgtDesc#=%u\n", prQueList->u4NumElem); -+ -+#if CFG_DBG_MGT_BUF -+ DBGLOG(MEM, WARN, "rMgtBufInfo: alloc#=%u, free#=%u, null#=%u\n", -+ prAdapter->rMgtBufInfo.u4AllocCount, -+ prAdapter->rMgtBufInfo.u4FreeCount, prAdapter->rMgtBufInfo.u4AllocNullCount); -+#endif -+ -+ DBGLOG(MEM, WARN, "\n"); -+ } -+#endif -+ -+ return prMsduInfo; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID cnmMgtPktFree(P_ADAPTER_T prAdapter, P_MSDU_INFO_T prMsduInfo) -+{ -+ P_QUE_T prQueList; -+ -+ KAL_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(prAdapter); -+ ASSERT(prMsduInfo); -+ -+ prQueList = &prAdapter->rTxCtrl.rFreeMsduInfoList; -+ -+ ASSERT(prMsduInfo->prPacket); -+ if (prMsduInfo->prPacket) { -+ cnmMemFree(prAdapter, prMsduInfo->prPacket); -+ prMsduInfo->prPacket = NULL; -+ } -+ -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_MSDU_INFO_LIST); -+ prMsduInfo->fgIsBasicRate = FALSE; -+ QUEUE_INSERT_TAIL(prQueList, &prMsduInfo->rQueEntry) -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_MSDU_INFO_LIST); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is used to initial the MGMT/MSG memory pool. -+* -+* \param (none) -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID cnmMemInit(P_ADAPTER_T prAdapter) -+{ -+ P_BUF_INFO_T prBufInfo; -+ -+ /* Initialize Management buffer pool */ -+ prBufInfo = &prAdapter->rMgtBufInfo; -+ kalMemZero(prBufInfo, sizeof(prAdapter->rMgtBufInfo)); -+ prBufInfo->pucBuf = prAdapter->pucMgtBufCached; -+ -+ /* Setup available memory blocks. 1 indicates FREE */ -+ prBufInfo->rFreeBlocksBitmap = (BUF_BITMAP) BITS(0, MAX_NUM_OF_BUF_BLOCKS - 1); -+ -+ /* Initialize Message buffer pool */ -+ prBufInfo = &prAdapter->rMsgBufInfo; -+ kalMemZero(prBufInfo, sizeof(prAdapter->rMsgBufInfo)); -+ prBufInfo->pucBuf = &prAdapter->aucMsgBuf[0]; -+ -+ /* Setup available memory blocks. 1 indicates FREE */ -+ prBufInfo->rFreeBlocksBitmap = (BUF_BITMAP) BITS(0, MAX_NUM_OF_BUF_BLOCKS - 1); -+ -+ return; -+ -+} /* end of cnmMemInit() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Allocate MGMT/MSG memory pool. -+* -+* \param[in] eRamType Target RAM type. -+* TCM blk_sz= 16bytes, BUF blk_sz= 256bytes -+* \param[in] u4Length Length of the buffer to allocate. -+* -+* \retval !NULL Pointer to the start address of allocated memory. -+* \retval NULL Fail to allocat memory -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT_32 u4MemAllocCnt = 0, u4MemFreeCnt = 0; -+PVOID cnmMemAlloc(IN P_ADAPTER_T prAdapter, IN ENUM_RAM_TYPE_T eRamType, IN UINT_32 u4Length) -+{ -+ P_BUF_INFO_T prBufInfo; -+ BUF_BITMAP rRequiredBitmap; -+ UINT_32 u4BlockNum; -+ UINT_32 i, u4BlkSzInPower; -+ PVOID pvMemory; -+ -+ KAL_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(prAdapter); -+ ASSERT(u4Length); -+ -+ u4MemAllocCnt++; -+ -+ if (eRamType == RAM_TYPE_MSG && u4Length <= 256) { -+ prBufInfo = &prAdapter->rMsgBufInfo; -+ u4BlkSzInPower = MSG_BUF_BLOCK_SIZE_IN_POWER_OF_2; -+ -+ u4Length += (MSG_BUF_BLOCK_SIZE - 1); -+ u4BlockNum = u4Length >> MSG_BUF_BLOCK_SIZE_IN_POWER_OF_2; -+ -+ ASSERT(u4BlockNum <= MAX_NUM_OF_BUF_BLOCKS); -+ } else { -+ eRamType = RAM_TYPE_BUF; -+ -+ prBufInfo = &prAdapter->rMgtBufInfo; -+ u4BlkSzInPower = MGT_BUF_BLOCK_SIZE_IN_POWER_OF_2; -+ -+ u4Length += (MGT_BUF_BLOCK_SIZE - 1); -+ u4BlockNum = u4Length >> MGT_BUF_BLOCK_SIZE_IN_POWER_OF_2; -+ -+ ASSERT(u4BlockNum <= MAX_NUM_OF_BUF_BLOCKS); -+ } -+ -+#if CFG_DBG_MGT_BUF -+ prBufInfo->u4AllocCount++; -+#endif -+ -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, eRamType == RAM_TYPE_MSG ? SPIN_LOCK_MSG_BUF : SPIN_LOCK_MGT_BUF); -+ -+ if ((u4BlockNum > 0) && (u4BlockNum <= MAX_NUM_OF_BUF_BLOCKS)) { -+ -+ /* Convert number of block into bit cluster */ -+ rRequiredBitmap = BITS(0, u4BlockNum - 1); -+ -+ for (i = 0; i <= (MAX_NUM_OF_BUF_BLOCKS - u4BlockNum); i++) { -+ -+ /* Have available memory blocks */ -+ if ((prBufInfo->rFreeBlocksBitmap & rRequiredBitmap) -+ == rRequiredBitmap) { -+ -+ /* Clear corresponding bits of allocated memory blocks */ -+ prBufInfo->rFreeBlocksBitmap &= ~rRequiredBitmap; -+ -+ /* Store how many blocks be allocated */ -+ prBufInfo->aucAllocatedBlockNum[i] = (UINT_8) u4BlockNum; -+ -+ KAL_RELEASE_SPIN_LOCK(prAdapter, -+ eRamType == RAM_TYPE_MSG ? SPIN_LOCK_MSG_BUF : SPIN_LOCK_MGT_BUF); -+ -+ /* Return the start address of allocated memory */ -+ return (PVOID) (prBufInfo->pucBuf + (i << u4BlkSzInPower)); -+ -+ } -+ -+ rRequiredBitmap <<= 1; -+ } -+ } -+ -+ KAL_RELEASE_SPIN_LOCK(prAdapter, eRamType == RAM_TYPE_MSG ? SPIN_LOCK_MSG_BUF : SPIN_LOCK_MGT_BUF); -+ -+ /* cannot move the allocation between spin_lock_irqsave and spin_unlock_irqrestore */ -+#ifdef LINUX -+ pvMemory = (PVOID) kalMemAlloc(u4Length, VIR_MEM_TYPE); -+ if (pvMemory) -+ kalMemZero(pvMemory, u4Length); -+#else -+ pvMemory = (PVOID) NULL; -+#endif -+ -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, eRamType == RAM_TYPE_MSG ? SPIN_LOCK_MSG_BUF : SPIN_LOCK_MGT_BUF); -+ -+#if CFG_DBG_MGT_BUF -+ prBufInfo->u4AllocNullCount++; -+ -+ if (pvMemory) -+ prAdapter->u4MemAllocDynamicCount++; -+#endif -+ -+ KAL_RELEASE_SPIN_LOCK(prAdapter, eRamType == RAM_TYPE_MSG ? SPIN_LOCK_MSG_BUF : SPIN_LOCK_MGT_BUF); -+ -+ return pvMemory; -+ -+} /* end of cnmMemAlloc() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Release memory to MGT/MSG memory pool. -+* -+* \param pucMemory Start address of previous allocated memory -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID cnmMemFree(IN P_ADAPTER_T prAdapter, IN PVOID pvMemory) -+{ -+ P_BUF_INFO_T prBufInfo; -+ UINT_32 u4BlockIndex; -+ BUF_BITMAP rAllocatedBlocksBitmap; -+ ENUM_RAM_TYPE_T eRamType; -+ -+ KAL_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(prAdapter); -+ ASSERT(pvMemory); -+ if (!pvMemory) -+ return; -+ -+ u4MemFreeCnt++; -+ -+ /* Judge it belongs to which RAM type */ -+ if (((ULONG) pvMemory >= (ULONG)&prAdapter->aucMsgBuf[0]) && -+ ((ULONG) pvMemory <= (ULONG)&prAdapter->aucMsgBuf[MSG_BUFFER_SIZE - 1])) { -+ -+ prBufInfo = &prAdapter->rMsgBufInfo; -+ u4BlockIndex = ((ULONG) pvMemory - (ULONG) prBufInfo->pucBuf) -+ >> MSG_BUF_BLOCK_SIZE_IN_POWER_OF_2; -+ ASSERT(u4BlockIndex < MAX_NUM_OF_BUF_BLOCKS); -+ eRamType = RAM_TYPE_MSG; -+ } else if (((ULONG) pvMemory >= (ULONG) prAdapter->pucMgtBufCached) && -+ ((ULONG) pvMemory <= ((ULONG) prAdapter->pucMgtBufCached + MGT_BUFFER_SIZE - 1))) { -+ prBufInfo = &prAdapter->rMgtBufInfo; -+ u4BlockIndex = ((ULONG) pvMemory - (ULONG) prBufInfo->pucBuf) -+ >> MGT_BUF_BLOCK_SIZE_IN_POWER_OF_2; -+ ASSERT(u4BlockIndex < MAX_NUM_OF_BUF_BLOCKS); -+ eRamType = RAM_TYPE_BUF; -+ } else { -+#ifdef LINUX -+ /* For Linux, it is supported because size is not needed */ -+ kalMemFree(pvMemory, VIR_MEM_TYPE, 0); -+#else -+ /* For Windows, it is not supported because of no size argument */ -+ ASSERT(0); -+#endif -+ -+#if CFG_DBG_MGT_BUF -+ prAdapter->u4MemFreeDynamicCount++; -+#endif -+ return; -+ } -+ -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, eRamType == RAM_TYPE_MSG ? SPIN_LOCK_MSG_BUF : SPIN_LOCK_MGT_BUF); -+ -+#if CFG_DBG_MGT_BUF -+ prBufInfo->u4FreeCount++; -+#endif -+ -+ /* Convert number of block into bit cluster */ -+ ASSERT(prBufInfo->aucAllocatedBlockNum[u4BlockIndex] > 0); -+ -+ rAllocatedBlocksBitmap = BITS(0, prBufInfo->aucAllocatedBlockNum[u4BlockIndex] - 1); -+ rAllocatedBlocksBitmap <<= u4BlockIndex; -+ -+ /* Clear saved block count for this memory segment */ -+ prBufInfo->aucAllocatedBlockNum[u4BlockIndex] = 0; -+ -+ /* Set corresponding bit of released memory block */ -+ prBufInfo->rFreeBlocksBitmap |= rAllocatedBlocksBitmap; -+ -+ KAL_RELEASE_SPIN_LOCK(prAdapter, eRamType == RAM_TYPE_MSG ? SPIN_LOCK_MSG_BUF : SPIN_LOCK_MGT_BUF); -+ -+ return; -+ -+} /* end of cnmMemFree() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID cnmStaRecInit(P_ADAPTER_T prAdapter) -+{ -+ P_STA_RECORD_T prStaRec; -+ UINT_16 i; -+ -+ for (i = 0; i < CFG_STA_REC_NUM; i++) { -+ prStaRec = &prAdapter->arStaRec[i]; -+ -+ prStaRec->ucIndex = (UINT_8) i; -+ prStaRec->fgIsInUse = FALSE; -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID cnmStaRecUninit(IN P_ADAPTER_T prAdapter) -+{ -+ P_STA_RECORD_T prStaRec; -+ UINT_16 i; -+ -+ for (i = 0; i < CFG_STA_REC_NUM; i++) { -+ prStaRec = &prAdapter->arStaRec[i]; -+ -+ if (prStaRec->fgIsInUse) -+ cnmStaRecFree(prAdapter, prStaRec, FALSE); -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+P_STA_RECORD_T cnmStaRecAlloc(P_ADAPTER_T prAdapter, UINT_8 ucNetTypeIndex) -+{ -+ P_STA_RECORD_T prStaRec; -+ UINT_16 i, k; -+ -+ ASSERT(prAdapter); -+ -+ for (i = 0; i < CFG_STA_REC_NUM; i++) { -+ prStaRec = &prAdapter->arStaRec[i]; -+ -+ if (!prStaRec->fgIsInUse) { -+ /*---- Initialize STA_REC_T here ----*/ -+ kalMemZero(prStaRec, sizeof(STA_RECORD_T)); -+ prStaRec->ucIndex = (UINT_8) i; -+ prStaRec->ucNetTypeIndex = ucNetTypeIndex; -+ prStaRec->fgIsInUse = TRUE; -+ -+ if (prStaRec->pucAssocReqIe) { -+ kalMemFree(prStaRec->pucAssocReqIe, VIR_MEM_TYPE, prStaRec->u2AssocReqIeLen); -+ prStaRec->pucAssocReqIe = NULL; -+ prStaRec->u2AssocReqIeLen = 0; -+ } -+ -+ /* Initialize the SN caches for duplicate detection */ -+ for (k = 0; k < TID_NUM + 1; k++) -+ prStaRec->au2CachedSeqCtrl[k] = 0xFFFF; -+ -+ /* Initialize SW TX queues in STA_REC */ -+ for (k = 0; k < STA_WAIT_QUEUE_NUM; k++) -+ LINK_INITIALIZE(&prStaRec->arStaWaitQueue[k]); -+ -+ /* Default enable TX/RX AMPDU */ -+ prStaRec->fgTxAmpduEn = TRUE; -+ prStaRec->fgRxAmpduEn = TRUE; -+ -+#if CFG_ENABLE_PER_STA_STATISTICS && CFG_ENABLE_PKT_LIFETIME_PROFILE -+ prStaRec->u4TotalTxPktsNumber = 0; -+ prStaRec->u4TotalTxPktsTime = 0; -+ prStaRec->u4MaxTxPktsTime = 0; -+#endif -+ -+ for (k = 0; k < NUM_OF_PER_STA_TX_QUEUES; k++) -+ QUEUE_INITIALIZE(&prStaRec->arTxQueue[k]); -+ -+ break; -+ } -+ } -+ -+ return (i < CFG_STA_REC_NUM) ? prStaRec : NULL; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID cnmStaRecFree(P_ADAPTER_T prAdapter, P_STA_RECORD_T prStaRec, BOOLEAN fgSyncToChip) -+{ -+ ASSERT(prAdapter); -+ ASSERT(prStaRec); -+ -+ /* To do: free related resources, e.g. timers, buffers, etc */ -+ cnmTimerStopTimer(prAdapter, &prStaRec->rTxReqDoneOrRxRespTimer); -+ prStaRec->fgTransmitKeyExist = FALSE; -+ prStaRec->fgSetPwrMgtBit = FALSE; -+ -+ if (prStaRec->pucAssocReqIe) { -+ kalMemFree(prStaRec->pucAssocReqIe, VIR_MEM_TYPE, prStaRec->u2AssocReqIeLen); -+ prStaRec->pucAssocReqIe = NULL; -+ prStaRec->u2AssocReqIeLen = 0; -+ } -+ -+ qmDeactivateStaRec(prAdapter, prStaRec->ucIndex); -+ -+ if (fgSyncToChip) -+ cnmStaSendRemoveCmd(prAdapter, prStaRec); -+ -+ prStaRec->fgIsInUse = FALSE; -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID cnmStaFreeAllStaByNetType(P_ADAPTER_T prAdapter, ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, BOOLEAN fgSyncToChip) -+{ -+ P_STA_RECORD_T prStaRec; -+ UINT_16 i; -+ -+ for (i = 0; i < CFG_STA_REC_NUM; i++) { -+ prStaRec = (P_STA_RECORD_T) &prAdapter->arStaRec[i]; -+ -+ if (prStaRec->fgIsInUse && prStaRec->ucNetTypeIndex == (UINT_8) eNetTypeIndex) -+ cnmStaRecFree(prAdapter, prStaRec, fgSyncToChip); -+ } /* end of for loop */ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+P_STA_RECORD_T cnmGetStaRecByIndex(P_ADAPTER_T prAdapter, UINT_8 ucIndex) -+{ -+ P_STA_RECORD_T prStaRec; -+ -+ ASSERT(prAdapter); -+ -+ prStaRec = (ucIndex < CFG_STA_REC_NUM) ? &prAdapter->arStaRec[ucIndex] : NULL; -+ -+ if (prStaRec && prStaRec->fgIsInUse == FALSE) -+ prStaRec = NULL; -+ -+ return prStaRec; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Get STA_RECORD_T by Peer MAC Address(Usually TA). -+* -+* @param[in] pucPeerMacAddr Given Peer MAC Address. -+* -+* @retval Pointer to STA_RECORD_T, if found. NULL, if not found -+*/ -+/*----------------------------------------------------------------------------*/ -+P_STA_RECORD_T cnmGetStaRecByAddress(P_ADAPTER_T prAdapter, UINT_8 ucNetTypeIndex, PUINT_8 pucPeerMacAddr) -+{ -+ P_STA_RECORD_T prStaRec; -+ UINT_16 i; -+ -+ ASSERT(prAdapter); -+ ASSERT(pucPeerMacAddr); -+ -+ for (i = 0; i < CFG_STA_REC_NUM; i++) { -+ prStaRec = &prAdapter->arStaRec[i]; -+ -+ if (prStaRec->fgIsInUse && -+ prStaRec->ucNetTypeIndex == ucNetTypeIndex && -+ EQUAL_MAC_ADDR(prStaRec->aucMacAddr, pucPeerMacAddr)) { -+ break; -+ } -+ } -+ -+ return (i < CFG_STA_REC_NUM) ? prStaRec : NULL; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Reset the Status and Reason Code Field to 0 of all Station Records for -+* the specified Network Type -+* -+* @param[in] eNetType Specify Network Type -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID cnmStaRecResetStatus(P_ADAPTER_T prAdapter, ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex) -+{ -+ cnmStaFreeAllStaByNetType(prAdapter, eNetTypeIndex, FALSE); -+ -+#if 0 -+ P_STA_RECORD_T prStaRec; -+ UINT_16 i; -+ -+ ASSERT(prAdapter); -+ -+ for (i = 0; i < CFG_STA_REC_NUM; i++) { -+ prStaRec = &prAdapter->arStaRec[i]; -+ -+ if (prStaRec->fgIsInUse) { -+ if ((NETWORK_TYPE_AIS_INDEX == eNetTypeIndex) && IS_STA_IN_AIS(prStaRec->eStaType)) { -+ -+ prStaRec->u2StatusCode = STATUS_CODE_SUCCESSFUL; -+ prStaRec->u2ReasonCode = REASON_CODE_RESERVED; -+ prStaRec->ucJoinFailureCount = 0; -+ prStaRec->fgTransmitKeyExist = FALSE; -+ -+ prStaRec->fgSetPwrMgtBit = FALSE; -+ } -+ -+ /* TODO(Kevin): For P2P and BOW */ -+ } -+ } -+ -+ return; -+#endif -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will change the ucStaState of STA_RECORD_T and also do -+* event indication to HOST to sync the STA_RECORD_T in driver. -+* -+* @param[in] prStaRec Pointer to the STA_RECORD_T -+* @param[in] u4NewState New STATE to change. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID cnmStaRecChangeState(P_ADAPTER_T prAdapter, P_STA_RECORD_T prStaRec, UINT_8 ucNewState) -+{ -+ BOOLEAN fgNeedResp; -+ -+ ASSERT(prAdapter); -+ ASSERT(prStaRec); -+ ASSERT(prStaRec->fgIsInUse); -+ -+ /* Do nothing when following state transitions happen, -+ * other 6 conditions should be sync to FW, including 1-->1, 3-->3 -+ */ -+ if ((ucNewState == STA_STATE_2 && prStaRec->ucStaState != STA_STATE_3) || -+ (ucNewState == STA_STATE_1 && prStaRec->ucStaState == STA_STATE_2)) { -+ prStaRec->ucStaState = ucNewState; -+ return; -+ } -+ -+ fgNeedResp = FALSE; -+ if (ucNewState == STA_STATE_3) { -+ secFsmEventStart(prAdapter, prStaRec); -+ if (ucNewState != prStaRec->ucStaState) -+ fgNeedResp = TRUE; -+ } else { -+ if (ucNewState != prStaRec->ucStaState && prStaRec->ucStaState == STA_STATE_3) -+ qmDeactivateStaRec(prAdapter, prStaRec->ucIndex); -+ fgNeedResp = FALSE; -+ } -+ prStaRec->ucStaState = ucNewState; -+ -+ cnmStaSendUpdateCmd(prAdapter, prStaRec, fgNeedResp); -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ /* To do: Confirm if it is invoked here or other location, but it should -+ * be invoked after state sync of STA_REC -+ * Update system operation parameters for AP mode -+ */ -+ if (prAdapter->fgIsP2PRegistered && (IS_STA_IN_P2P(prStaRec))) { -+ P_BSS_INFO_T prBssInfo; -+ -+ prBssInfo = &prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]; -+ -+ if (prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT) -+ rlmUpdateParamsForAP(prAdapter, prBssInfo, FALSE); -+ } -+#endif -+} -+ -+P_STA_RECORD_T -+cnmStaTheTypeGet(P_ADAPTER_T prAdapter, -+ ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, ENUM_STA_TYPE_T eStaType, UINT32 *pu4StartIdx) -+{ -+ P_STA_RECORD_T prStaRec = NULL; -+ UINT_16 i; -+ -+ for (i = *pu4StartIdx; i < CFG_STA_REC_NUM; i++) { -+ prStaRec = (P_STA_RECORD_T) &prAdapter->arStaRec[i]; -+ -+ if (prStaRec->fgIsInUse && -+ prStaRec->ucNetTypeIndex == (UINT_8) eNetTypeIndex && prStaRec->eStaType == eStaType) { -+ i++; -+ break; -+ } -+ -+ prStaRec = NULL; /* reset */ -+ } /* end of for loop */ -+ -+ *pu4StartIdx = i; -+ return prStaRec; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief -+* -+* @param[in] -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+static VOID cnmStaRecHandleEventPkt(P_ADAPTER_T prAdapter, P_CMD_INFO_T prCmdInfo, PUINT_8 pucEventBuf) -+{ -+ P_EVENT_ACTIVATE_STA_REC_T prEventContent; -+ P_STA_RECORD_T prStaRec; -+ -+ prEventContent = (P_EVENT_ACTIVATE_STA_REC_T) pucEventBuf; -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prEventContent->ucStaRecIdx); -+ -+ if (prStaRec && prStaRec->ucStaState == STA_STATE_3 && -+ !kalMemCmp(&prStaRec->aucMacAddr[0], &prEventContent->aucMacAddr[0], MAC_ADDR_LEN)) { -+ -+ qmActivateStaRec(prAdapter, prStaRec); -+ } -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief -+* -+* @param[in] -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+static VOID cnmStaSendUpdateCmd(P_ADAPTER_T prAdapter, P_STA_RECORD_T prStaRec, BOOLEAN fgNeedResp) -+{ -+ P_CMD_UPDATE_STA_RECORD_T prCmdContent; -+ WLAN_STATUS rStatus; -+ -+ ASSERT(prAdapter); -+ ASSERT(prStaRec); -+ ASSERT(prStaRec->fgIsInUse); -+ -+ /* To do: come out a mechanism to limit one STA_REC sync once for AP mode -+ * to avoid buffer empty case when many STAs are associated -+ * simultaneously. -+ */ -+ -+ /* To do: how to avoid 2 times of allocated memory. Use Stack? -+ * One is here, the other is in wlanSendQueryCmd() -+ */ -+ prCmdContent = cnmMemAlloc(prAdapter, RAM_TYPE_BUF, sizeof(CMD_UPDATE_STA_RECORD_T)); -+ ASSERT(prCmdContent); -+ -+ /* To do: exception handle */ -+ if (!prCmdContent) -+ return; -+ -+ prCmdContent->ucIndex = prStaRec->ucIndex; -+ prCmdContent->ucStaType = (UINT_8) prStaRec->eStaType; -+ kalMemCopy(&prCmdContent->aucMacAddr[0], &prStaRec->aucMacAddr[0], MAC_ADDR_LEN); -+ prCmdContent->u2AssocId = prStaRec->u2AssocId; -+ prCmdContent->u2ListenInterval = prStaRec->u2ListenInterval; -+ prCmdContent->ucNetTypeIndex = prStaRec->ucNetTypeIndex; -+ -+ prCmdContent->ucDesiredPhyTypeSet = prStaRec->ucDesiredPhyTypeSet; -+ prCmdContent->u2DesiredNonHTRateSet = prStaRec->u2DesiredNonHTRateSet; -+ prCmdContent->u2BSSBasicRateSet = prStaRec->u2BSSBasicRateSet; -+ prCmdContent->ucMcsSet = prStaRec->ucMcsSet; -+ prCmdContent->ucSupMcs32 = (UINT_8) prStaRec->fgSupMcs32; -+ prCmdContent->u2HtCapInfo = prStaRec->u2HtCapInfo; -+ prCmdContent->ucNeedResp = (UINT_8) fgNeedResp; -+ -+#if !CFG_SLT_SUPPORT -+ if (prAdapter->rWifiVar.eRateSetting != FIXED_RATE_NONE) { -+ /* override rate configuration */ -+ nicUpdateRateParams(prAdapter, -+ prAdapter->rWifiVar.eRateSetting, -+ &(prCmdContent->ucDesiredPhyTypeSet), -+ &(prCmdContent->u2DesiredNonHTRateSet), -+ &(prCmdContent->u2BSSBasicRateSet), -+ &(prCmdContent->ucMcsSet), -+ &(prCmdContent->ucSupMcs32), &(prCmdContent->u2HtCapInfo)); -+ } -+#endif -+ -+ prCmdContent->ucIsQoS = prStaRec->fgIsQoS; -+ prCmdContent->ucIsUapsdSupported = prStaRec->fgIsUapsdSupported; -+ prCmdContent->ucStaState = prStaRec->ucStaState; -+ -+ prCmdContent->ucAmpduParam = prStaRec->ucAmpduParam; -+ prCmdContent->u2HtExtendedCap = prStaRec->u2HtExtendedCap; -+ prCmdContent->u4TxBeamformingCap = prStaRec->u4TxBeamformingCap; -+ prCmdContent->ucAselCap = prStaRec->ucAselCap; -+ prCmdContent->ucRCPI = prStaRec->ucRCPI; -+ -+ prCmdContent->ucUapsdAc = prStaRec->ucBmpTriggerAC | (prStaRec->ucBmpDeliveryAC << 4); -+ prCmdContent->ucUapsdSp = prStaRec->ucUapsdSp; -+ -+ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ -+ CMD_ID_UPDATE_STA_RECORD, /* ucCID */ -+ TRUE, /* fgSetQuery */ -+ fgNeedResp, /* fgNeedResp */ -+ FALSE, /* fgIsOid */ -+ fgNeedResp ? cnmStaRecHandleEventPkt : NULL, NULL, /* pfCmdTimeoutHandler */ -+ sizeof(CMD_UPDATE_STA_RECORD_T), /* u4SetQueryInfoLen */ -+ (PUINT_8) prCmdContent, /* pucInfoBuffer */ -+ NULL, /* pvSetQueryBuffer */ -+ 0 /* u4SetQueryBufferLen */ -+ ); -+ -+ ASSERT(rStatus == WLAN_STATUS_PENDING); -+ -+ cnmMemFree(prAdapter, prCmdContent); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief -+* -+* @param[in] -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+static VOID cnmStaSendRemoveCmd(P_ADAPTER_T prAdapter, P_STA_RECORD_T prStaRec) -+{ -+ CMD_REMOVE_STA_RECORD_T rCmdContent; -+ WLAN_STATUS rStatus; -+ -+ ASSERT(prAdapter); -+ ASSERT(prStaRec); -+ -+ rCmdContent.ucIndex = prStaRec->ucIndex; -+ kalMemCopy(&rCmdContent.aucMacAddr[0], &prStaRec->aucMacAddr[0], MAC_ADDR_LEN); -+ -+ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ -+ CMD_ID_REMOVE_STA_RECORD, /* ucCID */ -+ TRUE, /* fgSetQuery */ -+ FALSE, /* fgNeedResp */ -+ FALSE, /* fgIsOid */ -+ NULL, /* pfCmdDoneHandler */ -+ NULL, /* pfCmdTimeoutHandler */ -+ sizeof(CMD_REMOVE_STA_RECORD_T), /* u4SetQueryInfoLen */ -+ (PUINT_8) &rCmdContent, /* pucInfoBuffer */ -+ NULL, /* pvSetQueryBuffer */ -+ 0 /* u4SetQueryBufferLen */ -+ ); -+ -+ ASSERT(rStatus == WLAN_STATUS_PENDING); -+} -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/cnm_timer.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/cnm_timer.c -new file mode 100644 -index 000000000000..8cc9ef9078fe ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/cnm_timer.c -@@ -0,0 +1,482 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/cnm_timer.c#1 -+*/ -+ -+/*! \file "cnm_timer.c" -+ \brief -+ -+*/ -+ -+/* -+** Log: cnm_timer.c -+ * -+ * 12 13 2011 cm.chang -+ * [WCXRP00001136] [All Wi-Fi][Driver] Add wake lock for pending timer -+ * Add wake lock if timer timeout value is smaller than 5 seconds -+ * -+ * 02 24 2011 cp.wu -+ * [WCXRP00000490] [MT6620 Wi-Fi][Driver][Win32] modify kalMsleep() implementation -+ * because NdisMSleep() won't sleep long enough for specified interval such as 500ms -+ * modify cnm_timer and hem_mbox APIs to be thread safe to ease invoking restrictions -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 08 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * cnm_timer has been migrated. -+ * -+ * 05 28 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Support sleep notification to host -+ * -+ * 05 19 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Add some checking assertions -+ * -+ * 04 24 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Return timer token back to COS when entering wait off state -+ * -+ * 01 11 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Remove compiling warning -+ * -+ * 01 08 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Support longer timeout interval to 45 days from 65secu1rwduu`wvpghlqg|fh+fmdkb -+ * -+ * 01 06 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Fix system time is 32KHz instead of 1ms -+ * -+ * 01 04 2010 tehuang.liu -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * For working out the first connection Chariot-verified version -+ * -+ * Dec 3 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Place rRootTimer.rNextExpiredSysTime = rExpiredSysTime; before set timer -+ * -+ * Oct 30 2009 mtk01104 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * In cnmTimerInitialize(), just stop timer if it was already created. -+ * -+ * Oct 30 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Move the external reference for Lint to precomp.h -+ * -+ * Oct 30 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Fix lint warning -+ * -+ * Oct 28 2009 mtk01104 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * -+** -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "precomp.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to set the time to do the time out check. -+* -+* \param[in] rTimeout Time out interval from current time. -+* -+* \retval TRUE Success. -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static BOOLEAN cnmTimerSetTimer(IN P_ADAPTER_T prAdapter, IN OS_SYSTIME rTimeout) -+{ -+ P_ROOT_TIMER prRootTimer; -+ BOOLEAN fgNeedWakeLock; -+ -+ ASSERT(prAdapter); -+ -+ prRootTimer = &prAdapter->rRootTimer; -+ -+ kalSetTimer(prAdapter->prGlueInfo, rTimeout); -+ -+ if (rTimeout <= SEC_TO_SYSTIME(WAKE_LOCK_MAX_TIME)) { -+ fgNeedWakeLock = TRUE; -+ -+ if (!prRootTimer->fgWakeLocked) { -+ KAL_WAKE_LOCK(prAdapter, &prRootTimer->rWakeLock); -+ prRootTimer->fgWakeLocked = TRUE; -+ } -+ } else { -+ fgNeedWakeLock = FALSE; -+ } -+ -+ return fgNeedWakeLock; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routines is called to initialize a root timer. -+* -+* \param[in] prAdapter -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID cnmTimerInitialize(IN P_ADAPTER_T prAdapter) -+{ -+ P_ROOT_TIMER prRootTimer; -+ -+ KAL_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(prAdapter); -+ -+ prRootTimer = &prAdapter->rRootTimer; -+ -+ /* Note: glue layer have configured timer */ -+ -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TIMER); -+ LINK_INITIALIZE(&prRootTimer->rLinkHead); -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TIMER); -+ -+ KAL_WAKE_LOCK_INIT(prAdapter, &prRootTimer->rWakeLock, "WLAN Timer"); -+ prRootTimer->fgWakeLocked = FALSE; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routines is called to destroy a root timer. -+* When WIFI is off, the token shall be returned back to system. -+* -+* \param[in] -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID cnmTimerDestroy(IN P_ADAPTER_T prAdapter) -+{ -+ P_ROOT_TIMER prRootTimer; -+ -+ KAL_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(prAdapter); -+ -+ prRootTimer = &prAdapter->rRootTimer; -+ -+ if (prRootTimer->fgWakeLocked) { -+ KAL_WAKE_UNLOCK(prAdapter, &prRootTimer->rWakeLock); -+ prRootTimer->fgWakeLocked = FALSE; -+ } -+ KAL_WAKE_LOCK_DESTROY(prAdapter, &prRootTimer->rWakeLock); -+ -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TIMER); -+ LINK_INITIALIZE(&prRootTimer->rLinkHead); -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TIMER); -+ -+ /* Note: glue layer will be responsible for timer destruction */ -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routines is called to initialize a timer. -+* -+* \param[in] prTimer Pointer to a timer structure. -+* \param[in] pfnFunc Pointer to the call back function. -+* \param[in] u4Data Parameter for call back function. -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID cnmTimerInitTimer(IN P_ADAPTER_T prAdapter, IN P_TIMER_T prTimer, IN PFN_MGMT_TIMEOUT_FUNC pfFunc, IN ULONG ulData) -+{ -+ ASSERT(prAdapter); -+ -+ ASSERT(prTimer); -+ -+#if DBG -+ /* Note: NULL function pointer is permitted for HEM POWER */ -+ if (pfFunc == NULL) -+ DBGLOG(CNM, WARN, "Init timer with NULL callback function!\n"); -+#endif -+ -+#if DBG -+ ASSERT(prAdapter->rRootTimer.rLinkHead.prNext); -+ { -+ P_LINK_T prTimerList; -+ P_LINK_ENTRY_T prLinkEntry; -+ P_TIMER_T prPendingTimer; -+ -+ prTimerList = &(prAdapter->rRootTimer.rLinkHead); -+ -+ LINK_FOR_EACH(prLinkEntry, prTimerList) { -+ prPendingTimer = LINK_ENTRY(prLinkEntry, TIMER_T, rLinkEntry); -+ ASSERT(prPendingTimer); -+ ASSERT(prPendingTimer != prTimer); -+ } -+ } -+#endif -+ -+ LINK_ENTRY_INITIALIZE(&prTimer->rLinkEntry); -+ -+ prTimer->pfMgmtTimeOutFunc = pfFunc; -+ prTimer->ulData = ulData; -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routines is called to stop a timer. -+* -+* \param[in] prTimer Pointer to a timer structure. -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+static VOID cnmTimerStopTimer_impl(IN P_ADAPTER_T prAdapter, IN P_TIMER_T prTimer, IN BOOLEAN fgAcquireSpinlock) -+{ -+ P_ROOT_TIMER prRootTimer; -+ -+ KAL_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(prAdapter); -+ ASSERT(prTimer); -+ -+ prRootTimer = &prAdapter->rRootTimer; -+ -+ if (fgAcquireSpinlock) -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TIMER); -+ -+ if (timerPendingTimer(prTimer)) { -+ LINK_REMOVE_KNOWN_ENTRY(&prRootTimer->rLinkHead, &prTimer->rLinkEntry); -+ -+ /* Reduce dummy timeout for power saving, especially HIF activity. -+ * If two or more timers exist and being removed timer is smallest, -+ * this dummy timeout will still happen, but it is OK. -+ */ -+ if (LINK_IS_EMPTY(&prRootTimer->rLinkHead)) { -+ kalCancelTimer(prAdapter->prGlueInfo); -+ -+ if (fgAcquireSpinlock && prRootTimer->fgWakeLocked) { -+ KAL_WAKE_UNLOCK(prAdapter, &prRootTimer->rWakeLock); -+ prRootTimer->fgWakeLocked = FALSE; -+ } -+ } -+ } -+ -+ if (fgAcquireSpinlock) -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TIMER); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routines is called to stop a timer. -+* -+* \param[in] prTimer Pointer to a timer structure. -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID cnmTimerStopTimer(IN P_ADAPTER_T prAdapter, IN P_TIMER_T prTimer) -+{ -+ ASSERT(prAdapter); -+ ASSERT(prTimer); -+ -+ cnmTimerStopTimer_impl(prAdapter, prTimer, TRUE); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routines is called to start a timer with wake_lock. -+* -+* \param[in] prTimer Pointer to a timer structure. -+* \param[in] u4TimeoutMs Timeout to issue the timer and call back function -+* (unit: ms). -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID cnmTimerStartTimer(IN P_ADAPTER_T prAdapter, IN P_TIMER_T prTimer, IN UINT_32 u4TimeoutMs) -+{ -+ P_ROOT_TIMER prRootTimer; -+ P_LINK_T prTimerList; -+ OS_SYSTIME rExpiredSysTime, rTimeoutSystime; -+ -+ KAL_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(prAdapter); -+ ASSERT(prTimer); -+ -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TIMER); -+ -+ prRootTimer = &prAdapter->rRootTimer; -+ prTimerList = &prRootTimer->rLinkHead; -+ -+ /* If timeout interval is larger than 1 minute, the mod value is set -+ * to the timeout value first, then per minutue. -+ */ -+ if (u4TimeoutMs > MSEC_PER_MIN) { -+ ASSERT(u4TimeoutMs <= ((UINT_32) 0xFFFF * MSEC_PER_MIN)); -+ -+ prTimer->u2Minutes = (UINT_16) (u4TimeoutMs / MSEC_PER_MIN); -+ u4TimeoutMs -= (prTimer->u2Minutes * MSEC_PER_MIN); -+ if (u4TimeoutMs == 0) { -+ u4TimeoutMs = MSEC_PER_MIN; -+ prTimer->u2Minutes--; -+ } -+ } else { -+ prTimer->u2Minutes = 0; -+ } -+ -+ /* The assertion check if MSEC_TO_SYSTIME() may be overflow. */ -+ ASSERT(u4TimeoutMs < (((UINT_32) 0x80000000 - MSEC_PER_SEC) / KAL_HZ)); -+ rTimeoutSystime = MSEC_TO_SYSTIME(u4TimeoutMs); -+ rExpiredSysTime = kalGetTimeTick() + rTimeoutSystime; -+ -+ /* If no timer pending or the fast time interval is used. */ -+ if (LINK_IS_EMPTY(prTimerList) || TIME_BEFORE(rExpiredSysTime, prRootTimer->rNextExpiredSysTime)) { -+ -+ prRootTimer->rNextExpiredSysTime = rExpiredSysTime; -+ cnmTimerSetTimer(prAdapter, rTimeoutSystime); -+ } -+ -+ /* Add this timer to checking list */ -+ prTimer->rExpiredSysTime = rExpiredSysTime; -+ -+ if (!timerPendingTimer(prTimer)) -+ LINK_INSERT_TAIL(prTimerList, &prTimer->rLinkEntry); -+ -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TIMER); -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routines is called to check the timer list. -+* -+* \param[in] -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID cnmTimerDoTimeOutCheck(IN P_ADAPTER_T prAdapter) -+{ -+ P_ROOT_TIMER prRootTimer; -+ P_LINK_T prTimerList; -+ P_LINK_ENTRY_T prLinkEntry; -+ P_TIMER_T prTimer; -+ OS_SYSTIME rCurSysTime; -+ PFN_MGMT_TIMEOUT_FUNC pfMgmtTimeOutFunc; -+ ULONG ulTimeoutData; -+ BOOLEAN fgNeedWakeLock; -+ -+ KAL_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(prAdapter); -+ -+ /* acquire spin lock */ -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TIMER); -+ -+ prRootTimer = &prAdapter->rRootTimer; -+ prTimerList = &prRootTimer->rLinkHead; -+ -+ rCurSysTime = kalGetTimeTick(); -+ -+ /* Set the permitted max timeout value for new one */ -+ prRootTimer->rNextExpiredSysTime = rCurSysTime + MGMT_MAX_TIMEOUT_INTERVAL; -+ -+ LINK_FOR_EACH(prLinkEntry, prTimerList) { -+ prTimer = LINK_ENTRY(prLinkEntry, TIMER_T, rLinkEntry); -+ ASSERT(prTimer); -+ -+ /* Check if this entry is timeout. */ -+ if (!TIME_BEFORE(rCurSysTime, prTimer->rExpiredSysTime)) { -+ cnmTimerStopTimer_impl(prAdapter, prTimer, FALSE); -+ -+ pfMgmtTimeOutFunc = prTimer->pfMgmtTimeOutFunc; -+ ulTimeoutData = prTimer->ulData; -+ -+ if (prTimer->u2Minutes > 0) { -+ prTimer->u2Minutes--; -+ prTimer->rExpiredSysTime = rCurSysTime + MSEC_TO_SYSTIME(MSEC_PER_MIN); -+ LINK_INSERT_TAIL(prTimerList, &prTimer->rLinkEntry); -+ } else if (pfMgmtTimeOutFunc) { -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TIMER); -+ (pfMgmtTimeOutFunc) (prAdapter, ulTimeoutData); -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TIMER); -+ } -+ -+ /* Search entire list again because of nest del and add timers -+ * and current MGMT_TIMER could be volatile after stopped -+ */ -+ prLinkEntry = (P_LINK_ENTRY_T) prTimerList; -+ -+ prRootTimer->rNextExpiredSysTime = rCurSysTime + MGMT_MAX_TIMEOUT_INTERVAL; -+ } else if (TIME_BEFORE(prTimer->rExpiredSysTime, prRootTimer->rNextExpiredSysTime)) { -+ prRootTimer->rNextExpiredSysTime = prTimer->rExpiredSysTime; -+ } -+ } /* end of for loop */ -+ -+ /* Setup the prNext timeout event. It is possible the timer was already -+ * set in the above timeout callback function. -+ */ -+ fgNeedWakeLock = FALSE; -+ if (!LINK_IS_EMPTY(prTimerList)) { -+ ASSERT(TIME_AFTER(prRootTimer->rNextExpiredSysTime, rCurSysTime)); -+ -+ fgNeedWakeLock = cnmTimerSetTimer(prAdapter, (OS_SYSTIME) -+ ((INT_32) prRootTimer->rNextExpiredSysTime - (INT_32) rCurSysTime)); -+ } -+ -+ if (prRootTimer->fgWakeLocked && !fgNeedWakeLock) { -+ KAL_WAKE_UNLOCK(prAdapter, &prRootTimer->rWakeLock); -+ prRootTimer->fgWakeLocked = FALSE; -+ } -+ -+ /* release spin lock */ -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TIMER); -+} -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/hem_mbox.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/hem_mbox.c -new file mode 100644 -index 000000000000..c7a23eb018b6 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/hem_mbox.c -@@ -0,0 +1,816 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/hem_mbox.c#3 -+*/ -+ -+/*! \file "hem_mbox.c" -+ \brief -+ -+*/ -+ -+/* -+** Log: hem_mbox.c -+** -+** 08 31 2012 yuche.tsai -+** [ALPS00349585] [6577JB][WiFi direct][KE]Establish p2p connection while both device -+** have connected to AP previously,one device reboots automatically with KE -+** Fix possible KE when concurrent & disconnect. -+** -+** 07 26 2012 yuche.tsai -+** [ALPS00324337] [ALPS.JB][Hot-Spot] Driver update for Hot-Spot -+** Update driver code of ALPS.JB for hot-spot. -+** -+** 07 19 2012 yuche.tsai -+** NULL -+** Code update for JB. -+ * -+ * 07 17 2012 yuche.tsai -+ * NULL -+ * Compile no error before trial run. -+ * -+ * 05 03 2012 cp.wu -+ * [WCXRP00001231] [MT6620 Wi-Fi][MT5931][Driver] Correct SCAN_V2 related debugging facilities within hem_mbox.c -+ * correct for debug message string table by adding missed scan_v2 related definitions. -+ * -+ * 03 02 2012 terry.wu -+ * NULL -+ * Sync CFG80211 modification from branch 2,2. -+ * -+ * 01 17 2012 yuche.tsai -+ * NULL -+ * Update mgmt frame filter setting. -+ * Please also update FW 2.1 -+ * -+ * 01 13 2012 yuche.tsai -+ * NULL -+ * WiFi Hot Spot Tethering for ICS ALPHA testing version. -+ * -+ * 11 24 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * Adjust code for DBG and CONFIG_XLOG. -+ * -+ * 11 15 2011 cm.chang -+ * NULL -+ * Add exception handle for NULL function pointer of mailbox message -+ * -+ * 11 11 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * modify the xlog related code. -+ * -+ * 11 02 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * adding the code for XLOG. -+ * -+ * 07 18 2011 cp.wu -+ * [WCXRP00000858] [MT5931][Driver][Firmware] Add support for scan to search -+ * for more than one SSID in a single scanning request -+ * add framework in driver domain for supporting new SCAN_REQ_V2 for more than 1 SSID support -+ * as well as uProbeDelay in NDIS 6.x driver model -+ * -+ * 06 07 2011 yuche.tsai -+ * [WCXRP00000696] [Volunteer Patch][MT6620][Driver] Infinite loop issue when RX invitation response. -+ * [WCXRP00000763] [Volunteer Patch][MT6620][Driver] RX Service Discovery Frame under AP mode Issue -+ * Add invitation support. -+ * -+ * 04 18 2011 terry.wu -+ * [WCXRP00000660] [MT6620 Wi-Fi][Driver] Remove flag CFG_WIFI_DIRECT_MOVED -+ * Remove flag CFG_WIFI_DIRECT_MOVED. -+ * -+ * 03 29 2011 cm.chang -+ * [WCXRP00000606] [MT6620 Wi-Fi][Driver][FW] Fix klocwork warning -+ * As CR title -+ * -+ * 02 24 2011 cp.wu -+ * [WCXRP00000490] [MT6620 Wi-Fi][Driver][Win32] modify kalMsleep() implementation -+ * because NdisMSleep() won't sleep long enough for specified interval such as 500ms -+ * modify cnm_timer and hem_mbox APIs to be thread safe to ease invoking restrictions -+ * -+ * 02 15 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Update bowString and channel grant. -+ * -+ * 01 26 2011 cm.chang -+ * [WCXRP00000395] [MT6620 Wi-Fi][Driver][FW] Search STA_REC with additional net type index argument -+ * Allocate system RAM if fixed message or mgmt buffer is not available -+ * -+ * 01 26 2011 yuche.tsai -+ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record. -+ * . -+ * -+ * 01 25 2011 yuche.tsai -+ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record. -+ * Fix Compile Error when DBG is disabled. -+ * -+ * 01 24 2011 cp.wu -+ * [WCXRP00000382] [MT6620 Wi-Fi][Driver] Track forwarding packet number with notifying tx thread for serving -+ * 1. add an extra counter for tracking pending forward frames. -+ * 2. notify TX service thread as well when there is pending forward frame -+ * 3. correct build errors leaded by introduction of Wi-Fi direct separation module -+ * -+ * 12 08 2010 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Support concurrent networks. -+ * -+ * 11 08 2010 cm.chang -+ * [WCXRP00000169] [MT6620 Wi-Fi][Driver][FW] Remove unused CNM recover message ID -+ * Remove CNM channel reover message ID -+ * -+ * 11 01 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000150] [MT6620 Wi-Fi][Driver] -+ * Add implementation for querying current TX rate from firmware auto rate module -+ * 1) Query link speed (TX rate) from firmware directly with buffering mechanism to reduce overhead -+ * 2) Remove CNM CH-RECOVER event handling -+ * 3) cfg read/write API renamed with kal prefix for unified naming rules. -+ * -+ * 10 08 2010 wh.su -+ * [WCXRP00000085] [MT6620 Wif-Fi] [Driver] update the modified p2p state machine -+ * update the frog's new p2p state machine. -+ * -+ * 09 28 2010 wh.su -+ * NULL -+ * [WCXRP00000069][MT6620 Wi-Fi][Driver] Fix some code for phase 1 P2P Demo. -+ * -+ * 09 16 2010 cm.chang -+ * NULL -+ * Remove unused message ID -+ * -+ * 08 30 2010 cp.wu -+ * NULL -+ * eliminate klockwork errors -+ * -+ * 08 26 2010 yuche.tsai -+ * NULL -+ * Add P2P Connection Abort Event Message handler. -+ * -+ * 08 25 2010 george.huang -+ * NULL -+ * update OID/ registry control path for PM related settings -+ * -+ * 08 24 2010 yarco.yang -+ * NULL -+ * Fixed Driver ASSERT at mboxInitMsgMap() -+ * -+ * 08 24 2010 chinghwa.yu -+ * NULL -+ * Update for MID_SCN_BOW_SCAN_DONE mboxDummy. -+ * Update saa_fsm for BOW. -+ * -+ * 08 23 2010 chinghwa.yu -+ * NULL -+ * Add CFG_ENABLE_BT_OVER_WIFI. -+ * -+ * 08 23 2010 chinghwa.yu -+ * NULL -+ * Update for BOW. -+ * -+ * 08 16 2010 cp.wu -+ * NULL -+ * add interface for RLM to trigger OBSS-SCAN. -+ * -+ * 08 16 2010 yuche.tsai -+ * NULL -+ * Add debug message for newly add P2P message. -+ * -+ * 08 11 2010 yuche.tsai -+ * NULL -+ * Add some function entry for P2P FSM under provisioning phase.. -+ * -+ * 08 11 2010 yuche.tsai -+ * NULL -+ * Add some events to P2P Module. -+ * -+ * 08 05 2010 yuche.tsai -+ * NULL -+ * Add message box event for P2P device switch on & device discovery. -+ * -+ * 08 04 2010 cp.wu -+ * NULL -+ * remove unused mailbox message definitions. -+ * -+ * 08 02 2010 yuche.tsai -+ * NULL -+ * P2P Group Negotiation Code Check in. -+ * -+ * 07 19 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration. -+ * message table should not be commented out by compilation option without modifying header file -+ * -+ * 07 19 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration. -+ * Add Ad-Hoc support to AIS-FSM -+ * -+ * 07 19 2010 yuche.tsai -+ * -+ * Add wifi direct scan done callback. -+ * -+ * 07 09 2010 cp.wu -+ * -+ * change handler of MID_MNY_CNM_CONNECTION_ABORT from NULL to mboxDummy. -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 07 08 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Rename MID_MNY_CNM_CH_RELEASE to MID_MNY_CNM_CH_ABORT -+ * -+ * 07 01 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * AIS-FSM integration with CNM channel request messages -+ * -+ * 07 01 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * implementation of DRV-SCN and related mailbox message handling. -+ * -+ * 07 01 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Modify CNM message handler for new flow -+ * -+ * 06 15 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * enable currently migrated message call-backs. -+ * -+ * 06 14 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * restore utility function invoking via hem_mbox to direct calls -+ * -+ * 06 10 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add buildable & linkable ais_fsm.c -+ * -+ * related reference are still waiting to be resolved -+ * -+ * 06 08 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * hem_mbox is migrated. -+ * -+ * 06 08 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add hem_mbox.c and cnm_mem.h (but disabled some feature) for further migration -+ * -+ * 05 12 2010 kevin.huang -+ * [BORA00000794][WIFISYS][New Feature]Power Management Support -+ * Fix file merge error -+ * -+ * 05 12 2010 kevin.huang -+ * [BORA00000794][WIFISYS][New Feature]Power Management Support -+ * Add Power Management - Legacy PS-POLL support. -+ * -+ * 04 29 2010 tehuang.liu -+ * [BORA00000605][WIFISYS] Phase3 Integration -+ * Removed MID_RXM_MQM_QOS_ACTION_FRAME -+ * -+ * 04 29 2010 tehuang.liu -+ * [BORA00000605][WIFISYS] Phase3 Integration -+ * Removed MID_RXM_MQM_BA_ACTION_FRAME -+ * -+ * 04 27 2010 tehuang.liu -+ * [BORA00000605][WIFISYS] Phase3 Integration -+ * MID_RXM_MQM_BA_ACTION_FRAME -+ * -+ * 03 30 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Support 2.4G OBSS scan -+ * -+ * 03 16 2010 kevin.huang -+ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support -+ * Add AdHoc Mode -+ * -+ * 03 10 2010 kevin.huang -+ * [BORA00000654][WIFISYS][New Feature] CNM Module - Ch Manager Support -+ * -+ * * * * * * * * * * * * * * Add Channel Manager for arbitration of JOIN and SCAN Req -+ * -+ * 03 05 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Develop partial DPD code -+ * -+ * 02 11 2010 tehuang.liu -+ * [BORA00000569][WIFISYS] Phase 2 Integration Test -+ * Updated arMsgMapTable for MID_RXM_MQM_QOS_ACTION_FRAME -+ * -+ * 01 11 2010 kevin.huang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Add Deauth and Disassoc Handler -+ * -+ * Dec 9 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Add hemRunEventScanDone() to arMsgMapTable[] -+ * -+ * Dec 4 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Fix mboxDummy() didn't free prMsgHdr -+ * -+ * Dec 3 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Add saaAisJoinComplete event handler -+ * -+ * Dec 2 2009 MTK02468 -+ * [BORA00000337] To check in codes for FPGA emulation -+ * Fixed the handler function name in arMsgMapTable for MID_RXM_MQM_BA_ACTION_FRAME -+ * -+ * Dec 2 2009 MTK02468 -+ * [BORA00000337] To check in codes for FPGA emulation -+ * Added MID_RXM_MQM_BA_ACTION_FRAME to MsgMapTable -+ * -+ * Nov 23 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Revise MSG Handler (remove dummy and add for SAA) -+ * -+ * Nov 16 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Add aisFsmRunEventAbort() event handler -+ * -+ * Nov 11 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Fix typo -+ * -+ * Nov 10 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Add more MSG_HNDL_ENTRY_T to avoid ASSERT() in mboxInitMsgMap() -+ * -+ * Nov 5 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Add SCN message and function entry to arMsgMapTable[] -+ * -+ * Nov 2 2009 mtk01104 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Fix sorting algorithm in mboxInitMsgMap() -+ * -+ * Oct 28 2009 mtk01104 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * -+** -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "precomp.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+#if DBG -+/*lint -save -e64 Type mismatch */ -+static PUINT_8 apucDebugMsg[] = { -+ (PUINT_8) DISP_STRING("MID_MNY_CNM_CH_REQ"), -+ (PUINT_8) DISP_STRING("MID_MNY_CNM_CH_ABORT"), -+ (PUINT_8) DISP_STRING("MID_CNM_AIS_CH_GRANT"), -+ (PUINT_8) DISP_STRING("MID_CNM_P2P_CH_GRANT"), -+ (PUINT_8) DISP_STRING("MID_CNM_BOW_CH_GRANT"), -+ -+ (PUINT_8) DISP_STRING("MID_AIS_SCN_SCAN_REQ"), -+ (PUINT_8) DISP_STRING("MID_AIS_SCN_SCAN_REQ_V2"), -+ (PUINT_8) DISP_STRING("MID_AIS_SCN_SCAN_CANCEL"), -+ (PUINT_8) DISP_STRING("MID_P2P_SCN_SCAN_REQ"), -+ (PUINT_8) DISP_STRING("MID_P2P_SCN_SCAN_REQ_V2"), -+ (PUINT_8) DISP_STRING("MID_P2P_SCN_SCAN_CANCEL"), -+ (PUINT_8) DISP_STRING("MID_BOW_SCN_SCAN_REQ"), -+ (PUINT_8) DISP_STRING("MID_BOW_SCN_SCAN_REQ_V2"), -+ (PUINT_8) DISP_STRING("MID_BOW_SCN_SCAN_CANCEL"), -+ (PUINT_8) DISP_STRING("MID_RLM_SCN_SCAN_REQ"), -+ (PUINT_8) DISP_STRING("MID_RLM_SCN_SCAN_REQ_V2"), -+ (PUINT_8) DISP_STRING("MID_RLM_SCN_SCAN_CANCEL"), -+ (PUINT_8) DISP_STRING("MID_SCN_AIS_SCAN_DONE"), -+ (PUINT_8) DISP_STRING("MID_SCN_P2P_SCAN_DONE"), -+ (PUINT_8) DISP_STRING("MID_SCN_BOW_SCAN_DONE"), -+ (PUINT_8) DISP_STRING("MID_SCN_RLM_SCAN_DONE"), -+ -+ (PUINT_8) DISP_STRING("MID_OID_AIS_FSM_JOIN_REQ"), -+ (PUINT_8) DISP_STRING("MID_OID_AIS_FSM_ABORT"), -+ (PUINT_8) DISP_STRING("MID_AIS_SAA_FSM_START"), -+ (PUINT_8) DISP_STRING("MID_AIS_SAA_FSM_ABORT"), -+ (PUINT_8) DISP_STRING("MID_SAA_AIS_JOIN_COMPLETE"), -+ -+#if CFG_ENABLE_BT_OVER_WIFI -+ (PUINT_8) DISP_STRING("MID_BOW_SAA_FSM_START"), -+ (PUINT_8) DISP_STRING("MID_BOW_SAA_FSM_ABORT"), -+ (PUINT_8) DISP_STRING("MID_SAA_BOW_JOIN_COMPLETE"), -+#endif -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ (PUINT_8) DISP_STRING("MID_P2P_SAA_FSM_START"), -+ (PUINT_8) DISP_STRING("MID_P2P_SAA_FSM_ABORT"), -+ (PUINT_8) DISP_STRING("MID_SAA_P2P_JOIN_COMPLETE"), -+ -+ (PUINT_8) DISP_STRING("MID_MNY_P2P_FUN_SWITCH"), -+ (PUINT_8) DISP_STRING("MID_MNY_P2P_DEVICE_DISCOVERY"), -+ (PUINT_8) DISP_STRING("MID_MNY_P2P_CONNECTION_REQ"), -+ (PUINT_8) DISP_STRING("MID_MNY_P2P_CONNECTION_ABORT"), -+ (PUINT_8) DISP_STRING("MID_MNY_P2P_BEACON_UPDATE"), -+ (PUINT_8) DISP_STRING("MID_MNY_P2P_STOP_AP"), -+ (PUINT_8) DISP_STRING("MID_MNY_P2P_CHNL_REQ"), -+ (PUINT_8) DISP_STRING("MID_MNY_P2P_CHNL_ABORT"), -+ (PUINT_8) DISP_STRING("MID_MNY_P2P_MGMT_TX"), -+ (PUINT_8) DISP_STRING("MID_MNY_P2P_GROUP_DISSOLVE"), -+ (PUINT_8) DISP_STRING("MID_MNY_P2P_MGMT_FRAME_REGISTER"), -+ (PUINT_8) DISP_STRING("MID_MNY_P2P_NET_DEV_REGISTER"), -+ (PUINT_8) DISP_STRING("MID_MNY_P2P_START_AP"), -+ (PUINT_8) DISP_STRING("MID_MNY_P2P_UPDATE_IE_BUF"), -+#endif -+ -+#if CFG_SUPPORT_ADHOC -+ /* (PUINT_8)DISP_STRING("MID_AIS_CNM_CREATE_IBSS_REQ"), */ -+ /* (PUINT_8)DISP_STRING("MID_CNM_AIS_CREATE_IBSS_GRANT"), */ -+ /* (PUINT_8)DISP_STRING("MID_AIS_CNM_MERGE_IBSS_REQ"), */ -+ /* (PUINT_8)DISP_STRING("MID_CNM_AIS_MERGE_IBSS_GRANT"), */ -+ (PUINT_8) DISP_STRING("MID_SCN_AIS_FOUND_IBSS"), -+#endif /* CFG_SUPPORT_ADHOC */ -+ -+ (PUINT_8) DISP_STRING("MID_SAA_AIS_FSM_ABORT"), -+ (PUINT_8) DISP_STRING("MID_MNY_AIS_REMAIN_ON_CHANNEL"), -+ (PUINT_8) DISP_STRING("MID_MNY_AIS_CANCEL_REMAIN_ON_CHANNEL"), -+ (PUINT_8) DISP_STRING("MID_MNY_AIS_MGMT_TX") -+}; -+ -+/*lint -restore */ -+#endif /* DBG */ -+ -+/* This message entry will be re-ordered based on the message ID order -+ * by invoking mboxInitMsgMap() -+ */ -+static MSG_HNDL_ENTRY_T arMsgMapTable[] = { -+ {MID_MNY_CNM_CH_REQ, cnmChMngrRequestPrivilege}, -+ {MID_MNY_CNM_CH_ABORT, cnmChMngrAbortPrivilege}, -+ {MID_CNM_AIS_CH_GRANT, aisFsmRunEventChGrant}, -+#if CFG_ENABLE_WIFI_DIRECT -+ {MID_CNM_P2P_CH_GRANT, p2pFsmRunEventChGrant}, /*set in gl_p2p_init.c */ -+#else -+ {MID_CNM_P2P_CH_GRANT, mboxDummy}, -+#endif -+ -+#if CFG_ENABLE_BT_OVER_WIFI -+ {MID_CNM_BOW_CH_GRANT, bowRunEventChGrant}, -+#else -+ {MID_CNM_BOW_CH_GRANT, mboxDummy}, -+#endif -+ -+ /*--------------------------------------------------*/ -+ /* SCN Module Mailbox Messages */ -+ /*--------------------------------------------------*/ -+ {MID_AIS_SCN_SCAN_REQ, scnFsmMsgStart}, -+ {MID_AIS_SCN_SCAN_REQ_V2, scnFsmMsgStart}, -+ {MID_AIS_SCN_SCAN_CANCEL, scnFsmMsgAbort}, -+ {MID_P2P_SCN_SCAN_REQ, scnFsmMsgStart}, -+ {MID_P2P_SCN_SCAN_REQ_V2, scnFsmMsgStart}, -+ {MID_P2P_SCN_SCAN_CANCEL, scnFsmMsgAbort}, -+ {MID_BOW_SCN_SCAN_REQ, scnFsmMsgStart}, -+ {MID_BOW_SCN_SCAN_REQ_V2, scnFsmMsgStart}, -+ {MID_BOW_SCN_SCAN_CANCEL, scnFsmMsgAbort}, -+ {MID_RLM_SCN_SCAN_REQ, scnFsmMsgStart}, -+ {MID_RLM_SCN_SCAN_REQ_V2, scnFsmMsgStart}, -+ {MID_RLM_SCN_SCAN_CANCEL, scnFsmMsgAbort}, -+ {MID_SCN_AIS_SCAN_DONE, aisFsmRunEventScanDone}, -+#if CFG_ENABLE_WIFI_DIRECT -+ {MID_SCN_P2P_SCAN_DONE, p2pFsmRunEventScanDone}, /*set in gl_p2p_init.c */ -+#else -+ {MID_SCN_P2P_SCAN_DONE, mboxDummy}, -+#endif -+ -+#if CFG_ENABLE_BT_OVER_WIFI -+ {MID_SCN_BOW_SCAN_DONE, bowResponderScanDone}, -+#else -+ {MID_SCN_BOW_SCAN_DONE, mboxDummy}, -+#endif -+ {MID_SCN_RLM_SCAN_DONE, rlmObssScanDone}, -+ -+ /*--------------------------------------------------*/ -+ /* AIS Module Mailbox Messages */ -+ /*--------------------------------------------------*/ -+ {MID_OID_AIS_FSM_JOIN_REQ, aisFsmRunEventAbort}, -+ {MID_OID_AIS_FSM_ABORT, aisFsmRunEventAbort}, -+ {MID_AIS_SAA_FSM_START, saaFsmRunEventStart}, -+ {MID_AIS_SAA_FSM_ABORT, saaFsmRunEventAbort}, -+ {MID_SAA_AIS_JOIN_COMPLETE, aisFsmRunEventJoinComplete}, -+ -+#if CFG_ENABLE_BT_OVER_WIFI -+ /*--------------------------------------------------*/ -+ /* BOW Module Mailbox Messages */ -+ /*--------------------------------------------------*/ -+ {MID_BOW_SAA_FSM_START, saaFsmRunEventStart}, -+ {MID_BOW_SAA_FSM_ABORT, saaFsmRunEventAbort}, -+ {MID_SAA_BOW_JOIN_COMPLETE, bowFsmRunEventJoinComplete}, -+#endif -+ -+#if CFG_ENABLE_WIFI_DIRECT /*set in gl_p2p_init.c */ -+ {MID_P2P_SAA_FSM_START, saaFsmRunEventStart}, -+ {MID_P2P_SAA_FSM_ABORT, saaFsmRunEventAbort}, -+ {MID_SAA_P2P_JOIN_COMPLETE, p2pFsmRunEventJoinComplete}, /* TODO: p2pFsmRunEventJoinComplete */ -+ -+ {MID_MNY_P2P_FUN_SWITCH, p2pFsmRunEventSwitchOPMode}, -+ {MID_MNY_P2P_DEVICE_DISCOVERY, p2pFsmRunEventScanRequest}, -+ {MID_MNY_P2P_CONNECTION_REQ, p2pFsmRunEventConnectionRequest}, -+ {MID_MNY_P2P_CONNECTION_ABORT, p2pFsmRunEventConnectionAbort}, -+ {MID_MNY_P2P_BEACON_UPDATE, p2pFsmRunEventBeaconUpdate}, -+ {MID_MNY_P2P_STOP_AP, p2pFsmRunEventStopAP}, -+ {MID_MNY_P2P_CHNL_REQ, p2pFsmRunEventChannelRequest}, -+ {MID_MNY_P2P_CHNL_ABORT, p2pFsmRunEventChannelAbort}, -+ {MID_MNY_P2P_MGMT_TX, p2pFsmRunEventMgmtFrameTx}, -+ {MID_MNY_P2P_GROUP_DISSOLVE, p2pFsmRunEventDissolve}, -+ {MID_MNY_P2P_MGMT_FRAME_REGISTER, p2pFsmRunEventMgmtFrameRegister}, -+ {MID_MNY_P2P_NET_DEV_REGISTER, p2pFsmRunEventNetDeviceRegister}, -+ {MID_MNY_P2P_START_AP, p2pFsmRunEventStartAP}, -+ {MID_MNY_P2P_MGMT_FRAME_UPDATE, p2pFsmRunEventUpdateMgmtFrame}, -+ {MID_MNY_P2P_EXTEND_LISTEN_INTERVAL, p2pFsmRunEventExtendListen}, -+#if CFG_SUPPORT_WFD -+ {MID_MNY_P2P_WFD_CFG_UPDATE, p2pFsmRunEventWfdSettingUpdate}, -+#endif -+ -+#endif -+ -+#if CFG_SUPPORT_ADHOC -+ {MID_SCN_AIS_FOUND_IBSS, aisFsmRunEventFoundIBSSPeer}, -+#endif /* CFG_SUPPORT_ADHOC */ -+ -+ {MID_SAA_AIS_FSM_ABORT, aisFsmRunEventAbort}, -+ {MID_MNY_AIS_REMAIN_ON_CHANNEL, aisFsmRunEventRemainOnChannel}, -+ {MID_MNY_AIS_CANCEL_REMAIN_ON_CHANNEL, aisFsmRunEventCancelRemainOnChannel}, -+ {MID_MNY_AIS_MGMT_TX, aisFsmRunEventMgmtFrameTx} -+}; -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+#if DBG -+#define MBOX_HNDL_MSG(prAdapter, prMsg) do { \ -+ ASSERT(arMsgMapTable[prMsg->eMsgId].pfMsgHndl); \ -+ if (arMsgMapTable[prMsg->eMsgId].pfMsgHndl) { \ -+ DBGLOG(CNM, LOUD, "DO MSG [%d: %s]\n", prMsg->eMsgId, apucDebugMsg[prMsg->eMsgId]); \ -+ arMsgMapTable[prMsg->eMsgId].pfMsgHndl(prAdapter, prMsg); \ -+ } \ -+ else { \ -+ DBGLOG(CNM, ERROR, "NULL fptr for MSG [%d]\n", prMsg->eMsgId); \ -+ cnmMemFree(prAdapter, prMsg); \ -+ } \ -+} while (0) -+#else -+#define MBOX_HNDL_MSG(prAdapter, prMsg) do { \ -+ ASSERT(arMsgMapTable[prMsg->eMsgId].pfMsgHndl); \ -+ if (arMsgMapTable[prMsg->eMsgId].pfMsgHndl) { \ -+ DBGLOG(CNM, LOUD, "DO MSG [%d]\n", prMsg->eMsgId); \ -+ arMsgMapTable[prMsg->eMsgId].pfMsgHndl(prAdapter, prMsg); \ -+ } \ -+ else { \ -+ DBGLOG(CNM, ERROR, "NULL fptr for MSG [%d]\n", prMsg->eMsgId); \ -+ cnmMemFree(prAdapter, prMsg); \ -+ } \ -+} while (0) -+#endif -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID mboxInitMsgMap(VOID) -+{ -+ UINT_32 i, idx; -+ MSG_HNDL_ENTRY_T rTempEntry; -+ -+ ASSERT((sizeof(arMsgMapTable) / sizeof(MSG_HNDL_ENTRY_T)) == MID_TOTAL_NUM); -+ -+ for (i = 0; i < MID_TOTAL_NUM; i++) { -+ if (arMsgMapTable[i].eMsgId == (ENUM_MSG_ID_T) i) -+ continue; -+ for (idx = i + 1; idx < MID_TOTAL_NUM; idx++) { -+ if (arMsgMapTable[idx].eMsgId == (ENUM_MSG_ID_T) i) -+ break; -+ } -+ ASSERT(idx < MID_TOTAL_NUM); -+ if (idx >= MID_TOTAL_NUM) -+ continue; -+ -+ /* Swap target entry and current entry */ -+ rTempEntry.eMsgId = arMsgMapTable[idx].eMsgId; -+ rTempEntry.pfMsgHndl = arMsgMapTable[idx].pfMsgHndl; -+ -+ arMsgMapTable[idx].eMsgId = arMsgMapTable[i].eMsgId; -+ arMsgMapTable[idx].pfMsgHndl = arMsgMapTable[i].pfMsgHndl; -+ -+ arMsgMapTable[i].eMsgId = rTempEntry.eMsgId; -+ arMsgMapTable[i].pfMsgHndl = rTempEntry.pfMsgHndl; -+ } -+ -+ /* Verify the correctness of final message map */ -+ for (i = 0; i < MID_TOTAL_NUM; i++) { -+ ASSERT(arMsgMapTable[i].eMsgId == (ENUM_MSG_ID_T) i); -+ while (arMsgMapTable[i].eMsgId != (ENUM_MSG_ID_T) i) -+ ; -+ } -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID mboxSetup(IN P_ADAPTER_T prAdapter, IN ENUM_MBOX_ID_T eMboxId) -+{ -+ P_MBOX_T prMbox; -+ -+ KAL_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(eMboxId < MBOX_ID_TOTAL_NUM); -+ ASSERT(prAdapter); -+ -+ prMbox = &(prAdapter->arMbox[eMboxId]); -+ -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_MAILBOX); -+ LINK_INITIALIZE(&prMbox->rLinkHead); -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_MAILBOX); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+mboxSendMsg(IN P_ADAPTER_T prAdapter, -+ IN ENUM_MBOX_ID_T eMboxId, IN P_MSG_HDR_T prMsg, IN EUNM_MSG_SEND_METHOD_T eMethod) -+{ -+ P_MBOX_T prMbox; -+ -+ KAL_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(eMboxId < MBOX_ID_TOTAL_NUM); -+ ASSERT(prMsg); -+ ASSERT(prAdapter); -+ -+ prMbox = &(prAdapter->arMbox[eMboxId]); -+ -+ switch (eMethod) { -+ case MSG_SEND_METHOD_BUF: -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_MAILBOX); -+ LINK_INSERT_TAIL(&prMbox->rLinkHead, &prMsg->rLinkEntry); -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_MAILBOX); -+ -+ /* to wake up main service thread */ -+ GLUE_SET_EVENT(prAdapter->prGlueInfo); -+ -+ break; -+ -+ case MSG_SEND_METHOD_UNBUF: -+ MBOX_HNDL_MSG(prAdapter, prMsg); -+ break; -+ -+ default: -+ ASSERT(0); -+ break; -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID mboxRcvAllMsg(IN P_ADAPTER_T prAdapter, ENUM_MBOX_ID_T eMboxId) -+{ -+ P_MBOX_T prMbox; -+ P_MSG_HDR_T prMsg; -+ -+ KAL_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(eMboxId < MBOX_ID_TOTAL_NUM); -+ ASSERT(prAdapter); -+ -+ prMbox = &(prAdapter->arMbox[eMboxId]); -+ -+ while (!LINK_IS_EMPTY(&prMbox->rLinkHead)) { -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_MAILBOX); -+ LINK_REMOVE_HEAD(&prMbox->rLinkHead, prMsg, P_MSG_HDR_T); -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_MAILBOX); -+ -+ ASSERT(prMsg); -+ MBOX_HNDL_MSG(prAdapter, prMsg); -+ } -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID mboxInitialize(IN P_ADAPTER_T prAdapter) -+{ -+ UINT_32 i; -+ -+ ASSERT(prAdapter); -+ -+ /* Initialize Mailbox */ -+ mboxInitMsgMap(); -+ -+ /* Setup/initialize each mailbox */ -+ for (i = 0; i < MBOX_ID_TOTAL_NUM; i++) -+ mboxSetup(prAdapter, i); -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID mboxDestroy(IN P_ADAPTER_T prAdapter) -+{ -+ P_MBOX_T prMbox; -+ P_MSG_HDR_T prMsg; -+ UINT_8 i; -+ -+ KAL_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(prAdapter); -+ -+ for (i = 0; i < MBOX_ID_TOTAL_NUM; i++) { -+ prMbox = &(prAdapter->arMbox[i]); -+ -+ while (!LINK_IS_EMPTY(&prMbox->rLinkHead)) { -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_MAILBOX); -+ LINK_REMOVE_HEAD(&prMbox->rLinkHead, prMsg, P_MSG_HDR_T); -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_MAILBOX); -+ -+ ASSERT(prMsg); -+ cnmMemFree(prAdapter, prMsg); -+ } -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This is dummy function to prevent empty arMsgMapTable[] for compiling. -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID mboxDummy(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) -+{ -+ ASSERT(prAdapter); -+ -+ cnmMemFree(prAdapter, prMsgHdr); -+ -+} -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/hs20.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/hs20.c -new file mode 100644 -index 000000000000..7fb71a199ccf ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/hs20.c -@@ -0,0 +1,498 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/HS2_DEV_SW/MT6620_WIFI_DRIVER_V2_1_HS_2_0/mgmt/hs20.c#2 -+*/ -+ -+/*! \file "hs20.c" -+ \brief This file including the hotspot 2.0 related function. -+ -+ This file provided the macros and functions library support for the -+ protocol layer hotspot 2.0 related function. -+ -+*/ -+ -+/* -+** Log: hs20.c -+ * -+ */ -+ -+ /******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "precomp.h" -+ -+#if CFG_SUPPORT_HOTSPOT_2_0 -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is called to generate Interworking IE for Probe Rsp, Bcn, Assoc Req/Rsp. -+* -+* \param[in] prAdapter Pointer of ADAPTER_T -+* \param[out] prMsduInfo Pointer of the Msdu Info -+* -+* \return VOID -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID hs20GenerateInterworkingIE(IN P_ADAPTER_T prAdapter, OUT P_MSDU_INFO_T prMsduInfo) -+{ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is called to generate Roaming Consortium IE for Probe Rsp, Bcn, Assoc Req/Rsp. -+* -+* \param[in] prAdapter Pointer of ADAPTER_T -+* \param[out] prMsduInfo Pointer of the Msdu Info -+* -+* \return VOID -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID hs20GenerateRoamingConsortiumIE(IN P_ADAPTER_T prAdapter, OUT P_MSDU_INFO_T prMsduInfo) -+{ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is called to generate HS2.0 IE for Probe Rsp, Bcn, Assoc Req/Rsp. -+* -+* \param[in] prAdapter Pointer of ADAPTER_T -+* \param[out] prMsduInfo Pointer of the Msdu Info -+* -+* \return VOID -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID hs20GenerateHS20IE(IN P_ADAPTER_T prAdapter, OUT P_MSDU_INFO_T prMsduInfo) -+{ -+ PUINT_8 pucBuffer; -+ -+ ASSERT(prAdapter); -+ ASSERT(prMsduInfo); -+ -+ if (prMsduInfo->ucNetworkType != NETWORK_TYPE_AIS_INDEX) -+ return; -+ -+ pucBuffer = (PUINT_8) ((ULONG) prMsduInfo->prPacket + (UINT_32) prMsduInfo->u2FrameLength); -+ -+ /* ASSOC INFO IE ID: 221 :0xDD */ -+ if (prAdapter->prGlueInfo->u2HS20AssocInfoIELen) { -+ kalMemCopy(pucBuffer, &prAdapter->prGlueInfo->aucHS20AssocInfoIE, -+ prAdapter->prGlueInfo->u2HS20AssocInfoIELen); -+ prMsduInfo->u2FrameLength += prAdapter->prGlueInfo->u2HS20AssocInfoIELen; -+ } -+ -+} -+ -+VOID hs20FillExtCapIE(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo, P_MSDU_INFO_T prMsduInfo) -+{ -+ P_HS20_EXT_CAP_T prExtCap; -+ -+ ASSERT(prAdapter); -+ ASSERT(prMsduInfo); -+ -+ /* Add Extended Capabilities IE */ -+ prExtCap = (P_HS20_EXT_CAP_T) -+ (((PUINT_8) prMsduInfo->prPacket) + prMsduInfo->u2FrameLength); -+ -+ prExtCap->ucId = ELEM_ID_EXTENDED_CAP; -+ if (prAdapter->prGlueInfo->fgConnectHS20AP == TRUE) -+ prExtCap->ucLength = ELEM_MAX_LEN_EXT_CAP; -+ else -+ prExtCap->ucLength = 3 - ELEM_HDR_LEN; -+ -+ kalMemZero(prExtCap->aucCapabilities, prExtCap->ucLength); -+ -+ prExtCap->aucCapabilities[0] = ELEM_EXT_CAP_DEFAULT_VAL; -+ -+ if (prBssInfo->eCurrentOPMode != OP_MODE_INFRASTRUCTURE) -+ prExtCap->aucCapabilities[0] &= ~ELEM_EXT_CAP_PSMP_CAP; -+ -+ if (prAdapter->prGlueInfo->fgConnectHS20AP == TRUE) { -+ SET_EXT_CAP(prExtCap->aucCapabilities, ELEM_MAX_LEN_EXT_CAP, ELEM_EXT_CAP_BSS_TRANSITION_BIT); -+ SET_EXT_CAP(prExtCap->aucCapabilities, ELEM_MAX_LEN_EXT_CAP, ELEM_EXT_CAP_UTC_TSF_OFFSET_BIT); -+ SET_EXT_CAP(prExtCap->aucCapabilities, ELEM_MAX_LEN_EXT_CAP, ELEM_EXT_CAP_INTERWORKING_BIT); -+ -+ /* For R2 WNM-Notification */ -+ SET_EXT_CAP(prExtCap->aucCapabilities, ELEM_MAX_LEN_EXT_CAP, ELEM_EXT_CAP_WNM_NOTIFICATION_BIT); -+ } -+ kalPrint("IE_SIZE(prExtCap) = %d, %d %d\n", IE_SIZE(prExtCap), ELEM_HDR_LEN, ELEM_MAX_LEN_EXT_CAP); -+ ASSERT(IE_SIZE(prExtCap) <= (ELEM_HDR_LEN + ELEM_MAX_LEN_EXT_CAP)); -+ -+ prMsduInfo->u2FrameLength += IE_SIZE(prExtCap); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is called to fill up the content of Ext Cap IE bit 31. -+* -+* \param[in] prAdapter Pointer of ADAPTER_T -+* \param[out] pucIE Pointer of the IE buffer -+* -+* \return VOID -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID hs20FillProreqExtCapIE(IN P_ADAPTER_T prAdapter, OUT PUINT_8 pucIE) -+{ -+ P_HS20_EXT_CAP_T prExtCap; -+ -+ ASSERT(prAdapter); -+ -+ /* Add Extended Capabilities IE */ -+ prExtCap = (P_HS20_EXT_CAP_T) pucIE; -+ -+ prExtCap->ucId = ELEM_ID_EXTENDED_CAP; -+ if (prAdapter->prGlueInfo->fgConnectHS20AP == TRUE) -+ prExtCap->ucLength = ELEM_MAX_LEN_EXT_CAP; -+ else -+ prExtCap->ucLength = 3 - ELEM_HDR_LEN; -+ -+ kalMemZero(prExtCap->aucCapabilities, prExtCap->ucLength); -+ -+ prExtCap->aucCapabilities[0] = ELEM_EXT_CAP_DEFAULT_VAL; -+ -+ if (prAdapter->prGlueInfo->fgConnectHS20AP == TRUE) { -+ SET_EXT_CAP(prExtCap->aucCapabilities, ELEM_MAX_LEN_EXT_CAP, ELEM_EXT_CAP_BSS_TRANSITION_BIT); -+ SET_EXT_CAP(prExtCap->aucCapabilities, ELEM_MAX_LEN_EXT_CAP, ELEM_EXT_CAP_UTC_TSF_OFFSET_BIT); -+ SET_EXT_CAP(prExtCap->aucCapabilities, ELEM_MAX_LEN_EXT_CAP, ELEM_EXT_CAP_INTERWORKING_BIT); -+ -+ /* For R2 WNM-Notification */ -+ SET_EXT_CAP(prExtCap->aucCapabilities, ELEM_MAX_LEN_EXT_CAP, ELEM_EXT_CAP_WNM_NOTIFICATION_BIT); -+ } -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is called to fill up the content of HS2.0 IE. -+* -+* \param[in] prAdapter Pointer of ADAPTER_T -+* \param[out] pucIE Pointer of the IE buffer -+* -+* \return VOID -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID hs20FillHS20IE(IN P_ADAPTER_T prAdapter, OUT PUINT_8 pucIE) -+{ -+ P_IE_HS20_INDICATION_T prHS20IndicationIe; -+ /* P_HS20_INFO_T prHS20Info; */ -+ UINT_8 aucWfaOui[] = VENDOR_OUI_WFA_SPECIFIC; -+ -+ /* prHS20Info = &(prAdapter->rWifiVar.rHS20Info); */ -+ -+ prHS20IndicationIe = (P_IE_HS20_INDICATION_T) pucIE; -+ -+ prHS20IndicationIe->ucId = ELEM_ID_VENDOR; -+ prHS20IndicationIe->ucLength = sizeof(IE_HS20_INDICATION_T) - ELEM_HDR_LEN; -+ prHS20IndicationIe->aucOui[0] = aucWfaOui[0]; -+ prHS20IndicationIe->aucOui[1] = aucWfaOui[1]; -+ prHS20IndicationIe->aucOui[2] = aucWfaOui[2]; -+ prHS20IndicationIe->ucType = VENDOR_OUI_TYPE_HS20; -+ prHS20IndicationIe->ucHotspotConfig = 0x00; /* prHS20Info->ucHotspotConfig; */ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is called while calculating length of hotspot 2.0 indication IE for Probe Request. -+* -+* \param[in] prAdapter Pointer of ADAPTER_T -+* \param[in] pucTargetBSSID Pointer of target HESSID -+* -+* \return the length of composed HS20 IE -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT_32 hs20CalculateHS20RelatedIEForProbeReq(IN P_ADAPTER_T prAdapter, IN PUINT_8 pucTargetBSSID) -+{ -+ UINT_32 u4IeLength; -+ -+ if (0) /* Todo:: Not HS20 STA */ -+ return 0; -+ -+ u4IeLength = -+ sizeof(IE_HS20_INDICATION_T) + /* sizeof(IE_INTERWORKING_T) */ + (ELEM_HDR_LEN + ELEM_MAX_LEN_EXT_CAP); -+ -+ if (!pucTargetBSSID) { -+ /* Do nothing */ -+ /* u4IeLength -= MAC_ADDR_LEN; */ -+ } -+ -+ return u4IeLength; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is called while composing hotspot 2.0 indication IE for Probe Request. -+* -+* \param[in] prAdapter Pointer of ADAPTER_T -+* \param[in] pucTargetBSSID Pointer of target HESSID -+* \param[out] prIE Pointer of the IE buffer -+* -+* \return the wlan status -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS hs20GenerateHS20RelatedIEForProbeReq(IN P_ADAPTER_T prAdapter, IN PUINT_8 pucTargetBSSID, OUT PUINT_8 prIE) -+{ -+ if (0) /* Todo:: Not HS20 STA */ -+ return 0; -+#if 0 -+ P_HS20_INFO_T prHS20Info; -+ -+ prHS20Info = &(prAdapter->rWifiVar.rHS20Info); -+ -+ /* -+ * Generate 802.11u Interworking IE (107) -+ */ -+ hs20FillInterworkingIE(prAdapter, -+ prHS20Info->ucAccessNetworkOptions, -+ prHS20Info->ucVenueGroup, prHS20Info->ucVenueType, pucTargetBSSID, prIE); -+ prIE += IE_SIZE(prIE); -+#endif -+ /* -+ * Generate Ext Cap IE (127) -+ */ -+ hs20FillProreqExtCapIE(prAdapter, prIE); -+ prIE += IE_SIZE(prIE); -+ -+ /* -+ * Generate HS2.0 Indication IE (221) -+ */ -+ hs20FillHS20IE(prAdapter, prIE); -+ prIE += IE_SIZE(prIE); -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+BOOLEAN hs20IsGratuitousArp(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prCurrSwRfb) -+{ -+ PUINT_8 pucSenderIP = prCurrSwRfb->pvHeader + ETHER_HEADER_LEN + ARP_SENDER_IP_OFFSET; -+ PUINT_8 pucTargetIP = prCurrSwRfb->pvHeader + ETHER_HEADER_LEN + ARP_TARGET_IP_OFFSET; -+ PUINT_8 pucSenderMac = ((PUINT_8) prCurrSwRfb->pvHeader + ETHER_HEADER_LEN + ARP_SNEDER_MAC_OFFSET); -+#if CFG_HS20_DEBUG && 0 -+/* UINT_8 aucIpAllZero[4] = {0,0,0,0}; */ -+/* UINT_8 aucMACAllZero[MAC_ADDR_LEN] = {0,0,0,0,0,0}; */ -+ PUINT_8 pucTargetMac = ((PUINT_8) prCurrSwRfb->pvHeader + ETHER_HEADER_LEN + ARP_TARGET_MAC_OFFSET); -+#endif -+ -+#if CFG_HS20_DEBUG && 0 -+ PUINT_16 pu2ArpOper = (PUINT_16) ((PUINT_8) prCurrSwRfb->pvHeader + ETHER_HEADER_LEN + ARP_OPERATION_OFFSET); -+ -+ kalPrint("Recv ARP 0x%04X\n", htons(*pu2ArpOper)); -+ kalPrint("SENDER[ %pM ] [%pI4]\n", pucSenderMac, pucSenderIP); -+ kalPrint("TARGET[ %pM ] [%pI4]\n", pucTargetMac, pucTargetIP); -+#endif -+ -+ /* IsGratuitousArp */ -+ if (!kalMemCmp(pucSenderIP, pucTargetIP, 4)) { -+ kalPrint("Drop Gratuitous ARP from [ %pM ] [%pI4]\n", pucSenderMac, pucTargetIP); -+ return TRUE; -+ } -+ return FALSE; -+} -+ -+BOOLEAN hs20IsUnsolicitedNeighborAdv(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prCurrSwRfb) -+{ -+ PUINT_8 pucIpv6Protocol = ((PUINT_8) prCurrSwRfb->pvHeader + ETHER_HEADER_LEN + IPV6_HDR_IP_PROTOCOL_OFFSET); -+ -+ /* kalPrint("pucIpv6Protocol [%02X:%02X]\n", *pucIpv6Protocol, IPV6_PROTOCOL_ICMPV6); */ -+ if (*pucIpv6Protocol == IPV6_PROTOCOL_ICMPV6) { -+ PUINT_8 pucICMPv6Type = -+ ((PUINT_8) prCurrSwRfb->pvHeader + ETHER_HEADER_LEN + IPV6_HDR_LEN + ICMPV6_TYPE_OFFSET); -+ /* kalPrint("pucICMPv6Type [%02X:%02X]\n", *pucICMPv6Type, ICMPV6_TYPE_NEIGHBOR_ADVERTISEMENT); */ -+ if (*pucICMPv6Type == ICMPV6_TYPE_NEIGHBOR_ADVERTISEMENT) { -+ PUINT_8 pucICMPv6Flag = -+ ((PUINT_8) prCurrSwRfb->pvHeader + ETHER_HEADER_LEN + IPV6_HDR_LEN + ICMPV6_FLAG_OFFSET); -+ PUINT_8 pucSrcMAC = ((PUINT_8) prCurrSwRfb->pvHeader + MAC_ADDR_LEN); -+ -+#if CFG_HS20_DEBUG -+ kalPrint("NAdv Flag [%02X] [R(%d)\\S(%d)\\O(%d)]\n", -+ *pucICMPv6Flag, -+ (UINT_8) (*pucICMPv6Flag & ICMPV6_FLAG_ROUTER_BIT) >> 7, -+ (UINT_8) (*pucICMPv6Flag & ICMPV6_FLAG_SOLICITED_BIT) >> 6, -+ (UINT_8) (*pucICMPv6Flag & ICMPV6_FLAG_OVERWRITE_BIT) >> 5); -+#endif -+ if (!(*pucICMPv6Flag & ICMPV6_FLAG_SOLICITED_BIT)) { -+ kalPrint("Drop Unsolicited Neighbor Advertisement from [%pM]\n", pucSrcMAC); -+ return TRUE; -+ } -+ } -+ } -+ -+ return FALSE; -+} -+ -+#if CFG_ENABLE_GTK_FRAME_FILTER -+BOOLEAN hs20IsForgedGTKFrame(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prBssInfo, IN P_SW_RFB_T prCurrSwRfb) -+{ -+ /* -+ P_CONNECTION_SETTINGS_T prConnSettings = &prAdapter->rWifiVar.rConnSettings; -+ PUINT_8 pucEthDestAddr = prCurrSwRfb->pvHeader; -+ */ -+ /* 3 TODO: Need to verify this function before enable it */ -+ return FALSE; -+ /* -+ if ((prConnSettings->eEncStatus != ENUM_ENCRYPTION_DISABLED) && IS_BMCAST_MAC_ADDR(pucEthDestAddr)) { -+ UINT_8 ucIdx = 0; -+ PUINT_32 prIpAddr, prPacketDA; -+ PUINT_16 pu2PktIpVer = -+ (PUINT_16) ((PUINT_8) prCurrSwRfb->pvHeader + (ETHER_HEADER_LEN - ETHER_TYPE_LEN)); -+ -+ if (*pu2PktIpVer == htons(ETH_P_IPV4)) { -+ if (!prBssInfo->prIpV4NetAddrList) -+ return FALSE; -+ for (ucIdx = 0; ucIdx < prBssInfo->prIpV4NetAddrList->ucAddrCount; ucIdx++) { -+ prIpAddr = (PUINT_32) &prBssInfo->prIpV4NetAddrList->arNetAddr[ucIdx].aucIpAddr[0]; -+ prPacketDA = -+ (PUINT_32) ((PUINT_8) prCurrSwRfb->pvHeader + ETHER_HEADER_LEN + -+ IPV4_HDR_IP_DST_ADDR_OFFSET); -+ -+ if (kalMemCmp(prIpAddr, prPacketDA, 4) == 0) { -+ kalPrint("Drop FORGED IPv4 packet\n"); -+ return TRUE; -+ } -+ } -+ } -+#ifdef CONFIG_IPV6 -+ else if (*pu2PktIpVer == htons(ETH_P_IPV6)) { -+ UINT_8 aucIPv6Mac[MAC_ADDR_LEN]; -+ PUINT_8 pucIdx = -+ prCurrSwRfb->pvHeader + ETHER_HEADER_LEN + IPV6_HDR_IP_DST_ADDR_MAC_HIGH_OFFSET; -+ -+ kalMemCopy(&aucIPv6Mac[0], pucIdx, 3); -+ pucIdx += 5; -+ kalMemCopy(&aucIPv6Mac[3], pucIdx, 3); -+ kalPrint("Get IPv6 frame Dst IP MAC part %pM\n", aucIPv6Mac); -+ if (EQUAL_MAC_ADDR(aucIPv6Mac, prBssInfo->aucOwnMacAddr)) { -+ kalPrint("Drop FORGED IPv6 packet\n"); -+ return TRUE; -+ } -+ } -+#endif -+ } -+ -+ return FALSE; -+ */ -+} -+#endif -+ -+BOOLEAN hs20IsUnsecuredFrame(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prBssInfo, IN P_SW_RFB_T prCurrSwRfb) -+{ -+ PUINT_16 pu2PktIpVer = (PUINT_16) ((PUINT_8) prCurrSwRfb->pvHeader + (ETHER_HEADER_LEN - ETHER_TYPE_LEN)); -+ -+ /* kalPrint("IPVER 0x%4X\n", htons(*pu2PktIpVer)); */ -+#if CFG_HS20_DEBUG & 0 -+ UINT_8 i = 0; -+ -+ kalPrint("==============================================="); -+ for (i = 0; i < 96; i++) { -+ if (!(i % 16)) -+ kalPrint("\n"); -+ kalPrint("%02X ", *((PUINT_8) prCurrSwRfb->pvHeader + i)); -+ } -+ kalPrint("\n"); -+#endif -+ -+#if CFG_ENABLE_GTK_FRAME_FILTER -+ if (hs20IsForgedGTKFrame(prAdapter, prBssInfo, prCurrSwRfb)) -+ return TRUE; -+ -+#endif -+ if (*pu2PktIpVer == htons(ETH_P_ARP)) -+ return hs20IsGratuitousArp(prAdapter, prCurrSwRfb); -+ else if (*pu2PktIpVer == htons(ETH_P_IPV6)) -+ return hs20IsUnsolicitedNeighborAdv(prAdapter, prCurrSwRfb); -+ -+ return FALSE; -+} -+ -+BOOLEAN hs20IsFrameFilterEnabled(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prBssInfo) -+{ -+#if 1 -+ if (prAdapter->prGlueInfo->fgConnectHS20AP) -+ return TRUE; -+#else -+ PARAM_SSID_T rParamSsid; -+ P_BSS_DESC_T prBssDesc; -+ -+ rParamSsid.u4SsidLen = prBssInfo->ucSSIDLen; -+ COPY_SSID(rParamSsid.aucSsid, rParamSsid.u4SsidLen, prBssInfo->aucSSID, prBssInfo->ucSSIDLen); -+ -+ prBssDesc = scanSearchBssDescByBssidAndSsid(prAdapter, prBssInfo->aucBSSID, TRUE, &rParamSsid); -+ if (!prBssDesc) -+ return FALSE; -+ -+ if (prBssDesc->fgIsSupportHS20) { -+ if (!(prBssDesc->ucHotspotConfig & ELEM_HS_CONFIG_DGAF_DISABLED_MASK)) -+ return TRUE; -+ -+ /* Disable frame filter only if DGAF == 1 */ -+ return FALSE; -+ -+ } -+#endif -+ -+ /* For Now, always return true to run hs20 check even for legacy AP */ -+ return TRUE; -+} -+ -+WLAN_STATUS hs20SetBssidPool(IN P_ADAPTER_T prAdapter, IN PVOID pvBuffer, IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIdx) -+{ -+ P_PARAM_HS20_SET_BSSID_POOL prParamBssidPool = (P_PARAM_HS20_SET_BSSID_POOL) pvBuffer; -+ P_HS20_INFO_T prHS20Info; -+ UINT_8 ucIdx; -+ -+ prHS20Info = &(prAdapter->rWifiVar.rHS20Info); -+ kalPrint("[%s]Set Bssid Pool! enable[%d] num[%d]\n", __func__, prParamBssidPool->fgIsEnable, -+ prParamBssidPool->ucNumBssidPool); -+ for (ucIdx = 0; ucIdx < prParamBssidPool->ucNumBssidPool; ucIdx++) { -+ COPY_MAC_ADDR(prHS20Info->arBssidPool[ucIdx].aucBSSID, &prParamBssidPool->arBSSID[ucIdx]); -+ kalPrint("[%s][%d][ %pM ]\n", __func__, ucIdx, (prHS20Info->arBssidPool[ucIdx].aucBSSID)); -+ } -+ prHS20Info->fgIsHS2SigmaMode = prParamBssidPool->fgIsEnable; -+ prHS20Info->ucNumBssidPoolEntry = prParamBssidPool->ucNumBssidPool; -+ -+#if 0 -+ wlanClearScanningResult(prAdapter); -+#endif -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+#endif -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/mib.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/mib.c -new file mode 100644 -index 000000000000..469a48ebe9c1 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/mib.c -@@ -0,0 +1,111 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/mib.c#1 -+*/ -+ -+/*! \file "mib.c" -+ \brief This file includes the mib default vale and functions. -+*/ -+ -+/* -+** Log: mib.c -+ * -+ * 09 03 2010 kevin.huang -+ * NULL -+ * Refine #include sequence and solve recursive/nested #include issue -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 07 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add mib.c. -+ * -+ * 02 04 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Add AAA Module Support, Revise Net Type to Net Type Index for array lookup -+ * -+ * Nov 23 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "precomp.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+NON_HT_PHY_ATTRIBUTE_T rNonHTPhyAttributes[] = { -+ {RATE_SET_HR_DSSS, TRUE, FALSE} -+ , /* For PHY_TYPE_HR_DSSS_INDEX(0) */ -+ {RATE_SET_ERP, TRUE, TRUE} -+ , /* For PHY_TYPE_ERP_INDEX(1) */ -+ {RATE_SET_ERP_P2P, TRUE, TRUE} -+ , /* For PHY_TYPE_ERP_P2P_INDEX(2) */ -+ {RATE_SET_OFDM, FALSE, FALSE} -+ , /* For PHY_TYPE_OFDM_INDEX(3) */ -+}; -+ -+NON_HT_ADHOC_MODE_ATTRIBUTE_T rNonHTAdHocModeAttributes[AD_HOC_MODE_NUM] = { -+ {PHY_TYPE_HR_DSSS_INDEX, BASIC_RATE_SET_HR_DSSS} -+ , /* For AD_HOC_MODE_11B(0) */ -+ {PHY_TYPE_ERP_INDEX, BASIC_RATE_SET_HR_DSSS_ERP} -+ , /* For AD_HOC_MODE_MIXED_11BG(1) */ -+ {PHY_TYPE_ERP_INDEX, BASIC_RATE_SET_ERP} -+ , /* For AD_HOC_MODE_11G(2) */ -+ {PHY_TYPE_OFDM_INDEX, BASIC_RATE_SET_OFDM} -+ , /* For AD_HOC_MODE_11A(3) */ -+}; -+ -+NON_HT_AP_MODE_ATTRIBUTE_T rNonHTApModeAttributes[AP_MODE_NUM] = { -+ {PHY_TYPE_HR_DSSS_INDEX, BASIC_RATE_SET_HR_DSSS} -+ , /* For AP_MODE_11B(0) */ -+ {PHY_TYPE_ERP_INDEX, BASIC_RATE_SET_HR_DSSS_ERP} -+ , /* For AP_MODE_MIXED_11BG(1) */ -+ {PHY_TYPE_ERP_INDEX, BASIC_RATE_SET_ERP} -+ , /* For AP_MODE_11G(2) */ -+ {PHY_TYPE_ERP_P2P_INDEX, BASIC_RATE_SET_ERP_P2P} -+ , /* For AP_MODE_11G_P2P(3) */ -+ {PHY_TYPE_OFDM_INDEX, BASIC_RATE_SET_OFDM} -+ , /* For AP_MODE_11A(4) */ -+}; -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_assoc.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_assoc.c -new file mode 100644 -index 000000000000..cb5fbebedd49 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_assoc.c -@@ -0,0 +1,87 @@ -+/* -+** Id: @(#) p2p_assoc.c@@ -+*/ -+ -+/*! \file "p2p_assoc.c" -+ \brief This file includes the Wi-Fi Direct association-related functions. -+ -+ This file includes the association-related functions. -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+#include "precomp.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is used to compose Common Information Elements for P2P Association -+* Request Frame. -+* -+* @param[in] prMsduInfo Pointer to the composed MSDU_INFO_T. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+PUINT_8 p2pBuildReAssocReqFrameCommonIEs(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo, IN PUINT_8 pucBuffer) -+{ -+ P_P2P_CONNECTION_SETTINGS_T prP2pConnSettings = (P_P2P_CONNECTION_SETTINGS_T) NULL; -+ -+ prP2pConnSettings = prAdapter->rWifiVar.prP2PConnSettings; -+ -+ /* Fill the SSID element. */ -+ SSID_IE(pucBuffer)->ucId = ELEM_ID_SSID; -+ -+ /* NOTE(Kevin): We copy the SSID from CONNECTION_SETTINGS for the case of -+ * Passive Scan and the target BSS didn't broadcast SSID on its Beacon Frame. -+ */ -+ -+ COPY_SSID(SSID_IE(pucBuffer)->aucSSID, -+ SSID_IE(pucBuffer)->ucLength, prP2pConnSettings->aucSSID, prP2pConnSettings->ucSSIDLen); -+ -+ prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer); -+ pucBuffer += IE_SIZE(pucBuffer); -+ return pucBuffer; -+} -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_bss.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_bss.c -new file mode 100644 -index 000000000000..72a20a322cee ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_bss.c -@@ -0,0 +1,58 @@ -+/* -+** Id: @(#) p2p_bss.c@@ -+*/ -+ -+/*! \file "p2p_bss.c" -+ \brief This file contains the functions for creating p2p BSS(AP). -+ -+ This file contains the functions for BSS(AP). We may create a BSS -+ network, or merge with exist IBSS network and sending Beacon Frame or reply -+ the Probe Response Frame for received Probe Request Frame. -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+#include "precomp.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_fsm.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_fsm.c -new file mode 100644 -index 000000000000..f8c09e2aa9de ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_fsm.c -@@ -0,0 +1,3139 @@ -+/* -+** Id: //Department/DaVinci/TRUNK/WiFi_P2P_Driver/mgmt/p2p_fsm.c#61 -+*/ -+ -+/*! \file "p2p_fsm.c" -+ \brief This file defines the FSM for P2P Module. -+ -+ This file defines the FSM for P2P Module. -+*/ -+ -+/* -+** Log: p2p_fsm.c -+** -+** 12 20 2012 yuche.tsai -+** [ALPS00410124] [Rose][Free Test][KE][rlmUpdateParamsForAP]The device reboot automatically -+** and then "Fatal/Kernel" pops up during use data service.(Once) -+** Fix possible NULL station record cause KE under AP mode. -+** May due to variable uninitial. -+** Review: http://mtksap20:8080/go?page=NewReview&reviewid=49970 -+** -+** 09 12 2012 wcpadmin -+** [ALPS00276400] Remove MTK copyright and legal header on GPL/LGPL related packages -+** . -+** -+** 08 31 2012 yuche.tsai -+** [ALPS00349585] [6577JB][WiFi direct][KE]Establish p2p connection while both device have connected -+**to AP previously,one device reboots automatically with KE -+** Fix possible KE when concurrent & disconnect. -+** -+** 08 21 2012 yuche.tsai -+** NULL -+** fix disconnect indication. -+** -+** 08 16 2012 yuche.tsai -+** NULL -+** Fix compile warning. -+** -+** 08 14 2012 yuche.tsai -+** NULL -+** Fix p2p bug find on ALPS.JB trunk. -+** -+** 07 27 2012 yuche.tsai -+** [ALPS00324337] [ALPS.JB][Hot-Spot] Driver update for Hot-Spot -+** Update for driver unload KE issue. -+** -+** 07 26 2012 yuche.tsai -+** [ALPS00324337] [ALPS.JB][Hot-Spot] Driver update for Hot-Spot -+** Update driver code of ALPS.JB for hot-spot. -+** -+** 07 19 2012 yuche.tsai -+** NULL -+** Code update for JB. -+ * -+ * 07 17 2012 yuche.tsai -+ * NULL -+ * Compile no error before trial run. -+ * -+ * 07 05 2011 yuche.tsai -+ * [WCXRP00000821] [Volunteer Patch][WiFi Direct][Driver] WiFi Direct Connection Speed Issue -+ * Fix the compile flag of enhancement. -+ * -+ * 07 05 2011 yuche.tsai -+ * [WCXRP00000808] [Volunteer Patch][MT6620][Driver/FW] Device discoverability issue fix -+ * Change device discoverability methodology. From driver SCAN to FW lock channel. -+ * -+ * 07 05 2011 yuche.tsai -+ * [WCXRP00000821] [Volunteer Patch][WiFi Direct][Driver] WiFi Direct Connection Speed Issue -+ * Add wifi direct connection enhancement method I, II & VI. -+ * -+ * 07 05 2011 yuche.tsai -+ * [WCXRP00000833] [Volunteer Patch][WiFi Direct][Driver] Service Discovery Frame RX Indicate Issue -+ * Fix Service Discovery Race Condition Issue. -+ * -+ * 06 23 2011 cp.wu -+ * [WCXRP00000798] [MT6620 Wi-Fi][Firmware] Follow-ups for WAPI frequency offset workaround in firmware SCN module -+ * change parameter name from PeerAddr to BSSID -+ * -+ * 06 21 2011 yuche.tsai -+ * [WCXRP00000799] [Volunteer Patch][MT6620][Driver] Connection Indication Twice Issue. -+ * Fix an issue of accepting connection of GO. -+ * -+ * 06 21 2011 yuche.tsai -+ * [WCXRP00000775] [Volunteer Patch][MT6620][Driver] Dynamic enable SD capability -+ * Drop GAS frame when SD is not enabled. -+ * -+ * 06 20 2011 yuche.tsai -+ * NULL -+ * Fix compile error. -+ * -+ * 06 20 2011 yuche.tsai -+ * [WCXRP00000799] [Volunteer Patch][MT6620][Driver] Connection Indication Twice Issue. -+ * Fix connection indication twice issue. -+ * -+ * 06 20 2011 cp.wu -+ * [WCXRP00000798] [MT6620 Wi-Fi][Firmware] Follow-ups for WAPI frequency offset workaround in firmware SCN module -+ * 1. specify target's BSSID when requesting channel privilege. -+ * 2. pass BSSID information to firmware domain -+ * -+ * 06 20 2011 yuche.tsai -+ * [WCXRP00000795] [Volunteer Patch][MT6620][Driver] GO can not connect second device issue -+ * Solve P2P GO can not formation with second device issue. -+ * -+ * 06 14 2011 yuche.tsai -+ * NULL -+ * Change disconnect feature. -+ * -+ * 06 10 2011 yuche.tsai -+ * [WCXRP00000775] [Volunteer Patch][MT6620][Driver] Dynamic enable SD capability[WCXRP00000776] -+ * [Need Patch][MT6620][Driver] MT6620 response probe request of P2P device with P2P IE under Hot Spot mode. -+ * 1. Dynamic enable SD capability after P2P supplicant ready. -+ * 2. Avoid response probe respone with p2p IE when under hot spot mode. -+ * -+ * 06 07 2011 yuche.tsai -+ * [WCXRP00000763] [Volunteer Patch][MT6620][Driver] RX Service Discovery Frame under AP mode Issue -+ * Fix RX SD request under AP mode issue. -+ * -+ * 06 02 2011 cp.wu -+ * [WCXRP00000681] [MT5931][Firmware] HIF code size reduction -+ * eliminate unused parameters for SAA-FSM -+ * -+ * 05 26 2011 yuche.tsai -+ * [WCXRP00000745] Support accepting connection after one Group Connection Lost. -+ -+After Group Formation & lost connection, if MT6620 behave as: -+ -+1. GO: It would keep under GO state until been dissolved by supplicant. -+ -+ At this time, other P2P device can use join method to join this group. -+ -+2. GC: It would keep on searching target GO or target device until been dissolved by supplicant. -+ -+At this time, it would ignore other P2P device formation request. -+ -+-- -+ -+Modification: Make driver to accept GO NEGO REQ at this time, to let user decide to accept new connection or not. -+ -+ * [Volunteer Patch][MT6620][Driver] -+ * Driver would indicate connection request, if password ID is not ready but connection request is issued. -+ * -+ * 05 18 2011 yuche.tsai -+ * [WCXRP00000728] [Volunteer Patch][MT6620][Driver] Service Discovery Request TX issue. -+ * A solution for both connection request & IO control. -+ * -+ * 05 16 2011 yuche.tsai -+ * [WCXRP00000728] [Volunteer Patch][MT6620][Driver] Service Discovery Request TX issue. -+ * Fix SD request can not send out issue. -+ * -+ * 05 09 2011 terry.wu -+ * [WCXRP00000711] [MT6620 Wi-Fi][Driver] Set Initial value of StaType in StaRec for Hotspot Client -+ * Set initial value of StaType in StaRec for hotspot client. -+ * -+ * 05 04 2011 yuche.tsai -+ * [WCXRP00000697] [Volunteer Patch][MT6620][Driver] -+ * Bug fix for p2p descriptor is NULL if BSS descriptor is found first. -+ * -+ * 05 04 2011 yuche.tsai -+ * NULL -+ * Support partial persistent group function. -+ * -+ * 05 02 2011 yuche.tsai -+ * [WCXRP00000693] [Volunteer Patch][MT6620][Driver] Clear Formation Flag after TX lifetime timeout. -+ * Clear formation flag after formation timeout. -+ * -+ * 04 20 2011 yuche.tsai -+ * [WCXRP00000668] [Volunteer Patch][MT6620][Driver] Possible race condition -+ * when add scan & query scan result at the same time. -+ * Fix side effect while starting ATGO. -+ * -+ * 04 20 2011 yuche.tsai -+ * NULL -+ * Fix ASSERT issue in FW, side effect of last change. -+ * -+ * 04 19 2011 yuche.tsai -+ * [WCXRP00000668] [Volunteer Patch][MT6620][Driver] Possible race condition -+ * when add scan & query scan result at the same time. -+ * Workaround for multiple device connection, before invitation ready. -+ * -+ * 04 19 2011 yuche.tsai -+ * [WCXRP00000665] [Wifi Direct][MT6620 E4] When use Ralink's dongle to establish wifi direct connection with PBC. -+ * But 6573 always not pop accept option to establish connection. -+ * Support connection indication when GO NEGO REQ doesn't have configure method, instead it has PasswordID. -+ * -+ * 04 18 2011 yuche.tsai -+ * NULL -+ * Fix error. -+ * -+ * 04 14 2011 yuche.tsai -+ * [WCXRP00000646] [Volunteer Patch][MT6620][FW/Driver] Sigma Test Modification for some test case. -+ * Fix a connection issue. -+ * -+ * 04 14 2011 yuche.tsai -+ * [WCXRP00000646] [Volunteer Patch][MT6620][FW/Driver] Sigma Test Modification for some test case. -+ * Fix the channel issue of AP mode. -+ * -+ * 04 14 2011 yuche.tsai -+ * [WCXRP00000646] [Volunteer Patch][MT6620][FW/Driver] Sigma Test Modification for some test case. -+ * Connection flow refine for Sigma test. -+ * -+ * 04 09 2011 yuche.tsai -+ * [WCXRP00000624] [Volunteer Patch][MT6620][Driver] Add device discoverability support for GO. -+ * Fix Device discoverability related issue. -+ * -+ * 04 09 2011 yuche.tsai -+ * [WCXRP00000624] [Volunteer Patch][MT6620][Driver] Add device discoverability support for GO. -+ * Fix bug for Device Discoverability. -+ * -+ * 04 08 2011 yuche.tsai -+ * [WCXRP00000624] [Volunteer Patch][MT6620][Driver] Add device discoverability support for GO. -+ * Fix compile error. -+ * -+ * 04 08 2011 yuche.tsai -+ * [WCXRP00000624] [Volunteer Patch][MT6620][Driver] Add device discoverability support for GO. -+ * Add device discoverability support. -+ * -+ * 03 28 2011 yuche.tsai -+ * NULL -+ * Fix a possible issue for retry join when media status connected. -+ * -+ * 03 25 2011 yuche.tsai -+ * NULL -+ * Improve some error handleing. -+ * -+ * 03 24 2011 yuche.tsai -+ * NULL -+ * Assign AID before change STA_REC state to state 3. -+ * -+ * 03 23 2011 yuche.tsai -+ * NULL -+ * Fix Response Rate Issue when TX Auth Rsp Frame under P2P Mode. -+ * -+ * 03 23 2011 yuche.tsai -+ * NULL -+ * Fix issue of connection to one GC. -+ * -+ * 03 23 2011 yuche.tsai -+ * NULL -+ * Fix ASSERT issue when starting Hot-spot. -+ * -+ * 03 22 2011 yuche.tsai -+ * NULL -+ * When Target Information is not available, change to passive mode. -+ * -+ * 03 22 2011 yuche.tsai -+ * NULL -+ * Fix one connection issue while using Keypad to connect a GO. -+ * -+ * 03 22 2011 yuche.tsai -+ * NULL -+ * 1. Fix two issues that may cause kernel panic. -+ * -+ * 03 22 2011 yuche.tsai -+ * NULL -+ * Fix GC connect to other device issue. -+ * -+ * 03 22 2011 yuche.tsai -+ * NULL -+ * 1.Shorten the LISTEN interval. -+ * 2. Fix IF address issue when we are GO -+ * 3. Fix LISTEN channel issue. -+ * -+ * 03 22 2011 yuche.tsai -+ * NULL -+ * Modify formation policy setting. -+ * -+ * 03 21 2011 yuche.tsai -+ * NULL -+ * Solve Listen State doesn't response probe response issue. -+ * -+ * 03 21 2011 yuche.tsai -+ * NULL -+ * Change P2P Connection Request Flow. -+ * -+ * 03 19 2011 yuche.tsai -+ * [WCXRP00000584] [Volunteer Patch][MT6620][Driver] Add beacon timeout support for WiFi Direct. -+ * Add beacon timeout support. -+ * -+ * 03 19 2011 yuche.tsai -+ * [WCXRP00000583] [Volunteer Patch][MT6620][Driver] P2P connection of the third peer issue -+ * Indicate the correct Group SSID when join on Group. -+ * -+ * 03 19 2011 yuche.tsai -+ * [WCXRP00000583] [Volunteer Patch][MT6620][Driver] P2P connection of the third peer issue -+ * Support the third P2P device to join GO/GC group. -+ * -+ * 03 19 2011 yuche.tsai -+ * [WCXRP00000581] [Volunteer Patch][MT6620][Driver] P2P IE in Assoc Req Issue -+ * Append P2P IE in Assoc Req, so that GC can be discovered in probe response of GO. -+ * -+ * 03 18 2011 yuche.tsai -+ * [WCXRP00000578] [Volunteer Patch][MT6620][Driver] Separate Connection Request from general IOCTL -+ * Separate connection request from general IOCTL. -+ * -+ * 03 18 2011 yuche.tsai -+ * [WCXRP00000574] [Volunteer Patch][MT6620][Driver] Modify P2P FSM Connection Flow -+ * Modify connection flow after Group Formation Complete, or device connect to a GO. -+ * Instead of request channel & connect directly, we use scan to allocate channel bandwidth & connect after RX BCN. -+ * -+ * 03 17 2011 yuche.tsai -+ * NULL -+ * When AIS is connect to an AP, Hot Spot would be enabled under fixed same channel. -+ * -+ * 03 17 2011 yuche.tsai -+ * NULL -+ * Solve the Group Info IE in Probe Response incorrect issue. -+ * -+ * 03 17 2011 yuche.tsai -+ * NULL -+ * Release Channel after Join Complete. -+ * -+ * 03 16 2011 wh.su -+ * [WCXRP00000530] [MT6620 Wi-Fi] [Driver] skip doing p2pRunEventAAAComplete after send assoc response Tx Done -+ * enable the protected while at P2P start GO, and skip some security check . -+ * -+ * 03 15 2011 yuche.tsai -+ * [WCXRP00000560] [Volunteer Patch][MT6620][Driver] P2P Connection from UI using KEY/DISPLAY issue -+ * Fix local configure method issue. -+ * -+ * 03 15 2011 yuche.tsai -+ * [WCXRP00000560] [Volunteer Patch][MT6620][Driver] P2P Connection from UI using KEY/DISPLAY issue -+ * Fix some configure method issue. -+ * -+ * 03 14 2011 yuche.tsai -+ * NULL -+ * . -+ * -+ * 03 14 2011 yuche.tsai -+ * NULL -+ * Fix password ID issue. -+ * -+ * 03 10 2011 yuche.tsai -+ * NULL -+ * Add P2P API. -+ * -+ * 03 08 2011 yuche.tsai -+ * [WCXRP00000480] [Volunteer Patch][MT6620][Driver] WCS IE format issue[WCXRP00000509] -+ * [Volunteer Patch][MT6620][Driver] Kernal panic when remove p2p module. -+ * . -+ * -+ * 03 07 2011 yuche.tsai -+ * [WCXRP00000502] [Volunteer Patch][MT6620][Driver] Fix group ID issue when doing Group Formation. -+ * . -+ * -+ * 03 07 2011 wh.su -+ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code -+ * rename the define to anti_pviracy. -+ * -+ * 03 05 2011 wh.su -+ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code -+ * add the code to get the check rsponse and indicate to app. -+ * -+ * 03 04 2011 wh.su -+ * [WCXRP00000510] [MT6620 Wi-Fi] [Driver] Fixed the CTIA enter test mode issue -+ * fixed the p2p action frame type check for device request indication. -+ * -+ * 03 02 2011 yuche.tsai -+ * [WCXRP00000245] 1. Invitation Request/Response. -+2. Provision Discovery Request/Response -+ -+ * Fix Service Discovery RX packet buffer pointer. -+ * -+ * 03 01 2011 yuche.tsai -+ * [WCXRP00000501] [Volunteer Patch][MT6620][Driver] No common channel issue when doing GO formation -+ * Update channel issue when doing GO formation.. -+ * -+ * 03 01 2011 yuche.tsai -+ * [WCXRP00000245] 1. Invitation Request/Response. -+2. Provision Discovery Request/Response -+ -+ * Update Service Discovery Related wlanoid function. -+ * -+ * 02 21 2011 yuche.tsai -+ * [WCXRP00000481] [Volunteer Patch][MT6620][FW] Scan hang under concurrent case. -+ * Fix all BE issue of WSC or P2P IE. -+ * -+ * 02 18 2011 wh.su -+ * [WCXRP00000471] [MT6620 Wi-Fi][Driver] Add P2P Provison discovery append Config Method attribute at WSC IE -+ * fixed the wsc config method mapping to driver used config method issue. -+ * -+ * 02 18 2011 yuche.tsai -+ * [WCXRP00000479] [Volunteer Patch][MT6620][Driver] Probe Response of P2P using 11b rate. -+ * Update basic rate to FW, after P2P is initialed. -+ * -+ * 02 18 2011 yuche.tsai -+ * [WCXRP00000478] [Volunteer Patch][MT6620][Driver] Probe request frame during search -+ * phase do not contain P2P wildcard SSID. -+ * Use P2P Wildcard SSID when scan type of P2P_WILDCARD_SSID is set. -+ * -+ * 02 18 2011 yuche.tsai -+ * [WCXRP00000480] [Volunteer Patch][MT6620][Driver] WCS IE format issue -+ * Fix WSC IE BE format issue. -+ * -+ * 02 17 2011 wh.su -+ * [WCXRP00000471] [MT6620 Wi-Fi][Driver] Add P2P Provison discovery append Config Method attribute at WSC IE -+ * append the WSC IE config method attribute at provision discovery request. -+ * -+ * 02 16 2011 wh.su -+ * [WCXRP00000448] [MT6620 Wi-Fi][Driver] Fixed WSC IE not send out at probe request -+ * fixed the probe request send out without WSC IE issue (at P2P). -+ * -+ * 02 16 2011 yuche.tsai -+ * [WCXRP00000431] [Volunteer Patch][MT6620][Driver] Add MLME support for deauthentication under AP(Hot-Spot) mode. -+ * If two station connected to the Hot-Spot and one disconnect, FW would get into an infinite loop -+ * -+ * 02 15 2011 yuche.tsai -+ * [WCXRP00000431] [Volunteer Patch][MT6620][Driver] Add MLME support for deauthentication under AP(Hot-Spot) mode. -+ * Fix re-connection issue after RX deauthentication. -+ * -+ * 02 15 2011 yuche.tsai -+ * [WCXRP00000431] [Volunteer Patch][MT6620][Driver] Add MLME support for deauthentication under AP(Hot-Spot) mode. -+ * Fix conneciton issue after disconnect with AP. -+ * -+ * 02 12 2011 yuche.tsai -+ * [WCXRP00000441] [Volunteer Patch][MT6620][Driver] BoW can not create desired station type when Hot Spot is enabled. -+ * P2P Create Station Type according to Target BSS capability. -+ * -+ * 02 10 2011 yuche.tsai -+ * [WCXRP00000431] [Volunteer Patch][MT6620][Driver] Add MLME support for deauthentication under AP(Hot-Spot) mode. -+ * Support Disassoc & Deauthentication for Hot-Spot. -+ * -+ * 02 09 2011 yuche.tsai -+ * [WCXRP00000245] 1. Invitation Request/Response. -+2. Provision Discovery Request/Response -+ -+ * Add Service Discovery Indication Related code. -+ * -+ * 02 09 2011 yuche.tsai -+ * [WCXRP00000431] [Volunteer Patch][MT6620][Driver] Add MLME support for deauthentication under AP(Hot-Spot) mode. -+ * Add Support for MLME deauthentication for Hot-Spot. -+ * -+ * 02 09 2011 yuche.tsai -+ * [WCXRP00000429] [Volunteer Patch][MT6620][Driver] Hot Spot Client Limit Issue -+ * Fix Client Limit Issue. -+ * -+ * 02 08 2011 yuche.tsai -+ * [WCXRP00000419] [Volunteer Patch][MT6620/MT5931][Driver] Provide function of disconnect -+ * to target station for AAA module. -+ * Disconnect every station client when disolve on P2P group. -+ * -+ * 02 08 2011 yuche.tsai -+ * [WCXRP00000245] 1. Invitation Request/Response. -+2. Provision Discovery Request/Response -+ -+ * 1. Fix Service Disocvery Logical issue. -+ * 2. Fix a NULL pointer access violation issue when sending deauthentication packet to a class error station. -+ * -+ * 02 08 2011 yuche.tsai -+ * [WCXRP00000419] [Volunteer Patch][MT6620/MT5931][Driver] Provide function of disconnect -+ * to target station for AAA module. -+ * Workaround of disable P2P network. -+ * -+ * 02 08 2011 yuche.tsai -+ * [WCXRP00000421] [Volunteer Patch][MT6620][Driver] Fix incorrect SSID length Issue -+ * 1. Fixed SSID wrong length issue. -+ * 2. Under Hot Spot configuration, there won't be any P2P IE. -+ * 3. Under Hot Spot configuration, P2P FSM won't get into LISTEN state first. -+ * -+ * 01 27 2011 yuche.tsai -+ * [WCXRP00000399] [Volunteer Patch][MT6620/MT5931][Driver] Fix scan side effect after P2P module separate. -+ * Modify Start GO flow. -+ * -+ * 01 27 2011 yuche.tsai -+ * [WCXRP00000399] [Volunteer Patch][MT6620/MT5931][Driver] Fix scan side effect after P2P module separate. -+ * Fix desire phy type set issue. -+ * -+ * 01 27 2011 yuche.tsai -+ * [WCXRP00000399] [Volunteer Patch][MT6620/MT5931][Driver] Fix scan side effect after P2P module separate. -+ * Add desire phy type set phase I. -+ * -+ * 01 26 2011 yuche.tsai -+ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record. -+ * Fix P2P Disconnect Issue. -+ * -+ * 01 26 2011 yuche.tsai -+ * [WCXRP00000245] 1. Invitation Request/Response. -+2. Provision Discovery Request/Response -+ -+ * Add Service Discovery Function. -+ * -+ * 01 26 2011 cm.chang -+ * [WCXRP00000395] [MT6620 Wi-Fi][Driver][FW] Search STA_REC with additional net type index argument -+ * . -+ * -+ * 01 25 2011 yuche.tsai -+ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record. -+ * Fix compile error when DBG is disabled. -+ * -+ * 01 25 2011 yuche.tsai -+ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record. -+ * Change Station Type Definition. -+ * -+ * 01 19 2011 yuche.tsai -+ * [WCXRP00000353] [Volunteer Patch][MT6620][Driver] Desired Non-HT Rate Set update -+ * when STA record is created under AP Mode. -+ * Add P2P QoS Support. -+ * -+ * 01 19 2011 george.huang -+ * [WCXRP00000355] [MT6620 Wi-Fi] Set WMM-PS related setting with qualifying AP capability -+ * Null NOA attribute setting when no related parameters. -+ * -+ * 01 14 2011 yuche.tsai -+ * [WCXRP00000352] [Volunteer Patch][MT6620][Driver] P2P Statsion Record Client List Issue -+ * Modify AAA flow according to CM's comment. -+ * -+ * 01 13 2011 yuche.tsai -+ * [WCXRP00000353] [Volunteer Patch][MT6620][Driver] Desired Non-HT Rate Set update -+ * when STA record is created under AP Mode. -+ * Resolve Channel ZERO issue. (Uninitialized default channel) -+ * -+ * 01 13 2011 yuche.tsai -+ * [WCXRP00000352] [Volunteer Patch][MT6620][Driver] P2P Statsion Record Client List Issue -+ * Update P2P State Debug Message. -+ * -+ * 01 12 2011 yuche.tsai -+ * [WCXRP00000353] [Volunteer Patch][MT6620][Driver] Desired Non-HT Rate Set update -+ * when STA record is created under AP Mode. -+ * Fix bug when allocating message buffer. -+ * -+ * 01 12 2011 yuche.tsai -+ * [WCXRP00000353] [Volunteer Patch][MT6620][Driver] Desired Non-HT Rate Set update -+ * when STA record is created under AP Mode. -+ * Update Phy Type Set. When legacy client is connected, it can use 11b rate, -+ * but if the P2P device is connected, 11b rate is not allowed. -+ * -+ * 01 12 2011 yuche.tsai -+ * [WCXRP00000352] [Volunteer Patch][MT6620][Driver] P2P Statsion Record Client List Issue -+ * 1. Modify Channel Acquire Time of AP mode from 5s to 1s. -+ * 2. Call cnmP2pIsPermit() before active P2P network. -+ * 3. Add channel selection support for AP mode. -+ * -+ * 01 12 2011 yuche.tsai -+ * [WCXRP00000352] [Volunteer Patch][MT6620][Driver] P2P Statsion Record Client List Issue -+ * Fix Bug of reference to NULL pointer. -+ * -+ * 01 12 2011 yuche.tsai -+ * [WCXRP00000352] [Volunteer Patch][MT6620][Driver] P2P Statsion Record Client List Issue -+ * Modify some behavior of AP mode. -+ * -+ * 01 12 2011 yuche.tsai -+ * [WCXRP00000352] [Volunteer Patch][MT6620][Driver] P2P Statsion Record Client List Issue -+ * Fix bug of wrong pointer check. -+ * -+ * 01 12 2011 yuche.tsai -+ * [WCXRP00000352] [Volunteer Patch][MT6620][Driver] P2P Statsion Record Client List Issue -+ * Fix Compile Error. -+ * -+ * 01 11 2011 yuche.tsai -+ * [WCXRP00000352] [Volunteer Patch][MT6620][Driver] P2P Statsion Record Client List Issue -+ * Add station record into client list before change it state from STATE_2 to STATE_3. -+ * -+ * 01 05 2011 yuche.tsai -+ * [WCXRP00000345] [MT6620][Volunteer Patch] P2P may issue a SSID specified scan request, -+ * but the SSID length is still invalid. -+ * Specify SSID Type when issue a scan request. -+ * -+ * 01 05 2011 cp.wu -+ * [WCXRP00000338] [MT6620 Wi-Fi][Driver] Separate kalMemAlloc into kmalloc and vmalloc implementations -+ * to ease physically continuous memory demands -+ * correct typo -+ * -+ * 01 05 2011 george.huang -+ * [WCXRP00000343] [MT6620 Wi-Fi] Add TSF reset path for concurrent operation -+ * modify NOA update path for preventing assertion false alarm. -+ * -+ * 01 04 2011 cp.wu -+ * [WCXRP00000338] [MT6620 Wi-Fi][Driver] Separate kalMemAlloc into kmalloc and vmalloc implementations -+ * to ease physically continuous memory demands -+ * separate kalMemAlloc() into virtually-continuous and physically-continuous type to ease slab system pressure -+ * -+ * 01 03 2011 wh.su -+ * [WCXRP00000326] [MT6620][Wi-Fi][Driver] check in the binary format gl_sec.o.new instead of use change type!!! -+ * let the p2p ap mode acept a legacy device join. -+ * -+ * 12 22 2010 yuche.tsai -+ * [WCXRP00000245] 1. Invitation Request/Response. -+2. Provision Discovery Request/Response -+ -+ * Fix Compile Error. -+ * -+ * 12 15 2010 yuche.tsai -+ * [WCXRP00000245] 1. Invitation Request/Response. -+2. Provision Discovery Request/Response -+ -+ * Refine Connection Flow. -+ * -+ * 12 08 2010 yuche.tsai -+ * [WCXRP00000245] [MT6620][Driver] Invitation & Provision Discovery Feature Check-in -+ * [WCXRP000000245][MT6620][Driver] Invitation Request Feature Add -+ * -+ * 12 08 2010 yuche.tsai -+ * [WCXRP00000244] [MT6620][Driver] Add station record type for each client when in AP mode. -+ * Change STA Type under AP mode. We would tell if client is a P2P device or a legacy client -+ * by checking the P2P IE in assoc req frame. -+ * -+ * 12 07 2010 cm.chang -+ * [WCXRP00000239] MT6620 Wi-Fi][Driver][FW] Merge concurrent branch back to maintrunk -+ * The order of invoking nicUpdateBss() and rlm functions -+ * -+ * 12 02 2010 yuche.tsai -+ * NULL -+ * Update P2P Connection Policy for Invitation. -+ * -+ * 12 02 2010 yuche.tsai -+ * NULL -+ * Update P2P Connection Policy for Invitation & Provision Discovery. -+ * -+ * 11 30 2010 yuche.tsai -+ * NULL -+ * Invitation & Provision Discovery Indication. -+ * -+ * 11 30 2010 yuche.tsai -+ * NULL -+ * Update Configure Method indication & selection for Provision Discovery & GO_NEGO_REQ -+ * -+ * 11 30 2010 yuche.tsai -+ * NULL -+ * Update RCIP value when RX assoc request frame. -+ * -+ * 11 29 2010 yuche.tsai -+ * NULL -+ * Update P2P related function for INVITATION & PROVISION DISCOVERY. -+ * -+ * 11 26 2010 george.huang -+ * [WCXRP00000152] [MT6620 Wi-Fi] AP mode power saving function -+ * Update P2P PS for NOA function. -+ * -+ * 11 25 2010 yuche.tsai -+ * NULL -+ * Update Code for Invitation Related Function. -+ * -+ * 11 17 2010 wh.su -+ * [WCXRP00000164] [MT6620 Wi-Fi][Driver] Support the p2p random SSID[WCXRP00000179] [MT6620 Wi-Fi][FW] -+ * Set the Tx lowest rate at wlan table for normal operation -+ * fixed some ASSERT check. -+ * -+ * 11 05 2010 wh.su -+ * [WCXRP00000164] [MT6620 Wi-Fi][Driver] Support the p2p random SSID -+ * fixed the p2p role code error. -+ * -+ * 11 04 2010 wh.su -+ * [WCXRP00000164] [MT6620 Wi-Fi][Driver] Support the p2p random SSID -+ * adding the p2p random ssid support. -+ * -+ * 10 20 2010 wh.su -+ * [WCXRP00000124] [MT6620 Wi-Fi] [Driver] Support the dissolve P2P Group -+ * fixed the ASSERT check error -+ * -+ * 10 20 2010 wh.su -+ * [WCXRP00000124] [MT6620 Wi-Fi] [Driver] Support the dissolve P2P Group -+ * Add the code to support disconnect p2p group -+ * -+ * 10 19 2010 wh.su -+ * [WCXRP00000085] [MT6620 Wif-Fi] [Driver] update the modified p2p state -+ * machine[WCXRP00000102] [MT6620 Wi-Fi] [FW] Add a compiling flag and code for support Direct GO at Android -+ * fixed the compiling error. -+ * -+ * 10 14 2010 wh.su -+ * [WCXRP00000102] [MT6620 Wi-Fi] [FW] Add a compiling flag and code for support Direct GO at Android -+ * adding a code to support Direct GO with a compiling flag . -+ * -+ * 10 08 2010 cp.wu -+ * [WCXRP00000087] [MT6620 Wi-Fi][Driver] Cannot connect to 5GHz AP, driver will cause FW assert. -+ * correct erroneous logic: specifying eBand with incompatible eSco -+ * -+ * 10 08 2010 wh.su -+ * [WCXRP00000085] [MT6620 Wif-Fi] [Driver] update the modified p2p state machine -+ * fixed the compiling error. -+ * -+ * 10 08 2010 wh.su -+ * [WCXRP00000085] [MT6620 Wif-Fi] [Driver] update the modified p2p state machine -+ * update the frog's new p2p state machine. -+ * -+ * 09 10 2010 wh.su -+ * NULL -+ * fixed the compiling error at WinXP. -+ * -+ * 09 07 2010 yuche.tsai -+ * NULL -+ * Reset Common IE Buffer of P2P INFO when scan request is issued. -+ * If an action frame other than public action frame is received, return direcly. -+ * -+ * 09 07 2010 wh.su -+ * NULL -+ * adding the code for beacon/probe req/ probe rsp wsc ie at p2p. -+ * -+ * 09 06 2010 wh.su -+ * NULL -+ * let the p2p can set the privacy bit at beacon and rsn ie at assoc req at key handshake state. -+ * -+ * 09 03 2010 kevin.huang -+ * NULL -+ * Refine #include sequence and solve recursive/nested #include issue -+ * -+ * 08 26 2010 yuche.tsai -+ * NULL -+ * Add P2P Connection Abort Event Message handler. -+ * -+ * 08 24 2010 cm.chang -+ * NULL -+ * Support RLM initail channel of Ad-hoc, P2P and BOW -+ * -+ * 08 23 2010 yuche.tsai -+ * NULL -+ * 1. Fix Interface Address from GO Nego Req/Rsp is not correct. -+ * 2. Fix GO mode does not change media state after station connected. -+ * 3. Fix STA don't response probe request when there is a connection request. -+ * -+ * 08 20 2010 cm.chang -+ * NULL -+ * Migrate RLM code to host from FW -+ * -+ * 08 20 2010 kevin.huang -+ * NULL -+ * Modify AAA Module for changing STA STATE 3 at p2p/bowRunEventAAAComplete() -+ * -+ * 08 20 2010 yuche.tsai -+ * NULL -+ * Add Glue Layer indication. -+ * -+ * 08 17 2010 yuche.tsai -+ * NULL -+ * Fix compile warning under Linux. -+ * -+ * 08 17 2010 yuche.tsai -+ * NULL -+ * Fix some P2P FSM bug. -+ * -+ * 08 16 2010 yuche.tsai -+ * NULL -+ * Add random Interface Address Generation support. -+ * -+ * 08 16 2010 yuche.tsai -+ * NULL -+ * Fix some P2P FSM bug. -+ * -+ * 08 16 2010 yuche.tsai -+ * NULL -+ * Update P2P FSM code for GO Nego. -+ * -+ * 08 16 2010 kevin.huang -+ * NULL -+ * Refine AAA functions -+ * -+ * 08 12 2010 kevin.huang -+ * NULL -+ * Refine bssProcessProbeRequest() and bssSendBeaconProbeResponse() -+ * -+ * 08 12 2010 yuche.tsai -+ * NULL -+ * Join complete indication. -+ * -+ * 08 11 2010 yuche.tsai -+ * NULL -+ * Add two boolean in connection request. -+ * Based on these two boolean value, P2P FSM should -+ * decide to do invitation or group formation or start a GO directly. -+ * -+ * 08 11 2010 yuche.tsai -+ * NULL -+ * Update P2P FSM, currently P2P Device Discovery is verified. -+ * -+ * 08 05 2010 yuche.tsai -+ * NULL -+ * Update P2P FSM for group formation. -+ * -+ * 08 03 2010 george.huang -+ * NULL -+ * handle event for updating NOA parameters indicated from FW -+ * -+ * 08 03 2010 cp.wu -+ * NULL -+ * limit build always needs spin-lock declaration. -+ * -+ * 08 02 2010 yuche.tsai -+ * NULL -+ * P2P Group Negotiation Code Check in. -+ * -+ * 07 26 2010 yuche.tsai -+ * -+ * Add P2P FSM code check in. -+ * -+ * 07 21 2010 yuche.tsai -+ * -+ * Add P2P Scan & Scan Result Parsing & Saving. -+ * -+ * 07 19 2010 yuche.tsai -+ * -+ * Update P2P FSM. -+ * -+ * 07 09 2010 george.huang -+ * -+ * [WPD00001556] Migrate PM variables from FW to driver: for composing QoS Info -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 21 2010 yuche.tsai -+ * [WPD00003839][MT6620 5931][P2P] Feature migration -+ * Fix compile error while enable WIFI_DIRECT support. -+ * -+ * 06 21 2010 yuche.tsai -+ * [WPD00003839][MT6620 5931][P2P] Feature migration -+ * Update P2P Function call. -+ * -+ * 06 17 2010 yuche.tsai -+ * [WPD00003839][MT6620 5931][P2P] Feature migration -+ * First draft for migration P2P FSM from FW to Driver. -+ * -+ * 04 19 2010 kevin.huang -+ * [BORA00000714][WIFISYS][New Feature]Beacon Timeout Support -+ * Add Beacon Timeout Support and will send Null frame to diagnose connection -+ * -+ * 03 18 2010 kevin.huang -+ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support -+ * Rename CFG flag for P2P -+ * -+ * 02 26 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Add code to test P2P GO -+ * -+ * 02 23 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Add Wi-Fi Direct SSID and P2P GO Test Mode -+ * -+ * 02 05 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Modify code due to BAND_24G define was changed -+ * -+ * 02 05 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Revise data structure to share the same BSS_INFO_T for avoiding coding error -+ * -+ * 02 04 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Add AAA Module Support, Revise Net Type to Net Type Index for array lookup -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "precomp.h" -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+#if DBG -+/*lint -save -e64 Type mismatch */ -+static PUINT_8 apucDebugP2pState[P2P_STATE_NUM] = { -+ (PUINT_8) DISP_STRING("P2P_STATE_IDLE"), -+ (PUINT_8) DISP_STRING("P2P_STATE_SCAN"), -+ (PUINT_8) DISP_STRING("P2P_STATE_AP_CHANNEL_DETECT"), -+ (PUINT_8) DISP_STRING("P2P_STATE_REQING_CHANNEL"), -+ (PUINT_8) DISP_STRING("P2P_STATE_CHNL_ON_HAND"), -+ (PUINT_8) DISP_STRING("P2P_STATE_GC_JOIN") -+}; -+ -+/*lint -restore */ -+#else -+static UINT_8 apucDebugP2pState[P2P_STATE_NUM] = { -+ P2P_STATE_IDLE, -+ P2P_STATE_SCAN, -+ P2P_STATE_AP_CHANNEL_DETECT, -+ P2P_STATE_REQING_CHANNEL, -+ P2P_STATE_CHNL_ON_HAND, -+ P2P_STATE_GC_JOIN -+}; -+ -+#endif /* DBG */ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+/* p2pStateXXX : Processing P2P FSM related action. -+ * p2pFSMXXX : Control P2P FSM flow. -+ * p2pFuncXXX : Function for doing one thing. -+ */ -+VOID p2pFsmInit(IN P_ADAPTER_T prAdapter) -+{ -+ -+ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; -+ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; -+ -+ do { -+ ASSERT_BREAK(prAdapter != NULL); -+ -+ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; -+ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); -+ -+ ASSERT_BREAK(prP2pFsmInfo != NULL); -+ -+ LINK_INITIALIZE(&(prP2pFsmInfo->rMsgEventQueue)); -+ LINK_INITIALIZE(&(prP2pBssInfo->rStaRecOfClientList)); -+ -+ prP2pFsmInfo->eCurrentState = prP2pFsmInfo->ePreviousState = P2P_STATE_IDLE; -+ prP2pFsmInfo->prTargetBss = NULL; -+ prP2pFsmInfo->fgIsWPSMode = 0; -+ -+ cnmTimerInitTimer(prAdapter, -+ &(prAdapter->rP2pFsmTimeoutTimer), -+ (PFN_MGMT_TIMEOUT_FUNC) p2pFsmRunEventFsmTimeout, (ULONG) prP2pFsmInfo); -+ -+ /* 4 <2> Initiate BSS_INFO_T - common part */ -+ BSS_INFO_INIT(prAdapter, NETWORK_TYPE_P2P_INDEX); -+ -+ /* 4 <2.1> Initiate BSS_INFO_T - Setup HW ID */ -+ prP2pBssInfo->ucConfigAdHocAPMode = AP_MODE_11G_P2P; -+ prP2pBssInfo->ucHwDefaultFixedRateCode = RATE_OFDM_6M; -+ -+ prP2pBssInfo->ucNonHTBasicPhyType = (UINT_8) -+ rNonHTApModeAttributes[prP2pBssInfo->ucConfigAdHocAPMode].ePhyTypeIndex; -+ prP2pBssInfo->u2BSSBasicRateSet = -+ rNonHTApModeAttributes[prP2pBssInfo->ucConfigAdHocAPMode].u2BSSBasicRateSet; -+ -+ prP2pBssInfo->u2OperationalRateSet = -+ rNonHTPhyAttributes[prP2pBssInfo->ucNonHTBasicPhyType].u2SupportedRateSet; -+ -+ rateGetDataRatesFromRateSet(prP2pBssInfo->u2OperationalRateSet, -+ prP2pBssInfo->u2BSSBasicRateSet, -+ prP2pBssInfo->aucAllSupportedRates, &prP2pBssInfo->ucAllSupportedRatesLen); -+ -+ prP2pBssInfo->prBeacon = cnmMgtPktAlloc(prAdapter, -+ OFFSET_OF(WLAN_BEACON_FRAME_T, aucInfoElem[0]) + MAX_IE_LENGTH); -+ -+ if (prP2pBssInfo->prBeacon) { -+ prP2pBssInfo->prBeacon->eSrc = TX_PACKET_MGMT; -+ prP2pBssInfo->prBeacon->ucStaRecIndex = 0xFF; /* NULL STA_REC */ -+ prP2pBssInfo->prBeacon->ucNetworkType = NETWORK_TYPE_P2P_INDEX; -+ } else { -+ /* Out of memory. */ -+ ASSERT(FALSE); -+ } -+ -+ prP2pBssInfo->eCurrentOPMode = OP_MODE_NUM; -+ -+ prP2pBssInfo->rPmProfSetupInfo.ucBmpDeliveryAC = PM_UAPSD_ALL; -+ prP2pBssInfo->rPmProfSetupInfo.ucBmpTriggerAC = PM_UAPSD_ALL; -+ prP2pBssInfo->rPmProfSetupInfo.ucUapsdSp = WMM_MAX_SP_LENGTH_2; -+ prP2pBssInfo->ucPrimaryChannel = P2P_DEFAULT_LISTEN_CHANNEL; -+ prP2pBssInfo->eBand = BAND_2G4; -+ prP2pBssInfo->eBssSCO = CHNL_EXT_SCN; -+ -+ if (prAdapter->rWifiVar.fgSupportQoS) -+ prP2pBssInfo->fgIsQBSS = TRUE; -+ else -+ prP2pBssInfo->fgIsQBSS = FALSE; -+ -+ SET_NET_PWR_STATE_IDLE(prAdapter, NETWORK_TYPE_P2P_INDEX); -+ -+ p2pFsmStateTransition(prAdapter, prP2pFsmInfo, P2P_STATE_IDLE); -+ -+ } while (FALSE); -+ -+} /* p2pFsmInit */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief The function is used to uninitialize the value in P2P_FSM_INFO_T for -+* P2P FSM operation -+* -+* @param (none) -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID p2pFsmUninit(IN P_ADAPTER_T prAdapter) -+{ -+ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; -+ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; -+ -+ do { -+ ASSERT_BREAK(prAdapter != NULL); -+ -+ DEBUGFUNC("p2pFsmUninit()"); -+ DBGLOG(P2P, INFO, "->p2pFsmUninit()\n"); -+ -+ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; -+ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); -+ -+ p2pFuncSwitchOPMode(prAdapter, prP2pBssInfo, OP_MODE_P2P_DEVICE, TRUE); -+ -+ p2pFsmRunEventAbort(prAdapter, prP2pFsmInfo); -+ -+ p2pStateAbort_IDLE(prAdapter, prP2pFsmInfo, P2P_STATE_NUM); -+ -+ UNSET_NET_ACTIVE(prAdapter, NETWORK_TYPE_P2P_INDEX); -+ -+ wlanAcquirePowerControl(prAdapter); -+ -+ /* Release all pending CMD queue. */ -+ DBGLOG(P2P, TRACE, "p2pFsmUninit: wlanProcessCommandQueue, num of element:%d\n", -+ (UINT_32) prAdapter->prGlueInfo->rCmdQueue.u4NumElem); -+ wlanProcessCommandQueue(prAdapter, &prAdapter->prGlueInfo->rCmdQueue); -+ -+ wlanReleasePowerControl(prAdapter); -+ -+ /* Release pending mgmt frame, -+ * mgmt frame may be pending by CMD without resource. -+ */ -+ kalClearMgmtFramesByNetType(prAdapter->prGlueInfo, NETWORK_TYPE_P2P_INDEX); -+ -+ /* Clear PendingCmdQue */ -+ wlanReleasePendingCMDbyNetwork(prAdapter, NETWORK_TYPE_P2P_INDEX); -+ -+ if (prP2pBssInfo->prBeacon) { -+ cnmMgtPktFree(prAdapter, prP2pBssInfo->prBeacon); -+ prP2pBssInfo->prBeacon = NULL; -+ } -+ -+ } while (FALSE); -+ -+ return; -+ -+} /* end of p2pFsmUninit() */ -+ -+VOID p2pFsmStateTransition(IN P_ADAPTER_T prAdapter, IN P_P2P_FSM_INFO_T prP2pFsmInfo, IN ENUM_P2P_STATE_T eNextState) -+{ -+ BOOLEAN fgIsTransOut = (BOOLEAN) FALSE; -+ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; -+ P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo = (P_P2P_SPECIFIC_BSS_INFO_T) NULL; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prP2pFsmInfo != NULL)); -+ -+ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); -+ prP2pSpecificBssInfo = prAdapter->rWifiVar.prP2pSpecificBssInfo; -+ -+ if (!IS_BSS_ACTIVE(prP2pBssInfo)) { -+ if (!cnmP2PIsPermitted(prAdapter)) -+ return; -+ -+ SET_NET_ACTIVE(prAdapter, NETWORK_TYPE_P2P_INDEX); -+ nicActivateNetwork(prAdapter, NETWORK_TYPE_P2P_INDEX); -+ } -+ -+ fgIsTransOut = fgIsTransOut ? FALSE : TRUE; -+ -+ if (!fgIsTransOut) { -+#if DBG -+ DBGLOG(P2P, STATE, "TRANSITION: [%s] -> [%s]\n", -+ apucDebugP2pState[prP2pFsmInfo->eCurrentState], -+ apucDebugP2pState[eNextState]); -+#else -+ DBGLOG(P2P, STATE, "[%d] TRANSITION: [%d] -> [%d]\n", -+ DBG_P2P_IDX, apucDebugP2pState[prP2pFsmInfo->eCurrentState], -+ apucDebugP2pState[eNextState]); -+#endif -+ -+ /* Transition into current state. */ -+ prP2pFsmInfo->ePreviousState = prP2pFsmInfo->eCurrentState; -+ prP2pFsmInfo->eCurrentState = eNextState; -+ } -+ -+ switch (prP2pFsmInfo->eCurrentState) { -+ case P2P_STATE_IDLE: -+ if (fgIsTransOut) -+ p2pStateAbort_IDLE(prAdapter, prP2pFsmInfo, eNextState); -+ else -+ fgIsTransOut = p2pStateInit_IDLE(prAdapter, prP2pFsmInfo, prP2pBssInfo, &eNextState); -+ break; -+ case P2P_STATE_SCAN: -+ if (fgIsTransOut) { -+ /* Scan done / scan canceled. */ -+ p2pStateAbort_SCAN(prAdapter, prP2pFsmInfo, eNextState); -+ } else { -+ /* Initial scan request. */ -+ p2pStateInit_SCAN(prAdapter, prP2pFsmInfo); -+ } -+ -+ break; -+ case P2P_STATE_AP_CHANNEL_DETECT: -+ if (fgIsTransOut) { -+ /* Scan done */ -+ /* Get sparse channel result. */ -+ p2pStateAbort_AP_CHANNEL_DETECT(prAdapter, -+ prP2pFsmInfo, prP2pSpecificBssInfo, eNextState); -+ } -+ -+ else { -+ /* Initial passive scan request. */ -+ p2pStateInit_AP_CHANNEL_DETECT(prAdapter, prP2pFsmInfo); -+ } -+ -+ break; -+ case P2P_STATE_REQING_CHANNEL: -+ if (fgIsTransOut) { -+ /* Channel on hand / Channel canceled. */ -+ p2pStateAbort_REQING_CHANNEL(prAdapter, prP2pFsmInfo, eNextState); -+ } else { -+ /* Initial channel request. */ -+ p2pFuncAcquireCh(prAdapter, &(prP2pFsmInfo->rChnlReqInfo)); -+ } -+ -+ break; -+ case P2P_STATE_CHNL_ON_HAND: -+ if (fgIsTransOut) { -+ p2pStateAbort_CHNL_ON_HAND(prAdapter, prP2pFsmInfo, prP2pBssInfo, eNextState); -+ } else { -+ /* Initial channel ready. */ -+ /* Send channel ready event. */ -+ /* Start a FSM timer. */ -+ p2pStateInit_CHNL_ON_HAND(prAdapter, prP2pBssInfo, prP2pFsmInfo); -+ } -+ -+ break; -+ case P2P_STATE_GC_JOIN: -+ if (fgIsTransOut) { -+ /* Join complete / join canceled. */ -+ p2pStateAbort_GC_JOIN(prAdapter, prP2pFsmInfo, &(prP2pFsmInfo->rJoinInfo), eNextState); -+ } else { -+ if (prP2pFsmInfo->prTargetBss == NULL) { -+ ASSERT(FALSE); -+ } else { -+ /* Send request to SAA module. */ -+ p2pStateInit_GC_JOIN(prAdapter, -+ prP2pFsmInfo, -+ prP2pBssInfo, -+ &(prP2pFsmInfo->rJoinInfo), prP2pFsmInfo->prTargetBss); -+ } -+ } -+ -+ break; -+ default: -+ break; -+ } -+ -+ } while (fgIsTransOut); -+ -+} /* p2pFsmStateTransition */ -+ -+VOID p2pFsmRunEventSwitchOPMode(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) -+{ -+ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; -+ P_MSG_P2P_SWITCH_OP_MODE_T prSwitchOpMode = (P_MSG_P2P_SWITCH_OP_MODE_T) prMsgHdr; -+ P_P2P_CONNECTION_SETTINGS_T prP2pConnSettings = (P_P2P_CONNECTION_SETTINGS_T) NULL; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prSwitchOpMode != NULL)); -+ -+ DBGLOG(P2P, TRACE, "p2pFsmRunEventSwitchOPMode\n"); -+ -+ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); -+ prP2pConnSettings = prAdapter->rWifiVar.prP2PConnSettings; -+ -+ if (prSwitchOpMode->eOpMode >= OP_MODE_NUM) { -+ ASSERT(FALSE); -+ break; -+ } -+ -+ /* P2P Device / GC. */ -+ p2pFuncSwitchOPMode(prAdapter, prP2pBssInfo, prSwitchOpMode->eOpMode, TRUE); -+ -+ } while (FALSE); -+ -+ if (prMsgHdr) -+ cnmMemFree(prAdapter, prMsgHdr); -+ -+} /* p2pFsmRunEventSwitchOPMode */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is used to handle scan done event during Device Discovery. -+* -+* \param[in] prAdapter Pointer of ADAPTER_T -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID p2pFsmRunEventScanDone(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) -+{ -+ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; -+ P_P2P_SCAN_REQ_INFO_T prScanReqInfo = (P_P2P_SCAN_REQ_INFO_T) NULL; -+ P_MSG_SCN_SCAN_DONE prScanDoneMsg = (P_MSG_SCN_SCAN_DONE) NULL; -+ ENUM_P2P_STATE_T eNextState = P2P_STATE_NUM; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prMsgHdr != NULL)); -+ -+ /* This scan done event is either for "SCAN" phase or "SEARCH" state or "LISTEN" state. -+ * The scan done for SCAN phase & SEARCH state doesn't imply Device -+ * Discovery over. -+ */ -+ DBGLOG(P2P, TRACE, "P2P Scan Done Event\n"); -+ -+ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; -+ -+ if (prP2pFsmInfo == NULL) -+ break; -+ -+ prScanReqInfo = &(prP2pFsmInfo->rScanReqInfo); -+ prScanDoneMsg = (P_MSG_SCN_SCAN_DONE) prMsgHdr; -+ -+ if (prScanDoneMsg->ucSeqNum != prScanReqInfo->ucSeqNumOfScnMsg) { -+ /* Scan Done message sequence number mismatch. -+ * Ignore this event. (P2P FSM issue two scan events.) -+ */ -+ /* The scan request has been cancelled. -+ * Ignore this message. It is possible. -+ */ -+ DBGLOG(P2P, TRACE, "P2P Scan Don SeqNum:%d <-> P2P Fsm SCAN Msg:%d\n", -+ prScanDoneMsg->ucSeqNum, prScanReqInfo->ucSeqNumOfScnMsg); -+ -+ break; -+ } -+ -+ switch (prP2pFsmInfo->eCurrentState) { -+ case P2P_STATE_SCAN: -+ { -+ P_P2P_CONNECTION_REQ_INFO_T prConnReqInfo = &(prP2pFsmInfo->rConnReqInfo); -+ -+ prScanReqInfo->fgIsAbort = FALSE; -+ -+ if (prConnReqInfo->fgIsConnRequest) { -+ prP2pFsmInfo->prTargetBss = p2pFuncKeepOnConnection(prAdapter, -+ &prP2pFsmInfo->rConnReqInfo, -+ &prP2pFsmInfo->rChnlReqInfo, -+ &prP2pFsmInfo->rScanReqInfo); -+ if (prP2pFsmInfo->prTargetBss == NULL) -+ eNextState = P2P_STATE_SCAN; -+ else -+ eNextState = P2P_STATE_REQING_CHANNEL; -+ } else { -+ eNextState = P2P_STATE_IDLE; -+ } -+ -+ } -+ break; -+ case P2P_STATE_AP_CHANNEL_DETECT: -+ eNextState = P2P_STATE_REQING_CHANNEL; -+ break; -+ default: -+ /* Unexpected channel scan done event without being chanceled. */ -+ ASSERT(FALSE); -+ break; -+ } -+ -+ prScanReqInfo->fgIsScanRequest = FALSE; -+ -+ p2pFsmStateTransition(prAdapter, prP2pFsmInfo, eNextState); -+ -+ } while (FALSE); -+ -+ if (prMsgHdr) -+ cnmMemFree(prAdapter, prMsgHdr); -+ -+} /* p2pFsmRunEventScanDone */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is call when channel is granted by CNM module from FW. -+* -+* \param[in] prAdapter Pointer of ADAPTER_T -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID p2pFsmRunEventChGrant(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) -+{ -+ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; -+ P_P2P_CHNL_REQ_INFO_T prChnlReqInfo = (P_P2P_CHNL_REQ_INFO_T) NULL; -+ P_MSG_CH_GRANT_T prMsgChGrant = (P_MSG_CH_GRANT_T) NULL; -+ UINT_8 ucTokenID = 0; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prMsgHdr != NULL)); -+ -+ DBGLOG(P2P, TRACE, "P2P Run Event Channel Grant\n"); -+ -+ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; -+ -+ if (prP2pFsmInfo == NULL) -+ break; -+ -+ prMsgChGrant = (P_MSG_CH_GRANT_T) prMsgHdr; -+ ucTokenID = prMsgChGrant->ucTokenID; -+ prP2pFsmInfo->u4GrantInterval = prMsgChGrant->u4GrantInterval; -+ -+ prChnlReqInfo = &(prP2pFsmInfo->rChnlReqInfo); -+ -+ if (ucTokenID == prChnlReqInfo->ucSeqNumOfChReq) { -+ ENUM_P2P_STATE_T eNextState = P2P_STATE_NUM; -+ -+ switch (prP2pFsmInfo->eCurrentState) { -+ case P2P_STATE_REQING_CHANNEL: -+ switch (prChnlReqInfo->eChannelReqType) { -+ case CHANNEL_REQ_TYPE_REMAIN_ON_CHANNEL: -+ eNextState = P2P_STATE_CHNL_ON_HAND; -+ break; -+ case CHANNEL_REQ_TYPE_GC_JOIN_REQ: -+ eNextState = P2P_STATE_GC_JOIN; -+ break; -+ case CHANNEL_REQ_TYPE_GO_START_BSS: -+ eNextState = P2P_STATE_IDLE; -+ break; -+ default: -+ break; -+ } -+ -+ p2pFsmStateTransition(prAdapter, prP2pFsmInfo, eNextState); -+ break; -+ default: -+ /* Channel is granted under unexpected state. -+ * Driver should cancel channel privileagea before leaving the states. -+ */ -+ ASSERT(FALSE); -+ break; -+ } -+ -+ } else { -+ /* Channel requsted, but released. */ -+ /* ASSERT(!prChnlReqInfo->fgIsChannelRequested); */ -+ DBGLOG(P2P, TRACE, "Channel requsted, but released\n"); -+ } -+ } while (FALSE); -+ -+ if (prMsgHdr) -+ cnmMemFree(prAdapter, prMsgHdr); -+ -+ return; -+ -+} /* p2pFsmRunEventChGrant */ -+ -+VOID p2pFsmRunEventChannelRequest(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) -+{ -+ P_P2P_CHNL_REQ_INFO_T prChnlReqInfo = (P_P2P_CHNL_REQ_INFO_T) NULL; -+ P_MSG_P2P_CHNL_REQUEST_T prP2pChnlReqMsg = (P_MSG_P2P_CHNL_REQUEST_T) NULL; -+ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; -+ ENUM_P2P_STATE_T eNextState = P2P_STATE_NUM; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prMsgHdr != NULL)); -+ -+ prP2pChnlReqMsg = (P_MSG_P2P_CHNL_REQUEST_T) prMsgHdr; -+ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; -+ -+ if (prP2pFsmInfo == NULL) -+ break; -+ -+ prChnlReqInfo = &(prP2pFsmInfo->rChnlReqInfo); -+ -+ DBGLOG(P2P, TRACE, "p2pFsmRunEventChannelRequest\n"); -+ -+ /* Special case of time renewing for same frequency. */ -+ if ((prP2pFsmInfo->eCurrentState == P2P_STATE_CHNL_ON_HAND) && -+ (prChnlReqInfo->ucReqChnlNum == prP2pChnlReqMsg->rChannelInfo.ucChannelNum) && -+ (prChnlReqInfo->eBand == prP2pChnlReqMsg->rChannelInfo.eBand) && -+ (prChnlReqInfo->eChnlSco == prP2pChnlReqMsg->eChnlSco)) { -+ -+ ASSERT(prChnlReqInfo->fgIsChannelRequested == TRUE); -+ ASSERT(prChnlReqInfo->eChannelReqType == CHANNEL_REQ_TYPE_REMAIN_ON_CHANNEL); -+ -+ prChnlReqInfo->u8Cookie = prP2pChnlReqMsg->u8Cookie; -+ prChnlReqInfo->u4MaxInterval = prP2pChnlReqMsg->u4Duration; -+ -+ /* Re-enter the state. */ -+ eNextState = P2P_STATE_CHNL_ON_HAND; -+ } else { -+ -+ /* Make sure the state is in IDLE state. */ -+ p2pFsmRunEventAbort(prAdapter, prP2pFsmInfo); -+ -+ /* Cookie can only be assign after abort.(for indication) */ -+ prChnlReqInfo->u8Cookie = prP2pChnlReqMsg->u8Cookie; -+ prChnlReqInfo->ucReqChnlNum = prP2pChnlReqMsg->rChannelInfo.ucChannelNum; -+ prChnlReqInfo->eBand = prP2pChnlReqMsg->rChannelInfo.eBand; -+ prChnlReqInfo->eChnlSco = prP2pChnlReqMsg->eChnlSco; -+ prChnlReqInfo->u4MaxInterval = prP2pChnlReqMsg->u4Duration; -+ prChnlReqInfo->eChannelReqType = CHANNEL_REQ_TYPE_REMAIN_ON_CHANNEL; -+ -+ eNextState = P2P_STATE_REQING_CHANNEL; -+ } -+ -+ p2pFsmStateTransition(prAdapter, prP2pFsmInfo, eNextState); -+ -+ } while (FALSE); -+ -+ if (prMsgHdr) -+ cnmMemFree(prAdapter, prMsgHdr); -+ -+} /* p2pFsmRunEventChannelRequest */ -+ -+VOID p2pFsmRunEventChannelAbort(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) -+{ -+ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; -+ P_MSG_P2P_CHNL_ABORT_T prChnlAbortMsg = (P_MSG_P2P_CHNL_ABORT_T) NULL; -+ P_P2P_CHNL_REQ_INFO_T prChnlReqInfo = (P_P2P_CHNL_REQ_INFO_T) NULL; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prMsgHdr != NULL)); -+ -+ prChnlAbortMsg = (P_MSG_P2P_CHNL_ABORT_T) prMsgHdr; -+ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; -+ -+ if (prP2pFsmInfo == NULL) -+ break; -+ -+ prChnlReqInfo = &prP2pFsmInfo->rChnlReqInfo; -+ -+ DBGLOG(P2P, TRACE, "p2pFsmRunEventChannelAbort\n"); -+ -+ if ((prChnlAbortMsg->u8Cookie == prChnlReqInfo->u8Cookie) && (prChnlReqInfo->fgIsChannelRequested)) { -+ -+ ASSERT((prP2pFsmInfo->eCurrentState == P2P_STATE_REQING_CHANNEL || -+ (prP2pFsmInfo->eCurrentState == P2P_STATE_CHNL_ON_HAND))); -+ -+ p2pFsmStateTransition(prAdapter, prP2pFsmInfo, P2P_STATE_IDLE); -+ } -+ -+ } while (FALSE); -+ -+ if (prMsgHdr) -+ cnmMemFree(prAdapter, prMsgHdr); -+ -+} /* p2pFsmRunEventChannelAbort */ -+ -+VOID p2pFsmRunEventScanRequest(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) -+{ -+ -+ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; -+ P_MSG_P2P_SCAN_REQUEST_T prP2pScanReqMsg = (P_MSG_P2P_SCAN_REQUEST_T) NULL; -+ P_P2P_SCAN_REQ_INFO_T prScanReqInfo = (P_P2P_SCAN_REQ_INFO_T) NULL; -+ UINT_32 u4ChnlListSize = 0; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prMsgHdr != NULL)); -+ -+ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; -+ -+ if (prP2pFsmInfo == NULL) -+ break; -+ -+ prP2pScanReqMsg = (P_MSG_P2P_SCAN_REQUEST_T) prMsgHdr; -+ prScanReqInfo = &(prP2pFsmInfo->rScanReqInfo); -+ -+ DBGLOG(P2P, TRACE, "p2pFsmRunEventScanRequest\n"); -+ -+ /* Make sure the state is in IDLE state. */ -+ p2pFsmRunEventAbort(prAdapter, prP2pFsmInfo); -+ -+ ASSERT(prScanReqInfo->fgIsScanRequest == FALSE); -+ -+ prScanReqInfo->fgIsAbort = TRUE; -+ prScanReqInfo->eScanType = SCAN_TYPE_ACTIVE_SCAN; -+ prScanReqInfo->eChannelSet = SCAN_CHANNEL_SPECIFIED; -+ -+ /* Channel List */ -+ prScanReqInfo->ucNumChannelList = prP2pScanReqMsg->u4NumChannel; -+ DBGLOG(P2P, TRACE, "Scan Request Channel List Number: %d\n", prScanReqInfo->ucNumChannelList); -+ if (prScanReqInfo->ucNumChannelList > MAXIMUM_OPERATION_CHANNEL_LIST) { -+ DBGLOG(P2P, TRACE, "Channel List Number Overloaded: %d, change to: %d\n", -+ prScanReqInfo->ucNumChannelList, MAXIMUM_OPERATION_CHANNEL_LIST); -+ prScanReqInfo->ucNumChannelList = MAXIMUM_OPERATION_CHANNEL_LIST; -+ } -+ -+ u4ChnlListSize = sizeof(RF_CHANNEL_INFO_T) * prScanReqInfo->ucNumChannelList; -+ kalMemCopy(prScanReqInfo->arScanChannelList, prP2pScanReqMsg->arChannelListInfo, u4ChnlListSize); -+ -+ /* TODO: I only take the first SSID. Multiple SSID may be needed in the future. */ -+ /* SSID */ -+ if (prP2pScanReqMsg->i4SsidNum >= 1) -+ kalMemCopy(&(prScanReqInfo->rSsidStruct), prP2pScanReqMsg->prSSID, sizeof(P2P_SSID_STRUCT_T)); -+ else -+ prScanReqInfo->rSsidStruct.ucSsidLen = 0; -+ -+ /* IE Buffer */ -+ kalMemCopy(prScanReqInfo->aucIEBuf, prP2pScanReqMsg->pucIEBuf, prP2pScanReqMsg->u4IELen); -+ -+ prScanReqInfo->u4BufLength = prP2pScanReqMsg->u4IELen; -+ -+ p2pFsmStateTransition(prAdapter, prP2pFsmInfo, P2P_STATE_SCAN); -+ -+ } while (FALSE); -+ -+ if (prMsgHdr) -+ cnmMemFree(prAdapter, prMsgHdr); -+ -+} /* p2pFsmRunEventScanRequest */ -+ -+VOID p2pFsmRunEventScanAbort(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) -+{ -+ -+ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; -+ -+ do { -+ ASSERT_BREAK(prAdapter != NULL); -+ -+ DBGLOG(P2P, TRACE, "p2pFsmRunEventScanAbort\n"); -+ -+ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; -+ -+ if (prP2pFsmInfo->eCurrentState == P2P_STATE_SCAN) { -+ P_P2P_SCAN_REQ_INFO_T prScanReqInfo = &(prP2pFsmInfo->rScanReqInfo); -+ -+ prScanReqInfo->fgIsAbort = TRUE; -+ -+ p2pFsmStateTransition(prAdapter, prP2pFsmInfo, P2P_STATE_IDLE); -+ } -+ -+ } while (FALSE); -+ -+ if (prMsgHdr) -+ cnmMemFree(prAdapter, prMsgHdr); -+ -+} /* p2pFsmRunEventScanAbort */ -+ -+VOID p2pFsmRunEventAbort(IN P_ADAPTER_T prAdapter, IN P_P2P_FSM_INFO_T prP2pFsmInfo) -+{ -+ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prP2pFsmInfo != NULL)); -+ -+ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); -+ -+ DBGLOG(P2P, TRACE, "p2pFsmRunEventAbort\n"); -+ -+ if (prP2pFsmInfo->eCurrentState != P2P_STATE_IDLE) { -+ -+ if (prP2pFsmInfo->eCurrentState == P2P_STATE_SCAN) { -+ -+ P_P2P_SCAN_REQ_INFO_T prScanReqInfo = &(prP2pFsmInfo->rScanReqInfo); -+ -+ prScanReqInfo->fgIsAbort = TRUE; -+ } else if (prP2pFsmInfo->eCurrentState == P2P_STATE_REQING_CHANNEL) { -+ /* 2012/08/06: frog -+ * Prevent Start GO. -+ */ -+ prP2pBssInfo->eIntendOPMode = OP_MODE_NUM; -+ } -+ /* For other state, is there any special action that should be take before leaving? */ -+ -+ p2pFsmStateTransition(prAdapter, prP2pFsmInfo, P2P_STATE_IDLE); -+ } else { -+ /* P2P State IDLE. */ -+ P_P2P_CHNL_REQ_INFO_T prChnlReqInfo = &(prP2pFsmInfo->rChnlReqInfo); -+ -+ if (prChnlReqInfo->fgIsChannelRequested) -+ p2pFuncReleaseCh(prAdapter, prChnlReqInfo); -+ -+ cnmTimerStopTimer(prAdapter, &(prAdapter->rP2pFsmTimeoutTimer)); -+ } -+ -+ } while (FALSE); -+ -+} /* p2pFsmRunEventAbort */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is used to handle FSM Timeout. -+* -+* \param[in] prAdapter Pointer of ADAPTER_T -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID p2pFsmRunEventFsmTimeout(IN P_ADAPTER_T prAdapter, IN ULONG ulParam) -+{ -+ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) ulParam; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prP2pFsmInfo != NULL)); -+ -+ DBGLOG(P2P, TRACE, "P2P FSM Timeout Event\n"); -+ -+ switch (prP2pFsmInfo->eCurrentState) { -+ case P2P_STATE_IDLE: -+ { -+ P_P2P_CHNL_REQ_INFO_T prChnlReqInfo = &prP2pFsmInfo->rChnlReqInfo; -+ -+ if (prChnlReqInfo->fgIsChannelRequested) { -+ p2pFuncReleaseCh(prAdapter, prChnlReqInfo); -+ } else if (IS_NET_PWR_STATE_IDLE(prAdapter, NETWORK_TYPE_P2P_INDEX)) { -+ UNSET_NET_ACTIVE(prAdapter, NETWORK_TYPE_P2P_INDEX); -+ nicDeactivateNetwork(prAdapter, NETWORK_TYPE_P2P_INDEX); -+ } -+ -+ } -+ break; -+ -+/* case P2P_STATE_SCAN: */ -+/* break; */ -+/* case P2P_STATE_AP_CHANNEL_DETECT: */ -+/* break; */ -+/* case P2P_STATE_REQING_CHANNEL: */ -+/* break; */ -+ case P2P_STATE_CHNL_ON_HAND: -+ switch (prP2pFsmInfo->eListenExted) { -+ case P2P_DEV_NOT_EXT_LISTEN: -+ case P2P_DEV_EXT_LISTEN_WAITFOR_TIMEOUT: -+ DBGLOG(P2P, INFO, "p2p timeout, state==P2P_STATE_CHNL_ON_HAND, eListenExted: %d\n", -+ prP2pFsmInfo->eListenExted); -+ p2pFsmStateTransition(prAdapter, prP2pFsmInfo, P2P_STATE_IDLE); -+ prP2pFsmInfo->eListenExted = P2P_DEV_NOT_EXT_LISTEN; -+ break; -+ case P2P_DEV_EXT_LISTEN_ING: -+ DBGLOG(P2P, INFO, "p2p timeout, state==P2P_STATE_CHNL_ON_HAND, eListenExted: %d\n", -+ prP2pFsmInfo->eListenExted); -+ p2pFsmStateTransition(prAdapter, prP2pFsmInfo, P2P_STATE_CHNL_ON_HAND); -+ prP2pFsmInfo->eListenExted = P2P_DEV_EXT_LISTEN_WAITFOR_TIMEOUT; -+ break; -+ default: -+ ASSERT(FALSE); -+ DBGLOG(P2P, ERROR, -+ "Current P2P State %d is unexpected for FSM timeout event.\n", -+ prP2pFsmInfo->eCurrentState); -+ } -+ break; -+/* case P2P_STATE_GC_JOIN: */ -+/* break; */ -+ default: -+ break; -+ } -+ -+ } while (FALSE); -+ -+} /* p2pFsmRunEventFsmTimeout */ -+ -+VOID p2pFsmRunEventMgmtFrameTx(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) -+{ -+ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; -+ P_MSG_P2P_MGMT_TX_REQUEST_T prMgmtTxMsg = (P_MSG_P2P_MGMT_TX_REQUEST_T) NULL; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prMsgHdr != NULL)); -+ -+ DBGLOG(P2P, TRACE, "p2pFsmRunEventMgmtFrameTx\n"); -+ -+ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; -+ -+ if (prP2pFsmInfo == NULL) -+ break; -+ -+ prMgmtTxMsg = (P_MSG_P2P_MGMT_TX_REQUEST_T) prMsgHdr; -+ -+ p2pFuncTxMgmtFrame(prAdapter, -+ &prP2pFsmInfo->rMgmtTxInfo, prMgmtTxMsg->prMgmtMsduInfo, prMgmtTxMsg->u8Cookie); -+ -+ } while (FALSE); -+ -+ if (prMsgHdr) -+ cnmMemFree(prAdapter, prMsgHdr); -+ -+ return; -+ -+} /* p2pFsmRunEventMgmtTx */ -+ -+VOID p2pFsmRunEventStartAP(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) -+{ -+ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; -+ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; -+ P_MSG_P2P_START_AP_T prP2pStartAPMsg = (P_MSG_P2P_START_AP_T) NULL; -+ P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo = (P_P2P_SPECIFIC_BSS_INFO_T) NULL; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prMsgHdr != NULL)); -+ -+ DBGLOG(P2P, TRACE, "p2pFsmRunEventStartAP\n"); -+ -+ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; -+ -+ if (prP2pFsmInfo == NULL) -+ break; -+ -+ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); -+ prP2pStartAPMsg = (P_MSG_P2P_START_AP_T) prMsgHdr; -+ prP2pSpecificBssInfo = prAdapter->rWifiVar.prP2pSpecificBssInfo; -+ -+ if (prP2pStartAPMsg->u4BcnInterval) { -+ DBGLOG(P2P, TRACE, "Beacon interval updated to :%u\n", prP2pStartAPMsg->u4BcnInterval); -+ prP2pBssInfo->u2BeaconInterval = (UINT_16) prP2pStartAPMsg->u4BcnInterval; -+ } else if (prP2pBssInfo->u2BeaconInterval == 0) { -+ prP2pBssInfo->u2BeaconInterval = DOT11_BEACON_PERIOD_DEFAULT; -+ } -+ -+ if (prP2pStartAPMsg->u4DtimPeriod) { -+ DBGLOG(P2P, TRACE, "DTIM interval updated to :%u\n", prP2pStartAPMsg->u4DtimPeriod); -+ prP2pBssInfo->ucDTIMPeriod = (UINT_8) prP2pStartAPMsg->u4DtimPeriod; -+ } else if (prP2pBssInfo->ucDTIMPeriod == 0) { -+ prP2pBssInfo->ucDTIMPeriod = DOT11_DTIM_PERIOD_DEFAULT; -+ } -+ -+ if (prP2pStartAPMsg->u2SsidLen != 0) { -+ kalMemCopy(prP2pBssInfo->aucSSID, prP2pStartAPMsg->aucSsid, prP2pStartAPMsg->u2SsidLen); -+ kalMemCopy(prP2pSpecificBssInfo->aucGroupSsid, prP2pStartAPMsg->aucSsid, -+ prP2pStartAPMsg->u2SsidLen); -+ prP2pBssInfo->ucSSIDLen = prP2pSpecificBssInfo->u2GroupSsidLen = prP2pStartAPMsg->u2SsidLen; -+ } -+ -+ prP2pBssInfo->eHiddenSsidType = prP2pStartAPMsg->ucHiddenSsidType; -+ -+ /* TODO: JB */ -+ /* Privacy & inactive timeout. */ -+ -+ if ((prP2pBssInfo->eCurrentOPMode != OP_MODE_ACCESS_POINT) || -+ (prP2pBssInfo->eIntendOPMode != OP_MODE_NUM)) { -+ UINT_8 ucPreferedChnl = 0; -+ ENUM_BAND_T eBand = BAND_NULL; -+ ENUM_CHNL_EXT_T eSco = CHNL_EXT_SCN; -+ ENUM_P2P_STATE_T eNextState = P2P_STATE_SCAN; -+ P_P2P_CONNECTION_SETTINGS_T prP2pConnSettings = prAdapter->rWifiVar.prP2PConnSettings; -+ -+ if (prP2pFsmInfo->eCurrentState != P2P_STATE_SCAN && -+ prP2pFsmInfo->eCurrentState != P2P_STATE_IDLE) { -+ /* Make sure the state is in IDLE state. */ -+ p2pFsmRunEventAbort(prAdapter, prP2pFsmInfo); -+ } -+ prAdapter->rWifiVar.prP2pFsmInfo->rScanReqInfo.fgIsGOInitialDone = 0; -+ DBGLOG(P2P, INFO, -+ "NFC:p2pFsmRunEventStartAP,fgIsGOInitialDone[%d]\n", -+ prAdapter->rWifiVar.prP2pFsmInfo->rScanReqInfo.fgIsGOInitialDone); -+ -+ /* 20120118: Moved to p2pFuncSwitchOPMode(). */ -+ /* SET_NET_ACTIVE(prAdapter, NETWORK_TYPE_P2P_INDEX); */ -+ -+ /* Leave IDLE state. */ -+ SET_NET_PWR_STATE_ACTIVE(prAdapter, NETWORK_TYPE_P2P_INDEX); -+ -+ /* sync with firmware */ -+ /* DBGLOG(P2P, INFO, ("Activate P2P Network.\n")); */ -+ /* nicActivateNetwork(prAdapter, NETWORK_TYPE_P2P_INDEX); */ -+ -+ /* Key to trigger P2P FSM to allocate channel for AP mode. */ -+ prP2pBssInfo->eIntendOPMode = OP_MODE_ACCESS_POINT; -+ -+ /* Sparse Channel to decide which channel to use. */ -+ if ((cnmPreferredChannel(prAdapter, -+ &eBand, -+ &ucPreferedChnl, -+ &eSco) == FALSE) && (prP2pConnSettings->ucOperatingChnl == 0)) { -+ /* Sparse Channel Detection using passive mode. */ -+ eNextState = P2P_STATE_AP_CHANNEL_DETECT; -+ } else { -+ P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo = -+ prAdapter->rWifiVar.prP2pSpecificBssInfo; -+ P_P2P_CHNL_REQ_INFO_T prChnlReqInfo = &prP2pFsmInfo->rChnlReqInfo; -+ -+#if 1 -+ /* 2012-01-27: frog - Channel set from upper layer is the first priority. */ -+ /* Because the channel & beacon is decided by p2p_supplicant. */ -+ if (prP2pConnSettings->ucOperatingChnl != 0) { -+ prP2pSpecificBssInfo->ucPreferredChannel = prP2pConnSettings->ucOperatingChnl; -+ prP2pSpecificBssInfo->eRfBand = prP2pConnSettings->eBand; -+ } -+ -+ else { -+ ASSERT(ucPreferedChnl != 0); -+ prP2pSpecificBssInfo->ucPreferredChannel = ucPreferedChnl; -+ prP2pSpecificBssInfo->eRfBand = eBand; -+ } -+#else -+ if (ucPreferedChnl) { -+ prP2pSpecificBssInfo->ucPreferredChannel = ucPreferedChnl; -+ prP2pSpecificBssInfo->eRfBand = eBand; -+ } else { -+ ASSERT(prP2pConnSettings->ucOperatingChnl != 0); -+ prP2pSpecificBssInfo->ucPreferredChannel = prP2pConnSettings->ucOperatingChnl; -+ prP2pSpecificBssInfo->eRfBand = prP2pConnSettings->eBand; -+ } -+ -+#endif -+ prChnlReqInfo->ucReqChnlNum = prP2pSpecificBssInfo->ucPreferredChannel; -+ prChnlReqInfo->eBand = prP2pSpecificBssInfo->eRfBand; -+ prChnlReqInfo->eChannelReqType = CHANNEL_REQ_TYPE_GO_START_BSS; -+ -+ DBGLOG(P2P, INFO, "p2pFsmRunEventStartAP GO Scan\n"); -+ } -+ -+ /* If channel is specified, use active scan to shorten the scan time. */ -+ p2pFsmStateTransition(prAdapter, prAdapter->rWifiVar.prP2pFsmInfo, eNextState); -+ } -+ -+ } while (FALSE); -+ -+ if (prMsgHdr) -+ cnmMemFree(prAdapter, prMsgHdr); -+ -+} /* p2pFsmRunEventStartAP */ -+ -+VOID p2pFsmRunEventNetDeviceRegister(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) -+{ -+ P_MSG_P2P_NETDEV_REGISTER_T prNetDevRegisterMsg = (P_MSG_P2P_NETDEV_REGISTER_T) NULL; -+ -+ do { -+ -+ ASSERT_BREAK((prAdapter != NULL) && (prMsgHdr != NULL)); -+ -+ DBGLOG(P2P, TRACE, "p2pFsmRunEventNetDeviceRegister\n"); -+ -+ prNetDevRegisterMsg = (P_MSG_P2P_NETDEV_REGISTER_T) prMsgHdr; -+ -+ if (prNetDevRegisterMsg->fgIsEnable) { -+ p2pSetMode((prNetDevRegisterMsg->ucMode == 1) ? TRUE : FALSE); -+ -+ if (p2pLaunch(prAdapter->prGlueInfo)) -+ ASSERT(prAdapter->fgIsP2PRegistered); -+ -+ } else { -+ if (prAdapter->fgIsP2PRegistered) -+ p2pRemove(prAdapter->prGlueInfo); -+ -+ } -+ } while (FALSE); -+ -+ if (prMsgHdr) -+ cnmMemFree(prAdapter, prMsgHdr); -+ -+} /* p2pFsmRunEventNetDeviceRegister */ -+ -+VOID p2pFsmRunEventUpdateMgmtFrame(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) -+{ -+ P_MSG_P2P_MGMT_FRAME_UPDATE_T prP2pMgmtFrameUpdateMsg = (P_MSG_P2P_MGMT_FRAME_UPDATE_T) NULL; -+ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prMsgHdr != NULL)); -+ -+ DBGLOG(P2P, TRACE, "p2pFsmRunEventUpdateMgmtFrame\n"); -+ -+ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; -+ -+ if (prP2pFsmInfo == NULL) -+ break; -+ -+ prP2pMgmtFrameUpdateMsg = (P_MSG_P2P_MGMT_FRAME_UPDATE_T) prMsgHdr; -+ -+ switch (prP2pMgmtFrameUpdateMsg->eBufferType) { -+ case ENUM_FRAME_TYPE_EXTRA_IE_BEACON: -+ break; -+ case ENUM_FRAME_TYPE_EXTRA_IE_ASSOC_RSP: -+ break; -+ case ENUM_FRAME_TYPE_EXTRA_IE_PROBE_RSP: -+ break; -+ case ENUM_FRAME_TYPE_PROBE_RSP_TEMPLATE: -+ break; -+ case ENUM_FRAME_TYPE_BEACON_TEMPLATE: -+ break; -+ default: -+ break; -+ } -+ -+ } while (FALSE); -+ -+ if (prMsgHdr) -+ cnmMemFree(prAdapter, prMsgHdr); -+ -+} /* p2pFsmRunEventUpdateMgmtFrame */ -+ -+VOID p2pFsmRunEventBeaconUpdate(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) -+{ -+ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; -+ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; -+ P_MSG_P2P_BEACON_UPDATE_T prBcnUpdateMsg = (P_MSG_P2P_BEACON_UPDATE_T) NULL; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prMsgHdr != NULL)); -+ -+ DBGLOG(P2P, TRACE, "p2pFsmRunEventBeaconUpdate\n"); -+ -+ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; -+ -+ if (prP2pFsmInfo == NULL) -+ break; -+ -+ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); -+ prBcnUpdateMsg = (P_MSG_P2P_BEACON_UPDATE_T) prMsgHdr; -+ -+ p2pFuncBeaconUpdate(prAdapter, -+ prP2pBssInfo, -+ &prP2pFsmInfo->rBcnContentInfo, -+ prBcnUpdateMsg->pucBcnHdr, -+ prBcnUpdateMsg->u4BcnHdrLen, -+ prBcnUpdateMsg->pucBcnBody, prBcnUpdateMsg->u4BcnBodyLen); -+ -+ if ((prP2pBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT) && -+ (prP2pBssInfo->eIntendOPMode == OP_MODE_NUM)) { -+ /* AP is created, Beacon Update. */ -+ /* nicPmIndicateBssAbort(prAdapter, NETWORK_TYPE_P2P_INDEX); */ -+ -+ bssUpdateBeaconContent(prAdapter, NETWORK_TYPE_P2P_INDEX); -+ -+ /* nicPmIndicateBssCreated(prAdapter, NETWORK_TYPE_P2P_INDEX); */ -+ } -+ -+ } while (FALSE); -+ -+ if (prMsgHdr) -+ cnmMemFree(prAdapter, prMsgHdr); -+ -+} /* p2pFsmRunEventBeaconUpdate */ -+ -+VOID p2pFsmRunEventStopAP(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) -+{ -+ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL)); -+ -+ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); -+ -+ DBGLOG(P2P, TRACE, "p2pFsmRunEventStopAP\n"); -+ -+ if ((prP2pBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT) -+ && (prP2pBssInfo->eIntendOPMode == OP_MODE_NUM)) { -+ /* AP is created, Beacon Update. */ -+ -+ p2pFuncDissolve(prAdapter, prP2pBssInfo, TRUE, REASON_CODE_DEAUTH_LEAVING_BSS); -+ -+ DBGLOG(P2P, TRACE, "Stop Beaconing\n"); -+ nicPmIndicateBssAbort(prAdapter, NETWORK_TYPE_P2P_INDEX); -+ -+ /* Reset RLM related field of BSSINFO. */ -+ rlmBssAborted(prAdapter, prP2pBssInfo); -+ } -+ /* 20120118: Moved to p2pFuncSwitchOPMode(). */ -+ /* UNSET_NET_ACTIVE(prAdapter, NETWORK_TYPE_P2P_INDEX); */ -+ -+ /* Enter IDLE state. */ -+ SET_NET_PWR_STATE_IDLE(prAdapter, NETWORK_TYPE_P2P_INDEX); -+ -+ DBGLOG(P2P, INFO, "Re activate P2P Network.\n"); -+ nicDeactivateNetwork(prAdapter, NETWORK_TYPE_P2P_INDEX); -+ -+ nicActivateNetwork(prAdapter, NETWORK_TYPE_P2P_INDEX); -+ -+#if CFG_SUPPORT_WFD -+ p2pFsmRunEventWfdSettingUpdate(prAdapter, NULL); -+#endif -+ -+ /* p2pFsmRunEventAbort(prAdapter, prAdapter->rWifiVar.prP2pFsmInfo); */ -+ p2pFsmStateTransition(prAdapter, prAdapter->rWifiVar.prP2pFsmInfo, P2P_STATE_IDLE); -+ -+ } while (FALSE); -+ -+ if (prMsgHdr) -+ cnmMemFree(prAdapter, prMsgHdr); -+ -+} /* p2pFsmRunEventStopAP */ -+ -+VOID p2pFsmRunEventConnectionRequest(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) -+{ -+ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; -+ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; -+ P_P2P_CHNL_REQ_INFO_T prChnlReqInfo = (P_P2P_CHNL_REQ_INFO_T) NULL; -+ P_MSG_P2P_CONNECTION_REQUEST_T prConnReqMsg = (P_MSG_P2P_CONNECTION_REQUEST_T) NULL; -+ P_P2P_CONNECTION_REQ_INFO_T prConnReqInfo = (P_P2P_CONNECTION_REQ_INFO_T) NULL; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prMsgHdr != NULL)); -+ -+ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); -+ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; -+ -+ if (prP2pFsmInfo == NULL) -+ break; -+ -+ prConnReqMsg = (P_MSG_P2P_CONNECTION_REQUEST_T) prMsgHdr; -+ -+ prConnReqInfo = &(prP2pFsmInfo->rConnReqInfo); -+ prChnlReqInfo = &(prP2pFsmInfo->rChnlReqInfo); -+ -+ DBGLOG(P2P, TRACE, "p2pFsmRunEventConnectionRequest\n"); -+ -+ if (prP2pBssInfo->eCurrentOPMode != OP_MODE_INFRASTRUCTURE) -+ break; -+ -+ SET_NET_PWR_STATE_ACTIVE(prAdapter, NETWORK_TYPE_P2P_INDEX); -+ -+ /* Make sure the state is in IDLE state. */ -+ p2pFsmRunEventAbort(prAdapter, prP2pFsmInfo); -+ -+ /* Update connection request information. */ -+ prConnReqInfo->fgIsConnRequest = TRUE; -+ COPY_MAC_ADDR(prConnReqInfo->aucBssid, prConnReqMsg->aucBssid); -+ kalMemCopy(&(prConnReqInfo->rSsidStruct), &(prConnReqMsg->rSsid), sizeof(P2P_SSID_STRUCT_T)); -+ kalMemCopy(prConnReqInfo->aucIEBuf, prConnReqMsg->aucIEBuf, prConnReqMsg->u4IELen); -+ prConnReqInfo->u4BufLength = prConnReqMsg->u4IELen; -+ -+ /* Find BSS Descriptor first. */ -+ prP2pFsmInfo->prTargetBss = scanP2pSearchDesc(prAdapter, prP2pBssInfo, prConnReqInfo); -+ -+ if (prP2pFsmInfo->prTargetBss == NULL) { -+ /* Update scan parameter... to scan target device. */ -+ P_P2P_SCAN_REQ_INFO_T prScanReqInfo = &(prP2pFsmInfo->rScanReqInfo); -+ -+ DBGLOG(P2P, INFO, "p2pFsmRunEventConnectionRequest,Trigger New Scan\n"); -+ -+ prScanReqInfo->ucNumChannelList = 1; -+ prScanReqInfo->eScanType = SCAN_TYPE_ACTIVE_SCAN; -+ prScanReqInfo->eChannelSet = SCAN_CHANNEL_SPECIFIED; -+ prScanReqInfo->arScanChannelList[0].ucChannelNum = prConnReqMsg->rChannelInfo.ucChannelNum; -+ kalMemCopy(&(prScanReqInfo->rSsidStruct), &(prConnReqMsg->rSsid), sizeof(P2P_SSID_STRUCT_T)); -+ prScanReqInfo->u4BufLength = 0; /* Prevent other P2P ID in IE. */ -+ prScanReqInfo->fgIsAbort = TRUE; -+ -+ p2pFsmStateTransition(prAdapter, prP2pFsmInfo, P2P_STATE_SCAN); -+ } else { -+ prChnlReqInfo->u8Cookie = 0; -+ prChnlReqInfo->ucReqChnlNum = prConnReqMsg->rChannelInfo.ucChannelNum; -+ prChnlReqInfo->eBand = prConnReqMsg->rChannelInfo.eBand; -+ prChnlReqInfo->eChnlSco = prConnReqMsg->eChnlSco; -+ prChnlReqInfo->u4MaxInterval = AIS_JOIN_CH_REQUEST_INTERVAL; -+ prChnlReqInfo->eChannelReqType = CHANNEL_REQ_TYPE_GC_JOIN_REQ; -+ DBGLOG(P2P, INFO, "p2pFsmRunEventConnectionRequest, Report the Connecting BSS Again.\n"); -+ p2pFsmStateTransition(prAdapter, prP2pFsmInfo, P2P_STATE_REQING_CHANNEL); -+ } -+ -+ } while (FALSE); -+ -+ if (prMsgHdr) -+ cnmMemFree(prAdapter, prMsgHdr); -+ -+ return; -+ -+} /* p2pFsmRunEventConnectionRequest */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is used to handle Connection Request from Supplicant. -+* -+* \param[in] prAdapter Pointer of ADAPTER_T -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID p2pFsmRunEventConnectionAbort(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) -+{ -+ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; -+ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; -+ P_MSG_P2P_CONNECTION_ABORT_T prDisconnMsg = (P_MSG_P2P_CONNECTION_ABORT_T) NULL; -+ /* P_STA_RECORD_T prTargetStaRec = (P_STA_RECORD_T)NULL; */ -+ -+ do { -+ -+ ASSERT_BREAK((prAdapter != NULL) && (prMsgHdr != NULL)); -+ -+ DBGLOG(P2P, TRACE, "p2pFsmRunEventConnectionAbort: Connection Abort.\n"); -+ -+ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; -+ -+ if (prP2pFsmInfo == NULL) -+ break; -+ -+ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); -+ -+ prDisconnMsg = (P_MSG_P2P_CONNECTION_ABORT_T) prMsgHdr; -+ -+ switch (prP2pBssInfo->eCurrentOPMode) { -+ case OP_MODE_INFRASTRUCTURE: -+ { -+ UINT_8 aucBCBSSID[] = BC_BSSID; -+ -+ if (!prP2pBssInfo->prStaRecOfAP) { -+ DBGLOG(P2P, TRACE, "GO's StaRec is NULL\n"); -+ break; -+ } -+ if (UNEQUAL_MAC_ADDR(prP2pBssInfo->prStaRecOfAP->aucMacAddr, prDisconnMsg->aucTargetID) -+ && UNEQUAL_MAC_ADDR(prDisconnMsg->aucTargetID, aucBCBSSID)) { -+ DBGLOG(P2P, TRACE, -+ "Unequal MAC ADDR [ %pM : %pM ]\n", -+ prP2pBssInfo->prStaRecOfAP->aucMacAddr, -+ prDisconnMsg->aucTargetID); -+ break; -+ } -+ -+ kalP2PGCIndicateConnectionStatus(prAdapter->prGlueInfo, -+ NULL, NULL, 0, 0, -+ WLAN_STATUS_MEDIA_DISCONNECT_LOCALLY); -+ -+ /* Stop rejoin timer if it is started. */ -+ /* TODO: If it has. */ -+ -+ p2pFuncDisconnect(prAdapter, prP2pBssInfo->prStaRecOfAP, prDisconnMsg->fgSendDeauth, -+ prDisconnMsg->u2ReasonCode); -+ -+ /* prTargetStaRec = prP2pBssInfo->prStaRecOfAP; */ -+ -+ /* Fix possible KE when RX Beacon & call nicPmIndicateBssConnected(). */ -+ /* hit prStaRecOfAP == NULL. */ -+ p2pChangeMediaState(prAdapter, PARAM_MEDIA_STATE_DISCONNECTED); -+ -+ prP2pBssInfo->prStaRecOfAP = NULL; -+ -+ SET_NET_PWR_STATE_IDLE(prAdapter, NETWORK_TYPE_P2P_INDEX); -+ -+ p2pFsmStateTransition(prAdapter, prP2pFsmInfo, P2P_STATE_IDLE); -+ -+ } -+ break; -+ case OP_MODE_ACCESS_POINT: -+ { -+ P_LINK_T prStaRecOfClientList = &prP2pBssInfo->rStaRecOfClientList; -+ /* Search specific client device, and disconnect. */ -+ /* 1. Send deauthentication frame. */ -+ /* 2. Indication: Device disconnect. */ -+ P_LINK_ENTRY_T prLinkEntry = (P_LINK_ENTRY_T) NULL; -+ P_STA_RECORD_T prCurrStaRec = (P_STA_RECORD_T) NULL; -+ -+ DBGLOG(P2P, TRACE, -+ "Disconnecting with Target ID: %pM\n", -+ prDisconnMsg->aucTargetID); -+ -+ LINK_FOR_EACH(prLinkEntry, prStaRecOfClientList) { -+ prCurrStaRec = LINK_ENTRY(prLinkEntry, STA_RECORD_T, rLinkEntry); -+ -+ ASSERT(prCurrStaRec); -+ -+ if (EQUAL_MAC_ADDR(prCurrStaRec->aucMacAddr, prDisconnMsg->aucTargetID)) { -+ -+ DBGLOG(P2P, TRACE, -+ "Disconnecting: %pM\n", -+ prCurrStaRec->aucMacAddr); -+ -+ /* Remove STA from client list. */ -+ LINK_REMOVE_KNOWN_ENTRY(prStaRecOfClientList, -+ &prCurrStaRec->rLinkEntry); -+ -+ /* Glue layer indication. */ -+ /* kalP2PGOStationUpdate(prAdapter->prGlueInfo, prCurrStaRec, FALSE); */ -+ -+ /* Send deauth & do indication. */ -+ p2pFuncDisconnect(prAdapter, prCurrStaRec, prDisconnMsg->fgSendDeauth, -+ prDisconnMsg->u2ReasonCode); -+ -+ /* prTargetStaRec = prCurrStaRec; */ -+ -+ break; -+ } -+ } -+ -+ } -+ break; -+ case OP_MODE_P2P_DEVICE: -+ default: -+ ASSERT(FALSE); -+ break; -+ } -+ -+ } while (FALSE); -+ -+ /* 20120830 moved into p2pFuncDisconnect() */ -+ /* if ((!prDisconnMsg->fgSendDeauth) && (prTargetStaRec)) { */ -+ /* cnmStaRecFree(prAdapter, prTargetStaRec, TRUE); */ -+ /* } */ -+ -+ if (prMsgHdr) -+ cnmMemFree(prAdapter, prMsgHdr); -+ -+} /* p2pFsmRunEventConnectionAbort */ -+ -+VOID p2pFsmRunEventDissolve(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) -+{ -+ -+ /* TODO: */ -+ -+ DBGLOG(P2P, TRACE, "p2pFsmRunEventDissolve\n"); -+ -+ if (prMsgHdr) -+ cnmMemFree(prAdapter, prMsgHdr); -+ -+} -+ -+WLAN_STATUS -+p2pFsmRunEventDeauthTxDone(IN P_ADAPTER_T prAdapter, -+ IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus) -+{ -+ -+ P_STA_RECORD_T prStaRec = (P_STA_RECORD_T) NULL; -+ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; -+ ENUM_PARAM_MEDIA_STATE_T eOriMediaStatus; -+ -+ do { -+ -+ ASSERT_BREAK((prAdapter != NULL) && (prMsduInfo != NULL)); -+ -+ DBGLOG(P2P, INFO, "Deauth TX Done Status: %d, seqNo %d\n", -+ rTxDoneStatus, prMsduInfo->ucTxSeqNum); -+ -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); -+ -+ if (prStaRec == NULL) { -+ DBGLOG(P2P, TRACE, "Station Record NULL, Index:%d\n", prMsduInfo->ucStaRecIndex); -+ break; -+ } -+ -+ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); -+ eOriMediaStatus = prP2pBssInfo->eConnectionState; -+ /* Change station state. */ -+ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); -+ -+ /* Reset Station Record Status. */ -+ p2pFuncResetStaRecStatus(prAdapter, prStaRec); -+ -+ bssRemoveStaRecFromClientList(prAdapter, prP2pBssInfo, prStaRec); -+ -+ /**/ cnmStaRecFree(prAdapter, prStaRec, TRUE); -+ -+ if ((prP2pBssInfo->eCurrentOPMode != OP_MODE_ACCESS_POINT) || -+ (prP2pBssInfo->rStaRecOfClientList.u4NumElem == 0)) { -+ DBGLOG(P2P, TRACE, "No More Client, Media Status DISCONNECTED\n"); -+ p2pChangeMediaState(prAdapter, PARAM_MEDIA_STATE_DISCONNECTED); -+ } -+ -+ /* Because the eConnectionState is changed before Deauth TxDone. Dont Check eConnectionState */ -+ /* if (eOriMediaStatus != prP2pBssInfo->eConnectionState) { */ -+ /* Update Disconnected state to FW. */ -+ nicUpdateBss(prAdapter, NETWORK_TYPE_P2P_INDEX); -+ /* } */ -+ -+ } while (FALSE); -+ -+ return WLAN_STATUS_SUCCESS; -+} /* p2pFsmRunEventDeauthTxDone */ -+ -+WLAN_STATUS -+p2pFsmRunEventMgmtFrameTxDone(IN P_ADAPTER_T prAdapter, -+ IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus) -+{ -+ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; -+ P_P2P_MGMT_TX_REQ_INFO_T prMgmtTxReqInfo = (P_P2P_MGMT_TX_REQ_INFO_T) NULL; -+ BOOLEAN fgIsSuccess = FALSE; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prMsduInfo != NULL)); -+ -+ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; -+ prMgmtTxReqInfo = &(prP2pFsmInfo->rMgmtTxInfo); -+ -+ if (rTxDoneStatus != TX_RESULT_SUCCESS) { -+ DBGLOG(P2P, INFO, "Mgmt Frame TX Fail, Status: %d, seq NO. %d, Cookie: 0x%llx\n", -+ rTxDoneStatus, prMsduInfo->ucTxSeqNum, prMgmtTxReqInfo->u8Cookie); -+ } else { -+ fgIsSuccess = TRUE; -+ DBGLOG(P2P, TRACE, "Mgmt Frame TX Done.\n"); -+ } -+ -+ if (prMgmtTxReqInfo->prMgmtTxMsdu == prMsduInfo) { -+ kalP2PIndicateMgmtTxStatus(prAdapter->prGlueInfo, -+ prMgmtTxReqInfo->u8Cookie, -+ fgIsSuccess, -+ prMsduInfo->prPacket, (UINT_32) prMsduInfo->u2FrameLength); -+ -+ prMgmtTxReqInfo->prMgmtTxMsdu = NULL; -+ } -+ -+ } while (FALSE); -+ -+ return WLAN_STATUS_SUCCESS; -+ -+} /* p2pFsmRunEventMgmtFrameTxDone */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is called when JOIN complete message event is received from SAA. -+* -+* \param[in] prAdapter Pointer of ADAPTER_T -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID p2pFsmRunEventJoinComplete(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) -+{ -+ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; -+ P_P2P_JOIN_INFO_T prJoinInfo = (P_P2P_JOIN_INFO_T) NULL; -+ P_MSG_JOIN_COMP_T prJoinCompMsg = (P_MSG_JOIN_COMP_T) NULL; -+ P_SW_RFB_T prAssocRspSwRfb = (P_SW_RFB_T) NULL; -+ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; -+ -+ ASSERT_BREAK((prAdapter != NULL) && (prMsgHdr != NULL)); -+ DBGLOG(P2P, TRACE, "P2P Join Complete\n"); -+ -+ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; -+ if (prP2pFsmInfo == NULL) { -+ if (prMsgHdr) -+ cnmMemFree(prAdapter, prMsgHdr); -+ return; -+ } -+ -+ prJoinInfo = &(prP2pFsmInfo->rJoinInfo); -+ if (prMsgHdr == NULL) -+ return; -+ prJoinCompMsg = (P_MSG_JOIN_COMP_T) prMsgHdr; -+ prAssocRspSwRfb = prJoinCompMsg->prSwRfb; -+ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); -+ -+ if (prP2pBssInfo->eCurrentOPMode == OP_MODE_INFRASTRUCTURE) { -+ P_STA_RECORD_T prStaRec = (P_STA_RECORD_T) NULL; -+ -+ prStaRec = prJoinCompMsg->prStaRec; -+ -+ /* Check SEQ NUM */ -+ if (prJoinCompMsg->ucSeqNum == prJoinInfo->ucSeqNumOfReqMsg) { -+ ASSERT(prStaRec == prJoinInfo->prTargetStaRec); -+ prJoinInfo->fgIsJoinComplete = TRUE; -+ -+ if (prJoinCompMsg->rJoinStatus == WLAN_STATUS_SUCCESS) { -+ -+ /* 4 <1.1> Change FW's Media State immediately. */ -+ p2pChangeMediaState(prAdapter, PARAM_MEDIA_STATE_CONNECTED); -+ -+ /* 4 <1.2> Deactivate previous AP's STA_RECORD_T in Driver if have. */ -+ if ((prP2pBssInfo->prStaRecOfAP) && (prP2pBssInfo->prStaRecOfAP != prStaRec)) { -+ cnmStaRecChangeState(prAdapter, prP2pBssInfo->prStaRecOfAP, -+ STA_STATE_1); -+ -+ cnmStaRecFree(prAdapter, prP2pBssInfo->prStaRecOfAP, TRUE); -+ -+ prP2pBssInfo->prStaRecOfAP = NULL; -+ } -+ /* 4 <1.3> Update BSS_INFO_T */ -+ p2pFuncUpdateBssInfoForJOIN(prAdapter, prP2pFsmInfo->prTargetBss, prStaRec, -+ prAssocRspSwRfb); -+ -+ /* 4 <1.4> Activate current AP's STA_RECORD_T in Driver. */ -+ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_3); -+ DBGLOG(P2P, INFO, "P2P GC Join Success\n"); -+ -+#if CFG_SUPPORT_P2P_RSSI_QUERY -+ /* <1.5> Update RSSI if necessary */ -+ nicUpdateRSSI(prAdapter, NETWORK_TYPE_P2P_INDEX, -+ (INT_8) (RCPI_TO_dBm(prStaRec->ucRCPI)), 0); -+#endif -+ -+ /* 4 <1.6> Indicate Connected Event to Host immediately. */ -+ /* Require BSSID, Association ID, Beacon Interval.. from AIS_BSS_INFO_T */ -+ /* p2pIndicationOfMediaStateToHost(prAdapter, PARAM_MEDIA_STATE_CONNECTED, */ -+ /* prStaRec->aucMacAddr); */ -+ if (prP2pFsmInfo->prTargetBss) -+ scanReportBss2Cfg80211(prAdapter, OP_MODE_P2P_DEVICE, -+ prP2pFsmInfo->prTargetBss); -+ kalP2PGCIndicateConnectionStatus(prAdapter->prGlueInfo, -+ &prP2pFsmInfo->rConnReqInfo, -+ prJoinInfo->aucIEBuf, prJoinInfo->u4BufLength, -+ prStaRec->u2StatusCode, -+ WLAN_STATUS_MEDIA_CONNECT); -+ -+ } else { -+ /* Join Fail */ -+ /* 4 <2.1> Redo JOIN process with other Auth Type if possible */ -+ if (p2pFuncRetryJOIN(prAdapter, prStaRec, prJoinInfo) == FALSE) { -+ P_BSS_DESC_T prBssDesc; -+ -+ /* Increase Failure Count */ -+ prStaRec->ucJoinFailureCount++; -+ -+ prBssDesc = prP2pFsmInfo->prTargetBss; -+ -+ ASSERT(prBssDesc); -+ ASSERT(prBssDesc->fgIsConnecting); -+ -+ prBssDesc->fgIsConnecting = FALSE; -+ -+ if (prStaRec->ucJoinFailureCount >= 3) { -+ -+ kalP2PGCIndicateConnectionStatus(prAdapter->prGlueInfo, -+ &prP2pFsmInfo->rConnReqInfo, -+ prJoinInfo->aucIEBuf, -+ prJoinInfo->u4BufLength, -+ prStaRec->u2StatusCode, -+ WLAN_STATUS_MEDIA_CONNECT); -+ } else { -+ /* Sometime the GO is not ready to response auth. */ -+ /* Connect it again */ -+ prP2pFsmInfo->prTargetBss = NULL; -+ } -+ DBGLOG(P2P, INFO, "P2P GC Join Failed\n"); -+ -+ } -+ -+ } -+ } -+ } -+ -+ if (prAssocRspSwRfb) -+ nicRxReturnRFB(prAdapter, prAssocRspSwRfb); -+ -+ if (prP2pFsmInfo->eCurrentState == P2P_STATE_GC_JOIN) { -+ -+ if (prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX].eConnectionState == -+ PARAM_MEDIA_STATE_CONNECTED) { -+ /* Return to IDLE state. */ -+ p2pFsmStateTransition(prAdapter, prP2pFsmInfo, P2P_STATE_IDLE); -+ } else { -+ /* p2pFsmStateTransition(prAdapter, prP2pFsmInfo, P2P_STATE_IDLE); */ -+ /* one more scan */ -+ p2pFsmStateTransition(prAdapter, prP2pFsmInfo, P2P_STATE_SCAN); -+ } -+ } -+ -+ if (prMsgHdr) -+ cnmMemFree(prAdapter, prMsgHdr); -+ -+} /* p2pFsmRunEventJoinComplete */ -+ -+VOID p2pFsmRunEventMgmtFrameRegister(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) -+{ -+ P_MSG_P2P_MGMT_FRAME_REGISTER_T prMgmtFrameRegister = (P_MSG_P2P_MGMT_FRAME_REGISTER_T) NULL; -+ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prMsgHdr != NULL)); -+ -+ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; -+ -+ if (prP2pFsmInfo == NULL) -+ break; -+ -+ prMgmtFrameRegister = (P_MSG_P2P_MGMT_FRAME_REGISTER_T) prMsgHdr; -+ -+ p2pFuncMgmtFrameRegister(prAdapter, -+ prMgmtFrameRegister->u2FrameType, -+ prMgmtFrameRegister->fgIsRegister, &prP2pFsmInfo->u4P2pPacketFilter); -+ -+ } while (FALSE); -+ -+ if (prMsgHdr) -+ cnmMemFree(prAdapter, prMsgHdr); -+ -+ return; -+ -+} /* p2pFsmRunEventMgmtFrameRegister */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is call when RX deauthentication frame from the AIR. -+* If we are under STA mode, we would go back to P2P Device. -+* If we are under AP mode, we would stay in AP mode until disconnect event from HOST. -+* -+* \param[in] prAdapter Pointer of ADAPTER_T -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID p2pFsmRunEventRxDeauthentication(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN P_SW_RFB_T prSwRfb) -+{ -+ -+ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; -+ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; -+ UINT_16 u2ReasonCode = 0; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prSwRfb != NULL)); -+ -+ if (prStaRec == NULL) -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); -+ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; -+ -+ if (prP2pFsmInfo == NULL) -+ break; -+ -+ if (!prStaRec) -+ break; -+ -+ prP2pBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]; -+ -+ if (prStaRec->ucStaState == STA_STATE_1) -+ break; -+ -+ DBGLOG(P2P, TRACE, "RX Deauth\n"); -+ -+ switch (prP2pBssInfo->eCurrentOPMode) { -+ case OP_MODE_INFRASTRUCTURE: -+ if (authProcessRxDeauthFrame(prSwRfb, -+ prStaRec->aucMacAddr, &u2ReasonCode) == WLAN_STATUS_SUCCESS) { -+ P_WLAN_DEAUTH_FRAME_T prDeauthFrame = (P_WLAN_DEAUTH_FRAME_T) prSwRfb->pvHeader; -+ UINT_16 u2IELength = 0; -+ -+ if (prP2pBssInfo->prStaRecOfAP != prStaRec) -+ break; -+ -+ prStaRec->u2ReasonCode = u2ReasonCode; -+ u2IELength = prSwRfb->u2PacketLen - (WLAN_MAC_HEADER_LEN + REASON_CODE_FIELD_LEN); -+ -+ ASSERT(prP2pBssInfo->prStaRecOfAP == prStaRec); -+ -+ /* Indicate disconnect to Host. */ -+ kalP2PGCIndicateConnectionStatus(prAdapter->prGlueInfo, -+ NULL, -+ prDeauthFrame->aucInfoElem, u2IELength, u2ReasonCode, -+ WLAN_STATUS_MEDIA_DISCONNECT); -+ -+ prP2pBssInfo->prStaRecOfAP = NULL; -+ DBGLOG(P2P, INFO, "GC RX Deauth Reason: %d\n", u2ReasonCode); -+ -+ p2pFuncDisconnect(prAdapter, prStaRec, FALSE, u2ReasonCode); -+ p2pChangeMediaState(prAdapter, PARAM_MEDIA_STATE_DISCONNECTED); -+ -+ SET_NET_PWR_STATE_IDLE(prAdapter, NETWORK_TYPE_P2P_INDEX); -+ -+ p2pFsmStateTransition(prAdapter, prP2pFsmInfo, P2P_STATE_IDLE); -+ } -+ break; -+ case OP_MODE_ACCESS_POINT: -+ /* Delete client from client list. */ -+ if (authProcessRxDeauthFrame(prSwRfb, -+ prP2pBssInfo->aucBSSID, &u2ReasonCode) == WLAN_STATUS_SUCCESS) { -+ P_LINK_T prStaRecOfClientList = (P_LINK_T) NULL; -+ P_LINK_ENTRY_T prLinkEntry = (P_LINK_ENTRY_T) NULL; -+ P_STA_RECORD_T prCurrStaRec = (P_STA_RECORD_T) NULL; -+ -+ prStaRecOfClientList = &prP2pBssInfo->rStaRecOfClientList; -+ -+ LINK_FOR_EACH(prLinkEntry, prStaRecOfClientList) { -+ prCurrStaRec = LINK_ENTRY(prLinkEntry, STA_RECORD_T, rLinkEntry); -+ -+ ASSERT(prCurrStaRec); -+ -+ if (EQUAL_MAC_ADDR(prCurrStaRec->aucMacAddr, prStaRec->aucMacAddr)) { -+ -+ /* Remove STA from client list. */ -+ LINK_REMOVE_KNOWN_ENTRY(prStaRecOfClientList, -+ &prCurrStaRec->rLinkEntry); -+ -+ /* Indicate to Host. */ -+ /* kalP2PGOStationUpdate(prAdapter->prGlueInfo, prStaRec, FALSE); */ -+ -+ /* Indicate disconnect to Host. */ -+ DBGLOG(P2P, INFO, "GO RX Deauth Reason: %d\n", u2ReasonCode); -+ p2pFuncDisconnect(prAdapter, prStaRec, FALSE, u2ReasonCode); -+ -+ break; -+ } -+ } -+ } -+ break; -+ case OP_MODE_P2P_DEVICE: -+ default: -+ /* Findout why someone sent deauthentication frame to us. */ -+ ASSERT(FALSE); -+ break; -+ } -+ -+ DBGLOG(P2P, TRACE, "Deauth Reason:%d\n", u2ReasonCode); -+ -+ } while (FALSE); -+} /* p2pFsmRunEventRxDeauthentication */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is call when RX deauthentication frame from the AIR. -+* If we are under STA mode, we would go back to P2P Device. -+* If we are under AP mode, we would stay in AP mode until disconnect event from HOST. -+* -+* \param[in] prAdapter Pointer of ADAPTER_T -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID p2pFsmRunEventRxDisassociation(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN P_SW_RFB_T prSwRfb) -+{ -+ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; -+ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; -+ UINT_16 u2ReasonCode = 0; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prSwRfb != NULL)); -+ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; -+ -+ if (prP2pFsmInfo == NULL) -+ break; -+ -+ if (prStaRec == NULL) { -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); -+ if (prStaRec == NULL) -+ break; -+ } -+ -+ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); -+ -+ if (prStaRec->ucStaState == STA_STATE_1) -+ break; -+ -+ DBGLOG(P2P, TRACE, "RX Disassoc\n"); -+ -+ switch (prP2pBssInfo->eCurrentOPMode) { -+ case OP_MODE_INFRASTRUCTURE: -+ if (assocProcessRxDisassocFrame(prAdapter, -+ prSwRfb, -+ prStaRec->aucMacAddr, -+ &prStaRec->u2ReasonCode) == WLAN_STATUS_SUCCESS) { -+ P_WLAN_DISASSOC_FRAME_T prDisassocFrame = (P_WLAN_DISASSOC_FRAME_T) prSwRfb->pvHeader; -+ UINT_16 u2IELength = 0; -+ -+ ASSERT(prP2pBssInfo->prStaRecOfAP == prStaRec); -+ -+ if (prP2pBssInfo->prStaRecOfAP != prStaRec) -+ break; -+ -+ u2IELength = prSwRfb->u2PacketLen - (WLAN_MAC_HEADER_LEN + REASON_CODE_FIELD_LEN); -+ -+ /* Indicate disconnect to Host. */ -+ kalP2PGCIndicateConnectionStatus(prAdapter->prGlueInfo, -+ NULL, -+ prDisassocFrame->aucInfoElem, -+ u2IELength, prStaRec->u2ReasonCode, -+ WLAN_STATUS_MEDIA_DISCONNECT); -+ -+ prP2pBssInfo->prStaRecOfAP = NULL; -+ -+ DBGLOG(P2P, INFO, "GC RX Disassoc Reason %d\n", prStaRec->u2ReasonCode); -+ p2pFuncDisconnect(prAdapter, prStaRec, FALSE, prStaRec->u2ReasonCode); -+ p2pChangeMediaState(prAdapter, PARAM_MEDIA_STATE_DISCONNECTED); -+ SET_NET_PWR_STATE_IDLE(prAdapter, NETWORK_TYPE_P2P_INDEX); -+ p2pFsmStateTransition(prAdapter, prP2pFsmInfo, P2P_STATE_IDLE); -+ -+ } -+ break; -+ case OP_MODE_ACCESS_POINT: -+ /* Delete client from client list. */ -+ if (assocProcessRxDisassocFrame(prAdapter, -+ prSwRfb, -+ prP2pBssInfo->aucBSSID, &u2ReasonCode) == WLAN_STATUS_SUCCESS) { -+ P_LINK_T prStaRecOfClientList = (P_LINK_T) NULL; -+ P_LINK_ENTRY_T prLinkEntry = (P_LINK_ENTRY_T) NULL; -+ P_STA_RECORD_T prCurrStaRec = (P_STA_RECORD_T) NULL; -+ -+ prStaRecOfClientList = &prP2pBssInfo->rStaRecOfClientList; -+ -+ LINK_FOR_EACH(prLinkEntry, prStaRecOfClientList) { -+ prCurrStaRec = LINK_ENTRY(prLinkEntry, STA_RECORD_T, rLinkEntry); -+ -+ ASSERT(prCurrStaRec); -+ -+ if (EQUAL_MAC_ADDR(prCurrStaRec->aucMacAddr, prStaRec->aucMacAddr)) { -+ -+ /* Remove STA from client list. */ -+ LINK_REMOVE_KNOWN_ENTRY(prStaRecOfClientList, -+ &prCurrStaRec->rLinkEntry); -+ -+ /* Indicate to Host. */ -+ /* kalP2PGOStationUpdate(prAdapter->prGlueInfo, prStaRec, FALSE); */ -+ -+ /* Indicate disconnect to Host. */ -+ DBGLOG(P2P, INFO, "GO RX Disassoc Reason %d\n", u2ReasonCode); -+ p2pFuncDisconnect(prAdapter, prStaRec, FALSE, u2ReasonCode); -+ -+ break; -+ } -+ } -+ } -+ break; -+ case OP_MODE_P2P_DEVICE: -+ default: -+ ASSERT(FALSE); -+ break; -+ } -+ -+ } while (FALSE); -+} /* p2pFsmRunEventRxDisassociation */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is called when a probe request frame is received. -+* -+* \param[in] prAdapter Pointer of ADAPTER_T -+* -+* \return boolean value if probe response frame is accepted & need cancel scan request. -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID p2pFsmRunEventRxProbeResponseFrame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, IN P_BSS_DESC_T prBssDesc) -+{ -+ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; -+ P_P2P_CONNECTION_SETTINGS_T prP2pConnSettings = (P_P2P_CONNECTION_SETTINGS_T) NULL; -+ P_WLAN_MAC_MGMT_HEADER_T prMgtHdr = (P_WLAN_MAC_MGMT_HEADER_T) NULL; -+ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prSwRfb != NULL) && (prBssDesc != NULL)); -+ -+ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; -+ prP2pConnSettings = prAdapter->rWifiVar.prP2PConnSettings; -+ prP2pBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]; -+ -+ /* There is a connection request. */ -+ prMgtHdr = (P_WLAN_MAC_MGMT_HEADER_T) prSwRfb->pvHeader; -+ -+ } while (FALSE); -+ -+} /* p2pFsmRunEventRxProbeResponseFrame */ -+ -+VOID p2pFsmRunEventBeaconTimeout(IN P_ADAPTER_T prAdapter) -+{ -+ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; -+ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; -+ -+ do { -+ ASSERT_BREAK(prAdapter != NULL); -+ -+ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; -+ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); -+ -+ DBGLOG(P2P, TRACE, "p2pFsmRunEventBeaconTimeout: Beacon Timeout\n"); -+ -+ /* Only client mode would have beacon lost event. */ -+ ASSERT(prP2pBssInfo->eCurrentOPMode == OP_MODE_INFRASTRUCTURE); -+ -+ if (prP2pBssInfo->eConnectionState == PARAM_MEDIA_STATE_CONNECTED) { -+ /* Indicate disconnect to Host. */ -+ kalP2PGCIndicateConnectionStatus(prAdapter->prGlueInfo, -+ NULL, NULL, 0, REASON_CODE_DISASSOC_INACTIVITY, -+ WLAN_STATUS_MEDIA_DISCONNECT); -+ -+ if (prP2pBssInfo->prStaRecOfAP != NULL) { -+ P_STA_RECORD_T prStaRec = prP2pBssInfo->prStaRecOfAP; -+ -+ prP2pBssInfo->prStaRecOfAP = NULL; -+ -+ p2pFuncDisconnect(prAdapter, prStaRec, FALSE, REASON_CODE_DISASSOC_LEAVING_BSS); -+ -+ /* 20120830 moved into p2pFuncDisconnect() */ -+ /* cnmStaRecFree(prAdapter, prP2pBssInfo->prStaRecOfAP, TRUE); */ -+ p2pChangeMediaState(prAdapter, PARAM_MEDIA_STATE_DISCONNECTED); -+ SET_NET_PWR_STATE_IDLE(prAdapter, NETWORK_TYPE_P2P_INDEX); -+ p2pFsmStateTransition(prAdapter, prP2pFsmInfo, P2P_STATE_IDLE); -+ -+ } -+ } -+ } while (FALSE); -+ -+} /* p2pFsmRunEventBeaconTimeout */ -+ -+VOID p2pFsmRunEventExtendListen(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) -+{ -+ P_P2P_FSM_INFO_T prP2pFsmInfo = NULL; -+ struct _MSG_P2P_EXTEND_LISTEN_INTERVAL_T *prExtListenMsg = NULL; -+ -+ ASSERT_BREAK((prAdapter != NULL) && (prMsgHdr != NULL)); -+ -+ prExtListenMsg = (struct _MSG_P2P_EXTEND_LISTEN_INTERVAL_T *) prMsgHdr; -+ -+ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; -+ ASSERT_BREAK(prP2pFsmInfo); -+ -+ if (!prExtListenMsg->wait) { -+ DBGLOG(P2P, INFO, "reset listen interval\n"); -+ prP2pFsmInfo->eListenExted = P2P_DEV_NOT_EXT_LISTEN; -+ if (prMsgHdr) -+ cnmMemFree(prAdapter, prMsgHdr); -+ return; -+ } -+ -+ if (prP2pFsmInfo && (prP2pFsmInfo->eListenExted == P2P_DEV_NOT_EXT_LISTEN)) { -+ DBGLOG(P2P, INFO, "try to ext listen, p2p state: %d\n", prP2pFsmInfo->eCurrentState); -+ if (prP2pFsmInfo->eCurrentState == P2P_STATE_CHNL_ON_HAND) { -+ DBGLOG(P2P, INFO, "here to ext listen interval\n"); -+ prP2pFsmInfo->eListenExted = P2P_DEV_EXT_LISTEN_ING; -+ } -+ } -+ if (prMsgHdr) -+ cnmMemFree(prAdapter, prMsgHdr); -+} /* p2pFsmRunEventUpdateMgmtFrame */ -+ -+#if CFG_SUPPORT_WFD -+VOID p2pFsmRunEventWfdSettingUpdate(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) -+{ -+ P_WFD_CFG_SETTINGS_T prWfdCfgSettings = (P_WFD_CFG_SETTINGS_T) NULL; -+ P_MSG_WFD_CONFIG_SETTINGS_CHANGED_T prMsgWfdCfgSettings = (P_MSG_WFD_CONFIG_SETTINGS_CHANGED_T) NULL; -+ WLAN_STATUS rStatus; -+ -+ DBGLOG(P2P, INFO, "p2pFsmRunEventWfdSettingUpdate\n"); -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL)); -+ -+ if (prMsgHdr != NULL) { -+ prMsgWfdCfgSettings = (P_MSG_WFD_CONFIG_SETTINGS_CHANGED_T) prMsgHdr; -+ prWfdCfgSettings = prMsgWfdCfgSettings->prWfdCfgSettings; -+ } else { -+ prWfdCfgSettings = &prAdapter->rWifiVar.prP2pFsmInfo->rWfdConfigureSettings; -+ } -+ -+ DBGLOG(P2P, INFO, "WFD Enalbe %x info %x state %x flag %x adv %x\n", -+ prWfdCfgSettings->ucWfdEnable, -+ prWfdCfgSettings->u2WfdDevInfo, -+ (UINT_32) prWfdCfgSettings->u4WfdState, -+ (UINT_32) prWfdCfgSettings->u4WfdFlag, -+ (UINT_32) prWfdCfgSettings->u4WfdAdvancedFlag); -+ -+ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ -+ CMD_ID_SET_WFD_CTRL, /* ucCID */ -+ TRUE, /* fgSetQuery */ -+ FALSE, /* fgNeedResp */ -+ FALSE, /* fgIsOid */ -+ NULL, NULL, /* pfCmdTimeoutHandler */ -+ sizeof(WFD_CFG_SETTINGS_T), /* u4SetQueryInfoLen */ -+ (PUINT_8) prWfdCfgSettings, /* pucInfoBuffer */ -+ NULL, /* pvSetQueryBuffer */ -+ 0 /* u4SetQueryBufferLen */ -+ ); -+ -+ } while (FALSE); -+ -+ return; -+ -+} -+ -+/* p2pFsmRunEventWfdSettingUpdate */ -+ -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is used to generate P2P IE for Beacon frame. -+* -+* @param[in] prMsduInfo Pointer to the composed MSDU_INFO_T. -+* -+* @return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID p2pGenerateP2P_IEForAssocReq(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo) -+{ -+ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; -+ P_STA_RECORD_T prStaRec = (P_STA_RECORD_T) NULL; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prMsduInfo != NULL)); -+ -+ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; -+ -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); -+ -+ if (prStaRec != NULL) { -+ if (IS_STA_P2P_TYPE(prStaRec)) { -+ /* Do nothing */ -+ /* TODO: */ -+ } -+ } -+ -+ } while (FALSE); -+ -+ return; -+ -+} /* end of p2pGenerateP2P_IEForAssocReq() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is used to generate P2P IE for Probe Request frame. -+* -+* @param[in] prMsduInfo Pointer to the composed MSDU_INFO_T. -+* -+* @return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+p2pGenerateP2P_IEForProbeReq(IN P_ADAPTER_T prAdapter, IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize) -+{ -+ ASSERT(prAdapter); -+ ASSERT(pucBuf); -+ -+ /* TODO: */ -+ -+ return; -+ -+} /* end of p2pGenerateP2P_IEForProbReq() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is used to calculate P2P IE length for Beacon frame. -+* -+* @param[in] eNetTypeIndex Specify which network -+* @param[in] prStaRec Pointer to the STA_RECORD_T -+* -+* @return The length of P2P IE added -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT_32 -+p2pCalculateP2P_IELenForProbeReq(IN P_ADAPTER_T prAdapter, -+ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec) -+{ -+ -+ if (eNetTypeIndex != NETWORK_TYPE_P2P_INDEX) -+ return 0; -+ /* TODO: */ -+ -+ return 0; -+ -+} /* end of p2pCalculateP2P_IELenForProbeReq() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will indicate the Event of Tx Fail of AAA Module. -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* @param[in] prStaRec Pointer to the STA_RECORD_T -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID p2pRunEventAAATxFail(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec) -+{ -+ P_BSS_INFO_T prBssInfo; -+ -+ ASSERT(prAdapter); -+ ASSERT(prStaRec); -+ -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]); -+ -+ bssRemoveStaRecFromClientList(prAdapter, prBssInfo, prStaRec); -+ -+ p2pFuncDisconnect(prAdapter, prStaRec, FALSE, REASON_CODE_UNSPECIFIED); -+ -+ /* 20120830 moved into p2puUncDisconnect. */ -+ /* cnmStaRecFree(prAdapter, prStaRec, TRUE); */ -+ -+} /* p2pRunEventAAATxFail */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will indicate the Event of Successful Completion of AAA Module. -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* @param[in] prStaRec Pointer to the STA_RECORD_T -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS p2pRunEventAAAComplete(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec) -+{ -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; -+ ENUM_PARAM_MEDIA_STATE_T eOriMediaState; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prStaRec != NULL)); -+ -+ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); -+ -+ eOriMediaState = prP2pBssInfo->eConnectionState; -+ -+ if (prStaRec != NULL) -+ bssRemoveStaRecFromClientList(prAdapter, prP2pBssInfo, prStaRec); -+ else -+ break; -+ -+ if (prP2pBssInfo->rStaRecOfClientList.u4NumElem > P2P_MAXIMUM_CLIENT_COUNT || -+ kalP2PMaxClients(prAdapter->prGlueInfo, prP2pBssInfo->rStaRecOfClientList.u4NumElem)) { -+ rStatus = WLAN_STATUS_RESOURCES; -+ break; -+ } -+ -+ bssAddStaRecToClientList(prAdapter, prP2pBssInfo, prStaRec); -+ -+ prStaRec->u2AssocId = bssAssignAssocID(prStaRec); -+ -+ if (prP2pBssInfo->rStaRecOfClientList.u4NumElem > P2P_MAXIMUM_CLIENT_COUNT || -+ kalP2PMaxClients(prAdapter->prGlueInfo, prP2pBssInfo->rStaRecOfClientList.u4NumElem)) { -+ rStatus = WLAN_STATUS_RESOURCES; -+ break; -+ } -+ DBGLOG(P2P, INFO, "P2P GO Join Complete\n"); -+ -+ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_3); -+ -+ p2pChangeMediaState(prAdapter, PARAM_MEDIA_STATE_CONNECTED); -+ -+ /* Update Connected state to FW. */ -+ if (eOriMediaState != prP2pBssInfo->eConnectionState) -+ nicUpdateBss(prAdapter, NETWORK_TYPE_P2P_INDEX); -+ -+ } while (FALSE); -+ -+ return rStatus; -+} /* p2pRunEventAAAComplete */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will indicate the Event of Successful Completion of AAA Module. -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* @param[in] prStaRec Pointer to the STA_RECORD_T -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS p2pRunEventAAASuccess(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec) -+{ -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prStaRec != NULL)); -+ -+ /* Glue layer indication. */ -+ kalP2PGOStationUpdate(prAdapter->prGlueInfo, prStaRec, TRUE); -+ -+ } while (FALSE); -+ -+ return rStatus; -+} /* p2pRunEventAAASuccess */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS p2pRxPublicActionFrame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb) -+{ -+ WLAN_STATUS rWlanStatus = WLAN_STATUS_SUCCESS; -+ P_P2P_PUBLIC_ACTION_FRAME_T prPublicActionFrame = (P_P2P_PUBLIC_ACTION_FRAME_T) NULL; -+ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; -+ -+ ASSERT(prSwRfb); -+ ASSERT(prAdapter); -+ -+ prPublicActionFrame = (P_P2P_PUBLIC_ACTION_FRAME_T) prSwRfb->pvHeader; -+ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; -+ -+ DBGLOG(P2P, TRACE, "RX Public Action Frame Token:%d.\n", prPublicActionFrame->ucDialogToken); -+ -+ if (prPublicActionFrame->ucCategory != CATEGORY_PUBLIC_ACTION) -+ return rWlanStatus; -+ -+ switch (prPublicActionFrame->ucAction) { -+ case ACTION_PUBLIC_WIFI_DIRECT: -+ break; -+ case ACTION_GAS_INITIAL_REQUEST: -+ case ACTION_GAS_INITIAL_RESPONSE: -+ case ACTION_GAS_COMEBACK_REQUEST: -+ case ACTION_GAS_COMEBACK_RESPONSE: -+ break; -+ default: -+ break; -+ } -+ -+ return rWlanStatus; -+} /* p2pRxPublicActionFrame */ -+ -+WLAN_STATUS p2pRxActionFrame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb) -+{ -+ WLAN_STATUS rWlanStatus = WLAN_STATUS_SUCCESS; -+ P_P2P_ACTION_FRAME_T prP2pActionFrame = (P_P2P_ACTION_FRAME_T) NULL; -+ UINT_8 aucOui[3] = VENDOR_OUI_WFA_SPECIFIC; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prSwRfb != NULL)); -+ -+ prP2pActionFrame = (P_P2P_ACTION_FRAME_T) prSwRfb->pvHeader; -+ -+ if (prP2pActionFrame->ucCategory != CATEGORY_VENDOR_SPECIFIC_ACTION) { -+ DBGLOG(P2P, TRACE, "RX Action Frame but not vendor specific.\n"); -+ break; -+ } -+ -+ if ((prP2pActionFrame->ucOuiType != VENDOR_OUI_TYPE_P2P) || -+ (prP2pActionFrame->aucOui[0] != aucOui[0]) || -+ (prP2pActionFrame->aucOui[1] != aucOui[1]) || (prP2pActionFrame->aucOui[2] != aucOui[2])) { -+ DBGLOG(P2P, TRACE, "RX Vendor Specific Action Frame but not P2P Type or not WFA OUI.\n"); -+ break; -+ } -+ -+ } while (FALSE); -+ -+ return rWlanStatus; -+} /* p2pRxActionFrame */ -+ -+VOID -+p2pProcessEvent_UpdateNOAParam(IN P_ADAPTER_T prAdapter, -+ UINT_8 ucNetTypeIndex, P_EVENT_UPDATE_NOA_PARAMS_T prEventUpdateNoaParam) -+{ -+ P_BSS_INFO_T prBssInfo = (P_BSS_INFO_T) NULL; -+ P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo; -+ UINT_32 i; -+ BOOLEAN fgNoaAttrExisted = FALSE; -+ -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[ucNetTypeIndex]); -+ prP2pSpecificBssInfo = prAdapter->rWifiVar.prP2pSpecificBssInfo; -+ -+ prP2pSpecificBssInfo->fgEnableOppPS = prEventUpdateNoaParam->fgEnableOppPS; -+ prP2pSpecificBssInfo->u2CTWindow = prEventUpdateNoaParam->u2CTWindow; -+ prP2pSpecificBssInfo->ucNoAIndex = prEventUpdateNoaParam->ucNoAIndex; -+ prP2pSpecificBssInfo->ucNoATimingCount = prEventUpdateNoaParam->ucNoATimingCount; -+ -+ fgNoaAttrExisted |= prP2pSpecificBssInfo->fgEnableOppPS; -+ -+ DBGLOG(P2P, INFO, "Update NoA Count=%d.\n", prEventUpdateNoaParam->ucNoATimingCount); -+ -+ ASSERT(prP2pSpecificBssInfo->ucNoATimingCount <= P2P_MAXIMUM_NOA_COUNT); -+ -+ for (i = 0; i < prP2pSpecificBssInfo->ucNoATimingCount; i++) { -+ /* in used */ -+ prP2pSpecificBssInfo->arNoATiming[i].fgIsInUse = prEventUpdateNoaParam->arEventNoaTiming[i].fgIsInUse; -+ /* count */ -+ prP2pSpecificBssInfo->arNoATiming[i].ucCount = prEventUpdateNoaParam->arEventNoaTiming[i].ucCount; -+ /* duration */ -+ prP2pSpecificBssInfo->arNoATiming[i].u4Duration = prEventUpdateNoaParam->arEventNoaTiming[i].u4Duration; -+ /* interval */ -+ prP2pSpecificBssInfo->arNoATiming[i].u4Interval = prEventUpdateNoaParam->arEventNoaTiming[i].u4Interval; -+ /* start time */ -+ prP2pSpecificBssInfo->arNoATiming[i].u4StartTime = -+ prEventUpdateNoaParam->arEventNoaTiming[i].u4StartTime; -+ -+ fgNoaAttrExisted |= prP2pSpecificBssInfo->arNoATiming[i].fgIsInUse; -+ } -+ -+ prP2pSpecificBssInfo->fgIsNoaAttrExisted = fgNoaAttrExisted; -+ -+ /* update beacon content by the change */ -+ bssUpdateBeaconContent(prAdapter, ucNetTypeIndex); -+} -+ -+#endif /* CFG_ENABLE_WIFI_DIRECT */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_func.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_func.c -new file mode 100644 -index 000000000000..586a74721b3b ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_func.c -@@ -0,0 +1,3796 @@ -+#include "precomp.h" -+#include -+ -+#ifdef __GNUC__ -+#pragma GCC diagnostic ignored "-Wformat" -+#endif -+ -+APPEND_VAR_ATTRI_ENTRY_T txAssocRspAttributesTable[] = { -+ {(P2P_ATTRI_HDR_LEN + P2P_ATTRI_MAX_LEN_STATUS), NULL, p2pFuncAppendAttriStatusForAssocRsp} /* 0 */ -+ , {(P2P_ATTRI_HDR_LEN + P2P_ATTRI_MAX_LEN_EXT_LISTEN_TIMING), NULL, p2pFuncAppendAttriExtListenTiming} /* 8 */ -+}; -+ -+APPEND_VAR_IE_ENTRY_T txProbeRspIETable[] = { -+ {(ELEM_HDR_LEN + (RATE_NUM - ELEM_MAX_LEN_SUP_RATES)), NULL, bssGenerateExtSuppRate_IE} /* 50 */ -+ , {(ELEM_HDR_LEN + ELEM_MAX_LEN_ERP), NULL, rlmRspGenerateErpIE} /* 42 */ -+ , {(ELEM_HDR_LEN + ELEM_MAX_LEN_HT_CAP), NULL, rlmRspGenerateHtCapIE} /* 45 */ -+ , {(ELEM_HDR_LEN + ELEM_MAX_LEN_HT_OP), NULL, rlmRspGenerateHtOpIE} /* 61 */ -+ , {(ELEM_HDR_LEN + ELEM_MAX_LEN_RSN), NULL, rsnGenerateRSNIE} /* 48 */ -+ , {(ELEM_HDR_LEN + ELEM_MAX_LEN_OBSS_SCAN), NULL, rlmRspGenerateObssScanIE} /* 74 */ -+ , {(ELEM_HDR_LEN + ELEM_MAX_LEN_EXT_CAP), NULL, rlmRspGenerateExtCapIE} /* 127 */ -+ , {(ELEM_HDR_LEN + ELEM_MAX_LEN_WPA), NULL, rsnGenerateWpaNoneIE} /* 221 */ -+ , {(ELEM_HDR_LEN + ELEM_MAX_LEN_WMM_PARAM), NULL, mqmGenerateWmmParamIE} /* 221 */ -+}; -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Function for requesting scan. There is an option to do ACTIVE or PASSIVE scan. -+* -+* @param eScanType - Specify the scan type of the scan request. It can be an ACTIVE/PASSIVE -+* Scan. -+* eChannelSet - Specify the preferred channel set. -+* A FULL scan would request a legacy full channel normal scan.(usually ACTIVE). -+* A P2P_SOCIAL scan would scan 1+6+11 channels.(usually ACTIVE) -+* A SPECIFIC scan would only 1/6/11 channels scan. (Passive Listen/Specific Search) -+* ucChannelNum - A specific channel number. (Only when channel is specified) -+* eBand - A specific band. (Only when channel is specified) -+* -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID p2pFuncRequestScan(IN P_ADAPTER_T prAdapter, IN P_P2P_SCAN_REQ_INFO_T prScanReqInfo) -+{ -+ -+ P_MSG_SCN_SCAN_REQ prScanReq = (P_MSG_SCN_SCAN_REQ) NULL; -+ /*NFC Beam + Indication */ -+ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; -+ BOOLEAN fgIsPureAP = FALSE; -+ P_P2P_CHNL_REQ_INFO_T prChnlReqInfo = (P_P2P_CHNL_REQ_INFO_T) NULL; -+ -+ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); -+ fgIsPureAP = prAdapter->rWifiVar.prP2pFsmInfo->fgIsApMode; -+ -+ DEBUGFUNC("p2pFuncRequestScan()"); -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prScanReqInfo != NULL)); -+ -+ if (prScanReqInfo->eChannelSet == SCAN_CHANNEL_SPECIFIED) { -+ ASSERT_BREAK(prScanReqInfo->ucNumChannelList > 0); -+ DBGLOG(P2P, LOUD, -+ "P2P Scan Request Channel:%d\n", prScanReqInfo->arScanChannelList[0].ucChannelNum); -+ } -+ -+ prScanReq = (P_MSG_SCN_SCAN_REQ) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_SCN_SCAN_REQ)); -+ if (!prScanReq) { -+ ASSERT(0); /* Can't trigger SCAN FSM */ -+ break; -+ } -+ -+ prScanReq->rMsgHdr.eMsgId = MID_P2P_SCN_SCAN_REQ; -+ prScanReq->ucSeqNum = ++prScanReqInfo->ucSeqNumOfScnMsg; -+ prScanReq->ucNetTypeIndex = (UINT_8) NETWORK_TYPE_P2P_INDEX; -+ prScanReq->eScanType = prScanReqInfo->eScanType; -+ prScanReq->eScanChannel = prScanReqInfo->eChannelSet; -+ prScanReq->u2IELen = 0; -+ -+ /* Copy IE for Probe Request. */ -+ if (prScanReqInfo->u4BufLength > MAX_IE_LENGTH) -+ prScanReqInfo->u4BufLength = MAX_IE_LENGTH; -+ kalMemCopy(prScanReq->aucIE, prScanReqInfo->aucIEBuf, prScanReqInfo->u4BufLength); -+ prScanReq->u2IELen = (UINT_16) prScanReqInfo->u4BufLength; -+ -+ prScanReq->u2ChannelDwellTime = prScanReqInfo->u2PassiveDewellTime; -+ -+ switch (prScanReqInfo->eChannelSet) { -+ case SCAN_CHANNEL_SPECIFIED: -+ { -+ UINT_32 u4Idx = 0; -+ P_RF_CHANNEL_INFO_T prDomainInfo = -+ (P_RF_CHANNEL_INFO_T) prScanReqInfo->arScanChannelList; -+ UINT_8 aucP2pSsid[] = P2P_WILDCARD_SSID; -+ -+ -+ if (prScanReqInfo->ucNumChannelList > MAXIMUM_OPERATION_CHANNEL_LIST) -+ prScanReqInfo->ucNumChannelList = MAXIMUM_OPERATION_CHANNEL_LIST; -+ -+ for (u4Idx = 0; u4Idx < prScanReqInfo->ucNumChannelList; u4Idx++) { -+ prScanReq->arChnlInfoList[u4Idx].ucChannelNum = prDomainInfo->ucChannelNum; -+ prScanReq->arChnlInfoList[u4Idx].eBand = prDomainInfo->eBand; -+ prDomainInfo++; -+ } -+ -+ prScanReq->ucChannelListNum = prScanReqInfo->ucNumChannelList; -+ -+ /*NFC Beam + Indication */ -+ prChnlReqInfo = &prAdapter->rWifiVar.prP2pFsmInfo->rChnlReqInfo; -+ if (prChnlReqInfo->eChannelReqType == CHANNEL_REQ_TYPE_GO_START_BSS && -+ prP2pBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT && -+ !fgIsPureAP) { -+ prScanReq->ucChannelListNum = 1; -+ prScanReq->arChnlInfoList[0].ucChannelNum = prChnlReqInfo->ucReqChnlNum; -+ prScanReq->arChnlInfoList[0].eBand = prChnlReqInfo->eBand; -+ -+ DBGLOG(P2P, INFO, -+ "NFC:GO Skip Scan and Only Froce on %s[%d]\n", -+ prChnlReqInfo->eBand == 1 ? "2.4G" : "5G", -+ prChnlReqInfo->ucReqChnlNum); -+ } -+ -+ COPY_SSID(prScanReq->aucSSID, -+ prScanReq->ucSSIDLength, -+ prScanReqInfo->rSsidStruct.aucSsid, prScanReqInfo->rSsidStruct.ucSsidLen); -+ -+ /* For compatible. */ -+ if (EQUAL_SSID(aucP2pSsid, P2P_WILDCARD_SSID_LEN, -+ prScanReq->aucSSID, prScanReq->ucSSIDLength)) { -+ prScanReq->ucSSIDType = SCAN_REQ_SSID_P2P_WILDCARD; -+ } else if (prScanReq->ucSSIDLength != 0) { -+ prScanReq->ucSSIDType = SCAN_REQ_SSID_SPECIFIED; -+ } -+ -+ } -+ break; -+ -+ case SCAN_CHANNEL_FULL: -+ { -+ UINT_8 aucP2pSsid[] = P2P_WILDCARD_SSID; -+ -+ COPY_SSID(prScanReq->aucSSID, -+ prScanReq->ucSSIDLength, -+ prScanReqInfo->rSsidStruct.aucSsid, prScanReqInfo->rSsidStruct.ucSsidLen); -+ -+ /* For compatible. */ -+ if (EQUAL_SSID(aucP2pSsid, P2P_WILDCARD_SSID_LEN, -+ prScanReq->aucSSID, prScanReq->ucSSIDLength)) { -+ prScanReq->ucSSIDType = SCAN_REQ_SSID_P2P_WILDCARD; -+ } else if (prScanReq->ucSSIDLength != 0) { -+ prScanReq->ucSSIDType = SCAN_REQ_SSID_SPECIFIED; -+ } -+ } -+ break; -+ -+ case SCAN_CHANNEL_2G4: -+ { -+ UINT_8 aucP2pSsid[] = P2P_WILDCARD_SSID; -+ -+ COPY_SSID(prScanReq->aucSSID, -+ prScanReq->ucSSIDLength, -+ prScanReqInfo->rSsidStruct.aucSsid, prScanReqInfo->rSsidStruct.ucSsidLen); -+ -+ /* For compatible. */ -+ if (EQUAL_SSID(aucP2pSsid, P2P_WILDCARD_SSID_LEN, -+ prScanReq->aucSSID, prScanReq->ucSSIDLength)) { -+ prScanReq->ucSSIDType = SCAN_REQ_SSID_P2P_WILDCARD; -+ } else if (prScanReq->ucSSIDLength != 0) { -+ prScanReq->ucSSIDType = SCAN_REQ_SSID_SPECIFIED; -+ } -+ } -+ break; -+ -+ case SCAN_CHANNEL_P2P_SOCIAL: -+ { -+ UINT_8 aucP2pSsid[] = P2P_WILDCARD_SSID; -+ -+ COPY_SSID(prScanReq->aucSSID, -+ prScanReq->ucSSIDLength, -+ prScanReqInfo->rSsidStruct.aucSsid, prScanReqInfo->rSsidStruct.ucSsidLen); -+ -+ /* For compatible. */ -+ if (EQUAL_SSID(aucP2pSsid, P2P_WILDCARD_SSID_LEN, -+ prScanReq->aucSSID, prScanReq->ucSSIDLength)) { -+ prScanReq->ucSSIDType = SCAN_REQ_SSID_P2P_WILDCARD; -+ } else if (prScanReq->ucSSIDLength != 0) { -+ prScanReq->ucSSIDType = SCAN_REQ_SSID_SPECIFIED; -+ } -+ } -+ break; -+ default: -+ /* Currently there is no other scan channel set. */ -+ ASSERT(FALSE); -+ break; -+ } -+ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prScanReq, MSG_SEND_METHOD_BUF); -+ -+ } while (FALSE); -+ -+} /* p2pFuncRequestScan */ -+ -+VOID p2pFuncCancelScan(IN P_ADAPTER_T prAdapter, IN P_P2P_SCAN_REQ_INFO_T prScanInfo) -+{ -+ P_MSG_SCN_SCAN_CANCEL prScanCancelMsg = (P_MSG_SCN_SCAN_CANCEL) NULL; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prScanInfo != NULL)); -+ -+ if (!prScanInfo->fgIsScanRequest) -+ break; -+ -+ if (prScanInfo->ucSeqNumOfScnMsg) { -+ /* There is a channel privilege on hand. */ -+ DBGLOG(P2P, TRACE, "P2P Cancel Scan\n"); -+ -+ prScanCancelMsg = -+ (P_MSG_SCN_SCAN_CANCEL) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_SCN_SCAN_CANCEL)); -+ if (!prScanCancelMsg) { -+ /* Buffer not enough, can not cancel scan request. */ -+ DBGLOG(P2P, TRACE, "Buffer not enough, can not cancel scan.\n"); -+ ASSERT(FALSE); -+ break; -+ } -+ -+ prScanCancelMsg->rMsgHdr.eMsgId = MID_P2P_SCN_SCAN_CANCEL; -+ prScanCancelMsg->ucNetTypeIndex = NETWORK_TYPE_P2P_INDEX; -+ prScanCancelMsg->ucSeqNum = prScanInfo->ucSeqNumOfScnMsg++; -+ prScanCancelMsg->fgIsChannelExt = FALSE; -+ prScanInfo->fgIsScanRequest = FALSE; -+ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prScanCancelMsg, MSG_SEND_METHOD_BUF); -+ -+ } -+ -+ } while (FALSE); -+ -+} /* p2pFuncCancelScan */ -+ -+VOID -+p2pFuncSwitchOPMode(IN P_ADAPTER_T prAdapter, -+ IN P_BSS_INFO_T prP2pBssInfo, IN ENUM_OP_MODE_T eOpMode, IN BOOLEAN fgSyncToFW) -+{ -+ if (!prAdapter) -+ return; -+ if (!prAdapter->prGlueInfo) -+ return; -+ if (prAdapter->prGlueInfo->ulFlag & GLUE_FLAG_HALT) -+ return; -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prP2pBssInfo != NULL) && (eOpMode < OP_MODE_NUM)); -+ -+ if (prP2pBssInfo->eCurrentOPMode != eOpMode) { -+ DBGLOG(P2P, TRACE, -+ "p2pFuncSwitchOPMode: Switch to from %d, to %d.\n", prP2pBssInfo->eCurrentOPMode, -+ eOpMode); -+ -+ switch (prP2pBssInfo->eCurrentOPMode) { -+ case OP_MODE_ACCESS_POINT: -+ p2pFuncDissolve(prAdapter, prP2pBssInfo, TRUE, REASON_CODE_DEAUTH_LEAVING_BSS); -+ -+ p2pFsmRunEventStopAP(prAdapter, NULL); -+ break; -+ default: -+ break; -+ } -+ -+ prP2pBssInfo->eIntendOPMode = eOpMode; -+ prP2pBssInfo->eCurrentOPMode = eOpMode; -+ switch (eOpMode) { -+ case OP_MODE_INFRASTRUCTURE: -+ DBGLOG(P2P, TRACE, "p2pFuncSwitchOPMode: Switch to Client.\n"); -+ case OP_MODE_ACCESS_POINT: -+/* if (!IS_BSS_ACTIVE(prP2pBssInfo)) { */ -+/* SET_NET_ACTIVE(prAdapter, NETWORK_TYPE_P2P_INDEX); */ -+/* nicActivateNetwork(prAdapter, NETWORK_TYPE_P2P_INDEX); */ -+/* } */ -+ -+ /* Change interface address. */ -+ if (eOpMode == OP_MODE_ACCESS_POINT) { -+ DBGLOG(P2P, TRACE, "p2pFuncSwitchOPMode: Switch to AP.\n"); -+ prP2pBssInfo->ucSSIDLen = 0; -+ } -+ -+ COPY_MAC_ADDR(prP2pBssInfo->aucOwnMacAddr, prAdapter->rWifiVar.aucInterfaceAddress); -+ COPY_MAC_ADDR(prP2pBssInfo->aucBSSID, prAdapter->rWifiVar.aucInterfaceAddress); -+ -+ break; -+ case OP_MODE_P2P_DEVICE: -+ { -+ /* Change device address. */ -+ DBGLOG(P2P, TRACE, "p2pFuncSwitchOPMode: Switch back to P2P Device.\n"); -+ -+/* if (!IS_BSS_ACTIVE(prP2pBssInfo)) { */ -+/* SET_NET_ACTIVE(prAdapter, NETWORK_TYPE_P2P_INDEX); */ -+/* nicActivateNetwork(prAdapter, NETWORK_TYPE_P2P_INDEX); */ -+/* } */ -+ -+ p2pChangeMediaState(prAdapter, PARAM_MEDIA_STATE_DISCONNECTED); -+ -+ COPY_MAC_ADDR(prP2pBssInfo->aucOwnMacAddr, -+ prAdapter->rWifiVar.aucDeviceAddress); -+ COPY_MAC_ADDR(prP2pBssInfo->aucBSSID, prAdapter->rWifiVar.aucDeviceAddress); -+ -+ } -+ break; -+ default: -+/* if (IS_BSS_ACTIVE(prP2pBssInfo)) { */ -+/* UNSET_NET_ACTIVE(prAdapter, NETWORK_TYPE_P2P_INDEX); */ -+ -+/* nicDeactivateNetwork(prAdapter, NETWORK_TYPE_P2P_INDEX); */ -+/* } */ -+ ASSERT(FALSE); -+ break; -+ } -+ -+ if (1) { -+ P2P_DISCONNECT_INFO rP2PDisInfo; -+ -+ rP2PDisInfo.ucRole = 2; -+ wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_P2P_ABORT, -+ TRUE, -+ FALSE, -+ FALSE, -+ NULL, -+ NULL, -+ sizeof(P2P_DISCONNECT_INFO), (PUINT_8)&rP2PDisInfo, NULL, 0); -+ } -+ -+ DBGLOG(P2P, TRACE, -+ "The device address is changed to %pM\n", -+ prP2pBssInfo->aucOwnMacAddr); -+ DBGLOG(P2P, TRACE, "The BSSID is changed to %pM\n", prP2pBssInfo->aucBSSID); -+ -+ /* Update BSS INFO to FW. */ -+ if ((fgSyncToFW) && (eOpMode != OP_MODE_ACCESS_POINT)) -+ nicUpdateBss(prAdapter, NETWORK_TYPE_P2P_INDEX); -+ } -+ -+ } while (FALSE); -+ -+} /* p2pFuncSwitchOPMode */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will start a P2P Group Owner and send Beacon Frames. -+* -+* @param (none) -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+p2pFuncStartGO(IN P_ADAPTER_T prAdapter, -+ IN P_BSS_INFO_T prBssInfo, -+ IN PUINT_8 pucSsidBuf, -+ IN UINT_8 ucSsidLen, -+ IN UINT_8 ucChannelNum, IN ENUM_BAND_T eBand, IN ENUM_CHNL_EXT_T eSco, IN BOOLEAN fgIsPureAP) -+{ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prBssInfo != NULL)); -+ -+ ASSERT(prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT); -+ -+ prAdapter->rWifiVar.prP2pFsmInfo->rScanReqInfo.fgIsGOInitialDone = 1; -+ DBGLOG(P2P, INFO, -+ "p2pFuncStartGO:NFC Done[%d]\n", -+ prAdapter->rWifiVar.prP2pFsmInfo->rScanReqInfo.fgIsGOInitialDone); -+ /* AP mode started. */ -+ p2pFuncSwitchOPMode(prAdapter, prBssInfo, prBssInfo->eIntendOPMode, FALSE); -+ -+ prBssInfo->eIntendOPMode = OP_MODE_NUM; -+ -+ /* 4 <1.1> Assign SSID */ -+ COPY_SSID(prBssInfo->aucSSID, prBssInfo->ucSSIDLen, pucSsidBuf, ucSsidLen); -+ -+ DBGLOG(P2P, TRACE, "GO SSID:%s\n", prBssInfo->aucSSID); -+ -+ /* 4 <1.2> Clear current AP's STA_RECORD_T and current AID */ -+ prBssInfo->prStaRecOfAP = (P_STA_RECORD_T) NULL; -+ prBssInfo->u2AssocId = 0; -+ -+ /* 4 <1.3> Setup Channel, Band and Phy Attributes */ -+ prBssInfo->ucPrimaryChannel = ucChannelNum; -+ prBssInfo->eBand = eBand; -+ prBssInfo->eBssSCO = eSco; -+ -+ DBGLOG(P2P, TRACE, "GO Channel:%d\n", ucChannelNum); -+ -+ if (prBssInfo->eBand == BAND_5G) { -+ /* Depend on eBand */ -+ prBssInfo->ucPhyTypeSet = (prAdapter->rWifiVar.ucAvailablePhyTypeSet & PHY_TYPE_SET_802_11AN); -+ /* Depend on eCurrentOPMode and ucPhyTypeSet */ -+ prBssInfo->ucConfigAdHocAPMode = AP_MODE_11A; -+ } else if (fgIsPureAP) { -+ /* Depend on eBand */ -+ prBssInfo->ucPhyTypeSet = (prAdapter->rWifiVar.ucAvailablePhyTypeSet & PHY_TYPE_SET_802_11BGN); -+ /* Depend on eCurrentOPMode and ucPhyTypeSet */ -+ prBssInfo->ucConfigAdHocAPMode = AP_MODE_MIXED_11BG; -+ } else { -+ /* Depend on eBand */ -+ prBssInfo->ucPhyTypeSet = (prAdapter->rWifiVar.ucAvailablePhyTypeSet & PHY_TYPE_SET_802_11GN); -+ /* Depend on eCurrentOPMode and ucPhyTypeSet */ -+ prBssInfo->ucConfigAdHocAPMode = AP_MODE_11G_P2P; -+ } -+ -+ prBssInfo->ucNonHTBasicPhyType = (UINT_8) -+ rNonHTApModeAttributes[prBssInfo->ucConfigAdHocAPMode].ePhyTypeIndex; -+ prBssInfo->u2BSSBasicRateSet = rNonHTApModeAttributes[prBssInfo->ucConfigAdHocAPMode].u2BSSBasicRateSet; -+ prBssInfo->u2OperationalRateSet = -+ rNonHTPhyAttributes[prBssInfo->ucNonHTBasicPhyType].u2SupportedRateSet; -+ -+ if (prBssInfo->ucAllSupportedRatesLen == 0) { -+ rateGetDataRatesFromRateSet(prBssInfo->u2OperationalRateSet, -+ prBssInfo->u2BSSBasicRateSet, -+ prBssInfo->aucAllSupportedRates, -+ &prBssInfo->ucAllSupportedRatesLen); -+ } -+ /* 4 <1.5> Setup MIB for current BSS */ -+ prBssInfo->u2ATIMWindow = 0; -+ prBssInfo->ucBeaconTimeoutCount = 0; -+ -+ /* 3 <2> Update BSS_INFO_T common part */ -+#if CFG_SUPPORT_AAA -+ if (!fgIsPureAP) { -+ prBssInfo->fgIsProtection = TRUE; /* Always enable protection at P2P GO */ -+ kalP2PSetCipher(prAdapter->prGlueInfo, IW_AUTH_CIPHER_CCMP); -+ } else { -+ if (kalP2PGetCipher(prAdapter->prGlueInfo)) -+ prBssInfo->fgIsProtection = TRUE; -+ } -+ -+ /* 20120106 frog: I want separate OP_Mode & Beacon TX Function. */ -+ /* p2pFuncSwitchOPMode(prAdapter, prBssInfo, OP_MODE_ACCESS_POINT, FALSE); */ -+ -+ bssInitForAP(prAdapter, prBssInfo, FALSE); -+ -+ nicQmUpdateWmmParms(prAdapter, NETWORK_TYPE_P2P_INDEX); -+#endif /* CFG_SUPPORT_AAA */ -+ -+ /* 3 <3> Set MAC HW */ -+ /* 4 <3.1> Setup channel and bandwidth */ -+ rlmBssInitForAPandIbss(prAdapter, prBssInfo); -+ -+ /* 4 <3.2> Reset HW TSF Update Mode and Beacon Mode */ -+ nicUpdateBss(prAdapter, NETWORK_TYPE_P2P_INDEX); -+ -+ /* 4 <3.3> Update Beacon again for network phy type confirmed. */ -+ bssUpdateBeaconContent(prAdapter, NETWORK_TYPE_P2P_INDEX); -+ -+#if 0 /* CFG_SUPPORT_HOTSPOT_OPTIMIZATION */ -+ { -+ CMD_HOTSPOT_OPTIMIZATION_CONFIG arHotspotOptimizationCfg; -+ -+ arHotspotOptimizationCfg.fgHotspotOptimizationEn = TRUE; -+ arHotspotOptimizationCfg.u4Level = (0x3) << 8 | 0x5; -+ wlanoidSendSetQueryP2PCmd(prAdapter, -+ CMD_ID_SET_HOTSPOT_OPTIMIZATION, -+ TRUE, -+ FALSE, -+ TRUE, -+ NULL, -+ NULL, -+ sizeof(CMD_HOTSPOT_OPTIMIZATION_CONFIG), -+ (PUINT_8)&arHotspotOptimizationCfg, NULL, 0); -+ } -+#endif -+ -+ /* 4 <3.4> Setup BSSID */ -+ nicPmIndicateBssCreated(prAdapter, NETWORK_TYPE_P2P_INDEX); -+ -+ } while (FALSE); -+ -+} /* p2pFuncStartGO() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is to inform CNM that channel privilege -+* has been released -+* -+* \param[in] prAdapter Pointer of ADAPTER_T -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID p2pFuncReleaseCh(IN P_ADAPTER_T prAdapter, IN P_P2P_CHNL_REQ_INFO_T prChnlReqInfo) -+{ -+ P_MSG_CH_ABORT_T prMsgChRelease = (P_MSG_CH_ABORT_T) NULL; -+ -+ DEBUGFUNC("p2pFuncReleaseCh()"); -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prChnlReqInfo != NULL)); -+ -+ if (!prChnlReqInfo->fgIsChannelRequested) -+ break; -+ -+ DBGLOG(P2P, TRACE, "P2P Release Channel\n"); -+ prChnlReqInfo->fgIsChannelRequested = FALSE; -+ -+ /* 1. return channel privilege to CNM immediately */ -+ prMsgChRelease = (P_MSG_CH_ABORT_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_CH_ABORT_T)); -+ if (!prMsgChRelease) { -+ ASSERT(0); /* Can't release Channel to CNM */ -+ break; -+ } -+ -+ prMsgChRelease->rMsgHdr.eMsgId = MID_MNY_CNM_CH_ABORT; -+ prMsgChRelease->ucNetTypeIndex = NETWORK_TYPE_P2P_INDEX; -+ prMsgChRelease->ucTokenID = prChnlReqInfo->ucSeqNumOfChReq++; -+ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgChRelease, MSG_SEND_METHOD_BUF); -+ -+ } while (FALSE); -+ -+} /* p2pFuncReleaseCh */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Process of CHANNEL_REQ_JOIN Initial. Enter CHANNEL_REQ_JOIN State. -+* -+* @param (none) -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID p2pFuncAcquireCh(IN P_ADAPTER_T prAdapter, IN P_P2P_CHNL_REQ_INFO_T prChnlReqInfo) -+{ -+ P_MSG_CH_REQ_T prMsgChReq = (P_MSG_CH_REQ_T) NULL; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prChnlReqInfo != NULL)); -+ -+ p2pFuncReleaseCh(prAdapter, prChnlReqInfo); -+ -+ /* send message to CNM for acquiring channel */ -+ prMsgChReq = (P_MSG_CH_REQ_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_CH_REQ_T)); -+ -+ if (!prMsgChReq) { -+ ASSERT(0); /* Can't indicate CNM for channel acquiring */ -+ break; -+ } -+ -+ prMsgChReq->rMsgHdr.eMsgId = MID_MNY_CNM_CH_REQ; -+ prMsgChReq->ucNetTypeIndex = NETWORK_TYPE_P2P_INDEX; -+ prMsgChReq->ucTokenID = ++prChnlReqInfo->ucSeqNumOfChReq; -+ prMsgChReq->eReqType = CH_REQ_TYPE_JOIN; -+ if (prChnlReqInfo->u4MaxInterval < P2P_EXT_LISTEN_TIME_MS) -+ prMsgChReq->u4MaxInterval = P2P_EXT_LISTEN_TIME_MS; -+ else -+ prMsgChReq->u4MaxInterval = prChnlReqInfo->u4MaxInterval; -+ -+ prMsgChReq->ucPrimaryChannel = prChnlReqInfo->ucReqChnlNum; -+ prMsgChReq->eRfSco = prChnlReqInfo->eChnlSco; -+ prMsgChReq->eRfBand = prChnlReqInfo->eBand; -+ -+ kalMemZero(prMsgChReq->aucBSSID, MAC_ADDR_LEN); -+ -+ /* Channel request join BSSID. */ -+ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgChReq, MSG_SEND_METHOD_BUF); -+ -+ prChnlReqInfo->fgIsChannelRequested = TRUE; -+ -+ } while (FALSE); -+ -+} /* p2pFuncAcquireCh */ -+ -+#if 0 -+WLAN_STATUS -+p2pFuncBeaconUpdate(IN P_ADAPTER_T prAdapter, -+ IN PUINT_8 pucBcnHdr, -+ IN UINT_32 u4HdrLen, -+ IN PUINT_8 pucBcnBody, IN UINT_32 u4BodyLen, IN UINT_32 u4DtimPeriod, IN UINT_32 u4BcnInterval) -+{ -+ WLAN_STATUS rResultStatus = WLAN_STATUS_INVALID_DATA; -+ P_WLAN_BEACON_FRAME_T prBcnFrame = (P_WLAN_BEACON_FRAME_T) NULL; -+ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; -+ P_MSDU_INFO_T prBcnMsduInfo = (P_MSDU_INFO_T) NULL; -+ PUINT_8 pucTIMBody = (PUINT_8) NULL; -+ UINT_16 u2FrameLength = 0, UINT_16 u2OldBodyLen = 0; -+ UINT_8 aucIEBuf[MAX_IE_LENGTH]; -+ -+ do { -+ ASSERT_BREAK(prAdapter != NULL); -+ -+ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); -+ prBcnMsduInfo = prP2pBssInfo->prBeacon ASSERT_BREAK(prBcnMsduInfo != NULL); -+ -+ /* TODO: Find TIM IE pointer. */ -+ prBcnFrame = prBcnMsduInfo->prPacket; -+ -+ ASSERT_BREAK(prBcnFrame != NULL); -+ -+ do { -+ /* Ori header. */ -+ UINT_16 u2IELength = 0, u2Offset = 0; -+ PUINT_8 pucIEBuf = prBcnFrame->aucInfoElem; -+ -+ u2IELength = prBcnMsduInfo->u2FrameLength - prBcnMsduInfo->ucMacHeaderLength; -+ -+ IE_FOR_EACH(pucIEBuf, u2IELength, u2Offset) { -+ if ((IE_ID(pucIEBuf) == ELEM_ID_TIM) || ((IE_ID(pucIEBuf) > ELEM_ID_IBSS_PARAM_SET))) { -+ pucTIMBody = pucIEBuf; -+ break; -+ } -+ u2FrameLength += IE_SIZE(pucIEBuf); -+ } -+ -+ if (pucTIMBody == NULL) -+ pucTIMBody = pucIEBuf; -+ -+ /* Body not change. */ -+ u2OldBodyLen = (UINT_16) ((UINT_32) pucTIMBody - (UINT_32) prBcnFrame->aucInfoElem); -+ /* Move body. */ -+ kalMemCmp(aucIEBuf, pucTIMBody, u2OldBodyLen); -+ } while (FALSE); -+ -+ if (pucBcnHdr) { -+ kalMemCopy(prBcnMsduInfo->prPacket, pucBcnHdr, u4HdrLen); -+ pucTIMBody = (PUINT_8) ((UINT_32) prBcnMsduInfo->prPacket + u4HdrLen); -+ prBcnMsduInfo->ucMacHeaderLength = (WLAN_MAC_MGMT_HEADER_LEN + -+ (TIMESTAMP_FIELD_LEN + BEACON_INTERVAL_FIELD_LEN + CAP_INFO_FIELD_LEN)); -+ u2FrameLength = u4HdrLen; /* Header + Partial Body. */ -+ } else { -+ /* Header not change. */ -+ u2FrameLength += prBcnMsduInfo->ucMacHeaderLength; -+ } -+ -+ if (pucBcnBody) { -+ kalMemCopy(pucTIMBody, pucBcnBody, u4BodyLen); -+ u2FrameLength += (UINT_16) u4BodyLen; -+ } else { -+ kalMemCopy(pucTIMBody, aucIEBuf, u2OldBodyLen); -+ u2FrameLength += u2OldBodyLen; -+ } -+ -+ /* Frame Length */ -+ prBcnMsduInfo->u2FrameLength = u2FrameLength; -+ prBcnMsduInfo->fgIs802_11 = TRUE; -+ prBcnMsduInfo->ucNetworkType = NETWORK_TYPE_P2P_INDEX; -+ prP2pBssInfo->u2BeaconInterval = (UINT_16) u4BcnInterval; -+ prP2pBssInfo->ucDTIMPeriod = (UINT_8) u4DtimPeriod; -+ prP2pBssInfo->u2CapInfo = prBcnFrame->u2CapInfo; -+ prBcnMsduInfo->ucPacketType = 3; -+ rResultStatus = nicUpdateBeaconIETemplate(prAdapter, -+ IE_UPD_METHOD_UPDATE_ALL, -+ NETWORK_TYPE_P2P_INDEX, -+ prP2pBssInfo->u2CapInfo, -+ (PUINT_8) prBcnFrame->aucInfoElem, -+ prBcnMsduInfo->u2FrameLength - -+ OFFSET_OF(WLAN_BEACON_FRAME_T, -+ aucInfoElem)); -+ if (prP2pBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT) { -+ /* AP is created, Beacon Update. */ -+ nicPmIndicateBssAbort(prAdapter, NETWORK_TYPE_P2P_INDEX); -+ nicPmIndicateBssCreated(prAdapter, NETWORK_TYPE_P2P_INDEX); -+ } -+ -+ } while (FALSE); -+ return rResultStatus; -+} /* p2pFuncBeaconUpdate */ -+ -+#else -+WLAN_STATUS -+ p2pFuncBeaconUpdate(IN P_ADAPTER_T prAdapter, -+ IN P_BSS_INFO_T prP2pBssInfo, -+ IN P_P2P_BEACON_UPDATE_INFO_T prBcnUpdateInfo, -+ IN PUINT_8 pucNewBcnHdr, IN UINT_32 u4NewHdrLen, IN PUINT_8 pucNewBcnBody, IN UINT_32 u4NewBodyLen) -+{ -+WLAN_STATUS rWlanStatus = WLAN_STATUS_SUCCESS; -+P_WLAN_BEACON_FRAME_T prBcnFrame = (P_WLAN_BEACON_FRAME_T) NULL; -+P_MSDU_INFO_T prBcnMsduInfo = (P_MSDU_INFO_T) NULL; -+PUINT_8 pucIEBuf = (PUINT_8) NULL; -+PUINT_8 paucIEBuf = (PUINT_8) NULL;/*[MAX_IE_LENGTH]; aucIEBuf*/ -+ -+do { -+ ASSERT_BREAK((prAdapter != NULL) && (prP2pBssInfo != NULL) && (prBcnUpdateInfo != NULL)); -+ -+ prBcnMsduInfo = prP2pBssInfo->prBeacon; -+ -+#if DBG -+ if (prBcnUpdateInfo->pucBcnHdr != NULL) { -+ ASSERT((UINT_32) prBcnUpdateInfo->pucBcnHdr == -+ ((UINT_32) prBcnMsduInfo->prPacket + MAC_TX_RESERVED_FIELD)); -+ } -+ -+ if (prBcnUpdateInfo->pucBcnBody != NULL) { -+ ASSERT((UINT_32) prBcnUpdateInfo->pucBcnBody == -+ ((UINT_32) prBcnUpdateInfo->pucBcnHdr + (UINT_32) prBcnUpdateInfo->u4BcnHdrLen)); -+ } -+#endif -+ prBcnFrame = (P_WLAN_BEACON_FRAME_T) ((ULONG) prBcnMsduInfo->prPacket + MAC_TX_RESERVED_FIELD); -+ -+ if (!pucNewBcnBody) { -+ /* Old body. */ -+ pucNewBcnBody = prBcnUpdateInfo->pucBcnBody; -+ ASSERT(u4NewBodyLen == 0); -+ u4NewBodyLen = prBcnUpdateInfo->u4BcnBodyLen; -+ } else { -+ prBcnUpdateInfo->u4BcnBodyLen = u4NewBodyLen; -+ } -+ -+ paucIEBuf = kalMemAlloc(MAX_IE_LENGTH, VIR_MEM_TYPE); -+ if (paucIEBuf == NULL) { -+ DBGLOG(P2P, TRACE, "p2p alloc paucIEBuf fail\n"); -+ return WLAN_STATUS_FAILURE; -+ } -+ -+ /* Temp buffer body part. */ -+ kalMemCopy(paucIEBuf, pucNewBcnBody, u4NewBodyLen); -+ -+ if (pucNewBcnHdr) { -+ kalMemCopy(prBcnFrame, pucNewBcnHdr, u4NewHdrLen); -+ prBcnUpdateInfo->pucBcnHdr = (PUINT_8) prBcnFrame; -+ prBcnUpdateInfo->u4BcnHdrLen = u4NewHdrLen; -+ } -+ -+ pucIEBuf = (PUINT_8) ((ULONG) prBcnUpdateInfo->pucBcnHdr + (UINT_32) prBcnUpdateInfo->u4BcnHdrLen); -+ kalMemCopy(pucIEBuf, paucIEBuf, u4NewBodyLen); -+ kalMemFree(paucIEBuf, VIR_MEM_TYPE, MAX_IE_LENGTH); -+ prBcnUpdateInfo->pucBcnBody = pucIEBuf; -+ -+ /* Frame Length */ -+ prBcnMsduInfo->u2FrameLength = (UINT_16) (prBcnUpdateInfo->u4BcnHdrLen + prBcnUpdateInfo->u4BcnBodyLen); -+ -+ prBcnMsduInfo->ucPacketType = 3; -+ prBcnMsduInfo->fgIs802_11 = TRUE; -+ prBcnMsduInfo->ucNetworkType = NETWORK_TYPE_P2P_INDEX; -+ -+ /* Update BSS INFO related information. */ -+ COPY_MAC_ADDR(prP2pBssInfo->aucOwnMacAddr, prBcnFrame->aucSrcAddr); -+ COPY_MAC_ADDR(prP2pBssInfo->aucBSSID, prBcnFrame->aucBSSID); -+ prP2pBssInfo->u2CapInfo = prBcnFrame->u2CapInfo; -+ -+ p2pFuncParseBeaconContent(prAdapter, -+ prP2pBssInfo, -+ (PUINT_8) prBcnFrame->aucInfoElem, -+ (prBcnMsduInfo->u2FrameLength - OFFSET_OF(WLAN_BEACON_FRAME_T, aucInfoElem))); -+ -+#if 1 -+ /* bssUpdateBeaconContent(prAdapter, NETWORK_TYPE_P2P_INDEX); */ -+#else -+ nicUpdateBeaconIETemplate(prAdapter, -+ IE_UPD_METHOD_UPDATE_ALL, -+ NETWORK_TYPE_P2P_INDEX, -+ prBcnFrame->u2CapInfo, -+ (PUINT_8) prBcnFrame->aucInfoElem, -+ (prBcnMsduInfo->u2FrameLength - OFFSET_OF(WLAN_BEACON_FRAME_T, aucInfoElem))); -+#endif -+} while (FALSE); -+ -+return rWlanStatus; -+} /* p2pFuncBeaconUpdate */ -+ -+#endif -+ -+/* TODO: We do not apply IE in deauth frame set from upper layer now. */ -+WLAN_STATUS -+p2pFuncDeauth(IN P_ADAPTER_T prAdapter, -+ IN PUINT_8 pucPeerMacAddr, -+ IN UINT_16 u2ReasonCode, IN PUINT_8 pucIEBuf, IN UINT_16 u2IELen, IN BOOLEAN fgSendDeauth) -+{ -+ WLAN_STATUS rWlanStatus = WLAN_STATUS_FAILURE; -+ P_STA_RECORD_T prCliStaRec = (P_STA_RECORD_T) NULL; -+ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; -+ BOOLEAN fgIsStaFound = FALSE; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (pucPeerMacAddr != NULL)); -+ -+ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); -+ -+ prCliStaRec = cnmGetStaRecByAddress(prAdapter, NETWORK_TYPE_P2P_INDEX, pucPeerMacAddr); -+ -+ switch (prP2pBssInfo->eCurrentOPMode) { -+ case OP_MODE_ACCESS_POINT: -+ { -+ P_LINK_T prStaRecOfClientList = (P_LINK_T) NULL; -+ P_LINK_ENTRY_T prLinkEntry = (P_LINK_ENTRY_T) NULL; -+ -+ prStaRecOfClientList = &(prP2pBssInfo->rStaRecOfClientList); -+ -+ LINK_FOR_EACH(prLinkEntry, prStaRecOfClientList) { -+ if ((ULONG) prCliStaRec == (ULONG) prLinkEntry) { -+ LINK_REMOVE_KNOWN_ENTRY(prStaRecOfClientList, &prCliStaRec->rLinkEntry); -+ fgIsStaFound = TRUE; -+ break; -+ } -+ } -+ -+ } -+ break; -+ case OP_MODE_INFRASTRUCTURE: -+ ASSERT(prCliStaRec == prP2pBssInfo->prStaRecOfAP); -+ if (prCliStaRec != prP2pBssInfo->prStaRecOfAP) -+ break; -+ prP2pBssInfo->prStaRecOfAP = NULL; -+ fgIsStaFound = TRUE; -+ break; -+ default: -+ break; -+ } -+ -+ if (fgIsStaFound) -+ p2pFuncDisconnect(prAdapter, prCliStaRec, fgSendDeauth, u2ReasonCode); -+ -+ rWlanStatus = WLAN_STATUS_SUCCESS; -+ } while (FALSE); -+ -+ return rWlanStatus; -+} /* p2pFuncDeauth */ -+ -+/* TODO: We do not apply IE in disassoc frame set from upper layer now. */ -+WLAN_STATUS -+p2pFuncDisassoc(IN P_ADAPTER_T prAdapter, -+ IN PUINT_8 pucPeerMacAddr, -+ IN UINT_16 u2ReasonCode, IN PUINT_8 pucIEBuf, IN UINT_16 u2IELen, IN BOOLEAN fgSendDisassoc) -+{ -+ WLAN_STATUS rWlanStatus = WLAN_STATUS_FAILURE; -+ P_STA_RECORD_T prCliStaRec = (P_STA_RECORD_T) NULL; -+ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; -+ BOOLEAN fgIsStaFound = FALSE; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (pucPeerMacAddr != NULL)); -+ -+ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); -+ -+ prCliStaRec = cnmGetStaRecByAddress(prAdapter, NETWORK_TYPE_P2P_INDEX, pucPeerMacAddr); -+ -+ switch (prP2pBssInfo->eCurrentOPMode) { -+ case OP_MODE_ACCESS_POINT: -+ { -+ P_LINK_T prStaRecOfClientList = (P_LINK_T) NULL; -+ P_LINK_ENTRY_T prLinkEntry = (P_LINK_ENTRY_T) NULL; -+ -+ prStaRecOfClientList = &(prP2pBssInfo->rStaRecOfClientList); -+ -+ LINK_FOR_EACH(prLinkEntry, prStaRecOfClientList) { -+ if ((ULONG) prCliStaRec == (ULONG) prLinkEntry) { -+ LINK_REMOVE_KNOWN_ENTRY(prStaRecOfClientList, &prCliStaRec->rLinkEntry); -+ fgIsStaFound = TRUE; -+ /* p2pFuncDisconnect(prAdapter, prCliStaRec, -+ * fgSendDisassoc, u2ReasonCode); */ -+ break; -+ } -+ } -+ -+ } -+ break; -+ case OP_MODE_INFRASTRUCTURE: -+ ASSERT(prCliStaRec == prP2pBssInfo->prStaRecOfAP); -+ if (prCliStaRec != prP2pBssInfo->prStaRecOfAP) -+ break; -+ /* p2pFuncDisconnect(prAdapter, prCliStaRec, fgSendDisassoc, u2ReasonCode); */ -+ prP2pBssInfo->prStaRecOfAP = NULL; -+ fgIsStaFound = TRUE; -+ break; -+ default: -+ break; -+ } -+ -+ if (fgIsStaFound) { -+ -+ p2pFuncDisconnect(prAdapter, prCliStaRec, fgSendDisassoc, u2ReasonCode); -+ /* 20120830 moved into p2pFuncDisconnect(). */ -+ /* cnmStaRecFree(prAdapter, prCliStaRec, TRUE); */ -+ -+ } -+ -+ rWlanStatus = WLAN_STATUS_SUCCESS; -+ } while (FALSE); -+ -+ return rWlanStatus; -+} /* p2pFuncDisassoc */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is called to dissolve from group or one group. (Would not change P2P FSM.) -+* 1. GC: Disconnect from AP. (Send Deauth) -+* 2. GO: Disconnect all STA -+* -+* @param[in] prAdapter Pointer to the adapter structure. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+p2pFuncDissolve(IN P_ADAPTER_T prAdapter, -+ IN P_BSS_INFO_T prP2pBssInfo, IN BOOLEAN fgSendDeauth, IN UINT_16 u2ReasonCode) -+{ -+ DEBUGFUNC("p2pFuncDissolve()"); -+ -+ do { -+ -+ ASSERT_BREAK((prAdapter != NULL) && (prP2pBssInfo != NULL)); -+ -+ switch (prP2pBssInfo->eCurrentOPMode) { -+ case OP_MODE_INFRASTRUCTURE: -+ /* Reset station record status. */ -+ if (prP2pBssInfo->prStaRecOfAP) { -+ kalP2PGCIndicateConnectionStatus(prAdapter->prGlueInfo, -+ NULL, NULL, 0, REASON_CODE_DEAUTH_LEAVING_BSS, -+ WLAN_STATUS_MEDIA_DISCONNECT_LOCALLY); -+ -+ /* 2012/02/14 frog: After formation before join group, prStaRecOfAP is NULL. */ -+ p2pFuncDisconnect(prAdapter, prP2pBssInfo->prStaRecOfAP, fgSendDeauth, u2ReasonCode); -+ } -+ -+ /* Fix possible KE when RX Beacon & call nicPmIndicateBssConnected(). -+ * hit prStaRecOfAP == NULL. */ -+ p2pChangeMediaState(prAdapter, PARAM_MEDIA_STATE_DISCONNECTED); -+ -+ prP2pBssInfo->prStaRecOfAP = NULL; -+ -+ break; -+ case OP_MODE_ACCESS_POINT: -+ /* Under AP mode, we would net send deauthentication frame to each STA. -+ * We only stop the Beacon & let all stations timeout. -+ */ -+ { -+ P_LINK_T prStaRecOfClientList = (P_LINK_T) NULL; -+ -+ /* Send deauth. */ -+ authSendDeauthFrame(prAdapter, -+ NULL, (P_SW_RFB_T) NULL, u2ReasonCode, (PFN_TX_DONE_HANDLER) NULL); -+ -+ prStaRecOfClientList = &prP2pBssInfo->rStaRecOfClientList; -+ -+ while (!LINK_IS_EMPTY(prStaRecOfClientList)) { -+ P_STA_RECORD_T prCurrStaRec; -+ -+ LINK_REMOVE_HEAD(prStaRecOfClientList, prCurrStaRec, P_STA_RECORD_T); -+ -+ /* Indicate to Host. */ -+ /* kalP2PGOStationUpdate(prAdapter->prGlueInfo, prCurrStaRec, FALSE); */ -+ -+ p2pFuncDisconnect(prAdapter, prCurrStaRec, TRUE, u2ReasonCode); -+ -+ } -+ prAdapter->rWifiVar.prP2pFsmInfo->rScanReqInfo.fgIsGOInitialDone = 0; -+ } -+ -+ break; -+ default: -+ return; /* 20110420 -- alreay in Device Mode. */ -+ } -+ -+ /* Make the deauth frame send to FW ASAP. */ -+ wlanAcquirePowerControl(prAdapter); -+ wlanProcessCommandQueue(prAdapter, &prAdapter->prGlueInfo->rCmdQueue); -+ wlanReleasePowerControl(prAdapter); -+ -+ kalMdelay(100); -+ -+ /* Change Connection Status. */ -+ p2pChangeMediaState(prAdapter, PARAM_MEDIA_STATE_DISCONNECTED); -+ -+ } while (FALSE); -+ -+} /* p2pFuncDissolve */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is called to dissolve from group or one group. (Would not change P2P FSM.) -+* 1. GC: Disconnect from AP. (Send Deauth) -+* 2. GO: Disconnect all STA -+* -+* @param[in] prAdapter Pointer to the adapter structure. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+p2pFuncDisconnect(IN P_ADAPTER_T prAdapter, -+ IN P_STA_RECORD_T prStaRec, IN BOOLEAN fgSendDeauth, IN UINT_16 u2ReasonCode) -+{ -+ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; -+ ENUM_PARAM_MEDIA_STATE_T eOriMediaStatus; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prStaRec != NULL)); -+ -+ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); -+ eOriMediaStatus = prP2pBssInfo->eConnectionState; -+ -+ /* Indicate disconnect. */ -+ /* TODO: */ -+ /* kalP2PGOStationUpdate */ -+ /* kalP2PGCIndicateConnectionStatus */ -+ /* p2pIndicationOfMediaStateToHost(prAdapter, PARAM_MEDIA_STATE_DISCONNECTED, prStaRec->aucMacAddr); */ -+ DBGLOG(P2P, INFO, "p2pFuncDisconnect, eCurrentOPMode: %d, sendDeauth: %s\n", -+ prP2pBssInfo->eCurrentOPMode, fgSendDeauth ? "True" : "False"); -+ if (prP2pBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT) -+ kalP2PGOStationUpdate(prAdapter->prGlueInfo, prStaRec, FALSE); -+ -+ if (fgSendDeauth) { -+ /* Send deauth. */ -+ authSendDeauthFrame(prAdapter, -+ prStaRec, -+ (P_SW_RFB_T) NULL, -+ u2ReasonCode, (PFN_TX_DONE_HANDLER) p2pFsmRunEventDeauthTxDone); -+ } else { -+ /* Change station state. */ -+ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); -+ -+ /* Reset Station Record Status. */ -+ p2pFuncResetStaRecStatus(prAdapter, prStaRec); -+ -+ cnmStaRecFree(prAdapter, prStaRec, TRUE); -+ -+ if ((prP2pBssInfo->eCurrentOPMode != OP_MODE_ACCESS_POINT) || -+ (prP2pBssInfo->rStaRecOfClientList.u4NumElem == 0)) { -+ DBGLOG(P2P, TRACE, "No More Client, Media Status DISCONNECTED\n"); -+ p2pChangeMediaState(prAdapter, PARAM_MEDIA_STATE_DISCONNECTED); -+ } -+ -+ if (eOriMediaStatus != prP2pBssInfo->eConnectionState) { -+ /* Update Disconnected state to FW. */ -+ nicUpdateBss(prAdapter, NETWORK_TYPE_P2P_INDEX); -+ } -+ -+ } -+ -+ if (prP2pBssInfo->eCurrentOPMode != OP_MODE_ACCESS_POINT) { -+ /* GO: It would stop Beacon TX. GC: Stop all BSS related PS function. */ -+ nicPmIndicateBssAbort(prAdapter, NETWORK_TYPE_P2P_INDEX); -+ -+ /* Reset RLM related field of BSSINFO. */ -+ rlmBssAborted(prAdapter, prP2pBssInfo); -+ } -+ -+ } while (FALSE); -+ -+ return; -+ -+} /* p2pFuncDisconnect */ -+ -+/* Action frame categories (IEEE 802.11-2007, 7.3.1.11, Table 7-24) */ -+#define WLAN_ACTION_SPECTRUM_MGMT 0 -+#define WLAN_ACTION_QOS 1 -+#define WLAN_ACTION_DLS 2 -+#define WLAN_ACTION_BLOCK_ACK 3 -+#define WLAN_ACTION_PUBLIC 4 -+#define WLAN_ACTION_RADIO_MEASUREMENT 5 -+#define WLAN_ACTION_FT 6 -+#define WLAN_ACTION_HT 7 -+#define WLAN_ACTION_SA_QUERY 8 -+#define WLAN_ACTION_PROTECTED_DUAL 9 -+#define WLAN_ACTION_WNM 10 -+#define WLAN_ACTION_UNPROTECTED_WNM 11 -+#define WLAN_ACTION_TDLS 12 -+#define WLAN_ACTION_SELF_PROTECTED 15 -+#define WLAN_ACTION_WMM 17 /* WMM Specification 1.1 */ -+#define WLAN_ACTION_VENDOR_SPECIFIC 127 -+ -+/* Public action codes */ -+#define WLAN_PA_20_40_BSS_COEX 0 -+#define WLAN_PA_VENDOR_SPECIFIC 9 -+#define WLAN_PA_GAS_INITIAL_REQ 10 -+#define WLAN_PA_GAS_INITIAL_RESP 11 -+#define WLAN_PA_GAS_COMEBACK_REQ 12 -+#define WLAN_PA_GAS_COMEBACK_RESP 13 -+#define WLAN_TDLS_DISCOVERY_RESPONSE 14 -+ -+/* P2P public action frames */ -+enum p2p_action_frame_type { -+ P2P_GO_NEG_REQ = 0, -+ P2P_GO_NEG_RESP = 1, -+ P2P_GO_NEG_CONF = 2, -+ P2P_INVITATION_REQ = 3, -+ P2P_INVITATION_RESP = 4, -+ P2P_DEV_DISC_REQ = 5, -+ P2P_DEV_DISC_RESP = 6, -+ P2P_PROV_DISC_REQ = 7, -+ P2P_PROV_DISC_RESP = 8 -+}; -+ -+const char *p2p_to_string(enum p2p_action_frame_type p2p_action) -+{ -+ switch (p2p_action) { -+ case P2P_GO_NEG_REQ: -+ return "GO_NEG_REQ"; -+ case P2P_GO_NEG_RESP: -+ return "GO_NEG_RESP"; -+ case P2P_GO_NEG_CONF: -+ return "GO_NEG_CONF"; -+ case P2P_INVITATION_REQ: -+ return "INVITATION_REQ"; -+ case P2P_INVITATION_RESP: -+ return "INVITATION_RESP"; -+ case P2P_DEV_DISC_REQ: -+ return "DEV_DISC_REQ"; -+ case P2P_DEV_DISC_RESP: -+ return "DEV_DISC_RESP"; -+ case P2P_PROV_DISC_REQ: -+ return "PROV_DISC_REQ"; -+ case P2P_PROV_DISC_RESP: -+ return "PROV_DISC_RESP"; -+ } -+ -+ return "UNKNOWN P2P Public Action"; -+} -+const char *pa_to_string(int pa_action) -+{ -+ switch (pa_action) { -+ case WLAN_PA_20_40_BSS_COEX: -+ return "PA_20_40_BSS_COEX"; -+ case WLAN_PA_VENDOR_SPECIFIC: -+ return "PA_VENDOR_SPECIFIC"; -+ case WLAN_PA_GAS_INITIAL_REQ: -+ return "PA_GAS_INITIAL_REQ"; -+ case WLAN_PA_GAS_INITIAL_RESP: -+ return "PA_GAS_INITIAL_RESP"; -+ case WLAN_PA_GAS_COMEBACK_REQ: -+ return "PA_GAS_COMEBACK_REQ"; -+ case WLAN_PA_GAS_COMEBACK_RESP: -+ return "PA_GAS_COMEBACK_RESP"; -+ case WLAN_TDLS_DISCOVERY_RESPONSE: -+ return "TDLS_DISCOVERY_RESPONSE"; -+ } -+ -+ return "UNKNOWN Public Action"; -+} -+ -+const char *action_to_string(int wlan_action) -+{ -+ switch (wlan_action) { -+ case WLAN_ACTION_SPECTRUM_MGMT: -+ return "SPECTRUM_MGMT"; -+ case WLAN_ACTION_QOS: -+ return "QOS"; -+ case WLAN_ACTION_DLS: -+ return "DLS"; -+ case WLAN_ACTION_BLOCK_ACK: -+ return "BLOCK_ACK"; -+ case WLAN_ACTION_PUBLIC: -+ return "PUBLIC"; -+ case WLAN_ACTION_RADIO_MEASUREMENT: -+ return "RADIO_MEASUREMENT"; -+ case WLAN_ACTION_FT: -+ return "FT"; -+ case WLAN_ACTION_HT: -+ return "HT"; -+ case WLAN_ACTION_SA_QUERY: -+ return "SA_QUERY"; -+ case WLAN_ACTION_PROTECTED_DUAL: -+ return "PROTECTED_DUAL"; -+ case WLAN_ACTION_WNM: -+ return "WNM"; -+ case WLAN_ACTION_UNPROTECTED_WNM: -+ return "UNPROTECTED_WNM"; -+ case WLAN_ACTION_TDLS: -+ return "TDLS"; -+ case WLAN_ACTION_SELF_PROTECTED: -+ return "SELF_PROTECTED"; -+ case WLAN_ACTION_WMM: -+ return "WMM"; -+ case WLAN_ACTION_VENDOR_SPECIFIC: -+ return "VENDOR_SPECIFIC"; -+ } -+ -+ return "UNKNOWN Action Frame"; -+} -+ -+VOID p2pFuncTagActionActionP2PFrame(IN P_MSDU_INFO_T prMgmtTxMsdu, -+ IN P_WLAN_ACTION_FRAME prActFrame, -+ IN UINT_8 ucP2pAction, IN UINT_64 u8Cookie) -+{ -+ DBGLOG(P2P, INFO, "Found P2P_%s, SA: %pM - DA: %pM, cookie: 0x%llx, SeqNO: %d\n", -+ p2p_to_string(ucP2pAction), -+ prActFrame->aucSrcAddr, -+ prActFrame->aucDestAddr, -+ u8Cookie, -+ prMgmtTxMsdu->ucTxSeqNum); -+} -+ -+VOID p2pFuncTagActionActionFrame(IN P_MSDU_INFO_T prMgmtTxMsdu, -+ IN P_WLAN_ACTION_FRAME prActFrame, -+ IN UINT_8 ucAction, IN UINT_64 u8Cookie) -+{ -+ PUINT_8 pucVendor = NULL; -+ -+ DBGLOG(P2P, INFO, "Found WLAN_%s, SA: %pM - DA: %pM, cookie: 0x%llx, SeqNo: %d\n", -+ pa_to_string(ucAction), -+ prActFrame->aucSrcAddr, -+ prActFrame->aucDestAddr, -+ u8Cookie, -+ prMgmtTxMsdu->ucTxSeqNum); -+ -+ if (ucAction == WLAN_PA_VENDOR_SPECIFIC) { -+ pucVendor = (PUINT_8)prActFrame + 26; -+ if (*(pucVendor + 0) == 0x50 && -+ *(pucVendor + 1) == 0x6f && -+ *(pucVendor + 2) == 0x9a) { -+ if (*(pucVendor + 3) == 0x09) -+ /* found p2p IE */ -+ p2pFuncTagActionActionP2PFrame(prMgmtTxMsdu, -+ prActFrame, *(pucVendor + 4), u8Cookie); -+ else if (*(pucVendor + 3) == 0x0a) -+ /* found WFD IE */ -+ DBGLOG(P2P, INFO, "Found WFD IE, SA: %pM - DA: %pM\n", -+ prActFrame->aucSrcAddr, -+ prActFrame->aucDestAddr); -+ else -+ DBGLOG(P2P, INFO, "Found Other vendor 0x%x, SA: %pM - DA: %pM\n", -+ *(pucVendor + 3), -+ prActFrame->aucSrcAddr, -+ prActFrame->aucDestAddr); -+ } -+ } -+} -+ -+VOID p2pFuncTagActionCategoryFrame(IN P_MSDU_INFO_T prMgmtTxMsdu, -+ P_WLAN_ACTION_FRAME prActFrame, -+ IN UINT_8 ucCategory, -+ IN UINT_64 u8Cookie) -+{ -+ -+ UINT_8 ucAction = 0; -+ -+ DBGLOG(P2P, INFO, "Found WLAN_ACTION_%s, SA: %pM - DA: %pM, u8Cookie: 0x%llx, SeqNO: %d\n", -+ action_to_string(ucCategory), -+ prActFrame->aucSrcAddr, -+ prActFrame->aucDestAddr, -+ u8Cookie, -+ prMgmtTxMsdu->ucTxSeqNum); -+ -+ if (ucCategory == WLAN_ACTION_PUBLIC) { -+ ucAction = prActFrame->ucAction; -+ p2pFuncTagActionActionFrame(prMgmtTxMsdu, prActFrame, ucAction, u8Cookie); -+ -+ } -+} -+ -+/* -+ * used to debug p2p mgmt frame: -+ * GO Nego Req -+ * GO Nego Res -+ * GO Nego Confirm -+ * GO Invite Req -+ * GO Invite Res -+ * Device Discoverability Req -+ * Device Discoverability Res -+ * Provision Discovery Req -+ * Provision Discovery Res -+ */ -+ -+VOID -+p2pFuncTagMgmtFrame(IN P_MSDU_INFO_T prMgmtTxMsdu, IN UINT_64 u8Cookie) -+{ -+ /* P_MSDU_INFO_T prTxMsduInfo = (P_MSDU_INFO_T)NULL; */ -+ P_WLAN_MAC_HEADER_T prWlanHdr = (P_WLAN_MAC_HEADER_T) NULL; -+ P_WLAN_PROBE_RSP_FRAME_T prProbRspHdr = (P_WLAN_PROBE_RSP_FRAME_T)NULL; -+ UINT_16 u2TxFrameCtrl; -+ P_WLAN_ACTION_FRAME prActFrame; -+ UINT_8 ucCategory; -+ -+ prWlanHdr = (P_WLAN_MAC_HEADER_T) ((ULONG) prMgmtTxMsdu->prPacket + MAC_TX_RESERVED_FIELD); -+ /* -+ * mgmt frame MASK_FC_TYPE = 0 -+ * use MASK_FRAME_TYPE is oK for frame type/subtype judge -+ */ -+ u2TxFrameCtrl = prWlanHdr->u2FrameCtrl & MASK_FRAME_TYPE; -+ -+ switch (u2TxFrameCtrl) { -+ case MAC_FRAME_PROBE_RSP: -+ -+ prProbRspHdr = (P_WLAN_PROBE_RSP_FRAME_T) prWlanHdr; -+ DBGLOG(P2P, INFO, "TX Probe Response Frame, SA: %pM - DA: %pM, cookie: 0x%llx, seqNo: %d\n", -+ prProbRspHdr->aucSrcAddr, prProbRspHdr->aucDestAddr, -+ u8Cookie, -+ prMgmtTxMsdu->ucTxSeqNum); -+ -+ break; -+ -+ case MAC_FRAME_ACTION: -+ -+ prActFrame = (P_WLAN_ACTION_FRAME)prWlanHdr; -+ ucCategory = prActFrame->ucCategory; -+ p2pFuncTagActionCategoryFrame(prMgmtTxMsdu, prActFrame, -+ ucCategory, u8Cookie); -+ -+ break; -+ default: -+ DBGLOG(P2P, INFO, "MGMT:, un-tagged frame type: 0x%x, A1: %pM, A2: %pM, A3: %pM seqNo: %d\n", -+ u2TxFrameCtrl, -+ prWlanHdr->aucAddr1, -+ prWlanHdr->aucAddr2, -+ prWlanHdr->aucAddr3, -+ prMgmtTxMsdu->ucTxSeqNum); -+ break; -+ } -+} -+ -+WLAN_STATUS -+p2pFuncTxMgmtFrame(IN P_ADAPTER_T prAdapter, -+ IN P_P2P_MGMT_TX_REQ_INFO_T prMgmtTxReqInfo, IN P_MSDU_INFO_T prMgmtTxMsdu, IN UINT_64 u8Cookie) -+{ -+ WLAN_STATUS rWlanStatus = WLAN_STATUS_SUCCESS; -+ P_MSDU_INFO_T prTxMsduInfo = (P_MSDU_INFO_T) NULL; -+ P_WLAN_MAC_HEADER_T prWlanHdr = (P_WLAN_MAC_HEADER_T) NULL; -+ P_STA_RECORD_T prStaRec = (P_STA_RECORD_T) NULL; -+ BOOLEAN fgIsProbrsp = FALSE; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prMgmtTxReqInfo != NULL)); -+ -+ if (prMgmtTxReqInfo->fgIsMgmtTxRequested) { -+ -+ /* 1. prMgmtTxReqInfo->prMgmtTxMsdu != NULL */ -+ /* Packet on driver, not done yet, drop it. */ -+ prTxMsduInfo = prMgmtTxReqInfo->prMgmtTxMsdu; -+ if (prTxMsduInfo != NULL) { -+ -+ kalP2PIndicateMgmtTxStatus(prAdapter->prGlueInfo, -+ prMgmtTxReqInfo->u8Cookie, -+ FALSE, -+ prTxMsduInfo->prPacket, -+ (UINT_32) prTxMsduInfo->u2FrameLength); -+ -+ /* Leave it to TX Done handler. */ -+ /* cnmMgtPktFree(prAdapter, prTxMsduInfo); */ -+ prMgmtTxReqInfo->prMgmtTxMsdu = NULL; -+ DBGLOG(P2P, INFO, "p2pFuncTxMgmtFrame: Drop MGMT cookie: 0x%llx\n", -+ prMgmtTxReqInfo->u8Cookie); -+ } -+ /* 2. prMgmtTxReqInfo->prMgmtTxMsdu == NULL */ -+ /* Packet transmitted, wait tx done. (cookie issue) */ -+ /* 20120105 frog - use another u8cookie to store this value. */ -+ } -+ -+ ASSERT(prMgmtTxReqInfo->prMgmtTxMsdu == NULL); -+ -+ prWlanHdr = (P_WLAN_MAC_HEADER_T) ((ULONG) prMgmtTxMsdu->prPacket + MAC_TX_RESERVED_FIELD); -+ prStaRec = cnmGetStaRecByAddress(prAdapter, NETWORK_TYPE_P2P_INDEX, prWlanHdr->aucAddr1); -+ prMgmtTxMsdu->ucNetworkType = (UINT_8) NETWORK_TYPE_P2P_INDEX; -+ -+ switch (prWlanHdr->u2FrameCtrl & MASK_FRAME_TYPE) { -+ case MAC_FRAME_PROBE_RSP: -+ DBGLOG(P2P, TRACE, "p2pFuncTxMgmtFrame: TX MAC_FRAME_PROBE_RSP\n"); -+ fgIsProbrsp = TRUE; -+ prMgmtTxMsdu = p2pFuncProcessP2pProbeRsp(prAdapter, prMgmtTxMsdu); -+ break; -+ default: -+ break; -+ } -+ -+ prMgmtTxReqInfo->u8Cookie = u8Cookie; -+ prMgmtTxReqInfo->prMgmtTxMsdu = prMgmtTxMsdu; -+ prMgmtTxReqInfo->fgIsMgmtTxRequested = TRUE; -+ -+ prMgmtTxMsdu->eSrc = TX_PACKET_MGMT; -+ prMgmtTxMsdu->ucPacketType = HIF_TX_PACKET_TYPE_MGMT; -+ prMgmtTxMsdu->ucStaRecIndex = (prStaRec != NULL) ? (prStaRec->ucIndex) : (0xFF); -+ if (prStaRec != NULL) -+ DBGLOG(P2P, TRACE, "Mgmt with station record: %pM.\n", prStaRec->aucMacAddr); -+ -+ prMgmtTxMsdu->ucMacHeaderLength = WLAN_MAC_MGMT_HEADER_LEN; /* TODO: undcertain. */ -+ prMgmtTxMsdu->fgIs802_1x = FALSE; -+ prMgmtTxMsdu->fgIs802_11 = TRUE; -+ prMgmtTxMsdu->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter); -+ prMgmtTxMsdu->pfTxDoneHandler = p2pFsmRunEventMgmtFrameTxDone; -+ prMgmtTxMsdu->fgIsBasicRate = TRUE; -+ -+ p2pFuncTagMgmtFrame(prMgmtTxMsdu, u8Cookie); -+ -+ nicTxEnqueueMsdu(prAdapter, prMgmtTxMsdu); -+ -+ } while (FALSE); -+ -+ return rWlanStatus; -+} /* p2pFuncTxMgmtFrame */ -+ -+VOID p2pFuncSetChannel(IN P_ADAPTER_T prAdapter, IN P_RF_CHANNEL_INFO_T prRfChannelInfo) -+{ -+ P_P2P_CONNECTION_SETTINGS_T prP2pConnSettings = (P_P2P_CONNECTION_SETTINGS_T) NULL; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prRfChannelInfo != NULL)); -+ -+ prP2pConnSettings = prAdapter->rWifiVar.prP2PConnSettings; -+ -+ prP2pConnSettings->ucOperatingChnl = prRfChannelInfo->ucChannelNum; -+ prP2pConnSettings->eBand = prRfChannelInfo->eBand; -+ -+ } while (FALSE); -+ -+} -+ -+/* p2pFuncSetChannel */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Retry JOIN for AUTH_MODE_AUTO_SWITCH -+* -+* @param[in] prStaRec Pointer to the STA_RECORD_T -+* -+* @retval TRUE We will retry JOIN -+* @retval FALSE We will not retry JOIN -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN p2pFuncRetryJOIN(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN P_P2P_JOIN_INFO_T prJoinInfo) -+{ -+ P_MSG_JOIN_REQ_T prJoinReqMsg = (P_MSG_JOIN_REQ_T) NULL; -+ BOOLEAN fgRetValue = FALSE; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prStaRec != NULL) && (prJoinInfo != NULL)); -+ -+ /* Retry other AuthType if possible */ -+ if (!prJoinInfo->ucAvailableAuthTypes) -+ break; -+ -+ if (prJoinInfo->ucAvailableAuthTypes & (UINT_8) AUTH_TYPE_SHARED_KEY) { -+ -+ DBGLOG(P2P, INFO, "RETRY JOIN INIT: Retry Authentication with AuthType == SHARED_KEY.\n"); -+ -+ prJoinInfo->ucAvailableAuthTypes &= ~(UINT_8) AUTH_TYPE_SHARED_KEY; -+ -+ prStaRec->ucAuthAlgNum = (UINT_8) AUTH_ALGORITHM_NUM_SHARED_KEY; -+ } else { -+ DBGLOG(P2P, ERROR, "RETRY JOIN INIT: Retry Authentication with Unexpected AuthType.\n"); -+ ASSERT(0); -+ break; -+ } -+ -+ prJoinInfo->ucAvailableAuthTypes = 0; /* No more available Auth Types */ -+ -+ /* Trigger SAA to start JOIN process. */ -+ prJoinReqMsg = (P_MSG_JOIN_REQ_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_JOIN_REQ_T)); -+ if (!prJoinReqMsg) { -+ ASSERT(0); /* Can't trigger SAA FSM */ -+ break; -+ } -+ -+ prJoinReqMsg->rMsgHdr.eMsgId = MID_P2P_SAA_FSM_START; -+ prJoinReqMsg->ucSeqNum = ++prJoinInfo->ucSeqNumOfReqMsg; -+ prJoinReqMsg->prStaRec = prStaRec; -+ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prJoinReqMsg, MSG_SEND_METHOD_BUF); -+ -+ fgRetValue = TRUE; -+ } while (FALSE); -+ -+ return fgRetValue; -+ -+} /* end of p2pFuncRetryJOIN() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will update the contain of BSS_INFO_T for AIS network once -+* the association was completed. -+* -+* @param[in] prStaRec Pointer to the STA_RECORD_T -+* @param[in] prAssocRspSwRfb Pointer to SW RFB of ASSOC RESP FRAME. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+p2pFuncUpdateBssInfoForJOIN(IN P_ADAPTER_T prAdapter, -+ IN P_BSS_DESC_T prBssDesc, IN P_STA_RECORD_T prStaRec, IN P_SW_RFB_T prAssocRspSwRfb) -+{ -+ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; -+ P_P2P_CONNECTION_SETTINGS_T prP2pConnSettings = (P_P2P_CONNECTION_SETTINGS_T) NULL; -+ P_WLAN_ASSOC_RSP_FRAME_T prAssocRspFrame = (P_WLAN_ASSOC_RSP_FRAME_T) NULL; -+ UINT_16 u2IELength; -+ PUINT_8 pucIE; -+ -+ DEBUGFUNC("p2pUpdateBssInfoForJOIN()"); -+ -+ ASSERT(prAdapter); -+ ASSERT(prStaRec); -+ ASSERT(prAssocRspSwRfb); -+ -+ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); -+ prP2pConnSettings = prAdapter->rWifiVar.prP2PConnSettings; -+ prAssocRspFrame = (P_WLAN_ASSOC_RSP_FRAME_T) prAssocRspSwRfb->pvHeader; -+ -+ DBGLOG(P2P, INFO, "Update P2P_BSS_INFO_T and apply settings to MAC\n"); -+ -+ /* 3 <1> Update BSS_INFO_T from AIS_FSM_INFO_T or User Settings */ -+ /* 4 <1.1> Setup Operation Mode */ -+ prP2pBssInfo->eCurrentOPMode = OP_MODE_INFRASTRUCTURE; -+ -+ /* 4 <1.2> Setup SSID */ -+ COPY_SSID(prP2pBssInfo->aucSSID, -+ prP2pBssInfo->ucSSIDLen, prP2pConnSettings->aucSSID, prP2pConnSettings->ucSSIDLen); -+ -+ if (prBssDesc == NULL) { -+ /* Target BSS NULL. */ -+ DBGLOG(P2P, TRACE, "Target BSS NULL\n"); -+ return; -+ } -+ -+ if (UNEQUAL_MAC_ADDR(prBssDesc->aucBSSID, prAssocRspFrame->aucBSSID)) -+ ASSERT(FALSE); -+ /* 4 <1.3> Setup Channel, Band */ -+ prP2pBssInfo->ucPrimaryChannel = prBssDesc->ucChannelNum; -+ prP2pBssInfo->eBand = prBssDesc->eBand; -+ -+ /* 3 <2> Update BSS_INFO_T from STA_RECORD_T */ -+ /* 4 <2.1> Save current AP's STA_RECORD_T and current AID */ -+ prP2pBssInfo->prStaRecOfAP = prStaRec; -+ prP2pBssInfo->u2AssocId = prStaRec->u2AssocId; -+ -+ /* 4 <2.2> Setup Capability */ -+ prP2pBssInfo->u2CapInfo = prStaRec->u2CapInfo; /* Use AP's Cap Info as BSS Cap Info */ -+ -+ if (prP2pBssInfo->u2CapInfo & CAP_INFO_SHORT_PREAMBLE) -+ prP2pBssInfo->fgIsShortPreambleAllowed = TRUE; -+ else -+ prP2pBssInfo->fgIsShortPreambleAllowed = FALSE; -+ -+ /* 4 <2.3> Setup PHY Attributes and Basic Rate Set/Operational Rate Set */ -+ prP2pBssInfo->ucPhyTypeSet = prStaRec->ucDesiredPhyTypeSet; -+ -+ prP2pBssInfo->ucNonHTBasicPhyType = prStaRec->ucNonHTBasicPhyType; -+ -+ prP2pBssInfo->u2OperationalRateSet = prStaRec->u2OperationalRateSet; -+ prP2pBssInfo->u2BSSBasicRateSet = prStaRec->u2BSSBasicRateSet; -+ -+ /* 3 <3> Update BSS_INFO_T from SW_RFB_T (Association Resp Frame) */ -+ /* 4 <3.1> Setup BSSID */ -+ COPY_MAC_ADDR(prP2pBssInfo->aucBSSID, prAssocRspFrame->aucBSSID); -+ -+ u2IELength = (UINT_16) ((prAssocRspSwRfb->u2PacketLen - prAssocRspSwRfb->u2HeaderLen) - -+ (OFFSET_OF(WLAN_ASSOC_RSP_FRAME_T, aucInfoElem[0]) - WLAN_MAC_MGMT_HEADER_LEN)); -+ pucIE = prAssocRspFrame->aucInfoElem; -+ -+ /* 4 <3.2> Parse WMM and setup QBSS flag */ -+ /* Parse WMM related IEs and configure HW CRs accordingly */ -+ mqmProcessAssocRsp(prAdapter, prAssocRspSwRfb, pucIE, u2IELength); -+ -+ prP2pBssInfo->fgIsQBSS = prStaRec->fgIsQoS; -+ -+ /* 3 <4> Update BSS_INFO_T from BSS_DESC_T */ -+ ASSERT(prBssDesc); -+ -+ prBssDesc->fgIsConnecting = FALSE; -+ prBssDesc->fgIsConnected = TRUE; -+ -+ /* 4 <4.1> Setup MIB for current BSS */ -+ prP2pBssInfo->u2BeaconInterval = prBssDesc->u2BeaconInterval; -+ /* NOTE: Defer ucDTIMPeriod updating to when beacon is received after connection */ -+ prP2pBssInfo->ucDTIMPeriod = 0; -+ prP2pBssInfo->u2ATIMWindow = 0; -+ -+ prP2pBssInfo->ucBeaconTimeoutCount = AIS_BEACON_TIMEOUT_COUNT_INFRA; -+ -+ /* 4 <4.2> Update HT information and set channel */ -+ /* Record HT related parameters in rStaRec and rBssInfo -+ * Note: it shall be called before nicUpdateBss() -+ */ -+ rlmProcessAssocRsp(prAdapter, prAssocRspSwRfb, pucIE, u2IELength); -+ -+ /* 4 <4.3> Sync with firmware for BSS-INFO */ -+ nicUpdateBss(prAdapter, NETWORK_TYPE_P2P_INDEX); -+ -+ /* 4 <4.4> *DEFER OPERATION* nicPmIndicateBssConnected() will be invoked */ -+ /* inside scanProcessBeaconAndProbeResp() after 1st beacon is received */ -+ -+} /* end of p2pUpdateBssInfoForJOIN() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will validate the Rx Auth Frame and then return -+* the status code to AAA to indicate if need to perform following actions -+* when the specified conditions were matched. -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* @param[in] prSwRfb Pointer to SW RFB data structure. -+* @param[in] pprStaRec Pointer to pointer of STA_RECORD_T structure. -+* @param[out] pu2StatusCode The Status Code of Validation Result -+* -+* @retval TRUE Reply the Auth -+* @retval FALSE Don't reply the Auth -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN -+p2pFuncValidateAuth(IN P_ADAPTER_T prAdapter, -+ IN P_SW_RFB_T prSwRfb, IN PP_STA_RECORD_T pprStaRec, OUT PUINT_16 pu2StatusCode) -+{ -+ BOOLEAN fgReplyAuth = TRUE; -+ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; -+ P_STA_RECORD_T prStaRec = (P_STA_RECORD_T) NULL; -+ P_WLAN_AUTH_FRAME_T prAuthFrame = (P_WLAN_AUTH_FRAME_T) NULL; -+ -+ DBGLOG(P2P, INFO, "p2pValidate Authentication Frame\n"); -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && -+ (prSwRfb != NULL) && (pprStaRec != NULL) && (pu2StatusCode != NULL)); -+ -+ /* P2P 3.2.8 */ -+ *pu2StatusCode = STATUS_CODE_REQ_DECLINED; -+ -+ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); -+ prAuthFrame = (P_WLAN_AUTH_FRAME_T) prSwRfb->pvHeader; -+ -+ if ((prP2pBssInfo->eCurrentOPMode != OP_MODE_ACCESS_POINT) -+ || (prP2pBssInfo->eIntendOPMode != OP_MODE_NUM)) { -+ /* We are not under AP Mode yet. */ -+ fgReplyAuth = FALSE; -+ DBGLOG(P2P, WARN, -+ "Current OP mode is not under AP mode. (%d)\n", prP2pBssInfo->eCurrentOPMode); -+ break; -+ } -+ -+ prStaRec = cnmGetStaRecByAddress(prAdapter, (UINT_8) NETWORK_TYPE_P2P_INDEX, prAuthFrame->aucSrcAddr); -+ -+ if (!prStaRec) { -+ prStaRec = cnmStaRecAlloc(prAdapter, (UINT_8) NETWORK_TYPE_P2P_INDEX); -+ -+ /* TODO(Kevin): Error handling of allocation of STA_RECORD_T for -+ * exhausted case and do removal of unused STA_RECORD_T. -+ */ -+ /* Sent a message event to clean un-used STA_RECORD_T. */ -+ ASSERT(prStaRec); -+ if (!prStaRec) { -+ DBGLOG(AAA, INFO, "Station Limit Full. Decline a new Authentication.\n"); -+ break; -+ } -+ -+ COPY_MAC_ADDR(prStaRec->aucMacAddr, prAuthFrame->aucSrcAddr); -+ -+ prSwRfb->ucStaRecIdx = prStaRec->ucIndex; -+ -+ prStaRec->u2BSSBasicRateSet = prP2pBssInfo->u2BSSBasicRateSet; -+ -+ prStaRec->u2DesiredNonHTRateSet = RATE_SET_ERP_P2P; -+ -+ prStaRec->u2OperationalRateSet = RATE_SET_ERP_P2P; -+ prStaRec->ucPhyTypeSet = PHY_TYPE_SET_802_11GN; -+ prStaRec->eStaType = STA_TYPE_P2P_GC; -+ -+ /* NOTE(Kevin): Better to change state here, not at TX Done */ -+ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); -+ } else { -+ prSwRfb->ucStaRecIdx = prStaRec->ucIndex; -+ -+ if ((prStaRec->ucStaState > STA_STATE_1) && (IS_STA_IN_P2P(prStaRec))) { -+ -+ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); -+ -+ p2pFuncResetStaRecStatus(prAdapter, prStaRec); -+ -+ bssRemoveStaRecFromClientList(prAdapter, prP2pBssInfo, prStaRec); -+ } -+ -+ } -+ -+ if (prP2pBssInfo->rStaRecOfClientList.u4NumElem >= P2P_MAXIMUM_CLIENT_COUNT || -+ kalP2PMaxClients(prAdapter->prGlueInfo, prP2pBssInfo->rStaRecOfClientList.u4NumElem)) { -+ /* GROUP limit full. */ -+ /* P2P 3.2.8 */ -+ DBGLOG(P2P, WARN, -+ "Group Limit Full. (%d)\n", (INT_16) prP2pBssInfo->rStaRecOfClientList.u4NumElem); -+ -+ bssRemoveStaRecFromClientList(prAdapter, prP2pBssInfo, prStaRec); -+ -+ cnmStaRecFree(prAdapter, prStaRec, FALSE); -+ fgReplyAuth = TRUE; -+ *pu2StatusCode = STATUS_CODE_ASSOC_DENIED_AP_OVERLOAD; -+ break; -+ } -+ /* Hotspot Blacklist */ -+ if (prAuthFrame->aucSrcAddr) { -+ if (kalP2PCmpBlackList(prAdapter->prGlueInfo, prAuthFrame->aucSrcAddr)) { -+ fgReplyAuth = TRUE; -+ *pu2StatusCode = STATUS_CODE_ASSOC_DENIED_OUTSIDE_STANDARD; -+ return fgReplyAuth; -+ } -+ } -+ -+ /* prStaRec->eStaType = STA_TYPE_INFRA_CLIENT; */ -+ prStaRec->eStaType = STA_TYPE_P2P_GC; -+ -+ prStaRec->ucNetTypeIndex = NETWORK_TYPE_P2P_INDEX; -+ -+ /* Update Station Record - Status/Reason Code */ -+ prStaRec->u2StatusCode = STATUS_CODE_SUCCESSFUL; -+ -+ prStaRec->ucJoinFailureCount = 0; -+ -+ *pprStaRec = prStaRec; -+ -+ *pu2StatusCode = STATUS_CODE_SUCCESSFUL; -+ -+ } while (FALSE); -+ -+ return fgReplyAuth; -+ -+} /* p2pFuncValidateAuth */ -+ -+VOID p2pFuncResetStaRecStatus(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec) -+{ -+ do { -+ if ((prAdapter == NULL) || (prStaRec == NULL)) { -+ ASSERT(FALSE); -+ break; -+ } -+ -+ prStaRec->u2StatusCode = STATUS_CODE_SUCCESSFUL; -+ prStaRec->u2ReasonCode = REASON_CODE_RESERVED; -+ prStaRec->ucJoinFailureCount = 0; -+ prStaRec->fgTransmitKeyExist = FALSE; -+ -+ prStaRec->fgSetPwrMgtBit = FALSE; -+ -+ } while (FALSE); -+ -+} /* p2pFuncResetStaRecStatus */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief The function is used to initialize the value of the connection settings for -+* P2P network -+* -+* @param (none) -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID p2pFuncInitConnectionSettings(IN P_ADAPTER_T prAdapter, IN P_P2P_CONNECTION_SETTINGS_T prP2PConnSettings) -+{ -+ P_DEVICE_TYPE_T prDevType; -+ UINT_8 aucDefaultDevName[] = P2P_DEFAULT_DEV_NAME; -+ UINT_8 aucWfaOui[] = VENDOR_OUI_WFA; -+#if CFG_SUPPORT_CFG_FILE -+ P_WIFI_VAR_T prWifiVar = NULL; -+#endif -+ -+ ASSERT(prP2PConnSettings); -+#if CFG_SUPPORT_CFG_FILE -+ prWifiVar = &(prAdapter->rWifiVar); -+ ASSERT(prWifiVar); -+#endif -+ -+ /* Setup Default Device Name */ -+ prP2PConnSettings->ucDevNameLen = P2P_DEFAULT_DEV_NAME_LEN; -+ kalMemCopy(prP2PConnSettings->aucDevName, aucDefaultDevName, sizeof(aucDefaultDevName)); -+ -+ /* Setup Primary Device Type (Big-Endian) */ -+ prDevType = &prP2PConnSettings->rPrimaryDevTypeBE; -+ -+ prDevType->u2CategoryId = HTONS(P2P_DEFAULT_PRIMARY_CATEGORY_ID); -+ prDevType->u2SubCategoryId = HTONS(P2P_DEFAULT_PRIMARY_SUB_CATEGORY_ID); -+ -+ prDevType->aucOui[0] = aucWfaOui[0]; -+ prDevType->aucOui[1] = aucWfaOui[1]; -+ prDevType->aucOui[2] = aucWfaOui[2]; -+ prDevType->aucOui[3] = VENDOR_OUI_TYPE_WPS; -+ -+ /* Setup Secondary Device Type */ -+ prP2PConnSettings->ucSecondaryDevTypeCount = 0; -+ -+ /* Setup Default Config Method */ -+ prP2PConnSettings->eConfigMethodSelType = ENUM_CONFIG_METHOD_SEL_AUTO; -+ prP2PConnSettings->u2ConfigMethodsSupport = P2P_DEFAULT_CONFIG_METHOD; -+ prP2PConnSettings->u2TargetConfigMethod = 0; -+ prP2PConnSettings->u2LocalConfigMethod = 0; -+ prP2PConnSettings->fgIsPasswordIDRdy = FALSE; -+ -+ /* For Device Capability */ -+ prP2PConnSettings->fgSupportServiceDiscovery = FALSE; -+ prP2PConnSettings->fgSupportClientDiscoverability = TRUE; -+ prP2PConnSettings->fgSupportConcurrentOperation = TRUE; -+ prP2PConnSettings->fgSupportInfraManaged = FALSE; -+ prP2PConnSettings->fgSupportInvitationProcedure = FALSE; -+ -+ /* For Group Capability */ -+#if CFG_SUPPORT_PERSISTENT_GROUP -+ prP2PConnSettings->fgSupportPersistentP2PGroup = TRUE; -+#else -+ prP2PConnSettings->fgSupportPersistentP2PGroup = FALSE; -+#endif -+ prP2PConnSettings->fgSupportIntraBSSDistribution = TRUE; -+ prP2PConnSettings->fgSupportCrossConnection = TRUE; -+ prP2PConnSettings->fgSupportPersistentReconnect = FALSE; -+ -+ prP2PConnSettings->fgSupportOppPS = FALSE; -+ prP2PConnSettings->u2CTWindow = P2P_CTWINDOW_DEFAULT; -+ -+ /* For Connection Settings. */ -+ prP2PConnSettings->eAuthMode = AUTH_MODE_OPEN; -+ -+ prP2PConnSettings->prTargetP2pDesc = NULL; -+ prP2PConnSettings->ucSSIDLen = 0; -+ -+ /* Misc */ -+ prP2PConnSettings->fgIsScanReqIssued = FALSE; -+ prP2PConnSettings->fgIsServiceDiscoverIssued = FALSE; -+ prP2PConnSettings->fgP2pGroupLimit = FALSE; -+ prP2PConnSettings->ucOperatingChnl = 0; -+ prP2PConnSettings->ucListenChnl = 0; -+ prP2PConnSettings->ucTieBreaker = (UINT_8) (kalRandomNumber() & 0x1); -+ -+ prP2PConnSettings->eFormationPolicy = ENUM_P2P_FORMATION_POLICY_AUTO; -+#if CFG_SUPPORT_CFG_FILE -+ /* prP2PConnSettings->fgIsWPSMode = prWifiVar->ucApWpsMode; */ -+ prAdapter->rWifiVar.prP2pFsmInfo->fgIsWPSMode = prWifiVar->ucApWpsMode; -+#endif -+} /* p2pFuncInitConnectionSettings */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will validate the Rx Assoc Req Frame and then return -+* the status code to AAA to indicate if need to perform following actions -+* when the specified conditions were matched. -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* @param[in] prSwRfb Pointer to SW RFB data structure. -+* @param[out] pu2StatusCode The Status Code of Validation Result -+* -+* @retval TRUE Reply the Assoc Resp -+* @retval FALSE Don't reply the Assoc Resp -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN p2pFuncValidateAssocReq(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, OUT PUINT_16 pu2StatusCode) -+{ -+ BOOLEAN fgReplyAssocResp = TRUE; -+ P_WLAN_ASSOC_REQ_FRAME_T prAssocReqFrame = (P_WLAN_ASSOC_REQ_FRAME_T) NULL; -+ P_STA_RECORD_T prStaRec = (P_STA_RECORD_T) NULL; -+ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; -+#if CFG_SUPPORT_WFD -+ P_WFD_CFG_SETTINGS_T prWfdCfgSettings = (P_WFD_CFG_SETTINGS_T) NULL; -+ P_WFD_ATTRIBUTE_T prWfdAttribute = (P_WFD_ATTRIBUTE_T) NULL; -+ BOOLEAN fgNeedFree = FALSE; -+#endif -+ /* UINT_16 u2AttriListLen = 0; */ -+ UINT_16 u2WfdDevInfo = 0; -+ P_WFD_DEVICE_INFORMATION_IE_T prAttriWfdDevInfo; -+ -+ /* TODO(Kevin): Call P2P functions to check .. -+ 2. Check we can accept connection from thsi peer -+ a. If we are in PROVISION state, only accept the peer we do the GO formation previously. -+ b. If we are in OPERATION state, only accept the other peer when P2P_GROUP_LIMIT is 0. -+ 3. Check Black List here. -+ */ -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prSwRfb != NULL) && (pu2StatusCode != NULL)); -+ -+ *pu2StatusCode = STATUS_CODE_REQ_DECLINED; -+ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); -+ prAssocReqFrame = (P_WLAN_ASSOC_REQ_FRAME_T) prSwRfb->pvHeader; -+ -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); -+ -+ if (prStaRec == NULL) { -+ /* Station record should be ready while RX AUTH frame. */ -+ fgReplyAssocResp = FALSE; -+ ASSERT(FALSE); -+ break; -+ } -+ prStaRec->ucRCPI = prSwRfb->prHifRxHdr->ucRcpi; -+ -+ prStaRec->u2DesiredNonHTRateSet &= prP2pBssInfo->u2OperationalRateSet; -+ prStaRec->ucDesiredPhyTypeSet = prStaRec->ucPhyTypeSet & prP2pBssInfo->ucPhyTypeSet; -+ -+ if (prStaRec->ucDesiredPhyTypeSet == 0) { -+ /* The station only support 11B rate. */ -+ *pu2StatusCode = STATUS_CODE_ASSOC_DENIED_RATE_NOT_SUPPORTED; -+ break; -+ } -+#if CFG_SUPPORT_WFD && 1 -+ /* LOG_FUNC("Skip check WFD IE because some API is not ready\n"); */ -+ if (!prAdapter->rWifiVar.prP2pFsmInfo) { -+ fgReplyAssocResp = FALSE; -+ ASSERT(FALSE); -+ break; -+ } -+ -+ prWfdCfgSettings = &prAdapter->rWifiVar.prP2pFsmInfo->rWfdConfigureSettings; -+ DBGLOG(P2P, INFO, "AssocReq, wfd_en %u wfd_info 0x%x wfd_policy 0x%x wfd_flag 0x%x\n", -+ prWfdCfgSettings->ucWfdEnable, prWfdCfgSettings->u2WfdDevInfo, -+ prWfdCfgSettings->u4WfdPolicy, prWfdCfgSettings->u4WfdFlag); /* Eddie */ -+ if (prWfdCfgSettings->ucWfdEnable) { -+ if (prWfdCfgSettings->u4WfdPolicy & BIT(6)) { -+ /* Rejected all. */ -+ break; -+ } -+ -+ /* fgNeedFree = p2pFuncGetAttriList(prAdapter, */ -+ /* VENDOR_OUI_TYPE_WFD, */ -+ /* (PUINT_8)prAssocReqFrame->aucInfoElem, */ -+ /* (prSwRfb->u2PacketLen - OFFSET_OF(WLAN_ASSOC_REQ_FRAME_T, aucInfoElem)), */ -+ /* (PPUINT_8)&prWfdAttribute, */ -+ /* &u2AttriListLen); */ -+ -+ prAttriWfdDevInfo = (P_WFD_DEVICE_INFORMATION_IE_T) -+ p2pFuncGetSpecAttri(prAdapter, -+ VENDOR_OUI_TYPE_WFD, -+ (PUINT_8) prAssocReqFrame->aucInfoElem, -+ (prSwRfb->u2PacketLen - -+ OFFSET_OF(WLAN_ASSOC_REQ_FRAME_T, aucInfoElem)), -+ WFD_ATTRI_ID_DEV_INFO); -+ -+ if ((prWfdCfgSettings->u4WfdPolicy & BIT(5)) && (prAttriWfdDevInfo != NULL)) { -+ /* Rejected with WFD IE. */ -+ break; -+ } -+ -+ if ((prWfdCfgSettings->u4WfdPolicy & BIT(0)) && (prAttriWfdDevInfo == NULL)) { -+ /* Rejected without WFD IE. */ -+ break; -+ } -+ -+ if (prAttriWfdDevInfo == NULL) { -+ /* -+ * Without WFD IE. -+ * Do nothing. Accept the connection request. -+ */ -+ *pu2StatusCode = STATUS_CODE_SUCCESSFUL; -+ break; -+ } -+ -+ /* prAttriWfdDevInfo = */ -+ /* (P_WFD_DEVICE_INFORMATION_IE_T)p2pFuncGetSpecAttri(prAdapter, */ -+ /* VENDOR_OUI_TYPE_WFD, */ -+ /* (PUINT_8)prWfdAttribute, */ -+ /* u2AttriListLen, */ -+ /* WFD_ATTRI_ID_DEV_INFO); */ -+ /* if (prAttriWfdDevInfo == NULL) { */ -+ /* No such attribute. */ -+ /* break; */ -+ /* } */ -+ -+ WLAN_GET_FIELD_BE16(&prAttriWfdDevInfo->u2WfdDevInfo, &u2WfdDevInfo); -+ DBGLOG(P2P, INFO, "RX Assoc Req WFD Info:0x%x.\n", u2WfdDevInfo); -+ -+ if ((prWfdCfgSettings->u4WfdPolicy & BIT(1)) && ((u2WfdDevInfo & 0x3) == 0x0)) { -+ /* Rejected because of SOURCE. */ -+ break; -+ } -+ -+ if ((prWfdCfgSettings->u4WfdPolicy & BIT(2)) && ((u2WfdDevInfo & 0x3) == 0x1)) { -+ /* Rejected because of Primary Sink. */ -+ break; -+ } -+ -+ if ((prWfdCfgSettings->u4WfdPolicy & BIT(3)) && ((u2WfdDevInfo & 0x3) == 0x2)) { -+ /* Rejected because of Secondary Sink. */ -+ break; -+ } -+ -+ if ((prWfdCfgSettings->u4WfdPolicy & BIT(4)) && ((u2WfdDevInfo & 0x3) == 0x3)) { -+ /* Rejected because of Source & Primary Sink. */ -+ break; -+ } -+ -+ /* Check role */ -+ -+ if ((prWfdCfgSettings->u4WfdFlag & WFD_FLAGS_DEV_INFO_VALID) && -+ ((prWfdCfgSettings->u2WfdDevInfo & BITS(0, 1)) == 0x3)) { -+ /* P_MSG_WFD_CONFIG_SETTINGS_CHANGED_T prMsgWfdCfgUpdate = -+ * (P_MSG_WFD_CONFIG_SETTINGS_CHANGED_T)NULL; */ -+ UINT_16 u2DevInfo = prWfdCfgSettings->u2WfdDevInfo; -+ -+ /* We may change role here if we are dual role */ -+ -+ if ((u2WfdDevInfo & BITS(0, 1)) == 0x00 /* Peer is Source */) { -+ DBGLOG(P2P, INFO, "WFD: Switch role to primary sink\n"); -+ -+ prWfdCfgSettings->u2WfdDevInfo &= ~BITS(0, 1); -+ prWfdCfgSettings->u2WfdDevInfo |= 0x1; -+ -+ /* event to annonce the role is chanaged to P-Sink */ -+ -+ } else if ((u2WfdDevInfo & BITS(0, 1)) == 0x01 /* Peer is P-Sink */) { -+ DBGLOG(P2P, INFO, "WFD: Switch role to source\n"); -+ -+ prWfdCfgSettings->u2WfdDevInfo &= ~BITS(0, 1); -+ /* event to annonce the role is chanaged to Source */ -+ } else { -+ DBGLOG(P2P, INFO, "WFD: Peer role is wrong type(dev 0x%x)\n", -+ (u2DevInfo)); -+ DBGLOG(P2P, INFO, "WFD: Switch role to source\n"); -+ -+ prWfdCfgSettings->u2WfdDevInfo &= ~BITS(0, 1); -+ /* event to annonce the role is chanaged to Source */ -+ } -+ -+ p2pFsmRunEventWfdSettingUpdate(prAdapter, NULL); -+ -+ } /* Dual role p2p->wfd_params->WfdDevInfo */ -+ -+ /* WFD_FLAG_DEV_INFO_VALID */ -+ } -+ /* ucWfdEnable */ -+#endif -+ *pu2StatusCode = STATUS_CODE_SUCCESSFUL; -+ } while (FALSE); -+ -+#if CFG_SUPPORT_WFD -+ if ((prWfdAttribute) && (fgNeedFree)) -+ kalMemFree(prWfdAttribute, VIR_MEM_TYPE, WPS_MAXIMUM_ATTRIBUTES_CACHE_SIZE); -+#endif -+ -+ return fgReplyAssocResp; -+ -+} /* p2pFuncValidateAssocReq */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is used to check the P2P IE -+* -+* -+* @return none -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN p2pFuncParseCheckForP2PInfoElem(IN P_ADAPTER_T prAdapter, IN PUINT_8 pucBuf, OUT PUINT_8 pucOuiType) -+{ -+ UINT_8 aucWfaOui[] = VENDOR_OUI_WFA_SPECIFIC; -+ P_IE_WFA_T prWfaIE = (P_IE_WFA_T) NULL; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (pucBuf != NULL) && (pucOuiType != NULL)); -+ -+ prWfaIE = (P_IE_WFA_T) pucBuf; -+ -+ if (IE_LEN(pucBuf) <= ELEM_MIN_LEN_WFA_OUI_TYPE_SUBTYPE) { -+ break; -+ } else if (prWfaIE->aucOui[0] != aucWfaOui[0] || -+ prWfaIE->aucOui[1] != aucWfaOui[1] || prWfaIE->aucOui[2] != aucWfaOui[2]) { -+ break; -+ } -+ -+ *pucOuiType = prWfaIE->ucOuiType; -+ -+ return TRUE; -+ } while (FALSE); -+ -+ return FALSE; -+} /* p2pFuncParseCheckForP2PInfoElem */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will validate the Rx Probe Request Frame and then return -+* result to BSS to indicate if need to send the corresponding Probe Response -+* Frame if the specified conditions were matched. -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* @param[in] prSwRfb Pointer to SW RFB data structure. -+* @param[out] pu4ControlFlags Control flags for replying the Probe Response -+* -+* @retval TRUE Reply the Probe Response -+* @retval FALSE Don't reply the Probe Response -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN p2pFuncValidateProbeReq(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, OUT PUINT_32 pu4ControlFlags) -+{ -+ BOOLEAN fgIsReplyProbeRsp = FALSE; -+ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; -+ -+ DEBUGFUNC("p2pFuncValidateProbeReq"); -+ DBGLOG(P2P, TRACE, "p2pFuncValidateProbeReq\n"); -+ -+ do { -+ -+ ASSERT_BREAK((prAdapter != NULL) && (prSwRfb != NULL)); -+ -+ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; -+ -+ if (prP2pFsmInfo->u4P2pPacketFilter & PARAM_PACKET_FILTER_PROBE_REQ) { -+ -+ DBGLOG(P2P, TRACE, "report probe req to OS\n"); -+ /* Leave the probe response to p2p_supplicant. */ -+ kalP2PIndicateRxMgmtFrame(prAdapter->prGlueInfo, prSwRfb); -+ } -+ -+ } while (FALSE); -+ -+ return fgIsReplyProbeRsp; -+ -+} /* end of p2pFuncValidateProbeReq() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will validate the Rx Probe Request Frame and then return -+* result to BSS to indicate if need to send the corresponding Probe Response -+* Frame if the specified conditions were matched. -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* @param[in] prSwRfb Pointer to SW RFB data structure. -+* @param[out] pu4ControlFlags Control flags for replying the Probe Response -+* -+* @retval TRUE Reply the Probe Response -+* @retval FALSE Don't reply the Probe Response -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID p2pFuncValidateRxActionFrame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb) -+{ -+ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; -+ -+ DEBUGFUNC("p2pFuncValidateProbeReq"); -+ -+ do { -+ -+ ASSERT_BREAK((prAdapter != NULL) && (prSwRfb != NULL)); -+ -+ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; -+ -+ if (prP2pFsmInfo->u4P2pPacketFilter & PARAM_PACKET_FILTER_ACTION_FRAME) { -+ /* Leave the probe response to p2p_supplicant. */ -+ kalP2PIndicateRxMgmtFrame(prAdapter->prGlueInfo, prSwRfb); -+ } -+ -+ } while (FALSE); -+ -+ return; -+ -+} /* p2pFuncValidateRxMgmtFrame */ -+ -+BOOLEAN p2pFuncIsAPMode(IN P_P2P_FSM_INFO_T prP2pFsmInfo) -+{ -+ if (prP2pFsmInfo) { -+ if (prP2pFsmInfo->fgIsWPSMode == 1) -+ return FALSE; -+ return prP2pFsmInfo->fgIsApMode; -+ } else { -+ return FALSE; -+ } -+} -+ -+/* p2pFuncIsAPMode */ -+ -+VOID -+p2pFuncParseBeaconContent(IN P_ADAPTER_T prAdapter, -+ IN P_BSS_INFO_T prP2pBssInfo, IN PUINT_8 pucIEInfo, IN UINT_32 u4IELen) -+{ -+ PUINT_8 pucIE = (PUINT_8) NULL; -+ UINT_16 u2Offset = 0; -+ P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo = (P_P2P_SPECIFIC_BSS_INFO_T) NULL; -+ BOOLEAN ucNewSecMode = FALSE; -+ BOOLEAN ucOldSecMode = FALSE; -+ UINT_8 ucOuiType; -+ UINT_16 u2SubTypeVersion; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prP2pBssInfo != NULL)); -+ -+ if (u4IELen == 0) -+ break; -+ -+ prP2pSpecificBssInfo = prAdapter->rWifiVar.prP2pSpecificBssInfo; -+ prP2pSpecificBssInfo->u2AttributeLen = 0; -+ -+ ASSERT_BREAK(pucIEInfo != NULL); -+ -+ pucIE = pucIEInfo; -+ -+ ucOldSecMode = kalP2PGetCipher(prAdapter->prGlueInfo); -+ -+ IE_FOR_EACH(pucIE, u4IELen, u2Offset) { -+ switch (IE_ID(pucIE)) { -+ case ELEM_ID_SSID: -+ { -+ /* 0 */ /* V */ /* Done */ -+ /* DBGLOG(P2P, TRACE, ("SSID update\n")); */ -+ /* SSID is saved when start AP/GO */ -+ /* SSID IE set in beacon from supplicant will not always be */ -+ /* the true since hidden SSID case */ -+ /* -+ COPY_SSID(prP2pBssInfo->aucSSID, -+ prP2pBssInfo->ucSSIDLen, -+ SSID_IE(pucIE)->aucSSID, -+ SSID_IE(pucIE)->ucLength); -+ -+ COPY_SSID(prP2pSpecificBssInfo->aucGroupSsid, -+ prP2pSpecificBssInfo->u2GroupSsidLen, -+ SSID_IE(pucIE)->aucSSID, -+ SSID_IE(pucIE)->ucLength); -+ */ -+ } -+ break; -+ case ELEM_ID_SUP_RATES: -+ { -+ /* 1 */ /* V */ /* Done */ -+ DBGLOG(P2P, TRACE, "Support Rate IE\n"); -+ kalMemCopy(prP2pBssInfo->aucAllSupportedRates, -+ SUP_RATES_IE(pucIE)->aucSupportedRates, -+ SUP_RATES_IE(pucIE)->ucLength); -+ -+ prP2pBssInfo->ucAllSupportedRatesLen = SUP_RATES_IE(pucIE)->ucLength; -+ -+ DBGLOG_MEM8(P2P, TRACE, SUP_RATES_IE(pucIE)->aucSupportedRates, -+ SUP_RATES_IE(pucIE)->ucLength); -+ } -+ break; -+ case ELEM_ID_DS_PARAM_SET: -+ { -+ /* 3 */ /* V */ /* Done */ -+ P_P2P_CONNECTION_SETTINGS_T prP2pConnSettings = -+ prAdapter->rWifiVar.prP2PConnSettings; -+ -+ DBGLOG(P2P, TRACE, "DS PARAM IE\n"); -+ -+ ASSERT(prP2pConnSettings->ucOperatingChnl == DS_PARAM_IE(pucIE)->ucCurrChnl); -+ -+ if (prP2pConnSettings->eBand != BAND_2G4) { -+ ASSERT(FALSE); -+ break; -+ } -+ /* prP2pBssInfo->ucPrimaryChannel = DS_PARAM_IE(pucIE)->ucCurrChnl; */ -+ -+ /* prP2pBssInfo->eBand = BAND_2G4; */ -+ } -+ break; -+ case ELEM_ID_TIM: /* 5 */ /* V */ -+ DBGLOG(P2P, TRACE, "TIM IE\n"); -+ TIM_IE(pucIE)->ucDTIMPeriod = prP2pBssInfo->ucDTIMPeriod; -+ break; -+ case ELEM_ID_ERP_INFO: /* 42 */ /* V */ -+ { -+#if 1 -+ /* This IE would dynamic change due to FW detection change is required. */ -+ DBGLOG(P2P, TRACE, "ERP IE will be over write by driver\n"); -+ DBGLOG(P2P, TRACE, " ucERP: %x.\n", ERP_INFO_IE(pucIE)->ucERP); -+ -+#else -+ /* This IE would dynamic change due to FW detection change is required. */ -+ DBGLOG(P2P, TRACE, "ERP IE.\n"); -+ -+ prP2pBssInfo->ucPhyTypeSet |= PHY_TYPE_SET_802_11GN; -+ -+ ASSERT(prP2pBssInfo->eBand == BAND_2G4); -+ -+ prP2pBssInfo->fgObssErpProtectMode = -+ ((ERP_INFO_IE(pucIE)->ucERP & ERP_INFO_USE_PROTECTION) ? TRUE : FALSE); -+ -+ prP2pBssInfo->fgErpProtectMode = -+ ((ERP_INFO_IE(pucIE)->ucERP & -+ (ERP_INFO_USE_PROTECTION | ERP_INFO_NON_ERP_PRESENT)) ? TRUE : FALSE); -+#endif -+ -+ } -+ break; -+ case ELEM_ID_HT_CAP: /* 45 */ /* V */ -+ { -+#if 1 -+ DBGLOG(P2P, TRACE, "HT CAP IE would be overwritten by driver\n"); -+ -+ DBGLOG(P2P, TRACE, -+ "HT Cap Info:%x, AMPDU Param:%x\n", HT_CAP_IE(pucIE)->u2HtCapInfo, -+ HT_CAP_IE(pucIE)->ucAmpduParam); -+ -+ DBGLOG(P2P, TRACE, -+ "HT Extended Cap Info%x,TX Beamforming Cap Info%x,Ant Selection Cap Info%x\n", -+ HT_CAP_IE(pucIE)->u2HtExtendedCap, HT_CAP_IE(pucIE)->u4TxBeamformingCap, -+ HT_CAP_IE(pucIE)->ucAselCap); -+#else -+ prP2pBssInfo->ucPhyTypeSet |= PHY_TYPE_SET_802_11N; -+ -+ /* u2HtCapInfo */ -+ if ((HT_CAP_IE(pucIE)->u2HtCapInfo & -+ (HT_CAP_INFO_SUP_CHNL_WIDTH | HT_CAP_INFO_SHORT_GI_40M | -+ HT_CAP_INFO_DSSS_CCK_IN_40M)) == 0) { -+ prP2pBssInfo->fgAssoc40mBwAllowed = FALSE; -+ } else { -+ prP2pBssInfo->fgAssoc40mBwAllowed = TRUE; -+ } -+ -+ if ((HT_CAP_IE(pucIE)->u2HtCapInfo & -+ (HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M)) == 0) { -+ prAdapter->rWifiVar.rConnSettings.fgRxShortGIDisabled = TRUE; -+ } else { -+ prAdapter->rWifiVar.rConnSettings.fgRxShortGIDisabled = FALSE; -+ } -+ -+ /* ucAmpduParam */ -+ DBGLOG(P2P, TRACE, -+ "AMPDU setting from supplicant:0x%x, & default value:0x%x\n", -+ (UINT_8) HT_CAP_IE(pucIE)->ucAmpduParam, -+ (UINT_8) AMPDU_PARAM_DEFAULT_VAL); -+ -+ /* rSupMcsSet */ -+ /* Can do nothing. the field is default value from other configuration. */ -+ /* HT_CAP_IE(pucIE)->rSupMcsSet; */ -+ -+ /* u2HtExtendedCap */ -+ ASSERT(HT_CAP_IE(pucIE)->u2HtExtendedCap == -+ (HT_EXT_CAP_DEFAULT_VAL & -+ ~(HT_EXT_CAP_PCO | HT_EXT_CAP_PCO_TRANS_TIME_NONE))); -+ -+ /* u4TxBeamformingCap */ -+ ASSERT(HT_CAP_IE(pucIE)->u4TxBeamformingCap == TX_BEAMFORMING_CAP_DEFAULT_VAL); -+ -+ /* ucAselCap */ -+ ASSERT(HT_CAP_IE(pucIE)->ucAselCap == ASEL_CAP_DEFAULT_VAL); -+#endif -+ } -+ break; -+ case ELEM_ID_RSN: /* 48 */ /* V */ -+ { -+ RSN_INFO_T rRsnIe; -+ -+ DBGLOG(P2P, TRACE, "RSN IE\n"); -+ kalP2PSetCipher(prAdapter->prGlueInfo, IW_AUTH_CIPHER_CCMP); -+ ucNewSecMode = TRUE; -+ -+ if (rsnParseRsnIE(prAdapter, RSN_IE(pucIE), &rRsnIe)) { -+ prP2pBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]; -+ prP2pBssInfo->u4RsnSelectedGroupCipher = RSN_CIPHER_SUITE_CCMP; -+ prP2pBssInfo->u4RsnSelectedPairwiseCipher = RSN_CIPHER_SUITE_CCMP; -+ prP2pBssInfo->u4RsnSelectedAKMSuite = RSN_AKM_SUITE_PSK; -+ prP2pBssInfo->u2RsnSelectedCapInfo = rRsnIe.u2RsnCap; -+ } -+ } -+ break; -+ case ELEM_ID_EXTENDED_SUP_RATES: /* 50 */ /* V */ -+ /* Be attention, -+ * ELEM_ID_SUP_RATES should be placed before ELEM_ID_EXTENDED_SUP_RATES. */ -+ DBGLOG(P2P, TRACE, "Ex Support Rate IE\n"); -+ kalMemCopy(&(prP2pBssInfo->aucAllSupportedRates[prP2pBssInfo->ucAllSupportedRatesLen]), -+ EXT_SUP_RATES_IE(pucIE)->aucExtSupportedRates, -+ EXT_SUP_RATES_IE(pucIE)->ucLength); -+ -+ DBGLOG_MEM8(P2P, TRACE, EXT_SUP_RATES_IE(pucIE)->aucExtSupportedRates, -+ EXT_SUP_RATES_IE(pucIE)->ucLength); -+ -+ prP2pBssInfo->ucAllSupportedRatesLen += EXT_SUP_RATES_IE(pucIE)->ucLength; -+ break; -+ case ELEM_ID_HT_OP: -+ { -+ /* 61 */ /* V */ /* TODO: */ -+#if 1 -+ DBGLOG(P2P, TRACE, "HT OP IE would be overwritten by driver\n"); -+ -+ DBGLOG(P2P, TRACE, -+ " Primary Channel: %x, Info1: %x, Info2: %x, Info3: %x\n", -+ HT_OP_IE(pucIE)->ucPrimaryChannel, HT_OP_IE(pucIE)->ucInfo1, -+ HT_OP_IE(pucIE)->u2Info2, HT_OP_IE(pucIE)->u2Info3); -+#else -+ UINT_16 u2Info2 = 0; -+ -+ prP2pBssInfo->ucPhyTypeSet |= PHY_TYPE_SET_802_11N; -+ -+ DBGLOG(P2P, TRACE, "HT OP IE\n"); -+ -+ /* ucPrimaryChannel. */ -+ ASSERT(HT_OP_IE(pucIE)->ucPrimaryChannel == prP2pBssInfo->ucPrimaryChannel); -+ -+ /* ucInfo1 */ -+ prP2pBssInfo->ucHtOpInfo1 = HT_OP_IE(pucIE)->ucInfo1; -+ -+ /* u2Info2 */ -+ u2Info2 = HT_OP_IE(pucIE)->u2Info2; -+ -+ if (u2Info2 & HT_OP_INFO2_NON_GF_HT_STA_PRESENT) { -+ ASSERT(prP2pBssInfo->eGfOperationMode != GF_MODE_NORMAL); -+ u2Info2 &= ~HT_OP_INFO2_NON_GF_HT_STA_PRESENT; -+ } -+ -+ if (u2Info2 & HT_OP_INFO2_OBSS_NON_HT_STA_PRESENT) { -+ prP2pBssInfo->eObssHtProtectMode = HT_PROTECT_MODE_NON_MEMBER; -+ u2Info2 &= ~HT_OP_INFO2_OBSS_NON_HT_STA_PRESENT; -+ } -+ -+ switch (u2Info2 & HT_OP_INFO2_HT_PROTECTION) { -+ case HT_PROTECT_MODE_NON_HT: -+ prP2pBssInfo->eHtProtectMode = HT_PROTECT_MODE_NON_HT; -+ break; -+ case HT_PROTECT_MODE_NON_MEMBER: -+ prP2pBssInfo->eHtProtectMode = HT_PROTECT_MODE_NONE; -+ prP2pBssInfo->eObssHtProtectMode = HT_PROTECT_MODE_NON_MEMBER; -+ break; -+ default: -+ prP2pBssInfo->eHtProtectMode = HT_OP_IE(pucIE)->u2Info2; -+ break; -+ } -+ -+ /* u2Info3 */ -+ prP2pBssInfo->u2HtOpInfo3 = HT_OP_IE(pucIE)->u2Info3; -+ -+ /* aucBasicMcsSet */ -+ DBGLOG_MEM8(P2P, TRACE, HT_OP_IE(pucIE)->aucBasicMcsSet, 16); -+#endif -+ } -+ break; -+ case ELEM_ID_OBSS_SCAN_PARAMS: /* 74 */ /* V */ -+ { -+ DBGLOG(P2P, TRACE, -+ "ELEM_ID_OBSS_SCAN_PARAMS IE would be replaced by driver\n"); -+ } -+ break; -+ case ELEM_ID_EXTENDED_CAP: /* 127 */ /* V */ -+ { -+ DBGLOG(P2P, TRACE, "ELEM_ID_EXTENDED_CAP IE would be replaced by driver\n"); -+ } -+ break; -+ case ELEM_ID_VENDOR: /* 221 */ /* V */ -+ DBGLOG(P2P, TRACE, "Vender Specific IE\n"); -+ if (rsnParseCheckForWFAInfoElem -+ (prAdapter, pucIE, &ucOuiType, &u2SubTypeVersion)) { -+ if ((ucOuiType == VENDOR_OUI_TYPE_WPA) -+ && (u2SubTypeVersion == VERSION_WPA)) { -+ kalP2PSetCipher(prAdapter->prGlueInfo, IW_AUTH_CIPHER_TKIP); -+ ucNewSecMode = TRUE; -+ kalMemCopy(prP2pSpecificBssInfo->aucWpaIeBuffer, pucIE, -+ IE_SIZE(pucIE)); -+ prP2pSpecificBssInfo->u2WpaIeLen = IE_SIZE(pucIE); -+ } else if (ucOuiType == VENDOR_OUI_TYPE_WPS) { -+ kalP2PUpdateWSC_IE(prAdapter->prGlueInfo, 0, pucIE, -+ IE_SIZE(pucIE)); -+ } -+ /* WMM here. */ -+ } else if (p2pFuncParseCheckForP2PInfoElem(prAdapter, pucIE, &ucOuiType)) { -+ /* TODO Store the whole P2P IE & generate later. */ -+ /* Be aware that there may be one or more P2P IE. */ -+ if (ucOuiType == VENDOR_OUI_TYPE_P2P) { -+ kalMemCopy(&prP2pSpecificBssInfo->aucAttributesCache -+ [prP2pSpecificBssInfo->u2AttributeLen], pucIE, -+ IE_SIZE(pucIE)); -+ -+ prP2pSpecificBssInfo->u2AttributeLen += IE_SIZE(pucIE); -+ } else if (ucOuiType == VENDOR_OUI_TYPE_WFD) { -+ -+ kalMemCopy(&prP2pSpecificBssInfo->aucAttributesCache -+ [prP2pSpecificBssInfo->u2AttributeLen], pucIE, -+ IE_SIZE(pucIE)); -+ -+ prP2pSpecificBssInfo->u2AttributeLen += IE_SIZE(pucIE); -+ } -+ } else { -+ -+ kalMemCopy(&prP2pSpecificBssInfo->aucAttributesCache -+ [prP2pSpecificBssInfo->u2AttributeLen], pucIE, -+ IE_SIZE(pucIE)); -+ -+ prP2pSpecificBssInfo->u2AttributeLen += IE_SIZE(pucIE); -+ DBGLOG(P2P, TRACE, "Driver unprocessed Vender Specific IE\n"); -+ ASSERT(FALSE); -+ } -+ -+ /* TODO: Store other Vender IE except for WMM Param. */ -+ break; -+ default: -+ DBGLOG(P2P, TRACE, "Unprocessed element ID:%d\n", IE_ID(pucIE)); -+ break; -+ } -+ } -+ -+ if (!ucNewSecMode && ucOldSecMode) -+ kalP2PSetCipher(prAdapter->prGlueInfo, IW_AUTH_CIPHER_NONE); -+ -+ } while (FALSE); -+ -+} /* p2pFuncParseBeaconContent */ -+ -+P_BSS_DESC_T -+p2pFuncKeepOnConnection(IN P_ADAPTER_T prAdapter, -+ IN P_P2P_CONNECTION_REQ_INFO_T prConnReqInfo, -+ IN P_P2P_CHNL_REQ_INFO_T prChnlReqInfo, IN P_P2P_SCAN_REQ_INFO_T prScanReqInfo) -+{ -+ P_BSS_DESC_T prTargetBss = (P_BSS_DESC_T) NULL; -+ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && -+ (prConnReqInfo != NULL) && (prChnlReqInfo != NULL) && (prScanReqInfo != NULL)); -+ -+ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); -+ -+ if (prP2pBssInfo->eCurrentOPMode != OP_MODE_INFRASTRUCTURE) -+ break; -+ /* Update connection request information. */ -+ ASSERT(prConnReqInfo->fgIsConnRequest == TRUE); -+ -+ /* Find BSS Descriptor first. */ -+ prTargetBss = scanP2pSearchDesc(prAdapter, prP2pBssInfo, prConnReqInfo); -+ -+ if (prTargetBss == NULL) { -+ /* Update scan parameter... to scan target device. */ -+ prScanReqInfo->ucNumChannelList = 1; -+ prScanReqInfo->eScanType = SCAN_TYPE_ACTIVE_SCAN; -+ prScanReqInfo->eChannelSet = SCAN_CHANNEL_FULL; -+ prScanReqInfo->u4BufLength = 0; /* Prevent other P2P ID in IE. */ -+ prScanReqInfo->fgIsAbort = TRUE; -+ } else { -+ prChnlReqInfo->u8Cookie = 0; -+ prChnlReqInfo->ucReqChnlNum = prTargetBss->ucChannelNum; -+ prChnlReqInfo->eBand = prTargetBss->eBand; -+ prChnlReqInfo->eChnlSco = prTargetBss->eSco; -+ prChnlReqInfo->u4MaxInterval = AIS_JOIN_CH_REQUEST_INTERVAL; -+ prChnlReqInfo->eChannelReqType = CHANNEL_REQ_TYPE_GC_JOIN_REQ; -+ } -+ -+ } while (FALSE); -+ -+ return prTargetBss; -+} /* p2pFuncKeepOnConnection */ -+ -+/* Currently Only for ASSOC Response Frame. */ -+VOID p2pFuncStoreAssocRspIEBuffer(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb) -+{ -+ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; -+ P_P2P_JOIN_INFO_T prJoinInfo = (P_P2P_JOIN_INFO_T) NULL; -+ P_WLAN_ASSOC_RSP_FRAME_T prAssocRspFrame = (P_WLAN_ASSOC_RSP_FRAME_T) NULL; -+ INT_16 i2IELen = 0; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prSwRfb != NULL)); -+ -+ prAssocRspFrame = (P_WLAN_ASSOC_RSP_FRAME_T) prSwRfb->pvHeader; -+ -+ if (prAssocRspFrame->u2FrameCtrl != MAC_FRAME_ASSOC_RSP) -+ break; -+ -+ i2IELen = prSwRfb->u2PacketLen - (WLAN_MAC_HEADER_LEN + -+ CAP_INFO_FIELD_LEN + STATUS_CODE_FIELD_LEN + AID_FIELD_LEN); -+ -+ if (i2IELen <= 0) -+ break; -+ -+ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; -+ prJoinInfo = &(prP2pFsmInfo->rJoinInfo); -+ prJoinInfo->u4BufLength = (UINT_32) i2IELen; -+ -+ kalMemCopy(prJoinInfo->aucIEBuf, prAssocRspFrame->aucInfoElem, prJoinInfo->u4BufLength); -+ -+ } while (FALSE); -+ -+} /* p2pFuncStoreAssocRspIEBuffer */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to set Packet Filter. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer Pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+* \retval WLAN_STATUS_NOT_SUPPORTED -+* \retval WLAN_STATUS_ADAPTER_NOT_READY -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+p2pFuncMgmtFrameRegister(IN P_ADAPTER_T prAdapter, -+ IN UINT_16 u2FrameType, IN BOOLEAN fgIsRegistered, OUT PUINT_32 pu4P2pPacketFilter) -+{ -+ UINT_32 u4NewPacketFilter = 0; -+ -+ DEBUGFUNC("p2pFuncMgmtFrameRegister"); -+ -+ do { -+ ASSERT_BREAK(prAdapter != NULL); -+ -+ if (pu4P2pPacketFilter) -+ u4NewPacketFilter = *pu4P2pPacketFilter; -+ -+ switch (u2FrameType) { -+ case MAC_FRAME_PROBE_REQ: -+ if (fgIsRegistered) { -+ u4NewPacketFilter |= PARAM_PACKET_FILTER_PROBE_REQ; -+ DBGLOG(P2P, TRACE, "Open packet filer probe request\n"); -+ } else { -+ u4NewPacketFilter &= ~PARAM_PACKET_FILTER_PROBE_REQ; -+ DBGLOG(P2P, TRACE, "Close packet filer probe request\n"); -+ } -+ break; -+ case MAC_FRAME_ACTION: -+ if (fgIsRegistered) { -+ u4NewPacketFilter |= PARAM_PACKET_FILTER_ACTION_FRAME; -+ DBGLOG(P2P, TRACE, "Open packet filer action frame.\n"); -+ } else { -+ u4NewPacketFilter &= ~PARAM_PACKET_FILTER_ACTION_FRAME; -+ DBGLOG(P2P, TRACE, "Close packet filer action frame.\n"); -+ } -+ break; -+ default: -+ DBGLOG(P2P, TRACE, "Ask frog to add code for mgmt:%x\n", u2FrameType); -+ break; -+ } -+ -+ if (pu4P2pPacketFilter) -+ *pu4P2pPacketFilter = u4NewPacketFilter; -+ -+ /* u4NewPacketFilter |= prAdapter->u4OsPacketFilter; */ -+ -+ prAdapter->u4OsPacketFilter &= ~PARAM_PACKET_FILTER_P2P_MASK; -+ prAdapter->u4OsPacketFilter |= u4NewPacketFilter; -+ -+ DBGLOG(P2P, TRACE, "P2P Set PACKET filter:0x%x\n", prAdapter->u4OsPacketFilter); -+ -+ wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SET_RX_FILTER, -+ TRUE, -+ FALSE, -+ FALSE, -+ nicCmdEventSetCommon, -+ nicOidCmdTimeoutCommon, -+ sizeof(UINT_32), -+ (PUINT_8) &prAdapter->u4OsPacketFilter, -+ &u4NewPacketFilter, sizeof(u4NewPacketFilter) -+ ); -+ -+ } while (FALSE); -+ -+} /* p2pFuncMgmtFrameRegister */ -+ -+VOID p2pFuncUpdateMgmtFrameRegister(IN P_ADAPTER_T prAdapter, IN UINT_32 u4OsFilter) -+{ -+ -+ do { -+ -+ prAdapter->rWifiVar.prP2pFsmInfo->u4P2pPacketFilter = u4OsFilter; -+ -+ if ((prAdapter->u4OsPacketFilter & PARAM_PACKET_FILTER_P2P_MASK) ^ u4OsFilter) { -+ -+ prAdapter->u4OsPacketFilter &= ~PARAM_PACKET_FILTER_P2P_MASK; -+ -+ prAdapter->u4OsPacketFilter |= (u4OsFilter & PARAM_PACKET_FILTER_P2P_MASK); -+ -+ wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SET_RX_FILTER, -+ TRUE, -+ FALSE, -+ FALSE, -+ nicCmdEventSetCommon, -+ nicOidCmdTimeoutCommon, -+ sizeof(UINT_32), -+ (PUINT_8) &prAdapter->u4OsPacketFilter, &u4OsFilter, sizeof(u4OsFilter) -+ ); -+ DBGLOG(P2P, TRACE, "P2P Set PACKET filter:0x%x\n", prAdapter->u4OsPacketFilter); -+ } -+ -+ } while (FALSE); -+ -+} /* p2pFuncUpdateMgmtFrameRegister */ -+ -+VOID p2pFuncGetStationInfo(IN P_ADAPTER_T prAdapter, IN PUINT_8 pucMacAddr, OUT P_P2P_STATION_INFO_T prStaInfo) -+{ -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (pucMacAddr != NULL) && (prStaInfo != NULL)); -+ -+ prStaInfo->u4InactiveTime = 0; -+ prStaInfo->u4RxBytes = 0; -+ prStaInfo->u4TxBytes = 0; -+ prStaInfo->u4RxPackets = 0; -+ prStaInfo->u4TxPackets = 0; -+ /* TODO: */ -+ -+ } while (FALSE); -+ -+} /* p2pFuncGetStationInfo */ -+ -+BOOLEAN -+p2pFuncGetAttriList(IN P_ADAPTER_T prAdapter, -+ IN UINT_8 ucOuiType, -+ IN PUINT_8 pucIE, IN UINT_16 u2IELength, OUT PPUINT_8 ppucAttriList, OUT PUINT_16 pu2AttriListLen) -+{ -+ BOOLEAN fgIsAllocMem = FALSE; -+ UINT_8 aucWfaOui[] = VENDOR_OUI_WFA_SPECIFIC; -+ UINT_16 u2Offset = 0; -+ P_IE_P2P_T prIe = (P_IE_P2P_T) NULL; -+ PUINT_8 pucAttriListStart = (PUINT_8) NULL; -+ UINT_16 u2AttriListLen = 0, u2BufferSize = 0; -+ BOOLEAN fgBackupAttributes = FALSE; -+ UINT_16 u2CopyLen; -+ -+ ASSERT(prAdapter); -+ ASSERT(pucIE); -+ ASSERT(ppucAttriList); -+ ASSERT(pu2AttriListLen); -+ -+ if (ppucAttriList) -+ *ppucAttriList = NULL; -+ if (pu2AttriListLen) -+ *pu2AttriListLen = 0; -+ -+ if (ucOuiType == VENDOR_OUI_TYPE_WPS) { -+ aucWfaOui[0] = 0x00; -+ aucWfaOui[1] = 0x50; -+ aucWfaOui[2] = 0xF2; -+ } else if ((ucOuiType != VENDOR_OUI_TYPE_P2P) -+#if CFG_SUPPORT_WFD -+ && (ucOuiType != VENDOR_OUI_TYPE_WFD) -+#endif -+ ) { -+ DBGLOG(P2P, INFO, "Not supported OUI Type to parsing 0x%x\n", ucOuiType); -+ return fgIsAllocMem; -+ } -+ -+ IE_FOR_EACH(pucIE, u2IELength, u2Offset) { -+ if (ELEM_ID_VENDOR != IE_ID(pucIE)) -+ continue; -+ -+ prIe = (P_IE_P2P_T) pucIE; -+ -+ if (prIe->ucLength <= P2P_OUI_TYPE_LEN) -+ continue; -+ -+ if ((prIe->aucOui[0] == aucWfaOui[0]) && -+ (prIe->aucOui[1] == aucWfaOui[1]) && -+ (prIe->aucOui[2] == aucWfaOui[2]) && (ucOuiType == prIe->ucOuiType)) { -+ -+ if (!pucAttriListStart) { -+ pucAttriListStart = &prIe->aucP2PAttributes[0]; -+ if (prIe->ucLength > P2P_OUI_TYPE_LEN) -+ u2AttriListLen = (UINT_16) (prIe->ucLength - P2P_OUI_TYPE_LEN); -+ else -+ ASSERT(FALSE); -+ continue; -+ } -+/* More than 2 attributes. */ -+ -+ if (FALSE == fgBackupAttributes) { -+ P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo = -+ prAdapter->rWifiVar.prP2pSpecificBssInfo; -+ -+ fgBackupAttributes = TRUE; -+ if (ucOuiType == VENDOR_OUI_TYPE_P2P) { -+ kalMemCopy(&prP2pSpecificBssInfo->aucAttributesCache[0], -+ pucAttriListStart, u2AttriListLen); -+ -+ pucAttriListStart = -+ &prP2pSpecificBssInfo->aucAttributesCache[0]; -+ -+ u2BufferSize = P2P_MAXIMUM_ATTRIBUTE_LEN; -+ } else if (ucOuiType == VENDOR_OUI_TYPE_WPS) { -+ kalMemCopy(&prP2pSpecificBssInfo->aucWscAttributesCache -+ [0], pucAttriListStart, u2AttriListLen); -+ pucAttriListStart = -+ &prP2pSpecificBssInfo->aucWscAttributesCache[0]; -+ -+ u2BufferSize = WPS_MAXIMUM_ATTRIBUTES_CACHE_SIZE; -+ } -+#if CFG_SUPPORT_WFD -+ else if (ucOuiType == VENDOR_OUI_TYPE_WFD) { -+ PUINT_8 pucTmpBuf = (PUINT_8) NULL; -+ -+ pucTmpBuf = (PUINT_8) -+ kalMemAlloc(WPS_MAXIMUM_ATTRIBUTES_CACHE_SIZE, -+ VIR_MEM_TYPE); -+ -+ if (pucTmpBuf != NULL) { -+ fgIsAllocMem = TRUE; -+ } else { -+ /* Can't alloca memory for WFD IE relocate. */ -+ ASSERT(FALSE); -+ break; -+ } -+ -+ kalMemCopy(pucTmpBuf, -+ pucAttriListStart, u2AttriListLen); -+ -+ pucAttriListStart = pucTmpBuf; -+ -+ u2BufferSize = WPS_MAXIMUM_ATTRIBUTES_CACHE_SIZE; -+ } -+#endif -+ else -+ fgBackupAttributes = FALSE; -+ } -+ -+ u2CopyLen = (UINT_16) (prIe->ucLength - P2P_OUI_TYPE_LEN); -+ -+ if ((u2AttriListLen + u2CopyLen) > u2BufferSize) { -+ u2CopyLen = u2BufferSize - u2AttriListLen; -+ DBGLOG(P2P, WARN, -+ "Length of received P2P attributes > maximum cache size.\n"); -+ } -+ -+ if (u2CopyLen) { -+ kalMemCopy((PUINT_8) -+ ((ULONG) pucAttriListStart + -+ (UINT_32) u2AttriListLen), -+ &prIe->aucP2PAttributes[0], u2CopyLen); -+ -+ u2AttriListLen += u2CopyLen; -+ } -+ } /* prIe->aucOui */ -+ } /* IE_FOR_EACH */ -+ -+ if (pucAttriListStart) { -+ PUINT_8 pucAttribute = pucAttriListStart; -+ -+ DBGLOG(P2P, LOUD, "Checking Attribute Length.\n"); -+ if (ucOuiType == VENDOR_OUI_TYPE_P2P) { -+ P2P_ATTRI_FOR_EACH(pucAttribute, u2AttriListLen, u2Offset); -+ } else if (ucOuiType == VENDOR_OUI_TYPE_WFD) { -+ /* Do nothing */ -+ } else if (ucOuiType == VENDOR_OUI_TYPE_WPS) { -+ /* Big Endian: WSC, WFD. */ -+ WSC_ATTRI_FOR_EACH(pucAttribute, u2AttriListLen, u2Offset) { -+ DBGLOG(P2P, LOUD, "Attribute ID:%d, Length:%d.\n", -+ WSC_ATTRI_ID(pucAttribute), WSC_ATTRI_LEN(pucAttribute)); -+ } -+ } else { -+ } -+ -+ ASSERT(u2Offset == u2AttriListLen); -+ -+ if (ppucAttriList) -+ *ppucAttriList = pucAttriListStart; -+ if (pu2AttriListLen) -+ *pu2AttriListLen = u2AttriListLen; -+ -+ } else { -+ if (ppucAttriList) -+ *ppucAttriList = (PUINT_8) NULL; -+ if (pu2AttriListLen) -+ *pu2AttriListLen = 0; -+ } -+ -+ return fgIsAllocMem; -+} /* p2pFuncGetAttriList */ -+ -+P_MSDU_INFO_T p2pFuncProcessP2pProbeRsp(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMgmtTxMsdu) -+{ -+ P_MSDU_INFO_T prRetMsduInfo = prMgmtTxMsdu; -+ P_WLAN_PROBE_RSP_FRAME_T prProbeRspFrame = (P_WLAN_PROBE_RSP_FRAME_T) NULL; -+ PUINT_8 pucIEBuf = (PUINT_8) NULL; -+ UINT_16 u2Offset = 0, u2IELength = 0, u2ProbeRspHdrLen = 0; -+ BOOLEAN fgIsP2PIE = FALSE, fgIsWSCIE = FALSE; -+ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; -+ UINT_16 u2EstimateSize = 0, u2EstimatedExtraIELen = 0; -+ UINT_32 u4IeArraySize = 0, u4Idx = 0; -+ UINT_8 ucOuiType = 0; -+ UINT_16 u2SubTypeVersion = 0; -+ -+ BOOLEAN fgIsPureAP = prAdapter->rWifiVar.prP2pFsmInfo->fgIsApMode; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prMgmtTxMsdu != NULL)); -+ -+ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); -+ -+ /* 3 Make sure this is probe response frame. */ -+ prProbeRspFrame = (P_WLAN_PROBE_RSP_FRAME_T) ((ULONG) prMgmtTxMsdu->prPacket + MAC_TX_RESERVED_FIELD); -+ ASSERT_BREAK((prProbeRspFrame->u2FrameCtrl & MASK_FRAME_TYPE) == MAC_FRAME_PROBE_RSP); -+ -+ if (prP2pBssInfo->u2BeaconInterval) -+ prProbeRspFrame->u2BeaconInterval = prP2pBssInfo->u2BeaconInterval; -+ -+ /* 3 Get the importent P2P IE. */ -+ u2ProbeRspHdrLen = -+ (WLAN_MAC_MGMT_HEADER_LEN + TIMESTAMP_FIELD_LEN + BEACON_INTERVAL_FIELD_LEN + CAP_INFO_FIELD_LEN); -+ pucIEBuf = prProbeRspFrame->aucInfoElem; -+ u2IELength = prMgmtTxMsdu->u2FrameLength - u2ProbeRspHdrLen; -+ -+#if CFG_SUPPORT_WFD -+ prAdapter->prGlueInfo->prP2PInfo->u2VenderIELen = 0; -+#endif -+ -+ IE_FOR_EACH(pucIEBuf, u2IELength, u2Offset) { -+ switch (IE_ID(pucIEBuf)) { -+ case ELEM_ID_SSID: -+ { -+ -+ COPY_SSID(prP2pBssInfo->aucSSID, -+ prP2pBssInfo->ucSSIDLen, -+ SSID_IE(pucIEBuf)->aucSSID, SSID_IE(pucIEBuf)->ucLength); -+ } -+ break; -+ case ELEM_ID_VENDOR: -+#if !CFG_SUPPORT_WFD -+ if (rsnParseCheckForWFAInfoElem(prAdapter, pucIEBuf, &ucOuiType, &u2SubTypeVersion)) { -+ if (ucOuiType == VENDOR_OUI_TYPE_WPS) { -+ kalP2PUpdateWSC_IE(prAdapter->prGlueInfo, 2, pucIEBuf, -+ IE_SIZE(pucIEBuf)); -+ fgIsWSCIE = TRUE; -+ } -+ -+ } else if (p2pFuncParseCheckForP2PInfoElem(prAdapter, pucIEBuf, &ucOuiType)) { -+ if (ucOuiType == VENDOR_OUI_TYPE_P2P) { -+ /* 2 Note(frog): I use WSC IE buffer for Probe Request to -+ * store the P2P IE for Probe Response. */ -+ kalP2PUpdateWSC_IE(prAdapter->prGlueInfo, 1, pucIEBuf, -+ IE_SIZE(pucIEBuf)); -+ fgIsP2PIE = TRUE; -+ } -+ -+ } else { -+ if ((prAdapter->prGlueInfo->prP2PInfo->u2VenderIELen + -+ IE_SIZE(pucIEBuf)) < 512) { -+ kalMemCopy(prAdapter->prGlueInfo->prP2PInfo->aucVenderIE, -+ pucIEBuf, IE_SIZE(pucIEBuf)); -+ prAdapter->prGlueInfo->prP2PInfo->u2VenderIELen += -+ IE_SIZE(pucIEBuf); -+ } -+ } -+#else -+ /* Eddie May be WFD */ -+ if (rsnParseCheckForWFAInfoElem -+ (prAdapter, pucIEBuf, &ucOuiType, &u2SubTypeVersion)) { -+ if (ucOuiType == VENDOR_OUI_TYPE_WMM) -+ break; -+ -+ } -+ if ((prAdapter->prGlueInfo->prP2PInfo->u2VenderIELen + IE_SIZE(pucIEBuf)) < -+ 1024) { -+ kalMemCopy(prAdapter->prGlueInfo->prP2PInfo->aucVenderIE + -+ prAdapter->prGlueInfo->prP2PInfo->u2VenderIELen, pucIEBuf, -+ IE_SIZE(pucIEBuf)); -+ prAdapter->prGlueInfo->prP2PInfo->u2VenderIELen += IE_SIZE(pucIEBuf); -+ } -+#endif -+ break; -+ default: -+ break; -+ } -+ -+ } -+ -+ /* 3 Check the total size & current frame. */ -+ u2EstimateSize = WLAN_MAC_MGMT_HEADER_LEN + -+ TIMESTAMP_FIELD_LEN + -+ BEACON_INTERVAL_FIELD_LEN + -+ CAP_INFO_FIELD_LEN + -+ (ELEM_HDR_LEN + ELEM_MAX_LEN_SSID) + -+ (ELEM_HDR_LEN + ELEM_MAX_LEN_SUP_RATES) + (ELEM_HDR_LEN + ELEM_MAX_LEN_DS_PARAMETER_SET); -+ -+ u2EstimatedExtraIELen = 0; -+ -+ u4IeArraySize = sizeof(txProbeRspIETable) / sizeof(APPEND_VAR_IE_ENTRY_T); -+ for (u4Idx = 0; u4Idx < u4IeArraySize; u4Idx++) { -+ if (txProbeRspIETable[u4Idx].u2EstimatedFixedIELen) { -+ u2EstimatedExtraIELen += txProbeRspIETable[u4Idx].u2EstimatedFixedIELen; -+ } -+ -+ else { -+ ASSERT(txProbeRspIETable[u4Idx].pfnCalculateVariableIELen); -+ -+ u2EstimatedExtraIELen += -+ (UINT_16) (txProbeRspIETable[u4Idx].pfnCalculateVariableIELen -+ (prAdapter, NETWORK_TYPE_P2P_INDEX, NULL)); -+ } -+ -+ } -+ -+ if (fgIsWSCIE) -+ u2EstimatedExtraIELen += kalP2PCalWSC_IELen(prAdapter->prGlueInfo, 2); -+ -+ if (fgIsP2PIE) { -+ u2EstimatedExtraIELen += kalP2PCalWSC_IELen(prAdapter->prGlueInfo, 1); -+ u2EstimatedExtraIELen += p2pFuncCalculateP2P_IE_NoA(prAdapter, 0, NULL); -+ } -+#if CFG_SUPPORT_WFD -+ u2EstimatedExtraIELen += prAdapter->prGlueInfo->prP2PInfo->u2VenderIELen; -+#endif -+ -+ u2EstimateSize += u2EstimatedExtraIELen; -+ if (u2EstimateSize > (prRetMsduInfo->u2FrameLength)) { -+ prRetMsduInfo = cnmMgtPktAlloc(prAdapter, u2EstimateSize); -+ -+ if (prRetMsduInfo == NULL) { -+ DBGLOG(P2P, WARN, "No packet for sending new probe response, use original one\n"); -+ prRetMsduInfo = prMgmtTxMsdu; -+ break; -+ } -+ -+ prRetMsduInfo->ucNetworkType = NETWORK_TYPE_P2P_INDEX; -+ } -+ /* 3 Compose / Re-compose probe response frame. */ -+ bssComposeBeaconProbeRespFrameHeaderAndFF((PUINT_8) -+ ((ULONG) (prRetMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD), -+ prProbeRspFrame->aucDestAddr, prProbeRspFrame->aucSrcAddr, -+ prProbeRspFrame->aucBSSID, prProbeRspFrame->u2BeaconInterval, -+ fgIsPureAP ? prP2pBssInfo-> -+ u2CapInfo : prProbeRspFrame->u2CapInfo); -+ -+ prRetMsduInfo->u2FrameLength = -+ (WLAN_MAC_MGMT_HEADER_LEN + TIMESTAMP_FIELD_LEN + BEACON_INTERVAL_FIELD_LEN + CAP_INFO_FIELD_LEN); -+ -+ bssBuildBeaconProbeRespFrameCommonIEs(prRetMsduInfo, prP2pBssInfo, prProbeRspFrame->aucDestAddr); -+ -+ for (u4Idx = 0; u4Idx < u4IeArraySize; u4Idx++) { -+ if (txProbeRspIETable[u4Idx].pfnAppendIE) -+ txProbeRspIETable[u4Idx].pfnAppendIE(prAdapter, prRetMsduInfo); -+ -+ } -+ -+ if (fgIsWSCIE) { -+ kalP2PGenWSC_IE(prAdapter->prGlueInfo, -+ 2, -+ (PUINT_8) ((ULONG) prRetMsduInfo->prPacket + -+ (UINT_32) prRetMsduInfo->u2FrameLength)); -+ -+ prRetMsduInfo->u2FrameLength += (UINT_16) kalP2PCalWSC_IELen(prAdapter->prGlueInfo, 2); -+ } -+ -+ if (fgIsP2PIE) { -+ kalP2PGenWSC_IE(prAdapter->prGlueInfo, -+ 1, -+ (PUINT_8) ((ULONG) prRetMsduInfo->prPacket + -+ (UINT_32) prRetMsduInfo->u2FrameLength)); -+ -+ prRetMsduInfo->u2FrameLength += (UINT_16) kalP2PCalWSC_IELen(prAdapter->prGlueInfo, 1); -+ p2pFuncGenerateP2P_IE_NoA(prAdapter, prRetMsduInfo); -+ } -+#if CFG_SUPPORT_WFD -+ if (prAdapter->prGlueInfo->prP2PInfo->u2VenderIELen > 0) { -+ kalMemCopy((PUINT_8) ((ULONG) prRetMsduInfo->prPacket + (UINT_32) prRetMsduInfo->u2FrameLength), -+ prAdapter->prGlueInfo->prP2PInfo->aucVenderIE, -+ prAdapter->prGlueInfo->prP2PInfo->u2VenderIELen); -+ prRetMsduInfo->u2FrameLength += (UINT_16) prAdapter->prGlueInfo->prP2PInfo->u2VenderIELen; -+ } -+#endif -+ -+ } while (FALSE); -+ -+ if (prRetMsduInfo != prMgmtTxMsdu) -+ cnmMgtPktFree(prAdapter, prMgmtTxMsdu); -+ -+ return prRetMsduInfo; -+} /* p2pFuncProcessP2pProbeRsp */ -+ -+#if 0 /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0) */ -+UINT_32 -+p2pFuncCalculateExtra_IELenForBeacon(IN P_ADAPTER_T prAdapter, -+ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec) -+{ -+ -+ P_P2P_SPECIFIC_BSS_INFO_T prP2pSpeBssInfo = (P_P2P_SPECIFIC_BSS_INFO_T) NULL; -+ UINT_32 u4IELen = 0; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (eNetTypeIndex == NETWORK_TYPE_P2P_INDEX)); -+ -+ if (p2pFuncIsAPMode(prAdapter->rWifiVar.prP2pFsmInfo)) -+ break; -+ -+ prP2pSpeBssInfo = prAdapter->rWifiVar.prP2pSpecificBssInfo; -+ -+ u4IELen = prP2pSpeBssInfo->u2IELenForBCN; -+ -+ } while (FALSE); -+ -+ return u4IELen; -+} /* p2pFuncCalculateP2p_IELenForBeacon */ -+ -+VOID p2pFuncGenerateExtra_IEForBeacon(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo) -+{ -+ P_P2P_SPECIFIC_BSS_INFO_T prP2pSpeBssInfo = (P_P2P_SPECIFIC_BSS_INFO_T) NULL; -+ PUINT_8 pucIEBuf = (PUINT_8) NULL; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prMsduInfo != NULL)); -+ -+ prP2pSpeBssInfo = prAdapter->rWifiVar.prP2pSpecificBssInfo; -+ -+ if (p2pFuncIsAPMode(prAdapter->rWifiVar.prP2pFsmInfo)) -+ break; -+ -+ pucIEBuf = (PUINT_8) ((UINT_32) prMsduInfo->prPacket + (UINT_32) prMsduInfo->u2FrameLength); -+ -+ kalMemCopy(pucIEBuf, prP2pSpeBssInfo->aucBeaconIECache, prP2pSpeBssInfo->u2IELenForBCN); -+ -+ prMsduInfo->u2FrameLength += prP2pSpeBssInfo->u2IELenForBCN; -+ -+ } while (FALSE); -+ -+} /* p2pFuncGenerateExtra_IEForBeacon */ -+ -+#else -+UINT_32 -+p2pFuncCalculateP2p_IELenForBeacon(IN P_ADAPTER_T prAdapter, -+ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec) -+{ -+ P_P2P_SPECIFIC_BSS_INFO_T prP2pSpeBssInfo = (P_P2P_SPECIFIC_BSS_INFO_T) NULL; -+ UINT_32 u4IELen = 0; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (eNetTypeIndex == NETWORK_TYPE_P2P_INDEX)); -+ -+ if (!prAdapter->fgIsP2PRegistered) -+ break; -+ -+ if (p2pFuncIsAPMode(prAdapter->rWifiVar.prP2pFsmInfo)) -+ break; -+ -+ prP2pSpeBssInfo = prAdapter->rWifiVar.prP2pSpecificBssInfo; -+ -+ u4IELen = prP2pSpeBssInfo->u2AttributeLen; -+ -+ } while (FALSE); -+ -+ return u4IELen; -+} /* p2pFuncCalculateP2p_IELenForBeacon */ -+ -+VOID p2pFuncGenerateP2p_IEForBeacon(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo) -+{ -+ P_P2P_SPECIFIC_BSS_INFO_T prP2pSpeBssInfo = (P_P2P_SPECIFIC_BSS_INFO_T) NULL; -+ PUINT_8 pucIEBuf = (PUINT_8) NULL; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prMsduInfo != NULL)); -+ -+ if (!prAdapter->fgIsP2PRegistered) -+ break; -+ -+ prP2pSpeBssInfo = prAdapter->rWifiVar.prP2pSpecificBssInfo; -+ -+ if (p2pFuncIsAPMode(prAdapter->rWifiVar.prP2pFsmInfo)) -+ break; -+ -+ pucIEBuf = (PUINT_8) ((ULONG) prMsduInfo->prPacket + (UINT_32) prMsduInfo->u2FrameLength); -+ -+ kalMemCopy(pucIEBuf, prP2pSpeBssInfo->aucAttributesCache, prP2pSpeBssInfo->u2AttributeLen); -+ -+ prMsduInfo->u2FrameLength += prP2pSpeBssInfo->u2AttributeLen; -+ -+ } while (FALSE); -+ -+} /* p2pFuncGenerateP2p_IEForBeacon */ -+ -+UINT_32 -+p2pFuncCalculateWSC_IELenForBeacon(IN P_ADAPTER_T prAdapter, -+ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec) -+{ -+ if (eNetTypeIndex != NETWORK_TYPE_P2P_INDEX) -+ return 0; -+ -+ return kalP2PCalWSC_IELen(prAdapter->prGlueInfo, 0); -+} /* p2pFuncCalculateP2p_IELenForBeacon */ -+ -+VOID p2pFuncGenerateWSC_IEForBeacon(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo) -+{ -+ PUINT_8 pucBuffer; -+ UINT_16 u2IELen = 0; -+ -+ ASSERT(prAdapter); -+ ASSERT(prMsduInfo); -+ -+ if (prMsduInfo->ucNetworkType != NETWORK_TYPE_P2P_INDEX) -+ return; -+ -+ u2IELen = (UINT_16) kalP2PCalWSC_IELen(prAdapter->prGlueInfo, 0); -+ -+ pucBuffer = (PUINT_8) ((ULONG) prMsduInfo->prPacket + (UINT_32) prMsduInfo->u2FrameLength); -+ -+ ASSERT(pucBuffer); -+ -+ /* TODO: Check P2P FSM State. */ -+ kalP2PGenWSC_IE(prAdapter->prGlueInfo, 0, pucBuffer); -+ -+ prMsduInfo->u2FrameLength += u2IELen; -+ -+} /* p2pFuncGenerateP2p_IEForBeacon */ -+ -+#endif -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is used to calculate P2P IE length for Beacon frame. -+* -+* @param[in] eNetTypeIndex Specify which network -+* @param[in] prStaRec Pointer to the STA_RECORD_T -+* -+* @return The length of P2P IE added -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT_32 -+p2pFuncCalculateP2p_IELenForAssocRsp(IN P_ADAPTER_T prAdapter, -+ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec) -+{ -+ -+ if (eNetTypeIndex != NETWORK_TYPE_P2P_INDEX) -+ return 0; -+ -+ return p2pFuncCalculateP2P_IELen(prAdapter, -+ eNetTypeIndex, -+ prStaRec, -+ txAssocRspAttributesTable, -+ sizeof(txAssocRspAttributesTable) / sizeof(APPEND_VAR_ATTRI_ENTRY_T)); -+ -+} /* p2pFuncCalculateP2p_IELenForAssocRsp */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is used to generate P2P IE for Beacon frame. -+* -+* @param[in] prMsduInfo Pointer to the composed MSDU_INFO_T. -+* -+* @return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID p2pFuncGenerateP2p_IEForAssocRsp(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo) -+{ -+ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; -+ P_STA_RECORD_T prStaRec = (P_STA_RECORD_T) NULL; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prMsduInfo != NULL)); -+ -+ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; -+ -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); -+ if (!prStaRec) -+ break; -+ -+ if (IS_STA_P2P_TYPE(prStaRec)) { -+ DBGLOG(P2P, TRACE, "Generate NULL P2P IE for Assoc Rsp.\n"); -+ -+ p2pFuncGenerateP2P_IE(prAdapter, -+ TRUE, -+ &prMsduInfo->u2FrameLength, -+ prMsduInfo->prPacket, -+ 1500, -+ txAssocRspAttributesTable, -+ sizeof(txAssocRspAttributesTable) / sizeof(APPEND_VAR_ATTRI_ENTRY_T)); -+ } else { -+ -+ DBGLOG(P2P, TRACE, "Legacy device, no P2P IE.\n"); -+ } -+ -+ } while (FALSE); -+ -+ return; -+ -+} /* p2pFuncGenerateP2p_IEForAssocRsp */ -+ -+UINT_32 -+p2pFuncCalculateWSC_IELenForAssocRsp(IN P_ADAPTER_T prAdapter, -+ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec) -+{ -+ DBGLOG(P2P, TRACE, "p2pFuncCalculateWSC_IELenForAssocRsp\n"); -+ if (eNetTypeIndex != NETWORK_TYPE_P2P_INDEX) -+ return 0; -+ -+ return kalP2PCalWSC_IELen(prAdapter->prGlueInfo, 0); -+} /* p2pFuncCalculateP2p_IELenForAssocRsp */ -+ -+VOID p2pFuncGenerateWSC_IEForAssocRsp(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo) -+{ -+ PUINT_8 pucBuffer; -+ UINT_16 u2IELen = 0; -+ -+ ASSERT(prAdapter); -+ ASSERT(prMsduInfo); -+ -+ if (prMsduInfo->ucNetworkType != NETWORK_TYPE_P2P_INDEX) -+ return; -+ DBGLOG(P2P, TRACE, "p2pFuncGenerateWSC_IEForAssocRsp\n"); -+ -+ u2IELen = (UINT_16) kalP2PCalWSC_IELen(prAdapter->prGlueInfo, 0); -+ -+ pucBuffer = (PUINT_8) ((ULONG) prMsduInfo->prPacket + (UINT_32) prMsduInfo->u2FrameLength); -+ -+ ASSERT(pucBuffer); -+ -+ /* TODO: Check P2P FSM State. */ -+ kalP2PGenWSC_IE(prAdapter->prGlueInfo, 0, pucBuffer); -+ -+ prMsduInfo->u2FrameLength += u2IELen; -+ -+} -+ -+/* p2pFuncGenerateP2p_IEForAssocRsp */ -+ -+UINT_32 -+p2pFuncCalculateP2P_IELen(IN P_ADAPTER_T prAdapter, -+ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, -+ IN P_STA_RECORD_T prStaRec, -+ IN APPEND_VAR_ATTRI_ENTRY_T arAppendAttriTable[], IN UINT_32 u4AttriTableSize) -+{ -+ -+ UINT_32 u4OverallAttriLen, u4Dummy; -+ UINT_16 u2EstimatedFixedAttriLen; -+ UINT_32 i; -+ -+ /* Overall length of all Attributes */ -+ u4OverallAttriLen = 0; -+ -+ for (i = 0; i < u4AttriTableSize; i++) { -+ u2EstimatedFixedAttriLen = arAppendAttriTable[i].u2EstimatedFixedAttriLen; -+ -+ if (u2EstimatedFixedAttriLen) { -+ u4OverallAttriLen += u2EstimatedFixedAttriLen; -+ } else { -+ ASSERT(arAppendAttriTable[i].pfnCalculateVariableAttriLen); -+ -+ u4OverallAttriLen += arAppendAttriTable[i].pfnCalculateVariableAttriLen(prAdapter, prStaRec); -+ } -+ } -+ -+ u4Dummy = u4OverallAttriLen; -+ u4OverallAttriLen += P2P_IE_OUI_HDR; -+ -+ for (; (u4Dummy > P2P_MAXIMUM_ATTRIBUTE_LEN);) { -+ u4OverallAttriLen += P2P_IE_OUI_HDR; -+ u4Dummy -= P2P_MAXIMUM_ATTRIBUTE_LEN; -+ } -+ -+ return u4OverallAttriLen; -+} /* p2pFuncCalculateP2P_IELen */ -+ -+VOID -+p2pFuncGenerateP2P_IE(IN P_ADAPTER_T prAdapter, -+ IN BOOLEAN fgIsAssocFrame, -+ IN PUINT_16 pu2Offset, -+ IN PUINT_8 pucBuf, -+ IN UINT_16 u2BufSize, -+ IN APPEND_VAR_ATTRI_ENTRY_T arAppendAttriTable[], IN UINT_32 u4AttriTableSize) -+{ -+ PUINT_8 pucBuffer = (PUINT_8) NULL; -+ P_IE_P2P_T prIeP2P = (P_IE_P2P_T) NULL; -+ UINT_32 u4OverallAttriLen; -+ UINT_32 u4AttriLen; -+ UINT_8 aucWfaOui[] = VENDOR_OUI_WFA_SPECIFIC; -+ UINT_8 aucTempBuffer[P2P_MAXIMUM_ATTRIBUTE_LEN]; -+ UINT_32 i; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (pucBuf != NULL)); -+ -+ pucBuffer = (PUINT_8) ((ULONG) pucBuf + (*pu2Offset)); -+ -+ ASSERT_BREAK(pucBuffer != NULL); -+ -+ /* Check buffer length is still enough. */ -+ ASSERT_BREAK((u2BufSize - (*pu2Offset)) >= P2P_IE_OUI_HDR); -+ -+ prIeP2P = (P_IE_P2P_T) pucBuffer; -+ -+ prIeP2P->ucId = ELEM_ID_P2P; -+ -+ prIeP2P->aucOui[0] = aucWfaOui[0]; -+ prIeP2P->aucOui[1] = aucWfaOui[1]; -+ prIeP2P->aucOui[2] = aucWfaOui[2]; -+ prIeP2P->ucOuiType = VENDOR_OUI_TYPE_P2P; -+ -+ (*pu2Offset) += P2P_IE_OUI_HDR; -+ -+ /* Overall length of all Attributes */ -+ u4OverallAttriLen = 0; -+ -+ for (i = 0; i < u4AttriTableSize; i++) { -+ -+ if (arAppendAttriTable[i].pfnAppendAttri) { -+ u4AttriLen = -+ arAppendAttriTable[i].pfnAppendAttri(prAdapter, fgIsAssocFrame, pu2Offset, pucBuf, -+ u2BufSize); -+ -+ u4OverallAttriLen += u4AttriLen; -+ -+ if (u4OverallAttriLen > P2P_MAXIMUM_ATTRIBUTE_LEN) { -+ u4OverallAttriLen -= P2P_MAXIMUM_ATTRIBUTE_LEN; -+ -+ prIeP2P->ucLength = (VENDOR_OUI_TYPE_LEN + P2P_MAXIMUM_ATTRIBUTE_LEN); -+ -+ pucBuffer = -+ (PUINT_8) ((ULONG) prIeP2P + -+ (VENDOR_OUI_TYPE_LEN + P2P_MAXIMUM_ATTRIBUTE_LEN)); -+ -+ prIeP2P = (P_IE_P2P_T) ((ULONG) prIeP2P + -+ (ELEM_HDR_LEN + -+ (VENDOR_OUI_TYPE_LEN + P2P_MAXIMUM_ATTRIBUTE_LEN))); -+ -+ kalMemCopy(aucTempBuffer, pucBuffer, u4OverallAttriLen); -+ -+ prIeP2P->ucId = ELEM_ID_P2P; -+ -+ prIeP2P->aucOui[0] = aucWfaOui[0]; -+ prIeP2P->aucOui[1] = aucWfaOui[1]; -+ prIeP2P->aucOui[2] = aucWfaOui[2]; -+ prIeP2P->ucOuiType = VENDOR_OUI_TYPE_P2P; -+ -+ kalMemCopy(prIeP2P->aucP2PAttributes, aucTempBuffer, u4OverallAttriLen); -+ (*pu2Offset) += P2P_IE_OUI_HDR; -+ } -+ -+ } -+ -+ } -+ -+ prIeP2P->ucLength = (UINT_8) (VENDOR_OUI_TYPE_LEN + u4OverallAttriLen); -+ -+ } while (FALSE); -+ -+} /* p2pFuncGenerateP2P_IE */ -+ -+UINT_32 -+p2pFuncAppendAttriStatusForAssocRsp(IN P_ADAPTER_T prAdapter, -+ IN BOOLEAN fgIsAssocFrame, -+ IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize) -+{ -+ PUINT_8 pucBuffer; -+ P_P2P_ATTRI_STATUS_T prAttriStatus; -+ P_P2P_CONNECTION_SETTINGS_T prP2pConnSettings = (P_P2P_CONNECTION_SETTINGS_T) NULL; -+ UINT_32 u4AttriLen = 0; -+ -+ ASSERT(prAdapter); -+ ASSERT(pucBuf); -+ -+ prP2pConnSettings = prAdapter->rWifiVar.prP2PConnSettings; -+ -+ if (fgIsAssocFrame) -+ return u4AttriLen; -+ /* TODO: For assoc request P2P IE check in driver & return status in P2P IE. */ -+ -+ pucBuffer = (PUINT_8) ((ULONG) pucBuf + (UINT_32) (*pu2Offset)); -+ -+ ASSERT(pucBuffer); -+ prAttriStatus = (P_P2P_ATTRI_STATUS_T) pucBuffer; -+ -+ ASSERT(u2BufSize >= ((*pu2Offset) + (UINT_16) u4AttriLen)); -+ -+ prAttriStatus->ucId = P2P_ATTRI_ID_STATUS; -+ WLAN_SET_FIELD_16(&prAttriStatus->u2Length, P2P_ATTRI_MAX_LEN_STATUS); -+ -+ prAttriStatus->ucStatusCode = P2P_STATUS_FAIL_PREVIOUS_PROTOCOL_ERR; -+ -+ u4AttriLen = (P2P_ATTRI_HDR_LEN + P2P_ATTRI_MAX_LEN_STATUS); -+ -+ (*pu2Offset) += (UINT_16) u4AttriLen; -+ -+ return u4AttriLen; -+} /* p2pFuncAppendAttriStatusForAssocRsp */ -+ -+UINT_32 -+p2pFuncAppendAttriExtListenTiming(IN P_ADAPTER_T prAdapter, -+ IN BOOLEAN fgIsAssocFrame, -+ IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize) -+{ -+ UINT_32 u4AttriLen = 0; -+ P_P2P_ATTRI_EXT_LISTEN_TIMING_T prP2pExtListenTiming = (P_P2P_ATTRI_EXT_LISTEN_TIMING_T) NULL; -+ P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo = (P_P2P_SPECIFIC_BSS_INFO_T) NULL; -+ PUINT_8 pucBuffer = NULL; -+ -+ ASSERT(prAdapter); -+ ASSERT(pucBuf); -+ -+ if (fgIsAssocFrame) -+ return u4AttriLen; -+ /* TODO: For extend listen timing. */ -+ -+ prP2pSpecificBssInfo = prAdapter->rWifiVar.prP2pSpecificBssInfo; -+ -+ u4AttriLen = (P2P_ATTRI_HDR_LEN + P2P_ATTRI_MAX_LEN_EXT_LISTEN_TIMING); -+ -+ ASSERT(u2BufSize >= ((*pu2Offset) + (UINT_16) u4AttriLen)); -+ -+ pucBuffer = (PUINT_8) ((ULONG) pucBuf + (UINT_32) (*pu2Offset)); -+ -+ ASSERT(pucBuffer); -+ -+ prP2pExtListenTiming = (P_P2P_ATTRI_EXT_LISTEN_TIMING_T) pucBuffer; -+ -+ prP2pExtListenTiming->ucId = P2P_ATTRI_ID_EXT_LISTEN_TIMING; -+ WLAN_SET_FIELD_16(&prP2pExtListenTiming->u2Length, P2P_ATTRI_MAX_LEN_EXT_LISTEN_TIMING); -+ WLAN_SET_FIELD_16(&prP2pExtListenTiming->u2AvailInterval, prP2pSpecificBssInfo->u2AvailabilityInterval); -+ WLAN_SET_FIELD_16(&prP2pExtListenTiming->u2AvailPeriod, prP2pSpecificBssInfo->u2AvailabilityPeriod); -+ -+ (*pu2Offset) += (UINT_16) u4AttriLen; -+ -+ return u4AttriLen; -+} /* p2pFuncAppendAttriExtListenTiming */ -+ -+P_IE_HDR_T -+p2pFuncGetSpecIE(IN P_ADAPTER_T prAdapter, -+ IN PUINT_8 pucIEBuf, IN UINT_16 u2BufferLen, IN UINT_8 ucElemID, IN PBOOLEAN pfgIsMore) -+{ -+ P_IE_HDR_T prTargetIE = (P_IE_HDR_T) NULL; -+ PUINT_8 pucIE = (PUINT_8) NULL; -+ UINT_16 u2Offset = 0; -+ -+ if (pfgIsMore) -+ *pfgIsMore = FALSE; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) -+ && (pucIEBuf != NULL)); -+ -+ pucIE = pucIEBuf; -+ -+ IE_FOR_EACH(pucIE, u2BufferLen, u2Offset) { -+ if (IE_ID(pucIE) == ucElemID) { -+ if ((prTargetIE) && (pfgIsMore)) { -+ -+ *pfgIsMore = TRUE; -+ break; -+ } -+ prTargetIE = (P_IE_HDR_T) pucIE; -+ -+ if (pfgIsMore == NULL) -+ break; -+ -+ } -+ } -+ -+ } while (FALSE); -+ -+ return prTargetIE; -+} /* p2pFuncGetSpecIE */ -+ -+P_ATTRIBUTE_HDR_T -+p2pFuncGetSpecAttri(IN P_ADAPTER_T prAdapter, -+ IN UINT_8 ucOuiType, IN PUINT_8 pucIEBuf, IN UINT_16 u2BufferLen, IN UINT_16 u2AttriID) -+{ -+ P_IE_P2P_T prP2pIE = (P_IE_P2P_T) NULL; -+ P_ATTRIBUTE_HDR_T prTargetAttri = (P_ATTRIBUTE_HDR_T) NULL; -+ BOOLEAN fgIsMore = FALSE; -+ PUINT_8 pucIE = (PUINT_8) NULL, pucAttri = (PUINT_8) NULL; -+ UINT_16 u2OffsetAttri = 0; -+ UINT_16 u2BufferLenLeft = 0; -+ UINT_8 aucWfaOui[] = VENDOR_OUI_WFA_SPECIFIC; -+ -+ DBGLOG(P2P, INFO, "Check AssocReq Oui type %u attri %u for len %u\n", ucOuiType, u2AttriID, u2BufferLen); -+ -+ ASSERT(prAdapter); -+ ASSERT(pucIEBuf); -+ -+ u2BufferLenLeft = u2BufferLen; -+ pucIE = pucIEBuf; -+ do { -+ fgIsMore = FALSE; -+ prP2pIE = (P_IE_P2P_T) p2pFuncGetSpecIE(prAdapter, -+ pucIE, u2BufferLenLeft, ELEM_ID_VENDOR, &fgIsMore); -+ if (prP2pIE == NULL) -+ continue; -+ -+ ASSERT((ULONG) prP2pIE >= (ULONG) pucIE); -+ -+ u2BufferLenLeft = u2BufferLen - (UINT_16) (((ULONG) prP2pIE) - ((ULONG) pucIEBuf)); -+ -+ DBGLOG(P2P, INFO, "Find vendor id %u len %u oui %u more %u LeftLen %u\n", -+ IE_ID(prP2pIE), IE_LEN(prP2pIE), prP2pIE->ucOuiType, fgIsMore, -+ u2BufferLenLeft); -+ -+ if ((IE_LEN(prP2pIE) > P2P_OUI_TYPE_LEN) && (prP2pIE->ucOuiType == ucOuiType)) { -+ switch (ucOuiType) { -+ case VENDOR_OUI_TYPE_WPS: -+ aucWfaOui[0] = 0x00; -+ aucWfaOui[1] = 0x50; -+ aucWfaOui[2] = 0xF2; -+ break; -+ case VENDOR_OUI_TYPE_P2P: -+ break; -+ case VENDOR_OUI_TYPE_WPA: -+ case VENDOR_OUI_TYPE_WMM: -+ case VENDOR_OUI_TYPE_WFD: -+ default: -+ break; -+ } -+ -+ if ((prP2pIE->aucOui[0] != aucWfaOui[0]) -+ || (prP2pIE->aucOui[1] != aucWfaOui[1]) -+ || (prP2pIE->aucOui[2] != aucWfaOui[2])) -+ continue; -+ -+ u2OffsetAttri = 0; -+ pucAttri = prP2pIE->aucP2PAttributes; -+ -+ if (ucOuiType == VENDOR_OUI_TYPE_WPS) { -+ WSC_ATTRI_FOR_EACH(pucAttri, -+ (IE_LEN(prP2pIE) - P2P_OUI_TYPE_LEN), u2OffsetAttri) { -+ /* LOG_FUNC("WSC: attri id=%u len=%u\n", -+ * WSC_ATTRI_ID(pucAttri), -+ * WSC_ATTRI_LEN(pucAttri)); */ -+ if (WSC_ATTRI_ID(pucAttri) == u2AttriID) { -+ prTargetAttri = -+ (P_ATTRIBUTE_HDR_T) pucAttri; -+ break; -+ } -+ } -+ -+ } else if (ucOuiType == VENDOR_OUI_TYPE_P2P) { -+ P2P_ATTRI_FOR_EACH(pucAttri, -+ (IE_LEN(prP2pIE) - P2P_OUI_TYPE_LEN), u2OffsetAttri) { -+ /* LOG_FUNC("P2P: attri id=%u len=%u\n", -+ * ATTRI_ID(pucAttri), ATTRI_LEN(pucAttri)); */ -+ if (ATTRI_ID(pucAttri) == (UINT_8) u2AttriID) { -+ prTargetAttri = (P_ATTRIBUTE_HDR_T) pucAttri; -+ break; -+ } -+ } -+ } -+#if CFG_SUPPORT_WFD -+ else if (ucOuiType == VENDOR_OUI_TYPE_WFD) { -+ WFD_ATTRI_FOR_EACH(pucAttri, -+ (IE_LEN(prP2pIE) - P2P_OUI_TYPE_LEN), u2OffsetAttri) { -+ /* DBGLOG(P2P, INFO, ("WFD: attri id=%u -+ * len=%u\n",WFD_ATTRI_ID(pucAttri), -+ * WFD_ATTRI_LEN(pucAttri))); */ -+ if (ATTRI_ID(pucAttri) == (UINT_8) u2AttriID) { -+ prTargetAttri = -+ (P_ATTRIBUTE_HDR_T) pucAttri; -+ break; -+ } -+ } -+ } -+#endif -+ /* Do nothing */ -+ /* Possible or else. */ -+ } /* ucOuiType */ -+ /* P2P_OUI_TYPE_LEN */ -+ pucIE = (PUINT_8) (((ULONG) prP2pIE) + IE_SIZE(prP2pIE)); -+ /* prP2pIE */ -+ } while (prP2pIE && fgIsMore && u2BufferLenLeft); -+ -+ return prTargetAttri; -+} -+ -+/* p2pFuncGetSpecAttri */ -+ -+WLAN_STATUS -+p2pFuncGenerateBeaconProbeRsp(IN P_ADAPTER_T prAdapter, -+ IN P_BSS_INFO_T prBssInfo, IN P_MSDU_INFO_T prMsduInfo, IN BOOLEAN fgIsProbeRsp) -+{ -+ WLAN_STATUS rWlanStatus = WLAN_STATUS_SUCCESS; -+ P_WLAN_BEACON_FRAME_T prBcnFrame = (P_WLAN_BEACON_FRAME_T) NULL; -+/* P_APPEND_VAR_IE_ENTRY_T prAppendIeTable = (P_APPEND_VAR_IE_ENTRY_T)NULL; */ -+ -+ do { -+ -+ ASSERT_BREAK((prAdapter != NULL) && (prBssInfo != NULL) && (prMsduInfo != NULL)); -+ -+/* txBcnIETable */ -+ -+/* txProbeRspIETable */ -+ -+ prBcnFrame = (P_WLAN_BEACON_FRAME_T) prMsduInfo->prPacket; -+ -+ return nicUpdateBeaconIETemplate(prAdapter, -+ IE_UPD_METHOD_UPDATE_ALL, -+ NETWORK_TYPE_P2P_INDEX, -+ prBssInfo->u2CapInfo, -+ (PUINT_8) prBcnFrame->aucInfoElem, -+ prMsduInfo->u2FrameLength - OFFSET_OF(WLAN_BEACON_FRAME_T, -+ aucInfoElem)); -+ -+ } while (FALSE); -+ -+ return rWlanStatus; -+} /* p2pFuncGenerateBeaconProbeRsp */ -+ -+WLAN_STATUS -+p2pFuncComposeBeaconProbeRspTemplate(IN P_ADAPTER_T prAdapter, -+ IN PUINT_8 pucBcnBuffer, -+ IN UINT_32 u4BcnBufLen, -+ IN BOOLEAN fgIsProbeRsp, -+ IN P_P2P_PROBE_RSP_UPDATE_INFO_T prP2pProbeRspInfo, IN BOOLEAN fgSynToFW) -+{ -+ WLAN_STATUS rWlanStatus = WLAN_STATUS_SUCCESS; -+ P_MSDU_INFO_T prMsduInfo = (P_MSDU_INFO_T) NULL; -+ P_WLAN_MAC_HEADER_T prWlanBcnFrame = (P_WLAN_MAC_HEADER_T) NULL; -+ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; -+ -+ PUINT_8 pucBuffer = (PUINT_8) NULL; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (pucBcnBuffer != NULL)); -+ -+ prWlanBcnFrame = (P_WLAN_MAC_HEADER_T) pucBcnBuffer; -+ -+ if ((prWlanBcnFrame->u2FrameCtrl != MAC_FRAME_BEACON) && (!fgIsProbeRsp)) { -+ rWlanStatus = WLAN_STATUS_INVALID_DATA; -+ break; -+ } -+ -+ else if (prWlanBcnFrame->u2FrameCtrl != MAC_FRAME_PROBE_RSP) { -+ rWlanStatus = WLAN_STATUS_INVALID_DATA; -+ break; -+ } -+ -+ if (fgIsProbeRsp) { -+ ASSERT_BREAK(prP2pProbeRspInfo != NULL); -+ -+ if (prP2pProbeRspInfo->prProbeRspMsduTemplate) -+ cnmMgtPktFree(prAdapter, prP2pProbeRspInfo->prProbeRspMsduTemplate); -+ -+ prP2pProbeRspInfo->prProbeRspMsduTemplate = cnmMgtPktAlloc(prAdapter, u4BcnBufLen); -+ -+ prMsduInfo = prP2pProbeRspInfo->prProbeRspMsduTemplate; -+ -+ prMsduInfo->eSrc = TX_PACKET_MGMT; -+ prMsduInfo->ucStaRecIndex = 0xFF; -+ prMsduInfo->ucNetworkType = NETWORK_TYPE_P2P_INDEX; -+ -+ } else { -+ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); -+ prMsduInfo = prP2pBssInfo->prBeacon; -+ -+ if (prMsduInfo == NULL) { -+ rWlanStatus = WLAN_STATUS_FAILURE; -+ break; -+ } -+ -+ if (u4BcnBufLen > (OFFSET_OF(WLAN_BEACON_FRAME_T, aucInfoElem[0]) + MAX_IE_LENGTH)) { -+ /* Unexpected error, buffer overflow. */ -+ ASSERT(FALSE); -+ break; -+ } -+ -+ } -+ -+ pucBuffer = (PUINT_8) ((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD); -+ -+ kalMemCopy(pucBuffer, pucBcnBuffer, u4BcnBufLen); -+ -+ prMsduInfo->fgIs802_11 = TRUE; -+ prMsduInfo->u2FrameLength = (UINT_16) u4BcnBufLen; -+ -+ if (fgSynToFW && prP2pBssInfo) -+ rWlanStatus = p2pFuncGenerateBeaconProbeRsp(prAdapter, prP2pBssInfo, prMsduInfo, fgIsProbeRsp); -+ -+ } while (FALSE); -+ -+ return rWlanStatus; -+ -+} /* p2pFuncComposeBeaconTemplate */ -+ -+#if CFG_SUPPORT_WFD -+WLAN_STATUS wfdAdjustResource(IN P_ADAPTER_T prAdapter, IN BOOLEAN fgEnable) -+{ -+#if 1 -+ /* The API shall be called in tx_thread */ -+ P_QUE_MGT_T prQM = &prAdapter->rQM; -+ -+ DBGLOG(P2P, INFO, "wfdAdjustResource %d\n", fgEnable); -+ if (fgEnable) { -+ prQM->au4MinReservedTcResource[TC2_INDEX] = QM_GUARANTEED_TC2_RESOURCE; -+ if (QM_GUARANTEED_TC0_RESOURCE > 2) { -+ prQM->au4GuaranteedTcResource[TC0_INDEX] = QM_GUARANTEED_TC0_RESOURCE - 2; -+ prQM->au4GuaranteedTcResource[TC2_INDEX] += 2; -+ } -+ if (QM_GUARANTEED_TC1_RESOURCE > 2) { -+ prQM->au4GuaranteedTcResource[TC1_INDEX] = QM_GUARANTEED_TC1_RESOURCE - 2; -+ prQM->au4GuaranteedTcResource[TC2_INDEX] += 2; -+ } -+ } else { -+ prQM->au4MinReservedTcResource[TC2_INDEX] = QM_MIN_RESERVED_TC2_RESOURCE; -+ prQM->au4GuaranteedTcResource[TC0_INDEX] = QM_GUARANTEED_TC0_RESOURCE; -+ prQM->au4GuaranteedTcResource[TC1_INDEX] = QM_GUARANTEED_TC1_RESOURCE; -+ prQM->au4GuaranteedTcResource[TC2_INDEX] = QM_GUARANTEED_TC2_RESOURCE; -+ } -+#endif -+ return WLAN_STATUS_SUCCESS; -+} -+ -+WLAN_STATUS wfdAdjustThread(IN P_ADAPTER_T prAdapter, IN BOOLEAN fgEnable) -+{ -+#define WFD_TX_THREAD_PRIORITY 70 -+ DBGLOG(P2P, INFO, "wfdAdjustResource %d\n", fgEnable); -+ if (prAdapter->prGlueInfo->main_thread != NULL) { -+ if (fgEnable) { -+#ifdef LINUX -+ /* TODO the change schedule API shall be provided by OS glue layer */ -+ /* Or the API shall be put in os glue layer */ -+ struct sched_param param = {.sched_priority = WFD_TX_THREAD_PRIORITY }; -+ -+ sched_setscheduler(prAdapter->prGlueInfo->main_thread, SCHED_RR, ¶m); -+#endif -+ } else { -+#ifdef LINUX -+ /* TODO the change schedule API shall be provided by OS glue layer */ -+ struct sched_param param = {.sched_priority = 0 }; -+ -+ sched_setscheduler(prAdapter->prGlueInfo->main_thread, SCHED_NORMAL, ¶m); -+#endif -+ } -+ } else { -+ -+ DBGLOG(P2P, WARN, "main_thread is null, please check if the wlanRemove is called in advance\n"); -+ } -+ return WLAN_STATUS_SUCCESS; -+} -+ -+#endif /* CFG_SUPPORT_WFD */ -+ -+WLAN_STATUS wfdChangeMediaState(IN P_ADAPTER_T prAdapter, -+ IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx, ENUM_PARAM_MEDIA_STATE_T eConnectionState) -+{ -+#if CFG_SUPPORT_WFD -+ P_WFD_CFG_SETTINGS_T prWfdCfgSettings = (P_WFD_CFG_SETTINGS_T) NULL; -+ -+ if (prAdapter->fgIsP2PRegistered == FALSE) -+ return WLAN_STATUS_SUCCESS; -+ prWfdCfgSettings = &prAdapter->rWifiVar.prP2pFsmInfo->rWfdConfigureSettings; -+ -+ if ((prWfdCfgSettings->ucWfdEnable) && ((prWfdCfgSettings->u4WfdFlag & WFD_FLAGS_DEV_INFO_VALID))) { -+ -+ if (prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX].eConnectionState == -+ PARAM_MEDIA_STATE_CONNECTED) { -+ wfdAdjustResource(prAdapter, TRUE); -+ wfdAdjustThread(prAdapter, TRUE); -+ } else { -+ wfdAdjustResource(prAdapter, FALSE); -+ wfdAdjustThread(prAdapter, FALSE); -+ } -+ -+ } -+#endif -+ return WLAN_STATUS_SUCCESS; -+} -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_ie.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_ie.c -new file mode 100644 -index 000000000000..991861f73608 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_ie.c -@@ -0,0 +1,612 @@ -+#include "p2p_precomp.h" -+ -+#if CFG_SUPPORT_WFD -+#if CFG_SUPPORT_WFD_COMPOSE_IE -+#if 0 -+APPEND_VAR_ATTRI_ENTRY_T txProbeRspWFDAttributesTable[] = { -+ {(WFD_ATTRI_HDR_LEN + WFD_ATTRI_MAX_LEN_DEV_INFO), NULL, wfdFuncAppendAttriDevInfo} /* 0 */ -+ , {(WFD_ATTRI_HDR_LEN + WFD_ATTRI_MAX_LEN_ASSOC_BSSID), NULL, wfdFuncAppendAttriAssocBssid} /* 1 */ -+ , {(WFD_ATTRI_HDR_LEN + WFD_ATTRI_MAX_LEN_COUPLED_SINK_INFO), NULL, wfdFuncAppendAttriCoupledSinkInfo} /* 6 */ -+ , {(WFD_ATTRI_HDR_LEN + WFD_ATTRI_MAX_LEN_EXT_CAPABILITY), NULL, wfdFuncAppendAttriExtCapability} /* 7 */ -+ , {0, wfdFuncCalculateAttriLenSessionInfo, wfdFuncAppendAttriSessionInfo} /* 9 */ -+}; -+ -+APPEND_VAR_ATTRI_ENTRY_T txBeaconWFDAttributesTable[] = { -+ {(WFD_ATTRI_HDR_LEN + WFD_ATTRI_MAX_LEN_DEV_INFO), NULL, wfdFuncAppendAttriDevInfo} /* 0 */ -+ , {(WFD_ATTRI_HDR_LEN + WFD_ATTRI_MAX_LEN_ASSOC_BSSID), NULL, wfdFuncAppendAttriAssocBssid} /* 1 */ -+ , {(WFD_ATTRI_HDR_LEN + WFD_ATTRI_MAX_LEN_COUPLED_SINK_INFO), NULL, wfdFuncAppendAttriCoupledSinkInfo} /* 6 */ -+}; -+ -+APPEND_VAR_ATTRI_ENTRY_T txAssocReqWFDAttributesTable[] = { -+ {(WFD_ATTRI_HDR_LEN + WFD_ATTRI_MAX_LEN_DEV_INFO), NULL, wfdFuncAppendAttriDevInfo} /* 0 */ -+ , {(WFD_ATTRI_HDR_LEN + WFD_ATTRI_MAX_LEN_ASSOC_BSSID), NULL, wfdFuncAppendAttriAssocBssid} /* 1 */ -+ , {(WFD_ATTRI_HDR_LEN + WFD_ATTRI_MAX_LEN_COUPLED_SINK_INFO), NULL, wfdFuncAppendAttriCoupledSinkInfo} /* 6 */ -+}; -+#endif -+ -+APPEND_VAR_ATTRI_ENTRY_T txAssocRspWFDAttributesTable[] = { -+ {(WFD_ATTRI_HDR_LEN + WFD_ATTRI_MAX_LEN_DEV_INFO), NULL, wfdFuncAppendAttriDevInfo} /* 0 */ -+ , {(WFD_ATTRI_HDR_LEN + WFD_ATTRI_MAX_LEN_ASSOC_BSSID), NULL, wfdFuncAppendAttriAssocBssid} /* 1 */ -+ , {(WFD_ATTRI_HDR_LEN + WFD_ATTRI_MAX_LEN_COUPLED_SINK_INFO), NULL, wfdFuncAppendAttriCoupledSinkInfo} /* 6 */ -+ , {0, wfdFuncCalculateAttriLenSessionInfo, wfdFuncAppendAttriSessionInfo} /* 9 */ -+ -+}; -+ -+#endif -+ -+UINT_32 -+p2pCalculate_IEForAssocReq(IN P_ADAPTER_T prAdapter, -+ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec) -+{ -+ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; -+ P_P2P_CONNECTION_REQ_INFO_T prConnReqInfo = (P_P2P_CONNECTION_REQ_INFO_T) NULL; -+ UINT_32 u4RetValue = 0; -+ -+ do { -+ ASSERT_BREAK((eNetTypeIndex == NETWORK_TYPE_P2P_INDEX) && (prAdapter != NULL)); -+ -+ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; -+ -+ prConnReqInfo = &(prP2pFsmInfo->rConnReqInfo); -+ -+ u4RetValue = prConnReqInfo->u4BufLength; -+ -+ /* ADD HT Capability */ -+ u4RetValue += (ELEM_HDR_LEN + ELEM_MAX_LEN_HT_CAP); -+ -+ /* ADD WMM Information Element */ -+ u4RetValue += (ELEM_HDR_LEN + ELEM_MAX_LEN_WMM_INFO); -+ -+ } while (FALSE); -+ -+ return u4RetValue; -+} /* p2pCalculate_IEForAssocReq */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is used to generate P2P IE for Beacon frame. -+* -+* @param[in] prMsduInfo Pointer to the composed MSDU_INFO_T. -+* -+* @return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID p2pGenerate_IEForAssocReq(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo) -+{ -+ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; -+ P_P2P_CONNECTION_REQ_INFO_T prConnReqInfo = (P_P2P_CONNECTION_REQ_INFO_T) NULL; -+ PUINT_8 pucIEBuf = (PUINT_8) NULL; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prMsduInfo != NULL)); -+ -+ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; -+ -+ prConnReqInfo = &(prP2pFsmInfo->rConnReqInfo); -+ -+ pucIEBuf = (PUINT_8) ((ULONG) prMsduInfo->prPacket + (UINT_32) prMsduInfo->u2FrameLength); -+ -+ kalMemCopy(pucIEBuf, prConnReqInfo->aucIEBuf, prConnReqInfo->u4BufLength); -+ -+ prMsduInfo->u2FrameLength += prConnReqInfo->u4BufLength; -+ -+ rlmReqGenerateHtCapIE(prAdapter, prMsduInfo); -+ mqmGenerateWmmInfoIE(prAdapter, prMsduInfo); -+ -+ } while (FALSE); -+ -+ return; -+ -+} /* p2pGenerate_IEForAssocReq */ -+ -+UINT_32 -+wfdFuncAppendAttriDevInfo(IN P_ADAPTER_T prAdapter, -+ IN BOOLEAN fgIsAssocFrame, IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize) -+{ -+ UINT_32 u4AttriLen = 0; -+ PUINT_8 pucBuffer = NULL; -+ P_WFD_DEVICE_INFORMATION_IE_T prWfdDevInfo = (P_WFD_DEVICE_INFORMATION_IE_T) NULL; -+ P_WFD_CFG_SETTINGS_T prWfdCfgSettings = (P_WFD_CFG_SETTINGS_T) NULL; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (pucBuf != NULL) && (pu2Offset != NULL)); -+ -+ prWfdCfgSettings = &(prAdapter->rWifiVar.prP2pFsmInfo->rWfdConfigureSettings); -+ -+ ASSERT_BREAK((prWfdCfgSettings != NULL)); -+ -+ if ((prWfdCfgSettings->ucWfdEnable == 0) || -+ ((prWfdCfgSettings->u4WfdFlag & WFD_FLAGS_DEV_INFO_VALID) == 0)) { -+ break; -+ } -+ -+ pucBuffer = (PUINT_8) ((ULONG) pucBuf + (UINT_32) (*pu2Offset)); -+ -+ ASSERT_BREAK(pucBuffer != NULL); -+ -+ prWfdDevInfo = (P_WFD_DEVICE_INFORMATION_IE_T) pucBuffer; -+ -+ prWfdDevInfo->ucElemID = WFD_ATTRI_ID_DEV_INFO; -+ -+ WLAN_SET_FIELD_BE16(&prWfdDevInfo->u2WfdDevInfo, prWfdCfgSettings->u2WfdDevInfo); -+ -+ WLAN_SET_FIELD_BE16(&prWfdDevInfo->u2SessionMgmtCtrlPort, prWfdCfgSettings->u2WfdControlPort); -+ -+ WLAN_SET_FIELD_BE16(&prWfdDevInfo->u2WfdDevMaxSpeed, prWfdCfgSettings->u2WfdMaximumTp); -+ -+ WLAN_SET_FIELD_BE16(&prWfdDevInfo->u2Length, WFD_ATTRI_MAX_LEN_DEV_INFO); -+ -+ u4AttriLen = WFD_ATTRI_MAX_LEN_DEV_INFO + WFD_ATTRI_HDR_LEN; -+ -+ } while (FALSE); -+ -+ (*pu2Offset) += (UINT_16) u4AttriLen; -+ -+ return u4AttriLen; -+} -+ -+/* wfdFuncAppendAttriDevInfo */ -+ -+UINT_32 -+wfdFuncAppendAttriAssocBssid(IN P_ADAPTER_T prAdapter, -+ IN BOOLEAN fgIsAssocFrame, IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize) -+{ -+ UINT_32 u4AttriLen = 0; -+ PUINT_8 pucBuffer = NULL; -+ P_WFD_ASSOCIATED_BSSID_IE_T prWfdAssocBssid = (P_WFD_ASSOCIATED_BSSID_IE_T) NULL; -+ P_WFD_CFG_SETTINGS_T prWfdCfgSettings = (P_WFD_CFG_SETTINGS_T) NULL; -+ P_BSS_INFO_T prAisBssInfo = (P_BSS_INFO_T) NULL; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (pucBuf != NULL) && (pu2Offset != NULL)); -+ -+ prWfdCfgSettings = &(prAdapter->rWifiVar.prP2pFsmInfo->rWfdConfigureSettings); -+ -+ ASSERT_BREAK((prWfdCfgSettings != NULL)); -+ -+ if (prWfdCfgSettings->ucWfdEnable == 0) -+ break; -+ -+ /* AIS network. */ -+ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ -+ if ((!IS_NET_ACTIVE(prAdapter, NETWORK_TYPE_AIS_INDEX)) || -+ (prAisBssInfo->eConnectionState != PARAM_MEDIA_STATE_CONNECTED)) { -+ break; -+ } -+ -+ pucBuffer = (PUINT_8) ((ULONG) pucBuf + (UINT_32) (*pu2Offset)); -+ -+ ASSERT_BREAK(pucBuffer != NULL); -+ -+ prWfdAssocBssid = (P_WFD_ASSOCIATED_BSSID_IE_T) pucBuffer; -+ -+ prWfdAssocBssid->ucElemID = WFD_ATTRI_ID_ASSOC_BSSID; -+ -+ WLAN_SET_FIELD_BE16(&prWfdAssocBssid->u2Length, WFD_ATTRI_MAX_LEN_ASSOC_BSSID); -+ -+ COPY_MAC_ADDR(prWfdAssocBssid->aucAssocBssid, prAisBssInfo->aucBSSID); -+ -+ u4AttriLen = WFD_ATTRI_MAX_LEN_ASSOC_BSSID + WFD_ATTRI_HDR_LEN; -+ -+ } while (FALSE); -+ -+ (*pu2Offset) += (UINT_16) u4AttriLen; -+ -+ return u4AttriLen; -+} -+ -+/* wfdFuncAppendAttriAssocBssid */ -+ -+UINT_32 -+wfdFuncAppendAttriCoupledSinkInfo(IN P_ADAPTER_T prAdapter, -+ IN BOOLEAN fgIsAssocFrame, -+ IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize) -+{ -+ UINT_32 u4AttriLen = 0; -+ PUINT_8 pucBuffer = NULL; -+ P_WFD_COUPLE_SINK_INFORMATION_IE_T prWfdCoupleSinkInfo = (P_WFD_COUPLE_SINK_INFORMATION_IE_T) NULL; -+ P_WFD_CFG_SETTINGS_T prWfdCfgSettings = (P_WFD_CFG_SETTINGS_T) NULL; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (pucBuf != NULL) && (pu2Offset != NULL)); -+ -+ prWfdCfgSettings = &(prAdapter->rWifiVar.prP2pFsmInfo->rWfdConfigureSettings); -+ -+ ASSERT_BREAK((prWfdCfgSettings != NULL)); -+ -+ if ((prWfdCfgSettings->ucWfdEnable == 0) || -+ ((prWfdCfgSettings->u4WfdFlag & WFD_FLAGS_SINK_INFO_VALID) == 0)) { -+ break; -+ } -+ -+ pucBuffer = (PUINT_8) ((ULONG) pucBuf + (UINT_32) (*pu2Offset)); -+ -+ ASSERT_BREAK(pucBuffer != NULL); -+ -+ prWfdCoupleSinkInfo = (P_WFD_COUPLE_SINK_INFORMATION_IE_T) pucBuffer; -+ -+ prWfdCoupleSinkInfo->ucElemID = WFD_ATTRI_ID_COUPLED_SINK_INFO; -+ -+ WLAN_SET_FIELD_BE16(&prWfdCoupleSinkInfo->u2Length, WFD_ATTRI_MAX_LEN_COUPLED_SINK_INFO); -+ -+ COPY_MAC_ADDR(prWfdCoupleSinkInfo->aucCoupleSinkMac, prWfdCfgSettings->aucWfdCoupleSinkAddress); -+ -+ prWfdCoupleSinkInfo->ucCoupleSinkStatusBp = prWfdCfgSettings->ucWfdCoupleSinkStatus; -+ -+ u4AttriLen = WFD_ATTRI_MAX_LEN_COUPLED_SINK_INFO + WFD_ATTRI_HDR_LEN; -+ -+ } while (FALSE); -+ -+ (*pu2Offset) += (UINT_16) u4AttriLen; -+ -+ return u4AttriLen; -+} -+ -+/* wfdFuncAppendAttriCoupledSinkInfo */ -+ -+UINT_32 -+wfdFuncAppendAttriExtCapability(IN P_ADAPTER_T prAdapter, -+ IN BOOLEAN fgIsAssocFrame, -+ IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize) -+{ -+ UINT_32 u4AttriLen = 0; -+ PUINT_8 pucBuffer = NULL; -+ P_WFD_EXTENDED_CAPABILITY_IE_T prWfdExtCapability = (P_WFD_EXTENDED_CAPABILITY_IE_T) NULL; -+ P_WFD_CFG_SETTINGS_T prWfdCfgSettings = (P_WFD_CFG_SETTINGS_T) NULL; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (pucBuf != NULL) && (pu2Offset != NULL)); -+ -+ prWfdCfgSettings = &(prAdapter->rWifiVar.prP2pFsmInfo->rWfdConfigureSettings); -+ -+ ASSERT_BREAK((prWfdCfgSettings != NULL)); -+ -+ if ((prWfdCfgSettings->ucWfdEnable == 0) || -+ ((prWfdCfgSettings->u4WfdFlag & WFD_FLAGS_EXT_CAPABILITY_VALID) == 0)) { -+ break; -+ } -+ -+ pucBuffer = (PUINT_8) ((ULONG) pucBuf + (UINT_32) (*pu2Offset)); -+ -+ ASSERT_BREAK(pucBuffer != NULL); -+ -+ prWfdExtCapability = (P_WFD_EXTENDED_CAPABILITY_IE_T) pucBuffer; -+ -+ prWfdExtCapability->ucElemID = WFD_ATTRI_ID_EXT_CAPABILITY; -+ -+ WLAN_SET_FIELD_BE16(&prWfdExtCapability->u2Length, WFD_ATTRI_MAX_LEN_EXT_CAPABILITY); -+ -+ WLAN_SET_FIELD_BE16(&prWfdExtCapability->u2WfdExtCapabilityBp, prWfdCfgSettings->u2WfdExtendCap); -+ -+ u4AttriLen = WFD_ATTRI_MAX_LEN_EXT_CAPABILITY + WFD_ATTRI_HDR_LEN; -+ -+ } while (FALSE); -+ -+ (*pu2Offset) += (UINT_16) u4AttriLen; -+ -+ return u4AttriLen; -+} -+ -+/* wfdFuncAppendAttriExtCapability */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is used to calculate length of Channel List Attribute -+* -+* @param[in] prStaRec Pointer to the STA_RECORD_T -+* -+* @return The length of Attribute added -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT_32 wfdFuncCalculateAttriLenSessionInfo(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec) -+{ -+ UINT_16 u2AttriLen = 0; -+ P_WFD_CFG_SETTINGS_T prWfdCfgSettings = (P_WFD_CFG_SETTINGS_T) NULL; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prStaRec != NULL)); -+ -+ prWfdCfgSettings = &(prAdapter->rWifiVar.prP2pFsmInfo->rWfdConfigureSettings); -+ -+ if (prWfdCfgSettings->ucWfdEnable == 0) -+ break; -+ -+ u2AttriLen = prWfdCfgSettings->u2WfdSessionInformationIELen + WFD_ATTRI_HDR_LEN; -+ -+ } while (FALSE); -+ -+ return (UINT_32) u2AttriLen; -+ -+} /* wfdFuncCalculateAttriLenSessionInfo */ -+ -+UINT_32 -+wfdFuncAppendAttriSessionInfo(IN P_ADAPTER_T prAdapter, -+ IN BOOLEAN fgIsAssocFrame, IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize) -+{ -+ UINT_32 u4AttriLen = 0; -+ PUINT_8 pucBuffer = NULL; -+ P_WFD_SESSION_INFORMATION_IE_T prWfdSessionInfo = (P_WFD_SESSION_INFORMATION_IE_T) NULL; -+ P_WFD_CFG_SETTINGS_T prWfdCfgSettings = (P_WFD_CFG_SETTINGS_T) NULL; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (pucBuf != NULL) && (pu2Offset != NULL)); -+ -+ prWfdCfgSettings = &(prAdapter->rWifiVar.prP2pFsmInfo->rWfdConfigureSettings); -+ -+ ASSERT_BREAK((prWfdCfgSettings != NULL)); -+ -+ if ((prWfdCfgSettings->ucWfdEnable == 0) || (prWfdCfgSettings->u2WfdSessionInformationIELen == 0)) -+ break; -+ -+ pucBuffer = (PUINT_8) ((ULONG) pucBuf + (UINT_32) (*pu2Offset)); -+ -+ ASSERT_BREAK(pucBuffer != NULL); -+ -+ prWfdSessionInfo = (P_WFD_SESSION_INFORMATION_IE_T) pucBuffer; -+ -+ prWfdSessionInfo->ucElemID = WFD_ATTRI_ID_SESSION_INFO; -+ -+ /* TODO: Check endian issue? */ -+ kalMemCopy(prWfdSessionInfo->pucWfdDevInfoDesc, prWfdCfgSettings->aucWfdSessionInformationIE, -+ prWfdCfgSettings->u2WfdSessionInformationIELen); -+ -+ WLAN_SET_FIELD_16(&prWfdSessionInfo->u2Length, prWfdCfgSettings->u2WfdSessionInformationIELen); -+ -+ u4AttriLen = prWfdCfgSettings->u2WfdSessionInformationIELen + WFD_ATTRI_HDR_LEN; -+ -+ } while (FALSE); -+ -+ (*pu2Offset) += (UINT_16) u4AttriLen; -+ -+ return u4AttriLen; -+} -+ -+/* wfdFuncAppendAttriSessionInfo */ -+ -+#if CFG_SUPPORT_WFD_COMPOSE_IE -+VOID -+wfdFuncGenerateWfd_IE(IN P_ADAPTER_T prAdapter, -+ IN BOOLEAN fgIsAssocFrame, -+ IN PUINT_16 pu2Offset, -+ IN PUINT_8 pucBuf, -+ IN UINT_16 u2BufSize, -+ IN APPEND_VAR_ATTRI_ENTRY_T arAppendAttriTable[], IN UINT_32 u4AttriTableSize) -+{ -+ -+ PUINT_8 pucBuffer = (PUINT_8) NULL; -+ P_IE_WFD_T prIeWFD = (P_IE_WFD_T) NULL; -+ UINT_32 u4OverallAttriLen; -+ UINT_32 u4AttriLen; -+ UINT_8 aucWfaOui[] = VENDOR_OUI_WFA_SPECIFIC; -+ UINT_8 aucTempBuffer[P2P_MAXIMUM_ATTRIBUTE_LEN]; -+ UINT_32 i; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (pucBuf != NULL)); -+ -+ pucBuffer = (PUINT_8) ((ULONG) pucBuf + (*pu2Offset)); -+ -+ ASSERT_BREAK(pucBuffer != NULL); -+ -+ /* Check buffer length is still enough. */ -+ ASSERT_BREAK((u2BufSize - (*pu2Offset)) >= WFD_IE_OUI_HDR); -+ -+ prIeWFD = (P_IE_WFD_T) pucBuffer; -+ -+ prIeWFD->ucId = ELEM_ID_WFD; -+ -+ prIeWFD->aucOui[0] = aucWfaOui[0]; -+ prIeWFD->aucOui[1] = aucWfaOui[1]; -+ prIeWFD->aucOui[2] = aucWfaOui[2]; -+ prIeWFD->ucOuiType = VENDOR_OUI_TYPE_WFD; -+ -+ (*pu2Offset) += WFD_IE_OUI_HDR; -+ -+ /* Overall length of all Attributes */ -+ u4OverallAttriLen = 0; -+ -+ for (i = 0; i < u4AttriTableSize; i++) { -+ -+ if (arAppendAttriTable[i].pfnAppendAttri) { -+ u4AttriLen = -+ arAppendAttriTable[i].pfnAppendAttri(prAdapter, fgIsAssocFrame, pu2Offset, pucBuf, -+ u2BufSize); -+ -+ u4OverallAttriLen += u4AttriLen; -+ -+ if (u4OverallAttriLen > P2P_MAXIMUM_ATTRIBUTE_LEN) { -+ u4OverallAttriLen -= P2P_MAXIMUM_ATTRIBUTE_LEN; -+ -+ prIeWFD->ucLength = (VENDOR_OUI_TYPE_LEN + P2P_MAXIMUM_ATTRIBUTE_LEN); -+ -+ pucBuffer = -+ (PUINT_8) ((ULONG) prIeWFD + (WFD_IE_OUI_HDR + P2P_MAXIMUM_ATTRIBUTE_LEN)); -+ -+ prIeWFD = -+ (P_IE_WFD_T) ((ULONG) prIeWFD + -+ (WFD_IE_OUI_HDR + P2P_MAXIMUM_ATTRIBUTE_LEN)); -+ -+ kalMemCopy(aucTempBuffer, pucBuffer, u4OverallAttriLen); -+ -+ prIeWFD->ucId = ELEM_ID_WFD; -+ -+ prIeWFD->aucOui[0] = aucWfaOui[0]; -+ prIeWFD->aucOui[1] = aucWfaOui[1]; -+ prIeWFD->aucOui[2] = aucWfaOui[2]; -+ prIeWFD->ucOuiType = VENDOR_OUI_TYPE_WFD; -+ -+ kalMemCopy(prIeWFD->aucWFDAttributes, aucTempBuffer, u4OverallAttriLen); -+ (*pu2Offset) += WFD_IE_OUI_HDR; -+ } -+ -+ } -+ -+ } -+ -+ prIeWFD->ucLength = (UINT_8) (VENDOR_OUI_TYPE_LEN + u4OverallAttriLen); -+ -+ } while (FALSE); -+ -+} /* wfdFuncGenerateWfd_IE */ -+ -+#endif /* CFG_SUPPORT_WFD_COMPOSE_IE */ -+ -+UINT_32 -+wfdFuncCalculateWfdIELenForAssocRsp(IN P_ADAPTER_T prAdapter, -+ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec) -+{ -+ -+#if CFG_SUPPORT_WFD_COMPOSE_IE -+ P_WFD_CFG_SETTINGS_T prWfdCfgSettings = (P_WFD_CFG_SETTINGS_T) NULL; -+ -+ prWfdCfgSettings = &(prAdapter->rWifiVar.prP2pFsmInfo->rWfdConfigureSettings); -+ -+ if (!IS_STA_P2P_TYPE(prStaRec) || (prWfdCfgSettings->ucWfdEnable == 0)) -+ return 0; -+ -+ return p2pFuncCalculateP2P_IELen(prAdapter, -+ eNetTypeIndex, -+ prStaRec, -+ txAssocRspWFDAttributesTable, -+ sizeof(txAssocRspWFDAttributesTable) / sizeof(APPEND_VAR_ATTRI_ENTRY_T)); -+ -+#else -+ return 0; -+#endif -+} /* wfdFuncCalculateWfdIELenForAssocRsp */ -+ -+VOID wfdFuncGenerateWfdIEForAssocRsp(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo) -+{ -+ -+#if CFG_SUPPORT_WFD_COMPOSE_IE -+ P_WFD_CFG_SETTINGS_T prWfdCfgSettings = (P_WFD_CFG_SETTINGS_T) NULL; -+ P_STA_RECORD_T prStaRec; -+ -+ do { -+ ASSERT_BREAK((prMsduInfo != NULL) && (prAdapter != NULL)); -+ -+ prWfdCfgSettings = &(prAdapter->rWifiVar.prP2pFsmInfo->rWfdConfigureSettings); -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); -+ -+ if (!prStaRec) { -+ ASSERT(FALSE); -+ } else if (IS_STA_P2P_TYPE(prStaRec)) { -+ -+ if (prWfdCfgSettings->ucWfdEnable == 0) -+ break; -+ if ((prWfdCfgSettings->u4WfdFlag & WFD_FLAGS_DEV_INFO_VALID) == 0) -+ break; -+ -+ wfdFuncGenerateWfd_IE(prAdapter, -+ FALSE, -+ &prMsduInfo->u2FrameLength, -+ prMsduInfo->prPacket, -+ 1500, -+ txAssocRspWFDAttributesTable, -+ sizeof(txAssocRspWFDAttributesTable) / sizeof(APPEND_VAR_ATTRI_ENTRY_T)); -+ } -+ } while (FALSE); -+ -+ return; -+#else -+ -+ return; -+#endif -+} /* wfdFuncGenerateWfdIEForAssocRsp */ -+ -+VOID p2pFuncComposeNoaAttribute(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo) -+{ -+ -+ P_IE_P2P_T prIeP2P; -+ P_P2P_ATTRI_NOA_T prNoaAttr = NULL; -+ P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo = NULL; -+ P_NOA_DESCRIPTOR_T prNoaDesc = NULL; -+ -+ UINT_8 aucWfaOui[] = VENDOR_OUI_WFA_SPECIFIC; -+ UINT_32 u4AttributeLen; -+ UINT_32 u4NumOfNoaDesc = 0; -+ UINT_32 i = 0; -+ /*P2P IE format */ -+ prIeP2P = (P_IE_P2P_T) ((ULONG) prMsduInfo->prPacket + (UINT_32) prMsduInfo->u2FrameLength); -+ prIeP2P->ucId = ELEM_ID_P2P; -+ prIeP2P->aucOui[0] = aucWfaOui[0]; -+ prIeP2P->aucOui[1] = aucWfaOui[1]; -+ prIeP2P->aucOui[2] = aucWfaOui[2]; -+ prIeP2P->ucOuiType = VENDOR_OUI_TYPE_P2P; -+ -+ prP2pSpecificBssInfo = prAdapter->rWifiVar.prP2pSpecificBssInfo; -+ /*P2P Attribute--NoA */ -+ prNoaAttr = (P_P2P_ATTRI_NOA_T) prIeP2P->aucP2PAttributes; -+ -+ prNoaAttr->ucId = P2P_ATTRI_ID_NOTICE_OF_ABSENCE; -+ prNoaAttr->ucIndex = prP2pSpecificBssInfo->ucNoAIndex; -+ /*OPP*/ if (prP2pSpecificBssInfo->fgEnableOppPS) { -+ prNoaAttr->ucCTWOppPSParam = P2P_CTW_OPPPS_PARAM_OPPPS_FIELD | -+ (prP2pSpecificBssInfo->u2CTWindow & P2P_CTW_OPPPS_PARAM_CTWINDOW_MASK); -+ } else { -+ prNoaAttr->ucCTWOppPSParam = 0; -+ } -+ /*NoA Description */ -+ DBGLOG(P2P, INFO, "Compose NoA count=%d.\n", prP2pSpecificBssInfo->ucNoATimingCount); -+ for (i = 0; i < prP2pSpecificBssInfo->ucNoATimingCount; i++) { -+ if (prP2pSpecificBssInfo->arNoATiming[i].fgIsInUse) { -+ -+ prNoaDesc = (P_NOA_DESCRIPTOR_T) &prNoaAttr->aucNoADesc[u4NumOfNoaDesc]; -+ -+ prNoaDesc->ucCountType = prP2pSpecificBssInfo->arNoATiming[i].ucCount; -+ prNoaDesc->u4Duration = prP2pSpecificBssInfo->arNoATiming[i].u4Duration; -+ prNoaDesc->u4Interval = prP2pSpecificBssInfo->arNoATiming[i].u4Interval; -+ prNoaDesc->u4StartTime = prP2pSpecificBssInfo->arNoATiming[i].u4StartTime; -+ -+ u4NumOfNoaDesc++; -+ } -+ } -+ -+ /* include "index" + "OppPs Params" + "NOA descriptors" */ -+ prNoaAttr->u2Length = 2 + u4NumOfNoaDesc * sizeof(NOA_DESCRIPTOR_T); -+ u4NumOfNoaDesc++; -+ -+ /* include "Attribute ID" + "Length" + "index" + "OppPs Params" + "NOA descriptors" */ -+ u4AttributeLen = P2P_ATTRI_HDR_LEN + prNoaAttr->u2Length; -+ -+ prIeP2P->ucLength = VENDOR_OUI_TYPE_LEN + u4AttributeLen; -+ prMsduInfo->u2FrameLength += (ELEM_HDR_LEN + prIeP2P->ucLength); -+ -+} -+ -+UINT_32 p2pFuncCalculateP2P_IE_NoA(IN P_ADAPTER_T prAdapter, IN UINT_32 ucBssIdx, IN P_STA_RECORD_T prStaRec) -+{ -+ P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo = NULL; -+ UINT_8 ucIdx; -+ UINT_32 u4NumOfNoaDesc = 0; -+ -+ if (p2pFuncIsAPMode(prAdapter->rWifiVar.prP2pFsmInfo)) -+ return 0; -+ -+ prP2pSpecificBssInfo = prAdapter->rWifiVar.prP2pSpecificBssInfo; -+ -+ for (ucIdx = 0; ucIdx < prP2pSpecificBssInfo->ucNoATimingCount; ucIdx++) { -+ if (prP2pSpecificBssInfo->arNoATiming[ucIdx].fgIsInUse) -+ u4NumOfNoaDesc++; -+ } -+ -+ /* include "index" + "OppPs Params" + "NOA descriptors" */ -+ /* include "Attribute ID" + "Length" + "index" + "OppPs Params" + "NOA descriptors" */ -+ -+ return P2P_ATTRI_LEN_NOTICE_OF_ABSENCE + (u4NumOfNoaDesc * sizeof(NOA_DESCRIPTOR_T)); -+} -+ -+VOID p2pFuncGenerateP2P_IE_NoA(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo) -+{ -+ if (p2pFuncIsAPMode(prAdapter->rWifiVar.prP2pFsmInfo)) { /* Hotspot */ -+ return; -+ } -+ -+ /* Compose NoA attribute */ -+ p2pFuncComposeNoaAttribute(prAdapter, -+ prMsduInfo /*prMsduInfo->ucBssIndex, prIeP2P->aucP2PAttributes, &u4AttributeLen */); -+ -+} -+ -+#endif -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_rlm.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_rlm.c -new file mode 100644 -index 000000000000..f25df82d9ca7 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_rlm.c -@@ -0,0 +1,905 @@ -+/* -+** Id: @(#) p2p_rlm.c@@ -+*/ -+ -+/*! \file "p2p_rlm.c" -+ \brief -+ -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+#include "precomp.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Init AP Bss -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rlmBssInitForAP(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo) -+{ -+ ENUM_BAND_T eBand; -+ UINT_8 ucChannel; -+ ENUM_CHNL_EXT_T eSCO; -+ -+ ASSERT(prAdapter); -+ ASSERT(prBssInfo); -+ -+ if (prBssInfo->eCurrentOPMode != OP_MODE_ACCESS_POINT) -+ return; -+ -+ /* Operation band, channel shall be ready before invoking this function. -+ * Bandwidth may be ready if other network is connected -+ */ -+ prBssInfo->fg40mBwAllowed = FALSE; -+ prBssInfo->fgAssoc40mBwAllowed = FALSE; -+ prBssInfo->eBssSCO = CHNL_EXT_SCN; -+ -+ if (RLM_AP_IS_BW_40_ALLOWED(prAdapter, prBssInfo)) { -+ /* In this case, the first BSS's SCO is 40MHz and known, so AP can -+ * apply 40MHz bandwidth, but the first BSS's SCO may be changed -+ * later if its Beacon lost timeout occurs -+ */ -+ if (cnmPreferredChannel(prAdapter, &eBand, &ucChannel, &eSCO) && -+ eSCO != CHNL_EXT_SCN && ucChannel == prBssInfo->ucPrimaryChannel && eBand == prBssInfo->eBand) { -+ prBssInfo->eBssSCO = eSCO; -+ } else if (cnmBss40mBwPermitted(prAdapter, prBssInfo->ucNetTypeIndex)) { -+ prBssInfo->eBssSCO = rlmDecideScoForAP(prAdapter, prBssInfo); -+ } -+ -+ if (prBssInfo->eBssSCO != CHNL_EXT_SCN) { -+ prBssInfo->fg40mBwAllowed = TRUE; -+ prBssInfo->fgAssoc40mBwAllowed = TRUE; -+ -+ prBssInfo->ucHtOpInfo1 = (UINT_8) -+ (((UINT_32) prBssInfo->eBssSCO) | HT_OP_INFO1_STA_CHNL_WIDTH); -+ -+ rlmUpdateBwByChListForAP(prAdapter, prBssInfo); -+ } -+ } -+ -+ DBGLOG(RLM, INFO, "WLAN AP SCO=%d\n", prBssInfo->eBssSCO); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief For probe response (GO, IBSS) and association response -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rlmRspGenerateObssScanIE(P_ADAPTER_T prAdapter, P_MSDU_INFO_T prMsduInfo) -+{ -+ P_BSS_INFO_T prBssInfo; -+ P_IE_OBSS_SCAN_PARAM_T prObssScanIe; -+ P_STA_RECORD_T prStaRec = (P_STA_RECORD_T) NULL; -+ -+ ASSERT(prAdapter); -+ ASSERT(prMsduInfo); -+ ASSERT(IS_NET_ACTIVE(prAdapter, prMsduInfo->ucNetworkType)); -+ -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); -+ -+ prBssInfo = &prAdapter->rWifiVar.arBssInfo[prMsduInfo->ucNetworkType]; -+ ASSERT(prBssInfo); -+ -+ if (RLM_NET_IS_11N(prBssInfo) && !RLM_NET_IS_BOW(prBssInfo) && -+ prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT && -+ (!prStaRec || (prStaRec->ucPhyTypeSet & PHY_TYPE_SET_802_11N)) && -+ prBssInfo->eBand == BAND_2G4 && prBssInfo->eBssSCO != CHNL_EXT_SCN) { -+ -+ prObssScanIe = (P_IE_OBSS_SCAN_PARAM_T) -+ (((PUINT_8) prMsduInfo->prPacket) + prMsduInfo->u2FrameLength); -+ -+ /* Add 20/40 BSS coexistence IE */ -+ prObssScanIe->ucId = ELEM_ID_OBSS_SCAN_PARAMS; -+ prObssScanIe->ucLength = sizeof(IE_OBSS_SCAN_PARAM_T) - ELEM_HDR_LEN; -+ -+ prObssScanIe->u2ScanPassiveDwell = dot11OBSSScanPassiveDwell; -+ prObssScanIe->u2ScanActiveDwell = dot11OBSSScanActiveDwell; -+ prObssScanIe->u2TriggerScanInterval = dot11BSSWidthTriggerScanInterval; -+ prObssScanIe->u2ScanPassiveTotalPerChnl = dot11OBSSScanPassiveTotalPerChannel; -+ prObssScanIe->u2ScanActiveTotalPerChnl = dot11OBSSScanActiveTotalPerChannel; -+ prObssScanIe->u2WidthTransDelayFactor = dot11BSSWidthChannelTransitionDelayFactor; -+ prObssScanIe->u2ScanActivityThres = dot11OBSSScanActivityThreshold; -+ -+ ASSERT(IE_SIZE(prObssScanIe) <= (ELEM_HDR_LEN + ELEM_MAX_LEN_OBSS_SCAN)); -+ -+ prMsduInfo->u2FrameLength += IE_SIZE(prObssScanIe); -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief P2P GO. -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN rlmUpdateBwByChListForAP(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo) -+{ -+ UINT_8 ucLevel; -+ BOOLEAN fgBwChange; -+ -+ ASSERT(prAdapter); -+ ASSERT(prBssInfo); -+ -+ fgBwChange = FALSE; -+ -+ if (prBssInfo->eBssSCO == CHNL_EXT_SCN) -+ return fgBwChange; -+ -+ ucLevel = rlmObssChnlLevel(prBssInfo, prBssInfo->eBand, prBssInfo->ucPrimaryChannel, prBssInfo->eBssSCO); -+ -+ if (ucLevel == CHNL_LEVEL0) { -+ /* Forced to 20MHz, so extended channel is SCN and STA width is zero */ -+ prBssInfo->fgObssActionForcedTo20M = TRUE; -+ -+ if (prBssInfo->ucHtOpInfo1 != (UINT_8) CHNL_EXT_SCN) { -+ prBssInfo->ucHtOpInfo1 = (UINT_8) CHNL_EXT_SCN; -+ fgBwChange = TRUE; -+ } -+ -+ cnmTimerStartTimer(prAdapter, &prBssInfo->rObssScanTimer, OBSS_20_40M_TIMEOUT * MSEC_PER_SEC); -+ } -+ -+ /* Clear up all channel lists */ -+ prBssInfo->auc2G_20mReqChnlList[0] = 0; -+ prBssInfo->auc2G_NonHtChnlList[0] = 0; -+ prBssInfo->auc2G_PriChnlList[0] = 0; -+ prBssInfo->auc2G_SecChnlList[0] = 0; -+ prBssInfo->auc5G_20mReqChnlList[0] = 0; -+ prBssInfo->auc5G_NonHtChnlList[0] = 0; -+ prBssInfo->auc5G_PriChnlList[0] = 0; -+ prBssInfo->auc5G_SecChnlList[0] = 0; -+ -+ return fgBwChange; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rlmProcessPublicAction(P_ADAPTER_T prAdapter, P_SW_RFB_T prSwRfb) -+{ -+ P_ACTION_20_40_COEXIST_FRAME prRxFrame; -+ P_IE_20_40_COEXIST_T prCoexist; -+ P_IE_INTOLERANT_CHNL_REPORT_T prChnlReport; -+ P_BSS_INFO_T prBssInfo; -+ P_STA_RECORD_T prStaRec; -+ PUINT_8 pucIE; -+ UINT_16 u2IELength, u2Offset; -+ UINT_8 i, j; -+ -+ ASSERT(prAdapter); -+ ASSERT(prSwRfb); -+ -+ prRxFrame = (P_ACTION_20_40_COEXIST_FRAME) prSwRfb->pvHeader; -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); -+ -+ if (prRxFrame->ucAction != ACTION_PUBLIC_20_40_COEXIST || -+ !prStaRec || prStaRec->ucStaState != STA_STATE_3 || -+ prSwRfb->u2PacketLen < (WLAN_MAC_MGMT_HEADER_LEN + 5) || -+ HIF_RX_HDR_GET_NETWORK_IDX(prSwRfb->prHifRxHdr) != NETWORK_TYPE_P2P_INDEX) { -+ return; -+ } -+ -+ prBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]; -+ ASSERT(prBssInfo); -+ -+ if (!IS_BSS_ACTIVE(prBssInfo) || -+ prBssInfo->eCurrentOPMode != OP_MODE_ACCESS_POINT || prBssInfo->eBssSCO == CHNL_EXT_SCN) { -+ return; -+ } -+ -+ prCoexist = &prRxFrame->rBssCoexist; -+ if (prCoexist->ucData & (BSS_COEXIST_40M_INTOLERANT | BSS_COEXIST_20M_REQ)) { -+ ASSERT(prBssInfo->auc2G_20mReqChnlList[0] <= CHNL_LIST_SZ_2G); -+ for (i = 1; i <= prBssInfo->auc2G_20mReqChnlList[0] && i <= CHNL_LIST_SZ_2G; i++) { -+ if (prBssInfo->auc2G_20mReqChnlList[i] == prBssInfo->ucPrimaryChannel) -+ break; -+ } -+ if ((i > prBssInfo->auc2G_20mReqChnlList[0]) && (i <= CHNL_LIST_SZ_2G)) { -+ prBssInfo->auc2G_20mReqChnlList[i] = prBssInfo->ucPrimaryChannel; -+ prBssInfo->auc2G_20mReqChnlList[0]++; -+ } -+ } -+ -+ /* Process intolerant channel report IE */ -+ pucIE = (PUINT_8) &prRxFrame->rChnlReport; -+ u2IELength = prSwRfb->u2PacketLen - (WLAN_MAC_MGMT_HEADER_LEN + 5); -+ -+ IE_FOR_EACH(pucIE, u2IELength, u2Offset) { -+ switch (IE_ID(pucIE)) { -+ case ELEM_ID_20_40_INTOLERANT_CHNL_REPORT: -+ prChnlReport = (P_IE_INTOLERANT_CHNL_REPORT_T) pucIE; -+ -+ if (prChnlReport->ucLength <= 1) -+ break; -+ -+ /* To do: process regulatory class. Now we assume 2.4G band */ -+ -+ for (j = 0; j < prChnlReport->ucLength - 1; j++) { -+ /* Update non-HT channel list */ -+ ASSERT(prBssInfo->auc2G_NonHtChnlList[0] <= CHNL_LIST_SZ_2G); -+ for (i = 1; i <= prBssInfo->auc2G_NonHtChnlList[0] && i <= CHNL_LIST_SZ_2G; i++) { -+ if (prBssInfo->auc2G_NonHtChnlList[i] == prChnlReport->aucChannelList[j]) -+ break; -+ } -+ if ((i > prBssInfo->auc2G_NonHtChnlList[0]) && (i <= CHNL_LIST_SZ_2G)) { -+ prBssInfo->auc2G_NonHtChnlList[i] = prChnlReport->aucChannelList[j]; -+ prBssInfo->auc2G_NonHtChnlList[0]++; -+ } -+ } -+ break; -+ -+ default: -+ break; -+ } -+ } /* end of IE_FOR_EACH */ -+ -+ if (rlmUpdateBwByChListForAP(prAdapter, prBssInfo)) { -+ bssUpdateBeaconContent(prAdapter, prBssInfo->ucNetTypeIndex); -+ rlmSyncOperationParams(prAdapter, prBssInfo); -+ } -+ -+ /* Check if OBSS scan exemption response should be sent */ -+ if (prCoexist->ucData & BSS_COEXIST_OBSS_SCAN_EXEMPTION_REQ) -+ rlmObssScanExemptionRsp(prAdapter, prBssInfo, prSwRfb); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rlmProcessHtAction(P_ADAPTER_T prAdapter, P_SW_RFB_T prSwRfb) -+{ -+ P_ACTION_NOTIFY_CHNL_WIDTH_FRAME prRxFrame; -+ P_STA_RECORD_T prStaRec; -+ -+ ASSERT(prAdapter); -+ ASSERT(prSwRfb); -+ -+ prRxFrame = (P_ACTION_NOTIFY_CHNL_WIDTH_FRAME) prSwRfb->pvHeader; -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); -+ -+ if (prRxFrame->ucAction != ACTION_HT_NOTIFY_CHANNEL_WIDTH || -+ !prStaRec || prStaRec->ucStaState != STA_STATE_3 || -+ prSwRfb->u2PacketLen < sizeof(ACTION_NOTIFY_CHNL_WIDTH_FRAME)) { -+ return; -+ } -+ -+ /* To do: depending regulation class 13 and 14 based on spec -+ * Note: (ucChannelWidth==1) shall restored back to original capability, -+ * not current setting to 40MHz BW here -+ */ -+ if (prRxFrame->ucChannelWidth == 0) -+ prStaRec->u2HtCapInfo &= ~HT_CAP_INFO_SUP_CHNL_WIDTH; -+ else if (prRxFrame->ucChannelWidth == 1) -+ prStaRec->u2HtCapInfo |= HT_CAP_INFO_SUP_CHNL_WIDTH; -+ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_3); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rlmHandleObssStatusEventPkt(P_ADAPTER_T prAdapter, P_EVENT_AP_OBSS_STATUS_T prObssStatus) -+{ -+ P_BSS_INFO_T prBssInfo; -+ -+ ASSERT(prAdapter); -+ ASSERT(prObssStatus); -+ ASSERT(prObssStatus->ucNetTypeIndex == NETWORK_TYPE_P2P_INDEX); -+ -+ prBssInfo = &prAdapter->rWifiVar.arBssInfo[prObssStatus->ucNetTypeIndex]; -+ ASSERT(prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT); -+ -+ prBssInfo->fgObssErpProtectMode = (BOOLEAN) prObssStatus->ucObssErpProtectMode; -+ prBssInfo->eObssHtProtectMode = (ENUM_HT_PROTECT_MODE_T) prObssStatus->ucObssHtProtectMode; -+ prBssInfo->eObssGfOperationMode = (ENUM_GF_MODE_T) prObssStatus->ucObssGfOperationMode; -+ prBssInfo->fgObssRifsOperationMode = (BOOLEAN) prObssStatus->ucObssRifsOperationMode; -+ prBssInfo->fgObssBeaconForcedTo20M = (BOOLEAN) prObssStatus->ucObssBeaconForcedTo20M; -+ -+ /* Check if Beacon content need to be updated */ -+ rlmUpdateParamsForAP(prAdapter, prBssInfo, TRUE); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief It is only for AP mode in NETWORK_TYPE_P2P_INDEX. -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rlmUpdateParamsForAP(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo, BOOLEAN fgUpdateBeacon) -+{ -+ P_LINK_T prStaList; -+ P_STA_RECORD_T prStaRec; -+ BOOLEAN fgErpProtectMode, fgSta40mIntolerant; -+ BOOLEAN fgUseShortPreamble, fgUseShortSlotTime; -+ ENUM_HT_PROTECT_MODE_T eHtProtectMode; -+ ENUM_GF_MODE_T eGfOperationMode; -+ UINT_8 ucHtOpInfo1; -+#if CFG_SUPPORT_HOTSPOT_OPTIMIZATION -+ P_GLUE_INFO_T prGlueInfo; -+#endif -+ -+ ASSERT(prAdapter); -+ ASSERT(prBssInfo); -+ -+ if (!IS_BSS_ACTIVE(prBssInfo) || prBssInfo->eCurrentOPMode != OP_MODE_ACCESS_POINT) -+ return; -+ -+ fgErpProtectMode = FALSE; -+ eHtProtectMode = HT_PROTECT_MODE_NONE; -+ eGfOperationMode = GF_MODE_NORMAL; -+ fgSta40mIntolerant = FALSE; -+ fgUseShortPreamble = prBssInfo->fgIsShortPreambleAllowed; -+ fgUseShortSlotTime = TRUE; -+ ucHtOpInfo1 = (UINT_8) CHNL_EXT_SCN; -+ -+ prStaList = &prBssInfo->rStaRecOfClientList; -+ -+ LINK_FOR_EACH_ENTRY(prStaRec, prStaList, rLinkEntry, STA_RECORD_T) { -+ /* ASSERT(prStaRec); */ -+ if (!prStaRec) { -+ DBGLOG(P2P, TRACE, "prStaRec is NULL in rlmUpdateParamsForAP()\n"); -+ break; -+ } -+ if (prStaRec->fgIsInUse && prStaRec->ucStaState == STA_STATE_3 && -+ prStaRec->ucNetTypeIndex == prBssInfo->ucNetTypeIndex) { -+ if (!(prStaRec->ucPhyTypeSet & (PHY_TYPE_SET_802_11GN | PHY_TYPE_SET_802_11A))) { -+ /* B-only mode, so mode 1 (ERP protection) */ -+ fgErpProtectMode = TRUE; -+ } -+ -+ if (!(prStaRec->ucPhyTypeSet & PHY_TYPE_SET_802_11N)) { -+ /* BG-only or A-only */ -+ eHtProtectMode = HT_PROTECT_MODE_NON_HT; -+ } else if (!(prStaRec->u2HtCapInfo & HT_CAP_INFO_SUP_CHNL_WIDTH)) { -+ /* 20MHz-only */ -+ /* -+ The HT Protection field may be set to 20 MHz protection -+ mode only if the following are true: -+ \A1X All STAs detected (by any means) in the primary channel -+ and all STAs detected (by any means) in the secondary -+ channel are HT STAs and all STAs that are members of -+ this BSS are HT STAs, and -+ \A1X This BSS is a 20/40 MHz BSS, and -+ \A1X There is at least one 20 MHz HT STA associated with this BSS. -+ */ -+ if (eHtProtectMode == HT_PROTECT_MODE_NONE && prBssInfo->fgAssoc40mBwAllowed) -+ eHtProtectMode = HT_PROTECT_MODE_20M; -+ } -+ -+ if (!(prStaRec->u2HtCapInfo & HT_CAP_INFO_HT_GF)) -+ eGfOperationMode = GF_MODE_PROTECT; -+ -+ if (!(prStaRec->u2CapInfo & CAP_INFO_SHORT_PREAMBLE)) -+ fgUseShortPreamble = FALSE; -+ -+ if (!(prStaRec->u2CapInfo & CAP_INFO_SHORT_SLOT_TIME)) -+ fgUseShortSlotTime = FALSE; -+ -+ if (prStaRec->u2HtCapInfo & HT_CAP_INFO_40M_INTOLERANT) -+ fgSta40mIntolerant = TRUE; -+ } -+ } /* end of LINK_FOR_EACH_ENTRY */ -+ -+ /* Check if HT operation IE about 20/40M bandwidth shall be updated */ -+ if (prBssInfo->eBssSCO != CHNL_EXT_SCN) { -+ if (/*!LINK_IS_EMPTY(prStaList) && */ !fgSta40mIntolerant && -+ !prBssInfo->fgObssActionForcedTo20M && !prBssInfo->fgObssBeaconForcedTo20M) { -+ -+ ucHtOpInfo1 = (UINT_8) -+ (((UINT_32) prBssInfo->eBssSCO) | HT_OP_INFO1_STA_CHNL_WIDTH); -+ } -+ } -+#if CFG_SUPPORT_HOTSPOT_OPTIMIZATION -+ prGlueInfo = prAdapter->prGlueInfo; -+ if (prGlueInfo->prP2PInfo->u4PsLevel & BITS(8, 15)) -+ fgErpProtectMode = TRUE; -+#endif -+ -+ /* Check if any new parameter may be updated */ -+ if (prBssInfo->fgErpProtectMode != fgErpProtectMode || -+ prBssInfo->eHtProtectMode != eHtProtectMode || -+ prBssInfo->eGfOperationMode != eGfOperationMode || -+ prBssInfo->ucHtOpInfo1 != ucHtOpInfo1 || -+ prBssInfo->fgUseShortPreamble != fgUseShortPreamble || -+ prBssInfo->fgUseShortSlotTime != fgUseShortSlotTime) { -+ -+ prBssInfo->fgErpProtectMode = fgErpProtectMode; -+ prBssInfo->eHtProtectMode = eHtProtectMode; -+ prBssInfo->eGfOperationMode = eGfOperationMode; -+ prBssInfo->ucHtOpInfo1 = ucHtOpInfo1; -+ prBssInfo->fgUseShortPreamble = fgUseShortPreamble; -+ prBssInfo->fgUseShortSlotTime = fgUseShortSlotTime; -+ -+ if (fgUseShortSlotTime) -+ prBssInfo->u2CapInfo |= CAP_INFO_SHORT_SLOT_TIME; -+ else -+ prBssInfo->u2CapInfo &= ~CAP_INFO_SHORT_SLOT_TIME; -+ -+ rlmSyncOperationParams(prAdapter, prBssInfo); -+ fgUpdateBeacon = TRUE; -+ } -+ -+ /* Update Beacon content if related IE content is changed */ -+ if (fgUpdateBeacon) -+ bssUpdateBeaconContent(prAdapter, prBssInfo->ucNetTypeIndex); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Initial the channel list from the domain information. -+* This function is called after P2P initial and Domain information changed. -+* Make sure the device is disconnected while changing domain information. -+* -+* \param[in] prAdapter Pointer of ADAPTER_T -+* -+* \return boolean value if probe response frame is -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rlmFuncInitialChannelList(IN P_ADAPTER_T prAdapter) -+{ -+ P_P2P_CONNECTION_SETTINGS_T prP2pConnSetting = (P_P2P_CONNECTION_SETTINGS_T) NULL; -+ P_DOMAIN_INFO_ENTRY prDomainInfoEntry = (P_DOMAIN_INFO_ENTRY) NULL; -+ P_DOMAIN_SUBBAND_INFO prDomainSubBand = (P_DOMAIN_SUBBAND_INFO) NULL; -+ P_CHANNEL_ENTRY_FIELD_T prChannelEntryField = (P_CHANNEL_ENTRY_FIELD_T) NULL; -+ UINT_32 u4Idx = 0, u4IdxII = 0; -+ UINT_8 ucBufferSize = P2P_MAX_SUPPORTED_CHANNEL_LIST_SIZE; -+#if 0 -+ UINT_8 ucSocialChnlSupport = 0, ucAutoChnl = 0; -+#endif -+ -+ do { -+ ASSERT_BREAK(prAdapter != NULL); -+ -+ prP2pConnSetting = prAdapter->rWifiVar.prP2PConnSettings; -+#if 0 -+ ucAutoChnl = prP2pConnSetting->ucOperatingChnl; -+#endif -+ -+ prDomainInfoEntry = rlmDomainGetDomainInfo(prAdapter); -+ -+ ASSERT_BREAK((prDomainInfoEntry != NULL) && (prP2pConnSetting != NULL)); -+ -+ prChannelEntryField = (P_CHANNEL_ENTRY_FIELD_T) prP2pConnSetting->aucChannelEntriesField; -+ -+ for (u4Idx = 0; u4Idx < MAX_SUBBAND_NUM; u4Idx++) { -+ prDomainSubBand = &prDomainInfoEntry->rSubBand[u4Idx]; -+ -+ if (((prDomainSubBand->ucBand == BAND_5G) && (!prAdapter->fgEnable5GBand)) || -+ (prDomainSubBand->ucBand == BAND_NULL)) { -+ continue; -+ } -+ -+ if (ucBufferSize < (P2P_ATTRI_LEN_CHANNEL_ENTRY + prDomainSubBand->ucNumChannels)) { -+ /* Buffer is not enough to include all supported channels. */ -+ break; /* for */ -+ } -+ -+ prChannelEntryField->ucRegulatoryClass = prDomainSubBand->ucRegClass; -+ prChannelEntryField->ucNumberOfChannels = prDomainSubBand->ucNumChannels; -+ -+ for (u4IdxII = 0; u4IdxII < prDomainSubBand->ucNumChannels; u4IdxII++) { -+ prChannelEntryField->aucChannelList[u4IdxII] = prDomainSubBand->ucFirstChannelNum + -+ (u4IdxII * prDomainSubBand->ucChannelSpan); -+ -+#if 0 -+ switch (prChannelEntryField->aucChannelList[u4IdxII]) { -+ case 1: -+ ucSocialChnlSupport = 1; -+ break; -+ case 6: -+ ucSocialChnlSupport = 6; -+ break; -+ case 11: -+ ucSocialChnlSupport = 11; -+ break; -+ default: -+ break; -+ } -+ -+#endif -+ } -+ -+ if (ucBufferSize >= (P2P_ATTRI_LEN_CHANNEL_ENTRY + prChannelEntryField->ucNumberOfChannels)) -+ ucBufferSize -= (P2P_ATTRI_LEN_CHANNEL_ENTRY + prChannelEntryField->ucNumberOfChannels); -+ else -+ break; -+ -+ prChannelEntryField = (P_CHANNEL_ENTRY_FIELD_T) ((ULONG) prChannelEntryField + -+ P2P_ATTRI_LEN_CHANNEL_ENTRY + -+ (ULONG) -+ prChannelEntryField->ucNumberOfChannels); -+ -+ } -+ -+#if 0 -+ if (prP2pConnSetting->ucListenChnl == 0) { -+ prP2pConnSetting->ucListenChnl = P2P_DEFAULT_LISTEN_CHANNEL; -+ -+ if (ucSocialChnlSupport != 0) { -+ /* 1. User Not Set LISTEN channel. -+ * 2. Social channel is not empty. -+ */ -+ prP2pConnSetting->ucListenChnl = ucSocialChnlSupport; -+ } -+ } -+#endif -+ -+ /* TODO: 20110921 frog - */ -+ /* If LISTEN channel is not set, -+ * a random supported channel would be set. -+ * If no social channel is supported, DEFAULT channel would be set. -+ */ -+ -+ prP2pConnSetting->ucRfChannelListSize = P2P_MAX_SUPPORTED_CHANNEL_LIST_SIZE - ucBufferSize; -+ -+#if 0 -+ if (prP2pConnSetting->ucOperatingChnl == 0) { /* User not set OPERATE channel. */ -+ -+ if (scnQuerySparseChannel(prAdapter, NULL, &ucAutoChnl)) -+ break; /* while */ -+ -+ ucBufferSize = prP2pConnSetting->ucRfChannelListSize; -+ -+ prChannelEntryField = (P_CHANNEL_ENTRY_FIELD_T) prP2pConnSetting->aucChannelEntriesField; -+ -+ while (ucBufferSize != 0) { -+ if (prChannelEntryField->ucNumberOfChannels != 0) { -+ ucAutoChnl = prChannelEntryField->aucChannelList[0]; -+ break; /* while */ -+ } -+ -+ else { -+ prChannelEntryField = (P_CHANNEL_ENTRY_FIELD_T) ((UINT_32) prChannelEntryField + -+ P2P_ATTRI_LEN_CHANNEL_ENTRY + -+ (UINT_32)prChannelEntryField->ucNumberOfChannels); -+ -+ ucBufferSize -= -+ (P2P_ATTRI_LEN_CHANNEL_ENTRY + prChannelEntryField->ucNumberOfChannels); -+ } -+ -+ } -+ -+ } -+#endif -+ /* We assume user would not set a channel not in the channel list. -+ * If so, the operating channel still depends on target device supporting capability. -+ */ -+ -+ /* TODO: 20110921 frog - */ -+ /* If the Operating channel is not set, a channel from supported channel list is set automatically. -+ * If there is no supported channel in channel list, a DEFAULT channel is set. -+ */ -+ -+ } while (FALSE); -+ -+#if 0 -+ prP2pConnSetting->ucOperatingChnl = ucAutoChnl; -+#endif -+ -+} /* rlmFuncInitialChannelList */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Find a common channel list from the local channel list info & target channel list info. -+* -+* \param[in] prAdapter Pointer of ADAPTER_T -+* -+* \return boolean value if probe response frame is -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+rlmFuncCommonChannelList(IN P_ADAPTER_T prAdapter, -+ IN P_CHANNEL_ENTRY_FIELD_T prChannelEntryII, IN UINT_8 ucChannelListSize) -+{ -+ P_P2P_CONNECTION_SETTINGS_T prP2pConnSetting = (P_P2P_CONNECTION_SETTINGS_T) NULL; -+ P_CHANNEL_ENTRY_FIELD_T prChannelEntryI = (P_CHANNEL_ENTRY_FIELD_T) NULL, prChannelEntryIII = -+ (P_CHANNEL_ENTRY_FIELD_T) NULL; -+ UINT_8 aucCommonChannelList[P2P_MAX_SUPPORTED_CHANNEL_LIST_SIZE] = {0}; -+ UINT_8 ucOriChnlSize = 0, ucNewChnlSize = 0; -+ -+ do { -+ -+ ASSERT_BREAK(prAdapter != NULL); -+ -+ prP2pConnSetting = prAdapter->rWifiVar.prP2PConnSettings; -+ -+ prChannelEntryIII = (P_CHANNEL_ENTRY_FIELD_T) aucCommonChannelList; -+ -+ while (ucChannelListSize > 0) { -+ -+ prChannelEntryI = (P_CHANNEL_ENTRY_FIELD_T) prP2pConnSetting->aucChannelEntriesField; -+ ucOriChnlSize = prP2pConnSetting->ucRfChannelListSize; -+ -+ while (ucOriChnlSize > 0) { -+ if (prChannelEntryI->ucRegulatoryClass == prChannelEntryII->ucRegulatoryClass) { -+ prChannelEntryIII->ucRegulatoryClass = prChannelEntryI->ucRegulatoryClass; -+ /* TODO: Currently we assume that the regulatory class the same, -+ * the channels are the same. */ -+ kalMemCopy(prChannelEntryIII->aucChannelList, prChannelEntryII->aucChannelList, -+ prChannelEntryII->ucNumberOfChannels); -+ prChannelEntryIII->ucNumberOfChannels = prChannelEntryII->ucNumberOfChannels; -+ -+ ucNewChnlSize += -+ P2P_ATTRI_LEN_CHANNEL_ENTRY + prChannelEntryIII->ucNumberOfChannels; -+ -+ prChannelEntryIII = (P_CHANNEL_ENTRY_FIELD_T) ((ULONG) prChannelEntryIII + -+ P2P_ATTRI_LEN_CHANNEL_ENTRY + -+ (ULONG)prChannelEntryIII->ucNumberOfChannels); -+ } -+ -+ ucOriChnlSize -= (P2P_ATTRI_LEN_CHANNEL_ENTRY + prChannelEntryI->ucNumberOfChannels); -+ -+ prChannelEntryI = (P_CHANNEL_ENTRY_FIELD_T) ((ULONG) prChannelEntryI + -+ P2P_ATTRI_LEN_CHANNEL_ENTRY + -+ (ULONG) -+ prChannelEntryI->ucNumberOfChannels); -+ -+ } -+ -+ ucChannelListSize -= (P2P_ATTRI_LEN_CHANNEL_ENTRY + prChannelEntryII->ucNumberOfChannels); -+ -+ prChannelEntryII = (P_CHANNEL_ENTRY_FIELD_T) ((ULONG) prChannelEntryII + -+ P2P_ATTRI_LEN_CHANNEL_ENTRY + -+ (ULONG) prChannelEntryII->ucNumberOfChannels); -+ -+ } -+ -+ kalMemCopy(prP2pConnSetting->aucChannelEntriesField, aucCommonChannelList, ucNewChnlSize); -+ prP2pConnSetting->ucRfChannelListSize = ucNewChnlSize; -+ -+ } while (FALSE); -+ -+} /* rlmFuncCommonChannelList */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT_8 rlmFuncFindOperatingClass(IN P_ADAPTER_T prAdapter, IN UINT_8 ucChannelNum) -+{ -+ UINT_8 ucRegulatoryClass = 0, ucBufferSize = 0; -+ P_P2P_CONNECTION_SETTINGS_T prP2pConnSetting = (P_P2P_CONNECTION_SETTINGS_T) NULL; -+ P_CHANNEL_ENTRY_FIELD_T prChannelEntryField = (P_CHANNEL_ENTRY_FIELD_T) NULL; -+ UINT_32 u4Idx = 0; -+ -+ do { -+ ASSERT_BREAK(prAdapter != NULL); -+ -+ prP2pConnSetting = prAdapter->rWifiVar.prP2PConnSettings; -+ ucBufferSize = prP2pConnSetting->ucRfChannelListSize; -+ prChannelEntryField = (P_CHANNEL_ENTRY_FIELD_T) prP2pConnSetting->aucChannelEntriesField; -+ -+ while (ucBufferSize != 0) { -+ -+ for (u4Idx = 0; u4Idx < prChannelEntryField->ucNumberOfChannels; u4Idx++) { -+ if (prChannelEntryField->aucChannelList[u4Idx] == ucChannelNum) { -+ ucRegulatoryClass = prChannelEntryField->ucRegulatoryClass; -+ break; -+ } -+ -+ } -+ -+ if (ucRegulatoryClass != 0) -+ break; /* while */ -+ -+ prChannelEntryField = (P_CHANNEL_ENTRY_FIELD_T) ((ULONG) prChannelEntryField + -+ P2P_ATTRI_LEN_CHANNEL_ENTRY + -+ (ULONG)prChannelEntryField->ucNumberOfChannels); -+ -+ ucBufferSize -= (P2P_ATTRI_LEN_CHANNEL_ENTRY + prChannelEntryField->ucNumberOfChannels); -+ -+ } -+ -+ } while (FALSE); -+ -+ return ucRegulatoryClass; -+} /* rlmFuncFindOperatingClass */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN -+rlmFuncFindAvailableChannel(IN P_ADAPTER_T prAdapter, -+ IN UINT_8 ucCheckChnl, -+ IN PUINT_8 pucSuggestChannel, IN BOOLEAN fgIsSocialChannel, IN BOOLEAN fgIsDefaultChannel) -+{ -+ BOOLEAN fgIsResultAvailable = FALSE; -+ P_CHANNEL_ENTRY_FIELD_T prChannelEntry = (P_CHANNEL_ENTRY_FIELD_T) NULL; -+ P_P2P_CONNECTION_SETTINGS_T prP2pConnSetting = (P_P2P_CONNECTION_SETTINGS_T) NULL; -+ UINT_8 ucBufferSize = 0, ucIdx = 0, ucChannelSelected = 0; -+ -+ do { -+ ASSERT_BREAK(prAdapter != NULL); -+ -+ if (fgIsDefaultChannel) -+ ucChannelSelected = P2P_DEFAULT_LISTEN_CHANNEL; -+ -+ prP2pConnSetting = prAdapter->rWifiVar.prP2PConnSettings; -+ ucBufferSize = prP2pConnSetting->ucRfChannelListSize; -+ prChannelEntry = (P_CHANNEL_ENTRY_FIELD_T) prP2pConnSetting->aucChannelEntriesField; -+ -+ while ((ucBufferSize != 0) && (!fgIsResultAvailable)) { -+ -+ for (ucIdx = 0; ucIdx < prChannelEntry->ucNumberOfChannels; ucIdx++) { -+ if ((!fgIsSocialChannel) || -+ (prChannelEntry->aucChannelList[ucIdx] == 1) || -+ (prChannelEntry->aucChannelList[ucIdx] == 6) || -+ (prChannelEntry->aucChannelList[ucIdx] == 11)) { -+ -+ if (prChannelEntry->aucChannelList[ucIdx] <= 11) { -+ /* 2.4G. */ -+ ucChannelSelected = prChannelEntry->aucChannelList[ucIdx]; -+ } else if ((prChannelEntry->aucChannelList[ucIdx] < 52) && -+ (prChannelEntry->aucChannelList[ucIdx] > 14)) { -+ /* 2.4G + 5G. */ -+ ucChannelSelected = prChannelEntry->aucChannelList[ucIdx]; -+ } -+ -+ if (ucChannelSelected == ucCheckChnl) { -+ fgIsResultAvailable = TRUE; -+ break; -+ } -+ } -+ -+ } -+ -+ ucBufferSize -= (P2P_ATTRI_LEN_CHANNEL_ENTRY + prChannelEntry->ucNumberOfChannels); -+ -+ prChannelEntry = (P_CHANNEL_ENTRY_FIELD_T) ((ULONG) prChannelEntry + -+ P2P_ATTRI_LEN_CHANNEL_ENTRY + -+ (ULONG) prChannelEntry->ucNumberOfChannels); -+ -+ } -+ -+ if ((!fgIsResultAvailable) && (pucSuggestChannel != NULL)) { -+ DBGLOG(P2P, TRACE, -+ "The request channel %d is not available, sugguested channel:%d\n", ucCheckChnl, -+ ucChannelSelected); -+ /* Given a suggested channel. */ -+ *pucSuggestChannel = ucChannelSelected; -+ } -+ -+ } while (FALSE); -+ -+ return fgIsResultAvailable; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+ENUM_CHNL_EXT_T rlmDecideScoForAP(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo) -+{ -+ P_DOMAIN_SUBBAND_INFO prSubband; -+ P_DOMAIN_INFO_ENTRY prDomainInfo; -+ UINT_8 ucSecondChannel, i, j; -+ ENUM_CHNL_EXT_T eSCO; -+ -+ eSCO = CHNL_EXT_SCN; -+ -+ if (prBssInfo->eBand == BAND_2G4) { -+ if (prBssInfo->ucPrimaryChannel != 14) -+ eSCO = (prBssInfo->ucPrimaryChannel > 7) ? CHNL_EXT_SCB : CHNL_EXT_SCA; -+ } else { -+ prDomainInfo = rlmDomainGetDomainInfo(prAdapter); -+ ASSERT(prDomainInfo); -+ -+ for (i = 0; i < MAX_SUBBAND_NUM; i++) { -+ prSubband = &prDomainInfo->rSubBand[i]; -+ if (prSubband->ucBand == prBssInfo->eBand) { -+ for (j = 0; j < prSubband->ucNumChannels; j++) { -+ if ((prSubband->ucFirstChannelNum + j * prSubband->ucChannelSpan) -+ == prBssInfo->ucPrimaryChannel) { -+ eSCO = (j & 1) ? CHNL_EXT_SCB : CHNL_EXT_SCA; -+ break; -+ } -+ } -+ -+ if (j < prSubband->ucNumChannels) -+ break; /* Found */ -+ } -+ } -+ } -+ -+ /* Check if it is boundary channel and 40MHz BW is permitted */ -+ if (eSCO != CHNL_EXT_SCN) { -+ ucSecondChannel = (eSCO == CHNL_EXT_SCA) ? -+ (prBssInfo->ucPrimaryChannel + 4) : (prBssInfo->ucPrimaryChannel - 4); -+ -+ if (!rlmDomainIsLegalChannel(prAdapter, prBssInfo->eBand, ucSecondChannel)) -+ eSCO = CHNL_EXT_SCN; -+ } -+ -+ return eSCO; -+} -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_rlm_obss.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_rlm_obss.c -new file mode 100644 -index 000000000000..154f1e5db0f7 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_rlm_obss.c -@@ -0,0 +1,313 @@ -+/* -+** Id: @(#) gl_p2p_cfg80211.c@@ -+*/ -+ -+/*! \file gl_p2p_cfg80211.c -+ \brief Main routines of Linux driver interface for Wi-Fi Direct -+ using cfg80211 interface -+ -+ This file contains the main routines of Linux driver for MediaTek Inc. 802.11 -+ Wireless LAN Adapters. -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#include "precomp.h" -+ -+static UINT_8 rlmObssChnlLevelIn2G4(P_BSS_INFO_T prBssInfo, UINT_8 ucPriChannel, ENUM_CHNL_EXT_T eExtend); -+ -+static UINT_8 rlmObssChnlLevelIn5G(P_BSS_INFO_T prBssInfo, UINT_8 ucPriChannel, ENUM_CHNL_EXT_T eExtend); -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Different concurrent network has itself channel lists, and -+* concurrent networks should have been recorded in channel lists. -+* If role of active P2P is GO, assume associated AP of AIS will -+* record our Beacon for P2P GO because of same channel. -+* -+* Note: If we have scenario of different channel in the future, -+* the internal FW communication channel shall be established. -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT_8 rlmObssChnlLevel(P_BSS_INFO_T prBssInfo, ENUM_BAND_T eBand, UINT_8 ucPriChannel, ENUM_CHNL_EXT_T eExtend) -+{ -+ UINT_8 ucChannelLevel; -+ -+ ASSERT(prBssInfo); -+ -+ if (eBand == BAND_2G4) { -+ ucChannelLevel = rlmObssChnlLevelIn2G4(prBssInfo, ucPriChannel, eExtend); -+ -+ /* (TBD) If concurrent networks permit different channel, extra -+ * channel judgement should be added. Please refer to -+ * previous version of this file. -+ */ -+ } else if (eBand == BAND_5G) { -+ ucChannelLevel = rlmObssChnlLevelIn5G(prBssInfo, ucPriChannel, eExtend); -+ -+ /* (TBD) If concurrent networks permit different channel, extra -+ * channel judgement should be added. Please refer to -+ * previous version of this file. -+ */ -+ } else { -+ ucChannelLevel = CHNL_LEVEL0; -+ } -+ -+ return ucChannelLevel; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+static UINT_8 rlmObssChnlLevelIn2G4(P_BSS_INFO_T prBssInfo, UINT_8 ucPriChannel, ENUM_CHNL_EXT_T eExtend) -+{ -+ UINT_8 i, ucChannelLevel; -+ UINT_8 ucSecChannel, ucCenterChannel; -+ UINT_8 ucAffectedChnl_L, ucAffectedChnl_H; -+ -+ ASSERT(prBssInfo); -+ -+ ucChannelLevel = CHNL_LEVEL2; -+ -+ /* Calculate center channel for 2.4G band */ -+ if (eExtend == CHNL_EXT_SCA) { -+ ucCenterChannel = ucPriChannel + 2; -+ ucSecChannel = ucPriChannel + 4; -+ } else if (eExtend == CHNL_EXT_SCB) { -+ ucCenterChannel = ucPriChannel - 2; -+ ucSecChannel = ucPriChannel - 4; -+ } else { -+ return CHNL_LEVEL0; -+ } -+ ASSERT(ucCenterChannel >= 1 && ucCenterChannel <= 14); -+ -+ /* Calculated low/upper channels in affected freq range */ -+ ucAffectedChnl_L = (ucCenterChannel <= AFFECTED_CHNL_OFFSET) ? 1 : (ucCenterChannel - AFFECTED_CHNL_OFFSET); -+ -+ ucAffectedChnl_H = (ucCenterChannel >= (14 - AFFECTED_CHNL_OFFSET)) ? -+ 14 : (ucCenterChannel + AFFECTED_CHNL_OFFSET); -+ -+ /* Check intolerant (Non-HT) channel list */ -+ ASSERT(prBssInfo->auc2G_NonHtChnlList[0] <= CHNL_LIST_SZ_2G); -+ for (i = 1; i <= prBssInfo->auc2G_NonHtChnlList[0] && i <= CHNL_LIST_SZ_2G; i++) { -+ if ((prBssInfo->auc2G_NonHtChnlList[i] >= ucAffectedChnl_L && -+ prBssInfo->auc2G_NonHtChnlList[i] <= ucAffectedChnl_H) && -+ prBssInfo->auc2G_NonHtChnlList[i] != ucPriChannel) { -+ -+ ucChannelLevel = CHNL_LEVEL0; -+ goto L_2G4_level_end; -+ } -+ } -+ -+ /* Check 20M BW request channel list */ -+ ASSERT(prBssInfo->auc2G_20mReqChnlList[0] <= CHNL_LIST_SZ_2G); -+ for (i = 1; i <= prBssInfo->auc2G_20mReqChnlList[0] && i <= CHNL_LIST_SZ_2G; i++) { -+ if ((prBssInfo->auc2G_20mReqChnlList[i] >= ucAffectedChnl_L && -+ prBssInfo->auc2G_20mReqChnlList[i] <= ucAffectedChnl_H)) { -+ -+ ucChannelLevel = CHNL_LEVEL0; -+ goto L_2G4_level_end; -+ } -+ } -+ -+ /* Check 2.4G primary channel list */ -+ ASSERT(prBssInfo->auc2G_PriChnlList[0] <= CHNL_LIST_SZ_2G); -+ for (i = 1; i <= prBssInfo->auc2G_PriChnlList[0] && i <= CHNL_LIST_SZ_2G; i++) { -+ if ((prBssInfo->auc2G_PriChnlList[i] >= ucAffectedChnl_L && -+ prBssInfo->auc2G_PriChnlList[i] <= ucAffectedChnl_H) && -+ prBssInfo->auc2G_PriChnlList[i] != ucPriChannel) { -+ -+ ucChannelLevel = CHNL_LEVEL0; -+ goto L_2G4_level_end; -+ } -+ } -+ -+ /* Check 2.4G secondary channel list */ -+ ASSERT(prBssInfo->auc2G_SecChnlList[0] <= CHNL_LIST_SZ_2G); -+ for (i = 1; i <= prBssInfo->auc2G_SecChnlList[0] && i <= CHNL_LIST_SZ_2G; i++) { -+ if ((prBssInfo->auc2G_SecChnlList[i] >= ucAffectedChnl_L && -+ prBssInfo->auc2G_SecChnlList[i] <= ucAffectedChnl_H) && -+ prBssInfo->auc2G_SecChnlList[i] != ucSecChannel) { -+ -+ ucChannelLevel = CHNL_LEVEL0; -+ goto L_2G4_level_end; -+ } -+ } -+ -+L_2G4_level_end: -+ -+ return ucChannelLevel; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+static UINT_8 rlmObssChnlLevelIn5G(P_BSS_INFO_T prBssInfo, UINT_8 ucPriChannel, ENUM_CHNL_EXT_T eExtend) -+{ -+ UINT_8 i, ucChannelLevel; -+ UINT_8 ucSecChannel; -+ -+ ASSERT(prBssInfo); -+ -+ ucChannelLevel = CHNL_LEVEL2; -+ -+ /* Calculate center channel for 2.4G band */ -+ if (eExtend == CHNL_EXT_SCA) -+ ucSecChannel = ucPriChannel + 4; -+ else if (eExtend == CHNL_EXT_SCB) -+ ucSecChannel = ucPriChannel - 4; -+ else -+ return CHNL_LEVEL0; -+ ASSERT(ucSecChannel >= 36); -+ -+ /* Check 5G primary channel list */ -+ ASSERT(prBssInfo->auc5G_PriChnlList[0] <= CHNL_LIST_SZ_5G); -+ for (i = 1; i <= prBssInfo->auc5G_PriChnlList[0] && i <= CHNL_LIST_SZ_5G; i++) { -+ if (prBssInfo->auc5G_PriChnlList[i] == ucSecChannel) { -+ -+ ucChannelLevel = CHNL_LEVEL0; -+ goto L_5G_level_end; -+ } else if (prBssInfo->auc5G_PriChnlList[i] == ucPriChannel) { -+ ucChannelLevel = CHNL_LEVEL1; -+ } -+ } -+ -+ /* Check non-HT channel list */ -+ ASSERT(prBssInfo->auc5G_NonHtChnlList[0] <= CHNL_LIST_SZ_5G); -+ for (i = 1; i <= prBssInfo->auc5G_NonHtChnlList[0] && i <= CHNL_LIST_SZ_5G; i++) { -+ if (prBssInfo->auc5G_NonHtChnlList[i] == ucSecChannel) { -+ -+ ucChannelLevel = CHNL_LEVEL0; -+ goto L_5G_level_end; -+ } else if (prBssInfo->auc5G_NonHtChnlList[i] == ucPriChannel) { -+ ucChannelLevel = CHNL_LEVEL1; -+ } -+ } -+ -+ /* Check secondary channel list */ -+ ASSERT(prBssInfo->auc5G_SecChnlList[0] <= CHNL_LIST_SZ_5G); -+ for (i = 1; i <= prBssInfo->auc5G_SecChnlList[0] && i <= CHNL_LIST_SZ_5G; i++) { -+ if (prBssInfo->auc5G_SecChnlList[i] == ucPriChannel) { -+ -+ ucChannelLevel = CHNL_LEVEL0; -+ goto L_5G_level_end; -+ } -+ } -+ -+L_5G_level_end: -+ -+ return ucChannelLevel; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rlmObssScanExemptionRsp(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo, P_SW_RFB_T prSwRfb) -+{ -+ P_MSDU_INFO_T prMsduInfo; -+ P_ACTION_20_40_COEXIST_FRAME prTxFrame; -+ -+ /* To do: need an algorithm to do judgement. Now always reject request */ -+ -+ prMsduInfo = (P_MSDU_INFO_T)cnmMgtPktAlloc(prAdapter, PUBLIC_ACTION_MAX_LEN); -+ if (prMsduInfo == NULL) -+ return; -+ -+ DBGLOG(RLM, INFO, "Send 20/40 coexistence rsp frame!\n"); -+ -+ prTxFrame = (P_ACTION_20_40_COEXIST_FRAME) prMsduInfo->prPacket; -+ -+ prTxFrame->u2FrameCtrl = MAC_FRAME_ACTION; -+ COPY_MAC_ADDR(prTxFrame->aucDestAddr, ((P_ACTION_20_40_COEXIST_FRAME) prSwRfb->pvHeader)->aucSrcAddr); -+ COPY_MAC_ADDR(prTxFrame->aucSrcAddr, prBssInfo->aucOwnMacAddr); -+ COPY_MAC_ADDR(prTxFrame->aucBSSID, prBssInfo->aucBSSID); -+ -+ prTxFrame->ucCategory = CATEGORY_PUBLIC_ACTION; -+ prTxFrame->ucAction = ACTION_PUBLIC_20_40_COEXIST; -+ -+ /* To do: find correct algorithm */ -+ prTxFrame->rBssCoexist.ucId = ELEM_ID_20_40_BSS_COEXISTENCE; -+ prTxFrame->rBssCoexist.ucLength = 1; -+ prTxFrame->rBssCoexist.ucData = 0; -+ -+ ASSERT((WLAN_MAC_HEADER_LEN + 5) <= PUBLIC_ACTION_MAX_LEN); -+ -+ prMsduInfo->ucPacketType = HIF_TX_PACKET_TYPE_MGMT; -+ prMsduInfo->ucStaRecIndex = prSwRfb->ucStaRecIdx; -+ prMsduInfo->ucNetworkType = prBssInfo->ucNetTypeIndex; -+ prMsduInfo->ucMacHeaderLength = WLAN_MAC_MGMT_HEADER_LEN; -+ prMsduInfo->fgIs802_1x = FALSE; -+ prMsduInfo->fgIs802_11 = TRUE; -+ prMsduInfo->u2FrameLength = WLAN_MAC_MGMT_HEADER_HTC_LEN + 5; -+ prMsduInfo->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter); -+ prMsduInfo->pfTxDoneHandler = NULL; -+ prMsduInfo->fgIsBasicRate = FALSE; -+ -+ /* Send them to HW queue */ -+ nicTxEnqueueMsdu(prAdapter, prMsduInfo); -+} -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_scan.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_scan.c -new file mode 100644 -index 000000000000..b5bd23965fe3 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_scan.c -@@ -0,0 +1,756 @@ -+/* -+** Id: @(#) p2p_scan.c@@ -+*/ -+ -+/*! \file "p2p_scan.c" -+ \brief This file defines the p2p scan profile and the processing function of -+ scan result for SCAN Module. -+ -+ The SCAN Profile selection is part of SCAN MODULE and responsible for defining -+ SCAN Parameters - e.g. MIN_CHANNEL_TIME, number of scan channels. -+ In this file we also define the process of SCAN Result including adding, searching -+ and removing SCAN record from the list. -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+#include "precomp.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+P_P2P_DEVICE_DESC_T -+scanSearchTargetP2pDesc(IN P_ADAPTER_T prAdapter, IN UINT_8 aucDeviceID[], IN PP_BSS_DESC_T pprBssDesc) -+{ -+ -+ P_P2P_DEVICE_DESC_T prTargetP2pDesc = (P_P2P_DEVICE_DESC_T) NULL; -+ P_SCAN_INFO_T prScanInfo = (P_SCAN_INFO_T) NULL; -+ P_LINK_T prBSSDescList; -+ P_BSS_DESC_T prBssDesc = (P_BSS_DESC_T) NULL; -+ -+ ASSERT(prAdapter); -+ ASSERT(aucDeviceID); -+ -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ prBSSDescList = &prScanInfo->rBSSDescList; -+ -+ /* 4 <1> The outer loop to search for a candidate. */ -+ LINK_FOR_EACH_ENTRY(prBssDesc, prBSSDescList, rLinkEntry, BSS_DESC_T) { -+ -+ /* Loop for each prBssDesc */ -+ prTargetP2pDesc = scanFindP2pDeviceDesc(prAdapter, prBssDesc, aucDeviceID, TRUE, FALSE); -+ -+ if (prTargetP2pDesc != NULL) -+ break; -+ } -+ -+ if ((pprBssDesc) && (prTargetP2pDesc != NULL)) { -+ /* Only valid if prTargetP2pDesc is not NULL. */ -+ *pprBssDesc = prBssDesc; -+ } -+ -+ return prTargetP2pDesc; -+} /* scanSearchTargetP2pDesc */ -+ -+VOID scanInvalidAllP2pClientDevice(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBssDesc) -+{ -+ P_LINK_ENTRY_T prLinkEntry = (P_LINK_ENTRY_T) NULL; -+ P_P2P_DEVICE_DESC_T prTargetDesc = (P_P2P_DEVICE_DESC_T) NULL; -+ -+ LINK_FOR_EACH(prLinkEntry, &prBssDesc->rP2pDeviceList) { -+ prTargetDesc = LINK_ENTRY(prLinkEntry, P2P_DEVICE_DESC_T, rLinkEntry); -+ -+ if (prTargetDesc->fgDevInfoValid) -+ prTargetDesc->fgDevInfoValid = FALSE; -+ } -+ -+} /* scanRenewP2pClientDevice */ -+ -+VOID scanRemoveInvalidP2pClientDevice(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBssDesc) -+{ -+ P_LINK_ENTRY_T prLinkEntry = (P_LINK_ENTRY_T) NULL, prNexEntry = (P_LINK_ENTRY_T) NULL; -+ P_P2P_DEVICE_DESC_T prTargetDesc = (P_P2P_DEVICE_DESC_T) NULL; -+ P_P2P_CONNECTION_SETTINGS_T prP2pConnSettings = (P_P2P_CONNECTION_SETTINGS_T) NULL; -+ -+ prP2pConnSettings = prAdapter->rWifiVar.prP2PConnSettings; -+ -+ LINK_FOR_EACH_SAFE(prLinkEntry, prNexEntry, &prBssDesc->rP2pDeviceList) { -+ prTargetDesc = LINK_ENTRY(prLinkEntry, P2P_DEVICE_DESC_T, rLinkEntry); -+ -+ if (!prTargetDesc->fgDevInfoValid) { -+ LINK_REMOVE_KNOWN_ENTRY(&prBssDesc->rP2pDeviceList, prLinkEntry); -+ if ((prP2pConnSettings) && (prP2pConnSettings->prTargetP2pDesc == prTargetDesc)) -+ prP2pConnSettings->prTargetP2pDesc = NULL; -+ kalMemFree(prTargetDesc, VIR_MEM_TYPE, sizeof(P2P_DEVICE_DESC_T)); -+ } -+ } -+ -+} /* scanRenewP2pClientDevice */ -+ -+P_P2P_DEVICE_DESC_T -+scanFindP2pDeviceDesc(IN P_ADAPTER_T prAdapter, -+ IN P_BSS_DESC_T prBssDesc, -+ IN UINT_8 aucMacAddr[], IN BOOLEAN fgIsDeviceAddr, IN BOOLEAN fgAddIfNoFound) -+{ -+ -+ P_P2P_DEVICE_DESC_T prTargetDesc = (P_P2P_DEVICE_DESC_T) NULL; -+ P_LINK_ENTRY_T prLinkEntry = (P_LINK_ENTRY_T) NULL; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prBssDesc != NULL) && (aucMacAddr != NULL)); -+ -+ LINK_FOR_EACH(prLinkEntry, &prBssDesc->rP2pDeviceList) { -+ prTargetDesc = LINK_ENTRY(prLinkEntry, P2P_DEVICE_DESC_T, rLinkEntry); -+ -+ if (fgIsDeviceAddr) { -+ if (EQUAL_MAC_ADDR(prTargetDesc->aucDeviceAddr, aucMacAddr)) -+ break; -+ } else { -+ if (EQUAL_MAC_ADDR(prTargetDesc->aucInterfaceAddr, aucMacAddr)) -+ break; -+ } -+ -+ prTargetDesc = NULL; -+ } -+ -+ if ((fgAddIfNoFound) && (prTargetDesc == NULL)) { -+ /* Target Not Found. */ -+ /* TODO: Use memory pool in the future. */ -+ prTargetDesc = kalMemAlloc(sizeof(P2P_DEVICE_DESC_T), VIR_MEM_TYPE); -+ -+ if (prTargetDesc) { -+ kalMemZero(prTargetDesc, sizeof(P2P_DEVICE_DESC_T)); -+ LINK_ENTRY_INITIALIZE(&(prTargetDesc->rLinkEntry)); -+ COPY_MAC_ADDR(prTargetDesc->aucDeviceAddr, aucMacAddr); -+ LINK_INSERT_TAIL(&prBssDesc->rP2pDeviceList, &prTargetDesc->rLinkEntry); -+ prTargetDesc->fgDevInfoValid = TRUE; -+ } else { -+ ASSERT(FALSE); -+ } -+ } -+ -+ } while (FALSE); -+ -+ return prTargetDesc; -+} /* scanFindP2pDeviceDesc */ -+ -+P_P2P_DEVICE_DESC_T scanGetP2pDeviceDesc(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBssDesc) -+{ -+ -+ P_P2P_DEVICE_DESC_T prTargetDesc = (P_P2P_DEVICE_DESC_T) NULL; -+ -+ ASSERT(prAdapter); -+ ASSERT(prBssDesc); -+ -+ if (prBssDesc->prP2pDesc == NULL) { -+ -+ prTargetDesc = kalMemAlloc(sizeof(P2P_DEVICE_DESC_T), VIR_MEM_TYPE); -+ -+ if (prTargetDesc) { -+ kalMemZero(prTargetDesc, sizeof(P2P_DEVICE_DESC_T)); -+ LINK_ENTRY_INITIALIZE(&(prTargetDesc->rLinkEntry)); -+ LINK_INSERT_TAIL(&prBssDesc->rP2pDeviceList, &prTargetDesc->rLinkEntry); -+ prTargetDesc->fgDevInfoValid = TRUE; -+ prBssDesc->prP2pDesc = prTargetDesc; -+ /* We are not sure the SrcAddr is Device Address or Interface Address. */ -+ COPY_MAC_ADDR(prTargetDesc->aucDeviceAddr, prBssDesc->aucSrcAddr); -+ COPY_MAC_ADDR(prTargetDesc->aucInterfaceAddr, prBssDesc->aucSrcAddr); -+ } else { -+ -+ ASSERT(FALSE); -+ } -+ } else { -+ prTargetDesc = prBssDesc->prP2pDesc; -+ } -+ -+ return prTargetDesc; -+ -+} /* scanFindP2pDeviceDesc */ -+ -+#if 0 -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Convert the Beacon or ProbeResp Frame in SW_RFB_T to Event Packet -+* -+* @param[in] prSwRfb Pointer to the receiving SW_RFB_T structure. -+* -+* @retval WLAN_STATUS_SUCCESS It is a valid Scan Result and been sent to the host. -+* @retval WLAN_STATUS_FAILURE It is not a valid Scan Result. -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN scanUpdateP2pDeviceDesc(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBssDesc) -+{ -+ P_P2P_DEVICE_DESC_T prP2pDesc = (P_P2P_DEVICE_DESC_T) NULL; -+ P_P2P_ATTRIBUTE_T prP2pAttribute = (P_P2P_ATTRIBUTE_T) NULL; -+ UINT_16 u2AttributeLen = 0; -+ UINT_32 u4Idx = 0; -+ BOOLEAN fgUpdateDevInfo = FALSE; -+ -+ P_DEVICE_NAME_TLV_T prP2pDevName = (P_DEVICE_NAME_TLV_T) NULL; -+ P_P2P_ATTRI_GROUP_INFO_T prP2pAttriGroupInfo = (P_P2P_ATTRI_GROUP_INFO_T) NULL; -+ -+ ASSERT(prAdapter); -+ -+ prP2pDesc = scanGetP2pDeviceDesc(prAdapter, prBssDesc); -+ -+ if (!prP2pDesc) { -+ ASSERT(FALSE); -+ return fgUpdateDevInfo; -+ } -+ -+ p2pGetP2PAttriList(prAdapter, prBssDesc->aucIEBuf, prBssDesc->u2IELength, (PPUINT_8) & prP2pAttribute, -+ &u2AttributeLen); -+ -+ while (u2AttributeLen >= P2P_ATTRI_HDR_LEN) { -+ switch (prP2pAttribute->ucId) { -+ case P2P_ATTRI_ID_P2P_CAPABILITY: /* Beacon, Probe Response */ -+ { -+ P_P2P_ATTRI_CAPABILITY_T prP2pAttriCapability = (P_P2P_ATTRI_CAPABILITY_T) NULL; -+ -+ prP2pAttriCapability = (P_P2P_ATTRI_CAPABILITY_T) prP2pAttribute; -+ ASSERT(prP2pAttriCapability->u2Length == 2); -+ -+ prP2pDesc->ucDeviceCapabilityBitmap = prP2pAttriCapability->ucDeviceCap; -+ prP2pDesc->ucGroupCapabilityBitmap = prP2pAttriCapability->ucGroupCap; -+ } -+ break; -+ case P2P_ATTRI_ID_P2P_DEV_ID: /* Beacon */ -+ { -+ P_P2P_ATTRI_DEV_ID_T prP2pAttriDevID = (P_P2P_ATTRI_DEV_ID_T) NULL; -+ -+ prP2pAttriDevID = (P_P2P_ATTRI_DEV_ID_T) prP2pAttribute; -+ ASSERT(prP2pAttriDevID->u2Length == P2P_ATTRI_MAX_LEN_P2P_DEV_ID); -+ -+ kalMemCopy(prP2pDesc->aucDeviceAddr, prP2pAttriDevID->aucDevAddr, MAC_ADDR_LEN); -+ } -+ break; -+ case P2P_ATTRI_ID_P2P_DEV_INFO: /* Probe Response */ -+ { -+ P_P2P_ATTRI_DEV_INFO_T prP2pAttriDevInfo = (P_P2P_ATTRI_DEV_INFO_T) NULL; -+ P_P2P_DEVICE_TYPE_T prP2pDevType = (P_P2P_DEVICE_TYPE_T) NULL; -+ UINT_16 u2NameLen = 0, u2Id = 0; -+ -+ fgUpdateDevInfo = TRUE; -+ -+ prP2pAttriDevInfo = (P_P2P_ATTRI_DEV_INFO_T) prP2pAttribute; -+ -+ kalMemCopy(prP2pDesc->aucDeviceAddr, prP2pAttriDevInfo->aucDevAddr, MAC_ADDR_LEN); -+ -+ WLAN_GET_FIELD_BE16(&prP2pAttriDevInfo->u2ConfigMethodsBE, &prP2pDesc->u2ConfigMethod); -+ -+ prP2pDevType = &prP2pDesc->rPriDevType; -+ WLAN_GET_FIELD_BE16(&prP2pAttriDevInfo->rPrimaryDevTypeBE.u2CategoryId, -+ &prP2pDevType->u2CategoryID); -+ WLAN_GET_FIELD_BE16(&prP2pAttriDevInfo->rPrimaryDevTypeBE.u2SubCategoryId, -+ &prP2pDevType->u2SubCategoryID); -+ -+ ASSERT(prP2pAttriDevInfo->ucNumOfSecondaryDevType <= -+ P2P_GC_MAX_CACHED_SEC_DEV_TYPE_COUNT); -+ /* TODO: Fixme if secondary device type is more than 2. */ -+ prP2pDesc->ucSecDevTypeNum = 0; -+ for (u4Idx = 0; u4Idx < prP2pAttriDevInfo->ucNumOfSecondaryDevType; u4Idx++) { -+ if (u4Idx < P2P_GC_MAX_CACHED_SEC_DEV_TYPE_COUNT) { -+ prP2pDevType = &(prP2pDesc->arSecDevType[u4Idx]); -+ WLAN_GET_FIELD_BE16(&prP2pAttriDevInfo-> -+ arSecondaryDevTypeListBE[u4Idx].u2CategoryId, -+ &prP2pDevType->u2CategoryID); -+ WLAN_GET_FIELD_BE16(&prP2pAttriDevInfo-> -+ arSecondaryDevTypeListBE[u4Idx].u2SubCategoryId, -+ &prP2pDevType->u2SubCategoryID); -+ prP2pDesc->ucSecDevTypeNum++; -+ } -+ -+ } -+ prP2pDevName = -+ (P_DEVICE_NAME_TLV_T) ((PUINT_8) prP2pAttriDevInfo->arSecondaryDevTypeListBE + -+ (u4Idx * sizeof(DEVICE_TYPE_T))); -+ WLAN_GET_FIELD_BE16(&prP2pDevName->u2Length, &u2NameLen); -+ WLAN_GET_FIELD_BE16(&prP2pDevName->u2Id, &u2Id); -+ ASSERT(u2Id == WPS_ATTRI_ID_DEVICE_NAME); -+ if (u2NameLen > WPS_ATTRI_MAX_LEN_DEVICE_NAME) -+ u2NameLen = WPS_ATTRI_MAX_LEN_DEVICE_NAME; -+ prP2pDesc->u2NameLength = u2NameLen; -+ kalMemCopy(prP2pDesc->aucName, prP2pDevName->aucName, prP2pDesc->u2NameLength); -+ } -+ break; -+ case P2P_ATTRI_ID_P2P_GROUP_INFO: /* Probe Response */ -+ prP2pAttriGroupInfo = (P_P2P_ATTRI_GROUP_INFO_T) prP2pAttribute; -+ break; -+ case P2P_ATTRI_ID_NOTICE_OF_ABSENCE: -+ break; -+ case P2P_ATTRI_ID_EXT_LISTEN_TIMING: -+ /* TODO: Not implement yet. */ -+ /* ASSERT(FALSE); */ -+ break; -+ default: -+ break; -+ } -+ -+ u2AttributeLen -= (prP2pAttribute->u2Length + P2P_ATTRI_HDR_LEN); -+ -+ prP2pAttribute = -+ (P_P2P_ATTRIBUTE_T) ((UINT_32) prP2pAttribute + (prP2pAttribute->u2Length + P2P_ATTRI_HDR_LEN)); -+ -+ } -+ -+ if (prP2pAttriGroupInfo != NULL) { -+ P_P2P_CLIENT_INFO_DESC_T prClientInfoDesc = (P_P2P_CLIENT_INFO_DESC_T) NULL; -+ P_P2P_DEVICE_TYPE_T prP2pDevType = (P_P2P_DEVICE_TYPE_T) NULL; -+ -+ scanInvalidAllP2pClientDevice(prAdapter, prBssDesc); -+ -+ /* GO/Device itself. */ -+ prP2pDesc->fgDevInfoValid = TRUE; -+ -+ prClientInfoDesc = (P_P2P_CLIENT_INFO_DESC_T) prP2pAttriGroupInfo->arClientDesc; -+ u2AttributeLen = prP2pAttriGroupInfo->u2Length; -+ -+ while (u2AttributeLen > 0) { -+ prP2pDesc = -+ scanFindP2pDeviceDesc(prAdapter, prBssDesc, prClientInfoDesc->aucDevAddr, TRUE, TRUE); -+ -+ if (!prP2pDesc) { -+ ASSERT(FALSE); -+ break; /* while */ -+ } -+ -+ prP2pDesc->fgDevInfoValid = TRUE; -+ -+ /* Basic size for P2P client info descriptor. */ -+ ASSERT(u2AttributeLen >= 25); -+ if (u2AttributeLen < 25) { -+ DBGLOG(P2P, WARN, "Length incorrect warning.\n"); -+ break; -+ } -+ COPY_MAC_ADDR(prP2pDesc->aucInterfaceAddr, prClientInfoDesc->aucIfAddr); -+ -+ prP2pDesc->ucDeviceCapabilityBitmap = prClientInfoDesc->ucDeviceCap; -+ -+ WLAN_GET_FIELD_BE16(&prClientInfoDesc->u2ConfigMethodsBE, &prP2pDesc->u2ConfigMethod); -+ -+ prP2pDevType = &(prP2pDesc->rPriDevType); -+ WLAN_GET_FIELD_BE16(&prClientInfoDesc->rPrimaryDevTypeBE.u2CategoryId, -+ &prP2pDevType->u2CategoryID); -+ WLAN_GET_FIELD_BE16(&prClientInfoDesc->rPrimaryDevTypeBE.u2SubCategoryId, -+ &prP2pDevType->u2SubCategoryID); -+ -+ ASSERT(prClientInfoDesc->ucNumOfSecondaryDevType <= P2P_GC_MAX_CACHED_SEC_DEV_TYPE_COUNT); -+ prP2pDesc->ucSecDevTypeNum = 0; -+ for (u4Idx = 0; u4Idx < prClientInfoDesc->ucNumOfSecondaryDevType; u4Idx++) { -+ if (u4Idx < P2P_GC_MAX_CACHED_SEC_DEV_TYPE_COUNT) { -+ prP2pDevType = &(prP2pDesc->arSecDevType[u4Idx]); -+ WLAN_GET_FIELD_BE16(&prClientInfoDesc-> -+ arSecondaryDevTypeListBE[u4Idx].u2CategoryId, -+ &prP2pDevType->u2CategoryID); -+ WLAN_GET_FIELD_BE16(&prClientInfoDesc-> -+ arSecondaryDevTypeListBE[u4Idx].u2SubCategoryId, -+ &prP2pDevType->u2SubCategoryID); -+ prP2pDesc->ucSecDevTypeNum++; -+ } -+ -+ } -+ prP2pDevName = -+ (P_DEVICE_NAME_TLV_T) (prClientInfoDesc->arSecondaryDevTypeListBE + -+ (u4Idx * sizeof(DEVICE_TYPE_T))); -+ WLAN_GET_FIELD_BE16(&prP2pDevName->u2Length, &prP2pDesc->u2NameLength); -+ if (prP2pDesc->u2NameLength > WPS_ATTRI_MAX_LEN_DEVICE_NAME) -+ prP2pDesc->u2NameLength = WPS_ATTRI_MAX_LEN_DEVICE_NAME; -+ -+ kalMemCopy(prP2pDesc->aucName, prP2pDevName->aucName, prP2pDesc->u2NameLength); -+ -+ u2AttributeLen -= (prClientInfoDesc->ucLength + P2P_CLIENT_INFO_DESC_HDR_LEN); -+ prClientInfoDesc = -+ (P_P2P_CLIENT_INFO_DESC_T) ((UINT_32) prClientInfoDesc + -+ (UINT_32) prClientInfoDesc->ucLength + -+ P2P_CLIENT_INFO_DESC_HDR_LEN); -+ } -+ -+ scanRemoveInvalidP2pClientDevice(prAdapter, prBssDesc); -+ } -+ -+ return fgUpdateDevInfo; -+} /* end of scanAddP2pDeviceInfo() */ -+ -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Convert the Beacon or ProbeResp Frame in SW_RFB_T to Event Packet -+* -+* @param[in] prSwRfb Pointer to the receiving SW_RFB_T structure. -+* -+* @retval WLAN_STATUS_SUCCESS It is a valid Scan Result and been sent to the host. -+* @retval WLAN_STATUS_FAILURE It is not a valid Scan Result. -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS scanSendDeviceDiscoverEvent(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBssDesc, IN P_SW_RFB_T prSwRfb) -+{ -+ EVENT_P2P_DEV_DISCOVER_RESULT_T rEventDevInfo; -+#if 1 -+ P_LINK_ENTRY_T prLinkEntry = (P_LINK_ENTRY_T) NULL; -+ P_P2P_DEVICE_DESC_T prTargetDesc = (P_P2P_DEVICE_DESC_T) NULL; -+ -+ LINK_FOR_EACH(prLinkEntry, &prBssDesc->rP2pDeviceList) { -+ prTargetDesc = LINK_ENTRY(prLinkEntry, P2P_DEVICE_DESC_T, rLinkEntry); -+ -+ COPY_MAC_ADDR(rEventDevInfo.aucDeviceAddr, prTargetDesc->aucDeviceAddr); -+ COPY_MAC_ADDR(rEventDevInfo.aucInterfaceAddr, prTargetDesc->aucInterfaceAddr); -+ -+ rEventDevInfo.ucDeviceCapabilityBitmap = prTargetDesc->ucDeviceCapabilityBitmap; -+ rEventDevInfo.ucGroupCapabilityBitmap = prTargetDesc->ucGroupCapabilityBitmap; -+ rEventDevInfo.u2ConfigMethod = prTargetDesc->u2ConfigMethod; -+ -+ kalMemCopy(&rEventDevInfo.rPriDevType, &prTargetDesc->rPriDevType, sizeof(P2P_DEVICE_TYPE_T)); -+ -+ kalMemCopy(rEventDevInfo.arSecDevType, -+ prTargetDesc->arSecDevType, (prTargetDesc->ucSecDevTypeNum * sizeof(P2P_DEVICE_TYPE_T))); -+ -+ rEventDevInfo.ucSecDevTypeNum = prTargetDesc->ucSecDevTypeNum; -+ -+ rEventDevInfo.u2NameLength = prTargetDesc->u2NameLength; -+ kalMemCopy(rEventDevInfo.aucName, prTargetDesc->aucName, prTargetDesc->u2NameLength); -+ -+ COPY_MAC_ADDR(rEventDevInfo.aucBSSID, prBssDesc->aucBSSID); -+ -+ if (prTargetDesc == prBssDesc->prP2pDesc) -+ nicRxAddP2pDevice(prAdapter, &rEventDevInfo, prBssDesc->aucIEBuf, prBssDesc->u2IELength); -+ else -+ nicRxAddP2pDevice(prAdapter, &rEventDevInfo, NULL, 0); -+ } -+ -+ kalP2PIndicateFound(prAdapter->prGlueInfo); -+ -+#else -+ -+ P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo = (P_P2P_SPECIFIC_BSS_INFO_T) NULL; -+ P_P2P_ATTRIBUTE_T prP2pAttribute = (P_P2P_ATTRIBUTE_T) NULL; -+ UINT_16 u2AttributeLen = 0; -+ UINT_32 u4Idx = 0; -+ P_P2P_ATTRI_GROUP_INFO_T prP2pAttriGroupInfo = (P_P2P_ATTRI_GROUP_INFO_T) NULL; -+ P_DEVICE_NAME_TLV_T prP2pDevName = (P_DEVICE_NAME_TLV_T) NULL; -+ -+ ASSERT(prAdapter); -+ -+ prP2pSpecificBssInfo = &prAdapter->rWifiVar.rP2pSpecificBssInfo; -+ -+#if 1 -+ p2pGetP2PAttriList(prAdapter, prBssDesc->aucIEBuf, prBssDesc->u2IELength, (PPUINT_8) & prP2pAttribute, -+ &u2AttributeLen); -+#else -+ prP2pAttribute = (P_P2P_ATTRIBUTE_T) &prP2pSpecificBssInfo->aucAttributesCache[0]; -+ u2AttributeLen = prP2pSpecificBssInfo->u2AttributeLen; -+#endif -+ rEventDevInfo.fgDevInfoValid = FALSE; -+ -+ while (u2AttributeLen >= P2P_ATTRI_HDR_LEN) { -+ switch (prP2pAttribute->ucId) { -+ case P2P_ATTRI_ID_P2P_CAPABILITY: -+ { -+ P_P2P_ATTRI_CAPABILITY_T prP2pAttriCapability = (P_P2P_ATTRI_CAPABILITY_T) NULL; -+ -+ prP2pAttriCapability = (P_P2P_ATTRI_CAPABILITY_T) prP2pAttribute; -+ ASSERT(prP2pAttriCapability->u2Length == 2); -+ rEventDevInfo.ucDeviceCapabilityBitmap = prP2pAttriCapability->ucDeviceCap; -+ rEventDevInfo.ucGroupCapabilityBitmap = prP2pAttriCapability->ucGroupCap; -+ } -+ break; -+ case P2P_ATTRI_ID_P2P_DEV_ID: -+ { -+ P_P2P_ATTRI_DEV_ID_T prP2pAttriDevID = (P_P2P_ATTRI_DEV_ID_T) NULL; -+ -+ prP2pAttriDevID = (P_P2P_ATTRI_DEV_ID_T) prP2pAttribute; -+ ASSERT(prP2pAttriDevID->u2Length == 6); -+ kalMemCopy(rEventDevInfo.aucCommunicateAddr, prP2pAttriDevID->aucDevAddr, MAC_ADDR_LEN); -+ } -+ break; -+ case P2P_ATTRI_ID_P2P_DEV_INFO: -+ { -+ P_P2P_ATTRI_DEV_INFO_T prP2pAttriDevInfo = (P_P2P_ATTRI_DEV_INFO_T) NULL; -+ P_P2P_DEVICE_TYPE_T prP2pDevType = (P_P2P_DEVICE_TYPE_T) NULL; -+ -+ prP2pAttriDevInfo = (P_P2P_ATTRI_DEV_INFO_T) prP2pAttribute; -+ rEventDevInfo.fgDevInfoValid = TRUE; -+ kalMemCopy(rEventDevInfo.aucCommunicateAddr, prP2pAttriDevInfo->aucDevAddr, -+ MAC_ADDR_LEN); -+ rEventDevInfo.u2ConfigMethod = prP2pAttriDevInfo->u2ConfigMethodsBE; -+ -+ prP2pDevType = &rEventDevInfo.rPriDevType; -+ prP2pDevType->u2CategoryID = prP2pAttriDevInfo->rPrimaryDevTypeBE.u2CategoryId; -+ prP2pDevType->u2SubCategoryID = prP2pAttriDevInfo->rPrimaryDevTypeBE.u2SubCategoryId; -+ -+ ASSERT(prP2pAttriDevInfo->ucNumOfSecondaryDevType <= 2); -+ /* TODO: Fixme if secondary device type is more than 2. */ -+ for (u4Idx = 0; u4Idx < prP2pAttriDevInfo->ucNumOfSecondaryDevType; u4Idx++) { -+ /* TODO: Current sub device type can only support 2. */ -+ prP2pDevType = &rEventDevInfo.arSecDevType[u4Idx]; -+ prP2pDevType->u2CategoryID = prP2pAttriDevInfo->rPrimaryDevTypeBE.u2CategoryId; -+ prP2pDevType->u2SubCategoryID = -+ prP2pAttriDevInfo->rPrimaryDevTypeBE.u2SubCategoryId; -+ } -+ -+ prP2pDevName = -+ (P_DEVICE_NAME_TLV_T) (prP2pAttriDevInfo->arSecondaryDevTypeListBE + -+ (u4Idx * sizeof(DEVICE_TYPE_T))); -+ ASSERT(prP2pDevName->u2Id == 0x1011); -+ ASSERT(prP2pDevName->u2Length <= 32); -+ /* TODO: Fixme if device name length is longer than 32 bytes. */ -+ kalMemCopy(rEventDevInfo.aucName, prP2pDevName->aucName, prP2pDevName->u2Length); -+ } -+ break; -+ case P2P_ATTRI_ID_P2P_GROUP_INFO: -+ prP2pAttriGroupInfo = (P_P2P_ATTRI_GROUP_INFO_T) prP2pAttribute; -+ break; -+ } -+ -+ u2AttributeLen -= (prP2pAttribute->u2Length + P2P_ATTRI_HDR_LEN); -+ -+ prP2pAttribute = -+ (P_P2P_ATTRIBUTE_T) ((UINT_32) prP2pAttribute + (prP2pAttribute->u2Length + P2P_ATTRI_HDR_LEN)); -+ -+ } -+ -+ nicRxAddP2pDevice(prAdapter, &rEventDevInfo); -+ -+ if (prP2pAttriGroupInfo != NULL) { -+ P_P2P_CLIENT_INFO_DESC_T prClientInfoDesc = (P_P2P_CLIENT_INFO_DESC_T) NULL; -+ P_P2P_DEVICE_TYPE_T prP2pDevType = (P_P2P_DEVICE_TYPE_T) NULL; -+ -+ prClientInfoDesc = prP2pAttriGroupInfo->arClientDesc; -+ u2AttributeLen = prP2pAttriGroupInfo->u2Length; -+ -+ while (u2AttributeLen > 0) { -+ /* Basic size for P2P client info descriptor. */ -+ ASSERT(u2AttributeLen >= 25); -+ rEventDevInfo.fgDevInfoValid = TRUE; -+ kalMemCopy(rEventDevInfo.aucCommunicateAddr, prClientInfoDesc->aucIfAddr, MAC_ADDR_LEN); -+ rEventDevInfo.ucDeviceCapabilityBitmap = prClientInfoDesc->ucDeviceCap; -+ rEventDevInfo.u2ConfigMethod = prClientInfoDesc->u2ConfigMethodsBE; -+ -+ prP2pDevType = &rEventDevInfo.rPriDevType; -+ prP2pDevType->u2CategoryID = prClientInfoDesc->rPrimaryDevTypeBE.u2CategoryId; -+ prP2pDevType->u2SubCategoryID = prClientInfoDesc->rPrimaryDevTypeBE.u2SubCategoryId; -+ -+ ASSERT(prClientInfoDesc->ucNumOfSecondaryDevType <= 2); -+ /* TODO: Fixme if secondary device type is more than 2. */ -+ for (u4Idx = 0; u4Idx < prClientInfoDesc->ucNumOfSecondaryDevType; u4Idx++) { -+ /* TODO: Current sub device type can only support 2. */ -+ prP2pDevType = &rEventDevInfo.arSecDevType[u4Idx]; -+ prP2pDevType->u2CategoryID = -+ prClientInfoDesc->arSecondaryDevTypeListBE[u4Idx].u2CategoryId; -+ prP2pDevType->u2SubCategoryID = -+ prClientInfoDesc->arSecondaryDevTypeListBE[u4Idx].u2SubCategoryId; -+ } -+ -+ prP2pDevName = -+ (P_DEVICE_NAME_TLV_T) (prClientInfoDesc->arSecondaryDevTypeListBE + -+ (u4Idx * sizeof(DEVICE_TYPE_T))); -+ ASSERT(prP2pDevName->u2Id == 0x1011); -+ ASSERT(prP2pDevName->u2Length <= 32); -+ /* TODO: Fixme if device name length is longer than 32 bytes. */ -+ kalMemCopy(&rEventDevInfo.aucName, prP2pDevName->aucName, prP2pDevName->u2Length); -+ -+ nicRxAddP2pDevice(prAdapter, &rEventDevInfo); -+ -+ u2AttributeLen -= prP2pAttriGroupInfo->u2Length; -+ prP2pAttriGroupInfo = prP2pAttriGroupInfo + prP2pAttriGroupInfo->u2Length + 1; -+ } -+ -+ } -+#endif -+ return WLAN_STATUS_SUCCESS; -+} /* scanSendDeviceDiscoverEvent */ -+ -+VOID -+scanP2pProcessBeaconAndProbeResp(IN P_ADAPTER_T prAdapter, -+ IN P_SW_RFB_T prSwRfb, -+ IN P_WLAN_STATUS prStatus, -+ IN P_BSS_DESC_T prBssDesc, IN P_WLAN_BEACON_FRAME_T prWlanBeaconFrame) -+{ -+ BOOLEAN fgIsSkipThisBeacon; -+ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; -+ P_P2P_CONNECTION_SETTINGS_T prP2pConnSettings = (P_P2P_CONNECTION_SETTINGS_T) NULL; -+ -+ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); -+ prP2pConnSettings = prAdapter->rWifiVar.prP2PConnSettings; -+ fgIsSkipThisBeacon = FALSE; -+ if (prBssDesc->fgIsP2PPresent) { -+ if ((prP2pBssInfo->eCurrentOPMode == OP_MODE_INFRASTRUCTURE) && /* P2P GC */ -+ (prP2pBssInfo->eConnectionState == PARAM_MEDIA_STATE_CONNECTED) && /* Connected */ -+ ((prWlanBeaconFrame->u2FrameCtrl & MASK_FRAME_TYPE) == MAC_FRAME_BEACON)) { /* TX Beacon */ -+ -+ fgIsSkipThisBeacon = TRUE; -+ } -+ -+ if ((!prP2pBssInfo->ucDTIMPeriod) && /* First time. */ -+ fgIsSkipThisBeacon && (EQUAL_SSID(prBssDesc->aucSSID, prBssDesc->ucSSIDLen, -+ prP2pConnSettings->aucSSID, prP2pConnSettings->ucSSIDLen))) { /* SSID Match */ -+ prP2pBssInfo->ucDTIMPeriod = prBssDesc->ucDTIMPeriod; -+ nicPmIndicateBssConnected(prAdapter, NETWORK_TYPE_P2P_INDEX); -+ } -+ -+ do { -+ RF_CHANNEL_INFO_T rChannelInfo; -+ -+ ASSERT_BREAK((prSwRfb != NULL) && (prBssDesc != NULL)); -+ -+ if (((prWlanBeaconFrame->u2FrameCtrl & MASK_FRAME_TYPE) != MAC_FRAME_PROBE_RSP)) { -+ /* Only report Probe Response frame to supplicant. */ -+ /* Probe response collect much more information. */ -+ -+ if (fgIsSkipThisBeacon || prBssDesc->eBand == BAND_2G4) -+ break; -+ } -+ -+ rChannelInfo.ucChannelNum = prBssDesc->ucChannelNum; -+ rChannelInfo.eBand = prBssDesc->eBand; -+ prBssDesc->fgIsP2PReport = TRUE; -+ -+ DBGLOG(P2P, INFO, "indicate %s [%d]\n", prBssDesc->aucSSID, prBssDesc->ucChannelNum); -+ -+ kalP2PIndicateBssInfo(prAdapter->prGlueInfo, -+ (PUINT_8) prSwRfb->pvHeader, -+ (UINT_32) prSwRfb->u2PacketLen, -+ &rChannelInfo, RCPI_TO_dBm(prBssDesc->ucRCPI)); -+ -+ } while (FALSE); -+ } -+} -+ -+VOID scnEventReturnChannel(IN P_ADAPTER_T prAdapter, IN UINT_8 ucScnSeqNum) -+{ -+ -+ CMD_SCAN_CANCEL rCmdScanCancel; -+ -+ /* send cancel message to firmware domain */ -+ rCmdScanCancel.ucSeqNum = ucScnSeqNum; -+ rCmdScanCancel.ucIsExtChannel = (UINT_8) FALSE; -+ -+ wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SCAN_CANCEL, -+ TRUE, -+ FALSE, FALSE, NULL, NULL, sizeof(CMD_SCAN_CANCEL), (PUINT_8)&rCmdScanCancel, NULL, 0); -+ -+} /* scnEventReturnChannel */ -+ -+VOID scanRemoveAllP2pBssDesc(IN P_ADAPTER_T prAdapter) -+{ -+ P_LINK_T prBSSDescList; -+ P_BSS_DESC_T prBssDesc; -+ P_BSS_DESC_T prBSSDescNext; -+ -+ ASSERT(prAdapter); -+ -+ prBSSDescList = &(prAdapter->rWifiVar.rScanInfo.rBSSDescList); -+ -+ /* Search BSS Desc from current SCAN result list. */ -+ LINK_FOR_EACH_ENTRY_SAFE(prBssDesc, prBSSDescNext, prBSSDescList, rLinkEntry, BSS_DESC_T) { -+ scanRemoveP2pBssDesc(prAdapter, prBssDesc); -+ } -+} /* scanRemoveAllP2pBssDesc */ -+ -+VOID scanRemoveP2pBssDesc(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBssDesc) -+{ -+ -+ -+} /* scanRemoveP2pBssDesc */ -+ -+P_BSS_DESC_T -+scanP2pSearchDesc(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prP2pBssInfo, IN P_P2P_CONNECTION_REQ_INFO_T prConnReqInfo) -+{ -+ P_BSS_DESC_T prCandidateBssDesc = (P_BSS_DESC_T) NULL, prBssDesc = (P_BSS_DESC_T) NULL; -+ P_LINK_T prBssDescList = (P_LINK_T) NULL; -+ -+ do { -+ if ((prAdapter == NULL) || (prP2pBssInfo == NULL) || (prConnReqInfo == NULL)) -+ break; -+ -+ prBssDescList = &(prAdapter->rWifiVar.rScanInfo.rBSSDescList); -+ -+ DBGLOG(P2P, LOUD, "Connecting to BSSID: %pM\n", prConnReqInfo->aucBssid); -+ DBGLOG(P2P, LOUD, "Connecting to SSID:%s, length:%d\n", -+ prConnReqInfo->rSsidStruct.aucSsid, prConnReqInfo->rSsidStruct.ucSsidLen); -+ -+ LINK_FOR_EACH_ENTRY(prBssDesc, prBssDescList, rLinkEntry, BSS_DESC_T) { -+ DBGLOG(P2P, LOUD, "Checking BSS: %pM\n", prBssDesc->aucBSSID); -+ -+ if (prBssDesc->eBSSType != BSS_TYPE_INFRASTRUCTURE) { -+ DBGLOG(P2P, LOUD, "Ignore mismatch BSS type.\n"); -+ continue; -+ } -+ -+ if (UNEQUAL_MAC_ADDR(prBssDesc->aucBSSID, prConnReqInfo->aucBssid)) { -+ DBGLOG(P2P, LOUD, "Ignore mismatch BSSID.\n"); -+ continue; -+ } -+ -+ /* SSID should be the same? SSID is vary for each connection. so... */ -+ if (UNEQUAL_SSID(prConnReqInfo->rSsidStruct.aucSsid, -+ prConnReqInfo->rSsidStruct.ucSsidLen, -+ prBssDesc->aucSSID, prBssDesc->ucSSIDLen)) { -+ -+ DBGLOG(P2P, TRACE, -+ "Connecting to BSSID: %pM\n", prConnReqInfo->aucBssid); -+ DBGLOG(P2P, TRACE, -+ "Connecting to SSID:%s, length:%d\n", prConnReqInfo->rSsidStruct.aucSsid, -+ prConnReqInfo->rSsidStruct.ucSsidLen); -+ DBGLOG(P2P, TRACE, -+ "Checking SSID:%s, length:%d\n", prBssDesc->aucSSID, prBssDesc->ucSSIDLen); -+ DBGLOG(P2P, TRACE, "Ignore mismatch SSID, (But BSSID match).\n"); -+ ASSERT(FALSE); -+ continue; -+ } -+ -+ if (!prBssDesc->fgIsP2PPresent) { -+ DBGLOG(P2P, ERROR, "SSID, BSSID, BSSTYPE match, but no P2P IE present.\n"); -+ continue; -+ } -+ -+ /* Final decision. */ -+ prCandidateBssDesc = prBssDesc; -+ break; -+ } -+ -+ } while (FALSE); -+ -+ return prCandidateBssDesc; -+} /* scanP2pSearchDesc */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_state.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_state.c -new file mode 100644 -index 000000000000..befb9978f473 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_state.c -@@ -0,0 +1,466 @@ -+#include "p2p_precomp.h" -+ -+BOOLEAN -+p2pStateInit_IDLE(IN P_ADAPTER_T prAdapter, -+ IN P_P2P_FSM_INFO_T prP2pFsmInfo, IN P_BSS_INFO_T prP2pBssInfo, OUT P_ENUM_P2P_STATE_T peNextState) -+{ -+ BOOLEAN fgIsTransOut = FALSE; -+/* P_P2P_CHNL_REQ_INFO_T prChnlReqInfo = (P_P2P_CHNL_REQ_INFO_T)NULL; */ -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && -+ (prP2pFsmInfo != NULL) && (prP2pBssInfo != NULL) && (peNextState != NULL)); -+ -+ if ((prP2pBssInfo->eIntendOPMode == OP_MODE_ACCESS_POINT) -+ && IS_NET_PWR_STATE_ACTIVE(prAdapter, NETWORK_TYPE_P2P_INDEX)) { -+ P_P2P_CHNL_REQ_INFO_T prChnlReqInfo = &(prP2pFsmInfo->rChnlReqInfo); -+ -+ fgIsTransOut = TRUE; -+ prChnlReqInfo->eChannelReqType = CHANNEL_REQ_TYPE_GO_START_BSS; -+ -+ DBGLOG(P2P, INFO, "p2pStateInit_IDLE GO Scan\n"); -+ *peNextState = P2P_STATE_REQING_CHANNEL; -+ -+ } else { -+#if 0 -+ else -+ if (IS_NET_PWR_STATE_ACTIVE(prAdapter, NETWORK_TYPE_P2P_INDEX)) { -+ -+ ASSERT((prP2pBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT) || -+ (prP2pBssInfo->eCurrentOPMode == OP_MODE_INFRASTRUCTURE)); -+ -+ prChnlReqInfo = &prP2pFsmInfo->rChnlReqInfo; -+ -+ if (prChnlReqInfo->fgIsChannelRequested) { -+ /* Start a timer for return channel. */ -+ DBGLOG(P2P, TRACE, "start a GO channel timer.\n"); -+ } -+ -+ } -+#endif -+ cnmTimerStartTimer(prAdapter, &(prAdapter->rP2pFsmTimeoutTimer), 5000); -+ } -+ -+ } while (FALSE); -+ -+ return fgIsTransOut; -+} /* p2pStateInit_IDLE */ -+ -+VOID p2pStateAbort_IDLE(IN P_ADAPTER_T prAdapter, IN P_P2P_FSM_INFO_T prP2pFsmInfo, IN ENUM_P2P_STATE_T eNextState) -+{ -+ -+ P_P2P_CHNL_REQ_INFO_T prChnlReqInfo = (P_P2P_CHNL_REQ_INFO_T) NULL; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prP2pFsmInfo != NULL)); -+ -+ prChnlReqInfo = &prP2pFsmInfo->rChnlReqInfo; -+ -+ if (prChnlReqInfo->fgIsChannelRequested) { -+ /* Release channel before timeout. */ -+ p2pFuncReleaseCh(prAdapter, prChnlReqInfo); -+ } -+ -+ /* Stop timer for leaving this state. */ -+ cnmTimerStopTimer(prAdapter, &(prAdapter->rP2pFsmTimeoutTimer)); -+ -+ } while (FALSE); -+ -+} /* p2pStateAbort_IDLE */ -+ -+VOID p2pStateInit_CHNL_ON_HAND(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prP2pBssInfo, IN P_P2P_FSM_INFO_T prP2pFsmInfo) -+{ -+ P_P2P_CHNL_REQ_INFO_T prChnlReqInfo = (P_P2P_CHNL_REQ_INFO_T) NULL; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prP2pFsmInfo != NULL)); -+ -+ prChnlReqInfo = &(prP2pFsmInfo->rChnlReqInfo); -+ -+ /* Store the original channel info. */ -+ prChnlReqInfo->ucOriChnlNum = prP2pBssInfo->ucPrimaryChannel; -+ prChnlReqInfo->eOriBand = prP2pBssInfo->eBand; -+ prChnlReqInfo->eOriChnlSco = prP2pBssInfo->eBssSCO; -+ -+ /* RX Probe Request would check primary channel. */ -+ prP2pBssInfo->ucPrimaryChannel = prChnlReqInfo->ucReqChnlNum; -+ prP2pBssInfo->eBand = prChnlReqInfo->eBand; -+ prP2pBssInfo->eBssSCO = prChnlReqInfo->eChnlSco; -+ -+ DBGLOG(P2P, TRACE, "start a channel on hand timer.\n"); -+ if (prP2pFsmInfo->eListenExted != P2P_DEV_EXT_LISTEN_ING) { -+ cnmTimerStartTimer(prAdapter, &(prAdapter->rP2pFsmTimeoutTimer), -+ prChnlReqInfo->u4MaxInterval); -+ -+ kalP2PIndicateChannelReady(prAdapter->prGlueInfo, -+ prChnlReqInfo->u8Cookie, -+ prChnlReqInfo->ucReqChnlNum, -+ prChnlReqInfo->eBand, prChnlReqInfo->eChnlSco, prChnlReqInfo->u4MaxInterval); -+ } else -+ cnmTimerStartTimer(prAdapter, &(prAdapter->rP2pFsmTimeoutTimer), -+ (P2P_EXT_LISTEN_TIME_MS - prChnlReqInfo->u4MaxInterval)); -+ } while (FALSE); -+ -+} /* p2pStateInit_CHNL_ON_HAND */ -+ -+VOID -+p2pStateAbort_CHNL_ON_HAND(IN P_ADAPTER_T prAdapter, -+ IN P_P2P_FSM_INFO_T prP2pFsmInfo, -+ IN P_BSS_INFO_T prP2pBssInfo, IN ENUM_P2P_STATE_T eNextState) -+{ -+ P_P2P_CHNL_REQ_INFO_T prChnlReqInfo = (P_P2P_CHNL_REQ_INFO_T) NULL; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prP2pFsmInfo != NULL)); -+ -+ prChnlReqInfo = &(prP2pFsmInfo->rChnlReqInfo); -+ -+ cnmTimerStopTimer(prAdapter, &(prAdapter->rP2pFsmTimeoutTimer)); -+ -+ /* Restore the original channel info. */ -+ prP2pBssInfo->ucPrimaryChannel = prChnlReqInfo->ucOriChnlNum; -+ prP2pBssInfo->eBand = prChnlReqInfo->eOriBand; -+ prP2pBssInfo->eBssSCO = prChnlReqInfo->eOriChnlSco; -+ -+ DBGLOG(P2P, INFO, "p2p state trans abort chann on hand, eListenExted: %d, eNextState: %d\n", -+ prP2pFsmInfo->eListenExted, eNextState); -+ if (prP2pFsmInfo->eListenExted != P2P_DEV_EXT_LISTEN_ING || -+ eNextState != P2P_STATE_CHNL_ON_HAND) { -+ /* Here maybe have a bug, when it's extlistening, a new remain_on_channel -+ was sent to driver? need to verify */ -+ prP2pFsmInfo->eListenExted = P2P_DEV_NOT_EXT_LISTEN; -+ /* Indicate channel return. */ -+ kalP2PIndicateChannelExpired(prAdapter->prGlueInfo, &prP2pFsmInfo->rChnlReqInfo); -+ -+ /* Return Channel. */ -+ p2pFuncReleaseCh(prAdapter, &(prP2pFsmInfo->rChnlReqInfo)); -+ } -+ -+ } while (FALSE); -+} /* p2pStateAbort_CHNL_ON_HAND */ -+ -+VOID -+p2pStateAbort_REQING_CHANNEL(IN P_ADAPTER_T prAdapter, IN P_P2P_FSM_INFO_T prP2pFsmInfo, IN ENUM_P2P_STATE_T eNextState) -+{ -+ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; -+ P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo = (P_P2P_SPECIFIC_BSS_INFO_T) NULL; -+ -+ do { -+ -+ ASSERT_BREAK((prAdapter != NULL) && (prP2pFsmInfo != NULL) && (eNextState < P2P_STATE_NUM)); -+ -+ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); -+ prP2pSpecificBssInfo = prAdapter->rWifiVar.prP2pSpecificBssInfo; -+ -+ if (eNextState == P2P_STATE_IDLE) { -+ if (prP2pBssInfo->eIntendOPMode == OP_MODE_ACCESS_POINT) { -+ /* Intend to be AP. */ -+ /* Setup for AP mode. */ -+ p2pFuncStartGO(prAdapter, -+ prP2pBssInfo, -+ prP2pSpecificBssInfo->aucGroupSsid, -+ prP2pSpecificBssInfo->u2GroupSsidLen, -+ prP2pSpecificBssInfo->ucPreferredChannel, -+ prP2pSpecificBssInfo->eRfBand, -+ prP2pSpecificBssInfo->eRfSco, prP2pFsmInfo->fgIsApMode); -+ -+ } else { -+ /* Return Channel. */ -+ p2pFuncReleaseCh(prAdapter, &(prP2pFsmInfo->rChnlReqInfo)); -+ } -+ -+ } -+ -+ } while (FALSE); -+ -+} /* p2pStateInit_AP_CHANNEL_DETECT */ -+ -+VOID p2pStateInit_AP_CHANNEL_DETECT(IN P_ADAPTER_T prAdapter, IN P_P2P_FSM_INFO_T prP2pFsmInfo) -+{ -+ P_P2P_SCAN_REQ_INFO_T prScanReqInfo = (P_P2P_SCAN_REQ_INFO_T) NULL; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prP2pFsmInfo != NULL)); -+ -+ prScanReqInfo = &(prP2pFsmInfo->rScanReqInfo); -+ -+ prScanReqInfo->eScanType = SCAN_TYPE_PASSIVE_SCAN; -+ prScanReqInfo->eChannelSet = SCAN_CHANNEL_2G4; -+ prScanReqInfo->u2PassiveDewellTime = 50; /* 50ms for passive channel load detection */ -+ prScanReqInfo->fgIsAbort = TRUE; -+ prScanReqInfo->fgIsScanRequest = TRUE; -+ prScanReqInfo->ucNumChannelList = 0; -+ prScanReqInfo->u4BufLength = 0; -+ prScanReqInfo->rSsidStruct.ucSsidLen = 0; -+ -+ p2pFuncRequestScan(prAdapter, prScanReqInfo); -+ -+ } while (FALSE); -+ -+} /* p2pStateInit_AP_CHANNEL_DETECT */ -+ -+VOID -+p2pStateAbort_AP_CHANNEL_DETECT(IN P_ADAPTER_T prAdapter, -+ IN P_P2P_FSM_INFO_T prP2pFsmInfo, -+ IN P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo, IN ENUM_P2P_STATE_T eNextState) -+{ -+ P_P2P_CHNL_REQ_INFO_T prChnlReqInfo = (P_P2P_CHNL_REQ_INFO_T) NULL; -+ P_P2P_CONNECTION_SETTINGS_T prP2pConnSettings = (P_P2P_CONNECTION_SETTINGS_T) NULL; -+ -+ do { -+ -+ if (eNextState == P2P_STATE_REQING_CHANNEL) { -+ UINT_8 ucPreferedChnl = 0; -+ ENUM_BAND_T eBand = BAND_NULL; -+ ENUM_CHNL_EXT_T eSco = CHNL_EXT_SCN; -+ -+ prChnlReqInfo = &(prP2pFsmInfo->rChnlReqInfo); -+ -+ /* Determine the channel for AP. */ -+ if (cnmPreferredChannel(prAdapter, &eBand, &ucPreferedChnl, &eSco) == FALSE) { -+ -+ prP2pConnSettings = prAdapter->rWifiVar.prP2PConnSettings; -+ ucPreferedChnl = prP2pConnSettings->ucOperatingChnl; -+ if (ucPreferedChnl == 0) { -+ -+ if (scnQuerySparseChannel(prAdapter, &eBand, &ucPreferedChnl) == FALSE) { -+ -+ /* What to do? */ -+ ASSERT(FALSE); -+ /* TODO: Pick up a valid channel from channel list. */ -+ ucPreferedChnl = 1; -+ eBand = BAND_2G4; -+ } -+ } -+ } -+ -+ prChnlReqInfo->eChannelReqType = CHANNEL_REQ_TYPE_GO_START_BSS; -+ -+ DBGLOG(P2P, INFO, "p2pStateAbort_AP_CHANNEL_DETECT GO Scan\n"); -+ prChnlReqInfo->ucReqChnlNum = prP2pSpecificBssInfo->ucPreferredChannel = ucPreferedChnl; -+ prChnlReqInfo->eBand = prP2pSpecificBssInfo->eRfBand = eBand; -+ prChnlReqInfo->eChnlSco = prP2pSpecificBssInfo->eRfSco = eSco; -+ } else { -+ p2pFuncCancelScan(prAdapter, &(prP2pFsmInfo->rScanReqInfo)); -+ } -+ -+ } while (FALSE); -+ -+} /* p2pStateAbort_AP_CHANNEL_DETECT */ -+ -+VOID p2pStateInit_SCAN(IN P_ADAPTER_T prAdapter, IN P_P2P_FSM_INFO_T prP2pFsmInfo) -+{ -+ P_P2P_SCAN_REQ_INFO_T prScanReqInfo = (P_P2P_SCAN_REQ_INFO_T) NULL; -+ -+ do { -+ -+ ASSERT_BREAK((prAdapter != NULL) && (prP2pFsmInfo != NULL)); -+ -+ prScanReqInfo = &prP2pFsmInfo->rScanReqInfo; -+ -+ prScanReqInfo->fgIsScanRequest = TRUE; -+ -+ p2pFuncRequestScan(prAdapter, prScanReqInfo); -+ -+ } while (FALSE); -+ -+} /* p2pStateInit_SCAN */ -+ -+VOID p2pStateAbort_SCAN(IN P_ADAPTER_T prAdapter, IN P_P2P_FSM_INFO_T prP2pFsmInfo, IN ENUM_P2P_STATE_T eNextState) -+{ -+ do { -+ ASSERT_BREAK(prAdapter != NULL); -+ -+ /* 1. Scan cancel. (Make sure the scan request is invalid. */ -+ p2pFuncCancelScan(prAdapter, &(prP2pFsmInfo->rScanReqInfo)); -+ -+ /* Scan done indication. */ -+ kalP2PIndicateScanDone(prAdapter->prGlueInfo, prP2pFsmInfo->rScanReqInfo.fgIsAbort); -+ } while (FALSE); -+ -+} /* p2pStateAbort_SCAN */ -+ -+VOID -+p2pStateInit_GC_JOIN(IN P_ADAPTER_T prAdapter, -+ IN P_P2P_FSM_INFO_T prP2pFsmInfo, -+ IN P_BSS_INFO_T prP2pBssInfo, IN P_P2P_JOIN_INFO_T prJoinInfo, IN P_BSS_DESC_T prBssDesc) -+{ -+ P_MSG_JOIN_REQ_T prJoinReqMsg = (P_MSG_JOIN_REQ_T) NULL; -+ P_STA_RECORD_T prStaRec = (P_STA_RECORD_T) NULL; -+ P_P2P_CONNECTION_SETTINGS_T prP2pConnSettings = (P_P2P_CONNECTION_SETTINGS_T) NULL; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && -+ (prP2pFsmInfo != NULL) && -+ (prP2pBssInfo != NULL) && (prJoinInfo != NULL) && (prBssDesc != NULL)); -+ -+ prP2pConnSettings = prAdapter->rWifiVar.prP2PConnSettings; -+ -+ if (prBssDesc->ucSSIDLen) { -+ COPY_SSID(prP2pConnSettings->aucSSID, -+ prP2pConnSettings->ucSSIDLen, prBssDesc->aucSSID, prBssDesc->ucSSIDLen); -+ } -+ /* Setup a join timer. */ -+ DBGLOG(P2P, TRACE, "Start a join init timer\n"); -+ cnmTimerStartTimer(prAdapter, -+ &(prAdapter->rP2pFsmTimeoutTimer), -+ (prP2pFsmInfo->u4GrantInterval - AIS_JOIN_CH_GRANT_THRESHOLD)); -+ -+ /* 2 <1> We are goin to connect to this BSS */ -+ prBssDesc->fgIsConnecting = TRUE; -+ -+ /* 2 <2> Setup corresponding STA_RECORD_T */ -+ prStaRec = bssCreateStaRecFromBssDesc(prAdapter, -+ (prBssDesc->fgIsP2PPresent ? (STA_TYPE_P2P_GO) -+ : (STA_TYPE_LEGACY_AP)), NETWORK_TYPE_P2P_INDEX, prBssDesc); -+ -+ if (prStaRec == NULL) { -+ DBGLOG(P2P, TRACE, "Create station record fail\n"); -+ break; -+ } -+ -+ prJoinInfo->prTargetStaRec = prStaRec; -+ prJoinInfo->fgIsJoinComplete = FALSE; -+ prJoinInfo->u4BufLength = 0; -+ -+ /* 2 <2.1> Sync. to FW domain */ -+ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); -+ -+ if (prP2pBssInfo->eConnectionState == PARAM_MEDIA_STATE_DISCONNECTED) { -+ P_P2P_CONNECTION_SETTINGS_T prP2pConnSettings = (P_P2P_CONNECTION_SETTINGS_T) NULL; -+ -+ prStaRec->fgIsReAssoc = FALSE; -+ -+ prP2pConnSettings = prAdapter->rWifiVar.prP2PConnSettings; -+ -+ switch (prP2pConnSettings->eAuthMode) { -+ case AUTH_MODE_OPEN: /* Note: Omit break here. */ -+ case AUTH_MODE_WPA: -+ case AUTH_MODE_WPA_PSK: -+ case AUTH_MODE_WPA2: -+ case AUTH_MODE_WPA2_PSK: -+ prJoinInfo->ucAvailableAuthTypes = (UINT_8) AUTH_TYPE_OPEN_SYSTEM; -+ break; -+ case AUTH_MODE_SHARED: -+ prJoinInfo->ucAvailableAuthTypes = (UINT_8) AUTH_TYPE_SHARED_KEY; -+ break; -+ case AUTH_MODE_AUTO_SWITCH: -+ DBGLOG(P2P, LOUD, "JOIN INIT: eAuthMode == AUTH_MODE_AUTO_SWITCH\n"); -+ prJoinInfo->ucAvailableAuthTypes = (UINT_8) (AUTH_TYPE_OPEN_SYSTEM | -+ AUTH_TYPE_SHARED_KEY); -+ break; -+ default: -+ ASSERT(!(prP2pConnSettings->eAuthMode == AUTH_MODE_WPA_NONE)); -+ DBGLOG(P2P, ERROR, "JOIN INIT: Auth Algorithm : %d was not supported by JOIN\n", -+ prP2pConnSettings->eAuthMode); -+ /* TODO(Kevin): error handling ? */ -+ return; -+ } -+ prStaRec->ucTxAuthAssocRetryLimit = TX_AUTH_ASSOCI_RETRY_LIMIT; -+ } else { -+ ASSERT(FALSE); -+ /* TODO: Shall we considering ROAMIN case for P2P Device?. */ -+ } -+ -+ /* 2 <4> Use an appropriate Authentication Algorithm Number among the ucAvailableAuthTypes. */ -+ if (prJoinInfo->ucAvailableAuthTypes & (UINT_8) AUTH_TYPE_OPEN_SYSTEM) { -+ -+ DBGLOG(P2P, TRACE, "JOIN INIT: Try to do Authentication with AuthType == OPEN_SYSTEM.\n"); -+ -+ prJoinInfo->ucAvailableAuthTypes &= ~(UINT_8) AUTH_TYPE_OPEN_SYSTEM; -+ -+ prStaRec->ucAuthAlgNum = (UINT_8) AUTH_ALGORITHM_NUM_OPEN_SYSTEM; -+ } else if (prJoinInfo->ucAvailableAuthTypes & (UINT_8) AUTH_TYPE_SHARED_KEY) { -+ -+ DBGLOG(P2P, TRACE, "JOIN INIT: Try to do Authentication with AuthType == SHARED_KEY.\n"); -+ -+ prJoinInfo->ucAvailableAuthTypes &= ~(UINT_8) AUTH_TYPE_SHARED_KEY; -+ -+ prStaRec->ucAuthAlgNum = (UINT_8) AUTH_ALGORITHM_NUM_SHARED_KEY; -+ } else if (prJoinInfo->ucAvailableAuthTypes & (UINT_8) AUTH_TYPE_FAST_BSS_TRANSITION) { -+ -+ DBGLOG(P2P, TRACE, -+ "JOIN INIT: Try to do Authentication with AuthType == FAST_BSS_TRANSITION.\n"); -+ -+ prJoinInfo->ucAvailableAuthTypes &= ~(UINT_8) AUTH_TYPE_FAST_BSS_TRANSITION; -+ -+ prStaRec->ucAuthAlgNum = (UINT_8) AUTH_ALGORITHM_NUM_FAST_BSS_TRANSITION; -+ } else { -+ ASSERT(0); -+ } -+ -+ /* 4 <5> Overwrite Connection Setting for eConnectionPolicy == ANY (Used by Assoc Req) */ -+ if (prBssDesc->ucSSIDLen) { -+ COPY_SSID(prJoinInfo->rSsidStruct.aucSsid, -+ prJoinInfo->rSsidStruct.ucSsidLen, prBssDesc->aucSSID, prBssDesc->ucSSIDLen); -+ } -+ /* 2 <5> Backup desired channel. */ -+ -+ /* 2 <6> Send a Msg to trigger SAA to start JOIN process. */ -+ prJoinReqMsg = (P_MSG_JOIN_REQ_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_JOIN_REQ_T)); -+ -+ if (!prJoinReqMsg) { -+ DBGLOG(P2P, TRACE, "Allocation Join Message Fail\n"); -+ ASSERT(FALSE); -+ return; -+ } -+ -+ prJoinReqMsg->rMsgHdr.eMsgId = MID_P2P_SAA_FSM_START; -+ prJoinReqMsg->ucSeqNum = ++prJoinInfo->ucSeqNumOfReqMsg; -+ prJoinReqMsg->prStaRec = prStaRec; -+ -+ /* TODO: Consider fragmentation info in station record. */ -+ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prJoinReqMsg, MSG_SEND_METHOD_BUF); -+ -+ } while (FALSE); -+ -+} /* p2pStateInit_GC_JOIN */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Process of JOIN Abort. Leave JOIN State & Abort JOIN. -+* -+* @param (none) -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+p2pStateAbort_GC_JOIN(IN P_ADAPTER_T prAdapter, -+ IN P_P2P_FSM_INFO_T prP2pFsmInfo, IN P_P2P_JOIN_INFO_T prJoinInfo, IN ENUM_P2P_STATE_T eNextState) -+{ -+ P_MSG_JOIN_ABORT_T prJoinAbortMsg = (P_MSG_JOIN_ABORT_T) NULL; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prP2pFsmInfo != NULL) && (prJoinInfo != NULL)); -+ -+ if (prJoinInfo->fgIsJoinComplete == FALSE) { -+ -+ prJoinAbortMsg = -+ (P_MSG_JOIN_ABORT_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_JOIN_ABORT_T)); -+ if (!prJoinAbortMsg) { -+ DBGLOG(P2P, TRACE, "Fail to allocate join abort message buffer\n"); -+ ASSERT(FALSE); -+ return; -+ } -+ -+ prJoinAbortMsg->rMsgHdr.eMsgId = MID_P2P_SAA_FSM_ABORT; -+ prJoinAbortMsg->ucSeqNum = prJoinInfo->ucSeqNumOfReqMsg; -+ prJoinAbortMsg->prStaRec = prJoinInfo->prTargetStaRec; -+ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prJoinAbortMsg, MSG_SEND_METHOD_BUF); -+ -+ } -+ -+ /* Stop Join Timer. */ -+ cnmTimerStopTimer(prAdapter, &(prAdapter->rP2pFsmTimeoutTimer)); -+ -+ /* Release channel requested. */ -+ p2pFuncReleaseCh(prAdapter, &(prP2pFsmInfo->rChnlReqInfo)); -+ -+ } while (FALSE); -+ -+ return; -+ -+} /* p2pStateAbort_GC_JOIN */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/privacy.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/privacy.c -new file mode 100644 -index 000000000000..72fa52e761da ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/privacy.c -@@ -0,0 +1,915 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/privacy.c#1 -+*/ -+ -+/*! \file "privacy.c" -+ \brief This file including the protocol layer privacy function. -+ -+ This file provided the macros and functions library support for the -+ protocol layer security setting from rsn.c and nic_privacy.c -+ -+*/ -+ -+/* -+** Log: privacy.c -+ * -+ * 11 10 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * change the debug module level. -+ * -+ * 10 20 2011 terry.wu -+ * NULL -+ * Fix Hotspot deauth send failed. -+ * -+ * 10 12 2011 wh.su -+ * [WCXRP00001036] [MT6620 Wi-Fi][Driver][FW] Adding the 802.11w code for MFP -+ * adding the 802.11w related function and define . -+ * -+ * 06 28 2011 tsaiyuan.hsu -+ * [WCXRP00000819] [MT6620 Wi-Fi][Driver] check if staRec is NULL or not in secCheckClassError -+ * check if staRec is NULL or not in secCheckClassError. -+ * -+ * 06 09 2011 tsaiyuan.hsu -+ * [WCXRP00000760] [MT5931 Wi-Fi][FW] Refine rxmHandleMacRxDone to reduce code size -+ * move send_auth at rxmHandleMacRxDone in firmware to driver to reduce code size. -+ * -+ * 01 25 2011 yuche.tsai -+ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record. -+ * Change Station Type in Station Record, Modify MACRO definition for getting station type & network type index & Role. -+ * -+ * 11 04 2010 wh.su -+ * [WCXRP00000164] [MT6620 Wi-Fi][Driver] Support the p2p random SSID -+ * adding the p2p random ssid support. -+ * -+ * 10 04 2010 cp.wu -+ * [WCXRP00000077] [MT6620 Wi-Fi][Driver][FW] Eliminate use of ENUM_NETWORK_TYPE_T -+ * and replaced by ENUM_NETWORK_TYPE_INDEX_T only -+ * remove ENUM_NETWORK_TYPE_T definitions -+ * -+ * 09 03 2010 kevin.huang -+ * NULL -+ * Refine #include sequence and solve recursive/nested #include issue -+ * -+ * 09 01 2010 wh.su -+ * NULL -+ * adding the wapi support for integration test. -+ * -+ * 07 24 2010 wh.su -+ * -+ * .support the Wi-Fi RSN -+ * -+ * 07 20 2010 wh.su -+ * -+ * adding the wapi code. -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 21 2010 wh.su -+ * [WPD00003840][MT6620 5931] Security migration -+ * modify some code for concurrent network. -+ * -+ * 06 21 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * enable RX management frame handling. -+ * -+ * 06 19 2010 wh.su -+ * [WPD00003840][MT6620 5931] Security migration -+ * adding the compiling flag for migration. -+ * -+ * 06 19 2010 wh.su -+ * [WPD00003840][MT6620 5931] Security migration -+ * consdier the concurrent network setting. -+ * -+ * 06 18 2010 wh.su -+ * [WPD00003840][MT6620 5931] Security migration -+ * migration the security related function from firmware. -+ * -+ * 05 28 2010 wh.su -+ * [BORA00000626][MT6620] Refine the remove key flow for WHQL testing -+ * fixed the ad-hoc wpa-none send non-encrypted frame issue. -+ * -+ * 05 24 2010 kevin.huang -+ * [BORA00000794][WIFISYS][New Feature]Power Management Support -+ * Refine authSendAuthFrame() for NULL STA_RECORD_T case and minimum deauth interval. -+ * -+ * 04 29 2010 wh.su -+ * [BORA00000637][MT6620 Wi-Fi] [Bug] WPA2 pre-authentication timer not correctly initialize -+ * adjsut the pre-authentication code. -+ * -+ * 04 22 2010 wh.su -+ * [BORA00000626][MT6620] Refine the remove key flow for WHQL testing -+ * fixed the wpi same key id rx issue and fixed the remove wep key issue. -+ * -+ * 04 19 2010 kevin.huang -+ * [BORA00000714][WIFISYS][New Feature]Beacon Timeout Support -+ * Add Send Deauth for Class 3 Error and Leave Network Support -+ * -+ * 04 15 2010 wh.su -+ * [BORA00000680][MT6620] Support the statistic for Micxxsoft os query -+ * remove the assert code for allow ad-hoc pkt. -+ * -+ * 04 13 2010 wh.su -+ * [BORA00000680][MT6620] Support the statistic for Micxxsoft os query -+ * fixed the Klocwork error and refine the class error message. -+ * -+ * 03 04 2010 wh.su -+ * [BORA00000605][WIFISYS] Phase3 Integration -+ * Code refine, and remove non-used code. -+ * -+ * 03 03 2010 wh.su -+ * [BORA00000637][MT6620 Wi-Fi] [Bug] WPA2 pre-authentication timer not correctly initialize -+ * move the AIS specific variable for security to AIS specific structure. -+ * -+ * 03 03 2010 wh.su -+ * [BORA00000637][MT6620 Wi-Fi] [Bug] WPA2 pre-authentication timer not correctly initialize -+ * Fixed the pre-authentication timer not correctly init issue, -+ * and modify the security related callback function prototype. -+ * -+ * 03 01 2010 wh.su -+ * [BORA00000605][WIFISYS] Phase3 Integration -+ * Refine the variable and parameter for security. -+ * -+ * 02 26 2010 wh.su -+ * [BORA00000626][MT6620] Refine the remove key flow for WHQL testing -+ * change the waning message shown level, and clear the global transmit flag for CMD INFRASTRUCTURE. -+ * -+ * 02 25 2010 wh.su -+ * [BORA00000626][MT6620] Refine the remove key flow for WHQL testing -+ * For support the WHQL test, do the remove key code refine. -+ * -+ * 01 27 2010 wh.su -+ * [BORA00000476][Wi-Fi][firmware] Add the security module initialize code -+ * add and fixed some security function. -+ * -+ * 12 25 2009 tehuang.liu -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Integrated modifications for 1st connection (mainly on FW modules MQM, TXM, and RXM) -+ * * * * * * * * * MQM: BA handling -+ * * * * * * * * * TXM: Macros updates -+ * * * * * * * * * RXM: Macros/Duplicate Removal updates -+ * -+ * 12 18 2009 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * . -+ * -+ * Dec 11 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * modify the cmd with result return -+ * -+ * Dec 11 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * fixed the value not initialize issue -+ * -+ * Dec 10 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * change the cmd return type -+ * -+ * Dec 8 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * adding the function to update the auth mode and encryption status for cmd build connection -+ * -+ * Dec 7 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * adding some code for wapi mode -+ * -+ * Dec 7 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * adding the call to check the 4th and eapol error report frame -+ * -+ * Dec 7 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * rename the function name -+ * -+ * Dec 4 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * adding the code for parsing the EAPoL frame, and do some code refine -+ * -+ * Dec 3 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * adding the class error check -+ * -+ * Dec 3 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * adding the cmd_802_11_pmkid code -+ * -+ * Dec 1 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * doing some function rename, and adding the code for cmd CMD_ADD_REMOVE_KEY -+ * -+ * Nov 23 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * adding the clear pmkid function -+ * -+ * Nov 23 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Fix eStaType check for AIS -+ * -+ * Nov 19 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * adding the ap selection related code -+ * -+ * Nov 18 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "precomp.h" -+ -+#if CFG_PRIVACY_MIGRATION -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to initialize the privacy-related -+* parameters. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* \param[in] ucNetTypeIdx Pointer to netowrk type index -+* -+* \retval NONE -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID secInit(IN P_ADAPTER_T prAdapter, IN UINT_8 ucNetTypeIdx) -+{ -+ UINT_8 i; -+ P_CONNECTION_SETTINGS_T prConnSettings; -+ P_BSS_INFO_T prBssInfo; -+ P_AIS_SPECIFIC_BSS_INFO_T prAisSpecBssInfo; -+ -+ DEBUGFUNC("secInit"); -+ -+ ASSERT(prAdapter); -+ -+ prConnSettings = &prAdapter->rWifiVar.rConnSettings; -+ prBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]; -+ prAisSpecBssInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo; -+ -+ prBssInfo->u4RsnSelectedGroupCipher = 0; -+ prBssInfo->u4RsnSelectedPairwiseCipher = 0; -+ prBssInfo->u4RsnSelectedAKMSuite = 0; -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ prBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]; -+ -+ prBssInfo->u4RsnSelectedGroupCipher = RSN_CIPHER_SUITE_CCMP; -+ prBssInfo->u4RsnSelectedPairwiseCipher = RSN_CIPHER_SUITE_CCMP; -+ prBssInfo->u4RsnSelectedAKMSuite = RSN_AKM_SUITE_PSK; -+#endif -+ -+#if CFG_ENABLE_BT_OVER_WIFI -+ prBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_BOW_INDEX]; -+ -+ prBssInfo->u4RsnSelectedGroupCipher = RSN_CIPHER_SUITE_CCMP; -+ prBssInfo->u4RsnSelectedPairwiseCipher = RSN_CIPHER_SUITE_CCMP; -+ prBssInfo->u4RsnSelectedAKMSuite = RSN_AKM_SUITE_PSK; -+#endif -+ -+ prAdapter->rMib.dot11RSNAConfigPairwiseCiphersTable[0].dot11RSNAConfigPairwiseCipher = WPA_CIPHER_SUITE_WEP40; -+ prAdapter->rMib.dot11RSNAConfigPairwiseCiphersTable[1].dot11RSNAConfigPairwiseCipher = WPA_CIPHER_SUITE_TKIP; -+ prAdapter->rMib.dot11RSNAConfigPairwiseCiphersTable[2].dot11RSNAConfigPairwiseCipher = WPA_CIPHER_SUITE_CCMP; -+ prAdapter->rMib.dot11RSNAConfigPairwiseCiphersTable[3].dot11RSNAConfigPairwiseCipher = WPA_CIPHER_SUITE_WEP104; -+ -+ prAdapter->rMib.dot11RSNAConfigPairwiseCiphersTable[4].dot11RSNAConfigPairwiseCipher = RSN_CIPHER_SUITE_WEP40; -+ prAdapter->rMib.dot11RSNAConfigPairwiseCiphersTable[5].dot11RSNAConfigPairwiseCipher = RSN_CIPHER_SUITE_TKIP; -+ prAdapter->rMib.dot11RSNAConfigPairwiseCiphersTable[6].dot11RSNAConfigPairwiseCipher = RSN_CIPHER_SUITE_CCMP; -+ prAdapter->rMib.dot11RSNAConfigPairwiseCiphersTable[7].dot11RSNAConfigPairwiseCipher = RSN_CIPHER_SUITE_WEP104; -+ -+ for (i = 0; i < MAX_NUM_SUPPORTED_CIPHER_SUITES; i++) -+ prAdapter->rMib.dot11RSNAConfigPairwiseCiphersTable[i].dot11RSNAConfigPairwiseCipherEnabled = FALSE; -+ -+ prAdapter->rMib.dot11RSNAConfigAuthenticationSuitesTable[0].dot11RSNAConfigAuthenticationSuite = -+ WPA_AKM_SUITE_NONE; -+ prAdapter->rMib.dot11RSNAConfigAuthenticationSuitesTable[1].dot11RSNAConfigAuthenticationSuite = -+ WPA_AKM_SUITE_802_1X; -+ prAdapter->rMib.dot11RSNAConfigAuthenticationSuitesTable[2].dot11RSNAConfigAuthenticationSuite = -+ WPA_AKM_SUITE_PSK; -+ prAdapter->rMib.dot11RSNAConfigAuthenticationSuitesTable[3].dot11RSNAConfigAuthenticationSuite = -+ RSN_AKM_SUITE_NONE; -+ prAdapter->rMib.dot11RSNAConfigAuthenticationSuitesTable[4].dot11RSNAConfigAuthenticationSuite = -+ RSN_AKM_SUITE_802_1X; -+ prAdapter->rMib.dot11RSNAConfigAuthenticationSuitesTable[5].dot11RSNAConfigAuthenticationSuite = -+ RSN_AKM_SUITE_PSK; -+ -+#if CFG_SUPPORT_802_11W -+ prAdapter->rMib.dot11RSNAConfigAuthenticationSuitesTable[6].dot11RSNAConfigAuthenticationSuite = -+ RSN_AKM_SUITE_802_1X_SHA256; -+ prAdapter->rMib.dot11RSNAConfigAuthenticationSuitesTable[7].dot11RSNAConfigAuthenticationSuite = -+ RSN_AKM_SUITE_PSK_SHA256; -+#endif -+ -+ for (i = 0; i < MAX_NUM_SUPPORTED_AKM_SUITES; i++) { -+ prAdapter->rMib.dot11RSNAConfigAuthenticationSuitesTable[i].dot11RSNAConfigAuthenticationSuiteEnabled = -+ FALSE; -+ } -+ -+ secClearPmkid(prAdapter); -+ -+ cnmTimerInitTimer(prAdapter, -+ &prAisSpecBssInfo->rPreauthenticationTimer, -+ (PFN_MGMT_TIMEOUT_FUNC) rsnIndicatePmkidCand, (ULONG) NULL); -+ -+#if CFG_SUPPORT_802_11W -+ cnmTimerInitTimer(prAdapter, -+ &prAisSpecBssInfo->rSaQueryTimer, (PFN_MGMT_TIMEOUT_FUNC) rsnStartSaQueryTimer, (ULONG) NULL); -+#endif -+ -+ prAisSpecBssInfo->fgCounterMeasure = FALSE; -+ prAisSpecBssInfo->ucWEPDefaultKeyID = 0; -+ -+#if 0 -+ for (i = 0; i < WTBL_SIZE; i++) { -+ g_prWifiVar->arWtbl[i].fgUsed = FALSE; -+ g_prWifiVar->arWtbl[i].prSta = NULL; -+ g_prWifiVar->arWtbl[i].ucNetTypeIdx = NETWORK_TYPE_INDEX_NUM; -+ -+ } -+ nicPrivacyInitialize((UINT_8) NETWORK_TYPE_INDEX_NUM); -+#endif -+} /* secInit */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will indicate an Event of "Rx Class Error" to SEC_FSM for -+* JOIN Module. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* \param[in] prSwRfb Pointer to the SW RFB. -+* -+* \return FALSE Class Error -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN secCheckClassError(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, IN P_STA_RECORD_T prStaRec) -+{ -+ ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex; -+ P_BSS_INFO_T prBssInfo; -+ -+ ASSERT(prAdapter); -+ ASSERT(prSwRfb); -+ -+ if (!prStaRec) -+ return FALSE; -+ -+ eNetTypeIndex = prStaRec->ucNetTypeIndex; -+ if (!IS_NET_ACTIVE(prAdapter, eNetTypeIndex)) -+ return FALSE; -+ -+ prBssInfo = &prAdapter->rWifiVar.arBssInfo[eNetTypeIndex]; -+ if ((STA_STATE_3 != prStaRec->ucStaState) && prBssInfo->fgIsNetAbsent == FALSE) { -+ /*(IS_AP_STA(prStaRec) || IS_CLIENT_STA(prStaRec))) { */ -+ -+#if 0 /* by scott's suggestions, do not put work-around in JB2,we need to find the root cause */ -+ /* work-around for CR ALPS00816361 */ -+ if (eNetTypeIndex == NETWORK_TYPE_P2P_INDEX) { -+ DBGLOG(RSN, INFO, -+ "p2p> skip to send Deauth to MAC:[%pM] for Rx Class 3.\n", -+ prStaRec->aucMacAddr); -+ return TRUE; -+ } -+#endif -+ -+ if (WLAN_STATUS_SUCCESS == authSendDeauthFrame(prAdapter, -+ prStaRec, -+ NULL, -+ REASON_CODE_CLASS_3_ERR, -+ (PFN_TX_DONE_HANDLER) NULL)) -+ -+ DBGLOG(RSN, INFO, "Send Deauth to [ %pM ] for Rx Class 3 Error.\n", -+ prStaRec->aucMacAddr); -+ else -+ DBGLOG(RSN, INFO, "Host sends Deauth to [ %pM ] for Rx Class 3 fail.\n", -+ prStaRec->aucMacAddr); -+ return FALSE; -+ } -+ -+ return secRxPortControlCheck(prAdapter, prSwRfb); -+} /* end of secCheckClassError() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is used to setting the sta port status. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* \param[in] prSta Pointer to the sta -+* \param[in] fgPortBlock The port status -+* -+* \retval none -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID secSetPortBlocked(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta, IN BOOLEAN fgPortBlock) -+{ -+ if (prSta == NULL) -+ return; -+ -+ prSta->fgPortBlock = fgPortBlock; -+ -+ DBGLOG(RSN, TRACE, -+ "The STA %pM port %s\n", prSta->aucMacAddr, fgPortBlock == TRUE ? "BLOCK" : " OPEN"); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is used to report the sta port status. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* \param[in] prSta Pointer to the sta -+* \param[out] fgPortBlock The port status -+* -+* \return TRUE sta exist, FALSE sta not exist -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN secGetPortStatus(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta, OUT PBOOLEAN pfgPortStatus) -+{ -+ if (prSta == NULL) -+ return FALSE; -+ -+ *pfgPortStatus = prSta->fgPortBlock; -+ -+ return TRUE; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to handle Peer device Tx Security process MSDU. -+* -+* \param[in] prMsduInfo pointer to the packet info pointer -+* -+* \retval TRUE Accept the packet -+* \retval FALSE Refuse the MSDU packet due port blocked -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN /* ENUM_PORT_CONTROL_RESULT */ -+secTxPortControlCheck(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo, IN P_STA_RECORD_T prStaRec) -+{ -+ ASSERT(prAdapter); -+ ASSERT(prMsduInfo); -+ ASSERT(prStaRec); -+ -+ if (prStaRec) { -+ -+ /* Todo:: */ -+ if (prMsduInfo->fgIs802_1x) -+ return TRUE; -+ -+ if (prStaRec->fgPortBlock == TRUE) { -+ DBGLOG(SEC, TRACE, "Drop Tx packet due Port Control!\n"); -+ return FALSE; -+ } -+#if CFG_SUPPORT_WAPI -+ if (prAdapter->rWifiVar.rConnSettings.fgWapiMode) -+ return TRUE; -+#endif -+ if (IS_STA_IN_AIS(prStaRec)) { -+ if (!prAdapter->rWifiVar.rAisSpecificBssInfo.fgTransmitKeyExist && -+ (prAdapter->rWifiVar.rConnSettings.eEncStatus == ENUM_ENCRYPTION1_ENABLED)) { -+ DBGLOG(SEC, TRACE, "Drop Tx packet due the key is removed!!!\n"); -+ return FALSE; -+ } -+ } -+ } -+ -+ return TRUE; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to handle The Rx Security process MSDU. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* \param[in] prSWRfb SW rfb pinter -+* -+* \retval TRUE Accept the packet -+* \retval FALSE Refuse the MSDU packet due port control -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN secRxPortControlCheck(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSWRfb) -+{ -+ ASSERT(prSWRfb); -+ -+#if 0 -+ /* whsu:Todo: Process MGMT and DATA */ -+ if (prSWRfb->prStaRec) { -+ if (prSWRfb->prStaRec->fgPortBlock == TRUE) { -+ if (1 /* prSWRfb->fgIsDataFrame and not 1x */ && -+ (g_prWifiVar->rConnSettings.eAuthMode >= AUTH_MODE_WPA)) { -+ /* DBGLOG(SEC, WARN, ("Drop Rx data due port control !\r\n")); */ -+ return TRUE; /* Todo: whsu FALSE; */ -+ } -+ /* if (!RX_STATUS_IS_PROTECT(prSWRfb->prRxStatus)) { */ -+ /* DBGLOG(RSN, WARN, ("Drop rcv non-encrypted data frame!\n")); */ -+ /* return FALSE; */ -+ /* } */ -+ } -+ } else { -+ } -+#endif -+ return TRUE; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine will enable/disable the cipher suite -+* -+* \param[in] prAdapter Pointer to the adapter object data area. -+* \param[in] u4CipherSuitesFlags flag for cipher suite -+* -+* \retval none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID secSetCipherSuite(IN P_ADAPTER_T prAdapter, IN UINT_32 u4CipherSuitesFlags) -+{ -+ UINT_32 i; -+ P_DOT11_RSNA_CONFIG_PAIRWISE_CIPHERS_ENTRY prEntry; -+ P_IEEE_802_11_MIB_T prMib; -+ -+ ASSERT(prAdapter); -+ -+ prMib = &prAdapter->rMib; -+ -+ ASSERT(prMib); -+ -+ if (u4CipherSuitesFlags == CIPHER_FLAG_NONE) { -+ /* Disable all the pairwise cipher suites. */ -+ for (i = 0; i < MAX_NUM_SUPPORTED_CIPHER_SUITES; i++) -+ prMib->dot11RSNAConfigPairwiseCiphersTable[i].dot11RSNAConfigPairwiseCipherEnabled = FALSE; -+ -+ /* Update the group cipher suite. */ -+ prMib->dot11RSNAConfigGroupCipher = WPA_CIPHER_SUITE_NONE; -+ -+ return; -+ } -+ -+ for (i = 0; i < MAX_NUM_SUPPORTED_CIPHER_SUITES; i++) { -+ prEntry = &prMib->dot11RSNAConfigPairwiseCiphersTable[i]; -+ -+ switch (prEntry->dot11RSNAConfigPairwiseCipher) { -+ case WPA_CIPHER_SUITE_WEP40: -+ case RSN_CIPHER_SUITE_WEP40: -+ if (u4CipherSuitesFlags & CIPHER_FLAG_WEP40) -+ prEntry->dot11RSNAConfigPairwiseCipherEnabled = TRUE; -+ else -+ prEntry->dot11RSNAConfigPairwiseCipherEnabled = FALSE; -+ break; -+ -+ case WPA_CIPHER_SUITE_TKIP: -+ case RSN_CIPHER_SUITE_TKIP: -+ if (u4CipherSuitesFlags & CIPHER_FLAG_TKIP) -+ prEntry->dot11RSNAConfigPairwiseCipherEnabled = TRUE; -+ else -+ prEntry->dot11RSNAConfigPairwiseCipherEnabled = FALSE; -+ break; -+ -+ case WPA_CIPHER_SUITE_CCMP: -+ case RSN_CIPHER_SUITE_CCMP: -+ if (u4CipherSuitesFlags & CIPHER_FLAG_CCMP) -+ prEntry->dot11RSNAConfigPairwiseCipherEnabled = TRUE; -+ else -+ prEntry->dot11RSNAConfigPairwiseCipherEnabled = FALSE; -+ break; -+ -+ case WPA_CIPHER_SUITE_WEP104: -+ case RSN_CIPHER_SUITE_WEP104: -+ if (u4CipherSuitesFlags & CIPHER_FLAG_WEP104) -+ prEntry->dot11RSNAConfigPairwiseCipherEnabled = TRUE; -+ else -+ prEntry->dot11RSNAConfigPairwiseCipherEnabled = FALSE; -+ break; -+ default: -+ break; -+ } -+ } -+ -+ /* Update the group cipher suite. */ -+ if (rsnSearchSupportedCipher(prAdapter, WPA_CIPHER_SUITE_CCMP, &i)) -+ prMib->dot11RSNAConfigGroupCipher = WPA_CIPHER_SUITE_CCMP; -+ else if (rsnSearchSupportedCipher(prAdapter, WPA_CIPHER_SUITE_TKIP, &i)) -+ prMib->dot11RSNAConfigGroupCipher = WPA_CIPHER_SUITE_TKIP; -+ else if (rsnSearchSupportedCipher(prAdapter, WPA_CIPHER_SUITE_WEP104, &i)) -+ prMib->dot11RSNAConfigGroupCipher = WPA_CIPHER_SUITE_WEP104; -+ else if (rsnSearchSupportedCipher(prAdapter, WPA_CIPHER_SUITE_WEP40, &i)) -+ prMib->dot11RSNAConfigGroupCipher = WPA_CIPHER_SUITE_WEP40; -+ else -+ prMib->dot11RSNAConfigGroupCipher = WPA_CIPHER_SUITE_NONE; -+ -+} /* secSetCipherSuite */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to handle The 2nd Tx EAPoL Frame. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* \param[in] prMsduInfo pointer to the packet info pointer -+* \param[in] pucPayload pointer to the 1x hdr -+* \param[in] u2PayloadLen the 1x payload length -+* -+* \retval TRUE Accept the packet -+* \retval FALSE Refuse the MSDU packet due port control -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN -+secProcessEAPOL(IN P_ADAPTER_T prAdapter, -+ IN P_MSDU_INFO_T prMsduInfo, IN P_STA_RECORD_T prStaRec, IN PUINT_8 pucPayload, IN UINT_16 u2PayloadLen) -+{ -+ P_EAPOL_KEY prEapol = (P_EAPOL_KEY) NULL; -+ P_IEEE_802_1X_HDR pr1xHdr; -+ UINT_16 u2KeyInfo; -+ -+ ASSERT(prMsduInfo); -+ ASSERT(prStaRec); -+ -+ /* prStaRec = &(g_arStaRec[prMsduInfo->ucStaRecIndex]); */ -+ ASSERT(prStaRec); -+ -+ if (prStaRec && IS_AP_STA(prStaRec)) { -+ pr1xHdr = (P_IEEE_802_1X_HDR) pucPayload; -+ if ((pr1xHdr->ucType == 3) /* EAPoL key */ && ((u2PayloadLen - 4) > sizeof(EAPOL_KEY))) { -+ prEapol = (P_EAPOL_KEY) ((PUINT_32) (pucPayload + 4)); -+ WLAN_GET_FIELD_BE16(prEapol->aucKeyInfo, &u2KeyInfo); -+ if ((prEapol->ucType == 254) && (u2KeyInfo & MASK_2ND_EAPOL)) { -+ if (u2KeyInfo & WPA_KEY_INFO_SECURE) { -+ /* 4th EAPoL check at secHandleTxDoneCallback() */ -+ /* DBGLOG(RSN, TRACE, ("Tx 4th EAPoL frame\r\n")); */ -+ } else if (u2PayloadLen == 123 /* Not include LLC */) { -+ DBGLOG(RSN, INFO, "Tx 2nd EAPoL frame\r\n"); -+ secFsmEvent2ndEapolTx(prAdapter, prStaRec); -+ } -+ } -+ } -+ } -+ -+ return TRUE; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will handle the 4th EAPoL Tx done and mic Error Report frame. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* \param[in] pMsduInfo Pointer to the Msdu Info -+* \param[in] rStatus The Tx done status -+* -+* \return - -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+secHandleTxDoneCallback(IN P_ADAPTER_T prAdapter, -+ IN P_MSDU_INFO_T prMsduInfo, IN P_STA_RECORD_T prStaRec, IN WLAN_STATUS rStatus) -+{ -+ PUINT_8 pucPayload; -+ P_IEEE_802_1X_HDR pr1xHdr = (P_IEEE_802_1X_HDR) NULL; -+ P_EAPOL_KEY prEapol = (P_EAPOL_KEY) NULL; -+ UINT_16 u2KeyInfo; -+ UINT_16 u2PayloadLen; -+ -+ DEBUGFUNC("secHandleTxDoneCallback"); -+ -+ ASSERT(prMsduInfo); -+ /* Todo:: Notice if using the TX free immediate after send to firmware, the payload may not correcttly!!!! */ -+ -+ ASSERT(prStaRec); -+ -+ /* Todo:: This call back may not need because the order of set key and send 4th 1x can be make sure */ -+ /* Todo:: Notice the LLC offset */ -+#if 1 -+ pucPayload = (PUINT_8) prMsduInfo->prPacket; -+ ASSERT(pucPayload); -+ -+ u2PayloadLen = prMsduInfo->u2FrameLength; -+ -+ if (0 /* prMsduInfo->fgIs1xFrame */) { -+ -+ if (prStaRec && IS_AP_STA(prStaRec)) { -+ pr1xHdr = (P_IEEE_802_1X_HDR) (PUINT_32) (pucPayload + 8); -+ if ((pr1xHdr->ucType == 3) /* EAPoL key */ && ((u2PayloadLen - 4) > sizeof(EAPOL_KEY))) { -+ prEapol = (P_EAPOL_KEY) (PUINT_32) (pucPayload + 12); -+ WLAN_GET_FIELD_BE16(prEapol->aucKeyInfo, &u2KeyInfo); -+ if ((prEapol->ucType == 254) && (u2KeyInfo & MASK_2ND_EAPOL)) { -+ if (prStaRec->rSecInfo.fg2nd1xSend == TRUE -+ && u2PayloadLen == -+ 107 /* include LLC *//* u2KeyInfo & WPA_KEY_INFO_SECURE */) { -+ DBGLOG(RSN, INFO, "Tx 4th EAPoL frame\r\n"); -+ secFsmEvent4ndEapolTxDone(prAdapter, prStaRec); -+ } else if (prAdapter->rWifiVar.rAisSpecificBssInfo.fgCheckEAPoLTxDone) { -+ DBGLOG(RSN, INFO, "Tx EAPoL Error report frame\r\n"); -+ /* secFsmEventEapolTxDone(prAdapter, (UINT_32)prMsduInfo->prStaRec); */ -+ } -+ } -+ } -+ } -+ -+ } -+#endif -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to initialize the pmkid parameters. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* -+* \retval NONE -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID secClearPmkid(IN P_ADAPTER_T prAdapter) -+{ -+ P_AIS_SPECIFIC_BSS_INFO_T prAisSpecBssInfo; -+ -+ DEBUGFUNC("secClearPmkid"); -+ -+ prAisSpecBssInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo; -+ DBGLOG(RSN, TRACE, "secClearPmkid\n"); -+ prAisSpecBssInfo->u4PmkidCandicateCount = 0; -+ prAisSpecBssInfo->u4PmkidCacheCount = 0; -+ kalMemZero((PVOID) prAisSpecBssInfo->arPmkidCandicate, sizeof(PMKID_CANDICATE_T) * CFG_MAX_PMKID_CACHE); -+ kalMemZero((PVOID) prAisSpecBssInfo->arPmkidCache, sizeof(PMKID_ENTRY_T) * CFG_MAX_PMKID_CACHE); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Whether WPA, or WPA2 but not WPA-None is enabled. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* -+* \retval BOOLEAN -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN secRsnKeyHandshakeEnabled(IN P_ADAPTER_T prAdapter) -+{ -+ P_CONNECTION_SETTINGS_T prConnSettings; -+ -+ ASSERT(prAdapter); -+ -+ prConnSettings = &prAdapter->rWifiVar.rConnSettings; -+ -+ ASSERT(prConnSettings); -+ -+ ASSERT(prConnSettings->eEncStatus < ENUM_ENCRYPTION3_KEY_ABSENT); -+ -+ if (prConnSettings->eEncStatus == ENUM_ENCRYPTION_DISABLED) -+ return FALSE; -+ -+ ASSERT(prConnSettings->eAuthMode < AUTH_MODE_NUM); -+ if ((prConnSettings->eAuthMode >= AUTH_MODE_WPA) && (prConnSettings->eAuthMode != AUTH_MODE_WPA_NONE)) -+ return TRUE; -+ -+ return FALSE; -+} /* secRsnKeyHandshakeEnabled */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Return whether the transmit key alread installed. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* \param[in] prSta Pointer the sta record -+* -+* \retval TRUE Default key or Transmit key installed -+* FALSE Default key or Transmit key not installed -+* -+* \note: -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN secTransmitKeyExist(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta) -+{ -+ ASSERT(prSta); -+ -+ if (prSta->fgTransmitKeyExist) -+ return TRUE; -+ else -+ return FALSE; -+} /* secTransmitKeyExist */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Whether 802.11 privacy is enabled. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* -+* \retval BOOLEAN -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN secEnabledInAis(IN P_ADAPTER_T prAdapter) -+{ -+ DEBUGFUNC("secEnabled"); -+ -+ ASSERT(prAdapter->rWifiVar.rConnSettings.eEncStatus < ENUM_ENCRYPTION3_KEY_ABSENT); -+ -+ switch (prAdapter->rWifiVar.rConnSettings.eEncStatus) { -+ case ENUM_ENCRYPTION_DISABLED: -+ return FALSE; -+ case ENUM_ENCRYPTION1_ENABLED: -+ case ENUM_ENCRYPTION2_ENABLED: -+ case ENUM_ENCRYPTION3_ENABLED: -+ return TRUE; -+ default: -+ DBGLOG(RSN, TRACE, "Unknown encryption setting %d\n", prAdapter->rWifiVar.rConnSettings.eEncStatus); -+ break; -+ } -+ return FALSE; -+} /* secEnabled */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to set the privacy bit at mac header for TxM -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* \param[in] prMsdu the msdu for known the sta record -+* -+* \return TRUE the privacy need to set -+* FALSE the privacy no need to set -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN secIsProtectedFrame(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsdu, IN P_STA_RECORD_T prStaRec) -+{ -+ ASSERT(prAdapter); -+ -+ ASSERT(prMsdu); -+ -+ ASSERT(prStaRec); -+ /* prStaRec = &(g_arStaRec[prMsdu->ucStaRecIndex]); */ -+ -+ if (prStaRec == NULL) { -+ if (prAdapter->rWifiVar.rAisSpecificBssInfo.fgTransmitKeyExist) -+ return TRUE; -+ return FALSE; /* No privacy bit */ -+ } -+ -+ /* Todo:: */ -+ if (0 /* prMsdu->fgIs1xFrame */) { -+ if (IS_STA_IN_AIS(prStaRec) && prAdapter->rWifiVar.rConnSettings.eAuthMode < AUTH_MODE_WPA) { -+ DBGLOG(RSN, LOUD, "For AIS Legacy 1x, always not encryped\n"); -+ return FALSE; -+ } else if (!prStaRec->fgTransmitKeyExist) { -+ DBGLOG(RSN, LOUD, "1x Not Protected.\n"); -+ return FALSE; -+ } else if (prStaRec->rSecInfo.fgKeyStored) { -+ DBGLOG(RSN, LOUD, "1x not Protected due key stored!\n"); -+ return FALSE; -+ } -+ DBGLOG(RSN, LOUD, "1x Protected.\n"); -+ return TRUE; -+ } -+ if (!prStaRec->fgTransmitKeyExist) { -+ /* whsu , check for AIS only */ -+ if (prAdapter->rWifiVar.rConnSettings.eAuthMode < AUTH_MODE_WPA && -+ prAdapter->rWifiVar.rAisSpecificBssInfo.fgTransmitKeyExist) { -+ DBGLOG(RSN, LOUD, "Protected\n"); -+ return TRUE; -+ } -+ } else { -+ DBGLOG(RSN, LOUD, "Protected.\n"); -+ return TRUE; -+ } -+ -+ /* No sec or key is removed!!! */ -+ return FALSE; -+} -+#endif -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rate.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rate.c -new file mode 100644 -index 000000000000..fd0a8772a666 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rate.c -@@ -0,0 +1,497 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/rate.c#1 -+*/ -+ -+/*! \file "rate.c" -+ \brief This file contains the transmission rate handling routines. -+ -+ This file contains the transmission rate handling routines for setting up -+ ACK/CTS Rate, Highest Tx Rate, Lowest Tx Rate, Initial Tx Rate and do -+ conversion between Rate Set and Data Rates. -+*/ -+ -+/* -+** Log: rate.c -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 08 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add rate.c. -+ * -+ * 03 16 2010 kevin.huang -+ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support -+ * Add AdHoc Mode -+ * -+ * 12 18 2009 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * . -+ * -+ * Nov 23 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Update comments -+ * -+ * Nov 16 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Fix DBGLOG -+ * -+ * Nov 5 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * -+** \main\maintrunk.MT5921\12 2008-12-19 17:19:32 GMT mtk01461 -+** Fix the problem that do not ASSERT the length of Supported Rate IE == 8 -+** \main\maintrunk.MT5921\11 2008-12-01 18:17:42 GMT mtk01088 -+** fixed the lint "possible using null pointer" warning -+** \main\maintrunk.MT5921\10 2008-08-20 00:16:36 GMT mtk01461 -+** Update for Driver Review -+** \main\maintrunk.MT5921\9 2008-04-13 21:17:13 GMT mtk01461 -+** Revise GEN Link Speed OID -+** \main\maintrunk.MT5921\8 2008-03-28 10:40:13 GMT mtk01461 -+** Add rateGetRateSetFromDataRates() for set desired rate OID -+** \main\maintrunk.MT5921\7 2008-03-26 09:16:20 GMT mtk01461 -+** Add adopt operational rate as ACK rate if BasicRateSet was not found -+** Add comments -+** \main\maintrunk.MT5921\6 2008-02-21 15:01:39 GMT mtk01461 -+** Add initial rate according rx signal quality support -+** \main\maintrunk.MT5921\5 2008-01-07 15:06:44 GMT mtk01461 -+** Fix typo of rate adaptation of CtrlResp Frame -+** \main\maintrunk.MT5921\4 2007-10-25 18:05:12 GMT mtk01461 -+** Add VOIP SCAN Support & Refine Roaming -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "precomp.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+/* The list of valid data rates. */ -+const UINT_8 aucDataRate[] = { -+ RATE_1M, /* RATE_1M_INDEX = 0 */ -+ RATE_2M, /* RATE_2M_INDEX */ -+ RATE_5_5M, /* RATE_5_5M_INDEX */ -+ RATE_11M, /* RATE_11M_INDEX */ -+ RATE_22M, /* RATE_22M_INDEX */ -+ RATE_33M, /* RATE_33M_INDEX */ -+ RATE_6M, /* RATE_6M_INDEX */ -+ RATE_9M, /* RATE_9M_INDEX */ -+ RATE_12M, /* RATE_12M_INDEX */ -+ RATE_18M, /* RATE_18M_INDEX */ -+ RATE_24M, /* RATE_24M_INDEX */ -+ RATE_36M, /* RATE_36M_INDEX */ -+ RATE_48M, /* RATE_48M_INDEX */ -+ RATE_54M, /* RATE_54M_INDEX */ -+ RATE_HT_PHY /* RATE_HT_PHY_INDEX */ -+}; -+ -+static const UINT_8 aucDefaultAckCtsRateIndex[RATE_NUM] = { -+ RATE_1M_INDEX, /* RATE_1M_INDEX = 0 */ -+ RATE_2M_INDEX, /* RATE_2M_INDEX */ -+ RATE_5_5M_INDEX, /* RATE_5_5M_INDEX */ -+ RATE_11M_INDEX, /* RATE_11M_INDEX */ -+ RATE_1M_INDEX, /* RATE_22M_INDEX - Not supported */ -+ RATE_1M_INDEX, /* RATE_33M_INDEX - Not supported */ -+ RATE_6M_INDEX, /* RATE_6M_INDEX */ -+ RATE_6M_INDEX, /* RATE_9M_INDEX */ -+ RATE_12M_INDEX, /* RATE_12M_INDEX */ -+ RATE_12M_INDEX, /* RATE_18M_INDEX */ -+ RATE_24M_INDEX, /* RATE_24M_INDEX */ -+ RATE_24M_INDEX, /* RATE_36M_INDEX */ -+ RATE_24M_INDEX, /* RATE_48M_INDEX */ -+ RATE_24M_INDEX /* RATE_54M_INDEX */ -+}; -+ -+const BOOLEAN afgIsOFDMRate[RATE_NUM] = { -+ FALSE, /* RATE_1M_INDEX = 0 */ -+ FALSE, /* RATE_2M_INDEX */ -+ FALSE, /* RATE_5_5M_INDEX */ -+ FALSE, /* RATE_11M_INDEX */ -+ FALSE, /* RATE_22M_INDEX - Not supported */ -+ FALSE, /* RATE_33M_INDEX - Not supported */ -+ TRUE, /* RATE_6M_INDEX */ -+ TRUE, /* RATE_9M_INDEX */ -+ TRUE, /* RATE_12M_INDEX */ -+ TRUE, /* RATE_18M_INDEX */ -+ TRUE, /* RATE_24M_INDEX */ -+ TRUE, /* RATE_36M_INDEX */ -+ TRUE, /* RATE_48M_INDEX */ -+ TRUE /* RATE_54M_INDEX */ -+}; -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Convert the given Supported Rate & Extended Supported Rate IE to the -+* Operational Rate Set and Basic Rate Set, and also check if any Basic -+* Rate Code is unknown by driver. -+* -+* @param[in] prIeSupportedRate Pointer to the Supported Rate IE -+* @param[in] prIeExtSupportedRate Pointer to the Ext Supported Rate IE -+* @param[out] pu2OperationalRateSet Pointer to the Operational Rate Set -+* @param[out] pu2BSSBasicRateSet Pointer to the Basic Rate Set -+* @param[out] pfgIsUnknownBSSBasicRate Pointer to a Flag to indicate that Basic -+* Rate Set has unknown Rate Code -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+rateGetRateSetFromIEs(IN P_IE_SUPPORTED_RATE_T prIeSupportedRate, -+ IN P_IE_EXT_SUPPORTED_RATE_T prIeExtSupportedRate, -+ OUT PUINT_16 pu2OperationalRateSet, -+ OUT PUINT_16 pu2BSSBasicRateSet, OUT PBOOLEAN pfgIsUnknownBSSBasicRate) -+{ -+ UINT_16 u2OperationalRateSet = 0; -+ UINT_16 u2BSSBasicRateSet = 0; -+ BOOLEAN fgIsUnknownBSSBasicRate = FALSE; -+ UINT_8 ucRate; -+ UINT_32 i, j; -+ -+ ASSERT(pu2OperationalRateSet); -+ ASSERT(pu2BSSBasicRateSet); -+ ASSERT(pfgIsUnknownBSSBasicRate); -+ -+ if (prIeSupportedRate) { -+ /* NOTE(Kevin): Buffalo WHR-G54S's supported rate set IE exceed 8. -+ * IE_LEN(pucIE) == 12, "1(B), 2(B), 5.5(B), 6(B), 9(B), 11(B), -+ * 12(B), 18(B), 24(B), 36(B), 48(B), 54(B)" -+ */ -+ /* ASSERT(prIeSupportedRate->ucLength <= ELEM_MAX_LEN_SUP_RATES); */ -+ ASSERT(prIeSupportedRate->ucLength <= RATE_NUM); -+ -+ for (i = 0; i < prIeSupportedRate->ucLength; i++) { -+ ucRate = prIeSupportedRate->aucSupportedRates[i] & RATE_MASK; -+ -+ /* Search all valid data rates */ -+ for (j = 0; j < sizeof(aucDataRate) / sizeof(UINT_8); j++) { -+ if (ucRate == aucDataRate[j]) { -+ u2OperationalRateSet |= BIT(j); -+ -+ if (prIeSupportedRate->aucSupportedRates[i] & RATE_BASIC_BIT) -+ u2BSSBasicRateSet |= BIT(j); -+ -+ break; -+ } -+ } -+ -+ if ((j == sizeof(aucDataRate) / sizeof(UINT_8)) && -+ (prIeSupportedRate->aucSupportedRates[i] & RATE_BASIC_BIT)) { -+ fgIsUnknownBSSBasicRate = TRUE; /* A data rate not list in the aucDataRate[] */ -+ } -+ } -+ } -+ -+ if (prIeExtSupportedRate) { -+ /* ASSERT(prIeExtSupportedRate->ucLength <= ELEM_MAX_LEN_EXTENDED_SUP_RATES); */ -+ -+ for (i = 0; i < prIeExtSupportedRate->ucLength; i++) { -+ ucRate = prIeExtSupportedRate->aucExtSupportedRates[i] & RATE_MASK; -+ -+ /* Search all valid data rates */ -+ for (j = 0; j < sizeof(aucDataRate) / sizeof(UINT_8); j++) { -+ if (ucRate == aucDataRate[j]) { -+ u2OperationalRateSet |= BIT(j); -+ -+ if (prIeExtSupportedRate->aucExtSupportedRates[i] & RATE_BASIC_BIT) -+ u2BSSBasicRateSet |= BIT(j); -+ -+ break; -+ } -+ } -+ -+ if ((j == sizeof(aucDataRate) / sizeof(UINT_8)) && -+ (prIeExtSupportedRate->aucExtSupportedRates[i] & RATE_BASIC_BIT)) { -+ fgIsUnknownBSSBasicRate = TRUE; /* A data rate not list in the aucDataRate[] */ -+ } -+ } -+ } -+ -+ *pu2OperationalRateSet = u2OperationalRateSet; -+ *pu2BSSBasicRateSet = u2BSSBasicRateSet; -+ *pfgIsUnknownBSSBasicRate = fgIsUnknownBSSBasicRate; -+ -+ return; -+ -+} /* end of rateGetRateSetFromIEs() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Convert the given Operational Rate Set & Basic Rate Set to the Rate Code -+* Format for used in (Ext)Supportec Rate IE. -+* -+* @param[in] u2OperationalRateSet Operational Rate Set -+* @param[in] u2BSSBasicRateSet Basic Rate Set -+* @param[out] pucDataRates Pointer to the Data Rate Buffer -+* @param[out] pucDataRatesLen Pointer to the Data Rate Buffer Length -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+rateGetDataRatesFromRateSet(IN UINT_16 u2OperationalRateSet, -+ IN UINT_16 u2BSSBasicRateSet, OUT PUINT_8 pucDataRates, OUT PUINT_8 pucDataRatesLen) -+{ -+ UINT_32 i, j; -+ -+ ASSERT(pucDataRates); -+ ASSERT(pucDataRatesLen); -+ -+ ASSERT(u2BSSBasicRateSet == (u2OperationalRateSet & u2BSSBasicRateSet)); -+ -+ for (i = RATE_1M_INDEX, j = 0; i < RATE_NUM; i++) { -+ if (u2OperationalRateSet & BIT(i)) { -+ -+ *(pucDataRates + j) = aucDataRate[i]; -+ -+ if (u2BSSBasicRateSet & BIT(i)) -+ *(pucDataRates + j) |= RATE_BASIC_BIT; -+ -+ j++; -+ } -+ } -+ -+ *pucDataRatesLen = (UINT_8) j; -+ -+ return; -+ -+} /* end of rateGetDataRatesFromRateSet() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Get the highest rate from given Rate Set. -+* -+* \param[in] u2RateSet Rate Set -+* \param[out] pucHighestRateIndex Pointer to buffer of the Highest Rate Index -+* -+* \retval TRUE Highest Rate Index was found -+* \retval FALSE Highest Rate Index was not found -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN rateGetHighestRateIndexFromRateSet(IN UINT_16 u2RateSet, OUT PUINT_8 pucHighestRateIndex) -+{ -+ INT_32 i; -+ -+ ASSERT(pucHighestRateIndex); -+ -+ for (i = RATE_54M_INDEX; i >= RATE_1M_INDEX; i--) { -+ if (u2RateSet & BIT(i)) { -+ *pucHighestRateIndex = (UINT_8) i; -+ return TRUE; -+ } -+ } -+ -+ return FALSE; -+ -+} /* end of rateGetHighestRateIndexFromRateSet() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Get the lowest rate from given Rate Set. -+* -+* \param[in] u2RateSet Rate Set -+* \param[out] pucLowestRateIndex Pointer to buffer of the Lowest Rate Index -+* -+* \retval TRUE Lowest Rate Index was found -+* \retval FALSE Lowest Rate Index was not found -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN rateGetLowestRateIndexFromRateSet(IN UINT_16 u2RateSet, OUT PUINT_8 pucLowestRateIndex) -+{ -+ UINT_32 i; -+ -+ ASSERT(pucLowestRateIndex); -+ -+ for (i = RATE_1M_INDEX; i <= RATE_54M_INDEX; i++) { -+ if (u2RateSet & BIT(i)) { -+ *pucLowestRateIndex = (UINT_8) i; -+ return TRUE; -+ } -+ } -+ -+ return FALSE; -+ -+} /* end of rateGetLowestRateIndexFromRateSet() */ -+ -+#if 0 /* NOTE(Kevin): For reference */ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Convert the given Data Rates to the Rate Set. -+* -+* \param[in] pucDataRates Pointer to the Data Rates -+* \param[in] ucDataRatesLen Length of given Data Rates -+* \param[out] pu2RateSet Pointer to the Rate Set -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rateGetRateSetFromDataRates(IN PUINT_8 pucDataRates, IN UINT_8 ucDataRatesLen, OUT PUINT_16 pu2RateSet) -+{ -+ UINT_16 u2RateSet = 0; -+ UINT_8 ucRate; -+ UINT_32 i, j; -+ -+ ASSERT(pucDataRates); -+ ASSERT(pu2RateSet); -+ -+ if (pucDataRates) { -+ for (i = 0; i < ucDataRatesLen; i++) { -+ ucRate = pucDataRates[i] & RATE_MASK; -+ -+ /* Search all valid data rates */ -+ for (j = 0; j < sizeof(aucDataRate) / sizeof(UINT_8); j++) { -+ if (ucRate == aucDataRate[j]) { -+ u2RateSet |= BIT(j); -+ break; -+ } -+ } -+ } -+ } -+ -+ *pu2RateSet = u2RateSet; -+ -+ return; -+ -+} /* end of rateGetRateSetFromDataRates() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Parse the Operational Rate Set and Basic Rate Set to get the corresponding -+* ACK/CTS(Respnose) TX Rates. -+* -+* \param[in] u2OperationalRateSet Operational Rate Set -+* \param[in] u2BSSBasicRateSet Basic Rate Set -+* \param[out] aucAckCtsRateIndex Pointer to the Ack/Cts Data Rate Buffer -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+rateSetAckCtsDataRatesFromRateSet(IN UINT_16 u2OperationalRateSet, -+ IN UINT_16 u2BSSBasicRateSet, IN OUT UINT_8 aucAckCtsRateIndex[]) -+{ -+ INT_32 i, j; -+ -+ ASSERT(aucAckCtsRateIndex); -+ ASSERT(u2BSSBasicRateSet == (u2OperationalRateSet & u2BSSBasicRateSet)); -+ -+ /* Setup default ACK/CTS response rate */ -+ kalMemCopy(aucAckCtsRateIndex, (PVOID) aucDefaultAckCtsRateIndex, sizeof(aucDefaultAckCtsRateIndex)); -+ -+ for (i = RATE_54M_INDEX; i >= RATE_1M_INDEX; i--) { -+ if (u2OperationalRateSet & BIT(i)) { -+ for (j = i; j >= RATE_1M_INDEX; j--) { -+ if (u2BSSBasicRateSet & BIT(j)) { -+ /* Reply ACK Frame at the same Modulation Scheme. */ -+ if ((afgIsOFDMRate[i] && afgIsOFDMRate[j]) || -+ (!afgIsOFDMRate[i] && !afgIsOFDMRate[j])) -+ aucAckCtsRateIndex[i] = (UINT_8) j; -+ break; -+ } -+ } -+ -+ /* NOTE(Kevin 2008/03/25): Following code is used for those AP which has -+ * NULL BasicRateSet. -+ * e.g. If input Operational Rate Set = [18M 12M 9M], Basic Rate Set = NULL. -+ * Originally we'll get Ack Rate for [18M 12M 9M] is [12M 12M "6M"]. -+ * Now we'll get Ack Rate for [18M 12M 9M] is [12M 12M 9M], -+ * The Ack Rate for Tx Rates which are not list in Operational Rate Set is still -+ * use highest mandatory rate as default. -+ */ -+ if (j < RATE_1M_INDEX) { /* The ACK/CTS rate was not found in BasicRateSet */ -+ if (!(BIT(aucAckCtsRateIndex[i]) & u2OperationalRateSet)) -+ aucAckCtsRateIndex[i] = (UINT_8) i; -+ } -+ } -+ } -+ -+ return; -+ -+} /* end of rateSetAckCtsDataRatesFromRateSet() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Get the proper initial rate from Rate Set according to given RCPI value -+* -+* \param[in] u2RateSet Rate Set -+* \param[in] rRcpi RCPI value from AP or Peer STA -+* \param[out] pucInitialRateIndex Pointer to buffer of the initial Rate Index -+* -+* \retval TRUE Initial Rate Index was found -+* \retval FALSE Initial Rate Index was not found -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN rateGetBestInitialRateIndex(IN UINT_16 u2RateSet, IN RCPI rRcpi, OUT PUINT_8 pucInitialRateIndex) -+{ -+ UINT_16 u2InitRateSet; -+ INT_32 i; -+ -+ ASSERT(pucInitialRateIndex); -+ -+ DBGLOG(MGT, TRACE, "rRcpi = %d\n", rRcpi); -+ -+ if (rRcpi >= RCPI_100) { /* Best Signal */ -+ u2InitRateSet = INITIAL_RATE_SET(RCPI_100); -+ } else if (rRcpi >= RCPI_80) { /* Better Signal */ -+ u2InitRateSet = INITIAL_RATE_SET(RCPI_80); -+ } else if (rRcpi >= RCPI_60) { /* Good Signal */ -+ u2InitRateSet = INITIAL_RATE_SET(RCPI_60); -+ } else { /* Worse Signal */ -+ /* NOTE(Kevin): If return FALSE, we should assign the BSS Basic Rate Index -+ * (prBssInfo->ucBasicRateIndex) to the initial rate. It was determined in -+ * function - bssUpdateTxRateForControlFrame(). -+ */ -+ return FALSE; -+ } -+ -+ u2RateSet &= u2InitRateSet; -+ -+ for (i = RATE_54M_INDEX; i >= RATE_1M_INDEX; i--) { -+ if (u2RateSet & BIT(i)) { -+ *pucInitialRateIndex = (UINT_8) i; -+ return TRUE; -+ } -+ } -+ -+ return FALSE; -+ -+} /* end of rateGetBestInitialRateIndex() */ -+#endif -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rlm.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rlm.c -new file mode 100644 -index 000000000000..244346983f40 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rlm.c -@@ -0,0 +1,1858 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/rlm.c#2 -+*/ -+ -+/*! \file "rlm.c" -+ \brief -+ -+*/ -+ -+/* -+** Log: rlm.c -+ * -+ * 07 17 2012 yuche.tsai -+ * NULL -+ * Compile no error before trial run. -+ * -+ * 11 15 2011 cm.chang -+ * NULL -+ * Check length HT cap IE about RX associate request frame -+ * -+ * 11 10 2011 cm.chang -+ * NULL -+ * Modify debug message for XLOG -+ * -+ * 11 08 2011 cm.chang -+ * NULL -+ * Add RLM and CNM debug message for XLOG -+ * -+ * 11 03 2011 cm.chang -+ * [WCXRP00000997] [MT6620 Wi-Fi][Driver][FW] Handle change of BSS preamble type and slot time -+ * Fix preamble type of STA mode -+ * -+ * 10 25 2011 cm.chang -+ * [WCXRP00001058] [All Wi-Fi][Driver] Fix sta_rec's phyTypeSet and OBSS scan in AP mode -+ * Not send ERP IE if peer STA is 802.11b-only -+ * -+ * 10 11 2011 cm.chang -+ * [WCXRP00001031] [All Wi-Fi][Driver] Check HT IE length to avoid wrong SCO parameter -+ * Ignore HT OP IE if its length field is not valid -+ * -+ * 09 28 2011 cm.chang -+ * NULL -+ * Add length check to reduce possibility to adopt wrong IE -+ * -+ * 09 20 2011 cm.chang -+ * [WCXRP00000997] [MT6620 Wi-Fi][Driver][FW] Handle change of BSS preamble type and slot time -+ * Handle client mode about preamble type and slot time -+ * -+ * 09 01 2011 cm.chang -+ * [WCXRP00000971] [MT6620 Wi-Fi][Driver][FW] Not set Beacon timeout interval when CPTT -+ * Final channel number only adopts the field from assoc response -+ * -+ * 06 10 2011 cm.chang -+ * [WCXRP00000773] [MT6620 Wi-Fi][Driver] Workaround some AP fill primary channel field with its secondary channel -+ * If DS IE exists, ignore the primary channel field in HT OP IE -+ * -+ * 05 03 2011 cm.chang -+ * [WCXRP00000691] [MT6620 Wi-Fi][Driver] Workaround about AP's wrong HT capability IE to have wrong channel number -+ * Fix compiling error -+ * -+ * 05 02 2011 cm.chang -+ * [WCXRP00000691] [MT6620 Wi-Fi][Driver] Workaround about AP's wrong HT capability IE to have wrong channel number -+ * Refine range of valid channel number -+ * -+ * 05 02 2011 cm.chang -+ * [WCXRP00000691] [MT6620 Wi-Fi][Driver] Workaround about AP's wrong HT capability IE to have wrong channel number -+ * Check if channel is valided before record ing BSS channel -+ * -+ * 04 14 2011 cm.chang -+ * [WCXRP00000634] [MT6620 Wi-Fi][Driver][FW] 2nd BSS will not support 40MHz bandwidth for concurrency -+ * . -+ * -+ * 04 12 2011 cm.chang -+ * [WCXRP00000634] [MT6620 Wi-Fi][Driver][FW] 2nd BSS will not support 40MHz bandwidth for concurrency -+ * . -+ * -+ * 03 29 2011 cm.chang -+ * [WCXRP00000606] [MT6620 Wi-Fi][Driver][FW] Fix klocwork warning -+ * As CR title -+ * -+ * 01 24 2011 cm.chang -+ * [WCXRP00000384] [MT6620 Wi-Fi][Driver][FW] Handle 20/40 action frame in AP mode -+ * and stop ampdu timer when sta_rec is freed -+ * Process received 20/40 coexistence action frame for AP mode -+ * -+ * 12 13 2010 cp.wu -+ * [WCXRP00000260] [MT6620 Wi-Fi][Driver][Firmware] Create V1.1 branch for both firmware and driver -+ * create branch for Wi-Fi driver v1.1 -+ * -+ * 12 07 2010 cm.chang -+ * [WCXRP00000239] MT6620 Wi-Fi][Driver][FW] Merge concurrent branch back to maintrunk -+ * 1. BSSINFO include RLM parameter -+ * 2. free all sta records when network is disconnected -+ * -+ * 12 07 2010 cm.chang -+ * [WCXRP00000238] MT6620 Wi-Fi][Driver][FW] Support regulation domain setting from NVRAM and supplicant -+ * 1. Country code is from NVRAM or supplicant -+ * 2. Change band definition in CMD/EVENT. -+ * -+ * 10 15 2010 cm.chang -+ * [WCXRP00000094] [MT6620 Wi-Fi][Driver] Connect to 2.4GHz AP, Driver crash. -+ * Add exception handle when no mgmt buffer in free build -+ * -+ * 10 08 2010 cm.chang -+ * NULL -+ * When 20M only setting, ignore OBSS IE -+ * -+ * 09 16 2010 cm.chang -+ * NULL -+ * Change conditional compiling options for BOW -+ * -+ * 09 10 2010 cm.chang -+ * NULL -+ * Always update Beacon content if FW sync OBSS info -+ * -+ * 09 03 2010 kevin.huang -+ * NULL -+ * Refine #include sequence and solve recursive/nested #include issue -+ * -+ * 08 24 2010 cm.chang -+ * NULL -+ * Support RLM initail channel of Ad-hoc, P2P and BOW -+ * -+ * 08 23 2010 cp.wu -+ * NULL -+ * revise constant definitions to be matched with implementation (original cmd-event definition is deprecated) -+ * -+ * 08 23 2010 chinghwa.yu -+ * NULL -+ * Temporary add rlmUpdateParamByStaForBow() and rlmBssInitForBow(). -+ * -+ * 08 23 2010 chinghwa.yu -+ * NULL -+ * Add CFG_ENABLE_BT_OVER_WIFI. -+ * -+ * 08 23 2010 chinghwa.yu -+ * NULL -+ * Update for BOW. -+ * -+ * 08 20 2010 cm.chang -+ * NULL -+ * Migrate RLM code to host from FW -+ * -+ * 08 02 2010 yuche.tsai -+ * NULL -+ * P2P Group Negotiation Code Check in. -+ * -+ * 07 26 2010 yuche.tsai -+ * -+ * Fix compile error while enabling WiFi Direct function. -+ * -+ * 07 21 2010 yuche.tsai -+ * -+ * Add P2P Scan & Scan Result Parsing & Saving. -+ * -+ * 07 19 2010 cm.chang -+ * -+ * Set RLM parameters and enable CNM channel manager -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 07 08 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * take use of RLM module for parsing/generating HT IEs for 11n capability -+ * -+ * 07 08 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Check draft RLM code for HT cap -+ * -+ * 06 05 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Fix channel ID definition in RFB status to primary channel instead of center channel -+ * -+ * 06 02 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Add TX short GI compiling option -+ * -+ * 06 02 2010 chinghwa.yu -+ * [BORA00000563]Add WiFi CoEx BCM module -+ * Roll back to remove CFG_SUPPORT_BCM_TEST. -+ * -+ * 06 01 2010 chinghwa.yu -+ * [BORA00000563]Add WiFi CoEx BCM module -+ * Update BCM Test and RW configuration. -+ * -+ * 05 31 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Add some compiling options to control 11n functions -+ * -+ * 05 28 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Set RTS threshold of 2K bytes initially -+ * -+ * 05 18 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Ad-hoc Beacon should not carry HT OP and OBSS IEs -+ * -+ * 05 07 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Process 20/40 coexistence public action frame in AP mode -+ * -+ * 05 05 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * First draft support for 20/40M bandwidth for AP mode -+ * -+ * 04 24 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * g_aprBssInfo[] depends on CFG_SUPPORT_P2P and CFG_SUPPORT_BOW -+ * -+ * 04 22 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * First draft code to support protection in AP mode -+ * -+ * 04 13 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Utilize status of swRfb to know channel number and band -+ * -+ * 04 07 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Different invoking order for WTBL entry of associated AP -+ * -+ * 04 07 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Add virtual test for OBSS scan -+ * -+ * 04 02 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Process Beacon only ready for infra STA now -+ * -+ * 03 30 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Support 2.4G OBSS scan -+ * -+ * 03 24 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Not carry HT cap when being associated with b/g only AP -+ * -+ * 03 24 2010 wh.su -+ * [BORA00000605][WIFISYS] Phase3 Integration -+ * fixed some WHQL testing error. -+ * -+ * 03 15 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Provide draft measurement and quiet functions -+ * -+ * 03 09 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * If bss is not 11n network, zero WTBL HT parameters -+ * -+ * 03 03 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * To support CFG_SUPPORT_BCM_STP -+ * -+ * 03 02 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Generate HT IE only depending on own phyTypeSet -+ * -+ * 03 02 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Not fill HT related IE if BssInfo does not include 11n phySet -+ * -+ * 03 01 2010 tehuang.liu -+ * [BORA00000569][WIFISYS] Phase 2 Integration Test -+ * To store field AMPDU Parameters in STA_REC -+ * -+ * 02 26 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Enable RDG RX, but disable RDG TX for IOT and LongNAV -+ * -+ * 02 12 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Use bss info array for concurrent handle -+ * -+ * 02 05 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Add AAA Module Support, Revise Net Type to Net Type Index for array lookup -+ * -+ * 01 22 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Support protection and bandwidth switch -+ * -+ * 01 07 2010 kevin.huang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Modify the parameter of rlmRecAssocRspHtInfo function -+ * -+ * 12 18 2009 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * . -+ * -+ * Dec 12 2009 mtk01104 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Fix prBssInfo->ucPrimaryChannel handle for assoc resp -+ * -+ * Dec 9 2009 mtk01104 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Add some function to process HT operation -+ * -+ * Nov 28 2009 mtk01104 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Call rlmStatisticsInit() to handle MIB counters -+ * -+ * Nov 18 2009 mtk01104 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * -+ * -+** -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "precomp.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+static VOID rlmFillHtCapIE(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo, P_MSDU_INFO_T prMsduInfo); -+ -+static VOID rlmFillExtCapIE(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo, P_MSDU_INFO_T prMsduInfo); -+ -+static VOID rlmFillHtOpIE(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo, P_MSDU_INFO_T prMsduInfo); -+ -+static UINT_8 rlmRecIeInfoForClient(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo, PUINT_8 pucIE, UINT_16 u2IELength); -+ -+static BOOLEAN -+rlmRecBcnFromNeighborForClient(P_ADAPTER_T prAdapter, -+ P_BSS_INFO_T prBssInfo, P_SW_RFB_T prSwRfb, PUINT_8 pucIE, UINT_16 u2IELength); -+ -+static BOOLEAN -+rlmRecBcnInfoForClient(P_ADAPTER_T prAdapter, -+ P_BSS_INFO_T prBssInfo, P_SW_RFB_T prSwRfb, PUINT_8 pucIE, UINT_16 u2IELength); -+ -+static VOID rlmBssReset(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo); -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rlmFsmEventInit(P_ADAPTER_T prAdapter) -+{ -+ ASSERT(prAdapter); -+ -+ /* Note: assume TIMER_T structures are reset to zero or stopped -+ * before invoking this function. -+ */ -+ -+ /* Initialize OBSS FSM */ -+ rlmObssInit(prAdapter); -+#if CFG_SUPPORT_PWR_LIMIT_COUNTRY -+ rlmDomainCheckCountryPowerLimitTable(prAdapter); -+#endif -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rlmFsmEventUninit(P_ADAPTER_T prAdapter) -+{ -+ P_BSS_INFO_T prBssInfo; -+ UINT_8 ucNetIdx; -+ -+ ASSERT(prAdapter); -+ -+ RLM_NET_FOR_EACH(ucNetIdx) { -+ prBssInfo = &prAdapter->rWifiVar.arBssInfo[ucNetIdx]; -+ ASSERT(prBssInfo); -+ -+ /* Note: all RLM timers will also be stopped. -+ * Now only one OBSS scan timer. -+ */ -+ rlmBssReset(prAdapter, prBssInfo); -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief For probe request, association request -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rlmReqGenerateHtCapIE(P_ADAPTER_T prAdapter, P_MSDU_INFO_T prMsduInfo) -+{ -+ P_BSS_INFO_T prBssInfo; -+ P_STA_RECORD_T prStaRec; -+ -+ ASSERT(prAdapter); -+ ASSERT(prMsduInfo); -+ -+ prBssInfo = &prAdapter->rWifiVar.arBssInfo[prMsduInfo->ucNetworkType]; -+ ASSERT(prBssInfo); -+ -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); -+ -+ if ((prAdapter->rWifiVar.ucAvailablePhyTypeSet & PHY_TYPE_SET_802_11N) && -+ (!prStaRec || (prStaRec->ucPhyTypeSet & PHY_TYPE_SET_802_11N))) -+ rlmFillHtCapIE(prAdapter, prBssInfo, prMsduInfo); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief For probe request, association request -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rlmReqGenerateExtCapIE(P_ADAPTER_T prAdapter, P_MSDU_INFO_T prMsduInfo) -+{ -+ P_BSS_INFO_T prBssInfo; -+ P_STA_RECORD_T prStaRec; -+ -+ ASSERT(prAdapter); -+ ASSERT(prMsduInfo); -+ -+ prBssInfo = &prAdapter->rWifiVar.arBssInfo[prMsduInfo->ucNetworkType]; -+ ASSERT(prBssInfo); -+ -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); -+ -+ if ((prAdapter->rWifiVar.ucAvailablePhyTypeSet & PHY_TYPE_SET_802_11N) && -+ (!prStaRec || (prStaRec->ucPhyTypeSet & PHY_TYPE_SET_802_11N))) -+ rlmFillExtCapIE(prAdapter, prBssInfo, prMsduInfo); -+#if CFG_SUPPORT_HOTSPOT_2_0 -+ else if (prAdapter->prGlueInfo->fgConnectHS20AP == TRUE) -+ hs20FillExtCapIE(prAdapter, prBssInfo, prMsduInfo); -+#endif -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief For probe response (GO, IBSS) and association response -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rlmRspGenerateHtCapIE(P_ADAPTER_T prAdapter, P_MSDU_INFO_T prMsduInfo) -+{ -+ P_BSS_INFO_T prBssInfo; -+ P_STA_RECORD_T prStaRec; -+ -+ ASSERT(prAdapter); -+ ASSERT(prMsduInfo); -+ ASSERT(IS_NET_ACTIVE(prAdapter, prMsduInfo->ucNetworkType)); -+ -+ prBssInfo = &prAdapter->rWifiVar.arBssInfo[prMsduInfo->ucNetworkType]; -+ ASSERT(prBssInfo); -+ -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); -+ -+ if (RLM_NET_IS_11N(prBssInfo) && (!prStaRec || (prStaRec->ucPhyTypeSet & PHY_TYPE_SET_802_11N))) -+ rlmFillHtCapIE(prAdapter, prBssInfo, prMsduInfo); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief For probe response (GO, IBSS) and association response -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rlmRspGenerateExtCapIE(P_ADAPTER_T prAdapter, P_MSDU_INFO_T prMsduInfo) -+{ -+ P_BSS_INFO_T prBssInfo; -+ P_STA_RECORD_T prStaRec; -+ -+ ASSERT(prAdapter); -+ ASSERT(prMsduInfo); -+ ASSERT(IS_NET_ACTIVE(prAdapter, prMsduInfo->ucNetworkType)); -+ -+ prBssInfo = &prAdapter->rWifiVar.arBssInfo[prMsduInfo->ucNetworkType]; -+ ASSERT(prBssInfo); -+ -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); -+ -+ if (RLM_NET_IS_11N(prBssInfo) && (!prStaRec || (prStaRec->ucPhyTypeSet & PHY_TYPE_SET_802_11N))) -+ rlmFillExtCapIE(prAdapter, prBssInfo, prMsduInfo); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief For probe response (GO, IBSS) and association response -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rlmRspGenerateHtOpIE(P_ADAPTER_T prAdapter, P_MSDU_INFO_T prMsduInfo) -+{ -+ P_BSS_INFO_T prBssInfo; -+ P_STA_RECORD_T prStaRec; -+ -+ ASSERT(prAdapter); -+ ASSERT(prMsduInfo); -+ ASSERT(IS_NET_ACTIVE(prAdapter, prMsduInfo->ucNetworkType)); -+ -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); -+ -+ prBssInfo = &prAdapter->rWifiVar.arBssInfo[prMsduInfo->ucNetworkType]; -+ ASSERT(prBssInfo); -+ -+ if (RLM_NET_IS_11N(prBssInfo) && (!prStaRec || (prStaRec->ucPhyTypeSet & PHY_TYPE_SET_802_11N))) -+ rlmFillHtOpIE(prAdapter, prBssInfo, prMsduInfo); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief For probe response (GO, IBSS) and association response -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rlmRspGenerateErpIE(P_ADAPTER_T prAdapter, P_MSDU_INFO_T prMsduInfo) -+{ -+ P_BSS_INFO_T prBssInfo; -+ P_STA_RECORD_T prStaRec; -+ P_IE_ERP_T prErpIe; -+ -+ ASSERT(prAdapter); -+ ASSERT(prMsduInfo); -+ ASSERT(IS_NET_ACTIVE(prAdapter, prMsduInfo->ucNetworkType)); -+ -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); -+ -+ prBssInfo = &prAdapter->rWifiVar.arBssInfo[prMsduInfo->ucNetworkType]; -+ ASSERT(prBssInfo); -+ -+ if (RLM_NET_IS_11GN(prBssInfo) && prBssInfo->eBand == BAND_2G4 && -+ (!prStaRec || (prStaRec->ucPhyTypeSet & PHY_TYPE_SET_802_11GN))) { -+ prErpIe = (P_IE_ERP_T) -+ (((PUINT_8) prMsduInfo->prPacket) + prMsduInfo->u2FrameLength); -+ -+ /* Add ERP IE */ -+ prErpIe->ucId = ELEM_ID_ERP_INFO; -+ prErpIe->ucLength = 1; -+ -+ prErpIe->ucERP = prBssInfo->fgObssErpProtectMode ? ERP_INFO_USE_PROTECTION : 0; -+ -+ if (prBssInfo->fgErpProtectMode) -+ prErpIe->ucERP |= (ERP_INFO_NON_ERP_PRESENT | ERP_INFO_USE_PROTECTION); -+ -+ /* Handle barker preamble */ -+ if (!prBssInfo->fgUseShortPreamble) -+ prErpIe->ucERP |= ERP_INFO_BARKER_PREAMBLE_MODE; -+ -+ ASSERT(IE_SIZE(prErpIe) <= (ELEM_HDR_LEN + ELEM_MAX_LEN_ERP)); -+ -+ prMsduInfo->u2FrameLength += IE_SIZE(prErpIe); -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT32 -+rlmFillHtCapIEByParams(BOOLEAN fg40mAllowed, -+ BOOLEAN fgShortGIDisabled, -+ UINT_8 u8SupportRxSgi20, -+ UINT_8 u8SupportRxSgi40, -+ UINT_8 u8SupportRxGf, UINT_8 u8SupportRxSTBC, ENUM_OP_MODE_T eCurrentOPMode, UINT_8 *pOutBuf) -+{ -+ P_IE_HT_CAP_T prHtCap; -+ P_SUP_MCS_SET_FIELD prSupMcsSet; -+ -+ ASSERT(pOutBuf); -+ -+ prHtCap = (P_IE_HT_CAP_T) pOutBuf; -+ -+ /* Add HT capabilities IE */ -+ prHtCap->ucId = ELEM_ID_HT_CAP; -+ prHtCap->ucLength = sizeof(IE_HT_CAP_T) - ELEM_HDR_LEN; -+ -+ prHtCap->u2HtCapInfo = HT_CAP_INFO_DEFAULT_VAL; -+ if (!fg40mAllowed) { -+ prHtCap->u2HtCapInfo &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH | -+ HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_DSSS_CCK_IN_40M); -+ } -+ if (fgShortGIDisabled) -+ prHtCap->u2HtCapInfo &= ~(HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M); -+ -+ if (u8SupportRxSgi20 == 2) -+ prHtCap->u2HtCapInfo &= ~(HT_CAP_INFO_SHORT_GI_20M); -+ if (u8SupportRxSgi40 == 2) -+ prHtCap->u2HtCapInfo &= ~(HT_CAP_INFO_SHORT_GI_40M); -+ if (u8SupportRxGf == 2) -+ prHtCap->u2HtCapInfo &= ~(HT_CAP_INFO_HT_GF); -+ if (u8SupportRxSTBC == 2) -+ prHtCap->u2HtCapInfo &= ~(HT_CAP_INFO_RX_STBC_1_SS); -+ prHtCap->ucAmpduParam = AMPDU_PARAM_DEFAULT_VAL; -+ -+ prSupMcsSet = &prHtCap->rSupMcsSet; -+ kalMemZero((PVOID)&prSupMcsSet->aucRxMcsBitmask[0], SUP_MCS_RX_BITMASK_OCTET_NUM); -+ -+ prSupMcsSet->aucRxMcsBitmask[0] = BITS(0, 7); -+ -+ if (fg40mAllowed) -+ prSupMcsSet->aucRxMcsBitmask[32 / 8] = BIT(0); /* MCS32 */ -+ prSupMcsSet->u2RxHighestSupportedRate = SUP_MCS_RX_DEFAULT_HIGHEST_RATE; -+ prSupMcsSet->u4TxRateInfo = SUP_MCS_TX_DEFAULT_VAL; -+ -+ prHtCap->u2HtExtendedCap = HT_EXT_CAP_DEFAULT_VAL; -+ if (!fg40mAllowed || eCurrentOPMode != OP_MODE_INFRASTRUCTURE) -+ prHtCap->u2HtExtendedCap &= ~(HT_EXT_CAP_PCO | HT_EXT_CAP_PCO_TRANS_TIME_NONE); -+ -+ prHtCap->u4TxBeamformingCap = TX_BEAMFORMING_CAP_DEFAULT_VAL; -+ -+ prHtCap->ucAselCap = ASEL_CAP_DEFAULT_VAL; -+ -+ ASSERT(IE_SIZE(prHtCap) <= (ELEM_HDR_LEN + ELEM_MAX_LEN_HT_CAP)); -+ -+ return IE_SIZE(prHtCap); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+static VOID rlmFillHtCapIE(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo, P_MSDU_INFO_T prMsduInfo) -+{ -+ P_IE_HT_CAP_T prHtCap; -+/* P_SUP_MCS_SET_FIELD prSupMcsSet; */ -+ BOOLEAN fg40mAllowed; -+ -+ ASSERT(prAdapter); -+ ASSERT(prBssInfo); -+ ASSERT(prMsduInfo); -+ -+ fg40mAllowed = prBssInfo->fgAssoc40mBwAllowed; -+ -+ prHtCap = (P_IE_HT_CAP_T) -+ (((PUINT_8) prMsduInfo->prPacket) + prMsduInfo->u2FrameLength); -+ -+#if 0 -+ /* Add HT capabilities IE */ -+ prHtCap->ucId = ELEM_ID_HT_CAP; -+ prHtCap->ucLength = sizeof(IE_HT_CAP_T) - ELEM_HDR_LEN; -+ -+ prHtCap->u2HtCapInfo = HT_CAP_INFO_DEFAULT_VAL; -+ if (!fg40mAllowed) -+ prHtCap->u2HtCapInfo &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH | -+ HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_DSSS_CCK_IN_40M); -+ if (prAdapter->rWifiVar.rConnSettings.fgRxShortGIDisabled) -+ prHtCap->u2HtCapInfo &= ~(HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M); -+ -+ if (prAdapter->rWifiVar.u8SupportRxSgi20 == 2) -+ prHtCap->u2HtCapInfo &= ~(HT_CAP_INFO_SHORT_GI_20M); -+ if (prAdapter->rWifiVar.u8SupportRxSgi40 == 2) -+ prHtCap->u2HtCapInfo &= ~(HT_CAP_INFO_SHORT_GI_40M); -+ if (prAdapter->rWifiVar.u8SupportRxGf == 2) -+ prHtCap->u2HtCapInfo &= ~(HT_CAP_INFO_HT_GF); -+ -+ prHtCap->ucAmpduParam = AMPDU_PARAM_DEFAULT_VAL; -+ -+ prSupMcsSet = &prHtCap->rSupMcsSet; -+ kalMemZero((PVOID)&prSupMcsSet->aucRxMcsBitmask[0], SUP_MCS_RX_BITMASK_OCTET_NUM); -+ -+ prSupMcsSet->aucRxMcsBitmask[0] = BITS(0, 7); -+ -+ if (fg40mAllowed) -+ prSupMcsSet->aucRxMcsBitmask[32 / 8] = BIT(0); /* MCS32 */ -+ prSupMcsSet->u2RxHighestSupportedRate = SUP_MCS_RX_DEFAULT_HIGHEST_RATE; -+ prSupMcsSet->u4TxRateInfo = SUP_MCS_TX_DEFAULT_VAL; -+ -+ prHtCap->u2HtExtendedCap = HT_EXT_CAP_DEFAULT_VAL; -+ if (!fg40mAllowed || prBssInfo->eCurrentOPMode != OP_MODE_INFRASTRUCTURE) -+ prHtCap->u2HtExtendedCap &= ~(HT_EXT_CAP_PCO | HT_EXT_CAP_PCO_TRANS_TIME_NONE); -+ -+ prHtCap->u4TxBeamformingCap = TX_BEAMFORMING_CAP_DEFAULT_VAL; -+ -+ prHtCap->ucAselCap = ASEL_CAP_DEFAULT_VAL; -+ -+ ASSERT(IE_SIZE(prHtCap) <= (ELEM_HDR_LEN + ELEM_MAX_LEN_HT_CAP)); -+ -+ prMsduInfo->u2FrameLength += IE_SIZE(prHtCap); -+#else -+ -+ prMsduInfo->u2FrameLength += rlmFillHtCapIEByParams(fg40mAllowed, -+ prAdapter->rWifiVar.rConnSettings.fgRxShortGIDisabled, -+ prAdapter->rWifiVar.u8SupportRxSgi20, -+ prAdapter->rWifiVar.u8SupportRxSgi40, -+ prAdapter->rWifiVar.u8SupportRxGf, -+ prAdapter->rWifiVar.u8SupportRxSTBC, -+ prBssInfo->eCurrentOPMode, (UINT_8 *) prHtCap); -+#endif -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+static VOID rlmFillExtCapIE(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo, P_MSDU_INFO_T prMsduInfo) -+{ -+#if CFG_SUPPORT_HOTSPOT_2_0 -+ P_HS20_EXT_CAP_T prHsExtCap; -+#else -+ P_EXT_CAP_T prExtCap; -+#endif -+ BOOLEAN fg40mAllowed; -+ -+ ASSERT(prAdapter); -+ ASSERT(prMsduInfo); -+ -+ fg40mAllowed = prBssInfo->fgAssoc40mBwAllowed; -+ -+#if CFG_SUPPORT_HOTSPOT_2_0 -+ prHsExtCap = (P_HS20_EXT_CAP_T) -+ (((PUINT_8) prMsduInfo->prPacket) + prMsduInfo->u2FrameLength); -+ prHsExtCap->ucId = ELEM_ID_EXTENDED_CAP; -+ -+ if (prAdapter->prGlueInfo->fgConnectHS20AP == TRUE) -+ prHsExtCap->ucLength = ELEM_MAX_LEN_EXT_CAP; -+ else -+ prHsExtCap->ucLength = 3 - ELEM_HDR_LEN; -+ -+ kalMemZero(prHsExtCap->aucCapabilities, sizeof(prHsExtCap->aucCapabilities)); -+ -+ prHsExtCap->aucCapabilities[0] = ELEM_EXT_CAP_DEFAULT_VAL; -+ -+ if (!fg40mAllowed) -+ prHsExtCap->aucCapabilities[0] &= ~ELEM_EXT_CAP_20_40_COEXIST_SUPPORT; -+ -+ if (prBssInfo->eCurrentOPMode != OP_MODE_INFRASTRUCTURE) -+ prHsExtCap->aucCapabilities[0] &= ~ELEM_EXT_CAP_PSMP_CAP; -+ -+ if (prAdapter->prGlueInfo->fgConnectHS20AP == TRUE) { -+ SET_EXT_CAP(prHsExtCap->aucCapabilities, ELEM_MAX_LEN_EXT_CAP, ELEM_EXT_CAP_INTERWORKING_BIT); -+ -+ /* For R2 WNM-Notification */ -+ SET_EXT_CAP(prHsExtCap->aucCapabilities, ELEM_MAX_LEN_EXT_CAP, ELEM_EXT_CAP_WNM_NOTIFICATION_BIT); -+ } -+ -+ ASSERT(IE_SIZE(prHsExtCap) <= (ELEM_HDR_LEN + ELEM_MAX_LEN_EXT_CAP)); -+ -+ prMsduInfo->u2FrameLength += IE_SIZE(prHsExtCap); -+ -+#else -+ /* Add Extended Capabilities IE */ -+ prExtCap = (P_EXT_CAP_T) -+ (((PUINT_8) prMsduInfo->prPacket) + prMsduInfo->u2FrameLength); -+ -+ prExtCap->ucId = ELEM_ID_EXTENDED_CAP; -+ -+ prExtCap->ucLength = 3 - ELEM_HDR_LEN; -+ kalMemZero(prExtCap->aucCapabilities, sizeof(prExtCap->aucCapabilities)); -+ -+ prExtCap->aucCapabilities[0] = ELEM_EXT_CAP_DEFAULT_VAL; -+ -+ if (!fg40mAllowed) -+ prExtCap->aucCapabilities[0] &= ~ELEM_EXT_CAP_20_40_COEXIST_SUPPORT; -+ -+ if (prBssInfo->eCurrentOPMode != OP_MODE_INFRASTRUCTURE) -+ prExtCap->aucCapabilities[0] &= ~ELEM_EXT_CAP_PSMP_CAP; -+ -+ ASSERT(IE_SIZE(prExtCap) <= (ELEM_HDR_LEN + ELEM_MAX_LEN_EXT_CAP)); -+ -+ prMsduInfo->u2FrameLength += IE_SIZE(prExtCap); -+#endif -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT32 rlmFillHtOpIeBody(P_BSS_INFO_T prBssInfo, UINT_8 *pFme) -+{ -+ P_IE_HT_OP_T prHtOp; -+ UINT_16 i; -+ -+ prHtOp = (P_IE_HT_OP_T) pFme; -+ -+ /* Add HT operation IE */ -+ prHtOp->ucId = ELEM_ID_HT_OP; -+ prHtOp->ucLength = sizeof(IE_HT_OP_T) - ELEM_HDR_LEN; -+ -+ /* RIFS and 20/40 bandwidth operations are included */ -+ prHtOp->ucPrimaryChannel = prBssInfo->ucPrimaryChannel; -+ prHtOp->ucInfo1 = prBssInfo->ucHtOpInfo1; -+ -+ /* Decide HT protection mode field */ -+ if (prBssInfo->eHtProtectMode == HT_PROTECT_MODE_NON_HT) -+ prHtOp->u2Info2 = (UINT_8) HT_PROTECT_MODE_NON_HT; -+ else if (prBssInfo->eObssHtProtectMode == HT_PROTECT_MODE_NON_MEMBER) -+ prHtOp->u2Info2 = (UINT_8) HT_PROTECT_MODE_NON_MEMBER; -+ else { -+ /* It may be SYS_PROTECT_MODE_NONE or SYS_PROTECT_MODE_20M */ -+ prHtOp->u2Info2 = (UINT_8) prBssInfo->eHtProtectMode; -+ } -+ -+ if (prBssInfo->eGfOperationMode != GF_MODE_NORMAL) { -+ /* It may be GF_MODE_PROTECT or GF_MODE_DISALLOWED -+ * Note: it will also be set in ad-hoc network -+ */ -+ prHtOp->u2Info2 |= HT_OP_INFO2_NON_GF_HT_STA_PRESENT; -+ } -+ -+ if (0 /* Regulatory class 16 */ && -+ prBssInfo->eObssHtProtectMode == HT_PROTECT_MODE_NON_MEMBER) { -+ /* (TBD) It is HT_PROTECT_MODE_NON_MEMBER, so require protection -+ * although it is possible to have no protection by spec. -+ */ -+ prHtOp->u2Info2 |= HT_OP_INFO2_OBSS_NON_HT_STA_PRESENT; -+ } -+ -+ prHtOp->u2Info3 = prBssInfo->u2HtOpInfo3; /* To do: handle L-SIG TXOP */ -+ -+ /* No basic MCSx are needed temporarily */ -+ for (i = 0; i < 16; i++) -+ prHtOp->aucBasicMcsSet[i] = 0; -+ -+ return sizeof(IE_HT_OP_T); -+} -+ -+static VOID rlmFillHtOpIE(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo, P_MSDU_INFO_T prMsduInfo) -+{ -+/* P_IE_HT_OP_T prHtOp; */ -+/* UINT_16 i; */ -+ -+ ASSERT(prAdapter); -+ ASSERT(prBssInfo); -+ ASSERT(prMsduInfo); -+ -+ prMsduInfo->u2FrameLength += rlmFillHtOpIeBody(prBssInfo, -+ (((PUINT_8) prMsduInfo->prPacket) + prMsduInfo->u2FrameLength)); -+#if 0 -+ prHtOp = (P_IE_HT_OP_T) -+ (((PUINT_8) prMsduInfo->prPacket) + prMsduInfo->u2FrameLength); -+ -+ /* Add HT operation IE */ -+ prHtOp->ucId = ELEM_ID_HT_OP; -+ prHtOp->ucLength = sizeof(IE_HT_OP_T) - ELEM_HDR_LEN; -+ -+ /* RIFS and 20/40 bandwidth operations are included */ -+ prHtOp->ucPrimaryChannel = prBssInfo->ucPrimaryChannel; -+ prHtOp->ucInfo1 = prBssInfo->ucHtOpInfo1; -+ -+ /* Decide HT protection mode field */ -+ if (prBssInfo->eHtProtectMode == HT_PROTECT_MODE_NON_HT) -+ prHtOp->u2Info2 = (UINT_8) HT_PROTECT_MODE_NON_HT; -+ else if (prBssInfo->eObssHtProtectMode == HT_PROTECT_MODE_NON_MEMBER) -+ prHtOp->u2Info2 = (UINT_8) HT_PROTECT_MODE_NON_MEMBER; -+ else { -+ /* It may be SYS_PROTECT_MODE_NONE or SYS_PROTECT_MODE_20M */ -+ prHtOp->u2Info2 = (UINT_8) prBssInfo->eHtProtectMode; -+ } -+ -+ if (prBssInfo->eGfOperationMode != GF_MODE_NORMAL) { -+ /* It may be GF_MODE_PROTECT or GF_MODE_DISALLOWED -+ * Note: it will also be set in ad-hoc network -+ */ -+ prHtOp->u2Info2 |= HT_OP_INFO2_NON_GF_HT_STA_PRESENT; -+ } -+ -+ if (0 /* Regulatory class 16 */ && -+ prBssInfo->eObssHtProtectMode == HT_PROTECT_MODE_NON_MEMBER) { -+ /* (TBD) It is HT_PROTECT_MODE_NON_MEMBER, so require protection -+ * although it is possible to have no protection by spec. -+ */ -+ prHtOp->u2Info2 |= HT_OP_INFO2_OBSS_NON_HT_STA_PRESENT; -+ } -+ -+ prHtOp->u2Info3 = prBssInfo->u2HtOpInfo3; /* To do: handle L-SIG TXOP */ -+ -+ /* No basic MCSx are needed temporarily */ -+ for (i = 0; i < 16; i++) -+ prHtOp->aucBasicMcsSet[i] = 0; -+ -+ ASSERT(IE_SIZE(prHtOp) <= (ELEM_HDR_LEN + ELEM_MAX_LEN_HT_OP)); -+ -+ prMsduInfo->u2FrameLength += IE_SIZE(prHtOp); -+#endif -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function should be invoked to update parameters of associated AP. -+* (Association response and Beacon) -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+static UINT_8 rlmRecIeInfoForClient(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo, PUINT_8 pucIE, UINT_16 u2IELength) -+{ -+ UINT_16 u2Offset; -+ P_STA_RECORD_T prStaRec; -+ P_IE_HT_CAP_T prHtCap; -+ P_IE_HT_OP_T prHtOp; -+ P_IE_OBSS_SCAN_PARAM_T prObssScnParam; -+ UINT_8 ucERP, ucPrimaryChannel; -+#if CFG_SUPPORT_QUIET && 0 -+ BOOLEAN fgHasQuietIE = FALSE; -+#endif -+ -+ ASSERT(prAdapter); -+ ASSERT(prBssInfo); -+ ASSERT(pucIE); -+ -+ prStaRec = prBssInfo->prStaRecOfAP; -+ ASSERT(prStaRec); -+ if (!prStaRec) -+ return 0; -+ -+ prBssInfo->fgUseShortPreamble = prBssInfo->fgIsShortPreambleAllowed; -+ ucPrimaryChannel = 0; -+ prObssScnParam = NULL; -+ -+ /* Note: HT-related members in staRec may not be zero before, so -+ * if following IE does not exist, they are still not zero. -+ * These HT-related parameters are valid only when the corresponding -+ * BssInfo supports 802.11n, i.e., RLM_NET_IS_11N() -+ */ -+ IE_FOR_EACH(pucIE, u2IELength, u2Offset) { -+ switch (IE_ID(pucIE)) { -+ case ELEM_ID_HT_CAP: -+ if (!RLM_NET_IS_11N(prBssInfo) || IE_LEN(pucIE) != (sizeof(IE_HT_CAP_T) - 2)) -+ break; -+ prHtCap = (P_IE_HT_CAP_T) pucIE; -+ prStaRec->ucMcsSet = prHtCap->rSupMcsSet.aucRxMcsBitmask[0]; -+ prStaRec->fgSupMcs32 = (prHtCap->rSupMcsSet.aucRxMcsBitmask[32 / 8] & BIT(0)) ? TRUE : FALSE; -+ -+ prStaRec->u2HtCapInfo = prHtCap->u2HtCapInfo; -+ prStaRec->ucAmpduParam = prHtCap->ucAmpduParam; -+ prStaRec->u2HtExtendedCap = prHtCap->u2HtExtendedCap; -+ prStaRec->u4TxBeamformingCap = prHtCap->u4TxBeamformingCap; -+ prStaRec->ucAselCap = prHtCap->ucAselCap; -+ break; -+ -+ case ELEM_ID_HT_OP: -+ if (!RLM_NET_IS_11N(prBssInfo) || IE_LEN(pucIE) != (sizeof(IE_HT_OP_T) - 2)) -+ break; -+ prHtOp = (P_IE_HT_OP_T) pucIE; -+ /* Workaround that some APs fill primary channel field by its -+ * secondary channel, but its DS IE is correct 20110610 -+ */ -+ if (ucPrimaryChannel == 0) -+ ucPrimaryChannel = prHtOp->ucPrimaryChannel; -+ prBssInfo->ucHtOpInfo1 = prHtOp->ucInfo1; -+ prBssInfo->u2HtOpInfo2 = prHtOp->u2Info2; -+ prBssInfo->u2HtOpInfo3 = prHtOp->u2Info3; -+ -+ if (!prBssInfo->fg40mBwAllowed) -+ prBssInfo->ucHtOpInfo1 &= ~(HT_OP_INFO1_SCO | HT_OP_INFO1_STA_CHNL_WIDTH); -+ -+ if ((prBssInfo->ucHtOpInfo1 & HT_OP_INFO1_SCO) != CHNL_EXT_RES) -+ prBssInfo->eBssSCO = (ENUM_CHNL_EXT_T)(prBssInfo->ucHtOpInfo1 & HT_OP_INFO1_SCO); -+ -+ prBssInfo->eHtProtectMode = (ENUM_HT_PROTECT_MODE_T) -+ (prBssInfo->u2HtOpInfo2 & HT_OP_INFO2_HT_PROTECTION); -+ -+ /* To do: process regulatory class 16 */ -+ if ((prBssInfo->u2HtOpInfo2 & HT_OP_INFO2_OBSS_NON_HT_STA_PRESENT) -+ && 0 /* && regulatory class is 16 */) -+ prBssInfo->eGfOperationMode = GF_MODE_DISALLOWED; -+ else if (prBssInfo->u2HtOpInfo2 & HT_OP_INFO2_NON_GF_HT_STA_PRESENT) -+ prBssInfo->eGfOperationMode = GF_MODE_PROTECT; -+ else -+ prBssInfo->eGfOperationMode = GF_MODE_NORMAL; -+ -+ prBssInfo->eRifsOperationMode = -+ (prBssInfo->ucHtOpInfo1 & HT_OP_INFO1_RIFS_MODE) ? RIFS_MODE_NORMAL : RIFS_MODE_DISALLOWED; -+ -+ break; -+ -+ case ELEM_ID_20_40_BSS_COEXISTENCE: -+ if (!RLM_NET_IS_11N(prBssInfo)) -+ break; -+ /* To do: store if scanning exemption grant to BssInfo */ -+ break; -+ -+ case ELEM_ID_OBSS_SCAN_PARAMS: -+ if (!RLM_NET_IS_11N(prBssInfo) || IE_LEN(pucIE) != (sizeof(IE_OBSS_SCAN_PARAM_T) - 2)) -+ break; -+ /* Store OBSS parameters to BssInfo */ -+ prObssScnParam = (P_IE_OBSS_SCAN_PARAM_T) pucIE; -+ break; -+ -+ case ELEM_ID_EXTENDED_CAP: -+ if (!RLM_NET_IS_11N(prBssInfo)) -+ break; -+ /* To do: store extended capability (PSMP, coexist) to BssInfo */ -+ break; -+ -+ case ELEM_ID_ERP_INFO: -+ if (IE_LEN(pucIE) != (sizeof(IE_ERP_T) - 2) || prBssInfo->eBand != BAND_2G4) -+ break; -+ ucERP = ERP_INFO_IE(pucIE)->ucERP; -+ prBssInfo->fgErpProtectMode = (ucERP & ERP_INFO_USE_PROTECTION) ? TRUE : FALSE; -+ -+ if (ucERP & ERP_INFO_BARKER_PREAMBLE_MODE) -+ prBssInfo->fgUseShortPreamble = FALSE; -+ break; -+ -+ case ELEM_ID_DS_PARAM_SET: -+ if (IE_LEN(pucIE) == ELEM_MAX_LEN_DS_PARAMETER_SET) -+ ucPrimaryChannel = DS_PARAM_IE(pucIE)->ucCurrChnl; -+ break; -+ -+#if CFG_SUPPORT_DFS /* Add by Enlai */ -+ case ELEM_ID_CH_SW_ANNOUNCEMENT: -+ { -+ rlmProcessChannelSwitchIE(prAdapter, (P_IE_CHANNEL_SWITCH_T) pucIE); -+ } -+ break; -+ -+#if CFG_SUPPORT_QUIET && 0 -+ /* Note: RRM code should be moved to independent RRM function by -+ * component design rule. But we attach it to RLM temporarily -+ */ -+ case ELEM_ID_QUIET: -+ rrmQuietHandleQuietIE(prBssInfo, (P_IE_QUIET_T) pucIE); -+ fgHasQuietIE = TRUE; -+ break; -+#endif -+#endif -+ -+ default: -+ break; -+ } /* end of switch */ -+ } /* end of IE_FOR_EACH */ -+ -+ /* Some AP will have wrong channel number (255) when running time. -+ * Check if correct channel number information. 20110501 -+ */ -+ if ((prBssInfo->eBand == BAND_2G4 && ucPrimaryChannel > 14) || -+ (prBssInfo->eBand != BAND_2G4 && (ucPrimaryChannel >= 200 || ucPrimaryChannel <= 14))) -+ ucPrimaryChannel = 0; -+#if CFG_SUPPORT_QUIET && 0 -+ if (!fgHasQuietIE) -+ rrmQuietIeNotExist(prAdapter, prBssInfo); -+#endif -+ -+ /* Check if OBSS scan process will launch */ -+ if (!prAdapter->fgEnOnlineScan || !prObssScnParam || -+ !(prStaRec->u2HtCapInfo & HT_CAP_INFO_SUP_CHNL_WIDTH) || -+ prBssInfo->eBand != BAND_2G4 || !prBssInfo->fg40mBwAllowed) { -+ -+ /* Note: it is ok not to stop rObssScanTimer() here */ -+ prBssInfo->u2ObssScanInterval = 0; -+ } else { -+ if (prObssScnParam->u2TriggerScanInterval < OBSS_SCAN_MIN_INTERVAL) -+ prObssScnParam->u2TriggerScanInterval = OBSS_SCAN_MIN_INTERVAL; -+ if (prBssInfo->u2ObssScanInterval != prObssScnParam->u2TriggerScanInterval) { -+ -+ prBssInfo->u2ObssScanInterval = prObssScnParam->u2TriggerScanInterval; -+ -+ /* Start timer to trigger OBSS scanning */ -+ cnmTimerStartTimer(prAdapter, &prBssInfo->rObssScanTimer, -+ prBssInfo->u2ObssScanInterval * MSEC_PER_SEC); -+ } -+ } -+ -+ return ucPrimaryChannel; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief AIS or P2P GC. -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+static BOOLEAN -+rlmRecBcnFromNeighborForClient(P_ADAPTER_T prAdapter, -+ P_BSS_INFO_T prBssInfo, P_SW_RFB_T prSwRfb, PUINT_8 pucIE, UINT_16 u2IELength) -+{ -+ UINT_16 u2Offset, i; -+ UINT_8 ucPriChannel, ucSecChannel; -+ ENUM_CHNL_EXT_T eSCO; -+ BOOLEAN fgHtBss, fg20mReq; -+ -+ if ((prAdapter == NULL) -+ || (pucIE == NULL) -+ || (prBssInfo == NULL) -+ || (prSwRfb == NULL)) { -+ ASSERT(FALSE); -+ return FALSE; -+ } -+ -+ /* Record it to channel list to change 20/40 bandwidth */ -+ ucPriChannel = 0; -+ eSCO = CHNL_EXT_SCN; -+ -+ fgHtBss = FALSE; -+ fg20mReq = FALSE; -+ -+ IE_FOR_EACH(pucIE, u2IELength, u2Offset) { -+ switch (IE_ID(pucIE)) { -+ case ELEM_ID_HT_CAP: -+ { -+ P_IE_HT_CAP_T prHtCap; -+ -+ if (IE_LEN(pucIE) != (sizeof(IE_HT_CAP_T) - 2)) -+ break; -+ -+ prHtCap = (P_IE_HT_CAP_T) pucIE; -+ if (prHtCap->u2HtCapInfo & HT_CAP_INFO_40M_INTOLERANT) -+ fg20mReq = TRUE; -+ fgHtBss = TRUE; -+ break; -+ } -+ case ELEM_ID_HT_OP: -+ { -+ P_IE_HT_OP_T prHtOp; -+ -+ if (IE_LEN(pucIE) != (sizeof(IE_HT_OP_T) - 2)) -+ break; -+ -+ prHtOp = (P_IE_HT_OP_T) pucIE; -+ /* Workaround that some APs fill primary channel field by its -+ * secondary channel, but its DS IE is correct 20110610 -+ */ -+ if (ucPriChannel == 0) -+ ucPriChannel = prHtOp->ucPrimaryChannel; -+ -+ if ((prHtOp->ucInfo1 & HT_OP_INFO1_SCO) != CHNL_EXT_RES) -+ eSCO = (ENUM_CHNL_EXT_T) (prHtOp->ucInfo1 & HT_OP_INFO1_SCO); -+ break; -+ } -+ case ELEM_ID_20_40_BSS_COEXISTENCE: -+ { -+ P_IE_20_40_COEXIST_T prCoexist; -+ -+ if (IE_LEN(pucIE) != (sizeof(IE_20_40_COEXIST_T) - 2)) -+ break; -+ -+ prCoexist = (P_IE_20_40_COEXIST_T) pucIE; -+ if (prCoexist->ucData & BSS_COEXIST_40M_INTOLERANT) -+ fg20mReq = TRUE; -+ break; -+ } -+ case ELEM_ID_DS_PARAM_SET: -+ if (IE_LEN(pucIE) != (sizeof(IE_DS_PARAM_SET_T) - 2)) -+ break; -+ ucPriChannel = DS_PARAM_IE(pucIE)->ucCurrChnl; -+ break; -+ -+ default: -+ break; -+ } -+ } -+ -+ /* To do: Update channel list and 5G band. All channel lists have the same -+ * update procedure. We should give it the entry pointer of desired -+ * channel list. -+ */ -+ if (HIF_RX_HDR_GET_RF_BAND(prSwRfb->prHifRxHdr) != BAND_2G4) -+ return FALSE; -+ -+ if (ucPriChannel == 0 || ucPriChannel > 14) -+ ucPriChannel = HIF_RX_HDR_GET_CHNL_NUM(prSwRfb->prHifRxHdr); -+ -+ if (fgHtBss) { -+ ASSERT(prBssInfo->auc2G_PriChnlList[0] <= CHNL_LIST_SZ_2G); -+ for (i = 1; i <= prBssInfo->auc2G_PriChnlList[0] && i <= CHNL_LIST_SZ_2G; i++) { -+ if (prBssInfo->auc2G_PriChnlList[i] == ucPriChannel) -+ break; -+ } -+ if ((i > prBssInfo->auc2G_PriChnlList[0]) && (i <= CHNL_LIST_SZ_2G)) { -+ prBssInfo->auc2G_PriChnlList[i] = ucPriChannel; -+ prBssInfo->auc2G_PriChnlList[0]++; -+ } -+ -+ /* Update secondary channel */ -+ if (eSCO != CHNL_EXT_SCN) { -+ ucSecChannel = (eSCO == CHNL_EXT_SCA) ? (ucPriChannel + 4) : (ucPriChannel - 4); -+ -+ ASSERT(prBssInfo->auc2G_SecChnlList[0] <= CHNL_LIST_SZ_2G); -+ for (i = 1; i <= prBssInfo->auc2G_SecChnlList[0] && i <= CHNL_LIST_SZ_2G; i++) { -+ if (prBssInfo->auc2G_SecChnlList[i] == ucSecChannel) -+ break; -+ } -+ if ((i > prBssInfo->auc2G_SecChnlList[0]) && (i <= CHNL_LIST_SZ_2G)) { -+ prBssInfo->auc2G_SecChnlList[i] = ucSecChannel; -+ prBssInfo->auc2G_SecChnlList[0]++; -+ } -+ } -+ -+ /* Update 20M bandwidth request channels */ -+ if (fg20mReq) { -+ ASSERT(prBssInfo->auc2G_20mReqChnlList[0] <= CHNL_LIST_SZ_2G); -+ for (i = 1; i <= prBssInfo->auc2G_20mReqChnlList[0] && i <= CHNL_LIST_SZ_2G; i++) { -+ if (prBssInfo->auc2G_20mReqChnlList[i] == ucPriChannel) -+ break; -+ } -+ if ((i > prBssInfo->auc2G_20mReqChnlList[0]) && (i <= CHNL_LIST_SZ_2G)) { -+ prBssInfo->auc2G_20mReqChnlList[i] = ucPriChannel; -+ prBssInfo->auc2G_20mReqChnlList[0]++; -+ } -+ } -+ } else { -+ /* Update non-HT channel list */ -+ ASSERT(prBssInfo->auc2G_NonHtChnlList[0] <= CHNL_LIST_SZ_2G); -+ for (i = 1; i <= prBssInfo->auc2G_NonHtChnlList[0] && i <= CHNL_LIST_SZ_2G; i++) { -+ if (prBssInfo->auc2G_NonHtChnlList[i] == ucPriChannel) -+ break; -+ } -+ if ((i > prBssInfo->auc2G_NonHtChnlList[0]) && (i <= CHNL_LIST_SZ_2G)) { -+ prBssInfo->auc2G_NonHtChnlList[i] = ucPriChannel; -+ prBssInfo->auc2G_NonHtChnlList[0]++; -+ } -+ -+ } -+ -+ return FALSE; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief AIS or P2P GC. -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+static BOOLEAN -+rlmRecBcnInfoForClient(P_ADAPTER_T prAdapter, -+ P_BSS_INFO_T prBssInfo, P_SW_RFB_T prSwRfb, PUINT_8 pucIE, UINT_16 u2IELength) -+{ -+ if ((prAdapter == NULL) -+ || (pucIE == NULL) -+ || (prBssInfo == NULL) -+ || (prSwRfb == NULL)) { -+ ASSERT(FALSE); -+ return FALSE; -+ } -+ -+#if 0 /* SW migration 2010/8/20 */ -+ /* Note: we shall not update parameters when scanning, otherwise -+ * channel and bandwidth will not be correct or asserted failure -+ * during scanning. -+ * Note: remove channel checking. All received Beacons should be processed -+ * if measurement or other actions are executed in adjacent channels -+ * and Beacon content checking mechanism is not disabled. -+ */ -+ if (IS_SCAN_ACTIVE() -+ /* || prBssInfo->ucPrimaryChannel != CHNL_NUM_BY_SWRFB(prSwRfb) */ -+ ) { -+ return FALSE; -+ } -+#endif -+ -+ /* Handle change of slot time */ -+ prBssInfo->u2CapInfo = ((P_WLAN_BEACON_FRAME_T) (prSwRfb->pvHeader))->u2CapInfo; -+ prBssInfo->fgUseShortSlotTime = (prBssInfo->u2CapInfo & CAP_INFO_SHORT_SLOT_TIME) ? TRUE : FALSE; -+ -+ rlmRecIeInfoForClient(prAdapter, prBssInfo, pucIE, u2IELength); -+ -+ return TRUE; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rlmProcessBcn(P_ADAPTER_T prAdapter, P_SW_RFB_T prSwRfb, PUINT_8 pucIE, UINT_16 u2IELength) -+{ -+ P_BSS_INFO_T prBssInfo; -+ BOOLEAN fgNewParameter; -+ UINT_8 ucNetIdx; -+ -+ ASSERT(prAdapter); -+ ASSERT(prSwRfb); -+ ASSERT(pucIE); -+ -+ fgNewParameter = FALSE; -+ -+ /* When concurrent networks exist, GO shall have the same handle as -+ * the other BSS, so the Beacon shall be processed for bandwidth and -+ * protection mechanism. -+ * Note1: we do not have 2 AP (GO) cases simultaneously now. -+ * Note2: If we are GO, concurrent AIS AP should detect it and reflect -+ * action in its Beacon, so AIS STA just follows Beacon from AP. -+ */ -+ RLM_NET_FOR_EACH_NO_BOW(ucNetIdx) { -+ prBssInfo = &prAdapter->rWifiVar.arBssInfo[ucNetIdx]; -+ ASSERT(prBssInfo); -+ -+ if (IS_BSS_ACTIVE(prBssInfo)) { -+ if (prBssInfo->eCurrentOPMode == OP_MODE_INFRASTRUCTURE && -+ prBssInfo->eConnectionState == PARAM_MEDIA_STATE_CONNECTED) { -+ /* P2P client or AIS infra STA */ -+ if (EQUAL_MAC_ADDR(prBssInfo->aucBSSID, ((P_WLAN_MAC_MGMT_HEADER_T) -+ (prSwRfb->pvHeader))->aucBSSID)) { -+ -+ fgNewParameter = rlmRecBcnInfoForClient(prAdapter, -+ prBssInfo, prSwRfb, pucIE, u2IELength); -+ } else { -+ fgNewParameter = rlmRecBcnFromNeighborForClient(prAdapter, -+ prBssInfo, prSwRfb, pucIE, -+ u2IELength); -+ } -+ } -+#if CFG_ENABLE_WIFI_DIRECT -+ else if (prAdapter->fgIsP2PRegistered && -+ (prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT || -+ prBssInfo->eCurrentOPMode == OP_MODE_P2P_DEVICE)) { -+ /* AP scan to check if 20/40M bandwidth is permitted */ -+ rlmRecBcnFromNeighborForClient(prAdapter, prBssInfo, prSwRfb, pucIE, u2IELength); -+ } -+#endif -+ else if (prBssInfo->eCurrentOPMode == OP_MODE_IBSS) { -+ /* Do nothing */ -+ /* To do: Ad-hoc */ -+ } -+ -+ /* Appy new parameters if necessary */ -+ if (fgNewParameter) { -+ DBGLOG(RLM, TRACE, "rlmProcessBcn\n"); -+ rlmSyncOperationParams(prAdapter, prBssInfo); -+ fgNewParameter = FALSE; -+ } -+ } /* end of IS_BSS_ACTIVE() */ -+ } /* end of RLM_NET_FOR_EACH_NO_BOW */ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function should be invoked after judging successful association. -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rlmProcessAssocRsp(P_ADAPTER_T prAdapter, P_SW_RFB_T prSwRfb, PUINT_8 pucIE, UINT_16 u2IELength) -+{ -+ P_BSS_INFO_T prBssInfo; -+ P_STA_RECORD_T prStaRec; -+ UINT_8 ucPriChannel; -+ -+ ASSERT(prAdapter); -+ ASSERT(prSwRfb); -+ ASSERT(pucIE); -+ -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); -+ ASSERT(prStaRec); -+ if (!prStaRec) -+ return; -+ ASSERT(prStaRec->ucNetTypeIndex < NETWORK_TYPE_INDEX_NUM); -+ -+ prBssInfo = &prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]; -+ ASSERT(prStaRec == prBssInfo->prStaRecOfAP); -+ -+ /* To do: the invoked function is used to clear all members. It may be -+ * done by center mechanism in invoker. -+ */ -+ rlmBssReset(prAdapter, prBssInfo); -+ -+ prBssInfo->fgUseShortSlotTime = (prBssInfo->u2CapInfo & CAP_INFO_SHORT_SLOT_TIME) ? TRUE : FALSE; -+ -+ ucPriChannel = rlmRecIeInfoForClient(prAdapter, prBssInfo, pucIE, u2IELength); -+ if (ucPriChannel > 0) -+ prBssInfo->ucPrimaryChannel = ucPriChannel; -+ -+ if (!RLM_NET_IS_11N(prBssInfo) || !(prStaRec->u2HtCapInfo & HT_CAP_INFO_SUP_CHNL_WIDTH)) -+ prBssInfo->fg40mBwAllowed = FALSE; -+ -+ /* Note: Update its capabilities to WTBL by cnmStaRecChangeState(), which -+ * shall be invoked afterwards. -+ * Update channel, bandwidth and protection mode by nicUpdateBss() -+ */ -+#if 1 -+ if (prStaRec->ucNetTypeIndex == NETWORK_TYPE_P2P_INDEX) { -+ -+ DBGLOG(P2P, WARN, "Force P2P BW to 20\n"); -+ prBssInfo->fgAssoc40mBwAllowed = FALSE; -+ } -+#endif -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function should be invoked after judging successful association. -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rlmFillSyncCmdParam(P_CMD_SET_BSS_RLM_PARAM_T prCmdBody, P_BSS_INFO_T prBssInfo) -+{ -+ ASSERT(prCmdBody && prBssInfo); -+ if (!prCmdBody || !prBssInfo) -+ return; -+ -+ prCmdBody->ucNetTypeIndex = prBssInfo->ucNetTypeIndex; -+ prCmdBody->ucRfBand = (UINT_8) prBssInfo->eBand; -+ prCmdBody->ucPrimaryChannel = prBssInfo->ucPrimaryChannel; -+ prCmdBody->ucRfSco = (UINT_8) prBssInfo->eBssSCO; -+ prCmdBody->ucErpProtectMode = (UINT_8) prBssInfo->fgErpProtectMode; -+ prCmdBody->ucHtProtectMode = (UINT_8) prBssInfo->eHtProtectMode; -+ prCmdBody->ucGfOperationMode = (UINT_8) prBssInfo->eGfOperationMode; -+ prCmdBody->ucTxRifsMode = (UINT_8) prBssInfo->eRifsOperationMode; -+ prCmdBody->u2HtOpInfo3 = prBssInfo->u2HtOpInfo3; -+ prCmdBody->u2HtOpInfo2 = prBssInfo->u2HtOpInfo2; -+ prCmdBody->ucHtOpInfo1 = prBssInfo->ucHtOpInfo1; -+ prCmdBody->ucUseShortPreamble = prBssInfo->fgUseShortPreamble; -+ prCmdBody->ucUseShortSlotTime = prBssInfo->fgUseShortSlotTime; -+ prCmdBody->ucCheckId = 0x72; -+ -+ if (RLM_NET_PARAM_VALID(prBssInfo)) { -+ DBGLOG(RLM, INFO, "N=%d b=%d c=%d s=%d e=%d h=%d I=0x%02x l=%d p=%d\n", -+ prCmdBody->ucNetTypeIndex, prCmdBody->ucRfBand, -+ prCmdBody->ucPrimaryChannel, prCmdBody->ucRfSco, -+ prCmdBody->ucErpProtectMode, prCmdBody->ucHtProtectMode, -+ prCmdBody->ucHtOpInfo1, prCmdBody->ucUseShortSlotTime, -+ prCmdBody->ucUseShortPreamble); -+ } else { -+ DBGLOG(RLM, TRACE, "N=%d closed\n", prCmdBody->ucNetTypeIndex); -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will operation parameters based on situations of -+* concurrent networks. Channel, bandwidth, protection mode, supported -+* rate will be modified. -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rlmSyncOperationParams(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo) -+{ -+ P_CMD_SET_BSS_RLM_PARAM_T prCmdBody; -+ WLAN_STATUS rStatus; -+ -+ ASSERT(prAdapter); -+ ASSERT(prBssInfo); -+ -+ prCmdBody = (P_CMD_SET_BSS_RLM_PARAM_T) -+ cnmMemAlloc(prAdapter, RAM_TYPE_BUF, sizeof(CMD_SET_BSS_RLM_PARAM_T)); -+ ASSERT(prCmdBody); -+ -+ /* To do: exception handle */ -+ if (!prCmdBody) { -+ DBGLOG(RLM, WARN, "No buf for sync RLM params (Net=%d)\n", prBssInfo->ucNetTypeIndex); -+ return; -+ } -+ -+ rlmFillSyncCmdParam(prCmdBody, prBssInfo); -+ -+ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ -+ CMD_ID_SET_BSS_RLM_PARAM, /* ucCID */ -+ TRUE, /* fgSetQuery */ -+ FALSE, /* fgNeedResp */ -+ FALSE, /* fgIsOid */ -+ NULL, /* pfCmdDoneHandler */ -+ NULL, /* pfCmdTimeoutHandler */ -+ sizeof(CMD_SET_BSS_RLM_PARAM_T), /* u4SetQueryInfoLen */ -+ (PUINT_8) prCmdBody, /* pucInfoBuffer */ -+ NULL, /* pvSetQueryBuffer */ -+ 0 /* u4SetQueryBufferLen */ -+ ); -+ -+ ASSERT(rStatus == WLAN_STATUS_PENDING); -+ -+ cnmMemFree(prAdapter, prCmdBody); -+} -+ -+#if CFG_SUPPORT_AAA -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function should be invoked after judging successful association. -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rlmProcessAssocReq(P_ADAPTER_T prAdapter, P_SW_RFB_T prSwRfb, PUINT_8 pucIE, UINT_16 u2IELength) -+{ -+ P_BSS_INFO_T prBssInfo; -+ P_STA_RECORD_T prStaRec; -+ UINT_16 u2Offset; -+ P_IE_HT_CAP_T prHtCap; -+ -+ ASSERT(prAdapter); -+ ASSERT(prSwRfb); -+ ASSERT(pucIE); -+ -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); -+ ASSERT(prStaRec); -+ if (!prStaRec) -+ return; -+ ASSERT(prStaRec->ucNetTypeIndex < NETWORK_TYPE_INDEX_NUM); -+ -+ prBssInfo = &prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]; -+ -+ IE_FOR_EACH(pucIE, u2IELength, u2Offset) { -+ switch (IE_ID(pucIE)) { -+ case ELEM_ID_HT_CAP: -+ if (!RLM_NET_IS_11N(prBssInfo) || IE_LEN(pucIE) != (sizeof(IE_HT_CAP_T) - 2)) -+ break; -+ prHtCap = (P_IE_HT_CAP_T) pucIE; -+ prStaRec->ucMcsSet = prHtCap->rSupMcsSet.aucRxMcsBitmask[0]; -+ prStaRec->fgSupMcs32 = (prHtCap->rSupMcsSet.aucRxMcsBitmask[32 / 8] & BIT(0)) ? TRUE : FALSE; -+ -+ prStaRec->u2HtCapInfo = prHtCap->u2HtCapInfo; -+ prStaRec->ucAmpduParam = prHtCap->ucAmpduParam; -+ prStaRec->u2HtExtendedCap = prHtCap->u2HtExtendedCap; -+ prStaRec->u4TxBeamformingCap = prHtCap->u4TxBeamformingCap; -+ prStaRec->ucAselCap = prHtCap->ucAselCap; -+ break; -+ -+ default: -+ break; -+ } /* end of switch */ -+ } /* end of IE_FOR_EACH */ -+} -+#endif /* CFG_SUPPORT_AAA */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief It is for both STA and AP modes -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rlmBssInitForAPandIbss(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo) -+{ -+ ASSERT(prAdapter); -+ ASSERT(prBssInfo); -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ if (prAdapter->fgIsP2PRegistered && prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT) -+ rlmBssInitForAP(prAdapter, prBssInfo); -+#endif -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief It is for both STA and AP modes -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rlmBssAborted(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo) -+{ -+ ASSERT(prAdapter); -+ ASSERT(prBssInfo); -+ -+ rlmBssReset(prAdapter, prBssInfo); -+ -+ prBssInfo->fg40mBwAllowed = FALSE; -+ prBssInfo->fgAssoc40mBwAllowed = FALSE; -+ -+ /* Assume FW state is updated by CMD_ID_SET_BSS_INFO, so -+ * the sync CMD is not needed here. -+ */ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief All RLM timers will also be stopped. -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+static VOID rlmBssReset(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo) -+{ -+ ASSERT(prAdapter); -+ ASSERT(prBssInfo); -+ -+ /* HT related parameters */ -+ prBssInfo->ucHtOpInfo1 = 0; /* RIFS disabled. 20MHz */ -+ prBssInfo->u2HtOpInfo2 = 0; -+ prBssInfo->u2HtOpInfo3 = 0; -+ -+ prBssInfo->eBssSCO = 0; -+ prBssInfo->fgErpProtectMode = 0; -+ prBssInfo->eHtProtectMode = 0; -+ prBssInfo->eGfOperationMode = 0; -+ prBssInfo->eRifsOperationMode = 0; -+ -+ /* OBSS related parameters */ -+ prBssInfo->auc2G_20mReqChnlList[0] = 0; -+ prBssInfo->auc2G_NonHtChnlList[0] = 0; -+ prBssInfo->auc2G_PriChnlList[0] = 0; -+ prBssInfo->auc2G_SecChnlList[0] = 0; -+ prBssInfo->auc5G_20mReqChnlList[0] = 0; -+ prBssInfo->auc5G_NonHtChnlList[0] = 0; -+ prBssInfo->auc5G_PriChnlList[0] = 0; -+ prBssInfo->auc5G_SecChnlList[0] = 0; -+ -+ /* All RLM timers will also be stopped */ -+ cnmTimerStopTimer(prAdapter, &prBssInfo->rObssScanTimer); -+ prBssInfo->u2ObssScanInterval = 0; -+ -+ prBssInfo->fgObssErpProtectMode = 0; /* GO only */ -+ prBssInfo->eObssHtProtectMode = 0; /* GO only */ -+ prBssInfo->eObssGfOperationMode = 0; /* GO only */ -+ prBssInfo->fgObssRifsOperationMode = 0; /* GO only */ -+ prBssInfo->fgObssActionForcedTo20M = 0; /* GO only */ -+ prBssInfo->fgObssBeaconForcedTo20M = 0; /* GO only */ -+} -+ -+#if CFG_SUPPORT_DFS /* Add by Enlai */ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function handle spectrum management action frame -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rlmProcessSpecMgtAction(P_ADAPTER_T prAdapter, P_SW_RFB_T prSwRfb) -+{ -+ P_ACTION_CHANNEL_SWITCH_FRAME prRxFrame; -+ -+ ASSERT(prAdapter); -+ ASSERT(prSwRfb); -+ -+ DBGLOG(RLM, INFO, "[5G DFS]rlmProcessSpecMgtAction \r\n"); -+ -+ prRxFrame = (P_ACTION_CHANNEL_SWITCH_FRAME) prSwRfb->pvHeader; -+ DBGLOG(RLM, INFO, "[5G DFS]prRxFrame->ucAction[%d] \r\n", prRxFrame->ucAction); -+ if (prRxFrame->ucAction == ACTION_CHNL_SWITCH) -+ rlmProcessChannelSwitchIE(prAdapter, (P_IE_CHANNEL_SWITCH_T) prRxFrame->aucInfoElem); -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function process Channel Switch IE -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rlmProcessChannelSwitchIE(P_ADAPTER_T prAdapter, P_IE_CHANNEL_SWITCH_T prChannelSwitchIE) -+{ -+ P_BSS_INFO_T prAisBssInfo; -+ -+ ASSERT(prAdapter); -+ ASSERT(prChannelSwitchIE); -+ -+ DBGLOG(RLM, INFO, "[5G DFS] rlmProcessChannelSwitchIE \r\n"); -+ DBGLOG(RLM, INFO, "[5G DFS] ucChannelSwitchMode[%d], ucChannelSwitchCount[%d], ucNewChannelNum[%d] \r\n", -+ prChannelSwitchIE->ucChannelSwitchMode, -+ prChannelSwitchIE->ucChannelSwitchCount, prChannelSwitchIE->ucNewChannelNum); -+ if (prChannelSwitchIE->ucChannelSwitchMode == 1) { -+ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ DBGLOG(RLM, INFO, "[5G DFS] switch channel [%d]->[%d] \r\n", prAisBssInfo->ucPrimaryChannel, -+ prChannelSwitchIE->ucNewChannelNum); -+ prAisBssInfo->ucPrimaryChannel = prChannelSwitchIE->ucNewChannelNum; -+ nicUpdateBss(prAdapter, prAisBssInfo->ucNetTypeIndex); -+ } -+ -+} -+ -+#endif -+ -+#if (CFG_SUPPORT_TXR_ENC == 1) -+VOID -+rlmTxRateEnhanceConfig( -+ P_ADAPTER_T prAdapter -+ ) -+{ -+ P_GLUE_INFO_T prGlueInfo; -+ WLAN_STATUS rStatus = WLAN_STATUS_FAILURE; -+ CMD_RLM_INFO_T rTxRInfo; -+ UINT_32 u4SetInfoLen = 0; -+ -+ -+ /* init */ -+ prGlueInfo = prAdapter->prGlueInfo; -+ -+ /* suggestion from Tsaiyuan.Hsu */ -+ kalMemZero(&rTxRInfo, sizeof(CMD_RLM_INFO_T)); -+ rTxRInfo.fgIsErrRatioEnhanceApplied = TRUE; -+ rTxRInfo.ucErrRatio2LimitMinRate = 3; -+ rTxRInfo.ucMinLegacyRateIdx = 2; -+ rTxRInfo.cMinRssiThreshold = -60; -+ rTxRInfo.fgIsRtsApplied = TRUE; -+ rTxRInfo.ucRecoverTime = 60; -+ -+ DBGLOG(RLM, INFO, "Enable tx rate enhance function\n"); -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetTxRateInfo, -+ &rTxRInfo, -+ sizeof(rTxRInfo), -+ TRUE, -+ TRUE, -+ TRUE, -+ FALSE, -+ &u4SetInfoLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) -+ DBGLOG(RLM, WARN, "set tx rate advance info fail 0x%lx\n", rStatus); -+} -+ -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to send a command to TX Auto Rate module. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prInBuf A pointer to the command string buffer -+* \param[in] u4InBufLen The length of the buffer -+* \param[out] None -+* -+* \retval None -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+rlmCmd(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) -+{ -+ UINT_32 u4Subcmd; -+ -+ -+ /* parse TAR sub-command */ -+ u4Subcmd = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ DBGLOG(RLM, INFO, " sub command = %u\n", (UINT32)u4Subcmd); -+ -+ /* handle different sub-command */ -+ switch (u4Subcmd) { -+ case 0x00: /* configure */ -+ /* iwpriv wlan0 set_str_cmd 1_0_0_1_3_2_60_1_60 */ -+ WLAN_STATUS rStatus = WLAN_STATUS_FAILURE; -+ CMD_RLM_INFO_T rTxRInfo; -+ UINT_32 u4SetInfoLen = 0; -+ -+ kalMemZero(&rTxRInfo, sizeof(CMD_RLM_INFO_T)); -+ rTxRInfo.u4Version = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ rTxRInfo.fgIsErrRatioEnhanceApplied = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ rTxRInfo.ucErrRatio2LimitMinRate = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ rTxRInfo.ucMinLegacyRateIdx = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ rTxRInfo.cMinRssiThreshold = 0 - CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ rTxRInfo.fgIsRtsApplied = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ rTxRInfo.ucRecoverTime = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ -+ DBGLOG(RLM, INFO, " rlmCmd = %u %u %u %u %d %u %u\n", -+ rTxRInfo.u4Version, -+ rTxRInfo.fgIsErrRatioEnhanceApplied, -+ rTxRInfo.ucErrRatio2LimitMinRate, -+ rTxRInfo.ucMinLegacyRateIdx, -+ rTxRInfo.cMinRssiThreshold, -+ rTxRInfo.fgIsRtsApplied, -+ rTxRInfo.ucRecoverTime)); -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetTxRateInfo, -+ &rTxRInfo, -+ sizeof(rTxRInfo), -+ TRUE, -+ TRUE, -+ TRUE, -+ FALSE, -+ &u4SetInfoLen); -+ break; -+ -+ default: -+ break; -+ } -+} -+#endif /* CFG_SUPPORT_TXR_ENC */ -+ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rlm_domain.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rlm_domain.c -new file mode 100644 -index 000000000000..5e127488ea49 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rlm_domain.c -@@ -0,0 +1,1791 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/rlm_domain.c#1 -+*/ -+ -+/*! \file "rlm_domain.c" -+ \brief -+ -+*/ -+ -+/* -+** Log: rlm_domain.c -+ * -+ * 11 10 2011 cm.chang -+ * NULL -+ * Modify debug message for XLOG -+ * -+ * 09 29 2011 cm.chang -+ * NULL -+ * Change the function prototype of rlmDomainGetChnlList() -+ * -+ * 09 23 2011 cm.chang -+ * [WCXRP00000969] [MT6620 Wi-Fi][Driver][FW] Channel list for 5G band based on country code -+ * Let channel number to zero if band is illegal -+ * -+ * 09 22 2011 cm.chang -+ * [WCXRP00000969] [MT6620 Wi-Fi][Driver][FW] Channel list for 5G band based on country code -+ * Exclude channel list with illegal band -+ * -+ * 09 15 2011 cm.chang -+ * [WCXRP00000969] [MT6620 Wi-Fi][Driver][FW] Channel list for 5G band based on country code -+ * Use defined country group to have a change to add new group -+ * -+ * 09 08 2011 cm.chang -+ * [WCXRP00000969] [MT6620 Wi-Fi][Driver][FW] Channel list for 5G band based on country code -+ * Use new fields ucChannelListMap and ucChannelListIndex in NVRAM -+ * -+ * 08 31 2011 cm.chang -+ * [WCXRP00000969] [MT6620 Wi-Fi][Driver][FW] Channel list for 5G band based on country code -+ * . -+ * -+ * 06 01 2011 cm.chang -+ * [WCXRP00000756] [MT6620 Wi-Fi][Driver] 1. AIS follow channel of BOW 2. Provide legal channel function -+ * Provide legal channel function based on domain -+ * -+ * 03 19 2011 yuche.tsai -+ * [WCXRP00000584] [Volunteer Patch][MT6620][Driver] Add beacon timeout support for WiFi Direct. -+ * Add beacon timeout support for WiFi Direct Network. -+ * -+ * 03 02 2011 terry.wu -+ * [WCXRP00000505] [MT6620 Wi-Fi][Driver/FW] WiFi Direct Integration -+ * Export rlmDomainGetDomainInfo for p2p driver. -+ * -+ * 01 12 2011 cm.chang -+ * [WCXRP00000354] [MT6620 Wi-Fi][Driver][FW] Follow NVRAM bandwidth setting -+ * User-defined bandwidth is for 2.4G and 5G individually -+ * -+ * 12 07 2010 cm.chang -+ * [WCXRP00000238] MT6620 Wi-Fi][Driver][FW] Support regulation domain setting from NVRAM and supplicant -+ * 1. Country code is from NVRAM or supplicant -+ * 2. Change band definition in CMD/EVENT. -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 07 08 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Check draft RLM code for HT cap -+ * -+ * 03 25 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Filter out not supported RF freq when reporting available chnl list -+ * -+ * 01 22 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Support protection and bandwidth switch -+ * -+ * 01 13 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Provide query function about full channel list. -+ * -+ * Dec 1 2009 mtk01104 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * -+ * -+** -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "precomp.h" -+#include "rlm_txpwr_init.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/* The following country or domain shall be set from host driver. -+ * And host driver should pass specified DOMAIN_INFO_ENTRY to MT6620 as -+ * the channel list of being a STA to do scanning/searching AP or being an -+ * AP to choose an adequate channel if auto-channel is set. -+ */ -+ -+/* Define mapping tables between country code and its channel set -+ */ -+static const UINT_16 g_u2CountryGroup0[] = { -+ COUNTRY_CODE_AO, COUNTRY_CODE_BZ, COUNTRY_CODE_BJ, COUNTRY_CODE_BT, -+ COUNTRY_CODE_BO, COUNTRY_CODE_BI, COUNTRY_CODE_CM, COUNTRY_CODE_CF, -+ COUNTRY_CODE_TD, COUNTRY_CODE_KM, COUNTRY_CODE_CD, COUNTRY_CODE_CG, -+ COUNTRY_CODE_CI, COUNTRY_CODE_DJ, COUNTRY_CODE_GQ, COUNTRY_CODE_ER, -+ COUNTRY_CODE_FJ, COUNTRY_CODE_GA, COUNTRY_CODE_GM, COUNTRY_CODE_GN, -+ COUNTRY_CODE_GW, COUNTRY_CODE_RKS, COUNTRY_CODE_KG, COUNTRY_CODE_LY, -+ COUNTRY_CODE_MG, COUNTRY_CODE_ML, COUNTRY_CODE_NR, COUNTRY_CODE_NC, -+ COUNTRY_CODE_ST, COUNTRY_CODE_SC, COUNTRY_CODE_SL, COUNTRY_CODE_SB, -+ COUNTRY_CODE_SO, COUNTRY_CODE_SR, COUNTRY_CODE_SZ, COUNTRY_CODE_TJ, -+ COUNTRY_CODE_TG, COUNTRY_CODE_TO, COUNTRY_CODE_TM, COUNTRY_CODE_TV, -+ COUNTRY_CODE_VU, COUNTRY_CODE_YE -+}; -+ -+static const UINT_16 g_u2CountryGroup1[] = { -+ COUNTRY_CODE_AS, COUNTRY_CODE_AI, COUNTRY_CODE_BM, COUNTRY_CODE_CA, -+ COUNTRY_CODE_KY, COUNTRY_CODE_GU, COUNTRY_CODE_FM, COUNTRY_CODE_PR, -+ COUNTRY_CODE_US, COUNTRY_CODE_VI -+}; -+ -+static const UINT_16 g_u2CountryGroup2[] = { -+ COUNTRY_CODE_AR, COUNTRY_CODE_AU, COUNTRY_CODE_AZ, COUNTRY_CODE_BW, -+ COUNTRY_CODE_KH, COUNTRY_CODE_CX, COUNTRY_CODE_CO, COUNTRY_CODE_CR, -+#if (CFG_CN_SUPPORT_CLASS121 == 1) -+ COUNTRY_CODE_CN, -+#endif -+ COUNTRY_CODE_EC, COUNTRY_CODE_GD, COUNTRY_CODE_GT, COUNTRY_CODE_HK, -+ COUNTRY_CODE_KI, COUNTRY_CODE_LB, COUNTRY_CODE_LR, COUNTRY_CODE_MN, -+ COUNTRY_CODE_AN, COUNTRY_CODE_NZ, COUNTRY_CODE_NI, COUNTRY_CODE_PW, -+ COUNTRY_CODE_PY, COUNTRY_CODE_PE, COUNTRY_CODE_PH, COUNTRY_CODE_WS, -+ COUNTRY_CODE_SG, COUNTRY_CODE_LK, COUNTRY_CODE_TH, COUNTRY_CODE_TT, -+ COUNTRY_CODE_UY, COUNTRY_CODE_VN -+}; -+ -+static const UINT_16 g_u2CountryGroup3[] = { -+ COUNTRY_CODE_AW, COUNTRY_CODE_LA, COUNTRY_CODE_SA, COUNTRY_CODE_AE, -+ COUNTRY_CODE_UG -+}; -+ -+static const UINT_16 g_u2CountryGroup4[] = { COUNTRY_CODE_MM }; -+ -+static const UINT_16 g_u2CountryGroup5[] = { -+ COUNTRY_CODE_AL, COUNTRY_CODE_DZ, COUNTRY_CODE_AD, COUNTRY_CODE_AT, -+ COUNTRY_CODE_BY, COUNTRY_CODE_BE, COUNTRY_CODE_BA, COUNTRY_CODE_VG, -+ COUNTRY_CODE_BG, COUNTRY_CODE_CV, COUNTRY_CODE_HR, COUNTRY_CODE_CY, -+ COUNTRY_CODE_CZ, COUNTRY_CODE_DK, COUNTRY_CODE_EE, COUNTRY_CODE_ET, -+ COUNTRY_CODE_FI, COUNTRY_CODE_FR, COUNTRY_CODE_GF, COUNTRY_CODE_PF, -+ COUNTRY_CODE_TF, COUNTRY_CODE_GE, COUNTRY_CODE_DE, COUNTRY_CODE_GH, -+ COUNTRY_CODE_GR, COUNTRY_CODE_GP, COUNTRY_CODE_HU, COUNTRY_CODE_IS, -+ COUNTRY_CODE_IQ, COUNTRY_CODE_IE, COUNTRY_CODE_IT, COUNTRY_CODE_KE, -+ COUNTRY_CODE_LV, COUNTRY_CODE_LS, COUNTRY_CODE_LI, COUNTRY_CODE_LT, -+ COUNTRY_CODE_LU, COUNTRY_CODE_MK, COUNTRY_CODE_MT, COUNTRY_CODE_MQ, -+ COUNTRY_CODE_MR, COUNTRY_CODE_MU, COUNTRY_CODE_YT, COUNTRY_CODE_MD, -+ COUNTRY_CODE_MC, COUNTRY_CODE_ME, COUNTRY_CODE_MS, COUNTRY_CODE_NL, -+ COUNTRY_CODE_NO, COUNTRY_CODE_OM, COUNTRY_CODE_PL, COUNTRY_CODE_PT, -+ COUNTRY_CODE_RE, COUNTRY_CODE_RO, COUNTRY_CODE_MF, COUNTRY_CODE_SM, -+ COUNTRY_CODE_SN, COUNTRY_CODE_RS, COUNTRY_CODE_SK, COUNTRY_CODE_SI, -+ COUNTRY_CODE_ZA, COUNTRY_CODE_ES, COUNTRY_CODE_SE, COUNTRY_CODE_CH, -+ COUNTRY_CODE_TR, COUNTRY_CODE_TC, COUNTRY_CODE_GB, COUNTRY_CODE_VA, -+ COUNTRY_CODE_EU -+}; -+ -+static const UINT_16 g_u2CountryGroup6[] = { COUNTRY_CODE_JP }; -+ -+static const UINT_16 g_u2CountryGroup7[] = { -+ COUNTRY_CODE_AM, COUNTRY_CODE_IL, COUNTRY_CODE_KW, COUNTRY_CODE_MA, -+ COUNTRY_CODE_NE, COUNTRY_CODE_TN, COUNTRY_CODE_MA -+}; -+ -+static const UINT_16 g_u2CountryGroup8[] = { COUNTRY_CODE_NP }; -+ -+static const UINT_16 g_u2CountryGroup9[] = { COUNTRY_CODE_AF }; -+ -+static const UINT_16 g_u2CountryGroup10[] = { -+ COUNTRY_CODE_AG, COUNTRY_CODE_BS, COUNTRY_CODE_BH, COUNTRY_CODE_BB, -+ COUNTRY_CODE_BN, COUNTRY_CODE_CL, COUNTRY_CODE_EG, -+#if (CFG_CN_SUPPORT_CLASS121 == 0) -+ COUNTRY_CODE_CN, -+#endif -+ COUNTRY_CODE_SV, COUNTRY_CODE_IN, COUNTRY_CODE_MY, COUNTRY_CODE_MV, -+ COUNTRY_CODE_PA, COUNTRY_CODE_VE, COUNTRY_CODE_ZM -+}; -+ -+static const UINT_16 g_u2CountryGroup11[] = { COUNTRY_CODE_JO, COUNTRY_CODE_PG }; -+ -+static const UINT_16 g_u2CountryGroup12[] = { -+ COUNTRY_CODE_BF, COUNTRY_CODE_GY, COUNTRY_CODE_HT, COUNTRY_CODE_HN, -+ COUNTRY_CODE_JM, COUNTRY_CODE_MO, COUNTRY_CODE_MW, COUNTRY_CODE_PK, -+ COUNTRY_CODE_QA, COUNTRY_CODE_RW, COUNTRY_CODE_KN, COUNTRY_CODE_TZ -+}; -+ -+static const UINT_16 g_u2CountryGroup13[] = { COUNTRY_CODE_ID }; -+ -+static const UINT_16 g_u2CountryGroup14[] = { COUNTRY_CODE_KR }; -+ -+static const UINT_16 g_u2CountryGroup15[] = { COUNTRY_CODE_NG }; -+ -+static const UINT_16 g_u2CountryGroup16[] = { -+ COUNTRY_CODE_BD, COUNTRY_CODE_BR, COUNTRY_CODE_DM, COUNTRY_CODE_DO, -+ COUNTRY_CODE_FK, COUNTRY_CODE_KZ, COUNTRY_CODE_MX, COUNTRY_CODE_MZ, -+ COUNTRY_CODE_NA, COUNTRY_CODE_RU, COUNTRY_CODE_LC, COUNTRY_CODE_VC, -+ COUNTRY_CODE_UA, COUNTRY_CODE_UZ, COUNTRY_CODE_ZW -+}; -+ -+static const UINT_16 g_u2CountryGroup17[] = { COUNTRY_CODE_MP }; -+ -+static const UINT_16 g_u2CountryGroup18[] = { COUNTRY_CODE_TW }; -+ -+static const UINT_16 g_u2CountryGroup19[] = { -+ COUNTRY_CODE_CK, COUNTRY_CODE_CU, COUNTRY_CODE_TL, COUNTRY_CODE_FO, -+ COUNTRY_CODE_GI, COUNTRY_CODE_GG, COUNTRY_CODE_IR, COUNTRY_CODE_IM, -+ COUNTRY_CODE_JE, COUNTRY_CODE_KP, COUNTRY_CODE_MH, COUNTRY_CODE_NU, -+ COUNTRY_CODE_NF, COUNTRY_CODE_PS, COUNTRY_CODE_PN, COUNTRY_CODE_PM, -+ COUNTRY_CODE_SS, COUNTRY_CODE_SD, COUNTRY_CODE_SY -+}; -+ -+static const UINT_16 g_u2CountryGroup20[] = { -+ COUNTRY_CODE_DF, COUNTRY_CODE_FF -+ /* When country code is not found and no matched NVRAM setting, -+ * this domain info will be used. -+ */ -+}; -+ -+static const UINT_16 g_u2CountryGroup21[] = { -+ COUNTRY_CODE_UDF -+}; -+ -+DOMAIN_INFO_ENTRY arSupportedRegDomains[] = { -+ { -+ (PUINT_16) g_u2CountryGroup0, sizeof(g_u2CountryGroup0) / 2, -+ { -+ {81, BAND_2G4, CHNL_SPAN_5, 1, 13, FALSE} -+ , /* CH_SET_2G4_1_13 */ -+ -+ {115, BAND_NULL, 0, 0, 0, FALSE} -+ , /* CH_SET_UNII_LOW_NA */ -+ {118, BAND_NULL, 0, 0, 0, FALSE} -+ , /* CH_SET_UNII_MID_NA */ -+ {121, BAND_NULL, 0, 0, 0, FALSE} -+ , /* CH_SET_UNII_WW_NA */ -+ {125, BAND_NULL, 0, 0, 0, FALSE} -+ , /* CH_SET_UNII_UPPER_NA */ -+ {0, BAND_NULL, 0, 0, 0, FALSE} -+ } -+ } -+ , -+ { -+ (PUINT_16) g_u2CountryGroup1, sizeof(g_u2CountryGroup1) / 2, -+ { -+ {81, BAND_2G4, CHNL_SPAN_5, 1, 11, FALSE} -+ , /* CH_SET_2G4_1_11 */ -+ -+ {115, BAND_5G, CHNL_SPAN_20, 36, 4, FALSE} -+ , /* CH_SET_UNII_LOW_36_48 */ -+ {118, BAND_5G, CHNL_SPAN_20, 52, 4, TRUE} -+ , /* CH_SET_UNII_MID_52_64 */ -+ {121, BAND_5G, CHNL_SPAN_20, 100, 12, TRUE} -+ , /* CH_SET_UNII_WW_100_144 */ -+ {125, BAND_5G, CHNL_SPAN_20, 149, 5, FALSE} -+ , /* CH_SET_UNII_UPPER_149_165 */ -+ {0, BAND_NULL, 0, 0, 0, FALSE} -+ } -+ } -+ , -+ { -+ (PUINT_16) g_u2CountryGroup2, sizeof(g_u2CountryGroup2) / 2, -+ { -+ {81, BAND_2G4, CHNL_SPAN_5, 1, 13, FALSE} -+ , /* CH_SET_2G4_1_13 */ -+ -+ {115, BAND_5G, CHNL_SPAN_20, 36, 4, FALSE} -+ , /* CH_SET_UNII_LOW_36_48 */ -+ {118, BAND_5G, CHNL_SPAN_20, 52, 4, TRUE} -+ , /* CH_SET_UNII_MID_52_64 */ -+ {121, BAND_5G, CHNL_SPAN_20, 100, 12, TRUE} -+ , /* CH_SET_UNII_WW_100_144 */ -+ {125, BAND_5G, CHNL_SPAN_20, 149, 5, FALSE} -+ , /* CH_SET_UNII_UPPER_149_165 */ -+ {0, BAND_NULL, 0, 0, 0, FALSE} -+ } -+ } -+ , -+ { -+ (PUINT_16) g_u2CountryGroup3, sizeof(g_u2CountryGroup3) / 2, -+ { -+ {81, BAND_2G4, CHNL_SPAN_5, 1, 13, FALSE} -+ , /* CH_SET_2G4_1_13 */ -+ -+ {115, BAND_5G, CHNL_SPAN_20, 36, 4, FALSE} -+ , /* CH_SET_UNII_LOW_36_48 */ -+ {118, BAND_5G, CHNL_SPAN_20, 52, 4, TRUE} -+ , /* CH_SET_UNII_MID_52_64 */ -+ {121, BAND_5G, CHNL_SPAN_20, 100, 12, TRUE} -+ , /* CH_SET_UNII_WW_100_144 */ -+ {125, BAND_5G, CHNL_SPAN_20, 149, 4, FALSE} -+ , /* CH_SET_UNII_UPPER_149_161 */ -+ {0, BAND_NULL, 0, 0, 0, FALSE} -+ } -+ } -+ , -+ { -+ (PUINT_16) g_u2CountryGroup4, sizeof(g_u2CountryGroup4) / 2, -+ { -+ {81, BAND_2G4, CHNL_SPAN_5, 1, 13, FALSE} -+ , /* CH_SET_2G4_1_13 */ -+ -+ {115, BAND_5G, CHNL_SPAN_20, 36, 4, FALSE} -+ , /* CH_SET_UNII_LOW_36_48 */ -+ {118, BAND_5G, CHNL_SPAN_20, 52, 4, TRUE} -+ , /* CH_SET_UNII_MID_52_64 */ -+ {121, BAND_5G, CHNL_SPAN_20, 100, 12, TRUE} -+ , /* CH_SET_UNII_WW_100_144 */ -+ {125, BAND_NULL, 0, 0, 0, FALSE} -+ , /* CH_SET_UNII_UPPER_NA */ -+ {0, BAND_NULL, 0, 0, 0, FALSE} -+ } -+ } -+ , -+ { -+ (PUINT_16) g_u2CountryGroup5, sizeof(g_u2CountryGroup5) / 2, -+ { -+ {81, BAND_2G4, CHNL_SPAN_5, 1, 13, FALSE} -+ , /* CH_SET_2G4_1_13 */ -+ -+ {115, BAND_5G, CHNL_SPAN_20, 36, 4, FALSE} -+ , /* CH_SET_UNII_LOW_36_48 */ -+ {118, BAND_5G, CHNL_SPAN_20, 52, 4, TRUE} -+ , /* CH_SET_UNII_MID_52_64 */ -+ {121, BAND_5G, CHNL_SPAN_20, 100, 11, TRUE} -+ , /* CH_SET_UNII_WW_100_140 */ -+ {125, BAND_NULL, 0, 0, 0, FALSE} -+ , /* CH_SET_UNII_UPPER_NA */ -+ {0, BAND_NULL, 0, 0, 0, FALSE} -+ } -+ } -+ , -+ { -+ (PUINT_16) g_u2CountryGroup6, sizeof(g_u2CountryGroup6) / 2, -+ { -+ {81, BAND_2G4, CHNL_SPAN_5, 1, 13, FALSE} -+ , /* CH_SET_2G4_1_13 */ -+ {82, BAND_2G4, CHNL_SPAN_5, 14, 1, FALSE} -+ , /* CH_SET_2G4_14_14 */ -+ {115, BAND_5G, CHNL_SPAN_20, 36, 4, FALSE} -+ , /* CH_SET_UNII_LOW_36_48 */ -+ {118, BAND_5G, CHNL_SPAN_20, 52, 4, TRUE} -+ , /* CH_SET_UNII_MID_52_64 */ -+ {121, BAND_5G, CHNL_SPAN_20, 100, 11, TRUE} -+ , /* CH_SET_UNII_WW_100_140 */ -+ {125, BAND_NULL, 0, 0, 0, FALSE} -+ , /* CH_SET_UNII_UPPER_NA */ -+ } -+ } -+ , -+ { -+ (PUINT_16) g_u2CountryGroup7, sizeof(g_u2CountryGroup7) / 2, -+ { -+ {81, BAND_2G4, CHNL_SPAN_5, 1, 13, FALSE} -+ , /* CH_SET_2G4_1_13 */ -+ -+ {115, BAND_5G, CHNL_SPAN_20, 36, 4, FALSE} -+ , /* CH_SET_UNII_LOW_36_48 */ -+ {118, BAND_5G, CHNL_SPAN_20, 52, 4, TRUE} -+ , /* CH_SET_UNII_MID_52_64 */ -+ {121, BAND_NULL, 0, 0, 0, FALSE} -+ , /* CH_SET_UNII_WW_NA */ -+ {125, BAND_NULL, 0, 0, 0, FALSE} -+ , /* CH_SET_UNII_UPPER_NA */ -+ {0, BAND_NULL, 0, 0, 0, FALSE} -+ } -+ } -+ , -+ { -+ (PUINT_16) g_u2CountryGroup8, sizeof(g_u2CountryGroup8) / 2, -+ { -+ {81, BAND_2G4, CHNL_SPAN_5, 1, 13, FALSE} -+ , /* CH_SET_2G4_1_13 */ -+ -+ {115, BAND_5G, CHNL_SPAN_20, 36, 4, FALSE} -+ , /* CH_SET_UNII_LOW_36_48 */ -+ {118, BAND_5G, CHNL_SPAN_20, 52, 4, TRUE} -+ , /* CH_SET_UNII_MID_52_64 */ -+ {121, BAND_NULL, 0, 0, 0, FALSE} -+ , /* CH_SET_UNII_WW_NA */ -+ {125, BAND_5G, CHNL_SPAN_20, 149, 4, FALSE} -+ , /* CH_SET_UNII_UPPER_149_161 */ -+ {0, BAND_NULL, 0, 0, 0, FALSE} -+ } -+ } -+ , -+ { -+ (PUINT_16) g_u2CountryGroup9, sizeof(g_u2CountryGroup9) / 2, -+ { -+ {81, BAND_2G4, CHNL_SPAN_5, 1, 13, FALSE} -+ , /* CH_SET_2G4_1_13 */ -+ -+ {115, BAND_5G, CHNL_SPAN_20, 36, 4, FALSE} -+ , /* CH_SET_UNII_LOW_36_48 */ -+ {118, BAND_NULL, 0, 0, 0, FALSE} -+ , /* CH_SET_UNII_MID_NA */ -+ {121, BAND_NULL, 0, 0, 0, FALSE} -+ , /* CH_SET_UNII_WW_NA */ -+ {125, BAND_NULL, 0, 0, 0, FALSE} -+ , /* CH_SET_UNII_UPPER_NA */ -+ {0, BAND_NULL, 0, 0, 0, FALSE} -+ } -+ } -+ , -+ { -+ (PUINT_16) g_u2CountryGroup10, sizeof(g_u2CountryGroup10) / 2, -+ { -+ {81, BAND_2G4, CHNL_SPAN_5, 1, 13, FALSE} -+ , /* CH_SET_2G4_1_13 */ -+ -+ {115, BAND_5G, CHNL_SPAN_20, 36, 4, FALSE} -+ , /* CH_SET_UNII_LOW_36_48 */ -+ {118, BAND_5G, CHNL_SPAN_20, 52, 4, TRUE} -+ , /* CH_SET_UNII_MID_52_64 */ -+ {121, BAND_NULL, 0, 0, 0, FALSE} -+ , /* CH_SET_UNII_WW_NA */ -+ {125, BAND_5G, CHNL_SPAN_20, 149, 5, FALSE} -+ , /* CH_SET_UNII_UPPER_149_165 */ -+ {0, BAND_NULL, 0, 0, 0, FALSE} -+ } -+ } -+ , -+ { -+ (PUINT_16) g_u2CountryGroup11, sizeof(g_u2CountryGroup11) / 2, -+ { -+ {81, BAND_2G4, CHNL_SPAN_5, 1, 13, FALSE} -+ , /* CH_SET_2G4_1_13 */ -+ -+ {115, BAND_5G, CHNL_SPAN_20, 36, 4, FALSE} -+ , /* CH_SET_UNII_LOW_36_48 */ -+ {118, BAND_NULL, 0, 0, 0, FALSE} -+ , /* CH_SET_UNII_MID_NA */ -+ {121, BAND_NULL, 0, 0, 0, FALSE} -+ , /* CH_SET_UNII_WW_NA */ -+ {125, BAND_5G, CHNL_SPAN_20, 149, 5, FALSE} -+ , /* CH_SET_UNII_UPPER_149_165 */ -+ {0, BAND_NULL, 0, 0, 0, FALSE} -+ } -+ } -+ , -+ { -+ (PUINT_16) g_u2CountryGroup12, sizeof(g_u2CountryGroup12) / 2, -+ { -+ {81, BAND_2G4, CHNL_SPAN_5, 1, 13, FALSE} -+ , /* CH_SET_2G4_1_13 */ -+ -+ {115, BAND_NULL, 0, 0, 0, FALSE} -+ , /* CH_SET_UNII_LOW_NA */ -+ {118, BAND_NULL, 0, 0, 0, FALSE} -+ , /* CH_SET_UNII_MID_NA */ -+ {121, BAND_NULL, 0, 0, 0, FALSE} -+ , /* CH_SET_UNII_WW_NA */ -+ {125, BAND_5G, CHNL_SPAN_20, 149, 5, FALSE} -+ , /* CH_SET_UNII_UPPER_149_165 */ -+ {0, BAND_NULL, 0, 0, 0, FALSE} -+ } -+ } -+ , -+ { -+ (PUINT_16) g_u2CountryGroup13, sizeof(g_u2CountryGroup13) / 2, -+ { -+ {81, BAND_2G4, CHNL_SPAN_5, 1, 13, FALSE} -+ , /* CH_SET_2G4_1_13 */ -+ -+ {115, BAND_NULL, 0, 0, 0, FALSE} -+ , /* CH_SET_UNII_LOW_NA */ -+ {118, BAND_NULL, 0, 0, 0, FALSE} -+ , /* CH_SET_UNII_MID_NA */ -+ {121, BAND_NULL, 0, 0, 0, FALSE} -+ , /* CH_SET_UNII_WW_NA */ -+ {125, BAND_5G, CHNL_SPAN_20, 149, 4, FALSE} -+ , /* CH_SET_UNII_UPPER_149_161 */ -+ {0, BAND_NULL, 0, 0, 0, FALSE} -+ } -+ } -+ , -+ { -+ (PUINT_16) g_u2CountryGroup14, sizeof(g_u2CountryGroup14) / 2, -+ { -+ {81, BAND_2G4, CHNL_SPAN_5, 1, 13, FALSE} -+ , /* CH_SET_2G4_1_13 */ -+ -+ {115, BAND_5G, CHNL_SPAN_20, 36, 4, FALSE} -+ , /* CH_SET_UNII_LOW_36_48 */ -+ {118, BAND_5G, CHNL_SPAN_20, 52, 4, FALSE} -+ , /* CH_SET_UNII_MID_52_64 */ -+ {121, BAND_5G, CHNL_SPAN_20, 100, 8, FALSE} -+ , /* CH_SET_UNII_WW_100_128 */ -+ {125, BAND_5G, CHNL_SPAN_20, 149, 4, FALSE} -+ , /* CH_SET_UNII_UPPER_149_161 */ -+ {0, BAND_NULL, 0, 0, 0, FALSE} -+ } -+ } -+ , -+ { -+ (PUINT_16) g_u2CountryGroup15, sizeof(g_u2CountryGroup15) / 2, -+ { -+ {81, BAND_2G4, CHNL_SPAN_5, 1, 13, FALSE} -+ , /* CH_SET_2G4_1_13 */ -+ -+ {115, BAND_NULL, 0, 0, 0, FALSE} -+ , /* CH_SET_UNII_LOW_36_48 */ -+ {118, BAND_5G, CHNL_SPAN_20, 52, 4, TRUE} -+ , /* CH_SET_UNII_MID_52_64 */ -+ {121, BAND_5G, CHNL_SPAN_20, 100, 11, TRUE} -+ , /* CH_SET_UNII_WW_100_140 */ -+ {125, BAND_5G, CHNL_SPAN_20, 149, 5, FALSE} -+ , /* CH_SET_UNII_UPPER_149_165 */ -+ {0, BAND_NULL, 0, 0, 0, FALSE} -+ } -+ } -+ , -+ { -+ (PUINT_16) g_u2CountryGroup16, sizeof(g_u2CountryGroup16) / 2, -+ { -+ {81, BAND_2G4, CHNL_SPAN_5, 1, 13, FALSE} -+ , /* CH_SET_2G4_1_13 */ -+ -+ {115, BAND_5G, CHNL_SPAN_20, 36, 4, FALSE} -+ , /* CH_SET_UNII_LOW_36_48 */ -+ {118, BAND_5G, CHNL_SPAN_20, 52, 4, FALSE} -+ , /* CH_SET_UNII_MID_52_64 */ -+ {121, BAND_5G, CHNL_SPAN_20, 100, 11, TRUE} -+ , /* CH_SET_UNII_WW_100_140 */ -+ {125, BAND_5G, CHNL_SPAN_20, 149, 5, FALSE} -+ , /* CH_SET_UNII_UPPER_149_165 */ -+ {0, BAND_NULL, 0, 0, 0, FALSE} -+ } -+ } -+ , -+ { -+ (PUINT_16) g_u2CountryGroup17, sizeof(g_u2CountryGroup17) / 2, -+ { -+ {81, BAND_2G4, CHNL_SPAN_5, 1, 11, FALSE} -+ , /* CH_SET_2G4_1_11 */ -+ -+ {115, BAND_5G, CHNL_SPAN_20, 36, 4, FALSE} -+ , /* CH_SET_UNII_LOW_36_48 */ -+ {118, BAND_5G, CHNL_SPAN_20, 52, 4, TRUE} -+ , /* CH_SET_UNII_MID_52_64 */ -+ {121, BAND_5G, CHNL_SPAN_20, 100, 11, TRUE} -+ , /* CH_SET_UNII_WW_100_140 */ -+ {125, BAND_5G, CHNL_SPAN_20, 149, 5, FALSE} -+ , /* CH_SET_UNII_UPPER_149_165 */ -+ {0, BAND_NULL, 0, 0, 0, FALSE} -+ } -+ } -+ , -+ { -+ (PUINT_16) g_u2CountryGroup18, sizeof(g_u2CountryGroup18) / 2, -+ { -+ {81, BAND_2G4, CHNL_SPAN_5, 1, 11, FALSE} -+ , /* CH_SET_2G4_1_11 */ -+ -+ {115, BAND_5G, CHNL_SPAN_20, 36, 4, FALSE} -+ , /* CH_SET_UNII_LOW_36_48 */ -+ {118, BAND_5G, CHNL_SPAN_20, 52, 4, FALSE} -+ , /* CH_SET_UNII_MID_52_64 */ -+ {121, BAND_5G, CHNL_SPAN_20, 100, 11, FALSE} -+ , /* CH_SET_UNII_WW_100_140 */ -+ {125, BAND_5G, CHNL_SPAN_20, 149, 5, FALSE} -+ , /* CH_SET_UNII_UPPER_149_165 */ -+ {0, BAND_NULL, 0, 0, 0, FALSE} -+ } -+ } -+ , -+ { -+ (PUINT_16) g_u2CountryGroup19, sizeof(g_u2CountryGroup19) / 2, -+ { -+ {81, BAND_2G4, CHNL_SPAN_5, 1, 13, FALSE} -+ , /* CH_SET_2G4_1_13 */ -+ -+ {115, BAND_5G, CHNL_SPAN_20, 36, 4, FALSE} -+ , /* CH_SET_UNII_LOW_36_48 */ -+ {118, BAND_5G, CHNL_SPAN_20, 52, 4, TRUE} -+ , /* CH_SET_UNII_MID_52_64 */ -+ {121, BAND_5G, CHNL_SPAN_20, 100, 12, TRUE} -+ , /* CH_SET_UNII_WW_100_144 */ -+ {125, BAND_5G, CHNL_SPAN_20, 149, 5, FALSE} -+ , /* CH_SET_UNII_UPPER_149_165 */ -+ {0, BAND_NULL, 0, 0, 0, FALSE} -+ } -+ } -+ , -+ { -+ /* Note: Default group if no matched country code */ -+ (PUINT_16) g_u2CountryGroup20, sizeof(g_u2CountryGroup20) / 2, -+ { -+ {81, BAND_2G4, CHNL_SPAN_5, 1, 13, FALSE} -+ , /* CH_SET_2G4_1_13 */ -+ -+ {115, BAND_5G, CHNL_SPAN_20, 36, 4, FALSE} -+ , /* CH_SET_UNII_LOW_36_48 */ -+ {118, BAND_5G, CHNL_SPAN_20, 52, 4, TRUE} -+ , /* CH_SET_UNII_MID_52_64 */ -+ {121, BAND_5G, CHNL_SPAN_20, 100, 12, TRUE} -+ , /* CH_SET_UNII_WW_100_144 */ -+ {125, BAND_5G, CHNL_SPAN_20, 149, 5, FALSE} -+ , /* CH_SET_UNII_UPPER_149_165 */ -+ {0, BAND_NULL, 0, 0, 0, FALSE} -+ } -+ } -+ , -+ { -+ /* Note: for customer configured their own scanning list and passive scan list */ -+ (PUINT_16) g_u2CountryGroup21, sizeof(g_u2CountryGroup21) / 2, -+ { -+ {81, BAND_2G4, CHNL_SPAN_5, 1, 12, FALSE} -+ , /* CH_SET_2G4_1_13 */ -+ -+ {115, BAND_5G, CHNL_SPAN_20, 36, 0, FALSE} -+ , -+ {118, BAND_5G, CHNL_SPAN_20, 52, 0, FALSE} -+ , -+ {121, BAND_5G, CHNL_SPAN_20, 100, 0, FALSE} -+ , -+ {125, BAND_5G, CHNL_SPAN_20, 149, 0, FALSE} -+ , -+ {0, BAND_NULL, 0, 0, 0, FALSE} -+ } -+ } -+}; -+ -+static UINT_16 g_u2CountryGroup0_Passive[] = { -+ COUNTRY_CODE_UDF -+}; -+ -+DOMAIN_INFO_ENTRY arSupportedRegDomains_Passive[] = { -+ { -+ /* Default passive scan channel table is empty */ -+ COUNTRY_CODE_NULL, 0, -+ { -+ {81, BAND_2G4, CHNL_SPAN_5, 11, 0, 0}, /* CH_SET_2G4_1_14 */ -+ {82, BAND_2G4, CHNL_SPAN_5, 5, 0, 0}, -+ -+ {115, BAND_5G, CHNL_SPAN_20, 36, 0, 0}, /* CH_SET_UNII_LOW_36_48 */ -+ {118, BAND_5G, CHNL_SPAN_20, 52, 0, 0}, /* CH_SET_UNII_MID_52_64 */ -+ {121, BAND_5G, CHNL_SPAN_20, 100, 0, 0}, /* CH_SET_UNII_WW_100_140 */ -+ {125, BAND_5G, CHNL_SPAN_20, 149, 0, 0}, /* CH_SET_UNII_UPPER_149_173 */ -+ } -+ }, -+ { -+ /* User Defined passive scan channel table */ -+ g_u2CountryGroup0_Passive, 0, -+ { -+ {81, BAND_2G4, CHNL_SPAN_5, 12, 1, 0}, /* CH_SET_2G4_1_14 */ -+ {82, BAND_2G4, CHNL_SPAN_5, 5, 0, 0}, -+ -+ {115, BAND_5G, CHNL_SPAN_20, 36, 0, 0}, /* CH_SET_UNII_LOW_36_48 */ -+ {118, BAND_5G, CHNL_SPAN_20, 52, 0, 0}, /* CH_SET_UNII_MID_52_64 */ -+ {121, BAND_5G, CHNL_SPAN_20, 100, 0, 0}, /* CH_SET_UNII_WW_100_140 */ -+ {125, BAND_5G, CHNL_SPAN_20, 149, 0, 0}, /* CH_SET_UNII_UPPER_149_173 */ -+ } -+ } -+}; -+ -+#if CFG_SUPPORT_PWR_LIMIT_COUNTRY -+SUBBAND_CHANNEL_T g_rRlmSubBand[] = { -+ -+ {BAND_2G4_LOWER_BOUND, BAND_2G4_UPPER_BOUND, 1, 0} -+ , /* 2.4G */ -+ {UNII1_LOWER_BOUND, UNII1_UPPER_BOUND, 2, 0} -+ , /* ch36,38,40,..,48 */ -+ {UNII2A_LOWER_BOUND, UNII2A_UPPER_BOUND, 2, 0} -+ , /* ch52,54,56,..,64 */ -+ {UNII2C_LOWER_BOUND, UNII2C_UPPER_BOUND, 2, 0} -+ , /* ch100,102,104,...,144 */ -+ {UNII3_LOWER_BOUND, UNII3_UPPER_BOUND, 2, 0} -+ /* ch149,151,153,....,173 */ -+}; -+#endif -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in/out] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+P_DOMAIN_INFO_ENTRY rlmDomainGetDomainInfo(P_ADAPTER_T prAdapter) -+{ -+#define REG_DOMAIN_DEF_IDX 20 /* Default country domain */ -+#define REG_DOMAIN_GROUP_NUM \ -+ (sizeof(arSupportedRegDomains) / sizeof(DOMAIN_INFO_ENTRY)) -+ -+ P_DOMAIN_INFO_ENTRY prDomainInfo; -+ P_REG_INFO_T prRegInfo; -+ UINT_16 u2TargetCountryCode; -+ UINT_16 i, j; -+ -+ ASSERT(prAdapter); -+ -+ if (prAdapter->prDomainInfo) -+ return prAdapter->prDomainInfo; -+ -+ prRegInfo = &prAdapter->prGlueInfo->rRegInfo; -+ -+ DBGLOG(RLM, TRACE, "eRegChannelListMap=%d, u2CountryCode=0x%04x\n", -+ prRegInfo->eRegChannelListMap, -+ prAdapter->rWifiVar.rConnSettings.u2CountryCode); -+ -+ /* -+ * Domain info can be specified by given idx of arSupportedRegDomains table, -+ * customized, or searched by country code, -+ * only one is set among these three methods in NVRAM. -+ */ -+ if (prRegInfo->eRegChannelListMap == REG_CH_MAP_TBL_IDX && -+ prRegInfo->ucRegChannelListIndex < REG_DOMAIN_GROUP_NUM) { -+ /* by given table idx */ -+ DBGLOG(RLM, TRACE, "ucRegChannelListIndex=%d\n", prRegInfo->ucRegChannelListIndex); -+ prDomainInfo = &arSupportedRegDomains[prRegInfo->ucRegChannelListIndex]; -+ } else if (prRegInfo->eRegChannelListMap == REG_CH_MAP_CUSTOMIZED) { -+ /* by customized */ -+ prDomainInfo = &prRegInfo->rDomainInfo; -+ } else { -+ /* by country code */ -+ u2TargetCountryCode = prAdapter->rWifiVar.rConnSettings.u2CountryCode; -+ -+ for (i = 0; i < REG_DOMAIN_GROUP_NUM; i++) { -+ prDomainInfo = &arSupportedRegDomains[i]; -+ -+ if ((prDomainInfo->u4CountryNum && prDomainInfo->pu2CountryGroup) || -+ prDomainInfo->u4CountryNum == 0) { -+ for (j = 0; j < prDomainInfo->u4CountryNum; j++) { -+ if (prDomainInfo->pu2CountryGroup[j] == u2TargetCountryCode) -+ break; -+ } -+ if (j < prDomainInfo->u4CountryNum) -+ break; /* Found */ -+ } -+ } -+ -+ /* If no matched country code, use the default country domain */ -+ if (i >= REG_DOMAIN_GROUP_NUM) { -+ DBGLOG(RLM, INFO, "No matched country code, use the default country domain\n"); -+ prDomainInfo = &arSupportedRegDomains[REG_DOMAIN_DEF_IDX]; -+ } -+ } -+ -+ prAdapter->prDomainInfo = prDomainInfo; -+ return prDomainInfo; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in/out] The input variable pointed by pucNumOfChannel is the max -+* arrary size. The return value indciates meaning list size. -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+rlmDomainGetChnlList(P_ADAPTER_T prAdapter, -+ ENUM_BAND_T eSpecificBand, BOOLEAN fgNoDfs, -+ UINT_8 ucMaxChannelNum, PUINT_8 pucNumOfChannel, P_RF_CHANNEL_INFO_T paucChannelList) -+{ -+ UINT_8 i, j, ucNum; -+ P_DOMAIN_SUBBAND_INFO prSubband; -+ P_DOMAIN_INFO_ENTRY prDomainInfo; -+ -+ ASSERT(prAdapter); -+ ASSERT(paucChannelList); -+ ASSERT(pucNumOfChannel); -+ -+ prDomainInfo = rlmDomainGetDomainInfo(prAdapter); -+ ASSERT(prDomainInfo); -+ -+ ucNum = 0; -+ for (i = 0; i < MAX_SUBBAND_NUM; i++) { -+ prSubband = &prDomainInfo->rSubBand[i]; -+ -+ if (prSubband->ucBand == BAND_NULL || prSubband->ucBand >= BAND_NUM || -+ (prSubband->ucBand == BAND_5G && !prAdapter->fgEnable5GBand)) -+ continue; -+ -+ if (fgNoDfs == TRUE && prSubband->fgDfs == TRUE) -+ continue; -+ -+ if (eSpecificBand == BAND_NULL || prSubband->ucBand == eSpecificBand) { -+ for (j = 0; j < prSubband->ucNumChannels; j++) { -+ if (ucNum >= ucMaxChannelNum) -+ break; -+ paucChannelList[ucNum].eBand = prSubband->ucBand; -+ paucChannelList[ucNum].ucChannelNum = -+ prSubband->ucFirstChannelNum + j * prSubband->ucChannelSpan; -+ ucNum++; -+ } -+ } -+ } -+ -+ *pucNumOfChannel = ucNum; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief -+* -+* @param[in] -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rlmDomainSendCmd(P_ADAPTER_T prAdapter, BOOLEAN fgIsOid) -+{ -+ rlmDomainSendDomainInfoCmd(prAdapter, fgIsOid); -+#if CFG_SUPPORT_PWR_LIMIT_COUNTRY -+ rlmDomainSendPwrLimitCmd(prAdapter); -+#endif -+ rlmDomainSendPassiveScanInfoCmd(prAdapter, fgIsOid); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief -+* -+* @param[in] -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rlmDomainSendDomainInfoCmd(P_ADAPTER_T prAdapter, BOOLEAN fgIsOid) -+{ -+ P_DOMAIN_INFO_ENTRY prDomainInfo; -+ P_CMD_SET_DOMAIN_INFO_T prCmd; -+ P_DOMAIN_SUBBAND_INFO prSubBand; -+ UINT_8 i; -+ -+ prDomainInfo = rlmDomainGetDomainInfo(prAdapter); -+ ASSERT(prDomainInfo); -+ -+ prCmd = cnmMemAlloc(prAdapter, RAM_TYPE_BUF, sizeof(CMD_SET_DOMAIN_INFO_T)); -+ if (!prCmd) { -+ DBGLOG(RLM, ERROR, "Alloc cmd buffer failed\n"); -+ return; -+ } -+ kalMemZero(prCmd, sizeof(CMD_SET_DOMAIN_INFO_T)); -+ -+ prCmd->u2CountryCode = prAdapter->rWifiVar.rConnSettings.u2CountryCode; -+ prCmd->u2IsSetPassiveScan = 0; -+ prCmd->uc2G4Bandwidth = prAdapter->rWifiVar.rConnSettings.uc2G4BandwidthMode; -+ prCmd->uc5GBandwidth = prAdapter->rWifiVar.rConnSettings.uc5GBandwidthMode; -+ prCmd->aucReserved[0] = 0; -+ prCmd->aucReserved[1] = 0; -+ -+ for (i = 0; i < MAX_SUBBAND_NUM; i++) { -+ prSubBand = &prDomainInfo->rSubBand[i]; -+ -+ prCmd->rSubBand[i].ucRegClass = prSubBand->ucRegClass; -+ prCmd->rSubBand[i].ucBand = prSubBand->ucBand; -+ -+ if (prSubBand->ucBand != BAND_NULL && prSubBand->ucBand < BAND_NUM) { -+ prCmd->rSubBand[i].ucChannelSpan = prSubBand->ucChannelSpan; -+ prCmd->rSubBand[i].ucFirstChannelNum = prSubBand->ucFirstChannelNum; -+ prCmd->rSubBand[i].ucNumChannels = prSubBand->ucNumChannels; -+ } -+ } -+ -+ /* Set domain info to chip */ -+ wlanSendSetQueryCmd(prAdapter, /* prAdapter */ -+ CMD_ID_SET_DOMAIN_INFO, /* ucCID */ -+ TRUE, /* fgSetQuery */ -+ FALSE, /* fgNeedResp */ -+ fgIsOid, /* fgIsOid */ -+ NULL, /* pfCmdDoneHandler */ -+ NULL, /* pfCmdTimeoutHandler */ -+ sizeof(CMD_SET_DOMAIN_INFO_T), /* u4SetQueryInfoLen */ -+ (PUINT_8)prCmd, /* pucInfoBuffer */ -+ NULL, /* pvSetQueryBuffer */ -+ 0 /* u4SetQueryBufferLen */ -+ ); -+ -+ cnmMemFree(prAdapter, prCmd); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief -+* -+* @param[in] -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rlmDomainSendPassiveScanInfoCmd(P_ADAPTER_T prAdapter, BOOLEAN fgIsOid) -+{ -+#define REG_DOMAIN_PASSIVE_DEF_IDX 0 -+#define REG_DOMAIN_PASSIVE_UDF_IDX 1 -+ -+ P_DOMAIN_INFO_ENTRY prDomainInfo; -+ P_CMD_SET_DOMAIN_INFO_T prCmd; -+ P_DOMAIN_SUBBAND_INFO prSubBand; -+ UINT_8 i; -+ -+ prCmd = cnmMemAlloc(prAdapter, RAM_TYPE_BUF, sizeof(CMD_SET_DOMAIN_INFO_T)); -+ if (!prCmd) { -+ DBGLOG(RLM, ERROR, "Alloc cmd buffer failed\n"); -+ return; -+ } -+ kalMemZero(prCmd, sizeof(CMD_SET_DOMAIN_INFO_T)); -+ -+ prCmd->u2CountryCode = prAdapter->rWifiVar.rConnSettings.u2CountryCode; -+ prCmd->u2IsSetPassiveScan = 1; -+ prCmd->uc2G4Bandwidth = prAdapter->rWifiVar.rConnSettings.uc2G4BandwidthMode; -+ prCmd->uc5GBandwidth = prAdapter->rWifiVar.rConnSettings.uc5GBandwidthMode; -+ prCmd->aucReserved[0] = 0; -+ prCmd->aucReserved[1] = 0; -+ -+ DBGLOG(RLM, TRACE, "u2CountryCode=0x%04x\n", prAdapter->rWifiVar.rConnSettings.u2CountryCode); -+ -+ if (prAdapter->rWifiVar.rConnSettings.u2CountryCode == COUNTRY_CODE_UDF) -+ prDomainInfo = &arSupportedRegDomains_Passive[REG_DOMAIN_PASSIVE_UDF_IDX]; -+ else -+ prDomainInfo = &arSupportedRegDomains_Passive[REG_DOMAIN_PASSIVE_DEF_IDX]; -+ -+ for (i = 0; i < MAX_SUBBAND_NUM; i++) { -+ prSubBand = &prDomainInfo->rSubBand[i]; -+ -+ prCmd->rSubBand[i].ucRegClass = prSubBand->ucRegClass; -+ prCmd->rSubBand[i].ucBand = prSubBand->ucBand; -+ -+ if (prSubBand->ucBand != BAND_NULL && prSubBand->ucBand < BAND_NUM) { -+ prCmd->rSubBand[i].ucChannelSpan = prSubBand->ucChannelSpan; -+ prCmd->rSubBand[i].ucFirstChannelNum = prSubBand->ucFirstChannelNum; -+ prCmd->rSubBand[i].ucNumChannels = prSubBand->ucNumChannels; -+ } -+ } -+ -+ /* Set passive scan channel info to chip */ -+ wlanSendSetQueryCmd(prAdapter, /* prAdapter */ -+ CMD_ID_SET_DOMAIN_INFO, /* ucCID */ -+ TRUE, /* fgSetQuery */ -+ FALSE, /* fgNeedResp */ -+ fgIsOid, /* fgIsOid */ -+ NULL, /* pfCmdDoneHandler */ -+ NULL, /* pfCmdTimeoutHandler */ -+ sizeof(CMD_SET_DOMAIN_INFO_T), /* u4SetQueryInfoLen */ -+ (PUINT_8) prCmd, /* pucInfoBuffer */ -+ NULL, /* pvSetQueryBuffer */ -+ 0 /* u4SetQueryBufferLen */ -+ ); -+ -+ cnmMemFree(prAdapter, prCmd); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in/out] -+* -+* \return TRUE Legal channel -+* FALSE Illegal channel for current regulatory domain -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN rlmDomainIsLegalChannel(P_ADAPTER_T prAdapter, ENUM_BAND_T eBand, UINT_8 ucChannel) -+{ -+ UINT_8 i, j; -+ P_DOMAIN_SUBBAND_INFO prSubband; -+ P_DOMAIN_INFO_ENTRY prDomainInfo; -+ -+ prDomainInfo = rlmDomainGetDomainInfo(prAdapter); -+ ASSERT(prDomainInfo); -+ -+ for (i = 0; i < MAX_SUBBAND_NUM; i++) { -+ prSubband = &prDomainInfo->rSubBand[i]; -+ -+ if (prSubband->ucBand == BAND_5G && !prAdapter->fgEnable5GBand) -+ continue; -+ -+ if (prSubband->ucBand == eBand) { -+ for (j = 0; j < prSubband->ucNumChannels; j++) { -+ if ((prSubband->ucFirstChannelNum + j * prSubband->ucChannelSpan) -+ == ucChannel) { -+ return TRUE; -+ } -+ } -+ } -+ } -+ -+ return FALSE; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in/out] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+ -+UINT_32 rlmDomainSupOperatingClassIeFill(PUINT_8 pBuf) -+{ -+ /* -+ The Country element should only be included for Status Code 0 (Successful). -+ */ -+ UINT_32 u4IeLen; -+ UINT_8 aucClass[12] = { 0x01, 0x02, 0x03, 0x05, 0x16, 0x17, 0x19, 0x1b, -+ 0x1c, 0x1e, 0x20, 0x21 -+ }; -+ -+ /* -+ The Supported Operating Classes element is used by a STA to advertise the -+ operating classes that it is capable of operating with in this country. -+ -+ The Country element (see 8.4.2.10) allows a STA to configure its PHY and MAC -+ for operation when the operating triplet of Operating Extension Identifier, -+ Operating Class, and Coverage Class fields is present. -+ */ -+ SUP_OPERATING_CLASS_IE(pBuf)->ucId = ELEM_ID_SUP_OPERATING_CLASS; -+ SUP_OPERATING_CLASS_IE(pBuf)->ucLength = 1 + sizeof(aucClass); -+ SUP_OPERATING_CLASS_IE(pBuf)->ucCur = 0x0c; /* 0x51 */ -+ kalMemCopy(SUP_OPERATING_CLASS_IE(pBuf)->ucSup, aucClass, sizeof(aucClass)); -+ u4IeLen = (SUP_OPERATING_CLASS_IE(pBuf)->ucLength + 2); -+ pBuf += u4IeLen; -+ -+ COUNTRY_IE(pBuf)->ucId = ELEM_ID_COUNTRY_INFO; -+ COUNTRY_IE(pBuf)->ucLength = 6; -+ COUNTRY_IE(pBuf)->aucCountryStr[0] = 0x55; -+ COUNTRY_IE(pBuf)->aucCountryStr[1] = 0x53; -+ COUNTRY_IE(pBuf)->aucCountryStr[2] = 0x20; -+ COUNTRY_IE(pBuf)->arCountryStr[0].ucFirstChnlNum = 1; -+ COUNTRY_IE(pBuf)->arCountryStr[0].ucNumOfChnl = 11; -+ COUNTRY_IE(pBuf)->arCountryStr[0].cMaxTxPwrLv = 0x1e; -+ u4IeLen += (COUNTRY_IE(pBuf)->ucLength + 2); -+ -+ return u4IeLen; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief -+* -+* @param[in] -+* -+* @return (fgValid) : 0 -> inValid, 1 -> Valid -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN rlmDomainCheckChannelEntryValid(P_ADAPTER_T prAdapter, UINT_8 ucCentralCh) -+{ -+ BOOLEAN fgValid = FALSE; -+ UINT_8 ucTemp = 0; -+ UINT_8 i; -+ /*Check Power limit table channel efficient or not */ -+ -+ for (i = POWER_LIMIT_2G4; i < POWER_LIMIT_SUBAND_NUM; i++) { -+ if ((ucCentralCh >= g_rRlmSubBand[i].ucStartCh) && (ucCentralCh <= g_rRlmSubBand[i].ucEndCh)) -+ ucTemp = (ucCentralCh - g_rRlmSubBand[i].ucStartCh) % g_rRlmSubBand[i].ucInterval; -+ } -+ -+#if 0 -+ /*2.4G, ex 1, 2, 3 */ -+ if (ucCentralCh >= BAND_2G4_LOWER_BOUND && ucCentralCh <= BAND_2G4_UPPER_BOUND) -+ ucTemp = 0; -+ /*FCC- Spec : Band UNII-1, ex 36, 38, 40.... */ -+ else if (ucCentralCh >= UNII1_LOWER_BOUND && ucCentralCh <= UNII1_UPPER_BOUND) -+ ucTemp = (ucCentralCh - UNII1_LOWER_BOUND) % 2; -+ /*FCC- Spec : Band UNII-2A, ex 52, 54, 56.... */ -+ else if (ucCentralCh >= UNII2A_LOWER_BOUND && ucCentralCh <= UNII2A_UPPER_BOUND) -+ ucTemp = (ucCentralCh - UNII2A_LOWER_BOUND) % 2; -+ /*FCC- Spec : Band UNII-2C, ex 100, 102, 104.... */ -+ else if (ucCentralCh >= UNII2C_LOWER_BOUND && ucCentralCh <= UNII2C_UPPER_BOUND) -+ ucTemp = (ucCentralCh - UNII2C_LOWER_BOUND) % 2; -+ /*FCC- Spec : Band UNII-3, ex 149, 151, 153... */ -+ else if (ucCentralCh >= UNII3_LOWER_BOUND && ucCentralCh <= UNII3_UPPER_BOUND) -+ ucTemp = (ucCentralCh - UNII3_LOWER_BOUND) % 2; -+#endif -+ if (ucTemp == 0) -+ fgValid = TRUE; -+ return fgValid; -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT_8 rlmDomainGetCenterChannel(ENUM_BAND_T eBand, UINT_8 ucPriChannel, ENUM_CHNL_EXT_T eExtend) -+{ -+ UINT_8 ucCenterChannel; -+ -+ if (eExtend == CHNL_EXT_SCA) -+ ucCenterChannel = ucPriChannel + 2; -+ else if (eExtend == CHNL_EXT_SCB) -+ ucCenterChannel = ucPriChannel - 2; -+ else -+ ucCenterChannel = ucPriChannel; -+ -+ return ucCenterChannel; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN -+rlmDomainIsValidRfSetting(P_ADAPTER_T prAdapter, -+ ENUM_BAND_T eBand, -+ UINT_8 ucPriChannel, -+ ENUM_CHNL_EXT_T eExtend, -+ ENUM_CHANNEL_WIDTH_T eChannelWidth, UINT_8 ucChannelS1, UINT_8 ucChannelS2) -+{ -+ UINT_8 ucCenterChannel; -+ BOOLEAN fgValidChannel = TRUE; -+ BOOLEAN fgValidBW = TRUE; -+ BOOLEAN fgValidRfSetting = TRUE; -+ UINT_32 u4PrimaryOffset; -+ -+ /*DBG msg for Channel InValid */ -+ if (eChannelWidth == CW_20_40MHZ) { -+ ucCenterChannel = rlmDomainGetCenterChannel(eBand, ucPriChannel, eExtend); -+ -+ /* Check Central Channel Valid or Not */ -+ fgValidChannel = rlmDomainCheckChannelEntryValid(prAdapter, ucCenterChannel); -+ if (fgValidChannel == FALSE) -+ DBGLOG(RLM, WARN, "Rf: CentralCh=%d\n", ucCenterChannel); -+ } else if (eChannelWidth == CW_80MHZ) { -+ ucCenterChannel = ucChannelS1; -+ -+ /* Check Central Channel Valid or Not */ -+ fgValidChannel = rlmDomainCheckChannelEntryValid(prAdapter, ucCenterChannel); -+ if (fgValidChannel == FALSE) -+ DBGLOG(RLM, WARN, "Rf: CentralCh=%d\n", ucCenterChannel); -+ } else if (eChannelWidth == CW_160MHZ) { -+ ucCenterChannel = ucChannelS2; -+ -+ /* Check Central Channel Valid or Not */ -+ /*TODo */ -+ } -+ -+ /* Check BW Setting Correct or Not */ -+ if (eBand == BAND_2G4) { -+ if (eChannelWidth != CW_20_40MHZ) { -+ fgValidBW = FALSE; -+ DBGLOG(RLM, WARN, "Rf: B=%d, W=%d\n", eBand, eChannelWidth); -+ } -+ } else { -+ if (eChannelWidth == CW_80MHZ) { -+ u4PrimaryOffset = CAL_CH_OFFSET_80M(ucPriChannel, ucCenterChannel); -+ if (u4PrimaryOffset > 4) { -+ fgValidBW = FALSE; -+ DBGLOG(RLM, WARN, "Rf: PriOffSet=%d, W=%d\n", u4PrimaryOffset, eChannelWidth); -+ } -+ } else if (eChannelWidth == CW_160MHZ) { -+ u4PrimaryOffset = CAL_CH_OFFSET_160M(ucPriChannel, ucCenterChannel); -+ if (u4PrimaryOffset > 8) { -+ fgValidBW = FALSE; -+ DBGLOG(RLM, WARN, "Rf: PriOffSet=%d, W=%d\n", u4PrimaryOffset, eChannelWidth); -+ } -+ } -+ } -+ -+ if ((fgValidBW == FALSE) || (fgValidChannel == FALSE)) -+ fgValidRfSetting = FALSE; -+ -+ return fgValidRfSetting; -+ -+} -+ -+#if CFG_SUPPORT_PWR_LIMIT_COUNTRY -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief -+* -+* @param[in] -+* -+* @return (fgValid) : 0 -> inValid, 1 -> Valid -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN -+rlmDomainCheckPowerLimitValid(P_ADAPTER_T prAdapter, -+ COUNTRY_POWER_LIMIT_TABLE_CONFIGURATION rPowerLimitTableConfiguration, -+ UINT_8 ucPwrLimitNum) -+{ -+ UINT_8 i; -+ BOOLEAN fgValid = TRUE; -+ PINT_8 prPwrLimit; -+ -+ prPwrLimit = &rPowerLimitTableConfiguration.aucPwrLimit[0]; -+ -+ for (i = 0; i < ucPwrLimitNum; i++, prPwrLimit++) { -+ if (*prPwrLimit > MAX_TX_POWER || *prPwrLimit < MIN_TX_POWER) { -+ fgValid = FALSE; -+ break; /*Find out Wrong Power limit */ -+ } -+ } -+ return fgValid; -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief -+* -+* @param[in] -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rlmDomainCheckCountryPowerLimitTable(P_ADAPTER_T prAdapter) -+{ -+ UINT_8 i, j; -+ UINT_16 u2CountryCodeTable, u2CountryCodeCheck; -+ BOOLEAN fgChannelValid = FALSE; -+ BOOLEAN fgPowerLimitValid = FALSE; -+ BOOLEAN fgEntryRepetetion = FALSE; -+ BOOLEAN fgTableValid = TRUE; -+ -+ /*Configuration Table Check */ -+ for (i = 0; i < sizeof(g_rRlmPowerLimitConfiguration) / sizeof(COUNTRY_POWER_LIMIT_TABLE_CONFIGURATION); i++) { -+ /*Table Country Code */ -+ WLAN_GET_FIELD_BE16(&g_rRlmPowerLimitConfiguration[i].aucCountryCode[0], &u2CountryCodeTable); -+ -+ /*Repetition Entry Check */ -+ for (j = i + 1; -+ j < sizeof(g_rRlmPowerLimitConfiguration) / sizeof(COUNTRY_POWER_LIMIT_TABLE_CONFIGURATION); -+ j++) { -+ -+ WLAN_GET_FIELD_BE16(&g_rRlmPowerLimitConfiguration[j].aucCountryCode[0], &u2CountryCodeCheck); -+ if (((g_rRlmPowerLimitConfiguration[i].ucCentralCh) == -+ g_rRlmPowerLimitConfiguration[j].ucCentralCh) -+ && (u2CountryCodeTable == u2CountryCodeCheck)) { -+ fgEntryRepetetion = TRUE; -+ DBGLOG(RLM, LOUD, "Domain: Configuration Repetition CC=%c%c, Ch=%d\n", -+ g_rRlmPowerLimitConfiguration[i].aucCountryCode[0], -+ g_rRlmPowerLimitConfiguration[i].aucCountryCode[1], -+ g_rRlmPowerLimitConfiguration[i].ucCentralCh); -+ } -+ } -+ -+ /*Channel Number Check */ -+ fgChannelValid = -+ rlmDomainCheckChannelEntryValid(prAdapter, g_rRlmPowerLimitConfiguration[i].ucCentralCh); -+ -+ /*Power Limit Check */ -+ fgPowerLimitValid = -+ rlmDomainCheckPowerLimitValid(prAdapter, g_rRlmPowerLimitConfiguration[i], PWR_LIMIT_NUM); -+ -+ if (fgChannelValid == FALSE || fgPowerLimitValid == FALSE) { -+ fgTableValid = FALSE; -+ DBGLOG(RLM, LOUD, "Domain: CC=%c%c, Ch=%d, Limit: %d,%d,%d,%d,%d\n", -+ g_rRlmPowerLimitConfiguration[i].aucCountryCode[0], -+ g_rRlmPowerLimitConfiguration[i].aucCountryCode[1], -+ g_rRlmPowerLimitConfiguration[i].ucCentralCh, -+ g_rRlmPowerLimitConfiguration[i].aucPwrLimit[PWR_LIMIT_CCK], -+ g_rRlmPowerLimitConfiguration[i].aucPwrLimit[PWR_LIMIT_20M], -+ g_rRlmPowerLimitConfiguration[i].aucPwrLimit[PWR_LIMIT_40M], -+ g_rRlmPowerLimitConfiguration[i].aucPwrLimit[PWR_LIMIT_80M], -+ g_rRlmPowerLimitConfiguration[i].aucPwrLimit[PWR_LIMIT_160M]); -+ } -+ -+ if (u2CountryCodeTable == COUNTRY_CODE_NULL) { -+ DBGLOG(RLM, LOUD, "Domain: Full search down\n"); -+ break; /*End of country table entry */ -+ } -+ -+ } -+ -+ if (fgEntryRepetetion == FALSE) -+ DBGLOG(RLM, TRACE, "Domain: Configuration Table no Repetiton.\n"); -+ -+ /*Configuration Table no error */ -+ if (fgTableValid == TRUE) -+ prAdapter->fgIsPowerLimitTableValid = TRUE; -+ else -+ prAdapter->fgIsPowerLimitTableValid = FALSE; -+ -+ /*Default Table Check */ -+ fgEntryRepetetion = FALSE; -+ for (i = 0; i < sizeof(g_rRlmPowerLimitDefault) / sizeof(COUNTRY_POWER_LIMIT_TABLE_DEFAULT); i++) { -+ -+ WLAN_GET_FIELD_BE16(&g_rRlmPowerLimitDefault[i].aucCountryCode[0], &u2CountryCodeTable); -+ -+ for (j = i + 1; j < sizeof(g_rRlmPowerLimitDefault) / sizeof(COUNTRY_POWER_LIMIT_TABLE_DEFAULT); j++) { -+ WLAN_GET_FIELD_BE16(&g_rRlmPowerLimitDefault[j].aucCountryCode[0], &u2CountryCodeCheck); -+ if (u2CountryCodeTable == u2CountryCodeCheck) { -+ fgEntryRepetetion = TRUE; -+ DBGLOG(RLM, LOUD, -+ "Domain: Default Repetition CC=%c%c\n", -+ g_rRlmPowerLimitDefault[j].aucCountryCode[0], -+ g_rRlmPowerLimitDefault[j].aucCountryCode[1]); -+ } -+ } -+ } -+ if (fgEntryRepetetion == FALSE) -+ DBGLOG(RLM, TRACE, "Domain: Default Table no Repetiton.\n"); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief -+* -+* @param[in] -+* -+* @return (u2TableIndex) : if 0xFFFF -> No Table Match -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT_16 rlmDomainPwrLimitDefaultTableDecision(P_ADAPTER_T prAdapter, UINT_16 u2CountryCode) -+{ -+ -+ UINT_16 i; -+ UINT_16 u2CountryCodeTable = COUNTRY_CODE_NULL; -+ UINT_16 u2TableIndex = POWER_LIMIT_TABLE_NULL; /* No Table Match */ -+ -+ /*Default Table Index */ -+ for (i = 0; i < sizeof(g_rRlmPowerLimitDefault) / sizeof(COUNTRY_POWER_LIMIT_TABLE_DEFAULT); i++) { -+ -+ WLAN_GET_FIELD_BE16(&g_rRlmPowerLimitDefault[i].aucCountryCode[0], &u2CountryCodeTable); -+ -+ if (u2CountryCodeTable == u2CountryCode) { -+ u2TableIndex = i; -+ break; /*match country code */ -+ } else if (u2CountryCodeTable == COUNTRY_CODE_NULL) { -+ u2TableIndex = i; -+ break; /*find last one country- Default */ -+ } -+ } -+ -+ DBGLOG(RLM, TRACE, "Domain: Default Table Index = %d\n", u2TableIndex); -+ -+ return u2TableIndex; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief -+* -+* @param[in] -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rlmDomainBuildCmdByDefaultTable(P_CMD_SET_COUNTRY_CHANNEL_POWER_LIMIT_T prCmd, UINT_16 u2DefaultTableIndex) -+{ -+ UINT_8 i, k; -+ P_COUNTRY_POWER_LIMIT_TABLE_DEFAULT prPwrLimitSubBand; -+ P_CMD_CHANNEL_POWER_LIMIT prCmdPwrLimit; -+ -+ prCmdPwrLimit = &prCmd->rChannelPowerLimit[0]; -+ prPwrLimitSubBand = &g_rRlmPowerLimitDefault[u2DefaultTableIndex]; -+ -+ /*Build power limit cmd by default table information */ -+ -+ for (i = POWER_LIMIT_2G4; i < POWER_LIMIT_SUBAND_NUM; i++) { -+ if (prPwrLimitSubBand->aucPwrLimitSubBand[i] < MAX_TX_POWER) { -+ for (k = g_rRlmSubBand[i].ucStartCh; k <= g_rRlmSubBand[i].ucEndCh; -+ k += g_rRlmSubBand[i].ucInterval) { -+ if ((prPwrLimitSubBand->ucPwrUnit & BIT(i)) == 0) { -+ prCmdPwrLimit->ucCentralCh = k; -+ prCmdPwrLimit->cPwrLimitCCK = -+ prPwrLimitSubBand->aucPwrLimitSubBand[i]; -+ prCmdPwrLimit->cPwrLimit20 = -+ prPwrLimitSubBand->aucPwrLimitSubBand[i]; -+ prCmdPwrLimit->cPwrLimit40 = -+ prPwrLimitSubBand->aucPwrLimitSubBand[i]; -+ prCmdPwrLimit->cPwrLimit80 = -+ prPwrLimitSubBand->aucPwrLimitSubBand[i]; -+ prCmdPwrLimit->cPwrLimit160 = -+ prPwrLimitSubBand->aucPwrLimitSubBand[i]; -+ prCmdPwrLimit++; -+ prCmd->ucNum++; -+ -+ } else { -+ /* ex: 40MHz power limit(mW\MHz) = 20MHz power limit(mW\MHz) * 2 -+ * ---> 40MHz power limit(dBm) = 20MHz power limit(dBm) + 6; */ -+ prCmdPwrLimit->ucCentralCh = k; -+ prCmdPwrLimit->cPwrLimitCCK = prPwrLimitSubBand->aucPwrLimitSubBand[i]; -+ prCmdPwrLimit->cPwrLimit20 = prPwrLimitSubBand->aucPwrLimitSubBand[i]; -+ prCmdPwrLimit->cPwrLimit40 = prPwrLimitSubBand->aucPwrLimitSubBand[i] + 6; -+ if (prCmdPwrLimit->cPwrLimit40 > MAX_TX_POWER) -+ prCmdPwrLimit->cPwrLimit40 = MAX_TX_POWER; -+ prCmdPwrLimit->cPwrLimit80 = prPwrLimitSubBand->aucPwrLimitSubBand[i] + 12; -+ if (prCmdPwrLimit->cPwrLimit80 > MAX_TX_POWER) -+ prCmdPwrLimit->cPwrLimit80 = MAX_TX_POWER; -+ prCmdPwrLimit->cPwrLimit160 = prPwrLimitSubBand->aucPwrLimitSubBand[i] + 18; -+ if (prCmdPwrLimit->cPwrLimit160 > MAX_TX_POWER) -+ prCmdPwrLimit->cPwrLimit160 = MAX_TX_POWER; -+ prCmdPwrLimit++; -+ prCmd->ucNum++; -+ } -+ } -+ } -+ } -+ -+#if 0 -+ if (prPwrLimitSubBand->aucPwrLimitSubBand[POWER_LIMIT_2G4] < MAX_TX_POWER) { -+ for (i = BAND_2G4_LOWER_BOUND; i <= BAND_2G4_UPPER_BOUND; i++) { -+ prCmdPwrLimit->ucCentralCh = i; -+ kalMemSet(&prCmdPwrLimit->cPwrLimitCCK, prPwrLimitSubBand->aucPwrLimitSubBand[POWER_LIMIT_2G4], -+ PWR_LIMIT_NUM); -+ prCmdPwrLimit++; -+ prCmd->ucNum++; -+ } -+ } -+ -+ if (prPwrLimitSubBand->aucPwrLimitSubBand[POWER_LIMIT_UNII1] < MAX_TX_POWER) { -+ if (prCmd->u2CountryCode != COUNTRY_CODE_KR) { -+ for (i = UNII1_LOWER_BOUND; i <= UNII1_UPPER_BOUND; i += 2) { -+ prCmdPwrLimit->ucCentralCh = i; -+ kalMemSet(&prCmdPwrLimit->cPwrLimitCCK, -+ prPwrLimitSubBand->aucPwrLimitSubBand[POWER_LIMIT_UNII1], PWR_LIMIT_NUM); -+ prCmdPwrLimit++; -+ prCmd->ucNum++; -+ } -+ } else { -+ for (i = UNII1_LOWER_BOUND; i <= UNII1_UPPER_BOUND; i += 2) { -+ /* ex: 40MHz power limit(mW\MHz) = 20MHz power limit(mW\MHz) * 2 -+ * ---> 40MHz power limit(dBm) = 20MHz power limit(dBm) + 6; */ -+ prCmdPwrLimit->ucCentralCh = i; -+ prCmdPwrLimit->cPwrLimitCCK = -+ g_rRlmPowerLimitDefault[u2DefaultTableIndex].cPwrLimitUnii1; -+ prCmdPwrLimit->cPwrLimit20 = -+ g_rRlmPowerLimitDefault[u2DefaultTableIndex].cPwrLimitUnii1; -+ prCmdPwrLimit->cPwrLimit40 = -+ g_rRlmPowerLimitDefault[u2DefaultTableIndex].cPwrLimitUnii1 + 6; -+ prCmdPwrLimit->cPwrLimit80 = -+ g_rRlmPowerLimitDefault[u2DefaultTableIndex].cPwrLimitUnii1 + 12; -+ prCmdPwrLimit->cPwrLimit160 = -+ g_rRlmPowerLimitDefault[u2DefaultTableIndex].cPwrLimitUnii1 + 18; -+ prCmdPwrLimit++; -+ prCmd->ucNum++; -+ } -+ } -+ } -+ -+ if (prPwrLimitSubBand->aucPwrLimitSubBand[POWER_LIMIT_UNII2A] < MAX_TX_POWER) { -+ for (i = UNII2A_LOWER_BOUND; i <= UNII2A_UPPER_BOUND; i += 2) { -+ prCmdPwrLimit->ucCentralCh = i; -+ kalMemSet(&prCmdPwrLimit->cPwrLimitCCK, -+ prPwrLimitSubBand->aucPwrLimitSubBand[POWER_LIMIT_UNII2A], PWR_LIMIT_NUM); -+ prCmdPwrLimit++; -+ prCmd->ucNum++; -+ } -+ } -+ -+ if (prPwrLimitSubBand->aucPwrLimitSubBand[POWER_LIMIT_UNII2C] < MAX_TX_POWER) { -+ for (i = UNII2C_LOWER_BOUND; i <= UNII2C_UPPER_BOUND; i += 2) { -+ prCmdPwrLimit->ucCentralCh = i; -+ kalMemSet(&prCmdPwrLimit->cPwrLimitCCK, -+ prPwrLimitSubBand->aucPwrLimitSubBand[POWER_LIMIT_UNII2C], PWR_LIMIT_NUM); -+ prCmdPwrLimit++; -+ prCmd->ucNum++; -+ } -+ } -+ if (prPwrLimitSubBand->aucPwrLimitSubBand[POWER_LIMIT_UNII3] < MAX_TX_POWER) { -+ for (i = UNII3_LOWER_BOUND; i <= UNII3_UPPER_BOUND; i += 2) { -+ prCmdPwrLimit->ucCentralCh = i; -+ kalMemSet(&prCmdPwrLimit->cPwrLimitCCK, -+ prPwrLimitSubBand->aucPwrLimitSubBand[POWER_LIMIT_UNII3], PWR_LIMIT_NUM); -+ prCmdPwrLimit++; -+ prCmd->ucNum++; -+ } -+ } -+#endif -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief -+* -+* @param[in] -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rlmDomainBuildCmdByConfigTable(P_ADAPTER_T prAdapter, P_CMD_SET_COUNTRY_CHANNEL_POWER_LIMIT_T prCmd) -+{ -+ UINT_8 i, k; -+ UINT_16 u2CountryCodeTable = COUNTRY_CODE_NULL; -+ P_CMD_CHANNEL_POWER_LIMIT prCmdPwrLimit; -+ BOOLEAN fgChannelValid; -+ -+ /*Build power limit cmd by configuration table information */ -+ -+ for (i = 0; i < sizeof(g_rRlmPowerLimitConfiguration) / sizeof(COUNTRY_POWER_LIMIT_TABLE_CONFIGURATION); i++) { -+ -+ WLAN_GET_FIELD_BE16(&g_rRlmPowerLimitConfiguration[i].aucCountryCode[0], &u2CountryCodeTable); -+ -+ fgChannelValid = -+ rlmDomainCheckChannelEntryValid(prAdapter, g_rRlmPowerLimitConfiguration[i].ucCentralCh); -+ -+ if (u2CountryCodeTable == COUNTRY_CODE_NULL) { -+ DBGLOG(RLM, TRACE, "Domain: full search configuration table done.\n"); -+ break; /*end of configuration table */ -+ } else if ((u2CountryCodeTable == prCmd->u2CountryCode) && (fgChannelValid == TRUE)) { -+ -+ prCmdPwrLimit = &prCmd->rChannelPowerLimit[0]; -+ -+ if (prCmd->ucNum != 0) { -+ for (k = 0; k < prCmd->ucNum; k++) { -+ if (prCmdPwrLimit->ucCentralCh == -+ g_rRlmPowerLimitConfiguration[i].ucCentralCh) { -+ -+ /*Cmd setting (Default table information) and -+ Configuration table has repetition channel entry, -+ ex : Default table (ex: 2.4G, limit = 20dBm) --> ch1~14 limit =20dBm, -+ Configuration table (ex: ch1, limit = 22dBm) --> ch 1 = 22 dBm -+ Cmd final setting --> ch1 = 22dBm, ch12~14 = 20dBm -+ */ -+ prCmdPwrLimit->cPwrLimitCCK = -+ g_rRlmPowerLimitConfiguration[i].aucPwrLimit[PWR_LIMIT_CCK]; -+ prCmdPwrLimit->cPwrLimit20 = -+ g_rRlmPowerLimitConfiguration[i].aucPwrLimit[PWR_LIMIT_20M]; -+ prCmdPwrLimit->cPwrLimit40 = -+ g_rRlmPowerLimitConfiguration[i].aucPwrLimit[PWR_LIMIT_40M]; -+ prCmdPwrLimit->cPwrLimit80 = -+ g_rRlmPowerLimitConfiguration[i].aucPwrLimit[PWR_LIMIT_80M]; -+ prCmdPwrLimit->cPwrLimit160 = -+ g_rRlmPowerLimitConfiguration[i].aucPwrLimit[PWR_LIMIT_160M]; -+ -+ DBGLOG(RLM, LOUD, -+ "Domain: CC=%c%c,ConfigCh=%d,Limit=%d,%d,%d,%d,%d,Fg=%d\n", -+ ((prCmd->u2CountryCode & 0xff00) >> 8), -+ (prCmd->u2CountryCode & 0x00ff), prCmdPwrLimit->ucCentralCh, -+ prCmdPwrLimit->cPwrLimitCCK, prCmdPwrLimit->cPwrLimit20, -+ prCmdPwrLimit->cPwrLimit40, prCmdPwrLimit->cPwrLimit80, -+ prCmdPwrLimit->cPwrLimit160, prCmdPwrLimit->ucFlag); -+ -+ break; -+ } -+ prCmdPwrLimit++; -+ } -+ if (k == prCmd->ucNum) { -+ -+ /*Full search cmd (Default table setting) no match channey, -+ ex : Default table (ex: 2.4G, limit = 20dBm) --> ch1~14 limit =20dBm, -+ Configuration table (ex: ch36, limit = 22dBm) --> ch 36 = 22 dBm -+ Cmd final setting --> ch1~14 = 20dBm, ch36= 22dBm -+ */ -+ prCmdPwrLimit->cPwrLimitCCK = -+ g_rRlmPowerLimitConfiguration[i].aucPwrLimit[PWR_LIMIT_CCK]; -+ prCmdPwrLimit->cPwrLimit20 = -+ g_rRlmPowerLimitConfiguration[i].aucPwrLimit[PWR_LIMIT_20M]; -+ prCmdPwrLimit->cPwrLimit40 = -+ g_rRlmPowerLimitConfiguration[i].aucPwrLimit[PWR_LIMIT_40M]; -+ prCmdPwrLimit->cPwrLimit80 = -+ g_rRlmPowerLimitConfiguration[i].aucPwrLimit[PWR_LIMIT_80M]; -+ prCmdPwrLimit->cPwrLimit160 = -+ g_rRlmPowerLimitConfiguration[i].aucPwrLimit[PWR_LIMIT_160M]; -+ prCmd->ucNum++; -+ -+ DBGLOG(RLM, LOUD, -+ "Domain: Full CC=%c%c,ConfigCh=%d,Limit=%d,%d,%d,%d,%d,Fg=%d\n", -+ ((prCmd->u2CountryCode & 0xff00) >> 8), (prCmd->u2CountryCode & 0x00ff), -+ prCmdPwrLimit->ucCentralCh, prCmdPwrLimit->cPwrLimitCCK, -+ prCmdPwrLimit->cPwrLimit20, prCmdPwrLimit->cPwrLimit40, -+ prCmdPwrLimit->cPwrLimit80, prCmdPwrLimit->cPwrLimit160, -+ prCmdPwrLimit->ucFlag); -+ -+ } -+ } else { -+ -+ /*Default table power limit value are 63--> cmd table no channel entry -+ ex : Default table (ex: 2.4G, limit = 63Bm) --> no channel entry in cmd, -+ Configuration table (ex: ch36, limit = 22dBm) --> ch 36 = 22 dBm -+ Cmd final setting --> ch36= 22dBm -+ */ -+ prCmdPwrLimit->ucCentralCh = g_rRlmPowerLimitConfiguration[i].ucCentralCh; -+ prCmdPwrLimit->cPwrLimitCCK = -+ g_rRlmPowerLimitConfiguration[i].aucPwrLimit[PWR_LIMIT_CCK]; -+ prCmdPwrLimit->cPwrLimit20 = -+ g_rRlmPowerLimitConfiguration[i].aucPwrLimit[PWR_LIMIT_20M]; -+ prCmdPwrLimit->cPwrLimit40 = -+ g_rRlmPowerLimitConfiguration[i].aucPwrLimit[PWR_LIMIT_40M]; -+ prCmdPwrLimit->cPwrLimit80 = -+ g_rRlmPowerLimitConfiguration[i].aucPwrLimit[PWR_LIMIT_80M]; -+ prCmdPwrLimit->cPwrLimit160 = -+ g_rRlmPowerLimitConfiguration[i].aucPwrLimit[PWR_LIMIT_160M]; -+ prCmd->ucNum++; -+ -+ DBGLOG(RLM, LOUD, "Domain: Default table power limit value are 63.\n"); -+ DBGLOG(RLM, LOUD, "Domain: CC=%c%c,ConfigCh=%d,Limit=%d,%d,%d,%d,%d,Fg=%d\n", -+ ((prCmd->u2CountryCode & 0xff00) >> 8), -+ (prCmd->u2CountryCode & 0x00ff), prCmdPwrLimit->ucCentralCh, -+ prCmdPwrLimit->cPwrLimitCCK, prCmdPwrLimit->cPwrLimit20, -+ prCmdPwrLimit->cPwrLimit40, prCmdPwrLimit->cPwrLimit80, -+ prCmdPwrLimit->cPwrLimit160, prCmdPwrLimit->ucFlag); -+ -+ } -+ } -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief -+* -+* @param[in] -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rlmDomainSendPwrLimitCmd(P_ADAPTER_T prAdapter) -+{ -+ P_CMD_SET_COUNTRY_CHANNEL_POWER_LIMIT_T prCmd; -+ UINT_8 i; -+ UINT_16 u2DefaultTableIndex; -+ UINT_32 u4SetCmdTableMaxSize; -+ UINT_32 u4SetQueryInfoLen; -+ P_CMD_CHANNEL_POWER_LIMIT prCmdPwrLimit; /* for print usage */ -+ -+ u4SetCmdTableMaxSize = -+ sizeof(CMD_SET_COUNTRY_CHANNEL_POWER_LIMIT_T) + -+ MAX_CMD_SUPPORT_CHANNEL_NUM * sizeof(CMD_CHANNEL_POWER_LIMIT); -+ -+ prCmd = cnmMemAlloc(prAdapter, RAM_TYPE_BUF, u4SetCmdTableMaxSize); -+ -+ if (!prCmd) { -+ DBGLOG(RLM, ERROR, "Domain: no buf to send cmd\n"); -+ return; -+ } -+ kalMemZero(prCmd, u4SetCmdTableMaxSize); -+ -+ u2DefaultTableIndex = -+ rlmDomainPwrLimitDefaultTableDecision(prAdapter, prAdapter->rWifiVar.rConnSettings.u2CountryCode); -+ -+ if (u2DefaultTableIndex != POWER_LIMIT_TABLE_NULL) { -+ -+ WLAN_GET_FIELD_BE16(&g_rRlmPowerLimitDefault[u2DefaultTableIndex].aucCountryCode[0], -+ &prCmd->u2CountryCode); -+ -+ prCmd->ucNum = 0; -+ -+ if (prCmd->u2CountryCode != COUNTRY_CODE_NULL) { -+ /*Command - default table information */ -+ rlmDomainBuildCmdByDefaultTable(prCmd, u2DefaultTableIndex); -+ -+ /*Command - configuration table information */ -+ rlmDomainBuildCmdByConfigTable(prAdapter, prCmd); -+ } -+ } -+#if 0 -+ u4SetCmdTableMaxSize = -+ sizeof(CMD_SET_COUNTRY_CHANNEL_POWER_LIMIT_T) + -+ MAX_CMD_SUPPORT_CHANNEL_NUM * sizeof(CMD_CHANNEL_POWER_LIMIT); -+ -+ prCmd = cnmMemAlloc(prAdapter, RAM_TYPE_BUF, u4SetCmdTableMaxSize); -+ ASSERT(prCmd); -+ -+ /* To do: exception handle */ -+ if (!prCmd) { -+ DBGLOG(RLM, ERROR, "Domain: no buf to send cmd\n"); -+ return; -+ } -+ kalMemZero(prCmd, u4SetCmdTableMaxSize); /* TODO memzero */ -+ -+ if (u2TableIndex != POWER_LIMIT_TABLE_NULL && u2TableIndex < MAX_DEFAULT_TABLE_COUNTRY_NUM) { -+ -+ prCmd->u2CountryCode = (((UINT_16) g_rRlmCountryPowerLimitTable[u2TableIndex].aucCountryCode[0]) << 8) | -+ (((UINT_16) g_rRlmCountryPowerLimitTable[u2TableIndex].aucCountryCode[1]) & BITS(0, 7)); -+ prChPwrLimit = &g_rRlmCountryPowerLimitTable[u2TableIndex].rChannelPowerLimit[0]; -+ prCmdPwrLimit = &prCmd->rChannelPowerLimit[0]; -+ prCmd->ucNum = 0; -+ for (i = 0; i < MAX_CMD_SUPPORT_CHANNEL_NUM; i++) { -+ -+ if (prChPwrLimit->ucCentralCh != ENDCH) { -+ -+ /*Check Power limit table channel efficient or not */ -+ fgChannelValid = rlmDomainCheckChannelEntryValid(prAdapter, prChPwrLimit->ucCentralCh); -+ -+ /*Cmd set up */ -+ if (fgChannelValid) { -+ kalMemCopy(prCmdPwrLimit, prChPwrLimit, sizeof(CMD_CHANNEL_POWER_LIMIT)); -+ DBGLOG(RLM, INFO, -+ "Domain: ValidCh=%d,Limit=%d,%d,%d,%d,%d,Fg=%d\n", -+ prCmdPwrLimit->ucCentralCh, prCmdPwrLimit->cPwrLimitCCK, -+ prCmdPwrLimit->cPwrLimit20, prCmdPwrLimit->cPwrLimit40, -+ prCmdPwrLimit->cPwrLimit80, prCmdPwrLimit->cPwrLimit160, -+ prCmdPwrLimit->ucFlag); -+ prCmd->ucNum++; -+ prCmdPwrLimit++; -+ } else { -+ DBGLOG(RLM, INFO, -+ "Domain: Non-Ch=%d,Limit=%d,%d,%d,%d,%d,Fg=%d\n", -+ prChPwrLimit->ucCentralCh, prChPwrLimit->cPwrLimitCCK, -+ prChPwrLimit->cPwrLimit20, prChPwrLimit->cPwrLimit40, -+ prChPwrLimit->cPwrLimit80, prChPwrLimit->cPwrLimit160, -+ prChPwrLimit->ucFlag); -+ } -+ prChPwrLimit++; -+ } else { -+ /*End of the chanel entry */ -+ break; -+ } -+ }; -+ } -+#endif -+ -+ if (prCmd->u2CountryCode != 0) { -+ DBGLOG(RLM, INFO, -+ "Domain: ValidCC =%c%c, ChNum=%d\n", ((prCmd->u2CountryCode & 0xff00) >> 8), -+ (prCmd->u2CountryCode & 0x00ff), prCmd->ucNum); -+ } else { -+ DBGLOG(RLM, INFO, "Domain: ValidCC =0x%04x, ucNum=%d\n", prCmd->u2CountryCode, prCmd->ucNum); -+ } -+ prCmdPwrLimit = &prCmd->rChannelPowerLimit[0]; -+ -+ for (i = 0; i < prCmd->ucNum; i++) { -+ DBGLOG(RLM, TRACE, "Domain: Ch=%d,Limit=%d,%d,%d,%d,%d,Fg=%d\n", prCmdPwrLimit->ucCentralCh, -+ prCmdPwrLimit->cPwrLimitCCK, prCmdPwrLimit->cPwrLimit20, prCmdPwrLimit->cPwrLimit40, -+ prCmdPwrLimit->cPwrLimit80, prCmdPwrLimit->cPwrLimit160, prCmdPwrLimit->ucFlag); -+ prCmdPwrLimit++; -+ } -+ -+ u4SetQueryInfoLen = -+ (sizeof(CMD_SET_COUNTRY_CHANNEL_POWER_LIMIT_T) + (prCmd->ucNum) * sizeof(CMD_CHANNEL_POWER_LIMIT)); -+ -+ /* Update domain info to chip */ -+ if (prCmd->ucNum <= MAX_CMD_SUPPORT_CHANNEL_NUM) { -+ wlanSendSetQueryCmd(prAdapter, /* prAdapter */ -+ CMD_ID_SET_COUNTRY_POWER_LIMIT, /* ucCID */ -+ TRUE, /* fgSetQuery */ -+ FALSE, /* fgNeedResp */ -+ FALSE, /* fgIsOid */ -+ NULL, /* pfCmdDoneHandler */ -+ NULL, /* pfCmdTimeoutHandler */ -+ u4SetQueryInfoLen, /* u4SetQueryInfoLen */ -+ (PUINT_8) prCmd, /* pucInfoBuffer */ -+ NULL, /* pvSetQueryBuffer */ -+ 0 /* u4SetQueryBufferLen */ -+ ); -+ } else -+ DBGLOG(RLM, ERROR, "Domain: illegal power limit table"); -+ -+ cnmMemFree(prAdapter, prCmd); -+ -+} -+#endif -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rlm_obss.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rlm_obss.c -new file mode 100644 -index 000000000000..8450124a3f38 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rlm_obss.c -@@ -0,0 +1,436 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/rlm_obss.c#2 -+*/ -+ -+/*! \file "rlm_obss.c" -+ \brief -+ -+*/ -+ -+/* -+** Log: rlm_obss.c -+ * -+ * 07 17 2012 yuche.tsai -+ * NULL -+ * Compile no error before trial run. -+ * -+ * 11 15 2011 cm.chang -+ * NULL -+ * Avoid possible OBSS scan when BSS is switched -+ * -+ * 11 08 2011 cm.chang -+ * NULL -+ * Add RLM and CNM debug message for XLOG -+ * -+ * 10 25 2011 cm.chang -+ * [WCXRP00001058] [All Wi-Fi][Driver] Fix sta_rec's phyTypeSet and OBSS scan in AP mode -+ * Regulation class is changed to 81 in 20_40_coexistence action frame -+ * -+ * 04 12 2011 cm.chang -+ * [WCXRP00000634] [MT6620 Wi-Fi][Driver][FW] 2nd BSS will not support 40MHz bandwidth for concurrency -+ * . -+ * -+ * 03 29 2011 cm.chang -+ * [WCXRP00000606] [MT6620 Wi-Fi][Driver][FW] Fix klocwork warning -+ * As CR title -+ * -+ * 01 24 2011 cm.chang -+ * [WCXRP00000384] [MT6620 Wi-Fi][Driver][FW] Handle 20/40 action frame -+ * in AP mode and stop ampdu timer when sta_rec is freed -+ * Process received 20/40 coexistence action frame for AP mode -+ * -+ * 01 13 2011 cm.chang -+ * [WCXRP00000358] [MT6620 Wi-Fi][Driver] Provide concurrent information for each module -+ * Refine function when rcv a 20/40M public action frame -+ * -+ * 01 13 2011 cm.chang -+ * [WCXRP00000354] [MT6620 Wi-Fi][Driver][FW] Follow NVRAM bandwidth setting -+ * Use SCO of BSS_INFO to replace user-defined setting variables -+ * -+ * 01 12 2011 cm.chang -+ * [WCXRP00000354] [MT6620 Wi-Fi][Driver][FW] Follow NVRAM bandwidth setting -+ * User-defined bandwidth is for 2.4G and 5G individually -+ * -+ * 10 18 2010 cp.wu -+ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning -+ * use definition macro to replace hard-coded constant -+ * -+ * 09 16 2010 cm.chang -+ * NULL -+ * Change conditional compiling options for BOW -+ * -+ * 09 10 2010 cm.chang -+ * NULL -+ * Always update Beacon content if FW sync OBSS info -+ * -+ * 08 24 2010 cm.chang -+ * NULL -+ * Support RLM initail channel of Ad-hoc, P2P and BOW -+ * -+ * 08 20 2010 cm.chang -+ * NULL -+ * Migrate RLM code to host from FW -+ * -+ * 07 26 2010 yuche.tsai -+ * -+ * Fix compile error while enabling WiFi Direct function. -+ * -+ * 07 21 2010 yuche.tsai -+ * -+ * Add P2P Scan & Scan Result Parsing & Saving. -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 07 08 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Check draft RLM code for HT cap -+ * -+ * 05 07 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Process 20/40 coexistence public action frame in AP mode -+ * -+ * 05 05 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * First draft support for 20/40M bandwidth for AP mode -+ * -+ * 04 24 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * g_aprBssInfo[] depends on CFG_SUPPORT_P2P and CFG_SUPPORT_BOW -+ * -+ * 04 13 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Add more ASSERT to check exception -+ * -+ * 04 07 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Add virtual test for OBSS scan -+ * -+ * 03 30 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Support 2.4G OBSS scan -+ * -+ * 03 03 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * To support CFG_SUPPORT_BCM_STP -+ * -+ * 02 13 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Support PCO in STA mode -+ * -+ * 02 12 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Use bss info array for concurrent handle -+ * -+ * 02 05 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Add AAA Module Support, Revise Net Type to Net Type Index for array lookup -+ * -+ * 01 25 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Support protection and bandwidth switch -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "precomp.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+static VOID rlmObssScanTimeout(P_ADAPTER_T prAdapter, ULONG ulData); -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rlmObssInit(P_ADAPTER_T prAdapter) -+{ -+ P_BSS_INFO_T prBssInfo; -+ UINT_8 ucNetIdx; -+ -+ RLM_NET_FOR_EACH(ucNetIdx) { -+ prBssInfo = &prAdapter->rWifiVar.arBssInfo[ucNetIdx]; -+ ASSERT(prBssInfo); -+ -+ cnmTimerInitTimer(prAdapter, &prBssInfo->rObssScanTimer, rlmObssScanTimeout, (ULONG) prBssInfo); -+ } /* end of RLM_NET_FOR_EACH */ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN rlmObssUpdateChnlLists(P_ADAPTER_T prAdapter, P_SW_RFB_T prSwRfb) -+{ -+ return TRUE; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rlmObssScanDone(P_ADAPTER_T prAdapter, P_MSG_HDR_T prMsgHdr) -+{ -+ P_MSG_SCN_SCAN_DONE prScanDoneMsg; -+ P_BSS_INFO_T prBssInfo; -+ P_MSDU_INFO_T prMsduInfo; -+ P_ACTION_20_40_COEXIST_FRAME prTxFrame; -+ UINT_16 i, u2PayloadLen; -+ -+ ASSERT(prMsgHdr); -+ -+ prScanDoneMsg = (P_MSG_SCN_SCAN_DONE) prMsgHdr; -+ prBssInfo = &prAdapter->rWifiVar.arBssInfo[prScanDoneMsg->ucNetTypeIndex]; -+ ASSERT(prBssInfo); -+ -+ DBGLOG(RLM, INFO, "OBSS Scan Done (NetIdx=%d, Mode=%d)\n", -+ prScanDoneMsg->ucNetTypeIndex, prBssInfo->eCurrentOPMode); -+ -+ cnmMemFree(prAdapter, prMsgHdr); -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ /* AP mode */ -+ if ((prAdapter->fgIsP2PRegistered) && -+ (IS_NET_ACTIVE(prAdapter, prBssInfo->ucNetTypeIndex)) && -+ (prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT)) { -+ return; -+ } -+#endif -+ -+ /* STA mode */ -+ if (prBssInfo->eCurrentOPMode != OP_MODE_INFRASTRUCTURE || -+ !RLM_NET_PARAM_VALID(prBssInfo) || prBssInfo->u2ObssScanInterval == 0) { -+ DBGLOG(RLM, WARN, "OBSS Scan Done (NetIdx=%d) -- Aborted!!\n", prBssInfo->ucNetTypeIndex); -+ return; -+ } -+ -+ /* To do: check 2.4G channel list to decide if obss mgmt should be -+ * sent to associated AP. Note: how to handle concurrent network? -+ * To do: invoke rlmObssChnlLevel() to decide if 20/40 BSS coexistence -+ * management frame is needed. -+ */ -+ prMsduInfo = (P_MSDU_INFO_T) cnmMgtPktAlloc(prAdapter, MAC_TX_RESERVED_FIELD + PUBLIC_ACTION_MAX_LEN); -+ if ((prBssInfo->auc2G_20mReqChnlList[0] > 0 || prBssInfo->auc2G_NonHtChnlList[0] > 0) && prMsduInfo != NULL) { -+ DBGLOG(RLM, INFO, "Send 20/40 coexistence mgmt(20mReq=%d, NonHt=%d)\n", -+ prBssInfo->auc2G_20mReqChnlList[0], prBssInfo->auc2G_NonHtChnlList[0]); -+ -+ prTxFrame = (P_ACTION_20_40_COEXIST_FRAME) -+ ((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD); -+ -+ prTxFrame->u2FrameCtrl = MAC_FRAME_ACTION; -+ COPY_MAC_ADDR(prTxFrame->aucDestAddr, prBssInfo->aucBSSID); -+ COPY_MAC_ADDR(prTxFrame->aucSrcAddr, prBssInfo->aucOwnMacAddr); -+ COPY_MAC_ADDR(prTxFrame->aucBSSID, prBssInfo->aucBSSID); -+ -+ prTxFrame->ucCategory = CATEGORY_PUBLIC_ACTION; -+ prTxFrame->ucAction = ACTION_PUBLIC_20_40_COEXIST; -+ -+ /* To do: find correct algorithm */ -+ prTxFrame->rBssCoexist.ucId = ELEM_ID_20_40_BSS_COEXISTENCE; -+ prTxFrame->rBssCoexist.ucLength = 1; -+ prTxFrame->rBssCoexist.ucData = (prBssInfo->auc2G_20mReqChnlList[0] > 0) ? BSS_COEXIST_20M_REQ : 0; -+ -+ u2PayloadLen = 2 + 3; -+ -+ if (prBssInfo->auc2G_NonHtChnlList[0] > 0) { -+ ASSERT(prBssInfo->auc2G_NonHtChnlList[0] <= CHNL_LIST_SZ_2G); -+ -+ prTxFrame->rChnlReport.ucId = ELEM_ID_20_40_INTOLERANT_CHNL_REPORT; -+ prTxFrame->rChnlReport.ucLength = prBssInfo->auc2G_NonHtChnlList[0] + 1; -+ prTxFrame->rChnlReport.ucRegulatoryClass = 81; /* 2.4GHz, ch1~13 */ -+ for (i = 0; i < prBssInfo->auc2G_NonHtChnlList[0] && i < CHNL_LIST_SZ_2G; i++) -+ prTxFrame->rChnlReport.aucChannelList[i] = prBssInfo->auc2G_NonHtChnlList[i + 1]; -+ -+ u2PayloadLen += IE_SIZE(&prTxFrame->rChnlReport); -+ } -+ ASSERT((WLAN_MAC_HEADER_LEN + u2PayloadLen) <= PUBLIC_ACTION_MAX_LEN); -+ -+ /* Clear up channel lists in 2.4G band */ -+ prBssInfo->auc2G_20mReqChnlList[0] = 0; -+ prBssInfo->auc2G_NonHtChnlList[0] = 0; -+ -+ /* 4 Update information of MSDU_INFO_T */ -+ prMsduInfo->ucPacketType = HIF_TX_PACKET_TYPE_MGMT; /* Management frame */ -+ prMsduInfo->ucStaRecIndex = prBssInfo->prStaRecOfAP->ucIndex; -+ prMsduInfo->ucNetworkType = prBssInfo->ucNetTypeIndex; -+ prMsduInfo->ucMacHeaderLength = WLAN_MAC_MGMT_HEADER_LEN; -+ prMsduInfo->fgIs802_1x = FALSE; -+ prMsduInfo->fgIs802_11 = TRUE; -+ prMsduInfo->u2FrameLength = WLAN_MAC_MGMT_HEADER_LEN + u2PayloadLen; -+ prMsduInfo->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter); -+ prMsduInfo->pfTxDoneHandler = NULL; -+ prMsduInfo->fgIsBasicRate = FALSE; -+ -+ /* 4 Enqueue the frame to send this action frame. */ -+ nicTxEnqueueMsdu(prAdapter, prMsduInfo); -+ } -+ /* end of prMsduInfo != NULL */ -+ if (prBssInfo->u2ObssScanInterval > 0) { -+ DBGLOG(RLM, INFO, "Set OBSS timer (NetIdx=%d, %d sec)\n", -+ prBssInfo->ucNetTypeIndex, prBssInfo->u2ObssScanInterval); -+ -+ cnmTimerStartTimer(prAdapter, &prBssInfo->rObssScanTimer, prBssInfo->u2ObssScanInterval * MSEC_PER_SEC); -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+static VOID rlmObssScanTimeout(P_ADAPTER_T prAdapter, ULONG ulData) -+{ -+ P_BSS_INFO_T prBssInfo; -+ -+ prBssInfo = (P_BSS_INFO_T) ulData; -+ ASSERT(prBssInfo); -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ if (prAdapter->fgIsP2PRegistered && (IS_NET_ACTIVE(prAdapter, prBssInfo->ucNetTypeIndex))) { -+ -+ /* AP mode */ -+ if (prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT) { -+ -+ prBssInfo->fgObssActionForcedTo20M = FALSE; -+ -+ /* Check if Beacon content need to be updated */ -+ rlmUpdateParamsForAP(prAdapter, prBssInfo, FALSE); -+ -+ return; -+ } -+#if CFG_SUPPORT_WFD -+ /* WFD streaming */ -+ else { -+ P_WFD_CFG_SETTINGS_T prWfdCfgSettings = -+ &prAdapter->rWifiVar.prP2pFsmInfo->rWfdConfigureSettings; -+ P_BSS_INFO_T prP2pBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]; -+ -+ /* If WFD is enabled & connected */ -+ if (prWfdCfgSettings->ucWfdEnable && -+ (prWfdCfgSettings->u4WfdFlag & BIT(0)) && RLM_NET_PARAM_VALID(prP2pBssInfo)) { -+ -+ /* Skip OBSS scan */ -+ prBssInfo->u2ObssScanInterval = 0; -+ -+ DBGLOG(RLM, INFO, "WFD is running. Stop net[%u] OBSS scan.\n", -+ (UINT_32) prBssInfo->ucNetTypeIndex); -+ -+ return; -+ } -+ } -+#endif -+ } -+#endif /* end of CFG_ENABLE_WIFI_DIRECT */ -+ -+ /* STA mode */ -+ if (prBssInfo->eCurrentOPMode != OP_MODE_INFRASTRUCTURE || -+ !RLM_NET_PARAM_VALID(prBssInfo) || prBssInfo->u2ObssScanInterval == 0) { -+ DBGLOG(RLM, WARN, "OBSS Scan timeout (NetIdx=%d) -- Aborted!!\n", prBssInfo->ucNetTypeIndex); -+ return; -+ } -+ -+ rlmObssTriggerScan(prAdapter, prBssInfo); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rlmObssTriggerScan(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo) -+{ -+ P_MSG_SCN_SCAN_REQ prScanReqMsg; -+ -+ ASSERT(prBssInfo); -+ -+ prScanReqMsg = (P_MSG_SCN_SCAN_REQ) -+ cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_SCN_SCAN_REQ)); -+ ASSERT(prScanReqMsg); -+ -+ if (!prScanReqMsg) { -+ DBGLOG(RLM, WARN, "No buf for OBSS scan (NetIdx=%d)!!\n", prBssInfo->ucNetTypeIndex); -+ -+ cnmTimerStartTimer(prAdapter, &prBssInfo->rObssScanTimer, prBssInfo->u2ObssScanInterval * MSEC_PER_SEC); -+ return; -+ } -+ -+ /* It is ok that ucSeqNum is set to fixed value because the same network -+ * OBSS scan interval is limited to OBSS_SCAN_MIN_INTERVAL (min 10 sec) -+ * and scan module don't care seqNum of OBSS scanning -+ */ -+ prScanReqMsg->rMsgHdr.eMsgId = MID_RLM_SCN_SCAN_REQ; -+ prScanReqMsg->ucSeqNum = 0x33; -+ prScanReqMsg->ucNetTypeIndex = prBssInfo->ucNetTypeIndex; -+ prScanReqMsg->eScanType = SCAN_TYPE_ACTIVE_SCAN; -+ prScanReqMsg->ucSSIDType = SCAN_REQ_SSID_WILDCARD; -+ prScanReqMsg->ucSSIDLength = 0; -+ prScanReqMsg->eScanChannel = SCAN_CHANNEL_2G4; -+ prScanReqMsg->u2IELen = 0; -+ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prScanReqMsg, MSG_SEND_METHOD_BUF); -+ -+ DBGLOG(RLM, INFO, "Timeout to trigger OBSS scan (NetIdx=%d)!!\n", prBssInfo->ucNetTypeIndex); -+} -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rlm_protection.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rlm_protection.c -new file mode 100644 -index 000000000000..d3c513397095 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rlm_protection.c -@@ -0,0 +1,105 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/rlm_protection.c#1 -+*/ -+ -+/*! \file "rlm_protection.c" -+ \brief -+ -+*/ -+ -+/* -+** Log: rlm_protection.c -+ * -+ * 08 20 2010 cm.chang -+ * NULL -+ * Migrate RLM code to host from FW -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 07 08 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Check draft RLM code for HT cap -+ * -+ * 05 28 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Set RTS threshold of 2K bytes initially -+ * -+ * 04 24 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * g_aprBssInfo[] depends on CFG_SUPPORT_P2P and CFG_SUPPORT_BOW -+ * -+ * 04 22 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * First draft code to support protection in AP mode -+ * -+ * 03 31 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Enable RTS threshold temporarily for AMPDU -+ * -+ * 03 16 2010 kevin.huang -+ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support -+ * Add AdHoc Mode -+ * -+ * 03 03 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * To support CFG_SUPPORT_BCM_STP -+ * -+ * 02 13 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Support PCO in STA mode -+ * -+ * 02 12 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Use bss info array for concurrent handle -+ * -+ * 01 25 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Support protection and bandwidth switch -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/roaming_fsm.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/roaming_fsm.c -new file mode 100644 -index 000000000000..3f088c283993 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/roaming_fsm.c -@@ -0,0 +1,539 @@ -+/* -+** Id: -+*/ -+ -+/*! \file "roaming_fsm.c" -+ \brief This file defines the FSM for Roaming MODULE. -+ -+ This file defines the FSM for Roaming MODULE. -+*/ -+ -+/* -+** Log: roaming_fsm.c -+ * -+ * 11 24 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * Adjust code for DBG and CONFIG_XLOG. -+ * -+ * 11 11 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * modify the xlog related code. -+ * -+ * 11 02 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * adding the code for XLOG. -+ * -+ * 08 31 2011 tsaiyuan.hsu -+ * [WCXRP00000931] [MT5931 Wi-Fi][DRV/FW] add swcr to disable roaming from driver -+ * remove obsolete code. -+ * -+ * 08 15 2011 tsaiyuan.hsu -+ * [WCXRP00000931] [MT5931 Wi-Fi][DRV/FW] add swcr to disable roaming from driver -+ * add swcr in driver reg, 0x9fxx0000, to disable roaming . -+ * -+ * 03 16 2011 tsaiyuan.hsu -+ * [WCXRP00000517] [MT6620 Wi-Fi][Driver][FW] Fine Tune Performance of Roaming -+ * remove obsolete definition and unused variables. -+ * -+ * 02 26 2011 tsaiyuan.hsu -+ * [WCXRP00000391] [MT6620 Wi-Fi][FW] Add Roaming Support -+ * not send disassoc or deauth to leaving AP so as to improve performace of roaming. -+ * -+ * 01 27 2011 tsaiyuan.hsu -+ * [WCXRP00000392] [MT6620 Wi-Fi][Driver] Add Roaming Support -+ * add roaming fsm -+ * 1. not support 11r, only use strength of signal to determine roaming. -+ * 2. not enable CFG_SUPPORT_ROAMING until completion of full test. -+ * 3. in 6620, adopt work-around to avoid sign extension problem of cck of hw -+ * 4. assume that change of link quality in smooth way. -+ * -+ * 01 27 2011 tsaiyuan.hsu -+ * [WCXRP00000392] [MT6620 Wi-Fi][Driver] Add Roaming Support -+ * add roaming fsm -+ * 1. not support 11r, only use strength of signal to determine roaming. -+ * 2. not enable CFG_SUPPORT_ROAMING until completion of full test. -+ * 3. in 6620, adopt work-around to avoid sign extension problem of cck of hw -+ * 4. assume that change of link quality in smooth way. -+ * -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "precomp.h" -+ -+#if CFG_SUPPORT_ROAMING -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+#if DBG -+/*lint -save -e64 Type mismatch */ -+static PUINT_8 apucDebugRoamingState[ROAMING_STATE_NUM] = { -+ (PUINT_8) DISP_STRING("ROAMING_STATE_IDLE"), -+ (PUINT_8) DISP_STRING("ROAMING_STATE_DECISION"), -+ (PUINT_8) DISP_STRING("ROAMING_STATE_DISCOVERY"), -+ (PUINT_8) DISP_STRING("ROAMING_STATE_ROAM") -+}; -+ -+/*lint -restore */ -+#endif /* DBG */ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+/* -+#define ROAMING_ENABLE_CHECK(_roam) \ -+{ \ -+ if (!(_roam->fgIsEnableRoaming)) \ -+ return; \ -+} -+*/ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Initialize the value in ROAMING_FSM_INFO_T for ROAMING FSM operation -+* -+* @param [IN P_ADAPTER_T] prAdapter -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID roamingFsmInit(IN P_ADAPTER_T prAdapter) -+{ -+ P_ROAMING_INFO_T prRoamingFsmInfo; -+ P_CONNECTION_SETTINGS_T prConnSettings; -+ -+ DBGLOG(ROAMING, LOUD, "->roamingFsmInit(): Current Time = %u\n", kalGetTimeTick()); -+ -+ prRoamingFsmInfo = (P_ROAMING_INFO_T) &(prAdapter->rWifiVar.rRoamingInfo); -+ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); -+ -+ /* 4 <1> Initiate FSM */ -+ prRoamingFsmInfo->fgIsEnableRoaming = prConnSettings->fgIsEnableRoaming; -+ prRoamingFsmInfo->eCurrentState = ROAMING_STATE_IDLE; -+ prRoamingFsmInfo->rRoamingDiscoveryUpdateTime = 0; -+ -+} /* end of roamingFsmInit() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Uninitialize the value in AIS_FSM_INFO_T for AIS FSM operation -+* -+* @param [IN P_ADAPTER_T] prAdapter -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID roamingFsmUninit(IN P_ADAPTER_T prAdapter) -+{ -+ P_ROAMING_INFO_T prRoamingFsmInfo; -+ -+ DBGLOG(ROAMING, LOUD, "->roamingFsmUninit(): Current Time = %u\n", kalGetTimeTick()); -+ -+ prRoamingFsmInfo = (P_ROAMING_INFO_T) &(prAdapter->rWifiVar.rRoamingInfo); -+ -+ prRoamingFsmInfo->eCurrentState = ROAMING_STATE_IDLE; -+ -+} /* end of roamingFsmUninit() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Send commands to firmware -+* -+* @param [IN P_ADAPTER_T] prAdapter -+* [IN P_ROAMING_PARAM_T] prParam -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID roamingFsmSendCmd(IN P_ADAPTER_T prAdapter, IN P_ROAMING_PARAM_T prParam) -+{ -+ P_ROAMING_INFO_T prRoamingFsmInfo; -+ WLAN_STATUS rStatus; -+ -+ DBGLOG(ROAMING, LOUD, "->roamingFsmSendCmd(): Current Time = %u\n", kalGetTimeTick()); -+ -+ prRoamingFsmInfo = (P_ROAMING_INFO_T) &(prAdapter->rWifiVar.rRoamingInfo); -+ -+ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ -+ CMD_ID_ROAMING_TRANSIT, /* ucCID */ -+ TRUE, /* fgSetQuery */ -+ FALSE, /* fgNeedResp */ -+ FALSE, /* fgIsOid */ -+ NULL, /* pfCmdDoneHandler */ -+ NULL, /* pfCmdTimeoutHandler */ -+ sizeof(ROAMING_PARAM_T), /* u4SetQueryInfoLen */ -+ (PUINT_8) prParam, /* pucInfoBuffer */ -+ NULL, /* pvSetQueryBuffer */ -+ 0 /* u4SetQueryBufferLen */ -+ ); -+ -+ ASSERT(rStatus == WLAN_STATUS_PENDING); -+ -+} /* end of roamingFsmSendCmd() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Update the recent time when ScanDone occurred -+* -+* @param [IN P_ADAPTER_T] prAdapter -+* -+* @return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID roamingFsmScanResultsUpdate(IN P_ADAPTER_T prAdapter) -+{ -+ P_ROAMING_INFO_T prRoamingFsmInfo; -+ -+ prRoamingFsmInfo = (P_ROAMING_INFO_T) &(prAdapter->rWifiVar.rRoamingInfo); -+ -+ /* Check Roaming Conditions */ -+ if (!(prRoamingFsmInfo->fgIsEnableRoaming)) -+ return; -+ -+ DBGLOG(ROAMING, LOUD, "->roamingFsmScanResultsUpdate(): Current Time = %u", kalGetTimeTick()); -+ -+ GET_CURRENT_SYSTIME(&prRoamingFsmInfo->rRoamingDiscoveryUpdateTime); -+ -+} /* end of roamingFsmScanResultsUpdate() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief The Core FSM engine of ROAMING for AIS Infra. -+* -+* @param [IN P_ADAPTER_T] prAdapter -+* [IN ENUM_ROAMING_STATE_T] eNextState Enum value of next AIS STATE -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID roamingFsmSteps(IN P_ADAPTER_T prAdapter, IN ENUM_ROAMING_STATE_T eNextState) -+{ -+ P_ROAMING_INFO_T prRoamingFsmInfo; -+ ENUM_ROAMING_STATE_T ePreviousState; -+ BOOLEAN fgIsTransition = (BOOLEAN) FALSE; -+ -+ prRoamingFsmInfo = (P_ROAMING_INFO_T) &(prAdapter->rWifiVar.rRoamingInfo); -+ -+ do { -+ -+ /* Do entering Next State */ -+#if DBG -+ DBGLOG(ROAMING, STATE, "TRANSITION: [%s] -> [%s]\n", -+ apucDebugRoamingState[prRoamingFsmInfo->eCurrentState], -+ apucDebugRoamingState[eNextState]); -+#else -+ DBGLOG(ROAMING, STATE, "[%d] TRANSITION: [%d] -> [%d]\n", -+ DBG_ROAMING_IDX, prRoamingFsmInfo->eCurrentState, eNextState); -+#endif -+ /* NOTE(Kevin): This is the only place to change the eCurrentState(except initial) */ -+ ePreviousState = prRoamingFsmInfo->eCurrentState; -+ prRoamingFsmInfo->eCurrentState = eNextState; -+ -+ fgIsTransition = (BOOLEAN) FALSE; -+ -+ /* Do tasks of the State that we just entered */ -+ switch (prRoamingFsmInfo->eCurrentState) { -+ /* NOTE(Kevin): we don't have to rearrange the sequence of following -+ * switch case. Instead I would like to use a common lookup table of array -+ * of function pointer to speed up state search. -+ */ -+ case ROAMING_STATE_IDLE: -+ case ROAMING_STATE_DECISION: -+ break; -+ -+ case ROAMING_STATE_DISCOVERY: -+ { -+ OS_SYSTIME rCurrentTime; -+ -+ GET_CURRENT_SYSTIME(&rCurrentTime); -+ if (CHECK_FOR_TIMEOUT(rCurrentTime, prRoamingFsmInfo->rRoamingDiscoveryUpdateTime, -+ SEC_TO_SYSTIME(ROAMING_DISCOVERY_TIMEOUT_SEC))) { -+ DBGLOG(ROAMING, LOUD, "roamingFsmSteps: DiscoveryUpdateTime Timeout"); -+ aisFsmRunEventRoamingDiscovery(prAdapter, TRUE); -+ } else { -+ DBGLOG(ROAMING, LOUD, "roamingFsmSteps: DiscoveryUpdateTime Updated"); -+#if CFG_SUPPORT_ROAMING_ENC -+ if (prAdapter->fgIsRoamingEncEnabled == TRUE) -+ aisFsmRunEventRoamingDiscovery(prAdapter, TRUE); -+ else -+#endif /* CFG_SUPPORT_ROAMING_ENC */ -+ aisFsmRunEventRoamingDiscovery(prAdapter, FALSE); -+ } -+ } -+ break; -+ -+ case ROAMING_STATE_ROAM: -+ break; -+ -+ default: -+ ASSERT(0); /* Make sure we have handle all STATEs */ -+ } -+ } while (fgIsTransition); -+ -+ return; -+ -+} /* end of roamingFsmSteps() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Transit to Decision state after join completion -+* -+* @param [IN P_ADAPTER_T] prAdapter -+* -+* @return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID roamingFsmRunEventStart(IN P_ADAPTER_T prAdapter) -+{ -+ P_ROAMING_INFO_T prRoamingFsmInfo; -+ ENUM_ROAMING_STATE_T eNextState; -+ P_BSS_INFO_T prAisBssInfo; -+ ROAMING_PARAM_T rParam; -+ -+ prRoamingFsmInfo = (P_ROAMING_INFO_T) &(prAdapter->rWifiVar.rRoamingInfo); -+ -+ /* Check Roaming Conditions */ -+ if (!(prRoamingFsmInfo->fgIsEnableRoaming)) -+ return; -+ -+ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ if (prAisBssInfo->eCurrentOPMode != OP_MODE_INFRASTRUCTURE) -+ return; -+ -+ DBGLOG(ROAMING, EVENT, "EVENT-ROAMING START: Current Time = %u\n", kalGetTimeTick()); -+ -+ /* IDLE, ROAM -> DECISION */ -+ /* Errors as DECISION, DISCOVERY -> DECISION */ -+ if (!(prRoamingFsmInfo->eCurrentState == ROAMING_STATE_IDLE || -+ prRoamingFsmInfo->eCurrentState == ROAMING_STATE_ROAM)) -+ return; -+ -+ eNextState = ROAMING_STATE_DECISION; -+ if (eNextState != prRoamingFsmInfo->eCurrentState) { -+ rParam.u2Event = ROAMING_EVENT_START; -+ roamingFsmSendCmd(prAdapter, (P_ROAMING_PARAM_T) & rParam); -+ -+ /* Step to next state */ -+ roamingFsmSteps(prAdapter, eNextState); -+ } -+ -+} /* end of roamingFsmRunEventStart() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Transit to Discovery state when deciding to find a candidate -+* -+* @param [IN P_ADAPTER_T] prAdapter -+* -+* @return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID roamingFsmRunEventDiscovery(IN P_ADAPTER_T prAdapter, IN P_ROAMING_PARAM_T prParam) -+{ -+ P_ROAMING_INFO_T prRoamingFsmInfo; -+ ENUM_ROAMING_STATE_T eNextState; -+ -+ prRoamingFsmInfo = (P_ROAMING_INFO_T) &(prAdapter->rWifiVar.rRoamingInfo); -+ -+ /* Check Roaming Conditions */ -+ if (!(prRoamingFsmInfo->fgIsEnableRoaming)) -+ return; -+ -+ DBGLOG(ROAMING, EVENT, "EVENT-ROAMING DISCOVERY: Current Time = %u Reason = %u\n", -+ kalGetTimeTick(), prParam->u2Reason); -+ -+ /* DECISION -> DISCOVERY */ -+ /* Errors as IDLE, DISCOVERY, ROAM -> DISCOVERY */ -+ if (prRoamingFsmInfo->eCurrentState != ROAMING_STATE_DECISION) -+ return; -+#if CFG_SUPPORT_ROAMING_ENC -+ prRoamingFsmInfo->RoamingEntryTimeoutSkipCount = 0; -+#endif -+ -+ eNextState = ROAMING_STATE_DISCOVERY; -+ /* DECISION -> DISCOVERY */ -+ if (eNextState != prRoamingFsmInfo->eCurrentState) { -+ P_BSS_INFO_T prAisBssInfo; -+ P_BSS_DESC_T prBssDesc; -+ -+ /* sync. rcpi with firmware */ -+ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ prBssDesc = scanSearchBssDescByBssid(prAdapter, prAisBssInfo->aucBSSID); -+ if (prBssDesc) -+ prBssDesc->ucRCPI = (UINT_8) (prParam->u2Data & 0xff); -+ -+ roamingFsmSteps(prAdapter, eNextState); -+ } -+ -+} /* end of roamingFsmRunEventDiscovery() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Transit to Roam state after Scan Done -+* -+* @param [IN P_ADAPTER_T] prAdapter -+* -+* @return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID roamingFsmRunEventRoam(IN P_ADAPTER_T prAdapter) -+{ -+ P_ROAMING_INFO_T prRoamingFsmInfo; -+ ENUM_ROAMING_STATE_T eNextState; -+ ROAMING_PARAM_T rParam; -+ -+ prRoamingFsmInfo = (P_ROAMING_INFO_T) &(prAdapter->rWifiVar.rRoamingInfo); -+ -+ /* Check Roaming Conditions */ -+ if (!(prRoamingFsmInfo->fgIsEnableRoaming)) -+ return; -+ -+ DBGLOG(ROAMING, EVENT, "EVENT-ROAMING ROAM: Current Time = %u\n", kalGetTimeTick()); -+ -+ /* IDLE, ROAM -> DECISION */ -+ /* Errors as IDLE, DECISION, ROAM -> ROAM */ -+ if (prRoamingFsmInfo->eCurrentState != ROAMING_STATE_DISCOVERY) -+ return; -+ -+ eNextState = ROAMING_STATE_ROAM; -+ /* DISCOVERY -> ROAM */ -+ if (eNextState != prRoamingFsmInfo->eCurrentState) { -+ rParam.u2Event = ROAMING_EVENT_ROAM; -+ roamingFsmSendCmd(prAdapter, (P_ROAMING_PARAM_T) & rParam); -+ -+ /* Step to next state */ -+ roamingFsmSteps(prAdapter, eNextState); -+ } -+ -+} /* end of roamingFsmRunEventRoam() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Transit to Decision state as being failed to find out any candidate -+* -+* @param [IN P_ADAPTER_T] prAdapter -+* -+* @return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID roamingFsmRunEventFail(IN P_ADAPTER_T prAdapter, IN UINT_32 u4Param) -+{ -+ P_ROAMING_INFO_T prRoamingFsmInfo; -+ ENUM_ROAMING_STATE_T eNextState; -+ ROAMING_PARAM_T rParam; -+ -+ prRoamingFsmInfo = (P_ROAMING_INFO_T) &(prAdapter->rWifiVar.rRoamingInfo); -+ -+ /* Check Roaming Conditions */ -+ if (!(prRoamingFsmInfo->fgIsEnableRoaming)) -+ return; -+ -+ DBGLOG(ROAMING, EVENT, "EVENT-ROAMING FAIL: reason %x Current Time = %u\n", u4Param, kalGetTimeTick()); -+ -+ /* IDLE, ROAM -> DECISION */ -+ /* Errors as IDLE, DECISION, DISCOVERY -> DECISION */ -+ if (prRoamingFsmInfo->eCurrentState != ROAMING_STATE_ROAM) -+ return; -+ -+ eNextState = ROAMING_STATE_DECISION; -+ /* ROAM -> DECISION */ -+ if (eNextState != prRoamingFsmInfo->eCurrentState) { -+ rParam.u2Event = ROAMING_EVENT_FAIL; -+ rParam.u2Data = (UINT_16) (u4Param & 0xffff); -+ roamingFsmSendCmd(prAdapter, (P_ROAMING_PARAM_T) & rParam); -+ -+ /* Step to next state */ -+ roamingFsmSteps(prAdapter, eNextState); -+ } -+ -+} /* end of roamingFsmRunEventFail() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Transit to Idle state as beging aborted by other moduels, AIS -+* -+* @param [IN P_ADAPTER_T] prAdapter -+* -+* @return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID roamingFsmRunEventAbort(IN P_ADAPTER_T prAdapter) -+{ -+ P_ROAMING_INFO_T prRoamingFsmInfo; -+ ENUM_ROAMING_STATE_T eNextState; -+ ROAMING_PARAM_T rParam; -+ -+ prRoamingFsmInfo = (P_ROAMING_INFO_T) &(prAdapter->rWifiVar.rRoamingInfo); -+ -+ if (!(prRoamingFsmInfo->fgIsEnableRoaming)) -+ return; -+ -+ DBGLOG(ROAMING, EVENT, "EVENT-ROAMING ABORT: Current Time = %u\n", kalGetTimeTick()); -+ -+ eNextState = ROAMING_STATE_IDLE; -+ /* IDLE, DECISION, DISCOVERY, ROAM -> IDLE */ -+ if (eNextState != prRoamingFsmInfo->eCurrentState) { -+ rParam.u2Event = ROAMING_EVENT_ABORT; -+ roamingFsmSendCmd(prAdapter, (P_ROAMING_PARAM_T) & rParam); -+ -+ /* Step to next state */ -+ roamingFsmSteps(prAdapter, eNextState); -+ } -+ -+} /* end of roamingFsmRunEventAbort() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Process events from firmware -+* -+* @param [IN P_ADAPTER_T] prAdapter -+* [IN P_ROAMING_PARAM_T] prParam -+* -+* @return none -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS roamingFsmProcessEvent(IN P_ADAPTER_T prAdapter, IN P_ROAMING_PARAM_T prParam) -+{ -+ DBGLOG(ROAMING, LOUD, "ROAMING Process Events: Current Time = %u\n", kalGetTimeTick()); -+ -+ if (ROAMING_EVENT_DISCOVERY == prParam->u2Event) -+ roamingFsmRunEventDiscovery(prAdapter, prParam); -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+#endif -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rsn.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rsn.c -new file mode 100644 -index 000000000000..eedd8d12f2fd ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rsn.c -@@ -0,0 +1,2533 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/rsn.c#2 -+*/ -+ -+/*! \file "rsn.c" -+ \brief This file including the 802.11i, wpa and wpa2(rsn) related function. -+ -+ This file provided the macros and functions library support the wpa/rsn ie parsing, -+ cipher and AKM check to help the AP seleced deciding, tkip mic error handler and rsn PMKID support. -+*/ -+ -+/* -+** Log: rsn.c -+ * -+ * 07 17 2012 yuche.tsai -+ * NULL -+ * Compile no error before trial run. -+ * -+ * 03 09 2012 chinglan.wang -+ * NULL -+ * Fix the condition error. -+ * -+ * 03 02 2012 terry.wu -+ * NULL -+ * Snc CFG80211 modification for ICS migration from branch 2.2. -+ * -+ * 03 02 2012 terry.wu -+ * NULL -+ * Sync CFG80211 modification from branch 2,2. -+ * -+ * 11 11 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * modify the xlog related code. -+ * -+ * 11 10 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * change the debug module level. -+ * -+ * 10 12 2011 wh.su -+ * [WCXRP00001036] [MT6620 Wi-Fi][Driver][FW] Adding the 802.11w code for MFP -+ * adding the 802.11w related function and define . -+ * -+ * 03 17 2011 chinglan.wang -+ * [WCXRP00000570] [MT6620 Wi-Fi][Driver] Add Wi-Fi Protected Setup v2.0 feature -+ * . -+ * -+ * 02 09 2011 wh.su -+ * [WCXRP00000432] [MT6620 Wi-Fi][Driver] Add STA privacy check at hotspot mode -+ * adding the code for check STA privacy bit at AP mode, . -+ * -+ * 12 24 2010 chinglan.wang -+ * NULL -+ * [MT6620][Wi-Fi] Modify the key management in the driver for WPS function. -+ * -+ * 12 13 2010 cp.wu -+ * [WCXRP00000260] [MT6620 Wi-Fi][Driver][Firmware] Create V1.1 branch for both firmware and driver -+ * create branch for Wi-Fi driver v1.1 -+ * -+ * 11 05 2010 wh.su -+ * [WCXRP00000165] [MT6620 Wi-Fi] [Pre-authentication] Assoc req rsn ie use wrong pmkid value -+ * fixed the.pmkid value mismatch issue -+ * -+ * 11 03 2010 wh.su -+ * [WCXRP00000124] [MT6620 Wi-Fi] [Driver] Support the dissolve P2P Group -+ * Refine the HT rate disallow TKIP pairwise cipher . -+ * -+ * 10 04 2010 cp.wu -+ * [WCXRP00000077] [MT6620 Wi-Fi][Driver][FW] Eliminate use of ENUM_NETWORK_TYPE_T -+ * and replaced by ENUM_NETWORK_TYPE_INDEX_T only -+ * remove ENUM_NETWORK_TYPE_T definitions -+ * -+ * 09 29 2010 yuche.tsai -+ * NULL -+ * Fix compile error, remove unused pointer in rsnGenerateRSNIE(). -+ * -+ * 09 28 2010 wh.su -+ * NULL -+ * [WCXRP00000069][MT6620 Wi-Fi][Driver] Fix some code for phase 1 P2P Demo. -+ * -+ * 09 24 2010 wh.su -+ * NULL -+ * [WCXRP00005002][MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning. -+ * -+ * 09 06 2010 wh.su -+ * NULL -+ * let the p2p can set the privacy bit at beacon and rsn ie at assoc req at key handshake state. -+ * -+ * 08 30 2010 wh.su -+ * NULL -+ * remove non-used code. -+ * -+ * 08 19 2010 wh.su -+ * NULL -+ * adding the tx pkt call back handle for countermeasure. -+ * -+ * 07 24 2010 wh.su -+ * -+ * .support the Wi-Fi RSN -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 21 2010 wh.su -+ * [WPD00003840][MT6620 5931] Security migration -+ * modify some code for concurrent network. -+ * -+ * 06 21 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * enable RX management frame handling. -+ * -+ * 06 19 2010 wh.su -+ * [WPD00003840][MT6620 5931] Security migration -+ * consdier the concurrent network setting. -+ * -+ * 06 18 2010 wh.su -+ * [WPD00003840][MT6620 5931] Security migration -+ * [WPD00003840] [MT6620 5931] Security migration -+ * migration from firmware. -+ * -+ * 05 27 2010 wh.su -+ * [BORA00000637][MT6620 Wi-Fi] [Bug] WPA2 pre-authentication timer not correctly initialize -+ * not indicate pmkid candidate while no new one scanned. -+ * -+ * 04 29 2010 wh.su -+ * [BORA00000637][MT6620 Wi-Fi] [Bug] WPA2 pre-authentication timer not correctly initialize -+ * adjsut the pre-authentication code. -+ * -+ * 03 03 2010 wh.su -+ * [BORA00000637][MT6620 Wi-Fi] [Bug] WPA2 pre-authentication timer not correctly initialize -+ * move the AIS specific variable for security to AIS specific structure. -+ * -+ * 03 03 2010 wh.su -+ * [BORA00000637][MT6620 Wi-Fi] [Bug] WPA2 pre-authentication timer not correctly initialize -+ * Fixed the pre-authentication timer not correctly init issue, -+ * and modify the security related callback function prototype. -+ * -+ * 01 27 2010 wh.su -+ * [BORA00000476][Wi-Fi][firmware] Add the security module initialize code -+ * add and fixed some security function. -+ * -+ * 12 18 2009 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * . -+ * -+ * Dec 8 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * change the name -+ * -+ * Dec 7 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * using the Rx0 port to indicate event -+ * -+ * Dec 4 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * refine the code for generate the WPA/RSN IE for assoc req -+ * -+ * Dec 3 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * adjust code for pmkid event -+ * -+ * Dec 1 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * adding the code for event (mic error and pmkid indicate) and do some function rename -+ * -+ * Nov 23 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * adding some security function -+ * -+ * Nov 19 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * adding some security feature, including pmkid -+ * -+ * Nov 18 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * -+** -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "precomp.h" -+ -+#if CFG_RSN_MIGRATION -+ -+/* extern PHY_ATTRIBUTE_T rPhyAttributes[]; */ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to parse RSN IE. -+* -+* \param[in] prInfoElem Pointer to the RSN IE -+* \param[out] prRsnInfo Pointer to the BSSDescription structure to store the -+** RSN information from the given RSN IE -+* -+* \retval TRUE - Succeeded -+* \retval FALSE - Failed -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN rsnParseRsnIE(IN P_ADAPTER_T prAdapter, IN P_RSN_INFO_ELEM_T prInfoElem, OUT P_RSN_INFO_T prRsnInfo) -+{ -+ UINT_32 i; -+ INT_32 u4RemainRsnIeLen; -+ UINT_16 u2Version; -+ UINT_16 u2Cap = 0; -+ UINT_32 u4GroupSuite = RSN_CIPHER_SUITE_CCMP; -+ UINT_16 u2PairSuiteCount = 0; -+ UINT_16 u2AuthSuiteCount = 0; -+ PUINT_8 pucPairSuite = NULL; -+ PUINT_8 pucAuthSuite = NULL; -+ PUINT_8 cp; -+ -+ DEBUGFUNC("rsnParseRsnIE"); -+ -+ ASSERT(prInfoElem); -+ ASSERT(prRsnInfo); -+ -+ /* Verify the length of the RSN IE. */ -+ if (prInfoElem->ucLength < 2) { -+ DBGLOG(RSN, TRACE, "RSN IE length too short (length=%d)\n", prInfoElem->ucLength); -+ return FALSE; -+ } -+ -+ /* Check RSN version: currently, we only support version 1. */ -+ WLAN_GET_FIELD_16(&prInfoElem->u2Version, &u2Version); -+ if (u2Version != 1) { -+ DBGLOG(RSN, TRACE, "Unsupported RSN IE version: %d\n", u2Version); -+ return FALSE; -+ } -+ -+ cp = (PUCHAR) & prInfoElem->u4GroupKeyCipherSuite; -+ u4RemainRsnIeLen = (INT_32) prInfoElem->ucLength - 2; -+ -+ do { -+ if (u4RemainRsnIeLen == 0) -+ break; -+ -+ /* Parse the Group Key Cipher Suite field. */ -+ if (u4RemainRsnIeLen < 4) { -+ DBGLOG(RSN, TRACE, "Fail to parse RSN IE in group cipher suite (IE len: %d)\n", -+ prInfoElem->ucLength); -+ return FALSE; -+ } -+ -+ WLAN_GET_FIELD_32(cp, &u4GroupSuite); -+ cp += 4; -+ u4RemainRsnIeLen -= 4; -+ -+ if (u4RemainRsnIeLen == 0) -+ break; -+ -+ /* Parse the Pairwise Key Cipher Suite Count field. */ -+ if (u4RemainRsnIeLen < 2) { -+ DBGLOG(RSN, TRACE, "Fail to parse RSN IE in pairwise cipher suite count (IE len: %d)\n", -+ prInfoElem->ucLength); -+ return FALSE; -+ } -+ -+ WLAN_GET_FIELD_16(cp, &u2PairSuiteCount); -+ cp += 2; -+ u4RemainRsnIeLen -= 2; -+ -+ /* Parse the Pairwise Key Cipher Suite List field. */ -+ i = (UINT_32) u2PairSuiteCount * 4; -+ if (u4RemainRsnIeLen < (INT_32) i) { -+ DBGLOG(RSN, TRACE, "Fail to parse RSN IE in pairwise cipher suite list (IE len: %d)\n", -+ prInfoElem->ucLength); -+ return FALSE; -+ } -+ -+ pucPairSuite = cp; -+ -+ cp += i; -+ u4RemainRsnIeLen -= (INT_32) i; -+ -+ if (u4RemainRsnIeLen == 0) -+ break; -+ -+ /* Parse the Authentication and Key Management Cipher Suite Count field. */ -+ if (u4RemainRsnIeLen < 2) { -+ DBGLOG(RSN, TRACE, "Fail to parse RSN IE in auth & key mgt suite count (IE len: %d)\n", -+ prInfoElem->ucLength); -+ return FALSE; -+ } -+ -+ WLAN_GET_FIELD_16(cp, &u2AuthSuiteCount); -+ cp += 2; -+ u4RemainRsnIeLen -= 2; -+ -+ /* Parse the Authentication and Key Management Cipher Suite List -+ field. */ -+ i = (UINT_32) u2AuthSuiteCount * 4; -+ if (u4RemainRsnIeLen < (INT_32) i) { -+ DBGLOG(RSN, TRACE, "Fail to parse RSN IE in auth & key mgt suite list (IE len: %d)\n", -+ prInfoElem->ucLength); -+ return FALSE; -+ } -+ -+ pucAuthSuite = cp; -+ -+ cp += i; -+ u4RemainRsnIeLen -= (INT_32) i; -+ -+ if (u4RemainRsnIeLen == 0) -+ break; -+ -+ /* Parse the RSN u2Capabilities field. */ -+ if (u4RemainRsnIeLen < 2) { -+ DBGLOG(RSN, TRACE, "Fail to parse RSN IE in RSN capabilities (IE len: %d)\n", -+ prInfoElem->ucLength); -+ return FALSE; -+ } -+ -+ WLAN_GET_FIELD_16(cp, &u2Cap); -+ } while (FALSE); -+ -+ /* Save the RSN information for the BSS. */ -+ prRsnInfo->ucElemId = ELEM_ID_RSN; -+ -+ prRsnInfo->u2Version = u2Version; -+ -+ prRsnInfo->u4GroupKeyCipherSuite = u4GroupSuite; -+ -+ DBGLOG(RSN, LOUD, "RSN: version %d, group key cipher suite %02x-%02x-%02x-%02x\n", -+ u2Version, (UCHAR) (u4GroupSuite & 0x000000FF), -+ (UCHAR) ((u4GroupSuite >> 8) & 0x000000FF), -+ (UCHAR) ((u4GroupSuite >> 16) & 0x000000FF), (UCHAR) ((u4GroupSuite >> 24) & 0x000000FF)); -+ -+ if (pucPairSuite) { -+ /* The information about the pairwise key cipher suites is present. */ -+ if (u2PairSuiteCount > MAX_NUM_SUPPORTED_CIPHER_SUITES) -+ u2PairSuiteCount = MAX_NUM_SUPPORTED_CIPHER_SUITES; -+ -+ prRsnInfo->u4PairwiseKeyCipherSuiteCount = (UINT_32) u2PairSuiteCount; -+ -+ for (i = 0; i < (UINT_32) u2PairSuiteCount; i++) { -+ WLAN_GET_FIELD_32(pucPairSuite, &prRsnInfo->au4PairwiseKeyCipherSuite[i]); -+ pucPairSuite += 4; -+ -+ DBGLOG(RSN, LOUD, "RSN: pairwise key cipher suite [%d]: %02x-%02x-%02x-%02x\n", -+ (UINT_8) i, (UCHAR) (prRsnInfo->au4PairwiseKeyCipherSuite[i] & 0x000000FF), -+ (UCHAR) ((prRsnInfo->au4PairwiseKeyCipherSuite[i] >> 8) & 0x000000FF), -+ (UCHAR) ((prRsnInfo->au4PairwiseKeyCipherSuite[i] >> 16) & 0x000000FF), -+ (UCHAR) ((prRsnInfo->au4PairwiseKeyCipherSuite[i] >> 24) & 0x000000FF)); -+ } -+ } else { -+ /* The information about the pairwise key cipher suites is not present. -+ Use the default chipher suite for RSN: CCMP. */ -+ prRsnInfo->u4PairwiseKeyCipherSuiteCount = 1; -+ prRsnInfo->au4PairwiseKeyCipherSuite[0] = RSN_CIPHER_SUITE_CCMP; -+ -+ DBGLOG(RSN, LOUD, "RSN: pairwise key cipher suite: %02x-%02x-%02x-%02x (default)\n", -+ (UCHAR) (prRsnInfo->au4PairwiseKeyCipherSuite[0] & 0x000000FF), -+ (UCHAR) ((prRsnInfo->au4PairwiseKeyCipherSuite[0] >> 8) & 0x000000FF), -+ (UCHAR) ((prRsnInfo->au4PairwiseKeyCipherSuite[0] >> 16) & 0x000000FF), -+ (UCHAR) ((prRsnInfo->au4PairwiseKeyCipherSuite[0] >> 24) & 0x000000FF)); -+ } -+ -+ if (pucAuthSuite) { -+ /* The information about the authentication and key management suites -+ is present. */ -+ if (u2AuthSuiteCount > MAX_NUM_SUPPORTED_AKM_SUITES) -+ u2AuthSuiteCount = MAX_NUM_SUPPORTED_AKM_SUITES; -+ -+ prRsnInfo->u4AuthKeyMgtSuiteCount = (UINT_32) u2AuthSuiteCount; -+ -+ for (i = 0; i < (UINT_32) u2AuthSuiteCount; i++) { -+ WLAN_GET_FIELD_32(pucAuthSuite, &prRsnInfo->au4AuthKeyMgtSuite[i]); -+ pucAuthSuite += 4; -+ -+ DBGLOG(RSN, LOUD, "RSN: AKM suite [%d]: %02x-%02x-%02x-%02x\n", -+ (UINT_8) i, (UCHAR) (prRsnInfo->au4AuthKeyMgtSuite[i] & 0x000000FF), -+ (UCHAR) ((prRsnInfo->au4AuthKeyMgtSuite[i] >> 8) & 0x000000FF), -+ (UCHAR) ((prRsnInfo->au4AuthKeyMgtSuite[i] >> 16) & 0x000000FF), -+ (UCHAR) ((prRsnInfo->au4AuthKeyMgtSuite[i] >> 24) & 0x000000FF)); -+ } -+ } else { -+ /* The information about the authentication and key management suites -+ is not present. Use the default AKM suite for RSN. */ -+ prRsnInfo->u4AuthKeyMgtSuiteCount = 1; -+ prRsnInfo->au4AuthKeyMgtSuite[0] = RSN_AKM_SUITE_802_1X; -+ -+ DBGLOG(RSN, LOUD, "RSN: AKM suite: %02x-%02x-%02x-%02x (default)\n", -+ (UCHAR) (prRsnInfo->au4AuthKeyMgtSuite[0] & 0x000000FF), -+ (UCHAR) ((prRsnInfo->au4AuthKeyMgtSuite[0] >> 8) & 0x000000FF), -+ (UCHAR) ((prRsnInfo->au4AuthKeyMgtSuite[0] >> 16) & 0x000000FF), -+ (UCHAR) ((prRsnInfo->au4AuthKeyMgtSuite[0] >> 24) & 0x000000FF)); -+ } -+ -+ prRsnInfo->u2RsnCap = u2Cap; -+#if CFG_SUPPORT_802_11W -+ prRsnInfo->fgRsnCapPresent = TRUE; -+#endif -+ DBGLOG(RSN, LOUD, "RSN cap: 0x%04x\n", prRsnInfo->u2RsnCap); -+ -+ return TRUE; -+} /* rsnParseRsnIE */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to parse WPA IE. -+* -+* \param[in] prInfoElem Pointer to the WPA IE. -+* \param[out] prWpaInfo Pointer to the BSSDescription structure to store the -+* WPA information from the given WPA IE. -+* -+* \retval TRUE Succeeded. -+* \retval FALSE Failed. -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN rsnParseWpaIE(IN P_ADAPTER_T prAdapter, IN P_WPA_INFO_ELEM_T prInfoElem, OUT P_RSN_INFO_T prWpaInfo) -+{ -+ UINT_32 i; -+ INT_32 u4RemainWpaIeLen; -+ UINT_16 u2Version; -+ UINT_16 u2Cap = 0; -+ UINT_32 u4GroupSuite = WPA_CIPHER_SUITE_TKIP; -+ UINT_16 u2PairSuiteCount = 0; -+ UINT_16 u2AuthSuiteCount = 0; -+ PUCHAR pucPairSuite = NULL; -+ PUCHAR pucAuthSuite = NULL; -+ PUCHAR cp; -+ BOOLEAN fgCapPresent = FALSE; -+ -+ DEBUGFUNC("rsnParseWpaIE"); -+ -+ ASSERT(prInfoElem); -+ ASSERT(prWpaInfo); -+ -+ /* Verify the length of the WPA IE. */ -+ if (prInfoElem->ucLength < 6) { -+ DBGLOG(RSN, TRACE, "WPA IE length too short (length=%d)\n", prInfoElem->ucLength); -+ return FALSE; -+ } -+ -+ /* Check WPA version: currently, we only support version 1. */ -+ WLAN_GET_FIELD_16(&prInfoElem->u2Version, &u2Version); -+ if (u2Version != 1) { -+ DBGLOG(RSN, TRACE, "Unsupported WPA IE version: %d\n", u2Version); -+ return FALSE; -+ } -+ -+ cp = (PUCHAR) &prInfoElem->u4GroupKeyCipherSuite; -+ u4RemainWpaIeLen = (INT_32) prInfoElem->ucLength - 6; -+ -+ do { -+ if (u4RemainWpaIeLen == 0) -+ break; -+ -+ /* WPA_OUI : 4 -+ Version : 2 -+ GroupSuite : 4 -+ PairwiseCount: 2 -+ PairwiseSuite: 4 * pairSuiteCount -+ AuthCount : 2 -+ AuthSuite : 4 * authSuiteCount -+ Cap : 2 */ -+ -+ /* Parse the Group Key Cipher Suite field. */ -+ if (u4RemainWpaIeLen < 4) { -+ DBGLOG(RSN, TRACE, "Fail to parse WPA IE in group cipher suite (IE len: %d)\n", -+ prInfoElem->ucLength); -+ return FALSE; -+ } -+ -+ WLAN_GET_FIELD_32(cp, &u4GroupSuite); -+ cp += 4; -+ u4RemainWpaIeLen -= 4; -+ -+ if (u4RemainWpaIeLen == 0) -+ break; -+ -+ /* Parse the Pairwise Key Cipher Suite Count field. */ -+ if (u4RemainWpaIeLen < 2) { -+ DBGLOG(RSN, TRACE, "Fail to parse WPA IE in pairwise cipher suite count (IE len: %d)\n", -+ prInfoElem->ucLength); -+ return FALSE; -+ } -+ -+ WLAN_GET_FIELD_16(cp, &u2PairSuiteCount); -+ cp += 2; -+ u4RemainWpaIeLen -= 2; -+ -+ /* Parse the Pairwise Key Cipher Suite List field. */ -+ i = (UINT_32) u2PairSuiteCount * 4; -+ if (u4RemainWpaIeLen < (INT_32) i) { -+ DBGLOG(RSN, TRACE, "Fail to parse WPA IE in pairwise cipher suite list (IE len: %d)\n", -+ prInfoElem->ucLength); -+ return FALSE; -+ } -+ -+ pucPairSuite = cp; -+ -+ cp += i; -+ u4RemainWpaIeLen -= (INT_32) i; -+ -+ if (u4RemainWpaIeLen == 0) -+ break; -+ -+ /* Parse the Authentication and Key Management Cipher Suite Count -+ field. */ -+ if (u4RemainWpaIeLen < 2) { -+ DBGLOG(RSN, TRACE, "Fail to parse WPA IE in auth & key mgt suite count (IE len: %d)\n", -+ prInfoElem->ucLength); -+ return FALSE; -+ } -+ -+ WLAN_GET_FIELD_16(cp, &u2AuthSuiteCount); -+ cp += 2; -+ u4RemainWpaIeLen -= 2; -+ -+ /* Parse the Authentication and Key Management Cipher Suite List -+ field. */ -+ i = (UINT_32) u2AuthSuiteCount * 4; -+ if (u4RemainWpaIeLen < (INT_32) i) { -+ DBGLOG(RSN, TRACE, "Fail to parse WPA IE in auth & key mgt suite list (IE len: %d)\n", -+ prInfoElem->ucLength); -+ return FALSE; -+ } -+ -+ pucAuthSuite = cp; -+ -+ cp += i; -+ u4RemainWpaIeLen -= (INT_32) i; -+ -+ if (u4RemainWpaIeLen == 0) -+ break; -+ -+ /* Parse the WPA u2Capabilities field. */ -+ if (u4RemainWpaIeLen < 2) { -+ DBGLOG(RSN, TRACE, "Fail to parse WPA IE in WPA capabilities (IE len: %d)\n", -+ prInfoElem->ucLength); -+ return FALSE; -+ } -+ -+ fgCapPresent = TRUE; -+ WLAN_GET_FIELD_16(cp, &u2Cap); -+ u4RemainWpaIeLen -= 2; -+ } while (FALSE); -+ -+ /* Save the WPA information for the BSS. */ -+ -+ prWpaInfo->ucElemId = ELEM_ID_WPA; -+ -+ prWpaInfo->u2Version = u2Version; -+ -+ prWpaInfo->u4GroupKeyCipherSuite = u4GroupSuite; -+ -+ DBGLOG(RSN, LOUD, "WPA: version %d, group key cipher suite %02x-%02x-%02x-%02x\n", -+ u2Version, (UCHAR) (u4GroupSuite & 0x000000FF), -+ (UCHAR) ((u4GroupSuite >> 8) & 0x000000FF), -+ (UCHAR) ((u4GroupSuite >> 16) & 0x000000FF), (UCHAR) ((u4GroupSuite >> 24) & 0x000000FF)); -+ -+ if (pucPairSuite) { -+ /* The information about the pairwise key cipher suites is present. */ -+ if (u2PairSuiteCount > MAX_NUM_SUPPORTED_CIPHER_SUITES) -+ u2PairSuiteCount = MAX_NUM_SUPPORTED_CIPHER_SUITES; -+ -+ prWpaInfo->u4PairwiseKeyCipherSuiteCount = (UINT_32) u2PairSuiteCount; -+ -+ for (i = 0; i < (UINT_32) u2PairSuiteCount; i++) { -+ WLAN_GET_FIELD_32(pucPairSuite, &prWpaInfo->au4PairwiseKeyCipherSuite[i]); -+ pucPairSuite += 4; -+ -+ DBGLOG(RSN, LOUD, "WPA: pairwise key cipher suite [%d]: %02x-%02x-%02x-%02x\n", -+ (UINT_8) i, (UCHAR) (prWpaInfo->au4PairwiseKeyCipherSuite[i] & 0x000000FF), -+ (UCHAR) ((prWpaInfo->au4PairwiseKeyCipherSuite[i] >> 8) & 0x000000FF), -+ (UCHAR) ((prWpaInfo->au4PairwiseKeyCipherSuite[i] >> 16) & 0x000000FF), -+ (UCHAR) ((prWpaInfo->au4PairwiseKeyCipherSuite[i] >> 24) & 0x000000FF)); -+ } -+ } else { -+ /* The information about the pairwise key cipher suites is not present. -+ Use the default chipher suite for WPA: TKIP. */ -+ prWpaInfo->u4PairwiseKeyCipherSuiteCount = 1; -+ prWpaInfo->au4PairwiseKeyCipherSuite[0] = WPA_CIPHER_SUITE_TKIP; -+ -+ DBGLOG(RSN, LOUD, "WPA: pairwise key cipher suite: %02x-%02x-%02x-%02x (default)\n", -+ (UCHAR) (prWpaInfo->au4PairwiseKeyCipherSuite[0] & 0x000000FF), -+ (UCHAR) ((prWpaInfo->au4PairwiseKeyCipherSuite[0] >> 8) & 0x000000FF), -+ (UCHAR) ((prWpaInfo->au4PairwiseKeyCipherSuite[0] >> 16) & 0x000000FF), -+ (UCHAR) ((prWpaInfo->au4PairwiseKeyCipherSuite[0] >> 24) & 0x000000FF)); -+ } -+ -+ if (pucAuthSuite) { -+ /* The information about the authentication and key management suites -+ is present. */ -+ if (u2AuthSuiteCount > MAX_NUM_SUPPORTED_AKM_SUITES) -+ u2AuthSuiteCount = MAX_NUM_SUPPORTED_AKM_SUITES; -+ -+ prWpaInfo->u4AuthKeyMgtSuiteCount = (UINT_32) u2AuthSuiteCount; -+ -+ for (i = 0; i < (UINT_32) u2AuthSuiteCount; i++) { -+ WLAN_GET_FIELD_32(pucAuthSuite, &prWpaInfo->au4AuthKeyMgtSuite[i]); -+ pucAuthSuite += 4; -+ -+ DBGLOG(RSN, LOUD, "WPA: AKM suite [%d]: %02x-%02x-%02x-%02x\n", -+ (UINT_8) i, (UCHAR) (prWpaInfo->au4AuthKeyMgtSuite[i] & 0x000000FF), -+ (UCHAR) ((prWpaInfo->au4AuthKeyMgtSuite[i] >> 8) & 0x000000FF), -+ (UCHAR) ((prWpaInfo->au4AuthKeyMgtSuite[i] >> 16) & 0x000000FF), -+ (UCHAR) ((prWpaInfo->au4AuthKeyMgtSuite[i] >> 24) & 0x000000FF)); -+ } -+ } else { -+ /* The information about the authentication and key management suites -+ is not present. Use the default AKM suite for WPA. */ -+ prWpaInfo->u4AuthKeyMgtSuiteCount = 1; -+ prWpaInfo->au4AuthKeyMgtSuite[0] = WPA_AKM_SUITE_802_1X; -+ -+ DBGLOG(RSN, LOUD, "WPA: AKM suite: %02x-%02x-%02x-%02x (default)\n", -+ (UCHAR) (prWpaInfo->au4AuthKeyMgtSuite[0] & 0x000000FF), -+ (UCHAR) ((prWpaInfo->au4AuthKeyMgtSuite[0] >> 8) & 0x000000FF), -+ (UCHAR) ((prWpaInfo->au4AuthKeyMgtSuite[0] >> 16) & 0x000000FF), -+ (UCHAR) ((prWpaInfo->au4AuthKeyMgtSuite[0] >> 24) & 0x000000FF)); -+ } -+ -+ if (fgCapPresent) { -+ prWpaInfo->fgRsnCapPresent = TRUE; -+ prWpaInfo->u2RsnCap = u2Cap; -+ DBGLOG(RSN, LOUD, "WPA: RSN cap: 0x%04x\n", prWpaInfo->u2RsnCap); -+ } else { -+ prWpaInfo->fgRsnCapPresent = FALSE; -+ prWpaInfo->u2RsnCap = 0; -+ } -+ -+ return TRUE; -+} /* rsnParseWpaIE */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to search the desired pairwise -+* cipher suite from the MIB Pairwise Cipher Suite -+* configuration table. -+* -+* \param[in] u4Cipher The desired pairwise cipher suite to be searched -+* \param[out] pu4Index Pointer to the index of the desired pairwise cipher in -+* the table -+* -+* \retval TRUE - The desired pairwise cipher suite is found in the table. -+* \retval FALSE - The desired pairwise cipher suite is not found in the -+* table. -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN rsnSearchSupportedCipher(IN P_ADAPTER_T prAdapter, IN UINT_32 u4Cipher, OUT PUINT_32 pu4Index) -+{ -+ UINT_8 i; -+ P_DOT11_RSNA_CONFIG_PAIRWISE_CIPHERS_ENTRY prEntry; -+ -+ DEBUGFUNC("rsnSearchSupportedCipher"); -+ -+ ASSERT(pu4Index); -+ -+ for (i = 0; i < MAX_NUM_SUPPORTED_CIPHER_SUITES; i++) { -+ prEntry = &prAdapter->rMib.dot11RSNAConfigPairwiseCiphersTable[i]; -+ if (prEntry->dot11RSNAConfigPairwiseCipher == u4Cipher && -+ prEntry->dot11RSNAConfigPairwiseCipherEnabled) { -+ *pu4Index = i; -+ return TRUE; -+ } -+ } -+ return FALSE; -+} /* rsnSearchSupportedCipher */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Whether BSS RSN is matched from upper layer set. -+* -+* \param[in] prAdapter Pointer to the Adapter structure, BSS RSN Information -+* -+* \retval BOOLEAN -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN rsnIsSuitableBSS(IN P_ADAPTER_T prAdapter, IN P_RSN_INFO_T prBssRsnInfo) -+{ -+ UINT_8 i = 0; -+ -+ DEBUGFUNC("rsnIsSuitableBSS"); -+ -+ do { -+ -+ if ((prAdapter->rWifiVar.rConnSettings.rRsnInfo.u4GroupKeyCipherSuite & 0x000000FF) != -+ GET_SELECTOR_TYPE(prBssRsnInfo->u4GroupKeyCipherSuite)) { -+ DBGLOG(RSN, TRACE, "Break by GroupKeyCipherSuite\n"); -+ break; -+ } -+ for (i = 0; i < prBssRsnInfo->u4PairwiseKeyCipherSuiteCount; i++) { -+ if (((prAdapter->rWifiVar.rConnSettings.rRsnInfo.au4PairwiseKeyCipherSuite[0] & 0x000000FF) != -+ GET_SELECTOR_TYPE(prBssRsnInfo->au4PairwiseKeyCipherSuite[i])) -+ && (i == prBssRsnInfo->u4PairwiseKeyCipherSuiteCount - 1)) { -+ DBGLOG(RSN, TRACE, "Break by PairwiseKeyCipherSuite\n"); -+ break; -+ } -+ } -+ for (i = 0; i < prBssRsnInfo->u4AuthKeyMgtSuiteCount; i++) { -+ if (((prAdapter->rWifiVar.rConnSettings.rRsnInfo.au4AuthKeyMgtSuite[0] & 0x000000FF) != -+ GET_SELECTOR_TYPE(prBssRsnInfo->au4AuthKeyMgtSuite[0])) -+ && (i == prBssRsnInfo->u4AuthKeyMgtSuiteCount - 1)) { -+ DBGLOG(RSN, TRACE, "Break by AuthKeyMgtSuite\n"); -+ break; -+ } -+ } -+ return TRUE; -+ } while (FALSE); -+ return FALSE; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* -+* \brief This routine is called to search the desired -+* authentication and key management (AKM) suite from the -+* MIB Authentication and Key Management Suites table. -+* -+* \param[in] u4AkmSuite The desired AKM suite to be searched -+* \param[out] pu4Index Pointer to the index of the desired AKM suite in the -+* table -+* -+* \retval TRUE The desired AKM suite is found in the table. -+* \retval FALSE The desired AKM suite is not found in the table. -+* -+* \note -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN rsnSearchAKMSuite(IN P_ADAPTER_T prAdapter, IN UINT_32 u4AkmSuite, OUT PUINT_32 pu4Index) -+{ -+ UINT_8 i; -+ P_DOT11_RSNA_CONFIG_AUTHENTICATION_SUITES_ENTRY prEntry; -+ -+ DEBUGFUNC("rsnSearchAKMSuite"); -+ -+ ASSERT(pu4Index); -+ -+ for (i = 0; i < MAX_NUM_SUPPORTED_AKM_SUITES; i++) { -+ prEntry = &prAdapter->rMib.dot11RSNAConfigAuthenticationSuitesTable[i]; -+ if (prEntry->dot11RSNAConfigAuthenticationSuite == u4AkmSuite && -+ prEntry->dot11RSNAConfigAuthenticationSuiteEnabled) { -+ *pu4Index = i; -+ return TRUE; -+ } -+ } -+ return FALSE; -+} /* rsnSearchAKMSuite */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to perform RSNA or TSN policy -+* selection for a given BSS. -+* -+* \param[in] prBss Pointer to the BSS description -+* -+* \retval TRUE - The RSNA/TSN policy selection for the given BSS is -+* successful. The selected pairwise and group cipher suites -+* are returned in the BSS description. -+* \retval FALSE - The RSNA/TSN policy selection for the given BSS is failed. -+* The driver shall not attempt to join the given BSS. -+* -+* \note The Encrypt status matched score will save to bss for final ap select. -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN rsnPerformPolicySelection(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBss) -+{ -+#if CFG_SUPPORT_802_11W -+ INT_32 i; -+ UINT_32 j; -+#else -+ UINT_32 i, j; -+#endif -+ BOOLEAN fgSuiteSupported; -+ UINT_32 u4PairwiseCipher = 0; -+ UINT_32 u4GroupCipher = 0; -+ UINT_32 u4AkmSuite = 0; -+ P_RSN_INFO_T prBssRsnInfo; -+ ENUM_NETWORK_TYPE_INDEX_T eNetwotkType; -+ BOOLEAN fgIsWpsActive = (BOOLEAN) FALSE; -+ -+ DEBUGFUNC("rsnPerformPolicySelection"); -+ -+ ASSERT(prBss); -+ -+ DBGLOG(RSN, TRACE, "rsnPerformPolicySelection\n"); -+ /* Todo:: */ -+ eNetwotkType = NETWORK_TYPE_AIS_INDEX; -+ -+ prBss->u4RsnSelectedPairwiseCipher = 0; -+ prBss->u4RsnSelectedGroupCipher = 0; -+ prBss->u4RsnSelectedAKMSuite = 0; -+ prBss->ucEncLevel = 0; -+ -+#if CFG_SUPPORT_WPS -+ fgIsWpsActive = kalWSCGetActiveState(prAdapter->prGlueInfo); -+ -+ /* CR1640, disable the AP select privacy check */ -+ if (fgIsWpsActive && -+ (prAdapter->rWifiVar.rConnSettings.eAuthMode < AUTH_MODE_WPA) && -+ (prAdapter->rWifiVar.rConnSettings.eOPMode == NET_TYPE_INFRA)) { -+ DBGLOG(RSN, TRACE, "-- Skip the Protected BSS check\n"); -+ return TRUE; -+ } -+#endif -+ -+ /* Protection is not required in this BSS. */ -+ if ((prBss->u2CapInfo & CAP_INFO_PRIVACY) == 0) { -+ -+ if (secEnabledInAis(prAdapter) == FALSE) { -+ DBGLOG(RSN, TRACE, "-- No Protected BSS\n"); -+ return TRUE; -+ } -+ DBGLOG(RSN, TRACE, "-- Protected BSS\n"); -+ return FALSE; -+ -+ } -+ -+ /* Protection is required in this BSS. */ -+ if ((prBss->u2CapInfo & CAP_INFO_PRIVACY) != 0) { -+ if (secEnabledInAis(prAdapter) == FALSE) { -+ DBGLOG(RSN, TRACE, "-- Protected BSS\n"); -+ return FALSE; -+ } -+ } -+ -+ if (prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA || -+ prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA_PSK || -+ prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA_NONE) { -+ -+ if (prBss->fgIEWPA) { -+ prBssRsnInfo = &prBss->rWPAInfo; -+ } else { -+ DBGLOG(RSN, TRACE, "WPA Information Element does not exist.\n"); -+ return FALSE; -+ } -+ } else if (prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA2 || -+ prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA2_PSK) { -+ -+ if (prBss->fgIERSN) { -+ prBssRsnInfo = &prBss->rRSNInfo; -+ } else { -+ DBGLOG(RSN, TRACE, "RSN Information Element does not exist.\n"); -+ return FALSE; -+ } -+ } else if (prAdapter->rWifiVar.rConnSettings.eEncStatus != ENUM_ENCRYPTION1_ENABLED) { -+ /* If the driver is configured to use WEP only, ignore this BSS. */ -+ DBGLOG(RSN, TRACE, "-- Not WEP-only legacy BSS %d\n", prAdapter->rWifiVar.rConnSettings.eEncStatus); -+ return FALSE; -+ } else if (prAdapter->rWifiVar.rConnSettings.eEncStatus == ENUM_ENCRYPTION1_ENABLED) { -+ /* If the driver is configured to use WEP only, use this BSS. */ -+ DBGLOG(RSN, TRACE, "-- WEP-only legacy BSS, fgIERSN %d, fgIEWPA %d\n", -+ prBss->fgIERSN, prBss->fgIEWPA); -+ /* if this BSS was configured to WPA/WPA2, don't select this AP */ -+ return (prBss->fgIERSN || prBss->fgIEWPA) ? FALSE : TRUE; -+ } -+ -+ if (!rsnIsSuitableBSS(prAdapter, prBssRsnInfo)) { -+ DBGLOG(RSN, TRACE, "RSN info check no matched\n"); -+ return FALSE; -+ } -+ -+ if (prBssRsnInfo->u4PairwiseKeyCipherSuiteCount == 1 && -+ GET_SELECTOR_TYPE(prBssRsnInfo->au4PairwiseKeyCipherSuite[0]) == CIPHER_SUITE_NONE) { -+ /* Since the pairwise cipher use the same cipher suite as the group -+ cipher in the BSS, we check the group cipher suite against the -+ current encryption status. */ -+ fgSuiteSupported = FALSE; -+ -+ switch (prBssRsnInfo->u4GroupKeyCipherSuite) { -+ case WPA_CIPHER_SUITE_CCMP: -+ case RSN_CIPHER_SUITE_CCMP: -+ if (prAdapter->rWifiVar.rConnSettings.eEncStatus == ENUM_ENCRYPTION3_ENABLED) -+ fgSuiteSupported = TRUE; -+ break; -+ -+ case WPA_CIPHER_SUITE_TKIP: -+ case RSN_CIPHER_SUITE_TKIP: -+ if (prAdapter->rWifiVar.rConnSettings.eEncStatus == ENUM_ENCRYPTION2_ENABLED) -+ fgSuiteSupported = TRUE; -+ break; -+ -+ case WPA_CIPHER_SUITE_WEP40: -+ case WPA_CIPHER_SUITE_WEP104: -+ if (prAdapter->rWifiVar.rConnSettings.eEncStatus == ENUM_ENCRYPTION1_ENABLED) -+ fgSuiteSupported = TRUE; -+ break; -+ } -+ -+ if (fgSuiteSupported) { -+ u4PairwiseCipher = WPA_CIPHER_SUITE_NONE; -+ u4GroupCipher = prBssRsnInfo->u4GroupKeyCipherSuite; -+ } -+#if DBG -+ else { -+ DBGLOG(RSN, TRACE, "Inproper encryption status %d for group-key-only BSS\n", -+ prAdapter->rWifiVar.rConnSettings.eEncStatus); -+ } -+#endif -+ } else { -+ fgSuiteSupported = FALSE; -+ -+ DBGLOG(RSN, TRACE, "eEncStatus %d %d 0x%x\n", prAdapter->rWifiVar.rConnSettings.eEncStatus, -+ (UINT_32) prBssRsnInfo->u4PairwiseKeyCipherSuiteCount, -+ (UINT_32) prBssRsnInfo->au4PairwiseKeyCipherSuite[0]); -+ /* Select pairwise/group ciphers */ -+ switch (prAdapter->rWifiVar.rConnSettings.eEncStatus) { -+ case ENUM_ENCRYPTION3_ENABLED: -+ for (i = 0; i < prBssRsnInfo->u4PairwiseKeyCipherSuiteCount; i++) { -+ if (GET_SELECTOR_TYPE(prBssRsnInfo->au4PairwiseKeyCipherSuite[i]) -+ == CIPHER_SUITE_CCMP) { -+ u4PairwiseCipher = prBssRsnInfo->au4PairwiseKeyCipherSuite[i]; -+ } -+ } -+ u4GroupCipher = prBssRsnInfo->u4GroupKeyCipherSuite; -+ break; -+ -+ case ENUM_ENCRYPTION2_ENABLED: -+ for (i = 0; i < prBssRsnInfo->u4PairwiseKeyCipherSuiteCount; i++) { -+ if (GET_SELECTOR_TYPE(prBssRsnInfo->au4PairwiseKeyCipherSuite[i]) -+ == CIPHER_SUITE_TKIP) { -+ u4PairwiseCipher = prBssRsnInfo->au4PairwiseKeyCipherSuite[i]; -+ } -+ } -+ if (GET_SELECTOR_TYPE(prBssRsnInfo->u4GroupKeyCipherSuite) == CIPHER_SUITE_CCMP) -+ DBGLOG(RSN, TRACE, "Cannot join CCMP BSS\n"); -+ else -+ u4GroupCipher = prBssRsnInfo->u4GroupKeyCipherSuite; -+ break; -+ -+ case ENUM_ENCRYPTION1_ENABLED: -+ for (i = 0; i < prBssRsnInfo->u4PairwiseKeyCipherSuiteCount; i++) { -+ if (GET_SELECTOR_TYPE(prBssRsnInfo->au4PairwiseKeyCipherSuite[i]) -+ == CIPHER_SUITE_WEP40 || -+ GET_SELECTOR_TYPE(prBssRsnInfo->au4PairwiseKeyCipherSuite[i]) -+ == CIPHER_SUITE_WEP104) { -+ u4PairwiseCipher = prBssRsnInfo->au4PairwiseKeyCipherSuite[i]; -+ } -+ } -+ if (GET_SELECTOR_TYPE(prBssRsnInfo->u4GroupKeyCipherSuite) == -+ CIPHER_SUITE_CCMP || -+ GET_SELECTOR_TYPE(prBssRsnInfo->u4GroupKeyCipherSuite) == CIPHER_SUITE_TKIP) { -+ DBGLOG(RSN, TRACE, "Cannot join CCMP/TKIP BSS\n"); -+ } else { -+ u4GroupCipher = prBssRsnInfo->u4GroupKeyCipherSuite; -+ } -+ break; -+ -+ default: -+ break; -+ } -+ } -+ -+ /* Exception handler */ -+ /* If we cannot find proper pairwise and group cipher suites to join the -+ BSS, do not check the supported AKM suites. */ -+ if (u4PairwiseCipher == 0 || u4GroupCipher == 0) { -+ DBGLOG(RSN, TRACE, "Failed to select pairwise/group cipher (0x%08x/0x%08x)\n", -+ u4PairwiseCipher, u4GroupCipher); -+ return FALSE; -+ } -+#if CFG_ENABLE_WIFI_DIRECT -+ if ((prAdapter->fgIsP2PRegistered) && (eNetwotkType == NETWORK_TYPE_P2P_INDEX)) { -+ if (u4PairwiseCipher != RSN_CIPHER_SUITE_CCMP || -+ u4GroupCipher != RSN_CIPHER_SUITE_CCMP || u4AkmSuite != RSN_AKM_SUITE_PSK) { -+ DBGLOG(RSN, TRACE, "Failed to select pairwise/group cipher for P2P network (0x%08x/0x%08x)\n", -+ u4PairwiseCipher, u4GroupCipher); -+ return FALSE; -+ } -+ } -+#endif -+ -+#if CFG_ENABLE_BT_OVER_WIFI -+ if (eNetwotkType == NETWORK_TYPE_BOW_INDEX) { -+ if (u4PairwiseCipher != RSN_CIPHER_SUITE_CCMP || -+ u4GroupCipher != RSN_CIPHER_SUITE_CCMP || u4AkmSuite != RSN_AKM_SUITE_PSK) { -+ /* Do nothing */ -+ } -+ DBGLOG(RSN, TRACE, -+ "Failed to select pairwise/group cipher for BT over Wi-Fi network (0x%08x/0x%08x)\n", -+ u4PairwiseCipher, u4GroupCipher); -+ return FALSE; -+ } -+#endif -+ -+ /* Verify if selected pairwisse cipher is supported */ -+ fgSuiteSupported = rsnSearchSupportedCipher(prAdapter, u4PairwiseCipher, &i); -+ -+ /* Verify if selected group cipher is supported */ -+ if (fgSuiteSupported) -+ fgSuiteSupported = rsnSearchSupportedCipher(prAdapter, u4GroupCipher, &i); -+ -+ if (!fgSuiteSupported) { -+ DBGLOG(RSN, TRACE, "Failed to support selected pairwise/group cipher (0x%08x/0x%08x)\n", -+ u4PairwiseCipher, u4GroupCipher); -+ return FALSE; -+ } -+ -+ /* Select AKM */ -+ /* If the driver cannot support any authentication suites advertised in -+ the given BSS, we fail to perform RSNA policy selection. */ -+ /* Attempt to find any overlapping supported AKM suite. */ -+#if CFG_SUPPORT_802_11W -+ if (i != 0) -+ for (i = (prBssRsnInfo->u4AuthKeyMgtSuiteCount - 1); i >= 0; i--) { -+#else -+ for (i = 0; i < prBssRsnInfo->u4AuthKeyMgtSuiteCount; i++) { -+#endif -+ if (rsnSearchAKMSuite(prAdapter, prBssRsnInfo->au4AuthKeyMgtSuite[i], &j)) { -+ u4AkmSuite = prBssRsnInfo->au4AuthKeyMgtSuite[i]; -+ break; -+ } -+ } -+ -+ if (u4AkmSuite == 0) { -+ DBGLOG(RSN, TRACE, "Cannot support any AKM suites\n"); -+ return FALSE; -+ } -+ -+ DBGLOG(RSN, TRACE, "Selected pairwise/group cipher: %02x-%02x-%02x-%02x/%02x-%02x-%02x-%02x\n", -+ (UINT_8) (u4PairwiseCipher & 0x000000FF), -+ (UINT_8) ((u4PairwiseCipher >> 8) & 0x000000FF), -+ (UINT_8) ((u4PairwiseCipher >> 16) & 0x000000FF), -+ (UINT_8) ((u4PairwiseCipher >> 24) & 0x000000FF), -+ (UINT_8) (u4GroupCipher & 0x000000FF), -+ (UINT_8) ((u4GroupCipher >> 8) & 0x000000FF), -+ (UINT_8) ((u4GroupCipher >> 16) & 0x000000FF), -+ (UINT_8) ((u4GroupCipher >> 24) & 0x000000FF)); -+ -+ DBGLOG(RSN, TRACE, "Selected AKM suite: %02x-%02x-%02x-%02x\n", -+ (UINT_8) (u4AkmSuite & 0x000000FF), -+ (UINT_8) ((u4AkmSuite >> 8) & 0x000000FF), -+ (UINT_8) ((u4AkmSuite >> 16) & 0x000000FF), (UINT_8) ((u4AkmSuite >> 24) & 0x000000FF)); -+ -+#if CFG_SUPPORT_802_11W -+ DBGLOG(RSN, TRACE, "MFP setting = %d\n ", kalGetMfpSetting(prAdapter->prGlueInfo)); -+ -+ if (kalGetMfpSetting(prAdapter->prGlueInfo) == RSN_AUTH_MFP_REQUIRED) { -+ if (!prBssRsnInfo->fgRsnCapPresent) { -+ DBGLOG(RSN, TRACE, "Skip RSN IE, No MFP Required Capability.\n"); -+ return FALSE; -+ } else if (!(prBssRsnInfo->u2RsnCap & ELEM_WPA_CAP_MFPC)) { -+ DBGLOG(RSN, TRACE, "Skip RSN IE, No MFP Required\n"); -+ return FALSE; -+ } -+ prAdapter->rWifiVar.rAisSpecificBssInfo.fgMgmtProtection = TRUE; -+ } else if (kalGetMfpSetting(prAdapter->prGlueInfo) == RSN_AUTH_MFP_OPTIONAL) { -+ if (prBssRsnInfo->u2RsnCap && ((prBssRsnInfo->u2RsnCap & ELEM_WPA_CAP_MFPR) || -+ (prBssRsnInfo->u2RsnCap & ELEM_WPA_CAP_MFPC))) { -+ prAdapter->rWifiVar.rAisSpecificBssInfo.fgMgmtProtection = TRUE; -+ } else { -+ prAdapter->rWifiVar.rAisSpecificBssInfo.fgMgmtProtection = FALSE; -+ } -+ } else { -+ if (prBssRsnInfo->fgRsnCapPresent && (prBssRsnInfo->u2RsnCap & ELEM_WPA_CAP_MFPR)) { -+ DBGLOG(RSN, TRACE, "Skip RSN IE, No MFP Required Capability\n"); -+ return FALSE; -+ } -+ prAdapter->rWifiVar.rAisSpecificBssInfo.fgMgmtProtection = FALSE; -+ } -+ DBGLOG(RSN, TRACE, "fgMgmtProtection = %d\n ", prAdapter->rWifiVar.rAisSpecificBssInfo.fgMgmtProtection); -+#endif -+ -+ if (GET_SELECTOR_TYPE(u4GroupCipher) == CIPHER_SUITE_CCMP) { -+ prBss->ucEncLevel = 3; -+ } else if (GET_SELECTOR_TYPE(u4GroupCipher) == CIPHER_SUITE_TKIP) { -+ prBss->ucEncLevel = 2; -+ } else if (GET_SELECTOR_TYPE(u4GroupCipher) == CIPHER_SUITE_WEP40 || -+ GET_SELECTOR_TYPE(u4GroupCipher) == CIPHER_SUITE_WEP104) { -+ prBss->ucEncLevel = 1; -+ } else { -+ ASSERT(FALSE); -+ } -+ prBss->u4RsnSelectedPairwiseCipher = u4PairwiseCipher; -+ prBss->u4RsnSelectedGroupCipher = u4GroupCipher; -+ prBss->u4RsnSelectedAKMSuite = u4AkmSuite; -+ -+ return TRUE; -+ -+} /* rsnPerformPolicySelection */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to generate WPA IE for beacon frame. -+* -+* \param[in] pucIeStartAddr Pointer to put the generated WPA IE. -+* -+* \return The append WPA-None IE length -+* \note -+* Called by: JOIN module, compose beacon IE -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rsnGenerateWpaNoneIE(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo) -+{ -+ UINT_32 i; -+ P_WPA_INFO_ELEM_T prWpaIE; -+ UINT_32 u4Suite; -+ UINT_16 u2SuiteCount; -+ PUINT_8 cp, cp2; -+ UINT_8 ucExpendedLen = 0; -+ PUINT_8 pucBuffer; -+ ENUM_NETWORK_TYPE_INDEX_T eNetworkId; -+ -+ DEBUGFUNC("rsnGenerateWpaNoneIE"); -+ -+ ASSERT(prMsduInfo); -+ -+ if (prAdapter->rWifiVar.rConnSettings.eAuthMode != AUTH_MODE_WPA_NONE) -+ return; -+ -+ eNetworkId = (ENUM_NETWORK_TYPE_INDEX_T) prMsduInfo->ucNetworkType; -+ -+ if (eNetworkId != NETWORK_TYPE_AIS_INDEX) -+ return; -+ -+ pucBuffer = (PUINT_8) ((ULONG) prMsduInfo->prPacket + (UINT_32) prMsduInfo->u2FrameLength); -+ -+ ASSERT(pucBuffer); -+ -+ prWpaIE = (P_WPA_INFO_ELEM_T) (pucBuffer); -+ -+ /* Start to construct a WPA IE. */ -+ /* Fill the Element ID field. */ -+ prWpaIE->ucElemId = ELEM_ID_WPA; -+ -+ /* Fill the OUI and OUI Type fields. */ -+ prWpaIE->aucOui[0] = 0x00; -+ prWpaIE->aucOui[1] = 0x50; -+ prWpaIE->aucOui[2] = 0xF2; -+ prWpaIE->ucOuiType = VENDOR_OUI_TYPE_WPA; -+ -+ /* Fill the Version field. */ -+ WLAN_SET_FIELD_16(&prWpaIE->u2Version, 1); /* version 1 */ -+ ucExpendedLen = 6; -+ -+ /* Fill the Pairwise Key Cipher Suite List field. */ -+ u2SuiteCount = 0; -+ cp = (PUINT_8) &prWpaIE->aucPairwiseKeyCipherSuite1[0]; -+ -+ if (rsnSearchSupportedCipher(prAdapter, WPA_CIPHER_SUITE_CCMP, &i)) -+ u4Suite = WPA_CIPHER_SUITE_CCMP; -+ else if (rsnSearchSupportedCipher(prAdapter, WPA_CIPHER_SUITE_TKIP, &i)) -+ u4Suite = WPA_CIPHER_SUITE_TKIP; -+ else if (rsnSearchSupportedCipher(prAdapter, WPA_CIPHER_SUITE_WEP104, &i)) -+ u4Suite = WPA_CIPHER_SUITE_WEP104; -+ else if (rsnSearchSupportedCipher(prAdapter, WPA_CIPHER_SUITE_WEP40, &i)) -+ u4Suite = WPA_CIPHER_SUITE_WEP40; -+ else -+ u4Suite = WPA_CIPHER_SUITE_TKIP; -+ -+ WLAN_SET_FIELD_32(cp, u4Suite); -+ u2SuiteCount++; -+ ucExpendedLen += 4; -+ cp += 4; -+ -+ /* Fill the Group Key Cipher Suite field as the same in pair-wise key. */ -+ WLAN_SET_FIELD_32(&prWpaIE->u4GroupKeyCipherSuite, u4Suite); -+ ucExpendedLen += 4; -+ -+ /* Fill the Pairwise Key Cipher Suite Count field. */ -+ WLAN_SET_FIELD_16(&prWpaIE->u2PairwiseKeyCipherSuiteCount, u2SuiteCount); -+ ucExpendedLen += 2; -+ -+ cp2 = cp; -+ -+ /* Fill the Authentication and Key Management Suite List field. */ -+ u2SuiteCount = 0; -+ cp += 2; -+ -+ if (rsnSearchAKMSuite(prAdapter, WPA_AKM_SUITE_802_1X, &i)) -+ u4Suite = WPA_AKM_SUITE_802_1X; -+ else if (rsnSearchAKMSuite(prAdapter, WPA_AKM_SUITE_PSK, &i)) -+ u4Suite = WPA_AKM_SUITE_PSK; -+ else -+ u4Suite = WPA_AKM_SUITE_NONE; -+ -+ /* This shall be the only available value for current implementation */ -+ ASSERT(u4Suite == WPA_AKM_SUITE_NONE); -+ -+ WLAN_SET_FIELD_32(cp, u4Suite); -+ u2SuiteCount++; -+ ucExpendedLen += 4; -+ cp += 4; -+ -+ /* Fill the Authentication and Key Management Suite Count field. */ -+ WLAN_SET_FIELD_16(cp2, u2SuiteCount); -+ ucExpendedLen += 2; -+ -+ /* Fill the Length field. */ -+ prWpaIE->ucLength = (UINT_8) ucExpendedLen; -+ -+ /* Increment the total IE length for the Element ID and Length fields. */ -+ prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer); -+ -+} /* rsnGenerateWpaNoneIE */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* -+* \brief This routine is called to generate WPA IE for -+* associate request frame. -+* -+* \param[in] prCurrentBss The Selected BSS description -+* -+* \retval The append WPA IE length -+* -+* \note -+* Called by: AIS module, Associate request -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rsnGenerateWPAIE(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo) -+{ -+ PUCHAR cp; -+ PUINT_8 pucBuffer; -+ ENUM_NETWORK_TYPE_INDEX_T eNetworkId; -+ P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo; -+ -+ DEBUGFUNC("rsnGenerateWPAIE"); -+ -+ ASSERT(prMsduInfo); -+ -+ pucBuffer = (PUINT_8) ((ULONG) prMsduInfo->prPacket + (UINT_32) prMsduInfo->u2FrameLength); -+ -+ ASSERT(pucBuffer); -+ -+ eNetworkId = (ENUM_NETWORK_TYPE_INDEX_T) prMsduInfo->ucNetworkType; -+ prP2pSpecificBssInfo = prAdapter->rWifiVar.prP2pSpecificBssInfo; -+ -+ /* if (eNetworkId != NETWORK_TYPE_AIS_INDEX) */ -+ /* return; */ -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ if ((1 /* prCurrentBss->fgIEWPA */ && -+ ((prAdapter->fgIsP2PRegistered) && -+ (eNetworkId == NETWORK_TYPE_P2P_INDEX) && -+ (kalP2PGetTkipCipher(prAdapter->prGlueInfo)))) || -+ ((prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA) || -+ (prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA_PSK))) { -+#else -+ if ((1 /* prCurrentBss->fgIEWPA */ && -+ ((prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA) || -+ (prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA_PSK)))) { -+#endif -+ if (prP2pSpecificBssInfo->u2WpaIeLen != 0) { -+ kalMemCopy(pucBuffer, prP2pSpecificBssInfo->aucWpaIeBuffer, prP2pSpecificBssInfo->u2WpaIeLen); -+ prMsduInfo->u2FrameLength += prP2pSpecificBssInfo->u2WpaIeLen; -+ return; -+ } -+ -+ /* Construct a WPA IE for association request frame. */ -+ WPA_IE(pucBuffer)->ucElemId = ELEM_ID_WPA; -+ WPA_IE(pucBuffer)->ucLength = ELEM_ID_WPA_LEN_FIXED; -+ WPA_IE(pucBuffer)->aucOui[0] = 0x00; -+ WPA_IE(pucBuffer)->aucOui[1] = 0x50; -+ WPA_IE(pucBuffer)->aucOui[2] = 0xF2; -+ WPA_IE(pucBuffer)->ucOuiType = VENDOR_OUI_TYPE_WPA; -+ WLAN_SET_FIELD_16(&WPA_IE(pucBuffer)->u2Version, 1); -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ if (prAdapter->fgIsP2PRegistered && eNetworkId == NETWORK_TYPE_P2P_INDEX) { -+ WLAN_SET_FIELD_32(&WPA_IE(pucBuffer)->u4GroupKeyCipherSuite, WPA_CIPHER_SUITE_TKIP); -+ } else -+#endif -+ WLAN_SET_FIELD_32(&WPA_IE(pucBuffer)->u4GroupKeyCipherSuite, -+ prAdapter->rWifiVar. -+ arBssInfo[NETWORK_TYPE_AIS_INDEX].u4RsnSelectedGroupCipher); -+ -+ cp = (PUCHAR) &WPA_IE(pucBuffer)->aucPairwiseKeyCipherSuite1[0]; -+ -+ WLAN_SET_FIELD_16(&WPA_IE(pucBuffer)->u2PairwiseKeyCipherSuiteCount, 1); -+#if CFG_ENABLE_WIFI_DIRECT -+ if (prAdapter->fgIsP2PRegistered && eNetworkId == NETWORK_TYPE_P2P_INDEX) { -+ WLAN_SET_FIELD_32(cp, WPA_CIPHER_SUITE_TKIP); -+ } else -+#endif -+ WLAN_SET_FIELD_32(cp, -+ prAdapter->rWifiVar. -+ arBssInfo[NETWORK_TYPE_AIS_INDEX].u4RsnSelectedPairwiseCipher); -+ cp += 4; -+ -+ WLAN_SET_FIELD_16(cp, 1); -+ cp += 2; -+#if CFG_ENABLE_WIFI_DIRECT -+ if (prAdapter->fgIsP2PRegistered && eNetworkId == NETWORK_TYPE_P2P_INDEX) { -+ WLAN_SET_FIELD_32(cp, WPA_AKM_SUITE_PSK); -+ } else -+#endif -+ WLAN_SET_FIELD_32(cp, -+ prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX].u4RsnSelectedAKMSuite); -+ cp += 4; -+ -+ WPA_IE(pucBuffer)->ucLength = ELEM_ID_WPA_LEN_FIXED; -+ -+ prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer); -+ } -+ -+} /* rsnGenerateWPAIE */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* -+* \brief This routine is called to generate RSN IE for -+* associate request frame. -+* -+* \param[in] prMsduInfo The Selected BSS description -+* -+* \retval The append RSN IE length -+* -+* \note -+* Called by: AIS module, P2P module, BOW module Associate request -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rsnGenerateRSNIE(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo) -+{ -+ UINT_32 u4Entry; -+ PUCHAR cp; -+ /* UINT_8 ucExpendedLen = 0; */ -+ PUINT_8 pucBuffer; -+ ENUM_NETWORK_TYPE_INDEX_T eNetworkId; -+ P_STA_RECORD_T prStaRec; -+ -+ DEBUGFUNC("rsnGenerateRSNIE"); -+ -+ ASSERT(prMsduInfo); -+ -+ pucBuffer = (PUINT_8) ((ULONG) prMsduInfo->prPacket + (UINT_32) prMsduInfo->u2FrameLength); -+ -+ ASSERT(pucBuffer); -+ -+ /* Todo:: network id */ -+ eNetworkId = (ENUM_NETWORK_TYPE_INDEX_T) prMsduInfo->ucNetworkType; -+ -+ if ( -+#if CFG_ENABLE_WIFI_DIRECT -+ ((prAdapter->fgIsP2PRegistered) && -+ (eNetworkId == NETWORK_TYPE_P2P_INDEX) && (kalP2PGetCcmpCipher(prAdapter->prGlueInfo))) || -+#endif -+#if CFG_ENABLE_BT_OVER_WIFI -+ (eNetworkId == NETWORK_TYPE_BOW_INDEX) || -+#endif -+ (eNetworkId == NETWORK_TYPE_AIS_INDEX /* prCurrentBss->fgIERSN */ && -+ ((prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA2) || -+ (prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA2_PSK)))) { -+ /* Construct a RSN IE for association request frame. */ -+ RSN_IE(pucBuffer)->ucElemId = ELEM_ID_RSN; -+ RSN_IE(pucBuffer)->ucLength = ELEM_ID_RSN_LEN_FIXED; -+ WLAN_SET_FIELD_16(&RSN_IE(pucBuffer)->u2Version, 1); /* Version */ -+ WLAN_SET_FIELD_32(&RSN_IE(pucBuffer)->u4GroupKeyCipherSuite, -+ prAdapter->rWifiVar.arBssInfo[eNetworkId].u4RsnSelectedGroupCipher); /* Group key suite */ -+ cp = (PUCHAR) &RSN_IE(pucBuffer)->aucPairwiseKeyCipherSuite1[0]; -+ WLAN_SET_FIELD_16(&RSN_IE(pucBuffer)->u2PairwiseKeyCipherSuiteCount, 1); -+ WLAN_SET_FIELD_32(cp, prAdapter->rWifiVar.arBssInfo[eNetworkId].u4RsnSelectedPairwiseCipher); -+ cp += 4; -+ WLAN_SET_FIELD_16(cp, 1); /* AKM suite count */ -+ cp += 2; -+ WLAN_SET_FIELD_32(cp, prAdapter->rWifiVar.arBssInfo[eNetworkId].u4RsnSelectedAKMSuite); /* AKM suite */ -+ cp += 4; -+ WLAN_SET_FIELD_16(cp, prAdapter->rWifiVar.arBssInfo[eNetworkId].u2RsnSelectedCapInfo);/* Capabilities */ -+#if CFG_SUPPORT_802_11W -+ if (eNetworkId == NETWORK_TYPE_AIS_INDEX && prAdapter->rWifiVar.rAisSpecificBssInfo.fgMgmtProtection) { -+ if (kalGetMfpSetting(prAdapter->prGlueInfo) == RSN_AUTH_MFP_REQUIRED) -+ WLAN_SET_FIELD_16(cp, ELEM_WPA_CAP_MFPC | ELEM_WPA_CAP_MFPR); /* Capabilities */ -+ else if (kalGetMfpSetting(prAdapter->prGlueInfo) == RSN_AUTH_MFP_OPTIONAL) -+ WLAN_SET_FIELD_16(cp, ELEM_WPA_CAP_MFPC); /* Capabilities */ -+ } -+#endif -+ cp += 2; -+ -+ if (eNetworkId == NETWORK_TYPE_AIS_INDEX) { -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); -+ if (!prStaRec) { -+ DBGLOG(RSN, TRACE, "rsnGenerateRSNIE: prStaRec is NULL\n"); -+ return; -+ } -+ } -+ -+ if (eNetworkId == NETWORK_TYPE_AIS_INDEX && -+ rsnSearchPmkidEntry(prAdapter, prStaRec->aucMacAddr, &u4Entry)) { -+ /* DBGLOG(RSN, TRACE, ("Add Pmk at assoc req\n")); */ -+ /* DBGLOG(RSN, TRACE, ("addr %pM PMKID %pM\n", */ -+ /* (prAdapter->rWifiVar.rAisSpecificBssInfo.arPmkidCache[u4Entry].rBssidInfo.arBSSID),*/ -+ /* (prAdapter->rWifiVar.rAisSpecificBssInfo.arPmkidCache[u4Entry].rBssidInfo.arPMKID))); */ -+ if (prAdapter->rWifiVar.rAisSpecificBssInfo.arPmkidCache[u4Entry].fgPmkidExist) { -+ RSN_IE(pucBuffer)->ucLength = 38; -+ WLAN_SET_FIELD_16(cp, 1); /* PMKID count */ -+ cp += 2; -+ DBGLOG(RSN, TRACE, -+ "BSSID %pM ind=%d\n", prStaRec->aucMacAddr, (UINT_32) u4Entry); -+ DBGLOG(RSN, TRACE, "use PMKID %pM\n", -+ (prAdapter->rWifiVar.rAisSpecificBssInfo. -+ arPmkidCache[u4Entry].rBssidInfo.arPMKID)); -+ kalMemCopy(cp, -+ (PVOID) prAdapter->rWifiVar.rAisSpecificBssInfo. -+ arPmkidCache[u4Entry].rBssidInfo.arPMKID, sizeof(PARAM_PMKID_VALUE)); -+ /* ucExpendedLen = 40; */ -+ } else { -+ WLAN_SET_FIELD_16(cp, 0); /* PMKID count */ -+ /* ucExpendedLen = ELEM_ID_RSN_LEN_FIXED + 2; */ -+#if CFG_SUPPORT_802_11W -+ cp += 2; -+ RSN_IE(pucBuffer)->ucLength += 2; -+#endif -+ } -+ } else { -+ WLAN_SET_FIELD_16(cp, 0); /* PMKID count */ -+ /* ucExpendedLen = ELEM_ID_RSN_LEN_FIXED + 2; */ -+#if CFG_SUPPORT_802_11W -+ cp += 2; -+ RSN_IE(pucBuffer)->ucLength += 2; -+#endif -+ } -+ -+#if CFG_SUPPORT_802_11W -+ if ((eNetworkId == NETWORK_TYPE_AIS_INDEX) -+ && (kalGetMfpSetting(prAdapter->prGlueInfo) != -+ RSN_AUTH_MFP_DISABLED) /* (mgmt_group_cipher == WPA_CIPHER_AES_128_CMAC) */) { -+ WLAN_SET_FIELD_32(cp, RSN_CIPHER_SUITE_AES_128_CMAC); -+ cp += 4; -+ RSN_IE(pucBuffer)->ucLength += 4; -+ } -+#endif -+ prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer); -+ } -+ -+} /* rsnGenerateRSNIE */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Parse the given IE buffer and check if it is WFA IE and return Type and -+* SubType for further process. -+* -+* \param[in] pucBuf Pointer to the buffer of WFA Information Element. -+* \param[out] pucOuiType Pointer to the storage of OUI Type. -+* \param[out] pu2SubTypeVersion Pointer to the storage of OUI SubType and Version. -+ -+* \retval TRUE Parse IE ok -+* \retval FALSE Parse IE fail -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN -+rsnParseCheckForWFAInfoElem(IN P_ADAPTER_T prAdapter, -+ IN PUINT_8 pucBuf, OUT PUINT_8 pucOuiType, OUT PUINT_16 pu2SubTypeVersion) -+{ -+ UINT_8 aucWfaOui[] = VENDOR_OUI_WFA; -+ P_IE_WFA_T prWfaIE; -+ -+ ASSERT(pucBuf); -+ ASSERT(pucOuiType); -+ ASSERT(pu2SubTypeVersion); -+ prWfaIE = (P_IE_WFA_T) pucBuf; -+ -+ do { -+ if (IE_LEN(pucBuf) <= ELEM_MIN_LEN_WFA_OUI_TYPE_SUBTYPE) { -+ break; -+ } else if (prWfaIE->aucOui[0] != aucWfaOui[0] || -+ prWfaIE->aucOui[1] != aucWfaOui[1] || prWfaIE->aucOui[2] != aucWfaOui[2]) { -+ break; -+ } -+ -+ *pucOuiType = prWfaIE->ucOuiType; -+ WLAN_GET_FIELD_16(&prWfaIE->aucOuiSubTypeVersion[0], pu2SubTypeVersion); -+ -+ return TRUE; -+ } while (FALSE); -+ -+ return FALSE; -+ -+} /* end of rsnParseCheckForWFAInfoElem() */ -+ -+#if CFG_SUPPORT_AAA -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Parse the given IE buffer and check if it is RSN IE with CCMP PSK -+* -+* \param[in] prAdapter Pointer to Adapter -+* \param[in] prSwRfb Pointer to the rx buffer -+* \param[in] pIE Pointer rthe buffer of Information Element. -+* \param[out] prStatusCode Pointer to the return status code. -+ -+* \retval none -+*/ -+/*----------------------------------------------------------------------------*/ -+void rsnParserCheckForRSNCCMPPSK(P_ADAPTER_T prAdapter, P_RSN_INFO_ELEM_T prIe, PUINT_16 pu2StatusCode) -+{ -+ -+ RSN_INFO_T rRsnIe; -+ -+ ASSERT(prAdapter); -+ ASSERT(prIe); -+ ASSERT(pu2StatusCode); -+ -+ *pu2StatusCode = STATUS_CODE_INVALID_INFO_ELEMENT; -+ -+ if (rsnParseRsnIE(prAdapter, prIe, &rRsnIe)) { -+ if ((rRsnIe.u4PairwiseKeyCipherSuiteCount != 1) -+ || (rRsnIe.au4PairwiseKeyCipherSuite[0] != RSN_CIPHER_SUITE_CCMP)) { -+ *pu2StatusCode = STATUS_CODE_INVALID_PAIRWISE_CIPHER; -+ return; -+ } -+ if (rRsnIe.u4GroupKeyCipherSuite != RSN_CIPHER_SUITE_CCMP) { -+ *pu2StatusCode = STATUS_CODE_INVALID_GROUP_CIPHER; -+ return; -+ } -+ if ((rRsnIe.u4AuthKeyMgtSuiteCount != 1) || (rRsnIe.au4AuthKeyMgtSuite[0] != RSN_AKM_SUITE_PSK)) { -+ *pu2StatusCode = STATUS_CODE_INVALID_AKMP; -+ return; -+ } -+ -+ DBGLOG(RSN, TRACE, "RSN with CCMP-PSK\n"); -+ *pu2StatusCode = WLAN_STATUS_SUCCESS; -+ } -+ -+} -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to generate an authentication event to NDIS. -+* -+* \param[in] u4Flags Authentication event: \n -+* PARAM_AUTH_REQUEST_REAUTH 0x01 \n -+* PARAM_AUTH_REQUEST_KEYUPDATE 0x02 \n -+* PARAM_AUTH_REQUEST_PAIRWISE_ERROR 0x06 \n -+* PARAM_AUTH_REQUEST_GROUP_ERROR 0x0E \n -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rsnGenMicErrorEvent(IN P_ADAPTER_T prAdapter, IN BOOLEAN fgFlags) -+{ -+ P_PARAM_AUTH_EVENT_T prAuthEvent; -+ -+ DEBUGFUNC("rsnGenMicErrorEvent"); -+ -+ prAuthEvent = (P_PARAM_AUTH_EVENT_T) prAdapter->aucIndicationEventBuffer; -+ -+ /* Status type: Authentication Event */ -+ prAuthEvent->rStatus.eStatusType = ENUM_STATUS_TYPE_AUTHENTICATION; -+ -+ /* Authentication request */ -+ prAuthEvent->arRequest[0].u4Length = sizeof(PARAM_AUTH_REQUEST_T); -+ kalMemCopy((PVOID) prAuthEvent->arRequest[0].arBssid, -+ (PVOID) prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX].aucBSSID, MAC_ADDR_LEN); -+ -+ if (fgFlags == TRUE) -+ prAuthEvent->arRequest[0].u4Flags = PARAM_AUTH_REQUEST_GROUP_ERROR; -+ else -+ prAuthEvent->arRequest[0].u4Flags = PARAM_AUTH_REQUEST_PAIRWISE_ERROR; -+ -+ kalIndicateStatusAndComplete(prAdapter->prGlueInfo, -+ WLAN_STATUS_MEDIA_SPECIFIC_INDICATION, -+ (PVOID) prAuthEvent, -+ sizeof(PARAM_STATUS_INDICATION_T) + sizeof(PARAM_AUTH_REQUEST_T)); -+ -+} /* rsnGenMicErrorEvent */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to handle TKIP MIC failures. -+* -+* \param[in] adapter_p Pointer to the adapter object data area. -+* \param[in] prSta Pointer to the STA which occur MIC Error -+* \param[in] fgErrorKeyType type of error key -+* -+* \retval none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rsnTkipHandleMICFailure(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta, IN BOOLEAN fgErrorKeyType) -+{ -+ /* UINT_32 u4RsnaCurrentMICFailTime; */ -+ /* P_AIS_SPECIFIC_BSS_INFO_T prAisSpecBssInfo; */ -+ -+ DEBUGFUNC("rsnTkipHandleMICFailure"); -+ -+ ASSERT(prAdapter); -+#if 1 -+ rsnGenMicErrorEvent(prAdapter, /* prSta, */ fgErrorKeyType); -+ -+ nicConfigPowerSaveProfile(prAdapter, NETWORK_TYPE_AIS_INDEX, Param_PowerModeCAM, FALSE); -+ -+ /* Generate authentication request event. */ -+ DBGLOG(RSN, INFO, "Generate TKIP MIC error event (type: 0%d)\n", fgErrorKeyType); -+#else -+ ASSERT(prSta); -+ -+ prAisSpecBssInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo; -+ -+ /* Record the MIC error occur time. */ -+ GET_CURRENT_SYSTIME(&u4RsnaCurrentMICFailTime); -+ -+ /* Generate authentication request event. */ -+ DBGLOG(RSN, INFO, "Generate TKIP MIC error event (type: 0%d)\n", fgErrorKeyType); -+ -+ /* If less than 60 seconds have passed since a previous TKIP MIC failure, -+ disassociate from the AP and wait for 60 seconds before (re)associating -+ with the same AP. */ -+ if (prAisSpecBssInfo->u4RsnaLastMICFailTime != 0 && -+ !CHECK_FOR_TIMEOUT(u4RsnaCurrentMICFailTime, -+ prAisSpecBssInfo->u4RsnaLastMICFailTime, SEC_TO_SYSTIME(TKIP_COUNTERMEASURE_SEC))) { -+ /* If less than 60 seconds expired since last MIC error, we have to -+ block traffic. */ -+ -+ DBGLOG(RSN, INFO, "Start blocking traffic!\n"); -+ rsnGenMicErrorEvent(prAdapter, /* prSta, */ fgErrorKeyType); -+ -+ secFsmEventStartCounterMeasure(prAdapter, prSta); -+ } else { -+ rsnGenMicErrorEvent(prAdapter, /* prSta, */ fgErrorKeyType); -+ DBGLOG(RSN, INFO, "First TKIP MIC error!\n"); -+ } -+ -+ COPY_SYSTIME(prAisSpecBssInfo->u4RsnaLastMICFailTime, u4RsnaCurrentMICFailTime); -+#endif -+} /* rsnTkipHandleMICFailure */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is called to select a list of BSSID from -+* the scan results for PMKID candidate list. -+* -+* \param[in] prBssDesc the BSS Desc at scan result list -+* \param[out] pu4CandidateCount Pointer to the number of selected candidates. -+* It is set to zero if no BSSID matches our requirement. -+* -+* \retval none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rsnSelectPmkidCandidateList(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBssDesc) -+{ -+ P_CONNECTION_SETTINGS_T prConnSettings; -+ P_AIS_BSS_INFO_T prAisBssInfo; -+ -+ DEBUGFUNC("rsnSelectPmkidCandidateList"); -+ -+ ASSERT(prBssDesc); -+ -+ prConnSettings = &prAdapter->rWifiVar.rConnSettings; -+ prAisBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]; -+ -+ /* Search a BSS with the same SSID from the given BSS description set. */ -+ /* DBGLOG(RSN, TRACE, ("Check scan result [%pM]\n", */ -+ /* prBssDesc->aucBSSID)); */ -+ -+ if (UNEQUAL_SSID(prBssDesc->aucSSID, prBssDesc->ucSSIDLen, -+ prConnSettings->aucSSID, prConnSettings->ucSSIDLen)) { -+ DBGLOG(RSN, TRACE, "-- SSID not matched\n"); -+ return; -+ } -+#if 0 -+ if ((prBssDesc->u2BSSBasicRateSet & -+ ~(rPhyAttributes[prAisBssInfo->ePhyType].u2SupportedRateSet)) || prBssDesc->fgIsUnknownBssBasicRate) { -+ DBGLOG(RSN, TRACE, "-- Rate set not matched\n"); -+ return; -+ } -+ -+ if (/* prBssDesc->u4RsnSelectedPairwiseCipher != prAisBssInfo->u4RsnSelectedPairwiseCipher || */ -+ prBssDesc->u4RsnSelectedGroupCipher != prAisBssInfo->u4RsnSelectedGroupCipher /*|| -+ prBssDesc->u4RsnSelectedAKMSuite != prAisBssInfo->u4RsnSelectedAKMSuite */) { -+ DBGLOG(RSN, TRACE, "-- Encrypt status not matched for PMKID\n"); -+ return; -+ } -+#endif -+ -+ rsnUpdatePmkidCandidateList(prAdapter, prBssDesc); -+ -+} /* rsnSelectPmkidCandidateList */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is called to select a list of BSSID from -+* the scan results for PMKID candidate list. -+* -+* \param[in] prBssDesc the BSS DESC at scan result list -+* -+* \retval none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rsnUpdatePmkidCandidateList(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBssDesc) -+{ -+ UINT_32 i; -+ P_CONNECTION_SETTINGS_T prConnSettings; -+ P_AIS_SPECIFIC_BSS_INFO_T prAisSpecBssInfo; -+ -+ DEBUGFUNC("rsnUpdatePmkidCandidateList"); -+ -+ ASSERT(prBssDesc); -+ -+ prConnSettings = &prAdapter->rWifiVar.rConnSettings; -+ prAisSpecBssInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo; -+ -+ if (UNEQUAL_SSID(prBssDesc->aucSSID, prBssDesc->ucSSIDLen, -+ prConnSettings->aucSSID, prConnSettings->ucSSIDLen)) { -+ DBGLOG(RSN, TRACE, "-- SSID not matched\n"); -+ return; -+ } -+ -+ for (i = 0; i < CFG_MAX_PMKID_CACHE; i++) { -+ if (EQUAL_MAC_ADDR(prBssDesc->aucBSSID, prAisSpecBssInfo->arPmkidCandicate[i].aucBssid)) -+ return; -+ } -+ -+ /* If the number of selected BSSID exceed MAX_NUM_PMKID_CACHE(16), -+ then we only store MAX_NUM_PMKID_CACHE(16) in PMKID cache */ -+ if ((prAisSpecBssInfo->u4PmkidCandicateCount + 1) > CFG_MAX_PMKID_CACHE) -+ prAisSpecBssInfo->u4PmkidCandicateCount--; -+ -+ i = prAisSpecBssInfo->u4PmkidCandicateCount; -+ -+ COPY_MAC_ADDR((PVOID) prAisSpecBssInfo->arPmkidCandicate[i].aucBssid, (PVOID) prBssDesc->aucBSSID); -+ -+ if (prBssDesc->u2RsnCap & MASK_RSNIE_CAP_PREAUTH) { -+ prAisSpecBssInfo->arPmkidCandicate[i].u4PreAuthFlags = 1; -+ DBGLOG(RSN, TRACE, "Add %pM with pre-auth to candidate list\n", -+ (prAisSpecBssInfo->arPmkidCandicate[i].aucBssid)); -+ } else { -+ prAisSpecBssInfo->arPmkidCandicate[i].u4PreAuthFlags = 0; -+ DBGLOG(RSN, TRACE, "Add %pM without pre-auth to candidate list\n", -+ (prAisSpecBssInfo->arPmkidCandicate[i].aucBssid)); -+ } -+ -+ prAisSpecBssInfo->u4PmkidCandicateCount++; -+ -+} /* rsnUpdatePmkidCandidateList */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to search the desired entry in -+* PMKID cache according to the BSSID -+* -+* \param[in] pucBssid Pointer to the BSSID -+* \param[out] pu4EntryIndex Pointer to place the found entry index -+* -+* \retval TRUE, if found one entry for specified BSSID -+* \retval FALSE, if not found -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN rsnSearchPmkidEntry(IN P_ADAPTER_T prAdapter, IN PUINT_8 pucBssid, OUT PUINT_32 pu4EntryIndex) -+{ -+ UINT_32 i; -+ P_AIS_SPECIFIC_BSS_INFO_T prAisSpecBssInfo; -+ -+ DEBUGFUNC("rsnSearchPmkidEntry"); -+ -+ ASSERT(pucBssid); -+ ASSERT(pu4EntryIndex); -+ -+ prAisSpecBssInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo; -+ -+ if (prAisSpecBssInfo->u4PmkidCacheCount > CFG_MAX_PMKID_CACHE) -+ return FALSE; -+ -+ ASSERT(prAisSpecBssInfo->u4PmkidCacheCount <= CFG_MAX_PMKID_CACHE); -+ -+ /* Search for desired BSSID */ -+ for (i = 0; i < prAisSpecBssInfo->u4PmkidCacheCount; i++) { -+ if (!kalMemCmp(prAisSpecBssInfo->arPmkidCache[i].rBssidInfo.arBSSID, pucBssid, MAC_ADDR_LEN)) -+ break; -+ } -+ -+ /* If desired BSSID is found, then set the PMKID */ -+ if (i < prAisSpecBssInfo->u4PmkidCacheCount) { -+ *pu4EntryIndex = i; -+ -+ return TRUE; -+ } -+ -+ return FALSE; -+} /* rsnSearchPmkidEntry */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to check if there is difference -+* between PMKID candicate list and PMKID cache. If there -+* is new candicate that no cache entry is available, then -+* add a new entry for the new candicate in the PMKID cache -+* and set the PMKID indication flag to TRUE. -+* -+* \retval TRUE, if new member in the PMKID candicate list -+* \retval FALSe, if no new member in the PMKID candicate list -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN rsnCheckPmkidCandicate(IN P_ADAPTER_T prAdapter) -+{ -+ P_AIS_SPECIFIC_BSS_INFO_T prAisSpecBssInfo; -+ UINT_32 i; /* Index for PMKID candicate */ -+ UINT_32 j; /* Indix for PMKID cache */ -+ BOOLEAN status = FALSE; -+ -+ DEBUGFUNC("rsnCheckPmkidCandicate"); -+ -+ prAisSpecBssInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo; -+ -+ /* Check for each candicate */ -+ for (i = 0; i < prAisSpecBssInfo->u4PmkidCandicateCount; i++) { -+ for (j = 0; j < prAisSpecBssInfo->u4PmkidCacheCount; j++) { -+ if (!kalMemCmp(prAisSpecBssInfo->arPmkidCache[j].rBssidInfo.arBSSID, -+ prAisSpecBssInfo->arPmkidCandicate[i].aucBssid, MAC_ADDR_LEN)) { -+ /* DBGLOG(RSN, TRACE, ("%pM at PMKID cache!!\n", -+ (prAisSpecBssInfo->arPmkidCandicate[i].aucBssid))); */ -+ break; -+ } -+ } -+ -+ /* No entry found in PMKID cache for the candicate, add new one */ -+ if (j == prAisSpecBssInfo->u4PmkidCacheCount -+ && prAisSpecBssInfo->u4PmkidCacheCount < CFG_MAX_PMKID_CACHE) { -+ DBGLOG(RSN, TRACE, -+ "Add %pM to PMKID cache!!\n", -+ (prAisSpecBssInfo->arPmkidCandicate[i].aucBssid)); -+ kalMemCopy((PVOID) prAisSpecBssInfo-> -+ arPmkidCache[prAisSpecBssInfo->u4PmkidCacheCount].rBssidInfo.arBSSID, -+ (PVOID) prAisSpecBssInfo->arPmkidCandicate[i].aucBssid, MAC_ADDR_LEN); -+ prAisSpecBssInfo->arPmkidCache[prAisSpecBssInfo->u4PmkidCacheCount].fgPmkidExist = FALSE; -+ prAisSpecBssInfo->u4PmkidCacheCount++; -+ -+ status = TRUE; -+ } -+ } -+ -+ return status; -+} /* rsnCheckPmkidCandicate */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is called to wait a duration to indicate the pre-auth AP candicate -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rsnIndicatePmkidCand(IN P_ADAPTER_T prAdapter, IN ULONG ulParm) -+{ -+ DBGLOG(RSN, EVENT, "Security - Time to indicate the PMKID cand.\n"); -+ -+ /* If the authentication mode is WPA2 and indication PMKID flag -+ is available, then we indicate the PMKID candidate list to NDIS and -+ clear the flag, indicatePMKID */ -+ -+ if (prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX].eConnectionState == PARAM_MEDIA_STATE_CONNECTED && -+ prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA2) { -+ rsnGeneratePmkidIndication(prAdapter); -+ } -+ -+} /* end of rsnIndicatePmkidCand() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to check the BSS Desc at scan result -+* with pre-auth cap at wpa2 mode. If there -+* is candicate that no cache entry is available, then -+* add a new entry for the new candicate in the PMKID cache -+* and set the PMKID indication flag to TRUE. -+* -+* \param[in] prBss The BSS Desc at scan result -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rsnCheckPmkidCache(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBss) -+{ -+ P_AIS_BSS_INFO_T prAisBssInfo; -+ P_AIS_SPECIFIC_BSS_INFO_T prAisSpecBssInfo; -+ P_CONNECTION_SETTINGS_T prConnSettings; -+ -+ DEBUGFUNC("rsnCheckPmkidCandicate"); -+ -+ ASSERT(prBss); -+ -+ prConnSettings = &prAdapter->rWifiVar.rConnSettings; -+ prAisBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]; -+ prAisSpecBssInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo; -+ -+ if ((prAisBssInfo->eConnectionState == PARAM_MEDIA_STATE_CONNECTED) && -+ (prConnSettings->eAuthMode == AUTH_MODE_WPA2)) { -+ rsnSelectPmkidCandidateList(prAdapter, prBss); -+ -+ /* Set indication flag of PMKID to TRUE, and then connHandleNetworkConnection() -+ will indicate this later */ -+ if (rsnCheckPmkidCandicate(prAdapter)) { -+ DBGLOG(RSN, TRACE, "Prepare a timer to indicate candidate PMKID Candidate\n"); -+ cnmTimerStopTimer(prAdapter, &prAisSpecBssInfo->rPreauthenticationTimer); -+ cnmTimerStartTimer(prAdapter, &prAisSpecBssInfo->rPreauthenticationTimer, -+ SEC_TO_MSEC(WAIT_TIME_IND_PMKID_CANDICATE_SEC)); -+ } -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to generate an PMKID candidate list -+* indication to NDIS. -+* -+* \param[in] prAdapter Pointer to the adapter object data area. -+* \param[in] u4Flags PMKID candidate list event: -+* PARAM_PMKID_CANDIDATE_PREAUTH_ENABLED 0x01 -+* -+* \retval none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rsnGeneratePmkidIndication(IN P_ADAPTER_T prAdapter) -+{ -+ P_PARAM_STATUS_INDICATION_T prStatusEvent; -+ P_PARAM_PMKID_CANDIDATE_LIST_T prPmkidEvent; -+ P_AIS_SPECIFIC_BSS_INFO_T prAisSpecificBssInfo; -+ UINT_8 i, j = 0, count = 0; -+ UINT_32 u4LenOfUsedBuffer; -+ -+ DEBUGFUNC("rsnGeneratePmkidIndication"); -+ -+ ASSERT(prAdapter); -+ -+ prStatusEvent = (P_PARAM_STATUS_INDICATION_T) prAdapter->aucIndicationEventBuffer; -+ -+ /* Status type: PMKID Candidatelist Event */ -+ prStatusEvent->eStatusType = ENUM_STATUS_TYPE_CANDIDATE_LIST; -+ ASSERT(prStatusEvent); -+ -+ prPmkidEvent = (P_PARAM_PMKID_CANDIDATE_LIST_T) (&prStatusEvent->eStatusType + 1); -+ ASSERT(prPmkidEvent); -+ -+ prAisSpecificBssInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo; -+ ASSERT(prAisSpecificBssInfo); -+ -+ for (i = 0; i < prAisSpecificBssInfo->u4PmkidCandicateCount; i++) { -+ for (j = 0; j < prAisSpecificBssInfo->u4PmkidCacheCount; j++) { -+ if (EQUAL_MAC_ADDR(prAisSpecificBssInfo->arPmkidCache[j].rBssidInfo.arBSSID, -+ prAisSpecificBssInfo->arPmkidCandicate[i].aucBssid) && -+ (prAisSpecificBssInfo->arPmkidCache[j].fgPmkidExist == TRUE)) { -+ break; -+ } -+ } -+ if (count >= CFG_MAX_PMKID_CACHE) -+ break; -+ -+ if (j == prAisSpecificBssInfo->u4PmkidCacheCount) { -+ kalMemCopy((PVOID) prPmkidEvent->arCandidateList[count].arBSSID, -+ (PVOID) prAisSpecificBssInfo->arPmkidCandicate[i].aucBssid, PARAM_MAC_ADDR_LEN); -+ prPmkidEvent->arCandidateList[count].u4Flags = -+ prAisSpecificBssInfo->arPmkidCandicate[i].u4PreAuthFlags; -+ DBGLOG(RSN, TRACE, "%pM %d\n", (prPmkidEvent->arCandidateList[count].arBSSID), -+ (UINT_32) prPmkidEvent->arCandidateList[count].u4Flags); -+ count++; -+ } -+ } -+ -+ /* PMKID Candidate List */ -+ prPmkidEvent->u4Version = 1; -+ prPmkidEvent->u4NumCandidates = count; -+ DBGLOG(RSN, TRACE, "rsnGeneratePmkidIndication #%d\n", (UINT_32) prPmkidEvent->u4NumCandidates); -+ u4LenOfUsedBuffer = sizeof(ENUM_STATUS_TYPE_T) + (2 * sizeof(UINT_32)) + -+ (count * sizeof(PARAM_PMKID_CANDIDATE_T)); -+ /* dumpMemory8((PUINT_8)prAdapter->aucIndicationEventBuffer, u4LenOfUsedBuffer); */ -+ -+ kalIndicateStatusAndComplete(prAdapter->prGlueInfo, -+ WLAN_STATUS_MEDIA_SPECIFIC_INDICATION, -+ (PVOID) prAdapter->aucIndicationEventBuffer, u4LenOfUsedBuffer); -+ -+} /* rsnGeneratePmkidIndication */ -+#endif -+ -+#if CFG_SUPPORT_WPS2 -+/*----------------------------------------------------------------------------*/ -+/*! -+* -+* \brief This routine is called to generate WSC IE for -+* associate request frame. -+* -+* \param[in] prCurrentBss The Selected BSS description -+* -+* \retval The append WSC IE length -+* -+* \note -+* Called by: AIS module, Associate request -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rsnGenerateWSCIE(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo) -+{ -+ PUINT_8 pucBuffer; -+ -+ ASSERT(prAdapter); -+ ASSERT(prMsduInfo); -+ -+ if (prMsduInfo->ucNetworkType != NETWORK_TYPE_AIS_INDEX) -+ return; -+ -+ pucBuffer = (PUINT_8) ((ULONG) prMsduInfo->prPacket + (UINT_32) prMsduInfo->u2FrameLength); -+ -+ /* ASSOC INFO IE ID: 221 :0xDD */ -+ if (prAdapter->prGlueInfo->u2WSCAssocInfoIELen) { -+ kalMemCopy(pucBuffer, &prAdapter->prGlueInfo->aucWSCAssocInfoIE, -+ prAdapter->prGlueInfo->u2WSCAssocInfoIELen); -+ prMsduInfo->u2FrameLength += prAdapter->prGlueInfo->u2WSCAssocInfoIELen; -+ } -+ -+} -+#endif -+ -+#if CFG_SUPPORT_802_11W -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief to check if the Bip Key installed or not -+* -+* \param[in] -+* prAdapter -+* -+* \return -+* TRUE -+* FALSE -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT_32 rsnCheckBipKeyInstalled(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec) -+{ -+ if (prStaRec && prStaRec->ucNetTypeIndex == (UINT_8) NETWORK_TYPE_AIS_INDEX) -+ return prAdapter->rWifiVar.rAisSpecificBssInfo.fgBipKeyInstalled; -+ else -+ return FALSE; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* -+* \brief This routine is called to check the Sa query timeout. -+* -+* -+* \note -+* Called by: AIS module, Handle by Sa Quert timeout -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT_8 rsnCheckSaQueryTimeout(IN P_ADAPTER_T prAdapter) -+{ -+ P_AIS_SPECIFIC_BSS_INFO_T prBssSpecInfo; -+ UINT_32 now; -+ -+ prBssSpecInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo; -+ ASSERT(prBssSpecInfo); -+ -+ GET_CURRENT_SYSTIME(&now); -+ -+ if (CHECK_FOR_TIMEOUT(now, prBssSpecInfo->u4SaQueryStart, TU_TO_MSEC(1000))) { -+ LOG_FUNC("association SA Query timed out\n"); -+ -+ prBssSpecInfo->ucSaQueryTimedOut = 1; -+ kalMemFree(prBssSpecInfo->pucSaQueryTransId, VIR_MEM_TYPE, -+ prBssSpecInfo->u4SaQueryCount * ACTION_SA_QUERY_TR_ID_LEN); -+ prBssSpecInfo->pucSaQueryTransId = NULL; -+ prBssSpecInfo->u4SaQueryCount = 0; -+ cnmTimerStopTimer(prAdapter, &prBssSpecInfo->rSaQueryTimer); -+ /* Re-connect */ -+ DBGLOG(RSN, TRACE, "DisBy11w\n"); -+ kalIndicateStatusAndComplete(prAdapter->prGlueInfo, WLAN_STATUS_MEDIA_DISCONNECT, NULL, 0); -+ -+ return 1; -+ } -+ -+ return 0; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* -+* \brief This routine is called to start the 802.11w sa query timer. -+* -+* -+* \note -+* Called by: AIS module, Handle Rx mgmt request -+*/ -+/*----------------------------------------------------------------------------*/ -+void rsnStartSaQueryTimer(IN P_ADAPTER_T prAdapter) -+{ -+ P_BSS_INFO_T prBssInfo; -+ P_AIS_SPECIFIC_BSS_INFO_T prBssSpecInfo; -+ P_MSDU_INFO_T prMsduInfo; -+ P_ACTION_SA_QUERY_FRAME prTxFrame; -+ UINT_16 u2PayloadLen; -+ PUINT_8 pucTmp = NULL; -+ UINT_8 ucTransId[ACTION_SA_QUERY_TR_ID_LEN]; -+ -+ prBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]; -+ ASSERT(prBssInfo); -+ -+ prBssSpecInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo; -+ ASSERT(prBssSpecInfo); -+ -+ LOG_FUNC("MFP: Start Sa Query\n"); -+ -+ if (prBssSpecInfo->u4SaQueryCount > 0 && rsnCheckSaQueryTimeout(prAdapter)) { -+ LOG_FUNC("MFP: u4SaQueryCount count =%d\n", prBssSpecInfo->u4SaQueryCount); -+ return; -+ } -+ -+ prMsduInfo = (P_MSDU_INFO_T) cnmMgtPktAlloc(prAdapter, MAC_TX_RESERVED_FIELD + PUBLIC_ACTION_MAX_LEN); -+ -+ if (!prMsduInfo) -+ return; -+ -+ prTxFrame = (P_ACTION_SA_QUERY_FRAME) -+ ((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD); -+ -+ prTxFrame->u2FrameCtrl = MAC_FRAME_ACTION; -+ prTxFrame->u2FrameCtrl |= MASK_FC_PROTECTED_FRAME; -+ -+ COPY_MAC_ADDR(prTxFrame->aucDestAddr, prBssInfo->aucBSSID); -+ COPY_MAC_ADDR(prTxFrame->aucSrcAddr, prBssInfo->aucOwnMacAddr); -+ COPY_MAC_ADDR(prTxFrame->aucBSSID, prBssInfo->aucBSSID); -+ -+ prTxFrame->ucCategory = CATEGORY_SA_QUERT_ACTION; -+ prTxFrame->ucAction = ACTION_SA_QUERY_REQUEST; -+ -+ if (prBssSpecInfo->u4SaQueryCount == 0) -+ GET_CURRENT_SYSTIME(&prBssSpecInfo->u4SaQueryStart); -+ -+ if (prBssSpecInfo->u4SaQueryCount) { -+ pucTmp = kalMemAlloc(prBssSpecInfo->u4SaQueryCount * ACTION_SA_QUERY_TR_ID_LEN, VIR_MEM_TYPE); -+ if (!pucTmp) { -+ DBGLOG(RSN, ERROR, "MFP: Fail to alloc tmp buffer for backup sa query id\n"); -+ return; -+ } -+ kalMemCopy(pucTmp, prBssSpecInfo->pucSaQueryTransId, -+ prBssSpecInfo->u4SaQueryCount * ACTION_SA_QUERY_TR_ID_LEN); -+ } -+ -+ kalMemFree(prBssSpecInfo->pucSaQueryTransId, VIR_MEM_TYPE, -+ prBssSpecInfo->u4SaQueryCount * ACTION_SA_QUERY_TR_ID_LEN); -+ -+ ucTransId[0] = (UINT_8) (kalRandomNumber() & 0xFF); -+ ucTransId[1] = (UINT_8) (kalRandomNumber() & 0xFF); -+ -+ kalMemCopy(prTxFrame->ucTransId, ucTransId, ACTION_SA_QUERY_TR_ID_LEN); -+ -+ prBssSpecInfo->u4SaQueryCount++; -+ -+ prBssSpecInfo->pucSaQueryTransId = -+ kalMemAlloc(prBssSpecInfo->u4SaQueryCount * ACTION_SA_QUERY_TR_ID_LEN, VIR_MEM_TYPE); -+ if (!prBssSpecInfo->pucSaQueryTransId) { -+ DBGLOG(RSN, ERROR, "MFP: Fail to alloc buffer for sa query id list\n"); -+ return; -+ } -+ -+ if (pucTmp) { -+ kalMemCopy(prBssSpecInfo->pucSaQueryTransId, pucTmp, -+ (prBssSpecInfo->u4SaQueryCount - 1) * ACTION_SA_QUERY_TR_ID_LEN); -+ kalMemCopy(&prBssSpecInfo->pucSaQueryTransId -+ [(prBssSpecInfo->u4SaQueryCount - 1) * ACTION_SA_QUERY_TR_ID_LEN], ucTransId, -+ ACTION_SA_QUERY_TR_ID_LEN); -+ kalMemFree(pucTmp, VIR_MEM_TYPE, (prBssSpecInfo->u4SaQueryCount - 1) * ACTION_SA_QUERY_TR_ID_LEN); -+ } else { -+ kalMemCopy(prBssSpecInfo->pucSaQueryTransId, ucTransId, ACTION_SA_QUERY_TR_ID_LEN); -+ } -+ -+ u2PayloadLen = 2 + ACTION_SA_QUERY_TR_ID_LEN; -+ -+ /* 4 Update information of MSDU_INFO_T */ -+ prMsduInfo->ucPacketType = HIF_TX_PACKET_TYPE_MGMT; /* Management frame */ -+ prMsduInfo->ucStaRecIndex = prBssInfo->prStaRecOfAP->ucIndex; -+ prMsduInfo->ucNetworkType = prBssInfo->ucNetTypeIndex; -+ prMsduInfo->ucMacHeaderLength = WLAN_MAC_MGMT_HEADER_LEN; -+ prMsduInfo->fgIs802_1x = FALSE; -+ prMsduInfo->fgIs802_11 = TRUE; -+ prMsduInfo->u2FrameLength = WLAN_MAC_MGMT_HEADER_LEN + u2PayloadLen; -+ prMsduInfo->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter); -+ prMsduInfo->pfTxDoneHandler = NULL; -+ prMsduInfo->fgIsBasicRate = FALSE; -+ -+ /* 4 Enqueue the frame to send this action frame. */ -+ nicTxEnqueueMsdu(prAdapter, prMsduInfo); -+ -+ DBGLOG(RSN, TRACE, -+ "Set SA Query timer %d (%d sec)\n", prBssSpecInfo->u4SaQueryCount, prBssInfo->u2ObssScanInterval); -+ -+ cnmTimerStartTimer(prAdapter, &prBssSpecInfo->rSaQueryTimer, TU_TO_MSEC(201)); -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* -+* \brief This routine is called to start the 802.11w sa query. -+* -+* -+* \note -+* Called by: AIS module, Handle Rx mgmt request -+*/ -+/*----------------------------------------------------------------------------*/ -+void rsnStartSaQuery(IN P_ADAPTER_T prAdapter) -+{ -+ rsnStartSaQueryTimer(prAdapter); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* -+* \brief This routine is called to stop the 802.11w sa query. -+* -+* -+* \note -+* Called by: AIS module, Handle Rx mgmt request -+*/ -+/*----------------------------------------------------------------------------*/ -+void rsnStopSaQuery(IN P_ADAPTER_T prAdapter) -+{ -+ P_AIS_SPECIFIC_BSS_INFO_T prBssSpecInfo; -+ -+ prBssSpecInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo; -+ ASSERT(prBssSpecInfo); -+ -+ cnmTimerStopTimer(prAdapter, &prBssSpecInfo->rSaQueryTimer); -+ kalMemFree(prBssSpecInfo->pucSaQueryTransId, VIR_MEM_TYPE, -+ prBssSpecInfo->u4SaQueryCount * ACTION_SA_QUERY_TR_ID_LEN); -+ prBssSpecInfo->pucSaQueryTransId = NULL; -+ prBssSpecInfo->u4SaQueryCount = 0; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* -+* \brief This routine is called to process the 802.11w sa query action frame. -+* -+* -+* \note -+* Called by: AIS module, Handle Rx mgmt request -+*/ -+/*----------------------------------------------------------------------------*/ -+void rsnSaQueryRequest(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb) -+{ -+ P_BSS_INFO_T prBssInfo; -+ P_MSDU_INFO_T prMsduInfo; -+ P_ACTION_SA_QUERY_FRAME prRxFrame = NULL; -+ UINT_16 u2PayloadLen; -+ P_STA_RECORD_T prStaRec; -+ P_ACTION_SA_QUERY_FRAME prTxFrame; -+ -+ prBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]; -+ ASSERT(prBssInfo); -+ -+ prRxFrame = (P_ACTION_SA_QUERY_FRAME) prSwRfb->pvHeader; -+ if (!prRxFrame) -+ return; -+ -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); -+ -+ DBGLOG(RSN, TRACE, "IEEE 802.11: Received SA Query Request from %pM\n", prStaRec->aucMacAddr); -+ -+ DBGLOG_MEM8(RSN, TRACE, prRxFrame->ucTransId, ACTION_SA_QUERY_TR_ID_LEN); -+ -+ if (kalGetMediaStateIndicated(prAdapter->prGlueInfo) == PARAM_MEDIA_STATE_DISCONNECTED) { -+ DBGLOG(RSN, TRACE, "IEEE 802.11: Ignore SA Query Request from unassociated STA %pM\n", -+ prStaRec->aucMacAddr); -+ return; -+ } -+ DBGLOG(RSN, TRACE, "IEEE 802.11: Sending SA Query Response to %pM\n", prStaRec->aucMacAddr); -+ -+ prMsduInfo = (P_MSDU_INFO_T) cnmMgtPktAlloc(prAdapter, MAC_TX_RESERVED_FIELD + PUBLIC_ACTION_MAX_LEN); -+ -+ if (!prMsduInfo) -+ return; -+ -+ prTxFrame = (P_ACTION_SA_QUERY_FRAME) -+ ((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD); -+ -+ prTxFrame->u2FrameCtrl = MAC_FRAME_ACTION; -+ /* SA Query always with protected */ -+ prTxFrame->u2FrameCtrl |= MASK_FC_PROTECTED_FRAME; -+ -+ COPY_MAC_ADDR(prTxFrame->aucDestAddr, prBssInfo->aucBSSID); -+ COPY_MAC_ADDR(prTxFrame->aucSrcAddr, prBssInfo->aucOwnMacAddr); -+ COPY_MAC_ADDR(prTxFrame->aucBSSID, prBssInfo->aucBSSID); -+ -+ prTxFrame->ucCategory = CATEGORY_SA_QUERT_ACTION; -+ prTxFrame->ucAction = ACTION_SA_QUERY_RESPONSE; -+ -+ kalMemCopy(prTxFrame->ucTransId, prRxFrame->ucTransId, ACTION_SA_QUERY_TR_ID_LEN); -+ -+ u2PayloadLen = 2 + ACTION_SA_QUERY_TR_ID_LEN; -+ -+ /* 4 Update information of MSDU_INFO_T */ -+ prMsduInfo->ucPacketType = HIF_TX_PACKET_TYPE_MGMT; /* Management frame */ -+ prMsduInfo->ucStaRecIndex = prBssInfo->prStaRecOfAP->ucIndex; -+ prMsduInfo->ucNetworkType = prBssInfo->ucNetTypeIndex; -+ prMsduInfo->ucMacHeaderLength = WLAN_MAC_MGMT_HEADER_LEN; -+ prMsduInfo->fgIs802_1x = FALSE; -+ prMsduInfo->fgIs802_11 = TRUE; -+ prMsduInfo->u2FrameLength = WLAN_MAC_MGMT_HEADER_LEN + u2PayloadLen; -+ prMsduInfo->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter); -+ prMsduInfo->pfTxDoneHandler = NULL; -+ prMsduInfo->fgIsBasicRate = FALSE; -+ -+ /* 4 Enqueue the frame to send this action frame. */ -+ nicTxEnqueueMsdu(prAdapter, prMsduInfo); -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* -+* \brief This routine is called to process the 802.11w sa query action frame. -+* -+* -+* \note -+* Called by: AIS module, Handle Rx mgmt request -+*/ -+/*----------------------------------------------------------------------------*/ -+void rsnSaQueryAction(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb) -+{ -+ P_AIS_SPECIFIC_BSS_INFO_T prBssSpecInfo; -+ P_ACTION_SA_QUERY_FRAME prRxFrame; -+ P_STA_RECORD_T prStaRec; -+ UINT_32 i; -+ -+ prBssSpecInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo; -+ ASSERT(prBssSpecInfo); -+ -+ prRxFrame = (P_ACTION_SA_QUERY_FRAME) prSwRfb->pvHeader; -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); -+ -+ if (prSwRfb->u2PacketLen < ACTION_SA_QUERY_TR_ID_LEN) { -+ DBGLOG(RSN, TRACE, "IEEE 802.11: Too short SA Query Action frame (len=%u)\n", -+ prSwRfb->u2PacketLen); -+ return; -+ } -+ -+ if (prRxFrame->ucAction == ACTION_SA_QUERY_REQUEST) { -+ rsnSaQueryRequest(prAdapter, prSwRfb); -+ return; -+ } -+ -+ if (prRxFrame->ucAction != ACTION_SA_QUERY_RESPONSE) { -+ DBGLOG(RSN, TRACE, "IEEE 802.11: Unexpected SA Query " "Action %d\n", prRxFrame->ucAction); -+ return; -+ } -+ -+ DBGLOG(RSN, TRACE, "IEEE 802.11: Received SA Query Response from %pM\n", prStaRec->aucMacAddr); -+ -+ DBGLOG_MEM8(RSN, TRACE, prRxFrame->ucTransId, ACTION_SA_QUERY_TR_ID_LEN); -+ -+ /* MLME-SAQuery.confirm */ -+ -+ for (i = 0; i < prBssSpecInfo->u4SaQueryCount; i++) { -+ if (kalMemCmp(prBssSpecInfo->pucSaQueryTransId + -+ i * ACTION_SA_QUERY_TR_ID_LEN, prRxFrame->ucTransId, ACTION_SA_QUERY_TR_ID_LEN) == 0) -+ break; -+ } -+ -+ if (i >= prBssSpecInfo->u4SaQueryCount) { -+ DBGLOG(RSN, TRACE, "IEEE 802.11: No matching SA Query " "transaction identifier found\n"); -+ return; -+ } -+ -+ DBGLOG(RSN, TRACE, "Reply to pending SA Query received\n"); -+ -+ rsnStopSaQuery(prAdapter); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* -+* \brief This routine is called to process the 802.11w mgmt frame. -+* -+* -+* \note -+* Called by: AIS module, Handle Rx mgmt request -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN rsnCheckRxMgmt(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, IN UINT_8 ucSubtype) -+{ -+ P_HIF_RX_HEADER_T prHifRxHdr; -+ BOOLEAN fgUnicast = TRUE; -+ BOOLEAN fgRobustAction = FALSE; -+ -+ prHifRxHdr = prSwRfb->prHifRxHdr; -+ -+ if ((HIF_RX_HDR_GET_NETWORK_IDX(prHifRxHdr) == NETWORK_TYPE_AIS_INDEX) && -+ prAdapter->rWifiVar.rAisSpecificBssInfo.fgMgmtProtection /* Use MFP */) { -+ -+ P_WLAN_ASSOC_REQ_FRAME_T prAssocReqFrame; -+ -+ prAssocReqFrame = (P_WLAN_ASSOC_REQ_FRAME_T) prSwRfb->pvHeader; -+ -+ if (prAssocReqFrame->aucDestAddr[0] & BIT(0)) -+ fgUnicast = FALSE; -+ -+ LOG_FUNC("QM RX MGT: rsnCheckRxMgmt = %d 0x%x %d ucSubtype=%x\n", fgUnicast, prHifRxHdr->ucReserved, -+ (prHifRxHdr->ucReserved & CONTROL_FLAG_UC_MGMT_NO_ENC), ucSubtype); -+ -+ if (prHifRxHdr->ucReserved & CONTROL_FLAG_UC_MGMT_NO_ENC) { -+ /* "Dropped unprotected Robust Action frame from an MFP STA" */ -+ /* exclude Public Action */ -+ if (ucSubtype == 13 /* 0x1011: MAC_FRAME_ACTION */) { -+ UINT_8 ucAction = *prSwRfb->pucRecvBuff; -+ -+ if (ucAction != CATEGORY_PUBLIC_ACTION && ucAction != CATEGORY_HT_ACTION) { -+#if DBG && CFG_RX_PKTS_DUMP -+ LOG_FUNC("QM RX MGT: UnProtected Robust Action frame = %d\n", ucAction); -+#endif -+ fgRobustAction = TRUE; -+ return TRUE; -+ } -+ } -+ if (fgUnicast && ((ucSubtype == 10 /* 0x1010: MAC_FRAME_DISASSOC */) -+ || (ucSubtype == 12 /* 0x1100: MAC_FRAME_DEAUTH */))) { -+ LOG_FUNC("QM RX MGT: rsnStartSaQuery\n"); -+ /* MFP test plan 5.3.3.5 */ -+ rsnStartSaQuery(prAdapter); -+ return TRUE; -+ } -+ } -+#if 0 -+ else { -+ if (fgUnicast && ((ucSubtype == MAC_FRAME_DISASSOC) || (ucSubtype == MAC_FRAME_DEAUTH))) { -+ /* This done by function handler */ -+ /* kalIndicateStatusAndComplete(prAdapter->prGlueInfo, */ -+ /* WLAN_STATUS_MEDIA_DISCONNECT, */ -+ /* NULL, */ -+ /* 0); */ -+ } -+ } -+#endif -+ } -+ return FALSE; -+} -+#endif -+ -+#if CFG_SUPPORT_DETECT_SECURITY_MODE_CHANGE -+static BOOLEAN rsnCheckWpaRsnInfo(P_BSS_INFO_T prBss, P_RSN_INFO_T prWpaRsnInfo) -+{ -+ UINT_32 i = 0; -+ -+ if (prWpaRsnInfo->u4GroupKeyCipherSuite != prBss->u4RsnSelectedGroupCipher) { -+ DBGLOG(RSN, INFO, "GroupCipherSuite change, old=0x%04x, new=0x%04x\n", -+ prBss->u4RsnSelectedGroupCipher, prWpaRsnInfo->u4GroupKeyCipherSuite); -+ return TRUE; -+ } -+ for (; i < prWpaRsnInfo->u4AuthKeyMgtSuiteCount; i++) -+ if (prBss->u4RsnSelectedAKMSuite == prWpaRsnInfo->au4AuthKeyMgtSuite[i]) -+ break; -+ if (i == prWpaRsnInfo->u4AuthKeyMgtSuiteCount) { -+ DBGLOG(RSN, INFO, "KeyMgmt change, not find 0x%04x in new beacon\n", prBss->u4RsnSelectedAKMSuite); -+ return TRUE; -+ } -+ -+ for (i = 0; i < prWpaRsnInfo->u4PairwiseKeyCipherSuiteCount; i++) -+ if (prBss->u4RsnSelectedPairwiseCipher == prWpaRsnInfo->au4PairwiseKeyCipherSuite[i]) -+ break; -+ if (i == prWpaRsnInfo->u4PairwiseKeyCipherSuiteCount) { -+ DBGLOG(RSN, INFO, "Pairwise Cipher change, not find 0x%04x in new beacon\n", -+ prBss->u4RsnSelectedPairwiseCipher); -+ return TRUE; -+ } -+ -+ return FALSE; -+} -+ -+BOOLEAN rsnCheckSecurityModeChanged(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo, P_BSS_DESC_T prBssDesc) -+{ -+ ENUM_PARAM_AUTH_MODE_T eAuthMode = prAdapter->rWifiVar.rConnSettings.eAuthMode; -+ -+ switch (eAuthMode) { -+ case AUTH_MODE_OPEN: /* original is open system */ -+ if ((prBssDesc->u2CapInfo & CAP_INFO_PRIVACY) && !prAdapter->prGlueInfo->rWpaInfo.fgPrivacyInvoke) { -+ DBGLOG(RSN, INFO, "security change, open->privacy\n"); -+ return TRUE; -+ } -+ break; -+ case AUTH_MODE_SHARED: /* original is WEP */ -+ case AUTH_MODE_AUTO_SWITCH: -+ if ((prBssDesc->u2CapInfo & CAP_INFO_PRIVACY) == 0) { -+ DBGLOG(RSN, INFO, "security change, WEP->open\n"); -+ return TRUE; -+ } else if (prBssDesc->fgIERSN || prBssDesc->fgIEWPA) { -+ DBGLOG(RSN, INFO, "security change, WEP->WPA/WPA2\n"); -+ return TRUE; -+ } -+ break; -+ case AUTH_MODE_WPA: /*original is WPA */ -+ case AUTH_MODE_WPA_PSK: -+ case AUTH_MODE_WPA_NONE: -+ if (prBssDesc->fgIEWPA) -+ return rsnCheckWpaRsnInfo(prBssInfo, &prBssDesc->rWPAInfo); -+ DBGLOG(RSN, INFO, "security change, WPA->%s\n", -+ prBssDesc->fgIERSN ? "WPA2" : -+ (prBssDesc->u2CapInfo & CAP_INFO_PRIVACY ? "WEP" : "OPEN")); -+ return TRUE; -+ case AUTH_MODE_WPA2: /*original is WPA2 */ -+ case AUTH_MODE_WPA2_PSK: -+ if (prBssDesc->fgIERSN) -+ return rsnCheckWpaRsnInfo(prBssInfo, &prBssDesc->rRSNInfo); -+ DBGLOG(RSN, INFO, "security change, WPA2->%s\n", -+ prBssDesc->fgIEWPA ? "WPA" : -+ (prBssDesc->u2CapInfo & CAP_INFO_PRIVACY ? "WEP" : "OPEN")); -+ return TRUE; -+ default: -+ DBGLOG(RSN, WARN, "unknowned eAuthMode=%d\n", eAuthMode); -+ break; -+ } -+ /*DBGLOG(RSN, INFO, ("rsnCheckSecurityModeChanged, eAuthMode=%d, u2CapInfo=0x%02x, fgIEWPA=%d, fgIERSN=%d\n", -+ eAuthMode, prBssDesc->u2CapInfo, prBssDesc->fgIEWPA, prBssDesc->fgIERSN)); */ -+ return FALSE; -+} -+#endif -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/saa_fsm.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/saa_fsm.c -new file mode 100644 -index 000000000000..596ede60d788 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/saa_fsm.c -@@ -0,0 +1,1788 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/saa_fsm.c#2 -+*/ -+ -+/*! \file "saa_fsm.c" -+ \brief This file defines the FSM for SAA MODULE. -+ -+ This file defines the FSM for SAA MODULE. -+*/ -+ -+/* -+** Log: saa_fsm.c -+** -+** 09 04 2013 cp.wu -+** fix typo -+** -+** 09 03 2013 cp.wu -+** add path for reassociation -+ * -+ * 07 17 2012 yuche.tsai -+ * NULL -+ * Compile no error before trial run. -+ * -+ * 04 20 2012 cp.wu -+ * [WCXRP00000913] [MT6620 Wi-Fi] create repository of source code dedicated for MT6620 E6 ASIC -+ * correct macro -+ * -+ * 11 24 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * Adjust code for DBG and CONFIG_XLOG. -+ * -+ * 11 11 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * modify the xlog related code. -+ * -+ * 11 04 2011 cp.wu -+ * [WCXRP00001086] [MT6620 Wi-Fi][Driver] On Android, indicate an extra DISCONNECT -+ * for REASSOCIATED cases as an explicit trigger for Android framework -+ * 1. for DEAUTH/DISASSOC cases, indicate for DISCONNECTION immediately. -+ * 2. (Android only) when reassociation-and-non-roaming cases happened, -+ * indicate an extra DISCONNECT indication to Android Wi-Fi framework -+ * -+ * 11 02 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * adding the code for XLOG. -+ * -+ * 09 30 2011 cm.chang -+ * [WCXRP00001020] [MT6620 Wi-Fi][Driver] Handle secondary channel offset of AP in 5GHz band -+ * Add debug message about 40MHz bandwidth allowed -+ * -+ * 05 12 2011 cp.wu -+ * [WCXRP00000720] [MT6620 Wi-Fi][Driver] Do not do any further operation in case STA-REC -+ * has been invalidated before SAA-FSM starts to roll -+ * check for valid STA-REC before SAA-FSM starts to roll. -+ * -+ * 04 21 2011 terry.wu -+ * [WCXRP00000674] [MT6620 Wi-Fi][Driver] Refine AAA authSendAuthFrame -+ * Add network type parameter to authSendAuthFrame. -+ * -+ * 04 15 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Add BOW short range mode. -+ * -+ * 04 14 2011 cm.chang -+ * [WCXRP00000634] [MT6620 Wi-Fi][Driver][FW] 2nd BSS will not support 40MHz bandwidth for concurrency -+ * . -+ * -+ * 03 31 2011 puff.wen -+ * NULL -+ * . -+ * -+ * 02 10 2011 yuche.tsai -+ * [WCXRP00000431] [Volunteer Patch][MT6620][Driver] Add MLME support for deauthentication under AP(Hot-Spot) mode. -+ * Add RX deauthentication & disassociation process under Hot-Spot mode. -+ * -+ * 01 26 2011 yuche.tsai -+ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record. -+ * . -+ * -+ * 01 25 2011 yuche.tsai -+ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record. -+ * Fix compile error of after Station Type Macro modification. -+ * -+ * 01 25 2011 yuche.tsai -+ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record. -+ * Change Station Type in Station Record, Modify MACRO definition for getting station type & network type index & Role. -+ * -+ * 11 29 2010 cp.wu -+ * [WCXRP00000210] [MT6620 Wi-Fi][Driver][FW] Set RCPI value in STA_REC -+ * for initial TX rate selection of auto-rate algorithm -+ * update ucRcpi of STA_RECORD_T for AIS when -+ * 1) Beacons for IBSS merge is received -+ * 2) Associate Response for a connecting peer is received -+ * -+ * 10 18 2010 cp.wu -+ * [WCXRP00000053] [MT6620 Wi-Fi][Driver] Reset incomplete -+ * and might leads to BSOD when entering RF test with AIS associated -+ * 1. remove redundant variables in STA_REC structure -+ * 2. add STA-REC uninitialization routine for clearing pending events -+ * -+ * 09 03 2010 kevin.huang -+ * NULL -+ * Refine #include sequence and solve recursive/nested #include issue -+ * -+ * 08 30 2010 cp.wu -+ * NULL -+ * eliminate klockwork errors -+ * -+ * 08 24 2010 chinghwa.yu -+ * NULL -+ * Update for MID_SCN_BOW_SCAN_DONE mboxDummy. -+ * Update saa_fsm for BOW. -+ * -+ * 08 16 2010 cp.wu -+ * NULL -+ * Replace CFG_SUPPORT_BOW by CFG_ENABLE_BT_OVER_WIFI. -+ * There is no CFG_SUPPORT_BOW in driver domain source. -+ * -+ * 08 02 2010 yuche.tsai -+ * NULL -+ * Add support for P2P join event start. -+ * -+ * 07 12 2010 cp.wu -+ * -+ * SAA will take a record for tracking request sequence number. -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 07 01 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * AIS-FSM integration with CNM channel request messages -+ * -+ * 06 23 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * sync. with main branch for resetting to state 1 when associating with another AP -+ * -+ * 06 21 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * refine TX-DONE callback. -+ * -+ * 06 21 2010 wh.su -+ * [WPD00003840][MT6620 5931] Security migration -+ * remove duplicate variable for migration. -+ * -+ * 06 18 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Provide cnmMgtPktAlloc() and alloc/free function of msg/buf -+ * -+ * 06 18 2010 wh.su -+ * [WPD00003840][MT6620 5931] Security migration -+ * migration the security related function from firmware. -+ * -+ * 06 17 2010 yuche.tsai -+ * [WPD00003839][MT6620 5931][P2P] Feature migration -+ * Fix compile error when enable WiFi Direct function. -+ * -+ * 06 14 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * saa_fsm.c is migrated. -+ * -+ * 05 12 2010 kevin.huang -+ * [BORA00000794][WIFISYS][New Feature]Power Management Support -+ * Add Power Management - Legacy PS-POLL support. -+ * -+ * 04 24 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * g_aprBssInfo[] depends on CFG_SUPPORT_P2P and CFG_SUPPORT_BOW -+ * -+ * 04 19 2010 kevin.huang -+ * [BORA00000714][WIFISYS][New Feature]Beacon Timeout Support -+ * -+ * * * Add Connection Policy - Any and Rx Burst Deauth Support for WHQL -+ * -+ * 03 10 2010 kevin.huang -+ * [BORA00000654][WIFISYS][New Feature] CNM Module - Ch Manager Support -+ * Add Channel Manager for arbitration of JOIN and SCAN Req -+ * -+ * 02 26 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Add support of Driver STA_RECORD_T activation -+ * -+ * 02 04 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Add AAA Module Support, Revise Net Type to Net Type Index for array lookup -+ * -+ * 01 27 2010 wh.su -+ * [BORA00000476][Wi-Fi][firmware] Add the security module initialize code -+ * add and fixed some security function. -+ * -+ * 01 12 2010 kevin.huang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Fix compile warning due to declared but not used -+ * -+ * 01 11 2010 kevin.huang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Add Deauth and Disassoc Handler -+ * -+ * 01 08 2010 kevin.huang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Refine Debug Label -+ * -+ * 12 18 2009 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * . -+ * -+ * Dec 3 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Update comment -+ * -+ * Dec 1 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * rename the function -+ * -+ * Nov 24 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Revise MGMT Handler with Retain Status -+ * -+ * Nov 23 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "precomp.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+#if DBG -+/*lint -save -e64 Type mismatch */ -+static PUINT_8 apucDebugAAState[AA_STATE_NUM] = { -+ (PUINT_8) DISP_STRING("AA_STATE_IDLE"), -+ (PUINT_8) DISP_STRING("SAA_STATE_SEND_AUTH1"), -+ (PUINT_8) DISP_STRING("SAA_STATE_WAIT_AUTH2"), -+ (PUINT_8) DISP_STRING("SAA_STATE_SEND_AUTH3"), -+ (PUINT_8) DISP_STRING("SAA_STATE_WAIT_AUTH4"), -+ (PUINT_8) DISP_STRING("SAA_STATE_SEND_ASSOC1"), -+ (PUINT_8) DISP_STRING("SAA_STATE_WAIT_ASSOC2"), -+ (PUINT_8) DISP_STRING("AAA_STATE_SEND_AUTH2"), -+ (PUINT_8) DISP_STRING("AAA_STATE_SEND_AUTH4"), -+ (PUINT_8) DISP_STRING("AAA_STATE_SEND_ASSOC2"), -+ (PUINT_8) DISP_STRING("AA_STATE_RESOURCE") -+}; -+ -+/*lint -restore */ -+#endif /* DBG */ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief The Core FSM engine of SAA Module. -+* -+* @param[in] prStaRec Pointer to the STA_RECORD_T -+* @param[in] eNextState The value of Next State -+* @param[in] prRetainedSwRfb Pointer to the retained SW_RFB_T for JOIN Success -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+saaFsmSteps(IN P_ADAPTER_T prAdapter, -+ IN P_STA_RECORD_T prStaRec, IN ENUM_AA_STATE_T eNextState, IN P_SW_RFB_T prRetainedSwRfb) -+{ -+ ENUM_AA_STATE_T ePreviousState; -+ BOOLEAN fgIsTransition; -+ -+ ASSERT(prStaRec); -+ if (!prStaRec) { -+ return; -+ } -+ -+ do { -+ -+#if DBG -+ DBGLOG(SAA, STATE, "TRANSITION: [%s] -> [%s]\n", -+ apucDebugAAState[prStaRec->eAuthAssocState], apucDebugAAState[eNextState]); -+#else -+ DBGLOG(SAA, STATE, "[%d] TRANSITION: [%d] -> [%d]\n", -+ DBG_SAA_IDX, prStaRec->eAuthAssocState, eNextState); -+#endif -+ ePreviousState = prStaRec->eAuthAssocState; -+ -+ /* NOTE(Kevin): This is the only place to change the eAuthAssocState(except initial) */ -+ prStaRec->eAuthAssocState = eNextState; -+ -+ fgIsTransition = (BOOLEAN) FALSE; -+ switch (prStaRec->eAuthAssocState) { -+ case AA_STATE_IDLE: -+ if (ePreviousState != prStaRec->eAuthAssocState) { /* Only trigger this event once */ -+ -+ if (prRetainedSwRfb) { -+ if (saaFsmSendEventJoinComplete(prAdapter, -+ WLAN_STATUS_SUCCESS, -+ prStaRec, -+ prRetainedSwRfb) == WLAN_STATUS_SUCCESS) { -+ /* Do nothing */ -+ } else { -+ eNextState = AA_STATE_RESOURCE; -+ fgIsTransition = TRUE; -+ } -+ } else { -+ if (saaFsmSendEventJoinComplete(prAdapter, -+ WLAN_STATUS_FAILURE, -+ prStaRec, -+ NULL) == WLAN_STATUS_RESOURCES) { -+ eNextState = AA_STATE_RESOURCE; -+ fgIsTransition = TRUE; -+ } -+ } -+ -+ } -+ -+ /* Free allocated TCM memory */ -+ if (prStaRec->prChallengeText) { -+ cnmMemFree(prAdapter, prStaRec->prChallengeText); -+ prStaRec->prChallengeText = (P_IE_CHALLENGE_TEXT_T) NULL; -+ } -+ break; -+ -+ case SAA_STATE_SEND_AUTH1: -+ { -+ /* Do tasks in INIT STATE */ -+ if (prStaRec->ucTxAuthAssocRetryCount >= prStaRec->ucTxAuthAssocRetryLimit) { -+ -+ /* Record the Status Code of Authentication Request */ -+ prStaRec->u2StatusCode = STATUS_CODE_AUTH_TIMEOUT; -+ -+ eNextState = AA_STATE_IDLE; -+ fgIsTransition = TRUE; -+ } else { -+ prStaRec->ucTxAuthAssocRetryCount++; -+ -+ /* Update Station Record - Class 1 Flag */ -+ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); -+ -+#if !CFG_SUPPORT_AAA -+ if (authSendAuthFrame(prAdapter, -+ prStaRec, AUTH_TRANSACTION_SEQ_1) != WLAN_STATUS_SUCCESS) { -+#else -+ if (authSendAuthFrame(prAdapter, -+ prStaRec, -+ prStaRec->ucNetTypeIndex, -+ NULL, -+ AUTH_TRANSACTION_SEQ_1, -+ STATUS_CODE_RESERVED) != WLAN_STATUS_SUCCESS) { -+#endif /* CFG_SUPPORT_AAA */ -+ cnmTimerInitTimer(prAdapter, -+ &prStaRec->rTxReqDoneOrRxRespTimer, -+ (PFN_MGMT_TIMEOUT_FUNC) saaFsmRunEventTxReqTimeOut, -+ (ULONG) prStaRec); -+ -+ cnmTimerStartTimer(prAdapter, -+ &prStaRec->rTxReqDoneOrRxRespTimer, -+ TU_TO_MSEC(TX_AUTHENTICATION_RETRY_TIMEOUT_TU)); -+ } -+ } -+ } -+ break; -+ -+ case SAA_STATE_WAIT_AUTH2: -+ break; -+ -+ case SAA_STATE_SEND_AUTH3: -+ { -+ /* Do tasks in INIT STATE */ -+ if (prStaRec->ucTxAuthAssocRetryCount >= prStaRec->ucTxAuthAssocRetryLimit) { -+ -+ /* Record the Status Code of Authentication Request */ -+ prStaRec->u2StatusCode = STATUS_CODE_AUTH_TIMEOUT; -+ -+ eNextState = AA_STATE_IDLE; -+ fgIsTransition = TRUE; -+ } else { -+ prStaRec->ucTxAuthAssocRetryCount++; -+ -+#if !CFG_SUPPORT_AAA -+ if (authSendAuthFrame(prAdapter, -+ prStaRec, AUTH_TRANSACTION_SEQ_3) != WLAN_STATUS_SUCCESS) { -+#else -+ if (authSendAuthFrame(prAdapter, -+ prStaRec, -+ prStaRec->ucNetTypeIndex, -+ NULL, -+ AUTH_TRANSACTION_SEQ_3, -+ STATUS_CODE_RESERVED) != WLAN_STATUS_SUCCESS) { -+#endif /* CFG_SUPPORT_AAA */ -+ -+ cnmTimerInitTimer(prAdapter, -+ &prStaRec->rTxReqDoneOrRxRespTimer, -+ (PFN_MGMT_TIMEOUT_FUNC) saaFsmRunEventTxReqTimeOut, -+ (ULONG) prStaRec); -+ -+ cnmTimerStartTimer(prAdapter, -+ &prStaRec->rTxReqDoneOrRxRespTimer, -+ TU_TO_MSEC(TX_AUTHENTICATION_RETRY_TIMEOUT_TU)); -+ } -+ } -+ } -+ break; -+ -+ case SAA_STATE_WAIT_AUTH4: -+ break; -+ -+ case SAA_STATE_SEND_ASSOC1: -+ /* Do tasks in INIT STATE */ -+ if (prStaRec->ucTxAuthAssocRetryCount >= prStaRec->ucTxAuthAssocRetryLimit) { -+ -+ /* Record the Status Code of Authentication Request */ -+ prStaRec->u2StatusCode = STATUS_CODE_ASSOC_TIMEOUT; -+ -+ eNextState = AA_STATE_IDLE; -+ fgIsTransition = TRUE; -+ } else { -+ prStaRec->ucTxAuthAssocRetryCount++; -+ -+ if (assocSendReAssocReqFrame(prAdapter, prStaRec) != WLAN_STATUS_SUCCESS) { -+ -+ cnmTimerInitTimer(prAdapter, -+ &prStaRec->rTxReqDoneOrRxRespTimer, -+ (PFN_MGMT_TIMEOUT_FUNC) saaFsmRunEventTxReqTimeOut, -+ (ULONG) prStaRec); -+ -+ cnmTimerStartTimer(prAdapter, -+ &prStaRec->rTxReqDoneOrRxRespTimer, -+ TU_TO_MSEC(TX_ASSOCIATION_RETRY_TIMEOUT_TU)); -+ } -+ } -+ -+ break; -+ -+ case SAA_STATE_WAIT_ASSOC2: -+ break; -+ -+ case AA_STATE_RESOURCE: -+ /* TODO(Kevin) Can setup a timer and send message later */ -+ break; -+ -+ default: -+ DBGLOG(SAA, ERROR, "Unknown AA STATE\n"); -+ ASSERT(0); -+ break; -+ } -+ -+ } while (fgIsTransition); -+ -+ return; -+ -+} /* end of saaFsmSteps() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will send Event to AIS/BOW/P2P -+* -+* @param[in] rJoinStatus To indicate JOIN success or failure. -+* @param[in] prStaRec Pointer to the STA_RECORD_T -+* @param[in] prSwRfb Pointer to the SW_RFB_T -+ -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+saaFsmSendEventJoinComplete(IN P_ADAPTER_T prAdapter, -+ IN WLAN_STATUS rJoinStatus, IN P_STA_RECORD_T prStaRec, IN P_SW_RFB_T prSwRfb) -+{ -+ P_BSS_INFO_T prBssInfo; -+ -+ ASSERT(prStaRec); -+ if (!prStaRec) -+ return WLAN_STATUS_INVALID_PACKET; -+ -+ /* Store limitation about 40Mhz bandwidth capability during association */ -+ if (prStaRec->ucNetTypeIndex < NETWORK_TYPE_INDEX_NUM) { -+ prBssInfo = &prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]; -+ -+ if (rJoinStatus == WLAN_STATUS_SUCCESS) -+ prBssInfo->fg40mBwAllowed = prBssInfo->fgAssoc40mBwAllowed; -+ prBssInfo->fgAssoc40mBwAllowed = FALSE; -+ } -+ -+ if (prStaRec->ucNetTypeIndex == NETWORK_TYPE_AIS_INDEX) { -+ P_MSG_SAA_FSM_COMP_T prSaaFsmCompMsg; -+ -+ prSaaFsmCompMsg = cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_SAA_FSM_COMP_T)); -+ if (!prSaaFsmCompMsg) -+ return WLAN_STATUS_RESOURCES; -+ -+ prSaaFsmCompMsg->rMsgHdr.eMsgId = MID_SAA_AIS_JOIN_COMPLETE; -+ prSaaFsmCompMsg->ucSeqNum = prStaRec->ucAuthAssocReqSeqNum; -+ prSaaFsmCompMsg->rJoinStatus = rJoinStatus; -+ prSaaFsmCompMsg->prStaRec = prStaRec; -+ prSaaFsmCompMsg->prSwRfb = prSwRfb; -+ -+ /* NOTE(Kevin): Set to UNBUF for immediately JOIN complete */ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prSaaFsmCompMsg, MSG_SEND_METHOD_UNBUF); -+ -+ return WLAN_STATUS_SUCCESS; -+ } -+#if CFG_ENABLE_WIFI_DIRECT -+ else if ((prAdapter->fgIsP2PRegistered) && (IS_STA_IN_P2P(prStaRec))) { -+ P_MSG_SAA_FSM_COMP_T prSaaFsmCompMsg; -+ -+ prSaaFsmCompMsg = cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_SAA_FSM_COMP_T)); -+ if (!prSaaFsmCompMsg) -+ return WLAN_STATUS_RESOURCES; -+ -+ prSaaFsmCompMsg->rMsgHdr.eMsgId = MID_SAA_P2P_JOIN_COMPLETE; -+ prSaaFsmCompMsg->ucSeqNum = prStaRec->ucAuthAssocReqSeqNum; -+ prSaaFsmCompMsg->rJoinStatus = rJoinStatus; -+ prSaaFsmCompMsg->prStaRec = prStaRec; -+ prSaaFsmCompMsg->prSwRfb = prSwRfb; -+ -+ /* NOTE(Kevin): Set to UNBUF for immediately JOIN complete */ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prSaaFsmCompMsg, MSG_SEND_METHOD_UNBUF); -+ -+ return WLAN_STATUS_SUCCESS; -+ } -+#endif -+#if CFG_ENABLE_BT_OVER_WIFI -+ else if (prStaRec->ucNetTypeIndex == NETWORK_TYPE_BOW_INDEX) { -+ /* @TODO: BOW handler */ -+ -+ P_MSG_SAA_FSM_COMP_T prSaaFsmCompMsg; -+ -+ prSaaFsmCompMsg = cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_SAA_FSM_COMP_T)); -+ if (!prSaaFsmCompMsg) -+ return WLAN_STATUS_RESOURCES; -+ -+ prSaaFsmCompMsg->rMsgHdr.eMsgId = MID_SAA_BOW_JOIN_COMPLETE; -+ prSaaFsmCompMsg->ucSeqNum = prStaRec->ucAuthAssocReqSeqNum; -+ prSaaFsmCompMsg->rJoinStatus = rJoinStatus; -+ prSaaFsmCompMsg->prStaRec = prStaRec; -+ prSaaFsmCompMsg->prSwRfb = prSwRfb; -+ -+ /* NOTE(Kevin): Set to UNBUF for immediately JOIN complete */ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prSaaFsmCompMsg, MSG_SEND_METHOD_UNBUF); -+ -+ return WLAN_STATUS_SUCCESS; -+ } -+#endif -+ else { -+ ASSERT(0); -+ return WLAN_STATUS_FAILURE; -+ } -+ -+} /* end of saaFsmSendEventJoinComplete() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will handle the Start Event to SAA FSM. -+* -+* @param[in] prMsgHdr Message of Join Request for a particular STA. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID saaFsmRunEventStart(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) -+{ -+ P_MSG_SAA_FSM_START_T prSaaFsmStartMsg; -+ P_STA_RECORD_T prStaRec; -+ P_BSS_INFO_T prBssInfo; -+ -+ ASSERT(prAdapter); -+ ASSERT(prMsgHdr); -+ -+ prSaaFsmStartMsg = (P_MSG_SAA_FSM_START_T) prMsgHdr; -+ prStaRec = prSaaFsmStartMsg->prStaRec; -+ -+ if ((!prStaRec) || (prStaRec->fgIsInUse == FALSE)) { -+ cnmMemFree(prAdapter, prMsgHdr); -+ return; -+ } -+ -+ ASSERT(prStaRec); -+ -+ DBGLOG(SAA, LOUD, "EVENT-START: Trigger SAA FSM.\n"); -+ -+ /* record sequence number of request message */ -+ prStaRec->ucAuthAssocReqSeqNum = prSaaFsmStartMsg->ucSeqNum; -+ -+ cnmMemFree(prAdapter, prMsgHdr); -+ -+ /* 4 <1> Validation of SAA Start Event */ -+ if (!IS_AP_STA(prStaRec)) { -+ -+ DBGLOG(SAA, ERROR, "EVENT-START: STA Type - %d was not supported.\n", prStaRec->eStaType); -+ -+ /* Ignore the return value because don't care the prSwRfb */ -+ saaFsmSendEventJoinComplete(prAdapter, WLAN_STATUS_FAILURE, prStaRec, NULL); -+ -+ return; -+ } -+ /* 4 <2> The previous JOIN process is not completed ? */ -+ if (prStaRec->eAuthAssocState != AA_STATE_IDLE) { -+ DBGLOG(SAA, ERROR, "EVENT-START: Reentry of SAA Module.\n"); -+ prStaRec->eAuthAssocState = AA_STATE_IDLE; -+ } -+ /* 4 <3> Reset Status Code and Time */ -+ /* Update Station Record - Status/Reason Code */ -+ prStaRec->u2StatusCode = STATUS_CODE_SUCCESSFUL; -+ -+ /* Update the record join time. */ -+ GET_CURRENT_SYSTIME(&prStaRec->rLastJoinTime); -+ -+ prStaRec->ucTxAuthAssocRetryCount = 0; -+ -+ if (prStaRec->prChallengeText) { -+ cnmMemFree(prAdapter, prStaRec->prChallengeText); -+ prStaRec->prChallengeText = (P_IE_CHALLENGE_TEXT_T) NULL; -+ } -+ -+ cnmTimerStopTimer(prAdapter, &prStaRec->rTxReqDoneOrRxRespTimer); -+ -+#if CFG_PRIVACY_MIGRATION -+ /* 4 <4> Init the sec fsm */ -+ secFsmInit(prAdapter, prStaRec); -+#endif -+ -+ /* 4 <5> Reset the STA STATE */ -+ /* Update Station Record - Class 1 Flag */ -+ /* NOTE(Kevin): Moved to AIS FSM for Reconnect issue - -+ * We won't deactivate the same STA_RECORD_T and then activate it again for the -+ * case of reconnection. -+ */ -+ /* cnmStaRecChangeState(prStaRec, STA_STATE_1); */ -+ -+ /* 4 <6> Decide if this BSS 20/40M bandwidth is allowed */ -+ if (prStaRec->ucNetTypeIndex < NETWORK_TYPE_INDEX_NUM) { -+ prBssInfo = &prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]; -+ -+ if ((prAdapter->rWifiVar.ucAvailablePhyTypeSet & PHY_TYPE_SET_802_11N) -+ && (prStaRec->ucPhyTypeSet & PHY_TYPE_SET_802_11N)) { -+ prBssInfo->fgAssoc40mBwAllowed = cnmBss40mBwPermitted(prAdapter, prBssInfo->ucNetTypeIndex); -+ } else { -+ prBssInfo->fgAssoc40mBwAllowed = FALSE; -+ } -+ DBGLOG(RLM, INFO, "STA 40mAllowed=%d\n", prBssInfo->fgAssoc40mBwAllowed); -+ } -+ /* 4 <7> Trigger SAA FSM */ -+ if (prStaRec->ucStaState == STA_STATE_1) -+ saaFsmSteps(prAdapter, prStaRec, SAA_STATE_SEND_AUTH1, (P_SW_RFB_T) NULL); -+ else if (prStaRec->ucStaState == STA_STATE_2 || prStaRec->ucStaState == STA_STATE_3) -+ saaFsmSteps(prAdapter, prStaRec, SAA_STATE_SEND_ASSOC1, (P_SW_RFB_T) NULL); -+ -+} /* end of saaFsmRunEventStart() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will handle TxDone(Auth1/Auth3/AssocReq) Event of SAA FSM. -+* -+* @param[in] prMsduInfo Pointer to the MSDU_INFO_T. -+* @param[in] rTxDoneStatus Return TX status of the Auth1/Auth3/AssocReq frame. -+* -+* @retval WLAN_STATUS_SUCCESS -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+saaFsmRunEventTxDone(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus) -+{ -+ -+ P_STA_RECORD_T prStaRec; -+ ENUM_AA_STATE_T eNextState; -+ -+ ASSERT(prMsduInfo); -+ -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); -+ -+ if (!prStaRec) { -+ DBGLOG(SAA, INFO, "EVENT-TX DONE: Status %d, Invalid StaRec\n", rTxDoneStatus); -+ return WLAN_STATUS_INVALID_PACKET; -+ } -+ -+ ASSERT(prStaRec); -+ -+ DBGLOG(SAA, INFO, "EVENT-TX DONE: Status: %d, eAuthAssocState: %d , SeqNO: %d ", -+ rTxDoneStatus, prStaRec->eAuthAssocState, -+ prMsduInfo->ucTxSeqNum); -+ -+ eNextState = prStaRec->eAuthAssocState; -+ -+ switch (prStaRec->eAuthAssocState) { -+ case SAA_STATE_SEND_AUTH1: -+ { -+ /* Strictly check the outgoing frame is matched with current AA STATE */ -+ if (authCheckTxAuthFrame(prAdapter, prMsduInfo, AUTH_TRANSACTION_SEQ_1) != WLAN_STATUS_SUCCESS) -+ break; -+ -+ if (rTxDoneStatus == TX_RESULT_SUCCESS) { -+ eNextState = SAA_STATE_WAIT_AUTH2; -+ -+ cnmTimerStopTimer(prAdapter, &prStaRec->rTxReqDoneOrRxRespTimer); -+ -+ cnmTimerInitTimer(prAdapter, -+ &prStaRec->rTxReqDoneOrRxRespTimer, -+ (PFN_MGMT_TIMEOUT_FUNC) saaFsmRunEventRxRespTimeOut, -+ (ULONG) prStaRec); -+ -+ cnmTimerStartTimer(prAdapter, -+ &prStaRec->rTxReqDoneOrRxRespTimer, -+ TU_TO_MSEC(DOT11_AUTHENTICATION_RESPONSE_TIMEOUT_TU)); -+ } -+ -+ /* if TX was successful, change to next state. -+ * if TX was failed, do retry if possible. -+ */ -+ saaFsmSteps(prAdapter, prStaRec, eNextState, (P_SW_RFB_T) NULL); -+ } -+ break; -+ -+ case SAA_STATE_SEND_AUTH3: -+ { -+ /* Strictly check the outgoing frame is matched with current JOIN STATE */ -+ if (authCheckTxAuthFrame(prAdapter, prMsduInfo, AUTH_TRANSACTION_SEQ_3) != WLAN_STATUS_SUCCESS) -+ break; -+ -+ if (rTxDoneStatus == TX_RESULT_SUCCESS) { -+ eNextState = SAA_STATE_WAIT_AUTH4; -+ -+ cnmTimerStopTimer(prAdapter, &prStaRec->rTxReqDoneOrRxRespTimer); -+ -+ cnmTimerInitTimer(prAdapter, -+ &prStaRec->rTxReqDoneOrRxRespTimer, -+ (PFN_MGMT_TIMEOUT_FUNC) saaFsmRunEventRxRespTimeOut, -+ (ULONG) prStaRec); -+ -+ cnmTimerStartTimer(prAdapter, -+ &prStaRec->rTxReqDoneOrRxRespTimer, -+ TU_TO_MSEC(DOT11_AUTHENTICATION_RESPONSE_TIMEOUT_TU)); -+ } -+ -+ /* if TX was successful, change to next state. -+ * if TX was failed, do retry if possible. -+ */ -+ saaFsmSteps(prAdapter, prStaRec, eNextState, (P_SW_RFB_T) NULL); -+ } -+ break; -+ -+ case SAA_STATE_SEND_ASSOC1: -+ { -+ /* Strictly check the outgoing frame is matched with current SAA STATE */ -+ if (assocCheckTxReAssocReqFrame(prAdapter, prMsduInfo) != WLAN_STATUS_SUCCESS) -+ break; -+ -+ if (rTxDoneStatus == TX_RESULT_SUCCESS) { -+ eNextState = SAA_STATE_WAIT_ASSOC2; -+ -+ cnmTimerStopTimer(prAdapter, &prStaRec->rTxReqDoneOrRxRespTimer); -+ -+ cnmTimerInitTimer(prAdapter, -+ &prStaRec->rTxReqDoneOrRxRespTimer, -+ (PFN_MGMT_TIMEOUT_FUNC) saaFsmRunEventRxRespTimeOut, -+ (ULONG) prStaRec); -+ -+ cnmTimerStartTimer(prAdapter, -+ &(prStaRec->rTxReqDoneOrRxRespTimer), -+ TU_TO_MSEC(DOT11_ASSOCIATION_RESPONSE_TIMEOUT_TU)); -+ } -+ /* if TX was successful, change to next state. -+ * if TX was failed, do retry if possible. -+ */ -+ saaFsmSteps(prAdapter, prStaRec, eNextState, (P_SW_RFB_T) NULL); -+ } -+ break; -+ -+ default: -+ break; /* Ignore other cases */ -+ } -+ -+ return WLAN_STATUS_SUCCESS; -+ -+} /* end of saaFsmRunEventTxDone() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will send Tx Request Timeout Event to SAA FSM. -+* -+* @param[in] prStaRec Pointer to the STA_RECORD_T -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID saaFsmRunEventTxReqTimeOut(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec) -+{ -+ ASSERT(prStaRec); -+ if (!prStaRec) -+ return; -+ -+ DBGLOG(SAA, LOUD, "EVENT-TIMER: TX REQ TIMEOUT, Current Time = %u\n", kalGetTimeTick()); -+ -+ switch (prStaRec->eAuthAssocState) { -+ case SAA_STATE_SEND_AUTH1: -+ case SAA_STATE_SEND_AUTH3: -+ case SAA_STATE_SEND_ASSOC1: -+ saaFsmSteps(prAdapter, prStaRec, prStaRec->eAuthAssocState, (P_SW_RFB_T) NULL); -+ break; -+ -+ default: -+ return; -+ } -+ -+} /* end of saaFsmRunEventTxReqTimeOut() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will send Rx Response Timeout Event to SAA FSM. -+* -+* @param[in] prStaRec Pointer to the STA_RECORD_T -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID saaFsmRunEventRxRespTimeOut(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec) -+{ -+ ENUM_AA_STATE_T eNextState; -+ -+ DBGLOG(SAA, LOUD, "EVENT-TIMER: RX RESP TIMEOUT, Current Time = %u\n", kalGetTimeTick()); -+ -+ ASSERT(prStaRec); -+ if (!prStaRec) -+ return; -+ -+ eNextState = prStaRec->eAuthAssocState; -+ -+ switch (prStaRec->eAuthAssocState) { -+ case SAA_STATE_WAIT_AUTH2: -+ /* Record the Status Code of Authentication Request */ -+ prStaRec->u2StatusCode = STATUS_CODE_AUTH_TIMEOUT; -+ -+ /* Pull back to earlier state to do retry */ -+ eNextState = SAA_STATE_SEND_AUTH1; -+ break; -+ -+ case SAA_STATE_WAIT_AUTH4: -+ /* Record the Status Code of Authentication Request */ -+ prStaRec->u2StatusCode = STATUS_CODE_AUTH_TIMEOUT; -+ -+ /* Pull back to earlier state to do retry */ -+ eNextState = SAA_STATE_SEND_AUTH3; -+ break; -+ -+ case SAA_STATE_WAIT_ASSOC2: -+ /* Record the Status Code of Authentication Request */ -+ prStaRec->u2StatusCode = STATUS_CODE_ASSOC_TIMEOUT; -+ -+ /* Pull back to earlier state to do retry */ -+ eNextState = SAA_STATE_SEND_ASSOC1; -+ break; -+ -+ default: -+ break; /* Ignore other cases */ -+ } -+ -+ if (eNextState != prStaRec->eAuthAssocState) -+ saaFsmSteps(prAdapter, prStaRec, eNextState, (P_SW_RFB_T) NULL); -+ -+} /* end of saaFsmRunEventRxRespTimeOut() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will process the Rx Auth Response Frame and then -+* trigger SAA FSM. -+* -+* @param[in] prSwRfb Pointer to the SW_RFB_T structure. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID saaFsmRunEventRxAuth(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb) -+{ -+ P_STA_RECORD_T prStaRec; -+ UINT_16 u2StatusCode; -+ ENUM_AA_STATE_T eNextState; -+ -+ ASSERT(prSwRfb); -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); -+ -+ /* We should have the corresponding Sta Record. */ -+ if (!prStaRec) { -+ /* Peter: we can handle the packet without station record */ -+ /* ASSERT(0); */ -+ return; -+ } -+ -+ if (!IS_AP_STA(prStaRec)) -+ return; -+ -+ switch (prStaRec->eAuthAssocState) { -+ case SAA_STATE_SEND_AUTH1: -+ case SAA_STATE_WAIT_AUTH2: -+ /* Check if the incoming frame is what we are waiting for */ -+ if (authCheckRxAuthFrameStatus(prAdapter, -+ prSwRfb, AUTH_TRANSACTION_SEQ_2, &u2StatusCode) == WLAN_STATUS_SUCCESS) { -+ -+ cnmTimerStopTimer(prAdapter, &prStaRec->rTxReqDoneOrRxRespTimer); -+ -+ /* Record the Status Code of Authentication Request */ -+ prStaRec->u2StatusCode = u2StatusCode; -+ -+ if (u2StatusCode == STATUS_CODE_SUCCESSFUL) { -+ -+ authProcessRxAuth2_Auth4Frame(prAdapter, prSwRfb); -+ -+ if (prStaRec->ucAuthAlgNum == (UINT_8) AUTH_ALGORITHM_NUM_SHARED_KEY) { -+ -+ eNextState = SAA_STATE_SEND_AUTH3; -+ } else { -+ /* Update Station Record - Class 2 Flag */ -+ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_2); -+ -+ eNextState = SAA_STATE_SEND_ASSOC1; -+ } -+ } else { -+ DBGLOG(SAA, INFO, "Auth Req was rejected by [ %pM ], Status Code = %d\n", -+ (prStaRec->aucMacAddr), u2StatusCode); -+ -+ eNextState = AA_STATE_IDLE; -+ } -+ -+ /* Reset Send Auth/(Re)Assoc Frame Count */ -+ prStaRec->ucTxAuthAssocRetryCount = 0; -+ -+ saaFsmSteps(prAdapter, prStaRec, eNextState, (P_SW_RFB_T) NULL); -+ } -+ break; -+ -+ case SAA_STATE_SEND_AUTH3: -+ case SAA_STATE_WAIT_AUTH4: -+ /* Check if the incoming frame is what we are waiting for */ -+ if (authCheckRxAuthFrameStatus(prAdapter, -+ prSwRfb, AUTH_TRANSACTION_SEQ_4, &u2StatusCode) == WLAN_STATUS_SUCCESS) { -+ -+ cnmTimerStopTimer(prAdapter, &prStaRec->rTxReqDoneOrRxRespTimer); -+ -+ /* Record the Status Code of Authentication Request */ -+ prStaRec->u2StatusCode = u2StatusCode; -+ -+ if (u2StatusCode == STATUS_CODE_SUCCESSFUL) { -+ -+ authProcessRxAuth2_Auth4Frame(prAdapter, prSwRfb); /* Add for 802.11r handling */ -+ -+ /* Update Station Record - Class 2 Flag */ -+ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_2); -+ -+ eNextState = SAA_STATE_SEND_ASSOC1; -+ } else { -+ DBGLOG(SAA, INFO, "Auth Req was rejected by [ %pM ], Status Code = %d\n", -+ (prStaRec->aucMacAddr), u2StatusCode); -+ -+ eNextState = AA_STATE_IDLE; -+ } -+ -+ /* Reset Send Auth/(Re)Assoc Frame Count */ -+ prStaRec->ucTxAuthAssocRetryCount = 0; -+ -+ saaFsmSteps(prAdapter, prStaRec, eNextState, (P_SW_RFB_T) NULL); -+ } -+ break; -+ -+ default: -+ break; /* Ignore other cases */ -+ } -+ -+} /* end of saaFsmRunEventRxAuth() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will process the Rx (Re)Association Response Frame and then -+* trigger SAA FSM. -+* -+* @param[in] prSwRfb Pointer to the SW_RFB_T structure. -+* -+* @retval WLAN_STATUS_SUCCESS if the status code was not success -+* @retval WLAN_STATUS_BUFFER_RETAINED if the status code was success -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS saaFsmRunEventRxAssoc(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb) -+{ -+ P_STA_RECORD_T prStaRec; -+ UINT_16 u2StatusCode; -+ ENUM_AA_STATE_T eNextState; -+ P_SW_RFB_T prRetainedSwRfb = (P_SW_RFB_T) NULL; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ -+ ASSERT(prSwRfb); -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); -+ -+ /* We should have the corresponding Sta Record. */ -+ if (!prStaRec) { -+ ASSERT(0); -+ return rStatus; -+ } -+ -+ if (!IS_AP_STA(prStaRec)) -+ return rStatus; -+ -+ switch (prStaRec->eAuthAssocState) { -+ case SAA_STATE_SEND_ASSOC1: -+ case SAA_STATE_WAIT_ASSOC2: -+ /* TRUE if the incoming frame is what we are waiting for */ -+ if (assocCheckRxReAssocRspFrameStatus(prAdapter, prSwRfb, &u2StatusCode) == WLAN_STATUS_SUCCESS) { -+ -+ cnmTimerStopTimer(prAdapter, &prStaRec->rTxReqDoneOrRxRespTimer); -+ -+ /* Record the Status Code of Authentication Request */ -+ prStaRec->u2StatusCode = u2StatusCode; -+ -+ if (u2StatusCode == STATUS_CODE_SUCCESSFUL) { -+ -+ /* Update Station Record - Class 3 Flag */ -+ /* NOTE(Kevin): Moved to AIS FSM for roaming issue - -+ * We should deactivate the STA_RECORD_T of previous AP before -+ * activate new one in Driver. -+ */ -+ /* cnmStaRecChangeState(prStaRec, STA_STATE_3); */ -+ -+ prStaRec->ucJoinFailureCount = 0; /* Clear history. */ -+ -+ prRetainedSwRfb = prSwRfb; -+ rStatus = WLAN_STATUS_PENDING; -+ } else { -+ DBGLOG(SAA, INFO, "Assoc Req was rejected by [ %pM ], Status Code = %d\n", -+ (prStaRec->aucMacAddr), u2StatusCode); -+ } -+ -+ /* Reset Send Auth/(Re)Assoc Frame Count */ -+ prStaRec->ucTxAuthAssocRetryCount = 0; -+ -+ /* update RCPI */ -+ prStaRec->ucRCPI = prSwRfb->prHifRxHdr->ucRcpi; -+ -+ eNextState = AA_STATE_IDLE; -+ -+ saaFsmSteps(prAdapter, prStaRec, eNextState, prRetainedSwRfb); -+ } -+ break; -+ -+ default: -+ break; /* Ignore other cases */ -+ } -+ -+ return rStatus; -+ -+} /* end of saaFsmRunEventRxAssoc() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will check the incoming Deauth Frame. -+* -+* @param[in] prSwRfb Pointer to the SW_RFB_T structure. -+* -+* @retval WLAN_STATUS_SUCCESS Always not retain deauthentication frames -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS saaFsmRunEventRxDeauth(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb) -+{ -+ P_STA_RECORD_T prStaRec; -+ P_WLAN_DEAUTH_FRAME_T prDeauthFrame; -+ -+ ASSERT(prSwRfb); -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); -+ if (prStaRec == NULL) -+ return WLAN_STATUS_FAILURE; -+ -+ prDeauthFrame = (P_WLAN_DEAUTH_FRAME_T) prSwRfb->pvHeader; -+ DBGLOG(SAA, INFO, "Rx Deauth frame from BSSID=[ %pM ].\n", prDeauthFrame->aucBSSID); -+ -+ do { -+ if (IS_STA_IN_AIS(prStaRec)) { -+ P_AIS_BSS_INFO_T prAisBssInfo; -+ -+ if (!IS_AP_STA(prStaRec)) -+ break; -+ -+ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ -+ if (prStaRec->ucStaState <= STA_STATE_1) -+ break; -+ -+ /* Check if this is the AP we are associated or associating with */ -+ if (authProcessRxDeauthFrame(prSwRfb, -+ prStaRec->aucMacAddr, -+ &prStaRec->u2ReasonCode) == WLAN_STATUS_SUCCESS) { -+ -+ DBGLOG(SAA, INFO, "Deauth reason = %d\n", prStaRec->u2ReasonCode); -+ -+ if (STA_STATE_2 <= prStaRec->ucStaState) { -+ P_MSG_AIS_ABORT_T prAisAbortMsg; -+ -+ /* NOTE(Kevin): Change state immediately to avoid starvation of -+ * MSG buffer because of too many deauth frames before changing -+ * the STA state. -+ */ -+ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); -+ -+ prAisAbortMsg = -+ (P_MSG_AIS_ABORT_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, -+ sizeof(MSG_AIS_ABORT_T)); -+ if (!prAisAbortMsg) -+ break; -+ -+ prAisAbortMsg->rMsgHdr.eMsgId = MID_SAA_AIS_FSM_ABORT; -+ prAisAbortMsg->ucReasonOfDisconnect = -+ DISCONNECT_REASON_CODE_DEAUTHENTICATED; -+ prAisAbortMsg->fgDelayIndication = FALSE; -+ -+ mboxSendMsg(prAdapter, -+ MBOX_ID_0, -+ (P_MSG_HDR_T) prAisAbortMsg, MSG_SEND_METHOD_BUF); -+ } else { -+ -+ /* TODO(Kevin): Joining Abort */ -+ } -+ prAisBssInfo->u2DeauthReason = prStaRec->u2ReasonCode; -+ -+ } -+ -+ } -+#if CFG_ENABLE_WIFI_DIRECT -+ else if (prAdapter->fgIsP2PRegistered && IS_STA_IN_P2P(prStaRec)) { -+ /* TODO(Kevin) */ -+ p2pFsmRunEventRxDeauthentication(prAdapter, prStaRec, prSwRfb); -+ } -+#endif -+#if CFG_ENABLE_BT_OVER_WIFI -+ else if (IS_STA_IN_BOW(prStaRec)) -+ bowRunEventRxDeAuth(prAdapter, prStaRec, prSwRfb); -+#endif -+ else -+ ASSERT(0); -+ -+ } while (FALSE); -+ -+ return WLAN_STATUS_SUCCESS; -+} /* end of saaFsmRunEventRxDeauth() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will check the incoming Disassociation Frame. -+* -+* @param[in] prSwRfb Pointer to the SW_RFB_T structure. -+* -+* @retval WLAN_STATUS_SUCCESS Always not retain disassociation frames -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS saaFsmRunEventRxDisassoc(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb) -+{ -+ P_STA_RECORD_T prStaRec; -+ P_WLAN_DISASSOC_FRAME_T prDisassocFrame; -+ -+ ASSERT(prSwRfb); -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); -+ if (prStaRec == NULL) -+ return WLAN_STATUS_FAILURE; -+ -+ prDisassocFrame = (P_WLAN_DISASSOC_FRAME_T) prSwRfb->pvHeader; -+ DBGLOG(SAA, INFO, "Rx Disassoc frame from BSSID=[ %pM ].\n", (prDisassocFrame->aucBSSID)); -+ -+ do { -+ if (IS_STA_IN_AIS(prStaRec)) { -+ P_AIS_BSS_INFO_T prAisBssInfo; -+ -+ if (!IS_AP_STA(prStaRec)) -+ break; -+ -+ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ -+ if (prStaRec->ucStaState <= STA_STATE_1) -+ break; -+ -+ /* Check if this is the AP we are associated or associating with */ -+ if (assocProcessRxDisassocFrame(prAdapter, -+ prSwRfb, -+ prStaRec->aucMacAddr, -+ &prStaRec->u2ReasonCode) == WLAN_STATUS_SUCCESS) { -+ -+ DBGLOG(SAA, INFO, "Disassoc reason = %d\n", prStaRec->u2ReasonCode); -+ -+ if (STA_STATE_3 <= prStaRec->ucStaState) { -+ P_MSG_AIS_ABORT_T prAisAbortMsg; -+ /* NOTE(Chaozhong): Change state immediately to avoid starvation of -+ * MSG buffer because of too many disassoc frames before changing -+ * the STA state. -+ */ -+ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_2); -+ -+ prAisAbortMsg = -+ (P_MSG_AIS_ABORT_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, -+ sizeof(MSG_AIS_ABORT_T)); -+ if (!prAisAbortMsg) -+ break; -+ -+ prAisAbortMsg->rMsgHdr.eMsgId = MID_SAA_AIS_FSM_ABORT; -+ prAisAbortMsg->ucReasonOfDisconnect = -+ DISCONNECT_REASON_CODE_DISASSOCIATED; -+ prAisAbortMsg->fgDelayIndication = FALSE; -+ -+ mboxSendMsg(prAdapter, -+ MBOX_ID_0, -+ (P_MSG_HDR_T) prAisAbortMsg, MSG_SEND_METHOD_BUF); -+ } else { -+ -+ /* TODO(Kevin): Joining Abort */ -+ } -+ prAisBssInfo->u2DeauthReason = prStaRec->u2ReasonCode; -+ -+ } -+ -+ } -+#if CFG_ENABLE_WIFI_DIRECT -+ else if (prAdapter->fgIsP2PRegistered && IS_STA_IN_P2P(prStaRec)) { -+ /* TODO(Kevin) */ -+ p2pFsmRunEventRxDisassociation(prAdapter, prStaRec, prSwRfb); -+ } -+#endif -+#if CFG_ENABLE_BT_OVER_WIFI -+ else if (IS_STA_IN_BOW(prStaRec)) { -+ /* Do nothing */ -+ /* TODO(Kevin) */ -+ } -+#endif -+ else -+ ASSERT(0); -+ -+ } while (FALSE); -+ -+ return WLAN_STATUS_SUCCESS; -+} /* end of saaFsmRunEventRxDisassoc() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will handle the Abort Event to SAA FSM. -+* -+* @param[in] prMsgHdr Message of Abort Request for a particular STA. -+* -+* @return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID saaFsmRunEventAbort(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) -+{ -+ P_MSG_SAA_FSM_ABORT_T prSaaFsmAbortMsg; -+ P_STA_RECORD_T prStaRec; -+ -+ ASSERT(prMsgHdr); -+ -+ prSaaFsmAbortMsg = (P_MSG_SAA_FSM_ABORT_T) prMsgHdr; -+ prStaRec = prSaaFsmAbortMsg->prStaRec; -+ -+ ASSERT(prStaRec); -+ if (!prStaRec) { -+ cnmMemFree(prAdapter, prMsgHdr); -+ return; -+ } -+ -+ DBGLOG(SAA, LOUD, "EVENT-ABORT: Stop SAA FSM.\n"); -+ -+ cnmMemFree(prAdapter, prMsgHdr); -+ -+ /* Reset Send Auth/(Re)Assoc Frame Count */ -+ prStaRec->ucTxAuthAssocRetryCount = 0; -+ -+ /* Cancel JOIN relative Timer */ -+ cnmTimerStopTimer(prAdapter, &prStaRec->rTxReqDoneOrRxRespTimer); -+ -+ if (prStaRec->eAuthAssocState != AA_STATE_IDLE) { -+#if DBG -+ DBGLOG(SAA, LOUD, "EVENT-ABORT: Previous Auth/Assoc State == %s.\n", -+ apucDebugAAState[prStaRec->eAuthAssocState]); -+#else -+ DBGLOG(SAA, LOUD, "EVENT-ABORT: Previous Auth/Assoc State == %d.\n", prStaRec->eAuthAssocState); -+#endif -+ } -+#if 0 -+ /* For the Auth/Assoc State to IDLE */ -+ prStaRec->eAuthAssocState = AA_STATE_IDLE; -+#else -+ /* Free this StaRec */ -+ cnmStaRecFree(prAdapter, prStaRec, FALSE); -+#endif -+ -+} /* end of saaFsmRunEventAbort() */ -+ -+/* TODO(Kevin): following code will be modified and move to AIS FSM */ -+#if 0 -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will send Join Timeout Event to JOIN FSM. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* -+* \retval WLAN_STATUS_FAILURE Fail because of Join Timeout -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS joinFsmRunEventJoinTimeOut(IN P_ADAPTER_T prAdapter) -+{ -+ P_JOIN_INFO_T prJoinInfo; -+ P_STA_RECORD_T prStaRec; -+ -+ DEBUGFUNC("joinFsmRunEventJoinTimeOut"); -+ -+ ASSERT(prAdapter); -+ prJoinInfo = &prAdapter->rJoinInfo; -+ -+ DBGLOG(JOIN, EVENT, "JOIN EVENT: JOIN TIMEOUT\n"); -+ -+ /* Get a Station Record if possible, TA == BSSID for AP */ -+ prStaRec = staRecGetStaRecordByAddr(prAdapter, prJoinInfo->prBssDesc->aucBSSID); -+ -+ /* We have renew this Sta Record when in JOIN_STATE_INIT */ -+ ASSERT(prStaRec); -+ -+ /* Record the Status Code of Authentication Request */ -+ prStaRec->u2StatusCode = STATUS_CODE_JOIN_TIMEOUT; -+ -+ /* Increase Failure Count */ -+ prStaRec->ucJoinFailureCount++; -+ -+ /* Reset Send Auth/(Re)Assoc Frame Count */ -+ prJoinInfo->ucTxAuthAssocRetryCount = 0; -+ -+ /* Cancel other JOIN relative Timer */ -+ ARB_CANCEL_TIMER(prAdapter, prJoinInfo->rTxRequestTimer); -+ -+ ARB_CANCEL_TIMER(prAdapter, prJoinInfo->rRxResponseTimer); -+ -+ /* Restore original setting from current BSS_INFO_T */ -+ if (prAdapter->eConnectionState == MEDIA_STATE_CONNECTED) -+ joinAdoptParametersFromCurrentBss(prAdapter); -+ -+ /* Pull back to IDLE */ -+ joinFsmSteps(prAdapter, JOIN_STATE_IDLE); -+ -+ return WLAN_STATUS_FAILURE; -+ -+} /* end of joinFsmRunEventJoinTimeOut() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will adopt the parameters from Peer BSS. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID joinAdoptParametersFromPeerBss(IN P_ADAPTER_T prAdapter) -+{ -+ P_JOIN_INFO_T prJoinInfo; -+ P_BSS_DESC_T prBssDesc; -+ -+ DEBUGFUNC("joinAdoptParametersFromPeerBss"); -+ -+ ASSERT(prAdapter); -+ prJoinInfo = &prAdapter->rJoinInfo; -+ prBssDesc = prJoinInfo->prBssDesc; -+ -+ /* 4 <1> Adopt Peer BSS' PHY TYPE */ -+ prAdapter->eCurrentPhyType = prBssDesc->ePhyType; -+ -+ DBGLOG(JOIN, INFO, "Target BSS[%s]'s PhyType = %s\n", -+ prBssDesc->aucSSID, (prBssDesc->ePhyType == PHY_TYPE_ERP_INDEX) ? "ERP" : "HR_DSSS"); -+ -+ /* 4 <2> Adopt Peer BSS' Frequency(Band/Channel) */ -+ DBGLOG(JOIN, INFO, "Target BSS's Channel = %d, Band = %d\n", prBssDesc->ucChannelNum, prBssDesc->eBand); -+ -+ nicSwitchChannel(prAdapter, prBssDesc->eBand, prBssDesc->ucChannelNum, 10); -+ -+ prJoinInfo->fgIsParameterAdopted = TRUE; -+ -+} /* end of joinAdoptParametersFromPeerBss() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will adopt the parameters from current associated BSS. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID joinAdoptParametersFromCurrentBss(IN P_ADAPTER_T prAdapter) -+{ -+ /* P_JOIN_INFO_T prJoinInfo = &prAdapter->rJoinInfo; */ -+ P_BSS_INFO_T prBssInfo; -+ -+ ASSERT(prAdapter); -+ prBssInfo = &prAdapter->rBssInfo; -+ -+ /* 4 <1> Adopt current BSS' PHY TYPE */ -+ prAdapter->eCurrentPhyType = prBssInfo->ePhyType; -+ -+ /* 4 <2> Adopt current BSS' Frequency(Band/Channel) */ -+ DBGLOG(JOIN, INFO, "Current BSS's Channel = %d, Band = %d\n", prBssInfo->ucChnl, prBssInfo->eBand); -+ -+ nicSwitchChannel(prAdapter, prBssInfo->eBand, prBssInfo->ucChnl, 10); -+} /* end of joinAdoptParametersFromCurrentBss() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will update all the SW variables and HW MCR registers after -+* the association with target BSS. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID joinComplete(IN P_ADAPTER_T prAdapter) -+{ -+ P_JOIN_INFO_T prJoinInfo; -+ P_BSS_DESC_T prBssDesc; -+ P_PEER_BSS_INFO_T prPeerBssInfo; -+ P_BSS_INFO_T prBssInfo; -+ P_CONNECTION_SETTINGS_T prConnSettings; -+ P_STA_RECORD_T prStaRec; -+ P_TX_CTRL_T prTxCtrl; -+#if CFG_SUPPORT_802_11D -+ P_IE_COUNTRY_T prIECountry; -+#endif -+ -+ DEBUGFUNC("joinComplete"); -+ -+ ASSERT(prAdapter); -+ prJoinInfo = &prAdapter->rJoinInfo; -+ prBssDesc = prJoinInfo->prBssDesc; -+ prPeerBssInfo = &prAdapter->rPeerBssInfo; -+ prBssInfo = &prAdapter->rBssInfo; -+ prConnSettings = &prAdapter->rConnSettings; -+ prTxCtrl = &prAdapter->rTxCtrl; -+ -+/* 4 <1> Update Connecting & Connected Flag of BSS_DESC_T. */ -+ /* Remove previous AP's Connection Flags if have */ -+ scanRemoveConnectionFlagOfBssDescByBssid(prAdapter, prBssInfo->aucBSSID); -+ -+ prBssDesc->fgIsConnected = TRUE; /* Mask as Connected */ -+ -+ if (prBssDesc->fgIsHiddenSSID) { -+ /* NOTE(Kevin): This is for the case of Passive Scan and the target BSS didn't -+ * broadcast SSID on its Beacon Frame. -+ */ -+ COPY_SSID(prBssDesc->aucSSID, -+ prBssDesc->ucSSIDLen, prAdapter->rConnSettings.aucSSID, prAdapter->rConnSettings.ucSSIDLen); -+ -+ if (prBssDesc->ucSSIDLen) -+ prBssDesc->fgIsHiddenSSID = FALSE; -+#if DBG -+ else -+ ASSERT(0); -+#endif /* DBG */ -+ -+ DBGLOG(JOIN, INFO, "Hidden SSID! - Update SSID : %s\n", prBssDesc->aucSSID); -+ } -+/* 4 <2> Update BSS_INFO_T from BSS_DESC_T */ -+ /* 4 <2.A> PHY Type */ -+ prBssInfo->ePhyType = prBssDesc->ePhyType; -+ -+ /* 4 <2.B> BSS Type */ -+ prBssInfo->eBSSType = BSS_TYPE_INFRASTRUCTURE; -+ -+ /* 4 <2.C> BSSID */ -+ COPY_MAC_ADDR(prBssInfo->aucBSSID, prBssDesc->aucBSSID); -+ -+ DBGLOG(JOIN, INFO, "JOIN to BSSID: [%pM]\n", prBssDesc->aucBSSID); -+ -+ /* 4 <2.D> SSID */ -+ COPY_SSID(prBssInfo->aucSSID, prBssInfo->ucSSIDLen, prBssDesc->aucSSID, prBssDesc->ucSSIDLen); -+ -+ /* 4 <2.E> Channel / Band information. */ -+ prBssInfo->eBand = prBssDesc->eBand; -+ prBssInfo->ucChnl = prBssDesc->ucChannelNum; -+ -+ /* 4 <2.F> RSN/WPA information. */ -+ secFsmRunEventStart(prAdapter); -+ prBssInfo->u4RsnSelectedPairwiseCipher = prBssDesc->u4RsnSelectedPairwiseCipher; -+ prBssInfo->u4RsnSelectedGroupCipher = prBssDesc->u4RsnSelectedGroupCipher; -+ prBssInfo->u4RsnSelectedAKMSuite = prBssDesc->u4RsnSelectedAKMSuite; -+ -+ if (secRsnKeyHandshakeEnabled()) -+ prBssInfo->fgIsWPAorWPA2Enabled = TRUE; -+ else -+ prBssInfo->fgIsWPAorWPA2Enabled = FALSE; -+ -+ /* 4 <2.G> Beacon interval. */ -+ prBssInfo->u2BeaconInterval = prBssDesc->u2BeaconInterval; -+ -+ /* 4 <2.H> DTIM period. */ -+ prBssInfo->ucDtimPeriod = prBssDesc->ucDTIMPeriod; -+ -+ /* 4 <2.I> ERP Information */ -+ if ((prBssInfo->ePhyType == PHY_TYPE_ERP_INDEX) && /* Our BSS's PHY_TYPE is ERP now. */ -+ (prBssDesc->fgIsERPPresent)) { -+ -+ prBssInfo->fgIsERPPresent = TRUE; -+ prBssInfo->ucERP = prBssDesc->ucERP; /* Save the ERP for later check */ -+ } else { /* Some AP, may send ProbeResp without ERP IE. Thus prBssDesc->fgIsERPPresent is FALSE. */ -+ prBssInfo->fgIsERPPresent = FALSE; -+ prBssInfo->ucERP = 0; -+ } -+ -+#if CFG_SUPPORT_802_11D -+ /* 4 <2.J> Country inforamtion of the associated AP */ -+ if (prConnSettings->fgMultiDomainCapabilityEnabled) { -+ DOMAIN_INFO_ENTRY rDomainInfo; -+ -+ if (domainGetDomainInfoByScanResult(prAdapter, &rDomainInfo)) { -+ if (prBssDesc->prIECountry) { -+ prIECountry = prBssDesc->prIECountry; -+ -+ domainParseCountryInfoElem(prIECountry, &prBssInfo->rDomainInfo); -+ -+ /* use the domain get from the BSS info */ -+ prBssInfo->fgIsCountryInfoPresent = TRUE; -+ nicSetupOpChnlList(prAdapter, prBssInfo->rDomainInfo.u2CountryCode, FALSE); -+ } else { -+ /* use the domain get from the scan result */ -+ prBssInfo->fgIsCountryInfoPresent = TRUE; -+ nicSetupOpChnlList(prAdapter, rDomainInfo.u2CountryCode, FALSE); -+ } -+ } -+ } -+#endif -+ -+ /* 4 <2.K> Signal Power of the associated AP */ -+ prBssInfo->rRcpi = prBssDesc->rRcpi; -+ prBssInfo->rRssi = RCPI_TO_dBm(prBssInfo->rRcpi); -+ GET_CURRENT_SYSTIME(&prBssInfo->rRssiLastUpdateTime); -+ -+ /* 4 <2.L> Capability Field of the associated AP */ -+ prBssInfo->u2CapInfo = prBssDesc->u2CapInfo; -+ -+ DBGLOG(JOIN, INFO, "prBssInfo-> fgIsERPPresent = %d, ucERP = %02x, rRcpi = %d, rRssi = %ld\n", -+ prBssInfo->fgIsERPPresent, prBssInfo->ucERP, prBssInfo->rRcpi, prBssInfo->rRssi); -+ -+/* 4 <3> Update BSS_INFO_T from PEER_BSS_INFO_T & NIC RATE FUNC */ -+ /* 4 <3.A> Association ID */ -+ prBssInfo->u2AssocId = prPeerBssInfo->u2AssocId; -+ -+ /* 4 <3.B> WMM Information */ -+ if (prAdapter->fgIsEnableWMM && (prPeerBssInfo->rWmmInfo.ucWmmFlag & WMM_FLAG_SUPPORT_WMM)) { -+ -+ prBssInfo->fgIsWmmAssoc = TRUE; -+ prTxCtrl->rTxQForVoipAccess = TXQ_AC3; -+ -+ qosWmmInfoInit(&prBssInfo->rWmmInfo, (prBssInfo->ePhyType == PHY_TYPE_HR_DSSS_INDEX) ? TRUE : FALSE); -+ -+ if (prPeerBssInfo->rWmmInfo.ucWmmFlag & WMM_FLAG_AC_PARAM_PRESENT) { -+ kalMemCopy(&prBssInfo->rWmmInfo, &prPeerBssInfo->rWmmInfo, sizeof(WMM_INFO_T)); -+ } else { -+ kalMemCopy(&prBssInfo->rWmmInfo, -+ &prPeerBssInfo->rWmmInfo, -+ sizeof(WMM_INFO_T) - sizeof(prPeerBssInfo->rWmmInfo.arWmmAcParams)); -+ } -+ } else { -+ prBssInfo->fgIsWmmAssoc = FALSE; -+ prTxCtrl->rTxQForVoipAccess = TXQ_AC1; -+ -+ kalMemZero(&prBssInfo->rWmmInfo, sizeof(WMM_INFO_T)); -+ } -+ -+ /* 4 <3.C> Operational Rate Set & BSS Basic Rate Set */ -+ prBssInfo->u2OperationalRateSet = prPeerBssInfo->u2OperationalRateSet; -+ prBssInfo->u2BSSBasicRateSet = prPeerBssInfo->u2BSSBasicRateSet; -+ -+ /* 4 <3.D> Short Preamble */ -+ if (prBssInfo->fgIsERPPresent) { -+ -+ /* NOTE(Kevin 2007/12/24): Truth Table. -+ * Short Preamble Bit in -+ * Final Driver Setting(Short) -+ * TRUE FALSE FALSE FALSE(shouldn't have such case, use the AssocResp) -+ * TRUE FALSE TRUE FALSE -+ * FALSE FALSE FALSE FALSE(shouldn't have such case, use the AssocResp) -+ * FALSE FALSE TRUE FALSE -+ * TRUE TRUE FALSE TRUE(follow ERP) -+ * TRUE TRUE TRUE FALSE(follow ERP) -+ * FALSE TRUE FALSE FALSE(shouldn't have such case, and we should set to FALSE) -+ * FALSE TRUE TRUE FALSE(we should set to FALSE) -+ */ -+ if ((prPeerBssInfo->fgIsShortPreambleAllowed) && -+ ((prConnSettings->ePreambleType == PREAMBLE_TYPE_SHORT) || -+ ((prConnSettings->ePreambleType == PREAMBLE_TYPE_AUTO) && -+ (prBssDesc->u2CapInfo & CAP_INFO_SHORT_PREAMBLE)))) { -+ -+ prBssInfo->fgIsShortPreambleAllowed = TRUE; -+ -+ if (prBssInfo->ucERP & ERP_INFO_BARKER_PREAMBLE_MODE) -+ prBssInfo->fgUseShortPreamble = FALSE; -+ else -+ prBssInfo->fgUseShortPreamble = TRUE; -+ } else { -+ prBssInfo->fgIsShortPreambleAllowed = FALSE; -+ prBssInfo->fgUseShortPreamble = FALSE; -+ } -+ } else { -+ /* NOTE(Kevin 2007/12/24): Truth Table. -+ * Short Preamble Bit in -+ * Final Driver Setting(Short) -+ * TRUE FALSE FALSE -+ * FALSE FALSE FALSE -+ * TRUE TRUE TRUE -+ * FALSE TRUE(status success) TRUE -+ * --> Honor the result of prPeerBssInfo. -+ */ -+ -+ prBssInfo->fgIsShortPreambleAllowed = prBssInfo->fgUseShortPreamble = -+ prPeerBssInfo->fgIsShortPreambleAllowed; -+ } -+ -+ DBGLOG(JOIN, INFO, "prBssInfo->fgIsShortPreambleAllowed = %d, prBssInfo->fgUseShortPreamble = %d\n", -+ prBssInfo->fgIsShortPreambleAllowed, prBssInfo->fgUseShortPreamble); -+ -+ /* 4 <3.E> Short Slot Time */ -+ prBssInfo->fgUseShortSlotTime = prPeerBssInfo->fgUseShortSlotTime; /* AP support Short Slot Time */ -+ -+ DBGLOG(JOIN, INFO, "prBssInfo->fgUseShortSlotTime = %d\n", prBssInfo->fgUseShortSlotTime); -+ -+ nicSetSlotTime(prAdapter, -+ prBssInfo->ePhyType, -+ ((prConnSettings->fgIsShortSlotTimeOptionEnable && -+ prBssInfo->fgUseShortSlotTime) ? TRUE : FALSE)); -+ -+ /* 4 <3.F> Update Tx Rate for Control Frame */ -+ bssUpdateTxRateForControlFrame(prAdapter); -+ -+ /* 4 <3.G> Save the available Auth Types during Roaming (Design for Fast BSS Transition). */ -+ /* if (prAdapter->fgIsEnableRoaming) */ /* NOTE(Kevin): Always prepare info for roaming */ -+ { -+ -+ if (prJoinInfo->ucCurrAuthAlgNum == AUTH_ALGORITHM_NUM_OPEN_SYSTEM) -+ prJoinInfo->ucRoamingAuthTypes |= AUTH_TYPE_OPEN_SYSTEM; -+ else if (prJoinInfo->ucCurrAuthAlgNum == AUTH_ALGORITHM_NUM_SHARED_KEY) -+ prJoinInfo->ucRoamingAuthTypes |= AUTH_TYPE_SHARED_KEY; -+ -+ prBssInfo->ucRoamingAuthTypes = prJoinInfo->ucRoamingAuthTypes; -+ -+ /* Set the stable time of the associated BSS. We won't do roaming decision -+ * during the stable time. -+ */ -+ SET_EXPIRATION_TIME(prBssInfo->rRoamingStableExpirationTime, -+ SEC_TO_SYSTIME(ROAMING_STABLE_TIMEOUT_SEC)); -+ } -+ -+ /* 4 <3.H> Update Parameter for TX Fragmentation Threshold */ -+#if CFG_TX_FRAGMENT -+ txFragInfoUpdate(prAdapter); -+#endif /* CFG_TX_FRAGMENT */ -+ -+/* 4 <4> Update STA_RECORD_T */ -+ /* Get a Station Record if possible */ -+ prStaRec = staRecGetStaRecordByAddr(prAdapter, prBssDesc->aucBSSID); -+ -+ if (prStaRec) { -+ UINT_16 u2OperationalRateSet, u2DesiredRateSet; -+ -+ /* 4 <4.A> Desired Rate Set */ -+ u2OperationalRateSet = (rPhyAttributes[prBssInfo->ePhyType].u2SupportedRateSet & -+ prBssInfo->u2OperationalRateSet); -+ -+ u2DesiredRateSet = (u2OperationalRateSet & prConnSettings->u2DesiredRateSet); -+ if (u2DesiredRateSet) { -+ prStaRec->u2DesiredRateSet = u2DesiredRateSet; -+ } else { -+ /* For Error Handling - The Desired Rate Set is not covered in Operational Rate Set. */ -+ prStaRec->u2DesiredRateSet = u2OperationalRateSet; -+ } -+ -+ /* Try to set the best initial rate for this entry */ -+ if (!rateGetBestInitialRateIndex(prStaRec->u2DesiredRateSet, -+ prStaRec->rRcpi, &prStaRec->ucCurrRate1Index)) { -+ -+ if (!rateGetLowestRateIndexFromRateSet(prStaRec->u2DesiredRateSet, &prStaRec->ucCurrRate1Index)) -+ ASSERT(0); -+ } -+ -+ DBGLOG(JOIN, INFO, "prStaRec->ucCurrRate1Index = %d\n", prStaRec->ucCurrRate1Index); -+ -+ /* 4 <4.B> Preamble Mode */ -+ prStaRec->fgIsShortPreambleOptionEnable = prBssInfo->fgUseShortPreamble; -+ -+ /* 4 <4.C> QoS Flag */ -+ prStaRec->fgIsQoS = prBssInfo->fgIsWmmAssoc; -+ } -+#if DBG -+ else -+ ASSERT(0); -+#endif /* DBG */ -+ -+/* 4 <5> Update NIC */ -+ /* 4 <5.A> Update BSSID & Operation Mode */ -+ nicSetupBSS(prAdapter, prBssInfo); -+ -+ /* 4 <5.B> Update WLAN Table. */ -+ if (nicSetHwBySta(prAdapter, prStaRec) == FALSE) -+ ASSERT(FALSE); -+ /* 4 <5.C> Update Desired Rate Set for BT. */ -+#if CFG_TX_FRAGMENT -+ if (prConnSettings->fgIsEnableTxAutoFragmentForBT) -+ txRateSetInitForBT(prAdapter, prStaRec); -+#endif /* CFG_TX_FRAGMENT */ -+ -+ /* 4 <5.D> TX AC Parameter and TX/RX Queue Control */ -+ if (prBssInfo->fgIsWmmAssoc) { -+ -+#if CFG_TX_AGGREGATE_HW_FIFO -+ nicTxAggregateTXQ(prAdapter, FALSE); -+#endif /* CFG_TX_AGGREGATE_HW_FIFO */ -+ -+ qosUpdateWMMParametersAndAssignAllowedACI(prAdapter, &prBssInfo->rWmmInfo); -+ } else { -+ -+#if CFG_TX_AGGREGATE_HW_FIFO -+ nicTxAggregateTXQ(prAdapter, TRUE); -+#endif /* CFG_TX_AGGREGATE_HW_FIFO */ -+ -+ nicTxNonQoSAssignDefaultAdmittedTXQ(prAdapter); -+ -+ nicTxNonQoSUpdateTXQParameters(prAdapter, prBssInfo->ePhyType); -+ } -+ -+#if CFG_TX_STOP_WRITE_TX_FIFO_UNTIL_JOIN -+ { -+ prTxCtrl->fgBlockTxDuringJoin = FALSE; -+ -+#if !CFG_TX_AGGREGATE_HW_FIFO /* TX FIFO AGGREGATE already do flush once */ -+ nicTxFlushStopQueues(prAdapter, (UINT_8) TXQ_DATA_MASK, (UINT_8) NULL); -+#endif /* CFG_TX_AGGREGATE_HW_FIFO */ -+ -+ nicTxRetransmitOfSendWaitQue(prAdapter); -+ -+ if (prTxCtrl->fgIsPacketInOsSendQueue) -+ nicTxRetransmitOfOsSendQue(prAdapter); -+#if CFG_SDIO_TX_ENHANCE -+ halTxLeftClusteredMpdu(prAdapter); -+#endif /* CFG_SDIO_TX_ENHANCE */ -+ -+ } -+#endif /* CFG_TX_STOP_WRITE_TX_FIFO_UNTIL_JOIN */ -+ -+/* 4 <6> Setup CONNECTION flag. */ -+ prAdapter->eConnectionState = MEDIA_STATE_CONNECTED; -+ prAdapter->eConnectionStateIndicated = MEDIA_STATE_CONNECTED; -+ -+ if (prJoinInfo->fgIsReAssoc) -+ prAdapter->fgBypassPortCtrlForRoaming = TRUE; -+ else -+ prAdapter->fgBypassPortCtrlForRoaming = FALSE; -+ -+ kalIndicateStatusAndComplete(prAdapter->prGlueInfo, WLAN_STATUS_MEDIA_CONNECT, (PVOID) NULL, 0); -+ -+} /* end of joinComplete() */ -+#endif -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/scan.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/scan.c -new file mode 100644 -index 000000000000..2c9ccbe82dd1 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/scan.c -@@ -0,0 +1,3103 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/scan.c#3 -+*/ -+ -+/*! \file "scan.c" -+ \brief This file defines the scan profile and the processing function of -+ scan result for SCAN Module. -+ -+ The SCAN Profile selection is part of SCAN MODULE and responsible for defining -+ SCAN Parameters - e.g. MIN_CHANNEL_TIME, number of scan channels. -+ In this file we also define the process of SCAN Result including adding, searching -+ and removing SCAN record from the list. -+*/ -+ -+/* -+** Log: scan.c -+** -+** 01 30 2013 yuche.tsai -+** [ALPS00451578] [JB2][WFD][Case Fail][JE][MR1]?????????[Java (JE),660,-1361051648,99, -+** /data/core/,0,system_server_crash,system_server]JE happens when try to connect WFD.(4/5) -+** Fix possible old scan result indicate to supplicant after formation. -+** -+** 01 16 2013 yuche.tsai -+** [ALPS00431980] [WFD]Aupus one ?play game 10 minitues?wfd connection automaticlly disconnect -+** Fix possible FW assert issue. -+ * -+ * 07 17 2012 yuche.tsai -+ * NULL -+ * Let netdev bring up. -+ * -+ * 07 17 2012 yuche.tsai -+ * NULL -+ * Compile no error before trial run. -+ * -+ * 06 25 2012 cp.wu -+ * [WCXRP00001258] [MT6620][MT5931][MT6628][Driver] Do not use stale scan result for deciding connection target -+ * drop off scan result which is older than 5 seconds when choosing which BSS to join -+ * -+ * 03 02 2012 terry.wu -+ * NULL -+ * Sync CFG80211 modification from branch 2,2. -+ * -+ * 01 16 2012 cp.wu -+ * [WCXRP00001169] [MT6620 Wi-Fi][Driver] API and behavior modification for preferred band -+ * configuration with corresponding network configuration -+ * correct typo. -+ * -+ * 01 16 2012 cp.wu -+ * [MT6620 Wi-Fi][Driver] API and behavior modification for preferred band configuration -+ * with corresponding network configuration -+ * add wlanSetPreferBandByNetwork() for glue layer to invoke for setting preferred -+ * band configuration corresponding to network type. -+ * -+ * 12 05 2011 cp.wu -+ * [WCXRP00001131] [MT6620 Wi-Fi][Driver][AIS] Implement connect-by-BSSID path -+ * add CONNECT_BY_BSSID policy -+ * -+ * 11 23 2011 cp.wu -+ * [WCXRP00001123] [MT6620 Wi-Fi][Driver] Add option to disable beacon content change detection -+ * add compile option to disable beacon content change detection. -+ * -+ * 11 04 2011 cp.wu -+ * [WCXRP00001085] [MT6628 Wi-Fi][Driver] deprecate old BSS-DESC if timestamp -+ * is reset with received beacon/probe response frames -+ * deprecate old BSS-DESC when timestamp in received beacon/probe response frames showed a smaller value than before -+ * -+ * 10 11 2011 cm.chang -+ * [WCXRP00001031] [All Wi-Fi][Driver] Check HT IE length to avoid wrong SCO parameter -+ * Ignore HT OP IE if its length field is not valid -+ * -+ * 09 30 2011 cp.wu -+ * [WCXRP00001021] [MT5931][Driver] Correct scan result generation for conversion between BSS type and operation mode -+ * correct type casting issue. -+ * -+ * 08 23 2011 yuche.tsai -+ * NULL -+ * Fix multicast address list issue. -+ * -+ * 08 11 2011 cp.wu -+ * [WCXRP00000830] [MT6620 Wi-Fi][Firmware] Use MDRDY counter to detect empty channel for shortening scan time -+ * sparse channel detection: -+ * driver: collect sparse channel information with scan-done event -+ * -+ * 08 10 2011 cp.wu -+ * [WCXRP00000922] [MT6620 Wi-Fi][Driver] traverse whole BSS-DESC list for removing -+ * traverse whole BSS-DESC list because BSSID is not unique anymore. -+ * -+ * 07 12 2011 cp.wu -+ * [WCXRP00000815] [MT6620 Wi-Fi][Driver] allow single BSSID with multiple -+ * SSID settings to work around some tricky AP which use space character as hidden SSID -+ * for multiple BSS descriptior detecting issue: -+ * 1) check BSSID for infrastructure network -+ * 2) check SSID for AdHoc network -+ * -+ * 07 12 2011 cp.wu -+ * [WCXRP00000815] [MT6620 Wi-Fi][Driver] allow single BSSID with multiple -+ * SSID settings to work around some tricky AP which use space character as hidden SSID -+ * check for BSSID for beacons used to update DTIM -+ * -+ * 07 12 2011 cp.wu -+ * [WCXRP00000815] [MT6620 Wi-Fi][Driver] allow single BSSID with multiple -+ * SSID settings to work around some tricky AP which use space character as hidden SSID -+ * do not check BSS descriptor for connected flag due to linksys's hidden -+ * SSID will use another BSS descriptor and never connected -+ * -+ * 07 11 2011 cp.wu -+ * [WCXRP00000815] [MT6620 Wi-Fi][Driver] allow single BSSID with multiple -+ * SSID settings to work around some tricky AP which use space character as hidden SSID -+ * just pass beacons with the same BSSID. -+ * -+ * 07 11 2011 wh.su -+ * [WCXRP00000849] [MT6620 Wi-Fi][Driver] Remove some of the WAPI define -+ * for make sure the value is initialize, for customer not enable WAPI -+ * For make sure wapi initial value is set. -+ * -+ * 06 28 2011 cp.wu -+ * [WCXRP00000815] [MT6620 Wi-Fi][Driver] allow single BSSID with multiple -+ * SSID settings to work around some tricky AP which use space character as hidden SSID -+ * Do not check for SSID as beacon content change due to the existence of -+ * single BSSID with multiple SSID AP configuration -+ * -+ * 06 27 2011 cp.wu -+ * [WCXRP00000815] [MT6620 Wi-Fi][Driver] allow single BSSID with multiple -+ * SSID settings to work around some tricky AP which use space character as hidden SSID -+ * 1. correct logic -+ * 2. replace only BSS-DESC which doesn't have a valid SSID. -+ * -+ * 06 27 2011 cp.wu -+ * [WCXRP00000815] [MT6620 Wi-Fi][Driver] allow single BSSID with multiple SSID -+ * settings to work around some tricky AP which use space character as hidden SSID -+ * remove unused temporal variable reference. -+ * -+ * 06 27 2011 cp.wu -+ * [WCXRP00000815] [MT6620 Wi-Fi][Driver] allow single BSSID with multiple SSID -+ * settings to work around some tricky AP which use space character as hidden SSID -+ * allow to have a single BSSID with multiple SSID to be presented in scanning result -+ * -+ * 06 02 2011 cp.wu -+ * [WCXRP00000757] [MT6620 Wi-Fi][Driver][SCN] take use of RLM API to filter out BSS in disallowed channels -+ * filter out BSS in disallowed channel by -+ * 1. do not add to scan result array if BSS is at disallowed channel -+ * 2. do not allow to search for BSS-DESC in disallowed channels -+ * -+ * 05 02 2011 cm.chang -+ * [WCXRP00000691] [MT6620 Wi-Fi][Driver] Workaround about AP's wrong HT capability IE to have wrong channel number -+ * Refine range of valid channel number -+ * -+ * 05 02 2011 cp.wu -+ * [MT6620 Wi-Fi][Driver] Take parsed result for channel information instead of -+ * hardware channel number passed from firmware domain -+ * take parsed result for generating scanning result with channel information. -+ * -+ * 05 02 2011 cm.chang -+ * [WCXRP00000691] [MT6620 Wi-Fi][Driver] Workaround about AP's wrong HT capability IE to have wrong channel number -+ * Check if channel is valided before record ing BSS channel -+ * -+ * 04 18 2011 terry.wu -+ * [WCXRP00000660] [MT6620 Wi-Fi][Driver] Remove flag CFG_WIFI_DIRECT_MOVED -+ * Remove flag CFG_WIFI_DIRECT_MOVED. -+ * -+ * 04 14 2011 cm.chang -+ * [WCXRP00000634] [MT6620 Wi-Fi][Driver][FW] 2nd BSS will not support 40MHz bandwidth for concurrency -+ * . -+ * -+ * 04 12 2011 eddie.chen -+ * [WCXRP00000617] [MT6620 Wi-Fi][DRV/FW] Fix for sigma -+ * Fix the sta index in processing security frame -+ * Simple flow control for TC4 to avoid mgt frames for PS STA to occupy the TC4 -+ * Add debug message. -+ * -+ * 03 25 2011 yuche.tsai -+ * NULL -+ * Always update Bss Type, for Bss Type for P2P Network is changing every time. -+ * -+ * 03 23 2011 yuche.tsai -+ * NULL -+ * Fix concurrent issue when AIS scan result would overwrite p2p scan result. -+ * -+ * 03 14 2011 cp.wu -+ * [WCXRP00000535] [MT6620 Wi-Fi][Driver] Fixed channel operation when AIS and Tethering are operating concurrently -+ * filtering out other BSS coming from adjacent channels -+ * -+ * 03 11 2011 chinglan.wang -+ * [WCXRP00000537] [MT6620 Wi-Fi][Driver] Can not connect to 802.11b/g/n mixed AP with WEP security. -+ * . -+ * -+ * 03 11 2011 cp.wu -+ * [WCXRP00000535] [MT6620 Wi-Fi][Driver] Fixed channel operation when AIS and Tethering are operating concurrently -+ * When fixed channel operation is necessary, AIS-FSM would scan and only connect for BSS on the specific channel -+ * -+ * 02 24 2011 cp.wu -+ * [WCXRP00000490] [MT6620 Wi-Fi][Driver][Win32] modify kalMsleep() implementation because NdisMSleep() -+ * won't sleep long enough for specified interval such as 500ms -+ * implement beacon change detection by checking SSID and supported rate. -+ * -+ * 02 22 2011 yuche.tsai -+ * [WCXRP00000480] [Volunteer Patch][MT6620][Driver] WCS IE format issue -+ * Fix WSC big endian issue. -+ * -+ * 02 21 2011 terry.wu -+ * [WCXRP00000476] [MT6620 Wi-Fi][Driver] Clean P2P scan list while removing P2P -+ * Clean P2P scan list while removing P2P. -+ * -+ * 01 27 2011 yuche.tsai -+ * [WCXRP00000399] [Volunteer Patch][MT6620/MT5931][Driver] Fix scan side effect after P2P module separate. -+ * Fix scan channel extension issue when p2p module is not registered. -+ * -+ * 01 26 2011 cm.chang -+ * [WCXRP00000395] [MT6620 Wi-Fi][Driver][FW] Search STA_REC with additional net type index argument -+ * . -+ * -+ * 01 21 2011 cp.wu -+ * [WCXRP00000380] [MT6620 Wi-Fi][Driver] SSID information should come from buffered -+ * BSS_DESC_T rather than using beacon-carried information -+ * SSID should come from buffered prBssDesc rather than beacon-carried information -+ * -+ * 01 14 2011 yuche.tsai -+ * [WCXRP00000352] [Volunteer Patch][MT6620][Driver] P2P Statsion Record Client List Issue -+ * Fix compile error. -+ * -+ * 01 14 2011 yuche.tsai -+ * [WCXRP00000352] [Volunteer Patch][MT6620][Driver] P2P Statsion Record Client List Issue -+ * Memfree for P2P Descriptor & P2P Descriptor List. -+ * -+ * 01 14 2011 yuche.tsai -+ * [WCXRP00000352] [Volunteer Patch][MT6620][Driver] P2P Statsion Record Client List Issue -+ * Free P2P Descriptor List & Descriptor under BSS Descriptor. -+ * -+ * 01 04 2011 cp.wu -+ * [WCXRP00000338] [MT6620 Wi-Fi][Driver] Separate kalMemAlloc into kmalloc -+ * and vmalloc implementations to ease physically continuous memory demands -+ * 1) correct typo in scan.c -+ * 2) TX descriptors, RX descriptos and management buffer should use virtually -+ * continuous buffer instead of physically continuous one -+ * -+ * 01 04 2011 cp.wu -+ * [WCXRP00000338] [MT6620 Wi-Fi][Driver] Separate kalMemAlloc into kmalloc -+ * and vmalloc implementations to ease physically continuous memory demands -+ * separate kalMemAlloc() into virtually-continuous and physically-continuous type to ease slab system pressure -+ * -+ * 12 31 2010 cp.wu -+ * [WCXRP00000327] [MT6620 Wi-Fi][Driver] Improve HEC WHQA 6972 workaround coverage in driver side -+ * while being unloaded, clear all pending interrupt then set LP-own to firmware -+ * -+ * 12 21 2010 cp.wu -+ * [WCXRP00000280] [MT6620 Wi-Fi][Driver] Enable BSS selection with best RCPI policy in SCN module -+ * SCN: enable BEST RSSI selection policy support -+ * -+ * 11 29 2010 cp.wu -+ * [WCXRP00000210] [MT6620 Wi-Fi][Driver][FW] Set RCPI value in STA_REC -+ * for initial TX rate selection of auto-rate algorithm -+ * update ucRcpi of STA_RECORD_T for AIS when -+ * 1) Beacons for IBSS merge is received -+ * 2) Associate Response for a connecting peer is received -+ * -+ * 11 03 2010 wh.su -+ * [WCXRP00000124] [MT6620 Wi-Fi] [Driver] Support the dissolve P2P Group -+ * Refine the HT rate disallow TKIP pairwise cipher . -+ * -+ * 10 12 2010 cp.wu -+ * [WCXRP00000091] [MT6620 Wi-Fi][Driver] Add scanning logic to filter out -+ * beacons which is received on the folding frequency -+ * trust HT IE if available for 5GHz band -+ * -+ * 10 11 2010 cp.wu -+ * [WCXRP00000091] [MT6620 Wi-Fi][Driver] Add scanning logic to filter out -+ * beacons which is received on the folding frequency -+ * add timing and strenght constraint for filtering out beacons with same SSID/TA but received on different channels -+ * -+ * 10 08 2010 wh.su -+ * [WCXRP00000085] [MT6620 Wif-Fi] [Driver] update the modified p2p state machine -+ * update the frog's new p2p state machine. -+ * -+ * 10 01 2010 yuche.tsai -+ * NULL -+ * [MT6620 P2P] Fix Big Endian Issue when parse P2P device name TLV. -+ * -+ * 09 24 2010 cp.wu -+ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning -+ * eliminate unused variables which lead gcc to argue -+ * -+ * 09 08 2010 cp.wu -+ * NULL -+ * use static memory pool for storing IEs of scanning result. -+ * -+ * 09 07 2010 yuche.tsai -+ * NULL -+ * When indicate scan result, append IE buffer information in the scan result. -+ * -+ * 09 03 2010 yuche.tsai -+ * NULL -+ * 1. Update Beacon RX count when running SLT. -+ * 2. Ignore Beacon when running SLT, would not update information from Beacon. -+ * -+ * 09 03 2010 kevin.huang -+ * NULL -+ * Refine #include sequence and solve recursive/nested #include issue -+ * -+ * 08 31 2010 kevin.huang -+ * NULL -+ * Use LINK LIST operation to process SCAN result -+ * -+ * 08 29 2010 yuche.tsai -+ * NULL -+ * 1. Fix P2P Descriptor List to be a link list, to avoid link corrupt after Bss Descriptor Free. -+ * 2.. Fix P2P Device Name Length BE issue. -+ * -+ * 08 23 2010 yuche.tsai -+ * NULL -+ * Add P2P Device Found Indication to supplicant -+ * -+ * 08 20 2010 cp.wu -+ * NULL -+ * reset BSS_DESC_T variables before parsing IE due to peer might have been reconfigured. -+ * -+ * 08 20 2010 yuche.tsai -+ * NULL -+ * Workaround for P2P Descriptor Infinite loop issue. -+ * -+ * 08 16 2010 cp.wu -+ * NULL -+ * Replace CFG_SUPPORT_BOW by CFG_ENABLE_BT_OVER_WIFI. -+ * There is no CFG_SUPPORT_BOW in driver domain source. -+ * -+ * 08 16 2010 yuche.tsai -+ * NULL -+ * Modify code of processing Probe Resonse frame for P2P. -+ * -+ * 08 12 2010 yuche.tsai -+ * NULL -+ * Add function to get P2P descriptor of BSS descriptor directly. -+ * -+ * 08 11 2010 yuche.tsai -+ * NULL -+ * Modify Scan result processing for P2P module. -+ * -+ * 08 05 2010 yuche.tsai -+ * NULL -+ * Update P2P Device Discovery result add function. -+ * -+ * 08 03 2010 cp.wu -+ * NULL -+ * surpress compilation warning. -+ * -+ * 07 26 2010 yuche.tsai -+ * -+ * Add support for Probe Request & Response parsing. -+ * -+ * 07 21 2010 cp.wu -+ * -+ * 1) change BG_SCAN to ONLINE_SCAN for consistent term -+ * 2) only clear scanning result when scan is permitted to do -+ * -+ * 07 21 2010 yuche.tsai -+ * -+ * Fix compile error for SCAN module while disabling P2P feature. -+ * -+ * 07 21 2010 yuche.tsai -+ * -+ * Add P2P Scan & Scan Result Parsing & Saving. -+ * -+ * 07 19 2010 wh.su -+ * -+ * update for security supporting. -+ * -+ * 07 19 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration. -+ * Add Ad-Hoc support to AIS-FSM -+ * -+ * 07 19 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration. -+ * SCN module is now able to handle multiple concurrent scanning requests -+ * -+ * 07 15 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration. -+ * driver no longer generates probe request frames -+ * -+ * 07 14 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration. -+ * remove timer in DRV-SCN. -+ * -+ * 07 09 2010 cp.wu -+ * -+ * 1) separate AIS_FSM state for two kinds of scanning. (OID triggered scan, and scan-for-connection) -+ * 2) eliminate PRE_BSS_DESC_T, Beacon/PrebResp is now parsed in single pass -+ * 3) implment DRV-SCN module, currently only accepts single scan request, -+ * other request will be directly dropped by returning BUSY -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 07 08 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * take use of RLM module for parsing/generating HT IEs for 11n capability -+ * -+ * 07 05 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) ignore RSN checking when RSN is not turned on. -+ * 2) set STA-REC deactivation callback as NULL -+ * 3) add variable initialization API based on PHY configuration -+ * -+ * 07 05 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * correct BSS_DESC_T initialization after allocated. -+ * -+ * 07 02 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) for event packet, no need to fill RFB. -+ * 2) when wlanAdapterStart() failed, no need to initialize state machines -+ * 3) after Beacon/ProbeResp parsing, corresponding BSS_DESC_T should be marked as IE-parsed -+ * -+ * 07 01 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add scan uninitialization procedure -+ * -+ * 06 30 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * if beacon/probe-resp is received in 2.4GHz bands and there is ELEM_ID_DS_PARAM_SET IE available, -+ * trust IE instead of RMAC information -+ * -+ * 06 29 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) sync to. CMD/EVENT document v0.03 -+ * 2) simplify DTIM period parsing in scan.c only, bss.c no longer parses it again. -+ * 3) send command packet to indicate FW-PM after -+ * a) 1st beacon is received after AIS has connected to an AP -+ * b) IBSS-ALONE has been created -+ * c) IBSS-MERGE has occurred -+ * -+ * 06 28 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * send MMPDU in basic rate. -+ * -+ * 06 25 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * modify Beacon/ProbeResp to complete parsing, -+ * because host software has looser memory usage restriction -+ * -+ * 06 23 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * integrate . -+ * -+ * 06 22 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * comment out RLM APIs by CFG_RLM_MIGRATION. -+ * -+ * 06 21 2010 yuche.tsai -+ * [WPD00003839][MT6620 5931][P2P] Feature migration -+ * Update P2P Function call. -+ * -+ * 06 21 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * RSN/PRIVACY compilation flag awareness correction -+ * -+ * 06 21 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * specify correct value for management frames. -+ * -+ * 06 18 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Provide cnmMgtPktAlloc() and alloc/free function of msg/buf -+ * -+ * 06 18 2010 wh.su -+ * [WPD00003840][MT6620 5931] Security migration -+ * migration from MT6620 firmware. -+ * -+ * 06 17 2010 yuche.tsai -+ * [WPD00003839][MT6620 5931][P2P] Feature migration -+ * Fix compile error when enable P2P function. -+ * -+ * 06 15 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * correct when ADHOC support is turned on. -+ * -+ * 06 15 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add scan.c. -+ * -+ * 06 04 2010 george.huang -+ * [BORA00000678][MT6620]WiFi LP integration -+ * [PM] Support U-APSD for STA mode -+ * -+ * 05 28 2010 wh.su -+ * [BORA00000680][MT6620] Support the statistic for Micxxsoft os query -+ * adding the TKIP disallow join a HT AP code. -+ * -+ * 05 14 2010 kevin.huang -+ * [BORA00000794][WIFISYS][New Feature]Power Management Support -+ * Add more chance of JOIN retry for BG_SCAN -+ * -+ * 05 12 2010 kevin.huang -+ * [BORA00000794][WIFISYS][New Feature]Power Management Support -+ * Add Power Management - Legacy PS-POLL support. -+ * -+ * 04 29 2010 wh.su -+ * [BORA00000637][MT6620 Wi-Fi] [Bug] WPA2 pre-authentication timer not correctly initialize -+ * adjsut the pre-authentication code. -+ * -+ * 04 27 2010 kevin.huang -+ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support -+ * Add Set Slot Time and Beacon Timeout Support for AdHoc Mode -+ * -+ * 04 24 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * g_aprBssInfo[] depends on CFG_SUPPORT_P2P and CFG_SUPPORT_BOW -+ * -+ * 04 19 2010 kevin.huang -+ * [BORA00000714][WIFISYS][New Feature]Beacon Timeout Support -+ * Add Beacon Timeout Support and will send Null frame to diagnose connection -+ * -+ * 04 13 2010 kevin.huang -+ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support -+ * Add new HW CH macro support -+ * -+ * 04 06 2010 wh.su -+ * [BORA00000680][MT6620] Support the statistic for Micxxsoft os query -+ * fixed the firmware return the broadcast frame at wrong tc. -+ * -+ * 03 29 2010 wh.su -+ * [BORA00000605][WIFISYS] Phase3 Integration -+ * let the rsn wapi IE always parsing. -+ * -+ * 03 24 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Not carry HT cap when being associated with b/g only AP -+ * -+ * 03 18 2010 kevin.huang -+ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support -+ * Solve the compile warning for 'return non-void' function -+ * -+ * 03 16 2010 kevin.huang -+ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support -+ * Add AdHoc Mode -+ * -+ * 03 10 2010 kevin.huang -+ * [BORA00000654][WIFISYS][New Feature] CNM Module - Ch Manager Support -+ * -+ * * * * * * * * * * * * * * * * Add Channel Manager for arbitration of JOIN and SCAN Req -+ * -+ * 03 03 2010 wh.su -+ * [BORA00000637][MT6620 Wi-Fi] [Bug] WPA2 pre-authentication timer not correctly initialize -+ * move the AIS specific variable for security to AIS specific structure. -+ * -+ * 03 01 2010 wh.su -+ * [BORA00000605][WIFISYS] Phase3 Integration -+ * Refine the variable and parameter for security. -+ * -+ * 02 26 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Fix No PKT_INFO_T issue -+ * -+ * 02 26 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Update outgoing ProbeRequest Frame's TX data rate -+ * -+ * 02 23 2010 wh.su -+ * [BORA00000592][MT6620 Wi-Fi] Adding the security related code for driver -+ * refine the scan procedure, reduce the WPA and WAPI IE parsing, and move the parsing to the time for join. -+ * -+ * 02 23 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Add support scan channel 1~14 and update scan result's frequency infou1rwduu`wvpghlqg|n`slk+mpdkb -+ * -+ * 02 04 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Add AAA Module Support, Revise Net Type to Net Type Index for array lookup -+ * -+ * 01 27 2010 wh.su -+ * [BORA00000476][Wi-Fi][firmware] Add the security module initialize code -+ * add and fixed some security function. -+ * -+ * 01 22 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Support protection and bandwidth switch -+ * -+ * 01 20 2010 kevin.huang -+ * [BORA00000569][WIFISYS] Phase 2 Integration Test -+ * Add PHASE_2_INTEGRATION_WORK_AROUND and CFG_SUPPORT_BCM flags -+ * -+ * 01 11 2010 kevin.huang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Add Deauth and Disassoc Handler -+ * -+ * 01 08 2010 kevin.huang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * -+ * Refine Beacon processing, add read RF channel from RX Status -+ * -+ * 01 04 2010 tehuang.liu -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * For working out the first connection Chariot-verified version -+ * -+ * 12 18 2009 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * . -+ * -+ * Dec 12 2009 mtk01104 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Modify u2EstimatedExtraIELen for probe request -+ * -+ * Dec 9 2009 mtk01104 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Add HT cap IE to probe request -+ * -+ * Dec 7 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Fix lint warning -+ * -+ * -+ * Dec 3 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Update the process of SCAN Result by adding more Phy Attributes -+ * -+ * Dec 1 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * adjust the function and code for meet the new define -+ * -+ * Nov 30 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Rename u4RSSI to i4RSSI -+ * -+ * Nov 30 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Report event of scan result to host -+ * -+ * Nov 26 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Fix SCAN Record update -+ * -+ * Nov 24 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Revise MGMT Handler with Retain Status and Integrate with TXM -+ * -+ * Nov 23 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Add (Ext)Support Rate Set IE to ProbeReq -+ * -+ * Nov 20 2009 mtk02468 -+ * [BORA00000337] To check in codes for FPGA emulation -+ * Removed the use of SW_RFB->u2FrameLength -+ * -+ * Nov 20 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Fix uninitial aucMacAddress[] for ProbeReq -+ * -+ * Nov 16 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Add scanSearchBssDescByPolicy() -+ * -+ * Nov 5 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Add Send Probe Request Frame -+ * -+ * Oct 30 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "precomp.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+#define REPLICATED_BEACON_TIME_THRESHOLD (3000) -+#define REPLICATED_BEACON_FRESH_PERIOD (10000) -+#define REPLICATED_BEACON_STRENGTH_THRESHOLD (32) -+ -+#define ROAMING_NO_SWING_RCPI_STEP (10) -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is used by SCN to initialize its variables -+* -+* @param (none) -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID scnInit(IN P_ADAPTER_T prAdapter) -+{ -+ P_SCAN_INFO_T prScanInfo; -+ P_BSS_DESC_T prBSSDesc; -+ PUINT_8 pucBSSBuff; -+ UINT_32 i; -+ -+ ASSERT(prAdapter); -+ -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ pucBSSBuff = &prScanInfo->aucScanBuffer[0]; -+ -+ DBGLOG(SCN, INFO, "->scnInit()\n"); -+ -+ /* 4 <1> Reset STATE and Message List */ -+ prScanInfo->eCurrentState = SCAN_STATE_IDLE; -+ -+ prScanInfo->rLastScanCompletedTime = (OS_SYSTIME) 0; -+ -+ LINK_INITIALIZE(&prScanInfo->rPendingMsgList); -+ -+ /* 4 <2> Reset link list of BSS_DESC_T */ -+ kalMemZero((PVOID) pucBSSBuff, SCN_MAX_BUFFER_SIZE); -+ -+ LINK_INITIALIZE(&prScanInfo->rFreeBSSDescList); -+ LINK_INITIALIZE(&prScanInfo->rBSSDescList); -+ -+ for (i = 0; i < CFG_MAX_NUM_BSS_LIST; i++) { -+ -+ prBSSDesc = (P_BSS_DESC_T) pucBSSBuff; -+ -+ LINK_INSERT_TAIL(&prScanInfo->rFreeBSSDescList, &prBSSDesc->rLinkEntry); -+ -+ pucBSSBuff += ALIGN_4(sizeof(BSS_DESC_T)); -+ } -+ /* Check if the memory allocation consist with this initialization function */ -+ ASSERT(((ULONG) pucBSSBuff - (ULONG)&prScanInfo->aucScanBuffer[0]) == SCN_MAX_BUFFER_SIZE); -+ -+ /* reset freest channel information */ -+ prScanInfo->fgIsSparseChannelValid = FALSE; -+ -+ /* reset NLO state */ -+ prScanInfo->fgNloScanning = FALSE; -+ prScanInfo->fgPscnOnnning = FALSE; -+ -+ prScanInfo->prPscnParam = kalMemAlloc(sizeof(PSCN_PARAM_T), VIR_MEM_TYPE); -+ if (prScanInfo->prPscnParam) -+ kalMemZero(prScanInfo->prPscnParam, sizeof(PSCN_PARAM_T)); -+ -+} /* end of scnInit() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is used by SCN to uninitialize its variables -+* -+* @param (none) -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID scnUninit(IN P_ADAPTER_T prAdapter) -+{ -+ P_SCAN_INFO_T prScanInfo; -+ -+ ASSERT(prAdapter); -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ -+ DBGLOG(SCN, INFO, "->scnUninit()\n"); -+ -+ /* 4 <1> Reset STATE and Message List */ -+ prScanInfo->eCurrentState = SCAN_STATE_IDLE; -+ -+ prScanInfo->rLastScanCompletedTime = (OS_SYSTIME) 0; -+ -+ /* NOTE(Kevin): Check rPendingMsgList ? */ -+ -+ /* 4 <2> Reset link list of BSS_DESC_T */ -+ LINK_INITIALIZE(&prScanInfo->rFreeBSSDescList); -+ LINK_INITIALIZE(&prScanInfo->rBSSDescList); -+ -+ kalMemFree(prScanInfo->prPscnParam, VIR_MEM_TYPE, sizeof(PSCN_PARAM_T)); -+ -+} /* end of scnUninit() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Find the corresponding BSS Descriptor according to given BSSID -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* @param[in] aucBSSID Given BSSID. -+* -+* @return Pointer to BSS Descriptor, if found. NULL, if not found -+*/ -+/*----------------------------------------------------------------------------*/ -+P_BSS_DESC_T scanSearchBssDescByBssid(IN P_ADAPTER_T prAdapter, IN UINT_8 aucBSSID[]) -+{ -+ return scanSearchBssDescByBssidAndSsid(prAdapter, aucBSSID, FALSE, NULL); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Find the corresponding BSS Descriptor according to given BSSID -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* @param[in] aucBSSID Given BSSID. -+* @param[in] fgCheckSsid Need to check SSID or not. (for multiple SSID with single BSSID cases) -+* @param[in] prSsid Specified SSID -+* -+* @return Pointer to BSS Descriptor, if found. NULL, if not found -+*/ -+/*----------------------------------------------------------------------------*/ -+P_BSS_DESC_T -+scanSearchBssDescByBssidAndSsid(IN P_ADAPTER_T prAdapter, -+ IN UINT_8 aucBSSID[], IN BOOLEAN fgCheckSsid, IN P_PARAM_SSID_T prSsid) -+{ -+ P_SCAN_INFO_T prScanInfo; -+ P_LINK_T prBSSDescList; -+ P_BSS_DESC_T prBssDesc; -+ P_BSS_DESC_T prDstBssDesc = (P_BSS_DESC_T) NULL; -+ -+ ASSERT(prAdapter); -+ ASSERT(aucBSSID); -+ -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ -+ prBSSDescList = &prScanInfo->rBSSDescList; -+ -+ /* Search BSS Desc from current SCAN result list. */ -+ LINK_FOR_EACH_ENTRY(prBssDesc, prBSSDescList, rLinkEntry, BSS_DESC_T) { -+ -+ if (EQUAL_MAC_ADDR(prBssDesc->aucBSSID, aucBSSID)) { -+ if (fgCheckSsid == FALSE || prSsid == NULL) -+ return prBssDesc; -+ -+ if (EQUAL_SSID(prBssDesc->aucSSID, -+ prBssDesc->ucSSIDLen, prSsid->aucSsid, prSsid->u4SsidLen)) { -+ return prBssDesc; -+ } else if (prDstBssDesc == NULL && prBssDesc->fgIsHiddenSSID == TRUE) { -+ prDstBssDesc = prBssDesc; -+ } else { -+ /* 20120206 frog: Equal BSSID but not SSID, SSID not hidden, -+ * SSID must be updated. */ -+ COPY_SSID(prBssDesc->aucSSID, -+ prBssDesc->ucSSIDLen, prSsid->aucSsid, prSsid->u4SsidLen); -+ return prBssDesc; -+ } -+ } -+ } -+ -+ return prDstBssDesc; -+ -+} /* end of scanSearchBssDescByBssid() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Find the corresponding BSS Descriptor according to given Transmitter Address. -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* @param[in] aucSrcAddr Given Source Address(TA). -+* -+* @return Pointer to BSS Descriptor, if found. NULL, if not found -+*/ -+/*----------------------------------------------------------------------------*/ -+P_BSS_DESC_T scanSearchBssDescByTA(IN P_ADAPTER_T prAdapter, IN UINT_8 aucSrcAddr[]) -+{ -+ return scanSearchBssDescByTAAndSsid(prAdapter, aucSrcAddr, FALSE, NULL); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Find the corresponding BSS Descriptor according to given Transmitter Address. -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* @param[in] aucSrcAddr Given Source Address(TA). -+* @param[in] fgCheckSsid Need to check SSID or not. (for multiple SSID with single BSSID cases) -+* @param[in] prSsid Specified SSID -+* -+* @return Pointer to BSS Descriptor, if found. NULL, if not found -+*/ -+/*----------------------------------------------------------------------------*/ -+P_BSS_DESC_T -+scanSearchBssDescByTAAndSsid(IN P_ADAPTER_T prAdapter, -+ IN UINT_8 aucSrcAddr[], IN BOOLEAN fgCheckSsid, IN P_PARAM_SSID_T prSsid) -+{ -+ P_SCAN_INFO_T prScanInfo; -+ P_LINK_T prBSSDescList; -+ P_BSS_DESC_T prBssDesc; -+ P_BSS_DESC_T prDstBssDesc = (P_BSS_DESC_T) NULL; -+ -+ ASSERT(prAdapter); -+ ASSERT(aucSrcAddr); -+ -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ -+ prBSSDescList = &prScanInfo->rBSSDescList; -+ -+ /* Search BSS Desc from current SCAN result list. */ -+ LINK_FOR_EACH_ENTRY(prBssDesc, prBSSDescList, rLinkEntry, BSS_DESC_T) { -+ -+ if (EQUAL_MAC_ADDR(prBssDesc->aucSrcAddr, aucSrcAddr)) { -+ if (fgCheckSsid == FALSE || prSsid == NULL) -+ return prBssDesc; -+ -+ if (EQUAL_SSID(prBssDesc->aucSSID, -+ prBssDesc->ucSSIDLen, prSsid->aucSsid, prSsid->u4SsidLen)) { -+ return prBssDesc; -+ } else if (prDstBssDesc == NULL && prBssDesc->fgIsHiddenSSID == TRUE) { -+ prDstBssDesc = prBssDesc; -+ } -+ -+ } -+ } -+ -+ return prDstBssDesc; -+ -+} /* end of scanSearchBssDescByTA() */ -+ -+#if CFG_SUPPORT_HOTSPOT_2_0 -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Find the corresponding BSS Descriptor according to given BSSID -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* @param[in] aucBSSID Given BSSID. -+* @param[in] fgCheckSsid Need to check SSID or not. (for multiple SSID with single BSSID cases) -+* @param[in] prSsid Specified SSID -+* -+* @return Pointer to BSS Descriptor, if found. NULL, if not found -+*/ -+/*----------------------------------------------------------------------------*/ -+P_BSS_DESC_T scanSearchBssDescByBssidAndLatestUpdateTime(IN P_ADAPTER_T prAdapter, IN UINT_8 aucBSSID[]) -+{ -+ P_SCAN_INFO_T prScanInfo; -+ P_LINK_T prBSSDescList; -+ P_BSS_DESC_T prBssDesc; -+ P_BSS_DESC_T prDstBssDesc = (P_BSS_DESC_T) NULL; -+ OS_SYSTIME rLatestUpdateTime = 0; -+ -+ ASSERT(prAdapter); -+ ASSERT(aucBSSID); -+ -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ -+ prBSSDescList = &prScanInfo->rBSSDescList; -+ -+ /* Search BSS Desc from current SCAN result list. */ -+ LINK_FOR_EACH_ENTRY(prBssDesc, prBSSDescList, rLinkEntry, BSS_DESC_T) { -+ -+ if (EQUAL_MAC_ADDR(prBssDesc->aucBSSID, aucBSSID)) { -+ if (!rLatestUpdateTime || CHECK_FOR_EXPIRATION(prBssDesc->rUpdateTime, rLatestUpdateTime)) { -+ prDstBssDesc = prBssDesc; -+ COPY_SYSTIME(rLatestUpdateTime, prBssDesc->rUpdateTime); -+ } -+ } -+ } -+ -+ return prDstBssDesc; -+ -+} /* end of scanSearchBssDescByBssid() */ -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Find the corresponding BSS Descriptor according to -+* given eBSSType, BSSID and Transmitter Address -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* @param[in] eBSSType BSS Type of incoming Beacon/ProbeResp frame. -+* @param[in] aucBSSID Given BSSID of Beacon/ProbeResp frame. -+* @param[in] aucSrcAddr Given source address (TA) of Beacon/ProbeResp frame. -+* -+* @return Pointer to BSS Descriptor, if found. NULL, if not found -+*/ -+/*----------------------------------------------------------------------------*/ -+P_BSS_DESC_T -+scanSearchExistingBssDesc(IN P_ADAPTER_T prAdapter, -+ IN ENUM_BSS_TYPE_T eBSSType, IN UINT_8 aucBSSID[], IN UINT_8 aucSrcAddr[]) -+{ -+ return scanSearchExistingBssDescWithSsid(prAdapter, eBSSType, aucBSSID, aucSrcAddr, FALSE, NULL); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Find the corresponding BSS Descriptor according to -+* given eBSSType, BSSID and Transmitter Address -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* @param[in] eBSSType BSS Type of incoming Beacon/ProbeResp frame. -+* @param[in] aucBSSID Given BSSID of Beacon/ProbeResp frame. -+* @param[in] aucSrcAddr Given source address (TA) of Beacon/ProbeResp frame. -+* @param[in] fgCheckSsid Need to check SSID or not. (for multiple SSID with single BSSID cases) -+* @param[in] prSsid Specified SSID -+* -+* @return Pointer to BSS Descriptor, if found. NULL, if not found -+*/ -+/*----------------------------------------------------------------------------*/ -+P_BSS_DESC_T -+scanSearchExistingBssDescWithSsid(IN P_ADAPTER_T prAdapter, -+ IN ENUM_BSS_TYPE_T eBSSType, -+ IN UINT_8 aucBSSID[], -+ IN UINT_8 aucSrcAddr[], IN BOOLEAN fgCheckSsid, IN P_PARAM_SSID_T prSsid) -+{ -+ P_SCAN_INFO_T prScanInfo; -+ P_BSS_DESC_T prBssDesc, prIBSSBssDesc; -+ P_LINK_T prBSSDescList; -+ P_LINK_T prFreeBSSDescList; -+ -+ -+ ASSERT(prAdapter); -+ ASSERT(aucSrcAddr); -+ -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ -+ switch (eBSSType) { -+ case BSS_TYPE_P2P_DEVICE: -+ fgCheckSsid = FALSE; -+ case BSS_TYPE_INFRASTRUCTURE: -+ case BSS_TYPE_BOW_DEVICE: -+ { -+ prBssDesc = scanSearchBssDescByBssidAndSsid(prAdapter, aucBSSID, fgCheckSsid, prSsid); -+ -+ /* if (eBSSType == prBssDesc->eBSSType) */ -+ -+ return prBssDesc; -+ } -+ -+ case BSS_TYPE_IBSS: -+ { -+ prIBSSBssDesc = scanSearchBssDescByBssidAndSsid(prAdapter, aucBSSID, fgCheckSsid, prSsid); -+ prBssDesc = scanSearchBssDescByTAAndSsid(prAdapter, aucSrcAddr, fgCheckSsid, prSsid); -+ -+ /* NOTE(Kevin): -+ * Rules to maintain the SCAN Result: -+ * For AdHoc - -+ * CASE I We have TA1(BSSID1), but it change its BSSID to BSSID2 -+ * -> Update TA1 entry's BSSID. -+ * CASE II We have TA1(BSSID1), and get TA1(BSSID1) again -+ * -> Update TA1 entry's contain. -+ * CASE III We have a SCAN result TA1(BSSID1), and TA2(BSSID2). Sooner or -+ * later, TA2 merge into TA1, we get TA2(BSSID1) -+ * -> Remove TA2 first and then replace TA1 entry's TA with TA2, -+ * Still have only one entry of BSSID. -+ * CASE IV We have a SCAN result TA1(BSSID1), and another TA2 also merge into BSSID1. -+ * -> Replace TA1 entry's TA with TA2, Still have only one entry. -+ * CASE V New IBSS -+ * -> Add this one to SCAN result. -+ */ -+ if (prBssDesc) { -+ if ((!prIBSSBssDesc) || /* CASE I */ -+ (prBssDesc == prIBSSBssDesc)) { /* CASE II */ -+ -+ return prBssDesc; -+ } /* CASE III */ -+ -+ prBSSDescList = &prScanInfo->rBSSDescList; -+ prFreeBSSDescList = &prScanInfo->rFreeBSSDescList; -+ -+ /* Remove this BSS Desc from the BSS Desc list */ -+ LINK_REMOVE_KNOWN_ENTRY(prBSSDescList, prBssDesc); -+ -+ /* Return this BSS Desc to the free BSS Desc list. */ -+ LINK_INSERT_TAIL(prFreeBSSDescList, &prBssDesc->rLinkEntry); -+ -+ return prIBSSBssDesc; -+ } -+ -+ if (prIBSSBssDesc) { /* CASE IV */ -+ -+ return prIBSSBssDesc; -+ } -+ /* CASE V */ -+ break; /* Return NULL; */ -+ } -+ -+ default: -+ break; -+ } -+ -+ return (P_BSS_DESC_T) NULL; -+ -+} /* end of scanSearchExistingBssDesc() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Delete BSS Descriptors from current list according to given Remove Policy. -+* -+* @param[in] u4RemovePolicy Remove Policy. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID scanRemoveBssDescsByPolicy(IN P_ADAPTER_T prAdapter, IN UINT_32 u4RemovePolicy) -+{ -+ P_CONNECTION_SETTINGS_T prConnSettings; -+ P_SCAN_INFO_T prScanInfo; -+ P_LINK_T prBSSDescList; -+ P_LINK_T prFreeBSSDescList; -+ P_BSS_DESC_T prBssDesc; -+ -+ ASSERT(prAdapter); -+ -+ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ prBSSDescList = &prScanInfo->rBSSDescList; -+ prFreeBSSDescList = &prScanInfo->rFreeBSSDescList; -+ -+ /* DBGLOG(SCN, TRACE, ("Before Remove - Number Of SCAN Result = %ld\n", */ -+ /* prBSSDescList->u4NumElem)); */ -+ -+ if (u4RemovePolicy & SCN_RM_POLICY_TIMEOUT) { -+ P_BSS_DESC_T prBSSDescNext; -+ OS_SYSTIME rCurrentTime; -+ -+ GET_CURRENT_SYSTIME(&rCurrentTime); -+ -+ /* Search BSS Desc from current SCAN result list. */ -+ LINK_FOR_EACH_ENTRY_SAFE(prBssDesc, prBSSDescNext, prBSSDescList, rLinkEntry, BSS_DESC_T) { -+ -+ if ((u4RemovePolicy & SCN_RM_POLICY_EXCLUDE_CONNECTED) && -+ (prBssDesc->fgIsConnected || prBssDesc->fgIsConnecting)) { -+ /* Don't remove the one currently we are connected. */ -+ continue; -+ } -+ -+ if (CHECK_FOR_TIMEOUT(rCurrentTime, prBssDesc->rUpdateTime, -+ SEC_TO_SYSTIME(SCN_BSS_DESC_REMOVE_TIMEOUT_SEC))) { -+ -+ /* DBGLOG(SCN, TRACE, ("Remove TIMEOUT BSS DESC(%#x): -+ * MAC: %pM, Current Time = %08lx, Update Time = %08lx\n", */ -+ /* prBssDesc, prBssDesc->aucBSSID, rCurrentTime, prBssDesc->rUpdateTime)); */ -+ -+ /* Remove this BSS Desc from the BSS Desc list */ -+ LINK_REMOVE_KNOWN_ENTRY(prBSSDescList, prBssDesc); -+ -+ /* Return this BSS Desc to the free BSS Desc list. */ -+ LINK_INSERT_TAIL(prFreeBSSDescList, &prBssDesc->rLinkEntry); -+ } -+ } -+ } else if (u4RemovePolicy & SCN_RM_POLICY_OLDEST_HIDDEN) { -+ P_BSS_DESC_T prBssDescOldest = (P_BSS_DESC_T) NULL; -+ -+ /* Search BSS Desc from current SCAN result list. */ -+ LINK_FOR_EACH_ENTRY(prBssDesc, prBSSDescList, rLinkEntry, BSS_DESC_T) { -+ -+ if ((u4RemovePolicy & SCN_RM_POLICY_EXCLUDE_CONNECTED) && -+ (prBssDesc->fgIsConnected || prBssDesc->fgIsConnecting)) { -+ /* Don't remove the one currently we are connected. */ -+ continue; -+ } -+ -+ if (!prBssDesc->fgIsHiddenSSID) -+ continue; -+ -+ if (!prBssDescOldest) { /* 1st element */ -+ prBssDescOldest = prBssDesc; -+ continue; -+ } -+ -+ if (TIME_BEFORE(prBssDesc->rUpdateTime, prBssDescOldest->rUpdateTime)) -+ prBssDescOldest = prBssDesc; -+ } -+ -+ if (prBssDescOldest) { -+ -+ /* DBGLOG(SCN, TRACE, ("Remove OLDEST HIDDEN BSS DESC(%#x): -+ * MAC: %pM, Update Time = %08lx\n", */ -+ /* prBssDescOldest, prBssDescOldest->aucBSSID, prBssDescOldest->rUpdateTime)); */ -+ -+ /* Remove this BSS Desc from the BSS Desc list */ -+ LINK_REMOVE_KNOWN_ENTRY(prBSSDescList, prBssDescOldest); -+ -+ /* Return this BSS Desc to the free BSS Desc list. */ -+ LINK_INSERT_TAIL(prFreeBSSDescList, &prBssDescOldest->rLinkEntry); -+ } -+ } else if (u4RemovePolicy & SCN_RM_POLICY_SMART_WEAKEST) { -+ P_BSS_DESC_T prBssDescWeakest = (P_BSS_DESC_T) NULL; -+ P_BSS_DESC_T prBssDescWeakestSameSSID = (P_BSS_DESC_T) NULL; -+ UINT_32 u4SameSSIDCount = 0; -+ -+ /* Search BSS Desc from current SCAN result list. */ -+ LINK_FOR_EACH_ENTRY(prBssDesc, prBSSDescList, rLinkEntry, BSS_DESC_T) { -+ -+ if ((u4RemovePolicy & SCN_RM_POLICY_EXCLUDE_CONNECTED) && -+ (prBssDesc->fgIsConnected || prBssDesc->fgIsConnecting)) { -+ /* Don't remove the one currently we are connected. */ -+ continue; -+ } -+ -+ if ((!prBssDesc->fgIsHiddenSSID) && -+ (EQUAL_SSID(prBssDesc->aucSSID, -+ prBssDesc->ucSSIDLen, prConnSettings->aucSSID, prConnSettings->ucSSIDLen))) { -+ -+ u4SameSSIDCount++; -+ -+ if (!prBssDescWeakestSameSSID) -+ prBssDescWeakestSameSSID = prBssDesc; -+ else if (prBssDesc->ucRCPI < prBssDescWeakestSameSSID->ucRCPI) -+ prBssDescWeakestSameSSID = prBssDesc; -+ } -+ -+ if (!prBssDescWeakest) { /* 1st element */ -+ prBssDescWeakest = prBssDesc; -+ continue; -+ } -+ -+ if (prBssDesc->ucRCPI < prBssDescWeakest->ucRCPI) -+ prBssDescWeakest = prBssDesc; -+ -+ } -+ -+ if ((u4SameSSIDCount >= SCN_BSS_DESC_SAME_SSID_THRESHOLD) && (prBssDescWeakestSameSSID)) -+ prBssDescWeakest = prBssDescWeakestSameSSID; -+ -+ if (prBssDescWeakest) { -+ -+ /* DBGLOG(SCN, TRACE, ("Remove WEAKEST BSS DESC(%#x): MAC: %pM, Update Time = %08lx\n", */ -+ /* prBssDescOldest, prBssDescOldest->aucBSSID, prBssDescOldest->rUpdateTime)); */ -+ -+ /* Remove this BSS Desc from the BSS Desc list */ -+ LINK_REMOVE_KNOWN_ENTRY(prBSSDescList, prBssDescWeakest); -+ -+ /* Return this BSS Desc to the free BSS Desc list. */ -+ LINK_INSERT_TAIL(prFreeBSSDescList, &prBssDescWeakest->rLinkEntry); -+ } -+ } else if (u4RemovePolicy & SCN_RM_POLICY_ENTIRE) { -+ P_BSS_DESC_T prBSSDescNext; -+ -+ LINK_FOR_EACH_ENTRY_SAFE(prBssDesc, prBSSDescNext, prBSSDescList, rLinkEntry, BSS_DESC_T) { -+ -+ if ((u4RemovePolicy & SCN_RM_POLICY_EXCLUDE_CONNECTED) && -+ (prBssDesc->fgIsConnected || prBssDesc->fgIsConnecting)) { -+ /* Don't remove the one currently we are connected. */ -+ continue; -+ } -+ -+ /* Remove this BSS Desc from the BSS Desc list */ -+ LINK_REMOVE_KNOWN_ENTRY(prBSSDescList, prBssDesc); -+ -+ /* Return this BSS Desc to the free BSS Desc list. */ -+ LINK_INSERT_TAIL(prFreeBSSDescList, &prBssDesc->rLinkEntry); -+ } -+ -+ } -+ -+ return; -+ -+} /* end of scanRemoveBssDescsByPolicy() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Delete BSS Descriptors from current list according to given BSSID. -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* @param[in] aucBSSID Given BSSID. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID scanRemoveBssDescByBssid(IN P_ADAPTER_T prAdapter, IN UINT_8 aucBSSID[]) -+{ -+ P_SCAN_INFO_T prScanInfo; -+ P_LINK_T prBSSDescList; -+ P_LINK_T prFreeBSSDescList; -+ P_BSS_DESC_T prBssDesc = (P_BSS_DESC_T) NULL; -+ P_BSS_DESC_T prBSSDescNext; -+ -+ ASSERT(prAdapter); -+ ASSERT(aucBSSID); -+ -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ prBSSDescList = &prScanInfo->rBSSDescList; -+ prFreeBSSDescList = &prScanInfo->rFreeBSSDescList; -+ -+ /* Check if such BSS Descriptor exists in a valid list */ -+ LINK_FOR_EACH_ENTRY_SAFE(prBssDesc, prBSSDescNext, prBSSDescList, rLinkEntry, BSS_DESC_T) { -+ -+ if (EQUAL_MAC_ADDR(prBssDesc->aucBSSID, aucBSSID)) { -+ -+ /* Remove this BSS Desc from the BSS Desc list */ -+ LINK_REMOVE_KNOWN_ENTRY(prBSSDescList, prBssDesc); -+ -+ /* Return this BSS Desc to the free BSS Desc list. */ -+ LINK_INSERT_TAIL(prFreeBSSDescList, &prBssDesc->rLinkEntry); -+ -+ /* BSSID is not unique, so need to traverse whols link-list */ -+ } -+ } -+ -+} /* end of scanRemoveBssDescByBssid() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Delete BSS Descriptors from current list according to given band configuration -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* @param[in] eBand Given band -+* @param[in] eNetTypeIndex AIS - Remove IBSS/Infrastructure BSS -+* BOW - Remove BOW BSS -+* P2P - Remove P2P BSS -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+scanRemoveBssDescByBandAndNetwork(IN P_ADAPTER_T prAdapter, -+ IN ENUM_BAND_T eBand, IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex) -+{ -+ P_SCAN_INFO_T prScanInfo; -+ P_LINK_T prBSSDescList; -+ P_LINK_T prFreeBSSDescList; -+ P_BSS_DESC_T prBssDesc = (P_BSS_DESC_T) NULL; -+ P_BSS_DESC_T prBSSDescNext; -+ BOOLEAN fgToRemove; -+ -+ ASSERT(prAdapter); -+ ASSERT(eBand <= BAND_NUM); -+ ASSERT(eNetTypeIndex <= NETWORK_TYPE_INDEX_NUM); -+ -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ prBSSDescList = &prScanInfo->rBSSDescList; -+ prFreeBSSDescList = &prScanInfo->rFreeBSSDescList; -+ -+ if (eBand == BAND_NULL) -+ return; /* no need to do anything, keep all scan result */ -+ -+ /* Check if such BSS Descriptor exists in a valid list */ -+ LINK_FOR_EACH_ENTRY_SAFE(prBssDesc, prBSSDescNext, prBSSDescList, rLinkEntry, BSS_DESC_T) { -+ fgToRemove = FALSE; -+ -+ if (prBssDesc->eBand == eBand) { -+ switch (eNetTypeIndex) { -+ case NETWORK_TYPE_AIS_INDEX: -+ if ((prBssDesc->eBSSType == BSS_TYPE_INFRASTRUCTURE) -+ || (prBssDesc->eBSSType == BSS_TYPE_IBSS)) { -+ fgToRemove = TRUE; -+ } -+ break; -+ -+ case NETWORK_TYPE_P2P_INDEX: -+ if (prBssDesc->eBSSType == BSS_TYPE_P2P_DEVICE) -+ fgToRemove = TRUE; -+ break; -+ -+ case NETWORK_TYPE_BOW_INDEX: -+ if (prBssDesc->eBSSType == BSS_TYPE_BOW_DEVICE) -+ fgToRemove = TRUE; -+ break; -+ -+ default: -+ ASSERT(0); -+ break; -+ } -+ } -+ -+ if (fgToRemove == TRUE) { -+ /* Remove this BSS Desc from the BSS Desc list */ -+ LINK_REMOVE_KNOWN_ENTRY(prBSSDescList, prBssDesc); -+ -+ /* Return this BSS Desc to the free BSS Desc list. */ -+ LINK_INSERT_TAIL(prFreeBSSDescList, &prBssDesc->rLinkEntry); -+ } -+ } -+ -+} /* end of scanRemoveBssDescByBand() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Clear the CONNECTION FLAG of a specified BSS Descriptor. -+* -+* @param[in] aucBSSID Given BSSID. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID scanRemoveConnFlagOfBssDescByBssid(IN P_ADAPTER_T prAdapter, IN UINT_8 aucBSSID[]) -+{ -+ P_SCAN_INFO_T prScanInfo; -+ P_LINK_T prBSSDescList; -+ P_BSS_DESC_T prBssDesc = (P_BSS_DESC_T) NULL; -+ -+ ASSERT(prAdapter); -+ ASSERT(aucBSSID); -+ -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ prBSSDescList = &prScanInfo->rBSSDescList; -+ -+ /* Search BSS Desc from current SCAN result list. */ -+ LINK_FOR_EACH_ENTRY(prBssDesc, prBSSDescList, rLinkEntry, BSS_DESC_T) { -+ -+ if (EQUAL_MAC_ADDR(prBssDesc->aucBSSID, aucBSSID)) { -+ prBssDesc->fgIsConnected = FALSE; -+ prBssDesc->fgIsConnecting = FALSE; -+ -+ /* BSSID is not unique, so need to traverse whols link-list */ -+ } -+ } -+ -+ return; -+ -+} /* end of scanRemoveConnectionFlagOfBssDescByBssid() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Allocate new BSS_DESC_T -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* -+* @return Pointer to BSS Descriptor, if has free space. NULL, if has no space. -+*/ -+/*----------------------------------------------------------------------------*/ -+P_BSS_DESC_T scanAllocateBssDesc(IN P_ADAPTER_T prAdapter) -+{ -+ P_SCAN_INFO_T prScanInfo; -+ P_LINK_T prFreeBSSDescList; -+ P_BSS_DESC_T prBssDesc; -+ -+ ASSERT(prAdapter); -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ -+ prFreeBSSDescList = &prScanInfo->rFreeBSSDescList; -+ -+ LINK_REMOVE_HEAD(prFreeBSSDescList, prBssDesc, P_BSS_DESC_T); -+ -+ if (prBssDesc) { -+ P_LINK_T prBSSDescList; -+ -+ kalMemZero(prBssDesc, sizeof(BSS_DESC_T)); -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ LINK_INITIALIZE(&(prBssDesc->rP2pDeviceList)); -+ prBssDesc->fgIsP2PPresent = FALSE; -+#endif /* CFG_ENABLE_WIFI_DIRECT */ -+ -+ prBSSDescList = &prScanInfo->rBSSDescList; -+ -+ /* NOTE(Kevin): In current design, this new empty BSS_DESC_T will be -+ * inserted to BSSDescList immediately. -+ */ -+ LINK_INSERT_TAIL(prBSSDescList, &prBssDesc->rLinkEntry); -+ } -+ -+ return prBssDesc; -+ -+} /* end of scanAllocateBssDesc() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This API parses Beacon/ProbeResp frame and insert extracted BSS_DESC_T -+* with IEs into prAdapter->rWifiVar.rScanInfo.aucScanBuffer -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* @param[in] prSwRfb Pointer to the receiving frame buffer. -+* -+* @return Pointer to BSS Descriptor -+* NULL if the Beacon/ProbeResp frame is invalid -+*/ -+/*----------------------------------------------------------------------------*/ -+P_BSS_DESC_T scanAddToBssDesc(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb) -+{ -+ P_BSS_DESC_T prBssDesc = NULL; -+ UINT_16 u2CapInfo; -+ ENUM_BSS_TYPE_T eBSSType = BSS_TYPE_INFRASTRUCTURE; -+ -+ PUINT_8 pucIE; -+ UINT_16 u2IELength; -+ UINT_16 u2Offset = 0; -+ -+ P_WLAN_BEACON_FRAME_T prWlanBeaconFrame = (P_WLAN_BEACON_FRAME_T) NULL; -+ P_IE_SSID_T prIeSsid = (P_IE_SSID_T) NULL; -+ P_IE_SUPPORTED_RATE_T prIeSupportedRate = (P_IE_SUPPORTED_RATE_T) NULL; -+ P_IE_EXT_SUPPORTED_RATE_T prIeExtSupportedRate = (P_IE_EXT_SUPPORTED_RATE_T) NULL; -+ P_HIF_RX_HEADER_T prHifRxHdr; -+ UINT_8 ucHwChannelNum = 0; -+ UINT_8 ucIeDsChannelNum = 0; -+ UINT_8 ucIeHtChannelNum = 0; -+ BOOLEAN fgIsValidSsid = FALSE, fgEscape = FALSE; -+ PARAM_SSID_T rSsid; -+ UINT_64 u8Timestamp; -+ BOOLEAN fgIsNewBssDesc = FALSE; -+ -+ UINT_32 i; -+ UINT_8 ucSSIDChar; -+ -+ UINT_8 ucOuiType; -+ UINT_16 u2SubTypeVersion; -+ -+ ASSERT(prAdapter); -+ ASSERT(prSwRfb); -+ -+ prWlanBeaconFrame = (P_WLAN_BEACON_FRAME_T) prSwRfb->pvHeader; -+ -+ WLAN_GET_FIELD_16(&prWlanBeaconFrame->u2CapInfo, &u2CapInfo); -+ WLAN_GET_FIELD_64(&prWlanBeaconFrame->au4Timestamp[0], &u8Timestamp); -+ -+ /* decide BSS type */ -+ switch (u2CapInfo & CAP_INFO_BSS_TYPE) { -+ case CAP_INFO_ESS: -+ /* It can also be Group Owner of P2P Group. */ -+ eBSSType = BSS_TYPE_INFRASTRUCTURE; -+ break; -+ -+ case CAP_INFO_IBSS: -+ eBSSType = BSS_TYPE_IBSS; -+ break; -+ case 0: -+ /* The P2P Device shall set the ESS bit of the Capabilities field -+ * in the Probe Response fame to 0 and IBSS bit to 0. (3.1.2.1.1) */ -+ eBSSType = BSS_TYPE_P2P_DEVICE; -+ break; -+ -+#if CFG_ENABLE_BT_OVER_WIFI -+ /* @TODO: add rule to identify BOW beacons */ -+#endif -+ -+ default: -+ DBGLOG(SCN, ERROR, "wrong bss type %d\n", (INT_32)(u2CapInfo & CAP_INFO_BSS_TYPE)); -+ return NULL; -+ } -+ -+ /* 4 <1.1> Pre-parse SSID IE */ -+ pucIE = prWlanBeaconFrame->aucInfoElem; -+ u2IELength = (prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen) - -+ (UINT_16) OFFSET_OF(WLAN_BEACON_FRAME_BODY_T, aucInfoElem[0]); -+ -+ if (u2IELength > CFG_IE_BUFFER_SIZE) -+ u2IELength = CFG_IE_BUFFER_SIZE; -+ kalMemZero(&rSsid, sizeof(rSsid)); -+ IE_FOR_EACH(pucIE, u2IELength, u2Offset) { -+ switch (IE_ID(pucIE)) { -+ case ELEM_ID_SSID: -+ if (IE_LEN(pucIE) <= ELEM_MAX_LEN_SSID) { -+ ucSSIDChar = '\0'; -+ -+ /* D-Link DWL-900AP+ */ -+ if (IE_LEN(pucIE) == 0) -+ fgIsValidSsid = FALSE; -+ /* Cisco AP1230A - (IE_LEN(pucIE) == 1) && (SSID_IE(pucIE)->aucSSID[0] == '\0') */ -+ /* Linksys WRK54G/WL520g - (IE_LEN(pucIE) == n) && -+ * (SSID_IE(pucIE)->aucSSID[0~(n-1)] == '\0') */ -+ else { -+ for (i = 0; i < IE_LEN(pucIE); i++) -+ ucSSIDChar |= SSID_IE(pucIE)->aucSSID[i]; -+ -+ if (ucSSIDChar) -+ fgIsValidSsid = TRUE; -+ } -+ -+ /* Update SSID to BSS Descriptor only if SSID is not hidden. */ -+ if (fgIsValidSsid == TRUE) { -+ COPY_SSID(rSsid.aucSsid, -+ rSsid.u4SsidLen, SSID_IE(pucIE)->aucSSID, SSID_IE(pucIE)->ucLength); -+ } -+ } -+ fgEscape = TRUE; -+ break; -+ default: -+ break; -+ } -+ -+ if (fgEscape == TRUE) -+ break; -+ } -+ if (fgIsValidSsid) -+ DBGLOG(SCN, EVENT, "%s %pM channel %d\n", rSsid.aucSsid, prWlanBeaconFrame->aucBSSID, -+ HIF_RX_HDR_GET_CHNL_NUM(prSwRfb->prHifRxHdr)); -+ else -+ DBGLOG(SCN, EVENT, "hidden ssid, %pM channel %d\n", prWlanBeaconFrame->aucBSSID, -+ HIF_RX_HDR_GET_CHNL_NUM(prSwRfb->prHifRxHdr)); -+ /* 4 <1.2> Replace existing BSS_DESC_T or allocate a new one */ -+ prBssDesc = scanSearchExistingBssDescWithSsid(prAdapter, -+ eBSSType, -+ (PUINT_8) prWlanBeaconFrame->aucBSSID, -+ (PUINT_8) prWlanBeaconFrame->aucSrcAddr, -+ fgIsValidSsid, fgIsValidSsid == TRUE ? &rSsid : NULL); -+ -+ if (prBssDesc == (P_BSS_DESC_T) NULL) { -+ fgIsNewBssDesc = TRUE; -+ -+ do { -+ /* 4 <1.2.1> First trial of allocation */ -+ prBssDesc = scanAllocateBssDesc(prAdapter); -+ if (prBssDesc) -+ break; -+ /* 4 <1.2.2> Hidden is useless, remove the oldest hidden ssid. (for passive scan) */ -+ scanRemoveBssDescsByPolicy(prAdapter, -+ (SCN_RM_POLICY_EXCLUDE_CONNECTED | SCN_RM_POLICY_OLDEST_HIDDEN)); -+ -+ /* 4 <1.2.3> Second tail of allocation */ -+ prBssDesc = scanAllocateBssDesc(prAdapter); -+ if (prBssDesc) -+ break; -+ /* 4 <1.2.4> Remove the weakest one */ -+ /* If there are more than half of BSS which has the same ssid as connection -+ * setting, remove the weakest one from them. -+ * Else remove the weakest one. -+ */ -+ scanRemoveBssDescsByPolicy(prAdapter, -+ (SCN_RM_POLICY_EXCLUDE_CONNECTED | SCN_RM_POLICY_SMART_WEAKEST)); -+ -+ /* 4 <1.2.5> reallocation */ -+ prBssDesc = scanAllocateBssDesc(prAdapter); -+ if (prBssDesc) -+ break; -+ /* 4 <1.2.6> no space, should not happen */ -+ DBGLOG(SCN, ERROR, "no bss desc available after remove policy\n"); -+ return NULL; -+ -+ } while (FALSE); -+ -+ } else { -+ OS_SYSTIME rCurrentTime; -+ -+ /* WCXRP00000091 */ -+ /* if the received strength is much weaker than the original one, */ -+ /* ignore it due to it might be received on the folding frequency */ -+ -+ GET_CURRENT_SYSTIME(&rCurrentTime); -+ -+ if (prBssDesc->eBSSType != eBSSType) { -+ prBssDesc->eBSSType = eBSSType; -+ } else if (HIF_RX_HDR_GET_CHNL_NUM(prSwRfb->prHifRxHdr) != prBssDesc->ucChannelNum && -+ prBssDesc->ucRCPI > prSwRfb->prHifRxHdr->ucRcpi) { -+ /* for signal strength is too much weaker and previous beacon is not stale */ -+ if ((prBssDesc->ucRCPI - prSwRfb->prHifRxHdr->ucRcpi) >= REPLICATED_BEACON_STRENGTH_THRESHOLD && -+ (rCurrentTime - prBssDesc->rUpdateTime) <= REPLICATED_BEACON_FRESH_PERIOD) { -+ DBGLOG(SCN, EVENT, "rssi is too much weaker and previous one is fresh\n"); -+ return prBssDesc; -+ } -+ /* for received beacons too close in time domain */ -+ else if (rCurrentTime - prBssDesc->rUpdateTime <= REPLICATED_BEACON_TIME_THRESHOLD) { -+ DBGLOG(SCN, EVENT, "receive beacon/probe reponses too close\n"); -+ return prBssDesc; -+ } -+ } -+ -+ /* if Timestamp has been reset, re-generate BSS DESC 'cause AP should have reset itself */ -+ if (prBssDesc->eBSSType == BSS_TYPE_INFRASTRUCTURE && u8Timestamp < prBssDesc->u8TimeStamp.QuadPart) { -+ BOOLEAN fgIsConnected, fgIsConnecting; -+ -+ /* set flag for indicating this is a new BSS-DESC */ -+ fgIsNewBssDesc = TRUE; -+ -+ /* backup 2 flags for APs which reset timestamp unexpectedly */ -+ fgIsConnected = prBssDesc->fgIsConnected; -+ fgIsConnecting = prBssDesc->fgIsConnecting; -+ scanRemoveBssDescByBssid(prAdapter, prBssDesc->aucBSSID); -+ -+ prBssDesc = scanAllocateBssDesc(prAdapter); -+ if (!prBssDesc) -+ return NULL; -+ -+ /* restore */ -+ prBssDesc->fgIsConnected = fgIsConnected; -+ prBssDesc->fgIsConnecting = fgIsConnecting; -+ } -+ } -+#if 1 -+ -+ prBssDesc->u2RawLength = prSwRfb->u2PacketLen; -+ if (prBssDesc->u2RawLength > CFG_RAW_BUFFER_SIZE) -+ prBssDesc->u2RawLength = CFG_RAW_BUFFER_SIZE; -+ kalMemCopy(prBssDesc->aucRawBuf, prWlanBeaconFrame, prBssDesc->u2RawLength); -+#endif -+ -+ /* NOTE: Keep consistency of Scan Record during JOIN process */ -+ if ((fgIsNewBssDesc == FALSE) && prBssDesc->fgIsConnecting) { -+ DBGLOG(SCN, INFO, "we're connecting this BSS(%pM) now, don't update it\n", -+ prBssDesc->aucBSSID); -+ return prBssDesc; -+ } -+ /* 4 <2> Get information from Fixed Fields */ -+ prBssDesc->eBSSType = eBSSType; /* Update the latest BSS type information. */ -+ -+ COPY_MAC_ADDR(prBssDesc->aucSrcAddr, prWlanBeaconFrame->aucSrcAddr); -+ -+ COPY_MAC_ADDR(prBssDesc->aucBSSID, prWlanBeaconFrame->aucBSSID); -+ -+ prBssDesc->u8TimeStamp.QuadPart = u8Timestamp; -+ -+ WLAN_GET_FIELD_16(&prWlanBeaconFrame->u2BeaconInterval, &prBssDesc->u2BeaconInterval); -+ -+ prBssDesc->u2CapInfo = u2CapInfo; -+ -+ /* 4 <2.1> Retrieve IEs for later parsing */ -+ u2IELength = (prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen) - -+ (UINT_16) OFFSET_OF(WLAN_BEACON_FRAME_BODY_T, aucInfoElem[0]); -+ -+ if (u2IELength > CFG_IE_BUFFER_SIZE) { -+ u2IELength = CFG_IE_BUFFER_SIZE; -+ prBssDesc->fgIsIEOverflow = TRUE; -+ } else { -+ prBssDesc->fgIsIEOverflow = FALSE; -+ } -+ prBssDesc->u2IELength = u2IELength; -+ -+ kalMemCopy(prBssDesc->aucIEBuf, prWlanBeaconFrame->aucInfoElem, u2IELength); -+ -+ /* 4 <2.2> reset prBssDesc variables in case that AP has been reconfigured */ -+ prBssDesc->fgIsERPPresent = FALSE; -+ prBssDesc->fgIsHTPresent = FALSE; -+ prBssDesc->eSco = CHNL_EXT_SCN; -+ prBssDesc->fgIEWAPI = FALSE; -+#if CFG_RSN_MIGRATION -+ prBssDesc->fgIERSN = FALSE; -+#endif -+#if CFG_PRIVACY_MIGRATION -+ prBssDesc->fgIEWPA = FALSE; -+#endif -+ -+ /* 4 <3.1> Full IE parsing on SW_RFB_T */ -+ pucIE = prWlanBeaconFrame->aucInfoElem; -+ -+ IE_FOR_EACH(pucIE, u2IELength, u2Offset) { -+ -+ switch (IE_ID(pucIE)) { -+ case ELEM_ID_SSID: -+ if ((!prIeSsid) && /* NOTE(Kevin): for Atheros IOT #1 */ -+ (IE_LEN(pucIE) <= ELEM_MAX_LEN_SSID)) { -+ BOOLEAN fgIsHiddenSSID = FALSE; -+ -+ ucSSIDChar = '\0'; -+ -+ prIeSsid = (P_IE_SSID_T) pucIE; -+ -+ /* D-Link DWL-900AP+ */ -+ if (IE_LEN(pucIE) == 0) -+ fgIsHiddenSSID = TRUE; -+ /* Cisco AP1230A - (IE_LEN(pucIE) == 1) && (SSID_IE(pucIE)->aucSSID[0] == '\0') */ -+ /* Linksys WRK54G/WL520g - (IE_LEN(pucIE) == n) && -+ * (SSID_IE(pucIE)->aucSSID[0~(n-1)] == '\0') */ -+ else { -+ for (i = 0; i < IE_LEN(pucIE); i++) -+ ucSSIDChar |= SSID_IE(pucIE)->aucSSID[i]; -+ -+ if (!ucSSIDChar) -+ fgIsHiddenSSID = TRUE; -+ } -+ -+ /* Update SSID to BSS Descriptor only if SSID is not hidden. */ -+ if (!fgIsHiddenSSID) { -+ COPY_SSID(prBssDesc->aucSSID, -+ prBssDesc->ucSSIDLen, -+ SSID_IE(pucIE)->aucSSID, SSID_IE(pucIE)->ucLength); -+ } -+#if 0 -+ /* -+ After we connect to a hidden SSID, prBssDesc->aucSSID[] will -+ not be empty and prBssDesc->ucSSIDLen will not be 0, -+ so maybe we need to empty prBssDesc->aucSSID[] and set -+ prBssDesc->ucSSIDLen to 0 in prBssDesc to avoid that -+ UI still displays hidden SSID AP in scan list after -+ we disconnect the hidden SSID AP. -+ */ -+ else { -+ prBssDesc->aucSSID[0] = '\0'; -+ prBssDesc->ucSSIDLen = 0; -+ } -+#endif -+ -+ } -+ break; -+ -+ case ELEM_ID_SUP_RATES: -+ /* NOTE(Kevin): Buffalo WHR-G54S's supported rate set IE exceed 8. -+ * IE_LEN(pucIE) == 12, "1(B), 2(B), 5.5(B), 6(B), 9(B), 11(B), -+ * 12(B), 18(B), 24(B), 36(B), 48(B), 54(B)" -+ */ -+ /* TP-LINK will set extra and incorrect ie with ELEM_ID_SUP_RATES */ -+ if ((!prIeSupportedRate) && (IE_LEN(pucIE) <= RATE_NUM)) -+ prIeSupportedRate = SUP_RATES_IE(pucIE); -+ break; -+ -+ case ELEM_ID_DS_PARAM_SET: -+ if (IE_LEN(pucIE) == ELEM_MAX_LEN_DS_PARAMETER_SET) -+ ucIeDsChannelNum = DS_PARAM_IE(pucIE)->ucCurrChnl; -+ break; -+ -+ case ELEM_ID_TIM: -+ if (IE_LEN(pucIE) <= ELEM_MAX_LEN_TIM) -+ prBssDesc->ucDTIMPeriod = TIM_IE(pucIE)->ucDTIMPeriod; -+ break; -+ -+ case ELEM_ID_IBSS_PARAM_SET: -+ if (IE_LEN(pucIE) == ELEM_MAX_LEN_IBSS_PARAMETER_SET) -+ prBssDesc->u2ATIMWindow = IBSS_PARAM_IE(pucIE)->u2ATIMWindow; -+ break; -+ -+#if 0 /* CFG_SUPPORT_802_11D */ -+ case ELEM_ID_COUNTRY_INFO: -+ prBssDesc->prIECountry = (P_IE_COUNTRY_T) pucIE; -+ break; -+#endif -+ -+ case ELEM_ID_ERP_INFO: -+ if (IE_LEN(pucIE) == ELEM_MAX_LEN_ERP) -+ prBssDesc->fgIsERPPresent = TRUE; -+ break; -+ -+ case ELEM_ID_EXTENDED_SUP_RATES: -+ if (!prIeExtSupportedRate) -+ prIeExtSupportedRate = EXT_SUP_RATES_IE(pucIE); -+ break; -+ -+#if CFG_RSN_MIGRATION -+ case ELEM_ID_RSN: -+ if (rsnParseRsnIE(prAdapter, RSN_IE(pucIE), &prBssDesc->rRSNInfo)) { -+ prBssDesc->fgIERSN = TRUE; -+ prBssDesc->u2RsnCap = prBssDesc->rRSNInfo.u2RsnCap; -+ if (prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA2) -+ rsnCheckPmkidCache(prAdapter, prBssDesc); -+ } -+ break; -+#endif -+ -+ case ELEM_ID_HT_CAP: -+ prBssDesc->fgIsHTPresent = TRUE; -+ break; -+ -+ case ELEM_ID_HT_OP: -+ if (IE_LEN(pucIE) != (sizeof(IE_HT_OP_T) - 2)) -+ break; -+ -+ if ((((P_IE_HT_OP_T) pucIE)->ucInfo1 & HT_OP_INFO1_SCO) != CHNL_EXT_RES) { -+ prBssDesc->eSco = (ENUM_CHNL_EXT_T) -+ (((P_IE_HT_OP_T) pucIE)->ucInfo1 & HT_OP_INFO1_SCO); -+ } -+ ucIeHtChannelNum = ((P_IE_HT_OP_T) pucIE)->ucPrimaryChannel; -+ -+ break; -+ -+#if CFG_SUPPORT_WAPI -+ case ELEM_ID_WAPI: -+ if (wapiParseWapiIE(WAPI_IE(pucIE), &prBssDesc->rIEWAPI)) -+ prBssDesc->fgIEWAPI = TRUE; -+ break; -+#endif -+ -+ case ELEM_ID_VENDOR: /* ELEM_ID_P2P, ELEM_ID_WMM */ -+#if CFG_PRIVACY_MIGRATION -+ if (rsnParseCheckForWFAInfoElem(prAdapter, pucIE, &ucOuiType, &u2SubTypeVersion)) { -+ if ((ucOuiType == VENDOR_OUI_TYPE_WPA) && (u2SubTypeVersion == VERSION_WPA)) { -+ -+ if (rsnParseWpaIE(prAdapter, WPA_IE(pucIE), &prBssDesc->rWPAInfo)) -+ prBssDesc->fgIEWPA = TRUE; -+ } -+ } -+#endif -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ if (prAdapter->fgIsP2PRegistered) { -+ if (p2pFuncParseCheckForP2PInfoElem(prAdapter, pucIE, &ucOuiType)) { -+ if (ucOuiType == VENDOR_OUI_TYPE_P2P) -+ prBssDesc->fgIsP2PPresent = TRUE; -+ } -+ } -+#endif /* CFG_ENABLE_WIFI_DIRECT */ -+ break; -+ -+ /* no default */ -+ } -+ } -+ -+ /* 4 <3.2> Save information from IEs - SSID */ -+ /* Update Flag of Hidden SSID for used in SEARCH STATE. */ -+ -+ /* NOTE(Kevin): in current driver, the ucSSIDLen == 0 represent -+ * all cases of hidden SSID. -+ * If the fgIsHiddenSSID == TRUE, it means we didn't get the ProbeResp with -+ * valid SSID. -+ */ -+ if (prBssDesc->ucSSIDLen == 0) -+ prBssDesc->fgIsHiddenSSID = TRUE; -+ else -+ prBssDesc->fgIsHiddenSSID = FALSE; -+ -+ /* 4 <3.3> Check rate information in related IEs. */ -+ if (prIeSupportedRate || prIeExtSupportedRate) { -+ rateGetRateSetFromIEs(prIeSupportedRate, -+ prIeExtSupportedRate, -+ &prBssDesc->u2OperationalRateSet, -+ &prBssDesc->u2BSSBasicRateSet, &prBssDesc->fgIsUnknownBssBasicRate); -+ } -+ /* 4 <4> Update information from HIF RX Header */ -+ { -+ prHifRxHdr = prSwRfb->prHifRxHdr; -+ -+ ASSERT(prHifRxHdr); -+ -+ /* 4 <4.1> Get TSF comparison result */ -+ prBssDesc->fgIsLargerTSF = HIF_RX_HDR_GET_TCL_FLAG(prHifRxHdr); -+ -+ /* 4 <4.2> Get Band information */ -+ prBssDesc->eBand = HIF_RX_HDR_GET_RF_BAND(prHifRxHdr); -+ -+ /* 4 <4.2> Get channel and RCPI information */ -+ ucHwChannelNum = HIF_RX_HDR_GET_CHNL_NUM(prHifRxHdr); -+ -+ if (BAND_2G4 == prBssDesc->eBand) { -+ -+ /* Update RCPI if in right channel */ -+ if (ucIeDsChannelNum >= 1 && ucIeDsChannelNum <= 14) { -+ -+ /* Receive Beacon/ProbeResp frame from adjacent channel. */ -+ if ((ucIeDsChannelNum == ucHwChannelNum) || (prHifRxHdr->ucRcpi > prBssDesc->ucRCPI)) -+ prBssDesc->ucRCPI = prHifRxHdr->ucRcpi; -+ /* trust channel information brought by IE */ -+ prBssDesc->ucChannelNum = ucIeDsChannelNum; -+ } else if (ucIeHtChannelNum >= 1 && ucIeHtChannelNum <= 14) { -+ /* Receive Beacon/ProbeResp frame from adjacent channel. */ -+ if ((ucIeHtChannelNum == ucHwChannelNum) || (prHifRxHdr->ucRcpi > prBssDesc->ucRCPI)) -+ prBssDesc->ucRCPI = prHifRxHdr->ucRcpi; -+ /* trust channel information brought by IE */ -+ prBssDesc->ucChannelNum = ucIeHtChannelNum; -+ } else { -+ prBssDesc->ucRCPI = prHifRxHdr->ucRcpi; -+ -+ prBssDesc->ucChannelNum = ucHwChannelNum; -+ } -+ } -+ /* 5G Band */ -+ else { -+ if (ucIeHtChannelNum >= 1 && ucIeHtChannelNum < 200) { -+ /* Receive Beacon/ProbeResp frame from adjacent channel. */ -+ if ((ucIeHtChannelNum == ucHwChannelNum) || (prHifRxHdr->ucRcpi > prBssDesc->ucRCPI)) -+ prBssDesc->ucRCPI = prHifRxHdr->ucRcpi; -+ /* trust channel information brought by IE */ -+ prBssDesc->ucChannelNum = ucIeHtChannelNum; -+ } else { -+ /* Always update RCPI */ -+ prBssDesc->ucRCPI = prHifRxHdr->ucRcpi; -+ -+ prBssDesc->ucChannelNum = ucHwChannelNum; -+ } -+ } -+ } -+ -+ /* 4 <5> PHY type setting */ -+ prBssDesc->ucPhyTypeSet = 0; -+ -+ if (BAND_2G4 == prBssDesc->eBand) { -+ /* check if support 11n */ -+ if (prBssDesc->fgIsHTPresent) -+ prBssDesc->ucPhyTypeSet |= PHY_TYPE_BIT_HT; -+ -+ /* if not 11n only */ -+ if (!(prBssDesc->u2BSSBasicRateSet & RATE_SET_BIT_HT_PHY)) { -+ /* check if support 11g */ -+ if ((prBssDesc->u2OperationalRateSet & RATE_SET_OFDM) || prBssDesc->fgIsERPPresent) -+ prBssDesc->ucPhyTypeSet |= PHY_TYPE_BIT_ERP; -+ -+ /* if not 11g only */ -+ if (!(prBssDesc->u2BSSBasicRateSet & RATE_SET_OFDM)) { -+ /* check if support 11b */ -+ if ((prBssDesc->u2OperationalRateSet & RATE_SET_HR_DSSS)) -+ prBssDesc->ucPhyTypeSet |= PHY_TYPE_BIT_HR_DSSS; -+ } -+ } -+ } else { /* (BAND_5G == prBssDesc->eBande) */ -+ /* check if support 11n */ -+ if (prBssDesc->fgIsHTPresent) -+ prBssDesc->ucPhyTypeSet |= PHY_TYPE_BIT_HT; -+ -+ /* if not 11n only */ -+ if (!(prBssDesc->u2BSSBasicRateSet & RATE_SET_BIT_HT_PHY)) { -+ /* Support 11a definitely */ -+ prBssDesc->ucPhyTypeSet |= PHY_TYPE_BIT_OFDM; -+ -+ ASSERT(!(prBssDesc->u2OperationalRateSet & RATE_SET_HR_DSSS)); -+ } -+ } -+ -+ /* 4 <6> Update BSS_DESC_T's Last Update TimeStamp. */ -+ GET_CURRENT_SYSTIME(&prBssDesc->rUpdateTime); -+ -+ return prBssDesc; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Convert the Beacon or ProbeResp Frame in SW_RFB_T to scan result for query -+* -+* @param[in] prSwRfb Pointer to the receiving SW_RFB_T structure. -+* -+* @retval WLAN_STATUS_SUCCESS It is a valid Scan Result and been sent to the host. -+* @retval WLAN_STATUS_FAILURE It is not a valid Scan Result. -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS scanAddScanResult(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBssDesc, IN P_SW_RFB_T prSwRfb) -+{ -+ P_SCAN_INFO_T prScanInfo; -+ UINT_8 aucRatesEx[PARAM_MAX_LEN_RATES_EX]; -+ P_WLAN_BEACON_FRAME_T prWlanBeaconFrame; -+ PARAM_MAC_ADDRESS rMacAddr; -+ PARAM_SSID_T rSsid; -+ ENUM_PARAM_NETWORK_TYPE_T eNetworkType; -+ PARAM_802_11_CONFIG_T rConfiguration; -+ ENUM_PARAM_OP_MODE_T eOpMode; -+ UINT_8 ucRateLen = 0; -+ UINT_32 i; -+ -+ ASSERT(prAdapter); -+ ASSERT(prSwRfb); -+ -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ -+ if (prBssDesc->eBand == BAND_2G4) { -+ if ((prBssDesc->u2OperationalRateSet & RATE_SET_OFDM) -+ || prBssDesc->fgIsERPPresent) { -+ eNetworkType = PARAM_NETWORK_TYPE_OFDM24; -+ } else { -+ eNetworkType = PARAM_NETWORK_TYPE_DS; -+ } -+ } else { -+ ASSERT(prBssDesc->eBand == BAND_5G); -+ eNetworkType = PARAM_NETWORK_TYPE_OFDM5; -+ } -+ -+ if (prBssDesc->eBSSType == BSS_TYPE_P2P_DEVICE) { -+ /* NOTE(Kevin): Not supported by WZC(TBD) */ -+ return WLAN_STATUS_FAILURE; -+ } -+ -+ prWlanBeaconFrame = (P_WLAN_BEACON_FRAME_T) prSwRfb->pvHeader; -+ COPY_MAC_ADDR(rMacAddr, prWlanBeaconFrame->aucBSSID); -+ COPY_SSID(rSsid.aucSsid, rSsid.u4SsidLen, prBssDesc->aucSSID, prBssDesc->ucSSIDLen); -+ -+ rConfiguration.u4Length = sizeof(PARAM_802_11_CONFIG_T); -+ rConfiguration.u4BeaconPeriod = (UINT_32) prWlanBeaconFrame->u2BeaconInterval; -+ rConfiguration.u4ATIMWindow = prBssDesc->u2ATIMWindow; -+ rConfiguration.u4DSConfig = nicChannelNum2Freq(prBssDesc->ucChannelNum); -+ rConfiguration.rFHConfig.u4Length = sizeof(PARAM_802_11_CONFIG_FH_T); -+ -+ rateGetDataRatesFromRateSet(prBssDesc->u2OperationalRateSet, 0, aucRatesEx, &ucRateLen); -+ -+ /* NOTE(Kevin): Set unused entries, if any, at the end of the array to 0. -+ * from OID_802_11_BSSID_LIST -+ */ -+ for (i = ucRateLen; i < sizeof(aucRatesEx) / sizeof(aucRatesEx[0]); i++) -+ aucRatesEx[i] = 0; -+ -+ switch (prBssDesc->eBSSType) { -+ case BSS_TYPE_IBSS: -+ eOpMode = NET_TYPE_IBSS; -+ break; -+ -+ case BSS_TYPE_INFRASTRUCTURE: -+ case BSS_TYPE_P2P_DEVICE: -+ case BSS_TYPE_BOW_DEVICE: -+ default: -+ eOpMode = NET_TYPE_INFRA; -+ break; -+ } -+ -+ DBGLOG(SCN, TRACE, "ind %s %d\n", prBssDesc->aucSSID, prBssDesc->ucChannelNum); -+ -+#if (CFG_SUPPORT_TDLS == 1) -+ { -+ if (flgTdlsTestExtCapElm == TRUE) { -+ /* only for RALINK AP */ -+ UINT8 *pucElm = (UINT8 *) (prSwRfb->pvHeader + prSwRfb->u2PacketLen); -+ -+ kalMemCopy(pucElm - 9, aucTdlsTestExtCapElm, 7); -+ prSwRfb->u2PacketLen -= 2; -+/* prSwRfb->u2PacketLen += 7; */ -+ -+ DBGLOG(TDLS, INFO, -+ " %s: append ext cap element to %pM\n", -+ __func__, prBssDesc->aucBSSID); -+ } -+ } -+#endif /* CFG_SUPPORT_TDLS */ -+ -+ if (prAdapter->rWifiVar.rScanInfo.fgNloScanning && -+ test_bit(SUSPEND_FLAG_CLEAR_WHEN_RESUME, &prAdapter->ulSuspendFlag)) { -+ UINT_8 i = 0; -+ P_BSS_DESC_T *pprPendBssDesc = &prScanInfo->rNloParam.aprPendingBssDescToInd[0]; -+ -+ for (; i < SCN_SSID_MATCH_MAX_NUM; i++) { -+ if (pprPendBssDesc[i]) -+ continue; -+ DBGLOG(SCN, INFO, -+ "indicate bss[%pM] before wiphy resume, need to indicate again after wiphy resume\n", -+ prBssDesc->aucBSSID); -+ pprPendBssDesc[i] = prBssDesc; -+ break; -+ } -+ } -+ -+ kalIndicateBssInfo(prAdapter->prGlueInfo, -+ (PUINT_8) prSwRfb->pvHeader, -+ prSwRfb->u2PacketLen, prBssDesc->ucChannelNum, RCPI_TO_dBm(prBssDesc->ucRCPI)); -+ -+ nicAddScanResult(prAdapter, -+ rMacAddr, -+ &rSsid, -+ prWlanBeaconFrame->u2CapInfo & CAP_INFO_PRIVACY ? 1 : 0, -+ RCPI_TO_dBm(prBssDesc->ucRCPI), -+ eNetworkType, -+ &rConfiguration, -+ eOpMode, -+ aucRatesEx, -+ prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen, -+ (PUINT_8) ((ULONG) (prSwRfb->pvHeader) + WLAN_MAC_MGMT_HEADER_LEN)); -+ -+ return WLAN_STATUS_SUCCESS; -+ -+} /* end of scanAddScanResult() */ -+ -+#if 1 -+ -+BOOLEAN scanCheckBssIsLegal(IN P_ADAPTER_T prAdapter, P_BSS_DESC_T prBssDesc) -+{ -+ BOOLEAN fgAddToScanResult = FALSE; -+ ENUM_BAND_T eBand = 0; -+ UINT_8 ucChannel = 0; -+ -+ ASSERT(prAdapter); -+ /* check the channel is in the legal doamin */ -+ if (rlmDomainIsLegalChannel(prAdapter, prBssDesc->eBand, prBssDesc->ucChannelNum) == TRUE) { -+ /* check ucChannelNum/eBand for adjacement channel filtering */ -+ if (cnmAisInfraChannelFixed(prAdapter, &eBand, &ucChannel) == TRUE && -+ (eBand != prBssDesc->eBand || ucChannel != prBssDesc->ucChannelNum)) { -+ fgAddToScanResult = FALSE; -+ } else { -+ fgAddToScanResult = TRUE; -+ } -+ } -+ return fgAddToScanResult; -+ -+} -+ -+VOID scanReportBss2Cfg80211(IN P_ADAPTER_T prAdapter, IN ENUM_BSS_TYPE_T eBSSType, IN P_BSS_DESC_T SpecificprBssDesc) -+{ -+ P_SCAN_INFO_T prScanInfo = (P_SCAN_INFO_T) NULL; -+ P_LINK_T prBSSDescList = (P_LINK_T) NULL; -+ P_BSS_DESC_T prBssDesc = (P_BSS_DESC_T) NULL; -+ RF_CHANNEL_INFO_T rChannelInfo; -+ -+ ASSERT(prAdapter); -+ -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ -+ prBSSDescList = &prScanInfo->rBSSDescList; -+ -+ DBGLOG(SCN, TRACE, "scanReportBss2Cfg80211\n"); -+ -+ if (SpecificprBssDesc) { -+ { -+ /* check BSSID is legal channel */ -+ if (!scanCheckBssIsLegal(prAdapter, SpecificprBssDesc)) { -+ DBGLOG(SCN, TRACE, "Remove specific SSID[%s %d]\n", -+ SpecificprBssDesc->aucSSID, SpecificprBssDesc->ucChannelNum); -+ return; -+ } -+ -+ DBGLOG(SCN, TRACE, "Report Specific SSID[%s]\n", SpecificprBssDesc->aucSSID); -+ if (eBSSType == BSS_TYPE_INFRASTRUCTURE) { -+ -+ kalIndicateBssInfo(prAdapter->prGlueInfo, -+ (PUINT_8) SpecificprBssDesc->aucRawBuf, -+ SpecificprBssDesc->u2RawLength, -+ SpecificprBssDesc->ucChannelNum, -+ RCPI_TO_dBm(SpecificprBssDesc->ucRCPI)); -+ } else { -+ -+ rChannelInfo.ucChannelNum = SpecificprBssDesc->ucChannelNum; -+ rChannelInfo.eBand = SpecificprBssDesc->eBand; -+ kalP2PIndicateBssInfo(prAdapter->prGlueInfo, -+ (PUINT_8) SpecificprBssDesc->aucRawBuf, -+ SpecificprBssDesc->u2RawLength, -+ &rChannelInfo, RCPI_TO_dBm(SpecificprBssDesc->ucRCPI)); -+ -+ } -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ SpecificprBssDesc->fgIsP2PReport = FALSE; -+#endif -+ } -+ } else { -+ /* Search BSS Desc from current SCAN result list. */ -+ LINK_FOR_EACH_ENTRY(prBssDesc, prBSSDescList, rLinkEntry, BSS_DESC_T) { -+ -+#if CFG_AUTO_CHANNEL_SEL_SUPPORT -+ /* 4 Auto Channel Selection:Record the AP Number */ -+ P_PARAM_CHN_LOAD_INFO prChnLoad; -+ UINT_8 ucIdx = 0; -+ -+ if (((prBssDesc->ucChannelNum > 0) && (prBssDesc->ucChannelNum <= 48)) -+ || (prBssDesc->ucChannelNum >= 147) /*non-DFS Channel */) { -+ if (prBssDesc->ucChannelNum <= HW_CHNL_NUM_MAX_2G4) { -+ ucIdx = prBssDesc->ucChannelNum - 1; -+ } else if (prBssDesc->ucChannelNum <= 48) { -+ ucIdx = (UINT_8) (HW_CHNL_NUM_MAX_2G4 + (prBssDesc->ucChannelNum - 34) / 4); -+ } else { -+ ucIdx = -+ (UINT_8) (HW_CHNL_NUM_MAX_2G4 + 4 + (prBssDesc->ucChannelNum - 149) / 4); -+ } -+ -+ if (ucIdx < MAX_AUTO_CHAL_NUM) { -+ prChnLoad = (P_PARAM_CHN_LOAD_INFO) & -+ (prAdapter->rWifiVar.rChnLoadInfo.rEachChnLoad[ucIdx]); -+ prChnLoad->ucChannel = prBssDesc->ucChannelNum; -+ prChnLoad->u2APNum++; -+ } else { -+ DBGLOG(SCN, WARN, "ACS: ChIdx > MAX_AUTO_CHAL_NUM\n"); -+ } -+ -+ } -+#endif -+ /* check BSSID is legal channel */ -+ if (!scanCheckBssIsLegal(prAdapter, prBssDesc)) { -+ DBGLOG(SCN, TRACE, "Remove SSID[%s %d]\n", -+ prBssDesc->aucSSID, prBssDesc->ucChannelNum); -+ -+ continue; -+ } -+ -+ if ((prBssDesc->eBSSType == eBSSType) -+#if CFG_ENABLE_WIFI_DIRECT -+ || ((eBSSType == BSS_TYPE_P2P_DEVICE) && (prBssDesc->fgIsP2PReport == TRUE)) -+#endif -+ ) { -+ -+ DBGLOG(SCN, TRACE, "Report ALL SSID[%s %d]\n", -+ prBssDesc->aucSSID, prBssDesc->ucChannelNum); -+ -+ if (eBSSType == BSS_TYPE_INFRASTRUCTURE) { -+ if (prBssDesc->u2RawLength != 0) { -+ kalIndicateBssInfo(prAdapter->prGlueInfo, -+ (PUINT_8) prBssDesc->aucRawBuf, -+ prBssDesc->u2RawLength, -+ prBssDesc->ucChannelNum, -+ RCPI_TO_dBm(prBssDesc->ucRCPI)); -+ kalMemZero(prBssDesc->aucRawBuf, CFG_RAW_BUFFER_SIZE); -+ prBssDesc->u2RawLength = 0; -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ prBssDesc->fgIsP2PReport = FALSE; -+#endif -+ } -+ } else { -+#if CFG_ENABLE_WIFI_DIRECT -+ if (prBssDesc->fgIsP2PReport == TRUE) { -+#endif -+ rChannelInfo.ucChannelNum = prBssDesc->ucChannelNum; -+ rChannelInfo.eBand = prBssDesc->eBand; -+ -+ kalP2PIndicateBssInfo(prAdapter->prGlueInfo, -+ (PUINT_8) prBssDesc->aucRawBuf, -+ prBssDesc->u2RawLength, -+ &rChannelInfo, RCPI_TO_dBm(prBssDesc->ucRCPI)); -+ -+ /* do not clear it then we can pass the bss in Specific report */ -+ /* kalMemZero(prBssDesc->aucRawBuf,CFG_RAW_BUFFER_SIZE); */ -+ -+ /* -+ the BSS entry will not be cleared after scan done. -+ So if we dont receive the BSS in next scan, we cannot -+ pass it. We use u2RawLength for the purpose. -+ */ -+ /* prBssDesc->u2RawLength=0; */ -+#if CFG_ENABLE_WIFI_DIRECT -+ prBssDesc->fgIsP2PReport = FALSE; -+ } -+#endif -+ } -+ } -+ -+ } -+#if CFG_AUTO_CHANNEL_SEL_SUPPORT -+ prAdapter->rWifiVar.rChnLoadInfo.fgDataReadyBit = TRUE; -+#endif -+ -+ } -+ -+} -+ -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Parse the content of given Beacon or ProbeResp Frame. -+* -+* @param[in] prSwRfb Pointer to the receiving SW_RFB_T structure. -+* -+* @retval WLAN_STATUS_SUCCESS if not report this SW_RFB_T to host -+* @retval WLAN_STATUS_PENDING if report this SW_RFB_T to host as scan result -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS scanProcessBeaconAndProbeResp(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb) -+{ -+ P_CONNECTION_SETTINGS_T prConnSettings; -+ P_BSS_DESC_T prBssDesc = (P_BSS_DESC_T) NULL; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ P_BSS_INFO_T prAisBssInfo; -+ P_WLAN_BEACON_FRAME_T prWlanBeaconFrame = (P_WLAN_BEACON_FRAME_T) NULL; -+#if CFG_SLT_SUPPORT -+ P_SLT_INFO_T prSltInfo = (P_SLT_INFO_T) NULL; -+#endif -+ -+ ASSERT(prAdapter); -+ ASSERT(prSwRfb); -+ -+ /* 4 <0> Ignore invalid Beacon Frame */ -+ if ((prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen) < -+ (TIMESTAMP_FIELD_LEN + BEACON_INTERVAL_FIELD_LEN + CAP_INFO_FIELD_LEN)) { -+ /* to debug beacon length too small issue */ -+ UINT_32 u4MailBox0; -+ -+ nicGetMailbox(prAdapter, 0, &u4MailBox0); -+ DBGLOG(SCN, WARN, "if conn sys also get less length (0x5a means yes) %x\n", (UINT_32) u4MailBox0); -+ DBGLOG(SCN, WARN, "u2PacketLen %d, u2HeaderLen %d, payloadLen %d\n", -+ prSwRfb->u2PacketLen, prSwRfb->u2HeaderLen, -+ prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen); -+ /* dumpMemory8(prSwRfb->pvHeader, prSwRfb->u2PacketLen); */ -+ -+#ifndef _lint -+ ASSERT(0); -+#endif /* _lint */ -+ return rStatus; -+ } -+#if CFG_SLT_SUPPORT -+ prSltInfo = &prAdapter->rWifiVar.rSltInfo; -+ -+ if (prSltInfo->fgIsDUT) { -+ DBGLOG(SCN, INFO, "\n\rBCN: RX\n"); -+ prSltInfo->u4BeaconReceiveCnt++; -+ return WLAN_STATUS_SUCCESS; -+ } else { -+ return WLAN_STATUS_SUCCESS; -+ } -+#endif -+ -+ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); -+ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ prWlanBeaconFrame = (P_WLAN_BEACON_FRAME_T) prSwRfb->pvHeader; -+ -+ /*ALPS01475157: don't show SSID on scan list for multicast MAC AP */ -+ if (IS_BMCAST_MAC_ADDR(prWlanBeaconFrame->aucSrcAddr)) { -+ DBGLOG(SCN, WARN, "received beacon/probe response from multicast AP\n"); -+ return rStatus; -+ } -+ -+ /* 4 <1> Parse and add into BSS_DESC_T */ -+ prBssDesc = scanAddToBssDesc(prAdapter, prSwRfb); -+ -+ if (prBssDesc) { -+ /* 4 <1.1> Beacon Change Detection for Connected BSS */ -+ if (prAisBssInfo->eConnectionState == PARAM_MEDIA_STATE_CONNECTED && -+ ((prBssDesc->eBSSType == BSS_TYPE_INFRASTRUCTURE && prConnSettings->eOPMode != NET_TYPE_IBSS) -+ || (prBssDesc->eBSSType == BSS_TYPE_IBSS && prConnSettings->eOPMode != NET_TYPE_INFRA)) && -+ EQUAL_MAC_ADDR(prBssDesc->aucBSSID, prAisBssInfo->aucBSSID) && -+ EQUAL_SSID(prBssDesc->aucSSID, prBssDesc->ucSSIDLen, prAisBssInfo->aucSSID, -+ prAisBssInfo->ucSSIDLen)) { -+ BOOLEAN fgNeedDisconnect = FALSE; -+ -+#if CFG_SUPPORT_BEACON_CHANGE_DETECTION -+ /* <1.1.2> check if supported rate differs */ -+ if (prAisBssInfo->u2OperationalRateSet != prBssDesc->u2OperationalRateSet) -+ fgNeedDisconnect = TRUE; -+#endif -+#if CFG_SUPPORT_DETECT_SECURITY_MODE_CHANGE -+ if ( -+#if CFG_SUPPORT_WAPI -+ (prAdapter->rWifiVar.rConnSettings.fgWapiMode == TRUE && -+ !wapiPerformPolicySelection(prAdapter, prBssDesc)) || -+#endif -+ rsnCheckSecurityModeChanged(prAdapter, prAisBssInfo, prBssDesc)) { -+ DBGLOG(SCN, INFO, "Beacon security mode change detected\n"); -+ fgNeedDisconnect = FALSE; -+ aisBssSecurityChanged(prAdapter); -+ } -+#endif -+ -+ /* <1.1.3> beacon content change detected, disconnect immediately */ -+ if (fgNeedDisconnect == TRUE) -+ aisBssBeaconTimeout(prAdapter); -+ } -+ /* 4 <1.1> Update AIS_BSS_INFO */ -+ if (((prBssDesc->eBSSType == BSS_TYPE_INFRASTRUCTURE && prConnSettings->eOPMode != NET_TYPE_IBSS) -+ || (prBssDesc->eBSSType == BSS_TYPE_IBSS && prConnSettings->eOPMode != NET_TYPE_INFRA))) { -+ if (prAisBssInfo->eConnectionState == PARAM_MEDIA_STATE_CONNECTED) { -+ /* *not* checking prBssDesc->fgIsConnected anymore, -+ * due to Linksys AP uses " " as hidden SSID, and would have different BSS descriptor */ -+ if ((!prAisBssInfo->ucDTIMPeriod) && -+ EQUAL_MAC_ADDR(prBssDesc->aucBSSID, prAisBssInfo->aucBSSID) && -+ (prAisBssInfo->eCurrentOPMode == OP_MODE_INFRASTRUCTURE) && -+ ((prWlanBeaconFrame->u2FrameCtrl & MASK_FRAME_TYPE) == MAC_FRAME_BEACON)) { -+ -+ prAisBssInfo->ucDTIMPeriod = prBssDesc->ucDTIMPeriod; -+ -+ /* sync with firmware for beacon information */ -+ nicPmIndicateBssConnected(prAdapter, NETWORK_TYPE_AIS_INDEX); -+ } -+ } -+#if CFG_SUPPORT_ADHOC -+ if (EQUAL_SSID(prBssDesc->aucSSID, -+ prBssDesc->ucSSIDLen, -+ prConnSettings->aucSSID, -+ prConnSettings->ucSSIDLen) && -+ (prBssDesc->eBSSType == BSS_TYPE_IBSS) && (prAisBssInfo->eCurrentOPMode == OP_MODE_IBSS)) { -+ ibssProcessMatchedBeacon(prAdapter, prAisBssInfo, prBssDesc, -+ prSwRfb->prHifRxHdr->ucRcpi); -+ } -+#endif /* CFG_SUPPORT_ADHOC */ -+ } -+ -+ rlmProcessBcn(prAdapter, -+ prSwRfb, -+ ((P_WLAN_BEACON_FRAME_T) (prSwRfb->pvHeader))->aucInfoElem, -+ (prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen) - -+ (UINT_16) (OFFSET_OF(WLAN_BEACON_FRAME_BODY_T, aucInfoElem[0]))); -+ -+ /* 4 <3> Send SW_RFB_T to HIF when we perform SCAN for HOST */ -+ if (prBssDesc->eBSSType == BSS_TYPE_INFRASTRUCTURE || prBssDesc->eBSSType == BSS_TYPE_IBSS) { -+ /* for AIS, send to host */ -+ if (prConnSettings->fgIsScanReqIssued || prAdapter->rWifiVar.rScanInfo.fgNloScanning) { -+ BOOLEAN fgAddToScanResult; -+ -+ fgAddToScanResult = scanCheckBssIsLegal(prAdapter, prBssDesc); -+ -+ if (fgAddToScanResult == TRUE) -+ rStatus = scanAddScanResult(prAdapter, prBssDesc, prSwRfb); -+ } -+ } -+#if CFG_ENABLE_WIFI_DIRECT -+ if (prAdapter->fgIsP2PRegistered) -+ scanP2pProcessBeaconAndProbeResp(prAdapter, prSwRfb, &rStatus, prBssDesc, prWlanBeaconFrame); -+#endif -+ } -+ -+ return rStatus; -+ -+} /* end of scanProcessBeaconAndProbeResp() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Search the Candidate of BSS Descriptor for JOIN(Infrastructure) or -+* MERGE(AdHoc) according to current Connection Policy. -+* -+* \return Pointer to BSS Descriptor, if found. NULL, if not found -+*/ -+/*----------------------------------------------------------------------------*/ -+P_BSS_DESC_T scanSearchBssDescByPolicy(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex) -+{ -+ P_CONNECTION_SETTINGS_T prConnSettings; -+ P_BSS_INFO_T prBssInfo; -+ P_AIS_SPECIFIC_BSS_INFO_T prAisSpecBssInfo; -+ P_SCAN_INFO_T prScanInfo; -+ -+ P_LINK_T prBSSDescList; -+ -+ P_BSS_DESC_T prBssDesc = (P_BSS_DESC_T) NULL; -+ P_BSS_DESC_T prPrimaryBssDesc = (P_BSS_DESC_T) NULL; -+ P_BSS_DESC_T prCandidateBssDesc = (P_BSS_DESC_T) NULL; -+ -+ P_STA_RECORD_T prStaRec = (P_STA_RECORD_T) NULL; -+ P_STA_RECORD_T prPrimaryStaRec; -+ P_STA_RECORD_T prCandidateStaRec = (P_STA_RECORD_T) NULL; -+ -+ OS_SYSTIME rCurrentTime; -+ -+ /* The first one reach the check point will be our candidate */ -+ BOOLEAN fgIsFindFirst = (BOOLEAN) FALSE; -+ -+ BOOLEAN fgIsFindBestRSSI = (BOOLEAN) FALSE; -+ BOOLEAN fgIsFindBestEncryptionLevel = (BOOLEAN) FALSE; -+ /* BOOLEAN fgIsFindMinChannelLoad = (BOOLEAN)FALSE; */ -+ -+ /* TODO(Kevin): Support Min Channel Load */ -+ /* UINT_8 aucChannelLoad[CHANNEL_NUM] = {0}; */ -+ -+ BOOLEAN fgIsFixedChannel; -+ ENUM_BAND_T eBand = 0; -+ UINT_8 ucChannel = 0; -+ -+ ASSERT(prAdapter); -+ -+ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[eNetTypeIndex]); -+ -+ prAisSpecBssInfo = &(prAdapter->rWifiVar.rAisSpecificBssInfo); -+ -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ prBSSDescList = &prScanInfo->rBSSDescList; -+ -+ GET_CURRENT_SYSTIME(&rCurrentTime); -+ -+ /* check for fixed channel operation */ -+ if (eNetTypeIndex == NETWORK_TYPE_AIS_INDEX) { -+#if CFG_P2P_LEGACY_COEX_REVISE -+ fgIsFixedChannel = cnmAisDetectP2PChannel(prAdapter, &eBand, &ucChannel); -+#else -+ fgIsFixedChannel = cnmAisInfraChannelFixed(prAdapter, &eBand, &ucChannel); -+#endif -+ } else { -+ fgIsFixedChannel = FALSE; -+ } -+ -+#if DBG -+ if (prConnSettings->ucSSIDLen < ELEM_MAX_LEN_SSID) -+ prConnSettings->aucSSID[prConnSettings->ucSSIDLen] = '\0'; -+#endif -+ -+ DBGLOG(SCN, INFO, "SEARCH: Bss Num: %d, Look for SSID: %s, %pM Band=%d, channel=%d\n", -+ (UINT_32) prBSSDescList->u4NumElem, prConnSettings->aucSSID, -+ (prConnSettings->aucBSSID), eBand, ucChannel); -+ -+ /* 4 <1> The outer loop to search for a candidate. */ -+ LINK_FOR_EACH_ENTRY(prBssDesc, prBSSDescList, rLinkEntry, BSS_DESC_T) { -+ -+ /* TODO(Kevin): Update Minimum Channel Load Information here */ -+ -+ DBGLOG(SCN, TRACE, "SEARCH: [ %pM ], SSID:%s\n", -+ prBssDesc->aucBSSID, prBssDesc->aucSSID); -+ -+ /* 4 <2> Check PHY Type and attributes */ -+ /* 4 <2.1> Check Unsupported BSS PHY Type */ -+ if (!(prBssDesc->ucPhyTypeSet & (prAdapter->rWifiVar.ucAvailablePhyTypeSet))) { -+ DBGLOG(SCN, TRACE, "SEARCH: Ignore unsupported ucPhyTypeSet = %x\n", prBssDesc->ucPhyTypeSet); -+ continue; -+ } -+ /* 4 <2.2> Check if has unknown NonHT BSS Basic Rate Set. */ -+ if (prBssDesc->fgIsUnknownBssBasicRate) -+ continue; -+ /* 4 <2.3> Check if fixed operation cases should be aware */ -+ if (fgIsFixedChannel == TRUE && (prBssDesc->eBand != eBand || prBssDesc->ucChannelNum != ucChannel)) -+ continue; -+ /* 4 <2.4> Check if the channel is legal under regulatory domain */ -+ if (rlmDomainIsLegalChannel(prAdapter, prBssDesc->eBand, prBssDesc->ucChannelNum) == FALSE) -+ continue; -+ /* 4 <2.5> Check if this BSS_DESC_T is stale */ -+ if (CHECK_FOR_TIMEOUT(rCurrentTime, prBssDesc->rUpdateTime, -+ SEC_TO_SYSTIME(SCN_BSS_DESC_REMOVE_TIMEOUT_SEC))) { -+ -+ BOOLEAN fgIsNeedToCheckTimeout = TRUE; -+ -+#if CFG_SUPPORT_ROAMING -+ P_ROAMING_INFO_T prRoamingFsmInfo; -+ -+ prRoamingFsmInfo = (P_ROAMING_INFO_T) &(prAdapter->rWifiVar.rRoamingInfo); -+ if ((prRoamingFsmInfo->eCurrentState == ROAMING_STATE_DISCOVERY) || -+ (prRoamingFsmInfo->eCurrentState == ROAMING_STATE_ROAM)) { -+ if (++prRoamingFsmInfo->RoamingEntryTimeoutSkipCount < -+ ROAMING_ENTRY_TIMEOUT_SKIP_COUNT_MAX) { -+ fgIsNeedToCheckTimeout = FALSE; -+ DBGLOG(SCN, INFO, "SEARCH: Romaing skip SCN_BSS_DESC_REMOVE_TIMEOUT_SEC\n"); -+ } -+ } -+#endif -+ -+ if (fgIsNeedToCheckTimeout == TRUE) { -+ DBGLOG(SCN, TRACE, "Ignore stale bss %pM\n", prBssDesc->aucBSSID); -+ continue; -+ } -+ } -+ /* 4 <3> Check if reach the excessive join retry limit */ -+ /* NOTE(Kevin): STA_RECORD_T is recorded by TA. */ -+ prStaRec = cnmGetStaRecByAddress(prAdapter, (UINT_8) eNetTypeIndex, prBssDesc->aucSrcAddr); -+ -+ if (prStaRec) { -+ /* NOTE(Kevin): -+ * The Status Code is the result of a Previous Connection Request, -+ * we use this as SCORE for choosing a proper -+ * candidate (Also used for compare see <6>) -+ * The Reason Code is an indication of the reason why AP reject us, -+ * we use this Code for "Reject" -+ * a SCAN result to become our candidate(Like a blacklist). -+ */ -+#if 0 /* TODO(Kevin): */ -+ if (prStaRec->u2ReasonCode != REASON_CODE_RESERVED) { -+ DBGLOG(SCN, INFO, "SEARCH: Ignore BSS with previous Reason Code = %d\n", -+ prStaRec->u2ReasonCode); -+ continue; -+ } else -+#endif -+ if (prStaRec->u2StatusCode != STATUS_CODE_SUCCESSFUL) { -+ /* NOTE(Kevin): greedy association - after timeout, we'll still -+ * try to associate to the AP whose STATUS of conection attempt -+ * was not success. -+ * We may also use (ucJoinFailureCount x JOIN_RETRY_INTERVAL_SEC) for -+ * time bound. -+ */ -+ if ((prStaRec->ucJoinFailureCount < JOIN_MAX_RETRY_FAILURE_COUNT) || -+ (CHECK_FOR_TIMEOUT(rCurrentTime, -+ prStaRec->rLastJoinTime, -+ SEC_TO_SYSTIME(JOIN_RETRY_INTERVAL_SEC)))) { -+ -+ /* NOTE(Kevin): Every JOIN_RETRY_INTERVAL_SEC interval, we can retry -+ * JOIN_MAX_RETRY_FAILURE_COUNT times. -+ */ -+ if (prStaRec->ucJoinFailureCount >= JOIN_MAX_RETRY_FAILURE_COUNT) -+ prStaRec->ucJoinFailureCount = 0; -+ DBGLOG(SCN, INFO, -+ "SEARCH: Try to join BSS again,Status Code=%d (Curr=%u/Last Join=%u)\n", -+ prStaRec->u2StatusCode, rCurrentTime, prStaRec->rLastJoinTime); -+ } else { -+ DBGLOG(SCN, INFO, -+ "SEARCH: Ignore BSS which reach maximum Join Retry Count = %d\n", -+ JOIN_MAX_RETRY_FAILURE_COUNT); -+ continue; -+ } -+ -+ } -+ } -+ /* 4 <4> Check for various NETWORK conditions */ -+ if (eNetTypeIndex == NETWORK_TYPE_AIS_INDEX) { -+ -+ /* 4 <4.1> Check BSS Type for the corresponding Operation Mode in Connection Setting */ -+ /* NOTE(Kevin): For NET_TYPE_AUTO_SWITCH, we will always pass following check. */ -+ if (((prConnSettings->eOPMode == NET_TYPE_INFRA) && -+ (prBssDesc->eBSSType != BSS_TYPE_INFRASTRUCTURE)) -+#if CFG_SUPPORT_ADHOC -+ || ((prConnSettings->eOPMode == NET_TYPE_IBSS -+ || prConnSettings->eOPMode == NET_TYPE_DEDICATED_IBSS) -+ && (prBssDesc->eBSSType != BSS_TYPE_IBSS)) -+#endif -+ ) { -+ -+ DBGLOG(SCN, TRACE, "Cur OPMode %d, Ignore eBSSType = %d\n", -+ prConnSettings->eOPMode, prBssDesc->eBSSType); -+ continue; -+ } -+ /* 4 <4.2> Check AP's BSSID if OID_802_11_BSSID has been set. */ -+ if ((prConnSettings->fgIsConnByBssidIssued) && -+ (prBssDesc->eBSSType == BSS_TYPE_INFRASTRUCTURE)) { -+ -+ if (UNEQUAL_MAC_ADDR(prConnSettings->aucBSSID, prBssDesc->aucBSSID)) { -+ -+ DBGLOG(SCN, TRACE, "SEARCH: Ignore due to BSSID was not matched!\n"); -+ continue; -+ } -+ } -+#if CFG_SUPPORT_ADHOC -+ /* 4 <4.3> Check for AdHoc Mode */ -+ if (prBssDesc->eBSSType == BSS_TYPE_IBSS) { -+ OS_SYSTIME rCurrentTime; -+ -+ /* 4 <4.3.1> Check if this SCAN record has been updated recently for IBSS. */ -+ /* NOTE(Kevin): Because some STA may change its BSSID frequently after it -+ * create the IBSS - e.g. IPN2220, so we need to make sure we get the new one. -+ * For BSS, if the old record was matched, however it won't be able to pass -+ * the Join Process later. -+ */ -+ GET_CURRENT_SYSTIME(&rCurrentTime); -+ if (CHECK_FOR_TIMEOUT(rCurrentTime, prBssDesc->rUpdateTime, -+ SEC_TO_SYSTIME(SCN_ADHOC_BSS_DESC_TIMEOUT_SEC))) { -+ DBGLOG(SCN, LOUD, -+ "SEARCH: Skip old record of BSS Descriptor - BSSID:[%pM]\n\n", -+ prBssDesc->aucBSSID); -+ continue; -+ } -+ /* 4 <4.3.2> Check Peer's capability */ -+ if (ibssCheckCapabilityForAdHocMode(prAdapter, prBssDesc) == WLAN_STATUS_FAILURE) { -+ -+ if (prPrimaryBssDesc) -+ DBGLOG(SCN, INFO, -+ "SEARCH: BSS DESC MAC: %pM, not supported AdHoc Mode.\n", -+ prPrimaryBssDesc->aucBSSID); -+ -+ continue; -+ } -+ /* 4 <4.3.3> Compare TSF */ -+ if (prBssInfo->fgIsBeaconActivated && -+ UNEQUAL_MAC_ADDR(prBssInfo->aucBSSID, prBssDesc->aucBSSID)) { -+ -+ DBGLOG(SCN, LOUD, -+ "SEARCH: prBssDesc->fgIsLargerTSF = %d\n", prBssDesc->fgIsLargerTSF); -+ -+ if (!prBssDesc->fgIsLargerTSF) { -+ DBGLOG(SCN, INFO, -+ "SEARCH: Ignore BSS DESC MAC: [ %pM ], Smaller TSF\n", -+ prBssDesc->aucBSSID); -+ continue; -+ } -+ } -+ } -+#endif /* CFG_SUPPORT_ADHOC */ -+ -+ } -+#if 0 /* TODO(Kevin): For IBSS */ -+ /* 4 <2.c> Check if this SCAN record has been updated recently for IBSS. */ -+ /* NOTE(Kevin): Because some STA may change its BSSID frequently after it -+ * create the IBSS, so we need to make sure we get the new one. -+ * For BSS, if the old record was matched, however it won't be able to pass -+ * the Join Process later. -+ */ -+ if (prBssDesc->eBSSType == BSS_TYPE_IBSS) { -+ OS_SYSTIME rCurrentTime; -+ -+ GET_CURRENT_SYSTIME(&rCurrentTime); -+ if (CHECK_FOR_TIMEOUT(rCurrentTime, prBssDesc->rUpdateTime, -+ SEC_TO_SYSTIME(BSS_DESC_TIMEOUT_SEC))) { -+ DBGLOG(SCAN, TRACE, "Skip old record of BSS Descriptor - BSSID:[%pM]\n\n", -+ prBssDesc->aucBSSID); -+ continue; -+ } -+ } -+ -+ if ((prBssDesc->eBSSType == BSS_TYPE_INFRASTRUCTURE) && -+ (prAdapter->eConnectionState == MEDIA_STATE_CONNECTED)) { -+ OS_SYSTIME rCurrentTime; -+ -+ GET_CURRENT_SYSTIME(&rCurrentTime); -+ if (CHECK_FOR_TIMEOUT(rCurrentTime, prBssDesc->rUpdateTime, -+ SEC_TO_SYSTIME(BSS_DESC_TIMEOUT_SEC))) { -+ DBGLOG(SCAN, TRACE, "Skip old record of BSS Descriptor - BSSID:[%pM]\n\n", -+ (prBssDesc->aucBSSID)); -+ continue; -+ } -+ } -+ /* 4 <4B> Check for IBSS AdHoc Mode. */ -+ /* Skip if one or more BSS Basic Rate are not supported by current AdHocMode */ -+ if (prPrimaryBssDesc->eBSSType == BSS_TYPE_IBSS) { -+ /* 4 <4B.1> Check if match the Capability of current IBSS AdHoc Mode. */ -+ if (ibssCheckCapabilityForAdHocMode(prAdapter, prPrimaryBssDesc) == WLAN_STATUS_FAILURE) { -+ -+ DBGLOG(SCAN, TRACE, -+ "Ignore BSS DESC MAC: %pM, Capability not supported for AdHoc Mode.\n", -+ prPrimaryBssDesc->aucBSSID); -+ -+ continue; -+ } -+ /* 4 <4B.2> IBSS Merge Decision Flow for SEARCH STATE. */ -+ if (prAdapter->fgIsIBSSActive && -+ UNEQUAL_MAC_ADDR(prBssInfo->aucBSSID, prPrimaryBssDesc->aucBSSID)) { -+ -+ if (!fgIsLocalTSFRead) { -+ NIC_GET_CURRENT_TSF(prAdapter, &rCurrentTsf); -+ -+ DBGLOG(SCAN, TRACE, -+ "\n\nCurrent TSF : %08lx-%08lx\n\n", -+ rCurrentTsf.u.HighPart, rCurrentTsf.u.LowPart); -+ } -+ -+ if (rCurrentTsf.QuadPart > prPrimaryBssDesc->u8TimeStamp.QuadPart) { -+ DBGLOG(SCAN, TRACE, -+ "Ignore BSS DESC MAC: [%pM], Current BSSID: [%pM].\n", -+ prPrimaryBssDesc->aucBSSID, prBssInfo->aucBSSID); -+ -+ DBGLOG(SCAN, TRACE, -+ "\n\nBSS's TSF : %08lx-%08lx\n\n", -+ prPrimaryBssDesc->u8TimeStamp.u.HighPart, -+ prPrimaryBssDesc->u8TimeStamp.u.LowPart); -+ -+ prPrimaryBssDesc->fgIsLargerTSF = FALSE; -+ continue; -+ } else { -+ prPrimaryBssDesc->fgIsLargerTSF = TRUE; -+ } -+ -+ } -+ } -+ /* 4 <5> Check the Encryption Status. */ -+ if (rsnPerformPolicySelection(prPrimaryBssDesc)) { -+ -+ if (prPrimaryBssDesc->ucEncLevel > 0) { -+ fgIsFindBestEncryptionLevel = TRUE; -+ -+ fgIsFindFirst = FALSE; -+ } -+ } else { -+ /* Can't pass the Encryption Status Check, get next one */ -+ continue; -+ } -+ -+ /* For RSN Pre-authentication, update the PMKID canidate list for -+ same SSID and encrypt status */ -+ /* Update PMKID candicate list. */ -+ if (prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA2) { -+ rsnUpdatePmkidCandidateList(prPrimaryBssDesc); -+ if (prAdapter->rWifiVar.rAisBssInfo.u4PmkidCandicateCount) -+ prAdapter->rWifiVar.rAisBssInfo.fgIndicatePMKID = rsnCheckPmkidCandicate(); -+ } -+#endif -+ -+ prPrimaryBssDesc = (P_BSS_DESC_T) NULL; -+ -+ /* 4 <6> Check current Connection Policy. */ -+ switch (prConnSettings->eConnectionPolicy) { -+ case CONNECT_BY_SSID_BEST_RSSI: -+ /* Choose Hidden SSID to join only if the `fgIsEnableJoin...` is TRUE */ -+ if (prAdapter->rWifiVar.fgEnableJoinToHiddenSSID && prBssDesc->fgIsHiddenSSID) { -+ /* NOTE(Kevin): following if () statement means that -+ * If Target is hidden, then we won't connect when user specify SSID_ANY policy. -+ */ -+ if (prConnSettings->ucSSIDLen) { -+ prPrimaryBssDesc = prBssDesc; -+ fgIsFindBestRSSI = TRUE; -+ } -+ -+ } else if (EQUAL_SSID(prBssDesc->aucSSID, -+ prBssDesc->ucSSIDLen, -+ prConnSettings->aucSSID, prConnSettings->ucSSIDLen)) { -+ prPrimaryBssDesc = prBssDesc; -+ fgIsFindBestRSSI = TRUE; -+ -+ DBGLOG(SCN, TRACE, "SEARCH: fgIsFindBestRSSI=TRUE, %d, prPrimaryBssDesc=[ %pM ]\n", -+ prBssDesc->ucRCPI, prPrimaryBssDesc->aucBSSID); -+ } -+ break; -+ -+ case CONNECT_BY_SSID_ANY: -+ /* NOTE(Kevin): In this policy, we don't know the desired -+ * SSID from user, so we should exclude the Hidden SSID from scan list. -+ * And because we refuse to connect to Hidden SSID node at the beginning, so -+ * when the JOIN Module deal with a BSS_DESC_T which has fgIsHiddenSSID == TRUE, -+ * then the Connection Settings must be valid without doubt. -+ */ -+ if (!prBssDesc->fgIsHiddenSSID) { -+ prPrimaryBssDesc = prBssDesc; -+ fgIsFindFirst = TRUE; -+ } -+ break; -+ -+ case CONNECT_BY_BSSID: -+ if (EQUAL_MAC_ADDR(prBssDesc->aucBSSID, prConnSettings->aucBSSID)) -+ prPrimaryBssDesc = prBssDesc; -+ break; -+ -+ default: -+ break; -+ } -+ -+ /* Primary Candidate was not found */ -+ if (prPrimaryBssDesc == NULL) -+ continue; -+ /* 4 <7> Check the Encryption Status. */ -+ if (prPrimaryBssDesc->eBSSType == BSS_TYPE_INFRASTRUCTURE) { -+#if CFG_SUPPORT_WAPI -+ if (prAdapter->rWifiVar.rConnSettings.fgWapiMode) { -+ DBGLOG(SCN, TRACE, "SEARCH: fgWapiMode == 1\n"); -+ -+ if (wapiPerformPolicySelection(prAdapter, prPrimaryBssDesc)) { -+ fgIsFindFirst = TRUE; -+ } else { -+ /* Can't pass the Encryption Status Check, get next one */ -+ DBGLOG(SCN, TRACE, "SEARCH: WAPI cannot pass the Encryption Status Check!\n"); -+ continue; -+ } -+ } else -+#endif -+#if CFG_RSN_MIGRATION -+ if (rsnPerformPolicySelection(prAdapter, prPrimaryBssDesc)) { -+ if (prAisSpecBssInfo->fgCounterMeasure) { -+ DBGLOG(RSN, INFO, "Skip while at counter measure period!!!\n"); -+ continue; -+ } -+ -+ if (prPrimaryBssDesc->ucEncLevel > 0) { -+ fgIsFindBestEncryptionLevel = TRUE; -+ fgIsFindFirst = FALSE; -+ } -+#if 0 -+ /* Update PMKID candicate list. */ -+ if (prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA2) { -+ rsnUpdatePmkidCandidateList(prPrimaryBssDesc); -+ if (prAisSpecBssInfo->u4PmkidCandicateCount) { -+ if (rsnCheckPmkidCandicate()) { -+ DBGLOG(RSN, WARN, -+ "Prepare a timer to indicate candidate %pM\n", -+ (prAisSpecBssInfo->arPmkidCache -+ [prAisSpecBssInfo->u4PmkidCacheCount]. -+ rBssidInfo.aucBssid))); -+ cnmTimerStopTimer(&prAisSpecBssInfo->rPreauthenticationTimer); -+ cnmTimerStartTimer(&prAisSpecBssInfo->rPreauthenticationTimer, -+ SEC_TO_MSEC -+ (WAIT_TIME_IND_PMKID_CANDICATE_SEC)); -+ } -+ } -+ } -+#endif -+ } else { -+ /* Can't pass the Encryption Status Check, get next one */ -+ continue; -+ } -+#endif -+ } else { -+ /* Todo:: P2P and BOW Policy Selection */ -+ } -+ -+ prPrimaryStaRec = prStaRec; -+ -+ /* 4 <8> Compare the Candidate and the Primary Scan Record. */ -+ if (!prCandidateBssDesc) { -+ prCandidateBssDesc = prPrimaryBssDesc; -+ prCandidateStaRec = prPrimaryStaRec; -+ -+ /* 4 <8.1> Condition - Get the first matched one. */ -+ if (fgIsFindFirst) -+ break; -+ } else { -+#if 0 /* TODO(Kevin): For security(TBD) */ -+ /* 4 <6B> Condition - Choose the one with best Encryption Score. */ -+ if (fgIsFindBestEncryptionLevel) { -+ if (prCandidateBssDesc->ucEncLevel < prPrimaryBssDesc->ucEncLevel) { -+ -+ prCandidateBssDesc = prPrimaryBssDesc; -+ prCandidateStaRec = prPrimaryStaRec; -+ continue; -+ } -+ } -+ -+ /* If reach here, that means they have the same Encryption Score. -+ */ -+ -+ /* 4 <6C> Condition - Give opportunity to the one we didn't connect before. */ -+ /* For roaming, only compare the candidates other than current associated BSSID. */ -+ if (!prCandidateBssDesc->fgIsConnected && !prPrimaryBssDesc->fgIsConnected) { -+ if ((prCandidateStaRec != (P_STA_RECORD_T) NULL) && -+ (prCandidateStaRec->u2StatusCode != STATUS_CODE_SUCCESSFUL)) { -+ -+ DBGLOG(SCAN, TRACE, -+ "So far -BSS DESC MAC: %pM has nonzero Status Code = %d\n", -+ prCandidateBssDesc->aucBSSID, -+ prCandidateStaRec->u2StatusCode); -+ -+ if (prPrimaryStaRec != (P_STA_RECORD_T) NULL) { -+ if (prPrimaryStaRec->u2StatusCode != STATUS_CODE_SUCCESSFUL) { -+ -+ /* Give opportunity to the one with smaller rLastJoinTime */ -+ if (TIME_BEFORE(prCandidateStaRec->rLastJoinTime, -+ prPrimaryStaRec->rLastJoinTime)) { -+ continue; -+ } -+ /* We've connect to CANDIDATE recently, -+ * let us try PRIMARY now */ -+ else { -+ prCandidateBssDesc = prPrimaryBssDesc; -+ prCandidateStaRec = prPrimaryStaRec; -+ continue; -+ } -+ } -+ /* PRIMARY's u2StatusCode = 0 */ -+ else { -+ prCandidateBssDesc = prPrimaryBssDesc; -+ prCandidateStaRec = prPrimaryStaRec; -+ continue; -+ } -+ } -+ /* PRIMARY has no StaRec - We didn't connet to PRIMARY before */ -+ else { -+ prCandidateBssDesc = prPrimaryBssDesc; -+ prCandidateStaRec = prPrimaryStaRec; -+ continue; -+ } -+ } else { -+ if ((prPrimaryStaRec != (P_STA_RECORD_T) NULL) && -+ (prPrimaryStaRec->u2StatusCode != STATUS_CODE_SUCCESSFUL)) { -+ continue; -+ } -+ } -+ } -+#endif -+ -+ /* 4 <6D> Condition - Visible SSID win Hidden SSID. */ -+ if (prCandidateBssDesc->fgIsHiddenSSID) { -+ if (!prPrimaryBssDesc->fgIsHiddenSSID) { -+ prCandidateBssDesc = prPrimaryBssDesc; /* The non Hidden SSID win. */ -+ prCandidateStaRec = prPrimaryStaRec; -+ continue; -+ } -+ } else { -+ if (prPrimaryBssDesc->fgIsHiddenSSID) -+ continue; -+ } -+ -+ /* 4 <6E> Condition - Choose the one with better RCPI(RSSI). */ -+ if (fgIsFindBestRSSI) { -+ /* TODO(Kevin): We shouldn't compare the actual value, we should -+ * allow some acceptable tolerance of some RSSI percentage here. -+ */ -+ DBGLOG(SCN, TRACE, -+ "Candidate [%pM]: RCPI = %d, joinFailCnt=%d, Primary [%pM]: RCPI = %d, joinFailCnt=%d\n", -+ prCandidateBssDesc->aucBSSID, -+ prCandidateBssDesc->ucRCPI, prCandidateBssDesc->ucJoinFailureCount, -+ prPrimaryBssDesc->aucBSSID, -+ prPrimaryBssDesc->ucRCPI, prPrimaryBssDesc->ucJoinFailureCount); -+ -+ ASSERT(!(prCandidateBssDesc->fgIsConnected && prPrimaryBssDesc->fgIsConnected)); -+ if (prPrimaryBssDesc->ucJoinFailureCount >= SCN_BSS_JOIN_FAIL_THRESOLD) { -+ /* give a chance to do join if join fail before -+ * SCN_BSS_DECRASE_JOIN_FAIL_CNT_SEC seconds -+ */ -+ if (CHECK_FOR_TIMEOUT(rCurrentTime, prBssDesc->rJoinFailTime, -+ SEC_TO_SYSTIME(SCN_BSS_JOIN_FAIL_CNT_RESET_SEC))) { -+ prBssDesc->ucJoinFailureCount = SCN_BSS_JOIN_FAIL_THRESOLD - -+ SCN_BSS_JOIN_FAIL_RESET_STEP; -+ DBGLOG(SCN, INFO, -+ "decrease join fail count for Bss %pM to %u, timeout second %d\n", -+ prBssDesc->aucBSSID, prBssDesc->ucJoinFailureCount, -+ SCN_BSS_JOIN_FAIL_CNT_RESET_SEC); -+ } -+ } -+ -+ /* NOTE: To prevent SWING, -+ * we do roaming only if target AP has at least 5dBm larger than us. */ -+ if (prCandidateBssDesc->fgIsConnected) { -+ if (prCandidateBssDesc->ucRCPI + ROAMING_NO_SWING_RCPI_STEP <= -+ prPrimaryBssDesc->ucRCPI && -+ prPrimaryBssDesc->ucJoinFailureCount < SCN_BSS_JOIN_FAIL_THRESOLD) { -+ -+ prCandidateBssDesc = prPrimaryBssDesc; -+ prCandidateStaRec = prPrimaryStaRec; -+ continue; -+ } -+ } else if (prPrimaryBssDesc->fgIsConnected) { -+ if (prCandidateBssDesc->ucRCPI < -+ (prPrimaryBssDesc->ucRCPI + ROAMING_NO_SWING_RCPI_STEP) || -+ (prCandidateBssDesc->ucJoinFailureCount >= -+ SCN_BSS_JOIN_FAIL_THRESOLD)) { -+ prCandidateBssDesc = prPrimaryBssDesc; -+ prCandidateStaRec = prPrimaryStaRec; -+ continue; -+ } -+ } else if (prPrimaryBssDesc->ucJoinFailureCount >= SCN_BSS_JOIN_FAIL_THRESOLD) -+ continue; -+ else if (prCandidateBssDesc->ucJoinFailureCount >= SCN_BSS_JOIN_FAIL_THRESOLD || -+ prCandidateBssDesc->ucRCPI < prPrimaryBssDesc->ucRCPI) { -+ prCandidateBssDesc = prPrimaryBssDesc; -+ prCandidateStaRec = prPrimaryStaRec; -+ continue; -+ } -+ } -+#if 0 -+ /* If reach here, that means they have the same Encryption Score, and -+ * both RSSI value are close too. -+ */ -+ /* 4 <6F> Seek the minimum Channel Load for less interference. */ -+ if (fgIsFindMinChannelLoad) { -+ /* Do nothing */ -+ /* TODO(Kevin): Check which one has minimum channel load in its channel */ -+ } -+#endif -+ } -+ } -+ -+ -+ if (prCandidateBssDesc != NULL) { -+ DBGLOG(SCN, INFO, -+ "SEARCH: Candidate BSS: %pM\n", prCandidateBssDesc->aucBSSID); -+ } -+ -+ return prCandidateBssDesc; -+ -+} /* end of scanSearchBssDescByPolicy() */ -+ -+#if CFG_SUPPORT_AGPS_ASSIST -+VOID scanReportScanResultToAgps(P_ADAPTER_T prAdapter) -+{ -+ P_LINK_T prBSSDescList = &prAdapter->rWifiVar.rScanInfo.rBSSDescList; -+ P_BSS_DESC_T prBssDesc = NULL; -+ P_AGPS_AP_LIST_T prAgpsApList; -+ P_AGPS_AP_INFO_T prAgpsInfo; -+ P_SCAN_INFO_T prScanInfo = &prAdapter->rWifiVar.rScanInfo; -+ UINT_8 ucIndex = 0; -+ -+ prAgpsApList = kalMemAlloc(sizeof(AGPS_AP_LIST_T), VIR_MEM_TYPE); -+ if (!prAgpsApList) -+ return; -+ -+ prAgpsInfo = &prAgpsApList->arApInfo[0]; -+ LINK_FOR_EACH_ENTRY(prBssDesc, prBSSDescList, rLinkEntry, BSS_DESC_T) { -+ if (prBssDesc->rUpdateTime < prScanInfo->rLastScanCompletedTime) -+ continue; -+ COPY_MAC_ADDR(prAgpsInfo->aucBSSID, prBssDesc->aucBSSID); -+ prAgpsInfo->ePhyType = AGPS_PHY_G; -+ prAgpsInfo->u2Channel = prBssDesc->ucChannelNum; -+ prAgpsInfo->i2ApRssi = RCPI_TO_dBm(prBssDesc->ucRCPI); -+ prAgpsInfo++; -+ ucIndex++; -+ if (ucIndex == 32) -+ break; -+ } -+ prAgpsApList->ucNum = ucIndex; -+ GET_CURRENT_SYSTIME(&prScanInfo->rLastScanCompletedTime); -+ /* DBGLOG(SCN, INFO, ("num of scan list:%d\n", ucIndex)); */ -+ kalIndicateAgpsNotify(prAdapter, AGPS_EVENT_WLAN_AP_LIST, (PUINT_8) prAgpsApList, sizeof(AGPS_AP_LIST_T)); -+ kalMemFree(prAgpsApList, VIR_MEM_TYPE, sizeof(AGPS_AP_LIST_T)); -+} -+#endif -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/scan_fsm.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/scan_fsm.c -new file mode 100644 -index 000000000000..fac9f94428dd ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/scan_fsm.c -@@ -0,0 +1,2136 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/scan_fsm.c#1 -+*/ -+ -+/*! \file "scan_fsm.c" -+ \brief This file defines the state transition function for SCAN FSM. -+ -+ The SCAN FSM is part of SCAN MODULE and responsible for performing basic SCAN -+ behavior as metioned in IEEE 802.11 2007 11.1.3.1 & 11.1.3.2 . -+*/ -+ -+/* -+** Log: scan_fsm.c -+ * -+ * 06 13 2012 yuche.tsai -+ * NULL -+ * Update maintrunk driver. -+ * Add support for driver compose assoc request frame. -+ * -+ * 11 24 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * Adjust code for DBG and CONFIG_XLOG. -+ * -+ * 11 14 2011 yuche.tsai -+ * [WCXRP00001095] [Volunteer Patch][Driver] Always Scan before enable Hot-Spot. -+ * Fix bug when unregister P2P network.. -+ * -+ * 11 11 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * modify the xlog related code. -+ * -+ * 11 02 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * adding the code for XLOG. -+ * -+ * 08 11 2011 cp.wu -+ * [WCXRP00000830] [MT6620 Wi-Fi][Firmware] Use MDRDY counter to detect empty channel for shortening scan time -+ * sparse channel detection: -+ * driver: collect sparse channel information with scan-done event -+ * -+ * 07 18 2011 cp.wu -+ * [WCXRP00000858] [MT5931][Driver][Firmware] Add support for scan to search -+ * for more than one SSID in a single scanning request -+ * free mailbox message afte parsing is completed. -+ * -+ * 07 18 2011 cp.wu -+ * [WCXRP00000858] [MT5931][Driver][Firmware] Add support for scan to search -+ * for more than one SSID in a single scanning request -+ * add framework in driver domain for supporting new SCAN_REQ_V2 for more than 1 SSID support -+ * as well as uProbeDelay in NDIS 6.x driver model -+ * -+ * 04 18 2011 terry.wu -+ * [WCXRP00000660] [MT6620 Wi-Fi][Driver] Remove flag CFG_WIFI_DIRECT_MOVED -+ * Remove flag CFG_WIFI_DIRECT_MOVED. -+ * -+ * 03 29 2011 cp.wu -+ * [WCXRP00000604] [MT6620 Wi-Fi][Driver] Surpress Klockwork Warning -+ * surpress klock warning with code path rewritten -+ * -+ * 03 18 2011 cm.chang -+ * [WCXRP00000576] [MT6620 Wi-Fi][Driver][FW] Remove P2P compile option in scan req/cancel command -+ * As CR title -+ * -+ * 02 18 2011 yuche.tsai -+ * [WCXRP00000478] [Volunteer Patch][MT6620][Driver] Probe request frame -+ * during search phase do not contain P2P wildcard SSID. -+ * Take P2P wildcard SSID into consideration. -+ * -+ * 01 27 2011 yuche.tsai -+ * [WCXRP00000399] [Volunteer Patch][MT6620/MT5931][Driver] Fix scan side effect after P2P module separate. -+ * Fix scan channel extension issue when p2p module is not registered. -+ * -+ * 01 26 2011 yuche.tsai -+ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record. -+ * . -+ * -+ * 01 25 2011 yuche.tsai -+ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record. -+ * Fix Compile Error when DBG is disabled. -+ * -+ * 12 07 2010 cm.chang -+ * [WCXRP00000238] MT6620 Wi-Fi][Driver][FW] Support regulation domain setting from NVRAM and supplicant -+ * 1. Country code is from NVRAM or supplicant -+ * 2. Change band definition in CMD/EVENT. -+ * -+ * 09 03 2010 kevin.huang -+ * NULL -+ * Refine #include sequence and solve recursive/nested #include issue -+ * -+ * 08 30 2010 cp.wu -+ * NULL -+ * eliminate klockwork errors -+ * -+ * 08 16 2010 cp.wu -+ * NULL -+ * add interface for RLM to trigger OBSS-SCAN. -+ * -+ * 08 16 2010 yuche.tsai -+ * NULL -+ * Fix bug for processing queued scan request. -+ * -+ * 08 11 2010 yuche.tsai -+ * NULL -+ * Add a function for returning channel. -+ * -+ * 08 05 2010 yuche.tsai -+ * NULL -+ * Update SCAN FSM for support P2P Device discovery scan. -+ * -+ * 08 03 2010 cp.wu -+ * NULL -+ * surpress compilation warning. -+ * -+ * 07 26 2010 yuche.tsai -+ * -+ * Add option of channel extension while cancelling scan request. -+ * -+ * 07 21 2010 yuche.tsai -+ * -+ * Add P2P Scan & Scan Result Parsing & Saving. -+ * -+ * 07 20 2010 cp.wu -+ * -+ * pass band information for scan in an efficient way by mapping ENUM_BAND_T into UINT_8.. -+ * -+ * 07 19 2010 cp.wu -+ * -+ * due to FW/DRV won't be sync. precisely, some strict assertions should be eased. -+ * -+ * 07 19 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration. -+ * SCN module is now able to handle multiple concurrent scanning requests -+ * -+ * 07 16 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration. -+ * bugfix for SCN migration -+ * 1) modify QUEUE_CONCATENATE_QUEUES() so it could be used to concatence with an empty queue -+ * 2) before AIS issues scan request, network(BSS) needs to be activated first -+ * 3) only invoke COPY_SSID when using specified SSID for scan -+ * -+ * 07 15 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration. -+ * driver no longer generates probe request frames -+ * -+ * 07 14 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration. -+ * pass band with channel number information as scan parameter -+ * -+ * 07 14 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration. -+ * remove timer in DRV-SCN. -+ * -+ * 07 09 2010 cp.wu -+ * -+ * 1) separate AIS_FSM state for two kinds of scanning. (OID triggered scan, and scan-for-connection) -+ * 2) eliminate PRE_BSS_DESC_T, Beacon/PrebResp is now parsed in single pass -+ * 3) implment DRV-SCN module, currently only accepts single scan request, -+ * other request will be directly dropped by returning BUSY -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 07 08 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * take use of RLM module for parsing/generating HT IEs for 11n capability -+ * -+ * 07 02 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * when returning to SCAN_IDLE state, send a correct message to source FSM. -+ * -+ * 07 01 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * implementation of DRV-SCN and related mailbox message handling. -+ * -+ * 06 22 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * comment out RLM APIs by CFG_RLM_MIGRATION. -+ * -+ * 06 21 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add scan_fsm into building. -+ * -+ * 05 14 2010 kevin.huang -+ * [BORA00000794][WIFISYS][New Feature]Power Management Support -+ * Refine the order of Stop TX Queue and Switch Channel -+ * -+ * 05 12 2010 kevin.huang -+ * [BORA00000794][WIFISYS][New Feature]Power Management Support -+ * Update pause/resume/flush API to new Bitmap API -+ * -+ * 05 12 2010 kevin.huang -+ * [BORA00000794][WIFISYS][New Feature]Power Management Support -+ * Add Power Management - Legacy PS-POLL support. -+ * -+ * 03 18 2010 kevin.huang -+ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support -+ * Ignore the PROBE_DELAY state if the value of Probe Delay == 0 -+ * -+ * 03 10 2010 kevin.huang -+ * [BORA00000654][WIFISYS][New Feature] CNM Module - Ch Manager Support -+ * Add Channel Manager for arbitration of JOIN and SCAN Req -+ * -+ * 02 23 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Add support scan channel 1~14 and update scan result's frequency infou1rwduu`wvpghlqg|n`slk+mpdkb -+ * -+ * 01 08 2010 kevin.huang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Add set RX Filter to receive BCN from different BSSID during SCAN -+ * -+ * 12 18 2009 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * . -+ * -+ * Nov 25 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Remove flag of CFG_TEST_MGMT_FSM -+ * -+ * Nov 20 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Change parameter of scanSendProbeReqFrames() -+ * -+ * Nov 16 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Update scnFsmSteps() -+ * -+ * Nov 5 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Fix typo -+ * -+ * Nov 5 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "precomp.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+#if DBG -+/*lint -save -e64 Type mismatch */ -+static PUINT_8 apucDebugScanState[SCAN_STATE_NUM] = { -+ (PUINT_8) DISP_STRING("SCAN_STATE_IDLE"), -+ (PUINT_8) DISP_STRING("SCAN_STATE_SCANNING"), -+}; -+ -+/*lint -restore */ -+#endif /* DBG */ -+ -+#define CURRENT_PSCN_VERSION 1 -+#define RSSI_MARGIN_DEFAULT 5 -+#define MAX_PERIOD 200000 -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID scnFsmSteps(IN P_ADAPTER_T prAdapter, IN ENUM_SCAN_STATE_T eNextState) -+{ -+ P_SCAN_INFO_T prScanInfo; -+ P_SCAN_PARAM_T prScanParam; -+ P_MSG_HDR_T prMsgHdr; -+ -+ BOOLEAN fgIsTransition = (BOOLEAN) FALSE; -+ -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ prScanParam = &prScanInfo->rScanParam; -+ -+ do { -+ -+#if DBG -+ DBGLOG(SCN, STATE, "TRANSITION: [%s] -> [%s]\n", -+ apucDebugScanState[prScanInfo->eCurrentState], apucDebugScanState[eNextState]); -+#else -+ DBGLOG(SCN, STATE, "[%d] TRANSITION: [%d] -> [%d]\n", -+ DBG_SCN_IDX, prScanInfo->eCurrentState, eNextState); -+#endif -+ -+ /* NOTE(Kevin): This is the only place to change the eCurrentState(except initial) */ -+ prScanInfo->eCurrentState = eNextState; -+ -+ fgIsTransition = (BOOLEAN) FALSE; -+ -+ switch (prScanInfo->eCurrentState) { -+ case SCAN_STATE_IDLE: -+ /* check for pending scanning requests */ -+ if (!LINK_IS_EMPTY(&(prScanInfo->rPendingMsgList))) { -+ /* load next message from pending list as scan parameters */ -+ LINK_REMOVE_HEAD(&(prScanInfo->rPendingMsgList), prMsgHdr, P_MSG_HDR_T); -+ -+ if (prMsgHdr->eMsgId == MID_AIS_SCN_SCAN_REQ -+ || prMsgHdr->eMsgId == MID_BOW_SCN_SCAN_REQ -+ || prMsgHdr->eMsgId == MID_P2P_SCN_SCAN_REQ -+ || prMsgHdr->eMsgId == MID_RLM_SCN_SCAN_REQ) { -+ scnFsmHandleScanMsg(prAdapter, (P_MSG_SCN_SCAN_REQ) prMsgHdr); -+ } else { -+ scnFsmHandleScanMsgV2(prAdapter, (P_MSG_SCN_SCAN_REQ_V2) prMsgHdr); -+ } -+ -+ /* switch to next state */ -+ eNextState = SCAN_STATE_SCANNING; -+ fgIsTransition = TRUE; -+ -+ cnmMemFree(prAdapter, prMsgHdr); -+ } -+ break; -+ -+ case SCAN_STATE_SCANNING: -+ if (prScanParam->fgIsScanV2 == FALSE) -+ scnSendScanReq(prAdapter); -+ else -+ scnSendScanReqV2(prAdapter); -+ break; -+ -+ default: -+ ASSERT(0); -+ break; -+ -+ } -+ } while (fgIsTransition); -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Generate CMD_ID_SCAN_REQ command -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID scnSendScanReqExtCh(IN P_ADAPTER_T prAdapter) -+{ -+ P_SCAN_INFO_T prScanInfo; -+ P_SCAN_PARAM_T prScanParam; -+ /*CMD_SCAN_REQ_EXT_CH rCmdScanReq;*/ -+ P_CMD_SCAN_REQ_EXT_CH prCmdScanReq; -+ UINT_32 i; -+ -+ ASSERT(prAdapter); -+ -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ prScanParam = &prScanInfo->rScanParam; -+ -+ prCmdScanReq = kalMemAlloc(sizeof(CMD_SCAN_REQ_EXT_CH), VIR_MEM_TYPE); -+ if (prCmdScanReq == NULL) -+ return; -+ -+ /* send command packet for scan */ -+ kalMemZero(prCmdScanReq, sizeof(CMD_SCAN_REQ_EXT_CH)); -+ -+ prCmdScanReq->ucSeqNum = prScanParam->ucSeqNum; -+ prCmdScanReq->ucNetworkType = (UINT_8) prScanParam->eNetTypeIndex; -+ prCmdScanReq->ucScanType = (UINT_8) prScanParam->eScanType; -+ prCmdScanReq->ucSSIDType = prScanParam->ucSSIDType; -+ -+ if (prScanParam->ucSSIDNum == 1) { -+ COPY_SSID(prCmdScanReq->aucSSID, -+ prCmdScanReq->ucSSIDLength, -+ prScanParam->aucSpecifiedSSID[0], prScanParam->ucSpecifiedSSIDLen[0]); -+ } -+ -+ prCmdScanReq->ucChannelType = (UINT_8) prScanParam->eScanChannel; -+ -+ if (prScanParam->eScanChannel == SCAN_CHANNEL_SPECIFIED) { -+ /* P2P would use: -+ * 1. Specified Listen Channel of passive scan for LISTEN state. -+ * 2. Specified Listen Channel of Target Device of active scan for SEARCH state. (Target != NULL) -+ */ -+ prCmdScanReq->ucChannelListNum = prScanParam->ucChannelListNum; -+ -+ for (i = 0; i < prCmdScanReq->ucChannelListNum; i++) { -+ prCmdScanReq->arChannelList[i].ucBand = (UINT_8) prScanParam->arChnlInfoList[i].eBand; -+ -+ prCmdScanReq->arChannelList[i].ucChannelNum = -+ (UINT_8) prScanParam->arChnlInfoList[i].ucChannelNum; -+ } -+ } -+#if CFG_ENABLE_WIFI_DIRECT -+ if (prScanParam->eNetTypeIndex == NETWORK_TYPE_P2P_INDEX) -+ prCmdScanReq->u2ChannelDwellTime = prScanParam->u2PassiveListenInterval; -+#endif -+ -+ if (prScanParam->u2IELen <= MAX_IE_LENGTH) -+ prCmdScanReq->u2IELen = prScanParam->u2IELen; -+ else -+ prCmdScanReq->u2IELen = MAX_IE_LENGTH; -+ -+ if (prScanParam->u2IELen) -+ kalMemCopy(prCmdScanReq->aucIE, prScanParam->aucIE, sizeof(UINT_8) * prCmdScanReq->u2IELen); -+ -+ wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SCAN_REQ, -+ TRUE, -+ FALSE, -+ FALSE, -+ NULL, -+ NULL, -+ OFFSET_OF(CMD_SCAN_REQ_EXT_CH, aucIE) + prCmdScanReq->u2IELen, -+ (PUINT_8) prCmdScanReq, NULL, 0); -+ /* sanity check for some scan parameters */ -+ if (prCmdScanReq->ucScanType >= SCAN_TYPE_NUM) -+ kalSendAeeWarning("wlan", "wrong scan type %d", prCmdScanReq->ucScanType); -+ else if (prCmdScanReq->ucChannelType >= SCAN_CHANNEL_NUM) -+ kalSendAeeWarning("wlan", "wrong channel type %d", prCmdScanReq->ucChannelType); -+ else if (prCmdScanReq->ucChannelType != SCAN_CHANNEL_SPECIFIED && -+ prCmdScanReq->ucChannelListNum != 0) -+ kalSendAeeWarning("wlan", -+ "channel list is not NULL but channel type is not specified"); -+ else if (prCmdScanReq->ucNetworkType >= NETWORK_TYPE_INDEX_NUM) -+ kalSendAeeWarning("wlan", "wrong network type %d", prCmdScanReq->ucNetworkType); -+ else if (prCmdScanReq->ucSSIDType >= BIT(4)) /* ssid type is wrong */ -+ kalSendAeeWarning("wlan", "wrong ssid type %d", prCmdScanReq->ucSSIDType); -+ else if (prCmdScanReq->ucSSIDLength > 32) -+ kalSendAeeWarning("wlan", "wrong ssid length %d", prCmdScanReq->ucSSIDLength); -+ -+ kalMemFree(prCmdScanReq, VIR_MEM_TYPE, sizeof(CMD_SCAN_REQ_EXT_CH)); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Generate CMD_ID_SCAN_REQ command -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID scnSendScanReq(IN P_ADAPTER_T prAdapter) -+{ -+ P_SCAN_INFO_T prScanInfo; -+ P_SCAN_PARAM_T prScanParam; -+ /*CMD_SCAN_REQ rCmdScanReq;*/ -+ P_CMD_SCAN_REQ prCmdScanReq; -+ UINT_32 i; -+ -+ ASSERT(prAdapter); -+ -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ prScanParam = &prScanInfo->rScanParam; -+ -+ if (prScanParam->ucChannelListNum > 32) { -+ scnSendScanReqExtCh(prAdapter); -+ } else { -+ prCmdScanReq = kalMemAlloc(sizeof(CMD_SCAN_REQ), VIR_MEM_TYPE); -+ if (prCmdScanReq == NULL) { -+ DBGLOG(SCN, INFO, "alloc CmdScanReq fail"); -+ return; -+ } -+ /* send command packet for scan */ -+ kalMemZero(prCmdScanReq, sizeof(CMD_SCAN_REQ)); -+ -+ prCmdScanReq->ucSeqNum = prScanParam->ucSeqNum; -+ prCmdScanReq->ucNetworkType = (UINT_8) prScanParam->eNetTypeIndex; -+ prCmdScanReq->ucScanType = (UINT_8) prScanParam->eScanType; -+ prCmdScanReq->ucSSIDType = prScanParam->ucSSIDType; -+ -+ if (prScanParam->ucSSIDNum == 1) { -+ COPY_SSID(prCmdScanReq->aucSSID, -+ prCmdScanReq->ucSSIDLength, -+ prScanParam->aucSpecifiedSSID[0], prScanParam->ucSpecifiedSSIDLen[0]); -+ } -+ -+ prCmdScanReq->ucChannelType = (UINT_8) prScanParam->eScanChannel; -+ -+ if (prScanParam->eScanChannel == SCAN_CHANNEL_SPECIFIED) { -+ /* P2P would use: -+ * 1. Specified Listen Channel of passive scan for LISTEN state. -+ * 2. Specified Listen Channel of Target Device of active scan for SEARCH state. -+ * (Target != NULL) -+ */ -+ prCmdScanReq->ucChannelListNum = prScanParam->ucChannelListNum; -+ -+ for (i = 0; i < prCmdScanReq->ucChannelListNum; i++) { -+ prCmdScanReq->arChannelList[i].ucBand = (UINT_8) prScanParam->arChnlInfoList[i].eBand; -+ -+ prCmdScanReq->arChannelList[i].ucChannelNum = -+ (UINT_8) prScanParam->arChnlInfoList[i].ucChannelNum; -+ } -+ } -+#if CFG_ENABLE_WIFI_DIRECT -+ if (prScanParam->eNetTypeIndex == NETWORK_TYPE_P2P_INDEX) -+ prCmdScanReq->u2ChannelDwellTime = prScanParam->u2PassiveListenInterval; -+#endif -+#if CFG_ENABLE_FAST_SCAN -+ if (prScanParam->eNetTypeIndex == NETWORK_TYPE_AIS_INDEX) -+ prCmdScanReq->u2ChannelDwellTime = CFG_FAST_SCAN_DWELL_TIME; -+#endif -+ if (prScanParam->u2IELen <= MAX_IE_LENGTH) -+ prCmdScanReq->u2IELen = prScanParam->u2IELen; -+ else -+ prCmdScanReq->u2IELen = MAX_IE_LENGTH; -+ -+ if (prScanParam->u2IELen) -+ kalMemCopy(prCmdScanReq->aucIE, prScanParam->aucIE, sizeof(UINT_8) * prCmdScanReq->u2IELen); -+ -+ wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SCAN_REQ, -+ TRUE, -+ FALSE, -+ FALSE, -+ NULL, -+ NULL, -+ OFFSET_OF(CMD_SCAN_REQ, aucIE) + prCmdScanReq->u2IELen, -+ (PUINT_8) prCmdScanReq, NULL, 0); -+ /* sanity check for some scan parameters */ -+ if (prCmdScanReq->ucScanType >= SCAN_TYPE_NUM) -+ kalSendAeeWarning("wlan", "wrong scan type %d", prCmdScanReq->ucScanType); -+ else if (prCmdScanReq->ucChannelType >= SCAN_CHANNEL_NUM) -+ kalSendAeeWarning("wlan", "wrong channel type %d", prCmdScanReq->ucChannelType); -+ else if (prCmdScanReq->ucChannelType != SCAN_CHANNEL_SPECIFIED && -+ prCmdScanReq->ucChannelListNum != 0) -+ kalSendAeeWarning("wlan", -+ "channel list is not NULL but channel type is not specified"); -+ else if (prCmdScanReq->ucNetworkType >= NETWORK_TYPE_INDEX_NUM) -+ kalSendAeeWarning("wlan", "wrong network type %d", prCmdScanReq->ucNetworkType); -+ else if (prCmdScanReq->ucSSIDType >= BIT(4)) /* ssid type is wrong */ -+ kalSendAeeWarning("wlan", "wrong ssid type %d", prCmdScanReq->ucSSIDType); -+ else if (prCmdScanReq->ucSSIDLength > 32) -+ kalSendAeeWarning("wlan", "wrong ssid length %d", prCmdScanReq->ucSSIDLength); -+ -+ kalMemFree(prCmdScanReq, VIR_MEM_TYPE, sizeof(CMD_SCAN_REQ)); -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Generate CMD_ID_SCAN_REQ_V2 command -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID scnSendScanReqV2ExtCh(IN P_ADAPTER_T prAdapter) -+{ -+ P_SCAN_INFO_T prScanInfo; -+ P_SCAN_PARAM_T prScanParam; -+ /*CMD_SCAN_REQ_V2_EXT_CH rCmdScanReq;*/ -+ P_CMD_SCAN_REQ_V2_EXT_CH prCmdScanReq; -+ UINT_32 i; -+ -+ ASSERT(prAdapter); -+ -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ prScanParam = &prScanInfo->rScanParam; -+ -+ prCmdScanReq = kalMemAlloc(sizeof(CMD_SCAN_REQ_V2_EXT_CH), VIR_MEM_TYPE); -+ if (prCmdScanReq == NULL) -+ return; -+ -+ /* send command packet for scan */ -+ kalMemZero(prCmdScanReq, sizeof(CMD_SCAN_REQ_V2_EXT_CH)); -+ -+ prCmdScanReq->ucSeqNum = prScanParam->ucSeqNum; -+ prCmdScanReq->ucNetworkType = (UINT_8) prScanParam->eNetTypeIndex; -+ prCmdScanReq->ucScanType = (UINT_8) prScanParam->eScanType; -+ prCmdScanReq->ucSSIDType = prScanParam->ucSSIDType; -+ -+ for (i = 0; i < prScanParam->ucSSIDNum; i++) { -+ COPY_SSID(prCmdScanReq->arSSID[i].aucSsid, -+ prCmdScanReq->arSSID[i].u4SsidLen, -+ prScanParam->aucSpecifiedSSID[i], prScanParam->ucSpecifiedSSIDLen[i]); -+ } -+ -+ prCmdScanReq->u2ProbeDelayTime = (UINT_8) prScanParam->u2ProbeDelayTime; -+ prCmdScanReq->ucChannelType = (UINT_8) prScanParam->eScanChannel; -+ -+ if (prScanParam->eScanChannel == SCAN_CHANNEL_SPECIFIED) { -+ /* P2P would use: -+ * 1. Specified Listen Channel of passive scan for LISTEN state. -+ * 2. Specified Listen Channel of Target Device of active scan for SEARCH state. (Target != NULL) -+ */ -+ prCmdScanReq->ucChannelListNum = prScanParam->ucChannelListNum; -+ -+ for (i = 0; i < prCmdScanReq->ucChannelListNum; i++) { -+ prCmdScanReq->arChannelList[i].ucBand = (UINT_8) prScanParam->arChnlInfoList[i].eBand; -+ -+ prCmdScanReq->arChannelList[i].ucChannelNum = -+ (UINT_8) prScanParam->arChnlInfoList[i].ucChannelNum; -+ } -+ } -+#if CFG_ENABLE_WIFI_DIRECT -+ if (prScanParam->eNetTypeIndex == NETWORK_TYPE_P2P_INDEX) -+ prCmdScanReq->u2ChannelDwellTime = prScanParam->u2PassiveListenInterval; -+#endif -+ -+ if (prScanParam->u2IELen <= MAX_IE_LENGTH) -+ prCmdScanReq->u2IELen = prScanParam->u2IELen; -+ else -+ prCmdScanReq->u2IELen = MAX_IE_LENGTH; -+ -+ if (prScanParam->u2IELen) -+ kalMemCopy(prCmdScanReq->aucIE, prScanParam->aucIE, sizeof(UINT_8) * prCmdScanReq->u2IELen); -+ -+ wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SCAN_REQ_V2, -+ TRUE, -+ FALSE, -+ FALSE, -+ NULL, -+ NULL, -+ OFFSET_OF(CMD_SCAN_REQ_V2_EXT_CH, aucIE) + prCmdScanReq->u2IELen, -+ (PUINT_8) prCmdScanReq, NULL, 0); -+ /* sanity check for some scan parameters */ -+ if (prCmdScanReq->ucScanType >= SCAN_TYPE_NUM) -+ kalSendAeeWarning("wlan", "wrong scan type %d", prCmdScanReq->ucScanType); -+ else if (prCmdScanReq->ucChannelType >= SCAN_CHANNEL_NUM) -+ kalSendAeeWarning("wlan", "wrong channel type %d", prCmdScanReq->ucChannelType); -+ else if (prCmdScanReq->ucChannelType != SCAN_CHANNEL_SPECIFIED && -+ prCmdScanReq->ucChannelListNum != 0) -+ kalSendAeeWarning("wlan", -+ "channel list is not NULL but channel type is not specified"); -+ else if (prCmdScanReq->ucNetworkType >= NETWORK_TYPE_INDEX_NUM) -+ kalSendAeeWarning("wlan", "wrong network type %d", prCmdScanReq->ucNetworkType); -+ else if (prCmdScanReq->ucSSIDType >= BIT(4)) /* ssid type is wrong */ -+ kalSendAeeWarning("wlan", "wrong ssid type %d", prCmdScanReq->ucSSIDType); -+ -+ kalMemFree(prCmdScanReq, VIR_MEM_TYPE, sizeof(CMD_SCAN_REQ_V2_EXT_CH)); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Generate CMD_ID_SCAN_REQ_V2 command -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID scnSendScanReqV2(IN P_ADAPTER_T prAdapter) -+{ -+ P_SCAN_INFO_T prScanInfo; -+ P_SCAN_PARAM_T prScanParam; -+ /*CMD_SCAN_REQ_V2 rCmdScanReq;*/ -+ P_CMD_SCAN_REQ_V2 prCmdScanReq; -+ UINT_32 i; -+ -+ ASSERT(prAdapter); -+ -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ prScanParam = &prScanInfo->rScanParam; -+ -+ if (prScanParam->ucChannelListNum > 32) { -+ scnSendScanReqV2ExtCh(prAdapter); -+ } else { -+ prCmdScanReq = kalMemAlloc(sizeof(CMD_SCAN_REQ_V2), VIR_MEM_TYPE); -+ if (prCmdScanReq == NULL) { -+ DBGLOG(SCN, INFO, "alloc CmdScanReq v2 fail"); -+ return; -+ } -+ /* send command packet for scan */ -+ kalMemZero(prCmdScanReq, sizeof(CMD_SCAN_REQ_V2)); -+ -+ prCmdScanReq->ucSeqNum = prScanParam->ucSeqNum; -+ prCmdScanReq->ucNetworkType = (UINT_8) prScanParam->eNetTypeIndex; -+ prCmdScanReq->ucScanType = (UINT_8) prScanParam->eScanType; -+ prCmdScanReq->ucSSIDType = prScanParam->ucSSIDType; -+ -+ for (i = 0; i < prScanParam->ucSSIDNum; i++) { -+ COPY_SSID(prCmdScanReq->arSSID[i].aucSsid, -+ prCmdScanReq->arSSID[i].u4SsidLen, -+ prScanParam->aucSpecifiedSSID[i], prScanParam->ucSpecifiedSSIDLen[i]); -+ } -+ -+ prCmdScanReq->u2ProbeDelayTime = (UINT_8) prScanParam->u2ProbeDelayTime; -+ prCmdScanReq->ucChannelType = (UINT_8) prScanParam->eScanChannel; -+ -+ if (prScanParam->eScanChannel == SCAN_CHANNEL_SPECIFIED) { -+ /* P2P would use: -+ * 1. Specified Listen Channel of passive scan for LISTEN state. -+ * 2. Specified Listen Channel of Target Device of active scan for SEARCH state. -+ * (Target != NULL) -+ */ -+ prCmdScanReq->ucChannelListNum = prScanParam->ucChannelListNum; -+ -+ for (i = 0; i < prCmdScanReq->ucChannelListNum; i++) { -+ prCmdScanReq->arChannelList[i].ucBand = (UINT_8) prScanParam->arChnlInfoList[i].eBand; -+ -+ prCmdScanReq->arChannelList[i].ucChannelNum = -+ (UINT_8) prScanParam->arChnlInfoList[i].ucChannelNum; -+ } -+ } -+#if CFG_ENABLE_WIFI_DIRECT -+ if (prScanParam->eNetTypeIndex == NETWORK_TYPE_P2P_INDEX) -+ prCmdScanReq->u2ChannelDwellTime = prScanParam->u2PassiveListenInterval; -+#endif -+ if (prScanParam->u2IELen <= MAX_IE_LENGTH) -+ prCmdScanReq->u2IELen = prScanParam->u2IELen; -+ else -+ prCmdScanReq->u2IELen = MAX_IE_LENGTH; -+ -+ if (prScanParam->u2IELen) -+ kalMemCopy(prCmdScanReq->aucIE, prScanParam->aucIE, sizeof(UINT_8) * prCmdScanReq->u2IELen); -+ -+ wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SCAN_REQ_V2, -+ TRUE, -+ FALSE, -+ FALSE, -+ NULL, -+ NULL, -+ OFFSET_OF(CMD_SCAN_REQ_V2, aucIE) + prCmdScanReq->u2IELen, -+ (PUINT_8) prCmdScanReq, NULL, 0); -+ /* sanity check for some scan parameters */ -+ if (prCmdScanReq->ucScanType >= SCAN_TYPE_NUM) -+ kalSendAeeWarning("wlan", "wrong scan type %d", prCmdScanReq->ucScanType); -+ else if (prCmdScanReq->ucChannelType >= SCAN_CHANNEL_NUM) -+ kalSendAeeWarning("wlan", "wrong channel type %d", prCmdScanReq->ucChannelType); -+ else if (prCmdScanReq->ucChannelType != SCAN_CHANNEL_SPECIFIED && -+ prCmdScanReq->ucChannelListNum != 0) -+ kalSendAeeWarning("wlan", -+ "channel list is not NULL but channel type is not specified"); -+ else if (prCmdScanReq->ucNetworkType >= NETWORK_TYPE_INDEX_NUM) -+ kalSendAeeWarning("wlan", "wrong network type %d", prCmdScanReq->ucNetworkType); -+ else if (prCmdScanReq->ucSSIDType >= BIT(4)) /* ssid type is wrong */ -+ kalSendAeeWarning("wlan", "wrong ssid type %d", prCmdScanReq->ucSSIDType); -+ -+ kalMemFree(prCmdScanReq, VIR_MEM_TYPE, sizeof(CMD_SCAN_REQ_V2)); -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID scnFsmMsgStart(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) -+{ -+ P_SCAN_INFO_T prScanInfo; -+ P_SCAN_PARAM_T prScanParam; -+ -+ ASSERT(prMsgHdr); -+ -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ prScanParam = &prScanInfo->rScanParam; -+ -+ if (prScanInfo->eCurrentState == SCAN_STATE_IDLE) { -+ if (prMsgHdr->eMsgId == MID_AIS_SCN_SCAN_REQ -+ || prMsgHdr->eMsgId == MID_BOW_SCN_SCAN_REQ -+ || prMsgHdr->eMsgId == MID_P2P_SCN_SCAN_REQ || prMsgHdr->eMsgId == MID_RLM_SCN_SCAN_REQ) { -+ scnFsmHandleScanMsg(prAdapter, (P_MSG_SCN_SCAN_REQ) prMsgHdr); -+ } else if (prMsgHdr->eMsgId == MID_AIS_SCN_SCAN_REQ_V2 -+ || prMsgHdr->eMsgId == MID_BOW_SCN_SCAN_REQ_V2 -+ || prMsgHdr->eMsgId == MID_P2P_SCN_SCAN_REQ_V2 -+ || prMsgHdr->eMsgId == MID_RLM_SCN_SCAN_REQ_V2) { -+ scnFsmHandleScanMsgV2(prAdapter, (P_MSG_SCN_SCAN_REQ_V2) prMsgHdr); -+ } else { -+ /* should not deliver to this function */ -+ ASSERT(0); -+ } -+ -+ cnmMemFree(prAdapter, prMsgHdr); -+ scnFsmSteps(prAdapter, SCAN_STATE_SCANNING); -+ } else { -+ LINK_INSERT_TAIL(&prScanInfo->rPendingMsgList, &prMsgHdr->rLinkEntry); -+ } -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID scnFsmMsgAbort(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) -+{ -+ P_MSG_SCN_SCAN_CANCEL prScanCancel; -+ P_SCAN_INFO_T prScanInfo; -+ P_SCAN_PARAM_T prScanParam; -+ CMD_SCAN_CANCEL rCmdScanCancel; -+ -+ ASSERT(prMsgHdr); -+ -+ prScanCancel = (P_MSG_SCN_SCAN_CANCEL) prMsgHdr; -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ prScanParam = &prScanInfo->rScanParam; -+ -+ if (prScanInfo->eCurrentState != SCAN_STATE_IDLE) { -+ if (prScanCancel->ucSeqNum == prScanParam->ucSeqNum && -+ prScanCancel->ucNetTypeIndex == (UINT_8) prScanParam->eNetTypeIndex) { -+ /* send cancel message to firmware domain */ -+ rCmdScanCancel.ucSeqNum = prScanParam->ucSeqNum; -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ if (prScanParam->eNetTypeIndex == NETWORK_TYPE_P2P_INDEX) -+ rCmdScanCancel.ucIsExtChannel = (UINT_8) prScanCancel->fgIsChannelExt; -+ else -+ rCmdScanCancel.ucIsExtChannel = (UINT_8) FALSE; -+#endif -+ -+ wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SCAN_CANCEL, -+ TRUE, -+ FALSE, -+ FALSE, -+ NULL, NULL, sizeof(CMD_SCAN_CANCEL), (PUINT_8) &rCmdScanCancel, NULL, 0); -+ -+ /* generate scan-done event for caller */ -+ scnFsmGenerateScanDoneMsg(prAdapter, -+ prScanParam->ucSeqNum, -+ (UINT_8) prScanParam->eNetTypeIndex, SCAN_STATUS_CANCELLED); -+ -+ /* switch to next pending scan */ -+ scnFsmSteps(prAdapter, SCAN_STATE_IDLE); -+ } else { -+ scnFsmRemovePendingMsg(prAdapter, prScanCancel->ucSeqNum, prScanCancel->ucNetTypeIndex); -+ } -+ } -+ -+ cnmMemFree(prAdapter, prMsgHdr); -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Scan Message Parsing (Legacy) -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID scnFsmHandleScanMsg(IN P_ADAPTER_T prAdapter, IN P_MSG_SCN_SCAN_REQ prScanReqMsg) -+{ -+ P_SCAN_INFO_T prScanInfo; -+ P_SCAN_PARAM_T prScanParam; -+ UINT_32 i; -+ -+ ASSERT(prAdapter); -+ ASSERT(prScanReqMsg); -+ -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ prScanParam = &prScanInfo->rScanParam; -+ -+ prScanParam->eScanType = prScanReqMsg->eScanType; -+ prScanParam->eNetTypeIndex = (ENUM_NETWORK_TYPE_INDEX_T) prScanReqMsg->ucNetTypeIndex; -+ prScanParam->ucSSIDType = prScanReqMsg->ucSSIDType; -+ if (prScanParam->ucSSIDType & (SCAN_REQ_SSID_SPECIFIED | SCAN_REQ_SSID_P2P_WILDCARD)) { -+ prScanParam->ucSSIDNum = 1; -+ -+ COPY_SSID(prScanParam->aucSpecifiedSSID[0], -+ prScanParam->ucSpecifiedSSIDLen[0], prScanReqMsg->aucSSID, prScanReqMsg->ucSSIDLength); -+ -+ /* reset SSID length to zero for rest array entries */ -+ for (i = 1; i < SCN_SSID_MAX_NUM; i++) -+ prScanParam->ucSpecifiedSSIDLen[i] = 0; -+ } else { -+ prScanParam->ucSSIDNum = 0; -+ -+ for (i = 0; i < SCN_SSID_MAX_NUM; i++) -+ prScanParam->ucSpecifiedSSIDLen[i] = 0; -+ } -+ -+ prScanParam->u2ProbeDelayTime = 0; -+ prScanParam->eScanChannel = prScanReqMsg->eScanChannel; -+ if (prScanParam->eScanChannel == SCAN_CHANNEL_SPECIFIED) { -+ if (prScanReqMsg->ucChannelListNum <= MAXIMUM_OPERATION_CHANNEL_LIST) -+ prScanParam->ucChannelListNum = prScanReqMsg->ucChannelListNum; -+ else -+ prScanParam->ucChannelListNum = MAXIMUM_OPERATION_CHANNEL_LIST; -+ -+ kalMemCopy(prScanParam->arChnlInfoList, -+ prScanReqMsg->arChnlInfoList, sizeof(RF_CHANNEL_INFO_T) * prScanParam->ucChannelListNum); -+ } -+ -+ if (prScanReqMsg->u2IELen <= MAX_IE_LENGTH) -+ prScanParam->u2IELen = prScanReqMsg->u2IELen; -+ else -+ prScanParam->u2IELen = MAX_IE_LENGTH; -+ -+ if (prScanParam->u2IELen) -+ kalMemCopy(prScanParam->aucIE, prScanReqMsg->aucIE, prScanParam->u2IELen); -+#if CFG_ENABLE_WIFI_DIRECT -+ if (prScanParam->eNetTypeIndex == NETWORK_TYPE_P2P_INDEX) -+ prScanParam->u2PassiveListenInterval = prScanReqMsg->u2ChannelDwellTime; -+#endif -+ prScanParam->ucSeqNum = prScanReqMsg->ucSeqNum; -+ -+ if (prScanReqMsg->rMsgHdr.eMsgId == MID_RLM_SCN_SCAN_REQ) -+ prScanParam->fgIsObssScan = TRUE; -+ else -+ prScanParam->fgIsObssScan = FALSE; -+ -+ prScanParam->fgIsScanV2 = FALSE; -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Scan Message Parsing - V2 with multiple SSID support -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID scnFsmHandleScanMsgV2(IN P_ADAPTER_T prAdapter, IN P_MSG_SCN_SCAN_REQ_V2 prScanReqMsg) -+{ -+ P_SCAN_INFO_T prScanInfo; -+ P_SCAN_PARAM_T prScanParam; -+ UINT_32 i; -+ -+ ASSERT(prAdapter); -+ ASSERT(prScanReqMsg); -+ ASSERT(prScanReqMsg->ucSSIDNum <= SCN_SSID_MAX_NUM); -+ -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ prScanParam = &prScanInfo->rScanParam; -+ -+ prScanParam->eScanType = prScanReqMsg->eScanType; -+ prScanParam->eNetTypeIndex = (ENUM_NETWORK_TYPE_INDEX_T) prScanReqMsg->ucNetTypeIndex; -+ prScanParam->ucSSIDType = prScanReqMsg->ucSSIDType; -+ prScanParam->ucSSIDNum = prScanReqMsg->ucSSIDNum; -+ -+ for (i = 0; i < prScanReqMsg->ucSSIDNum; i++) { -+ COPY_SSID(prScanParam->aucSpecifiedSSID[i], -+ prScanParam->ucSpecifiedSSIDLen[i], -+ prScanReqMsg->prSsid[i].aucSsid, (UINT_8) prScanReqMsg->prSsid[i].u4SsidLen); -+ } -+ -+ prScanParam->u2ProbeDelayTime = prScanReqMsg->u2ProbeDelay; -+ prScanParam->eScanChannel = prScanReqMsg->eScanChannel; -+ if (prScanParam->eScanChannel == SCAN_CHANNEL_SPECIFIED) { -+ if (prScanReqMsg->ucChannelListNum <= MAXIMUM_OPERATION_CHANNEL_LIST) -+ prScanParam->ucChannelListNum = prScanReqMsg->ucChannelListNum; -+ else -+ prScanParam->ucChannelListNum = MAXIMUM_OPERATION_CHANNEL_LIST; -+ -+ kalMemCopy(prScanParam->arChnlInfoList, -+ prScanReqMsg->arChnlInfoList, sizeof(RF_CHANNEL_INFO_T) * prScanParam->ucChannelListNum); -+ } -+ -+ if (prScanReqMsg->u2IELen <= MAX_IE_LENGTH) -+ prScanParam->u2IELen = prScanReqMsg->u2IELen; -+ else -+ prScanParam->u2IELen = MAX_IE_LENGTH; -+ -+ if (prScanParam->u2IELen) -+ kalMemCopy(prScanParam->aucIE, prScanReqMsg->aucIE, prScanParam->u2IELen); -+#if CFG_ENABLE_WIFI_DIRECT -+ if (prScanParam->eNetTypeIndex == NETWORK_TYPE_P2P_INDEX) -+ prScanParam->u2PassiveListenInterval = prScanReqMsg->u2ChannelDwellTime; -+#endif -+ prScanParam->ucSeqNum = prScanReqMsg->ucSeqNum; -+ -+ if (prScanReqMsg->rMsgHdr.eMsgId == MID_RLM_SCN_SCAN_REQ) -+ prScanParam->fgIsObssScan = TRUE; -+ else -+ prScanParam->fgIsObssScan = FALSE; -+ -+ prScanParam->fgIsScanV2 = TRUE; -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Remove pending scan request -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID scnFsmRemovePendingMsg(IN P_ADAPTER_T prAdapter, IN UINT_8 ucSeqNum, IN UINT_8 ucNetTypeIndex) -+{ -+ P_SCAN_INFO_T prScanInfo; -+ P_SCAN_PARAM_T prScanParam; -+ P_MSG_HDR_T prPendingMsgHdr, prPendingMsgHdrNext, prRemoveMsgHdr = NULL; -+ P_LINK_ENTRY_T prRemoveLinkEntry = NULL; -+ -+ ASSERT(prAdapter); -+ -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ prScanParam = &prScanInfo->rScanParam; -+ -+ /* traverse through rPendingMsgList for removal */ -+ LINK_FOR_EACH_ENTRY_SAFE(prPendingMsgHdr, -+ prPendingMsgHdrNext, &(prScanInfo->rPendingMsgList), rLinkEntry, MSG_HDR_T) { -+ if (prPendingMsgHdr->eMsgId == MID_AIS_SCN_SCAN_REQ -+ || prPendingMsgHdr->eMsgId == MID_BOW_SCN_SCAN_REQ -+ || prPendingMsgHdr->eMsgId == MID_P2P_SCN_SCAN_REQ -+ || prPendingMsgHdr->eMsgId == MID_RLM_SCN_SCAN_REQ) { -+ P_MSG_SCN_SCAN_REQ prScanReqMsg = (P_MSG_SCN_SCAN_REQ) prPendingMsgHdr; -+ -+ if (ucSeqNum == prScanReqMsg->ucSeqNum && ucNetTypeIndex == prScanReqMsg->ucNetTypeIndex) { -+ prRemoveLinkEntry = &(prScanReqMsg->rMsgHdr.rLinkEntry); -+ prRemoveMsgHdr = prPendingMsgHdr; -+ } -+ } else if (prPendingMsgHdr->eMsgId == MID_AIS_SCN_SCAN_REQ_V2 -+ || prPendingMsgHdr->eMsgId == MID_BOW_SCN_SCAN_REQ_V2 -+ || prPendingMsgHdr->eMsgId == MID_P2P_SCN_SCAN_REQ_V2 -+ || prPendingMsgHdr->eMsgId == MID_RLM_SCN_SCAN_REQ_V2) { -+ P_MSG_SCN_SCAN_REQ_V2 prScanReqMsgV2 = (P_MSG_SCN_SCAN_REQ_V2) prPendingMsgHdr; -+ -+ if (ucSeqNum == prScanReqMsgV2->ucSeqNum && ucNetTypeIndex == prScanReqMsgV2->ucNetTypeIndex) { -+ prRemoveLinkEntry = &(prScanReqMsgV2->rMsgHdr.rLinkEntry); -+ prRemoveMsgHdr = prPendingMsgHdr; -+ } -+ } -+ -+ if (prRemoveLinkEntry) { -+ /* generate scan-done event for caller */ -+ scnFsmGenerateScanDoneMsg(prAdapter, ucSeqNum, ucNetTypeIndex, SCAN_STATUS_CANCELLED); -+ -+ /* remove from pending list */ -+ LINK_REMOVE_KNOWN_ENTRY(&(prScanInfo->rPendingMsgList), prRemoveLinkEntry); -+ cnmMemFree(prAdapter, prRemoveMsgHdr); -+ -+ break; -+ } -+ } -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID scnEventScanDone(IN P_ADAPTER_T prAdapter, IN P_EVENT_SCAN_DONE prScanDone) -+{ -+ P_SCAN_INFO_T prScanInfo; -+ P_SCAN_PARAM_T prScanParam; -+ -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ prScanParam = &prScanInfo->rScanParam; -+ -+ /* buffer empty channel information */ -+ if (prScanParam->eScanChannel == SCAN_CHANNEL_FULL || prScanParam->eScanChannel == SCAN_CHANNEL_2G4) { -+ if (prScanDone->ucSparseChannelValid) { -+ prScanInfo->fgIsSparseChannelValid = TRUE; -+ prScanInfo->rSparseChannel.eBand = (ENUM_BAND_T) prScanDone->rSparseChannel.ucBand; -+ prScanInfo->rSparseChannel.ucChannelNum = prScanDone->rSparseChannel.ucChannelNum; -+ } else { -+ prScanInfo->fgIsSparseChannelValid = FALSE; -+ } -+ } -+ -+ if (prScanInfo->eCurrentState == SCAN_STATE_SCANNING && prScanDone->ucSeqNum == prScanParam->ucSeqNum) { -+ /* generate scan-done event for caller */ -+ scnFsmGenerateScanDoneMsg(prAdapter, -+ prScanParam->ucSeqNum, (UINT_8) prScanParam->eNetTypeIndex, SCAN_STATUS_DONE); -+ -+ /* switch to next pending scan */ -+ scnFsmSteps(prAdapter, SCAN_STATE_IDLE); -+ } else { -+ DBGLOG(SCN, WARN, "Unexpected SCAN-DONE event: SeqNum = %d, Current State = %d\n", -+ prScanDone->ucSeqNum, prScanInfo->eCurrentState); -+ } -+ -+} /* end of scnEventScanDone */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+scnFsmGenerateScanDoneMsg(IN P_ADAPTER_T prAdapter, -+ IN UINT_8 ucSeqNum, IN UINT_8 ucNetTypeIndex, IN ENUM_SCAN_STATUS eScanStatus) -+{ -+ P_SCAN_INFO_T prScanInfo; -+ P_SCAN_PARAM_T prScanParam; -+ P_MSG_SCN_SCAN_DONE prScanDoneMsg; -+ -+ ASSERT(prAdapter); -+ -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ prScanParam = &prScanInfo->rScanParam; -+ -+ DBGLOG(SCN, INFO, "Rcv Scan Done, NetIdx %d, Obss %d, Status %d, Seq %d\n", -+ ucNetTypeIndex, prScanParam->fgIsObssScan, eScanStatus, ucSeqNum); -+ prScanDoneMsg = (P_MSG_SCN_SCAN_DONE) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_SCN_SCAN_DONE)); -+ if (!prScanDoneMsg) { -+ ASSERT(0); /* Can't indicate SCAN FSM Complete */ -+ return; -+ } -+ -+ if (prScanParam->fgIsObssScan == TRUE) { -+ prScanDoneMsg->rMsgHdr.eMsgId = MID_SCN_RLM_SCAN_DONE; -+ } else { -+ switch ((ENUM_NETWORK_TYPE_INDEX_T) ucNetTypeIndex) { -+ case NETWORK_TYPE_AIS_INDEX: -+ prScanDoneMsg->rMsgHdr.eMsgId = MID_SCN_AIS_SCAN_DONE; -+ break; -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ case NETWORK_TYPE_P2P_INDEX: -+ prScanDoneMsg->rMsgHdr.eMsgId = MID_SCN_P2P_SCAN_DONE; -+ break; -+#endif -+ -+#if CFG_ENABLE_BT_OVER_WIFI -+ case NETWORK_TYPE_BOW_INDEX: -+ prScanDoneMsg->rMsgHdr.eMsgId = MID_SCN_BOW_SCAN_DONE; -+ break; -+#endif -+ -+ default: -+ ASSERT(0); -+ break; -+ } -+ } -+ -+ prScanDoneMsg->ucSeqNum = ucSeqNum; -+ prScanDoneMsg->ucNetTypeIndex = ucNetTypeIndex; -+ prScanDoneMsg->eScanStatus = eScanStatus; -+ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prScanDoneMsg, MSG_SEND_METHOD_BUF); -+ -+} /* end of scnFsmGenerateScanDoneMsg() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Query for most sparse channel -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN scnQuerySparseChannel(IN P_ADAPTER_T prAdapter, P_ENUM_BAND_T prSparseBand, PUINT_8 pucSparseChannel) -+{ -+ P_SCAN_INFO_T prScanInfo; -+ -+ ASSERT(prAdapter); -+ -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ -+ if (prScanInfo->fgIsSparseChannelValid == TRUE) { -+ if (prSparseBand) -+ *prSparseBand = prScanInfo->rSparseChannel.eBand; -+ -+ if (pucSparseChannel) -+ *pucSparseChannel = prScanInfo->rSparseChannel.ucChannelNum; -+ -+ return TRUE; -+ } else { -+ return FALSE; -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Event handler for NLO done event -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID scnEventNloDone(IN P_ADAPTER_T prAdapter, IN P_EVENT_NLO_DONE_T prNloDone) -+{ -+ P_SCAN_INFO_T prScanInfo; -+ P_NLO_PARAM_T prNloParam; -+ P_SCAN_PARAM_T prScanParam; -+ -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ prNloParam = &prScanInfo->rNloParam; -+ prScanParam = &prNloParam->rScanParam; -+ -+ if (prScanInfo->fgNloScanning == TRUE) { -+ DBGLOG(SCN, INFO, "scnEventNloDone Current State = %d\n", prScanInfo->eCurrentState); -+ -+ kalSchedScanResults(prAdapter->prGlueInfo); -+ -+ if (prNloParam->fgStopAfterIndication == TRUE) -+ prScanInfo->fgNloScanning = FALSE; -+ -+ kalMemZero(&prNloParam->aprPendingBssDescToInd[0], -+ CFG_SCAN_SSID_MATCH_MAX_NUM * sizeof(P_BSS_DESC_T)); -+ } else { -+ DBGLOG(SCN, INFO, "Unexpected NLO-DONE event\n"); -+ } -+ -+} -+ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief handler for starting scheduled scan -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN -+scnFsmSchedScanRequest(IN P_ADAPTER_T prAdapter, -+ IN UINT_8 ucSsidNum, -+ IN P_PARAM_SSID_T prSsid, IN UINT_32 u4IeLength, IN PUINT_8 pucIe, IN UINT_16 u2Interval) -+{ -+ P_SCAN_INFO_T prScanInfo; -+ P_NLO_PARAM_T prNloParam; -+ P_SCAN_PARAM_T prScanParam; -+ P_CMD_NLO_REQ prCmdNloReq; -+ UINT_32 i, j; -+ -+ ASSERT(prAdapter); -+ -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ prNloParam = &prScanInfo->rNloParam; -+ prScanParam = &prNloParam->rScanParam; -+ -+ if (prScanInfo->fgNloScanning) { -+ DBGLOG(SCN, INFO, "prScanInfo->fgNloScanning == TRUE already scanning\n"); -+ return TRUE; -+ } -+ -+ prScanInfo->fgNloScanning = TRUE; -+ -+ /* 1. load parameters */ -+ prScanParam->ucSeqNum++; -+ /* prScanParam->ucBssIndex = prAdapter->prAisBssInfo->ucBssIndex; */ -+ -+ prNloParam->fgStopAfterIndication = TRUE; -+ prNloParam->ucFastScanIteration = 0; -+ prNloParam->u2FastScanPeriod = u2Interval; -+ prNloParam->u2SlowScanPeriod = u2Interval; -+ -+ if (prScanParam->ucSSIDNum > CFG_SCAN_SSID_MAX_NUM) -+ prScanParam->ucSSIDNum = CFG_SCAN_SSID_MAX_NUM; -+ else -+ prScanParam->ucSSIDNum = ucSsidNum; -+ -+ if (prNloParam->ucMatchSSIDNum > CFG_SCAN_SSID_MATCH_MAX_NUM) -+ prNloParam->ucMatchSSIDNum = CFG_SCAN_SSID_MATCH_MAX_NUM; -+ else -+ prNloParam->ucMatchSSIDNum = ucSsidNum; -+ -+ for (i = 0; i < prNloParam->ucMatchSSIDNum; i++) { -+ if (i < CFG_SCAN_SSID_MAX_NUM) { -+ COPY_SSID(prScanParam->aucSpecifiedSSID[i], -+ prScanParam->ucSpecifiedSSIDLen[i], prSsid[i].aucSsid, (UINT_8) prSsid[i].u4SsidLen); -+ } -+ -+ COPY_SSID(prNloParam->aucMatchSSID[i], -+ prNloParam->ucMatchSSIDLen[i], prSsid[i].aucSsid, (UINT_8) prSsid[i].u4SsidLen); -+ -+ prNloParam->aucCipherAlgo[i] = 0; -+ prNloParam->au2AuthAlgo[i] = 0; -+ -+ for (j = 0; j < SCN_NLO_NETWORK_CHANNEL_NUM; j++) -+ prNloParam->aucChannelHint[i][j] = 0; -+ } -+ -+ /* 2. prepare command for sending */ -+ prCmdNloReq = (P_CMD_NLO_REQ) cnmMemAlloc(prAdapter, RAM_TYPE_BUF, sizeof(CMD_NLO_REQ) + prScanParam->u2IELen); -+ -+ if (!prCmdNloReq) { -+ ASSERT(0); /* Can't initiate NLO operation */ -+ return FALSE; -+ } -+ -+ /* 3. send command packet for NLO operation */ -+ kalMemZero(prCmdNloReq, sizeof(CMD_NLO_REQ)); -+ -+ prCmdNloReq->ucSeqNum = prScanParam->ucSeqNum; -+ /* prCmdNloReq->ucBssIndex = prScanParam->ucBssIndex; */ -+ -+ prCmdNloReq->ucNetworkType = prScanParam->eNetTypeIndex; -+ prCmdNloReq->ucScanType = (UINT_8) prScanParam->eScanType; -+ -+ prCmdNloReq->fgStopAfterIndication = prNloParam->fgStopAfterIndication; -+ prCmdNloReq->ucFastScanIteration = prNloParam->ucFastScanIteration; -+ prCmdNloReq->u2FastScanPeriod = prNloParam->u2FastScanPeriod; -+ prCmdNloReq->u2SlowScanPeriod = prNloParam->u2SlowScanPeriod; -+ prCmdNloReq->ucEntryNum = prNloParam->ucMatchSSIDNum; -+ for (i = 0; i < prNloParam->ucMatchSSIDNum; i++) { -+ COPY_SSID(prCmdNloReq->arNetworkList[i].aucSSID, -+ prCmdNloReq->arNetworkList[i].ucSSIDLength, -+ prNloParam->aucMatchSSID[i], prNloParam->ucMatchSSIDLen[i]); -+ -+ prCmdNloReq->arNetworkList[i].ucCipherAlgo = prNloParam->aucCipherAlgo[i]; -+ prCmdNloReq->arNetworkList[i].u2AuthAlgo = prNloParam->au2AuthAlgo[i]; -+ -+ for (j = 0; j < SCN_NLO_NETWORK_CHANNEL_NUM; j++) -+ prCmdNloReq->arNetworkList[i].ucNumChannelHint[j] = prNloParam->aucChannelHint[i][j]; -+ } -+ -+ if (prScanParam->u2IELen <= MAX_IE_LENGTH) -+ prCmdNloReq->u2IELen = prScanParam->u2IELen; -+ else -+ prCmdNloReq->u2IELen = MAX_IE_LENGTH; -+ -+ if (prScanParam->u2IELen) -+ kalMemCopy(prCmdNloReq->aucIE, prScanParam->aucIE, sizeof(UINT_8) * prCmdNloReq->u2IELen); -+#if !CFG_SUPPORT_GSCN -+ -+ wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SET_NLO_REQ, -+ TRUE, -+ FALSE, -+ TRUE, -+ nicCmdEventSetCommon, -+ nicOidCmdTimeoutCommon, -+ sizeof(CMD_NLO_REQ) + prCmdNloReq->u2IELen, (PUINT_8) prCmdNloReq, NULL, 0); -+ -+#else -+ scnPSCNFsm(prAdapter, PSCN_RESET, prCmdNloReq, NULL, NULL, NULL, FALSE, FALSE, FALSE, FALSE); -+#endif -+ cnmMemFree(prAdapter, (PVOID) prCmdNloReq); -+ -+ return TRUE; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief handler for stopping scheduled scan -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN scnFsmSchedScanStopRequest(IN P_ADAPTER_T prAdapter) -+{ -+ P_SCAN_INFO_T prScanInfo; -+ P_NLO_PARAM_T prNloParam; -+ P_SCAN_PARAM_T prScanParam; -+ CMD_NLO_CANCEL rCmdNloCancel; -+ -+ ASSERT(prAdapter); -+ -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ prNloParam = &prScanInfo->rNloParam; -+ prScanParam = &prNloParam->rScanParam; -+ -+ /* send cancel message to firmware domain */ -+ rCmdNloCancel.ucSeqNum = prScanParam->ucSeqNum; -+ -+#if !CFG_SUPPORT_GSCN -+ -+ wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SET_NLO_CANCEL, -+ TRUE, -+ FALSE, -+ TRUE, -+ nicCmdEventSetStopSchedScan, -+ nicOidCmdTimeoutCommon, sizeof(CMD_NLO_CANCEL), (PUINT_8)(&rCmdNloCancel), NULL, 0); -+#else -+ -+ scnPSCNFsm(prAdapter, PSCN_RESET, NULL, NULL, NULL, NULL, TRUE, FALSE, FALSE, FALSE); -+#endif -+ -+ prScanInfo->fgNloScanning = FALSE; -+ -+ return TRUE; -+} -+ -+#if CFG_SUPPORT_GSCN -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief handler for Set PSCN action -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN scnFsmPSCNAction(IN P_ADAPTER_T prAdapter, IN UINT_8 ucPscanAct) -+{ -+ CMD_SET_PSCAN_ENABLE rCmdPscnAction; -+ P_SCAN_INFO_T prScanInfo; -+ -+ DBGLOG(SCN, TRACE, "scnFsmPSCNAction Act = %d\n", ucPscanAct); -+ -+ rCmdPscnAction.ucPscanAct = ucPscanAct; -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ -+ if (ucPscanAct == DISABLE) -+ prScanInfo->fgPscnOnnning = FALSE; -+ if (ucPscanAct == ENABLE) -+ prScanInfo->fgPscnOnnning = TRUE; -+ -+ wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SET_PSCN_ENABLE, -+ TRUE, -+ FALSE, -+ FALSE, NULL, NULL, sizeof(CMD_SET_PSCAN_ENABLE), (PUINT_8) &rCmdPscnAction, NULL, 0); -+ -+ DBGLOG(SCN, INFO, "scnFsmPSCNAction Act = %d is Set to FW\n", ucPscanAct); -+ return TRUE; -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief handler for Set PSCN param -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN scnFsmPSCNSetParam(IN P_ADAPTER_T prAdapter, IN P_CMD_SET_PSCAN_PARAM prCmdPscnParam) -+{ -+ UINT_8 i, j; -+ -+ i = 0; -+ j = 0; -+ -+ ASSERT(prAdapter); -+ /*prCmdPscnParam->u4BasePeriod = prCmdPscnParam->u4BasePeriod;*/ -+#if 0 -+ DBGLOG(SCN, TRACE, -+ "rCmdPscnParam: Period[%u],NumCache[%u],Threshold[%u],NumBkts[%u],fgGSCN[%d] fgNLO[%d] fgBatch[%d]\n", -+ prCmdPscnParam->rCmdGscnReq.u4BasePeriod, prCmdPscnParam->rCmdGscnReq.ucNumScnToCache, -+ prCmdPscnParam->rCmdGscnReq.u4BufferThreshold, prCmdPscnParam->rCmdGscnReq.u4NumBuckets, -+ prCmdPscnParam->fgGScnEnable, prCmdPscnParam->fgNLOScnEnable, prCmdPscnParam->fgBatchScnEnable)); -+ -+ for (i = 0; i < prCmdPscnParam->rCmdGscnReq.u4NumBuckets; i++) { -+ DBGLOG(SCN, TRACE, "rCmdPscnParam.rCmdGscnParam.arChannelBucket[%d] has channel: ", i); -+ DBGLOG(SCN, TRACE, -+ "band[%u], Index[%u] NumChannels[%u], ucBktFreqMultiple[%u] Flag[%u]\n", -+ prCmdPscnParam->rCmdGscnReq.arChannelBucket[i].eBand, -+ prCmdPscnParam->rCmdGscnReq.arChannelBucket[i].u2BucketIndex, -+ prCmdPscnParam->rCmdGscnReq.arChannelBucket[i].ucNumChannels, -+ prCmdPscnParam->rCmdGscnReq.arChannelBucket[i].ucBucketFreqMultiple, -+ prCmdPscnParam->rCmdGscnReq.arChannelBucket[i].ucReportFlag)); -+ for (j = 0; j < prCmdPscnParam->rCmdGscnReq.arChannelBucket[i].ucNumChannels; j++) -+ DBGLOG(SCN, TRACE, -+ " %d, ", prCmdPscnParam->rCmdGscnReq.arChannelBucket[i].arChannelList[j].ucChannel); -+ DBGLOG(SCN, TRACE, "\n"); -+ } -+#endif -+ -+ if (1 /*prScanInfo->fgPscnOnnning == FALSE */) { -+ wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SET_PSCAN_PARAM, -+ TRUE, -+ FALSE, -+ FALSE, NULL, NULL, sizeof(CMD_SET_PSCAN_PARAM), (PUINT_8) prCmdPscnParam, NULL, 0); -+ -+ DBGLOG(SCN, TRACE, "CMD_ID_SET_PSCAN_PARAM is set to FW !!!!!!!!!!\n"); -+ return TRUE; -+ } -+ return FALSE; -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief handler for Set hotlist -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN scnFsmPSCNSetHotlist(IN P_ADAPTER_T prAdapter, IN P_CMD_SET_PSCAN_ADD_HOTLIST_BSSID prCmdPscnAddHotlist) -+{ -+ CMD_SET_PSCAN_ADD_HOTLIST_BSSID rCmdPscnAddHotlist; -+ P_SCAN_INFO_T prScanInfo; -+ -+ ASSERT(prAdapter); -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ memcpy(&rCmdPscnAddHotlist.aucMacAddr, &(prCmdPscnAddHotlist->aucMacAddr), sizeof(MAC_ADDR_LEN)); -+ -+ /* rCmdPscnAddHotlist.aucMacAddr = prCmdPscnAddHotlist->aucMacAddr; */ -+ rCmdPscnAddHotlist.ucFlags = prCmdPscnAddHotlist->ucFlags; -+ -+ if (prScanInfo->fgPscnOnnning && prScanInfo->prPscnParam->fgGScnEnable) { -+ wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SET_PSCN_ADD_HOTLIST_BSSID, -+ TRUE, -+ FALSE, -+ FALSE, -+ NULL, -+ NULL, -+ sizeof(CMD_SET_PSCAN_ADD_HOTLIST_BSSID), (PUINT_8) &rCmdPscnAddHotlist, NULL, 0); -+ return TRUE; -+ } -+ /* debug msg, No PSCN, Sched SCAN no need to add the hotlist ??? */ -+ return FALSE; -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief handler for Set CMD_ID_SET_PSCN_ADD_SW_BSSID -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN scnFsmPSCNAddSWCBssId(IN P_ADAPTER_T prAdapter, IN P_CMD_SET_PSCAN_ADD_SWC_BSSID prCmdPscnAddSWCBssId) -+{ -+ CMD_SET_PSCAN_ADD_SWC_BSSID rCmdPscnAddSWCBssId; -+ P_SCAN_INFO_T prScanInfo; -+ -+ ASSERT(prAdapter); -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ -+ memcpy(&rCmdPscnAddSWCBssId.aucMacAddr, &(prCmdPscnAddSWCBssId->aucMacAddr), sizeof(MAC_ADDR_LEN)); -+ -+ /* rCmdPscnAddSWCBssId.aucMacAddr = prCmdPscnAddSWCBssId->aucMacAddr; */ -+ rCmdPscnAddSWCBssId.i4RssiHighThreshold = prCmdPscnAddSWCBssId->i4RssiHighThreshold; -+ rCmdPscnAddSWCBssId.i4RssiLowThreshold = prCmdPscnAddSWCBssId->i4RssiLowThreshold; -+ -+ if (prScanInfo->fgPscnOnnning && prScanInfo->prPscnParam->fgGScnEnable) { -+ wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SET_PSCN_ADD_SW_BSSID, -+ TRUE, -+ FALSE, -+ FALSE, -+ NULL, -+ NULL, -+ sizeof(CMD_SET_PSCAN_ADD_SWC_BSSID), (PUINT_8) &rCmdPscnAddSWCBssId, NULL, 0); -+ return TRUE; -+ } -+ /* debug msg, No PSCN, Sched SCAN no need to add the hotlist ??? */ -+ return FALSE; -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief handler for Set CMD_ID_SET_PSCN_MAC_ADDR -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN scnFsmPSCNSetMacAddr(IN P_ADAPTER_T prAdapter, IN P_CMD_SET_PSCAN_MAC_ADDR prCmdPscnSetMacAddr) -+{ -+ CMD_SET_PSCAN_MAC_ADDR rCmdPscnSetMacAddr; -+ P_SCAN_INFO_T prScanInfo; -+ -+ ASSERT(prAdapter); -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ -+ /* rCmdPscnSetMacAddr.aucMacAddr = prCmdPscnSetMacAddr->aucMacAddr; */ -+ memcpy(&rCmdPscnSetMacAddr.aucMacAddr, &(prCmdPscnSetMacAddr->aucMacAddr), sizeof(MAC_ADDR_LEN)); -+ -+ rCmdPscnSetMacAddr.ucFlags = prCmdPscnSetMacAddr->ucFlags; -+ rCmdPscnSetMacAddr.ucVersion = prCmdPscnSetMacAddr->ucVersion; -+ -+ if (1 /* (prScanInfo->fgPscnOnnning == TRUE */) { -+ wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SET_PSCN_MAC_ADDR, -+ TRUE, -+ FALSE, -+ FALSE, -+ NULL, -+ NULL, sizeof(CMD_SET_PSCAN_MAC_ADDR), (PUINT_8) &rCmdPscnSetMacAddr, NULL, 0); -+ return TRUE; -+ } -+ /* debug msg, No PSCN, Sched SCAN no need to add the hotlist ??? */ -+ return FALSE; -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief handler for Set GSCN param -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN scnSetGSCNParam(IN P_ADAPTER_T prAdapter, IN P_PARAM_WIFI_GSCAN_CMD_PARAMS prCmdGscnParam) -+{ -+ /*CMD_GSCN_REQ_T rCmdGscnParam;*/ -+ P_CMD_GSCN_REQ_T rCmdGscnParamp; -+ P_SCAN_INFO_T prScanInfo; -+ UINT_8 ucChannelBuckIndex; -+ UINT_8 i; -+ -+ ASSERT(prAdapter); -+ rCmdGscnParamp = kalMemAlloc(sizeof(CMD_GSCN_REQ_T), VIR_MEM_TYPE); -+ if (rCmdGscnParamp == NULL) { -+ DBGLOG(SCN, INFO, "alloc CmdGscnParam fail\n"); -+ return TRUE; -+ } -+ kalMemZero(rCmdGscnParamp, sizeof(CMD_GSCN_REQ_T)); -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ rCmdGscnParamp->u4NumBuckets = prCmdGscnParam->num_buckets; -+ rCmdGscnParamp->u4BasePeriod = prCmdGscnParam->base_period; -+ DBGLOG(SCN, INFO, -+ "u4BasePeriod[%d], u4NumBuckets[%d]\n", rCmdGscnParamp->u4BasePeriod, rCmdGscnParamp->u4NumBuckets); -+ for (ucChannelBuckIndex = 0; ucChannelBuckIndex < prCmdGscnParam->num_buckets; ucChannelBuckIndex++) { -+ DBGLOG(SCN, TRACE, "assign channels to bucket[%d]\n", ucChannelBuckIndex); -+ for (i = 0; i < prCmdGscnParam->buckets[ucChannelBuckIndex].num_channels; i++) { -+ rCmdGscnParamp->arChannelBucket[ucChannelBuckIndex].arChannelList[i].ucChannel = -+ (UINT_8) nicFreq2ChannelNum(prCmdGscnParam->buckets[ucChannelBuckIndex]. -+ channels[i].channel * 1000); -+ rCmdGscnParamp->arChannelBucket[ucChannelBuckIndex].arChannelList[i].ucPassive = -+ (UINT_8) prCmdGscnParam->buckets[ucChannelBuckIndex].channels[i].passive; -+ rCmdGscnParamp->arChannelBucket[ucChannelBuckIndex].arChannelList[i].u4DwellTimeMs = -+ (UINT_8) prCmdGscnParam->buckets[ucChannelBuckIndex].channels[i].dwellTimeMs; -+ -+ DBGLOG(SCN, TRACE, "[ucChannel %d, ucPassive %d, u4DwellTimeMs %d\n", -+ rCmdGscnParamp->arChannelBucket[ucChannelBuckIndex].arChannelList[i].ucChannel, -+ rCmdGscnParamp->arChannelBucket[ucChannelBuckIndex].arChannelList[i].ucPassive, -+ rCmdGscnParamp->arChannelBucket[ucChannelBuckIndex].arChannelList[i].u4DwellTimeMs); -+ -+ } -+ rCmdGscnParamp->arChannelBucket[ucChannelBuckIndex].u2BucketIndex = -+ (UINT_16) prCmdGscnParam->buckets[ucChannelBuckIndex].bucket; -+ rCmdGscnParamp->arChannelBucket[ucChannelBuckIndex].eBand = -+ prCmdGscnParam->buckets[ucChannelBuckIndex].band; -+ rCmdGscnParamp->arChannelBucket[ucChannelBuckIndex].ucBucketFreqMultiple = -+ (prCmdGscnParam->buckets[ucChannelBuckIndex].period / prCmdGscnParam->base_period); -+ rCmdGscnParamp->arChannelBucket[ucChannelBuckIndex].ucNumChannels = -+ prCmdGscnParam->buckets[ucChannelBuckIndex].num_channels; -+ rCmdGscnParamp->arChannelBucket[ucChannelBuckIndex].ucReportFlag = -+ prCmdGscnParam->buckets[ucChannelBuckIndex].report_events; -+ -+ /* printk("\n"); */ -+ } -+ -+ DBGLOG(SCN, INFO, "scnSetGSCNParam ---> scnPSCNFsm PSCN_RESET\n"); -+ -+ scnPSCNFsm(prAdapter, PSCN_RESET, NULL, NULL, rCmdGscnParamp, NULL, FALSE, FALSE, FALSE, FALSE); -+ kalMemFree(rCmdGscnParamp, VIR_MEM_TYPE, sizeof(CMD_GSCN_REQ_T)); -+ return TRUE; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief handler for Combine PNO Scan params into PSCAN param -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+ -+VOID -+scnSubCombineNLOtoPSCN(IN P_ADAPTER_T prAdapter, -+ IN P_CMD_NLO_REQ prNewCmdNloReq, IN P_CMD_SET_PSCAN_PARAM prCmdPscnParam) -+{ -+ P_SCAN_INFO_T prScanInfo; -+ -+ ASSERT(prAdapter); -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ -+ if (prNewCmdNloReq) { -+ prCmdPscnParam->fgNLOScnEnable = TRUE; -+ memcpy(&prCmdPscnParam->rCmdNloReq, prNewCmdNloReq, sizeof(CMD_NLO_REQ)); -+ } else if (prScanInfo->prPscnParam->fgNLOScnEnable) { -+ memcpy(&prCmdPscnParam->rCmdNloReq, &prScanInfo->prPscnParam->rCurrentCmdNloReq, sizeof(CMD_NLO_REQ)); -+ } else -+ prCmdPscnParam->fgNLOScnEnable = FALSE; -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief handler for Combine Batcht Scan params into PSCAN param -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+ -+VOID -+scnSubCombineBatchSCNtoPSCN(IN P_ADAPTER_T prAdapter, -+ IN P_CMD_BATCH_REQ_T prNewCmdBatchReq, IN P_CMD_SET_PSCAN_PARAM prCmdPscnParam) -+{ -+ P_SCAN_INFO_T prScanInfo; -+ -+ ASSERT(prAdapter); -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ -+ if (prNewCmdBatchReq) { -+ prCmdPscnParam->fgBatchScnEnable = TRUE; -+ memcpy(&prCmdPscnParam->rCmdBatchReq, prNewCmdBatchReq, sizeof(CMD_BATCH_REQ_T)); -+ } else if (prScanInfo->prPscnParam->fgBatchScnEnable) { -+ memcpy(&prCmdPscnParam->rCmdBatchReq, &prScanInfo->prPscnParam->rCurrentCmdBatchReq, -+ sizeof(CMD_BATCH_REQ_T)); -+ } else -+ prCmdPscnParam->fgBatchScnEnable = FALSE; -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief handler for Combine GSCN Scan params into PSCAN param -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+ -+VOID -+scnSubCombineGSCNtoPSCN(IN P_ADAPTER_T prAdapter, -+ IN P_CMD_GSCN_REQ_T prNewCmdGscnReq, -+ IN P_CMD_GSCN_SCN_COFIG_T prNewCmdGscnConfig, IN P_CMD_SET_PSCAN_PARAM prCmdPscnParam) -+{ -+ P_SCAN_INFO_T prScanInfo; -+ UINT_32 ucPeriodMin = MAX_PERIOD; -+ -+ ASSERT(prAdapter); -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ prCmdPscnParam->fgGScnEnable = FALSE; -+ -+ DBGLOG(SCN, TRACE, "scnSubCombineGSCNtoPSCN fgGScnParamSet %d fgGScnConfigSet %d\n", -+ prScanInfo->fgGScnParamSet, prScanInfo->fgGScnConfigSet); -+ -+ if (prNewCmdGscnReq) { -+ DBGLOG(SCN, INFO, "setup prNewCmdGscnReq\n"); -+ prScanInfo->fgGScnParamSet = TRUE; -+ memcpy(&prCmdPscnParam->rCmdGscnReq, prNewCmdGscnReq, sizeof(CMD_GSCN_REQ_T)); -+ if (ucPeriodMin > prNewCmdGscnReq->u4BasePeriod) -+ prCmdPscnParam->u4BasePeriod = prNewCmdGscnReq->u4BasePeriod; -+ } else if (prScanInfo->fgGScnParamSet) { -+ DBGLOG(SCN, INFO, "no new prNewCmdGscnReq but there is a old one\n"); -+ memcpy(&prCmdPscnParam->rCmdGscnReq, &prScanInfo->prPscnParam->rCurrentCmdGscnReq, -+ sizeof(CMD_GSCN_REQ_T)); -+ prCmdPscnParam->u4BasePeriod = prScanInfo->prPscnParam->u4BasePeriod; -+ } else -+ prScanInfo->fgGScnParamSet = FALSE; -+ -+ if (prNewCmdGscnConfig) { -+ DBGLOG(SCN, INFO, "set up prNewCmdGscnConfig\n"); -+ memcpy(prCmdPscnParam, prScanInfo->prPscnParam, sizeof(CMD_SET_PSCAN_PARAM)); -+ prScanInfo->fgGScnConfigSet = TRUE; -+ prCmdPscnParam->rCmdGscnReq.u4BufferThreshold = prNewCmdGscnConfig->u4BufferThreshold; -+ prCmdPscnParam->rCmdGscnReq.ucNumScnToCache = (UINT_8) prNewCmdGscnConfig->u4NumScnToCache; -+ } else if (prScanInfo->fgGScnConfigSet) { -+ DBGLOG(SCN, INFO, "no new prNewCmdGscnConfig but there is a old one\n"); -+ memcpy(prCmdPscnParam, prScanInfo->prPscnParam, sizeof(CMD_SET_PSCAN_PARAM)); -+ prCmdPscnParam->rCmdGscnReq.u4BufferThreshold = -+ prScanInfo->prPscnParam->rCurrentCmdGscnReq.u4BufferThreshold; -+ prCmdPscnParam->rCmdGscnReq.ucNumScnToCache = -+ (UINT_8) prScanInfo->prPscnParam->rCurrentCmdGscnReq.ucNumScnToCache; -+ } else -+ prScanInfo->fgGScnConfigSet = FALSE; -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief handler for Combine GSCN Scan params into PSCAN param -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+ -+VOID -+scnRemoveFromPSCN(IN P_ADAPTER_T prAdapter, -+ IN BOOLEAN fgRemoveNLOfromPSCN, -+ IN BOOLEAN fgRemoveBatchSCNfromPSCN, -+ IN BOOLEAN fgRemoveGSCNfromPSCN, IN P_CMD_SET_PSCAN_PARAM prCmdPscnParam) -+{ -+ P_SCAN_INFO_T prScanInfo; -+ UINT_8 ucPscanAct = DISABLE; -+ -+ ASSERT(prAdapter); -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ -+ { -+ DBGLOG(SCN, INFO, "remove NLO or Batch or GSCN from PSCN--->NLO=%d, BSN=%d, GSN=%d\n", -+ fgRemoveNLOfromPSCN, fgRemoveBatchSCNfromPSCN, fgRemoveGSCNfromPSCN); -+ -+ if (fgRemoveNLOfromPSCN) { -+ memcpy(prCmdPscnParam, prScanInfo->prPscnParam, sizeof(CMD_SET_PSCAN_PARAM)); -+ prCmdPscnParam->fgNLOScnEnable = FALSE; -+ kalMemZero(&prCmdPscnParam->rCmdNloReq, sizeof(CMD_NLO_REQ)); -+ kalMemZero(&prScanInfo->prPscnParam->rCurrentCmdNloReq, sizeof(CMD_NLO_REQ)); -+ } -+ if (fgRemoveBatchSCNfromPSCN) { -+ memcpy(prCmdPscnParam, prScanInfo->prPscnParam, sizeof(CMD_SET_PSCAN_PARAM)); -+ prCmdPscnParam->fgBatchScnEnable = FALSE; -+ kalMemZero(&prCmdPscnParam->rCmdBatchReq, sizeof(CMD_BATCH_REQ_T)); -+ kalMemZero(&prScanInfo->prPscnParam->rCurrentCmdBatchReq, sizeof(CMD_BATCH_REQ_T)); -+ } -+ if (fgRemoveGSCNfromPSCN) { -+ memcpy(prCmdPscnParam, prScanInfo->prPscnParam, sizeof(CMD_SET_PSCAN_PARAM)); -+ prCmdPscnParam->fgGScnEnable = FALSE; -+ prScanInfo->fgGScnParamSet = FALSE; -+ kalMemZero(&prCmdPscnParam->rCmdGscnReq, sizeof(CMD_GSCN_REQ_T)); -+ kalMemZero(&prScanInfo->prPscnParam->rCurrentCmdGscnReq, sizeof(CMD_GSCN_REQ_T)); -+ } -+ -+ if (!fgRemoveNLOfromPSCN && !fgRemoveBatchSCNfromPSCN && !fgRemoveGSCNfromPSCN) { -+ /* prCmdPscnParam->fgIsPeriodicallyScn = FALSE; */ -+ prScanInfo->fgPscnOnnning = FALSE; -+ scnFsmPSCNSetParam(prAdapter, prCmdPscnParam); -+ scnFsmPSCNAction(prAdapter, ucPscanAct); -+ } else { -+ /* prCmdPscnParam->fgIsPeriodicallyScn = TRUE; */ -+ scnFsmPSCNSetParam(prAdapter, prCmdPscnParam); -+ DBGLOG(SCN, INFO, " disable NLO or GSCN or Batch but fgIsPeriodicallyScn = TRUE <-----\n"); -+ } -+ } -+ -+} -+ -+#if 1 -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief handler for Combine GSCN , Batch, PNO Scan params into PSCAN param -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+ -+BOOLEAN -+scnCombineParamsIntoPSCN(IN P_ADAPTER_T prAdapter, -+ IN P_CMD_NLO_REQ prNewCmdNloReq, -+ IN P_CMD_BATCH_REQ_T prNewCmdBatchReq, -+ IN P_CMD_GSCN_REQ_T prNewCmdGscnReq, -+ IN P_CMD_GSCN_SCN_COFIG_T prNewCmdGscnConfig, -+ IN BOOLEAN fgRemoveNLOfromPSCN, -+ IN BOOLEAN fgRemoveBatchSCNfromPSCN, IN BOOLEAN fgRemoveGSCNfromPSCN) -+{ -+ P_SCAN_INFO_T prScanInfo; -+ /* CMD_SET_PSCAN_PARAM rCmdPscnParam; */ -+ P_CMD_SET_PSCAN_PARAM prCmdPscnParam; -+ /* UINT_8 i, j = 0; */ -+ -+ ASSERT(prAdapter); -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ -+ prCmdPscnParam = (P_CMD_SET_PSCAN_PARAM) kalMemAlloc(sizeof(CMD_SET_PSCAN_PARAM), VIR_MEM_TYPE); -+ if (!prCmdPscnParam) { -+ DBGLOG(SCN, ERROR, "Can not alloc memory for PARAM_WIFI_GSCAN_CMD_PARAMS\n"); -+ return -ENOMEM; -+ } -+ kalMemZero(prCmdPscnParam, sizeof(CMD_SET_PSCAN_PARAM)); -+ -+ prCmdPscnParam->ucVersion = CURRENT_PSCN_VERSION; -+ -+ if (fgRemoveNLOfromPSCN || fgRemoveBatchSCNfromPSCN || fgRemoveGSCNfromPSCN) { -+ scnRemoveFromPSCN(prAdapter, -+ fgRemoveNLOfromPSCN, fgRemoveBatchSCNfromPSCN, fgRemoveGSCNfromPSCN, prCmdPscnParam); -+ } else { -+ DBGLOG(SCN, INFO, "combine GSCN or Batch or NLO to PSCN --->\n"); -+ -+ scnSubCombineNLOtoPSCN(prAdapter, prNewCmdNloReq, prCmdPscnParam); -+ scnSubCombineBatchSCNtoPSCN(prAdapter, prNewCmdBatchReq, prCmdPscnParam); -+ if (prNewCmdGscnReq) -+ scnSubCombineGSCNtoPSCN(prAdapter, prNewCmdGscnReq, NULL, prCmdPscnParam); -+ if (prNewCmdGscnConfig) -+ scnSubCombineGSCNtoPSCN(prAdapter, NULL, prNewCmdGscnConfig, prCmdPscnParam); -+ /* scnFsmPSCNSetParam(prAdapter, prCmdPscnParam); */ -+ -+#if 0 -+ DBGLOG(SCN, TRACE, "combine GSCN or Batch or NLO to PSCN <--- rCmdPscnParam\n"); -+ DBGLOG(SCN, TRACE, -+ "Period[%u], NumCache[%u], Threshold[%u], NumBuckets[%u],GSCNEn[%d] NLOEn[%d] BatchEn[%d]\n", -+ prCmdPscnParam->rCmdGscnReq.u4BasePeriod, prCmdPscnParam->rCmdGscnReq.ucNumScnToCache, -+ prCmdPscnParam->rCmdGscnReq.u4BufferThreshold, prCmdPscnParam->rCmdGscnReq.u4NumBuckets, -+ prCmdPscnParam->fgGScnEnable, prCmdPscnParam->fgNLOScnEnable, -+ prCmdPscnParam->fgBatchScnEnable)); -+ -+ for (i = 0; i < prCmdPscnParam->rCmdGscnReq.u4NumBuckets; i++) { -+ DBGLOG(SCN, TRACE, "rCmdPscnParam.rCmdGscnParam.arChannelBucket[%d] has channel: ", i); -+ DBGLOG(SCN, TRACE, -+ "band[%u], ChnBkt[%u] NumChns[%u], BktFreqMltpl[%u] Flag[%u]\n", -+ prCmdPscnParam->rCmdGscnReq.arChannelBucket[i].eBand, -+ prCmdPscnParam->rCmdGscnReq.arChannelBucket[i].u2BucketIndex, -+ prCmdPscnParam->rCmdGscnReq.arChannelBucket[i].ucNumChannels, -+ prCmdPscnParam->rCmdGscnReq.arChannelBucket[i].ucBucketFreqMultiple, -+ prCmdPscnParam->rCmdGscnReq.arChannelBucket[i].ucReportFlag)); -+ for (j = 0; j < prCmdPscnParam->rCmdGscnReq.arChannelBucket[i].ucNumChannels; j++) { -+ DBGLOG(SCN, TRACE, " %d, ", -+ prCmdPscnParam->rCmdGscnReq.arChannelBucket[i].arChannelList[j].ucChannel); -+ } -+ DBGLOG(SCN, TRACE, "\n"); -+ } -+#endif -+ } -+ -+ memcpy(prScanInfo->prPscnParam, prCmdPscnParam, sizeof(CMD_SET_PSCAN_PARAM)); -+ kalMemFree(prCmdPscnParam, VIR_MEM_TYPE, sizeof(CMD_SET_PSCAN_PARAM)); -+ return TRUE; -+} -+ -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief handler for Set CMD_ID_SET_PSCN_MAC_ADDR -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN scnFsmSetGSCNConfig(IN P_ADAPTER_T prAdapter, IN P_CMD_GSCN_SCN_COFIG_T prCmdGscnScnConfig) -+{ -+ CMD_GSCN_SCN_COFIG_T rCmdGscnScnConfig; -+ -+ ASSERT(prAdapter); -+ memcpy(&rCmdGscnScnConfig, prCmdGscnScnConfig, sizeof(CMD_GSCN_SCN_COFIG_T)); -+ DBGLOG(SCN, TRACE, "rCmdGscnScnConfig: u4BufferThreshold; [%d] ucNumApPerScn [%d] ucNumScnToCache [%d]\n", -+ rCmdGscnScnConfig.u4BufferThreshold, -+ rCmdGscnScnConfig.ucNumApPerScn, -+ rCmdGscnScnConfig.u4NumScnToCache); -+ -+ scnPSCNFsm(prAdapter, PSCN_RESET, NULL, NULL, NULL, &rCmdGscnScnConfig, FALSE, FALSE, FALSE, FALSE); -+ -+ return TRUE; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief handler for Set CMD_ID_SET_PSCN_MAC_ADDR -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN scnFsmGetGSCNResult(IN P_ADAPTER_T prAdapter, IN P_CMD_GET_GSCAN_RESULT_T prGetGscnScnResultCmd) -+{ -+ CMD_GET_GSCAN_RESULT_T rGetGscnScnResultCmd; -+ P_SCAN_INFO_T prScanInfo; -+ -+ ASSERT(prAdapter); -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ memcpy(&rGetGscnScnResultCmd, prGetGscnScnResultCmd, sizeof(CMD_GET_GSCAN_RESULT_T)); -+ DBGLOG(SCN, INFO, "rGetGscnScnResultCmd: ucGetNum [%d] fgFlush [%d]\n", -+ rGetGscnScnResultCmd.u4Num, rGetGscnScnResultCmd.ucFlush); -+ -+ if (prScanInfo->fgPscnOnnning && prScanInfo->prPscnParam->fgGScnEnable) { -+ wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_GET_GSCN_SCN_RESULT, -+ TRUE, -+ FALSE, -+ FALSE, -+ NULL, -+ NULL, sizeof(CMD_GET_GSCAN_RESULT_T), (PUINT_8) &rGetGscnScnResultCmd, NULL, 0); -+ return TRUE; -+ } -+ /* debug msg, No PSCN, Sched SCAN GSCN ongoing ??? */ -+ return FALSE; -+ -+} -+ -+VOID -+scnPSCNFsm(IN P_ADAPTER_T prAdapter, -+ ENUM_PSCAN_STATE_T eNextPSCNState, -+ IN P_CMD_NLO_REQ prCmdNloReq, -+ IN P_CMD_BATCH_REQ_T prCmdBatchReq, -+ IN P_CMD_GSCN_REQ_T prCmdGscnReq, -+ IN P_CMD_GSCN_SCN_COFIG_T prNewCmdGscnConfig, -+ IN BOOLEAN fgRemoveNLOfromPSCN, -+ IN BOOLEAN fgRemoveBatchSCNfromPSCN, IN BOOLEAN fgRemoveGSCNfromPSCN, IN BOOLEAN fgEnableGSCN) -+{ -+ P_SCAN_INFO_T prScanInfo; -+ BOOLEAN fgTransitionState = FALSE; -+ -+ ASSERT(prAdapter); -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ -+ do { -+ fgTransitionState = FALSE; -+ -+ DBGLOG(SCN, STATE, "eCurrentPSCNState=%d, eNextPSCNState=%d\n", -+ prScanInfo->eCurrentPSCNState, eNextPSCNState); -+ -+ switch (prScanInfo->eCurrentPSCNState) { -+ case PSCN_IDLE: -+ if (eNextPSCNState == PSCN_RESET) { -+ if (fgRemoveNLOfromPSCN || fgRemoveBatchSCNfromPSCN || fgRemoveGSCNfromPSCN) { -+ DBGLOG(SCN, TRACE, "Unexpected remove NLO/BATCH/GSCN request\n"); -+ eNextPSCNState = PSCN_IDLE; -+ break; -+ } -+ -+ if (prCmdNloReq || prCmdBatchReq) { -+ DBGLOG(SCN, TRACE, "PSCN_IDLE->PSCN_RESET,.... scnFsmPSCNActionDISABLE\n"); -+ /*TBD check PSCAN is ongoing */ -+ scnFsmPSCNAction(prAdapter, DISABLE); -+ break; -+ } -+ -+ } else if (eNextPSCNState == PSCN_SCANNING) { -+ if (fgEnableGSCN) { -+ if (prScanInfo->fgPscnOnnning) -+ scnFsmPSCNAction(prAdapter, DISABLE); -+ if (prScanInfo->fgGScnParamSet) { -+ DBGLOG(SCN, TRACE, -+ "PSCN_IDLE->PSCN_SCANNING,.... scnFsmPSCNActionENABLE\n"); -+ prScanInfo->prPscnParam->fgGScnEnable = TRUE; -+ scnFsmPSCNSetParam(prAdapter, -+ (P_CMD_SET_PSCAN_PARAM)prScanInfo->prPscnParam); -+ scnFsmPSCNAction(prAdapter, ENABLE); -+ eNextPSCNState = PSCN_SCANNING; -+ } -+ } -+ } -+ break; -+ -+ case PSCN_RESET: -+ scnCombineParamsIntoPSCN(prAdapter, -+ prCmdNloReq, -+ prCmdBatchReq, -+ prCmdGscnReq, -+ prNewCmdGscnConfig, -+ fgRemoveNLOfromPSCN, fgRemoveBatchSCNfromPSCN, fgRemoveGSCNfromPSCN); -+ -+ if (!prScanInfo->prPscnParam->fgNLOScnEnable && !prScanInfo->prPscnParam->fgBatchScnEnable -+ && !prScanInfo->prPscnParam->fgGScnEnable) { -+ DBGLOG(SCN, TRACE, -+ "PSCN_RESET->PSCN_IDLE,.... fgNLOScnEnable/fgBatchScnEnable/fgGScnEnable false\n"); -+ eNextPSCNState = PSCN_IDLE; -+ } else { -+ if (prScanInfo->prPscnParam->fgNLOScnEnable -+ || prScanInfo->prPscnParam->fgBatchScnEnable) { -+ scnFsmPSCNSetParam(prAdapter, (P_CMD_SET_PSCAN_PARAM) prScanInfo->prPscnParam); -+ scnFsmPSCNAction(prAdapter, ENABLE); -+ eNextPSCNState = PSCN_SCANNING; -+ DBGLOG(SCN, TRACE, -+ "PSCN_RESET->PSCN_SCANNING,.... fgNLOScnEnable/fgBatchScnEnable ENABLE\n"); -+ } -+ } -+ break; -+ -+ case PSCN_SCANNING: -+ if (eNextPSCNState == PSCN_RESET) { -+ if (fgRemoveNLOfromPSCN || fgRemoveBatchSCNfromPSCN || fgRemoveGSCNfromPSCN) { -+ DBGLOG(SCN, TRACE, -+ "PSCN_SCANNING->PSCN_RESET,.... fgRemoveNLOfromPSCN/fgRemoveBatchSCNfromPSCN/fgRemoveGSCNfromPSCN\n"); -+ scnFsmPSCNAction(prAdapter, DISABLE); -+ break; -+ } -+ -+ if (prCmdNloReq || prCmdBatchReq || prCmdGscnReq || prNewCmdGscnConfig) { -+ DBGLOG(SCN, TRACE, -+ "PSCN_SCANNING->PSCN_RESET,.... prCmdNloReq/prCmdBatchReq/prCmdGscnReq/prNewCmdGscnConfig\n"); -+ scnFsmPSCNAction(prAdapter, DISABLE); -+ break; -+ } -+ -+ } else if (eNextPSCNState == PSCN_SCANNING) { -+ if (fgEnableGSCN) { -+ if (prScanInfo->prPscnParam->fgGScnEnable && (!prScanInfo->fgPscnOnnning)) { -+ DBGLOG(SCN, TRACE, -+ "PSCN_SCANNING->PSCN_SCANNING,.... fgGScnEnable/!fgPscnOnnning\n"); -+ /* scnFsmPSCNAction(prAdapter, ENABLE); */ -+ eNextPSCNState = PSCN_SCANNING; -+ } else { -+ -+ DBGLOG(SCN, TRACE, -+ "PSCN_SCANNING->PSCN_SCANNING,.... fgGScnEnable/!fgPscnOnnning\n"); -+ } -+ } -+ } -+ eNextPSCNState = PSCN_SCANNING; -+ break; -+ -+ default: -+ DBGLOG(SCN, WARN, "Unexpected state\n"); -+ ASSERT(0); -+ break; -+ } -+ -+ DBGLOG(SCN, STATE, "eCurrentState %d , eNextPSCNState %d\n", -+ prScanInfo->eCurrentPSCNState, eNextPSCNState); -+ if (prScanInfo->eCurrentPSCNState != eNextPSCNState) -+ fgTransitionState = TRUE; -+ -+ prScanInfo->eCurrentPSCNState = eNextPSCNState; -+ } while (fgTransitionState); -+ -+} -+#endif -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/sec_fsm.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/sec_fsm.c -new file mode 100644 -index 000000000000..29eb8d4e7d92 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/sec_fsm.c -@@ -0,0 +1,1112 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/sec_fsm.c#1 -+*/ -+ -+/*! \file "sec_fsm.c" -+ \brief This is the file implement security check state machine. -+ -+ In security module, do the port control check after success join to an AP, -+ and the path to NORMAL TR, the state machine handle these state transition. -+*/ -+ -+/* -+** Log: sec_fsm.c -+ * -+ * 11 24 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * Adjust code for DBG and CONFIG_XLOG. -+ * -+ * 11 11 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * modify the xlog related code. -+ * -+ * 11 10 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * change the debug module level. -+ * -+ * 11 02 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * adding the code for XLOG. -+ * -+ * 03 29 2011 wh.su -+ * [WCXRP00000248] [MT6620 Wi-Fi][FW]Fixed the Klockwork error -+ * fixed the kclocwork error. -+ * -+ * 01 26 2011 yuche.tsai -+ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record. -+ * . -+ * -+ * 01 25 2011 yuche.tsai -+ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record. -+ * Fix Compile Error when DBG is disabled. -+ * -+ * 01 25 2011 yuche.tsai -+ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record. -+ * Change Station Type in Station Record, Modify MACRO definition for getting station type & network type index & Role. -+ * -+ * 09 29 2010 wh.su -+ * [WCXRP00000072] [MT6620 Wi-Fi][Driver] Fix TKIP Counter Measure EAPoL callback register issue -+ * [MT6620 Wi-Fi][Driver] Fix TKIP Counter Measure EAPoL callback register issue. -+ * -+ * 09 24 2010 wh.su -+ * NULL -+ * [WCXRP00005002][MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning. -+ * -+ * 09 03 2010 kevin.huang -+ * NULL -+ * Refine #include sequence and solve recursive/nested #include issue -+ * -+ * 08 20 2010 wh.su -+ * NULL -+ * adding the eapol callback setting. -+ * -+ * 08 19 2010 wh.su -+ * NULL -+ * adding the tx pkt call back handle for countermeasure. -+ * -+ * 07 19 2010 wh.su -+ * -+ * fixed the compilng error at debug mode. -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 21 2010 wh.su -+ * [WPD00003840][MT6620 5931] Security migration -+ * modify some code for concurrent network. -+ * -+ * 06 19 2010 wh.su -+ * [WPD00003840][MT6620 5931] Security migration -+ * consdier the concurrent network setting. -+ * -+ * 05 28 2010 wh.su -+ * [BORA00000626][MT6620] Refine the remove key flow for WHQL testing -+ * fixed the ad-hoc wpa-none send non-encrypted frame issue. -+ * -+ * 05 24 2010 kevin.huang -+ * [BORA00000794][WIFISYS][New Feature]Power Management Support -+ * Refine authSendAuthFrame() for NULL STA_RECORD_T case and minimum deauth interval. -+ * -+ * 04 24 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * g_aprBssInfo[] depends on CFG_SUPPORT_P2P and CFG_SUPPORT_BOW -+ * -+ * 04 13 2010 wh.su -+ * [BORA00000680][MT6620] Support the statistic for Micxxsoft os query -+ * fixed the Klocwork error and refine the class error message. -+ * -+ * 03 03 2010 wh.su -+ * [BORA00000637][MT6620 Wi-Fi] [Bug] WPA2 pre-authentication timer not correctly initialize -+ * move the AIS specific variable for security to AIS specific structure. -+ * -+ * 03 03 2010 wh.su -+ * [BORA00000637][MT6620 Wi-Fi] [Bug] WPA2 pre-authentication timer not correctly initialize -+ * Fixed the pre-authentication timer not correctly init issue, -+ * and modify the security related callback function prototype. -+ * -+ * 03 01 2010 wh.su -+ * [BORA00000605][WIFISYS] Phase3 Integration -+ * Refine the variable and parameter for security. -+ * -+ * 01 27 2010 wh.su -+ * [BORA00000476][Wi-Fi][firmware] Add the security module initialize code -+ * add and fixed some security function. -+ * -+ * 01 13 2010 wh.su -+ * [BORA00000476][Wi-Fi][firmware] Add the security module initialize code -+ * fixed the compiling warning -+ * -+ * 12 18 2009 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * . -+ * -+ * Dec 7 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * refine some code -+ * -+ * Dec 4 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * refine the code -+ * -+ * Dec 1 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * code refine -+ * -+ * Nov 23 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * adjust the function name -+ * -+ * Nov 19 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * adjust the state machine, to meet the firmware security design v1.1 -+ * -+ * Nov 18 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * -+** -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "precomp.h" -+ -+#if CFG_RSN_MIGRATION -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+#if DBG -+/*lint -save -e64 Type mismatch */ -+static PUINT_8 apucDebugSecState[SEC_STATE_NUM] = { -+ (PUINT_8) DISP_STRING("SEC_STATE_INIT"), -+ (PUINT_8) DISP_STRING("SEC_STATE_INITIATOR_PORT_BLOCKED"), -+ (PUINT_8) DISP_STRING("SEC_STATE_RESPONDER_PORT_BLOCKED"), -+ (PUINT_8) DISP_STRING("SEC_STATE_CHECK_OK"), -+ (PUINT_8) DISP_STRING("SEC_STATE_SEND_EAPOL"), -+ (PUINT_8) DISP_STRING("SEC_STATE_SEND_DEAUTH"), -+ (PUINT_8) DISP_STRING("SEC_STATE_COUNTERMEASURE"), -+}; -+ -+/*lint -restore */ -+#endif /* DBG */ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will do initialization of Security FSM and all variables in -+* SEC_INFO_T. -+* -+* \param[in] prSta Pointer to the STA record -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID secFsmInit(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta) -+{ -+ P_SEC_INFO_T prSecInfo; -+ P_AIS_SPECIFIC_BSS_INFO_T prAisSpecBssInfo; -+ -+ ASSERT(prSta); -+ -+ prSecInfo = &prSta->rSecInfo; -+ -+#if 1 /* MT6620 */ -+ /* At MT5921, is ok, but at MT6620, firmware base ASIC, the firmware */ -+ /* will lost these data, thus, driver have to keep the wep material and */ -+ /* setting to firmware while awake from D3. */ -+#endif -+ -+ prSecInfo->eCurrentState = SEC_STATE_INIT; -+ -+ prSecInfo->fg2nd1xSend = FALSE; -+ prSecInfo->fgKeyStored = FALSE; -+ -+ if (IS_STA_IN_AIS(prSta)) { -+ prAisSpecBssInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo; -+ -+ prAisSpecBssInfo->u4RsnaLastMICFailTime = 0; -+ prAisSpecBssInfo->fgCheckEAPoLTxDone = FALSE; -+ -+ cnmTimerInitTimer(prAdapter, -+ &prAdapter->rWifiVar.rAisSpecificBssInfo.rRsnaEAPoLReportTimeoutTimer, -+ (PFN_MGMT_TIMEOUT_FUNC) secFsmEventEapolTxTimeout, (ULONG) prSta); -+ -+ cnmTimerInitTimer(prAdapter, -+ &prAdapter->rWifiVar.rAisSpecificBssInfo.rRsnaBlockTrafficTimer, -+ (PFN_MGMT_TIMEOUT_FUNC) secFsmEventEndOfCounterMeasure, (ULONG) prSta); -+ -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will do uninitialization of Security FSM and all variables in -+* SEC_INFO_T. -+* -+* \param[in] prSta Pointer to the STA record -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID /* whsu:Todo: */ -+secFsmUnInit(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta) -+{ -+ P_SEC_INFO_T prSecInfo; -+ -+ ASSERT(prSta); -+ -+ prSecInfo = &prSta->rSecInfo; -+ -+ prSecInfo->fg2nd1xSend = FALSE; -+ prSecInfo->fgKeyStored = FALSE; -+ -+ /* nicPrivacyRemoveWlanTable(prSta->ucWTEntry); */ -+ -+ if (IS_STA_IN_AIS(prSta)) { -+ cnmTimerStopTimer(prAdapter, &prAdapter->rWifiVar.rAisSpecificBssInfo.rRsnaEAPoLReportTimeoutTimer); -+ cnmTimerStopTimer(prAdapter, &prAdapter->rWifiVar.rAisSpecificBssInfo.rRsnaBlockTrafficTimer); -+ } -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will do action part while in STATE transition of -+* STANDBY to CHECK_OK. -+* -+* \param[in] prSta Pointer to the Sta record -+* -+* \return - none -+*/ -+/*----------------------------------------------------------------------------*/ -+static inline VOID secFsmTrans_INIT_to_CHECK_OK(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta) -+{ -+ secSetPortBlocked(prAdapter, prSta, FALSE); -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will do action part while in STATE transition of -+* INIT to INITIATOR_PORT_BLOCKED. -+* -+* \param[in] prSta Pointer to the Sta record -+* -+* \return - none -+*/ -+/*----------------------------------------------------------------------------*/ -+static inline VOID secFsmTrans_INIT_to_INITIATOR_PORT_BLOCKED(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta) -+{ -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will do action part while in STATE transition of -+* INIT to RESPONDER_PORT_BLOCKED. -+* -+* \param[in] prSta Pointer to the Sta record -+* -+* \return - none -+*/ -+/*----------------------------------------------------------------------------*/ -+static inline VOID secFsmTrans_INIT_to_RESPONDER_PORT_BLOCKED(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta) -+{ -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will do action part while in STATE transition of -+* INITIATOR_PORT_BLOCKED to CHECK_OK. -+* -+* \param[in] prSta Pointer to the Sta record -+* -+* \return - none -+*/ -+/*----------------------------------------------------------------------------*/ -+static inline VOID secFsmTrans_INITIATOR_PORT_BLOCKED_to_CHECK_OK(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta) -+{ -+ secSetPortBlocked(prAdapter, prSta, FALSE); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will do action part while in STATE transition of -+* RESPONDER_PORT_BLOCKED to CHECK_OK. -+* -+* \param[in] prSta Pointer to the Sta record -+* -+* \return - none -+*/ -+/*----------------------------------------------------------------------------*/ -+static inline VOID secFsmTrans_RESPONDER_PORT_BLOCKED_to_CHECK_OK(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta) -+{ -+ secSetPortBlocked(prAdapter, prSta, FALSE); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will do action part while in STATE transition of -+* CHECK_OK to SEND_EAPOL -+* -+* \param[in] prSta Pointer to the Sta record -+* -+* \return - -+*/ -+/*----------------------------------------------------------------------------*/ -+static inline VOID secFsmTrans_CHECK_OK_to_SEND_EAPOL(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta) -+{ -+ -+ P_AIS_SPECIFIC_BSS_INFO_T prAisBssInfo; -+ -+ ASSERT(prAdapter); -+ -+ ASSERT(prSta); -+ -+ prAisBssInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo; -+ -+ ASSERT(prAisBssInfo); -+ -+ if (!IS_STA_IN_AIS(prSta)) { -+ DBGLOG(RSN, INFO, "Counter Measure should occur at AIS network!!\n"); -+ /* ASSERT(0); */ -+ return; -+ } -+ -+ prAisBssInfo->fgCheckEAPoLTxDone = TRUE; -+ -+ /* cnmTimerStartTimer(prAdapter, */ -+ /* &prAisBssInfo->rRsnaEAPoLReportTimeoutTimer, */ -+ /* SEC_TO_MSEC(EAPOL_REPORT_SEND_TIMEOUT_INTERVAL_SEC)); */ -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will do action part while in STATE transition of -+* SEND_EAPOL to SEND_DEAUTH. -+* -+* \param[in] prSta Pointer to the Sta record -+* -+* \return - none -+*/ -+/*----------------------------------------------------------------------------*/ -+static inline VOID secFsmTrans_SEND_EAPOL_to_SEND_DEAUTH(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta) -+{ -+ -+ if (!IS_STA_IN_AIS(prSta)) { -+ DBGLOG(RSN, INFO, "Counter Measure should occur at AIS network!!\n"); -+ /* ASSERT(0); */ -+ return; -+ } -+ -+ /* Compose deauth frame to AP, a call back function for tx done */ -+ if (authSendDeauthFrame(prAdapter, -+ prSta, -+ (P_SW_RFB_T) NULL, -+ REASON_CODE_MIC_FAILURE, -+ (PFN_TX_DONE_HANDLER) secFsmEventDeauthTxDone) != WLAN_STATUS_SUCCESS) { -+ ASSERT(FALSE); -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will do action part while in STATE transition of -+* SEND_DEAUTH to COUNTERMEASURE. -+* -+* \param[in] prSta Pointer to the Sta record -+* -+* \return - -+*/ -+/*----------------------------------------------------------------------------*/ -+static inline VOID secFsmTrans_SEND_DEAUTH_to_COUNTERMEASURE(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta) -+{ -+ ASSERT(prAdapter); -+ ASSERT(prSta); -+ -+ if (!IS_STA_IN_AIS(prSta)) { -+ DBGLOG(RSN, INFO, "Counter Measure should occur at AIS network!!\n"); -+ /* ASSERT(0); */ -+ return; -+ } -+ /* Start the 60 sec timer */ -+ cnmTimerStartTimer(prAdapter, -+ &prAdapter->rWifiVar.rAisSpecificBssInfo.rRsnaBlockTrafficTimer, -+ SEC_TO_MSEC(COUNTER_MEASURE_TIMEOUT_INTERVAL_SEC)); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will do action part while in STATE transition of -+* SEND_DEAUTH to COUNTERMEASURE. -+* -+* \param[in] prSta Pointer to the Sta record -+* -+* \return - -+*/ -+/*----------------------------------------------------------------------------*/ -+static inline VOID secFsmTrans_COUNTERMEASURE_to_INIT(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta) -+{ -+ -+ /* Clear the counter measure flag */ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief The Core FSM engine of security module. -+* -+* \param[in] prSta Pointer to the Sta record -+* \param[in] eNextState Enum value of next sec STATE -+* -+* \return - -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID secFsmSteps(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta, IN ENUM_SEC_STATE_T eNextState) -+{ -+ P_SEC_INFO_T prSecInfo; -+ BOOLEAN fgIsTransition = (BOOLEAN) FALSE; -+ -+ ASSERT(prSta); -+ -+ prSecInfo = &prSta->rSecInfo; -+ ASSERT(prSecInfo); -+ -+ DEBUGFUNC("secFsmSteps"); -+ do { -+ /* Do entering Next State */ -+ prSecInfo->ePreviousState = prSecInfo->eCurrentState; -+ -+ /* Do entering Next State */ -+#if DBG -+ DBGLOG(RSN, STATE, "\n %pM TRANSITION: [%s] -> [%s]\n\n", -+ prSta->aucMacAddr, -+ apucDebugSecState[prSecInfo->eCurrentState], apucDebugSecState[eNextState]); -+#else -+ DBGLOG(RSN, STATE, "\n %pM [%d] TRANSITION: [%d] -> [%d]\n\n", -+ prSta->aucMacAddr, DBG_RSN_IDX, prSecInfo->eCurrentState, eNextState); -+#endif -+ prSecInfo->eCurrentState = eNextState; -+ -+ fgIsTransition = (BOOLEAN) FALSE; -+#if 0 -+ /* Do tasks of the State that we just entered */ -+ switch (prSecInfo->eCurrentState) { -+ case SEC_STATE_INIT: -+ break; -+ case SEC_STATE_INITIATOR_PORT_BLOCKED: -+ break; -+ case SEC_STATE_RESPONDER_PORT_BLOCKED: -+ break; -+ case SEC_STATE_CHECK_OK: -+ break; -+ case SEC_STATE_SEND_EAPOL: -+ break; -+ case SEC_STATE_SEND_DEAUTH: -+ break; -+ case SEC_STATE_COUNTERMEASURE: -+ break; -+ default: -+ ASSERT(0); /* Make sure we have handle all STATEs */ -+ break; -+ } -+#endif -+ } while (fgIsTransition); -+ -+ return; -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will do initialization of Security FSM and all variables in -+* SEC_INFO_T. -+* -+* \param[in] prSta Pointer to the Sta record -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID secFsmEventStart(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta) -+{ -+ P_SEC_INFO_T prSecInfo; -+ BOOLEAN fgIsTransition = (BOOLEAN) FALSE; -+ ENUM_SEC_STATE_T eNextState; -+ -+ DBGLOG(RSN, TRACE, "secFsmRunEventStart\n"); -+ -+ ASSERT(prSta); -+ -+ if (!prSta) -+ return; -+ -+ if (!IS_STA_IN_AIS(prSta)) -+ return; -+ -+ DBGLOG(RSN, TRACE, "secFsmRunEventStart for sta %pM network %d\n", -+ prSta->aucMacAddr, prSta->ucNetTypeIndex); -+ -+ prSecInfo = (P_SEC_INFO_T) &prSta->rSecInfo; -+ -+ eNextState = prSecInfo->eCurrentState; -+ -+ secSetPortBlocked(prAdapter, prSta, TRUE); -+ -+ /* prSta->fgTransmitKeyExist = FALSE; */ -+ /* whsu:: nicPrivacySetStaDefaultWTIdx(prSta); */ -+ -+#if 1 /* Since the 1x and key can set to firmware in order, always enter the check ok state */ -+ SEC_STATE_TRANSITION(prAdapter, prSta, INIT, CHECK_OK); -+#else -+ if (IS_STA_IN_AIS(prSta->eStaType)) { -+ if (secRsnKeyHandshakeEnabled(prAdapter) == TRUE -+#if CFG_SUPPORT_WAPI -+ || (prAdapter->rWifiVar.rConnSettings.fgWapiMode) -+#endif -+ ) { -+ prSta->fgTransmitKeyExist = FALSE; -+ /* nicPrivacyInitialize(prSta->ucNetTypeIndex); */ -+ SEC_STATE_TRANSITION(prAdapter, prSta, INIT, INITIATOR_PORT_BLOCKED); -+ } else { -+ SEC_STATE_TRANSITION(prAdapter, prSta, INIT, CHECK_OK); -+ } -+ } -+#if CFG_ENABLE_WIFI_DIRECT || CFG_ENABLE_BT_OVER_WIFI -+#if CFG_ENABLE_WIFI_DIRECT && CFG_ENABLE_BT_OVER_WIFI -+ else if ((prSta->eStaType == STA_TYPE_BOW_CLIENT) || (prSta->eStaType == STA_TYPE_P2P_GC)) { -+#elif CFG_ENABLE_WIFI_DIRECT -+ else if (prSta->eStaType == STA_TYPE_P2P_GC) { -+#elif CFG_ENABLE_BT_OVER_WIFI -+ else if (prSta->eStaType == STA_TYPE_BOW_CLIENT) { -+#endif -+ SEC_STATE_TRANSITION(prAdapter, prSta, INIT, RESPONDER_PORT_BLOCKED); -+ } -+#endif -+ else -+ SEC_STATE_TRANSITION(prAdapter, prSta, INIT, INITIATOR_PORT_BLOCKED); -+#endif -+ if (prSecInfo->eCurrentState != eNextState) -+ secFsmSteps(prAdapter, prSta, eNextState); -+ -+} /* secFsmRunEventStart */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function called by reset procedure to force the sec fsm enter -+* idle state -+* -+* \param[in] ucNetTypeIdx The Specific Network type index -+* \param[in] prSta Pointer to the Sta record -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID secFsmEventAbort(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta) -+{ -+ P_SEC_INFO_T prSecInfo; -+ -+ DBGLOG(RSN, TRACE, "secFsmEventAbort for sta %pM network %d\n", -+ prSta->aucMacAddr, prSta->ucNetTypeIndex); -+ -+ ASSERT(prSta); -+ -+ if (!prSta) -+ return; -+ -+ if (!IS_STA_IN_AIS(prSta)) -+ return; -+ -+ prSecInfo = (P_SEC_INFO_T) &prSta->rSecInfo; -+ -+ prSta->fgTransmitKeyExist = FALSE; -+ -+ secSetPortBlocked(prAdapter, prSta, TRUE); -+ -+ if (prSecInfo == NULL) -+ return; -+ -+ if (IS_STA_IN_AIS(prSta)) { -+ -+ prAdapter->rWifiVar.rAisSpecificBssInfo.fgTransmitKeyExist = FALSE; -+ -+ if (prSecInfo->eCurrentState == SEC_STATE_SEND_EAPOL) { -+ if (prAdapter->rWifiVar.rAisSpecificBssInfo.fgCheckEAPoLTxDone == FALSE) { -+ DBGLOG(RSN, TRACE, "EAPOL STATE not match the flag\n"); -+ /* cnmTimerStopTimer(prAdapter, &prAdapter->rWifiVar. -+ * rAisSpecificBssInfo.rRsnaEAPoLReportTimeoutTimer); */ -+ } -+ } -+ } -+ prSecInfo->eCurrentState = SEC_STATE_INIT; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will indicate an Event of "2nd EAPoL Tx is sending" to Sec FSM. -+* -+* \param[in] prSta Pointer to the Sta record -+* -+* \return - -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID secFsmEvent2ndEapolTx(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta) -+{ -+ P_SEC_INFO_T prSecInfo; -+ ENUM_SEC_STATE_T eNextState; -+ /* BOOLEAN fgIsTransition = (BOOLEAN)FALSE; */ -+ -+ DEBUGFUNC("secFsmRunEvent2ndEapolTx"); -+ -+ ASSERT(prSta); -+ -+ prSecInfo = &prSta->rSecInfo; -+ eNextState = prSecInfo->eCurrentState; -+ -+#if DBG -+ DBGLOG(RSN, TRACE, "%pM Sec state %s\n", prSta->aucMacAddr, -+ apucDebugSecState[prSecInfo->eCurrentState]); -+#else -+ DBGLOG(RSN, TRACE, "%pM Sec state [%d]\n", prSta->aucMacAddr, prSecInfo->eCurrentState); -+#endif -+ -+ switch (prSecInfo->eCurrentState) { -+ case SEC_STATE_INITIATOR_PORT_BLOCKED: -+ case SEC_STATE_CHECK_OK: -+ prSecInfo->fg2nd1xSend = TRUE; -+ break; -+ default: -+#if DBG -+ DBGLOG(RSN, WARN, "Rcv 2nd EAPoL at %s\n", apucDebugSecState[prSecInfo->eCurrentState]); -+#else -+ DBGLOG(RSN, WARN, "Rcv 2nd EAPoL at [%d]\n", prSecInfo->eCurrentState); -+#endif -+ break; -+ } -+ -+ if (prSecInfo->eCurrentState != eNextState) -+ secFsmSteps(prAdapter, prSta, eNextState); -+ -+ return; -+ -+} /* secFsmRunEvent2ndEapolTx */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will indicate an Event of "4th EAPoL Tx is Tx done" to Sec FSM. -+* -+* \param[in] prSta Pointer to the Sta record -+* -+* \return - -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID secFsmEvent4ndEapolTxDone(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta) -+{ -+ P_SEC_INFO_T prSecInfo; -+ ENUM_SEC_STATE_T eNextState; -+ BOOLEAN fgIsTransition = (BOOLEAN) FALSE; -+ P_CMD_802_11_KEY prStoredKey; -+ -+ DEBUGFUNC("secFsmRunEvent4ndEapolTx"); -+ -+ ASSERT(prSta); -+ -+ prSecInfo = &prSta->rSecInfo; -+ eNextState = prSecInfo->eCurrentState; -+ -+#if DBG -+ DBGLOG(RSN, TRACE, "%pM Sec state %s\n", prSta->aucMacAddr, -+ apucDebugSecState[prSecInfo->eCurrentState]); -+#else -+ DBGLOG(RSN, TRACE, "%pM Sec state [%d]\n", prSta->aucMacAddr, prSecInfo->eCurrentState); -+#endif -+ -+ switch (prSecInfo->eCurrentState) { -+ case SEC_STATE_INITIATOR_PORT_BLOCKED: -+ case SEC_STATE_CHECK_OK: -+ prSecInfo->fg2nd1xSend = FALSE; -+ if (prSecInfo->fgKeyStored) { -+ prStoredKey = (P_CMD_802_11_KEY) prSecInfo->aucStoredKey; -+ -+ /* prSta = rxmLookupStaRecIndexFromTA(prStoredKey->aucPeerAddr); */ -+ /* if (nicPrivacySetKeyEntry(prStoredKey, prSta->ucWTEntry) == FALSE) */ -+ /* DBGLOG(RSN, WARN, ("nicPrivacySetKeyEntry() fail,..\n")); */ -+ -+ /* key update */ -+ prSecInfo->fgKeyStored = FALSE; -+ prSta->fgTransmitKeyExist = TRUE; -+ } -+ if (prSecInfo->eCurrentState == SEC_STATE_INITIATOR_PORT_BLOCKED) -+ SEC_STATE_TRANSITION(prAdapter, prSta, INITIATOR_PORT_BLOCKED, CHECK_OK); -+ break; -+ default: -+ -+#if DBG -+ DBGLOG(RSN, WARN, "Rcv thh EAPoL Tx done at %s\n", apucDebugSecState[prSecInfo->eCurrentState]); -+#else -+ DBGLOG(RSN, WARN, "Rcv thh EAPoL Tx done at [%d]\n", prSecInfo->eCurrentState); -+#endif -+ break; -+ } -+ -+ if (prSecInfo->eCurrentState != eNextState) -+ secFsmSteps(prAdapter, prSta, eNextState); -+ -+ return; -+ -+} /* secFsmRunEvent4ndEapolTx */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will indicate an Event of "Pairwise key installed" to SEC FSM. -+* -+* \param[in] prSta Pointer to the Sta record -+* -+* \retval TRUE The key can be installed to HW -+* \retval FALSE The kay conflict with the current key, abort it -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN secFsmEventPTKInstalled(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta) -+{ -+ P_SEC_INFO_T prSecInfo; -+ ENUM_SEC_STATE_T eNextState; -+ BOOLEAN fgStatus = TRUE; -+ BOOLEAN fgIsTransition = (BOOLEAN) FALSE; -+ -+ ASSERT(prSta); -+ -+ prSecInfo = &prSta->rSecInfo; -+ if (prSecInfo == NULL) -+ return TRUE; /* Not PTK */ -+ -+#if DBG -+ DBGLOG(RSN, TRACE, "%pM Sec state %s\n", prSta->aucMacAdd), -+ apucDebugSecState[prSecInfo->eCurrentState]); -+#else -+ DBGLOG(RSN, TRACE, "%pM Sec state [%d]\n", prSta->aucMacAddr, prSecInfo->eCurrentState); -+#endif -+ -+ eNextState = prSecInfo->eCurrentState; -+ -+ switch (prSecInfo->eCurrentState) { -+ case SEC_STATE_INIT: -+ /* Legacy wep, wpa-none */ -+ break; -+ -+ case SEC_STATE_INITIATOR_PORT_BLOCKED: -+ if (prSecInfo->fg2nd1xSend) -+ ; -+ else -+ SEC_STATE_TRANSITION(prAdapter, prSta, INITIATOR_PORT_BLOCKED, CHECK_OK); -+ break; -+ -+ case SEC_STATE_RESPONDER_PORT_BLOCKED: -+ SEC_STATE_TRANSITION(prAdapter, prSta, RESPONDER_PORT_BLOCKED, CHECK_OK); -+ break; -+ -+ case SEC_STATE_CHECK_OK: -+ break; -+ -+ default: -+ fgStatus = FALSE; -+ break; -+ } -+ -+ if (prSecInfo->eCurrentState != eNextState) -+ secFsmSteps(prAdapter, prSta, eNextState); -+ -+ return fgStatus; -+ -+} /* end of secFsmRunEventPTKInstalled() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will indicate an Event of "Counter Measure" to SEC FSM. -+* -+* \param[in] prSta Pointer to the Sta record -+* -+* \return - -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID secFsmEventStartCounterMeasure(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta) -+{ -+ P_SEC_INFO_T prSecInfo; -+ ENUM_SEC_STATE_T eNextState; -+ BOOLEAN fgIsTransition = (BOOLEAN) FALSE; -+ -+ DEBUGFUNC("secFsmRunEventStartCounterMeasure"); -+ -+ ASSERT(prSta); -+ -+ if (!IS_STA_IN_AIS(prSta)) { -+ DBGLOG(RSN, INFO, "Counter Measure should occur at AIS network!!\n"); -+ /* ASSERT(0); */ -+ return; -+ } -+ -+ prSecInfo = &prSta->rSecInfo; -+ -+ eNextState = prSecInfo->eCurrentState; -+ -+#if DBG -+ DBGLOG(RSN, TRACE, "%pM Sec state %s\n", prSta->aucMacAddr, -+ apucDebugSecState[prSecInfo->eCurrentState]); -+#else -+ DBGLOG(RSN, TRACE, "%pM Sec state [%d]\n", prSta->aucMacAddr, prSecInfo->eCurrentState); -+#endif -+ -+ prAdapter->rWifiVar.rAisSpecificBssInfo.u4RsnaLastMICFailTime = 0; -+ -+ switch (prSecInfo->eCurrentState) { -+ case SEC_STATE_CHECK_OK: -+ { -+ prAdapter->rWifiVar.rAisSpecificBssInfo.fgCounterMeasure = TRUE; -+ -+ /* dls port control */ -+ SEC_STATE_TRANSITION(prAdapter, prSta, CHECK_OK, SEND_EAPOL); -+ } -+ break; -+ -+ default: -+ break; -+ } -+ -+ /* Call arbFsmSteps() when we are going to change ARB STATE */ -+ if (prSecInfo->eCurrentState != eNextState) -+ secFsmSteps(prAdapter, prSta, eNextState); -+ -+ return; -+ -+} /* secFsmRunEventStartCounterMeasure */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will indicate an Event of "802.1x EAPoL Tx Done" to Sec FSM. -+* -+* \param[in] prSta Pointer to the Sta record -+* -+* \return - -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+secFsmEventEapolTxDone(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus) -+{ -+ P_SEC_INFO_T prSecInfo; -+ ENUM_SEC_STATE_T eNextState; -+ BOOLEAN fgIsTransition = (BOOLEAN) FALSE; -+ P_AIS_SPECIFIC_BSS_INFO_T prAisBssInfo; -+ -+ DEBUGFUNC("secFsmRunEventEapolTxDone"); -+ -+ ASSERT(prStaRec); -+ -+ if (rTxDoneStatus != TX_RESULT_SUCCESS) { -+ DBGLOG(RSN, INFO, "Error EAPoL fram fail to send!!\n"); -+ /* ASSERT(0); */ -+ return; -+ } -+ -+ if (!IS_STA_IN_AIS(prStaRec)) { -+ DBGLOG(RSN, INFO, "Counter Measure should occur at AIS network!!\n"); -+ /* ASSERT(0); */ -+ return; -+ } -+ -+ prAisBssInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo; -+ -+ ASSERT(prAisBssInfo); -+ -+ prSecInfo = &prStaRec->rSecInfo; -+ eNextState = prSecInfo->eCurrentState; -+ -+#if DBG -+ DBGLOG(RSN, TRACE, "%pM Sec state %s\n", prStaRec->aucMacAddr, -+ apucDebugSecState[prSecInfo->eCurrentState]); -+#else -+ DBGLOG(RSN, TRACE, "%pM Sec state [%d]\n", prStaRec->aucMacAddr, prSecInfo->eCurrentState); -+#endif -+ -+ switch (prSecInfo->eCurrentState) { -+ case SEC_STATE_SEND_EAPOL: -+ if (prAisBssInfo->fgCheckEAPoLTxDone == FALSE) -+ ASSERT(0); -+ -+ prAisBssInfo->fgCheckEAPoLTxDone = FALSE; -+ /* cnmTimerStopTimer(prAdapter, &prAisBssInfo->rRsnaEAPoLReportTimeoutTimer); */ -+ -+ SEC_STATE_TRANSITION(prAdapter, prStaRec, SEND_EAPOL, SEND_DEAUTH); -+ break; -+ default: -+ break; -+ } -+ -+ if (prSecInfo->eCurrentState != eNextState) -+ secFsmSteps(prAdapter, prStaRec, eNextState); -+ -+ return; -+ -+} /* secFsmRunEventEapolTxDone */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will indicate an Event of "Deauth frame Tx Done" to Sec FSM. -+* -+* \param[in] pMsduInfo Pointer to the Msdu Info -+* \param[in] rStatus The Tx done status -+* -+* \return - -+* -+* \note after receive deauth frame, callback function call this -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+secFsmEventDeauthTxDone(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus) -+{ -+ P_STA_RECORD_T prStaRec; -+ P_SEC_INFO_T prSecInfo; -+ ENUM_SEC_STATE_T eNextState; -+ BOOLEAN fgIsTransition = (BOOLEAN) FALSE; -+ -+ DEBUGFUNC("secFsmRunEventDeauthTxDone"); -+ -+ ASSERT(prMsduInfo); -+ -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); -+ -+ ASSERT(prStaRec); -+ -+ if (!prStaRec) -+ return; -+ -+ if (!IS_STA_IN_AIS(prStaRec)) { -+ DBGLOG(RSN, INFO, "Counter Measure should occur at AIS network!!\n"); -+ /* ASSERT(0); */ -+ return; -+ } -+ -+ prSecInfo = (P_SEC_INFO_T) &prStaRec->rSecInfo; -+ -+#if DBG -+ DBGLOG(RSN, TRACE, "%pM Sec state %s\n", prStaRec->aucMacAddr, -+ apucDebugSecState[prSecInfo->eCurrentState]); -+#else -+ DBGLOG(RSN, TRACE, "%pM Sec state [%d]\n", prStaRec->aucMacAddr, prSecInfo->eCurrentState); -+#endif -+ -+ switch (prSecInfo->eCurrentState) { -+ case SEC_STATE_SEND_DEAUTH: -+ -+ DBGLOG(RSN, TRACE, "Set timer %d\n", COUNTER_MEASURE_TIMEOUT_INTERVAL_SEC); -+ -+ SEC_STATE_TRANSITION(prAdapter, prStaRec, SEND_DEAUTH, COUNTERMEASURE); -+ -+ break; -+ -+ default: -+ ASSERT(0); -+ break; -+ } -+ -+} /* secFsmRunEventDeauthTxDone */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will check the eapol error frame fail to send issue. -+* -+* \param[in] prSta Pointer to the Sta record -+* -+* \return - -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID secFsmEventEapolTxTimeout(IN P_ADAPTER_T prAdapter, IN ULONG ulParm) -+{ -+ P_STA_RECORD_T prStaRec; -+ -+ DEBUGFUNC("secFsmRunEventEapolTxTimeout"); -+ -+ prStaRec = (P_STA_RECORD_T) ulParm; -+ -+ ASSERT(prStaRec); -+ -+ /* Todo:: How to handle the Eapol Error fail to send case? */ -+ ASSERT(0); -+ -+ return; -+ -+} /* secFsmEventEapolTxTimeout */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will stop the counterMeasure duration. -+* -+* \param[in] prSta Pointer to the Sta record -+* -+* \return - -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID secFsmEventEndOfCounterMeasure(IN P_ADAPTER_T prAdapter, ULONG ulParm) -+{ -+ P_STA_RECORD_T prSta; -+ P_SEC_INFO_T prSecInfo; -+ ENUM_SEC_STATE_T eNextState; -+ BOOLEAN fgIsTransition = (BOOLEAN) FALSE; -+ -+ DEBUGFUNC("secFsmRunEventEndOfCounterMeasure"); -+ -+ prSta = (P_STA_RECORD_T) ulParm; -+ -+ ASSERT(prSta); -+ -+ if (!IS_STA_IN_AIS(prSta)) { -+ DBGLOG(RSN, INFO, "Counter Measure should occur at AIS network!!\n"); -+ /* ASSERT(0); */ -+ return; -+ } -+ -+ prSecInfo = &prSta->rSecInfo; -+ eNextState = prSecInfo->eCurrentState; -+ -+#if DBG -+ DBGLOG(RSN, TRACE, "%pM Sec state %s\n", prSta->aucMacAddr, -+ apucDebugSecState[prSecInfo->eCurrentState]); -+#else -+ DBGLOG(RSN, TRACE, "%pM Sec state [%d]\n", prSta->aucMacAddr, prSecInfo->eCurrentState); -+#endif -+ -+ switch (prSecInfo->eCurrentState) { -+ case SEC_STATE_SEND_DEAUTH: -+ { -+ prAdapter->rWifiVar.rAisSpecificBssInfo.fgCounterMeasure = FALSE; -+ -+ SEC_STATE_TRANSITION(prAdapter, prSta, COUNTERMEASURE, INIT); -+ } -+ break; -+ -+ default: -+ ASSERT(0); -+ } -+ -+ /* Call arbFsmSteps() when we are going to change ARB STATE */ -+ if (prSecInfo->eCurrentState != eNextState) -+ secFsmSteps(prAdapter, prSta, eNextState); -+ -+} /* end of secFsmRunEventEndOfCounterMeasure */ -+#endif -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/stats.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/stats.c -new file mode 100644 -index 000000000000..ab3fcc028375 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/stats.c -@@ -0,0 +1,1342 @@ -+/* -+** Id: stats.c#1 -+*/ -+ -+/*! \file stats.c -+ \brief This file includes statistics support. -+*/ -+ -+/* -+** Log: stats.c -+ * -+ * 07 17 2014 samp.lin -+ * NULL -+ * Initial version. -+ */ -+ -+/******************************************************************************* -+ * C O M P I L E R F L A G S -+ ******************************************************************************** -+ */ -+ -+/******************************************************************************* -+ * E X T E R N A L R E F E R E N C E S -+ ******************************************************************************** -+ */ -+#include "precomp.h" -+ -+enum EVENT_TYPE { -+ EVENT_RX, -+ EVENT_TX, -+ EVENT_TX_DONE -+}; -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+static void statsInfoEnvDisplay(GLUE_INFO_T *prGlueInfo, UINT8 *prInBuf, UINT32 u4InBufLen); -+ -+static WLAN_STATUS -+statsInfoEnvRequest(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen); -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+UINT_64 u8DrvOwnStart, u8DrvOwnEnd; -+UINT32 u4DrvOwnMax = 0; -+#define CFG_USER_LOAD 0 -+static UINT_16 su2TxDoneCfg = CFG_DHCP | CFG_ICMP | CFG_EAPOL; -+/******************************************************************************* -+* P R I V A T E F U N C T I O N S -+******************************************************************************** -+*/ -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to display all environment log. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prInBuf A pointer to the command string buffer, from u4EventSubId -+* \param[in] u4InBufLen The length of the buffer -+* \param[out] None -+* -+* \retval None -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static void statsInfoEnvDisplay(GLUE_INFO_T *prGlueInfo, UINT8 *prInBuf, UINT32 u4InBufLen) -+{ -+ P_ADAPTER_T prAdapter; -+ STA_RECORD_T *prStaRec; -+ UINT32 u4NumOfInfo, u4InfoId; -+ UINT32 u4RxErrBitmap; -+ STATS_INFO_ENV_T *prInfo; -+ UINT32 u4Total, u4RateId; -+ -+/* -+[wlan] statsInfoEnvRequest: (INIT INFO) statsInfoEnvRequest cmd ok. -+[wlan] statsEventHandle: (INIT INFO) statsEventHandle: Rcv a event -+[wlan] statsEventHandle: (INIT INFO) statsEventHandle: Rcv a event: 0 -+[wlan] statsInfoEnvDisplay: (INIT INFO) Display stats for [00:0c:43:31:35:97]: -+ -+[wlan] statsInfoEnvDisplay: (INIT INFO) TPAM(0x0) RTS(0 0) BA(0x1 0) OK(9 9 xxx) ERR(0 0 0 0 0 0 0) -+ TPAM (bit0: enable 40M, bit1: enable 20 short GI, bit2: enable 40 short GI, -+ bit3: use 40M TX, bit4: use short GI TX, bit5: use no ack) -+ RTS (1st: current use RTS/CTS, 2nd: ever use RTS/CTS) -+ BA (1st: TX session BA bitmap for TID0 ~ TID7, 2nd: peer receive maximum agg number) -+ OK (1st: total number of tx packet from host, 2nd: total number of tx ok, system time last TX OK) -+ ERR (1st: total number of tx err, 2nd ~ 7st: total number of -+ WLAN_STATUS_BUFFER_RETAINED, WLAN_STATUS_PACKET_FLUSHED, WLAN_STATUS_PACKET_AGING_TIMEOUT, -+ WLAN_STATUS_PACKET_MPDU_ERROR, WLAN_STATUS_PACKET_RTS_ERROR, WLAN_STATUS_PACKET_LIFETIME_ERROR) -+ -+[wlan] statsInfoEnvDisplay: (INIT INFO) TRATE (6 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0) (0 0 0 0 0 0 0 3) -+ TX rate count (1M 2 5.5 11 NA NA NA NA 48 24 12 6 54 36 18 9) (MCS0 ~ MCS7) -+ -+[wlan] statsInfoEnvDisplay: (INIT INFO) RX(148 1 0) BA(0x1 64) OK(2 2) ERR(0) -+ RX (1st: latest RCPI, 2nd: chan num) -+ BA (1st: RX session BA bitmap for TID0 ~ TID7, 2nd: our receive maximum agg number) -+ OK (number of rx packets without error, number of rx packets to OS) -+ ERR (number of rx packets with error) -+ -+[wlan] statsInfoEnvDisplay: (INIT INFO) RCCK (0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0) -+ CCK MODE (1 2 5.5 11M) -+[wlan] statsInfoEnvDisplay: (INIT INFO) ROFDM (0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0) -+ OFDM MODE (NA NA NA NA 6 9 12 18 24 36 48 54M) -+[wlan] statsInfoEnvDisplay: (INIT INFO) RHT (0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0) -+ MIXED MODE (number of rx packets with MCS0 ~ MCS15) -+ -+[wlan] statsInfoEnvDisplay: (INIT INFO) StayIntH2M us (29 29 32) (0 0 0) (0 0 0) -+ delay from HIF to MAC own bit=1 (min, avg, max for 500B) (min, avg, max for 1000B) (min, avg, max for others) -+ -+[wlan] statsInfoEnvDisplay: (INIT INFO) AirTime us (608 864 4480) (0 0 0) (0 0 0) -+ delay from MAC start TX to MAC TX done -+ -+[wlan] statsInfoEnvDisplay: (INIT INFO) StayInt us (795 1052 4644_4504) (0 0 0_0) (0 0 0_0) -+ delay from HIF to MAC TX done (min, avg, max_system time for 500B) -+ -+[wlan] statsInfoEnvDisplay: (INIT INFO) StayIntD2T us (795 1052 4644) (0 0 0) (0 0 0) -+ delay from driver to MAC TX done (min, avg, max for 500B) -+ -+[wlan] statsInfoEnvDisplay: (INIT INFO) StayIntR_M2H us (37 40 58) (0 0 0) (0 0 0) -+ delay from MAC to HIF (min, avg, max for 500B) -+ -+[wlan] statsInfoEnvDisplay: (INIT INFO) StayIntR_H2D us (0 0 0) (0 0 0) (0 0 0) -+ delay from HIF to Driver OS (min, avg, max for 500B) -+ -+[wlan] statsInfoEnvDisplay: (INIT INFO) StayCntD2H unit:10ms (10 0 0 0) -+ delay count from Driver to HIF (count in 0~10ms, 10~20ms, 20~30ms, others) -+ -+[wlan] statsInfoEnvDisplay: (INIT INFO) StayCnt unit:1ms (6 3 0 1) -+ delay count from HIF to TX DONE (count in 0~1ms, 1~5ms, 5~10ms, others) -+ -+[wlan] statsInfoEnvDisplay: (INIT INFO) StayCnt (0~1161:7) (1161~2322:2) (2322~3483:0) (3483~4644:0) (4644~:1) -+ delay count from HIF to TX DONE (count in 0~1161 ticks, 1161~2322, 2322~3483, 3483~4644, others) -+ -+[wlan] statsInfoEnvDisplay: (INIT INFO) OTHER (61877) (0) (38) (0) (0) (0ms) -+ Channel idle time, scan count, channel change count, empty tx quota count, -+ power save change count from active to PS, maximum delay from PS to active -+*/ -+ -+ /* init */ -+ prAdapter = prGlueInfo->prAdapter; -+ /*prInfo = &rStatsInfoEnv;*/ -+ prInfo = kalMemAlloc(sizeof(STATS_INFO_ENV_T), VIR_MEM_TYPE); -+ if (prInfo == NULL) { -+ DBGLOG(RX, INFO, "prInfo alloc fail"); -+ return; -+ } -+ -+ kalMemZero(prInfo, sizeof(STATS_INFO_ENV_T)); -+ -+ if (u4InBufLen > sizeof(STATS_INFO_ENV_T)) -+ u4InBufLen = sizeof(STATS_INFO_ENV_T); -+ -+ /* parse */ -+ u4NumOfInfo = *(UINT32 *) prInBuf; -+ u4RxErrBitmap = *(UINT32 *) (prInBuf + 4); -+ -+ /* print */ -+ for (u4InfoId = 0; u4InfoId < u4NumOfInfo; u4InfoId++) { -+ /* -+ use u4InBufLen, not sizeof(rStatsInfoEnv) -+ because the firmware version maybe not equal to driver version -+ */ -+ kalMemCopy(prInfo, prInBuf + 8, u4InBufLen); -+ -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prInfo->ucStaRecIdx); -+ if (prStaRec == NULL) -+ continue; -+ -+ DBGLOG(RX, INFO, " Display stats for [%pM]: %uB\n", -+ prStaRec->aucMacAddr, (UINT32) sizeof(STATS_INFO_ENV_T)); -+ -+ if (prStaRec->ucStatsGenDisplayCnt++ > 10) { -+ /* display general statistics information every 10 * (5 or 10s) */ -+ DBGLOG(RX, INFO, " TBA(0x%x %u) RBA(0x%x %u)\n", -+ prInfo->ucTxAggBitmap, prInfo->ucTxPeerAggMaxSize, -+ prInfo->ucRxAggBitmap, prInfo->ucRxAggMaxSize); -+ prStaRec->ucStatsGenDisplayCnt = 0; -+ } -+ -+ if (prInfo->u4TxDataCntErr == 0) { -+ DBGLOG(RX, INFO, " TOS(%u) OK(%u %u)\n", -+ (UINT32) prGlueInfo->rNetDevStats.tx_packets, -+ prInfo->u4TxDataCntAll, prInfo->u4TxDataCntOK); -+ } else { -+ DBGLOG(RX, INFO, " TOS(%u) OK(%u %u) ERR(%u)\n", -+ (UINT32) prGlueInfo->rNetDevStats.tx_packets, -+ prInfo->u4TxDataCntAll, prInfo->u4TxDataCntOK, prInfo->u4TxDataCntErr); -+ DBGLOG(RX, INFO, " ERR type(%u %u %u %u %u %u)\n", -+ prInfo->u4TxDataCntErrType[0], prInfo->u4TxDataCntErrType[1], -+ prInfo->u4TxDataCntErrType[2], prInfo->u4TxDataCntErrType[3], -+ prInfo->u4TxDataCntErrType[4], prInfo->u4TxDataCntErrType[5]); -+ } -+ -+ for (u4RateId = 1, u4Total = 0; u4RateId < 16; u4RateId++) -+ u4Total += prInfo->u4TxRateCntNonHT[u4RateId]; -+ if (u4Total > 0) { -+ DBGLOG(RX, INFO, " non-HT TRATE (%u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u)\n", -+ prInfo->u4TxRateCntNonHT[0], prInfo->u4TxRateCntNonHT[1], -+ prInfo->u4TxRateCntNonHT[2], prInfo->u4TxRateCntNonHT[3], -+ prInfo->u4TxRateCntNonHT[4], prInfo->u4TxRateCntNonHT[5], -+ prInfo->u4TxRateCntNonHT[6], prInfo->u4TxRateCntNonHT[7], -+ prInfo->u4TxRateCntNonHT[8], prInfo->u4TxRateCntNonHT[9], -+ prInfo->u4TxRateCntNonHT[10], prInfo->u4TxRateCntNonHT[11], -+ prInfo->u4TxRateCntNonHT[12], prInfo->u4TxRateCntNonHT[13], -+ prInfo->u4TxRateCntNonHT[14], prInfo->u4TxRateCntNonHT[15]); -+ } -+ if (prInfo->u4TxRateCntNonHT[0] > 0) { -+ DBGLOG(RX, INFO, " HT TRATE (1M %u) (%u %u %u %u %u %u %u %u)\n", -+ prInfo->u4TxRateCntNonHT[0], -+ prInfo->u4TxRateCntHT[0], prInfo->u4TxRateCntHT[1], -+ prInfo->u4TxRateCntHT[2], prInfo->u4TxRateCntHT[3], -+ prInfo->u4TxRateCntHT[4], prInfo->u4TxRateCntHT[5], -+ prInfo->u4TxRateCntHT[6], prInfo->u4TxRateCntHT[7]); -+ } else { -+ DBGLOG(RX, INFO, " HT TRATE (%u %u %u %u %u %u %u %u)\n", -+ prInfo->u4TxRateCntHT[0], prInfo->u4TxRateCntHT[1], -+ prInfo->u4TxRateCntHT[2], prInfo->u4TxRateCntHT[3], -+ prInfo->u4TxRateCntHT[4], prInfo->u4TxRateCntHT[5], -+ prInfo->u4TxRateCntHT[6], prInfo->u4TxRateCntHT[7]); -+ } -+ -+ if ((prStaRec->u4RxReorderFallAheadCnt != 0) || -+ (prStaRec->u4RxReorderFallBehindCnt != 0) || (prStaRec->u4RxReorderHoleCnt != 0)) { -+ DBGLOG(RX, INFO, " TREORDER (%u %u %u)\n", -+ prStaRec->u4RxReorderFallAheadCnt, -+ prStaRec->u4RxReorderFallBehindCnt, prStaRec->u4RxReorderHoleCnt); -+ } -+ -+ if (prInfo->u4RxDataCntErr == 0) { -+ DBGLOG(RX, INFO, " ROK(%u %u)\n", -+ prInfo->u4RxDataCntAll, prStaRec->u4StatsRxPassToOsCnt); -+ } else { -+ DBGLOG(RX, INFO, " ROK(%u %u) ERR(%u)\n", -+ prInfo->u4RxDataCntAll, prStaRec->u4StatsRxPassToOsCnt, -+ prInfo->u4RxDataCntErr); -+ } -+ -+ for (u4RateId = 1, u4Total = 0; u4RateId < 16; u4RateId++) -+ u4Total += prInfo->u4RxRateCnt[0][u4RateId] + prInfo->u4RxRateRetryCnt[0][u4RateId]; -+ if (u4Total > 0) { -+ for (u4RateId = 0, u4Total = 0; u4RateId < 16; u4RateId++) -+ u4Total += prInfo->u4RxRateRetryCnt[0][u4RateId]; -+ if (u4Total > 0) { -+ DBGLOG(RX, INFO, -+ " RCCK (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u)\n" -+ "(%u %u)(%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u)\n", -+ prInfo->u4RxRateCnt[0][0], prInfo->u4RxRateRetryCnt[0][0], -+ prInfo->u4RxRateCnt[0][1], prInfo->u4RxRateRetryCnt[0][1], -+ prInfo->u4RxRateCnt[0][2], prInfo->u4RxRateRetryCnt[0][2], -+ prInfo->u4RxRateCnt[0][3], prInfo->u4RxRateRetryCnt[0][3], -+ prInfo->u4RxRateCnt[0][4], prInfo->u4RxRateRetryCnt[0][4], -+ prInfo->u4RxRateCnt[0][5], prInfo->u4RxRateRetryCnt[0][5], -+ prInfo->u4RxRateCnt[0][6], prInfo->u4RxRateRetryCnt[0][6], -+ prInfo->u4RxRateCnt[0][7], prInfo->u4RxRateRetryCnt[0][7], -+ prInfo->u4RxRateCnt[0][8], prInfo->u4RxRateRetryCnt[0][8], -+ prInfo->u4RxRateCnt[0][9], prInfo->u4RxRateRetryCnt[0][9], -+ prInfo->u4RxRateCnt[0][10], prInfo->u4RxRateRetryCnt[0][10], -+ prInfo->u4RxRateCnt[0][11], prInfo->u4RxRateRetryCnt[0][11], -+ prInfo->u4RxRateCnt[0][12], prInfo->u4RxRateRetryCnt[0][12], -+ prInfo->u4RxRateCnt[0][13], prInfo->u4RxRateRetryCnt[0][13], -+ prInfo->u4RxRateCnt[0][14], prInfo->u4RxRateRetryCnt[0][14], -+ prInfo->u4RxRateCnt[0][15], prInfo->u4RxRateRetryCnt[0][15]); -+ } else { -+ DBGLOG(RX, INFO, " RCCK (%u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u)\n", -+ prInfo->u4RxRateCnt[0][0], -+ prInfo->u4RxRateCnt[0][1], -+ prInfo->u4RxRateCnt[0][2], -+ prInfo->u4RxRateCnt[0][3], -+ prInfo->u4RxRateCnt[0][4], -+ prInfo->u4RxRateCnt[0][5], -+ prInfo->u4RxRateCnt[0][6], -+ prInfo->u4RxRateCnt[0][7], -+ prInfo->u4RxRateCnt[0][8], -+ prInfo->u4RxRateCnt[0][9], -+ prInfo->u4RxRateCnt[0][10], -+ prInfo->u4RxRateCnt[0][11], -+ prInfo->u4RxRateCnt[0][12], -+ prInfo->u4RxRateCnt[0][13], -+ prInfo->u4RxRateCnt[0][14], prInfo->u4RxRateCnt[0][15]); -+ } -+ } else { -+ if ((prInfo->u4RxRateCnt[0][0] + prInfo->u4RxRateRetryCnt[0][0]) > 0) { -+ DBGLOG(RX, INFO, " RCCK (%u %u)\n", -+ prInfo->u4RxRateCnt[0][0], prInfo->u4RxRateRetryCnt[0][0]); -+ } -+ } -+ -+ for (u4RateId = 0, u4Total = 0; u4RateId < 16; u4RateId++) -+ u4Total += prInfo->u4RxRateCnt[1][u4RateId] + prInfo->u4RxRateRetryCnt[1][u4RateId]; -+ if (u4Total > 0) { -+ for (u4RateId = 0, u4Total = 0; u4RateId < 16; u4RateId++) -+ u4Total += prInfo->u4RxRateRetryCnt[1][u4RateId]; -+ if (u4Total > 0) { -+ DBGLOG(RX, INFO, -+ " ROFDM (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u)\n" -+ "(%u %u)(%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u)\n", -+ prInfo->u4RxRateCnt[1][0], prInfo->u4RxRateRetryCnt[1][0], -+ prInfo->u4RxRateCnt[1][1], prInfo->u4RxRateRetryCnt[1][1], -+ prInfo->u4RxRateCnt[1][2], prInfo->u4RxRateRetryCnt[1][2], -+ prInfo->u4RxRateCnt[1][3], prInfo->u4RxRateRetryCnt[1][3], -+ prInfo->u4RxRateCnt[1][4], prInfo->u4RxRateRetryCnt[1][4], -+ prInfo->u4RxRateCnt[1][5], prInfo->u4RxRateRetryCnt[1][5], -+ prInfo->u4RxRateCnt[1][6], prInfo->u4RxRateRetryCnt[1][6], -+ prInfo->u4RxRateCnt[1][7], prInfo->u4RxRateRetryCnt[1][7], -+ prInfo->u4RxRateCnt[1][8], prInfo->u4RxRateRetryCnt[1][8], -+ prInfo->u4RxRateCnt[1][9], prInfo->u4RxRateRetryCnt[1][9], -+ prInfo->u4RxRateCnt[1][10], prInfo->u4RxRateRetryCnt[1][10], -+ prInfo->u4RxRateCnt[1][11], prInfo->u4RxRateRetryCnt[1][11], -+ prInfo->u4RxRateCnt[1][12], prInfo->u4RxRateRetryCnt[1][12], -+ prInfo->u4RxRateCnt[1][13], prInfo->u4RxRateRetryCnt[1][13], -+ prInfo->u4RxRateCnt[1][14], prInfo->u4RxRateRetryCnt[1][14], -+ prInfo->u4RxRateCnt[1][15], prInfo->u4RxRateRetryCnt[1][15]); -+ } else { -+ DBGLOG(RX, INFO, " ROFDM (%u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u)\n", -+ prInfo->u4RxRateCnt[1][0], -+ prInfo->u4RxRateCnt[1][1], -+ prInfo->u4RxRateCnt[1][2], -+ prInfo->u4RxRateCnt[1][3], -+ prInfo->u4RxRateCnt[1][4], -+ prInfo->u4RxRateCnt[1][5], -+ prInfo->u4RxRateCnt[1][6], -+ prInfo->u4RxRateCnt[1][7], -+ prInfo->u4RxRateCnt[1][8], -+ prInfo->u4RxRateCnt[1][9], -+ prInfo->u4RxRateCnt[1][10], -+ prInfo->u4RxRateCnt[1][11], -+ prInfo->u4RxRateCnt[1][12], -+ prInfo->u4RxRateCnt[1][13], -+ prInfo->u4RxRateCnt[1][14], prInfo->u4RxRateCnt[1][15]); -+ } -+ } -+ -+ for (u4RateId = 0, u4Total = 0; u4RateId < 16; u4RateId++) -+ u4Total += prInfo->u4RxRateCnt[2][u4RateId] + prInfo->u4RxRateRetryCnt[2][u4RateId]; -+ if (u4Total > 0) { -+ for (u4RateId = 0, u4Total = 0; u4RateId < 16; u4RateId++) -+ u4Total += prInfo->u4RxRateRetryCnt[2][u4RateId]; -+ if (u4Total > 0) { -+ DBGLOG(RX, INFO, " RHT\n" -+ "(%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u)\n", -+ prInfo->u4RxRateCnt[2][0], prInfo->u4RxRateRetryCnt[2][0], -+ prInfo->u4RxRateCnt[2][1], prInfo->u4RxRateRetryCnt[2][1], -+ prInfo->u4RxRateCnt[2][2], prInfo->u4RxRateRetryCnt[2][2], -+ prInfo->u4RxRateCnt[2][3], prInfo->u4RxRateRetryCnt[2][3], -+ prInfo->u4RxRateCnt[2][4], prInfo->u4RxRateRetryCnt[2][4], -+ prInfo->u4RxRateCnt[2][5], prInfo->u4RxRateRetryCnt[2][5], -+ prInfo->u4RxRateCnt[2][6], prInfo->u4RxRateRetryCnt[2][6], -+ prInfo->u4RxRateCnt[2][7], prInfo->u4RxRateRetryCnt[2][7]); -+ } else { -+ DBGLOG(RX, INFO, " RHT (%u %u %u %u %u %u %u %u)\n", -+ prInfo->u4RxRateCnt[2][0], -+ prInfo->u4RxRateCnt[2][1], -+ prInfo->u4RxRateCnt[2][2], -+ prInfo->u4RxRateCnt[2][3], -+ prInfo->u4RxRateCnt[2][4], -+ prInfo->u4RxRateCnt[2][5], -+ prInfo->u4RxRateCnt[2][6], prInfo->u4RxRateCnt[2][7]); -+ } -+ } -+ -+ /* RX drop counts */ -+ for (u4RateId = 0, u4Total = 0; u4RateId < 20; u4RateId++) -+ u4Total += prInfo->u4NumOfRxDrop[u4RateId]; -+ if (u4Total > 0) { -+ DBGLOG(RX, INFO, " RX Drop Count: (%u) (%u) (%u) (%u) (%u) (%u) (%u) (%u)\n" -+ " (%u) (%u) (%u) (%u) (%u) (%u) (%u) (%u) (%u) (%u) (%u) (%u)\n", -+ prInfo->u4NumOfRxDrop[0], prInfo->u4NumOfRxDrop[1], -+ prInfo->u4NumOfRxDrop[2], prInfo->u4NumOfRxDrop[3], -+ prInfo->u4NumOfRxDrop[4], prInfo->u4NumOfRxDrop[5], -+ prInfo->u4NumOfRxDrop[6], prInfo->u4NumOfRxDrop[7], -+ prInfo->u4NumOfRxDrop[8], prInfo->u4NumOfRxDrop[9], -+ prInfo->u4NumOfRxDrop[10], prInfo->u4NumOfRxDrop[11], -+ prInfo->u4NumOfRxDrop[12], prInfo->u4NumOfRxDrop[13], -+ prInfo->u4NumOfRxDrop[14], prInfo->u4NumOfRxDrop[15], -+ prInfo->u4NumOfRxDrop[16], prInfo->u4NumOfRxDrop[17], -+ prInfo->u4NumOfRxDrop[18], prInfo->u4NumOfRxDrop[19]); -+ } -+ -+ /* delay from HIF RX to HIF RX Done */ -+ if (((prInfo->u4StayIntMinHR2HRD[1] + prInfo->u4StayIntAvgHR2HRD[1] + -+ prInfo->u4StayIntMaxHR2HRD[1]) > 0) || -+ ((prInfo->u4StayIntMinHR2HRD[2] + prInfo->u4StayIntAvgHR2HRD[2] + -+ prInfo->u4StayIntMaxHR2HRD[2]) > 0)) { -+ DBGLOG(RX, INFO, " StayIntR_HR2HRD us (%u %u %u) (%u %u %u) (%u %u %u)\n", -+ prInfo->u4StayIntMinHR2HRD[0], prInfo->u4StayIntAvgHR2HRD[0], -+ prInfo->u4StayIntMaxHR2HRD[0], -+ prInfo->u4StayIntMinHR2HRD[1], prInfo->u4StayIntAvgHR2HRD[1], -+ prInfo->u4StayIntMaxHR2HRD[1], -+ prInfo->u4StayIntMinHR2HRD[2], prInfo->u4StayIntAvgHR2HRD[2], -+ prInfo->u4StayIntMaxHR2HRD[2]); -+ } else { -+ DBGLOG(RX, INFO, " StayIntR_HR2HRD us (%u %u %u)\n", -+ prInfo->u4StayIntMinHR2HRD[0], prInfo->u4StayIntAvgHR2HRD[0], -+ prInfo->u4StayIntMaxHR2HRD[0]); -+ } -+ -+ /* others */ -+ DBGLOG(RX, INFO, " OTHER (%u) (%u) (%u) (%x)\n", -+ prInfo->u4RxFifoFullCnt, prAdapter->ucScanTime, -+ prInfo->u4NumOfChanChange, prInfo->u4CurrChnlInfo); -+#if CFG_SUPPORT_THERMO_THROTTLING -+ prAdapter->u4AirDelayTotal = (prInfo->u4AirDelayTotal << 5) / 400000; -+#endif -+ /* reset */ -+ kalMemZero(prStaRec->u4StayIntMinRx, sizeof(prStaRec->u4StayIntMinRx)); -+ kalMemZero(prStaRec->u4StayIntAvgRx, sizeof(prStaRec->u4StayIntAvgRx)); -+ kalMemZero(prStaRec->u4StayIntMaxRx, sizeof(prStaRec->u4StayIntMaxRx)); -+ prStaRec->u4StatsRxPassToOsCnt = 0; -+ prStaRec->u4RxReorderFallAheadCnt = 0; -+ prStaRec->u4RxReorderFallBehindCnt = 0; -+ prStaRec->u4RxReorderHoleCnt = 0; -+ } -+ -+ STATS_DRIVER_OWN_RESET(); -+ kalMemFree(prInfo, VIR_MEM_TYPE, sizeof(STATS_INFO_ENV_T)); -+} -+ -+#if 0 -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to display all environment log. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prInBuf A pointer to the command string buffer, from u4EventSubId -+* \param[in] u4InBufLen The length of the buffer -+* \param[out] None -+* -+* \retval None -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static void statsInfoEnvDisplay(GLUE_INFO_T *prGlueInfo, UINT8 *prInBuf, UINT32 u4InBufLen) -+{ -+ P_ADAPTER_T prAdapter; -+ STA_RECORD_T *prStaRec; -+ UINT32 u4NumOfInfo, u4InfoId; -+ UINT32 u4RxErrBitmap; -+ STATS_INFO_ENV_T rStatsInfoEnv, *prInfo; -+ -+/* -+[wlan] statsInfoEnvRequest: (INIT INFO) statsInfoEnvRequest cmd ok. -+[wlan] statsEventHandle: (INIT INFO) statsEventHandle: Rcv a event -+[wlan] statsEventHandle: (INIT INFO) statsEventHandle: Rcv a event: 0 -+[wlan] statsInfoEnvDisplay: (INIT INFO) Display stats for [00:0c:43:31:35:97]: -+ -+[wlan] statsInfoEnvDisplay: (INIT INFO) TPAM(0x0) RTS(0 0) BA(0x1 0) OK(9 9 xxx) ERR(0 0 0 0 0 0 0) -+ TPAM (bit0: enable 40M, bit1: enable 20 short GI, bit2: enable 40 short GI, -+ bit3: use 40M TX, bit4: use short GI TX, bit5: use no ack) -+ RTS (1st: current use RTS/CTS, 2nd: ever use RTS/CTS) -+ BA (1st: TX session BA bitmap for TID0 ~ TID7, 2nd: peer receive maximum agg number) -+ OK (1st: total number of tx packet from host, 2nd: total number of tx ok, system time last TX OK) -+ ERR (1st: total number of tx err, 2nd ~ 7st: total number of -+ WLAN_STATUS_BUFFER_RETAINED, WLAN_STATUS_PACKET_FLUSHED, WLAN_STATUS_PACKET_AGING_TIMEOUT, -+ WLAN_STATUS_PACKET_MPDU_ERROR, WLAN_STATUS_PACKET_RTS_ERROR, WLAN_STATUS_PACKET_LIFETIME_ERROR) -+ -+[wlan] statsInfoEnvDisplay: (INIT INFO) TRATE (6 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0) (0 0 0 0 0 0 0 3) -+ TX rate count (1M 2 5.5 11 NA NA NA NA 48 24 12 6 54 36 18 9) (MCS0 ~ MCS7) -+ -+[wlan] statsInfoEnvDisplay: (INIT INFO) RX(148 1 0) BA(0x1 64) OK(2 2) ERR(0) -+ RX (1st: latest RCPI, 2nd: chan num) -+ BA (1st: RX session BA bitmap for TID0 ~ TID7, 2nd: our receive maximum agg number) -+ OK (number of rx packets without error, number of rx packets to OS) -+ ERR (number of rx packets with error) -+ -+[wlan] statsInfoEnvDisplay: (INIT INFO) RCCK (0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0) -+ CCK MODE (1 2 5.5 11M) -+[wlan] statsInfoEnvDisplay: (INIT INFO) ROFDM (0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0) -+ OFDM MODE (NA NA NA NA 6 9 12 18 24 36 48 54M) -+[wlan] statsInfoEnvDisplay: (INIT INFO) RHT (0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0) -+ MIXED MODE (number of rx packets with MCS0 ~ MCS15) -+ -+[wlan] statsInfoEnvDisplay: (INIT INFO) StayIntH2M us (29 29 32) (0 0 0) (0 0 0) -+ delay from HIF to MAC own bit=1 (min, avg, max for 500B) (min, avg, max for 1000B) (min, avg, max for others) -+ -+[wlan] statsInfoEnvDisplay: (INIT INFO) AirTime us (608 864 4480) (0 0 0) (0 0 0) -+ delay from MAC start TX to MAC TX done -+ -+[wlan] statsInfoEnvDisplay: (INIT INFO) StayInt us (795 1052 4644_4504) (0 0 0_0) (0 0 0_0) -+ delay from HIF to MAC TX done (min, avg, max_system time for 500B) -+ -+[wlan] statsInfoEnvDisplay: (INIT INFO) StayIntD2T us (795 1052 4644) (0 0 0) (0 0 0) -+ delay from driver to MAC TX done (min, avg, max for 500B) -+ -+[wlan] statsInfoEnvDisplay: (INIT INFO) StayIntR_M2H us (37 40 58) (0 0 0) (0 0 0) -+ delay from MAC to HIF (min, avg, max for 500B) -+ -+[wlan] statsInfoEnvDisplay: (INIT INFO) StayIntR_H2D us (0 0 0) (0 0 0) (0 0 0) -+ delay from HIF to Driver OS (min, avg, max for 500B) -+ -+[wlan] statsInfoEnvDisplay: (INIT INFO) StayCntD2H unit:10ms (10 0 0 0) -+ delay count from Driver to HIF (count in 0~10ms, 10~20ms, 20~30ms, others) -+ -+[wlan] statsInfoEnvDisplay: (INIT INFO) StayCnt unit:1ms (6 3 0 1) -+ delay count from HIF to TX DONE (count in 0~1ms, 1~5ms, 5~10ms, others) -+ -+[wlan] statsInfoEnvDisplay: (INIT INFO) StayCnt (0~1161:7) (1161~2322:2) (2322~3483:0) (3483~4644:0) (4644~:1) -+ delay count from HIF to TX DONE (count in 0~1161 ticks, 1161~2322, 2322~3483, 3483~4644, others) -+ -+[wlan] statsInfoEnvDisplay: (INIT INFO) OTHER (61877) (0) (38) (0) (0) (0ms) -+ Channel idle time, scan count, channel change count, empty tx quota count, -+ power save change count from active to PS, maximum delay from PS to active -+*/ -+ -+ /* init */ -+ prAdapter = prGlueInfo->prAdapter; -+ prInfo = &rStatsInfoEnv; -+ kalMemZero(&rStatsInfoEnv, sizeof(rStatsInfoEnv)); -+ -+ if (u4InBufLen > sizeof(rStatsInfoEnv)) -+ u4InBufLen = sizeof(rStatsInfoEnv); -+ -+ /* parse */ -+ u4NumOfInfo = *(UINT32 *) prInBuf; -+ u4RxErrBitmap = *(UINT32 *) (prInBuf + 4); -+ -+ /* print */ -+ for (u4InfoId = 0; u4InfoId < u4NumOfInfo; u4InfoId++) { -+ /* -+ use u4InBufLen, not sizeof(rStatsInfoEnv) -+ because the firmware version maybe not equal to driver version -+ */ -+ kalMemCopy(&rStatsInfoEnv, prInBuf + 8, u4InBufLen); -+ -+ prStaRec = cnmGetStaRecByIndex(prAdapter, rStatsInfoEnv.ucStaRecIdx); -+ if (prStaRec == NULL) -+ continue; -+ -+ DBGLOG(RX, INFO, " Display stats V%d.%d for [%pM]: %uB %ums\n", -+ prInfo->ucFwVer[0], prInfo->ucFwVer[1], -+ (prStaRec->aucMacAddr), (UINT32) sizeof(STATS_INFO_ENV_T), -+ prInfo->u4ReportSysTime); -+ DBGLOG(RX, INFO, "TPAM(0x%x)RTS(%u %u)BA(0x%x %u)OS(%u)OK(%u %u)ERR(%u %u %u %u %u %u %u)\n", -+ prInfo->ucTxParam, -+ prInfo->fgTxIsRtsUsed, prInfo->fgTxIsRtsEverUsed, -+ prInfo->ucTxAggBitmap, prInfo->ucTxPeerAggMaxSize, -+ (UINT32) prGlueInfo->rNetDevStats.tx_packets, -+ prInfo->u4TxDataCntAll, prInfo->u4TxDataCntOK, -+ prInfo->u4TxDataCntErr, prInfo->u4TxDataCntErrType[0], -+ prInfo->u4TxDataCntErrType[1], prInfo->u4TxDataCntErrType[2], -+ prInfo->u4TxDataCntErrType[3], prInfo->u4TxDataCntErrType[4], -+ prInfo->u4TxDataCntErrType[5])); -+ -+ DBGLOG(RX, INFO, "TRATE(%u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u)\n", -+ prInfo->u4TxRateCntNonHT[0], prInfo->u4TxRateCntNonHT[1], -+ prInfo->u4TxRateCntNonHT[2], prInfo->u4TxRateCntNonHT[3], -+ prInfo->u4TxRateCntNonHT[4], prInfo->u4TxRateCntNonHT[5], -+ prInfo->u4TxRateCntNonHT[6], prInfo->u4TxRateCntNonHT[7], -+ prInfo->u4TxRateCntNonHT[8], prInfo->u4TxRateCntNonHT[9], -+ prInfo->u4TxRateCntNonHT[10], prInfo->u4TxRateCntNonHT[11], -+ prInfo->u4TxRateCntNonHT[12], prInfo->u4TxRateCntNonHT[13], -+ prInfo->u4TxRateCntNonHT[14], prInfo->u4TxRateCntNonHT[15], -+ prInfo->u4TxRateCntHT[0], prInfo->u4TxRateCntHT[1], -+ prInfo->u4TxRateCntHT[2], prInfo->u4TxRateCntHT[3], -+ prInfo->u4TxRateCntHT[4], prInfo->u4TxRateCntHT[5], -+ prInfo->u4TxRateCntHT[6], prInfo->u4TxRateCntHT[7])); -+ -+ DBGLOG(RX, INFO, " TREORDER (%u %u %u)\n", -+ prStaRec->u4RxReorderFallAheadCnt, -+ prStaRec->u4RxReorderFallBehindCnt, prStaRec->u4RxReorderHoleCnt); -+ -+ DBGLOG(RX, INFO, " RX(%u %u %u) BA(0x%x %u) OK(%u %u) ERR(%u)\n", -+ prInfo->ucRcvRcpi, prInfo->ucHwChanNum, prInfo->fgRxIsShortGI, -+ prInfo->ucRxAggBitmap, prInfo->ucRxAggMaxSize, -+ prInfo->u4RxDataCntAll, prStaRec->u4StatsRxPassToOsCnt, prInfo->u4RxDataCntErr); -+ -+ DBGLOG(RX, INFO, " RX Free MAC DESC(%u %u %u %u %u %u) Free HIF DESC(%u %u %u %u %u %u)\n", -+ prInfo->u4RxMacFreeDescCnt[0], prInfo->u4RxMacFreeDescCnt[1], -+ prInfo->u4RxMacFreeDescCnt[2], prInfo->u4RxMacFreeDescCnt[3], -+ prInfo->u4RxMacFreeDescCnt[4], prInfo->u4RxMacFreeDescCnt[5], -+ prInfo->u4RxHifFreeDescCnt[0], prInfo->u4RxHifFreeDescCnt[1], -+ prInfo->u4RxHifFreeDescCnt[2], prInfo->u4RxHifFreeDescCnt[3], -+ prInfo->u4RxHifFreeDescCnt[4], prInfo->u4RxHifFreeDescCnt[5])); -+ -+ DBGLOG(RX, INFO, " RCCK (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u)\n" -+ "(%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u)\n", -+ prInfo->u4RxRateCnt[0][0], prInfo->u4RxRateRetryCnt[0][0], -+ prInfo->u4RxRateCnt[0][1], prInfo->u4RxRateRetryCnt[0][1], -+ prInfo->u4RxRateCnt[0][2], prInfo->u4RxRateRetryCnt[0][2], -+ prInfo->u4RxRateCnt[0][3], prInfo->u4RxRateRetryCnt[0][3], -+ prInfo->u4RxRateCnt[0][4], prInfo->u4RxRateRetryCnt[0][4], -+ prInfo->u4RxRateCnt[0][5], prInfo->u4RxRateRetryCnt[0][5], -+ prInfo->u4RxRateCnt[0][6], prInfo->u4RxRateRetryCnt[0][6], -+ prInfo->u4RxRateCnt[0][7], prInfo->u4RxRateRetryCnt[0][7], -+ prInfo->u4RxRateCnt[0][8], prInfo->u4RxRateRetryCnt[0][8], -+ prInfo->u4RxRateCnt[0][9], prInfo->u4RxRateRetryCnt[0][9], -+ prInfo->u4RxRateCnt[0][10], prInfo->u4RxRateRetryCnt[0][10], -+ prInfo->u4RxRateCnt[0][11], prInfo->u4RxRateRetryCnt[0][11], -+ prInfo->u4RxRateCnt[0][12], prInfo->u4RxRateRetryCnt[0][12], -+ prInfo->u4RxRateCnt[0][13], prInfo->u4RxRateRetryCnt[0][13], -+ prInfo->u4RxRateCnt[0][14], prInfo->u4RxRateRetryCnt[0][14], -+ prInfo->u4RxRateCnt[0][15], prInfo->u4RxRateRetryCnt[0][15])); -+ DBGLOG(RX, INFO, " ROFDM (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u)\n" -+ "(%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u)\n", -+ prInfo->u4RxRateCnt[1][0], prInfo->u4RxRateRetryCnt[1][0], -+ prInfo->u4RxRateCnt[1][1], prInfo->u4RxRateRetryCnt[1][1], -+ prInfo->u4RxRateCnt[1][2], prInfo->u4RxRateRetryCnt[1][2], -+ prInfo->u4RxRateCnt[1][3], prInfo->u4RxRateRetryCnt[1][3], -+ prInfo->u4RxRateCnt[1][4], prInfo->u4RxRateRetryCnt[1][4], -+ prInfo->u4RxRateCnt[1][5], prInfo->u4RxRateRetryCnt[1][5], -+ prInfo->u4RxRateCnt[1][6], prInfo->u4RxRateRetryCnt[1][6], -+ prInfo->u4RxRateCnt[1][7], prInfo->u4RxRateRetryCnt[1][7], -+ prInfo->u4RxRateCnt[1][8], prInfo->u4RxRateRetryCnt[1][8], -+ prInfo->u4RxRateCnt[1][9], prInfo->u4RxRateRetryCnt[1][9], -+ prInfo->u4RxRateCnt[1][10], prInfo->u4RxRateRetryCnt[1][10], -+ prInfo->u4RxRateCnt[1][11], prInfo->u4RxRateRetryCnt[1][11], -+ prInfo->u4RxRateCnt[1][12], prInfo->u4RxRateRetryCnt[1][12], -+ prInfo->u4RxRateCnt[1][13], prInfo->u4RxRateRetryCnt[1][13], -+ prInfo->u4RxRateCnt[1][14], prInfo->u4RxRateRetryCnt[1][14], -+ prInfo->u4RxRateCnt[1][15], prInfo->u4RxRateRetryCnt[1][15])); -+ DBGLOG(RX, INFO, " RHT (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u)\n" -+ "(%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u)\n", -+ prInfo->u4RxRateCnt[2][0], prInfo->u4RxRateRetryCnt[2][0], -+ prInfo->u4RxRateCnt[2][1], prInfo->u4RxRateRetryCnt[2][1], -+ prInfo->u4RxRateCnt[2][2], prInfo->u4RxRateRetryCnt[2][2], -+ prInfo->u4RxRateCnt[2][3], prInfo->u4RxRateRetryCnt[2][3], -+ prInfo->u4RxRateCnt[2][4], prInfo->u4RxRateRetryCnt[2][4], -+ prInfo->u4RxRateCnt[2][5], prInfo->u4RxRateRetryCnt[2][5], -+ prInfo->u4RxRateCnt[2][6], prInfo->u4RxRateRetryCnt[2][6], -+ prInfo->u4RxRateCnt[2][7], prInfo->u4RxRateRetryCnt[2][7], -+ prInfo->u4RxRateCnt[2][8], prInfo->u4RxRateRetryCnt[2][8], -+ prInfo->u4RxRateCnt[2][9], prInfo->u4RxRateRetryCnt[2][9], -+ prInfo->u4RxRateCnt[2][10], prInfo->u4RxRateRetryCnt[2][10], -+ prInfo->u4RxRateCnt[2][11], prInfo->u4RxRateRetryCnt[2][11], -+ prInfo->u4RxRateCnt[2][12], prInfo->u4RxRateRetryCnt[2][12], -+ prInfo->u4RxRateCnt[2][13], prInfo->u4RxRateRetryCnt[2][13], -+ prInfo->u4RxRateCnt[2][14], prInfo->u4RxRateRetryCnt[2][14], -+ prInfo->u4RxRateCnt[2][15], prInfo->u4RxRateRetryCnt[2][15])); -+ -+ /* delay from HIF to MAC */ -+ DBGLOG(RX, INFO, " StayIntH2M us (%u %u %u) (%u %u %u) (%u %u %u)\n", -+ prInfo->u4StayIntMinH2M[0], prInfo->u4StayIntAvgH2M[0], -+ prInfo->u4StayIntMaxH2M[0], -+ prInfo->u4StayIntMinH2M[1], prInfo->u4StayIntAvgH2M[1], -+ prInfo->u4StayIntMaxH2M[1], -+ prInfo->u4StayIntMinH2M[2], prInfo->u4StayIntAvgH2M[2], -+ prInfo->u4StayIntMaxH2M[2])); -+ /* delay from MAC to TXDONE */ -+ DBGLOG(RX, INFO, " AirTime us (%u %u %u) (%u %u %u) (%u %u %u)\n", -+ prInfo->u4AirDelayMin[0] << 5, prInfo->u4AirDelayAvg[0] << 5, -+ prInfo->u4AirDelayMax[0] << 5, -+ prInfo->u4AirDelayMin[1] << 5, prInfo->u4AirDelayAvg[1] << 5, -+ prInfo->u4AirDelayMax[1] << 5, -+ prInfo->u4TxDataCntAll, (prInfo->u4AirDelayAvg[2] << 5) / (prInfo->u4TxDataCntAll), -+ (prInfo->u4AirDelayAvg[2] << 5) / 400000)); -+ prAdapter->u4AirDelayTotal = (prInfo->u4AirDelayTotal << 5) / 400000; -+ /* delay from HIF to TXDONE */ -+ DBGLOG(RX, INFO, " StayInt us (%u %u %u_%u) (%u %u %u_%u) (%u %u %u_%u)\n", -+ prInfo->u4StayIntMin[0], prInfo->u4StayIntAvg[0], -+ prInfo->u4StayIntMax[0], prInfo->u4StayIntMaxSysTime[0], -+ prInfo->u4StayIntMin[1], prInfo->u4StayIntAvg[1], -+ prInfo->u4StayIntMax[1], prInfo->u4StayIntMaxSysTime[1], -+ prInfo->u4StayIntMin[2], prInfo->u4StayIntAvg[2], -+ prInfo->u4StayIntMax[2], prInfo->u4StayIntMaxSysTime[2])); -+ /* delay from Driver to TXDONE */ -+ DBGLOG(RX, INFO, " StayIntD2T us (%u %u %u) (%u %u %u) (%u %u %u)\n", -+ prInfo->u4StayIntMinD2T[0], prInfo->u4StayIntAvgD2T[0], -+ prInfo->u4StayIntMaxD2T[0], -+ prInfo->u4StayIntMinD2T[1], prInfo->u4StayIntAvgD2T[1], -+ prInfo->u4StayIntMaxD2T[1], -+ prInfo->u4StayIntMinD2T[2], prInfo->u4StayIntAvgD2T[2], -+ prInfo->u4StayIntMaxD2T[2])); -+ -+ /* delay from RXDONE to HIF */ -+ DBGLOG(RX, INFO, " StayIntR_M2H us (%u %u %u) (%u %u %u) (%u %u %u)\n", -+ prInfo->u4StayIntMinRx[0], prInfo->u4StayIntAvgRx[0], -+ prInfo->u4StayIntMaxRx[0], -+ prInfo->u4StayIntMinRx[1], prInfo->u4StayIntAvgRx[1], -+ prInfo->u4StayIntMaxRx[1], -+ prInfo->u4StayIntMinRx[2], prInfo->u4StayIntAvgRx[2], prInfo->u4StayIntMaxRx[2])); -+ /* delay from HIF to OS */ -+ DBGLOG(RX, INFO, " StayIntR_H2D us (%u %u %u) (%u %u %u) (%u %u %u)\n", -+ prStaRec->u4StayIntMinRx[0], prStaRec->u4StayIntAvgRx[0], -+ prStaRec->u4StayIntMaxRx[0], -+ prStaRec->u4StayIntMinRx[1], prStaRec->u4StayIntAvgRx[1], -+ prStaRec->u4StayIntMaxRx[1], -+ prStaRec->u4StayIntMinRx[2], prStaRec->u4StayIntAvgRx[2], -+ prStaRec->u4StayIntMaxRx[2])); -+ -+ /* count based on delay from OS to HIF */ -+ DBGLOG(RX, INFO, " StayCntD2H unit:%dms (%d %d %d %d)\n", -+ STATS_STAY_INT_D2H_CONST, -+ prInfo->u4StayIntD2HByConst[0], prInfo->u4StayIntD2HByConst[1], -+ prInfo->u4StayIntD2HByConst[2], prInfo->u4StayIntD2HByConst[3]); -+ -+ /* count based on different delay from HIF to TX DONE */ -+ DBGLOG(RX, INFO, " StayCnt unit:%dms (%d %d %d %d)\n", -+ STATS_STAY_INT_CONST, -+ prInfo->u4StayIntByConst[0], prInfo->u4StayIntByConst[1], -+ prInfo->u4StayIntByConst[2], prInfo->u4StayIntByConst[3]); -+ DBGLOG(RX, INFO, " StayCnt (%d~%d:%d) (%d~%d:%d) (%d~%d:%d) (%d~%d:%d) (%d~:%d)\n", -+ 0, prInfo->u4StayIntMaxPast / 4, prInfo->u4StayIntCnt[0], -+ prInfo->u4StayIntMaxPast / 4, prInfo->u4StayIntMaxPast / 2, prInfo->u4StayIntCnt[1], -+ prInfo->u4StayIntMaxPast / 2, prInfo->u4StayIntMaxPast * 3 / 4, -+ prInfo->u4StayIntCnt[2], prInfo->u4StayIntMaxPast * 3 / 4, prInfo->u4StayIntMaxPast, -+ prInfo->u4StayIntCnt[3], prInfo->u4StayIntMaxPast, prInfo->u4StayIntCnt[4])); -+ -+ /* channel idle time */ -+ DBGLOG(RX, INFO, " Idle Time (slot): (%u) (%u) (%u) (%u) (%u) (%u) (%u) (%u) (%u) (%u)\n", -+ prInfo->au4ChanIdleCnt[0], prInfo->au4ChanIdleCnt[1], -+ prInfo->au4ChanIdleCnt[2], prInfo->au4ChanIdleCnt[3], -+ prInfo->au4ChanIdleCnt[4], prInfo->au4ChanIdleCnt[5], -+ prInfo->au4ChanIdleCnt[6], prInfo->au4ChanIdleCnt[7], -+ prInfo->au4ChanIdleCnt[8], prInfo->au4ChanIdleCnt[9])); -+ -+ /* BT coex */ -+ DBGLOG(RX, INFO, " BT coex (0x%x)\n", prInfo->u4BtContUseTime); -+ -+ /* others */ -+ DBGLOG(RX, INFO, " OTHER (%u) (%u) (%u) (%u) (%u) (%ums) (%uus)\n", -+ prInfo->u4RxFifoFullCnt, prAdapter->ucScanTime, -+ prInfo->u4NumOfChanChange, prStaRec->u4NumOfNoTxQuota, -+ prInfo->ucNumOfPsChange, prInfo->u4PsIntMax, u4DrvOwnMax / 1000); -+ -+ /* reset */ -+ kalMemZero(prStaRec->u4StayIntMinRx, sizeof(prStaRec->u4StayIntMinRx)); -+ kalMemZero(prStaRec->u4StayIntAvgRx, sizeof(prStaRec->u4StayIntAvgRx)); -+ kalMemZero(prStaRec->u4StayIntMaxRx, sizeof(prStaRec->u4StayIntMaxRx)); -+ prStaRec->u4StatsRxPassToOsCnt = 0; -+ prStaRec->u4RxReorderFallAheadCnt = 0; -+ prStaRec->u4RxReorderFallBehindCnt = 0; -+ prStaRec->u4RxReorderHoleCnt = 0; -+ } -+ -+ STATS_DRIVER_OWN_RESET(); -+} -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to request firmware to feedback statistics. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set -+* \param[in] u4SetBufferLen The length of the set buffer -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed due to invalid length of -+* the set buffer, returns the amount of storage needed. -+* -+* \retval TDLS_STATUS_xx -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static WLAN_STATUS -+statsInfoEnvRequest(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen) -+{ -+ STATS_CMD_CORE_T *prCmdContent; -+ WLAN_STATUS rStatus; -+ -+ /* sanity check */ -+ if (fgIsUnderSuspend == true) -+ return WLAN_STATUS_SUCCESS; /* do not request stats after early suspend */ -+ -+ /* init command buffer */ -+ prCmdContent = (STATS_CMD_CORE_T *) pvSetBuffer; -+ prCmdContent->u4Command = STATS_CORE_CMD_ENV_REQUEST; -+ -+ /* send the command */ -+ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ -+ CMD_ID_STATS, /* ucCID */ -+ TRUE, /* fgSetQuery */ -+ FALSE, /* fgNeedResp */ -+ FALSE, /* fgIsOid */ -+ NULL, NULL, /* pfCmdTimeoutHandler */ -+ sizeof(STATS_CMD_CORE_T), /* u4SetQueryInfoLen */ -+ (PUINT_8) prCmdContent, /* pucInfoBuffer */ -+ NULL, /* pvSetQueryBuffer */ -+ 0 /* u4SetQueryBufferLen */ -+ ); -+ -+ if (rStatus != WLAN_STATUS_PENDING) { -+ DBGLOG(RX, ERROR, "%s wlanSendSetQueryCmd allocation fail!\n", __func__); -+ return WLAN_STATUS_RESOURCES; -+ } -+ -+ DBGLOG(RX, INFO, "%s cmd ok.\n", __func__); -+ return WLAN_STATUS_SUCCESS; -+} -+ -+/******************************************************************************* -+* P U B L I C F U N C T I O N S -+******************************************************************************** -+*/ -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to handle any statistics event. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prInBuf A pointer to the command string buffer -+* \param[in] u4InBufLen The length of the buffer -+* \param[out] None -+* -+* \retval None -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID statsEventHandle(GLUE_INFO_T *prGlueInfo, UINT8 *prInBuf, UINT32 u4InBufLen) -+{ -+ UINT32 u4EventId; -+ -+ /* sanity check */ -+/* DBGLOG(RX, INFO, */ -+/* (" %s: Rcv a event\n", __FUNCTION__)); */ -+ -+ if ((prGlueInfo == NULL) || (prInBuf == NULL)) -+ return; /* shall not be here */ -+ -+ /* handle */ -+ u4EventId = *(UINT32 *) prInBuf; -+ u4InBufLen -= 4; -+ -+/* DBGLOG(RX, INFO, */ -+/* (" %s: Rcv a event: %d\n", __FUNCTION__, u4EventId)); */ -+ -+ switch (u4EventId) { -+ case STATS_HOST_EVENT_ENV_REPORT: -+ statsInfoEnvDisplay(prGlueInfo, prInBuf + 4, u4InBufLen); -+ break; -+ -+ default: -+ break; -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to detect if we can request firmware to feedback statistics. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] ucStaRecIndex The station index -+* \param[out] None -+* -+* \retval None -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID statsEnvReportDetect(ADAPTER_T *prAdapter, UINT8 ucStaRecIndex) -+{ -+ STA_RECORD_T *prStaRec; -+ OS_SYSTIME rCurTime; -+ STATS_CMD_CORE_T rCmd; -+ -+ prStaRec = cnmGetStaRecByIndex(prAdapter, ucStaRecIndex); -+ if (prStaRec == NULL) -+ return; -+ -+ prStaRec->u4StatsEnvTxCnt++; -+ GET_CURRENT_SYSTIME(&rCurTime); -+ -+ if (prStaRec->rStatsEnvTxPeriodLastTime == 0) { -+ prStaRec->rStatsEnvTxLastTime = rCurTime; -+ prStaRec->rStatsEnvTxPeriodLastTime = rCurTime; -+ return; -+ } -+ -+ if (prStaRec->u4StatsEnvTxCnt > STATS_ENV_TX_CNT_REPORT_TRIGGER) { -+ if (CHECK_FOR_TIMEOUT(rCurTime, prStaRec->rStatsEnvTxLastTime, -+ SEC_TO_SYSTIME(STATS_ENV_TX_CNT_REPORT_TRIGGER_SEC))) { -+ rCmd.ucStaRecIdx = ucStaRecIndex; -+ statsInfoEnvRequest(prAdapter, &rCmd, 0, NULL); -+ -+ prStaRec->rStatsEnvTxLastTime = rCurTime; -+ prStaRec->rStatsEnvTxPeriodLastTime = rCurTime; -+ prStaRec->u4StatsEnvTxCnt = 0; -+ return; -+ } -+ } -+ -+ if (CHECK_FOR_TIMEOUT(rCurTime, prStaRec->rStatsEnvTxPeriodLastTime, SEC_TO_SYSTIME(STATS_ENV_TIMEOUT_SEC))) { -+ rCmd.ucStaRecIdx = ucStaRecIndex; -+ statsInfoEnvRequest(prAdapter, &rCmd, 0, NULL); -+ -+ prStaRec->rStatsEnvTxPeriodLastTime = rCurTime; -+ return; -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to handle rx done. -+* -+* \param[in] prStaRec Pointer to the STA_RECORD_T structure -+* \param[in] prSwRfb Pointer to the received packet -+* \param[out] None -+* -+* \retval None -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID StatsEnvRxDone(STA_RECORD_T *prStaRec, SW_RFB_T *prSwRfb) -+{ -+ UINT32 u4LenId; -+ UINT32 u4CurTime, u4DifTime; -+ -+ /* sanity check */ -+ if (prStaRec == NULL) -+ return; -+ -+ /* stats: rx done count */ -+ prStaRec->u4StatsRxPassToOsCnt++; -+ -+ /* get length partition ID */ -+ u4LenId = 0; -+ if (prSwRfb->u2PacketLen < STATS_STAY_INT_BYTE_THRESHOLD) { -+ u4LenId = 0; -+ } else { -+ if ((STATS_STAY_INT_BYTE_THRESHOLD <= prSwRfb->u2PacketLen) && -+ (prSwRfb->u2PacketLen < (STATS_STAY_INT_BYTE_THRESHOLD << 1))) { -+ u4LenId = 1; -+ } else -+ u4LenId = 2; -+ } -+ -+ /* stats: rx delay */ -+ u4CurTime = kalGetTimeTick(); -+ -+ if ((u4CurTime > prSwRfb->rRxTime) && (prSwRfb->rRxTime != 0)) { -+ u4DifTime = u4CurTime - prSwRfb->rRxTime; -+ -+ if (prStaRec->u4StayIntMinRx[u4LenId] == 0) /* impossible */ -+ prStaRec->u4StayIntMinRx[u4LenId] = 0xffffffff; -+ -+ if (u4DifTime > prStaRec->u4StayIntMaxRx[u4LenId]) -+ prStaRec->u4StayIntMaxRx[u4LenId] = u4DifTime; -+ else if (u4DifTime < prStaRec->u4StayIntMinRx[u4LenId]) -+ prStaRec->u4StayIntMinRx[u4LenId] = u4DifTime; -+ -+ prStaRec->u4StayIntAvgRx[u4LenId] += u4DifTime; -+ if (prStaRec->u4StayIntAvgRx[u4LenId] != u4DifTime) -+ prStaRec->u4StayIntAvgRx[u4LenId] >>= 1; -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to handle rx done. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prInBuf A pointer to the command string buffer -+* \param[in] u4InBufLen The length of the buffer -+* \param[out] None -+* -+* \retval None -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT_64 StatsEnvTimeGet(VOID) -+{ -+ /* TODO: use better API to get time to save time, jiffies unit is 10ms, too large */ -+ -+/* struct timeval tv; */ -+ -+/* do_gettimeofday(&tv); */ -+/* return tv.tv_usec + tv.tv_sec * (UINT_64)1000000; */ -+ -+ UINT_64 u8Clk; -+/* UINT32 *pClk = &u8Clk; */ -+ -+ u8Clk = sched_clock(); /* unit: naro seconds */ -+/* printk(" sched_clock() = %x %x %u\n", pClk[0], pClk[1], sizeof(jiffies)); */ -+ -+ return (UINT_64) u8Clk; /* sched_clock *//* jiffies size = 4B */ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to handle rx done. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prInBuf A pointer to the command string buffer -+* \param[in] u4InBufLen The length of the buffer -+* \param[out] None -+* -+* \retval None -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID StatsEnvTxTime2Hif(MSDU_INFO_T *prMsduInfo, HIF_TX_HEADER_T *prHwTxHeader) -+{ -+ UINT_64 u8SysTime, u8SysTimeIn; -+ UINT32 u4TimeDiff; -+ -+ u8SysTime = StatsEnvTimeGet(); -+ u8SysTimeIn = GLUE_GET_PKT_XTIME(prMsduInfo->prPacket); -+ -+/* printk(" hif: 0x%x %u %u %u\n", */ -+/* prMsduInfo->prPacket, StatsEnvTimeGet(), u8SysTime, GLUE_GET_PKT_XTIME(prMsduInfo->prPacket)); */ -+ -+ if ((u8SysTimeIn > 0) && (u8SysTime > u8SysTimeIn)) { -+ u8SysTime = u8SysTime - u8SysTimeIn; -+ u4TimeDiff = (UINT32) u8SysTime; -+ u4TimeDiff = u4TimeDiff / 1000; /* ns to us */ -+ -+ /* pass the delay between OS to us and we to HIF */ -+ if (u4TimeDiff > 0xFFFF) -+ *(UINT16 *) prHwTxHeader->aucReserved = (UINT16) 0xFFFF; /* 65535 us */ -+ else -+ *(UINT16 *) prHwTxHeader->aucReserved = (UINT16) u4TimeDiff; -+ -+/* printk(" u4TimeDiff: %u\n", u4TimeDiff); */ -+ } else { -+ prHwTxHeader->aucReserved[0] = 0; -+ prHwTxHeader->aucReserved[1] = 0; -+ } -+} -+ -+static VOID statsParsePktInfo(PUINT_8 pucPkt, UINT_8 status, UINT_8 eventType, P_MSDU_INFO_T prMsduInfo) -+{ -+ /* get ethernet protocol */ -+ UINT_16 u2EtherType = (pucPkt[ETH_TYPE_LEN_OFFSET] << 8) | (pucPkt[ETH_TYPE_LEN_OFFSET + 1]); -+ PUINT_8 pucEthBody = &pucPkt[ETH_HLEN]; -+ -+ switch (u2EtherType) { -+ case ETH_P_ARP: -+ { -+ UINT_16 u2OpCode = (pucEthBody[6] << 8) | pucEthBody[7]; -+ if (eventType == EVENT_TX) -+ prMsduInfo->fgIsBasicRate = TRUE; -+ -+ if ((su2TxDoneCfg & CFG_ARP) == 0) -+ break; -+ -+ switch (eventType) { -+ case EVENT_RX: -+ if (u2OpCode == ARP_PRO_REQ) -+ DBGLOG(RX, INFO, " Arp Req From IP: %d.%d.%d.%d\n", -+ pucEthBody[14], pucEthBody[15], pucEthBody[16], pucEthBody[17]); -+ else if (u2OpCode == ARP_PRO_RSP) -+ DBGLOG(RX, INFO, " Arp Rsp from IP: %d.%d.%d.%d\n", -+ pucEthBody[14], pucEthBody[15], pucEthBody[16], pucEthBody[17]); -+ break; -+ case EVENT_TX: -+ if (u2OpCode == ARP_PRO_REQ) -+ DBGLOG(TX, INFO, " Arp Req to IP: %d.%d.%d.%d\n", -+ pucEthBody[24], pucEthBody[25], pucEthBody[26], pucEthBody[27]); -+ else if (u2OpCode == ARP_PRO_RSP) -+ DBGLOG(TX, INFO, " Arp Rsp to IP: %d.%d.%d.%d\n", -+ pucEthBody[24], pucEthBody[25], pucEthBody[26], pucEthBody[27]); -+ prMsduInfo->fgNeedTxDoneStatus = TRUE; -+ break; -+ case EVENT_TX_DONE: -+ if (u2OpCode == ARP_PRO_REQ) -+ DBGLOG(TX, INFO, " Arp Req to IP: %d.%d.%d.%d\n", status, -+ pucEthBody[24], pucEthBody[25], pucEthBody[26], pucEthBody[27]); -+ else if (u2OpCode == ARP_PRO_RSP) -+ DBGLOG(TX, INFO, " Arp Rsp to IP: %d.%d.%d.%d\n", status, -+ pucEthBody[24], pucEthBody[25], pucEthBody[26], pucEthBody[27]); -+ break; -+ } -+ break; -+ } -+ case ETH_P_IP: -+ { -+ UINT_8 ucIpProto = pucEthBody[9]; /* IP header without options */ -+ UINT_8 ucIpVersion = (pucEthBody[0] & IPVH_VERSION_MASK) >> IPVH_VERSION_OFFSET; -+ UINT_16 u2IpId = pucEthBody[4]<<8 | pucEthBody[5]; -+ -+ if (ucIpVersion != IPVERSION) -+ break; -+ -+ switch (ucIpProto) { -+ case IP_PRO_ICMP: -+ { -+ /* the number of ICMP packets is seldom so we print log here */ -+ UINT_8 ucIcmpType; -+ UINT_16 u2IcmpId, u2IcmpSeq; -+ PUINT_8 pucIcmp = &pucEthBody[20]; -+ -+ ucIcmpType = pucIcmp[0]; -+ /* don't log network unreachable packet */ -+ if (((su2TxDoneCfg & CFG_ICMP) == 0) || ucIcmpType == 3) -+ break; -+ u2IcmpId = *(UINT_16 *) &pucIcmp[4]; -+ u2IcmpSeq = *(UINT_16 *) &pucIcmp[6]; -+ switch (eventType) { -+ case EVENT_RX: -+ DBGLOG(RX, INFO, " ICMP: Type %d, Id BE 0x%04x, Seq BE 0x%04x\n", -+ ucIcmpType, u2IcmpId, u2IcmpSeq); -+ break; -+ case EVENT_TX: -+ DBGLOG(TX, INFO, " ICMP: Type %d, Id 0x04%x, Seq BE 0x%04x\n", -+ ucIcmpType, u2IcmpId, u2IcmpSeq); -+ prMsduInfo->fgNeedTxDoneStatus = TRUE; -+ break; -+ case EVENT_TX_DONE: -+ DBGLOG(TX, INFO, " Type %d, Id 0x%04x, Seq 0x%04x\n", -+ status, ucIcmpType, u2IcmpId, u2IcmpSeq); -+ break; -+ } -+ break; -+ } -+ case IP_PRO_UDP: -+ { -+ /* the number of DHCP packets is seldom so we print log here */ -+ PUINT_8 pucUdp = &pucEthBody[20]; -+ PUINT_8 pucUdpPayload = &pucUdp[8]; -+ UINT_16 u2UdpDstPort; -+ UINT_16 u2UdpSrcPort; -+ -+ u2UdpDstPort = (pucUdp[2] << 8) | pucUdp[3]; -+ u2UdpSrcPort = (pucUdp[0] << 8) | pucUdp[1]; -+ /* dhcp */ -+ if ((u2UdpDstPort == UDP_PORT_DHCPS) || (u2UdpDstPort == UDP_PORT_DHCPC)) { -+ UINT_32 u4TransID = pucUdpPayload[4]<<24 | pucUdpPayload[5]<<16 | -+ pucUdpPayload[6]<<8 | pucUdpPayload[7]; -+ -+ switch (eventType) { -+ case EVENT_RX: -+ DBGLOG(RX, INFO, " DHCP: IPID 0x%02x, MsgType 0x%x, TransID 0x%08x\n", -+ u2IpId, pucUdpPayload[0], u4TransID); -+ break; -+ case EVENT_TX: -+ DBGLOG(TX, INFO, " DHCP: IPID 0x%02x, MsgType 0x%x, TransID 0x%08x\n", -+ u2IpId, pucUdpPayload[0], u4TransID); -+ prMsduInfo->fgNeedTxDoneStatus = TRUE; -+ prMsduInfo->fgIsBasicRate = TRUE; -+ break; -+ case EVENT_TX_DONE: -+ DBGLOG(TX, INFO, -+ " DHCP: IPID 0x%02x, MsgType 0x%x, TransID 0x%08x\n", -+ status, u2IpId, pucUdpPayload[0], u4TransID); -+ break; -+ } -+ } else if (u2UdpDstPort == UDP_PORT_DNS) { /* tx dns */ -+ UINT_16 u2TransId = (pucUdpPayload[0] << 8) | pucUdpPayload[1]; -+ if (eventType == EVENT_TX) -+ prMsduInfo->fgIsBasicRate = TRUE; -+ -+ if ((su2TxDoneCfg & CFG_DNS) == 0) -+ break; -+ if (eventType == EVENT_TX) { -+ DBGLOG(TX, INFO, " DNS: IPID 0x%02x, TransID 0x%04x\n", u2IpId, u2TransId); -+ prMsduInfo->fgNeedTxDoneStatus = TRUE; -+ } else if (eventType == EVENT_TX_DONE) -+ DBGLOG(TX, INFO, " DNS: IPID 0x%02x, TransID 0x%04x\n", -+ status, u2IpId, u2TransId); -+ } else if (u2UdpSrcPort == UDP_PORT_DNS && eventType == EVENT_RX) { /* rx dns */ -+ UINT_16 u2TransId = (pucUdpPayload[0] << 8) | pucUdpPayload[1]; -+ -+ if ((su2TxDoneCfg & CFG_DNS) == 0) -+ break; -+ DBGLOG(RX, INFO, " DNS: IPID 0x%02x, TransID 0x%04x\n", u2IpId, u2TransId); -+ } else if ((su2TxDoneCfg & CFG_UDP) != 0) { -+ switch (eventType) { -+ case EVENT_RX: -+ DBGLOG(RX, INFO, " UDP: IPID 0x%04x\n", u2IpId); -+ break; -+ case EVENT_TX: -+ DBGLOG(TX, INFO, " UDP: IPID 0x%04x\n", u2IpId); -+ prMsduInfo->fgNeedTxDoneStatus = TRUE; -+ break; -+ case EVENT_TX_DONE: -+ DBGLOG(TX, INFO, " UDP: IPID 0x%04x\n", status, u2IpId); -+ break; -+ } -+ } -+ break; -+ } -+ case IP_PRO_TCP: -+ if ((su2TxDoneCfg & CFG_TCP) == 0) -+ break; -+ -+ switch (eventType) { -+ case EVENT_RX: -+ DBGLOG(RX, INFO, " TCP: IPID 0x%04x\n", u2IpId); -+ break; -+ case EVENT_TX: -+ DBGLOG(TX, INFO, " TCP: IPID 0x%04x\n", u2IpId); -+ prMsduInfo->fgNeedTxDoneStatus = TRUE; -+ break; -+ case EVENT_TX_DONE: -+ DBGLOG(TX, INFO, " TCP: IPID 0x%04x\n", status, u2IpId); -+ break; -+ } -+ break; -+ } -+ break; -+ } -+ case ETH_P_PRE_1X: -+ DBGLOG(RX, INFO, "pre-1x\n"); -+ case ETH_P_1X: -+ { -+ PUINT_8 pucEapol = pucEthBody; -+ UINT_8 ucEapolType = pucEapol[1]; -+ -+ switch (ucEapolType) { -+ case 0: /* eap packet */ -+ switch (eventType) { -+ case EVENT_RX: -+ DBGLOG(RX, INFO, " EAP Packet: code %d, id %d, type %d\n", -+ pucEapol[4], pucEapol[5], pucEapol[7]); -+ break; -+ case EVENT_TX: -+ DBGLOG(TX, INFO, " EAP Packet: code %d, id %d, type %d\n", -+ pucEapol[4], pucEapol[5], pucEapol[7]); -+ break; -+ case EVENT_TX_DONE: -+ DBGLOG(TX, INFO, " EAP Packet: code %d, id %d, type %d\n", -+ status, pucEapol[4], pucEapol[5], pucEapol[7]); -+ break; -+ } -+ break; -+ case 1: /* eapol start */ -+ switch (eventType) { -+ case EVENT_RX: -+ DBGLOG(RX, INFO, " EAPOL: start\n"); -+ break; -+ case EVENT_TX: -+ DBGLOG(TX, INFO, " EAPOL: start\n"); -+ break; -+ case EVENT_TX_DONE: -+ DBGLOG(TX, INFO, " EAPOL: start\n", status); -+ break; -+ } -+ break; -+ case 3: /* key */ -+ { -+ UINT_16 u2KeyInfo = pucEapol[5]<<8 | pucEapol[6]; -+ -+ switch (eventType) { -+ case EVENT_RX: -+ DBGLOG(RX, INFO, -+ " EAPOL: key, KeyInfo 0x%04x, Nonce %02x%02x%02x%02x%02x%02x%02x%02x...\n", -+ u2KeyInfo, pucEapol[17], pucEapol[18], pucEapol[19], pucEapol[20], -+ pucEapol[21], pucEapol[22], pucEapol[23], pucEapol[24]); -+ break; -+ case EVENT_TX: -+ DBGLOG(TX, INFO, -+ " EAPOL: key, KeyInfo 0x%04x, Nonce %02x%02x%02x%02x%02x%02x%02x%02x...\n", -+ u2KeyInfo, -+ pucEapol[17], pucEapol[18], pucEapol[19], pucEapol[20], -+ pucEapol[21], pucEapol[22], pucEapol[23], pucEapol[24]); -+ break; -+ case EVENT_TX_DONE: -+ DBGLOG(TX, INFO, -+ " EAPOL: key, KeyInfo 0x%04x, Nonce %02x%02x%02x%02x%02x%02x%02x%02x...\n", -+ status, u2KeyInfo, pucEapol[17], pucEapol[18], pucEapol[19], -+ pucEapol[20], pucEapol[21], pucEapol[22], pucEapol[23], pucEapol[24]); -+ break; -+ } -+ -+ break; -+ } -+ } -+ break; -+ } -+ case ETH_WPI_1X: -+ { -+ UINT_8 ucSubType = pucEthBody[3]; /* sub type filed*/ -+ UINT_16 u2Length = *(PUINT_16)&pucEthBody[6]; -+ UINT_16 u2Seq = *(PUINT_16)&pucEthBody[8]; -+ -+ switch (eventType) { -+ case EVENT_RX: -+ DBGLOG(RX, INFO, " WAPI: subType %d, Len %d, Seq %d\n", -+ ucSubType, u2Length, u2Seq); -+ break; -+ case EVENT_TX: -+ DBGLOG(TX, INFO, " WAPI: subType %d, Len %d, Seq %d\n", -+ ucSubType, u2Length, u2Seq); -+ break; -+ case EVENT_TX_DONE: -+ DBGLOG(TX, INFO, " WAPI: subType %d, Len %d, Seq %d\n", -+ status, ucSubType, u2Length, u2Seq); -+ break; -+ } -+ break; -+ } -+ } -+} -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to display rx packet information. -+* -+* \param[in] pPkt Pointer to the packet -+* \param[out] None -+* -+* \retval None -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID StatsRxPktInfoDisplay(UINT_8 *pPkt) -+{ -+ statsParsePktInfo(pPkt, 0, EVENT_RX, NULL); -+#if 0 /* carefully! too many ARP */ -+ if (pucIpHdr[0] == 0x00) { /* ARP */ -+ UINT_8 *pucDstIp = (UINT_8 *) pucIpHdr; -+ -+ if (pucDstIp[7] == ARP_PRO_REQ) { -+ DBGLOG(RX, TRACE, " OS rx a arp req from %d.%d.%d.%d\n", -+ pucDstIp[14], pucDstIp[15], pucDstIp[16], pucDstIp[17]); -+ } else if (pucDstIp[7] == ARP_PRO_RSP) { -+ DBGLOG(RX, TRACE, " OS rx a arp rsp from %d.%d.%d.%d\n", -+ pucDstIp[24], pucDstIp[25], pucDstIp[26], pucDstIp[27]); -+ } -+ } -+#endif -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to display tx packet information. -+* -+* \param[in] pPkt Pointer to the packet -+* \param[out] None -+* -+* \retval None -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID StatsTxPktCallBack(UINT_8 *pPkt, P_MSDU_INFO_T prMsduInfo) -+{ -+ UINT_16 u2EtherTypeLen; -+ -+ u2EtherTypeLen = (pPkt[ETH_TYPE_LEN_OFFSET] << 8) | (pPkt[ETH_TYPE_LEN_OFFSET + 1]); -+ statsParsePktInfo(pPkt, 0, EVENT_TX, prMsduInfo); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to handle display tx packet tx done information. -+* -+* \param[in] pPkt Pointer to the packet -+* \param[out] None -+* -+* \retval None -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID StatsTxPktDoneInfoDisplay(ADAPTER_T *prAdapter, UINT_8 *pucEvtBuf) -+{ -+ EVENT_TX_DONE_STATUS_T *prTxDone; -+ -+ prTxDone = (EVENT_TX_DONE_STATUS_T *) pucEvtBuf; -+ /* -+ * Why 65 Bytes: -+ * 8B + wlanheader(40B) + hif_tx_header(16B) + 6B + 6B(LLC) - 12B -+ */ -+ statsParsePktInfo(&prTxDone->aucPktBuf[64], prTxDone->ucStatus, EVENT_TX_DONE, NULL); -+} -+ -+VOID StatsSetCfgTxDone(UINT_16 u2Cfg, BOOLEAN fgSet) -+{ -+ if (fgSet) -+ su2TxDoneCfg |= u2Cfg; -+ else -+ su2TxDoneCfg &= ~u2Cfg; -+} -+ -+UINT_16 StatsGetCfgTxDone(VOID) -+{ -+ return su2TxDoneCfg; -+} -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/swcr.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/swcr.c -new file mode 100644 -index 000000000000..67eccbda9fa8 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/swcr.c -@@ -0,0 +1,1170 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/swcr.c#1 -+*/ -+ -+/*! \file "swcr.c" -+ \brief -+ -+*/ -+ -+/* -+** Log: swcr.c -+ * -+ * 06 04 2012 tsaiyuan.hsu -+ * [WCXRP00001249] [ALPS.ICS] Daily build warning on "wlan/mgmt/swcr.c#1" -+ * resolve build waring for "WNM_UNIT_TEST not defined". -+ * -+ * 03 02 2012 terry.wu -+ * NULL -+ * Sync CFG80211 modification from branch 2,2. -+ * -+ * 01 05 2012 tsaiyuan.hsu -+ * [WCXRP00001157] [MT6620 Wi-Fi][FW][DRV] add timing measurement support for 802.11v -+ * add timing measurement support for 802.11v. -+ * -+ * 11 22 2011 tsaiyuan.hsu -+ * [WCXRP00001083] [MT6620 Wi-Fi][DRV]] dump debug counter or frames when debugging is triggered -+ * keep debug counter setting after wake up. -+ * -+ * 11 15 2011 cm.chang -+ * NULL -+ * Fix compiling warning -+ * -+ * 11 11 2011 tsaiyuan.hsu -+ * [WCXRP00001083] [MT6620 Wi-Fi][DRV]] dump debug counter or frames when debugging is triggered -+ * fix debug counters of rx in driver. -+ * -+ * 11 11 2011 tsaiyuan.hsu -+ * [WCXRP00001083] [MT6620 Wi-Fi][DRV]] dump debug counter or frames when debugging is triggered -+ * add debug counters of bb and ar for xlog. -+ * -+ * 11 10 2011 eddie.chen -+ * [WCXRP00001096] [MT6620 Wi-Fi][Driver/FW] Enhance the log function (xlog) -+ * Modify the QM xlog level and remove LOG_FUNC. -+ * -+ * 11 08 2011 tsaiyuan.hsu -+ * [WCXRP00001083] [MT6620 Wi-Fi][DRV]] dump debug counter or frames when debugging is triggered -+ * add debug counters, eCurPsProf, for PS. -+ * -+ * 11 07 2011 tsaiyuan.hsu -+ * [WCXRP00001083] [MT6620 Wi-Fi][DRV]] dump debug counter or frames when debugging is triggered -+ * add debug counters and periodically dump counters for debugging. -+ * -+ * 11 03 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * change the DBGLOG for "\n" and "\r\n". LABEL to LOUD for XLOG -+ * -+ * 08 31 2011 tsaiyuan.hsu -+ * [WCXRP00000931] [MT5931 Wi-Fi][DRV/FW] add swcr to disable roaming from driver -+ * remove obsolete code. -+ * -+ * 08 15 2011 tsaiyuan.hsu -+ * [WCXRP00000931] [MT5931 Wi-Fi][DRV/FW] add swcr to disable roaming from driver -+ * add swcr in driver reg, 0x9fxx0000, to disable roaming . -+ * -+ * 05 11 2011 eddie.chen -+ * [WCXRP00000709] [MT6620 Wi-Fi][Driver] Check free number before copying broadcast packet -+ * Fix dest type when GO packet copying. -+ * -+ * 05 09 2011 eddie.chen -+ * [WCXRP00000709] [MT6620 Wi-Fi][Driver] Check free number before copying broadcast packet -+ * Check free number before copying broadcast packet. -+ * -+ * 04 14 2011 eddie.chen -+ * [WCXRP00000603] [MT6620 Wi-Fi][DRV] Fix Klocwork warning -+ * Check the SW RFB free. Fix the compile warning.. -+ * -+ * 04 12 2011 eddie.chen -+ * [WCXRP00000617] [MT6620 Wi-Fi][DRV/FW] Fix for sigma -+ * Fix the sta index in processing security frame -+ * Simple flow control for TC4 to avoid mgt frames for PS STA to occupy the TC4 -+ * Add debug message. -+ * -+ * 03 28 2011 eddie.chen -+ * [WCXRP00000603] [MT6620 Wi-Fi][DRV] Fix Klocwork warning -+ * Fix Klockwork warning. -+ * -+ * 03 15 2011 eddie.chen -+ * [WCXRP00000554] [MT6620 Wi-Fi][DRV] Add sw control debug counter -+ * Add sw debug counter for QM. -+ * -+ * 01 11 2011 eddie.chen -+ * [WCXRP00000322] Add WMM IE in beacon, -+Add per station flow control when STA is in PS -+ -+ * Add swcr for test. -+ * -+* -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "precomp.h" -+ -+#if CFG_SUPPORT_SWCR -+ -+#ifdef __GNUC__ -+#pragma GCC diagnostic ignored "-Wformat" -+#endif -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+#if 0 -+SWCR_MOD_MAP_ENTRY_T g_arSwCrAllMaps[] = { -+ {SWCR_MAP_NUM(g_arRlmArSwCrMap), g_arRlmArSwCrMap}, /* 0x00nn */ -+ {0, NULL} -+}; -+#endif -+ -+UINT_32 g_au4SwCr[SWCR_CR_NUM]; /*: 0: command other: data */ -+ -+/* JB mDNS Filter*/ -+UINT_32 g_u4mDNSRXFilter = 0; /* [31] 0: stop 1: start, [3] IPv6 [2] IPv4 */ -+ -+static TIMER_T g_rSwcrDebugTimer; -+static BOOLEAN g_fgSwcrDebugTimer = FALSE; -+static UINT_32 g_u4SwcrDebugCheckTimeout; -+static ENUM_SWCR_DBG_TYPE_T g_ucSwcrDebugCheckType; -+static UINT_32 g_u4SwcrDebugFrameDumpType; -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+#define TEST_PS 1 -+ -+static const PFN_CMD_RW_T g_arSwCtrlCmd[] = { -+ swCtrlCmdCategory0, -+ swCtrlCmdCategory1 -+#if TEST_PS -+ , testPsCmdCategory0, testPsCmdCategory1 -+#endif -+#if CFG_SUPPORT_802_11V -+#if (CFG_SUPPORT_802_11V_TIMING_MEASUREMENT == 1) && (WNM_UNIT_TEST == 1) -+ , testWNMCmdCategory0 -+#endif -+#endif -+}; -+ -+const PFN_SWCR_RW_T g_arSwCrModHandle[] = { -+ swCtrlSwCr, -+ NULL -+}; -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+enum { -+ SWCTRL_MAGIC, -+ SWCTRL_DEBUG, -+ SWCTRL_WIFI_VAR, -+ SWCTRL_ENABLE_INT, -+ SWCTRL_DISABLE_INT, -+ SWCTRL_TXM_INFO, -+ SWCTRL_RXM_INFO, -+ SWCTRL_DUMP_BSS, -+ SWCTRL_QM_INFO, -+ SWCTRL_DUMP_ALL_QUEUE_LEN, -+ SWCTRL_DUMP_MEM, -+ SWCTRL_TX_CTRL_INFO, -+ SWCTRL_DUMP_QUEUE, -+ SWCTRL_DUMP_QM_DBG_CNT, -+ SWCTRL_QM_DBG_CNT, -+ SWCTRL_RX_PKTS_DUMP, -+ SWCTRL_RX_MDNS_FILTER, -+ SWCTRL_CATA0_INDEX_NUM -+}; -+ -+enum { -+ SWCTRL_STA_INFO, -+ SWCTRL_DUMP_STA, -+ SWCTRL_STA_QUE_INFO, -+ SWCTRL_CATA1_INDEX_NUM -+}; -+ -+/* JB mDNS Filter*/ -+#define RX_MDNS_FILTER_START (1<<31) -+#define RX_MDNS_FILTER_IPV4 (1<<2) -+#define RX_MDNS_FILTER_IPV6 (1<<3) -+typedef enum _ENUM_SWCR_RX_MDNS_FILTER_CMD_T { -+ SWCR_RX_MDNS_FILTER_CMD_STOP = 0, -+ SWCR_RX_MDNS_FILTER_CMD_START, -+ SWCR_RX_MDNS_FILTER_CMD_ADD, -+ SWCR_RX_MDNS_FILTER_CMD_REMOVE, -+ SWCR_RX_MDNS_FILTER_NUM -+} ENUM_SWCR_RX_MDNS_FILTER_CMD_T; -+ -+#if TEST_PS -+enum { -+ TEST_PS_MAGIC, -+ TEST_PS_SETUP_BSS, -+ TEST_PS_ENABLE_BEACON, -+ TEST_PS_TRIGGER_BMC, -+ TEST_PS_SEND_NULL, -+ TEST_PS_BUFFER_BMC, -+ TEST_PS_UPDATE_BEACON, -+ TEST_PS_CATA0_INDEX_NUM -+}; -+ -+enum { -+ TEST_PS_STA_PS, -+ TEST_PS_STA_ENTER_PS, -+ TEST_PS_STA_EXIT_PS, -+ TEST_PS_STA_TRIGGER_PSPOLL, -+ TEST_PS_STA_TRIGGER_FRAME, -+ TEST_PS_CATA1_INDEX_NUM -+}; -+#endif -+ -+#if CFG_SUPPORT_802_11V -+#if WNM_UNIT_TEST -+enum { -+ TEST_WNM_TIMING_MEAS, -+ TEST_WNM_CATA0_INDEX_NUM -+}; -+#endif -+#endif -+ -+#define _SWCTRL_MAGIC 0x66201642 -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+void dumpQueue(P_ADAPTER_T prAdapter) -+{ -+ -+ P_TX_CTRL_T prTxCtrl; -+ P_QUE_MGT_T prQM; -+ P_GLUE_INFO_T prGlueInfo; -+ UINT_32 i; -+ UINT_32 j; -+ -+ DEBUGFUNC("dumpQueue"); -+ -+ prTxCtrl = &prAdapter->rTxCtrl; -+ prQM = &prAdapter->rQM; -+ prGlueInfo = prAdapter->prGlueInfo; -+ -+ for (i = TC0_INDEX; i <= TC5_INDEX; i++) { -+ DBGLOG(SW4, INFO, "TC %u\n", i); -+ DBGLOG(SW4, INFO, "Max %u Free %u\n", -+ prTxCtrl->rTc.aucMaxNumOfBuffer[i], prTxCtrl->rTc.aucFreeBufferCount[i]); -+ -+ DBGLOG(SW4, INFO, "Average %u minReserved %u CurrentTcResource %u GuaranteedTcResource %u\n", -+ QM_GET_TX_QUEUE_LEN(prAdapter, i), -+ prQM->au4MinReservedTcResource[i], -+ prQM->au4CurrentTcResource[i], prQM->au4GuaranteedTcResource[i]); -+ -+ } -+ -+ for (i = 0; i < NUM_OF_PER_STA_TX_QUEUES; i++) { -+ DBGLOG(SW4, INFO, -+ "TC %u HeadStaIdx %u ForwardCount %u\n", i, prQM->au4HeadStaRecIndex[i], -+ prQM->au4ForwardCount[i]); -+ } -+ -+ DBGLOG(SW4, INFO, "BMC or unknown TxQueue Len %u\n", prQM->arTxQueue[0].u4NumElem); -+ DBGLOG(SW4, INFO, "Pending %d\n", prGlueInfo->i4TxPendingFrameNum); -+ DBGLOG(SW4, INFO, "Pending Security %d\n", prGlueInfo->i4TxPendingSecurityFrameNum); -+#if defined(LINUX) -+ for (i = 0; i < 4; i++) { -+ for (j = 0; j < CFG_MAX_TXQ_NUM; j++) { -+ DBGLOG(SW4, INFO, -+ "Pending Q[%u][%u] %d\n", i, j, prGlueInfo->ai4TxPendingFrameNumPerQueue[i][j]); -+ } -+ } -+#endif -+ -+ DBGLOG(SW4, INFO, " rFreeSwRfbList %u\n", prAdapter->rRxCtrl.rFreeSwRfbList.u4NumElem); -+ DBGLOG(SW4, INFO, " rReceivedRfbList %u\n", prAdapter->rRxCtrl.rReceivedRfbList.u4NumElem); -+ DBGLOG(SW4, INFO, " rIndicatedRfbList %u\n", prAdapter->rRxCtrl.rIndicatedRfbList.u4NumElem); -+ DBGLOG(SW4, INFO, " ucNumIndPacket %u\n", prAdapter->rRxCtrl.ucNumIndPacket); -+ DBGLOG(SW4, INFO, " ucNumRetainedPacket %u\n", prAdapter->rRxCtrl.ucNumRetainedPacket); -+ -+} -+ -+void dumpSTA(P_ADAPTER_T prAdapter, P_STA_RECORD_T prStaRec) -+{ -+ UINT_8 ucWTEntry; -+ UINT_32 i; -+ P_BSS_INFO_T prBssInfo; -+ -+ DEBUGFUNC("dumpSTA"); -+ -+ ASSERT(prStaRec); -+ ucWTEntry = prStaRec->ucWTEntry; -+ -+ prBssInfo = &prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]; -+ ASSERT(prBssInfo); -+ -+ DBGLOG(SW4, INFO, "Mac address: %pM Rcpi %u" "\n", prStaRec->aucMacAddr, prStaRec->ucRCPI); -+ -+ DBGLOG(SW4, INFO, "Idx %u Wtbl %u Used %u State %u Bss Phy 0x%x Sta DesiredPhy 0x%x\n", -+ prStaRec->ucIndex, ucWTEntry, -+ prStaRec->fgIsInUse, prStaRec->ucStaState, -+ prBssInfo->ucPhyTypeSet, prStaRec->ucDesiredPhyTypeSet); -+ -+ DBGLOG(SW4, INFO, "Sta Operation 0x%x DesiredNontHtRateSet 0x%x Mcs 0x%x u2HtCapInfo 0x%x\n", -+ prStaRec->u2OperationalRateSet, prStaRec->u2DesiredNonHTRateSet, prStaRec->ucMcsSet, -+ prStaRec->u2HtCapInfo); -+ -+ for (i = 0; i < NUM_OF_PER_STA_TX_QUEUES; i++) -+ DBGLOG(SW4, INFO, "TC %u Queue Len %u\n", i, prStaRec->arTxQueue[i].u4NumElem); -+ -+ DBGLOG(SW4, INFO, "BmpDeliveryAC %x\n", prStaRec->ucBmpDeliveryAC); -+ DBGLOG(SW4, INFO, "BmpTriggerAC %x\n", prStaRec->ucBmpTriggerAC); -+ DBGLOG(SW4, INFO, "UapsdSpSupproted %u\n", prStaRec->fgIsUapsdSupported); -+ DBGLOG(SW4, INFO, "IsQoS %u\n", prStaRec->fgIsQoS); -+ DBGLOG(SW4, INFO, "AssocId %u\n", prStaRec->u2AssocId); -+ -+ DBGLOG(SW4, INFO, "fgIsInPS %u\n", prStaRec->fgIsInPS); -+ DBGLOG(SW4, INFO, "ucFreeQuota %u\n", prStaRec->ucFreeQuota); -+ DBGLOG(SW4, INFO, "ucFreeQuotaForDelivery %u\n", prStaRec->ucFreeQuotaForDelivery); -+ DBGLOG(SW4, INFO, "ucFreeQuotaForNonDelivery %u\n", prStaRec->ucFreeQuotaForNonDelivery); -+ -+#if 0 -+ DBGLOG(SW4, INFO, "IsQmmSup %u\n", prStaRec->fgIsWmmSupported); -+ DBGLOG(SW4, INFO, "IsUapsdSup %u\n", prStaRec->fgIsUapsdSupported); -+ DBGLOG(SW4, INFO, "AvailabaleDeliverPkts %u\n", prStaRec->ucAvailableDeliverPkts); -+ DBGLOG(SW4, INFO, "BmpDeliverPktsAC %u\n", prStaRec->u4BmpDeliverPktsAC); -+ DBGLOG(SW4, INFO, "BmpBufferAC %u\n", prStaRec->u4BmpBufferAC); -+ DBGLOG(SW4, INFO, "BmpNonDeliverPktsAC %u\n", prStaRec->u4BmpNonDeliverPktsAC); -+#endif -+ -+ for (i = 0; i < CFG_RX_MAX_BA_TID_NUM; i++) { -+ if (prStaRec->aprRxReorderParamRefTbl[i]) { -+ DBGLOG(SW4, INFO, -+ "RxReorder fgIsValid: %u\n", prStaRec->aprRxReorderParamRefTbl[i]->fgIsValid); -+ DBGLOG(SW4, INFO, "RxReorder Tid: %u\n", prStaRec->aprRxReorderParamRefTbl[i]->ucTid); -+ DBGLOG(SW4, INFO, -+ "RxReorder rReOrderQue Len: %u\n", -+ prStaRec->aprRxReorderParamRefTbl[i]->rReOrderQue.u4NumElem); -+ DBGLOG(SW4, INFO, -+ "RxReorder WinStart: %u\n", prStaRec->aprRxReorderParamRefTbl[i]->u2WinStart); -+ DBGLOG(SW4, INFO, "RxReorder WinEnd: %u\n", prStaRec->aprRxReorderParamRefTbl[i]->u2WinEnd); -+ DBGLOG(SW4, INFO, "RxReorder WinSize: %u\n", prStaRec->aprRxReorderParamRefTbl[i]->u2WinSize); -+ } -+ } -+ -+} -+ -+VOID dumpBss(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo) -+{ -+ -+ DBGLOG(SW4, INFO, "SSID %s\n", prBssInfo->aucSSID); -+ DBGLOG(SW4, INFO, "OWN %pM\n", prBssInfo->aucOwnMacAddr); -+ DBGLOG(SW4, INFO, "BSSID %pM\n", prBssInfo->aucBSSID); -+ DBGLOG(SW4, INFO, "ucNetTypeIndex %u\n", prBssInfo->ucNetTypeIndex); -+ DBGLOG(SW4, INFO, "eConnectionState %u\n", prBssInfo->eConnectionState); -+ DBGLOG(SW4, INFO, "eCurrentOPMode %u\n", prBssInfo->eCurrentOPMode); -+ DBGLOG(SW4, INFO, "fgIsQBSS %u\n", prBssInfo->fgIsQBSS); -+ DBGLOG(SW4, INFO, "fgIsShortPreambleAllowed %u\n", prBssInfo->fgIsShortPreambleAllowed); -+ DBGLOG(SW4, INFO, "fgUseShortPreamble %u\n", prBssInfo->fgUseShortPreamble); -+ DBGLOG(SW4, INFO, "fgUseShortSlotTime %u\n", prBssInfo->fgUseShortSlotTime); -+ DBGLOG(SW4, INFO, "ucNonHTBasicPhyType %x\n", prBssInfo->ucNonHTBasicPhyType); -+ DBGLOG(SW4, INFO, "u2OperationalRateSet %x\n", prBssInfo->u2OperationalRateSet); -+ DBGLOG(SW4, INFO, "u2BSSBasicRateSet %x\n", prBssInfo->u2BSSBasicRateSet); -+ DBGLOG(SW4, INFO, "ucPhyTypeSet %x\n", prBssInfo->ucPhyTypeSet); -+ DBGLOG(SW4, INFO, "rStaRecOfClientList %d\n", prBssInfo->rStaRecOfClientList.u4NumElem); -+ DBGLOG(SW4, INFO, "u2CapInfo %x\n", prBssInfo->u2CapInfo); -+ DBGLOG(SW4, INFO, "u2ATIMWindow %x\n", prBssInfo->u2ATIMWindow); -+ DBGLOG(SW4, INFO, "u2AssocId %x\n", prBssInfo->u2AssocId); -+ DBGLOG(SW4, INFO, "ucDTIMPeriod %x\n", prBssInfo->ucDTIMPeriod); -+ DBGLOG(SW4, INFO, "ucDTIMCount %x\n", prBssInfo->ucDTIMCount); -+ DBGLOG(SW4, INFO, "fgIsNetAbsent %x\n", prBssInfo->fgIsNetAbsent); -+ DBGLOG(SW4, INFO, "eBand %d\n", prBssInfo->eBand); -+ DBGLOG(SW4, INFO, "ucPrimaryChannel %d\n", prBssInfo->ucPrimaryChannel); -+ DBGLOG(SW4, INFO, "ucHtOpInfo1 %d\n", prBssInfo->ucHtOpInfo1); -+ DBGLOG(SW4, INFO, "ucHtOpInfo2 %d\n", prBssInfo->u2HtOpInfo2); -+ DBGLOG(SW4, INFO, "ucHtOpInfo3 %d\n", prBssInfo->u2HtOpInfo3); -+ DBGLOG(SW4, INFO, "fgErpProtectMode %d\n", prBssInfo->fgErpProtectMode); -+ DBGLOG(SW4, INFO, "eHtProtectMode %d\n", prBssInfo->eHtProtectMode); -+ DBGLOG(SW4, INFO, "eGfOperationMode %d\n", prBssInfo->eGfOperationMode); -+ DBGLOG(SW4, INFO, "eRifsOperationMode %d\n", prBssInfo->eRifsOperationMode); -+ DBGLOG(SW4, INFO, "fgObssErpProtectMode %d\n", prBssInfo->fgObssErpProtectMode); -+ DBGLOG(SW4, INFO, "eObssHtProtectMode %d\n", prBssInfo->eObssHtProtectMode); -+ DBGLOG(SW4, INFO, "eObssGfProtectMode %d\n", prBssInfo->eObssGfOperationMode); -+ DBGLOG(SW4, INFO, "fgObssRifsOperationMode %d\n", prBssInfo->fgObssRifsOperationMode); -+ DBGLOG(SW4, INFO, "fgAssoc40mBwAllowed %d\n", prBssInfo->fgAssoc40mBwAllowed); -+ DBGLOG(SW4, INFO, "fg40mBwAllowed %d\n", prBssInfo->fg40mBwAllowed); -+ DBGLOG(SW4, INFO, "eBssSCO %d\n", prBssInfo->eBssSCO); -+ -+} -+ -+VOID swCtrlCmdCategory0(P_ADAPTER_T prAdapter, UINT_8 ucCate, UINT_8 ucAction, UINT_8 ucOpt0, UINT_8 ucOpt1) -+{ -+ UINT_8 ucIndex, ucRead; -+ UINT_32 i; -+ -+ DEBUGFUNC("swCtrlCmdCategory0"); -+ -+ SWCR_GET_RW_INDEX(ucAction, ucRead, ucIndex); -+ -+ i = 0; -+ -+ if (ucIndex >= SWCTRL_CATA0_INDEX_NUM) -+ return; -+ -+ if (ucRead == SWCR_WRITE) { -+ switch (ucIndex) { -+ case SWCTRL_DEBUG: -+#if DBG -+ aucDebugModule[ucOpt0] = (UINT_8) g_au4SwCr[1]; -+#endif -+ break; -+ case SWCTRL_WIFI_VAR: -+ break; -+ -+#if QM_DEBUG_COUNTER -+ case SWCTRL_DUMP_QM_DBG_CNT: -+ for (i = 0; i < QM_DBG_CNT_NUM; i++) -+ prAdapter->rQM.au4QmDebugCounters[i] = 0; -+ break; -+ case SWCTRL_QM_DBG_CNT: -+ prAdapter->rQM.au4QmDebugCounters[ucOpt0] = g_au4SwCr[1]; -+ -+ break; -+#endif -+#if CFG_RX_PKTS_DUMP -+ case SWCTRL_RX_PKTS_DUMP: -+ /* DBGLOG(SW4, INFO,("SWCTRL_RX_PKTS_DUMP: mask %x\n", g_au4SwCr[1])); */ -+ prAdapter->rRxCtrl.u4RxPktsDumpTypeMask = g_au4SwCr[1]; -+ break; -+#endif -+ case SWCTRL_RX_MDNS_FILTER: -+ { -+ UINT_32 u4rxfilter; -+ BOOLEAN fgUpdate = FALSE; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ -+ if (ucOpt0 == SWCR_RX_MDNS_FILTER_CMD_STOP) { -+ g_u4mDNSRXFilter &= ~(RX_MDNS_FILTER_START); -+ -+ u4rxfilter = prAdapter->u4OsPacketFilter; -+ fgUpdate = TRUE; -+ } else if (ucOpt0 == SWCR_RX_MDNS_FILTER_CMD_START) { -+ g_u4mDNSRXFilter |= (RX_MDNS_FILTER_START); -+ -+ u4rxfilter = prAdapter->u4OsPacketFilter; -+ if ((g_u4mDNSRXFilter & RX_MDNS_FILTER_IPV4) || -+ (g_u4mDNSRXFilter & RX_MDNS_FILTER_IPV6)) { -+ u4rxfilter |= PARAM_PACKET_FILTER_ALL_MULTICAST; -+ } -+ fgUpdate = TRUE; -+ } else if (ucOpt0 == SWCR_RX_MDNS_FILTER_CMD_ADD) { -+ if (ucOpt1 < 31) -+ g_u4mDNSRXFilter |= (1 << ucOpt1); -+ } else if (ucOpt0 == SWCR_RX_MDNS_FILTER_CMD_REMOVE) { -+ if (ucOpt1 < 31) -+ g_u4mDNSRXFilter &= ~(1 << ucOpt1); -+ } -+ -+ if (fgUpdate == TRUE) { -+ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ -+ CMD_ID_SET_RX_FILTER, /* ucCID */ -+ TRUE, /* fgSetQuery */ -+ FALSE, /* fgNeedResp */ -+ FALSE, /* fgIsOid */ -+ NULL, /* pfCmdDoneHandler */ -+ NULL, /* pfCmdTimeoutHandler */ -+ sizeof(UINT_32), /* u4SetQueryInfoLen */ -+ (PUINT_8)&u4rxfilter, /* pucInfoBuffer */ -+ NULL, /* pvSetQueryBuffer */ -+ 0 /* un4SetQueryBufferLen */ -+ ); -+ } -+/* DBGLOG(SW4, INFO,("SWCTRL_RX_MDNS_FILTER: g_u4mDNSRXFilter %x ucOpt0 %x ucOpt1 %x fgUpdate %x u4rxfilter %x, */ -+/* rStatus %x\n", g_u4mDNSRXFilter, ucOpt0, ucOpt1, fgUpdate, u4rxfilter, rStatus)); */ -+ } -+ break; -+ default: -+ break; -+ } -+ } else { -+ switch (ucIndex) { -+ case SWCTRL_DEBUG: -+#if DBG -+ g_au4SwCr[1] = aucDebugModule[ucOpt0]; -+#endif -+ break; -+ case SWCTRL_MAGIC: -+ g_au4SwCr[1] = _SWCTRL_MAGIC; -+ /* DBGLOG(SW4, INFO, "BUILD TIME: %s %s\n", __DATE__, __TIME__); */ -+ break; -+ case SWCTRL_QM_INFO: -+ { -+ P_QUE_MGT_T prQM = &prAdapter->rQM; -+ -+ switch (ucOpt0) { -+ case 0: -+ g_au4SwCr[1] = (QM_GET_TX_QUEUE_LEN(prAdapter, ucOpt1)); -+ g_au4SwCr[2] = prQM->au4MinReservedTcResource[ucOpt1]; -+ g_au4SwCr[3] = prQM->au4CurrentTcResource[ucOpt1]; -+ g_au4SwCr[4] = prQM->au4GuaranteedTcResource[ucOpt1]; -+ break; -+ -+ case 1: -+ g_au4SwCr[1] = prQM->au4ForwardCount[ucOpt1]; -+ g_au4SwCr[2] = prQM->au4HeadStaRecIndex[ucOpt1]; -+ break; -+ -+ case 2: -+ g_au4SwCr[1] = prQM->arTxQueue[ucOpt1].u4NumElem; /* only one */ -+ -+ break; -+ } -+ -+ } -+ break; -+ case SWCTRL_TX_CTRL_INFO: -+ { -+ P_TX_CTRL_T prTxCtrl; -+ -+ prTxCtrl = &prAdapter->rTxCtrl; -+ switch (ucOpt0) { -+ case 0: -+ g_au4SwCr[1] = prAdapter->rTxCtrl.rTc.aucFreeBufferCount[ucOpt1]; -+ g_au4SwCr[2] = prAdapter->rTxCtrl.rTc.aucMaxNumOfBuffer[ucOpt1]; -+ break; -+ } -+ -+ } -+ break; -+ case SWCTRL_DUMP_QUEUE: -+ dumpQueue(prAdapter); -+ -+ break; -+#if QM_DEBUG_COUNTER -+ case SWCTRL_DUMP_QM_DBG_CNT: -+ for (i = 0; i < QM_DBG_CNT_NUM; i++) -+ DBGLOG(SW4, INFO, "QM:DBG %u %u\n", i, prAdapter->rQM.au4QmDebugCounters[i]); -+ break; -+ -+ case SWCTRL_QM_DBG_CNT: -+ g_au4SwCr[1] = prAdapter->rQM.au4QmDebugCounters[ucOpt0]; -+ break; -+#endif -+ case SWCTRL_DUMP_BSS: -+ { -+ dumpBss(prAdapter, &(prAdapter->rWifiVar.arBssInfo[ucOpt0])); -+ } -+ break; -+ -+ default: -+ break; -+ } -+ -+ } -+} -+ -+VOID swCtrlCmdCategory1(P_ADAPTER_T prAdapter, UINT_8 ucCate, UINT_8 ucAction, UINT_8 ucOpt0, UINT_8 ucOpt1) -+{ -+ UINT_8 ucIndex, ucRead; -+ UINT_8 ucWTEntry; -+ P_STA_RECORD_T prStaRec; -+ -+ DEBUGFUNC("swCtrlCmdCategory1"); -+ -+ SWCR_GET_RW_INDEX(ucAction, ucRead, ucIndex); -+ -+ if (ucOpt0 >= CFG_STA_REC_NUM) -+ return; -+ -+ /* prStaRec = cnmGetStaRecByIndex (prAdapter, ucOpt0); */ -+ prStaRec = &prAdapter->arStaRec[ucOpt0]; -+ ucWTEntry = prStaRec->ucWTEntry; -+ if (ucRead == SWCR_WRITE) { -+ /* Do nothing */ -+ } else { -+ /* Read */ -+ switch (ucIndex) { -+ case SWCTRL_STA_QUE_INFO: -+ { -+ g_au4SwCr[1] = prStaRec->arTxQueue[ucOpt1].u4NumElem; -+ } -+ break; -+ case SWCTRL_STA_INFO: -+ switch (ucOpt1) { -+ case 0: -+ g_au4SwCr[1] = prStaRec->fgIsInPS; -+ break; -+ } -+ -+ break; -+ -+ case SWCTRL_DUMP_STA: -+ { -+ dumpSTA(prAdapter, prStaRec); -+ } -+ break; -+ -+ default: -+ -+ break; -+ } -+ } -+ -+} -+ -+#if TEST_PS -+ -+VOID -+testPsSendQoSNullFrame(IN P_ADAPTER_T prAdapter, -+ IN P_STA_RECORD_T prStaRec, -+ IN UINT_8 ucUP, -+ IN UINT_8 ucNetTypeIndex, -+ IN BOOLEAN fgBMC, -+ IN BOOLEAN fgIsBurstEnd, IN BOOLEAN ucPacketType, IN BOOLEAN ucPsSessionID, IN BOOLEAN fgSetEOSP) -+{ -+ P_MSDU_INFO_T prMsduInfo; -+ UINT_16 u2EstimatedFrameLen; -+ P_WLAN_MAC_HEADER_QOS_T prQoSNullFrame; -+ -+ DEBUGFUNC("testPsSendQoSNullFrame"); -+ DBGLOG(SW4, LOUD, "\n"); -+ -+ /* 4 <1> Allocate a PKT_INFO_T for Null Frame */ -+ /* Init with MGMT Header Length */ -+ u2EstimatedFrameLen = MAC_TX_RESERVED_FIELD + WLAN_MAC_HEADER_QOS_LEN; -+ -+ /* Allocate a MSDU_INFO_T */ -+ prMsduInfo = cnmMgtPktAlloc(prAdapter, u2EstimatedFrameLen); -+ if (prMsduInfo == NULL) { -+ DBGLOG(SW4, WARN, "No PKT_INFO_T for sending Null Frame.\n"); -+ return; -+ } -+ /* 4 <2> Compose Null frame in MSDU_INfO_T. */ -+ bssComposeQoSNullFrame(prAdapter, -+ (PUINT_8) ((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD), -+ prStaRec, ucUP, fgSetEOSP); -+ -+ prMsduInfo->eSrc = TX_PACKET_MGMT; -+ /* prMsduInfo->ucPacketType = HIF_TX_PACKET_TYPE_DATA; */ -+ prMsduInfo->ucPacketType = ucPacketType; -+ prMsduInfo->ucStaRecIndex = prStaRec->ucIndex; -+ prMsduInfo->ucNetworkType = ucNetTypeIndex; -+ prMsduInfo->ucMacHeaderLength = WLAN_MAC_HEADER_QOS_LEN; -+ prMsduInfo->fgIs802_1x = FALSE; -+ prMsduInfo->fgIs802_11 = TRUE; -+ prMsduInfo->u2FrameLength = WLAN_MAC_HEADER_QOS_LEN; -+ prMsduInfo->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter); -+ prMsduInfo->pfTxDoneHandler = NULL; -+ prMsduInfo->fgIsBasicRate = TRUE; -+ prMsduInfo->fgIsBurstEnd = fgIsBurstEnd; -+ prMsduInfo->ucUserPriority = ucUP; -+ prMsduInfo->ucPsSessionID = ucPsSessionID /* 0~7 Test 7 means NOACK */; -+ -+ prQoSNullFrame = (P_WLAN_MAC_HEADER_QOS_T) (((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD)); -+ -+ if (fgBMC) -+ prQoSNullFrame->aucAddr1[0] = 0xfd; -+ else -+ prQoSNullFrame->aucAddr1[5] = 0xdd; -+ -+ /* 4 <4> Inform TXM to send this Null frame. */ -+ nicTxEnqueueMsdu(prAdapter, prMsduInfo); -+ -+} -+ -+VOID testPsSetupBss(IN P_ADAPTER_T prAdapter, IN UINT_8 ucNetworkTypeIndex) -+{ -+ P_BSS_INFO_T prBssInfo; -+ UINT_8 _aucZeroMacAddr[] = NULL_MAC_ADDR; -+ -+ DEBUGFUNC("testPsSetupBss()"); -+ DBGLOG(SW4, INFO, "index %d\n", ucNetworkTypeIndex); -+ -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[ucNetworkTypeIndex]); -+ -+ /* 4 <1.2> Initiate PWR STATE */ -+ /* SET_NET_PWR_STATE_IDLE(prAdapter, ucNetworkTypeIndex); */ -+ -+ /* 4 <2> Initiate BSS_INFO_T - common part */ -+ BSS_INFO_INIT(prAdapter, ucNetworkTypeIndex); -+ -+ prBssInfo->eConnectionState = PARAM_MEDIA_STATE_DISCONNECTED; -+ prBssInfo->eConnectionStateIndicated = PARAM_MEDIA_STATE_DISCONNECTED; -+ prBssInfo->eCurrentOPMode = OP_MODE_ACCESS_POINT; -+ prBssInfo->fgIsNetActive = TRUE; -+ prBssInfo->ucNetTypeIndex = (ucNetworkTypeIndex); -+ prBssInfo->ucReasonOfDisconnect = DISCONNECT_REASON_CODE_RESERVED; -+ -+ prBssInfo->ucPhyTypeSet = PHY_TYPE_SET_802_11BG; /* Depend on eBand */ -+ prBssInfo->ucConfigAdHocAPMode = AP_MODE_MIXED_11BG; /* Depend on eCurrentOPMode and ucPhyTypeSet */ -+ prBssInfo->u2BSSBasicRateSet = RATE_SET_ERP; -+ prBssInfo->u2OperationalRateSet = RATE_SET_OFDM; -+ prBssInfo->fgErpProtectMode = FALSE; -+ prBssInfo->fgIsQBSS = TRUE; -+ -+ /* 4 <1.5> Setup MIB for current BSS */ -+ prBssInfo->u2BeaconInterval = 100; -+ prBssInfo->ucDTIMPeriod = DOT11_DTIM_PERIOD_DEFAULT; -+ prBssInfo->u2ATIMWindow = 0; -+ -+ prBssInfo->ucBeaconTimeoutCount = 0; -+ -+ bssInitForAP(prAdapter, prBssInfo, TRUE); -+ -+ COPY_MAC_ADDR(prBssInfo->aucBSSID, _aucZeroMacAddr); -+ LINK_INITIALIZE(&prBssInfo->rStaRecOfClientList); -+ prBssInfo->fgIsBeaconActivated = TRUE; -+ prBssInfo->ucHwDefaultFixedRateCode = RATE_CCK_1M_LONG; -+ -+ COPY_MAC_ADDR(prBssInfo->aucOwnMacAddr, prAdapter->rWifiVar.aucMacAddress); -+ -+ /* 4 <3> Initiate BSS_INFO_T - private part */ -+ /* TODO */ -+ prBssInfo->eBand = BAND_2G4; -+ prBssInfo->ucPrimaryChannel = 1; -+ prBssInfo->prStaRecOfAP = (P_STA_RECORD_T) NULL; -+ -+ /* prBssInfo->fgErpProtectMode = eErpProectMode; */ -+ /* prBssInfo->eHtProtectMode = eHtProtectMode; */ -+ /* prBssInfo->eGfOperationMode = eGfOperationMode; */ -+ -+ /* 4 <4> Allocate MSDU_INFO_T for Beacon */ -+ prBssInfo->prBeacon = cnmMgtPktAlloc(prAdapter, OFFSET_OF(WLAN_BEACON_FRAME_T, aucInfoElem[0]) + MAX_IE_LENGTH); -+ -+ if (prBssInfo->prBeacon) { -+ prBssInfo->prBeacon->eSrc = TX_PACKET_MGMT; -+ prBssInfo->prBeacon->ucNetworkType = ucNetworkTypeIndex; -+ } else { -+ DBGLOG(SW4, INFO, "prBeacon allocation fail\n"); -+ } -+ -+#if 0 -+ prBssInfo->rPmProfSetupInfo.ucBmpDeliveryAC = PM_UAPSD_ALL; -+ prBssInfo->rPmProfSetupInfo.ucBmpTriggerAC = PM_UAPSD_ALL; -+ prBssInfo->rPmProfSetupInfo.ucUapsdSp = WMM_MAX_SP_LENGTH_2; -+#else -+ prBssInfo->rPmProfSetupInfo.ucBmpDeliveryAC = (UINT_8) prAdapter->u4UapsdAcBmp; -+ prBssInfo->rPmProfSetupInfo.ucBmpTriggerAC = (UINT_8) prAdapter->u4UapsdAcBmp; -+ prBssInfo->rPmProfSetupInfo.ucUapsdSp = (UINT_8) prAdapter->u4MaxSpLen; -+#endif -+ -+#if 0 -+ for (eAci = 0; eAci < WMM_AC_INDEX_NUM; eAci++) { -+ -+ prBssInfo->arACQueParms[eAci].fgIsACMSet = FALSE; -+ prBssInfo->arACQueParms[eAci].u2Aifsn = (UINT_16) eAci; -+ prBssInfo->arACQueParms[eAci].u2CWmin = 7; -+ prBssInfo->arACQueParms[eAci].u2CWmax = 31; -+ prBssInfo->arACQueParms[eAci].u2TxopLimit = eAci + 1; -+ DBGLOG(SW4, INFO, "MQM: eAci = %d, ACM = %d, Aifsn = %d, CWmin = %d, CWmax = %d, TxopLimit = %d\n", -+ eAci, prBssInfo->arACQueParms[eAci].fgIsACMSet, -+ prBssInfo->arACQueParms[eAci].u2Aifsn, -+ prBssInfo->arACQueParms[eAci].u2CWmin, -+ prBssInfo->arACQueParms[eAci].u2CWmax, prBssInfo->arACQueParms[eAci].u2TxopLimit)); -+ -+ } -+#endif -+ -+ DBGLOG(SW4, INFO, "[2] ucBmpDeliveryAC:0x%x, ucBmpTriggerAC:0x%x, ucUapsdSp:0x%x", -+ prBssInfo->rPmProfSetupInfo.ucBmpDeliveryAC, -+ prBssInfo->rPmProfSetupInfo.ucBmpTriggerAC, prBssInfo->rPmProfSetupInfo.ucUapsdSp); -+ -+} -+ -+VOID testPsCmdCategory0(P_ADAPTER_T prAdapter, UINT_8 ucCate, UINT_8 ucAction, UINT_8 ucOpt0, UINT_8 ucOpt1) -+{ -+ UINT_8 ucIndex, ucRead; -+ P_STA_RECORD_T prStaRec; -+ -+ DEBUGFUNC("testPsCmdCategory0"); -+ SWCR_GET_RW_INDEX(ucAction, ucRead, ucIndex); -+ -+ DBGLOG(SW4, LOUD, "Read %u Index %u\n", ucRead, ucIndex); -+ -+ prStaRec = cnmGetStaRecByIndex(prAdapter, 0); -+ -+ if (ucIndex >= TEST_PS_CATA0_INDEX_NUM) -+ return; -+ -+ if (ucRead == SWCR_WRITE) { -+ switch (ucIndex) { -+ case TEST_PS_SETUP_BSS: -+ testPsSetupBss(prAdapter, ucOpt0); -+ break; -+ -+ case TEST_PS_ENABLE_BEACON: -+ break; -+ -+ case TEST_PS_TRIGGER_BMC: -+ /* txmForwardQueuedBmcPkts (ucOpt0); */ -+ break; -+ case TEST_PS_SEND_NULL: -+ { -+ -+ testPsSendQoSNullFrame(prAdapter, prStaRec, (UINT_8) (g_au4SwCr[1] & 0xFF), /* UP */ -+ ucOpt0, (BOOLEAN) ((g_au4SwCr[1] >> 8) & 0xFF), /* BMC */ -+ (BOOLEAN) ((g_au4SwCr[1] >> 16) & 0xFF), /* BurstEnd */ -+ (BOOLEAN) ((g_au4SwCr[1] >> 24) & 0xFF), /* Packet type */ -+ (UINT_8) ((g_au4SwCr[2]) & 0xFF), /* PS sesson ID 7: NOACK */ -+ FALSE /* EOSP */ -+ ); -+ } -+ break; -+ case TEST_PS_BUFFER_BMC: -+ /* g_aprBssInfo[ucOpt0]->fgApToBufferBMC = (g_au4SwCr[1] & 0xFF); */ -+ break; -+ case TEST_PS_UPDATE_BEACON: -+ bssUpdateBeaconContent(prAdapter, ucOpt0 /*networktype */); -+ break; -+ -+ default: -+ break; -+ } -+ } else { -+ switch (ucIndex) { -+ -+ case TEST_PS_MAGIC: -+ g_au4SwCr[1] = 0x88660011; -+ break; -+ -+ } -+ } -+} -+ -+#endif /* TEST_PS */ -+ -+#if TEST_PS -+ -+VOID testPsCmdCategory1(P_ADAPTER_T prAdapter, UINT_8 ucCate, UINT_8 ucAction, UINT_8 ucOpt0, UINT_8 ucOpt1) -+{ -+ UINT_8 ucIndex, ucRead; -+ UINT_8 ucWTEntry; -+ P_STA_RECORD_T prStaRec; -+ -+ DEBUGFUNC("testPsCmdCategory1"); -+ -+ SWCR_GET_RW_INDEX(ucAction, ucRead, ucIndex); -+ -+ if (ucOpt0 >= CFG_STA_REC_NUM) -+ return; -+ -+ prStaRec = cnmGetStaRecByIndex(prAdapter, ucOpt0); -+ if (!prStaRec) -+ return; -+ ucWTEntry = prStaRec->ucWTEntry; -+ if (ucRead == SWCR_WRITE) { -+ -+ switch (ucIndex) { -+ case TEST_PS_STA_PS: -+ prStaRec->fgIsInPS = (BOOLEAN) (g_au4SwCr[1] & 0x1); -+ prStaRec->fgIsQoS = (BOOLEAN) (g_au4SwCr[1] >> 8 & 0xFF); -+ prStaRec->fgIsUapsdSupported = (BOOLEAN) (g_au4SwCr[1] >> 16 & 0xFF); -+ prStaRec->ucBmpDeliveryAC = (BOOLEAN) (g_au4SwCr[1] >> 24 & 0xFF); -+ break; -+ -+ } -+ -+ } else { -+ /* Read */ -+ switch (ucIndex) { -+ default: -+ break; -+ } -+ } -+ -+} -+ -+#endif /* TEST_PS */ -+ -+#if CFG_SUPPORT_802_11V -+#if (CFG_SUPPORT_802_11V_TIMING_MEASUREMENT == 1) && (WNM_UNIT_TEST == 1) -+VOID testWNMCmdCategory0(P_ADAPTER_T prAdapter, UINT_8 ucCate, UINT_8 ucAction, UINT_8 ucOpt0, UINT_8 ucOpt1) -+{ -+ UINT_8 ucIndex, ucRead; -+ P_STA_RECORD_T prStaRec; -+ -+ DEBUGFUNC("testWNMCmdCategory0"); -+ SWCR_GET_RW_INDEX(ucAction, ucRead, ucIndex); -+ -+ DBGLOG(SW4, INFO, "Read %u Index %u\n", ucRead, ucIndex); -+ -+ if (ucIndex >= TEST_WNM_CATA0_INDEX_NUM) -+ return; -+ -+ if (ucRead == SWCR_WRITE) { -+ switch (ucIndex) { -+ case TEST_WNM_TIMING_MEAS: -+ wnmTimingMeasUnitTest1(prAdapter, ucOpt0); -+ break; -+ -+ default: -+ break; -+ } -+ } -+} -+#endif /* TEST_WNM */ -+#endif /* CFG_SUPPORT_802_11V */ -+ -+VOID swCtrlSwCr(P_ADAPTER_T prAdapter, UINT_8 ucRead, UINT_16 u2Addr, UINT_32 *pu4Data) -+{ -+ /* According other register STAIDX */ -+ UINT_8 ucOffset; -+ -+ ucOffset = (u2Addr >> 2) & 0x3F; -+ -+ if (ucOffset >= SWCR_CR_NUM) -+ return; -+ -+ if (ucRead == SWCR_WRITE) { -+ g_au4SwCr[ucOffset] = *pu4Data; -+ if (ucOffset == 0x0) { -+ /* Commmand [31:24]: Category */ -+ /* Commmand [23:23]: 1(W) 0(R) */ -+ /* Commmand [22:16]: Index */ -+ /* Commmand [15:08]: Option0 */ -+ /* Commmand [07:00]: Option1 */ -+ UINT_8 ucCate; -+ UINT_32 u4Cmd; -+ -+ u4Cmd = g_au4SwCr[0]; -+ ucCate = (UINT_8) (u4Cmd >> 24); -+ if (ucCate < sizeof(g_arSwCtrlCmd) / sizeof(g_arSwCtrlCmd[0])) { -+ if (g_arSwCtrlCmd[ucCate] != NULL) { -+ g_arSwCtrlCmd[ucCate] (prAdapter, ucCate, (UINT_8) (u4Cmd >> 16 & 0xFF), -+ (UINT_8) ((u4Cmd >> 8) & 0xFF), (UINT_8) (u4Cmd & 0xFF)); -+ } -+ } -+ } -+ } else { -+ *pu4Data = g_au4SwCr[ucOffset]; -+ } -+} -+ -+VOID swCrReadWriteCmd(P_ADAPTER_T prAdapter, UINT_8 ucRead, UINT_16 u2Addr, UINT_32 *pu4Data) -+{ -+ UINT_8 ucMod; -+ -+ ucMod = u2Addr >> 8; -+ /* Address [15:8] MOD ID */ -+ /* Address [7:0] OFFSET */ -+ -+ DEBUGFUNC("swCrReadWriteCmd"); -+ DBGLOG(SW4, TRACE, "%u addr 0x%x data 0x%x\n", ucRead, u2Addr, *pu4Data); -+ -+ if (ucMod < (sizeof(g_arSwCrModHandle) / sizeof(g_arSwCrModHandle[0]))) { -+ -+ if (g_arSwCrModHandle[ucMod] != NULL) -+ g_arSwCrModHandle[ucMod] (prAdapter, ucRead, u2Addr, pu4Data); -+ } /* ucMod */ -+} -+ -+/* Debug Support */ -+VOID swCrFrameCheckEnable(P_ADAPTER_T prAdapter, UINT_32 u4DumpType) -+{ -+ g_u4SwcrDebugFrameDumpType = u4DumpType; -+ prAdapter->rRxCtrl.u4RxPktsDumpTypeMask = u4DumpType; -+} -+ -+VOID swCrDebugInit(P_ADAPTER_T prAdapter) -+{ -+ /* frame dump */ -+ if (g_u4SwcrDebugFrameDumpType) -+ swCrFrameCheckEnable(prAdapter, g_u4SwcrDebugFrameDumpType); -+ /* debug counter */ -+ g_fgSwcrDebugTimer = FALSE; -+ -+ cnmTimerInitTimer(prAdapter, &g_rSwcrDebugTimer, (PFN_MGMT_TIMEOUT_FUNC) swCrDebugCheckTimeout, (ULONG) NULL); -+ -+ if (g_u4SwcrDebugCheckTimeout) -+ swCrDebugCheckEnable(prAdapter, TRUE, g_ucSwcrDebugCheckType, g_u4SwcrDebugCheckTimeout); -+} -+ -+VOID swCrDebugUninit(P_ADAPTER_T prAdapter) -+{ -+ cnmTimerStopTimer(prAdapter, &g_rSwcrDebugTimer); -+ -+ g_fgSwcrDebugTimer = FALSE; -+} -+ -+VOID swCrDebugCheckEnable(P_ADAPTER_T prAdapter, BOOLEAN fgIsEnable, UINT_8 ucType, UINT_32 u4Timeout) -+{ -+ if (fgIsEnable) { -+ g_ucSwcrDebugCheckType = ucType; -+ g_u4SwcrDebugCheckTimeout = u4Timeout; -+ if (g_fgSwcrDebugTimer == FALSE) -+ swCrDebugCheckTimeout(prAdapter, 0); -+ } else { -+ cnmTimerStopTimer(prAdapter, &g_rSwcrDebugTimer); -+ g_u4SwcrDebugCheckTimeout = 0; -+ } -+ -+ g_fgSwcrDebugTimer = fgIsEnable; -+} -+ -+VOID swCrDebugCheck(P_ADAPTER_T prAdapter, P_CMD_SW_DBG_CTRL_T prCmdSwCtrl) -+{ -+ P_RX_CTRL_T prRxCtrl; -+ P_TX_CTRL_T prTxCtrl; -+ -+ ASSERT(prAdapter); -+ -+ prTxCtrl = &prAdapter->rTxCtrl; -+ prRxCtrl = &prAdapter->rRxCtrl; -+ -+ /* dump counters */ -+ if (prCmdSwCtrl) { -+ if (prCmdSwCtrl->u4Data == SWCR_DBG_TYPE_ALL) { -+ -+ /* TX Counter from fw */ -+ DBGLOG(SW4, INFO, "TX0\n" -+ "%08x %08x %08x %08x\n" -+ "%08x %08x %08x %08x\n", -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_TX_CNT], -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_TX_BCN_CNT], -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_TX_FAILED_CNT], -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_TX_RETRY_CNT], -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_TX_AGING_TIMEOUT_CNT], -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_TX_PS_OVERFLOW_CNT], -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_TX_MGNT_DROP_CNT], -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_TX_ERROR_CNT]); -+#if 1 -+ /* TX Counter from drv */ -+ DBGLOG(SW4, INFO, "TX1\n" -+ "%08x %08x %08x %08x\n", -+ (UINT_32) TX_GET_CNT(prTxCtrl, TX_INACTIVE_BSS_DROP), -+ (UINT_32) TX_GET_CNT(prTxCtrl, TX_INACTIVE_STA_DROP), -+ (UINT_32) TX_GET_CNT(prTxCtrl, TX_FORWARD_OVERFLOW_DROP), -+ (UINT_32) TX_GET_CNT(prTxCtrl, TX_AP_BORADCAST_DROP)); -+#endif -+ -+ /* RX Counter */ -+ DBGLOG(SW4, INFO, "RX0\n" -+ "%08x %08x %08x %08x\n" -+ "%08x %08x %08x %08x\n" -+ "%08x %08x %08x %08x\n" -+ "%08x %08x %08x %08x\n", -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_RX_CNT], -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_RX_DROP_CNT], -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_RX_DUP_DROP_CNT], -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_RX_TYPE_ERROR_DROP_CNT], -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_RX_CLASS_ERROR_DROP_CNT], -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_RX_AMPDU_ERROR_DROP_CNT], -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_RX_STATUS_ERROR_DROP_CNT], -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_RX_FORMAT_ERROR_DROP_CNT], -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_RX_ICV_ERROR_DROP_CNT], -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_RX_KEY_ERROR_DROP_CNT], -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_RX_TKIP_ERROR_DROP_CNT], -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_RX_MIC_ERROR_DROP_CNT], -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_RX_BIP_ERROR_DROP_CNT], -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_RX_FCSERR_CNT], -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_RX_FIFOFULL_CNT], -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_RX_PFDROP_CNT]); -+ -+ DBGLOG(SW4, INFO, "RX1\n" -+ "%08x %08x %08x %08x\n" -+ "%08x %08x %08x %08x\n", -+ (UINT_32) RX_GET_CNT(prRxCtrl, RX_MPDU_TOTAL_COUNT), -+ (UINT_32) RX_GET_CNT(prRxCtrl, RX_DATA_INDICATION_COUNT), -+ (UINT_32) RX_GET_CNT(prRxCtrl, RX_DATA_RETURNED_COUNT), -+ (UINT_32) RX_GET_CNT(prRxCtrl, RX_DATA_RETAINED_COUNT), -+ (UINT_32) RX_GET_CNT(prRxCtrl, RX_DROP_TOTAL_COUNT), -+ (UINT_32) RX_GET_CNT(prRxCtrl, RX_TYPE_ERR_DROP_COUNT), -+ (UINT_32) RX_GET_CNT(prRxCtrl, RX_CLASS_ERR_DROP_COUNT), -+ (UINT_32) RX_GET_CNT(prRxCtrl, RX_DST_NULL_DROP_COUNT)); -+ -+ DBGLOG(SW4, INFO, "PWR\n" -+ "%08x %08x %08x %08x\n" -+ "%08x %08x %08x %08x\n", -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_PWR_PS_POLL_CNT], -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_PWR_TRIGGER_NULL_CNT], -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_PWR_BCN_IND_CNT], -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_PWR_BCN_TIMEOUT_CNT], -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_PWR_PM_STATE0], -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_PWR_PM_STATE1], -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_PWR_CUR_PS_PROF0], -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_PWR_CUR_PS_PROF1]); -+ -+ DBGLOG(SW4, INFO, "ARM\n" -+ "%08x %08x %08x %08x\n" -+ "%08x %08x\n", -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_AR_STA0_RATE], -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_AR_STA0_BWGI], -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_AR_STA0_RX_RATE_RCPI], -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_ROAMING_ENABLE], -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_ROAMING_ROAM_CNT], -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_ROAMING_INT_CNT]); -+ -+ DBGLOG(SW4, INFO, "BB\n" -+ "%08x %08x %08x %08x\n" -+ "%08x %08x %08x %08x\n", -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_BB_RX_MDRDY_CNT], -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_BB_RX_FCSERR_CNT], -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_BB_CCK_PD_CNT], -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_BB_OFDM_PD_CNT], -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_BB_CCK_SFDERR_CNT], -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_BB_CCK_SIGERR_CNT], -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_BB_OFDM_TAGERR_CNT], -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_BB_OFDM_SIGERR_CNT]); -+ -+ } -+ } -+ /* start the next check */ -+ if (g_u4SwcrDebugCheckTimeout) -+ cnmTimerStartTimer(prAdapter, &g_rSwcrDebugTimer, g_u4SwcrDebugCheckTimeout * MSEC_PER_SEC); -+} -+ -+VOID swCrDebugCheckTimeout(IN P_ADAPTER_T prAdapter, ULONG ulParam) -+{ -+ CMD_SW_DBG_CTRL_T rCmdSwCtrl; -+ WLAN_STATUS rStatus; -+ -+ rCmdSwCtrl.u4Id = (0xb000 << 16) + g_ucSwcrDebugCheckType; -+ rCmdSwCtrl.u4Data = 0; -+ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ -+ CMD_ID_SW_DBG_CTRL, /* ucCID */ -+ FALSE, /* fgSetQuery */ -+ TRUE, /* fgNeedResp */ -+ FALSE, /* fgIsOid */ -+ swCrDebugQuery, /* pfCmdDoneHandler */ -+ swCrDebugQueryTimeout, /* pfCmdTimeoutHandler */ -+ sizeof(CMD_SW_DBG_CTRL_T), /* u4SetQueryInfoLen */ -+ (PUINT_8)&rCmdSwCtrl, /* pucInfoBuffer */ -+ NULL, /* pvSetQueryBuffer */ -+ 0 /* u4SetQueryBufferLen */ -+ ); -+ -+ ASSERT(rStatus == WLAN_STATUS_PENDING); -+ -+} -+ -+VOID swCrDebugQuery(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) -+{ -+ ASSERT(prAdapter); -+ -+ swCrDebugCheck(prAdapter, (P_CMD_SW_DBG_CTRL_T) (pucEventBuf)); -+} -+ -+VOID swCrDebugQueryTimeout(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo) -+{ -+ ASSERT(prAdapter); -+ -+ swCrDebugCheck(prAdapter, NULL); -+} -+ -+#endif /* CFG_SUPPORT_SWCR */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/tdls.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/tdls.c -new file mode 100644 -index 000000000000..96293c57e2b0 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/tdls.c -@@ -0,0 +1,5199 @@ -+/* -+** Id: tdls.c#1 -+*/ -+ -+/*! \file tdls.c -+ \brief This file includes IEEE802.11z TDLS support. -+*/ -+ -+/* -+** Log: tdls.c -+ * -+ * 11 13 2013 vend_samp.lin -+ * NULL -+ * Initial version. -+ */ -+ -+/******************************************************************************* -+ * C O M P I L E R F L A G S -+ ******************************************************************************** -+ */ -+ -+/******************************************************************************* -+ * E X T E R N A L R E F E R E N C E S -+ ******************************************************************************** -+ */ -+#include "precomp.h" -+ -+#if (CFG_SUPPORT_TDLS == 1) -+#include "gl_wext.h" -+#include "tdls.h" -+#include "gl_cfg80211.h" -+#include -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+static VOID TdlsCmdTestRxIndicatePkts(GLUE_INFO_T *prGlueInfo, struct sk_buff *prSkb); -+ -+#if TDLS_CFG_CMD_TEST -+static void TdlsCmdTestAddPeer(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); -+ -+static void TdlsCmdTestChSwProhibitedBitSet(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); -+ -+static void TdlsCmdTestChSwReqRecv(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); -+ -+static void TdlsCmdTestChSwRspRecv(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); -+ -+static void TdlsCmdTestChSwTimeoutSkip(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); -+ -+static void TdlsCmdTestDataContSend(GLUE_INFO_T *prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); -+ -+static void TdlsCmdTestDataRecv(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); -+ -+static void TdlsCmdTestDataSend(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); -+ -+static void TdlsCmdTestDelay(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); -+ -+static void TdlsCmdTestDiscoveryReqRecv(GLUE_INFO_T *prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); -+ -+static void TdlsCmdTestKeepAliveSkip(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); -+ -+static void TdlsCmdTestProhibitedBitSet(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); -+ -+static void TdlsCmdTestPtiReqRecv(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); -+ -+static void TdlsCmdTestPtiRspRecv(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); -+ -+static void TdlsCmdTestPtiTxDoneFail(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); -+ -+static void TdlsCmdTestRvFrame(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); -+ -+static void TdlsCmdTestSetupConfirmRecv(GLUE_INFO_T *prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); -+ -+static void TdlsCmdTestSetupReqRecv(GLUE_INFO_T *prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); -+ -+static void TdlsCmdTestSetupRspRecv(GLUE_INFO_T *prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); -+ -+static void TdlsCmdTestScanCtrl(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); -+ -+static void TdlsCmdTestTearDownRecv(GLUE_INFO_T *prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); -+ -+static void TdlsCmdTestTxFailSkip(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); -+ -+static void TdlsCmdTestTxTdlsFrame(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); -+ -+static void TdlsCmdTestTxFrame(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); -+ -+static TDLS_STATUS -+TdlsCmdTestTxFmeSetupReqBufTranslate(UINT_8 *pCmdBuf, UINT_32 u4BufLen, PARAM_CUSTOM_TDLS_CMD_STRUCT_T *prCmd); -+ -+static void TdlsCmdTestUpdatePeer(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); -+ -+static void TdlsCmdTestNullRecv(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); -+ -+static VOID TdlsTimerTestDataContSend(ADAPTER_T *prAdapter, UINT_32 u4Param); -+ -+static TDLS_STATUS -+TdlsTestChStReqRecv(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen); -+ -+static TDLS_STATUS -+TdlsTestChStRspRecv(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen); -+ -+static TDLS_STATUS -+TdlsTestFrameSend(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen); -+ -+static TDLS_STATUS -+TdlsTestNullRecv(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen); -+ -+static TDLS_STATUS -+TdlsTestPtiReqRecv(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen); -+ -+static TDLS_STATUS -+TdlsTestPtiRspRecv(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen); -+ -+static TDLS_STATUS -+TdlsTestTearDownRecv(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen); -+ -+static TDLS_STATUS -+TdlsTestDataRecv(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen); -+ -+static TDLS_STATUS -+TdlsTestPtiTxFail(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen); -+ -+static TDLS_STATUS -+TdlsTestTdlsFrameSend(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen); -+ -+static TDLS_STATUS -+TdlsTestTxFailSkip(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen); -+ -+static TDLS_STATUS -+TdlsTestKeepAliveSkip(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen); -+ -+static TDLS_STATUS -+TdlsTestChSwTimeoutSkip(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen); -+ -+static TDLS_STATUS -+TdlsTestScanSkip(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen); -+ -+static TDLS_STATUS -+TdlsChSwConf(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen); -+ -+static void TdlsCmdChSwConf(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); -+ -+static void TdlsCmdInfoDisplay(GLUE_INFO_T *prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); -+ -+static void TdlsCmdKeyInfoDisplay(GLUE_INFO_T *prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); -+ -+static void TdlsCmdMibParamUpdate(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); -+ -+static void TdlsCmdSetupConf(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); -+ -+static void TdlsCmdUapsdConf(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); -+ -+static TDLS_STATUS -+TdlsInfoDisplay(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen); -+ -+static TDLS_STATUS -+TdlsKeyInfoDisplay(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen); -+ -+static VOID -+TdlsLinkHistoryRecord(GLUE_INFO_T *prGlueInfo, -+ BOOLEAN fgIsTearDown, -+ UINT8 *pucPeerMac, BOOLEAN fgIsFromUs, UINT16 u2ReasonCode, VOID *prOthers); -+ -+static VOID -+TdlsLinkHistoryRecordUpdate(GLUE_INFO_T *prGlueInfo, -+ UINT8 *pucPeerMac, TDLS_EVENT_HOST_SUBID_SPECIFIC_FRAME eFmeStatus, VOID *pInfo); -+ -+static TDLS_STATUS -+TdlsMibParamUpdate(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen); -+ -+static TDLS_STATUS -+TdlsSetupConf(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen); -+ -+static TDLS_STATUS -+TdlsUapsdConf(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen); -+ -+static void TdlsEventStatistics(GLUE_INFO_T *prGlueInfo, UINT8 *prInBuf, UINT32 u4InBufLen); -+ -+static void TdlsEventTearDown(GLUE_INFO_T *prGlueInfo, UINT8 *prInBuf, UINT32 u4InBufLen); -+ -+#endif /* TDLS_CFG_CMD_TEST */ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+static BOOLEAN fgIsPtiTimeoutSkip = FALSE; -+ -+/******************************************************************************* -+* P R I V A T E F U N C T I O N S -+******************************************************************************** -+*/ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to indicate packets to upper layer. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prSkb A pointer to the received packet -+* -+* \retval None -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static VOID TdlsCmdTestRxIndicatePkts(GLUE_INFO_T *prGlueInfo, struct sk_buff *prSkb) -+{ -+ struct net_device *prNetDev; -+ -+ /* init */ -+ prNetDev = prGlueInfo->prDevHandler; -+ prGlueInfo->rNetDevStats.rx_bytes += prSkb->len; -+ prGlueInfo->rNetDevStats.rx_packets++; -+ -+ /* pass to upper layer */ -+ //prNetDev->last_rx = jiffies; -+ prSkb->protocol = eth_type_trans(prSkb, prNetDev); -+ prSkb->dev = prNetDev; -+ -+ if (!in_interrupt()) -+ netif_rx_ni(prSkb); /* only in non-interrupt context */ -+ else -+ netif_rx(prSkb); -+} -+ -+#if TDLS_CFG_CMD_TEST -+ -+#define LR_TDLS_FME_FIELD_FILL(__Len) \ -+do { \ -+ pPkt += __Len; \ -+ u4PktLen += __Len; \ -+} while (0) -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to add a TDLS peer. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prInBuf A pointer to the command string buffer -+* \param[in] u4InBufLen The length of the buffer -+* \param[out] None -+* -+* \retval None -+* -+* EX: iwpriv wlan0 set_str_cmd 0_2_[Responder MAC] -+ -+ iwpriv wlan0 set_str_cmd 0_2_00:11:22:33:44:01 -+*/ -+/*----------------------------------------------------------------------------*/ -+static void TdlsCmdTestAddPeer(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) -+{ -+ PARAM_CUSTOM_TDLS_CMD_STRUCT_T rCmd; -+ struct wireless_dev *prWdev; -+ -+ /* reset */ -+ kalMemZero(&rCmd, sizeof(rCmd)); -+ -+ /* parse arguments */ -+ CmdStringMacParse(prInBuf, &prInBuf, &u4InBufLen, rCmd.arRspAddr); -+ -+ /* init */ -+ rCmd.rPeerInfo.supported_rates = NULL; -+ rCmd.rPeerInfo.ht_capa = &rCmd.rHtCapa; -+ rCmd.rPeerInfo.vht_capa = &rCmd.rVhtCapa; /* LINUX_KERNEL_VERSION >= 3.10.0 */ -+ rCmd.rPeerInfo.sta_flags_set = BIT(NL80211_STA_FLAG_TDLS_PEER); -+ -+ /* send command to wifi task to handle */ -+ prWdev = prGlueInfo->prDevHandler->ieee80211_ptr; -+ mtk_cfg80211_add_station(prWdev->wiphy, (void *)0x1, rCmd.arRspAddr, &rCmd.rPeerInfo); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to simulate to set the TDLS Prohibited bit. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prInBuf A pointer to the command string buffer -+* \param[in] u4InBufLen The length of the buffer -+* \param[out] None -+* -+* \retval None -+* -+* EX: iwpriv wlan0 set_str_cmd 0_16_[Enable/Disable]_[Set/Clear] -+ -+ iwpriv wlan0 set_str_cmd 0_16_1_1 -+*/ -+/*----------------------------------------------------------------------------*/ -+static void TdlsCmdTestChSwProhibitedBitSet(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) -+{ -+ TDLS_CMD_CORE_T rCmd; -+ -+ /* parse arguments */ -+ kalMemZero(rCmd.aucPeerMac, sizeof(rCmd.aucPeerMac)); -+ rCmd.Content.rCmdProhibit.fgIsEnable = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ rCmd.Content.rCmdProhibit.fgIsSet = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ -+ DBGLOG(TDLS, INFO, "%s: fgIsEnable = %d\n", __func__, rCmd.Content.rCmdProhibit.fgIsEnable); -+ -+ /* command to do this */ -+ flgTdlsTestExtCapElm = rCmd.Content.rCmdProhibit.fgIsEnable; -+ -+ aucTdlsTestExtCapElm[0] = ELEM_ID_EXTENDED_CAP; -+ aucTdlsTestExtCapElm[1] = 5; -+ aucTdlsTestExtCapElm[2] = 0; -+ aucTdlsTestExtCapElm[3] = 0; -+ aucTdlsTestExtCapElm[4] = 0; -+ aucTdlsTestExtCapElm[5] = 0; -+ aucTdlsTestExtCapElm[6] = (rCmd.Content.rCmdProhibit.fgIsSet << 7); /* bit39 */ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to receive a channel switch request from the peer. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prInBuf A pointer to the command string buffer -+* \param[in] u4InBufLen The length of the buffer -+* \param[out] None -+* -+* \retval None -+* -+* EX: iwpriv wlan0 set_str_cmd 0_1_5_[TDLS Peer MAC]_[Chan]_[RegulatoryClass]_ -+ [SecondaryChannelOffset]_[SwitchTime]_[SwitchTimeout] -+ -+ iwpriv wlan0 set_str_cmd 0_1_5_00:11:22:33:44:01_1_255_0_15000_30000 -+ -+ RegulatoryClass: TODO (reference to Annex I of 802.11n spec.) -+ Secondary Channel Offset: 0 (SCN - no secondary channel) -+ 1 (SCA - secondary channel above) -+ 2 (SCB - secondary channel below) -+ SwitchTime: units of microseconds -+ -+*/ -+/*----------------------------------------------------------------------------*/ -+static void TdlsCmdTestChSwReqRecv(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) -+{ -+ WLAN_STATUS rStatus; -+ TDLS_CMD_CORE_T rCmd; -+ UINT_32 u4BufLen; -+ -+ /* parse arguments */ -+ CmdStringMacParse(prInBuf, &prInBuf, &u4InBufLen, rCmd.aucPeerMac); -+ -+ rCmd.Content.rCmdChStReqRcv.u4Chan = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ rCmd.Content.rCmdChStReqRcv.u4RegClass = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ rCmd.Content.rCmdChStReqRcv.u4SecChanOff = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ rCmd.Content.rCmdChStReqRcv.u4SwitchTime = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ rCmd.Content.rCmdChStReqRcv.u4SwitchTimeout = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ -+ DBGLOG(TDLS, INFO, "%s:[%pM]u4Chan=%u u4RegClass=%u u4SecChanOff=%u u4SwitchTime=%u u4SwitchTimeout=%u\n", -+ __func__, rCmd.aucPeerMac, -+ (UINT32) rCmd.Content.rCmdChStReqRcv.u4Chan, -+ (UINT32) rCmd.Content.rCmdChStReqRcv.u4RegClass, -+ (UINT32) rCmd.Content.rCmdChStReqRcv.u4SecChanOff, -+ (UINT32) rCmd.Content.rCmdChStReqRcv.u4SwitchTime, -+ (UINT32) rCmd.Content.rCmdChStReqRcv.u4SwitchTimeout); -+ -+ /* command to do this */ -+ rStatus = kalIoctl(prGlueInfo, TdlsTestChStReqRecv, &rCmd, sizeof(rCmd), FALSE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ DBGLOG(TDLS, ERROR, "%s kalIoctl fail:%x\n", __func__, rStatus); -+ return; -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to receive a channel switch response from the peer. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prInBuf A pointer to the command string buffer -+* \param[in] u4InBufLen The length of the buffer -+* \param[out] None -+* -+* \retval None -+* -+* EX: iwpriv wlan0 set_str_cmd 0_1_6_[TDLS Peer MAC]_[Chan]_ -+ [SwitchTime]_[SwitchTimeout]_[StatusCode] -+ -+ iwpriv wlan0 set_str_cmd 0_1_6_00:11:22:33:44:01_11_15000_30000_0 -+ -+ RegulatoryClass: TODO (reference to Annex I of 802.11n spec.) -+ Secondary Channel Offset: 0 (SCN - no secondary channel) -+ 1 (SCA - secondary channel above) -+ 2 (SCB - secondary channel below) -+ SwitchTime: units of microseconds -+ -+*/ -+/*----------------------------------------------------------------------------*/ -+static void TdlsCmdTestChSwRspRecv(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) -+{ -+ WLAN_STATUS rStatus; -+ TDLS_CMD_CORE_T rCmd; -+ UINT_32 u4BufLen; -+ -+ /* parse arguments */ -+ CmdStringMacParse(prInBuf, &prInBuf, &u4InBufLen, rCmd.aucPeerMac); -+ -+ rCmd.Content.rCmdChStRspRcv.u4Chan = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ rCmd.Content.rCmdChStRspRcv.u4SwitchTime = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ rCmd.Content.rCmdChStRspRcv.u4SwitchTimeout = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ rCmd.Content.rCmdChStRspRcv.u4StatusCode = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ -+ DBGLOG(TDLS, INFO, "%s: [ %pM ] u4Chan=%u u4SwitchTime=%u u4SwitchTimeout=%u u4StatusCode=%u\n", -+ __func__, rCmd.aucPeerMac, -+ (UINT32) rCmd.Content.rCmdChStRspRcv.u4Chan, -+ (UINT32) rCmd.Content.rCmdChStRspRcv.u4SwitchTime, -+ (UINT32) rCmd.Content.rCmdChStRspRcv.u4SwitchTimeout, -+ (UINT32) rCmd.Content.rCmdChStRspRcv.u4StatusCode); -+ -+ /* command to do this */ -+ rStatus = kalIoctl(prGlueInfo, TdlsTestChStRspRecv, &rCmd, sizeof(rCmd), FALSE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ DBGLOG(TDLS, ERROR, "%s kalIoctl fail:%x\n", __func__, rStatus); -+ return; -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to inform firmware to skip channel switch timeout function. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prInBuf A pointer to the command string buffer -+* \param[in] u4InBufLen The length of the buffer -+* \param[out] None -+* -+* \retval None -+* -+* EX: iwpriv wlan0 set_str_cmd 0_11_[Enable/Disable] -+ -+ iwpriv wlan0 set_str_cmd 0_11_1 -+*/ -+/*----------------------------------------------------------------------------*/ -+static void TdlsCmdTestChSwTimeoutSkip(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) -+{ -+ WLAN_STATUS rStatus; -+ TDLS_CMD_CORE_T rCmd; -+ UINT_32 u4BufLen; -+ -+ /* parse arguments */ -+ kalMemZero(rCmd.aucPeerMac, sizeof(rCmd.aucPeerMac)); -+ rCmd.Content.rCmdKeepAliveSkip.fgIsEnable = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ -+ DBGLOG(TDLS, INFO, "%s: fgIsEnable = %d\n", __func__, rCmd.Content.rCmdKeepAliveSkip.fgIsEnable); -+ -+ /* command to do this */ -+ rStatus = kalIoctl(prGlueInfo, -+ TdlsTestChSwTimeoutSkip, &rCmd, sizeof(rCmd), FALSE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ DBGLOG(TDLS, ERROR, "%s kalIoctl fail:%x\n", __func__, rStatus); -+ return; -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to send a data frame to the peer periodically. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prInBuf A pointer to the command string buffer -+* \param[in] u4InBufLen The length of the buffer -+* \param[out] None -+* -+* \retval None -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static TIMER_T rTdlsTimerTestDataSend; -+static UINT_8 aucTdlsTestDataSPeerMac[6]; -+static UINT_16 u2TdlsTestDataSInterval; -+ -+static void TdlsCmdTestDataContSend(GLUE_INFO_T *prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) -+{ -+ ADAPTER_T *prAdapter; -+ BOOLEAN fgIsEnabled; -+ -+ /* init */ -+ prAdapter = prGlueInfo->prAdapter; -+ -+ /* parse arguments */ -+ CmdStringMacParse(prInBuf, &prInBuf, &u4InBufLen, aucTdlsTestDataSPeerMac); -+ u2TdlsTestDataSInterval = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ fgIsEnabled = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ -+ cnmTimerStopTimer(prAdapter, &rTdlsTimerTestDataSend); -+ -+ if (fgIsEnabled == FALSE) { -+ /* stop test timer */ -+ return; -+ } -+ -+ /* re-init test timer */ -+ cnmTimerInitTimer(prAdapter, -+ &rTdlsTimerTestDataSend, (PFN_MGMT_TIMEOUT_FUNC) TdlsTimerTestDataContSend, (ULONG) NULL); -+ -+ cnmTimerStartTimer(prAdapter, &rTdlsTimerTestDataSend, u2TdlsTestDataSInterval); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to receive a data frame from the peer. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prInBuf A pointer to the command string buffer -+* \param[in] u4InBufLen The length of the buffer -+* \param[out] None -+* -+* \retval None -+* -+* EX: iwpriv wlan0 set_str_cmd 0_0_x80_[TDLS Peer MAC]_[PM]_[UP]_[EOSP]_[IsNull] -+ -+ iwpriv wlan0 set_str_cmd 0_1_x80_00:11:22:33:44:01_0_0_0_0 -+*/ -+/*----------------------------------------------------------------------------*/ -+static void TdlsCmdTestDataRecv(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) -+{ -+ WLAN_STATUS rStatus; -+ TDLS_CMD_CORE_T rCmd; -+ UINT_32 u4BufLen; -+ -+ /* parse arguments */ -+ CmdStringMacParse(prInBuf, &prInBuf, &u4InBufLen, rCmd.aucPeerMac); -+ rCmd.Content.rCmdDatRcv.u4PM = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ rCmd.Content.rCmdDatRcv.u4UP = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ rCmd.Content.rCmdDatRcv.u4EOSP = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ rCmd.Content.rCmdDatRcv.u4IsNull = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ -+ DBGLOG(TDLS, INFO, -+ " %s: [%pM] PM(%u) UP(%u) EOSP(%u) NULL(%u)\n", -+ __func__, rCmd.aucPeerMac, -+ (UINT32) rCmd.Content.rCmdDatRcv.u4PM, -+ (UINT32) rCmd.Content.rCmdDatRcv.u4UP, -+ (UINT32) rCmd.Content.rCmdDatRcv.u4EOSP, (UINT32) rCmd.Content.rCmdDatRcv.u4IsNull); -+ -+ /* command to do this */ -+ rStatus = kalIoctl(prGlueInfo, TdlsTestDataRecv, &rCmd, sizeof(rCmd), FALSE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ DBGLOG(TDLS, ERROR, "%s kalIoctl fail:%x\n", __func__, rStatus); -+ return; -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to send a data frame to the peer. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prInBuf A pointer to the command string buffer -+* \param[in] u4InBufLen The length of the buffer -+* \param[out] None -+* -+* \retval None -+* -+* EX: iwpriv wlan0 set_str_cmd 0_4_[Responder MAC]_[tx status] -+ -+ iwpriv wlan0 set_str_cmd 0_4_00:11:22:33:44:01_0 -+*/ -+/*----------------------------------------------------------------------------*/ -+static void TdlsCmdTestDataSend(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) -+{ -+ P_ADAPTER_T prAdapter; -+ struct sk_buff *prMsduInfo; -+ UINT_8 *prPkt; -+ UINT_8 MAC[6]; -+ UINT_8 ucTxStatus; -+ -+ /* init */ -+ prAdapter = prGlueInfo->prAdapter; -+ -+ /* parse arguments */ -+ CmdStringMacParse(prInBuf, &prInBuf, &u4InBufLen, MAC); -+ ucTxStatus = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ -+ /* allocate a data frame */ -+ prMsduInfo = kalPacketAlloc(prGlueInfo, 1000, &prPkt); -+ if (prMsduInfo == NULL) { -+ DBGLOG(TDLS, ERROR, " %s allocate pkt fail!\n", __func__); -+ return; -+ } -+ -+ /* init dev */ -+ prMsduInfo->dev = prGlueInfo->prDevHandler; -+ if (prMsduInfo->dev == NULL) { -+ DBGLOG(TDLS, ERROR, " %s prMsduInfo->dev == NULL!\n", __func__); -+ kalPacketFree(prGlueInfo, prMsduInfo); -+ return; -+ } -+ -+ /* init packet */ -+ prMsduInfo->len = 1000; -+ kalMemZero(prMsduInfo->data, 100); /* for QoS field */ -+ kalMemCopy(prMsduInfo->data, MAC, 6); -+ kalMemCopy(prMsduInfo->data + 6, prAdapter->rMyMacAddr, 6); -+ *(UINT_16 *) (prMsduInfo->data + 12) = 0x0800; -+ -+ /* simulate OS to send the packet */ -+ wlanHardStartXmit(prMsduInfo, prMsduInfo->dev); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to simulate to set the TDLS Prohibited bit. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prInBuf A pointer to the command string buffer -+* \param[in] u4InBufLen The length of the buffer -+* \param[out] None -+* -+* \retval None -+* -+* EX: iwpriv wlan0 set_str_cmd 0_16_[mili seconds] -+ -+ iwpriv wlan0 set_str_cmd 0_19_1000 -+*/ -+/*----------------------------------------------------------------------------*/ -+static void TdlsCmdTestDelay(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) -+{ -+ UINT32 u4Delay; -+ -+ u4Delay = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ DBGLOG(TDLS, INFO, "%s: Delay = %d\n", __func__, u4Delay); -+ -+ kalMdelay(u4Delay); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to receive a test discovery request frame command. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prInBuf A pointer to the command string buffer -+* \param[in] u4InBufLen The length of the buffer -+* \param[out] None -+* -+* \retval None -+* -+* EX: iwpriv wlan0 set_str_cmd 0_1_10_[DialogToken]_[Peer MAC]_[BSSID] -+ -+ iwpriv wlan0 set_str_cmd 0_1_10_1_00:11:22:33:44:01 -+ iwpriv wlan0 set_str_cmd 0_1_10_1_00:11:22:33:44:01_00:22:33:44:11:22 -+*/ -+/*----------------------------------------------------------------------------*/ -+static void TdlsCmdTestDiscoveryReqRecv(GLUE_INFO_T *prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) -+{ -+ ADAPTER_T *prAdapter; -+ P_BSS_INFO_T prBssInfo; -+ struct sk_buff *prMsduInfo; -+ UINT_8 *pPkt; -+ UINT_32 u4PktLen, u4IeLen; -+ UINT_8 ucDialogToken, aucPeerMac[6], aucBSSID[6], aucZeroMac[6]; -+ -+ /* parse arguments */ -+ ucDialogToken = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ CmdStringMacParse(prInBuf, &prInBuf, &u4InBufLen, aucPeerMac); -+ -+ kalMemZero(aucZeroMac, sizeof(aucZeroMac)); -+ kalMemZero(aucBSSID, sizeof(aucBSSID)); -+ CmdStringMacParse(prInBuf, &prInBuf, &u4InBufLen, aucBSSID); -+ -+ DBGLOG(TDLS, INFO, -+ " %s: DialogToken=%d from %pM\n", __func__, ucDialogToken, aucPeerMac); -+ -+ /* allocate/init packet */ -+ prAdapter = prGlueInfo->prAdapter; -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ u4PktLen = 0; -+ -+ prMsduInfo = kalPacketAlloc(prGlueInfo, 1600, &pPkt); -+ if (prMsduInfo == NULL) { -+ DBGLOG(TDLS, ERROR, " %s: allocate pkt fail\n", __func__); -+ return; -+ } -+ -+ prMsduInfo->dev = prGlueInfo->prDevHandler; -+ if (prMsduInfo->dev == NULL) { -+ DBGLOG(TDLS, ERROR, " %s: MsduInfo->dev == NULL\n", __func__); -+ kalPacketFree(prGlueInfo, prMsduInfo); -+ return; -+ } -+ -+ /* make up frame content */ -+ /* 1. 802.3 header */ -+ kalMemCopy(pPkt, prAdapter->rMyMacAddr, TDLS_FME_MAC_ADDR_LEN); -+ LR_TDLS_FME_FIELD_FILL(TDLS_FME_MAC_ADDR_LEN); -+ kalMemCopy(pPkt, aucPeerMac, TDLS_FME_MAC_ADDR_LEN); -+ LR_TDLS_FME_FIELD_FILL(TDLS_FME_MAC_ADDR_LEN); -+ *(UINT_16 *) pPkt = htons(TDLS_FRM_PROT_TYPE); -+ LR_TDLS_FME_FIELD_FILL(2); -+ -+ /* 2. payload type */ -+ *pPkt = TDLS_FRM_PAYLOAD_TYPE; -+ LR_TDLS_FME_FIELD_FILL(1); -+ -+ /* 3. Frame Formation - (1) Category */ -+ *pPkt = TDLS_FRM_CATEGORY; -+ LR_TDLS_FME_FIELD_FILL(1); -+ -+ /* 3. Frame Formation - (2) Action */ -+ *pPkt = TDLS_FRM_ACTION_DISCOVERY_REQ; -+ LR_TDLS_FME_FIELD_FILL(1); -+ -+ /* 3. Frame Formation - (3) Dialog token */ -+ *pPkt = ucDialogToken; -+ LR_TDLS_FME_FIELD_FILL(1); -+ -+ /* 3. Frame Formation - (16) Link identifier element */ -+ TDLS_LINK_IDENTIFIER_IE(pPkt)->ucId = ELEM_ID_LINK_IDENTIFIER; -+ TDLS_LINK_IDENTIFIER_IE(pPkt)->ucLength = 18; -+ -+ if (kalMemCmp(aucBSSID, aucZeroMac, 6) == 0) -+ kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aBSSID, prBssInfo->aucBSSID, 6); -+ else -+ kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aBSSID, aucBSSID, 6); -+ -+ kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aInitiator, aucPeerMac, 6); -+ kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aResponder, prAdapter->rMyMacAddr, 6); -+ -+ u4IeLen = IE_SIZE(pPkt); -+ LR_TDLS_FME_FIELD_FILL(u4IeLen); -+ -+ /* 4. Update packet length */ -+ prMsduInfo->len = u4PktLen; -+ dumpMemory8(prMsduInfo->data, u4PktLen); -+ -+ /* pass to OS */ -+ TdlsCmdTestRxIndicatePkts(prGlueInfo, prMsduInfo); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to inform firmware to skip keep alive function. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prInBuf A pointer to the command string buffer -+* \param[in] u4InBufLen The length of the buffer -+* \param[out] None -+* -+* \retval None -+* -+* EX: iwpriv wlan0 set_str_cmd 0_10_[Enable/Disable] -+ -+ iwpriv wlan0 set_str_cmd 0_10_1 -+*/ -+/*----------------------------------------------------------------------------*/ -+static void TdlsCmdTestKeepAliveSkip(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) -+{ -+ WLAN_STATUS rStatus; -+ TDLS_CMD_CORE_T rCmd; -+ UINT_32 u4BufLen; -+ -+ /* parse arguments */ -+ kalMemZero(rCmd.aucPeerMac, sizeof(rCmd.aucPeerMac)); -+ rCmd.Content.rCmdKeepAliveSkip.fgIsEnable = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ -+ DBGLOG(TDLS, INFO, "%s: fgIsEnable = %d\n", __func__, rCmd.Content.rCmdKeepAliveSkip.fgIsEnable); -+ -+ /* command to do this */ -+ rStatus = kalIoctl(prGlueInfo, -+ TdlsTestKeepAliveSkip, &rCmd, sizeof(rCmd), FALSE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ DBGLOG(TDLS, ERROR, "%s kalIoctl fail:%x\n", __func__, rStatus); -+ return; -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to simulate to set the TDLS Prohibited bit. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prInBuf A pointer to the command string buffer -+* \param[in] u4InBufLen The length of the buffer -+* \param[out] None -+* -+* \retval None -+* -+* EX: iwpriv wlan0 set_str_cmd 0_11_[Enable/Disable]_[Set/Clear] -+ -+ iwpriv wlan0 set_str_cmd 0_13_1_1 -+*/ -+/*----------------------------------------------------------------------------*/ -+static void TdlsCmdTestProhibitedBitSet(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) -+{ -+ TDLS_CMD_CORE_T rCmd; -+ -+ /* parse arguments */ -+ kalMemZero(rCmd.aucPeerMac, sizeof(rCmd.aucPeerMac)); -+ rCmd.Content.rCmdProhibit.fgIsEnable = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ rCmd.Content.rCmdProhibit.fgIsSet = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ -+ DBGLOG(TDLS, INFO, "%s: fgIsEnable = %d\n", __func__, rCmd.Content.rCmdProhibit.fgIsEnable); -+ -+ /* command to do this */ -+ flgTdlsTestExtCapElm = rCmd.Content.rCmdProhibit.fgIsEnable; -+ -+ aucTdlsTestExtCapElm[0] = ELEM_ID_EXTENDED_CAP; -+ aucTdlsTestExtCapElm[1] = 5; -+ aucTdlsTestExtCapElm[2] = 0; -+ aucTdlsTestExtCapElm[3] = 0; -+ aucTdlsTestExtCapElm[4] = 0; -+ aucTdlsTestExtCapElm[5] = 0; -+ aucTdlsTestExtCapElm[6] = (rCmd.Content.rCmdProhibit.fgIsSet << 6); /* bit38 */ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to receive a PTI request from the AP. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prInBuf A pointer to the command string buffer -+* \param[in] u4InBufLen The length of the buffer -+* \param[out] None -+* -+* \retval None -+* -+* EX: iwpriv wlan0 set_str_cmd 0_1_4_[TDLS Peer MAC]_[Dialog Token] -+ -+ iwpriv wlan0 set_str_cmd 0_1_4_00:11:22:33:44:01_0 -+*/ -+/*----------------------------------------------------------------------------*/ -+static void TdlsCmdTestPtiReqRecv(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) -+{ -+ WLAN_STATUS rStatus; -+ TDLS_CMD_CORE_T rCmd; -+ UINT_32 u4BufLen; -+ -+ /* parse arguments */ -+ CmdStringMacParse(prInBuf, &prInBuf, &u4InBufLen, rCmd.aucPeerMac); -+ -+ rCmd.Content.rCmdPtiRspRcv.u4DialogToken = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ -+ DBGLOG(TDLS, INFO, "%s: [ %pM ] u4DialogToken = %u\n", -+ __func__, rCmd.aucPeerMac, (UINT32) rCmd.Content.rCmdPtiRspRcv.u4DialogToken); -+ -+ /* command to do this */ -+ rStatus = kalIoctl(prGlueInfo, TdlsTestPtiReqRecv, &rCmd, sizeof(rCmd), FALSE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ DBGLOG(TDLS, ERROR, "%s kalIoctl fail:%x\n", __func__, rStatus); -+ return; -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to receive a PTI response from the peer. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prInBuf A pointer to the command string buffer -+* \param[in] u4InBufLen The length of the buffer -+* \param[out] None -+* -+* \retval None -+* -+* EX: iwpriv wlan0 set_str_cmd 0_1_9_[TDLS Peer MAC]_[Dialog Token]_[PM] -+ -+ iwpriv wlan0 set_str_cmd 0_1_9_00:11:22:33:44:01_0_1 -+*/ -+/*----------------------------------------------------------------------------*/ -+static void TdlsCmdTestPtiRspRecv(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) -+{ -+ WLAN_STATUS rStatus; -+ TDLS_CMD_CORE_T rCmd; -+ UINT_32 u4BufLen; -+ -+ /* parse arguments */ -+ CmdStringMacParse(prInBuf, &prInBuf, &u4InBufLen, rCmd.aucPeerMac); -+ -+ rCmd.Content.rCmdPtiRspRcv.u4DialogToken = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ rCmd.Content.rCmdPtiRspRcv.u4PM = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ -+ DBGLOG(TDLS, INFO, "%s: [%pM] u4DialogToken = %u %u\n", -+ __func__, rCmd.aucPeerMac, -+ (UINT32) rCmd.Content.rCmdPtiRspRcv.u4DialogToken, -+ (UINT32) rCmd.Content.rCmdPtiRspRcv.u4PM); -+ -+ /* command to do this */ -+ rStatus = kalIoctl(prGlueInfo, TdlsTestPtiRspRecv, &rCmd, sizeof(rCmd), FALSE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ DBGLOG(TDLS, ERROR, "%s kalIoctl fail:%x\n", __func__, rStatus); -+ return; -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to inform firmware to simulate PTI tx done fail case. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prInBuf A pointer to the command string buffer -+* \param[in] u4InBufLen The length of the buffer -+* \param[out] None -+* -+* \retval None -+* -+* EX: iwpriv wlan0 set_str_cmd 0_21_[Enable/Disable] -+ -+ iwpriv wlan0 set_str_cmd 0_21_1 -+*/ -+/*----------------------------------------------------------------------------*/ -+static void TdlsCmdTestPtiTxDoneFail(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) -+{ -+ WLAN_STATUS rStatus; -+ TDLS_CMD_CORE_T rCmd; -+ UINT_32 u4BufLen; -+ -+ /* parse arguments */ -+ kalMemZero(rCmd.aucPeerMac, sizeof(rCmd.aucPeerMac)); -+ rCmd.Content.rCmdPtiTxFail.fgIsEnable = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ -+ DBGLOG(TDLS, INFO, "%s: fgIsEnable = %d\n", __func__, rCmd.Content.rCmdPtiTxFail.fgIsEnable); -+ -+ /* command to do this */ -+ rStatus = kalIoctl(prGlueInfo, TdlsTestPtiTxFail, &rCmd, sizeof(rCmd), FALSE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ DBGLOG(TDLS, ERROR, "%s kalIoctl fail:%x\n", __func__, rStatus); -+ return; -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to receive a test frame. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prInBuf A pointer to the command string buffer -+* \param[in] u4InBufLen The length of the buffer -+* \param[out] None -+* -+* \retval None -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static void TdlsCmdTestRvFrame(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) -+{ -+/* PARAM_CUSTOM_TDLS_CMD_STRUCT_T rCmd; */ -+/* TDLS_STATUS u4Status; */ -+ UINT_32 u4Subcmd; -+/* UINT_32 u4BufLen; */ -+ -+ /* parse sub-command */ -+ u4Subcmd = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ DBGLOG(TDLS, INFO, " test rv frame sub command = %u\n", (UINT32) u4Subcmd); -+ -+ /* parse command arguments */ -+ switch (u4Subcmd) { -+ case TDLS_FRM_ACTION_SETUP_REQ: -+ /* simulate to receive a setup request frame */ -+ TdlsCmdTestSetupReqRecv(prGlueInfo, prInBuf, u4InBufLen); -+ break; -+ -+ case TDLS_FRM_ACTION_SETUP_RSP: -+ /* simulate to receive a setup response frame */ -+ TdlsCmdTestSetupRspRecv(prGlueInfo, prInBuf, u4InBufLen); -+ break; -+ -+ case TDLS_FRM_ACTION_CONFIRM: -+ /* simulate to receive a setup confirm frame */ -+ TdlsCmdTestSetupConfirmRecv(prGlueInfo, prInBuf, u4InBufLen); -+ break; -+ -+ case TDLS_FRM_ACTION_TEARDOWN: -+ /* simulate to receive a tear down frame */ -+ TdlsCmdTestTearDownRecv(prGlueInfo, prInBuf, u4InBufLen); -+ break; -+ -+ case TDLS_FRM_ACTION_PTI: -+ /* simulate to receive a PTI request frame */ -+ TdlsCmdTestPtiReqRecv(prGlueInfo, prInBuf, u4InBufLen); -+ break; -+ -+ case TDLS_FRM_ACTION_PTI_RSP: -+ /* simulate to receive a PTI response frame */ -+ TdlsCmdTestPtiRspRecv(prGlueInfo, prInBuf, u4InBufLen); -+ break; -+ -+ case TDLS_FRM_DATA_TEST_DATA: -+ /* simulate to receive a DATA frame */ -+ TdlsCmdTestDataRecv(prGlueInfo, prInBuf, u4InBufLen); -+ break; -+ -+ case TDLS_FRM_ACTION_CHAN_SWITCH_REQ: -+ /* simulate to receive a channel switch request frame */ -+ TdlsCmdTestChSwReqRecv(prGlueInfo, prInBuf, u4InBufLen); -+ break; -+ -+ case TDLS_FRM_ACTION_CHAN_SWITCH_RSP: -+ /* simulate to receive a channel switch response frame */ -+ TdlsCmdTestChSwRspRecv(prGlueInfo, prInBuf, u4InBufLen); -+ break; -+ -+ case TDLS_FRM_ACTION_DISCOVERY_REQ: -+ /* simulate to receive a discovery request frame */ -+ TdlsCmdTestDiscoveryReqRecv(prGlueInfo, prInBuf, u4InBufLen); -+ break; -+ -+ default: -+ DBGLOG(TDLS, ERROR, " wrong test rv frame sub command\n"); -+ return; -+ } -+ -+/* if (u4Status != TDLS_STATUS_SUCCESS) */ -+ { -+/* DBGLOG(TDLS, ERROR, (" command parse fail\n")); */ -+/* return; */ -+ } -+ -+ /* send command to wifi task to handle */ -+#if 0 -+ kalIoctl(prGlueInfo, -+ TdlsTestFrameSend, -+ (PVOID)&rCmd, sizeof(PARAM_CUSTOM_TDLS_CMD_STRUCT_T), FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+#endif -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to receive a test setup confirm frame command. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prInBuf A pointer to the command string buffer -+* \param[in] u4InBufLen The length of the buffer -+* \param[out] None -+* -+* \retval None -+* -+* EX: iwpriv wlan0 set_str_cmd 0_1_2_[DialogToken]_[StatusCode]_[Peer MAC] -+ -+ iwpriv wlan0 set_str_cmd 0_1_2_1_0_00:11:22:33:44:01 -+*/ -+/*----------------------------------------------------------------------------*/ -+static void TdlsCmdTestSetupConfirmRecv(GLUE_INFO_T *prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) -+{ -+ ADAPTER_T *prAdapter; -+ P_BSS_INFO_T prBssInfo; -+ PM_PROFILE_SETUP_INFO_T *prPmProfSetupInfo; -+ struct sk_buff *prMsduInfo; -+ UINT_8 *pPkt; -+ UINT_32 u4PktLen, u4IeLen; -+ UINT_8 ucDialogToken, ucStatusCode, aucPeerMac[6]; -+ -+ /* parse arguments */ -+ ucDialogToken = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ ucStatusCode = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ CmdStringMacParse(prInBuf, &prInBuf, &u4InBufLen, aucPeerMac); -+ -+ DBGLOG(TDLS, INFO, -+ " %s: DialogToken=%d StatusCode=%d from %pM\n", -+ __func__, ucDialogToken, ucStatusCode, aucPeerMac); -+ -+ /* allocate/init packet */ -+ prAdapter = prGlueInfo->prAdapter; -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ prPmProfSetupInfo = &prBssInfo->rPmProfSetupInfo; -+ u4PktLen = 0; -+ -+ prMsduInfo = kalPacketAlloc(prGlueInfo, 1600, &pPkt); -+ if (prMsduInfo == NULL) { -+ DBGLOG(TDLS, ERROR, " %s: allocate pkt fail\n", __func__); -+ return; -+ } -+ -+ prMsduInfo->dev = prGlueInfo->prDevHandler; -+ if (prMsduInfo->dev == NULL) { -+ DBGLOG(TDLS, ERROR, " %s: MsduInfo->dev == NULL\n", __func__); -+ kalPacketFree(prGlueInfo, prMsduInfo); -+ return; -+ } -+ -+ /* make up frame content */ -+ /* 1. 802.3 header */ -+ kalMemCopy(pPkt, prAdapter->rMyMacAddr, TDLS_FME_MAC_ADDR_LEN); -+ LR_TDLS_FME_FIELD_FILL(TDLS_FME_MAC_ADDR_LEN); -+ kalMemCopy(pPkt, aucPeerMac, TDLS_FME_MAC_ADDR_LEN); -+ LR_TDLS_FME_FIELD_FILL(TDLS_FME_MAC_ADDR_LEN); -+ *(UINT_16 *) pPkt = htons(TDLS_FRM_PROT_TYPE); -+ LR_TDLS_FME_FIELD_FILL(2); -+ -+ /* 2. payload type */ -+ *pPkt = TDLS_FRM_PAYLOAD_TYPE; -+ LR_TDLS_FME_FIELD_FILL(1); -+ -+ /* 3. Frame Formation - (1) Category */ -+ *pPkt = TDLS_FRM_CATEGORY; -+ LR_TDLS_FME_FIELD_FILL(1); -+ -+ /* 3. Frame Formation - (2) Action */ -+ *pPkt = TDLS_FRM_ACTION_CONFIRM; -+ LR_TDLS_FME_FIELD_FILL(1); -+ -+ /* 3. Frame Formation - (3) Status Code */ -+ *pPkt = ucStatusCode; -+ *(pPkt + 1) = 0x00; -+ LR_TDLS_FME_FIELD_FILL(2); -+ -+ /* 3. Frame Formation - (4) Dialog token */ -+ *pPkt = ucDialogToken; -+ LR_TDLS_FME_FIELD_FILL(1); -+ -+ /* 3. Frame Formation - (17) WMM Information element */ -+ if (prAdapter->rWifiVar.fgSupportQoS) { -+ u4IeLen = mqmGenerateWmmParamIEByParam(prAdapter, prBssInfo, pPkt, OP_MODE_INFRASTRUCTURE); -+ LR_TDLS_FME_FIELD_FILL(u4IeLen); -+ } -+ -+ /* 3. Frame Formation - (16) Link identifier element */ -+ TDLS_LINK_IDENTIFIER_IE(pPkt)->ucId = ELEM_ID_LINK_IDENTIFIER; -+ TDLS_LINK_IDENTIFIER_IE(pPkt)->ucLength = ELEM_LEN_LINK_IDENTIFIER; -+ -+ kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aBSSID, prBssInfo->aucBSSID, 6); -+ kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aInitiator, aucPeerMac, 6); -+ kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aResponder, prAdapter->rMyMacAddr, 6); -+ -+ u4IeLen = IE_SIZE(pPkt); -+ LR_TDLS_FME_FIELD_FILL(u4IeLen); -+ -+ /* 4. Update packet length */ -+ prMsduInfo->len = u4PktLen; -+ dumpMemory8(prMsduInfo->data, u4PktLen); -+ -+ /* pass to OS */ -+ TdlsCmdTestRxIndicatePkts(prGlueInfo, prMsduInfo); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to receive a test setup request frame command. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prInBuf A pointer to the command string buffer -+* \param[in] u4InBufLen The length of the buffer -+* \param[out] None -+* -+* \retval None -+* -+* EX: iwpriv wlan0 set_str_cmd 0_1_0_[DialogToken]_[Peer MAC]_[BSSID] -+ -+ iwpriv wlan0 set_str_cmd 0_1_0_1_00:11:22:33:44:01 -+ iwpriv wlan0 set_str_cmd 0_1_0_1_00:11:22:33:44:01_00:22:33:44:11:22 -+*/ -+/*----------------------------------------------------------------------------*/ -+static void TdlsCmdTestSetupReqRecv(GLUE_INFO_T *prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) -+{ -+ ADAPTER_T *prAdapter; -+ P_BSS_INFO_T prBssInfo; -+ struct sk_buff *prMsduInfo; -+ UINT_8 *pPkt; -+ UINT_32 u4PktLen, u4IeLen; -+ UINT_8 ucDialogToken, aucPeerMac[6], aucBSSID[6], aucZeroMac[6]; -+ UINT_16 u2CapInfo; -+ -+ /* parse arguments */ -+ ucDialogToken = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ CmdStringMacParse(prInBuf, &prInBuf, &u4InBufLen, aucPeerMac); -+ -+ kalMemZero(aucZeroMac, sizeof(aucZeroMac)); -+ kalMemZero(aucBSSID, sizeof(aucBSSID)); -+ CmdStringMacParse(prInBuf, &prInBuf, &u4InBufLen, aucBSSID); -+ -+ DBGLOG(TDLS, INFO, -+ " %s: DialogToken=%d from %pM\n", __func__, ucDialogToken, aucPeerMac); -+ -+ /* allocate/init packet */ -+ prAdapter = prGlueInfo->prAdapter; -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ u4PktLen = 0; -+ -+ prMsduInfo = kalPacketAlloc(prGlueInfo, 1600, &pPkt); -+ if (prMsduInfo == NULL) { -+ DBGLOG(TDLS, ERROR, " %s: allocate pkt fail\n", __func__); -+ return; -+ } -+ -+ prMsduInfo->dev = prGlueInfo->prDevHandler; -+ if (prMsduInfo->dev == NULL) { -+ DBGLOG(TDLS, ERROR, " %s: MsduInfo->dev == NULL\n", __func__); -+ kalPacketFree(prGlueInfo, prMsduInfo); -+ return; -+ } -+ -+ /* make up frame content */ -+ /* 1. 802.3 header */ -+ kalMemCopy(pPkt, prAdapter->rMyMacAddr, TDLS_FME_MAC_ADDR_LEN); -+ LR_TDLS_FME_FIELD_FILL(TDLS_FME_MAC_ADDR_LEN); -+ kalMemCopy(pPkt, aucPeerMac, TDLS_FME_MAC_ADDR_LEN); -+ LR_TDLS_FME_FIELD_FILL(TDLS_FME_MAC_ADDR_LEN); -+ *(UINT_16 *) pPkt = htons(TDLS_FRM_PROT_TYPE); -+ LR_TDLS_FME_FIELD_FILL(2); -+ -+ /* 2. payload type */ -+ *pPkt = TDLS_FRM_PAYLOAD_TYPE; -+ LR_TDLS_FME_FIELD_FILL(1); -+ -+ /* 3. Frame Formation - (1) Category */ -+ *pPkt = TDLS_FRM_CATEGORY; -+ LR_TDLS_FME_FIELD_FILL(1); -+ -+ /* 3. Frame Formation - (2) Action */ -+ *pPkt = TDLS_FRM_ACTION_SETUP_REQ; -+ LR_TDLS_FME_FIELD_FILL(1); -+ -+ /* 3. Frame Formation - (3) Dialog token */ -+ *pPkt = ucDialogToken; -+ LR_TDLS_FME_FIELD_FILL(1); -+ -+ /* 3. Frame Formation - (4) Capability */ -+ u2CapInfo = assocBuildCapabilityInfo(prAdapter, NULL); -+ WLAN_SET_FIELD_16(pPkt, u2CapInfo); -+ LR_TDLS_FME_FIELD_FILL(2); -+ -+ /* 4. Append general IEs */ -+ u4IeLen = TdlsFrameGeneralIeAppend(prAdapter, NULL, 0, pPkt); -+ LR_TDLS_FME_FIELD_FILL(u4IeLen); -+ -+ /* 3. Frame Formation - (10) Extended capabilities element */ -+ EXT_CAP_IE(pPkt)->ucId = ELEM_ID_EXTENDED_CAP; -+ EXT_CAP_IE(pPkt)->ucLength = 5; -+ -+ EXT_CAP_IE(pPkt)->aucCapabilities[0] = 0x00; /* bit0 ~ bit7 */ -+ EXT_CAP_IE(pPkt)->aucCapabilities[1] = 0x00; /* bit8 ~ bit15 */ -+ EXT_CAP_IE(pPkt)->aucCapabilities[2] = 0x00; /* bit16 ~ bit23 */ -+ EXT_CAP_IE(pPkt)->aucCapabilities[3] = 0x00; /* bit24 ~ bit31 */ -+ EXT_CAP_IE(pPkt)->aucCapabilities[4] = 0x00; /* bit32 ~ bit39 */ -+ -+ /* TDLS_EX_CAP_PEER_UAPSD */ -+ EXT_CAP_IE(pPkt)->aucCapabilities[3] |= BIT((28 - 24)); -+ /* TDLS_EX_CAP_CHAN_SWITCH */ -+ EXT_CAP_IE(pPkt)->aucCapabilities[3] |= BIT((30 - 24)); -+ /* TDLS_EX_CAP_TDLS */ -+ EXT_CAP_IE(pPkt)->aucCapabilities[4] |= BIT((37 - 32)); -+ -+ u4IeLen = IE_SIZE(pPkt); -+ LR_TDLS_FME_FIELD_FILL(u4IeLen); -+ -+ /* 3. Frame Formation - (16) Link identifier element */ -+ TDLS_LINK_IDENTIFIER_IE(pPkt)->ucId = ELEM_ID_LINK_IDENTIFIER; -+ TDLS_LINK_IDENTIFIER_IE(pPkt)->ucLength = 18; -+ -+ if (kalMemCmp(aucBSSID, aucZeroMac, 6) == 0) -+ kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aBSSID, prBssInfo->aucBSSID, 6); -+ else -+ kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aBSSID, aucBSSID, 6); -+ -+ kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aInitiator, aucPeerMac, 6); -+ kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aResponder, prAdapter->rMyMacAddr, 6); -+ -+ u4IeLen = IE_SIZE(pPkt); -+ LR_TDLS_FME_FIELD_FILL(u4IeLen); -+ -+ /* 4. Update packet length */ -+ prMsduInfo->len = u4PktLen; -+ dumpMemory8(prMsduInfo->data, u4PktLen); -+ -+ /* pass to OS */ -+ TdlsCmdTestRxIndicatePkts(prGlueInfo, prMsduInfo); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to receive a test setup response frame command. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prInBuf A pointer to the command string buffer -+* \param[in] u4InBufLen The length of the buffer -+* \param[out] None -+* -+* \retval None -+* -+* EX: iwpriv wlan0 set_str_cmd 0_1_1_[DialogToken]_[StatusCode]_[Peer MAC] -+ -+ iwpriv wlan0 set_str_cmd 0_1_1_1_0_00:11:22:33:44:01 -+*/ -+/*----------------------------------------------------------------------------*/ -+static void TdlsCmdTestSetupRspRecv(GLUE_INFO_T *prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) -+{ -+ ADAPTER_T *prAdapter; -+ P_BSS_INFO_T prBssInfo; -+ struct sk_buff *prMsduInfo; -+ UINT_8 *pPkt; -+ UINT_32 u4PktLen, u4IeLen; -+ UINT_8 ucDialogToken, ucStatusCode, aucPeerMac[6]; -+ UINT_16 u2CapInfo; -+ -+ /* parse arguments */ -+ ucDialogToken = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ ucStatusCode = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ CmdStringMacParse(prInBuf, &prInBuf, &u4InBufLen, aucPeerMac); -+ -+ DBGLOG(TDLS, INFO, -+ " %s: DialogToken=%d StatusCode=%d from %pM\n", -+ __func__, ucDialogToken, ucStatusCode, aucPeerMac); -+ -+ /* allocate/init packet */ -+ prAdapter = prGlueInfo->prAdapter; -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ u4PktLen = 0; -+ -+ prMsduInfo = kalPacketAlloc(prGlueInfo, 1600, &pPkt); -+ if (prMsduInfo == NULL) { -+ DBGLOG(TDLS, ERROR, " %s: allocate pkt fail\n", __func__); -+ return; -+ } -+ -+ prMsduInfo->dev = prGlueInfo->prDevHandler; -+ if (prMsduInfo->dev == NULL) { -+ DBGLOG(TDLS, ERROR, " %s: MsduInfo->dev == NULL\n", __func__); -+ kalPacketFree(prGlueInfo, prMsduInfo); -+ return; -+ } -+ -+ /* make up frame content */ -+ /* 1. 802.3 header */ -+ kalMemCopy(pPkt, prAdapter->rMyMacAddr, TDLS_FME_MAC_ADDR_LEN); -+ LR_TDLS_FME_FIELD_FILL(TDLS_FME_MAC_ADDR_LEN); -+ kalMemCopy(pPkt, aucPeerMac, TDLS_FME_MAC_ADDR_LEN); -+ LR_TDLS_FME_FIELD_FILL(TDLS_FME_MAC_ADDR_LEN); -+ *(UINT_16 *) pPkt = htons(TDLS_FRM_PROT_TYPE); -+ LR_TDLS_FME_FIELD_FILL(2); -+ -+ /* 2. payload type */ -+ *pPkt = TDLS_FRM_PAYLOAD_TYPE; -+ LR_TDLS_FME_FIELD_FILL(1); -+ -+ /* 3. Frame Formation - (1) Category */ -+ *pPkt = TDLS_FRM_CATEGORY; -+ LR_TDLS_FME_FIELD_FILL(1); -+ -+ /* 3. Frame Formation - (2) Action */ -+ *pPkt = TDLS_FRM_ACTION_SETUP_RSP; -+ LR_TDLS_FME_FIELD_FILL(1); -+ -+ /* 3. Frame Formation - (3) Status Code */ -+ *pPkt = ucStatusCode; -+ *(pPkt + 1) = 0x00; -+ LR_TDLS_FME_FIELD_FILL(2); -+ -+ /* 3. Frame Formation - (4) Dialog token */ -+ *pPkt = ucDialogToken; -+ LR_TDLS_FME_FIELD_FILL(1); -+ -+ /* 3. Frame Formation - (5) Capability */ -+ u2CapInfo = assocBuildCapabilityInfo(prAdapter, NULL); -+ WLAN_SET_FIELD_16(pPkt, u2CapInfo); -+ LR_TDLS_FME_FIELD_FILL(2); -+ -+ /* 4. Append general IEs */ -+ u4IeLen = TdlsFrameGeneralIeAppend(prAdapter, NULL, 0, pPkt); -+ LR_TDLS_FME_FIELD_FILL(u4IeLen); -+ -+ /* 3. Frame Formation - (10) Extended capabilities element */ -+ EXT_CAP_IE(pPkt)->ucId = ELEM_ID_EXTENDED_CAP; -+ EXT_CAP_IE(pPkt)->ucLength = 5; -+ -+ EXT_CAP_IE(pPkt)->aucCapabilities[0] = 0x00; /* bit0 ~ bit7 */ -+ EXT_CAP_IE(pPkt)->aucCapabilities[1] = 0x00; /* bit8 ~ bit15 */ -+ EXT_CAP_IE(pPkt)->aucCapabilities[2] = 0x00; /* bit16 ~ bit23 */ -+ EXT_CAP_IE(pPkt)->aucCapabilities[3] = 0x00; /* bit24 ~ bit31 */ -+ EXT_CAP_IE(pPkt)->aucCapabilities[4] = 0x00; /* bit32 ~ bit39 */ -+ -+ /* TDLS_EX_CAP_PEER_UAPSD */ -+ EXT_CAP_IE(pPkt)->aucCapabilities[3] |= BIT((28 - 24)); -+ /* TDLS_EX_CAP_CHAN_SWITCH */ -+ EXT_CAP_IE(pPkt)->aucCapabilities[3] |= BIT((30 - 24)); -+ /* TDLS_EX_CAP_TDLS */ -+ EXT_CAP_IE(pPkt)->aucCapabilities[4] |= BIT((37 - 32)); -+ -+ u4IeLen = IE_SIZE(pPkt); -+ LR_TDLS_FME_FIELD_FILL(u4IeLen); -+ -+ /* 3. Frame Formation - (16) Link identifier element */ -+ TDLS_LINK_IDENTIFIER_IE(pPkt)->ucId = ELEM_ID_LINK_IDENTIFIER; -+ TDLS_LINK_IDENTIFIER_IE(pPkt)->ucLength = ELEM_LEN_LINK_IDENTIFIER; -+ -+ kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aBSSID, prBssInfo->aucBSSID, 6); -+ kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aInitiator, prAdapter->rMyMacAddr, 6); -+ kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aResponder, aucPeerMac, 6); -+ -+ u4IeLen = IE_SIZE(pPkt); -+ LR_TDLS_FME_FIELD_FILL(u4IeLen); -+ -+ /* 4. Update packet length */ -+ prMsduInfo->len = u4PktLen; -+ dumpMemory8(prMsduInfo->data, u4PktLen); -+ -+ /* pass to OS */ -+ TdlsCmdTestRxIndicatePkts(prGlueInfo, prMsduInfo); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to inform firmware to skip channel switch timeout function. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prInBuf A pointer to the command string buffer -+* \param[in] u4InBufLen The length of the buffer -+* \param[out] None -+* -+* \retval None -+* -+* EX: iwpriv wlan0 set_str_cmd 0_14_[Enable/Disable] -+ -+ iwpriv wlan0 set_str_cmd 0_14_0 -+*/ -+/*----------------------------------------------------------------------------*/ -+static void TdlsCmdTestScanCtrl(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) -+{ -+ WLAN_STATUS rStatus; -+ TDLS_CMD_CORE_T rCmd; -+ UINT_32 u4BufLen; -+ -+ /* parse arguments */ -+ kalMemZero(rCmd.aucPeerMac, sizeof(rCmd.aucPeerMac)); -+ rCmd.Content.rCmdScanSkip.fgIsEnable = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ -+ DBGLOG(TDLS, INFO, "%s: fgIsEnable = %d\n", __func__, rCmd.Content.rCmdScanSkip.fgIsEnable); -+ -+ /* command to do this */ -+ rStatus = kalIoctl(prGlueInfo, TdlsTestScanSkip, &rCmd, sizeof(rCmd), FALSE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ DBGLOG(TDLS, ERROR, "%s kalIoctl fail:%x\n", __func__, rStatus); -+ return; -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to receive a test tear down frame command. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prInBuf A pointer to the command string buffer -+* \param[in] u4InBufLen The length of the buffer -+* \param[out] None -+* -+* \retval None -+* -+* EX: iwpriv wlan0 set_str_cmd 0_1_3_[IsInitiator]_[ReasonCode]_[Peer MAC]_[Where] -+ -+ Where 0 (From driver) or 1 (From FW) -+ -+ iwpriv wlan0 set_str_cmd 0_1_3_1_26_00:11:22:33:44:01_0 -+*/ -+/*----------------------------------------------------------------------------*/ -+static void TdlsCmdTestTearDownRecv(GLUE_INFO_T *prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) -+{ -+ ADAPTER_T *prAdapter; -+ P_BSS_INFO_T prBssInfo; -+ struct sk_buff *prMsduInfo; -+ UINT_8 *pPkt; -+ UINT_32 u4PktLen, u4IeLen; -+ BOOLEAN fgIsInitiator; -+ UINT_8 ucReasonCode, aucPeerMac[6]; -+ BOOLEAN fgIsFromWhich; -+ WLAN_STATUS rStatus; -+ TDLS_CMD_CORE_T rCmd; -+ UINT_32 u4BufLen; -+ -+ /* parse arguments */ -+ fgIsInitiator = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ ucReasonCode = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ CmdStringMacParse(prInBuf, &prInBuf, &u4InBufLen, aucPeerMac); -+ fgIsFromWhich = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ -+ DBGLOG(TDLS, INFO, -+ " %s: ReasonCode=%d from %pM %d\n", -+ __func__, ucReasonCode, aucPeerMac, fgIsFromWhich); -+ -+ if (fgIsFromWhich == 0) { -+ /* allocate/init packet */ -+ prAdapter = prGlueInfo->prAdapter; -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ u4PktLen = 0; -+ -+ prMsduInfo = kalPacketAlloc(prGlueInfo, 1600, &pPkt); -+ if (prMsduInfo == NULL) { -+ DBGLOG(TDLS, ERROR, " %s: allocate pkt fail\n", __func__); -+ return; -+ } -+ -+ prMsduInfo->dev = prGlueInfo->prDevHandler; -+ if (prMsduInfo->dev == NULL) { -+ DBGLOG(TDLS, ERROR, " %s: MsduInfo->dev == NULL\n", __func__); -+ kalPacketFree(prGlueInfo, prMsduInfo); -+ return; -+ } -+ -+ /* make up frame content */ -+ /* 1. 802.3 header */ -+ kalMemCopy(pPkt, prAdapter->rMyMacAddr, TDLS_FME_MAC_ADDR_LEN); -+ LR_TDLS_FME_FIELD_FILL(TDLS_FME_MAC_ADDR_LEN); -+ kalMemCopy(pPkt, aucPeerMac, TDLS_FME_MAC_ADDR_LEN); -+ LR_TDLS_FME_FIELD_FILL(TDLS_FME_MAC_ADDR_LEN); -+ *(UINT_16 *) pPkt = htons(TDLS_FRM_PROT_TYPE); -+ LR_TDLS_FME_FIELD_FILL(2); -+ -+ /* 2. payload type */ -+ *pPkt = TDLS_FRM_PAYLOAD_TYPE; -+ LR_TDLS_FME_FIELD_FILL(1); -+ -+ /* 3. Frame Formation - (1) Category */ -+ *pPkt = TDLS_FRM_CATEGORY; -+ LR_TDLS_FME_FIELD_FILL(1); -+ -+ /* 3. Frame Formation - (2) Action */ -+ *pPkt = TDLS_FRM_ACTION_TEARDOWN; -+ LR_TDLS_FME_FIELD_FILL(1); -+ -+ /* 3. Frame Formation - (3) Reason Code */ -+ *pPkt = ucReasonCode; -+ *(pPkt + 1) = 0x00; -+ LR_TDLS_FME_FIELD_FILL(2); -+ -+ /* 3. Frame Formation - (16) Link identifier element */ -+ TDLS_LINK_IDENTIFIER_IE(pPkt)->ucId = ELEM_ID_LINK_IDENTIFIER; -+ TDLS_LINK_IDENTIFIER_IE(pPkt)->ucLength = ELEM_LEN_LINK_IDENTIFIER; -+ -+ kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aBSSID, prBssInfo->aucBSSID, 6); -+ if (fgIsInitiator == 1) { -+ kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aInitiator, aucPeerMac, 6); -+ kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aResponder, prAdapter->rMyMacAddr, 6); -+ } else { -+ kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aInitiator, prAdapter->rMyMacAddr, 6); -+ kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aResponder, aucPeerMac, 6); -+ } -+ -+ u4IeLen = IE_SIZE(pPkt); -+ LR_TDLS_FME_FIELD_FILL(u4IeLen); -+ -+ /* 4. Update packet length */ -+ prMsduInfo->len = u4PktLen; -+ dumpMemory8(prMsduInfo->data, u4PktLen); -+ -+ /* pass to OS */ -+ TdlsCmdTestRxIndicatePkts(prGlueInfo, prMsduInfo); -+ } else { -+ kalMemZero(&rCmd, sizeof(rCmd)); -+ kalMemCopy(rCmd.aucPeerMac, aucPeerMac, 6); -+ rCmd.Content.rCmdTearDownRcv.u4ReasonCode = (UINT32) ucReasonCode; -+ -+ /* command to do this */ -+ rStatus = kalIoctl(prGlueInfo, -+ TdlsTestTearDownRecv, &rCmd, sizeof(rCmd), FALSE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ DBGLOG(TDLS, ERROR, "%s kalIoctl fail:%x\n", __func__, rStatus); -+ return; -+ } -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to inform firmware to skip tx fail case. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prInBuf A pointer to the command string buffer -+* \param[in] u4InBufLen The length of the buffer -+* \param[out] None -+* -+* \retval None -+* -+* EX: iwpriv wlan0 set_str_cmd 0_7_[Enable/Disable] -+ -+ iwpriv wlan0 set_str_cmd 0_7_1 -+*/ -+/*----------------------------------------------------------------------------*/ -+static void TdlsCmdTestTxFailSkip(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) -+{ -+ WLAN_STATUS rStatus; -+ TDLS_CMD_CORE_T rCmd; -+ UINT_32 u4BufLen; -+ -+ /* parse arguments */ -+ kalMemZero(rCmd.aucPeerMac, sizeof(rCmd.aucPeerMac)); -+ rCmd.Content.rCmdTxFailSkip.fgIsEnable = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ -+ DBGLOG(TDLS, INFO, "%s: fgIsEnable = %d\n", __func__, rCmd.Content.rCmdTxFailSkip.fgIsEnable); -+ -+ /* command to do this */ -+ rStatus = kalIoctl(prGlueInfo, TdlsTestTxFailSkip, &rCmd, sizeof(rCmd), FALSE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ DBGLOG(TDLS, ERROR, "%s kalIoctl fail:%x\n", __func__, rStatus); -+ return; -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to send a test frame command to wifi task. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prInBuf A pointer to the command string buffer -+* \param[in] u4InBufLen The length of the buffer -+* \param[out] None -+* -+* \retval None -+* -+* EX: iwpriv wlan0 set_str_cmd 0_12_0_[FrameType]_[DialogToken]_[Peer MAC] -+ -+ iwpriv wlan0 set_str_cmd 0_12_0_0_1_00:11:22:33:44:01 -+* -+* EX: iwpriv wlan0 set_str_cmd 0_12_2_[FrameType]_[DialogToken]_[Peer MAC] -+ -+ iwpriv wlan0 set_str_cmd 0_12_2_0_1_00:11:22:33:44:01 -+*/ -+/*----------------------------------------------------------------------------*/ -+static void TdlsCmdTestTxTdlsFrame(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) -+{ -+ PARAM_CUSTOM_TDLS_CMD_STRUCT_T rCmd; -+ UINT32 u4Subcmd; -+ UINT_32 u4BufLen; -+ -+ /* parse sub-command */ -+ u4Subcmd = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ DBGLOG(TDLS, INFO, " test tx tdls frame sub command = %u\n", u4Subcmd); -+ -+ /* parse command arguments */ -+ rCmd.ucFmeType = CmdStringDecParse(prInBuf, &prInBuf, &u4BufLen); -+ -+ switch (u4Subcmd) { -+ case TDLS_FRM_ACTION_SETUP_REQ: -+ case TDLS_FRM_ACTION_SETUP_RSP: -+ case TDLS_FRM_ACTION_CONFIRM: -+ rCmd.ucToken = CmdStringDecParse(prInBuf, &prInBuf, &u4BufLen); -+ CmdStringMacParse(prInBuf, &prInBuf, &u4InBufLen, rCmd.arRspAddr); -+ -+ DBGLOG(TDLS, INFO, " setup FmeType=%d Token=%d to [%pM]\n", -+ rCmd.ucFmeType, rCmd.ucToken, rCmd.arRspAddr); -+ break; -+ -+ default: -+ DBGLOG(TDLS, ERROR, " wrong test tx frame sub command\n"); -+ return; -+ } -+ -+ /* send command to wifi task to handle */ -+ kalIoctl(prGlueInfo, -+ TdlsTestTdlsFrameSend, -+ (PVOID)&rCmd, sizeof(PARAM_CUSTOM_TDLS_CMD_STRUCT_T), FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to send a test frame command to wifi task. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prInBuf A pointer to the command string buffer -+* \param[in] u4InBufLen The length of the buffer -+* \param[out] None -+* -+* \retval None -+* -+* EX: iwpriv wlan0 set_str_cmd 0_0_0_[FrameType]_[DialogToken]_[Cap]_[ExCap]_ -+ [SupRate0]_[SupRate1]_[SupRate2]_[SupRate3]_ -+ [SupChan0]_[SupChan1]_[SupChan2]_[SupChan3]_ -+ [Timeout]_[Peer MAC] -+ -+ iwpriv wlan0 set_str_cmd 0_0_0_0_1_1_7_0_0_0_0_0_0_0_0_300_00:11:22:33:44:01 -+*/ -+/*----------------------------------------------------------------------------*/ -+static void TdlsCmdTestTxFrame(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) -+{ -+ PARAM_CUSTOM_TDLS_CMD_STRUCT_T rCmd; -+ TDLS_STATUS u4Status; -+ UINT_32 u4Subcmd; -+ UINT_32 u4BufLen; -+ -+ /* parse sub-command */ -+ u4Subcmd = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ DBGLOG(TDLS, INFO, " test tx frame sub command = %u\n", (UINT32) u4Subcmd); -+ -+ /* parse command arguments */ -+ switch (u4Subcmd) { -+ case TDLS_FRM_ACTION_SETUP_REQ: -+ u4Status = TdlsCmdTestTxFmeSetupReqBufTranslate(prInBuf, u4InBufLen, &rCmd); -+ break; -+ -+ default: -+ DBGLOG(TDLS, ERROR, " wrong test tx frame sub command\n"); -+ return; -+ } -+ -+ if (u4Status != TDLS_STATUS_SUCCESS) { -+ DBGLOG(TDLS, ERROR, " command parse fail\n"); -+ return; -+ } -+ -+ /* send command to wifi task to handle */ -+ kalIoctl(prGlueInfo, -+ TdlsTestFrameSend, -+ (PVOID)&rCmd, sizeof(PARAM_CUSTOM_TDLS_CMD_STRUCT_T), FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Parse the TDLS test frame command, setup request -+* -+* @param CmdBuf Pointer to the buffer. -+* @param BufLen Record buffer length. -+* @param CmdTspec Pointer to the structure. -+* -+* @retval WLAN_STATUS_SUCCESS: Translate OK. -+* @retval WLAN_STATUS_FAILURE: Translate fail. -+* @usage iwpriv wlan0 set_str_cmd [tdls]_[command] -+* -+* EX: iwpriv wlan0 set_str_cmd 0_0_0_[FrameType]_[DialogToken]_[Cap]_[ExCap]_ -+ [SupRate0]_[SupRate1]_[SupRate2]_[SupRate3]_ -+ [SupChan0]_[SupChan1]_[SupChan2]_[SupChan3]_ -+ [Timeout]_[Peer MAC] -+ -+ iwpriv wlan0 set_str_cmd 0_0_0_0_1_1_7_0_0_0_0_0_0_0_0_300_00:11:22:33:44:01 -+*/ -+/*----------------------------------------------------------------------------*/ -+static TDLS_STATUS -+TdlsCmdTestTxFmeSetupReqBufTranslate(UINT_8 *pCmdBuf, UINT_32 u4BufLen, PARAM_CUSTOM_TDLS_CMD_STRUCT_T *prCmd) -+{ -+/* dumpMemory8(ANDROID_LOG_INFO, pCmdBuf, u4BufLen); */ -+ -+ prCmd->ucFmeType = CmdStringDecParse(pCmdBuf, &pCmdBuf, &u4BufLen); -+ prCmd->ucToken = CmdStringDecParse(pCmdBuf, &pCmdBuf, &u4BufLen); -+ prCmd->u2Cap = CmdStringDecParse(pCmdBuf, &pCmdBuf, &u4BufLen); -+ prCmd->ucExCap = CmdStringDecParse(pCmdBuf, &pCmdBuf, &u4BufLen); -+ prCmd->arSupRate[0] = CmdStringDecParse(pCmdBuf, &pCmdBuf, &u4BufLen); -+ prCmd->arSupRate[1] = CmdStringDecParse(pCmdBuf, &pCmdBuf, &u4BufLen); -+ prCmd->arSupRate[2] = CmdStringDecParse(pCmdBuf, &pCmdBuf, &u4BufLen); -+ prCmd->arSupRate[3] = CmdStringDecParse(pCmdBuf, &pCmdBuf, &u4BufLen); -+ prCmd->arSupChan[0] = CmdStringDecParse(pCmdBuf, &pCmdBuf, &u4BufLen); -+ prCmd->arSupChan[1] = CmdStringDecParse(pCmdBuf, &pCmdBuf, &u4BufLen); -+ prCmd->arSupChan[2] = CmdStringDecParse(pCmdBuf, &pCmdBuf, &u4BufLen); -+ prCmd->arSupChan[3] = CmdStringDecParse(pCmdBuf, &pCmdBuf, &u4BufLen); -+ prCmd->u4Timeout = CmdStringDecParse(pCmdBuf, &pCmdBuf, &u4BufLen); -+ CmdStringMacParse(pCmdBuf, &pCmdBuf, &u4BufLen, prCmd->arRspAddr); -+ -+ DBGLOG(TDLS, INFO, " command content =\n"); -+ DBGLOG(TDLS, INFO, "\tPeer MAC = %pM\n", (prCmd->arRspAddr)); -+ DBGLOG(TDLS, INFO, "\tToken = %u, Cap = 0x%x, ExCap = 0x%x, Timeout = %us FrameType = %u\n", -+ (UINT32) prCmd->ucToken, prCmd->u2Cap, prCmd->ucExCap, -+ (UINT32) prCmd->u4Timeout, (UINT32) prCmd->ucFmeType); -+ DBGLOG(TDLS, INFO, "\tSupRate = 0x%x %x %x %x\n", -+ prCmd->arSupRate[0], prCmd->arSupRate[1], prCmd->arSupRate[2], prCmd->arSupRate[3]); -+ DBGLOG(TDLS, INFO, "\tSupChan = %d %d %d %d\n", -+ prCmd->arSupChan[0], prCmd->arSupChan[1], prCmd->arSupChan[2], prCmd->arSupChan[3]); -+ -+ return TDLS_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to update a TDLS peer. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prInBuf A pointer to the command string buffer -+* \param[in] u4InBufLen The length of the buffer -+* \param[out] None -+* -+* \retval None -+* -+* EX: iwpriv wlan0 set_str_cmd 0_3_[Responder MAC] -+ -+ iwpriv wlan0 set_str_cmd 0_3_00:11:22:33:44:01 -+*/ -+/*----------------------------------------------------------------------------*/ -+static void TdlsCmdTestUpdatePeer(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) -+{ -+ PARAM_CUSTOM_TDLS_CMD_STRUCT_T rCmd; -+ struct wireless_dev *prWdev; -+ -+ /* reset */ -+ kalMemZero(&rCmd, sizeof(rCmd)); -+ -+ /* parse arguments */ -+ CmdStringMacParse(prInBuf, &prInBuf, &u4InBufLen, rCmd.arRspAddr); -+ -+ /* init */ -+ rCmd.rPeerInfo.supported_rates = rCmd.arSupRate; -+ rCmd.rPeerInfo.ht_capa = &rCmd.rHtCapa; -+ rCmd.rPeerInfo.vht_capa = &rCmd.rVhtCapa; /* LINUX_KERNEL_VERSION >= 3.10.0 */ -+ rCmd.rPeerInfo.sta_flags_set = BIT(NL80211_STA_FLAG_TDLS_PEER); -+ rCmd.rPeerInfo.uapsd_queues = 0xf; /* all AC */ -+ rCmd.rPeerInfo.max_sp = 0; /* delivery all packets */ -+ -+ /* send command to wifi task to handle */ -+ prWdev = prGlueInfo->prDevHandler->ieee80211_ptr; -+ mtk_cfg80211_add_station(prWdev->wiphy, (void *)0x1, rCmd.arRspAddr, &rCmd.rPeerInfo); -+ -+ /* update */ -+ TdlsexCfg80211TdlsOper(prWdev->wiphy, (void *)0x1, rCmd.arRspAddr, NL80211_TDLS_ENABLE_LINK); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to receive a Null frame from the peer. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set -+* \param[in] u4SetBufferLen The length of the set buffer -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed due to invalid length of -+* the set buffer, returns the amount of storage needed. -+* -+* \retval TDLS_STATUS_xx -+* -+* EX: iwpriv wlan0 set_str_cmd 0_5_[Responder MAC]_[PM bit] -+ -+ iwpriv wlan0 set_str_cmd 0_5_00:11:22:33:44:01_1 -+*/ -+/*----------------------------------------------------------------------------*/ -+static void TdlsCmdTestNullRecv(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) -+{ -+ WLAN_STATUS rStatus; -+ TDLS_CMD_CORE_T rCmd; -+ UINT_32 u4BufLen; -+ -+ /* parse arguments */ -+ CmdStringMacParse(prInBuf, &prInBuf, &u4InBufLen, rCmd.aucPeerMac); -+ rCmd.Content.rCmdNullRcv.u4PM = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ -+ DBGLOG(TDLS, INFO, "%s: [%pM] u4PM = %u\n", -+ __func__, (rCmd.aucPeerMac), (UINT32) rCmd.Content.rCmdNullRcv.u4PM); -+ -+ /* command to do this */ -+ rStatus = kalIoctl(prGlueInfo, TdlsTestNullRecv, &rCmd, sizeof(rCmd), FALSE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ DBGLOG(TDLS, ERROR, "%s kalIoctl fail:%x\n", __func__, rStatus); -+ return; -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to send a data frame to the peer periodically. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* \param[in] u4Param no use -+* \param[out] None -+* -+* \retval None -+* -+* EX: iwpriv wlan0 set_str_cmd 0_15_[Responder MAC]_[Interval: ms]_[Enable/Disable] -+ -+ iwpriv wlan0 set_str_cmd 0_15_00:11:22:33:44:01_5000_1 -+*/ -+/*----------------------------------------------------------------------------*/ -+static VOID TdlsTimerTestDataContSend(ADAPTER_T *prAdapter, UINT_32 u4Param) -+{ -+ GLUE_INFO_T *prGlueInfo; -+ struct sk_buff *prMsduInfo; -+ UINT_8 *prPkt; -+ -+ /* init */ -+ prGlueInfo = prAdapter->prGlueInfo; -+ -+ /* allocate a data frame */ -+ prMsduInfo = kalPacketAlloc(prGlueInfo, 1000, &prPkt); -+ if (prMsduInfo == NULL) { -+ DBGLOG(TDLS, ERROR, " %s allocate pkt fail!\n", __func__); -+ return; -+ } -+ -+ /* init dev */ -+ prMsduInfo->dev = prGlueInfo->prDevHandler; -+ if (prMsduInfo->dev == NULL) { -+ DBGLOG(TDLS, ERROR, " %s prMsduInfo->dev == NULL!\n", __func__); -+ kalPacketFree(prGlueInfo, prMsduInfo); -+ return; -+ } -+ -+ /* init packet */ -+ prMsduInfo->len = 1000; -+ kalMemCopy(prMsduInfo->data, aucTdlsTestDataSPeerMac, 6); -+ kalMemCopy(prMsduInfo->data + 6, prAdapter->rMyMacAddr, 6); -+ *(UINT_16 *) (prMsduInfo->data + 12) = 0x0800; -+ -+ DBGLOG(TDLS, INFO, " %s try to send a data frame to %pM\n", -+ __func__, aucTdlsTestDataSPeerMac); -+ -+ /* simulate OS to send the packet */ -+ wlanHardStartXmit(prMsduInfo, prMsduInfo->dev); -+ -+ /* restart test timer */ -+ cnmTimerStartTimer(prAdapter, &rTdlsTimerTestDataSend, u2TdlsTestDataSInterval); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to receive a Channel Switch Request frame. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set -+* \param[in] u4SetBufferLen The length of the set buffer -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed due to invalid length of -+* the set buffer, returns the amount of storage needed. -+* -+* \retval TDLS_STATUS_xx -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static TDLS_STATUS -+TdlsTestChStReqRecv(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen) -+{ -+ TDLS_CMD_CORE_T *prCmdContent; -+ WLAN_STATUS rStatus; -+ -+ /* init command buffer */ -+ prCmdContent = (TDLS_CMD_CORE_T *) pvSetBuffer; -+ prCmdContent->u4Command = TDLS_CORE_CMD_TEST_CHSW_REQ; -+ -+ /* send the command */ -+ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ -+ CMD_ID_TDLS_CORE, /* ucCID */ -+ TRUE, /* fgSetQuery */ -+ FALSE, /* fgNeedResp */ -+ FALSE, /* fgIsOid */ -+ NULL, NULL, /* pfCmdTimeoutHandler */ -+ sizeof(TDLS_CMD_CORE_T), /* u4SetQueryInfoLen */ -+ (PUINT_8) prCmdContent, /* pucInfoBuffer */ -+ NULL, /* pvSetQueryBuffer */ -+ 0 /* u4SetQueryBufferLen */ -+ ); -+ -+ if (rStatus != WLAN_STATUS_PENDING) { -+ DBGLOG(TDLS, ERROR, "%s wlanSendSetQueryCmd allocation fail!\n", __func__); -+ return TDLS_STATUS_RESOURCES; -+ } -+ -+ DBGLOG(TDLS, INFO, "%s cmd ok.\n", __func__); -+ return TDLS_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to receive a Channel Switch Response frame. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set -+* \param[in] u4SetBufferLen The length of the set buffer -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed due to invalid length of -+* the set buffer, returns the amount of storage needed. -+* -+* \retval TDLS_STATUS_xx -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static TDLS_STATUS -+TdlsTestChStRspRecv(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen) -+{ -+ TDLS_CMD_CORE_T *prCmdContent; -+ WLAN_STATUS rStatus; -+ -+ /* init command buffer */ -+ prCmdContent = (TDLS_CMD_CORE_T *) pvSetBuffer; -+ prCmdContent->u4Command = TDLS_CORE_CMD_TEST_CHSW_RSP; -+ -+ /* send the command */ -+ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ -+ CMD_ID_TDLS_CORE, /* ucCID */ -+ TRUE, /* fgSetQuery */ -+ FALSE, /* fgNeedResp */ -+ FALSE, /* fgIsOid */ -+ NULL, NULL, /* pfCmdTimeoutHandler */ -+ sizeof(TDLS_CMD_CORE_T), /* u4SetQueryInfoLen */ -+ (PUINT_8) prCmdContent, /* pucInfoBuffer */ -+ NULL, /* pvSetQueryBuffer */ -+ 0 /* u4SetQueryBufferLen */ -+ ); -+ -+ if (rStatus != WLAN_STATUS_PENDING) { -+ DBGLOG(TDLS, ERROR, "%s wlanSendSetQueryCmd allocation fail!\n", __func__); -+ return TDLS_STATUS_RESOURCES; -+ } -+ -+ DBGLOG(TDLS, INFO, "%s cmd ok.\n", __func__); -+ return TDLS_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to send a test frame. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set -+* \param[in] u4SetBufferLen The length of the set buffer -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed due to invalid length of -+* the set buffer, returns the amount of storage needed. -+* -+* \retval TDLS_STATUS_xx -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static TDLS_STATUS -+TdlsTestFrameSend(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen) -+{ -+ GLUE_INFO_T *prGlueInfo; -+ PARAM_CUSTOM_TDLS_CMD_STRUCT_T *prCmd; -+ P_BSS_INFO_T prBssInfo; -+ struct sk_buff *prMsduInfo; -+ UINT_8 *pPkt; -+ UINT_32 u4PktLen, u4IeLen; -+ -+ /* sanity check */ -+ ASSERT(prAdapter); -+ ASSERT(pvSetBuffer); -+ ASSERT(pu4SetInfoLen); -+ -+ DBGLOG(TDLS, INFO, " %s\n", __func__); -+ -+ if (u4SetBufferLen == 0) -+ return TDLS_STATUS_INVALID_LENGTH; -+ -+ /* allocate/init packet */ -+ prGlueInfo = (GLUE_INFO_T *) prAdapter->prGlueInfo; -+ prCmd = (PARAM_CUSTOM_TDLS_CMD_STRUCT_T *) pvSetBuffer; -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ *pu4SetInfoLen = u4SetBufferLen; -+ u4PktLen = 0; -+ -+ prMsduInfo = kalPacketAlloc(prGlueInfo, 1600, &pPkt); -+ if (prMsduInfo == NULL) { -+ DBGLOG(TDLS, ERROR, " %s: allocate pkt fail\n", __func__); -+ return TDLS_STATUS_RESOURCES; -+ } -+ -+ prMsduInfo->dev = prGlueInfo->prDevHandler; -+ if (prMsduInfo->dev == NULL) { -+ DBGLOG(TDLS, ERROR, " %s: MsduInfo->dev == NULL\n", __func__); -+ kalPacketFree(prGlueInfo, prMsduInfo); -+ return TDLS_STATUS_FAILURE; -+ } -+ -+ /* make up frame content */ -+ /* 1. 802.3 header */ -+ kalMemCopy(pPkt, prCmd->arRspAddr, TDLS_FME_MAC_ADDR_LEN); -+ LR_TDLS_FME_FIELD_FILL(TDLS_FME_MAC_ADDR_LEN); -+ kalMemCopy(pPkt, prAdapter->rMyMacAddr, TDLS_FME_MAC_ADDR_LEN); -+ LR_TDLS_FME_FIELD_FILL(TDLS_FME_MAC_ADDR_LEN); -+ *(UINT_16 *) pPkt = htons(TDLS_FRM_PROT_TYPE); -+ LR_TDLS_FME_FIELD_FILL(2); -+ -+ /* 2. payload type */ -+ *pPkt = TDLS_FRM_PAYLOAD_TYPE; -+ LR_TDLS_FME_FIELD_FILL(1); -+ -+ /* 3. Frame Formation - (1) Category */ -+ *pPkt = TDLS_FRM_CATEGORY; -+ LR_TDLS_FME_FIELD_FILL(1); -+ -+ /* 3. Frame Formation - (2) Action */ -+ *pPkt = prCmd->ucFmeType; -+ LR_TDLS_FME_FIELD_FILL(1); -+ -+ /* 3. Frame Formation - (3) Dialog token */ -+ *pPkt = prCmd->ucToken; -+ LR_TDLS_FME_FIELD_FILL(1); -+ -+ /* 3. Frame Formation - (4) Capability */ -+ WLAN_SET_FIELD_16(pPkt, prCmd->u2Cap); -+ LR_TDLS_FME_FIELD_FILL(2); -+ -+ /* 4. Append general IEs */ -+ u4IeLen = TdlsFrameGeneralIeAppend(prAdapter, NULL, 0, pPkt); -+ LR_TDLS_FME_FIELD_FILL(u4IeLen); -+ -+ /* 3. Frame Formation - (10) Extended capabilities element */ -+ EXT_CAP_IE(pPkt)->ucId = ELEM_ID_EXTENDED_CAP; -+ EXT_CAP_IE(pPkt)->ucLength = 5; -+ -+ EXT_CAP_IE(pPkt)->aucCapabilities[0] = 0x00; /* bit0 ~ bit7 */ -+ EXT_CAP_IE(pPkt)->aucCapabilities[1] = 0x00; /* bit8 ~ bit15 */ -+ EXT_CAP_IE(pPkt)->aucCapabilities[2] = 0x00; /* bit16 ~ bit23 */ -+ EXT_CAP_IE(pPkt)->aucCapabilities[3] = 0x00; /* bit24 ~ bit31 */ -+ EXT_CAP_IE(pPkt)->aucCapabilities[4] = 0x00; /* bit32 ~ bit39 */ -+ -+ if (prCmd->ucExCap & TDLS_EX_CAP_PEER_UAPSD) -+ EXT_CAP_IE(pPkt)->aucCapabilities[3] |= BIT((28 - 24)); -+ if (prCmd->ucExCap & TDLS_EX_CAP_CHAN_SWITCH) -+ EXT_CAP_IE(pPkt)->aucCapabilities[3] |= BIT((30 - 24)); -+ if (prCmd->ucExCap & TDLS_EX_CAP_TDLS) -+ EXT_CAP_IE(pPkt)->aucCapabilities[4] |= BIT((37 - 32)); -+ -+ u4IeLen = IE_SIZE(pPkt); -+ LR_TDLS_FME_FIELD_FILL(u4IeLen); -+ -+ /* 3. Frame Formation - (12) Timeout interval element (TPK Key Lifetime) */ -+ TIMEOUT_INTERVAL_IE(pPkt)->ucId = ELEM_ID_TIMEOUT_INTERVAL; -+ TIMEOUT_INTERVAL_IE(pPkt)->ucLength = 5; -+ -+ TIMEOUT_INTERVAL_IE(pPkt)->ucType = IE_TIMEOUT_INTERVAL_TYPE_KEY_LIFETIME; -+ TIMEOUT_INTERVAL_IE(pPkt)->u4Value = htonl(prCmd->u4Timeout); -+ -+ u4IeLen = IE_SIZE(pPkt); -+ LR_TDLS_FME_FIELD_FILL(u4IeLen); -+ -+ /* 3. Frame Formation - (16) Link identifier element */ -+ TDLS_LINK_IDENTIFIER_IE(pPkt)->ucId = ELEM_ID_LINK_IDENTIFIER; -+ TDLS_LINK_IDENTIFIER_IE(pPkt)->ucLength = ELEM_LEN_LINK_IDENTIFIER; -+ -+ kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aBSSID, prBssInfo->aucBSSID, 6); -+ kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aInitiator, prAdapter->rMyMacAddr, 6); -+ kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aResponder, prCmd->arRspAddr, 6); -+ -+ u4IeLen = IE_SIZE(pPkt); -+ LR_TDLS_FME_FIELD_FILL(u4IeLen); -+ -+ /* 4. Update packet length */ -+ prMsduInfo->len = u4PktLen; -+ dumpMemory8(prMsduInfo->data, u4PktLen); -+ -+ /* 5. send the data frame */ -+ wlanHardStartXmit(prMsduInfo, prMsduInfo->dev); -+ return TDLS_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to receive a NULL frame. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set -+* \param[in] u4SetBufferLen The length of the set buffer -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed due to invalid length of -+* the set buffer, returns the amount of storage needed. -+* -+* \retval TDLS_STATUS_xx -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static TDLS_STATUS -+TdlsTestNullRecv(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen) -+{ -+ TDLS_CMD_CORE_T *prCmdContent; -+ WLAN_STATUS rStatus; -+ -+ /* init command buffer */ -+ prCmdContent = (TDLS_CMD_CORE_T *) pvSetBuffer; -+ prCmdContent->u4Command = TDLS_CORE_CMD_TEST_NULL_RCV; -+ -+ /* send the command */ -+ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ -+ CMD_ID_TDLS_CORE, /* ucCID */ -+ TRUE, /* fgSetQuery */ -+ FALSE, /* fgNeedResp */ -+ FALSE, /* fgIsOid */ -+ NULL, NULL, /* pfCmdTimeoutHandler */ -+ sizeof(TDLS_CMD_CORE_T), /* u4SetQueryInfoLen */ -+ (PUINT_8) prCmdContent, /* pucInfoBuffer */ -+ NULL, /* pvSetQueryBuffer */ -+ 0 /* u4SetQueryBufferLen */ -+ ); -+ -+ if (rStatus != WLAN_STATUS_PENDING) { -+ DBGLOG(TDLS, ERROR, "%s wlanSendSetQueryCmd allocation fail!\n", __func__); -+ return TDLS_STATUS_RESOURCES; -+ } -+ -+ DBGLOG(TDLS, INFO, "%s cmd ok.\n", __func__); -+ return TDLS_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to receive a PTI frame. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set -+* \param[in] u4SetBufferLen The length of the set buffer -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed due to invalid length of -+* the set buffer, returns the amount of storage needed. -+* -+* \retval TDLS_STATUS_xx -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static TDLS_STATUS -+TdlsTestPtiReqRecv(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen) -+{ -+ TDLS_CMD_CORE_T *prCmdContent; -+ WLAN_STATUS rStatus; -+ -+ /* init command buffer */ -+ prCmdContent = (TDLS_CMD_CORE_T *) pvSetBuffer; -+ prCmdContent->u4Command = TDLS_CORE_CMD_TEST_PTI_REQ; -+ -+ /* send the command */ -+ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ -+ CMD_ID_TDLS_CORE, /* ucCID */ -+ TRUE, /* fgSetQuery */ -+ FALSE, /* fgNeedResp */ -+ FALSE, /* fgIsOid */ -+ NULL, NULL, /* pfCmdTimeoutHandler */ -+ sizeof(TDLS_CMD_CORE_T), /* u4SetQueryInfoLen */ -+ (PUINT_8) prCmdContent, /* pucInfoBuffer */ -+ NULL, /* pvSetQueryBuffer */ -+ 0 /* u4SetQueryBufferLen */ -+ ); -+ -+ if (rStatus != WLAN_STATUS_PENDING) { -+ DBGLOG(TDLS, ERROR, "%s wlanSendSetQueryCmd allocation fail!\n", __func__); -+ return TDLS_STATUS_RESOURCES; -+ } -+ -+ DBGLOG(TDLS, INFO, "%s cmd ok.\n", __func__); -+ return TDLS_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to receive a PTI response frame. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set -+* \param[in] u4SetBufferLen The length of the set buffer -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed due to invalid length of -+* the set buffer, returns the amount of storage needed. -+* -+* \retval TDLS_STATUS_xx -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static TDLS_STATUS -+TdlsTestPtiRspRecv(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen) -+{ -+ TDLS_CMD_CORE_T *prCmdContent; -+ WLAN_STATUS rStatus; -+ -+ /* init command buffer */ -+ prCmdContent = (TDLS_CMD_CORE_T *) pvSetBuffer; -+ prCmdContent->u4Command = TDLS_CORE_CMD_TEST_PTI_RSP; -+ -+ /* send the command */ -+ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ -+ CMD_ID_TDLS_CORE, /* ucCID */ -+ TRUE, /* fgSetQuery */ -+ FALSE, /* fgNeedResp */ -+ FALSE, /* fgIsOid */ -+ NULL, NULL, /* pfCmdTimeoutHandler */ -+ sizeof(TDLS_CMD_CORE_T), /* u4SetQueryInfoLen */ -+ (PUINT_8) prCmdContent, /* pucInfoBuffer */ -+ NULL, /* pvSetQueryBuffer */ -+ 0 /* u4SetQueryBufferLen */ -+ ); -+ -+ if (rStatus != WLAN_STATUS_PENDING) { -+ DBGLOG(TDLS, ERROR, "%s wlanSendSetQueryCmd allocation fail!\n", __func__); -+ return TDLS_STATUS_RESOURCES; -+ } -+ -+ DBGLOG(TDLS, INFO, "%s cmd ok.\n", __func__); -+ return TDLS_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to receive a Tear Down frame. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set -+* \param[in] u4SetBufferLen The length of the set buffer -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed due to invalid length of -+* the set buffer, returns the amount of storage needed. -+* -+* \retval TDLS_STATUS_xx -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static TDLS_STATUS -+TdlsTestTearDownRecv(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen) -+{ -+ TDLS_CMD_CORE_T *prCmdContent; -+ WLAN_STATUS rStatus; -+ -+ /* init command buffer */ -+ prCmdContent = (TDLS_CMD_CORE_T *) pvSetBuffer; -+ prCmdContent->u4Command = TDLS_CORE_CMD_TEST_TEAR_DOWN; -+ -+ /* send the command */ -+ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ -+ CMD_ID_TDLS_CORE, /* ucCID */ -+ TRUE, /* fgSetQuery */ -+ FALSE, /* fgNeedResp */ -+ FALSE, /* fgIsOid */ -+ NULL, NULL, /* pfCmdTimeoutHandler */ -+ sizeof(TDLS_CMD_CORE_T), /* u4SetQueryInfoLen */ -+ (PUINT_8) prCmdContent, /* pucInfoBuffer */ -+ NULL, /* pvSetQueryBuffer */ -+ 0 /* u4SetQueryBufferLen */ -+ ); -+ -+ if (rStatus != WLAN_STATUS_PENDING) { -+ DBGLOG(TDLS, ERROR, "%s wlanSendSetQueryCmd allocation fail!\n", __func__); -+ return TDLS_STATUS_RESOURCES; -+ } -+ -+ DBGLOG(TDLS, INFO, "%s cmd ok.\n", __func__); -+ return TDLS_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to receive a data frame. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set -+* \param[in] u4SetBufferLen The length of the set buffer -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed due to invalid length of -+* the set buffer, returns the amount of storage needed. -+* -+* \retval TDLS_STATUS_xx -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static TDLS_STATUS -+TdlsTestDataRecv(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen) -+{ -+ TDLS_CMD_CORE_T *prCmdContent; -+ WLAN_STATUS rStatus; -+ -+ /* init command buffer */ -+ prCmdContent = (TDLS_CMD_CORE_T *) pvSetBuffer; -+ prCmdContent->u4Command = TDLS_CORE_CMD_TEST_DATA_RCV; -+ -+ /* send the command */ -+ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ -+ CMD_ID_TDLS_CORE, /* ucCID */ -+ TRUE, /* fgSetQuery */ -+ FALSE, /* fgNeedResp */ -+ FALSE, /* fgIsOid */ -+ NULL, NULL, /* pfCmdTimeoutHandler */ -+ sizeof(TDLS_CMD_CORE_T), /* u4SetQueryInfoLen */ -+ (PUINT_8) prCmdContent, /* pucInfoBuffer */ -+ NULL, /* pvSetQueryBuffer */ -+ 0 /* u4SetQueryBufferLen */ -+ ); -+ -+ if (rStatus != WLAN_STATUS_PENDING) { -+ DBGLOG(TDLS, ERROR, "%s wlanSendSetQueryCmd allocation fail!\n", __func__); -+ return TDLS_STATUS_RESOURCES; -+ } -+ -+ DBGLOG(TDLS, INFO, "%s cmd ok.\n", __func__); -+ return TDLS_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to skip PTI tx fail status. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set -+* \param[in] u4SetBufferLen The length of the set buffer -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed due to invalid length of -+* the set buffer, returns the amount of storage needed. -+* -+* \retval TDLS_STATUS_xx -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static TDLS_STATUS -+TdlsTestPtiTxFail(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen) -+{ -+ TDLS_CMD_CORE_T *prCmdContent; -+ WLAN_STATUS rStatus; -+ -+ /* init command buffer */ -+ prCmdContent = (TDLS_CMD_CORE_T *) pvSetBuffer; -+ prCmdContent->u4Command = TDLS_CORE_CMD_TEST_PTI_TX_FAIL; -+ -+ /* send the command */ -+ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ -+ CMD_ID_TDLS_CORE, /* ucCID */ -+ TRUE, /* fgSetQuery */ -+ FALSE, /* fgNeedResp */ -+ FALSE, /* fgIsOid */ -+ NULL, NULL, /* pfCmdTimeoutHandler */ -+ sizeof(TDLS_CMD_CORE_T), /* u4SetQueryInfoLen */ -+ (PUINT_8) prCmdContent, /* pucInfoBuffer */ -+ NULL, /* pvSetQueryBuffer */ -+ 0 /* u4SetQueryBufferLen */ -+ ); -+ -+ if (rStatus != WLAN_STATUS_PENDING) { -+ DBGLOG(TDLS, ERROR, "%s wlanSendSetQueryCmd allocation fail!\n", __func__); -+ return TDLS_STATUS_RESOURCES; -+ } -+ -+ DBGLOG(TDLS, INFO, "%s cmd ok.\n", __func__); -+ return TDLS_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to send a TDLS action frame. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set -+* \param[in] u4SetBufferLen The length of the set buffer -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed due to invalid length of -+* the set buffer, returns the amount of storage needed. -+* -+* \retval TDLS_STATUS_xx -+* -+* EX: iwpriv wlan0 set_str_cmd 0_12_0_[FrameType]_[DialogToken]_[Peer MAC] -+ -+ iwpriv wlan0 set_str_cmd 0_12_0_0_1_00:11:22:33:44:01 -+*/ -+/*----------------------------------------------------------------------------*/ -+static TDLS_STATUS -+TdlsTestTdlsFrameSend(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen) -+{ -+ GLUE_INFO_T *prGlueInfo; -+ PARAM_CUSTOM_TDLS_CMD_STRUCT_T *prCmd; -+ struct wireless_dev *prWdev; -+ -+ /* sanity check */ -+ ASSERT(prAdapter); -+ ASSERT(pvSetBuffer); -+ ASSERT(pu4SetInfoLen); -+ -+ DBGLOG(TDLS, INFO, " %s\n", __func__); -+ -+ if (u4SetBufferLen == 0) -+ return TDLS_STATUS_INVALID_LENGTH; -+ -+ /* allocate/init packet */ -+ prGlueInfo = (GLUE_INFO_T *) prAdapter->prGlueInfo; -+ prCmd = (PARAM_CUSTOM_TDLS_CMD_STRUCT_T *) pvSetBuffer; -+ prWdev = (struct wireless_dev *)prGlueInfo->prDevHandler->ieee80211_ptr; -+ -+ TdlsexCfg80211TdlsMgmt(prWdev->wiphy, NULL, -+ prCmd->arRspAddr, prCmd->ucFmeType, 1, -+ 0, 0, /* open/none */ -+ FALSE, NULL, 0); -+ -+ return TDLS_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to skip tx fail status. So always success in tx done in firmware. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set -+* \param[in] u4SetBufferLen The length of the set buffer -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed due to invalid length of -+* the set buffer, returns the amount of storage needed. -+* -+* \retval TDLS_STATUS_xx -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static TDLS_STATUS -+TdlsTestTxFailSkip(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen) -+{ -+ TDLS_CMD_CORE_T *prCmdContent; -+ WLAN_STATUS rStatus; -+ -+ /* init command buffer */ -+ prCmdContent = (TDLS_CMD_CORE_T *) pvSetBuffer; -+ prCmdContent->u4Command = TDLS_CORE_CMD_TEST_TX_FAIL_SKIP; -+ -+ /* send the command */ -+ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ -+ CMD_ID_TDLS_CORE, /* ucCID */ -+ TRUE, /* fgSetQuery */ -+ FALSE, /* fgNeedResp */ -+ FALSE, /* fgIsOid */ -+ NULL, NULL, /* pfCmdTimeoutHandler */ -+ sizeof(TDLS_CMD_CORE_T), /* u4SetQueryInfoLen */ -+ (PUINT_8) prCmdContent, /* pucInfoBuffer */ -+ NULL, /* pvSetQueryBuffer */ -+ 0 /* u4SetQueryBufferLen */ -+ ); -+ -+ if (rStatus != WLAN_STATUS_PENDING) { -+ DBGLOG(TDLS, ERROR, "%s wlanSendSetQueryCmd allocation fail!\n", __func__); -+ return TDLS_STATUS_RESOURCES; -+ } -+ -+ DBGLOG(TDLS, INFO, "%s cmd ok.\n", __func__); -+ return TDLS_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to skip to do keep alive function in firmware. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set -+* \param[in] u4SetBufferLen The length of the set buffer -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed due to invalid length of -+* the set buffer, returns the amount of storage needed. -+* -+* \retval TDLS_STATUS_xx -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static TDLS_STATUS -+TdlsTestKeepAliveSkip(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen) -+{ -+ TDLS_CMD_CORE_T *prCmdContent; -+ WLAN_STATUS rStatus; -+ -+ /* init command buffer */ -+ prCmdContent = (TDLS_CMD_CORE_T *) pvSetBuffer; -+ prCmdContent->u4Command = TDLS_CORE_CMD_TEST_KEEP_ALIVE_SKIP; -+ -+ /* send the command */ -+ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ -+ CMD_ID_TDLS_CORE, /* ucCID */ -+ TRUE, /* fgSetQuery */ -+ FALSE, /* fgNeedResp */ -+ FALSE, /* fgIsOid */ -+ NULL, NULL, /* pfCmdTimeoutHandler */ -+ sizeof(TDLS_CMD_CORE_T), /* u4SetQueryInfoLen */ -+ (PUINT_8) prCmdContent, /* pucInfoBuffer */ -+ NULL, /* pvSetQueryBuffer */ -+ 0 /* u4SetQueryBufferLen */ -+ ); -+ -+ if (rStatus != WLAN_STATUS_PENDING) { -+ DBGLOG(TDLS, ERROR, "%s wlanSendSetQueryCmd allocation fail!\n", __func__); -+ return TDLS_STATUS_RESOURCES; -+ } -+ -+ DBGLOG(TDLS, INFO, "%s cmd ok.\n", __func__); -+ return TDLS_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to skip channel switch timeout. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set -+* \param[in] u4SetBufferLen The length of the set buffer -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed due to invalid length of -+* the set buffer, returns the amount of storage needed. -+* -+* \retval TDLS_STATUS_xx -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static TDLS_STATUS -+TdlsTestChSwTimeoutSkip(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen) -+{ -+ TDLS_CMD_CORE_T *prCmdContent; -+ WLAN_STATUS rStatus; -+ -+ /* init command buffer */ -+ prCmdContent = (TDLS_CMD_CORE_T *) pvSetBuffer; -+ prCmdContent->u4Command = TDLS_CORE_CMD_TEST_CHSW_TIMEOUT_SKIP; -+ -+ /* send the command */ -+ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ -+ CMD_ID_TDLS_CORE, /* ucCID */ -+ TRUE, /* fgSetQuery */ -+ FALSE, /* fgNeedResp */ -+ FALSE, /* fgIsOid */ -+ NULL, NULL, /* pfCmdTimeoutHandler */ -+ sizeof(TDLS_CMD_CORE_T), /* u4SetQueryInfoLen */ -+ (PUINT_8) prCmdContent, /* pucInfoBuffer */ -+ NULL, /* pvSetQueryBuffer */ -+ 0 /* u4SetQueryBufferLen */ -+ ); -+ -+ if (rStatus != WLAN_STATUS_PENDING) { -+ DBGLOG(TDLS, ERROR, "%s wlanSendSetQueryCmd allocation fail!\n", __func__); -+ return TDLS_STATUS_RESOURCES; -+ } -+ -+ DBGLOG(TDLS, INFO, "%s cmd ok.\n", __func__); -+ return TDLS_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to skip scan request. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set -+* \param[in] u4SetBufferLen The length of the set buffer -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed due to invalid length of -+* the set buffer, returns the amount of storage needed. -+* -+* \retval TDLS_STATUS_xx -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static TDLS_STATUS -+TdlsTestScanSkip(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen) -+{ -+ TDLS_CMD_CORE_T *prCmdContent; -+ WLAN_STATUS rStatus; -+ -+ /* init command buffer */ -+ prCmdContent = (TDLS_CMD_CORE_T *) pvSetBuffer; -+ prCmdContent->u4Command = TDLS_CORE_CMD_TEST_SCAN_SKIP; -+ -+ /* send the command */ -+ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ -+ CMD_ID_TDLS_CORE, /* ucCID */ -+ TRUE, /* fgSetQuery */ -+ FALSE, /* fgNeedResp */ -+ FALSE, /* fgIsOid */ -+ NULL, NULL, /* pfCmdTimeoutHandler */ -+ sizeof(TDLS_CMD_CORE_T), /* u4SetQueryInfoLen */ -+ (PUINT_8) prCmdContent, /* pucInfoBuffer */ -+ NULL, /* pvSetQueryBuffer */ -+ 0 /* u4SetQueryBufferLen */ -+ ); -+ -+ if (rStatus != WLAN_STATUS_PENDING) { -+ DBGLOG(TDLS, ERROR, "%s wlanSendSetQueryCmd allocation fail!\n", __func__); -+ return TDLS_STATUS_RESOURCES; -+ } -+ -+ DBGLOG(TDLS, INFO, "%s cmd ok.\n", __func__); -+ return TDLS_STATUS_SUCCESS; -+} -+ -+#endif /* TDLS_CFG_CMD_TEST */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to configure channel switch parameters. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set -+* \param[in] u4SetBufferLen The length of the set buffer -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed due to invalid length of -+* the set buffer, returns the amount of storage needed. -+* -+* \retval TDLS_STATUS_xx -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static TDLS_STATUS -+TdlsChSwConf(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen) -+{ -+ TDLS_CMD_CORE_T *prCmdContent; -+ WLAN_STATUS rStatus; -+ -+ /* init command buffer */ -+ prCmdContent = (TDLS_CMD_CORE_T *) pvSetBuffer; -+ prCmdContent->u4Command = TDLS_CORE_CMD_CHSW_CONF; -+ -+ /* send the command */ -+ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ -+ CMD_ID_TDLS_CORE, /* ucCID */ -+ TRUE, /* fgSetQuery */ -+ FALSE, /* fgNeedResp */ -+ FALSE, /* fgIsOid */ -+ NULL, NULL, /* pfCmdTimeoutHandler */ -+ sizeof(TDLS_CMD_CORE_T), /* u4SetQueryInfoLen */ -+ (PUINT_8) prCmdContent, /* pucInfoBuffer */ -+ NULL, /* pvSetQueryBuffer */ -+ 0 /* u4SetQueryBufferLen */ -+ ); -+ -+ if (rStatus != WLAN_STATUS_PENDING) { -+ DBGLOG(TDLS, ERROR, "%s wlanSendSetQueryCmd allocation fail!\n", __func__); -+ return TDLS_STATUS_RESOURCES; -+ } -+ -+ DBGLOG(TDLS, INFO, "%s cmd ok.\n", __func__); -+ return TDLS_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to update channel switch parameters. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prInBuf A pointer to the command string buffer -+* \param[in] u4InBufLen The length of the buffer -+* \param[out] None -+* -+* \retval None -+* -+* EX: iwpriv wlan0 set_str_cmd 0_9_[TDLS Peer MAC]_ -+ [NetworkTypeIndex]_[1 (Enable) or (0) Disable]_[1 (Start) or 0 (Stop)]_ -+ [RegClass]_[Chan]_[SecChanOff]_[1 (Reqular) or (0) One Shot] -+ -+ RegulatoryClass: TODO (reference to Annex I of 802.11n spec.) -+ Secondary Channel Offset: 0 (SCN - no secondary channel) -+ 1 (SCA - secondary channel above) -+ 2 (SCB - secondary channel below) -+ SwitchTime: units of microseconds -+ -+ iwpriv wlan0 set_str_cmd 0_9_00:11:22:33:44:01_0_1_0_0_1_0_0 -+*/ -+/*----------------------------------------------------------------------------*/ -+static void TdlsCmdChSwConf(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) -+{ -+ WLAN_STATUS rStatus; -+ TDLS_CMD_CORE_T rCmd; -+ UINT_32 u4BufLen; -+ -+ /* parse arguments */ -+ CmdStringMacParse(prInBuf, &prInBuf, &u4InBufLen, rCmd.aucPeerMac); -+ -+ rCmd.Content.rCmdChSwConf.ucNetTypeIndex = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ rCmd.Content.rCmdChSwConf.fgIsChSwEnabled = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ rCmd.Content.rCmdChSwConf.fgIsChSwStarted = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ rCmd.Content.rCmdChSwConf.ucRegClass = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ rCmd.Content.rCmdChSwConf.ucTargetChan = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ rCmd.Content.rCmdChSwConf.ucSecChanOff = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ rCmd.Content.rCmdChSwConf.fgIsChSwRegular = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ -+ DBGLOG(TDLS, INFO, "%s: %pM ucNetTypeIndex=%d, fgIsChSwEnabled=%d, fgIsChSwStarted=%d", -+ __func__, (rCmd.aucPeerMac), -+ rCmd.Content.rCmdChSwConf.ucNetTypeIndex, -+ rCmd.Content.rCmdChSwConf.fgIsChSwEnabled, -+ rCmd.Content.rCmdChSwConf.fgIsChSwStarted); -+ DBGLOG(TDLS, INFO, " RegClass=%d, TargetChan=%d, SecChanOff=%d, Regular=%d\n", -+ rCmd.Content.rCmdChSwConf.ucRegClass, -+ rCmd.Content.rCmdChSwConf.ucTargetChan, -+ rCmd.Content.rCmdChSwConf.ucSecChanOff, rCmd.Content.rCmdChSwConf.fgIsChSwRegular); -+ -+ /* command to do this */ -+ rStatus = kalIoctl(prGlueInfo, TdlsChSwConf, &rCmd, sizeof(rCmd), FALSE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ DBGLOG(TDLS, ERROR, "%s kalIoctl fail:%x\n", __func__, rStatus); -+ return; -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to display TDLS related information. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prInBuf A pointer to the command string buffer -+* \param[in] u4InBufLen The length of the buffer -+* \param[out] None -+* -+* \retval None -+* -+* EX: iwpriv wlan0 set_str_cmd 0_18_[Peer MAC]_[Network Interface ID]_[IsClear] -+ -+ Network Interface ID: reference to ENUM_NETWORK_TYPE_INDEX_T -+ -+ typedef enum _ENUM_NETWORK_TYPE_INDEX_T { -+ NETWORK_TYPE_AIS_INDEX = 0, -+ NETWORK_TYPE_P2P_INDEX, -+ NETWORK_TYPE_BOW_INDEX, -+ NETWORK_TYPE_INDEX_NUM -+ } ENUM_NETWORK_TYPE_INDEX_T; -+ -+ iwpriv wlan0 set_str_cmd 0_18_00:00:00:00:00:00_0_0 -+*/ -+/*----------------------------------------------------------------------------*/ -+static void TdlsCmdInfoDisplay(GLUE_INFO_T *prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) -+{ -+ WLAN_STATUS rStatus; -+ TDLS_CMD_CORE_T rCmd; -+ UINT_32 u4BufLen; -+ -+ /* parse arguments */ -+ kalMemZero(&rCmd, sizeof(rCmd)); -+ -+ CmdStringMacParse(prInBuf, &prInBuf, &u4InBufLen, rCmd.aucPeerMac); -+ rCmd.ucNetTypeIndex = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ rCmd.Content.rCmdInfoDisplay.fgIsToClearAllHistory = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ -+ DBGLOG(TDLS, INFO, " %s: Command PeerMac=%pM in BSS%u\n", -+ __func__, (rCmd.aucPeerMac), rCmd.ucNetTypeIndex); -+ -+ /* command to do this */ -+ rStatus = kalIoctl(prGlueInfo, TdlsInfoDisplay, &rCmd, sizeof(rCmd), FALSE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ DBGLOG(TDLS, ERROR, "%s kalIoctl fail:%x\n", __func__, rStatus); -+ return; -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to display key related information. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prInBuf A pointer to the command string buffer -+* \param[in] u4InBufLen The length of the buffer -+* \param[out] None -+* -+* \retval None -+* -+* EX: iwpriv wlan0 set_str_cmd 0_20 -+ -+ iwpriv wlan0 set_str_cmd 0_20 -+*/ -+/*----------------------------------------------------------------------------*/ -+static void TdlsCmdKeyInfoDisplay(GLUE_INFO_T *prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) -+{ -+ WLAN_STATUS rStatus; -+ TDLS_CMD_CORE_T rCmd; -+ UINT_32 u4BufLen; -+ -+ /* parse arguments */ -+ kalMemZero(&rCmd, sizeof(rCmd)); -+ -+ DBGLOG(TDLS, INFO, " %s\n", __func__); -+ -+ /* command to do this */ -+ rStatus = kalIoctl(prGlueInfo, TdlsKeyInfoDisplay, &rCmd, sizeof(rCmd), FALSE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ DBGLOG(TDLS, ERROR, "%s kalIoctl fail:%x\n", __func__, rStatus); -+ return; -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to update MIB parameters. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prInBuf A pointer to the command string buffer -+* \param[in] u4InBufLen The length of the buffer -+* \param[out] None -+* -+* \retval None -+* -+* EX: iwpriv wlan0 set_str_cmd 0_6_[TdlsEn]_[UapsdEn]_[PsmEn]_[PtiWin]_[CWCap]_ -+ [AckMisRetry]_[RspTimeout]_[CWPbDelay]_[DRWin]_[LowestAcInt] -+ -+ iwpriv wlan0 set_str_cmd 0_6_1_1_0_1_1_3_5_1000_2_1 -+ -+ reference to TDLS_CMD_CORE_MIB_PARAM_UPDATE_T -+*/ -+/*----------------------------------------------------------------------------*/ -+static void TdlsCmdMibParamUpdate(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) -+{ -+ WLAN_STATUS rStatus; -+ TDLS_CMD_CORE_T rCmd; -+ UINT_32 u4BufLen; -+ -+ /* reset */ -+ kalMemZero(&rCmd, sizeof(rCmd)); -+ -+ /* parse arguments */ -+ rCmd.Content.rCmdMibUpdate.Tdlsdot11TunneledDirectLinkSetupImplemented = -+ CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ rCmd.Content.rCmdMibUpdate.Tdlsdot11TDLSPeerUAPSDBufferSTAActivated = -+ CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ rCmd.Content.rCmdMibUpdate.Tdlsdot11TDLSPeerPSMActivated = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ rCmd.Content.rCmdMibUpdate.Tdlsdot11TDLSPeerUAPSDIndicationWindow = -+ CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ rCmd.Content.rCmdMibUpdate.Tdlsdot11TDLSChannelSwitchingActivated = -+ CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ rCmd.Content.rCmdMibUpdate.Tdlsdot11TDLSPeerSTAMissingAckRetryLimit = -+ CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ rCmd.Content.rCmdMibUpdate.Tdlsdot11TDLSResponseTimeout = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ rCmd.Content.rCmdMibUpdate.Tdlsdot11TDLSProbeDelay = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ rCmd.Content.rCmdMibUpdate.Tdlsdot11TDLSDiscoveryRequestWindow = -+ CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ rCmd.Content.rCmdMibUpdate.Tdlsdot11TDLSACDeterminationInterval = -+ CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ -+ DBGLOG(TDLS, INFO, " MIB param = %d %d %d %d %d %d %d %d %d %d\n", -+ rCmd.Content.rCmdMibUpdate.Tdlsdot11TunneledDirectLinkSetupImplemented, -+ rCmd.Content.rCmdMibUpdate.Tdlsdot11TDLSPeerUAPSDBufferSTAActivated, -+ rCmd.Content.rCmdMibUpdate.Tdlsdot11TDLSPeerPSMActivated, -+ rCmd.Content.rCmdMibUpdate.Tdlsdot11TDLSPeerUAPSDIndicationWindow, -+ rCmd.Content.rCmdMibUpdate.Tdlsdot11TDLSChannelSwitchingActivated, -+ rCmd.Content.rCmdMibUpdate.Tdlsdot11TDLSPeerSTAMissingAckRetryLimit, -+ rCmd.Content.rCmdMibUpdate.Tdlsdot11TDLSResponseTimeout, -+ rCmd.Content.rCmdMibUpdate.Tdlsdot11TDLSProbeDelay, -+ rCmd.Content.rCmdMibUpdate.Tdlsdot11TDLSDiscoveryRequestWindow, -+ rCmd.Content.rCmdMibUpdate.Tdlsdot11TDLSACDeterminationInterval); -+ -+ /* command to do this */ -+ rStatus = kalIoctl(prGlueInfo, TdlsMibParamUpdate, &rCmd, sizeof(rCmd), FALSE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ DBGLOG(TDLS, ERROR, "%s kalIoctl fail:%x\n", __func__, rStatus); -+ return; -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to update setup parameters. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prInBuf A pointer to the command string buffer -+* \param[in] u4InBufLen The length of the buffer -+* \param[out] None -+* -+* \retval None -+* -+* EX: iwpriv wlan0 set_str_cmd 0_17_[20/40 Support] -+ -+ iwpriv wlan0 set_str_cmd 0_17_1 -+*/ -+/*----------------------------------------------------------------------------*/ -+static void TdlsCmdSetupConf(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) -+{ -+ WLAN_STATUS rStatus; -+ TDLS_CMD_CORE_T rCmd; -+ UINT_32 u4BufLen; -+ -+ /* parse arguments */ -+ kalMemZero(rCmd.aucPeerMac, sizeof(rCmd.aucPeerMac)); -+ -+ rCmd.Content.rCmdSetupConf.fgIs2040Supported = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ -+ DBGLOG(TDLS, INFO, "%s: rCmdSetupConf=%d\n", __func__, rCmd.Content.rCmdSetupConf.fgIs2040Supported); -+ -+ /* command to do this */ -+ prGlueInfo->rTdlsLink.fgIs2040Sup = rCmd.Content.rCmdSetupConf.fgIs2040Supported; -+ -+ rStatus = kalIoctl(prGlueInfo, TdlsSetupConf, &rCmd, sizeof(rCmd), FALSE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ DBGLOG(TDLS, ERROR, "%s kalIoctl fail:%x\n", __func__, rStatus); -+ return; -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to update UAPSD parameters. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prInBuf A pointer to the command string buffer -+* \param[in] u4InBufLen The length of the buffer -+* \param[out] None -+* -+* \retval None -+* -+* EX: iwpriv wlan0 set_str_cmd 0_8_[SP timeout skip]_[PTI timeout skip] -+ -+ iwpriv wlan0 set_str_cmd 0_8_1_1 -+*/ -+/*----------------------------------------------------------------------------*/ -+static void TdlsCmdUapsdConf(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) -+{ -+ WLAN_STATUS rStatus; -+ TDLS_CMD_CORE_T rCmd; -+ UINT_32 u4BufLen; -+ -+ /* parse arguments */ -+ kalMemZero(rCmd.aucPeerMac, sizeof(rCmd.aucPeerMac)); -+ -+ /* UAPSD Service Period */ -+ rCmd.Content.rCmdUapsdConf.fgIsSpTimeoutSkip = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ rCmd.Content.rCmdUapsdConf.fgIsPtiTimeoutSkip = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ /* PTI Service Period */ -+ fgIsPtiTimeoutSkip = rCmd.Content.rCmdUapsdConf.fgIsPtiTimeoutSkip; -+ -+ DBGLOG(TDLS, INFO, "%s: fgIsSpTimeoutSkip=%d, fgIsPtiTimeoutSkip=%d\n", -+ __func__, rCmd.Content.rCmdUapsdConf.fgIsSpTimeoutSkip, fgIsPtiTimeoutSkip); -+ -+ /* command to do this */ -+ rStatus = kalIoctl(prGlueInfo, TdlsUapsdConf, &rCmd, sizeof(rCmd), FALSE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ DBGLOG(TDLS, ERROR, "%s kalIoctl fail:%x\n", __func__, rStatus); -+ return; -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to display TDLS all information. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set -+* \param[in] u4SetBufferLen The length of the set buffer -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed due to invalid length of -+* the set buffer, returns the amount of storage needed. -+* -+* \retval TDLS_STATUS_xx -+* -+* iwpriv wlan0 set_str_cmd 0_18_00:00:00:00:00:00_0_0 -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static TDLS_STATUS -+TdlsInfoDisplay(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen) -+{ -+ GLUE_INFO_T *prGlueInfo; -+ TDLS_CMD_CORE_T *prCmdContent; -+ STA_RECORD_T *prStaRec; -+ TDLS_INFO_LINK_T *prLink; -+ UINT32 u4StartIdx; -+ UINT32 u4PeerNum; -+ BOOLEAN fgIsListAll; -+ UINT8 ucMacZero[6]; -+ UINT32 u4HisIdx; -+ UINT8 ucNetTypeIndex; -+ -+ /* init */ -+ prGlueInfo = prAdapter->prGlueInfo; -+ prCmdContent = (TDLS_CMD_CORE_T *) pvSetBuffer; -+ u4StartIdx = 0; -+ u4PeerNum = 1; -+ fgIsListAll = TRUE; -+ kalMemZero(ucMacZero, sizeof(ucMacZero)); -+ ucNetTypeIndex = NETWORK_TYPE_AIS_INDEX; -+ -+ /* display common information */ -+ DBGLOG(TDLS, TRACE, "TDLS common:\n"); -+ DBGLOG(TDLS, TRACE, "\t\trFreeSwRfbList=%u\n", (UINT32) prAdapter->rRxCtrl.rFreeSwRfbList.u4NumElem); -+ DBGLOG(TDLS, TRACE, "\t\tjiffies=%u %ums (HZ=%d)\n", (UINT32) jiffies, (UINT32) kalGetTimeTick(), HZ); -+ -+ /* display disconnection history information */ -+ DBGLOG(TDLS, TRACE, "TDLS link history: %d\n", prGlueInfo->rTdlsLink.u4LinkIdx); -+ -+ for (u4HisIdx = prGlueInfo->rTdlsLink.u4LinkIdx + 1; u4HisIdx < TDLS_LINK_HISTORY_MAX; u4HisIdx++) { -+ prLink = &prGlueInfo->rTdlsLink.rLinkHistory[u4HisIdx]; -+ -+ if (kalMemCmp(prLink->aucPeerMac, ucMacZero, 6) == 0) -+ continue; /* skip all zero */ -+ -+ DBGLOG(TDLS, TRACE, -+ "\t\t%d. %pM jiffies start(%lu %ums)end(%lu %ums)Reason(%u)fromUs(%u)Dup(%u)HT(%u)\n", -+ u4HisIdx, prLink->aucPeerMac, -+ prLink->jiffies_start, jiffies_to_msecs(prLink->jiffies_start), -+ prLink->jiffies_end, jiffies_to_msecs(prLink->jiffies_end), -+ prLink->ucReasonCode, -+ prLink->fgIsFromUs, prLink->ucDupCount, (prLink->ucHtCap & TDLS_INFO_LINK_HT_CAP_SUP)); -+ -+ if (prLink->ucHtCap & TDLS_INFO_LINK_HT_CAP_SUP) { -+ DBGLOG(TDLS, TRACE, -+ "\t\t\tBA (0x%x %x %x %x %x %x %x %x)\n", -+ prLink->ucHtBa[0], prLink->ucHtBa[1], -+ prLink->ucHtBa[2], prLink->ucHtBa[3], -+ prLink->ucHtBa[4], prLink->ucHtBa[5], prLink->ucHtBa[6], prLink->ucHtBa[7]); -+ } -+ } -+ for (u4HisIdx = 0; u4HisIdx <= prGlueInfo->rTdlsLink.u4LinkIdx; u4HisIdx++) { -+ prLink = &prGlueInfo->rTdlsLink.rLinkHistory[u4HisIdx]; -+ -+ if (kalMemCmp(prLink->aucPeerMac, ucMacZero, 6) == 0) -+ continue; /* skip all zero, use continue, not break */ -+ -+ DBGLOG(TDLS, TRACE, -+ "\t\t%d. %pM jiffies start(%lu %ums)end(%lu %ums)Reason(%u)fromUs(%u)Dup(%u)HT(%u)\n", -+ u4HisIdx, (prLink->aucPeerMac), -+ prLink->jiffies_start, jiffies_to_msecs(prLink->jiffies_start), -+ prLink->jiffies_end, jiffies_to_msecs(prLink->jiffies_end), -+ prLink->ucReasonCode, -+ prLink->fgIsFromUs, prLink->ucDupCount, (prLink->ucHtCap & TDLS_INFO_LINK_HT_CAP_SUP)); -+ -+ if (prLink->ucHtCap & TDLS_INFO_LINK_HT_CAP_SUP) { -+ DBGLOG(TDLS, TRACE, -+ "\t\t\tBA (0x%x %x %x %x %x %x %x %x)\n", -+ prLink->ucHtBa[0], prLink->ucHtBa[1], -+ prLink->ucHtBa[2], prLink->ucHtBa[3], -+ prLink->ucHtBa[4], prLink->ucHtBa[5], prLink->ucHtBa[6], prLink->ucHtBa[7]); -+ } -+ } -+ DBGLOG(TDLS, TRACE, "\n"); -+ -+ /* display link information */ -+ if (prCmdContent != NULL) { -+ if (kalMemCmp(prCmdContent->aucPeerMac, ucMacZero, 6) != 0) { -+ prStaRec = cnmGetStaRecByAddress(prAdapter, -+ prCmdContent->ucNetTypeIndex, prCmdContent->aucPeerMac); -+ if (prStaRec == NULL) -+ fgIsListAll = TRUE; -+ } -+ -+ ucNetTypeIndex = prCmdContent->ucNetTypeIndex; -+ } -+ -+ while (1) { -+ if (fgIsListAll == TRUE) { -+ /* list all TDLS peers */ -+ prStaRec = cnmStaTheTypeGet(prAdapter, ucNetTypeIndex, STA_TYPE_TDLS_PEER, &u4StartIdx); -+ if (prStaRec == NULL) -+ break; -+ } -+ -+ DBGLOG(TDLS, TRACE, "-------- TDLS %d: 0x %pM\n", u4PeerNum, (prStaRec->aucMacAddr)); -+ DBGLOG(TDLS, TRACE, "\t\t\t State %d, PM %d, Cap 0x%x\n", -+ prStaRec->ucStaState, prStaRec->fgIsInPS, prStaRec->u2CapInfo); -+ DBGLOG(TDLS, TRACE, "\t\t\t SetupDisable %d, ChSwDisable %d\n", -+ prStaRec->fgTdlsIsProhibited, prStaRec->fgTdlsIsChSwProhibited); -+ -+ if (fgIsListAll == FALSE) -+ break; /* only list one */ -+ } -+ -+ /* check if we need to clear all histories */ -+ if ((prCmdContent != NULL) && (prCmdContent->Content.rCmdInfoDisplay.fgIsToClearAllHistory == TRUE)) { -+ kalMemZero(&prGlueInfo->rTdlsLink, sizeof(prGlueInfo->rTdlsLink)); -+ prGlueInfo->rTdlsLink.u4LinkIdx = TDLS_LINK_HISTORY_MAX - 1; -+ } -+ -+ DBGLOG(TDLS, INFO, "%s cmd ok.\n", __func__); -+ return TDLS_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to display key information. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set -+* \param[in] u4SetBufferLen The length of the set buffer -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed due to invalid length of -+* the set buffer, returns the amount of storage needed. -+* -+* \retval TDLS_STATUS_xx -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static TDLS_STATUS -+TdlsKeyInfoDisplay(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen) -+{ -+ TDLS_CMD_CORE_T *prCmdContent; -+ WLAN_STATUS rStatus; -+ -+ /* init command buffer */ -+ prCmdContent = (TDLS_CMD_CORE_T *) pvSetBuffer; -+ prCmdContent->u4Command = TDLS_CORE_CMD_KEY_INFO; -+ -+ /* send the command */ -+ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ -+ CMD_ID_TDLS_CORE, /* ucCID */ -+ TRUE, /* fgSetQuery */ -+ FALSE, /* fgNeedResp */ -+ FALSE, /* fgIsOid */ -+ NULL, NULL, /* pfCmdTimeoutHandler */ -+ sizeof(TDLS_CMD_CORE_T), /* u4SetQueryInfoLen */ -+ (PUINT_8) prCmdContent, /* pucInfoBuffer */ -+ NULL, /* pvSetQueryBuffer */ -+ 0 /* u4SetQueryBufferLen */ -+ ); -+ -+ if (rStatus != WLAN_STATUS_PENDING) { -+ DBGLOG(TDLS, ERROR, "%s wlanSendSetQueryCmd allocation fail!\n", __func__); -+ return TDLS_STATUS_RESOURCES; -+ } -+ -+ DBGLOG(TDLS, INFO, "%s cmd ok.\n", __func__); -+ return TDLS_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to record a disconnection event. -+* -+* \param[in] prGlueInfo Pointer to the GLUE_INFO_T structure -+* \param[in] fgIsTearDown TRUE: the link is torn down -+* \param[in] pucPeerMac Pointer to the MAC of the TDLS peer -+* \param[in] fgIsFromUs TRUE: tear down is from us -+* \param[in] u2ReasonCode Disconnection reason (TDLS_REASON_CODE) -+* -+* \retval none -+*/ -+/*----------------------------------------------------------------------------*/ -+static VOID -+TdlsLinkHistoryRecord(GLUE_INFO_T *prGlueInfo, -+ BOOLEAN fgIsTearDown, -+ UINT8 *pucPeerMac, BOOLEAN fgIsFromUs, UINT16 u2ReasonCode, VOID *prOthers) -+{ -+ TDLS_INFO_LINK_T *prLink; -+ -+ DBGLOG(TDLS, INFO, -+ " %s: record history for %pM %d %d %d %d\n", -+ __func__, pucPeerMac, prGlueInfo->rTdlsLink.u4LinkIdx, -+ fgIsTearDown, fgIsFromUs, u2ReasonCode); -+ -+ /* check duplicate one */ -+ if (prGlueInfo->rTdlsLink.u4LinkIdx >= TDLS_LINK_HISTORY_MAX) { -+ DBGLOG(TDLS, ERROR, " %s: u4LinkIdx >= TDLS_LINK_HISTORY_MAX\n", __func__); -+ -+ /* reset to 0 */ -+ prGlueInfo->rTdlsLink.u4LinkIdx = 0; -+ } -+ -+ prLink = &prGlueInfo->rTdlsLink.rLinkHistory[prGlueInfo->rTdlsLink.u4LinkIdx]; -+ -+ if (kalMemCmp(&prLink->aucPeerMac, pucPeerMac, 6) == 0) { -+ if ((prLink->ucReasonCode == u2ReasonCode) && (prLink->fgIsFromUs == fgIsFromUs)) { -+ /* same Peer MAC, Reason Code, Trigger source */ -+ if (fgIsTearDown == TRUE) { -+ if (prLink->jiffies_end != 0) { -+ /* already torn down */ -+ prLink->ucDupCount++; -+ return; -+ } -+ } else { -+ /* already built */ -+ prLink->ucDupCount++; -+ return; -+ } -+ } -+ } -+ -+ /* search old entry */ -+ if (fgIsTearDown == TRUE) { -+ /* TODO: need to search all entries to find it if we support multiple TDLS link design */ -+ if (kalMemCmp(&prLink->aucPeerMac, pucPeerMac, 6) != 0) { -+ /* error! can not find the link entry */ -+ DBGLOG(TDLS, INFO, " %s: cannot find the same entry!!!\n", __func__); -+ return; -+ } -+ -+ prLink->jiffies_end = jiffies; -+ prLink->ucReasonCode = (UINT8) u2ReasonCode; -+ prLink->fgIsFromUs = fgIsFromUs; -+ } else { -+ /* record new one */ -+ prGlueInfo->rTdlsLink.u4LinkIdx++; -+ if (prGlueInfo->rTdlsLink.u4LinkIdx >= TDLS_LINK_HISTORY_MAX) -+ prGlueInfo->rTdlsLink.u4LinkIdx = 0; -+ -+ prLink = &prGlueInfo->rTdlsLink.rLinkHistory[prGlueInfo->rTdlsLink.u4LinkIdx]; -+ -+ prLink->jiffies_start = jiffies; -+ prLink->jiffies_end = 0; -+ kalMemCopy(&prLink->aucPeerMac, pucPeerMac, 6); -+ prLink->ucReasonCode = 0; -+ prLink->fgIsFromUs = (UINT8) fgIsFromUs; -+ prLink->ucDupCount = 0; -+ -+ if (prOthers != NULL) { -+ /* record other parameters */ -+ TDLS_LINK_HIS_OTHERS_T *prHisOthers; -+ -+ prHisOthers = (TDLS_LINK_HIS_OTHERS_T *) prOthers; -+ if (prHisOthers->fgIsHt == TRUE) -+ prLink->ucHtCap |= TDLS_INFO_LINK_HT_CAP_SUP; -+ } -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to update a disconnection event. -+* -+* \param[in] prGlueInfo Pointer to the GLUE_INFO_T structure -+* \param[in] pucPeerMac Pointer to the MAC of the TDLS peer -+* \param[in] eFmeStatus TDLS_EVENT_HOST_SUBID_SPECIFIC_FRAME -+* \param[in] pInfo other information -+* -+* \retval none -+*/ -+/*----------------------------------------------------------------------------*/ -+static VOID -+TdlsLinkHistoryRecordUpdate(GLUE_INFO_T *prGlueInfo, -+ UINT8 *pucPeerMac, TDLS_EVENT_HOST_SUBID_SPECIFIC_FRAME eFmeStatus, VOID *pInfo) -+{ -+ TDLS_INFO_LINK_T *prLink; -+ UINT32 u4LinkIdx; -+ UINT32 u4Tid; -+ -+ /* sanity check */ -+ if ((eFmeStatus < TDLS_HOST_EVENT_SF_BA) || (eFmeStatus > TDLS_HOST_EVENT_SF_BA_RSP_DECLINE)) { -+ /* do not care these frames */ -+ return; -+ } -+ -+ DBGLOG(TDLS, INFO, -+ " %s: update history for %pM %d %d\n", -+ __func__, (pucPeerMac), prGlueInfo->rTdlsLink.u4LinkIdx, eFmeStatus); -+ -+ /* init */ -+ u4LinkIdx = prGlueInfo->rTdlsLink.u4LinkIdx; -+ prLink = &prGlueInfo->rTdlsLink.rLinkHistory[u4LinkIdx]; -+ -+ /* TODO: need to search all entries to find it if we support multiple TDLS link design */ -+ if (kalMemCmp(&prLink->aucPeerMac, pucPeerMac, 6) != 0) { -+ /* error! can not find the link entry */ -+ DBGLOG(TDLS, INFO, " %s: cannot find the same entry!!!\n", __func__); -+ return; -+ } -+ -+ /* update */ -+ u4Tid = *(UINT32 *) pInfo; -+ switch (eFmeStatus) { -+ case TDLS_HOST_EVENT_SF_BA: -+ prLink->ucHtBa[u4Tid] |= TDLS_INFO_LINK_HT_BA_SETUP; -+ break; -+ -+ case TDLS_HOST_EVENT_SF_BA_OK: -+ prLink->ucHtBa[u4Tid] |= TDLS_INFO_LINK_HT_BA_SETUP_OK; -+ break; -+ -+ case TDLS_HOST_EVENT_SF_BA_DECLINE: -+ prLink->ucHtBa[u4Tid] |= TDLS_INFO_LINK_HT_BA_SETUP_DECLINE; -+ break; -+ -+ case TDLS_HOST_EVENT_SF_BA_PEER: -+ prLink->ucHtBa[u4Tid] |= TDLS_INFO_LINK_HT_BA_PEER; -+ break; -+ -+ case TDLS_HOST_EVENT_SF_BA_RSP_OK: -+ prLink->ucHtBa[u4Tid] |= TDLS_INFO_LINK_HT_BA_RSP_OK; -+ break; -+ -+ case TDLS_HOST_EVENT_SF_BA_RSP_DECLINE: -+ prLink->ucHtBa[u4Tid] |= TDLS_INFO_LINK_HT_BA_RSP_DECLINE; -+ break; -+ } -+ -+ /* display TDLS link history */ -+ TdlsInfoDisplay(prGlueInfo->prAdapter, NULL, 0, NULL); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to configure TDLS MIB parameters. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set -+* \param[in] u4SetBufferLen The length of the set buffer -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed due to invalid length of -+* the set buffer, returns the amount of storage needed. -+* -+* \retval TDLS_STATUS_xx -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static TDLS_STATUS -+TdlsMibParamUpdate(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen) -+{ -+ TDLS_CMD_CORE_T *prCmdContent; -+ WLAN_STATUS rStatus; -+ -+ /* init command buffer */ -+ prCmdContent = (TDLS_CMD_CORE_T *) pvSetBuffer; -+ prCmdContent->u4Command = TDLS_CORE_CMD_MIB_UPDATE; -+ -+ /* send the command */ -+ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ -+ CMD_ID_TDLS_CORE, /* ucCID */ -+ TRUE, /* fgSetQuery */ -+ FALSE, /* fgNeedResp */ -+ FALSE, /* fgIsOid */ -+ NULL, NULL, /* pfCmdTimeoutHandler */ -+ sizeof(TDLS_CMD_CORE_T), /* u4SetQueryInfoLen */ -+ (PUINT_8) prCmdContent, /* pucInfoBuffer */ -+ NULL, /* pvSetQueryBuffer */ -+ 0 /* u4SetQueryBufferLen */ -+ ); -+ -+ if (rStatus != WLAN_STATUS_PENDING) { -+ DBGLOG(TDLS, ERROR, "%s wlanSendSetQueryCmd allocation fail!\n", __func__); -+ return TDLS_STATUS_RESOURCES; -+ } -+ -+ DBGLOG(TDLS, INFO, "%s cmd ok.\n", __func__); -+ return TDLS_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to configure TDLS SETUP parameters. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set -+* \param[in] u4SetBufferLen The length of the set buffer -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed due to invalid length of -+* the set buffer, returns the amount of storage needed. -+* -+* \retval TDLS_STATUS_xx -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static TDLS_STATUS -+TdlsSetupConf(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen) -+{ -+ TDLS_CMD_CORE_T *prCmdContent; -+ WLAN_STATUS rStatus; -+ -+ /* init command buffer */ -+ prCmdContent = (TDLS_CMD_CORE_T *) pvSetBuffer; -+ prCmdContent->u4Command = TDLS_CORE_CMD_SETUP_CONF; -+ -+ /* send the command */ -+ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ -+ CMD_ID_TDLS_CORE, /* ucCID */ -+ TRUE, /* fgSetQuery */ -+ FALSE, /* fgNeedResp */ -+ FALSE, /* fgIsOid */ -+ NULL, NULL, /* pfCmdTimeoutHandler */ -+ sizeof(TDLS_CMD_CORE_T), /* u4SetQueryInfoLen */ -+ (PUINT_8) prCmdContent, /* pucInfoBuffer */ -+ NULL, /* pvSetQueryBuffer */ -+ 0 /* u4SetQueryBufferLen */ -+ ); -+ -+ if (rStatus != WLAN_STATUS_PENDING) { -+ DBGLOG(TDLS, ERROR, "%s wlanSendSetQueryCmd allocation fail!\n", __func__); -+ return TDLS_STATUS_RESOURCES; -+ } -+ -+ DBGLOG(TDLS, INFO, "%s cmd ok.\n", __func__); -+ return TDLS_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to configure UAPSD parameters. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set -+* \param[in] u4SetBufferLen The length of the set buffer -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed due to invalid length of -+* the set buffer, returns the amount of storage needed. -+* -+* \retval TDLS_STATUS_xx -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static TDLS_STATUS -+TdlsUapsdConf(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen) -+{ -+ TDLS_CMD_CORE_T *prCmdContent; -+ WLAN_STATUS rStatus; -+ -+ /* init command buffer */ -+ prCmdContent = (TDLS_CMD_CORE_T *) pvSetBuffer; -+ prCmdContent->u4Command = TDLS_CORE_CMD_UAPSD_CONF; -+ -+ /* send the command */ -+ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ -+ CMD_ID_TDLS_CORE, /* ucCID */ -+ TRUE, /* fgSetQuery */ -+ FALSE, /* fgNeedResp */ -+ FALSE, /* fgIsOid */ -+ NULL, NULL, /* pfCmdTimeoutHandler */ -+ sizeof(TDLS_CMD_CORE_T), /* u4SetQueryInfoLen */ -+ (PUINT_8) prCmdContent, /* pucInfoBuffer */ -+ NULL, /* pvSetQueryBuffer */ -+ 0 /* u4SetQueryBufferLen */ -+ ); -+ -+ if (rStatus != WLAN_STATUS_PENDING) { -+ DBGLOG(TDLS, ERROR, "%s wlanSendSetQueryCmd allocation fail!\n", __func__); -+ return TDLS_STATUS_RESOURCES; -+ } -+ -+ DBGLOG(TDLS, INFO, "%s cmd ok.\n", __func__); -+ return TDLS_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to update frame status. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prInBuf A pointer to the command string buffer, from u4EventSubId -+* \param[in] u4InBufLen The length of the buffer -+* \param[out] None -+* -+* \retval None -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static void TdlsEventFmeStatus(GLUE_INFO_T *prGlueInfo, UINT8 *prInBuf, UINT32 u4InBufLen) -+{ -+ TDLS_EVENT_HOST_SUBID_SPECIFIC_FRAME eFmeStatus; -+ STA_RECORD_T *prStaRec; -+ UINT32 u4Tid; -+ -+ /* init */ -+ u4Tid = *(UINT32 *) prInBuf; -+ prInBuf += 4; /* skip u4EventSubId */ -+ -+ /* sanity check */ -+ prStaRec = cnmGetStaRecByIndex(prGlueInfo->prAdapter, *prInBuf); -+ if ((prStaRec == NULL) || (!IS_TDLS_STA(prStaRec))) -+ return; -+ prInBuf++; -+ -+ /* update status */ -+ eFmeStatus = *prInBuf; -+ TdlsLinkHistoryRecordUpdate(prGlueInfo, prStaRec->aucMacAddr, eFmeStatus, &u4Tid); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to collect TDLS statistics from firmware. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prInBuf A pointer to the command string buffer, from u4EventSubId -+* \param[in] u4InBufLen The length of the buffer -+* \param[out] None -+* -+* \retval None -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static void TdlsEventStatistics(GLUE_INFO_T *prGlueInfo, UINT8 *prInBuf, UINT32 u4InBufLen) -+{ -+ STA_RECORD_T *prStaRec; -+ STAT_CNT_INFO_FW_T *prStat; -+ UINT32 u4RateId; -+ -+ /* init */ -+ prStaRec = cnmGetStaRecByIndex(prGlueInfo->prAdapter, *prInBuf); -+ if ((prStaRec == NULL) || (!IS_TDLS_STA(prStaRec))) -+ return; -+ -+ prInBuf += 4; /* skip prStaRec->ucIndex */ -+ -+ /* update statistics */ -+ kalMemCopy(&prStaRec->rTdlsStatistics.rFw, prInBuf, sizeof(prStaRec->rTdlsStatistics.rFw)); -+ -+ /* display statistics */ -+ prStat = &prStaRec->rTdlsStatistics.rFw; -+ -+ DBGLOG(TDLS, TRACE, " peer [%pM] statistics:\n", (prStaRec->aucMacAddr)); -+ DBGLOG(TDLS, TRACE, "\t\tT%d %d %d (P%d %d) (%dus) - E%d 0x%x - R%d (P%d)\n", -+ prStat->u4NumOfTx, prStat->u4NumOfTxOK, prStat->u4NumOfTxRetry, -+ prStat->u4NumOfPtiRspTxOk, prStat->u4NumOfPtiRspTxErr, -+ prStat->u4TxDoneAirTimeMax, -+ prStat->u4NumOfTxErr, prStat->u4TxErrBitmap, prStat->u4NumOfRx, prStat->u4NumOfPtiRspRx); -+ -+ DBGLOG(TDLS, TRACE, "\t\t"); -+ -+ for (u4RateId = prStat->u4TxRateOkHisId; u4RateId < STAT_CNT_INFO_MAX_TX_RATE_OK_HIS_NUM; u4RateId++) -+ DBGLOG(TDLS, TRACE, -+ "%d(%d) ", prStat->aucTxRateOkHis[u4RateId][0], prStat->aucTxRateOkHis[u4RateId][1]); -+ for (u4RateId = 0; u4RateId < prStat->u4TxRateOkHisId; u4RateId++) -+ DBGLOG(TDLS, TRACE, -+ "%d(%d) ", prStat->aucTxRateOkHis[u4RateId][0], prStat->aucTxRateOkHis[u4RateId][1]); -+ -+ DBGLOG(TDLS, TRACE, "\n\n"); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to do tear down. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prInBuf A pointer to the command string buffer, from u4EventSubId -+* \param[in] u4InBufLen The length of the buffer -+* \param[out] None -+* -+* \retval None -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static void TdlsEventTearDown(GLUE_INFO_T *prGlueInfo, UINT8 *prInBuf, UINT32 u4InBufLen) -+{ -+ STA_RECORD_T *prStaRec; -+ UINT16 u2ReasonCode; -+ UINT32 u4TearDownSubId; -+ UINT8 *pMac, aucZeroMac[6]; -+ -+ /* init */ -+ u4TearDownSubId = *(UINT32 *) prInBuf; -+ kalMemZero(aucZeroMac, sizeof(aucZeroMac)); -+ pMac = aucZeroMac; -+ -+ prStaRec = cnmGetStaRecByIndex(prGlueInfo->prAdapter, *(prInBuf + 4)); -+ if (prStaRec != NULL) -+ pMac = prStaRec->aucMacAddr; -+ -+ /* handle */ -+ if (u4TearDownSubId == TDLS_HOST_EVENT_TD_PTI_TIMEOUT) { -+ DBGLOG(TDLS, WARN, " %s: peer [%pM] Reason=PTI timeout\n", -+ __func__, pMac); -+ } else if (u4TearDownSubId == TDLS_HOST_EVENT_TD_AGE_TIMEOUT) { -+ DBGLOG(TDLS, WARN, " %s: peer [%pM] Reason=AGE timeout\n", -+ __func__, pMac); -+ } else { -+ DBGLOG(TDLS, WARN, " %s: peer [%pM] Reason=%d\n", -+ __func__, pMac, u4TearDownSubId); -+ } -+ -+ /* sanity check */ -+ if (prStaRec == NULL) -+ return; -+ -+ if (fgIsPtiTimeoutSkip == TRUE) { -+ /* skip PTI timeout event */ -+ if (u4TearDownSubId == TDLS_HOST_EVENT_TD_PTI_TIMEOUT) { -+ DBGLOG(TDLS, WARN, " %s: skip PTI timeout\n", __func__); -+ return; -+ } -+ } -+ -+ /* record history */ -+ if (u4TearDownSubId == TDLS_HOST_EVENT_TD_AGE_TIMEOUT) -+ u2ReasonCode = TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_AGE_TIMEOUT; -+ else if (u4TearDownSubId == TDLS_HOST_EVENT_TD_PTI_TIMEOUT) -+ u2ReasonCode = TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_PTI_TIMEOUT; -+ else if (u4TearDownSubId == TDLS_HOST_EVENT_TD_PTI_SEND_FAIL) -+ u2ReasonCode = TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_PTI_SEND_FAIL; -+ else if (u4TearDownSubId == TDLS_HOST_EVENT_TD_PTI_SEND_MAX_FAIL) -+ u2ReasonCode = TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_PTI_SEND_MAX_FAIL; -+ else if (u4TearDownSubId == TDLS_HOST_EVENT_TD_WRONG_NETWORK_IDX) -+ u2ReasonCode = TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_WRONG_NETWORK_IDX; -+ else if (u4TearDownSubId == TDLS_HOST_EVENT_TD_NON_STATE3) -+ u2ReasonCode = TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_NON_STATE3; -+ else if (u4TearDownSubId == TDLS_HOST_EVENT_TD_LOST_TEAR_DOWN) -+ u2ReasonCode = TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_LOST_TEAR_DOWN; -+ else { -+ /* shall not be here */ -+ u2ReasonCode = TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_UNKNOWN; -+ } -+ -+ TdlsLinkHistoryRecord(prGlueInfo, TRUE, prStaRec->aucMacAddr, TRUE, u2ReasonCode, NULL); -+ -+ /* correct correct reason code for PTI or AGE timeout to supplicant */ -+ if ((u2ReasonCode == TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_AGE_TIMEOUT) || -+ (u2ReasonCode == TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_PTI_TIMEOUT)) { -+ u2ReasonCode = TDLS_REASON_CODE_UNREACHABLE; -+ } -+ -+ /* 16 Nov 21:49 2012 http://permalink.gmane.org/gmane.linux.kernel.wireless.general/99712 */ -+ cfg80211_tdls_oper_request(prGlueInfo->prDevHandler, -+ prStaRec->aucMacAddr, NL80211_TDLS_TEARDOWN, u2ReasonCode, GFP_ATOMIC); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to do tx down. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prInBuf A pointer to the command string buffer, from u4EventSubId -+* \param[in] u4InBufLen The length of the buffer -+* \param[out] None -+* -+* \retval None -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static void TdlsEventTxDone(GLUE_INFO_T *prGlueInfo, UINT8 *prInBuf, UINT32 u4InBufLen) -+{ -+ /* UINT32 u4FmeIdx; */ -+ UINT8 *pucFmeHdr; -+ UINT8 ucErrStatus; -+ -+ ucErrStatus = *(UINT32 *) prInBuf; -+ -+ pucFmeHdr = prInBuf + 4; /* skip ucErrStatus */ -+ -+ if (ucErrStatus == 0) -+ DBGLOG(TDLS, TRACE, " %s: OK to tx a TDLS action:", __func__); -+ else -+ DBGLOG(TDLS, TRACE, " %s: fail to tx a TDLS action (err=0x%x):", __func__, ucErrStatus); -+ #if 0 -+ /* dump TX packet content from wlan header */ -+ for (u4FmeIdx = 0; u4FmeIdx < (u4InBufLen - 4); u4FmeIdx++) { -+ if ((u4FmeIdx % 16) == 0) -+ DBGLOG(TDLS, TRACE, "\n"); -+ -+ DBGLOG(TDLS, TRACE, "%02x ", *pucFmeHdr++); -+ } -+ DBGLOG(TDLS, TRACE, "\n\n"); -+ #endif -+} -+ -+/******************************************************************************* -+* P U B L I C F U N C T I O N S -+******************************************************************************** -+*/ -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to parse TDLS Extended Capabilities element. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prInBuf A pointer to the command string buffer -+* \param[in] u4InBufLen The length of the buffer -+* \param[out] None -+* -+* \retval None -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID TdlsexBssExtCapParse(STA_RECORD_T *prStaRec, UINT_8 *pucIE) -+{ -+ UINT_8 *pucIeExtCap; -+ -+ /* sanity check */ -+ if ((prStaRec == NULL) || (pucIE == NULL)) -+ return; -+ -+ if (IE_ID(pucIE) != ELEM_ID_EXTENDED_CAP) -+ return; -+ -+ /* -+ from bit0 ~ -+ -+ bit 38: TDLS Prohibited -+ The TDLS Prohibited subfield indicates whether the use of TDLS is prohibited. The -+ field is set to 1 to indicate that TDLS is prohibited and to 0 to indicate that TDLS is -+ allowed. -+ */ -+ if (IE_LEN(pucIE) < 5) -+ return; /* we need 39/8 = 5 bytes */ -+ -+ /* init */ -+ prStaRec->fgTdlsIsProhibited = FALSE; -+ prStaRec->fgTdlsIsChSwProhibited = FALSE; -+ -+ /* parse */ -+ pucIeExtCap = pucIE + 2; -+ pucIeExtCap += 4; /* shift to the byte we care about */ -+ -+ if ((*pucIeExtCap) & BIT(38 - 32)) -+ prStaRec->fgTdlsIsProhibited = TRUE; -+ if ((*pucIeExtCap) & BIT(39 - 32)) -+ prStaRec->fgTdlsIsChSwProhibited = TRUE; -+ -+ DBGLOG(TDLS, TRACE, -+ " %s: AP [%pM] tdls prohibit bit=%d %d\n", -+ __func__, -+ prStaRec->aucMacAddr, prStaRec->fgTdlsIsProhibited, prStaRec->fgTdlsIsChSwProhibited); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to transmit a TDLS data frame from nl80211. -+* -+* \param[in] pvAdapter Pointer to the Adapter structure. -+* \param[in] -+* \param[in] -+* \param[in] buf includes RSN IE + FT IE + Lifetimeout IE -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+int -+TdlsexCfg80211TdlsMgmt(struct wiphy *wiphy, struct net_device *dev, -+ const u8 *peer, u8 action_code, u8 dialog_token, -+ u16 status_code, u32 peer_capability, -+ bool initiator, const u8 *buf, size_t len) -+{ -+ ADAPTER_T *prAdapter; -+ GLUE_INFO_T *prGlueInfo; -+ BSS_INFO_T *prAisBssInfo; -+ WLAN_STATUS rStatus; -+ UINT_32 u4BufLen; -+ TDLS_MGMT_TX_INFO *prMgmtTxInfo; -+ -+ /* -+ Have correct behavior for STAUT receiving TDLS Setup Request after sending TDLS -+ Set Request and before receiving TDLS Setup Response: -+ -- Source Address of received Request is higher than own MAC address -+ -- Source Address of received Request is lower than own MAC address -+ -+ ==> STA with larger MAC address will send the response frame. -+ -+ Supplicant will do this in wpa_tdls_process_tpk_m1(). -+ */ -+ -+ /* sanity check */ -+ if ((wiphy == NULL) || (peer == NULL)) { -+ DBGLOG(TDLS, ERROR, " %s: wrong 0x%p 0x%p!\n", __func__, wiphy, peer); -+ return -EINVAL; -+ } -+ -+ DBGLOG(TDLS, INFO, " %s: [%pM] %d %d %d 0x%p %u\n", -+ __func__, peer, action_code, dialog_token, status_code, buf, (UINT32) len); -+ -+ /* init */ -+ prGlueInfo = (GLUE_INFO_T *) wiphy_priv(wiphy); -+ if (prGlueInfo == NULL) { -+ DBGLOG(TDLS, ERROR, " %s: wrong prGlueInfo 0x%p!\n", __func__, prGlueInfo); -+ return -EINVAL; -+ } -+ -+ prAdapter = prGlueInfo->prAdapter; -+ if (prAdapter->fgTdlsIsSup == FALSE) { -+ DBGLOG(TDLS, ERROR, " %s: firmware TDLS is not supported!\n", __func__); -+ return -EBUSY; -+ } -+ -+ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ if (prAisBssInfo->fgTdlsIsProhibited == TRUE) { -+ /* do not send anything if TDLS is prohibited in the BSS */ -+ return 0; -+ } -+ -+ prMgmtTxInfo = kalMemAlloc(sizeof(TDLS_MGMT_TX_INFO), VIR_MEM_TYPE); -+ if (prMgmtTxInfo == NULL) { -+ DBGLOG(TDLS, ERROR, " %s: allocate fail!\n", __func__); -+ return -ENOMEM; -+ } -+ -+ kalMemZero(prMgmtTxInfo, sizeof(TDLS_MGMT_TX_INFO)); -+ -+ if (peer != NULL) -+ kalMemCopy(prMgmtTxInfo->aucPeer, peer, 6); -+ prMgmtTxInfo->ucActionCode = action_code; -+ prMgmtTxInfo->ucDialogToken = dialog_token; -+ prMgmtTxInfo->u2StatusCode = status_code; -+ -+ if (buf != NULL) { -+ if (len > sizeof(prMgmtTxInfo->aucSecBuf)) { -+ kalMemFree(prMgmtTxInfo, VIR_MEM_TYPE, sizeof(TDLS_MGMT_TX_INFO)); -+ return -EINVAL; -+ } -+ prMgmtTxInfo->u4SecBufLen = len; -+ kalMemCopy(prMgmtTxInfo->aucSecBuf, buf, len); -+ } -+ -+ /* send the TDLS action data frame */ -+ rStatus = kalIoctl(prGlueInfo, -+ TdlsexMgmtCtrl, -+ prMgmtTxInfo, sizeof(TDLS_MGMT_TX_INFO), FALSE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ /* -+ clear all content to avoid any bug if we dont yet execute TdlsexMgmtCtrl() -+ then kalIoctl finishes -+ */ -+ kalMemZero(prMgmtTxInfo, sizeof(TDLS_MGMT_TX_INFO)); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ DBGLOG(TDLS, ERROR, "%s enable or disable link fail:%x\n", __func__, rStatus); -+ kalMemFree(prMgmtTxInfo, VIR_MEM_TYPE, sizeof(TDLS_MGMT_TX_INFO)); -+ return -EINVAL; -+ } -+ -+ kalMemFree(prMgmtTxInfo, VIR_MEM_TYPE, sizeof(TDLS_MGMT_TX_INFO)); -+ return 0; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to enable or disable TDLS link from upper layer. -+* -+* \param[in] pvAdapter Pointer to the Adapter structure. -+* \param[in] -+* \param[in] -+* \param[in] buf includes RSN IE + FT IE + Lifetimeout IE -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+int TdlsexCfg80211TdlsOper(struct wiphy *wiphy, struct net_device *dev, -+ const u8 *peer, enum nl80211_tdls_operation oper) -+{ -+ ADAPTER_T *prAdapter; -+ GLUE_INFO_T *prGlueInfo; -+ WLAN_STATUS rStatus; -+ UINT_32 u4BufLen; -+ TDLS_CMD_LINK_T rCmdLink; -+ -+ /* sanity check */ -+ if (peer == NULL) { -+ DBGLOG(TDLS, ERROR, " %s: peer == NULL!\n", __func__); -+ return -EINVAL; -+ } -+ -+ DBGLOG(TDLS, INFO, " %s: [%pM] %d %d\n", -+ __func__, peer, oper, (wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS)); -+ -+ if (!(wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS)) -+ return -ENOTSUPP; -+ -+ /* init */ -+ prGlueInfo = (GLUE_INFO_T *) wiphy_priv(wiphy); -+ if (prGlueInfo == NULL) { -+ DBGLOG(TDLS, ERROR, " %s: wrong prGlueInfo 0x%p!\n", __func__, prGlueInfo); -+ return -EINVAL; -+ } -+ prAdapter = prGlueInfo->prAdapter; -+ kalMemCopy(rCmdLink.aucPeerMac, peer, sizeof(rCmdLink.aucPeerMac)); -+ rCmdLink.fgIsEnabled = FALSE; -+ -+ /* -+ enum nl80211_tdls_operation { -+ NL80211_TDLS_DISCOVERY_REQ, -+ NL80211_TDLS_SETUP, -+ NL80211_TDLS_TEARDOWN, -+ NL80211_TDLS_ENABLE_LINK, -+ NL80211_TDLS_DISABLE_LINK, -+ }; -+ */ -+ -+ switch (oper) { -+ case NL80211_TDLS_ENABLE_LINK: -+ rCmdLink.fgIsEnabled = TRUE; -+ break; -+ -+ case NL80211_TDLS_DISABLE_LINK: -+ rCmdLink.fgIsEnabled = FALSE; -+ break; -+ -+ case NL80211_TDLS_TEARDOWN: -+ case NL80211_TDLS_SETUP: -+ case NL80211_TDLS_DISCOVERY_REQ: -+ /* we do not support setup/teardown/discovery from driver */ -+ return -ENOTSUPP; -+ -+ default: -+ return -ENOTSUPP; -+ } -+ -+ /* enable or disable TDLS link */ -+ rStatus = kalIoctl(prGlueInfo, -+ TdlsexLinkCtrl, &rCmdLink, sizeof(TDLS_CMD_LINK_T), FALSE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ DBGLOG(TDLS, ERROR, "%s enable or disable link fail:%x\n", __func__, rStatus); -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to send a command to TDLS module. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prInBuf A pointer to the command string buffer -+* \param[in] u4InBufLen The length of the buffer -+* \param[out] None -+* -+* \retval None -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID TdlsexCmd(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) -+{ -+ UINT_32 u4Subcmd; -+ static void (*TdlsCmdTestFunc)(P_GLUE_INFO_T, UINT_8 *, UINT_32); -+ -+ /* parse TDLS sub-command */ -+ u4Subcmd = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ DBGLOG(TDLS, INFO, " sub command = %u\n", (UINT32) u4Subcmd); -+ TdlsCmdTestFunc = NULL; -+ -+ /* handle different sub-command */ -+ switch (u4Subcmd) { -+#if TDLS_CFG_CMD_TEST /* only for unit test */ -+ case TDLS_CMD_TEST_TX_FRAME: -+ /* simulate to send a TDLS frame */ -+ /* TdlsCmdTestTxFrame(prGlueInfo, prInBuf, u4InBufLen); */ -+ TdlsCmdTestFunc = TdlsCmdTestTxFrame; -+ break; -+ -+ case TDLS_CMD_TEST_TX_TDLS_FRAME: -+ /* simulate to send a TDLS frame from supplicant */ -+ /* TdlsCmdTestTxTdlsFrame(prGlueInfo, prInBuf, u4InBufLen); */ -+ TdlsCmdTestFunc = TdlsCmdTestTxTdlsFrame; -+ break; -+ -+ case TDLS_CMD_TEST_RCV_FRAME: -+ /* simulate to receive a TDLS frame */ -+ /* TdlsCmdTestRvFrame(prGlueInfo, prInBuf, u4InBufLen); */ -+ TdlsCmdTestFunc = TdlsCmdTestRvFrame; -+ break; -+ -+ case TDLS_CMD_TEST_PEER_ADD: -+ /* simulate to add a TDLS peer */ -+ /* TdlsCmdTestAddPeer(prGlueInfo, prInBuf, u4InBufLen); */ -+ TdlsCmdTestFunc = TdlsCmdTestAddPeer; -+ break; -+ -+ case TDLS_CMD_TEST_PEER_UPDATE: -+ /* simulate to update a TDLS peer */ -+ /* TdlsCmdTestUpdatePeer(prGlueInfo, prInBuf, u4InBufLen); */ -+ TdlsCmdTestFunc = TdlsCmdTestUpdatePeer; -+ break; -+ -+ case TDLS_CMD_TEST_DATA_FRAME: -+ /* simulate to send a data frame to the peer */ -+ /* TdlsCmdTestDataSend(prGlueInfo, prInBuf, u4InBufLen); */ -+ TdlsCmdTestFunc = TdlsCmdTestDataSend; -+ break; -+ -+ case TDLS_CMD_TEST_RCV_NULL: -+ /* simulate to receive a QoS null frame from the peer */ -+ /* TdlsCmdTestNullRecv(prGlueInfo, prInBuf, u4InBufLen); */ -+ TdlsCmdTestFunc = TdlsCmdTestNullRecv; -+ break; -+ -+ case TDLS_CMD_TEST_SKIP_TX_FAIL: -+ /* command firmware to skip tx fail case */ -+ /* TdlsCmdTestTxFailSkip(prGlueInfo, prInBuf, u4InBufLen); */ -+ TdlsCmdTestFunc = TdlsCmdTestTxFailSkip; -+ break; -+ -+ case TDLS_CMD_TEST_SKIP_KEEP_ALIVE: -+ /* command firmware to skip keep alive function */ -+ /* TdlsCmdTestKeepAliveSkip(prGlueInfo, prInBuf, u4InBufLen); */ -+ TdlsCmdTestFunc = TdlsCmdTestKeepAliveSkip; -+ break; -+ -+ case TDLS_CMD_TEST_SKIP_CHSW_TIMEOUT: -+ /* command firmware to skip channel switch timeout function */ -+ /* TdlsCmdTestChSwTimeoutSkip(prGlueInfo, prInBuf, u4InBufLen); */ -+ TdlsCmdTestFunc = TdlsCmdTestChSwTimeoutSkip; -+ break; -+ -+ case TDLS_CMD_TEST_PROHIBIT_SET_IN_AP: -+ /* simulate to set Prohibited Bit in AP */ -+ /* TdlsCmdTestProhibitedBitSet(prGlueInfo, prInBuf, u4InBufLen); */ -+ TdlsCmdTestFunc = TdlsCmdTestProhibitedBitSet; -+ break; -+ -+ case TDLS_CMD_TEST_SCAN_DISABLE: -+ /* command to disable scan request to do channel switch */ -+ /* TdlsCmdTestScanCtrl(prGlueInfo, prInBuf, u4InBufLen); */ -+ TdlsCmdTestFunc = TdlsCmdTestScanCtrl; -+ break; -+ -+ case TDLS_CMD_TEST_DATA_FRAME_CONT: -+ /* simulate to send a data frame to the peer periodically */ -+ /* TdlsCmdTestDataContSend(prGlueInfo, prInBuf, u4InBufLen); */ -+ TdlsCmdTestFunc = TdlsCmdTestDataContSend; -+ break; -+ -+ case TDLS_CMD_TEST_CH_SW_PROHIBIT_SET_IN_AP: -+ /* simulate to set channel switch Prohibited Bit in AP */ -+ /* TdlsCmdTestChSwProhibitedBitSet(prGlueInfo, prInBuf, u4InBufLen); */ -+ TdlsCmdTestFunc = TdlsCmdTestChSwProhibitedBitSet; -+ break; -+ -+ case TDLS_CMD_TEST_DELAY: -+ /* delay a where */ -+ /* TdlsCmdTestDelay(prGlueInfo, prInBuf, u4InBufLen); */ -+ TdlsCmdTestFunc = TdlsCmdTestDelay; -+ break; -+ -+ case TDLS_CMD_TEST_PTI_TX_FAIL: -+ /* simulate the tx done fail for PTI */ -+ /* TdlsCmdTestPtiTxDoneFail(prGlueInfo, prInBuf, u4InBufLen); */ -+ TdlsCmdTestFunc = TdlsCmdTestPtiTxDoneFail; -+ break; -+#endif /* TDLS_CFG_CMD_TEST */ -+ -+ case TDLS_CMD_MIB_UPDATE: -+ /* update MIB parameters */ -+ /* TdlsCmdMibParamUpdate(prGlueInfo, prInBuf, u4InBufLen); */ -+ TdlsCmdTestFunc = TdlsCmdMibParamUpdate; -+ break; -+ -+ case TDLS_CMD_UAPSD_CONF: -+ /* config UAPSD parameters */ -+ /* TdlsCmdUapsdConf(prGlueInfo, prInBuf, u4InBufLen); */ -+ TdlsCmdTestFunc = TdlsCmdUapsdConf; -+ break; -+ -+ case TDLS_CMD_CH_SW_CONF: -+ /* enable or disable or start or stop channel switch function */ -+ /* TdlsCmdChSwConf(prGlueInfo, prInBuf, u4InBufLen); */ -+ TdlsCmdTestFunc = TdlsCmdChSwConf; -+ break; -+ -+ case TDLS_CMD_SETUP_CONF: -+ /* config setup parameters */ -+ /* TdlsCmdSetupConf(prGlueInfo, prInBuf, u4InBufLen); */ -+ TdlsCmdTestFunc = TdlsCmdSetupConf; -+ break; -+ -+ case TDLS_CMD_INFO: -+ /* display all TDLS information */ -+ /* TdlsCmdInfoDisplay(prGlueInfo, prInBuf, u4InBufLen); */ -+ TdlsCmdTestFunc = TdlsCmdInfoDisplay; -+ break; -+ -+ case TDLS_CMD_KEY_INFO: -+ /* display key information */ -+ /* TdlsCmdKeyInfoDisplay(prGlueInfo, prInBuf, u4InBufLen); */ -+ TdlsCmdTestFunc = TdlsCmdKeyInfoDisplay; -+ break; -+ -+ default: -+ break; -+ } -+ -+ if (TdlsCmdTestFunc != NULL) -+ TdlsCmdTestFunc(prGlueInfo, prInBuf, u4InBufLen); -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to record a disconnection event. -+* -+* \param[in] prGlueInfo Pointer to the GLUE_INFO_T structure -+* \param[in] fgIsTearDown TRUE: tear down -+* \param[in] pucPeerMac Pointer to the MAC of the TDLS peer -+* \param[in] fgIsFromUs TRUE: tear down is from us -+* \param[in] u2ReasonCode Disconnection reason (TDLS_REASON_CODE) -+* -+* \retval none -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+TdlsexLinkHistoryRecord(GLUE_INFO_T *prGlueInfo, -+ BOOLEAN fgIsTearDown, UINT8 *pucPeerMac, BOOLEAN fgIsFromUs, UINT16 u2ReasonCode) -+{ -+ /* sanity check */ -+ if ((prGlueInfo == NULL) || (pucPeerMac == NULL)) -+ return; -+ -+ DBGLOG(TDLS, INFO, -+ " %s: Rcv a inform from %pM %d %d\n", -+ __func__, pucPeerMac, fgIsFromUs, u2ReasonCode); -+ -+ /* record */ -+ TdlsLinkHistoryRecord(prGlueInfo, fgIsTearDown, pucPeerMac, fgIsFromUs, u2ReasonCode, NULL); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to send a command to TDLS module. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prInBuf A pointer to the command string buffer -+* \param[in] u4InBufLen The length of the buffer -+* \param[out] None -+* -+* \retval None -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID TdlsexEventHandle(GLUE_INFO_T *prGlueInfo, UINT8 *prInBuf, UINT32 u4InBufLen) -+{ -+ UINT32 u4EventId; -+ -+ /* sanity check */ -+ if ((prGlueInfo == NULL) || (prInBuf == NULL)) -+ return; /* shall not be here */ -+ -+ /* handle */ -+ u4EventId = *(UINT32 *) prInBuf; -+ u4InBufLen -= 4; -+ -+ DBGLOG(TDLS, INFO, " %s: Rcv a event: %d\n", __func__, u4EventId); -+ -+ switch (u4EventId) { -+ case TDLS_HOST_EVENT_TEAR_DOWN: -+ TdlsEventTearDown(prGlueInfo, prInBuf + 4, u4InBufLen); -+ break; -+ -+ case TDLS_HOST_EVENT_TX_DONE: -+ TdlsEventTxDone(prGlueInfo, prInBuf + 4, u4InBufLen); -+ break; -+ -+ case TDLS_HOST_EVENT_FME_STATUS: -+ TdlsEventFmeStatus(prGlueInfo, prInBuf + 4, u4InBufLen); -+ break; -+ -+ case TDLS_HOST_EVENT_STATISTICS: -+ TdlsEventStatistics(prGlueInfo, prInBuf + 4, u4InBufLen); -+ break; -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is used to initialize variables in TDLS. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* -+* @return TDLS_STATUS_SUCCESS: do not set key and key infor. is queued -+ TDLS_STATUS_FAILURE: set key -+*/ -+/*----------------------------------------------------------------------------*/ -+TDLS_STATUS TdlsexKeyHandle(ADAPTER_T *prAdapter, PARAM_KEY_T *prNewKey) -+{ -+ STA_RECORD_T *prStaRec; -+ -+ /* sanity check */ -+ if ((prAdapter == NULL) || (prNewKey == NULL)) -+ return TDLS_STATUS_FAILURE; -+ -+ /* -+ supplicant will set key before updating station & enabling the link so we need to -+ backup the key information and set key when link is enabled -+ */ -+ prStaRec = cnmGetStaRecByAddress(prAdapter, NETWORK_TYPE_AIS_INDEX, prNewKey->arBSSID); -+ if ((prStaRec != NULL) && IS_TDLS_STA(prStaRec)) { -+ DBGLOG(TDLS, TRACE, " %s: [%pM] queue key (len=%d) until link is enabled\n", -+ __func__, prNewKey->arBSSID, (UINT32) prNewKey->u4KeyLength); -+ -+ if (prStaRec->ucStaState == STA_STATE_3) { -+ DBGLOG(TDLS, TRACE, " %s: [%pM] tear down the link due to STA_STATE_3\n", -+ __func__, prNewKey->arBSSID); -+ -+ /* re-key */ -+ TdlsLinkHistoryRecord(prAdapter->prGlueInfo, TRUE, -+ prStaRec->aucMacAddr, TRUE, -+ TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_REKEY, NULL); -+ -+ /* 16 Nov 21:49 2012 http://permalink.gmane.org/gmane.linux.kernel.wireless.general/99712 */ -+ cfg80211_tdls_oper_request(prAdapter->prGlueInfo->prDevHandler, -+ prStaRec->aucMacAddr, TDLS_FRM_ACTION_TEARDOWN, -+ TDLS_REASON_CODE_UNSPECIFIED, GFP_ATOMIC); -+ return TDLS_STATUS_SUCCESS; -+ } -+ -+ /* backup the key */ -+ kalMemCopy(&prStaRec->rTdlsKeyTemp, prNewKey, sizeof(prStaRec->rTdlsKeyTemp)); -+ return TDLS_STATUS_SUCCESS; -+ } -+ -+ return TDLS_STATUS_FAILURE; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is used to initialize variables in TDLS. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID TdlsexInit(ADAPTER_T *prAdapter) -+{ -+ GLUE_INFO_T *prGlueInfo; -+ -+ /* init */ -+ prGlueInfo = (GLUE_INFO_T *) prAdapter->prGlueInfo; -+ -+ /* reset */ -+ kalMemZero(&prGlueInfo->rTdlsLink, sizeof(prGlueInfo->rTdlsLink)); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to get any peer is in power save. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* -+* \retval TRUE (at least one peer is in power save) -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN TdlsexIsAnyPeerInPowerSave(ADAPTER_T *prAdapter) -+{ -+ STA_RECORD_T *prStaRec; -+ UINT32 u4StaId, u4StartIdx; -+ -+ for (u4StaId = 0, u4StartIdx = 0; u4StaId < CFG_STA_REC_NUM; u4StaId++) { -+ /* list all TDLS peers */ -+ prStaRec = cnmStaTheTypeGet(prAdapter, NETWORK_TYPE_AIS_INDEX, STA_TYPE_TDLS_PEER, &u4StartIdx); -+ if (prStaRec == NULL) -+ break; -+ -+ if (prStaRec->fgIsInPS == TRUE) { -+ DBGLOG(TDLS, TRACE, " yes, at least one peer is in ps\n"); -+ return TRUE; -+ } -+ } -+ -+ return FALSE; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to enable or disable a TDLS link. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set -+* \param[in] u4SetBufferLen The length of the set buffer -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed due to invalid length of -+* the set buffer, returns the amount of storage needed. -+* -+* \retval TDLS_STATUS_xx -+*/ -+/*----------------------------------------------------------------------------*/ -+TDLS_STATUS TdlsexLinkCtrl(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen) -+{ -+ GLUE_INFO_T *prGlueInfo; -+ TDLS_CMD_LINK_T *prCmd; -+ BSS_INFO_T *prBssInfo; -+ STA_RECORD_T *prStaRec; -+ TDLS_LINK_HIS_OTHERS_T rHisOthers; -+ -+ /* sanity check */ -+ if ((prAdapter == NULL) || (pvSetBuffer == NULL) || (pu4SetInfoLen == NULL)) { -+ DBGLOG(TDLS, ERROR, " %s: sanity fail!\n", __func__); -+ return TDLS_STATUS_FAILURE; -+ } -+ -+ /* init */ -+ prGlueInfo = (GLUE_INFO_T *) prAdapter->prGlueInfo; -+ *pu4SetInfoLen = sizeof(TDLS_CMD_LINK_T); -+ prCmd = (TDLS_CMD_LINK_T *) pvSetBuffer; -+ -+ /* search old entry */ -+ prStaRec = cnmGetStaRecByAddress(prAdapter, (UINT_8) NETWORK_TYPE_AIS_INDEX, prCmd->aucPeerMac); -+ if (prStaRec == NULL) { -+ DBGLOG(TDLS, ERROR, " %s: cannot find the peer! %pM\n", -+ __func__, prCmd->aucPeerMac); -+ return TDLS_STATUS_FAILURE; -+ } -+ -+ if (prCmd->fgIsEnabled == TRUE) { -+ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_3); -+ DBGLOG(TDLS, TRACE, " %s: NL80211_TDLS_ENABLE_LINK\n", __func__); -+ -+ /* update key information after cnmStaRecChangeState(STA_STATE_3) */ -+ prStaRec->fgTdlsInSecurityMode = FALSE; -+ -+ if (prStaRec->rTdlsKeyTemp.u4Length > 0) { -+ UINT_32 u4BufLen; /* no use */ -+ -+ DBGLOG(TDLS, INFO, " %s: key len=%d\n", -+ __func__, (UINT32) prStaRec->rTdlsKeyTemp.u4Length); -+ -+ /* -+ reminder the function that we are CIPHER_SUITE_CCMP, -+ do not change cipher type to CIPHER_SUITE_WEP128 -+ */ -+ _wlanoidSetAddKey(prAdapter, &prStaRec->rTdlsKeyTemp, -+ prStaRec->rTdlsKeyTemp.u4Length, FALSE, CIPHER_SUITE_CCMP, &u4BufLen); -+ -+ /* clear the temp key */ -+ prStaRec->fgTdlsInSecurityMode = TRUE; -+ kalMemZero(&prStaRec->rTdlsKeyTemp, sizeof(prStaRec->rTdlsKeyTemp)); -+ } -+ -+ /* check if we need to disable channel switch function */ -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]); -+ if (prBssInfo->fgTdlsIsChSwProhibited == TRUE) { -+ TDLS_CMD_CORE_T rCmd; -+ -+ kalMemZero(&rCmd, sizeof(TDLS_CMD_CORE_T)); -+ rCmd.Content.rCmdChSwConf.ucNetTypeIndex = prStaRec->ucNetTypeIndex; -+ rCmd.Content.rCmdChSwConf.fgIsChSwEnabled = FALSE; -+ kalMemCopy(rCmd.aucPeerMac, prStaRec->aucMacAddr, 6); -+ TdlsChSwConf(prAdapter, &rCmd, 0, 0); -+ -+ DBGLOG(TDLS, INFO, " %s: disable channel switch\n", __func__); -+ } -+ -+ TDLS_LINK_INCREASE(prGlueInfo); -+ -+ /* record link */ -+ if (prStaRec->ucDesiredPhyTypeSet & PHY_TYPE_SET_802_11N) -+ rHisOthers.fgIsHt = TRUE; -+ else -+ rHisOthers.fgIsHt = FALSE; -+ -+ TdlsLinkHistoryRecord(prAdapter->prGlueInfo, FALSE, -+ prStaRec->aucMacAddr, !prStaRec->flgTdlsIsInitiator, 0, &rHisOthers); -+ } else { -+ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); -+ cnmStaRecFree(prAdapter, prStaRec, TRUE); /* release to other TDLS peers */ -+ DBGLOG(TDLS, TRACE, " %s: NL80211_TDLS_DISABLE_LINK\n", __func__); -+ -+ TDLS_LINK_DECREASE(prGlueInfo); -+/* while(1); //sample debug */ -+ } -+ -+ /* work-around link count */ -+ if ((TDLS_LINK_COUNT(prGlueInfo) < 0) || (TDLS_LINK_COUNT(prGlueInfo) > 1)) { -+ /* ERROR case: work-around to recount by searching all station records */ -+ UINT32 u4Idx; -+ -+ TDLS_LINK_COUNT_RESET(prGlueInfo); -+ -+ for (u4Idx = 0; u4Idx < CFG_STA_REC_NUM; u4Idx++) { -+ prStaRec = &prAdapter->arStaRec[u4Idx]; -+ -+ if (prStaRec->fgIsInUse && IS_TDLS_STA(prStaRec)) -+ TDLS_LINK_INCREASE(prGlueInfo); -+ } -+ -+ if (TDLS_LINK_COUNT(prGlueInfo) > 1) { -+ /* number of links is still > 1 */ -+ DBGLOG(TDLS, INFO, " %s: cTdlsLinkCnt %d > 1?\n", -+ __func__, TDLS_LINK_COUNT(prGlueInfo)); -+ -+ TDLS_LINK_COUNT_RESET(prGlueInfo); -+ -+ /* free all TDLS links */ -+ for (u4Idx = 0; u4Idx < CFG_STA_REC_NUM; u4Idx++) { -+ prStaRec = &prAdapter->arStaRec[u4Idx]; -+ -+ if (prStaRec->fgIsInUse && IS_TDLS_STA(prStaRec)) -+ cnmStaRecFree(prAdapter, prStaRec, TRUE); -+ } -+ -+ /* maybe inform supplicant ? */ -+ } -+ } -+ -+ /* display TDLS link history */ -+ TdlsInfoDisplay(prAdapter, NULL, 0, NULL); -+ -+ return TDLS_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to send a TDLS action data frame. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set -+* \param[in] u4SetBufferLen The length of the set buffer -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed due to invalid length of -+* the set buffer, returns the amount of storage needed. -+* -+* \retval TDLS_STATUS_xx -+*/ -+/*----------------------------------------------------------------------------*/ -+TDLS_STATUS TdlsexMgmtCtrl(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen) -+{ -+ GLUE_INFO_T *prGlueInfo; -+ TDLS_MGMT_TX_INFO *prMgmtTxInfo; -+ STA_RECORD_T *prStaRec; -+ -+ /* sanity check */ -+ if ((prAdapter == NULL) || (pvSetBuffer == NULL) || (pu4SetInfoLen == NULL)) { -+ DBGLOG(TDLS, ERROR, " %s: sanity fail!\n", __func__); -+ return TDLS_STATUS_FAILURE; -+ } -+ -+ /* init */ -+ prGlueInfo = (GLUE_INFO_T *) prAdapter->prGlueInfo; -+ *pu4SetInfoLen = sizeof(TDLS_MGMT_TX_INFO); -+ prMgmtTxInfo = (TDLS_MGMT_TX_INFO *) pvSetBuffer; -+ -+ switch (prMgmtTxInfo->ucActionCode) { -+ case TDLS_FRM_ACTION_DISCOVERY_RESPONSE: -+ prStaRec = NULL; -+ break; -+ -+ case TDLS_FRM_ACTION_SETUP_REQ: -+ prStaRec = cnmGetStaRecByAddress(prAdapter, (UINT_8) NETWORK_TYPE_AIS_INDEX, prMgmtTxInfo->aucPeer); -+ if ((prStaRec != NULL) && (prStaRec->ucStaState == STA_STATE_3)) { -+ /* rekey? we reject re-setup link currently */ -+ /* TODO: Still can setup link during rekey */ -+ -+ /* -+ return success to avoid supplicant clear TDLS entry; -+ Or we cannot send out any TDLS tear down frame to the peer -+ */ -+ DBGLOG(TDLS, TRACE, " %s: skip new setup on the exist link!\n", __func__); -+ return TDLS_STATUS_SUCCESS; -+ } -+ -+ prStaRec = NULL; -+ break; -+ -+ case TDLS_FRM_ACTION_SETUP_RSP: -+ case TDLS_FRM_ACTION_CONFIRM: -+ case TDLS_FRM_ACTION_TEARDOWN: -+ prStaRec = cnmGetStaRecByAddress(prAdapter, (UINT_8) NETWORK_TYPE_AIS_INDEX, prMgmtTxInfo->aucPeer); -+#if 0 /* in some cases, the prStaRec is still NULL */ -+ /* -+ EX: if a peer sends us a TDLS setup request with wrong BSSID, -+ supplicant will not call TdlsexPeerAdd() to create prStaRec and -+ supplicant will send a TDLS setup response with status code 7. -+ -+ So in the case, prStaRec will be NULL. -+ */ -+ if (prStaRec == NULL) { -+ DBGLOG(TDLS, ERROR, " %s: cannot find the peer!\n", __func__); -+ return -EINVAL; -+ } -+#endif -+ break; -+ -+ /* -+ TODO: Discovery response frame -+ Note that the TDLS Discovery Response frame is not a TDLS frame but a 11 -+ Public Action frame. -+ In WiFi TDLS Tech Minutes June 8 2010.doc, -+ a public action frame (i.e. it is no longer an encapsulated data frame) -+ */ -+ -+ default: -+ DBGLOG(TDLS, ERROR, -+ " %s: wrong action_code %d!\n", __func__, prMgmtTxInfo->ucActionCode); -+ return TDLS_STATUS_FAILURE; -+ } -+ -+ /* send the TDLS data frame */ -+ if (prStaRec != NULL) { -+ DBGLOG(TDLS, INFO, " %s: [%pM] ps=%d status=%d\n", -+ __func__, prStaRec->aucMacAddr, -+ prStaRec->fgIsInPS, prMgmtTxInfo->u2StatusCode); -+ -+ if (prMgmtTxInfo->ucActionCode == TDLS_FRM_ACTION_TEARDOWN) { -+ /* record disconnect history */ -+ TdlsLinkHistoryRecord(prGlueInfo, TRUE, prMgmtTxInfo->aucPeer, -+ TRUE, prMgmtTxInfo->u2StatusCode, NULL); -+ } -+ } -+ -+ return TdlsDataFrameSend(prAdapter, -+ prStaRec, -+ prMgmtTxInfo->aucPeer, -+ prMgmtTxInfo->ucActionCode, -+ prMgmtTxInfo->ucDialogToken, -+ prMgmtTxInfo->u2StatusCode, -+ (UINT_8 *) prMgmtTxInfo->aucSecBuf, prMgmtTxInfo->u4SecBufLen); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to add a peer record. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set -+* \param[in] u4SetBufferLen The length of the set buffer -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed due to invalid length of -+* the set buffer, returns the amount of storage needed. -+* -+* \retval TDLS_STATUS_xx -+*/ -+/*----------------------------------------------------------------------------*/ -+TDLS_STATUS TdlsexPeerAdd(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen) -+{ -+ GLUE_INFO_T *prGlueInfo; -+ TDLS_CMD_PEER_ADD_T *prCmd; -+ BSS_INFO_T *prAisBssInfo; -+ STA_RECORD_T *prStaRec; -+ UINT_8 ucNonHTPhyTypeSet; -+ UINT32 u4StartIdx; -+ OS_SYSTIME rCurTime; -+ -+ /* sanity check */ -+ DBGLOG(TDLS, INFO, " %s\n", __func__); -+ -+ if ((prAdapter == NULL) || (pvSetBuffer == NULL) || (pu4SetInfoLen == NULL)) { -+ DBGLOG(TDLS, ERROR, " %s: sanity fail!\n", __func__); -+ return TDLS_STATUS_FAILURE; -+ } -+ -+ /* init */ -+ prGlueInfo = (GLUE_INFO_T *) prAdapter->prGlueInfo; -+ *pu4SetInfoLen = sizeof(TDLS_CMD_PEER_ADD_T); -+ prCmd = (TDLS_CMD_PEER_ADD_T *) pvSetBuffer; -+ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ u4StartIdx = 0; -+ -+ /* search old entry */ -+ prStaRec = cnmGetStaRecByAddress(prAdapter, (UINT_8) NETWORK_TYPE_AIS_INDEX, prCmd->aucPeerMac); -+ -+ /* check if any TDLS link exists because we only support one TDLS link currently */ -+ if (prStaRec == NULL) { -+ /* the MAC is new peer */ -+ prStaRec = cnmStaTheTypeGet(prAdapter, NETWORK_TYPE_AIS_INDEX, STA_TYPE_TDLS_PEER, &u4StartIdx); -+ -+ if (prStaRec != NULL) { -+ /* a building TDLS link exists */ -+ DBGLOG(TDLS, ERROR, -+ " %s: one TDLS link setup [%pM] is going...\n", -+ __func__, prStaRec->aucMacAddr); -+ -+ if (prStaRec->ucStaState != STA_STATE_3) { -+ /* check timeout */ -+ GET_CURRENT_SYSTIME(&rCurTime); -+ -+ if (CHECK_FOR_TIMEOUT(rCurTime, prStaRec->rTdlsSetupStartTime, -+ SEC_TO_SYSTIME(TDLS_SETUP_TIMEOUT_SEC))) { -+ /* free the StaRec */ -+ cnmStaRecFree(prAdapter, prStaRec, TRUE); -+ -+ DBGLOG(TDLS, ERROR, -+ " %s: free going TDLS link setup [%pM]\n", -+ __func__, (prStaRec->aucMacAddr)); -+ -+ /* handle new setup */ -+ prStaRec = NULL; -+ } else -+ return TDLS_STATUS_FAILURE; -+ } else { -+ /* the TDLS is built and works fine, reject new one */ -+ return TDLS_STATUS_FAILURE; -+ } -+ } -+ } else { -+ if (prStaRec->ucStaState == STA_STATE_3) { -+ /* the peer exists, maybe TPK lifetime expired, supplicant wants to renew key */ -+ TdlsLinkHistoryRecord(prAdapter->prGlueInfo, TRUE, -+ prStaRec->aucMacAddr, TRUE, -+ TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_REKEY, NULL); -+ -+ /* 16 Nov 21:49 2012 http://permalink.gmane.org/gmane.linux.kernel.wireless.general/99712 */ -+ cfg80211_tdls_oper_request(prAdapter->prGlueInfo->prDevHandler, -+ prStaRec->aucMacAddr, TDLS_FRM_ACTION_TEARDOWN, -+ TDLS_REASON_CODE_UNSPECIFIED, GFP_ATOMIC); -+ -+ DBGLOG(TDLS, TRACE, -+ " %s: re-setup link for [%pM] maybe re-key?\n", -+ __func__, (prStaRec->aucMacAddr)); -+ return TDLS_STATUS_FAILURE; -+ } -+ } -+ -+ /* -+ create new entry if not exist -+ -+ 1. we are initiator -+ (1) send TDLS setup request -+ wpa_sm_tdls_peer_addset(sm, peer->addr, 1, 0, 0, NULL, 0, NULL, NULL, 0, NULL, 0); -+ create a station record with STA_STATE_1. -+ (2) got TDLS setup response and send TDLS setup confirm -+ wpa_tdls_enable_link() -+ update a station record with STA_STATE_3. -+ -+ 2. we are responder -+ (1) got TDLS setup request -+ wpa_sm_tdls_peer_addset(sm, peer->addr, 1, 0, 0, NULL, 0, NULL, NULL, 0, NULL, 0); -+ create a station record with STA_STATE_1. -+ (2) send TDLS setup response -+ (3) got TDLS setup confirm -+ wpa_tdls_enable_link() -+ update a station record with STA_STATE_3. -+ */ -+ if (prStaRec == NULL) { -+ prStaRec = cnmStaRecAlloc(prAdapter, (UINT_8) NETWORK_TYPE_AIS_INDEX); -+ -+ if (prStaRec == NULL) { -+ /* shall not be here */ -+ DBGLOG(TDLS, ERROR, " %s: alloc prStaRec fail!\n", __func__); -+ return TDLS_STATUS_RESOURCES; -+ } -+ -+ /* init the prStaRec */ -+ /* prStaRec will be zero first in cnmStaRecAlloc() */ -+ COPY_MAC_ADDR(prStaRec->aucMacAddr, prCmd->aucPeerMac); -+ -+/* cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); */ -+ } else { -+#if 0 -+ if ((prStaRec->ucStaState > STA_STATE_1) && (IS_TDLS_STA(prStaRec))) { -+ /* -+ test plan: The STAUT should locally tear down existing TDLS direct link and -+ respond with Set up Response frame. -+ */ -+ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); -+ } -+#endif -+ } -+ -+ /* reference to bssCreateStaRecFromBssDesc() and use our best capability */ -+ /* reference to assocBuildReAssocReqFrameCommonIEs() to fill elements */ -+ -+ /* prStaRec->u2CapInfo */ -+ /* TODO: Need to parse elements from setup request frame */ -+ prStaRec->u2OperationalRateSet = prAisBssInfo->u2OperationalRateSet; -+ prStaRec->u2BSSBasicRateSet = prAisBssInfo->u2BSSBasicRateSet; -+ prStaRec->u2DesiredNonHTRateSet = prAdapter->rWifiVar.ucAvailablePhyTypeSet; -+ prStaRec->ucPhyTypeSet = prAisBssInfo->ucPhyTypeSet; -+ prStaRec->eStaType = STA_TYPE_TDLS_PEER; -+ -+ prStaRec->ucDesiredPhyTypeSet = /*prStaRec->ucPhyTypeSet & */ -+ prAdapter->rWifiVar.ucAvailablePhyTypeSet; -+ ucNonHTPhyTypeSet = prStaRec->ucDesiredPhyTypeSet & PHY_TYPE_SET_802_11ABG; -+ -+ /* check for Target BSS's non HT Phy Types */ -+ if (ucNonHTPhyTypeSet) { -+ if (ucNonHTPhyTypeSet & PHY_TYPE_BIT_ERP) { -+ prStaRec->ucNonHTBasicPhyType = PHY_TYPE_ERP_INDEX; -+ } else if (ucNonHTPhyTypeSet & PHY_TYPE_BIT_OFDM) { -+ prStaRec->ucNonHTBasicPhyType = PHY_TYPE_OFDM_INDEX; -+ } else { /* if (ucNonHTPhyTypeSet & PHY_TYPE_HR_DSSS_INDEX) */ -+ -+ prStaRec->ucNonHTBasicPhyType = PHY_TYPE_HR_DSSS_INDEX; -+ } -+ -+ prStaRec->fgHasBasicPhyType = TRUE; -+ } else { -+ /* use mandatory for 11N only BSS */ -+/* ASSERT(prStaRec->ucPhyTypeSet & PHY_TYPE_SET_802_11N); */ -+ -+ prStaRec->ucNonHTBasicPhyType = PHY_TYPE_HR_DSSS_INDEX; -+ prStaRec->fgHasBasicPhyType = FALSE; -+ } -+ -+ /* update non HT Desired Rate Set */ -+ { -+ P_CONNECTION_SETTINGS_T prConnSettings; -+ -+ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); -+ prStaRec->u2DesiredNonHTRateSet = -+ (prStaRec->u2OperationalRateSet & prConnSettings->u2DesiredNonHTRateSet); -+ } -+ -+#if 0 /* TdlsexPeerAdd() will be called before we receive setup rsp in TdlsexRxFrameHandle() */ -+ /* check if the add is from the same peer in the 1st unhandled setup request frame */ -+ DBGLOG(TDLS, INFO, " %s: [%pM] [%pM]\n", -+ __func__, prGlueInfo->aucTdlsHtPeerMac, prCmd->aucPeerMac); -+ -+ if (kalMemCmp(prGlueInfo->aucTdlsHtPeerMac, prCmd->aucPeerMac, 6) == 0) { -+ /* copy the HT capability from its setup request */ -+ kalMemCopy(&prStaRec->rTdlsHtCap, &prGlueInfo->rTdlsHtCap, sizeof(IE_HT_CAP_T)); -+ -+ prStaRec->ucPhyTypeSet |= PHY_TYPE_SET_802_11N; -+ prStaRec->u2DesiredNonHTRateSet |= BIT(RATE_HT_PHY_INDEX); -+ -+ /* reset backup */ -+ kalMemZero(&prGlueInfo->rTdlsHtCap, sizeof(prStaRec->rTdlsHtCap)); -+ kalMemZero(prGlueInfo->aucTdlsHtPeerMac, sizeof(prGlueInfo->aucTdlsHtPeerMac)); -+ -+ DBGLOG(TDLS, INFO, " %s: peer is a HT device\n", __func__); -+ } -+#endif -+ -+ /* update WMM: must support due to UAPSD in TDLS link */ -+ prStaRec->fgIsWmmSupported = TRUE; -+ prStaRec->fgIsUapsdSupported = TRUE; -+ -+ /* update station record to firmware */ -+ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); -+ -+ /* update time */ -+ GET_CURRENT_SYSTIME(&prStaRec->rTdlsSetupStartTime); -+ -+ DBGLOG(TDLS, INFO, " %s: create a peer [%pM]\n", -+ __func__, (prStaRec->aucMacAddr)); -+ -+ return TDLS_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to update a peer record. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set -+* \param[in] u4SetBufferLen The length of the set buffer -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed due to invalid length of -+* the set buffer, returns the amount of storage needed. -+* -+* \retval TDLS_STATUS_xx -+*/ -+/*----------------------------------------------------------------------------*/ -+TDLS_STATUS TdlsexPeerUpdate(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen) -+{ -+ GLUE_INFO_T *prGlueInfo; -+ TDLS_CMD_PEER_UPDATE_T *prCmd; -+ BSS_INFO_T *prAisBssInfo; -+ STA_RECORD_T *prStaRec; -+ IE_HT_CAP_T *prHtCap; -+ -+ /* sanity check */ -+ DBGLOG(TDLS, INFO, " %s\n", __func__); -+ -+ if ((prAdapter == NULL) || (pvSetBuffer == NULL) || (pu4SetInfoLen == NULL)) { -+ DBGLOG(TDLS, ERROR, " %s: sanity fail!\n", __func__); -+ return TDLS_STATUS_FAILURE; -+ } -+ -+ /* init */ -+ prGlueInfo = (GLUE_INFO_T *) prAdapter->prGlueInfo; -+ *pu4SetInfoLen = sizeof(TDLS_CMD_PEER_ADD_T); -+ prCmd = (TDLS_CMD_PEER_UPDATE_T *) pvSetBuffer; -+ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ -+ /* search old entry */ -+ prStaRec = cnmGetStaRecByAddress(prAdapter, (UINT_8) NETWORK_TYPE_AIS_INDEX, prCmd->aucPeerMac); -+ -+ /* -+ create new entry if not exist -+ -+ 1. we are initiator -+ (1) send TDLS setup request -+ wpa_sm_tdls_peer_addset(sm, peer->addr, 1, 0, 0, NULL, 0, NULL, NULL, 0, NULL, 0); -+ create a station record with STA_STATE_1. -+ (2) got TDLS setup response and send TDLS setup confirm -+ wpa_tdls_enable_link() -+ update a station record with STA_STATE_3. -+ -+ 2. we are responder -+ (1) got TDLS setup request -+ wpa_sm_tdls_peer_addset(sm, peer->addr, 1, 0, 0, NULL, 0, NULL, NULL, 0, NULL, 0); -+ create a station record with STA_STATE_1. -+ (2) send TDLS setup response -+ (3) got TDLS setup confirm -+ wpa_tdls_enable_link() -+ update a station record with STA_STATE_3. -+ */ -+ if ((prStaRec == NULL) || (prStaRec->fgIsInUse == 0)) { -+ DBGLOG(TDLS, ERROR, " %s: cannot find the peer!\n", __func__); -+ return TDLS_STATUS_FAILURE; -+ } -+ -+ DBGLOG(TDLS, INFO, " %s: update a peer [%pM] %d -> %d, 0x%x\n", -+ __func__, (prStaRec->aucMacAddr), -+ prStaRec->ucStaState, STA_STATE_3, prStaRec->eStaType); -+ -+ if (!IS_TDLS_STA(prStaRec)) { -+ DBGLOG(TDLS, ERROR, " %s: peer is not TDLS one!\n", __func__); -+ return TDLS_STATUS_FAILURE; -+ } -+ -+ /* check if the add is from the same peer in the 1st unhandled setup request frame */ -+ DBGLOG(TDLS, INFO, " %s: [%pM] [%pM]\n", -+ __func__, (prGlueInfo->aucTdlsHtPeerMac), (prCmd->aucPeerMac)); -+ -+ if (kalMemCmp(prGlueInfo->aucTdlsHtPeerMac, prCmd->aucPeerMac, 6) == 0) { -+ /* copy the HT capability from its setup request */ -+ kalMemCopy(&prStaRec->rTdlsHtCap, &prGlueInfo->rTdlsHtCap, sizeof(IE_HT_CAP_T)); -+ -+ prStaRec->ucPhyTypeSet |= PHY_TYPE_SET_802_11N; -+ prStaRec->u2DesiredNonHTRateSet |= BIT(RATE_HT_PHY_INDEX); -+ -+ /* reset backup */ -+ kalMemZero(&prGlueInfo->rTdlsHtCap, sizeof(prStaRec->rTdlsHtCap)); -+ kalMemZero(prGlueInfo->aucTdlsHtPeerMac, sizeof(prGlueInfo->aucTdlsHtPeerMac)); -+ -+ DBGLOG(TDLS, INFO, " %s: peer is a HT device\n", __func__); -+ } -+ -+ /* update the record join time. */ -+ GET_CURRENT_SYSTIME(&prStaRec->rUpdateTime); -+ -+ /* update Station Record - Status/Reason Code */ -+ prStaRec->u2StatusCode = prCmd->u2StatusCode; -+ -+ /* prStaRec->ucStaState shall be STA_STATE_1 */ -+ -+ prStaRec->u2CapInfo = prCmd->u2Capability; -+/* prStaRec->u2OperationalRateSet */ -+ prStaRec->u2AssocId = 0; /* no use */ -+ prStaRec->u2ListenInterval = 0; /* unknown */ -+/* prStaRec->ucDesiredPhyTypeSet */ -+/* prStaRec->u2DesiredNonHTRateSet */ -+/* prStaRec->u2BSSBasicRateSet */ -+/* prStaRec->ucMcsSet */ -+/* prStaRec->fgSupMcs32 */ -+/* prStaRec->u2HtCapInfo */ -+ prStaRec->fgIsQoS = TRUE; -+ prStaRec->fgIsUapsdSupported = (prCmd->UapsdBitmap == 0) ? FALSE : TRUE; -+/* prStaRec->ucAmpduParam */ -+/* prStaRec->u2HtExtendedCap */ -+ prStaRec->u4TxBeamformingCap = 0; /* no use */ -+ prStaRec->ucAselCap = 0; /* no use */ -+ prStaRec->ucRCPI = 0; -+ prStaRec->ucBmpTriggerAC = prCmd->UapsdBitmap; -+ prStaRec->ucBmpDeliveryAC = prCmd->UapsdBitmap; -+ prStaRec->ucUapsdSp = prCmd->UapsdMaxSp; -+ -+ /* update HT */ -+#if (TDLS_CFG_HT_SUP == 1) -+ if (prCmd->fgIsSupHt == FALSE) { -+ /* no HT IE is from supplicant so we use the backup */ -+ prHtCap = (IE_HT_CAP_T *) &prStaRec->rTdlsHtCap; -+ -+ DBGLOG(TDLS, INFO, " %s: [%pM] update ht ie 0x%x\n", -+ __func__, (prStaRec->aucMacAddr), prHtCap->ucId); -+ -+ if (prHtCap->ucId == ELEM_ID_HT_CAP) { -+ prStaRec->ucMcsSet = prHtCap->rSupMcsSet.aucRxMcsBitmask[0]; -+ prStaRec->fgSupMcs32 = (prHtCap->rSupMcsSet.aucRxMcsBitmask[32 / 8] & BIT(0)) ? TRUE : FALSE; -+ -+ prStaRec->u2HtCapInfo = prHtCap->u2HtCapInfo; -+ prStaRec->ucAmpduParam = prHtCap->ucAmpduParam; -+ prStaRec->u2HtExtendedCap = prHtCap->u2HtExtendedCap; -+ prStaRec->u4TxBeamformingCap = prHtCap->u4TxBeamformingCap; -+ prStaRec->ucAselCap = prHtCap->ucAselCap; -+ prStaRec->ucDesiredPhyTypeSet |= PHY_TYPE_SET_802_11N; -+ } -+ } else { -+ /* TODO: use the HT IE from supplicant */ -+ } -+#endif /* TDLS_CFG_HT_SUP */ -+ -+ DBGLOG(TDLS, INFO, " %s: UAPSD 0x%x %d MCS=0x%x\n", -+ __func__, prCmd->UapsdBitmap, prCmd->UapsdMaxSp, prStaRec->ucMcsSet); -+ -+/* cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_3); */ -+ -+ DBGLOG(TDLS, INFO, " %s: update a peer [%pM]\n", -+ __func__, (prStaRec->aucMacAddr)); -+ -+ return TDLS_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to check if we need to drop a TDLS action frame. -+* -+* \param[in] *pPkt Pointer to the struct sk_buff->data. -+* \param[in] -+* \param[in] -+* -+* \retval None -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN TdlsexRxFrameDrop(GLUE_INFO_T *prGlueInfo, UINT_8 *pPkt) -+{ -+ ADAPTER_T *prAdapter; -+ UINT8 ucActionId; -+ -+ /* sanity check */ -+ if ((pPkt == NULL) || (*(pPkt + 12) != 0x89) || (*(pPkt + 13) != 0x0d)) -+ return FALSE; /* not TDLS data frame htons(0x890d) */ -+ -+#if 0 /* supplicant handles this check */ -+ if (prStaRec == NULL) -+ return FALSE; /* shall not be here */ -+ -+ DBGLOG(TDLS, INFO, -+ " %s: Rcv a TDLS action frame (id=%d) %d %d\n", -+ __func__, *(pPkt + 13 + 4), prStaRec->fgTdlsIsProhibited, fgIsPtiTimeoutSkip); -+ -+ /* check if TDLS Prohibited bit is set in AP's beacon */ -+ if (prStaRec->fgTdlsIsProhibited == TRUE) -+ return TRUE; -+#endif -+ -+ ucActionId = *(pPkt + 12 + 2 + 2); /* skip dst, src MAC, type, payload type, category */ -+ -+ if (fgIsPtiTimeoutSkip == TRUE) { -+ /* also skip any tear down frame from the peer */ -+ if (ucActionId == TDLS_FRM_ACTION_TEARDOWN) -+ return TRUE; -+ } -+ -+ prAdapter = prGlueInfo->prAdapter; -+ DBGLOG(TDLS, INFO, -+ " %s: Rcv a TDLS action frame %d (%u)\n", -+ __func__, ucActionId, (UINT32) prAdapter->rRxCtrl.rFreeSwRfbList.u4NumElem); -+ -+ if (ucActionId == TDLS_FRM_ACTION_TEARDOWN) { -+ DBGLOG(TDLS, WARN, " %s: Rcv a TDLS tear down frame %d, will DISABLE link\n", -+ __func__, *(pPkt + 13 + 4)); /* reason code */ -+ -+ /* record disconnect history */ -+ TdlsLinkHistoryRecord(prGlueInfo, TRUE, pPkt + 6, FALSE, *(pPkt + 13 + 4), NULL); -+ -+ /* inform tear down to supplicant only in OPEN/NONE mode */ -+ /* -+ we need to tear down the link manually; or supplicant will display -+ "No FTIE in TDLS Teardown" and it will not tear down the link -+ */ -+ cfg80211_tdls_oper_request(prGlueInfo->prDevHandler, -+ pPkt + 6, TDLS_FRM_ACTION_TEARDOWN, *(pPkt + 13 + 4), GFP_ATOMIC); -+ } -+#if 0 /* pass all to supplicant except same thing is handled in supplicant */ -+ if (((*(pPkt + 13 + 3)) == TDLS_FRM_ACTION_PTI) || -+ ((*(pPkt + 13 + 3)) == TDLS_FRM_ACTION_CHAN_SWITCH_REQ) || -+ ((*(pPkt + 13 + 3)) == TDLS_FRM_ACTION_CHAN_SWITCH_RSP) || -+ ((*(pPkt + 13 + 3)) == TDLS_FRM_ACTION_PTI_RSP)) { -+ return TRUE; -+ } -+#endif -+ -+ return FALSE; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to parse some IEs in the setup frame from the peer. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] pPkt Pointer to the ethernet packet -+* -+* \retval None -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID TdlsexRxFrameHandle(GLUE_INFO_T *prGlueInfo, UINT8 *pPkt, UINT16 u2PktLen) -+{ -+ ADAPTER_T *prAdapter; -+ STA_RECORD_T *prStaRec; -+ UINT8 ucActionId; -+ UINT8 *pucPeerMac, ucElmId, ucElmLen; -+ INT16 s2FmeLen; -+ -+ /* sanity check */ -+ if ((prGlueInfo == NULL) || (pPkt == NULL) || (*(pPkt + 12) != 0x89) || (*(pPkt + 13) != 0x0d)) -+ return; -+ -+ ucActionId = *(pPkt + 12 + 2 + 2); /* skip dst, src MAC, type, payload type, category */ -+ -+ if ((ucActionId != TDLS_FRM_ACTION_SETUP_REQ) && (ucActionId != TDLS_FRM_ACTION_SETUP_RSP)) -+ return; -+ -+ /* init */ -+ prAdapter = prGlueInfo->prAdapter; -+ pucPeerMac = pPkt + 6; -+ s2FmeLen = (INT16) u2PktLen; -+ -+ DBGLOG(TDLS, TRACE, -+ " %s: get a setup frame %d from %pM\n", -+ __func__, ucActionId, (pucPeerMac)); -+ -+ if (ucActionId == TDLS_FRM_ACTION_SETUP_REQ) -+ pPkt += 12 + 2 + 2 + 1 + 1 + 2; /* skip action, dialog token, capability */ -+ else -+ pPkt += 12 + 2 + 2 + 1 + 2 + 1 + 2; /* skip action, status code, dialog token, capability */ -+ -+ /* check station record */ -+ prStaRec = cnmGetStaRecByAddress(prGlueInfo->prAdapter, (UINT_8) NETWORK_TYPE_AIS_INDEX, pucPeerMac); -+ -+ if (prStaRec == NULL) { -+ prStaRec = cnmStaRecAlloc(prAdapter, (UINT_8) NETWORK_TYPE_AIS_INDEX); -+ -+ if (prStaRec == NULL) { -+ /* TODO: only one TDLS entry, need to free old one if timeout */ -+ DBGLOG(TDLS, ERROR, " %s: alloc prStaRec fail!\n", __func__); -+ return; -+ } -+ -+ /* init the prStaRec */ -+ /* prStaRec will be zero first in cnmStaRecAlloc() */ -+ COPY_MAC_ADDR(prStaRec->aucMacAddr, pucPeerMac); -+ -+ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); -+ } -+ -+ /* backup HT IE to station record */ -+ /* TODO: Maybe our TDLS only supports non-11n */ -+ while (s2FmeLen > 0) { -+ ucElmId = *pPkt++; -+ ucElmLen = *pPkt++; -+ -+ switch (ucElmId) { -+ case ELEM_ID_HT_CAP: /* 0x2d */ -+ /* backup the HT IE of 1st unhandled setup request frame */ -+ if (prGlueInfo->rTdlsHtCap.ucId == 0x00) { -+ kalMemCopy(prGlueInfo->aucTdlsHtPeerMac, pucPeerMac, 6); -+ kalMemCopy(&prGlueInfo->rTdlsHtCap, pPkt - 2, ucElmLen + 2); -+ -+ /* -+ cannot backup in prStaRec; or -+ -+ 1. we build a TDLS link -+ 2. peer re-sends setup req -+ 3. we backup HT cap element -+ 4. supplicant disables the link -+ 5. we clear the prStaRec -+ */ -+ -+ DBGLOG(TDLS, TRACE, -+ " %s: %pM: find a HT IE\n", -+ __func__, (pucPeerMac)); -+ } -+ return; -+ -+ case ELEM_ID_EXTENDED_CAP: -+ /* TODO: backup the extended capability IE */ -+ break; -+ } -+ -+ pPkt += ucElmLen; -+ s2FmeLen -= (2 + ucElmLen); -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to get the TDLS station record. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prInBuf A pointer to the command string buffer -+* \param[in] u4InBufLen The length of the buffer -+* \param[out] None -+* -+* \retval TDLS_STATUS_SUCCESS: this is TDLS packet -+* TDLS_STATUS_FAILURE: this is not TDLS packet -+*/ -+/*----------------------------------------------------------------------------*/ -+TDLS_STATUS TdlsexStaRecIdxGet(ADAPTER_T *prAdapter, MSDU_INFO_T *prMsduInfo) -+{ -+ BSS_INFO_T *prBssInfo; -+ STA_RECORD_T *prStaRec; -+ TDLS_STATUS Status; -+ -+ /* sanity check */ -+ if ((prAdapter == NULL) || (prMsduInfo == NULL)) -+ return TDLS_STATUS_FAILURE; -+ -+ if (prAdapter->prGlueInfo == NULL) -+ return TDLS_STATUS_FAILURE; -+ if (TDLS_IS_NO_LINK_GOING(prAdapter->prGlueInfo)) -+ return TDLS_STATUS_FAILURE; -+ -+ /* init */ -+ prMsduInfo->ucStaRecIndex = STA_REC_INDEX_NOT_FOUND; -+ Status = TDLS_STATUS_SUCCESS; -+ -+ /* get record by ether dest */ -+ prStaRec = cnmGetStaRecByAddress(prAdapter, (UINT_8) NETWORK_TYPE_AIS_INDEX, prMsduInfo->aucEthDestAddr); -+ -+ /* -+ TDLS Setup Request frames, TDLS Setup Response frames and TDLS Setup Confirm -+ frames shall be transmitted through the AP and shall not be transmitted to a group -+ address. -+ -+ 1. In first time, prStaRec == NULL or prStaRec->ucStaState != STA_STATE_3, -+ we will send them to AP; -+ 2. When link is still on, if you command to send TDLS setup from supplicant, -+ supplicant will DISABLE LINK first, prStaRec will be NULL then send TDLS -+ setup frame to the peer. -+ */ -+ -+ do { -+ if ((prStaRec != NULL) && (prStaRec->ucStaState == STA_STATE_3) && (IS_TDLS_STA(prStaRec))) { -+ /* -+ TDLS Test Case 5.3 Tear Down -+ Automatically sends TDLS Teardown frame to STA 2 via AP -+ -+ 11.21.5 TDLS Direct Link Teardown -+ The TDLS Teardown frame shall be sent over the direct path and the reason -+ code shall be set to "TDLS 40 direct link teardown for unspecified reason", -+ except when the TDLS peer STA is unreachable via the TDLS direct link, -+ in which case, the TDLS Teardown frame shall be sent through the AP and -+ the reason code shall be set to "TDLS direct link teardown due to TDLS peer -+ STA unreachable via the TDLS direct link". -+ */ -+ /* if (prStaRec->fgIsInPS == TRUE) */ -+ /* -+ check if the packet is tear down: -+ we do not want to use PTI to indicate the tear down and -+ we want to send the tear down to AP then AP help us to send it -+ */ -+ struct sk_buff *prSkb; -+ UINT8 *pEth; -+ UINT_16 u2EtherTypeLen; -+ -+ prSkb = (struct sk_buff *)prMsduInfo->prPacket; -+ if (prSkb != NULL) { -+ UINT8 ucActionCode, ucReasonCode; -+ -+ /* init */ -+ pEth = prSkb->data; -+ u2EtherTypeLen = (pEth[ETH_TYPE_LEN_OFFSET] << 8) | -+ (pEth[ETH_TYPE_LEN_OFFSET + 1]); -+ ucActionCode = pEth[ETH_TYPE_LEN_OFFSET + 1 + 3]; -+ ucReasonCode = pEth[ETH_TYPE_LEN_OFFSET + 1 + 4] | -+ (pEth[ETH_TYPE_LEN_OFFSET + 1 + 5] << 8); -+ -+ /* TDLS_REASON_CODE_UNREACHABLE: keep alive fail or PTI timeout */ -+ if ((u2EtherTypeLen == TDLS_FRM_PROT_TYPE) && -+ (ucActionCode == TDLS_FRM_ACTION_TEARDOWN) && -+ (ucReasonCode == TDLS_REASON_CODE_UNREACHABLE)) { -+ /* -+ when we cannot reach the peer, -+ we need AP's help to send the tear down frame -+ */ -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ prStaRec = prBssInfo->prStaRecOfAP; -+ if (prStaRec == NULL) { -+ Status = TDLS_STATUS_FAILURE; -+ break; -+ } -+#if 0 -+ /* change status code */ -+ pEth[ETH_TYPE_LEN_OFFSET + 1 + 4] = TDLS_REASON_CODE_UNREACHABLE; -+#endif -+ } -+ } -+ prMsduInfo->ucStaRecIndex = prStaRec->ucIndex; -+ } -+ } while (FALSE); -+ -+ DBGLOG(TDLS, INFO, " %s: (Status=%x) [%pM] ucStaRecIndex = %d!\n", -+ __func__, (INT32) Status, (prMsduInfo->aucEthDestAddr), -+ prMsduInfo->ucStaRecIndex); -+ return Status; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is used to check if we suffer timeout for TX quota empty case. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID TdlsexTxQuotaCheck(GLUE_INFO_T *prGlueInfo, STA_RECORD_T *prStaRec, UINT8 FreeQuota) -+{ -+ OS_SYSTIME rCurTime; -+ -+ /* sanity check */ -+ if (!IS_TDLS_STA(prStaRec)) -+ return; -+ -+ if (FreeQuota != 0) { -+ /* reset timeout */ -+ prStaRec->rTdlsTxQuotaEmptyTime = 0; -+ return; -+ } -+ -+ /* work-around: check if the no free quota case is too long */ -+ GET_CURRENT_SYSTIME(&rCurTime); -+ -+ if (prStaRec->rTdlsTxQuotaEmptyTime == 0) { -+ prStaRec->rTdlsTxQuotaEmptyTime = rCurTime; -+ } else { -+ if (CHECK_FOR_TIMEOUT(rCurTime, prStaRec->rTdlsTxQuotaEmptyTime, -+ SEC_TO_SYSTIME(TDLS_TX_QUOTA_EMPTY_TIMEOUT))) { -+ /* tear down the link */ -+ DBGLOG(TDLS, WARN, -+ " %s: [%pM] TX quota empty timeout!\n", -+ __func__, (prStaRec->aucMacAddr)); -+ -+ /* record disconnect history */ -+ TdlsLinkHistoryRecord(prGlueInfo, TRUE, prStaRec->aucMacAddr, -+ TRUE, TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_TX_QUOTA_EMPTY, NULL); -+ -+ /* inform tear down to supplicant only in OPEN/NONE mode */ -+ /* -+ we need to tear down the link manually; or supplicant will display -+ "No FTIE in TDLS Teardown" and it will not tear down the link -+ */ -+ cfg80211_tdls_oper_request(prGlueInfo->prDevHandler, -+ prStaRec->aucMacAddr, TDLS_FRM_ACTION_TEARDOWN, -+ TDLS_REASON_CODE_UNREACHABLE, GFP_ATOMIC); -+ } -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is used to un-initialize variables in TDLS. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID TdlsexUninit(ADAPTER_T *prAdapter) -+{ -+#if TDLS_CFG_CMD_TEST -+ cnmTimerStopTimer(prAdapter, &rTdlsTimerTestDataSend); -+#endif /* TDLS_CFG_CMD_TEST */ -+} -+ -+#endif /* CFG_SUPPORT_TDLS */ -+ -+/* End of tdls.c */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/tdls_com.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/tdls_com.c -new file mode 100644 -index 000000000000..5450cbb65183 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/tdls_com.c -@@ -0,0 +1,741 @@ -+/* -+** Id: tdls_com.c#1 -+*/ -+ -+/*! \file tdls_com.c -+ \brief This file includes IEEE802.11z TDLS main support. -+*/ -+ -+/* -+** Log: tdls_com.c -+ * -+ * 11 13 2013 vend_samp.lin -+ * NULL -+ * Initial version. -+ */ -+ -+/******************************************************************************* -+ * C O M P I L E R F L A G S -+ ******************************************************************************** -+ */ -+ -+/******************************************************************************* -+ * E X T E R N A L R E F E R E N C E S -+ ******************************************************************************** -+ */ -+ -+#include "precomp.h" -+ -+#if (CFG_SUPPORT_TDLS == 1) -+#include "tdls.h" -+ -+ /******************************************************************************* -+ * C O N S T A N T S -+ ******************************************************************************** -+ */ -+ -+ /******************************************************************************* -+ * F U N C T I O N D E C L A R A T I O N S -+ ******************************************************************************** -+ */ -+ -+ /******************************************************************************* -+ * P R I V A T E D A T A -+ ******************************************************************************** -+ */ -+ -+ /******************************************************************************* -+ * P R I V A T E F U N C T I O N S -+ ******************************************************************************** -+ */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to append general IEs. -+* -+* \param[in] pvAdapter Pointer to the Adapter structure. -+* \param[in] prStaRec Pointer to the STA_RECORD_T structure. -+* \param[in] u2StatusCode Status code. -+* \param[in] pPkt Pointer to the frame body -+* -+* \retval append length -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT_32 TdlsFrameGeneralIeAppend(ADAPTER_T *prAdapter, STA_RECORD_T *prStaRec, UINT_16 u2StatusCode, UINT_8 *pPkt) -+{ -+ GLUE_INFO_T *prGlueInfo; -+ BSS_INFO_T *prBssInfo; -+ PM_PROFILE_SETUP_INFO_T *prPmProfSetupInfo; -+ UINT_32 u4NonHTPhyType; -+ UINT_16 u2SupportedRateSet; -+ UINT_8 aucAllSupportedRates[RATE_NUM] = { 0 }; -+ UINT_8 ucAllSupportedRatesLen; -+ UINT_8 ucSupRatesLen; -+ UINT_8 ucExtSupRatesLen; -+ UINT_32 u4PktLen, u4IeLen; -+ BOOLEAN fg40mAllowed; -+ -+ /* reference to assocBuildReAssocReqFrameCommonIEs() */ -+ -+ /* init */ -+ prGlueInfo = (GLUE_INFO_T *) prAdapter->prGlueInfo; -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ prPmProfSetupInfo = &prBssInfo->rPmProfSetupInfo; -+ u4PktLen = 0; -+ -+ /* 3. Frame Formation - (5) Supported Rates element */ -+ /* use all sup rate we can support */ -+ if (prStaRec != NULL) -+ u4NonHTPhyType = prStaRec->ucNonHTBasicPhyType; -+ else -+ u4NonHTPhyType = PHY_TYPE_ERP_INDEX; /* default */ -+ -+ u2SupportedRateSet = rNonHTPhyAttributes[u4NonHTPhyType].u2SupportedRateSet; -+ -+ if (prStaRec != NULL) { -+ u2SupportedRateSet &= prStaRec->u2OperationalRateSet; -+ -+ if (u2SupportedRateSet == 0) -+ u2SupportedRateSet = rNonHTPhyAttributes[u4NonHTPhyType].u2SupportedRateSet; -+ } -+ -+ rateGetDataRatesFromRateSet(u2SupportedRateSet, -+ prBssInfo->u2BSSBasicRateSet, aucAllSupportedRates, &ucAllSupportedRatesLen); -+ -+ ucSupRatesLen = ((ucAllSupportedRatesLen > ELEM_MAX_LEN_SUP_RATES) ? -+ ELEM_MAX_LEN_SUP_RATES : ucAllSupportedRatesLen); -+ -+ ucExtSupRatesLen = ucAllSupportedRatesLen - ucSupRatesLen; -+ -+ if (ucSupRatesLen) { -+ SUP_RATES_IE(pPkt)->ucId = ELEM_ID_SUP_RATES; -+ SUP_RATES_IE(pPkt)->ucLength = ucSupRatesLen; -+ kalMemCopy(SUP_RATES_IE(pPkt)->aucSupportedRates, aucAllSupportedRates, ucSupRatesLen); -+ -+ u4IeLen = IE_SIZE(pPkt); -+ pPkt += u4IeLen; -+ u4PktLen += u4IeLen; -+ } -+ -+ /* 3. Frame Formation - (7) Extended sup rates element */ -+ if (ucExtSupRatesLen) { -+ -+ EXT_SUP_RATES_IE(pPkt)->ucId = ELEM_ID_EXTENDED_SUP_RATES; -+ EXT_SUP_RATES_IE(pPkt)->ucLength = ucExtSupRatesLen; -+ -+ kalMemCopy(EXT_SUP_RATES_IE(pPkt)->aucExtSupportedRates, -+ &aucAllSupportedRates[ucSupRatesLen], ucExtSupRatesLen); -+ -+ u4IeLen = IE_SIZE(pPkt); -+ pPkt += u4IeLen; -+ u4PktLen += u4IeLen; -+ } -+ -+ /* 3. Frame Formation - (8) Supported channels element */ -+ /* -+ The Supported channels element is included in Request frame and also in Response -+ frame if Status Code 0 (successful). -+ */ -+ if (u2StatusCode == 0) { -+ SUPPORTED_CHANNELS_IE(pPkt)->ucId = ELEM_ID_SUP_CHS; -+ SUPPORTED_CHANNELS_IE(pPkt)->ucLength = 2; -+ SUPPORTED_CHANNELS_IE(pPkt)->ucChannelNum[0] = 1; -+ SUPPORTED_CHANNELS_IE(pPkt)->ucChannelNum[1] = 11; -+ -+#if CFG_SUPPORT_DFS -+ if (prAdapter->fgEnable5GBand == TRUE) { -+ /* 5G support */ -+ SUPPORTED_CHANNELS_IE(pPkt)->ucLength = 10; -+ SUPPORTED_CHANNELS_IE(pPkt)->ucChannelNum[2] = 36; -+ SUPPORTED_CHANNELS_IE(pPkt)->ucChannelNum[3] = 4; -+ SUPPORTED_CHANNELS_IE(pPkt)->ucChannelNum[4] = 52; -+ SUPPORTED_CHANNELS_IE(pPkt)->ucChannelNum[5] = 4; -+ SUPPORTED_CHANNELS_IE(pPkt)->ucChannelNum[6] = 149; -+ SUPPORTED_CHANNELS_IE(pPkt)->ucChannelNum[7] = 4; -+ SUPPORTED_CHANNELS_IE(pPkt)->ucChannelNum[8] = 165; -+ SUPPORTED_CHANNELS_IE(pPkt)->ucChannelNum[9] = 4; -+ } -+#endif /* CFG_SUPPORT_DFS */ -+ -+ u4IeLen = IE_SIZE(pPkt); -+ pPkt += u4IeLen; -+ u4PktLen += u4IeLen; -+ } -+ -+ /* 3. Frame Formation - (14) HT capabilities element */ -+ -+ /* no need to check AP capability */ -+/* if ((prAdapter->rWifiVar.ucAvailablePhyTypeSet & PHY_TYPE_SET_802_11N) && */ -+ -+ /* -+ after we set ucPhyTypeSet to PHY_TYPE_SET_802_11N in TdlsexRxFrameHandle(), -+ supplicant will disable link if exists and we will clear prStaRec. -+ -+ finally, prStaRec->ucPhyTypeSet will also be 0 -+ -+ so we have a fix in TdlsexPeerAdd(). -+ */ -+ if (!prStaRec || (prStaRec->ucPhyTypeSet & PHY_TYPE_SET_802_11N)) { -+ /* TODO: prAdapter->rWifiVar.rConnSettings.uc5GBandwidthMode */ -+#if 0 /* always support */ -+ if (prAdapter->rWifiVar.rConnSettings.uc2G4BandwidthMode == CONFIG_BW_20M) -+ fg40mAllowed = FALSE; -+ else -+#endif -+ fg40mAllowed = TRUE; -+ -+ u4IeLen = rlmFillHtCapIEByParams(fg40mAllowed, -+ prAdapter->rWifiVar.rConnSettings.fgRxShortGIDisabled, -+ prAdapter->rWifiVar.u8SupportRxSgi20, -+ prAdapter->rWifiVar.u8SupportRxSgi40, -+ prAdapter->rWifiVar.u8SupportRxGf, -+ prAdapter->rWifiVar.u8SupportRxSTBC, prBssInfo->eCurrentOPMode, pPkt); -+ -+ pPkt += u4IeLen; -+ u4PktLen += u4IeLen; -+ } -+ -+ /* 3. Frame Formation - (17) WMM Information element */ -+ -+ /* always support */ -+/* if (prAdapter->rWifiVar.fgSupportQoS) */ -+ -+ { -+ /* force to support all UAPSD in TDLS link */ -+ u4IeLen = mqmGenerateWmmInfoIEByParam(TRUE /*prAdapter->rWifiVar.fgSupportUAPSD */ , -+ 0xf /*prPmProfSetupInfo->ucBmpDeliveryAC */ , -+ 0xf /*prPmProfSetupInfo->ucBmpTriggerAC */ , -+ WMM_MAX_SP_LENGTH_ALL /*prPmProfSetupInfo->ucUapsdSp */ , -+ pPkt); -+ -+ pPkt += u4IeLen; -+ u4PktLen += u4IeLen; -+ } -+ -+ return u4PktLen; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to transmit a TDLS data frame (setup req/rsp/confirm and tear down). -+* -+* \param[in] pvAdapter Pointer to the Adapter structure. -+* \param[in] prStaRec Pointer to the STA_RECORD_T structure. -+* \param[in] pPeerMac Pointer to the MAC of the TDLS peer -+* \param[in] ucActionCode TDLS Action -+* \param[in] ucDialogToken Dialog token -+* \param[in] u2StatusCode Status code -+* \param[in] pAppendIe Others IEs (here are security IEs from supplicant) -+* \param[in] AppendIeLen IE length of others IEs -+* -+* \retval TDLS_STATUS_xx -+*/ -+/*----------------------------------------------------------------------------*/ -+TDLS_STATUS -+TdlsDataFrameSend(ADAPTER_T *prAdapter, -+ STA_RECORD_T *prStaRec, -+ UINT_8 *pPeerMac, -+ UINT_8 ucActionCode, -+ UINT_8 ucDialogToken, UINT_16 u2StatusCode, UINT_8 *pAppendIe, UINT_32 AppendIeLen) -+{ -+#define LR_TDLS_FME_FIELD_FILL(__Len) \ -+do { \ -+ pPkt += __Len; \ -+ u4PktLen += __Len; \ -+} while (0) -+ -+ GLUE_INFO_T *prGlueInfo; -+ BSS_INFO_T *prBssInfo; -+ PM_PROFILE_SETUP_INFO_T *prPmProfSetupInfo; -+ struct sk_buff *prMsduInfo; -+ MSDU_INFO_T *prMsduInfoMgmt; -+ UINT8 *pPkt, *pucInitiator, *pucResponder; -+ UINT32 u4PktLen, u4IeLen; -+ UINT16 u2CapInfo; -+/* UINT8 *pPktTemp; */ -+ -+ prGlueInfo = (GLUE_INFO_T *) prAdapter->prGlueInfo; -+ -+ DBGLOG(TDLS, INFO, " %s: 2040=%d\n", __func__, prGlueInfo->rTdlsLink.fgIs2040Sup); -+ -+ /* sanity check */ -+ if (prStaRec != NULL) { -+ if (prStaRec->ucNetTypeIndex >= NETWORK_TYPE_INDEX_NUM) { -+ DBGLOG(TDLS, ERROR, -+ " %s: net index %d fail\n", __func__, prStaRec->ucNetTypeIndex); -+ return TDLS_STATUS_FAILURE; -+ } -+ -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]); -+ } else { -+ /* prStaRec maybe NULL in setup request */ -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ } -+ -+ /* allocate/init packet */ -+ prPmProfSetupInfo = &prBssInfo->rPmProfSetupInfo; -+ u4PktLen = 0; -+ prMsduInfo = NULL; -+ prMsduInfoMgmt = NULL; -+ -+ /* make up frame content */ -+ if (ucActionCode != TDLS_FRM_ACTION_DISCOVERY_RESPONSE) { -+ /* -+ The STAUT will not respond to a TDLS Discovery Request Frame with different BSSID. -+ Supplicant will check this in wpa_tdls_process_discovery_request(). -+ */ -+ -+ /* TODO: reduce 1600 to correct size */ -+ prMsduInfo = kalPacketAlloc(prGlueInfo, 1600, &pPkt); -+ if (prMsduInfo == NULL) { -+ DBGLOG(TDLS, ERROR, " %s: allocate pkt fail\n", __func__); -+ return TDLS_STATUS_RESOURCES; -+ } -+ -+ prMsduInfo->dev = prGlueInfo->prDevHandler; -+ if (prMsduInfo->dev == NULL) { -+ DBGLOG(TDLS, ERROR, " %s: MsduInfo->dev == NULL\n", __func__); -+ kalPacketFree(prGlueInfo, prMsduInfo); -+ return TDLS_STATUS_FAILURE; -+ } -+ -+ /* 1. 802.3 header */ -+/* pPktTemp = pPkt; */ -+ kalMemCopy(pPkt, pPeerMac, TDLS_FME_MAC_ADDR_LEN); -+ LR_TDLS_FME_FIELD_FILL(TDLS_FME_MAC_ADDR_LEN); -+ kalMemCopy(pPkt, prBssInfo->aucOwnMacAddr, TDLS_FME_MAC_ADDR_LEN); -+ LR_TDLS_FME_FIELD_FILL(TDLS_FME_MAC_ADDR_LEN); -+ *(UINT_16 *) pPkt = htons(TDLS_FRM_PROT_TYPE); -+ LR_TDLS_FME_FIELD_FILL(2); -+ -+ /* 2. payload type */ -+ *pPkt = TDLS_FRM_PAYLOAD_TYPE; -+ LR_TDLS_FME_FIELD_FILL(1); -+ -+ /* 3. Frame Formation - (1) Category */ -+ *pPkt = TDLS_FRM_CATEGORY; -+ LR_TDLS_FME_FIELD_FILL(1); -+ } else { -+ /* discovery response */ -+ WLAN_MAC_HEADER_T *prHdr; -+ -+ prMsduInfoMgmt = (MSDU_INFO_T *) -+ cnmMgtPktAlloc(prAdapter, PUBLIC_ACTION_MAX_LEN); -+ if (prMsduInfoMgmt == NULL) { -+ DBGLOG(TDLS, ERROR, " %s: allocate mgmt pkt fail\n", __func__); -+ return TDLS_STATUS_RESOURCES; -+ } -+ -+ pPkt = (UINT8 *) prMsduInfoMgmt->prPacket; -+ prHdr = (WLAN_MAC_HEADER_T *) pPkt; -+ -+ /* 1. 802.11 header */ -+ prHdr->u2FrameCtrl = MAC_FRAME_ACTION; -+ prHdr->u2DurationID = 0; -+ kalMemCopy(prHdr->aucAddr1, pPeerMac, TDLS_FME_MAC_ADDR_LEN); -+ kalMemCopy(prHdr->aucAddr2, prBssInfo->aucOwnMacAddr, TDLS_FME_MAC_ADDR_LEN); -+ kalMemCopy(prHdr->aucAddr3, prBssInfo->aucBSSID, TDLS_FME_MAC_ADDR_LEN); -+ prHdr->u2SeqCtrl = 0; -+ LR_TDLS_FME_FIELD_FILL(sizeof(WLAN_MAC_HEADER_T)); -+ -+ /* Frame Formation - (1) Category */ -+ *pPkt = CATEGORY_PUBLIC_ACTION; -+ LR_TDLS_FME_FIELD_FILL(1); -+ } -+ -+ /* 3. Frame Formation - (2) Action */ -+ *pPkt = ucActionCode; -+ LR_TDLS_FME_FIELD_FILL(1); -+ -+ /* 3. Frame Formation - Status Code */ -+ switch (ucActionCode) { -+ case TDLS_FRM_ACTION_SETUP_RSP: -+ case TDLS_FRM_ACTION_CONFIRM: -+ case TDLS_FRM_ACTION_TEARDOWN: -+ WLAN_SET_FIELD_16(pPkt, u2StatusCode); -+ LR_TDLS_FME_FIELD_FILL(2); -+ break; -+ } -+ -+ /* 3. Frame Formation - (3) Dialog token */ -+ if (ucActionCode != TDLS_FRM_ACTION_TEARDOWN) { -+ *pPkt = ucDialogToken; -+ LR_TDLS_FME_FIELD_FILL(1); -+ } -+ -+ /* Fill elements */ -+ if (ucActionCode != TDLS_FRM_ACTION_TEARDOWN) { -+ /* -+ Capability -+ -+ Support Rates -+ Extended Support Rates -+ Supported Channels -+ HT Capabilities -+ WMM Information Element -+ -+ Extended Capabilities -+ Link Identifier -+ -+ RSNIE -+ FTIE -+ Timeout Interval -+ */ -+ if (ucActionCode != TDLS_FRM_ACTION_CONFIRM) { -+ /* 3. Frame Formation - (4) Capability: 0x31 0x04, privacy bit will be set */ -+ u2CapInfo = assocBuildCapabilityInfo(prAdapter, prStaRec); -+ WLAN_SET_FIELD_16(pPkt, u2CapInfo); -+ LR_TDLS_FME_FIELD_FILL(2); -+ -+ /* 4. Append general IEs */ -+ /* -+ TODO check HT: prAdapter->rWifiVar.rConnSettings.uc2G4BandwidthMode -+ must be CONFIG_BW_20_40M. -+ -+ TODO check HT: HT_CAP_INFO_40M_INTOLERANT must be clear if -+ Tdls 20/40 is enabled. -+ */ -+ u4IeLen = TdlsFrameGeneralIeAppend(prAdapter, prStaRec, u2StatusCode, pPkt); -+ LR_TDLS_FME_FIELD_FILL(u4IeLen); -+ -+ /* 5. Frame Formation - Extended capabilities element */ -+ EXT_CAP_IE(pPkt)->ucId = ELEM_ID_EXTENDED_CAP; -+ EXT_CAP_IE(pPkt)->ucLength = 5; -+ -+ EXT_CAP_IE(pPkt)->aucCapabilities[0] = 0x00; /* bit0 ~ bit7 */ -+ EXT_CAP_IE(pPkt)->aucCapabilities[1] = 0x00; /* bit8 ~ bit15 */ -+ EXT_CAP_IE(pPkt)->aucCapabilities[2] = 0x00; /* bit16 ~ bit23 */ -+ EXT_CAP_IE(pPkt)->aucCapabilities[3] = 0x00; /* bit24 ~ bit31 */ -+ EXT_CAP_IE(pPkt)->aucCapabilities[4] = 0x00; /* bit32 ~ bit39 */ -+ -+ /* if (prCmd->ucExCap & TDLS_EX_CAP_PEER_UAPSD) */ -+ EXT_CAP_IE(pPkt)->aucCapabilities[3] |= BIT((28 - 24)); -+ /* if (prCmd->ucExCap & TDLS_EX_CAP_CHAN_SWITCH) */ -+ EXT_CAP_IE(pPkt)->aucCapabilities[3] |= BIT((30 - 24)); -+ /* if (prCmd->ucExCap & TDLS_EX_CAP_TDLS) */ -+ EXT_CAP_IE(pPkt)->aucCapabilities[4] |= BIT((37 - 32)); -+ -+ u4IeLen = IE_SIZE(pPkt); -+ LR_TDLS_FME_FIELD_FILL(u4IeLen); -+ } else { -+ /* 5. Frame Formation - WMM Parameter element */ -+ if (prAdapter->rWifiVar.fgSupportQoS) { -+ u4IeLen = mqmGenerateWmmParamIEByParam(prAdapter, -+ prBssInfo, pPkt, OP_MODE_INFRASTRUCTURE); -+ -+ LR_TDLS_FME_FIELD_FILL(u4IeLen); -+ } -+ } -+ } -+ -+ /* 6. Frame Formation - 20/40 BSS Coexistence */ -+ /* -+ Follow WiFi test plan, add 20/40 element to request/response/confirm. -+ */ -+/* if (prGlueInfo->rTdlsLink.fgIs2040Sup == TRUE) */ /* force to enable */ -+ if (ucActionCode != TDLS_FRM_ACTION_TEARDOWN) { -+ /* -+ bit0 = 1: The Information Request field is used to indicate that a -+ transmitting STA is requesting the recipient to transmit a 20/40 BSS -+ Coexistence Management frame with the transmitting STA as the -+ recipient. -+ -+ bit1 = 0: The Forty MHz Intolerant field is set to 1 to prohibit an AP -+ that receives this information or reports of this information from -+ operating a 20/40 MHz BSS. -+ -+ bit2 = 0: The 20 MHz BSS Width Request field is set to 1 to prohibit -+ a receiving AP from operating its BSS as a 20/40 MHz BSS. -+ */ -+ BSS_20_40_COEXIST_IE(pPkt)->ucId = ELEM_ID_20_40_BSS_COEXISTENCE; -+ BSS_20_40_COEXIST_IE(pPkt)->ucLength = 1; -+ BSS_20_40_COEXIST_IE(pPkt)->ucData = 0x01; -+ LR_TDLS_FME_FIELD_FILL(3); -+ } -+ -+ /* 6. Frame Formation - HT Operation element */ -+/* u4IeLen = rlmFillHtOpIeBody(prBssInfo, pPkt); */ -+/* LR_TDLS_FME_FIELD_FILL(u4IeLen); */ -+ -+ /* 7. Frame Formation - Link identifier element */ -+ /* Note1: Link ID sequence must be correct; Or the calculated MIC will be error */ -+ /* -+ Note2: When we receive a setup request with link ID, Marvell will send setup response -+ to the peer in link ID, not the SA in the WLAN header. -+ */ -+ TDLS_LINK_IDENTIFIER_IE(pPkt)->ucId = ELEM_ID_LINK_IDENTIFIER; -+ TDLS_LINK_IDENTIFIER_IE(pPkt)->ucLength = ELEM_LEN_LINK_IDENTIFIER; -+ -+ kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aBSSID, prBssInfo->aucBSSID, 6); -+ -+ switch (ucActionCode) { -+ case TDLS_FRM_ACTION_SETUP_REQ: -+ case TDLS_FRM_ACTION_CONFIRM: -+ default: -+ /* we are initiator */ -+ pucInitiator = prBssInfo->aucOwnMacAddr; -+ pucResponder = pPeerMac; -+ -+ if (prStaRec != NULL) -+ prStaRec->flgTdlsIsInitiator = TRUE; -+ break; -+ -+ case TDLS_FRM_ACTION_SETUP_RSP: -+ case TDLS_FRM_ACTION_DISCOVERY_RESPONSE: -+ /* peer is initiator */ -+ pucInitiator = pPeerMac; -+ pucResponder = prBssInfo->aucOwnMacAddr; -+ -+ if (prStaRec != NULL) -+ prStaRec->flgTdlsIsInitiator = FALSE; -+ break; -+ -+ case TDLS_FRM_ACTION_TEARDOWN: -+ if (prStaRec != NULL) { -+ if (prStaRec->flgTdlsIsInitiator == TRUE) { -+ /* we are initiator */ -+ pucInitiator = prBssInfo->aucOwnMacAddr; -+ pucResponder = pPeerMac; -+ } else { -+ /* peer is initiator */ -+ pucInitiator = pPeerMac; -+ pucResponder = prBssInfo->aucOwnMacAddr; -+ } -+ } else { -+ /* peer is initiator */ -+ pucInitiator = pPeerMac; -+ pucResponder = prBssInfo->aucOwnMacAddr; -+ } -+ break; -+ } -+ -+ kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aInitiator, pucInitiator, 6); -+ kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aResponder, pucResponder, 6); -+ -+ u4IeLen = IE_SIZE(pPkt); -+ LR_TDLS_FME_FIELD_FILL(u4IeLen); -+ -+ /* 8. Append security IEs */ -+ /* -+ 11.21.5 TDLS Direct Link Teardown -+ If the STA has security enabled on the link 37 with the AP, then the FTIE shall be -+ included in the TDLS Teardown frame. -+ -+ For ralink station, it can accept our tear down without FTIE but marvell station. -+ */ -+/* if ((ucActionCode != TDLS_FRM_ACTION_TEARDOWN) && (pAppendIe != NULL)) */ -+ if (pAppendIe != NULL) { -+ if ((ucActionCode != TDLS_FRM_ACTION_TEARDOWN) || -+ ((ucActionCode == TDLS_FRM_ACTION_TEARDOWN) && -+ (prStaRec != NULL) && (prStaRec->fgTdlsInSecurityMode == TRUE))) { -+ kalMemCopy(pPkt, pAppendIe, AppendIeLen); -+ LR_TDLS_FME_FIELD_FILL(AppendIeLen); -+ } -+ } -+ -+ /* 7. Append Supported Operating Classes IE */ -+ if (ucActionCode != TDLS_FRM_ACTION_TEARDOWN) { -+ /* Note: if we do not put the IE, Marvell STA will decline our TDLS setup request */ -+ u4IeLen = rlmDomainSupOperatingClassIeFill(pPkt); -+ LR_TDLS_FME_FIELD_FILL(u4IeLen); -+ } -+ -+ /* 11. send the data or management frame */ -+ if (ucActionCode != TDLS_FRM_ACTION_DISCOVERY_RESPONSE) { -+#if 0 -+ /* -+ Note1: remember to modify our MAC & AP MAC & peer MAC in LINK ID -+ Note2: dialog token in rsp & confirm must be same as sender. -+ */ -+ -+#if 1 -+ /* example for Ralink's and Broadcom's TDLS setup request frame in open/none */ -+ if (ucActionCode == TDLS_FRM_ACTION_SETUP_REQ) { -+#if 0 -+ /* mediatek */ -+ char buffer[] = { 0x31, 0x04, -+ 0x01, 0x08, 0x02, 0x04, 0x0b, 0x16, 0xc, 0x12, 0x18, 0x24, -+ 0x32, 0x04, 0x30, 0x48, 0x60, 0x6c, -+ 0x24, 0x0a, 0x01, 0x0b, 0x24, 0x04, 0x34, 0x04, 0x95, 0x04, 0xa5, 0x01, -+ 0x2d, 0x1a, 0x72, 0x11, 0x03, 0xff, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, -+ 0xdd, 0x07, 0x00, 0x50, 0xf2, 0x02, 0x00, 0x01, 0x0f, -+ 0x7f, 0x05, 0x00, 0x00, 0x00, 0x50, 0x20, -+ 0x48, 0x01, 0x01, -+ 0x65, 0x12, 0x00, 0x0c, 0x43, 0x31, 0x35, 0x97, 0x00, 0x11, 0x22, 0x33, -+ 0x44, 0x05, 0x00, 0x22, 0x58, 0x00, 0xcc, 0x0f, -+ 0x3b, 0x0d, 0x0c, 0x01, 0x02, 0x03, 0x05, 0x16, 0x17, 0x19, -+ 0x1b, 0x1c, 0x1e, 0x20, 0x21, -+ 0x07, 0x06, 0x55, 0x53, 0x20, 0x01, 0x0b, 0x1e -+ }; -+#endif -+ -+#if 1 -+ /* ralink *//* from capability */ -+ char buffer[] = { 0x21, 0x04, -+ 0x01, 0x08, 0x82, 0x84, 0x8b, 0x96, 0x12, 0x24, 0x48, 0x6c, -+ 0x07, 0x06, 0x55, 0x53, 0x20, 0xdd, 0x20, 0x00, -+ 0x32, 0x04, 0x0c, 0x18, 0x30, 0x60, -+ 0x24, 0x06, 0x01, 0x0b, 0x24, 0x08, 0x95, 0x04, -+ 0x7f, 0x05, 0x01, 0x00, 0x00, 0x50, 0x20, -+ 0x3b, 0x10, 0x20, 0x01, 0x02, 0x03, 0x04, 0x0c, 0x16, 0x17, 0x18, 0x19, -+ 0x1b, 0x1c, 0x1d, 0x1e, 0x20, 0x21, -+ 0x2d, 0x1a, 0x6e, 0x00, 0x17, 0xff, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, -+ 0x00, 0x00, 0x00, 0x00, -+ 0x48, 0x01, 0x01, -+ 0x65, 0x12, 0x00, 0x0c, 0x43, 0x44, 0x0b, 0x1a, 0x00, 0x11, 0x22, 0x33, -+ 0x44, 0x05, 0x00, 0x22, 0x58, 0x00, 0xcc, 0x0f, -+ 0xdd, 0x07, 0x00, 0x50, 0xf2, 0x02, 0x00, 0x01, 0x0f -+ }; -+#endif -+#if 0 -+ /* 6630 */ -+ char buffer[] = { 0x01, 0x01, -+ 0x01, 0x04, 0x02, 0x04, 0x0b, 0x16, -+ 0x24, 0x02, 0x01, 0x0d, -+ 0x7f, 0x05, 0x00, 0x00, 0x00, 0x50, 0xff, -+ 0x2d, 0x1a, 0x61, 0x01, 0x03, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, -+ 0x38, 0x05, 0x02, 0xc0, 0xa8, 0x00, 0x00, -+ 0x48, 0x01, 0x01, -+ 0x3b, 0x0d, 0x0c, 0x01, 0x02, 0x03, 0x05, 0x16, 0x17, 0x19, -+ 0x1b, 0x1c, 0x1d, 0x1e, 0x20, 0x21, -+ 0x07, 0x06, 0x55, 0x53, 0x20, 0x01, 0x0b, 0x1e, -+ 0x65, 0x12, 0x00, 0x0c, 0x43, 0x44, 0x0b, 0x1a, 0x00, 0x11, 0x22, 0x33, -+ 0x44, 0x05, 0x00, 0x22, 0x58, 0x00, 0xcc, 0x0f, -+ 0xdd, 0x18, 0x00, 0x50, 0xf2, 0x02, 0x01, 0x01, 0x80, 0x01, 0x00, 0x00, -+ 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x60, -+ 0x00, 0x00, 0x00, -+ 0xbf, 0x0c, 0x30, 0x01, 0x80, 0x03, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, -+ 0x00, 0x00 -+ }; -+#endif -+ -+ pPktTemp += 18; -+ memcpy(pPktTemp, buffer, sizeof(buffer)); -+ u4PktLen = 18 + sizeof(buffer); -+ } -+#endif -+ -+#if 1 -+ if (ucActionCode == TDLS_FRM_ACTION_CONFIRM) { -+ /* Note: dialog token must be same as request */ -+#if 1 -+ /* ralink */ -+ char buffer[] = { 0x00, -+ 0x01, 0x2d, 0x1a, 0x6e, 0x00, 0x17, 0xff, 0x00, 0x00, 0x00, -+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x65, 0x12, 0x00, 0x0c, 0x43, 0x44, 0x0b, 0x1a, 0x00, 0x11, 0x22, 0x33, -+ 0x44, 0x05, 0x00, 0x22, 0x58, 0x00, 0xcc, 0x0f, -+ 0xdd, 0x18, 0x00, 0x50, 0xf2, 0x02, 0x01, 0x01, 0x0f, 0x00, 0x03, -+ 0xa4, 0x00, 0x00, 0x27, 0xa4, 0x00, 0x00, 0x42, 0x43, 0x5e, 0x00, -+ 0x62, 0x32, 0x2f, 0x00 -+ }; -+#endif -+ -+#if 0 -+ /* 6630 */ -+ char buffer[] = { 0x00, -+ 0x01, -+ 0x38, 0x05, 0x02, 0xc0, 0xa8, 0x00, 0x00, -+ 0x48, 0x01, 0x01, -+ 0x3b, 0x0d, 0x0c, 0x01, 0x02, 0x03, 0x05, 0x16, 0x17, 0x19, -+ 0x1b, 0x1c, 0x1d, 0x1e, 0x20, 0x21, -+ 0x07, 0x06, 0x55, 0x53, 0x20, 0x01, 0x0b, 0x1e, -+ 0x65, 0x12, 0x00, 0x0c, 0x43, 0x44, 0x0b, 0x1a, 0x00, 0x11, 0x22, 0x33, -+ 0x44, 0x05, 0x00, 0x22, 0x58, 0x00, 0xcc, 0x0f, -+ 0xdd, 0x07, 0x00, 0x50, 0xf2, 0x02, 0x00, 0x01, 0x00, -+ 0xdd, 0x18, 0x00, 0x50, 0xf2, 0x02, 0x01, 0x01, 0x80, 0x3f, 0x00, 0x00, -+ 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x60, -+ 0x00, 0x00, 0x00 -+ }; -+#endif -+ -+#if 0 -+ /* A/D die */ -+ char buffer[] = { 0x00, -+ 0x01, -+ 0xdd, 0x18, 0x00, 0x50, 0xf2, 0x02, 0x01, 0x01, 0x0f, 0x6b, 0x00, 0x00, -+ 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x60, -+ 0x00, 0x00, 0x00 0x65, 0x12, 0x00, 0x0c, 0x43, 0x31, 0x35, 0x97, 0x00, 0x11, 0x22, 0x33, -+ 0x44, 0x05, 0x00, 0x22, 0x58, 0x00, 0xcc, 0x0f, -+ 0x38, 0x0d, 0x0c, 0x01, 0x02, 0x03, 0x05, 0x16, 0x17, 0x19, 0x1b, -+ 0x1c, 0x1e, 0x20, 0x21, -+ 0x07, 0x06, 0x55, 0x53, 0x20, 0x01, 0x0b, 0x1e -+ }; -+#endif -+ -+ pPktTemp += 18; -+ memcpy(pPktTemp, buffer, sizeof(buffer)); -+ u4PktLen = 18 + sizeof(buffer); -+ } -+#endif -+ -+#else -+ -+#if 0 -+ /* for test in open/none */ -+ if (ucActionCode == TDLS_FRM_ACTION_SETUP_REQ) { -+ char buffer[] = { 0x01, 0x04, -+ 0x01, 0x08, 0x82, 0x84, 0x8b, 0x96, 0x12, 0x24, 0x48, 0x6c, -+ 0x07, 0x06, 0x55, 0x53, 0x20, 0xdd, 0x20, 0x00, -+ 0x32, 0x04, 0x30, 0x48, 0x60, 0x6c, -+ 0x24, 0x0a, 0x01, 0x0b, 0x24, 0x04, 0x34, 0x04, 0x95, 0x04, 0xa5, 0x01, -+ 0x2d, 0x1a, 0x72, 0x11, 0x03, 0xff, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, -+ 0xdd, 0x07, 0x00, 0x50, 0xf2, 0x02, 0x00, 0x01, 0x0f, -+ 0x7f, 0x05, 0x00, 0x00, 0x00, 0x50, 0x20, -+ 0x48, 0x01, 0x01, -+ 0x65, 0x12, 0x00, 0x0c, 0x43, 0x44, 0x0b, 0x1a, 0x00, 0x11, 0x22, 0x33, -+ 0x44, 0x05, 0x00, 0x22, 0x58, 0x00, 0xcc, 0x0f, -+ 0x3b, 0x0d, 0x0c, 0x01, 0x02, 0x03, 0x05, 0x16, 0x17, 0x19, -+ 0x1b, 0x1c, 0x1e, 0x20, 0x21 -+ }; -+ -+ pPktTemp += 18; -+ memcpy(pPktTemp, buffer, sizeof(buffer)); -+ u4PktLen = 18 + sizeof(buffer); -+ } -+#endif -+#endif /* 0 */ -+ -+ /* 9. Update packet length */ -+ prMsduInfo->len = u4PktLen; -+ dumpMemory8(prMsduInfo->data, u4PktLen); -+ -+ wlanHardStartXmit(prMsduInfo, prMsduInfo->dev); -+ } else { -+ /* -+ A TDLS capable STA that receives a TDLS Discovery Request frame is required to -+ send the response "to the requesting STA, via the direct path." -+ However, prior to establishment of the direct link, the responding STA may not -+ know the rate capabilities of the requesting STA. In this case, the responding -+ STA shall send the TDLS Discovery Response frame using a rate from the -+ BSSBasicRateSet of the BSS to which the STA is currently associated. -+ */ -+ prMsduInfoMgmt->ucPacketType = HIF_TX_PACKET_TYPE_MGMT; -+ prMsduInfoMgmt->ucStaRecIndex = prBssInfo->prStaRecOfAP->ucIndex; -+ prMsduInfoMgmt->ucNetworkType = prBssInfo->ucNetTypeIndex; -+ prMsduInfoMgmt->ucMacHeaderLength = WLAN_MAC_MGMT_HEADER_LEN; -+ prMsduInfoMgmt->fgIs802_1x = FALSE; -+ prMsduInfoMgmt->fgIs802_11 = TRUE; -+ prMsduInfoMgmt->u2FrameLength = u4PktLen; -+ prMsduInfoMgmt->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter); -+ prMsduInfoMgmt->pfTxDoneHandler = NULL; -+ prMsduInfoMgmt->fgIsBasicRate = TRUE; /* use basic rate */ -+ -+ /* Send them to HW queue */ -+ nicTxEnqueueMsdu(prAdapter, prMsduInfoMgmt); -+ } -+ -+ return TDLS_STATUS_SUCCESS; -+} -+ -+#endif /* CFG_SUPPORT_TDLS */ -+ -+ /* End of tdls_com.c */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/wapi.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/wapi.c -new file mode 100644 -index 000000000000..af66ef95d17c ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/wapi.c -@@ -0,0 +1,491 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/wapi.c#1 -+*/ -+ -+/*! \file "wapi.c" -+ \brief This file including the WAPI related function. -+ -+ This file provided the macros and functions library support the wapi ie parsing, -+ cipher and AKM check to help the AP seleced deciding. -+*/ -+ -+/* -+** Log: wapi.c -+** -+** 10 24 2012 wh.su -+** [ALPS00376392] [klocwork 9.1] in wapi.c, line 344 -+** Use MAX_NUM_SUPPORTED_WAPI_AKM_SUITESfor avoid Klocwork warning. -+** -+** 10 24 2012 wh.su -+** [ALPS00376391] [klocwork 9.1] in wapi.c, line 311 -+** Use the MAX_NUM_SUPPORTED_WAPI_CIPHER_SUITES for avoid Klccwork waring. -+ * -+ * 11 10 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * change the debug module level. -+ * -+ * 10 20 2010 wh.su -+ * [WCXRP00000067] [MT6620 Wi-Fi][Driver] Support the android+ WAPI function -+ * fixed the network type -+ * -+ * 09 01 2010 wh.su -+ * NULL -+ * adding the wapi support for integration test. -+ * -+ * 07 20 2010 wh.su -+ * -+ * . -+ * -+ * 04 06 2010 wh.su -+ * [BORA00000680][MT6620] Support the statistic for Micxxsoft os query -+ * fixed the firmware return the broadcast frame at wrong tc. -+ * -+ * 03 03 2010 wh.su -+ * [BORA00000637][MT6620 Wi-Fi] [Bug] WPA2 pre-authentication timer not correctly initialize -+ * move the AIS specific variable for security to AIS specific structure. -+ * -+ * 12 18 2009 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * . -+ * -+ * Dec 8 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * adding the function to check and update the default wapi tx -+ * -+ * Dec 7 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * adding the generate wapi ie function, and replace the tabe by space -+ * -+ * Nov 23 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+#include "precomp.h" -+#if CFG_SUPPORT_WAPI -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* -+* \brief This routine is called to generate WPA IE for -+* associate request frame. -+* -+* \param[in] prCurrentBss The Selected BSS description -+* -+* \retval The append WPA IE length -+* -+* \note -+* Called by: AIS module, Associate request -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID wapiGenerateWAPIIE(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo) -+{ -+ PUINT_8 pucBuffer; -+ -+ ASSERT(prAdapter); -+ ASSERT(prMsduInfo); -+ -+ if (prMsduInfo->ucNetworkType != NETWORK_TYPE_AIS_INDEX) -+ return; -+ -+ pucBuffer = (PUINT_8) ((ULONG) prMsduInfo->prPacket + prMsduInfo->u2FrameLength); -+ -+ /* ASSOC INFO IE ID: 68 :0x44 */ -+ if (/* prWlanInfo->fgWapiMode && */ prAdapter->prGlueInfo->u2WapiAssocInfoIESz) { -+ kalMemCopy(pucBuffer, &prAdapter->prGlueInfo->aucWapiAssocInfoIEs, -+ prAdapter->prGlueInfo->u2WapiAssocInfoIESz); -+ prMsduInfo->u2FrameLength += prAdapter->prGlueInfo->u2WapiAssocInfoIESz; -+ } -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to parse WAPI IE. -+* -+* \param[in] prInfoElem Pointer to the RSN IE -+* \param[out] prRsnInfo Pointer to the BSSDescription structure to store the -+** WAPI information from the given WAPI IE -+* -+* \retval TRUE - Succeeded -+* \retval FALSE - Failed -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN wapiParseWapiIE(IN P_WAPI_INFO_ELEM_T prInfoElem, OUT P_WAPI_INFO_T prWapiInfo) -+{ -+ UINT_32 i; -+ INT_32 u4RemainWapiIeLen; -+ UINT_16 u2Version; -+ UINT_16 u2Cap = 0; -+ UINT_32 u4GroupSuite = WAPI_CIPHER_SUITE_WPI; -+ UINT_16 u2PairSuiteCount = 0; -+ UINT_16 u2AuthSuiteCount = 0; -+ PUCHAR pucPairSuite = NULL; -+ PUCHAR pucAuthSuite = NULL; -+ PUCHAR cp; -+ -+ DEBUGFUNC("wapiParseWapiIE"); -+ -+ ASSERT(prInfoElem); -+ ASSERT(prWapiInfo); -+ -+ /* Verify the length of the WAPI IE. */ -+ if (prInfoElem->ucLength < 6) { -+ DBGLOG(SEC, TRACE, "WAPI IE length too short (length=%d)\n", prInfoElem->ucLength); -+ return FALSE; -+ } -+ -+ /* Check WAPI version: currently, we only support version 1. */ -+ WLAN_GET_FIELD_16(&prInfoElem->u2Version, &u2Version); -+ if (u2Version != 1) { -+ DBGLOG(SEC, TRACE, "Unsupported WAPI IE version: %d\n", u2Version); -+ return FALSE; -+ } -+ -+ cp = (PUCHAR) &prInfoElem->u2AuthKeyMgtSuiteCount; -+ u4RemainWapiIeLen = (INT_32) prInfoElem->ucLength - 2; -+ -+ do { -+ if (u4RemainWapiIeLen == 0) -+ break; -+ -+ /* -+ AuthCount : 2 -+ AuthSuite : 4 * authSuiteCount -+ PairwiseCount: 2 -+ PairwiseSuite: 4 * pairSuiteCount -+ GroupSuite : 4 -+ Cap : 2 */ -+ -+ /* Parse the Authentication and Key Management Cipher Suite Count -+ field. */ -+ if (u4RemainWapiIeLen < 2) { -+ DBGLOG(SEC, TRACE, "Fail to parse WAPI IE in auth & key mgt suite count (IE len: %d)\n", -+ prInfoElem->ucLength); -+ return FALSE; -+ } -+ -+ WLAN_GET_FIELD_16(cp, &u2AuthSuiteCount); -+ cp += 2; -+ u4RemainWapiIeLen -= 2; -+ -+ /* Parse the Authentication and Key Management Cipher Suite List -+ field. */ -+ i = (UINT_32) u2AuthSuiteCount * 4; -+ if (u4RemainWapiIeLen < (INT_32) i) { -+ DBGLOG(SEC, TRACE, "Fail to parse WAPI IE in auth & key mgt suite list (IE len: %d)\n", -+ prInfoElem->ucLength); -+ return FALSE; -+ } -+ -+ pucAuthSuite = cp; -+ -+ cp += i; -+ u4RemainWapiIeLen -= (INT_32) i; -+ -+ if (u4RemainWapiIeLen == 0) -+ break; -+ -+ /* Parse the Pairwise Key Cipher Suite Count field. */ -+ if (u4RemainWapiIeLen < 2) { -+ DBGLOG(SEC, TRACE, "Fail to parse WAPI IE in pairwise cipher suite count (IE len: %d)\n", -+ prInfoElem->ucLength); -+ return FALSE; -+ } -+ -+ WLAN_GET_FIELD_16(cp, &u2PairSuiteCount); -+ cp += 2; -+ u4RemainWapiIeLen -= 2; -+ -+ /* Parse the Pairwise Key Cipher Suite List field. */ -+ i = (UINT_32) u2PairSuiteCount * 4; -+ if (u4RemainWapiIeLen < (INT_32) i) { -+ DBGLOG(SEC, TRACE, "Fail to parse WAPI IE in pairwise cipher suite list (IE len: %d)\n", -+ prInfoElem->ucLength); -+ return FALSE; -+ } -+ -+ pucPairSuite = cp; -+ -+ cp += i; -+ u4RemainWapiIeLen -= (INT_32) i; -+ -+ /* Parse the Group Key Cipher Suite field. */ -+ if (u4RemainWapiIeLen < 4) { -+ DBGLOG(SEC, TRACE, "Fail to parse WAPI IE in group cipher suite (IE len: %d)\n", -+ prInfoElem->ucLength); -+ return FALSE; -+ } -+ -+ WLAN_GET_FIELD_32(cp, &u4GroupSuite); -+ cp += 4; -+ u4RemainWapiIeLen -= 4; -+ -+ /* Parse the WAPI u2Capabilities field. */ -+ if (u4RemainWapiIeLen < 2) { -+ DBGLOG(SEC, TRACE, "Fail to parse WAPI IE in WAPI capabilities (IE len: %d)\n", -+ prInfoElem->ucLength); -+ return FALSE; -+ } -+ -+ WLAN_GET_FIELD_16(cp, &u2Cap); -+ u4RemainWapiIeLen -= 2; -+ -+ /* Todo:: BKID support */ -+ } while (FALSE); -+ -+ /* Save the WAPI information for the BSS. */ -+ -+ prWapiInfo->ucElemId = ELEM_ID_WAPI; -+ -+ prWapiInfo->u2Version = u2Version; -+ -+ prWapiInfo->u4GroupKeyCipherSuite = u4GroupSuite; -+ -+ DBGLOG(SEC, LOUD, "WAPI: version %d, group key cipher suite %02x-%02x-%02x-%02x\n", -+ u2Version, (UCHAR) (u4GroupSuite & 0x000000FF), -+ (UCHAR) ((u4GroupSuite >> 8) & 0x000000FF), -+ (UCHAR) ((u4GroupSuite >> 16) & 0x000000FF), (UCHAR) ((u4GroupSuite >> 24) & 0x000000FF)); -+ -+ if (pucPairSuite) { -+ /* The information about the pairwise key cipher suites is present. */ -+ if (u2PairSuiteCount > MAX_NUM_SUPPORTED_WAPI_CIPHER_SUITES) -+ u2PairSuiteCount = MAX_NUM_SUPPORTED_WAPI_CIPHER_SUITES; -+ -+ prWapiInfo->u4PairwiseKeyCipherSuiteCount = (UINT_32) u2PairSuiteCount; -+ -+ for (i = 0; i < (UINT_32) u2PairSuiteCount; i++) { -+ WLAN_GET_FIELD_32(pucPairSuite, &prWapiInfo->au4PairwiseKeyCipherSuite[i]); -+ pucPairSuite += 4; -+ -+ DBGLOG(SEC, LOUD, "WAPI: pairwise key cipher suite [%d]: %02x-%02x-%02x-%02x\n", -+ (UINT_8) i, (UCHAR) (prWapiInfo->au4PairwiseKeyCipherSuite[i] & 0x000000FF), -+ (UCHAR) ((prWapiInfo->au4PairwiseKeyCipherSuite[i] >> 8) & 0x000000FF), -+ (UCHAR) ((prWapiInfo->au4PairwiseKeyCipherSuite[i] >> 16) & 0x000000FF), -+ (UCHAR) ((prWapiInfo->au4PairwiseKeyCipherSuite[i] >> 24) & 0x000000FF)); -+ } -+ } else { -+ /* The information about the pairwise key cipher suites is not present. -+ Use the default chipher suite for WAPI: WPI. */ -+ prWapiInfo->u4PairwiseKeyCipherSuiteCount = 1; -+ prWapiInfo->au4PairwiseKeyCipherSuite[0] = WAPI_CIPHER_SUITE_WPI; -+ -+ DBGLOG(SEC, LOUD, "WAPI: pairwise key cipher suite: %02x-%02x-%02x-%02x (default)\n", -+ (UCHAR) (prWapiInfo->au4PairwiseKeyCipherSuite[0] & 0x000000FF), -+ (UCHAR) ((prWapiInfo->au4PairwiseKeyCipherSuite[0] >> 8) & 0x000000FF), -+ (UCHAR) ((prWapiInfo->au4PairwiseKeyCipherSuite[0] >> 16) & 0x000000FF), -+ (UCHAR) ((prWapiInfo->au4PairwiseKeyCipherSuite[0] >> 24) & 0x000000FF)); -+ } -+ -+ if (pucAuthSuite) { -+ /* The information about the authentication and key management suites -+ is present. */ -+ if (u2AuthSuiteCount > MAX_NUM_SUPPORTED_WAPI_AKM_SUITES) -+ u2AuthSuiteCount = MAX_NUM_SUPPORTED_WAPI_AKM_SUITES; -+ -+ prWapiInfo->u4AuthKeyMgtSuiteCount = (UINT_32) u2AuthSuiteCount; -+ -+ for (i = 0; i < (UINT_32) u2AuthSuiteCount; i++) { -+ WLAN_GET_FIELD_32(pucAuthSuite, &prWapiInfo->au4AuthKeyMgtSuite[i]); -+ pucAuthSuite += 4; -+ -+ DBGLOG(SEC, LOUD, "WAPI: AKM suite [%d]: %02x-%02x-%02x-%02x\n", -+ (UINT_8) i, (UCHAR) (prWapiInfo->au4AuthKeyMgtSuite[i] & 0x000000FF), -+ (UCHAR) ((prWapiInfo->au4AuthKeyMgtSuite[i] >> 8) & 0x000000FF), -+ (UCHAR) ((prWapiInfo->au4AuthKeyMgtSuite[i] >> 16) & 0x000000FF), -+ (UCHAR) ((prWapiInfo->au4AuthKeyMgtSuite[i] >> 24) & 0x000000FF)); -+ } -+ } else { -+ /* The information about the authentication and key management suites -+ is not present. Use the default AKM suite for WAPI. */ -+ prWapiInfo->u4AuthKeyMgtSuiteCount = 1; -+ prWapiInfo->au4AuthKeyMgtSuite[0] = WAPI_AKM_SUITE_802_1X; -+ -+ DBGLOG(SEC, LOUD, "WAPI: AKM suite: %02x-%02x-%02x-%02x (default)\n", -+ (UCHAR) (prWapiInfo->au4AuthKeyMgtSuite[0] & 0x000000FF), -+ (UCHAR) ((prWapiInfo->au4AuthKeyMgtSuite[0] >> 8) & 0x000000FF), -+ (UCHAR) ((prWapiInfo->au4AuthKeyMgtSuite[0] >> 16) & 0x000000FF), -+ (UCHAR) ((prWapiInfo->au4AuthKeyMgtSuite[0] >> 24) & 0x000000FF)); -+ } -+ -+ prWapiInfo->u2WapiCap = u2Cap; -+ DBGLOG(SEC, LOUD, "WAPI: cap: 0x%04x\n", prWapiInfo->u2WapiCap); -+ -+ return TRUE; -+} /* wapiParseWapiIE */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to perform WAPI policy selection for a given BSS. -+* -+* \param[in] prAdapter Pointer to the adapter object data area. -+* \param[in] prBss Pointer to the BSS description -+* -+* \retval TRUE - The WAPI policy selection for the given BSS is -+* successful. The selected pairwise and group cipher suites -+* are returned in the BSS description. -+* \retval FALSE - The WAPI policy selection for the given BSS is failed. -+* The driver shall not attempt to join the given BSS. -+* -+* \note The Encrypt status matched score will save to bss for final ap select. -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN wapiPerformPolicySelection(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBss) -+{ -+ UINT_32 i; -+ UINT_32 u4PairwiseCipher = 0; -+ UINT_32 u4GroupCipher = 0; -+ UINT_32 u4AkmSuite = 0; -+ P_WAPI_INFO_T prBssWapiInfo; -+ P_WLAN_INFO_T prWlanInfo; -+ -+ DEBUGFUNC("wapiPerformPolicySelection"); -+ -+ ASSERT(prBss); -+ -+ /* Notice!!!! WAPI AP not set the privacy bit for WAI and WAI-PSK at WZC configuration mode */ -+ prWlanInfo = &prAdapter->rWlanInfo; -+ -+ if (prBss->fgIEWAPI) { -+ prBssWapiInfo = &prBss->rIEWAPI; -+ } else { -+ if (prAdapter->rWifiVar.rConnSettings.fgWapiMode == FALSE) { -+ DBGLOG(SEC, TRACE, "-- No Protected BSS\n"); -+ return TRUE; -+ } -+ DBGLOG(SEC, TRACE, "WAPI Information Element does not exist.\n"); -+ return FALSE; -+ } -+ -+ /* Select pairwise/group ciphers */ -+ for (i = 0; i < prBssWapiInfo->u4PairwiseKeyCipherSuiteCount; i++) { -+ if (prBssWapiInfo->au4PairwiseKeyCipherSuite[i] == -+ prAdapter->rWifiVar.rConnSettings.u4WapiSelectedPairwiseCipher) { -+ u4PairwiseCipher = prBssWapiInfo->au4PairwiseKeyCipherSuite[i]; -+ } -+ } -+ if (prBssWapiInfo->u4GroupKeyCipherSuite == prAdapter->rWifiVar.rConnSettings.u4WapiSelectedGroupCipher) -+ u4GroupCipher = prBssWapiInfo->u4GroupKeyCipherSuite; -+ -+ /* Exception handler */ -+ /* If we cannot find proper pairwise and group cipher suites to join the -+ BSS, do not check the supported AKM suites. */ -+ if (u4PairwiseCipher == 0 || u4GroupCipher == 0) { -+ DBGLOG(SEC, TRACE, "Failed to select pairwise/group cipher (0x%08x/0x%08x)\n", -+ u4PairwiseCipher, u4GroupCipher); -+ return FALSE; -+ } -+ -+ /* Select AKM */ -+ /* If the driver cannot support any authentication suites advertised in -+ the given BSS, we fail to perform RSNA policy selection. */ -+ /* Attempt to find any overlapping supported AKM suite. */ -+ for (i = 0; i < prBssWapiInfo->u4AuthKeyMgtSuiteCount; i++) { -+ if (prBssWapiInfo->au4AuthKeyMgtSuite[i] == prAdapter->rWifiVar.rConnSettings.u4WapiSelectedAKMSuite) { -+ u4AkmSuite = prBssWapiInfo->au4AuthKeyMgtSuite[i]; -+ break; -+ } -+ } -+ -+ if (u4AkmSuite == 0) { -+ DBGLOG(SEC, TRACE, "Cannot support any AKM suites\n"); -+ return FALSE; -+ } -+ -+ DBGLOG(SEC, TRACE, "Selected pairwise/group cipher: %02x-%02x-%02x-%02x/%02x-%02x-%02x-%02x\n", -+ (UINT_8) (u4PairwiseCipher & 0x000000FF), -+ (UINT_8) ((u4PairwiseCipher >> 8) & 0x000000FF), -+ (UINT_8) ((u4PairwiseCipher >> 16) & 0x000000FF), -+ (UINT_8) ((u4PairwiseCipher >> 24) & 0x000000FF), -+ (UINT_8) (u4GroupCipher & 0x000000FF), -+ (UINT_8) ((u4GroupCipher >> 8) & 0x000000FF), -+ (UINT_8) ((u4GroupCipher >> 16) & 0x000000FF), -+ (UINT_8) ((u4GroupCipher >> 24) & 0x000000FF)); -+ -+ DBGLOG(SEC, TRACE, "Selected AKM suite: %02x-%02x-%02x-%02x\n", -+ (UINT_8) (u4AkmSuite & 0x000000FF), -+ (UINT_8) ((u4AkmSuite >> 8) & 0x000000FF), -+ (UINT_8) ((u4AkmSuite >> 16) & 0x000000FF), (UINT_8) ((u4AkmSuite >> 24) & 0x000000FF)); -+ -+ return TRUE; -+} /* wapiPerformPolicySelection */ -+ -+#if 0 -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is use for wapi mode, to update the current wpi tx idx ? 0 :1 . -+* -+* \param[in] prStaRec Pointer to the Sta record -+* \param[out] ucWlanIdx The Rx status->wlanidx field -+* -+* \retval TRUE - Succeeded -+* \retval FALSE - Failed -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN wapiUpdateTxKeyIdx(IN P_STA_RECORD_T prStaRec, IN UINT_8 ucWlanIdx) -+{ -+ UINT_8 ucKeyId; -+ -+ if ((ucWlanIdx & BITS(0, 3)) == CIPHER_SUITE_WPI) { -+ -+ ucKeyId = ((ucWlanIdx & BITS(4, 5)) >> 4); -+ -+ if (ucKeyId != g_prWifiVar->rAisSpecificBssInfo.ucWpiActivedPWKey) { -+ DBGLOG(RSN, STATE, -+ "Change wapi key index from %d->%d\n", -+ g_prWifiVar->rAisSpecificBssInfo.ucWpiActivedPWKey, ucKeyId); -+ g_prWifiVar->rAisSpecificBssInfo.ucWpiActivedPWKey = ucKeyId; -+ -+ prStaRec->ucWTEntry = -+ (ucKeyId == -+ WTBL_AIS_BSSID_WAPI_IDX_0) ? WTBL_AIS_BSSID_WAPI_IDX_0 : WTBL_AIS_BSSID_WAPI_IDX_1; -+ } -+ } -+} -+#endif -+#endif -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/wnm.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/wnm.c -new file mode 100644 -index 000000000000..f54d22941148 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/wnm.c -@@ -0,0 +1,301 @@ -+/* -+** Id: //Department/DaVinci/TRUNK/MT6620_5931_WiFi_Driver/mgmt/wnm.c#1 -+*/ -+ -+/*! \file "wnm.c" -+ \brief This file includes the 802.11v default vale and functions. -+*/ -+ -+/* -+** Log: wnm.c -+ * -+ * 01 05 2012 tsaiyuan.hsu -+ * [WCXRP00001157] [MT6620 Wi-Fi][FW][DRV] add timing measurement support for 802.11v -+ * add timing measurement support for 802.11v. -+ * -+ * -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "precomp.h" -+ -+#if CFG_SUPPORT_802_11V -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+#define WNM_MAX_TOD_ERROR 0 -+#define WNM_MAX_TOA_ERROR 0 -+#define MICRO_TO_10NANO(x) ((x)*100) -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+static UINT_8 ucTimingMeasToken; -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* -+* \brief This routine is called to process the 802.11v wnm category action frame. -+* -+* -+* \note -+* Called by: Handle Rx mgmt request -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID wnmWNMAction(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb) -+{ -+ P_WLAN_ACTION_FRAME prRxFrame; -+ -+ ASSERT(prAdapter); -+ ASSERT(prSwRfb); -+ -+ prRxFrame = (P_WLAN_ACTION_FRAME) prSwRfb->pvHeader; -+ -+#if CFG_SUPPORT_802_11V_TIMING_MEASUREMENT -+ if (prRxFrame->ucAction == ACTION_WNM_TIMING_MEASUREMENT_REQUEST) { -+ wnmTimingMeasRequest(prAdapter, prSwRfb); -+ return; -+ } -+#endif -+ -+ DBGLOG(WNM, TRACE, "Unsupport WNM action frame: %d\n", prRxFrame->ucAction); -+} -+ -+#if CFG_SUPPORT_802_11V_TIMING_MEASUREMENT -+/*----------------------------------------------------------------------------*/ -+/*! -+* -+* \brief This routine is called to report timing measurement data. -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID wnmReportTimingMeas(IN P_ADAPTER_T prAdapter, IN UINT_8 ucStaRecIndex, IN UINT_32 u4ToD, IN UINT_32 u4ToA) -+{ -+ P_STA_RECORD_T prStaRec; -+ -+ prStaRec = cnmGetStaRecByIndex(prAdapter, ucStaRecIndex); -+ -+ if ((!prStaRec) || (!prStaRec->fgIsInUse)) -+ return; -+ -+ DBGLOG(WNM, TRACE, "wnmReportTimingMeas: u4ToD %x u4ToA %x", u4ToD, u4ToA); -+ -+ if (!prStaRec->rWNMTimingMsmt.ucTrigger) -+ return; -+ -+ prStaRec->rWNMTimingMsmt.u4ToD = MICRO_TO_10NANO(u4ToD); -+ prStaRec->rWNMTimingMsmt.u4ToA = MICRO_TO_10NANO(u4ToA); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will handle TxDone(TimingMeasurement) Event. -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* @param[in] prMsduInfo Pointer to the MSDU_INFO_T. -+* @param[in] rTxDoneStatus Return TX status of the Timing Measurement frame. -+* -+* @retval WLAN_STATUS_SUCCESS -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wnmRunEventTimgingMeasTxDone(IN P_ADAPTER_T prAdapter, -+ IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus) -+{ -+ P_STA_RECORD_T prStaRec; -+ -+ ASSERT(prAdapter); -+ ASSERT(prMsduInfo); -+ -+ DBGLOG(WNM, LOUD, "EVENT-TX DONE: Current Time = %u\n", kalGetTimeTick()); -+ -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); -+ -+ if ((!prStaRec) || (!prStaRec->fgIsInUse)) -+ return WLAN_STATUS_SUCCESS; /* For the case of replying ERROR STATUS CODE */ -+ -+ DBGLOG(WNM, TRACE, "wnmRunEventTimgingMeasTxDone: ucDialog %d ucFollowUp %d u4ToD %x u4ToA %x", -+ prStaRec->rWNMTimingMsmt.ucDialogToken, -+ prStaRec->rWNMTimingMsmt.ucFollowUpDialogToken, -+ prStaRec->rWNMTimingMsmt.u4ToD, prStaRec->rWNMTimingMsmt.u4ToA); -+ -+ prStaRec->rWNMTimingMsmt.ucFollowUpDialogToken = prStaRec->rWNMTimingMsmt.ucDialogToken; -+ prStaRec->rWNMTimingMsmt.ucDialogToken = ++ucTimingMeasToken; -+ -+ wnmComposeTimingMeasFrame(prAdapter, prStaRec, NULL); -+ -+ return WLAN_STATUS_SUCCESS; -+ -+} /* end of wnmRunEventTimgingMeasTxDone() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will compose the Timing Measurement frame. -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* @param[in] prStaRec Pointer to the STA_RECORD_T. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+wnmComposeTimingMeasFrame(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN PFN_TX_DONE_HANDLER pfTxDoneHandler) -+{ -+ P_MSDU_INFO_T prMsduInfo; -+ P_BSS_INFO_T prBssInfo; -+ P_ACTION_UNPROTECTED_WNM_TIMING_MEAS_FRAME prTxFrame; -+ UINT_16 u2PayloadLen; -+ -+ prBssInfo = &prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]; -+ ASSERT(prBssInfo); -+ -+ prMsduInfo = (P_MSDU_INFO_T) cnmMgtPktAlloc(prAdapter, MAC_TX_RESERVED_FIELD + PUBLIC_ACTION_MAX_LEN); -+ -+ if (!prMsduInfo) -+ return; -+ -+ prTxFrame = (P_ACTION_UNPROTECTED_WNM_TIMING_MEAS_FRAME) -+ ((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD); -+ -+ prTxFrame->u2FrameCtrl = MAC_FRAME_ACTION; -+ -+ COPY_MAC_ADDR(prTxFrame->aucDestAddr, prStaRec->aucMacAddr); -+ COPY_MAC_ADDR(prTxFrame->aucSrcAddr, prBssInfo->aucOwnMacAddr); -+ COPY_MAC_ADDR(prTxFrame->aucBSSID, prBssInfo->aucBSSID); -+ -+ prTxFrame->ucCategory = CATEGORY_UNPROTECTED_WNM_ACTION; -+ prTxFrame->ucAction = ACTION_UNPROTECTED_WNM_TIMING_MEASUREMENT; -+ -+ /* 3 Compose the frame body's frame. */ -+ prTxFrame->ucDialogToken = prStaRec->rWNMTimingMsmt.ucDialogToken; -+ prTxFrame->ucFollowUpDialogToken = prStaRec->rWNMTimingMsmt.ucFollowUpDialogToken; -+ prTxFrame->u4ToD = prStaRec->rWNMTimingMsmt.u4ToD; -+ prTxFrame->u4ToA = prStaRec->rWNMTimingMsmt.u4ToA; -+ prTxFrame->ucMaxToDErr = WNM_MAX_TOD_ERROR; -+ prTxFrame->ucMaxToAErr = WNM_MAX_TOA_ERROR; -+ -+ u2PayloadLen = 2 + ACTION_UNPROTECTED_WNM_TIMING_MEAS_LEN; -+ -+ /* 4 Update information of MSDU_INFO_T */ -+ prMsduInfo->ucPacketType = HIF_TX_PACKET_TYPE_MGMT; /* Management frame */ -+ prMsduInfo->ucStaRecIndex = prStaRec->ucIndex; -+ prMsduInfo->ucNetworkType = prStaRec->ucNetTypeIndex; -+ prMsduInfo->ucMacHeaderLength = WLAN_MAC_MGMT_HEADER_LEN; -+ prMsduInfo->fgIs802_1x = FALSE; -+ prMsduInfo->fgIs802_11 = TRUE; -+ prMsduInfo->u2FrameLength = WLAN_MAC_MGMT_HEADER_LEN + u2PayloadLen; -+ prMsduInfo->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter); -+ prMsduInfo->pfTxDoneHandler = pfTxDoneHandler; -+ prMsduInfo->fgIsBasicRate = FALSE; -+ -+ DBGLOG(WNM, TRACE, "wnmComposeTimingMeasFrame: ucDialogToken %d ucFollowUpDialogToken %d u4ToD %x u4ToA %x\n", -+ prTxFrame->ucDialogToken, prTxFrame->ucFollowUpDialogToken, -+ prTxFrame->u4ToD, prTxFrame->u4ToA); -+ -+ /* 4 Enqueue the frame to send this action frame. */ -+ nicTxEnqueueMsdu(prAdapter, prMsduInfo); -+ -+ return; -+ -+} /* end of wnmComposeTimingMeasFrame() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* -+* \brief This routine is called to process the 802.11v timing measurement request. -+* -+* -+* \note -+* Handle Rx mgmt request -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID wnmTimingMeasRequest(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb) -+{ -+ P_ACTION_WNM_TIMING_MEAS_REQ_FRAME prRxFrame = NULL; -+ P_STA_RECORD_T prStaRec; -+ -+ prRxFrame = (P_ACTION_WNM_TIMING_MEAS_REQ_FRAME) prSwRfb->pvHeader; -+ if (!prRxFrame) -+ return; -+ -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); -+ if ((!prStaRec) || (!prStaRec->fgIsInUse)) -+ return; -+ -+ DBGLOG(WNM, TRACE, "IEEE 802.11: Received Timing Measuremen Request from %pM\n" -+ prStaRec->aucMacAdd); -+ -+ /* reset timing msmt */ -+ prStaRec->rWNMTimingMsmt.fgInitiator = TRUE; -+ prStaRec->rWNMTimingMsmt.ucTrigger = prRxFrame->ucTrigger; -+ if (!prRxFrame->ucTrigger) -+ return; -+ -+ prStaRec->rWNMTimingMsmt.ucDialogToken = ++ucTimingMeasToken; -+ prStaRec->rWNMTimingMsmt.ucFollowUpDialogToken = 0; -+ -+ wnmComposeTimingMeasFrame(prAdapter, prStaRec, wnmRunEventTimgingMeasTxDone); -+} -+ -+#if WNM_UNIT_TEST -+VOID wnmTimingMeasUnitTest1(P_ADAPTER_T prAdapter, UINT_8 ucStaRecIndex) -+{ -+ P_STA_RECORD_T prStaRec; -+ -+ prStaRec = cnmGetStaRecByIndex(prAdapter, ucStaRecIndex); -+ if ((!prStaRec) || (!prStaRec->fgIsInUse)) -+ return; -+ -+ DBGLOG(WNM, INFO, "IEEE 802.11v: Test Timing Measuremen Request from %pM\n", -+ prStaRec->aucMacAddr); -+ -+ prStaRec->rWNMTimingMsmt.fgInitiator = TRUE; -+ prStaRec->rWNMTimingMsmt.ucTrigger = 1; -+ -+ prStaRec->rWNMTimingMsmt.ucDialogToken = ++ucTimingMeasToken; -+ prStaRec->rWNMTimingMsmt.ucFollowUpDialogToken = 0; -+ -+ wnmComposeTimingMeasFrame(prAdapter, prStaRec, wnmRunEventTimgingMeasTxDone); -+} -+#endif -+ -+#endif /* CFG_SUPPORT_802_11V_TIMING_MEASUREMENT */ -+ -+#endif /* CFG_SUPPORT_802_11V */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/nic/cmd_buf.c b/drivers/misc/mediatek/connectivity/wlan/gen2/nic/cmd_buf.c -new file mode 100644 -index 000000000000..6f1bb6fd771e ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/nic/cmd_buf.c -@@ -0,0 +1,254 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/nic/cmd_buf.c#1 -+*/ -+ -+/*! \file "cmd_buf.c" -+ \brief This file contain the management function of internal Command Buffer -+ for CMD_INFO_T. -+ -+ We'll convert the OID into Command Packet and then send to FW. Thus we need -+ to copy the OID information to Command Buffer for following reasons. -+ 1. The data structure of OID information may not equal to the data structure of -+ Command, we cannot use the OID buffer directly. -+ 2. If the Command was not generated by driver we also need a place to store the -+ information. -+ 3. Because the CMD is NOT FIFO when doing memory allocation (CMD will be generated -+ from OID or interrupt handler), thus we'll use the Block style of Memory Allocation -+ here. -+*/ -+ -+/* -+** Log: cmd_buf.c -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 18 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Provide cnmMgtPktAlloc() and alloc/free function of msg/buf -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 02 03 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1. clear prPendingCmdInfo properly -+ * * 2. while allocating memory for cmdinfo, no need to add extra 4 bytes. -+** \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-10-13 21:59:08 GMT mtk01084 -+** remove un-neceasary spaces -+** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-05-20 12:24:26 GMT mtk01461 -+** Increase CMD Buffer - HIF_RX_HW_APPENDED_LEN when doing CMD_INFO_T allocation -+** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-04-21 09:41:08 GMT mtk01461 -+** Add init of Driver Domain MCR flag and fix lint MTK WARN -+** \main\maintrunk.MT6620WiFiDriver_Prj\1 2009-04-17 19:51:45 GMT mtk01461 -+** allocation function of CMD_INFO_T -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "precomp.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+static BOOLEAN fgCmdDumpIsDone = FALSE; -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is used to initial the MGMT memory pool for CMD Packet. -+* -+* @param prAdapter Pointer to the Adapter structure. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID cmdBufInitialize(IN P_ADAPTER_T prAdapter) -+{ -+ P_CMD_INFO_T prCmdInfo; -+ UINT_32 i; -+ -+ ASSERT(prAdapter); -+ -+ QUEUE_INITIALIZE(&prAdapter->rFreeCmdList); -+ -+ for (i = 0; i < CFG_TX_MAX_CMD_PKT_NUM; i++) { -+ prCmdInfo = &prAdapter->arHifCmdDesc[i]; -+ QUEUE_INSERT_TAIL(&prAdapter->rFreeCmdList, &prCmdInfo->rQueEntry); -+ } -+ fgCmdDumpIsDone = FALSE; -+} /* end of cmdBufInitialize() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief dump CMD queue and print to trace, for debug use only -+* @param[in] prQueue Pointer to the command Queue to be dumped -+* @param[in] quename Name of the queue -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID cmdBufDumpCmdQueue(P_QUE_T prQueue, CHAR *queName) -+{ -+ P_CMD_INFO_T prCmdInfo = (P_CMD_INFO_T)QUEUE_GET_HEAD(prQueue); -+ -+ DBGLOG(NIC, INFO, "Dump CMD info for %s, Elem number:%u\n", queName, prQueue->u4NumElem); -+ while (prCmdInfo) { -+ P_CMD_INFO_T prCmdInfo1, prCmdInfo2, prCmdInfo3; -+ -+ prCmdInfo1 = (P_CMD_INFO_T)QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T)prCmdInfo); -+ if (!prCmdInfo1) { -+ DBGLOG(NIC, INFO, "CID:%d SEQ:%d\n", prCmdInfo->ucCID, prCmdInfo->ucCmdSeqNum); -+ break; -+ } -+ prCmdInfo2 = (P_CMD_INFO_T)QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T)prCmdInfo1); -+ if (!prCmdInfo2) { -+ DBGLOG(NIC, INFO, "CID:%d, SEQ:%d; CID:%d, SEQ:%d\n", prCmdInfo->ucCID, -+ prCmdInfo->ucCmdSeqNum, prCmdInfo1->ucCID, prCmdInfo1->ucCmdSeqNum); -+ break; -+ } -+ prCmdInfo3 = (P_CMD_INFO_T)QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T)prCmdInfo2); -+ if (!prCmdInfo3) { -+ DBGLOG(NIC, INFO, "CID:%d, SEQ:%d; CID:%d, SEQ:%d; CID:%d, SEQ:%d\n", prCmdInfo->ucCID, -+ prCmdInfo->ucCmdSeqNum, prCmdInfo1->ucCID, prCmdInfo1->ucCmdSeqNum, -+ prCmdInfo2->ucCID, prCmdInfo2->ucCmdSeqNum); -+ break; -+ } -+ DBGLOG(NIC, INFO, "CID:%d, SEQ:%d; CID:%d, SEQ:%d; CID:%d, SEQ:%d; CID:%d, SEQ:%d\n", -+ prCmdInfo->ucCID, prCmdInfo->ucCmdSeqNum, prCmdInfo1->ucCID, -+ prCmdInfo1->ucCmdSeqNum, prCmdInfo2->ucCID, prCmdInfo2->ucCmdSeqNum, -+ prCmdInfo3->ucCID, prCmdInfo3->ucCmdSeqNum); -+ prCmdInfo = (P_CMD_INFO_T)QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T)prCmdInfo3); -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Allocate CMD_INFO_T from a free list and MGMT memory pool. -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* @param[in] u4Length Length of the frame buffer to allocate. -+* -+* @retval NULL Pointer to the valid CMD Packet handler -+* @retval !NULL Fail to allocat CMD Packet -+*/ -+/*----------------------------------------------------------------------------*/ -+P_CMD_INFO_T cmdBufAllocateCmdInfo(IN P_ADAPTER_T prAdapter, IN UINT_32 u4Length) -+{ -+ P_CMD_INFO_T prCmdInfo; -+ -+ KAL_SPIN_LOCK_DECLARATION(); -+ -+ DEBUGFUNC("cmdBufAllocateCmdInfo"); -+ -+ ASSERT(prAdapter); -+ -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_RESOURCE); -+ QUEUE_REMOVE_HEAD(&prAdapter->rFreeCmdList, prCmdInfo, P_CMD_INFO_T); -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_RESOURCE); -+ -+ if (prCmdInfo) { -+ /* Setup initial value in CMD_INFO_T */ -+ /* Start address of allocated memory */ -+ prCmdInfo->pucInfoBuffer = cnmMemAlloc(prAdapter, RAM_TYPE_BUF, u4Length); -+ -+ if (prCmdInfo->pucInfoBuffer == NULL) { -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_RESOURCE); -+ QUEUE_INSERT_TAIL(&prAdapter->rFreeCmdList, &prCmdInfo->rQueEntry); -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_RESOURCE); -+ -+ prCmdInfo = NULL; -+ -+ DBGLOG(NIC, ERROR, "Allocate prCmdInfo->pucInfoBuffer fail!\n"); -+ } else { -+ prCmdInfo->u2InfoBufLen = 0; -+ prCmdInfo->fgIsOid = FALSE; -+ prCmdInfo->fgDriverDomainMCR = FALSE; -+ } -+ fgCmdDumpIsDone = FALSE; -+ } else if (!fgCmdDumpIsDone) { -+ P_GLUE_INFO_T prGlueInfo = prAdapter->prGlueInfo; -+ P_QUE_T prCmdQue = &prGlueInfo->rCmdQueue; -+ P_QUE_T prPendingCmdQue = &prAdapter->rPendingCmdQueue; -+ P_TX_TCQ_STATUS_T prTc = &prAdapter->rTxCtrl.rTc; -+ -+ fgCmdDumpIsDone = TRUE; -+ cmdBufDumpCmdQueue(prCmdQue, "waiting Tx CMD queue"); -+ cmdBufDumpCmdQueue(prPendingCmdQue, "waiting response CMD queue"); -+ DBGLOG(NIC, INFO, "Tc4 number:%d\n", prTc->aucFreeBufferCount[TC4_INDEX]); -+ if (prTc->aucFreeBufferCount[TC4_INDEX] != 0) -+ glDoChipReset(); -+ } -+ -+ return prCmdInfo; -+ -+} /* end of cmdBufAllocateCmdInfo() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is used to free the CMD Packet to the MGMT memory pool. -+* -+* @param prAdapter Pointer to the Adapter structure. -+* @param prCmdInfo CMD Packet handler -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID cmdBufFreeCmdInfo(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo) -+{ -+ KAL_SPIN_LOCK_DECLARATION(); -+ -+ DEBUGFUNC("cmdBufFreeCmdInfo"); -+ -+ ASSERT(prAdapter); -+ ASSERT(prCmdInfo); -+ -+ if (prCmdInfo) { -+ if (prCmdInfo->pucInfoBuffer) { -+ cnmMemFree(prAdapter, prCmdInfo->pucInfoBuffer); -+ prCmdInfo->pucInfoBuffer = NULL; -+ } -+ -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_RESOURCE); -+ QUEUE_INSERT_TAIL(&prAdapter->rFreeCmdList, &prCmdInfo->rQueEntry); -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_RESOURCE); -+ } -+ -+ return; -+ -+} /* end of cmdBufFreeCmdPacket() */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic.c b/drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic.c -new file mode 100644 -index 000000000000..dfaaedd118bf ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic.c -@@ -0,0 +1,4062 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/nic/nic.c#2 -+*/ -+ -+/*! \file nic.c -+ \brief Functions that provide operation in NIC's (Network Interface Card) point of view. -+ -+ This file includes functions which unite multiple hal(Hardware) operations -+ and also take the responsibility of Software Resource Management in order -+ to keep the synchronization with Hardware Manipulation. -+*/ -+ -+/* -+** Log: nic.c -+ * -+ * 07 17 2012 yuche.tsai -+ * NULL -+ * Compile no error before trial run. -+ * -+ * 05 02 2012 terry.wu -+ * NULL -+ * Set the default value of AP StaRec index to "STA_REC_INDEX_NOT_FOUND" in update firmware bss command. -+ * -+ * 03 02 2012 terry.wu -+ * NULL -+ * Sync CFG80211 modification from branch 2,2. -+ * -+ * 11 28 2011 cp.wu -+ * [WCXRP00001125] [MT6620 Wi-Fi][Firmware] Strengthen Wi-Fi power off sequence to have a clearroom environment when -+ * returining to ROM code -+ * 1. Due to firmware now stops HIF DMA for powering off, do not try to receive any packet from firmware -+ * 2. Take use of prAdapter->fgIsEnterD3ReqIssued for tracking whether it is powering off or not -+ * -+ * 11 22 2011 tsaiyuan.hsu -+ * [WCXRP00001083] [MT6620 Wi-Fi][DRV]] dump debug counter or frames when debugging is triggered -+ * keep debug counter setting after wake up. -+ * -+ * 11 19 2011 yuche.tsai -+ * NULL -+ * Update RSSI for P2P. -+ * -+ * 11 18 2011 yuche.tsai -+ * NULL -+ * CONFIG P2P support RSSI query, default turned off. -+ * -+ * 11 07 2011 tsaiyuan.hsu -+ * [WCXRP00001083] [MT6620 Wi-Fi][DRV]] dump debug counter or frames when debugging is triggered -+ * add debug counters and periodically dump counters for debugging. -+ * -+ * 11 04 2011 cp.wu -+ * [WCXRP00001079] [MT5931][Driver] Release pending MMPDU only when BSS is being deactivated -+ * pre-check for NULL before calling MMPDU free function -+ * -+ * 11 03 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * change the DBGLOG for "\n" and "\r\n". LABEL to LOUD for XLOG -+ * -+ * 11 01 2011 chinglan.wang -+ * NULL -+ * Modify the Wi-Fi method of the flush TX queue when disconnect the AP. -+ * If disconnect the AP and flush all the data frame in the TX queue, WPS cannot do the 4-way handshake to connect to -+ * the AP.. -+ * -+ * 10 11 2011 terry.wu -+ * NULL -+ * Rewrite Assert Dump Function for Portability. -+ * -+ * 09 20 2011 cm.chang -+ * [WCXRP00000997] [MT6620 Wi-Fi][Driver][FW] Handle change of BSS preamble type and slot time -+ * New CMD definition about RLM parameters -+ * -+ * 08 15 2011 cp.wu -+ * [WCXRP00000851] [MT6628 Wi-Fi][Driver] Add HIFSYS related definition to driver source tree -+ * reuse firmware download logic of MT6620 for MT6628. -+ * -+ * 08 03 2011 terry.wu -+ * [WCXRP00000899] [MT6620] [FW] Reply probe rsp in FW for hotspot mode -+ * Reply Probe Rsp in FW for Hotspot Mode. -+ * -+ * -+ * -+ * 08 03 2011 terry.wu -+ * [WCXRP00000899] [MT6620] [FW] Reply probe rsp in FW for hotspot mode -+ * Reply Probe Rsp in FW for Hotspot Mode. -+ * -+ * -+ * 08 03 2011 terry.wu -+ * [WCXRP00000899] [MT6620] [FW] Reply probe rsp in FW for hotspot mode -+ * Reply Probe Rsp in FW for Hotspot Mode. -+ * -+ * 08 03 2011 terry.wu -+ * [WCXRP00000899] [MT6620] [FW] Reply probe rsp in FW for hotspot mode -+ * Reply Probe Rsp in FW for Hotspot Mode. -+ * -+ * 08 02 2011 yuche.tsai -+ * [WCXRP00000896] [Volunteer Patch][WiFi Direct][Driver] GO with multiple client, TX deauth to a disconnecting device -+ * issue. -+ * Fix GO send deauth frame issue. -+ * -+ * 07 18 2011 chinghwa.yu -+ * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm -+ * Add CMD/Event for RDD and BWCS. -+ * -+ * 07 11 2011 wh.su -+ * [WCXRP00000849] [MT6620 Wi-Fi][Driver] Remove some of the WAPI define for make sure the value is initialize, for -+ * customer not enable WAPI -+ * For make sure wapi initial value is set. -+ * -+ * 06 27 2011 cp.wu -+ * [WCXRP00000815] [MT6620 Wi-Fi][Driver] allow single BSSID with multiple SSID settings to work around some tricky -+ * AP which use space character as hidden SSID -+ * 1. correct logic -+ * 2. replace only BSS-DESC which doesn't have a valid SSID. -+ * -+ * 06 27 2011 cp.wu -+ * [WCXRP00000815] [MT6620 Wi-Fi][Driver] allow single BSSID with multiple SSID settings to work around some tricky -+ * AP which use space character as hidden SSID -+ * allow to have a single BSSID with multiple SSID to be presented in scanning result -+ * -+ * 05 12 2011 puff.wen -+ * NULL -+ * FW Assert information dump to driver -+ * -+ * 04 18 2011 terry.wu -+ * [WCXRP00000660] [MT6620 Wi-Fi][Driver] Remove flag CFG_WIFI_DIRECT_MOVED -+ * Remove flag CFG_WIFI_DIRECT_MOVED. -+ * -+ * 04 15 2011 cp.wu -+ * [WCXRP00000651] [MT6620 Wi-Fi][Driver] Refine RSSI buffering mechanism -+ * ROLLBACK due to the special design is to workaround incorrect initial RCPI value coming from firmware domain. -+ * -+ * 04 14 2011 cm.chang -+ * [WCXRP00000634] [MT6620 Wi-Fi][Driver][FW] 2nd BSS will not support 40MHz bandwidth for concurrency -+ * . -+ * -+ * 04 14 2011 cp.wu -+ * [WCXRP00000598] [MT6620 Wi-Fi][Driver] Implementation of interface for communicating with user space process for -+ * RESET_START and RESET_END events -+ * 1. add code to put whole-chip resetting trigger when abnormal firmware assertion is detected -+ * 2. add dummy function for both Win32 and Linux part. -+ * -+ * 04 12 2011 cp.wu -+ * [WCXRP00000635] [MT6620 Wi-Fi][Driver] Clear pending security frames when QM clear pending data frames for -+ * dedicated network type -+ * clear pending security frames for dedicated network type when BSS is being deactivated/disconnected -+ * -+ * 04 12 2011 wh.su -+ * NULL -+ * enable the p2p check the cipher to set the bssInfo auth mode. -+ * -+ * 04 12 2011 wh.su -+ * NULL -+ * prepare the code for sync the auth mode and encryption status for P2P and BOW. -+ * -+ * 04 11 2011 yuche.tsai -+ * [WCXRP00000627] [Volunteer Patch][MT6620][Driver] Pending MMPUD of P2P Network may crash system issue. -+ * Fix kernel panic issue when MMPDU of P2P is pending in driver. -+ * -+ * 04 10 2011 george.huang -+ * [WCXRP00000621] [MT6620 Wi-Fi][Driver] Support P2P supplicant to set power mode -+ * Fix compiler issue. -+ * -+ * 04 08 2011 george.huang -+ * [WCXRP00000621] [MT6620 Wi-Fi][Driver] Support P2P supplicant to set power mode -+ * separate settings of P2P and AIS -+ * -+ * 04 08 2011 eddie.chen -+ * [WCXRP00000617] [MT6620 Wi-Fi][DRV/FW] Fix for sigma -+ * Fix for sigma -+ * -+ * 04 07 2011 cp.wu -+ * [WCXRP00000616] [MT6620 Wi-Fi][Driver] Free memory to pool and kernel in case any unexpected failure happend inside -+ * wlanAdapterStart -+ * . -+ * -+ * 04 07 2011 cp.wu -+ * [WCXRP00000616] [MT6620 Wi-Fi][Driver] Free memory to pool and kernel in case any unexpected failure happend inside -+ * wlanAdapterStart -+ * implementation of internal error handling of nicAllocateAdapterMemory. -+ * -+ * 03 31 2011 chinglan.wang -+ * [WCXRP00000613] [MT6620 Wi-Fi] [FW] [Driver] BssInfo can get the security mode which is WPA/WPA2/WAPI or not. -+ * . -+ * -+ * 03 21 2011 cp.wu -+ * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer -+ * portability improvement -+ * -+ * 03 17 2011 cp.wu -+ * [WCXRP00000562] [MT6620 Wi-Fi][Driver] I/O buffer pre-allocation to avoid physically continuous memory shortage -+ * after system running for a long period -+ * use pre-allocated buffer for storing enhanced interrupt response as well -+ * -+ * 03 16 2011 cp.wu -+ * [WCXRP00000562] [MT6620 Wi-Fi][Driver] I/O buffer pre-allocation to avoid physically continuous memory shortage -+ * after system running for a long period -+ * 1. pre-allocate physical continuous buffer while module is being loaded -+ * 2. use pre-allocated physical continuous buffer for TX/RX DMA transfer -+ * -+ * The windows part remained the same as before, but added similar APIs to hide the difference. -+ * -+ * 03 15 2011 cp.wu -+ * [WCXRP00000559] [MT6620 Wi-Fi][Driver] Combine TX/RX DMA buffers into a single one to reduce physically continuous -+ * memory consumption -+ * 1. deprecate CFG_HANDLE_IST_IN_SDIO_CALLBACK -+ * 2. Use common coalescing buffer for both TX/RX directions -+ * -+ * -+ * 03 10 2011 cm.chang -+ * [WCXRP00000358] [MT6620 Wi-Fi][Driver] Provide concurrent information for each module -+ * Add some functions to let AIS/Tethering or AIS/BOW be the same channel -+ * -+ * 03 07 2011 terry.wu -+ * [WCXRP00000521] [MT6620 Wi-Fi][Driver] Remove non-standard debug message -+ * Toggle non-standard debug messages to comments. -+ * -+ * 03 02 2011 cp.wu -+ * [WCXRP00000503] [MT6620 Wi-Fi][Driver] Take RCPI brought by association response as initial RSSI right after -+ * connection is built. -+ * use RCPI brought by ASSOC-RESP after connection is built as initial RCPI to avoid using a uninitialized MAC-RX RCPI. -+ * -+ * 02 08 2011 terry.wu -+ * [WCXRP00000412] [MT6620 Wi-Fi][FW/Driver] Dump firmware assert info at android kernel log -+ * Use kalPrint to print firmware assert info. -+ * -+ * 02 01 2011 terry.wu -+ * [WCXRP00000412] [MT6620 Wi-Fi][FW/Driver] Dump firmware assert info at android kernel log -+ * . -+ * -+ * 02 01 2011 cm.chang -+ * [WCXRP00000415] [MT6620 Wi-Fi][Driver] Check if any memory leakage happens when uninitializing in DGB mode -+ * . -+ * -+ * 01 31 2011 terry.wu -+ * [WCXRP00000412] [MT6620 Wi-Fi][FW/Driver] Dump firmware assert info at android kernel log -+ * Print firmware ASSERT info at Android kernel log, driver side -+ * -+ * 01 27 2011 tsaiyuan.hsu -+ * [WCXRP00000392] [MT6620 Wi-Fi][Driver] Add Roaming Support -+ * add roaming fsm -+ * 1. not support 11r, only use strength of signal to determine roaming. -+ * 2. not enable CFG_SUPPORT_ROAMING until completion of full test. -+ * 3. in 6620, adopt work-around to avoid sign extension problem of cck of hw -+ * 4. assume that change of link quality in smooth way. -+ * -+ * 01 26 2011 cm.chang -+ * [WCXRP00000395] [MT6620 Wi-Fi][Driver][FW] Search STA_REC with additional net type index argument -+ * Allocate system RAM if fixed message or mgmt buffer is not available -+ * -+ * 01 24 2011 cp.wu -+ * [WCXRP00000382] [MT6620 Wi-Fi][Driver] Track forwarding packet number with notifying tx thread for serving -+ * 1. add an extra counter for tracking pending forward frames. -+ * 2. notify TX service thread as well when there is pending forward frame -+ * 3. correct build errors leaded by introduction of Wi-Fi direct separation module -+ * -+ * 01 19 2011 cp.wu -+ * [WCXRP00000372] [MT6620 Wi-Fi][Driver] Check bus access failure inside nicProcessIST() -+ * check bus error and/or card removal when retrieving interrupt status from HAL -+ * -+ * 01 04 2011 cp.wu -+ * [WCXRP00000338] [MT6620 Wi-Fi][Driver] Separate kalMemAlloc into kmalloc and vmalloc implementations to ease -+ * physically continuous memory demands -+ * 1) correct typo in scan.c -+ * 2) TX descriptors, RX descriptos and management buffer should use virtually continuous buffer instead of -+ * physically contineous one -+ * -+ * 01 04 2011 cp.wu -+ * [WCXRP00000338] [MT6620 Wi-Fi][Driver] Separate kalMemAlloc into kmalloc and vmalloc implementations to ease -+ * physically continuous memory demands -+ * separate kalMemAlloc() into virtually-continuous and physically-continuous type to ease slab system pressure -+ * -+ * 12 30 2010 cp.wu -+ * [WCXRP00000327] [MT6620 Wi-Fi][Driver] Improve HEC WHQA 6972 workaround coverage in driver side -+ * host driver not to set FW-own when there is still pending interrupts -+ * -+ * 12 17 2010 cp.wu -+ * [WCXRP00000270] [MT6620 Wi-Fi][Driver] Clear issues after concurrent networking support has been merged -+ * before BSS disconnection is indicated to firmware, all correlated peer should be cleared and freed -+ * -+ * 12 07 2010 cm.chang -+ * [WCXRP00000239] MT6620 Wi-Fi][Driver][FW] Merge concurrent branch back to maintrunk -+ * 1. BSSINFO include RLM parameter -+ * 2. free all sta records when network is disconnected -+ * -+ * 12 02 2010 eddie.chen -+ * [WCXRP00000218] [MT6620 Wi-Fi][Driver] Add auto rate window control in registry -+ * Add more control value but dont use it now. -+ * -+ * 11 30 2010 eddie.chen -+ * [WCXRP00000218] [MT6620 Wi-Fi][Driver] Add auto rate window control in registry -+ * Add auto rate check window in registry -+ * -+ * 11 10 2010 eddie.chen -+ * [WCXRP00000156] [MT6620][FW] Change Auto rate window to 64 and add throughput swcr -+ * Use autorate parameter 1 as phy rate mask. -+ * -+ * 11 08 2010 cp.wu -+ * [WCXRP00000166] [MT6620 Wi-Fi][Driver] use SDIO CMD52 for enabling/disabling interrupt to reduce transaction period -+ * change to use CMD52 for enabling/disabling interrupt to reduce SDIO transaction time -+ * -+ * 10 26 2010 eddie.chen -+ * [WCXRP00000134] [MT6620 Wi-Fi][Driver] Add a registry to enable auto rate for SQA test by using E1 EVB -+ * Add auto rate parameter in registry. -+ * -+ * 10 18 2010 cp.wu -+ * [WCXRP00000053] [MT6620 Wi-Fi][Driver] Reset incomplete and might leads to -+ * BSOD when entering RF test with AIS associated -+ * 1. remove redundant variables in STA_REC structure -+ * 2. add STA-REC uninitialization routine for clearing pending events -+ * -+ * 10 18 2010 cp.wu -+ * [WCXRP00000103] [MT6620 Wi-Fi][Driver] Driver crashed when using WZC to connect to AP#B with connection with AP#A -+ * reset ptrs when IEs are going to be dropped -+ * -+ * 10 12 2010 cp.wu -+ * [WCXRP00000084] [MT6620 Wi-Fi][Driver][FW] Add fixed rate support for distance test -+ * add HT (802.11n) fixed rate support. -+ * -+ * 10 08 2010 cp.wu -+ * [WCXRP00000084] [MT6620 Wi-Fi][Driver][FW] Add fixed rate support for distance test -+ * adding fixed rate support for distance test. (from registry setting) -+ * -+ * 10 07 2010 cp.wu -+ * [WCXRP00000083] [MT5931][Driver][FW] Add necessary logic for MT5931 first connection -+ * add firmware download for MT5931. -+ * -+ * 10 05 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check -+ * load manufacture data when CFG_SUPPORT_NVRAM is set to 1 -+ * -+ * 10 04 2010 cp.wu -+ * [WCXRP00000077] [MT6620 Wi-Fi][Driver][FW] Eliminate use of ENUM_NETWORK_TYPE_T and replaced by -+ * ENUM_NETWORK_TYPE_INDEX_T only remove ENUM_NETWORK_TYPE_T definitions -+ * -+ * 09 21 2010 cp.wu -+ * [WCXRP00000053] [MT6620 Wi-Fi][Driver] Reset incomplete and might leads to BSOD when entering RF test -+ * with AIS associated -+ * Do a complete reset with STA-REC null checking for RF test re-entry -+ * -+ * 09 08 2010 cp.wu -+ * NULL -+ * use static memory pool for storing IEs of scanning result. -+ * -+ * 09 06 2010 cp.wu -+ * NULL -+ * Androi/Linux: return current operating channel information -+ * -+ * 09 01 2010 cp.wu -+ * NULL -+ * HIFSYS Clock Source Workaround -+ * -+ * 08 26 2010 yuche.tsai -+ * NULL -+ * Fix someones coding error while enable WIFI_DIRECT. -+ * -+ * 08 25 2010 george.huang -+ * NULL -+ * update OID/ registry control path for PM related settings -+ * -+ * 08 24 2010 cm.chang -+ * NULL -+ * Support RLM initail channel of Ad-hoc, P2P and BOW -+ * -+ * 08 24 2010 chinghwa.yu -+ * NULL -+ * Update BOW for the 1st time. -+ * -+ * 08 23 2010 chinghwa.yu -+ * NULL -+ * Update for BOW. -+ * -+ * 08 20 2010 yuche.tsai -+ * NULL -+ * Add state change indication. -+ * -+ * 08 16 2010 yuche.tsai -+ * NULL -+ * Add support for P2P BSS update info. -+ * -+ * 08 12 2010 cp.wu -+ * NULL -+ * [removing debugging] not to dump beacon content. -+ * -+ * 08 12 2010 cp.wu -+ * NULL -+ * [AIS-FSM] honor registry setting for adhoc running mode. (A/B/G) -+ * -+ * 08 11 2010 cp.wu -+ * NULL -+ * 1) do not use in-stack variable for beacon updating. (for MAUI porting) -+ * 2) extending scanning result to 64 instead of 48 -+ * -+ * 08 04 2010 yarco.yang -+ * NULL -+ * Add TX_AMPDU and ADDBA_REJECT command -+ * -+ * 08 03 2010 cp.wu -+ * NULL -+ * surpress compilation warning. -+ * -+ * 08 03 2010 cp.wu -+ * NULL -+ * Centralize mgmt/system service procedures into independent calls. -+ * -+ * 07 28 2010 cp.wu -+ * NULL -+ * 1) eliminate redundant variable eOPMode in prAdapter->rWlanInfo -+ * 2) change nicMediaStateChange() API prototype -+ * -+ * 07 28 2010 cp.wu -+ * NULL -+ * sync. CMD_BSS_INFO structure change to CMD-EVENT v0.15. -+ * -+ * 07 24 2010 wh.su -+ * -+ * .support the Wi-Fi RSN -+ * -+ * 07 23 2010 cp.wu -+ * -+ * FIX: structure of CMD_SET_BSS_INFO has been changed but no follow-ups are done. -+ * -+ * 07 22 2010 george.huang -+ * -+ * . -+ * -+ * 07 22 2010 george.huang -+ * -+ * Update fgIsQoS information in BSS INFO by CMD -+ * -+ * 07 19 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration. -+ * Add Ad-Hoc support to AIS-FSM -+ * -+ * 07 14 2010 yarco.yang -+ * -+ * 1. Remove CFG_MQM_MIGRATION -+ * 2. Add CMD_UPDATE_WMM_PARMS command -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 07 07 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * update prStaRecOfAP with BSS-INFO. -+ * -+ * 07 06 2010 george.huang -+ * [WPD00001556]Basic power managemenet function -+ * Update arguments for nicUpdateBeaconIETemplate() -+ * -+ * 07 06 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * STA-REC is maintained by CNM only. -+ * -+ * 07 05 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) ignore RSN checking when RSN is not turned on. -+ * 2) set STA-REC deactivation callback as NULL -+ * 3) add variable initialization API based on PHY configuration -+ * -+ * 07 01 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Support sync command of STA_REC -+ * -+ * 06 30 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * sync. with CMD/EVENT document ver0.07. -+ * -+ * 06 29 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * correct variable naming for 8-bit variable used in CMD_BEACON_TEMPLATE_UPDATE. -+ * -+ * 06 29 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) sync to. CMD/EVENT document v0.03 -+ * 2) simplify DTIM period parsing in scan.c only, bss.c no longer parses it again. -+ * 3) send command packet to indicate FW-PM after -+ * a) 1st beacon is received after AIS has connected to an AP -+ * b) IBSS-ALONE has been created -+ * c) IBSS-MERGE has occurred -+ * -+ * 06 25 2010 george.huang -+ * [WPD00001556]Basic power managemenet function -+ * Create beacon update path, with expose bssUpdateBeaconContent() -+ * -+ * 06 22 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * fill fgIsUapsdConnection when indicating BSS-CREATE with AIS-STA mode. -+ * -+ * 06 22 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) add command warpper for STA-REC/BSS-INFO sync. -+ * 2) enhance command packet sending procedure for non-oid part -+ * 3) add command packet definitions for STA-REC/BSS-INFO sync. -+ * -+ * 06 21 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * implement TX_DONE callback path. -+ * -+ * 06 21 2010 wh.su -+ * [WPD00003840][MT6620 5931] Security migration -+ * remove duplicate variable for migration. -+ * -+ * 06 21 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * TX descriptors are now allocated once for reducing allocation overhead -+ * -+ * 06 18 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Provide cnmMgtPktAlloc() and alloc/free function of msg/buf -+ * -+ * 06 11 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) migrate assoc.c. -+ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness -+ * 3) add configuration options for CNM_MEM and RSN modules -+ * 4) add data path for management frames -+ * 5) eliminate rPacketInfo of MSDU_INFO_T -+ * -+ * 06 10 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) eliminate CFG_CMD_EVENT_VERSION_0_9 -+ * 2) when disconnected, indicate nic directly (no event is needed) -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 04 26 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) surpress compiler warning -+ * 2) when acqruing LP-own, keep writing WHLPCR whenever OWN is not acquired yet -+ * -+ * 04 23 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * surpress compiler warning -+ * -+ * 04 13 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * add framework for BT-over-Wi-Fi support. -+ * * * * * * * * * * * * * 1) prPendingCmdInfo is replaced by queue for multiple handler capability -+ * * * * * * * * * * * * * 2) command sequence number is now increased atomically -+ * * * * * * * * * * * * * 3) private data could be hold and taken use for other purpose -+ * -+ * 04 12 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * add channel frequency <-> number conversion -+ * -+ * 04 06 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * eliminate direct access for prGlueInfo->fgIsCardRemoved in non-glue layer -+ * -+ * 04 06 2010 cp.wu -+ * [WPD00003827][MT6620 Wi-Fi] Chariot fail and following ping fail, no pkt send from driver -+ * correct nicProcessIST_impl() for interrupt status brought up by RX enhanced response -+ * -+ * 03 19 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) add ACPI D0/D3 state switching support -+ * * * * * * * 2) use more formal way to handle interrupt when the status is retrieved from enhanced RX response -+ * -+ * 03 17 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * always process TX interrupt first then RX interrupt. -+ * -+ * 02 25 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * correct behavior to prevent duplicated RX handling for RX0_DONE and RX1_DONE -+ * -+ * 02 23 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * add checksum offloading support. -+** \main\maintrunk.MT6620WiFiDriver_Prj\27 2009-12-16 18:03:43 GMT mtk02752 -+** handling enhanced response which fields are fetched at different moments -+** \main\maintrunk.MT6620WiFiDriver_Prj\26 2009-12-15 17:00:29 GMT mtk02752 -+** if RX enhanced response is used, D2H interrupt status should be coming from buffered result as well -+** \main\maintrunk.MT6620WiFiDriver_Prj\25 2009-12-15 12:01:55 GMT mtk02752 -+** if TX_DONE bit is not set but WTSR0/WTSR1 is non-zero, then set TX_DONE -+** bit due to time latency of interrupt status enhanced response -+** \main\maintrunk.MT6620WiFiDriver_Prj\24 2009-12-10 16:52:52 GMT mtk02752 -+** code clean -+** \main\maintrunk.MT6620WiFiDriver_Prj\23 2009-11-24 20:51:01 GMT mtk02752 -+** integrate with SD1 by invoking qmHandleMailboxRxMessage() -+** \main\maintrunk.MT6620WiFiDriver_Prj\22 2009-11-16 17:32:33 GMT mtk02752 -+** prepare code for invoking rxHandleMailboxRxMessage() -+** \main\maintrunk.MT6620WiFiDriver_Prj\21 2009-11-11 10:36:08 GMT mtk01084 -+** \main\maintrunk.MT6620WiFiDriver_Prj\20 2009-11-09 22:56:41 GMT mtk01084 -+** modify HW access routines -+** \main\maintrunk.MT6620WiFiDriver_Prj\19 2009-10-30 18:17:20 GMT mtk01084 -+** prevent warning -+** \main\maintrunk.MT6620WiFiDriver_Prj\18 2009-10-29 19:54:57 GMT mtk01084 -+** init HIF -+** \main\maintrunk.MT6620WiFiDriver_Prj\17 2009-10-23 16:08:30 GMT mtk01084 -+** \main\maintrunk.MT6620WiFiDriver_Prj\16 2009-10-13 21:59:12 GMT mtk01084 -+** update for new HW design -+** \main\maintrunk.MT6620WiFiDriver_Prj\15 2009-09-09 17:26:15 GMT mtk01084 -+** modify for CFG_TEST_WITH_MT5921 -+** \main\maintrunk.MT6620WiFiDriver_Prj\14 2009-05-19 10:55:22 GMT mtk01461 -+** Unmask the unused HISR -+** \main\maintrunk.MT6620WiFiDriver_Prj\13 2009-05-18 15:59:13 GMT mtk01084 -+** remove debug purpose code -+** \main\maintrunk.MT6620WiFiDriver_Prj\12 2009-05-18 14:05:02 GMT mtk01084 -+** update for WIFI ownback part on initial -+** \main\maintrunk.MT6620WiFiDriver_Prj\11 2009-05-04 21:32:57 GMT mtk01084 -+** add temporarily code to set driver own on adapter initialization -+** \main\maintrunk.MT6620WiFiDriver_Prj\10 2009-04-28 10:35:41 GMT mtk01461 -+** Add init of TX aggregation and fix RX STATUS is DW align for SDIO_STATUS_ENHANCE mode -+** \main\maintrunk.MT6620WiFiDriver_Prj\9 2009-04-24 21:12:10 GMT mtk01104 -+** Add function nicRestoreSpiDefMode() -+** \main\maintrunk.MT6620WiFiDriver_Prj\8 2009-04-21 09:43:31 GMT mtk01461 -+** Revise for MTK coding style - nicInitializeAdapter() -+** \main\maintrunk.MT6620WiFiDriver_Prj\7 2009-04-17 19:52:47 GMT mtk01461 -+** Update allocate Adapter Memory for MGMT Memory pool -+** \main\maintrunk.MT6620WiFiDriver_Prj\6 2009-04-01 10:57:08 GMT mtk01461 -+** Refine the order of release memory from pucRxCoalescingBufCached -+** \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-03-19 18:32:57 GMT mtk01084 -+** update for basic power management functions -+** \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-03-18 21:00:14 GMT mtk01426 -+** Add CFG_SDIO_RX_ENHANCE support -+** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-03-16 09:10:27 GMT mtk01461 -+** Update TX PATH API -+** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 20:25:59 GMT mtk01426 -+** Init for develop -+** -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "precomp.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+const UINT_8 aucPhyCfg2PhyTypeSet[PHY_CONFIG_NUM] = { -+ PHY_TYPE_SET_802_11ABG, /* PHY_CONFIG_802_11ABG */ -+ PHY_TYPE_SET_802_11BG, /* PHY_CONFIG_802_11BG */ -+ PHY_TYPE_SET_802_11G, /* PHY_CONFIG_802_11G */ -+ PHY_TYPE_SET_802_11A, /* PHY_CONFIG_802_11A */ -+ PHY_TYPE_SET_802_11B, /* PHY_CONFIG_802_11B */ -+ PHY_TYPE_SET_802_11ABGN, /* PHY_CONFIG_802_11ABGN */ -+ PHY_TYPE_SET_802_11BGN, /* PHY_CONFIG_802_11BGN */ -+ PHY_TYPE_SET_802_11AN, /* PHY_CONFIG_802_11AN */ -+ PHY_TYPE_SET_802_11GN /* PHY_CONFIG_802_11GN */ -+}; -+ -+#if (MT6620_E1_ASIC_HIFSYS_WORKAROUND == 1) -+#define REQ_GATING_ENABLE_H2D_INT BIT(31) -+#define REQ_GATING_DISABLE_H2D_INT BIT(30) -+#define ACK_GATING_ENABLE_D2H_INT BIT(31) -+#define ACK_GATING_DISABLE_D2H_INT BIT(30) -+ -+#define GATING_CONTROL_POLL_LIMIT 64 -+#endif -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+static INT_EVENT_MAP_T arIntEventMapTable[] = { -+ {WHISR_ABNORMAL_INT, INT_EVENT_ABNORMAL}, -+ {WHISR_D2H_SW_INT, INT_EVENT_SW_INT}, -+ {WHISR_TX_DONE_INT, INT_EVENT_TX}, -+ {(WHISR_RX0_DONE_INT | WHISR_RX1_DONE_INT), INT_EVENT_RX} -+}; -+ -+static const UINT_8 ucIntEventMapSize = (sizeof(arIntEventMapTable) / sizeof(INT_EVENT_MAP_T)); -+ -+static IST_EVENT_FUNCTION apfnEventFuncTable[] = { -+ nicProcessAbnormalInterrupt, /*!< INT_EVENT_ABNORMAL */ -+ nicProcessSoftwareInterrupt, /*!< INT_EVENT_SW_INT */ -+ nicProcessTxInterrupt, /*!< INT_EVENT_TX */ -+ nicProcessRxInterrupt, /*!< INT_EVENT_RX */ -+}; -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+/*! This macro is used to reduce coding errors inside nicAllocateAdapterMemory() -+ * and also enhance the readability. -+ */ -+#define LOCAL_NIC_ALLOCATE_MEMORY(pucMem, u4Size, eMemType, pucComment) \ -+ { \ -+ DBGLOG(NIC, INFO, "Allocating %u bytes for %s.\n", u4Size, pucComment); \ -+ pucMem = (PUINT_8)kalMemAlloc(u4Size, eMemType); \ -+ if (pucMem == (PUINT_8)NULL) { \ -+ DBGLOG(NIC, ERROR, "Could not allocate %u bytes for %s.\n", u4Size, pucComment); \ -+ break; \ -+ } \ -+ ASSERT(((ULONG)pucMem % 4) == 0); \ -+ DBGLOG(NIC, TRACE, "Virtual Address = %p for %s.\n", pucMem, pucComment); \ -+ } -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+VOID HifDumpEnhanceModeData(P_ADAPTER_T prAdapter) -+{ -+ dumpMemory32((PUINT_32)prAdapter->prSDIOCtrl, sizeof(ENHANCE_MODE_DATA_STRUCT_T)); -+} -+ -+VOID HifRegDump(P_ADAPTER_T prAdapter) -+{ -+ UINT_32 i; -+ UINT_32 RegVal = 0; -+ -+ for (i = 0; i <= 0x58; i += 4) { -+ if ((i != MCR_WTDR0) && (i != MCR_WTDR1) && (i != MCR_WRDR0) && -+ (i != MCR_WRDR1) && (i != MCR_WSDIOCSR) && (i != MCR_WRPLR)) { -+ HAL_MCR_RD(prAdapter, i, &RegVal); -+ DBGLOG(NIC, WARN, "HIF Reg 0x%x = 0x%x\n", i, RegVal); -+ } -+ } -+ DBGLOG(NIC, WARN, "\n\n"); -+} -+ -+BOOLEAN HifIsFwOwn(P_ADAPTER_T prAdapter) -+{ -+ return prAdapter->fgIsFwOwn; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This routine is responsible for the allocation of the data structures -+* inside the Adapter structure, include: -+* 1. SW_RFB_Ts -+* 2. Common coalescing buffer for TX PATH. -+* -+* @param prAdapter Pointer of Adapter Data Structure -+* -+* @retval WLAN_STATUS_SUCCESS - Has enough memory. -+* @retval WLAN_STATUS_RESOURCES - Memory is not enough. -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS nicAllocateAdapterMemory(IN P_ADAPTER_T prAdapter) -+{ -+ WLAN_STATUS status = WLAN_STATUS_RESOURCES; -+ P_RX_CTRL_T prRxCtrl; -+ P_TX_CTRL_T prTxCtrl; -+ -+ DEBUGFUNC("nicAllocateAdapterMemory"); -+ -+ ASSERT(prAdapter); -+ prRxCtrl = &prAdapter->rRxCtrl; -+ prTxCtrl = &prAdapter->rTxCtrl; -+ -+ do { -+ /* 4 <0> Reset all Memory Handler */ -+#if CFG_DBG_MGT_BUF -+ prAdapter->u4MemFreeDynamicCount = 0; -+ prAdapter->u4MemAllocDynamicCount = 0; -+#endif -+ prAdapter->pucMgtBufCached = (PUINT_8) NULL; -+ prRxCtrl->pucRxCached = (PUINT_8) NULL; -+ prAdapter->prSDIOCtrl = (P_SDIO_CTRL_T) NULL; -+ -+ /* 4 <1> Memory for Management Memory Pool and CMD_INFO_T */ -+ /* Allocate memory for the CMD_INFO_T and its MGMT memory pool. */ -+ prAdapter->u4MgtBufCachedSize = MGT_BUFFER_SIZE; -+ -+ LOCAL_NIC_ALLOCATE_MEMORY(prAdapter->pucMgtBufCached, -+ prAdapter->u4MgtBufCachedSize, VIR_MEM_TYPE, "COMMON MGMT MEMORY POOL"); -+ -+ /* 4 <2> Memory for RX Descriptor */ -+ /* Initialize the number of rx buffers we will have in our queue. */ -+ /* We may setup ucRxPacketDescriptors by GLUE Layer, and using -+ * this variable directly. -+ */ -+ /* Allocate memory for the SW receive structures. */ -+ prRxCtrl->u4RxCachedSize = CFG_RX_MAX_PKT_NUM * ALIGN_4(sizeof(SW_RFB_T)); -+ -+ LOCAL_NIC_ALLOCATE_MEMORY(prRxCtrl->pucRxCached, prRxCtrl->u4RxCachedSize, VIR_MEM_TYPE, "SW_RFB_T"); -+ -+ /* 4 <3> Memory for TX DEscriptor */ -+ prTxCtrl->u4TxCachedSize = CFG_TX_MAX_PKT_NUM * ALIGN_4(sizeof(MSDU_INFO_T)); -+ -+ LOCAL_NIC_ALLOCATE_MEMORY(prTxCtrl->pucTxCached, prTxCtrl->u4TxCachedSize, VIR_MEM_TYPE, "MSDU_INFO_T"); -+ -+ /* 4 <4> Memory for Common Coalescing Buffer */ -+#if CFG_COALESCING_BUFFER_SIZE || CFG_SDIO_RX_AGG -+ prAdapter->pucCoalescingBufCached = (PUINT_8) NULL; -+ -+ /* Allocate memory for the common coalescing buffer. */ -+ prAdapter->u4CoalescingBufCachedSize = CFG_COALESCING_BUFFER_SIZE > CFG_RX_COALESCING_BUFFER_SIZE ? -+ CFG_COALESCING_BUFFER_SIZE : CFG_RX_COALESCING_BUFFER_SIZE; -+ -+ prAdapter->pucCoalescingBufCached = kalAllocateIOBuffer(prAdapter->u4CoalescingBufCachedSize); -+ -+ if (prAdapter->pucCoalescingBufCached == NULL) { -+ DBGLOG(NIC, ERROR, -+ "Could not allocate %u bytes for coalescing buffer.\n", -+ prAdapter->u4CoalescingBufCachedSize); -+ break; -+ } -+#endif /* CFG_COALESCING_BUFFER_SIZE */ -+ -+ /* 4 <5> Memory for enhanced interrupt response */ -+ prAdapter->prSDIOCtrl = (P_SDIO_CTRL_T) -+ kalAllocateIOBuffer(sizeof(ENHANCE_MODE_DATA_STRUCT_T)); -+ -+ if (prAdapter->prSDIOCtrl == NULL) { -+ DBGLOG(NIC, ERROR, -+ "Could not allocate %zu bytes for interrupt response.\n", -+ sizeof(ENHANCE_MODE_DATA_STRUCT_T)); -+ break; -+ } -+ -+ status = WLAN_STATUS_SUCCESS; -+ -+ } while (FALSE); -+ -+ if (status != WLAN_STATUS_SUCCESS) -+ nicReleaseAdapterMemory(prAdapter); -+ -+ return status; -+ -+} /* end of nicAllocateAdapterMemory() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This routine is responsible for releasing the allocated memory by -+* nicAllocatedAdapterMemory(). -+* -+* @param prAdapter Pointer of Adapter Data Structure -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicReleaseAdapterMemory(IN P_ADAPTER_T prAdapter) -+{ -+ P_TX_CTRL_T prTxCtrl; -+ P_RX_CTRL_T prRxCtrl; -+ -+ ASSERT(prAdapter); -+ prTxCtrl = &prAdapter->rTxCtrl; -+ prRxCtrl = &prAdapter->rRxCtrl; -+ -+ /* 4 <5> Memory for enhanced interrupt response */ -+ if (prAdapter->prSDIOCtrl) { -+ kalReleaseIOBuffer((PVOID) prAdapter->prSDIOCtrl, sizeof(ENHANCE_MODE_DATA_STRUCT_T)); -+ prAdapter->prSDIOCtrl = (P_SDIO_CTRL_T) NULL; -+ } -+ /* 4 <4> Memory for Common Coalescing Buffer */ -+#if CFG_COALESCING_BUFFER_SIZE || CFG_SDIO_RX_AGG -+ if (prAdapter->pucCoalescingBufCached) { -+ kalReleaseIOBuffer((PVOID) prAdapter->pucCoalescingBufCached, prAdapter->u4CoalescingBufCachedSize); -+ prAdapter->pucCoalescingBufCached = (PUINT_8) NULL; -+ } -+#endif /* CFG_COALESCING_BUFFER_SIZE */ -+ -+ /* 4 <3> Memory for TX Descriptor */ -+ if (prTxCtrl->pucTxCached) { -+ kalMemFree((PVOID) prTxCtrl->pucTxCached, VIR_MEM_TYPE, prTxCtrl->u4TxCachedSize); -+ prTxCtrl->pucTxCached = (PUINT_8) NULL; -+ } -+ /* 4 <2> Memory for RX Descriptor */ -+ if (prRxCtrl->pucRxCached) { -+ kalMemFree((PVOID) prRxCtrl->pucRxCached, VIR_MEM_TYPE, prRxCtrl->u4RxCachedSize); -+ prRxCtrl->pucRxCached = (PUINT_8) NULL; -+ } -+ /* 4 <1> Memory for Management Memory Pool */ -+ if (prAdapter->pucMgtBufCached) { -+ kalMemFree((PVOID) prAdapter->pucMgtBufCached, VIR_MEM_TYPE, prAdapter->u4MgtBufCachedSize); -+ prAdapter->pucMgtBufCached = (PUINT_8) NULL; -+ } -+#if CFG_DBG_MGT_BUF -+ /* Check if all allocated memories are free */ -+ ASSERT(prAdapter->u4MemFreeDynamicCount == prAdapter->u4MemAllocDynamicCount); -+#endif -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief disable global interrupt -+* -+* @param prAdapter pointer to the Adapter handler -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicDisableInterrupt(IN P_ADAPTER_T prAdapter) -+{ -+ ASSERT(prAdapter); -+ -+ HAL_MCR_WR(prAdapter, MCR_WHLPCR, WHLPCR_INT_EN_CLR); -+ -+ prAdapter->fgIsIntEnable = FALSE; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief enable global interrupt -+* -+* @param prAdapter pointer to the Adapter handler -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicEnableInterrupt(IN P_ADAPTER_T prAdapter) -+{ -+ BOOLEAN fgIsIntEnableCache; -+ -+ ASSERT(prAdapter); -+ fgIsIntEnableCache = prAdapter->fgIsIntEnable; -+ -+ prAdapter->fgIsIntEnable = TRUE; /* NOTE(Kevin): It must be placed before MCR GINT write. */ -+ -+ /* If need enable INT and also set LPOwn at the same time. */ -+ if (prAdapter->fgIsIntEnableWithLPOwnSet) { -+ prAdapter->fgIsIntEnableWithLPOwnSet = FALSE; /* NOTE(Kevin): It's better to place it -+ * before MCR GINT write. -+ */ -+ /* If INT was enabled, only set LPOwn */ -+ if (fgIsIntEnableCache) { -+ HAL_MCR_WR(prAdapter, MCR_WHLPCR, WHLPCR_FW_OWN_REQ_SET); -+ prAdapter->fgIsFwOwn = TRUE; -+ } -+ /* If INT was not enabled, enable it and also set LPOwn now */ -+ else { -+ HAL_MCR_WR(prAdapter, MCR_WHLPCR, WHLPCR_FW_OWN_REQ_SET | WHLPCR_INT_EN_SET); -+ prAdapter->fgIsFwOwn = TRUE; -+ } -+ } -+ /* If INT was not enabled, enable it now */ -+ else if (!fgIsIntEnableCache) -+ HAL_MCR_WR(prAdapter, MCR_WHLPCR, WHLPCR_INT_EN_SET); -+ -+} /* end of nicEnableInterrupt() */ -+ -+#if CFG_SDIO_INTR_ENHANCE -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief For SDIO enhance mode, set the max rx len and tx status -+* -+* @param prAdapter a pointer to adapter private data structure. -+* -+* @return - none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicSDIOInit(IN P_ADAPTER_T prAdapter) -+{ -+ UINT_32 u4Value = 0; -+ -+ ASSERT(prAdapter); -+ -+ /* 4 <1> Check STATUS Buffer is DW alignment. */ -+ ASSERT(IS_ALIGN_4((ULONG)&prAdapter->prSDIOCtrl->u4WHISR)); -+ -+ /* 4 <2> Setup STATUS count. */ -+ { -+ HAL_MCR_RD(prAdapter, MCR_WHCR, &u4Value); -+ -+ /* 4 <2.1> Setup the number of maximum RX length to be report */ -+ u4Value &= ~(WHCR_MAX_HIF_RX_LEN_NUM); -+ u4Value |= ((SDIO_MAXIMUM_RX_LEN_NUM << WHCR_OFFSET_MAX_HIF_RX_LEN_NUM)); -+ -+ /* 4 <2.2> Setup RX enhancement mode */ -+#if CFG_SDIO_RX_ENHANCE -+ u4Value |= WHCR_RX_ENHANCE_MODE_EN; -+#else -+ u4Value &= ~WHCR_RX_ENHANCE_MODE_EN; -+#endif /* CFG_SDIO_RX_AGG */ -+ -+ HAL_MCR_WR(prAdapter, MCR_WHCR, u4Value); -+ } -+ -+ return; -+ -+} /* end of nicSDIOInit() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Read interrupt status from hardware -+* -+* @param prAdapter pointer to the Adapter handler -+* @param the interrupts -+* -+* @return N/A -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicSDIOReadIntStatus(IN P_ADAPTER_T prAdapter, OUT PUINT_32 pu4IntStatus) -+{ -+ P_SDIO_CTRL_T prSDIOCtrl; -+ -+ DEBUGFUNC("nicSDIOReadIntStatus"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4IntStatus); -+ -+ /* -+ prSDIOCtrl is from IO buffer. -+ prAdapter->prSDIOCtrl = (P_SDIO_CTRL_T) -+ kalAllocateIOBuffer(sizeof(ENHANCE_MODE_DATA_STRUCT_T)); -+ */ -+ prSDIOCtrl = prAdapter->prSDIOCtrl; -+ ASSERT(prSDIOCtrl); -+ -+ HAL_PORT_RD(prAdapter, -+ MCR_WHISR, -+ sizeof(ENHANCE_MODE_DATA_STRUCT_T), (PUINT_8) prSDIOCtrl, sizeof(ENHANCE_MODE_DATA_STRUCT_T)); -+ -+ if (kalIsCardRemoved(prAdapter->prGlueInfo) == TRUE || fgIsBusAccessFailed == TRUE) { -+ *pu4IntStatus = 0; -+ return; -+ } -+ -+ /* workaround */ -+ if ((prSDIOCtrl->u4WHISR & WHISR_TX_DONE_INT) == 0 && -+ (prSDIOCtrl->rTxInfo.au4WTSR[0] | prSDIOCtrl->rTxInfo.au4WTSR[1])) { -+ prSDIOCtrl->u4WHISR |= WHISR_TX_DONE_INT; -+ } -+ -+ if ((prSDIOCtrl->u4WHISR & BIT(31)) == 0 && -+ HAL_GET_MAILBOX_READ_CLEAR(prAdapter) == TRUE && -+ (prSDIOCtrl->u4RcvMailbox0 != 0 || prSDIOCtrl->u4RcvMailbox1 != 0)) { -+ prSDIOCtrl->u4WHISR |= BIT(31); -+ } -+ -+ *pu4IntStatus = prSDIOCtrl->u4WHISR; -+ -+} /* end of nicSDIOReadIntStatus() */ -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief The function used to read interrupt status and then invoking -+* dispatching procedure for the appropriate functions -+* corresponding to specific interrupt bits -+* -+* @param prAdapter pointer to the Adapter handler -+* -+* @retval WLAN_STATUS_SUCCESS -+* @retval WLAN_STATUS_ADAPTER_NOT_READY -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS nicProcessIST(IN P_ADAPTER_T prAdapter) -+{ -+ WLAN_STATUS u4Status = WLAN_STATUS_SUCCESS; -+ UINT_32 u4IntStatus = 0; -+ UINT_32 i; -+ -+ DEBUGFUNC("nicProcessIST"); -+ /* DBGLOG(NIC, LOUD, ("\n")); */ -+ -+ ASSERT(prAdapter); -+ -+ if (prAdapter->rAcpiState == ACPI_STATE_D3) { -+ DBGLOG(REQ, WARN, "Fail in set nicProcessIST! (Adapter not ready). ACPI=D%d, Radio=%d\n", -+ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); -+ return WLAN_STATUS_ADAPTER_NOT_READY; -+ } -+#if (MT6620_E1_ASIC_HIFSYS_WORKAROUND == 1) -+ if (prAdapter->fgIsClockGatingEnabled == TRUE) -+ nicDisableClockGating(prAdapter); -+#endif -+ -+ for (i = 0; i < CFG_IST_LOOP_COUNT; i++) { /* CFG_IST_LOOP_COUNT = 1 */ -+ -+#if CFG_SDIO_INTR_ENHANCE -+ nicSDIOReadIntStatus(prAdapter, &u4IntStatus); -+#else -+ HAL_MCR_RD(prAdapter, MCR_WHISR, &u4IntStatus); -+#endif /* CFG_SDIO_INTR_ENHANCE */ -+ -+/* DBGLOG(NIC, TRACE, ("u4IntStatus: 0x%x\n", u4IntStatus)); */ -+ -+ if (u4IntStatus & ~(WHIER_DEFAULT | WHIER_FW_OWN_BACK_INT_EN)) { -+ DBGLOG(INTR, WARN, "Un-handled HISR %#x, HISR = %#x (HIER:0x%x)\n", -+ (UINT_32) (u4IntStatus & ~WHIER_DEFAULT), u4IntStatus, -+ (UINT_32) WHIER_DEFAULT); -+ u4IntStatus &= WHIER_DEFAULT; -+ } -+ -+ nicProcessIST_impl(prAdapter, u4IntStatus); -+ -+ if (u4IntStatus == 0) { -+ if (i == 0) -+ u4Status = WLAN_STATUS_NOT_INDICATING; -+ break; -+ } -+ } -+ -+#if (MT6620_E1_ASIC_HIFSYS_WORKAROUND == 1) -+ if (prAdapter->fgIsClockGatingEnabled == FALSE) -+ nicEnableClockGating(prAdapter); -+#endif -+ -+ return u4Status; -+} /* end of nicProcessIST() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief The function used to dispatch the appropriate functions for specific -+* interrupt bits -+* -+* @param prAdapter pointer to the Adapter handler -+* u4IntStatus interrupt status bits -+* -+* @retval WLAN_STATUS_SUCCESS -+* @retval WLAN_STATUS_ADAPTER_NOT_READY -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS nicProcessIST_impl(IN P_ADAPTER_T prAdapter, IN UINT_32 u4IntStatus) -+{ -+ UINT_32 u4IntCount = 0; -+ P_INT_EVENT_MAP_T prIntEventMap = NULL; -+ -+ ASSERT(prAdapter); -+ -+ prAdapter->u4IntStatus = u4IntStatus; -+ -+ /* Process each of the interrupt status consequently */ -+ prIntEventMap = &arIntEventMapTable[0]; -+ for (u4IntCount = 0; u4IntCount < ucIntEventMapSize; prIntEventMap++, u4IntCount++) { -+ if (prIntEventMap->u4Int & prAdapter->u4IntStatus) { -+ if (prIntEventMap->u4Event == INT_EVENT_RX && prAdapter->fgIsEnterD3ReqIssued == TRUE) { -+ /* ignore */ -+ } else if (apfnEventFuncTable[prIntEventMap->u4Event] != NULL) { -+ apfnEventFuncTable[prIntEventMap->u4Event] (prAdapter); -+ } else { -+ DBGLOG(INTR, WARN, -+ "Empty INTR handler! ISAR bit#: %u, event:%u, func: %p\n", -+ prIntEventMap->u4Int, prIntEventMap->u4Event, -+ apfnEventFuncTable[prIntEventMap->u4Event]); -+ -+ ASSERT(0); /* to trap any NULL interrupt handler */ -+ } -+ prAdapter->u4IntStatus &= ~prIntEventMap->u4Int; -+ } -+ } -+ -+ return WLAN_STATUS_SUCCESS; -+} /* end of nicProcessIST_impl() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Verify the CHIP ID -+* -+* @param prAdapter a pointer to adapter private data structure. -+* -+* -+* @retval TRUE CHIP ID is the same as the setting compiled -+* @retval FALSE CHIP ID is different from the setting compiled -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN nicVerifyChipID(IN P_ADAPTER_T prAdapter) -+{ -+ UINT_32 u4CIR = 0; -+ -+ ASSERT(prAdapter); -+ -+ HAL_MCR_RD(prAdapter, MCR_WCIR, &u4CIR); -+ -+ DBGLOG(NIC, TRACE, "Chip ID: 0x%x\n", (UINT_32) (u4CIR & WCIR_CHIP_ID)); -+ DBGLOG(NIC, TRACE, "Revision ID: 0x%x\n", (UINT_32) ((u4CIR & WCIR_REVISION_ID) >> 16)); -+ -+#if 0 -+ if (((u4CIR & WCIR_CHIP_ID) != MTK_CHIP_REV_72) && ((u4CIR & WCIR_CHIP_ID) != MTK_CHIP_REV_82)) -+ return FALSE; -+#endif -+ -+ prAdapter->ucRevID = (UINT_8) (((u4CIR & WCIR_REVISION_ID) >> 16) & 0xF); -+ -+ return TRUE; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Initialize the MCR to the appropriate init value, and verify the init -+* value -+* -+* @param prAdapter a pointer to adapter private data structure. -+* -+* @return - -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicMCRInit(IN P_ADAPTER_T prAdapter) -+{ -+ -+ ASSERT(prAdapter); -+ -+ /* 4 <0> Initial value */ -+} -+ -+VOID nicHifInit(IN P_ADAPTER_T prAdapter) -+{ -+ -+ ASSERT(prAdapter); -+#if 0 -+ /* reset event */ -+ nicPutMailbox(prAdapter, 0, 0x52455345); /* RESE */ -+ nicPutMailbox(prAdapter, 1, 0x545F5746); /* T_WF */ -+ nicSetSwIntr(prAdapter, BIT(16)); -+#endif -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Initialize the Adapter soft variable -+* -+* @param prAdapter pointer to the Adapter handler -+* -+* @return (none) -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS nicInitializeAdapter(IN P_ADAPTER_T prAdapter) -+{ -+ WLAN_STATUS u4Status = WLAN_STATUS_SUCCESS; -+ -+ ASSERT(prAdapter); -+ -+ prAdapter->fgIsIntEnableWithLPOwnSet = FALSE; -+ -+ do { -+ if (!nicVerifyChipID(prAdapter)) { -+ u4Status = WLAN_STATUS_FAILURE; -+ break; -+ } -+ /* 4 <1> MCR init */ -+ nicMCRInit(prAdapter); -+ -+#if CFG_SDIO_INTR_ENHANCE -+ nicSDIOInit(prAdapter); -+#endif /* CFG_SDIO_INTR_ENHANCE */ -+ -+ HAL_MCR_WR(prAdapter, MCR_WHIER, WHIER_DEFAULT); -+ -+ /* 4 <2> init FW HIF */ -+ nicHifInit(prAdapter); -+ } while (FALSE); -+ -+ return u4Status; -+} -+ -+#if defined(_HIF_SPI) -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Restore the SPI Mode Select to default mode, -+* this is important while driver is unload, and this must be last mcr -+* since the operation will let the hif use 8bit mode access -+* -+* \param[in] prAdapter a pointer to adapter private data structure. -+* \param[in] eGPIO2_Mode GPIO2 operation mode -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+void nicRestoreSpiDefMode(IN P_ADAPTER_T prAdapter) -+{ -+ ASSERT(prAdapter); -+ -+ HAL_MCR_WR(prAdapter, MCR_WCSR, SPICSR_8BIT_MODE_DATA); -+ -+} -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Process rx interrupt. When the rx -+* Interrupt is asserted, it means there are frames in queue. -+* -+* @param prAdapter Pointer to the Adapter structure. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicProcessAbnormalInterrupt(IN P_ADAPTER_T prAdapter) -+{ -+ UINT_32 u4Value = 0; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ -+ prGlueInfo = prAdapter->prGlueInfo; -+ prGlueInfo->IsrAbnormalCnt++; -+ HAL_MCR_RD(prAdapter, MCR_WASR, &u4Value); -+ DBGLOG(REQ, WARN, "MCR_WASR: 0x%x\n", u4Value); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief . -+* -+* @param prAdapter Pointer to the Adapter structure. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicProcessFwOwnBackInterrupt(IN P_ADAPTER_T prAdapter) -+{ -+ -+} /* end of nicProcessFwOwnBackInterrupt() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief . -+* -+* @param prAdapter Pointer to the Adapter structure. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicProcessSoftwareInterrupt(IN P_ADAPTER_T prAdapter) -+{ -+ UINT_32 u4IntrBits; -+ -+ P_GLUE_INFO_T prGlueInfo = prAdapter->prGlueInfo; -+ u4IntrBits = prAdapter->u4IntStatus & BITS(8, 31); -+ -+ prGlueInfo->IsrSoftWareCnt++; -+ -+ if ((u4IntrBits & WHISR_D2H_SW_ASSERT_INFO_INT) != 0) { -+ nicPrintFirmwareAssertInfo(prAdapter); -+#if CFG_CHIP_RESET_SUPPORT -+ glSendResetRequest(); -+#endif -+ } -+#if (MT6620_E1_ASIC_HIFSYS_WORKAROUND == 1) -+ ASSERT((u4IntrBits & (ACK_GATING_ENABLE_D2H_INT | ACK_GATING_DISABLE_D2H_INT)) -+ != (ACK_GATING_ENABLE_D2H_INT | ACK_GATING_DISABLE_D2H_INT)); -+ -+ if (u4IntrBits & ACK_GATING_ENABLE_D2H_INT) -+ prAdapter->fgIsClockGatingEnabled = TRUE; -+ -+ if (u4IntrBits & ACK_GATING_DISABLE_D2H_INT) { -+ prAdapter->fgIsClockGatingEnabled = FALSE; -+ -+ /* Indicate Service Thread for TX */ -+ if (kalGetTxPendingCmdCount(prAdapter->prGlueInfo) > 0 || wlanGetTxPendingFrameCount(prAdapter) > 0) -+ kalSetEvent(prAdapter->prGlueInfo); -+ } -+#endif -+ -+ DBGLOG(REQ, WARN, "u4IntrBits: 0x%x\n", u4IntrBits); -+} /* end of nicProcessSoftwareInterrupt() */ -+ -+VOID nicPutMailbox(IN P_ADAPTER_T prAdapter, IN UINT_32 u4MailboxNum, IN UINT_32 u4Data) -+{ -+ if (u4MailboxNum == 0) { -+ /* HAL_MCR_WR */ -+ HAL_MCR_WR(prAdapter, MCR_H2DSM0R, u4Data); -+ } else if (u4MailboxNum == 1) { -+ /* HAL_MCR_WR */ -+ HAL_MCR_WR(prAdapter, MCR_H2DSM1R, u4Data); -+ } else { -+ ASSERT(0); -+ } -+} -+ -+VOID nicGetMailbox(IN P_ADAPTER_T prAdapter, IN UINT_32 u4MailboxNum, OUT PUINT_32 pu4Data) -+{ -+ if (u4MailboxNum == 0) { -+ /* HAL_MCR_RD */ -+ HAL_MCR_RD(prAdapter, MCR_D2HRM0R, pu4Data); -+ } else if (u4MailboxNum == 1) { -+ /* HAL_MCR_RD */ -+ HAL_MCR_RD(prAdapter, MCR_D2HRM1R, pu4Data); -+ } else { -+ ASSERT(0); -+ } -+} -+ -+VOID nicSetSwIntr(IN P_ADAPTER_T prAdapter, IN UINT_32 u4SwIntrBitmap) -+{ -+ /* NOTE: -+ * SW interrupt in HW bit 16 is mapping to SW bit 0 (shift 16bit in HW transparancy) -+ * SW interrupt valid from b0~b15 -+ */ -+ ASSERT((u4SwIntrBitmap & BITS(0, 15)) == 0); -+/* DBGLOG(NIC, TRACE, ("u4SwIntrBitmap: 0x%08x\n", u4SwIntrBitmap)); */ -+ -+ HAL_MCR_WR(prAdapter, MCR_WSICR, u4SwIntrBitmap); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This procedure is used to dequeue from prAdapter->rPendingCmdQueue -+* with specified sequential number -+* -+* @param prAdapter Pointer of ADAPTER_T -+* ucSeqNum Sequential Number -+* -+* @retval - P_CMD_INFO_T -+*/ -+/*----------------------------------------------------------------------------*/ -+P_CMD_INFO_T nicGetPendingCmdInfo(IN P_ADAPTER_T prAdapter, IN UINT_8 ucSeqNum) -+{ -+ P_QUE_T prCmdQue; -+ QUE_T rTempCmdQue; -+ P_QUE_T prTempCmdQue = &rTempCmdQue; -+ P_QUE_ENTRY_T prQueueEntry = (P_QUE_ENTRY_T) NULL; -+ P_CMD_INFO_T prCmdInfo = (P_CMD_INFO_T) NULL; -+ -+ GLUE_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(prAdapter); -+ -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_PENDING); -+ -+ prCmdQue = &prAdapter->rPendingCmdQueue; -+ QUEUE_MOVE_ALL(prTempCmdQue, prCmdQue); -+ -+ QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T); -+ while (prQueueEntry) { -+ prCmdInfo = (P_CMD_INFO_T) prQueueEntry; -+ -+ if (prCmdInfo->ucCmdSeqNum == ucSeqNum) -+ break; -+ -+ QUEUE_INSERT_TAIL(prCmdQue, prQueueEntry); -+ -+ prCmdInfo = NULL; -+ -+ QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T); -+ } -+ QUEUE_CONCATENATE_QUEUES(prCmdQue, prTempCmdQue); -+ -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_PENDING); -+ -+ return prCmdInfo; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This procedure is used to dequeue from prAdapter->rTxCtrl.rTxMgmtTxingQueue -+* with specified sequential number -+* -+* @param prAdapter Pointer of ADAPTER_T -+* ucSeqNum Sequential Number -+* -+* @retval - P_MSDU_INFO_T -+*/ -+/*----------------------------------------------------------------------------*/ -+P_MSDU_INFO_T nicGetPendingTxMsduInfo(IN P_ADAPTER_T prAdapter, IN UINT_8 ucSeqNum) -+{ -+ P_QUE_T prTxingQue; -+ QUE_T rTempQue; -+ P_QUE_T prTempQue = &rTempQue; -+ P_QUE_ENTRY_T prQueueEntry = (P_QUE_ENTRY_T) NULL; -+ P_MSDU_INFO_T prMsduInfo = (P_MSDU_INFO_T) NULL; -+ -+ GLUE_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(prAdapter); -+ -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TXING_MGMT_LIST); -+ -+ prTxingQue = &(prAdapter->rTxCtrl.rTxMgmtTxingQueue); -+ QUEUE_MOVE_ALL(prTempQue, prTxingQue); -+ -+ QUEUE_REMOVE_HEAD(prTempQue, prQueueEntry, P_QUE_ENTRY_T); -+ while (prQueueEntry) { -+ prMsduInfo = (P_MSDU_INFO_T) prQueueEntry; -+ -+ if (prMsduInfo->ucTxSeqNum == ucSeqNum) -+ break; -+ -+ QUEUE_INSERT_TAIL(prTxingQue, prQueueEntry); -+ -+ prMsduInfo = NULL; -+ -+ QUEUE_REMOVE_HEAD(prTempQue, prQueueEntry, P_QUE_ENTRY_T); -+ } -+ QUEUE_CONCATENATE_QUEUES(prTxingQue, prTempQue); -+ -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TXING_MGMT_LIST); -+ -+ return prMsduInfo; -+} -+ -+P_MSDU_INFO_T nicGetPendingStaMMPDU(IN P_ADAPTER_T prAdapter, IN UINT_8 ucStaRecIdx) -+{ -+ P_MSDU_INFO_T prMsduInfoListHead = (P_MSDU_INFO_T) NULL; -+ P_QUE_T prTxingQue = (P_QUE_T) NULL; -+ QUE_T rTempQue; -+ P_QUE_T prTempQue = &rTempQue; -+ P_QUE_ENTRY_T prQueueEntry = (P_QUE_ENTRY_T) NULL; -+ P_MSDU_INFO_T prMsduInfo = (P_MSDU_INFO_T) NULL; -+ GLUE_SPIN_LOCK_DECLARATION(); -+ -+ if (prAdapter == NULL) { -+ ASSERT(FALSE); -+ return NULL; -+ } -+ -+ -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TXING_MGMT_LIST); -+ do { -+ -+ prTxingQue = &(prAdapter->rTxCtrl.rTxMgmtTxingQueue); -+ QUEUE_MOVE_ALL(prTempQue, prTxingQue); -+ -+ QUEUE_REMOVE_HEAD(prTempQue, prQueueEntry, P_QUE_ENTRY_T); -+ while (prQueueEntry) { -+ prMsduInfo = (P_MSDU_INFO_T) prQueueEntry; -+ -+ if ((prMsduInfo->ucStaRecIndex == ucStaRecIdx) && (prMsduInfo->pfTxDoneHandler != NULL)) { -+ QM_TX_SET_NEXT_MSDU_INFO(prMsduInfo, prMsduInfoListHead); -+ prMsduInfoListHead = prMsduInfo; -+ } else { -+ QUEUE_INSERT_TAIL(prTxingQue, prQueueEntry); -+ -+ prMsduInfo = NULL; -+ } -+ -+ QUEUE_REMOVE_HEAD(prTempQue, prQueueEntry, P_QUE_ENTRY_T); -+ } -+ -+ } while (FALSE); -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TXING_MGMT_LIST); -+ -+ return prMsduInfoListHead; -+} /* nicGetPendingStaMMPDU */ -+ -+VOID nicFreePendingTxMsduInfoByNetwork(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkType) -+{ -+ P_QUE_T prTxingQue; -+ QUE_T rTempQue; -+ P_QUE_T prTempQue = &rTempQue; -+ P_QUE_ENTRY_T prQueueEntry = (P_QUE_ENTRY_T) NULL; -+ P_MSDU_INFO_T prMsduInfoListHead = (P_MSDU_INFO_T) NULL; -+ P_MSDU_INFO_T prMsduInfoListTail = (P_MSDU_INFO_T) NULL; -+ P_MSDU_INFO_T prMsduInfo = (P_MSDU_INFO_T) NULL; -+ -+ GLUE_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(prAdapter); -+ -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TXING_MGMT_LIST); -+ -+ prTxingQue = &(prAdapter->rTxCtrl.rTxMgmtTxingQueue); -+ QUEUE_MOVE_ALL(prTempQue, prTxingQue); -+ -+ QUEUE_REMOVE_HEAD(prTempQue, prQueueEntry, P_QUE_ENTRY_T); -+ while (prQueueEntry) { -+ prMsduInfo = (P_MSDU_INFO_T) prQueueEntry; -+ -+ if ((ENUM_NETWORK_TYPE_INDEX_T) (prMsduInfo->ucNetworkType) == eNetworkType) { -+ if (prMsduInfoListHead == NULL) { -+ prMsduInfoListHead = prMsduInfoListTail = prMsduInfo; -+ } else { -+ QM_TX_SET_NEXT_MSDU_INFO(prMsduInfoListTail, prMsduInfo); -+ prMsduInfoListTail = prMsduInfo; -+ } -+ } else { -+ QUEUE_INSERT_TAIL(prTxingQue, prQueueEntry); -+ -+ prMsduInfo = NULL; -+ } -+ -+ QUEUE_REMOVE_HEAD(prTempQue, prQueueEntry, P_QUE_ENTRY_T); -+ } -+ QUEUE_CONCATENATE_QUEUES(prTxingQue, prTempQue); -+ -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TXING_MGMT_LIST); -+ -+ /* free */ -+ if (prMsduInfoListHead) -+ nicTxFreeMsduInfoPacket(prAdapter, prMsduInfoListHead); -+ -+ return; -+ -+} /* end of nicFreePendingTxMsduInfoByNetwork() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This procedure is used to retrieve a CMD sequence number atomically -+* -+* @param prAdapter Pointer of ADAPTER_T -+* -+* @retval - UINT_8 -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT_8 nicIncreaseCmdSeqNum(IN P_ADAPTER_T prAdapter) -+{ -+ UINT_8 ucRetval; -+ -+ KAL_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(prAdapter); -+ -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_SEQ_NUM); -+ -+ prAdapter->ucCmdSeqNum++; -+ ucRetval = prAdapter->ucCmdSeqNum; -+ -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_SEQ_NUM); -+ -+ return ucRetval; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This procedure is used to retrieve a TX sequence number atomically -+* -+* @param prAdapter Pointer of ADAPTER_T -+* -+* @retval - UINT_8 -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT_8 nicIncreaseTxSeqNum(IN P_ADAPTER_T prAdapter) -+{ -+ UINT_8 ucRetval; -+ -+ KAL_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(prAdapter); -+ -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_SEQ_NUM); -+ -+ prAdapter->ucTxSeqNum++; -+ ucRetval = prAdapter->ucTxSeqNum; -+ -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_SEQ_NUM); -+ -+ return ucRetval; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This utility function is used to handle -+* media state change event -+* -+* @param -+* -+* @retval -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+nicMediaStateChange(IN P_ADAPTER_T prAdapter, -+ IN ENUM_NETWORK_TYPE_INDEX_T eNetworkType, IN P_EVENT_CONNECTION_STATUS prConnectionStatus) -+{ -+ P_GLUE_INFO_T prGlueInfo; -+ -+ ASSERT(prAdapter); -+ prGlueInfo = prAdapter->prGlueInfo; -+ -+ switch (eNetworkType) { -+ case NETWORK_TYPE_AIS_INDEX: -+ if (prConnectionStatus->ucMediaStatus == PARAM_MEDIA_STATE_DISCONNECTED) { /* disconnected */ -+ if (kalGetMediaStateIndicated(prGlueInfo) != PARAM_MEDIA_STATE_DISCONNECTED) { -+ -+ DBGLOG(NIC, TRACE, "DisByMC\n"); -+ kalIndicateStatusAndComplete(prGlueInfo, WLAN_STATUS_MEDIA_DISCONNECT, NULL, 0); -+ -+ prAdapter->rWlanInfo.u4SysTime = kalGetTimeTick(); -+ } -+ -+ /* reset buffered link quality information */ -+ prAdapter->fgIsLinkQualityValid = FALSE; -+ prAdapter->fgIsLinkRateValid = FALSE; -+ } else if (prConnectionStatus->ucMediaStatus == PARAM_MEDIA_STATE_CONNECTED) { /* connected */ -+ prAdapter->rWlanInfo.u4SysTime = kalGetTimeTick(); -+ -+ /* fill information for association result */ -+ prAdapter->rWlanInfo.rCurrBssId.rSsid.u4SsidLen = prConnectionStatus->ucSsidLen; -+ kalMemCopy(prAdapter->rWlanInfo.rCurrBssId.rSsid.aucSsid, -+ prConnectionStatus->aucSsid, prConnectionStatus->ucSsidLen); -+ kalMemCopy(prAdapter->rWlanInfo.rCurrBssId.arMacAddress, -+ prConnectionStatus->aucBssid, MAC_ADDR_LEN); -+ prAdapter->rWlanInfo.rCurrBssId.u4Privacy -+ = prConnectionStatus->ucEncryptStatus; /* @FIXME */ -+ prAdapter->rWlanInfo.rCurrBssId.rRssi = 0; /* @FIXME */ -+ prAdapter->rWlanInfo.rCurrBssId.eNetworkTypeInUse -+ = PARAM_NETWORK_TYPE_AUTOMODE; /* @FIXME */ -+ prAdapter->rWlanInfo.rCurrBssId.rConfiguration.u4BeaconPeriod -+ = prConnectionStatus->u2BeaconPeriod; -+ prAdapter->rWlanInfo.rCurrBssId.rConfiguration.u4ATIMWindow = prConnectionStatus->u2ATIMWindow; -+ prAdapter->rWlanInfo.rCurrBssId.rConfiguration.u4DSConfig = prConnectionStatus->u4FreqInKHz; -+ prAdapter->rWlanInfo.ucNetworkType = prConnectionStatus->ucNetworkType; -+ prAdapter->rWlanInfo.rCurrBssId.eOpMode -+ = (ENUM_PARAM_OP_MODE_T) prConnectionStatus->ucInfraMode; -+ -+ /* always indicate to OS according to MSDN (re-association/roaming) */ -+ if (kalGetMediaStateIndicated(prGlueInfo) != PARAM_MEDIA_STATE_CONNECTED) { -+ kalIndicateStatusAndComplete(prGlueInfo, WLAN_STATUS_MEDIA_CONNECT, NULL, 0); -+ } else { -+ /* connected -> connected : roaming ? */ -+ kalIndicateStatusAndComplete(prGlueInfo, WLAN_STATUS_ROAM_OUT_FIND_BEST, NULL, 0); -+ } -+ } -+ break; -+ -+#if CFG_ENABLE_BT_OVER_WIFI -+ case NETWORK_TYPE_BOW_INDEX: -+ break; -+#endif -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ case NETWORK_TYPE_P2P_INDEX: -+ break; -+#endif -+ default: -+ ASSERT(0); -+ } -+ -+ return WLAN_STATUS_SUCCESS; -+} /* nicMediaStateChange */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This utility function is used to convert between -+* frequency and channel number -+* -+* @param u4ChannelNum -+* -+* @retval - Frequency in unit of KHz, 0 for invalid channel number -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT_32 nicChannelNum2Freq(UINT_32 u4ChannelNum) -+{ -+ UINT_32 u4ChannelInMHz; -+ -+ if (u4ChannelNum >= 1 && u4ChannelNum <= 13) -+ u4ChannelInMHz = 2412 + (u4ChannelNum - 1) * 5; -+ else if (u4ChannelNum == 14) -+ u4ChannelInMHz = 2484; -+ else if (u4ChannelNum == 133) -+ u4ChannelInMHz = 3665; /* 802.11y */ -+ else if (u4ChannelNum == 137) -+ u4ChannelInMHz = 3685; /* 802.11y */ -+ else if (u4ChannelNum >= 34 && u4ChannelNum <= 165) -+ u4ChannelInMHz = 5000 + u4ChannelNum * 5; -+ else if (u4ChannelNum >= 183 && u4ChannelNum <= 196) -+ u4ChannelInMHz = 4000 + u4ChannelNum * 5; -+ else -+ u4ChannelInMHz = 0; -+ -+ return 1000 * u4ChannelInMHz; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This utility function is used to convert between -+* frequency and channel number -+* -+* @param u4FreqInKHz -+* -+* @retval - Frequency Number, 0 for invalid freqency -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT_32 nicFreq2ChannelNum(UINT_32 u4FreqInKHz) -+{ -+ switch (u4FreqInKHz) { -+ case 2412000: -+ return 1; -+ case 2417000: -+ return 2; -+ case 2422000: -+ return 3; -+ case 2427000: -+ return 4; -+ case 2432000: -+ return 5; -+ case 2437000: -+ return 6; -+ case 2442000: -+ return 7; -+ case 2447000: -+ return 8; -+ case 2452000: -+ return 9; -+ case 2457000: -+ return 10; -+ case 2462000: -+ return 11; -+ case 2467000: -+ return 12; -+ case 2472000: -+ return 13; -+ case 2484000: -+ return 14; -+ case 3665000: -+ return 133; /* 802.11y */ -+ case 3685000: -+ return 137; /* 802.11y */ -+ case 4915000: -+ return 183; -+ case 4920000: -+ return 184; -+ case 4925000: -+ return 185; -+ case 4930000: -+ return 186; -+ case 4935000: -+ return 187; -+ case 4940000: -+ return 188; -+ case 4945000: -+ return 189; -+ case 4960000: -+ return 192; -+ case 4980000: -+ return 196; -+ case 5170000: -+ return 34; -+ case 5180000: -+ return 36; -+ case 5190000: -+ return 38; -+ case 5200000: -+ return 40; -+ case 5210000: -+ return 42; -+ case 5220000: -+ return 44; -+ case 5230000: -+ return 46; -+ case 5240000: -+ return 48; -+ case 5250000: -+ return 50; -+ case 5260000: -+ return 52; -+ case 5270000: -+ return 54; -+ case 5280000: -+ return 56; -+ case 5290000: -+ return 58; -+ case 5300000: -+ return 60; -+ case 5320000: -+ return 64; -+ case 5500000: -+ return 100; -+ case 5520000: -+ return 104; -+ case 5540000: -+ return 108; -+ case 5560000: -+ return 112; -+ case 5580000: -+ return 116; -+ case 5600000: -+ return 120; -+ case 5620000: -+ return 124; -+ case 5640000: -+ return 128; -+ case 5660000: -+ return 132; -+ case 5680000: -+ return 136; -+ case 5700000: -+ return 140; -+ case 5745000: -+ return 149; -+ case 5765000: -+ return 153; -+ case 5785000: -+ return 157; -+ case 5805000: -+ return 161; -+ case 5825000: -+ return 165; -+ case 5845000: -+ return 169; -+ case 5865000: -+ return 173; -+ default: -+ return 0; -+ } -+} -+ -+/* firmware command wrapper */ -+/* NETWORK (WIFISYS) */ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This utility function is used to activate WIFISYS for specified network -+* -+* @param prAdapter Pointer of ADAPTER_T -+* eNetworkTypeIdx Index of network type -+* -+* @retval - -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS nicActivateNetwork(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx) -+{ -+ CMD_BSS_ACTIVATE_CTRL rCmdActivateCtrl; -+ P_BSS_INFO_T prBssInfo; -+ -+ ASSERT(prAdapter); -+ ASSERT(eNetworkTypeIdx < NETWORK_TYPE_INDEX_NUM); -+ -+ rCmdActivateCtrl.ucNetTypeIndex = (UINT_8) eNetworkTypeIdx; -+ rCmdActivateCtrl.ucActive = 1; -+ -+ if (((UINT_8) eNetworkTypeIdx) < NETWORK_TYPE_INDEX_NUM) { -+ prBssInfo = &prAdapter->rWifiVar.arBssInfo[eNetworkTypeIdx]; -+ prBssInfo->fg40mBwAllowed = FALSE; -+ prBssInfo->fgAssoc40mBwAllowed = FALSE; -+ } -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_BSS_ACTIVATE_CTRL, -+ TRUE, -+ FALSE, -+ FALSE, -+ NULL, NULL, sizeof(CMD_BSS_ACTIVATE_CTRL), (PUINT_8)&rCmdActivateCtrl, NULL, 0); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This utility function is used to deactivate WIFISYS for specified network -+* -+* @param prAdapter Pointer of ADAPTER_T -+* eNetworkTypeIdx Index of network type -+* -+* @retval - -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS nicDeactivateNetwork(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx) -+{ -+ WLAN_STATUS u4Status; -+ CMD_BSS_ACTIVATE_CTRL rCmdActivateCtrl; -+ -+ ASSERT(prAdapter); -+ ASSERT(eNetworkTypeIdx < NETWORK_TYPE_INDEX_NUM); -+ -+ rCmdActivateCtrl.ucNetTypeIndex = (UINT_8) eNetworkTypeIdx; -+ rCmdActivateCtrl.ucActive = 0; -+ -+ u4Status = wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_BSS_ACTIVATE_CTRL, -+ TRUE, -+ FALSE, -+ FALSE, -+ NULL, -+ NULL, sizeof(CMD_BSS_ACTIVATE_CTRL), (PUINT_8)&rCmdActivateCtrl, NULL, 0); -+ -+ /* free all correlated station records */ -+ cnmStaFreeAllStaByNetType(prAdapter, eNetworkTypeIdx, FALSE); -+ qmFreeAllByNetType(prAdapter, eNetworkTypeIdx); -+ nicFreePendingTxMsduInfoByNetwork(prAdapter, eNetworkTypeIdx); -+ kalClearSecurityFramesByNetType(prAdapter->prGlueInfo, eNetworkTypeIdx); -+ -+ return u4Status; -+} -+ -+/* BSS-INFO */ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This utility function is used to sync bss info with firmware -+* when a new BSS has been connected or disconnected -+* -+* @param prAdapter Pointer of ADAPTER_T -+* eNetworkTypeIdx Index of BSS-INFO type -+* -+* @retval - -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS nicUpdateBss(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx) -+{ -+ WLAN_STATUS u4Status; -+ P_BSS_INFO_T prBssInfo; -+ CMD_SET_BSS_INFO rCmdSetBssInfo; -+ -+ ASSERT(prAdapter); -+ ASSERT(eNetworkTypeIdx < NETWORK_TYPE_INDEX_NUM); -+ -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[eNetworkTypeIdx]); -+ -+ kalMemZero(&rCmdSetBssInfo, sizeof(CMD_SET_BSS_INFO)); -+ -+ rCmdSetBssInfo.ucNetTypeIndex = (UINT_8) eNetworkTypeIdx; -+ rCmdSetBssInfo.ucConnectionState = (UINT_8) prBssInfo->eConnectionState; -+ rCmdSetBssInfo.ucCurrentOPMode = (UINT_8) prBssInfo->eCurrentOPMode; -+ rCmdSetBssInfo.ucSSIDLen = (UINT_8) prBssInfo->ucSSIDLen; -+ kalMemCopy(rCmdSetBssInfo.aucSSID, prBssInfo->aucSSID, prBssInfo->ucSSIDLen); -+ COPY_MAC_ADDR(rCmdSetBssInfo.aucBSSID, prBssInfo->aucBSSID); -+ rCmdSetBssInfo.ucIsQBSS = (UINT_8) prBssInfo->fgIsQBSS; -+ rCmdSetBssInfo.ucNonHTBasicPhyType = prBssInfo->ucNonHTBasicPhyType; -+ rCmdSetBssInfo.u2OperationalRateSet = prBssInfo->u2OperationalRateSet; -+ rCmdSetBssInfo.u2BSSBasicRateSet = prBssInfo->u2BSSBasicRateSet; -+ rCmdSetBssInfo.ucPhyTypeSet = prBssInfo->ucPhyTypeSet; -+ rCmdSetBssInfo.fgHiddenSsidMode = prBssInfo->eHiddenSsidType; -+#if CFG_ENABLE_WIFI_DIRECT -+ if (prAdapter->fgIsP2PRegistered) -+ COPY_MAC_ADDR(rCmdSetBssInfo.aucOwnMac, prBssInfo->aucOwnMacAddr); -+#endif -+ -+ rlmFillSyncCmdParam(&rCmdSetBssInfo.rBssRlmParam, prBssInfo); -+ -+ rCmdSetBssInfo.fgWapiMode = (UINT_8) FALSE; -+ -+ if (rCmdSetBssInfo.ucNetTypeIndex == NETWORK_TYPE_AIS_INDEX) { -+ P_CONNECTION_SETTINGS_T prConnSettings = &(prAdapter->rWifiVar.rConnSettings); -+ -+ rCmdSetBssInfo.ucAuthMode = (UINT_8) prConnSettings->eAuthMode; -+ rCmdSetBssInfo.ucEncStatus = (UINT_8) prConnSettings->eEncStatus; -+ rCmdSetBssInfo.fgWapiMode = (UINT_8) prConnSettings->fgWapiMode; -+ } -+#if CFG_ENABLE_BT_OVER_WIFI -+ else if (rCmdSetBssInfo.ucNetTypeIndex == NETWORK_TYPE_BOW_INDEX) { -+ /* P_CONNECTION_SETTINGS_T prConnSettings = &(prAdapter->rWifiVar.rConnSettings); */ -+ rCmdSetBssInfo.ucAuthMode = (UINT_8) AUTH_MODE_WPA2_PSK; -+ rCmdSetBssInfo.ucEncStatus = (UINT_8) ENUM_ENCRYPTION3_KEY_ABSENT; -+ } -+#endif -+ else { -+#if CFG_ENABLE_WIFI_DIRECT -+ if (prAdapter->fgIsP2PRegistered) { -+ if (kalP2PGetCipher(prAdapter->prGlueInfo)) { -+ rCmdSetBssInfo.ucAuthMode = (UINT_8) AUTH_MODE_WPA2_PSK; -+ rCmdSetBssInfo.ucEncStatus = (UINT_8) ENUM_ENCRYPTION3_KEY_ABSENT; -+ } else { -+ rCmdSetBssInfo.ucAuthMode = (UINT_8) AUTH_MODE_OPEN; -+ rCmdSetBssInfo.ucEncStatus = (UINT_8) ENUM_ENCRYPTION_DISABLED; -+ } -+ /* Need the probe response to detect the PBC overlap */ -+ rCmdSetBssInfo.fgIsApMode = p2pFuncIsAPMode(prAdapter->rWifiVar.prP2pFsmInfo); -+ } -+#else -+ rCmdSetBssInfo.ucAuthMode = (UINT_8) AUTH_MODE_WPA2_PSK; -+ rCmdSetBssInfo.ucEncStatus = (UINT_8) ENUM_ENCRYPTION3_KEY_ABSENT; -+#endif -+ } -+ -+ if (eNetworkTypeIdx == NETWORK_TYPE_AIS_INDEX && -+ prBssInfo->eCurrentOPMode == OP_MODE_INFRASTRUCTURE && prBssInfo->prStaRecOfAP != NULL) { -+ rCmdSetBssInfo.ucStaRecIdxOfAP = prBssInfo->prStaRecOfAP->ucIndex; -+ -+ cnmAisInfraConnectNotify(prAdapter); -+ } -+#if CFG_ENABLE_WIFI_DIRECT -+ else if ((prAdapter->fgIsP2PRegistered) && -+ (eNetworkTypeIdx == NETWORK_TYPE_P2P_INDEX) && -+ (prBssInfo->eCurrentOPMode == OP_MODE_INFRASTRUCTURE) && (prBssInfo->prStaRecOfAP != NULL)) { -+ rCmdSetBssInfo.ucStaRecIdxOfAP = prBssInfo->prStaRecOfAP->ucIndex; -+ } -+#endif -+ -+#if CFG_ENABLE_BT_OVER_WIFI -+ else if (eNetworkTypeIdx == NETWORK_TYPE_BOW_INDEX && -+ prBssInfo->eCurrentOPMode == OP_MODE_BOW && prBssInfo->prStaRecOfAP != NULL) { -+ rCmdSetBssInfo.ucStaRecIdxOfAP = prBssInfo->prStaRecOfAP->ucIndex; -+ } -+#endif -+ else -+ rCmdSetBssInfo.ucStaRecIdxOfAP = STA_REC_INDEX_NOT_FOUND; -+ -+ u4Status = wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SET_BSS_INFO, -+ TRUE, -+ FALSE, -+ FALSE, -+ NULL, NULL, sizeof(CMD_SET_BSS_INFO), (PUINT_8)&rCmdSetBssInfo, NULL, 0); -+ -+ /* if BSS-INFO is going to be disconnected state, free all correlated station records */ -+ if (prBssInfo->eConnectionState == PARAM_MEDIA_STATE_DISCONNECTED) { -+ /* clear client list */ -+ bssClearClientList(prAdapter, prBssInfo); -+ -+ /* free all correlated station records */ -+ cnmStaFreeAllStaByNetType(prAdapter, eNetworkTypeIdx, FALSE); -+ qmFreeAllByNetType(prAdapter, eNetworkTypeIdx); -+ kalClearSecurityFramesByNetType(prAdapter->prGlueInfo, eNetworkTypeIdx); -+#if CFG_ENABLE_GTK_FRAME_FILTER -+ if (prBssInfo->prIpV4NetAddrList) -+ FREE_IPV4_NETWORK_ADDR_LIST(prBssInfo->prIpV4NetAddrList); -+#endif -+ } -+ -+ return u4Status; -+} -+ -+/* BSS-INFO Indication (PM) */ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This utility function is used to indicate PM that -+* a BSS has been created. (for AdHoc / P2P-GO) -+* -+* @param prAdapter Pointer of ADAPTER_T -+* eNetworkTypeIdx Index of BSS-INFO -+* -+* @retval - -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS nicPmIndicateBssCreated(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx) -+{ -+ P_BSS_INFO_T prBssInfo; -+ CMD_INDICATE_PM_BSS_CREATED rCmdIndicatePmBssCreated; -+ -+ ASSERT(prAdapter); -+ ASSERT(eNetworkTypeIdx < NETWORK_TYPE_INDEX_NUM); -+ -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[eNetworkTypeIdx]); -+ -+ rCmdIndicatePmBssCreated.ucNetTypeIndex = (UINT_8) eNetworkTypeIdx; -+ rCmdIndicatePmBssCreated.ucDtimPeriod = prBssInfo->ucDTIMPeriod; -+ rCmdIndicatePmBssCreated.u2BeaconInterval = prBssInfo->u2BeaconInterval; -+ rCmdIndicatePmBssCreated.u2AtimWindow = prBssInfo->u2ATIMWindow; -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_INDICATE_PM_BSS_CREATED, -+ TRUE, -+ FALSE, -+ FALSE, -+ NULL, -+ NULL, -+ sizeof(CMD_INDICATE_PM_BSS_CREATED), (PUINT_8)&rCmdIndicatePmBssCreated, NULL, 0); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This utility function is used to indicate PM that -+* a BSS has been connected -+* -+* @param prAdapter Pointer of ADAPTER_T -+* eNetworkTypeIdx Index of BSS-INFO -+* -+* @retval - -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS nicPmIndicateBssConnected(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx) -+{ -+ P_BSS_INFO_T prBssInfo; -+ CMD_INDICATE_PM_BSS_CONNECTED rCmdIndicatePmBssConnected; -+ -+ ASSERT(prAdapter); -+ ASSERT(eNetworkTypeIdx < NETWORK_TYPE_INDEX_NUM); -+ -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[eNetworkTypeIdx]); -+ -+ rCmdIndicatePmBssConnected.ucNetTypeIndex = (UINT_8) eNetworkTypeIdx; -+ rCmdIndicatePmBssConnected.ucDtimPeriod = prBssInfo->ucDTIMPeriod; -+ rCmdIndicatePmBssConnected.u2AssocId = prBssInfo->u2AssocId; -+ rCmdIndicatePmBssConnected.u2BeaconInterval = prBssInfo->u2BeaconInterval; -+ rCmdIndicatePmBssConnected.u2AtimWindow = prBssInfo->u2ATIMWindow; -+ -+ rCmdIndicatePmBssConnected.ucBmpDeliveryAC = prBssInfo->rPmProfSetupInfo.ucBmpDeliveryAC; -+ rCmdIndicatePmBssConnected.ucBmpTriggerAC = prBssInfo->rPmProfSetupInfo.ucBmpTriggerAC; -+ -+ /* DBGPRINTF("nicPmIndicateBssConnected: ucBmpDeliveryAC:0x%x, ucBmpTriggerAC:0x%x", */ -+ /* rCmdIndicatePmBssConnected.ucBmpDeliveryAC, */ -+ /* rCmdIndicatePmBssConnected.ucBmpTriggerAC); */ -+ -+ if ((eNetworkTypeIdx == NETWORK_TYPE_AIS_INDEX) -+#if CFG_ENABLE_WIFI_DIRECT -+ || ((eNetworkTypeIdx == NETWORK_TYPE_P2P_INDEX) && (prAdapter->fgIsP2PRegistered)) -+#endif -+ ) { -+ if (prBssInfo->eCurrentOPMode == OP_MODE_INFRASTRUCTURE) { -+ rCmdIndicatePmBssConnected.fgIsUapsdConnection = -+ (UINT_8) prBssInfo->prStaRecOfAP->fgIsUapsdSupported; -+ } else { -+ rCmdIndicatePmBssConnected.fgIsUapsdConnection = 0; /* @FIXME */ -+ } -+ } else { -+ rCmdIndicatePmBssConnected.fgIsUapsdConnection = 0; -+ } -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_INDICATE_PM_BSS_CONNECTED, -+ TRUE, -+ FALSE, -+ FALSE, -+ NULL, -+ NULL, -+ sizeof(CMD_INDICATE_PM_BSS_CONNECTED), -+ (PUINT_8)&rCmdIndicatePmBssConnected, NULL, 0); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This utility function is used to indicate PM that -+* a BSS has been disconnected -+* -+* @param prAdapter Pointer of ADAPTER_T -+* eNetworkTypeIdx Index of BSS-INFO -+* -+* @retval - -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS nicPmIndicateBssAbort(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx) -+{ -+ CMD_INDICATE_PM_BSS_ABORT rCmdIndicatePmBssAbort; -+ -+ ASSERT(prAdapter); -+ ASSERT(eNetworkTypeIdx < NETWORK_TYPE_INDEX_NUM); -+ -+ rCmdIndicatePmBssAbort.ucNetTypeIndex = (UINT_8) eNetworkTypeIdx; -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_INDICATE_PM_BSS_ABORT, -+ TRUE, -+ FALSE, -+ FALSE, -+ NULL, -+ NULL, -+ sizeof(CMD_INDICATE_PM_BSS_ABORT), (PUINT_8)&rCmdIndicatePmBssAbort, NULL, 0); -+} -+ -+WLAN_STATUS -+nicConfigPowerSaveProfile(IN P_ADAPTER_T prAdapter, -+ ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, PARAM_POWER_MODE ePwrMode, BOOLEAN fgEnCmdEvent) -+{ -+ DEBUGFUNC("nicConfigPowerSaveProfile"); -+ DBGLOG(NIC, TRACE, "eNetTypeIndex:%d, ePwrMode:%d, fgEnCmdEvent:%d\n", -+ eNetTypeIndex, ePwrMode, fgEnCmdEvent); -+ -+ ASSERT(prAdapter); -+ -+ if (eNetTypeIndex >= NETWORK_TYPE_INDEX_NUM) { -+ ASSERT(0); -+ return WLAN_STATUS_NOT_SUPPORTED; -+ } -+/* prAdapter->rWlanInfo.ePowerSaveMode.ucNetTypeIndex = eNetTypeIndex; */ -+/* prAdapter->rWlanInfo.ePowerSaveMode.ucPsProfile = (UINT_8)ePwrMode; */ -+ prAdapter->rWlanInfo.arPowerSaveMode[eNetTypeIndex].ucNetTypeIndex = eNetTypeIndex; -+ prAdapter->rWlanInfo.arPowerSaveMode[eNetTypeIndex].ucPsProfile = (UINT_8) ePwrMode; -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_POWER_SAVE_MODE, -+ TRUE, -+ FALSE, -+ (fgEnCmdEvent ? TRUE : FALSE), -+ (fgEnCmdEvent ? nicCmdEventSetCommon : NULL), -+ (fgEnCmdEvent ? nicOidCmdTimeoutCommon : NULL), -+ sizeof(CMD_PS_PROFILE_T), -+ (PUINT_8)&(prAdapter->rWlanInfo.arPowerSaveMode[eNetTypeIndex]), -+ NULL, sizeof(PARAM_POWER_MODE) -+ ); -+ -+} /* end of wlanoidSetAcpiDevicePowerStateMode() */ -+ -+WLAN_STATUS nicEnterCtiaMode(IN P_ADAPTER_T prAdapter, BOOLEAN fgEnterCtia, BOOLEAN fgEnCmdEvent) -+{ -+ CMD_SW_DBG_CTRL_T rCmdSwCtrl; -+ CMD_ACCESS_REG rCmdAccessReg; -+ WLAN_STATUS rWlanStatus; -+ -+ DEBUGFUNC("nicEnterCtiaMode"); -+ DBGLOG(NIC, TRACE, "nicEnterCtiaMode: %d\n", fgEnterCtia); -+ -+ ASSERT(prAdapter); -+ -+ rWlanStatus = WLAN_STATUS_SUCCESS; -+ -+ if (fgEnterCtia) { -+ /* 1. Disable On-Lin Scan */ -+ prAdapter->fgEnOnlineScan = FALSE; -+ -+ /* 3. Disable FIFO FULL no ack */ -+ rCmdAccessReg.u4Address = 0x60140028; -+ rCmdAccessReg.u4Data = 0x904; -+ wlanSendSetQueryCmd(prAdapter, CMD_ID_ACCESS_REG, TRUE, /* FALSE, */ -+ FALSE, /* TRUE, */ -+ FALSE, NULL, NULL, sizeof(CMD_ACCESS_REG), (PUINT_8)&rCmdAccessReg, NULL, 0); -+ -+ /* 4. Disable Roaming */ -+ rCmdSwCtrl.u4Id = 0x90000204; -+ rCmdSwCtrl.u4Data = 0x0; -+ wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SW_DBG_CTRL, -+ TRUE, -+ FALSE, -+ FALSE, NULL, NULL, sizeof(CMD_SW_DBG_CTRL_T), (PUINT_8)&rCmdSwCtrl, NULL, 0); -+ -+ rCmdSwCtrl.u4Id = 0x90000200; -+ rCmdSwCtrl.u4Data = 0x820000; -+ wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SW_DBG_CTRL, -+ TRUE, -+ FALSE, -+ FALSE, NULL, NULL, sizeof(CMD_SW_DBG_CTRL_T), (PUINT_8)&rCmdSwCtrl, NULL, 0); -+ -+ /* Disalbe auto tx power */ -+ rCmdSwCtrl.u4Id = 0xa0100003; -+ rCmdSwCtrl.u4Data = 0x0; -+ wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SW_DBG_CTRL, -+ TRUE, -+ FALSE, -+ FALSE, NULL, NULL, sizeof(CMD_SW_DBG_CTRL_T), (PUINT_8)&rCmdSwCtrl, NULL, 0); -+ -+ /* 2. Keep at CAM mode */ -+ { -+ PARAM_POWER_MODE ePowerMode; -+ -+ prAdapter->u4CtiaPowerMode = 0; -+ prAdapter->fgEnCtiaPowerMode = TRUE; -+ -+ ePowerMode = Param_PowerModeCAM; -+ rWlanStatus = nicConfigPowerSaveProfile(prAdapter, -+ NETWORK_TYPE_AIS_INDEX, ePowerMode, fgEnCmdEvent); -+ } -+ -+ /* 5. Disable Beacon Timeout Detection */ -+ prAdapter->fgDisBcnLostDetection = TRUE; -+ } else { -+ /* 1. Enaable On-Lin Scan */ -+ prAdapter->fgEnOnlineScan = TRUE; -+ -+ /* 3. Enable FIFO FULL no ack */ -+ rCmdAccessReg.u4Address = 0x60140028; -+ rCmdAccessReg.u4Data = 0x905; -+ wlanSendSetQueryCmd(prAdapter, CMD_ID_ACCESS_REG, TRUE, /* FALSE, */ -+ FALSE, /* TRUE, */ -+ FALSE, NULL, NULL, sizeof(CMD_ACCESS_REG), (PUINT_8)&rCmdAccessReg, NULL, 0); -+ -+ /* 4. Enable Roaming */ -+ rCmdSwCtrl.u4Id = 0x90000204; -+ rCmdSwCtrl.u4Data = 0x1; -+ wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SW_DBG_CTRL, -+ TRUE, -+ FALSE, -+ FALSE, NULL, NULL, sizeof(CMD_SW_DBG_CTRL_T), (PUINT_8)&rCmdSwCtrl, NULL, 0); -+ -+ rCmdSwCtrl.u4Id = 0x90000200; -+ rCmdSwCtrl.u4Data = 0x820000; -+ wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SW_DBG_CTRL, -+ TRUE, -+ FALSE, -+ FALSE, NULL, NULL, sizeof(CMD_SW_DBG_CTRL_T), (PUINT_8)&rCmdSwCtrl, NULL, 0); -+ -+ /* Enable auto tx power */ -+ /* */ -+ -+ rCmdSwCtrl.u4Id = 0xa0100003; -+ rCmdSwCtrl.u4Data = 0x1; -+ wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SW_DBG_CTRL, -+ TRUE, -+ FALSE, -+ FALSE, NULL, NULL, sizeof(CMD_SW_DBG_CTRL_T), (PUINT_8)&rCmdSwCtrl, NULL, 0); -+ -+ /* 2. Keep at Fast PS */ -+ { -+ PARAM_POWER_MODE ePowerMode; -+ -+ prAdapter->u4CtiaPowerMode = 2; -+ prAdapter->fgEnCtiaPowerMode = TRUE; -+ -+ ePowerMode = Param_PowerModeFast_PSP; -+ rWlanStatus = nicConfigPowerSaveProfile(prAdapter, -+ NETWORK_TYPE_AIS_INDEX, ePowerMode, fgEnCmdEvent); -+ } -+ -+ /* 5. Enable Beacon Timeout Detection */ -+ prAdapter->fgDisBcnLostDetection = FALSE; -+ -+ } -+ -+ return rWlanStatus; -+} /* end of nicEnterCtiaMode() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This utility function is used to indicate firmware domain -+* for beacon generation parameters -+* -+* @param prAdapter Pointer of ADAPTER_T -+* eIeUpdMethod, Update Method -+* eNetTypeIndex Index of Network -+* u2Capability Capability -+* aucIe Pointer to buffer of IEs -+* u2IELen Length of IEs -+* -+* @retval - WLAN_STATUS_SUCCESS -+* WLAN_STATUS_FAILURE -+* WLAN_STATUS_PENDING -+* WLAN_STATUS_INVALID_DATA -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+nicUpdateBeaconIETemplate(IN P_ADAPTER_T prAdapter, -+ IN ENUM_IE_UPD_METHOD_T eIeUpdMethod, -+ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, -+ IN UINT_16 u2Capability, IN PUINT_8 aucIe, IN UINT_16 u2IELen) -+{ -+ P_CMD_BEACON_TEMPLATE_UPDATE prCmdBcnUpdate; -+ UINT_16 u2CmdBufLen = 0; -+ P_GLUE_INFO_T prGlueInfo; -+ P_CMD_INFO_T prCmdInfo; -+ P_WIFI_CMD_T prWifiCmd; -+ UINT_8 ucCmdSeqNum; -+ -+ DEBUGFUNC("wlanUpdateBeaconIETemplate"); -+ -+ DBGLOG(NIC, LOUD, "\nnicUpdateBeaconIETemplate\n"); -+ -+ ASSERT(prAdapter); -+ prGlueInfo = prAdapter->prGlueInfo; -+ -+ if (u2IELen > MAX_IE_LENGTH) -+ return WLAN_STATUS_INVALID_DATA; -+ -+ if (eIeUpdMethod == IE_UPD_METHOD_UPDATE_RANDOM || eIeUpdMethod == IE_UPD_METHOD_UPDATE_ALL) { -+ u2CmdBufLen = OFFSET_OF(CMD_BEACON_TEMPLATE_UPDATE, aucIE) + u2IELen; -+ } else if (eIeUpdMethod == IE_UPD_METHOD_DELETE_ALL) { -+ u2CmdBufLen = OFFSET_OF(CMD_BEACON_TEMPLATE_UPDATE, u2IELen); -+ } else { -+ ASSERT(0); -+ return WLAN_STATUS_FAILURE; -+ } -+ -+ /* prepare command info */ -+ prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, (CMD_HDR_SIZE + u2CmdBufLen)); -+ if (!prCmdInfo) { -+ DBGLOG(NIC, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); -+ return WLAN_STATUS_FAILURE; -+ } -+ /* increase command sequence number */ -+ ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter); -+ DBGLOG(REQ, TRACE, "ucCmdSeqNum =%d\n", ucCmdSeqNum); -+ -+ /* Setup common CMD Info Packet */ -+ prCmdInfo->eCmdType = COMMAND_TYPE_NETWORK_IOCTL; -+ prCmdInfo->eNetworkType = eNetTypeIndex; -+ prCmdInfo->u2InfoBufLen = (UINT_16) (CMD_HDR_SIZE + u2CmdBufLen); -+ prCmdInfo->pfCmdDoneHandler = NULL; /* @FIXME */ -+ prCmdInfo->pfCmdTimeoutHandler = NULL; /* @FIXME */ -+ prCmdInfo->fgIsOid = FALSE; -+ prCmdInfo->ucCID = CMD_ID_UPDATE_BEACON_CONTENT; -+ prCmdInfo->fgSetQuery = TRUE; -+ prCmdInfo->fgNeedResp = FALSE; -+ prCmdInfo->fgDriverDomainMCR = FALSE; -+ prCmdInfo->ucCmdSeqNum = ucCmdSeqNum; -+ prCmdInfo->u4SetInfoLen = u2CmdBufLen; -+ prCmdInfo->pvInformationBuffer = NULL; -+ prCmdInfo->u4InformationBufferLength = 0; -+ -+ /* Setup WIFI_CMD_T (no payload) */ -+ prWifiCmd = (P_WIFI_CMD_T) (prCmdInfo->pucInfoBuffer); -+ prWifiCmd->u2TxByteCount_UserPriority = prCmdInfo->u2InfoBufLen; -+ prWifiCmd->ucCID = prCmdInfo->ucCID; -+ prWifiCmd->ucSetQuery = prCmdInfo->fgSetQuery; -+ prWifiCmd->ucSeqNum = prCmdInfo->ucCmdSeqNum; -+ -+ prCmdBcnUpdate = (P_CMD_BEACON_TEMPLATE_UPDATE) (prWifiCmd->aucBuffer); -+ -+ /* fill beacon updating command */ -+ prCmdBcnUpdate->ucUpdateMethod = (UINT_8) eIeUpdMethod; -+ prCmdBcnUpdate->ucNetTypeIndex = (UINT_8) eNetTypeIndex; -+ prCmdBcnUpdate->u2Capability = u2Capability; -+ prCmdBcnUpdate->u2IELen = u2IELen; -+ if (u2IELen > 0) -+ kalMemCopy(prCmdBcnUpdate->aucIE, aucIe, u2IELen); -+ -+ /* insert into prCmdQueue */ -+ kalEnqueueCommand(prGlueInfo, (P_QUE_ENTRY_T) prCmdInfo); -+ -+ /* wakeup txServiceThread later */ -+ GLUE_SET_EVENT(prGlueInfo); -+ return WLAN_STATUS_PENDING; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This utility function is used to initialization PHY related -+* varaibles -+* -+* @param prAdapter Pointer of ADAPTER_T -+* -+* @retval none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicSetAvailablePhyTypeSet(IN P_ADAPTER_T prAdapter) -+{ -+ P_CONNECTION_SETTINGS_T prConnSettings; -+ -+ ASSERT(prAdapter); -+ -+ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); -+ -+ if (prConnSettings->eDesiredPhyConfig >= PHY_CONFIG_NUM) { -+ ASSERT(0); -+ return; -+ } -+ -+ prAdapter->rWifiVar.ucAvailablePhyTypeSet = aucPhyCfg2PhyTypeSet[prConnSettings->eDesiredPhyConfig]; -+ -+ if (prAdapter->rWifiVar.ucAvailablePhyTypeSet & PHY_TYPE_BIT_ERP) -+ prAdapter->rWifiVar.eNonHTBasicPhyType2G4 = PHY_TYPE_ERP_INDEX; -+ /* NOTE(Kevin): Because we don't have N only mode, TBD */ -+ else { /* if (ucNonHTPhyTypeSet & PHY_TYPE_HR_DSSS_INDEX) */ -+ -+ prAdapter->rWifiVar.eNonHTBasicPhyType2G4 = PHY_TYPE_HR_DSSS_INDEX; -+ } -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This utility function is used to update WMM Parms -+* -+* @param prAdapter Pointer of ADAPTER_T -+* eNetworkTypeIdx Index of BSS-INFO -+* -+* @retval - -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS nicQmUpdateWmmParms(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx) -+{ -+ P_BSS_INFO_T prBssInfo; -+ CMD_UPDATE_WMM_PARMS_T rCmdUpdateWmmParms; -+ -+ ASSERT(prAdapter); -+ ASSERT(eNetworkTypeIdx < NETWORK_TYPE_INDEX_NUM); -+ -+ DBGLOG(QM, EVENT, "sizeof(AC_QUE_PARMS_T): %zu\n", sizeof(AC_QUE_PARMS_T)); -+ DBGLOG(QM, EVENT, "sizeof(CMD_UPDATE_WMM_PARMS): %zu\n", sizeof(CMD_UPDATE_WMM_PARMS_T)); -+ DBGLOG(QM, EVENT, "sizeof(WIFI_CMD_T): %zu\n", sizeof(WIFI_CMD_T)); -+ -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[eNetworkTypeIdx]); -+ rCmdUpdateWmmParms.ucNetTypeIndex = (UINT_8) eNetworkTypeIdx; -+ kalMemCopy(&rCmdUpdateWmmParms.arACQueParms[0], &prBssInfo->arACQueParms[0], (sizeof(AC_QUE_PARMS_T) * AC_NUM)); -+ -+ rCmdUpdateWmmParms.fgIsQBSS = prBssInfo->fgIsQBSS; -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_UPDATE_WMM_PARMS, -+ TRUE, -+ FALSE, -+ FALSE, -+ NULL, NULL, sizeof(CMD_UPDATE_WMM_PARMS_T), (PUINT_8)&rCmdUpdateWmmParms, NULL, 0); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This utility function is used to update TX power gain corresponding to -+* each band/modulation combination -+* -+* @param prAdapter Pointer of ADAPTER_T -+* prTxPwrParam Pointer of TX power parameters -+* -+* @retval WLAN_STATUS_PENDING -+* WLAN_STATUS_FAILURE -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS nicUpdateTxPower(IN P_ADAPTER_T prAdapter, IN P_CMD_TX_PWR_T prTxPwrParam) -+{ -+ DEBUGFUNC("nicUpdateTxPower"); -+ -+ ASSERT(prAdapter); -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SET_TX_PWR, -+ TRUE, -+ FALSE, FALSE, NULL, NULL, sizeof(CMD_TX_PWR_T), (PUINT_8) prTxPwrParam, NULL, 0); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This utility function is used to set auto tx power parameter -+* -+* @param prAdapter Pointer of ADAPTER_T -+* prTxPwrParam Pointer of Auto TX power parameters -+* -+* @retval WLAN_STATUS_PENDING -+* WLAN_STATUS_FAILURE -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS nicSetAutoTxPower(IN P_ADAPTER_T prAdapter, IN P_CMD_AUTO_POWER_PARAM_T prAutoPwrParam) -+{ -+ DEBUGFUNC("nicSetAutoTxPower"); -+ -+ ASSERT(prAdapter); -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SET_AUTOPWR_CTRL, -+ TRUE, -+ FALSE, -+ FALSE, -+ NULL, NULL, sizeof(CMD_AUTO_POWER_PARAM_T), (PUINT_8) prAutoPwrParam, NULL, 0); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This utility function is used to update TX power gain corresponding to -+* each band/modulation combination -+* -+* @param prAdapter Pointer of ADAPTER_T -+* prTxPwrParam Pointer of TX power parameters -+* -+* @retval WLAN_STATUS_PENDING -+* WLAN_STATUS_FAILURE -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS nicSetAutoTxPowerControl(IN P_ADAPTER_T prAdapter, IN P_CMD_TX_PWR_T prTxPwrParam) -+{ -+ DEBUGFUNC("nicUpdateTxPower"); -+ -+ ASSERT(prAdapter); -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SET_TX_PWR, -+ TRUE, -+ FALSE, FALSE, NULL, NULL, sizeof(CMD_TX_PWR_T), (PUINT_8) prTxPwrParam, NULL, 0); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This utility function is used to update power offset around 5GHz band -+* -+* @param prAdapter Pointer of ADAPTER_T -+* pr5GPwrOffset Pointer of 5GHz power offset parameter -+* -+* @retval WLAN_STATUS_PENDING -+* WLAN_STATUS_FAILURE -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS nicUpdate5GOffset(IN P_ADAPTER_T prAdapter, IN P_CMD_5G_PWR_OFFSET_T pr5GPwrOffset) -+{ -+ DEBUGFUNC("nicUpdate5GOffset"); -+ -+ ASSERT(prAdapter); -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SET_5G_PWR_OFFSET, -+ TRUE, -+ FALSE, -+ FALSE, NULL, NULL, sizeof(CMD_5G_PWR_OFFSET_T), (PUINT_8) pr5GPwrOffset, NULL, 0); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This utility function is used to update DPD calibration result -+* -+* @param prAdapter Pointer of ADAPTER_T -+* pr5GPwrOffset Pointer of parameter for DPD calibration result -+* -+* @retval WLAN_STATUS_PENDING -+* WLAN_STATUS_FAILURE -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS nicUpdateDPD(IN P_ADAPTER_T prAdapter, IN P_CMD_PWR_PARAM_T prDpdCalResult) -+{ -+ DEBUGFUNC("nicUpdateDPD"); -+ -+ ASSERT(prAdapter); -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SET_PWR_PARAM, -+ TRUE, -+ FALSE, -+ FALSE, NULL, NULL, sizeof(CMD_PWR_PARAM_T), (PUINT_8) prDpdCalResult, NULL, 0); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This utility function starts system service such as timer and -+* memory pools -+* -+* @param prAdapter Pointer of ADAPTER_T -+* -+* @retval none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicInitSystemService(IN P_ADAPTER_T prAdapter) -+{ -+ ASSERT(prAdapter); -+ -+ /* <1> Initialize MGMT Memory pool and STA_REC */ -+ cnmMemInit(prAdapter); -+ cnmStaRecInit(prAdapter); -+ cmdBufInitialize(prAdapter); -+ -+ /* <2> Mailbox Initialization */ -+ mboxInitialize(prAdapter); -+ -+ /* <3> Timer Initialization */ -+ cnmTimerInitialize(prAdapter); -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This utility function reset some specific system service, -+* such as STA-REC -+* -+* @param prAdapter Pointer of ADAPTER_T -+* -+* @retval none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicResetSystemService(IN P_ADAPTER_T prAdapter) -+{ -+ ASSERT(prAdapter); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This utility function is used to update WMM Parms -+* -+* @param prAdapter Pointer of ADAPTER_T -+* -+* @retval none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicUninitSystemService(IN P_ADAPTER_T prAdapter) -+{ -+ ASSERT(prAdapter); -+ -+ /* Timer Destruction */ -+ cnmTimerDestroy(prAdapter); -+ -+ /* Mailbox Destruction */ -+ mboxDestroy(prAdapter); -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This utility function is used to update WMM Parms -+* -+* @param prAdapter Pointer of ADAPTER_T -+* -+* @retval none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicInitMGMT(IN P_ADAPTER_T prAdapter, IN P_REG_INFO_T prRegInfo) -+{ -+ ASSERT(prAdapter); -+ -+ /* CNM Module - initialization */ -+ cnmInit(prAdapter); -+ -+ /* RLM Module - initialization */ -+ rlmFsmEventInit(prAdapter); -+ -+ /* SCN Module - initialization */ -+ scnInit(prAdapter); -+ -+ /* AIS Module - intiailization */ -+ aisInitializeConnectionSettings(prAdapter, prRegInfo); -+ aisFsmInit(prAdapter); -+ -+#if CFG_SUPPORT_ROAMING -+ /* Roaming Module - intiailization */ -+ roamingFsmInit(prAdapter); -+#endif /* CFG_SUPPORT_ROAMING */ -+ -+#if CFG_SUPPORT_SWCR -+ swCrDebugInit(prAdapter); -+#endif /* CFG_SUPPORT_SWCR */ -+ -+#if (CFG_SUPPORT_TDLS == 1) -+ TdlsexInit(prAdapter); -+#endif /* CFG_SUPPORT_TDLS */ -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This utility function is used to update WMM Parms -+* -+* @param prAdapter Pointer of ADAPTER_T -+* -+* @retval none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicUninitMGMT(IN P_ADAPTER_T prAdapter) -+{ -+ ASSERT(prAdapter); -+ -+#if CFG_SUPPORT_SWCR -+ swCrDebugUninit(prAdapter); -+#endif /* CFG_SUPPORT_SWCR */ -+ -+#if CFG_SUPPORT_ROAMING -+ /* Roaming Module - unintiailization */ -+ roamingFsmUninit(prAdapter); -+#endif /* CFG_SUPPORT_ROAMING */ -+ -+ /* AIS Module - unintiailization */ -+ aisFsmUninit(prAdapter); -+ -+ /* SCN Module - unintiailization */ -+ scnUninit(prAdapter); -+ -+ /* RLM Module - uninitialization */ -+ rlmFsmEventUninit(prAdapter); -+ -+ /* CNM Module - uninitialization */ -+ cnmUninit(prAdapter); -+ -+#if (CFG_SUPPORT_TDLS == 1) -+ TdlsexUninit(prAdapter); -+#endif /* CFG_SUPPORT_TDLS */ -+ -+} -+ -+#if (MT6620_E1_ASIC_HIFSYS_WORKAROUND == 1) -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This utility function is to inform firmware to enable MCU clock gating -+* -+* @param prAdapter Pointer of ADAPTER_T -+* -+* @retval none -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS nicEnableClockGating(IN P_ADAPTER_T prAdapter) -+{ -+ UINT_32 i, u4WHISR = 0; -+ -+ ASSERT(prAdapter); -+ -+ if (prAdapter->fgIsClockGatingEnabled == TRUE) -+ return WLAN_STATUS_SUCCESS; -+ -+ nicSetSwIntr(prAdapter, REQ_GATING_ENABLE_H2D_INT); -+ -+ i = 0; -+ while (i < GATING_CONTROL_POLL_LIMIT) { -+ if (kalIsCardRemoved(prAdapter->prGlueInfo) == TRUE || fgIsBusAccessFailed == TRUE) -+ return WLAN_STATUS_FAILURE; -+ -+ HAL_READ_INTR_STATUS(prAdapter, sizeof(UINT_32), (PUINT_8)&u4WHISR); -+ -+ if (u4WHISR & ACK_GATING_ENABLE_D2H_INT) { -+ prAdapter->fgIsClockGatingEnabled = TRUE; -+ return WLAN_STATUS_SUCCESS; -+ } -+ } -+ -+ ASSERT(0); -+ return WLAN_STATUS_PENDING; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This utility function is to inform firmware to disable MCU clock gating -+* -+* @param prAdapter Pointer of ADAPTER_T -+* -+* @retval none -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS nicDisableClockGating(IN P_ADAPTER_T prAdapter) -+{ -+ UINT_32 i, u4WHISR = 0; -+ -+ ASSERT(prAdapter); -+ -+ if (prAdapter->fgIsClockGatingEnabled == FALSE) -+ return WLAN_STATUS_SUCCESS; -+ -+ nicSetSwIntr(prAdapter, REQ_GATING_DISABLE_H2D_INT); -+ -+ i = 0; -+ while (i < GATING_CONTROL_POLL_LIMIT) { -+ if (kalIsCardRemoved(prAdapter->prGlueInfo) == TRUE || fgIsBusAccessFailed == TRUE) -+ return WLAN_STATUS_FAILURE; -+ -+ HAL_READ_INTR_STATUS(prAdapter, sizeof(UINT_32), (PUINT_8)&u4WHISR); -+ -+ if (u4WHISR & ACK_GATING_DISABLE_D2H_INT) { -+ prAdapter->fgIsClockGatingEnabled = FALSE; -+ return WLAN_STATUS_SUCCESS; -+ } -+ } -+ -+ ASSERT(0); -+ return WLAN_STATUS_PENDING; -+} -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is invoked to buffer scan result -+* -+* @param prAdapter Pointer to the Adapter structure. -+* @param rMacAddr BSSID -+* @param prSsid Pointer to SSID -+* @param u4Privacy Privacy settings (0: Open / 1: WEP/WPA/WPA2 enabled) -+* @param rRssi Received Strength (-10 ~ -200 dBm) -+* @param eNetworkType Network Type (a/b/g) -+* @param prConfiguration Network Parameter -+* @param eOpMode Infra/Ad-Hoc -+* @param rSupportedRates Supported basic rates -+* @param u2IELength IE Length -+* @param pucIEBuf Pointer to Information Elements(IEs) -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+nicAddScanResult(IN P_ADAPTER_T prAdapter, -+ IN PARAM_MAC_ADDRESS rMacAddr, -+ IN P_PARAM_SSID_T prSsid, -+ IN UINT_32 u4Privacy, -+ IN PARAM_RSSI rRssi, -+ IN ENUM_PARAM_NETWORK_TYPE_T eNetworkType, -+ IN P_PARAM_802_11_CONFIG_T prConfiguration, -+ IN ENUM_PARAM_OP_MODE_T eOpMode, -+ IN PARAM_RATES_EX rSupportedRates, IN UINT_16 u2IELength, IN PUINT_8 pucIEBuf) -+{ -+ BOOLEAN bReplace; -+ UINT_32 i; -+ UINT_32 u4IdxWeakest = 0; -+ PARAM_RSSI rWeakestRssi; -+ UINT_32 u4BufferSize; -+ -+ ASSERT(prAdapter); -+ -+ rWeakestRssi = (PARAM_RSSI) INT_MAX; -+ u4BufferSize = sizeof(prAdapter->rWlanInfo.aucScanIEBuf) / sizeof(prAdapter->rWlanInfo.aucScanIEBuf[0]); -+ -+ bReplace = FALSE; -+ -+ /* decide to replace or add */ -+ for (i = 0; i < prAdapter->rWlanInfo.u4ScanResultNum; i++) { -+ /* find weakest entry && not connected one */ -+ if (UNEQUAL_MAC_ADDR -+ (prAdapter->rWlanInfo.arScanResult[i].arMacAddress, prAdapter->rWlanInfo.rCurrBssId.arMacAddress) -+ && prAdapter->rWlanInfo.arScanResult[i].rRssi < rWeakestRssi) { -+ u4IdxWeakest = i; -+ rWeakestRssi = prAdapter->rWlanInfo.arScanResult[i].rRssi; -+ } -+ -+ if (prAdapter->rWlanInfo.arScanResult[i].eOpMode == eOpMode && -+ EQUAL_MAC_ADDR(&(prAdapter->rWlanInfo.arScanResult[i].arMacAddress), rMacAddr) && -+ (EQUAL_SSID(prAdapter->rWlanInfo.arScanResult[i].rSsid.aucSsid, -+ prAdapter->rWlanInfo.arScanResult[i].rSsid.u4SsidLen, -+ prSsid->aucSsid, prSsid->u4SsidLen) -+ || prAdapter->rWlanInfo.arScanResult[i].rSsid.u4SsidLen == 0)) { -+ /* replace entry */ -+ bReplace = TRUE; -+ -+ /* free IE buffer then zero */ -+ nicFreeScanResultIE(prAdapter, i); -+ kalMemZero(&(prAdapter->rWlanInfo.arScanResult[i]), OFFSET_OF(PARAM_BSSID_EX_T, aucIEs)); -+ -+ /* then fill buffer */ -+ prAdapter->rWlanInfo.arScanResult[i].u4Length = -+ OFFSET_OF(PARAM_BSSID_EX_T, aucIEs) + u2IELength; -+ COPY_MAC_ADDR(prAdapter->rWlanInfo.arScanResult[i].arMacAddress, rMacAddr); -+ COPY_SSID(prAdapter->rWlanInfo.arScanResult[i].rSsid.aucSsid, -+ prAdapter->rWlanInfo.arScanResult[i].rSsid.u4SsidLen, -+ prSsid->aucSsid, prSsid->u4SsidLen); -+ prAdapter->rWlanInfo.arScanResult[i].u4Privacy = u4Privacy; -+ prAdapter->rWlanInfo.arScanResult[i].rRssi = rRssi; -+ prAdapter->rWlanInfo.arScanResult[i].eNetworkTypeInUse = eNetworkType; -+ kalMemCopy(&(prAdapter->rWlanInfo.arScanResult[i].rConfiguration), -+ prConfiguration, sizeof(PARAM_802_11_CONFIG_T)); -+ prAdapter->rWlanInfo.arScanResult[i].eOpMode = eOpMode; -+ kalMemCopy((prAdapter->rWlanInfo.arScanResult[i].rSupportedRates), -+ rSupportedRates, sizeof(PARAM_RATES_EX)); -+ prAdapter->rWlanInfo.arScanResult[i].u4IELength = (UINT_32) u2IELength; -+ -+ /* IE - allocate buffer and update pointer */ -+ if (u2IELength > 0) { -+ if (ALIGN_4(u2IELength) + prAdapter->rWlanInfo.u4ScanIEBufferUsage <= u4BufferSize) { -+ kalMemCopy(& -+ (prAdapter-> -+ rWlanInfo.aucScanIEBuf[prAdapter->rWlanInfo.u4ScanIEBufferUsage]), -+ pucIEBuf, u2IELength); -+ -+ prAdapter->rWlanInfo.apucScanResultIEs[i] = -+ &(prAdapter-> -+ rWlanInfo.aucScanIEBuf[prAdapter->rWlanInfo.u4ScanIEBufferUsage]); -+ -+ prAdapter->rWlanInfo.u4ScanIEBufferUsage += ALIGN_4(u2IELength); -+ } else { -+ /* buffer is not enough */ -+ prAdapter->rWlanInfo.arScanResult[i].u4Length -= u2IELength; -+ prAdapter->rWlanInfo.arScanResult[i].u4IELength = 0; -+ prAdapter->rWlanInfo.apucScanResultIEs[i] = NULL; -+ } -+ } else { -+ prAdapter->rWlanInfo.apucScanResultIEs[i] = NULL; -+ } -+ -+ break; -+ } -+ } -+ -+ if (bReplace == FALSE) { -+ if (prAdapter->rWlanInfo.u4ScanResultNum < (CFG_MAX_NUM_BSS_LIST - 1)) { -+ i = prAdapter->rWlanInfo.u4ScanResultNum; -+ -+ /* zero */ -+ kalMemZero(&(prAdapter->rWlanInfo.arScanResult[i]), OFFSET_OF(PARAM_BSSID_EX_T, aucIEs)); -+ -+ /* then fill buffer */ -+ prAdapter->rWlanInfo.arScanResult[i].u4Length = -+ OFFSET_OF(PARAM_BSSID_EX_T, aucIEs) + u2IELength; -+ COPY_MAC_ADDR(prAdapter->rWlanInfo.arScanResult[i].arMacAddress, rMacAddr); -+ COPY_SSID(prAdapter->rWlanInfo.arScanResult[i].rSsid.aucSsid, -+ prAdapter->rWlanInfo.arScanResult[i].rSsid.u4SsidLen, -+ prSsid->aucSsid, prSsid->u4SsidLen); -+ prAdapter->rWlanInfo.arScanResult[i].u4Privacy = u4Privacy; -+ prAdapter->rWlanInfo.arScanResult[i].rRssi = rRssi; -+ prAdapter->rWlanInfo.arScanResult[i].eNetworkTypeInUse = eNetworkType; -+ kalMemCopy(&(prAdapter->rWlanInfo.arScanResult[i].rConfiguration), -+ prConfiguration, sizeof(PARAM_802_11_CONFIG_T)); -+ prAdapter->rWlanInfo.arScanResult[i].eOpMode = eOpMode; -+ kalMemCopy((prAdapter->rWlanInfo.arScanResult[i].rSupportedRates), -+ rSupportedRates, sizeof(PARAM_RATES_EX)); -+ prAdapter->rWlanInfo.arScanResult[i].u4IELength = (UINT_32) u2IELength; -+ -+ /* IE - allocate buffer and update pointer */ -+ if (u2IELength > 0) { -+ if (ALIGN_4(u2IELength) + prAdapter->rWlanInfo.u4ScanIEBufferUsage <= u4BufferSize) { -+ kalMemCopy(& -+ (prAdapter-> -+ rWlanInfo.aucScanIEBuf[prAdapter->rWlanInfo.u4ScanIEBufferUsage]), -+ pucIEBuf, u2IELength); -+ -+ prAdapter->rWlanInfo.apucScanResultIEs[i] = -+ &(prAdapter-> -+ rWlanInfo.aucScanIEBuf[prAdapter->rWlanInfo.u4ScanIEBufferUsage]); -+ -+ prAdapter->rWlanInfo.u4ScanIEBufferUsage += ALIGN_4(u2IELength); -+ } else { -+ /* buffer is not enough */ -+ prAdapter->rWlanInfo.arScanResult[i].u4Length -= u2IELength; -+ prAdapter->rWlanInfo.arScanResult[i].u4IELength = 0; -+ prAdapter->rWlanInfo.apucScanResultIEs[i] = NULL; -+ } -+ } else { -+ prAdapter->rWlanInfo.apucScanResultIEs[i] = NULL; -+ } -+ -+ prAdapter->rWlanInfo.u4ScanResultNum++; -+ } else if (rWeakestRssi != (PARAM_RSSI) INT_MAX) { -+ /* replace weakest one */ -+ i = u4IdxWeakest; -+ -+ /* free IE buffer then zero */ -+ nicFreeScanResultIE(prAdapter, i); -+ kalMemZero(&(prAdapter->rWlanInfo.arScanResult[i]), OFFSET_OF(PARAM_BSSID_EX_T, aucIEs)); -+ -+ /* then fill buffer */ -+ prAdapter->rWlanInfo.arScanResult[i].u4Length = -+ OFFSET_OF(PARAM_BSSID_EX_T, aucIEs) + u2IELength; -+ COPY_MAC_ADDR(prAdapter->rWlanInfo.arScanResult[i].arMacAddress, rMacAddr); -+ COPY_SSID(prAdapter->rWlanInfo.arScanResult[i].rSsid.aucSsid, -+ prAdapter->rWlanInfo.arScanResult[i].rSsid.u4SsidLen, -+ prSsid->aucSsid, prSsid->u4SsidLen); -+ prAdapter->rWlanInfo.arScanResult[i].u4Privacy = u4Privacy; -+ prAdapter->rWlanInfo.arScanResult[i].rRssi = rRssi; -+ prAdapter->rWlanInfo.arScanResult[i].eNetworkTypeInUse = eNetworkType; -+ kalMemCopy(&(prAdapter->rWlanInfo.arScanResult[i].rConfiguration), -+ prConfiguration, sizeof(PARAM_802_11_CONFIG_T)); -+ prAdapter->rWlanInfo.arScanResult[i].eOpMode = eOpMode; -+ kalMemCopy((prAdapter->rWlanInfo.arScanResult[i].rSupportedRates), -+ rSupportedRates, sizeof(PARAM_RATES_EX)); -+ prAdapter->rWlanInfo.arScanResult[i].u4IELength = (UINT_32) u2IELength; -+ -+ if (u2IELength > 0) { -+ /* IE - allocate buffer and update pointer */ -+ if (ALIGN_4(u2IELength) + prAdapter->rWlanInfo.u4ScanIEBufferUsage <= u4BufferSize) { -+ kalMemCopy(& -+ (prAdapter-> -+ rWlanInfo.aucScanIEBuf[prAdapter->rWlanInfo.u4ScanIEBufferUsage]), -+ pucIEBuf, u2IELength); -+ -+ prAdapter->rWlanInfo.apucScanResultIEs[i] = -+ &(prAdapter-> -+ rWlanInfo.aucScanIEBuf[prAdapter->rWlanInfo.u4ScanIEBufferUsage]); -+ -+ prAdapter->rWlanInfo.u4ScanIEBufferUsage += ALIGN_4(u2IELength); -+ } else { -+ /* buffer is not enough */ -+ prAdapter->rWlanInfo.arScanResult[i].u4Length -= u2IELength; -+ prAdapter->rWlanInfo.arScanResult[i].u4IELength = 0; -+ prAdapter->rWlanInfo.apucScanResultIEs[i] = NULL; -+ } -+ } else { -+ prAdapter->rWlanInfo.apucScanResultIEs[i] = NULL; -+ } -+ } -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is invoked to free IE buffer for dedicated scan result -+* -+* @param prAdapter Pointer to the Adapter structure. -+* @param u4Idx Index of Scan Result -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicFreeScanResultIE(IN P_ADAPTER_T prAdapter, IN UINT_32 u4Idx) -+{ -+ UINT_32 i; -+ PUINT_8 pucPivot, pucMovePivot; -+ UINT_32 u4MoveSize, u4FreeSize, u4ReserveSize; -+ -+ ASSERT(prAdapter); -+ ASSERT(u4Idx < CFG_MAX_NUM_BSS_LIST); -+ -+ if (prAdapter->rWlanInfo.arScanResult[u4Idx].u4IELength == 0 -+ || prAdapter->rWlanInfo.apucScanResultIEs[u4Idx] == NULL) { -+ return; -+ } -+ -+ u4FreeSize = ALIGN_4(prAdapter->rWlanInfo.arScanResult[u4Idx].u4IELength); -+ -+ pucPivot = prAdapter->rWlanInfo.apucScanResultIEs[u4Idx]; -+ pucMovePivot = (PUINT_8) ((ULONG) (prAdapter->rWlanInfo.apucScanResultIEs[u4Idx]) + u4FreeSize); -+ -+ u4ReserveSize = ((ULONG) pucPivot) - (ULONG) (&(prAdapter->rWlanInfo.aucScanIEBuf[0])); -+ u4MoveSize = prAdapter->rWlanInfo.u4ScanIEBufferUsage - u4ReserveSize - u4FreeSize; -+ -+ /* 1. rest of buffer to move forward */ -+ kalMemCopy(pucPivot, pucMovePivot, u4MoveSize); -+ -+ /* 1.1 modify pointers */ -+ for (i = 0; i < prAdapter->rWlanInfo.u4ScanResultNum; i++) { -+ if (i != u4Idx) { -+ if (prAdapter->rWlanInfo.apucScanResultIEs[i] >= pucMovePivot) { -+ prAdapter->rWlanInfo.apucScanResultIEs[i] = -+ (PUINT_8) ((ULONG) (prAdapter->rWlanInfo.apucScanResultIEs[i]) - u4FreeSize); -+ } -+ } -+ } -+ -+ /* 1.2 reset the freed one */ -+ prAdapter->rWlanInfo.arScanResult[u4Idx].u4IELength = 0; -+ prAdapter->rWlanInfo.apucScanResultIEs[i] = NULL; -+ -+ /* 2. reduce IE buffer usage */ -+ prAdapter->rWlanInfo.u4ScanIEBufferUsage -= u4FreeSize; -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is to hack parameters for WLAN TABLE for -+* fixed rate settings -+* -+* @param prAdapter Pointer to the Adapter structure. -+* @param eRateSetting -+* @param pu2DesiredNonHTRateSet, -+* @param pu2BSSBasicRateSet, -+* @param pucMcsSet -+* @param pucSupMcs32 -+* @param pu2HtCapInfo -+* -+* @return WLAN_STATUS_SUCCESS -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+nicUpdateRateParams(IN P_ADAPTER_T prAdapter, -+ IN ENUM_REGISTRY_FIXED_RATE_T eRateSetting, -+ IN PUINT_8 pucDesiredPhyTypeSet, -+ IN PUINT_16 pu2DesiredNonHTRateSet, -+ IN PUINT_16 pu2BSSBasicRateSet, -+ IN PUINT_8 pucMcsSet, IN PUINT_8 pucSupMcs32, IN PUINT_16 pu2HtCapInfo) -+{ -+ ASSERT(prAdapter); -+ ASSERT(eRateSetting > FIXED_RATE_NONE && eRateSetting < FIXED_RATE_NUM); -+ -+ switch (prAdapter->rWifiVar.eRateSetting) { -+ case FIXED_RATE_1M: -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HR_DSSS; -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_1M; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_1M; -+ *pucMcsSet = 0; -+ *pucSupMcs32 = 0; -+ *pu2HtCapInfo = 0; -+ break; -+ -+ case FIXED_RATE_2M: -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HR_DSSS; -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_2M; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_2M; -+ *pucMcsSet = 0; -+ *pucSupMcs32 = 0; -+ *pu2HtCapInfo = 0; -+ break; -+ -+ case FIXED_RATE_5_5M: -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HR_DSSS; -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_5_5M; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_5_5M; -+ *pucMcsSet = 0; -+ *pucSupMcs32 = 0; -+ *pu2HtCapInfo = 0; -+ break; -+ -+ case FIXED_RATE_11M: -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HR_DSSS; -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_11M; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_11M; -+ *pucMcsSet = 0; -+ *pucSupMcs32 = 0; -+ *pu2HtCapInfo = 0; -+ break; -+ -+ case FIXED_RATE_6M: -+ if ((*pucDesiredPhyTypeSet) & PHY_TYPE_BIT_ERP) -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_ERP; -+ else if ((*pucDesiredPhyTypeSet) & PHY_TYPE_BIT_OFDM) -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_OFDM; -+ -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_6M; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_6M; -+ *pucMcsSet = 0; -+ *pucSupMcs32 = 0; -+ *pu2HtCapInfo = 0; -+ break; -+ -+ case FIXED_RATE_9M: -+ if ((*pucDesiredPhyTypeSet) & PHY_TYPE_BIT_ERP) -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_ERP; -+ else if ((*pucDesiredPhyTypeSet) & PHY_TYPE_BIT_OFDM) -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_OFDM; -+ -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_9M; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_9M; -+ *pucMcsSet = 0; -+ *pucSupMcs32 = 0; -+ *pu2HtCapInfo = 0; -+ break; -+ -+ case FIXED_RATE_12M: -+ if ((*pucDesiredPhyTypeSet) & PHY_TYPE_BIT_ERP) -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_ERP; -+ else if ((*pucDesiredPhyTypeSet) & PHY_TYPE_BIT_OFDM) -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_OFDM; -+ -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_12M; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_12M; -+ *pucMcsSet = 0; -+ *pucSupMcs32 = 0; -+ *pu2HtCapInfo = 0; -+ break; -+ -+ case FIXED_RATE_18M: -+ if ((*pucDesiredPhyTypeSet) & PHY_TYPE_BIT_ERP) -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_ERP; -+ else if ((*pucDesiredPhyTypeSet) & PHY_TYPE_BIT_OFDM) -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_OFDM; -+ -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_18M; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_18M; -+ *pucMcsSet = 0; -+ *pucSupMcs32 = 0; -+ *pu2HtCapInfo = 0; -+ break; -+ -+ case FIXED_RATE_24M: -+ if ((*pucDesiredPhyTypeSet) & PHY_TYPE_BIT_ERP) -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_ERP; -+ else if ((*pucDesiredPhyTypeSet) & PHY_TYPE_BIT_OFDM) -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_OFDM; -+ -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_24M; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_24M; -+ *pucMcsSet = 0; -+ *pucSupMcs32 = 0; -+ *pu2HtCapInfo = 0; -+ break; -+ -+ case FIXED_RATE_36M: -+ if ((*pucDesiredPhyTypeSet) & PHY_TYPE_BIT_ERP) -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_ERP; -+ else if ((*pucDesiredPhyTypeSet) & PHY_TYPE_BIT_OFDM) -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_OFDM; -+ -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_36M; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_36M; -+ *pucMcsSet = 0; -+ *pucSupMcs32 = 0; -+ *pu2HtCapInfo = 0; -+ break; -+ -+ case FIXED_RATE_48M: -+ if ((*pucDesiredPhyTypeSet) & PHY_TYPE_BIT_ERP) -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_ERP; -+ else if ((*pucDesiredPhyTypeSet) & PHY_TYPE_BIT_OFDM) -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_OFDM; -+ -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_48M; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_48M; -+ *pucMcsSet = 0; -+ *pucSupMcs32 = 0; -+ *pu2HtCapInfo = 0; -+ break; -+ -+ case FIXED_RATE_54M: -+ if ((*pucDesiredPhyTypeSet) & PHY_TYPE_BIT_ERP) -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_ERP; -+ else if ((*pucDesiredPhyTypeSet) & PHY_TYPE_BIT_OFDM) -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_OFDM; -+ -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_54M; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_54M; -+ *pucMcsSet = 0; -+ *pucSupMcs32 = 0; -+ *pu2HtCapInfo = 0; -+ break; -+ -+ case FIXED_RATE_MCS0_20M_800NS: -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; -+ *pucMcsSet = HT_RATE_MCS0_INDEX; -+ *pucSupMcs32 = 0; -+ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH -+ | HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); -+ break; -+ -+ case FIXED_RATE_MCS1_20M_800NS: -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; -+ *pucMcsSet = HT_RATE_MCS1_INDEX; -+ *pucSupMcs32 = 0; -+ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH -+ | HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); -+ break; -+ -+ case FIXED_RATE_MCS2_20M_800NS: -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; -+ *pucMcsSet = HT_RATE_MCS2_INDEX; -+ *pucSupMcs32 = 0; -+ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH -+ | HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); -+ break; -+ -+ case FIXED_RATE_MCS3_20M_800NS: -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; -+ *pucMcsSet = HT_RATE_MCS3_INDEX; -+ *pucSupMcs32 = 0; -+ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH -+ | HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); -+ break; -+ -+ case FIXED_RATE_MCS4_20M_800NS: -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; -+ *pucMcsSet = HT_RATE_MCS4_INDEX; -+ *pucSupMcs32 = 0; -+ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH -+ | HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); -+ break; -+ -+ case FIXED_RATE_MCS5_20M_800NS: -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; -+ *pucMcsSet = HT_RATE_MCS5_INDEX; -+ *pucSupMcs32 = 0; -+ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH -+ | HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); -+ break; -+ -+ case FIXED_RATE_MCS6_20M_800NS: -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; -+ *pucMcsSet = HT_RATE_MCS6_INDEX; -+ *pucSupMcs32 = 0; -+ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH -+ | HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); -+ break; -+ -+ case FIXED_RATE_MCS7_20M_800NS: -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; -+ *pucMcsSet = HT_RATE_MCS7_INDEX; -+ *pucSupMcs32 = 0; -+ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH -+ | HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); -+ break; -+ -+ case FIXED_RATE_MCS0_20M_400NS: -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; -+ *pucMcsSet = HT_RATE_MCS0_INDEX; -+ *pucSupMcs32 = 0; -+ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); -+ (*pu2HtCapInfo) |= HT_CAP_INFO_SHORT_GI_20M; -+ break; -+ -+ case FIXED_RATE_MCS1_20M_400NS: -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; -+ *pucMcsSet = HT_RATE_MCS1_INDEX; -+ *pucSupMcs32 = 0; -+ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); -+ (*pu2HtCapInfo) |= HT_CAP_INFO_SHORT_GI_20M; -+ break; -+ -+ case FIXED_RATE_MCS2_20M_400NS: -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; -+ *pucMcsSet = HT_RATE_MCS2_INDEX; -+ *pucSupMcs32 = 0; -+ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); -+ (*pu2HtCapInfo) |= HT_CAP_INFO_SHORT_GI_20M; -+ break; -+ -+ case FIXED_RATE_MCS3_20M_400NS: -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; -+ *pucMcsSet = HT_RATE_MCS3_INDEX; -+ *pucSupMcs32 = 0; -+ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); -+ (*pu2HtCapInfo) |= HT_CAP_INFO_SHORT_GI_20M; -+ break; -+ -+ case FIXED_RATE_MCS4_20M_400NS: -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; -+ *pucMcsSet = HT_RATE_MCS4_INDEX; -+ *pucSupMcs32 = 0; -+ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); -+ (*pu2HtCapInfo) |= HT_CAP_INFO_SHORT_GI_20M; -+ break; -+ -+ case FIXED_RATE_MCS5_20M_400NS: -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; -+ *pucMcsSet = HT_RATE_MCS5_INDEX; -+ *pucSupMcs32 = 0; -+ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); -+ (*pu2HtCapInfo) |= HT_CAP_INFO_SHORT_GI_20M; -+ break; -+ -+ case FIXED_RATE_MCS6_20M_400NS: -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; -+ *pucMcsSet = HT_RATE_MCS6_INDEX; -+ *pucSupMcs32 = 0; -+ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); -+ (*pu2HtCapInfo) |= HT_CAP_INFO_SHORT_GI_20M; -+ break; -+ -+ case FIXED_RATE_MCS7_20M_400NS: -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; -+ *pucMcsSet = HT_RATE_MCS7_INDEX; -+ *pucSupMcs32 = 0; -+ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); -+ (*pu2HtCapInfo) |= HT_CAP_INFO_SHORT_GI_20M; -+ break; -+ -+ case FIXED_RATE_MCS0_40M_800NS: -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; -+ *pucMcsSet = HT_RATE_MCS0_INDEX; -+ *pucSupMcs32 = 0; -+ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); -+ (*pu2HtCapInfo) |= HT_CAP_INFO_SUP_CHNL_WIDTH; -+ break; -+ -+ case FIXED_RATE_MCS1_40M_800NS: -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; -+ *pucMcsSet = HT_RATE_MCS1_INDEX; -+ *pucSupMcs32 = 0; -+ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); -+ (*pu2HtCapInfo) |= HT_CAP_INFO_SUP_CHNL_WIDTH; -+ break; -+ -+ case FIXED_RATE_MCS2_40M_800NS: -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; -+ *pucMcsSet = HT_RATE_MCS2_INDEX; -+ *pucSupMcs32 = 0; -+ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); -+ (*pu2HtCapInfo) |= HT_CAP_INFO_SUP_CHNL_WIDTH; -+ break; -+ -+ case FIXED_RATE_MCS3_40M_800NS: -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; -+ *pucMcsSet = HT_RATE_MCS3_INDEX; -+ *pucSupMcs32 = 0; -+ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); -+ (*pu2HtCapInfo) |= HT_CAP_INFO_SUP_CHNL_WIDTH; -+ break; -+ -+ case FIXED_RATE_MCS4_40M_800NS: -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; -+ *pucMcsSet = HT_RATE_MCS4_INDEX; -+ *pucSupMcs32 = 0; -+ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); -+ (*pu2HtCapInfo) |= HT_CAP_INFO_SUP_CHNL_WIDTH; -+ break; -+ -+ case FIXED_RATE_MCS5_40M_800NS: -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; -+ *pucMcsSet = HT_RATE_MCS5_INDEX; -+ *pucSupMcs32 = 0; -+ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); -+ (*pu2HtCapInfo) |= HT_CAP_INFO_SUP_CHNL_WIDTH; -+ break; -+ -+ case FIXED_RATE_MCS6_40M_800NS: -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; -+ *pucMcsSet = HT_RATE_MCS6_INDEX; -+ *pucSupMcs32 = 0; -+ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); -+ (*pu2HtCapInfo) |= HT_CAP_INFO_SUP_CHNL_WIDTH; -+ break; -+ -+ case FIXED_RATE_MCS7_40M_800NS: -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; -+ *pucMcsSet = HT_RATE_MCS7_INDEX; -+ *pucSupMcs32 = 0; -+ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); -+ (*pu2HtCapInfo) |= HT_CAP_INFO_SUP_CHNL_WIDTH; -+ break; -+ -+ case FIXED_RATE_MCS32_800NS: -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; -+ *pucMcsSet = HT_RATE_MCS32_INDEX; -+ *pucSupMcs32 = 1; -+ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); -+ (*pu2HtCapInfo) |= HT_CAP_INFO_SUP_CHNL_WIDTH; -+ break; -+ -+ case FIXED_RATE_MCS0_40M_400NS: -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; -+ *pucMcsSet = HT_RATE_MCS0_INDEX; -+ *pucSupMcs32 = 0; -+ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_HT_GF); -+ (*pu2HtCapInfo) |= (HT_CAP_INFO_SUP_CHNL_WIDTH | HT_CAP_INFO_SHORT_GI_40M); -+ break; -+ -+ case FIXED_RATE_MCS1_40M_400NS: -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; -+ *pucMcsSet = HT_RATE_MCS1_INDEX; -+ *pucSupMcs32 = 0; -+ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_HT_GF); -+ (*pu2HtCapInfo) |= (HT_CAP_INFO_SUP_CHNL_WIDTH | HT_CAP_INFO_SHORT_GI_40M); -+ break; -+ -+ case FIXED_RATE_MCS2_40M_400NS: -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; -+ *pucMcsSet = HT_RATE_MCS2_INDEX; -+ *pucSupMcs32 = 0; -+ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_HT_GF); -+ (*pu2HtCapInfo) |= (HT_CAP_INFO_SUP_CHNL_WIDTH | HT_CAP_INFO_SHORT_GI_40M); -+ break; -+ -+ case FIXED_RATE_MCS3_40M_400NS: -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; -+ *pucMcsSet = HT_RATE_MCS3_INDEX; -+ *pucSupMcs32 = 0; -+ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_HT_GF); -+ (*pu2HtCapInfo) |= (HT_CAP_INFO_SUP_CHNL_WIDTH | HT_CAP_INFO_SHORT_GI_40M); -+ break; -+ -+ case FIXED_RATE_MCS4_40M_400NS: -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; -+ *pucMcsSet = HT_RATE_MCS4_INDEX; -+ *pucSupMcs32 = 0; -+ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_HT_GF); -+ (*pu2HtCapInfo) |= (HT_CAP_INFO_SUP_CHNL_WIDTH | HT_CAP_INFO_SHORT_GI_40M); -+ break; -+ -+ case FIXED_RATE_MCS5_40M_400NS: -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; -+ *pucMcsSet = HT_RATE_MCS5_INDEX; -+ *pucSupMcs32 = 0; -+ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_HT_GF); -+ (*pu2HtCapInfo) |= (HT_CAP_INFO_SUP_CHNL_WIDTH | HT_CAP_INFO_SHORT_GI_40M); -+ break; -+ -+ case FIXED_RATE_MCS6_40M_400NS: -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; -+ *pucMcsSet = HT_RATE_MCS6_INDEX; -+ *pucSupMcs32 = 0; -+ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_HT_GF); -+ (*pu2HtCapInfo) |= (HT_CAP_INFO_SUP_CHNL_WIDTH | HT_CAP_INFO_SHORT_GI_40M); -+ break; -+ -+ case FIXED_RATE_MCS7_40M_400NS: -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; -+ *pucMcsSet = HT_RATE_MCS7_INDEX; -+ *pucSupMcs32 = 0; -+ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_HT_GF); -+ (*pu2HtCapInfo) |= (HT_CAP_INFO_SUP_CHNL_WIDTH | HT_CAP_INFO_SHORT_GI_40M); -+ break; -+ -+ case FIXED_RATE_MCS32_400NS: -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; -+ *pucMcsSet = HT_RATE_MCS32_INDEX; -+ *pucSupMcs32 = 1; -+ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_HT_GF); -+ (*pu2HtCapInfo) |= (HT_CAP_INFO_SUP_CHNL_WIDTH | HT_CAP_INFO_SHORT_GI_40M); -+ break; -+ -+ default: -+ ASSERT(0); -+ } -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This utility function is used to write the register -+* -+* @param u4Address Register address -+* u4Value the value to be written -+* -+* @retval WLAN_STATUS_SUCCESS -+* WLAN_STATUS_FAILURE -+*/ -+/*----------------------------------------------------------------------------*/ -+ -+WLAN_STATUS nicWriteMcr(IN P_ADAPTER_T prAdapter, IN UINT_32 u4Address, IN UINT_32 u4Value) -+{ -+ CMD_ACCESS_REG rCmdAccessReg; -+ -+ rCmdAccessReg.u4Address = u4Address; -+ rCmdAccessReg.u4Data = u4Value; -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_ACCESS_REG, -+ TRUE, -+ FALSE, -+ FALSE, NULL, NULL, sizeof(CMD_ACCESS_REG), (PUINT_8) &rCmdAccessReg, NULL, 0); -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This utility function is used to modify the auto rate parameters -+* -+* @param u4ArSysParam0 see description below -+* u4ArSysParam1 -+* u4ArSysParam2 -+* u4ArSysParam3 -+* -+* -+* @retval WLAN_STATUS_SUCCESS -+* WLAN_STATUS_FAILURE -+* -+* @note -+* ArSysParam0[0:3] -> auto rate version (0:disable 1:version1 2:version2) -+* ArSysParam0[4:5]-> auto bw version (0:disable 1:version1 2:version2) -+* ArSysParam0[6:7]-> auto gi version (0:disable 1:version1 2:version2) -+* ArSysParam0[8:15]-> HT rate clear mask -+* ArSysParam0[16:31]-> Legacy rate clear mask -+* ArSysParam1[0:7]-> Auto Rate check weighting window -+* ArSysParam1[8:15]-> Auto Rate v1 Force Rate down -+* ArSysParam1[16:23]-> Auto Rate v1 PerH -+* ArSysParam1[24:31]-> Auto Rate v1 PerL -+* -+* Examples -+* ArSysParam0 = 1, -+* Enable auto rate version 1 -+* -+* ArSysParam0 = 983041, -+* Enable auto rate version 1 -+* Remove CCK 1M, 2M, 5.5M, 11M -+* -+* ArSysParam0 = 786433 -+* Enable auto rate version 1 -+* Remove CCK 5.5M 11M -+*/ -+/*----------------------------------------------------------------------------*/ -+ -+WLAN_STATUS -+nicRlmArUpdateParms(IN P_ADAPTER_T prAdapter, -+ IN UINT_32 u4ArSysParam0, -+ IN UINT_32 u4ArSysParam1, IN UINT_32 u4ArSysParam2, IN UINT_32 u4ArSysParam3) -+{ -+ UINT_8 ucArVer, ucAbwVer, ucAgiVer; -+ UINT_16 u2HtClrMask; -+ UINT_16 u2LegacyClrMask; -+ UINT_8 ucArCheckWindow; -+ UINT_8 ucArPerL; -+ UINT_8 ucArPerH; -+ UINT_8 ucArPerForceRateDownPer; -+ -+ ucArVer = (UINT_8) (u4ArSysParam0 & BITS(0, 3)); -+ ucAbwVer = (UINT_8) ((u4ArSysParam0 & BITS(4, 5)) >> 4); -+ ucAgiVer = (UINT_8) ((u4ArSysParam0 & BITS(6, 7)) >> 6); -+ u2HtClrMask = (UINT_16) ((u4ArSysParam0 & BITS(8, 15)) >> 8); -+ u2LegacyClrMask = (UINT_16) ((u4ArSysParam0 & BITS(16, 31)) >> 16); -+ -+#if 0 -+ ucArCheckWindow = (UINT_8) (u4ArSysParam1 & BITS(0, 7)); -+ ucArPerForceRateDownPer = (UINT_8) ((u4ArSysParam1 & BITS(8, 15) >> 8)); -+ ucArPerH = (UINT_8) ((u4ArSysParam1 & BITS(16, 23)) >> 16); -+ ucArPerL = (UINT_8) ((u4ArSysParam1 & BITS(24, 31)) >> 24); -+#endif -+ -+ ucArCheckWindow = (UINT_8) (u4ArSysParam1 & BITS(0, 7)); -+ ucArPerForceRateDownPer = (UINT_8) (((u4ArSysParam1 >> 8) & BITS(0, 7))); -+ ucArPerH = (UINT_8) (((u4ArSysParam1 >> 16) & BITS(0, 7))); -+ ucArPerL = (UINT_8) (((u4ArSysParam1 >> 24) & BITS(0, 7))); -+ -+ DBGLOG(NIC, INFO, "ArParam %u %u %u %u\n", u4ArSysParam0, u4ArSysParam1, u4ArSysParam2, u4ArSysParam3); -+ DBGLOG(NIC, INFO, "ArVer %u AbwVer %u AgiVer %u\n", ucArVer, ucAbwVer, ucAgiVer); -+ DBGLOG(NIC, INFO, "HtMask %x LegacyMask %x\n", u2HtClrMask, u2LegacyClrMask); -+ DBGLOG(NIC, INFO, -+ "CheckWin %u RateDownPer %u PerH %u PerL %u\n", ucArCheckWindow, ucArPerForceRateDownPer, ucArPerH, -+ ucArPerL); -+ -+#define SWCR_DATA_ADDR(MOD, ADDR) (0x90000000+(MOD<<8)+(ADDR)) -+#define SWCR_DATA_CMD(CATE, WRITE, INDEX, OPT0, OPT1) ((CATE<<24) | (WRITE<<23) | (INDEX<<16) | (OPT0 << 8) | OPT1) -+#define SWCR_DATA0 0x0 -+#define SWCR_DATA1 0x4 -+#define SWCR_DATA2 0x8 -+#define SWCR_DATA3 0xC -+#define SWCR_DATA4 0x10 -+#define SWCR_WRITE 1 -+#define SWCR_READ 0 -+ -+ if (ucArVer > 0) { -+ /* dummy = WiFi.WriteMCR(&h90000104, &h00000001) */ -+ /* dummy = WiFi.WriteMCR(&h90000100, &h00850000) */ -+ -+ nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, SWCR_DATA1), 1); -+ nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, SWCR_DATA0), SWCR_DATA_CMD(0, SWCR_WRITE, 5, 0, 0)); -+ } else { -+ nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, SWCR_DATA1), 0); -+ nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, SWCR_DATA0), SWCR_DATA_CMD(0, SWCR_WRITE, 5, 0, 0)); -+ } -+ -+ /* ucArVer 0: none 1:PER 2:Rcpi */ -+ nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, SWCR_DATA1), ucArVer); -+ nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, SWCR_DATA0), SWCR_DATA_CMD(0, SWCR_WRITE, 7, 0, 0)); -+ -+ /* Candidate rate Ht mask */ -+ nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, SWCR_DATA1), u2HtClrMask); -+ nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, SWCR_DATA0), SWCR_DATA_CMD(0, SWCR_WRITE, 0x1c, 0, 0)); -+ -+ /* Candidate rate legacy mask */ -+ nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, SWCR_DATA1), u2LegacyClrMask); -+ nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, SWCR_DATA0), SWCR_DATA_CMD(0, SWCR_WRITE, 0x1d, 0, 0)); -+ -+#if 0 -+ if (ucArCheckWindow != 0) { -+ /* TX DONE MCS INDEX CHECK STA RATE DOWN TH */ -+ nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, SWCR_DATA1), ucArCheckWindow); -+ nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, SWCR_DATA0), SWCR_DATA_CMD(0, SWCR_WRITE, 0x14, 0, 0)); -+ nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, SWCR_DATA1), ucArCheckWindow); -+ nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, SWCR_DATA0), SWCR_DATA_CMD(0, SWCR_WRITE, 0xc, 0, 0)); -+ } -+ -+ if (ucArPerForceRateDownPer != 0) { -+ nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, SWCR_DATA1), ucArPerForceRateDownPer); -+ nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, SWCR_DATA0), SWCR_DATA_CMD(0, SWCR_WRITE, 0x18, 0, 0)); -+ } -+ if (ucArPerH != 0) { -+ nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, SWCR_DATA1), ucArPerH); -+ nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, SWCR_DATA0), SWCR_DATA_CMD(0, SWCR_WRITE, 0x1, 0, 0)); -+ } -+ if (ucArPerL != 0) { -+ nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, SWCR_DATA1), ucArPerL); -+ nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, SWCR_DATA0), SWCR_DATA_CMD(0, SWCR_WRITE, 0x2, 0, 0)); -+ } -+#endif -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This utility function is used to enable roaming -+* -+* @param u4EnableRoaming -+* -+* -+* @retval WLAN_STATUS_SUCCESS -+* WLAN_STATUS_FAILURE -+* -+* @note -+* u4EnableRoaming -> Enable Romaing -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS nicRoamingUpdateParams(IN P_ADAPTER_T prAdapter, IN UINT_32 u4EnableRoaming) -+{ -+ P_CONNECTION_SETTINGS_T prConnSettings; -+ -+ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); -+ prConnSettings->fgIsEnableRoaming = ((u4EnableRoaming > 0) ? (TRUE) : (FALSE)); -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief dump firmware Assert message -+* -+* \param[in] -+* prAdapter -+* -+* \return -+* TRUE -+* FALSE -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicPrintFirmwareAssertInfo(IN P_ADAPTER_T prAdapter) -+{ -+ UINT_32 u4MailBox0, u4MailBox1; -+ UINT_32 line = 0; -+ UINT_8 aucAssertFile[7]; -+ UINT_32 u4ChipId; -+ -+#if CFG_SDIO_INTR_ENHANCE -+ u4MailBox0 = prAdapter->prSDIOCtrl->u4RcvMailbox0; -+ u4MailBox1 = prAdapter->prSDIOCtrl->u4RcvMailbox1; -+#else -+ nicGetMailbox(prAdapter, 0, &u4MailBox0); -+ nicGetMailbox(prAdapter, 1, &u4MailBox1); -+#endif -+ -+ line = u4MailBox0 & 0x0000FFFF; -+ -+ u4MailBox0 = ((u4MailBox0 >> 16) & 0x0000FFFF); -+ -+ kalMemCopy(&aucAssertFile[0], &u4MailBox0, 2); -+ kalMemCopy(&aucAssertFile[2], &u4MailBox1, 4); -+ -+ aucAssertFile[6] = '\0'; -+ -+#if defined(MT6620) -+ u4ChipId = 6620; -+#elif defined(MT6628) -+ u4ChipId = 6582; -+#endif -+ -+ kalPrint("\n[MT%u][wifi][Firmware] Assert at \"%s\" #%u\n\n", u4ChipId, aucAssertFile, line); -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is called to update Link Quality information -+* -+* @param prAdapter Pointer of Adapter Data Structure -+* eNetTypeIdx -+* prEventLinkQuality -+* cRssi -+* cLinkQuality -+* -+* @return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+nicUpdateLinkQuality(IN P_ADAPTER_T prAdapter, -+ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIdx, IN P_EVENT_LINK_QUALITY prEventLinkQuality) -+{ -+ ASSERT(prAdapter); -+ ASSERT(eNetTypeIdx < NETWORK_TYPE_INDEX_NUM); -+ ASSERT(prEventLinkQuality); -+ -+ switch (eNetTypeIdx) { -+ case NETWORK_TYPE_AIS_INDEX: -+ if (prAdapter->rWifiVar.arBssInfo[eNetTypeIdx].eConnectionState == PARAM_MEDIA_STATE_CONNECTED) { -+ /* check is to prevent RSSI to be updated by incorrect initial RSSI from hardware */ -+ /* buffer statistics for further query */ -+ if (prAdapter->fgIsLinkQualityValid == FALSE -+ || (kalGetTimeTick() - prAdapter->rLinkQualityUpdateTime) > CFG_LINK_QUALITY_VALID_PERIOD) { -+ nicUpdateRSSI(prAdapter, eNetTypeIdx, prEventLinkQuality->cRssi, -+ prEventLinkQuality->cLinkQuality); -+ } -+ -+ if (prAdapter->fgIsLinkRateValid == FALSE -+ || (kalGetTimeTick() - prAdapter->rLinkRateUpdateTime) > CFG_LINK_QUALITY_VALID_PERIOD) { -+ nicUpdateLinkSpeed(prAdapter, eNetTypeIdx, prEventLinkQuality->u2LinkSpeed); -+ } -+ } -+ break; -+#if CFG_ENABLE_WIFI_DIRECT && CFG_SUPPORT_P2P_RSSI_QUERY -+ case NETWORK_TYPE_P2P_INDEX: -+ if (prAdapter->fgIsP2pLinkQualityValid == FALSE -+ || (kalGetTimeTick() - prAdapter->rP2pLinkQualityUpdateTime) > CFG_LINK_QUALITY_VALID_PERIOD) { -+ P_EVENT_LINK_QUALITY_EX prEventLQEx = (P_EVENT_LINK_QUALITY_EX) prEventLinkQuality; -+ -+ nicUpdateRSSI(prAdapter, NETWORK_TYPE_P2P_INDEX, prEventLQEx->cRssiP2P, -+ prEventLQEx->cLinkQualityP2P); -+ } -+ break; -+#endif -+ default: -+ break; -+ -+ } -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is called to update RSSI and Link Quality information -+* -+* @param prAdapter Pointer of Adapter Data Structure -+* eNetTypeIdx -+* cRssi -+* cLinkQuality -+* -+* @return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+nicUpdateRSSI(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIdx, IN INT_8 cRssi, IN INT_8 cLinkQuality) -+{ -+ ASSERT(prAdapter); -+ ASSERT(eNetTypeIdx < NETWORK_TYPE_INDEX_NUM); -+ -+ switch (eNetTypeIdx) { -+ case NETWORK_TYPE_AIS_INDEX: -+ if (prAdapter->rWifiVar.arBssInfo[eNetTypeIdx].eConnectionState == PARAM_MEDIA_STATE_CONNECTED) { -+ prAdapter->fgIsLinkQualityValid = TRUE; -+ prAdapter->rLinkQualityUpdateTime = kalGetTimeTick(); -+ -+ prAdapter->rLinkQuality.cRssi = cRssi; -+ prAdapter->rLinkQuality.cLinkQuality = cLinkQuality; -+ -+ /* indicate to glue layer */ -+ kalUpdateRSSI(prAdapter->prGlueInfo, -+ KAL_NETWORK_TYPE_AIS_INDEX, -+ prAdapter->rLinkQuality.cRssi, prAdapter->rLinkQuality.cLinkQuality); -+ } -+ -+ break; -+#if CFG_ENABLE_WIFI_DIRECT -+#if CFG_SUPPORT_P2P_RSSI_QUERY -+ case NETWORK_TYPE_P2P_INDEX: -+ prAdapter->fgIsP2pLinkQualityValid = TRUE; -+ prAdapter->rP2pLinkQualityUpdateTime = kalGetTimeTick(); -+ -+ prAdapter->rP2pLinkQuality.cRssi = cRssi; -+ prAdapter->rP2pLinkQuality.cLinkQuality = cLinkQuality; -+ -+ kalUpdateRSSI(prAdapter->prGlueInfo, KAL_NETWORK_TYPE_P2P_INDEX, cRssi, cLinkQuality); -+ break; -+#endif -+#endif -+ default: -+ break; -+ -+ } -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is called to update Link Quality information -+* -+* @param prAdapter Pointer of Adapter Data Structure -+* eNetTypeIdx -+* prEventLinkQuality -+* cRssi -+* cLinkQuality -+* -+* @return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicUpdateLinkSpeed(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIdx, IN UINT_16 u2LinkSpeed) -+{ -+ ASSERT(prAdapter); -+ ASSERT(eNetTypeIdx < NETWORK_TYPE_INDEX_NUM); -+ -+ switch (eNetTypeIdx) { -+ case NETWORK_TYPE_AIS_INDEX: -+ if (prAdapter->rWifiVar.arBssInfo[eNetTypeIdx].eConnectionState == PARAM_MEDIA_STATE_CONNECTED) { -+ /* buffer statistics for further query */ -+ prAdapter->fgIsLinkRateValid = TRUE; -+ prAdapter->rLinkRateUpdateTime = kalGetTimeTick(); -+ -+ prAdapter->rLinkQuality.u2LinkSpeed = u2LinkSpeed; -+ } -+ break; -+ -+ default: -+ break; -+ -+ } -+ -+} -+ -+#if CFG_SUPPORT_RDD_TEST_MODE -+WLAN_STATUS nicUpdateRddTestMode(IN P_ADAPTER_T prAdapter, IN P_CMD_RDD_CH_T prRddChParam) -+{ -+ DEBUGFUNC("nicUpdateRddTestMode.\n"); -+ -+ ASSERT(prAdapter); -+ -+/* aisFsmScanRequest(prAdapter, NULL); */ -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SET_RDD_CH, -+ TRUE, -+ FALSE, FALSE, NULL, NULL, sizeof(CMD_RDD_CH_T), (PUINT_8) prRddChParam, NULL, 0); -+} -+#endif -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic_cmd_event.c b/drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic_cmd_event.c -new file mode 100644 -index 000000000000..3c9c24f9542b ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic_cmd_event.c -@@ -0,0 +1,1636 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/nic/nic_cmd_event.c#1 -+*/ -+ -+/*! \file nic_cmd_event.c -+ \brief Callback functions for Command packets. -+ -+ Various Event packet handlers which will be setup in the callback function of -+ a command packet. -+*/ -+ -+/* -+** Log: nic_cmd_event.c -+ * -+ * 04 10 2012 yuche.tsai -+ * NULL -+ * Update address for wifi direct connection issue. -+ * -+ * 06 15 2011 cm.chang -+ * [WCXRP00000785] [MT6620 Wi-Fi][Driver][FW] P2P/BOW MAC address is XOR with AIS MAC address -+ * P2P/BOW mac address XOR with local bit instead of OR -+ * -+ * 03 05 2011 wh.su -+ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code -+ * add the code to get the check rsponse and indicate to app. -+ * -+ * 03 02 2011 wh.su -+ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code -+ * Add security check code. -+ * -+ * 02 24 2011 cp.wu -+ * [WCXRP00000493] [MT6620 Wi-Fi][Driver] Do not indicate redundant disconnection to host when entering into RF -+ * test mode -+ * only indicate DISCONNECTION to host when entering RF test if necessary (connected -> disconnected cases) -+ * -+ * 01 20 2011 eddie.chen -+ * [WCXRP00000374] [MT6620 Wi-Fi][DRV] SW debug control -+ * Add Oid for sw control debug command -+ * -+ * 12 31 2010 cp.wu -+ * [WCXRP00000335] [MT6620 Wi-Fi][Driver] change to use milliseconds sleep instead of delay to avoid blocking to -+ * system scheduling -+ * change to use msleep() and shorten waiting interval to reduce blocking to other task while Wi-Fi driver is being -+ * loaded -+ * -+ * 12 01 2010 cp.wu -+ * [WCXRP00000223] MT6620 Wi-Fi][Driver][FW] Adopt NVRAM parameters when enter/exit RF test mode -+ * reload NVRAM settings before entering RF test mode and leaving from RF test mode. -+ * -+ * 11 01 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000150] [MT6620 Wi-Fi][Driver] -+ * Add implementation for querying current TX rate from firmware auto rate module -+ * 1) Query link speed (TX rate) from firmware directly with buffering mechanism to reduce overhead -+ * 2) Remove CNM CH-RECOVER event handling -+ * 3) cfg read/write API renamed with kal prefix for unified naming rules. -+ * -+ * 10 20 2010 cp.wu -+ * [WCXRP00000117] [MT6620 Wi-Fi][Driver] Add logic for suspending driver when MT6620 is not responding anymore -+ * use OID_CUSTOM_TEST_MODE as indication for driver reset -+ * by dropping pending TX packets -+ * -+ * 10 18 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000086] [MT6620 Wi-Fi][Driver] -+ * The mac address is all zero at android -+ * complete implementation of Android NVRAM access -+ * -+ * 09 21 2010 cp.wu -+ * [WCXRP00000053] [MT6620 Wi-Fi][Driver] Reset incomplete and might leads to BSOD when entering RF test with AIS -+ * associated -+ * Do a complete reset with STA-REC null checking for RF test re-entry -+ * -+ * 09 15 2010 yuche.tsai -+ * NULL -+ * Start to test AT GO only when P2P state is not IDLE. -+ * -+ * 09 09 2010 yuche.tsai -+ * NULL -+ * Add AT GO Test mode after MAC address available. -+ * -+ * 09 03 2010 kevin.huang -+ * NULL -+ * Refine #include sequence and solve recursive/nested #include issue -+ * -+ * 08 30 2010 cp.wu -+ * NULL -+ * eliminate klockwork errors -+ * -+ * 08 16 2010 cp.wu -+ * NULL -+ * Replace CFG_SUPPORT_BOW by CFG_ENABLE_BT_OVER_WIFI. -+ * There is no CFG_SUPPORT_BOW in driver domain source. -+ * -+ * 08 12 2010 cp.wu -+ * NULL -+ * [AIS-FSM] honor registry setting for adhoc running mode. (A/B/G) -+ * -+ * 08 11 2010 yuche.tsai -+ * NULL -+ * Add support for P2P Device Address query from FW. -+ * -+ * 08 03 2010 cp.wu -+ * NULL -+ * Centralize mgmt/system service procedures into independent calls. -+ * -+ * 08 02 2010 cp.wu -+ * NULL -+ * reset FSMs before entering RF test mode. -+ * -+ * 07 22 2010 cp.wu -+ * -+ * 1) refine AIS-FSM indent. -+ * 2) when entering RF Test mode, flush 802.1X frames as well -+ * 3) when entering D3 state, flush 802.1X frames as well -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 07 05 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) change fake BSS_DESC from channel 6 to channel 1 due to channel switching is not done yet. -+ * 2) after MAC address is queried from firmware, all related variables in driver domain should be updated as well -+ * -+ * 06 21 2010 wh.su -+ * [WPD00003840][MT6620 5931] Security migration -+ * remove duplicate variable for migration. -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 05 29 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * change upon request: indicate as disconnected in driver domain when leaving from RF test mode -+ * -+ * 05 24 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * do not clear scanning list array after disassociation -+ * -+ * 05 22 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) disable NETWORK_LAYER_ADDRESSES handling temporally. -+ * 2) finish statistics OIDs -+ * -+ * 05 22 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * change OID behavior to meet WHQL requirement. -+ * -+ * 05 20 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) integrate OID_GEN_NETWORK_LAYER_ADDRESSES with CMD_ID_SET_IP_ADDRESS -+ * 2) buffer statistics data for 2 seconds -+ * 3) use default value for adhoc parameters instead of 0 -+ * -+ * 05 19 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) do not take timeout mechanism for power mode oids -+ * 2) retrieve network type from connection status -+ * 3) after disassciation, set radio state to off -+ * 4) TCP option over IPv6 is supported -+ * -+ * 05 17 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * correct OID_802_11_DISASSOCIATE handling. -+ * -+ * 05 17 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * 1) add timeout handler mechanism for pending command packets -+ * 2) add p2p add/removal key -+ * -+ * 04 16 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * treat BUS access failure as kind of card removal. -+ * -+ * 04 14 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * information buffer for query oid/ioctl is now buffered in prCmdInfo -+ * * * * * * instead of glue-layer variable to improve multiple oid/ioctl capability -+ * -+ * 04 13 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * add framework for BT-over-Wi-Fi support. -+ * * * * * * * * * * * * * * 1) prPendingCmdInfo is replaced by queue for multiple handler capability -+ * * * * * * * * * * * * * * 2) command sequence number is now increased atomically -+ * * * * * * * * * * * * * * 3) private data could be hold and taken use for other purpose -+ * -+ * 04 07 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * accessing to firmware load/start address, and access to OID handling information -+ * are now handled in glue layer -+ * -+ * 04 07 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * rWlanInfo should be placed at adapter rather than glue due to most operations -+ * * * * are done in adapter layer. -+ * -+ * 04 06 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * add KAL API: kalFlushPendingTxPackets(), and take use of the API -+ * -+ * 04 06 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * eliminate direct access to prGlueInfo->rWlanInfo.eLinkAttr.ucMediaStreamMode from non-glue layer. -+ * -+ * 04 06 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * improve none-glude code portability -+ * -+ * 04 06 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * sync statistics data structure definition with firmware implementation -+ * -+ * 04 06 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * code refine: fgTestMode should be at adapter rather than glue due to the device/fw is also involved -+ * -+ * 04 06 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * eliminate direct access for prGlueInfo->fgIsCardRemoved in non-glue layer -+ * -+ * 03 30 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * statistics information OIDs are now handled by querying from firmware domain -+ * -+ * 03 26 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * indicate media stream mode after set is done -+ * -+ * 03 24 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * initial import for Linux port -+ * -+ * 03 03 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * implement custom OID: EEPROM read/write access -+ * -+ * 03 03 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * implement OID_802_3_MULTICAST_LIST oid handling -+ * -+ * 02 25 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * limit RSSI return value to micxxsoft defined range. -+ * -+ * 02 09 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1. Permanent and current MAC address are now retrieved by CMD/EVENT packets instead of hard-coded address -+ * * * * * * * 2. follow MSDN defined behavior when associates to another AP -+ * * * * * * * 3. for firmware download, packet size could be up to 2048 bytes -+ * -+ * 01 29 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * block until firmware finished RF test enter/leave then indicate completion to upper layer -+ * -+ * 01 29 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * when entering RF test mode and leaving from RF test mode, wait for W_FUNC_RDY bit to be asserted forever until it -+ * is set or card is removed. -+ * -+ * 01 27 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1. eliminate improper variable in rHifInfo -+ * * * * * * * * 2. block TX/ordinary OID when RF test mode is engaged -+ * * * * * * * * 3. wait until firmware finish operation when entering into and leaving from RF test mode -+ * * * * * * * * 4. correct some HAL implementation -+ * -+ * 01 26 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * Under WinXP with SDIO, use prGlueInfo->rHifInfo.pvInformationBuffer instead of prGlueInfo->pvInformationBuffer -+ * -+ * 01 22 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * implement following 802.11 OIDs: -+ * * * * * OID_802_11_RSSI, -+ * * * * * OID_802_11_RSSI_TRIGGER, -+ * * * * * OID_802_11_STATISTICS, -+ * * * * * OID_802_11_DISASSOCIATE, -+ * * * * * OID_802_11_POWER_MODE -+ * -+ * 01 21 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * implement OID_802_11_MEDIA_STREAM_MODE -+ * -+ * 12 30 2009 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) According to CMD/EVENT documentation v0.8, -+ * * * * * * * * OID_CUSTOM_TEST_RX_STATUS & OID_CUSTOM_TEST_TX_STATUS is no longer used, -+ * * * * * * * * and result is retrieved by get ATInfo instead -+ * * * * * * * * 2) add 4 counter for recording aggregation statistics -+** \main\maintrunk.MT6620WiFiDriver_Prj\10 2009-12-10 16:47:47 GMT mtk02752 -+** only handle MCR read when accessing FW domain register -+** \main\maintrunk.MT6620WiFiDriver_Prj\9 2009-12-08 17:37:28 GMT mtk02752 -+** * refine nicCmdEventQueryMcrRead -+** + add TxStatus/RxStatus for RF test QueryInformation OIDs -+** \main\maintrunk.MT6620WiFiDriver_Prj\8 2009-12-02 22:05:45 GMT mtk02752 -+** kalOidComplete() will decrease i4OidPendingCount -+** \main\maintrunk.MT6620WiFiDriver_Prj\7 2009-12-01 23:02:57 GMT mtk02752 -+** remove unnecessary spin locks -+** \main\maintrunk.MT6620WiFiDriver_Prj\6 2009-12-01 22:51:18 GMT mtk02752 -+** maintein i4OidPendingCount -+** \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-11-30 10:55:03 GMT mtk02752 -+** modify for compatibility -+** \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-11-23 14:46:32 GMT mtk02752 -+** add another version of command-done handler upon new event structure -+** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-04-29 15:42:33 GMT mtk01461 -+** Add comment -+** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-04-21 19:32:42 GMT mtk01461 -+** Add nicCmdEventSetCommon() for general set OID -+** \main\maintrunk.MT6620WiFiDriver_Prj\1 2009-04-21 01:40:35 GMT mtk01461 -+** Command Done Handler -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "precomp.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+VOID nicCmdEventQueryMcrRead(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) -+{ -+ UINT_32 u4QueryInfoLen; -+ P_PARAM_CUSTOM_MCR_RW_STRUCT_T prMcrRdInfo; -+ P_GLUE_INFO_T prGlueInfo; -+ P_CMD_ACCESS_REG prCmdAccessReg; -+ -+ ASSERT(prAdapter); -+ ASSERT(prCmdInfo); -+ ASSERT(pucEventBuf); -+ -+ /* 4 <2> Update information of OID */ -+ if (prCmdInfo->fgIsOid) { -+ prGlueInfo = prAdapter->prGlueInfo; -+ prCmdAccessReg = (P_CMD_ACCESS_REG) (pucEventBuf); -+ -+ u4QueryInfoLen = sizeof(PARAM_CUSTOM_MCR_RW_STRUCT_T); -+ -+ prMcrRdInfo = (P_PARAM_CUSTOM_MCR_RW_STRUCT_T) prCmdInfo->pvInformationBuffer; -+ prMcrRdInfo->u4McrOffset = prCmdAccessReg->u4Address; -+ prMcrRdInfo->u4McrData = prCmdAccessReg->u4Data; -+ -+ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS); -+ } -+ -+ return; -+ -+} -+ -+VOID nicCmdEventQuerySwCtrlRead(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) -+{ -+ UINT_32 u4QueryInfoLen; -+ P_PARAM_CUSTOM_SW_CTRL_STRUCT_T prSwCtrlInfo; -+ P_GLUE_INFO_T prGlueInfo; -+ P_CMD_SW_DBG_CTRL_T prCmdSwCtrl; -+ -+ ASSERT(prAdapter); -+ ASSERT(prCmdInfo); -+ ASSERT(pucEventBuf); -+ -+ /* 4 <2> Update information of OID */ -+ if (prCmdInfo->fgIsOid) { -+ prGlueInfo = prAdapter->prGlueInfo; -+ prCmdSwCtrl = (P_CMD_SW_DBG_CTRL_T) (pucEventBuf); -+ -+ u4QueryInfoLen = sizeof(PARAM_CUSTOM_SW_CTRL_STRUCT_T); -+ -+ prSwCtrlInfo = (P_PARAM_CUSTOM_SW_CTRL_STRUCT_T) prCmdInfo->pvInformationBuffer; -+ prSwCtrlInfo->u4Id = prCmdSwCtrl->u4Id; -+ prSwCtrlInfo->u4Data = prCmdSwCtrl->u4Data; -+ -+ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS); -+ } -+ -+ return; -+ -+} -+ -+VOID nicCmdEventSetCommon(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) -+{ -+ ASSERT(prAdapter); -+ ASSERT(prCmdInfo); -+ -+ if (prCmdInfo->fgIsOid) { -+ /* Update Set Information Length */ -+ kalOidComplete(prAdapter->prGlueInfo, -+ prCmdInfo->fgSetQuery, prCmdInfo->u4InformationBufferLength, WLAN_STATUS_SUCCESS); -+ } -+ -+} -+ -+VOID nicCmdEventSetDisassociate(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) -+{ -+ ASSERT(prAdapter); -+ ASSERT(prCmdInfo); -+ -+ if (prCmdInfo->fgIsOid) { -+ /* Update Set Information Length */ -+ kalOidComplete(prAdapter->prGlueInfo, prCmdInfo->fgSetQuery, 0, WLAN_STATUS_SUCCESS); -+ } -+ -+ DBGLOG(NIC, TRACE, "DisByCmdE\n"); -+ kalIndicateStatusAndComplete(prAdapter->prGlueInfo, WLAN_STATUS_MEDIA_DISCONNECT, NULL, 0); -+ -+#if !defined(LINUX) -+ prAdapter->fgIsRadioOff = TRUE; -+#endif -+ -+} -+ -+VOID nicCmdEventSetIpAddress(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) -+{ -+ UINT_32 u4Count; -+ -+ ASSERT(prAdapter); -+ ASSERT(prCmdInfo); -+ -+ u4Count = (prCmdInfo->u4SetInfoLen - OFFSET_OF(CMD_SET_NETWORK_ADDRESS_LIST, arNetAddress)) -+ / sizeof(IPV4_NETWORK_ADDRESS); -+ -+ if (prCmdInfo->fgIsOid) { -+ /* Update Set Information Length */ -+ kalOidComplete(prAdapter->prGlueInfo, -+ prCmdInfo->fgSetQuery, -+ OFFSET_OF(PARAM_NETWORK_ADDRESS_LIST, arAddress) + u4Count * -+ (OFFSET_OF(PARAM_NETWORK_ADDRESS, aucAddress) + sizeof(PARAM_NETWORK_ADDRESS_IP)), -+ WLAN_STATUS_SUCCESS); -+ } -+ -+} -+ -+VOID nicCmdEventQueryRfTestATInfo(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) -+{ -+ P_EVENT_TEST_STATUS prTestStatus, prQueryBuffer; -+ P_GLUE_INFO_T prGlueInfo; -+ UINT_32 u4QueryInfoLen; -+ -+ ASSERT(prAdapter); -+ ASSERT(prCmdInfo); -+ -+ prTestStatus = (P_EVENT_TEST_STATUS) pucEventBuf; -+ -+ if (prCmdInfo->fgIsOid) { -+ prGlueInfo = prAdapter->prGlueInfo; -+ prQueryBuffer = (P_EVENT_TEST_STATUS) prCmdInfo->pvInformationBuffer; -+ -+ kalMemCopy(prQueryBuffer, prTestStatus, sizeof(EVENT_TEST_STATUS)); -+ -+ u4QueryInfoLen = sizeof(EVENT_TEST_STATUS); -+ -+ /* Update Query Information Length */ -+ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS); -+ } -+ -+} -+ -+VOID nicCmdEventQueryLinkQuality(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) -+{ -+ PARAM_RSSI rRssi, *prRssi; -+ P_EVENT_LINK_QUALITY prLinkQuality; -+ P_GLUE_INFO_T prGlueInfo; -+ UINT_32 u4QueryInfoLen; -+ -+ ASSERT(prAdapter); -+ ASSERT(prCmdInfo); -+ -+ prLinkQuality = (P_EVENT_LINK_QUALITY) pucEventBuf; -+ -+ rRssi = (PARAM_RSSI) prLinkQuality->cRssi; /* ranged from (-128 ~ 30) in unit of dBm */ -+ DBGLOG(NIC, INFO, " %s: rRssi = %d\n", __func__, rRssi); -+ -+ if (prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX].eConnectionState == PARAM_MEDIA_STATE_CONNECTED) { -+ if (rRssi > PARAM_WHQL_RSSI_MAX_DBM) -+ rRssi = PARAM_WHQL_RSSI_MAX_DBM; -+ else if (rRssi < PARAM_WHQL_RSSI_MIN_DBM) -+ rRssi = PARAM_WHQL_RSSI_MIN_DBM; -+ } else { -+ rRssi = PARAM_WHQL_RSSI_MIN_DBM; -+ } -+ -+ if (prCmdInfo->fgIsOid) { -+ prGlueInfo = prAdapter->prGlueInfo; -+ prRssi = (PARAM_RSSI *) prCmdInfo->pvInformationBuffer; -+ -+ kalMemCopy(prRssi, &rRssi, sizeof(PARAM_RSSI)); -+ u4QueryInfoLen = sizeof(PARAM_RSSI); -+ -+ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS); -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This routine is in response of OID_GEN_LINK_SPEED query request -+* -+* @param prAdapter Pointer to the Adapter structure. -+* @param prCmdInfo Pointer to the pending command info -+* @param pucEventBuf -+* -+* @retval none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicCmdEventQueryLinkSpeed(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) -+{ -+ P_EVENT_LINK_QUALITY prLinkQuality; -+ P_GLUE_INFO_T prGlueInfo; -+ UINT_32 u4QueryInfoLen; -+ PUINT_32 pu4LinkSpeed; -+ -+ ASSERT(prAdapter); -+ ASSERT(prCmdInfo); -+ -+ prLinkQuality = (P_EVENT_LINK_QUALITY) pucEventBuf; -+ -+ if (prCmdInfo->fgIsOid) { -+ prGlueInfo = prAdapter->prGlueInfo; -+ pu4LinkSpeed = (PUINT_32) (prCmdInfo->pvInformationBuffer); -+ -+ *pu4LinkSpeed = prLinkQuality->u2LinkSpeed * 5000; -+ -+ u4QueryInfoLen = sizeof(UINT_32); -+ -+ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS); -+ } -+} -+ -+VOID nicCmdEventQueryStatistics(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) -+{ -+ P_PARAM_802_11_STATISTICS_STRUCT_T prStatistics; -+ P_EVENT_STATISTICS prEventStatistics; -+ P_GLUE_INFO_T prGlueInfo; -+ UINT_32 u4QueryInfoLen; -+ -+ ASSERT(prAdapter); -+ ASSERT(prCmdInfo); -+ -+ prEventStatistics = (P_EVENT_STATISTICS) pucEventBuf; -+ -+ if (prCmdInfo->fgIsOid) { -+ prGlueInfo = prAdapter->prGlueInfo; -+ -+ u4QueryInfoLen = sizeof(PARAM_802_11_STATISTICS_STRUCT_T); -+ prStatistics = (P_PARAM_802_11_STATISTICS_STRUCT_T) prCmdInfo->pvInformationBuffer; -+ -+ prStatistics->u4Length = sizeof(PARAM_802_11_STATISTICS_STRUCT_T); -+ prStatistics->rTransmittedFragmentCount = prEventStatistics->rTransmittedFragmentCount; -+ prStatistics->rMulticastTransmittedFrameCount = prEventStatistics->rMulticastTransmittedFrameCount; -+ prStatistics->rFailedCount = prEventStatistics->rFailedCount; -+ prStatistics->rRetryCount = prEventStatistics->rRetryCount; -+ prStatistics->rMultipleRetryCount = prEventStatistics->rMultipleRetryCount; -+ prStatistics->rRTSSuccessCount = prEventStatistics->rRTSSuccessCount; -+ prStatistics->rRTSFailureCount = prEventStatistics->rRTSFailureCount; -+ prStatistics->rACKFailureCount = prEventStatistics->rACKFailureCount; -+ prStatistics->rFrameDuplicateCount = prEventStatistics->rFrameDuplicateCount; -+ prStatistics->rReceivedFragmentCount = prEventStatistics->rReceivedFragmentCount; -+ prStatistics->rMulticastReceivedFrameCount = prEventStatistics->rMulticastReceivedFrameCount; -+ prStatistics->rFCSErrorCount = prEventStatistics->rFCSErrorCount; -+ prStatistics->rTKIPLocalMICFailures.QuadPart = 0; -+ prStatistics->rTKIPICVErrors.QuadPart = 0; -+ prStatistics->rTKIPCounterMeasuresInvoked.QuadPart = 0; -+ prStatistics->rTKIPReplays.QuadPart = 0; -+ prStatistics->rCCMPFormatErrors.QuadPart = 0; -+ prStatistics->rCCMPReplays.QuadPart = 0; -+ prStatistics->rCCMPDecryptErrors.QuadPart = 0; -+ prStatistics->rFourWayHandshakeFailures.QuadPart = 0; -+ prStatistics->rWEPUndecryptableCount.QuadPart = 0; -+ prStatistics->rWEPICVErrorCount.QuadPart = 0; -+ prStatistics->rDecryptSuccessCount.QuadPart = 0; -+ prStatistics->rDecryptFailureCount.QuadPart = 0; -+ -+ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS); -+ } -+} -+ -+VOID nicCmdEventEnterRfTest(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) -+{ -+#define WAIT_FW_READY_RETRY_CNT 200 -+ -+ UINT_32 u4WHISR = 0, u4Value = 0; -+ UINT_8 aucTxCount[8]; -+ UINT_16 u2RetryCnt = 0; -+ -+ ASSERT(prAdapter); -+ ASSERT(prCmdInfo); -+ -+ /* [driver-land] */ -+ prAdapter->fgTestMode = TRUE; -+ -+ /* 0. always indicate disconnection */ -+ if (kalGetMediaStateIndicated(prAdapter->prGlueInfo) != PARAM_MEDIA_STATE_DISCONNECTED) -+ kalIndicateStatusAndComplete(prAdapter->prGlueInfo, WLAN_STATUS_MEDIA_DISCONNECT, NULL, 0); -+ /* 1. Remove pending TX */ -+ nicTxRelease(prAdapter); -+ -+ /* 1.1 clear pending Security / Management Frames */ -+ kalClearSecurityFrames(prAdapter->prGlueInfo); -+ kalClearMgmtFrames(prAdapter->prGlueInfo); -+ -+ /* 1.2 clear pending TX packet queued in glue layer */ -+ kalFlushPendingTxPackets(prAdapter->prGlueInfo); -+ -+ /* 2. Reset driver-domain FSMs */ -+ nicUninitMGMT(prAdapter); -+ -+ nicResetSystemService(prAdapter); -+ nicInitMGMT(prAdapter, NULL); -+ -+ /* 3. Disable Interrupt */ -+ HAL_INTR_DISABLE(prAdapter); -+ -+ /* 4. Block til firmware completed entering into RF test mode */ -+ kalMsleep(500); -+ while (1) { -+ HAL_MCR_RD(prAdapter, MCR_WCIR, &u4Value); -+ -+ if (u4Value & WCIR_WLAN_READY) { -+ break; -+ } else if (kalIsCardRemoved(prAdapter->prGlueInfo) == TRUE || fgIsBusAccessFailed == TRUE || -+ kalIsResetting() || u2RetryCnt >= WAIT_FW_READY_RETRY_CNT) { -+ if (prCmdInfo->fgIsOid) { -+ /* Update Set Information Length */ -+ kalOidComplete(prAdapter->prGlueInfo, -+ prCmdInfo->fgSetQuery, -+ prCmdInfo->u4SetInfoLen, WLAN_STATUS_NOT_SUPPORTED); -+ -+ } -+ return; -+ } -+ kalMsleep(10); -+ u2RetryCnt++; -+ } -+ -+ /* 5. Clear Interrupt Status */ -+ HAL_READ_INTR_STATUS(prAdapter, 4, (PUINT_8)&u4WHISR); -+ if (HAL_IS_TX_DONE_INTR(u4WHISR)) -+ HAL_READ_TX_RELEASED_COUNT(prAdapter, aucTxCount); -+ /* 6. Reset TX Counter */ -+ nicTxResetResource(prAdapter); -+ -+ /* 7. Re-enable Interrupt */ -+ HAL_INTR_ENABLE(prAdapter); -+ -+ /* 8. completion indication */ -+ if (prCmdInfo->fgIsOid) { -+ /* Update Set Information Length */ -+ kalOidComplete(prAdapter->prGlueInfo, -+ prCmdInfo->fgSetQuery, prCmdInfo->u4SetInfoLen, WLAN_STATUS_SUCCESS); -+ } -+#if CFG_SUPPORT_NVRAM -+ /* 9. load manufacture data */ -+ wlanLoadManufactureData(prAdapter, kalGetConfiguration(prAdapter->prGlueInfo)); -+#endif -+ -+} -+ -+VOID nicCmdEventLeaveRfTest(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) -+{ -+#define WAIT_FW_READY_RETRY_CNT 200 -+ -+ UINT_32 u4WHISR = 0, u4Value = 0; -+ UINT_8 aucTxCount[8]; -+ UINT_16 u2RetryCnt = 0; -+ -+ ASSERT(prAdapter); -+ ASSERT(prCmdInfo); -+ -+ /* 1. Disable Interrupt */ -+ HAL_INTR_DISABLE(prAdapter); -+ -+ /* 2. Block til firmware completed leaving from RF test mode */ -+ kalMsleep(500); -+ while (1) { -+ HAL_MCR_RD(prAdapter, MCR_WCIR, &u4Value); -+ -+ if (u4Value & WCIR_WLAN_READY) { -+ break; -+ } else if (kalIsCardRemoved(prAdapter->prGlueInfo) == TRUE || fgIsBusAccessFailed == TRUE || -+ kalIsResetting() || u2RetryCnt >= WAIT_FW_READY_RETRY_CNT) { -+ if (prCmdInfo->fgIsOid) { -+ /* Update Set Information Length */ -+ kalOidComplete(prAdapter->prGlueInfo, -+ prCmdInfo->fgSetQuery, -+ prCmdInfo->u4SetInfoLen, WLAN_STATUS_NOT_SUPPORTED); -+ -+ } -+ return; -+ } -+ kalMsleep(10); -+ u2RetryCnt++; -+ } -+ -+ /* 3. Clear Interrupt Status */ -+ HAL_READ_INTR_STATUS(prAdapter, 4, (PUINT_8)&u4WHISR); -+ if (HAL_IS_TX_DONE_INTR(u4WHISR)) -+ HAL_READ_TX_RELEASED_COUNT(prAdapter, aucTxCount); -+ /* 4. Reset TX Counter */ -+ nicTxResetResource(prAdapter); -+ -+ /* 5. Re-enable Interrupt */ -+ HAL_INTR_ENABLE(prAdapter); -+ -+ /* 6. set driver-land variable */ -+ prAdapter->fgTestMode = FALSE; -+ -+ /* 7. completion indication */ -+ if (prCmdInfo->fgIsOid) { -+ /* Update Set Information Length */ -+ kalOidComplete(prAdapter->prGlueInfo, -+ prCmdInfo->fgSetQuery, prCmdInfo->u4SetInfoLen, WLAN_STATUS_SUCCESS); -+ } -+ -+ /* 8. Indicate as disconnected */ -+ if (kalGetMediaStateIndicated(prAdapter->prGlueInfo) != PARAM_MEDIA_STATE_DISCONNECTED) { -+ -+ kalIndicateStatusAndComplete(prAdapter->prGlueInfo, WLAN_STATUS_MEDIA_DISCONNECT, NULL, 0); -+ -+ prAdapter->rWlanInfo.u4SysTime = kalGetTimeTick(); -+ } -+#if CFG_SUPPORT_NVRAM -+ /* 9. load manufacture data */ -+ wlanLoadManufactureData(prAdapter, kalGetConfiguration(prAdapter->prGlueInfo)); -+#endif -+ -+ /* 10. Override network address */ -+ wlanUpdateNetworkAddress(prAdapter); -+ -+} -+ -+VOID nicCmdEventQueryAddress(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) -+{ -+ UINT_32 u4QueryInfoLen; -+ P_GLUE_INFO_T prGlueInfo; -+ P_EVENT_BASIC_CONFIG prEventBasicConfig; -+ -+ ASSERT(prAdapter); -+ ASSERT(prCmdInfo); -+ ASSERT(pucEventBuf); -+ -+ prEventBasicConfig = (P_EVENT_BASIC_CONFIG) (pucEventBuf); -+ -+ /* copy to adapter */ -+ kalMemCopy(&(prAdapter->rMyMacAddr), &(prEventBasicConfig->rMyMacAddr), MAC_ADDR_LEN); -+ -+ /* 4 <2> Update information of OID */ -+ if (prCmdInfo->fgIsOid) { -+ prGlueInfo = prAdapter->prGlueInfo; -+ -+ kalMemCopy(prCmdInfo->pvInformationBuffer, &(prEventBasicConfig->rMyMacAddr), MAC_ADDR_LEN); -+ u4QueryInfoLen = MAC_ADDR_LEN; -+ -+ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS); -+ } -+ /* 4 <3> Update new MAC address and all 3 networks */ -+ COPY_MAC_ADDR(prAdapter->rWifiVar.aucMacAddress, prAdapter->rMyMacAddr); -+ COPY_MAC_ADDR(prAdapter->rWifiVar.aucDeviceAddress, prAdapter->rMyMacAddr); -+ prAdapter->rWifiVar.aucDeviceAddress[0] ^= MAC_ADDR_LOCAL_ADMIN; -+ -+ COPY_MAC_ADDR(prAdapter->rWifiVar.aucInterfaceAddress, prAdapter->rMyMacAddr); -+ prAdapter->rWifiVar.aucInterfaceAddress[0] ^= MAC_ADDR_LOCAL_ADMIN; -+ -+ COPY_MAC_ADDR(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX].aucOwnMacAddr, prAdapter->rMyMacAddr); -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ if (prAdapter->fgIsP2PRegistered) { -+ COPY_MAC_ADDR(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX].aucOwnMacAddr, -+ prAdapter->rWifiVar.aucDeviceAddress); -+ } -+#endif -+ -+#if CFG_ENABLE_BT_OVER_WIFI -+ COPY_MAC_ADDR(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_BOW_INDEX].aucOwnMacAddr, -+ prAdapter->rWifiVar.aucDeviceAddress); -+#endif -+ -+#if CFG_TEST_WIFI_DIRECT_GO -+ if (prAdapter->rWifiVar.prP2pFsmInfo->eCurrentState == P2P_STATE_IDLE) { -+ wlanEnableP2pFunction(prAdapter); -+ -+ wlanEnableATGO(prAdapter); -+ } -+#endif -+ -+ kalUpdateMACAddress(prAdapter->prGlueInfo, prAdapter->rWifiVar.aucMacAddress); -+ -+} -+ -+VOID nicCmdEventQueryMcastAddr(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) -+{ -+ UINT_32 u4QueryInfoLen; -+ P_GLUE_INFO_T prGlueInfo; -+ P_EVENT_MAC_MCAST_ADDR prEventMacMcastAddr; -+ -+ ASSERT(prAdapter); -+ ASSERT(prCmdInfo); -+ ASSERT(pucEventBuf); -+ -+ /* 4 <2> Update information of OID */ -+ if (prCmdInfo->fgIsOid) { -+ prGlueInfo = prAdapter->prGlueInfo; -+ prEventMacMcastAddr = (P_EVENT_MAC_MCAST_ADDR) (pucEventBuf); -+ -+ u4QueryInfoLen = prEventMacMcastAddr->u4NumOfGroupAddr * MAC_ADDR_LEN; -+ -+ /* buffer length check */ -+ if (prCmdInfo->u4InformationBufferLength < u4QueryInfoLen) { -+ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_BUFFER_TOO_SHORT); -+ } else { -+ kalMemCopy(prCmdInfo->pvInformationBuffer, -+ prEventMacMcastAddr->arAddress, -+ prEventMacMcastAddr->u4NumOfGroupAddr * MAC_ADDR_LEN); -+ -+ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS); -+ } -+ } -+} -+ -+VOID nicCmdEventQueryEepromRead(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) -+{ -+ UINT_32 u4QueryInfoLen; -+ P_PARAM_CUSTOM_EEPROM_RW_STRUCT_T prEepromRdInfo; -+ P_GLUE_INFO_T prGlueInfo; -+ P_EVENT_ACCESS_EEPROM prEventAccessEeprom; -+ -+ ASSERT(prAdapter); -+ ASSERT(prCmdInfo); -+ ASSERT(pucEventBuf); -+ -+ /* 4 <2> Update information of OID */ -+ if (prCmdInfo->fgIsOid) { -+ prGlueInfo = prAdapter->prGlueInfo; -+ prEventAccessEeprom = (P_EVENT_ACCESS_EEPROM) (pucEventBuf); -+ -+ u4QueryInfoLen = sizeof(PARAM_CUSTOM_EEPROM_RW_STRUCT_T); -+ -+ prEepromRdInfo = (P_PARAM_CUSTOM_EEPROM_RW_STRUCT_T) prCmdInfo->pvInformationBuffer; -+ prEepromRdInfo->ucEepromIndex = (UINT_8) (prEventAccessEeprom->u2Offset); -+ prEepromRdInfo->u2EepromData = prEventAccessEeprom->u2Data; -+ -+ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS); -+ } -+ -+ return; -+ -+} -+ -+VOID nicCmdEventSetMediaStreamMode(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) -+{ -+ PARAM_MEDIA_STREAMING_INDICATION rParamMediaStreamIndication; -+ -+ ASSERT(prAdapter); -+ ASSERT(prCmdInfo); -+ -+ if (prCmdInfo->fgIsOid) { -+ /* Update Set Information Length */ -+ kalOidComplete(prAdapter->prGlueInfo, -+ prCmdInfo->fgSetQuery, prCmdInfo->u4SetInfoLen, WLAN_STATUS_SUCCESS); -+ } -+ -+ rParamMediaStreamIndication.rStatus.eStatusType = ENUM_STATUS_TYPE_MEDIA_STREAM_MODE; -+ rParamMediaStreamIndication.eMediaStreamMode = -+ prAdapter->rWlanInfo.eLinkAttr.ucMediaStreamMode == 0 ? ENUM_MEDIA_STREAM_OFF : ENUM_MEDIA_STREAM_ON; -+ -+ kalIndicateStatusAndComplete(prAdapter->prGlueInfo, -+ WLAN_STATUS_MEDIA_SPECIFIC_INDICATION, -+ (PVOID)&rParamMediaStreamIndication, sizeof(PARAM_MEDIA_STREAMING_INDICATION)); -+} -+ -+/* Statistics responder */ -+VOID nicCmdEventQueryXmitOk(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) -+{ -+ P_EVENT_STATISTICS prEventStatistics; -+ P_GLUE_INFO_T prGlueInfo; -+ UINT_32 u4QueryInfoLen; -+ PUINT_32 pu4Data; -+ PUINT_64 pu8Data; -+ -+ ASSERT(prAdapter); -+ ASSERT(prCmdInfo); -+ -+ prEventStatistics = (P_EVENT_STATISTICS) pucEventBuf; -+ -+ if (prCmdInfo->fgIsOid) { -+ prGlueInfo = prAdapter->prGlueInfo; -+ -+ if (prCmdInfo->u4InformationBufferLength == sizeof(UINT_32)) { -+ u4QueryInfoLen = sizeof(UINT_32); -+ -+ pu4Data = (PUINT_32) prCmdInfo->pvInformationBuffer; -+ *pu4Data = (UINT_32) prEventStatistics->rTransmittedFragmentCount.QuadPart; -+ } else { -+ u4QueryInfoLen = sizeof(UINT_64); -+ -+ pu8Data = (PUINT_64) prCmdInfo->pvInformationBuffer; -+ *pu8Data = prEventStatistics->rTransmittedFragmentCount.QuadPart; -+ } -+ -+ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS); -+ } -+} -+ -+VOID nicCmdEventQueryRecvOk(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) -+{ -+ P_EVENT_STATISTICS prEventStatistics; -+ P_GLUE_INFO_T prGlueInfo; -+ UINT_32 u4QueryInfoLen; -+ PUINT_32 pu4Data; -+ PUINT_64 pu8Data; -+ -+ ASSERT(prAdapter); -+ ASSERT(prCmdInfo); -+ -+ prEventStatistics = (P_EVENT_STATISTICS) pucEventBuf; -+ -+ if (prCmdInfo->fgIsOid) { -+ prGlueInfo = prAdapter->prGlueInfo; -+ -+ if (prCmdInfo->u4InformationBufferLength == sizeof(UINT_32)) { -+ u4QueryInfoLen = sizeof(UINT_32); -+ -+ pu4Data = (PUINT_32) prCmdInfo->pvInformationBuffer; -+ *pu4Data = (UINT_32) prEventStatistics->rReceivedFragmentCount.QuadPart; -+ } else { -+ u4QueryInfoLen = sizeof(UINT_64); -+ -+ pu8Data = (PUINT_64) prCmdInfo->pvInformationBuffer; -+ *pu8Data = prEventStatistics->rReceivedFragmentCount.QuadPart; -+ } -+ -+ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS); -+ } -+} -+ -+VOID nicCmdEventQueryXmitError(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) -+{ -+ P_EVENT_STATISTICS prEventStatistics; -+ P_GLUE_INFO_T prGlueInfo; -+ UINT_32 u4QueryInfoLen; -+ PUINT_32 pu4Data; -+ PUINT_64 pu8Data; -+ -+ ASSERT(prAdapter); -+ ASSERT(prCmdInfo); -+ -+ prEventStatistics = (P_EVENT_STATISTICS) pucEventBuf; -+ -+ if (prCmdInfo->fgIsOid) { -+ prGlueInfo = prAdapter->prGlueInfo; -+ -+ if (prCmdInfo->u4InformationBufferLength == sizeof(UINT_32)) { -+ u4QueryInfoLen = sizeof(UINT_32); -+ -+ pu4Data = (PUINT_32) prCmdInfo->pvInformationBuffer; -+ *pu4Data = (UINT_32) prEventStatistics->rFailedCount.QuadPart; -+ } else { -+ u4QueryInfoLen = sizeof(UINT_64); -+ -+ pu8Data = (PUINT_64) prCmdInfo->pvInformationBuffer; -+ *pu8Data = (UINT_64) prEventStatistics->rFailedCount.QuadPart; -+ } -+ -+ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS); -+ } -+} -+ -+VOID nicCmdEventQueryRecvError(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) -+{ -+ P_EVENT_STATISTICS prEventStatistics; -+ P_GLUE_INFO_T prGlueInfo; -+ UINT_32 u4QueryInfoLen; -+ PUINT_32 pu4Data; -+ PUINT_64 pu8Data; -+ -+ ASSERT(prAdapter); -+ ASSERT(prCmdInfo); -+ -+ prEventStatistics = (P_EVENT_STATISTICS) pucEventBuf; -+ -+ if (prCmdInfo->fgIsOid) { -+ prGlueInfo = prAdapter->prGlueInfo; -+ -+ if (prCmdInfo->u4InformationBufferLength == sizeof(UINT_32)) { -+ u4QueryInfoLen = sizeof(UINT_32); -+ -+ pu4Data = (PUINT_32) prCmdInfo->pvInformationBuffer; -+ *pu4Data = (UINT_32) prEventStatistics->rFCSErrorCount.QuadPart; -+ /* @FIXME, RX_ERROR_DROP_COUNT/RX_FIFO_FULL_DROP_COUNT is not calculated */ -+ } else { -+ u4QueryInfoLen = sizeof(UINT_64); -+ -+ pu8Data = (PUINT_64) prCmdInfo->pvInformationBuffer; -+ *pu8Data = prEventStatistics->rFCSErrorCount.QuadPart; -+ /* @FIXME, RX_ERROR_DROP_COUNT/RX_FIFO_FULL_DROP_COUNT is not calculated */ -+ } -+ -+ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS); -+ } -+} -+ -+VOID nicCmdEventQueryRecvNoBuffer(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) -+{ -+ P_EVENT_STATISTICS prEventStatistics; -+ P_GLUE_INFO_T prGlueInfo; -+ UINT_32 u4QueryInfoLen; -+ PUINT_32 pu4Data; -+ PUINT_64 pu8Data; -+ -+ ASSERT(prAdapter); -+ ASSERT(prCmdInfo); -+ -+ prEventStatistics = (P_EVENT_STATISTICS) pucEventBuf; -+ -+ if (prCmdInfo->fgIsOid) { -+ prGlueInfo = prAdapter->prGlueInfo; -+ -+ if (prCmdInfo->u4InformationBufferLength == sizeof(UINT_32)) { -+ u4QueryInfoLen = sizeof(UINT_32); -+ -+ pu4Data = (PUINT_32) prCmdInfo->pvInformationBuffer; -+ *pu4Data = 0; /* @FIXME? */ -+ } else { -+ u4QueryInfoLen = sizeof(UINT_64); -+ -+ pu8Data = (PUINT_64) prCmdInfo->pvInformationBuffer; -+ *pu8Data = 0; /* @FIXME? */ -+ } -+ -+ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS); -+ } -+} -+ -+VOID nicCmdEventQueryRecvCrcError(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) -+{ -+ P_EVENT_STATISTICS prEventStatistics; -+ P_GLUE_INFO_T prGlueInfo; -+ UINT_32 u4QueryInfoLen; -+ PUINT_32 pu4Data; -+ PUINT_64 pu8Data; -+ -+ ASSERT(prAdapter); -+ ASSERT(prCmdInfo); -+ -+ prEventStatistics = (P_EVENT_STATISTICS) pucEventBuf; -+ -+ if (prCmdInfo->fgIsOid) { -+ prGlueInfo = prAdapter->prGlueInfo; -+ -+ if (prCmdInfo->u4InformationBufferLength == sizeof(UINT_32)) { -+ u4QueryInfoLen = sizeof(UINT_32); -+ -+ pu4Data = (PUINT_32) prCmdInfo->pvInformationBuffer; -+ *pu4Data = (UINT_32) prEventStatistics->rFCSErrorCount.QuadPart; -+ } else { -+ u4QueryInfoLen = sizeof(UINT_64); -+ -+ pu8Data = (PUINT_64) prCmdInfo->pvInformationBuffer; -+ *pu8Data = prEventStatistics->rFCSErrorCount.QuadPart; -+ } -+ -+ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS); -+ } -+} -+ -+VOID nicCmdEventQueryRecvErrorAlignment(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) -+{ -+ P_EVENT_STATISTICS prEventStatistics; -+ P_GLUE_INFO_T prGlueInfo; -+ UINT_32 u4QueryInfoLen; -+ PUINT_32 pu4Data; -+ PUINT_64 pu8Data; -+ -+ ASSERT(prAdapter); -+ ASSERT(prCmdInfo); -+ -+ prEventStatistics = (P_EVENT_STATISTICS) pucEventBuf; -+ -+ if (prCmdInfo->fgIsOid) { -+ prGlueInfo = prAdapter->prGlueInfo; -+ -+ if (prCmdInfo->u4InformationBufferLength == sizeof(UINT_32)) { -+ u4QueryInfoLen = sizeof(UINT_32); -+ -+ pu4Data = (PUINT_32) prCmdInfo->pvInformationBuffer; -+ *pu4Data = (UINT_32) 0; /* @FIXME */ -+ } else { -+ u4QueryInfoLen = sizeof(UINT_64); -+ -+ pu8Data = (PUINT_64) prCmdInfo->pvInformationBuffer; -+ *pu8Data = 0; /* @FIXME */ -+ } -+ -+ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS); -+ } -+} -+ -+VOID nicCmdEventQueryXmitOneCollision(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) -+{ -+ P_EVENT_STATISTICS prEventStatistics; -+ P_GLUE_INFO_T prGlueInfo; -+ UINT_32 u4QueryInfoLen; -+ PUINT_32 pu4Data; -+ PUINT_64 pu8Data; -+ -+ ASSERT(prAdapter); -+ ASSERT(prCmdInfo); -+ -+ prEventStatistics = (P_EVENT_STATISTICS) pucEventBuf; -+ -+ if (prCmdInfo->fgIsOid) { -+ prGlueInfo = prAdapter->prGlueInfo; -+ -+ if (prCmdInfo->u4InformationBufferLength == sizeof(UINT_32)) { -+ u4QueryInfoLen = sizeof(UINT_32); -+ -+ pu4Data = (PUINT_32) prCmdInfo->pvInformationBuffer; -+ *pu4Data = -+ (UINT_32) (prEventStatistics->rMultipleRetryCount.QuadPart - -+ prEventStatistics->rRetryCount.QuadPart); -+ } else { -+ u4QueryInfoLen = sizeof(UINT_64); -+ -+ pu8Data = (PUINT_64) prCmdInfo->pvInformationBuffer; -+ *pu8Data = -+ (UINT_64) (prEventStatistics->rMultipleRetryCount.QuadPart - -+ prEventStatistics->rRetryCount.QuadPart); -+ } -+ -+ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS); -+ } -+} -+ -+VOID nicCmdEventQueryXmitMoreCollisions(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) -+{ -+ P_EVENT_STATISTICS prEventStatistics; -+ P_GLUE_INFO_T prGlueInfo; -+ UINT_32 u4QueryInfoLen; -+ PUINT_32 pu4Data; -+ PUINT_64 pu8Data; -+ -+ ASSERT(prAdapter); -+ ASSERT(prCmdInfo); -+ -+ prEventStatistics = (P_EVENT_STATISTICS) pucEventBuf; -+ -+ if (prCmdInfo->fgIsOid) { -+ prGlueInfo = prAdapter->prGlueInfo; -+ -+ if (prCmdInfo->u4InformationBufferLength == sizeof(UINT_32)) { -+ u4QueryInfoLen = sizeof(UINT_32); -+ -+ pu4Data = (PUINT_32) prCmdInfo->pvInformationBuffer; -+ *pu4Data = (UINT_32) prEventStatistics->rMultipleRetryCount.QuadPart; -+ } else { -+ u4QueryInfoLen = sizeof(UINT_64); -+ -+ pu8Data = (PUINT_64) prCmdInfo->pvInformationBuffer; -+ *pu8Data = (UINT_64) prEventStatistics->rMultipleRetryCount.QuadPart; -+ } -+ -+ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS); -+ } -+} -+ -+VOID nicCmdEventQueryXmitMaxCollisions(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) -+{ -+ P_EVENT_STATISTICS prEventStatistics; -+ P_GLUE_INFO_T prGlueInfo; -+ UINT_32 u4QueryInfoLen; -+ PUINT_32 pu4Data; -+ PUINT_64 pu8Data; -+ -+ ASSERT(prAdapter); -+ ASSERT(prCmdInfo); -+ -+ prEventStatistics = (P_EVENT_STATISTICS) pucEventBuf; -+ -+ if (prCmdInfo->fgIsOid) { -+ prGlueInfo = prAdapter->prGlueInfo; -+ -+ if (prCmdInfo->u4InformationBufferLength == sizeof(UINT_32)) { -+ u4QueryInfoLen = sizeof(UINT_32); -+ -+ pu4Data = (PUINT_32) prCmdInfo->pvInformationBuffer; -+ *pu4Data = (UINT_32) prEventStatistics->rFailedCount.QuadPart; -+ } else { -+ u4QueryInfoLen = sizeof(UINT_64); -+ -+ pu8Data = (PUINT_64) prCmdInfo->pvInformationBuffer; -+ *pu8Data = (UINT_64) prEventStatistics->rFailedCount.QuadPart; -+ } -+ -+ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS); -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is called when command by OID/ioctl has been timeout -+* -+* @param prAdapter Pointer to the Adapter structure. -+* @param prCmdInfo Pointer to the command information -+* -+* @return TRUE -+* FALSE -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicOidCmdTimeoutCommon(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo) -+{ -+ ASSERT(prAdapter); -+ -+ kalOidComplete(prAdapter->prGlueInfo, prCmdInfo->fgSetQuery, 0, WLAN_STATUS_FAILURE); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is a generic command timeout handler -+* -+* @param pfnOidHandler Pointer to the OID handler -+* -+* @return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicCmdTimeoutCommon(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo) -+{ -+ ASSERT(prAdapter); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is called when command for entering RF test has -+* failed sending due to timeout (highly possibly by firmware crash) -+* -+* @param prAdapter Pointer to the Adapter structure. -+* @param prCmdInfo Pointer to the command information -+* -+* @return none -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicOidCmdEnterRFTestTimeout(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo) -+{ -+ ASSERT(prAdapter); -+ -+ /* 1. Remove pending TX frames */ -+ nicTxRelease(prAdapter); -+ -+ /* 1.1 clear pending Security / Management Frames */ -+ kalClearSecurityFrames(prAdapter->prGlueInfo); -+ kalClearMgmtFrames(prAdapter->prGlueInfo); -+ -+ /* 1.2 clear pending TX packet queued in glue layer */ -+ kalFlushPendingTxPackets(prAdapter->prGlueInfo); -+ -+ /* 2. indicate for OID failure */ -+ kalOidComplete(prAdapter->prGlueInfo, prCmdInfo->fgSetQuery, 0, WLAN_STATUS_FAILURE); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is called when command for memory dump has -+* replied a event. -+* -+* @param prAdapter Pointer to the Adapter structure. -+* @param prCmdInfo Pointer to the command information -+* @param pucEventBuf Pointer to event buffer -+* -+* @return none -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicCmdEventQueryMemDump(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) -+{ -+ UINT_32 u4QueryInfoLen; -+ P_PARAM_CUSTOM_MEM_DUMP_STRUCT_T prMemDumpInfo; -+ P_GLUE_INFO_T prGlueInfo; -+ P_EVENT_DUMP_MEM_T prEventDumpMem; -+ static UINT_8 aucPath[256]; -+ static UINT_32 u4CurTimeTick; -+ -+ ASSERT(prAdapter); -+ ASSERT(prCmdInfo); -+ ASSERT(pucEventBuf); -+ -+ /* 4 <2> Update information of OID */ -+ if (prCmdInfo->fgIsOid) { -+ prGlueInfo = prAdapter->prGlueInfo; -+ prEventDumpMem = (P_EVENT_DUMP_MEM_T) (pucEventBuf); -+ -+ u4QueryInfoLen = sizeof(P_PARAM_CUSTOM_MEM_DUMP_STRUCT_T); -+ -+ prMemDumpInfo = (P_PARAM_CUSTOM_MEM_DUMP_STRUCT_T) prCmdInfo->pvInformationBuffer; -+ prMemDumpInfo->u4Address = prEventDumpMem->u4Address; -+ prMemDumpInfo->u4Length = prEventDumpMem->u4Length; -+ prMemDumpInfo->u4RemainLength = prEventDumpMem->u4RemainLength; -+ prMemDumpInfo->ucFragNum = prEventDumpMem->ucFragNum; -+ -+#if 0 -+ do { -+ UINT_32 i = 0; -+ -+ DBGLOG(REQ, TRACE, "Rx dump address 0x%X, Length %d, FragNum %d, remain %d\n", -+ prEventDumpMem->u4Address, -+ prEventDumpMem->u4Length, prEventDumpMem->ucFragNum, prEventDumpMem->u4RemainLength); -+#if 0 -+ for (i = 0; i < prEventDumpMem->u4Length; i++) { -+ DBGLOG(REQ, TRACE, "%02X ", prEventDumpMem->aucBuffer[i]); -+ if (i % 32 == 31) -+ DBGLOG(REQ, TRACE, "\n"); -+ } -+#endif -+ } while (FALSE); -+#endif -+ -+ if (prEventDumpMem->ucFragNum == 1) { -+ /* Store memory dump into sdcard, -+ * path /sdcard/dump___.hex -+ */ -+ u4CurTimeTick = kalGetTimeTick(); -+ sprintf(aucPath, "/sdcard/dump_%d_0x%08X_%d.hex", -+ u4CurTimeTick, -+ prEventDumpMem->u4Address, prEventDumpMem->u4Length + prEventDumpMem->u4RemainLength); -+ kalWriteToFile(aucPath, FALSE, &prEventDumpMem->aucBuffer[0], prEventDumpMem->u4Length); -+ } else { -+ /* Append current memory dump to the hex file */ -+ kalWriteToFile(aucPath, TRUE, &prEventDumpMem->aucBuffer[0], prEventDumpMem->u4Length); -+ } -+ -+ if (prEventDumpMem->u4RemainLength == 0 || prEventDumpMem->u4Address == 0xFFFFFFFF) { -+ /* The request is finished or firmware response a error */ -+ /* Reply time tick to iwpriv */ -+ *((PUINT_32) prCmdInfo->pvInformationBuffer) = u4CurTimeTick; -+ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS); -+ } else { -+ /* The memory dump request is not finished, Send next command */ -+ wlanSendMemDumpCmd(prAdapter, -+ prCmdInfo->pvInformationBuffer, prCmdInfo->u4InformationBufferLength); -+ } -+ } -+ -+ return; -+ -+} -+ -+#if CFG_SUPPORT_BATCH_SCAN -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is called when event for SUPPORT_BATCH_SCAN -+* -+* @param prAdapter Pointer to the Adapter structure. -+* @param prCmdInfo Pointer to the command information -+* @param pucEventBuf Pointer to the event buffer -+* -+* @return none -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicCmdEventBatchScanResult(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) -+{ -+ UINT_32 u4QueryInfoLen; -+ P_EVENT_BATCH_RESULT_T prEventBatchResult; -+ P_GLUE_INFO_T prGlueInfo; -+ -+ DBGLOG(SCN, TRACE, "nicCmdEventBatchScanResult"); -+ -+ ASSERT(prAdapter); -+ ASSERT(prCmdInfo); -+ ASSERT(pucEventBuf); -+ -+ /* 4 <2> Update information of OID */ -+ if (prCmdInfo->fgIsOid) { -+ prGlueInfo = prAdapter->prGlueInfo; -+ prEventBatchResult = (P_EVENT_BATCH_RESULT_T) pucEventBuf; -+ -+ u4QueryInfoLen = sizeof(EVENT_BATCH_RESULT_T); -+ kalMemCopy(prCmdInfo->pvInformationBuffer, prEventBatchResult, sizeof(EVENT_BATCH_RESULT_T)); -+ -+ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS); -+ } -+ -+} -+#endif -+ -+#if CFG_SUPPORT_BUILD_DATE_CODE -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is called when event for build date code information -+* has been retrieved -+* -+* @param prAdapter Pointer to the Adapter structure. -+* @param prCmdInfo Pointer to the command information -+* @param pucEventBuf Pointer to the event buffer -+* -+* @return none -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicCmdEventBuildDateCode(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) -+{ -+ UINT_32 u4QueryInfoLen; -+ P_EVENT_BUILD_DATE_CODE prEvent; -+ P_GLUE_INFO_T prGlueInfo; -+ -+ ASSERT(prAdapter); -+ ASSERT(prCmdInfo); -+ ASSERT(pucEventBuf); -+ -+ /* 4 <2> Update information of OID */ -+ if (prCmdInfo->fgIsOid) { -+ prGlueInfo = prAdapter->prGlueInfo; -+ prEvent = (P_EVENT_BUILD_DATE_CODE) pucEventBuf; -+ -+ u4QueryInfoLen = sizeof(UINT_8) * 16; -+ kalMemCopy(prCmdInfo->pvInformationBuffer, prEvent->aucDateCode, sizeof(UINT_8) * 16); -+ -+ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS); -+ } -+ -+} -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is called when event for query STA link status -+* has been retrieved -+* -+* @param prAdapter Pointer to the Adapter structure. -+* @param prCmdInfo Pointer to the command information -+* @param pucEventBuf Pointer to the event buffer -+* -+* @return none -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicCmdEventQueryStaStatistics(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) -+{ -+ UINT_32 u4QueryInfoLen; -+ P_EVENT_STA_STATISTICS_T prEvent; -+ P_GLUE_INFO_T prGlueInfo; -+ P_PARAM_GET_STA_STATISTICS prStaStatistics; -+ -+ if ((prAdapter == NULL) -+ || (prCmdInfo == NULL) -+ || (pucEventBuf == NULL) -+ || (prCmdInfo->pvInformationBuffer == NULL)) { -+ ASSERT(FALSE); -+ return; -+ } -+ -+ if (prCmdInfo->fgIsOid) { -+ prGlueInfo = prAdapter->prGlueInfo; -+ prEvent = (P_EVENT_STA_STATISTICS_T) pucEventBuf; -+ prStaStatistics = (P_PARAM_GET_STA_STATISTICS) prCmdInfo->pvInformationBuffer; -+ -+ u4QueryInfoLen = sizeof(PARAM_GET_STA_STA_STATISTICS); -+ -+ /* Statistics from FW is valid */ -+ if (prEvent->u4Flags & BIT(0)) { -+ prStaStatistics->ucPer = prEvent->ucPer; -+ prStaStatistics->ucRcpi = prEvent->ucRcpi; -+ prStaStatistics->u4PhyMode = prEvent->u4PhyMode; -+ prStaStatistics->u2LinkSpeed = prEvent->u2LinkSpeed; -+ -+ prStaStatistics->u4TxFailCount = prEvent->u4TxFailCount; -+ prStaStatistics->u4TxLifeTimeoutCount = prEvent->u4TxLifeTimeoutCount; -+ -+ if (prEvent->u4TxCount) { -+ UINT_32 u4TxDoneAirTimeMs = USEC_TO_MSEC(prEvent->u4TxDoneAirTime * 32); -+ -+ prStaStatistics->u4TxAverageAirTime = (u4TxDoneAirTimeMs / prEvent->u4TxCount); -+ } else { -+ prStaStatistics->u4TxAverageAirTime = 0; -+ } -+ } -+ -+ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS); -+ } -+ -+} -+ -+#if CFG_AUTO_CHANNEL_SEL_SUPPORT -+ -+/* 4 Auto Channel Selection */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is called when event for query STA link status -+* has been retrieved -+* -+* @param prAdapter Pointer to the Adapter structure. -+* @param prCmdInfo Pointer to the command information -+* @param pucEventBuf Pointer to the event buffer -+* -+* @return none -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicCmdEventQueryChannelLoad(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) -+{ -+ UINT_32 u4QueryInfoLen; -+ P_EVENT_CHN_LOAD_T prEvent; -+ P_GLUE_INFO_T prGlueInfo; -+ P_PARAM_GET_CHN_LOAD prChnLoad; -+ -+ if ((prAdapter == NULL) -+ || (prCmdInfo == NULL) -+ || (pucEventBuf == NULL) -+ || (prCmdInfo->pvInformationBuffer == NULL)) { -+ ASSERT(FALSE); -+ return; -+ } -+ -+ if (prCmdInfo->fgIsOid) { -+ prGlueInfo = prAdapter->prGlueInfo; -+ prEvent = (P_EVENT_CHN_LOAD_T) pucEventBuf; /* 4 The firmware responsed data */ -+ /* 4 Fill the firmware data in and send it back to host */ -+ prChnLoad = (P_PARAM_GET_CHN_LOAD) prCmdInfo->pvInformationBuffer; -+ -+ u4QueryInfoLen = sizeof(PARAM_GET_CHN_LOAD); -+ -+ /* Statistics from FW is valid */ -+ if (prEvent->u4Flags & BIT(0)) { -+ prChnLoad->rEachChnLoad[0].ucChannel = prEvent->ucChannel; -+ prChnLoad->rEachChnLoad[0].u2ChannelLoad = prEvent->u2ChannelLoad; -+ DBGLOG(P2P, INFO, "CHN[%d]=%d\n", prEvent->ucChannel, prEvent->u2ChannelLoad); -+ -+ } -+ -+ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS); -+ } -+ -+} -+ -+VOID nicCmdEventQueryLTESafeChn(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) -+{ -+ UINT_8 ucIdx = 0; -+ UINT_32 u4QueryInfoLen; -+ P_EVENT_LTE_MODE_T prEvent; -+ P_GLUE_INFO_T prGlueInfo; -+ P_PARAM_GET_CHN_LOAD prLteSafeChnInfo; -+ -+ if ((prAdapter == NULL) -+ || (prCmdInfo == NULL) -+ || (pucEventBuf == NULL) -+ || (prCmdInfo->pvInformationBuffer == NULL)) { -+ ASSERT(FALSE); -+ return; -+ } -+ if (prCmdInfo->fgIsOid) { -+ prGlueInfo = prAdapter->prGlueInfo; -+ prEvent = (P_EVENT_LTE_MODE_T) pucEventBuf; /* 4 The firmware responsed data */ -+ -+ prLteSafeChnInfo = (P_PARAM_GET_CHN_LOAD) prCmdInfo->pvInformationBuffer; -+ -+ u4QueryInfoLen = sizeof(PARAM_GET_CHN_LOAD); -+ -+ /* Statistics from FW is valid */ -+ if (prEvent->u4Flags & BIT(0)) { -+ for (ucIdx = 0; ucIdx < (NL80211_TESTMODE_AVAILABLE_CHAN_NUM - 1); ucIdx++) { -+ prLteSafeChnInfo->rLteSafeChnList.au4SafeChannelBitmask[ucIdx] = -+ prEvent->rLteSafeChn.au4SafeChannelBitmask[ucIdx]; -+ -+ DBGLOG(P2P, INFO, -+ "[Auto Channel]LTE safe channels [%d]=[%x]\n", ucIdx, -+ (UINT32) prLteSafeChnInfo->rLteSafeChnList.au4SafeChannelBitmask[ucIdx]); -+ } -+ } -+ -+ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS); -+ } -+ -+} -+#endif -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is called when event for query FW bss info -+* has been retrieved -+* -+* @param prAdapter Pointer to the Adapter structure. -+* @param prCmdInfo Pointer to the command information -+* @param pucEventBuf Pointer to the event buffer -+* -+* @return none -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+ -+VOID nicCmdEventGetBSSInfo(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) -+{ -+ UINT_32 u4QueryInfoLen; -+ P_EVENT_AIS_BSS_INFO_T prEvent; -+ P_GLUE_INFO_T prGlueInfo; -+ P_BSS_INFO_T prAisBssInfo; -+ -+ ASSERT(prAdapter); -+ -+ ASSERT(prCmdInfo); -+ ASSERT(pucEventBuf); -+ -+ /* 4 <2> Update information of OID */ -+ if (prCmdInfo->fgIsOid) { -+ prGlueInfo = prAdapter->prGlueInfo; -+ prEvent = (P_EVENT_AIS_BSS_INFO_T) pucEventBuf; -+ -+ u4QueryInfoLen = sizeof(EVENT_AIS_BSS_INFO_T); -+ kalMemCopy(prCmdInfo->pvInformationBuffer, prEvent, sizeof(EVENT_AIS_BSS_INFO_T)); -+ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ -+ if (prEvent->eCurrentOPMode == OP_MODE_INFRASTRUCTURE) { -+ if (prEvent->eConnectionState != prAisBssInfo->eConnectionState) { -+ DBGLOG(NIC, ERROR, "driver[%d] & FW[%d] status didn't sync !!!\n", -+ prAisBssInfo->eConnectionState, prEvent->eCurrentOPMode); -+ aisFsmStateAbort(prAdapter, DISCONNECT_REASON_CODE_RADIO_LOST, FALSE); -+ } -+ } -+ -+ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS); -+ } -+ -+} -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic_pwr_mgt.c b/drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic_pwr_mgt.c -new file mode 100644 -index 000000000000..cf80fd999a24 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic_pwr_mgt.c -@@ -0,0 +1,669 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/nic/nic_pwr_mgt.c#1 -+*/ -+ -+/*! \file "nic_pwr_mgt.c" -+ \brief In this file we define the STATE and EVENT for Power Management FSM. -+ -+ The SCAN FSM is responsible for performing SCAN behavior when the Arbiter enter -+ ARB_STATE_SCAN. The STATE and EVENT for SCAN FSM are defined here with detail -+ description. -+*/ -+ -+/* -+** Log: nic_pwr_mgt.c -+ * -+ * 11 28 2011 cp.wu -+ * [WCXRP00001125] [MT6620 Wi-Fi][Firmware] Strengthen Wi-Fi power off sequence to have a clearroom environment when -+ * returining to ROM code -+ * 1. Due to firmware now stops HIF DMA for powering off, do not try to receive any packet from firmware -+ * 2. Take use of prAdapter->fgIsEnterD3ReqIssued for tracking whether it is powering off or not -+ * -+ * 10 03 2011 cp.wu -+ * [WCXRP00001022] [MT6628 Driver][Firmware Download] Add multi section independent download functionality -+ * add firmware download path in divided scatters. -+ * -+ * 08 15 2011 cp.wu -+ * [WCXRP00000851] [MT6628 Wi-Fi][Driver] Add HIFSYS related definition to driver source tree -+ * reuse firmware download logic of MT6620 for MT6628. -+ * -+ * 05 11 2011 cp.wu -+ * [WCXRP00000718] [MT6620 Wi-Fi] modify the behavior of setting tx power -+ * ACPI APIs migrate to wlan_lib.c for glue layer to invoke. -+ * -+ * 04 29 2011 cp.wu -+ * [WCXRP00000636] [WHQL][MT5931 Driver] 2c_PMHibernate (hang on 2h) -+ * fix for compilation error when applied with FW_DOWNLOAD = 0 -+ * -+ * 04 18 2011 cp.wu -+ * [WCXRP00000636] [WHQL][MT5931 Driver] 2c_PMHibernate (hang on 2h) -+ * 1) add API for glue layer to query ACPI state -+ * 2) Windows glue should not access to hardware after switched into D3 state -+ * -+ * 04 13 2011 cp.wu -+ * [WCXRP00000639] [WHQL][MT5931 Driver] 2c_PMStandby test item can not complete -+ * refine for MT5931/MT6620 logic separation. -+ * -+ * 04 13 2011 cp.wu -+ * [WCXRP00000639] [WHQL][MT5931 Driver] 2c_PMStandby test item can not complete -+ * bugfix: firmware download procedure for ACPI state transition is not complete. -+ * -+ * 03 15 2011 cp.wu -+ * [WCXRP00000559] [MT6620 Wi-Fi][Driver] Combine TX/RX DMA buffers into a single one to reduce physically continuous -+ * memory consumption -+ * 1. deprecate CFG_HANDLE_IST_IN_SDIO_CALLBACK -+ * 2. Use common coalescing buffer for both TX/RX directions -+ * -+ * -+ * 03 07 2011 terry.wu -+ * [WCXRP00000521] [MT6620 Wi-Fi][Driver] Remove non-standard debug message -+ * Toggle non-standard debug messages to comments. -+ * -+ * 12 31 2010 cp.wu -+ * [WCXRP00000335] [MT6620 Wi-Fi][Driver] change to use milliseconds sleep instead of delay to avoid blocking to system -+ * scheduling -+ * change to use msleep() and shorten waiting interval to reduce blocking to other task while Wi-Fi driver is being -+ * loaded -+ * -+ * 12 31 2010 cp.wu -+ * [WCXRP00000327] [MT6620 Wi-Fi][Driver] Improve HEC WHQA 6972 workaround coverage in driver side -+ * check success or failure for setting fw-own -+ * -+ * 12 30 2010 cp.wu -+ * [WCXRP00000327] [MT6620 Wi-Fi][Driver] Improve HEC WHQA 6972 workaround coverage in driver side -+ * host driver not to set FW-own when there is still pending interrupts -+ * -+ * 10 07 2010 cp.wu -+ * [WCXRP00000083] [MT5931][Driver][FW] Add necessary logic for MT5931 first connection -+ * add firmware download for MT5931. -+ * -+ * 09 21 2010 cp.wu -+ * [WCXRP00000053] [MT6620 Wi-Fi][Driver] Reset incomplete and might leads to BSOD when entering RF test with AIS -+ * associated -+ * Do a complete reset with STA-REC null checking for RF test re-entry -+ * -+ * 08 30 2010 cp.wu -+ * NULL -+ * eliminate klockwork errors -+ * -+ * 08 30 2010 cp.wu -+ * NULL -+ * reset ACPI power state before waking up MT6620 Wi-Fi firmware. -+ * -+ * 08 12 2010 cp.wu -+ * NULL -+ * [AIS-FSM] honor registry setting for adhoc running mode. (A/B/G) -+ * -+ * 08 03 2010 cp.wu -+ * NULL -+ * Centralize mgmt/system service procedures into independent calls. -+ * -+ * 07 22 2010 cp.wu -+ * -+ * 1) refine AIS-FSM indent. -+ * 2) when entering RF Test mode, flush 802.1X frames as well -+ * 3) when entering D3 state, flush 802.1X frames as well -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 21 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * change MAC address updating logic. -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 05 24 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) when acquiring LP-own, write for clr-own with lower frequency compared to read poll -+ * 2) correct address list parsing -+ * -+ * 05 22 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * sleepy notify is only used for sleepy state, -+ * while wake-up state is automatically set when host needs to access device -+ * -+ * 05 19 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * correct hibernation problem. -+ * -+ * 04 26 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) surpress compiler warning -+ * 2) when acqruing LP-own, keep writing WHLPCR whenever OWN is not acquired yet -+ * -+ * 04 23 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * surpress compiler warning -+ * -+ * 04 22 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * when acquiring driver-own, wait for up to 8 seconds. -+ * -+ * 04 21 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * add for private ioctl support -+ * -+ * 04 20 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) remove redundant firmware image unloading -+ * * 2) use compile-time macros to separate logic related to accquiring own -+ * -+ * 04 16 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * treat BUS access failure as kind of card removal. -+ * -+ * 04 07 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * accessing to firmware load/start address, and access to OID handling information -+ * * are now handled in glue layer -+ * -+ * 04 06 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * ePowerCtrl is not necessary as a glue variable. -+ * -+ * 04 06 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * add KAL API: kalFlushPendingTxPackets(), and take use of the API -+ * -+ * 04 06 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * eliminate direct access for prGlueInfo->fgIsCardRemoved in non-glue layer -+ * -+ * 03 24 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * initial import for Linux port -+ * -+ * 03 22 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * always send CMD_NIC_POWER_CTRL packet when nic is being halted -+ * -+ * 03 19 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * correct typo. -+ * -+ * 03 19 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) add ACPI D0/D3 state switching support -+ * * * * * * * * 2) use more formal way to handle interrupt when the status is retrieved from enhanced RX -+ * response -+ * -+ * 03 08 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) add another spin-lock to protect MsduInfoList due to it might be accessed by different thread. -+ * * 2) change own-back acquiring procedure to wait for up to 16.67 seconds -+** \main\maintrunk.MT6620WiFiDriver_Prj\6 2009-10-13 21:59:15 GMT mtk01084 -+** update for new HW design -+** \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-09-09 17:26:36 GMT mtk01084 -+** remove CMD52 access -+** \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-05-18 14:50:29 GMT mtk01084 -+** modify lines in nicpmSetDriverOwn() -+** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-03-23 16:55:37 GMT mtk01084 -+** modify nicpmSetDriverOwn() -+** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-19 18:33:00 GMT mtk01084 -+** update for basic power management functions -+** \main\maintrunk.MT6620WiFiDriver_Prj\1 2009-03-19 15:05:32 GMT mtk01084 -+** Initial version -+** -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "precomp.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is used to process the POWER ON procedure. -+* -+* \param[in] pvAdapter Pointer to the Adapter structure. -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicpmSetFWOwn(IN P_ADAPTER_T prAdapter, IN BOOLEAN fgEnableGlobalInt) -+{ -+ UINT_32 u4RegValue = 0; -+ -+ ASSERT(prAdapter); -+ -+ if (prAdapter->fgIsFwOwn == TRUE) -+ return; -+ -+ if (nicProcessIST(prAdapter) != WLAN_STATUS_NOT_INDICATING) { -+ /* pending interrupts */ -+ return; -+ } -+ -+ if (fgEnableGlobalInt) { -+ prAdapter->fgIsIntEnableWithLPOwnSet = TRUE; -+ } else { -+ HAL_MCR_WR(prAdapter, MCR_WHLPCR, WHLPCR_FW_OWN_REQ_SET); -+ -+ HAL_MCR_RD(prAdapter, MCR_WHLPCR, &u4RegValue); -+ if (u4RegValue & WHLPCR_FW_OWN_REQ_SET) { -+ /* if set firmware own not successful (possibly pending interrupts), */ -+ /* indicate an own clear event */ -+ HAL_MCR_WR(prAdapter, MCR_WHLPCR, WHLPCR_FW_OWN_REQ_CLR); -+ -+ return; -+ } -+ -+ prAdapter->fgIsFwOwn = TRUE; -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is used to process the POWER OFF procedure. -+* -+* \param[in] pvAdapter Pointer to the Adapter structure. -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT_32 u4OriRegValue = 0; -+BOOLEAN nicpmSetDriverOwn(IN P_ADAPTER_T prAdapter) -+{ -+#define LP_OWN_BACK_TOTAL_DELAY_MS 2000 /* exponential of 2 */ -+#define LP_OWN_BACK_LOOP_DELAY_MS 1 /* exponential of 2 */ -+#define LP_OWN_BACK_CLR_OWN_ITERATION 256 /* exponential of 2 */ -+ -+ BOOLEAN fgStatus = TRUE; -+ UINT_32 i, u4CurrTick; -+ UINT_32 u4RegValue = 0; -+ GL_HIF_INFO_T *HifInfo; -+ -+ ASSERT(prAdapter); -+ -+ if (prAdapter->fgIsFwOwn == FALSE) -+ return fgStatus; -+ -+ HifInfo = &prAdapter->prGlueInfo->rHifInfo; -+ -+ u4CurrTick = kalGetTimeTick(); -+ STATS_DRIVER_OWN_START_RECORD(); -+ i = 0; -+ -+ while (1) { -+ HAL_MCR_RD(prAdapter, MCR_WHLPCR, &u4RegValue); -+ -+ if (u4RegValue & WHLPCR_FW_OWN_REQ_SET) { -+ HAL_MCR_RD(prAdapter, MCR_D2HRM2R, &u4OriRegValue); -+ prAdapter->fgIsFwOwn = FALSE; -+ break; -+ } else if (kalIsCardRemoved(prAdapter->prGlueInfo) == TRUE -+ || fgIsBusAccessFailed == TRUE -+ || (kalGetTimeTick() - u4CurrTick) > LP_OWN_BACK_TOTAL_DELAY_MS || fgIsResetting == TRUE) { -+ /* ERRORLOG(("LP cannot be own back (for %ld ms)", kalGetTimeTick() - u4CurrTick)); */ -+ fgStatus = FALSE; -+ if (fgIsResetting != TRUE) { -+ UINT_32 u4FwCnt; -+ static unsigned int u4OwnCnt; -+ /* MCR_D2HRM2R: low 4 bit means interrupt times, -+ * high 4 bit means firmware response times. -+ * ORI_MCR_D2HRM2R: the last successful value. -+ * for example: -+ * MCR_D2HRM2R = 0x44, ORI_MCR_D2HRM2R = 0x44 -+ * means firmware no receive interrupt form hardware. -+ * MCR_D2HRM2R = 0x45, ORI_MCR_D2HRM2R = 0x44 -+ * means firmware no send response. -+ * MCR_D2HRM2R = 0x55, ORI_MCR_D2HRM2R = 0x44 -+ * means firmware send response, but driver no receive. */ -+ HAL_MCR_RD(prAdapter, MCR_D2HRM2R, &u4RegValue); -+ DBGLOG(NIC, WARN, " [1]MCR_D2HRM2R = 0x%x, ORI_MCR_D2HRM2R = 0x%x\n", -+ u4RegValue, u4OriRegValue); -+ -+ HAL_MCR_WR(prAdapter, MCR_WHLPCR, WHLPCR_FW_OWN_REQ_CLR); -+ HAL_MCR_RD(prAdapter, MCR_WHLPCR, &u4RegValue); -+ if (u4RegValue & WHLPCR_FW_OWN_REQ_SET) { -+ HAL_MCR_RD(prAdapter, MCR_D2HRM2R, &u4OriRegValue); -+ prAdapter->fgIsFwOwn = FALSE; -+ break; -+ } -+ HAL_MCR_RD(prAdapter, MCR_D2HRM2R, &u4RegValue); -+ DBGLOG(NIC, WARN, " [2]MCR_D2HRM2R = 0x%x, ORI_MCR_D2HRM2R = 0x%x\n", -+ u4RegValue, u4OriRegValue); -+ DBGLOG(NIC, WARN, -+ " Fatal error! Driver own fail!!!!!!!!!!!! %d, fgIsBusAccessFailed: %d\n", -+ u4OwnCnt++, fgIsBusAccessFailed); -+ -+ DBGLOG(NIC, WARN, "CONNSYS FW CPUINFO:\n"); -+ for (u4FwCnt = 0; u4FwCnt < 16; u4FwCnt++) -+ DBGLOG(NIC, WARN, "0x%08x ", MCU_REG_READL(HifInfo, CONN_MCU_CPUPCR)); -+ /* CONSYS_REG_READ(CONSYS_CPUPCR_REG) */ -+ kalSendAeeWarning("[Fatal error! Driver own fail!]", __func__); -+ glDoChipReset(); -+ } -+ break; -+ } -+ if ((i & (LP_OWN_BACK_CLR_OWN_ITERATION - 1)) == 0) { -+ /* Software get LP ownership - per 256 iterations */ -+ HAL_MCR_WR(prAdapter, MCR_WHLPCR, WHLPCR_FW_OWN_REQ_CLR); -+ } -+ -+ /* Delay for LP engine to complete its operation. */ -+ kalMsleep(LP_OWN_BACK_LOOP_DELAY_MS); -+ i++; -+ } -+ -+ STATS_DRIVER_OWN_END_RECORD(); -+ STATS_DRIVER_OWN_STOP(); -+ -+ return fgStatus; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is used to set ACPI power mode to D0. -+* -+* \param[in] pvAdapter Pointer to the Adapter structure. -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN nicpmSetAcpiPowerD0(IN P_ADAPTER_T prAdapter) -+{ -+ WLAN_STATUS u4Status = WLAN_STATUS_SUCCESS; -+ UINT_32 u4Value = 0, u4WHISR = 0; -+ UINT_8 aucTxCount[8]; -+ UINT_32 i; -+#if CFG_ENABLE_FW_DOWNLOAD -+ UINT_32 u4FwImgLength, u4FwLoadAddr, u4ImgSecSize; -+ PVOID prFwMappingHandle; -+ PVOID pvFwImageMapFile = NULL; -+#if CFG_ENABLE_FW_DIVIDED_DOWNLOAD -+ UINT_32 j; -+ P_FIRMWARE_DIVIDED_DOWNLOAD_T prFwHead; -+ BOOLEAN fgValidHead; -+ const UINT_32 u4CRCOffset = offsetof(FIRMWARE_DIVIDED_DOWNLOAD_T, u4NumOfEntries); -+#endif -+#endif -+ -+ DEBUGFUNC("nicpmSetAcpiPowerD0"); -+ ASSERT(prAdapter); -+ -+ do { -+ /* 0. Reset variables in ADAPTER_T */ -+ prAdapter->fgIsFwOwn = TRUE; -+ prAdapter->fgWiFiInSleepyState = FALSE; -+ prAdapter->rAcpiState = ACPI_STATE_D0; -+ prAdapter->fgIsEnterD3ReqIssued = FALSE; -+ -+ /* 1. Request Ownership to enter F/W download state */ -+ ACQUIRE_POWER_CONTROL_FROM_PM(prAdapter); -+#if !CFG_ENABLE_FULL_PM -+ nicpmSetDriverOwn(prAdapter); -+#endif -+ -+ /* 2. Initialize the Adapter */ -+ u4Status = nicInitializeAdapter(prAdapter); -+ if (u4Status != WLAN_STATUS_SUCCESS) { -+ DBGLOG(NIC, ERROR, "nicInitializeAdapter failed!\n"); -+ u4Status = WLAN_STATUS_FAILURE; -+ break; -+ } -+ -+#if CFG_ENABLE_FW_DOWNLOAD -+ prFwMappingHandle = kalFirmwareImageMapping(prAdapter->prGlueInfo, &pvFwImageMapFile, &u4FwImgLength); -+ if (!prFwMappingHandle) { -+ DBGLOG(NIC, ERROR, "Fail to load FW image from file!\n"); -+ pvFwImageMapFile = NULL; -+ } -+ -+ if (pvFwImageMapFile == NULL) { -+ u4Status = WLAN_STATUS_FAILURE; -+ break; -+ } -+ -+ /* 3.1 disable interrupt, download is done by polling mode only */ -+ nicDisableInterrupt(prAdapter); -+ -+ /* 3.2 Initialize Tx Resource to fw download state */ -+ nicTxInitResetResource(prAdapter); -+ -+ /* 3.3 FW download here */ -+ u4FwLoadAddr = kalGetFwLoadAddress(prAdapter->prGlueInfo); -+ -+#if CFG_ENABLE_FW_DIVIDED_DOWNLOAD -+ /* 3a. parse file header for decision of divided firmware download or not */ -+ prFwHead = (P_FIRMWARE_DIVIDED_DOWNLOAD_T) pvFwImageMapFile; -+ -+ if (prFwHead->u4Signature == MTK_WIFI_SIGNATURE && -+ prFwHead->u4CRC == wlanCRC32((PUINT_8) pvFwImageMapFile + u4CRCOffset, -+ u4FwImgLength - u4CRCOffset)) { -+ fgValidHead = TRUE; -+ } else { -+ fgValidHead = FALSE; -+ } -+ -+ /* 3b. engage divided firmware downloading */ -+ if (fgValidHead == TRUE) { -+ for (i = 0; i < prFwHead->u4NumOfEntries; i++) { -+#if CFG_ENABLE_FW_DOWNLOAD_AGGREGATION -+ if (wlanImageSectionDownloadAggregated(prAdapter, -+ prFwHead->arSection[i].u4DestAddr, -+ prFwHead->arSection[i].u4Length, -+ (PUINT_8) pvFwImageMapFile + -+ prFwHead->arSection[i].u4Offset) != -+ WLAN_STATUS_SUCCESS) { -+ DBGLOG(NIC, ERROR, "Firmware scatter download failed!\n"); -+ u4Status = WLAN_STATUS_FAILURE; -+ } -+#else -+ for (j = 0; j < prFwHead->arSection[i].u4Length; j += CMD_PKT_SIZE_FOR_IMAGE) { -+ if (j + CMD_PKT_SIZE_FOR_IMAGE < prFwHead->arSection[i].u4Length) -+ u4ImgSecSize = CMD_PKT_SIZE_FOR_IMAGE; -+ else -+ u4ImgSecSize = prFwHead->arSection[i].u4Length - j; -+ -+ if (wlanImageSectionDownload(prAdapter, -+ prFwHead->arSection[i].u4DestAddr + j, -+ u4ImgSecSize, -+ (PUINT_8) pvFwImageMapFile + -+ prFwHead->arSection[i].u4Offset + j) != WLAN_STATUS_SUCCESS) { -+ DBGLOG(NIC, ERROR, "Firmware scatter download failed!\n"); -+ u4Status = WLAN_STATUS_FAILURE; -+ break; -+ } -+ } -+#endif -+ /* escape from loop if any pending error occurs */ -+ if (u4Status == WLAN_STATUS_FAILURE) -+ break; -+ } -+ } else -+#endif -+#if CFG_ENABLE_FW_DOWNLOAD_AGGREGATION -+ if (wlanImageSectionDownloadAggregated(prAdapter, -+ u4FwLoadAddr, -+ u4FwImgLength, -+ (PUINT_8) pvFwImageMapFile) != WLAN_STATUS_SUCCESS) { -+ DBGLOG(NIC, ERROR, "Firmware scatter download failed!\n"); -+ u4Status = WLAN_STATUS_FAILURE; -+ } -+#else -+ for (i = 0; i < u4FwImgLength; i += CMD_PKT_SIZE_FOR_IMAGE) { -+ if (i + CMD_PKT_SIZE_FOR_IMAGE < u4FwImgLength) -+ u4ImgSecSize = CMD_PKT_SIZE_FOR_IMAGE; -+ else -+ u4ImgSecSize = u4FwImgLength - i; -+ -+ if (wlanImageSectionDownload(prAdapter, -+ u4FwLoadAddr + i, -+ u4ImgSecSize, -+ (PUINT_8) pvFwImageMapFile + i) != WLAN_STATUS_SUCCESS) { -+ DBGLOG(NIC, ERROR, "wlanImageSectionDownload failed!\n"); -+ u4Status = WLAN_STATUS_FAILURE; -+ break; -+ } -+ } -+#endif -+ -+ if (u4Status != WLAN_STATUS_SUCCESS) { -+ kalFirmwareImageUnmapping(prAdapter->prGlueInfo, prFwMappingHandle, pvFwImageMapFile); -+ break; -+ } -+#if !CFG_ENABLE_FW_DOWNLOAD_ACK -+ /* Send INIT_CMD_ID_QUERY_PENDING_ERROR command and wait for response */ -+ if (wlanImageQueryStatus(prAdapter) != WLAN_STATUS_SUCCESS) { -+ kalFirmwareImageUnmapping(prAdapter->prGlueInfo, prFwMappingHandle, pvFwImageMapFile); -+ u4Status = WLAN_STATUS_FAILURE; -+ break; -+ } -+#endif -+ kalFirmwareImageUnmapping(prAdapter->prGlueInfo, prFwMappingHandle, pvFwImageMapFile); -+ -+ /* 4. send Wi-Fi Start command */ -+#if CFG_OVERRIDE_FW_START_ADDRESS -+ wlanConfigWifiFunc(prAdapter, TRUE, kalGetFwStartAddress(prAdapter->prGlueInfo)); -+#else -+ wlanConfigWifiFunc(prAdapter, FALSE, 0); -+#endif -+#endif /* if CFG_ENABLE_FW_DOWNLOAD */ -+ -+ /* 5. check Wi-Fi FW asserts ready bit */ -+ DBGLOG(NIC, TRACE, "wlanAdapterStart(): Waiting for Ready bit..\n"); -+ i = 0; -+ while (1) { -+ HAL_MCR_RD(prAdapter, MCR_WCIR, &u4Value); -+ -+ if (u4Value & WCIR_WLAN_READY) { -+ DBGLOG(NIC, TRACE, "Ready bit asserted\n"); -+ break; -+ } else if (kalIsCardRemoved(prAdapter->prGlueInfo) == TRUE || fgIsBusAccessFailed == TRUE) { -+ u4Status = WLAN_STATUS_FAILURE; -+ break; -+ } else if (i >= CFG_RESPONSE_POLLING_TIMEOUT) { -+ DBGLOG(NIC, ERROR, "Waiting for Ready bit: Timeout\n"); -+ u4Status = WLAN_STATUS_FAILURE; -+ break; -+ } -+ i++; -+ kalMsleep(10); -+ } -+ -+ if (u4Status == WLAN_STATUS_SUCCESS) { -+ /* 6.1 reset interrupt status */ -+ HAL_READ_INTR_STATUS(prAdapter, 4, (PUINT_8)(&u4WHISR)); -+ if (HAL_IS_TX_DONE_INTR(u4WHISR)) -+ HAL_READ_TX_RELEASED_COUNT(prAdapter, aucTxCount); -+ -+ /* 6.2 reset TX Resource for normal operation */ -+ nicTxResetResource(prAdapter); -+ -+ /* 6.3 Enable interrupt */ -+ nicEnableInterrupt(prAdapter); -+ -+ /* 6.4 Override network address */ -+ wlanUpdateNetworkAddress(prAdapter); -+ -+ /* 6.5 indicate disconnection as default status */ -+ kalIndicateStatusAndComplete(prAdapter->prGlueInfo, WLAN_STATUS_MEDIA_DISCONNECT, NULL, 0); -+ } -+ -+ RECLAIM_POWER_CONTROL_TO_PM(prAdapter, FALSE); -+ -+ /* MGMT Initialization */ -+ nicInitMGMT(prAdapter, NULL); -+ -+ } while (FALSE); -+ -+ if (u4Status != WLAN_STATUS_SUCCESS) -+ return FALSE; -+ else -+ return TRUE; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This routine is used to set ACPI power mode to D3. -+* -+* @param prAdapter pointer to the Adapter handler -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN nicpmSetAcpiPowerD3(IN P_ADAPTER_T prAdapter) -+{ -+ UINT_32 i; -+ -+ ASSERT(prAdapter); -+ -+ /* 1. MGMT - unitialization */ -+ nicUninitMGMT(prAdapter); -+ -+ /* 2. Disable Interrupt */ -+ nicDisableInterrupt(prAdapter); -+ -+ /* 3. emit CMD_NIC_POWER_CTRL command packet */ -+ wlanSendNicPowerCtrlCmd(prAdapter, 1); -+ -+ /* 4. Clear Interrupt Status */ -+ i = 0; -+ while (i < CFG_IST_LOOP_COUNT && nicProcessIST(prAdapter) != WLAN_STATUS_NOT_INDICATING) { -+ i++; -+ }; -+ -+ /* 5. Remove pending TX */ -+ nicTxRelease(prAdapter); -+ -+ /* 5.1 clear pending Security / Management Frames */ -+ kalClearSecurityFrames(prAdapter->prGlueInfo); -+ kalClearMgmtFrames(prAdapter->prGlueInfo); -+ -+ /* 5.2 clear pending TX packet queued in glue layer */ -+ kalFlushPendingTxPackets(prAdapter->prGlueInfo); -+ -+ /* 6. Set Onwership to F/W */ -+ nicpmSetFWOwn(prAdapter, FALSE); -+ -+ /* 7. Set variables */ -+ prAdapter->rAcpiState = ACPI_STATE_D3; -+ -+ return TRUE; -+} -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic_rx.c b/drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic_rx.c -new file mode 100644 -index 000000000000..ba4840414da8 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic_rx.c -@@ -0,0 +1,3782 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/nic/nic_rx.c#3 -+*/ -+ -+/*! \file nic_rx.c -+ \brief Functions that provide many rx-related functions -+ -+ This file includes the functions used to process RFB and dispatch RFBs to -+ the appropriate related rx functions for protocols. -+*/ -+ -+/* -+** Log: nic_rx.c -+** -+** 08 31 2012 yuche.tsai -+** [ALPS00349585] [6577JB][WiFi direct][KE]Establish p2p connection while both device have connected to AP previously, -+** one device reboots automatically with KE -+** Fix possible KE when concurrent & disconnect. -+ * -+ * 07 17 2012 yuche.tsai -+ * NULL -+ * Let netdev bring up. -+ * -+ * 07 17 2012 yuche.tsai -+ * NULL -+ * Compile no error before trial run. -+ * -+ * 03 02 2012 terry.wu -+ * NULL -+ * Sync CFG80211 modification from branch 2,2. -+ * -+ * 02 14 2012 cp.wu -+ * NULL -+ * remove another assertion by error message dump -+ * -+ * 01 05 2012 tsaiyuan.hsu -+ * [WCXRP00001157] [MT6620 Wi-Fi][FW][DRV] add timing measurement support for 802.11v -+ * add timing measurement support for 802.11v. -+ * -+ * 11 19 2011 yuche.tsai -+ * NULL -+ * Update RSSI for P2P. -+ * -+ * 11 18 2011 yuche.tsai -+ * NULL -+ * CONFIG P2P support RSSI query, default turned off. -+ * -+ * 11 17 2011 tsaiyuan.hsu -+ * [WCXRP00001115] [MT6620 Wi-Fi][DRV] avoid deactivating staRec when changing state 3 to 3. -+ * avoid deactivating staRec when changing state from 3 to 3. -+ * -+ * 11 11 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * modify the xlog related code. -+ * -+ * 11 10 2011 eddie.chen -+ * [WCXRP00001096] [MT6620 Wi-Fi][Driver/FW] Enhance the log function (xlog) -+ * Modify the QM xlog level and remove LOG_FUNC. -+ * -+ * 11 09 2011 eddie.chen -+ * [WCXRP00001096] [MT6620 Wi-Fi][Driver/FW] Enhance the log function (xlog) -+ * Add xlog for beacon timeout and sta aging timeout. -+ * -+ * 11 08 2011 eddie.chen -+ * [WCXRP00001096] [MT6620 Wi-Fi][Driver/FW] Enhance the log function (xlog) -+ * Add xlog function. -+ * -+ * 11 07 2011 tsaiyuan.hsu -+ * [WCXRP00001083] [MT6620 Wi-Fi][DRV]] dump debug counter or frames when debugging is triggered -+ * add debug counters and periodically dump counters for debugging. -+ * -+ * 10 21 2011 eddie.chen -+ * [WCXRP00001051] [MT6620 Wi-Fi][Driver/Fw] Adjust the STA aging timeout -+ * Add switch to ignore the STA aging timeout. -+ * -+ * 10 12 2011 wh.su -+ * [WCXRP00001036] [MT6620 Wi-Fi][Driver][FW] Adding the 802.11w code for MFP -+ * adding the 802.11w related function and define . -+ * -+ * 08 26 2011 cp.wu -+ * [WCXRP00000958] [MT6620 Wi-Fi][Driver] Extend polling timeout from 25ms to 1sec due to RF calibration might took -+ * up to 600ms -+ * extend polling RX response timeout period from 25ms to 1000ms. -+ * -+ * 08 11 2011 cp.wu -+ * [WCXRP00000830] [MT6620 Wi-Fi][Firmware] Use MDRDY counter to detect empty channel for shortening scan time -+ * sparse channel detection: -+ * driver: collect sparse channel information with scan-done event -+ * -+ * 07 28 2011 chinghwa.yu -+ * [WCXRP00000063] Update BCM CoEx design and settings -+ * Add BWCS cmd and event. -+ * -+ * 07 27 2011 cp.wu -+ * [WCXRP00000876] [MT5931][Drver] Decide to retain according to currently available RX counter and QUE_MGT used count -+ * correct comment. -+ * -+ * 07 27 2011 cp.wu -+ * [WCXRP00000876] [MT5931][Drver] Decide to retain according to currently available RX counter and QUE_MGT used count -+ * take use of QUE_MGT exported function to estimate currently RX buffer usage count. -+ * -+ * 07 18 2011 chinghwa.yu -+ * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm -+ * Add CMD/Event for RDD and BWCS. -+ * -+ * 06 09 2011 tsaiyuan.hsu -+ * [WCXRP00000760] [MT5931 Wi-Fi][FW] Refine rxmHandleMacRxDone to reduce code size -+ * move send_auth at rxmHandleMacRxDone in firmware to driver to reduce code size. -+ * -+ * 05 11 2011 eddie.chen -+ * [WCXRP00000709] [MT6620 Wi-Fi][Driver] Check free number before copying broadcast packet -+ * Fix dest type when GO packet copying. -+ * -+ * 05 09 2011 eddie.chen -+ * [WCXRP00000709] [MT6620 Wi-Fi][Driver] Check free number before copying broadcast packet -+ * Check free number before copying broadcast packet. -+ * -+ * 05 05 2011 cp.wu -+ * [WCXRP00000702] [MT5931][Driver] Modify initialization sequence for E1 ASIC -+ * add delay after whole-chip resetting for MT5931 E1 ASIC. -+ * -+ * 04 18 2011 terry.wu -+ * [WCXRP00000660] [MT6620 Wi-Fi][Driver] Remove flag CFG_WIFI_DIRECT_MOVED -+ * Remove flag CFG_WIFI_DIRECT_MOVED. -+ * -+ * 04 12 2011 cm.chang -+ * [WCXRP00000634] [MT6620 Wi-Fi][Driver][FW] 2nd BSS will not support 40MHz bandwidth for concurrency -+ * . -+ * -+ * 04 08 2011 yuche.tsai -+ * [WCXRP00000624] [Volunteer Patch][MT6620][Driver] Add device discoverability support for GO. -+ * Add device discoverability support for GO. -+ * -+ * 04 01 2011 tsaiyuan.hsu -+ * [WCXRP00000615] [MT 6620 Wi-Fi][Driver] Fix klocwork issues -+ * fix the klocwork issues, 57500, 57501, 57502 and 57503. -+ * -+ * 03 19 2011 yuche.tsai -+ * [WCXRP00000584] [Volunteer Patch][MT6620][Driver] Add beacon timeout support for WiFi Direct. -+ * Add beacon timeout support for WiFi Direct Network. -+ * -+ * 03 18 2011 wh.su -+ * [WCXRP00000530] [MT6620 Wi-Fi] [Driver] skip doing p2pRunEventAAAComplete after send assoc response Tx Done -+ * enable the Anti_piracy check at driver . -+ * -+ * 03 17 2011 cp.wu -+ * [WCXRP00000562] [MT6620 Wi-Fi][Driver] I/O buffer pre-allocation to avoid physically continuous memory shortage -+ * after system running for a long period -+ * use pre-allocated buffer for storing enhanced interrupt response as well -+ * -+ * 03 15 2011 cp.wu -+ * [WCXRP00000559] [MT6620 Wi-Fi][Driver] Combine TX/RX DMA buffers into a single one to reduce physically continuous -+ * memory consumption -+ * 1. deprecate CFG_HANDLE_IST_IN_SDIO_CALLBACK -+ * 2. Use common coalescing buffer for both TX/RX directions -+ * -+ * -+ * 03 07 2011 wh.su -+ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code -+ * rename the define to anti_pviracy. -+ * -+ * 03 05 2011 wh.su -+ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code -+ * add the code to get the check rsponse and indicate to app. -+ * -+ * 03 02 2011 wh.su -+ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code -+ * Add security check code. -+ * -+ * 03 02 2011 cp.wu -+ * [WCXRP00000503] [MT6620 Wi-Fi][Driver] Take RCPI brought by association response as initial RSSI right after -+ * connection is built. -+ * use RCPI brought by ASSOC-RESP after connection is built as initial RCPI to avoid using a uninitialized MAC-RX RCPI. -+ * -+ * 02 10 2011 yuche.tsai -+ * [WCXRP00000419] [Volunteer Patch][MT6620/MT5931][Driver] Provide function of disconnect to target station for AAA -+ * module. -+ * Remove Station Record after Aging timeout. -+ * -+ * 02 10 2011 cp.wu -+ * [WCXRP00000434] [MT6620 Wi-Fi][Driver] Obsolete unused event packet handlers -+ * EVENT_ID_CONNECTION_STATUS has been obsoleted and no need to handle. -+ * -+ * 02 09 2011 yuche.tsai -+ * [WCXRP00000431] [Volunteer Patch][MT6620][Driver] Add MLME support for deauthentication under AP(Hot-Spot) mode. -+ * Add MLME deauthentication support for Hot-Spot mode. -+ * -+ * 02 09 2011 eddie.chen -+ * [WCXRP00000426] [MT6620 Wi-Fi][FW/Driver] Add STA aging timeout and defualtHwRatein AP mode -+ * Adjust variable order. -+ * -+ * 02 08 2011 eddie.chen -+ * [WCXRP00000426] [MT6620 Wi-Fi][FW/Driver] Add STA aging timeout and defualtHwRatein AP mode -+ * Add event STA agint timeout -+ * -+ * 01 27 2011 tsaiyuan.hsu -+ * [WCXRP00000392] [MT6620 Wi-Fi][Driver] Add Roaming Support -+ * add roaming fsm -+ * 1. not support 11r, only use strength of signal to determine roaming. -+ * 2. not enable CFG_SUPPORT_ROAMING until completion of full test. -+ * 3. in 6620, adopt work-around to avoid sign extension problem of cck of hw -+ * 4. assume that change of link quality in smooth way. -+ * -+ * 01 26 2011 cm.chang -+ * [WCXRP00000395] [MT6620 Wi-Fi][Driver][FW] Search STA_REC with additional net type index argument -+ * . -+ * -+ * 01 24 2011 eddie.chen -+ * [WCXRP00000385] [MT6620 Wi-Fi][DRV] Add destination decision for forwarding packets -+ * Remove comments. -+ * -+ * 01 24 2011 eddie.chen -+ * [WCXRP00000385] [MT6620 Wi-Fi][DRV] Add destination decision for forwarding packets -+ * Add destination decision in AP mode. -+ * -+ * 01 24 2011 cm.chang -+ * [WCXRP00000384] [MT6620 Wi-Fi][Driver][FW] Handle 20/40 action frame in AP mode and stop ampdu timer when sta_rec -+ * is freed -+ * Process received 20/40 coexistence action frame for AP mode -+ * -+ * 01 24 2011 cp.wu -+ * [WCXRP00000382] [MT6620 Wi-Fi][Driver] Track forwarding packet number with notifying tx thread for serving -+ * 1. add an extra counter for tracking pending forward frames. -+ * 2. notify TX service thread as well when there is pending forward frame -+ * 3. correct build errors leaded by introduction of Wi-Fi direct separation module -+ * -+ * 01 12 2011 cp.wu -+ * [WCXRP00000357] [MT6620 Wi-Fi][Driver][Bluetooth over Wi-Fi] add another net device interface for BT AMP -+ * implementation of separate BT_OVER_WIFI data path. -+ * -+ * 12 29 2010 eddie.chen -+ * [WCXRP00000322] Add WMM IE in beacon, -+Add per station flow control when STA is in PS -+ -+ * 1) PS flow control event -+ * -+ * 2) WMM IE in beacon, assoc resp, probe resp -+ * -+ * 12 15 2010 george.huang -+ * [WCXRP00000152] [MT6620 Wi-Fi] AP mode power saving function -+ * update beacon for NoA -+ * -+ * 11 01 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000150] [MT6620 Wi-Fi][Driver] -+ * Add implementation for querying current TX rate from firmware auto rate module -+ * 1) Query link speed (TX rate) from firmware directly with buffering mechanism to reduce overhead -+ * 2) Remove CNM CH-RECOVER event handling -+ * 3) cfg read/write API renamed with kal prefix for unified naming rules. -+ * -+ * 10 27 2010 george.huang -+ * [WCXRP00000127] [MT6620 Wi-Fi][Driver] Add a registry to disable Beacon Timeout function for SQA test by using E1 EVB -+ * Support registry option for disable beacon lost detection. -+ * -+ * 10 20 2010 wh.su -+ * NULL -+ * add a cmd to reset the p2p key -+ * -+ * 10 20 2010 wh.su -+ * [WCXRP00000124] [MT6620 Wi-Fi] [Driver] Support the dissolve P2P Group -+ * Add the code to support disconnect p2p group -+ * -+ * 09 29 2010 wh.su -+ * [WCXRP00000072] [MT6620 Wi-Fi][Driver] Fix TKIP Counter Measure EAPoL callback register issue -+ * fixed compilier error. -+ * -+ * 09 29 2010 wh.su -+ * [WCXRP00000072] [MT6620 Wi-Fi][Driver] Fix TKIP Counter Measure EAPoL callback register issue -+ * [MT6620 Wi-Fi][Driver] Fix TKIP Counter Measure EAPoL callback register issue. -+ * -+ * 09 23 2010 cp.wu -+ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning -+ * eliminate reference of CFG_RESPONSE_MAX_PKT_SIZE -+ * -+ * 09 21 2010 cp.wu -+ * [WCXRP00000053] [MT6620 Wi-Fi][Driver] Reset incomplete and might leads to BSOD when entering RF test with AIS -+ * associated -+ * release RX packet to packet pool when in RF test mode -+ * -+ * 09 21 2010 cp.wu -+ * [WCXRP00000053] [MT6620 Wi-Fi][Driver] Reset incomplete and might leads to BSOD when entering RF test with AIS -+ @ associated -+ * Do a complete reset with STA-REC null checking for RF test re-entry -+ * -+ * 09 08 2010 cp.wu -+ * NULL -+ * use static memory pool for storing IEs of scanning result. -+ * -+ * 09 07 2010 yuche.tsai -+ * NULL -+ * Add a common buffer, store the IE of a P2P device in this common buffer. -+ * -+ * 09 03 2010 kevin.huang -+ * NULL -+ * Refine #include sequence and solve recursive/nested #include issue -+ * -+ * 08 31 2010 kevin.huang -+ * NULL -+ * Use LINK LIST operation to process SCAN result -+ * -+ * 08 30 2010 cp.wu -+ * NULL -+ * eliminate klockwork errors -+ * -+ * 08 20 2010 cm.chang -+ * NULL -+ * Migrate RLM code to host from FW -+ * -+ * 08 20 2010 yuche.tsai -+ * NULL -+ * When enable WiFi Direct function, check each packet to tell which interface to indicate. -+ * -+ * 08 05 2010 yuche.tsai -+ * NULL -+ * Add P2P Device Discovery Function. -+ * -+ * 08 03 2010 cp.wu -+ * NULL -+ * surpress compilation warning. -+ * -+ * 08 03 2010 george.huang -+ * NULL -+ * handle event for updating NOA parameters indicated from FW -+ * -+ * 08 02 2010 yuche.tsai -+ * NULL -+ * Add support API for RX public action frame. -+ * -+ * 08 02 2010 jeffrey.chang -+ * NULL -+ * 1) modify tx service thread to avoid busy looping -+ * 2) add spin lock declartion for linux build -+ * -+ * 07 30 2010 cp.wu -+ * NULL -+ * 1) BoW wrapper: use definitions instead of hard-coded constant for error code -+ * 2) AIS-FSM: eliminate use of desired RF parameters, use prTargetBssDesc instead -+ * 3) add handling for RX_PKT_DESTINATION_HOST_WITH_FORWARD for GO-broadcast frames -+ * -+ * 07 26 2010 yuche.tsai -+ * -+ * Update Device Capability Bitmap & Group Capability Bitmap from 16 bits to 8 bits. -+ * -+ * 07 24 2010 wh.su -+ * -+ * .support the Wi-Fi RSN -+ * -+ * 07 23 2010 cp.wu -+ * -+ * add AIS-FSM handling for beacon timeout event. -+ * -+ * 07 21 2010 yuche.tsai -+ * -+ * Add P2P Scan & Scan Result Parsing & Saving. -+ * -+ * 07 19 2010 cm.chang -+ * -+ * Set RLM parameters and enable CNM channel manager -+ * -+ * 07 19 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration. -+ * Add Ad-Hoc support to AIS-FSM -+ * -+ * 07 19 2010 jeffrey.chang -+ * -+ * Linux port modification -+ * -+ * 07 16 2010 yarco.yang -+ * -+ * 1. Support BSS Absence/Presence Event -+ * 2. Support STA change PS mode Event -+ * 3. Support BMC forwarding for AP mode. -+ * -+ * 07 15 2010 cp.wu -+ * -+ * sync. bluetooth-over-Wi-Fi interface to driver interface document v0.2.6. -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 07 07 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * fill ucStaRecIdx into SW_RFB_T. -+ * -+ * 07 02 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) for event packet, no need to fill RFB. -+ * 2) when wlanAdapterStart() failed, no need to initialize state machines -+ * 3) after Beacon/ProbeResp parsing, corresponding BSS_DESC_T should be marked as IE-parsed -+ * -+ * 07 01 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * implementation of DRV-SCN and related mailbox message handling. -+ * -+ * 06 29 2010 yarco.yang -+ * [WPD00003837][MT6620]Data Path Refine -+ * replace g_rQM with Adpater->rQM -+ * -+ * 06 23 2010 yarco.yang -+ * [WPD00003837][MT6620]Data Path Refine -+ * Merge g_arStaRec[] into adapter->arStaRec[] -+ * -+ * 06 22 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) add command warpper for STA-REC/BSS-INFO sync. -+ * 2) enhance command packet sending procedure for non-oid part -+ * 3) add command packet definitions for STA-REC/BSS-INFO sync. -+ * -+ * 06 21 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * refine TX-DONE callback. -+ * -+ * 06 21 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * implement TX_DONE callback path. -+ * -+ * 06 21 2010 yarco.yang -+ * [WPD00003837][MT6620]Data Path Refine -+ * Add TX Done Event handle entry -+ * -+ * 06 21 2010 wh.su -+ * [WPD00003840][MT6620 5931] Security migration -+ * remove duplicate variable for migration. -+ * -+ * 06 15 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * . -+ * -+ * 06 15 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * . -+ * -+ * 06 14 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * saa_fsm.c is migrated. -+ * -+ * 06 14 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add management dispatching function table. -+ * -+ * 06 11 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) migrate assoc.c. -+ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness -+ * 3) add configuration options for CNM_MEM and RSN modules -+ * 4) add data path for management frames -+ * 5) eliminate rPacketInfo of MSDU_INFO_T -+ * -+ * 06 10 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) eliminate CFG_CMD_EVENT_VERSION_0_9 -+ * 2) when disconnected, indicate nic directly (no event is needed) -+ * -+ * 06 08 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * cnm_timer has been migrated. -+ * -+ * 06 07 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * merge wlan_def.h. -+ * -+ * 06 07 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * sync with MT6620 driver for scan result replacement policy -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 05 20 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) integrate OID_GEN_NETWORK_LAYER_ADDRESSES with CMD_ID_SET_IP_ADDRESS -+ * 2) buffer statistics data for 2 seconds -+ * 3) use default value for adhoc parameters instead of 0 -+ * -+ * 05 19 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) do not take timeout mechanism for power mode oids -+ * 2) retrieve network type from connection status -+ * 3) after disassciation, set radio state to off -+ * 4) TCP option over IPv6 is supported -+ * -+ * 04 29 2010 wh.su -+ * [WPD00003816][MT6620 Wi-Fi] Adding the security support -+ * fixing the PMKID candicate indicate code. -+ * -+ * 04 28 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * change prefix for data structure used to communicate with 802.11 PAL -+ * to avoid ambiguous naming with firmware interface -+ * -+ * 04 27 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * basic implementation for EVENT_BT_OVER_WIFI -+ * -+ * 04 23 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * surpress compiler warning -+ * -+ * 04 22 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * -+ * 1) modify rx path code for supporting Wi-Fi direct -+ * 2) modify config.h since Linux dont need to consider retaining packet -+ * -+ * 04 16 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * treat BUS access failure as kind of card removal. -+ * -+ * 04 14 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * nicRxProcessEvent packet doesn't access spin-lock directly from now on. -+ * -+ * 04 14 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * do not need to release the spin lock due to it is done inside nicGetPendingCmdInfo() -+ * -+ * 04 13 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * add framework for BT-over-Wi-Fi support. -+ * * * * * * * * * * * * * * * 1) prPendingCmdInfo is replaced by queue for multiple handler capability -+ * * * * * * * * * * * * * * * 2) command sequence number is now increased atomically -+ * * * * * * * * * * * * * * * 3) private data could be hold and taken use for other purpose -+ * -+ * 04 12 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * add channel frequency <-> number conversion -+ * -+ * 04 09 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * 1) add spinlock -+ * 2) add KAPI for handling association info -+ * -+ * 04 07 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * rWlanInfo should be placed at adapter rather than glue due to most operations -+ * * * * * are done in adapter layer. -+ * -+ * 04 07 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * eliminate direct access to prGlueInfo->eParamMediaStateIndicated from non-glue layer -+ * -+ * 04 06 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * eliminate direct access for prGlueInfo->fgIsCardRemoved in non-glue layer -+ * -+ * 04 01 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * improve Linux supplicant compliance -+ * -+ * 03 31 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * fix ioctl which may cause cmdinfo memory leak -+ * -+ * 03 30 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * remove driver-land statistics. -+ * -+ * 03 29 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * improve none-glue code portability -+ * -+ * 03 28 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * rWlanInfo is modified before data is indicated to OS -+ * -+ * 03 28 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * rWlanInfo is modified before data is indicated to OS -+ * -+ * 03 26 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * add a temporary flag for integration with CMD/EVENT v0.9. -+ * -+ * 03 25 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) correct OID_802_11_CONFIGURATION with frequency setting behavior. -+ * * * the frequency is used for adhoc connection only -+ * * * 2) update with SD1 v0.9 CMD/EVENT documentation -+ * -+ * 03 24 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * initial import for Linux port -+ * -+ * 03 24 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * . -+ * -+ * 03 24 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * generate information for OID_GEN_RCV_OK & OID_GEN_XMIT_OK -+ * * * * -+ * -+ * 03 19 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) add ACPI D0/D3 state switching support -+ * * * * * * * * * 2) use more formal way to handle interrupt when the status is retrieved from enhanced RX -+ * response -+ * -+ * 03 15 2010 kevin.huang -+ * [WPD00003820][MT6620 Wi-Fi] Modify the code for meet the WHQL test -+ * Add event for activate STA_RECORD_T -+ * -+ * 03 12 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * correct fgSetQuery/fgNeedResp check -+ * -+ * 03 11 2010 cp.wu -+ * [WPD00003821][BUG] Host driver stops processing RX packets from HIF RX0 -+ * add RX starvation warning debug message controlled by CFG_HIF_RX_STARVATION_WARNING -+ * -+ * 03 10 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * code clean: removing unused variables and structure definitions -+ * -+ * 03 08 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) add another spin-lock to protect MsduInfoList due to it might be accessed by different thread. -+ * * * 2) change own-back acquiring procedure to wait for up to 16.67 seconds -+ * -+ * 03 02 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) the use of prPendingOid revised, all accessing are now protected by spin lock -+ * * * * 2) ensure wlanReleasePendingOid will clear all command queues -+ * -+ * 03 02 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * add mutex to avoid multiple access to qmTxQueue simultaneously. -+ * -+ * 02 26 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * move EVENT_ID_ASSOC_INFO from nic_rx.c to gl_kal_ndis_51.c -+ * * 'cause it involves OS dependent data structure handling -+ * -+ * 02 25 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * correct behavior to prevent duplicated RX handling for RX0_DONE and RX1_DONE -+ * -+ * 02 24 2010 tehuang.liu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * Updated API interfaces for qmHandleEventRxAddBa() and qmHandleEventRxDelBa() -+ * -+ * 02 10 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * implement host-side firmware download logic -+ * -+ * 02 10 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) remove unused function in nic_rx.c [which has been handled in que_mgt.c] -+ * * * * * 2) firmware image length is now retrieved via NdisFileOpen -+ * * * * * 3) firmware image is not structured by (P_IMG_SEC_HDR_T) anymore -+ * * * * * 4) nicRxWaitResponse() revised -+ * * * * * 5) another set of TQ counter default value is added for fw-download state -+ * * * * * 6) Wi-Fi load address is now retrieved from registry too -+ * -+ * 02 09 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1. Permanent and current MAC address are now retrieved by CMD/EVENT packets instead of hard-coded address -+ * * * * * * * * 2. follow MSDN defined behavior when associates to another AP -+ * * * * * * * * 3. for firmware download, packet size could be up to 2048 bytes -+ * -+ * 01 27 2010 wh.su -+ * [WPD00003816][MT6620 Wi-Fi] Adding the security support -+ * . -+ * -+ * 01 22 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * implement following 802.11 OIDs: -+ * * * * * * OID_802_11_RSSI, -+ * * * * * * OID_802_11_RSSI_TRIGGER, -+ * * * * * * OID_802_11_STATISTICS, -+ * * * * * * OID_802_11_DISASSOCIATE, -+ * * * * * * OID_802_11_POWER_MODE -+ * -+ * 12 30 2009 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) According to CMD/EVENT documentation v0.8, -+ * * * * * * * * * OID_CUSTOM_TEST_RX_STATUS & OID_CUSTOM_TEST_TX_STATUS is no longer used, -+ * * * * * * * * * and result is retrieved by get ATInfo instead -+ * * * * * * * * * 2) add 4 counter for recording aggregation statistics -+ * -+ * 12 23 2009 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * add a precheck: if free sw rfb is not enough, do not invoke read transactionu1rwduu`wvpghlqg|fu+rp -+ * -+ * 12 22 2009 cp.wu -+ * [WPD00003809][Bug] Host driver will crash when processing reordered MSDUs -+ * The root cause is pointer accessing by mistake. After dequeued from reordering-buffer, handling logic should access -+ * returned pointer instead of pointer which has been passed in before. -+** \main\maintrunk.MT6620WiFiDriver_Prj\58 2009-12-17 13:40:33 GMT mtk02752 -+** always update prAdapter->rSDIOCtrl when enhanced response is read by RX -+** \main\maintrunk.MT6620WiFiDriver_Prj\57 2009-12-16 18:01:38 GMT mtk02752 -+** if interrupt enhanced response is fetched by RX enhanced response, RX needs to invoke interrupt handlers too -+** \main\maintrunk.MT6620WiFiDriver_Prj\56 2009-12-16 14:16:52 GMT mtk02752 -+** \main\maintrunk.MT6620WiFiDriver_Prj\55 2009-12-15 20:03:12 GMT mtk02752 -+** ASSERT when RX FreeSwRfb is not enough -+** \main\maintrunk.MT6620WiFiDriver_Prj\54 2009-12-15 17:01:29 GMT mtk02752 -+** when CFG_SDIO_RX_ENHANCE is enabled, after enhanced response is read, rx procedure should process -+** 1) TX_DONE_INT 2) D2H INT as well -+** \main\maintrunk.MT6620WiFiDriver_Prj\53 2009-12-14 20:45:28 GMT mtk02752 -+** when CFG_SDIO_RX_ENHANCE is set, TC counter must be updated each time RX enhance response is read -+** -+** \main\maintrunk.MT6620WiFiDriver_Prj\52 2009-12-14 11:34:16 GMT mtk02752 -+** correct a trivial logic issue -+** \main\maintrunk.MT6620WiFiDriver_Prj\51 2009-12-14 10:28:25 GMT mtk02752 -+** add a protection to avoid out-of-boundary access -+** \main\maintrunk.MT6620WiFiDriver_Prj\50 2009-12-10 16:55:18 GMT mtk02752 -+** code clean -+** \main\maintrunk.MT6620WiFiDriver_Prj\49 2009-12-09 14:06:47 GMT MTK02468 -+** Added parsing event packets with EVENT_ID_RX_ADDBA or EVENT_ID_RX_DELBA -+** \main\maintrunk.MT6620WiFiDriver_Prj\48 2009-12-08 17:37:51 GMT mtk02752 -+** handle EVENT_ID_TEST_STATUS as well -+** \main\maintrunk.MT6620WiFiDriver_Prj\47 2009-12-04 17:59:11 GMT mtk02752 -+** to pass free-build compilation check -+** \main\maintrunk.MT6620WiFiDriver_Prj\46 2009-12-04 12:09:52 GMT mtk02752 -+** correct trivial mistake -+** \main\maintrunk.MT6620WiFiDriver_Prj\45 2009-12-04 11:53:37 GMT mtk02752 -+** all API should be compilable under SD1_SD3_DATAPATH_INTEGRATION == 0 -+** \main\maintrunk.MT6620WiFiDriver_Prj\44 2009-12-03 16:19:48 GMT mtk01461 -+** Fix the Connected Event -+** \main\maintrunk.MT6620WiFiDriver_Prj\43 2009-11-30 10:56:18 GMT mtk02752 -+** 1st DW of WIFI_EVENT_T is shared with HIF_RX_HEADER_T -+** \main\maintrunk.MT6620WiFiDriver_Prj\42 2009-11-30 10:11:27 GMT mtk02752 -+** implement replacement for bss scan result -+** \main\maintrunk.MT6620WiFiDriver_Prj\41 2009-11-27 11:08:05 GMT mtk02752 -+** add flush for reset -+** \main\maintrunk.MT6620WiFiDriver_Prj\40 2009-11-26 09:38:59 GMT mtk02752 -+** \main\maintrunk.MT6620WiFiDriver_Prj\39 2009-11-26 09:29:40 GMT mtk02752 -+** enable packet forwarding path (for AP mode) -+** \main\maintrunk.MT6620WiFiDriver_Prj\38 2009-11-25 21:37:00 GMT mtk02752 -+** sync. with EVENT_SCAN_RESULT_T change, and add an assert for checking event size -+** \main\maintrunk.MT6620WiFiDriver_Prj\37 2009-11-25 20:17:41 GMT mtk02752 -+** fill HIF_TX_HEADER_T.u2SeqNo -+** \main\maintrunk.MT6620WiFiDriver_Prj\36 2009-11-25 18:18:57 GMT mtk02752 -+** buffer scan result to prGlueInfo->rWlanInfo.arScanResult directly. -+** \main\maintrunk.MT6620WiFiDriver_Prj\35 2009-11-24 22:42:45 GMT mtk02752 -+** add nicRxAddScanResult() to prepare to handle SCAN_RESULT event (not implemented yet) -+** \main\maintrunk.MT6620WiFiDriver_Prj\34 2009-11-24 20:51:41 GMT mtk02752 -+** integrate with SD1's data path API -+** \main\maintrunk.MT6620WiFiDriver_Prj\33 2009-11-24 19:56:17 GMT mtk02752 -+** adopt P_HIF_RX_HEADER_T in new path -+** \main\maintrunk.MT6620WiFiDriver_Prj\32 2009-11-23 20:31:21 GMT mtk02752 -+** payload to send into pfCmdDoneHandler() will not include WIFI_EVENT_T -+** \main\maintrunk.MT6620WiFiDriver_Prj\31 2009-11-23 17:51:34 GMT mtk02752 -+** when event packet corresponding to some pendingOID is received, pendingOID should be cleared -+** \main\maintrunk.MT6620WiFiDriver_Prj\30 2009-11-23 14:46:54 GMT mtk02752 -+** implement nicRxProcessEventPacket() -+** \main\maintrunk.MT6620WiFiDriver_Prj\29 2009-11-17 22:40:54 GMT mtk01084 -+** \main\maintrunk.MT6620WiFiDriver_Prj\28 2009-11-16 21:48:22 GMT mtk02752 -+** add SD1_SD3_DATAPATH_INTEGRATION data path handling -+** \main\maintrunk.MT6620WiFiDriver_Prj\27 2009-11-16 15:41:18 GMT mtk01084 -+** modify the length to be read in emu mode -+** \main\maintrunk.MT6620WiFiDriver_Prj\26 2009-11-13 17:00:12 GMT mtk02752 -+** add blank function for event packet -+** \main\maintrunk.MT6620WiFiDriver_Prj\25 2009-11-13 13:54:24 GMT mtk01084 -+** \main\maintrunk.MT6620WiFiDriver_Prj\24 2009-11-11 14:41:51 GMT mtk02752 -+** fix typo -+** \main\maintrunk.MT6620WiFiDriver_Prj\23 2009-11-11 14:33:46 GMT mtk02752 -+** add protection when there is no packet avilable -+** \main\maintrunk.MT6620WiFiDriver_Prj\22 2009-11-11 12:33:36 GMT mtk02752 -+** add RX1 read path for aggregated/enhanced/normal packet read procedures -+** \main\maintrunk.MT6620WiFiDriver_Prj\21 2009-11-11 10:36:18 GMT mtk01084 -+** \main\maintrunk.MT6620WiFiDriver_Prj\20 2009-11-04 14:11:08 GMT mtk01084 -+** modify lines in RX aggregation -+** \main\maintrunk.MT6620WiFiDriver_Prj\19 2009-10-30 18:17:23 GMT mtk01084 -+** modify RX aggregation handling -+** \main\maintrunk.MT6620WiFiDriver_Prj\18 2009-10-29 19:56:12 GMT mtk01084 -+** modify HAL part -+** \main\maintrunk.MT6620WiFiDriver_Prj\17 2009-10-23 16:08:34 GMT mtk01084 -+** \main\maintrunk.MT6620WiFiDriver_Prj\16 2009-10-13 21:59:20 GMT mtk01084 -+** update for new HW design -+** \main\maintrunk.MT6620WiFiDriver_Prj\15 2009-10-02 13:59:08 GMT mtk01725 -+** \main\maintrunk.MT6620WiFiDriver_Prj\14 2009-05-21 23:39:05 GMT mtk01461 -+** Fix the paste error of RX STATUS in OOB of HIF Loopback CTRL -+** \main\maintrunk.MT6620WiFiDriver_Prj\13 2009-05-20 12:25:32 GMT mtk01461 -+** Fix process of Read Done, and add u4MaxEventBufferLen to nicRxWaitResponse() -+** \main\maintrunk.MT6620WiFiDriver_Prj\12 2009-05-18 21:13:18 GMT mtk01426 -+** Fixed compiler error -+** \main\maintrunk.MT6620WiFiDriver_Prj\11 2009-05-18 21:05:29 GMT mtk01426 -+** Fixed nicRxSDIOAggReceiveRFBs() ASSERT issue -+** \main\maintrunk.MT6620WiFiDriver_Prj\10 2009-04-28 10:38:43 GMT mtk01461 -+** Fix RX STATUS is DW align for SDIO_STATUS_ENHANCE mode and refine nicRxSDIOAggeceiveRFBs() for RX Aggregation -+** \main\maintrunk.MT6620WiFiDriver_Prj\9 2009-04-22 09:12:17 GMT mtk01461 -+** Fix nicRxProcessHIFLoopbackPacket(), the size of HIF CTRL LENGTH field is 1 byte -+** \main\maintrunk.MT6620WiFiDriver_Prj\8 2009-04-14 15:51:26 GMT mtk01426 -+** Update RX OOB Setting -+** \main\maintrunk.MT6620WiFiDriver_Prj\7 2009-04-03 14:58:58 GMT mtk01426 -+** Fixed logical error -+** \main\maintrunk.MT6620WiFiDriver_Prj\6 2009-04-01 10:58:31 GMT mtk01461 -+** Rename the HIF_PKT_TYPE_DATA -+** \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-03-23 21:51:18 GMT mtk01461 -+** Fix u4HeaderOffset in nicRxProcessHIFLoopbackPacket() -+** \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-03-18 21:02:58 GMT mtk01426 -+** Add CFG_SDIO_RX_ENHANCE and CFG_HIF_LOOPBACK support -+** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-03-17 20:20:59 GMT mtk01426 -+** Add nicRxWaitResponse function -+** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 20:26:01 GMT mtk01426 -+** Init for develop -+** -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "precomp.h" -+ -+#ifndef LINUX -+#include -+#else -+#include -+#endif -+ -+#include "gl_os.h" -+#include "debug.h" -+#include "wlan_lib.h" -+#include "gl_wext.h" -+#include -+#include -+#include -+#include "gl_cfg80211.h" -+#include "gl_vendor.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+#define RX_RESPONSE_TIMEOUT (1000) -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+#if CFG_MGMT_FRAME_HANDLING -+static PROCESS_RX_MGT_FUNCTION apfnProcessRxMgtFrame[MAX_NUM_OF_FC_SUBTYPES] = { -+#if CFG_SUPPORT_AAA -+ aaaFsmRunEventRxAssoc, /* subtype 0000: Association request */ -+#else -+ NULL, /* subtype 0000: Association request */ -+#endif /* CFG_SUPPORT_AAA */ -+ saaFsmRunEventRxAssoc, /* subtype 0001: Association response */ -+#if CFG_SUPPORT_AAA -+ aaaFsmRunEventRxAssoc, /* subtype 0010: Reassociation request */ -+#else -+ NULL, /* subtype 0010: Reassociation request */ -+#endif /* CFG_SUPPORT_AAA */ -+ saaFsmRunEventRxAssoc, /* subtype 0011: Reassociation response */ -+#if (CFG_SUPPORT_ADHOC) || (CFG_SUPPORT_AAA) -+ bssProcessProbeRequest, /* subtype 0100: Probe request */ -+#else -+ NULL, /* subtype 0100: Probe request */ -+#endif /* CFG_SUPPORT_ADHOC */ -+ scanProcessBeaconAndProbeResp, /* subtype 0101: Probe response */ -+ NULL, /* subtype 0110: reserved */ -+ NULL, /* subtype 0111: reserved */ -+ scanProcessBeaconAndProbeResp, /* subtype 1000: Beacon */ -+ NULL, /* subtype 1001: ATIM */ -+ saaFsmRunEventRxDisassoc, /* subtype 1010: Disassociation */ -+ authCheckRxAuthFrameTransSeq, /* subtype 1011: Authentication */ -+ saaFsmRunEventRxDeauth, /* subtype 1100: Deauthentication */ -+ nicRxProcessActionFrame, /* subtype 1101: Action */ -+ NULL, /* subtype 1110: reserved */ -+ NULL /* subtype 1111: reserved */ -+}; -+#endif -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Initialize the RFBs -+* -+* @param prAdapter Pointer to the Adapter structure. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicRxInitialize(IN P_ADAPTER_T prAdapter) -+{ -+ P_RX_CTRL_T prRxCtrl; -+ PUINT_8 pucMemHandle; -+ P_SW_RFB_T prSwRfb = (P_SW_RFB_T) NULL; -+ UINT_32 i; -+ -+ DEBUGFUNC("nicRxInitialize"); -+ -+ ASSERT(prAdapter); -+ prRxCtrl = &prAdapter->rRxCtrl; -+ -+ /* 4 <0> Clear allocated memory. */ -+ kalMemZero((PVOID) prRxCtrl->pucRxCached, prRxCtrl->u4RxCachedSize); -+ -+ /* 4 <1> Initialize the RFB lists */ -+ QUEUE_INITIALIZE(&prRxCtrl->rFreeSwRfbList); -+ QUEUE_INITIALIZE(&prRxCtrl->rReceivedRfbList); -+ QUEUE_INITIALIZE(&prRxCtrl->rIndicatedRfbList); -+ -+ pucMemHandle = prRxCtrl->pucRxCached; -+ for (i = CFG_RX_MAX_PKT_NUM; i != 0; i--) { -+ prSwRfb = (P_SW_RFB_T) pucMemHandle; -+ -+ nicRxSetupRFB(prAdapter, prSwRfb); -+ nicRxReturnRFB(prAdapter, prSwRfb); -+ -+ pucMemHandle += ALIGN_4(sizeof(SW_RFB_T)); -+ } -+ -+ ASSERT(prRxCtrl->rFreeSwRfbList.u4NumElem == CFG_RX_MAX_PKT_NUM); -+ /* Check if the memory allocation consist with this initialization function */ -+ ASSERT((ULONG) (pucMemHandle - prRxCtrl->pucRxCached) == prRxCtrl->u4RxCachedSize); -+ -+ /* 4 <2> Clear all RX counters */ -+ RX_RESET_ALL_CNTS(prRxCtrl); -+ -+#if CFG_SDIO_RX_AGG -+ prRxCtrl->pucRxCoalescingBufPtr = prAdapter->pucCoalescingBufCached; -+ HAL_CFG_MAX_HIF_RX_LEN_NUM(prAdapter, CFG_SDIO_MAX_RX_AGG_NUM); -+#else -+ HAL_CFG_MAX_HIF_RX_LEN_NUM(prAdapter, 1); -+#endif -+ -+#if CFG_HIF_STATISTICS -+ prRxCtrl->u4TotalRxAccessNum = 0; -+ prRxCtrl->u4TotalRxPacketNum = 0; -+#endif -+ -+#if CFG_HIF_RX_STARVATION_WARNING -+ prRxCtrl->u4QueuedCnt = 0; -+ prRxCtrl->u4DequeuedCnt = 0; -+#endif -+ -+} /* end of nicRxInitialize() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Uninitialize the RFBs -+* -+* @param prAdapter Pointer to the Adapter structure. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicRxUninitialize(IN P_ADAPTER_T prAdapter) -+{ -+ P_RX_CTRL_T prRxCtrl; -+ P_SW_RFB_T prSwRfb = (P_SW_RFB_T) NULL; -+ -+ KAL_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(prAdapter); -+ prRxCtrl = &prAdapter->rRxCtrl; -+ ASSERT(prRxCtrl); -+ -+ nicRxFlush(prAdapter); -+ -+ do { -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); -+ QUEUE_REMOVE_HEAD(&prRxCtrl->rReceivedRfbList, prSwRfb, P_SW_RFB_T); -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); -+ if (prSwRfb) { -+ if (prSwRfb->pvPacket) -+ kalPacketFree(prAdapter->prGlueInfo, prSwRfb->pvPacket); -+ prSwRfb->pvPacket = NULL; -+ } else { -+ break; -+ } -+ } while (TRUE); -+ -+ do { -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); -+ QUEUE_REMOVE_HEAD(&prRxCtrl->rFreeSwRfbList, prSwRfb, P_SW_RFB_T); -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); -+ if (prSwRfb) { -+ if (prSwRfb->pvPacket) -+ kalPacketFree(prAdapter->prGlueInfo, prSwRfb->pvPacket); -+ prSwRfb->pvPacket = NULL; -+ } else { -+ break; -+ } -+ } while (TRUE); -+ -+} /* end of nicRxUninitialize() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Fill RFB -+* -+* @param prAdapter pointer to the Adapter handler -+* @param prSWRfb specify the RFB to receive rx data -+* -+* @return (none) -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicRxFillRFB(IN P_ADAPTER_T prAdapter, IN OUT P_SW_RFB_T prSwRfb) -+{ -+ P_HIF_RX_HEADER_T prHifRxHdr; -+ -+ UINT_32 u4PktLen = 0; -+ UINT_32 u4MacHeaderLen; -+ UINT_32 u4HeaderOffset; -+ -+ DEBUGFUNC("nicRxFillRFB"); -+ -+ ASSERT(prAdapter); -+ ASSERT(prSwRfb); -+ -+ prHifRxHdr = prSwRfb->prHifRxHdr; -+ ASSERT(prHifRxHdr); -+ -+ u4PktLen = prHifRxHdr->u2PacketLen; -+ -+ u4HeaderOffset = (UINT_32) (prHifRxHdr->ucHerderLenOffset & HIF_RX_HDR_HEADER_OFFSET_MASK); -+ u4MacHeaderLen = (UINT_32) (prHifRxHdr->ucHerderLenOffset & HIF_RX_HDR_HEADER_LEN) -+ >> HIF_RX_HDR_HEADER_LEN_OFFSET; -+ -+ /* DBGLOG(RX, TRACE, ("u4HeaderOffset = %d, u4MacHeaderLen = %d\n", */ -+ /* u4HeaderOffset, u4MacHeaderLen)); */ -+ -+ prSwRfb->u2HeaderLen = (UINT_16) u4MacHeaderLen; -+ prSwRfb->pvHeader = (PUINT_8) prHifRxHdr + HIF_RX_HDR_SIZE + u4HeaderOffset; -+ prSwRfb->u2PacketLen = (UINT_16) (u4PktLen - (HIF_RX_HDR_SIZE + u4HeaderOffset)); -+ -+ /* DBGLOG(RX, TRACE, ("Dump Rx packet, u2PacketLen = %d\n", prSwRfb->u2PacketLen)); */ -+ /* DBGLOG_MEM8(RX, TRACE, prSwRfb->pvHeader, prSwRfb->u2PacketLen); */ -+ -+#if 0 -+ if (prHifRxHdr->ucReorder & HIF_RX_HDR_80211_HEADER_FORMAT) { -+ prSwRfb->u4HifRxHdrFlag |= HIF_RX_HDR_FLAG_802_11_FORMAT; -+ DBGLOG(RX, TRACE, "HIF_RX_HDR_FLAG_802_11_FORMAT\n"); -+ } -+ -+ if (prHifRxHdr->ucReorder & HIF_RX_HDR_DO_REORDER) { -+ prSwRfb->u4HifRxHdrFlag |= HIF_RX_HDR_FLAG_DO_REORDERING; -+ DBGLOG(RX, TRACE, "HIF_RX_HDR_FLAG_DO_REORDERING\n"); -+ -+ /* Get Seq. No and TID, Wlan Index info */ -+ if (prHifRxHdr->u2SeqNoTid & HIF_RX_HDR_BAR_FRAME) { -+ prSwRfb->u4HifRxHdrFlag |= HIF_RX_HDR_FLAG_BAR_FRAME; -+ DBGLOG(RX, TRACE, "HIF_RX_HDR_FLAG_BAR_FRAME\n"); -+ } -+ -+ prSwRfb->u2SSN = prHifRxHdr->u2SeqNoTid & HIF_RX_HDR_SEQ_NO_MASK; -+ prSwRfb->ucTid = (UINT_8) ((prHifRxHdr->u2SeqNoTid & HIF_RX_HDR_TID_MASK) -+ >> HIF_RX_HDR_TID_OFFSET); -+ DBGLOG(RX, TRACE, "u2SSN = %d, ucTid = %d\n", prSwRfb->u2SSN, prSwRfb->ucTid); -+ } -+ -+ if (prHifRxHdr->ucReorder & HIF_RX_HDR_WDS) { -+ prSwRfb->u4HifRxHdrFlag |= HIF_RX_HDR_FLAG_AMP_WDS; -+ DBGLOG(RX, TRACE, "HIF_RX_HDR_FLAG_AMP_WDS\n"); -+ } -+#endif -+} -+ -+#if CFG_TCP_IP_CHKSUM_OFFLOAD || CFG_TCP_IP_CHKSUM_OFFLOAD_NDIS_60 -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Fill checksum status in RFB -+* -+* @param prAdapter pointer to the Adapter handler -+* @param prSWRfb the RFB to receive rx data -+* @param u4TcpUdpIpCksStatus specify the Checksum status -+* -+* @return (none) -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicRxFillChksumStatus(IN P_ADAPTER_T prAdapter, IN OUT P_SW_RFB_T prSwRfb, IN UINT_32 u4TcpUdpIpCksStatus) -+{ -+ -+ ASSERT(prAdapter); -+ ASSERT(prSwRfb); -+ -+ if (prAdapter->u4CSUMFlags != CSUM_NOT_SUPPORTED) { -+ if (u4TcpUdpIpCksStatus & RX_CS_TYPE_IPv4) { /* IPv4 packet */ -+ prSwRfb->aeCSUM[CSUM_TYPE_IPV6] = CSUM_RES_NONE; -+ if (u4TcpUdpIpCksStatus & RX_CS_STATUS_IP) { /* IP packet csum failed */ -+ prSwRfb->aeCSUM[CSUM_TYPE_IPV4] = CSUM_RES_FAILED; -+ } else { -+ prSwRfb->aeCSUM[CSUM_TYPE_IPV4] = CSUM_RES_SUCCESS; -+ } -+ -+ if (u4TcpUdpIpCksStatus & RX_CS_TYPE_TCP) { /* TCP packet */ -+ prSwRfb->aeCSUM[CSUM_TYPE_UDP] = CSUM_RES_NONE; -+ if (u4TcpUdpIpCksStatus & RX_CS_STATUS_TCP) { /* TCP packet csum failed */ -+ prSwRfb->aeCSUM[CSUM_TYPE_TCP] = CSUM_RES_FAILED; -+ } else { -+ prSwRfb->aeCSUM[CSUM_TYPE_TCP] = CSUM_RES_SUCCESS; -+ } -+ } else if (u4TcpUdpIpCksStatus & RX_CS_TYPE_UDP) { /* UDP packet */ -+ prSwRfb->aeCSUM[CSUM_TYPE_TCP] = CSUM_RES_NONE; -+ if (u4TcpUdpIpCksStatus & RX_CS_STATUS_UDP) { /* UDP packet csum failed */ -+ prSwRfb->aeCSUM[CSUM_TYPE_UDP] = CSUM_RES_FAILED; -+ } else { -+ prSwRfb->aeCSUM[CSUM_TYPE_UDP] = CSUM_RES_SUCCESS; -+ } -+ } else { -+ prSwRfb->aeCSUM[CSUM_TYPE_UDP] = CSUM_RES_NONE; -+ prSwRfb->aeCSUM[CSUM_TYPE_TCP] = CSUM_RES_NONE; -+ } -+ } else if (u4TcpUdpIpCksStatus & RX_CS_TYPE_IPv6) { /* IPv6 packet */ -+ prSwRfb->aeCSUM[CSUM_TYPE_IPV4] = CSUM_RES_NONE; -+ prSwRfb->aeCSUM[CSUM_TYPE_IPV6] = CSUM_RES_SUCCESS; -+ -+ if (u4TcpUdpIpCksStatus & RX_CS_TYPE_TCP) { /* TCP packet */ -+ prSwRfb->aeCSUM[CSUM_TYPE_UDP] = CSUM_RES_NONE; -+ if (u4TcpUdpIpCksStatus & RX_CS_STATUS_TCP) { /* TCP packet csum failed */ -+ prSwRfb->aeCSUM[CSUM_TYPE_TCP] = CSUM_RES_FAILED; -+ } else { -+ prSwRfb->aeCSUM[CSUM_TYPE_TCP] = CSUM_RES_SUCCESS; -+ } -+ } else if (u4TcpUdpIpCksStatus & RX_CS_TYPE_UDP) { /* UDP packet */ -+ prSwRfb->aeCSUM[CSUM_TYPE_TCP] = CSUM_RES_NONE; -+ if (u4TcpUdpIpCksStatus & RX_CS_STATUS_UDP) { /* UDP packet csum failed */ -+ prSwRfb->aeCSUM[CSUM_TYPE_UDP] = CSUM_RES_FAILED; -+ } else { -+ prSwRfb->aeCSUM[CSUM_TYPE_UDP] = CSUM_RES_SUCCESS; -+ } -+ } else { -+ prSwRfb->aeCSUM[CSUM_TYPE_UDP] = CSUM_RES_NONE; -+ prSwRfb->aeCSUM[CSUM_TYPE_TCP] = CSUM_RES_NONE; -+ } -+ } else { -+ prSwRfb->aeCSUM[CSUM_TYPE_IPV4] = CSUM_RES_NONE; -+ prSwRfb->aeCSUM[CSUM_TYPE_IPV6] = CSUM_RES_NONE; -+ } -+ } -+ -+} -+#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Process packet doesn't need to do buffer reordering -+* -+* @param prAdapter pointer to the Adapter handler -+* @param prSWRfb the RFB to receive rx data -+* -+* @return (none) -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicRxProcessPktWithoutReorder(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb) -+{ -+ P_RX_CTRL_T prRxCtrl; -+ P_TX_CTRL_T prTxCtrl; -+ BOOLEAN fgIsRetained = FALSE; -+ UINT_32 u4CurrentRxBufferCount; -+ P_STA_RECORD_T prStaRec = (P_STA_RECORD_T) NULL; -+ -+ DEBUGFUNC("nicRxProcessPktWithoutReorder"); -+ /* DBGLOG(RX, TRACE, ("\n")); */ -+ -+ ASSERT(prAdapter); -+ ASSERT(prSwRfb); -+ -+ prRxCtrl = &prAdapter->rRxCtrl; -+ ASSERT(prRxCtrl); -+ -+ prTxCtrl = &prAdapter->rTxCtrl; -+ ASSERT(prTxCtrl); -+ -+ u4CurrentRxBufferCount = prRxCtrl->rFreeSwRfbList.u4NumElem; -+ /* QM USED = $A, AVAILABLE COUNT = $B, INDICATED TO OS = $C -+ * TOTAL = $A + $B + $C -+ * -+ * Case #1 (Retain) -+ * ------------------------------------------------------- -+ * $A + $B < THRESHOLD := $A + $B + $C < THRESHOLD + $C := $TOTAL - THRESHOLD < $C -+ * => $C used too much, retain -+ * -+ * Case #2 (Non-Retain) -+ * ------------------------------------------------------- -+ * $A + $B > THRESHOLD := $A + $B + $C > THRESHOLD + $C := $TOTAL - THRESHOLD > $C -+ * => still available for $C to use -+ * -+ */ -+ fgIsRetained = (((u4CurrentRxBufferCount + -+ qmGetRxReorderQueuedBufferCount(prAdapter) + -+ prTxCtrl->i4PendingFwdFrameCount) < CFG_RX_RETAINED_PKT_THRESHOLD) ? TRUE : FALSE); -+ -+ /* DBGLOG(RX, INFO, ("fgIsRetained = %d\n", fgIsRetained)); */ -+ -+ if (kalProcessRxPacket(prAdapter->prGlueInfo, -+ prSwRfb->pvPacket, -+ prSwRfb->pvHeader, -+ (UINT_32) prSwRfb->u2PacketLen, fgIsRetained, prSwRfb->aeCSUM) != WLAN_STATUS_SUCCESS) { -+ DBGLOG(RX, ERROR, "kalProcessRxPacket return value != WLAN_STATUS_SUCCESS\n"); -+ ASSERT(0); -+ -+ nicRxReturnRFB(prAdapter, prSwRfb); -+ return; -+ } -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); -+ -+ if (prStaRec) { -+#if CFG_ENABLE_WIFI_DIRECT -+ if (prStaRec->ucNetTypeIndex == NETWORK_TYPE_P2P_INDEX && prAdapter->fgIsP2PRegistered == TRUE) -+ GLUE_SET_PKT_FLAG_P2P(prSwRfb->pvPacket); -+#endif -+#if CFG_ENABLE_BT_OVER_WIFI -+ if (prStaRec->ucNetTypeIndex == NETWORK_TYPE_BOW_INDEX) -+ GLUE_SET_PKT_FLAG_PAL(prSwRfb->pvPacket); -+#endif -+ -+ /* record the count to pass to os */ -+ STATS_RX_PASS2OS_INC(prStaRec, prSwRfb); -+ } -+ prRxCtrl->apvIndPacket[prRxCtrl->ucNumIndPacket] = prSwRfb->pvPacket; -+ prRxCtrl->ucNumIndPacket++; -+ -+ if (fgIsRetained) { -+ prRxCtrl->apvRetainedPacket[prRxCtrl->ucNumRetainedPacket] = prSwRfb->pvPacket; -+ prRxCtrl->ucNumRetainedPacket++; -+ /* TODO : error handling of nicRxSetupRFB */ -+ nicRxSetupRFB(prAdapter, prSwRfb); -+ nicRxReturnRFB(prAdapter, prSwRfb); -+ } else { -+ prSwRfb->pvPacket = NULL; -+ nicRxReturnRFB(prAdapter, prSwRfb); -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Process forwarding data packet -+* -+* @param prAdapter pointer to the Adapter handler -+* @param prSWRfb the RFB to receive rx data -+* -+* @return (none) -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicRxProcessForwardPkt(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb) -+{ -+ P_MSDU_INFO_T prMsduInfo, prRetMsduInfoList; -+ P_TX_CTRL_T prTxCtrl; -+ P_RX_CTRL_T prRxCtrl; -+ -+ KAL_SPIN_LOCK_DECLARATION(); -+ -+ DEBUGFUNC("nicRxProcessForwardPkt"); -+ -+ ASSERT(prAdapter); -+ ASSERT(prSwRfb); -+ -+ prTxCtrl = &prAdapter->rTxCtrl; -+ prRxCtrl = &prAdapter->rRxCtrl; -+ -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_MSDU_INFO_LIST); -+ QUEUE_REMOVE_HEAD(&prTxCtrl->rFreeMsduInfoList, prMsduInfo, P_MSDU_INFO_T); -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_MSDU_INFO_LIST); -+ -+ if (prMsduInfo && kalProcessRxPacket(prAdapter->prGlueInfo, -+ prSwRfb->pvPacket, -+ prSwRfb->pvHeader, -+ (UINT_32) prSwRfb->u2PacketLen, -+ prRxCtrl->rFreeSwRfbList.u4NumElem < -+ CFG_RX_RETAINED_PKT_THRESHOLD ? TRUE : FALSE, -+ prSwRfb->aeCSUM) == WLAN_STATUS_SUCCESS) { -+ -+ prMsduInfo->eSrc = TX_PACKET_FORWARDING; -+ /* pack into MSDU_INFO_T */ -+ nicTxFillMsduInfo(prAdapter, prMsduInfo, (P_NATIVE_PACKET) (prSwRfb->pvPacket)); -+ /* Overwrite the ucNetworkType */ -+ prMsduInfo->ucNetworkType = HIF_RX_HDR_GET_NETWORK_IDX(prSwRfb->prHifRxHdr); -+ -+ /* release RX buffer (to rIndicatedRfbList) */ -+ prSwRfb->pvPacket = NULL; -+ nicRxReturnRFB(prAdapter, prSwRfb); -+ -+ /* increase forward frame counter */ -+ GLUE_INC_REF_CNT(prTxCtrl->i4PendingFwdFrameCount); -+ -+ /* send into TX queue */ -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_QM_TX_QUEUE); -+ prRetMsduInfoList = qmEnqueueTxPackets(prAdapter, prMsduInfo); -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_QM_TX_QUEUE); -+ -+ if (prRetMsduInfoList != NULL) { /* TX queue refuses queuing the packet */ -+ nicTxFreeMsduInfoPacket(prAdapter, prRetMsduInfoList); -+ nicTxReturnMsduInfo(prAdapter, prRetMsduInfoList); -+ } -+ /* indicate service thread for sending */ -+ if (prTxCtrl->i4PendingFwdFrameCount > 0) -+ kalSetEvent(prAdapter->prGlueInfo); -+ } else /* no TX resource */ -+ nicRxReturnRFB(prAdapter, prSwRfb); -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Process broadcast data packet for both host and forwarding -+* -+* @param prAdapter pointer to the Adapter handler -+* @param prSWRfb the RFB to receive rx data -+* -+* @return (none) -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicRxProcessGOBroadcastPkt(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb) -+{ -+ P_SW_RFB_T prSwRfbDuplicated; -+ P_TX_CTRL_T prTxCtrl; -+ P_RX_CTRL_T prRxCtrl; -+ P_HIF_RX_HEADER_T prHifRxHdr; -+ -+ KAL_SPIN_LOCK_DECLARATION(); -+ -+ DEBUGFUNC("nicRxProcessGOBroadcastPkt"); -+ -+ ASSERT(prAdapter); -+ ASSERT(prSwRfb); -+ -+ prTxCtrl = &prAdapter->rTxCtrl; -+ prRxCtrl = &prAdapter->rRxCtrl; -+ -+ prHifRxHdr = prSwRfb->prHifRxHdr; -+ ASSERT(prHifRxHdr); -+ -+ ASSERT(CFG_NUM_OF_QM_RX_PKT_NUM >= 16); -+ -+ if (prRxCtrl->rFreeSwRfbList.u4NumElem -+ >= (CFG_RX_MAX_PKT_NUM - (CFG_NUM_OF_QM_RX_PKT_NUM - 16 /* Reserved for others */))) { -+ -+ /* 1. Duplicate SW_RFB_T */ -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); -+ QUEUE_REMOVE_HEAD(&prRxCtrl->rFreeSwRfbList, prSwRfbDuplicated, P_SW_RFB_T); -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); -+ -+ if (prSwRfbDuplicated) { -+ kalMemCopy(prSwRfbDuplicated->pucRecvBuff, -+ prSwRfb->pucRecvBuff, ALIGN_4(prHifRxHdr->u2PacketLen + HIF_RX_HW_APPENDED_LEN)); -+ -+ prSwRfbDuplicated->ucPacketType = HIF_RX_PKT_TYPE_DATA; -+ prSwRfbDuplicated->ucStaRecIdx = (UINT_8) (prHifRxHdr->ucStaRecIdx); -+ nicRxFillRFB(prAdapter, prSwRfbDuplicated); -+ -+ /* 2. Modify eDst */ -+ prSwRfbDuplicated->eDst = RX_PKT_DESTINATION_FORWARD; -+ -+ /* 4. Forward */ -+ nicRxProcessForwardPkt(prAdapter, prSwRfbDuplicated); -+ } -+ } else { -+ DBGLOG(RX, WARN, "Stop to forward BMC packet due to less free Sw Rfb %u\n", -+ prRxCtrl->rFreeSwRfbList.u4NumElem); -+ } -+ -+ /* 3. Indicate to host */ -+ prSwRfb->eDst = RX_PKT_DESTINATION_HOST; -+ nicRxProcessPktWithoutReorder(prAdapter, prSwRfb); -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Process HIF data packet -+* -+* @param prAdapter pointer to the Adapter handler -+* @param prSWRfb the RFB to receive rx data -+* -+* @return (none) -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicRxProcessDataPacket(IN P_ADAPTER_T prAdapter, IN OUT P_SW_RFB_T prSwRfb) -+{ -+ P_RX_CTRL_T prRxCtrl; -+ P_SW_RFB_T prRetSwRfb, prNextSwRfb; -+ P_HIF_RX_HEADER_T prHifRxHdr; -+ P_STA_RECORD_T prStaRec; -+ BOOLEAN fIsDummy = FALSE; -+ -+ DEBUGFUNC("nicRxProcessDataPacket"); -+ /* DBGLOG(RX, TRACE, ("\n")); */ -+ -+ ASSERT(prAdapter); -+ ASSERT(prSwRfb); -+ -+ prHifRxHdr = prSwRfb->prHifRxHdr; -+ prRxCtrl = &prAdapter->rRxCtrl; -+ -+ fIsDummy = (prHifRxHdr->u2PacketLen >= 12) ? FALSE : TRUE; -+ -+ nicRxFillRFB(prAdapter, prSwRfb); -+ -+#if CFG_TCP_IP_CHKSUM_OFFLOAD || CFG_TCP_IP_CHKSUM_OFFLOAD_NDIS_60 -+ { -+ UINT_32 u4TcpUdpIpCksStatus; -+ -+ u4TcpUdpIpCksStatus = *((PUINT_32) ((ULONG) prHifRxHdr + (UINT_32) (ALIGN_4(prHifRxHdr->u2PacketLen)))); -+ nicRxFillChksumStatus(prAdapter, prSwRfb, u4TcpUdpIpCksStatus); -+ -+ } -+#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */ -+ -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prHifRxHdr->ucStaRecIdx); -+ if (secCheckClassError(prAdapter, prSwRfb, prStaRec) == TRUE && prAdapter->fgTestMode == FALSE) { -+#if CFG_HIF_RX_STARVATION_WARNING -+ prRxCtrl->u4QueuedCnt++; -+#endif -+ prRetSwRfb = qmHandleRxPackets(prAdapter, prSwRfb); -+ if (prRetSwRfb != NULL) { -+ do { -+ /* save next first */ -+ prNextSwRfb = (P_SW_RFB_T) QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T) prRetSwRfb); -+ if (fIsDummy == TRUE) { -+ nicRxReturnRFB(prAdapter, prRetSwRfb); -+ RX_INC_CNT(prRxCtrl, RX_DROP_TOTAL_COUNT); -+ DBGLOG(RX, WARN, "Drop Dummy Packets"); -+ -+ } else { -+ switch (prRetSwRfb->eDst) { -+ case RX_PKT_DESTINATION_HOST: -+#if ARP_MONITER_ENABLE -+ if (IS_STA_IN_AIS(prStaRec)) -+ qmHandleRxArpPackets(prAdapter, prRetSwRfb); -+#endif -+ nicRxProcessPktWithoutReorder(prAdapter, prRetSwRfb); -+ break; -+ -+ case RX_PKT_DESTINATION_FORWARD: -+ nicRxProcessForwardPkt(prAdapter, prRetSwRfb); -+ break; -+ -+ case RX_PKT_DESTINATION_HOST_WITH_FORWARD: -+ nicRxProcessGOBroadcastPkt(prAdapter, prRetSwRfb); -+ break; -+ -+ case RX_PKT_DESTINATION_NULL: -+ nicRxReturnRFB(prAdapter, prRetSwRfb); -+ RX_INC_CNT(prRxCtrl, RX_DST_NULL_DROP_COUNT); -+ RX_INC_CNT(prRxCtrl, RX_DROP_TOTAL_COUNT); -+ break; -+ -+ default: -+ break; -+ } -+ } -+#if CFG_HIF_RX_STARVATION_WARNING -+ prRxCtrl->u4DequeuedCnt++; -+#endif -+ prRetSwRfb = prNextSwRfb; -+ } while (prRetSwRfb); -+ } -+ } else { -+ nicRxReturnRFB(prAdapter, prSwRfb); -+ RX_INC_CNT(prRxCtrl, RX_CLASS_ERR_DROP_COUNT); -+ RX_INC_CNT(prRxCtrl, RX_DROP_TOTAL_COUNT); -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Process HIF event packet -+* -+* @param prAdapter pointer to the Adapter handler -+* @param prSWRfb the RFB to receive rx data -+* -+* @return (none) -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+ -+UINT_8 nicRxProcessGSCNEvent(IN P_ADAPTER_T prAdapter, IN OUT P_SW_RFB_T prSwRfb) -+{ -+ P_WIFI_EVENT_T prEvent; -+ P_GLUE_INFO_T prGlueInfo; -+ struct sk_buff *skb; -+ struct wiphy *wiphy; -+ -+ UINT_32 real_num = 0; -+ -+ P_EVENT_GSCAN_SCAN_AVAILABLE_T prEventGscnAvailable; -+ P_EVENT_GSCAN_RESULT_T prEventBuffer; -+ P_WIFI_GSCAN_RESULT_T prEventGscnResult; -+ INT_32 i4Status = -EINVAL; -+ struct nlattr *attr; -+ UINT_32 scan_id; -+ UINT_8 scan_flag; -+ P_EVENT_GSCAN_CAPABILITY_T prEventGscnCapbiblity; -+ P_EVENT_GSCAN_SCAN_COMPLETE_T prEventGscnScnDone; -+ P_WIFI_GSCAN_RESULT_T prEventGscnFullResult; -+ P_PARAM_WIFI_GSCAN_RESULT prParamGscnFullResult; -+ P_EVENT_GSCAN_SIGNIFICANT_CHANGE_T prEventGscnSignificantChange; -+ P_EVENT_GSCAN_SIGNIFICANT_CHANGE_T prEventGscnGeofenceFound; -+ -+ P_PARAM_WIFI_GSCAN_RESULT prResults; -+ -+ DEBUGFUNC("nicRxProcessGSCNEvent"); -+ /* DBGLOG(RX, TRACE, ("\n")); */ -+ -+ DBGLOG(SCN, INFO, "nicRxProcessGSCNEvent\n"); -+ -+ ASSERT(prAdapter); -+ ASSERT(prSwRfb); -+ -+ prEvent = (P_WIFI_EVENT_T) prSwRfb->pucRecvBuff; -+ prGlueInfo = prAdapter->prGlueInfo; -+ -+ /* Push the data to the skb */ -+ wiphy = priv_to_wiphy(prGlueInfo); -+ -+ /* prGlueInfo-> */ -+ -+ /* Event Handling */ -+ switch (prEvent->ucEID) { -+ case EVENT_ID_GSCAN_SCAN_AVAILABLE: -+ { -+ DBGLOG(SCN, INFO, "EVENT_ID_GSCAN_SCAN_AVAILABLE\n"); -+ -+ prEventGscnAvailable = (P_EVENT_GSCAN_SCAN_AVAILABLE_T) (prEvent->aucBuffer); -+ memcpy(prEventGscnAvailable, (P_EVENT_GSCAN_SCAN_AVAILABLE_T) (prEvent->aucBuffer), -+ sizeof(EVENT_GSCAN_SCAN_AVAILABLE_T)); -+ -+ mtk_cfg80211_vendor_event_scan_results_available(wiphy, prGlueInfo->prDevHandler->ieee80211_ptr, -+ prEventGscnAvailable->u2Num); -+ } -+ break; -+ -+ case EVENT_ID_GSCAN_RESULT: -+ { -+ DBGLOG(SCN, INFO, "EVENT_ID_GSCAN_RESULT 2\n"); -+ -+ prEventBuffer = (P_EVENT_GSCAN_RESULT_T) (prEvent->aucBuffer); -+ prEventGscnResult = prEventBuffer->rResult; -+/* -+ the following event struct should moved to kal and use the kal api to avoid future porting effort -+ -+*/ -+ scan_id = prEventBuffer->u2ScanId; -+ scan_flag = prEventBuffer->u2ScanFlags; -+ real_num = prEventBuffer->u2NumOfResults; -+ -+ DBGLOG(SCN, INFO, "scan_id=%d, scan_flag =%d, real_num=%d\r\n", scan_id, scan_flag, real_num); -+ -+ skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(PARAM_WIFI_GSCAN_RESULT) * real_num); -+ if (!skb) { -+ DBGLOG(RX, TRACE, "%s allocate skb failed:%x\n", __func__, i4Status); -+ return -ENOMEM; -+ } -+ -+ attr = nla_nest_start(skb, GSCAN_ATTRIBUTE_SCAN_RESULTS); -+ /*NLA_PUT_U32(skb, GSCAN_ATTRIBUTE_SCAN_ID, scan_id);*/ -+ { -+ unsigned int __tmp = scan_id; -+ -+ if (unlikely(nla_put(skb, GSCAN_ATTRIBUTE_SCAN_ID, sizeof(unsigned int), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ /*NLA_PUT_U8(skb, GSCAN_ATTRIBUTE_SCAN_FLAGS, 1);*/ -+ { -+ unsigned char __tmp = 1; -+ -+ if (unlikely(nla_put(skb, GSCAN_ATTRIBUTE_SCAN_FLAGS, sizeof(u8), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ /*NLA_PUT_U32(skb, GSCAN_ATTRIBUTE_NUM_OF_RESULTS, real_num);*/ -+ { -+ unsigned int __tmp = real_num; -+ -+ if (unlikely(nla_put(skb, GSCAN_ATTRIBUTE_NUM_OF_RESULTS, -+ sizeof(unsigned int), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ -+ prResults = (P_PARAM_WIFI_GSCAN_RESULT) prEventGscnResult; -+ if (prResults) -+ DBGLOG(SCN, INFO, "ssid=%s, rssi=%d, channel=%d \r\n", -+ prResults->ssid, prResults->rssi, prResults->channel); -+ /*NLA_PUT(skb, GSCAN_ATTRIBUTE_SCAN_RESULTS, sizeof(PARAM_WIFI_GSCAN_RESULT) * real_num, -+ prResults);*/ -+ -+ if (unlikely(nla_put(skb, GSCAN_ATTRIBUTE_SCAN_RESULTS, -+ sizeof(PARAM_WIFI_GSCAN_RESULT)*real_num, prResults) < 0)) -+ goto nla_put_failure; -+ -+ DBGLOG(SCN, INFO, "NLA_PUT scan results over\t"); -+ -+ if (attr) -+ nla_nest_end(skb, attr); -+ /* report_events=1 */ -+ /*NLA_PUT_U8(skb, GSCAN_ATTRIBUTE_SCAN_RESULTS_COMPLETE, 1);*/ -+ { -+ unsigned char __tmp = 1; -+ -+ if (unlikely(nla_put(skb, GSCAN_ATTRIBUTE_SCAN_RESULTS_COMPLETE, -+ sizeof(unsigned int), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ -+ -+ i4Status = cfg80211_vendor_cmd_reply(skb); -+ skb = NULL; -+ DBGLOG(SCN, INFO, " i4Status %d\n", i4Status); -+ } -+ break; -+ -+ case EVENT_ID_GSCAN_CAPABILITY: -+ { -+ DBGLOG(SCN, INFO, "EVENT_ID_GSCAN_CAPABILITY\n"); -+ -+ prEventGscnCapbiblity = (P_EVENT_GSCAN_CAPABILITY_T) (prEvent->aucBuffer); -+ memcpy(prEventGscnCapbiblity, (P_EVENT_GSCAN_CAPABILITY_T) (prEvent->aucBuffer), -+ sizeof(EVENT_GSCAN_CAPABILITY_T)); -+ -+ mtk_cfg80211_vendor_get_gscan_capabilities(wiphy, prGlueInfo->prDevHandler->ieee80211_ptr, -+ prEventGscnCapbiblity, sizeof(EVENT_GSCAN_CAPABILITY_T)); -+ } -+ break; -+ -+ case EVENT_ID_GSCAN_SCAN_COMPLETE: -+ { -+ DBGLOG(SCN, INFO, "EVENT_ID_GSCAN_SCAN_COMPLETE\n"); -+ prEventGscnScnDone = (P_EVENT_GSCAN_SCAN_COMPLETE_T) (prEvent->aucBuffer); -+ memcpy(prEventGscnScnDone, (P_EVENT_GSCAN_SCAN_COMPLETE_T) (prEvent->aucBuffer), -+ sizeof(EVENT_GSCAN_SCAN_COMPLETE_T)); -+ -+ mtk_cfg80211_vendor_event_complete_scan(wiphy, prGlueInfo->prDevHandler->ieee80211_ptr, -+ prEventGscnScnDone->ucScanState); -+ } -+ break; -+ -+ case EVENT_ID_GSCAN_FULL_RESULT: -+ { -+ DBGLOG(SCN, INFO, "EVENT_ID_GSCAN_FULL_RESULT\n"); -+ -+ prEventGscnFullResult = kalMemAlloc(sizeof(WIFI_GSCAN_RESULT_T), VIR_MEM_TYPE); -+ if (prEventGscnFullResult) -+ memcpy(prEventGscnFullResult, (P_WIFI_GSCAN_RESULT_T) (prEvent->aucBuffer), -+ sizeof(WIFI_GSCAN_RESULT_T)); -+ -+ prParamGscnFullResult = kalMemAlloc(sizeof(PARAM_WIFI_GSCAN_RESULT), VIR_MEM_TYPE); -+ if (prEventGscnFullResult && prParamGscnFullResult) { -+ kalMemZero(prParamGscnFullResult, sizeof(PARAM_WIFI_GSCAN_RESULT)); -+ memcpy(prParamGscnFullResult, prEventGscnFullResult, sizeof(WIFI_GSCAN_RESULT_T)); -+ -+ mtk_cfg80211_vendor_event_full_scan_results(wiphy, -+ prGlueInfo->prDevHandler->ieee80211_ptr, -+ prParamGscnFullResult, -+ sizeof(PARAM_WIFI_GSCAN_RESULT)); -+ } -+ } -+ break; -+ -+ case EVENT_ID_GSCAN_SIGNIFICANT_CHANGE: -+ { -+ prEventGscnSignificantChange = (P_EVENT_GSCAN_SIGNIFICANT_CHANGE_T) (prEvent->aucBuffer); -+ memcpy(prEventGscnSignificantChange, (P_EVENT_GSCAN_SIGNIFICANT_CHANGE_T) (prEvent->aucBuffer), -+ sizeof(EVENT_GSCAN_SIGNIFICANT_CHANGE_T)); -+ } -+ break; -+ -+ case EVENT_ID_GSCAN_GEOFENCE_FOUND: -+ { -+ prEventGscnGeofenceFound = (P_EVENT_GSCAN_SIGNIFICANT_CHANGE_T) (prEvent->aucBuffer); -+ memcpy(prEventGscnGeofenceFound, (P_EVENT_GSCAN_SIGNIFICANT_CHANGE_T) (prEvent->aucBuffer), -+ sizeof(EVENT_GSCAN_SIGNIFICANT_CHANGE_T)); -+ } -+ break; -+ -+ default: -+ DBGLOG(SCN, INFO, "not GSCN event ????\n"); -+ break; -+ } -+ -+ DBGLOG(SCN, INFO, "Done with GSCN event handling\n"); -+ return real_num; /* cfg80211_vendor_cmd_reply(skb); */ -+ -+nla_put_failure: -+ if (skb != NULL) -+ kfree_skb(skb); -+ DBGLOG(SCN, INFO, "nla_put_failure\n"); -+ return 0; /* cfg80211_vendor_cmd_reply(skb); */ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Process HIF event packet -+* -+* @param prAdapter pointer to the Adapter handler -+* @param prSWRfb the RFB to receive rx data -+* -+* @return (none) -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicRxProcessEventPacket(IN P_ADAPTER_T prAdapter, IN OUT P_SW_RFB_T prSwRfb) -+{ -+ P_CMD_INFO_T prCmdInfo; -+ P_MSDU_INFO_T prMsduInfo; -+ P_WIFI_EVENT_T prEvent; -+ P_GLUE_INFO_T prGlueInfo; -+ -+ DEBUGFUNC("nicRxProcessEventPacket"); -+ -+ ASSERT(prAdapter); -+ ASSERT(prSwRfb); -+ -+ prEvent = (P_WIFI_EVENT_T) prSwRfb->pucRecvBuff; -+ prGlueInfo = prAdapter->prGlueInfo; -+ -+ DBGLOG(RX, EVENT, "prEvent->ucEID = 0x%02x\n", prEvent->ucEID); -+ /* Event Handling */ -+ switch (prEvent->ucEID) { -+ case EVENT_ID_CMD_RESULT: -+ prCmdInfo = nicGetPendingCmdInfo(prAdapter, prEvent->ucSeqNum); -+ -+ if (prCmdInfo != NULL) { -+ P_EVENT_CMD_RESULT prCmdResult; -+ -+ prCmdResult = (P_EVENT_CMD_RESULT) ((PUINT_8) prEvent + EVENT_HDR_SIZE); -+ -+ /* CMD_RESULT should be only in response to Set commands */ -+ ASSERT(prCmdInfo->fgSetQuery == FALSE || prCmdInfo->fgNeedResp == TRUE); -+ -+ if (prCmdResult->ucStatus == 0) { /* success */ -+ if (prCmdInfo->pfCmdDoneHandler) { -+ prCmdInfo->pfCmdDoneHandler(prAdapter, prCmdInfo, prEvent->aucBuffer); -+ } else if (prCmdInfo->fgIsOid == TRUE) { -+ kalOidComplete(prAdapter->prGlueInfo, prCmdInfo->fgSetQuery, 0, -+ WLAN_STATUS_SUCCESS); -+ } -+ } else if (prCmdResult->ucStatus == 1) { /* reject */ -+ if (prCmdInfo->fgIsOid == TRUE) -+ kalOidComplete(prAdapter->prGlueInfo, prCmdInfo->fgSetQuery, 0, -+ WLAN_STATUS_FAILURE); -+ } else if (prCmdResult->ucStatus == 2) { /* unknown CMD */ -+ if (prCmdInfo->fgIsOid == TRUE) -+ kalOidComplete(prAdapter->prGlueInfo, prCmdInfo->fgSetQuery, 0, -+ WLAN_STATUS_NOT_SUPPORTED); -+ } -+ /* return prCmdInfo */ -+ cmdBufFreeCmdInfo(prAdapter, prCmdInfo); -+ } -+ -+ break; -+ -+#if 0 -+ case EVENT_ID_CONNECTION_STATUS: -+ /* OBSELETE */ -+ { -+ P_EVENT_CONNECTION_STATUS prConnectionStatus; -+ -+ prConnectionStatus = (P_EVENT_CONNECTION_STATUS) (prEvent->aucBuffer); -+ -+ DbgPrint("RX EVENT: EVENT_ID_CONNECTION_STATUS = %d\n", prConnectionStatus->ucMediaStatus); -+ if (prConnectionStatus->ucMediaStatus == PARAM_MEDIA_STATE_DISCONNECTED) { -+ /* disconnected */ -+ if (kalGetMediaStateIndicated(prGlueInfo) != PARAM_MEDIA_STATE_DISCONNECTED) { -+ -+ kalIndicateStatusAndComplete(prGlueInfo, WLAN_STATUS_MEDIA_DISCONNECT, NULL, 0); -+ -+ prAdapter->rWlanInfo.u4SysTime = kalGetTimeTick(); -+ } -+ } else if (prConnectionStatus->ucMediaStatus == PARAM_MEDIA_STATE_CONNECTED) { -+ /* connected */ -+ prAdapter->rWlanInfo.u4SysTime = kalGetTimeTick(); -+ -+ /* fill information for association result */ -+ prAdapter->rWlanInfo.rCurrBssId.rSsid.u4SsidLen = prConnectionStatus->ucSsidLen; -+ kalMemCopy(prAdapter->rWlanInfo.rCurrBssId.rSsid.aucSsid, -+ prConnectionStatus->aucSsid, prConnectionStatus->ucSsidLen); -+ -+ kalMemCopy(prAdapter->rWlanInfo.rCurrBssId.arMacAddress, -+ prConnectionStatus->aucBssid, MAC_ADDR_LEN); -+ -+ /* @FIXME */ -+ prAdapter->rWlanInfo.rCurrBssId.u4Privacy = prConnectionStatus->ucEncryptStatus; -+ prAdapter->rWlanInfo.rCurrBssId.rRssi = 0; /* @FIXME */ -+ /* @FIXME */ -+ prAdapter->rWlanInfo.rCurrBssId.eNetworkTypeInUse = PARAM_NETWORK_TYPE_AUTOMODE; -+ prAdapter->rWlanInfo.rCurrBssId.rConfiguration.u4BeaconPeriod -+ = prConnectionStatus->u2BeaconPeriod; -+ prAdapter->rWlanInfo.rCurrBssId.rConfiguration.u4ATIMWindow -+ = prConnectionStatus->u2ATIMWindow; -+ prAdapter->rWlanInfo.rCurrBssId.rConfiguration.u4DSConfig -+ = prConnectionStatus->u4FreqInKHz; -+ prAdapter->rWlanInfo.ucNetworkType = prConnectionStatus->ucNetworkType; -+ -+ switch (prConnectionStatus->ucInfraMode) { -+ case 0: -+ prAdapter->rWlanInfo.rCurrBssId.eOpMode = NET_TYPE_IBSS; -+ break; -+ case 1: -+ prAdapter->rWlanInfo.rCurrBssId.eOpMode = NET_TYPE_INFRA; -+ break; -+ case 2: -+ default: -+ prAdapter->rWlanInfo.rCurrBssId.eOpMode = NET_TYPE_AUTO_SWITCH; -+ break; -+ } -+ /* always indicate to OS according to MSDN (re-association/roaming) */ -+ kalIndicateStatusAndComplete(prGlueInfo, WLAN_STATUS_MEDIA_CONNECT, NULL, 0); -+ } -+ } -+ break; -+ -+ case EVENT_ID_SCAN_RESULT: -+ /* OBSELETE */ -+ break; -+#endif -+ -+ case EVENT_ID_RX_ADDBA: -+ /* The FW indicates that an RX BA agreement will be established */ -+ qmHandleEventRxAddBa(prAdapter, prEvent); -+ break; -+ -+ case EVENT_ID_RX_DELBA: -+ /* The FW indicates that an RX BA agreement has been deleted */ -+ qmHandleEventRxDelBa(prAdapter, prEvent); -+ break; -+ -+ case EVENT_ID_LINK_QUALITY: -+#if CFG_ENABLE_WIFI_DIRECT && CFG_SUPPORT_P2P_RSSI_QUERY -+ if (prEvent->u2PacketLen == EVENT_HDR_SIZE + sizeof(EVENT_LINK_QUALITY_EX)) { -+ P_EVENT_LINK_QUALITY_EX prLqEx = (P_EVENT_LINK_QUALITY_EX) (prEvent->aucBuffer); -+ -+ if (prLqEx->ucIsLQ0Rdy) -+ nicUpdateLinkQuality(prAdapter, NETWORK_TYPE_AIS_INDEX, (P_EVENT_LINK_QUALITY) prLqEx); -+ if (prLqEx->ucIsLQ1Rdy) -+ nicUpdateLinkQuality(prAdapter, NETWORK_TYPE_P2P_INDEX, (P_EVENT_LINK_QUALITY) prLqEx); -+ } else { -+ /* For old FW, P2P may invoke link quality query, and make driver flag becone TRUE. */ -+ DBGLOG(P2P, WARN, "Old FW version, not support P2P RSSI query.\n"); -+ -+ /* Must not use NETWORK_TYPE_P2P_INDEX, cause the structure is mismatch. */ -+ nicUpdateLinkQuality(prAdapter, NETWORK_TYPE_AIS_INDEX, -+ (P_EVENT_LINK_QUALITY) (prEvent->aucBuffer)); -+ } -+#else -+ nicUpdateLinkQuality(prAdapter, NETWORK_TYPE_AIS_INDEX, (P_EVENT_LINK_QUALITY) (prEvent->aucBuffer)); -+#endif -+ -+ /* command response handling */ -+ prCmdInfo = nicGetPendingCmdInfo(prAdapter, prEvent->ucSeqNum); -+ -+ if (prCmdInfo != NULL) { -+ if (prCmdInfo->pfCmdDoneHandler) -+ prCmdInfo->pfCmdDoneHandler(prAdapter, prCmdInfo, prEvent->aucBuffer); -+ else if (prCmdInfo->fgIsOid) -+ kalOidComplete(prAdapter->prGlueInfo, prCmdInfo->fgSetQuery, 0, WLAN_STATUS_SUCCESS); -+ /* return prCmdInfo */ -+ cmdBufFreeCmdInfo(prAdapter, prCmdInfo); -+ } -+#ifndef LINUX -+ if (prAdapter->rWlanInfo.eRssiTriggerType == ENUM_RSSI_TRIGGER_GREATER && -+ prAdapter->rWlanInfo.rRssiTriggerValue >= (PARAM_RSSI) (prAdapter->rLinkQuality.cRssi)) { -+ prAdapter->rWlanInfo.eRssiTriggerType = ENUM_RSSI_TRIGGER_TRIGGERED; -+ -+ kalIndicateStatusAndComplete(prGlueInfo, -+ WLAN_STATUS_MEDIA_SPECIFIC_INDICATION, -+ (PVOID)&(prAdapter->rWlanInfo.rRssiTriggerValue), -+ sizeof(PARAM_RSSI)); -+ } else if (prAdapter->rWlanInfo.eRssiTriggerType == ENUM_RSSI_TRIGGER_LESS -+ && prAdapter->rWlanInfo.rRssiTriggerValue <= (PARAM_RSSI) (prAdapter->rLinkQuality.cRssi)) { -+ prAdapter->rWlanInfo.eRssiTriggerType = ENUM_RSSI_TRIGGER_TRIGGERED; -+ -+ kalIndicateStatusAndComplete(prGlueInfo, -+ WLAN_STATUS_MEDIA_SPECIFIC_INDICATION, -+ (PVOID)&(prAdapter->rWlanInfo.rRssiTriggerValue), -+ sizeof(PARAM_RSSI)); -+ } -+#endif -+ -+ break; -+ -+ case EVENT_ID_MIC_ERR_INFO: -+ { -+ P_EVENT_MIC_ERR_INFO prMicError; -+ /* P_PARAM_AUTH_EVENT_T prAuthEvent; */ -+ P_STA_RECORD_T prStaRec; -+ -+ DBGLOG(RSN, EVENT, "EVENT_ID_MIC_ERR_INFO\n"); -+ -+ prMicError = (P_EVENT_MIC_ERR_INFO) (prEvent->aucBuffer); -+ prStaRec = cnmGetStaRecByAddress(prAdapter, -+ (UINT_8) NETWORK_TYPE_AIS_INDEX, -+ prAdapter->rWlanInfo.rCurrBssId.arMacAddress); -+ ASSERT(prStaRec); -+ -+ if (prStaRec) -+ rsnTkipHandleMICFailure(prAdapter, prStaRec, (BOOLEAN) prMicError->u4Flags); -+ else -+ DBGLOG(RSN, WARN, "No STA rec!!\n"); -+#if 0 -+ prAuthEvent = (P_PARAM_AUTH_EVENT_T) prAdapter->aucIndicationEventBuffer; -+ -+ /* Status type: Authentication Event */ -+ prAuthEvent->rStatus.eStatusType = ENUM_STATUS_TYPE_AUTHENTICATION; -+ -+ /* Authentication request */ -+ prAuthEvent->arRequest[0].u4Length = sizeof(PARAM_AUTH_REQUEST_T); -+ kalMemCopy((PVOID) prAuthEvent->arRequest[0].arBssid, -+ (PVOID) prAdapter->rWlanInfo.rCurrBssId.arMacAddress, -+ /* whsu:Todo? */PARAM_MAC_ADDR_LEN); -+ -+ if (prMicError->u4Flags != 0) -+ prAuthEvent->arRequest[0].u4Flags = PARAM_AUTH_REQUEST_GROUP_ERROR; -+ else -+ prAuthEvent->arRequest[0].u4Flags = PARAM_AUTH_REQUEST_PAIRWISE_ERROR; -+ -+ kalIndicateStatusAndComplete(prAdapter->prGlueInfo, -+ WLAN_STATUS_MEDIA_SPECIFIC_INDICATION, -+ (PVOID) prAuthEvent, -+ sizeof(PARAM_STATUS_INDICATION_T) + sizeof(PARAM_AUTH_REQUEST_T)); -+#endif -+ } -+ break; -+ -+ case EVENT_ID_ASSOC_INFO: -+ { -+ P_EVENT_ASSOC_INFO prAssocInfo; -+ -+ prAssocInfo = (P_EVENT_ASSOC_INFO) (prEvent->aucBuffer); -+ -+ kalHandleAssocInfo(prAdapter->prGlueInfo, prAssocInfo); -+ } -+ break; -+ -+ case EVENT_ID_802_11_PMKID: -+ { -+ P_PARAM_AUTH_EVENT_T prAuthEvent; -+ PUINT_8 cp; -+ UINT_32 u4LenOfUsedBuffer; -+ -+ prAuthEvent = (P_PARAM_AUTH_EVENT_T) prAdapter->aucIndicationEventBuffer; -+ -+ prAuthEvent->rStatus.eStatusType = ENUM_STATUS_TYPE_CANDIDATE_LIST; -+ -+ u4LenOfUsedBuffer = (UINT_32) (prEvent->u2PacketLen - 8); -+ -+ prAuthEvent->arRequest[0].u4Length = u4LenOfUsedBuffer; -+ -+ cp = (PUINT_8) &prAuthEvent->arRequest[0]; -+ -+ /* Status type: PMKID Candidatelist Event */ -+ kalMemCopy(cp, (P_EVENT_PMKID_CANDIDATE_LIST_T) (prEvent->aucBuffer), prEvent->u2PacketLen - 8); -+ -+ kalIndicateStatusAndComplete(prAdapter->prGlueInfo, -+ WLAN_STATUS_MEDIA_SPECIFIC_INDICATION, -+ (PVOID) prAuthEvent, -+ sizeof(PARAM_STATUS_INDICATION_T) + u4LenOfUsedBuffer); -+ } -+ break; -+ -+#if 0 -+ case EVENT_ID_ACTIVATE_STA_REC_T: -+ { -+ P_EVENT_ACTIVATE_STA_REC_T prActivateStaRec; -+ -+ prActivateStaRec = (P_EVENT_ACTIVATE_STA_REC_T) (prEvent->aucBuffer); -+ -+ DbgPrint("RX EVENT: EVENT_ID_ACTIVATE_STA_REC_T Index:%d, MAC:[%pM]\n", -+ prActivateStaRec->ucStaRecIdx, prActivateStaRec->aucMacAddr); -+ -+ qmActivateStaRec(prAdapter, -+ (UINT_32) prActivateStaRec->ucStaRecIdx, -+ ((prActivateStaRec->fgIsQoS) ? TRUE : FALSE), -+ prActivateStaRec->ucNetworkTypeIndex, -+ ((prActivateStaRec->fgIsAP) ? TRUE : FALSE), prActivateStaRec->aucMacAddr); -+ -+ } -+ break; -+ -+ case EVENT_ID_DEACTIVATE_STA_REC_T: -+ { -+ P_EVENT_DEACTIVATE_STA_REC_T prDeactivateStaRec; -+ -+ prDeactivateStaRec = (P_EVENT_DEACTIVATE_STA_REC_T) (prEvent->aucBuffer); -+ -+ DbgPrint("RX EVENT: EVENT_ID_DEACTIVATE_STA_REC_T Index:%d, MAC:[%pM]\n", -+ prDeactivateStaRec->ucStaRecIdx, prActivateStaRec->aucMacAddr); -+ -+ qmDeactivateStaRec(prAdapter, prDeactivateStaRec->ucStaRecIdx); -+ } -+ break; -+#endif -+ -+ case EVENT_ID_SCAN_DONE: -+ scnEventScanDone(prAdapter, (P_EVENT_SCAN_DONE) (prEvent->aucBuffer)); -+ break; -+ -+ case EVENT_ID_TX_DONE_STATUS: -+ STATS_TX_PKT_DONE_INFO_DISPLAY(prAdapter, prEvent->aucBuffer); -+ break; -+ -+ case EVENT_ID_TX_DONE: -+ { -+ P_EVENT_TX_DONE_T prTxDone; -+ -+ prTxDone = (P_EVENT_TX_DONE_T) (prEvent->aucBuffer); -+ if (prTxDone->ucStatus) -+ DBGLOG(RX, INFO, "EVENT_ID_TX_DONE PacketSeq:%u ucStatus: %u SN: %u\n", -+ prTxDone->ucPacketSeq, prTxDone->ucStatus, prTxDone->u2SequenceNumber); -+ -+ /* call related TX Done Handler */ -+ prMsduInfo = nicGetPendingTxMsduInfo(prAdapter, prTxDone->ucPacketSeq); -+ -+#if CFG_SUPPORT_802_11V_TIMING_MEASUREMENT -+ DBGLOG(RX, TRACE, "EVENT_ID_TX_DONE u4TimeStamp = %x u2AirDelay = %x\n", -+ prTxDone->au4Reserved1, prTxDone->au4Reserved2); -+ -+ wnmReportTimingMeas(prAdapter, prMsduInfo->ucStaRecIndex, -+ prTxDone->au4Reserved1, prTxDone->au4Reserved1 + prTxDone->au4Reserved2); -+#endif -+ -+ if (prMsduInfo) { -+ prMsduInfo->pfTxDoneHandler(prAdapter, prMsduInfo, -+ (ENUM_TX_RESULT_CODE_T) (prTxDone->ucStatus)); -+ -+ cnmMgtPktFree(prAdapter, prMsduInfo); -+ } -+ } -+ break; -+ case EVENT_ID_SLEEPY_NOTIFY: -+ { -+ P_EVENT_SLEEPY_NOTIFY prEventSleepyNotify; -+ -+ prEventSleepyNotify = (P_EVENT_SLEEPY_NOTIFY) (prEvent->aucBuffer); -+ -+ /* DBGLOG(RX, INFO, ("ucSleepyState = %d\n", prEventSleepyNotify->ucSleepyState)); */ -+ -+ prAdapter->fgWiFiInSleepyState = (BOOLEAN) (prEventSleepyNotify->ucSleepyState); -+ } -+ break; -+ case EVENT_ID_BT_OVER_WIFI: -+#if CFG_ENABLE_BT_OVER_WIFI -+ { -+ UINT_8 aucTmp[sizeof(AMPC_EVENT) + sizeof(BOW_LINK_DISCONNECTED)]; -+ P_EVENT_BT_OVER_WIFI prEventBtOverWifi; -+ P_AMPC_EVENT prBowEvent; -+ P_BOW_LINK_CONNECTED prBowLinkConnected; -+ P_BOW_LINK_DISCONNECTED prBowLinkDisconnected; -+ -+ prEventBtOverWifi = (P_EVENT_BT_OVER_WIFI) (prEvent->aucBuffer); -+ -+ /* construct event header */ -+ prBowEvent = (P_AMPC_EVENT) aucTmp; -+ -+ if (prEventBtOverWifi->ucLinkStatus == 0) { -+ /* Connection */ -+ prBowEvent->rHeader.ucEventId = BOW_EVENT_ID_LINK_CONNECTED; -+ prBowEvent->rHeader.ucSeqNumber = 0; -+ prBowEvent->rHeader.u2PayloadLength = sizeof(BOW_LINK_CONNECTED); -+ -+ /* fill event body */ -+ prBowLinkConnected = (P_BOW_LINK_CONNECTED) (prBowEvent->aucPayload); -+ prBowLinkConnected->rChannel.ucChannelNum = prEventBtOverWifi->ucSelectedChannel; -+ kalMemZero(prBowLinkConnected->aucPeerAddress, MAC_ADDR_LEN); /* @FIXME */ -+ -+ kalIndicateBOWEvent(prAdapter->prGlueInfo, prBowEvent); -+ } else { -+ /* Disconnection */ -+ prBowEvent->rHeader.ucEventId = BOW_EVENT_ID_LINK_DISCONNECTED; -+ prBowEvent->rHeader.ucSeqNumber = 0; -+ prBowEvent->rHeader.u2PayloadLength = sizeof(BOW_LINK_DISCONNECTED); -+ -+ /* fill event body */ -+ prBowLinkDisconnected = (P_BOW_LINK_DISCONNECTED) (prBowEvent->aucPayload); -+ prBowLinkDisconnected->ucReason = 0; /* @FIXME */ -+ kalMemZero(prBowLinkDisconnected->aucPeerAddress, MAC_ADDR_LEN); /* @FIXME */ -+ -+ kalIndicateBOWEvent(prAdapter->prGlueInfo, prBowEvent); -+ } -+ } -+ break; -+#endif -+ case EVENT_ID_STATISTICS: -+ /* buffer statistics for further query */ -+ prAdapter->fgIsStatValid = TRUE; -+ prAdapter->rStatUpdateTime = kalGetTimeTick(); -+ kalMemCopy(&prAdapter->rStatStruct, prEvent->aucBuffer, sizeof(EVENT_STATISTICS)); -+ -+ /* command response handling */ -+ prCmdInfo = nicGetPendingCmdInfo(prAdapter, prEvent->ucSeqNum); -+ -+ if (prCmdInfo != NULL) { -+ if (prCmdInfo->pfCmdDoneHandler) -+ prCmdInfo->pfCmdDoneHandler(prAdapter, prCmdInfo, prEvent->aucBuffer); -+ else if (prCmdInfo->fgIsOid) -+ kalOidComplete(prAdapter->prGlueInfo, prCmdInfo->fgSetQuery, 0, WLAN_STATUS_SUCCESS); -+ /* return prCmdInfo */ -+ cmdBufFreeCmdInfo(prAdapter, prCmdInfo); -+ } -+ -+ break; -+ -+ case EVENT_ID_CH_PRIVILEGE: -+ cnmChMngrHandleChEvent(prAdapter, prEvent); -+ break; -+ -+ case EVENT_ID_BSS_ABSENCE_PRESENCE: -+ qmHandleEventBssAbsencePresence(prAdapter, prEvent); -+ break; -+ -+ case EVENT_ID_STA_CHANGE_PS_MODE: -+ qmHandleEventStaChangePsMode(prAdapter, prEvent); -+ break; -+#if CFG_ENABLE_WIFI_DIRECT -+ case EVENT_ID_STA_UPDATE_FREE_QUOTA: -+ qmHandleEventStaUpdateFreeQuota(prAdapter, prEvent); -+ break; -+#endif -+ case EVENT_ID_BSS_BEACON_TIMEOUT: -+ if (prAdapter->fgDisBcnLostDetection == FALSE) { -+ P_EVENT_BSS_BEACON_TIMEOUT_T prEventBssBeaconTimeout; -+ -+ prEventBssBeaconTimeout = (P_EVENT_BSS_BEACON_TIMEOUT_T) (prEvent->aucBuffer); -+ -+ DBGLOG(RX, INFO, "Beacon Timeout Reason = %u\n", prEventBssBeaconTimeout->ucReason); -+ -+ if (prEventBssBeaconTimeout->ucNetTypeIndex == NETWORK_TYPE_AIS_INDEX) { -+ /* Request stats report before beacon timeout */ -+ P_BSS_INFO_T prBssInfo; -+ P_STA_RECORD_T prStaRec; -+ -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ if (prBssInfo) { -+ prStaRec = cnmGetStaRecByAddress(prAdapter, -+ NETWORK_TYPE_AIS_INDEX, -+ prBssInfo->aucBSSID); -+ if (prStaRec) -+ STATS_ENV_REPORT_DETECT(prAdapter, prStaRec->ucIndex); -+ } -+ aisBssBeaconTimeout(prAdapter); -+ } -+#if CFG_ENABLE_WIFI_DIRECT -+ else if ((prAdapter->fgIsP2PRegistered) && -+ (prEventBssBeaconTimeout->ucNetTypeIndex == NETWORK_TYPE_P2P_INDEX)) -+ -+ p2pFsmRunEventBeaconTimeout(prAdapter); -+#endif -+ else { -+ DBGLOG(RX, ERROR, "EVENT_ID_BSS_BEACON_TIMEOUT: (ucNetTypeIdx = %d)\n", -+ prEventBssBeaconTimeout->ucNetTypeIndex); -+ } -+ } -+ -+ break; -+ case EVENT_ID_UPDATE_NOA_PARAMS: -+#if CFG_ENABLE_WIFI_DIRECT -+ if (prAdapter->fgIsP2PRegistered) { -+ P_EVENT_UPDATE_NOA_PARAMS_T prEventUpdateNoaParam; -+ -+ prEventUpdateNoaParam = (P_EVENT_UPDATE_NOA_PARAMS_T) (prEvent->aucBuffer); -+ -+ if (prEventUpdateNoaParam->ucNetTypeIndex == NETWORK_TYPE_P2P_INDEX) { -+ p2pProcessEvent_UpdateNOAParam(prAdapter, -+ prEventUpdateNoaParam->ucNetTypeIndex, -+ prEventUpdateNoaParam); -+ } else { -+ ASSERT(0); -+ } -+ } -+#else -+ ASSERT(0); -+#endif -+ break; -+ -+ case EVENT_ID_STA_AGING_TIMEOUT: -+#if CFG_ENABLE_WIFI_DIRECT -+ { -+ if (prAdapter->fgDisStaAgingTimeoutDetection == FALSE) { -+ P_EVENT_STA_AGING_TIMEOUT_T prEventStaAgingTimeout; -+ P_STA_RECORD_T prStaRec; -+ P_BSS_INFO_T prBssInfo = (P_BSS_INFO_T) NULL; -+ -+ prEventStaAgingTimeout = (P_EVENT_STA_AGING_TIMEOUT_T) (prEvent->aucBuffer); -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prEventStaAgingTimeout->ucStaRecIdx); -+ if (prStaRec == NULL) -+ break; -+ -+ DBGLOG(RX, INFO, "EVENT_ID_STA_AGING_TIMEOUT %u %pM\n", -+ prEventStaAgingTimeout->ucStaRecIdx, -+ prStaRec->aucMacAddr); -+ -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]); -+ -+ bssRemoveStaRecFromClientList(prAdapter, prBssInfo, prStaRec); -+ -+ /* Call False Auth */ -+ if (prAdapter->fgIsP2PRegistered) -+ p2pFuncDisconnect(prAdapter, prStaRec, TRUE, REASON_CODE_DISASSOC_INACTIVITY); -+ -+ } -+ /* gDisStaAgingTimeoutDetection */ -+ } -+#endif -+ break; -+ -+ case EVENT_ID_AP_OBSS_STATUS: -+#if CFG_ENABLE_WIFI_DIRECT -+ if (prAdapter->fgIsP2PRegistered) -+ rlmHandleObssStatusEventPkt(prAdapter, (P_EVENT_AP_OBSS_STATUS_T) prEvent->aucBuffer); -+#endif -+ break; -+ -+ case EVENT_ID_ROAMING_STATUS: -+#if CFG_SUPPORT_ROAMING -+ { -+ P_ROAMING_PARAM_T prParam; -+ -+ prParam = (P_ROAMING_PARAM_T) (prEvent->aucBuffer); -+ roamingFsmProcessEvent(prAdapter, prParam); -+ } -+#endif /* CFG_SUPPORT_ROAMING */ -+ break; -+ case EVENT_ID_SEND_DEAUTH: -+ { -+ P_WLAN_MAC_HEADER_T prWlanMacHeader; -+ P_STA_RECORD_T prStaRec; -+ -+ prWlanMacHeader = (P_WLAN_MAC_HEADER_T) &prEvent->aucBuffer[0]; -+ DBGLOG(RSN, INFO, "nicRx: aucAddr1: %pM, nicRx: aucAddr2: %pM\n", -+ prWlanMacHeader->aucAddr1, prWlanMacHeader->aucAddr2); -+ prStaRec = cnmGetStaRecByAddress(prAdapter, NETWORK_TYPE_AIS_INDEX, prWlanMacHeader->aucAddr2); -+ if (prStaRec != NULL && prStaRec->ucStaState == STA_STATE_3) { -+ DBGLOG(RSN, WARN, "Ignore Deauth for Rx Class 3 error!\n"); -+ } else { -+ /* receive packets without StaRec */ -+ prSwRfb->pvHeader = (P_WLAN_MAC_HEADER_T) &prEvent->aucBuffer[0]; -+ if (WLAN_STATUS_SUCCESS == authSendDeauthFrame(prAdapter, -+ NULL, -+ prSwRfb, -+ REASON_CODE_CLASS_3_ERR, -+ (PFN_TX_DONE_HANDLER) NULL)) -+ DBGLOG(RSN, INFO, "Send Deauth for Rx Class3 Error\n"); -+ else -+ DBGLOG(RSN, WARN, "failed to send deauth for Rx class3 error\n"); -+ } -+ } -+ break; -+ -+#if CFG_SUPPORT_RDD_TEST_MODE -+ case EVENT_ID_UPDATE_RDD_STATUS: -+ { -+ P_EVENT_RDD_STATUS_T prEventRddStatus; -+ -+ prEventRddStatus = (P_EVENT_RDD_STATUS_T) (prEvent->aucBuffer); -+ -+ prAdapter->ucRddStatus = prEventRddStatus->ucRddStatus; -+ } -+ -+ break; -+#endif -+ -+#if CFG_SUPPORT_BCM && CFG_SUPPORT_BCM_BWCS -+ case EVENT_ID_UPDATE_BWCS_STATUS: -+ { -+ P_PTA_IPC_T prEventBwcsStatus; -+ -+ prEventBwcsStatus = (P_PTA_IPC_T) (prEvent->aucBuffer); -+ -+#if CFG_SUPPORT_BCM_BWCS_DEBUG -+ DBGLOG(RSN, INFO, -+ "BCM BWCS Event: %02x%02x%02x%02x\n", -+ prEventBwcsStatus->u.aucBTPParams[0], prEventBwcsStatus->u.aucBTPParams[1], -+ prEventBwcsStatus->u.aucBTPParams[2], prEventBwcsStatus->u.aucBTPParams[3]); -+ -+ DBGLOG(RSN, INFO, -+ "BCM BWCS Event: BTPParams[0]:%02x, BTPParams[1]:%02x, BTPParams[2]:%02x, BTPParams[3]:%02x\n", -+ prEventBwcsStatus->u.aucBTPParams[0], prEventBwcsStatus->u.aucBTPParams[1], -+ prEventBwcsStatus->u.aucBTPParams[2], prEventBwcsStatus->u.aucBTPParams[3]); -+#endif -+ -+ kalIndicateStatusAndComplete(prAdapter->prGlueInfo, -+ WLAN_STATUS_BWCS_UPDATE, -+ (PVOID) prEventBwcsStatus, sizeof(PTA_IPC_T)); -+ } -+ -+ break; -+ -+ case EVENT_ID_UPDATE_BCM_DEBUG: -+ { -+ P_PTA_IPC_T prEventBwcsStatus; -+ -+ prEventBwcsStatus = (P_PTA_IPC_T) (prEvent->aucBuffer); -+ -+#if CFG_SUPPORT_BCM_BWCS_DEBUG -+ DBGLOG(RSN, INFO, -+ "BCM FW status: %02x%02x%02x%02x\n", -+ prEventBwcsStatus->u.aucBTPParams[0], prEventBwcsStatus->u.aucBTPParams[1], -+ prEventBwcsStatus->u.aucBTPParams[2], prEventBwcsStatus->u.aucBTPParams[3]); -+ -+ DBGLOG(RSN, INFO, -+ "BCM FW status: BTPParams[0]:%02x, BTPParams[1]:%02x, BTPParams[2]:%02x, BTPParams[3]:%02x\n", -+ prEventBwcsStatus->u.aucBTPParams[0], prEventBwcsStatus->u.aucBTPParams[1], -+ prEventBwcsStatus->u.aucBTPParams[2], prEventBwcsStatus->u.aucBTPParams[3]; -+#endif -+ } -+ -+ break; -+#endif -+ -+ case EVENT_ID_DEBUG_CODE: /* only for debug */ -+ { -+ UINT_32 u4CodeId; -+ -+ DBGLOG(RSN, INFO, "[wlan-fw] function sequence: "); -+ for (u4CodeId = 0; u4CodeId < 1000; u4CodeId++) -+ DBGLOG(RSN, INFO, "%d ", prEvent->aucBuffer[u4CodeId]); -+ DBGLOG(RSN, INFO, "\n\n"); -+ } -+ break; -+ -+ case EVENT_ID_RFTEST_READY: -+ -+ /* command response handling */ -+ prCmdInfo = nicGetPendingCmdInfo(prAdapter, prEvent->ucSeqNum); -+ -+ if (prCmdInfo != NULL) { -+ if (prCmdInfo->pfCmdDoneHandler) -+ prCmdInfo->pfCmdDoneHandler(prAdapter, prCmdInfo, prEvent->aucBuffer); -+ else if (prCmdInfo->fgIsOid) -+ kalOidComplete(prAdapter->prGlueInfo, prCmdInfo->fgSetQuery, 0, WLAN_STATUS_SUCCESS); -+ /* return prCmdInfo */ -+ cmdBufFreeCmdInfo(prAdapter, prCmdInfo); -+ } -+ -+ break; -+ -+ case EVENT_ID_GSCAN_SCAN_AVAILABLE: -+ case EVENT_ID_GSCAN_CAPABILITY: -+ case EVENT_ID_GSCAN_SCAN_COMPLETE: -+ case EVENT_ID_GSCAN_FULL_RESULT: -+ case EVENT_ID_GSCAN_SIGNIFICANT_CHANGE: -+ case EVENT_ID_GSCAN_GEOFENCE_FOUND: -+ nicRxProcessGSCNEvent(prAdapter, prSwRfb); -+ break; -+ -+ case EVENT_ID_GSCAN_RESULT: -+ { -+ -+ UINT_8 realnum = 0; -+ -+ DBGLOG(SCN, TRACE, "nicRxProcessGSCNEvent ----->\n"); -+ realnum = nicRxProcessGSCNEvent(prAdapter, prSwRfb); -+ DBGLOG(SCN, TRACE, "nicRxProcessGSCNEvent <-----\n"); -+ -+#if 0 /* workaround for FW events cnt mis-match with the actual reqirements from wifi_hal */ -+ if (g_GetResultsCmdCnt == 0) { -+ DBGLOG(SCN, INFO, -+ "FW report events more than the wifi_hal asked number, buffer the results\n"); -+ UINT_8 i = 0; -+ -+ for (i = 0; i < MAX_BUFFERED_GSCN_RESULTS; i++) { -+#if 1 -+ if (!g_arGscanResultsIndicateNumber[i]) { -+ DBGLOG(SCN, INFO, -+ "found available index %d to insert results number %d into buffer\r\n", -+ i, realnum); -+ -+ g_arGscnResultsTempBuffer[i] = prSwRfb; -+ g_arGscanResultsIndicateNumber[i] = realnum; -+ g_GetResultsBufferedCnt++; -+ fgKeepprSwRfb = TRUE; -+ DBGLOG(SCN, INFO, "results buffered in index[%d] \r\n", i); -+ break; -+ } -+#endif -+ } -+ if (i == MAX_BUFFERED_GSCN_RESULTS) -+ DBGLOG(SCN, INFO, -+ "Gscn results buffer is full(all valid), no space to buffer result\r\n"); -+ } else if (g_GetResultsCmdCnt > 0) { -+ DBGLOG(SCN, INFO, "FW report events match the wifi_hal asked number\n"); -+ g_GetResultsCmdCnt--; -+ } else -+ DBGLOG(SCN, INFO, "g_GetResultsCmdCnt < 0 ??? unexpected case\n"); -+#endif -+ /* end of workaround */ -+ -+ } -+ break; -+ -+ case EVENT_ID_NLO_DONE: -+ prAdapter->rWifiVar.rScanInfo.fgPscnOnnning = FALSE; -+ -+ DBGLOG(INIT, INFO, "EVENT_ID_NLO_DONE\n"); -+ scnEventNloDone(prAdapter, (P_EVENT_NLO_DONE_T) (prEvent->aucBuffer)); -+ -+ break; -+ -+#if CFG_SUPPORT_BATCH_SCAN -+ case EVENT_ID_BATCH_RESULT: -+ DBGLOG(SCN, TRACE, "Got EVENT_ID_BATCH_RESULT"); -+ -+ /* command response handling */ -+ prCmdInfo = nicGetPendingCmdInfo(prAdapter, prEvent->ucSeqNum); -+ -+ if (prCmdInfo != NULL) { -+ if (prCmdInfo->pfCmdDoneHandler) -+ prCmdInfo->pfCmdDoneHandler(prAdapter, prCmdInfo, prEvent->aucBuffer); -+ else if (prCmdInfo->fgIsOid) -+ kalOidComplete(prAdapter->prGlueInfo, prCmdInfo->fgSetQuery, 0, WLAN_STATUS_SUCCESS); -+ /* return prCmdInfo */ -+ cmdBufFreeCmdInfo(prAdapter, prCmdInfo); -+ } -+ -+ break; -+#endif /* CFG_SUPPORT_BATCH_SCAN */ -+ -+#if (CFG_SUPPORT_TDLS == 1) -+ case EVENT_ID_TDLS: -+ TdlsexEventHandle(prAdapter->prGlueInfo, -+ (UINT8 *) prEvent->aucBuffer, (UINT32) (prEvent->u2PacketLen - 8)); -+ break; -+#endif /* CFG_SUPPORT_TDLS */ -+ -+#if (CFG_SUPPORT_STATISTICS == 1) -+ case EVENT_ID_STATS_ENV: -+ statsEventHandle(prAdapter->prGlueInfo, -+ (UINT8 *) prEvent->aucBuffer, (UINT32) (prEvent->u2PacketLen - 8)); -+ break; -+#endif /* CFG_SUPPORT_STATISTICS */ -+ -+ case EVENT_ID_FW_LOG_ENV: -+ { -+ P_EVENT_FW_LOG_T prEventLog; -+ -+ prEventLog = (P_EVENT_FW_LOG_T) (prEvent->aucBuffer); -+ DBGLOG(RX, INFO, "[F-L]%s\n", prEventLog->log); -+ } -+ break; -+ -+ default: -+ prCmdInfo = nicGetPendingCmdInfo(prAdapter, prEvent->ucSeqNum); -+ -+ if (prCmdInfo != NULL) { -+ if (prCmdInfo->pfCmdDoneHandler) -+ prCmdInfo->pfCmdDoneHandler(prAdapter, prCmdInfo, prEvent->aucBuffer); -+ else if (prCmdInfo->fgIsOid) -+ kalOidComplete(prAdapter->prGlueInfo, prCmdInfo->fgSetQuery, 0, WLAN_STATUS_SUCCESS); -+ /* return prCmdInfo */ -+ cmdBufFreeCmdInfo(prAdapter, prCmdInfo); -+ } -+ -+ break; -+ } -+ -+ nicRxReturnRFB(prAdapter, prSwRfb); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief nicRxProcessMgmtPacket is used to dispatch management frames -+* to corresponding modules -+* -+* @param prAdapter Pointer to the Adapter structure. -+* @param prSWRfb the RFB to receive rx data -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicRxProcessMgmtPacket(IN P_ADAPTER_T prAdapter, IN OUT P_SW_RFB_T prSwRfb) -+{ -+ UINT_8 ucSubtype; -+#if CFG_SUPPORT_802_11W -+ BOOLEAN fgMfgDrop = FALSE; -+#endif -+ ASSERT(prAdapter); -+ ASSERT(prSwRfb); -+ -+ nicRxFillRFB(prAdapter, prSwRfb); -+ -+ ucSubtype = (*(PUINT_8) (prSwRfb->pvHeader) & MASK_FC_SUBTYPE) >> OFFSET_OF_FC_SUBTYPE; -+ -+#if 0 /* CFG_RX_PKTS_DUMP */ -+ { -+ P_HIF_RX_HEADER_T prHifRxHdr; -+ UINT_16 u2TxFrameCtrl; -+ -+ prHifRxHdr = prSwRfb->prHifRxHdr; -+ u2TxFrameCtrl = (*(PUINT_8) (prSwRfb->pvHeader) & MASK_FRAME_TYPE); -+ /* if (prAdapter->rRxCtrl.u4RxPktsDumpTypeMask & BIT(HIF_RX_PKT_TYPE_MANAGEMENT)) { */ -+ /* if (u2TxFrameCtrl == MAC_FRAME_BEACON || */ -+ /* u2TxFrameCtrl == MAC_FRAME_PROBE_RSP) { */ -+ -+ DBGLOG(RX, INFO, "QM RX MGT: net %u sta idx %u wlan idx %u ssn %u ptype %u subtype %u 11 %u\n", -+ (UINT_32) HIF_RX_HDR_GET_NETWORK_IDX(prHifRxHdr), prHifRxHdr->ucStaRecIdx, -+ prSwRfb->ucWlanIdx, (UINT_32) HIF_RX_HDR_GET_SN(prHifRxHdr),/* The new SN of the frame */ -+ prSwRfb->ucPacketType, ucSubtype, HIF_RX_HDR_GET_80211_FLAG(prHifRxHdr)); -+ -+ /* DBGLOG_MEM8(SW4, TRACE, (PUINT_8)prSwRfb->pvHeader, prSwRfb->u2PacketLen); */ -+ /* } */ -+ /* } */ -+ } -+#endif -+ -+ if ((prAdapter->fgTestMode == FALSE) && (prAdapter->prGlueInfo->fgIsRegistered == TRUE)) { -+#if CFG_MGMT_FRAME_HANDLING -+#if CFG_SUPPORT_802_11W -+ fgMfgDrop = rsnCheckRxMgmt(prAdapter, prSwRfb, ucSubtype); -+ if (fgMfgDrop) { -+#if DBG -+ LOG_FUNC("QM RX MGT: Drop Unprotected Mgmt frame!!!\n"); -+#endif -+ nicRxReturnRFB(prAdapter, prSwRfb); -+ RX_INC_CNT(prRxCtrl, RX_DROP_TOTAL_COUNT); -+ return; -+ } -+#endif -+ if (apfnProcessRxMgtFrame[ucSubtype]) { -+ switch (apfnProcessRxMgtFrame[ucSubtype] (prAdapter, prSwRfb)) { -+ case WLAN_STATUS_PENDING: -+ return; -+ case WLAN_STATUS_SUCCESS: -+ case WLAN_STATUS_FAILURE: -+ break; -+ -+ default: -+ DBGLOG(RX, WARN, -+ "Unexpected MMPDU(0x%02X) returned with abnormal status\n", ucSubtype); -+ break; -+ } -+ } -+#endif -+ } -+ -+ nicRxReturnRFB(prAdapter, prSwRfb); -+} -+ -+#if CFG_SUPPORT_WAKEUP_REASON_DEBUG -+static VOID nicRxCheckWakeupReason(P_SW_RFB_T prSwRfb) -+{ -+ PUINT_8 pvHeader = NULL; -+ P_HIF_RX_HEADER_T prHifRxHdr; -+ UINT_16 u2PktLen = 0; -+ UINT_32 u4HeaderOffset; -+ -+ if (!prSwRfb) -+ return; -+ prHifRxHdr = prSwRfb->prHifRxHdr; -+ if (!prHifRxHdr) -+ return; -+ -+ switch (prSwRfb->ucPacketType) { -+ case HIF_RX_PKT_TYPE_DATA: -+ { -+ UINT_16 u2Temp = 0; -+ -+ if (HIF_RX_HDR_GET_BAR_FLAG(prHifRxHdr)) { -+ DBGLOG(RX, INFO, "BAR frame[SSN:%d, TID:%d] wakeup host\n", -+ (UINT_16)HIF_RX_HDR_GET_SN(prHifRxHdr), (UINT_8)HIF_RX_HDR_GET_TID(prHifRxHdr)); -+ break; -+ } -+ u4HeaderOffset = (UINT_32)(prHifRxHdr->ucHerderLenOffset & HIF_RX_HDR_HEADER_OFFSET_MASK); -+ pvHeader = (PUINT_8)prHifRxHdr + HIF_RX_HDR_SIZE + u4HeaderOffset; -+ u2PktLen = (UINT_16)(prHifRxHdr->u2PacketLen - (HIF_RX_HDR_SIZE + u4HeaderOffset)); -+ if (!pvHeader) { -+ DBGLOG(RX, ERROR, "data packet but pvHeader is NULL!\n"); -+ break; -+ } -+ u2Temp = (pvHeader[ETH_TYPE_LEN_OFFSET] << 8) | (pvHeader[ETH_TYPE_LEN_OFFSET + 1]); -+ -+ switch (u2Temp) { -+ case ETH_P_IPV4: -+ u2Temp = *(UINT_16 *) &pvHeader[ETH_HLEN + 4]; -+ DBGLOG(RX, INFO, "IP Packet from:%d.%d.%d.%d, IP ID 0x%04x wakeup host\n", -+ pvHeader[ETH_HLEN + 12], pvHeader[ETH_HLEN + 13], -+ pvHeader[ETH_HLEN + 14], pvHeader[ETH_HLEN + 15], u2Temp); -+ break; -+ case ETH_P_ARP: -+ { -+ PUINT_8 pucEthBody = &pvHeader[ETH_HLEN]; -+ UINT_16 u2OpCode = (pucEthBody[6] << 8) | pucEthBody[7]; -+ -+ if (u2OpCode == ARP_PRO_REQ) -+ DBGLOG(RX, INFO, "Arp Req From IP: %d.%d.%d.%d wakeup host\n", -+ pucEthBody[14], pucEthBody[15], pucEthBody[16], pucEthBody[17]); -+ else if (u2OpCode == ARP_PRO_RSP) -+ DBGLOG(RX, INFO, "Arp Rsp from IP: %d.%d.%d.%d wakeup host\n", -+ pucEthBody[14], pucEthBody[15], pucEthBody[16], pucEthBody[17]); -+ break; -+ } -+ case ETH_P_1X: -+ case ETH_P_PRE_1X: -+#if CFG_SUPPORT_WAPI -+ case ETH_WPI_1X: -+#endif -+ case ETH_P_AARP: -+ case ETH_P_IPV6: -+ case ETH_P_IPX: -+ case 0x8100: /* VLAN */ -+ case 0x890d: /* TDLS */ -+ DBGLOG(RX, INFO, "Data Packet, EthType 0x%04x wakeup host\n", u2Temp); -+ break; -+ default: -+ DBGLOG(RX, WARN, "maybe abnormal data packet, EthType 0x%04x wakeup host, dump it\n", -+ u2Temp); -+ DBGLOG_MEM8(RX, INFO, pvHeader, u2PktLen > 50 ? 50:u2PacketLen); -+ break; -+ } -+ break; -+ } -+ case HIF_RX_PKT_TYPE_EVENT: -+ { -+ P_WIFI_EVENT_T prEvent = (P_WIFI_EVENT_T) prSwRfb->pucRecvBuff; -+ -+ DBGLOG(RX, INFO, "Event 0x%02x wakeup host\n", prEvent->ucEID); -+ break; -+ } -+ case HIF_RX_PKT_TYPE_MANAGEMENT: -+ { -+ UINT_8 ucSubtype; -+ P_WLAN_MAC_MGMT_HEADER_T prWlanMgmtHeader; -+ -+ u4HeaderOffset = (UINT_32)(prHifRxHdr->ucHerderLenOffset & HIF_RX_HDR_HEADER_OFFSET_MASK); -+ pvHeader = (PUINT_8)prHifRxHdr + HIF_RX_HDR_SIZE + u4HeaderOffset; -+ if (!pvHeader) { -+ DBGLOG(RX, ERROR, "Mgmt Frame but pvHeader is NULL!\n"); -+ break; -+ } -+ prWlanMgmtHeader = (P_WLAN_MAC_MGMT_HEADER_T)pvHeader; -+ ucSubtype = (prWlanMgmtHeader->u2FrameCtrl & MASK_FC_SUBTYPE) >> -+ OFFSET_OF_FC_SUBTYPE; -+ DBGLOG(RX, INFO, "MGMT frame subtype: %d SeqCtrl %d wakeup host\n", -+ ucSubtype, prWlanMgmtHeader->u2SeqCtrl); -+ break; -+ } -+ default: -+ DBGLOG(RX, WARN, "Unknown Packet %d wakeup host\n", prSwRfb->ucPacketType); -+ break; -+ } -+} -+#endif -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief nicProcessRFBs is used to process RFBs in the rReceivedRFBList queue. -+* -+* @param prAdapter Pointer to the Adapter structure. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicRxProcessRFBs(IN P_ADAPTER_T prAdapter) -+{ -+ P_RX_CTRL_T prRxCtrl; -+ P_SW_RFB_T prSwRfb = (P_SW_RFB_T) NULL; -+ -+ KAL_SPIN_LOCK_DECLARATION(); -+ -+ DEBUGFUNC("nicRxProcessRFBs"); -+ -+ ASSERT(prAdapter); -+ -+ prRxCtrl = &prAdapter->rRxCtrl; -+ ASSERT(prRxCtrl); -+ -+ prRxCtrl->ucNumIndPacket = 0; -+ prRxCtrl->ucNumRetainedPacket = 0; -+ -+ do { -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); -+ QUEUE_REMOVE_HEAD(&prRxCtrl->rReceivedRfbList, prSwRfb, P_SW_RFB_T); -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); -+ -+ if (prSwRfb) { -+#if CFG_SUPPORT_WAKEUP_REASON_DEBUG -+ if (kalIsWakeupByWlan(prAdapter)) -+ nicRxCheckWakeupReason(prSwRfb); -+#endif -+ switch (prSwRfb->ucPacketType) { -+ case HIF_RX_PKT_TYPE_DATA: -+ nicRxProcessDataPacket(prAdapter, prSwRfb); -+ break; -+ -+ case HIF_RX_PKT_TYPE_EVENT: -+ nicRxProcessEventPacket(prAdapter, prSwRfb); -+ break; -+ -+ case HIF_RX_PKT_TYPE_TX_LOOPBACK: -+#if (CONF_HIF_LOOPBACK_AUTO == 1) -+ { -+ kalDevLoopbkRxHandle(prAdapter, prSwRfb); -+ nicRxReturnRFB(prAdapter, prSwRfb); -+ } -+#else -+ DBGLOG(RX, ERROR, "ucPacketType = %d\n", prSwRfb->ucPacketType); -+#endif /* CONF_HIF_LOOPBACK_AUTO */ -+ break; -+ -+ case HIF_RX_PKT_TYPE_MANAGEMENT: -+ nicRxProcessMgmtPacket(prAdapter, prSwRfb); -+ break; -+ -+ default: -+ RX_INC_CNT(prRxCtrl, RX_TYPE_ERR_DROP_COUNT); -+ RX_INC_CNT(prRxCtrl, RX_DROP_TOTAL_COUNT); -+ DBGLOG(RX, ERROR, "ucPacketType = %d\n", prSwRfb->ucPacketType); -+ nicRxReturnRFB(prAdapter, prSwRfb); /* need to free it */ -+ break; -+ } -+ } else { -+ break; -+ } -+ } while (TRUE); -+ -+ if (prRxCtrl->ucNumIndPacket > 0) { -+ RX_ADD_CNT(prRxCtrl, RX_DATA_INDICATION_COUNT, prRxCtrl->ucNumIndPacket); -+ RX_ADD_CNT(prRxCtrl, RX_DATA_RETAINED_COUNT, prRxCtrl->ucNumRetainedPacket); -+ -+ /* DBGLOG(RX, INFO, ("%d packets indicated, Retained cnt = %d\n", */ -+ /* prRxCtrl->ucNumIndPacket, prRxCtrl->ucNumRetainedPacket)); */ -+#if CFG_NATIVE_802_11 -+ kalRxIndicatePkts(prAdapter->prGlueInfo, (UINT_32) prRxCtrl->ucNumIndPacket, -+ (UINT_32) prRxCtrl->ucNumRetainedPacket); -+#else -+ kalRxIndicatePkts(prAdapter->prGlueInfo, prRxCtrl->apvIndPacket, (UINT_32) prRxCtrl->ucNumIndPacket); -+#endif -+ } -+ -+} /* end of nicRxProcessRFBs() */ -+ -+#if !CFG_SDIO_INTR_ENHANCE -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Read the rx data from data port and setup RFB -+* -+* @param prAdapter pointer to the Adapter handler -+* @param prSWRfb the RFB to receive rx data -+* -+* @retval WLAN_STATUS_SUCCESS: SUCCESS -+* @retval WLAN_STATUS_FAILURE: FAILURE -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS nicRxReadBuffer(IN P_ADAPTER_T prAdapter, IN OUT P_SW_RFB_T prSwRfb) -+{ -+ P_RX_CTRL_T prRxCtrl; -+ PUINT_8 pucBuf; -+ P_HIF_RX_HEADER_T prHifRxHdr; -+ UINT_32 u4PktLen = 0, u4ReadBytes; -+ WLAN_STATUS u4Status = WLAN_STATUS_SUCCESS; -+ BOOLEAN fgResult = TRUE; -+ UINT_32 u4RegValue; -+ UINT_32 rxNum; -+ -+ DEBUGFUNC("nicRxReadBuffer"); -+ -+ ASSERT(prAdapter); -+ ASSERT(prSwRfb); -+ -+ prRxCtrl = &prAdapter->rRxCtrl; -+ ASSERT(prRxCtrl); -+ -+ pucBuf = prSwRfb->pucRecvBuff; -+ prHifRxHdr = prSwRfb->prHifRxHdr; -+ ASSERT(pucBuf); -+ DBGLOG(RX, TRACE, "pucBuf= 0x%x, prHifRxHdr= 0x%x\n", pucBuf, prHifRxHdr); -+ -+ do { -+ /* Read the RFB DW length and packet length */ -+ HAL_MCR_RD(prAdapter, MCR_WRPLR, &u4RegValue); -+ if (!fgResult) { -+ DBGLOG(RX, ERROR, "Read RX Packet Lentgh Error\n"); -+ return WLAN_STATUS_FAILURE; -+ } -+ /* 20091021 move the line to get the HIF RX header (for RX0/1) */ -+ if (u4RegValue == 0) { -+ DBGLOG(RX, ERROR, "No RX packet\n"); -+ return WLAN_STATUS_FAILURE; -+ } -+ -+ u4PktLen = u4RegValue & BITS(0, 15); -+ if (u4PktLen != 0) { -+ rxNum = 0; -+ } else { -+ rxNum = 1; -+ u4PktLen = (u4RegValue & BITS(16, 31)) >> 16; -+ } -+ -+ DBGLOG(RX, TRACE, "RX%d: u4PktLen = %d\n", rxNum, u4PktLen); -+ -+ /* 4 <4> Read Entire RFB and packet, include HW appended DW (Checksum Status) */ -+ u4ReadBytes = ALIGN_4(u4PktLen) + 4; -+ HAL_READ_RX_PORT(prAdapter, rxNum, u4ReadBytes, pucBuf, CFG_RX_MAX_PKT_SIZE); -+ -+ /* 20091021 move the line to get the HIF RX header */ -+ /* u4PktLen = (UINT_32)prHifRxHdr->u2PacketLen; */ -+ if (u4PktLen != (UINT_32) prHifRxHdr->u2PacketLen) { -+ DBGLOG(RX, ERROR, "Read u4PktLen = %d, prHifRxHdr->u2PacketLen: %d\n", -+ u4PktLen, prHifRxHdr->u2PacketLen); -+#if DBG -+ dumpMemory8((PUINT_8) prHifRxHdr, -+ (prHifRxHdr->u2PacketLen > 4096) ? 4096 : prHifRxHdr->u2PacketLen); -+#endif -+ ASSERT(0); -+ } -+ /* u4PktLen is byte unit, not inlude HW appended DW */ -+ -+ prSwRfb->ucPacketType = (UINT_8) (prHifRxHdr->u2PacketType & HIF_RX_HDR_PACKET_TYPE_MASK); -+ DBGLOG(RX, TRACE, "ucPacketType = %d\n", prSwRfb->ucPacketType); -+ -+ prSwRfb->ucStaRecIdx = (UINT_8) (prHifRxHdr->ucStaRecIdx); -+ -+ /* fgResult will be updated in MACRO */ -+ if (!fgResult) -+ return WLAN_STATUS_FAILURE; -+ -+ DBGLOG(RX, TRACE, "Dump RX buffer, length = 0x%x\n", u4ReadBytes); -+ DBGLOG_MEM8(RX, TRACE, pucBuf, u4ReadBytes); -+ } while (FALSE); -+ -+ return u4Status; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Read frames from the data port, fill RFB -+* and put each frame into the rReceivedRFBList queue. -+* -+* @param prAdapter Pointer to the Adapter structure. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicRxReceiveRFBs(IN P_ADAPTER_T prAdapter) -+{ -+ P_RX_CTRL_T prRxCtrl; -+ P_SW_RFB_T prSwRfb = (P_SW_RFB_T) NULL; -+ P_HIF_RX_HEADER_T prHifRxHdr; -+ -+ UINT_32 u4HwAppendDW; -+ -+ KAL_SPIN_LOCK_DECLARATION(); -+ -+ DEBUGFUNC("nicRxReceiveRFBs"); -+ -+ ASSERT(prAdapter); -+ -+ prRxCtrl = &prAdapter->rRxCtrl; -+ ASSERT(prRxCtrl); -+ -+ do { -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); -+ QUEUE_REMOVE_HEAD(&prRxCtrl->rFreeSwRfbList, prSwRfb, P_SW_RFB_T); -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); -+ -+ if (!prSwRfb) { -+ DBGLOG(RX, TRACE, "No More RFB\n"); -+ break; -+ } -+ /* need to consider */ -+ if (nicRxReadBuffer(prAdapter, prSwRfb) == WLAN_STATUS_FAILURE) { -+ DBGLOG(RX, TRACE, "halRxFillRFB failed\n"); -+ nicRxReturnRFB(prAdapter, prSwRfb); -+ break; -+ } -+ -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); -+ QUEUE_INSERT_TAIL(&prRxCtrl->rReceivedRfbList, &prSwRfb->rQueEntry); -+ RX_INC_CNT(prRxCtrl, RX_MPDU_TOTAL_COUNT); -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); -+ -+ prHifRxHdr = prSwRfb->prHifRxHdr; -+ u4HwAppendDW = *((PUINT_32) ((ULONG) prHifRxHdr + (UINT_32) (ALIGN_4(prHifRxHdr->u2PacketLen)))); -+ DBGLOG(RX, TRACE, "u4HwAppendDW = 0x%x\n", u4HwAppendDW); -+ DBGLOG(RX, TRACE, "u2PacketLen = 0x%x\n", prHifRxHdr->u2PacketLen); -+ } while (FALSE); /* while (RX_STATUS_TEST_MORE_FLAG(u4HwAppendDW)); */ -+ -+ return; -+ -+} /* end of nicReceiveRFBs() */ -+ -+#else -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Read frames from the data port, fill RFB -+* and put each frame into the rReceivedRFBList queue. -+* -+* @param prAdapter Pointer to the Adapter structure. -+* @param u4DataPort Specify which port to read -+* @param u2RxLength Specify to the the rx packet length in Byte. -+* @param prSwRfb the RFB to receive rx data. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+ -+WLAN_STATUS -+nicRxEnhanceReadBuffer(IN P_ADAPTER_T prAdapter, -+ IN UINT_32 u4DataPort, IN UINT_16 u2RxLength, IN OUT P_SW_RFB_T prSwRfb) -+{ -+ P_RX_CTRL_T prRxCtrl; -+ PUINT_8 pucBuf; -+ P_HIF_RX_HEADER_T prHifRxHdr; -+ UINT_32 u4PktLen = 0; -+ WLAN_STATUS u4Status = WLAN_STATUS_FAILURE; -+ BOOLEAN fgResult = TRUE; -+ -+ DEBUGFUNC("nicRxEnhanceReadBuffer"); -+ -+ ASSERT(prAdapter); -+ ASSERT(prSwRfb); -+ -+ prRxCtrl = &prAdapter->rRxCtrl; -+ ASSERT(prRxCtrl); -+ -+ pucBuf = prSwRfb->pucRecvBuff; -+ ASSERT(pucBuf); -+ -+ prHifRxHdr = prSwRfb->prHifRxHdr; -+ ASSERT(prHifRxHdr); -+ -+ /* DBGLOG(RX, TRACE, ("u2RxLength = %d\n", u2RxLength)); */ -+ -+ do { -+ /* 4 <1> Read RFB frame from MCR_WRDR0, include HW appended DW */ -+ HAL_READ_RX_PORT(prAdapter, -+ u4DataPort, ALIGN_4(u2RxLength + HIF_RX_HW_APPENDED_LEN), pucBuf, CFG_RX_MAX_PKT_SIZE); -+ -+ if (!fgResult) { -+ DBGLOG(RX, ERROR, "Read RX Packet Lentgh Error\n"); -+ break; -+ } -+ -+ u4PktLen = (UINT_32) (prHifRxHdr->u2PacketLen); -+ /* DBGLOG(RX, TRACE, ("u4PktLen = %d\n", u4PktLen)); */ -+ -+ prSwRfb->ucPacketType = (UINT_8) (prHifRxHdr->u2PacketType & HIF_RX_HDR_PACKET_TYPE_MASK); -+ /* DBGLOG(RX, TRACE, ("ucPacketType = %d\n", prSwRfb->ucPacketType)); */ -+ -+ prSwRfb->ucStaRecIdx = (UINT_8) (prHifRxHdr->ucStaRecIdx); -+ -+ /* 4 <2> if the RFB dw size or packet size is zero */ -+ if (u4PktLen == 0) { -+ DBGLOG(RX, ERROR, "Packet Length = %u\n", u4PktLen); -+ ASSERT(0); -+ break; -+ } -+ /* 4 <3> if the packet is too large or too small */ -+ if (u4PktLen > CFG_RX_MAX_PKT_SIZE) { -+ DBGLOG(RX, TRACE, "Read RX Packet Lentgh Error (%u)\n", u4PktLen); -+ ASSERT(0); -+ break; -+ } -+ -+ u4Status = WLAN_STATUS_SUCCESS; -+ } while (FALSE); -+ -+ DBGLOG_MEM8(RX, TRACE, pucBuf, ALIGN_4(u2RxLength + HIF_RX_HW_APPENDED_LEN)); -+ return u4Status; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Read frames from the data port for SDIO -+* I/F, fill RFB and put each frame into the rReceivedRFBList queue. -+* -+* @param prAdapter Pointer to the Adapter structure. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicRxSDIOReceiveRFBs(IN P_ADAPTER_T prAdapter) -+{ -+ P_SDIO_CTRL_T prSDIOCtrl; -+ P_RX_CTRL_T prRxCtrl; -+ P_SW_RFB_T prSwRfb = (P_SW_RFB_T) NULL; -+ UINT_32 i, rxNum; -+ UINT_16 u2RxPktNum, u2RxLength = 0, u2Tmp = 0; -+ -+ KAL_SPIN_LOCK_DECLARATION(); -+ -+ DEBUGFUNC("nicRxSDIOReceiveRFBs"); -+ -+ ASSERT(prAdapter); -+ -+ prSDIOCtrl = prAdapter->prSDIOCtrl; -+ ASSERT(prSDIOCtrl); -+ -+ prRxCtrl = &prAdapter->rRxCtrl; -+ ASSERT(prRxCtrl); -+ -+ for (rxNum = 0; rxNum < 2; rxNum++) { -+ u2RxPktNum = -+ (rxNum == 0 ? prSDIOCtrl->rRxInfo.u.u2NumValidRx0Len : prSDIOCtrl->rRxInfo.u.u2NumValidRx1Len); -+ -+ if (u2RxPktNum == 0) -+ continue; -+ -+ for (i = 0; i < u2RxPktNum; i++) { -+ if (rxNum == 0) { -+ /* HAL_READ_RX_LENGTH */ -+ HAL_READ_RX_LENGTH(prAdapter, &u2RxLength, &u2Tmp); -+ } else if (rxNum == 1) { -+ /* HAL_READ_RX_LENGTH */ -+ HAL_READ_RX_LENGTH(prAdapter, &u2Tmp, &u2RxLength); -+ } -+ -+ if (!u2RxLength) -+ break; -+ -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); -+ QUEUE_REMOVE_HEAD(&prRxCtrl->rFreeSwRfbList, prSwRfb, P_SW_RFB_T); -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); -+ -+ if (!prSwRfb) { -+ DBGLOG(RX, TRACE, "No More RFB\n"); -+ break; -+ } -+ ASSERT(prSwRfb); -+ -+ if (nicRxEnhanceReadBuffer(prAdapter, rxNum, u2RxLength, prSwRfb) == WLAN_STATUS_FAILURE) { -+ DBGLOG(RX, TRACE, "nicRxEnhanceRxReadBuffer failed\n"); -+ nicRxReturnRFB(prAdapter, prSwRfb); -+ break; -+ } -+ /* prSDIOCtrl->au4RxLength[i] = 0; */ -+ -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); -+ QUEUE_INSERT_TAIL(&prRxCtrl->rReceivedRfbList, &prSwRfb->rQueEntry); -+ RX_INC_CNT(prRxCtrl, RX_MPDU_TOTAL_COUNT); -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); -+ } -+ } -+ -+ prSDIOCtrl->rRxInfo.u.u2NumValidRx0Len = 0; -+ prSDIOCtrl->rRxInfo.u.u2NumValidRx1Len = 0; -+ -+} /* end of nicRxSDIOReceiveRFBs() */ -+ -+#endif /* CFG_SDIO_INTR_ENHANCE */ -+ -+#if CFG_SDIO_RX_AGG -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Read frames from the data port for SDIO with Rx aggregation enabled -+* I/F, fill RFB and put each frame into the rReceivedRFBList queue. -+* -+* @param prAdapter Pointer to the Adapter structure. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicRxSDIOAggReceiveRFBs(IN P_ADAPTER_T prAdapter) -+{ -+ P_ENHANCE_MODE_DATA_STRUCT_T prEnhDataStr; -+ P_RX_CTRL_T prRxCtrl; -+ P_SDIO_CTRL_T prSDIOCtrl; -+ P_SW_RFB_T prSwRfb = (P_SW_RFB_T) NULL; -+ UINT_32 u4RxLength; -+ UINT_32 i, rxNum; -+ UINT_32 u4RxAggCount = 0, u4RxAggLength = 0; -+ UINT_32 u4RxAvailAggLen, u4CurrAvailFreeRfbCnt; -+ PUINT_8 pucSrcAddr; -+ P_HIF_RX_HEADER_T prHifRxHdr; -+ BOOLEAN fgResult = TRUE; -+ BOOLEAN fgIsRxEnhanceMode; -+ UINT_16 u2RxPktNum; -+#if CFG_SDIO_RX_ENHANCE -+ UINT_32 u4MaxLoopCount = CFG_MAX_RX_ENHANCE_LOOP_COUNT; -+#endif -+ -+ KAL_SPIN_LOCK_DECLARATION(); -+ -+ DEBUGFUNC("nicRxSDIOAggReceiveRFBs"); -+ -+ ASSERT(prAdapter); -+ prEnhDataStr = prAdapter->prSDIOCtrl; -+ prRxCtrl = &prAdapter->rRxCtrl; -+ prSDIOCtrl = prAdapter->prSDIOCtrl; -+ -+#if CFG_SDIO_RX_ENHANCE -+ fgIsRxEnhanceMode = TRUE; -+#else -+ fgIsRxEnhanceMode = FALSE; -+#endif -+ -+ do { -+#if CFG_SDIO_RX_ENHANCE -+ /* to limit maximum loop for RX */ -+ u4MaxLoopCount--; -+ if (u4MaxLoopCount == 0) -+ break; -+#endif -+ -+ if (prEnhDataStr->rRxInfo.u.u2NumValidRx0Len == 0 && prEnhDataStr->rRxInfo.u.u2NumValidRx1Len == 0) -+ break; -+ -+ for (rxNum = 0; rxNum < 2; rxNum++) { -+ u2RxPktNum = -+ (rxNum == -+ 0 ? prEnhDataStr->rRxInfo.u.u2NumValidRx0Len : prEnhDataStr->rRxInfo.u.u2NumValidRx1Len); -+ -+ /* if this assertion happened, it is most likely a F/W bug */ -+ ASSERT(u2RxPktNum <= 16); -+ -+ if (u2RxPktNum > 16) -+ continue; -+ -+ if (u2RxPktNum == 0) -+ continue; -+ -+#if CFG_HIF_STATISTICS -+ prRxCtrl->u4TotalRxAccessNum++; -+ prRxCtrl->u4TotalRxPacketNum += u2RxPktNum; -+#endif -+ -+ u4CurrAvailFreeRfbCnt = prRxCtrl->rFreeSwRfbList.u4NumElem; -+ -+ /* if SwRfb is not enough, abort reading this time */ -+ if (u4CurrAvailFreeRfbCnt < u2RxPktNum) { -+#if CFG_HIF_RX_STARVATION_WARNING -+ DbgPrint("FreeRfb is not enough: %d available, need %d\n", u4CurrAvailFreeRfbCnt, -+ u2RxPktNum); -+ DbgPrint("Queued Count: %d / Dequeud Count: %d\n", prRxCtrl->u4QueuedCnt, -+ prRxCtrl->u4DequeuedCnt); -+#endif -+ continue; -+ } -+#if CFG_SDIO_RX_ENHANCE -+ u4RxAvailAggLen = -+ CFG_RX_COALESCING_BUFFER_SIZE - (sizeof(ENHANCE_MODE_DATA_STRUCT_T) + -+ 4 /* extra HW padding */); -+#else -+ u4RxAvailAggLen = CFG_RX_COALESCING_BUFFER_SIZE; -+#endif -+ u4RxAggCount = 0; -+ -+ for (i = 0; i < u2RxPktNum; i++) { -+ u4RxLength = (rxNum == 0 ? -+ (UINT_32) prEnhDataStr->rRxInfo.u.au2Rx0Len[i] : -+ (UINT_32) prEnhDataStr->rRxInfo.u.au2Rx1Len[i]); -+ -+ if (!u4RxLength) { -+ ASSERT(0); -+ break; -+ } -+ -+ if (ALIGN_4(u4RxLength + HIF_RX_HW_APPENDED_LEN) < u4RxAvailAggLen) { -+ if (u4RxAggCount < u4CurrAvailFreeRfbCnt) { -+ u4RxAvailAggLen -= ALIGN_4(u4RxLength + HIF_RX_HW_APPENDED_LEN); -+ u4RxAggCount++; -+ } else { -+ /* no FreeSwRfb for rx packet */ -+ ASSERT(0); -+ break; -+ } -+ } else { -+ /* CFG_RX_COALESCING_BUFFER_SIZE is not large enough */ -+ ASSERT(0); -+ break; -+ } -+ } -+ -+ u4RxAggLength = (CFG_RX_COALESCING_BUFFER_SIZE - u4RxAvailAggLen); -+ /* DBGLOG(RX, INFO, ("u4RxAggCount = %d, u4RxAggLength = %d\n", */ -+ /* u4RxAggCount, u4RxAggLength)); */ -+ -+ HAL_READ_RX_PORT(prAdapter, -+ rxNum, -+ u4RxAggLength, prRxCtrl->pucRxCoalescingBufPtr, CFG_RX_COALESCING_BUFFER_SIZE); -+ if (!fgResult) { -+ DBGLOG(RX, ERROR, "Read RX Agg Packet Error\n"); -+ continue; -+ } -+ -+ pucSrcAddr = prRxCtrl->pucRxCoalescingBufPtr; -+ for (i = 0; i < u4RxAggCount; i++) { -+ UINT_16 u2PktLength; -+ -+ u2PktLength = (rxNum == 0 ? -+ prEnhDataStr->rRxInfo.u.au2Rx0Len[i] : -+ prEnhDataStr->rRxInfo.u.au2Rx1Len[i]); -+ -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); -+ QUEUE_REMOVE_HEAD(&prRxCtrl->rFreeSwRfbList, prSwRfb, P_SW_RFB_T); -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); -+ -+ ASSERT(prSwRfb); -+ kalMemCopy(prSwRfb->pucRecvBuff, pucSrcAddr, -+ ALIGN_4(u2PktLength + HIF_RX_HW_APPENDED_LEN)); -+ -+ /* record the rx time */ -+ STATS_RX_ARRIVE_TIME_RECORD(prSwRfb); /* ms */ -+ -+ prHifRxHdr = prSwRfb->prHifRxHdr; -+ ASSERT(prHifRxHdr); -+ -+ prSwRfb->ucPacketType = -+ (UINT_8) (prHifRxHdr->u2PacketType & HIF_RX_HDR_PACKET_TYPE_MASK); -+ /* DBGLOG(RX, TRACE, ("ucPacketType = %d\n", prSwRfb->ucPacketType)); */ -+ -+ prSwRfb->ucStaRecIdx = (UINT_8) (prHifRxHdr->ucStaRecIdx); -+ -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); -+ QUEUE_INSERT_TAIL(&prRxCtrl->rReceivedRfbList, &prSwRfb->rQueEntry); -+ RX_INC_CNT(prRxCtrl, RX_MPDU_TOTAL_COUNT); -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); -+ -+ pucSrcAddr += ALIGN_4(u2PktLength + HIF_RX_HW_APPENDED_LEN); -+ /* prEnhDataStr->au4RxLength[i] = 0; */ -+ } -+ -+#if CFG_SDIO_RX_ENHANCE -+ kalMemCopy(prAdapter->prSDIOCtrl, (pucSrcAddr + 4), sizeof(ENHANCE_MODE_DATA_STRUCT_T)); -+ -+ /* do the same thing what nicSDIOReadIntStatus() does */ -+ if ((prSDIOCtrl->u4WHISR & WHISR_TX_DONE_INT) == 0 && -+ (prSDIOCtrl->rTxInfo.au4WTSR[0] | prSDIOCtrl->rTxInfo.au4WTSR[1])) { -+ prSDIOCtrl->u4WHISR |= WHISR_TX_DONE_INT; -+ } -+ -+ if ((prSDIOCtrl->u4WHISR & BIT(31)) == 0 && -+ HAL_GET_MAILBOX_READ_CLEAR(prAdapter) == TRUE && -+ (prSDIOCtrl->u4RcvMailbox0 != 0 || prSDIOCtrl->u4RcvMailbox1 != 0)) { -+ prSDIOCtrl->u4WHISR |= BIT(31); -+ } -+ -+ /* dispatch to interrupt handler with RX bits masked */ -+ nicProcessIST_impl(prAdapter, -+ prSDIOCtrl->u4WHISR & (~(WHISR_RX0_DONE_INT | WHISR_RX1_DONE_INT))); -+#endif -+ } -+ -+#if !CFG_SDIO_RX_ENHANCE -+ prEnhDataStr->rRxInfo.u.u2NumValidRx0Len = 0; -+ prEnhDataStr->rRxInfo.u.u2NumValidRx1Len = 0; -+#endif -+ } while ((prEnhDataStr->rRxInfo.u.u2NumValidRx0Len || prEnhDataStr->rRxInfo.u.u2NumValidRx1Len) -+ && fgIsRxEnhanceMode); -+ -+} -+#endif /* CFG_SDIO_RX_AGG */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Setup a RFB and allocate the os packet to the RFB -+* -+* @param prAdapter Pointer to the Adapter structure. -+* @param prSwRfb Pointer to the RFB -+* -+* @retval WLAN_STATUS_SUCCESS -+* @retval WLAN_STATUS_RESOURCES -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS nicRxSetupRFB(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb) -+{ -+ PVOID pvPacket; -+ PUINT_8 pucRecvBuff; -+ -+ ASSERT(prAdapter); -+ ASSERT(prSwRfb); -+ -+ if (!prSwRfb->pvPacket) { -+ kalMemZero(prSwRfb, sizeof(SW_RFB_T)); -+ pvPacket = kalPacketAlloc(prAdapter->prGlueInfo, CFG_RX_MAX_PKT_SIZE, &pucRecvBuff); -+ if (pvPacket == NULL) -+ return WLAN_STATUS_RESOURCES; -+ -+ prSwRfb->pvPacket = pvPacket; -+ prSwRfb->pucRecvBuff = (PVOID) pucRecvBuff; -+ } else { -+ kalMemZero(((PUINT_8) prSwRfb + OFFSET_OF(SW_RFB_T, prHifRxHdr)), -+ (sizeof(SW_RFB_T) - OFFSET_OF(SW_RFB_T, prHifRxHdr))); -+ } -+ -+ prSwRfb->prHifRxHdr = (P_HIF_RX_HEADER_T) (prSwRfb->pucRecvBuff); -+ -+ return WLAN_STATUS_SUCCESS; -+ -+} /* end of nicRxSetupRFB() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This routine is called to put a RFB back onto the "RFB with Buffer" list -+* or "RFB without buffer" list according to pvPacket. -+* -+* @param prAdapter Pointer to the Adapter structure. -+* @param prSwRfb Pointer to the RFB -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicRxReturnRFB(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb) -+{ -+ P_RX_CTRL_T prRxCtrl; -+ P_QUE_ENTRY_T prQueEntry; -+ -+ KAL_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(prAdapter); -+ ASSERT(prSwRfb); -+ prRxCtrl = &prAdapter->rRxCtrl; -+ prQueEntry = &prSwRfb->rQueEntry; -+ -+ ASSERT(prQueEntry); -+ -+ /* The processing on this RFB is done, so put it back on the tail of -+ our list */ -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); -+ -+ if (prSwRfb->pvPacket) { -+ /* QUEUE_INSERT_TAIL */ -+ QUEUE_INSERT_TAIL(&prRxCtrl->rFreeSwRfbList, prQueEntry); -+ } else { -+ /* QUEUE_INSERT_TAIL */ -+ QUEUE_INSERT_TAIL(&prRxCtrl->rIndicatedRfbList, prQueEntry); -+ } -+ -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); -+} /* end of nicRxReturnRFB() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Process rx interrupt. When the rx -+* Interrupt is asserted, it means there are frames in queue. -+* -+* @param prAdapter Pointer to the Adapter structure. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicProcessRxInterrupt(IN P_ADAPTER_T prAdapter) -+{ -+ P_GLUE_INFO_T prGlueInfo = prAdapter->prGlueInfo; -+ -+ prGlueInfo->IsrRxCnt++; -+#if CFG_SDIO_INTR_ENHANCE -+#if CFG_SDIO_RX_AGG -+ nicRxSDIOAggReceiveRFBs(prAdapter); -+#else -+ nicRxSDIOReceiveRFBs(prAdapter); -+#endif -+#else -+ nicRxReceiveRFBs(prAdapter); -+#endif /* CFG_SDIO_INTR_ENHANCE */ -+ -+ nicRxProcessRFBs(prAdapter); -+ -+ return; -+ -+} /* end of nicProcessRxInterrupt() */ -+ -+#if CFG_TCP_IP_CHKSUM_OFFLOAD -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Used to update IP/TCP/UDP checksum statistics of RX Module. -+* -+* @param prAdapter Pointer to the Adapter structure. -+* @param aeCSUM The array of checksum result. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicRxUpdateCSUMStatistics(IN P_ADAPTER_T prAdapter, IN const ENUM_CSUM_RESULT_T aeCSUM[]) -+{ -+ P_RX_CTRL_T prRxCtrl; -+ -+ ASSERT(prAdapter); -+ ASSERT(aeCSUM); -+ -+ prRxCtrl = &prAdapter->rRxCtrl; -+ ASSERT(prRxCtrl); -+ -+ if ((aeCSUM[CSUM_TYPE_IPV4] == CSUM_RES_SUCCESS) || -+ (aeCSUM[CSUM_TYPE_IPV6] == CSUM_RES_SUCCESS)) { -+ RX_INC_CNT(prRxCtrl, RX_CSUM_IP_SUCCESS_COUNT); -+ } else if ((aeCSUM[CSUM_TYPE_IPV4] == CSUM_RES_FAILED) || (aeCSUM[CSUM_TYPE_IPV6] == CSUM_RES_FAILED)) { -+ RX_INC_CNT(prRxCtrl, RX_CSUM_IP_FAILED_COUNT); -+ } else if ((aeCSUM[CSUM_TYPE_IPV4] == CSUM_RES_NONE) && (aeCSUM[CSUM_TYPE_IPV6] == CSUM_RES_NONE)) { -+ RX_INC_CNT(prRxCtrl, RX_CSUM_UNKNOWN_L3_PKT_COUNT); -+ } else { -+ ASSERT(0); -+ } -+ -+ if (aeCSUM[CSUM_TYPE_TCP] == CSUM_RES_SUCCESS) { -+ /* count success num */ -+ RX_INC_CNT(prRxCtrl, RX_CSUM_TCP_SUCCESS_COUNT); -+ } else if (aeCSUM[CSUM_TYPE_TCP] == CSUM_RES_FAILED) { -+ RX_INC_CNT(prRxCtrl, RX_CSUM_TCP_FAILED_COUNT); -+ } else if (aeCSUM[CSUM_TYPE_UDP] == CSUM_RES_SUCCESS) { -+ RX_INC_CNT(prRxCtrl, RX_CSUM_UDP_SUCCESS_COUNT); -+ } else if (aeCSUM[CSUM_TYPE_UDP] == CSUM_RES_FAILED) { -+ RX_INC_CNT(prRxCtrl, RX_CSUM_UDP_FAILED_COUNT); -+ } else if ((aeCSUM[CSUM_TYPE_UDP] == CSUM_RES_NONE) && (aeCSUM[CSUM_TYPE_TCP] == CSUM_RES_NONE)) { -+ RX_INC_CNT(prRxCtrl, RX_CSUM_UNKNOWN_L4_PKT_COUNT); -+ } else { -+ ASSERT(0); -+ } -+ -+} /* end of nicRxUpdateCSUMStatistics() */ -+#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is used to query current status of RX Module. -+* -+* @param prAdapter Pointer to the Adapter structure. -+* @param pucBuffer Pointer to the message buffer. -+* @param pu4Count Pointer to the buffer of message length count. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicRxQueryStatus(IN P_ADAPTER_T prAdapter, IN PUINT_8 pucBuffer, OUT PUINT_32 pu4Count) -+{ -+ P_RX_CTRL_T prRxCtrl; -+ PUINT_8 pucCurrBuf = pucBuffer; -+ -+ ASSERT(prAdapter); -+ prRxCtrl = &prAdapter->rRxCtrl; -+ ASSERT(prRxCtrl); -+ -+ /* if (pucBuffer) {} */ /* For Windows, we'll print directly instead of sprintf() */ -+ ASSERT(pu4Count); -+ -+ SPRINTF(pucCurrBuf, ("\n\nRX CTRL STATUS:")); -+ SPRINTF(pucCurrBuf, ("\n===============")); -+ SPRINTF(pucCurrBuf, ("\nFREE RFB w/i BUF LIST :%9u", prRxCtrl->rFreeSwRfbList.u4NumElem)); -+ SPRINTF(pucCurrBuf, ("\nFREE RFB w/o BUF LIST :%9u", prRxCtrl->rIndicatedRfbList.u4NumElem)); -+ SPRINTF(pucCurrBuf, ("\nRECEIVED RFB LIST :%9u", prRxCtrl->rReceivedRfbList.u4NumElem)); -+ -+ SPRINTF(pucCurrBuf, ("\n\n")); -+ -+ /* *pu4Count = (UINT_32)((UINT_32)pucCurrBuf - (UINT_32)pucBuffer); */ -+ -+} /* end of nicRxQueryStatus() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Clear RX related counters -+* -+* @param prAdapter Pointer of Adapter Data Structure -+* -+* @return - (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicRxClearStatistics(IN P_ADAPTER_T prAdapter) -+{ -+ P_RX_CTRL_T prRxCtrl; -+ -+ ASSERT(prAdapter); -+ prRxCtrl = &prAdapter->rRxCtrl; -+ ASSERT(prRxCtrl); -+ -+ RX_RESET_ALL_CNTS(prRxCtrl); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is used to query current statistics of RX Module. -+* -+* @param prAdapter Pointer to the Adapter structure. -+* @param pucBuffer Pointer to the message buffer. -+* @param pu4Count Pointer to the buffer of message length count. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicRxQueryStatistics(IN P_ADAPTER_T prAdapter, IN PUINT_8 pucBuffer, OUT PUINT_32 pu4Count) -+{ -+ P_RX_CTRL_T prRxCtrl; -+ PUINT_8 pucCurrBuf = pucBuffer; -+ -+ ASSERT(prAdapter); -+ prRxCtrl = &prAdapter->rRxCtrl; -+ ASSERT(prRxCtrl); -+ -+ /* if (pucBuffer) {} */ /* For Windows, we'll print directly instead of sprintf() */ -+ ASSERT(pu4Count); -+ -+#define SPRINTF_RX_COUNTER(eCounter) \ -+ SPRINTF(pucCurrBuf, ("%-30s : %u\n", #eCounter, (UINT_32)prRxCtrl->au8Statistics[eCounter])) -+ -+ SPRINTF_RX_COUNTER(RX_MPDU_TOTAL_COUNT); -+ SPRINTF_RX_COUNTER(RX_SIZE_ERR_DROP_COUNT); -+ SPRINTF_RX_COUNTER(RX_DATA_INDICATION_COUNT); -+ SPRINTF_RX_COUNTER(RX_DATA_RETURNED_COUNT); -+ SPRINTF_RX_COUNTER(RX_DATA_RETAINED_COUNT); -+ -+#if CFG_TCP_IP_CHKSUM_OFFLOAD || CFG_TCP_IP_CHKSUM_OFFLOAD_NDIS_60 -+ SPRINTF_RX_COUNTER(RX_CSUM_TCP_FAILED_COUNT); -+ SPRINTF_RX_COUNTER(RX_CSUM_UDP_FAILED_COUNT); -+ SPRINTF_RX_COUNTER(RX_CSUM_IP_FAILED_COUNT); -+ SPRINTF_RX_COUNTER(RX_CSUM_TCP_SUCCESS_COUNT); -+ SPRINTF_RX_COUNTER(RX_CSUM_UDP_SUCCESS_COUNT); -+ SPRINTF_RX_COUNTER(RX_CSUM_IP_SUCCESS_COUNT); -+ SPRINTF_RX_COUNTER(RX_CSUM_UNKNOWN_L4_PKT_COUNT); -+ SPRINTF_RX_COUNTER(RX_CSUM_UNKNOWN_L3_PKT_COUNT); -+ SPRINTF_RX_COUNTER(RX_IP_V6_PKT_CCOUNT); -+#endif -+ -+ /* *pu4Count = (UINT_32)(pucCurrBuf - pucBuffer); */ -+ -+ nicRxClearStatistics(prAdapter); -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Read the Response data from data port -+* -+* @param prAdapter pointer to the Adapter handler -+* @param pucRspBuffer pointer to the Response buffer -+* -+* @retval WLAN_STATUS_SUCCESS: Response packet has been read -+* @retval WLAN_STATUS_FAILURE: Read Response packet timeout or error occurred -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+nicRxWaitResponse(IN P_ADAPTER_T prAdapter, -+ IN UINT_8 ucPortIdx, OUT PUINT_8 pucRspBuffer, IN UINT_32 u4MaxRespBufferLen, OUT PUINT_32 pu4Length) -+{ -+ UINT_32 u4Value = 0, u4PktLen = 0; -+ UINT_32 i = 0; -+ WLAN_STATUS u4Status = WLAN_STATUS_SUCCESS; -+ BOOLEAN fgResult = TRUE; -+ UINT_32 u4Time, u4Current; -+ -+ DEBUGFUNC("nicRxWaitResponse"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pucRspBuffer); -+ ASSERT(ucPortIdx < 2); -+ -+ u4Time = kalGetTimeTick(); -+ -+ do { -+ /* Read the packet length */ -+ HAL_MCR_RD(prAdapter, MCR_WRPLR, &u4Value); -+ -+ if (!fgResult) { -+ DBGLOG(RX, ERROR, "Read Response Packet Error\n"); -+ return WLAN_STATUS_FAILURE; -+ } -+ -+ if (ucPortIdx == 0) -+ u4PktLen = u4Value & 0xFFFF; -+ else -+ u4PktLen = (u4Value >> 16) & 0xFFFF; -+ -+/* DBGLOG(RX, TRACE, ("i = %d, u4PktLen = %d\n", i, u4PktLen)); */ -+ -+ if (u4PktLen == 0) { -+ /* timeout exceeding check */ -+ u4Current = kalGetTimeTick(); -+ -+ if ((u4Current > u4Time) && ((u4Current - u4Time) > RX_RESPONSE_TIMEOUT)) { -+ DBGLOG(RX, ERROR, "RX_RESPONSE_TIMEOUT1 %u %d %u\n", u4PktLen, i, u4Current); -+ return WLAN_STATUS_FAILURE; -+ } else if (u4Current < u4Time && ((u4Current + (0xFFFFFFFF - u4Time)) > RX_RESPONSE_TIMEOUT)) { -+ DBGLOG(RX, ERROR, "RX_RESPONSE_TIMEOUT2 %u %d %u\n", u4PktLen, i, u4Current); -+ return WLAN_STATUS_FAILURE; -+ } -+ -+ /* Response packet is not ready */ -+ kalUdelay(50); -+ -+ i++; -+ continue; -+ } -+ if (u4PktLen > u4MaxRespBufferLen) { -+ /* -+ TO: buffer is not enough but we still need to read all data from HIF to avoid -+ HIF crazy. -+ */ -+ DBGLOG(RX, ERROR, -+ "Not enough Event Buffer: required length = 0x%x, available buffer length = %d\n", -+ u4PktLen, u4MaxRespBufferLen); -+ DBGLOG(RX, ERROR, "i = %d, u4PktLen = %u\n", i, u4PktLen); -+ return WLAN_STATUS_FAILURE; -+ } -+ HAL_PORT_RD(prAdapter, -+ ucPortIdx == 0 ? MCR_WRDR0 : MCR_WRDR1, u4PktLen, pucRspBuffer, u4MaxRespBufferLen); -+ -+ /* fgResult will be updated in MACRO */ -+ if (!fgResult) { -+ DBGLOG(RX, ERROR, "Read Response Packet Error\n"); -+ return WLAN_STATUS_FAILURE; -+ } -+ -+ DBGLOG(RX, TRACE, "Dump Response buffer, length = 0x%x\n", u4PktLen); -+ DBGLOG_MEM8(RX, TRACE, pucRspBuffer, u4PktLen); -+ -+ *pu4Length = u4PktLen; -+ break; -+ } while (TRUE); -+ -+ return u4Status; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Set filter to enable Promiscuous Mode -+* -+* @param prAdapter Pointer to the Adapter structure. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicRxEnablePromiscuousMode(IN P_ADAPTER_T prAdapter) -+{ -+ ASSERT(prAdapter); -+ -+} /* end of nicRxEnablePromiscuousMode() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Set filter to disable Promiscuous Mode -+* -+* @param prAdapter Pointer to the Adapter structure. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicRxDisablePromiscuousMode(IN P_ADAPTER_T prAdapter) -+{ -+ ASSERT(prAdapter); -+ -+} /* end of nicRxDisablePromiscuousMode() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief this function flushes all packets queued in reordering module -+* -+* @param prAdapter Pointer to the Adapter structure. -+* -+* @retval WLAN_STATUS_SUCCESS Flushed successfully -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS nicRxFlush(IN P_ADAPTER_T prAdapter) -+{ -+ P_SW_RFB_T prSwRfb; -+ -+ ASSERT(prAdapter); -+ -+ prSwRfb = qmFlushRxQueues(prAdapter); -+ if (prSwRfb != NULL) { -+ do { -+ P_SW_RFB_T prNextSwRfb; -+ -+ /* save next first */ -+ prNextSwRfb = (P_SW_RFB_T) QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T) prSwRfb); -+ -+ /* free */ -+ nicRxReturnRFB(prAdapter, prSwRfb); -+ -+ prSwRfb = prNextSwRfb; -+ } while (prSwRfb); -+ } -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief -+* -+* @param -+* -+* @retval -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS nicRxProcessActionFrame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb) -+{ -+ P_WLAN_ACTION_FRAME prActFrame; -+ -+ ASSERT(prAdapter); -+ ASSERT(prSwRfb); -+ -+ if (prSwRfb->u2PacketLen < sizeof(WLAN_ACTION_FRAME) - 1) -+ return WLAN_STATUS_INVALID_PACKET; -+ prActFrame = (P_WLAN_ACTION_FRAME) prSwRfb->pvHeader; -+ DBGLOG(RX, INFO, "Category %u\n", prActFrame->ucCategory); -+ -+ switch (prActFrame->ucCategory) { -+ case CATEGORY_PUBLIC_ACTION: -+ if (HIF_RX_HDR_GET_NETWORK_IDX(prSwRfb->prHifRxHdr) == NETWORK_TYPE_AIS_INDEX) -+ aisFuncValidateRxActionFrame(prAdapter, prSwRfb); -+#if CFG_ENABLE_WIFI_DIRECT -+ else if (prAdapter->fgIsP2PRegistered) { -+ rlmProcessPublicAction(prAdapter, prSwRfb); -+ -+ p2pFuncValidateRxActionFrame(prAdapter, prSwRfb); -+ -+ } -+#endif -+ break; -+ -+ case CATEGORY_HT_ACTION: -+#if CFG_ENABLE_WIFI_DIRECT -+ if (prAdapter->fgIsP2PRegistered) -+ rlmProcessHtAction(prAdapter, prSwRfb); -+#endif -+ break; -+ case CATEGORY_VENDOR_SPECIFIC_ACTION: -+#if CFG_ENABLE_WIFI_DIRECT -+ if (prAdapter->fgIsP2PRegistered) -+ p2pFuncValidateRxActionFrame(prAdapter, prSwRfb); -+#endif -+ break; -+#if CFG_SUPPORT_802_11W -+ case CATEGORY_SA_QUERT_ACTION: -+ { -+ P_HIF_RX_HEADER_T prHifRxHdr; -+ -+ prHifRxHdr = prSwRfb->prHifRxHdr; -+ -+ if ((HIF_RX_HDR_GET_NETWORK_IDX(prHifRxHdr) == NETWORK_TYPE_AIS_INDEX) -+ && prAdapter->rWifiVar.rAisSpecificBssInfo.fgMgmtProtection /* Use MFP */) { -+ if (!(prHifRxHdr->ucReserved & CONTROL_FLAG_UC_MGMT_NO_ENC)) { -+ /* MFP test plan 5.3.3.4 */ -+ rsnSaQueryAction(prAdapter, prSwRfb); -+ } else { -+ DBGLOG(RSN, TRACE, "Un-Protected SA Query, do nothing\n"); -+ } -+ } -+ } -+ break; -+#endif -+#if CFG_SUPPORT_802_11V -+ case CATEGORY_WNM_ACTION: -+ { -+ wnmWNMAction(prAdapter, prSwRfb); -+ } -+ break; -+#endif -+ -+#if CFG_SUPPORT_DFS /* Add by Enlai */ -+ case CATEGORY_SPEC_MGT: -+ { -+ if (prAdapter->fgEnable5GBand == TRUE) -+ rlmProcessSpecMgtAction(prAdapter, prSwRfb); -+ } -+ break; -+#endif -+ -+#if (CFG_SUPPORT_TDLS == 1) -+ case 12: /* shall not be here */ -+ /* -+ A received TDLS Action frame with the Type field set to Management shall -+ be discarded. Note that the TDLS Discovery Response frame is not a TDLS -+ frame but a Public Action frame. -+ */ -+ break; -+#endif /* CFG_SUPPORT_TDLS */ -+ -+ default: -+ break; -+ } /* end of switch case */ -+ -+ return WLAN_STATUS_SUCCESS; -+} -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic_tx.c b/drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic_tx.c -new file mode 100644 -index 000000000000..024bd9507603 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic_tx.c -@@ -0,0 +1,2350 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/nic/nic_tx.c#1 -+*/ -+ -+/*! \file nic_tx.c -+ \brief Functions that provide TX operation in NIC Layer. -+ -+ This file provides TX functions which are responsible for both Hardware and -+ Software Resource Management and keep their Synchronization. -+*/ -+ -+/* -+** Log: nic_tx.c -+ * -+ * 06 13 2012 yuche.tsai -+ * NULL -+ * Update maintrunk driver. -+ * Add support for driver compose assoc request frame. -+ * -+ * 11 18 2011 eddie.chen -+ * [WCXRP00001096] [MT6620 Wi-Fi][Driver/FW] Enhance the log function (xlog) -+ * Add log counter for tx -+ * -+ * 11 09 2011 eddie.chen -+ * [WCXRP00001096] [MT6620 Wi-Fi][Driver/FW] Enhance the log function (xlog) -+ * Add xlog for beacon timeout and sta aging timeout. -+ * -+ * 11 08 2011 eddie.chen -+ * [WCXRP00001096] [MT6620 Wi-Fi][Driver/FW] Enhance the log function (xlog) -+ * Add xlog function. -+ * -+ * 05 17 2011 cp.wu -+ * [WCXRP00000732] [MT6620 Wi-Fi][AIS] No need to switch back to IDLE state when DEAUTH frame is dropped due to bss -+ * disconnection -+ * when TX DONE status is TX_RESULT_DROPPED_IN_DRIVER, no need to switch back to IDLE state. -+ * -+ * 04 12 2011 eddie.chen -+ * [WCXRP00000617] [MT6620 Wi-Fi][DRV/FW] Fix for sigma -+ * Fix the sta index in processing security frame -+ * Simple flow control for TC4 to avoid mgt frames for PS STA to occupy the TC4 -+ * Add debug message. -+ * -+ * 04 12 2011 cp.wu -+ * [WCXRP00000631] [MT6620 Wi-Fi][Driver] Add an API for QM to retrieve current TC counter value and processing frame -+ * dropping cases for TC4 path -+ * remove unused variables. -+ * -+ * 04 12 2011 cp.wu -+ * [WCXRP00000631] [MT6620 Wi-Fi][Driver] Add an API for QM to retrieve current TC counter value and processing frame -+ * dropping cases for TC4 path -+ * 1. add nicTxGetResource() API for QM to make decisions. -+ * 2. if management frames is decided by QM for dropping, the call back is invoked to indicate such a case. -+ * -+ * 03 17 2011 cp.wu -+ * [WCXRP00000562] [MT6620 Wi-Fi][Driver] I/O buffer pre-allocation to avoid physically continuous memory shortage -+ * after system running for a long period -+ * use pre-allocated buffer for storing enhanced interrupt response as well -+ * -+ * 03 15 2011 cp.wu -+ * [WCXRP00000559] [MT6620 Wi-Fi][Driver] Combine TX/RX DMA buffers into a single one to reduce physically continuous -+ * memory consumption -+ * 1. deprecate CFG_HANDLE_IST_IN_SDIO_CALLBACK -+ * 2. Use common coalescing buffer for both TX/RX directions -+ * -+ * -+ * 02 16 2011 cp.wu -+ * [WCXRP00000449] [MT6620 Wi-Fi][Driver] Refine CMD queue handling by adding an extra API for checking available count -+ * and modify behavior -+ * 1. add new API: nicTxGetFreeCmdCount() -+ * 2. when there is insufficient command descriptor, nicTxEnqueueMsdu() will drop command packets directly -+ * -+ * 01 24 2011 cp.wu -+ * [WCXRP00000382] [MT6620 Wi-Fi][Driver] Track forwarding packet number with notifying tx thread for serving -+ * 1. add an extra counter for tracking pending forward frames. -+ * 2. notify TX service thread as well when there is pending forward frame -+ * 3. correct build errors leaded by introduction of Wi-Fi direct separation module -+ * -+ * 01 12 2011 cp.wu -+ * [WCXRP00000356] [MT6620 Wi-Fi][Driver] fill mac header length for security frames 'cause hardware header translation -+ * needs such information -+ * fill mac header length information for 802.1x frames. -+ * -+ * 12 31 2010 cp.wu -+ * [WCXRP00000335] [MT6620 Wi-Fi][Driver] change to use milliseconds sleep instead of delay to avoid blocking to system -+ * scheduling -+ * change to use msleep() and shorten waiting interval to reduce blocking to other task while Wi-Fi driver is being -+ * loaded -+ * -+ * 11 01 2010 yarco.yang -+ * [WCXRP00000149] [MT6620 WI-Fi][Driver]Fine tune performance on MT6516 platform -+ * Add GPIO debug function -+ * -+ * 10 18 2010 cp.wu -+ * [WCXRP00000117] [MT6620 Wi-Fi][Driver] Add logic for suspending driver when MT6620 is not responding anymore -+ * 1. when wlanAdapterStop() failed to send POWER CTRL command to firmware, do not poll for ready bit dis-assertion -+ * 2. shorten polling count for shorter response time -+ * 3. if bad I/O operation is detected during TX resource polling, then further operation is aborted as well -+ * -+ * 10 06 2010 cp.wu -+ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning -+ * code reorganization to improve isolation between GLUE and CORE layers. -+ * -+ * 09 29 2010 wh.su -+ * [WCXRP00000072] [MT6620 Wi-Fi][Driver] Fix TKIP Counter Measure EAPoL callback register issue -+ * [MT6620 Wi-Fi][Driver] Fix TKIP Counter Measure EAPoL callback register issue. -+ * -+ * 09 27 2010 wh.su -+ * NULL -+ * since the u2TxByteCount_UserPriority will or another setting, keep the overall buffer for avoid error -+ * -+ * 09 24 2010 wh.su -+ * NULL -+ * [WCXRP000000058][MT6620 Wi-Fi][Driver] Fail to handshake with WAPI AP due the 802.1x frame send to fw with extra -+ * bytes padding. -+ * -+ * 09 01 2010 cp.wu -+ * NULL -+ * HIFSYS Clock Source Workaround -+ * -+ * 08 30 2010 cp.wu -+ * NULL -+ * API added: nicTxPendingPackets(), for simplifying porting layer -+ * -+ * 08 30 2010 cp.wu -+ * NULL -+ * eliminate klockwork errors -+ * -+ * 08 20 2010 wh.su -+ * NULL -+ * adding the eapol callback setting. -+ * -+ * 08 18 2010 yarco.yang -+ * NULL -+ * 1. Fixed HW checksum offload function not work under Linux issue. -+ * 2. Add debug message. -+ * -+ * 08 05 2010 yuche.tsai -+ * NULL -+ * . -+ * -+ * 08 03 2010 cp.wu -+ * NULL -+ * surpress compilation warning. -+ * -+ * 08 02 2010 jeffrey.chang -+ * NULL -+ * 1) modify tx service thread to avoid busy looping -+ * 2) add spin lock declartion for linux build -+ * -+ * 07 29 2010 cp.wu -+ * NULL -+ * simplify post-handling after TX_DONE interrupt is handled. -+ * -+ * 07 19 2010 jeffrey.chang -+ * -+ * Linux port modification -+ * -+ * 07 13 2010 cp.wu -+ * -+ * 1) MMPDUs are now sent to MT6620 by CMD queue for keeping strict order of 1X/MMPDU/CMD packets -+ * 2) integrate with qmGetFrameAction() for deciding which MMPDU/1X could pass checking for sending -+ * 2) enhance CMD_INFO_T descriptor number from 10 to 32 to avoid descriptor underflow under concurrent network -+ * operation -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 29 2010 yarco.yang -+ * [WPD00003837][MT6620]Data Path Refine -+ * replace g_rQM with Adpater->rQM -+ * -+ * 06 25 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add API in que_mgt to retrieve sta-rec index for security frames. -+ * -+ * 06 24 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 802.1x and bluetooth-over-Wi-Fi security frames are now delievered to firmware via command path instead of data path. -+ * -+ * 06 23 2010 yarco.yang -+ * [WPD00003837][MT6620]Data Path Refine -+ * Merge g_arStaRec[] into adapter->arStaRec[] -+ * -+ * 06 22 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) add command warpper for STA-REC/BSS-INFO sync. -+ * 2) enhance command packet sending procedure for non-oid part -+ * 3) add command packet definitions for STA-REC/BSS-INFO sync. -+ * -+ * 06 21 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add checking for TX descriptor poll. -+ * -+ * 06 21 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * TX descriptors are now allocated once for reducing allocation overhead -+ * -+ * 06 18 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Provide cnmMgtPktAlloc() and alloc/free function of msg/buf -+ * -+ * 06 15 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * change zero-padding for TX port access to HAL. -+ * -+ * 06 15 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * . -+ * -+ * 06 15 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * . -+ * -+ * 06 14 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * fill extra information for revised HIF_TX_HEADER. -+ * -+ * 06 11 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) migrate assoc.c. -+ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness -+ * 3) add configuration options for CNM_MEM and RSN modules -+ * 4) add data path for management frames -+ * 5) eliminate rPacketInfo of MSDU_INFO_T -+ * -+ * 06 10 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * change to enqueue TX frame infinitely. -+ * -+ * 06 09 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add TX_PACKET_MGMT to indicate the frame is coming from management modules -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 05 10 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * fill network type field while doing frame identification. -+ * -+ * 04 23 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * surpress compiler warning -+ * -+ * 04 06 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * Tag the packet for QoS on Tx path -+ * -+ * 03 30 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * remove driver-land statistics. -+ * -+ * 03 29 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * improve none-glue code portability -+ * -+ * 03 24 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * initial import for Linux port -+ * -+ * 03 24 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * generate information for OID_GEN_RCV_OK & OID_GEN_XMIT_OK -+ * * * * * -+ * -+* 03 10 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * code clean: removing unused variables and structure definitions -+ * -+ * 03 08 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) add another spin-lock to protect MsduInfoList due to it might be accessed by different thread. -+ * * * * 2) change own-back acquiring procedure to wait for up to 16.67 seconds -+ * -+ * 03 02 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * add mutex to avoid multiple access to qmTxQueue simultaneously. -+ * -+ * 02 26 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * avoid referring to NDIS-specific data structure directly from non-glue layer. -+ * -+ * 02 24 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * add Ethernet destination address information in packet info for TX -+ * -+ * 02 10 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) remove unused function in nic_rx.c [which has been handled in que_mgt.c] -+ * * * * * * 2) firmware image length is now retrieved via NdisFileOpen -+ * * * * * * 3) firmware image is not structured by (P_IMG_SEC_HDR_T) anymore -+ * * * * * * 4) nicRxWaitResponse() revised -+ * * * * * * 5) another set of TQ counter default value is added for fw-download state -+ * * * * * * 6) Wi-Fi load address is now retrieved from registry too -+ * -+ * 02 09 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1. Permanent and current MAC address are now retrieved by CMD/EVENT packets instead of hard-coded address -+ * * * * * * * * * 2. follow MSDN defined behavior when associates to another AP -+ * * * * * * * * * 3. for firmware download, packet size could be up to 2048 bytes -+ * -+ * 02 08 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * prepare for implementing fw download logic -+ * -+ * 01 27 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1. eliminate improper variable in rHifInfo -+ * * * * * * * * * 2. block TX/ordinary OID when RF test mode is engaged -+ * * * * * * * * * 3. wait until firmware finish operation when entering into and leaving from RF test mode -+ * * * * * * * * * 4. correct some HAL implementation -+ * -+ * 01 13 2010 tehuang.liu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * Enabled the Burst_End Indication mechanism -+ * -+ * 01 13 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * TX: fill ucWlanHeaderLength/ucPktFormtId_Flags according to info provided by prMsduInfo -+ * -+ * 12 30 2009 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) According to CMD/EVENT documentation v0.8, -+ * * * * * * * * * * OID_CUSTOM_TEST_RX_STATUS & OID_CUSTOM_TEST_TX_STATUS is no longer used, -+ * * * * * * * * * * and result is retrieved by get ATInfo instead -+ * * * * * * * * * * 2) add 4 counter for recording aggregation statistics -+** \main\maintrunk.MT6620WiFiDriver_Prj\44 2009-12-10 16:52:15 GMT mtk02752 -+** remove unused API -+** \main\maintrunk.MT6620WiFiDriver_Prj\43 2009-12-07 22:44:24 GMT mtk02752 -+** correct assertion criterion -+** \main\maintrunk.MT6620WiFiDriver_Prj\42 2009-12-07 21:15:52 GMT mtk02752 -+** correct trivial mistake -+** \main\maintrunk.MT6620WiFiDriver_Prj\41 2009-12-04 15:47:21 GMT mtk02752 -+** + always append a dword of zero on TX path to avoid TX aggregation to triggered on uninitialized data -+** + add more assertion for packet size check -+** \main\maintrunk.MT6620WiFiDriver_Prj\40 2009-12-04 14:51:55 GMT mtk02752 -+** nicTxMsduInfo(): save ptr for next entry before attaching to qDataPort -+** \main\maintrunk.MT6620WiFiDriver_Prj\39 2009-12-04 11:54:54 GMT mtk02752 -+** add 2 assertion for size check -+** \main\maintrunk.MT6620WiFiDriver_Prj\38 2009-12-03 16:20:35 GMT mtk01461 -+** Add debug message -+** \main\maintrunk.MT6620WiFiDriver_Prj\37 2009-11-30 10:57:10 GMT mtk02752 -+** 1st DW of WIFI_CMD_T is shared with HIF_TX_HEADER_T -+** \main\maintrunk.MT6620WiFiDriver_Prj\36 2009-11-30 09:20:43 GMT mtk02752 -+** use TC4 instead of TC5 for command packet -+** \main\maintrunk.MT6620WiFiDriver_Prj\35 2009-11-27 11:08:11 GMT mtk02752 -+** add flush for reset -+** \main\maintrunk.MT6620WiFiDriver_Prj\34 2009-11-26 20:31:22 GMT mtk02752 -+** fill prMsduInfo->ucUserPriority -+** \main\maintrunk.MT6620WiFiDriver_Prj\33 2009-11-25 21:04:33 GMT mtk02752 -+** fill u2SeqNo -+** \main\maintrunk.MT6620WiFiDriver_Prj\32 2009-11-24 20:52:12 GMT mtk02752 -+** integration with SD1's data path API -+** \main\maintrunk.MT6620WiFiDriver_Prj\31 2009-11-24 19:54:25 GMT mtk02752 -+** nicTxRetransmitOfOsSendQue & nicTxData but changed to use nicTxMsduInfoList -+** \main\maintrunk.MT6620WiFiDriver_Prj\30 2009-11-23 17:53:18 GMT mtk02752 -+** add nicTxCmd() for SD1_SD3_DATAPATH_INTEGRATION, which will append only HIF_TX_HEADER. seqNum, -+** WIFI_CMD_T will be created inside oid handler -+** \main\maintrunk.MT6620WiFiDriver_Prj\29 2009-11-20 15:10:24 GMT mtk02752 -+** use TxAccquireResource instead of accessing TCQ directly. -+** \main\maintrunk.MT6620WiFiDriver_Prj\28 2009-11-17 22:40:57 GMT mtk01084 -+** \main\maintrunk.MT6620WiFiDriver_Prj\27 2009-11-17 17:35:40 GMT mtk02752 -+** add nicTxMsduInfoList () implementation -+** \main\maintrunk.MT6620WiFiDriver_Prj\26 2009-11-17 11:07:10 GMT mtk02752 -+** add nicTxAdjustTcq() implementation -+** \main\maintrunk.MT6620WiFiDriver_Prj\25 2009-11-16 22:28:38 GMT mtk02752 -+** move aucFreeBufferCount/aucMaxNumOfBuffer into another structure -+** \main\maintrunk.MT6620WiFiDriver_Prj\24 2009-11-16 21:45:32 GMT mtk02752 -+** add SD1_SD3_DATAPATH_INTEGRATION data path handling -+** \main\maintrunk.MT6620WiFiDriver_Prj\23 2009-11-13 13:29:56 GMT mtk01084 -+** modify TX hdr format, fix tx retransmission issue -+** \main\maintrunk.MT6620WiFiDriver_Prj\22 2009-11-11 10:36:21 GMT mtk01084 -+** \main\maintrunk.MT6620WiFiDriver_Prj\21 2009-11-04 14:11:11 GMT mtk01084 -+** modify TX SW data structure -+** \main\maintrunk.MT6620WiFiDriver_Prj\20 2009-10-29 19:56:17 GMT mtk01084 -+** modify HAL part -+** \main\maintrunk.MT6620WiFiDriver_Prj\19 2009-10-13 21:59:23 GMT mtk01084 -+** update for new HW design -+** \main\maintrunk.MT6620WiFiDriver_Prj\18 2009-10-02 14:00:18 GMT mtk01725 -+** \main\maintrunk.MT6620WiFiDriver_Prj\17 2009-05-20 12:26:06 GMT mtk01461 -+** Assign SeqNum to CMD Packet -+** \main\maintrunk.MT6620WiFiDriver_Prj\16 2009-05-19 10:54:04 GMT mtk01461 -+** Add debug message -+** \main\maintrunk.MT6620WiFiDriver_Prj\15 2009-05-12 09:41:55 GMT mtk01461 -+** Fix Query Command need resp issue -+** \main\maintrunk.MT6620WiFiDriver_Prj\14 2009-04-29 15:44:38 GMT mtk01461 -+** Move OS dependent code to kalQueryTxOOBData() -+** \main\maintrunk.MT6620WiFiDriver_Prj\13 2009-04-28 10:40:03 GMT mtk01461 -+** Add nicTxReleaseResource() for SDIO_STATUS_ENHANCE, and also fix the TX aggregation issue for 1x packet to TX1 port -+** \main\maintrunk.MT6620WiFiDriver_Prj\12 2009-04-21 09:50:47 GMT mtk01461 -+** Update nicTxCmd() for moving wait RESP function call to wlanSendCommand() -+** \main\maintrunk.MT6620WiFiDriver_Prj\11 2009-04-17 19:56:32 GMT mtk01461 -+** Move the CMD_INFO_T related function to cmd_buf.c -+** \main\maintrunk.MT6620WiFiDriver_Prj\10 2009-04-17 18:14:40 GMT mtk01426 -+** Update OOB query for TX packet -+** \main\maintrunk.MT6620WiFiDriver_Prj\9 2009-04-14 15:51:32 GMT mtk01426 -+** Support PKGUIO -+** \main\maintrunk.MT6620WiFiDriver_Prj\8 2009-04-02 17:26:40 GMT mtk01461 -+** Add virtual OOB for HIF LOOPBACK SW PRETEST -+** \main\maintrunk.MT6620WiFiDriver_Prj\7 2009-04-01 10:54:43 GMT mtk01461 -+** Add function for SDIO_TX_ENHANCE -+** \main\maintrunk.MT6620WiFiDriver_Prj\6 2009-03-23 21:53:47 GMT mtk01461 -+** Add code for retransmit of rOsSendQueue, mpSendPacket(), and add code for TX Checksum offload, Loopback Test. -+** \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-03-23 00:33:51 GMT mtk01461 -+** Add code for TX Data & Cmd Packet -+** \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-03-18 20:25:40 GMT mtk01461 -+** Fix LINT warning -+** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-03-16 09:10:30 GMT mtk01461 -+** Update TX PATH API -+** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 20:26:04 GMT mtk01426 -+** Init for develop -+** -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "precomp.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will initial all variables in regard to SW TX Queues and -+* all free lists of MSDU_INFO_T and SW_TFCB_T. -+* -+* @param prAdapter Pointer to the Adapter structure. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicTxInitialize(IN P_ADAPTER_T prAdapter) -+{ -+ P_TX_CTRL_T prTxCtrl; -+ PUINT_8 pucMemHandle; -+ P_MSDU_INFO_T prMsduInfo; -+ UINT_32 i; -+ -+ KAL_SPIN_LOCK_DECLARATION(); -+ -+ DEBUGFUNC("nicTxInitialize"); -+ -+ ASSERT(prAdapter); -+ prTxCtrl = &prAdapter->rTxCtrl; -+ -+ /* 4 <1> Initialization of Traffic Class Queue Parameters */ -+ nicTxResetResource(prAdapter); -+ -+#if CFG_SDIO_TX_AGG -+ prTxCtrl->pucTxCoalescingBufPtr = prAdapter->pucCoalescingBufCached; -+#endif /* CFG_SDIO_TX_AGG */ -+ -+ /* allocate MSDU_INFO_T and link it into rFreeMsduInfoList */ -+ QUEUE_INITIALIZE(&prTxCtrl->rFreeMsduInfoList); -+ -+ pucMemHandle = prTxCtrl->pucTxCached; -+ for (i = 0; i < CFG_TX_MAX_PKT_NUM; i++) { -+ prMsduInfo = (P_MSDU_INFO_T) pucMemHandle; -+ kalMemZero(prMsduInfo, sizeof(MSDU_INFO_T)); -+ -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_MSDU_INFO_LIST); -+ QUEUE_INSERT_TAIL(&prTxCtrl->rFreeMsduInfoList, (P_QUE_ENTRY_T) prMsduInfo); -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_MSDU_INFO_LIST); -+ -+ pucMemHandle += ALIGN_4(sizeof(MSDU_INFO_T)); -+ } -+ -+ ASSERT(prTxCtrl->rFreeMsduInfoList.u4NumElem == CFG_TX_MAX_PKT_NUM); -+ /* Check if the memory allocation consist with this initialization function */ -+ ASSERT((UINT_32) (pucMemHandle - prTxCtrl->pucTxCached) == prTxCtrl->u4TxCachedSize); -+ -+ QUEUE_INITIALIZE(&prTxCtrl->rTxMgmtTxingQueue); -+ prTxCtrl->i4TxMgmtPendingNum = 0; -+ -+#if CFG_HIF_STATISTICS -+ prTxCtrl->u4TotalTxAccessNum = 0; -+ prTxCtrl->u4TotalTxPacketNum = 0; -+#endif -+ -+ prTxCtrl->i4PendingFwdFrameCount = 0; -+ -+ qmInit(prAdapter); -+ -+ TX_RESET_ALL_CNTS(prTxCtrl); -+ -+} /* end of nicTxInitialize() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Driver maintain a variable that is synchronous with the usage of individual -+* TC Buffer Count. This function will check if has enough TC Buffer for incoming -+* packet and then update the value after promise to provide the resources. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] ucTC Specify the resource of TC -+* -+* \retval WLAN_STATUS_SUCCESS Resource is available and been assigned. -+* \retval WLAN_STATUS_RESOURCES Resource is not available. -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT_32 u4CurrTick = 0; -+WLAN_STATUS nicTxAcquireResource(IN P_ADAPTER_T prAdapter, IN UINT_8 ucTC, IN BOOLEAN pfgIsSecOrMgmt) -+{ -+#define TC4_NO_RESOURCE_DELAY_MS 5 /* exponential of 5s */ -+ -+ P_TX_CTRL_T prTxCtrl; -+ WLAN_STATUS u4Status = WLAN_STATUS_RESOURCES; -+ P_QUE_MGT_T prQM; -+ -+ KAL_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(prAdapter); -+ prTxCtrl = &prAdapter->rTxCtrl; -+ -+ prQM = &prAdapter->rQM; -+ -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_RESOURCE); -+ -+/* DbgPrint("nicTxAcquireResource prTxCtrl->rTc.aucFreeBufferCount[%d]=%d\n", -+ ucTC, prTxCtrl->rTc.aucFreeBufferCount[ucTC]); */ -+ do { -+ if (pfgIsSecOrMgmt && (ucTC == TC4_INDEX)) { -+ if (prTxCtrl->rTc.aucFreeBufferCount[ucTC] < 2) { -+ DBGLOG(TX, EVENT, " aucFreeBufferCount = %d\n", -+ prTxCtrl->rTc.aucFreeBufferCount[ucTC]); -+ -+ if (prTxCtrl->rTc.aucFreeBufferCount[ucTC]) -+ u4CurrTick = 0; -+ -+ break; -+ } -+ } -+ -+ if (prTxCtrl->rTc.aucFreeBufferCount[ucTC]) { -+ -+ if (ucTC == TC4_INDEX) -+ u4CurrTick = 0; -+ /* get a available TX entry */ -+ prTxCtrl->rTc.aucFreeBufferCount[ucTC]--; -+ -+ prQM->au4ResourceUsedCounter[ucTC]++; -+ -+ DBGLOG(TX, EVENT, "Acquire: TC = %d aucFreeBufferCount = %d\n", -+ ucTC, prTxCtrl->rTc.aucFreeBufferCount[ucTC]); -+ -+ u4Status = WLAN_STATUS_SUCCESS; -+ } -+ } while (FALSE); -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_RESOURCE); -+ -+ if (ucTC == TC4_INDEX) { -+ if (u4CurrTick == 0) -+ u4CurrTick = kalGetTimeTick(); -+ if (CHECK_FOR_TIMEOUT(kalGetTimeTick(), u4CurrTick, -+ SEC_TO_SYSTIME(TC4_NO_RESOURCE_DELAY_MS))) { -+ wlanDumpTcResAndTxedCmd(NULL, 0); -+ cmdBufDumpCmdQueue(&prAdapter->rPendingCmdQueue, "waiting response CMD queue"); -+ glDumpConnSysCpuInfo(prAdapter->prGlueInfo); -+ kalSendAeeWarning("[TC4 no resource delay 5s!]", __func__); -+ glDoChipReset(); -+ u4CurrTick = 0; -+ } -+ } -+ return u4Status; -+ -+} /* end of nicTxAcquireResourceAndTFCBs() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Driver maintain a variable that is synchronous with the usage of individual -+* TC Buffer Count. This function will do polling if FW has return the resource. -+* Used when driver start up before enable interrupt. -+* -+* @param prAdapter Pointer to the Adapter structure. -+* @param ucTC Specify the resource of TC -+* -+* @retval WLAN_STATUS_SUCCESS Resource is available. -+* @retval WLAN_STATUS_FAILURE Resource is not available. -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS nicTxPollingResource(IN P_ADAPTER_T prAdapter, IN UINT_8 ucTC) -+{ -+ P_TX_CTRL_T prTxCtrl; -+ WLAN_STATUS u4Status = WLAN_STATUS_FAILURE; -+ INT_32 i = NIC_TX_RESOURCE_POLLING_TIMEOUT; -+ UINT_32 au4WTSR[2]; -+ -+ ASSERT(prAdapter); -+ prTxCtrl = &prAdapter->rTxCtrl; -+ -+ if (ucTC >= TC_NUM) -+ return WLAN_STATUS_FAILURE; -+ -+ if (prTxCtrl->rTc.aucFreeBufferCount[ucTC] > 0) -+ return WLAN_STATUS_SUCCESS; -+ -+ while (i-- > 0) { -+ HAL_READ_TX_RELEASED_COUNT(prAdapter, au4WTSR); -+ -+ if (kalIsCardRemoved(prAdapter->prGlueInfo) == TRUE || fgIsBusAccessFailed == TRUE) { -+ u4Status = WLAN_STATUS_FAILURE; -+ break; -+ } else if (nicTxReleaseResource(prAdapter, (PUINT_8) au4WTSR)) { -+ if (prTxCtrl->rTc.aucFreeBufferCount[ucTC] > 0) { -+ u4Status = WLAN_STATUS_SUCCESS; -+ break; -+ } -+ kalMsleep(NIC_TX_RESOURCE_POLLING_DELAY_MSEC); -+ -+ } else { -+ kalMsleep(NIC_TX_RESOURCE_POLLING_DELAY_MSEC); -+ } -+ } -+ -+ if (i <= 0 && ucTC == TC4_INDEX) { -+ DBGLOG(TX, ERROR, "polling Tx resource for Tc4 timeout\n"); -+ glDumpConnSysCpuInfo(prAdapter->prGlueInfo); -+ } -+#if DBG -+ { -+ INT_32 i4Times = NIC_TX_RESOURCE_POLLING_TIMEOUT - (i + 1); -+ -+ if (i4Times) { -+ DBGLOG(TX, TRACE, "Polling MCR_WTSR delay %d times, %d msec\n", -+ i4Times, (i4Times * NIC_TX_RESOURCE_POLLING_DELAY_MSEC)); -+ } -+ } -+#endif /* DBG */ -+ -+ return u4Status; -+ -+} /* end of nicTxPollingResource() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Driver maintain a variable that is synchronous with the usage of individual -+* TC Buffer Count. This function will release TC Buffer count according to -+* the given TX_STATUS COUNTER after TX Done. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] u4TxStatusCnt Value of TX STATUS -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN nicTxReleaseResource(IN P_ADAPTER_T prAdapter, IN unsigned char *aucTxRlsCnt) -+{ -+ PUINT_32 pu4Tmp = (PUINT_32) aucTxRlsCnt; -+ P_TX_CTRL_T prTxCtrl; -+ BOOLEAN bStatus = FALSE; -+ UINT_32 i; -+ -+ KAL_SPIN_LOCK_DECLARATION(); -+ -+ P_QUE_MGT_T prQM = &prAdapter->rQM; -+ prTxCtrl = &prAdapter->rTxCtrl; -+ -+ if (pu4Tmp[0] | pu4Tmp[1]) { -+ -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_RESOURCE); -+ for (i = 0; i < TC_NUM; i++) -+ prTxCtrl->rTc.aucFreeBufferCount[i] += aucTxRlsCnt[i]; -+ for (i = 0; i < TC_NUM; i++) -+ prQM->au4QmTcResourceBackCounter[i] += aucTxRlsCnt[i]; -+ if (aucTxRlsCnt[TC4_INDEX] != 0) -+ wlanTraceReleaseTcRes(prAdapter, aucTxRlsCnt, prTxCtrl->rTc.aucFreeBufferCount[TC4_INDEX]); -+ -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_RESOURCE); -+#if 0 -+ for (i = 0; i < TC_NUM; i++) { -+ DBGLOG(TX, TRACE, "aucFreeBufferCount[%d]: %d, aucMaxNumOfBuffer[%d]: %d\n", -+ i, prTxCtrl->rTc.aucFreeBufferCount[i], i, -+ prTxCtrl->rTc.aucMaxNumOfBuffer[i]); -+ } -+ DbgPrint("prTxCtrl->rTc.aucFreeBufferCount[0]=%d\n", prTxCtrl->rTc.aucFreeBufferCount[0]); -+ DbgPrint("prTxCtrl->rTc.aucFreeBufferCount[1]=%d\n", prTxCtrl->rTc.aucFreeBufferCount[1]); -+ DbgPrint("prTxCtrl->rTc.aucFreeBufferCount[2]=%d\n", prTxCtrl->rTc.aucFreeBufferCount[2]); -+ DbgPrint("prTxCtrl->rTc.aucFreeBufferCount[3]=%d\n", prTxCtrl->rTc.aucFreeBufferCount[3]); -+ DbgPrint("prTxCtrl->rTc.aucFreeBufferCount[4]=%d\n", prTxCtrl->rTc.aucFreeBufferCount[4]); -+ DbgPrint("prTxCtrl->rTc.aucFreeBufferCount[5]=%d\n", prTxCtrl->rTc.aucFreeBufferCount[5]); -+#endif -+ ASSERT(prTxCtrl->rTc.aucFreeBufferCount[TC0_INDEX] <= prTxCtrl->rTc.aucMaxNumOfBuffer[TC0_INDEX]); -+ ASSERT(prTxCtrl->rTc.aucFreeBufferCount[TC1_INDEX] <= prTxCtrl->rTc.aucMaxNumOfBuffer[TC1_INDEX]); -+ ASSERT(prTxCtrl->rTc.aucFreeBufferCount[TC2_INDEX] <= prTxCtrl->rTc.aucMaxNumOfBuffer[TC2_INDEX]); -+ ASSERT(prTxCtrl->rTc.aucFreeBufferCount[TC3_INDEX] <= prTxCtrl->rTc.aucMaxNumOfBuffer[TC3_INDEX]); -+ ASSERT(prTxCtrl->rTc.aucFreeBufferCount[TC4_INDEX] <= prTxCtrl->rTc.aucMaxNumOfBuffer[TC4_INDEX]); -+ ASSERT(prTxCtrl->rTc.aucFreeBufferCount[TC5_INDEX] <= prTxCtrl->rTc.aucMaxNumOfBuffer[TC5_INDEX]); -+ bStatus = TRUE; -+ } -+ -+ return bStatus; -+} /* end of nicTxReleaseResource() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Reset TC Buffer Count to initialized value -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* -+* @return WLAN_STATUS_SUCCESS -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS nicTxResetResource(IN P_ADAPTER_T prAdapter) -+{ -+ P_TX_CTRL_T prTxCtrl; -+ -+ KAL_SPIN_LOCK_DECLARATION(); -+ -+ DEBUGFUNC("nicTxResetResource"); -+ -+ ASSERT(prAdapter); -+ prTxCtrl = &prAdapter->rTxCtrl; -+ -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_RESOURCE); -+ -+ prTxCtrl->rTc.aucMaxNumOfBuffer[TC0_INDEX] = NIC_TX_BUFF_COUNT_TC0; -+ prTxCtrl->rTc.aucFreeBufferCount[TC0_INDEX] = NIC_TX_BUFF_COUNT_TC0; -+ -+ prTxCtrl->rTc.aucMaxNumOfBuffer[TC1_INDEX] = NIC_TX_BUFF_COUNT_TC1; -+ prTxCtrl->rTc.aucFreeBufferCount[TC1_INDEX] = NIC_TX_BUFF_COUNT_TC1; -+ -+ prTxCtrl->rTc.aucMaxNumOfBuffer[TC2_INDEX] = NIC_TX_BUFF_COUNT_TC2; -+ prTxCtrl->rTc.aucFreeBufferCount[TC2_INDEX] = NIC_TX_BUFF_COUNT_TC2; -+ -+ prTxCtrl->rTc.aucMaxNumOfBuffer[TC3_INDEX] = NIC_TX_BUFF_COUNT_TC3; -+ prTxCtrl->rTc.aucFreeBufferCount[TC3_INDEX] = NIC_TX_BUFF_COUNT_TC3; -+ -+ prTxCtrl->rTc.aucMaxNumOfBuffer[TC4_INDEX] = NIC_TX_BUFF_COUNT_TC4; -+ prTxCtrl->rTc.aucFreeBufferCount[TC4_INDEX] = NIC_TX_BUFF_COUNT_TC4; -+ -+ prTxCtrl->rTc.aucMaxNumOfBuffer[TC5_INDEX] = NIC_TX_BUFF_COUNT_TC5; -+ prTxCtrl->rTc.aucFreeBufferCount[TC5_INDEX] = NIC_TX_BUFF_COUNT_TC5; -+ -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_RESOURCE); -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Driver maintain a variable that is synchronous with the usage of individual -+* TC Buffer Count. This function will return the value for other component -+* which needs this information for making decisions -+* -+* @param prAdapter Pointer to the Adapter structure. -+* @param ucTC Specify the resource of TC -+* -+* @retval UINT_8 The number of corresponding TC number -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT_8 nicTxGetResource(IN P_ADAPTER_T prAdapter, IN UINT_8 ucTC) -+{ -+ P_TX_CTRL_T prTxCtrl; -+ -+ ASSERT(prAdapter); -+ prTxCtrl = &prAdapter->rTxCtrl; -+ -+ ASSERT(prTxCtrl); -+ -+ if (ucTC >= TC_NUM) -+ return 0; -+ else -+ return prTxCtrl->rTc.aucFreeBufferCount[ucTC]; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief In this function, we'll aggregate frame(PACKET_INFO_T) -+* corresponding to HIF TX port -+* -+* @param prAdapter Pointer to the Adapter structure. -+* @param prMsduInfoListHead a link list of P_MSDU_INFO_T -+* -+* @retval WLAN_STATUS_SUCCESS Bus access ok. -+* @retval WLAN_STATUS_FAILURE Bus access fail. -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS nicTxMsduInfoList(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfoListHead) -+{ -+ P_MSDU_INFO_T prMsduInfo, prNextMsduInfo; -+ QUE_T qDataPort0, qDataPort1; -+ WLAN_STATUS status; -+ BOOLEAN pfgIsSecOrMgmt = FALSE; -+ -+ ASSERT(prAdapter); -+ ASSERT(prMsduInfoListHead); -+ -+ prMsduInfo = prMsduInfoListHead; -+ -+ QUEUE_INITIALIZE(&qDataPort0); -+ QUEUE_INITIALIZE(&qDataPort1); -+ -+ /* Separate MSDU_INFO_T lists into 2 categories: for Port#0 & Port#1 */ -+ while (prMsduInfo) { -+ prNextMsduInfo = (P_MSDU_INFO_T) QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T) prMsduInfo); -+#if DBG && 0 -+ LOG_FUNC("nicTxMsduInfoList Acquire TC %d net %u mac len %u len %u Type %u 1x %u 11 %u\n", -+ prMsduInfo->ucTC, -+ prMsduInfo->ucNetworkType, -+ prMsduInfo->ucMacHeaderLength, -+ prMsduInfo->u2FrameLength, -+ prMsduInfo->ucPacketType, prMsduInfo->fgIs802_1x, prMsduInfo->fgIs802_11); -+ -+ LOG_FUNC("Dest Mac: %pM\n", prMsduInfo->aucEthDestAddr); -+#endif -+ -+ /* double-check available TX resouce (need to sync with CONNSYS FW) */ -+ /* caller must guarantee that the TX resource is enough in the func; OR assert here */ -+ switch (prMsduInfo->ucTC) { -+ case TC0_INDEX: -+ case TC1_INDEX: -+ case TC2_INDEX: -+ case TC3_INDEX: -+ case TC5_INDEX: /* Broadcast/multicast data packets */ -+ QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T) prMsduInfo) = NULL; -+ QUEUE_INSERT_TAIL(&qDataPort0, (P_QUE_ENTRY_T) prMsduInfo); -+ status = nicTxAcquireResource(prAdapter, prMsduInfo->ucTC, FALSE); -+ ASSERT(status == WLAN_STATUS_SUCCESS) -+ -+ break; -+ -+ case TC4_INDEX: /* Command or 802.1x packets */ -+ QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T) prMsduInfo) = NULL; -+ QUEUE_INSERT_TAIL(&qDataPort1, (P_QUE_ENTRY_T) prMsduInfo); -+ -+ if ((prMsduInfo->fgIs802_1x == TRUE) || -+ (prMsduInfo->fgIs802_11 == TRUE)) -+ pfgIsSecOrMgmt = TRUE; -+ -+ status = nicTxAcquireResource(prAdapter, prMsduInfo->ucTC, pfgIsSecOrMgmt); -+ ASSERT(status == WLAN_STATUS_SUCCESS) -+ -+ break; -+ -+ default: -+ ASSERT(0); -+ break; -+ } -+ -+ prMsduInfo = prNextMsduInfo; -+ } -+ -+ /* send packets to HIF port0 or port1 here */ -+ if (qDataPort0.u4NumElem > 0) -+ nicTxMsduQueue(prAdapter, 0, &qDataPort0); -+ -+ if (qDataPort1.u4NumElem > 0) -+ nicTxMsduQueue(prAdapter, 1, &qDataPort1); -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+#if CFG_ENABLE_PKT_LIFETIME_PROFILE -+ -+#if CFG_PRINT_RTP_PROFILE -+PKT_PROFILE_T rPrevRoundLastPkt; -+ -+BOOLEAN -+nicTxLifetimePrintCheckRTP(IN P_MSDU_INFO_T prPrevProfileMsduInfo, -+ IN P_PKT_PROFILE_T prPrevRoundLastPkt, -+ IN P_PKT_PROFILE_T prPktProfile, -+ IN OUT PBOOLEAN pfgGotFirst, IN UINT_32 u4MaxDeltaTime, IN UINT_8 ucSnToBePrinted) -+{ -+ BOOLEAN fgPrintCurPkt = FALSE; -+ -+ if (u4MaxDeltaTime) { -+ /* 4 1. check delta between current round first pkt and prevous round last pkt */ -+ if (!*pfgGotFirst) { -+ *pfgGotFirst = TRUE; -+ -+ if (prPrevRoundLastPkt->fgIsValid) { -+ if (CHK_PROFILES_DELTA(prPktProfile, prPrevRoundLastPkt, u4MaxDeltaTime)) { -+ PRINT_PKT_PROFILE(prPrevRoundLastPkt, "PR"); -+ fgPrintCurPkt = TRUE; -+ } -+ } -+ } -+ /* 4 2. check delta between current pkt and previous pkt */ -+ if (prPrevProfileMsduInfo) { -+ if (CHK_PROFILES_DELTA(prPktProfile, &prPrevProfileMsduInfo->rPktProfile, u4MaxDeltaTime)) { -+ PRINT_PKT_PROFILE(&prPrevProfileMsduInfo->rPktProfile, "P"); -+ fgPrintCurPkt = TRUE; -+ } -+ } -+ /* 4 3. check delta of current pkt lifetime */ -+ if (CHK_PROFILE_DELTA(prPktProfile, u4MaxDeltaTime)) -+ fgPrintCurPkt = TRUE; -+ } -+ /* 4 4. print every X RTP packets */ -+#if CFG_SUPPORT_WFD -+ if ((ucSnToBePrinted != 0) && (prPktProfile->u2RtpSn % ucSnToBePrinted) == 0) -+ fgPrintCurPkt = TRUE; -+#endif -+ -+ return fgPrintCurPkt; -+} -+ -+BOOLEAN -+nicTxLifetimePrintCheckSnOrder(IN P_MSDU_INFO_T prPrevProfileMsduInfo, -+ IN P_PKT_PROFILE_T prPrevRoundLastPkt, -+ IN P_PKT_PROFILE_T prPktProfile, IN OUT PBOOLEAN pfgGotFirst, IN UINT_8 ucLayer) -+{ -+ BOOLEAN fgPrintCurPkt = FALSE; -+ P_PKT_PROFILE_T prTarPktProfile = NULL; -+ UINT_16 u2PredictSn = 0; -+ UINT_16 u2CurrentSn = 0; -+ UINT_8 aucNote[8]; -+ -+ /* 4 1. Get the target packet profile to compare */ -+ -+ /* 4 1.1 check SN between current round first pkt and prevous round last pkt */ -+ if ((!*pfgGotFirst) && (prPrevRoundLastPkt->fgIsValid)) { -+ *pfgGotFirst = TRUE; -+ prTarPktProfile = prPrevRoundLastPkt; -+ kalMemCopy(aucNote, "PR\0", 3); -+ } -+ /* 4 1.2 check SN between current pkt and previous pkt */ -+ else if (prPrevProfileMsduInfo) { -+ prTarPktProfile = &prPrevProfileMsduInfo->rPktProfile; -+ kalMemCopy(aucNote, "P\0", 2); -+ } -+ -+ if (!prTarPktProfile) -+ return FALSE; -+ /* 4 2. Check IP or RTP SN */ -+ switch (ucLayer) { -+ /* Check IP SN */ -+ case 0: -+ u2PredictSn = prTarPktProfile->u2IpSn + 1; -+ u2CurrentSn = prPktProfile->u2IpSn; -+ break; -+ /* Check RTP SN */ -+ case 1: -+ default: -+ u2PredictSn = prTarPktProfile->u2RtpSn + 1; -+ u2CurrentSn = prPktProfile->u2RtpSn; -+ break; -+ -+ } -+ /* 4 */ -+ /* 4 3. Compare SN */ -+ if (u2CurrentSn != u2PredictSn) { -+ PRINT_PKT_PROFILE(prTarPktProfile, aucNote); -+ fgPrintCurPkt = TRUE; -+ } -+ -+ return fgPrintCurPkt; -+} -+#endif -+ -+VOID nicTxReturnMsduInfoProfiling(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfoListHead) -+{ -+ P_MSDU_INFO_T prMsduInfo = prMsduInfoListHead, prNextMsduInfo; -+ P_PKT_PROFILE_T prPktProfile; -+ UINT_16 u2MagicCode = 0; -+ -+ UINT_8 ucDebugtMode = 0; -+#if CFG_PRINT_RTP_PROFILE -+ P_MSDU_INFO_T prPrevProfileMsduInfo = NULL; -+ P_PKT_PROFILE_T prPrevRoundLastPkt = &rPrevRoundLastPkt; -+ -+ BOOLEAN fgPrintCurPkt = FALSE; -+ BOOLEAN fgGotFirst = FALSE; -+ UINT_8 ucSnToBePrinted = 0; -+ -+ UINT_32 u4MaxDeltaTime = 50; /* in ms */ -+#endif -+ -+#if CFG_ENABLE_PER_STA_STATISTICS -+ UINT_32 u4PktPrintPeriod = 0; -+#endif -+ -+#if CFG_SUPPORT_WFD -+ P_WFD_CFG_SETTINGS_T prWfdCfgSettings = (P_WFD_CFG_SETTINGS_T) NULL; -+ -+ if (prAdapter->fgIsP2PRegistered) { -+ prWfdCfgSettings = &prAdapter->rWifiVar.prP2pFsmInfo->rWfdConfigureSettings; -+ u2MagicCode = prWfdCfgSettings->u2WfdMaximumTp; -+ ucDebugtMode = prAdapter->rWifiVar.prP2pFsmInfo->rWfdDebugSetting.ucWfdDebugMode; -+ /* if(prWfdCfgSettings->ucWfdEnable && (prWfdCfgSettings->u4WfdFlag & BIT(0))) { */ -+ /* u2MagicCode = 0xE040; */ -+ /* } */ -+ } -+#endif -+ -+#if CFG_PRINT_RTP_PROFILE -+ if ((u2MagicCode >= 0xF000)) { -+ ucSnToBePrinted = (UINT_8) (u2MagicCode & BITS(0, 7)); -+ u4MaxDeltaTime = (UINT_8) (((u2MagicCode & BITS(8, 11)) >> 8) * 10); -+ } else { -+ ucSnToBePrinted = 0; -+ u4MaxDeltaTime = 0; -+ } -+ -+#endif -+ -+#if CFG_ENABLE_PER_STA_STATISTICS -+ if ((u2MagicCode >= 0xE000) && (u2MagicCode < 0xF000)) -+ u4PktPrintPeriod = (UINT_32) ((u2MagicCode & BITS(0, 7)) * 32); -+ else -+ u4PktPrintPeriod = 0; -+#endif -+ -+ while (prMsduInfo) { -+ prNextMsduInfo = (P_MSDU_INFO_T) QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T) prMsduInfo); -+ prPktProfile = &prMsduInfo->rPktProfile; -+ -+ if (prPktProfile->fgIsValid) { -+ -+ prPktProfile->rHifTxDoneTimestamp = kalGetTimeTick(); -+ if (ucDebugtMode > 1) { -+ -+#if CFG_PRINT_RTP_PROFILE -+#if CFG_PRINT_RTP_SN_SKIP -+ fgPrintCurPkt = nicTxLifetimePrintCheckSnOrder(prPrevProfileMsduInfo, -+ prPrevRoundLastPkt, -+ prPktProfile, &fgGotFirst, 0); -+#else -+ fgPrintCurPkt = nicTxLifetimePrintCheckRTP(prPrevProfileMsduInfo, -+ prPrevRoundLastPkt, -+ prPktProfile, -+ &fgGotFirst, -+ u4MaxDeltaTime, ucSnToBePrinted); -+#endif -+ -+ /* Print current pkt profile */ -+ if (fgPrintCurPkt && ucDebugtMode > 1) -+ PRINT_PKT_PROFILE(prPktProfile, "C"); -+ -+ prPrevProfileMsduInfo = prMsduInfo; -+ fgPrintCurPkt = FALSE; -+#endif -+ } -+#if CFG_ENABLE_PER_STA_STATISTICS -+ { -+ P_STA_RECORD_T prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); -+ UINT_32 u4DeltaTime; -+ UINT_32 u4DeltaHifTime; -+#if 0 -+ P_QUE_MGT_T prQM = &prAdapter->rQM; -+#endif -+ UINT_8 ucNetIndex; -+ -+ if (prStaRec) { -+ ucNetIndex = prStaRec->ucNetTypeIndex; -+ u4DeltaTime = (UINT_32) (prPktProfile->rHifTxDoneTimestamp - -+ prPktProfile->rHardXmitArrivalTimestamp); -+ u4DeltaHifTime = (UINT_32) (prPktProfile->rHifTxDoneTimestamp - -+ prPktProfile->rDequeueTimestamp); -+ prStaRec->u4TotalTxPktsNumber++; -+ -+ prStaRec->u4TotalTxPktsTime += u4DeltaTime; -+ prStaRec->u4TotalTxPktsHifTime += u4DeltaHifTime; -+ -+ if (u4DeltaTime > prStaRec->u4MaxTxPktsTime) -+ prStaRec->u4MaxTxPktsTime = u4DeltaTime; -+ -+ if (u4DeltaHifTime > prStaRec->u4MaxTxPktsHifTime) -+ prStaRec->u4MaxTxPktsHifTime = u4DeltaHifTime; -+ -+ -+ if (u4DeltaTime >= NIC_TX_TIME_THRESHOLD) -+ prStaRec->u4ThresholdCounter++; -+#if 0 -+ if (u4PktPrintPeriod && (prStaRec->u4TotalTxPktsNumber >= u4PktPrintPeriod)) { -+ -+ DBGLOG(TX, TRACE, "[%u]N[%4u]A[%5u]M[%4u]T[%4u]E[%4u]\n", -+ prStaRec->ucIndex, -+ prStaRec->u4TotalTxPktsNumber, -+ prStaRec->u4TotalTxPktsTime / prStaRec->u4TotalTxPktsNumber, -+ prStaRec->u4MaxTxPktsTime, -+ prStaRec->u4ThresholdCounter, -+ prQM->au4QmTcResourceEmptyCounter[ucNetIndex][TC2_INDEX]); -+ -+ prStaRec->u4TotalTxPktsNumber = 0; -+ prStaRec->u4TotalTxPktsTime = 0; -+ prStaRec->u4MaxTxPktsTime = 0; -+ prStaRec->u4ThresholdCounter = 0; -+ prQM->au4QmTcResourceEmptyCounter[ucNetIndex][TC2_INDEX] = 0; -+ } -+#endif -+ } -+ -+ } -+#endif -+ } -+ -+ prMsduInfo = prNextMsduInfo; -+ }; -+ -+#if CFG_PRINT_RTP_PROFILE -+ /* 4 4. record the lifetime of current round last pkt */ -+ if (prPrevProfileMsduInfo) { -+ prPktProfile = &prPrevProfileMsduInfo->rPktProfile; -+ prPrevRoundLastPkt->u2IpSn = prPktProfile->u2IpSn; -+ prPrevRoundLastPkt->u2RtpSn = prPktProfile->u2RtpSn; -+ prPrevRoundLastPkt->rHardXmitArrivalTimestamp = prPktProfile->rHardXmitArrivalTimestamp; -+ prPrevRoundLastPkt->rEnqueueTimestamp = prPktProfile->rEnqueueTimestamp; -+ prPrevRoundLastPkt->rDequeueTimestamp = prPktProfile->rDequeueTimestamp; -+ prPrevRoundLastPkt->rHifTxDoneTimestamp = prPktProfile->rHifTxDoneTimestamp; -+ prPrevRoundLastPkt->ucTcxFreeCount = prPktProfile->ucTcxFreeCount; -+ prPrevRoundLastPkt->fgIsPrinted = prPktProfile->fgIsPrinted; -+ prPrevRoundLastPkt->fgIsValid = TRUE; -+ } -+#endif -+ -+ nicTxReturnMsduInfo(prAdapter, prMsduInfoListHead); -+ -+} -+ -+VOID nicTxLifetimeRecordEn(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo, IN P_NATIVE_PACKET prPacket) -+{ -+ P_PKT_PROFILE_T prPktProfile = &prMsduInfo->rPktProfile; -+ -+ /* Enable packet lifetime profiling */ -+ prPktProfile->fgIsValid = TRUE; -+ -+ /* Packet arrival time at kernel Hard Xmit */ -+ prPktProfile->rHardXmitArrivalTimestamp = GLUE_GET_PKT_ARRIVAL_TIME(prPacket); -+ -+ /* Packet enqueue time */ -+ prPktProfile->rEnqueueTimestamp = (OS_SYSTIME) kalGetTimeTick(); -+ -+} -+ -+#if CFG_PRINT_RTP_PROFILE -+/* -+ in: -+ data RTP packet pointer -+ size RTP size -+ return -+ 0:audio 1: video, -1:none -+*/ -+UINT8 checkRtpAV(PUINT_8 data, UINT_32 size) -+{ -+ PUINT_8 buf = data + 12; -+ -+ while (buf + 188 <= data + size) { -+ int pid = ((buf[1] << 8) & 0x1F00) | (buf[2] & 0xFF); -+ -+ if (pid == 0 || pid == 0x100 || pid == 0x1000) -+ buf += 188; -+ else if (pid == 0x1100) -+ return 0; -+ else if (pid == 0x1011) -+ return 1; -+ } -+ return -1; -+} -+ -+VOID -+nicTxLifetimeCheckRTP(IN P_ADAPTER_T prAdapter, -+ IN P_MSDU_INFO_T prMsduInfo, -+ IN P_NATIVE_PACKET prPacket, IN UINT_32 u4PacketLen, IN UINT_8 ucNetworkType) -+{ -+ struct sk_buff *prSkb = (struct sk_buff *)prPacket; -+ UINT_16 u2EtherTypeLen; -+ PUINT_8 aucLookAheadBuf = NULL; -+ P_PKT_PROFILE_T prPktProfile = &prMsduInfo->rPktProfile; -+ -+ /* UINT_8 ucRtpHdrOffset = 28; */ -+ UINT_8 ucRtpSnOffset = 30; -+ /* UINT_32 u4RtpSrcPort = 15550; */ -+ P_TX_CTRL_T prTxCtrl; -+#if CFG_SUPPORT_WFD -+ P_WFD_CFG_SETTINGS_T prWfdCfgSettings = (P_WFD_CFG_SETTINGS_T) NULL; -+ P_WFD_DBG_CFG_SETTINGS_T prWfdDbgSettings = (P_WFD_DBG_CFG_SETTINGS_T) NULL; -+ -+ BOOLEAN fgEnProfiling = FALSE; -+ -+ if (prAdapter->fgIsP2PRegistered) { -+ prWfdCfgSettings = &prAdapter->rWifiVar.prP2pFsmInfo->rWfdConfigureSettings; -+ prWfdDbgSettings = &prAdapter->rWifiVar.prP2pFsmInfo->rWfdDebugSetting; -+#if CFG_PRINT_RTP_SN_SKIP -+ if (ucNetworkType == NETWORK_TYPE_P2P_INDEX) { -+ fgEnProfiling = TRUE; -+ } else -+#endif -+ if (((prWfdCfgSettings->u2WfdMaximumTp >= 0xF000) || -+ (prWfdDbgSettings->ucWfdDebugMode > 0)) && (ucNetworkType == NETWORK_TYPE_P2P_INDEX)) { -+ fgEnProfiling = TRUE; -+ } -+ } -+ -+ if (fgEnProfiling == FALSE) { -+ /* prPktProfile->fgIsValid = FALSE; */ -+ return; -+ } -+#endif -+ -+ prTxCtrl = &prAdapter->rTxCtrl; -+ /* prPktProfile->fgIsValid = FALSE; */ -+ -+ aucLookAheadBuf = prSkb->data; -+ -+ u2EtherTypeLen = (aucLookAheadBuf[ETH_TYPE_LEN_OFFSET] << 8) | (aucLookAheadBuf[ETH_TYPE_LEN_OFFSET + 1]); -+ -+ if ((u2EtherTypeLen == ETH_P_IP) && (u4PacketLen >= LOOK_AHEAD_LEN)) { -+ PUINT_8 pucIpHdr = &aucLookAheadBuf[ETH_HLEN]; -+ UINT_16 u2tmpIpSN = 0; -+ UINT_8 ucIpVersion; -+ -+ ucIpVersion = (pucIpHdr[0] & IPVH_VERSION_MASK) >> IPVH_VERSION_OFFSET; -+ if (ucIpVersion == IPVERSION) { -+ if (pucIpHdr[IPV4_HDR_IP_PROTOCOL_OFFSET] == IP_PROTOCOL_UDP) { -+ -+ /* if(checkRtpAV(&pucIpHdr[ucRtpHdrOffset], -+ (u4PacketLen - ETH_HLEN - ucRtpHdrOffset)) == 0) { */ -+ -+ if (prPktProfile->fgIsValid == FALSE) -+ nicTxLifetimeRecordEn(prAdapter, prMsduInfo, prPacket); -+ -+ prPktProfile->fgIsPrinted = FALSE; -+ -+ prPktProfile->ucTcxFreeCount = prTxCtrl->rTc.aucFreeBufferCount[TC2_INDEX]; -+ -+ /* RTP SN */ -+ prPktProfile->u2RtpSn = pucIpHdr[ucRtpSnOffset] << 8 | pucIpHdr[ucRtpSnOffset + 1]; -+ -+ /* IP SN */ -+ prPktProfile->u2IpSn = pucIpHdr[IPV4_HDR_IP_IDENTIFICATION_OFFSET] << 8 | -+ pucIpHdr[IPV4_HDR_IP_IDENTIFICATION_OFFSET + 1]; -+ u2tmpIpSN = prPktProfile->u2IpSn; -+ if (prWfdDbgSettings->ucWfdDebugMode == 1) { -+ if ((u2tmpIpSN & (prWfdDbgSettings->u2WfdSNShowPeiroid)) == 0) -+ DBGLOG(TX, TRACE, -+ "RtpSn=%d IPId=%d j=%lu\n", prPktProfile->u2RtpSn, -+ prPktProfile->u2IpSn, jiffies); -+ } -+ /* } */ -+ } -+ } -+ } -+ -+} -+#endif -+#if CFG_ENABLE_PER_STA_STATISTICS -+VOID -+nicTxLifetimeCheckByAC(IN P_ADAPTER_T prAdapter, -+ IN P_MSDU_INFO_T prMsduInfo, IN P_NATIVE_PACKET prPacket, IN UINT_8 ucPriorityParam) -+{ -+ switch (ucPriorityParam) { -+ /* BK */ -+ /* case 1: */ -+ /* case 2: */ -+ -+ /* BE */ -+ /* case 0: */ -+ /* case 3: */ -+ -+ /* VI */ -+ case 4: -+ case 5: -+ -+ /* VO */ -+ case 6: -+ case 7: -+ nicTxLifetimeRecordEn(prAdapter, prMsduInfo, prPacket); -+ break; -+ default: -+ break; -+ } -+} -+ -+#endif -+ -+VOID -+nicTxLifetimeCheck(IN P_ADAPTER_T prAdapter, -+ IN P_MSDU_INFO_T prMsduInfo, -+ IN P_NATIVE_PACKET prPacket, -+ IN UINT_8 ucPriorityParam, IN UINT_32 u4PacketLen, IN UINT_8 ucNetworkType) -+{ -+ P_PKT_PROFILE_T prPktProfile = &prMsduInfo->rPktProfile; -+ -+ /* Reset packet profile */ -+ prPktProfile->fgIsValid = FALSE; -+ -+#if CFG_ENABLE_PER_STA_STATISTICS -+ nicTxLifetimeCheckByAC(prAdapter, prMsduInfo, prPacket, ucPriorityParam); -+#endif -+ -+#if CFG_PRINT_RTP_PROFILE -+ nicTxLifetimeCheckRTP(prAdapter, prMsduInfo, prPacket, u4PacketLen, ucNetworkType); -+#endif -+ -+} -+ -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief In this function, we'll write frame(PACKET_INFO_T) into HIF. -+* -+* @param prAdapter Pointer to the Adapter structure. -+* @param ucPortIdx Port Number -+* @param prQue a link list of P_MSDU_INFO_T -+* -+* @retval WLAN_STATUS_SUCCESS Bus access ok. -+* @retval WLAN_STATUS_FAILURE Bus access fail. -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS nicTxMsduQueue(IN P_ADAPTER_T prAdapter, UINT_8 ucPortIdx, P_QUE_T prQue) -+{ -+ P_MSDU_INFO_T prMsduInfo, prNextMsduInfo; -+ HIF_TX_HEADER_T rHwTxHeader; -+ P_NATIVE_PACKET prNativePacket; -+ UINT_16 u2OverallBufferLength; -+ UINT_8 ucEtherTypeOffsetInWord; -+ PUINT_8 pucOutputBuf = (PUINT_8) NULL; /* Pointer to Transmit Data Structure Frame */ -+ UINT_32 u4TxHdrSize; -+ UINT_32 u4ValidBufSize; -+ UINT_32 u4TotalLength; -+ P_TX_CTRL_T prTxCtrl; -+ QUE_T rFreeQueue; -+#if CFG_TCP_IP_CHKSUM_OFFLOAD -+ UINT_8 ucChksumFlag; -+#endif -+ -+ ASSERT(prAdapter); -+ ASSERT(ucPortIdx < 2); -+ ASSERT(prQue); -+ -+ prTxCtrl = &prAdapter->rTxCtrl; -+ u4ValidBufSize = prAdapter->u4CoalescingBufCachedSize; -+ -+#if CFG_HIF_STATISTICS -+ prTxCtrl->u4TotalTxAccessNum++; -+ prTxCtrl->u4TotalTxPacketNum += prQue->u4NumElem; -+#endif -+ -+ QUEUE_INITIALIZE(&rFreeQueue); -+ -+ if (prQue->u4NumElem > 0) { -+ prMsduInfo = (P_MSDU_INFO_T) QUEUE_GET_HEAD(prQue); -+ pucOutputBuf = prTxCtrl->pucTxCoalescingBufPtr; -+ u4TotalLength = 0; -+ -+ while (prMsduInfo) { -+ -+#if (CFG_SUPPORT_TDLS_DBG == 1) -+ { -+ struct sk_buff *prSkb = (struct sk_buff *)prMsduInfo->prPacket; -+ UINT8 *pkt = prSkb->data; -+ UINT16 u2Identifier; -+ -+ if ((*(pkt + 12) == 0x08) && (*(pkt + 13) == 0x00)) { -+ /* ip */ -+ u2Identifier = ((*(pkt + 18)) << 8) | (*(pkt + 19)); -+ DBGLOG(TX, TRACE, " %d\n", u2Identifier); -+ } -+ } -+#endif -+#if (CFG_SUPPORT_MET_PROFILING == 1) -+ kalMetProfilingFinish(prAdapter, prMsduInfo); -+#endif -+ kalMemZero(&rHwTxHeader, sizeof(rHwTxHeader)); -+ -+ prNativePacket = prMsduInfo->prPacket; -+ -+ ASSERT(prNativePacket); -+ -+ u4TxHdrSize = TX_HDR_SIZE; -+ -+ u2OverallBufferLength = ((prMsduInfo->u2FrameLength + TX_HDR_SIZE) & -+ (UINT_16) HIF_TX_HDR_TX_BYTE_COUNT_MASK); -+ -+ /* init TX header */ -+ rHwTxHeader.u2TxByteCount_UserPriority = u2OverallBufferLength; -+ rHwTxHeader.u2TxByteCount_UserPriority |= -+ ((UINT_16) prMsduInfo->ucUserPriority << HIF_TX_HDR_USER_PRIORITY_OFFSET); -+ -+ if (prMsduInfo->fgIs802_11) { -+ ucEtherTypeOffsetInWord = -+ (TX_HDR_SIZE + prMsduInfo->ucMacHeaderLength + prMsduInfo->ucLlcLength) >> 1; -+ } else { -+ ucEtherTypeOffsetInWord = ((ETHER_HEADER_LEN - ETHER_TYPE_LEN) + TX_HDR_SIZE) >> 1; -+ } -+ -+ rHwTxHeader.ucEtherTypeOffset = ucEtherTypeOffsetInWord & HIF_TX_HDR_ETHER_TYPE_OFFSET_MASK; -+ -+ rHwTxHeader.ucResource_PktType_CSflags = (prMsduInfo->ucTC) << HIF_TX_HDR_RESOURCE_OFFSET; -+ rHwTxHeader.ucResource_PktType_CSflags |= -+ (UINT_8) (((prMsduInfo->ucPacketType) << HIF_TX_HDR_PACKET_TYPE_OFFSET) & -+ (HIF_TX_HDR_PACKET_TYPE_MASK)); -+ -+#if CFG_TCP_IP_CHKSUM_OFFLOAD -+ if (prMsduInfo->eSrc == TX_PACKET_OS || prMsduInfo->eSrc == TX_PACKET_FORWARDING) { -+ if (prAdapter->u4CSUMFlags & -+ (CSUM_OFFLOAD_EN_TX_TCP | CSUM_OFFLOAD_EN_TX_UDP | CSUM_OFFLOAD_EN_TX_IP)) { -+ kalQueryTxChksumOffloadParam(prNativePacket, &ucChksumFlag); -+ -+ if (ucChksumFlag & TX_CS_IP_GEN) -+ rHwTxHeader.ucResource_PktType_CSflags |= (UINT_8) HIF_TX_HDR_IP_CSUM; -+ -+ if (ucChksumFlag & TX_CS_TCP_UDP_GEN) -+ rHwTxHeader.ucResource_PktType_CSflags |= (UINT_8) HIF_TX_HDR_TCP_CSUM; -+ } -+ } -+#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */ -+ -+ rHwTxHeader.u2LLH = prMsduInfo->u2PalLLH; -+ rHwTxHeader.ucStaRecIdx = prMsduInfo->ucStaRecIndex; -+ rHwTxHeader.ucForwardingType_SessionID_Reserved = -+ (prMsduInfo->ucPsForwardingType) | ((prMsduInfo->ucPsSessionID) << -+ HIF_TX_HDR_PS_SESSION_ID_OFFSET) -+ | ((prMsduInfo->fgIsBurstEnd) ? HIF_TX_HDR_BURST_END_MASK : 0); -+ -+ rHwTxHeader.ucWlanHeaderLength = -+ (prMsduInfo->ucMacHeaderLength & HIF_TX_HDR_WLAN_HEADER_LEN_MASK); -+ rHwTxHeader.ucPktFormtId_Flags = (prMsduInfo->ucFormatID & HIF_TX_HDR_FORMAT_ID_MASK) -+ | ((prMsduInfo->ucNetworkType << HIF_TX_HDR_NETWORK_TYPE_OFFSET) & -+ HIF_TX_HDR_NETWORK_TYPE_MASK) -+ | ((prMsduInfo->fgIs802_1x << HIF_TX_HDR_FLAG_1X_FRAME_OFFSET) & -+ HIF_TX_HDR_FLAG_1X_FRAME_MASK) -+ | ((prMsduInfo->fgIs802_11 << HIF_TX_HDR_FLAG_802_11_FORMAT_OFFSET) & -+ HIF_TX_HDR_FLAG_802_11_FORMAT_MASK); -+ -+ rHwTxHeader.u2SeqNo = prMsduInfo->u2AclSN; -+ -+ if (prMsduInfo->pfTxDoneHandler) { -+ rHwTxHeader.ucPacketSeqNo = prMsduInfo->ucTxSeqNum; -+ rHwTxHeader.ucAck_BIP_BasicRate = HIF_TX_HDR_NEED_ACK; -+ } else { -+ rHwTxHeader.ucPacketSeqNo = 0; -+ rHwTxHeader.ucAck_BIP_BasicRate = 0; -+ } -+ -+ if (prMsduInfo->fgNeedTxDoneStatus == TRUE) -+ rHwTxHeader.ucAck_BIP_BasicRate |= HIF_TX_HDR_NEED_TX_DONE_STATUS; -+ -+ if (prMsduInfo->fgIsBIP) -+ rHwTxHeader.ucAck_BIP_BasicRate |= HIF_TX_HDR_BIP; -+ -+ if (prMsduInfo->fgIsBasicRate) -+ rHwTxHeader.ucAck_BIP_BasicRate |= HIF_TX_HDR_BASIC_RATE; -+#if CFG_ENABLE_PKT_LIFETIME_PROFILE -+ if (prMsduInfo->rPktProfile.fgIsValid) -+ prMsduInfo->rPktProfile.rDequeueTimestamp = kalGetTimeTick(); -+#endif -+ -+ /* record the queue time in driver */ -+ STATS_TX_TIME_TO_HIF(prMsduInfo, &rHwTxHeader); -+ -+#if CFG_SDIO_TX_AGG -+ /* attach to coalescing buffer */ -+ kalMemCopy(pucOutputBuf + u4TotalLength, &rHwTxHeader, u4TxHdrSize); -+ u4TotalLength += u4TxHdrSize; -+ -+ if (prMsduInfo->eSrc == TX_PACKET_OS || prMsduInfo->eSrc == TX_PACKET_FORWARDING) -+ kalCopyFrame(prAdapter->prGlueInfo, prNativePacket, pucOutputBuf + u4TotalLength); -+ else if (prMsduInfo->eSrc == TX_PACKET_MGMT) -+ kalMemCopy(pucOutputBuf + u4TotalLength, prNativePacket, prMsduInfo->u2FrameLength); -+ else -+ ASSERT(0); -+ -+ u4TotalLength += ALIGN_4(prMsduInfo->u2FrameLength); -+ -+#else -+ kalMemCopy(pucOutputBuf, &rHwTxHeader, u4TxHdrSize); -+ -+ /* Copy Frame Body */ -+ if (prMsduInfo->eSrc == TX_PACKET_OS || prMsduInfo->eSrc == TX_PACKET_FORWARDING) -+ kalCopyFrame(prAdapter->prGlueInfo, prNativePacket, pucOutputBuf + u4TxHdrSize); -+ else if (prMsduInfo->eSrc == TX_PACKET_MGMT) -+ kalMemCopy(pucOutputBuf + u4TxHdrSize, prNativePacket, prMsduInfo->u2FrameLength); -+ else -+ ASSERT(0); -+ -+ ASSERT(u2OverallBufferLength <= u4ValidBufSize); -+ -+ HAL_WRITE_TX_PORT(prAdapter, -+ ucPortIdx, -+ (UINT_32) u2OverallBufferLength, (PUINT_8) pucOutputBuf, u4ValidBufSize); -+ -+ /* send immediately */ -+#endif -+ prNextMsduInfo = (P_MSDU_INFO_T) -+ QUEUE_GET_NEXT_ENTRY(&prMsduInfo->rQueEntry); -+ -+ if (prMsduInfo->eSrc == TX_PACKET_MGMT) { -+ GLUE_DEC_REF_CNT(prTxCtrl->i4TxMgmtPendingNum); -+ -+ if (prMsduInfo->pfTxDoneHandler == NULL) { -+ cnmMgtPktFree(prAdapter, prMsduInfo); -+ } else { -+ KAL_SPIN_LOCK_DECLARATION(); -+ DBGLOG(TX, TRACE, "Wait TxSeqNum:%d\n", prMsduInfo->ucTxSeqNum); -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TXING_MGMT_LIST); -+ QUEUE_INSERT_TAIL(&(prTxCtrl->rTxMgmtTxingQueue), (P_QUE_ENTRY_T) prMsduInfo); -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TXING_MGMT_LIST); -+ } -+ } else { -+ /* only free MSDU when it is not a MGMT frame */ -+ QUEUE_INSERT_TAIL(&rFreeQueue, (P_QUE_ENTRY_T) prMsduInfo); -+ -+ if (prMsduInfo->eSrc == TX_PACKET_OS) -+ kalSendComplete(prAdapter->prGlueInfo, prNativePacket, WLAN_STATUS_SUCCESS); -+ else if (prMsduInfo->eSrc == TX_PACKET_FORWARDING) -+ GLUE_DEC_REF_CNT(prTxCtrl->i4PendingFwdFrameCount); -+ } -+ -+ prMsduInfo = prNextMsduInfo; -+ } -+ -+#if CFG_SDIO_TX_AGG -+ ASSERT(u4TotalLength <= u4ValidBufSize); -+ -+#if CFG_DBG_GPIO_PINS -+ { -+ /* Start port write */ -+ mtk_wcn_stp_debug_gpio_assert(IDX_TX_PORT_WRITE, DBG_TIE_LOW); -+ kalUdelay(1); -+ mtk_wcn_stp_debug_gpio_assert(IDX_TX_PORT_WRITE, DBG_TIE_HIGH); -+ } -+#endif -+ -+ /* send coalescing buffer */ -+ HAL_WRITE_TX_PORT(prAdapter, ucPortIdx, u4TotalLength, (PUINT_8) pucOutputBuf, u4ValidBufSize); -+#endif -+ -+#if CFG_ENABLE_PKT_LIFETIME_PROFILE -+#if CFG_SUPPORT_WFD && CFG_PRINT_RTP_PROFILE && !CFG_ENABLE_PER_STA_STATISTICS -+ do { -+ P_WFD_CFG_SETTINGS_T prWfdCfgSettings = (P_WFD_CFG_SETTINGS_T) NULL; -+ -+ prWfdCfgSettings = &prAdapter->rWifiVar.prP2pFsmInfo->rWfdConfigureSettings; -+ -+ if ((prWfdCfgSettings->u2WfdMaximumTp >= 0xF000)) { -+ /* Enable profiling */ -+ nicTxReturnMsduInfoProfiling(prAdapter, (P_MSDU_INFO_T) QUEUE_GET_HEAD(&rFreeQueue)); -+ } else { -+ /* Skip profiling */ -+ nicTxReturnMsduInfo(prAdapter, (P_MSDU_INFO_T) QUEUE_GET_HEAD(&rFreeQueue)); -+ } -+ } while (FALSE); -+#else -+ nicTxReturnMsduInfoProfiling(prAdapter, (P_MSDU_INFO_T) QUEUE_GET_HEAD(&rFreeQueue)); -+#endif -+#else -+ /* return */ -+ nicTxReturnMsduInfo(prAdapter, (P_MSDU_INFO_T) QUEUE_GET_HEAD(&rFreeQueue)); -+#endif -+ } -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief In this function, we'll write Command(CMD_INFO_T) into HIF. -+* -+* @param prAdapter Pointer to the Adapter structure. -+* @param prPacketInfo Pointer of CMD_INFO_T -+* @param ucTC Specify the resource of TC -+* -+* @retval WLAN_STATUS_SUCCESS Bus access ok. -+* @retval WLAN_STATUS_FAILURE Bus access fail. -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS nicTxCmd(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN UINT_8 ucTC) -+{ -+ P_WIFI_CMD_T prWifiCmd; -+ UINT_16 u2OverallBufferLength; -+ PUINT_8 pucOutputBuf = (PUINT_8) NULL; /* Pointer to Transmit Data Structure Frame */ -+ UINT_8 ucPortIdx; -+ HIF_TX_HEADER_T rHwTxHeader; -+ P_NATIVE_PACKET prNativePacket; -+ UINT_8 ucEtherTypeOffsetInWord; -+ P_MSDU_INFO_T prMsduInfo; -+ P_TX_CTRL_T prTxCtrl; -+ -+ KAL_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(prAdapter); -+ ASSERT(prCmdInfo); -+ -+ prTxCtrl = &prAdapter->rTxCtrl; -+ pucOutputBuf = prTxCtrl->pucTxCoalescingBufPtr; -+ -+ /* <1> Assign Data Port */ -+ if (ucTC != TC4_INDEX) { -+ ucPortIdx = 0; -+ } else { -+ /* Broadcast/multicast data frames, 1x frames, command packets, MMPDU */ -+ ucPortIdx = 1; -+ } -+ wlanTraceTxCmd(prCmdInfo); -+ -+ if (prCmdInfo->eCmdType == COMMAND_TYPE_SECURITY_FRAME) { -+ /* <2> Compose HIF_TX_HEADER */ -+ kalMemZero(&rHwTxHeader, sizeof(rHwTxHeader)); -+ -+ prNativePacket = prCmdInfo->prPacket; -+ -+ ASSERT(prNativePacket); -+ -+ u2OverallBufferLength = TFCB_FRAME_PAD_TO_DW((prCmdInfo->u2InfoBufLen + TX_HDR_SIZE) -+ & (UINT_16) HIF_TX_HDR_TX_BYTE_COUNT_MASK); -+ -+ rHwTxHeader.u2TxByteCount_UserPriority = ((prCmdInfo->u2InfoBufLen + TX_HDR_SIZE) -+ & (UINT_16) HIF_TX_HDR_TX_BYTE_COUNT_MASK); -+ ucEtherTypeOffsetInWord = ((ETHER_HEADER_LEN - ETHER_TYPE_LEN) + TX_HDR_SIZE) >> 1; -+ -+ rHwTxHeader.ucEtherTypeOffset = ucEtherTypeOffsetInWord & HIF_TX_HDR_ETHER_TYPE_OFFSET_MASK; -+ -+ rHwTxHeader.ucResource_PktType_CSflags = (ucTC << HIF_TX_HDR_RESOURCE_OFFSET); -+ -+ rHwTxHeader.ucStaRecIdx = prCmdInfo->ucStaRecIndex; -+ rHwTxHeader.ucForwardingType_SessionID_Reserved = HIF_TX_HDR_BURST_END_MASK; -+ -+ rHwTxHeader.ucWlanHeaderLength = (ETH_HLEN & HIF_TX_HDR_WLAN_HEADER_LEN_MASK); -+ rHwTxHeader.ucPktFormtId_Flags = -+ (((UINT_8) (prCmdInfo->eNetworkType) << HIF_TX_HDR_NETWORK_TYPE_OFFSET) & -+ HIF_TX_HDR_NETWORK_TYPE_MASK) -+ | ((1 << HIF_TX_HDR_FLAG_1X_FRAME_OFFSET) & HIF_TX_HDR_FLAG_1X_FRAME_MASK); -+ -+ rHwTxHeader.u2SeqNo = 0; -+ rHwTxHeader.ucPacketSeqNo = 0; -+ rHwTxHeader.ucAck_BIP_BasicRate = HIF_TX_HDR_NEED_TX_DONE_STATUS; -+ rHwTxHeader.ucAck_BIP_BasicRate |= HIF_TX_HDR_BASIC_RATE /* | HIF_TX_HDR_RTS */; -+ -+ /* <2.3> Copy HIF TX HEADER */ -+ kalMemCopy((PVOID)&pucOutputBuf[0], (PVOID)&rHwTxHeader, TX_HDR_SIZE); -+ -+ /* <3> Copy Frame Body Copy */ -+ kalCopyFrame(prAdapter->prGlueInfo, prNativePacket, pucOutputBuf + TX_HDR_SIZE); -+ } else if (prCmdInfo->eCmdType == COMMAND_TYPE_MANAGEMENT_FRAME) { -+ prMsduInfo = (P_MSDU_INFO_T) prCmdInfo->prPacket; -+ -+ ASSERT(prMsduInfo->fgIs802_11 == TRUE); -+ ASSERT(prMsduInfo->eSrc == TX_PACKET_MGMT); -+ -+ /* <2> Compose HIF_TX_HEADER */ -+ kalMemZero(&rHwTxHeader, sizeof(rHwTxHeader)); -+ -+ u2OverallBufferLength = ((prMsduInfo->u2FrameLength + TX_HDR_SIZE) & -+ (UINT_16) HIF_TX_HDR_TX_BYTE_COUNT_MASK); -+ -+ rHwTxHeader.u2TxByteCount_UserPriority = u2OverallBufferLength; -+ rHwTxHeader.u2TxByteCount_UserPriority |= -+ ((UINT_16) prMsduInfo->ucUserPriority << HIF_TX_HDR_USER_PRIORITY_OFFSET); -+ -+ ucEtherTypeOffsetInWord = (TX_HDR_SIZE + prMsduInfo->ucMacHeaderLength + prMsduInfo->ucLlcLength) >> 1; -+ -+ rHwTxHeader.ucEtherTypeOffset = ucEtherTypeOffsetInWord & HIF_TX_HDR_ETHER_TYPE_OFFSET_MASK; -+ -+ rHwTxHeader.ucResource_PktType_CSflags = (prMsduInfo->ucTC) << HIF_TX_HDR_RESOURCE_OFFSET; -+ rHwTxHeader.ucResource_PktType_CSflags |= -+ (UINT_8) (((prMsduInfo->ucPacketType) << HIF_TX_HDR_PACKET_TYPE_OFFSET) & -+ (HIF_TX_HDR_PACKET_TYPE_MASK)); -+ -+ rHwTxHeader.u2LLH = prMsduInfo->u2PalLLH; -+ rHwTxHeader.ucStaRecIdx = prMsduInfo->ucStaRecIndex; -+ rHwTxHeader.ucForwardingType_SessionID_Reserved = -+ (prMsduInfo->ucPsForwardingType) | ((prMsduInfo->ucPsSessionID) << HIF_TX_HDR_PS_SESSION_ID_OFFSET) -+ | ((prMsduInfo->fgIsBurstEnd) ? HIF_TX_HDR_BURST_END_MASK : 0); -+ -+ rHwTxHeader.ucWlanHeaderLength = (prMsduInfo->ucMacHeaderLength & HIF_TX_HDR_WLAN_HEADER_LEN_MASK); -+ rHwTxHeader.ucPktFormtId_Flags = (prMsduInfo->ucFormatID & HIF_TX_HDR_FORMAT_ID_MASK) -+ | ((prMsduInfo->ucNetworkType << HIF_TX_HDR_NETWORK_TYPE_OFFSET) & HIF_TX_HDR_NETWORK_TYPE_MASK) -+ | ((prMsduInfo->fgIs802_1x << HIF_TX_HDR_FLAG_1X_FRAME_OFFSET) & HIF_TX_HDR_FLAG_1X_FRAME_MASK) -+ | ((prMsduInfo->fgIs802_11 << HIF_TX_HDR_FLAG_802_11_FORMAT_OFFSET) & -+ HIF_TX_HDR_FLAG_802_11_FORMAT_MASK); -+ -+ rHwTxHeader.u2SeqNo = prMsduInfo->u2AclSN; -+ -+ if (prMsduInfo->pfTxDoneHandler) { -+ rHwTxHeader.ucPacketSeqNo = prMsduInfo->ucTxSeqNum; -+ rHwTxHeader.ucAck_BIP_BasicRate = HIF_TX_HDR_NEED_ACK; -+ } else { -+ rHwTxHeader.ucPacketSeqNo = 0; -+ rHwTxHeader.ucAck_BIP_BasicRate = 0; -+ } -+ -+ if (prMsduInfo->fgIsBIP) -+ rHwTxHeader.ucAck_BIP_BasicRate |= HIF_TX_HDR_BIP; -+ -+ if (prMsduInfo->fgIsBasicRate) -+ rHwTxHeader.ucAck_BIP_BasicRate |= HIF_TX_HDR_BASIC_RATE; -+ /* <2.3> Copy HIF TX HEADER */ -+ kalMemCopy((PVOID)&pucOutputBuf[0], (PVOID)&rHwTxHeader, TX_HDR_SIZE); -+ -+ /* <3> Copy Frame Body */ -+ kalMemCopy(pucOutputBuf + TX_HDR_SIZE, prMsduInfo->prPacket, prMsduInfo->u2FrameLength); -+ -+ /* <4> Management Frame Post-Processing */ -+ GLUE_DEC_REF_CNT(prTxCtrl->i4TxMgmtPendingNum); -+ -+ if (prMsduInfo->pfTxDoneHandler == NULL) { -+ cnmMgtPktFree(prAdapter, prMsduInfo); -+ } else { -+ -+ DBGLOG(TX, TRACE, "Wait Cmd TxSeqNum:%d\n", prMsduInfo->ucTxSeqNum); -+ -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TXING_MGMT_LIST); -+ QUEUE_INSERT_TAIL(&(prTxCtrl->rTxMgmtTxingQueue), (P_QUE_ENTRY_T) prMsduInfo); -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TXING_MGMT_LIST); -+ } -+ } else { -+ prWifiCmd = (P_WIFI_CMD_T) prCmdInfo->pucInfoBuffer; -+ -+ /* <2> Compose the Header of Transmit Data Structure for CMD Packet */ -+ u2OverallBufferLength = -+ TFCB_FRAME_PAD_TO_DW((prCmdInfo->u2InfoBufLen) & (UINT_16) HIF_TX_HDR_TX_BYTE_COUNT_MASK); -+ -+ prWifiCmd->u2TxByteCount_UserPriority = u2OverallBufferLength; -+ prWifiCmd->ucEtherTypeOffset = 0; -+ prWifiCmd->ucResource_PktType_CSflags = (ucTC << HIF_TX_HDR_RESOURCE_OFFSET) -+ | (UINT_8) ((HIF_TX_PKT_TYPE_CMD << HIF_TX_HDR_PACKET_TYPE_OFFSET) & (HIF_TX_HDR_PACKET_TYPE_MASK)); -+ -+ /* <3> Copy CMD Header to command buffer (by using pucCoalescingBufCached) */ -+ kalMemCopy((PVOID)&pucOutputBuf[0], (PVOID) prCmdInfo->pucInfoBuffer, prCmdInfo->u2InfoBufLen); -+ -+ ASSERT(u2OverallBufferLength <= prAdapter->u4CoalescingBufCachedSize); -+ -+ if ((prCmdInfo->ucCID == CMD_ID_SCAN_REQ) || -+ (prCmdInfo->ucCID == CMD_ID_SCAN_CANCEL) || -+ (prCmdInfo->ucCID == CMD_ID_SCAN_REQ_V2)) -+ DBGLOG(TX, INFO, "ucCmdSeqNum =%d, ucCID =%d\n", prCmdInfo->ucCmdSeqNum, prCmdInfo->ucCID); -+ } -+ -+ /* <4> Write frame to data port */ -+ HAL_WRITE_TX_PORT(prAdapter, -+ ucPortIdx, -+ (UINT_32) u2OverallBufferLength, -+ (PUINT_8) pucOutputBuf, (UINT_32) prAdapter->u4CoalescingBufCachedSize); -+ -+ return WLAN_STATUS_SUCCESS; -+} /* end of nicTxCmd() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will clean up all the pending frames in internal SW Queues -+* by return the pending TX packet to the system. -+* -+* @param prAdapter Pointer to the Adapter structure. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicTxRelease(IN P_ADAPTER_T prAdapter) -+{ -+ P_TX_CTRL_T prTxCtrl; -+ P_MSDU_INFO_T prMsduInfo; -+ -+ KAL_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(prAdapter); -+ -+ prTxCtrl = &prAdapter->rTxCtrl; -+ -+ nicTxFlush(prAdapter); -+ -+ /* free MSDU_INFO_T from rTxMgmtMsduInfoList */ -+ do { -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TXING_MGMT_LIST); -+ QUEUE_REMOVE_HEAD(&prTxCtrl->rTxMgmtTxingQueue, prMsduInfo, P_MSDU_INFO_T); -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TXING_MGMT_LIST); -+ -+ if (prMsduInfo) { -+ /* the packet must be mgmt frame with tx done callback */ -+ ASSERT(prMsduInfo->eSrc == TX_PACKET_MGMT); -+ -+ /* invoke done handler */ -+ prMsduInfo->pfTxDoneHandler(prAdapter, prMsduInfo, TX_RESULT_LIFE_TIMEOUT); -+ -+ cnmMgtPktFree(prAdapter, prMsduInfo); -+ } else { -+ break; -+ } -+ } while (TRUE); -+ -+} /* end of nicTxRelease() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Process the TX Done interrupt and pull in more pending frames in SW -+* Queues for transmission. -+* -+* @param prAdapter Pointer to the Adapter structure. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicProcessTxInterrupt(IN P_ADAPTER_T prAdapter) -+{ -+ P_TX_CTRL_T prTxCtrl; -+#if CFG_SDIO_INTR_ENHANCE -+ P_SDIO_CTRL_T prSDIOCtrl; -+#else -+ UINT_32 au4TxCount[2]; -+#endif /* CFG_SDIO_INTR_ENHANCE */ -+ -+ P_GLUE_INFO_T prGlueInfo = prAdapter->prGlueInfo; -+ -+ prTxCtrl = &prAdapter->rTxCtrl; -+ ASSERT(prTxCtrl); -+ prGlueInfo->IsrTxCnt++; -+ -+ /* Get the TX STATUS */ -+#if CFG_SDIO_INTR_ENHANCE -+ -+ prSDIOCtrl = prAdapter->prSDIOCtrl; -+#if DBG -+ /* dumpMemory8((PUINT_8)prSDIOCtrl, sizeof(SDIO_CTRL_T)); */ -+#endif -+ -+ nicTxReleaseResource(prAdapter, (PUINT_8) &prSDIOCtrl->rTxInfo); -+ kalMemZero(&prSDIOCtrl->rTxInfo, sizeof(prSDIOCtrl->rTxInfo)); -+ -+#else -+ -+ HAL_MCR_RD(prAdapter, MCR_WTSR0, &au4TxCount[0]); -+ HAL_MCR_RD(prAdapter, MCR_WTSR1, &au4TxCount[1]); -+ DBGLOG(EMU, TRACE, "MCR_WTSR0: 0x%x, MCR_WTSR1: 0x%x\n", au4TxCount[0], au4TxCount[1]); -+ -+ nicTxReleaseResource(prAdapter, (PUINT_8) au4TxCount); -+ -+#endif /* CFG_SDIO_INTR_ENHANCE */ -+ -+ nicTxAdjustTcq(prAdapter); -+ -+ /* Indicate Service Thread */ -+ if (kalGetTxPendingCmdCount(prAdapter->prGlueInfo) > 0 || wlanGetTxPendingFrameCount(prAdapter) > 0) -+ kalSetEvent(prAdapter->prGlueInfo); -+ -+} /* end of nicProcessTxInterrupt() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief this function frees packet of P_MSDU_INFO_T linked-list -+* -+* @param prAdapter Pointer to the Adapter structure. -+* @param prMsduInfoList a link list of P_MSDU_INFO_T -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicTxFreeMsduInfoPacket(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfoListHead) -+{ -+ P_NATIVE_PACKET prNativePacket; -+ P_MSDU_INFO_T prMsduInfo = prMsduInfoListHead; -+ P_TX_CTRL_T prTxCtrl; -+ -+ ASSERT(prAdapter); -+ ASSERT(prMsduInfoListHead); -+ -+ prTxCtrl = &prAdapter->rTxCtrl; -+ -+ while (prMsduInfo) { -+ prNativePacket = prMsduInfo->prPacket; -+ -+ if (prMsduInfo->eSrc == TX_PACKET_OS) { -+ kalSendComplete(prAdapter->prGlueInfo, prNativePacket, WLAN_STATUS_FAILURE); -+ } else if (prMsduInfo->eSrc == TX_PACKET_MGMT) { -+ P_MSDU_INFO_T prTempMsduInfo = prMsduInfo; -+ -+ if (prMsduInfo->pfTxDoneHandler) -+ prMsduInfo->pfTxDoneHandler(prAdapter, prMsduInfo, TX_RESULT_DROPPED_IN_DRIVER); -+ prMsduInfo = (P_MSDU_INFO_T) QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T) prMsduInfo); -+ cnmMgtPktFree(prAdapter, prTempMsduInfo); -+ continue; -+ } else if (prMsduInfo->eSrc == TX_PACKET_FORWARDING) { -+ GLUE_DEC_REF_CNT(prTxCtrl->i4PendingFwdFrameCount); -+ } -+ -+ prMsduInfo = (P_MSDU_INFO_T) QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T) prMsduInfo); -+ } -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief this function returns P_MSDU_INFO_T of MsduInfoList to TxCtrl->rfreeMsduInfoList -+* -+* @param prAdapter Pointer to the Adapter structure. -+* @param prMsduInfoList a link list of P_MSDU_INFO_T -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicTxReturnMsduInfo(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfoListHead) -+{ -+ P_TX_CTRL_T prTxCtrl; -+ P_MSDU_INFO_T prMsduInfo = prMsduInfoListHead, prNextMsduInfo; -+ -+ KAL_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(prAdapter); -+ -+ prTxCtrl = &prAdapter->rTxCtrl; -+ ASSERT(prTxCtrl); -+ -+ while (prMsduInfo) { -+ prNextMsduInfo = (P_MSDU_INFO_T) QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T) prMsduInfo); -+ -+ switch (prMsduInfo->eSrc) { -+ case TX_PACKET_FORWARDING: -+ wlanReturnPacket(prAdapter, prMsduInfo->prPacket); -+ break; -+ case TX_PACKET_OS: -+ case TX_PACKET_OS_OID: -+ case TX_PACKET_MGMT: -+ default: -+ break; -+ } -+ -+ /* Reset MSDU_INFO fields */ -+ kalMemZero(prMsduInfo, sizeof(MSDU_INFO_T)); -+ -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_MSDU_INFO_LIST); -+ QUEUE_INSERT_TAIL(&prTxCtrl->rFreeMsduInfoList, (P_QUE_ENTRY_T) prMsduInfo); -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_MSDU_INFO_LIST); -+ prMsduInfo = prNextMsduInfo; -+ }; -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief this function fills packet information to P_MSDU_INFO_T -+* -+* @param prAdapter Pointer to the Adapter structure. -+* @param prMsduInfo P_MSDU_INFO_T -+* @param prPacket P_NATIVE_PACKET -+* -+* @retval TRUE Success to extract information -+* @retval FALSE Fail to extract correct information -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN nicTxFillMsduInfo(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo, IN P_NATIVE_PACKET prPacket) -+{ -+ P_GLUE_INFO_T prGlueInfo; -+ UINT_8 ucPriorityParam; -+ UINT_8 ucMacHeaderLen; -+ UINT_8 aucEthDestAddr[PARAM_MAC_ADDR_LEN]; -+ BOOLEAN fgIs1x = FALSE; -+ BOOLEAN fgIsPAL = FALSE; -+ UINT_32 u4PacketLen; -+ ULONG u4SysTime; -+ UINT_8 ucNetworkType; -+ struct sk_buff *prSkb = (struct sk_buff *)prPacket; -+ -+ ASSERT(prAdapter); -+ -+ prGlueInfo = prAdapter->prGlueInfo; -+ ASSERT(prGlueInfo); -+ -+ if (kalQoSFrameClassifierAndPacketInfo(prGlueInfo, -+ prPacket, -+ &ucPriorityParam, -+ &u4PacketLen, -+ aucEthDestAddr, -+ &fgIs1x, &fgIsPAL, &ucNetworkType, -+ NULL) == FALSE) { -+ return FALSE; -+ } -+#if CFG_ENABLE_PKT_LIFETIME_PROFILE -+ nicTxLifetimeCheck(prAdapter, prMsduInfo, prPacket, ucPriorityParam, u4PacketLen, ucNetworkType); -+#endif -+ -+ /* Save the value of Priority Parameter */ -+ GLUE_SET_PKT_TID(prPacket, ucPriorityParam); -+ -+ if (fgIs1x) -+ GLUE_SET_PKT_FLAG_1X(prPacket); -+ -+ if (fgIsPAL) -+ GLUE_SET_PKT_FLAG_PAL(prPacket); -+ -+ ucMacHeaderLen = ETH_HLEN; -+ -+ /* Save the value of Header Length */ -+ GLUE_SET_PKT_HEADER_LEN(prPacket, ucMacHeaderLen); -+ -+ /* Save the value of Frame Length */ -+ GLUE_SET_PKT_FRAME_LEN(prPacket, (UINT_16) u4PacketLen); -+ -+ /* Save the value of Arrival Time */ -+ u4SysTime = (OS_SYSTIME) kalGetTimeTick(); -+ GLUE_SET_PKT_ARRIVAL_TIME(prPacket, u4SysTime); -+ -+ prMsduInfo->prPacket = prPacket; -+ prMsduInfo->fgIs802_1x = fgIs1x; -+ prMsduInfo->fgIs802_11 = FALSE; -+ prMsduInfo->ucNetworkType = ucNetworkType; -+ prMsduInfo->ucUserPriority = ucPriorityParam; -+ prMsduInfo->ucMacHeaderLength = ucMacHeaderLen; -+ prMsduInfo->u2FrameLength = (UINT_16) u4PacketLen; -+ COPY_MAC_ADDR(prMsduInfo->aucEthDestAddr, aucEthDestAddr); -+ -+ if (prSkb->len > ETH_HLEN) -+ STATS_TX_PKT_CALLBACK(prSkb->data, prMsduInfo); -+ return TRUE; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief this function update TCQ values by passing current status to txAdjustTcQuotas -+* -+* @param prAdapter Pointer to the Adapter structure. -+* -+* @retval WLAN_STATUS_SUCCESS Updated successfully -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS nicTxAdjustTcq(IN P_ADAPTER_T prAdapter) -+{ -+ UINT_32 u4Num; -+ TX_TCQ_ADJUST_T rTcqAdjust; -+ P_TX_CTRL_T prTxCtrl; -+ -+ KAL_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(prAdapter); -+ -+ prTxCtrl = &prAdapter->rTxCtrl; -+ ASSERT(prTxCtrl); -+ -+ qmAdjustTcQuotas(prAdapter, &rTcqAdjust, &prTxCtrl->rTc); -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_RESOURCE); -+ -+ for (u4Num = 0; u4Num < TC_NUM; u4Num++) { -+ prTxCtrl->rTc.aucFreeBufferCount[u4Num] += rTcqAdjust.acVariation[u4Num]; -+ prTxCtrl->rTc.aucMaxNumOfBuffer[u4Num] += rTcqAdjust.acVariation[u4Num]; -+ } -+ -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_RESOURCE); -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief this function flushes all packets queued in STA/AC queue -+* -+* @param prAdapter Pointer to the Adapter structure. -+* -+* @retval WLAN_STATUS_SUCCESS Flushed successfully -+*/ -+/*----------------------------------------------------------------------------*/ -+ -+WLAN_STATUS nicTxFlush(IN P_ADAPTER_T prAdapter) -+{ -+ P_MSDU_INFO_T prMsduInfo; -+ -+ KAL_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(prAdapter); -+ -+ /* ask Per STA/AC queue to be fllushed and return all queued packets */ -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_QM_TX_QUEUE); -+ prMsduInfo = qmFlushTxQueues(prAdapter); -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_QM_TX_QUEUE); -+ -+ if (prMsduInfo != NULL) { -+ nicTxFreeMsduInfoPacket(prAdapter, prMsduInfo); -+ nicTxReturnMsduInfo(prAdapter, prMsduInfo); -+ } -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+#if CFG_ENABLE_FW_DOWNLOAD -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief In this function, we'll write Command(CMD_INFO_T) into HIF. -+* However this function is used for INIT_CMD. -+* -+* In order to avoid further maintenance issues, these 2 functions are separated -+* -+* @param prAdapter Pointer to the Adapter structure. -+* @param prPacketInfo Pointer of CMD_INFO_T -+* @param ucTC Specify the resource of TC -+* -+* @retval WLAN_STATUS_SUCCESS Bus access ok. -+* @retval WLAN_STATUS_FAILURE Bus access fail. -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS nicTxInitCmd(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN UINT_8 ucTC) -+{ -+ P_INIT_HIF_TX_HEADER_T prInitTxHeader; -+ UINT_16 u2OverallBufferLength; -+ PUINT_8 pucOutputBuf = (PUINT_8) NULL; /* Pointer to Transmit Data Structure Frame */ -+ UINT_32 ucPortIdx; -+ P_TX_CTRL_T prTxCtrl; -+ -+ ASSERT(prAdapter); -+ ASSERT(prCmdInfo); -+ ASSERT(ucTC == TC0_INDEX); -+ -+ prTxCtrl = &prAdapter->rTxCtrl; -+ pucOutputBuf = prTxCtrl->pucTxCoalescingBufPtr; -+ prInitTxHeader = (P_INIT_HIF_TX_HEADER_T) prCmdInfo->pucInfoBuffer; -+ -+ /* <1> Compose the Header of Transmit Data Structure for CMD Packet */ -+ u2OverallBufferLength = -+ TFCB_FRAME_PAD_TO_DW((prCmdInfo->u2InfoBufLen) & (UINT_16) HIF_TX_HDR_TX_BYTE_COUNT_MASK); -+ -+ prInitTxHeader->u2TxByteCount = u2OverallBufferLength; -+ prInitTxHeader->ucEtherTypeOffset = 0; -+ prInitTxHeader->ucCSflags = 0; -+ -+ /* <2> Assign Data Port */ -+ if (ucTC != TC4_INDEX) { -+ ucPortIdx = 0; -+ } else { /* Broadcast/multicast data packets */ -+ ucPortIdx = 1; -+ } -+ -+ /* <3> Copy CMD Header to command buffer (by using pucCoalescingBufCached) */ -+ kalMemCopy((PVOID)&pucOutputBuf[0], (PVOID) prCmdInfo->pucInfoBuffer, prCmdInfo->u2InfoBufLen); -+ -+ ASSERT(u2OverallBufferLength <= prAdapter->u4CoalescingBufCachedSize); -+ -+ /* <4> Write frame to data port */ -+ HAL_WRITE_TX_PORT(prAdapter, -+ ucPortIdx, -+ (UINT_32) u2OverallBufferLength, -+ (PUINT_8) pucOutputBuf, (UINT_32) prAdapter->u4CoalescingBufCachedSize); -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief In this function, we'll reset TX resource counter to initial value used -+* in F/W download state -+* -+* @param prAdapter Pointer to the Adapter structure. -+* -+* @retval WLAN_STATUS_SUCCESS Reset is done successfully. -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS nicTxInitResetResource(IN P_ADAPTER_T prAdapter) -+{ -+ P_TX_CTRL_T prTxCtrl; -+ -+ DEBUGFUNC("nicTxInitResetResource"); -+ -+ ASSERT(prAdapter); -+ prTxCtrl = &prAdapter->rTxCtrl; -+ -+ prTxCtrl->rTc.aucMaxNumOfBuffer[TC0_INDEX] = NIC_TX_INIT_BUFF_COUNT_TC0; -+ prTxCtrl->rTc.aucFreeBufferCount[TC0_INDEX] = NIC_TX_INIT_BUFF_COUNT_TC0; -+ -+ prTxCtrl->rTc.aucMaxNumOfBuffer[TC1_INDEX] = NIC_TX_INIT_BUFF_COUNT_TC1; -+ prTxCtrl->rTc.aucFreeBufferCount[TC1_INDEX] = NIC_TX_INIT_BUFF_COUNT_TC1; -+ -+ prTxCtrl->rTc.aucMaxNumOfBuffer[TC2_INDEX] = NIC_TX_INIT_BUFF_COUNT_TC2; -+ prTxCtrl->rTc.aucFreeBufferCount[TC2_INDEX] = NIC_TX_INIT_BUFF_COUNT_TC2; -+ -+ prTxCtrl->rTc.aucMaxNumOfBuffer[TC3_INDEX] = NIC_TX_INIT_BUFF_COUNT_TC3; -+ prTxCtrl->rTc.aucFreeBufferCount[TC3_INDEX] = NIC_TX_INIT_BUFF_COUNT_TC3; -+ -+ prTxCtrl->rTc.aucMaxNumOfBuffer[TC4_INDEX] = NIC_TX_INIT_BUFF_COUNT_TC4; -+ prTxCtrl->rTc.aucFreeBufferCount[TC4_INDEX] = NIC_TX_INIT_BUFF_COUNT_TC4; -+ -+ prTxCtrl->rTc.aucMaxNumOfBuffer[TC5_INDEX] = NIC_TX_INIT_BUFF_COUNT_TC5; -+ prTxCtrl->rTc.aucFreeBufferCount[TC5_INDEX] = NIC_TX_INIT_BUFF_COUNT_TC5; -+ -+ return WLAN_STATUS_SUCCESS; -+ -+} -+ -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief this function enqueues MSDU_INFO_T into queue management, -+* or command queue -+* -+* @param prAdapter Pointer to the Adapter structure. -+* prMsduInfo Pointer to MSDU -+* -+* @retval WLAN_STATUS_SUCCESS Reset is done successfully. -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS nicTxEnqueueMsdu(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo) -+{ -+ P_TX_CTRL_T prTxCtrl; -+ P_MSDU_INFO_T prNextMsduInfo, prRetMsduInfo, prMsduInfoHead; -+ QUE_T qDataPort0, qDataPort1; -+ P_CMD_INFO_T prCmdInfo; -+ WLAN_STATUS u4Status = WLAN_STATUS_SUCCESS; -+ -+ KAL_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(prAdapter); -+ ASSERT(prMsduInfo); -+ -+ prTxCtrl = &prAdapter->rTxCtrl; -+ ASSERT(prTxCtrl); -+ -+ QUEUE_INITIALIZE(&qDataPort0); -+ QUEUE_INITIALIZE(&qDataPort1); -+ -+ /* check how many management frame are being queued */ -+ while (prMsduInfo) { -+ prNextMsduInfo = (P_MSDU_INFO_T) QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T) prMsduInfo); -+ -+ QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T) prMsduInfo) = NULL; -+ -+ if (prMsduInfo->eSrc == TX_PACKET_MGMT) { -+ /* MMPDU: force stick to TC4 */ -+ prMsduInfo->ucTC = TC4_INDEX; -+ -+ QUEUE_INSERT_TAIL(&qDataPort1, (P_QUE_ENTRY_T) prMsduInfo); -+ } else { -+ QUEUE_INSERT_TAIL(&qDataPort0, (P_QUE_ENTRY_T) prMsduInfo); -+ } -+ -+ prMsduInfo = prNextMsduInfo; -+ } -+ -+ if (qDataPort0.u4NumElem) { -+ /* send to QM: queue the packet to different TX queue by policy */ -+ KAL_SPIN_LOCK_DECLARATION(); -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_QM_TX_QUEUE); -+ prRetMsduInfo = qmEnqueueTxPackets(prAdapter, (P_MSDU_INFO_T) QUEUE_GET_HEAD(&qDataPort0)); -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_QM_TX_QUEUE); -+ -+ /* post-process for "dropped" packets */ -+ if (prRetMsduInfo != NULL) { /* unable to enqueue */ -+ nicTxFreeMsduInfoPacket(prAdapter, prRetMsduInfo); -+ nicTxReturnMsduInfo(prAdapter, prRetMsduInfo); -+ } -+ } -+ -+ if (qDataPort1.u4NumElem) { -+ prMsduInfoHead = (P_MSDU_INFO_T) QUEUE_GET_HEAD(&qDataPort1); -+ -+ if (qDataPort1.u4NumElem > nicTxGetFreeCmdCount(prAdapter)) { -+ /* not enough descriptors for sending */ -+ u4Status = WLAN_STATUS_FAILURE; -+ -+ /* free all MSDUs */ -+ while (prMsduInfoHead) { -+ prNextMsduInfo = (P_MSDU_INFO_T) QUEUE_GET_NEXT_ENTRY(&prMsduInfoHead->rQueEntry); -+ -+ if (prMsduInfoHead->pfTxDoneHandler != NULL) { -+ prMsduInfoHead->pfTxDoneHandler(prAdapter, prMsduInfoHead, -+ TX_RESULT_DROPPED_IN_DRIVER); -+ } -+ -+ cnmMgtPktFree(prAdapter, prMsduInfoHead); -+ -+ prMsduInfoHead = prNextMsduInfo; -+ } -+ } else { -+ /* send to command queue */ -+ while (prMsduInfoHead) { -+ prNextMsduInfo = (P_MSDU_INFO_T) QUEUE_GET_NEXT_ENTRY(&prMsduInfoHead->rQueEntry); -+ -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_RESOURCE); -+ QUEUE_REMOVE_HEAD(&prAdapter->rFreeCmdList, prCmdInfo, P_CMD_INFO_T); -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_RESOURCE); -+ -+ if (prCmdInfo) { -+ GLUE_INC_REF_CNT(prTxCtrl->i4TxMgmtPendingNum); -+ -+ kalMemZero(prCmdInfo, sizeof(CMD_INFO_T)); -+ -+ prCmdInfo->eCmdType = COMMAND_TYPE_MANAGEMENT_FRAME; -+ prCmdInfo->u2InfoBufLen = prMsduInfoHead->u2FrameLength; -+ prCmdInfo->pucInfoBuffer = NULL; -+ prCmdInfo->prPacket = (P_NATIVE_PACKET) prMsduInfoHead; -+ prCmdInfo->ucStaRecIndex = prMsduInfoHead->ucStaRecIndex; -+ prCmdInfo->eNetworkType = prMsduInfoHead->ucNetworkType; -+ prCmdInfo->pfCmdDoneHandler = NULL; -+ prCmdInfo->pfCmdTimeoutHandler = NULL; -+ prCmdInfo->fgIsOid = FALSE; -+ prCmdInfo->fgSetQuery = TRUE; -+ prCmdInfo->fgNeedResp = FALSE; -+ -+ kalEnqueueCommand(prAdapter->prGlueInfo, (P_QUE_ENTRY_T) prCmdInfo); -+ } else { -+ /* Cmd free count is larger than expected, but allocation fail. */ -+ ASSERT(0); -+ -+ u4Status = WLAN_STATUS_FAILURE; -+ cnmMgtPktFree(prAdapter, prMsduInfoHead); -+ } -+ -+ prMsduInfoHead = prNextMsduInfo; -+ } -+ } -+ } -+ -+ /* indicate service thread for sending */ -+ if (prTxCtrl->i4TxMgmtPendingNum > 0 || kalGetTxPendingFrameCount(prAdapter->prGlueInfo) > 0) -+ kalSetEvent(prAdapter->prGlueInfo); -+ -+ return u4Status; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief this function returns available count in command queue -+* -+* @param prAdapter Pointer to the Adapter structure. -+* -+* @retval -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT_32 nicTxGetFreeCmdCount(IN P_ADAPTER_T prAdapter) -+{ -+ ASSERT(prAdapter); -+ -+ return prAdapter->rFreeCmdList.u4NumElem; -+} -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/nic/p2p_nic.c b/drivers/misc/mediatek/connectivity/wlan/gen2/nic/p2p_nic.c -new file mode 100644 -index 000000000000..38e4569bc04f ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/nic/p2p_nic.c -@@ -0,0 +1,192 @@ -+/* -+** Id: @(#) p2p_nic.c@@ -+*/ -+ -+/*! \file p2p_nic.c -+ \brief Wi-Fi Direct Functions that provide operation in NIC's (Network Interface Card) point of view. -+ -+ This file includes functions which unite multiple hal(Hardware) operations -+ and also take the responsibility of Software Resource Management in order -+ to keep the synchronization with Hardware Manipulation. -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+#include "precomp.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief When Probe Rsp & Beacon frame is received and decide a P2P device, -+* this function will be invoked to buffer scan result -+* -+* @param prAdapter Pointer to the Adapter structure. -+* @param prEventScanResult Pointer of EVENT_SCAN_RESULT_T. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+nicRxAddP2pDevice(IN P_ADAPTER_T prAdapter, -+ IN P_EVENT_P2P_DEV_DISCOVER_RESULT_T prP2pResult, IN PUINT_8 pucRxIEBuf, IN UINT_16 u2RxIELength) -+{ -+ P_P2P_INFO_T prP2pInfo = (P_P2P_INFO_T) NULL; -+ P_EVENT_P2P_DEV_DISCOVER_RESULT_T prTargetResult = (P_EVENT_P2P_DEV_DISCOVER_RESULT_T) NULL; -+ UINT_32 u4Idx = 0; -+ BOOLEAN bUpdate = FALSE; -+ -+ PUINT_8 pucIeBuf = (PUINT_8) NULL; -+ UINT_16 u2IELength = 0; -+ UINT_8 zeroMac[] = { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }; -+ -+ ASSERT(prAdapter); -+ -+ prP2pInfo = prAdapter->prP2pInfo; -+ -+ for (u4Idx = 0; u4Idx < prP2pInfo->u4DeviceNum; u4Idx++) { -+ prTargetResult = &prP2pInfo->arP2pDiscoverResult[u4Idx]; -+ -+ if (EQUAL_MAC_ADDR(prTargetResult->aucDeviceAddr, prP2pResult->aucDeviceAddr)) { -+ bUpdate = TRUE; -+ -+ /* Backup OLD buffer result. */ -+ pucIeBuf = prTargetResult->pucIeBuf; -+ u2IELength = prTargetResult->u2IELength; -+ -+ /* Update Device Info. */ -+ /* zero */ -+ kalMemZero(prTargetResult, sizeof(EVENT_P2P_DEV_DISCOVER_RESULT_T)); -+ -+ /* then buffer */ -+ kalMemCopy(prTargetResult, (PVOID) prP2pResult, sizeof(EVENT_P2P_DEV_DISCOVER_RESULT_T)); -+ -+ /* See if new IE length is longer or not. */ -+ if ((u2RxIELength > u2IELength) && (u2IELength != 0)) { -+ /* Buffer is not enough. */ -+ u2RxIELength = u2IELength; -+ } else if ((u2IELength == 0) && (u2RxIELength != 0)) { -+ /* RX new IE buf. */ -+ ASSERT(pucIeBuf == NULL); -+ pucIeBuf = prP2pInfo->pucCurrIePtr; -+ -+ if (((ULONG) prP2pInfo->pucCurrIePtr + (ULONG) u2RxIELength) > -+ (ULONG)&prP2pInfo->aucCommIePool[CFG_MAX_COMMON_IE_BUF_LEN]) { -+ /* Common Buffer is no enough. */ -+ u2RxIELength = -+ (UINT_16) ((ULONG)&prP2pInfo->aucCommIePool[CFG_MAX_COMMON_IE_BUF_LEN] - -+ (ULONG) prP2pInfo->pucCurrIePtr); -+ } -+ -+ /* Step to next buffer address. */ -+ prP2pInfo->pucCurrIePtr = -+ (PUINT_8) ((ULONG) prP2pInfo->pucCurrIePtr + (ULONG) u2RxIELength); -+ } -+ -+ /* Restore buffer pointer. */ -+ prTargetResult->pucIeBuf = pucIeBuf; -+ -+ if (pucRxIEBuf) { -+ /* If new received IE is available. -+ * Replace the old one & update new IE length. -+ */ -+ kalMemCopy(pucIeBuf, pucRxIEBuf, u2RxIELength); -+ prTargetResult->u2IELength = u2RxIELength; -+ } else { -+ /* There is no new IE information, keep the old one. */ -+ prTargetResult->u2IELength = u2IELength; -+ } -+ } -+ } -+ -+ if (!bUpdate) { -+ /* We would flush the whole scan result after each scan request is issued. -+ * If P2P device is too many, it may over the scan list. -+ */ -+ if ((u4Idx < CFG_MAX_NUM_BSS_LIST) && (UNEQUAL_MAC_ADDR(zeroMac, prP2pResult->aucDeviceAddr))) { -+ /* whsu:XXX */ -+ prTargetResult = &prP2pInfo->arP2pDiscoverResult[u4Idx]; -+ -+ /* zero */ -+ kalMemZero(prTargetResult, sizeof(EVENT_P2P_DEV_DISCOVER_RESULT_T)); -+ -+ /* then buffer */ -+ kalMemCopy(prTargetResult, (PVOID) prP2pResult, sizeof(EVENT_P2P_DEV_DISCOVER_RESULT_T)); -+ -+ /* printk("DVC FND %d %pM, %pM\n", -+ prP2pInfo->u4DeviceNum, -+ prP2pResult->aucDeviceAddr, -+ prTargetResult->aucDeviceAddr); */ -+ -+ if (u2RxIELength) { -+ prTargetResult->pucIeBuf = prP2pInfo->pucCurrIePtr; -+ -+ if (((ULONG) prP2pInfo->pucCurrIePtr + (ULONG) u2RxIELength) > -+ (ULONG)&prP2pInfo->aucCommIePool[CFG_MAX_COMMON_IE_BUF_LEN]) { -+ /* Common Buffer is no enough. */ -+ u2IELength = -+ (UINT_16) ((ULONG)&prP2pInfo->aucCommIePool[CFG_MAX_COMMON_IE_BUF_LEN] - -+ (ULONG) prP2pInfo->pucCurrIePtr); -+ } else { -+ u2IELength = u2RxIELength; -+ } -+ -+ prP2pInfo->pucCurrIePtr = -+ (PUINT_8) ((ULONG) prP2pInfo->pucCurrIePtr + (ULONG) u2IELength); -+ -+ kalMemCopy((PVOID) prTargetResult->pucIeBuf, (PVOID) pucRxIEBuf, (UINT_32) u2IELength); -+ prTargetResult->u2IELength = u2IELength; -+ } else { -+ prTargetResult->pucIeBuf = NULL; -+ prTargetResult->u2IELength = 0; -+ } -+ -+ prP2pInfo->u4DeviceNum++; -+ -+ } else { -+ /* TODO: Fixme to replace an old one. (?) */ -+ ASSERT(FALSE); -+ } -+ } -+} /* nicRxAddP2pDevice */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/nic/que_mgt.c b/drivers/misc/mediatek/connectivity/wlan/gen2/nic/que_mgt.c -new file mode 100644 -index 000000000000..dd00859d4608 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/nic/que_mgt.c -@@ -0,0 +1,5038 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/nic/que_mgt.c#1 -+*/ -+ -+/*! \file "que_mgt.c" -+ \brief TX/RX queues management -+ -+ The main tasks of queue management include TC-based HIF TX flow control, -+ adaptive TC quota adjustment, HIF TX grant scheduling, Power-Save -+ forwarding control, RX packet reordering, and RX BA agreement management. -+*/ -+ -+/* -+** Log: que_mgt.c -+** -+** 04 11 2013 yuche.tsai -+** [ALPS00542142] [Pre-SQC][6627][W]use wifi direct press cancel connect, phone all stop. -+** Drop the probe response packet when absent. -+** -+** 04 09 2013 yuche.tsai -+** [ALPS00542142] [Pre-SQC][6627][W]use wifi direct press cancel connect, phone all stop. -+** Fix CMD buffer short issue. -+** -+** 04 09 2013 yuche.tsai -+** [ALPS00542142] [Pre-SQC][6627][W]use wifi direct press cancel connect, phone all stop. -+** Fix CMD buffer short issue. -+ * -+ * 03 02 2012 terry.wu -+ * NULL -+ * Sync CFG80211 modification from branch 2,2. -+ * -+ * 02 23 2012 eddie.chen -+ * [WCXRP00001194] [MT6620][DRV/FW] follow admission control bit to change the enqueue rule -+ * Change the enqueue policy when ACM = 1. -+ * -+ * 11 22 2011 yuche.tsai -+ * NULL -+ * Code refine, remove one #if 0 code. -+ * -+ * 11 19 2011 eddie.chen -+ * [WCXRP00001096] [MT6620 Wi-Fi][Driver/FW] Enhance the log function (xlog) -+ * Add xlog for tx -+ * -+ * 11 18 2011 yuche.tsai -+ * NULL -+ * CONFIG P2P support RSSI query, default turned off. -+ * -+ * 11 18 2011 eddie.chen -+ * [WCXRP00001096] [MT6620 Wi-Fi][Driver/FW] Enhance the log function (xlog) -+ * Fix xlog format to hex format -+ * -+ * 11 17 2011 tsaiyuan.hsu -+ * [WCXRP00001115] [MT6620 Wi-Fi][DRV] avoid deactivating staRec when changing state 3 to 3. -+ * avoid deactivating staRec when changing state from 3 to 3. -+ * -+ * 11 11 2011 tsaiyuan.hsu -+ * [WCXRP00001083] [MT6620 Wi-Fi][DRV]] dump debug counter or frames when debugging is triggered -+ * add debug msg for xlog. -+ * -+ * 11 11 2011 tsaiyuan.hsu -+ * [WCXRP00001083] [MT6620 Wi-Fi][DRV]] dump debug counter or frames when debugging is triggered -+ * add debug counters of bb and ar for xlog. -+ * -+ * 11 10 2011 eddie.chen -+ * [WCXRP00001096] [MT6620 Wi-Fi][Driver/FW] Enhance the log function (xlog) -+ * Use short name for xlog. -+ * -+ * 11 10 2011 eddie.chen -+ * [WCXRP00001096] [MT6620 Wi-Fi][Driver/FW] Enhance the log function (xlog) -+ * Modify the QM xlog level and remove LOG_FUNC. -+ * -+ * 11 10 2011 chinglan.wang -+ * NULL -+ * [WiFi WPS]Can't switch to new AP via WPS PBC when there existing a connection to another AP. -+ * -+ * 11 09 2011 chinglan.wang -+ * NULL -+ * [WiFi direct]Can't make P2P connect via PBC. -+ * -+ * 11 08 2011 eddie.chen -+ * [WCXRP00001096] [MT6620 Wi-Fi][Driver/FW] Enhance the log function (xlog) -+ * Add xlog function. -+ * -+ * 11 07 2011 tsaiyuan.hsu -+ * [WCXRP00001083] [MT6620 Wi-Fi][DRV]] dump debug counter or frames when debugging is triggered -+ * add debug counters and periodically dump counters for debugging. -+ * -+ * 11 01 2011 chinglan.wang -+ * NULL -+ * Modify the Wi-Fi method of the flush TX queue when disconnect the AP. -+ * If disconnect the AP and flush all the data frame in the TX queue, WPS cannot do the 4-way handshake to connect to -+ * the AP.. -+ * -+ * 10 25 2011 wh.su -+ * [WCXRP00001059] [MT6620 Wi-Fi][Driver][P2P] Fixed sometimes data (1x) will not indicate to upper layer due ba check -+ * un-expect -+ * let the Rx BA accept even the sta not valid. -+ * -+ * 09 28 2011 tsaiyuan.hsu -+ * [WCXRP00000900] [MT5931 Wi-Fi] Improve balance of TX and RX -+ * enlarge window size only by 4. -+ * -+ * 09 01 2011 tsaiyuan.hsu -+ * [WCXRP00000900] [MT5931 Wi-Fi] Improve balance of TX and RX -+ * set rx window size as twice buffer size. -+ * -+ * 08 23 2011 yuche.tsai -+ * NULL -+ * Fix multicast address list issue. -+ * -+ * 08 03 2011 tsaiyuan.hsu -+ * [WCXRP00000900] [MT5931 Wi-Fi] Improve balance of TX and RX -+ * force window size at least 16. -+ * -+ * 08 02 2011 yuche.tsai -+ * [WCXRP00000896] [Volunteer Patch][WiFi Direct][Driver] GO with multiple client, TX deauth to a disconnecting device -+ * issue. -+ * Fix GO send deauth frame issue. -+ * -+ * 07 26 2011 eddie.chen -+ * [WCXRP00000874] [MT5931][DRV] API for query the RX reorder queued packets counter -+ * API for query the RX reorder queued packets counter. -+ * -+ * 07 07 2011 eddie.chen -+ * [WCXRP00000834] [MT6620 Wi-Fi][DRV] Send 1x packet when peer STA is in PS. -+ * Add setEvent when free quota is updated. -+ * -+ * 07 05 2011 eddie.chen -+ * [WCXRP00000834] [MT6620 Wi-Fi][DRV] Send 1x packet when peer STA is in PS. -+ * Send 1x when peer STA is in PS. -+ * -+ * 05 31 2011 eddie.chen -+ * [WCXRP00000753] [MT5931 Wi-Fi][DRV] Adjust QM for MT5931 -+ * Fix the QM quota in MT5931. -+ * -+ * 05 11 2011 eddie.chen -+ * [WCXRP00000709] [MT6620 Wi-Fi][Driver] Check free number before copying broadcast packet -+ * Fix dest type when GO packet copying. -+ * -+ * 05 09 2011 yuche.tsai -+ * [WCXRP00000712] [Volunteer Patch][MT6620][Driver] Sending deauth issue when Hot spot is disabled. (GO is dissolved) -+ * Deauthentication frame is not bound to network active status. -+ * -+ * 05 09 2011 eddie.chen -+ * [WCXRP00000709] [MT6620 Wi-Fi][Driver] Check free number before copying broadcast packet -+ * Check free number before copying broadcast packet. -+ * -+ * 04 14 2011 eddie.chen -+ * [WCXRP00000603] [MT6620 Wi-Fi][DRV] Fix Klocwork warning -+ * Check the SW RFB free. Fix the compile warning.. -+ * -+ * 04 12 2011 eddie.chen -+ * [WCXRP00000617] [MT6620 Wi-Fi][DRV/FW] Fix for sigma -+ * Fix the sta index in processing security frame -+ * Simple flow control for TC4 to avoid mgt frames for PS STA to occupy the TC4 -+ * Add debug message. -+ * -+ * 04 11 2011 yuche.tsai -+ * [WCXRP00000627] [Volunteer Patch][MT6620][Driver] Pending MMPUD of P2P Network may crash system issue. -+ * Fix kernel panic issue when MMPDU of P2P is pending in driver. -+ * -+ * 04 08 2011 eddie.chen -+ * [WCXRP00000617] [MT6620 Wi-Fi][DRV/FW] Fix for sigma -+ * Fix for sigma -+ * -+ * 03 28 2011 eddie.chen -+ * [WCXRP00000603] [MT6620 Wi-Fi][DRV] Fix Klocwork warning -+ * Fix Klockwork warning. -+ * -+ * 03 28 2011 eddie.chen -+ * [WCXRP00000602] [MT6620 Wi-Fi][DRV] Fix wmm parameters in beacon for BOW -+ * Fix wmm parameters in beacon for BOW. -+ * -+ * 03 15 2011 eddie.chen -+ * [WCXRP00000554] [MT6620 Wi-Fi][DRV] Add sw control debug counter -+ * Add sw debug counter for QM. -+ * -+ * 02 23 2011 eddie.chen -+ * [WCXRP00000463] [MT6620 Wi-Fi][FW/Driver][Hotspot] Cannot update WMM PS STA's partital bitmap -+ * Fix parsing WMM INFO and bmp delivery bitmap definition. -+ * -+ * 02 17 2011 eddie.chen -+ * [WCXRP00000458] [MT6620 Wi-Fi][Driver] BOW Concurrent - ProbeResp was exist in other channel -+ * 1) Change GetFrameAction decision when BSS is absent. -+ * 2) Check channel and resource in processing ProbeRequest -+ * -+ * 02 08 2011 eddie.chen -+ * [WCXRP00000426] [MT6620 Wi-Fi][FW/Driver] Add STA aging timeout and defualtHwRatein AP mode -+ * Add event STA agint timeout -+ * -+ * 01 27 2011 tsaiyuan.hsu -+ * [WCXRP00000392] [MT6620 Wi-Fi][Driver] Add Roaming Support -+ * add roaming fsm -+ * 1. not support 11r, only use strength of signal to determine roaming. -+ * 2. not enable CFG_SUPPORT_ROAMING until completion of full test. -+ * 3. in 6620, adopt work-around to avoid sign extension problem of cck of hw -+ * 4. assume that change of link quality in smooth way. -+ * -+ * 01 25 2011 yuche.tsai -+ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record. -+ * Change Station Type in Station Record, Modify MACRO definition for getting station type & network type index & Role. -+ * -+ * 01 24 2011 eddie.chen -+ * [WCXRP00000385] [MT6620 Wi-Fi][DRV] Add destination decision for forwarding packets -+ * Remove comments. -+ * -+ * 01 24 2011 eddie.chen -+ * [WCXRP00000385] [MT6620 Wi-Fi][DRV] Add destination decision for forwarding packets -+ * Add destination decision in AP mode. -+ * -+ * 01 14 2011 wh.su -+ * [WCXRP00000099] [MT6620 Wi-Fi] [Driver] workaround to let the de-authentication can be send out[WCXRP00000326] -+ * [MT6620][Wi-Fi][Driver] check in the binary format gl_sec.o.new instead of use change type!!! -+ * Allow 802.1x can be send even the net is not active due the drver / fw sync issue. -+ * -+ * 01 13 2011 eddie.chen -+ * [WCXRP00000322] Add WMM IE in beacon, -+Add per station flow control when STA is in PS -+ * Fix typo and compile error. -+ * -+ * 01 12 2011 eddie.chen -+ * [WCXRP00000322] Add WMM IE in beacon, -+Add per station flow control when STA is in PS -+ * Fix WMM parameter condition for STA -+ * -+ * 01 12 2011 eddie.chen -+ * [WCXRP00000322] Add WMM IE in beacon, -+Add per station flow control when STA is in PS -+ * 1) Check Bss if support QoS before adding WMMIE -+ * 2) Check if support prAdapter->rWifiVar QoS and uapsd in flow control -+ * -+ * 01 12 2011 george.huang -+ * [WCXRP00000355] [MT6620 Wi-Fi] Set WMM-PS related setting with qualifying AP capability -+ * Update MQM for WMM IE generation method -+ * -+ * 01 11 2011 eddie.chen -+ * [WCXRP00000322] Add WMM IE in beacon, -+Add per station flow control when STA is in PS -+ -+ * Add per STA flow control when STA is in PS mode -+ * -+ * 01 03 2011 george.huang -+ * [WCXRP00000152] [MT6620 Wi-Fi] AP mode power saving function -+ * update prStaRec->fgIsUapsdSupported flag. -+ * -+ * 12 29 2010 eddie.chen -+ * [WCXRP00000322] Add WMM IE in beacon, -+Add per station flow control when STA is in PS -+ -+ * Add WMM parameter for broadcast. -+ * -+ * 12 29 2010 eddie.chen -+ * [WCXRP00000322] Add WMM IE in beacon, -+Add per station flow control when STA is in PS -+ -+ * 1) PS flow control event -+ * -+ * 2) WMM IE in beacon, assoc resp, probe resp -+ * -+ * 12 23 2010 george.huang -+ * [WCXRP00000152] [MT6620 Wi-Fi] AP mode power saving function -+ * 1. update WMM IE parsing, with ASSOC REQ handling -+ * 2. extend U-APSD parameter passing from driver to FW -+ * -+ * 10 14 2010 wh.su -+ * [WCXRP00000099] [MT6620 Wi-Fi] [Driver] workaround to let the de-authentication can be send out -+ * use the #14 and modify the add code for check MMPDU. -+ * -+ * 10 14 2010 wh.su -+ * [WCXRP00000099] [MT6620 Wi-Fi] [Driver] workaround to let the de-authentication can be send out -+ * only MMPDU not check the netActive flag. -+ * -+ * 10 14 2010 wh.su -+ * [WCXRP00000099] [MT6620 Wi-Fi] [Driver] workaround to let the de-authentication can be send out -+ * not check the netActive flag for mgmt . -+ * -+ * 10 04 2010 cp.wu -+ * [WCXRP00000077] [MT6620 Wi-Fi][Driver][FW] Eliminate use of ENUM_NETWORK_TYPE_T and replaced by -+ * ENUM_NETWORK_TYPE_INDEX_T only -+ * remove ENUM_NETWORK_TYPE_T definitions -+ * -+ * 09 21 2010 kevin.huang -+ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning -+ * Eliminate Linux Compile Warning -+ * -+ * 08 30 2010 yarco.yang -+ * NULL -+ * Fixed klockwork error message -+ * -+ * 08 18 2010 yarco.yang -+ * NULL -+ * 1. Fixed HW checksum offload function not work under Linux issue. -+ * 2. Add debug message. -+ * -+ * 08 10 2010 yarco.yang -+ * NULL -+ * Code refine -+ * -+ * 08 06 2010 yarco.yang -+ * NULL -+ * Update qmGetFrameAction() to allow P2P MGMT frame w/o STA_Record still can perform TX action -+ * -+ * 07 26 2010 cp.wu -+ * -+ * AIS-FSM FIX: return channel privilege even when the privilege is not granted yet -+ * QM: qmGetFrameAction() won't assert when corresponding STA-REC index is not found -+ * -+ * 07 20 2010 yarco.yang -+ * -+ * Add to SetEvent when BSS is from Absent to Present or STA from PS to Awake -+ * -+ * 07 16 2010 yarco.yang -+ * -+ * 1. Support BSS Absence/Presence Event -+ * 2. Support STA change PS mode Event -+ * 3. Support BMC forwarding for AP mode. -+ * -+ * 07 14 2010 yarco.yang -+ * -+ * 1. Remove CFG_MQM_MIGRATION -+ * 2. Add CMD_UPDATE_WMM_PARMS command -+ * -+ * 07 13 2010 yarco.yang -+ * -+ * [WPD00003849] -+ * [MT6620 and MT5931] SW Migration, add qmGetFrameAction() API for CMD Queue Processing -+ * -+ * 07 09 2010 yarco.yang -+ * -+ * [MT6620 and MT5931] SW Migration: Add ADDBA support -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 07 08 2010 yarco.yang -+ * [WPD00003837][MT6620]Data Path Refine -+ * . -+ * -+ * 07 06 2010 yarco.yang -+ * [WPD00003837][MT6620]Data Path Refine -+ * Use fgInUse instead of fgIsValid for De-queue judgement -+ * -+ * 07 06 2010 yarco.yang -+ * [WPD00003837][MT6620]Data Path Refine -+ * For MMPDU, STA_REC will be decided by caller module -+ * -+ * 07 06 2010 yarco.yang -+ * [WPD00003837][MT6620]Data Path Refine -+ * Add MGMT Packet type for HIF_TX_HEADER -+ * -+ * 06 29 2010 yarco.yang -+ * [WPD00003837][MT6620]Data Path Refine -+ * replace g_rQM with Adpater->rQM -+ * -+ * 06 25 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add API in que_mgt to retrieve sta-rec index for security frames. -+ * -+ * 06 23 2010 yarco.yang -+ * [WPD00003837][MT6620]Data Path Refine -+ * Merge g_arStaRec[] into adapter->arStaRec[] -+ * -+ * 06 21 2010 yarco.yang -+ * [WPD00003837][MT6620]Data Path Refine -+ * Support CFG_MQM_MIGRATION flag -+ * -+ * 06 11 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) migrate assoc.c. -+ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness -+ * 3) add configuration options for CNM_MEM and RSN modules -+ * 4) add data path for management frames -+ * 5) eliminate rPacketInfo of MSDU_INFO_T -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 03 31 2010 tehuang.liu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * Refined the debug msg -+ * -+ * 03 30 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * comment out one assertion which refer to undefined data member. -+ * -+ * 03 30 2010 tehuang.liu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * Enabled adaptive TC resource control -+ * -+ * 03 24 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * initial import for Linux port -+ * -+* 03 17 2010 tehuang.liu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * Changed STA_REC index determination rules (DA=BMCAST always --> STA_REC_INDEX_BMCAST) -+ * -+ * 03 11 2010 tehuang.liu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * Fixed buffer leak when processing BAR frames -+ * -+ * 03 02 2010 tehuang.liu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * For TX packets with STA_REC index = STA_REC_INDEX_NOT_FOUND, use TC5 -+ * -+ * 03 01 2010 tehuang.liu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * Fixed STA_REC index determination bug (fgIsValid shall be checked) -+ * -+ * 02 25 2010 tehuang.liu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * Refined function qmDetermineStaRecIndex() for BMCAST packets -+ * -+ * 02 25 2010 tehuang.liu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * Enabled multi-STA TX path with fairness -+ * -+ * 02 24 2010 tehuang.liu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * Enabled dynamically activating and deactivating STA_RECs -+ * -+ * 02 24 2010 tehuang.liu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * Added code for dynamic activating and deactivating STA_RECs. -+ * -+ * 01 13 2010 tehuang.liu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * Enabled the 802.1x path -+ * -+ * 01 13 2010 tehuang.liu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * Enabled the Burst_End Indication mechanism -+** \main\maintrunk.MT6620WiFiDriver_Prj\13 2009-12-14 15:01:37 GMT MTK02468 -+** Fixed casting for qmAddRxBaEntry() -+** \main\maintrunk.MT6620WiFiDriver_Prj\12 2009-12-10 16:51:03 GMT mtk02752 -+** remove SD1_SD3.. flag -+** \main\maintrunk.MT6620WiFiDriver_Prj\11 2009-12-09 14:07:25 GMT MTK02468 -+** Added RX buffer reordering functions -+** \main\maintrunk.MT6620WiFiDriver_Prj\10 2009-12-04 13:34:16 GMT MTK02468 -+** Modified Flush Queue function to let queues be reinitialized -+** \main\maintrunk.MT6620WiFiDriver_Prj\9 2009-12-04 13:18:25 GMT MTK02468 -+** Added flushing per-Type queues code -+** \main\maintrunk.MT6620WiFiDriver_Prj\8 2009-12-02 23:39:49 GMT MTK02468 -+** Added Debug msgs and fixed incorrect assert -+** \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-11-26 23:50:27 GMT MTK02468 -+** Bug fixing (qmDequeueTxPackets local variable initialization) -+** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-11-26 09:39:25 GMT mtk02752 -+** correct and surpress PREfast warning -+** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-11-23 22:10:55 GMT mtk02468 -+** Used SD1_SD3_DATAPATH_INTEGRATION -+** \main\maintrunk.MT6620WiFiDriver_Prj\1 2009-11-23 22:02:30 GMT mtk02468 -+** Initial version -+** -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "precomp.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+OS_SYSTIME g_arMissTimeout[CFG_STA_REC_NUM][CFG_RX_MAX_BA_TID_NUM]; -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+#if ARP_MONITER_ENABLE -+static UINT_16 arpMoniter; -+static UINT_8 apIp[4]; -+#endif -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+static inline VOID qmDetermineStaRecIndex(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); -+ -+static inline VOID -+qmDequeueTxPacketsFromPerStaQueues(IN P_ADAPTER_T prAdapter, -+ OUT P_QUE_T prQue, -+ IN UINT_8 ucTC, IN UINT_8 ucCurrentAvailableQuota, IN UINT_8 ucTotalQuota); -+ -+static inline VOID -+qmDequeueTxPacketsFromPerTypeQueues(IN P_ADAPTER_T prAdapter, OUT P_QUE_T prQue, IN UINT_8 ucTC, IN UINT_8 ucMaxNum); -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Init Queue Management for TX -+* -+* \param[in] (none) -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID qmInit(IN P_ADAPTER_T prAdapter) -+{ -+ UINT_32 u4QueArrayIdx; -+ UINT_32 i; -+ -+ P_QUE_MGT_T prQM = &prAdapter->rQM; -+ -+ /* DbgPrint("QM: Enter qmInit()\n"); */ -+#if CFG_SUPPORT_QOS -+ prAdapter->rWifiVar.fgSupportQoS = TRUE; -+#else -+ prAdapter->rWifiVar.fgSupportQoS = FALSE; -+#endif -+ -+#if CFG_SUPPORT_AMPDU_RX -+ prAdapter->rWifiVar.fgSupportAmpduRx = TRUE; -+#else -+ prAdapter->rWifiVar.fgSupportAmpduRx = FALSE; -+#endif -+ -+#if CFG_SUPPORT_AMPDU_TX -+ prAdapter->rWifiVar.fgSupportAmpduTx = TRUE; -+#else -+ prAdapter->rWifiVar.fgSupportAmpduTx = FALSE; -+#endif -+ -+#if CFG_SUPPORT_TSPEC -+ prAdapter->rWifiVar.fgSupportTspec = TRUE; -+#else -+ prAdapter->rWifiVar.fgSupportTspec = FALSE; -+#endif -+ -+#if CFG_SUPPORT_UAPSD -+ prAdapter->rWifiVar.fgSupportUAPSD = TRUE; -+#else -+ prAdapter->rWifiVar.fgSupportUAPSD = FALSE; -+#endif -+ -+#if CFG_SUPPORT_UL_PSMP -+ prAdapter->rWifiVar.fgSupportULPSMP = TRUE; -+#else -+ prAdapter->rWifiVar.fgSupportULPSMP = FALSE; -+#endif -+ -+#if CFG_SUPPORT_RX_SGI -+ prAdapter->rWifiVar.u8SupportRxSgi20 = 0; -+ prAdapter->rWifiVar.u8SupportRxSgi40 = 0; -+#else -+ prAdapter->rWifiVar.u8SupportRxSgi20 = 2; -+ prAdapter->rWifiVar.u8SupportRxSgi40 = 2; -+#endif -+ -+#if CFG_SUPPORT_RX_HT_GF -+ prAdapter->rWifiVar.u8SupportRxGf = 0; -+#else -+ prAdapter->rWifiVar.u8SupportRxGf = 2; -+#endif -+ -+ /* 4 <2> Initialize other TX queues (queues not in STA_RECs) */ -+ for (u4QueArrayIdx = 0; u4QueArrayIdx < NUM_OF_PER_TYPE_TX_QUEUES; u4QueArrayIdx++) -+ QUEUE_INITIALIZE(&(prQM->arTxQueue[u4QueArrayIdx])); -+ -+ /* 4 <3> Initialize the RX BA table and RX queues */ -+ /* Initialize the RX Reordering Parameters and Queues */ -+ for (u4QueArrayIdx = 0; u4QueArrayIdx < CFG_NUM_OF_RX_BA_AGREEMENTS; u4QueArrayIdx++) { -+ prQM->arRxBaTable[u4QueArrayIdx].fgIsValid = FALSE; -+ QUEUE_INITIALIZE(&(prQM->arRxBaTable[u4QueArrayIdx].rReOrderQue)); -+ prQM->arRxBaTable[u4QueArrayIdx].u2WinStart = 0xFFFF; -+ prQM->arRxBaTable[u4QueArrayIdx].u2WinEnd = 0xFFFF; -+ -+ prQM->arRxBaTable[u4QueArrayIdx].fgIsWaitingForPktWithSsn = FALSE; -+ -+ } -+ prQM->ucRxBaCount = 0; -+ -+ kalMemSet(&g_arMissTimeout, 0, sizeof(g_arMissTimeout)); -+ -+#if QM_ADAPTIVE_TC_RESOURCE_CTRL -+ /* 4 <4> Initialize TC resource control variables */ -+ for (i = 0; i < TC_NUM; i++) -+ prQM->au4AverageQueLen[i] = 0; -+ prQM->u4TimeToAdjustTcResource = QM_INIT_TIME_TO_ADJUST_TC_RSC; -+ prQM->u4TimeToUpdateQueLen = QM_INIT_TIME_TO_UPDATE_QUE_LEN; -+ prQM->u4TxNumOfVi = 0; -+ prQM->u4TxNumOfVo = 0; -+ -+/* ASSERT(prQM->u4TimeToAdjust && prQM->u4TimeToUpdateQueLen); */ -+ -+ /* 1 20 1 1 4 1 */ -+ prQM->au4CurrentTcResource[TC0_INDEX] = NIC_TX_BUFF_COUNT_TC0; -+ prQM->au4CurrentTcResource[TC1_INDEX] = NIC_TX_BUFF_COUNT_TC1; -+ prQM->au4CurrentTcResource[TC2_INDEX] = NIC_TX_BUFF_COUNT_TC2; -+ prQM->au4CurrentTcResource[TC3_INDEX] = NIC_TX_BUFF_COUNT_TC3; -+ prQM->au4CurrentTcResource[TC4_INDEX] = NIC_TX_BUFF_COUNT_TC4; /* Not adjustable (TX port 1) */ -+ prQM->au4CurrentTcResource[TC5_INDEX] = NIC_TX_BUFF_COUNT_TC5; -+ DBGLOG(QM, TRACE, "QM: NIC_TX_BUFF_COUNT_TC0 = %d\n", NIC_TX_BUFF_COUNT_TC0); -+ DBGLOG(QM, TRACE, "QM: NIC_TX_BUFF_COUNT_TC1 = %d\n", NIC_TX_BUFF_COUNT_TC1); -+ DBGLOG(QM, TRACE, "QM: NIC_TX_BUFF_COUNT_TC2 = %d\n", NIC_TX_BUFF_COUNT_TC2); -+ DBGLOG(QM, TRACE, "QM: NIC_TX_BUFF_COUNT_TC3 = %d\n", NIC_TX_BUFF_COUNT_TC3); -+ DBGLOG(QM, TRACE, "QM: NIC_TX_BUFF_COUNT_TC4 = %d\n", NIC_TX_BUFF_COUNT_TC4); -+ DBGLOG(QM, TRACE, "QM: NIC_TX_BUFF_COUNT_TC5 = %d\n", NIC_TX_BUFF_COUNT_TC5); -+ -+ /* 1 1 1 1 2 1 */ -+ prQM->au4MinReservedTcResource[TC0_INDEX] = QM_MIN_RESERVED_TC0_RESOURCE; -+ prQM->au4MinReservedTcResource[TC1_INDEX] = QM_MIN_RESERVED_TC1_RESOURCE; -+ prQM->au4MinReservedTcResource[TC2_INDEX] = QM_MIN_RESERVED_TC2_RESOURCE; -+ prQM->au4MinReservedTcResource[TC3_INDEX] = QM_MIN_RESERVED_TC3_RESOURCE; -+ prQM->au4MinReservedTcResource[TC4_INDEX] = QM_MIN_RESERVED_TC4_RESOURCE; /* Not adjustable (TX port 1) */ -+ prQM->au4MinReservedTcResource[TC5_INDEX] = QM_MIN_RESERVED_TC5_RESOURCE; -+ -+ /* 4 4 6 6 2 4 */ -+ prQM->au4GuaranteedTcResource[TC0_INDEX] = QM_GUARANTEED_TC0_RESOURCE; -+ prQM->au4GuaranteedTcResource[TC1_INDEX] = QM_GUARANTEED_TC1_RESOURCE; -+ prQM->au4GuaranteedTcResource[TC2_INDEX] = QM_GUARANTEED_TC2_RESOURCE; -+ prQM->au4GuaranteedTcResource[TC3_INDEX] = QM_GUARANTEED_TC3_RESOURCE; -+ prQM->au4GuaranteedTcResource[TC4_INDEX] = QM_GUARANTEED_TC4_RESOURCE; -+ prQM->au4GuaranteedTcResource[TC5_INDEX] = QM_GUARANTEED_TC5_RESOURCE; -+ -+ prQM->fgTcResourcePostAnnealing = FALSE; -+ -+ ASSERT(QM_INITIAL_RESIDUAL_TC_RESOURCE < 64); -+#endif -+ -+#if QM_TEST_MODE -+ prQM->u4PktCount = 0; -+ -+#if QM_TEST_FAIR_FORWARDING -+ -+ prQM->u4CurrentStaRecIndexToEnqueue = 0; -+ { -+ UINT_8 aucMacAddr[MAC_ADDR_LEN]; -+ P_STA_RECORD_T prStaRec; -+ -+ /* Irrelevant in case this STA is an AIS AP (see qmDetermineStaRecIndex()) */ -+ aucMacAddr[0] = 0x11; -+ aucMacAddr[1] = 0x22; -+ aucMacAddr[2] = 0xAA; -+ aucMacAddr[3] = 0xBB; -+ aucMacAddr[4] = 0xCC; -+ aucMacAddr[5] = 0xDD; -+ -+ prStaRec = &prAdapter->arStaRec[1]; -+ ASSERT(prStaRec); -+ -+ prStaRec->fgIsValid = TRUE; -+ prStaRec->fgIsQoS = TRUE; -+ prStaRec->fgIsInPS = FALSE; -+ prStaRec->ucPsSessionID = 0xFF; -+ prStaRec->ucNetTypeIndex = NETWORK_TYPE_AIS_INDEX; -+ prStaRec->fgIsAp = TRUE; -+ COPY_MAC_ADDR((prStaRec)->aucMacAddr, aucMacAddr); -+ -+ } -+ -+#endif -+ -+#endif -+ -+#if QM_FORWARDING_FAIRNESS -+ { -+ UINT_32 i; -+ -+ for (i = 0; i < NUM_OF_PER_STA_TX_QUEUES; i++) { -+ prQM->au4ForwardCount[i] = 0; -+ prQM->au4HeadStaRecIndex[i] = 0; -+ } -+ } -+#endif -+ -+#if QM_TC_RESOURCE_EMPTY_COUNTER -+ kalMemZero(prQM->au4QmTcResourceEmptyCounter, sizeof(prQM->au4QmTcResourceEmptyCounter)); -+#endif -+ -+} -+ -+#if QM_TEST_MODE -+VOID qmTestCases(IN P_ADAPTER_T prAdapter) -+{ -+ P_QUE_MGT_T prQM = &prAdapter->rQM; -+ -+ DbgPrint("QM: ** TEST MODE **\n"); -+ -+ if (QM_TEST_STA_REC_DETERMINATION) { -+ if (prAdapter->arStaRec[0].fgIsValid) { -+ prAdapter->arStaRec[0].fgIsValid = FALSE; -+ DbgPrint("QM: (Test) Deactivate STA_REC[0]\n"); -+ } else { -+ prAdapter->arStaRec[0].fgIsValid = TRUE; -+ DbgPrint("QM: (Test) Activate STA_REC[0]\n"); -+ } -+ } -+ -+ if (QM_TEST_STA_REC_DEACTIVATION) { -+ /* Note that QM_STA_REC_HARD_CODING shall be set to 1 for this test */ -+ -+ if (prAdapter->arStaRec[0].fgIsValid) { -+ -+ DbgPrint("QM: (Test) Deactivate STA_REC[0]\n"); -+ qmDeactivateStaRec(prAdapter, 0); -+ } else { -+ -+ UINT_8 aucMacAddr[MAC_ADDR_LEN]; -+ -+ /* Irrelevant in case this STA is an AIS AP (see qmDetermineStaRecIndex()) */ -+ aucMacAddr[0] = 0x11; -+ aucMacAddr[1] = 0x22; -+ aucMacAddr[2] = 0xAA; -+ aucMacAddr[3] = 0xBB; -+ aucMacAddr[4] = 0xCC; -+ aucMacAddr[5] = 0xDD; -+ -+ DbgPrint("QM: (Test) Activate STA_REC[0]\n"); -+ qmActivateStaRec(prAdapter, /* Adapter pointer */ -+ 0, /* STA_REC index from FW */ -+ TRUE, /* fgIsQoS */ -+ NETWORK_TYPE_AIS_INDEX, /* Network type */ -+ TRUE, /* fgIsAp */ -+ aucMacAddr /* MAC address */ -+ ); -+ } -+ } -+ -+ if (QM_TEST_FAIR_FORWARDING) { -+ if (prAdapter->arStaRec[1].fgIsValid) { -+ prQM->u4CurrentStaRecIndexToEnqueue++; -+ prQM->u4CurrentStaRecIndexToEnqueue %= 2; -+ DbgPrint("QM: (Test) Switch to STA_REC[%u]\n", prQM->u4CurrentStaRecIndexToEnqueue); -+ } -+ } -+ -+} -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Activate a STA_REC -+* -+* \param[in] prAdapter Pointer to the Adapter instance -+* \param[in] u4StaRecIdx The index of the STA_REC -+* \param[in] fgIsQoS Set to TRUE if this is a QoS STA -+* \param[in] pucMacAddr The MAC address of the STA -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID qmActivateStaRec(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec) -+{ -+ -+ /* 4 <1> Deactivate first */ -+ ASSERT(prStaRec); -+ -+ if (prStaRec->fgIsValid) { /* The STA_REC has been activated */ -+ DBGLOG(QM, WARN, "QM: (WARNING) Activating a STA_REC which has been activated\n"); -+ DBGLOG(QM, WARN, "QM: (WARNING) Deactivating a STA_REC before re-activating\n"); -+ /* To flush TX/RX queues and del RX BA agreements */ -+ qmDeactivateStaRec(prAdapter, prStaRec->ucIndex); -+ } -+ /* 4 <2> Activate the STA_REC */ -+ /* Init the STA_REC */ -+ prStaRec->fgIsValid = TRUE; -+ prStaRec->fgIsInPS = FALSE; -+ prStaRec->ucPsSessionID = 0xFF; -+ prStaRec->fgIsAp = (IS_AP_STA(prStaRec)) ? TRUE : FALSE; -+ -+ /* Done in qmInit() or qmDeactivateStaRec() */ -+#if 0 -+ /* At the beginning, no RX BA agreements have been established */ -+ for (i = 0; i < CFG_RX_MAX_BA_TID_NUM; i++) -+ (prStaRec->aprRxReorderParamRefTbl)[i] = NULL; -+#endif -+ -+ DBGLOG(QM, TRACE, "QM: +STA[%u]\n", (UINT_32) prStaRec->ucIndex); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Deactivate a STA_REC -+* -+* \param[in] prAdapter Pointer to the Adapter instance -+* \param[in] u4StaRecIdx The index of the STA_REC -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID qmDeactivateStaRec(IN P_ADAPTER_T prAdapter, IN UINT_32 u4StaRecIdx) -+{ -+ P_STA_RECORD_T prStaRec; -+ UINT_32 i; -+ P_MSDU_INFO_T prFlushedTxPacketList = NULL; -+ -+ ASSERT(u4StaRecIdx < CFG_NUM_OF_STA_RECORD); -+ -+ prStaRec = &prAdapter->arStaRec[u4StaRecIdx]; -+ ASSERT(prStaRec); -+ -+ /* 4<1> Flush TX queues */ -+ prFlushedTxPacketList = qmFlushStaTxQueues(prAdapter, u4StaRecIdx); -+ -+ if (prFlushedTxPacketList) -+ wlanProcessQueuedMsduInfo(prAdapter, prFlushedTxPacketList); -+ /* 4 <2> Flush RX queues and delete RX BA agreements */ -+ for (i = 0; i < CFG_RX_MAX_BA_TID_NUM; i++) { -+ /* Delete the RX BA entry with TID = i */ -+ qmDelRxBaEntry(prAdapter, (UINT_8) u4StaRecIdx, (UINT_8) i, FALSE); -+ } -+ -+ /* 4 <3> Deactivate the STA_REC */ -+ prStaRec->fgIsValid = FALSE; -+ prStaRec->fgIsInPS = FALSE; -+ -+ /* To reduce printk for IOT sta to connect all the time, */ -+ /* DBGLOG(QM, INFO, ("QM: -STA[%ld]\n", u4StaRecIdx)); */ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Deactivate a STA_REC -+* -+* \param[in] prAdapter Pointer to the Adapter instance -+* \param[in] u4StaRecIdx The index of the network -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+ -+VOID qmFreeAllByNetType(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx) -+{ -+ -+ P_QUE_MGT_T prQM; -+ P_QUE_T prQue; -+ QUE_T rNeedToFreeQue; -+ QUE_T rTempQue; -+ P_QUE_T prNeedToFreeQue; -+ P_QUE_T prTempQue; -+ P_MSDU_INFO_T prMsduInfo; -+ -+ prQM = &prAdapter->rQM; -+ prQue = &prQM->arTxQueue[TX_QUEUE_INDEX_BMCAST]; -+ -+ QUEUE_INITIALIZE(&rNeedToFreeQue); -+ QUEUE_INITIALIZE(&rTempQue); -+ -+ prNeedToFreeQue = &rNeedToFreeQue; -+ prTempQue = &rTempQue; -+ -+ QUEUE_MOVE_ALL(prTempQue, prQue); -+ -+ QUEUE_REMOVE_HEAD(prTempQue, prMsduInfo, P_MSDU_INFO_T); -+ while (prMsduInfo) { -+ -+ if (prMsduInfo->ucNetworkType == eNetworkTypeIdx) { -+ /* QUEUE_INSERT_TAIL */ -+ QUEUE_INSERT_TAIL(prNeedToFreeQue, (P_QUE_ENTRY_T) prMsduInfo); -+ } else { -+ /* QUEUE_INSERT_TAIL */ -+ QUEUE_INSERT_TAIL(prQue, (P_QUE_ENTRY_T) prMsduInfo); -+ } -+ -+ QUEUE_REMOVE_HEAD(prTempQue, prMsduInfo, P_MSDU_INFO_T); -+ } -+ if (QUEUE_IS_NOT_EMPTY(prNeedToFreeQue)) -+ wlanProcessQueuedMsduInfo(prAdapter, (P_MSDU_INFO_T) QUEUE_GET_HEAD(prNeedToFreeQue)); -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Flush all TX queues -+* -+* \param[in] (none) -+* -+* \return The flushed packets (in a list of MSDU_INFOs) -+*/ -+/*----------------------------------------------------------------------------*/ -+P_MSDU_INFO_T qmFlushTxQueues(IN P_ADAPTER_T prAdapter) -+{ -+ UINT_8 ucStaArrayIdx; -+ UINT_8 ucQueArrayIdx; -+ -+ P_MSDU_INFO_T prMsduInfoListHead; -+ P_MSDU_INFO_T prMsduInfoListTail; -+ -+ P_QUE_MGT_T prQM = &prAdapter->rQM; -+ -+ DBGLOG(QM, TRACE, "QM: Enter qmFlushTxQueues()\n"); -+ -+ prMsduInfoListHead = NULL; -+ prMsduInfoListTail = NULL; -+ -+ /* Concatenate all MSDU_INFOs in per-STA queues */ -+ for (ucStaArrayIdx = 0; ucStaArrayIdx < CFG_NUM_OF_STA_RECORD; ucStaArrayIdx++) { -+ -+ /* Always check each STA_REC when flushing packets no matter it is inactive or active */ -+#if 0 -+ if (!prAdapter->arStaRec[ucStaArrayIdx].fgIsValid) -+ continue; /* Continue to check the next STA_REC */ -+#endif -+ -+ for (ucQueArrayIdx = 0; ucQueArrayIdx < NUM_OF_PER_STA_TX_QUEUES; ucQueArrayIdx++) { -+ if (QUEUE_IS_EMPTY(&(prAdapter->arStaRec[ucStaArrayIdx].arTxQueue[ucQueArrayIdx]))) -+ continue; /* Continue to check the next TX queue of the same STA */ -+ -+ if (!prMsduInfoListHead) { -+ -+ /* The first MSDU_INFO is found */ -+ prMsduInfoListHead = (P_MSDU_INFO_T) -+ QUEUE_GET_HEAD(&prAdapter->arStaRec[ucStaArrayIdx].arTxQueue[ucQueArrayIdx]); -+ prMsduInfoListTail = (P_MSDU_INFO_T) -+ QUEUE_GET_TAIL(&prAdapter->arStaRec[ucStaArrayIdx].arTxQueue[ucQueArrayIdx]); -+ } else { -+ /* Concatenate the MSDU_INFO list with the existing list */ -+ QM_TX_SET_NEXT_MSDU_INFO(prMsduInfoListTail, -+ QUEUE_GET_HEAD(&prAdapter-> -+ arStaRec[ucStaArrayIdx].arTxQueue -+ [ucQueArrayIdx])); -+ -+ prMsduInfoListTail = (P_MSDU_INFO_T) -+ QUEUE_GET_TAIL(&prAdapter->arStaRec[ucStaArrayIdx].arTxQueue[ucQueArrayIdx]); -+ } -+ -+ QUEUE_INITIALIZE(&prAdapter->arStaRec[ucStaArrayIdx].arTxQueue[ucQueArrayIdx]); -+ } -+ } -+ -+ /* Flush per-Type queues */ -+ for (ucQueArrayIdx = 0; ucQueArrayIdx < NUM_OF_PER_TYPE_TX_QUEUES; ucQueArrayIdx++) { -+ -+ if (QUEUE_IS_EMPTY(&(prQM->arTxQueue[ucQueArrayIdx]))) -+ continue; /* Continue to check the next TX queue of the same STA */ -+ -+ if (!prMsduInfoListHead) { -+ -+ /* The first MSDU_INFO is found */ -+ prMsduInfoListHead = (P_MSDU_INFO_T) -+ QUEUE_GET_HEAD(&prQM->arTxQueue[ucQueArrayIdx]); -+ prMsduInfoListTail = (P_MSDU_INFO_T) -+ QUEUE_GET_TAIL(&prQM->arTxQueue[ucQueArrayIdx]); -+ } else { -+ /* Concatenate the MSDU_INFO list with the existing list */ -+ QM_TX_SET_NEXT_MSDU_INFO(prMsduInfoListTail, QUEUE_GET_HEAD(&prQM->arTxQueue[ucQueArrayIdx])); -+ -+ prMsduInfoListTail = (P_MSDU_INFO_T) -+ QUEUE_GET_TAIL(&prQM->arTxQueue[ucQueArrayIdx]); -+ } -+ -+ QUEUE_INITIALIZE(&prQM->arTxQueue[ucQueArrayIdx]); -+ -+ } -+ -+ if (prMsduInfoListTail) { -+ /* Terminate the MSDU_INFO list with a NULL pointer */ -+ QM_TX_SET_NEXT_MSDU_INFO(prMsduInfoListTail, NULL); -+ } -+ -+ return prMsduInfoListHead; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Flush TX packets for a particular STA -+* -+* \param[in] u4StaRecIdx STA_REC index -+* -+* \return The flushed packets (in a list of MSDU_INFOs) -+*/ -+/*----------------------------------------------------------------------------*/ -+P_MSDU_INFO_T qmFlushStaTxQueues(IN P_ADAPTER_T prAdapter, IN UINT_32 u4StaRecIdx) -+{ -+ UINT_8 ucQueArrayIdx; -+ P_MSDU_INFO_T prMsduInfoListHead; -+ P_MSDU_INFO_T prMsduInfoListTail; -+ P_STA_RECORD_T prStaRec; -+ -+ /* To reduce printk for IOT sta to connect all the time, */ -+ /* DBGLOG(QM, TRACE, ("QM: Enter qmFlushStaTxQueues(%ld)\n", u4StaRecIdx)); */ -+ -+ ASSERT(u4StaRecIdx < CFG_NUM_OF_STA_RECORD); -+ -+ prMsduInfoListHead = NULL; -+ prMsduInfoListTail = NULL; -+ -+ prStaRec = &prAdapter->arStaRec[u4StaRecIdx]; -+ ASSERT(prStaRec); -+ -+ /* No matter whether this is an activated STA_REC, do flush */ -+#if 0 -+ if (!prStaRec->fgIsValid) -+ return NULL; -+#endif -+ -+ /* Concatenate all MSDU_INFOs in TX queues of this STA_REC */ -+ for (ucQueArrayIdx = 0; ucQueArrayIdx < NUM_OF_PER_STA_TX_QUEUES; ucQueArrayIdx++) { -+ if (QUEUE_IS_EMPTY(&(prStaRec->arTxQueue[ucQueArrayIdx]))) -+ continue; -+ -+ if (!prMsduInfoListHead) { -+ /* The first MSDU_INFO is found */ -+ prMsduInfoListHead = (P_MSDU_INFO_T) -+ QUEUE_GET_HEAD(&prStaRec->arTxQueue[ucQueArrayIdx]); -+ prMsduInfoListTail = (P_MSDU_INFO_T) -+ QUEUE_GET_TAIL(&prStaRec->arTxQueue[ucQueArrayIdx]); -+ } else { -+ /* Concatenate the MSDU_INFO list with the existing list */ -+ QM_TX_SET_NEXT_MSDU_INFO(prMsduInfoListTail, -+ QUEUE_GET_HEAD(&prStaRec->arTxQueue[ucQueArrayIdx])); -+ -+ prMsduInfoListTail = (P_MSDU_INFO_T) QUEUE_GET_TAIL(&prStaRec->arTxQueue[ucQueArrayIdx]); -+ } -+ -+ QUEUE_INITIALIZE(&prStaRec->arTxQueue[ucQueArrayIdx]); -+ -+ } -+ -+#if 0 -+ if (prMsduInfoListTail) { -+ /* Terminate the MSDU_INFO list with a NULL pointer */ -+ QM_TX_SET_NEXT_MSDU_INFO(prMsduInfoListTail, nicGetPendingStaMMPDU(prAdapter, (UINT_8) u4StaRecIdx)); -+ } else { -+ prMsduInfoListHead = nicGetPendingStaMMPDU(prAdapter, (UINT_8) u4StaRecIdx); -+ } -+#endif -+ -+ return prMsduInfoListHead; -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Flush RX packets -+* -+* \param[in] (none) -+* -+* \return The flushed packets (in a list of SW_RFBs) -+*/ -+/*----------------------------------------------------------------------------*/ -+P_SW_RFB_T qmFlushRxQueues(IN P_ADAPTER_T prAdapter) -+{ -+ UINT_32 i; -+ P_SW_RFB_T prSwRfbListHead; -+ P_SW_RFB_T prSwRfbListTail; -+ P_QUE_MGT_T prQM = &prAdapter->rQM; -+ -+ prSwRfbListHead = prSwRfbListTail = NULL; -+ -+ DBGLOG(QM, TRACE, "QM: Enter qmFlushRxQueues()\n"); -+ -+ for (i = 0; i < CFG_NUM_OF_RX_BA_AGREEMENTS; i++) { -+ if (QUEUE_IS_NOT_EMPTY(&(prQM->arRxBaTable[i].rReOrderQue))) { -+ if (!prSwRfbListHead) { -+ -+ /* The first MSDU_INFO is found */ -+ prSwRfbListHead = (P_SW_RFB_T) -+ QUEUE_GET_HEAD(&(prQM->arRxBaTable[i].rReOrderQue)); -+ prSwRfbListTail = (P_SW_RFB_T) -+ QUEUE_GET_TAIL(&(prQM->arRxBaTable[i].rReOrderQue)); -+ } else { -+ /* Concatenate the MSDU_INFO list with the existing list */ -+ QM_TX_SET_NEXT_MSDU_INFO(prSwRfbListTail, -+ QUEUE_GET_HEAD(&(prQM->arRxBaTable[i].rReOrderQue))); -+ -+ prSwRfbListTail = (P_SW_RFB_T) -+ QUEUE_GET_TAIL(&(prQM->arRxBaTable[i].rReOrderQue)); -+ } -+ -+ QUEUE_INITIALIZE(&(prQM->arRxBaTable[i].rReOrderQue)); -+ -+ } else { -+ continue; -+ } -+ } -+ -+ if (prSwRfbListTail) { -+ /* Terminate the MSDU_INFO list with a NULL pointer */ -+ QM_TX_SET_NEXT_SW_RFB(prSwRfbListTail, NULL); -+ } -+ return prSwRfbListHead; -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Flush RX packets with respect to a particular STA -+* -+* \param[in] u4StaRecIdx STA_REC index -+* \param[in] u4Tid TID -+* -+* \return The flushed packets (in a list of SW_RFBs) -+*/ -+/*----------------------------------------------------------------------------*/ -+P_SW_RFB_T qmFlushStaRxQueue(IN P_ADAPTER_T prAdapter, IN UINT_32 u4StaRecIdx, IN UINT_32 u4Tid) -+{ -+ /* UINT_32 i; */ -+ P_SW_RFB_T prSwRfbListHead; -+ P_SW_RFB_T prSwRfbListTail; -+ P_RX_BA_ENTRY_T prReorderQueParm; -+ P_STA_RECORD_T prStaRec; -+ -+ DBGLOG(QM, TRACE, "QM: Enter qmFlushStaRxQueues(%u)\n", u4StaRecIdx); -+ -+ prSwRfbListHead = prSwRfbListTail = NULL; -+ -+ prStaRec = &prAdapter->arStaRec[u4StaRecIdx]; -+ ASSERT(prStaRec); -+ -+ /* No matter whether this is an activated STA_REC, do flush */ -+#if 0 -+ if (!prStaRec->fgIsValid) -+ return NULL; -+#endif -+ -+ /* Obtain the RX BA Entry pointer */ -+ prReorderQueParm = ((prStaRec->aprRxReorderParamRefTbl)[u4Tid]); -+ -+ /* Note: For each queued packet, prCurrSwRfb->eDst equals RX_PKT_DESTINATION_HOST */ -+ if (prReorderQueParm) { -+ -+ if (QUEUE_IS_NOT_EMPTY(&(prReorderQueParm->rReOrderQue))) { -+ -+ prSwRfbListHead = (P_SW_RFB_T) -+ QUEUE_GET_HEAD(&(prReorderQueParm->rReOrderQue)); -+ prSwRfbListTail = (P_SW_RFB_T) -+ QUEUE_GET_TAIL(&(prReorderQueParm->rReOrderQue)); -+ -+ QUEUE_INITIALIZE(&(prReorderQueParm->rReOrderQue)); -+ -+ } -+ } -+ -+ if (prSwRfbListTail) { -+ /* Terminate the MSDU_INFO list with a NULL pointer */ -+ QM_TX_SET_NEXT_SW_RFB(prSwRfbListTail, NULL); -+ } -+ return prSwRfbListHead; -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Enqueue TX packets -+* -+* \param[in] prMsduInfoListHead Pointer to the list of TX packets -+* -+* \return The freed packets, which are not enqueued -+*/ -+/*----------------------------------------------------------------------------*/ -+P_MSDU_INFO_T qmEnqueueTxPackets(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfoListHead) -+{ -+ P_MSDU_INFO_T prMsduInfoReleaseList; -+ P_MSDU_INFO_T prCurrentMsduInfo; -+ P_MSDU_INFO_T prNextMsduInfo; -+ -+ P_STA_RECORD_T prStaRec; -+ QUE_T rNotEnqueuedQue; -+ P_QUE_T prTxQue = &rNotEnqueuedQue; -+ -+ UINT_8 ucPacketType; -+ UINT_8 ucTC; -+ P_QUE_MGT_T prQM = &prAdapter->rQM; -+ UINT_8 aucNextUP[WMM_AC_INDEX_NUM] = { 1 /* BEtoBK */ , 1 /*na */ , 0 /*VItoBE */ , 4 /*VOtoVI */ }; -+ -+ DBGLOG(QM, LOUD, "Enter qmEnqueueTxPackets\n"); -+ -+ ASSERT(prMsduInfoListHead); -+ -+#if QM_ADAPTIVE_TC_RESOURCE_CTRL -+ { -+ /* UINT_32 i; */ -+ /* 4 <0> Update TC resource control related variables */ -+ /* Keep track of the queue length */ -+ if (--prQM->u4TimeToUpdateQueLen == 0) { /* -- only here */ -+ prQM->u4TimeToUpdateQueLen = QM_INIT_TIME_TO_UPDATE_QUE_LEN; -+ qmUpdateAverageTxQueLen(prAdapter); -+ } -+ } -+#endif -+ -+ /* Push TX packets into STA_REC (for UNICAST) or prAdapter->rQM (for BMCAST) */ -+ prStaRec = NULL; -+ prMsduInfoReleaseList = NULL; -+ prCurrentMsduInfo = NULL; -+ QUEUE_INITIALIZE(&rNotEnqueuedQue); -+ prNextMsduInfo = prMsduInfoListHead; -+ -+ do { -+ P_BSS_INFO_T prBssInfo; -+ BOOLEAN fgCheckACMAgain; -+ ENUM_WMM_ACI_T eAci = WMM_AC_BE_INDEX; -+ -+ prCurrentMsduInfo = prNextMsduInfo; -+ prNextMsduInfo = QM_TX_GET_NEXT_MSDU_INFO(prCurrentMsduInfo); -+ ucTC = TC1_INDEX; -+ -+ /* 4 <1> Lookup the STA_REC index */ -+ /* The ucStaRecIndex will be set in this function */ -+ qmDetermineStaRecIndex(prAdapter, prCurrentMsduInfo); -+ ucPacketType = HIF_TX_PACKET_TYPE_DATA; -+ -+ STATS_ENV_REPORT_DETECT(prAdapter, prCurrentMsduInfo->ucStaRecIndex); -+ -+ DBGLOG(QM, LOUD, "***** ucStaRecIndex = %d *****\n", prCurrentMsduInfo->ucStaRecIndex); -+ -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prCurrentMsduInfo->ucNetworkType]); -+ -+#if (CONF_HIF_LOOPBACK_AUTO == 0) -+ if (IS_NET_ACTIVE(prAdapter, prCurrentMsduInfo->ucNetworkType)) { -+#else -+ /* force to send the loopback test packet */ -+ if (1) { -+ SET_NET_ACTIVE(prAdapter, prCurrentMsduInfo->ucNetworkType); -+ prCurrentMsduInfo->ucStaRecIndex = STA_REC_INDEX_BMCAST; -+ ucPacketType = HIF_TX_PKT_TYPE_HIF_LOOPBACK; -+#endif /* End of CONF_HIF_LOOPBACK_AUTO */ -+ -+ switch (prCurrentMsduInfo->ucStaRecIndex) { -+ case STA_REC_INDEX_BMCAST: -+ prTxQue = &prQM->arTxQueue[TX_QUEUE_INDEX_BMCAST]; -+ ucTC = TC5_INDEX; -+#if 0 -+ if (prCurrentMsduInfo->ucNetworkType == NETWORK_TYPE_P2P_INDEX -+ && prCurrentMsduInfo->eSrc != TX_PACKET_MGMT) { -+ if (LINK_IS_EMPTY -+ (&prAdapter->rWifiVar. -+ arBssInfo[NETWORK_TYPE_P2P_INDEX].rStaRecOfClientList)) { -+ prTxQue = &rNotEnqueuedQue; -+ TX_INC_CNT(&prAdapter->rTxCtrl, TX_AP_BORADCAST_DROP); -+ } -+ } -+#endif -+ -+ QM_DBG_CNT_INC(prQM, QM_DBG_CNT_23); -+ break; -+ -+ case STA_REC_INDEX_NOT_FOUND: -+ ucTC = TC5_INDEX; -+ -+ if (prCurrentMsduInfo->eSrc == TX_PACKET_FORWARDING) { -+ -+ /* if the packet is the forward type. the packet should be freed */ -+ DBGLOG(QM, TRACE, "Forwarding packet but Sta is STA_REC_INDEX_NOT_FOUND\n"); -+ /* prTxQue = &rNotEnqueuedQue; */ -+ } -+ prTxQue = &prQM->arTxQueue[TX_QUEUE_INDEX_NO_STA_REC]; -+ QM_DBG_CNT_INC(prQM, QM_DBG_CNT_24); -+ -+ break; -+ -+ default: -+ prStaRec = QM_GET_STA_REC_PTR_FROM_INDEX(prAdapter, prCurrentMsduInfo->ucStaRecIndex); -+ -+ if (!prStaRec) { -+ DBGLOG(QM, ERROR, "prStaRec is NULL\n"); -+ break; -+ } -+ ASSERT(prStaRec->fgIsValid); -+ -+ if (prCurrentMsduInfo->ucUserPriority < 8) { -+ QM_DBG_CNT_INC(prQM, prCurrentMsduInfo->ucUserPriority + 15); -+ /* QM_DBG_CNT_15 *//* QM_DBG_CNT_16 *//* QM_DBG_CNT_17 *//* QM_DBG_CNT_18 */ -+ /* QM_DBG_CNT_19 *//* QM_DBG_CNT_20 *//* QM_DBG_CNT_21 *//* QM_DBG_CNT_22 */ -+ } -+ -+ eAci = WMM_AC_BE_INDEX; -+ do { -+ fgCheckACMAgain = FALSE; -+ if (!prStaRec->fgIsQoS) { -+ prTxQue = &prStaRec->arTxQueue[TX_QUEUE_INDEX_AC1]; -+ ucTC = TC1_INDEX; -+ break; -+ } -+ -+ switch (prCurrentMsduInfo->ucUserPriority) { -+ case 1: -+ case 2: -+ prTxQue = &prStaRec->arTxQueue[TX_QUEUE_INDEX_AC0]; -+ ucTC = TC0_INDEX; -+ eAci = WMM_AC_BK_INDEX; -+ break; -+ case 0: -+ case 3: -+ prTxQue = &prStaRec->arTxQueue[TX_QUEUE_INDEX_AC1]; -+ ucTC = TC1_INDEX; -+ eAci = WMM_AC_BE_INDEX; -+ break; -+ case 4: -+ case 5: -+ prTxQue = &prStaRec->arTxQueue[TX_QUEUE_INDEX_AC2]; -+ ucTC = TC2_INDEX; -+ eAci = WMM_AC_VI_INDEX; -+#if QM_ADAPTIVE_TC_RESOURCE_CTRL -+ prQM->u4TxNumOfVi++; -+#endif -+ break; -+ case 6: -+ case 7: -+ prTxQue = &prStaRec->arTxQueue[TX_QUEUE_INDEX_AC3]; -+ ucTC = TC3_INDEX; -+ eAci = WMM_AC_VO_INDEX; -+#if QM_ADAPTIVE_TC_RESOURCE_CTRL -+ prQM->u4TxNumOfVo++; -+#endif -+ break; -+ default: -+ prTxQue = &prStaRec->arTxQueue[TX_QUEUE_INDEX_AC1]; -+ ucTC = TC1_INDEX; -+ eAci = WMM_AC_BE_INDEX; -+ ASSERT(0); -+ break; -+ } -+ if (prBssInfo->arACQueParms[eAci].fgIsACMSet && eAci -+ != WMM_AC_BK_INDEX) { -+ prCurrentMsduInfo->ucUserPriority = aucNextUP[eAci]; -+ fgCheckACMAgain = TRUE; -+ } -+ } while (fgCheckACMAgain); -+ -+ /* LOG_FUNC ("QoS %u UP %u TC %u", */ -+ /* prStaRec->fgIsQoS,prCurrentMsduInfo->ucUserPriority, ucTC); */ -+ -+#if QM_ADAPTIVE_TC_RESOURCE_CTRL -+ /* -+ In TDLS or AP mode, peer maybe enter "sleep mode". -+ -+ If QM_INIT_TIME_TO_UPDATE_QUE_LEN = 60 when peer is in sleep mode, -+ we need to wait 60 * u4TimeToAdjustTcResource = 180 packets -+ u4TimeToAdjustTcResource = 3, -+ then we will adjust TC resouce for VI or VO. -+ -+ But in TDLS test case, the throughput is very low, only 0.8Mbps in 5.7, -+ we will to wait about 12 seconds to collect 180 packets. -+ but the test time is only 20 seconds. -+ */ -+ if ((prQM->u4TxNumOfVi == 10) || (prQM->u4TxNumOfVo == 10)) { -+ /* force to do TC resouce update */ -+ prQM->u4TimeToUpdateQueLen = QM_INIT_TIME_TO_UPDATE_QUE_LEN_MIN; -+ prQM->u4TimeToAdjustTcResource = 1; -+ } -+#endif -+#if ARP_MONITER_ENABLE -+ if (IS_STA_IN_AIS(prStaRec) && prCurrentMsduInfo->eSrc == TX_PACKET_OS) -+ qmDetectArpNoResponse(prAdapter, prCurrentMsduInfo); -+#endif -+ -+ break; /*default */ -+ } /* switch (prCurrentMsduInfo->ucStaRecIndex) */ -+ -+ if (prCurrentMsduInfo->eSrc == TX_PACKET_FORWARDING) { -+ if (prTxQue->u4NumElem > 32) { -+ DBGLOG(QM, WARN, -+ "Drop the Packet for full Tx queue (forwarding) Bss %u\n", -+ prCurrentMsduInfo->ucNetworkType); -+ prTxQue = &rNotEnqueuedQue; -+ TX_INC_CNT(&prAdapter->rTxCtrl, TX_FORWARD_OVERFLOW_DROP); -+ } -+ } -+ -+ } else { -+ -+ DBGLOG(QM, WARN, "Drop the Packet for inactive Bss %u\n", prCurrentMsduInfo->ucNetworkType); -+ QM_DBG_CNT_INC(prQM, QM_DBG_CNT_31); -+ prTxQue = &rNotEnqueuedQue; -+ TX_INC_CNT(&prAdapter->rTxCtrl, TX_INACTIVE_BSS_DROP); -+ } -+ -+ /* 4 <3> Fill the MSDU_INFO for constructing HIF TX header */ -+ -+ /* TODO: Fill MSDU_INFO according to the network type, -+ * EtherType, and STA status (for PS forwarding control). -+ */ -+ -+ /* Note that the Network Type Index and STA_REC index are determined in -+ * qmDetermineStaRecIndex(prCurrentMsduInfo). -+ */ -+ QM_TX_SET_MSDU_INFO_FOR_DATA_PACKET(prCurrentMsduInfo, /* MSDU_INFO ptr */ -+ ucTC, /* TC tag */ -+ ucPacketType, /* Packet Type */ -+ 0, /* Format ID */ -+ prCurrentMsduInfo->fgIs802_1x, /* Flag 802.1x */ -+ prCurrentMsduInfo->fgIs802_11, /* Flag 802.11 */ -+ 0, /* PAL LLH */ -+ 0, /* ACL SN */ -+ PS_FORWARDING_TYPE_NON_PS, /* PS Forwarding Type */ -+ 0 /* PS Session ID */ -+ ); -+ -+ /* 4 <4> Enqueue the packet to different AC queue (max 5 AC queues) */ -+ QUEUE_INSERT_TAIL(prTxQue, (P_QUE_ENTRY_T) prCurrentMsduInfo); -+ -+ if (prTxQue != &rNotEnqueuedQue) { -+ prQM->u4EnqeueuCounter++; -+ prQM->au4ResourceWantedCounter[ucTC]++; -+ } -+ if (prStaRec) -+ prStaRec->u4EnqeueuCounter++; -+ -+#if QM_TC_RESOURCE_EMPTY_COUNTER -+ { -+ P_TX_CTRL_T prTxCtrl = &prAdapter->rTxCtrl; -+ -+ if (prTxCtrl->rTc.aucFreeBufferCount[ucTC] == 0) { -+ prQM->au4QmTcResourceEmptyCounter[prCurrentMsduInfo->ucNetworkType][ucTC]++; -+ /* -+ DBGLOG(QM, TRACE, ("TC%d Q Empty Count: [%d]%ld\n", -+ ucTC, -+ prCurrentMsduInfo->ucNetworkType, -+ prQM->au4QmTcResourceEmptyCounter[prCurrentMsduInfo->ucNetworkType][ucTC])); -+ */ -+ } -+ -+ } -+#endif -+ -+#if QM_TEST_MODE -+ if (++prQM->u4PktCount == QM_TEST_TRIGGER_TX_COUNT) { -+ prQM->u4PktCount = 0; -+ qmTestCases(prAdapter); -+ } -+#endif -+ -+ DBGLOG(QM, LOUD, "Current queue length = %u\n", prTxQue->u4NumElem); -+ } while (prNextMsduInfo); -+ -+ if (QUEUE_IS_NOT_EMPTY(&rNotEnqueuedQue)) { -+ QM_TX_SET_NEXT_MSDU_INFO((P_MSDU_INFO_T) QUEUE_GET_TAIL(&rNotEnqueuedQue), NULL); -+ prMsduInfoReleaseList = (P_MSDU_INFO_T) QUEUE_GET_HEAD(&rNotEnqueuedQue); -+ } -+ -+ return prMsduInfoReleaseList; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Determine the STA_REC index for a packet -+* -+* \param[in] prMsduInfo Pointer to the packet -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+static VOID qmDetermineStaRecIndex(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo) -+{ -+ UINT_32 i; -+ -+ P_STA_RECORD_T prTempStaRec; -+ /* P_QUE_MGT_T prQM = &prAdapter->rQM; */ -+ -+ prTempStaRec = NULL; -+ -+ ASSERT(prMsduInfo); -+ -+ /* 4 <1> DA = BMCAST */ -+ if (IS_BMCAST_MAC_ADDR(prMsduInfo->aucEthDestAddr)) { -+ /* For intrastructure mode and P2P (playing as a GC), BMCAST frames shall be sent to the AP. -+ * FW shall take care of this. The host driver is not able to distinguish these cases. */ -+ prMsduInfo->ucStaRecIndex = STA_REC_INDEX_BMCAST; -+ DBGLOG(QM, LOUD, "TX with DA = BMCAST\n"); -+ return; -+ } -+#if (CFG_SUPPORT_TDLS == 1) -+ /* Check if the peer is TDLS one */ -+ if (TdlsexStaRecIdxGet(prAdapter, prMsduInfo) == TDLS_STATUS_SUCCESS) -+ return; /* find a TDLS record */ -+#endif /* CFG_SUPPORT_TDLS */ -+ -+ /* 4 <2> Check if an AP STA is present */ -+ for (i = 0; i < CFG_NUM_OF_STA_RECORD; i++) { -+ prTempStaRec = &(prAdapter->arStaRec[i]); -+ -+ if ((prTempStaRec->ucNetTypeIndex == prMsduInfo->ucNetworkType) -+ && (prTempStaRec->fgIsAp) -+ && (prTempStaRec->fgIsValid)) { -+ prMsduInfo->ucStaRecIndex = prTempStaRec->ucIndex; -+ return; -+ } -+ } -+ -+ /* 4 <3> Not BMCAST, No AP --> Compare DA (i.e., to see whether this is a unicast frame to a client) */ -+ for (i = 0; i < CFG_NUM_OF_STA_RECORD; i++) { -+ prTempStaRec = &(prAdapter->arStaRec[i]); -+ if (prTempStaRec->fgIsValid) { -+ if (EQUAL_MAC_ADDR(prTempStaRec->aucMacAddr, prMsduInfo->aucEthDestAddr)) { -+ prMsduInfo->ucStaRecIndex = prTempStaRec->ucIndex; -+ return; -+ } -+ } -+ } -+ -+ /* 4 <4> No STA found, Not BMCAST --> Indicate NOT_FOUND to FW */ -+ prMsduInfo->ucStaRecIndex = STA_REC_INDEX_NOT_FOUND; -+ DBGLOG(QM, LOUD, "QM: TX with STA_REC_INDEX_NOT_FOUND\n"); -+ -+#if (QM_TEST_MODE && QM_TEST_FAIR_FORWARDING) -+ prMsduInfo->ucStaRecIndex = (UINT_8) prQM->u4CurrentStaRecIndexToEnqueue; -+#endif -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Dequeue TX packets from a STA_REC for a particular TC -+* -+* \param[out] prQue The queue to put the dequeued packets -+* \param[in] ucTC The TC index (TC0_INDEX to TC5_INDEX) -+* \param[in] ucMaxNum The maximum amount of dequeued packets -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+static VOID -+qmDequeueTxPacketsFromPerStaQueues(IN P_ADAPTER_T prAdapter, -+ OUT P_QUE_T prQue, IN UINT_8 ucTC, IN UINT_8 ucCurrentQuota, IN UINT_8 ucTotalQuota) -+{ -+ -+#if QM_FORWARDING_FAIRNESS -+ UINT_32 i; /* Loop for */ -+ -+ PUINT_32 pu4HeadStaRecIndex; /* The Head STA index */ -+ PUINT_32 pu4HeadStaRecForwardCount; /* The total forwarded packets for the head STA */ -+ -+ P_STA_RECORD_T prStaRec; /* The current focused STA */ -+ P_BSS_INFO_T prBssInfo; /* The Bss for current focused STA */ -+ P_QUE_T prCurrQueue; /* The current TX queue to dequeue */ -+ P_MSDU_INFO_T prDequeuedPkt; /* The dequeued packet */ -+ -+ UINT_32 u4ForwardCount; /* To remember the total forwarded packets for a STA */ -+ UINT_32 u4MaxForwardCount; /* The maximum number of packets a STA can forward */ -+ UINT_32 u4Resource; /* The TX resource amount */ -+ -+ BOOLEAN fgChangeHeadSta; /* Whether a new head STA shall be determined at the end of the function */ -+ P_QUE_MGT_T prQM = &prAdapter->rQM; -+ -+ PUINT_8 pucFreeQuota = NULL; -+#if CFG_ENABLE_WIFI_DIRECT -+ P_P2P_CHNL_REQ_INFO_T prChnlReqInfo = &prAdapter->rWifiVar.prP2pFsmInfo->rChnlReqInfo; -+ /*NFC Beam + Indication */ -+#endif -+ DBGLOG(QM, LOUD, "Enter qmDequeueTxPacketsFromPerStaQueues (TC = %u)\n", ucTC); -+ -+ ASSERT(ucTC == TC0_INDEX || ucTC == TC1_INDEX || ucTC == TC2_INDEX || ucTC == TC3_INDEX || ucTC == TC4_INDEX); -+ -+ if (!ucCurrentQuota) { -+ prQM->au4DequeueNoTcResourceCounter[ucTC]++; -+ DBGLOG(TX, LOUD, "@@@@@ TC = %u ucCurrentQuota = %u @@@@@\n", ucTC, ucCurrentQuota); -+ return; -+ } -+ -+ u4Resource = ucCurrentQuota; -+ -+ /* 4 <1> Determine the head STA */ -+ /* The head STA shall be an active STA */ -+ -+ pu4HeadStaRecIndex = &(prQM->au4HeadStaRecIndex[ucTC]); -+ pu4HeadStaRecForwardCount = &(prQM->au4ForwardCount[ucTC]); -+ -+ DBGLOG(QM, LOUD, "(Fairness) TID = %u Init Head STA = %u Resource = %u\n", -+ ucTC, *pu4HeadStaRecIndex, u4Resource); -+ -+ /* From STA[x] to STA[x+1] to STA[x+2] to ... to STA[x] */ -+ for (i = 0; i < CFG_NUM_OF_STA_RECORD + 1; i++) { -+ prStaRec = &prAdapter->arStaRec[(*pu4HeadStaRecIndex)]; -+ ASSERT(prStaRec); -+ -+ /* Only Data frame (1x was not included) will be queued in */ -+ if (prStaRec->fgIsValid) { -+ -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]); -+ -+ ASSERT(prBssInfo->ucNetTypeIndex == prStaRec->ucNetTypeIndex); -+ -+ /* Determine how many packets the head STA is allowed to send in a round */ -+ -+ QM_DBG_CNT_INC(prQM, QM_DBG_CNT_25); -+ u4MaxForwardCount = ucTotalQuota; -+#if CFG_ENABLE_WIFI_DIRECT -+ -+ pucFreeQuota = NULL; -+ if (prStaRec->fgIsInPS && (ucTC != TC4_INDEX)) { -+ /* TODO: Change the threshold in coorperation with the PS forwarding mechanism */ -+ /* u4MaxForwardCount = ucTotalQuota; */ -+ /* Per STA flow control when STA in PS mode */ -+ /* The PHASE 1: only update from ucFreeQuota (now) */ -+ /* XXX The PHASE 2: Decide by ucFreeQuota and ucBmpDeliveryAC (per queue ) */ -+ /* aucFreeQuotaPerQueue[] */ -+ /* NOTE: other method to set u4Resource */ -+ -+ if (prStaRec->fgIsQoS && prStaRec->fgIsUapsdSupported -+ /* && prAdapter->rWifiVar.fgSupportQoS -+ && prAdapter->rWifiVar.fgSupportUAPSD */) { -+ -+ if (prStaRec->ucBmpTriggerAC & BIT(ucTC)) { -+ u4MaxForwardCount = prStaRec->ucFreeQuotaForDelivery; -+ pucFreeQuota = &prStaRec->ucFreeQuotaForDelivery; -+ } else { -+ u4MaxForwardCount = prStaRec->ucFreeQuotaForNonDelivery; -+ pucFreeQuota = &prStaRec->ucFreeQuotaForNonDelivery; -+ } -+ -+ } else { -+ ASSERT(prStaRec->ucFreeQuotaForDelivery == 0); -+ u4MaxForwardCount = prStaRec->ucFreeQuotaForNonDelivery; -+ pucFreeQuota = &prStaRec->ucFreeQuotaForNonDelivery; -+ } -+ -+ } /* fgIsInPS */ -+#endif /* CFG_ENABLE_WIFI_DIRECT */ -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ -+ /*NFC Beam + Indication */ -+ -+ if (prBssInfo->fgIsNetAbsent && (ucTC != TC4_INDEX)) { -+ if (prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT) { -+ if ((prChnlReqInfo->NFC_BEAM != 1) && -+ (u4MaxForwardCount > prBssInfo->ucBssFreeQuota)) -+ u4MaxForwardCount = prBssInfo->ucBssFreeQuota; -+ } else { -+ if (u4MaxForwardCount > prBssInfo->ucBssFreeQuota) -+ u4MaxForwardCount = prBssInfo->ucBssFreeQuota; -+ } -+ } -+#endif /* CFG_ENABLE_WIFI_DIRECT */ -+ -+ /* Determine whether the head STA can continue to forward packets in this round */ -+ if ((*pu4HeadStaRecForwardCount) < u4MaxForwardCount) -+ break; -+ -+ } /* prStaRec->fgIsValid */ -+ else { -+ /* The current Head STA has been deactivated, so search for a new head STA */ -+ prStaRec = NULL; -+ prBssInfo = NULL; -+ (*pu4HeadStaRecIndex)++; -+ (*pu4HeadStaRecIndex) %= CFG_NUM_OF_STA_RECORD; -+ -+ /* Reset the forwarding count before searching (since this is for a new selected STA) */ -+ (*pu4HeadStaRecForwardCount) = 0; -+ } -+ } /* i < CFG_NUM_OF_STA_RECORD + 1 */ -+ -+ /* All STA_RECs are inactive, so exit */ -+ if (!prStaRec) { -+ /* Under concurrent, it is possible that there is no candidcated STA. */ -+ /* DBGLOG(TX, EVENT, ("All STA_RECs are inactive\n")); */ -+ return; -+ } -+ -+ DBGLOG(QM, LOUD, "(Fairness) TID = %u Round Head STA = %u\n", ucTC, *pu4HeadStaRecIndex); -+ -+ /* 4 <2> Dequeue packets from the head STA */ -+ -+ prCurrQueue = &prStaRec->arTxQueue[ucTC]; -+ prDequeuedPkt = NULL; -+ fgChangeHeadSta = FALSE; -+ -+#if (CFG_SUPPORT_TDLS == 1) -+ if (pucFreeQuota != NULL) -+ TdlsexTxQuotaCheck(prAdapter->prGlueInfo, prStaRec, *pucFreeQuota); -+#endif /* CFG_SUPPORT_TDLS */ -+ -+ while (prCurrQueue) { -+ -+#if QM_DEBUG_COUNTER -+ -+ if (ucTC <= TC4_INDEX) { -+ if (QUEUE_IS_EMPTY(prCurrQueue)) { -+ QM_DBG_CNT_INC(prQM, ucTC); -+ /* QM_DBG_CNT_00 *//* QM_DBG_CNT_01 *//* QM_DBG_CNT_02 */ -+ /* QM_DBG_CNT_03 *//* QM_DBG_CNT_04 */ -+ } -+ if (u4Resource == 0) { -+ QM_DBG_CNT_INC(prQM, ucTC + 5); -+ /* QM_DBG_CNT_05 *//* QM_DBG_CNT_06 *//* QM_DBG_CNT_07 */ -+ /* QM_DBG_CNT_08 *//* QM_DBG_CNT_09 */ -+ } -+ if (((*pu4HeadStaRecForwardCount) >= u4MaxForwardCount)) { -+ QM_DBG_CNT_INC(prQM, ucTC + 10); -+ /* QM_DBG_CNT_10 *//* QM_DBG_CNT_11 *//* QM_DBG_CNT_12 */ -+ /* QM_DBG_CNT_13 *//* QM_DBG_CNT_14 */ -+ } -+ } -+#endif -+ -+ /* Three cases to break: (1) No resource (2) No packets (3) Fairness */ -+ if (QUEUE_IS_EMPTY(prCurrQueue) || ((*pu4HeadStaRecForwardCount) >= u4MaxForwardCount)) { -+ fgChangeHeadSta = TRUE; -+ break; -+ } else if (u4Resource == 0) { -+#if (CFG_SUPPORT_STATISTICS == 1) -+ prStaRec->u4NumOfNoTxQuota++; -+#endif /* CFG_SUPPORT_STATISTICS */ -+ break; -+ } -+ -+ QUEUE_REMOVE_HEAD(prCurrQueue, prDequeuedPkt, P_MSDU_INFO_T); -+ prStaRec->u4DeqeueuCounter++; -+ prQM->u4DequeueCounter++; -+ -+#if (CFG_SUPPORT_TDLS_DBG == 1) -+ if (prDequeuedPkt != NULL) { -+ struct sk_buff *prSkb = (struct sk_buff *)prDequeuedPkt->prPacket; -+ UINT8 *pkt = prSkb->data; -+ UINT16 u2Identifier; -+ -+ if ((*(pkt + 12) == 0x08) && (*(pkt + 13) == 0x00)) { -+ /* ip */ -+ u2Identifier = ((*(pkt + 18)) << 8) | (*(pkt + 19)); -+ DBGLOG(QM, LOUD, " %d\n", u2Identifier); -+ } -+ } -+#endif -+#if DBG && 0 -+ LOG_FUNC("Deq0 TC %d queued %u net %u mac len %u len %u Type %u 1x %u 11 %u\n", -+ prDequeuedPkt->ucTC, -+ prCurrQueue->u4NumElem, -+ prDequeuedPkt->ucNetworkType, -+ prDequeuedPkt->ucMacHeaderLength, -+ prDequeuedPkt->u2FrameLength, -+ prDequeuedPkt->ucPacketType, prDequeuedPkt->fgIs802_1x, prDequeuedPkt->fgIs802_11); -+ -+ LOG_FUNC("Dest Mac: %pM\n", prDequeuedPkt->aucEthDestAddr); -+ -+#if LINUX -+ { -+ struct sk_buff *prSkb = (struct sk_buff *)prDequeuedPkt->prPacket; -+ -+ dumpMemory8((PUINT_8) prSkb->data, prSkb->len); -+ } -+#endif -+ -+#endif -+ -+ ASSERT(prDequeuedPkt->ucTC == ucTC); -+ -+ if (!QUEUE_IS_EMPTY(prCurrQueue)) { -+ /* XXX: check all queues for STA */ -+ prDequeuedPkt->ucPsForwardingType = PS_FORWARDING_MORE_DATA_ENABLED; -+ } -+ -+ QUEUE_INSERT_TAIL(prQue, (P_QUE_ENTRY_T) prDequeuedPkt); -+ u4Resource--; -+ (*pu4HeadStaRecForwardCount)++; -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ /* XXX The PHASE 2: decrease from aucFreeQuotaPerQueue[] */ -+ if (prStaRec->fgIsInPS && (ucTC != TC4_INDEX)) { -+ if ((pucFreeQuota) && (*pucFreeQuota > 0)) -+ *pucFreeQuota = *pucFreeQuota - 1; -+ } -+#endif /* CFG_ENABLE_WIFI_DIRECT */ -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ if (prBssInfo->fgIsNetAbsent && (ucTC != TC4_INDEX)) { -+ if (prBssInfo->ucBssFreeQuota > 0) -+ prBssInfo->ucBssFreeQuota--; -+ } -+#endif /* CFG_ENABLE_WIFI_DIRECT */ -+ -+ } -+ -+ if (*pu4HeadStaRecForwardCount) { -+ DBGLOG(QM, LOUD, -+ "TC = %u Round Head STA = %u, u4HeadStaRecForwardCount = %u\n", ucTC, *pu4HeadStaRecIndex, -+ (*pu4HeadStaRecForwardCount)); -+ } -+#if QM_BURST_END_INFO_ENABLED -+ /* Let FW know which packet is the last one dequeued from the STA */ -+ if (prDequeuedPkt) -+ prDequeuedPkt->fgIsBurstEnd = TRUE; -+#endif -+ -+ /* 4 <3> Dequeue from the other STAs if there is residual TX resource */ -+ -+ /* Check all of the STAs to continue forwarding packets (including the head STA) */ -+ for (i = 0; i < CFG_NUM_OF_STA_RECORD; i++) { -+ /* Break in case no reasource is available */ -+ if (u4Resource == 0) { -+ prQM->au4DequeueNoTcResourceCounter[ucTC]++; -+ break; -+ } -+ -+ /* The current head STA will be examined when i = CFG_NUM_OF_STA_RECORD-1 */ -+ prStaRec = &prAdapter->arStaRec[((*pu4HeadStaRecIndex) + i + 1) % CFG_NUM_OF_STA_RECORD]; -+ ASSERT(prStaRec); -+ -+ if (prStaRec->fgIsValid) { -+ -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]); -+ ASSERT(prBssInfo->ucNetTypeIndex == prStaRec->ucNetTypeIndex); -+ -+ DBGLOG(QM, LOUD, "(Fairness) TID = %u Sharing STA = %u Resource = %u\n", -+ ucTC, prStaRec->ucIndex, u4Resource); -+ -+ prCurrQueue = &prStaRec->arTxQueue[ucTC]; -+ u4ForwardCount = 0; -+ u4MaxForwardCount = ucTotalQuota; -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ pucFreeQuota = NULL; -+ if (prStaRec->fgIsInPS && (ucTC != TC4_INDEX)) { -+ /* TODO: Change the threshold in coorperation with the PS forwarding mechanism */ -+ /* u4MaxForwardCount = ucTotalQuota; */ -+ /* Per STA flow control when STA in PS mode */ -+ /* The PHASE 1: only update from ucFreeQuota (now) */ -+ /* XXX The PHASE 2: Decide by ucFreeQuota and ucBmpDeliveryAC (per queue ) */ -+ /* aucFreeQuotaPerQueue[] */ -+ /* NOTE: other method to set u4Resource */ -+ if (prStaRec->fgIsQoS && prStaRec->fgIsUapsdSupported -+ /* && prAdapter->rWifiVar.fgSupportQoS -+ && prAdapter->rWifiVar.fgSupportUAPSD */) { -+ -+ if (prStaRec->ucBmpTriggerAC & BIT(ucTC)) { -+ u4MaxForwardCount = prStaRec->ucFreeQuotaForDelivery; -+ pucFreeQuota = &prStaRec->ucFreeQuotaForDelivery; -+ } else { -+ u4MaxForwardCount = prStaRec->ucFreeQuotaForNonDelivery; -+ pucFreeQuota = &prStaRec->ucFreeQuotaForNonDelivery; -+ } -+ -+ } else { -+ ASSERT(prStaRec->ucFreeQuotaForDelivery == 0); -+ u4MaxForwardCount = prStaRec->ucFreeQuotaForNonDelivery; -+ pucFreeQuota = &prStaRec->ucFreeQuotaForNonDelivery; -+ } -+ -+ } -+#endif /* CFG_ENABLE_WIFI_DIRECT */ -+#if CFG_ENABLE_WIFI_DIRECT -+ if (prBssInfo->fgIsNetAbsent && (ucTC != TC4_INDEX)) { -+ if (u4MaxForwardCount > prBssInfo->ucBssFreeQuota) -+ u4MaxForwardCount = prBssInfo->ucBssFreeQuota; -+ } -+#endif /* CFG_ENABLE_WIFI_DIRECT */ -+ } /* prStaRec->fgIsValid */ -+ else { -+ prBssInfo = NULL; -+ /* Invalid STA, so check the next STA */ -+ continue; -+ } -+ -+ while (prCurrQueue) { -+ /* Three cases to break: (1) No resource (2) No packets (3) Fairness */ -+ if ((u4Resource == 0) || QUEUE_IS_EMPTY(prCurrQueue) || (u4ForwardCount >= u4MaxForwardCount)) -+ break; -+ -+ -+ QUEUE_REMOVE_HEAD(prCurrQueue, prDequeuedPkt, P_MSDU_INFO_T); -+ -+#if DBG && 0 -+ DBGLOG(QM, LOUD, "Deq0 TC %d queued %u net %u mac len %u len %u Type %u 1x %u 11 %u\n", -+ prDequeuedPkt->ucTC, -+ prCurrQueue->u4NumElem, -+ prDequeuedPkt->ucNetworkType, -+ prDequeuedPkt->ucMacHeaderLength, -+ prDequeuedPkt->u2FrameLength, -+ prDequeuedPkt->ucPacketType, -+ prDequeuedPkt->fgIs802_1x, prDequeuedPkt->fgIs802_11)); -+ -+ DBGLOG(QM, LOUD, "Dest Mac: %pM\n", prDequeuedPkt->aucEthDestAddr); -+ -+#if LINUX -+ { -+ struct sk_buff *prSkb = (struct sk_buff *)prDequeuedPkt->prPacket; -+ -+ dumpMemory8((PUINT_8) prSkb->data, prSkb->len); -+ } -+#endif -+ -+#endif -+ -+ ASSERT(prDequeuedPkt->ucTC == ucTC); -+ -+ if (!QUEUE_IS_EMPTY(prCurrQueue)) -+ /* more data field ? */ -+ prDequeuedPkt->ucPsForwardingType = PS_FORWARDING_MORE_DATA_ENABLED; -+ -+ QUEUE_INSERT_TAIL(prQue, (P_QUE_ENTRY_T) prDequeuedPkt); -+ if (prStaRec) -+ prStaRec->u4DeqeueuCounter++; -+ prQM->u4DequeueCounter++; -+ u4Resource--; -+ u4ForwardCount++; -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ /* XXX The PHASE 2: decrease from aucFreeQuotaPerQueue[] */ -+ if (prStaRec->fgIsInPS && (ucTC != TC4_INDEX)) { -+ ASSERT(pucFreeQuota); -+ ASSERT(*pucFreeQuota > 0); -+ if (*pucFreeQuota > 0) -+ *pucFreeQuota = *pucFreeQuota - 1; -+ } -+#endif /* CFG_ENABLE_WIFI_DIRECT */ -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ ASSERT(prBssInfo->ucNetTypeIndex == prStaRec->ucNetTypeIndex); -+ if (prBssInfo->fgIsNetAbsent && (ucTC != TC4_INDEX)) { -+ if (prBssInfo->ucBssFreeQuota > 0) -+ prBssInfo->ucBssFreeQuota--; -+ } -+#endif /* CFG_ENABLE_WIFI_DIRECT */ -+ -+ } -+ -+#if QM_BURST_END_INFO_ENABLED -+ /* Let FW know which packet is the last one dequeued from the STA */ -+ if (u4ForwardCount) -+ prDequeuedPkt->fgIsBurstEnd = TRUE; -+#endif -+ } -+ -+ if (fgChangeHeadSta) { -+ (*pu4HeadStaRecIndex)++; -+ (*pu4HeadStaRecIndex) %= CFG_NUM_OF_STA_RECORD; -+ (*pu4HeadStaRecForwardCount) = 0; -+ DBGLOG(QM, LOUD, "(Fairness) TID = %u Scheduled Head STA = %u Left Resource = %u\n", -+ ucTC, (*pu4HeadStaRecIndex), u4Resource); -+ } -+ -+/***************************************************************************************/ -+#else -+ UINT_8 ucStaRecIndex; -+ P_STA_RECORD_T prStaRec; -+ P_QUE_T prCurrQueue; -+ UINT_8 ucPktCount; -+ P_MSDU_INFO_T prDequeuedPkt; -+ -+ DBGLOG(QM, LOUD, "Enter qmDequeueTxPacketsFromPerStaQueues (TC = %u)\n", ucTC); -+ -+ if (ucCurrentQuota == 0) -+ return; -+ /* 4 <1> Determine the queue index and the head STA */ -+ -+ /* The head STA */ -+ ucStaRecIndex = 0; /* TODO: Get the current head STA */ -+ prStaRec = QM_GET_STA_REC_PTR_FROM_INDEX(prAdapter, ucStaRecIndex); -+ ASSERT(prStaRec); -+ -+ if (prStaRec == NULL) -+ return; -+ -+ /* The queue to pull out packets */ -+ ASSERT(ucTC == TC0_INDEX || ucTC == TC1_INDEX || ucTC == TC2_INDEX || ucTC == TC3_INDEX || ucTC == TC4_INDEX); -+ prCurrQueue = &prStaRec->arTxQueue[ucTC]; -+ -+ ucPktCount = ucCurrentQuota; -+ prDequeuedPkt = NULL; -+ -+ /* 4 <2> Dequeue packets for the head STA */ -+ while (TRUE) { -+ if (!(prStaRec->fgIsValid) || ucPktCount == 0 || QUEUE_IS_EMPTY(prCurrQueue)) { -+ break; -+ -+ } else { -+ -+ QUEUE_REMOVE_HEAD(prCurrQueue, prDequeuedPkt, P_MSDU_INFO_T); -+ /* DbgPrint("QM: Remove Queue Head, TC= %d\n", prDequeuedPkt->ucTC); */ -+ ASSERT(prDequeuedPkt->ucTC == ucTC); -+ -+ QUEUE_INSERT_TAIL(prQue, (P_QUE_ENTRY_T) prDequeuedPkt); -+ ucPktCount--; -+ } -+ } -+ -+ /* DbgPrint("QM: Remaining number of queued packets = %d\n", prCurrQueue->u4NumElem); */ -+ -+#if QM_BURST_END_INFO_ENABLED -+ if (prDequeuedPkt) -+ prDequeuedPkt->fgIsBurstEnd = TRUE; -+#endif -+ -+ /* 4 <3> Update scheduling info */ -+ /* TODO */ -+ -+ /* 4 <4> Utilize the remainaing TX opportunities for non-head STAs */ -+ /* TODO */ -+#endif -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Dequeue TX packets from a per-Type-based Queue for a particular TC -+* -+* \param[out] prQue The queue to put the dequeued packets -+* \param[in] ucTC The TC index (Shall always be TC5_INDEX) -+* \param[in] ucMaxNum The maximum amount of dequeued packets -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+static VOID -+qmDequeueTxPacketsFromPerTypeQueues(IN P_ADAPTER_T prAdapter, OUT P_QUE_T prQue, IN UINT_8 ucTC, IN UINT_8 ucMaxNum) -+{ -+ /* UINT_8 ucQueIndex; */ -+ /* UINT_8 ucStaRecIndex; */ -+ P_BSS_INFO_T prBssInfo; -+ P_BSS_INFO_T parBssInfo; -+ P_QUE_T prCurrQueue; -+ UINT_8 ucPktCount; -+ P_MSDU_INFO_T prDequeuedPkt; -+ P_MSDU_INFO_T prBurstEndPkt; -+ QUE_T rMergeQue; -+ P_QUE_T prMergeQue; -+ P_QUE_MGT_T prQM; -+ -+ DBGLOG(QM, LOUD, "Enter qmDequeueTxPacketsFromPerTypeQueues (TC = %d, Max = %d)\n", ucTC, ucMaxNum); -+ -+ /* TC5: Broadcast/Multicast data packets */ -+ ASSERT(ucTC == TC5_INDEX); -+ -+ if (ucMaxNum == 0) -+ return; -+ -+ prQM = &prAdapter->rQM; -+ /* 4 <1> Determine the queue */ -+ -+ prCurrQueue = &prQM->arTxQueue[TX_QUEUE_INDEX_BMCAST]; -+ ucPktCount = ucMaxNum; -+ prDequeuedPkt = NULL; -+ prBurstEndPkt = NULL; -+ -+ parBssInfo = prAdapter->rWifiVar.arBssInfo; -+ -+ QUEUE_INITIALIZE(&rMergeQue); -+ prMergeQue = &rMergeQue; -+ -+ /* 4 <2> Dequeue packets */ -+ while (TRUE) { -+ if (ucPktCount == 0 || QUEUE_IS_EMPTY(prCurrQueue)) -+ break; -+ -+ QUEUE_REMOVE_HEAD(prCurrQueue, prDequeuedPkt, P_MSDU_INFO_T); -+ ASSERT(prDequeuedPkt->ucTC == ucTC); -+ -+ ASSERT(prDequeuedPkt->ucNetworkType < NETWORK_TYPE_INDEX_NUM); -+ -+ prBssInfo = &parBssInfo[prDequeuedPkt->ucNetworkType]; -+ -+ if (IS_BSS_ACTIVE(prBssInfo)) { -+ if (!prBssInfo->fgIsNetAbsent) { -+ QUEUE_INSERT_TAIL(prQue, (P_QUE_ENTRY_T) prDequeuedPkt); -+ prQM->u4DequeueCounter++; -+ prBurstEndPkt = prDequeuedPkt; -+ ucPktCount--; -+ QM_DBG_CNT_INC(prQM, QM_DBG_CNT_26); -+#if DBG && 0 -+ LOG_FUNC -+ ("DeqType TC %d queued %u net %u mac len %u len %u Type %u 1x %u 11 %u\n", -+ prDequeuedPkt->ucTC, prCurrQueue->u4NumElem, prDequeuedPkt->ucNetworkType, -+ prDequeuedPkt->ucMacHeaderLength, prDequeuedPkt->u2FrameLength, -+ prDequeuedPkt->ucPacketType, prDequeuedPkt->fgIs802_1x, -+ prDequeuedPkt->fgIs802_11); -+ -+ LOG_FUNC("Dest Mac: %pM\n", prDequeuedPkt->aucEthDestAddr); -+ -+#if LINUX -+ { -+ struct sk_buff *prSkb = (struct sk_buff *)prDequeuedPkt->prPacket; -+ -+ dumpMemory8((PUINT_8) prSkb->data, prSkb->len); -+ } -+#endif -+ -+#endif -+ } else { -+ QUEUE_INSERT_TAIL(prMergeQue, (P_QUE_ENTRY_T) prDequeuedPkt); -+ } -+ } else { -+ QM_TX_SET_NEXT_MSDU_INFO(prDequeuedPkt, NULL); -+ wlanProcessQueuedMsduInfo(prAdapter, prDequeuedPkt); -+ } -+ } -+ -+ if (QUEUE_IS_NOT_EMPTY(prMergeQue)) { -+ QUEUE_CONCATENATE_QUEUES(prMergeQue, prCurrQueue); -+ QUEUE_MOVE_ALL(prCurrQueue, prMergeQue); -+ if (QUEUE_GET_TAIL(prCurrQueue)) -+ QM_TX_SET_NEXT_MSDU_INFO((P_MSDU_INFO_T) QUEUE_GET_TAIL(prCurrQueue), NULL); -+ } -+#if QM_BURST_END_INFO_ENABLED -+ if (prBurstEndPkt) -+ prBurstEndPkt->fgIsBurstEnd = TRUE; -+#endif -+} /* qmDequeueTxPacketsFromPerTypeQueues */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Dequeue TX packets to send to HIF TX -+* -+* \param[in] prTcqStatus Info about the maximum amount of dequeued packets -+* -+* \return The list of dequeued TX packets -+*/ -+/*----------------------------------------------------------------------------*/ -+P_MSDU_INFO_T qmDequeueTxPackets(IN P_ADAPTER_T prAdapter, IN P_TX_TCQ_STATUS_T prTcqStatus) -+{ -+ -+ INT32 i; -+ P_MSDU_INFO_T prReturnedPacketListHead; -+ QUE_T rReturnedQue; -+ -+ DBGLOG(QM, LOUD, "Enter qmDequeueTxPackets\n"); -+ -+ QUEUE_INITIALIZE(&rReturnedQue); -+ -+ prReturnedPacketListHead = NULL; -+ -+ /* dequeue packets from different AC queue based on available aucFreeBufferCount */ -+ /* TC0 to TC4: AC0~AC3, 802.1x (commands packets are not handled by QM) */ -+ for (i = TC4_INDEX; i >= TC0_INDEX; i--) { -+ DBGLOG(QM, LOUD, "Dequeue packets from Per-STA queue[%d]\n", i); -+ -+ /* -+ in the function, we will re-calculate the ucFreeQuota. -+ If any packet with any priority for the station will be sent, ucFreeQuota -- -+ -+ Note1: ucFreeQuota will be decrease only when station is in power save mode. -+ In active mode, we will sent the packet to the air directly. -+ -+ if(prStaRec->fgIsInPS && (ucTC!=TC4_INDEX)) { -+ ASSERT(pucFreeQuota); -+ ASSERT(*pucFreeQuota>0); -+ if ((pucFreeQuota) && (*pucFreeQuota>0)) { -+ *pucFreeQuota = *pucFreeQuota - 1; -+ } -+ } -+ -+ Note2: maximum queued number for a station is 10, TXM_MAX_BUFFER_PER_STA_DEF in fw -+ i.e. default prStaRec->ucFreeQuota = 10 -+ -+ Note3: In qmUpdateFreeQuota(), we will adjust -+ ucFreeQuotaForNonDelivery = ucFreeQuota>>1; -+ ucFreeQuotaForDelivery = ucFreeQuota - ucFreeQuotaForNonDelivery; -+ */ -+ qmDequeueTxPacketsFromPerStaQueues(prAdapter, -+ &rReturnedQue, -+ (UINT_8) i, -+ prTcqStatus->aucFreeBufferCount[i], /* maximum dequeue number */ -+ prTcqStatus->aucMaxNumOfBuffer[i]); -+ -+ /* The aggregate number of dequeued packets */ -+ DBGLOG(QM, LOUD, "DQA)[%u](%u)\n", i, rReturnedQue.u4NumElem); -+ } -+ -+ /* TC5 (BMCAST or STA-NOT-FOUND packets) */ -+ qmDequeueTxPacketsFromPerTypeQueues(prAdapter, -+ &rReturnedQue, TC5_INDEX, prTcqStatus->aucFreeBufferCount[TC5_INDEX] -+ ); -+ -+ DBGLOG(QM, LOUD, "Current total number of dequeued packets = %u\n", rReturnedQue.u4NumElem); -+ -+ if (QUEUE_IS_NOT_EMPTY(&rReturnedQue)) { -+ prReturnedPacketListHead = (P_MSDU_INFO_T) QUEUE_GET_HEAD(&rReturnedQue); -+ QM_TX_SET_NEXT_MSDU_INFO((P_MSDU_INFO_T) QUEUE_GET_TAIL(&rReturnedQue), NULL); -+ } -+ -+ return prReturnedPacketListHead; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Adjust the TC quotas according to traffic demands -+* -+* \param[out] prTcqAdjust The resulting adjustment -+* \param[in] prTcqStatus Info about the current TC quotas and counters -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID qmAdjustTcQuotas(IN P_ADAPTER_T prAdapter, OUT P_TX_TCQ_ADJUST_T prTcqAdjust, IN P_TX_TCQ_STATUS_T prTcqStatus) -+{ -+#if QM_ADAPTIVE_TC_RESOURCE_CTRL -+ UINT_32 i; -+ P_QUE_MGT_T prQM = &prAdapter->rQM; -+ -+ /* Must reset */ -+ for (i = 0; i < TC_NUM; i++) -+ prTcqAdjust->acVariation[i] = 0; -+ -+ /* 4 <1> If TC resource is not just adjusted, exit directly */ -+ if (!prQM->fgTcResourcePostAnnealing) -+ return; -+ /* 4 <2> Adjust TcqStatus according to the updated prQM->au4CurrentTcResource */ -+ else { -+ INT_32 i4TotalExtraQuota = 0; -+ INT_32 ai4ExtraQuota[TC_NUM]; -+ BOOLEAN fgResourceRedistributed = TRUE; -+ -+ /* Obtain the free-to-distribute resource */ -+ for (i = 0; i < TC_NUM; i++) { -+ ai4ExtraQuota[i] = -+ (INT_32) prTcqStatus->aucMaxNumOfBuffer[i] - (INT_32) prQM->au4CurrentTcResource[i]; -+ -+ if (ai4ExtraQuota[i] > 0) { /* The resource shall be reallocated to other TCs */ -+ -+ if (ai4ExtraQuota[i] > prTcqStatus->aucFreeBufferCount[i]) { -+ /* -+ we have residunt TC resources for the TC: -+ EX: aucMaxNumOfBuffer[] = 20, au4CurrentTcResource[] = 5 -+ ai4ExtraQuota[] = 15, aucFreeBufferCount[] = 10 -+ -+ so ai4ExtraQuota[] = aucFreeBufferCount[] = 10 -+ because we available TC resources actually is 10, not 20 -+ */ -+ ai4ExtraQuota[i] = prTcqStatus->aucFreeBufferCount[i]; -+ -+ /* -+ FALSE means we can re-do TC resource adjustment in tx done -+ at next time, maybe more tx done is finished -+ */ -+ fgResourceRedistributed = FALSE; -+ } -+ -+ /* accumulate current all available TC resources */ -+ i4TotalExtraQuota += ai4ExtraQuota[i]; -+ -+ /* deduce unused TC resources for the TC */ -+ prTcqAdjust->acVariation[i] = (INT_8) (-ai4ExtraQuota[i]); -+ } -+ } -+ -+ /* Distribute quotas to TCs which need extra resource according to prQM->au4CurrentTcResource */ -+ for (i = 0; i < TC_NUM; i++) { -+ if (ai4ExtraQuota[i] < 0) { -+ -+ /* The TC needs extra resources */ -+ if ((-ai4ExtraQuota[i]) > i4TotalExtraQuota) { -+ /* the number of needed extra resources is larger than total available */ -+ ai4ExtraQuota[i] = (-i4TotalExtraQuota); -+ -+ /* wait for next tx done to do adjustment */ -+ fgResourceRedistributed = FALSE; -+ } -+ -+ /* decrease the total available */ -+ i4TotalExtraQuota += ai4ExtraQuota[i]; -+ -+ /* mark to increase TC resources for the TC */ -+ prTcqAdjust->acVariation[i] = (INT_8) (-ai4ExtraQuota[i]); -+ } -+ } -+ -+ /* In case some TC is waiting for TX Done, continue to adjust TC quotas upon TX Done */ -+ -+ /* -+ if fgResourceRedistributed == TRUE, it means we will adjust at this time so -+ we need to re-adjust TC resources (fgTcResourcePostAnnealing = FALSE). -+ */ -+ prQM->fgTcResourcePostAnnealing = (!fgResourceRedistributed); -+ -+#if QM_PRINT_TC_RESOURCE_CTRL -+ DBGLOG(QM, LOUD, "QM: Curr Quota [0]=%u [1]=%u [2]=%u [3]=%u [4]=%u [5]=%u\n", -+ prTcqStatus->aucFreeBufferCount[0], -+ prTcqStatus->aucFreeBufferCount[1], -+ prTcqStatus->aucFreeBufferCount[2], -+ prTcqStatus->aucFreeBufferCount[3], -+ prTcqStatus->aucFreeBufferCount[4], prTcqStatus->aucFreeBufferCount[5] -+ )); -+#endif -+ } -+ -+#else -+ UINT_32 i; -+ -+ for (i = 0; i < TC_NUM; i++) -+ prTcqAdjust->acVariation[i] = 0; -+ -+#endif -+} -+ -+#if QM_ADAPTIVE_TC_RESOURCE_CTRL -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Update the average TX queue length for the TC resource control mechanism -+* -+* \param (none) -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID qmUpdateAverageTxQueLen(IN P_ADAPTER_T prAdapter) -+{ -+ INT_32 u4CurrQueLen, i, k; -+ P_STA_RECORD_T prStaRec; -+ P_QUE_MGT_T prQM = &prAdapter->rQM; -+ -+ /* 4 <1> Update the queue lengths for TC0 to TC3 (skip TC4) and TC5 */ -+ /* use moving average algorithm to calculate au4AverageQueLen for every TC queue */ -+ for (i = 0; i < NUM_OF_PER_STA_TX_QUEUES - 1; i++) { -+ u4CurrQueLen = 0; -+ -+ for (k = 0; k < CFG_NUM_OF_STA_RECORD; k++) { -+ prStaRec = &prAdapter->arStaRec[k]; -+ ASSERT(prStaRec); -+ -+ /* If the STA is activated, get the queue length */ -+ if (prStaRec->fgIsValid && -+ (!prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex].fgIsNetAbsent) -+ ) { -+ -+ u4CurrQueLen += (prStaRec->arTxQueue[i].u4NumElem); -+ } -+ } -+ -+ if (prQM->au4AverageQueLen[i] == 0) { -+ prQM->au4AverageQueLen[i] = (u4CurrQueLen << QM_QUE_LEN_MOVING_AVE_FACTOR); /* *8 */ -+ } else { -+ /* len => len - len/8 = 7/8 * len + new len */ -+ prQM->au4AverageQueLen[i] -= (prQM->au4AverageQueLen[i] >> QM_QUE_LEN_MOVING_AVE_FACTOR); -+ prQM->au4AverageQueLen[i] += (u4CurrQueLen); -+ } -+ -+ } -+ -+ /* Update the queue length for TC5 (BMCAST) */ -+ u4CurrQueLen = prQM->arTxQueue[TX_QUEUE_INDEX_BMCAST].u4NumElem; -+ -+ if (prQM->au4AverageQueLen[TC_NUM - 1] == 0) { -+ prQM->au4AverageQueLen[TC_NUM - 1] = (u4CurrQueLen << QM_QUE_LEN_MOVING_AVE_FACTOR); -+ } else { -+ prQM->au4AverageQueLen[TC_NUM - 1] -= -+ (prQM->au4AverageQueLen[TC_NUM - 1] >> QM_QUE_LEN_MOVING_AVE_FACTOR); -+ prQM->au4AverageQueLen[TC_NUM - 1] += (u4CurrQueLen); -+ } -+ -+ /* 4 <2> Adjust TC resource assignment every 3 times */ -+ /* Check whether it is time to adjust the TC resource assignment */ -+ if (--prQM->u4TimeToAdjustTcResource == 0) { /* u4TimeToAdjustTcResource = 3 */ -+ -+ /* The last assignment has not been completely applied */ -+ if (prQM->fgTcResourcePostAnnealing) { -+ /* Upon the next qmUpdateAverageTxQueLen function call, do this check again */ -+ -+ /* wait for next time to do qmReassignTcResource */ -+ prQM->u4TimeToAdjustTcResource = 1; -+ } else { /* The last assignment has been applied */ -+ prQM->u4TimeToAdjustTcResource = QM_INIT_TIME_TO_ADJUST_TC_RSC; -+ qmReassignTcResource(prAdapter); -+ } -+ } -+ -+ /* Debug */ -+#if QM_PRINT_TC_RESOURCE_CTRL -+ for (i = 0; i < TC_NUM; i++) { -+ if (QM_GET_TX_QUEUE_LEN(prAdapter, i) >= 100) { -+ DBGLOG(QM, LOUD, "QM: QueLen [%u %u %u %u %u %u]\n", -+ QM_GET_TX_QUEUE_LEN(prAdapter, 0), -+ QM_GET_TX_QUEUE_LEN(prAdapter, 1), -+ QM_GET_TX_QUEUE_LEN(prAdapter, 2), -+ QM_GET_TX_QUEUE_LEN(prAdapter, 3), -+ QM_GET_TX_QUEUE_LEN(prAdapter, 4), QM_GET_TX_QUEUE_LEN(prAdapter, 5) -+ )); -+ break; -+ } -+ } -+#endif -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Assign TX resource for each TC according to TX queue length and current assignment -+* -+* \param (none) -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID qmReassignTcResource(IN P_ADAPTER_T prAdapter) -+{ -+ INT_32 i4TotalResourceDemand = 0; -+ UINT_32 u4ResidualResource = 0; -+ UINT_32 i; -+ INT_32 ai4PerTcResourceDemand[TC_NUM]; -+ UINT_32 u4ShareCount = 0; -+ UINT_32 u4Share = 0; -+ P_QUE_MGT_T prQM = &prAdapter->rQM; -+ -+ /* Note: After the new assignment is obtained, set prQM->fgTcResourcePostAnnealing to TRUE to -+ * start the TC-quota adjusting procedure, which will be invoked upon every TX Done -+ */ -+ /* tx done -> nicProcessTxInterrupt() -> nicTxAdjustTcq() -+ * -> qmAdjustTcQuotas() -> check fgTcResourcePostAnnealing */ -+ -+ /* 4 <1> Determine the demands */ -+ /* Determine the amount of extra resource to fulfill all of the demands */ -+ for (i = 0; i < TC_NUM; i++) { -+ /* Skip TC4, which is not adjustable */ -+ if (i == TC4_INDEX) -+ continue; -+ -+ /* -+ Define: extra_demand = average que_length (includes all station records) + -+ min_reserved_quota - -+ current available TC resources -+ -+ extra_demand means we need extra TC resources to transmit; other TCs can -+ borrow their resources to us? -+ */ -+ ai4PerTcResourceDemand[i] = -+ ((UINT_32) (QM_GET_TX_QUEUE_LEN(prAdapter, i)) + -+ prQM->au4MinReservedTcResource[i] - prQM->au4CurrentTcResource[i]); -+ -+ /* If there are queued packets, allocate extra resource for the TC (for TCP consideration) */ -+ if (QM_GET_TX_QUEUE_LEN(prAdapter, i)) -+ ai4PerTcResourceDemand[i] += QM_EXTRA_RESERVED_RESOURCE_WHEN_BUSY; /* 0 */ -+ -+ /* -+ accumulate all needed extra TC resources -+ maybe someone need + resource, maybe someone need - resource -+ */ -+ i4TotalResourceDemand += ai4PerTcResourceDemand[i]; -+ } -+ -+ /* 4 <2> Case 1: Demand <= Total Resource */ -+ if (i4TotalResourceDemand <= 0) { -+ /* 4 <2.1> Satisfy every TC */ -+ /* total TC resources are enough, no extra TC resources is needed */ -+ -+ /* adjust used TC resources to average TC resources + min reserve TC resources */ -+ for (i = 0; i < TC_NUM; i++) { -+ /* Skip TC4 (not adjustable) */ -+ if (i == TC4_INDEX) -+ continue; -+ -+ /* -+ the number of resources that one TC releases can be used for -+ other TCs -+ -+ EX: TC0 au4CurrentTcResource[0] = 10 ai4PerTcResourceDemand[0] = -5 -+ TC1 au4CurrentTcResource[1] = 5 ai4PerTcResourceDemand[0] = +5 -+ => TC0 au4CurrentTcResource[0] = 10 + (-5) = 5 -+ TC1 au4CurrentTcResource[1] = 5 + (+5) = 10 -+ */ -+ prQM->au4CurrentTcResource[i] += ai4PerTcResourceDemand[i]; -+ } -+ -+ /* 4 <2.2> Share the residual resource evenly */ -+ u4ShareCount = (TC_NUM - 1); /* 5, excluding TC4 */ -+ -+ /* -+ EX: i4TotalResourceDemand = -10 -+ means we have 10 available resources can be used. -+ */ -+ u4ResidualResource = (UINT_32) (-i4TotalResourceDemand); -+ u4Share = (u4ResidualResource / u4ShareCount); -+ -+ /* share available TC resources to all TCs averagely */ -+ for (i = 0; i < TC_NUM; i++) { -+ /* Skip TC4 (not adjustable) */ -+ if (i == TC4_INDEX) -+ continue; -+ -+ /* allocate residual average resources to the TC */ -+ prQM->au4CurrentTcResource[i] += u4Share; -+ -+ /* Every TC is fully satisfied so no need extra resources */ -+ ai4PerTcResourceDemand[i] = 0; -+ -+ /* decrease the allocated resources */ -+ u4ResidualResource -= u4Share; -+ } -+ -+ /* if still have available resources, we decide to give them to VO (TC3) queue */ -+ /* 4 <2.3> Allocate the left resource to TC3 (VO) */ -+ prQM->au4CurrentTcResource[TC3_INDEX] += (u4ResidualResource); -+ -+ } -+ /* 4 <3> Case 2: Demand > Total Resource --> Guarantee a minimum amount of resource for each TC */ -+ else { -+ /* -+ u4ResidualResource means we at least need to keep -+ QM_INITIAL_RESIDUAL_TC_RESOURCE available TC resources -+ -+ in 6628, u4ResidualResource = 26, max 28 -+ */ -+ u4ResidualResource = QM_INITIAL_RESIDUAL_TC_RESOURCE; -+ -+ /* 4 <3.1> Allocated resource amount = minimum of (guaranteed, total demand) */ -+ for (i = 0; i < TC_NUM; i++) { -+ -+ if (i == TC4_INDEX) -+ continue; /* Skip TC4 (not adjustable) */ -+ -+ /* The demand can be fulfilled with the guaranteed resource amount 4 4 6 6 2 4 */ -+ -+ /* -+ ai4PerTcResourceDemand[i] = -+ ((UINT_32)(QM_GET_TX_QUEUE_LEN(prAdapter, i)) + -+ prQM->au4MinReservedTcResource[i] - -+ prQM->au4CurrentTcResource[i]); -+ -+ so au4CurrentTcResource + ai4PerTcResourceDemand = -+ -+ ((UINT_32)(QM_GET_TX_QUEUE_LEN(prAdapter, i)) + -+ prQM->au4MinReservedTcResource[i] = -+ -+ current average queue len + min TC resources -+ */ -+ if (prQM->au4CurrentTcResource[i] + ai4PerTcResourceDemand[i] < -+ prQM->au4GuaranteedTcResource[i]) { -+ -+ /* avg queue len + min reserve still smaller than guarantee so enough */ -+ prQM->au4CurrentTcResource[i] += ai4PerTcResourceDemand[i]; -+ -+ /* accumulate available TC resources from the TC */ -+ u4ResidualResource += -+ (prQM->au4GuaranteedTcResource[i] - prQM->au4CurrentTcResource[i]); -+ ai4PerTcResourceDemand[i] = 0; -+ } -+ -+ /* The demand can not be fulfilled with the guaranteed resource amount */ -+ else { -+ -+ /* means even we use all guarantee resources for the TC is still not enough */ -+ -+ /* -+ guarantee number is always for the TC so extra resource number cannot -+ include the guarantee number. -+ -+ EX: au4GuaranteedTcResource = 10, au4CurrentTcResource = 5 -+ ai4PerTcResourceDemand = 6 -+ -+ ai4PerTcResourceDemand -= (10 - 5) ==> 1 -+ only need extra 1 TC resouce is enough. -+ */ -+ ai4PerTcResourceDemand[i] -= -+ (prQM->au4GuaranteedTcResource[i] - prQM->au4CurrentTcResource[i]); -+ -+ /* update current avg TC resource to guarantee number */ -+ prQM->au4CurrentTcResource[i] = prQM->au4GuaranteedTcResource[i]; -+ -+ /* count how many TC queues need to get extra resources */ -+ u4ShareCount++; -+ } -+ } -+ -+ /* 4 <3.2> Allocate the residual resource */ -+ do { -+ /* If there is no resource left, exit directly */ -+ if (u4ResidualResource == 0) -+ break; -+ -+ /* This shall not happen */ -+ if (u4ShareCount == 0) { -+ prQM->au4CurrentTcResource[TC1_INDEX] += u4ResidualResource; -+ DBGLOG(QM, ERROR, "QM: (Error) u4ShareCount = 0\n"); -+ break; -+ } -+ -+ /* Share the residual resource evenly */ -+ u4Share = (u4ResidualResource / u4ShareCount); -+ -+ if (u4Share) { -+ for (i = 0; i < TC_NUM; i++) { -+ /* Skip TC4 (not adjustable) */ -+ if (i == TC4_INDEX) -+ continue; -+ -+ if (ai4PerTcResourceDemand[i] == 0) -+ continue; -+ -+ if (ai4PerTcResourceDemand[i] - u4Share) { -+ /* still not enough but we just can give it u4Share resources */ -+ prQM->au4CurrentTcResource[i] += u4Share; -+ u4ResidualResource -= u4Share; -+ ai4PerTcResourceDemand[i] -= u4Share; -+ } else { -+ /* enough */ -+ prQM->au4CurrentTcResource[i] += ai4PerTcResourceDemand[i]; -+ u4ResidualResource -= ai4PerTcResourceDemand[i]; -+ ai4PerTcResourceDemand[i] = 0; -+ } -+ } -+ } -+ -+ if (u4ResidualResource == 0) -+ break; -+ /* By priority, allocate the left resource that is not divisible by u4Share */ -+ -+ if (ai4PerTcResourceDemand[TC3_INDEX]) { /* VO */ -+ prQM->au4CurrentTcResource[TC3_INDEX]++; -+ if (--u4ResidualResource == 0) -+ break; -+ } -+ -+ if (ai4PerTcResourceDemand[TC2_INDEX]) { /* VI */ -+ prQM->au4CurrentTcResource[TC2_INDEX]++; -+ if (--u4ResidualResource == 0) -+ break; -+ } -+ -+ if (ai4PerTcResourceDemand[TC5_INDEX]) { /* BMCAST */ -+ prQM->au4CurrentTcResource[TC5_INDEX]++; -+ if (--u4ResidualResource == 0) -+ break; -+ } -+ -+ if (ai4PerTcResourceDemand[TC1_INDEX]) { /* BE */ -+ prQM->au4CurrentTcResource[TC1_INDEX]++; -+ if (--u4ResidualResource == 0) -+ break; -+ } -+ -+ if (ai4PerTcResourceDemand[TC0_INDEX]) { /* BK */ -+ prQM->au4CurrentTcResource[TC0_INDEX]++; -+ if (--u4ResidualResource == 0) -+ break; -+ } -+ -+ /* Allocate the left resource */ -+ prQM->au4CurrentTcResource[TC3_INDEX] += u4ResidualResource; -+ -+ } while (FALSE); -+ } -+ -+ /* mark the flag that we can start to do TC resource adjustment after TX done handle */ -+ prQM->fgTcResourcePostAnnealing = TRUE; -+ -+#if QM_PRINT_TC_RESOURCE_CTRL -+ /* Debug print */ -+ DBGLOG(QM, LOUD, "QM: TC Rsc %u %u %u %u %u %u\n", -+ prQM->au4CurrentTcResource[0], -+ prQM->au4CurrentTcResource[1], -+ prQM->au4CurrentTcResource[2], -+ prQM->au4CurrentTcResource[3], prQM->au4CurrentTcResource[4], prQM->au4CurrentTcResource[5] -+ )); -+#endif -+ -+} -+ -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/* RX-Related Queue Management */ -+/*----------------------------------------------------------------------------*/ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Init Queue Management for RX -+* -+* \param[in] (none) -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID qmInitRxQueues(IN P_ADAPTER_T prAdapter) -+{ -+ /* DbgPrint("QM: Enter qmInitRxQueues()\n"); */ -+ /* TODO */ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Handle RX packets (buffer reordering) -+* -+* \param[in] prSwRfbListHead The list of RX packets -+* -+* \return The list of packets which are not buffered for reordering -+*/ -+/*----------------------------------------------------------------------------*/ -+P_SW_RFB_T qmHandleRxPackets(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfbListHead) -+{ -+ -+#if CFG_RX_REORDERING_ENABLED -+ /* UINT_32 i; */ -+ P_SW_RFB_T prCurrSwRfb; -+ P_SW_RFB_T prNextSwRfb; -+ P_HIF_RX_HEADER_T prHifRxHdr; -+ QUE_T rReturnedQue; -+ PUINT_8 pucEthDestAddr; -+ BOOLEAN fgIsBMC; -+ -+ /* DbgPrint("QM: Enter qmHandleRxPackets()\n"); */ -+ -+ DEBUGFUNC("qmHandleRxPackets"); -+ -+ ASSERT(prSwRfbListHead); -+ -+ QUEUE_INITIALIZE(&rReturnedQue); -+ prNextSwRfb = prSwRfbListHead; -+ -+ do { -+ prCurrSwRfb = prNextSwRfb; -+ prNextSwRfb = QM_RX_GET_NEXT_SW_RFB(prCurrSwRfb); -+ -+ prHifRxHdr = prCurrSwRfb->prHifRxHdr; /* TODO: (Tehuang) Use macro to obtain the pointer */ -+ -+ /* TODO: (Tehuang) Check if relaying */ -+ prCurrSwRfb->eDst = RX_PKT_DESTINATION_HOST; -+ -+ /* Decide the Destination */ -+#if CFG_RX_PKTS_DUMP -+ if (prAdapter->rRxCtrl.u4RxPktsDumpTypeMask & BIT(HIF_RX_PKT_TYPE_DATA)) { -+ DBGLOG(SW4, INFO, "QM RX DATA: net %u sta idx %u wlan idx %u ssn %u tid %u ptype %u 11 %u\n", -+ (UINT_32) HIF_RX_HDR_GET_NETWORK_IDX(prHifRxHdr), -+ prHifRxHdr->ucStaRecIdx, prCurrSwRfb->ucWlanIdx, -+ (UINT_32) HIF_RX_HDR_GET_SN(prHifRxHdr), /* The new SN of the frame */ -+ (UINT_32) HIF_RX_HDR_GET_TID(prHifRxHdr), -+ prCurrSwRfb->ucPacketType, -+ (UINT_32) HIF_RX_HDR_GET_80211_FLAG(prHifRxHdr)); -+ -+ DBGLOG_MEM8(SW4, TRACE, (PUINT_8) prCurrSwRfb->pvHeader, prCurrSwRfb->u2PacketLen); -+ } -+#endif -+ -+ fgIsBMC = FALSE; -+ if (!HIF_RX_HDR_GET_80211_FLAG(prHifRxHdr)) { -+ -+ UINT_8 ucNetTypeIdx; -+ P_BSS_INFO_T prBssInfo; -+ -+ pucEthDestAddr = prCurrSwRfb->pvHeader; -+ ucNetTypeIdx = HIF_RX_HDR_GET_NETWORK_IDX(prHifRxHdr); -+ -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[ucNetTypeIdx]); -+ /* DBGLOG_MEM8(QM, TRACE,prCurrSwRfb->pvHeader, 16); */ -+ /* */ -+ -+ if (IS_BMCAST_MAC_ADDR(pucEthDestAddr) && (OP_MODE_ACCESS_POINT != prBssInfo->eCurrentOPMode)) -+ fgIsBMC = TRUE; -+ -+ if (prAdapter->rRxCtrl.rFreeSwRfbList.u4NumElem > -+ (CFG_RX_MAX_PKT_NUM - CFG_NUM_OF_QM_RX_PKT_NUM)) { -+ -+ if (!IS_BSS_ACTIVE(prBssInfo)) { -+ DBGLOG(QM, WARN, "Mark NULL the Packet for inactive Bss %u\n", ucNetTypeIdx); -+ prCurrSwRfb->eDst = RX_PKT_DESTINATION_NULL; -+ QUEUE_INSERT_TAIL(&rReturnedQue, (P_QUE_ENTRY_T) prCurrSwRfb); -+ continue; -+ } -+ -+ if (OP_MODE_ACCESS_POINT == prBssInfo->eCurrentOPMode) { -+ if (IS_BMCAST_MAC_ADDR(pucEthDestAddr)) -+ prCurrSwRfb->eDst = RX_PKT_DESTINATION_HOST_WITH_FORWARD; -+ else if (UNEQUAL_MAC_ADDR(prBssInfo->aucOwnMacAddr, pucEthDestAddr) && -+ bssGetClientByAddress(prBssInfo, pucEthDestAddr)) -+ prCurrSwRfb->eDst = RX_PKT_DESTINATION_FORWARD; -+ /* TODO : need to check the dst mac is valid */ -+ /* If src mac is invalid, the packet will be freed in fw */ -+ } /* OP_MODE_ACCESS_POINT */ -+#if CFG_SUPPORT_HOTSPOT_2_0 -+ else if (hs20IsFrameFilterEnabled(prAdapter, prBssInfo) && -+ hs20IsUnsecuredFrame(prAdapter, prBssInfo, prCurrSwRfb)) { -+ DBGLOG(QM, WARN, -+ "Mark NULL the Packet for Dropped Packet %u\n", ucNetTypeIdx); -+ prCurrSwRfb->eDst = RX_PKT_DESTINATION_NULL; -+ QUEUE_INSERT_TAIL(&rReturnedQue, (P_QUE_ENTRY_T) prCurrSwRfb); -+ continue; -+ } -+#endif -+ } else { -+ /* Dont not occupy other SW RFB */ -+ DBGLOG(QM, WARN, "Mark NULL the Packet for less Free Sw Rfb\n"); -+ prCurrSwRfb->eDst = RX_PKT_DESTINATION_NULL; -+ QUEUE_INSERT_TAIL(&rReturnedQue, (P_QUE_ENTRY_T) prCurrSwRfb); -+ continue; -+ } -+ -+ } -+#if CFG_SUPPORT_WAPI -+ if (prCurrSwRfb->u2PacketLen > ETHER_HEADER_LEN) { -+ PUINT_8 pc = (PUINT_8) prCurrSwRfb->pvHeader; -+ UINT_16 u2Etype = 0; -+ -+ u2Etype = (pc[ETH_TYPE_LEN_OFFSET] << 8) | (pc[ETH_TYPE_LEN_OFFSET + 1]); -+ -+ /* for wapi integrity test. WPI_1x packet should be always in non-encrypted mode. -+ if we received any WPI(0x88b4) packet that is encrypted, drop here. */ -+ if (u2Etype == ETH_WPI_1X && HIF_RX_HDR_GET_SEC_MODE(prHifRxHdr) != 0) { -+ DBGLOG(QM, INFO, "drop wpi packet with sec mode\n"); -+ prCurrSwRfb->eDst = RX_PKT_DESTINATION_NULL; -+ QUEUE_INSERT_TAIL(&rReturnedQue, (P_QUE_ENTRY_T) prCurrSwRfb); -+ continue; -+ } -+ } -+#endif -+ /* BAR frame */ -+ if (HIF_RX_HDR_GET_BAR_FLAG(prHifRxHdr)) { -+ prCurrSwRfb->eDst = RX_PKT_DESTINATION_NULL; -+ qmProcessBarFrame(prAdapter, prCurrSwRfb, &rReturnedQue); -+ } -+ /* Reordering is not required for this packet, return it without buffering */ -+ else if (!HIF_RX_HDR_GET_REORDER_FLAG(prHifRxHdr) || fgIsBMC) { -+#if 0 -+ if (!HIF_RX_HDR_GET_80211_FLAG(prHifRxHdr)) { -+ UINT_8 ucNetTypeIdx; -+ P_BSS_INFO_T prBssInfo; -+ -+ pucEthDestAddr = prCurrSwRfb->pvHeader; -+ ucNetTypeIdx = HIF_RX_HDR_GET_NETWORK_IDX(prHifRxHdr); -+ -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[ucNetTypeIdx]); -+ -+ if (IS_BMCAST_MAC_ADDR(pucEthDestAddr) -+ && (OP_MODE_ACCESS_POINT == prBssInfo->eCurrentOPMode)) { -+ prCurrSwRfb->eDst = RX_PKT_DESTINATION_HOST_WITH_FORWARD; -+ } -+ } -+#endif -+ QUEUE_INSERT_TAIL(&rReturnedQue, (P_QUE_ENTRY_T) prCurrSwRfb); -+ } -+ /* Reordering is required for this packet */ -+ else { -+ /* If this packet should dropped or indicated to the host immediately, -+ * it should be enqueued into the rReturnedQue with specific flags. If -+ * this packet should be buffered for reordering, it should be enqueued -+ * into the reordering queue in the STA_REC rather than into the -+ * rReturnedQue. -+ */ -+ qmProcessPktWithReordering(prAdapter, prCurrSwRfb, &rReturnedQue); -+ -+ } -+ } while (prNextSwRfb); -+ -+ /* RX_PKT_DESTINATION_HOST_WITH_FORWARD or RX_PKT_DESTINATION_FORWARD */ -+ /* The returned list of SW_RFBs must end with a NULL pointer */ -+ if (QUEUE_IS_NOT_EMPTY(&rReturnedQue)) -+ QM_TX_SET_NEXT_MSDU_INFO((P_SW_RFB_T) QUEUE_GET_TAIL(&rReturnedQue), NULL); -+ -+ return (P_SW_RFB_T) QUEUE_GET_HEAD(&rReturnedQue); -+ -+#else -+ -+ /* DbgPrint("QM: Enter qmHandleRxPackets()\n"); */ -+ return prSwRfbListHead; -+ -+#endif -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Reorder the received packet -+* -+* \param[in] prSwRfb The RX packet to process -+* \param[out] prReturnedQue The queue for indicating packets -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID qmProcessPktWithReordering(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, OUT P_QUE_T prReturnedQue) -+{ -+ -+ P_STA_RECORD_T prStaRec; -+ P_HIF_RX_HEADER_T prHifRxHdr; -+ P_RX_BA_ENTRY_T prReorderQueParm; -+ -+ UINT_32 u4SeqNo; -+ UINT_32 u4WinStart; -+ UINT_32 u4WinEnd; -+ P_QUE_T prReorderQue; -+ /* P_SW_RFB_T prReorderedSwRfb; */ -+ BOOLEAN fgIsBaTimeout; -+ -+ DEBUGFUNC("qmProcessPktWithReordering"); -+ -+ if ((prSwRfb == NULL) || (prReturnedQue == NULL) || (prSwRfb->prHifRxHdr == NULL)) { -+ ASSERT(FALSE); -+ return; -+ } -+ -+ prHifRxHdr = prSwRfb->prHifRxHdr; -+ prSwRfb->ucStaRecIdx = prHifRxHdr->ucStaRecIdx; -+ prSwRfb->u2SSN = HIF_RX_HDR_GET_SN(prHifRxHdr); /* The new SN of the frame */ -+ prSwRfb->ucTid = (UINT_8) (HIF_RX_HDR_GET_TID(prHifRxHdr)); -+ /* prSwRfb->eDst = RX_PKT_DESTINATION_HOST; */ -+ -+ /* Incorrect STA_REC index */ -+ if (prSwRfb->ucStaRecIdx >= CFG_NUM_OF_STA_RECORD) { -+ prSwRfb->eDst = RX_PKT_DESTINATION_NULL; -+ QUEUE_INSERT_TAIL(prReturnedQue, (P_QUE_ENTRY_T) prSwRfb); -+ DBGLOG(QM, WARN, "Reordering for a NULL STA_REC, ucStaRecIdx = %d\n", prSwRfb->ucStaRecIdx); -+ /* ASSERT(0); */ -+ return; -+ } -+ -+ /* Check whether the STA_REC is activated */ -+ prStaRec = &(prAdapter->arStaRec[prSwRfb->ucStaRecIdx]); -+ ASSERT(prStaRec); -+ -+#if 0 -+ if (!(prStaRec->fgIsValid)) { -+ /* TODO: (Tehuang) Handle the Host-FW sync issue. */ -+ prSwRfb->eDst = RX_PKT_DESTINATION_NULL; -+ QUEUE_INSERT_TAIL(prReturnedQue, (P_QUE_ENTRY_T) prSwRfb); -+ DBGLOG(QM, WARN, "Reordering for an invalid STA_REC\n"); -+ /* ASSERT(0); */ -+ return; -+ } -+#endif -+ -+ /* Check whether the BA agreement exists */ -+ prReorderQueParm = ((prStaRec->aprRxReorderParamRefTbl)[prSwRfb->ucTid]); -+ if (!prReorderQueParm) { -+ /* TODO: (Tehuang) Handle the Host-FW sync issue. */ -+ prSwRfb->eDst = RX_PKT_DESTINATION_NULL; -+ QUEUE_INSERT_TAIL(prReturnedQue, (P_QUE_ENTRY_T) prSwRfb); -+ DBGLOG(QM, WARN, "Reordering for a NULL ReorderQueParm\n"); -+ /* ASSERT(0); */ -+ return; -+ } -+ -+ /* Start to reorder packets */ -+ u4SeqNo = (UINT_32) (prSwRfb->u2SSN); -+ prReorderQue = &(prReorderQueParm->rReOrderQue); -+ u4WinStart = (UINT_32) (prReorderQueParm->u2WinStart); -+ u4WinEnd = (UINT_32) (prReorderQueParm->u2WinEnd); -+ -+ /* Debug */ -+ /* DbgPrint("QM:(R)[%d](%ld){%ld,%ld}\n", prSwRfb->ucTid, u4SeqNo, u4WinStart, u4WinEnd); */ -+ -+ /* Case 1: Fall within */ -+ if /* 0 - start - sn - end - 4095 */ -+ (((u4WinStart <= u4SeqNo) && (u4SeqNo <= u4WinEnd)) -+ /* 0 - end - start - sn - 4095 */ -+ || ((u4WinEnd < u4WinStart) && (u4WinStart <= u4SeqNo)) -+ /* 0 - sn - end - start - 4095 */ -+ || ((u4SeqNo <= u4WinEnd) && (u4WinEnd < u4WinStart))) { -+ -+ qmInsertFallWithinReorderPkt(prSwRfb, prReorderQueParm, prReturnedQue); -+ -+#if QM_RX_WIN_SSN_AUTO_ADVANCING -+ if (prReorderQueParm->fgIsWaitingForPktWithSsn) { -+ /* Let the first received packet pass the reorder check */ -+ DBGLOG(QM, LOUD, "QM:(A)[%d](%u){%u,%u}\n", prSwRfb->ucTid, u4SeqNo, u4WinStart, u4WinEnd); -+ -+ prReorderQueParm->u2WinStart = (UINT_16) u4SeqNo; -+ prReorderQueParm->u2WinEnd = -+ ((prReorderQueParm->u2WinStart) + (prReorderQueParm->u2WinSize) - 1) % MAX_SEQ_NO_COUNT; -+ prReorderQueParm->fgIsWaitingForPktWithSsn = FALSE; -+ } -+#endif -+ -+ if (qmPopOutDueToFallWithin(prReorderQueParm, prReturnedQue, &fgIsBaTimeout) == FALSE) -+ STATS_RX_REORDER_HOLE_INC(prStaRec); /* record hole count */ -+ STATS_RX_REORDER_HOLE_TIMEOUT_INC(prStaRec, fgIsBaTimeout); -+ } -+ /* Case 2: Fall ahead */ -+ else if -+ /* 0 - start - end - sn - (start+2048) - 4095 */ -+ (((u4WinStart < u4WinEnd) -+ && (u4WinEnd < u4SeqNo) -+ && (u4SeqNo < (u4WinStart + HALF_SEQ_NO_COUNT))) -+ /* 0 - sn - (start+2048) - start - end - 4095 */ -+ || ((u4SeqNo < u4WinStart) -+ && (u4WinStart < u4WinEnd) -+ && ((u4SeqNo + MAX_SEQ_NO_COUNT) < (u4WinStart + HALF_SEQ_NO_COUNT))) -+ /* 0 - end - sn - (start+2048) - start - 4095 */ -+ || ((u4WinEnd < u4SeqNo) -+ && (u4SeqNo < u4WinStart) -+ && ((u4SeqNo + MAX_SEQ_NO_COUNT) < (u4WinStart + HALF_SEQ_NO_COUNT)))) { -+ -+#if QM_RX_WIN_SSN_AUTO_ADVANCING -+ if (prReorderQueParm->fgIsWaitingForPktWithSsn) -+ prReorderQueParm->fgIsWaitingForPktWithSsn = FALSE; -+#endif -+ -+ qmInsertFallAheadReorderPkt(prSwRfb, prReorderQueParm, prReturnedQue); -+ -+ /* Advance the window after inserting a new tail */ -+ prReorderQueParm->u2WinEnd = (UINT_16) u4SeqNo; -+ prReorderQueParm->u2WinStart = -+ (((prReorderQueParm->u2WinEnd) - (prReorderQueParm->u2WinSize) + MAX_SEQ_NO_COUNT + 1) -+ % MAX_SEQ_NO_COUNT); -+ -+ qmPopOutDueToFallAhead(prReorderQueParm, prReturnedQue); -+ -+ STATS_RX_REORDER_FALL_AHEAD_INC(prStaRec); -+ -+ } -+ /* Case 3: Fall behind */ -+ else { -+ -+#if QM_RX_WIN_SSN_AUTO_ADVANCING -+#if QM_RX_INIT_FALL_BEHIND_PASS -+ if (prReorderQueParm->fgIsWaitingForPktWithSsn) { -+ /* ?? prSwRfb->eDst = RX_PKT_DESTINATION_HOST; */ -+ QUEUE_INSERT_TAIL(prReturnedQue, (P_QUE_ENTRY_T) prSwRfb); -+ /* DbgPrint("QM:(P)[%d](%ld){%ld,%ld}\n", prSwRfb->ucTid, u4SeqNo, u4WinStart, u4WinEnd); */ -+ return; -+ } -+#endif -+#endif -+ -+ STATS_RX_REORDER_FALL_BEHIND_INC(prStaRec); -+ /* An erroneous packet */ -+ prSwRfb->eDst = RX_PKT_DESTINATION_NULL; -+ QUEUE_INSERT_TAIL(prReturnedQue, (P_QUE_ENTRY_T) prSwRfb); -+ /* DbgPrint("QM:(D)[%d](%ld){%ld,%ld}\n", prSwRfb->ucTid, u4SeqNo, u4WinStart, u4WinEnd); */ -+ return; -+ } -+ -+ return; -+ -+} -+ -+VOID qmProcessBarFrame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, OUT P_QUE_T prReturnedQue) -+{ -+ -+ P_STA_RECORD_T prStaRec; -+ P_HIF_RX_HEADER_T prHifRxHdr; -+ P_RX_BA_ENTRY_T prReorderQueParm; -+ -+ UINT_32 u4SSN; -+ UINT_32 u4WinStart; -+ UINT_32 u4WinEnd; -+ P_QUE_T prReorderQue; -+ /* P_SW_RFB_T prReorderedSwRfb; */ -+ -+ if ((prSwRfb == NULL) || (prReturnedQue == NULL) || (prSwRfb->prHifRxHdr == NULL)) { -+ ASSERT(FALSE); -+ return; -+ } -+ -+ prHifRxHdr = prSwRfb->prHifRxHdr; -+ prSwRfb->ucStaRecIdx = prHifRxHdr->ucStaRecIdx; -+ prSwRfb->u2SSN = HIF_RX_HDR_GET_SN(prHifRxHdr); /* The new SSN */ -+ prSwRfb->ucTid = (UINT_8) (HIF_RX_HDR_GET_TID(prHifRxHdr)); -+ -+ prSwRfb->eDst = RX_PKT_DESTINATION_NULL; -+ QUEUE_INSERT_TAIL(prReturnedQue, (P_QUE_ENTRY_T) prSwRfb); -+ -+ /* Incorrect STA_REC index */ -+ if (prSwRfb->ucStaRecIdx >= CFG_NUM_OF_STA_RECORD) { -+ DBGLOG(QM, WARN, "QM: (Warning) BAR for a NULL STA_REC, ucStaRecIdx = %d\n", prSwRfb->ucStaRecIdx); -+ /* ASSERT(0); */ -+ return; -+ } -+ -+ /* Check whether the STA_REC is activated */ -+ prStaRec = &(prAdapter->arStaRec[prSwRfb->ucStaRecIdx]); -+ ASSERT(prStaRec); -+ -+#if 0 -+ if (!(prStaRec->fgIsValid)) { -+ /* TODO: (Tehuang) Handle the Host-FW sync issue. */ -+ DbgPrint("QM: (Warning) BAR for an invalid STA_REC\n"); -+ /* ASSERT(0); */ -+ return; -+ } -+#endif -+ -+ /* Check whether the BA agreement exists */ -+ prReorderQueParm = ((prStaRec->aprRxReorderParamRefTbl)[prSwRfb->ucTid]); -+ if (!prReorderQueParm) { -+ /* TODO: (Tehuang) Handle the Host-FW sync issue. */ -+ DBGLOG(QM, WARN, "QM: (Warning) BAR for a NULL ReorderQueParm\n"); -+ /* ASSERT(0); */ -+ return; -+ } -+ -+ u4SSN = (UINT_32) (prSwRfb->u2SSN); -+ prReorderQue = &(prReorderQueParm->rReOrderQue); -+ u4WinStart = (UINT_32) (prReorderQueParm->u2WinStart); -+ u4WinEnd = (UINT_32) (prReorderQueParm->u2WinEnd); -+ -+ if (qmCompareSnIsLessThan(u4WinStart, u4SSN)) { -+ prReorderQueParm->u2WinStart = (UINT_16) u4SSN; -+ prReorderQueParm->u2WinEnd = -+ ((prReorderQueParm->u2WinStart) + (prReorderQueParm->u2WinSize) - 1) % MAX_SEQ_NO_COUNT; -+ DBGLOG(QM, TRACE, -+ "QM:(BAR)[%d](%u){%d,%d}\n", prSwRfb->ucTid, u4SSN, prReorderQueParm->u2WinStart, -+ prReorderQueParm->u2WinEnd); -+ qmPopOutDueToFallAhead(prReorderQueParm, prReturnedQue); -+ } else { -+ DBGLOG(QM, TRACE, "QM:(BAR)(%d)(%u){%u,%u}\n", prSwRfb->ucTid, u4SSN, u4WinStart, u4WinEnd); -+ } -+} -+ -+VOID qmInsertFallWithinReorderPkt(IN P_SW_RFB_T prSwRfb, IN P_RX_BA_ENTRY_T prReorderQueParm, OUT P_QUE_T prReturnedQue) -+{ -+ P_SW_RFB_T prExaminedQueuedSwRfb; -+ P_QUE_T prReorderQue; -+ -+ ASSERT(prSwRfb); -+ ASSERT(prReorderQueParm); -+ ASSERT(prReturnedQue); -+ -+ prReorderQue = &(prReorderQueParm->rReOrderQue); -+ prExaminedQueuedSwRfb = (P_SW_RFB_T) QUEUE_GET_HEAD(prReorderQue); -+ -+ /* There are no packets queued in the Reorder Queue */ -+ if (prExaminedQueuedSwRfb == NULL) { -+ ((P_QUE_ENTRY_T) prSwRfb)->prPrev = NULL; -+ ((P_QUE_ENTRY_T) prSwRfb)->prNext = NULL; -+ prReorderQue->prHead = (P_QUE_ENTRY_T) prSwRfb; -+ prReorderQue->prTail = (P_QUE_ENTRY_T) prSwRfb; -+ prReorderQue->u4NumElem++; -+ } -+ -+ /* Determine the insert position */ -+ else { -+ do { -+ /* Case 1: Terminate. A duplicate packet */ -+ if (((prExaminedQueuedSwRfb->u2SSN) == (prSwRfb->u2SSN))) { -+ prSwRfb->eDst = RX_PKT_DESTINATION_NULL; -+ QUEUE_INSERT_TAIL(prReturnedQue, (P_QUE_ENTRY_T) prSwRfb); -+ return; -+ } -+ -+ /* Case 2: Terminate. The insert point is found */ -+ else if (qmCompareSnIsLessThan((prSwRfb->u2SSN), (prExaminedQueuedSwRfb->u2SSN))) -+ break; -+ -+ /* Case 3: Insert point not found. Check the next SW_RFB in the Reorder Queue */ -+ else -+ prExaminedQueuedSwRfb = (P_SW_RFB_T) (((P_QUE_ENTRY_T) prExaminedQueuedSwRfb)->prNext); -+ } while (prExaminedQueuedSwRfb); -+ -+ /* Update the Reorder Queue Parameters according to the found insert position */ -+ if (prExaminedQueuedSwRfb == NULL) { -+ /* The received packet shall be placed at the tail */ -+ ((P_QUE_ENTRY_T) prSwRfb)->prPrev = prReorderQue->prTail; -+ ((P_QUE_ENTRY_T) prSwRfb)->prNext = NULL; -+ (prReorderQue->prTail)->prNext = (P_QUE_ENTRY_T) (prSwRfb); -+ prReorderQue->prTail = (P_QUE_ENTRY_T) (prSwRfb); -+ } else { -+ ((P_QUE_ENTRY_T) prSwRfb)->prPrev = ((P_QUE_ENTRY_T) prExaminedQueuedSwRfb)->prPrev; -+ ((P_QUE_ENTRY_T) prSwRfb)->prNext = (P_QUE_ENTRY_T) prExaminedQueuedSwRfb; -+ if (((P_QUE_ENTRY_T) prExaminedQueuedSwRfb) == (prReorderQue->prHead)) { -+ /* The received packet will become the head */ -+ prReorderQue->prHead = (P_QUE_ENTRY_T) prSwRfb; -+ } else { -+ (((P_QUE_ENTRY_T) prExaminedQueuedSwRfb)->prPrev)->prNext = (P_QUE_ENTRY_T) prSwRfb; -+ } -+ ((P_QUE_ENTRY_T) prExaminedQueuedSwRfb)->prPrev = (P_QUE_ENTRY_T) prSwRfb; -+ } -+ -+ prReorderQue->u4NumElem++; -+ -+ } -+ -+} -+ -+VOID qmInsertFallAheadReorderPkt(IN P_SW_RFB_T prSwRfb, IN P_RX_BA_ENTRY_T prReorderQueParm, OUT P_QUE_T prReturnedQue) -+{ -+ P_QUE_T prReorderQue; -+ -+ ASSERT(prSwRfb); -+ ASSERT(prReorderQueParm); -+ ASSERT(prReturnedQue); -+ -+ prReorderQue = &(prReorderQueParm->rReOrderQue); -+ -+ /* There are no packets queued in the Reorder Queue */ -+ if (QUEUE_IS_EMPTY(prReorderQue)) { -+ ((P_QUE_ENTRY_T) prSwRfb)->prPrev = NULL; -+ ((P_QUE_ENTRY_T) prSwRfb)->prNext = NULL; -+ prReorderQue->prHead = (P_QUE_ENTRY_T) prSwRfb; -+ } else { -+ ((P_QUE_ENTRY_T) prSwRfb)->prPrev = prReorderQue->prTail; -+ ((P_QUE_ENTRY_T) prSwRfb)->prNext = NULL; -+ (prReorderQue->prTail)->prNext = (P_QUE_ENTRY_T) (prSwRfb); -+ } -+ prReorderQue->prTail = (P_QUE_ENTRY_T) prSwRfb; -+ prReorderQue->u4NumElem++; -+ -+} -+ -+BOOLEAN -+qmPopOutDueToFallWithin(IN P_RX_BA_ENTRY_T prReorderQueParm, OUT P_QUE_T prReturnedQue, OUT BOOLEAN *fgIsTimeout) -+{ -+ P_SW_RFB_T prReorderedSwRfb; -+ P_QUE_T prReorderQue; -+ BOOLEAN fgDequeuHead, fgMissing; -+ OS_SYSTIME rCurrentTime, *prMissTimeout; -+ -+ prReorderQue = &(prReorderQueParm->rReOrderQue); -+ -+ *fgIsTimeout = FALSE; -+ fgMissing = FALSE; -+ rCurrentTime = 0; -+ prMissTimeout = &(g_arMissTimeout[prReorderQueParm->ucStaRecIdx][prReorderQueParm->ucTid]); -+ if ((*prMissTimeout)) { -+ fgMissing = TRUE; -+ GET_CURRENT_SYSTIME(&rCurrentTime); -+ } -+ -+ /* Check whether any packet can be indicated to the higher layer */ -+ while (TRUE) { -+ if (QUEUE_IS_EMPTY(prReorderQue)) -+ break; -+ -+ /* Always examine the head packet */ -+ prReorderedSwRfb = (P_SW_RFB_T) QUEUE_GET_HEAD(prReorderQue); -+ fgDequeuHead = FALSE; -+ -+ /* SN == WinStart, so the head packet shall be indicated (advance the window) */ -+ if ((prReorderedSwRfb->u2SSN) == (prReorderQueParm->u2WinStart)) { -+ -+ fgDequeuHead = TRUE; -+ prReorderQueParm->u2WinStart = (((prReorderedSwRfb->u2SSN) + 1) % MAX_SEQ_NO_COUNT); -+ } -+ /* SN > WinStart, break to update WinEnd */ -+ else { -+ if ((fgMissing == TRUE) && -+ CHECK_FOR_TIMEOUT(rCurrentTime, (*prMissTimeout), -+ MSEC_TO_SYSTIME(QM_RX_BA_ENTRY_MISS_TIMEOUT_MS))) { -+ DBGLOG(QM, TRACE, -+ "QM:RX BA Timout Next Tid %d SSN %d\n", prReorderQueParm->ucTid, -+ prReorderedSwRfb->u2SSN); -+ fgDequeuHead = TRUE; -+ prReorderQueParm->u2WinStart = (((prReorderedSwRfb->u2SSN) + 1) % MAX_SEQ_NO_COUNT); -+ -+ fgMissing = FALSE; -+ *fgIsTimeout = TRUE; -+ } else -+ break; -+ } -+ -+ /* Dequeue the head packet */ -+ if (fgDequeuHead) { -+ -+ if (((P_QUE_ENTRY_T) prReorderedSwRfb)->prNext == NULL) { -+ prReorderQue->prHead = NULL; -+ prReorderQue->prTail = NULL; -+ } else { -+ prReorderQue->prHead = ((P_QUE_ENTRY_T) prReorderedSwRfb)->prNext; -+ (((P_QUE_ENTRY_T) prReorderedSwRfb)->prNext)->prPrev = NULL; -+ } -+ prReorderQue->u4NumElem--; -+ /* DbgPrint("QM: [%d] %d (%d)\n", -+ prReorderQueParm->ucTid, -+ prReorderedSwRfb->u2PacketLen, -+ prReorderedSwRfb->u2SSN); */ -+ QUEUE_INSERT_TAIL(prReturnedQue, (P_QUE_ENTRY_T) prReorderedSwRfb); -+ } -+ } -+ -+ if (QUEUE_IS_EMPTY(prReorderQue)) -+ *prMissTimeout = 0; -+ else { -+ if (fgMissing == FALSE) -+ GET_CURRENT_SYSTIME(prMissTimeout); -+ } -+ -+ /* After WinStart has been determined, update the WinEnd */ -+ prReorderQueParm->u2WinEnd = -+ (((prReorderQueParm->u2WinStart) + (prReorderQueParm->u2WinSize) - 1) % MAX_SEQ_NO_COUNT); -+ return QUEUE_IS_EMPTY(prReorderQue); -+} -+ -+VOID qmPopOutDueToFallAhead(IN P_RX_BA_ENTRY_T prReorderQueParm, OUT P_QUE_T prReturnedQue) -+{ -+ P_SW_RFB_T prReorderedSwRfb; -+ P_QUE_T prReorderQue; -+ BOOLEAN fgDequeuHead; -+ -+ prReorderQue = &(prReorderQueParm->rReOrderQue); -+ -+ /* Check whether any packet can be indicated to the higher layer */ -+ while (TRUE) { -+ if (QUEUE_IS_EMPTY(prReorderQue)) -+ break; -+ -+ /* Always examine the head packet */ -+ prReorderedSwRfb = (P_SW_RFB_T) QUEUE_GET_HEAD(prReorderQue); -+ fgDequeuHead = FALSE; -+ -+ /* SN == WinStart, so the head packet shall be indicated (advance the window) */ -+ if ((prReorderedSwRfb->u2SSN) == (prReorderQueParm->u2WinStart)) { -+ -+ fgDequeuHead = TRUE; -+ prReorderQueParm->u2WinStart = (((prReorderedSwRfb->u2SSN) + 1) % MAX_SEQ_NO_COUNT); -+ } -+ -+ /* SN < WinStart, so the head packet shall be indicated (do not advance the window) */ -+ else if (qmCompareSnIsLessThan((UINT_32) (prReorderedSwRfb->u2SSN), -+ (UINT_32) (prReorderQueParm->u2WinStart))) -+ fgDequeuHead = TRUE; -+ -+ /* SN > WinStart, break to update WinEnd */ -+ else -+ break; -+ -+ /* Dequeue the head packet */ -+ if (fgDequeuHead) { -+ -+ if (((P_QUE_ENTRY_T) prReorderedSwRfb)->prNext == NULL) { -+ prReorderQue->prHead = NULL; -+ prReorderQue->prTail = NULL; -+ } else { -+ prReorderQue->prHead = ((P_QUE_ENTRY_T) prReorderedSwRfb)->prNext; -+ (((P_QUE_ENTRY_T) prReorderedSwRfb)->prNext)->prPrev = NULL; -+ } -+ prReorderQue->u4NumElem--; -+ /* DbgPrint("QM: [%d] %d (%d)\n", */ -+ /* prReorderQueParm->ucTid, prReorderedSwRfb->u2PacketLen, prReorderedSwRfb->u2SSN); */ -+ QUEUE_INSERT_TAIL(prReturnedQue, (P_QUE_ENTRY_T) prReorderedSwRfb); -+ } -+ } -+ -+ /* After WinStart has been determined, update the WinEnd */ -+ prReorderQueParm->u2WinEnd = -+ (((prReorderQueParm->u2WinStart) + (prReorderQueParm->u2WinSize) - 1) % MAX_SEQ_NO_COUNT); -+ -+} -+ -+BOOLEAN qmCompareSnIsLessThan(IN UINT_32 u4SnLess, IN UINT_32 u4SnGreater) -+{ -+ /* 0 <---> SnLess <--(gap>2048)--> SnGreater : SnLess > SnGreater */ -+ if ((u4SnLess + HALF_SEQ_NO_COUNT) <= u4SnGreater) /* Shall be <= */ -+ return FALSE; -+ -+ /* 0 <---> SnGreater <--(gap>2048)--> SnLess : SnLess < SnGreater */ -+ else if ((u4SnGreater + HALF_SEQ_NO_COUNT) < u4SnLess) -+ return TRUE; -+ -+ /* 0 <---> SnGreater <--(gap<2048)--> SnLess : SnLess > SnGreater */ -+ /* 0 <---> SnLess <--(gap<2048)--> SnGreater : SnLess < SnGreater */ -+ else if (u4SnLess < u4SnGreater) -+ return TRUE; -+ else -+ return FALSE; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Handle Mailbox RX messages -+* -+* \param[in] prMailboxRxMsg The received Mailbox message from the FW -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID qmHandleMailboxRxMessage(IN MAILBOX_MSG_T prMailboxRxMsg) -+{ -+ /* DbgPrint("QM: Enter qmHandleMailboxRxMessage()\n"); */ -+ /* TODO */ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Handle ADD RX BA Event from the FW -+* -+* \param[in] prAdapter Adapter pointer -+* \param[in] prEvent The event packet from the FW -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID qmHandleEventRxAddBa(IN P_ADAPTER_T prAdapter, IN P_WIFI_EVENT_T prEvent) -+{ -+ P_EVENT_RX_ADDBA_T prEventRxAddBa; -+ P_STA_RECORD_T prStaRec; -+ UINT_32 u4Tid; -+ UINT_32 u4WinSize; -+ -+ DBGLOG(QM, INFO, "QM:Event +RxBa\n"); -+ -+ prEventRxAddBa = (P_EVENT_RX_ADDBA_T) prEvent; -+ prStaRec = QM_GET_STA_REC_PTR_FROM_INDEX(prAdapter, prEventRxAddBa->ucStaRecIdx); -+ -+ if (!prStaRec) { -+ /* Invalid STA_REC index, discard the event packet */ -+ /* ASSERT(0); */ -+ DBGLOG(QM, WARN, "QM: (Warning) RX ADDBA Event for a NULL STA_REC\n"); -+ return; -+ } -+#if 0 -+ if (!(prStaRec->fgIsValid)) { -+ /* TODO: (Tehuang) Handle the Host-FW synchronization issue */ -+ DBGLOG(QM, WARN, "QM: (Warning) RX ADDBA Event for an invalid STA_REC\n"); -+ /* ASSERT(0); */ -+ /* return; */ -+ } -+#endif -+ -+ u4Tid = (((prEventRxAddBa->u2BAParameterSet) & BA_PARAM_SET_TID_MASK) -+ >> BA_PARAM_SET_TID_MASK_OFFSET); -+ -+ u4WinSize = (((prEventRxAddBa->u2BAParameterSet) & BA_PARAM_SET_BUFFER_SIZE_MASK) -+ >> BA_PARAM_SET_BUFFER_SIZE_MASK_OFFSET); -+ -+ if (!qmAddRxBaEntry(prAdapter, -+ prStaRec->ucIndex, -+ (UINT_8) u4Tid, -+ (prEventRxAddBa->u2BAStartSeqCtrl >> OFFSET_BAR_SSC_SN), (UINT_16) u4WinSize)) { -+ -+ /* FW shall ensure the availabiilty of the free-to-use BA entry */ -+ DBGLOG(QM, ERROR, "QM: (Error) qmAddRxBaEntry() failure\n"); -+ ASSERT(0); -+ } -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Handle DEL RX BA Event from the FW -+* -+* \param[in] prAdapter Adapter pointer -+* \param[in] prEvent The event packet from the FW -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID qmHandleEventRxDelBa(IN P_ADAPTER_T prAdapter, IN P_WIFI_EVENT_T prEvent) -+{ -+ P_EVENT_RX_DELBA_T prEventRxDelBa; -+ P_STA_RECORD_T prStaRec; -+ -+ /* DbgPrint("QM:Event -RxBa\n"); */ -+ -+ prEventRxDelBa = (P_EVENT_RX_DELBA_T) prEvent; -+ prStaRec = QM_GET_STA_REC_PTR_FROM_INDEX(prAdapter, prEventRxDelBa->ucStaRecIdx); -+ -+ if (!prStaRec) -+ /* Invalid STA_REC index, discard the event packet */ -+ /* ASSERT(0); */ -+ return; -+#if 0 -+ if (!(prStaRec->fgIsValid)) -+ /* TODO: (Tehuang) Handle the Host-FW synchronization issue */ -+ /* ASSERT(0); */ -+ return; -+#endif -+ -+ qmDelRxBaEntry(prAdapter, prStaRec->ucIndex, prEventRxDelBa->ucTid, TRUE); -+ -+} -+ -+P_RX_BA_ENTRY_T qmLookupRxBaEntry(IN P_ADAPTER_T prAdapter, UINT_8 ucStaRecIdx, UINT_8 ucTid) -+{ -+ int i; -+ P_QUE_MGT_T prQM = &prAdapter->rQM; -+ -+ /* DbgPrint("QM: Enter qmLookupRxBaEntry()\n"); */ -+ -+ for (i = 0; i < CFG_NUM_OF_RX_BA_AGREEMENTS; i++) { -+ if (prQM->arRxBaTable[i].fgIsValid) { -+ if ((prQM->arRxBaTable[i].ucStaRecIdx == ucStaRecIdx) && (prQM->arRxBaTable[i].ucTid == ucTid)) -+ return &prQM->arRxBaTable[i]; -+ } -+ } -+ return NULL; -+} -+ -+BOOLEAN -+qmAddRxBaEntry(IN P_ADAPTER_T prAdapter, -+ IN UINT_8 ucStaRecIdx, IN UINT_8 ucTid, IN UINT_16 u2WinStart, IN UINT_16 u2WinSize) -+{ -+ int i; -+ P_RX_BA_ENTRY_T prRxBaEntry = NULL; -+ P_STA_RECORD_T prStaRec; -+ P_QUE_MGT_T prQM = &prAdapter->rQM; -+ -+ ASSERT(ucStaRecIdx < CFG_NUM_OF_STA_RECORD); -+ -+ if (ucStaRecIdx >= CFG_NUM_OF_STA_RECORD) { -+ /* Invalid STA_REC index, discard the event packet */ -+ DBGLOG(QM, WARN, "QM: (WARNING) RX ADDBA Event for a invalid ucStaRecIdx = %d\n", ucStaRecIdx); -+ return FALSE; -+ } -+ -+ prStaRec = &prAdapter->arStaRec[ucStaRecIdx]; -+ ASSERT(prStaRec); -+ -+ /* if(!(prStaRec->fgIsValid)){ */ -+ /* DbgPrint("QM: (WARNING) Invalid STA when adding an RX BA\n"); */ -+ /* return FALSE; */ -+ /* } */ -+ -+ /* 4 <1> Delete before adding */ -+ /* Remove the BA entry for the same (STA, TID) tuple if it exists */ -+ if (qmLookupRxBaEntry(prAdapter, ucStaRecIdx, ucTid)) -+ qmDelRxBaEntry(prAdapter, ucStaRecIdx, ucTid, TRUE); /* prQM->ucRxBaCount-- */ -+ /* 4 <2> Add a new BA entry */ -+ /* No available entry to store the BA agreement info. Retrun FALSE. */ -+ if (prQM->ucRxBaCount >= CFG_NUM_OF_RX_BA_AGREEMENTS) { -+ DBGLOG(QM, ERROR, "QM: **failure** (limited resource, ucRxBaCount=%d)\n", prQM->ucRxBaCount); -+ return FALSE; -+ } -+ /* Find the free-to-use BA entry */ -+ for (i = 0; i < CFG_NUM_OF_RX_BA_AGREEMENTS; i++) { -+ if (!prQM->arRxBaTable[i].fgIsValid) { -+ prRxBaEntry = &(prQM->arRxBaTable[i]); -+ prQM->ucRxBaCount++; -+ DBGLOG(QM, LOUD, "QM: ucRxBaCount=%d\n", prQM->ucRxBaCount); -+ break; -+ } -+ } -+ /* If a free-to-use entry is found, configure it and associate it with the STA_REC */ -+ u2WinSize += CFG_RX_BA_INC_SIZE; -+ if (prRxBaEntry) { -+ prRxBaEntry->ucStaRecIdx = ucStaRecIdx; -+ prRxBaEntry->ucTid = ucTid; -+ prRxBaEntry->u2WinStart = u2WinStart; -+ prRxBaEntry->u2WinSize = u2WinSize; -+ prRxBaEntry->u2WinEnd = ((u2WinStart + u2WinSize - 1) % MAX_SEQ_NO_COUNT); -+ prRxBaEntry->fgIsValid = TRUE; -+ prRxBaEntry->fgIsWaitingForPktWithSsn = TRUE; -+ -+ g_arMissTimeout[ucStaRecIdx][ucTid] = 0; -+ -+ DBGLOG(QM, INFO, "QM: +RxBA(STA=%d TID=%d WinStart=%d WinEnd=%d WinSize=%d)\n", -+ ucStaRecIdx, ucTid, -+ prRxBaEntry->u2WinStart, prRxBaEntry->u2WinEnd, prRxBaEntry->u2WinSize); -+ -+ /* Update the BA entry reference table for per-packet lookup */ -+ prStaRec->aprRxReorderParamRefTbl[ucTid] = prRxBaEntry; -+ } else { -+ /* This shall not happen because FW should keep track of the usage of RX BA entries */ -+ DBGLOG(QM, ERROR, "QM: **AddBA Error** (ucRxBaCount=%d)\n", prQM->ucRxBaCount); -+ return FALSE; -+ } -+ return TRUE; -+} -+ -+VOID qmDelRxBaEntry(IN P_ADAPTER_T prAdapter, IN UINT_8 ucStaRecIdx, IN UINT_8 ucTid, IN BOOLEAN fgFlushToHost) -+{ -+ P_RX_BA_ENTRY_T prRxBaEntry; -+ P_STA_RECORD_T prStaRec; -+ P_SW_RFB_T prFlushedPacketList = NULL; -+ P_QUE_MGT_T prQM = &prAdapter->rQM; -+ -+ ASSERT(ucStaRecIdx < CFG_NUM_OF_STA_RECORD); -+ -+ prStaRec = &prAdapter->arStaRec[ucStaRecIdx]; -+ ASSERT(prStaRec); -+ -+#if 0 -+ if (!(prStaRec->fgIsValid)) { -+ DbgPrint("QM: (WARNING) Invalid STA when deleting an RX BA\n"); -+ return; -+ } -+#endif -+ -+ /* Remove the BA entry for the same (STA, TID) tuple if it exists */ -+ prRxBaEntry = prStaRec->aprRxReorderParamRefTbl[ucTid]; -+ -+ if (prRxBaEntry) { -+ -+ prFlushedPacketList = qmFlushStaRxQueue(prAdapter, ucStaRecIdx, ucTid); -+ -+ if (prFlushedPacketList) { -+ -+ if (fgFlushToHost) { -+ wlanProcessQueuedSwRfb(prAdapter, prFlushedPacketList); -+ } else { -+ -+ P_SW_RFB_T prSwRfb; -+ P_SW_RFB_T prNextSwRfb; -+ -+ prSwRfb = prFlushedPacketList; -+ -+ do { -+ prNextSwRfb = (P_SW_RFB_T) QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T) prSwRfb); -+ nicRxReturnRFB(prAdapter, prSwRfb); -+ prSwRfb = prNextSwRfb; -+ } while (prSwRfb); -+ -+ } -+ -+ } -+#if ((QM_TEST_MODE == 0) && (QM_TEST_STA_REC_DEACTIVATION == 0)) -+ /* Update RX BA entry state. Note that RX queue flush is not done here */ -+ prRxBaEntry->fgIsValid = FALSE; -+ prQM->ucRxBaCount--; -+ -+ /* Debug */ -+#if 0 -+ DbgPrint("QM: ucRxBaCount=%d\n", prQM->ucRxBaCount); -+#endif -+ -+ /* Update STA RX BA table */ -+ prStaRec->aprRxReorderParamRefTbl[ucTid] = NULL; -+#endif -+ -+ DBGLOG(QM, INFO, "QM: -RxBA(STA=%d,TID=%d)\n", ucStaRecIdx, ucTid); -+ -+ } -+ -+ /* Debug */ -+#if CFG_HIF_RX_STARVATION_WARNING -+ { -+ P_RX_CTRL_T prRxCtrl; -+ -+ prRxCtrl = &prAdapter->rRxCtrl; -+ DBGLOG(QM, TRACE, -+ "QM: (RX DEBUG) Enqueued: %d / Dequeued: %d\n", prRxCtrl->u4QueuedCnt, -+ prRxCtrl->u4DequeuedCnt); -+ } -+#endif -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief To process WMM related IEs in ASSOC_RSP -+* -+* \param[in] prAdapter Adapter pointer -+* \param[in] prSwRfb The received frame -+* \param[in] pucIE The pointer to the first IE in the frame -+* \param[in] u2IELength The total length of IEs in the frame -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID mqmProcessAssocReq(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, IN PUINT_8 pucIE, IN UINT_16 u2IELength) -+{ -+ P_STA_RECORD_T prStaRec; -+ UINT_16 u2Offset; -+ PUINT_8 pucIEStart; -+ UINT_8 aucWfaOui[] = VENDOR_OUI_WFA; -+ P_IE_WMM_INFO_T prIeWmmInfo; -+ UINT_8 ucQosInfo; -+ UINT_8 ucQosInfoAC; -+ UINT_8 ucBmpAC; -+ -+ DEBUGFUNC("mqmProcessAssocReq"); -+ -+ ASSERT(prSwRfb); -+ ASSERT(pucIE); -+ -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); -+ ASSERT(prStaRec); -+ -+ if (prStaRec == NULL) -+ return; -+ -+ prStaRec->fgIsQoS = FALSE; -+ prStaRec->fgIsWmmSupported = prStaRec->fgIsUapsdSupported = FALSE; -+ -+ pucIEStart = pucIE; -+ -+ /* If the device does not support QoS or if WMM is not supported by the peer, exit. */ -+ if (!prAdapter->rWifiVar.fgSupportQoS) -+ return; -+ -+ /* Determine whether QoS is enabled with the association */ -+ IE_FOR_EACH(pucIE, u2IELength, u2Offset) { -+ switch (IE_ID(pucIE)) { -+ case ELEM_ID_WMM: -+ -+ if ((WMM_IE_OUI_TYPE(pucIE) == VENDOR_OUI_TYPE_WMM) && -+ (!kalMemCmp(WMM_IE_OUI(pucIE), aucWfaOui, 3))) { -+ switch (WMM_IE_OUI_SUBTYPE(pucIE)) { -+ case VENDOR_OUI_SUBTYPE_WMM_INFO: -+ if (IE_LEN(pucIE) != 7) -+ break; /* WMM Info IE with a wrong length */ -+ prStaRec->fgIsQoS = TRUE; -+ prStaRec->fgIsWmmSupported = TRUE; -+ -+ prIeWmmInfo = (P_IE_WMM_INFO_T) pucIE; -+ ucQosInfo = prIeWmmInfo->ucQosInfo; -+ ucQosInfoAC = ucQosInfo & BITS(0, 3); -+ -+ prStaRec->fgIsUapsdSupported = ((ucQosInfoAC) ? TRUE : FALSE) & -+ prAdapter->rWifiVar.fgSupportUAPSD; -+ -+ ucBmpAC = 0; -+ -+ if (ucQosInfoAC & WMM_QOS_INFO_VO_UAPSD) -+ ucBmpAC |= BIT(ACI_VO); -+ if (ucQosInfoAC & WMM_QOS_INFO_VI_UAPSD) -+ ucBmpAC |= BIT(ACI_VI); -+ if (ucQosInfoAC & WMM_QOS_INFO_BE_UAPSD) -+ ucBmpAC |= BIT(ACI_BE); -+ if (ucQosInfoAC & WMM_QOS_INFO_BK_UAPSD) -+ ucBmpAC |= BIT(ACI_BK); -+ -+ prStaRec->ucBmpTriggerAC = prStaRec->ucBmpDeliveryAC = ucBmpAC; -+ -+ prStaRec->ucUapsdSp = -+ (ucQosInfo & WMM_QOS_INFO_MAX_SP_LEN_MASK) >> 5; -+ break; -+ default: -+ /* Other WMM QoS IEs. Ignore any */ -+ break; -+ } -+ } -+ /* else: VENDOR_OUI_TYPE_WPA, VENDOR_OUI_TYPE_WPS */ -+ -+ break; -+ -+ case ELEM_ID_HT_CAP: -+ /* Some client won't put the WMM IE if client is 802.11n */ -+ if (IE_LEN(pucIE) == (sizeof(IE_HT_CAP_T) - 2)) -+ prStaRec->fgIsQoS = TRUE; -+ break; -+ default: -+ break; -+ } -+ } -+ -+ DBGLOG(QM, TRACE, "MQM: Assoc_Req Parsing (QoS Enabled=%d)\n", prStaRec->fgIsQoS); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief To process WMM related IEs in ASSOC_RSP -+* -+* \param[in] prAdapter Adapter pointer -+* \param[in] prSwRfb The received frame -+* \param[in] pucIE The pointer to the first IE in the frame -+* \param[in] u2IELength The total length of IEs in the frame -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID mqmProcessAssocRsp(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, IN PUINT_8 pucIE, IN UINT_16 u2IELength) -+{ -+ P_STA_RECORD_T prStaRec; -+ UINT_16 u2Offset; -+ PUINT_8 pucIEStart; -+ UINT_8 aucWfaOui[] = VENDOR_OUI_WFA; -+ -+ DEBUGFUNC("mqmProcessAssocRsp"); -+ -+ ASSERT(prSwRfb); -+ ASSERT(pucIE); -+ -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); -+ ASSERT(prStaRec); -+ -+ if (prStaRec == NULL) -+ return; -+ -+ prStaRec->fgIsQoS = FALSE; -+ -+ pucIEStart = pucIE; -+ -+ DBGLOG(QM, TRACE, "QM: (fgIsWmmSupported=%d, fgSupportQoS=%d)\n", -+ prStaRec->fgIsWmmSupported, prAdapter->rWifiVar.fgSupportQoS); -+ -+ /* If the device does not support QoS or if WMM is not supported by the peer, exit. */ -+ /* if((!prAdapter->rWifiVar.fgSupportQoS) || (!prStaRec->fgIsWmmSupported)) */ -+ if ((!prAdapter->rWifiVar.fgSupportQoS)) -+ return; -+ -+ /* Determine whether QoS is enabled with the association */ -+ IE_FOR_EACH(pucIE, u2IELength, u2Offset) { -+ switch (IE_ID(pucIE)) { -+ case ELEM_ID_WMM: -+ if ((WMM_IE_OUI_TYPE(pucIE) == VENDOR_OUI_TYPE_WMM) && -+ (!kalMemCmp(WMM_IE_OUI(pucIE), aucWfaOui, 3))) { -+ -+ switch (WMM_IE_OUI_SUBTYPE(pucIE)) { -+ case VENDOR_OUI_SUBTYPE_WMM_PARAM: -+ if (IE_LEN(pucIE) != 24) -+ break; /* WMM Info IE with a wrong length */ -+ prStaRec->fgIsQoS = TRUE; -+ break; -+ -+ case VENDOR_OUI_SUBTYPE_WMM_INFO: -+ if (IE_LEN(pucIE) != 7) -+ break; /* WMM Info IE with a wrong length */ -+ prStaRec->fgIsQoS = TRUE; -+ break; -+ -+ default: -+ /* Other WMM QoS IEs. Ignore any */ -+ break; -+ } -+ } -+ /* else: VENDOR_OUI_TYPE_WPA, VENDOR_OUI_TYPE_WPS */ -+ break; -+ -+ case ELEM_ID_HT_CAP: -+ /* Some AP won't put the WMM IE if client is 802.11n */ -+ if (IE_LEN(pucIE) == (sizeof(IE_HT_CAP_T) - 2)) -+ prStaRec->fgIsQoS = TRUE; -+ break; -+ default: -+ break; -+ } -+ } -+ -+ /* Parse AC parameters and write to HW CRs */ -+ if ((prStaRec->fgIsQoS) && (prStaRec->eStaType == STA_TYPE_LEGACY_AP)) { -+ mqmParseEdcaParameters(prAdapter, prSwRfb, pucIEStart, u2IELength, TRUE); -+#if ARP_MONITER_ENABLE -+ qmResetArpDetect(); -+#endif -+ } -+ -+ DBGLOG(QM, TRACE, "MQM: Assoc_Rsp Parsing (QoS Enabled=%d)\n", prStaRec->fgIsQoS); -+ if (prStaRec->fgIsWmmSupported) -+ nicQmUpdateWmmParms(prAdapter, prStaRec->ucNetTypeIndex); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief To parse WMM Parameter IE (in BCN or Assoc_Rsp) -+* -+* \param[in] prAdapter Adapter pointer -+* \param[in] prSwRfb The received frame -+* \param[in] pucIE The pointer to the first IE in the frame -+* \param[in] u2IELength The total length of IEs in the frame -+* \param[in] fgForceOverride TRUE: If EDCA parameters are found, always set to HW CRs. -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+mqmParseEdcaParameters(IN P_ADAPTER_T prAdapter, -+ IN P_SW_RFB_T prSwRfb, IN PUINT_8 pucIE, IN UINT_16 u2IELength, IN BOOLEAN fgForceOverride) -+{ -+ P_STA_RECORD_T prStaRec; -+ UINT_16 u2Offset; -+ UINT_8 aucWfaOui[] = VENDOR_OUI_WFA; -+ P_BSS_INFO_T prBssInfo; -+ P_AC_QUE_PARMS_T prAcQueParams; -+ P_IE_WMM_PARAM_T prIeWmmParam; -+ ENUM_WMM_ACI_T eAci; -+ PUINT_8 pucWmmParamSetCount; -+ -+ DEBUGFUNC("mqmParseEdcaParameters"); -+ -+ ASSERT(prSwRfb); -+ ASSERT(pucIE); -+ -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); -+ ASSERT(prStaRec); -+ if (prStaRec == NULL) -+ return; -+ -+ DBGLOG(QM, TRACE, "QM: (fgIsWmmSupported=%d, fgIsQoS=%d)\n", prStaRec->fgIsWmmSupported, prStaRec->fgIsQoS); -+ -+ if ((!prAdapter->rWifiVar.fgSupportQoS) || (!prStaRec->fgIsWmmSupported) || (!prStaRec->fgIsQoS)) -+ return; -+ -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]); -+ -+ /* Goal: Obtain the EDCA parameters */ -+ IE_FOR_EACH(pucIE, u2IELength, u2Offset) { -+ switch (IE_ID(pucIE)) { -+ case ELEM_ID_WMM: -+ if ((WMM_IE_OUI_TYPE(pucIE) != VENDOR_OUI_TYPE_WMM) || -+ (kalMemCmp(WMM_IE_OUI(pucIE), aucWfaOui, 3))) -+ break; -+ -+ switch (WMM_IE_OUI_SUBTYPE(pucIE)) { -+ case VENDOR_OUI_SUBTYPE_WMM_PARAM: -+ if (IE_LEN(pucIE) != 24) -+ break; /* WMM Param IE with a wrong length */ -+ -+ pucWmmParamSetCount = &(prBssInfo->ucWmmParamSetCount); -+ prIeWmmParam = (P_IE_WMM_PARAM_T) pucIE; -+ -+ /* Check the Parameter Set Count to determine whether EDCA parameters */ -+ /* have been changed */ -+ if (!fgForceOverride && (*pucWmmParamSetCount -+ == (prIeWmmParam->ucQosInfo & WMM_QOS_INFO_PARAM_SET_CNT))) -+ break; /* Ignore the IE without updating HW CRs */ -+ -+ /* Update Parameter Set Count */ -+ *pucWmmParamSetCount = -+ (prIeWmmParam->ucQosInfo & WMM_QOS_INFO_PARAM_SET_CNT); -+ -+ /* Update EDCA parameters */ -+ for (eAci = 0; eAci < WMM_AC_INDEX_NUM; eAci++) { -+ -+ prAcQueParams = &prBssInfo->arACQueParms[eAci]; -+ mqmFillAcQueParam(prIeWmmParam, eAci, prAcQueParams); -+ -+ prAcQueParams->fgIsACMSet = -+ (prAcQueParams->u2Aifsn & WMM_ACIAIFSN_ACM) ? TRUE : FALSE; -+ prAcQueParams->u2Aifsn &= WMM_ACIAIFSN_AIFSN; -+ -+ DBGLOG(QM, LOUD, -+ "eAci:%d, ACM:%d, Aifsn:%d, CWmin:%d, CWmax:%d, TxopLmt:%d\n", -+ eAci, prAcQueParams->fgIsACMSet, prAcQueParams->u2Aifsn, -+ prAcQueParams->u2CWmin, prAcQueParams->u2CWmax, -+ prAcQueParams->u2TxopLimit); -+ } -+ break; -+ default: -+ /* Other WMM QoS IEs. Ignore */ -+ break; -+ } -+ -+ /* else: VENDOR_OUI_TYPE_WPA, VENDOR_OUI_TYPE_WPS, ... (not cared) */ -+ break; -+ default: -+ break; -+ } -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is used for parsing EDCA parameters specified in the WMM Parameter IE -+* -+* \param[in] prAdapter Adapter pointer -+* \param[in] prIeWmmParam The pointer to the WMM Parameter IE -+* \param[in] u4AcOffset The offset specifying the AC queue for parsing -+* \param[in] prHwAcParams The parameter structure used to configure the HW CRs -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID mqmFillAcQueParam(IN P_IE_WMM_PARAM_T prIeWmmParam, IN UINT_32 u4AcOffset, OUT P_AC_QUE_PARMS_T prAcQueParams) -+{ -+ prAcQueParams->u2Aifsn = *((PUINT_8) (&(prIeWmmParam->ucAciAifsn_BE)) + (u4AcOffset * 4)); -+ -+ prAcQueParams->u2CWmax = BIT(((*((PUINT_8) (&(prIeWmmParam->ucEcw_BE)) + (u4AcOffset * 4))) & WMM_ECW_WMAX_MASK) -+ >> WMM_ECW_WMAX_OFFSET) - 1; -+ -+ prAcQueParams->u2CWmin = -+ BIT((*((PUINT_8) (&(prIeWmmParam->ucEcw_BE)) + (u4AcOffset * 4))) & WMM_ECW_WMIN_MASK) - 1; -+ -+ WLAN_GET_FIELD_16(((PUINT_8) (&(prIeWmmParam->aucTxopLimit_BE)) + (u4AcOffset * 4)), -+ &(prAcQueParams->u2TxopLimit)); -+ -+ prAcQueParams->ucGuradTime = TXM_DEFAULT_FLUSH_QUEUE_GUARD_TIME; -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief To parse WMM/11n related IEs in scan results (only for AP peers) -+* -+* \param[in] prAdapter Adapter pointer -+* \param[in] prScanResult The scan result which shall be parsed to obtain needed info -+* \param[out] prStaRec The obtained info is stored in the STA_REC -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+#if (CFG_SUPPORT_TDLS == 1) /* for test purpose */ -+BOOLEAN flgTdlsTestExtCapElm = FALSE; -+UINT8 aucTdlsTestExtCapElm[7]; -+#endif /* CFG_SUPPORT_TDLS */ -+VOID mqmProcessScanResult(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prScanResult, OUT P_STA_RECORD_T prStaRec) -+{ -+ PUINT_8 pucIE; -+ UINT_16 u2IELength; -+ UINT_16 u2Offset; -+ UINT_8 aucWfaOui[] = VENDOR_OUI_WFA; -+ -+ DEBUGFUNC("mqmProcessScanResult"); -+ -+ ASSERT(prScanResult); -+ ASSERT(prStaRec); -+ -+ /* Reset the flag before parsing */ -+ prStaRec->fgIsWmmSupported = prStaRec->fgIsUapsdSupported = FALSE; -+ -+ if (!prAdapter->rWifiVar.fgSupportQoS) -+ return; -+ -+ u2IELength = prScanResult->u2IELength; -+ pucIE = prScanResult->aucIEBuf; -+ -+#if (CFG_SUPPORT_TDLS == 1) -+ /* TDLS test purpose */ -+ if (flgTdlsTestExtCapElm == TRUE) -+ TdlsexBssExtCapParse(prStaRec, aucTdlsTestExtCapElm); -+#endif /* CFG_SUPPORT_TDLS */ -+ -+ /* Goal: Determine whether the peer supports WMM/QoS and UAPSDU */ -+ IE_FOR_EACH(pucIE, u2IELength, u2Offset) { -+ switch (IE_ID(pucIE)) { -+ case ELEM_ID_EXTENDED_CAP: -+#if (CFG_SUPPORT_TDLS == 1) -+ TdlsexBssExtCapParse(prStaRec, pucIE); -+#endif /* CFG_SUPPORT_TDLS */ -+ break; -+ -+ case ELEM_ID_WMM: -+ if ((WMM_IE_OUI_TYPE(pucIE) == VENDOR_OUI_TYPE_WMM) && -+ (!kalMemCmp(WMM_IE_OUI(pucIE), aucWfaOui, 3))) { -+ -+ switch (WMM_IE_OUI_SUBTYPE(pucIE)) { -+ case VENDOR_OUI_SUBTYPE_WMM_PARAM: -+ if (IE_LEN(pucIE) != 24) -+ break; /* WMM Param IE with a wrong length */ -+ -+ prStaRec->fgIsWmmSupported = TRUE; -+ prStaRec->fgIsUapsdSupported = -+ (((((P_IE_WMM_PARAM_T) pucIE)->ucQosInfo) & WMM_QOS_INFO_UAPSD) ? -+ TRUE : FALSE); -+ break; -+ -+ case VENDOR_OUI_SUBTYPE_WMM_INFO: -+ if (IE_LEN(pucIE) != 7) -+ break; /* WMM Info IE with a wrong length */ -+ -+ prStaRec->fgIsWmmSupported = TRUE; -+ prStaRec->fgIsUapsdSupported = -+ (((((P_IE_WMM_INFO_T) pucIE)->ucQosInfo) & WMM_QOS_INFO_UAPSD) ? -+ TRUE : FALSE); -+ break; -+ -+ default: -+ /* A WMM QoS IE that doesn't matter. Ignore it. */ -+ break; -+ } -+ } -+ /* else: VENDOR_OUI_TYPE_WPA, VENDOR_OUI_TYPE_WPS, ... (not cared) */ -+ -+ break; -+ -+ default: -+ /* A WMM IE that doesn't matter. Ignore it. */ -+ break; -+ } -+ } -+ DBGLOG(QM, LOUD, "MQM: Scan Result Parsing (WMM=%d, UAPSD=%d)\n", -+ prStaRec->fgIsWmmSupported, prStaRec->fgIsUapsdSupported); -+ -+} -+ -+UINT_8 qmGetStaRecIdx(IN P_ADAPTER_T prAdapter, IN PUINT_8 pucEthDestAddr, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkType) -+{ -+ UINT_32 i; -+ P_STA_RECORD_T prTempStaRec; -+ -+ prTempStaRec = NULL; -+ -+ ASSERT(prAdapter); -+ -+ /* 4 <1> DA = BMCAST */ -+ if (IS_BMCAST_MAC_ADDR(pucEthDestAddr)) -+ return STA_REC_INDEX_BMCAST; -+ /* 4 <2> Check if an AP STA is present */ -+ for (i = 0; i < CFG_NUM_OF_STA_RECORD; i++) { -+ prTempStaRec = &(prAdapter->arStaRec[i]); -+ if ((prTempStaRec->ucNetTypeIndex == eNetworkType) -+ && (prTempStaRec->fgIsAp) -+ && (prTempStaRec->fgIsValid)) { -+ return prTempStaRec->ucIndex; -+ } -+ } -+ -+ /* 4 <3> Not BMCAST, No AP --> Compare DA (i.e., to see whether this is a unicast frame to a client) */ -+ for (i = 0; i < CFG_NUM_OF_STA_RECORD; i++) { -+ prTempStaRec = &(prAdapter->arStaRec[i]); -+ if (prTempStaRec->fgIsValid) { -+ if (EQUAL_MAC_ADDR(prTempStaRec->aucMacAddr, pucEthDestAddr)) -+ return prTempStaRec->ucIndex; -+ } -+ } -+ -+ /* 4 <4> No STA found, Not BMCAST --> Indicate NOT_FOUND to FW */ -+ return STA_REC_INDEX_NOT_FOUND; -+} -+ -+UINT_32 -+mqmGenerateWmmInfoIEByParam(BOOLEAN fgSupportUAPSD, -+ UINT_8 ucBmpDeliveryAC, UINT_8 ucBmpTriggerAC, UINT_8 ucUapsdSp, UINT_8 *pOutBuf) -+{ -+ P_IE_WMM_INFO_T prIeWmmInfo; -+ UINT_32 ucUapsd[] = { -+ WMM_QOS_INFO_BE_UAPSD, -+ WMM_QOS_INFO_BK_UAPSD, -+ WMM_QOS_INFO_VI_UAPSD, -+ WMM_QOS_INFO_VO_UAPSD -+ }; -+ UINT_8 aucWfaOui[] = VENDOR_OUI_WFA; -+ -+ ASSERT(pOutBuf); -+ -+ prIeWmmInfo = (P_IE_WMM_INFO_T) pOutBuf; -+ -+ prIeWmmInfo->ucId = ELEM_ID_WMM; -+ prIeWmmInfo->ucLength = ELEM_MAX_LEN_WMM_INFO; -+ -+ /* WMM-2.2.1 WMM Information Element Field Values */ -+ prIeWmmInfo->aucOui[0] = aucWfaOui[0]; -+ prIeWmmInfo->aucOui[1] = aucWfaOui[1]; -+ prIeWmmInfo->aucOui[2] = aucWfaOui[2]; -+ prIeWmmInfo->ucOuiType = VENDOR_OUI_TYPE_WMM; -+ prIeWmmInfo->ucOuiSubtype = VENDOR_OUI_SUBTYPE_WMM_INFO; -+ -+ prIeWmmInfo->ucVersion = VERSION_WMM; -+ prIeWmmInfo->ucQosInfo = 0; -+ -+ /* UAPSD initial queue configurations (delivery and trigger enabled) */ -+ if (fgSupportUAPSD) { -+ -+ UINT_8 ucQosInfo = 0; -+ UINT_8 i; -+ -+ /* Static U-APSD setting */ -+ for (i = ACI_BE; i <= ACI_VO; i++) { -+ if (ucBmpDeliveryAC & ucBmpTriggerAC & BIT(i)) -+ ucQosInfo |= (UINT_8) ucUapsd[i]; -+ } -+ -+ if (ucBmpDeliveryAC & ucBmpTriggerAC) { -+ switch (ucUapsdSp) { -+ case WMM_MAX_SP_LENGTH_ALL: -+ ucQosInfo |= WMM_QOS_INFO_MAX_SP_ALL; -+ break; -+ -+ case WMM_MAX_SP_LENGTH_2: -+ ucQosInfo |= WMM_QOS_INFO_MAX_SP_2; -+ break; -+ -+ case WMM_MAX_SP_LENGTH_4: -+ ucQosInfo |= WMM_QOS_INFO_MAX_SP_4; -+ break; -+ -+ case WMM_MAX_SP_LENGTH_6: -+ ucQosInfo |= WMM_QOS_INFO_MAX_SP_6; -+ break; -+ -+ default: -+ DBGLOG(QM, WARN, "MQM: Incorrect SP length\n"); -+ ucQosInfo |= WMM_QOS_INFO_MAX_SP_2; -+ break; -+ } -+ } -+ prIeWmmInfo->ucQosInfo = ucQosInfo; -+ -+ } -+ -+ /* Increment the total IE length for the Element ID and Length fields. */ -+ return IE_SIZE(prIeWmmInfo); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Generate the WMM Info IE -+* -+* \param[in] prAdapter Adapter pointer -+* @param prMsduInfo The TX MMPDU -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID mqmGenerateWmmInfoIE(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo) -+{ -+ P_IE_WMM_INFO_T prIeWmmInfo; -+ P_PM_PROFILE_SETUP_INFO_T prPmProfSetupInfo; -+ P_BSS_INFO_T prBssInfo; -+ P_STA_RECORD_T prStaRec; -+ -+ DEBUGFUNC("mqmGenerateWmmInfoIE"); -+ -+ ASSERT(prMsduInfo); -+ -+ /* In case QoS is not turned off, exit directly */ -+ if (!prAdapter->rWifiVar.fgSupportQoS) -+ return; -+ -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); -+ ASSERT(prStaRec); -+ -+ if (prStaRec == NULL) -+ return; -+ -+ if (!prStaRec->fgIsWmmSupported) -+ return; -+ -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]); -+ -+ prPmProfSetupInfo = &prBssInfo->rPmProfSetupInfo; -+ -+ prIeWmmInfo = (P_IE_WMM_INFO_T) -+ ((PUINT_8) prMsduInfo->prPacket + prMsduInfo->u2FrameLength); -+ -+#if 0 -+ prIeWmmInfo->ucId = ELEM_ID_WMM; -+ prIeWmmInfo->ucLength = ELEM_MAX_LEN_WMM_INFO; -+ -+ /* WMM-2.2.1 WMM Information Element Field Values */ -+ prIeWmmInfo->aucOui[0] = aucWfaOui[0]; -+ prIeWmmInfo->aucOui[1] = aucWfaOui[1]; -+ prIeWmmInfo->aucOui[2] = aucWfaOui[2]; -+ prIeWmmInfo->ucOuiType = VENDOR_OUI_TYPE_WMM; -+ prIeWmmInfo->ucOuiSubtype = VENDOR_OUI_SUBTYPE_WMM_INFO; -+ -+ prIeWmmInfo->ucVersion = VERSION_WMM; -+ prIeWmmInfo->ucQosInfo = 0; -+ -+ /* UAPSD initial queue configurations (delivery and trigger enabled) */ -+/* if(prAdapter->rWifiVar.fgSupportUAPSD){ */ -+ if (prAdapter->rWifiVar.fgSupportUAPSD && prStaRec->fgIsUapsdSupported) { -+ -+ UINT_8 ucQosInfo = 0; -+ UINT_8 i; -+ -+ /* Static U-APSD setting */ -+ for (i = ACI_BE; i <= ACI_VO; i++) { -+ if (prPmProfSetupInfo->ucBmpDeliveryAC & prPmProfSetupInfo->ucBmpTriggerAC & BIT(i)) -+ ucQosInfo |= (UINT_8) ucUapsd[i]; -+ } -+ -+ if (prPmProfSetupInfo->ucBmpDeliveryAC & prPmProfSetupInfo->ucBmpTriggerAC) { -+ switch (prPmProfSetupInfo->ucUapsdSp) { -+ case WMM_MAX_SP_LENGTH_ALL: -+ ucQosInfo |= WMM_QOS_INFO_MAX_SP_ALL; -+ break; -+ -+ case WMM_MAX_SP_LENGTH_2: -+ ucQosInfo |= WMM_QOS_INFO_MAX_SP_2; -+ break; -+ -+ case WMM_MAX_SP_LENGTH_4: -+ ucQosInfo |= WMM_QOS_INFO_MAX_SP_4; -+ break; -+ -+ case WMM_MAX_SP_LENGTH_6: -+ ucQosInfo |= WMM_QOS_INFO_MAX_SP_6; -+ break; -+ -+ default: -+ DBGLOG(QM, INFO, "MQM: Incorrect SP length\n"); -+ ucQosInfo |= WMM_QOS_INFO_MAX_SP_2; -+ break; -+ } -+ } -+ prIeWmmInfo->ucQosInfo = ucQosInfo; -+ -+ } -+ -+ /* Increment the total IE length for the Element ID and Length fields. */ -+ prMsduInfo->u2FrameLength += IE_SIZE(prIeWmmInfo); -+#else -+ -+ prMsduInfo->u2FrameLength += mqmGenerateWmmInfoIEByParam((prAdapter->rWifiVar.fgSupportUAPSD -+ && prStaRec->fgIsUapsdSupported), -+ prPmProfSetupInfo->ucBmpDeliveryAC, -+ prPmProfSetupInfo->ucBmpTriggerAC, -+ prPmProfSetupInfo->ucUapsdSp, (UINT_8 *) prIeWmmInfo); -+#endif -+} -+ -+#if 0 -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief log2 calculation for CW -+* -+* @param[in] val value -+* -+* @return log2(val) -+*/ -+/*----------------------------------------------------------------------------*/ -+ -+UINT_32 cwlog2(UINT_32 val) -+{ -+ -+ UINT_32 n; -+ -+ n = 0; -+ -+ while (val >= 512) { -+ n += 9; -+ val = val >> 9; -+ } -+ while (val >= 16) { -+ n += 4; -+ val >>= 4; -+ } -+ while (val >= 2) { -+ n += 1; -+ val >>= 1; -+ } -+ return n; -+} -+#endif -+ -+UINT_32 mqmGenerateWmmParamIEByParam(P_ADAPTER_T prAdapter, -+ P_BSS_INFO_T prBssInfo, UINT_8 *pOutBuf, ENUM_OP_MODE_T ucOpMode) -+{ -+ P_IE_WMM_PARAM_T prIeWmmParam; -+ UINT_8 aucWfaOui[] = VENDOR_OUI_WFA; -+ UINT_8 aucACI[] = { -+ WMM_ACI_AC_BE, -+ WMM_ACI_AC_BK, -+ WMM_ACI_AC_VI, -+ WMM_ACI_AC_VO -+ }; -+ ENUM_WMM_ACI_T eAci; -+ UCHAR *pucAciAifsn, *pucEcw, *pucTxopLimit; -+ -+ ASSERT(pOutBuf); -+ -+ prIeWmmParam = (P_IE_WMM_PARAM_T) pOutBuf; -+ -+ prIeWmmParam->ucId = ELEM_ID_WMM; -+ prIeWmmParam->ucLength = ELEM_MAX_LEN_WMM_PARAM; -+ -+ /* WMM-2.2.1 WMM Information Element Field Values */ -+ prIeWmmParam->aucOui[0] = aucWfaOui[0]; -+ prIeWmmParam->aucOui[1] = aucWfaOui[1]; -+ prIeWmmParam->aucOui[2] = aucWfaOui[2]; -+ prIeWmmParam->ucOuiType = VENDOR_OUI_TYPE_WMM; -+ prIeWmmParam->ucOuiSubtype = VENDOR_OUI_SUBTYPE_WMM_PARAM; -+ -+ prIeWmmParam->ucVersion = VERSION_WMM; -+ prIeWmmParam->ucQosInfo = (prBssInfo->ucWmmParamSetCount & WMM_QOS_INFO_PARAM_SET_CNT); -+ -+ /* UAPSD initial queue configurations (delivery and trigger enabled) */ -+ if (prAdapter->rWifiVar.fgSupportUAPSD) { -+ if (ucOpMode == OP_MODE_INFRASTRUCTURE) -+ prIeWmmParam->ucQosInfo = 0xf; -+ else -+ prIeWmmParam->ucQosInfo |= WMM_QOS_INFO_UAPSD; -+ } -+ -+ /* EDCA parameter */ -+ -+ for (eAci = 0; eAci < WMM_AC_INDEX_NUM; eAci++) { -+ -+ /* DBGLOG(QM, LOUD, */ -+ /* ("MQM: eAci = %d, ACM = %d, Aifsn = %d, CWmin = %d, CWmax = %d, TxopLimit = %d\n", */ -+ /* eAci,prBssInfo->arACQueParmsForBcast[eAci].fgIsACMSet , */ -+ /* prBssInfo->arACQueParmsForBcast[eAci].u2Aifsn, */ -+ /* prBssInfo->arACQueParmsForBcast[eAci].u2CWmin, */ -+ /* prBssInfo->arACQueParmsForBcast[eAci].u2CWmax, */ -+ /* prBssInfo->arACQueParmsForBcast[eAci].u2TxopLimit)); */ -+ -+#if 0 -+ *(((PUINT_8) (&prIeWmmParam->ucAciAifsn_BE)) + (eAci << 2)) = (UINT_8) (aucACI[eAci] -+ | -+ (prBssInfo->arACQueParmsForBcast -+ [eAci].fgIsACMSet ? -+ WMM_ACIAIFSN_ACM : 0) -+ | -+ (prBssInfo->arACQueParmsForBcast -+ [eAci].u2Aifsn & -+ (WMM_ACIAIFSN_AIFSN))); -+#else -+ /* avoid compile warnings in Klockwork tool */ -+ if (eAci == WMM_AC_BE_INDEX) { -+ pucAciAifsn = &prIeWmmParam->ucAciAifsn_BE; -+ pucEcw = &prIeWmmParam->ucEcw_BE; -+ pucTxopLimit = prIeWmmParam->aucTxopLimit_BE; -+ } else if (eAci == WMM_AC_BK_INDEX) { -+ pucAciAifsn = &prIeWmmParam->ucAciAifsn_BG; -+ pucEcw = &prIeWmmParam->ucEcw_BG; -+ pucTxopLimit = prIeWmmParam->aucTxopLimit_BG; -+ } else if (eAci == WMM_AC_VI_INDEX) { -+ pucAciAifsn = &prIeWmmParam->ucAciAifsn_VI; -+ pucEcw = &prIeWmmParam->ucEcw_VI; -+ pucTxopLimit = prIeWmmParam->aucTxopLimit_VI; -+ } else if (eAci == WMM_AC_VO_INDEX) { -+ pucAciAifsn = &prIeWmmParam->ucAciAifsn_VO; -+ pucEcw = &prIeWmmParam->ucEcw_VO; -+ pucTxopLimit = prIeWmmParam->aucTxopLimit_VO; -+ } -+ -+ *pucAciAifsn = (UINT_8) (aucACI[eAci] -+ | (prBssInfo->arACQueParmsForBcast[eAci].fgIsACMSet ? WMM_ACIAIFSN_ACM : 0) -+ | (prBssInfo->arACQueParmsForBcast[eAci].u2Aifsn & (WMM_ACIAIFSN_AIFSN))); -+#endif -+ -+#if 1 -+/* *( ((PUINT_8)(&prIeWmmParam->ucEcw_BE)) + (eAci <<2) ) = (UINT_8) (0 */ -+ *pucEcw = (UINT_8) (0 | (((prBssInfo->aucCWminLog2ForBcast[eAci])) & WMM_ECW_WMIN_MASK) -+ | ((((prBssInfo->aucCWmaxLog2ForBcast[eAci])) << WMM_ECW_WMAX_OFFSET) & -+ WMM_ECW_WMAX_MASK) -+ ); -+#else -+ *(((PUINT_8) (&prIeWmmParam->ucEcw_BE)) + (eAci << 2)) = (UINT_8) (0 -+ | -+ (cwlog2 -+ ((prBssInfo->arACQueParmsForBcast -+ [eAci].u2CWmin + -+ 1)) & WMM_ECW_WMIN_MASK) -+ | -+ ((cwlog2 -+ ((prBssInfo->arACQueParmsForBcast -+ [eAci].u2CWmax + -+ 1)) << WMM_ECW_WMAX_OFFSET) & -+ WMM_ECW_WMAX_MASK) -+ ); -+#endif -+ -+#if 0 -+ WLAN_SET_FIELD_16(((PUINT_8) (prIeWmmParam->aucTxopLimit_BE)) + (eAci << 2) -+ , prBssInfo->arACQueParmsForBcast[eAci].u2TxopLimit); -+#else -+ WLAN_SET_FIELD_16(pucTxopLimit, prBssInfo->arACQueParmsForBcast[eAci].u2TxopLimit); -+#endif -+ } -+ -+ /* Increment the total IE length for the Element ID and Length fields. */ -+ return IE_SIZE(prIeWmmParam); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Generate the WMM Param IE -+* -+* \param[in] prAdapter Adapter pointer -+* @param prMsduInfo The TX MMPDU -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID mqmGenerateWmmParamIE(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo) -+{ -+ P_IE_WMM_PARAM_T prIeWmmParam; -+ -+#if 0 -+ UINT_8 aucWfaOui[] = VENDOR_OUI_WFA; -+ -+ UINT_8 aucACI[] = { -+ WMM_ACI_AC_BE, -+ WMM_ACI_AC_BK, -+ WMM_ACI_AC_VI, -+ WMM_ACI_AC_VO -+ }; -+ ENUM_WMM_ACI_T eAci; -+#endif -+ -+ P_BSS_INFO_T prBssInfo; -+ P_STA_RECORD_T prStaRec; -+ -+ DEBUGFUNC("mqmGenerateWmmParamIE"); -+ DBGLOG(QM, LOUD, "\n"); -+ -+ ASSERT(prMsduInfo); -+ -+ /* In case QoS is not turned off, exit directly */ -+ if (!prAdapter->rWifiVar.fgSupportQoS) -+ return; -+ -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); -+ -+ if (prStaRec) { -+ if (!prStaRec->fgIsQoS) -+ return; -+ } -+ -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prMsduInfo->ucNetworkType]); -+ -+ if (!prBssInfo->fgIsQBSS) -+ return; -+/* 20120220 frog: update beacon content & change OP mode is a separate event for P2P network. */ -+#if 0 -+ if (prBssInfo->eCurrentOPMode != OP_MODE_ACCESS_POINT && prBssInfo->eCurrentOPMode != OP_MODE_BOW) -+ return; -+#endif -+ -+ prIeWmmParam = (P_IE_WMM_PARAM_T) -+ ((PUINT_8) prMsduInfo->prPacket + prMsduInfo->u2FrameLength); -+ -+#if 0 -+ prIeWmmParam->ucId = ELEM_ID_WMM; -+ prIeWmmParam->ucLength = ELEM_MAX_LEN_WMM_PARAM; -+ -+ /* WMM-2.2.1 WMM Information Element Field Values */ -+ prIeWmmParam->aucOui[0] = aucWfaOui[0]; -+ prIeWmmParam->aucOui[1] = aucWfaOui[1]; -+ prIeWmmParam->aucOui[2] = aucWfaOui[2]; -+ prIeWmmParam->ucOuiType = VENDOR_OUI_TYPE_WMM; -+ prIeWmmParam->ucOuiSubtype = VENDOR_OUI_SUBTYPE_WMM_PARAM; -+ -+ prIeWmmParam->ucVersion = VERSION_WMM; -+ prIeWmmParam->ucQosInfo = (prBssInfo->ucWmmParamSetCount & WMM_QOS_INFO_PARAM_SET_CNT); -+ -+ /* UAPSD initial queue configurations (delivery and trigger enabled) */ -+ if (prAdapter->rWifiVar.fgSupportUAPSD) -+ prIeWmmParam->ucQosInfo |= WMM_QOS_INFO_UAPSD; -+ -+ /* EDCA parameter */ -+ -+ for (eAci = 0; eAci < WMM_AC_INDEX_NUM; eAci++) { -+ -+ /* DBGLOG(QM, LOUD, */ -+ /* ("MQM: eAci = %d, ACM = %d, Aifsn = %d, CWmin = %d, CWmax = %d, TxopLimit = %d\n", */ -+ /* eAci,prBssInfo->arACQueParmsForBcast[eAci].fgIsACMSet , */ -+ /* prBssInfo->arACQueParmsForBcast[eAci].u2Aifsn, */ -+ /* prBssInfo->arACQueParmsForBcast[eAci].u2CWmin, */ -+ /* prBssInfo->arACQueParmsForBcast[eAci].u2CWmax, */ -+ /* prBssInfo->arACQueParmsForBcast[eAci].u2TxopLimit)); */ -+ -+ *(((PUINT_8) (&prIeWmmParam->ucAciAifsn_BE)) + (eAci << 2)) = (UINT_8) (aucACI[eAci] -+ | -+ (prBssInfo->arACQueParmsForBcast -+ [eAci].fgIsACMSet ? -+ WMM_ACIAIFSN_ACM : 0) -+ | -+ (prBssInfo->arACQueParmsForBcast -+ [eAci].u2Aifsn & -+ (WMM_ACIAIFSN_AIFSN))); -+#if 1 -+ *(((PUINT_8) (&prIeWmmParam->ucEcw_BE)) + (eAci << 2)) = (UINT_8) (0 -+ | -+ (((prBssInfo->aucCWminLog2ForBcast -+ [eAci])) & WMM_ECW_WMIN_MASK) -+ | -+ ((((prBssInfo->aucCWmaxLog2ForBcast -+ [eAci])) << WMM_ECW_WMAX_OFFSET) -+ & WMM_ECW_WMAX_MASK) -+ ); -+#else -+ *(((PUINT_8) (&prIeWmmParam->ucEcw_BE)) + (eAci << 2)) = (UINT_8) (0 -+ | -+ (cwlog2 -+ ((prBssInfo->arACQueParmsForBcast -+ [eAci].u2CWmin + -+ 1)) & WMM_ECW_WMIN_MASK) -+ | -+ ((cwlog2 -+ ((prBssInfo->arACQueParmsForBcast -+ [eAci].u2CWmax + -+ 1)) << WMM_ECW_WMAX_OFFSET) & -+ WMM_ECW_WMAX_MASK) -+ ); -+#endif -+ -+ WLAN_SET_FIELD_16(((PUINT_8) (prIeWmmParam->aucTxopLimit_BE)) + (eAci << 2) -+ , prBssInfo->arACQueParmsForBcast[eAci].u2TxopLimit); -+ -+ } -+ -+ /* Increment the total IE length for the Element ID and Length fields. */ -+ prMsduInfo->u2FrameLength += IE_SIZE(prIeWmmParam); -+#else -+ -+ prMsduInfo->u2FrameLength += mqmGenerateWmmParamIEByParam(prAdapter, -+ prBssInfo, (UINT_8 *) prIeWmmParam, OP_MODE_ACCESS_POINT); -+#endif -+} -+ -+ENUM_FRAME_ACTION_T -+qmGetFrameAction(IN P_ADAPTER_T prAdapter, -+ IN ENUM_NETWORK_TYPE_INDEX_T eNetworkType, -+ IN UINT_8 ucStaRecIdx, IN P_MSDU_INFO_T prMsduInfo, IN ENUM_FRAME_TYPE_IN_CMD_Q_T eFrameType) -+{ -+ P_BSS_INFO_T prBssInfo; -+ P_STA_RECORD_T prStaRec; -+ P_WLAN_MAC_HEADER_T prWlanFrame; -+ UINT_16 u2TxFrameCtrl; -+ -+ DEBUGFUNC("qmGetFrameAction"); -+ -+#if (NIC_TX_BUFF_COUNT_TC4 > 2) -+#define QM_MGMT_QUUEUD_THRESHOLD 2 -+#else -+#define QM_MGMT_QUUEUD_THRESHOLD 1 -+#endif -+ -+ DATA_STRUCT_INSPECTING_ASSERT(QM_MGMT_QUUEUD_THRESHOLD <= (NIC_TX_BUFF_COUNT_TC4)); -+ DATA_STRUCT_INSPECTING_ASSERT(QM_MGMT_QUUEUD_THRESHOLD > 0); -+ -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[eNetworkType]); -+ prStaRec = QM_GET_STA_REC_PTR_FROM_INDEX(prAdapter, ucStaRecIdx); -+ -+ /* XXX Check BOW P2P AIS time ot set active */ -+ if (!IS_BSS_ACTIVE(prBssInfo)) { -+ if (eFrameType == FRAME_TYPE_MMPDU) { -+ prWlanFrame = (P_WLAN_MAC_HEADER_T) prMsduInfo->prPacket; -+ u2TxFrameCtrl = (prWlanFrame->u2FrameCtrl) & MASK_FRAME_TYPE; /* Optimized for ARM */ -+ if (((u2TxFrameCtrl == MAC_FRAME_DEAUTH) -+ && (prMsduInfo->pfTxDoneHandler == NULL)) -+ || (u2TxFrameCtrl == MAC_FRAME_ACTION)) /* whsu */ -+ return FRAME_ACTION_TX_PKT; -+ } -+ -+ DBGLOG(QM, WARN, "Drop packets Action, eFrameType: %d (Bss Index %u).\n", -+ eFrameType, prBssInfo->ucNetTypeIndex); -+ TX_INC_CNT(&prAdapter->rTxCtrl, TX_INACTIVE_BSS_DROP); -+ return FRAME_ACTION_DROP_PKT; -+ } -+ -+ /* TODO Handle disconnect issue */ -+ -+ /* P2P probe Request frame */ -+ do { -+ if (eFrameType == FRAME_TYPE_MMPDU) { -+ prWlanFrame = (P_WLAN_MAC_HEADER_T) prMsduInfo->prPacket; -+ u2TxFrameCtrl = (prWlanFrame->u2FrameCtrl) & MASK_FRAME_TYPE; /* Optimized for ARM */ -+ -+ if (u2TxFrameCtrl == MAC_FRAME_BEACON) { -+ if (prBssInfo->fgIsNetAbsent) -+ return FRAME_ACTION_DROP_PKT; -+ } else if (u2TxFrameCtrl == MAC_FRAME_PROBE_RSP) { -+ if (prBssInfo->fgIsNetAbsent) -+ return FRAME_ACTION_DROP_PKT; -+ } else if (u2TxFrameCtrl == MAC_FRAME_DEAUTH) { -+ if (prBssInfo->fgIsNetAbsent) -+ break; -+ DBGLOG(P2P, LOUD, "Sending DEAUTH Frame\n"); -+ return FRAME_ACTION_TX_PKT; -+ } -+ /* MMPDU with prStaRec && fgIsInUse not check fgIsNetActive */ -+ else if (u2TxFrameCtrl == MAC_FRAME_ASSOC_REQ -+ || u2TxFrameCtrl == MAC_FRAME_AUTH -+ || u2TxFrameCtrl == MAC_FRAME_REASSOC_REQ -+ || u2TxFrameCtrl == MAC_FRAME_PROBE_REQ || u2TxFrameCtrl == MAC_FRAME_ACTION) { -+ -+ if ((prStaRec) && (prStaRec->fgIsInPS)) { -+ if (nicTxGetResource(prAdapter, TC4_INDEX) >= QM_MGMT_QUUEUD_THRESHOLD) -+ return FRAME_ACTION_TX_PKT; -+ else -+ return FRAME_ACTION_QUEUE_PKT; -+ } -+ return FRAME_ACTION_TX_PKT; -+ } -+ -+ if (!prStaRec) -+ return FRAME_ACTION_TX_PKT; -+ -+ if (!prStaRec->fgIsInUse) -+ return FRAME_ACTION_DROP_PKT; -+ -+ } /* FRAME_TYPE_MMPDU */ -+ else if (eFrameType == FRAME_TYPE_802_1X) { -+ -+ if (!prStaRec) -+ return FRAME_ACTION_TX_PKT; -+ -+ if (!prStaRec->fgIsInUse) -+ return FRAME_ACTION_DROP_PKT; -+ if (prStaRec->fgIsInPS) { -+ if (nicTxGetResource(prAdapter, TC4_INDEX) >= QM_MGMT_QUUEUD_THRESHOLD) -+ return FRAME_ACTION_TX_PKT; -+ else -+ return FRAME_ACTION_QUEUE_PKT; -+ } -+ -+ } /* FRAME_TYPE_802_1X */ -+ else if ((!IS_BSS_ACTIVE(prBssInfo)) -+ || (!prStaRec) -+ || (!prStaRec->fgIsInUse)) { -+ return FRAME_ACTION_DROP_PKT; -+ } -+ } while (0); -+ -+ if (prBssInfo->fgIsNetAbsent) { -+ DBGLOG(QM, LOUD, "Queue packets (Absent %u).\n", prBssInfo->ucNetTypeIndex); -+ return FRAME_ACTION_QUEUE_PKT; -+ } -+ -+ if (prStaRec && prStaRec->fgIsInPS) { -+ DBGLOG(QM, LOUD, "Queue packets (PS %u).\n", prStaRec->fgIsInPS); -+ return FRAME_ACTION_QUEUE_PKT; -+ } -+ switch (eFrameType) { -+ case FRAME_TYPE_802_1X: -+ if (!prStaRec->fgIsValid) -+ return FRAME_ACTION_QUEUE_PKT; -+ break; -+ -+ case FRAME_TYPE_MMPDU: -+ break; -+ -+ default: -+ ASSERT(0); -+ } -+ -+ return FRAME_ACTION_TX_PKT; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Handle BSS change operation Event from the FW -+* -+* \param[in] prAdapter Adapter pointer -+* \param[in] prEvent The event packet from the FW -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID qmHandleEventBssAbsencePresence(IN P_ADAPTER_T prAdapter, IN P_WIFI_EVENT_T prEvent) -+{ -+ P_EVENT_BSS_ABSENCE_PRESENCE_T prEventBssStatus; -+ P_BSS_INFO_T prBssInfo; -+ BOOLEAN fgIsNetAbsentOld; -+ -+ prEventBssStatus = (P_EVENT_BSS_ABSENCE_PRESENCE_T) prEvent; -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prEventBssStatus->ucNetTypeIdx]); -+ fgIsNetAbsentOld = prBssInfo->fgIsNetAbsent; -+ prBssInfo->fgIsNetAbsent = prEventBssStatus->fgIsAbsent; -+ prBssInfo->ucBssFreeQuota = prEventBssStatus->ucBssFreeQuota; -+ -+ /* DBGLOG(QM, TRACE, ("qmHandleEventBssAbsencePresence (ucNetTypeIdx=%d, fgIsAbsent=%d, FreeQuota=%d)\n", */ -+ /* prEventBssStatus->ucNetTypeIdx, prBssInfo->fgIsNetAbsent, prBssInfo->ucBssFreeQuota)); */ -+ -+ DBGLOG(QM, INFO, "NAF=%d,%d,%d\n", -+ prEventBssStatus->ucNetTypeIdx, prBssInfo->fgIsNetAbsent, prBssInfo->ucBssFreeQuota); -+ -+ if (!prBssInfo->fgIsNetAbsent) { -+ /* QM_DBG_CNT_27 */ -+ QM_DBG_CNT_INC(&(prAdapter->rQM), QM_DBG_CNT_27); -+ } else { -+ /* QM_DBG_CNT_28 */ -+ QM_DBG_CNT_INC(&(prAdapter->rQM), QM_DBG_CNT_28); -+ } -+ /* From Absent to Present */ -+ if ((fgIsNetAbsentOld) && (!prBssInfo->fgIsNetAbsent)) -+ kalSetEvent(prAdapter->prGlueInfo); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Handle STA change PS mode Event from the FW -+* -+* \param[in] prAdapter Adapter pointer -+* \param[in] prEvent The event packet from the FW -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID qmHandleEventStaChangePsMode(IN P_ADAPTER_T prAdapter, IN P_WIFI_EVENT_T prEvent) -+{ -+ P_EVENT_STA_CHANGE_PS_MODE_T prEventStaChangePsMode; -+ P_STA_RECORD_T prStaRec; -+ BOOLEAN fgIsInPSOld; -+ -+ /* DbgPrint("QM:Event -RxBa\n"); */ -+ -+ prEventStaChangePsMode = (P_EVENT_STA_CHANGE_PS_MODE_T) prEvent; -+ prStaRec = QM_GET_STA_REC_PTR_FROM_INDEX(prAdapter, prEventStaChangePsMode->ucStaRecIdx); -+ ASSERT(prStaRec); -+ -+ if (prStaRec) { -+ -+ fgIsInPSOld = prStaRec->fgIsInPS; -+ prStaRec->fgIsInPS = prEventStaChangePsMode->fgIsInPs; -+ -+ qmUpdateFreeQuota(prAdapter, -+ prStaRec, -+ prEventStaChangePsMode->ucUpdateMode, prEventStaChangePsMode->ucFreeQuota, 0); -+ -+ /* DBGLOG(QM, TRACE, ("qmHandleEventStaChangePsMode (ucStaRecIdx=%d, fgIsInPs=%d)\n", */ -+ /* prEventStaChangePsMode->ucStaRecIdx, prStaRec->fgIsInPS)); */ -+ -+ DBGLOG(QM, TRACE, "PS=%d,%d\n", prEventStaChangePsMode->ucStaRecIdx, prStaRec->fgIsInPS); -+ -+ /* From PS to Awake */ -+ if ((fgIsInPSOld) && (!prStaRec->fgIsInPS)) -+ kalSetEvent(prAdapter->prGlueInfo); -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Update STA free quota Event from FW -+* -+* \param[in] prAdapter Adapter pointer -+* \param[in] prEvent The event packet from the FW -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID qmHandleEventStaUpdateFreeQuota(IN P_ADAPTER_T prAdapter, IN P_WIFI_EVENT_T prEvent) -+{ -+ P_EVENT_STA_UPDATE_FREE_QUOTA_T prEventStaUpdateFreeQuota; -+ P_STA_RECORD_T prStaRec; -+ -+ prEventStaUpdateFreeQuota = (P_EVENT_STA_UPDATE_FREE_QUOTA_T) prEvent; -+ prStaRec = QM_GET_STA_REC_PTR_FROM_INDEX(prAdapter, prEventStaUpdateFreeQuota->ucStaRecIdx); -+ ASSERT(prStaRec); -+ -+ if (prStaRec) { -+ if (prStaRec->fgIsInPS) { -+ qmUpdateFreeQuota(prAdapter, -+ prStaRec, -+ prEventStaUpdateFreeQuota->ucUpdateMode, -+ prEventStaUpdateFreeQuota->ucFreeQuota, -+ prEventStaUpdateFreeQuota->aucReserved[0]); -+ -+ kalSetEvent(prAdapter->prGlueInfo); -+ } -+#if 0 -+ DBGLOG(QM, TRACE, -+ "qmHandleEventStaUpdateFreeQuota (ucStaRecIdx=%d, ucUpdateMode=%d, ucFreeQuota=%d)\n", -+ prEventStaUpdateFreeQuota->ucStaRecIdx, prEventStaUpdateFreeQuota->ucUpdateMode, -+ prEventStaUpdateFreeQuota->ucFreeQuota); -+#endif -+ -+ DBGLOG(QM, TRACE, "UFQ=%d,%d,%d\n", -+ prEventStaUpdateFreeQuota->ucStaRecIdx, -+ prEventStaUpdateFreeQuota->ucUpdateMode, prEventStaUpdateFreeQuota->ucFreeQuota); -+ -+ } -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Update STA free quota -+* -+* \param[in] prStaRec the STA -+* \param[in] ucUpdateMode the method to update free quota -+* \param[in] ucFreeQuota the value for update -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+qmUpdateFreeQuota(IN P_ADAPTER_T prAdapter, -+ IN P_STA_RECORD_T prStaRec, IN UINT_8 ucUpdateMode, IN UINT_8 ucFreeQuota, IN UINT_8 ucNumOfTxDone) -+{ -+ -+ UINT_8 ucFreeQuotaForNonDelivery; -+ UINT_8 ucFreeQuotaForDelivery; -+ BOOLEAN flgIsUpdateForcedToDelivery; -+ -+ ASSERT(prStaRec); -+ DBGLOG(QM, LOUD, "qmUpdateFreeQuota orig ucFreeQuota=%d Mode %u New %u\n", -+ prStaRec->ucFreeQuota, ucUpdateMode, ucFreeQuota); -+ -+ if (!prStaRec->fgIsInPS) -+ return; -+ -+ flgIsUpdateForcedToDelivery = FALSE; -+ -+ if (ucNumOfTxDone > 0) { -+ /* -+ update free quota by -+ num of tx done + resident free quota (delivery + non-delivery) -+ */ -+ UINT_8 ucAvailQuota; -+ -+ ucAvailQuota = ucNumOfTxDone + prStaRec->ucFreeQuotaForDelivery + prStaRec->ucFreeQuotaForNonDelivery; -+ if (ucAvailQuota > ucFreeQuota) /* sanity check */ -+ ucAvailQuota = ucFreeQuota; -+ -+ /* update current free quota */ -+ ucFreeQuota = ucAvailQuota; -+ -+ /* check if the update is from last packet */ -+ if (ucFreeQuota == (prStaRec->ucFreeQuota + 1)) { -+ /* just add the extra quota to delivery queue */ -+ -+ /* -+ EX: -+ 1. TDLS peer enters power save -+ 2. When the last 2 VI packets are tx done, we will receive 2 update events -+ 3. 1st update event: ucFreeQuota = 9 -+ 4. We will correct new quota for delivey and non-delivery to 7:2 -+ 5. 2rd update event: ucFreeQuota = 10 -+ 6. We will re-correct new quota for delivery and non-delivery to 5:5 -+ -+ But non-delivery queue is not busy. -+ So in the case, we will have wrong decision, i.e. higher queue always quota 5 -+ -+ Solution: skip the 2rd update event and just add the extra quota to delivery. -+ */ -+ -+ flgIsUpdateForcedToDelivery = TRUE; -+ } -+ } -+ -+ switch (ucUpdateMode) { -+ case FREE_QUOTA_UPDATE_MODE_INIT: -+ case FREE_QUOTA_UPDATE_MODE_OVERWRITE: -+ prStaRec->ucFreeQuota = ucFreeQuota; -+ break; -+ case FREE_QUOTA_UPDATE_MODE_INCREASE: -+ prStaRec->ucFreeQuota += ucFreeQuota; -+ break; -+ case FREE_QUOTA_UPDATE_MODE_DECREASE: -+ prStaRec->ucFreeQuota -= ucFreeQuota; -+ break; -+ default: -+ ASSERT(0); -+ } -+ -+ DBGLOG(QM, LOUD, "qmUpdateFreeQuota new ucFreeQuota=%d)\n", prStaRec->ucFreeQuota); -+ -+ ucFreeQuota = prStaRec->ucFreeQuota; -+ -+ ucFreeQuotaForNonDelivery = 0; -+ ucFreeQuotaForDelivery = 0; -+ -+ if (ucFreeQuota > 0) { -+ if (prStaRec->fgIsQoS && prStaRec->fgIsUapsdSupported -+ /* && prAdapter->rWifiVar.fgSupportQoS -+ && prAdapter->rWifiVar.fgSupportUAPSD */) { -+ /* XXX We should assign quota to aucFreeQuotaPerQueue[NUM_OF_PER_STA_TX_QUEUES] */ -+ -+ if (flgIsUpdateForcedToDelivery == FALSE) { -+ if (prStaRec->ucFreeQuotaForNonDelivery > 0 && prStaRec->ucFreeQuotaForDelivery > 0) { -+ ucFreeQuotaForNonDelivery = ucFreeQuota >> 1; -+ ucFreeQuotaForDelivery = ucFreeQuota - ucFreeQuotaForNonDelivery; -+ } else if (prStaRec->ucFreeQuotaForNonDelivery == 0 -+ && prStaRec->ucFreeQuotaForDelivery == 0) { -+ ucFreeQuotaForNonDelivery = ucFreeQuota >> 1; -+ ucFreeQuotaForDelivery = ucFreeQuota - ucFreeQuotaForNonDelivery; -+ } else if (prStaRec->ucFreeQuotaForNonDelivery > 0) { -+ /* NonDelivery is not busy */ -+ if (ucFreeQuota >= 3) { -+ ucFreeQuotaForNonDelivery = 2; -+ ucFreeQuotaForDelivery = ucFreeQuota - ucFreeQuotaForNonDelivery; -+ } else { -+ ucFreeQuotaForDelivery = ucFreeQuota; -+ ucFreeQuotaForNonDelivery = 0; -+ } -+ } else if (prStaRec->ucFreeQuotaForDelivery > 0) { -+ /* Delivery is not busy */ -+ if (ucFreeQuota >= 3) { -+ ucFreeQuotaForDelivery = 2; -+ ucFreeQuotaForNonDelivery = ucFreeQuota - ucFreeQuotaForDelivery; -+ } else { -+ ucFreeQuotaForNonDelivery = ucFreeQuota; -+ ucFreeQuotaForDelivery = 0; -+ } -+ } -+ } else { -+ ucFreeQuotaForNonDelivery = 2; -+ ucFreeQuotaForDelivery = ucFreeQuota - ucFreeQuotaForNonDelivery; -+ } -+ } else { -+ /* no use ? */ -+ /* !prStaRec->fgIsUapsdSupported */ -+ ucFreeQuotaForNonDelivery = ucFreeQuota; -+ ucFreeQuotaForDelivery = 0; -+ } -+ } -+ /* ucFreeQuota > 0 */ -+ prStaRec->ucFreeQuotaForDelivery = ucFreeQuotaForDelivery; -+ prStaRec->ucFreeQuotaForNonDelivery = ucFreeQuotaForNonDelivery; -+ -+#if (CFG_SUPPORT_TDLS_DBG == 1) -+ if (IS_TDLS_STA(prStaRec)) -+ DBGLOG(QM, LOUD, " quota %d %d %d\n", -+ ucFreeQuota, ucFreeQuotaForDelivery, ucFreeQuotaForNonDelivery); -+#endif -+ -+ DBGLOG(QM, LOUD, "new QuotaForDelivery = %d QuotaForNonDelivery = %d\n", -+ prStaRec->ucFreeQuotaForDelivery, prStaRec->ucFreeQuotaForNonDelivery); -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Return the reorder queued RX packets -+* -+* \param[in] (none) -+* -+* \return The number of queued RX packets -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT_32 qmGetRxReorderQueuedBufferCount(IN P_ADAPTER_T prAdapter) -+{ -+ UINT_32 i, u4Total; -+ P_QUE_MGT_T prQM = &prAdapter->rQM; -+ -+ u4Total = 0; -+ /* XXX The summation may impact the performance */ -+ for (i = 0; i < CFG_NUM_OF_RX_BA_AGREEMENTS; i++) { -+ u4Total += prQM->arRxBaTable[i].rReOrderQue.u4NumElem; -+#if DBG && 0 -+ if (QUEUE_IS_EMPTY(&(prQM->arRxBaTable[i].rReOrderQue))) -+ ASSERT(prQM->arRxBaTable[i].rReOrderQue == 0); -+#endif -+ } -+ ASSERT(u4Total <= (CFG_NUM_OF_QM_RX_PKT_NUM * 2)); -+ return u4Total; -+} -+ -+#if ARP_MONITER_ENABLE -+VOID qmDetectArpNoResponse(P_ADAPTER_T prAdapter, P_MSDU_INFO_T prMsduInfo) -+{ -+ struct sk_buff *prSkb = NULL; -+ PUINT_8 pucData = NULL; -+ UINT_16 u2EtherType = 0; -+ int arpOpCode = 0; -+ -+ prSkb = (struct sk_buff *)prMsduInfo->prPacket; -+ -+ if (!prSkb || (prSkb->len <= ETHER_HEADER_LEN)) -+ return; -+ -+ pucData = prSkb->data; -+ if (!pucData) -+ return; -+ u2EtherType = (pucData[ETH_TYPE_LEN_OFFSET] << 8) | (pucData[ETH_TYPE_LEN_OFFSET + 1]); -+ -+ if (u2EtherType != ETH_P_ARP || (apIp[0] | apIp[1] | apIp[2] | apIp[3]) == 0) -+ return; -+ -+ if (strncmp(apIp, &pucData[ETH_TYPE_LEN_OFFSET + 26], sizeof(apIp))) /* dest ip address */ -+ return; -+ -+ arpOpCode = (pucData[ETH_TYPE_LEN_OFFSET + 8] << 8) | (pucData[ETH_TYPE_LEN_OFFSET + 8 + 1]); -+ if (arpOpCode == ARP_PRO_REQ) { -+ arpMoniter++; -+ if (arpMoniter > 20) { -+ DBGLOG(INIT, WARN, "IOT Critical issue, arp no resp, check AP!\n"); -+ aisBssBeaconTimeout(prAdapter); -+ arpMoniter = 0; -+ kalMemZero(apIp, sizeof(apIp)); -+ } -+ } -+} -+ -+VOID qmHandleRxArpPackets(P_ADAPTER_T prAdapter, P_SW_RFB_T prSwRfb) -+{ -+ PUINT_8 pucData = NULL; -+ UINT_16 u2EtherType = 0; -+ int arpOpCode = 0; -+ P_BSS_INFO_T prBssInfo = NULL; -+ -+ if (prSwRfb->u2PacketLen <= ETHER_HEADER_LEN) -+ return; -+ -+ pucData = (PUINT_8)prSwRfb->pvHeader; -+ if (!pucData) -+ return; -+ u2EtherType = (pucData[ETH_TYPE_LEN_OFFSET] << 8) | (pucData[ETH_TYPE_LEN_OFFSET + 1]); -+ -+ if (u2EtherType != ETH_P_ARP) -+ return; -+ -+ arpOpCode = (pucData[ETH_TYPE_LEN_OFFSET + 8] << 8) | (pucData[ETH_TYPE_LEN_OFFSET + 8 + 1]); -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ if (arpOpCode == ARP_PRO_RSP) { -+ arpMoniter = 0; -+ if (prBssInfo && prBssInfo->prStaRecOfAP && prBssInfo->prStaRecOfAP->aucMacAddr) { -+ if (EQUAL_MAC_ADDR(&(pucData[ETH_TYPE_LEN_OFFSET + 10]), /* source hardware address */ -+ prBssInfo->prStaRecOfAP->aucMacAddr)) { -+ strncpy(apIp, &(pucData[ETH_TYPE_LEN_OFFSET + 16]), sizeof(apIp)); /* src ip address */ -+ DBGLOG(INIT, TRACE, "get arp response from AP %d.%d.%d.%d\n", -+ apIp[0], apIp[1], apIp[2], apIp[3]); -+ } -+ } -+ } -+} -+ -+VOID qmResetArpDetect(VOID) -+{ -+ arpMoniter = 0; -+ kalMemZero(apIp, sizeof(apIp)); -+} -+#endif -+ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_bow.c b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_bow.c -new file mode 100644 -index 000000000000..6f5c0bcdd90b ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_bow.c -@@ -0,0 +1,1177 @@ -+/* -+** Id: @(#) gl_bow.c@@ -+*/ -+ -+/*! \file gl_bow.c -+ \brief Main routines of Linux driver interface for 802.11 PAL (BT 3.0 + HS) -+ -+ This file contains the main routines of Linux driver for MediaTek Inc. 802.11 -+ Wireless LAN Adapters. -+*/ -+ -+/* -+** Log: gl_bow.c -+ * -+ * 02 16 2012 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * [ALPS00235223] [Rose][ICS][Cross Feature][AEE-IPANIC]The device reboot automatically and then the "KE" pops up -+ * after you turn on the "Airplane mode".(once) -+ * -+ * [Root Cause] -+ * PAL operates BOW char dev poll after BOW char dev is registered. -+ * -+ * [Solution] -+ * Rejects PAL char device operation after BOW is unregistered or when wlan GLUE_FLAG_HALT is set. -+ * -+ * This is a workaround for BOW driver robustness, happens only in ICS. -+ * -+ * Root cause should be fixed by CR [ALPS00231570] -+ * -+ * 02 03 2012 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * [ALPS00118114] [Rose][ICS][Free Test][Bluetooth]The "KE" pops up after you turn on the airplane mode.(5/5) -+ * -+ * [Root Cause] -+ * PAL operates BOW char dev poll after BOW char dev is registered. -+ * -+ * [Solution] -+ * Rejects PAL char device operation after BOW is unregistered. -+ * -+ * Happens only in ICS. -+ * -+ * Notified PAL owener to reivew MTKBT/PAL closing BOW char dev procedure. -+ * -+ * [Side Effect] -+ * None. -+ * -+ * 01 16 2012 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Support BOW for 5GHz band. -+ * -+ * 11 10 2011 cp.wu -+ * [WCXRP00001098] [MT6620 Wi-Fi][Driver] Replace printk by DBG LOG macros in linux porting layer -+ * 1. eliminaite direct calls to printk in porting layer. -+ * 2. replaced by DBGLOG, which would be XLOG on ALPS platforms. -+ * -+ * 10 25 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Modify ampc0 char device for major number 151 for all MT6575 projects. -+ * -+ * 07 28 2011 cp.wu -+ * [WCXRP00000884] [MT6620 Wi-Fi][Driver] Deprecate ioctl interface by unlocked ioctl -+ * unlocked_ioctl returns as long instead of int. -+ * -+ * 07 28 2011 cp.wu -+ * [WCXRP00000884] [MT6620 Wi-Fi][Driver] Deprecate ioctl interface by unlocked ioctl -+ * migrate to unlocked ioctl interface -+ * -+ * 04 12 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Add WMM IE for BOW initiator data. -+ * -+ * 04 10 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Change Link disconnection event procedure for hotspot and change skb length check to 1514 bytes. -+ * -+ * 04 09 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Change Link connection event procedure and change skb length check to 1512 bytes. -+ * -+ * 03 27 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Support multiple physical link. -+ * -+ * 03 06 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Sync BOW Driver to latest person development branch version.. -+ * -+ * 03 03 2011 jeffrey.chang -+ * [WCXRP00000512] [MT6620 Wi-Fi][Driver] modify the net device relative functions to support the H/W multiple queue -+ * support concurrent network -+ * -+ * 03 03 2011 jeffrey.chang -+ * [WCXRP00000512] [MT6620 Wi-Fi][Driver] modify the net device relative functions to support the H/W multiple queue -+ * replace alloc_netdev to alloc_netdev_mq for BoW -+ * -+ * 03 03 2011 jeffrey.chang -+ * [WCXRP00000512] [MT6620 Wi-Fi][Driver] modify the net device relative functions to support the H/W multiple queue -+ * modify net device relative functions to support multiple H/W queues -+ * -+ * 02 15 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Update net register and BOW for concurrent features. -+ * -+ * 02 10 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Fix kernel API change issue. -+ * Before ALPS 2.2 (2.2 included), kfifo_alloc() is -+ * struct kfifo *kfifo_alloc(unsigned int size, gfp_t gfp_mask, spinlock_t *lock); -+ * After ALPS 2.3, kfifo_alloc() is changed to -+ * int kfifo_alloc(struct kfifo *fifo, unsigned int size, gfp_t gfp_mask); -+ * -+ * 02 09 2011 cp.wu -+ * [WCXRP00000430] [MT6620 Wi-Fi][Firmware][Driver] Create V1.2 branch for MT6620E1 and MT6620E3 -+ * create V1.2 driver branch based on label MT6620_WIFI_DRIVER_V1_2_110209_1031 -+ * with BOW and P2P enabled as default -+ * -+ * 02 08 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Replace kfifo_get and kfifo_put with kfifo_out and kfifo_in. -+ * Update BOW get MAC status, remove returning event for AIS network type. -+ * -+ * 01 12 2011 cp.wu -+ * [WCXRP00000357] [MT6620 Wi-Fi][Driver][Bluetooth over Wi-Fi] add another net device interface for BT AMP -+ * implementation of separate BT_OVER_WIFI data path. -+ * -+ * 01 12 2011 cp.wu -+ * [WCXRP00000356] [MT6620 Wi-Fi][Driver] fill mac header length for security frames 'cause hardware header translation -+ * needs such information -+ * fill mac header length information for 802.1x frames. -+ * -+ * 11 11 2010 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Fix BoW timer assert issue. -+ * -+ * 09 14 2010 chinghwa.yu -+ * NULL -+ * Add bowRunEventAAAComplete. -+ * -+ * 09 14 2010 cp.wu -+ * NULL -+ * correct typo: POLLOUT instead of POLL_OUT -+ * -+ * 09 13 2010 cp.wu -+ * NULL -+ * add waitq for poll() and read(). -+ * -+ * 08 24 2010 chinghwa.yu -+ * NULL -+ * Update BOW for the 1st time. -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 05 05 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * change variable names for multiple physical link to match with coding convention -+ * -+ * 05 05 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * multiple BoW interfaces need to compare with peer address -+ * -+ * 04 28 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * change prefix for data structure used to communicate with 802.11 PAL -+ * to avoid ambiguous naming with firmware interface -+ * -+ * 04 28 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * fix kalIndicateBOWEvent. -+ * -+ * 04 27 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * add multiple physical link support -+ * -+ * 04 13 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * add framework for BT-over-Wi-Fi support. -+ * * * * * * * * * * * * * * * * 1) prPendingCmdInfo is replaced by queue for multiple handler capability -+ * * * * * * * * * * * * * * * * 2) command sequence number is now increased atomically -+ * * * * * * * * * * * * * * * * 3) private data could be hold and taken use for other purpose -+** -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "gl_os.h" -+#include "debug.h" -+#include "wlan_lib.h" -+#include "gl_wext.h" -+#include "precomp.h" -+#include -+#include "bss.h" -+ -+#if CFG_ENABLE_BT_OVER_WIFI -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+/* @FIXME if there is command/event with payload length > 28 */ -+#define MAX_BUFFER_SIZE (64) -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+#if CFG_BOW_TEST -+UINT_32 g_u4PrevSysTime = 0; -+UINT_32 g_u4CurrentSysTime = 0; -+UINT_32 g_arBowRevPalPacketTime[11]; -+#endif -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/* forward declarations */ -+static ssize_t mt6620_ampc_read(IN struct file *filp, IN char __user *buf, IN size_t size, IN OUT loff_t *ppos); -+ -+static ssize_t -+mt6620_ampc_write(IN struct file *filp, OUT const char __user *buf, IN size_t size, IN OUT loff_t *ppos); -+ -+static long mt6620_ampc_ioctl(IN struct file *filp, IN unsigned int cmd, IN OUT unsigned long arg); -+ -+static unsigned int mt6620_ampc_poll(IN struct file *filp, IN poll_table *wait); -+ -+static int mt6620_ampc_open(IN struct inode *inodep, IN struct file *filp); -+ -+static int mt6620_ampc_release(IN struct inode *inodep, IN struct file *filp); -+ -+/* character file operations */ -+static const struct file_operations mt6620_ampc_fops = { -+ /* .owner = THIS_MODULE, */ -+ .read = mt6620_ampc_read, -+ .write = mt6620_ampc_write, -+ .unlocked_ioctl = mt6620_ampc_ioctl, -+ .poll = mt6620_ampc_poll, -+ .open = mt6620_ampc_open, -+ .release = mt6620_ampc_release, -+}; -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Register for character device to communicate with 802.11 PAL -+* -+* \param[in] prGlueInfo Pointer to glue info -+* -+* \return TRUE -+* FALSE -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN glRegisterAmpc(IN P_GLUE_INFO_T prGlueInfo) -+{ -+ ASSERT(prGlueInfo); -+ -+ if (prGlueInfo->rBowInfo.fgIsRegistered == TRUE) -+ return FALSE; -+ -+#if 0 -+ /* 1. allocate major number dynamically */ -+ -+ if (alloc_chrdev_region(&(prGlueInfo->rBowInfo.u4DeviceNumber), 0, /* first minor number */ -+ 1, /* number */ -+ GLUE_BOW_DEVICE_NAME) != 0) -+ -+ return FALSE; -+#endif -+ -+#if 1 -+ -+#if defined(CONFIG_AMPC_CDEV_NUM) -+ prGlueInfo->rBowInfo.u4DeviceNumber = MKDEV(CONFIG_AMPC_CDEV_NUM, 0); -+#else -+ prGlueInfo->rBowInfo.u4DeviceNumber = MKDEV(226, 0); -+#endif -+ -+ if (register_chrdev_region(prGlueInfo->rBowInfo.u4DeviceNumber, 1, /* number */ -+ GLUE_BOW_DEVICE_NAME) != 0) -+ -+ return FALSE; -+#endif -+ -+ /* 2. spin-lock initialization */ -+ /* spin_lock_init(&(prGlueInfo->rBowInfo.rSpinLock)); */ -+ -+ /* 3. initialize kfifo */ -+/* prGlueInfo->rBowInfo.prKfifo = kfifo_alloc(GLUE_BOW_KFIFO_DEPTH, -+ GFP_KERNEL, -+ &(prGlueInfo->rBowInfo.rSpinLock));*/ -+ if ((kfifo_alloc((struct kfifo *)&(prGlueInfo->rBowInfo.rKfifo), GLUE_BOW_KFIFO_DEPTH, GFP_KERNEL))) -+ goto fail_kfifo_alloc; -+ -+/* if(prGlueInfo->rBowInfo.prKfifo == NULL) */ -+ if (&(prGlueInfo->rBowInfo.rKfifo) == NULL) -+ goto fail_kfifo_alloc; -+ -+ /* 4. initialize cdev */ -+ cdev_init(&(prGlueInfo->rBowInfo.cdev), &mt6620_ampc_fops); -+ /* prGlueInfo->rBowInfo.cdev.owner = THIS_MODULE; */ -+ prGlueInfo->rBowInfo.cdev.ops = &mt6620_ampc_fops; -+ -+ /* 5. add character device */ -+ if (cdev_add(&(prGlueInfo->rBowInfo.cdev), prGlueInfo->rBowInfo.u4DeviceNumber, 1)) -+ goto fail_cdev_add; -+ -+ /* 6. in queue initialization */ -+ init_waitqueue_head(&(prGlueInfo->rBowInfo.outq)); -+ -+ /* 7. finish */ -+ prGlueInfo->rBowInfo.fgIsRegistered = TRUE; -+ return TRUE; -+ -+fail_cdev_add: -+ kfifo_free(&(prGlueInfo->rBowInfo.rKfifo)); -+/* kfifo_free(prGlueInfo->rBowInfo.prKfifo); */ -+fail_kfifo_alloc: -+ unregister_chrdev_region(prGlueInfo->rBowInfo.u4DeviceNumber, 1); -+ return FALSE; -+} /* end of glRegisterAmpc */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Unregister character device for communicating with 802.11 PAL -+* -+* \param[in] prGlueInfo Pointer to glue info -+* -+* \return TRUE -+* FALSE -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN glUnregisterAmpc(IN P_GLUE_INFO_T prGlueInfo) -+{ -+ ASSERT(prGlueInfo); -+ -+ if (prGlueInfo->rBowInfo.fgIsRegistered == FALSE) -+ return FALSE; -+ -+ prGlueInfo->rBowInfo.fgIsRegistered = FALSE; -+ -+ /* 1. free netdev if necessary */ -+#if CFG_BOW_SEPARATE_DATA_PATH -+ kalUninitBowDevice(prGlueInfo); -+#endif -+ -+ /* 2. removal of character device */ -+ cdev_del(&(prGlueInfo->rBowInfo.cdev)); -+ -+ /* 3. free kfifo */ -+/* kfifo_free(prGlueInfo->rBowInfo.prKfifo); */ -+ kfifo_free(&(prGlueInfo->rBowInfo.rKfifo)); -+/* prGlueInfo->rBowInfo.prKfifo = NULL; */ -+/* prGlueInfo->rBowInfo.rKfifo = NULL; */ -+ -+ /* 4. free device number */ -+ unregister_chrdev_region(prGlueInfo->rBowInfo.u4DeviceNumber, 1); -+ -+ return TRUE; -+} /* end of glUnregisterAmpc */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief read handler for character device to communicate with 802.11 PAL -+* -+* \param[in] -+* \return -+* Follows Linux Character Device Interface -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static ssize_t mt6620_ampc_read(IN struct file *filp, IN char __user *buf, IN size_t size, IN OUT loff_t *ppos) -+{ -+ UINT_8 aucBuffer[MAX_BUFFER_SIZE]; -+ ssize_t retval; -+ P_GLUE_INFO_T prGlueInfo; -+ -+ prGlueInfo = (P_GLUE_INFO_T) (filp->private_data); -+ -+ ASSERT(prGlueInfo); -+ -+ if ((prGlueInfo->rBowInfo.fgIsRegistered == FALSE) || (prGlueInfo->ulFlag & GLUE_FLAG_HALT)) -+ return -EFAULT; -+ /* size check */ -+/* if(kfifo_len(prGlueInfo->rBowInfo.prKfifo) >= size) */ -+ if (kfifo_len(&(prGlueInfo->rBowInfo.rKfifo)) >= size) -+ retval = size; -+ else -+ retval = kfifo_len(&(prGlueInfo->rBowInfo.rKfifo)); -+/* retval = kfifo_len(prGlueInfo->rBowInfo.prKfifo); */ -+ -+/* kfifo_get(prGlueInfo->rBowInfo.prKfifo, aucBuffer, retval); */ -+/* kfifo_out(prGlueInfo->rBowInfo.prKfifo, aucBuffer, retval); */ -+ if (!(kfifo_out(&(prGlueInfo->rBowInfo.rKfifo), aucBuffer, retval))) { -+ retval = -EIO; -+ return retval; -+ } -+ -+ if (copy_to_user(buf, aucBuffer, retval)) -+ retval = -EIO; -+ -+ return retval; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief write handler for character device to communicate with 802.11 PAL -+* -+* \param[in] -+* \return -+* Follows Linux Character Device Interface -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static ssize_t -+mt6620_ampc_write(IN struct file *filp, OUT const char __user *buf, IN size_t size, IN OUT loff_t *ppos) -+{ -+#if CFG_BOW_TEST -+ UINT_8 i; -+#endif -+ -+ UINT_8 aucBuffer[MAX_BUFFER_SIZE]; -+ P_AMPC_COMMAND prCmd; -+ P_GLUE_INFO_T prGlueInfo; -+ -+ prGlueInfo = (P_GLUE_INFO_T) (filp->private_data); -+ ASSERT(prGlueInfo); -+ -+ if ((prGlueInfo->rBowInfo.fgIsRegistered == FALSE) || (prGlueInfo->ulFlag & GLUE_FLAG_HALT)) -+ return -EFAULT; -+ -+ if (size > MAX_BUFFER_SIZE) -+ return -EINVAL; -+ else if (copy_from_user(aucBuffer, buf, size)) -+ return -EIO; -+ -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "AMP driver CMD buffer size : %d.\n", size); -+ -+ for (i = 0; i < MAX_BUFFER_SIZE; i++) -+ DBGLOG(BOW, EVENT, "AMP write content : 0x%x.\n", aucBuffer[i]); -+ -+ DBGLOG(BOW, EVENT, "BoW CMD write.\n"); -+#endif -+ -+ prCmd = (P_AMPC_COMMAND) aucBuffer; -+ -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "AMP write content payload length : %d.\n", prCmd->rHeader.u2PayloadLength); -+ -+ DBGLOG(BOW, EVENT, "AMP write content header length : %d.\n", sizeof(AMPC_COMMAND_HEADER_T)); -+#endif -+ -+ /* size check */ -+ if (prCmd->rHeader.u2PayloadLength + sizeof(AMPC_COMMAND_HEADER_T) != size) { -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "Wrong CMD total length.\n"); -+#endif -+ -+ return -EINVAL; -+ } -+ -+ if (wlanbowHandleCommand(prGlueInfo->prAdapter, prCmd) == WLAN_STATUS_SUCCESS) -+ return size; -+ else -+ return -EINVAL; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief ioctl handler for character device to communicate with 802.11 PAL -+* -+* \param[in] -+* \return -+* Follows Linux Character Device Interface -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static long mt6620_ampc_ioctl(IN struct file *filp, IN unsigned int cmd, IN OUT unsigned long arg) -+{ -+ int err = 0; -+ P_GLUE_INFO_T prGlueInfo; -+ -+ prGlueInfo = (P_GLUE_INFO_T) (filp->private_data); -+ -+ ASSERT(prGlueInfo); -+ -+ if ((prGlueInfo->rBowInfo.fgIsRegistered == FALSE) || (prGlueInfo->ulFlag & GLUE_FLAG_HALT)) -+ return -EFAULT; -+ /* permission check */ -+ if (_IOC_DIR(cmd) & _IOC_READ) -+ err = !access_ok(VERIFY_WRITE, (void __user *)arg, _IOC_SIZE(cmd)); -+ else if (_IOC_DIR(cmd) & _IOC_WRITE) -+ err = !access_ok(VERIFY_READ, (void __user *)arg, _IOC_SIZE(cmd)); -+ if (err) -+ return -EFAULT; -+ -+ /* no ioctl is implemented yet */ -+ return 0; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief ioctl handler for character device to communicate with 802.11 PAL -+* -+* \param[in] -+* \return -+* Follows Linux Character Device Interface -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static unsigned int mt6620_ampc_poll(IN struct file *filp, IN poll_table *wait) -+{ -+ unsigned int retval; -+ P_GLUE_INFO_T prGlueInfo; -+ -+ prGlueInfo = (P_GLUE_INFO_T) (filp->private_data); -+ -+ ASSERT(prGlueInfo); -+ -+ if ((prGlueInfo->rBowInfo.fgIsRegistered == FALSE) || (prGlueInfo->ulFlag & GLUE_FLAG_HALT)) -+ return -EFAULT; -+ -+ poll_wait(filp, &prGlueInfo->rBowInfo.outq, wait); -+ -+ retval = (POLLOUT | POLLWRNORM); /* always accepts incoming command packets */ -+ -+/* DBGLOG(BOW, EVENT, ("mt6620_ampc_pol, POLLOUT | POLLWRNORM, %x\n", retval)); */ -+ -+/* if(kfifo_len(prGlueInfo->rBowInfo.prKfifo) > 0) */ -+ if (kfifo_len(&(prGlueInfo->rBowInfo.rKfifo)) > 0) { -+ retval |= (POLLIN | POLLRDNORM); -+ -+/* DBGLOG(BOW, EVENT, ("mt6620_ampc_pol, POLLIN | POLLRDNORM, %x\n", retval)); */ -+ -+ } -+ -+ return retval; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief open handler for character device to communicate with 802.11 PAL -+* -+* \param[in] -+* \return -+* Follows Linux Character Device Interface -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static int mt6620_ampc_open(IN struct inode *inodep, IN struct file *filp) -+{ -+ P_GLUE_INFO_T prGlueInfo; -+ P_GL_BOW_INFO prBowInfo; -+ -+ prBowInfo = container_of(inodep->i_cdev, GL_BOW_INFO, cdev); -+ ASSERT(prBowInfo); -+ -+ prGlueInfo = container_of(prBowInfo, GLUE_INFO_T, rBowInfo); -+ ASSERT(prGlueInfo); -+ -+ /* set-up private data */ -+ filp->private_data = prGlueInfo; -+ -+ return 0; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief close handler for character device to communicate with 802.11 PAL -+* -+* \param[in] -+* \return -+* Follows Linux Character Device Interface -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static int mt6620_ampc_release(IN struct inode *inodep, IN struct file *filp) -+{ -+ P_GLUE_INFO_T prGlueInfo; -+ -+ prGlueInfo = (P_GLUE_INFO_T) (filp->private_data); -+ -+ ASSERT(prGlueInfo); -+ -+ return 0; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief to indicate event for Bluetooth over Wi-Fi -+* -+* \param[in] -+* prGlueInfo -+* prEvent -+* \return -+* none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID kalIndicateBOWEvent(IN P_GLUE_INFO_T prGlueInfo, IN P_AMPC_EVENT prEvent) -+{ -+ size_t u4AvailSize, u4EventSize; -+ -+ ASSERT(prGlueInfo); -+ ASSERT(prEvent); -+ -+ /* check device */ -+ if ((prGlueInfo->rBowInfo.fgIsRegistered == FALSE) || (prGlueInfo->ulFlag & GLUE_FLAG_HALT)) -+ return; -+ -+/* u4AvailSize = -+ GLUE_BOW_KFIFO_DEPTH - kfifo_len(prGlueInfo->rBowInfo.prKfifo);*/ -+ -+ u4AvailSize = GLUE_BOW_KFIFO_DEPTH - kfifo_len(&(prGlueInfo->rBowInfo.rKfifo)); -+ -+ u4EventSize = prEvent->rHeader.u2PayloadLength + sizeof(AMPC_EVENT_HEADER_T); -+ -+ /* check kfifo availability */ -+ if (u4AvailSize < u4EventSize) { -+ DBGLOG(BOW, EVENT, "[bow] no space for event: %zu/%zu\n", u4EventSize, u4AvailSize); -+ return; -+ } -+ /* queue into kfifo */ -+/* kfifo_put(prGlueInfo->rBowInfo.prKfifo, (PUINT_8)prEvent, u4EventSize); */ -+/* kfifo_in(prGlueInfo->rBowInfo.prKfifo, (PUINT_8)prEvent, u4EventSize); */ -+ kfifo_in(&(prGlueInfo->rBowInfo.rKfifo), (PUINT_8) prEvent, u4EventSize); -+ wake_up_interruptible(&(prGlueInfo->rBowInfo.outq)); -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief to retrieve Bluetooth-over-Wi-Fi state from glue layer -+* -+* \param[in] -+* prGlueInfo -+* rPeerAddr -+* \return -+* ENUM_BOW_DEVICE_STATE -+*/ -+/*----------------------------------------------------------------------------*/ -+ENUM_BOW_DEVICE_STATE kalGetBowState(IN P_GLUE_INFO_T prGlueInfo, IN UINT_8 aucPeerAddress[6]) -+{ -+ UINT_8 i; -+ -+ ASSERT(prGlueInfo); -+ -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "kalGetBowState.\n"); -+#endif -+ -+ for (i = 0; i < CFG_BOW_PHYSICAL_LINK_NUM; i++) { -+ if (EQUAL_MAC_ADDR(prGlueInfo->rBowInfo.arPeerAddr, aucPeerAddress) == 0) { -+ -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "kalGetBowState, aucPeerAddress %x, %x:%x:%x:%x:%x:%x.\n", i, -+ aucPeerAddress[0], -+ aucPeerAddress[1], -+ aucPeerAddress[2], -+ aucPeerAddress[3], aucPeerAddress[4], aucPeerAddress[5])); -+ -+ DBGLOG(BOW, EVENT, -+ "kalGetBowState, prGlueInfo->rBowInfo.aeState %x, %x.\n", i, -+ prGlueInfo->rBowInfo.aeState[i]); -+ -+#endif -+ -+ return prGlueInfo->rBowInfo.aeState[i]; -+ } -+ } -+ -+ return BOW_DEVICE_STATE_DISCONNECTED; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief to set Bluetooth-over-Wi-Fi state in glue layer -+* -+* \param[in] -+* prGlueInfo -+* eBowState -+* rPeerAddr -+* \return -+* none -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN kalSetBowState(IN P_GLUE_INFO_T prGlueInfo, IN ENUM_BOW_DEVICE_STATE eBowState, IN UINT_8 aucPeerAddress[6]) -+{ -+ UINT_8 i; -+ -+ ASSERT(prGlueInfo); -+ -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "kalSetBowState.\n"); -+ -+ DBGLOG(BOW, EVENT, "kalSetBowState, prGlueInfo->rBowInfo.arPeerAddr, %x:%x:%x:%x:%x:%x.\n", -+ prGlueInfo->rBowInfo.arPeerAddr[0], -+ prGlueInfo->rBowInfo.arPeerAddr[1], -+ prGlueInfo->rBowInfo.arPeerAddr[2], -+ prGlueInfo->rBowInfo.arPeerAddr[3], -+ prGlueInfo->rBowInfo.arPeerAddr[4], prGlueInfo->rBowInfo.arPeerAddr[5])); -+ -+ DBGLOG(BOW, EVENT, "kalSetBowState, aucPeerAddress, %x:%x:%x:%x:%x:%x.\n", -+ aucPeerAddress[0], -+ aucPeerAddress[1], -+ aucPeerAddress[2], aucPeerAddress[3], aucPeerAddress[4], aucPeerAddress[5]); -+#endif -+ -+ for (i = 0; i < CFG_BOW_PHYSICAL_LINK_NUM; i++) { -+ if (EQUAL_MAC_ADDR(prGlueInfo->rBowInfo.arPeerAddr, aucPeerAddress) == 0) { -+ prGlueInfo->rBowInfo.aeState[i] = eBowState; -+ -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "kalSetBowState, aucPeerAddress %x, %x:%x:%x:%x:%x:%x.\n", i, -+ aucPeerAddress[0], -+ aucPeerAddress[1], -+ aucPeerAddress[2], -+ aucPeerAddress[3], aucPeerAddress[4], aucPeerAddress[5])); -+ -+ DBGLOG(BOW, EVENT, -+ "kalSetBowState, prGlueInfo->rBowInfo.aeState %x, %x.\n", i, -+ prGlueInfo->rBowInfo.aeState[i]); -+#endif -+ -+ return TRUE; -+ } -+ } -+ -+ return FALSE; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief to retrieve Bluetooth-over-Wi-Fi global state -+* -+* \param[in] -+* prGlueInfo -+* -+* \return -+* BOW_DEVICE_STATE_DISCONNECTED -+* in case there is no BoW connection or -+* BoW connection under initialization -+* -+* BOW_DEVICE_STATE_STARTING -+* in case there is no BoW connection but -+* some BoW connection under initialization -+* -+* BOW_DEVICE_STATE_CONNECTED -+* in case there is any BoW connection available -+*/ -+/*----------------------------------------------------------------------------*/ -+ENUM_BOW_DEVICE_STATE kalGetBowGlobalState(IN P_GLUE_INFO_T prGlueInfo) -+{ -+ UINT_32 i; -+ -+ ASSERT(prGlueInfo); -+ -+/* Henry, can reduce this logic to indentify state change */ -+ -+ for (i = 0; i < CFG_BOW_PHYSICAL_LINK_NUM; i++) { -+ if (prGlueInfo->rBowInfo.aeState[i] == BOW_DEVICE_STATE_CONNECTED) -+ return BOW_DEVICE_STATE_CONNECTED; -+ } -+ -+ for (i = 0; i < CFG_BOW_PHYSICAL_LINK_NUM; i++) { -+ if (prGlueInfo->rBowInfo.aeState[i] == BOW_DEVICE_STATE_STARTING) -+ return BOW_DEVICE_STATE_STARTING; -+ } -+ -+ return BOW_DEVICE_STATE_DISCONNECTED; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief to retrieve Bluetooth-over-Wi-Fi operating frequency -+* -+* \param[in] -+* prGlueInfo -+* -+* \return -+* in unit of KHz -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT_32 kalGetBowFreqInKHz(IN P_GLUE_INFO_T prGlueInfo) -+{ -+ ASSERT(prGlueInfo); -+ -+ return prGlueInfo->rBowInfo.u4FreqInKHz; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief to retrieve Bluetooth-over-Wi-Fi role -+* -+* \param[in] -+* prGlueInfo -+* -+* \return -+* 0: Responder -+* 1: Initiator -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT_8 kalGetBowRole(IN P_GLUE_INFO_T prGlueInfo, IN PARAM_MAC_ADDRESS rPeerAddr) -+{ -+ UINT_32 i; -+ -+ ASSERT(prGlueInfo); -+ -+ for (i = 0; i < CFG_BOW_PHYSICAL_LINK_NUM; i++) { -+ if (EQUAL_MAC_ADDR(prGlueInfo->rBowInfo.arPeerAddr[i], rPeerAddr) == 0) -+ return prGlueInfo->rBowInfo.aucRole[i]; -+ } -+ -+ return 0; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief to set Bluetooth-over-Wi-Fi role -+* -+* \param[in] -+* prGlueInfo -+* ucRole -+* 0: Responder -+* 1: Initiator -+* \return -+* none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID kalSetBowRole(IN P_GLUE_INFO_T prGlueInfo, IN UINT_8 ucRole, IN PARAM_MAC_ADDRESS rPeerAddr) -+{ -+ UINT_32 i; -+ -+ ASSERT(prGlueInfo); -+ ASSERT(ucRole <= 1); -+ -+ for (i = 0; i < CFG_BOW_PHYSICAL_LINK_NUM; i++) { -+ if (EQUAL_MAC_ADDR(prGlueInfo->rBowInfo.arPeerAddr[i], rPeerAddr) == 0) -+ prGlueInfo->rBowInfo.aucRole[i] = ucRole; /* Henry, 0 : Responder, 1 : Initiator */ -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief to get available Bluetooth-over-Wi-Fi physical link number -+* -+* \param[in] -+* prGlueInfo -+* \return -+* UINT_32 -+* how many physical links are aviailable -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT_8 kalGetBowAvailablePhysicalLinkCount(IN P_GLUE_INFO_T prGlueInfo) -+{ -+ UINT_8 i; -+ UINT_8 ucLinkCount = 0; -+ -+ ASSERT(prGlueInfo); -+ -+ for (i = 0; i < CFG_BOW_PHYSICAL_LINK_NUM; i++) { -+ if (prGlueInfo->rBowInfo.aeState[i] == BOW_DEVICE_STATE_DISCONNECTED) -+ ucLinkCount++; -+ } -+ -+#if 0 /* CFG_BOW_TEST */ -+ DBGLOG(BOW, EVENT, "kalGetBowAvailablePhysicalLinkCount, ucLinkCount, %c.\n", ucLinkCount); -+#endif -+ -+ return ucLinkCount; -+} -+ -+#if CFG_BOW_SEPARATE_DATA_PATH -+ -+/* Net Device Hooks */ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * \brief A function for net_device open (ifup) -+ * -+ * \param[in] prDev Pointer to struct net_device. -+ * -+ * \retval 0 The execution succeeds. -+ * \retval < 0 The execution failed. -+ */ -+/*----------------------------------------------------------------------------*/ -+static int bowOpen(IN struct net_device *prDev) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ P_ADAPTER_T prAdapter = NULL; -+ -+ ASSERT(prDev); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ ASSERT(prGlueInfo); -+ -+ prAdapter = prGlueInfo->prAdapter; -+ ASSERT(prAdapter); -+ -+ /* 2. carrier on & start TX queue */ -+ netif_carrier_on(prDev); -+ netif_tx_start_all_queues(prDev); -+ -+ return 0; /* success */ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * \brief A function for net_device stop (ifdown) -+ * -+ * \param[in] prDev Pointer to struct net_device. -+ * -+ * \retval 0 The execution succeeds. -+ * \retval < 0 The execution failed. -+ */ -+/*----------------------------------------------------------------------------*/ -+static int bowStop(IN struct net_device *prDev) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ P_ADAPTER_T prAdapter = NULL; -+ -+ ASSERT(prDev); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ ASSERT(prGlueInfo); -+ -+ prAdapter = prGlueInfo->prAdapter; -+ ASSERT(prAdapter); -+ -+ /* 1. stop TX queue */ -+ netif_tx_stop_all_queues(prDev); -+ -+ /* 2. turn of carrier */ -+ if (netif_carrier_ok(prDev)) -+ netif_carrier_off(prDev); -+ -+ return 0; -+}; -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * \brief This function is TX entry point of NET DEVICE. -+ * -+ * \param[in] prSkb Pointer of the sk_buff to be sent -+ * \param[in] prDev Pointer to struct net_device -+ * -+ * \retval NETDEV_TX_OK - on success. -+ * \retval NETDEV_TX_BUSY - on failure, packet will be discarded by upper layer. -+ */ -+/*----------------------------------------------------------------------------*/ -+static int bowHardStartXmit(IN struct sk_buff *prSkb, IN struct net_device *prDev) -+{ -+ P_GLUE_INFO_T prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ -+ P_QUE_ENTRY_T prQueueEntry = NULL; -+ P_QUE_T prTxQueue = NULL; -+ UINT_16 u2QueueIdx = 0; -+ UINT_8 ucDSAP, ucSSAP, ucControl; -+ UINT_8 aucOUI[3]; -+ PUINT_8 aucLookAheadBuf = NULL; -+ -+#if CFG_BOW_TEST -+ UINT_32 i; -+#endif -+ -+ GLUE_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(prSkb); -+ ASSERT(prDev); -+ ASSERT(prGlueInfo); -+ -+ aucLookAheadBuf = prSkb->data; -+ -+ ucDSAP = *(PUINT_8) &aucLookAheadBuf[ETH_LLC_OFFSET]; -+ ucSSAP = *(PUINT_8) &aucLookAheadBuf[ETH_LLC_OFFSET + 1]; -+ ucControl = *(PUINT_8) &aucLookAheadBuf[ETH_LLC_OFFSET + 2]; -+ aucOUI[0] = *(PUINT_8) &aucLookAheadBuf[ETH_SNAP_OFFSET]; -+ aucOUI[1] = *(PUINT_8) &aucLookAheadBuf[ETH_SNAP_OFFSET + 1]; -+ aucOUI[2] = *(PUINT_8) &aucLookAheadBuf[ETH_SNAP_OFFSET + 2]; -+ prGlueInfo->u8SkbToDriver++; -+ -+ if (!(ucDSAP == ETH_LLC_DSAP_SNAP && -+ ucSSAP == ETH_LLC_SSAP_SNAP && -+ ucControl == ETH_LLC_CONTROL_UNNUMBERED_INFORMATION && -+ aucOUI[0] == ETH_SNAP_BT_SIG_OUI_0 && -+ aucOUI[1] == ETH_SNAP_BT_SIG_OUI_1 && aucOUI[2] == ETH_SNAP_BT_SIG_OUI_2) || (prSkb->len > 1514)) { -+ -+#if CFG_BOW_TEST -+ DBGLOG(BOW, TRACE, "Invalid BOW packet, skip tx\n"); -+#endif -+ -+ dev_kfree_skb(prSkb); -+ prGlueInfo->u8SkbFreed++; -+ return NETDEV_TX_OK; -+ } -+ -+ if (prGlueInfo->ulFlag & GLUE_FLAG_HALT) { -+ DBGLOG(BOW, TRACE, "GLUE_FLAG_HALT skip tx\n"); -+ dev_kfree_skb(prSkb); -+ prGlueInfo->u8SkbFreed++; -+ return NETDEV_TX_OK; -+ } -+ -+ prQueueEntry = (P_QUE_ENTRY_T) GLUE_GET_PKT_QUEUE_ENTRY(prSkb); -+ prTxQueue = &prGlueInfo->rTxQueue; -+ -+#if CFG_BOW_TEST -+ DBGLOG(BOW, TRACE, "Tx sk_buff->len: %d\n", prSkb->len); -+ DBGLOG(BOW, TRACE, "Tx sk_buff->data_len: %d\n", prSkb->data_len); -+ DBGLOG(BOW, TRACE, "Tx sk_buff->data:\n"); -+ -+ for (i = 0; i < prSkb->len; i++) { -+ DBGLOG(BOW, TRACE, "%4x", prSkb->data[i]); -+ -+ if ((i + 1) % 16 == 0) -+ DBGLOG(BOW, TRACE, "\n"); -+ } -+ -+ DBGLOG(BOW, TRACE, "\n"; -+#endif -+#if CFG_BOW_TEST -+/* g_u4CurrentSysTime = (OS_SYSTIME)kalGetTimeTick(; */ -+ g_u4CurrentSysTime = (OS_SYSTIME) jiffies_to_usecs(jiffies); -+ i = g_u4CurrentSysTime - g_u4PrevSysTime; -+ if ((i >> 10) > 0) -+ i = 10; -+ else -+ i = i >> 7; -+ g_arBowRevPalPacketTime[i]++; -+ g_u4PrevSysTime = g_u4CurrentSysTime; -+#endif -+ if (wlanProcessSecurityFrame(prGlueInfo->prAdapter, (P_NATIVE_PACKET) prSkb) == FALSE) { -+ GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_TX_QUE); -+ QUEUE_INSERT_TAIL(prTxQueue, prQueueEntry); -+ GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_TX_QUE); -+ GLUE_INC_REF_CNT(prGlueInfo->i4TxPendingFrameNum); -+ GLUE_INC_REF_CNT(prGlueInfo->ai4TxPendingFrameNumPerQueue[NETWORK_TYPE_BOW_INDEX][u2QueueIdx]); -+ if (prGlueInfo->ai4TxPendingFrameNumPerQueue[NETWORK_TYPE_BOW_INDEX][u2QueueIdx] >= -+ CFG_TX_STOP_NETIF_PER_QUEUE_THRESHOLD) -+ DBGLOG(TX, INFO, "netif_stop_subqueue for BOW, Queue len: %d\n", -+ prGlueInfo->ai4TxPendingFrameNumPerQueue[NETWORK_TYPE_BOW_INDEX][u2QueueIdx]); -+ -+ netif_stop_subqueue(prDev, u2QueueIdx); -+ } else { -+ GLUE_INC_REF_CNT(prGlueInfo->i4TxPendingSecurityFrameNum); -+ } -+ -+ kalSetEvent(prGlueInfo); -+ /* For Linux, we'll always return OK FLAG, because we'll free this skb by ourself */ -+ return NETDEV_TX_OK; -+} -+ -+/* callbacks for netdevice */ -+static const struct net_device_ops bow_netdev_ops = { -+ .ndo_open = bowOpen, .ndo_stop = bowStop, .ndo_start_xmit = bowHardStartXmit,}; -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief initialize net device for Bluetooth-over-Wi-Fi -+* -+* \param[in] -+* prGlueInfo -+* prDevName -+* -+* \return -+* TRUE -+* FALSE -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN kalInitBowDevice(IN P_GLUE_INFO_T prGlueInfo, IN const char *prDevName) -+{ -+ P_ADAPTER_T prAdapter; -+ P_GL_HIF_INFO_T prHif; -+ PARAM_MAC_ADDRESS rMacAddr; -+ -+ ASSERT(prGlueInfo); -+ ASSERT(prGlueInfo->rBowInfo.fgIsRegistered == TRUE); -+ prAdapter = prGlueInfo->prAdapter; -+ ASSERT(prAdapter); -+ prHif = &prGlueInfo->rHifInfo; -+ ASSERT(prHif); -+ if (prGlueInfo->rBowInfo.fgIsNetRegistered == FALSE) { -+ prGlueInfo->rBowInfo.prDevHandler = -+ alloc_netdev_mq(sizeof(P_GLUE_INFO_T), prDevName, NET_NAME_PREDICTABLE, ether_setup, CFG_MAX_TXQ_NUM); -+ if (!prGlueInfo->rBowInfo.prDevHandler) -+ return FALSE; -+ -+ /* 1. setup netdev */ -+ /* 1.1 Point to shared glue structure */ -+ *((P_GLUE_INFO_T *) netdev_priv(prGlueInfo->rBowInfo.prDevHandler)) = prGlueInfo; -+ /* 1.2 fill hardware address */ -+ COPY_MAC_ADDR(rMacAddr, prAdapter->rMyMacAddr); -+ rMacAddr[0] |= 0x2; -+ /* change to local administrated address */ -+ ether_addr_copy(prGlueInfo->rBowInfo.prDevHandler->dev_addr, rMacAddr); -+ ether_addr_copy(prGlueInfo->rBowInfo.prDevHandler->perm_addr, -+ prGlueInfo->rBowInfo.prDevHandler->dev_addr); -+ /* 1.3 register callback functions */ -+ prGlueInfo->rBowInfo.prDevHandler->netdev_ops = &bow_netdev_ops; -+#if (MTK_WCN_HIF_SDIO == 0) -+ SET_NETDEV_DEV(prGlueInfo->rBowInfo.prDevHandler, prHif->Dev); -+#endif -+ register_netdev(prGlueInfo->rBowInfo.prDevHandler); -+ /* 2. net device initialize */ -+ netif_carrier_off(prGlueInfo->rBowInfo.prDevHandler); -+ netif_tx_stop_all_queues(prGlueInfo->rBowInfo.prDevHandler); -+ /* 3. finish */ -+ prGlueInfo->rBowInfo.fgIsNetRegistered = TRUE; -+ } -+ -+ return TRUE; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief uninitialize net device for Bluetooth-over-Wi-Fi -+* -+* \param[in] -+* prGlueInfo -+* -+* \return -+* TRUE -+* FALSE -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN kalUninitBowDevice(IN P_GLUE_INFO_T prGlueInfo) -+{ -+ ASSERT(prGlueInfo); -+ /* ASSERT(prGlueInfo->rBowInfo.fgIsRegistered == TRUE); */ -+ if (prGlueInfo->rBowInfo.fgIsNetRegistered == TRUE) { -+ prGlueInfo->rBowInfo.fgIsNetRegistered = FALSE; -+ if (netif_carrier_ok(prGlueInfo->rBowInfo.prDevHandler)) -+ netif_carrier_off(prGlueInfo->rBowInfo.prDevHandler); -+ -+ netif_tx_stop_all_queues(prGlueInfo->rBowInfo.prDevHandler); -+ /* netdevice unregistration & free */ -+ unregister_netdev(prGlueInfo->rBowInfo.prDevHandler); -+ free_netdev(prGlueInfo->rBowInfo.prDevHandler); -+ prGlueInfo->rBowInfo.prDevHandler = NULL; -+ return TRUE; -+ } else { -+ return FALSE; -+ } -+} -+#endif /* CFG_BOW_SEPARATE_DATA_PATH */ -+#endif /* CFG_ENABLE_BT_OVER_WIFI */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_cfg80211.c b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_cfg80211.c -new file mode 100644 -index 000000000000..1fed65ebc60e ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_cfg80211.c -@@ -0,0 +1,3110 @@ -+/* -+** Id: @(#) gl_cfg80211.c@@ -+*/ -+ -+/*! \file gl_cfg80211.c -+ \brief Main routines for supporintg MT6620 cfg80211 control interface -+ -+ This file contains the support routines of Linux driver for MediaTek Inc. 802.11 -+ Wireless LAN Adapters. -+*/ -+ -+/* -+** Log: gl_cfg80211.c -+** -+** 09 05 2013 cp.wu -+** correct length to pass to wlanoidSetBssid() -+** -+** 09 04 2013 cp.wu -+** fix typo -+** -+** 09 03 2013 cp.wu -+** add path for reassociation -+** -+** 11 23 2012 yuche.tsai -+** [ALPS00398671] [Acer-Tablet] Remove Wi-Fi Direct completely -+** Fix bug of WiFi may reboot under user load, when WiFi Direct is removed.. -+** -+** 09 12 2012 wcpadmin -+** [ALPS00276400] Remove MTK copyright and legal header on GPL/LGPL related packages -+** . -+** -+** 08 30 2012 chinglan.wang -+** [ALPS00349664] [6577JB][WIFI] Phone can not connect to AP secured with AES via WPS in 802.11n Only -+** . -+ * -+** -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "gl_os.h" -+#include "debug.h" -+#include "wlan_lib.h" -+#include "gl_wext.h" -+#include "precomp.h" -+#include -+#include -+#include -+#include "gl_cfg80211.h" -+#include "gl_vendor.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/* workaround for some ANR CRs. if suppliant is blocked longer than 10s, wifi hal will tell wifiMonitor -+to teminate. for the case which can block supplicant 10s is to del key more than 5 times. the root cause -+is that there is no resource in TC4, so del key command was not able to set, and then oid -+timeout was happed. if we found the root cause why fw couldn't release TC resouce, we will remove this -+workaround */ -+static UINT_8 gucKeyIndex = 255; -+ -+P_SW_RFB_T g_arGscnResultsTempBuffer[MAX_BUFFERED_GSCN_RESULTS]; -+UINT_8 g_GscanResultsTempBufferIndex = 0; -+UINT_8 g_arGscanResultsIndicateNumber[MAX_BUFFERED_GSCN_RESULTS] = { 0, 0, 0, 0, 0 }; -+ -+UINT_8 g_GetResultsBufferedCnt = 0; -+UINT_8 g_GetResultsCmdCnt = 0; -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * @brief This routine is responsible for change STA type between -+ * 1. Infrastructure Client (Non-AP STA) -+ * 2. Ad-Hoc IBSS -+ * -+ * @param -+ * -+ * @retval 0: successful -+ * others: failure -+ */ -+/*----------------------------------------------------------------------------*/ -+int -+mtk_cfg80211_change_iface(struct wiphy *wiphy, -+ struct net_device *ndev, enum nl80211_iftype type, /*u32 *flags,*/ struct vif_params *params) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ ENUM_PARAM_OP_MODE_T eOpMode; -+ UINT_32 u4BufLen; -+ -+ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); -+ ASSERT(prGlueInfo); -+ -+ if (type == NL80211_IFTYPE_STATION) -+ eOpMode = NET_TYPE_INFRA; -+ else if (type == NL80211_IFTYPE_ADHOC) -+ eOpMode = NET_TYPE_IBSS; -+ else -+ return -EINVAL; -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetInfrastructureMode, -+ &eOpMode, sizeof(eOpMode), FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) -+ DBGLOG(REQ, WARN, "set infrastructure mode error:%x\n", rStatus); -+ -+ /* reset wpa info */ -+ prGlueInfo->rWpaInfo.u4WpaVersion = IW_AUTH_WPA_VERSION_DISABLED; -+ prGlueInfo->rWpaInfo.u4KeyMgmt = 0; -+ prGlueInfo->rWpaInfo.u4CipherGroup = IW_AUTH_CIPHER_NONE; -+ prGlueInfo->rWpaInfo.u4CipherPairwise = IW_AUTH_CIPHER_NONE; -+ prGlueInfo->rWpaInfo.u4AuthAlg = IW_AUTH_ALG_OPEN_SYSTEM; -+#if CFG_SUPPORT_802_11W -+ prGlueInfo->rWpaInfo.u4Mfp = IW_AUTH_MFP_DISABLED; -+#endif -+ -+ return 0; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * @brief This routine is responsible for adding key -+ * -+ * @param -+ * -+ * @retval 0: successful -+ * others: failure -+ */ -+/*----------------------------------------------------------------------------*/ -+int -+mtk_cfg80211_add_key(struct wiphy *wiphy, -+ struct net_device *ndev, -+ u8 key_index, bool pairwise, const u8 *mac_addr, struct key_params *params) -+{ -+ PARAM_KEY_T rKey; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ INT_32 i4Rslt = -EINVAL; -+ UINT_32 u4BufLen = 0; -+ UINT_8 tmp1[8]; -+ UINT_8 tmp2[8]; -+ -+ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); -+ ASSERT(prGlueInfo); -+ -+ kalMemZero(&rKey, sizeof(PARAM_KEY_T)); -+ -+ rKey.u4KeyIndex = key_index; -+ -+ if (mac_addr) { -+ COPY_MAC_ADDR(rKey.arBSSID, mac_addr); -+ if ((rKey.arBSSID[0] == 0x00) && (rKey.arBSSID[1] == 0x00) && (rKey.arBSSID[2] == 0x00) && -+ (rKey.arBSSID[3] == 0x00) && (rKey.arBSSID[4] == 0x00) && (rKey.arBSSID[5] == 0x00)) { -+ rKey.arBSSID[0] = 0xff; -+ rKey.arBSSID[1] = 0xff; -+ rKey.arBSSID[2] = 0xff; -+ rKey.arBSSID[3] = 0xff; -+ rKey.arBSSID[4] = 0xff; -+ rKey.arBSSID[5] = 0xff; -+ } -+ if (rKey.arBSSID[0] != 0xFF) { -+ rKey.u4KeyIndex |= BIT(31); -+ if ((rKey.arBSSID[0] != 0x00) || (rKey.arBSSID[1] != 0x00) || (rKey.arBSSID[2] != 0x00) || -+ (rKey.arBSSID[3] != 0x00) || (rKey.arBSSID[4] != 0x00) || (rKey.arBSSID[5] != 0x00)) -+ rKey.u4KeyIndex |= BIT(30); -+ } -+ } else { -+ rKey.arBSSID[0] = 0xff; -+ rKey.arBSSID[1] = 0xff; -+ rKey.arBSSID[2] = 0xff; -+ rKey.arBSSID[3] = 0xff; -+ rKey.arBSSID[4] = 0xff; -+ rKey.arBSSID[5] = 0xff; -+ /* rKey.u4KeyIndex |= BIT(31);//Enable BIT 31 will make tx use bc key id,should use pairwise key id 0 */ -+ } -+ -+ if (params->key) { -+ /* rKey.aucKeyMaterial[0] = kalMemAlloc(params->key_len, VIR_MEM_TYPE); */ -+ kalMemCopy(rKey.aucKeyMaterial, params->key, params->key_len); -+ if (params->key_len == 32) { -+ kalMemCopy(tmp1, ¶ms->key[16], 8); -+ kalMemCopy(tmp2, ¶ms->key[24], 8); -+ kalMemCopy(&rKey.aucKeyMaterial[16], tmp2, 8); -+ kalMemCopy(&rKey.aucKeyMaterial[24], tmp1, 8); -+ } -+ } -+ -+ rKey.u4KeyLength = params->key_len; -+ rKey.u4Length = ((ULONG)&(((P_P2P_PARAM_KEY_T) 0)->aucKeyMaterial)) + rKey.u4KeyLength; -+ -+ rStatus = kalIoctl(prGlueInfo, wlanoidSetAddKey, &rKey, rKey.u4Length, FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ -+ if (rStatus == WLAN_STATUS_SUCCESS) -+ i4Rslt = 0; -+ -+ return i4Rslt; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * @brief This routine is responsible for getting key for specified STA -+ * -+ * @param -+ * -+ * @retval 0: successful -+ * others: failure -+ */ -+/*----------------------------------------------------------------------------*/ -+int -+mtk_cfg80211_get_key(struct wiphy *wiphy, -+ struct net_device *ndev, -+ u8 key_index, -+ bool pairwise, -+ const u8 *mac_addr, void *cookie, void (*callback) (void *cookie, struct key_params *)) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ -+ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); -+ ASSERT(prGlueInfo); -+ -+ DBGLOG(REQ, TRACE, "--> %s()\n", __func__); -+ -+ /* not implemented */ -+ -+ return -EINVAL; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * @brief This routine is responsible for removing key for specified STA -+ * -+ * @param -+ * -+ * @retval 0: successful -+ * others: failure -+ */ -+/*----------------------------------------------------------------------------*/ -+int mtk_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev, u8 key_index, bool pairwise, const u8 *mac_addr) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ PARAM_REMOVE_KEY_T rRemoveKey; -+ UINT_32 u4BufLen = 0; -+ INT_32 i4Rslt = -EINVAL; -+ -+ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); -+ ASSERT(prGlueInfo); -+ -+ kalMemZero(&rRemoveKey, sizeof(PARAM_REMOVE_KEY_T)); -+ if (mac_addr) -+ COPY_MAC_ADDR(rRemoveKey.arBSSID, mac_addr); -+ else if (key_index <= gucKeyIndex) { /* new operation, reset gucKeyIndex */ -+ gucKeyIndex = 255; -+ } else { /* bypass the next remove key operation */ -+ gucKeyIndex = key_index; -+ return -EBUSY; -+ } -+ rRemoveKey.u4KeyIndex = key_index; -+ rRemoveKey.u4Length = sizeof(PARAM_REMOVE_KEY_T); -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetRemoveKey, &rRemoveKey, rRemoveKey.u4Length, FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ DBGLOG(REQ, WARN, "remove key error:%x\n", rStatus); -+ if (WLAN_STATUS_FAILURE == rStatus && mac_addr) { -+ i4Rslt = -EBUSY; -+ gucKeyIndex = key_index; -+ } -+ } else { -+ gucKeyIndex = 255; -+ i4Rslt = 0; -+ } -+ -+ return i4Rslt; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * @brief This routine is responsible for setting default key on an interface -+ * -+ * @param -+ * -+ * @retval 0: successful -+ * others: failure -+ */ -+/*----------------------------------------------------------------------------*/ -+int -+mtk_cfg80211_set_default_key(struct wiphy *wiphy, struct net_device *ndev, u8 key_index, bool unicast, bool multicast) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ -+ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); -+ ASSERT(prGlueInfo); -+ -+ DBGLOG(REQ, TRACE, "--> %s()\n", __func__); -+ -+ /* not implemented */ -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * @brief This routine is responsible for setting set_default_mgmt_ke on an interface -+ * -+ * @param -+ * -+ * @retval 0: successful -+ * others: failure -+ */ -+/*----------------------------------------------------------------------------*/ -+int mtk_cfg80211_set_default_mgmt_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index) -+{ -+ return 0; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * @brief This routine is responsible for getting station information such as RSSI -+ * -+ * @param -+ * -+ * @retval 0: successful -+ * others: failure -+ */ -+/*----------------------------------------------------------------------------*/ -+int mtk_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev, const u8 *mac, struct station_info *sinfo) -+{ -+#define LINKSPEED_MAX_RANGE_11BGN 3000 -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ WLAN_STATUS rStatus; -+ PARAM_MAC_ADDRESS arBssid; -+ UINT_32 u4BufLen; -+ UINT_32 u4Rate = 0; -+ UINT_32 u8diffTxBad, u8diffRetry; -+ INT_32 i4Rssi = 0; -+ PARAM_802_11_STATISTICS_STRUCT_T rStatistics; -+ -+ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); -+ ASSERT(prGlueInfo); -+ -+ kalMemZero(arBssid, MAC_ADDR_LEN); -+ wlanQueryInformation(prGlueInfo->prAdapter, wlanoidQueryBssid, &arBssid[0], sizeof(arBssid), &u4BufLen); -+ -+ /* 1. check BSSID */ -+ if (UNEQUAL_MAC_ADDR(arBssid, mac)) { -+ /* wrong MAC address */ -+ DBGLOG(REQ, WARN, "incorrect BSSID: [ %pM ] currently connected BSSID[ %pM ]\n", -+ mac, arBssid); -+ return -ENOENT; -+ } -+ -+ /* 2. fill TX rate */ -+ if (prGlueInfo->eParamMediaStateIndicated != PARAM_MEDIA_STATE_CONNECTED) { -+ /* not connected */ -+ DBGLOG(REQ, WARN, "not yet connected\n"); -+ } else { -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidQueryLinkSpeed, &u4Rate, sizeof(u4Rate), TRUE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ sinfo->filled |= BIT(NL80211_STA_INFO_TX_BITRATE); -+ -+ if ((rStatus != WLAN_STATUS_SUCCESS) || (u4Rate == 0)) { -+ /* DBGLOG(REQ, WARN, "unable to retrieve link speed\n")); */ -+ DBGLOG(REQ, WARN, "last link speed\n"); -+ sinfo->txrate.legacy = prGlueInfo->u4LinkSpeedCache; -+ } else { -+ /* sinfo->filled |= STATION_INFO_TX_BITRATE; */ -+ sinfo->txrate.legacy = u4Rate / 1000; /* convert from 100bps to 100kbps */ -+ prGlueInfo->u4LinkSpeedCache = u4Rate / 1000; -+ } -+ } -+ -+ /* 3. fill RSSI */ -+ if (prGlueInfo->eParamMediaStateIndicated != PARAM_MEDIA_STATE_CONNECTED) { -+ /* not connected */ -+ DBGLOG(REQ, WARN, "not yet connected\n"); -+ } else { -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidQueryRssi, &i4Rssi, sizeof(i4Rssi), TRUE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS || (i4Rssi == PARAM_WHQL_RSSI_MIN_DBM) -+ || (i4Rssi == PARAM_WHQL_RSSI_MAX_DBM)) { -+ /* DBGLOG(REQ, WARN, "unable to retrieve link speed\n"); */ -+ DBGLOG(REQ, WARN, "last rssi\n"); -+ sinfo->signal = prGlueInfo->i4RssiCache; -+ } else { -+ /* in the cfg80211 layer, the signal is a signed char variable. */ -+ sinfo->signal = i4Rssi; /* dBm */ -+ prGlueInfo->i4RssiCache = i4Rssi; -+ } -+ sinfo->rx_packets = prGlueInfo->rNetDevStats.rx_packets; -+ -+ /* 4. Fill Tx OK and Tx Bad */ -+ -+ sinfo->filled |= BIT(NL80211_STA_INFO_TX_PACKETS); -+ sinfo->filled |= BIT(NL80211_STA_INFO_TX_FAILED); -+ { -+ WLAN_STATUS rStatus; -+ -+ kalMemZero(&rStatistics, sizeof(rStatistics)); -+ /* Get Tx OK/Fail cnt from AIS statistic counter */ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidQueryStatisticsPL, -+ &rStatistics, sizeof(rStatistics), TRUE, TRUE, TRUE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ DBGLOG(REQ, WARN, "unable to retrieive statistic\n"); -+ } else { -+ INT_32 i4RssiThreshold = -85; /* set rssi threshold -85dBm */ -+ UINT_32 u4LinkspeedThreshold = 55; /* set link speed threshold 5.5Mbps */ -+ BOOLEAN fgWeighted = 0; -+ -+ /* calculate difference */ -+ u8diffTxBad = rStatistics.rFailedCount.QuadPart - prGlueInfo->u8Statistic[0]; -+ u8diffRetry = rStatistics.rRetryCount.QuadPart - prGlueInfo->u8Statistic[1]; -+ /* restore counters */ -+ prGlueInfo->u8Statistic[0] = rStatistics.rFailedCount.QuadPart; -+ prGlueInfo->u8Statistic[1] = rStatistics.rRetryCount.QuadPart; -+ -+ /* check threshold is valid */ -+ if (prGlueInfo->fgPoorlinkValid) { -+ if (prGlueInfo->i4RssiThreshold) -+ i4RssiThreshold = prGlueInfo->i4RssiThreshold; -+ if (prGlueInfo->u4LinkspeedThreshold) -+ u4LinkspeedThreshold = prGlueInfo->u4LinkspeedThreshold; -+ } -+ /* add weighted to fail counter */ -+ if (sinfo->txrate.legacy < u4LinkspeedThreshold || sinfo->signal < i4RssiThreshold) { -+ prGlueInfo->u8TotalFailCnt += (u8diffTxBad * 16 + u8diffRetry); -+ fgWeighted = 1; -+ } else { -+ prGlueInfo->u8TotalFailCnt += u8diffTxBad; -+ } -+ /* report counters */ -+ prGlueInfo->rNetDevStats.tx_packets = rStatistics.rTransmittedFragmentCount.QuadPart; -+ prGlueInfo->rNetDevStats.tx_errors = prGlueInfo->u8TotalFailCnt; -+ -+ sinfo->tx_packets = prGlueInfo->rNetDevStats.tx_packets; -+ sinfo->tx_failed = prGlueInfo->rNetDevStats.tx_errors; -+ /* Good Fail Bad Difference retry difference Linkspeed Rate Weighted */ -+ DBGLOG(REQ, TRACE, -+ "Poorlink State TxOK(%d) TxFail(%d) Bad(%d) Retry(%d)", -+ sinfo->tx_packets, -+ sinfo->tx_failed, -+ (int)u8diffTxBad, -+ (int)u8diffRetry); -+ DBGLOG(REQ, TRACE, -+ "Rate(%d) Signal(%d) Weight(%d) QuadPart(%d)\n", -+ sinfo->txrate.legacy, -+ sinfo->signal, -+ (int)fgWeighted, -+ (int)rStatistics.rMultipleRetryCount.QuadPart); -+ } -+ } -+ -+ } -+ return 0; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * @brief This routine is responsible for adding a station information -+ * -+ * @param -+ * -+ * @retval 0: successful -+ * others: failure -+ */ -+/*----------------------------------------------------------------------------*/ -+int mtk_cfg80211_change_station(struct wiphy *wiphy, struct net_device *ndev, -+ const u8 *mac, struct station_parameters *params) -+{ -+#if (CFG_SUPPORT_TDLS == 1) -+ /* -+ EX: In supplicant, -+ (Supplicant) wpa_tdls_process_tpk_m3() -> -+ (Supplicant) wpa_tdls_enable_link() -> -+ (Supplicant) wpa_sm_tdls_peer_addset() -> -+ (Supplicant) ..tdls_peer_addset() -> -+ (Supplicant) wpa_supplicant_tdls_peer_addset() -> -+ (Supplicant) wpa_drv_sta_add() -> -+ (Supplicant) ..sta_add() -> -+ (Supplicant) wpa_driver_nl80211_sta_add() -> -+ (NL80211) nl80211_set_station() -> -+ (Driver) mtk_cfg80211_change_station() -+ -+ if nl80211_set_station fails, supplicant will tear down the link. -+ */ -+ P_GLUE_INFO_T prGlueInfo; -+ TDLS_CMD_PEER_UPDATE_T rCmdUpdate; -+ WLAN_STATUS rStatus; -+ UINT_32 u4BufLen, u4Temp; -+ -+ /* sanity check */ -+ if ((wiphy == NULL) || (mac == NULL) || (params == NULL)) -+ return -EINVAL; -+ -+ DBGLOG(TDLS, INFO, "%s: 0x%p 0x%x\n", __func__, params->supported_rates, params->sta_flags_set); -+ -+ if (!(params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER))) -+ return -EOPNOTSUPP; -+ -+ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); -+ if (prGlueInfo == NULL) -+ return -EINVAL; -+ -+ /* TODO: check if we are station mode, not AP mode */ -+ -+ /* init */ -+ kalMemZero(&rCmdUpdate, sizeof(rCmdUpdate)); -+ kalMemCopy(rCmdUpdate.aucPeerMac, mac, 6); -+ -+ if (params->supported_rates != NULL) { -+ u4Temp = params->supported_rates_len; -+ if (u4Temp > TDLS_CMD_PEER_UPDATE_SUP_RATE_MAX) { -+ u4Temp = TDLS_CMD_PEER_UPDATE_SUP_RATE_MAX; -+ DBGLOG(TDLS, ERROR, "%s sup rate too long: %d\n", __func__, params->supported_rates_len); -+ } -+ kalMemCopy(rCmdUpdate.aucSupRate, params->supported_rates, u4Temp); -+ rCmdUpdate.u2SupRateLen = u4Temp; -+ } -+ -+ /* -+ In supplicant, only recognize WLAN_EID_QOS 46, not 0xDD WMM -+ So force to support UAPSD here. -+ */ -+ rCmdUpdate.UapsdBitmap = 0x0F; /*params->uapsd_queues; */ -+ rCmdUpdate.UapsdMaxSp = 0; /*params->max_sp; */ -+ -+ DBGLOG(TDLS, INFO, "%s: UapsdBitmap=0x%x UapsdMaxSp=%d\n", -+ __func__, rCmdUpdate.UapsdBitmap, rCmdUpdate.UapsdMaxSp); -+ -+ rCmdUpdate.u2Capability = params->capability; -+ -+ if (params->ext_capab != NULL) { -+ u4Temp = params->ext_capab_len; -+ if (u4Temp > TDLS_CMD_PEER_UPDATE_EXT_CAP_MAXLEN) { -+ u4Temp = TDLS_CMD_PEER_UPDATE_EXT_CAP_MAXLEN; -+ DBGLOG(TDLS, ERROR, "%s ext_capab too long: %d\n", __func__, params->ext_capab_len); -+ } -+ kalMemCopy(rCmdUpdate.aucExtCap, params->ext_capab, u4Temp); -+ rCmdUpdate.u2ExtCapLen = u4Temp; -+ } -+ -+ if (params->ht_capa != NULL) { -+ DBGLOG(TDLS, INFO, "%s: peer is 11n device\n", __func__); -+ -+ rCmdUpdate.rHtCap.u2CapInfo = params->ht_capa->cap_info; -+ rCmdUpdate.rHtCap.ucAmpduParamsInfo = params->ht_capa->ampdu_params_info; -+ rCmdUpdate.rHtCap.u2ExtHtCapInfo = params->ht_capa->extended_ht_cap_info; -+ rCmdUpdate.rHtCap.u4TxBfCapInfo = params->ht_capa->tx_BF_cap_info; -+ rCmdUpdate.rHtCap.ucAntennaSelInfo = params->ht_capa->antenna_selection_info; -+ kalMemCopy(rCmdUpdate.rHtCap.rMCS.arRxMask, -+ params->ht_capa->mcs.rx_mask, sizeof(rCmdUpdate.rHtCap.rMCS.arRxMask)); -+ rCmdUpdate.rHtCap.rMCS.u2RxHighest = params->ht_capa->mcs.rx_highest; -+ rCmdUpdate.rHtCap.rMCS.ucTxParams = params->ht_capa->mcs.tx_params; -+ rCmdUpdate.fgIsSupHt = TRUE; -+ } -+ -+ /* update a TDLS peer record */ -+ rStatus = kalIoctl(prGlueInfo, -+ TdlsexPeerUpdate, -+ &rCmdUpdate, sizeof(TDLS_CMD_PEER_UPDATE_T), FALSE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ DBGLOG(TDLS, ERROR, "%s update error:%x\n", __func__, rStatus); -+ return -EINVAL; -+ } -+#endif /* CFG_SUPPORT_TDLS */ -+ -+ return 0; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * @brief This routine is responsible for adding a station information -+ * -+ * @param -+ * -+ * @retval 0: successful -+ * others: failure -+ */ -+/*----------------------------------------------------------------------------*/ -+int mtk_cfg80211_add_station(struct wiphy *wiphy, struct net_device *ndev, -+ const u8 *mac, struct station_parameters *params) -+{ -+#if (CFG_SUPPORT_TDLS == 1) -+ /* from supplicant -- wpa_supplicant_tdls_peer_addset() */ -+ P_GLUE_INFO_T prGlueInfo; -+ TDLS_CMD_PEER_ADD_T rCmdCreate; -+ WLAN_STATUS rStatus; -+ UINT_32 u4BufLen; -+ -+ if ((wiphy == NULL) || (mac == NULL) || (params == NULL)) -+ return -EINVAL; -+ -+ /* -+ wpa_sm_tdls_peer_addset(sm, peer->addr, 1, 0, 0, NULL, 0, NULL, NULL, 0, -+ NULL, 0); -+ -+ wpa_sm_tdls_peer_addset(struct wpa_sm *sm, const u8 *addr, int add, -+ u16 aid, u16 capability, const u8 *supp_rates, -+ size_t supp_rates_len, -+ const struct ieee80211_ht_capabilities *ht_capab, -+ const struct ieee80211_vht_capabilities *vht_capab, -+ u8 qosinfo, const u8 *ext_capab, size_t ext_capab_len) -+ -+ Only MAC address of the peer is valid. -+ */ -+ -+ DBGLOG(TDLS, INFO, "%s: 0x%p %d\n", __func__, params->supported_rates, params->supported_rates_len); -+ -+ /* sanity check */ -+ if (!(params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER))) -+ return -EOPNOTSUPP; -+ -+ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); -+ if (prGlueInfo == NULL) -+ return -EINVAL; -+ -+ /* TODO: check if we are station mode, not AP mode */ -+ -+ /* init */ -+ kalMemZero(&rCmdCreate, sizeof(rCmdCreate)); -+ kalMemCopy(rCmdCreate.aucPeerMac, mac, 6); -+ -+#if 0 -+ rCmdCreate.eNetTypeIndex = NETWORK_TYPE_AIS_INDEX; -+ -+ rCmdCreate.u2CapInfo = params->capability; -+ -+ DBGLOG(TDLS, INFO, " %s: capability = 0x%x\n", __func__, rCmdCreate.u2CapInfo); -+ -+ if ((params->supported_rates != NULL) && (params->supported_rates_len != 0)) { -+ UINT32 u4Idx; -+ -+ DBGLOG(TDLS, INFO, " %s: sup rate = 0x", __func__); -+ -+ rIeSup.ucId = ELEM_ID_SUP_RATES; -+ rIeSup.ucLength = params->supported_rates_len; -+ for (u4Idx = 0; u4Idx < rIeSup.ucLength; u4Idx++) { -+ rIeSup.aucSupportedRates[u4Idx] = params->supported_rates[u4Idx]; -+ DBGLOG(TDLS, INFO, "%x ", rIeSup.aucSupportedRates[u4Idx]); -+ } -+ DBGLOG(TDLS, INFO, "\n"); -+ -+ rateGetRateSetFromIEs(&rIeSup, -+ NULL, -+ &rCmdCreate.u2OperationalRateSet, -+ &rCmdCreate.u2BSSBasicRateSet, &rCmdCreate.fgIsUnknownBssBasicRate); -+ } -+ -+ /* phy type */ -+#endif -+ -+ /* create a TDLS peer record */ -+ rStatus = kalIoctl(prGlueInfo, -+ TdlsexPeerAdd, -+ &rCmdCreate, sizeof(TDLS_CMD_PEER_ADD_T), FALSE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ DBGLOG(TDLS, ERROR, "%s create error:%x\n", __func__, rStatus); -+ return -EINVAL; -+ } -+#endif /* CFG_SUPPORT_TDLS */ -+ -+ return 0; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * @brief This routine is responsible for deleting a station information -+ * -+ * @param -+ * -+ * @retval 0: successful -+ * others: failure -+ * -+ * @other -+ * must implement if you have add_station(). -+ */ -+/*----------------------------------------------------------------------------*/ -+int mtk_cfg80211_del_station(struct wiphy *wiphy, struct net_device *ndev, struct station_del_parameters *params) -+//int mtk_cfg80211_del_station(struct wiphy *wiphy, struct net_device *ndev, const u8 *mac) -+{ -+ return 0; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * @brief This routine is responsible for requesting to do a scan -+ * -+ * @param -+ * -+ * @retval 0: successful -+ * others: failure -+ */ -+/*----------------------------------------------------------------------------*/ -+static PARAM_SCAN_REQUEST_EXT_T rScanRequest; -+int mtk_cfg80211_scan(struct wiphy *wiphy, struct cfg80211_scan_request *request) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ WLAN_STATUS rStatus; -+ UINT_32 u4BufLen; -+/* PARAM_SCAN_REQUEST_EXT_T rScanRequest; */ -+ -+ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); -+ ASSERT(prGlueInfo); -+ -+ DBGLOG(REQ, TRACE, "mtk_cfg80211_scan\n"); -+ kalMemZero(&rScanRequest, sizeof(PARAM_SCAN_REQUEST_EXT_T)); -+ -+ /* check if there is any pending scan not yet finished */ -+ if (prGlueInfo->prScanRequest != NULL) { -+ DBGLOG(REQ, ERROR, "prGlueInfo->prScanRequest != NULL\n"); -+ return -EBUSY; -+ } -+ -+ if (request->n_ssids == 0) { -+ rScanRequest.rSsid.u4SsidLen = 0; -+ } else if (request->n_ssids == 1) { -+ COPY_SSID(rScanRequest.rSsid.aucSsid, rScanRequest.rSsid.u4SsidLen, request->ssids[0].ssid, -+ request->ssids[0].ssid_len); -+ } else { -+ DBGLOG(REQ, ERROR, "request->n_ssids:%d\n", request->n_ssids); -+ return -EINVAL; -+ } -+ -+ if (request->ie_len > 0) { -+ rScanRequest.u4IELength = request->ie_len; -+ rScanRequest.pucIE = (PUINT_8) (request->ie); -+ } else { -+ rScanRequest.u4IELength = 0; -+ } -+#if 0 -+ prGlueInfo->prScanRequest = request; -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetBssidListScanExt, -+ &rScanRequest, sizeof(PARAM_SCAN_REQUEST_EXT_T), FALSE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ DBGLOG(REQ, ERROR, "scan error:%x\n", rStatus); -+ prGlueInfo->prScanRequest = NULL; -+ return -EINVAL; -+ } -+ -+ /*prGlueInfo->prScanRequest = request;*/ -+#endif -+ -+ prGlueInfo->prScanRequest = request; -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetBssidListScanExt, -+ &rScanRequest, sizeof(PARAM_SCAN_REQUEST_EXT_T), FALSE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ prGlueInfo->prScanRequest = NULL; -+ DBGLOG(REQ, ERROR, "scan error:%x\n", rStatus); -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ -+static UINT_8 wepBuf[48]; -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * @brief This routine is responsible for requesting to connect to -+ * the ESS with the specified parameters -+ * -+ * @param -+ * -+ * @retval 0: successful -+ * others: failure -+ */ -+/*----------------------------------------------------------------------------*/ -+int mtk_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev, struct cfg80211_connect_params *sme) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ WLAN_STATUS rStatus; -+ UINT_32 u4BufLen; -+ ENUM_PARAM_ENCRYPTION_STATUS_T eEncStatus; -+ ENUM_PARAM_AUTH_MODE_T eAuthMode; -+ UINT_32 cipher; -+ PARAM_CONNECT_T rNewSsid; -+ BOOLEAN fgCarryWPSIE = FALSE; -+ ENUM_PARAM_OP_MODE_T eOpMode; -+ -+ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); -+ ASSERT(prGlueInfo); -+ -+ DBGLOG(REQ, TRACE, "[wlan] mtk_cfg80211_connect %p %zu\n", sme->ie, sme->ie_len); -+ -+ if (prGlueInfo->prAdapter->rWifiVar.rConnSettings.eOPMode > NET_TYPE_AUTO_SWITCH) -+ eOpMode = NET_TYPE_AUTO_SWITCH; -+ else -+ eOpMode = prGlueInfo->prAdapter->rWifiVar.rConnSettings.eOPMode; -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetInfrastructureMode, -+ &eOpMode, sizeof(eOpMode), FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ DBGLOG(REQ, ERROR, "wlanoidSetInfrastructureMode fail 0x%x\n", rStatus); -+ return -EFAULT; -+ } -+ -+ /* after set operation mode, key table are cleared */ -+ -+ /* reset wpa info */ -+ prGlueInfo->rWpaInfo.u4WpaVersion = IW_AUTH_WPA_VERSION_DISABLED; -+ prGlueInfo->rWpaInfo.u4KeyMgmt = 0; -+ prGlueInfo->rWpaInfo.u4CipherGroup = IW_AUTH_CIPHER_NONE; -+ prGlueInfo->rWpaInfo.u4CipherPairwise = IW_AUTH_CIPHER_NONE; -+ prGlueInfo->rWpaInfo.u4AuthAlg = IW_AUTH_ALG_OPEN_SYSTEM; -+#if CFG_SUPPORT_802_11W -+ prGlueInfo->rWpaInfo.u4Mfp = IW_AUTH_MFP_DISABLED; -+#endif -+ -+ if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1) -+ prGlueInfo->rWpaInfo.u4WpaVersion = IW_AUTH_WPA_VERSION_WPA; -+ else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2) -+ prGlueInfo->rWpaInfo.u4WpaVersion = IW_AUTH_WPA_VERSION_WPA2; -+ else -+ prGlueInfo->rWpaInfo.u4WpaVersion = IW_AUTH_WPA_VERSION_DISABLED; -+ -+ switch (sme->auth_type) { -+ case NL80211_AUTHTYPE_OPEN_SYSTEM: -+ prGlueInfo->rWpaInfo.u4AuthAlg = IW_AUTH_ALG_OPEN_SYSTEM; -+ break; -+ case NL80211_AUTHTYPE_SHARED_KEY: -+ prGlueInfo->rWpaInfo.u4AuthAlg = IW_AUTH_ALG_SHARED_KEY; -+ break; -+ default: -+ prGlueInfo->rWpaInfo.u4AuthAlg = IW_AUTH_ALG_OPEN_SYSTEM | IW_AUTH_ALG_SHARED_KEY; -+ break; -+ } -+ -+ if (sme->crypto.n_ciphers_pairwise) { -+ prGlueInfo->prAdapter->rWifiVar.rConnSettings.rRsnInfo.au4PairwiseKeyCipherSuite[0] = -+ sme->crypto.ciphers_pairwise[0]; -+ switch (sme->crypto.ciphers_pairwise[0]) { -+ case WLAN_CIPHER_SUITE_WEP40: -+ prGlueInfo->rWpaInfo.u4CipherPairwise = IW_AUTH_CIPHER_WEP40; -+ break; -+ case WLAN_CIPHER_SUITE_WEP104: -+ prGlueInfo->rWpaInfo.u4CipherPairwise = IW_AUTH_CIPHER_WEP104; -+ break; -+ case WLAN_CIPHER_SUITE_TKIP: -+ prGlueInfo->rWpaInfo.u4CipherPairwise = IW_AUTH_CIPHER_TKIP; -+ break; -+ case WLAN_CIPHER_SUITE_CCMP: -+ prGlueInfo->rWpaInfo.u4CipherPairwise = IW_AUTH_CIPHER_CCMP; -+ break; -+ case WLAN_CIPHER_SUITE_AES_CMAC: -+ prGlueInfo->rWpaInfo.u4CipherPairwise = IW_AUTH_CIPHER_CCMP; -+ break; -+ default: -+ DBGLOG(REQ, WARN, "invalid cipher pairwise (%d)\n", sme->crypto.ciphers_pairwise[0]); -+ return -EINVAL; -+ } -+ } -+ -+ if (sme->crypto.cipher_group) { -+ prGlueInfo->prAdapter->rWifiVar.rConnSettings.rRsnInfo.u4GroupKeyCipherSuite = sme->crypto.cipher_group; -+ switch (sme->crypto.cipher_group) { -+ case WLAN_CIPHER_SUITE_WEP40: -+ prGlueInfo->rWpaInfo.u4CipherGroup = IW_AUTH_CIPHER_WEP40; -+ break; -+ case WLAN_CIPHER_SUITE_WEP104: -+ prGlueInfo->rWpaInfo.u4CipherGroup = IW_AUTH_CIPHER_WEP104; -+ break; -+ case WLAN_CIPHER_SUITE_TKIP: -+ prGlueInfo->rWpaInfo.u4CipherGroup = IW_AUTH_CIPHER_TKIP; -+ break; -+ case WLAN_CIPHER_SUITE_CCMP: -+ prGlueInfo->rWpaInfo.u4CipherGroup = IW_AUTH_CIPHER_CCMP; -+ break; -+ case WLAN_CIPHER_SUITE_AES_CMAC: -+ prGlueInfo->rWpaInfo.u4CipherGroup = IW_AUTH_CIPHER_CCMP; -+ break; -+ default: -+ DBGLOG(REQ, WARN, "invalid cipher group (%d)\n", sme->crypto.cipher_group); -+ return -EINVAL; -+ } -+ } -+ -+ if (sme->crypto.n_akm_suites) { -+ prGlueInfo->prAdapter->rWifiVar.rConnSettings.rRsnInfo.au4AuthKeyMgtSuite[0] = -+ sme->crypto.akm_suites[0]; -+ if (prGlueInfo->rWpaInfo.u4WpaVersion == IW_AUTH_WPA_VERSION_WPA) { -+ switch (sme->crypto.akm_suites[0]) { -+ case WLAN_AKM_SUITE_8021X: -+ eAuthMode = AUTH_MODE_WPA; -+ break; -+ case WLAN_AKM_SUITE_PSK: -+ eAuthMode = AUTH_MODE_WPA_PSK; -+ break; -+ default: -+ DBGLOG(REQ, WARN, "invalid cipher group (%d)\n", sme->crypto.cipher_group); -+ return -EINVAL; -+ } -+ } else if (prGlueInfo->rWpaInfo.u4WpaVersion == IW_AUTH_WPA_VERSION_WPA2) { -+ switch (sme->crypto.akm_suites[0]) { -+ case WLAN_AKM_SUITE_8021X: -+ eAuthMode = AUTH_MODE_WPA2; -+ break; -+ case WLAN_AKM_SUITE_PSK: -+ eAuthMode = AUTH_MODE_WPA2_PSK; -+ break; -+ default: -+ DBGLOG(REQ, WARN, "invalid cipher group (%d)\n", sme->crypto.cipher_group); -+ return -EINVAL; -+ } -+ } -+ } -+ -+ if (prGlueInfo->rWpaInfo.u4WpaVersion == IW_AUTH_WPA_VERSION_DISABLED) { -+ eAuthMode = (prGlueInfo->rWpaInfo.u4AuthAlg == IW_AUTH_ALG_OPEN_SYSTEM) ? -+ AUTH_MODE_OPEN : AUTH_MODE_AUTO_SWITCH; -+ } -+ -+ prGlueInfo->rWpaInfo.fgPrivacyInvoke = sme->privacy; -+ -+ prGlueInfo->fgWpsActive = FALSE; -+#if CFG_SUPPORT_HOTSPOT_2_0 -+ prGlueInfo->fgConnectHS20AP = FALSE; -+#endif -+ -+ if (sme->ie && sme->ie_len > 0) { -+ WLAN_STATUS rStatus; -+ UINT_32 u4BufLen; -+ PUINT_8 prDesiredIE = NULL; -+ PUINT_8 pucIEStart = (PUINT_8)sme->ie; -+ -+#if CFG_SUPPORT_WAPI -+ if (wextSrchDesiredWAPIIE(pucIEStart, sme->ie_len, (PUINT_8 *) &prDesiredIE)) { -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetWapiAssocInfo, -+ prDesiredIE, IE_SIZE(prDesiredIE), FALSE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) -+ DBGLOG(SEC, WARN, "[wapi] set wapi assoc info error:%x\n", rStatus); -+ } -+#endif -+ -+ DBGLOG(REQ, TRACE, "[wlan] wlanoidSetWapiAssocInfo: .fgWapiMode = %d\n", -+ prGlueInfo->prAdapter->rWifiVar.rConnSettings.fgWapiMode); -+ -+#if CFG_SUPPORT_WPS2 -+ if (wextSrchDesiredWPSIE(pucIEStart, sme->ie_len, 0xDD, (PUINT_8 *) &prDesiredIE)) { -+ prGlueInfo->fgWpsActive = TRUE; -+ fgCarryWPSIE = TRUE; -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetWSCAssocInfo, -+ prDesiredIE, IE_SIZE(prDesiredIE), FALSE, FALSE, FALSE, FALSE, &u4BufLen); -+ if (rStatus != WLAN_STATUS_SUCCESS) -+ DBGLOG(SEC, WARN, "WSC] set WSC assoc info error:%x\n", rStatus); -+ } -+#endif -+ -+#if CFG_SUPPORT_HOTSPOT_2_0 -+ if (wextSrchDesiredHS20IE(pucIEStart, sme->ie_len, (PUINT_8 *) &prDesiredIE)) { -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetHS20Info, -+ prDesiredIE, IE_SIZE(prDesiredIE), FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ /* Do nothing */ -+ /* printk(KERN_INFO "[HS20] set HS20 assoc info error:%lx\n", rStatus); */ -+ } -+ } -+ if (wextSrchDesiredInterworkingIE(pucIEStart, sme->ie_len, (PUINT_8 *) &prDesiredIE)) { -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetInterworkingInfo, -+ prDesiredIE, IE_SIZE(prDesiredIE), FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ /* Do nothing */ -+ /* printk(KERN_INFO "[HS20] set Interworking assoc info error:%lx\n", rStatus); */ -+ } -+ } -+ if (wextSrchDesiredRoamingConsortiumIE(pucIEStart, sme->ie_len, (PUINT_8 *) &prDesiredIE)) { -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetRoamingConsortiumIEInfo, -+ prDesiredIE, IE_SIZE(prDesiredIE), FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ /* Do nothing */ -+ /* printk(KERN_INFO "[HS20] set RoamingConsortium assoc info error:%lx\n", rStatus); */ -+ } -+ } -+#endif -+ } -+ -+ /* clear WSC Assoc IE buffer in case WPS IE is not detected */ -+ if (fgCarryWPSIE == FALSE) { -+ kalMemZero(&prGlueInfo->aucWSCAssocInfoIE, 200); -+ prGlueInfo->u2WSCAssocInfoIELen = 0; -+ } -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetAuthMode, &eAuthMode, sizeof(eAuthMode), FALSE, FALSE, FALSE, FALSE, &u4BufLen); -+ if (rStatus != WLAN_STATUS_SUCCESS) -+ DBGLOG(REQ, WARN, "set auth mode error:%x\n", rStatus); -+ -+ cipher = prGlueInfo->rWpaInfo.u4CipherGroup | prGlueInfo->rWpaInfo.u4CipherPairwise; -+ -+ if (prGlueInfo->rWpaInfo.fgPrivacyInvoke) { -+ if (cipher & IW_AUTH_CIPHER_CCMP) { -+ eEncStatus = ENUM_ENCRYPTION3_ENABLED; -+ } else if (cipher & IW_AUTH_CIPHER_TKIP) { -+ eEncStatus = ENUM_ENCRYPTION2_ENABLED; -+ } else if (cipher & (IW_AUTH_CIPHER_WEP104 | IW_AUTH_CIPHER_WEP40)) { -+ eEncStatus = ENUM_ENCRYPTION1_ENABLED; -+ } else if (cipher & IW_AUTH_CIPHER_NONE) { -+ if (prGlueInfo->rWpaInfo.fgPrivacyInvoke) -+ eEncStatus = ENUM_ENCRYPTION1_ENABLED; -+ else -+ eEncStatus = ENUM_ENCRYPTION_DISABLED; -+ } else { -+ eEncStatus = ENUM_ENCRYPTION_DISABLED; -+ } -+ } else { -+ eEncStatus = ENUM_ENCRYPTION_DISABLED; -+ } -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetEncryptionStatus, -+ &eEncStatus, sizeof(eEncStatus), FALSE, FALSE, FALSE, FALSE, &u4BufLen); -+ if (rStatus != WLAN_STATUS_SUCCESS) -+ DBGLOG(REQ, WARN, "set encryption mode error:%x\n", rStatus); -+ -+ if (sme->key_len != 0 && prGlueInfo->rWpaInfo.u4WpaVersion == IW_AUTH_WPA_VERSION_DISABLED) { -+ P_PARAM_WEP_T prWepKey = (P_PARAM_WEP_T) wepBuf; -+ -+ prWepKey->u4Length = 12 + sme->key_len; -+ prWepKey->u4KeyLength = (UINT_32) sme->key_len; -+ prWepKey->u4KeyIndex = (UINT_32) sme->key_idx; -+ prWepKey->u4KeyIndex |= BIT(31); -+ if (prWepKey->u4KeyLength > 32) { -+ DBGLOG(REQ, ERROR, "Too long key length (%u)\n", prWepKey->u4KeyLength); -+ return -EINVAL; -+ } -+ kalMemCopy(prWepKey->aucKeyMaterial, sme->key, prWepKey->u4KeyLength); -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetAddWep, -+ prWepKey, prWepKey->u4Length, FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ DBGLOG(REQ, ERROR, "wlanoidSetAddWep fail 0x%x\n", rStatus); -+ return -EFAULT; -+ } -+ } -+ -+ if (sme->channel) -+ rNewSsid.u4CenterFreq = sme->channel->center_freq; -+ else -+ rNewSsid.u4CenterFreq = 0; -+ rNewSsid.pucBssid = (UINT_8 *)sme->bssid; -+ rNewSsid.pucSsid = (UINT_8 *)sme->ssid; -+ rNewSsid.u4SsidLen = sme->ssid_len; -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetConnect, -+ (PVOID)(&rNewSsid), sizeof(PARAM_CONNECT_T), FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ DBGLOG(REQ, ERROR, "set SSID:%x\n", rStatus); -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * @brief This routine is responsible for requesting to disconnect from -+ * currently connected ESS -+ * -+ * @param -+ * -+ * @retval 0: successful -+ * others: failure -+ */ -+/*----------------------------------------------------------------------------*/ -+int mtk_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *ndev, u16 reason_code) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ WLAN_STATUS rStatus; -+ UINT_32 u4BufLen; -+ -+ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); -+ ASSERT(prGlueInfo); -+ -+ rStatus = kalIoctl(prGlueInfo, wlanoidSetDisassociate, NULL, 0, FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ DBGLOG(REQ, WARN, "disassociate error:%x\n", rStatus); -+ return -EFAULT; -+ } -+ -+ return 0; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * @brief This routine is responsible for requesting to join an IBSS group -+ * -+ * @param -+ * -+ * @retval 0: successful -+ * others: failure -+ */ -+/*----------------------------------------------------------------------------*/ -+int mtk_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev, struct cfg80211_ibss_params *params) -+{ -+ PARAM_SSID_T rNewSsid; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ UINT_32 u4ChnlFreq; /* Store channel or frequency information */ -+ UINT_32 u4BufLen = 0; -+ WLAN_STATUS rStatus; -+ struct ieee80211_channel *channel = NULL; -+ -+ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); -+ ASSERT(prGlueInfo); -+ -+ /* set channel */ -+ if (params->chandef.chan) -+ channel = params->chandef.chan; -+ if (channel) { -+ u4ChnlFreq = nicChannelNum2Freq(channel->hw_value); -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetFrequency, -+ &u4ChnlFreq, sizeof(u4ChnlFreq), FALSE, FALSE, FALSE, FALSE, &u4BufLen); -+ if (rStatus != WLAN_STATUS_SUCCESS) -+ return -EFAULT; -+ } -+ -+ /* set SSID */ -+ kalMemCopy(rNewSsid.aucSsid, params->ssid, params->ssid_len); -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetSsid, -+ (PVOID)(&rNewSsid), sizeof(PARAM_SSID_T), FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ DBGLOG(REQ, WARN, "set SSID:%x\n", rStatus); -+ return -EFAULT; -+ } -+ -+ return 0; -+ -+ return -EINVAL; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * @brief This routine is responsible for requesting to leave from IBSS group -+ * -+ * @param -+ * -+ * @retval 0: successful -+ * others: failure -+ */ -+/*----------------------------------------------------------------------------*/ -+int mtk_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *ndev) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ WLAN_STATUS rStatus; -+ UINT_32 u4BufLen; -+ -+ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); -+ ASSERT(prGlueInfo); -+ -+ rStatus = kalIoctl(prGlueInfo, wlanoidSetDisassociate, NULL, 0, FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ DBGLOG(REQ, WARN, "disassociate error:%x\n", rStatus); -+ return -EFAULT; -+ } -+ -+ return 0; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * @brief This routine is responsible for requesting to configure -+ * WLAN power managemenet -+ * -+ * @param -+ * -+ * @retval 0: successful -+ * others: failure -+ */ -+/*----------------------------------------------------------------------------*/ -+int mtk_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *ndev, bool enabled, int timeout) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ WLAN_STATUS rStatus; -+ UINT_32 u4BufLen; -+ PARAM_POWER_MODE ePowerMode; -+ -+ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); -+ ASSERT(prGlueInfo); -+ -+ if (enabled) { -+ if (timeout == -1) -+ ePowerMode = Param_PowerModeFast_PSP; -+ else -+ ePowerMode = Param_PowerModeMAX_PSP; -+ } else { -+ ePowerMode = Param_PowerModeCAM; -+ } -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSet802dot11PowerSaveProfile, -+ &ePowerMode, sizeof(ePowerMode), FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ DBGLOG(REQ, WARN, "set_power_mgmt error:%x\n", rStatus); -+ return -EFAULT; -+ } -+ -+ return 0; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * @brief This routine is responsible for requesting to cache -+ * a PMKID for a BSSID -+ * -+ * @param -+ * -+ * @retval 0: successful -+ * others: failure -+ */ -+/*----------------------------------------------------------------------------*/ -+int mtk_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *ndev, struct cfg80211_pmksa *pmksa) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ WLAN_STATUS rStatus; -+ UINT_32 u4BufLen; -+ P_PARAM_PMKID_T prPmkid; -+ -+ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); -+ ASSERT(prGlueInfo); -+ -+ prPmkid = (P_PARAM_PMKID_T) kalMemAlloc(8 + sizeof(PARAM_BSSID_INFO_T), VIR_MEM_TYPE); -+ if (!prPmkid) { -+ DBGLOG(REQ, ERROR, "Can not alloc memory for IW_PMKSA_ADD\n"); -+ return -ENOMEM; -+ } -+ -+ prPmkid->u4Length = 8 + sizeof(PARAM_BSSID_INFO_T); -+ prPmkid->u4BSSIDInfoCount = 1; -+ kalMemCopy(prPmkid->arBSSIDInfo->arBSSID, pmksa->bssid, 6); -+ kalMemCopy(prPmkid->arBSSIDInfo->arPMKID, pmksa->pmkid, IW_PMKID_LEN); -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetPmkid, prPmkid, sizeof(PARAM_PMKID_T), FALSE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) -+ DBGLOG(REQ, WARN, "add pmkid error:%x\n", rStatus); -+ kalMemFree(prPmkid, VIR_MEM_TYPE, 8 + sizeof(PARAM_BSSID_INFO_T)); -+ -+ return 0; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * @brief This routine is responsible for requesting to remove -+ * a cached PMKID for a BSSID -+ * -+ * @param -+ * -+ * @retval 0: successful -+ * others: failure -+ */ -+/*----------------------------------------------------------------------------*/ -+int mtk_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *ndev, struct cfg80211_pmksa *pmksa) -+{ -+ -+ return 0; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * @brief This routine is responsible for requesting to flush -+ * all cached PMKID -+ * -+ * @param -+ * -+ * @retval 0: successful -+ * others: failure -+ */ -+/*----------------------------------------------------------------------------*/ -+int mtk_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *ndev) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ WLAN_STATUS rStatus; -+ UINT_32 u4BufLen; -+ P_PARAM_PMKID_T prPmkid; -+ -+ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); -+ ASSERT(prGlueInfo); -+ -+ prPmkid = (P_PARAM_PMKID_T) kalMemAlloc(8, VIR_MEM_TYPE); -+ if (!prPmkid) { -+ DBGLOG(REQ, ERROR, "Can not alloc memory for IW_PMKSA_FLUSH\n"); -+ return -ENOMEM; -+ } -+ -+ prPmkid->u4Length = 8; -+ prPmkid->u4BSSIDInfoCount = 0; -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetPmkid, prPmkid, sizeof(PARAM_PMKID_T), FALSE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) -+ DBGLOG(REQ, WARN, "flush pmkid error:%x\n", rStatus); -+ kalMemFree(prPmkid, VIR_MEM_TYPE, 8); -+ -+ return 0; -+} -+ -+void mtk_cfg80211_mgmt_frame_register(IN struct wiphy *wiphy, -+ IN struct wireless_dev *wdev, -+ IN u16 frame_type, IN bool reg) -+{ -+#if 0 -+ P_MSG_P2P_MGMT_FRAME_REGISTER_T prMgmtFrameRegister = (P_MSG_P2P_MGMT_FRAME_REGISTER_T) NULL; -+#endif -+ P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) NULL; -+ -+ do { -+ -+ DBGLOG(REQ, LOUD, "mtk_cfg80211_mgmt_frame_register\n"); -+ -+ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); -+ -+ switch (frame_type) { -+ case MAC_FRAME_PROBE_REQ: -+ if (reg) { -+ prGlueInfo->u4OsMgmtFrameFilter |= PARAM_PACKET_FILTER_PROBE_REQ; -+ DBGLOG(REQ, LOUD, "Open packet filer probe request\n"); -+ } else { -+ prGlueInfo->u4OsMgmtFrameFilter &= ~PARAM_PACKET_FILTER_PROBE_REQ; -+ DBGLOG(REQ, LOUD, "Close packet filer probe request\n"); -+ } -+ break; -+ case MAC_FRAME_ACTION: -+ if (reg) { -+ prGlueInfo->u4OsMgmtFrameFilter |= PARAM_PACKET_FILTER_ACTION_FRAME; -+ DBGLOG(REQ, LOUD, "Open packet filer action frame.\n"); -+ } else { -+ prGlueInfo->u4OsMgmtFrameFilter &= ~PARAM_PACKET_FILTER_ACTION_FRAME; -+ DBGLOG(REQ, LOUD, "Close packet filer action frame.\n"); -+ } -+ break; -+ default: -+ DBGLOG(REQ, TRACE, "Ask frog to add code for mgmt:%x\n", frame_type); -+ break; -+ } -+ -+ if (prGlueInfo->prAdapter != NULL) { -+ /* prGlueInfo->ulFlag |= GLUE_FLAG_FRAME_FILTER_AIS; */ -+ set_bit(GLUE_FLAG_FRAME_FILTER_AIS_BIT, &prGlueInfo->ulFlag); -+ -+ /* wake up main thread */ -+ wake_up_interruptible(&prGlueInfo->waitq); -+ -+ if (in_interrupt()) -+ DBGLOG(REQ, TRACE, "It is in interrupt level\n"); -+ } -+#if 0 -+ -+ prMgmtFrameRegister = (P_MSG_P2P_MGMT_FRAME_REGISTER_T) cnmMemAlloc(prGlueInfo->prAdapter, -+ RAM_TYPE_MSG, -+ sizeof -+ (MSG_P2P_MGMT_FRAME_REGISTER_T)); -+ -+ if (prMgmtFrameRegister == NULL) { -+ ASSERT(FALSE); -+ break; -+ } -+ -+ prMgmtFrameRegister->rMsgHdr.eMsgId = MID_MNY_P2P_MGMT_FRAME_REGISTER; -+ -+ prMgmtFrameRegister->u2FrameType = frame_type; -+ prMgmtFrameRegister->fgIsRegister = reg; -+ -+ mboxSendMsg(prGlueInfo->prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMgmtFrameRegister, MSG_SEND_METHOD_BUF); -+ -+#endif -+ -+ } while (FALSE); -+ -+} /* mtk_cfg80211_mgmt_frame_register */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * @brief This routine is responsible for requesting to stay on a -+ * specified channel -+ * -+ * @param -+ * -+ * @retval 0: successful -+ * others: failure -+ */ -+/*----------------------------------------------------------------------------*/ -+int mtk_cfg80211_remain_on_channel(struct wiphy *wiphy, -+ struct wireless_dev *wdev, -+ struct ieee80211_channel *chan, -+ unsigned int duration, u64 *cookie) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ INT_32 i4Rslt = -EINVAL; -+ P_MSG_REMAIN_ON_CHANNEL_T prMsgChnlReq = (P_MSG_REMAIN_ON_CHANNEL_T) NULL; -+ -+ do { -+ if ((wiphy == NULL) || (wdev == NULL) || (chan == NULL) || (cookie == NULL)) -+ break; -+ -+ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); -+ ASSERT(prGlueInfo); -+ -+#if 1 -+ DBGLOG(REQ, TRACE, "--> %s()\n", __func__); -+#endif -+ -+ *cookie = prGlueInfo->u8Cookie++; -+ -+ prMsgChnlReq = cnmMemAlloc(prGlueInfo->prAdapter, RAM_TYPE_MSG, sizeof(MSG_REMAIN_ON_CHANNEL_T)); -+ -+ if (prMsgChnlReq == NULL) { -+ ASSERT(FALSE); -+ i4Rslt = -ENOMEM; -+ break; -+ } -+ kalMemZero(prMsgChnlReq, sizeof(MSG_REMAIN_ON_CHANNEL_T)); -+ -+ prMsgChnlReq->rMsgHdr.eMsgId = MID_MNY_AIS_REMAIN_ON_CHANNEL; -+ prMsgChnlReq->u8Cookie = *cookie; -+ prMsgChnlReq->u4DurationMs = duration; -+ -+ prMsgChnlReq->ucChannelNum = nicFreq2ChannelNum(chan->center_freq * 1000); -+ -+ switch (chan->band) { -+ case NL80211_BAND_2GHZ: -+ prMsgChnlReq->eBand = BAND_2G4; -+ break; -+ case NL80211_BAND_5GHZ: -+ prMsgChnlReq->eBand = BAND_5G; -+ break; -+ default: -+ prMsgChnlReq->eBand = BAND_2G4; -+ break; -+ } -+ -+ mboxSendMsg(prGlueInfo->prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgChnlReq, MSG_SEND_METHOD_BUF); -+ -+ i4Rslt = 0; -+ } while (FALSE); -+ -+ return i4Rslt; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * @brief This routine is responsible for requesting to cancel staying -+ * on a specified channel -+ * -+ * @param -+ * -+ * @retval 0: successful -+ * others: failure -+ */ -+/*----------------------------------------------------------------------------*/ -+int mtk_cfg80211_cancel_remain_on_channel(struct wiphy *wiphy, -+ struct wireless_dev *wdev, -+ u64 cookie) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ INT_32 i4Rslt = -EINVAL; -+ P_MSG_CANCEL_REMAIN_ON_CHANNEL_T prMsgChnlAbort = (P_MSG_CANCEL_REMAIN_ON_CHANNEL_T) NULL; -+ -+ do { -+ if ((wiphy == NULL) || (wdev == NULL)) -+ break; -+ -+ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); -+ ASSERT(prGlueInfo); -+ -+#if 1 -+ DBGLOG(REQ, TRACE, "--> %s()\n", __func__); -+#endif -+ -+ prMsgChnlAbort = -+ cnmMemAlloc(prGlueInfo->prAdapter, RAM_TYPE_MSG, sizeof(MSG_CANCEL_REMAIN_ON_CHANNEL_T)); -+ -+ if (prMsgChnlAbort == NULL) { -+ ASSERT(FALSE); -+ i4Rslt = -ENOMEM; -+ break; -+ } -+ -+ prMsgChnlAbort->rMsgHdr.eMsgId = MID_MNY_AIS_CANCEL_REMAIN_ON_CHANNEL; -+ prMsgChnlAbort->u8Cookie = cookie; -+ -+ mboxSendMsg(prGlueInfo->prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgChnlAbort, MSG_SEND_METHOD_BUF); -+ -+ i4Rslt = 0; -+ } while (FALSE); -+ -+ return i4Rslt; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * @brief This routine is responsible for requesting to send a management frame -+ * -+ * @param -+ * -+ * @retval 0: successful -+ * others: failure -+ */ -+/*----------------------------------------------------------------------------*/ -+int -+mtk_cfg80211_mgmt_tx(struct wiphy *wiphy, -+ struct wireless_dev *wdev, -+ struct cfg80211_mgmt_tx_params *params, -+ u64 *cookie) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ INT_32 i4Rslt = -EINVAL; -+ P_MSG_MGMT_TX_REQUEST_T prMsgTxReq = (P_MSG_MGMT_TX_REQUEST_T) NULL; -+ P_MSDU_INFO_T prMgmtFrame = (P_MSDU_INFO_T) NULL; -+ PUINT_8 pucFrameBuf = (PUINT_8) NULL; -+ -+ do { -+#if 1 -+ DBGLOG(REQ, TRACE, "--> %s()\n", __func__); -+#endif -+ -+ if ((wiphy == NULL) || (wdev == NULL) || (params == 0) || (cookie == NULL)) -+ break; -+ -+ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); -+ ASSERT(prGlueInfo); -+ -+ *cookie = prGlueInfo->u8Cookie++; -+ -+ /* Channel & Channel Type & Wait time are ignored. */ -+ prMsgTxReq = cnmMemAlloc(prGlueInfo->prAdapter, RAM_TYPE_MSG, sizeof(MSG_MGMT_TX_REQUEST_T)); -+ -+ if (prMsgTxReq == NULL) { -+ ASSERT(FALSE); -+ i4Rslt = -ENOMEM; -+ break; -+ } -+ -+ prMsgTxReq->fgNoneCckRate = FALSE; -+ prMsgTxReq->fgIsWaitRsp = TRUE; -+ -+ prMgmtFrame = cnmMgtPktAlloc(prGlueInfo->prAdapter, (UINT_32) (params->len + MAC_TX_RESERVED_FIELD)); -+ prMsgTxReq->prMgmtMsduInfo = prMgmtFrame; -+ if (prMsgTxReq->prMgmtMsduInfo == NULL) { -+ ASSERT(FALSE); -+ i4Rslt = -ENOMEM; -+ break; -+ } -+ -+ prMsgTxReq->u8Cookie = *cookie; -+ prMsgTxReq->rMsgHdr.eMsgId = MID_MNY_AIS_MGMT_TX; -+ -+ pucFrameBuf = (PUINT_8) ((ULONG) prMgmtFrame->prPacket + MAC_TX_RESERVED_FIELD); -+ -+ kalMemCopy(pucFrameBuf, params->buf, params->len); -+ -+ prMgmtFrame->u2FrameLength = params->len; -+ -+ mboxSendMsg(prGlueInfo->prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgTxReq, MSG_SEND_METHOD_BUF); -+ -+ i4Rslt = 0; -+ } while (FALSE); -+ -+ if ((i4Rslt != 0) && (prMsgTxReq != NULL)) { -+ if (prMsgTxReq->prMgmtMsduInfo != NULL) -+ cnmMgtPktFree(prGlueInfo->prAdapter, prMsgTxReq->prMgmtMsduInfo); -+ -+ cnmMemFree(prGlueInfo->prAdapter, prMsgTxReq); -+ } -+ -+ return i4Rslt; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * @brief This routine is responsible for requesting to cancel the wait time -+ * from transmitting a management frame on another channel -+ * -+ * @param -+ * -+ * @retval 0: successful -+ * others: failure -+ */ -+/*----------------------------------------------------------------------------*/ -+int mtk_cfg80211_mgmt_tx_cancel_wait(struct wiphy *wiphy, -+ struct wireless_dev *wdev, -+ u64 cookie) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ -+ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); -+ ASSERT(prGlueInfo); -+ -+ DBGLOG(REQ, TRACE, "--> %s()\n", __func__); -+ -+ /* not implemented */ -+ -+ return -EINVAL; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * @brief This routine is responsible for handling sched_scan start/stop request -+ * -+ * @param -+ * -+ * @retval 0: successful -+ * others: failure -+ */ -+/*----------------------------------------------------------------------------*/ -+ -+int -+mtk_cfg80211_sched_scan_start(IN struct wiphy *wiphy, -+ IN struct net_device *ndev, IN struct cfg80211_sched_scan_request *request) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ WLAN_STATUS rStatus; -+ UINT_32 i, u4BufLen; -+ P_PARAM_SCHED_SCAN_REQUEST prSchedScanRequest; -+ -+ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); -+ -+ ASSERT(prGlueInfo); -+ -+ /* check if there is any pending scan/sched_scan not yet finished */ -+ if (prGlueInfo->prScanRequest != NULL || prGlueInfo->prSchedScanRequest != NULL) { -+ DBGLOG(SCN, ERROR, "(prGlueInfo->prScanRequest != NULL || prGlueInfo->prSchedScanRequest != NULL)\n"); -+ return -EBUSY; -+ } else if (request == NULL || request->n_match_sets > CFG_SCAN_SSID_MATCH_MAX_NUM) { -+ DBGLOG(SCN, ERROR, "(request == NULL || request->n_match_sets > CFG_SCAN_SSID_MATCH_MAX_NUM)\n"); -+ /* invalid scheduled scan request */ -+ return -EINVAL; -+ } else if (/* !request->n_ssids || */!request->n_match_sets) { -+ /* invalid scheduled scan request */ -+ return -EINVAL; -+ } -+ -+ prSchedScanRequest = (P_PARAM_SCHED_SCAN_REQUEST) kalMemAlloc(sizeof(PARAM_SCHED_SCAN_REQUEST), VIR_MEM_TYPE); -+ if (prSchedScanRequest == NULL) { -+ DBGLOG(SCN, ERROR, "(prSchedScanRequest == NULL) kalMemAlloc fail\n"); -+ return -ENOMEM; -+ } -+ -+ kalMemZero(prSchedScanRequest, sizeof(PARAM_SCHED_SCAN_REQUEST)); -+ -+ prSchedScanRequest->u4SsidNum = request->n_match_sets; -+ for (i = 0; i < request->n_match_sets; i++) { -+ if (request->match_sets == NULL || &(request->match_sets[i]) == NULL) { -+ prSchedScanRequest->arSsid[i].u4SsidLen = 0; -+ } else { -+ COPY_SSID(prSchedScanRequest->arSsid[i].aucSsid, -+ prSchedScanRequest->arSsid[i].u4SsidLen, -+ request->match_sets[i].ssid.ssid, request->match_sets[i].ssid.ssid_len); -+ } -+ } -+ -+ prSchedScanRequest->u4IELength = request->ie_len; -+ if (request->ie_len > 0) -+ prSchedScanRequest->pucIE = (PUINT_8) (request->ie); -+ -+ prSchedScanRequest->u2ScanInterval = (UINT_16) (request->scan_plans[0].interval); -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetStartSchedScan, -+ prSchedScanRequest, sizeof(PARAM_SCHED_SCAN_REQUEST), FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ -+ kalMemFree(prSchedScanRequest, VIR_MEM_TYPE, sizeof(PARAM_SCHED_SCAN_REQUEST)); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ DBGLOG(SCN, ERROR, "scheduled scan error:%x\n", rStatus); -+ return -EINVAL; -+ } -+ -+ prGlueInfo->prSchedScanRequest = request; -+ -+ return 0; -+} -+ -+int mtk_cfg80211_sched_scan_stop(IN struct wiphy *wiphy, IN struct net_device *ndev, u64 reqid) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ WLAN_STATUS rStatus; -+ UINT_32 u4BufLen; -+ -+ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); -+ ASSERT(prGlueInfo); -+ -+ /* check if there is any pending scan/sched_scan not yet finished */ -+ if (prGlueInfo->prSchedScanRequest == NULL) { -+ DBGLOG(SCN, ERROR, "prGlueInfo->prSchedScanRequest == NULL\n"); -+ return -EBUSY; -+ } -+ -+ rStatus = kalIoctl(prGlueInfo, wlanoidSetStopSchedScan, NULL, 0, FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ DBGLOG(SCN, ERROR, "scheduled scan error, rStatus: %d\n", rStatus); -+ return -EINVAL; -+ } -+ -+ /* 1. reset first for newly incoming request */ -+ /* GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV); */ -+ if (prGlueInfo->prSchedScanRequest != NULL) -+ prGlueInfo->prSchedScanRequest = NULL; -+ /* GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV); */ -+ -+ DBGLOG(SCN, TRACE, "start work queue to send event\n"); -+ schedule_delayed_work(&sched_workq, 0); -+ DBGLOG(SCN, TRACE, "tx_thread return from kalSchedScanStoppped\n"); -+ -+ return 0; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * @brief This routine is responsible for handling association request -+ * -+ * @param -+ * -+ * @retval 0: successful -+ * others: failure -+ */ -+/*----------------------------------------------------------------------------*/ -+int mtk_cfg80211_assoc(struct wiphy *wiphy, struct net_device *ndev, struct cfg80211_assoc_request *req) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ PARAM_MAC_ADDRESS arBssid; -+#if CFG_SUPPORT_HOTSPOT_2_0 -+ PUINT_8 prDesiredIE = NULL; -+#endif -+ WLAN_STATUS rStatus; -+ UINT_32 u4BufLen; -+ -+ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); -+ ASSERT(prGlueInfo); -+ -+ kalMemZero(arBssid, MAC_ADDR_LEN); -+ wlanQueryInformation(prGlueInfo->prAdapter, wlanoidQueryBssid, &arBssid[0], sizeof(arBssid), &u4BufLen); -+ -+ /* 1. check BSSID */ -+ if (UNEQUAL_MAC_ADDR(arBssid, req->bss->bssid)) { -+ /* wrong MAC address */ -+ DBGLOG(REQ, WARN, "incorrect BSSID: [ %pM ] currently connected BSSID[ %pM ]\n", -+ req->bss->bssid, arBssid); -+ return -ENOENT; -+ } -+ -+ if (req->ie && req->ie_len > 0) { -+#if CFG_SUPPORT_HOTSPOT_2_0 -+ if (wextSrchDesiredHS20IE((PUINT_8) req->ie, req->ie_len, (PUINT_8 *) &prDesiredIE)) { -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetHS20Info, -+ prDesiredIE, IE_SIZE(prDesiredIE), FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ /* Do nothing */ -+ /* printk(KERN_INFO "[HS20] set HS20 assoc info error:%lx\n", rStatus); */ -+ } -+ } -+ -+ if (wextSrchDesiredInterworkingIE((PUINT_8) req->ie, req->ie_len, (PUINT_8 *) &prDesiredIE)) { -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetInterworkingInfo, -+ prDesiredIE, IE_SIZE(prDesiredIE), FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ /* Do nothing */ -+ /* printk(KERN_INFO "[HS20] set Interworking assoc info error:%lx\n", rStatus); */ -+ } -+ } -+ -+ if (wextSrchDesiredRoamingConsortiumIE((PUINT_8) req->ie, req->ie_len, (PUINT_8 *) &prDesiredIE)) { -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetRoamingConsortiumIEInfo, -+ prDesiredIE, IE_SIZE(prDesiredIE), FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ /* Do nothing */ -+ /* printk(KERN_INFO "[HS20] set RoamingConsortium assoc info error:%lx\n", rStatus); */ -+ } -+ } -+#endif -+ } -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetBssid, -+ (PVOID) req->bss->bssid, MAC_ADDR_LEN, FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ DBGLOG(REQ, WARN, "set BSSID:%x\n", rStatus); -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ -+#if CONFIG_NL80211_TESTMODE -+/* -+#define NLA_PUT(skb, attrtype, attrlen, data) \ -+do { \ -+ if (unlikely(nla_put(skb, attrtype, attrlen, data) < 0)) \ -+ goto nla_put_failure; \ -+} while (0) -+ -+#define NLA_PUT_TYPE(skb, type, attrtype, value) \ -+do { \ -+ type __tmp = value; \ -+ NLA_PUT(skb, attrtype, sizeof(type), &__tmp); \ -+} while (0) -+ -+#define NLA_PUT_U8(skb, attrtype, value) \ -+ NLA_PUT_TYPE(skb, u8, attrtype, value) -+ -+#define NLA_PUT_U16(skb, attrtype, value) \ -+ NLA_PUT_TYPE(skb, u16, attrtype, value) -+ -+#define NLA_PUT_U32(skb, attrtype, value) \ -+ NLA_PUT_TYPE(skb, u32, attrtype, value) -+ -+#define NLA_PUT_U64(skb, attrtype, value) \ -+ NLA_PUT_TYPE(skb, u64, attrtype, value) -+*/ -+#if CFG_SUPPORT_WAPI -+int mtk_cfg80211_testmode_set_key_ext(IN struct wiphy *wiphy, IN void *data, IN int len) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ P_NL80211_DRIVER_SET_KEY_EXTS prParams = (P_NL80211_DRIVER_SET_KEY_EXTS) NULL; -+ struct iw_encode_exts *prIWEncExt = (struct iw_encode_exts *)NULL; -+ WLAN_STATUS rstatus = WLAN_STATUS_SUCCESS; -+ int fgIsValid = 0; -+ UINT_32 u4BufLen = 0; -+ -+ P_PARAM_WPI_KEY_T prWpiKey = (P_PARAM_WPI_KEY_T) keyStructBuf; -+ -+ memset(keyStructBuf, 0, sizeof(keyStructBuf)); -+ -+ ASSERT(wiphy); -+ -+ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); -+ -+ DBGLOG(REQ, TRACE, "--> %s()\n", __func__); -+ -+ if (data && len) { -+ prParams = (P_NL80211_DRIVER_SET_KEY_EXTS) data; -+ } else { -+ DBGLOG(REQ, ERROR, "mtk_cfg80211_testmode_set_key_ext, data is NULL\n"); -+ return -EINVAL; -+ } -+ -+ if (prParams) -+ prIWEncExt = (struct iw_encode_exts *)&prParams->ext; -+ -+ if (prIWEncExt->alg == IW_ENCODE_ALG_SMS4) { -+ /* KeyID */ -+ prWpiKey->ucKeyID = prParams->key_index; -+ prWpiKey->ucKeyID--; -+ if (prWpiKey->ucKeyID > 1) { -+ /* key id is out of range */ -+ /* printk(KERN_INFO "[wapi] add key error: key_id invalid %d\n", prWpiKey->ucKeyID); */ -+ return -EINVAL; -+ } -+ -+ if (prIWEncExt->key_len != 32) { -+ /* key length not valid */ -+ /* printk(KERN_INFO "[wapi] add key error: key_len invalid %d\n", prIWEncExt->key_len); */ -+ return -EINVAL; -+ } -+ /* printk(KERN_INFO "[wapi] %d ext_flags %d\n", prEnc->flags, prIWEncExt->ext_flags); */ -+ -+ if (prIWEncExt->ext_flags & IW_ENCODE_EXT_GROUP_KEY) { -+ prWpiKey->eKeyType = ENUM_WPI_GROUP_KEY; -+ prWpiKey->eDirection = ENUM_WPI_RX; -+ } else if (prIWEncExt->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) { -+ prWpiKey->eKeyType = ENUM_WPI_PAIRWISE_KEY; -+ prWpiKey->eDirection = ENUM_WPI_RX_TX; -+ } -+/* #if CFG_SUPPORT_WAPI */ -+ /* handle_sec_msg_final(prIWEncExt->key, 32, prIWEncExt->key, NULL); */ -+/* #endif */ -+ /* PN */ -+ memcpy(prWpiKey->aucPN, prIWEncExt->tx_seq, IW_ENCODE_SEQ_MAX_SIZE); -+ memcpy(prWpiKey->aucPN + IW_ENCODE_SEQ_MAX_SIZE, prIWEncExt->rx_seq, IW_ENCODE_SEQ_MAX_SIZE); -+ -+ -+ /* BSSID */ -+ memcpy(prWpiKey->aucAddrIndex, prIWEncExt->addr, 6); -+ -+ memcpy(prWpiKey->aucWPIEK, prIWEncExt->key, 16); -+ prWpiKey->u4LenWPIEK = 16; -+ -+ memcpy(prWpiKey->aucWPICK, &prIWEncExt->key[16], 16); -+ prWpiKey->u4LenWPICK = 16; -+ -+ rstatus = kalIoctl(prGlueInfo, -+ wlanoidSetWapiKey, -+ prWpiKey, sizeof(PARAM_WPI_KEY_T), FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ -+ if (rstatus != WLAN_STATUS_SUCCESS) { -+ /* printk(KERN_INFO "[wapi] add key error:%lx\n", rStatus); */ -+ fgIsValid = -EFAULT; -+ } -+ -+ } -+ return fgIsValid; -+} -+#endif -+ -+int -+mtk_cfg80211_testmode_get_sta_statistics(IN struct wiphy *wiphy, IN void *data, IN int len, IN P_GLUE_INFO_T prGlueInfo) -+{ -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ INT_32 i4Status = -EINVAL; -+ UINT_32 u4BufLen; -+ UINT_32 u4LinkScore; -+ UINT_32 u4TotalError; -+ UINT_32 u4TxExceedThresholdCount; -+ UINT_32 u4TxTotalCount; -+ -+ P_NL80211_DRIVER_GET_STA_STATISTICS_PARAMS prParams = NULL; -+ PARAM_GET_STA_STA_STATISTICS rQueryStaStatistics; -+ struct sk_buff *skb; -+ -+ ASSERT(wiphy); -+ ASSERT(prGlueInfo); -+ -+ if (data && len) { -+ prParams = (P_NL80211_DRIVER_GET_STA_STATISTICS_PARAMS) data; -+ } else { -+ DBGLOG(QM, ERROR, "mtk_cfg80211_testmode_get_sta_statistics, data is NULL\n"); -+ return -EINVAL; -+ } -+/* -+ if (!prParams->aucMacAddr) { -+ DBGLOG(QM, INFO, "%s MAC Address is NULL\n", __func__); -+ return -EINVAL; -+ } -+*/ -+ skb = cfg80211_testmode_alloc_reply_skb(wiphy, sizeof(PARAM_GET_STA_STA_STATISTICS) + 1); -+ -+ if (!skb) { -+ DBGLOG(QM, ERROR, "%s allocate skb failed:%x\n", __func__, rStatus); -+ return -ENOMEM; -+ } -+ -+ DBGLOG(QM, TRACE, "Get [ %pM ] STA statistics\n", prParams->aucMacAddr); -+ -+ kalMemZero(&rQueryStaStatistics, sizeof(rQueryStaStatistics)); -+ COPY_MAC_ADDR(rQueryStaStatistics.aucMacAddr, prParams->aucMacAddr); -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidQueryStaStatistics, -+ &rQueryStaStatistics, sizeof(rQueryStaStatistics), TRUE, FALSE, TRUE, TRUE, &u4BufLen); -+ -+ /* Calcute Link Score */ -+ u4TxExceedThresholdCount = rQueryStaStatistics.u4TxExceedThresholdCount; -+ u4TxTotalCount = rQueryStaStatistics.u4TxTotalCount; -+ u4TotalError = rQueryStaStatistics.u4TxFailCount + rQueryStaStatistics.u4TxLifeTimeoutCount; -+ -+ /* u4LinkScore 10~100 , ExceedThreshold ratio 0~90 only */ -+ /* u4LinkScore 0~9 , Drop packet ratio 0~9 and all packets exceed threshold */ -+ if (u4TxTotalCount) { -+ if (u4TxExceedThresholdCount <= u4TxTotalCount) -+ u4LinkScore = (90 - ((u4TxExceedThresholdCount * 90) / u4TxTotalCount)); -+ else -+ u4LinkScore = 0; -+ } else { -+ u4LinkScore = 90; -+ } -+ -+ u4LinkScore += 10; -+ -+ if (u4LinkScore == 10) { -+ -+ if (u4TotalError <= u4TxTotalCount) -+ u4LinkScore = (10 - ((u4TotalError * 10) / u4TxTotalCount)); -+ else -+ u4LinkScore = 0; -+ -+ } -+ -+ if (u4LinkScore > 100) -+ u4LinkScore = 100; -+ -+ /*NLA_PUT_U8(skb, NL80211_TESTMODE_STA_STATISTICS_INVALID, 0);*/ -+ { -+ unsigned char __tmp = 0; -+ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_INVALID, sizeof(unsigned char), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ -+ /*NLA_PUT_U8(skb, NL80211_TESTMODE_STA_STATISTICS_VERSION, NL80211_DRIVER_TESTMODE_VERSION);*/ -+ { -+ unsigned char __tmp = NL80211_DRIVER_TESTMODE_VERSION; -+ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_VERSION, sizeof(unsigned char), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ -+ /* NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_LINK_SCORE, u4LinkScore); */ -+ { -+ unsigned int __tmp = u4LinkScore; -+ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_LINK_SCORE, -+ sizeof(unsigned int), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ -+ /*NLA_PUT(skb, NL80211_TESTMODE_STA_STATISTICS_MAC, MAC_ADDR_LEN, prParams->aucMacAddr);*/ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_MAC, MAC_ADDR_LEN, &prParams->aucMacAddr) < 0)) -+ goto nla_put_failure; -+ -+ /*NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_FLAG, rQueryStaStatistics.u4Flag);*/ -+ { -+ unsigned int __tmp = rQueryStaStatistics.u4Flag; -+ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_FLAG, -+ sizeof(unsigned int), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ -+ -+ /* FW part STA link status */ -+ /*NLA_PUT_U8(skb, NL80211_TESTMODE_STA_STATISTICS_PER, rQueryStaStatistics.ucPer);*/ -+ { -+ unsigned char __tmp = rQueryStaStatistics.ucPer; -+ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_PER, sizeof(unsigned char), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ -+ /*NLA_PUT_U8(skb, NL80211_TESTMODE_STA_STATISTICS_RSSI, rQueryStaStatistics.ucRcpi);*/ -+ { -+ unsigned char __tmp = rQueryStaStatistics.ucRcpi; -+ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_RSSI, sizeof(unsigned char), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ -+ /*NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_PHY_MODE, rQueryStaStatistics.u4PhyMode);*/ -+ { -+ unsigned int __tmp = rQueryStaStatistics.u4PhyMode; -+ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_PHY_MODE, -+ sizeof(unsigned int), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ -+ /*NLA_PUT_U16(skb, NL80211_TESTMODE_STA_STATISTICS_TX_RATE, rQueryStaStatistics.u2LinkSpeed);*/ -+ { -+ unsigned short __tmp = rQueryStaStatistics.u2LinkSpeed; -+ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_TX_RATE, -+ sizeof(unsigned short), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ /*NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_FAIL_CNT, rQueryStaStatistics.u4TxFailCount);*/ -+ { -+ unsigned int __tmp = rQueryStaStatistics.u4TxFailCount; -+ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_FAIL_CNT, -+ sizeof(unsigned int), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ -+ /*NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_TIMEOUT_CNT, rQueryStaStatistics.u4TxLifeTimeoutCount);*/ -+ { -+ unsigned int __tmp = rQueryStaStatistics.u4TxLifeTimeoutCount; -+ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_TIMEOUT_CNT, -+ sizeof(unsigned int), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ -+ /*NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_AVG_AIR_TIME, rQueryStaStatistics.u4TxAverageAirTime);*/ -+ { -+ unsigned int __tmp = rQueryStaStatistics.u4TxAverageAirTime; -+ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_AVG_AIR_TIME, -+ sizeof(unsigned int), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ -+ /* Driver part link status */ -+ /*NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_TOTAL_CNT, rQueryStaStatistics.u4TxTotalCount);*/ -+ { -+ unsigned int __tmp = rQueryStaStatistics.u4TxTotalCount; -+ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_TOTAL_CNT, -+ sizeof(unsigned int), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ -+ /*NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_THRESHOLD_CNT, -+ rQueryStaStatistics.u4TxExceedThresholdCount);*/ -+ { -+ unsigned int __tmp = rQueryStaStatistics.u4TxExceedThresholdCount; -+ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_THRESHOLD_CNT, -+ sizeof(unsigned int), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ /*NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_AVG_PROCESS_TIME, -+ rQueryStaStatistics.u4TxAverageProcessTime);*/ -+ { -+ unsigned int __tmp = rQueryStaStatistics.u4TxAverageProcessTime; -+ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_AVG_PROCESS_TIME, -+ sizeof(unsigned int), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ -+ { -+ unsigned int __tmp = rQueryStaStatistics.u4TxMaxTime; -+ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_MAX_PROCESS_TIME, -+ sizeof(unsigned int), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ -+ -+ { -+ unsigned int __tmp = rQueryStaStatistics.u4TxAverageHifTime; -+ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_AVG_HIF_PROCESS_TIME, -+ sizeof(unsigned int), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ -+ { -+ unsigned int __tmp = rQueryStaStatistics.u4TxMaxHifTime; -+ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_MAX_HIF_PROCESS_TIME, -+ sizeof(unsigned int), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ -+ /* -+ * NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_ENQUEUE, rQueryStaStatistics.u4EnqueueCounter); -+ */ -+ { -+ unsigned int __tmp = rQueryStaStatistics.u4EnqueueCounter; -+ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_ENQUEUE, -+ sizeof(unsigned int), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ /* -+ * NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_DEQUEUE, rQueryStaStatistics.u4DequeueCounter); -+ */ -+ { -+ unsigned int __tmp = rQueryStaStatistics.u4DequeueCounter; -+ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_DEQUEUE, -+ sizeof(unsigned int), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ /* -+ * NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_STA_ENQUEUE, rQueryStaStatistics.u4EnqueueStaCounter); -+ */ -+ { -+ unsigned int __tmp = rQueryStaStatistics.u4EnqueueStaCounter; -+ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_STA_ENQUEUE, -+ sizeof(unsigned int), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ /* -+ * NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_STA_DEQUEUE, rQueryStaStatistics.u4DequeueStaCounter); -+ */ -+ { -+ unsigned int __tmp = rQueryStaStatistics.u4DequeueStaCounter; -+ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_STA_DEQUEUE, -+ sizeof(unsigned int), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ -+ /* -+ * NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_IRQ_ISR_CNT, rQueryStaStatistics.IsrCnt); -+ */ -+ { -+ unsigned int __tmp = rQueryStaStatistics.IsrCnt; -+ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_IRQ_ISR_CNT, -+ sizeof(unsigned int), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ /* -+ * NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_IRQ_ISR_PASS_CNT, rQueryStaStatistics.IsrPassCnt); -+ */ -+ { -+ unsigned int __tmp = rQueryStaStatistics.IsrPassCnt; -+ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_IRQ_ISR_PASS_CNT, -+ sizeof(unsigned int), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ /* -+ * NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_IRQ_TASK_CNT, rQueryStaStatistics.TaskIsrCnt); -+ */ -+ { -+ unsigned int __tmp = rQueryStaStatistics.TaskIsrCnt; -+ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_IRQ_TASK_CNT, -+ sizeof(unsigned int), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ -+ /* -+ * NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_IRQ_AB_CNT, rQueryStaStatistics.IsrAbnormalCnt); -+ */ -+ { -+ unsigned int __tmp = rQueryStaStatistics.IsrAbnormalCnt; -+ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_IRQ_AB_CNT, -+ sizeof(unsigned int), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ /* -+ * NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_IRQ_SW_CNT, rQueryStaStatistics.IsrSoftWareCnt); -+ */ -+ { -+ unsigned int __tmp = rQueryStaStatistics.IsrSoftWareCnt; -+ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_IRQ_SW_CNT, -+ sizeof(unsigned int), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ /* -+ * NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_IRQ_TX_CNT, rQueryStaStatistics.IsrTxCnt); -+ */ -+ { -+ unsigned int __tmp = rQueryStaStatistics.IsrTxCnt; -+ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_IRQ_TX_CNT, -+ sizeof(unsigned int), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ /* -+ *NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_IRQ_RX_CNT, rQueryStaStatistics.IsrRxCnt); -+ */ -+ { -+ unsigned int __tmp = rQueryStaStatistics.IsrRxCnt; -+ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_IRQ_RX_CNT, -+ sizeof(unsigned int), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ /* Network counter */ -+ /*NLA_PUT(skb, -+ NL80211_TESTMODE_STA_STATISTICS_TC_EMPTY_CNT_ARRAY, -+ sizeof(rQueryStaStatistics.au4TcResourceEmptyCount), rQueryStaStatistics.au4TcResourceEmptyCount);*/ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_TC_EMPTY_CNT_ARRAY, -+ sizeof(rQueryStaStatistics.au4TcResourceEmptyCount), &rQueryStaStatistics.au4TcResourceEmptyCount) < 0)) -+ goto nla_put_failure; -+ /* -+ NLA_PUT(skb, -+ NL80211_TESTMODE_STA_STATISTICS_NO_TC_ARRAY, -+ sizeof(rQueryStaStatistics.au4DequeueNoTcResource), rQueryStaStatistics.au4DequeueNoTcResource); -+ */ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_NO_TC_ARRAY, -+ sizeof(rQueryStaStatistics.au4DequeueNoTcResource), &rQueryStaStatistics.au4DequeueNoTcResource) < 0)) -+ goto nla_put_failure; -+ /* -+ NLA_PUT(skb, -+ NL80211_TESTMODE_STA_STATISTICS_RB_ARRAY, -+ sizeof(rQueryStaStatistics.au4TcResourceBackCount), rQueryStaStatistics.au4TcResourceBackCount); -+ */ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_RB_ARRAY, -+ sizeof(rQueryStaStatistics.au4TcResourceBackCount), &rQueryStaStatistics.au4TcResourceBackCount) < 0)) -+ goto nla_put_failure; -+ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_USED_BFCT_ARRAY, -+ sizeof(rQueryStaStatistics.au4TcResourceUsedCount), &rQueryStaStatistics.au4TcResourceUsedCount) < 0)) -+ goto nla_put_failure; -+ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_WANTED_BFCT_ARRAY, -+ sizeof(rQueryStaStatistics.au4TcResourceWantedCount), -+ &rQueryStaStatistics.au4TcResourceWantedCount) < 0)) -+ goto nla_put_failure; -+ -+ /* Sta queue length */ -+ /*NLA_PUT(skb, -+ NL80211_TESTMODE_STA_STATISTICS_TC_QUE_LEN_ARRAY, -+ sizeof(rQueryStaStatistics.au4TcQueLen), rQueryStaStatistics.au4TcQueLen);*/ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_TC_QUE_LEN_ARRAY, -+ sizeof(rQueryStaStatistics.au4TcQueLen), &rQueryStaStatistics.au4TcQueLen) < 0)) -+ goto nla_put_failure; -+ -+ -+ /* Global QM counter */ -+ /*NLA_PUT(skb, -+ NL80211_TESTMODE_STA_STATISTICS_TC_AVG_QUE_LEN_ARRAY, -+ sizeof(rQueryStaStatistics.au4TcAverageQueLen), rQueryStaStatistics.au4TcAverageQueLen);*/ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_TC_AVG_QUE_LEN_ARRAY, -+ sizeof(rQueryStaStatistics.au4TcAverageQueLen), &rQueryStaStatistics.au4TcAverageQueLen) < 0)) -+ goto nla_put_failure; -+ -+ /*NLA_PUT(skb, -+ NL80211_TESTMODE_STA_STATISTICS_TC_CUR_QUE_LEN_ARRAY, -+ sizeof(rQueryStaStatistics.au4TcCurrentQueLen), rQueryStaStatistics.au4TcCurrentQueLen);*/ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_TC_CUR_QUE_LEN_ARRAY, -+ sizeof(rQueryStaStatistics.au4TcCurrentQueLen), &rQueryStaStatistics.au4TcCurrentQueLen) < 0)) -+ goto nla_put_failure; -+ -+ -+ /* Reserved field */ -+ /*NLA_PUT(skb, -+ NL80211_TESTMODE_STA_STATISTICS_RESERVED_ARRAY, -+ sizeof(rQueryStaStatistics.au4Reserved), rQueryStaStatistics.au4Reserved);*/ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_RESERVED_ARRAY, -+ sizeof(rQueryStaStatistics.au4Reserved), &rQueryStaStatistics.au4Reserved) < 0)) -+ goto nla_put_failure; -+ -+ i4Status = cfg80211_testmode_reply(skb); -+ skb = NULL; -+ -+nla_put_failure: -+ if (skb != NULL) -+ kfree_skb(skb); -+ return i4Status; -+} -+ -+int -+mtk_cfg80211_testmode_get_link_detection(IN struct wiphy *wiphy, IN void *data, IN int len, IN P_GLUE_INFO_T prGlueInfo) -+{ -+ -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ INT_32 i4Status = -EINVAL; -+ UINT_32 u4BufLen; -+ -+ PARAM_802_11_STATISTICS_STRUCT_T rStatistics; -+ struct sk_buff *skb; -+ -+ ASSERT(wiphy); -+ ASSERT(prGlueInfo); -+ -+ skb = cfg80211_testmode_alloc_reply_skb(wiphy, sizeof(PARAM_GET_STA_STA_STATISTICS) + 1); -+ -+ if (!skb) { -+ DBGLOG(QM, TRACE, "%s allocate skb failed:%x\n", __func__, rStatus); -+ return -ENOMEM; -+ } -+ -+ kalMemZero(&rStatistics, sizeof(rStatistics)); -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidQueryStatistics, -+ &rStatistics, sizeof(rStatistics), TRUE, TRUE, TRUE, FALSE, &u4BufLen); -+ -+ /*NLA_PUT_U8(skb, NL80211_TESTMODE_STA_STATISTICS_INVALID, 0);*/ -+ { -+ unsigned char __tmp = 0; -+ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_INVALID, sizeof(unsigned char), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ -+ /*NLA_PUT_U64(skb, NL80211_TESTMODE_LINK_TX_FAIL_CNT, rStatistics.rFailedCount.QuadPart);*/ -+ { -+ u64 __tmp = rStatistics.rFailedCount.QuadPart; -+ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_LINK_TX_FAIL_CNT, -+ sizeof(u64), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ -+ /*NLA_PUT_U64(skb, NL80211_TESTMODE_LINK_TX_RETRY_CNT, rStatistics.rRetryCount.QuadPart);*/ -+ { -+ u64 __tmp = rStatistics.rFailedCount.QuadPart; -+ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_LINK_TX_RETRY_CNT, -+ sizeof(u64), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ -+ /*NLA_PUT_U64(skb, NL80211_TESTMODE_LINK_TX_MULTI_RETRY_CNT, rStatistics.rMultipleRetryCount.QuadPart);*/ -+ { -+ u64 __tmp = rStatistics.rMultipleRetryCount.QuadPart; -+ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_LINK_TX_MULTI_RETRY_CNT, -+ sizeof(u64), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ -+ /*NLA_PUT_U64(skb, NL80211_TESTMODE_LINK_ACK_FAIL_CNT, rStatistics.rACKFailureCount.QuadPart);*/ -+ { -+ u64 __tmp = rStatistics.rACKFailureCount.QuadPart; -+ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_LINK_ACK_FAIL_CNT, -+ sizeof(u64), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ -+ /*NLA_PUT_U64(skb, NL80211_TESTMODE_LINK_FCS_ERR_CNT, rStatistics.rFCSErrorCount.QuadPart);*/ -+ { -+ u64 __tmp = rStatistics.rFCSErrorCount.QuadPart; -+ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_LINK_FCS_ERR_CNT, -+ sizeof(u64), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ -+ -+ i4Status = cfg80211_testmode_reply(skb); -+ skb = NULL; -+ -+nla_put_failure: -+ if (skb != NULL) -+ kfree_skb(skb); -+ return i4Status; -+} -+ -+int mtk_cfg80211_testmode_sw_cmd(IN struct wiphy *wiphy, IN void *data, IN int len) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ P_NL80211_DRIVER_SW_CMD_PARAMS prParams = (P_NL80211_DRIVER_SW_CMD_PARAMS) NULL; -+ WLAN_STATUS rstatus = WLAN_STATUS_SUCCESS; -+ int fgIsValid = 0; -+ UINT_32 u4SetInfoLen = 0; -+ -+ ASSERT(wiphy); -+ -+ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); -+ -+ DBGLOG(REQ, TRACE, "--> %s()\n", __func__); -+ -+ if (data && len) -+ prParams = (P_NL80211_DRIVER_SW_CMD_PARAMS) data; -+ -+ if (prParams) { -+ if (prParams->set == 1) { -+ rstatus = kalIoctl(prGlueInfo, -+ (PFN_OID_HANDLER_FUNC) wlanoidSetSwCtrlWrite, -+ &prParams->adr, (UINT_32) 8, FALSE, FALSE, TRUE, FALSE, &u4SetInfoLen); -+ } -+ } -+ -+ if (WLAN_STATUS_SUCCESS != rstatus) -+ fgIsValid = -EFAULT; -+ -+ return fgIsValid; -+} -+ -+#if CFG_SUPPORT_HOTSPOT_2_0 -+int mtk_cfg80211_testmode_hs20_cmd(IN struct wiphy *wiphy, IN void *data, IN int len) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ struct wpa_driver_hs20_data_s *prParams = NULL; -+ WLAN_STATUS rstatus = WLAN_STATUS_SUCCESS; -+ int fgIsValid = 0; -+ UINT_32 u4SetInfoLen = 0; -+ -+ ASSERT(wiphy); -+ -+ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); -+ -+ DBGLOG(REQ, TRACE, "--> %s()\n", __func__); -+ -+ if (data && len) { -+ prParams = (struct wpa_driver_hs20_data_s *)data; -+ -+ DBGLOG(REQ, TRACE, "[%s] Cmd Type (%d)\n", __func__, prParams->CmdType); -+ } -+ -+ if (prParams) { -+ int i; -+ -+ switch (prParams->CmdType) { -+ case HS20_CMD_ID_SET_BSSID_POOL: -+ DBGLOG(REQ, TRACE, "fgBssidPoolIsEnable=%d, ucNumBssidPool=%d\n", -+ prParams->hs20_set_bssid_pool.fgBssidPoolIsEnable, -+ prParams->hs20_set_bssid_pool.ucNumBssidPool); -+ for (i = 0; i < prParams->hs20_set_bssid_pool.ucNumBssidPool; i++) { -+ DBGLOG(REQ, TRACE, "[%d][ %pM ]\n", i, -+ (prParams->hs20_set_bssid_pool.arBssidPool[i])); -+ } -+ rstatus = kalIoctl(prGlueInfo, -+ (PFN_OID_HANDLER_FUNC) wlanoidSetHS20BssidPool, -+ &prParams->hs20_set_bssid_pool, -+ sizeof(struct param_hs20_set_bssid_pool), -+ FALSE, FALSE, TRUE, FALSE, &u4SetInfoLen); -+ break; -+ default: -+ DBGLOG(REQ, TRACE, "[%s] Unknown Cmd Type (%d)\n", __func__, prParams->CmdType); -+ rstatus = WLAN_STATUS_FAILURE; -+ -+ } -+ -+ } -+ -+ if (WLAN_STATUS_SUCCESS != rstatus) -+ fgIsValid = -EFAULT; -+ -+ return fgIsValid; -+} -+ -+#endif -+int -+mtk_cfg80211_testmode_set_poorlink_param(IN struct wiphy *wiphy, IN void *data, IN int len, IN P_GLUE_INFO_T prGlueInfo) -+{ -+ int fgIsValid = 0; -+ P_NL80211_DRIVER_POORLINK_PARAMS prParams = NULL; -+ -+ ASSERT(wiphy); -+ ASSERT(prGlueInfo); -+ -+ if (data && len) { -+ prParams = (P_NL80211_DRIVER_POORLINK_PARAMS) data; -+ } else { -+ DBGLOG(REQ, ERROR, "mtk_cfg80211_testmode_set_poorlink_param, data is NULL\n"); -+ return -EINVAL; -+ } -+ if (prParams->ucLinkSpeed) -+ prGlueInfo->u4LinkspeedThreshold = prParams->ucLinkSpeed * 10; -+ if (prParams->cRssi) -+ prGlueInfo->i4RssiThreshold = prParams->cRssi; -+ if (!prGlueInfo->fgPoorlinkValid) -+ prGlueInfo->fgPoorlinkValid = 1; -+#if 0 -+ DBGLOG(REQ, TRACE, "poorlink set param valid(%d)rssi(%d)linkspeed(%d)\n", -+ prGlueInfo->fgPoorlinkValid, prGlueInfo->i4RssiThreshold, prGlueInfo->u4LinkspeedThreshold); -+#endif -+ -+ return fgIsValid; -+ -+} -+ -+int mtk_cfg80211_testmode_cmd(IN struct wiphy *wiphy, IN struct wireless_dev *wdev, IN void *data, IN int len) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ P_NL80211_DRIVER_TEST_MODE_PARAMS prParams = (P_NL80211_DRIVER_TEST_MODE_PARAMS) NULL; -+ INT_32 i4Status = -EINVAL; -+#if CFG_SUPPORT_HOTSPOT_2_0 -+ BOOLEAN fgIsValid = 0; -+#endif -+ -+ ASSERT(wiphy); -+ ASSERT(wdev); -+ -+ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); -+ -+ if (data && len) { -+ prParams = (P_NL80211_DRIVER_TEST_MODE_PARAMS) data; -+ } else { -+ DBGLOG(REQ, ERROR, "mtk_cfg80211_testmode_cmd, data is NULL\n"); -+ return i4Status; -+ } -+ -+ /* Clear the version byte */ -+ prParams->index = prParams->index & ~BITS(24, 31); -+ -+ if (prParams) { -+ switch (prParams->index) { -+ case TESTMODE_CMD_ID_SW_CMD: /* SW cmd */ -+ i4Status = mtk_cfg80211_testmode_sw_cmd(wiphy, data, len); -+ break; -+ case TESTMODE_CMD_ID_WAPI: /* WAPI */ -+#if CFG_SUPPORT_WAPI -+ i4Status = mtk_cfg80211_testmode_set_key_ext(wiphy, data, len); -+#endif -+ break; -+ case TESTMODE_CMD_ID_SUSPEND: -+ { -+ P_NL80211_DRIVER_SUSPEND_PARAMS prParams = (P_NL80211_DRIVER_SUSPEND_PARAMS) data; -+ -+ if (prParams->suspend == 1) { -+ wlanHandleSystemSuspend(); -+ if (prGlueInfo->prAdapter->fgIsP2PRegistered) -+ p2pHandleSystemSuspend(); -+ i4Status = 0; -+ } else if (prParams->suspend == 0) { -+ wlanHandleSystemResume(); -+ if (prGlueInfo->prAdapter->fgIsP2PRegistered) -+ p2pHandleSystemResume(); -+ i4Status = 0; -+ } -+ break; -+ } -+ case TESTMODE_CMD_ID_STATISTICS: -+ i4Status = mtk_cfg80211_testmode_get_sta_statistics(wiphy, data, len, prGlueInfo); -+ break; -+ case TESTMODE_CMD_ID_LINK_DETECT: -+ i4Status = mtk_cfg80211_testmode_get_link_detection(wiphy, data, len, prGlueInfo); -+ break; -+ case TESTMODE_CMD_ID_POORLINK: -+ i4Status = mtk_cfg80211_testmode_set_poorlink_param(wiphy, data, len, prGlueInfo); -+ break; -+ -+#if CFG_SUPPORT_HOTSPOT_2_0 -+ case TESTMODE_CMD_ID_HS20: -+ if (mtk_cfg80211_testmode_hs20_cmd(wiphy, data, len)) -+ fgIsValid = TRUE; -+ break; -+#endif -+ default: -+ i4Status = -EINVAL; -+ break; -+ } -+ } -+ -+ return i4Status; -+} -+ -+int mtk_cfg80211_testmode_get_scan_done(IN struct wiphy *wiphy, IN void *data, IN int len, IN P_GLUE_INFO_T prGlueInfo) -+{ -+#define NL80211_TESTMODE_P2P_SCANDONE_INVALID 0 -+#define NL80211_TESTMODE_P2P_SCANDONE_STATUS 1 -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ INT_32 i4Status = -EINVAL, READY_TO_BEAM = 0; -+ -+/* P_NL80211_DRIVER_GET_STA_STATISTICS_PARAMS prParams = NULL; */ -+ struct sk_buff *skb; -+ -+ ASSERT(wiphy); -+ ASSERT(prGlueInfo); -+ -+ skb = cfg80211_testmode_alloc_reply_skb(wiphy, sizeof(UINT_32)); -+ READY_TO_BEAM = -+ (UINT_32) (prGlueInfo->prAdapter->rWifiVar.prP2pFsmInfo->rScanReqInfo. -+ fgIsGOInitialDone) & -+ (!prGlueInfo->prAdapter->rWifiVar.prP2pFsmInfo->rScanReqInfo.fgIsScanRequest); -+ DBGLOG(QM, TRACE, -+ "NFC:GOInitialDone[%d] and P2PScanning[%d]\n", -+ prGlueInfo->prAdapter->rWifiVar.prP2pFsmInfo->rScanReqInfo.fgIsGOInitialDone, -+ prGlueInfo->prAdapter->rWifiVar.prP2pFsmInfo->rScanReqInfo.fgIsScanRequest); -+ -+ if (!skb) { -+ DBGLOG(QM, TRACE, "%s allocate skb failed:%x\n", __func__, rStatus); -+ return -ENOMEM; -+ } -+ -+ /*NLA_PUT_U8(skb, NL80211_TESTMODE_P2P_SCANDONE_INVALID, 0);*/ -+ { -+ unsigned char __tmp = 0; -+ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_P2P_SCANDONE_INVALID, sizeof(unsigned char), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ /*NLA_PUT_U32(skb, NL80211_TESTMODE_P2P_SCANDONE_STATUS, READY_TO_BEAM);*/ -+ { -+ unsigned int __tmp = READY_TO_BEAM; -+ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_P2P_SCANDONE_STATUS, sizeof(unsigned int), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ -+ -+ i4Status = cfg80211_testmode_reply(skb); -+ skb = NULL; -+ -+nla_put_failure: -+ if (skb != NULL) -+ kfree_skb(skb); -+ return i4Status; -+} -+ -+#if CFG_AUTO_CHANNEL_SEL_SUPPORT -+int -+mtk_cfg80211_testmode_get_lte_channel(IN struct wiphy *wiphy, IN void *data, IN int len, IN P_GLUE_INFO_T prGlueInfo) -+{ -+#define MAXMUN_2_4G_CHA_NUM 14 -+#define CHN_DIRTY_WEIGHT_UPPERBOUND 4 -+ -+ BOOLEAN fgIsReady = FALSE, fgIsFistRecord = TRUE; -+ BOOLEAN fgIsPureAP, fgIsLteSafeChn = FALSE; -+ -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ UINT_8 ucIdx = 0, ucMax_24G_Chn_List = 11, ucDefaultIdx = 0, ucArrayIdx = 0; -+ UINT_16 u2APNumScore = 0, u2UpThreshold = 0, u2LowThreshold = 0, ucInnerIdx = 0; -+ INT_32 i4Status = -EINVAL; -+ UINT_32 u4BufLen, u4LteSafeChnBitMask_2_4G = 0; -+ UINT32 AcsChnReport[4]; -+ /*RF_CHANNEL_INFO_T aucChannelList[MAXMUN_2_4G_CHA_NUM];*/ -+ -+ struct sk_buff *skb; -+ -+ /*PARAM_GET_CHN_LOAD rQueryLTEChn;*/ -+ P_PARAM_GET_CHN_LOAD prQueryLTEChn; -+ PARAM_PREFER_CHN_INFO rPreferChannels[2], ar2_4G_ChannelLoadingWeightScore[MAXMUN_2_4G_CHA_NUM]; -+ P_PARAM_CHN_LOAD_INFO prChnLoad; -+ P_PARAM_GET_CHN_LOAD prGetChnLoad; -+ -+ P_DOMAIN_INFO_ENTRY prDomainInfo; -+ -+/* -+ P_PARAM_GET_CHN_LOAD prParams = NULL; -+*/ -+ ASSERT(wiphy); -+ ASSERT(prGlueInfo); -+ -+ kalMemZero(rPreferChannels, sizeof(rPreferChannels)); -+ fgIsPureAP = prGlueInfo->prAdapter->rWifiVar.prP2pFsmInfo->fgIsApMode; -+#if 0 -+ if (data && len) -+ prParams = (P_NL80211_DRIVER_GET_LTE_PARAMS) data; -+#endif -+ skb = cfg80211_testmode_alloc_reply_skb(wiphy, sizeof(AcsChnReport) + sizeof(UINT8) + 1); -+ if (!skb) { -+ DBGLOG(QM, TRACE, "%s allocate skb failed:%x\n", __func__, rStatus); -+ return -ENOMEM; -+ } -+ -+ DBGLOG(P2P, INFO, "[Auto Channel]Get LTE Channels\n"); -+ prQueryLTEChn = kalMemAlloc(sizeof(PARAM_GET_CHN_LOAD), VIR_MEM_TYPE); -+ if (prQueryLTEChn == NULL) { -+ DBGLOG(QM, TRACE, "alloc QueryLTEChn fail\n"); -+ kalMemFree(skb, VIR_MEM_TYPE, sizeof(struct sk_buff)); -+ return -ENOMEM; -+ } -+ kalMemZero(prQueryLTEChn, sizeof(PARAM_GET_CHN_LOAD)); -+ -+ /* Query LTE Safe Channels */ -+ prQueryLTEChn->rLteSafeChnList.au4SafeChannelBitmask[NL80211_TESTMODE_AVAILABLE_CHAN_2G_BASE_1 - 1] -+ = 0xFFFFFFFF; -+ -+ prQueryLTEChn->rLteSafeChnList.au4SafeChannelBitmask[NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_34 - 1] -+ = 0xFFFFFFFF; -+ -+ prQueryLTEChn->rLteSafeChnList.au4SafeChannelBitmask[NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_149 - 1] -+ = 0xFFFFFFFF; -+ -+ prQueryLTEChn->rLteSafeChnList.au4SafeChannelBitmask[NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_184 - 1] = -+ 0xFFFFFFFF; -+ -+ rStatus = kalIoctl(prGlueInfo, wlanoidQueryACSChannelList, prQueryLTEChn, sizeof(PARAM_GET_CHN_LOAD), -+ TRUE, FALSE, TRUE, TRUE, &u4BufLen); -+#if 0 -+ if (fgIsPureAP) { -+ -+ AcsChnRepot[NL80211_TESTMODE_AVAILABLE_CHAN_2G_BASE_1 - 1] = 0x20; /* Channel 6 */ -+ } else -+#endif -+ { -+ fgIsReady = prGlueInfo->prAdapter->rWifiVar.rChnLoadInfo.fgDataReadyBit; -+ rPreferChannels[0].u2APNum = 0xFFFF; -+ rPreferChannels[1].u2APNum = 0xFFFF; -+ -+ /* 4 In LTE Mode, Hotspot pick up channels from ch4. */ -+ ucDefaultIdx = 0; -+ /* -+ if (fgIsPureAP) { -+ ucDefaultIdx=3; //SKIP LTE Channels 1~3 -+ } -+ */ -+ -+ /* 4 Get the Maximun channel List in 2.4G Bands */ -+ -+ prDomainInfo = rlmDomainGetDomainInfo(prGlueInfo->prAdapter); -+ ASSERT(prDomainInfo); -+ -+ /* 4 ToDo: Enable Step 2 only if we could get Country Code from framework */ -+ /* 4 2. Get current domain channel list */ -+ -+#if 0 -+ rlmDomainGetChnlList(prGlueInfo->prAdapter, -+ BAND_2G4, MAXMUN_2_4G_CHA_NUM, &ucMax_24G_Chn_List, aucChannelList); -+#endif -+ -+ prGetChnLoad = (P_PARAM_GET_CHN_LOAD) &(prGlueInfo->prAdapter->rWifiVar.rChnLoadInfo); -+ for (ucIdx = 0; ucIdx < ucMax_24G_Chn_List; ucIdx++) { -+ DBGLOG(P2P, INFO, -+ "[Auto Channel] ch[%d]=%d\n", ucIdx, -+ prGetChnLoad->rEachChnLoad[ucIdx + ucInnerIdx].u2APNum); -+ } -+ -+ /*Calculate Each Channel Direty Score */ -+ for (ucIdx = ucDefaultIdx; ucIdx < ucMax_24G_Chn_List; ucIdx++) { -+ -+#if 1 -+ u2APNumScore = prGetChnLoad->rEachChnLoad[ucIdx].u2APNum * CHN_DIRTY_WEIGHT_UPPERBOUND; -+ u2UpThreshold = u2LowThreshold = 3; -+ -+ if (ucIdx < 3) { -+ u2UpThreshold = ucIdx; -+ u2LowThreshold = 3; -+ } else if (ucIdx >= (ucMax_24G_Chn_List - 3)) { -+ u2UpThreshold = 3; -+ u2LowThreshold = ucMax_24G_Chn_List - (ucIdx + 1); -+ -+ } -+ -+ /*Calculate Lower Channel Dirty Score */ -+ for (ucInnerIdx = 0; ucInnerIdx < u2LowThreshold; ucInnerIdx++) { -+ ucArrayIdx = ucIdx + ucInnerIdx + 1; -+ if (ucArrayIdx < MAX_AUTO_CHAL_NUM) { -+ u2APNumScore += -+ (prGetChnLoad->rEachChnLoad[ucArrayIdx].u2APNum * -+ (CHN_DIRTY_WEIGHT_UPPERBOUND - 1 - ucInnerIdx)); -+ } -+ } -+ -+ /*Calculate Upper Channel Dirty Score */ -+ for (ucInnerIdx = 0; ucInnerIdx < u2UpThreshold; ucInnerIdx++) { -+ ucArrayIdx = ucIdx - ucInnerIdx - 1; -+ if (ucArrayIdx < MAX_AUTO_CHAL_NUM) { -+ u2APNumScore += -+ (prGetChnLoad->rEachChnLoad[ucArrayIdx].u2APNum * -+ (CHN_DIRTY_WEIGHT_UPPERBOUND - 1 - ucInnerIdx)); -+ } -+ } -+ -+ ar2_4G_ChannelLoadingWeightScore[ucIdx].u2APNum = u2APNumScore; -+ -+ DBGLOG(P2P, INFO, "[Auto Channel]chn=%d score=%d\n", ucIdx, u2APNumScore); -+#else -+ if (ucIdx == 0) { -+ /* ar2_4G_ChannelLoadingWeightScore[ucIdx].u2APNum = -+ (prGetChnLoad->rEachChnLoad[ucIdx].u2APNum + -+ prGetChnLoad->rEachChnLoad[ucIdx+1].u2APNum*0.75); */ -+ u2APNumScore = (prGetChnLoad->rEachChnLoad[ucIdx].u2APNum + ((UINT_16) -+ ((3 * -+ (prGetChnLoad-> -+ rEachChnLoad[ucIdx + -+ 1]. -+ u2APNum + -+ prGetChnLoad-> -+ rEachChnLoad[ucIdx + -+ 2]. -+ u2APNum)) / 4))); -+ -+ ar2_4G_ChannelLoadingWeightScore[ucIdx].u2APNum = u2APNumScore; -+ DBGLOG(P2P, INFO, -+ "[Auto Channel]ucIdx=%d score=%d=%d+0.75*%d\n", ucIdx, -+ ar2_4G_ChannelLoadingWeightScore[ucIdx].u2APNum, -+ prGetChnLoad->rEachChnLoad[ucIdx].u2APNum, -+ prGetChnLoad->rEachChnLoad[ucIdx + 1].u2APNum)); -+ } -+ if ((ucIdx > 0) && (ucIdx < (MAXMUN_2_4G_CHA_NUM - 1))) { -+ u2APNumScore = (prGetChnLoad->rEachChnLoad[ucIdx].u2APNum + ((UINT_16) -+ ((3 * -+ (prGetChnLoad-> -+ rEachChnLoad[ucIdx + -+ 1]. -+ u2APNum + -+ prGetChnLoad-> -+ rEachChnLoad[ucIdx - -+ 1]. -+ u2APNum)) / 4))); -+ -+ ar2_4G_ChannelLoadingWeightScore[ucIdx].u2APNum = u2APNumScore; -+ DBGLOG(P2P, INFO, -+ "[Auto Channel]ucIdx=%d score=%d=%d+0.75*%d+0.75*%d\n", ucIdx, -+ ar2_4G_ChannelLoadingWeightScore[ucIdx].u2APNum, -+ prGetChnLoad->rEachChnLoad[ucIdx].u2APNum, -+ prGetChnLoad->rEachChnLoad[ucIdx + 1].u2APNum, -+ prGetChnLoad->rEachChnLoad[ucIdx - 1].u2APNum)); -+ } -+ -+ if (ucIdx == (MAXMUN_2_4G_CHA_NUM - 1)) { -+ u2APNumScore = (prGetChnLoad->rEachChnLoad[ucIdx].u2APNum + -+ ((UINT_16) ((3 * prGetChnLoad->rEachChnLoad[ucIdx - 1].u2APNum) / 4))); -+ -+ ar2_4G_ChannelLoadingWeightScore[ucIdx].u2APNum = u2APNumScore; -+ DBGLOG(P2P, INFO, -+ "[Auto Channel]ucIdx=%d score=%d=%d+0.75*%d\n", ucIdx, -+ ar2_4G_ChannelLoadingWeightScore[ucIdx].u2APNum, -+ prGetChnLoad->rEachChnLoad[ucIdx].u2APNum, -+ prGetChnLoad->rEachChnLoad[ucIdx - 1].u2APNum)); -+ } -+#endif -+ -+ } -+ -+ u4LteSafeChnBitMask_2_4G = -+ prQueryLTEChn->rLteSafeChnList.au4SafeChannelBitmask[NL80211_TESTMODE_AVAILABLE_CHAN_2G_BASE_1 - 1]; -+ -+ /*Find out the best channel */ -+ for (ucIdx = ucDefaultIdx; ucIdx < ucMax_24G_Chn_List; ucIdx++) { -+ /* 4 Skip LTE Unsafe Channel */ -+ fgIsLteSafeChn = ((u4LteSafeChnBitMask_2_4G & BIT(ucIdx + 1)) >> ucIdx); -+ if (!fgIsLteSafeChn) -+ continue; -+ -+ prChnLoad = -+ (P_PARAM_CHN_LOAD_INFO) &(prGlueInfo->prAdapter->rWifiVar. -+ rChnLoadInfo.rEachChnLoad[ucIdx]); -+ if (rPreferChannels[0].u2APNum >= ar2_4G_ChannelLoadingWeightScore[ucIdx].u2APNum) { -+ rPreferChannels[1].ucChannel = rPreferChannels[0].ucChannel; -+ rPreferChannels[1].u2APNum = rPreferChannels[0].u2APNum; -+ -+ rPreferChannels[0].ucChannel = ucIdx; -+ rPreferChannels[0].u2APNum = ar2_4G_ChannelLoadingWeightScore[ucIdx].u2APNum; -+ } else { -+ if (rPreferChannels[1].u2APNum >= ar2_4G_ChannelLoadingWeightScore[ucIdx].u2APNum -+ || fgIsFistRecord == 1) { -+ fgIsFistRecord = FALSE; -+ rPreferChannels[1].ucChannel = ucIdx; -+ rPreferChannels[1].u2APNum = ar2_4G_ChannelLoadingWeightScore[ucIdx].u2APNum; -+ } -+ } -+ } -+ /* AcsChnRepot[NL80211_TESTMODE_AVAILABLE_CHAN_2G_BASE_1-1] = -+ BITS((rQueryLTEChn.rLteSafeChnList.ucChannelLow-1),(rQueryLTEChn.rLteSafeChnList.ucChannelHigh-1)); */ -+ AcsChnReport[NL80211_TESTMODE_AVAILABLE_CHAN_2G_BASE_1 - 1] = fgIsReady ? BIT(31) : 0; -+ AcsChnReport[NL80211_TESTMODE_AVAILABLE_CHAN_2G_BASE_1 - 1] |= BIT(rPreferChannels[0].ucChannel); -+ } -+ -+ /* ToDo: Support 5G Channel Selection */ -+ AcsChnReport[NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_34 - 1] = 0x11223344; -+ AcsChnReport[NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_149 - 1] = 0x55667788; -+ AcsChnReport[NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_184 - 1] = 0x99AABBCC; -+ -+ /*NLA_PUT_U8(skb, NL80211_TESTMODE_AVAILABLE_CHAN_INVALID, 0);*/ -+ { -+ unsigned char __tmp = 0; -+ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_AVAILABLE_CHAN_INVALID, sizeof(unsigned char), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ -+ /*NLA_PUT_U32(skb, NL80211_TESTMODE_AVAILABLE_CHAN_2G_BASE_1, -+ AcsChnReport[NL80211_TESTMODE_AVAILABLE_CHAN_2G_BASE_1 - 1]);*/ -+ { -+ unsigned int __tmp = AcsChnReport[NL80211_TESTMODE_AVAILABLE_CHAN_2G_BASE_1 - 1]; -+ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_AVAILABLE_CHAN_2G_BASE_1, -+ sizeof(unsigned int), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ -+ /*NLA_PUT_U32(skb, NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_34, -+ AcsChnReport[NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_34 - 1]);*/ -+ { -+ unsigned int __tmp = AcsChnReport[NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_34 - 1]; -+ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_34, -+ sizeof(unsigned int), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ -+ /*NLA_PUT_U32(skb, NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_149, -+ AcsChnReport[NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_149 - 1]);*/ -+ { -+ unsigned int __tmp = AcsChnReport[NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_149 - 1]; -+ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_149, -+ sizeof(unsigned int), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ -+ -+ /*NLA_PUT_U32(skb, NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_184, -+ AcsChnReport[NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_184 - 1]);*/ -+ { -+ unsigned int __tmp = AcsChnReport[NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_184 - 1]; -+ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_184, -+ sizeof(unsigned int), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ -+ DBGLOG(P2P, INFO, -+ "[Auto Channel]Relpy AcsChanInfo[%x:%x:%x:%x]\n", AcsChnReport[0], AcsChnReport[1], AcsChnReport[2], -+ AcsChnReport[3]); -+ -+ i4Status = cfg80211_testmode_reply(skb); -+ /*need confirm cfg80211_testmode_reply will free skb*/ -+ skb = NULL; -+ /*kalMemFree(prQueryLTEChn, VIR_MEM_TYPE, sizeof(PARAM_GET_CHN_LOAD));*/ -+ -+nla_put_failure: -+ kalMemFree(prQueryLTEChn, VIR_MEM_TYPE, sizeof(PARAM_GET_CHN_LOAD)); -+ if (skb != NULL) -+ kfree_skb(skb); -+ return i4Status; -+ -+} -+#endif -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * @brief cfg80211 suspend callback, will be invoked in wiphy_suspend -+ * -+ * @param wiphy: pointer to wiphy -+ * wow: pointer to cfg80211_wowlan -+ * -+ * @retval 0: successful -+ * others: failure -+ */ -+/*----------------------------------------------------------------------------*/ -+int mtk_cfg80211_suspend(struct wiphy *wiphy, struct cfg80211_wowlan *wow) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ -+ if (kalHaltTryLock()) -+ return 0; -+ -+ if (kalIsHalted() || !wiphy) -+ goto end; -+ -+ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); -+ -+ set_bit(SUSPEND_FLAG_FOR_WAKEUP_REASON, &prGlueInfo->prAdapter->ulSuspendFlag); -+ set_bit(SUSPEND_FLAG_CLEAR_WHEN_RESUME, &prGlueInfo->prAdapter->ulSuspendFlag); -+end: -+ kalHaltUnlock(); -+ return 0; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * @brief cfg80211 resume callback, will be invoked in wiphy_resume. -+ * -+ * @param wiphy: pointer to wiphy -+ * -+ * @retval 0: successful -+ * others: failure -+ */ -+/*----------------------------------------------------------------------------*/ -+int mtk_cfg80211_resume(struct wiphy *wiphy) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ P_BSS_DESC_T *pprBssDesc = NULL; -+ P_ADAPTER_T prAdapter = NULL; -+ UINT_8 i = 0; -+ -+ if (kalHaltTryLock()) -+ return 0; -+ -+ if (kalIsHalted() || !wiphy) -+ goto end; -+ -+ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); -+ prAdapter = prGlueInfo->prAdapter; -+ clear_bit(SUSPEND_FLAG_CLEAR_WHEN_RESUME, &prAdapter->ulSuspendFlag); -+ pprBssDesc = &prAdapter->rWifiVar.rScanInfo.rNloParam.aprPendingBssDescToInd[0]; -+ for (; i < SCN_SSID_MATCH_MAX_NUM; i++) { -+ if (pprBssDesc[i] == NULL) -+ break; -+ if (pprBssDesc[i]->u2RawLength == 0) -+ continue; -+ kalIndicateBssInfo(prGlueInfo, -+ (PUINT_8) pprBssDesc[i]->aucRawBuf, -+ pprBssDesc[i]->u2RawLength, -+ pprBssDesc[i]->ucChannelNum, -+ RCPI_TO_dBm(pprBssDesc[i]->ucRCPI)); -+ } -+ DBGLOG(SCN, INFO, "pending %d sched scan results\n", i); -+ if (i > 0) -+ kalMemZero(&pprBssDesc[0], i * sizeof(P_BSS_DESC_T)); -+end: -+ kalHaltUnlock(); -+ return 0; -+} -+ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_init.c b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_init.c -new file mode 100644 -index 000000000000..abe366585d05 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_init.c -@@ -0,0 +1,3501 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -+ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux/gl_init.c#7 -+*/ -+ -+/*! \file gl_init.c -+ \brief Main routines of Linux driver -+ -+ This file contains the main routines of Linux driver for MediaTek Inc. 802.11 -+ Wireless LAN Adapters. -+*/ -+ -+/* -+** Log: gl_init.c -+** -+** 09 03 2013 cp.wu -+** add path for reassociation -+ * -+ * 07 17 2012 yuche.tsai -+ * NULL -+ * Fix compile error. -+ * -+ * 07 17 2012 yuche.tsai -+ * NULL -+ * Fix compile error for JB. -+ * -+ * 07 17 2012 yuche.tsai -+ * NULL -+ * Let netdev bring up. -+ * -+ * 07 17 2012 yuche.tsai -+ * NULL -+ * Compile no error before trial run. -+ * -+ * 06 13 2012 yuche.tsai -+ * NULL -+ * Update maintrunk driver. -+ * Add support for driver compose assoc request frame. -+ * -+ * 05 25 2012 yuche.tsai -+ * NULL -+ * Fix reset KE issue. -+ * -+ * 05 11 2012 cp.wu -+ * [WCXRP00001237] [MT6620 Wi-Fi][Driver] Show MAC address and MAC address source for ACS's convenience -+ * show MAC address & source while initiliazation -+ * -+ * 03 02 2012 terry.wu -+ * NULL -+ * EXPORT_SYMBOL(rsnParseCheckForWFAInfoElem);. -+ * -+ * 03 02 2012 terry.wu -+ * NULL -+ * Snc CFG80211 modification for ICS migration from branch 2.2. -+ * -+ * 03 02 2012 terry.wu -+ * NULL -+ * Sync CFG80211 modification from branch 2,2. -+ * -+ * 03 02 2012 terry.wu -+ * NULL -+ * Enable CFG80211 Support. -+ * -+ * 12 22 2011 george.huang -+ * [WCXRP00000905] [MT6628 Wi-Fi][FW] Code refinement for ROM/ RAM module dependency -+ * using global variable instead of stack for setting wlanoidSetNetworkAddress(), due to buffer may be released before -+ * TX thread handling -+ * -+ * 11 18 2011 yuche.tsai -+ * NULL -+ * CONFIG P2P support RSSI query, default turned off. -+ * -+ * 11 14 2011 yuche.tsai -+ * [WCXRP00001107] [Volunteer Patch][Driver] Large Network Type index assert in FW issue. -+ * Fix large network type index assert in FW issue. -+ * -+ * 11 14 2011 cm.chang -+ * NULL -+ * Fix compiling warning -+ * -+ * 11 11 2011 yuche.tsai -+ * NULL -+ * Fix work thread cancel issue. -+ * -+ * 11 10 2011 cp.wu -+ * [WCXRP00001098] [MT6620 Wi-Fi][Driver] Replace printk by DBG LOG macros in linux porting layer -+ * 1. eliminaite direct calls to printk in porting layer. -+ * 2. replaced by DBGLOG, which would be XLOG on ALPS platforms. -+ * -+ * 10 06 2011 eddie.chen -+ * [WCXRP00001027] [MT6628 Wi-Fi][Firmware/Driver] Tx fragmentation -+ * Add rlmDomainGetChnlList symbol. -+ * -+ * 09 22 2011 cm.chang -+ * NULL -+ * Safer writng stype to avoid unitialized regitry structure -+ * -+ * 09 21 2011 cm.chang -+ * [WCXRP00000969] [MT6620 Wi-Fi][Driver][FW] Channel list for 5G band based on country code -+ * Avoid possible structure alignment problem -+ * -+ * 09 20 2011 chinglan.wang -+ * [WCXRP00000989] [WiFi Direct] [Driver] Add a new io control API to start the formation for the sigma test. -+ * . -+ * -+ * 09 08 2011 cm.chang -+ * [WCXRP00000969] [MT6620 Wi-Fi][Driver][FW] Channel list for 5G band based on country code -+ * Use new fields ucChannelListMap and ucChannelListIndex in NVRAM -+ * -+ * 08 31 2011 cm.chang -+ * [WCXRP00000969] [MT6620 Wi-Fi][Driver][FW] Channel list for 5G band based on country code -+ * . -+ * -+ * 08 11 2011 cp.wu -+ * [WCXRP00000830] [MT6620 Wi-Fi][Firmware] Use MDRDY counter to detect empty channel for shortening scan time -+ * expose scnQuerySparseChannel() for P2P-FSM. -+ * -+ * 08 11 2011 cp.wu -+ * [WCXRP00000830] [MT6620 Wi-Fi][Firmware] Use MDRDY counter to detect empty channel for shortening scan time -+ * sparse channel detection: -+ * driver: collect sparse channel information with scan-done event -+ * -+ * 08 02 2011 yuche.tsai -+ * [WCXRP00000896] [Volunteer Patch][WiFi Direct][Driver] GO with multiple client, TX deauth to a disconnecting -+ * device issue. -+ * Fix GO send deauth frame issue. -+ * -+ * 07 07 2011 wh.su -+ * [WCXRP00000839] [MT6620 Wi-Fi][Driver] Add the dumpMemory8 and dumpMemory32 EXPORT_SYMBOL -+ * Add the dumpMemory8 symbol export for debug mode. -+ * -+ * 07 06 2011 terry.wu -+ * [WCXRP00000735] [MT6620 Wi-Fi][BoW][FW/Driver] Protect BoW connection establishment -+ * Improve BoW connection establishment speed. -+ * -+ * 07 05 2011 yuche.tsai -+ * [WCXRP00000821] [Volunteer Patch][WiFi Direct][Driver] WiFi Direct Connection Speed Issue -+ * Export one symbol for enhancement. -+ * -+ * 06 13 2011 eddie.chen -+ * [WCXRP00000779] [MT6620 Wi-Fi][DRV] Add tx rx statistics in linux and use netif_rx_ni -+ * Add tx rx statistics and netif_rx_ni. -+ * -+ * 05 27 2011 cp.wu -+ * [WCXRP00000749] [MT6620 Wi-Fi][Driver] Add band edge tx power control to Wi-Fi NVRAM -+ * invoke CMD_ID_SET_EDGE_TXPWR_LIMIT when there is valid data exist in NVRAM content. -+ * -+ * 05 18 2011 cp.wu -+ * [WCXRP00000734] [MT6620 Wi-Fi][Driver] Pass PHY_PARAM in NVRAM to firmware domain -+ * pass PHY_PARAM in NVRAM from driver to firmware. -+ * -+ * 05 09 2011 jeffrey.chang -+ * [WCXRP00000710] [MT6620 Wi-Fi] Support pattern filter update function on IP address change -+ * support ARP filter through kernel notifier -+ * -+ * 05 03 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Use kalMemAlloc to allocate event buffer for kalIndicateBOWEvent. -+ * -+ * 04 27 2011 george.huang -+ * [WCXRP00000684] [MT6620 Wi-Fi][Driver] Support P2P setting ARP filter -+ * Support P2P ARP filter setting on early suspend/ late resume -+ * -+ * 04 18 2011 terry.wu -+ * [WCXRP00000660] [MT6620 Wi-Fi][Driver] Remove flag CFG_WIFI_DIRECT_MOVED -+ * Remove flag CFG_WIFI_DIRECT_MOVED. -+ * -+ * 04 15 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Add BOW short range mode. -+ * -+ * 04 14 2011 yuche.tsai -+ * [WCXRP00000646] [Volunteer Patch][MT6620][FW/Driver] Sigma Test Modification for some test case. -+ * Modify some driver connection flow or behavior to pass Sigma test more easier.. -+ * -+ * 04 12 2011 cm.chang -+ * [WCXRP00000634] [MT6620 Wi-Fi][Driver][FW] 2nd BSS will not support 40MHz bandwidth for concurrency -+ * . -+ * -+ * 04 11 2011 george.huang -+ * [WCXRP00000621] [MT6620 Wi-Fi][Driver] Support P2P supplicant to set power mode -+ * export wlan functions to p2p -+ * -+ * 04 08 2011 pat.lu -+ * [WCXRP00000623] [MT6620 Wi-Fi][Driver] use ARCH define to distinguish PC Linux driver -+ * Use CONFIG_X86 instead of PC_LINUX_DRIVER_USE option to have proper compile setting for PC Linux driver -+ * -+ * 04 08 2011 cp.wu -+ * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer -+ * glBusFreeIrq() should use the same pvCookie as glBusSetIrq() or request_irq()/free_irq() won't work as a pair. -+ * -+ * 04 08 2011 eddie.chen -+ * [WCXRP00000617] [MT6620 Wi-Fi][DRV/FW] Fix for sigma -+ * Fix for sigma -+ * -+ * 04 06 2011 cp.wu -+ * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer -+ * 1. do not check for pvData inside wlanNetCreate() due to it is NULL for eHPI port -+ * 2. update perm_addr as well for MAC address -+ * 3. not calling check_mem_region() anymore for eHPI -+ * 4. correct MSC_CS macro for 0-based notation -+ * -+ * 03 29 2011 cp.wu -+ * [WCXRP00000598] [MT6620 Wi-Fi][Driver] Implementation of interface for communicating with user space process for -+ * RESET_START and RESET_END events -+ * fix typo. -+ * -+ * 03 29 2011 cp.wu -+ * [WCXRP00000598] [MT6620 Wi-Fi][Driver] Implementation of interface for communicating with user space process for -+ * RESET_START and RESET_END events -+ * implement kernel-to-userspace communication via generic netlink socket for whole-chip resetting mechanism -+ * -+ * 03 23 2011 cp.wu -+ * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer -+ * apply multi-queue operation only for linux kernel > 2.6.26 -+ * -+ * 03 22 2011 pat.lu -+ * [WCXRP00000592] [MT6620 Wi-Fi][Driver] Support PC Linux Environment Driver Build -+ * Add a compiler option "PC_LINUX_DRIVER_USE" for building driver in PC Linux environment. -+ * -+ * 03 21 2011 cp.wu -+ * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer -+ * portability for compatible with linux 2.6.12. -+ * -+ * 03 21 2011 cp.wu -+ * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer -+ * improve portability for awareness of early version of linux kernel and wireless extension. -+ * -+ * 03 21 2011 cp.wu -+ * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer -+ * portability improvement -+ * -+ * 03 18 2011 jeffrey.chang -+ * [WCXRP00000512] [MT6620 Wi-Fi][Driver] modify the net device relative functions to support the H/W multiple queue -+ * remove early suspend functions -+ * -+ * 03 17 2011 cp.wu -+ * [WCXRP00000562] [MT6620 Wi-Fi][Driver] I/O buffer pre-allocation to avoid physically continuous memory shortage -+ * after system running for a long period -+ * reverse order to prevent probing racing. -+ * -+ * 03 16 2011 cp.wu -+ * [WCXRP00000562] [MT6620 Wi-Fi][Driver] I/O buffer pre-allocation to avoid physically continuous memory shortage -+ * after system running for a long period -+ * 1. pre-allocate physical continuous buffer while module is being loaded -+ * 2. use pre-allocated physical continuous buffer for TX/RX DMA transfer -+ * -+ * The windows part remained the same as before, but added similar APIs to hide the difference. -+ * -+ * 03 15 2011 jeffrey.chang -+ * [WCXRP00000558] [MT6620 Wi-Fi][MT6620 Wi-Fi][Driver] refine the queue selection algorithm for WMM -+ * refine the queue_select function -+ * -+ * 03 10 2011 cp.wu -+ * [WCXRP00000532] [MT6620 Wi-Fi][Driver] Migrate NVRAM configuration procedures from MT6620 E2 to MT6620 E3 -+ * deprecate configuration used by MT6620 E2 -+ * -+ * 03 10 2011 terry.wu -+ * [WCXRP00000505] [MT6620 Wi-Fi][Driver/FW] WiFi Direct Integration -+ * Remove unnecessary assert and message. -+ * -+ * 03 08 2011 terry.wu -+ * [WCXRP00000505] [MT6620 Wi-Fi][Driver/FW] WiFi Direct Integration -+ * Export nicQmUpdateWmmParms. -+ * -+ * 03 03 2011 jeffrey.chang -+ * [WCXRP00000512] [MT6620 Wi-Fi][Driver] modify the net device relative functions to support the H/W multiple queue -+ * support concurrent network -+ * -+ * 03 03 2011 jeffrey.chang -+ * [WCXRP00000512] [MT6620 Wi-Fi][Driver] modify the net device relative functions to support the H/W multiple queue -+ * modify net device relative functions to support multiple H/W queues -+ * -+ * 02 24 2011 george.huang -+ * [WCXRP00000495] [MT6620 Wi-Fi][FW] Support pattern filter for unwanted ARP frames -+ * Support ARP filter during suspended -+ * -+ * 02 21 2011 cp.wu -+ * [WCXRP00000482] [MT6620 Wi-Fi][Driver] Simplify logic for checking NVRAM existence in driver domain -+ * simplify logic for checking NVRAM existence only once. -+ * -+ * 02 17 2011 terry.wu -+ * [WCXRP00000459] [MT6620 Wi-Fi][Driver] Fix deference null pointer problem in wlanRemove -+ * Fix deference a null pointer problem in wlanRemove. -+ * -+ * 02 16 2011 jeffrey.chang -+ * NULL -+ * fix compilig error -+ * -+ * 02 16 2011 jeffrey.chang -+ * NULL -+ * Add query ipv4 and ipv6 address during early suspend and late resume -+ * -+ * 02 15 2011 jeffrey.chang -+ * NULL -+ * to support early suspend in android -+ * -+ * 02 11 2011 yuche.tsai -+ * [WCXRP00000431] [Volunteer Patch][MT6620][Driver] Add MLME support for deauthentication under AP(Hot-Spot) mode. -+ * Add one more export symbol. -+ * -+ * 02 10 2011 yuche.tsai -+ * [WCXRP00000431] [Volunteer Patch][MT6620][Driver] Add MLME support for deauthentication under AP(Hot-Spot) mode. -+ * Add RX deauthentication & disassociation process under Hot-Spot mode. -+ * -+ * 02 09 2011 terry.wu -+ * [WCXRP00000383] [MT6620 Wi-Fi][Driver] Separate WiFi and P2P driver into two modules -+ * Halt p2p module init and exit until TxThread finished p2p register and unregister. -+ * -+ * 02 08 2011 george.huang -+ * [WCXRP00000422] [MT6620 Wi-Fi][Driver] support query power mode OID handler -+ * Support querying power mode OID. -+ * -+ * 02 08 2011 yuche.tsai -+ * [WCXRP00000421] [Volunteer Patch][MT6620][Driver] Fix incorrect SSID length Issue -+ * Export Deactivation Network. -+ * -+ * 02 01 2011 jeffrey.chang -+ * [WCXRP00000414] KAL Timer is not unregistered when driver not loaded -+ * Unregister the KAL timer during driver unloading -+ * -+ * 01 26 2011 cm.chang -+ * [WCXRP00000395] [MT6620 Wi-Fi][Driver][FW] Search STA_REC with additional net type index argument -+ * Allocate system RAM if fixed message or mgmt buffer is not available -+ * -+ * 01 19 2011 cp.wu -+ * [WCXRP00000371] [MT6620 Wi-Fi][Driver] make linux glue layer portable for Android 2.3.1 with Linux 2.6.35.7 -+ * add compile option to check linux version 2.6.35 for different usage of system API to improve portability -+ * -+ * 01 12 2011 cp.wu -+ * [WCXRP00000357] [MT6620 Wi-Fi][Driver][Bluetooth over Wi-Fi] add another net device interface for BT AMP -+ * implementation of separate BT_OVER_WIFI data path. -+ * -+ * 01 10 2011 cp.wu -+ * [WCXRP00000349] [MT6620 Wi-Fi][Driver] make kalIoctl() of linux port as a thread safe API to avoid potential issues -+ * due to multiple access -+ * use mutex to protect kalIoctl() for thread safe. -+ * -+ * 01 04 2011 cp.wu -+ * [WCXRP00000338] [MT6620 Wi-Fi][Driver] Separate kalMemAlloc into kmalloc and vmalloc implementations to ease -+ * physically continuous memory demands -+ * separate kalMemAlloc() into virtually-continuous and physically-continuous type to ease slab system pressure -+ * -+ * 12 15 2010 cp.wu -+ * [WCXRP00000265] [MT6620 Wi-Fi][Driver] Remove set_mac_address routine from legacy Wi-Fi Android driver -+ * remove set MAC address. MAC address is always loaded from NVRAM instead. -+ * -+ * 12 10 2010 kevin.huang -+ * [WCXRP00000128] [MT6620 Wi-Fi][Driver] Add proc support to Android Driver for debug and driver status check -+ * Add Linux Proc Support -+ * -+ * 11 01 2010 yarco.yang -+ * [WCXRP00000149] [MT6620 WI-Fi][Driver]Fine tune performance on MT6516 platform -+ * Add GPIO debug function -+ * -+ * 11 01 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000150] [MT6620 Wi-Fi][Driver] -+ * Add implementation for querying current TX rate from firmware auto rate module -+ * 1) Query link speed (TX rate) from firmware directly with buffering mechanism to reduce overhead -+ * 2) Remove CNM CH-RECOVER event handling -+ * 3) cfg read/write API renamed with kal prefix for unified naming rules. -+ * -+ * 10 26 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000137] [MT6620 Wi-Fi] [FW] -+ * Support NIC capability query command -+ * 1) update NVRAM content template to ver 1.02 -+ * 2) add compile option for querying NIC capability (default: off) -+ * 3) modify AIS 5GHz support to run-time option, which could be turned on by registry or NVRAM setting -+ * 4) correct auto-rate compiler error under linux (treat warning as error) -+ * 5) simplify usage of NVRAM and REG_INFO_T -+ * 6) add version checking between driver and firmware -+ * -+ * 10 21 2010 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * . -+ * -+ * 10 19 2010 jeffrey.chang -+ * [WCXRP00000120] [MT6620 Wi-Fi][Driver] Refine linux kernel module to the license of MTK propietary and enable MTK -+ * HIF by default -+ * Refine linux kernel module to the license of MTK and enable MTK HIF -+ * -+ * 10 18 2010 jeffrey.chang -+ * [WCXRP00000106] [MT6620 Wi-Fi][Driver] Enable setting multicast callback in Android -+ * . -+ * -+ * 10 18 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000086] [MT6620 Wi-Fi][Driver] -+ * The mac address is all zero at android -+ * complete implementation of Android NVRAM access -+ * -+ * 09 27 2010 chinghwa.yu -+ * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000065] Update BoW design and settings -+ * Update BCM/BoW design and settings. -+ * -+ * 09 23 2010 cp.wu -+ * [WCXRP00000051] [MT6620 Wi-Fi][Driver] WHQL test fail in MAC address changed item -+ * use firmware reported mac address right after wlanAdapterStart() as permanent address -+ * -+ * 09 21 2010 kevin.huang -+ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning -+ * Eliminate Linux Compile Warning -+ * -+ * 09 03 2010 kevin.huang -+ * NULL -+ * Refine #include sequence and solve recursive/nested #include issue -+ * -+ * 09 01 2010 wh.su -+ * NULL -+ * adding the wapi support for integration test. -+ * -+ * 08 18 2010 yarco.yang -+ * NULL -+ * 1. Fixed HW checksum offload function not work under Linux issue. -+ * 2. Add debug message. -+ * -+ * 08 16 2010 yarco.yang -+ * NULL -+ * Support Linux x86 -+ * -+ * 08 02 2010 jeffrey.chang -+ * NULL -+ * 1) modify tx service thread to avoid busy looping -+ * 2) add spin lock declartion for linux build -+ * -+ * 07 29 2010 jeffrey.chang -+ * NULL -+ * fix memory leak for module unloading -+ * -+ * 07 28 2010 jeffrey.chang -+ * NULL -+ * 1) remove unused spinlocks -+ * 2) enable encyption ioctls -+ * 3) fix scan ioctl which may cause supplicant to hang -+ * -+ * 07 23 2010 jeffrey.chang -+ * -+ * bug fix: allocate regInfo when disabling firmware download -+ * -+ * 07 23 2010 jeffrey.chang -+ * -+ * use glue layer api to decrease or increase counter atomically -+ * -+ * 07 22 2010 jeffrey.chang -+ * -+ * add new spinlock -+ * -+ * 07 19 2010 jeffrey.chang -+ * -+ * modify cmd/data path for new design -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 05 26 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * 1) Modify set mac address code -+ * 2) remove power management macro -+ * -+ * 05 10 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * implement basic wi-fi direct framework -+ * -+ * 05 07 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * prevent supplicant accessing driver during resume -+ * -+ * 05 07 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * add basic framework for implementating P2P driver hook. -+ * -+ * 04 27 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * 1) fix firmware download bug -+ * 2) remove query statistics for acelerating firmware download -+ * -+ * 04 27 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * follow Linux's firmware framework, and remove unused kal API -+ * -+ * 04 21 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * add for private ioctl support -+ * -+ * 04 19 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * Query statistics from firmware -+ * -+ * 04 19 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * modify tcp/ip checksum offload flags -+ * -+ * 04 16 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * fix tcp/ip checksum offload bug -+ * -+ * 04 13 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * add framework for BT-over-Wi-Fi support. -+ * * * * * * * * * * * * * * * * * 1) prPendingCmdInfo is replaced by queue for multiple handler -+ * * * * * * * * * * * * * * * * * capability -+ * * * * * * * * * * * * * * * * * 2) command sequence number is now increased atomically -+ * * * * * * * * * * * * * * * * * 3) private data could be hold and taken use for other purpose -+ * -+ * 04 09 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * fix spinlock usage -+ * -+ * 04 07 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * Set MAC address from firmware -+ * -+ * 04 07 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * rWlanInfo should be placed at adapter rather than glue due to most operations -+ * * * * * * are done in adapter layer. -+ * -+ * 04 07 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * (1)improve none-glue code portability -+ * * (2) disable set Multicast address during atomic context -+ * -+ * 04 06 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * adding debug module -+ * -+ * 03 31 2010 wh.su -+ * [WPD00003816][MT6620 Wi-Fi] Adding the security support -+ * modify the wapi related code for new driver's design. -+ * -+ * 03 30 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * emulate NDIS Pending OID facility -+ * -+ * 03 26 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * fix f/w download start and load address by using config.h -+ * -+ * 03 26 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * [WPD00003826] Initial import for Linux port -+ * adding firmware download support -+ * -+ * 03 24 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * initial import for Linux port -+** \main\maintrunk.MT5921\52 2009-10-27 22:49:59 GMT mtk01090 -+** Fix compile error for Linux EHPI driver -+** \main\maintrunk.MT5921\51 2009-10-20 17:38:22 GMT mtk01090 -+** Refine driver unloading and clean up procedure. Block requests, stop main thread and clean up queued requests, -+** and then stop hw. -+** \main\maintrunk.MT5921\50 2009-10-08 10:33:11 GMT mtk01090 -+** Avoid accessing private data of net_device directly. Replace with netdev_priv(). Add more checking for input -+** parameters and pointers. -+** \main\maintrunk.MT5921\49 2009-09-28 20:19:05 GMT mtk01090 -+** Add private ioctl to carry OID structures. Restructure public/private ioctl interfaces to Linux kernel. -+** \main\maintrunk.MT5921\48 2009-09-03 13:58:46 GMT mtk01088 -+** remove non-used code -+** \main\maintrunk.MT5921\47 2009-09-03 11:40:25 GMT mtk01088 -+** adding the module parameter for wapi -+** \main\maintrunk.MT5921\46 2009-08-18 22:56:41 GMT mtk01090 -+** Add Linux SDIO (with mmc core) support. -+** Add Linux 2.6.21, 2.6.25, 2.6.26. -+** Fix compile warning in Linux. -+** \main\maintrunk.MT5921\45 2009-07-06 20:53:00 GMT mtk01088 -+** adding the code to check the wapi 1x frame -+** \main\maintrunk.MT5921\44 2009-06-23 23:18:55 GMT mtk01090 -+** Add build option BUILD_USE_EEPROM and compile option CFG_SUPPORT_EXT_CONFIG for NVRAM support -+** \main\maintrunk.MT5921\43 2009-02-16 23:46:51 GMT mtk01461 -+** Revise the order of increasing u4TxPendingFrameNum because of CFG_TX_RET_TX_CTRL_EARLY -+** \main\maintrunk.MT5921\42 2009-01-22 13:11:59 GMT mtk01088 -+** set the tid and 1x value at same packet reserved field -+** \main\maintrunk.MT5921\41 2008-10-20 22:43:53 GMT mtk01104 -+** Fix wrong variable name "prDev" in wlanStop() -+** \main\maintrunk.MT5921\40 2008-10-16 15:37:10 GMT mtk01461 -+** add handle WLAN_STATUS_SUCCESS in wlanHardStartXmit() for CFG_TX_RET_TX_CTRL_EARLY -+** \main\maintrunk.MT5921\39 2008-09-25 15:56:21 GMT mtk01461 -+** Update driver for Code review -+** \main\maintrunk.MT5921\38 2008-09-05 17:25:07 GMT mtk01461 -+** Update Driver for Code Review -+** \main\maintrunk.MT5921\37 2008-09-02 10:57:06 GMT mtk01461 -+** Update driver for code review -+** \main\maintrunk.MT5921\36 2008-08-05 01:53:28 GMT mtk01461 -+** Add support for linux statistics -+** \main\maintrunk.MT5921\35 2008-08-04 16:52:58 GMT mtk01461 -+** Fix ASSERT if removing module in BG_SSID_SCAN state -+** \main\maintrunk.MT5921\34 2008-06-13 22:52:24 GMT mtk01461 -+** Revise status code handling in wlanHardStartXmit() for WLAN_STATUS_SUCCESS -+** \main\maintrunk.MT5921\33 2008-05-30 18:56:53 GMT mtk01461 -+** Not use wlanoidSetCurrentAddrForLinux() -+** \main\maintrunk.MT5921\32 2008-05-30 14:39:40 GMT mtk01461 -+** Remove WMM Assoc Flag -+** \main\maintrunk.MT5921\31 2008-05-23 10:26:40 GMT mtk01084 -+** modify wlanISR interface -+** \main\maintrunk.MT5921\30 2008-05-03 18:52:36 GMT mtk01461 -+** Fix Unset Broadcast filter when setMulticast -+** \main\maintrunk.MT5921\29 2008-05-03 15:17:26 GMT mtk01461 -+** Move Query Media Status to GLUE -+** \main\maintrunk.MT5921\28 2008-04-24 22:48:21 GMT mtk01461 -+** Revise set multicast function by using windows oid style for LP own back -+** \main\maintrunk.MT5921\27 2008-04-24 12:00:08 GMT mtk01461 -+** Fix multicast setting in Linux and add comment -+** \main\maintrunk.MT5921\26 2008-03-28 10:40:22 GMT mtk01461 -+** Fix set mac address func in Linux -+** \main\maintrunk.MT5921\25 2008-03-26 15:37:26 GMT mtk01461 -+** Add set MAC Address -+** \main\maintrunk.MT5921\24 2008-03-26 14:24:53 GMT mtk01461 -+** For Linux, set net_device has feature with checksum offload by default -+** \main\maintrunk.MT5921\23 2008-03-11 14:50:52 GMT mtk01461 -+** Fix typo -+** \main\maintrunk.MT5921\22 2008-02-29 15:35:20 GMT mtk01088 -+** add 1x decide code for sw port control -+** \main\maintrunk.MT5921\21 2008-02-21 15:01:54 GMT mtk01461 -+** Rearrange the set off place of GLUE spin lock in HardStartXmit -+** \main\maintrunk.MT5921\20 2008-02-12 23:26:50 GMT mtk01461 -+** Add debug option - Packet Order for Linux and add debug level - Event -+** \main\maintrunk.MT5921\19 2007-12-11 00:11:12 GMT mtk01461 -+** Fix SPIN_LOCK protection -+** \main\maintrunk.MT5921\18 2007-11-30 17:02:25 GMT mtk01425 -+** 1. Set Rx multicast packets mode before setting the address list -+** \main\maintrunk.MT5921\17 2007-11-26 19:44:24 GMT mtk01461 -+** Add OS_TIMESTAMP to packet -+** \main\maintrunk.MT5921\16 2007-11-21 15:47:20 GMT mtk01088 -+** fixed the unload module issue -+** \main\maintrunk.MT5921\15 2007-11-07 18:37:38 GMT mtk01461 -+** Fix compile warnning -+** \main\maintrunk.MT5921\14 2007-11-02 01:03:19 GMT mtk01461 -+** Unify TX Path for Normal and IBSS Power Save + IBSS neighbor learning -+** \main\maintrunk.MT5921\13 2007-10-30 10:42:33 GMT mtk01425 -+** 1. Refine for multicast list -+** \main\maintrunk.MT5921\12 2007-10-25 18:08:13 GMT mtk01461 -+** Add VOIP SCAN Support & Refine Roaming -+** Revision 1.4 2007/07/05 07:25:33 MTK01461 -+** Add Linux initial code, modify doc, add 11BB, RF init code -+** -+** Revision 1.3 2007/06/27 02:18:50 MTK01461 -+** Update SCAN_FSM, Initial(Can Load Module), Proc(Can do Reg R/W), TX API -+** -+** Revision 1.2 2007/06/25 06:16:24 MTK01461 -+** Update illustrations, gl_init.c, gl_kal.c, gl_kal.h, gl_os.h and RX API -+** -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "gl_os.h" -+#include "wlan_lib.h" -+#include "gl_wext.h" -+#include "gl_cfg80211.h" -+#include "precomp.h" -+#if CFG_SUPPORT_AGPS_ASSIST -+#include "gl_kal.h" -+#endif -+#if defined(CONFIG_MTK_TC1_FEATURE) -+#include -+#endif -+#include "gl_vendor.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+/* #define MAX_IOREQ_NUM 10 */ -+ -+BOOLEAN fgIsUnderSuspend = false; -+ -+ -+#if CFG_ENABLE_WIFI_DIRECT -+spinlock_t g_p2p_lock; -+int g_u4P2PEnding = 0; -+int g_u4P2POnOffing = 0; -+#endif -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+/* Tasklet mechanism is like buttom-half in Linux. We just want to -+ * send a signal to OS for interrupt defer processing. All resources -+ * are NOT allowed reentry, so txPacket, ISR-DPC and ioctl must avoid preempty. -+ */ -+typedef struct _WLANDEV_INFO_T { -+ struct net_device *prDev; -+} WLANDEV_INFO_T, *P_WLANDEV_INFO_T; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+#define CHAN2G(_channel, _freq, _flags) \ -+{ \ -+ .band = NL80211_BAND_2GHZ, \ -+ .center_freq = (_freq), \ -+ .hw_value = (_channel), \ -+ .flags = (_flags), \ -+ .max_antenna_gain = 0, \ -+ .max_power = 30, \ -+} -+ -+static struct ieee80211_channel mtk_2ghz_channels[] = { -+ CHAN2G(1, 2412, 0), -+ CHAN2G(2, 2417, 0), -+ CHAN2G(3, 2422, 0), -+ CHAN2G(4, 2427, 0), -+ CHAN2G(5, 2432, 0), -+ CHAN2G(6, 2437, 0), -+ CHAN2G(7, 2442, 0), -+ CHAN2G(8, 2447, 0), -+ CHAN2G(9, 2452, 0), -+ CHAN2G(10, 2457, 0), -+ CHAN2G(11, 2462, 0), -+ CHAN2G(12, 2467, 0), -+ CHAN2G(13, 2472, 0), -+ CHAN2G(14, 2484, 0), -+}; -+ -+#define CHAN5G(_channel, _flags) \ -+{ \ -+ .band = NL80211_BAND_5GHZ, \ -+ .center_freq = 5000 + (5 * (_channel)), \ -+ .hw_value = (_channel), \ -+ .flags = (_flags), \ -+ .max_antenna_gain = 0, \ -+ .max_power = 30, \ -+} -+ -+static struct ieee80211_channel mtk_5ghz_channels[] = { -+ CHAN5G(34, 0), CHAN5G(36, 0), -+ CHAN5G(38, 0), CHAN5G(40, 0), -+ CHAN5G(42, 0), CHAN5G(44, 0), -+ CHAN5G(46, 0), CHAN5G(48, 0), -+ CHAN5G(52, 0), CHAN5G(56, 0), -+ CHAN5G(60, 0), CHAN5G(64, 0), -+ CHAN5G(100, 0), CHAN5G(104, 0), -+ CHAN5G(108, 0), CHAN5G(112, 0), -+ CHAN5G(116, 0), CHAN5G(120, 0), -+ CHAN5G(124, 0), CHAN5G(128, 0), -+ CHAN5G(132, 0), CHAN5G(136, 0), -+ CHAN5G(140, 0), CHAN5G(149, 0), -+ CHAN5G(153, 0), CHAN5G(157, 0), -+ CHAN5G(161, 0), CHAN5G(165, 0), -+ CHAN5G(169, 0), CHAN5G(173, 0), -+ CHAN5G(184, 0), CHAN5G(188, 0), -+ CHAN5G(192, 0), CHAN5G(196, 0), -+ CHAN5G(200, 0), CHAN5G(204, 0), -+ CHAN5G(208, 0), CHAN5G(212, 0), -+ CHAN5G(216, 0), -+}; -+ -+#define RATETAB_ENT(_rate, _rateid, _flags) \ -+{ \ -+ .bitrate = (_rate), \ -+ .hw_value = (_rateid), \ -+ .flags = (_flags), \ -+} -+ -+/* for cfg80211 - rate table */ -+static struct ieee80211_rate mtk_rates[] = { -+ RATETAB_ENT(10, 0x1000, 0), -+ RATETAB_ENT(20, 0x1001, 0), -+ RATETAB_ENT(55, 0x1002, 0), -+ RATETAB_ENT(110, 0x1003, 0), /* 802.11b */ -+ RATETAB_ENT(60, 0x2000, 0), -+ RATETAB_ENT(90, 0x2001, 0), -+ RATETAB_ENT(120, 0x2002, 0), -+ RATETAB_ENT(180, 0x2003, 0), -+ RATETAB_ENT(240, 0x2004, 0), -+ RATETAB_ENT(360, 0x2005, 0), -+ RATETAB_ENT(480, 0x2006, 0), -+ RATETAB_ENT(540, 0x2007, 0), /* 802.11a/g */ -+}; -+ -+#define mtk_a_rates (mtk_rates + 4) -+#define mtk_a_rates_size (sizeof(mtk_rates) / sizeof(mtk_rates[0]) - 4) -+#define mtk_g_rates (mtk_rates + 0) -+#define mtk_g_rates_size (sizeof(mtk_rates) / sizeof(mtk_rates[0]) - 0) -+ -+#define WLAN_MCS_INFO \ -+{ \ -+ .rx_mask = {0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0},\ -+ .rx_highest = 0, \ -+ .tx_params = IEEE80211_HT_MCS_TX_DEFINED, \ -+} -+ -+#define WLAN_HT_CAP \ -+{ \ -+ .ht_supported = true, \ -+ .cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 \ -+ | IEEE80211_HT_CAP_SM_PS \ -+ | IEEE80211_HT_CAP_GRN_FLD \ -+ | IEEE80211_HT_CAP_SGI_20 \ -+ | IEEE80211_HT_CAP_SGI_40, \ -+ .ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K, \ -+ .ampdu_density = IEEE80211_HT_MPDU_DENSITY_NONE, \ -+ .mcs = WLAN_MCS_INFO, \ -+} -+ -+/********************************************************** -+* Public for both legacy Wi-Fi and P2P to access -+**********************************************************/ -+struct ieee80211_supported_band mtk_band_2ghz = { -+ .band = NL80211_BAND_2GHZ, -+ .channels = mtk_2ghz_channels, -+ .n_channels = ARRAY_SIZE(mtk_2ghz_channels), -+ .bitrates = mtk_g_rates, -+ .n_bitrates = mtk_g_rates_size, -+ .ht_cap = WLAN_HT_CAP, -+}; -+ -+struct ieee80211_supported_band mtk_band_5ghz = { -+ .band = NL80211_BAND_5GHZ, -+ .channels = mtk_5ghz_channels, -+ .n_channels = ARRAY_SIZE(mtk_5ghz_channels), -+ .bitrates = mtk_a_rates, -+ .n_bitrates = mtk_a_rates_size, -+ .ht_cap = WLAN_HT_CAP, -+}; -+ -+const UINT_32 mtk_cipher_suites[5] = { -+ /* keep WEP first, it may be removed below */ -+ WLAN_CIPHER_SUITE_WEP40, -+ WLAN_CIPHER_SUITE_WEP104, -+ WLAN_CIPHER_SUITE_TKIP, -+ WLAN_CIPHER_SUITE_CCMP, -+ -+ /* keep last -- depends on hw flags! */ -+ WLAN_CIPHER_SUITE_AES_CMAC -+}; -+ -+/*********************************************************/ -+ -+#define NIC_INF_NAME "wlan%d" /* interface name */ -+#if CFG_TC1_FEATURE -+#define NIC_INF_NAME_IN_AP_MODE "legacy%d" -+#endif -+ -+/* support to change debug module info dynamically */ -+UINT_8 aucDebugModule[DBG_MODULE_NUM]; -+UINT_32 u4DebugModule = 0; -+ -+/* 4 2007/06/26, mikewu, now we don't use this, we just fix the number of wlan device to 1 */ -+static WLANDEV_INFO_T arWlanDevInfo[CFG_MAX_WLAN_DEVICES] = { {0} }; -+ -+static UINT_32 u4WlanDevNum; /* How many NICs coexist now */ -+ -+/**20150205 added work queue for sched_scan to avoid cfg80211 stop schedule scan dead loack**/ -+struct delayed_work sched_workq; -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+#if CFG_ENABLE_WIFI_DIRECT -+static SUB_MODULE_HANDLER rSubModHandler[SUB_MODULE_NUM] = { {NULL} }; -+#endif -+ -+static struct cfg80211_ops mtk_wlan_ops = { -+ .suspend = mtk_cfg80211_suspend, -+ .resume = mtk_cfg80211_resume, -+ .change_virtual_intf = mtk_cfg80211_change_iface, -+ .add_key = mtk_cfg80211_add_key, -+ .get_key = mtk_cfg80211_get_key, -+ .del_key = mtk_cfg80211_del_key, -+ .set_default_key = mtk_cfg80211_set_default_key, -+ .set_default_mgmt_key = mtk_cfg80211_set_default_mgmt_key, -+ .get_station = mtk_cfg80211_get_station, -+ .change_station = mtk_cfg80211_change_station, -+ .add_station = mtk_cfg80211_add_station, -+ .del_station = mtk_cfg80211_del_station, -+ .scan = mtk_cfg80211_scan, -+ .connect = mtk_cfg80211_connect, -+ .disconnect = mtk_cfg80211_disconnect, -+ .join_ibss = mtk_cfg80211_join_ibss, -+ .leave_ibss = mtk_cfg80211_leave_ibss, -+ .set_power_mgmt = mtk_cfg80211_set_power_mgmt, -+ .set_pmksa = mtk_cfg80211_set_pmksa, -+ .del_pmksa = mtk_cfg80211_del_pmksa, -+ .flush_pmksa = mtk_cfg80211_flush_pmksa, -+ .assoc = mtk_cfg80211_assoc, -+ /* Action Frame TX/RX */ -+ .remain_on_channel = mtk_cfg80211_remain_on_channel, -+ .cancel_remain_on_channel = mtk_cfg80211_cancel_remain_on_channel, -+ .mgmt_tx = mtk_cfg80211_mgmt_tx, -+/* .mgmt_tx_cancel_wait = mtk_cfg80211_mgmt_tx_cancel_wait, */ -+ .mgmt_frame_register = mtk_cfg80211_mgmt_frame_register, -+#ifdef CONFIG_NL80211_TESTMODE -+ .testmode_cmd = mtk_cfg80211_testmode_cmd, -+#endif -+#if (CFG_SUPPORT_TDLS == 1) -+ .tdls_mgmt = TdlsexCfg80211TdlsMgmt, -+ .tdls_oper = TdlsexCfg80211TdlsOper, -+#endif /* CFG_SUPPORT_TDLS */ -+#if 1 /* Remove schedule_scan because we need more verification for NLO */ -+ .sched_scan_start = mtk_cfg80211_sched_scan_start, -+ .sched_scan_stop = mtk_cfg80211_sched_scan_stop, -+#endif -+}; -+ -+static const struct wiphy_vendor_command mtk_wlan_vendor_ops[] = { -+ { -+ { -+ .vendor_id = GOOGLE_OUI, -+ .subcmd = WIFI_SUBCMD_GET_CHANNEL_LIST -+ }, -+ .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, -+ .doit = mtk_cfg80211_vendor_get_channel_list -+ }, -+ { -+ { -+ .vendor_id = GOOGLE_OUI, -+ .subcmd = WIFI_SUBCMD_SET_COUNTRY_CODE -+ }, -+ .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, -+ .doit = mtk_cfg80211_vendor_set_country_code -+ }, -+ /* GSCAN */ -+ { -+ { -+ .vendor_id = GOOGLE_OUI, -+ .subcmd = GSCAN_SUBCMD_GET_CAPABILITIES -+ }, -+ .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, -+ .doit = mtk_cfg80211_vendor_get_gscan_capabilities -+ }, -+ { -+ { -+ .vendor_id = GOOGLE_OUI, -+ .subcmd = GSCAN_SUBCMD_SET_CONFIG -+ }, -+ .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, -+ .doit = mtk_cfg80211_vendor_set_config -+ }, -+ { -+ { -+ .vendor_id = GOOGLE_OUI, -+ .subcmd = GSCAN_SUBCMD_SET_SCAN_CONFIG -+ }, -+ .flags = WIPHY_VENDOR_CMD_NEED_WDEV, -+ .doit = mtk_cfg80211_vendor_set_scan_config -+ }, -+ { -+ { -+ .vendor_id = GOOGLE_OUI, -+ .subcmd = GSCAN_SUBCMD_ENABLE_GSCAN -+ }, -+ .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, -+ .doit = mtk_cfg80211_vendor_enable_scan -+ }, -+ { -+ { -+ .vendor_id = GOOGLE_OUI, -+ .subcmd = GSCAN_SUBCMD_ENABLE_FULL_SCAN_RESULTS -+ }, -+ .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, -+ .doit = mtk_cfg80211_vendor_enable_full_scan_results -+ }, -+ { -+ { -+ .vendor_id = GOOGLE_OUI, -+ .subcmd = GSCAN_SUBCMD_GET_SCAN_RESULTS -+ }, -+ .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, -+ .doit = mtk_cfg80211_vendor_get_scan_results -+ }, -+ { -+ { -+ .vendor_id = GOOGLE_OUI, -+ .subcmd = GSCAN_SUBCMD_SET_SIGNIFICANT_CHANGE_CONFIG -+ }, -+ .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, -+ .doit = mtk_cfg80211_vendor_set_significant_change -+ }, -+ { -+ { -+ .vendor_id = GOOGLE_OUI, -+ .subcmd = GSCAN_SUBCMD_SET_HOTLIST -+ }, -+ .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, -+ .doit = mtk_cfg80211_vendor_set_hotlist -+ }, -+ /* RTT */ -+ { -+ { -+ .vendor_id = GOOGLE_OUI, -+ .subcmd = RTT_SUBCMD_GETCAPABILITY -+ }, -+ .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, -+ .doit = mtk_cfg80211_vendor_get_rtt_capabilities -+ }, -+ /* Link Layer Statistics */ -+ { -+ { -+ .vendor_id = GOOGLE_OUI, -+ .subcmd = LSTATS_SUBCMD_GET_INFO -+ }, -+ .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, -+ .doit = mtk_cfg80211_vendor_llstats_get_info -+ }, -+ -+}; -+ -+static const struct nl80211_vendor_cmd_info mtk_wlan_vendor_events[] = { -+ { -+ .vendor_id = GOOGLE_OUI, -+ .subcmd = GSCAN_EVENT_SIGNIFICANT_CHANGE_RESULTS -+ }, -+ { -+ .vendor_id = GOOGLE_OUI, -+ .subcmd = GSCAN_EVENT_HOTLIST_RESULTS_FOUND -+ }, -+ { -+ .vendor_id = GOOGLE_OUI, -+ .subcmd = GSCAN_EVENT_SCAN_RESULTS_AVAILABLE -+ }, -+ { -+ .vendor_id = GOOGLE_OUI, -+ .subcmd = GSCAN_EVENT_FULL_SCAN_RESULTS -+ }, -+ { -+ .vendor_id = GOOGLE_OUI, -+ .subcmd = RTT_EVENT_COMPLETE -+ }, -+ { -+ .vendor_id = GOOGLE_OUI, -+ .subcmd = GSCAN_EVENT_COMPLETE_SCAN -+ }, -+ { -+ .vendor_id = GOOGLE_OUI, -+ .subcmd = GSCAN_EVENT_HOTLIST_RESULTS_LOST -+ }, -+}; -+ -+/* There isn't a lot of sense in it, but you can transmit anything you like */ -+static const struct ieee80211_txrx_stypes -+ mtk_cfg80211_ais_default_mgmt_stypes[NUM_NL80211_IFTYPES] = { -+ [NL80211_IFTYPE_ADHOC] = { -+ .tx = 0xffff, -+ .rx = BIT(IEEE80211_STYPE_ACTION >> 4) -+ }, -+ [NL80211_IFTYPE_STATION] = { -+ .tx = 0xffff, -+ .rx = BIT(IEEE80211_STYPE_ACTION >> 4) | BIT(IEEE80211_STYPE_PROBE_REQ >> 4) -+ }, -+ [NL80211_IFTYPE_AP] = { -+ .tx = 0xffff, -+ .rx = BIT(IEEE80211_STYPE_PROBE_REQ >> 4) | BIT(IEEE80211_STYPE_ACTION >> 4) -+ }, -+ [NL80211_IFTYPE_AP_VLAN] = { -+ /* copy AP */ -+ .tx = 0xffff, -+ .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) | -+ BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) | -+ BIT(IEEE80211_STYPE_PROBE_REQ >> 4) | -+ BIT(IEEE80211_STYPE_DISASSOC >> 4) | -+ BIT(IEEE80211_STYPE_AUTH >> 4) | -+ BIT(IEEE80211_STYPE_DEAUTH >> 4) | BIT(IEEE80211_STYPE_ACTION >> 4) -+ }, -+ [NL80211_IFTYPE_P2P_CLIENT] = { -+ .tx = 0xffff, -+ .rx = BIT(IEEE80211_STYPE_ACTION >> 4) | BIT(IEEE80211_STYPE_PROBE_REQ >> 4) -+ }, -+ [NL80211_IFTYPE_P2P_GO] = { -+ .tx = 0xffff, -+ .rx = BIT(IEEE80211_STYPE_PROBE_REQ >> 4) | BIT(IEEE80211_STYPE_ACTION >> 4) -+ } -+}; -+ -+#ifdef CONFIG_PM -+static const struct wiphy_wowlan_support mtk_wlan_wowlan_support = { -+ .flags = WIPHY_WOWLAN_DISCONNECT | WIPHY_WOWLAN_ANY, -+}; -+#endif -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Override the implementation of select queue -+* -+* \param[in] dev Pointer to struct net_device -+* \param[in] skb Pointer to struct skb_buff -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+unsigned int _cfg80211_classify8021d(struct sk_buff *skb) -+{ -+ unsigned int dscp = 0; -+ -+ /* skb->priority values from 256->263 are magic values -+ * directly indicate a specific 802.1d priority. This is -+ * to allow 802.1d priority to be passed directly in from -+ * tags -+ */ -+ -+ if (skb->priority >= 256 && skb->priority <= 263) -+ return skb->priority - 256; -+ switch (skb->protocol) { -+ case htons(ETH_P_IP): -+ dscp = ip_hdr(skb)->tos & 0xfc; -+ break; -+ } -+ return dscp >> 5; -+} -+ -+static const UINT_16 au16Wlan1dToQueueIdx[8] = { 1, 0, 0, 1, 2, 2, 3, 3 }; -+ -+static UINT_16 wlanSelectQueue(struct net_device *dev, struct sk_buff *skb, -+ void *accel_priv, select_queue_fallback_t fallback) -+{ -+ skb->priority = _cfg80211_classify8021d(skb); -+ -+ return au16Wlan1dToQueueIdx[skb->priority]; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Load NVRAM data and translate it into REG_INFO_T -+* -+* \param[in] prGlueInfo Pointer to struct GLUE_INFO_T -+* \param[out] prRegInfo Pointer to struct REG_INFO_T -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+static void glLoadNvram(IN P_GLUE_INFO_T prGlueInfo, OUT P_REG_INFO_T prRegInfo) -+{ -+ UINT_32 i, j; -+ UINT_8 aucTmp[2]; -+ PUINT_8 pucDest; -+ -+ ASSERT(prGlueInfo); -+ ASSERT(prRegInfo); -+ -+ if ((!prGlueInfo) || (!prRegInfo)) -+ return; -+ -+ if (kalCfgDataRead16(prGlueInfo, sizeof(WIFI_CFG_PARAM_STRUCT) - sizeof(UINT_16), (PUINT_16) aucTmp) == TRUE) { -+ prGlueInfo->fgNvramAvailable = TRUE; -+ -+ /* load MAC Address */ -+#if !defined(CONFIG_MTK_TC1_FEATURE) -+ for (i = 0; i < PARAM_MAC_ADDR_LEN; i += sizeof(UINT_16)) { -+ kalCfgDataRead16(prGlueInfo, -+ OFFSET_OF(WIFI_CFG_PARAM_STRUCT, aucMacAddress) + i, -+ (PUINT_16) (((PUINT_8) prRegInfo->aucMacAddr) + i)); -+ } -+#else -+ TC1_FAC_NAME(FacReadWifiMacAddr) ((unsigned char *)prRegInfo->aucMacAddr); -+#endif -+ -+ /* load country code */ -+ kalCfgDataRead16(prGlueInfo, OFFSET_OF(WIFI_CFG_PARAM_STRUCT, aucCountryCode[0]), (PUINT_16) aucTmp); -+ -+ /* cast to wide characters */ -+ prRegInfo->au2CountryCode[0] = (UINT_16) aucTmp[0]; -+ prRegInfo->au2CountryCode[1] = (UINT_16) aucTmp[1]; -+ -+ /* load default normal TX power */ -+ for (i = 0; i < sizeof(TX_PWR_PARAM_T); i += sizeof(UINT_16)) { -+ kalCfgDataRead16(prGlueInfo, -+ OFFSET_OF(WIFI_CFG_PARAM_STRUCT, rTxPwr) + i, -+ (PUINT_16) (((PUINT_8) &(prRegInfo->rTxPwr)) + i)); -+ } -+ -+ /* load feature flags */ -+ kalCfgDataRead16(prGlueInfo, OFFSET_OF(WIFI_CFG_PARAM_STRUCT, ucTxPwrValid), (PUINT_16) aucTmp); -+ prRegInfo->ucTxPwrValid = aucTmp[0]; -+ prRegInfo->ucSupport5GBand = aucTmp[1]; -+ -+ kalCfgDataRead16(prGlueInfo, OFFSET_OF(WIFI_CFG_PARAM_STRUCT, uc2G4BwFixed20M), (PUINT_16) aucTmp); -+ prRegInfo->uc2G4BwFixed20M = aucTmp[0]; -+ prRegInfo->uc5GBwFixed20M = aucTmp[1]; -+ -+ kalCfgDataRead16(prGlueInfo, OFFSET_OF(WIFI_CFG_PARAM_STRUCT, ucEnable5GBand), (PUINT_16) aucTmp); -+ prRegInfo->ucEnable5GBand = aucTmp[0]; -+ -+ /* load EFUSE overriding part */ -+ for (i = 0; i < sizeof(prRegInfo->aucEFUSE); i += sizeof(UINT_16)) { -+ kalCfgDataRead16(prGlueInfo, -+ OFFSET_OF(WIFI_CFG_PARAM_STRUCT, aucEFUSE) + i, -+ (PUINT_16) (((PUINT_8) &(prRegInfo->aucEFUSE)) + i)); -+ } -+ -+ /* load band edge tx power control */ -+ kalCfgDataRead16(prGlueInfo, OFFSET_OF(WIFI_CFG_PARAM_STRUCT, fg2G4BandEdgePwrUsed), (PUINT_16) aucTmp); -+ prRegInfo->fg2G4BandEdgePwrUsed = (BOOLEAN) aucTmp[0]; -+ if (aucTmp[0]) { -+ prRegInfo->cBandEdgeMaxPwrCCK = (INT_8) aucTmp[1]; -+ -+ kalCfgDataRead16(prGlueInfo, -+ OFFSET_OF(WIFI_CFG_PARAM_STRUCT, cBandEdgeMaxPwrOFDM20), (PUINT_16) aucTmp); -+ prRegInfo->cBandEdgeMaxPwrOFDM20 = (INT_8) aucTmp[0]; -+ prRegInfo->cBandEdgeMaxPwrOFDM40 = (INT_8) aucTmp[1]; -+ } -+ -+ /* load regulation subbands */ -+ kalCfgDataRead16(prGlueInfo, OFFSET_OF(WIFI_CFG_PARAM_STRUCT, ucRegChannelListMap), (PUINT_16) aucTmp); -+ prRegInfo->eRegChannelListMap = (ENUM_REG_CH_MAP_T) aucTmp[0]; -+ prRegInfo->ucRegChannelListIndex = aucTmp[1]; -+ -+ if (prRegInfo->eRegChannelListMap == REG_CH_MAP_CUSTOMIZED) { -+ for (i = 0; i < MAX_SUBBAND_NUM; i++) { -+ pucDest = (PUINT_8) &prRegInfo->rDomainInfo.rSubBand[i]; -+ for (j = 0; j < 6; j += sizeof(UINT_16)) { -+ kalCfgDataRead16(prGlueInfo, OFFSET_OF(WIFI_CFG_PARAM_STRUCT, aucRegSubbandInfo) -+ + (i * 6 + j), (PUINT_16) aucTmp); -+ -+ *pucDest++ = aucTmp[0]; -+ *pucDest++ = aucTmp[1]; -+ } -+ } -+ } -+ /* load RSSI compensation */ -+ kalCfgDataRead16(prGlueInfo, OFFSET_OF(WIFI_CFG_PARAM_STRUCT, uc2GRssiCompensation), (PUINT_16) aucTmp); -+ prRegInfo->uc2GRssiCompensation = aucTmp[0]; -+ prRegInfo->uc5GRssiCompensation = aucTmp[1]; -+ -+ kalCfgDataRead16(prGlueInfo, -+ OFFSET_OF(WIFI_CFG_PARAM_STRUCT, fgRssiCompensationValidbit), (PUINT_16) aucTmp); -+ prRegInfo->fgRssiCompensationValidbit = aucTmp[0]; -+ prRegInfo->ucRxAntennanumber = aucTmp[1]; -+ } else { -+ prGlueInfo->fgNvramAvailable = FALSE; -+ } -+ -+} -+ -+#if CFG_ENABLE_WIFI_DIRECT -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief called by txthread, run sub module init function -+* -+* \param[in] prGlueInfo Pointer to struct GLUE_INFO_T -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID wlanSubModRunInit(P_GLUE_INFO_T prGlueInfo) -+{ -+ /*now, we only have p2p module */ -+ if (rSubModHandler[P2P_MODULE].fgIsInited == FALSE) { -+ rSubModHandler[P2P_MODULE].subModInit(prGlueInfo); -+ rSubModHandler[P2P_MODULE].fgIsInited = TRUE; -+ } -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief called by txthread, run sub module exit function -+* -+* \param[in] prGlueInfo Pointer to struct GLUE_INFO_T -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID wlanSubModRunExit(P_GLUE_INFO_T prGlueInfo) -+{ -+ /*now, we only have p2p module */ -+ if (rSubModHandler[P2P_MODULE].fgIsInited == TRUE) { -+ rSubModHandler[P2P_MODULE].subModExit(prGlueInfo); -+ rSubModHandler[P2P_MODULE].fgIsInited = FALSE; -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief set sub module init flag, force TxThread to run sub modle init -+* -+* \param[in] prGlueInfo Pointer to struct GLUE_INFO_T -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN wlanSubModInit(P_GLUE_INFO_T prGlueInfo) -+{ -+ /* 4 Mark HALT, notify main thread to finish current job */ -+ prGlueInfo->ulFlag |= GLUE_FLAG_SUB_MOD_INIT; -+ /* wake up main thread */ -+ wake_up_interruptible(&prGlueInfo->waitq); -+ /* wait main thread finish sub module INIT */ -+ wait_for_completion_interruptible(&prGlueInfo->rSubModComp); -+ -+#if 0 -+ if (prGlueInfo->prAdapter->fgIsP2PRegistered) -+ p2pNetRegister(prGlueInfo); -+#endif -+ -+ return TRUE; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief set sub module exit flag, force TxThread to run sub modle exit -+* -+* \param[in] prGlueInfo Pointer to struct GLUE_INFO_T -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN wlanSubModExit(P_GLUE_INFO_T prGlueInfo) -+{ -+#if 0 -+ if (prGlueInfo->prAdapter->fgIsP2PRegistered) -+ p2pNetUnregister(prGlueInfo); -+#endif -+ -+ /* 4 Mark HALT, notify main thread to finish current job */ -+ prGlueInfo->ulFlag |= GLUE_FLAG_SUB_MOD_EXIT; -+ /* wake up main thread */ -+ wake_up_interruptible(&prGlueInfo->waitq); -+ /* wait main thread finish sub module EXIT */ -+ wait_for_completion_interruptible(&prGlueInfo->rSubModComp); -+ -+ return TRUE; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief set by sub module, indicate sub module is already inserted -+* -+* \param[in] rSubModInit, function pointer point to sub module init function -+* \param[in] rSubModExit, function pointer point to sub module exit function -+* \param[in] eSubModIdx, sub module index -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+wlanSubModRegisterInitExit(SUB_MODULE_INIT rSubModInit, SUB_MODULE_EXIT rSubModExit, ENUM_SUB_MODULE_IDX_T eSubModIdx) -+{ -+ rSubModHandler[eSubModIdx].subModInit = rSubModInit; -+ rSubModHandler[eSubModIdx].subModExit = rSubModExit; -+ rSubModHandler[eSubModIdx].fgIsInited = FALSE; -+} -+ -+#if 0 -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief check wlan is launched or not -+* -+* \param[in] (none) -+* -+* \return TRUE, wlan is already started -+* FALSE, wlan is not started yet -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN wlanIsLaunched(VOID) -+{ -+ struct net_device *prDev = NULL; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ -+ /* 4 <0> Sanity check */ -+ ASSERT(u4WlanDevNum <= CFG_MAX_WLAN_DEVICES); -+ if (0 == u4WlanDevNum) -+ return FALSE; -+ -+ prDev = arWlanDevInfo[u4WlanDevNum - 1].prDev; -+ -+ ASSERT(prDev); -+ if (NULL == prDev) -+ return FALSE; -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ ASSERT(prGlueInfo); -+ if (NULL == prGlueInfo) -+ return FALSE; -+ -+ return prGlueInfo->prAdapter->fgIsWlanLaunched; -+} -+ -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Export wlan GLUE_INFO_T pointer to p2p module -+* -+* \param[in] prGlueInfo Pointer to struct GLUE_INFO_T -+* -+* \return TRUE: get GlueInfo pointer successfully -+* FALSE: wlan is not started yet -+*/ -+/*---------------------------------------------------------------------------*/ -+BOOLEAN wlanExportGlueInfo(P_GLUE_INFO_T *prGlueInfoExpAddr) -+{ -+ struct net_device *prDev = NULL; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ -+ if (0 == u4WlanDevNum) -+ return FALSE; -+ -+ prDev = arWlanDevInfo[u4WlanDevNum - 1].prDev; -+ if (NULL == prDev) -+ return FALSE; -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ if (NULL == prGlueInfo) -+ return FALSE; -+ -+ if (FALSE == prGlueInfo->prAdapter->fgIsWlanLaunched) -+ return FALSE; -+ -+ *prGlueInfoExpAddr = prGlueInfo; -+ return TRUE; -+} -+ -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Release prDev from wlandev_array and free tasklet object related to it. -+* -+* \param[in] prDev Pointer to struct net_device -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+static void wlanClearDevIdx(struct net_device *prDev) -+{ -+ int i; -+ -+ ASSERT(prDev); -+ -+ for (i = 0; i < CFG_MAX_WLAN_DEVICES; i++) { -+ if (arWlanDevInfo[i].prDev == prDev) { -+ arWlanDevInfo[i].prDev = NULL; -+ u4WlanDevNum--; -+ } -+ } -+ -+} /* end of wlanClearDevIdx() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Allocate an unique interface index, net_device::ifindex member for this -+* wlan device. Store the net_device in wlandev_array, and initialize -+* tasklet object related to it. -+* -+* \param[in] prDev Pointer to struct net_device -+* -+* \retval >= 0 The device number. -+* \retval -1 Fail to get index. -+*/ -+/*----------------------------------------------------------------------------*/ -+static int wlanGetDevIdx(struct net_device *prDev) -+{ -+ int i; -+ -+ ASSERT(prDev); -+ -+ for (i = 0; i < CFG_MAX_WLAN_DEVICES; i++) { -+ if (arWlanDevInfo[i].prDev == (struct net_device *)NULL) { -+ /* Reserve 2 bytes space to store one digit of -+ * device number and NULL terminator. -+ */ -+ arWlanDevInfo[i].prDev = prDev; -+ u4WlanDevNum++; -+ return i; -+ } -+ } -+ -+ return -1; -+} /* end of wlanGetDevIdx() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief A method of struct net_device, a primary SOCKET interface to configure -+* the interface lively. Handle an ioctl call on one of our devices. -+* Everything Linux ioctl specific is done here. Then we pass the contents -+* of the ifr->data to the request message handler. -+* -+* \param[in] prDev Linux kernel netdevice -+* -+* \param[in] prIfReq Our private ioctl request structure, typed for the generic -+* struct ifreq so we can use ptr to function -+* -+* \param[in] cmd Command ID -+* -+* \retval 0 The IOCTL command is executed successfully. -+* \retval <0 The execution of IOCTL command is failed. -+*/ -+/*----------------------------------------------------------------------------*/ -+int wlanDoIOCTL(struct net_device *prDev, struct ifreq *prIfReq, int i4Cmd) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ int ret = 0; -+ -+ /* Verify input parameters for the following functions */ -+ ASSERT(prDev && prIfReq); -+ if (!prDev || !prIfReq) { -+ DBGLOG(INIT, ERROR, "Invalid input data\n"); -+ return -EINVAL; -+ } -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ if (!prGlueInfo) { -+ DBGLOG(INIT, ERROR, "prGlueInfo is NULL\n"); -+ return -EFAULT; -+ } -+ -+ if (prGlueInfo->u4ReadyFlag == 0) { -+ DBGLOG(INIT, ERROR, "Adapter is not ready\n"); -+ return -EINVAL; -+ } -+ -+ if ((i4Cmd >= SIOCIWFIRST) && (i4Cmd < SIOCIWFIRSTPRIV)) { -+ /* 0x8B00 ~ 0x8BDF, wireless extension region */ -+ ret = wext_support_ioctl(prDev, prIfReq, i4Cmd); -+ } else if ((i4Cmd >= SIOCIWFIRSTPRIV) && (i4Cmd < SIOCIWLASTPRIV)) { -+ /* 0x8BE0 ~ 0x8BFF, private ioctl region */ -+ ret = priv_support_ioctl(prDev, prIfReq, i4Cmd); -+ } else if (i4Cmd == SIOCDEVPRIVATE + 1) { -+ ret = priv_support_driver_cmd(prDev, prIfReq, i4Cmd); -+ } else { -+ DBGLOG(INIT, WARN, "Unexpected ioctl command: 0x%04x\n", i4Cmd); -+ ret = -EOPNOTSUPP; -+ } -+ -+ return ret; -+} /* end of wlanDoIOCTL() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is to set multicast list and set rx mode. -+* -+* \param[in] prDev Pointer to struct net_device -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+ -+static struct delayed_work workq; -+static struct net_device *gPrDev; -+static BOOLEAN fgIsWorkMcStart = FALSE; -+static BOOLEAN fgIsWorkMcEverInit = FALSE; -+static struct wireless_dev *gprWdev; -+ -+static void createWirelessDevice(void) -+{ -+ struct wiphy *prWiphy = NULL; -+ struct wireless_dev *prWdev = NULL; -+#if CFG_SUPPORT_PERSIST_NETDEV -+ struct net_device *prNetDev = NULL; -+#endif -+ -+ /* <1.1> Create wireless_dev */ -+ prWdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL); -+ if (!prWdev) { -+ DBGLOG(INIT, ERROR, "Allocating memory to wireless_dev context failed\n"); -+ return; -+ } -+ -+ -+ /* <1.2> Create wiphy */ -+ prWiphy = wiphy_new(&mtk_wlan_ops, sizeof(GLUE_INFO_T)); -+ if (!prWiphy) { -+ DBGLOG(INIT, ERROR, "Allocating memory to wiphy device failed\n"); -+ goto free_wdev; -+ } -+ -+ /* <1.3> configure wireless_dev & wiphy */ -+ prWdev->iftype = NL80211_IFTYPE_STATION; -+ prWiphy->max_scan_ssids = 1; /* FIXME: for combo scan */ -+ prWiphy->max_scan_ie_len = 512; -+ -+ prWiphy->max_sched_scan_ssids = CFG_SCAN_SSID_MAX_NUM; -+ prWiphy->max_match_sets = CFG_SCAN_SSID_MATCH_MAX_NUM; -+ prWiphy->max_sched_scan_ie_len = CFG_CFG80211_IE_BUF_LEN; -+ -+ prWiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC); -+ prWiphy->bands[NL80211_BAND_2GHZ] = &mtk_band_2ghz; -+ /* always assign 5Ghz bands here, if the chip is not support 5Ghz, -+ bands[IEEE80211_BAND_5GHZ] will be assign to NULL */ -+ prWiphy->bands[NL80211_BAND_5GHZ] = &mtk_band_5ghz; -+ prWiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM; -+ prWiphy->cipher_suites = mtk_cipher_suites; -+ prWiphy->n_cipher_suites = ARRAY_SIZE(mtk_cipher_suites); -+ prWiphy->flags = WIPHY_FLAG_SUPPORTS_FW_ROAM -+ | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL -+ | WIPHY_FLAG_SUPPORTS_SCHED_SCAN; -+ prWiphy->regulatory_flags = REGULATORY_CUSTOM_REG; -+#if CFG_SUPPORT_TDLS -+ TDLSEX_WIPHY_FLAGS_INIT(prWiphy->flags); -+#endif /* CFG_SUPPORT_TDLS */ -+ prWiphy->max_remain_on_channel_duration = 5000; -+ prWiphy->mgmt_stypes = mtk_cfg80211_ais_default_mgmt_stypes; -+ prWiphy->vendor_commands = mtk_wlan_vendor_ops; -+ prWiphy->n_vendor_commands = sizeof(mtk_wlan_vendor_ops) / sizeof(struct wiphy_vendor_command); -+ prWiphy->vendor_events = mtk_wlan_vendor_events; -+ prWiphy->n_vendor_events = ARRAY_SIZE(mtk_wlan_vendor_events); -+ -+ /* <1.4> wowlan support */ -+#ifdef CONFIG_PM -+ prWiphy->wowlan = &mtk_wlan_wowlan_support; -+#endif -+#ifdef CONFIG_CFG80211_WEXT -+ /* <1.5> Use wireless extension to replace IOCTL */ -+ prWiphy->wext = &wext_handler_def; -+#endif -+ -+ if (wiphy_register(prWiphy) < 0) { -+ DBGLOG(INIT, ERROR, "wiphy_register error\n"); -+ goto free_wiphy; -+ } -+ prWdev->wiphy = prWiphy; -+ -+#if CFG_SUPPORT_PERSIST_NETDEV -+ /* <2> allocate and register net_device */ -+#if CFG_TC1_FEATURE -+ if (wlan_if_changed) -+ prNetDev = alloc_netdev_mq(sizeof(P_GLUE_INFO_T), NIC_INF_NAME_IN_AP_MODE, NET_NAME_PREDICTABLE, -+ ether_setup, CFG_MAX_TXQ_NUM); -+ else -+#else -+ prNetDev = alloc_netdev_mq(sizeof(P_GLUE_INFO_T), NIC_INF_NAME, NET_NAME_PREDICTABLE, -+ ether_setup, CFG_MAX_TXQ_NUM); -+#endif -+ if (!prNetDev) { -+ DBGLOG(INIT, ERROR, "Allocating memory to net_device context failed\n"); -+ goto unregister_wiphy; -+ } -+ -+ *((P_GLUE_INFO_T *) netdev_priv(prNetDev)) = (P_GLUE_INFO_T) wiphy_priv(prWiphy); -+ -+ prNetDev->netdev_ops = &wlan_netdev_ops; -+#ifdef CONFIG_WIRELESS_EXT -+ prNetDev->wireless_handlers = &wext_handler_def; -+#endif -+ netif_carrier_off(prNetDev); -+ netif_tx_stop_all_queues(prNetDev); -+ -+ /* <2.1> co-relate with wireless_dev bi-directionally */ -+ prNetDev->ieee80211_ptr = prWdev; -+ prWdev->netdev = prNetDev; -+#if CFG_TCP_IP_CHKSUM_OFFLOAD -+ prNetDev->features = NETIF_F_HW_CSUM; -+#endif -+ -+ /* <2.2> co-relate net device & device tree */ -+ SET_NETDEV_DEV(prNetDev, wiphy_dev(prWiphy)); -+ -+ /* <2.3> register net_device */ -+ if (register_netdev(prWdev->netdev) < 0) { -+ DBGLOG(INIT, ERROR, "wlanNetRegister: net_device context is not registered.\n"); -+ goto unregister_wiphy; -+ } -+#endif /* CFG_SUPPORT_PERSIST_NETDEV */ -+ gprWdev = prWdev; -+ DBGLOG(INIT, INFO, "create wireless device success\n"); -+ return; -+ -+#if CFG_SUPPORT_PERSIST_NETDEV -+unregister_wiphy: -+ wiphy_unregister(prWiphy); -+#endif -+free_wiphy: -+ wiphy_free(prWiphy); -+free_wdev: -+ kfree(prWdev); -+} -+ -+static void destroyWirelessDevice(void) -+{ -+#if CFG_SUPPORT_PERSIST_NETDEV -+ unregister_netdev(gprWdev->netdev); -+ free_netdev(gprWdev->netdev); -+#endif -+ wiphy_unregister(gprWdev->wiphy); -+ wiphy_free(gprWdev->wiphy); -+ kfree(gprWdev); -+ gprWdev = NULL; -+} -+ -+static void wlanSetMulticastList(struct net_device *prDev) -+{ -+ gPrDev = prDev; -+ schedule_delayed_work(&workq, 0); -+} -+ -+/* FIXME: Since we cannot sleep in the wlanSetMulticastList, we arrange -+ * another workqueue for sleeping. We don't want to block -+ * tx_thread, so we can't let tx_thread to do this */ -+ -+static void wlanSetMulticastListWorkQueue(struct work_struct *work) -+{ -+ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ UINT_32 u4PacketFilter = 0; -+ UINT_32 u4SetInfoLen; -+ struct net_device *prDev = gPrDev; -+ -+ fgIsWorkMcStart = TRUE; -+ -+ if (kalHaltLock(KAL_HALT_LOCK_TIMEOUT_NORMAL_CASE)) -+ return; -+ if (kalIsHalted()) { -+ fgIsWorkMcStart = FALSE; -+ kalHaltUnlock(); -+ return; -+ } -+ -+ prGlueInfo = (NULL != prDev) ? *((P_GLUE_INFO_T *) netdev_priv(prDev)) : NULL; -+ ASSERT(prDev); -+ ASSERT(prGlueInfo); -+ if (!prDev || !prGlueInfo) { -+ DBGLOG(INIT, WARN, "abnormal dev or skb: prDev(0x%p), prGlueInfo(0x%p)\n", prDev, prGlueInfo); -+ fgIsWorkMcStart = FALSE; -+ kalHaltUnlock(); -+ return; -+ } -+ -+ if (prDev->flags & IFF_PROMISC) -+ u4PacketFilter |= PARAM_PACKET_FILTER_PROMISCUOUS; -+ -+ if (prDev->flags & IFF_BROADCAST) -+ u4PacketFilter |= PARAM_PACKET_FILTER_BROADCAST; -+ -+ if (prDev->flags & IFF_MULTICAST) { -+ if ((prDev->flags & IFF_ALLMULTI) || -+ (netdev_mc_count(prDev) > MAX_NUM_GROUP_ADDR)) { -+ -+ u4PacketFilter |= PARAM_PACKET_FILTER_ALL_MULTICAST; -+ } else { -+ u4PacketFilter |= PARAM_PACKET_FILTER_MULTICAST; -+ } -+ } -+ -+ kalHaltUnlock(); -+ -+ if (kalIoctl(prGlueInfo, -+ wlanoidSetCurrentPacketFilter, -+ &u4PacketFilter, -+ sizeof(u4PacketFilter), FALSE, FALSE, TRUE, FALSE, &u4SetInfoLen) != WLAN_STATUS_SUCCESS) { -+ fgIsWorkMcStart = FALSE; -+ DBGLOG(INIT, ERROR, "wlanSetMulticastListWorkQueue kalIoctl u4PacketFilter=%d\n", u4PacketFilter); -+ return; -+ } -+ -+ if (u4PacketFilter & PARAM_PACKET_FILTER_MULTICAST) { -+ /* Prepare multicast address list */ -+ struct netdev_hw_addr *ha; -+ PUINT_8 prMCAddrList = NULL; -+ UINT_32 i = 0; -+ -+ if (kalHaltLock(KAL_HALT_LOCK_TIMEOUT_NORMAL_CASE)) -+ return; -+ if (kalIsHalted()) { -+ fgIsWorkMcStart = FALSE; -+ kalHaltUnlock(); -+ /*DBGLOG(INIT, WARN, "wlanSetMulticastListWorkQueue g_u4HaltFlag=%d\n", g_u4HaltFlag);*/ -+ return; -+ } -+ -+ prMCAddrList = kalMemAlloc(MAX_NUM_GROUP_ADDR * ETH_ALEN, VIR_MEM_TYPE); -+ -+ netdev_for_each_mc_addr(ha, prDev) { -+ if (i < MAX_NUM_GROUP_ADDR) { -+ memcpy((prMCAddrList + i * ETH_ALEN), ha->addr, ETH_ALEN); -+ i++; -+ } -+ } -+ -+ kalHaltUnlock(); -+ -+ kalIoctl(prGlueInfo, -+ wlanoidSetMulticastList, -+ prMCAddrList, (i * ETH_ALEN), FALSE, FALSE, TRUE, FALSE, &u4SetInfoLen); -+ -+ kalMemFree(prMCAddrList, VIR_MEM_TYPE, MAX_NUM_GROUP_ADDR * ETH_ALEN); -+ } -+ -+ fgIsWorkMcStart = FALSE; -+ -+} /* end of wlanSetMulticastList() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief To indicate scheduled scan has been stopped -+* -+* \param[in] -+* prGlueInfo -+* -+* \return -+* None -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID wlanSchedScanStoppedWorkQueue(struct work_struct *work) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ struct net_device *prDev = gPrDev; -+ -+ prGlueInfo = (NULL != prDev) ? *((P_GLUE_INFO_T *) netdev_priv(prDev)) : NULL; -+ if (!prGlueInfo) { -+ DBGLOG(SCN, ERROR, "prGlueInfo == NULL unexpected\n"); -+ return; -+ } -+ -+ /* 2. indication to cfg80211 */ -+ /* 20150205 change cfg80211_sched_scan_stopped to work queue due to sched_scan_mtx dead lock issue */ -+ cfg80211_sched_scan_stopped(priv_to_wiphy(prGlueInfo),0); -+ DBGLOG(SCN, INFO, -+ "cfg80211_sched_scan_stopped event send done\n"); -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is TX entry point of NET DEVICE. -+* -+* \param[in] prSkb Pointer of the sk_buff to be sent -+* \param[in] prDev Pointer to struct net_device -+* -+* \retval NETDEV_TX_OK - on success. -+* \retval NETDEV_TX_BUSY - on failure, packet will be discarded by upper layer. -+*/ -+/*----------------------------------------------------------------------------*/ -+int wlanHardStartXmit(struct sk_buff *prSkb, struct net_device *prDev) -+{ -+ P_GLUE_INFO_T prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ -+ P_QUE_ENTRY_T prQueueEntry = NULL; -+ P_QUE_T prTxQueue = NULL; -+ UINT_16 u2QueueIdx = 0; -+#if (CFG_SUPPORT_TDLS_DBG == 1) -+ UINT16 u2Identifier = 0; -+#endif -+ -+#if CFG_BOW_TEST -+ UINT_32 i; -+#endif -+ -+ GLUE_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(prSkb); -+ ASSERT(prDev); -+ ASSERT(prGlueInfo); -+ prGlueInfo->u8SkbToDriver++; -+ -+#if (CFG_SUPPORT_TDLS_DBG == 1) -+ { -+ UINT8 *pkt = prSkb->data; -+ -+ if ((*(pkt + 12) == 0x08) && (*(pkt + 13) == 0x00)) { -+ /* ip */ -+ u2Identifier = ((*(pkt + 18)) << 8) | (*(pkt + 19)); -+ /* u2TdlsTxSeq[u4TdlsTxSeqId ++] = u2Identifier; */ -+ DBGLOG(INIT, INFO, " %d\n", u2Identifier); -+ } -+ } -+#endif -+ /* check if WiFi is halt */ -+ if (prGlueInfo->ulFlag & GLUE_FLAG_HALT) { -+ DBGLOG(INIT, INFO, "GLUE_FLAG_HALT skip tx\n"); -+ dev_kfree_skb(prSkb); -+ prGlueInfo->u8SkbFreed++; -+ return NETDEV_TX_OK; -+ } -+#if CFG_SUPPORT_HOTSPOT_2_0 -+ if (prGlueInfo->fgIsDad) { -+ /* kalPrint("[Passpoint R2] Due to ipv4_dad...TX is forbidden\n"); */ -+ dev_kfree_skb(prSkb); -+ prGlueInfo->u8SkbFreed++; -+ return NETDEV_TX_OK; -+ } -+ if (prGlueInfo->fgIs6Dad) { -+ /* kalPrint("[Passpoint R2] Due to ipv6_dad...TX is forbidden\n"); */ -+ dev_kfree_skb(prSkb); -+ prGlueInfo->u8SkbFreed++; -+ return NETDEV_TX_OK; -+ } -+#endif -+ -+ STATS_TX_TIME_ARRIVE(prSkb); -+ prQueueEntry = (P_QUE_ENTRY_T) GLUE_GET_PKT_QUEUE_ENTRY(prSkb); -+ prTxQueue = &prGlueInfo->rTxQueue; -+ -+#if CFG_BOW_TEST -+ DBGLOG(BOW, TRACE, "sk_buff->len: %d\n", prSkb->len); -+ DBGLOG(BOW, TRACE, "sk_buff->data_len: %d\n", prSkb->data_len); -+ DBGLOG(BOW, TRACE, "sk_buff->data:\n"); -+ -+ for (i = 0; i < prSkb->len; i++) { -+ DBGLOG(BOW, TRACE, "%4x", prSkb->data[i]); -+ -+ if ((i + 1) % 16 == 0) -+ DBGLOG(BOW, TRACE, "\n"); -+ } -+ -+ DBGLOG(BOW, TRACE, "\n"); -+#endif -+ -+ if (wlanProcessSecurityFrame(prGlueInfo->prAdapter, (P_NATIVE_PACKET) prSkb) == FALSE) { -+ -+ /* non-1x packets */ -+ -+#if CFG_DBG_GPIO_PINS -+ { -+ /* TX request from OS */ -+ mtk_wcn_stp_debug_gpio_assert(IDX_TX_REQ, DBG_TIE_LOW); -+ kalUdelay(1); -+ mtk_wcn_stp_debug_gpio_assert(IDX_TX_REQ, DBG_TIE_HIGH); -+ } -+#endif -+ -+ u2QueueIdx = skb_get_queue_mapping(prSkb); -+ ASSERT(u2QueueIdx < CFG_MAX_TXQ_NUM); -+ -+#if CFG_ENABLE_PKT_LIFETIME_PROFILE -+ GLUE_SET_PKT_ARRIVAL_TIME(prSkb, kalGetTimeTick()); -+#endif -+ GLUE_INC_REF_CNT(prGlueInfo->i4TxPendingFrameNum); -+ if (u2QueueIdx < CFG_MAX_TXQ_NUM) -+ GLUE_INC_REF_CNT(prGlueInfo->ai4TxPendingFrameNumPerQueue[NETWORK_TYPE_AIS_INDEX][u2QueueIdx]); -+ -+ GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_TX_QUE); -+ QUEUE_INSERT_TAIL(prTxQueue, prQueueEntry); -+ GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_TX_QUE); -+/* GLUE_INC_REF_CNT(prGlueInfo->i4TxPendingFrameNum); */ -+/* GLUE_INC_REF_CNT(prGlueInfo->ai4TxPendingFrameNumPerQueue[NETWORK_TYPE_AIS_INDEX][u2QueueIdx]); */ -+ -+ if (u2QueueIdx < CFG_MAX_TXQ_NUM) { -+ if (prGlueInfo->ai4TxPendingFrameNumPerQueue[NETWORK_TYPE_AIS_INDEX][u2QueueIdx] >= -+ CFG_TX_STOP_NETIF_PER_QUEUE_THRESHOLD) { -+ DBGLOG(TX, INFO, "netif_stop_subqueue for wlan0, Queue len: %d\n", -+ prGlueInfo->ai4TxPendingFrameNumPerQueue[NETWORK_TYPE_AIS_INDEX][u2QueueIdx]); -+ -+ netif_stop_subqueue(prDev, u2QueueIdx); -+ -+#if (CONF_HIF_LOOPBACK_AUTO == 1) -+ prGlueInfo->rHifInfo.HifLoopbkFlg |= 0x01; -+#endif /* CONF_HIF_LOOPBACK_AUTO */ -+ } -+ } -+ } else { -+ /* printk("is security frame\n"); */ -+ -+ GLUE_INC_REF_CNT(prGlueInfo->i4TxPendingSecurityFrameNum); -+ } -+ -+ DBGLOG(TX, EVENT, "\n+++++ pending frame %d len = %d +++++\n", prGlueInfo->i4TxPendingFrameNum, prSkb->len); -+ prGlueInfo->rNetDevStats.tx_bytes += prSkb->len; -+ prGlueInfo->rNetDevStats.tx_packets++; -+ kalPerMonStart(prGlueInfo); -+ -+ /* set GLUE_FLAG_TXREQ_BIT */ -+ -+ /* pr->u4Flag |= GLUE_FLAG_TXREQ; */ -+ /* wake_up_interruptible(&prGlueInfo->waitq); */ -+ kalSetEvent(prGlueInfo); -+ -+ /* For Linux, we'll always return OK FLAG, because we'll free this skb by ourself */ -+ return NETDEV_TX_OK; -+} /* end of wlanHardStartXmit() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief A method of struct net_device, to get the network interface statistical -+* information. -+* -+* Whenever an application needs to get statistics for the interface, this method -+* is called. This happens, for example, when ifconfig or netstat -i is run. -+* -+* \param[in] prDev Pointer to struct net_device. -+* -+* \return net_device_stats buffer pointer. -+*/ -+/*----------------------------------------------------------------------------*/ -+struct net_device_stats *wlanGetStats(IN struct net_device *prDev) -+{ -+ P_GLUE_INFO_T prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ -+#if 0 -+ WLAN_STATUS rStatus; -+ UINT_32 u4XmitError = 0; -+ UINT_32 u4XmitOk = 0; -+ UINT_32 u4RecvError = 0; -+ UINT_32 u4RecvOk = 0; -+ UINT_32 u4BufLen; -+ -+ ASSERT(prDev); -+ -+ /* @FIX ME: need a more clear way to do this */ -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidQueryXmitError, &u4XmitError, sizeof(UINT_32), TRUE, TRUE, TRUE, &u4BufLen); -+ -+ rStatus = kalIoctl(prGlueInfo, wlanoidQueryXmitOk, &u4XmitOk, sizeof(UINT_32), TRUE, TRUE, TRUE, &u4BufLen); -+ rStatus = kalIoctl(prGlueInfo, wlanoidQueryRcvOk, &u4RecvOk, sizeof(UINT_32), TRUE, TRUE, TRUE, &u4BufLen); -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidQueryRcvError, &u4RecvError, sizeof(UINT_32), TRUE, TRUE, TRUE, &u4BufLen); -+ prGlueInfo->rNetDevStats.rx_packets = u4RecvOk; -+ prGlueInfo->rNetDevStats.tx_packets = u4XmitOk; -+ prGlueInfo->rNetDevStats.tx_errors = u4XmitError; -+ prGlueInfo->rNetDevStats.rx_errors = u4RecvError; -+ /* prGlueInfo->rNetDevStats.rx_bytes = rCustomNetDevStats.u4RxBytes; */ -+ /* prGlueInfo->rNetDevStats.tx_bytes = rCustomNetDevStats.u4TxBytes; */ -+ /* prGlueInfo->rNetDevStats.rx_errors = rCustomNetDevStats.u4RxErrors; */ -+ /* prGlueInfo->rNetDevStats.multicast = rCustomNetDevStats.u4Multicast; */ -+#endif -+ /* prGlueInfo->rNetDevStats.rx_packets = 0; */ -+ /* prGlueInfo->rNetDevStats.tx_packets = 0; */ -+ prGlueInfo->rNetDevStats.tx_errors = 0; -+ prGlueInfo->rNetDevStats.rx_errors = 0; -+ /* prGlueInfo->rNetDevStats.rx_bytes = 0; */ -+ /* prGlueInfo->rNetDevStats.tx_bytes = 0; */ -+ prGlueInfo->rNetDevStats.rx_errors = 0; -+ prGlueInfo->rNetDevStats.multicast = 0; -+ -+ return &prGlueInfo->rNetDevStats; -+ -+} /* end of wlanGetStats() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief A function for prDev->init -+* -+* \param[in] prDev Pointer to struct net_device. -+* -+* \retval 0 The execution of wlanInit succeeds. -+* \retval -ENXIO No such device. -+*/ -+/*----------------------------------------------------------------------------*/ -+static int wlanInit(struct net_device *prDev) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ -+ if (fgIsWorkMcEverInit == FALSE) { -+ if (!prDev) -+ return -ENXIO; -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ INIT_DELAYED_WORK(&workq, wlanSetMulticastListWorkQueue); -+ -+ /* 20150205 work queue for sched_scan */ -+ INIT_DELAYED_WORK(&sched_workq, wlanSchedScanStoppedWorkQueue); -+ -+ fgIsWorkMcEverInit = TRUE; -+ } -+ -+ return 0; /* success */ -+} /* end of wlanInit() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief A function for prDev->uninit -+* -+* \param[in] prDev Pointer to struct net_device. -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+static void wlanUninit(struct net_device *prDev) -+{ -+ -+} /* end of wlanUninit() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief A function for prDev->open -+* -+* \param[in] prDev Pointer to struct net_device. -+* -+* \retval 0 The execution of wlanOpen succeeds. -+* \retval < 0 The execution of wlanOpen failed. -+*/ -+/*----------------------------------------------------------------------------*/ -+static int wlanOpen(struct net_device *prDev) -+{ -+ ASSERT(prDev); -+ -+ netif_tx_start_all_queues(prDev); -+ -+ return 0; /* success */ -+} /* end of wlanOpen() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief A function for prDev->stop -+* -+* \param[in] prDev Pointer to struct net_device. -+* -+* \retval 0 The execution of wlanStop succeeds. -+* \retval < 0 The execution of wlanStop failed. -+*/ -+/*----------------------------------------------------------------------------*/ -+static int wlanStop(struct net_device *prDev) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ struct cfg80211_scan_request *prScanRequest = NULL; -+ -+ struct cfg80211_scan_info info = { -+ .aborted = true, -+ }; -+ -+ GLUE_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(prDev); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ -+ /* CFG80211 down */ -+ GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV); -+ if (prGlueInfo->prScanRequest != NULL) { -+ prScanRequest = prGlueInfo->prScanRequest; -+ prGlueInfo->prScanRequest = NULL; -+ } -+ GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV); -+ -+ if (prScanRequest) -+ cfg80211_scan_done(prScanRequest, &info); -+ netif_tx_stop_all_queues(prDev); -+ -+ return 0; /* success */ -+} /* end of wlanStop() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * \brief Update channel table for cfg80211 based on current country domain -+ * -+ * \param[in] prGlueInfo Pointer to glue info -+ * -+ * \return none -+ */ -+/*----------------------------------------------------------------------------*/ -+VOID wlanUpdateChannelTable(P_GLUE_INFO_T prGlueInfo) -+{ -+ UINT_8 i, j; -+ UINT_8 ucNumOfChannel; -+ RF_CHANNEL_INFO_T aucChannelList[ARRAY_SIZE(mtk_2ghz_channels) + ARRAY_SIZE(mtk_5ghz_channels)]; -+ -+ /* 1. Disable all channels */ -+ for (i = 0; i < ARRAY_SIZE(mtk_2ghz_channels); i++) { -+ mtk_2ghz_channels[i].flags |= IEEE80211_CHAN_DISABLED; -+ mtk_2ghz_channels[i].orig_flags |= IEEE80211_CHAN_DISABLED; -+ } -+ -+ for (i = 0; i < ARRAY_SIZE(mtk_5ghz_channels); i++) { -+ mtk_5ghz_channels[i].flags |= IEEE80211_CHAN_DISABLED; -+ mtk_5ghz_channels[i].orig_flags |= IEEE80211_CHAN_DISABLED; -+ } -+ -+ /* 2. Get current domain channel list */ -+ rlmDomainGetChnlList(prGlueInfo->prAdapter, -+ BAND_NULL, FALSE, -+ ARRAY_SIZE(mtk_2ghz_channels) + ARRAY_SIZE(mtk_5ghz_channels), -+ &ucNumOfChannel, aucChannelList); -+ -+ /* 3. Enable specific channel based on domain channel list */ -+ for (i = 0; i < ucNumOfChannel; i++) { -+ switch (aucChannelList[i].eBand) { -+ case BAND_2G4: -+ for (j = 0; j < ARRAY_SIZE(mtk_2ghz_channels); j++) { -+ if (mtk_2ghz_channels[j].hw_value == aucChannelList[i].ucChannelNum) { -+ mtk_2ghz_channels[j].flags &= ~IEEE80211_CHAN_DISABLED; -+ mtk_2ghz_channels[j].orig_flags &= ~IEEE80211_CHAN_DISABLED; -+ break; -+ } -+ } -+ break; -+ -+ case BAND_5G: -+ for (j = 0; j < ARRAY_SIZE(mtk_5ghz_channels); j++) { -+ if (mtk_5ghz_channels[j].hw_value == aucChannelList[i].ucChannelNum) { -+ mtk_5ghz_channels[j].flags &= ~IEEE80211_CHAN_DISABLED; -+ mtk_5ghz_channels[j].orig_flags &= ~IEEE80211_CHAN_DISABLED; -+ break; -+ } -+ } -+ break; -+ -+ default: -+ DBGLOG(INIT, WARN, "Unknown band %d\n", aucChannelList[i].eBand); -+ break; -+ } -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Register the device to the kernel and return the index. -+* -+* \param[in] prDev Pointer to struct net_device. -+* -+* \retval 0 The execution of wlanNetRegister succeeds. -+* \retval < 0 The execution of wlanNetRegister failed. -+*/ -+/*----------------------------------------------------------------------------*/ -+static INT_32 wlanNetRegister(struct wireless_dev *prWdev) -+{ -+ P_GLUE_INFO_T prGlueInfo; -+ INT_32 i4DevIdx = -1; -+ -+ ASSERT(prWdev); -+ -+ do { -+ if (!prWdev) -+ break; -+ -+ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(prWdev->wiphy); -+ i4DevIdx = wlanGetDevIdx(prWdev->netdev); -+ if (i4DevIdx < 0) { -+ DBGLOG(INIT, ERROR, "wlanNetRegister: net_device number exceeds.\n"); -+ break; -+ } -+ -+#if !CFG_SUPPORT_PERSIST_NETDEV -+ if (register_netdev(prWdev->netdev) < 0) { -+ DBGLOG(INIT, ERROR, "wlanNetRegister: net_device context is not registered.\n"); -+ -+ wiphy_unregister(prWdev->wiphy); -+ wlanClearDevIdx(prWdev->netdev); -+ i4DevIdx = -1; -+ } -+#endif -+ if (i4DevIdx != -1) -+ prGlueInfo->fgIsRegistered = TRUE; -+ -+ } while (FALSE); -+ -+ return i4DevIdx; /* success */ -+} /* end of wlanNetRegister() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Unregister the device from the kernel -+* -+* \param[in] prWdev Pointer to struct net_device. -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+static VOID wlanNetUnregister(struct wireless_dev *prWdev) -+{ -+ P_GLUE_INFO_T prGlueInfo; -+ -+ if (!prWdev) { -+ DBGLOG(INIT, ERROR, "wlanNetUnregister: The device context is NULL\n"); -+ return; -+ } -+ DBGLOG(INIT, TRACE, "unregister net_dev(0x%p)\n", prWdev->netdev); -+ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(prWdev->wiphy); -+ wlanClearDevIdx(prWdev->netdev); -+#if !CFG_SUPPORT_PERSIST_NETDEV -+ unregister_netdev(prWdev->netdev); -+#endif -+ prGlueInfo->fgIsRegistered = FALSE; -+ -+ DBGLOG(INIT, INFO, "unregister wireless_dev(0x%p), ifindex=%d\n", prWdev, prWdev->netdev->ifindex); -+ -+} /* end of wlanNetUnregister() */ -+ -+static const struct net_device_ops wlan_netdev_ops = { -+ .ndo_open = wlanOpen, -+ .ndo_stop = wlanStop, -+ .ndo_set_rx_mode = wlanSetMulticastList, -+ .ndo_get_stats = wlanGetStats, -+ .ndo_do_ioctl = wlanDoIOCTL, -+ .ndo_start_xmit = wlanHardStartXmit, -+ .ndo_init = wlanInit, -+ .ndo_uninit = wlanUninit, -+ .ndo_select_queue = wlanSelectQueue, -+}; -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief A method for creating Linux NET4 struct net_device object and the -+* private data(prGlueInfo and prAdapter). Setup the IO address to the HIF. -+* Assign the function pointer to the net_device object -+* -+* \param[in] pvData Memory address for the device -+* -+* \retval Not null The wireless_dev object. -+* \retval NULL Fail to create wireless_dev object -+*/ -+/*----------------------------------------------------------------------------*/ -+static struct lock_class_key rSpinKey[SPIN_LOCK_NUM]; -+static struct wireless_dev *wlanNetCreate(PVOID pvData) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ struct wireless_dev *prWdev = gprWdev; -+ UINT_32 i; -+ struct device *prDev; -+ -+ if (!prWdev) { -+ DBGLOG(INIT, ERROR, "Allocating memory to wireless_dev context failed\n"); -+ return NULL; -+ } -+ /* 4 <1> co-relate wiphy & prDev */ -+#if MTK_WCN_HIF_SDIO -+ mtk_wcn_hif_sdio_get_dev(*((MTK_WCN_HIF_SDIO_CLTCTX *) pvData), &prDev); -+#else -+/* prDev = &((struct sdio_func *) pvData)->dev; //samp */ -+ prDev = pvData; /* samp */ -+#endif -+ if (!prDev) -+ DBGLOG(INIT, WARN, "unable to get struct dev for wlan\n"); -+ /* don't set prDev as parent of wiphy->dev, because we have done device_add -+ in driver init. if we set parent here, parent will be not able to know this child, -+ and may occurs a KE in device_shutdown, to free wiphy->dev, because his parent -+ has been freed. */ -+ /*set_wiphy_dev(prWdev->wiphy, prDev);*/ -+ -+#if !CFG_SUPPORT_PERSIST_NETDEV -+ /* 4 <3> Initial Glue structure */ -+ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(prWdev->wiphy); -+ kalMemZero(prGlueInfo, sizeof(GLUE_INFO_T)); -+ /* 4 <3.1> Create net device */ -+#if CFG_TC1_FEATURE -+ if (wlan_if_changed) { -+ prGlueInfo->prDevHandler = alloc_netdev_mq(sizeof(P_GLUE_INFO_T), NIC_INF_NAME_IN_AP_MODE, -+ NET_NAME_PREDICTABLE, ether_setup, CFG_MAX_TXQ_NUM); -+ } else { -+ prGlueInfo->prDevHandler = alloc_netdev_mq(sizeof(P_GLUE_INFO_T), NIC_INF_NAME, NET_NAME_PREDICTABLE, -+ ether_setup, CFG_MAX_TXQ_NUM); -+ } -+#else -+ prGlueInfo->prDevHandler = alloc_netdev_mq(sizeof(P_GLUE_INFO_T), NIC_INF_NAME, NET_NAME_PREDICTABLE, -+ ether_setup, CFG_MAX_TXQ_NUM); -+#endif -+ if (!prGlueInfo->prDevHandler) { -+ DBGLOG(INIT, ERROR, "Allocating memory to net_device context failed\n"); -+ return NULL; -+ } -+ DBGLOG(INIT, INFO, "net_device prDev(0x%p) allocated ifindex=%d\n", -+ prGlueInfo->prDevHandler, prGlueInfo->prDevHandler->ifindex); -+ -+ /* 4 <3.1.1> initialize net device varaiables */ -+ *((P_GLUE_INFO_T *) netdev_priv(prGlueInfo->prDevHandler)) = prGlueInfo; -+ -+ prGlueInfo->prDevHandler->netdev_ops = &wlan_netdev_ops; -+#ifdef CONFIG_WIRELESS_EXT -+ prGlueInfo->prDevHandler->wireless_handlers = &wext_handler_def; -+#endif -+ netif_carrier_off(prGlueInfo->prDevHandler); -+ netif_tx_stop_all_queues(prGlueInfo->prDevHandler); -+ -+ /* 4 <3.1.2> co-relate with wiphy bi-directionally */ -+ prGlueInfo->prDevHandler->ieee80211_ptr = prWdev; -+#if CFG_TCP_IP_CHKSUM_OFFLOAD -+ prGlueInfo->prDevHandler->features = NETIF_F_HW_CSUM; -+#endif -+ prWdev->netdev = prGlueInfo->prDevHandler; -+ -+ /* 4 <3.1.3> co-relate net device & prDev */ -+ /*SET_NETDEV_DEV(prGlueInfo->prDevHandler, wiphy_dev(prWdev->wiphy));*/ -+ SET_NETDEV_DEV(prGlueInfo->prDevHandler, prDev); -+#else /* CFG_SUPPORT_PERSIST_NETDEV */ -+ prGlueInfo->prDevHandler = gprWdev->netdev; -+#endif /* CFG_SUPPORT_PERSIST_NETDEV */ -+ -+ /* 4 <3.2> initiali glue variables */ -+ prGlueInfo->eParamMediaStateIndicated = PARAM_MEDIA_STATE_DISCONNECTED; -+ prGlueInfo->ePowerState = ParamDeviceStateD0; -+ prGlueInfo->fgIsMacAddrOverride = FALSE; -+ prGlueInfo->fgIsRegistered = FALSE; -+ prGlueInfo->prScanRequest = NULL; -+ -+#if CFG_SUPPORT_HOTSPOT_2_0 -+ /* Init DAD */ -+ prGlueInfo->fgIsDad = FALSE; -+ prGlueInfo->fgIs6Dad = FALSE; -+ kalMemZero(prGlueInfo->aucDADipv4, 4); -+ kalMemZero(prGlueInfo->aucDADipv6, 16); -+#endif -+ -+ init_completion(&prGlueInfo->rScanComp); -+ init_completion(&prGlueInfo->rHaltComp); -+ init_completion(&prGlueInfo->rPendComp); -+#if CFG_ENABLE_WIFI_DIRECT -+ init_completion(&prGlueInfo->rSubModComp); -+#endif -+ -+ /* initialize timer for OID timeout checker */ -+ kalOsTimerInitialize(prGlueInfo, kalTimeoutHandler); -+ -+ for (i = 0; i < SPIN_LOCK_NUM; i++) { -+ spin_lock_init(&prGlueInfo->rSpinLock[i]); -+ lockdep_set_class(&prGlueInfo->rSpinLock[i], &rSpinKey[i]); -+ } -+ -+ /* initialize semaphore for ioctl */ -+ sema_init(&prGlueInfo->ioctl_sem, 1); -+ -+ glSetHifInfo(prGlueInfo, (ULONG) pvData); -+ -+ /* 4 <8> Init Queues */ -+ init_waitqueue_head(&prGlueInfo->waitq); -+ QUEUE_INITIALIZE(&prGlueInfo->rCmdQueue); -+ QUEUE_INITIALIZE(&prGlueInfo->rTxQueue); -+ -+ /* 4 <4> Create Adapter structure */ -+ prGlueInfo->prAdapter = (P_ADAPTER_T) wlanAdapterCreate(prGlueInfo); -+ -+ if (!prGlueInfo->prAdapter) { -+ DBGLOG(INIT, ERROR, "Allocating memory to adapter failed\n"); -+ return NULL; -+ } -+ KAL_WAKE_LOCK_INIT(prAdapter, &prGlueInfo->rAhbIsrWakeLock, "WLAN AHB ISR"); -+#if CFG_SUPPORT_PERSIST_NETDEV -+ dev_open(prGlueInfo->prDevHandler); -+ netif_carrier_off(prGlueInfo->prDevHandler); -+ netif_tx_stop_all_queues(prGlueInfo->prDevHandler); -+#endif -+ -+ return prWdev; -+} /* end of wlanNetCreate() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Destroying the struct net_device object and the private data. -+* -+* \param[in] prWdev Pointer to struct wireless_dev. -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+static VOID wlanNetDestroy(struct wireless_dev *prWdev) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ -+ ASSERT(prWdev); -+ -+ if (!prWdev) { -+ DBGLOG(INIT, ERROR, "wlanNetDestroy: The device context is NULL\n"); -+ return; -+ } -+ -+ /* prGlueInfo is allocated with net_device */ -+ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(prWdev->wiphy); -+ ASSERT(prGlueInfo); -+ -+ /* destroy kal OS timer */ -+ kalCancelTimer(prGlueInfo); -+ -+ glClearHifInfo(prGlueInfo); -+ -+ wlanAdapterDestroy(prGlueInfo->prAdapter); -+ prGlueInfo->prAdapter = NULL; -+ -+#if CFG_SUPPORT_PERSIST_NETDEV -+ /* take the net_device to down state */ -+ dev_close(prGlueInfo->prDevHandler); -+#else -+ /* Free net_device and private data prGlueInfo, which are allocated by alloc_netdev(). */ -+ free_netdev(prWdev->netdev); -+#endif -+ -+} /* end of wlanNetDestroy() */ -+ -+#ifndef CONFIG_X86 -+UINT_8 g_aucBufIpAddr[32] = { 0 }; -+static void wlanNotifyFwSuspend(P_GLUE_INFO_T prGlueInfo, BOOLEAN fgSuspend) -+{ -+ WLAN_STATUS rStatus = WLAN_STATUS_FAILURE; -+ UINT_32 u4SetInfoLen; -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidNotifyFwSuspend, -+ (PVOID)&fgSuspend, -+ sizeof(fgSuspend), -+ FALSE, -+ FALSE, -+ TRUE, -+ FALSE, -+ &u4SetInfoLen); -+ if (rStatus != WLAN_STATUS_SUCCESS) -+ DBGLOG(INIT, INFO, "wlanNotifyFwSuspend fail\n"); -+} -+ -+void wlanHandleSystemSuspend(void) -+{ -+ WLAN_STATUS rStatus = WLAN_STATUS_FAILURE; -+ struct net_device *prDev = NULL; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ UINT_8 ip[4] = { 0 }; -+ UINT_32 u4NumIPv4 = 0; -+#ifdef CONFIG_IPV6 -+ UINT_8 ip6[16] = { 0 }; /* FIX ME: avoid to allocate large memory in stack */ -+ UINT_32 u4NumIPv6 = 0; -+#endif -+ UINT_32 i; -+ P_PARAM_NETWORK_ADDRESS_IP prParamIpAddr; -+ -+ /* <1> Sanity check and acquire the net_device */ -+ ASSERT(u4WlanDevNum <= CFG_MAX_WLAN_DEVICES); -+ if (u4WlanDevNum == 0) { -+ DBGLOG(INIT, ERROR, "wlanEarlySuspend u4WlanDevNum==0 invalid!!\n"); -+ return; -+ } -+ prDev = arWlanDevInfo[u4WlanDevNum - 1].prDev; -+ -+ fgIsUnderSuspend = true; -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ ASSERT(prGlueInfo); -+ -+ kalPerMonDisable(prGlueInfo); -+ -+ if (!prDev || !(prDev->ip_ptr) || -+ !((struct in_device *)(prDev->ip_ptr))->ifa_list || -+ !(&(((struct in_device *)(prDev->ip_ptr))->ifa_list->ifa_local))) { -+ goto notify_suspend; -+ } -+ kalMemCopy(ip, &(((struct in_device *)(prDev->ip_ptr))->ifa_list->ifa_local), sizeof(ip)); -+ -+ /* todo: traverse between list to find whole sets of IPv4 addresses */ -+ if (!((ip[0] == 0) && (ip[1] == 0) && (ip[2] == 0) && (ip[3] == 0))) -+ u4NumIPv4++; -+#ifdef CONFIG_IPV6 -+ if (!prDev || !(prDev->ip6_ptr) || -+ !((struct in_device *)(prDev->ip6_ptr))->ifa_list || -+ !(&(((struct in_device *)(prDev->ip6_ptr))->ifa_list->ifa_local))) { -+ goto notify_suspend; -+ } -+ kalMemCopy(ip6, &(((struct in_device *)(prDev->ip6_ptr))->ifa_list->ifa_local), sizeof(ip6)); -+ DBGLOG(INIT, INFO, "ipv6 is %d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d\n", -+ ip6[0], ip6[1], ip6[2], ip6[3], -+ ip6[4], ip6[5], ip6[6], ip6[7], -+ ip6[8], ip6[9], ip6[10], ip6[11], ip6[12], ip6[13], ip6[14], ip6[15] -+ ); -+ -+ /* todo: traverse between list to find whole sets of IPv6 addresses */ -+ if (!((ip6[0] == 0) && (ip6[1] == 0) && (ip6[2] == 0) && (ip6[3] == 0) && (ip6[4] == 0) && (ip6[5] == 0))) { -+ /* Do nothing */ -+ /* u4NumIPv6++; */ -+ } -+#endif -+ -+ /* <7> set up the ARP filter */ -+ { -+ UINT_32 u4SetInfoLen = 0; -+ UINT_32 u4Len = OFFSET_OF(PARAM_NETWORK_ADDRESS_LIST, arAddress); -+ P_PARAM_NETWORK_ADDRESS_LIST prParamNetAddrList = (P_PARAM_NETWORK_ADDRESS_LIST) g_aucBufIpAddr; -+ P_PARAM_NETWORK_ADDRESS prParamNetAddr = prParamNetAddrList->arAddress; -+ -+ kalMemZero(g_aucBufIpAddr, sizeof(g_aucBufIpAddr)); -+ -+ prParamNetAddrList->u4AddressCount = u4NumIPv4; -+#ifdef CONFIG_IPV6 -+ prParamNetAddrList->u4AddressCount += u4NumIPv6; -+#endif -+ prParamNetAddrList->u2AddressType = PARAM_PROTOCOL_ID_TCP_IP; -+ for (i = 0; i < u4NumIPv4; i++) { -+ prParamNetAddr->u2AddressLength = sizeof(PARAM_NETWORK_ADDRESS_IP); /* 4;; */ -+ prParamNetAddr->u2AddressType = PARAM_PROTOCOL_ID_TCP_IP; -+ prParamIpAddr = (P_PARAM_NETWORK_ADDRESS_IP) prParamNetAddr->aucAddress; -+ kalMemCopy(&prParamIpAddr->in_addr, ip, sizeof(ip)); -+ prParamNetAddr = -+ (P_PARAM_NETWORK_ADDRESS) ((ULONG) prParamNetAddr + sizeof(PARAM_NETWORK_ADDRESS)); -+ u4Len += OFFSET_OF(PARAM_NETWORK_ADDRESS, aucAddress) + sizeof(PARAM_NETWORK_ADDRESS); -+ } -+#ifdef CONFIG_IPV6 -+ for (i = 0; i < u4NumIPv6; i++) { -+ prParamNetAddr->u2AddressLength = 6; -+ prParamNetAddr->u2AddressType = PARAM_PROTOCOL_ID_TCP_IP; -+ kalMemCopy(prParamNetAddr->aucAddress, ip6, sizeof(ip6)); -+ prParamNetAddr = (P_PARAM_NETWORK_ADDRESS) ((ULONG) prParamNetAddr + sizeof(ip6)); -+ u4Len += OFFSET_OF(PARAM_NETWORK_ADDRESS, aucAddress) + sizeof(ip6); -+ } -+#endif -+ ASSERT(u4Len <= sizeof(g_aucBufIpAddr)); -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetNetworkAddress, -+ (PVOID) prParamNetAddrList, u4Len, FALSE, FALSE, TRUE, FALSE, &u4SetInfoLen); -+ } -+ -+notify_suspend: -+ DBGLOG(INIT, INFO, "IP: %d.%d.%d.%d, rStatus: %u\n", ip[0], ip[1], ip[2], ip[3], rStatus); -+ if (rStatus != WLAN_STATUS_SUCCESS) -+ wlanNotifyFwSuspend(prGlueInfo, TRUE); -+} -+ -+void wlanHandleSystemResume(void) -+{ -+ struct net_device *prDev = NULL; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ WLAN_STATUS rStatus = WLAN_STATUS_FAILURE; -+ UINT_8 ip[4] = { 0 }; -+#ifdef CONFIG_IPV6 -+ UINT_8 ip6[16] = { 0 }; /* FIX ME: avoid to allocate large memory in stack */ -+#endif -+ EVENT_AIS_BSS_INFO_T rParam; -+ UINT_32 u4BufLen = 0; -+ -+ /* <1> Sanity check and acquire the net_device */ -+ ASSERT(u4WlanDevNum <= CFG_MAX_WLAN_DEVICES); -+ if (u4WlanDevNum == 0) { -+ DBGLOG(INIT, ERROR, "wlanLateResume u4WlanDevNum==0 invalid!!\n"); -+ return; -+ } -+ prDev = arWlanDevInfo[u4WlanDevNum - 1].prDev; -+ /* ASSERT(prDev); */ -+ -+ fgIsUnderSuspend = false; -+ -+ if (!prDev) { -+ DBGLOG(INIT, INFO, "prDev == NULL!!!\n"); -+ return; -+ } -+ /* <3> acquire the prGlueInfo */ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ ASSERT(prGlueInfo); -+ -+ kalPerMonEnable(prGlueInfo); -+ -+ /* -+ We will receive the event in rx, we will check if the status is the same in driver -+ and FW, if not the same, trigger disconnetion procedure. -+ */ -+ -+ kalMemZero(&rParam, sizeof(EVENT_AIS_BSS_INFO_T)); -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidQueryBSSInfo, -+ &rParam, sizeof(EVENT_AIS_BSS_INFO_T), TRUE, TRUE, TRUE, FALSE, &u4BufLen); -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ DBGLOG(INIT, ERROR, "Query BSSinfo fail 0x%x!!\n", rStatus); -+ } -+ -+ /* <2> get the IPv4 address */ -+ if (!(prDev->ip_ptr) || -+ !((struct in_device *)(prDev->ip_ptr))->ifa_list || -+ !(&(((struct in_device *)(prDev->ip_ptr))->ifa_list->ifa_local))) { -+ goto notify_resume; -+ } -+ /* <4> copy the IPv4 address */ -+ kalMemCopy(ip, &(((struct in_device *)(prDev->ip_ptr))->ifa_list->ifa_local), sizeof(ip)); -+ -+#ifdef CONFIG_IPV6 -+ /* <5> get the IPv6 address */ -+ if (!prDev || !(prDev->ip6_ptr) || -+ !((struct in_device *)(prDev->ip6_ptr))->ifa_list || -+ !(&(((struct in_device *)(prDev->ip6_ptr))->ifa_list->ifa_local))) { -+ goto notify_resume; -+ } -+ /* <6> copy the IPv6 address */ -+ kalMemCopy(ip6, &(((struct in_device *)(prDev->ip6_ptr))->ifa_list->ifa_local), sizeof(ip6)); -+ DBGLOG(INIT, INFO, "ipv6 is %d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d\n", -+ ip6[0], ip6[1], ip6[2], ip6[3], -+ ip6[4], ip6[5], ip6[6], ip6[7], -+ ip6[8], ip6[9], ip6[10], ip6[11], ip6[12], ip6[13], ip6[14], ip6[15] -+ ); -+#endif -+ /* <7> clear the ARP filter */ -+ { -+ UINT_32 u4SetInfoLen = 0; -+/* UINT_8 aucBuf[32] = {0}; */ -+ UINT_32 u4Len = sizeof(PARAM_NETWORK_ADDRESS_LIST); -+ P_PARAM_NETWORK_ADDRESS_LIST prParamNetAddrList = (P_PARAM_NETWORK_ADDRESS_LIST) g_aucBufIpAddr; -+ /* aucBuf; */ -+ -+ kalMemZero(g_aucBufIpAddr, sizeof(g_aucBufIpAddr)); -+ -+ prParamNetAddrList->u4AddressCount = 0; -+ prParamNetAddrList->u2AddressType = PARAM_PROTOCOL_ID_TCP_IP; -+ -+ ASSERT(u4Len <= sizeof(g_aucBufIpAddr /*aucBuf */)); -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetNetworkAddress, -+ (PVOID) prParamNetAddrList, u4Len, FALSE, FALSE, TRUE, FALSE, &u4SetInfoLen); -+ } -+ -+notify_resume: -+ DBGLOG(INIT, INFO, "Query BSS result: %d %d %d, IP: %d.%d.%d.%d, rStatus: %u\n", -+ rParam.eConnectionState, rParam.eCurrentOPMode, rParam.fgIsNetActive, -+ ip[0], ip[1], ip[2], ip[3], rStatus); -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ wlanNotifyFwSuspend(prGlueInfo, FALSE); -+ } -+} -+#endif /* ! CONFIG_X86 */ -+ -+int set_p2p_mode_handler(struct net_device *netdev, PARAM_CUSTOM_P2P_SET_STRUCT_T p2pmode) -+{ -+#if 0 -+ P_GLUE_INFO_T prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(netdev)); -+ PARAM_CUSTOM_P2P_SET_STRUCT_T rSetP2P; -+ WLAN_STATUS rWlanStatus = WLAN_STATUS_SUCCESS; -+ UINT_32 u4BufLen = 0; -+ -+ rSetP2P.u4Enable = p2pmode.u4Enable; -+ rSetP2P.u4Mode = p2pmode.u4Mode; -+ -+ if (!rSetP2P.u4Enable) -+ p2pNetUnregister(prGlueInfo, TRUE); -+ -+ rWlanStatus = kalIoctl(prGlueInfo, -+ wlanoidSetP2pMode, -+ (PVOID) &rSetP2P, -+ sizeof(PARAM_CUSTOM_P2P_SET_STRUCT_T), FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ DBGLOG(INIT, INFO, "ret = %d\n", rWlanStatus); -+ if (rSetP2P.u4Enable) -+ p2pNetRegister(prGlueInfo, TRUE); -+ -+ return 0; -+ -+#else -+ -+ P_GLUE_INFO_T prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(netdev)); -+ PARAM_CUSTOM_P2P_SET_STRUCT_T rSetP2P; -+ WLAN_STATUS rWlanStatus = WLAN_STATUS_SUCCESS; -+ BOOLEAN fgIsP2PEnding; -+ UINT_32 u4BufLen = 0; -+ -+ GLUE_SPIN_LOCK_DECLARATION(); -+ -+ DBGLOG(INIT, INFO, "%u %u\n", (UINT_32) p2pmode.u4Enable, (UINT_32) p2pmode.u4Mode); -+ -+ /* avoid remove & p2p off command simultaneously */ -+ GLUE_ACQUIRE_THE_SPIN_LOCK(&g_p2p_lock); -+ fgIsP2PEnding = g_u4P2PEnding; -+ g_u4P2POnOffing = 1; -+ GLUE_RELEASE_THE_SPIN_LOCK(&g_p2p_lock); -+ -+ if (fgIsP2PEnding == 1) { -+ /* skip the command if we are removing */ -+ GLUE_ACQUIRE_THE_SPIN_LOCK(&g_p2p_lock); -+ g_u4P2POnOffing = 0; -+ GLUE_RELEASE_THE_SPIN_LOCK(&g_p2p_lock); -+ return 0; -+ } -+ -+ rSetP2P.u4Enable = p2pmode.u4Enable; -+ rSetP2P.u4Mode = p2pmode.u4Mode; -+ -+#if !CFG_SUPPORT_PERSIST_NETDEV -+ if ((!rSetP2P.u4Enable) && (fgIsResetting == FALSE)) -+ p2pNetUnregister(prGlueInfo, TRUE); -+#endif -+ /* move out to caller to avoid kalIoctrl & suspend/resume deadlock problem ALPS00844864 */ -+ /* -+ Scenario: -+ 1. System enters suspend/resume but not yet enter wlanearlysuspend() -+ or wlanlateresume(); -+ -+ 2. System switches to do PRIV_CMD_P2P_MODE and execute kalIoctl() -+ and get g_halt_sem then do glRegisterEarlySuspend() or -+ glUnregisterEarlySuspend(); -+ -+ But system suspend/resume procedure is not yet finished so we -+ suspend; -+ -+ 3. System switches back to do suspend/resume procedure and execute -+ kalIoctl(). But driver does not yet release g_halt_sem so system -+ suspend in wlanearlysuspend() or wlanlateresume(); -+ -+ ==> deadlock occurs. -+ */ -+ -+ rWlanStatus = kalIoctl(prGlueInfo, wlanoidSetP2pMode, (PVOID) &rSetP2P,/* pu4IntBuf[0]is used as input SubCmd */ -+ sizeof(PARAM_CUSTOM_P2P_SET_STRUCT_T), FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+#if !CFG_SUPPORT_PERSIST_NETDEV -+ /* Need to check fgIsP2PRegistered, in case of whole chip reset. -+ * in this case, kalIOCTL return success always, -+ * and prGlueInfo->prP2pInfo may be NULL */ -+ if ((rSetP2P.u4Enable) && (prGlueInfo->prAdapter->fgIsP2PRegistered) && (fgIsResetting == FALSE)) -+ p2pNetRegister(prGlueInfo, TRUE); -+#endif -+ GLUE_ACQUIRE_THE_SPIN_LOCK(&g_p2p_lock); -+ g_u4P2POnOffing = 0; -+ GLUE_RELEASE_THE_SPIN_LOCK(&g_p2p_lock); -+ return 0; -+#endif -+} -+ -+static void set_dbg_level_handler(unsigned char dbg_lvl[DBG_MODULE_NUM]) -+{ -+ kalMemCopy(aucDebugModule, dbg_lvl, sizeof(aucDebugModule)); -+ kalPrint("[wlan] change debug level"); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Wlan probe function. This function probes and initializes the device. -+* -+* \param[in] pvData data passed by bus driver init function -+* _HIF_EHPI: NULL -+* _HIF_SDIO: sdio bus driver handle -+* -+* \retval 0 Success -+* \retval negative value Failed -+*/ -+/*----------------------------------------------------------------------------*/ -+static INT_32 wlanProbe(PVOID pvData) -+{ -+ struct wireless_dev *prWdev = NULL; -+ enum probe_fail_reason { -+ BUS_INIT_FAIL, -+ NET_CREATE_FAIL, -+ BUS_SET_IRQ_FAIL, -+ ADAPTER_START_FAIL, -+ NET_REGISTER_FAIL, -+ PROC_INIT_FAIL, -+ FAIL_REASON_NUM -+ } eFailReason; -+ P_WLANDEV_INFO_T prWlandevInfo = NULL; -+ INT_32 i4DevIdx = 0; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ P_ADAPTER_T prAdapter = NULL; -+ INT_32 i4Status = 0; -+ BOOLEAN bRet = FALSE; -+ -+ eFailReason = FAIL_REASON_NUM; -+ do { -+ /* 4 <1> Initialize the IO port of the interface */ -+ /* GeorgeKuo: pData has different meaning for _HIF_XXX: -+ * _HIF_EHPI: pointer to memory base variable, which will be -+ * initialized by glBusInit(). -+ * _HIF_SDIO: bus driver handle -+ */ -+ -+ bRet = glBusInit(pvData); -+ wlanDebugInit(); -+ /* Cannot get IO address from interface */ -+ if (FALSE == bRet) { -+ DBGLOG(INIT, ERROR, KERN_ALERT "wlanProbe: glBusInit() fail\n"); -+ i4Status = -EIO; -+ eFailReason = BUS_INIT_FAIL; -+ break; -+ } -+ /* 4 <2> Create network device, Adapter, KalInfo, prDevHandler(netdev) */ -+ prWdev = wlanNetCreate(pvData); -+ if (prWdev == NULL) { -+ DBGLOG(INIT, ERROR, "wlanProbe: No memory for dev and its private\n"); -+ i4Status = -ENOMEM; -+ eFailReason = NET_CREATE_FAIL; -+ break; -+ } -+ /* 4 <2.5> Set the ioaddr to HIF Info */ -+ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(prWdev->wiphy); -+ gPrDev = prGlueInfo->prDevHandler; -+ -+ /* 4 <4> Setup IRQ */ -+ prWlandevInfo = &arWlanDevInfo[i4DevIdx]; -+ -+ i4Status = glBusSetIrq(prWdev->netdev, NULL, *((P_GLUE_INFO_T *) netdev_priv(prWdev->netdev))); -+ -+ if (i4Status != WLAN_STATUS_SUCCESS) { -+ DBGLOG(INIT, ERROR, "wlanProbe: Set IRQ error\n"); -+ eFailReason = BUS_SET_IRQ_FAIL; -+ break; -+ } -+ -+ prGlueInfo->i4DevIdx = i4DevIdx; -+ -+ prAdapter = prGlueInfo->prAdapter; -+ -+ prGlueInfo->u4ReadyFlag = 0; -+ -+#if CFG_TCP_IP_CHKSUM_OFFLOAD -+ prAdapter->u4CSUMFlags = (CSUM_OFFLOAD_EN_TX_TCP | CSUM_OFFLOAD_EN_TX_UDP | CSUM_OFFLOAD_EN_TX_IP); -+#endif -+#if CFG_SUPPORT_CFG_FILE -+ { -+ PUINT_8 pucConfigBuf; -+ UINT_32 u4ConfigReadLen; -+ -+ wlanCfgInit(prAdapter, NULL, 0, 0); -+ pucConfigBuf = (PUINT_8) kalMemAlloc(WLAN_CFG_FILE_BUF_SIZE, VIR_MEM_TYPE); -+ u4ConfigReadLen = 0; -+ DBGLOG(INIT, LOUD, "CFG_FILE: Read File...\n"); -+ if (pucConfigBuf) { -+ kalMemZero(pucConfigBuf, WLAN_CFG_FILE_BUF_SIZE); -+ if (kalReadToFile("/data/misc/wifi.cfg", -+ pucConfigBuf, WLAN_CFG_FILE_BUF_SIZE, &u4ConfigReadLen) == 0) { -+ DBGLOG(INIT, LOUD, "CFG_FILE: Read /data/misc/wifi.cfg\n"); -+ -+ } else if (kalReadToFile("/data/misc/wifi/wifi.cfg", -+ pucConfigBuf, WLAN_CFG_FILE_BUF_SIZE, &u4ConfigReadLen) == 0) { -+ DBGLOG(INIT, LOUD, "CFG_FILE: Read /data/misc/wifi/wifi.cfg\n"); -+ } else if (kalReadToFile("/etc/firmware/wifi.cfg", -+ pucConfigBuf, WLAN_CFG_FILE_BUF_SIZE, &u4ConfigReadLen) == 0) { -+ DBGLOG(INIT, LOUD, "CFG_FILE: Read /etc/firmware/wifi.cfg\n"); -+ } -+ -+ if (pucConfigBuf[0] != '\0' && u4ConfigReadLen > 0) -+ wlanCfgInit(prAdapter, pucConfigBuf, u4ConfigReadLen, 0); -+ kalMemFree(pucConfigBuf, VIR_MEM_TYPE, WLAN_CFG_FILE_BUF_SIZE); -+ } /* pucConfigBuf */ -+ } -+#endif -+ /* 4 <5> Start Device */ -+ /* */ -+#if CFG_ENABLE_FW_DOWNLOAD -+ DBGLOG(INIT, TRACE, "start to download firmware...\n"); -+ -+ /* before start adapter, we need to open and load firmware */ -+ { -+ UINT_32 u4FwSize = 0; -+ PVOID prFwBuffer = NULL; -+ P_REG_INFO_T prRegInfo = &prGlueInfo->rRegInfo; -+ -+ /* P_REG_INFO_T prRegInfo = (P_REG_INFO_T) kmalloc(sizeof(REG_INFO_T), GFP_KERNEL); */ -+ kalMemSet(prRegInfo, 0, sizeof(REG_INFO_T)); -+ prRegInfo->u4StartAddress = CFG_FW_START_ADDRESS; -+ prRegInfo->u4LoadAddress = CFG_FW_LOAD_ADDRESS; -+ -+ /* Load NVRAM content to REG_INFO_T */ -+ glLoadNvram(prGlueInfo, prRegInfo); -+#if CFG_SUPPORT_CFG_FILE -+ wlanCfgApply(prAdapter); -+#endif -+ -+ /* kalMemCopy(&prGlueInfo->rRegInfo, prRegInfo, sizeof(REG_INFO_T)); */ -+ -+ prRegInfo->u4PowerMode = CFG_INIT_POWER_SAVE_PROF; -+ prRegInfo->fgEnArpFilter = TRUE; -+ -+ if (kalFirmwareImageMapping(prGlueInfo, &prFwBuffer, &u4FwSize) == NULL) { -+ i4Status = -EIO; -+ DBGLOG(INIT, ERROR, "kalFirmwareImageMapping fail!\n"); -+ goto bailout; -+ } else { -+ -+ if (wlanAdapterStart(prAdapter, prRegInfo, prFwBuffer, -+ u4FwSize) != WLAN_STATUS_SUCCESS) { -+ i4Status = -EIO; -+ } -+ } -+ -+ kalFirmwareImageUnmapping(prGlueInfo, NULL, prFwBuffer); -+ -+bailout: -+ /* kfree(prRegInfo); */ -+ -+ DBGLOG(INIT, TRACE, "download firmware status = %d\n", i4Status); -+ -+ if (i4Status < 0) { -+ GL_HIF_INFO_T *HifInfo; -+ UINT_32 u4FwCnt; -+ -+ DBGLOG(INIT, WARN, "CONNSYS FW CPUINFO:\n"); -+ HifInfo = &prAdapter->prGlueInfo->rHifInfo; -+ for (u4FwCnt = 0; u4FwCnt < 16; u4FwCnt++) -+ DBGLOG(INIT, WARN, "0x%08x ", MCU_REG_READL(HifInfo, CONN_MCU_CPUPCR)); -+ /* CONSYS_REG_READ(CONSYS_CPUPCR_REG) */ -+ -+ /* dump HIF/DMA registers, if fgIsBusAccessFailed is FALSE, otherwise, */ -+ /* dump HIF register may be hung */ -+ if (!fgIsBusAccessFailed) -+ HifRegDump(prGlueInfo->prAdapter); -+/* if (prGlueInfo->rHifInfo.DmaOps->DmaRegDump != NULL) */ -+/* prGlueInfo->rHifInfo.DmaOps->DmaRegDump(&prGlueInfo->rHifInfo); */ -+ eFailReason = ADAPTER_START_FAIL; -+ break; -+ } -+ } -+#else -+ /* P_REG_INFO_T prRegInfo = (P_REG_INFO_T) kmalloc(sizeof(REG_INFO_T), GFP_KERNEL); */ -+ kalMemSet(&prGlueInfo->rRegInfo, 0, sizeof(REG_INFO_T)); -+ P_REG_INFO_T prRegInfo = &prGlueInfo->rRegInfo; -+ -+ /* Load NVRAM content to REG_INFO_T */ -+ glLoadNvram(prGlueInfo, prRegInfo); -+ -+ prRegInfo->u4PowerMode = CFG_INIT_POWER_SAVE_PROF; -+ -+ if (wlanAdapterStart(prAdapter, prRegInfo, NULL, 0) != WLAN_STATUS_SUCCESS) { -+ i4Status = -EIO; -+ eFailReason = ADAPTER_START_FAIL; -+ break; -+ } -+#endif -+ if (FALSE == prAdapter->fgEnable5GBand) -+ prWdev->wiphy->bands[NL80211_BAND_5GHZ] = NULL; -+ -+ prGlueInfo->main_thread = kthread_run(tx_thread, prGlueInfo->prDevHandler, "tx_thread"); -+ kalSetHalted(FALSE); -+#if CFG_SUPPORT_ROAMING_ENC -+ /* adjust roaming threshold */ -+ { -+ WLAN_STATUS rStatus = WLAN_STATUS_FAILURE; -+ CMD_ROAMING_INFO_T rRoamingInfo; -+ UINT_32 u4SetInfoLen = 0; -+ -+ prAdapter->fgIsRoamingEncEnabled = TRUE; -+ -+ /* suggestion from Tsaiyuan.Hsu */ -+ kalMemZero(&rRoamingInfo, sizeof(CMD_ROAMING_INFO_T)); -+ rRoamingInfo.fgIsFastRoamingApplied = TRUE; -+ -+ DBGLOG(INIT, TRACE, "Enable roaming enhance function\n"); -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetRoamingInfo, -+ &rRoamingInfo, sizeof(rRoamingInfo), TRUE, TRUE, TRUE, FALSE, &u4SetInfoLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) -+ DBGLOG(INIT, ERROR, "set roaming advance info fail 0x%x\n", rStatus); -+ } -+#endif /* CFG_SUPPORT_ROAMING_ENC */ -+ -+#if (CFG_SUPPORT_TXR_ENC == 1) -+ /* adjust tx rate switch threshold */ -+ rlmTxRateEnhanceConfig(prGlueInfo->prAdapter); -+#endif /* CFG_SUPPORT_TXR_ENC */ -+ -+ /* set MAC address */ -+ { -+ WLAN_STATUS rStatus = WLAN_STATUS_FAILURE; -+ struct sockaddr MacAddr; -+ UINT_32 u4SetInfoLen = 0; -+ -+ kalMemZero(MacAddr.sa_data, sizeof(MacAddr.sa_data)); -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidQueryCurrentAddr, -+ &MacAddr.sa_data, -+ PARAM_MAC_ADDR_LEN, TRUE, TRUE, TRUE, FALSE, &u4SetInfoLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ DBGLOG(INIT, WARN, "set MAC addr fail 0x%x\n", rStatus); -+ prGlueInfo->u4ReadyFlag = 0; -+ } else { -+ ether_addr_copy(prGlueInfo->prDevHandler->dev_addr, (const u8 *)&(MacAddr.sa_data)); -+ ether_addr_copy(prGlueInfo->prDevHandler->perm_addr, -+ prGlueInfo->prDevHandler->dev_addr); -+ -+ /* card is ready */ -+ prGlueInfo->u4ReadyFlag = 1; -+#if CFG_SHOW_MACADDR_SOURCE -+ DBGLOG(INIT, INFO, "MAC address: %pM ", (&MacAddr.sa_data)); -+#endif -+ } -+ } -+ -+#if CFG_TCP_IP_CHKSUM_OFFLOAD -+ /* set HW checksum offload */ -+ { -+ WLAN_STATUS rStatus = WLAN_STATUS_FAILURE; -+ UINT_32 u4CSUMFlags = CSUM_OFFLOAD_EN_ALL; -+ UINT_32 u4SetInfoLen = 0; -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetCSUMOffload, -+ (PVOID) &u4CSUMFlags, -+ sizeof(UINT_32), FALSE, FALSE, TRUE, FALSE, &u4SetInfoLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) -+ DBGLOG(INIT, WARN, "set HW checksum offload fail 0x%x\n", rStatus); -+ } -+#endif -+ -+ /* 4 <3> Register the card */ -+ DBGLOG(INIT, TRACE, "wlanNetRegister...\n"); -+ i4DevIdx = wlanNetRegister(prWdev); -+ if (i4DevIdx < 0) { -+ i4Status = -ENXIO; -+ DBGLOG(INIT, ERROR, "wlanProbe: Cannot register the net_device context to the kernel\n"); -+ eFailReason = NET_REGISTER_FAIL; -+ break; -+ } -+ -+ wlanRegisterNotifier(); -+ /* 4 <6> Initialize /proc filesystem */ -+#ifdef WLAN_INCLUDE_PROC -+ DBGLOG(INIT, TRACE, "init procfs...\n"); -+ i4Status = procCreateFsEntry(prGlueInfo); -+ if (i4Status < 0) { -+ DBGLOG(INIT, ERROR, "wlanProbe: init procfs failed\n"); -+ eFailReason = PROC_INIT_FAIL; -+ break; -+ } -+#endif /* WLAN_INCLUDE_PROC */ -+ -+#if CFG_ENABLE_BT_OVER_WIFI -+ prGlueInfo->rBowInfo.fgIsNetRegistered = FALSE; -+ prGlueInfo->rBowInfo.fgIsRegistered = FALSE; -+ glRegisterAmpc(prGlueInfo); -+#endif -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ DBGLOG(INIT, TRACE, "wlanSubModInit...\n"); -+ -+ /* wlan is launched */ -+ prGlueInfo->prAdapter->fgIsWlanLaunched = TRUE; -+ /* if p2p module is inserted, notify tx_thread to init p2p network */ -+ if (rSubModHandler[P2P_MODULE].subModInit) -+ wlanSubModInit(prGlueInfo); -+ /* register set_p2p_mode handler to mtk_wmt_wifi */ -+ register_set_p2p_mode_handler(set_p2p_mode_handler); -+#endif -+#if CFG_SPM_WORKAROUND_FOR_HOTSPOT -+ if (glIsChipNeedWakelock(prGlueInfo)) -+ KAL_WAKE_LOCK_INIT(prGlueInfo->prAdapter, &prGlueInfo->prAdapter->rApWakeLock, "WLAN AP"); -+#endif -+ } while (FALSE); -+ -+ if (i4Status != WLAN_STATUS_SUCCESS) { -+ switch (eFailReason) { -+ case PROC_INIT_FAIL: -+ wlanNetUnregister(prWdev); -+ set_bit(GLUE_FLAG_HALT_BIT, &prGlueInfo->ulFlag); -+ /* wake up main thread */ -+ wake_up_interruptible(&prGlueInfo->waitq); -+ /* wait main thread stops */ -+ wait_for_completion_interruptible(&prGlueInfo->rHaltComp); -+ KAL_WAKE_LOCK_DESTROY(prAdapter, &prAdapter->rTxThreadWakeLock); -+ wlanAdapterStop(prAdapter); -+ glBusFreeIrq(prWdev->netdev, *((P_GLUE_INFO_T *) netdev_priv(prWdev->netdev))); -+ KAL_WAKE_LOCK_DESTROY(prAdapter, &prGlueInfo->rAhbIsrWakeLock); -+ wlanNetDestroy(prWdev); -+ break; -+ case NET_REGISTER_FAIL: -+ set_bit(GLUE_FLAG_HALT_BIT, &prGlueInfo->ulFlag); -+ /* wake up main thread */ -+ wake_up_interruptible(&prGlueInfo->waitq); -+ /* wait main thread stops */ -+ wait_for_completion_interruptible(&prGlueInfo->rHaltComp); -+ KAL_WAKE_LOCK_DESTROY(prAdapter, &prAdapter->rTxThreadWakeLock); -+ wlanAdapterStop(prAdapter); -+ glBusFreeIrq(prWdev->netdev, *((P_GLUE_INFO_T *) netdev_priv(prWdev->netdev))); -+ KAL_WAKE_LOCK_DESTROY(prAdapter, &prGlueInfo->rAhbIsrWakeLock); -+ wlanNetDestroy(prWdev); -+ break; -+ case ADAPTER_START_FAIL: -+ glBusFreeIrq(prWdev->netdev, *((P_GLUE_INFO_T *) netdev_priv(prWdev->netdev))); -+ KAL_WAKE_LOCK_DESTROY(prAdapter, &prGlueInfo->rAhbIsrWakeLock); -+ wlanNetDestroy(prWdev); -+ break; -+ case BUS_SET_IRQ_FAIL: -+ KAL_WAKE_LOCK_DESTROY(prAdapter, &prGlueInfo->rAhbIsrWakeLock); -+ wlanNetDestroy(prWdev); -+ break; -+ case NET_CREATE_FAIL: -+ break; -+ case BUS_INIT_FAIL: -+ break; -+ default: -+ break; -+ } -+ } -+#if CFG_ENABLE_WIFI_DIRECT -+ { -+ GLUE_SPIN_LOCK_DECLARATION(); -+ -+ GLUE_ACQUIRE_THE_SPIN_LOCK(&g_p2p_lock); -+ g_u4P2PEnding = 0; -+ GLUE_RELEASE_THE_SPIN_LOCK(&g_p2p_lock); -+ } -+#endif -+#if CFG_SUPPORT_AGPS_ASSIST -+ if (i4Status == WLAN_STATUS_SUCCESS) -+ kalIndicateAgpsNotify(prAdapter, AGPS_EVENT_WLAN_ON, NULL, 0); -+#endif -+#if (CFG_SUPPORT_MET_PROFILING == 1) -+ { -+ int iMetInitRet = WLAN_STATUS_FAILURE; -+ -+ if (i4Status == WLAN_STATUS_SUCCESS) { -+ DBGLOG(INIT, TRACE, "init MET procfs...\n"); -+ iMetInitRet = kalMetInitProcfs(prGlueInfo); -+ if (iMetInitRet < 0) -+ DBGLOG(INIT, ERROR, "wlanProbe: init MET procfs failed\n"); -+ } -+ } -+#endif -+ if (i4Status == WLAN_STATUS_SUCCESS) { -+ /*Init performance monitor structure */ -+ kalPerMonInit(prGlueInfo); -+ /* probe ok */ -+ DBGLOG(INIT, TRACE, "wlanProbe ok\n"); -+ } else { -+ /* we don't care the return value of mtk_wcn_set_connsys_power_off_flag, -+ * because even this function returns -+ * error, we can also call core dump but only core dump failed. */ -+ if (g_IsNeedDoChipReset) -+ mtk_wcn_set_connsys_power_off_flag(0); -+ /* probe failed */ -+ DBGLOG(INIT, ERROR, "wlanProbe failed\n"); -+ } -+ -+ return i4Status; -+} /* end of wlanProbe() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief A method to stop driver operation and release all resources. Following -+* this call, no frame should go up or down through this interface. -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+static VOID wlanRemove(VOID) -+{ -+#define KAL_WLAN_REMOVE_TIMEOUT_MSEC 3000 -+ struct net_device *prDev = NULL; -+ P_WLANDEV_INFO_T prWlandevInfo = NULL; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ P_ADAPTER_T prAdapter = NULL; -+ -+ DBGLOG(INIT, LOUD, "Remove wlan!\n"); -+ -+ /* 4 <0> Sanity check */ -+ ASSERT(u4WlanDevNum <= CFG_MAX_WLAN_DEVICES); -+ if (0 == u4WlanDevNum) { -+ DBGLOG(INIT, ERROR, "0 == u4WlanDevNum\n"); -+ return; -+ } -+ /* unregister set_p2p_mode handler to mtk_wmt_wifi */ -+ register_set_p2p_mode_handler(NULL); -+ -+ prDev = arWlanDevInfo[u4WlanDevNum - 1].prDev; -+ prWlandevInfo = &arWlanDevInfo[u4WlanDevNum - 1]; -+ -+ ASSERT(prDev); -+ if (NULL == prDev) { -+ DBGLOG(INIT, ERROR, "NULL == prDev\n"); -+ return; -+ } -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ ASSERT(prGlueInfo); -+ if (NULL == prGlueInfo) { -+ DBGLOG(INIT, ERROR, "NULL == prGlueInfo\n"); -+ free_netdev(prDev); -+ return; -+ } -+ -+ kalPerMonDestroy(prGlueInfo); -+#if CFG_ENABLE_WIFI_DIRECT -+ /* avoid remove & p2p off command simultaneously */ -+ { -+ BOOLEAN fgIsP2POnOffing; -+ -+ GLUE_SPIN_LOCK_DECLARATION(); -+ -+ GLUE_ACQUIRE_THE_SPIN_LOCK(&g_p2p_lock); -+ g_u4P2PEnding = 1; -+ fgIsP2POnOffing = g_u4P2POnOffing; -+ GLUE_RELEASE_THE_SPIN_LOCK(&g_p2p_lock); -+ -+ DBGLOG(INIT, TRACE, "waiting for fgIsP2POnOffing...\n"); -+ -+ /* History: cannot use down() here, sometimes we cannot come back here */ -+ /* waiting for p2p off command finishes, we cannot skip the remove */ -+ while (1) { -+ if (fgIsP2POnOffing == 0) -+ break; -+ GLUE_ACQUIRE_THE_SPIN_LOCK(&g_p2p_lock); -+ fgIsP2POnOffing = g_u4P2POnOffing; -+ GLUE_RELEASE_THE_SPIN_LOCK(&g_p2p_lock); -+ } -+ } -+#endif -+ -+#if CFG_ENABLE_BT_OVER_WIFI -+ if (prGlueInfo->rBowInfo.fgIsNetRegistered) { -+ bowNotifyAllLinkDisconnected(prGlueInfo->prAdapter); -+ /* wait 300ms for BoW module to send deauth */ -+ kalMsleep(300); -+ } -+#endif -+ -+ /* 4 <1> Stopping handling interrupt and free IRQ */ -+ DBGLOG(INIT, TRACE, "free IRQ...\n"); -+ glBusFreeIrq(prDev, *((P_GLUE_INFO_T *) netdev_priv(prDev))); -+ -+ kalMemSet(&(prGlueInfo->prAdapter->rWlanInfo), 0, sizeof(WLAN_INFO_T)); -+ -+ kalSetHalted(TRUE); /* before flush_delayed_work() */ -+ if (fgIsWorkMcStart == TRUE) { -+ DBGLOG(INIT, TRACE, "flush_delayed_work...\n"); -+ flush_delayed_work(&workq); /* flush_delayed_work_sync is deprecated */ -+ } -+ -+ flush_delayed_work(&sched_workq); -+ -+ DBGLOG(INIT, INFO, "down g_halt_sem...\n"); -+ kalHaltLock(KAL_WLAN_REMOVE_TIMEOUT_MSEC); -+#if CFG_SPM_WORKAROUND_FOR_HOTSPOT -+ if (glIsChipNeedWakelock(prGlueInfo)) -+ KAL_WAKE_LOCK_DESTROY(prGlueInfo->prAdapter, &prGlueInfo->prAdapter->rApWakeLock); -+#endif -+ -+/* flush_delayed_work_sync(&workq); */ -+/* flush_delayed_work(&workq); */ /* flush_delayed_work_sync is deprecated */ -+ -+ /* 4 <2> Mark HALT, notify main thread to stop, and clean up queued requests */ -+/* prGlueInfo->u4Flag |= GLUE_FLAG_HALT; */ -+ set_bit(GLUE_FLAG_HALT_BIT, &prGlueInfo->ulFlag); -+ DBGLOG(INIT, TRACE, "waiting for tx_thread stop...\n"); -+ -+ /* wake up main thread */ -+ wake_up_interruptible(&prGlueInfo->waitq); -+ -+ DBGLOG(INIT, TRACE, "wait_for_completion_interruptible\n"); -+ -+ /* wait main thread stops */ -+ wait_for_completion_interruptible(&prGlueInfo->rHaltComp); -+ -+ DBGLOG(INIT, TRACE, "mtk_sdiod stopped\n"); -+ -+ KAL_WAKE_LOCK_DESTROY(prGlueInfo->prAdapter, &prGlueInfo->prAdapter->rTxThreadWakeLock); -+ KAL_WAKE_LOCK_DESTROY(prGlueInfo->prAdapter, &prGlueInfo->rAhbIsrWakeLock); -+ -+ /* prGlueInfo->rHifInfo.main_thread = NULL; */ -+ prGlueInfo->main_thread = NULL; -+ -+#if CFG_ENABLE_BT_OVER_WIFI -+ if (prGlueInfo->rBowInfo.fgIsRegistered) -+ glUnregisterAmpc(prGlueInfo); -+#endif -+ -+ /* 4 <3> Remove /proc filesystem. */ -+#ifdef WLAN_INCLUDE_PROC -+ procRemoveProcfs(); -+#endif /* WLAN_INCLUDE_PROC */ -+ -+#if (CFG_SUPPORT_MET_PROFILING == 1) -+ kalMetRemoveProcfs(); -+#endif -+ -+ /* Force to do DMA reset */ -+ DBGLOG(INIT, TRACE, "glResetHif\n"); -+ glResetHif(prGlueInfo); -+ -+ /* 4 <4> wlanAdapterStop */ -+ prAdapter = prGlueInfo->prAdapter; -+#if CFG_SUPPORT_AGPS_ASSIST -+ kalIndicateAgpsNotify(prAdapter, AGPS_EVENT_WLAN_OFF, NULL, 0); -+#endif -+ -+ wlanAdapterStop(prAdapter); -+ DBGLOG(INIT, TRACE, "Number of Stalled Packets = %d\n", prGlueInfo->i4TxPendingFrameNum); -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ prGlueInfo->prAdapter->fgIsWlanLaunched = FALSE; -+ if (prGlueInfo->prAdapter->fgIsP2PRegistered) { -+ DBGLOG(INIT, TRACE, "p2pNetUnregister...\n"); -+#if !CFG_SUPPORT_PERSIST_NETDEV -+ p2pNetUnregister(prGlueInfo, FALSE); -+#endif -+ DBGLOG(INIT, INFO, "p2pRemove...\n"); -+ p2pRemove(prGlueInfo); -+ } -+#endif -+ -+ /* 4 <5> Release the Bus */ -+ glBusRelease(prDev); -+ -+ kalHaltUnlock(); -+ wlanDebugUninit(); -+ /* 4 <6> Unregister the card */ -+ wlanNetUnregister(prDev->ieee80211_ptr); -+ -+ /* 4 <7> Destroy the device */ -+ wlanNetDestroy(prDev->ieee80211_ptr); -+ prDev = NULL; -+ -+ DBGLOG(INIT, LOUD, "wlanUnregisterNotifier...\n"); -+ wlanUnregisterNotifier(); -+ -+ DBGLOG(INIT, INFO, "wlanRemove ok\n"); -+} /* end of wlanRemove() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Driver entry point when the driver is configured as a Linux Module, and -+* is called once at module load time, by the user-level modutils -+* application: insmod or modprobe. -+* -+* \retval 0 Success -+*/ -+/*----------------------------------------------------------------------------*/ -+/* 1 Module Entry Point */ -+static int initWlan(void) -+{ -+ int ret = 0, i; -+#if DBG -+ for (i = 0; i < DBG_MODULE_NUM; i++) -+ aucDebugModule[i] = DBG_CLASS_MASK; /* enable all */ -+#else -+ /* Initial debug level is D1 */ -+ for (i = 0; i < DBG_MODULE_NUM; i++) -+ aucDebugModule[i] = DBG_CLASS_ERROR | DBG_CLASS_WARN | DBG_CLASS_INFO | DBG_CLASS_STATE; -+#endif /* DBG */ -+ DBGLOG(INIT, INFO, "initWlan\n"); -+ -+ spin_lock_init(&g_p2p_lock); -+ -+ /* memory pre-allocation */ -+ kalInitIOBuffer(); -+ procInitFs(); -+ createWirelessDevice(); -+ if (gprWdev) -+ glP2pCreateWirelessDevice((P_GLUE_INFO_T) wiphy_priv(gprWdev->wiphy)); -+ -+ ret = ((glRegisterBus(wlanProbe, wlanRemove) == WLAN_STATUS_SUCCESS) ? 0 : -EIO); -+ -+ if (ret == -EIO) { -+ kalUninitIOBuffer(); -+ return ret; -+ } -+#if (CFG_CHIP_RESET_SUPPORT) -+ glResetInit(); -+#endif -+ -+ /* register set_dbg_level handler to mtk_wmt_wifi */ -+ register_set_dbg_level_handler(set_dbg_level_handler); -+ -+ /* Set the initial DEBUG CLASS of each module */ -+ return ret; -+} /* end of initWlan() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Driver exit point when the driver as a Linux Module is removed. Called -+* at module unload time, by the user level modutils application: rmmod. -+* This is our last chance to clean up after ourselves. -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+/* 1 Module Leave Point */ -+static VOID exitWlan(void) -+{ -+ DBGLOG(INIT, INFO, "exitWlan\n"); -+ -+ /* unregister set_dbg_level handler to mtk_wmt_wifi */ -+ register_set_dbg_level_handler(NULL); -+ -+#if CFG_CHIP_RESET_SUPPORT -+ glResetUninit(); -+#endif -+ destroyWirelessDevice(); -+ glP2pDestroyWirelessDevice(); -+ -+ glUnregisterBus(wlanRemove); -+ -+ /* free pre-allocated memory */ -+ kalUninitIOBuffer(); -+ -+ DBGLOG(INIT, INFO, "exitWlan\n"); -+ procUninitProcFs(); -+ -+} /* end of exitWlan() */ -+ -+#ifdef MTK_WCN_BUILT_IN_DRIVER -+ -+int mtk_wcn_wlan_gen2_init(void) -+{ -+ return initWlan(); -+} -+EXPORT_SYMBOL(mtk_wcn_wlan_gen2_init); -+ -+void mtk_wcn_wlan_gen2_exit(void) -+{ -+ return exitWlan(); -+} -+EXPORT_SYMBOL(mtk_wcn_wlan_gen2_exit); -+ -+#else -+ -+module_init(initWlan); -+module_exit(exitWlan); -+ -+#endif -+ -+MODULE_AUTHOR(NIC_AUTHOR); -+MODULE_DESCRIPTION(NIC_DESC); -+MODULE_SUPPORTED_DEVICE(NIC_NAME); -+MODULE_LICENSE("GPL"); -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_kal.c b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_kal.c -new file mode 100644 -index 000000000000..e8f4f76960a5 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_kal.c -@@ -0,0 +1,4801 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux/gl_kal.c#3 -+*/ -+ -+/*! \file gl_kal.c -+ \brief GLUE Layer will export the required procedures here for internal driver stack. -+ -+ This file contains all routines which are exported from GLUE Layer to internal -+ driver stack. -+*/ -+ -+/* -+** Log: gl_kal.c -+** -+** 08 20 2012 yuche.tsai -+** NULL -+** Fix possible KE issue. -+ * -+ * 07 17 2012 yuche.tsai -+ * NULL -+ * Let netdev bring up. -+ * -+ * 07 17 2012 yuche.tsai -+ * NULL -+ * Compile no error before trial run. -+ * -+ * 06 13 2012 yuche.tsai -+ * NULL -+ * Update maintrunk driver. -+ * Add support for driver compose assoc request frame. -+ * -+ * 05 31 2012 terry.wu -+ * NULL -+ * . -+ * -+ * 03 26 2012 cp.wu -+ * [WCXRP00001187] [MT6620 Wi-Fi][Driver][Android] Add error handling while firmware image doesn't exist -+ * invoke put_cred() after get_current_cred() calls. -+ * -+ * 03 07 2012 yuche.tsai -+ * NULL -+ * Fix compile error when WiFi Direct is off. -+ * -+ * 03 02 2012 terry.wu -+ * NULL -+ * Snc CFG80211 modification for ICS migration from branch 2.2. -+ * -+ * 02 20 2012 cp.wu -+ * [WCXRP00001187] [MT6620 Wi-Fi][Driver][Android] Add error handling while firmware image doesn't exist -+ * do not need to invoke free() while firmware image file doesn't exist -+ * -+ * 01 05 2012 wh.su -+ * [WCXRP00001153] [MT6620 Wi-Fi][Driver] Adding the get_ch_list and set_tx_power proto type function -+ * Adding the related ioctl / wlan oid function to set the Tx power cfg. -+ * -+ * 01 02 2012 wh.su -+ * [WCXRP00001153] [MT6620 Wi-Fi][Driver] Adding the get_ch_list and set_tx_power proto type function -+ * Adding the proto type function for set_int set_tx_power and get int get_ch_list. -+ * -+ * 11 21 2011 cp.wu -+ * [WCXRP00001118] [MT6620 Wi-Fi][Driver] Corner case protections to pass Monkey testing -+ * 1. wlanoidQueryBssIdList might be passed with a non-zero length but a NULL pointer of buffer -+ * add more checking for such cases -+ * -+ * 2. kalSendComplete() might be invoked with a packet belongs to P2P network right after P2P is unregistered. -+ * add some tweaking to protect such cases because that net device has become invalid. -+ * -+ * 11 18 2011 yuche.tsai -+ * NULL -+ * CONFIG P2P support RSSI query, default turned off. -+ * -+ * 11 16 2011 yuche.tsai -+ * NULL -+ * Avoid using work thread. -+ * -+ * 11 10 2011 cp.wu -+ * [WCXRP00001098] [MT6620 Wi-Fi][Driver] Replace printk by DBG LOG macros in linux porting layer -+ * 1. eliminaite direct calls to printk in porting layer. -+ * 2. replaced by DBGLOG, which would be XLOG on ALPS platforms. -+ * -+ * 10 12 2011 wh.su -+ * [WCXRP00001036] [MT6620 Wi-Fi][Driver][FW] Adding the 802.11w code for MFP -+ * adding the 802.11w related function and define . -+ * -+ * 09 23 2011 yuche.tsai -+ * [WCXRP00000998] [Volunteer Patch][WiFi Direct][FW] P2P Social Channel & country domain issue -+ * Regulation domain feature check in. -+ * -+ * 08 12 2011 cp.wu -+ * [WCXRP00000913] [MT6620 Wi-Fi] create repository of source code dedicated for MT6620 E6 ASIC -+ * load WIFI_RAM_CODE_E6 for MT6620 E6 ASIC. -+ * -+ * 07 18 2011 chinghwa.yu -+ * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm -+ * Add CMD/Event for RDD and BWCS. -+ * -+ * 06 13 2011 eddie.chen -+ * [WCXRP00000779] [MT6620 Wi-Fi][DRV] Add tx rx statistics in linux and use netif_rx_ni -+ * Add tx rx statistics and netif_rx_ni. -+ * -+ * 04 15 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Add BOW short range mode. -+ * -+ * 04 12 2011 cp.wu -+ * [WCXRP00000635] [MT6620 Wi-Fi][Driver] Clear pending security frames when QM clear pending data frames for dedicated -+ * network type -+ * clear pending security frames for dedicated network type when BSS is being deactivated/disconnected -+ * -+ * 04 08 2011 cp.wu -+ * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer -+ * correct i4TxPendingFrameNum decreasing. -+ * -+ * 03 23 2011 cp.wu -+ * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer -+ * apply multi-queue operation only for linux kernel > 2.6.26 -+ * -+ * 03 21 2011 cp.wu -+ * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer -+ * portability for compatible with linux 2.6.12. -+ * -+ * 03 21 2011 cp.wu -+ * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer -+ * improve portability for awareness of early version of linux kernel and wireless extension. -+ * -+ * 03 18 2011 cp.wu -+ * [WCXRP00000562] [MT6620 Wi-Fi][Driver] I/O buffer pre-allocation to avoid physically continuous memory shortage -+ * after system running for a long period -+ * refix ... -+ * -+ * 03 18 2011 cp.wu -+ * [WCXRP00000562] [MT6620 Wi-Fi][Driver] I/O buffer pre-allocation to avoid physically continuous memory shortage -+ * after system running for a long period -+ * correct compiling warning/error. -+ * -+ * 03 18 2011 cp.wu -+ * [WCXRP00000562] [MT6620 Wi-Fi][Driver] I/O buffer pre-allocation to avoid physically continuous memory shortage -+ * after system running for a long period -+ * add more robust fault tolerance design when pre-allocation failed. (rarely happen) -+ * -+ * 03 17 2011 cp.wu -+ * [WCXRP00000562] [MT6620 Wi-Fi][Driver] I/O buffer pre-allocation to avoid physically continuous memory shortage -+ * after system running for a long period -+ * use pre-allocated buffer for storing enhanced interrupt response as well -+ * -+ * 03 16 2011 cp.wu -+ * [WCXRP00000562] [MT6620 Wi-Fi][Driver] I/O buffer pre-allocation to avoid physically continuous memory shortage -+ * after system running for a long period -+ * 1. pre-allocate physical continuous buffer while module is being loaded -+ * 2. use pre-allocated physical continuous buffer for TX/RX DMA transfer -+ * -+ * The windows part remained the same as before, but added similar APIs to hide the difference. -+ * -+ * 03 15 2011 cp.wu -+ * [WCXRP00000559] [MT6620 Wi-Fi][Driver] Combine TX/RX DMA buffers into a single one to reduce physically continuous -+ * memory consumption -+ * 1. deprecate CFG_HANDLE_IST_IN_SDIO_CALLBACK -+ * 2. Use common coalescing buffer for both TX/RX directions -+ * -+ * -+ * 03 14 2011 jeffrey.chang -+ * [WCXRP00000546] [MT6620 Wi-Fi][MT6620 Wi-Fi][Driver] fix kernel build warning message -+ * fix kernel build warning message -+ * -+ * 03 07 2011 terry.wu -+ * [WCXRP00000521] [MT6620 Wi-Fi][Driver] Remove non-standard debug message -+ * Toggle non-standard debug messages to comments. -+ * -+ * 03 06 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Sync BOW Driver to latest person development branch version.. -+ * -+ * 03 03 2011 jeffrey.chang -+ * [WCXRP00000512] [MT6620 Wi-Fi][Driver] modify the net device relative functions to support the H/W multiple queue -+ * support concurrent network -+ * -+ * 03 03 2011 jeffrey.chang -+ * [WCXRP00000512] [MT6620 Wi-Fi][Driver] modify the net device relative functions to support the H/W multiple queue -+ * modify net device relative functions to support multiple H/W queues -+ * -+ * 03 02 2011 cp.wu -+ * [WCXRP00000503] [MT6620 Wi-Fi][Driver] Take RCPI brought by association response as initial RSSI right after -+ * connection is built. -+ * use RCPI brought by ASSOC-RESP after connection is built as initial RCPI to avoid using a uninitialized MAC-RX RCPI. -+ * -+ * 02 21 2011 cp.wu -+ * [WCXRP00000482] [MT6620 Wi-Fi][Driver] Simplify logic for checking NVRAM existence in driver domain -+ * simplify logic for checking NVRAM existence only once. -+ * -+ * 01 24 2011 cp.wu -+ * [WCXRP00000382] [MT6620 Wi-Fi][Driver] Track forwarding packet number with notifying tx thread for serving -+ * 1. add an extra counter for tracking pending forward frames. -+ * 2. notify TX service thread as well when there is pending forward frame -+ * 3. correct build errors leaded by introduction of Wi-Fi direct separation module -+ * -+ * 01 19 2011 cp.wu -+ * [WCXRP00000371] [MT6620 Wi-Fi][Driver] make linux glue layer portable for Android 2.3.1 with Linux 2.6.35.7 -+ * add compile option to check linux version 2.6.35 for different usage of system API to improve portability -+ * -+ * 01 12 2011 cp.wu -+ * [WCXRP00000357] [MT6620 Wi-Fi][Driver][Bluetooth over Wi-Fi] add another net device interface for BT AMP -+ * implementation of separate BT_OVER_WIFI data path. -+ * -+ * 01 10 2011 cp.wu -+ * [WCXRP00000349] [MT6620 Wi-Fi][Driver] make kalIoctl() of linux port as a thread safe API to avoid potential issues -+ * due to multiple access -+ * use mutex to protect kalIoctl() for thread safe. -+ * -+ * 11 26 2010 cp.wu -+ * [WCXRP00000209] [MT6620 Wi-Fi][Driver] Modify NVRAM checking mechanism to warning only with necessary data field -+ * checking -+ * 1. NVRAM error is now treated as warning only, thus normal operation is still available but extra scan result used -+ * to indicate user is attached -+ * 2. DPD and TX-PWR are needed fields from now on, if these 2 fields are not available then warning message is shown -+ * -+ * 11 04 2010 wh.su -+ * [WCXRP00000164] [MT6620 Wi-Fi][Driver] Support the p2p random SSID -+ * adding the p2p random ssid support. -+ * -+ * 11 02 2010 jeffrey.chang -+ * [WCXRP00000145] [MT6620 Wi-Fi][Driver] fix issue of byte endian in packet classifier which discards BoW packets -+ * . -+ * -+ * 11 01 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000150] [MT6620 Wi-Fi][Driver] -+ * Add implementation for querying current TX rate from firmware auto rate module -+ * 1) Query link speed (TX rate) from firmware directly with buffering mechanism to reduce overhead -+ * 2) Remove CNM CH-RECOVER event handling -+ * 3) cfg read/write API renamed with kal prefix for unified naming rules. -+ * -+ * 11 01 2010 yarco.yang -+ * [WCXRP00000149] [MT6620 WI-Fi][Driver]Fine tune performance on MT6516 platform -+ * Add code to run WlanIST in SDIO callback. -+ * -+ * 10 26 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000137] [MT6620 Wi-Fi] [FW] -+ * Support NIC capability query command -+ * 1) update NVRAM content template to ver 1.02 -+ * 2) add compile option for querying NIC capability (default: off) -+ * 3) modify AIS 5GHz support to run-time option, which could be turned on by registry or NVRAM setting -+ * 4) correct auto-rate compiler error under linux (treat warning as error) -+ * 5) simplify usage of NVRAM and REG_INFO_T -+ * 6) add version checking between driver and firmware -+ * -+ * 10 25 2010 jeffrey.chang -+ * [WCXRP00000129] [MT6620] [Driver] Kernel panic when rmmod module on Andriod platform -+ * Remove redundant code which cause mismatch of power control release -+ * -+ * 10 25 2010 jeffrey.chang -+ * [WCXRP00000129] [MT6620] [Driver] Kernel panic when rmmod module on Andriod platform -+ * Remove redundant GLUE_HALT condfition to avoid unmatched release of power control -+ * -+ * 10 18 2010 jeffrey.chang -+ * [WCXRP00000116] [MT6620 Wi-Fi][Driver] Refine the set_scan ioctl to resolve the Android UI hanging issue -+ * refine the scan ioctl to prevent hanging of Android UI -+ * -+ * 10 18 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000086] [MT6620 Wi-Fi][Driver] -+ * The mac address is all zero at android -+ * complete implementation of Android NVRAM access -+ * -+ * 10 06 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check -+ * if there is NVRAM, then use MAC address on NVRAM as default MAC address. -+ * -+ * 10 06 2010 cp.wu -+ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning -+ * code reorganization to improve isolation between GLUE and CORE layers. -+ * -+ * 10 05 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check -+ * 1) add NVRAM access API -+ * 2) fake scanning result when NVRAM doesn't exist and/or version mismatch. (off by compiler option) -+ * 3) add OID implementation for NVRAM read/write service -+ * -+ * 09 21 2010 cp.wu -+ * [WCXRP00000053] [MT6620 Wi-Fi][Driver] Reset incomplete and might leads to BSOD when entering RF test with AIS -+ * associated -+ * Do a complete reset with STA-REC null checking for RF test re-entry -+ * -+ * 09 21 2010 kevin.huang -+ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning -+ * Eliminate Linux Compile Warning -+ * -+ * 09 07 2010 wh.su -+ * NULL -+ * adding the code for beacon/probe req/ probe rsp wsc ie at p2p. -+ * -+ * 09 03 2010 kevin.huang -+ * NULL -+ * Refine #include sequence and solve recursive/nested #include issue -+ * -+ * 08 30 2010 cp.wu -+ * NULL -+ * API added: nicTxPendingPackets(), for simplifying porting layer -+ * -+ * 08 20 2010 yuche.tsai -+ * NULL -+ * Support second interface indicate when enabling P2P. -+ * -+ * 08 18 2010 yarco.yang -+ * NULL -+ * 1. Fixed HW checksum offload function not work under Linux issue. -+ * 2. Add debug message. -+ * -+ * 08 16 2010 jeffrey.chang -+ * NULL -+ * remove redundant code which cause kernel panic -+ * -+ * 08 16 2010 cp.wu -+ * NULL -+ * P2P packets are now marked when being queued into driver, and identified later without checking MAC address -+ * -+ * 08 02 2010 jeffrey.chang -+ * NULL -+ * 1) modify tx service thread to avoid busy looping -+ * 2) add spin lock declartion for linux build -+ * -+ * 07 29 2010 cp.wu -+ * NULL -+ * simplify post-handling after TX_DONE interrupt is handled. -+ * -+ * 07 28 2010 jeffrey.chang -+ * NULL -+ * 1) remove unused spinlocks -+ * 2) enable encyption ioctls -+ * 3) fix scan ioctl which may cause supplicant to hang -+ * -+ * 07 23 2010 cp.wu -+ * -+ * 1) re-enable AIS-FSM beacon timeout handling. -+ * 2) scan done API revised -+ * -+ * 07 23 2010 jeffrey.chang -+ * -+ * add new KAL api -+ * -+ * 07 23 2010 jeffrey.chang -+ * -+ * bug fix: allocate regInfo when disabling firmware download -+ * -+ * 07 23 2010 jeffrey.chang -+ * -+ * use glue layer api to decrease or increase counter atomically -+ * -+ * 07 22 2010 jeffrey.chang -+ * -+ * modify tx thread and remove some spinlock -+ * -+ * 07 22 2010 jeffrey.chang -+ * -+ * use different spin lock for security frame -+ * -+ * 07 22 2010 jeffrey.chang -+ * -+ * add new spinlock -+ * -+ * 07 19 2010 jeffrey.chang -+ * -+ * add spinlock for pending security frame count -+ * -+ * 07 19 2010 jeffrey.chang -+ * -+ * adjust the timer unit to microsecond -+ * -+ * 07 19 2010 jeffrey.chang -+ * -+ * timer should return value greater than zero -+ * -+ * 07 19 2010 jeffrey.chang -+ * -+ * add kal api for scanning done -+ * -+ * 07 19 2010 jeffrey.chang -+ * -+ * modify cmd/data path for new design -+ * -+ * 07 19 2010 jeffrey.chang -+ * -+ * add new kal api -+ * -+ * 07 19 2010 jeffrey.chang -+ * -+ * for linux driver migration -+ * -+ * 07 19 2010 jeffrey.chang -+ * -+ * Linux port modification -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 23 2010 yarco.yang -+ * [WPD00003837][MT6620]Data Path Refine -+ * Merge g_arStaRec[] into adapter->arStaRec[] -+ * -+ * 06 21 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * change MAC address updating logic. -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 06 01 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * remove unused files. -+ * -+ * 05 29 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * fix private ioctl for rftest -+ * -+ * 05 29 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * workaround for fixing request_firmware() failure on android 2.1 -+ * -+ * 05 28 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * fix kernel panic when debug mode enabled -+ * -+ * 05 26 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * 1) Modify set mac address code -+ * 2) remove power management macro -+ * -+ * 05 17 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * 1) add timeout handler mechanism for pending command packets -+ * 2) add p2p add/removal key -+ * -+ * 05 14 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * Disable network interface after disassociation -+ * -+ * 05 10 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * fill network type field while doing frame identification. -+ * -+ * 05 07 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * prevent supplicant accessing driver during resume -+ * -+ * 04 27 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * identify BT Over Wi-Fi Security frame and mark it as 802.1X frame -+ * -+ * 04 27 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * 1) fix firmware download bug -+ * 2) remove query statistics for acelerating firmware download -+ * -+ * 04 27 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * follow Linux's firmware framework, and remove unused kal API -+ * -+ * 04 22 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * -+ * 1) modify rx path code for supporting Wi-Fi direct -+ * 2) modify config.h since Linux dont need to consider retaining packet -+ * -+ * 04 21 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * add for private ioctl support -+ * -+ * 04 15 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * change firmware name -+ * -+ * 04 14 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * flush pending TX packets while unloading driver -+ * -+ * 04 14 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * Set driver own before handling cmd queue -+ * -+ * 04 14 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * 1) prGlueInfo->pvInformationBuffer and prGlueInfo->u4InformationBufferLength are no longer used -+ * 2) fix ioctl -+ * -+ * 04 14 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * information buffer for query oid/ioctl is now buffered in prCmdInfo -+ * * * * * * * instead of glue-layer variable to improve multiple oid/ioctl capability -+ * -+ * 04 13 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * add framework for BT-over-Wi-Fi support. -+ * * * * * * * * * * * * * * * * * * 1) prPendingCmdInfo is replaced by queue for multiple handler -+ * * * * * * * * * * * * * * * * * * capability -+ * * * * * * * * * * * * * * * * * * 2) command sequence number is now increased atomically -+ * * * * * * * * * * * * * * * * * * 3) private data could be hold and taken use for other purpose -+ * -+ * 04 09 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * fix spinlock usage -+ * -+ * 04 09 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * add spinlock for i4TxPendingFrameNum access -+ * -+ * 04 09 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * 1) add spinlock -+ * * 2) add KAPI for handling association info -+ * -+ * 04 09 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * fix spinlock usage -+ * -+ * 04 09 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * adding firmware download KAPI -+ * -+ * 04 07 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * Set MAC address from firmware -+ * -+ * 04 07 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1. free cmdinfo after command is emiited. -+ * 2. for BoW frames, user priority is extracted from sk_buff directly. -+ * -+ * 04 07 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * finish non-glue layer access to glue variables -+ * -+ * 04 07 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * accessing to firmware load/start address, and access to OID handling information -+ * * * are now handled in glue layer -+ * -+ * 04 07 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * rWlanInfo should be placed at adapter rather than glue due to most operations -+ * * * * * * * are done in adapter layer. -+ * -+ * 04 07 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * eliminate direct access to prGlueInfo->eParamMediaStateIndicated from non-glue layer -+ * -+ * 04 06 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * (1)deliver the kalOidComplete status to upper layer -+ * (2) fix spin lock -+ * -+ * 04 06 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * add KAL API: kalFlushPendingTxPackets(), and take use of the API -+ * -+ * 04 06 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * eliminate direct access to prGlueInfo->rWlanInfo.eLinkAttr.ucMediaStreamMode from non-glue layer. -+ * -+ * 04 06 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * add timeout check in the kalOidComplete -+ * -+ * 04 06 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * improve none-glue code portability -+ * -+ * 04 06 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * code refine: fgTestMode should be at adapter rather than glue due to the device/fw is also involved -+ * -+ * 04 06 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * eliminate direct access for prGlueInfo->fgIsCardRemoved in non-glue layer -+ * -+ * 04 06 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) for some OID, never do timeout expiration -+ * * * 2) add 2 kal API for later integration -+ * -+ * 04 06 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * raising the priority of processing interrupt -+ * -+ * 04 01 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * Bug fix: the tx thread will cause starvation of MMC thread, and the interrupt will never come in -+ * -+ * 03 30 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * emulate NDIS Pending OID facility -+ * -+ * 03 28 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * adding secondary command queue for improving non-glue code portability -+ * -+ * 03 26 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * [WPD00003826] Initial import for Linux port -+ * adding firmware download kal api -+ * -+ * 03 25 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * add Bluetooth-over-Wifi frame header check -+ * -+ * 03 24 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * initial import for Linux port -+** \main\maintrunk.MT5921\50 2009-09-28 20:19:08 GMT mtk01090 -+** Add private ioctl to carry OID structures. Restructure public/private ioctl interfaces to Linux kernel. -+** \main\maintrunk.MT5921\49 2009-08-18 22:56:44 GMT mtk01090 -+** Add Linux SDIO (with mmc core) support. -+** Add Linux 2.6.21, 2.6.25, 2.6.26. -+** Fix compile warning in Linux. -+** \main\maintrunk.MT5921\48 2009-06-23 23:18:58 GMT mtk01090 -+** Add build option BUILD_USE_EEPROM and compile option CFG_SUPPORT_EXT_CONFIG for NVRAM support -+** \main\maintrunk.MT5921\47 2008-11-19 11:55:43 GMT mtk01088 -+** fixed some lint warning, and rename some variable with pre-fix to avoid the misunderstanding -+** \main\maintrunk.MT5921\46 2008-09-02 21:07:42 GMT mtk01461 -+** Remove ASSERT(pvBuf) in kalIndicateStatusAndComplete(), this parameter can be NULL -+** \main\maintrunk.MT5921\45 2008-08-29 16:03:21 GMT mtk01088 -+** remove non-used code for code review, add assert check -+** \main\maintrunk.MT5921\44 2008-08-21 00:32:49 GMT mtk01461 -+** \main\maintrunk.MT5921\43 2008-05-30 20:27:02 GMT mtk01461 -+** Rename KAL function -+** \main\maintrunk.MT5921\42 2008-05-30 15:47:29 GMT mtk01461 -+** \main\maintrunk.MT5921\41 2008-05-30 15:13:04 GMT mtk01084 -+** rename wlanoid -+** \main\maintrunk.MT5921\40 2008-05-29 14:15:14 GMT mtk01084 -+** remove un-used KAL function -+** \main\maintrunk.MT5921\39 2008-05-03 15:17:30 GMT mtk01461 -+** Move Query Media Status to GLUE -+** \main\maintrunk.MT5921\38 2008-04-24 11:59:44 GMT mtk01461 -+** change awake queue threshold and remove code which mark #if 0 -+** \main\maintrunk.MT5921\37 2008-04-17 23:06:35 GMT mtk01461 -+** Add iwpriv support for AdHocMode setting -+** \main\maintrunk.MT5921\36 2008-04-08 15:38:56 GMT mtk01084 -+** add KAL function to setting pattern search function enable/ disable -+** \main\maintrunk.MT5921\35 2008-04-01 23:53:13 GMT mtk01461 -+** Add comment -+** \main\maintrunk.MT5921\34 2008-03-26 15:36:48 GMT mtk01461 -+** Add update MAC Address for Linux -+** \main\maintrunk.MT5921\33 2008-03-18 11:49:34 GMT mtk01084 -+** update function for initial value access -+** \main\maintrunk.MT5921\32 2008-03-18 10:25:22 GMT mtk01088 -+** use kal update associate request at linux -+** \main\maintrunk.MT5921\31 2008-03-06 23:43:08 GMT mtk01385 -+** 1. add Query Registry Mac address function. -+** \main\maintrunk.MT5921\30 2008-02-26 09:47:57 GMT mtk01084 -+** modify KAL set network address/ checksum offload part -+** \main\maintrunk.MT5921\29 2008-02-12 23:26:53 GMT mtk01461 -+** Add debug option - Packet Order for Linux -+** \main\maintrunk.MT5921\28 2008-01-09 17:54:43 GMT mtk01084 -+** modify the argument of kalQueryPacketInfo() -+** \main\maintrunk.MT5921\27 2007-12-24 16:02:03 GMT mtk01425 -+** 1. Revise csum offload -+** \main\maintrunk.MT5921\26 2007-11-30 17:03:36 GMT mtk01425 -+** 1. Fix bugs -+** -+** \main\maintrunk.MT5921\25 2007-11-29 01:57:17 GMT mtk01461 -+** Fix Windows RX multiple packet retain problem -+** \main\maintrunk.MT5921\24 2007-11-20 11:24:07 GMT mtk01088 -+** CR90, not doing the netif_carrier_off to let supplicant 1x pkt can be rcv at hardstattXmit -+** \main\maintrunk.MT5921\23 2007-11-09 16:36:44 GMT mtk01425 -+** 1. Modify for CSUM offloading with Tx Fragment -+** \main\maintrunk.MT5921\22 2007-11-07 18:37:39 GMT mtk01461 -+** Add Tx Fragmentation Support -+** \main\maintrunk.MT5921\21 2007-11-06 19:34:06 GMT mtk01088 -+** add the WPS code, indicate the mgmt frame to upper layer -+** \main\maintrunk.MT5921\20 2007-11-02 01:03:21 GMT mtk01461 -+** Unify TX Path for Normal and IBSS Power Save + IBSS neighbor learning -+** \main\maintrunk.MT5921\19 2007-10-30 11:59:38 GMT MTK01425 -+** 1. Update wlanQueryInformation -+** \main\maintrunk.MT5921\18 2007-10-30 10:44:57 GMT mtk01425 -+** 1. Refine multicast list code -+** 2. Refine TCP/IP csum offload code -+** -+** Revision 1.5 2007/07/17 13:01:18 MTK01088 -+** add associate req and rsp function -+** -+** Revision 1.4 2007/07/13 05:19:19 MTK01084 -+** provide timer set functions -+** -+** Revision 1.3 2007/06/27 02:18:51 MTK01461 -+** Update SCAN_FSM, Initial(Can Load Module), Proc(Can do Reg R/W), TX API -+** -+** Revision 1.2 2007/06/25 06:16:24 MTK01461 -+** Update illustrations, gl_init.c, gl_kal.c, gl_kal.h, gl_os.h and RX API -+** -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include -+#include "gl_os.h" -+#include "gl_wext.h" -+#include "precomp.h" -+#if defined(CONFIG_MTK_TC1_FEATURE) -+#include -+#endif -+#if CFG_SUPPORT_AGPS_ASSIST -+#include -+#endif -+#if CFG_SUPPORT_WAKEUP_REASON_DEBUG -+#include -+#endif -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+#if DBG -+int allocatedMemSize = 0; -+#endif -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+/* #define MTK_DMA_BUF_MEMCPY_SUP */ -+static PVOID pvIoBuffer; -+ -+#ifdef MTK_DMA_BUF_MEMCPY_SUP -+static PVOID pvIoPhyBuf; -+static PVOID pvDmaBuffer; -+static PVOID pvDmaPhyBuf; -+#endif /* MTK_DMA_BUF_MEMCPY_SUP */ -+ -+static UINT_32 pvIoBufferSize; -+static UINT_32 pvIoBufferUsage; -+static struct KAL_HALT_CTRL_T rHaltCtrl = { -+ .lock = __SEMAPHORE_INITIALIZER(rHaltCtrl.lock, 1), -+ .owner = NULL, -+ .fgHalt = TRUE, -+ .fgHeldByKalIoctl = FALSE, -+ .u4HoldStart = 0, -+}; -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+#if defined(MT6620) && CFG_MULTI_ECOVER_SUPPORT -+typedef enum _ENUM_WMTHWVER_TYPE_T { -+ WMTHWVER_MT6620_E1 = 0x0, -+ WMTHWVER_MT6620_E2 = 0x1, -+ WMTHWVER_MT6620_E3 = 0x2, -+ WMTHWVER_MT6620_E4 = 0x3, -+ WMTHWVER_MT6620_E5 = 0x4, -+ WMTHWVER_MT6620_E6 = 0x5, -+ WMTHWVER_MT6620_MAX, -+ WMTHWVER_INVALID = 0xff -+} ENUM_WMTHWVER_TYPE_T, *P_ENUM_WMTHWVER_TYPE_T; -+#endif -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+VOID kalHifAhbKalWakeLockTimeout(IN P_GLUE_INFO_T prGlueInfo) -+{ -+ KAL_WAKE_LOCK_TIMEOUT(prGlueInfo->prAdapter, &(prGlueInfo->rAhbIsrWakeLock), (HZ / 10)); /* 100ms */ -+} -+ -+#if CFG_ENABLE_FW_DOWNLOAD -+ -+static struct file *filp; -+static uid_t orgfsuid; -+static gid_t orgfsgid; -+static mm_segment_t orgfs; -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is provided by GLUE Layer for internal driver stack to -+* open firmware image in kernel space -+* -+* \param[in] prGlueInfo Pointer of GLUE Data Structure -+* -+* \retval WLAN_STATUS_SUCCESS. -+* \retval WLAN_STATUS_FAILURE. -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS kalFirmwareOpen(IN P_GLUE_INFO_T prGlueInfo) -+{ -+ UINT_8 aucFilePath[50]; -+ -+ /* FIX ME: since we don't have hotplug script in the filesystem -+ * , so the request_firmware() KAPI can not work properly -+ */ -+ -+ /* save uid and gid used for filesystem access. -+ * set user and group to 0(root) */ -+ struct cred *cred = (struct cred *)get_current_cred(); -+ -+ orgfsuid = cred->fsuid.val; -+ orgfsgid = cred->fsgid.val; -+ cred->fsuid.val = cred->fsgid.val = 0; -+ -+ ASSERT(prGlueInfo); -+ -+ orgfs = get_fs(); -+ set_fs(get_ds()); -+ -+ /* open the fw file */ -+#if defined(MT6620) & CFG_MULTI_ECOVER_SUPPORT -+ switch (mtk_wcn_wmt_hwver_get()) { -+ case WMTHWVER_MT6620_E1: -+ case WMTHWVER_MT6620_E2: -+ case WMTHWVER_MT6620_E3: -+ case WMTHWVER_MT6620_E4: -+ case WMTHWVER_MT6620_E5: -+ filp = filp_open("/etc/firmware/" CFG_FW_FILENAME, O_RDONLY, 0); -+ break; -+ -+ case WMTHWVER_MT6620_E6: -+ default: -+ filp = filp_open("/etc/firmware/" CFG_FW_FILENAME "_E6", O_RDONLY, 0); -+ break; -+ } -+#elif defined(MT6628) -+/* filp = filp_open("/etc/firmware/"CFG_FW_FILENAME"_MT6628", O_RDONLY, 0); */ -+/* filp = filp_open("/etc/firmware/"CFG_FW_FILENAME"_MT6582", O_RDONLY, 0); */ -+#if 0 /* new wifi ram code mechanism, waiting firmware ready, then we can enable these code */ -+ kalMemZero(aucFilePath, sizeof(aucFilePath)); -+ kalMemCopy(aucFilePath, "/etc/firmware/" CFG_FW_FILENAME "_AD", sizeof("/etc/firmware/" CFG_FW_FILENAME "_AD")); -+ filp = filp_open(aucFilePath, O_RDONLY, 0); -+ if (!IS_ERR(filp)) -+ goto open_success; -+#endif -+ kalMemZero(aucFilePath, sizeof(aucFilePath)); -+ kalMemCopy(aucFilePath, "/etc/firmware/" CFG_FW_FILENAME "_", strlen("/etc/firmware/" CFG_FW_FILENAME "_")); -+ glGetChipInfo(prGlueInfo, &aucFilePath[strlen("/etc/firmware/" CFG_FW_FILENAME "_")]); -+ -+ DBGLOG(INIT, INFO, "open file: %s\n", aucFilePath); -+ -+ filp = filp_open(aucFilePath, O_RDONLY, 0); -+#else -+ filp = filp_open("/etc/firmware/" CFG_FW_FILENAME, O_RDONLY, 0); -+#endif -+ if (IS_ERR(filp)) { -+ DBGLOG(INIT, ERROR, "Open FW image: %s failed\n", CFG_FW_FILENAME); -+ goto error_open; -+ } -+#if 0 -+open_success: -+#endif -+ DBGLOG(INIT, TRACE, "Open FW image: %s done\n", CFG_FW_FILENAME); -+ return WLAN_STATUS_SUCCESS; -+ -+error_open: -+ /* restore */ -+ set_fs(orgfs); -+ cred->fsuid.val = orgfsuid; -+ cred->fsgid.val = orgfsgid; -+ put_cred(cred); -+ return WLAN_STATUS_FAILURE; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is provided by GLUE Layer for internal driver stack to -+* release firmware image in kernel space -+* -+* \param[in] prGlueInfo Pointer of GLUE Data Structure -+* -+* \retval WLAN_STATUS_SUCCESS. -+* \retval WLAN_STATUS_FAILURE. -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS kalFirmwareClose(IN P_GLUE_INFO_T prGlueInfo) -+{ -+ ASSERT(prGlueInfo); -+ -+ if ((filp != NULL) && !IS_ERR(filp)) { -+ /* close firmware file */ -+ filp_close(filp, NULL); -+ -+ /* restore */ -+ set_fs(orgfs); -+ { -+ struct cred *cred = (struct cred *)get_current_cred(); -+ -+ cred->fsuid.val = orgfsuid; -+ cred->fsgid.val = orgfsgid; -+ put_cred(cred); -+ } -+ filp = NULL; -+ } -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is provided by GLUE Layer for internal driver stack to -+* load firmware image in kernel space -+* -+* \param[in] prGlueInfo Pointer of GLUE Data Structure -+* -+* \retval WLAN_STATUS_SUCCESS. -+* \retval WLAN_STATUS_FAILURE. -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS kalFirmwareLoad(IN P_GLUE_INFO_T prGlueInfo, OUT PVOID prBuf, IN UINT_32 u4Offset, OUT PUINT_32 pu4Size) -+{ -+ ASSERT(prGlueInfo); -+ ASSERT(pu4Size); -+ ASSERT(prBuf); -+ -+ /* l = filp->f_path.dentry->d_inode->i_size; */ -+#if 0 -+ /* the object must have a read method */ -+ if ((filp == NULL) || IS_ERR(filp) || (filp->f_op == NULL) || (filp->f_op->read == NULL)) { -+ goto error_read; -+ } else { -+ filp->f_pos = u4Offset; -+ *pu4Size = filp->f_op->read(filp, prBuf, *pu4Size, &filp->f_pos); -+ } -+#else -+ /* the object must have a read method */ -+ if ((filp == NULL) || IS_ERR(filp) || (filp->f_op == NULL) ) { -+ goto error_read; -+ } else { -+ filp->f_pos = u4Offset; -+ *pu4Size = vfs_read(filp, prBuf, *pu4Size, &filp->f_pos); -+ } -+#endif -+ -+ return WLAN_STATUS_SUCCESS; -+ -+error_read: -+ return WLAN_STATUS_FAILURE; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is provided by GLUE Layer for internal driver stack to -+* query firmware image size in kernel space -+* -+* \param[in] prGlueInfo Pointer of GLUE Data Structure -+* -+* \retval WLAN_STATUS_SUCCESS. -+* \retval WLAN_STATUS_FAILURE. -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+ -+WLAN_STATUS kalFirmwareSize(IN P_GLUE_INFO_T prGlueInfo, OUT PUINT_32 pu4Size) -+{ -+ ASSERT(prGlueInfo); -+ ASSERT(pu4Size); -+ -+ //*pu4Size = filp->f_path.dentry->d_inode->i_size; -+ *pu4Size = filp->f_op->llseek(filp, 0, 2); -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is used to load firmware image -+* -+* \param pvGlueInfo Pointer of GLUE Data Structure -+* \param ppvMapFileBuf Pointer of pointer to memory-mapped firmware image -+* \param pu4FileLength File length and memory mapped length as well -+ -+* \retval Map File Handle, used for unammping -+*/ -+/*----------------------------------------------------------------------------*/ -+ -+PVOID kalFirmwareImageMapping(IN P_GLUE_INFO_T prGlueInfo, OUT PPVOID ppvMapFileBuf, OUT PUINT_32 pu4FileLength) -+{ -+ UINT_32 u4FwSize = 0; -+ PVOID prFwBuffer = NULL; -+ -+ DEBUGFUNC("kalFirmwareImageMapping"); -+ -+ ASSERT(prGlueInfo); -+ ASSERT(ppvMapFileBuf); -+ ASSERT(pu4FileLength); -+ -+ do { -+ /* <1> Open firmware */ -+ if (kalFirmwareOpen(prGlueInfo) != WLAN_STATUS_SUCCESS) { -+ DBGLOG(INIT, TRACE, "kalFirmwareOpen fail!\n"); -+ break; -+ } -+ -+ /* <2> Query firmare size */ -+ kalFirmwareSize(prGlueInfo, &u4FwSize); -+ printk(KERN_ERR "%s firmware size %d\n", __FUNCTION__, u4FwSize); -+ /* <3> Use vmalloc for allocating large memory trunk */ -+ prFwBuffer = vmalloc(ALIGN_4(u4FwSize)); -+ /* <4> Load image binary into buffer */ -+ if (kalFirmwareLoad(prGlueInfo, prFwBuffer, 0, &u4FwSize) != WLAN_STATUS_SUCCESS) { -+ vfree(prFwBuffer); -+ kalFirmwareClose(prGlueInfo); -+ DBGLOG(INIT, TRACE, "kalFirmwareLoad fail!\n"); -+ break; -+ } -+ /* <5> write back info */ -+ *pu4FileLength = u4FwSize; -+ *ppvMapFileBuf = prFwBuffer; -+ -+ return prFwBuffer; -+ -+ } while (FALSE); -+ -+ return NULL; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is used to unload firmware image mapped memory -+* -+* \param pvGlueInfo Pointer of GLUE Data Structure -+* \param pvFwHandle Pointer to mapping handle -+* \param pvMapFileBuf Pointer to memory-mapped firmware image -+* -+* \retval none -+*/ -+/*----------------------------------------------------------------------------*/ -+ -+VOID kalFirmwareImageUnmapping(IN P_GLUE_INFO_T prGlueInfo, IN PVOID prFwHandle, IN PVOID pvMapFileBuf) -+{ -+ DEBUGFUNC("kalFirmwareImageUnmapping"); -+ -+ ASSERT(prGlueInfo); -+ -+ /* pvMapFileBuf might be NULL when file doesn't exist */ -+ if (pvMapFileBuf) -+ vfree(pvMapFileBuf); -+ -+ kalFirmwareClose(prGlueInfo); -+} -+ -+#endif -+ -+#if 0 -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is used to load firmware image -+* -+* \param pvGlueInfo Pointer of GLUE Data Structure -+* \param ppvMapFileBuf Pointer of pointer to memory-mapped firmware image -+* \param pu4FileLength File length and memory mapped length as well -+ -+* \retval Map File Handle, used for unammping -+*/ -+/*----------------------------------------------------------------------------*/ -+ -+PVOID kalFirmwareImageMapping(IN P_GLUE_INFO_T prGlueInfo, OUT PPVOID ppvMapFileBuf, OUT PUINT_32 pu4FileLength) -+{ -+ INT_32 i4Ret = 0; -+ -+ DEBUGFUNC("kalFirmwareImageMapping"); -+ -+ ASSERT(prGlueInfo); -+ ASSERT(ppvMapFileBuf); -+ ASSERT(pu4FileLength); -+ -+ do { -+ GL_HIF_INFO_T *prHifInfo = &prGlueInfo->rHifInfo; -+ -+ prGlueInfo->prFw = NULL; -+ -+ /* <1> Open firmware */ -+ i4Ret = request_firmware(&prGlueInfo->prFw, CFG_FW_FILENAME, prHifInfo->Dev); -+ -+ if (i4Ret) { -+ DBGLOG(INIT, TRACE, "fw %s:request failed %d\n", CFG_FW_FILENAME, i4Ret); -+ break; -+ } -+ *pu4FileLength = prGlueInfo->prFw->size; -+ *ppvMapFileBuf = prGlueInfo->prFw->data; -+ return prGlueInfo->prFw->data; -+ -+ } while (FALSE); -+ -+ return NULL; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is used to unload firmware image mapped memory -+* -+* \param pvGlueInfo Pointer of GLUE Data Structure -+* \param pvFwHandle Pointer to mapping handle -+* \param pvMapFileBuf Pointer to memory-mapped firmware image -+* -+* \retval none -+*/ -+/*----------------------------------------------------------------------------*/ -+ -+VOID kalFirmwareImageUnmapping(IN P_GLUE_INFO_T prGlueInfo, IN PVOID prFwHandle, IN PVOID pvMapFileBuf) -+{ -+ DEBUGFUNC("kalFirmwareImageUnmapping"); -+ -+ ASSERT(prGlueInfo); -+ ASSERT(pvMapFileBuf); -+ -+ release_firmware(prGlueInfo->prFw); -+ -+} -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is provided by GLUE Layer for internal driver stack to acquire -+* OS SPIN_LOCK. -+* -+* \param[in] prGlueInfo Pointer of GLUE Data Structure -+* \param[in] rLockCategory Specify which SPIN_LOCK -+* \param[out] pu4Flags Pointer of a variable for saving IRQ flags -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+kalAcquireSpinLock(IN P_GLUE_INFO_T prGlueInfo, IN ENUM_SPIN_LOCK_CATEGORY_E rLockCategory, OUT unsigned long *pu4Flags) -+{ -+ unsigned long u4Flags = 0; -+ -+ ASSERT(prGlueInfo); -+ ASSERT(pu4Flags); -+ -+ if (rLockCategory < SPIN_LOCK_NUM) { -+ -+#if CFG_USE_SPIN_LOCK_BOTTOM_HALF -+ spin_lock_bh(&prGlueInfo->rSpinLock[rLockCategory]); -+#else /* !CFG_USE_SPIN_LOCK_BOTTOM_HALF */ -+ spin_lock_irqsave(&prGlueInfo->rSpinLock[rLockCategory], u4Flags); -+#endif /* !CFG_USE_SPIN_LOCK_BOTTOM_HALF */ -+ -+ *pu4Flags = u4Flags; -+/* DBGLOG(INIT, TRACE, ("A+%d\n", rLockCategory)); */ -+ } -+ -+} /* end of kalAcquireSpinLock() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is provided by GLUE Layer for internal driver stack to release -+* OS SPIN_LOCK. -+* -+* \param[in] prGlueInfo Pointer of GLUE Data Structure -+* \param[in] rLockCategory Specify which SPIN_LOCK -+* \param[in] u4Flags Saved IRQ flags -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID kalReleaseSpinLock(IN P_GLUE_INFO_T prGlueInfo, IN ENUM_SPIN_LOCK_CATEGORY_E rLockCategory, IN UINT_32 u4Flags) -+{ -+ ASSERT(prGlueInfo); -+ -+ if (rLockCategory < SPIN_LOCK_NUM) { -+ /* DBGLOG(INIT, TRACE, ("A-%d %d %d\n", rLockCategory, u4MemAllocCnt, u4MemFreeCnt)); */ -+#if CFG_USE_SPIN_LOCK_BOTTOM_HALF -+ spin_unlock_bh(&prGlueInfo->rSpinLock[rLockCategory]); -+#else /* !CFG_USE_SPIN_LOCK_BOTTOM_HALF */ -+ spin_unlock_irqrestore(&prGlueInfo->rSpinLock[rLockCategory], u4Flags); -+#endif /* !CFG_USE_SPIN_LOCK_BOTTOM_HALF */ -+ -+ } -+ -+} /* end of kalReleaseSpinLock() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is provided by GLUE Layer for internal driver stack to update -+* current MAC address. -+* -+* \param[in] prGlueInfo Pointer of GLUE Data Structure -+* \param[in] pucMacAddr Pointer of current MAC address -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID kalUpdateMACAddress(IN P_GLUE_INFO_T prGlueInfo, IN PUINT_8 pucMacAddr) -+{ -+ ASSERT(prGlueInfo); -+ ASSERT(pucMacAddr); -+ -+ if (UNEQUAL_MAC_ADDR(prGlueInfo->prDevHandler->dev_addr, pucMacAddr)) -+ memcpy(prGlueInfo->prDevHandler->dev_addr, pucMacAddr, PARAM_MAC_ADDR_LEN); -+ -+} -+ -+#if CFG_TCP_IP_CHKSUM_OFFLOAD -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief To query the packet information for offload related parameters. -+* -+* \param[in] pvPacket Pointer to the packet descriptor. -+* \param[in] pucFlag Points to the offload related parameter. -+* -+* \return (none) -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID kalQueryTxChksumOffloadParam(IN PVOID pvPacket, OUT PUINT_8 pucFlag) -+{ -+ struct sk_buff *skb = (struct sk_buff *)pvPacket; -+ UINT_8 ucFlag = 0; -+ -+ ASSERT(pvPacket); -+ ASSERT(pucFlag); -+ -+ -+ if (skb->ip_summed == CHECKSUM_PARTIAL) { -+#if DBG -+ /* Kevin: do double check, we can remove this part in Normal Driver. -+ * Because we register NIC feature with NETIF_F_IP_CSUM for MT5912B MAC, so -+ * we'll process IP packet only. -+ */ -+ if (skb->protocol != htons(ETH_P_IP)) { -+ /* printk("Wrong skb->protocol( = %08x) for TX Checksum Offload.\n", skb->protocol); */ -+ } else -+#endif -+ ucFlag |= (TX_CS_IP_GEN | TX_CS_TCP_UDP_GEN); -+ } -+ -+ *pucFlag = ucFlag; -+ -+} /* kalQueryChksumOffloadParam */ -+ -+/* 4 2007/10/8, mikewu, this is rewritten by Mike */ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief To update the checksum offload status to the packet to be indicated to OS. -+* -+* \param[in] pvPacket Pointer to the packet descriptor. -+* \param[in] pucFlag Points to the offload related parameter. -+* -+* \return (none) -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID kalUpdateRxCSUMOffloadParam(IN PVOID pvPacket, IN ENUM_CSUM_RESULT_T aeCSUM[]) -+{ -+ struct sk_buff *skb = (struct sk_buff *)pvPacket; -+ -+ ASSERT(pvPacket); -+ -+ if ((aeCSUM[CSUM_TYPE_IPV4] == CSUM_RES_SUCCESS || aeCSUM[CSUM_TYPE_IPV6] == CSUM_RES_SUCCESS) && -+ ((aeCSUM[CSUM_TYPE_TCP] == CSUM_RES_SUCCESS) || (aeCSUM[CSUM_TYPE_UDP] == CSUM_RES_SUCCESS))) { -+ skb->ip_summed = CHECKSUM_UNNECESSARY; -+ } else { -+ skb->ip_summed = CHECKSUM_NONE; -+#if DBG -+ if (aeCSUM[CSUM_TYPE_IPV4] == CSUM_RES_NONE && aeCSUM[CSUM_TYPE_IPV6] == CSUM_RES_NONE) -+ DBGLOG(RX, TRACE, "RX: \"non-IPv4/IPv6\" Packet\n"); -+ else if (aeCSUM[CSUM_TYPE_IPV4] == CSUM_RES_FAILED) -+ DBGLOG(RX, TRACE, "RX: \"bad IP Checksum\" Packet\n"); -+ else if (aeCSUM[CSUM_TYPE_TCP] == CSUM_RES_FAILED) -+ DBGLOG(RX, TRACE, "RX: \"bad TCP Checksum\" Packet\n"); -+ else if (aeCSUM[CSUM_TYPE_UDP] == CSUM_RES_FAILED) -+ DBGLOG(RX, TRACE, "RX: \"bad UDP Checksum\" Packet\n"); -+ else -+ /* Do nothing */ -+#endif -+ } -+ -+} /* kalUpdateRxCSUMOffloadParam */ -+#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is called to free packet allocated from kalPacketAlloc. -+* -+* \param[in] prGlueInfo Pointer of GLUE Data Structure -+* \param[in] pvPacket Pointer of the packet descriptor -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID kalPacketFree(IN P_GLUE_INFO_T prGlueInfo, IN PVOID pvPacket) -+{ -+ dev_kfree_skb((struct sk_buff *)pvPacket); -+ if (prGlueInfo) -+ prGlueInfo->u8SkbFreed++; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Only handles driver own creating packet (coalescing buffer). -+* -+* \param prGlueInfo Pointer of GLUE Data Structure -+* \param u4Size Pointer of Packet Handle -+* \param ppucData Status Code for OS upper layer -+* -+* \return NULL: Failed to allocate skb, Not NULL get skb -+*/ -+/*----------------------------------------------------------------------------*/ -+PVOID kalPacketAlloc(IN P_GLUE_INFO_T prGlueInfo, IN UINT_32 u4Size, OUT PUINT_8 *ppucData) -+{ -+ struct sk_buff *prSkb = dev_alloc_skb(u4Size); -+ -+ if (prSkb) -+ *ppucData = (PUINT_8) (prSkb->data); -+#if DBG -+ { -+ PUINT_32 pu4Head = (PUINT_32) &prSkb->cb[0]; -+ *pu4Head = (UINT_32) prSkb->head; -+ DBGLOG(RX, TRACE, "prSkb->head = %#x, prSkb->cb = %#x\n", (UINT_32) prSkb->head, *pu4Head); -+ } -+#endif -+ return (PVOID) prSkb; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Process the received packet for indicating to OS. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure. -+* \param[in] pvPacket Pointer of the packet descriptor -+* \param[in] pucPacketStart The starting address of the buffer of Rx packet. -+* \param[in] u4PacketLen The packet length. -+* \param[in] pfgIsRetain Is the packet to be retained. -+* \param[in] aerCSUM The result of TCP/ IP checksum offload. -+* -+* \retval WLAN_STATUS_SUCCESS. -+* \retval WLAN_STATUS_FAILURE. -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+kalProcessRxPacket(IN P_GLUE_INFO_T prGlueInfo, IN PVOID pvPacket, IN PUINT_8 pucPacketStart, IN UINT_32 u4PacketLen, -+ /* IN PBOOLEAN pfgIsRetain, */ -+ IN BOOLEAN fgIsRetain, IN ENUM_CSUM_RESULT_T aerCSUM[]) -+{ -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ struct sk_buff *skb = (struct sk_buff *)pvPacket; -+ -+ skb->data = pucPacketStart; -+ skb_reset_tail_pointer(skb); /* reset tail pointer first, for 64bit kernel,we should call linux kernel API */ -+ skb_trim(skb, 0); /* only if skb->len > len, then skb_trim has effect */ -+ skb_put(skb, u4PacketLen); /* shift tail and skb->len to correct value */ -+ -+#if CFG_TCP_IP_CHKSUM_OFFLOAD -+ kalUpdateRxCSUMOffloadParam(skb, aerCSUM); -+#endif -+ -+ return rStatus; -+} -+ -+#if (CONF_HIF_LOOPBACK_AUTO == 1) -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Do HIF loopback test. -+* -+* \param[in] GlueInfo Pointer to the GLUE_INFO_T structure. -+* -+* \retval None -+*/ -+/*----------------------------------------------------------------------------*/ -+unsigned int testmode = 0; -+unsigned int testlen = 64; -+ -+void kalDevLoopbkAuto(IN GLUE_INFO_T *GlueInfo) -+{ -+#define HIF_LOOPBK_AUTO_TEST_LEN 1600 -+/* GL_HIF_INFO_T *HifInfo; */ -+ static unsigned int txcnt; -+ struct sk_buff *MsduInfo; -+ UINT_8 *Pkt; -+ UINT_32 RegVal; -+ UINT_32 PktLen = 16; -+ -+ /* Init */ -+ if (testmode != 0) { -+ PktLen = kalRandomNumber() % 1520; -+ if (PktLen < 64) -+ PktLen = 64; -+ } else { -+ PktLen = testlen++; -+ if (PktLen > 1520) { -+ testmode = 1; -+ PktLen = 64; -+ } -+ } -+ -+/* PktLen = 100; */ -+ DBGLOG(INIT, INFO, "kalDevLoopbkAuto> Send a packet to HIF (len = %d) (total = %d)...\n", PktLen, ++txcnt); -+/* HifInfo = &GlueInfo->rHifInfo; */ -+ -+ /* Allocate a MSDU_INFO_T */ -+ MsduInfo = kalPacketAlloc(GlueInfo, HIF_LOOPBK_AUTO_TEST_LEN, &Pkt); -+ if (MsduInfo == NULL) { -+ DBGLOG(INIT, WARN, "No PKT_INFO_T for sending loopback packet!\n"); -+ return; -+ } -+ -+ /* Init the packet */ -+ MsduInfo->dev = GlueInfo->prDevHandler; -+ if (MsduInfo->dev == NULL) { -+ DBGLOG(INIT, WARN, "MsduInfo->dev == NULL!!\n"); -+ kalPacketFree(GlueInfo, MsduInfo); -+ return; -+ } -+ -+ MsduInfo->len = PktLen; -+ kalMemSet(MsduInfo->data, 0xff, 6); -+ kalMemSet(MsduInfo->data + 6, 0x5a, PktLen - 6); -+ -+ /* Simulate OS to send the packet */ -+ wlanHardStartXmit(MsduInfo, MsduInfo->dev); -+ -+#if 0 -+ PktLen += 4; -+ if (PktLen >= 1600) -+ PktLen = 16; -+#endif -+ -+ /* Note: in FPGA, clock is not accuracy so 3000 here, not 10000 */ -+/* HifInfo->HifTmrLoopbkFn.expires = jiffies + MSEC_TO_SYSTIME(1000); */ -+/* add_timer(&(HifInfo->HifTmrLoopbkFn)); */ -+} -+ -+int kalDevLoopbkThread(IN void *data) -+{ -+ struct net_device *dev = data; -+ P_GLUE_INFO_T GlueInfo = *((P_GLUE_INFO_T *) netdev_priv(dev)); -+ GL_HIF_INFO_T *HifInfo = &GlueInfo->rHifInfo; -+ int ret; -+ static int test; -+ -+ while (TRUE) { -+ ret = wait_event_interruptible(HifInfo->HifWaitq, (HifInfo->HifLoopbkFlg != 0)); -+ -+ if (HifInfo->HifLoopbkFlg == 0xFFFFFFFF) -+ break; -+ -+ while (TRUE) { -+ /* if ((HifInfo->HifLoopbkFlg & 0x01) == 0) */ -+ if (GlueInfo->i4TxPendingFrameNum < 64) { -+ DBGLOG(INIT, INFO, "GlueInfo->i4TxPendingFrameNum = %d\n", -+ GlueInfo->i4TxPendingFrameNum); -+ kalDevLoopbkAuto(GlueInfo); -+ -+ if (testmode == 0) -+ kalMsleep(3000); -+ } else -+ kalMsleep(1); -+ } -+ } -+} -+ -+void kalDevLoopbkRxHandle(IN P_ADAPTER_T prAdapter, IN OUT P_SW_RFB_T prSwRfb) -+{ -+ static unsigned int rxcnt; -+ UINT_32 i; -+ UINT_8 *Buf = prSwRfb->pucRecvBuff + sizeof(HIF_TX_HEADER_T); -+ P_HIF_RX_HEADER_T prHifRxHdr = prSwRfb->prHifRxHdr; -+ UINT_32 len = prHifRxHdr->u2PacketLen - sizeof(HIF_TX_HEADER_T); -+ -+ if (len > 1600) { -+ while (1) -+ DBGLOG(INIT, ERROR, "HIF> Loopback len > 1600!!! error!!!\n"); -+ } -+ -+ for (i = 0; i < 6; i++) { -+ if (Buf[i] != 0xff) { -+ while (1) { -+ DBGLOG(INIT, ERROR, "HIF> Loopbk dst addr error (len = %d)!\n", len); -+ dumpMemory8(prSwRfb->pucRecvBuff, prHifRxHdr->u2PacketLen); -+ } -+ } -+ } -+ -+ for (i = 6; i < len; i++) { -+ if (Buf[i] != 0x5a) { -+ while (1) { -+ DBGLOG(INIT, ERROR, "HIF> Loopbk error (len = %d)!\n", len); -+ dumpMemory8(prSwRfb->pucRecvBuff, prHifRxHdr->u2PacketLen); -+ } -+ } -+ } -+ -+ DBGLOG(INIT, INFO, "HIF> Loopbk OK (len = %d) (total = %d)!\n", len, ++rxcnt); -+} -+#endif /* CONF_HIF_LOOPBACK_AUTO */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief To indicate an array of received packets is available for higher -+* level protocol uses. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure. -+* \param[in] apvPkts The packet array to be indicated -+* \param[in] ucPktNum The number of packets to be indicated -+* -+* \retval TRUE Success. -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS kalRxIndicatePkts(IN P_GLUE_INFO_T prGlueInfo, IN PVOID apvPkts[], IN UINT_8 ucPktNum) -+{ -+ UINT_8 ucIdx = 0; -+ struct net_device *prNetDev = prGlueInfo->prDevHandler; -+ struct sk_buff *prSkb = NULL; -+ -+ ASSERT(prGlueInfo); -+ ASSERT(apvPkts); -+ -+#if CFG_BOW_TEST -+ UINT_32 i; -+#endif -+ -+ for (ucIdx = 0; ucIdx < ucPktNum; ucIdx++) { -+ prSkb = apvPkts[ucIdx]; -+#if DBG -+ do { -+ PUINT_8 pu4Head = (PUINT_8) &prSkb->cb[0]; -+ UINT_32 u4HeadValue = 0; -+ -+ kalMemCopy(&u4HeadValue, pu4Head, sizeof(u4HeadValue)); -+ DBGLOG(RX, TRACE, "prSkb->head = %p, prSkb->cb = 0x%x\n", pu4Head, u4HeadValue); -+ } while (0); -+#endif -+ -+ if (GLUE_GET_PKT_IS_P2P(prSkb)) { -+ /* P2P */ -+#if CFG_ENABLE_WIFI_DIRECT -+ if (prGlueInfo->prAdapter->fgIsP2PRegistered) -+ prNetDev = kalP2PGetDevHdlr(prGlueInfo); -+ /* prNetDev->stats.rx_bytes += prSkb->len; */ -+ /* prNetDev->stats.rx_packets++; */ -+ prGlueInfo->prP2PInfo->rNetDevStats.rx_bytes += prSkb->len; -+ prGlueInfo->prP2PInfo->rNetDevStats.rx_packets++; -+ -+#else -+ prNetDev = prGlueInfo->prDevHandler; -+#endif -+ } else if (GLUE_GET_PKT_IS_PAL(prSkb)) { -+ /* BOW */ -+#if CFG_ENABLE_BT_OVER_WIFI && CFG_BOW_SEPARATE_DATA_PATH -+ if (prGlueInfo->rBowInfo.fgIsNetRegistered) -+ prNetDev = prGlueInfo->rBowInfo.prDevHandler; -+#else -+ prNetDev = prGlueInfo->prDevHandler; -+#endif -+ } else { -+ /* AIS */ -+ prNetDev = prGlueInfo->prDevHandler; -+ prGlueInfo->rNetDevStats.rx_bytes += prSkb->len; -+ prGlueInfo->rNetDevStats.rx_packets++; -+ -+ } -+ -+ /* check if the "unicast" packet is from us */ -+ if (kalMemCmp(prSkb->data, prSkb->data + 6, 6) == 0) { -+ /* we will filter broadcast/multicast packet sent from us in hardware */ -+ /* source address = destination address ? */ -+ DBGLOG(RX, EVENT, -+ "kalRxIndicatePkts got from us!!! Drop it! ([ %pM ] len %d)\n", -+ prSkb->data, prSkb->len); -+ wlanReturnPacket(prGlueInfo->prAdapter, prSkb); -+ continue; -+ } -+#if (CFG_SUPPORT_TDLS == 1) -+ if (TdlsexRxFrameDrop(prGlueInfo, prSkb->data) == TRUE) { -+ /* drop the received TDLS action frame */ -+ DBGLOG(TDLS, WARN, -+ " %s: drop a received packet from %pM %u\n", -+ __func__, prSkb->data, -+ (UINT32) ((P_ADAPTER_T) (prGlueInfo->prAdapter))->rRxCtrl.rFreeSwRfbList.u4NumElem); -+ wlanReturnPacket(prGlueInfo->prAdapter, prSkb); -+ continue; -+ } -+ -+ /* -+ get a TDLS request/response/confirm, we need to parse the HT IE -+ because older supplicant does not pass HT IE to us -+ */ -+ TdlsexRxFrameHandle(prGlueInfo, prSkb->data, prSkb->len); -+#endif /* CFG_SUPPORT_TDLS */ -+ -+ STATS_RX_PKT_INFO_DISPLAY(prSkb->data); -+ -+ //prNetDev->last_rx = jiffies; -+ prSkb->protocol = eth_type_trans(prSkb, prNetDev); -+ prSkb->dev = prNetDev; -+ /* DBGLOG_MEM32(RX, TRACE, (PUINT_32)prSkb->data, prSkb->len); */ -+ DBGLOG(RX, TRACE, "kalRxIndicatePkts len = %d\n", prSkb->len); -+ -+#if CFG_BOW_TEST -+ DBGLOG(BOW, TRACE, "Rx sk_buff->len: %d\n", prSkb->len); -+ DBGLOG(BOW, TRACE, "Rx sk_buff->data_len: %d\n", prSkb->data_len); -+ DBGLOG(BOW, TRACE, "Rx sk_buff->data:\n"); -+ -+ for (i = 0; i < prSkb->len; i++) { -+ DBGLOG(BOW, TRACE, "%4x", prSkb->data[i]); -+ -+ if ((i + 1) % 16 == 0) -+ DBGLOG(BOW, TRACE, "\n"); -+ } -+ -+ DBGLOG(BOW, TRACE, "\n"); -+#endif -+ -+ if (!in_interrupt()) -+ netif_rx_ni(prSkb); /* only in non-interrupt context */ -+ else -+ netif_rx(prSkb); -+ -+ wlanReturnPacket(prGlueInfo->prAdapter, NULL); -+ } -+ -+ kalPerMonStart(prGlueInfo); -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Called by driver to indicate event to upper layer, for example, the wpa -+* supplicant or wireless tools. -+* -+* \param[in] pvAdapter Pointer to the adapter descriptor. -+* \param[in] eStatus Indicated status. -+* \param[in] pvBuf Indicated message buffer. -+* \param[in] u4BufLen Indicated message buffer size. -+* -+* \return (none) -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT_32 ScanCnt = 0, ScanDoneFailCnt = 0; -+VOID -+kalIndicateStatusAndComplete(IN P_GLUE_INFO_T prGlueInfo, IN WLAN_STATUS eStatus, IN PVOID pvBuf, IN UINT_32 u4BufLen) -+{ -+ UINT_32 bufLen; -+ P_PARAM_STATUS_INDICATION_T pStatus = (P_PARAM_STATUS_INDICATION_T) pvBuf; -+ P_PARAM_AUTH_EVENT_T pAuth = (P_PARAM_AUTH_EVENT_T) pStatus; -+ P_PARAM_PMKID_CANDIDATE_LIST_T pPmkid = (P_PARAM_PMKID_CANDIDATE_LIST_T) (pStatus + 1); -+ PARAM_MAC_ADDRESS arBssid; -+ struct cfg80211_scan_request *prScanRequest = NULL; -+ PARAM_SSID_T ssid; -+ struct ieee80211_channel *prChannel = NULL; -+ struct cfg80211_bss *bss; -+ UINT_8 ucChannelNum; -+ P_BSS_DESC_T prBssDesc = NULL; -+ struct cfg80211_scan_info info = { -+ .aborted = false, -+ }; -+ -+ GLUE_SPIN_LOCK_DECLARATION(); -+ -+ kalMemZero(arBssid, MAC_ADDR_LEN); -+ -+ ASSERT(prGlueInfo); -+ -+ switch (eStatus) { -+ case WLAN_STATUS_ROAM_OUT_FIND_BEST: -+ case WLAN_STATUS_MEDIA_CONNECT: -+ -+ prGlueInfo->eParamMediaStateIndicated = PARAM_MEDIA_STATE_CONNECTED; -+ -+ /* indicate assoc event */ -+ wlanQueryInformation(prGlueInfo->prAdapter, wlanoidQueryBssid, &arBssid[0], sizeof(arBssid), &bufLen); -+ wext_indicate_wext_event(prGlueInfo, SIOCGIWAP, arBssid, bufLen); -+ -+ /* switch netif on */ -+ netif_carrier_on(prGlueInfo->prDevHandler); -+ -+ do { -+ /* print message on console */ -+ wlanQueryInformation(prGlueInfo->prAdapter, wlanoidQuerySsid, &ssid, sizeof(ssid), &bufLen); -+ -+ ssid.aucSsid[(ssid.u4SsidLen >= PARAM_MAX_LEN_SSID) ? -+ (PARAM_MAX_LEN_SSID - 1) : ssid.u4SsidLen] = '\0'; -+ DBGLOG(AIS, INFO, " %s netif_carrier_on [ssid:%s %pM ]\n", -+ prGlueInfo->prDevHandler->name, ssid.aucSsid, arBssid); -+ } while (0); -+ -+ if (prGlueInfo->fgIsRegistered == TRUE) { -+ struct cfg80211_bss *bss_others = NULL; -+ UINT_8 ucLoopCnt = 15; /* only loop 15 times to avoid dead loop */ -+ -+ /* retrieve channel */ -+ ucChannelNum = wlanGetChannelNumberByNetwork(prGlueInfo->prAdapter, NETWORK_TYPE_AIS_INDEX); -+ if (ucChannelNum <= 14) { -+ prChannel = -+ ieee80211_get_channel(priv_to_wiphy(prGlueInfo), -+ ieee80211_channel_to_frequency(ucChannelNum, -+ NL80211_BAND_2GHZ)); -+ } else { -+ prChannel = -+ ieee80211_get_channel(priv_to_wiphy(prGlueInfo), -+ ieee80211_channel_to_frequency(ucChannelNum, -+ NL80211_BAND_5GHZ)); -+ } -+ -+ /* ensure BSS exists */ -+ bss = cfg80211_get_bss(priv_to_wiphy(prGlueInfo), prChannel, arBssid, -+ ssid.aucSsid, ssid.u4SsidLen, WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS); -+ -+ if (bss == NULL) { -+ /* create BSS on-the-fly */ -+ prBssDesc = -+ wlanGetTargetBssDescByNetwork(prGlueInfo->prAdapter, NETWORK_TYPE_AIS_INDEX); -+ -+ if (prBssDesc != NULL) { -+ bss = cfg80211_inform_bss(priv_to_wiphy(prGlueInfo), prChannel, -+ CFG80211_BSS_FTYPE_PRESP, -+ arBssid, 0, /* TSF */ -+ WLAN_CAPABILITY_ESS, -+ prBssDesc->u2BeaconInterval, /* beacon interval */ -+ prBssDesc->aucIEBuf, /* IE */ -+ prBssDesc->u2IELength, /* IE Length */ -+ RCPI_TO_dBm(prBssDesc->ucRCPI) * 100, /* MBM */ -+ GFP_KERNEL); -+ } -+ } -+ /* remove all bsses that before and only channel different with the current connected one -+ if without this patch, UI will show channel A is connected even if AP has change channel -+ from A to B */ -+ while (ucLoopCnt--) { -+ bss_others = cfg80211_get_bss(priv_to_wiphy(prGlueInfo), NULL, arBssid, -+ ssid.aucSsid, ssid.u4SsidLen, WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS); -+ if (bss && bss_others && bss_others != bss) { -+ DBGLOG(SCN, INFO, "remove BSSes that only channel different\n"); -+ cfg80211_unlink_bss(priv_to_wiphy(prGlueInfo), bss_others); -+ } else -+ break; -+ } -+ -+ /* CFG80211 Indication */ -+ if (eStatus == WLAN_STATUS_ROAM_OUT_FIND_BEST) { -+ /*cfg80211_roamed_bss(prGlueInfo->prDevHandler, -+ bss, -+ prGlueInfo->aucReqIe, -+ prGlueInfo->u4ReqIeLength, -+ prGlueInfo->aucRspIe, prGlueInfo->u4RspIeLength, GFP_KERNEL); -+ */ -+ struct cfg80211_roam_info roam_info = { -+ .bss = bss, -+ .req_ie = prGlueInfo->aucReqIe, -+ .req_ie_len = prGlueInfo->u4ReqIeLength, -+ .resp_ie = prGlueInfo->aucRspIe, -+ .resp_ie_len = prGlueInfo->u4RspIeLength -+ }; -+ cfg80211_roamed(prGlueInfo->prDevHandler, -+ &roam_info, -+ GFP_KERNEL); -+ } else { -+ /* to support user space roaming, cfg80211 will change the sme_state to connecting -+ before reassociate */ -+ cfg80211_connect_result(prGlueInfo->prDevHandler, -+ arBssid, -+ prGlueInfo->aucReqIe, -+ prGlueInfo->u4ReqIeLength, -+ prGlueInfo->aucRspIe, -+ prGlueInfo->u4RspIeLength, WLAN_STATUS_SUCCESS, GFP_KERNEL); -+ } -+ } -+ -+ break; -+ -+ case WLAN_STATUS_MEDIA_DISCONNECT: -+ case WLAN_STATUS_MEDIA_DISCONNECT_LOCALLY: -+ /* indicate disassoc event */ -+ wext_indicate_wext_event(prGlueInfo, SIOCGIWAP, NULL, 0); -+ /* For CR 90 and CR99, While supplicant do reassociate, driver will do netif_carrier_off first, -+ after associated success, at joinComplete(), do netif_carier_on, -+ but for unknown reason, the supplicant 1x pkt will not called the driver -+ hardStartXmit, for template workaround these bugs, add this compiling flag -+ */ -+ /* switch netif off */ -+ -+ DBGLOG(AIS, INFO, "[wifi] %s netif_carrier_off\n", -+ prGlueInfo->prDevHandler->name); -+ -+ netif_carrier_off(prGlueInfo->prDevHandler); -+ -+ if (prGlueInfo->fgIsRegistered == TRUE) { -+ P_WIFI_VAR_T prWifiVar = &prGlueInfo->prAdapter->rWifiVar; -+ UINT_16 u2DeauthReason = prWifiVar->arBssInfo[NETWORK_TYPE_AIS_INDEX].u2DeauthReason; -+ /* CFG80211 Indication */ -+ DBGLOG(AIS, INFO, "[wifi] %s cfg80211_disconnected\n", prGlueInfo->prDevHandler->name); -+ cfg80211_disconnected(prGlueInfo->prDevHandler, u2DeauthReason, NULL, 0, false, GFP_KERNEL); -+ } -+ -+ prGlueInfo->eParamMediaStateIndicated = PARAM_MEDIA_STATE_DISCONNECTED; -+ -+ break; -+ -+ case WLAN_STATUS_SCAN_COMPLETE: -+ /* indicate scan complete event */ -+ wext_indicate_wext_event(prGlueInfo, SIOCGIWSCAN, NULL, 0); -+ -+ /* 1. reset first for newly incoming request */ -+ GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV); -+ if (prGlueInfo->prScanRequest != NULL) { -+ prScanRequest = prGlueInfo->prScanRequest; -+ prGlueInfo->prScanRequest = NULL; -+ } -+ GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV); -+ -+ /* 2. then CFG80211 Indication */ -+ DBGLOG(SCN, TRACE, "[ais] scan complete %p %d %d\n", prScanRequest, ScanCnt, ScanDoneFailCnt); -+ -+ if (prScanRequest != NULL) -+ cfg80211_scan_done(prScanRequest, &info); -+ break; -+ case WLAN_STATUS_CONNECT_INDICATION: -+ /* indicate AIS Jion fail event -+ if (prGlueInfo->prDevHandler->ieee80211_ptr->sme_state == CFG80211_SME_CONNECTING) */ -+ cfg80211_connect_result(prGlueInfo->prDevHandler, -+ prGlueInfo->prAdapter->rWifiVar.rAisFsmInfo.prTargetBssDesc->aucBSSID, -+ prGlueInfo->aucReqIe, -+ prGlueInfo->u4ReqIeLength, -+ prGlueInfo->aucRspIe, -+ prGlueInfo->u4RspIeLength, WLAN_STATUS_AUTH_TIMEOUT, GFP_KERNEL); -+ break; -+ -+#if 0 -+ case WLAN_STATUS_MSDU_OK: -+ if (netif_running(prGlueInfo->prDevHandler)) -+ netif_wake_queue(prGlueInfo->prDevHandler); -+ break; -+#endif -+ -+ case WLAN_STATUS_MEDIA_SPECIFIC_INDICATION: -+ if (pStatus) { -+ switch (pStatus->eStatusType) { -+ case ENUM_STATUS_TYPE_AUTHENTICATION: -+ /* -+ printk(KERN_NOTICE "ENUM_STATUS_TYPE_AUTHENTICATION: L(%ld) [ %pM ] F:%lx\n", -+ pAuth->Request[0].Length, -+ pAuth->Request[0].Bssid, -+ pAuth->Request[0].Flags); -+ */ -+ /* indicate (UC/GC) MIC ERROR event only */ -+ if ((pAuth->arRequest[0].u4Flags == -+ PARAM_AUTH_REQUEST_PAIRWISE_ERROR) || -+ (pAuth->arRequest[0].u4Flags == PARAM_AUTH_REQUEST_GROUP_ERROR)) { -+ cfg80211_michael_mic_failure(prGlueInfo->prDevHandler, NULL, -+ (pAuth->arRequest[0].u4Flags == -+ PARAM_AUTH_REQUEST_PAIRWISE_ERROR) ? -+ NL80211_KEYTYPE_PAIRWISE : NL80211_KEYTYPE_GROUP, -+ 0, NULL, GFP_KERNEL); -+ wext_indicate_wext_event(prGlueInfo, IWEVMICHAELMICFAILURE, -+ (unsigned char *)&pAuth->arRequest[0], -+ pAuth->arRequest[0].u4Length); -+ } -+ break; -+ -+ case ENUM_STATUS_TYPE_CANDIDATE_LIST: -+ /* -+ printk(KERN_NOTICE "Param_StatusType_PMKID_CandidateList: Ver(%ld) Num(%ld)\n", -+ pPmkid->u2Version, -+ pPmkid->u4NumCandidates); -+ if (pPmkid->u4NumCandidates > 0) { -+ printk(KERN_NOTICE "candidate[ %pM ] preAuth Flag:%lx\n", -+ pPmkid->arCandidateList[0].rBSSID, -+ pPmkid->arCandidateList[0].fgFlags); -+ } -+ */ -+ { -+ UINT_32 i = 0; -+ /*struct net_device *prDev = prGlueInfo->prDevHandler; */ -+ P_PARAM_PMKID_CANDIDATE_T prCand = NULL; -+ /* indicate pmk candidate via cfg80211 to supplicant, -+ the second parameter is 1000 for -+ cfg80211_pmksa_candidate_notify, because wpa_supplicant defined it. */ -+ for (i = 0; i < pPmkid->u4NumCandidates; i++) { -+ prCand = &pPmkid->arCandidateList[i]; -+ cfg80211_pmksa_candidate_notify(prGlueInfo->prDevHandler, 1000, -+ prCand->arBSSID, prCand->u4Flags, -+ GFP_KERNEL); -+ -+ wext_indicate_wext_event(prGlueInfo, -+ IWEVPMKIDCAND, -+ (unsigned char *)prCand, -+ pPmkid->u4NumCandidates); -+ } -+ } -+ break; -+ -+ default: -+ /* case ENUM_STATUS_TYPE_MEDIA_STREAM_MODE */ -+ /* -+ printk(KERN_NOTICE "unknown media specific indication type:%x\n", -+ pStatus->StatusType); -+ */ -+ break; -+ } -+ } else { -+ /* -+ printk(KERN_WARNING "media specific indication buffer NULL\n"); -+ */ -+ } -+ break; -+ -+#if CFG_SUPPORT_BCM && CFG_SUPPORT_BCM_BWCS -+ case WLAN_STATUS_BWCS_UPDATE: -+ { -+ wext_indicate_wext_event(prGlueInfo, IWEVCUSTOM, pvBuf, sizeof(PTA_IPC_T)); -+ } -+ -+ break; -+ -+#endif -+ -+ default: -+ /* -+ printk(KERN_WARNING "unknown indication:%lx\n", eStatus); -+ */ -+ break; -+ } -+} /* kalIndicateStatusAndComplete */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to update the (re)association request -+* information to the structure used to query and set -+* OID_802_11_ASSOCIATION_INFORMATION. -+* -+* \param[in] prGlueInfo Pointer to the Glue structure. -+* \param[in] pucFrameBody Pointer to the frame body of the last (Re)Association -+* Request frame from the AP. -+* \param[in] u4FrameBodyLen The length of the frame body of the last -+* (Re)Association Request frame. -+* \param[in] fgReassocRequest TRUE, if it is a Reassociation Request frame. -+* -+* \return (none) -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+kalUpdateReAssocReqInfo(IN P_GLUE_INFO_T prGlueInfo, -+ IN PUINT_8 pucFrameBody, IN UINT_32 u4FrameBodyLen, IN BOOLEAN fgReassocRequest) -+{ -+ PUINT_8 cp; -+ -+ ASSERT(prGlueInfo); -+ -+ /* reset */ -+ prGlueInfo->u4ReqIeLength = 0; -+ -+ if (fgReassocRequest) { -+ if (u4FrameBodyLen < 15) { -+ /* -+ printk(KERN_WARNING "frameBodyLen too short:%ld\n", frameBodyLen); -+ */ -+ return; -+ } -+ } else { -+ if (u4FrameBodyLen < 9) { -+ /* -+ printk(KERN_WARNING "frameBodyLen too short:%ld\n", frameBodyLen); -+ */ -+ return; -+ } -+ } -+ -+ cp = pucFrameBody; -+ -+ if (fgReassocRequest) { -+ /* Capability information field 2 */ -+ /* Listen interval field 2 */ -+ /* Current AP address 6 */ -+ cp += 10; -+ u4FrameBodyLen -= 10; -+ } else { -+ /* Capability information field 2 */ -+ /* Listen interval field 2 */ -+ cp += 4; -+ u4FrameBodyLen -= 4; -+ } -+ -+ wext_indicate_wext_event(prGlueInfo, IWEVASSOCREQIE, cp, u4FrameBodyLen); -+ -+ if (u4FrameBodyLen <= CFG_CFG80211_IE_BUF_LEN) { -+ prGlueInfo->u4ReqIeLength = u4FrameBodyLen; -+ kalMemCopy(prGlueInfo->aucReqIe, cp, u4FrameBodyLen); -+ } -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This routine is called to update the (re)association -+* response information to the structure used to reply with -+* cfg80211_connect_result -+* -+* @param prGlueInfo Pointer to adapter descriptor -+* @param pucFrameBody Pointer to the frame body of the last (Re)Association -+* Response frame from the AP -+* @param u4FrameBodyLen The length of the frame body of the last -+* (Re)Association Response frame -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID kalUpdateReAssocRspInfo(IN P_GLUE_INFO_T prGlueInfo, IN PUINT_8 pucFrameBody, IN UINT_32 u4FrameBodyLen) -+{ -+ UINT_32 u4IEOffset = 6; /* cap_info, status_code & assoc_id */ -+ UINT_32 u4IELength = u4FrameBodyLen - u4IEOffset; -+ -+ ASSERT(prGlueInfo); -+ -+ /* reset */ -+ prGlueInfo->u4RspIeLength = 0; -+ -+ if (u4IELength <= CFG_CFG80211_IE_BUF_LEN) { -+ prGlueInfo->u4RspIeLength = u4IELength; -+ kalMemCopy(prGlueInfo->aucRspIe, pucFrameBody + u4IEOffset, u4IELength); -+ } -+ -+} /* kalUpdateReAssocRspInfo */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Notify OS with SendComplete event of the specific packet. Linux should -+* free packets here. -+* -+* \param[in] prGlueInfo Pointer of GLUE Data Structure -+* \param[in] pvPacket Pointer of Packet Handle -+* \param[in] status Status Code for OS upper layer -+* -+* \return - -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID kalSendCompleteAndAwakeQueue(IN P_GLUE_INFO_T prGlueInfo, IN PVOID pvPacket) -+{ -+ -+ struct net_device *prDev = NULL; -+ struct sk_buff *prSkb = NULL; -+ UINT_16 u2QueueIdx = 0; -+ UINT_8 ucNetworkType = 0; -+ BOOLEAN fgIsValidDevice = TRUE; -+ -+ ASSERT(pvPacket); -+ ASSERT(prGlueInfo->i4TxPendingFrameNum); -+ -+ prSkb = (struct sk_buff *)pvPacket; -+ u2QueueIdx = skb_get_queue_mapping(prSkb); -+ ASSERT(u2QueueIdx < CFG_MAX_TXQ_NUM); -+ -+ if (GLUE_GET_PKT_IS_PAL(prSkb)) { -+ ucNetworkType = NETWORK_TYPE_BOW_INDEX; -+ } else if (GLUE_GET_PKT_IS_P2P(prSkb)) { -+ ucNetworkType = NETWORK_TYPE_P2P_INDEX; -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ /* in case packet was sent after P2P device is unregistered */ -+ if (prGlueInfo->prAdapter->fgIsP2PRegistered == FALSE) -+ fgIsValidDevice = FALSE; -+#endif -+ } else { -+ ucNetworkType = NETWORK_TYPE_AIS_INDEX; -+ } -+ -+ GLUE_DEC_REF_CNT(prGlueInfo->i4TxPendingFrameNum); -+ if (u2QueueIdx < CFG_MAX_TXQ_NUM) -+ GLUE_DEC_REF_CNT(prGlueInfo->ai4TxPendingFrameNumPerQueue[ucNetworkType][u2QueueIdx]); -+ prDev = prSkb->dev; -+ -+ ASSERT(prDev); -+ -+ if ((fgIsValidDevice == TRUE) && (u2QueueIdx < CFG_MAX_TXQ_NUM)) { -+ if (netif_subqueue_stopped(prDev, prSkb) && -+ prGlueInfo->ai4TxPendingFrameNumPerQueue[ucNetworkType][u2QueueIdx] <= -+ CFG_TX_START_NETIF_PER_QUEUE_THRESHOLD) { -+ DBGLOG(TX, INFO, "netif_wake_subqueue for bss: %d. Queue len: %d\n", -+ ucNetworkType, -+ prGlueInfo->ai4TxPendingFrameNumPerQueue[ucNetworkType][u2QueueIdx]); -+ netif_wake_subqueue(prDev, u2QueueIdx); -+ -+#if (CONF_HIF_LOOPBACK_AUTO == 1) -+ prGlueInfo->rHifInfo.HifLoopbkFlg &= ~0x01; -+#endif /* CONF_HIF_LOOPBACK_AUTO */ -+ } -+ } -+ -+ dev_kfree_skb((struct sk_buff *)pvPacket); -+ prGlueInfo->u8SkbFreed++; -+ -+ DBGLOG(TX, EVENT, "----- pending frame %d -----\n", prGlueInfo->i4TxPendingFrameNum); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Copy Mac Address setting from registry. It's All Zeros in Linux. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* -+* \param[out] paucMacAddr Pointer to the Mac Address buffer -+* -+* \retval WLAN_STATUS_SUCCESS -+* -+* \note -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID kalQueryRegistryMacAddr(IN P_GLUE_INFO_T prGlueInfo, OUT PUINT_8 paucMacAddr) -+{ -+ UINT_8 aucZeroMac[MAC_ADDR_LEN] = { 0, 0, 0, 0, 0, 0 } -+ -+ DEBUGFUNC("kalQueryRegistryMacAddr"); -+ -+ ASSERT(prGlueInfo); -+ ASSERT(paucMacAddr); -+ -+ kalMemCopy((PVOID) paucMacAddr, (PVOID) aucZeroMac, MAC_ADDR_LEN); -+ -+} /* end of kalQueryRegistryMacAddr() */ -+ -+#if CFG_SUPPORT_EXT_CONFIG -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Read external configuration, ex. NVRAM or file -+* -+* \param[in] prGlueInfo Pointer of GLUE Data Structure -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT_32 kalReadExtCfg(IN P_GLUE_INFO_T prGlueInfo) -+{ -+ ASSERT(prGlueInfo); -+ -+ /* External data is given from user space by ioctl or /proc, not read by -+ driver. -+ */ -+ if (0 != prGlueInfo->u4ExtCfgLength) -+ DBGLOG(INIT, TRACE, "Read external configuration data -- OK\n"); -+ else -+ DBGLOG(INIT, TRACE, "Read external configuration data -- fail\n"); -+ -+ return prGlueInfo->u4ExtCfgLength; -+} -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This inline function is to extract some packet information, including -+* user priority, packet length, destination address, 802.1x and BT over Wi-Fi -+* or not. -+* -+* @param prGlueInfo Pointer to the glue structure -+* @param prNdisPacket Packet descriptor -+* @param pucPriorityParam User priority -+* @param pu4PacketLen Packet length -+* @param pucEthDestAddr Destination address -+* @param pfgIs1X 802.1x packet or not -+* @param pfgIsPAL BT over Wi-Fi packet or not -+* @prGenUse General used param -+* -+* @retval TRUE Success to extract information -+* @retval FALSE Fail to extract correct information -+*/ -+/*----------------------------------------------------------------------------*/ -+ -+BOOLEAN -+kalQoSFrameClassifierAndPacketInfo(IN P_GLUE_INFO_T prGlueInfo, -+ IN P_NATIVE_PACKET prPacket, -+ OUT PUINT_8 pucPriorityParam, -+ OUT PUINT_32 pu4PacketLen, -+ OUT PUINT_8 pucEthDestAddr, -+ OUT PBOOLEAN pfgIs1X, -+ OUT PBOOLEAN pfgIsPAL, OUT PUINT_8 pucNetworkType, -+ OUT PVOID prGenUse) -+{ -+ -+ UINT_32 u4PacketLen; -+ -+ UINT_8 ucUserPriority = USER_PRIORITY_DEFAULT; /* Default */ -+ UINT_16 u2EtherTypeLen; -+ struct sk_buff *prSkb = (struct sk_buff *)prPacket; -+ PUINT_8 aucLookAheadBuf = NULL; -+ -+ DEBUGFUNC("kalQoSFrameClassifierAndPacketInfo"); -+ -+ u4PacketLen = prSkb->len; -+ -+ if (u4PacketLen < ETH_HLEN) { -+ DBGLOG(TX, WARN, "Invalid Ether packet length: %u\n", (UINT_32) u4PacketLen); -+ return FALSE; -+ } -+ -+ aucLookAheadBuf = prSkb->data; -+ -+ *pfgIs1X = FALSE; -+ *pfgIsPAL = FALSE; -+ -+ /* 4 <3> Obtain the User Priority for WMM */ -+ u2EtherTypeLen = (aucLookAheadBuf[ETH_TYPE_LEN_OFFSET] << 8) | (aucLookAheadBuf[ETH_TYPE_LEN_OFFSET + 1]); -+ -+ if ((u2EtherTypeLen == ETH_P_IP) && (u4PacketLen >= LOOK_AHEAD_LEN)) { -+ PUINT_8 pucIpHdr = &aucLookAheadBuf[ETH_HLEN]; -+ UINT_8 ucIpVersion; -+ -+ ucIpVersion = (pucIpHdr[0] & IPVH_VERSION_MASK) >> IPVH_VERSION_OFFSET; -+ if (ucIpVersion == IPVERSION) { -+ UINT_8 ucIpTos; -+ /* Get the DSCP value from the header of IP packet. */ -+ ucIpTos = pucIpHdr[1]; -+ ucUserPriority = ((ucIpTos & IPTOS_PREC_MASK) >> IPTOS_PREC_OFFSET); -+ } -+ -+ /* TODO(Kevin): Add TSPEC classifier here */ -+ } else if (u2EtherTypeLen == ETH_P_1X || u2EtherTypeLen == ETH_P_PRE_1X) { /* For Port Control */ -+ PUINT_8 pucEapol = &aucLookAheadBuf[ETH_HLEN]; -+ UINT_8 ucEapolType = pucEapol[1]; -+ UINT_16 u2KeyInfo = pucEapol[5]<<8 | pucEapol[6]; -+ /* -+ * generate a seq number used to trace security frame TX -+ */ -+ if (prGenUse) -+ *(UINT_8 *)prGenUse = nicIncreaseCmdSeqNum(prGlueInfo->prAdapter); -+ -+ switch (ucEapolType) { -+ case 0: /* eap packet */ -+ DBGLOG(TX, INFO, " EAP Packet: code %d, id %d, type %d, seqNo %d\n", -+ pucEapol[4], pucEapol[5], pucEapol[7], -+ prGenUse ? *(UINT_8 *)prGenUse : 0); -+ break; -+ case 1: /* eapol start */ -+ DBGLOG(TX, INFO, " EAPOL: start, seqNo %d\n", -+ prGenUse ? *(UINT_8 *)prGenUse : 0); -+ break; -+ case 3: /* key */ -+ DBGLOG(TX, INFO, -+ " EAPOL: key, KeyInfo 0x%04x, Nonce %02x%02x%02x%02x%02x%02x%02x%02x... seqNo %d\n", -+ u2KeyInfo, pucEapol[17], pucEapol[18], pucEapol[19], pucEapol[20], -+ pucEapol[21], pucEapol[22], pucEapol[23], pucEapol[24], -+ prGenUse ? *(UINT_8 *)prGenUse : 0); -+ break; -+ } -+ *pfgIs1X = TRUE; -+ } -+#if CFG_SUPPORT_WAPI -+ else if (u2EtherTypeLen == ETH_WPI_1X) { -+ PUINT_8 pucEthBody = &aucLookAheadBuf[ETH_HLEN]; -+ UINT_8 ucSubType = pucEthBody[3]; /* sub type filed*/ -+ UINT_16 u2Length = *(PUINT_16)&pucEthBody[6]; -+ UINT_16 u2Seq = *(PUINT_16)&pucEthBody[8]; -+ -+ DBGLOG(TX, INFO, " WAPI: subType %d, Len %d, Seq %d\n", -+ ucSubType, u2Length, u2Seq); -+ *pfgIs1X = TRUE; -+ } -+#endif -+#if (CFG_SUPPORT_TDLS == 1) -+ else if (u2EtherTypeLen == TDLS_FRM_PROT_TYPE) { -+ /* TDLS case */ -+ TDLSEX_UP_ASSIGN(ucUserPriority); -+ } -+#endif /* CFG_SUPPORT_TDLS */ -+ else if (u2EtherTypeLen <= 1500) { /* 802.3 Frame */ -+ UINT_8 ucDSAP, ucSSAP, ucControl; -+ UINT_8 aucOUI[3]; -+ -+ ucDSAP = *(PUINT_8) &aucLookAheadBuf[ETH_LLC_OFFSET]; -+ ucSSAP = *(PUINT_8) &aucLookAheadBuf[ETH_LLC_OFFSET + 1]; -+ ucControl = *(PUINT_8) &aucLookAheadBuf[ETH_LLC_OFFSET + 2]; -+ -+ aucOUI[0] = *(PUINT_8) &aucLookAheadBuf[ETH_SNAP_OFFSET]; -+ aucOUI[1] = *(PUINT_8) &aucLookAheadBuf[ETH_SNAP_OFFSET + 1]; -+ aucOUI[2] = *(PUINT_8) &aucLookAheadBuf[ETH_SNAP_OFFSET + 2]; -+ -+ if (ucDSAP == ETH_LLC_DSAP_SNAP && -+ ucSSAP == ETH_LLC_SSAP_SNAP && -+ ucControl == ETH_LLC_CONTROL_UNNUMBERED_INFORMATION && -+ aucOUI[0] == ETH_SNAP_BT_SIG_OUI_0 && -+ aucOUI[1] == ETH_SNAP_BT_SIG_OUI_1 && aucOUI[2] == ETH_SNAP_BT_SIG_OUI_2) { -+ -+ UINT_16 tmp = -+ ((aucLookAheadBuf[ETH_SNAP_OFFSET + 3] << 8) | aucLookAheadBuf[ETH_SNAP_OFFSET + 4]); -+ -+ *pfgIsPAL = TRUE; -+ ucUserPriority = (UINT_8) prSkb->priority; -+ -+ if (tmp == BOW_PROTOCOL_ID_SECURITY_FRAME) { -+ PUINT_8 pucEapol = &aucLookAheadBuf[ETH_SNAP_OFFSET + 5]; -+ UINT_8 ucEapolType = pucEapol[1]; -+ UINT_16 u2KeyInfo = pucEapol[5]<<8 | pucEapol[6]; -+ if (prGenUse) -+ *(UINT_8 *)prGenUse = nicIncreaseCmdSeqNum(prGlueInfo->prAdapter); -+ -+ switch (ucEapolType) { -+ case 0: /* eap packet */ -+ DBGLOG(TX, INFO, " EAP Packet: code %d, id %d, type %d, seqNo %d\n", -+ pucEapol[4], pucEapol[5], pucEapol[7], -+ prGenUse ? *(UINT_8 *)prGenUse : 0); -+ break; -+ case 1: /* eapol start */ -+ DBGLOG(TX, INFO, " EAPOL: start, seqNo %d\n", -+ prGenUse ? *(UINT_8 *)prGenUse : 0); -+ break; -+ case 3: /* key */ -+ DBGLOG(TX, INFO, -+ " EAPOL: key, KeyInfo 0x%04x, Nonce %02x%02x%02x%02x%02x%02x%02x%02x seqNo %d\n", -+ u2KeyInfo, pucEapol[17], pucEapol[18], pucEapol[19], pucEapol[20], -+ pucEapol[21], pucEapol[22], pucEapol[23], pucEapol[24], -+ prGenUse ? *(UINT_8 *)prGenUse : 0); -+ break; -+ } -+ *pfgIs1X = TRUE; -+ } -+ } -+ } -+ /* 4 <4> Return the value of Priority Parameter. */ -+ *pucPriorityParam = ucUserPriority; -+ -+ /* 4 <5> Retrieve Packet Information - DA */ -+ /* Packet Length/ Destination Address */ -+ *pu4PacketLen = u4PacketLen; -+ -+ kalMemCopy(pucEthDestAddr, aucLookAheadBuf, PARAM_MAC_ADDR_LEN); -+ -+ /* <6> Network type */ -+#if CFG_ENABLE_BT_OVER_WIFI -+ if (*pfgIsPAL == TRUE) { -+ *pucNetworkType = NETWORK_TYPE_BOW_INDEX; -+ } else -+#endif -+ { -+#if CFG_ENABLE_WIFI_DIRECT -+ if (prGlueInfo->prAdapter->fgIsP2PRegistered && GLUE_GET_PKT_IS_P2P(prPacket)) { -+ *pucNetworkType = NETWORK_TYPE_P2P_INDEX; -+ } else -+#endif -+ { -+ *pucNetworkType = NETWORK_TYPE_AIS_INDEX; -+ } -+ } -+ return TRUE; -+} /* end of kalQoSFrameClassifier() */ -+ -+VOID -+kalOidComplete(IN P_GLUE_INFO_T prGlueInfo, -+ IN BOOLEAN fgSetQuery, IN UINT_32 u4SetQueryInfoLen, IN WLAN_STATUS rOidStatus) -+{ -+ -+ ASSERT(prGlueInfo); -+ /* remove timeout check timer */ -+ wlanoidClearTimeoutCheck(prGlueInfo->prAdapter); -+ -+ /* if (prGlueInfo->u4TimeoutFlag != 1) { */ -+ prGlueInfo->rPendStatus = rOidStatus; -+ DBGLOG(OID, TEMP, "kalOidComplete, caller: %p\n", __builtin_return_address(0)); -+ complete(&prGlueInfo->rPendComp); -+ prGlueInfo->u4OidCompleteFlag = 1; -+ /* } */ -+ /* else let it timeout on kalIoctl entry */ -+} -+ -+VOID kalOidClearance(IN P_GLUE_INFO_T prGlueInfo) -+{ -+ /* if (prGlueInfo->u4TimeoutFlag != 1) { */ -+ /* clear_bit(GLUE_FLAG_OID_BIT, &prGlueInfo->u4Flag); */ -+ if (prGlueInfo->u4OidCompleteFlag != 1) { -+ DBGLOG(OID, TEMP, "kalOidClearance, caller: %p\n", __builtin_return_address(0)); -+ complete(&prGlueInfo->rPendComp); -+ } -+ /* } */ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is used to transfer linux ioctl to OID, and we -+* need to specify the behavior of the OID by ourself -+* -+* @param prGlueInfo Pointer to the glue structure -+* @param pvInfoBuf Data buffer -+* @param u4InfoBufLen Data buffer length -+* @param fgRead Is this a read OID -+* @param fgWaitResp does this OID need to wait for values -+* @param fgCmd does this OID compose command packet -+* @param pu4QryInfoLen The data length of the return values -+* -+* @retval TRUE Success to extract information -+* @retval FALSE Fail to extract correct information -+*/ -+/*----------------------------------------------------------------------------*/ -+ -+/* todo: enqueue the i/o requests for multiple processes access */ -+/* */ -+/* currently, return -1 */ -+/* */ -+ -+/* static GL_IO_REQ_T OidEntry; */ -+ -+WLAN_STATUS -+kalIoctl(IN P_GLUE_INFO_T prGlueInfo, -+ IN PFN_OID_HANDLER_FUNC pfnOidHandler, -+ IN PVOID pvInfoBuf, -+ IN UINT_32 u4InfoBufLen, -+ IN BOOLEAN fgRead, IN BOOLEAN fgWaitResp, IN BOOLEAN fgCmd, IN BOOLEAN fgIsP2pOid, OUT PUINT_32 pu4QryInfoLen) -+{ -+ P_GL_IO_REQ_T prIoReq = NULL; -+ WLAN_STATUS ret = WLAN_STATUS_SUCCESS; -+ -+ if (fgIsResetting == TRUE) -+ return WLAN_STATUS_SUCCESS; -+ -+ /* GLUE_SPIN_LOCK_DECLARATION(); */ -+ ASSERT(prGlueInfo); -+ -+ /* <1> Check if driver is halt */ -+ /* if (prGlueInfo->u4Flag & GLUE_FLAG_HALT) { */ -+ /* return WLAN_STATUS_ADAPTER_NOT_READY; */ -+ /* } */ -+ -+ /* if wait longer than double OID timeout timer, then will show backtrace who held halt lock. -+ at this case, we will return kalIoctl failure because tx_thread may be hung */ -+ if (kalHaltLock(2 * WLAN_OID_TIMEOUT_THRESHOLD)) -+ return WLAN_STATUS_FAILURE; -+ -+ if (kalIsHalted()) { -+ kalHaltUnlock(); -+ return WLAN_STATUS_ADAPTER_NOT_READY; -+ } -+ -+ if (down_interruptible(&prGlueInfo->ioctl_sem)) { -+ kalHaltUnlock(); -+ return WLAN_STATUS_FAILURE; -+ } -+ -+ /* <2> TODO: thread-safe */ -+ -+ /* <3> point to the OidEntry of Glue layer */ -+ -+ prIoReq = &(prGlueInfo->OidEntry); -+ -+ ASSERT(prIoReq); -+ -+ /* <4> Compose the I/O request */ -+ prIoReq->prAdapter = prGlueInfo->prAdapter; -+ prIoReq->pfnOidHandler = pfnOidHandler; -+ prIoReq->pvInfoBuf = pvInfoBuf; -+ prIoReq->u4InfoBufLen = u4InfoBufLen; -+ prIoReq->pu4QryInfoLen = pu4QryInfoLen; -+ prIoReq->fgRead = fgRead; -+ prIoReq->fgWaitResp = fgWaitResp; -+ prIoReq->rStatus = WLAN_STATUS_FAILURE; -+#if CFG_ENABLE_WIFI_DIRECT -+ prIoReq->fgIsP2pOid = fgIsP2pOid; -+#endif -+ -+ /* <5> Reset the status of pending OID */ -+ prGlueInfo->rPendStatus = WLAN_STATUS_FAILURE; -+ /* prGlueInfo->u4TimeoutFlag = 0; */ -+ /* prGlueInfo->u4OidCompleteFlag = 0; */ -+ -+ /* <6> Check if we use the command queue */ -+ prIoReq->u4Flag = fgCmd; -+ -+ /* <7> schedule the OID bit */ -+ set_bit(GLUE_FLAG_OID_BIT, &prGlueInfo->ulFlag); -+ -+ /* <8> Wake up tx thread to handle kick start the I/O request */ -+ wake_up_interruptible(&prGlueInfo->waitq); -+ -+ /* <9> Block and wait for event or timeout, current the timeout is 5 secs */ -+ /* if (wait_for_completion_interruptible_timeout(&prGlueInfo->rPendComp, 5 * KAL_HZ)) { */ -+ /* if (!wait_for_completion_interruptible(&prGlueInfo->rPendComp)) { */ -+ DBGLOG(OID, TEMP, "kalIoctl: before wait, caller: %p\n", __builtin_return_address(0)); -+ wait_for_completion(&prGlueInfo->rPendComp); { -+ /* Case 1: No timeout. */ -+ /* if return WLAN_STATUS_PENDING, the status of cmd is stored in prGlueInfo */ -+ if (prIoReq->rStatus == WLAN_STATUS_PENDING) -+ ret = prGlueInfo->rPendStatus; -+ else -+ ret = prIoReq->rStatus; -+ } -+#if 0 -+ else { -+ /* Case 2: timeout */ -+ /* clear pending OID's cmd in CMD queue */ -+ if (fgCmd) { -+ prGlueInfo->u4TimeoutFlag = 1; -+ wlanReleasePendingOid(prGlueInfo->prAdapter, 0); -+ } -+ ret = WLAN_STATUS_FAILURE; -+ } -+#endif -+ DBGLOG(OID, TEMP, "kalIoctl: done\n"); -+ up(&prGlueInfo->ioctl_sem); -+ kalHaltUnlock(); -+ -+ return ret; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is used to clear all pending security frames -+* -+* \param prGlueInfo Pointer of GLUE Data Structure -+* -+* \retval none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID kalClearSecurityFrames(IN P_GLUE_INFO_T prGlueInfo) -+{ -+ P_QUE_T prCmdQue; -+ QUE_T rTempCmdQue; -+ P_QUE_T prTempCmdQue = &rTempCmdQue; -+ P_QUE_ENTRY_T prQueueEntry = (P_QUE_ENTRY_T) NULL; -+ P_CMD_INFO_T prCmdInfo = (P_CMD_INFO_T) NULL; -+ -+ GLUE_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(prGlueInfo); -+ -+ /* Clear pending security frames in prGlueInfo->rCmdQueue */ -+ prCmdQue = &prGlueInfo->rCmdQueue; -+ -+ GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE); -+ QUEUE_MOVE_ALL(prTempCmdQue, prCmdQue); -+ -+ QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T); -+ while (prQueueEntry) { -+ prCmdInfo = (P_CMD_INFO_T) prQueueEntry; -+ -+ if (prCmdInfo->eCmdType == COMMAND_TYPE_SECURITY_FRAME) { -+ prCmdInfo->pfCmdTimeoutHandler(prGlueInfo->prAdapter, prCmdInfo); -+ cmdBufFreeCmdInfo(prGlueInfo->prAdapter, prCmdInfo); -+ } else { -+ QUEUE_INSERT_TAIL(prCmdQue, prQueueEntry); -+ } -+ -+ QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T); -+ } -+ -+ QUEUE_CONCATENATE_QUEUES(prCmdQue, prTempCmdQue); -+ GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is used to clear pending security frames -+* belongs to dedicated network type -+* -+* \param prGlueInfo Pointer of GLUE Data Structure -+* \param eNetworkTypeIdx Network Type Index -+* -+* \retval none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID kalClearSecurityFramesByNetType(IN P_GLUE_INFO_T prGlueInfo, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx) -+{ -+ P_QUE_T prCmdQue; -+ QUE_T rTempCmdQue; -+ P_QUE_T prTempCmdQue = &rTempCmdQue; -+ P_QUE_ENTRY_T prQueueEntry = (P_QUE_ENTRY_T) NULL; -+ -+ P_CMD_INFO_T prCmdInfo = (P_CMD_INFO_T) NULL; -+ -+ GLUE_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(prGlueInfo); -+ -+ /* Clear pending security frames in prGlueInfo->rCmdQueue */ -+ prCmdQue = &prGlueInfo->rCmdQueue; -+ -+ GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE); -+ QUEUE_MOVE_ALL(prTempCmdQue, prCmdQue); -+ -+ QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T); -+ while (prQueueEntry) { -+ prCmdInfo = (P_CMD_INFO_T) prQueueEntry; -+ -+ if (prCmdInfo->eCmdType == COMMAND_TYPE_SECURITY_FRAME && prCmdInfo->eNetworkType == eNetworkTypeIdx) { -+ prCmdInfo->pfCmdTimeoutHandler(prGlueInfo->prAdapter, prCmdInfo); -+ cmdBufFreeCmdInfo(prGlueInfo->prAdapter, prCmdInfo); -+ } else { -+ QUEUE_INSERT_TAIL(prCmdQue, prQueueEntry); -+ } -+ -+ QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T); -+ } -+ -+ QUEUE_CONCATENATE_QUEUES(prCmdQue, prTempCmdQue); -+ GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is used to clear all pending management frames -+* -+* \param prGlueInfo Pointer of GLUE Data Structure -+* -+* \retval none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID kalClearMgmtFrames(IN P_GLUE_INFO_T prGlueInfo) -+{ -+ P_QUE_T prCmdQue; -+ QUE_T rTempCmdQue; -+ P_QUE_T prTempCmdQue = &rTempCmdQue; -+ P_QUE_ENTRY_T prQueueEntry = (P_QUE_ENTRY_T) NULL; -+ P_CMD_INFO_T prCmdInfo = (P_CMD_INFO_T) NULL; -+ -+ GLUE_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(prGlueInfo); -+ -+ /* Clear pending management frames in prGlueInfo->rCmdQueue */ -+ prCmdQue = &prGlueInfo->rCmdQueue; -+ -+ GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE); -+ QUEUE_MOVE_ALL(prTempCmdQue, prCmdQue); -+ -+ QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T); -+ while (prQueueEntry) { -+ prCmdInfo = (P_CMD_INFO_T) prQueueEntry; -+ -+ if (prCmdInfo->eCmdType == COMMAND_TYPE_MANAGEMENT_FRAME) { -+ wlanReleaseCommand(prGlueInfo->prAdapter, prCmdInfo); -+ cmdBufFreeCmdInfo(prGlueInfo->prAdapter, prCmdInfo); -+ } else { -+ QUEUE_INSERT_TAIL(prCmdQue, prQueueEntry); -+ } -+ -+ QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T); -+ } -+ -+ QUEUE_CONCATENATE_QUEUES(prCmdQue, prTempCmdQue); -+ GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is used to clear all pending management frames -+* belongs to dedicated network type -+* \param prGlueInfo Pointer of GLUE Data Structure -+* -+* \retval none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID kalClearMgmtFramesByNetType(IN P_GLUE_INFO_T prGlueInfo, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx) -+{ -+ P_QUE_T prCmdQue; -+ QUE_T rTempCmdQue; -+ P_QUE_T prTempCmdQue = &rTempCmdQue; -+ P_QUE_ENTRY_T prQueueEntry = (P_QUE_ENTRY_T) NULL; -+ P_CMD_INFO_T prCmdInfo = (P_CMD_INFO_T) NULL; -+ -+ GLUE_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(prGlueInfo); -+ -+ /* Clear pending management frames in prGlueInfo->rCmdQueue */ -+ prCmdQue = &prGlueInfo->rCmdQueue; -+ -+ GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE); -+ QUEUE_MOVE_ALL(prTempCmdQue, prCmdQue); -+ -+ QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T); -+ while (prQueueEntry) { -+ prCmdInfo = (P_CMD_INFO_T) prQueueEntry; -+ -+ if (prCmdInfo->eCmdType == COMMAND_TYPE_MANAGEMENT_FRAME && -+ prCmdInfo->eNetworkType == eNetworkTypeIdx) { -+ wlanReleaseCommand(prGlueInfo->prAdapter, prCmdInfo); -+ cmdBufFreeCmdInfo(prGlueInfo->prAdapter, prCmdInfo); -+ } else { -+ QUEUE_INSERT_TAIL(prCmdQue, prQueueEntry); -+ } -+ -+ QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T); -+ } -+ -+ QUEUE_CONCATENATE_QUEUES(prCmdQue, prTempCmdQue); -+ GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE); -+} /* kalClearMgmtFramesByNetType */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is a kernel thread function for handling command packets -+* Tx requests and interrupt events -+* -+* @param data data pointer to private data of tx_thread -+* -+* @retval If the function succeeds, the return value is 0. -+* Otherwise, an error code is returned. -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+ -+int tx_thread(void *data) -+{ -+ struct net_device *dev = data; -+ P_GLUE_INFO_T prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(dev)); -+ -+ P_QUE_ENTRY_T prQueueEntry = NULL; -+ P_GL_IO_REQ_T prIoReq = NULL; -+ P_QUE_T prTxQueue = NULL; -+ P_QUE_T prCmdQue = NULL; -+ -+ int ret = 0; -+ -+ BOOLEAN fgNeedHwAccess = FALSE; -+ -+ struct sk_buff *prSkb = NULL; -+ -+ /* for spin lock acquire and release */ -+ GLUE_SPIN_LOCK_DECLARATION(); -+ -+ prTxQueue = &prGlueInfo->rTxQueue; -+ prCmdQue = &prGlueInfo->rCmdQueue; -+ -+ current->flags |= PF_NOFREEZE; -+ -+ DBGLOG(INIT, INFO, "tx_thread starts running...\n"); -+ -+ while (TRUE) { -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ /*run p2p multicast list work. */ -+ if (test_and_clear_bit(GLUE_FLAG_SUB_MOD_MULTICAST_BIT, &prGlueInfo->ulFlag)) -+ p2pSetMulticastListWorkQueueWrapper(prGlueInfo); -+#endif -+ -+ if (test_and_clear_bit(GLUE_FLAG_FRAME_FILTER_AIS_BIT, &prGlueInfo->ulFlag)) { -+ P_AIS_FSM_INFO_T prAisFsmInfo = (P_AIS_FSM_INFO_T) NULL; -+ /* printk("prGlueInfo->u4OsMgmtFrameFilter = %x", prGlueInfo->u4OsMgmtFrameFilter); */ -+ prAisFsmInfo = &(prGlueInfo->prAdapter->rWifiVar.rAisFsmInfo); -+ prAisFsmInfo->u4AisPacketFilter = prGlueInfo->u4OsMgmtFrameFilter; -+ } -+ -+ if (prGlueInfo->ulFlag & GLUE_FLAG_HALT) { -+ KAL_WAKE_UNLOCK(prGlueInfo->prAdapter, &(prGlueInfo->prAdapter)->rTxThreadWakeLock); -+ DBGLOG(INIT, INFO, "tx_thread should stop now...\n"); -+ break; -+ } -+ -+ /* -+ * sleep on waitqueue if no events occurred. Event contain (1) GLUE_FLAG_INT -+ * (2) GLUE_FLAG_OID (3) GLUE_FLAG_TXREQ (4) GLUE_FLAG_HALT -+ * -+ */ -+ KAL_WAKE_UNLOCK(prGlueInfo->prAdapter, &(prGlueInfo->prAdapter)->rTxThreadWakeLock); -+ -+ ret = wait_event_interruptible(prGlueInfo->waitq, (prGlueInfo->ulFlag != 0)); -+ -+ KAL_WAKE_LOCK(prGlueInfo->prAdapter, &(prGlueInfo->prAdapter)->rTxThreadWakeLock); -+ -+/* #if (CONF_HIF_LOOPBACK_AUTO == 1) */ -+/* if (test_and_clear_bit(GLUE_FLAG_HIF_LOOPBK_AUTO_BIT, &prGlueInfo->u4Flag)) { */ -+/* kalDevLoopbkAuto(prGlueInfo); */ -+/* } */ -+/* #endif */ /* CONF_HIF_LOOPBACK_AUTO */ -+ -+#if CFG_DBG_GPIO_PINS -+ /* TX thread Wake up */ -+ mtk_wcn_stp_debug_gpio_assert(IDX_TX_THREAD, DBG_TIE_LOW); -+#endif -+#if CFG_ENABLE_WIFI_DIRECT -+ /*run p2p multicast list work. */ -+ if (test_and_clear_bit(GLUE_FLAG_SUB_MOD_MULTICAST_BIT, &prGlueInfo->ulFlag)) -+ p2pSetMulticastListWorkQueueWrapper(prGlueInfo); -+ -+ if (test_and_clear_bit(GLUE_FLAG_FRAME_FILTER_BIT, &prGlueInfo->ulFlag)) { -+ p2pFuncUpdateMgmtFrameRegister(prGlueInfo->prAdapter, -+ prGlueInfo->prP2PInfo->u4OsMgmtFrameFilter); -+ } -+#endif -+ if (test_and_clear_bit(GLUE_FLAG_FRAME_FILTER_AIS_BIT, &prGlueInfo->ulFlag)) { -+ P_AIS_FSM_INFO_T prAisFsmInfo = (P_AIS_FSM_INFO_T) NULL; -+ /* printk("prGlueInfo->u4OsMgmtFrameFilter = %x", prGlueInfo->u4OsMgmtFrameFilter); */ -+ prAisFsmInfo = &(prGlueInfo->prAdapter->rWifiVar.rAisFsmInfo); -+ prAisFsmInfo->u4AisPacketFilter = prGlueInfo->u4OsMgmtFrameFilter; -+ } -+ -+ if (prGlueInfo->ulFlag & GLUE_FLAG_HALT) { -+ KAL_WAKE_UNLOCK(prGlueInfo->prAdapter, &(prGlueInfo->prAdapter)->rTxThreadWakeLock); -+ DBGLOG(INIT, INFO, "<1>tx_thread should stop now...\n"); -+ break; -+ } -+ -+ fgNeedHwAccess = FALSE; -+ -+ /* Handle Interrupt */ -+ if (test_and_clear_bit(GLUE_FLAG_INT_BIT, &prGlueInfo->ulFlag)) { -+ if (fgNeedHwAccess == FALSE) { -+ fgNeedHwAccess = TRUE; -+ -+ wlanAcquirePowerControl(prGlueInfo->prAdapter); -+ } -+ -+ /* the Wi-Fi interrupt is already disabled in mmc thread, -+ so we set the flag only to enable the interrupt later */ -+ prGlueInfo->prAdapter->fgIsIntEnable = FALSE; -+ /* wlanISR(prGlueInfo->prAdapter, TRUE); */ -+ -+ if (prGlueInfo->ulFlag & GLUE_FLAG_HALT) { -+ /* Should stop now... skip pending interrupt */ -+ DBGLOG(INIT, INFO, "ignore pending interrupt\n"); -+ } else { -+ prGlueInfo->TaskIsrCnt++; -+ wlanIST(prGlueInfo->prAdapter); -+ } -+ } -+ -+ /* transfer ioctl to OID request */ -+#if 0 -+ if (prGlueInfo->u4Flag & GLUE_FLAG_HALT) { -+ DBGLOG(INIT, INFO, "<2>tx_thread should stop now...\n"); -+ break; -+ } -+#endif -+ -+ do { -+ if (test_and_clear_bit(GLUE_FLAG_OID_BIT, &prGlueInfo->ulFlag)) { -+ /* get current prIoReq */ -+ prGlueInfo->u4OidCompleteFlag = 0; -+ -+ prIoReq = &(prGlueInfo->OidEntry); -+#if CFG_ENABLE_WIFI_DIRECT -+ if (prGlueInfo->prAdapter->fgIsP2PRegistered == FALSE && prIoReq->fgIsP2pOid == TRUE) { -+ /* if this Oid belongs to p2p and p2p module is removed -+ * do nothing, -+ */ -+ } else -+#endif -+ { -+ if (FALSE == prIoReq->fgRead) { -+ prIoReq->rStatus = wlanSetInformation(prIoReq->prAdapter, -+ prIoReq->pfnOidHandler, -+ prIoReq->pvInfoBuf, -+ prIoReq->u4InfoBufLen, -+ prIoReq->pu4QryInfoLen); -+ } else { -+ prIoReq->rStatus = wlanQueryInformation(prIoReq->prAdapter, -+ prIoReq->pfnOidHandler, -+ prIoReq->pvInfoBuf, -+ prIoReq->u4InfoBufLen, -+ prIoReq->pu4QryInfoLen); -+ } -+ -+ if (prIoReq->rStatus != WLAN_STATUS_PENDING) { -+ DBGLOG(OID, TEMP, "tx_thread, complete\n"); -+ complete(&prGlueInfo->rPendComp); -+ } else { -+ wlanoidTimeoutCheck(prGlueInfo->prAdapter, prIoReq->pfnOidHandler); -+ } -+ } -+ } -+ -+ } while (FALSE); -+ -+ /* -+ * -+ * if TX request, clear the TXREQ flag. TXREQ set by kalSetEvent/GlueSetEvent -+ * indicates the following requests occur -+ * -+ */ -+#if 0 -+ if (prGlueInfo->u4Flag & GLUE_FLAG_HALT) { -+ DBGLOG(INIT, INFO, "<3>tx_thread should stop now...\n"); -+ break; -+ } -+#endif -+ -+ if (test_and_clear_bit(GLUE_FLAG_TXREQ_BIT, &prGlueInfo->ulFlag)) { -+ /* Process Mailbox Messages */ -+ wlanProcessMboxMessage(prGlueInfo->prAdapter); -+ -+ /* Process CMD request */ -+ do { -+ if (prCmdQue->u4NumElem > 0) { -+ if (fgNeedHwAccess == FALSE) { -+ fgNeedHwAccess = TRUE; -+ -+ wlanAcquirePowerControl(prGlueInfo->prAdapter); -+ } -+ wlanProcessCommandQueue(prGlueInfo->prAdapter, prCmdQue); -+ } -+ } while (FALSE); -+ -+ /* Handle Packet Tx */ -+ { -+ while (QUEUE_IS_NOT_EMPTY(prTxQueue)) { -+ GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_TX_QUE); -+ QUEUE_REMOVE_HEAD(prTxQueue, prQueueEntry, P_QUE_ENTRY_T); -+ GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_TX_QUE); -+ -+ ASSERT(prQueueEntry); -+ if (NULL == prQueueEntry) -+ break; -+ -+ prSkb = (struct sk_buff *)GLUE_GET_PKT_DESCRIPTOR(prQueueEntry); -+ ASSERT(prSkb); -+ if (NULL == prSkb) { -+ DBGLOG(INIT, ERROR, "prSkb == NULL!\n"); -+ continue; -+ } -+#if (CFG_SUPPORT_TDLS_DBG == 1) -+ UINT8 *pkt = prSkb->data; -+ UINT16 u2Identifier; -+ -+ if ((*(pkt + 12) == 0x08) && (*(pkt + 13) == 0x00)) { -+ /* ip */ -+ u2Identifier = ((*(pkt + 18)) << 8) | (*(pkt + 19)); -+ DBGLOG(INIT, LOUD, " %d\n", u2Identifier); -+ } -+#endif -+ if (wlanEnqueueTxPacket(prGlueInfo->prAdapter, -+ (P_NATIVE_PACKET) prSkb) == WLAN_STATUS_RESOURCES) { -+ /* no available entry in rFreeMsduInfoList */ -+ GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_TX_QUE); -+ QUEUE_INSERT_HEAD(prTxQueue, prQueueEntry); -+ GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_TX_QUE); -+ -+ break; -+ } -+ } -+ -+ if (wlanGetTxPendingFrameCount(prGlueInfo->prAdapter) > 0) { -+ /* send packets to HIF here */ -+ wlanTxPendingPackets(prGlueInfo->prAdapter, &fgNeedHwAccess); -+ } -+ } -+ -+ } -+ -+ /* Process RX, In linux, we don't need to free sk_buff by ourself */ -+ -+ /* In linux, we don't need to free sk_buff by ourself */ -+ -+ /* In linux, we don't do reset */ -+ if (fgNeedHwAccess == TRUE) -+ wlanReleasePowerControl(prGlueInfo->prAdapter); -+ -+ /* handle cnmTimer time out */ -+ if (test_and_clear_bit(GLUE_FLAG_TIMEOUT_BIT, &prGlueInfo->ulFlag)) -+ wlanTimerTimeoutCheck(prGlueInfo->prAdapter); -+#if CFG_DBG_GPIO_PINS -+ /* TX thread go to sleep */ -+ if (!prGlueInfo->ulFlag) -+ mtk_wcn_stp_debug_gpio_assert(IDX_TX_THREAD, DBG_TIE_HIGH); -+#endif -+ } -+ -+#if 0 -+ if (fgNeedHwAccess == TRUE) -+ wlanReleasePowerControl(prGlueInfo->prAdapter); -+#endif -+ -+ /* exit while loop, tx thread is closed so we flush all pending packets */ -+ /* flush the pending TX packets */ -+ if (prGlueInfo->i4TxPendingFrameNum > 0) -+ kalFlushPendingTxPackets(prGlueInfo); -+ -+ /* flush pending security frames */ -+ if (prGlueInfo->i4TxPendingSecurityFrameNum > 0) -+ kalClearSecurityFrames(prGlueInfo); -+ -+ /* remove pending oid */ -+ wlanReleasePendingOid(prGlueInfo->prAdapter, 0); -+ -+ /* In linux, we don't need to free sk_buff by ourself */ -+ -+ DBGLOG(INIT, INFO, "mtk_sdiod stops\n"); -+ complete(&prGlueInfo->rHaltComp); -+ -+ return 0; -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is used to check if card is removed -+* -+* \param pvGlueInfo Pointer of GLUE Data Structure -+* -+* \retval TRUE: card is removed -+* FALSE: card is still attached -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN kalIsCardRemoved(IN P_GLUE_INFO_T prGlueInfo) -+{ -+ ASSERT(prGlueInfo); -+ -+ return FALSE; -+ /* Linux MMC doesn't have removal notification yet */ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * \brief This routine is used to send command to firmware for overriding netweork address -+ * -+ * \param pvGlueInfo Pointer of GLUE Data Structure -+ -+ * \retval TRUE -+ * FALSE -+ */ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN kalRetrieveNetworkAddress(IN P_GLUE_INFO_T prGlueInfo, IN OUT PARAM_MAC_ADDRESS *prMacAddr) -+{ -+ ASSERT(prGlueInfo); -+ -+ if (prGlueInfo->fgIsMacAddrOverride == FALSE) { -+#if !defined(CONFIG_X86) -+#if !defined(CONFIG_MTK_TC1_FEATURE) -+ UINT_32 i; -+#endif -+ BOOLEAN fgIsReadError = FALSE; -+ -+#if !defined(CONFIG_MTK_TC1_FEATURE) -+ for (i = 0; i < MAC_ADDR_LEN; i += 2) { -+ if (kalCfgDataRead16(prGlueInfo, -+ OFFSET_OF(WIFI_CFG_PARAM_STRUCT, aucMacAddress) + i, -+ (PUINT_16) (((PUINT_8) prMacAddr) + i)) == FALSE) { -+ fgIsReadError = TRUE; -+ break; -+ } -+ } -+#else -+ TC1_FAC_NAME(FacReadWifiMacAddr) ((unsigned char *)prMacAddr); -+#endif -+ -+ if (fgIsReadError == TRUE) -+ return FALSE; -+ else -+ return TRUE; -+#else -+ /* x86 Linux doesn't need to override network address so far */ -+ return FALSE; -+#endif -+ } else { -+ COPY_MAC_ADDR(prMacAddr, prGlueInfo->rMacAddrOverride); -+ -+ return TRUE; -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is used to flush pending TX packets in glue layer -+* -+* \param pvGlueInfo Pointer of GLUE Data Structure -+* -+* \retval none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID kalFlushPendingTxPackets(IN P_GLUE_INFO_T prGlueInfo) -+{ -+ P_QUE_T prTxQue; -+ P_QUE_ENTRY_T prQueueEntry; -+ PVOID prPacket; -+ -+ GLUE_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(prGlueInfo); -+ -+ prTxQue = &(prGlueInfo->rTxQueue); -+ -+ if (prGlueInfo->i4TxPendingFrameNum) { -+ while (TRUE) { -+ GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_TX_QUE); -+ QUEUE_REMOVE_HEAD(prTxQue, prQueueEntry, P_QUE_ENTRY_T); -+ GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_TX_QUE); -+ -+ if (prQueueEntry == NULL) -+ break; -+ -+ prPacket = GLUE_GET_PKT_DESCRIPTOR(prQueueEntry); -+ -+ kalSendComplete(prGlueInfo, prPacket, WLAN_STATUS_NOT_ACCEPTED); -+ } -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is get indicated media state -+* -+* \param pvGlueInfo Pointer of GLUE Data Structure -+* -+* \retval -+*/ -+/*----------------------------------------------------------------------------*/ -+ENUM_PARAM_MEDIA_STATE_T kalGetMediaStateIndicated(IN P_GLUE_INFO_T prGlueInfo) -+{ -+ ASSERT(prGlueInfo); -+ -+ return prGlueInfo->eParamMediaStateIndicated; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is used to set indicated media state -+* -+* \param pvGlueInfo Pointer of GLUE Data Structure -+* -+* \retval none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID kalSetMediaStateIndicated(IN P_GLUE_INFO_T prGlueInfo, IN ENUM_PARAM_MEDIA_STATE_T eParamMediaStateIndicate) -+{ -+ ASSERT(prGlueInfo); -+ -+ prGlueInfo->eParamMediaStateIndicated = eParamMediaStateIndicate; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is used to clear pending OID staying in command queue -+* -+* \param prGlueInfo Pointer of GLUE Data Structure -+* -+* \retval none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID kalOidCmdClearance(IN P_GLUE_INFO_T prGlueInfo) -+{ -+ P_QUE_T prCmdQue; -+ QUE_T rTempCmdQue; -+ P_QUE_T prTempCmdQue = &rTempCmdQue; -+ P_QUE_ENTRY_T prQueueEntry = (P_QUE_ENTRY_T) NULL; -+ P_CMD_INFO_T prCmdInfo = (P_CMD_INFO_T) NULL; -+ -+ GLUE_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(prGlueInfo); -+ -+ prCmdQue = &prGlueInfo->rCmdQueue; -+ -+ GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE); -+ QUEUE_MOVE_ALL(prTempCmdQue, prCmdQue); -+ -+ QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T); -+ while (prQueueEntry) { -+ -+ if (((P_CMD_INFO_T) prQueueEntry)->fgIsOid) { -+ prCmdInfo = (P_CMD_INFO_T) prQueueEntry; -+ break; -+ } -+ QUEUE_INSERT_TAIL(prCmdQue, prQueueEntry); -+ -+ QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T); -+ } -+ -+ QUEUE_CONCATENATE_QUEUES(prCmdQue, prTempCmdQue); -+ GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE); -+ -+ if (prCmdInfo) { -+ if (prCmdInfo->pfCmdTimeoutHandler) -+ prCmdInfo->pfCmdTimeoutHandler(prGlueInfo->prAdapter, prCmdInfo); -+ else -+ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, 0, WLAN_STATUS_NOT_ACCEPTED); -+ -+ prGlueInfo->u4OidCompleteFlag = 1; -+ cmdBufFreeCmdInfo(prGlueInfo->prAdapter, prCmdInfo); -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is used to insert command into prCmdQueue -+* -+* \param prGlueInfo Pointer of GLUE Data Structure -+* prQueueEntry Pointer of queue entry to be inserted -+* -+* \retval none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID kalEnqueueCommand(IN P_GLUE_INFO_T prGlueInfo, IN P_QUE_ENTRY_T prQueueEntry) -+{ -+ P_QUE_T prCmdQue; -+ P_CMD_INFO_T prCmdInfo; -+ P_MSDU_INFO_T prMsduInfo; -+ -+ GLUE_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(prGlueInfo); -+ ASSERT(prQueueEntry); -+ -+ prCmdQue = &prGlueInfo->rCmdQueue; -+ -+ prCmdInfo = (P_CMD_INFO_T) prQueueEntry; -+ if (prCmdInfo->prPacket && prCmdInfo->eCmdType == COMMAND_TYPE_MANAGEMENT_FRAME) { -+ prMsduInfo = (P_MSDU_INFO_T) (prCmdInfo->prPacket); -+ prMsduInfo->eCmdType = prCmdInfo->eCmdType; -+ prMsduInfo->ucCID = prCmdInfo->ucCID; -+ prMsduInfo->u4InqueTime = kalGetTimeTick(); -+ } -+ -+ GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE); -+ QUEUE_INSERT_TAIL(prCmdQue, prQueueEntry); -+ GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Handle EVENT_ID_ASSOC_INFO event packet by indicating to OS with -+* proper information -+* -+* @param pvGlueInfo Pointer of GLUE Data Structure -+* @param prAssocInfo Pointer of EVENT_ID_ASSOC_INFO Packet -+* -+* @return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID kalHandleAssocInfo(IN P_GLUE_INFO_T prGlueInfo, IN P_EVENT_ASSOC_INFO prAssocInfo) -+{ -+ /* to do */ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is used to get firmware load address from registry -+* -+* \param prGlueInfo Pointer of GLUE Data Structure -+* -+* \retval -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT_32 kalGetFwLoadAddress(IN P_GLUE_INFO_T prGlueInfo) -+{ -+ ASSERT(prGlueInfo); -+ -+ return prGlueInfo->rRegInfo.u4LoadAddress; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is used to get firmware start address from registry -+* -+* \param prGlueInfo Pointer of GLUE Data Structure -+* -+* \retval -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT_32 kalGetFwStartAddress(IN P_GLUE_INFO_T prGlueInfo) -+{ -+ ASSERT(prGlueInfo); -+ -+ return prGlueInfo->rRegInfo.u4StartAddress; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * * @brief Notify OS with SendComplete event of the specific packet. Linux should -+ * * free packets here. -+ * * -+ * * @param pvGlueInfo Pointer of GLUE Data Structure -+ * * @param pvPacket Pointer of Packet Handle -+ * * @param status Status Code for OS upper layer -+ * * -+ * * @return none -+ * */ -+/*----------------------------------------------------------------------------*/ -+ -+/* / Todo */ -+VOID kalSecurityFrameSendComplete(IN P_GLUE_INFO_T prGlueInfo, IN PVOID pvPacket, IN WLAN_STATUS rStatus) -+{ -+ ASSERT(pvPacket); -+ -+ dev_kfree_skb((struct sk_buff *)pvPacket); -+ if (prGlueInfo) -+ prGlueInfo->u8SkbFreed++; -+ GLUE_DEC_REF_CNT(prGlueInfo->i4TxPendingSecurityFrameNum); -+} -+ -+UINT_32 kalGetTxPendingFrameCount(IN P_GLUE_INFO_T prGlueInfo) -+{ -+ ASSERT(prGlueInfo); -+ -+ return (UINT_32) (prGlueInfo->i4TxPendingFrameNum); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is used to retrieve the number of pending commands -+* (including MMPDU, 802.1X and command packets) -+* -+* \param prGlueInfo Pointer of GLUE Data Structure -+* -+* \retval -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT_32 kalGetTxPendingCmdCount(IN P_GLUE_INFO_T prGlueInfo) -+{ -+ P_QUE_T prCmdQue; -+ -+ ASSERT(prGlueInfo); -+ prCmdQue = &prGlueInfo->rCmdQueue; -+ -+ return prCmdQue->u4NumElem; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Timer Initialization Procedure -+* -+* \param[in] prGlueInfo Pointer to GLUE Data Structure -+* \param[in] prTimerHandler Pointer to timer handling function, whose only -+* argument is "prAdapter" -+* -+* \retval none -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+ -+/* static struct timer_list tickfn; */ -+ -+VOID kalOsTimerInitialize(IN P_GLUE_INFO_T prGlueInfo, IN PVOID prTimerHandler) -+{ -+ -+ ASSERT(prGlueInfo); -+ -+ init_timer(&(prGlueInfo->tickfn)); -+ prGlueInfo->tickfn.function = prTimerHandler; -+ prGlueInfo->tickfn.data = (ULONG) prGlueInfo; -+} -+ -+/* Todo */ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to set the time to do the time out check. -+* -+* \param[in] prGlueInfo Pointer to GLUE Data Structure -+* \param[in] rInterval Time out interval from current time. -+* -+* \retval TRUE Success. -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN kalSetTimer(IN P_GLUE_INFO_T prGlueInfo, IN UINT_32 u4Interval) -+{ -+ ASSERT(prGlueInfo); -+ del_timer_sync(&(prGlueInfo->tickfn)); -+ -+ prGlueInfo->tickfn.expires = jiffies + u4Interval * HZ / MSEC_PER_SEC; -+ add_timer(&(prGlueInfo->tickfn)); -+ -+ return TRUE; /* success */ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to cancel -+* -+* \param[in] prGlueInfo Pointer to GLUE Data Structure -+* -+* \retval TRUE : Timer has been canceled -+* FALAE : Timer doens't exist -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN kalCancelTimer(IN P_GLUE_INFO_T prGlueInfo) -+{ -+ ASSERT(prGlueInfo); -+ -+ clear_bit(GLUE_FLAG_TIMEOUT_BIT, &prGlueInfo->ulFlag); -+ -+ if (del_timer_sync(&(prGlueInfo->tickfn)) >= 0) -+ return TRUE; -+ else -+ return FALSE; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is a callback function for scanning done -+* -+* \param[in] prGlueInfo Pointer to GLUE Data Structure -+* -+* \retval none -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID kalScanDone(IN P_GLUE_INFO_T prGlueInfo, IN ENUM_KAL_NETWORK_TYPE_INDEX_T eNetTypeIdx, IN WLAN_STATUS status) -+{ -+ P_AIS_FSM_INFO_T prAisFsmInfo; -+ -+ ASSERT(prGlueInfo); -+ -+ prAisFsmInfo = &(prGlueInfo->prAdapter->rWifiVar.rAisFsmInfo); -+ /* report all queued beacon/probe response frames to upper layer */ -+ scanReportBss2Cfg80211(prGlueInfo->prAdapter, BSS_TYPE_INFRASTRUCTURE, NULL); -+ cnmTimerStopTimer(prGlueInfo->prAdapter, &prAisFsmInfo->rScanDoneTimer); -+ -+ /* check for system configuration for generating error message on scan list */ -+ wlanCheckSystemConfiguration(prGlueInfo->prAdapter); -+ -+ kalIndicateStatusAndComplete(prGlueInfo, WLAN_STATUS_SCAN_COMPLETE, NULL, 0); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is used to generate a random number -+* -+* \param none -+* -+* \retval UINT_32 -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT_32 kalRandomNumber(VOID) -+{ -+ UINT_32 number = 0; -+ -+ get_random_bytes(&number, 4); -+ -+ return number; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * \brief command timeout call-back function -+ * -+ * \param[in] prGlueInfo Pointer to the GLUE data structure. -+ * -+ * \retval (none) -+ */ -+/*----------------------------------------------------------------------------*/ -+VOID kalTimeoutHandler(ULONG arg) -+{ -+ -+ P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) arg; -+ -+ ASSERT(prGlueInfo); -+ -+ /* Notify tx thread for timeout event */ -+ set_bit(GLUE_FLAG_TIMEOUT_BIT, &prGlueInfo->ulFlag); -+ wake_up_interruptible(&prGlueInfo->waitq); -+ -+} -+ -+VOID kalSetEvent(P_GLUE_INFO_T pr) -+{ -+ set_bit(GLUE_FLAG_TXREQ_BIT, &pr->ulFlag); -+ wake_up_interruptible(&pr->waitq); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief to check if configuration file (NVRAM/Registry) exists -+* -+* \param[in] -+* prGlueInfo -+* -+* \return -+* TRUE -+* FALSE -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN kalIsConfigurationExist(IN P_GLUE_INFO_T prGlueInfo) -+{ -+#if !defined(CONFIG_X86) -+ ASSERT(prGlueInfo); -+ -+ return prGlueInfo->fgNvramAvailable; -+#else -+ /* there is no configuration data for x86-linux */ -+ return FALSE; -+#endif -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief to retrieve Registry information -+* -+* \param[in] -+* prGlueInfo -+* -+* \return -+* Pointer of REG_INFO_T -+*/ -+/*----------------------------------------------------------------------------*/ -+P_REG_INFO_T kalGetConfiguration(IN P_GLUE_INFO_T prGlueInfo) -+{ -+ ASSERT(prGlueInfo); -+ -+ return &(prGlueInfo->rRegInfo); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief to retrieve version information of corresponding configuration file -+* -+* \param[in] -+* prGlueInfo -+* -+* \param[out] -+* pu2Part1CfgOwnVersion -+* pu2Part1CfgPeerVersion -+* pu2Part2CfgOwnVersion -+* pu2Part2CfgPeerVersion -+* -+* \return -+* NONE -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+kalGetConfigurationVersion(IN P_GLUE_INFO_T prGlueInfo, -+ OUT PUINT_16 pu2Part1CfgOwnVersion, -+ OUT PUINT_16 pu2Part1CfgPeerVersion, -+ OUT PUINT_16 pu2Part2CfgOwnVersion, OUT PUINT_16 pu2Part2CfgPeerVersion) -+{ -+ ASSERT(prGlueInfo); -+ -+ ASSERT(pu2Part1CfgOwnVersion); -+ ASSERT(pu2Part1CfgPeerVersion); -+ ASSERT(pu2Part2CfgOwnVersion); -+ ASSERT(pu2Part2CfgPeerVersion); -+ -+ kalCfgDataRead16(prGlueInfo, OFFSET_OF(WIFI_CFG_PARAM_STRUCT, u2Part1OwnVersion), pu2Part1CfgOwnVersion); -+ -+ kalCfgDataRead16(prGlueInfo, OFFSET_OF(WIFI_CFG_PARAM_STRUCT, u2Part1PeerVersion), pu2Part1CfgPeerVersion); -+ -+ kalCfgDataRead16(prGlueInfo, OFFSET_OF(WIFI_CFG_PARAM_STRUCT, u2Part2OwnVersion), pu2Part2CfgOwnVersion); -+ -+ kalCfgDataRead16(prGlueInfo, OFFSET_OF(WIFI_CFG_PARAM_STRUCT, u2Part2PeerVersion), pu2Part2CfgPeerVersion); -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief to check if the WPS is active or not -+* -+* \param[in] -+* prGlueInfo -+* -+* \return -+* TRUE -+* FALSE -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN kalWSCGetActiveState(IN P_GLUE_INFO_T prGlueInfo) -+{ -+ ASSERT(prGlueInfo); -+ -+ return prGlueInfo->fgWpsActive; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief update RSSI and LinkQuality to GLUE layer -+* -+* \param[in] -+* prGlueInfo -+* eNetTypeIdx -+* cRssi -+* cLinkQuality -+* -+* \return -+* None -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+kalUpdateRSSI(IN P_GLUE_INFO_T prGlueInfo, -+ IN ENUM_KAL_NETWORK_TYPE_INDEX_T eNetTypeIdx, IN INT_8 cRssi, IN INT_8 cLinkQuality) -+{ -+ struct iw_statistics *pStats = (struct iw_statistics *)NULL; -+ -+ ASSERT(prGlueInfo); -+ -+ switch (eNetTypeIdx) { -+ case KAL_NETWORK_TYPE_AIS_INDEX: -+ pStats = (struct iw_statistics *)(&(prGlueInfo->rIwStats)); -+ break; -+#if CFG_ENABLE_WIFI_DIRECT -+#if CFG_SUPPORT_P2P_RSSI_QUERY -+ case KAL_NETWORK_TYPE_P2P_INDEX: -+ pStats = (struct iw_statistics *)(&(prGlueInfo->rP2pIwStats)); -+ break; -+#endif -+#endif -+ default: -+ break; -+ -+ } -+ -+ if (pStats) { -+ pStats->qual.qual = cLinkQuality; -+ pStats->qual.noise = 0; -+ pStats->qual.updated = IW_QUAL_QUAL_UPDATED | IW_QUAL_NOISE_UPDATED | IW_QUAL_DBM; -+ pStats->qual.level = 0x100 + cRssi; -+ pStats->qual.updated |= IW_QUAL_LEVEL_UPDATED; -+ } -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Pre-allocate I/O buffer -+* -+* \param[in] -+* none -+* -+* \return -+* TRUE -+* FALSE -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN kalInitIOBuffer(VOID) -+{ -+ UINT_32 u4Size; -+ -+ if (CFG_COALESCING_BUFFER_SIZE >= CFG_RX_COALESCING_BUFFER_SIZE) -+ u4Size = CFG_COALESCING_BUFFER_SIZE + sizeof(ENHANCE_MODE_DATA_STRUCT_T); -+ else -+ u4Size = CFG_RX_COALESCING_BUFFER_SIZE + sizeof(ENHANCE_MODE_DATA_STRUCT_T); -+ -+#ifdef MTK_DMA_BUF_MEMCPY_SUP -+ pvDmaBuffer = dma_alloc_coherent(NULL, CFG_RX_MAX_PKT_SIZE, &pvDmaPhyBuf, GFP_KERNEL); -+ if (pvDmaBuffer == NULL) -+ return FALSE; -+#endif /* MTK_DMA_BUF_MEMCPY_SUP */ -+ -+ pvIoBuffer = kmalloc(u4Size, GFP_KERNEL); -+/* pvIoBuffer = dma_alloc_coherent(NULL, u4Size, &pvIoPhyBuf, GFP_KERNEL); */ -+ if (pvIoBuffer) { -+ pvIoBufferSize = u4Size; -+ pvIoBufferUsage = 0; -+ -+ return TRUE; -+ } -+ -+ return FALSE; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Free pre-allocated I/O buffer -+* -+* \param[in] -+* none -+* -+* \return -+* none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID kalUninitIOBuffer(VOID) -+{ -+ kfree(pvIoBuffer); -+#ifdef MTK_DMA_BUF_MEMCPY_SUP -+ dma_free_coherent(NULL, CFG_RX_MAX_PKT_SIZE, pvDmaBuffer, pvDmaPhyBuf); -+#endif /* MTK_DMA_BUF_MEMCPY_SUP */ -+ /* dma_free_coherent(NULL, pvIoBufferSize, pvIoBuffer, pvIoPhyBuf); */ -+ -+ pvIoBuffer = (PVOID) NULL; -+ pvIoBufferSize = 0; -+ pvIoBufferUsage = 0; -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Dispatch pre-allocated I/O buffer -+* -+* \param[in] -+* u4AllocSize -+* -+* \return -+* PVOID for pointer of pre-allocated I/O buffer -+*/ -+/*----------------------------------------------------------------------------*/ -+PVOID kalAllocateIOBuffer(IN UINT_32 u4AllocSize) -+{ -+ PVOID ret = (PVOID) NULL; -+ -+ if (pvIoBuffer) { -+ if (u4AllocSize <= (pvIoBufferSize - pvIoBufferUsage)) { -+ ret = (PVOID) &(((PUINT_8) (pvIoBuffer))[pvIoBufferUsage]); -+ pvIoBufferUsage += u4AllocSize; -+ } -+ } else { -+ /* fault tolerance */ -+ ret = (PVOID) kalMemAlloc(u4AllocSize, PHY_MEM_TYPE); -+ } -+ -+ return ret; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Release all dispatched I/O buffer -+* -+* \param[in] -+* none -+* -+* \return -+* none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID kalReleaseIOBuffer(IN PVOID pvAddr, IN UINT_32 u4Size) -+{ -+ if (pvIoBuffer) { -+ pvIoBufferUsage -= u4Size; -+ } else { -+ /* fault tolerance */ -+ kalMemFree(pvAddr, PHY_MEM_TYPE, u4Size); -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] prAdapter Pointer of ADAPTER_T -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+kalGetChannelList(IN P_GLUE_INFO_T prGlueInfo, -+ IN ENUM_BAND_T eSpecificBand, -+ IN UINT_8 ucMaxChannelNum, IN PUINT_8 pucNumOfChannel, IN P_RF_CHANNEL_INFO_T paucChannelList) -+{ -+ rlmDomainGetChnlList(prGlueInfo->prAdapter, eSpecificBand, FALSE, ucMaxChannelNum, -+ pucNumOfChannel, paucChannelList); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] prAdapter Pointer of ADAPTER_T -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN kalIsAPmode(IN P_GLUE_INFO_T prGlueInfo) -+{ -+#if CFG_ENABLE_WIFI_DIRECT -+ if (IS_NET_ACTIVE(prGlueInfo->prAdapter, NETWORK_TYPE_P2P_INDEX) && -+ p2pFuncIsAPMode(prGlueInfo->prAdapter->rWifiVar.prP2pFsmInfo)) -+ return TRUE; -+#endif -+ -+ return FALSE; -+} -+ -+#ifdef MTK_DMA_BUF_MEMCPY_SUP -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function gets the physical address for Pre-allocate I/O buffer. -+* -+* \param[in] prGlueInfo Pointer of GLUE Data Structure -+* \param[in] rLockCategory Specify which SPIN_LOCK -+* \param[out] pu4Flags Pointer of a variable for saving IRQ flags -+* -+* \return physical addr -+*/ -+/*----------------------------------------------------------------------------*/ -+ULONG kalIOPhyAddrGet(IN ULONG VirtAddr) -+{ -+ ULONG PhyAddr; -+ -+ if ((VirtAddr >= (ULONG) pvIoBuffer) && (VirtAddr <= ((ULONG) (pvIoBuffer) + pvIoBufferSize))) { -+ PhyAddr = (ULONG) pvIoPhyBuf; -+ PhyAddr += (VirtAddr - (ULONG) (pvIoBuffer)); -+ return PhyAddr; -+ } -+ -+ return 0; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function gets the physical address for Pre-allocate I/O buffer. -+* -+* \param[in] prGlueInfo Pointer of GLUE Data Structure -+* \param[in] rLockCategory Specify which SPIN_LOCK -+* \param[out] pu4Flags Pointer of a variable for saving IRQ flags -+* -+* \return physical addr -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID kalDmaBufGet(OUT VOID **VirtAddr, OUT VOID **PhyAddr) -+{ -+ *VirtAddr = pvDmaBuffer; -+ *PhyAddr = pvDmaPhyBuf; -+} -+#endif /* MTK_DMA_BUF_MEMCPY_SUP */ -+ -+#if CFG_SUPPORT_802_11W -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief to check if the MFP is active or not -+* -+* \param[in] -+* prGlueInfo -+* -+* \return -+* TRUE -+* FALSE -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT_32 kalGetMfpSetting(IN P_GLUE_INFO_T prGlueInfo) -+{ -+ ASSERT(prGlueInfo); -+ -+ return prGlueInfo->rWpaInfo.u4Mfp; -+} -+#endif -+ -+struct file *kalFileOpen(const char *path, int flags, int rights) -+{ -+ struct file *filp = NULL; -+ mm_segment_t oldfs; -+ int err = 0; -+ -+ oldfs = get_fs(); -+ set_fs(get_ds()); -+ filp = filp_open(path, flags, rights); -+ set_fs(oldfs); -+ if (IS_ERR(filp)) { -+ err = PTR_ERR(filp); -+ return NULL; -+ } -+ return filp; -+} -+ -+VOID kalFileClose(struct file *file) -+{ -+ filp_close(file, NULL); -+} -+ -+UINT_32 kalFileRead(struct file *file, UINT_64 offset, UINT_8 *data, UINT_32 size) -+{ -+ mm_segment_t oldfs; -+ INT_32 ret; -+ -+ oldfs = get_fs(); -+ set_fs(get_ds()); -+ -+ ret = vfs_read(file, data, size, &offset); -+ -+ set_fs(oldfs); -+ return ret; -+} -+ -+UINT_32 kalFileWrite(struct file *file, UINT_64 offset, UINT_8 *data, UINT_32 size) -+{ -+ mm_segment_t oldfs; -+ INT_32 ret; -+ -+ oldfs = get_fs(); -+ set_fs(get_ds()); -+ -+ ret = vfs_write(file, data, size, &offset); -+ -+ set_fs(oldfs); -+ return ret; -+} -+ -+UINT_32 kalWriteToFile(const PUINT_8 pucPath, BOOLEAN fgDoAppend, PUINT_8 pucData, UINT_32 u4Size) -+{ -+ struct file *file = NULL; -+ UINT_32 ret = -1; -+ UINT_32 u4Flags = 0; -+ -+ if (fgDoAppend) -+ u4Flags = O_APPEND; -+ -+ file = kalFileOpen(pucPath, O_WRONLY | O_CREAT | u4Flags, S_IRWXU); -+ if (file) { -+ ret = kalFileWrite(file, 0, pucData, u4Size); -+ kalFileClose(file); -+ } -+ -+ return ret; -+} -+ -+INT_32 kalReadToFile(const PUINT_8 pucPath, PUINT_8 pucData, UINT_32 u4Size, PUINT_32 pu4ReadSize) -+{ -+ struct file *file = NULL; -+ INT_32 ret = -1; -+ UINT_32 u4ReadSize = 0; -+ -+ DBGLOG(INIT, LOUD, "kalReadToFile() path %s\n", pucPath); -+ -+ file = kalFileOpen(pucPath, O_RDONLY, 0); -+ -+ if ((file != NULL) && !IS_ERR(file)) { -+ u4ReadSize = kalFileRead(file, 0, pucData, u4Size); -+ kalFileClose(file); -+ if (pu4ReadSize) -+ *pu4ReadSize = u4ReadSize; -+ ret = 0; -+ } -+ return ret; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief To indicate BSS-INFO to NL80211 as scanning result -+* -+* \param[in] -+* prGlueInfo -+* pucBeaconProbeResp -+* u4FrameLen -+* -+* -+* -+* \return -+* none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+kalIndicateBssInfo(IN P_GLUE_INFO_T prGlueInfo, -+ IN PUINT_8 pucBeaconProbeResp, -+ IN UINT_32 u4FrameLen, IN UINT_8 ucChannelNum, IN INT_32 i4SignalStrength) -+{ -+ struct wiphy *wiphy; -+ struct ieee80211_channel *prChannel = NULL; -+ -+ ASSERT(prGlueInfo); -+ wiphy = priv_to_wiphy(prGlueInfo); -+ -+ /* search through channel entries */ -+ if (ucChannelNum <= 14) { -+ prChannel = -+ ieee80211_get_channel(wiphy, ieee80211_channel_to_frequency(ucChannelNum, NL80211_BAND_2GHZ)); -+ } else { -+ prChannel = -+ ieee80211_get_channel(wiphy, ieee80211_channel_to_frequency(ucChannelNum, NL80211_BAND_5GHZ)); -+ } -+ -+ if (prChannel != NULL && (prGlueInfo->prScanRequest != NULL || prGlueInfo->prSchedScanRequest != NULL)) { -+ struct cfg80211_bss *bss; -+#if CFG_SUPPORT_TSF_USING_BOOTTIME -+ struct ieee80211_mgmt *prMgmtFrame = (struct ieee80211_mgmt *)pucBeaconProbeResp; -+ -+ prMgmtFrame->u.beacon.timestamp = kalGetBootTime(); -+#endif -+ ScanCnt++; -+ -+ /* indicate to NL80211 subsystem */ -+ bss = cfg80211_inform_bss_frame(wiphy, -+ prChannel, -+ (struct ieee80211_mgmt *)pucBeaconProbeResp, -+ u4FrameLen, i4SignalStrength * 100, GFP_KERNEL); -+ -+ if (!bss) { -+ ScanDoneFailCnt++; -+ DBGLOG(SCN, WARN, "inform bss to cfg80211 failed, bss channel %d, rcpi %d\n", -+ ucChannelNum, i4SignalStrength); -+ } else { -+ cfg80211_put_bss(wiphy, bss); -+ DBGLOG(SCN, TRACE, "inform bss to cfg80211, bss channel %d, rcpi %d\n", -+ ucChannelNum, i4SignalStrength); -+ } -+ } -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief To indicate channel ready -+* -+* \param[in] -+* prGlueInfo -+* -+* \return -+* none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+kalReadyOnChannel(IN P_GLUE_INFO_T prGlueInfo, -+ IN UINT_64 u8Cookie, -+ IN ENUM_BAND_T eBand, IN ENUM_CHNL_EXT_T eSco, IN UINT_8 ucChannelNum, IN UINT_32 u4DurationMs) -+{ -+ struct ieee80211_channel *prChannel = NULL; -+ enum nl80211_channel_type rChannelType; -+ -+ /* ucChannelNum = wlanGetChannelNumberByNetwork(prGlueInfo->prAdapter, NETWORK_TYPE_AIS_INDEX); */ -+ -+ if (prGlueInfo->fgIsRegistered == TRUE) { -+ if (ucChannelNum <= 14) { -+ prChannel = -+ ieee80211_get_channel(priv_to_wiphy(prGlueInfo), -+ ieee80211_channel_to_frequency(ucChannelNum, NL80211_BAND_2GHZ)); -+ } else { -+ prChannel = -+ ieee80211_get_channel(priv_to_wiphy(prGlueInfo), -+ ieee80211_channel_to_frequency(ucChannelNum, NL80211_BAND_5GHZ)); -+ } -+ -+ switch (eSco) { -+ case CHNL_EXT_SCN: -+ rChannelType = NL80211_CHAN_NO_HT; -+ break; -+ -+ case CHNL_EXT_SCA: -+ rChannelType = NL80211_CHAN_HT40MINUS; -+ break; -+ -+ case CHNL_EXT_SCB: -+ rChannelType = NL80211_CHAN_HT40PLUS; -+ break; -+ -+ case CHNL_EXT_RES: -+ default: -+ rChannelType = NL80211_CHAN_HT20; -+ break; -+ } -+ -+ cfg80211_ready_on_channel(prGlueInfo->prDevHandler->ieee80211_ptr, u8Cookie, prChannel, u4DurationMs, -+ GFP_KERNEL); -+ } -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief To indicate channel expiration -+* -+* \param[in] -+* prGlueInfo -+* -+* \return -+* none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+kalRemainOnChannelExpired(IN P_GLUE_INFO_T prGlueInfo, -+ IN UINT_64 u8Cookie, IN ENUM_BAND_T eBand, IN ENUM_CHNL_EXT_T eSco, IN UINT_8 ucChannelNum) -+{ -+ struct ieee80211_channel *prChannel = NULL; -+ enum nl80211_channel_type rChannelType; -+ -+ ucChannelNum = wlanGetChannelNumberByNetwork(prGlueInfo->prAdapter, NETWORK_TYPE_AIS_INDEX); -+ -+ if (prGlueInfo->fgIsRegistered == TRUE) { -+ if (ucChannelNum <= 14) { -+ prChannel = -+ ieee80211_get_channel(priv_to_wiphy(prGlueInfo), -+ ieee80211_channel_to_frequency(ucChannelNum, NL80211_BAND_2GHZ)); -+ } else { -+ prChannel = -+ ieee80211_get_channel(priv_to_wiphy(prGlueInfo), -+ ieee80211_channel_to_frequency(ucChannelNum, NL80211_BAND_5GHZ)); -+ } -+ -+ switch (eSco) { -+ case CHNL_EXT_SCN: -+ rChannelType = NL80211_CHAN_NO_HT; -+ break; -+ -+ case CHNL_EXT_SCA: -+ rChannelType = NL80211_CHAN_HT40MINUS; -+ break; -+ -+ case CHNL_EXT_SCB: -+ rChannelType = NL80211_CHAN_HT40PLUS; -+ break; -+ -+ case CHNL_EXT_RES: -+ default: -+ rChannelType = NL80211_CHAN_HT20; -+ break; -+ } -+ -+ cfg80211_remain_on_channel_expired(prGlueInfo->prDevHandler->ieee80211_ptr, u8Cookie, prChannel, -+ GFP_KERNEL); -+ } -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief To indicate Mgmt tx status -+* -+* \param[in] -+* prGlueInfo -+* -+* \return -+* none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+kalIndicateMgmtTxStatus(IN P_GLUE_INFO_T prGlueInfo, -+ IN UINT_64 u8Cookie, IN BOOLEAN fgIsAck, IN PUINT_8 pucFrameBuf, IN UINT_32 u4FrameLen) -+{ -+ -+ do { -+ if ((prGlueInfo == NULL) || (pucFrameBuf == NULL) || (u4FrameLen == 0)) { -+ DBGLOG(AIS, TRACE, "Unexpected pointer PARAM. %p, %p, %u.", -+ prGlueInfo, pucFrameBuf, u4FrameLen); -+ ASSERT(FALSE); -+ break; -+ } -+ -+ cfg80211_mgmt_tx_status(prGlueInfo->prDevHandler->ieee80211_ptr, -+ u8Cookie, pucFrameBuf, u4FrameLen, fgIsAck, GFP_KERNEL); -+ } while (FALSE); -+ -+} /* kalIndicateMgmtTxStatus */ -+ -+VOID kalIndicateRxMgmtFrame(IN P_GLUE_INFO_T prGlueInfo, IN P_SW_RFB_T prSwRfb) -+{ -+#define DBG_MGMT_FRAME_INDICATION 1 -+ INT_32 i4Freq = 0; -+ UINT_8 ucChnlNum = 0; -+#if DBG_MGMT_FRAME_INDICATION -+ P_WLAN_MAC_HEADER_T prWlanHeader = (P_WLAN_MAC_HEADER_T) NULL; -+#endif -+ -+ do { -+ if ((prGlueInfo == NULL) || (prSwRfb == NULL)) { -+ ASSERT(FALSE); -+ break; -+ } -+ -+ ucChnlNum = prSwRfb->prHifRxHdr->ucHwChannelNum; -+ -+#if DBG_MGMT_FRAME_INDICATION -+ prWlanHeader = (P_WLAN_MAC_HEADER_T) prSwRfb->pvHeader; -+ -+ switch (prWlanHeader->u2FrameCtrl) { -+ case MAC_FRAME_PROBE_REQ: -+ DBGLOG(AIS, TRACE, "RX Probe Req at channel %d ", ucChnlNum); -+ break; -+ case MAC_FRAME_PROBE_RSP: -+ DBGLOG(AIS, TRACE, "RX Probe Rsp at channel %d ", ucChnlNum); -+ break; -+ case MAC_FRAME_ACTION: -+ DBGLOG(AIS, TRACE, "RX Action frame at channel %d ", ucChnlNum); -+ break; -+ default: -+ DBGLOG(AIS, TRACE, "RX Packet:%d at channel %d ", prWlanHeader->u2FrameCtrl, ucChnlNum); -+ break; -+ } -+ -+#endif -+ i4Freq = nicChannelNum2Freq(ucChnlNum) / 1000; -+ -+ cfg80211_rx_mgmt(prGlueInfo->prDevHandler->ieee80211_ptr, /* struct net_device * dev, */ -+ i4Freq, -+ RCPI_TO_dBm(prSwRfb->prHifRxHdr->ucRcpi), -+ prSwRfb->pvHeader, prSwRfb->u2PacketLen, GFP_KERNEL); -+ } while (FALSE); -+ -+} /* kalIndicateRxMgmtFrame */ -+ -+#if CFG_SUPPORT_AGPS_ASSIST -+BOOLEAN kalIndicateAgpsNotify(P_ADAPTER_T prAdapter, UINT_8 cmd, PUINT_8 data, UINT_16 dataLen) -+{ -+ P_GLUE_INFO_T prGlueInfo = prAdapter->prGlueInfo; -+ -+ struct sk_buff *skb = cfg80211_testmode_alloc_event_skb(priv_to_wiphy(prGlueInfo), -+ dataLen, GFP_KERNEL); -+ if (!skb) { -+ DBGLOG(AIS, ERROR, "kalIndicateAgpsNotify: alloc skb failed\n"); -+ return FALSE; -+ } -+ -+ /* DBGLOG(CCX, INFO, ("WLAN_STATUS_AGPS_NOTIFY, cmd=%d\n", cmd)); */ -+ if (unlikely(nla_put(skb, MTK_ATTR_AGPS_CMD, sizeof(cmd), &cmd) < 0)) -+ goto nla_put_failure; -+ if (dataLen > 0 && data && unlikely(nla_put(skb, MTK_ATTR_AGPS_DATA, dataLen, data) < 0)) -+ goto nla_put_failure; -+ if (unlikely(nla_put(skb, MTK_ATTR_AGPS_IFINDEX, sizeof(UINT_32), &prGlueInfo->prDevHandler->ifindex) < 0)) -+ goto nla_put_failure; -+ /* currently, the ifname maybe wlan0, p2p0, so the maximum name length will be 5 bytes */ -+ if (unlikely(nla_put(skb, MTK_ATTR_AGPS_IFNAME, 5, prGlueInfo->prDevHandler->name) < 0)) -+ goto nla_put_failure; -+ cfg80211_testmode_event(skb, GFP_KERNEL); -+ return TRUE; -+ -+nla_put_failure: -+ kfree_skb(skb); -+ return FALSE; -+} -+#endif -+ -+#if (CFG_SUPPORT_MET_PROFILING == 1) -+#define PROC_MET_PROF_CTRL "met_ctrl" -+#define PROC_MET_PROF_PORT "met_port" -+ -+struct proc_dir_entry *pMetProcDir; -+void *pMetGlobalData = NULL; -+static unsigned long __read_mostly tracing_mark_write_addr; -+ -+static inline void __mt_update_tracing_mark_write_addr(void) -+{ -+ if (unlikely(0 == tracing_mark_write_addr)) -+ tracing_mark_write_addr = kallsyms_lookup_name("tracing_mark_write"); -+} -+ -+VOID kalMetProfilingStart(IN P_GLUE_INFO_T prGlueInfo, IN struct sk_buff *prSkb) -+{ -+ UINT_8 ucIpVersion; -+ UINT_16 u2UdpSrcPort; -+ UINT_16 u2RtpSn; -+ PUINT_8 pucEthHdr = prSkb->data; -+ PUINT_8 pucIpHdr, pucUdpHdr, pucRtpHdr; -+ -+ /* | Ethernet(14) | IP(20) | UDP(8)| RTP(12) | */ -+ /* UDP==> |SRC_PORT(2)|DST_PORT(2)|LEN(2)|CHKSUM(2)| */ -+ /* RTP==> |CTRL(2)|SEQ(2)|TimeStamp(4)|... */ -+ /* printk("MET_PROF: MET enable=%d(HardXmit)\n", prGlueInfo->u8MetProfEnable); */ -+ if (prGlueInfo->u8MetProfEnable == 1) { -+ u2UdpSrcPort = prGlueInfo->u16MetUdpPort; -+ if ((*(pucEthHdr + 12) == 0x08) && (*(pucEthHdr + 13) == 0x00)) { -+ /* IP */ -+ pucIpHdr = pucEthHdr + ETH_HLEN; -+ ucIpVersion = (*pucIpHdr & IPVH_VERSION_MASK) >> IPVH_VERSION_OFFSET; -+ if ((ucIpVersion == IPVERSION) && (pucIpHdr[IPV4_HDR_IP_PROTOCOL_OFFSET] == IP_PROTOCOL_UDP)) { -+ /* UDP */ -+ pucUdpHdr = pucIpHdr + IP_HEADER_LEN; -+ /* check UDP port number */ -+ if (((UINT_16) pucUdpHdr[0] << 8 | (UINT_16) pucUdpHdr[1]) == u2UdpSrcPort) { -+ /* RTP */ -+ pucRtpHdr = pucUdpHdr + 8; -+ u2RtpSn = (UINT_16) pucRtpHdr[2] << 8 | pucRtpHdr[3]; -+ /* trace_printk("S|%d|%s|%d\n", current->tgid, "WIFI-CHIP", u2RtpSn); -+ //frm_sequence); */ -+#ifdef CONFIG_TRACING -+ __mt_update_tracing_mark_write_addr(); -+ if (tracing_mark_write_addr != 0) { -+ event_trace_printk(tracing_mark_write_addr, "S|%d|%s|%d\n", -+ current->tgid, "WIFI-CHIP", u2RtpSn); -+ } -+#endif -+ } -+ } -+ } -+ } -+} -+ -+VOID kalMetProfilingFinish(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo) -+{ -+ UINT_8 ucIpVersion; -+ UINT_16 u2UdpSrcPort; -+ UINT_16 u2RtpSn; -+ struct sk_buff *prSkb = (struct sk_buff *)prMsduInfo->prPacket; -+ PUINT_8 pucEthHdr = prSkb->data; -+ PUINT_8 pucIpHdr, pucUdpHdr, pucRtpHdr; -+ P_GLUE_INFO_T prGlueInfo = prAdapter->prGlueInfo; -+ -+ /* | Ethernet(14) | IP(20) | UDP(8)| RTP(12) | */ -+ /* UDP==> |SRC_PORT(2)|DST_PORT(2)|LEN(2)|CHKSUM(2)| */ -+ /* RTP==> |CTRL(2)|SEQ(2)|TimeStamp(4)|... */ -+ /* printk("MET_PROF: MET enable=%d(TxMsdu)\n", prGlueInfo->u8MetProfEnable); */ -+ if (prGlueInfo->u8MetProfEnable == 1) { -+ u2UdpSrcPort = prGlueInfo->u16MetUdpPort; -+ if ((*(pucEthHdr + 12) == 0x08) && (*(pucEthHdr + 13) == 0x00)) { -+ /* IP */ -+ pucIpHdr = pucEthHdr + ETH_HLEN; -+ ucIpVersion = (*pucIpHdr & IPVH_VERSION_MASK) >> IPVH_VERSION_OFFSET; -+ if ((ucIpVersion == IPVERSION) && (pucIpHdr[IPV4_HDR_IP_PROTOCOL_OFFSET] == IP_PROTOCOL_UDP)) { -+ /* UDP */ -+ pucUdpHdr = pucIpHdr + IP_HEADER_LEN; -+ /* check UDP port number */ -+ if (((UINT_16) pucUdpHdr[0] << 8 | (UINT_16) pucUdpHdr[1]) == u2UdpSrcPort) { -+ /* RTP */ -+ pucRtpHdr = pucUdpHdr + 8; -+ u2RtpSn = (UINT_16) pucRtpHdr[2] << 8 | pucRtpHdr[3]; -+ /* trace_printk("F|%d|%s|%d\n", current->tgid, "WIFI-CHIP", u2RtpSn); -+ //frm_sequence); */ -+#ifdef CONFIG_TRACING -+ __mt_update_tracing_mark_write_addr(); -+ if (tracing_mark_write_addr != 0) { -+ event_trace_printk(tracing_mark_write_addr, "F|%d|%s|%d\n", -+ current->tgid, "WIFI-CHIP", u2RtpSn); -+ } -+#endif -+ } -+ } -+ } -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief The PROC function for adjusting Debug Level to turn on/off debugging message. -+* -+* \param[in] file pointer to file. -+* \param[in] buffer Buffer from user space. -+* \param[in] count Number of characters to write -+* \param[in] data Pointer to the private data structure. -+* -+* \return number of characters write from User Space. -+*/ -+/*----------------------------------------------------------------------------*/ -+static ssize_t kalMetCtrlWriteProcfs(struct file *file, const char __user *buffer, size_t count, loff_t *off) -+{ -+ char acBuf[128 + 1]; /* + 1 for "\0" */ -+ UINT_32 u4CopySize; -+ int u8MetProfEnable; -+ -+ IN P_GLUE_INFO_T prGlueInfo; -+ -+ u4CopySize = (count < (sizeof(acBuf) - 1)) ? count : (sizeof(acBuf) - 1); -+ if (copy_from_user(acBuf, buffer, u4CopySize)) -+ return -1; -+ acBuf[u4CopySize] = '\0'; -+ -+ if (sscanf(acBuf, " %d", &u8MetProfEnable) == 1) -+ DBGLOG(INIT, INFO, "MET_PROF: Write MET PROC Enable=%d\n", u8MetProfEnable); -+ if (pMetGlobalData != NULL) { -+ prGlueInfo = (P_GLUE_INFO_T) pMetGlobalData; -+ prGlueInfo->u8MetProfEnable = (UINT_8) u8MetProfEnable; -+ } -+ return count; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief The PROC function for adjusting Debug Level to turn on/off debugging message. -+* -+* \param[in] file pointer to file. -+* \param[in] buffer Buffer from user space. -+* \param[in] count Number of characters to write -+* \param[in] data Pointer to the private data structure. -+* -+* \return number of characters write from User Space. -+*/ -+/*----------------------------------------------------------------------------*/ -+static ssize_t kalMetPortWriteProcfs(struct file *file, const char __user *buffer, size_t count, loff_t *off) -+{ -+ char acBuf[128 + 1]; /* + 1 for "\0" */ -+ UINT_32 u4CopySize; -+ int u16MetUdpPort; -+ -+ IN P_GLUE_INFO_T prGlueInfo; -+ -+ u4CopySize = (count < (sizeof(acBuf) - 1)) ? count : (sizeof(acBuf) - 1); -+ if (copy_from_user(acBuf, buffer, u4CopySize)) -+ return -1; -+ acBuf[u4CopySize] = '\0'; -+ -+ if (sscanf(acBuf, " %d", &u16MetUdpPort) == 1) -+ DBGLOG(INIT, INFO, "MET_PROF: Write MET PROC UDP_PORT=%d\n", u16MetUdpPort); -+ if (pMetGlobalData != NULL) { -+ prGlueInfo = (P_GLUE_INFO_T) pMetGlobalData; -+ prGlueInfo->u16MetUdpPort = (UINT_16) u16MetUdpPort; -+ } -+ return count; -+} -+ -+const struct file_operations rMetProcCtrlFops = { -+.write = kalMetCtrlWriteProcfs -+}; -+ -+const struct file_operations rMetProcPortFops = { -+.write = kalMetPortWriteProcfs -+}; -+ -+int kalMetInitProcfs(IN P_GLUE_INFO_T prGlueInfo) -+{ -+ /* struct proc_dir_entry *pMetProcDir; */ -+ if (init_net.proc_net == (struct proc_dir_entry *)NULL) { -+ DBGLOG(INIT, INFO, "init proc fs fail: proc_net == NULL\n"); -+ return -ENOENT; -+ } -+ /* -+ * Directory: Root (/proc/net/wlan0) -+ */ -+ pMetProcDir = proc_mkdir("wlan0", init_net.proc_net); -+ if (pMetProcDir == NULL) -+ return -ENOENT; -+ /* -+ /proc/net/wlan0 -+ |-- met_ctrl (PROC_MET_PROF_CTRL) -+ |-- met_port (PROC_MET_PROF_PORT) -+ */ -+ /* proc_create(PROC_MET_PROF_CTRL, 0x0644, pMetProcDir, &rMetProcFops); */ -+ proc_create(PROC_MET_PROF_CTRL, 0, pMetProcDir, &rMetProcCtrlFops); -+ proc_create(PROC_MET_PROF_PORT, 0, pMetProcDir, &rMetProcPortFops); -+ -+ pMetGlobalData = (void *)prGlueInfo; -+ -+ return 0; -+} -+ -+int kalMetRemoveProcfs(void) -+{ -+ -+ if (init_net.proc_net == (struct proc_dir_entry *)NULL) { -+ DBGLOG(INIT, WARN, "remove proc fs fail: proc_net == NULL\n"); -+ return -ENOENT; -+ } -+ remove_proc_entry(PROC_MET_PROF_CTRL, pMetProcDir); -+ remove_proc_entry(PROC_MET_PROF_PORT, pMetProcDir); -+ /* remove root directory (proc/net/wlan0) */ -+ remove_proc_entry("wlan0", init_net.proc_net); -+ /* clear MetGlobalData */ -+ pMetGlobalData = NULL; -+ -+ return 0; -+} -+#endif -+UINT_64 kalGetBootTime(void) -+{ -+ struct timespec ts; -+ UINT_64 bootTime = 0; -+ -+ get_monotonic_boottime(&ts); -+ /* we assign ts.tv_sec to bootTime first, then multiply USEC_PER_SEC -+ this will prevent multiply result turn to a negative value on 32bit system */ -+ bootTime = ts.tv_sec; -+ bootTime *= USEC_PER_SEC; -+ bootTime += ts.tv_nsec / NSEC_PER_USEC; -+ return bootTime; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief To indicate scheduled scan results are avilable -+* -+* \param[in] -+* prGlueInfo -+* -+* \return -+* None -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID kalSchedScanResults(IN P_GLUE_INFO_T prGlueInfo) -+{ -+ ASSERT(prGlueInfo); -+ -+ cfg80211_sched_scan_results(priv_to_wiphy(prGlueInfo),0); -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief To indicate scheduled scan has been stopped -+* -+* \param[in] -+* prGlueInfo -+* -+* \return -+* None -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID kalSchedScanStopped(IN P_GLUE_INFO_T prGlueInfo) -+{ -+ GLUE_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(prGlueInfo); -+ -+ /* 1. reset first for newly incoming request */ -+ GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV); -+ if (prGlueInfo->prSchedScanRequest != NULL) -+ prGlueInfo->prSchedScanRequest = NULL; -+ GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV); -+ DBGLOG(SCN, INFO, "cfg80211_sched_scan_stopped send event\n"); -+ -+ /* 2. indication to cfg80211 */ -+ /* 20150205 change cfg80211_sched_scan_stopped to work queue to use K thread to send event instead of Tx thread -+ due to sched_scan_mtx dead lock issue by Tx thread serves oid cmds and send event in the same time */ -+ DBGLOG(SCN, TRACE, "start work queue to send event\n"); -+ schedule_delayed_work(&sched_workq, 0); -+ DBGLOG(SCN, TRACE, "tx_thread return from kalSchedScanStoppped\n"); -+ -+} -+ -+#if CFG_SUPPORT_WAKEUP_REASON_DEBUG -+/* if SPM is not implement this function, we will use this default one */ -+wake_reason_t __weak slp_get_wake_reason(VOID) -+{ -+ return WR_NONE; -+} -+/* if SPM is not implement this function, we will use this default one */ -+UINT_32 __weak spm_get_last_wakeup_src(VOID) -+{ -+ return 0; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief To check if device if wake up by wlan -+* -+* \param[in] -+* prAdapter -+* -+* \return -+* TRUE: wake up by wlan; otherwise, FALSE -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN kalIsWakeupByWlan(P_ADAPTER_T prAdapter) -+{ -+ /* SUSPEND_FLAG_FOR_WAKEUP_REASON is set means system has suspended, but may be failed -+ duo to some driver suspend failed. so we need help of function slp_get_wake_reason */ -+ if (test_and_clear_bit(SUSPEND_FLAG_FOR_WAKEUP_REASON, &prAdapter->ulSuspendFlag) == 0) -+ return FALSE; -+ /* if slp_get_wake_reason or spm_get_last_wakeup_src is NULL, it means SPM module didn't implement -+ it. then we should return FALSE always. otherwise, if slp_get_wake_reason returns WR_WAKE_SRC, -+ then it means the host is suspend successfully. */ -+ if (slp_get_wake_reason() != WR_WAKE_SRC) -+ return FALSE; -+ /* spm_get_last_wakeup_src will returns the last wakeup source, -+ WAKE_SRC_CONN2AP is connsys */ -+ return !!(spm_get_last_wakeup_src() & WAKE_SRC_CONN2AP); -+} -+#endif -+ -+INT_32 kalHaltLock(UINT_32 waitMs) -+{ -+ INT_32 i4Ret = 0; -+ -+ if (waitMs) { -+ i4Ret = down_timeout(&rHaltCtrl.lock, MSEC_TO_JIFFIES(waitMs)); -+ if (!i4Ret) -+ goto success; -+ if (i4Ret != -ETIME) -+ return i4Ret; -+ if (rHaltCtrl.fgHeldByKalIoctl) { -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ -+ wlanExportGlueInfo(&prGlueInfo); -+ -+ DBGLOG(INIT, ERROR, -+ "kalIoctl was executed longer than %u ms, show backtrace of tx_thread!\n", -+ kalGetTimeTick() - rHaltCtrl.u4HoldStart); -+ if (prGlueInfo) -+ show_stack(prGlueInfo->main_thread, NULL); -+ } else { -+ DBGLOG(INIT, ERROR, "halt lock held by %s pid %d longer than %u ms!\n", -+ rHaltCtrl.owner->comm, rHaltCtrl.owner->pid, -+ kalGetTimeTick() - rHaltCtrl.u4HoldStart); -+ show_stack(rHaltCtrl.owner, NULL); -+ } -+ return i4Ret; -+ } -+ down(&rHaltCtrl.lock); -+success: -+ rHaltCtrl.owner = current; -+ rHaltCtrl.u4HoldStart = kalGetTimeTick(); -+ return 0; -+} -+ -+INT_32 kalHaltTryLock(VOID) -+{ -+ INT_32 i4Ret = 0; -+ -+ i4Ret = down_trylock(&rHaltCtrl.lock); -+ if (i4Ret) -+ return i4Ret; -+ rHaltCtrl.owner = current; -+ rHaltCtrl.u4HoldStart = kalGetTimeTick(); -+ return 0; -+} -+ -+VOID kalHaltUnlock(VOID) -+{ -+ if (kalGetTimeTick() - rHaltCtrl.u4HoldStart > WLAN_OID_TIMEOUT_THRESHOLD * 2 && -+ rHaltCtrl.owner) -+ DBGLOG(INIT, ERROR, "process %s pid %d hold halt lock longer than 4s!\n", -+ rHaltCtrl.owner->comm, rHaltCtrl.owner->pid); -+ rHaltCtrl.owner = NULL; -+ up(&rHaltCtrl.lock); -+} -+ -+VOID kalSetHalted(BOOLEAN fgHalt) -+{ -+ rHaltCtrl.fgHalt = fgHalt; -+} -+ -+BOOLEAN kalIsHalted(VOID) -+{ -+ return rHaltCtrl.fgHalt; -+} -+VOID kalPerMonDump(IN P_GLUE_INFO_T prGlueInfo) -+{ -+ struct GL_PER_MON_T *prPerMonitor; -+ -+ prPerMonitor = &prGlueInfo->prAdapter->rPerMonitor; -+ DBGLOG(SW4, WARN, "ulPerfMonFlag:0x%lx\n", prPerMonitor->ulPerfMonFlag); -+ DBGLOG(SW4, WARN, "ulLastTxBytes:%ld\n", prPerMonitor->ulLastTxBytes); -+ DBGLOG(SW4, WARN, "ulLastRxBytes:%ld\n", prPerMonitor->ulLastRxBytes); -+ DBGLOG(SW4, WARN, "ulP2PLastTxBytes:%ld\n", prPerMonitor->ulP2PLastTxBytes); -+ DBGLOG(SW4, WARN, "ulP2PLastRxBytes:%ld\n", prPerMonitor->ulP2PLastRxBytes); -+ DBGLOG(SW4, WARN, "ulThroughput:%ld\n", prPerMonitor->ulThroughput); -+ DBGLOG(SW4, WARN, "u4UpdatePeriod:%d\n", prPerMonitor->u4UpdatePeriod); -+ DBGLOG(SW4, WARN, "u4TarPerfLevel:%d\n", prPerMonitor->u4TarPerfLevel); -+ DBGLOG(SW4, WARN, "u4CurrPerfLevel:%d\n", prPerMonitor->u4CurrPerfLevel); -+ DBGLOG(SW4, WARN, "netStats tx_bytes:%ld\n", prGlueInfo->rNetDevStats.tx_bytes); -+ DBGLOG(SW4, WARN, "netStats tx_bytes:%ld\n", prGlueInfo->rNetDevStats.rx_bytes); -+ DBGLOG(SW4, WARN, "p2p netStats tx_bytes:%ld\n", prGlueInfo->prP2PInfo->rNetDevStats.tx_bytes); -+ DBGLOG(SW4, WARN, "p2p netStats tx_bytes:%ld\n", prGlueInfo->prP2PInfo->rNetDevStats.rx_bytes); -+} -+ -+inline INT32 kalPerMonInit(IN P_GLUE_INFO_T prGlueInfo) -+{ -+ struct GL_PER_MON_T *prPerMonitor; -+ -+ prPerMonitor = &prGlueInfo->prAdapter->rPerMonitor; -+ DBGLOG(SW4, INFO, "enter %s\n", __func__); -+ if (KAL_TEST_BIT(PERF_MON_RUNNING_BIT_OFF, prPerMonitor->ulPerfMonFlag)) -+ DBGLOG(SW4, WARN, "abnormal, perf monitory already running\n"); -+ KAL_CLR_BIT(PERF_MON_RUNNING_BIT_OFF, prPerMonitor->ulPerfMonFlag); -+ KAL_CLR_BIT(PERF_MON_DISABLE_BIT_OFF, prPerMonitor->ulPerfMonFlag); -+ KAL_SET_BIT(PERF_MON_STOP_BIT_OFF, prPerMonitor->ulPerfMonFlag); -+ prPerMonitor->u4UpdatePeriod = 1000; -+ cnmTimerInitTimer(prGlueInfo->prAdapter, -+ &prPerMonitor->rPerfMonTimer, -+ (PFN_MGMT_TIMEOUT_FUNC) kalPerMonHandler, (ULONG) NULL); -+ DBGLOG(SW4, INFO, "exit %s\n", __func__); -+ return 0; -+} -+ -+inline INT32 kalPerMonDisable(IN P_GLUE_INFO_T prGlueInfo) -+{ -+ struct GL_PER_MON_T *prPerMonitor; -+ -+ prPerMonitor = &prGlueInfo->prAdapter->rPerMonitor; -+ -+ DBGLOG(SW4, INFO, "enter %s\n", __func__); -+ if (KAL_TEST_BIT(PERF_MON_RUNNING_BIT_OFF, prPerMonitor->ulPerfMonFlag)) { -+ DBGLOG(SW4, TRACE, "need to stop before disable\n"); -+ kalPerMonStop(prGlueInfo); -+ } -+ KAL_SET_BIT(PERF_MON_DISABLE_BIT_OFF, prPerMonitor->ulPerfMonFlag); -+ DBGLOG(SW4, TRACE, "exit %s\n", __func__); -+ return 0; -+} -+ -+inline INT32 kalPerMonEnable(IN P_GLUE_INFO_T prGlueInfo) -+{ -+ struct GL_PER_MON_T *prPerMonitor; -+ -+ prPerMonitor = &prGlueInfo->prAdapter->rPerMonitor; -+ -+ DBGLOG(SW4, INFO, "enter %s\n", __func__); -+ KAL_CLR_BIT(PERF_MON_DISABLE_BIT_OFF, prPerMonitor->ulPerfMonFlag); -+ DBGLOG(SW4, TRACE, "exit %s\n", __func__); -+ return 0; -+} -+ -+inline INT32 kalPerMonStart(IN P_GLUE_INFO_T prGlueInfo) -+{ -+ struct GL_PER_MON_T *prPerMonitor; -+ -+ prPerMonitor = &prGlueInfo->prAdapter->rPerMonitor; -+ DBGLOG(SW4, TRACE, "enter %s\n", __func__); -+ if (KAL_TEST_BIT(PERF_MON_DISABLE_BIT_OFF, prPerMonitor->ulPerfMonFlag)) -+ return 0; -+ if (KAL_TEST_BIT(PERF_MON_RUNNING_BIT_OFF, prPerMonitor->ulPerfMonFlag)) { -+ DBGLOG(SW4, TRACE, "perf monitor already running\n"); -+ return 0; -+ } -+ cnmTimerStartTimer(prGlueInfo->prAdapter, &prPerMonitor->rPerfMonTimer, prPerMonitor->u4UpdatePeriod); -+ KAL_SET_BIT(PERF_MON_RUNNING_BIT_OFF, prPerMonitor->ulPerfMonFlag); -+ KAL_CLR_BIT(PERF_MON_STOP_BIT_OFF, prPerMonitor->ulPerfMonFlag); -+ DBGLOG(SW4, INFO, "perf monitor started\n"); -+ return 0; -+} -+ -+inline INT32 kalPerMonStop(IN P_GLUE_INFO_T prGlueInfo) -+{ -+ struct GL_PER_MON_T *prPerMonitor; -+ -+ prPerMonitor = &prGlueInfo->prAdapter->rPerMonitor; -+ DBGLOG(SW4, TRACE, "enter %s\n", __func__); -+ -+ if (KAL_TEST_BIT(PERF_MON_DISABLE_BIT_OFF, prPerMonitor->ulPerfMonFlag)) { -+ DBGLOG(SW4, TRACE, "perf monitory disabled\n"); -+ return 0; -+ } -+ -+ if (KAL_TEST_BIT(PERF_MON_STOP_BIT_OFF, prPerMonitor->ulPerfMonFlag)) { -+ DBGLOG(SW4, TRACE, "perf monitory already stopped\n"); -+ return 0; -+ } -+ -+ KAL_SET_BIT(PERF_MON_STOP_BIT_OFF, prPerMonitor->ulPerfMonFlag); -+ if (KAL_TEST_BIT(PERF_MON_RUNNING_BIT_OFF, prPerMonitor->ulPerfMonFlag)) { -+ cnmTimerStopTimer(prGlueInfo->prAdapter, &prPerMonitor->rPerfMonTimer); -+ KAL_CLR_BIT(PERF_MON_RUNNING_BIT_OFF, prPerMonitor->ulPerfMonFlag); -+ prPerMonitor->ulLastRxBytes = 0; -+ prPerMonitor->ulLastTxBytes = 0; -+ prPerMonitor->ulP2PLastRxBytes = 0; -+ prPerMonitor->ulP2PLastTxBytes = 0; -+ prPerMonitor->ulThroughput = 0; -+ prPerMonitor->u4CurrPerfLevel = 0; -+ prPerMonitor->u4TarPerfLevel = 0; -+ /*Cancel CPU performance mode request*/ -+ kalBoostCpu(0); -+ } -+ DBGLOG(SW4, TRACE, "exit %s\n", __func__); -+ return 0; -+} -+ -+inline INT32 kalPerMonDestroy(IN P_GLUE_INFO_T prGlueInfo) -+{ -+ kalPerMonDisable(prGlueInfo); -+ return 0; -+} -+ -+VOID kalPerMonHandler(IN P_ADAPTER_T prAdapter, ULONG ulParam) -+{ -+ /*Calculate current throughput*/ -+ struct GL_PER_MON_T *prPerMonitor; -+ -+ LONG latestTxBytes, latestRxBytes, txDiffBytes, rxDiffBytes; -+ LONG p2pLatestTxBytes, p2pLatestRxBytes, p2pTxDiffBytes, p2pRxDiffBytes; -+ P_GLUE_INFO_T prGlueInfo = prAdapter->prGlueInfo; -+ -+ if ((prGlueInfo->ulFlag & GLUE_FLAG_HALT) || (!prAdapter->fgIsP2PRegistered)) -+ return; -+ -+ prPerMonitor = &prAdapter->rPerMonitor; -+ DBGLOG(SW4, TRACE, "enter kalPerMonHandler\n"); -+ if (KAL_TEST_BIT(PERF_MON_DISABLE_BIT_OFF, prPerMonitor->ulPerfMonFlag)) { -+ KAL_CLR_BIT(PERF_MON_RUNNING_BIT_OFF, prPerMonitor->ulPerfMonFlag); -+ DBGLOG(SW4, WARN, "perf monitory disabled, omit timeout event\n"); -+ return; -+ } -+ -+ if (KAL_TEST_BIT(PERF_MON_STOP_BIT_OFF, prPerMonitor->ulPerfMonFlag)) { -+ KAL_CLR_BIT(PERF_MON_RUNNING_BIT_OFF, prPerMonitor->ulPerfMonFlag); -+ DBGLOG(SW4, WARN, "perf monitory stopped, omit timeout event\n"); -+ return; -+ } -+ latestTxBytes = prGlueInfo->rNetDevStats.tx_bytes; -+ latestRxBytes = prGlueInfo->rNetDevStats.rx_bytes; -+ p2pLatestTxBytes = prGlueInfo->prP2PInfo->rNetDevStats.tx_bytes; -+ p2pLatestRxBytes = prGlueInfo->prP2PInfo->rNetDevStats.rx_bytes; -+ if (0 == prPerMonitor->ulLastRxBytes && -+ 0 == prPerMonitor->ulLastTxBytes && -+ 0 == prPerMonitor->ulP2PLastRxBytes && -+ 0 == prPerMonitor->ulP2PLastTxBytes) { -+ prPerMonitor->ulThroughput = 0; -+ } else { -+ txDiffBytes = latestTxBytes - prPerMonitor->ulLastTxBytes; -+ rxDiffBytes = latestRxBytes - prPerMonitor->ulLastRxBytes; -+ if (0 > txDiffBytes) -+ txDiffBytes = -(txDiffBytes); -+ if (0 > rxDiffBytes) -+ rxDiffBytes = -(rxDiffBytes); -+ -+ p2pTxDiffBytes = p2pLatestTxBytes - prPerMonitor->ulP2PLastTxBytes; -+ p2pRxDiffBytes = p2pLatestRxBytes - prPerMonitor->ulP2PLastRxBytes; -+ if (0 > p2pTxDiffBytes) -+ p2pTxDiffBytes = -(p2pTxDiffBytes); -+ if (0 > p2pRxDiffBytes) -+ p2pRxDiffBytes = -(p2pRxDiffBytes); -+ -+ prPerMonitor->ulThroughput = txDiffBytes + rxDiffBytes + p2pTxDiffBytes + p2pRxDiffBytes; -+ prPerMonitor->ulThroughput *= 1000; -+ prPerMonitor->ulThroughput /= prPerMonitor->u4UpdatePeriod; -+ prPerMonitor->ulThroughput <<= 3; -+ } -+ /*start the timer again to make sure we can cancel performance mode request in the end*/ -+ cnmTimerStartTimer(prGlueInfo->prAdapter, &prPerMonitor->rPerfMonTimer, prPerMonitor->u4UpdatePeriod); -+ -+ prPerMonitor->ulLastTxBytes = latestTxBytes; -+ prPerMonitor->ulLastRxBytes = latestRxBytes; -+ prPerMonitor->ulP2PLastTxBytes = p2pLatestTxBytes; -+ prPerMonitor->ulP2PLastRxBytes = p2pLatestRxBytes; -+ -+ if (prPerMonitor->ulThroughput < THROUGHPUT_L1_THRESHOLD) -+ prPerMonitor->u4TarPerfLevel = 0; -+ else if (prPerMonitor->ulThroughput < THROUGHPUT_L2_THRESHOLD) -+ prPerMonitor->u4TarPerfLevel = 1; -+ else if (prPerMonitor->ulThroughput < THROUGHPUT_L3_THRESHOLD) -+ prPerMonitor->u4TarPerfLevel = 2; -+ else -+ prPerMonitor->u4TarPerfLevel = 3; -+ if (prPerMonitor->u4TarPerfLevel != prPerMonitor->u4CurrPerfLevel) { -+ if (0 == prPerMonitor->u4TarPerfLevel) { -+ /*cancel CPU performance mode request*/ -+ kalPerMonStop(prGlueInfo); -+ } else{ -+ DBGLOG(SW4, TRACE, "throughput:%ld bps\n", prPerMonitor->ulThroughput); -+ /*adjust CPU core number to prPerMonitor->u4TarPerfLevel+1*/ -+ kalBoostCpu(prPerMonitor->u4TarPerfLevel+1); -+ /*start the timer again to make sure we can cancel performance mode request in the end*/ -+ cnmTimerStartTimer(prGlueInfo->prAdapter, -+ &prPerMonitor->rPerfMonTimer, -+ prPerMonitor->u4UpdatePeriod); -+ } -+ } -+ prPerMonitor->u4CurrPerfLevel = prPerMonitor->u4TarPerfLevel; -+ DBGLOG(SW4, TRACE, "exit kalPerMonHandler\n"); -+} -+ -+INT32 __weak kalBoostCpu(UINT_32 core_num) -+{ -+ DBGLOG(SW4, WARN, "enter weak kalBoostCpu, core_num:%d\n", core_num); -+ return 0; -+} -+ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_p2p.c b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_p2p.c -new file mode 100644 -index 000000000000..2d9631538942 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_p2p.c -@@ -0,0 +1,4671 @@ -+/* -+** Id: @(#) gl_p2p.c@@ -+*/ -+ -+/*! \file gl_p2p.c -+ \brief Main routines of Linux driver interface for Wi-Fi Direct -+ -+ This file contains the main routines of Linux driver for MediaTek Inc. 802.11 -+ Wireless LAN Adapters. -+*/ -+ -+/* -+** Log: gl_p2p.c -+** -+** 09 12 2012 wcpadmin -+** [ALPS00276400] Remove MTK copyright and legal header on GPL/LGPL related packages -+** . -+** -+** 08 17 2012 yuche.tsai -+** NULL -+** Fix compile warning. -+** -+** 08 16 2012 yuche.tsai -+** NULL -+** Fix compile warning. -+** -+** 08 14 2012 yuche.tsai -+** NULL -+** FPB from ALPS.JB to phase 2 release. -+** -+** 07 26 2012 yuche.tsai -+** [ALPS00324337] [ALPS.JB][Hot-Spot] Driver update for Hot-Spot -+** Update driver code of ALPS.JB for hot-spot. -+** -+** 07 19 2012 yuche.tsai -+** NULL -+** Code update for JB. -+ * -+ * 07 17 2012 yuche.tsai -+ * NULL -+ * Fix compile error for JB. -+ * -+ * 07 17 2012 yuche.tsai -+ * NULL -+ * Let netdev bring up. -+ * -+ * 07 17 2012 yuche.tsai -+ * NULL -+ * Compile no error before trial run. -+ * -+ * 01 09 2012 terry.wu -+ * [WCXRP00001166] [Wi-Fi] [Driver] cfg80211 integration for p2p newtork -+ * cfg80211 integration for p2p network. -+ * -+ * 12 19 2011 terry.wu -+ * [WCXRP00001142] [Wi-Fi] [P2P Driver] XOR local admin bit to generate p2p net device MAC -+ * XOR local administrated bit to generate net device MAC of p2p network. -+ * -+ * 12 02 2011 yuche.tsai -+ * NULL -+ * Fix possible KE when unload p2p. -+ * -+ * 11 24 2011 yuche.tsai -+ * NULL -+ * Fix P2P IOCTL of multicast address bug, add low power driver stop control. -+ * -+ * 11 22 2011 yuche.tsai -+ * NULL -+ * Update RSSI link quality of P2P Network query method. (Bug fix) -+ * -+ * 11 19 2011 yuche.tsai -+ * NULL -+ * Add RSSI support for P2P network. -+ * -+ * 11 16 2011 yuche.tsai -+ * [WCXRP00001107] [Volunteer Patch][Driver] Large Network Type index assert in FW issue. -+ * Avoid using work thread in set p2p multicast address callback. -+ * -+ * 11 11 2011 yuche.tsai -+ * NULL -+ * Fix work thread cancel issue. -+ * -+ * 11 11 2011 yuche.tsai -+ * NULL -+ * Fix default device name issue. -+ * -+ * 11 08 2011 yuche.tsai -+ * [WCXRP00001094] [Volunteer Patch][Driver] Driver version & supplicant version query & set support for service -+ * discovery version check. -+ * Add support for driver version query & p2p supplicant verseion set. -+ * For new service discovery mechanism sync. -+ * -+ * 11 07 2011 yuche.tsai -+ * NULL -+ * [ALPS 00087243] KE in worker thread. -+ * The multicast address list is scheduled in worker thread. -+ * Before the worker thread is excuted, if P2P is unloaded, a KE may occur. -+ * -+ * 10 26 2011 terry.wu -+ * [WCXRP00001066] [MT6620 Wi-Fi] [P2P Driver] Fix P2P Oid Issue -+ * Fix some P2P OID functions didn't raise its flag "fgIsP2pOid" issue. -+ * -+ * 10 25 2011 cm.chang -+ * [WCXRP00001058] [All Wi-Fi][Driver] Fix sta_rec's phyTypeSet and OBSS scan in AP mode -+ * . -+ * -+ * 10 18 2011 yuche.tsai -+ * [WCXRP00001045] [WiFi Direct][Driver] Check 2.1 branch. -+ * Support Channel Query. -+ * -+ * 10 18 2011 yuche.tsai -+ * [WCXRP00001045] [WiFi Direct][Driver] Check 2.1 branch. -+ * New 2.1 branch -+ -+ * -+ * 08 26 2011 yuche.tsai -+ * NULL -+ * Fix bug of parsing secondary device list type issue. -+ * -+ * 08 24 2011 yuche.tsai -+ * [WCXRP00000919] [Volunteer Patch][WiFi Direct][Driver] Invitation New Feature. -+ * Invitation Abort. -+ * -+ * 08 23 2011 yuche.tsai -+ * NULL -+ * Fix multicast address list issue of P2P. -+ * -+ * 08 22 2011 chinglan.wang -+ * NULL -+ * Fix invitation indication bug.. -+ * -+ * 08 16 2011 cp.wu -+ * [WCXRP00000934] [MT6620 Wi-Fi][Driver][P2P] Wi-Fi hot spot with auto sparse channel residence -+ * auto channel decision for 2.4GHz hot spot mode -+ * -+ * 08 16 2011 chinglan.wang -+ * NULL -+ * Add the group id information in the invitation indication. -+ * -+ * 08 09 2011 yuche.tsai -+ * [WCXRP00000919] [Volunteer Patch][WiFi Direct][Driver] Invitation New Feature. -+ * Invitation Feature add on. -+ * -+ * 08 05 2011 yuche.tsai -+ * [WCXRP00000856] [Volunteer Patch][WiFi Direct][Driver] MT6620 WiFi Direct IOT Issue with BCM solution. -+ * Add Password ID check for quick connection. -+ * Also modify some connection policy. -+ * -+ * 07 18 2011 chinglan.wang -+ * NULL -+ * Add IOC_P2P_GO_WSC_IE (p2p capability). -+ * -+ * 06 14 2011 yuche.tsai -+ * NULL -+ * Add compile flag to disable persistent group support. -+ * -+ * 05 04 2011 chinglan.wang -+ * [WCXRP00000698] [MT6620 Wi-Fi][P2P][Driver] Add p2p invitation command for the p2p driver -+ * . -+ * -+ * 05 02 2011 yuche.tsai -+ * [WCXRP00000693] [Volunteer Patch][MT6620][Driver] Clear Formation Flag after TX lifetime timeout. -+ * Clear formation flag after formation timeout. -+ * -+ * 04 22 2011 george.huang -+ * [WCXRP00000621] [MT6620 Wi-Fi][Driver] Support P2P supplicant to set power mode -+ * . -+ * -+ * 04 21 2011 george.huang -+ * [WCXRP00000621] [MT6620 Wi-Fi][Driver] Support P2P supplicant to set power mode -+ * 1. Revise P2P power mode setting. -+ * 2. Revise fast-PS for concurrent -+ * -+ * 04 19 2011 wh.su -+ * NULL -+ * Adding length check before doing WPA RSN IE parsing for scan results indicate. -+ * -+ * 04 14 2011 yuche.tsai -+ * [WCXRP00000646] [Volunteer Patch][MT6620][FW/Driver] Sigma Test Modification for some test case. -+ * Connection flow refine for Sigma test. -+ * -+ * 04 08 2011 yuche.tsai -+ * [WCXRP00000624] [Volunteer Patch][MT6620][Driver] Add device discoverability support for GO. -+ * Add device discoverability support. -+ * -+ * 04 08 2011 george.huang -+ * [WCXRP00000621] [MT6620 Wi-Fi][Driver] Support P2P supplicant to set power mode -+ * separate settings of P2P and AIS -+ * -+ * 04 07 2011 terry.wu -+ * [WCXRP00000619] [MT6620 Wi-Fi][Driver] fix kernel panic may occur when removing wlan -+ * Fix kernel panic may occur when removing wlan driver. -+ * -+ * 03 31 2011 wh.su -+ * [WCXRP00000614] [MT6620 Wi-Fi][Driver] P2P: Update beacon content while setting WSC IE -+ * Update the wsc ie to beacon content. -+ * -+ * 03 25 2011 wh.su -+ * NULL -+ * add the sample code for set power mode and get power mode. -+ * -+ * 03 25 2011 yuche.tsai -+ * NULL -+ * Improve some error handleing. -+ * -+ * 03 22 2011 george.huang -+ * [WCXRP00000504] [MT6620 Wi-Fi][FW] Support Sigma CAPI for power saving related command -+ * link with supplicant commands -+ * -+ * 03 22 2011 yuche.tsai -+ * [WCXRP00000584] [Volunteer Patch][MT6620][Driver] Add beacon timeout support for WiFi Direct. -+ * Modify formation policy. -+ * -+ * 03 22 2011 yuche.tsai -+ * NULL -+ * Modify formation policy setting. -+ * -+ * 03 18 2011 yuche.tsai -+ * [WCXRP00000574] [Volunteer Patch][MT6620][Driver] Modify P2P FSM Connection Flow -+ * Modify connection flow after Group Formation Complete, or device connect to a GO. -+ * Instead of request channel & connect directly, we use scan to allocate channel bandwidth & connect after RX BCN. -+ * -+ * 03 15 2011 wh.su -+ * [WCXRP00000563] [MT6620 Wi-Fi] [P2P] Set local config method while set password Id ready -+ * set lccal config method method while set password Id ready. -+ * -+ * 03 15 2011 yuche.tsai -+ * [WCXRP00000560] [Volunteer Patch][MT6620][Driver] P2P Connection from UI using KEY/DISPLAY issue -+ * Fix some configure method issue. -+ * -+ * 03 15 2011 jeffrey.chang -+ * [WCXRP00000558] [MT6620 Wi-Fi][MT6620 Wi-Fi][Driver] refine the queue selection algorithm for WMM -+ * refine queue_select function -+ * -+ * 03 13 2011 wh.su -+ * [WCXRP00000530] [MT6620 Wi-Fi] [Driver] skip doing p2pRunEventAAAComplete after send assoc response Tx Done -+ * add code for avoid compiling warning. -+ * -+ * 03 10 2011 yuche.tsai -+ * NULL -+ * Add P2P API. -+ * -+ * 03 10 2011 terry.wu -+ * [WCXRP00000505] [MT6620 Wi-Fi][Driver/FW] WiFi Direct Integration -+ * Remove unnecessary assert and message. -+ * -+ * 03 08 2011 wh.su -+ * [WCXRP00000488] [MT6620 Wi-Fi][Driver] Support the SIGMA set p2p parameter to driver -+ * support the power save related p2p setting. -+ * -+ * 03 07 2011 wh.su -+ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code -+ * rename the define to anti_pviracy. -+ * -+ * 03 05 2011 wh.su -+ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code -+ * add the code to get the check rsponse and indicate to app. -+ * -+ * 03 03 2011 jeffrey.chang -+ * [WCXRP00000512] [MT6620 Wi-Fi][Driver] modify the net device relative functions to support the H/W multiple queue -+ * support concurrent network -+ * -+ * 03 03 2011 jeffrey.chang -+ * [WCXRP00000512] [MT6620 Wi-Fi][Driver] modify the net device relative functions to support the H/W multiple queue -+ * modify P2P's netdevice functions to support multiple H/W queues -+ * -+ * 03 03 2011 cp.wu -+ * [WCXRP00000283] [MT6620 Wi-Fi][Driver][Wi-Fi Direct] Implementation of interface for supporting Wi-Fi Direct Service -+ * Discovery -+ * for get request, the buffer length to be copied is header + payload. -+ * -+ * 03 02 2011 wh.su -+ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code -+ * add code to let the beacon and probe response for Auto GO WSC . -+ * -+ * 03 02 2011 cp.wu -+ * [WCXRP00000283] [MT6620 Wi-Fi][Driver][Wi-Fi Direct] Implementation of interface for supporting Wi-Fi Direct Service -+ * Discovery -+ * add a missed break. -+ * -+ * 03 01 2011 yuche.tsai -+ * [WCXRP00000501] [Volunteer Patch][MT6620][Driver] No common channel issue when doing GO formation -+ * Update channel issue when doing GO formation.. -+ * -+ * 02 25 2011 wh.su -+ * [WCXRP00000488] [MT6620 Wi-Fi][Driver] Support the SIGMA set p2p parameter to driver -+ * add the Operation channel setting. -+ * -+ * 02 23 2011 wh.su -+ * [WCXRP00000488] [MT6620 Wi-Fi][Driver] Support the SIGMA set p2p parameter to driver -+ * fixed the set int ioctl set index and value map to driver issue. -+ * -+ * 02 22 2011 wh.su -+ * [WCXRP00000488] [MT6620 Wi-Fi][Driver] Support the SIGMA set p2p parameter to driver -+ * adding the ioctl set int from supplicant, and can used to set the p2p parameters -+ * -+ * 02 21 2011 terry.wu -+ * [WCXRP00000476] [MT6620 Wi-Fi][Driver] Clean P2P scan list while removing P2P -+ * Clean P2P scan list while removing P2P. -+ * -+ * 02 18 2011 wh.su -+ * [WCXRP00000471] [MT6620 Wi-Fi][Driver] Add P2P Provison discovery append Config Method attribute at WSC IE -+ * fixed the ioctl setting that index not map to spec defined config method. -+ * -+ * 02 17 2011 wh.su -+ * [WCXRP00000471] [MT6620 Wi-Fi][Driver] Add P2P Provison discovery append Config Method attribute at WSC IE -+ * append the WSC IE config method attribute at provision discovery request. -+ * -+ * 02 17 2011 wh.su -+ * [WCXRP00000448] [MT6620 Wi-Fi][Driver] Fixed WSC IE not send out at probe request -+ * modify the structure pointer for set WSC IE. -+ * -+ * 02 16 2011 wh.su -+ * [WCXRP00000448] [MT6620 Wi-Fi][Driver] Fixed WSC IE not send out at probe request -+ * fixed the probe request send out without WSC IE issue (at P2P). -+ * -+ * 02 09 2011 cp.wu -+ * [WCXRP00000283] [MT6620 Wi-Fi][Driver][Wi-Fi Direct] Implementation of interface for supporting Wi-Fi Direct Service -+ * Discovery -+ * fix typo -+ * -+ * 02 09 2011 yuche.tsai -+ * [WCXRP00000431] [Volunteer Patch][MT6620][Driver] Add MLME support for deauthentication under AP(Hot-Spot) mode. -+ * Add Support for MLME deauthentication for Hot-Spot. -+ * -+ * 01 25 2011 terry.wu -+ * [WCXRP00000393] [MT6620 Wi-Fi][Driver] Add new module insert parameter -+ * Add a new module parameter to indicate current runnig mode, P2P or AP. -+ * -+ * 01 12 2011 yuche.tsai -+ * [WCXRP00000352] [Volunteer Patch][MT6620][Driver] P2P Statsion Record Client List Issue -+ * 1. Modify Channel Acquire Time of AP mode from 5s to 1s. -+ * 2. Call cnmP2pIsPermit() before active P2P network. -+ * 3. Add channel selection support for AP mode. -+ * -+ * 01 05 2011 cp.wu -+ * [WCXRP00000283] [MT6620 Wi-Fi][Driver][Wi-Fi Direct] Implementation of interface for supporting Wi-Fi Direct Service -+ * Discovery -+ * ioctl implementations for P2P Service Discovery -+ * -+ * 01 04 2011 cp.wu -+ * [WCXRP00000338] [MT6620 Wi-Fi][Driver] Separate kalMemAlloc into kmalloc and vmalloc implementations to ease -+ * physically continuous memory demands -+ * separate kalMemAlloc() into virtually-continuous and physically-continuous type to ease slab system pressure -+ * -+ * 12 22 2010 cp.wu -+ * [WCXRP00000283] [MT6620 Wi-Fi][Driver][Wi-Fi Direct] Implementation of interface for supporting Wi-Fi Direct Service -+ * Discovery -+ * 1. header file restructure for more clear module isolation -+ * 2. add function interface definition for implementing Service Discovery callbacks -+ * -+ * 12 15 2010 cp.wu -+ * NULL -+ * invoke nicEnableInterrupt() before leaving from wlanAdapterStart() -+ * -+ * 12 08 2010 yuche.tsai -+ * [WCXRP00000245] [MT6620][Driver] Invitation & Provision Discovery Feature Check-in -+ * [WCXRP000000245][MT6620][Driver] Invitation Request Feature Add -+ * -+ * 11 30 2010 yuche.tsai -+ * NULL -+ * Invitation & Provision Discovery Indication. -+ * -+ * 11 17 2010 wh.su -+ * [WCXRP00000164] [MT6620 Wi-Fi][Driver] Support the p2p random SSID[WCXRP00000179] [MT6620 Wi-Fi][FW] Set the Tx -+ * lowest rate at wlan table for normal operation -+ * fixed some ASSERT check. -+ * -+ * 11 04 2010 wh.su -+ * [WCXRP00000164] [MT6620 Wi-Fi][Driver] Support the p2p random SSID -+ * adding the p2p random ssid support. -+ * -+ * 10 20 2010 wh.su -+ * [WCXRP00000124] [MT6620 Wi-Fi] [Driver] Support the dissolve P2P Group -+ * Add the code to support disconnect p2p group -+ * -+ * 10 04 2010 wh.su -+ * [WCXRP00000081] [MT6620][Driver] Fix the compiling error at WinXP while enable P2P -+ * add a kal function for set cipher. -+ * -+ * 10 04 2010 wh.su -+ * [WCXRP00000081] [MT6620][Driver] Fix the compiling error at WinXP while enable P2P -+ * fixed compiling error while enable p2p. -+ * -+ * 09 28 2010 wh.su -+ * NULL -+ * [WCXRP00000069][MT6620 Wi-Fi][Driver] Fix some code for phase 1 P2P Demo. -+ * -+ * 09 21 2010 kevin.huang -+ * [WCXRP00000054] [MT6620 Wi-Fi][Driver] Restructure driver for second Interface -+ * Isolate P2P related function for Hardware Software Bundle -+ * -+ * 09 21 2010 kevin.huang -+ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning -+ * Eliminate Linux Compile Warning -+ * -+ * 09 10 2010 george.huang -+ * NULL -+ * update iwpriv LP related -+ * -+ * 09 10 2010 wh.su -+ * NULL -+ * fixed the compiling error at win XP. -+ * -+ * 09 09 2010 cp.wu -+ * NULL -+ * add WPS/WPA/RSN IE for Wi-Fi Direct scanning result. -+ * -+ * 09 07 2010 wh.su -+ * NULL -+ * adding the code for beacon/probe req/ probe rsp wsc ie at p2p. -+ * -+ * 09 06 2010 wh.su -+ * NULL -+ * let the p2p can set the privacy bit at beacon and rsn ie at assoc req at key handshake state. -+ * -+ * 08 25 2010 cp.wu -+ * NULL -+ * add netdev_ops(NDO) for linux kernel 2.6.31 or greater -+ * -+ * 08 23 2010 cp.wu -+ * NULL -+ * revise constant definitions to be matched with implementation (original cmd-event definition is deprecated) -+ * -+ * 08 20 2010 cp.wu -+ * NULL -+ * correct typo. -+ * -+ * 08 20 2010 yuche.tsai -+ * NULL -+ * Invert Connection request provision status parameter. -+ * -+ * 08 19 2010 cp.wu -+ * NULL -+ * add set mac address interface for further possibilities of wpa_supplicant overriding interface address. -+ * -+ * 08 18 2010 cp.wu -+ * NULL -+ * modify pwp ioctls attribution by removing FIXED_SIZE. -+ * -+ * 08 18 2010 jeffrey.chang -+ * NULL -+ * support multi-function sdio -+ * -+ * 08 17 2010 cp.wu -+ * NULL -+ * correct p2p net device registration with NULL pointer access issue. -+ * -+ * 08 16 2010 cp.wu -+ * NULL -+ * P2P packets are now marked when being queued into driver, and identified later without checking MAC address -+ * -+ * 08 16 2010 cp.wu -+ * NULL -+ * add subroutines for P2P to set multicast list. -+ * -+ * 08 16 2010 george.huang -+ * NULL -+ * add wext handlers to link P2P set PS profile/ network address function (TBD) -+ * -+ * 08 16 2010 cp.wu -+ * NULL -+ * revised implementation of Wi-Fi Direct io controls. -+ * -+ * 08 12 2010 cp.wu -+ * NULL -+ * follow-up with ioctl interface update for Wi-Fi Direct application -+ * -+ * 08 06 2010 cp.wu -+ * NULL -+ * driver hook modifications corresponding to ioctl interface change. -+ * -+ * 08 03 2010 cp.wu -+ * NULL -+ * add basic support for ioctl of getting scan result. (only address and SSID are reporterd though) -+ * -+ * 08 03 2010 cp.wu -+ * NULL -+ * [Wi-Fi Direct Driver Hook] change event indication API to be consistent with supplicant -+ * -+ * 08 03 2010 cp.wu -+ * NULL -+ * surpress compilation warning. -+ * -+ * 08 03 2010 cp.wu -+ * NULL -+ * [Wi-Fi Direct] add framework for driver hooks -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 23 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * p2p interface revised to be sync. with HAL -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 06 01 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * add ioctl to configure scan mode for p2p connection -+ * -+ * 05 31 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * add cfg80211 interface, which is to replace WE, for further extension -+ * -+ * 05 17 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * implement private io controls for Wi-Fi Direct -+ * -+ * 05 17 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * implement get scan result. -+ * -+ * 05 17 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * add basic handling framework for wireless extension ioctls. -+ * -+ * 05 17 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * 1) add timeout handler mechanism for pending command packets -+ * 2) add p2p add/removal key -+ * -+ * 05 14 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * implement wireless extension ioctls in iw_handler form. -+ * -+ * 05 14 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * add ioctl framework for Wi-Fi Direct by reusing wireless extension ioctls as well -+ * -+ * 05 11 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * p2p ioctls revised. -+ * -+ * 05 11 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * add ioctl for controlling p2p scan phase parameters -+ * -+ * 05 10 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * implement basic wi-fi direct framework -+ * -+ * 05 07 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * add basic framework for implementating P2P driver hook. -+ * -+** -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include -+#include -+ -+#include "gl_os.h" -+#include "wlan_lib.h" -+#include "gl_wext.h" -+#include "gl_p2p_os.h" -+#include "gl_p2p_ioctl.h" -+#include "gl_vendor.h" -+ -+#include "precomp.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+#define ARGV_MAX_NUM (4) -+ -+/*For CFG80211 - wiphy parameters*/ -+#define MAX_SCAN_LIST_NUM (1) -+#define MAX_SCAN_IE_LEN (512) -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+#if CFG_ENABLE_WIFI_DIRECT_CFG_80211 -+static struct cfg80211_ops mtk_p2p_ops = { -+ .change_virtual_intf = mtk_p2p_cfg80211_change_iface, /* 1st */ -+ .change_bss = mtk_p2p_cfg80211_change_bss, -+ .scan = mtk_p2p_cfg80211_scan, -+ .remain_on_channel = mtk_p2p_cfg80211_remain_on_channel, -+ .cancel_remain_on_channel = mtk_p2p_cfg80211_cancel_remain_on_channel, -+ .mgmt_tx = mtk_p2p_cfg80211_mgmt_tx, -+ .connect = mtk_p2p_cfg80211_connect, -+ .disconnect = mtk_p2p_cfg80211_disconnect, -+ .deauth = mtk_p2p_cfg80211_deauth, -+ .disassoc = mtk_p2p_cfg80211_disassoc, -+ .start_ap = mtk_p2p_cfg80211_start_ap, -+ .change_beacon = mtk_p2p_cfg80211_change_beacon, -+ .stop_ap = mtk_p2p_cfg80211_stop_ap, -+ .set_wiphy_params = mtk_p2p_cfg80211_set_wiphy_params, -+ .del_station = mtk_p2p_cfg80211_del_station, -+ .set_monitor_channel = mtk_p2p_cfg80211_set_channel, -+ .set_bitrate_mask = mtk_p2p_cfg80211_set_bitrate_mask, -+ .mgmt_frame_register = mtk_p2p_cfg80211_mgmt_frame_register, -+ .get_station = mtk_p2p_cfg80211_get_station, -+ .add_key = mtk_p2p_cfg80211_add_key, -+ .get_key = mtk_p2p_cfg80211_get_key, -+ .del_key = mtk_p2p_cfg80211_del_key, -+ .set_default_key = mtk_p2p_cfg80211_set_default_key, -+ .join_ibss = mtk_p2p_cfg80211_join_ibss, -+ .leave_ibss = mtk_p2p_cfg80211_leave_ibss, -+ .set_tx_power = mtk_p2p_cfg80211_set_txpower, -+ .get_tx_power = mtk_p2p_cfg80211_get_txpower, -+ .set_power_mgmt = mtk_p2p_cfg80211_set_power_mgmt, -+#ifdef CONFIG_NL80211_TESTMODE -+ .testmode_cmd = mtk_p2p_cfg80211_testmode_cmd, -+#endif -+}; -+ -+static const struct wiphy_vendor_command mtk_p2p_vendor_ops[] = { -+ { -+ { -+ .vendor_id = GOOGLE_OUI, -+ .subcmd = WIFI_SUBCMD_GET_CHANNEL_LIST -+ }, -+ .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, -+ .doit = mtk_cfg80211_vendor_get_channel_list -+ }, -+ { -+ { -+ .vendor_id = GOOGLE_OUI, -+ .subcmd = WIFI_SUBCMD_SET_COUNTRY_CODE -+ }, -+ .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, -+ .doit = mtk_cfg80211_vendor_set_country_code -+ }, -+}; -+ -+/* There isn't a lot of sense in it, but you can transmit anything you like */ -+static const struct ieee80211_txrx_stypes -+ mtk_cfg80211_default_mgmt_stypes[NUM_NL80211_IFTYPES] = { -+ [NL80211_IFTYPE_ADHOC] = { -+ .tx = 0xffff, -+ .rx = BIT(IEEE80211_STYPE_ACTION >> 4) -+ }, -+ [NL80211_IFTYPE_STATION] = { -+ .tx = 0xffff, -+ .rx = BIT(IEEE80211_STYPE_ACTION >> 4) | BIT(IEEE80211_STYPE_PROBE_REQ >> 4) -+ }, -+ [NL80211_IFTYPE_AP] = { -+ .tx = 0xffff, -+ .rx = BIT(IEEE80211_STYPE_PROBE_REQ >> 4) | BIT(IEEE80211_STYPE_ACTION >> 4) -+ }, -+ [NL80211_IFTYPE_AP_VLAN] = { -+ /* copy AP */ -+ .tx = 0xffff, -+ .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) | -+ BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) | -+ BIT(IEEE80211_STYPE_PROBE_REQ >> 4) | -+ BIT(IEEE80211_STYPE_DISASSOC >> 4) | -+ BIT(IEEE80211_STYPE_AUTH >> 4) | -+ BIT(IEEE80211_STYPE_DEAUTH >> 4) | BIT(IEEE80211_STYPE_ACTION >> 4) -+ }, -+ [NL80211_IFTYPE_P2P_CLIENT] = { -+ .tx = 0xffff, -+ .rx = BIT(IEEE80211_STYPE_ACTION >> 4) | BIT(IEEE80211_STYPE_PROBE_REQ >> 4) -+ }, -+ [NL80211_IFTYPE_P2P_GO] = { -+ .tx = 0xffff, -+ .rx = BIT(IEEE80211_STYPE_PROBE_REQ >> 4) | BIT(IEEE80211_STYPE_ACTION >> 4) -+ } -+}; -+ -+#endif -+ -+/* the legacy wireless extension stuff */ -+static const iw_handler rP2PIwStandardHandler[] = { -+ [SIOCGIWPRIV - SIOCIWFIRST] = mtk_p2p_wext_get_priv, -+ [SIOCGIWSCAN - SIOCIWFIRST] = mtk_p2p_wext_discovery_results, -+ [SIOCSIWESSID - SIOCIWFIRST] = mtk_p2p_wext_reconnect, -+ [SIOCSIWAUTH - SIOCIWFIRST] = mtk_p2p_wext_set_auth, -+ [SIOCSIWENCODEEXT - SIOCIWFIRST] = mtk_p2p_wext_set_key, -+ [SIOCSIWPOWER - SIOCIWFIRST] = mtk_p2p_wext_set_powermode, -+ [SIOCGIWPOWER - SIOCIWFIRST] = mtk_p2p_wext_get_powermode, -+ [SIOCSIWTXPOW - SIOCIWFIRST] = mtk_p2p_wext_set_txpow, -+#if CFG_SUPPORT_P2P_RSSI_QUERY -+ [SIOCGIWSTATS - SIOCIWFIRST] = mtk_p2p_wext_get_rssi, -+#endif -+ [SIOCSIWMLME - SIOCIWFIRST] = mtk_p2p_wext_mlme_handler, -+}; -+ -+static const iw_handler rP2PIwPrivHandler[] = { -+ [IOC_P2P_CFG_DEVICE - SIOCIWFIRSTPRIV] = mtk_p2p_wext_set_local_dev_info, -+ [IOC_P2P_PROVISION_COMPLETE - SIOCIWFIRSTPRIV] = mtk_p2p_wext_set_provision_complete, -+ [IOC_P2P_START_STOP_DISCOVERY - SIOCIWFIRSTPRIV] = mtk_p2p_wext_start_stop_discovery, -+ [IOC_P2P_DISCOVERY_RESULTS - SIOCIWFIRSTPRIV] = mtk_p2p_wext_discovery_results, -+ [IOC_P2P_WSC_BEACON_PROBE_RSP_IE - SIOCIWFIRSTPRIV] = mtk_p2p_wext_wsc_ie, -+ [IOC_P2P_CONNECT_DISCONNECT - SIOCIWFIRSTPRIV] = mtk_p2p_wext_connect_disconnect, -+ [IOC_P2P_PASSWORD_READY - SIOCIWFIRSTPRIV] = mtk_p2p_wext_password_ready, -+/* [IOC_P2P_SET_PWR_MGMT_PARAM - SIOCIWFIRSTPRIV] = mtk_p2p_wext_set_pm_param, */ -+ [IOC_P2P_SET_INT - SIOCIWFIRSTPRIV] = mtk_p2p_wext_set_int, -+ [IOC_P2P_GET_STRUCT - SIOCIWFIRSTPRIV] = mtk_p2p_wext_get_struct, -+ [IOC_P2P_SET_STRUCT - SIOCIWFIRSTPRIV] = mtk_p2p_wext_set_struct, -+ [IOC_P2P_GET_REQ_DEVICE_INFO - SIOCIWFIRSTPRIV] = mtk_p2p_wext_request_dev_info, -+}; -+ -+static const struct iw_priv_args rP2PIwPrivTable[] = { -+ { -+ .cmd = IOC_P2P_CFG_DEVICE, -+ .set_args = IW_PRIV_TYPE_BYTE | (__u16) sizeof(IW_P2P_CFG_DEVICE_TYPE), -+ .get_args = IW_PRIV_TYPE_NONE, -+ .name = "P2P_CFG_DEVICE"} -+ , -+ { -+ .cmd = IOC_P2P_START_STOP_DISCOVERY, -+ .set_args = IW_PRIV_TYPE_BYTE | (__u16) sizeof(IW_P2P_REQ_DEVICE_TYPE), -+ .get_args = IW_PRIV_TYPE_NONE, -+ .name = "P2P_DISCOVERY"} -+ , -+ { -+ .cmd = IOC_P2P_DISCOVERY_RESULTS, -+ .set_args = IW_PRIV_TYPE_NONE, -+ .get_args = IW_PRIV_TYPE_NONE, -+ .name = "P2P_RESULT"} -+ , -+ { -+ .cmd = IOC_P2P_WSC_BEACON_PROBE_RSP_IE, -+ .set_args = IW_PRIV_TYPE_BYTE | (__u16) sizeof(IW_P2P_HOSTAPD_PARAM), -+ .get_args = IW_PRIV_TYPE_NONE, -+ .name = "P2P_WSC_IE"} -+ , -+ { -+ .cmd = IOC_P2P_CONNECT_DISCONNECT, -+ .set_args = IW_PRIV_TYPE_BYTE | (__u16) sizeof(IW_P2P_CONNECT_DEVICE), -+ .get_args = IW_PRIV_TYPE_NONE, -+ .name = "P2P_CONNECT"} -+ , -+ { -+ .cmd = IOC_P2P_PASSWORD_READY, -+ .set_args = IW_PRIV_TYPE_BYTE | (__u16) sizeof(IW_P2P_PASSWORD_READY), -+ .get_args = IW_PRIV_TYPE_NONE, -+ .name = "P2P_PASSWD_RDY"} -+ , -+ { -+ .cmd = IOC_P2P_GET_STRUCT, -+ .set_args = IW_PRIV_TYPE_NONE, -+ .get_args = 256, -+ .name = "P2P_GET_STRUCT"} -+ , -+ { -+ .cmd = IOC_P2P_SET_STRUCT, -+ .set_args = 256, -+ .get_args = IW_PRIV_TYPE_NONE, -+ .name = "P2P_SET_STRUCT"} -+ , -+ { -+ .cmd = IOC_P2P_GET_REQ_DEVICE_INFO, -+ .set_args = IW_PRIV_TYPE_NONE, -+ .get_args = IW_PRIV_TYPE_BYTE | (__u16) sizeof(IW_P2P_DEVICE_REQ), -+ .name = "P2P_GET_REQDEV"} -+ , -+ { -+ /* SET STRUCT sub-ioctls commands */ -+ .cmd = PRIV_CMD_OID, -+ .set_args = 256, -+ .get_args = IW_PRIV_TYPE_NONE, -+ .name = "set_oid"} -+ , -+ { -+ /* GET STRUCT sub-ioctls commands */ -+ .cmd = PRIV_CMD_OID, -+ .set_args = IW_PRIV_TYPE_NONE, -+ .get_args = 256, -+ .name = "get_oid"} -+}; -+ -+const struct iw_handler_def mtk_p2p_wext_handler_def = { -+ .num_standard = (__u16) sizeof(rP2PIwStandardHandler) / sizeof(iw_handler), -+ .num_private = (__u16) sizeof(rP2PIwPrivHandler) / sizeof(iw_handler), -+ .num_private_args = (__u16) sizeof(rP2PIwPrivTable) / sizeof(struct iw_priv_args), -+ .standard = rP2PIwStandardHandler, -+ .private = rP2PIwPrivHandler, -+ .private_args = rP2PIwPrivTable, -+#if CFG_SUPPORT_P2P_RSSI_QUERY -+ .get_wireless_stats = mtk_p2p_wext_get_wireless_stats, -+#else -+ .get_wireless_stats = NULL, -+#endif -+}; -+ -+#ifdef CONFIG_PM -+static const struct wiphy_wowlan_support p2p_wowlan_support = { -+ .flags = WIPHY_WOWLAN_DISCONNECT | WIPHY_WOWLAN_ANY, -+}; -+#endif -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+/* for IE Searching */ -+extern BOOLEAN -+wextSrchDesiredWPAIE(IN PUINT_8 pucIEStart, -+ IN INT_32 i4TotalIeLen, IN UINT_8 ucDesiredElemId, OUT PUINT_8 *ppucDesiredIE); -+ -+#if CFG_SUPPORT_WPS -+extern BOOLEAN -+wextSrchDesiredWPSIE(IN PUINT_8 pucIEStart, -+ IN INT_32 i4TotalIeLen, IN UINT_8 ucDesiredElemId, OUT PUINT_8 *ppucDesiredIE); -+#endif -+ -+/* Net Device Hooks */ -+static int p2pOpen(IN struct net_device *prDev); -+ -+static int p2pStop(IN struct net_device *prDev); -+ -+static struct net_device_stats *p2pGetStats(IN struct net_device *prDev); -+ -+static void p2pSetMulticastList(IN struct net_device *prDev); -+ -+static int p2pHardStartXmit(IN struct sk_buff *prSkb, IN struct net_device *prDev); -+ -+static int p2pDoIOCTL(struct net_device *prDev, struct ifreq *prIfReq, int i4Cmd); -+ -+static int p2pSetMACAddress(IN struct net_device *prDev, void *addr); -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Override the implementation of select queue -+* -+* \param[in] dev Pointer to struct net_device -+* \param[in] skb Pointer to struct skb_buff -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+ -+unsigned int _p2p_cfg80211_classify8021d(struct sk_buff *skb) -+{ -+ unsigned int dscp = 0; -+ -+ /* skb->priority values from 256->263 are magic values -+ * directly indicate a specific 802.1d priority. This is -+ * to allow 802.1d priority to be passed directly in from -+ * tags -+ */ -+ -+ if (skb->priority >= 256 && skb->priority <= 263) -+ return skb->priority - 256; -+ switch (skb->protocol) { -+ case htons(ETH_P_IP): -+ dscp = ip_hdr(skb)->tos & 0xfc; -+ break; -+ } -+ return dscp >> 5; -+} -+ -+static const UINT_16 au16Wlan1dToQueueIdx[8] = { 1, 0, 0, 1, 2, 2, 3, 3 }; -+ -+static UINT_16 p2pSelectQueue(struct net_device *dev, struct sk_buff *skb, -+ void *accel_priv, select_queue_fallback_t fallback) -+{ -+ skb->priority = _p2p_cfg80211_classify8021d(skb); -+ -+ return au16Wlan1dToQueueIdx[skb->priority]; -+} -+ -+static struct net_device *g_P2pPrDev; -+static struct wireless_dev *gprP2pWdev; -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief A function for prDev->init -+* -+* \param[in] prDev Pointer to struct net_device. -+* -+* \retval 0 The execution of wlanInit succeeds. -+* \retval -ENXIO No such device. -+*/ -+/*----------------------------------------------------------------------------*/ -+static int p2pInit(struct net_device *prDev) -+{ -+/* P_GLUE_INFO_T prGlueInfo; */ -+ if (!prDev) -+ return -ENXIO; -+ -+ DBGLOG(P2P, INFO, "dev name=%s\n", prDev->name); -+ return 0; /* success */ -+} /* end of p2pInit() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief A function for prDev->uninit -+* -+* \param[in] prDev Pointer to struct net_device. -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+static void p2pUninit(IN struct net_device *prDev) -+{ -+ -+} /* end of p2pUninit() */ -+ -+static const struct net_device_ops p2p_netdev_ops = { -+ .ndo_open = p2pOpen, -+ .ndo_stop = p2pStop, -+ .ndo_set_mac_address = p2pSetMACAddress, -+ .ndo_set_rx_mode = p2pSetMulticastList, -+ .ndo_get_stats = p2pGetStats, -+ .ndo_do_ioctl = p2pDoIOCTL, -+ .ndo_start_xmit = p2pHardStartXmit, -+ .ndo_select_queue = p2pSelectQueue, -+ .ndo_init = p2pInit, -+ .ndo_uninit = p2pUninit, -+}; -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Allocate memory for P2P_INFO, GL_P2P_INFO, P2P_CONNECTION_SETTINGS -+* P2P_SPECIFIC_BSS_INFO, P2P_FSM_INFO -+* -+* \param[in] prGlueInfo Pointer to glue info -+* -+* \return TRUE -+* FALSE -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN p2PAllocInfo(IN P_GLUE_INFO_T prGlueInfo) -+{ -+ P_ADAPTER_T prAdapter = NULL; -+ P_WIFI_VAR_T prWifiVar = NULL; -+ -+ if ((!prGlueInfo) || (!prGlueInfo->prAdapter)) { -+ ASSERT(FALSE); -+ return FALSE; -+ } -+ -+ prAdapter = prGlueInfo->prAdapter; -+ prWifiVar = &(prAdapter->rWifiVar); -+ -+ if (!prWifiVar) { -+ ASSERT(FALSE); -+ return FALSE; -+ } -+ -+ do { -+ if (prGlueInfo->prP2PInfo == NULL) { -+ /*alloc memory for p2p info */ -+ prGlueInfo->prP2PInfo = kalMemAlloc(sizeof(GL_P2P_INFO_T), VIR_MEM_TYPE); -+ prAdapter->prP2pInfo = kalMemAlloc(sizeof(P2P_INFO_T), VIR_MEM_TYPE); -+ prWifiVar->prP2PConnSettings = kalMemAlloc(sizeof(P2P_CONNECTION_SETTINGS_T), VIR_MEM_TYPE); -+ prWifiVar->prP2pFsmInfo = kalMemAlloc(sizeof(P2P_FSM_INFO_T), VIR_MEM_TYPE); -+ prWifiVar->prP2pSpecificBssInfo = kalMemAlloc(sizeof(P2P_SPECIFIC_BSS_INFO_T), VIR_MEM_TYPE); -+ } else { -+ ASSERT(prAdapter->prP2pInfo != NULL); -+ ASSERT(prWifiVar->prP2PConnSettings != NULL); -+ ASSERT(prWifiVar->prP2pFsmInfo != NULL); -+ ASSERT(prWifiVar->prP2pSpecificBssInfo != NULL); -+ } -+ /*MUST set memory to 0 */ -+ if (prGlueInfo->prP2PInfo) -+ kalMemZero(prGlueInfo->prP2PInfo, sizeof(GL_P2P_INFO_T)); -+ if (prAdapter->prP2pInfo) -+ kalMemZero(prAdapter->prP2pInfo, sizeof(P2P_INFO_T)); -+ if (prWifiVar->prP2PConnSettings) -+ kalMemZero(prWifiVar->prP2PConnSettings, sizeof(P2P_CONNECTION_SETTINGS_T)); -+ if (prWifiVar->prP2pFsmInfo) -+ kalMemZero(prWifiVar->prP2pFsmInfo, sizeof(P2P_FSM_INFO_T)); -+ if (prWifiVar->prP2pSpecificBssInfo) -+ kalMemZero(prWifiVar->prP2pSpecificBssInfo, sizeof(P2P_SPECIFIC_BSS_INFO_T)); -+ -+ } while (FALSE); -+ -+ /* chk if alloc successful or not */ -+ if (prGlueInfo->prP2PInfo && -+ prAdapter->prP2pInfo && -+ prWifiVar->prP2PConnSettings && prWifiVar->prP2pFsmInfo && prWifiVar->prP2pSpecificBssInfo) { -+ return TRUE; -+ } -+ -+ if (prWifiVar->prP2pSpecificBssInfo) { -+ kalMemFree(prWifiVar->prP2pSpecificBssInfo, VIR_MEM_TYPE, sizeof(P2P_SPECIFIC_BSS_INFO_T)); -+ -+ prWifiVar->prP2pSpecificBssInfo = NULL; -+ } -+ if (prWifiVar->prP2pFsmInfo) { -+ kalMemFree(prWifiVar->prP2pFsmInfo, VIR_MEM_TYPE, sizeof(P2P_FSM_INFO_T)); -+ -+ prWifiVar->prP2pFsmInfo = NULL; -+ } -+ if (prWifiVar->prP2PConnSettings) { -+ kalMemFree(prWifiVar->prP2PConnSettings, VIR_MEM_TYPE, sizeof(P2P_CONNECTION_SETTINGS_T)); -+ -+ prWifiVar->prP2PConnSettings = NULL; -+ } -+ if (prGlueInfo->prP2PInfo) { -+ kalMemFree(prGlueInfo->prP2PInfo, VIR_MEM_TYPE, sizeof(GL_P2P_INFO_T)); -+ -+ prGlueInfo->prP2PInfo = NULL; -+ } -+ if (prAdapter->prP2pInfo) { -+ kalMemFree(prAdapter->prP2pInfo, VIR_MEM_TYPE, sizeof(P2P_INFO_T)); -+ -+ prAdapter->prP2pInfo = NULL; -+ } -+ return FALSE; -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Free memory for P2P_INFO, GL_P2P_INFO, P2P_CONNECTION_SETTINGS -+* P2P_SPECIFIC_BSS_INFO, P2P_FSM_INFO -+* -+* \param[in] prGlueInfo Pointer to glue info -+* -+* \return TRUE -+* FALSE -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN p2PFreeInfo(P_GLUE_INFO_T prGlueInfo) -+{ -+ -+ if ((!prGlueInfo) || (!prGlueInfo->prAdapter)) { -+ ASSERT(FALSE); -+ return FALSE; -+ } -+ -+ /* free memory after p2p module is ALREADY unregistered */ -+ if (prGlueInfo->prAdapter->fgIsP2PRegistered == FALSE) { -+ -+ kalMemFree(prGlueInfo->prAdapter->prP2pInfo, VIR_MEM_TYPE, sizeof(P2P_INFO_T)); -+ kalMemFree(prGlueInfo->prP2PInfo, VIR_MEM_TYPE, sizeof(GL_P2P_INFO_T)); -+ kalMemFree(prGlueInfo->prAdapter->rWifiVar.prP2PConnSettings, VIR_MEM_TYPE, -+ sizeof(P2P_CONNECTION_SETTINGS_T)); -+ kalMemFree(prGlueInfo->prAdapter->rWifiVar.prP2pFsmInfo, VIR_MEM_TYPE, sizeof(P2P_FSM_INFO_T)); -+ kalMemFree(prGlueInfo->prAdapter->rWifiVar.prP2pSpecificBssInfo, VIR_MEM_TYPE, -+ sizeof(P2P_SPECIFIC_BSS_INFO_T)); -+ -+ /*Reomve p2p bss scan list */ -+ scanRemoveAllP2pBssDesc(prGlueInfo->prAdapter); -+ -+ /*reset all pointer to NULL */ -+ prGlueInfo->prP2PInfo = NULL; -+ prGlueInfo->prAdapter->prP2pInfo = NULL; -+ prGlueInfo->prAdapter->rWifiVar.prP2PConnSettings = NULL; -+ prGlueInfo->prAdapter->rWifiVar.prP2pFsmInfo = NULL; -+ prGlueInfo->prAdapter->rWifiVar.prP2pSpecificBssInfo = NULL; -+ -+ return TRUE; -+ } else { -+ return FALSE; -+ } -+ -+} -+ -+#if !CFG_SUPPORT_PERSIST_NETDEV -+BOOLEAN p2pNetRegister(P_GLUE_INFO_T prGlueInfo, BOOLEAN fgIsRtnlLockAcquired) -+{ -+ BOOLEAN fgDoRegister = FALSE; -+/* BOOLEAN fgRollbackRtnlLock = FALSE; */ -+ BOOLEAN ret; -+ -+ GLUE_SPIN_LOCK_DECLARATION(); -+ -+ if ((!prGlueInfo) || (!prGlueInfo->prAdapter)) { -+ ASSERT(FALSE); -+ return FALSE; -+ } -+ -+ GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV); -+ if (prGlueInfo->prAdapter->rP2PNetRegState == ENUM_NET_REG_STATE_UNREGISTERED) { -+ prGlueInfo->prAdapter->rP2PNetRegState = ENUM_NET_REG_STATE_REGISTERING; -+ fgDoRegister = TRUE; -+ } -+ GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV); -+ -+ if (!fgDoRegister) -+ return TRUE; -+ -+ /* net device initialize */ -+ netif_carrier_off(prGlueInfo->prP2PInfo->prDevHandler); -+ netif_tx_stop_all_queues(prGlueInfo->prP2PInfo->prDevHandler); -+ -+ /* register for net device */ -+ if (register_netdev(prGlueInfo->prP2PInfo->prDevHandler) < 0) { -+ DBGLOG(P2P, WARN, "unable to register netdevice for p2p\n"); -+ -+ free_netdev(prGlueInfo->prP2PInfo->prDevHandler); -+ -+ ret = FALSE; -+ } else { -+ prGlueInfo->prAdapter->rP2PNetRegState = ENUM_NET_REG_STATE_REGISTERED; -+ ret = TRUE; -+ } -+ return ret; -+} -+ -+BOOLEAN p2pNetUnregister(P_GLUE_INFO_T prGlueInfo, BOOLEAN fgIsRtnlLockAcquired) -+{ -+ BOOLEAN fgDoUnregister = FALSE; -+/* BOOLEAN fgRollbackRtnlLock = FALSE; */ -+ GLUE_SPIN_LOCK_DECLARATION(); -+ -+ if ((!prGlueInfo) || (!prGlueInfo->prAdapter)) { -+ ASSERT(FALSE); -+ return FALSE; -+ } -+ -+ GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV); -+ if (prGlueInfo->prAdapter->rP2PNetRegState == ENUM_NET_REG_STATE_REGISTERED) { -+ prGlueInfo->prAdapter->rP2PNetRegState = ENUM_NET_REG_STATE_UNREGISTERING; -+ fgDoUnregister = TRUE; -+ } -+ GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV); -+ -+ if (!fgDoUnregister) -+ return TRUE; -+ -+ /* prepare for removal */ -+ if (netif_carrier_ok(prGlueInfo->prP2PInfo->prDevHandler)) -+ netif_carrier_off(prGlueInfo->prP2PInfo->prDevHandler); -+ -+ netif_tx_stop_all_queues(prGlueInfo->prP2PInfo->prDevHandler); -+ DBGLOG(P2P, INFO, "P2P unregister_netdev 0x%p\n", prGlueInfo->prP2PInfo->prDevHandler); -+ unregister_netdev(prGlueInfo->prP2PInfo->prDevHandler); -+ -+ prGlueInfo->prAdapter->rP2PNetRegState = ENUM_NET_REG_STATE_UNREGISTERED; -+ -+ return TRUE; -+} -+#endif -+ -+BOOLEAN glP2pCreateWirelessDevice(P_GLUE_INFO_T prGlueInfo) -+{ -+ struct wiphy *prWiphy = NULL; -+ struct wireless_dev *prWdev = NULL; -+#if CFG_SUPPORT_PERSIST_NETDEV -+ struct net_device *prNetDev = NULL; -+#endif -+#if CFG_ENABLE_WIFI_DIRECT_CFG_80211 -+ prWdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL); -+ if (!prWdev) { -+ DBGLOG(P2P, ERROR, "allocate p2p wireless device fail, no memory\n"); -+ return FALSE; -+ } -+ /* 1. allocate WIPHY */ -+ prWiphy = wiphy_new(&mtk_p2p_ops, sizeof(P_GLUE_INFO_T)); -+ if (!prWiphy) { -+ DBGLOG(P2P, ERROR, "unable to allocate wiphy for p2p\n"); -+ goto free_wdev; -+ } -+ -+ prWiphy->interface_modes = BIT(NL80211_IFTYPE_AP) | BIT(NL80211_IFTYPE_P2P_CLIENT) | -+ BIT(NL80211_IFTYPE_P2P_GO) | BIT(NL80211_IFTYPE_STATION); -+ -+ prWiphy->bands[NL80211_BAND_2GHZ] = &mtk_band_2ghz; -+ prWiphy->bands[NL80211_BAND_5GHZ] = &mtk_band_5ghz; -+ -+ prWiphy->mgmt_stypes = mtk_cfg80211_default_mgmt_stypes; -+ prWiphy->max_remain_on_channel_duration = 5000; -+ prWiphy->cipher_suites = mtk_cipher_suites; -+ prWiphy->n_cipher_suites = ARRAY_SIZE(mtk_cipher_suites); -+ prWiphy->flags = WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL | WIPHY_FLAG_HAVE_AP_SME; -+ prWiphy->regulatory_flags = REGULATORY_CUSTOM_REG; -+ prWiphy->ap_sme_capa = 1; -+ -+ prWiphy->max_scan_ssids = MAX_SCAN_LIST_NUM; -+ prWiphy->max_scan_ie_len = MAX_SCAN_IE_LEN; -+ prWiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM; -+ prWiphy->vendor_commands = mtk_p2p_vendor_ops; -+ prWiphy->n_vendor_commands = sizeof(mtk_p2p_vendor_ops) / sizeof(struct wiphy_vendor_command); -+ -+#ifdef CONFIG_PM -+ prWiphy->wowlan = &p2p_wowlan_support; -+#endif -+ -+ /* 2.1 set priv as pointer to glue structure */ -+ *((P_GLUE_INFO_T *) wiphy_priv(prWiphy)) = prGlueInfo; -+ if (wiphy_register(prWiphy) < 0) { -+ DBGLOG(P2P, ERROR, "fail to register wiphy for p2p\n"); -+ goto free_wiphy; -+ } -+ prWdev->wiphy = prWiphy; -+#if CFG_SUPPORT_PERSIST_NETDEV -+ /* 3. allocate netdev */ -+ prNetDev = alloc_netdev_mq(sizeof(P_GLUE_INFO_T), P2P_MODE_INF_NAME, NET_NAME_PREDICTABLE, -+ ether_setup, CFG_MAX_TXQ_NUM); -+ if (!prNetDev) { -+ DBGLOG(P2P, ERROR, "unable to allocate netdevice for p2p\n"); -+ goto unregister_wiphy; -+ } -+ -+ /* 4. setup netdev */ -+ /* 4.1 Point to shared glue structure */ -+ *((P_GLUE_INFO_T *) netdev_priv(prNetDev)) = prGlueInfo; -+ -+ /* 4.2 fill hardware address */ -+ /* COPY_MAC_ADDR(rMacAddr, prAdapter->rMyMacAddr); -+ rMacAddr[0] ^= 0x2; // change to local administrated address -+ memcpy(prGlueInfo->prP2PInfo->prDevHandler->dev_addr, rMacAddr, ETH_ALEN); -+ memcpy(prGlueInfo->prP2PInfo->prDevHandler->perm_addr, -+ prGlueInfo->prP2PInfo->prDevHandler->dev_addr, ETH_ALEN);*/ -+ -+ /* 4.3 register callback functions */ -+ prNetDev->netdev_ops = &p2p_netdev_ops; -+ /* prGlueInfo->prP2PInfo->prDevHandler->wireless_handlers = &mtk_p2p_wext_handler_def;*/ -+ -+ prNetDev->ieee80211_ptr = prWdev; -+ prWdev->netdev = prNetDev; -+ -+#if CFG_TCP_IP_CHKSUM_OFFLOAD -+ prNetDev->features = NETIF_F_IP_CSUM; -+#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */ -+ /* net device initialize */ -+ netif_carrier_off(prNetDev); -+ netif_tx_stop_all_queues(prNetDev); -+ -+ /* register for net device */ -+ if (register_netdev(prNetDev) < 0) { -+ DBGLOG(P2P, ERROR, "unable to register netdevice for p2p\n"); -+ free_netdev(prNetDev); -+ goto unregister_wiphy; -+ } -+#endif -+ gprP2pWdev = prWdev; -+ return TRUE; -+ -+#if CFG_SUPPORT_PERSIST_NETDEV -+unregister_wiphy: -+ wiphy_unregister(prWiphy); -+#endif -+free_wiphy: -+ wiphy_free(prWiphy); -+free_wdev: -+ kfree(prWdev); -+#endif -+ return FALSE; -+} -+ -+void glP2pDestroyWirelessDevice(VOID) -+{ -+#if CFG_ENABLE_WIFI_DIRECT_CFG_80211 -+#if CFG_SUPPORT_PERSIST_NETDEV -+ unregister_netdev(gprP2pWdev->netdev); -+ free_netdev(gprP2pWdev->netdev); -+#endif -+ wiphy_unregister(gprP2pWdev->wiphy); -+ wiphy_free(gprP2pWdev->wiphy); -+ kfree(gprP2pWdev); -+ gprP2pWdev = NULL; -+#endif -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Register for cfg80211 for Wi-Fi Direct -+* -+* \param[in] prGlueInfo Pointer to glue info -+* -+* \return TRUE -+* FALSE -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN glRegisterP2P(P_GLUE_INFO_T prGlueInfo, const char *prDevName, BOOLEAN fgIsApMode) -+{ -+ P_ADAPTER_T prAdapter = NULL; -+ P_GL_HIF_INFO_T prHif = NULL; -+ PARAM_MAC_ADDRESS rMacAddr; -+ struct net_device *prDevHandler = NULL; -+#if CFG_ENABLE_WIFI_DIRECT_CFG_80211 -+ struct device *prDev; -+#endif -+ -+ ASSERT(prGlueInfo); -+ -+ prAdapter = prGlueInfo->prAdapter; -+ ASSERT(prAdapter); -+ -+ prHif = &prGlueInfo->rHifInfo; -+ ASSERT(prHif); -+ -+ DBGLOG(P2P, TRACE, "glRegisterP2P\n"); -+#if CFG_ENABLE_WIFI_DIRECT_CFG_80211 -+ if (!gprP2pWdev) { -+ DBGLOG(P2P, ERROR, "gl_p2p, wireless device is not exist\n"); -+ return FALSE; -+ } -+#endif -+ /*0. allocate p2pinfo */ -+ if (!p2PAllocInfo(prGlueInfo)) { -+ DBGLOG(P2P, ERROR, "Allocate memory for p2p FAILED\n"); -+ ASSERT(0); -+ return FALSE; -+ } -+#if CFG_ENABLE_WIFI_DIRECT_CFG_80211 -+ prGlueInfo->prP2PInfo->prWdev = gprP2pWdev; -+ /* 1. fill wiphy parameters */ -+#if MTK_WCN_HIF_SDIO -+ mtk_wcn_hif_sdio_get_dev(prHif->cltCtx, &prDev); -+ if (!prDev) -+ DBGLOG(P2P, WARN, "unable to get struct dev for p2p\n"); -+#else -+ prDev = prHif->Dev; -+#endif -+ /*set_wiphy_dev(gprP2pWdev->wiphy, prDev);*/ -+ if (!prGlueInfo->prAdapter->fgEnable5GBand) -+ gprP2pWdev->wiphy->bands[NL80211_BAND_5GHZ] = NULL; -+ -+ /* 2 set priv as pointer to glue structure */ -+ *(P_GLUE_INFO_T *) wiphy_priv(gprP2pWdev->wiphy) = prGlueInfo; -+ -+ if (fgIsApMode) { -+ gprP2pWdev->iftype = NL80211_IFTYPE_AP; -+#if CFG_SUPPORT_PERSIST_NETDEV -+ if (kalStrnCmp(gprP2pWdev->netdev->name, AP_MODE_INF_NAME, 2)) { -+ rtnl_lock(); -+ dev_change_name(gprP2pWdev->netdev->name, AP_MODE_INF_NAME); -+ rtnl_unlock(); -+ } -+#endif -+ } else { -+#if CFG_SUPPORT_PERSIST_NETDEV -+ if (kalStrnCmp(gprP2pWdev->netdev->name, P2P_MODE_INF_NAME, 3)) { -+ rtnl_lock(); -+ dev_change_name(gprP2pWdev->netdev->name, P2P_MODE_INF_NAME); -+ rtnl_unlock(); -+ } -+#endif -+ gprP2pWdev->iftype = NL80211_IFTYPE_P2P_CLIENT; -+ } -+#endif /* CFG_ENABLE_WIFI_DIRECT_CFG_80211 */ -+ -+#if CFG_SUPPORT_PERSIST_NETDEV -+ prP2PInfo->prDevHandler = gprP2pWdev->netdev; -+#else /* CFG_SUPPORT_PERSIST_NETDEV */ -+ /* 3. allocate netdev */ -+ prDevHandler = -+ alloc_netdev_mq(sizeof(P_GLUE_INFO_T), prDevName, NET_NAME_PREDICTABLE, ether_setup, CFG_MAX_TXQ_NUM); -+ if (!prDevHandler) { -+ DBGLOG(P2P, ERROR, "unable to allocate netdevice for p2p\n"); -+ return FALSE; -+ } -+ prGlueInfo->prP2PInfo->prDevHandler = prDevHandler; -+ /* 4. setup netdev */ -+ /* 4.1 Point to shared glue structure */ -+ *((P_GLUE_INFO_T *) netdev_priv(prDevHandler)) = prGlueInfo; -+ -+ /* 4.2 fill hardware address */ -+ COPY_MAC_ADDR(rMacAddr, prAdapter->rMyMacAddr); -+ rMacAddr[0] ^= 0x2; /* change to local administrated address */ -+ ether_addr_copy(prDevHandler->dev_addr, rMacAddr); -+ ether_addr_copy(prDevHandler->perm_addr, prDevHandler->dev_addr); -+ -+ /* 4.3 register callback functions */ -+ prDevHandler->netdev_ops = &p2p_netdev_ops; -+ /* prGlueInfo->prP2PInfo->prDevHandler->wireless_handlers = &mtk_p2p_wext_handler_def; */ -+ -+#if (MTK_WCN_HIF_SDIO == 0) -+ SET_NETDEV_DEV(prDevHandler, prHif->Dev); -+#endif -+ -+#if CFG_ENABLE_WIFI_DIRECT_CFG_80211 -+ prDevHandler->ieee80211_ptr = gprP2pWdev; -+ gprP2pWdev->netdev = prDevHandler; -+#endif -+ -+#if CFG_TCP_IP_CHKSUM_OFFLOAD -+ prDevHandler->features = NETIF_F_IP_CSUM; -+#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */ -+#endif /* CFG_SUPPORT_PERSIST_NETDEV */ -+ -+ /* 5. set p2p net device register state */ -+ prAdapter->rP2PNetRegState = ENUM_NET_REG_STATE_UNREGISTERED; -+ -+ /* 6. setup running mode */ -+ prAdapter->rWifiVar.prP2pFsmInfo->fgIsApMode = fgIsApMode; -+ -+ /* 7. finish */ -+ p2pFsmInit(prAdapter); -+ -+ p2pFuncInitConnectionSettings(prAdapter, prAdapter->rWifiVar.prP2PConnSettings); -+ -+ /* Active network too early would cause HW not able to sleep. -+ * Defer the network active time. -+ */ -+/* nicActivateNetwork(prAdapter, NETWORK_TYPE_P2P_INDEX); */ -+ -+ return TRUE; -+} /* end of glRegisterP2P() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Unregister Net Device for Wi-Fi Direct -+* -+* \param[in] prGlueInfo Pointer to glue info -+* -+* \return TRUE -+* FALSE -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN glUnregisterP2P(P_GLUE_INFO_T prGlueInfo) -+{ -+ ASSERT(prGlueInfo); -+ /* normal flow: this func will called first before wlanRemove, and it can do fsmUninit/deactivateNetwork -+ gracefully. */ -+ /* when reset: because tx_thread with fw has stopped, so it can't do these job and the recovery will be -+ dependent on chip system reset. */ -+ /* if so, just skip it by flag GLUE_FLAG_HALT(warning: when tx_thread was stop, this flag was not cleared, -+ and NEED TO KEEP IT NOT CLEARED!). */ -+ if (!(prGlueInfo->ulFlag & GLUE_FLAG_HALT)) { -+ p2pFsmUninit(prGlueInfo->prAdapter); -+ nicDeactivateNetwork(prGlueInfo->prAdapter, NETWORK_TYPE_P2P_INDEX); -+ } -+#if CFG_SUPPORT_PERSIST_NETDEV -+ dev_close(prGlueInfo->prP2PInfo->prDevHandler); -+#else -+ free_netdev(prGlueInfo->prP2PInfo->prDevHandler); -+ prGlueInfo->prP2PInfo->prDevHandler = NULL; -+#endif -+ /* Free p2p memory */ -+ if (!p2PFreeInfo(prGlueInfo)) { -+ DBGLOG(P2P, ERROR, "Free memory for p2p FAILED\n"); -+ ASSERT(0); -+ return FALSE; -+ } -+ return TRUE; -+} /* end of glUnregisterP2P() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * \brief A function for stop p2p fsm immediate -+ * -+ * \param[in] prGlueInfo Pointer to struct P_GLUE_INFO_T. -+ * -+ * \retval TRUE The execution succeeds. -+ * \retval FALSE The execution failed. -+ */ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN p2pStopImmediate(P_GLUE_INFO_T prGlueInfo) -+{ -+/* P_ADAPTER_T prAdapter = NULL; */ -+/* P_MSG_P2P_FUNCTION_SWITCH_T prFuncSwitch; */ -+ -+ ASSERT(prGlueInfo); -+ -+/* prAdapter = prGlueInfo->prAdapter; */ -+/* ASSERT(prAdapter); */ -+ -+ /* 1. stop TX queue */ -+ netif_tx_stop_all_queues(prGlueInfo->prP2PInfo->prDevHandler); -+ -+#if 0 -+ /* 2. switch P2P-FSM off */ -+ /* 2.1 allocate for message */ -+ prFuncSwitch = (P_MSG_P2P_FUNCTION_SWITCH_T) cnmMemAlloc(prAdapter, -+ RAM_TYPE_MSG, sizeof(MSG_P2P_FUNCTION_SWITCH_T)); -+ -+ if (!prFuncSwitch) { -+ ASSERT(0); /* Can't trigger P2P FSM */ -+ DBGLOG(P2P, ERROR, "Allocate for p2p mesasage FAILED\n"); -+ /* return -ENOMEM; */ -+ } -+ -+ /* 2.2 fill message */ -+ prFuncSwitch->rMsgHdr.eMsgId = MID_MNY_P2P_FUN_SWITCH; -+ prFuncSwitch->fgIsFuncOn = FALSE; -+ -+ /* 2.3 send message */ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prFuncSwitch, MSG_SEND_METHOD_UNBUF); -+ -+#endif -+ -+ /* 3. stop queue and turn off carrier */ -+ prGlueInfo->prP2PInfo->eState = PARAM_MEDIA_STATE_DISCONNECTED; -+ -+ return TRUE; -+} /* end of p2pStop() */ -+ -+/* Net Device Hooks */ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * \brief A function for net_device open (ifup) -+ * -+ * \param[in] prDev Pointer to struct net_device. -+ * -+ * \retval 0 The execution succeeds. -+ * \retval < 0 The execution failed. -+ */ -+/*----------------------------------------------------------------------------*/ -+static int p2pOpen(IN struct net_device *prDev) -+{ -+/* P_GLUE_INFO_T prGlueInfo = NULL; */ -+/* P_ADAPTER_T prAdapter = NULL; */ -+/* P_MSG_P2P_FUNCTION_SWITCH_T prFuncSwitch; */ -+ -+ ASSERT(prDev); -+ -+#if 0 /* Move after device name set. (mtk_p2p_set_local_dev_info) */ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ ASSERT(prGlueInfo); -+ -+ prAdapter = prGlueInfo->prAdapter; -+ ASSERT(prAdapter); -+ -+ /* 1. switch P2P-FSM on */ -+ /* 1.1 allocate for message */ -+ prFuncSwitch = (P_MSG_P2P_FUNCTION_SWITCH_T) cnmMemAlloc(prAdapter, -+ RAM_TYPE_MSG, sizeof(MSG_P2P_FUNCTION_SWITCH_T)); -+ -+ if (!prFuncSwitch) { -+ ASSERT(0); /* Can't trigger P2P FSM */ -+ return -ENOMEM; -+ } -+ -+ /* 1.2 fill message */ -+ prFuncSwitch->rMsgHdr.eMsgId = MID_MNY_P2P_FUN_SWITCH; -+ prFuncSwitch->fgIsFuncOn = TRUE; -+ -+ /* 1.3 send message */ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prFuncSwitch, MSG_SEND_METHOD_BUF); -+#endif -+ -+ /* 2. carrier on & start TX queue */ -+ netif_carrier_on(prDev); -+ netif_tx_start_all_queues(prDev); -+ -+ return 0; /* success */ -+} /* end of p2pOpen() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * \brief A function for net_device stop (ifdown) -+ * -+ * \param[in] prDev Pointer to struct net_device. -+ * -+ * \retval 0 The execution succeeds. -+ * \retval < 0 The execution failed. -+ */ -+/*----------------------------------------------------------------------------*/ -+static int p2pStop(IN struct net_device *prDev) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ /* P_ADAPTER_T prAdapter = NULL; */ -+/* P_MSG_P2P_FUNCTION_SWITCH_T prFuncSwitch; */ -+ P_GL_P2P_INFO_T prGlueP2pInfo = (P_GL_P2P_INFO_T) NULL; -+ -+ struct cfg80211_scan_info info = { -+ .aborted = true, -+ }; -+ -+ struct cfg80211_scan_request *prScanRequest = NULL; -+ -+ GLUE_SPIN_LOCK_DECLARATION(); -+ ASSERT(prDev); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ ASSERT(prGlueInfo); -+ -+ prGlueP2pInfo = prGlueInfo->prP2PInfo; -+ ASSERT(prGlueP2pInfo); -+ -+ /* CFG80211 down */ -+ GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV); -+ if (prGlueP2pInfo->prScanRequest != NULL) { -+ prScanRequest = prGlueP2pInfo->prScanRequest; -+ prGlueP2pInfo->prScanRequest = NULL; -+ } -+ GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV); -+ -+ if (prScanRequest) -+ cfg80211_scan_done(prScanRequest, &info); -+#if 0 -+ -+ /* 1. stop TX queue */ -+ netif_tx_stop_all_queues(prDev); -+ -+ /* 2. switch P2P-FSM off */ -+ /* 2.1 allocate for message */ -+ prFuncSwitch = (P_MSG_P2P_FUNCTION_SWITCH_T) cnmMemAlloc(prAdapter, -+ RAM_TYPE_MSG, sizeof(MSG_P2P_FUNCTION_SWITCH_T)); -+ -+ if (!prFuncSwitch) { -+ ASSERT(0); /* Can't trigger P2P FSM */ -+ return -ENOMEM; -+ } -+ -+ /* 2.2 fill message */ -+ prFuncSwitch->rMsgHdr.eMsgId = MID_MNY_P2P_FUN_SWITCH; -+ prFuncSwitch->fgIsFuncOn = FALSE; -+ -+ /* 2.3 send message */ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prFuncSwitch, MSG_SEND_METHOD_BUF); -+#endif -+ /* 3. stop queue and turn off carrier */ -+ prGlueInfo->prP2PInfo->eState = PARAM_MEDIA_STATE_DISCONNECTED; -+ -+ netif_tx_stop_all_queues(prDev); -+ if (netif_carrier_ok(prDev)) -+ netif_carrier_off(prDev); -+ -+ return 0; -+} /* end of p2pStop() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * \brief A method of struct net_device, to get the network interface statistical -+ * information. -+ * -+ * Whenever an application needs to get statistics for the interface, this method -+ * is called. This happens, for example, when ifconfig or netstat -i is run. -+ * -+ * \param[in] prDev Pointer to struct net_device. -+ * -+ * \return net_device_stats buffer pointer. -+ */ -+/*----------------------------------------------------------------------------*/ -+struct net_device_stats *p2pGetStats(IN struct net_device *prDev) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ -+ ASSERT(prDev); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ -+#if CFG_SUPPORT_PERSIST_NETDEV -+ /* @FIXME */ -+ /* prDev->stats.rx_packets = 0; */ -+ /* prDev->stats.tx_packets = 0; */ -+ prDev->stats.tx_errors = 0; -+ prDev->stats.rx_errors = 0; -+ /* prDev->stats.rx_bytes = 0; */ -+ /* prDev->stats.tx_bytes = 0; */ -+ prDev->stats.multicast = 0; -+ -+ return &prDev->stats; -+ -+#else -+ /* prGlueInfo->prP2PInfo->rNetDevStats.rx_packets = 0; */ -+ /* prGlueInfo->prP2PInfo->rNetDevStats.tx_packets = 0; */ -+ prGlueInfo->prP2PInfo->rNetDevStats.tx_errors = 0; -+ prGlueInfo->prP2PInfo->rNetDevStats.rx_errors = 0; -+ /* prGlueInfo->prP2PInfo->rNetDevStats.rx_bytes = 0; */ -+ /* prGlueInfo->prP2PInfo->rNetDevStats.tx_bytes = 0; */ -+ /* prGlueInfo->prP2PInfo->rNetDevStats.rx_errors = 0; */ -+ prGlueInfo->prP2PInfo->rNetDevStats.multicast = 0; -+ -+ return &prGlueInfo->prP2PInfo->rNetDevStats; -+#endif -+} /* end of p2pGetStats() */ -+ -+static void p2pSetMulticastList(IN struct net_device *prDev) -+{ -+ P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) NULL; -+ -+ prGlueInfo = (NULL != prDev) ? *((P_GLUE_INFO_T *) netdev_priv(prDev)) : NULL; -+ -+ ASSERT(prDev); -+ ASSERT(prGlueInfo); -+ if (!prDev || !prGlueInfo) { -+ DBGLOG(P2P, WARN, "abnormal dev or skb: prDev(0x%p), prGlueInfo(0x%p)\n", prDev, prGlueInfo); -+ return; -+ } -+ -+ g_P2pPrDev = prDev; -+ -+ /* 4 Mark HALT, notify main thread to finish current job */ -+/* prGlueInfo->u4Flag |= GLUE_FLAG_SUB_MOD_MULTICAST; */ -+ set_bit(GLUE_FLAG_SUB_MOD_MULTICAST_BIT, &prGlueInfo->ulFlag); -+ -+ /* wake up main thread */ -+ wake_up_interruptible(&prGlueInfo->waitq); -+ -+} /* p2pSetMulticastList */ -+ -+/* FIXME: Since we cannot sleep in the wlanSetMulticastList, we arrange -+ * another workqueue for sleeping. We don't want to block -+ * tx_thread, so we can't let tx_thread to do this */ -+ -+void p2pSetMulticastListWorkQueueWrapper(P_GLUE_INFO_T prGlueInfo) -+{ -+ if (!prGlueInfo) { -+ DBGLOG(INIT, ERROR, "prGlueInfo is NULL\n"); -+ return; -+ } -+#if CFG_ENABLE_WIFI_DIRECT -+ if (prGlueInfo->prAdapter->fgIsP2PRegistered) -+ mtk_p2p_wext_set_Multicastlist(prGlueInfo); -+#endif -+} /* end of p2pSetMulticastListWorkQueueWrapper() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * \brief This function is to set multicast list and set rx mode. -+ * -+ * \param[in] prDev Pointer to struct net_device -+ * -+ * \return (none) -+ */ -+/*----------------------------------------------------------------------------*/ -+void mtk_p2p_wext_set_Multicastlist(P_GLUE_INFO_T prGlueInfo) -+{ -+ UINT_32 u4SetInfoLen = 0; -+ struct net_device *prDev = g_P2pPrDev; -+ -+ prGlueInfo = (NULL != prDev) ? *((P_GLUE_INFO_T *) netdev_priv(prDev)) : NULL; -+ -+ ASSERT(prDev); -+ ASSERT(prGlueInfo); -+ if (!prDev || !prGlueInfo) { -+ DBGLOG(P2P, WARN, "abnormal dev or skb: prDev(0x%p), prGlueInfo(0x%p)\n", prDev, prGlueInfo); -+ return; -+ } -+ -+ if (prDev->flags & IFF_PROMISC) -+ prGlueInfo->prP2PInfo->u4PacketFilter |= PARAM_PACKET_FILTER_PROMISCUOUS; -+ -+ if (prDev->flags & IFF_BROADCAST) -+ prGlueInfo->prP2PInfo->u4PacketFilter |= PARAM_PACKET_FILTER_BROADCAST; -+ -+ if (prDev->flags & IFF_MULTICAST) { -+ if ((prDev->flags & IFF_ALLMULTI) || -+ (netdev_mc_count(prDev) > MAX_NUM_GROUP_ADDR)) { -+ prGlueInfo->prP2PInfo->u4PacketFilter |= PARAM_PACKET_FILTER_ALL_MULTICAST; -+ } else { -+ prGlueInfo->prP2PInfo->u4PacketFilter |= PARAM_PACKET_FILTER_MULTICAST; -+ } -+ } -+ -+ if (prGlueInfo->prP2PInfo->u4PacketFilter & PARAM_PACKET_FILTER_MULTICAST) { -+ /* Prepare multicast address list */ -+ struct netdev_hw_addr *ha; -+ UINT_32 i = 0; -+ -+ netdev_for_each_mc_addr(ha, prDev) { -+ if (i < MAX_NUM_GROUP_ADDR) { -+ COPY_MAC_ADDR(&(prGlueInfo->prP2PInfo->aucMCAddrList[i]), ha->addr); -+ i++; -+ } -+ } -+ -+ DBGLOG(P2P, TRACE, "SEt Multicast Address List\n"); -+ -+ if (i >= MAX_NUM_GROUP_ADDR) -+ return; -+ wlanoidSetP2PMulticastList(prGlueInfo->prAdapter, -+ &(prGlueInfo->prP2PInfo->aucMCAddrList[0]), (i * ETH_ALEN), &u4SetInfoLen); -+ -+ } -+ -+} /* end of mtk_p2p_wext_set_Multicastlist */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * * \brief This function is TX entry point of NET DEVICE. -+ * * -+ * * \param[in] prSkb Pointer of the sk_buff to be sent -+ * * \param[in] prDev Pointer to struct net_device -+ * * -+ * * \retval NETDEV_TX_OK - on success. -+ * * \retval NETDEV_TX_BUSY - on failure, packet will be discarded by upper layer. -+ * */ -+/*----------------------------------------------------------------------------*/ -+int p2pHardStartXmit(IN struct sk_buff *prSkb, IN struct net_device *prDev) -+{ -+ P_QUE_ENTRY_T prQueueEntry = NULL; -+ P_QUE_T prTxQueue = NULL; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ UINT_16 u2QueueIdx = 0; -+ -+ GLUE_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(prSkb); -+ ASSERT(prDev); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ prGlueInfo->u8SkbToDriver++; -+ -+ if (prGlueInfo->ulFlag & GLUE_FLAG_HALT) { -+ DBGLOG(P2P, ERROR, "GLUE_FLAG_HALT skip tx\n"); -+ prGlueInfo->u8SkbFreed++; -+ dev_kfree_skb(prSkb); -+ return NETDEV_TX_OK; -+ } -+#if (CFG_SUPPORT_MET_PROFILING == 1) -+ kalMetProfilingStart(prGlueInfo, prSkb); -+#endif -+ -+ /* mark as P2P packets */ -+ GLUE_SET_PKT_FLAG_P2P(prSkb); -+#if CFG_ENABLE_PKT_LIFETIME_PROFILE -+ GLUE_SET_PKT_ARRIVAL_TIME(prSkb, kalGetTimeTick()); -+#endif -+ -+ STATS_TX_TIME_ARRIVE(prSkb); -+ prQueueEntry = (P_QUE_ENTRY_T) GLUE_GET_PKT_QUEUE_ENTRY(prSkb); -+ prTxQueue = &prGlueInfo->rTxQueue; -+ -+ if (wlanProcessSecurityFrame(prGlueInfo->prAdapter, (P_NATIVE_PACKET) prSkb) == FALSE) { -+ -+ u2QueueIdx = skb_get_queue_mapping(prSkb); -+ ASSERT(u2QueueIdx < CFG_MAX_TXQ_NUM); -+ -+ if (u2QueueIdx >= CFG_MAX_TXQ_NUM) { -+ DBGLOG(P2P, ERROR, "Incorrect queue index, skip this frame\n"); -+ prGlueInfo->u8SkbFreed++; -+ dev_kfree_skb(prSkb); -+ return NETDEV_TX_OK; -+ } -+ GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_TX_QUE); -+ QUEUE_INSERT_TAIL(prTxQueue, prQueueEntry); -+ GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_TX_QUE); -+ -+ GLUE_INC_REF_CNT(prGlueInfo->i4TxPendingFrameNum); -+ GLUE_INC_REF_CNT(prGlueInfo->ai4TxPendingFrameNumPerQueue[NETWORK_TYPE_P2P_INDEX][u2QueueIdx]); -+ -+ if (prGlueInfo->ai4TxPendingFrameNumPerQueue[NETWORK_TYPE_P2P_INDEX][u2QueueIdx] >= -+ CFG_TX_STOP_NETIF_PER_QUEUE_THRESHOLD) { -+ DBGLOG(TX, INFO, "netif_stop_subqueue for p2p0, Queue len: %d\n", -+ prGlueInfo->ai4TxPendingFrameNumPerQueue[NETWORK_TYPE_P2P_INDEX][u2QueueIdx]); -+ netif_stop_subqueue(prDev, u2QueueIdx); -+ } -+ } else { -+ GLUE_INC_REF_CNT(prGlueInfo->i4TxPendingSecurityFrameNum); -+ } -+ -+ kalSetEvent(prGlueInfo); -+ -+ /* Statistic usage. */ -+ prGlueInfo->prP2PInfo->rNetDevStats.tx_bytes += prSkb->len; -+ prGlueInfo->prP2PInfo->rNetDevStats.tx_packets++; -+ /* prDev->stats.tx_packets++; */ -+ kalPerMonStart(prGlueInfo); -+ return NETDEV_TX_OK; -+} /* end of p2pHardStartXmit() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * \brief A method of struct net_device, a primary SOCKET interface to configure -+ * the interface lively. Handle an ioctl call on one of our devices. -+ * Everything Linux ioctl specific is done here. Then we pass the contents -+ * of the ifr->data to the request message handler. -+ * -+ * \param[in] prDev Linux kernel netdevice -+ * -+ * \param[in] prIfReq Our private ioctl request structure, typed for the generic -+ * struct ifreq so we can use ptr to function -+ * -+ * \param[in] cmd Command ID -+ * -+ * \retval 0 The IOCTL command is executed successfully. -+ * \retval <0 The execution of IOCTL command is failed. -+ */ -+/*----------------------------------------------------------------------------*/ -+int p2pDoIOCTL(struct net_device *prDev, struct ifreq *prIfReq, int i4Cmd) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ int ret = 0; -+ char *prExtraBuf = NULL; -+ UINT_32 u4ExtraSize = 0; -+ struct iwreq *prIwReq = (struct iwreq *)prIfReq; -+ struct iw_request_info rIwReqInfo; -+ -+ ASSERT(prDev && prIfReq); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ if (!prGlueInfo) { -+ DBGLOG(P2P, ERROR, "prGlueInfo is NULL\n"); -+ return -EFAULT; -+ } -+ -+ if (prGlueInfo->u4ReadyFlag == 0) { -+ DBGLOG(P2P, ERROR, "Adapter is not ready\n"); -+ return -EINVAL; -+ } -+ -+ rIwReqInfo.cmd = (__u16) i4Cmd; -+ rIwReqInfo.flags = 0; -+ -+ switch (i4Cmd) { -+ case SIOCSIWENCODEEXT: -+ /* Set Encryption Material after 4-way handshaking is done */ -+ if (prIwReq->u.encoding.pointer) { -+ u4ExtraSize = prIwReq->u.encoding.length; -+ prExtraBuf = kalMemAlloc(u4ExtraSize, VIR_MEM_TYPE); -+ -+ if (!prExtraBuf) { -+ ret = -ENOMEM; -+ break; -+ } -+ -+ if (copy_from_user(prExtraBuf, prIwReq->u.encoding.pointer, prIwReq->u.encoding.length)) -+ ret = -EFAULT; -+ } else if (prIwReq->u.encoding.length != 0) { -+ ret = -EINVAL; -+ break; -+ } -+ -+ if (ret == 0) -+ ret = mtk_p2p_wext_set_key(prDev, &rIwReqInfo, &(prIwReq->u), prExtraBuf); -+ -+ kalMemFree(prExtraBuf, VIR_MEM_TYPE, u4ExtraSize); -+ prExtraBuf = NULL; -+ break; -+ -+ case SIOCSIWMLME: -+ /* IW_MLME_DISASSOC used for disconnection */ -+ if (prIwReq->u.data.length != sizeof(struct iw_mlme)) { -+ DBGLOG(P2P, WARN, "MLME buffer strange:%d\n", prIwReq->u.data.length); -+ ret = -EINVAL; -+ break; -+ } -+ -+ if (!prIwReq->u.data.pointer) { -+ ret = -EINVAL; -+ break; -+ } -+ -+ prExtraBuf = kalMemAlloc(sizeof(struct iw_mlme), VIR_MEM_TYPE); -+ if (!prExtraBuf) { -+ ret = -ENOMEM; -+ break; -+ } -+ -+ if (copy_from_user(prExtraBuf, prIwReq->u.data.pointer, sizeof(struct iw_mlme))) -+ ret = -EFAULT; -+ else -+ ret = mtk_p2p_wext_mlme_handler(prDev, &rIwReqInfo, &(prIwReq->u), prExtraBuf); -+ -+ kalMemFree(prExtraBuf, VIR_MEM_TYPE, sizeof(struct iw_mlme)); -+ prExtraBuf = NULL; -+ break; -+ -+ case SIOCGIWPRIV: -+ /* This ioctl is used to list all IW privilege ioctls */ -+ ret = mtk_p2p_wext_get_priv(prDev, &rIwReqInfo, &(prIwReq->u), NULL); -+ break; -+ -+ case SIOCGIWSCAN: -+ ret = mtk_p2p_wext_discovery_results(prDev, &rIwReqInfo, &(prIwReq->u), NULL); -+ break; -+ -+ case SIOCSIWAUTH: -+ ret = mtk_p2p_wext_set_auth(prDev, &rIwReqInfo, &(prIwReq->u), NULL); -+ break; -+ -+ case IOC_P2P_CFG_DEVICE: -+ case IOC_P2P_PROVISION_COMPLETE: -+ case IOC_P2P_START_STOP_DISCOVERY: -+ case IOC_P2P_DISCOVERY_RESULTS: -+ case IOC_P2P_WSC_BEACON_PROBE_RSP_IE: -+ case IOC_P2P_CONNECT_DISCONNECT: -+ case IOC_P2P_PASSWORD_READY: -+ case IOC_P2P_GET_STRUCT: -+ case IOC_P2P_SET_STRUCT: -+ case IOC_P2P_GET_REQ_DEVICE_INFO: -+ ret = -+ rP2PIwPrivHandler[i4Cmd - SIOCIWFIRSTPRIV] (prDev, &rIwReqInfo, &(prIwReq->u), -+ (char *)&(prIwReq->u)); -+ break; -+#if CFG_SUPPORT_P2P_RSSI_QUERY -+ case SIOCGIWSTATS: -+ ret = mtk_p2p_wext_get_rssi(prDev, &rIwReqInfo, &(prIwReq->u), NULL); -+ break; -+#endif -+ case IOC_GET_PRIVATE_IOCTL_CMD: -+ ret = priv_support_driver_cmd(prDev, prIfReq, i4Cmd); -+ -+ break; -+ default: -+ ret = -ENOTTY; -+ } -+ -+ return ret; -+} /* end of p2pDoIOCTL() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * \brief To report the iw private args table to user space. -+ * -+ * \param[in] prDev Net device requested. -+ * \param[in] info Pointer to iw_request_info. -+ * \param[inout] wrqu Pointer to iwreq_data. -+ * \param[inout] extra -+ * -+ * \retval 0 For success. -+ * \retval -E2BIG For user's buffer size is too small. -+ * \retval -EFAULT For fail. -+ * -+ */ -+/*----------------------------------------------------------------------------*/ -+int -+mtk_p2p_wext_get_priv(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) -+{ -+ struct iw_point *prData = (struct iw_point *)&wrqu->data; -+ UINT_16 u2BufferSize = prData->length; -+ -+ /* Update our private args table size */ -+ prData->length = (__u16)sizeof(rP2PIwPrivTable); -+ if (u2BufferSize < prData->length) -+ return -E2BIG; -+ -+ if (prData->length) { -+ if (copy_to_user(prData->pointer, rP2PIwPrivTable, sizeof(rP2PIwPrivTable))) -+ return -EFAULT; -+ } -+ -+ return 0; -+} /* end of mtk_p2p_wext_get_priv() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * \brief To indicate P2P-FSM for re-associate to the connecting device -+ * -+ * \param[in] prDev Net device requested. -+ * \param[inout] wrqu Pointer to iwreq_data -+ * -+ * \retval 0 For success. -+ * \retval -EFAULT For fail. -+ * -+ */ -+/*----------------------------------------------------------------------------*/ -+int -+mtk_p2p_wext_reconnect(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) -+{ -+#if 0 -+ P_ADAPTER_T prAdapter = NULL; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ P_MSG_HDR_T prMsgHdr; -+ -+ ASSERT(prDev); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ ASSERT(prGlueInfo); -+ -+ prAdapter = prGlueInfo->prAdapter; -+ ASSERT(prAdapter); -+ -+ prMsgHdr = (P_MSG_HDR_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_HDR_T)); -+ if (!prMsgHdr) { -+ ASSERT(0); /* Can't trigger P2P FSM */ -+ return -ENOMEM; -+ } -+ -+ /* 1.2 fill message */ -+ -+ DBGLOG(P2P, TRACE, "mtk_p2p_wext_reconnect: P2P Reconnect\n"); -+ -+ /* 1.3 send message */ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgHdr, MSG_SEND_METHOD_BUF); -+#endif -+ return 0; -+} /* end of mtk_p2p_wext_reconnect() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief MLME command handler -+* -+* \param[in] prDev Net device requested. -+* \param[inout] wrqu Pointer to iwreq_data -+* -+* \retval 0 Success. -+* \retval -EFAULT Setting parameters to driver fail. -+* \retval -EOPNOTSUPP Key size not supported. -+* -+* \note -+*/ -+/*----------------------------------------------------------------------------*/ -+int -+mtk_p2p_wext_mlme_handler(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) -+{ -+#if 0 -+ P_ADAPTER_T prAdapter = NULL; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ struct iw_mlme *mlme = (struct iw_mlme *)extra; -+ P_MSG_P2P_CONNECTION_ABORT_T prMsgP2PConnAbt = (P_MSG_P2P_CONNECTION_ABORT_T) NULL; -+ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; -+ -+ ASSERT(prDev); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ ASSERT(prGlueInfo); -+ -+ prAdapter = prGlueInfo->prAdapter; -+ ASSERT(prAdapter); -+ -+ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); -+ -+ DBGLOG(P2P, TRACE, "mtk_p2p_wext_mlme_handler:\n"); -+ -+ switch (mlme->cmd) { -+ case IW_MLME_DISASSOC: -+ prMsgP2PConnAbt = -+ (P_MSG_HDR_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_P2P_CONNECTION_ABORT_T)); -+ if (!prMsgP2PConnAbt) { -+ ASSERT(0); /* Can't trigger P2P FSM */ -+ return -ENOMEM; -+ } -+ -+ COPY_MAC_ADDR(prMsgP2PConnAbt->aucTargetID, mlme->addr.sa_data); -+ -+ prMsgP2PConnAbt->u2ReasonCode = mlme->reason_code; -+ -+ if (EQUAL_MAC_ADDR(prMsgP2PConnAbt->aucTargetID, prP2pBssInfo->aucOwnMacAddr)) { -+ DBGLOG(P2P, TRACE, "P2P Connection Abort:\n"); -+ -+ /* 1.2 fill message */ -+ prMsgP2PConnAbt->rMsgHdr.eMsgId = MID_MNY_P2P_CONNECTION_ABORT; -+ } else { -+ DBGLOG(P2P, TRACE, "P2P Connection Pause:\n"); -+ -+ /* 1.2 fill message */ -+ } -+ -+ /* 1.3 send message */ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgP2PConnAbt, MSG_SEND_METHOD_BUF); -+ -+ break; -+ -+ default: -+ return -EOPNOTSUPP; -+ } -+#endif -+ return 0; -+} /* end of mtk_p2p_wext_mlme_handler() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief P2P Private I/O Control handler (IOC_P2P_PROVISION_COMPLETE) -+* -+* \param[in] prDev Net device requested. -+* \param[inout] wrqu Pointer to iwreq_data -+* -+* \retval 0 Success. -+* \retval -EFAULT Setting parameters to driver fail. -+* \retval -EOPNOTSUPP Key size not supported. -+* -+* \note -+*/ -+/*----------------------------------------------------------------------------*/ -+int -+mtk_p2p_wext_set_provision_complete(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) -+{ -+#if 0 -+ P_ADAPTER_T prAdapter = NULL; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ struct iw_point *prData = (struct iw_point *)&wrqu->data; -+ P_MSG_HDR_T prMsgHdr; -+ -+ ASSERT(prDev); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ ASSERT(prGlueInfo); -+ -+ prAdapter = prGlueInfo->prAdapter; -+ ASSERT(prAdapter); -+ -+ switch (prData->flags) { -+ case P2P_PROVISIONING_SUCCESS: -+ prMsgHdr = (P_MSG_HDR_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_HDR_T)); -+ if (!prMsgHdr) { -+ ASSERT(0); /* Can't trigger P2P FSM */ -+ return -ENOMEM; -+ } -+ -+ /* 1.2 fill message */ -+ -+ prGlueInfo->prP2PInfo->u4CipherPairwise = IW_AUTH_CIPHER_CCMP; -+ -+ /* 1.3 send message */ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgHdr, MSG_SEND_METHOD_BUF); -+ -+ break; -+ -+ case P2P_PROVISIONING_FAIL: -+ -+ break; -+ -+ default: -+ return -EOPNOTSUPP; -+ } -+#endif -+ -+ return 0; -+} /* end of mtk_p2p_wext_set_provision_complete() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief P2P Private I/O Control handler (IOC_P2P_START_STOP_DISCOVERY) -+* -+* \param[in] prDev Net device requested. -+* \param[inout] wrqu Pointer to iwreq_data -+* -+* \retval 0 Success. -+* \retval -EFAULT Setting parameters to driver fail. -+* \retval -EOPNOTSUPP Key size not supported. -+* -+* \note -+*/ -+/*----------------------------------------------------------------------------*/ -+int -+mtk_p2p_wext_start_stop_discovery(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) -+{ -+#if 0 -+ P_ADAPTER_T prAdapter = NULL; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ struct iw_point *prData = (struct iw_point *)&wrqu->data; -+ P_IW_P2P_REQ_DEVICE_TYPE prReqDeviceType = (P_IW_P2P_REQ_DEVICE_TYPE) extra; -+ UINT_8 au4IeBuf[MAX_IE_LENGTH]; -+ P_MSG_HDR_T prMsgHdr; -+ P_MSG_P2P_DEVICE_DISCOVER_T prDiscoverMsg; -+ P_P2P_CONNECTION_SETTINGS_T prConnSettings; -+ UINT_8 aucNullAddr[] = NULL_MAC_ADDR; -+ -+ ASSERT(prDev); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ ASSERT(prGlueInfo); -+ -+ prAdapter = prGlueInfo->prAdapter; -+ ASSERT(prAdapter); -+ -+ prConnSettings = prAdapter->rWifiVar.prP2PConnSettings; -+ -+ if (prData->flags == P2P_STOP_DISCOVERY) { -+ prMsgHdr = (P_MSG_HDR_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_HDR_T)); -+ -+ if (!prMsgHdr) { -+ ASSERT(0); /* Can't trigger P2P FSM */ -+ return -ENOMEM; -+ } -+ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgHdr, MSG_SEND_METHOD_BUF); -+ } else if (prData->flags == P2P_START_DISCOVERY) { -+ -+ /* retrieve IE for Probe Response */ -+ if (prReqDeviceType->probe_rsp_len > 0) { -+ if (prReqDeviceType->probe_rsp_len <= MAX_IE_LENGTH) { -+ if (copy_from_user -+ (prGlueInfo->prP2PInfo->aucWSCIE[2], prReqDeviceType->probe_rsp_ie, -+ prReqDeviceType->probe_rsp_len)) { -+ return -EFAULT; -+ } -+ prGlueInfo->prP2PInfo->u2WSCIELen[2] = prReqDeviceType->probe_rsp_len; -+ } else { -+ return -E2BIG; -+ } -+ } -+ -+ /* retrieve IE for Probe Request */ -+ if (prReqDeviceType->probe_req_len > 0) { -+ if (prReqDeviceType->probe_req_len <= MAX_IE_LENGTH) { -+ if (copy_from_user -+ (prGlueInfo->prP2PInfo->aucWSCIE[1], prReqDeviceType->probe_req_ie, -+ prReqDeviceType->probe_req_len)) { -+ return -EFAULT; -+ } -+ prGlueInfo->prP2PInfo->u2WSCIELen[1] = prReqDeviceType->probe_req_len; -+ } else { -+ return -E2BIG; -+ } -+ } -+ /* update IE for Probe Request */ -+ -+ if (prReqDeviceType->scan_type == P2P_LISTEN) { -+ /* update listening parameter */ -+ -+ /* @TODO: update prConnSettings for Probe Response IE */ -+ } else { -+ /* indicate P2P-FSM with MID_MNY_P2P_DEVICE_DISCOVERY */ -+ prDiscoverMsg = (P_MSG_P2P_DEVICE_DISCOVER_T) cnmMemAlloc(prAdapter, -+ RAM_TYPE_MSG, -+ sizeof(MSG_P2P_DEVICE_DISCOVER_T)); -+ -+ if (!prDiscoverMsg) { -+ ASSERT(0); /* Can't trigger P2P FSM */ -+ return -ENOMEM; -+ } -+ -+ prDiscoverMsg->rMsgHdr.eMsgId = MID_MNY_P2P_DEVICE_DISCOVERY; -+ prDiscoverMsg->u4DevDiscoverTime = 0; /* unlimited */ -+ prDiscoverMsg->fgIsSpecificType = TRUE; -+ prDiscoverMsg->rTargetDeviceType.u2CategoryID = -+ *(PUINT_16) (&(prReqDeviceType->pri_device_type[0])); -+ prDiscoverMsg->rTargetDeviceType.u2SubCategoryID = -+ *(PUINT_16) (&(prReqDeviceType->pri_device_type[6])); -+ COPY_MAC_ADDR(prDiscoverMsg->aucTargetDeviceID, aucNullAddr); -+ -+ /* @FIXME: parameter to be refined, where to pass IE buffer ? */ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prDiscoverMsg, MSG_SEND_METHOD_BUF); -+ } -+ } else { -+ return -EINVAL; -+ } -+#endif -+ -+ return 0; -+} /* end of mtk_p2p_wext_start_stop_discovery() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief P2P Private I/O Control handler (IOC_P2P_SET_INT) -+* -+* \param[in] prDev Net device requested. -+* \param[inout] wrqu Pointer to iwreq_data -+* -+* \retval 0 Success. -+* \retval -EFAULT Setting parameters to driver fail. -+* \retval -EOPNOTSUPP Setting parameters not support. -+* -+* \note -+*/ -+/*----------------------------------------------------------------------------*/ -+int -+mtk_p2p_wext_invitation_request(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) -+{ -+ int i4Status = 0; -+#if 0 -+ P_ADAPTER_T prAdapter = (P_ADAPTER_T) NULL; -+ P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) NULL; -+ struct iw_point *prData = (struct iw_point *)&wrqu->data; -+ P_IW_P2P_IOCTL_INVITATION_STRUCT prIoctlInvitation = (P_IW_P2P_IOCTL_INVITATION_STRUCT) NULL; -+ -+ do { -+ if ((prDev == NULL) || (extra == NULL)) { -+ ASSERT(FALSE); -+ i4Status = -EINVAL; -+ break; -+ } -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ prIoctlInvitation = (P_IW_P2P_IOCTL_INVITATION_STRUCT) extra; -+ -+ if (prGlueInfo == NULL) { -+ i4Status = -EINVAL; -+ break; -+ } -+ -+ prAdapter = prGlueInfo->prAdapter; -+ -+ if (prAdapter == NULL) { -+ i4Status = -EINVAL; -+ break; -+ } -+ -+ if (prIoctlInvitation->ucReinvoke == 1) { -+ /* TODO: Set Group ID */ -+ p2pFuncSetGroupID(prAdapter, prIoctlInvitation->aucGroupID, prIoctlInvitation->aucSsid, -+ prIoctlInvitation->u4SsidLen); -+ } -+ -+ else { -+ P_MSG_P2P_INVITATION_REQUEST_T prMsgP2PInvitationReq = (P_MSG_P2P_INVITATION_REQUEST_T) NULL; -+ -+ /* TODO: Do Invitation. */ -+ prMsgP2PInvitationReq = -+ (P_MSG_P2P_INVITATION_REQUEST_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, -+ sizeof(MSG_P2P_INVITATION_REQUEST_T)); -+ if (!prMsgP2PInvitationReq) { -+ ASSERT(0); /* Can't trigger P2P FSM */ -+ i4Status = -ENOMEM; -+ break; -+ } -+ -+ /* 1.2 fill message */ -+ kalMemCopy(prMsgP2PInvitationReq->aucDeviceID, prIoctlInvitation->aucDeviceID, MAC_ADDR_LEN); -+ -+ DBGLOG(P2P, TRACE, "mtk_p2p_wext_invitation_request: P2P Invitation Req\n"); -+ -+ /* 1.3 send message */ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgP2PInvitationReq, MSG_SEND_METHOD_BUF); -+ -+ } -+ -+ } while (FALSE); -+#endif -+ -+ return i4Status; -+ -+} -+ -+/* mtk_p2p_wext_invitation_request */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief P2P Private I/O Control handler (IOC_P2P_SET_INT) -+* -+* \param[in] prDev Net device requested. -+* \param[inout] wrqu Pointer to iwreq_data -+* -+* \retval 0 Success. -+* \retval -EFAULT Setting parameters to driver fail. -+* \retval -EOPNOTSUPP Setting parameters not support. -+* -+* \note -+*/ -+/*----------------------------------------------------------------------------*/ -+int -+mtk_p2p_wext_invitation_abort(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) -+{ -+ int i4Status = 0; -+#if 0 -+ P_ADAPTER_T prAdapter = (P_ADAPTER_T) NULL; -+ P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) NULL; -+ struct iw_point *prData = (struct iw_point *)&wrqu->data; -+ P_IW_P2P_IOCTL_ABORT_INVITATION prIoctlInvitationAbort = (P_IW_P2P_IOCTL_ABORT_INVITATION) NULL; -+ -+ UINT_8 bssid[MAC_ADDR_LEN]; -+ -+ do { -+ if ((prDev == NULL) || (extra == NULL)) { -+ ASSERT(FALSE); -+ i4Status = -EINVAL; -+ break; -+ } -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ prIoctlInvitationAbort = (P_IW_P2P_IOCTL_ABORT_INVITATION) extra; -+ -+ if (prGlueInfo == NULL) { -+ i4Status = -EINVAL; -+ break; -+ } -+ -+ prAdapter = prGlueInfo->prAdapter; -+ -+ if (prAdapter == NULL) { -+ i4Status = -EINVAL; -+ break; -+ } -+ P_MSG_P2P_INVITATION_REQUEST_T prMsgP2PInvitationAbort = (P_MSG_P2P_INVITATION_REQUEST_T) NULL; -+ -+ prMsgP2PInvitationAbort = -+ (P_MSG_P2P_INVITATION_REQUEST_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, -+ sizeof(MSG_P2P_INVITATION_REQUEST_T)); -+ -+ if (!prMsgP2PInvitationAbort) { -+ ASSERT(0); /* Can't trigger P2P FSM */ -+ i4Status = -ENOMEM; -+ break; -+ } -+ -+ /* 1.2 fill message */ -+ kalMemCopy(prMsgP2PInvitationAbort->aucDeviceID, prIoctlInvitationAbort->dev_addr, -+ MAC_ADDR_LEN); -+ -+ DBGLOG(P2P, TRACE, "mtk_p2p_wext_invitation_request: P2P Invitation Req\n"); -+ -+ /* 1.3 send message */ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgP2PInvitationAbort, MSG_SEND_METHOD_BUF); -+ -+ -+ } while (FALSE); -+#endif -+ -+ return i4Status; -+ -+} -+ -+/* mtk_p2p_wext_invitation_abort */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * \brief To override p2p interface address -+ * -+ * \param[in] prDev Net device requested. -+ * \param[in] addr Pointer to address -+ * -+ * \retval 0 For success. -+ * \retval -E2BIG For user's buffer size is too small. -+ * \retval -EFAULT For fail. -+ * -+ */ -+/*----------------------------------------------------------------------------*/ -+int p2pSetMACAddress(IN struct net_device *prDev, void *addr) -+{ -+ P_ADAPTER_T prAdapter = NULL; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ -+ ASSERT(prDev); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ ASSERT(prGlueInfo); -+ -+ prAdapter = prGlueInfo->prAdapter; -+ ASSERT(prAdapter); -+ -+ /* @FIXME */ -+ return eth_mac_addr(prDev, addr); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief To set encryption cipher suite -+* -+* \param[in] prDev Net device requested. -+* \param[out] -+* -+* \retval 0 Success. -+* \retval -EINVAL Invalid parameter -+* \retval -EOPNOTSUPP Key size not supported. -+* -+* \note -+*/ -+/*----------------------------------------------------------------------------*/ -+int -+mtk_p2p_wext_set_auth(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ struct iw_param *prAuth = (struct iw_param *)wrqu; -+ -+ ASSERT(prDev); -+ ASSERT(prAuth); -+ if (FALSE == GLUE_CHK_PR2(prDev, prAuth)) -+ return -EINVAL; -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ -+ /* Save information to glue info and process later when ssid is set. */ -+ switch (prAuth->flags & IW_AUTH_INDEX) { -+ case IW_AUTH_WPA_VERSION: -+ break; -+ case IW_AUTH_CIPHER_PAIRWISE: -+ prGlueInfo->prP2PInfo->u4CipherPairwise = prAuth->value; -+ break; -+ case IW_AUTH_CIPHER_GROUP: -+ case IW_AUTH_KEY_MGMT: -+ case IW_AUTH_TKIP_COUNTERMEASURES: -+ case IW_AUTH_DROP_UNENCRYPTED: -+ case IW_AUTH_80211_AUTH_ALG: -+ case IW_AUTH_WPA_ENABLED: -+ case IW_AUTH_RX_UNENCRYPTED_EAPOL: -+ case IW_AUTH_ROAMING_CONTROL: -+ case IW_AUTH_PRIVACY_INVOKED: -+ default: -+ /* @TODO */ -+ break; -+ } -+ -+ return 0; -+} /* end of mtk_p2p_wext_set_auth() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief To set encryption cipher and key. -+* -+* \param[in] prDev Net device requested. -+* \param[out] prIfReq Pointer to ifreq structure, content is copied back to -+* user space buffer in gl_iwpriv_table. -+* -+* \retval 0 Success. -+* \retval -EFAULT Setting parameters to driver fail. -+* \retval -EOPNOTSUPP Key size not supported. -+* -+* \note Securiry information is stored in pEnc. -+*/ -+/*----------------------------------------------------------------------------*/ -+int -+mtk_p2p_wext_set_key(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) -+{ -+ int ret = 0; -+ struct iw_encode_ext *prIWEncExt; -+ struct iw_point *prEnc; -+ char *prExtraBuf = NULL; -+ UINT_32 u4ExtraSize = 0; -+ UINT_8 keyStructBuf[100]; -+ P_PARAM_REMOVE_KEY_T prRemoveKey = (P_PARAM_REMOVE_KEY_T) keyStructBuf; -+ P_PARAM_KEY_T prKey = (P_PARAM_KEY_T) keyStructBuf; -+ P_GLUE_INFO_T prGlueInfo; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ UINT_32 u4BufLen = 0; -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ -+ do { -+ if (wrqu->encoding.pointer) { -+ u4ExtraSize = wrqu->encoding.length; -+ /*need confirm u4ExtraSize > 0 but is not very large*/ -+ prExtraBuf = kalMemAlloc(u4ExtraSize, VIR_MEM_TYPE); -+ -+ if (!prExtraBuf) { -+ ret = -ENOMEM; -+ break; -+ } -+ /* here should set prExtraBuf default value */ -+ memset(prExtraBuf, 0, u4ExtraSize); -+ if (copy_from_user(prExtraBuf, wrqu->encoding.pointer, wrqu->encoding.length)) { -+ ret = -EFAULT; -+ break; -+ } -+ } else if (wrqu->encoding.length != 0) { -+ ret = -EINVAL; -+ break; -+ } -+ -+ prEnc = &wrqu->encoding; -+ /* here, need confirm (struct iw_encode_ext) < u4ExtraSize */ -+ prIWEncExt = (struct iw_encode_ext *)prExtraBuf; -+ -+ if (GLUE_CHK_PR3(prDev, prEnc, prExtraBuf) != TRUE) { -+ ret = -EINVAL; -+ break; -+ } -+ -+ memset(keyStructBuf, 0, sizeof(keyStructBuf)); -+ -+ if ((prEnc->flags & IW_ENCODE_MODE) == IW_ENCODE_DISABLED) { /* Key Removal */ -+ prRemoveKey->u4Length = sizeof(*prRemoveKey); -+ memcpy(prRemoveKey->arBSSID, prIWEncExt->addr.sa_data, 6); -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetRemoveP2PKey, -+ prRemoveKey, -+ prRemoveKey->u4Length, FALSE, FALSE, TRUE, TRUE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) -+ ret = -EFAULT; -+ } else { -+ if (prIWEncExt->alg == IW_ENCODE_ALG_CCMP) { -+ /* KeyID */ -+ prKey->u4KeyIndex = (prEnc->flags & IW_ENCODE_INDEX) ? -+ ((prEnc->flags & IW_ENCODE_INDEX) - 1) : 0; -+ if (prKey->u4KeyIndex <= 3) { -+ /* bit(31) and bit(30) are shared by pKey and pRemoveKey */ -+ /* Tx Key Bit(31) */ -+ if (prIWEncExt->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) -+ prKey->u4KeyIndex |= 0x1UL << 31; -+ -+ /* Pairwise Key Bit(30) */ -+ if (prIWEncExt->ext_flags & IW_ENCODE_EXT_GROUP_KEY) { -+ /* group key */ -+ } else { -+ /* pairwise key */ -+ prKey->u4KeyIndex |= 0x1UL << 30; -+ } -+ -+ /* Rx SC Bit(29) */ -+ if (prIWEncExt->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID) { -+ prKey->u4KeyIndex |= 0x1UL << 29; -+ memcpy(&prKey->rKeyRSC, prIWEncExt->rx_seq, -+ IW_ENCODE_SEQ_MAX_SIZE); -+ } -+ -+ /* BSSID */ -+ memcpy(prKey->arBSSID, prIWEncExt->addr.sa_data, 6); -+ memcpy(prKey->aucKeyMaterial, prIWEncExt->key, prIWEncExt->key_len); -+ -+ prKey->u4KeyLength = prIWEncExt->key_len; -+ prKey->u4Length = -+ ((ULONG)&(((P_PARAM_KEY_T) 0)->aucKeyMaterial)) + -+ prKey->u4KeyLength; -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetAddP2PKey, -+ prKey, -+ prKey->u4Length, -+ FALSE, FALSE, TRUE, TRUE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) -+ ret = -EFAULT; -+ } else { -+ ret = -EINVAL; -+ } -+ } else { -+ ret = -EINVAL; -+ } -+ } -+ -+ } while (FALSE); -+ -+ if (prExtraBuf) { -+ kalMemFree(prExtraBuf, VIR_MEM_TYPE, u4ExtraSize); -+ prExtraBuf = NULL; -+ } -+ -+ return ret; -+} /* end of mtk_p2p_wext_set_key() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief set the p2p gc power mode -+* -+* \param[in] prDev Net device requested. -+* \param[inout] wrqu Pointer to iwreq_data -+* -+* \retval 0 Success. -+* \retval -EFAULT Setting parameters to driver fail. -+* \retval -EOPNOTSUPP Key size not supported. -+* -+* \note -+*/ -+/*----------------------------------------------------------------------------*/ -+int -+mtk_p2p_wext_set_powermode(IN struct net_device *prNetDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) -+{ -+ /* printk("set_powermode = %d, value = %d\n", wrqu->power.disabled, wrqu->power.value); */ -+ struct iw_param *prPower = (struct iw_param *)&wrqu->power; -+#if 1 -+ PARAM_POWER_MODE ePowerMode; -+ INT_32 i4PowerValue; -+ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ UINT_32 u4BufLen = 0; -+ -+ ASSERT(prNetDev); -+ ASSERT(prPower); -+ if (FALSE == GLUE_CHK_PR2(prNetDev, prPower)) -+ return -EINVAL; -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); -+ -+ /* printk(KERN_INFO "wext_set_power value(%d) disabled(%d) flag(0x%x)\n", */ -+ /* prPower->value, prPower->disabled, prPower->flags); */ -+ -+ if (prPower->disabled) { -+ ePowerMode = Param_PowerModeCAM; -+ } else { -+ i4PowerValue = prPower->value; -+#if WIRELESS_EXT < 21 -+ i4PowerValue /= 1000000; -+#endif -+ if (i4PowerValue == 0) { -+ ePowerMode = Param_PowerModeCAM; -+ } else if (i4PowerValue == 1) { -+ ePowerMode = Param_PowerModeMAX_PSP; -+ } else if (i4PowerValue == 2) { -+ ePowerMode = Param_PowerModeFast_PSP; -+ } else { -+ DBGLOG(P2P, ERROR, "%s(): unsupported power management mode value = %d.\n", -+ __func__, prPower->value); -+ -+ return -EINVAL; -+ } -+ } -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetP2pPowerSaveProfile, -+ &ePowerMode, sizeof(ePowerMode), FALSE, FALSE, TRUE, TRUE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ /* printk(KERN_INFO DRV_NAME"wlanoidSet802dot11PowerSaveProfile fail 0x%lx\n", rStatus); */ -+ return -EFAULT; -+ } -+#endif -+ -+ return 0; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief get the p2p gc power mode -+* -+* \param[in] prDev Net device requested. -+* \param[inout] wrqu Pointer to iwreq_data -+* -+* \retval 0 Success. -+* \retval -EFAULT Setting parameters to driver fail. -+* \retval -EOPNOTSUPP Key size not supported. -+* -+* \note -+*/ -+/*----------------------------------------------------------------------------*/ -+int -+mtk_p2p_wext_get_powermode(IN struct net_device *prNetDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) -+{ -+ /* printk("mtk_p2p_wext_get_powermode\n"); */ -+ /* wrqu->power.disabled = 0; */ -+ /* wrqu->power.value = 1; */ -+ -+ struct iw_param *prPower = (struct iw_param *)&wrqu->power; -+ PARAM_POWER_MODE ePowerMode = Param_PowerModeMax; -+ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ UINT_32 u4BufLen = 0; -+ -+ ASSERT(prNetDev); -+ ASSERT(prPower); -+ if (FALSE == GLUE_CHK_PR2(prNetDev, prPower)) -+ return -EINVAL; -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); -+ ASSERT(prGlueInfo); -+ -+#if 1 -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidQueryP2pPowerSaveProfile, -+ &ePowerMode, sizeof(ePowerMode), TRUE, FALSE, FALSE, TRUE, &u4BufLen); -+#else -+ rStatus = wlanQueryInformation(prGlueInfo->prAdapter, -+ wlanoidQueryP2pPowerSaveProfile, &ePowerMode, sizeof(ePowerMode), &u4BufLen); -+#endif -+ -+ prPower->value = 0; -+ prPower->disabled = 1; -+ -+ if (Param_PowerModeCAM == ePowerMode) { -+ prPower->value = 0; -+ prPower->disabled = 1; -+ } else if (Param_PowerModeMAX_PSP == ePowerMode) { -+ prPower->value = 1; -+ prPower->disabled = 0; -+ } else if (Param_PowerModeFast_PSP == ePowerMode) { -+ prPower->value = 2; -+ prPower->disabled = 0; -+ } -+ -+ prPower->flags = IW_POWER_PERIOD | IW_POWER_RELATIVE; -+#if WIRELESS_EXT < 21 -+ prPower->value *= 1000000; -+#endif -+ -+ return 0; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief P2P Private I/O Control handler (IOC_P2P_CFG_DEVICE) -+* -+* \param[in] prDev Net device requested. -+* \param[inout] wrqu Pointer to iwreq_data -+* -+* \retval 0 Success. -+* \retval -EFAULT Setting parameters to driver fail. -+* \retval -EOPNOTSUPP Key size not supported. -+* -+* \note -+*/ -+/*----------------------------------------------------------------------------*/ -+int -+mtk_p2p_wext_set_local_dev_info(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) -+{ -+ P_ADAPTER_T prAdapter = NULL; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ P_IW_P2P_CFG_DEVICE_TYPE prDeviceCfg = (P_IW_P2P_CFG_DEVICE_TYPE) extra; -+ P_P2P_CONNECTION_SETTINGS_T prConnSettings; -+ P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo = (P_P2P_SPECIFIC_BSS_INFO_T) NULL; -+ /* P_MSG_P2P_FUNCTION_SWITCH_T prFuncSwitch = (P_MSG_P2P_FUNCTION_SWITCH_T)NULL; */ -+ -+ ASSERT(prDev); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ ASSERT(prGlueInfo); -+ -+ prAdapter = prGlueInfo->prAdapter; -+ ASSERT(prAdapter); -+ -+ prConnSettings = prAdapter->rWifiVar.prP2PConnSettings; -+ prP2pSpecificBssInfo = prAdapter->rWifiVar.prP2pSpecificBssInfo; -+ -+ /* update connection settings for P2P-FSM */ -+ /* 1. update SSID */ -+ if (prDeviceCfg->ssid_len > ELEM_MAX_LEN_SSID) -+ prConnSettings->ucSSIDLen = ELEM_MAX_LEN_SSID; -+ else -+ prConnSettings->ucSSIDLen = prDeviceCfg->ssid_len; -+ -+ if (copy_from_user(prConnSettings->aucSSID, prDeviceCfg->ssid, prConnSettings->ucSSIDLen)) -+ return -EFAULT; -+ /* 2. update device type (WPS IE) */ -+ kalMemCopy(&(prConnSettings->rPrimaryDevTypeBE), &(prDeviceCfg->pri_device_type), sizeof(DEVICE_TYPE_T)); -+#if P2P_MAX_SUPPORTED_SEC_DEV_TYPE_COUNT -+ kalMemCopy(&(prConnSettings->arSecondaryDevTypeBE[0]), &(prDeviceCfg->snd_device_type), sizeof(DEVICE_TYPE_T)); -+#endif -+ -+ /* 3. update device name */ -+ if (prDeviceCfg->device_name_len > WPS_ATTRI_MAX_LEN_DEVICE_NAME) -+ prConnSettings->ucDevNameLen = WPS_ATTRI_MAX_LEN_DEVICE_NAME; -+ else -+ prConnSettings->ucDevNameLen = prDeviceCfg->device_name_len; -+ if (copy_from_user(prConnSettings->aucDevName, prDeviceCfg->device_name, prConnSettings->ucDevNameLen)) -+ return -EFAULT; -+ /* 4. update GO intent */ -+ prConnSettings->ucGoIntent = prDeviceCfg->intend; -+ -+ /* Preferred channel bandwidth */ -+ prAdapter->rWifiVar.rConnSettings.uc2G4BandwidthMode = prDeviceCfg->ch_width ? CONFIG_BW_20_40M : CONFIG_BW_20M; -+ prAdapter->rWifiVar.rConnSettings.uc5GBandwidthMode = prDeviceCfg->ch_width ? CONFIG_BW_20_40M : CONFIG_BW_20M; -+ -+#if 0 -+ /* 1. switch P2P-FSM on */ -+ /* 1.1 allocate for message */ -+ prFuncSwitch = (P_MSG_P2P_FUNCTION_SWITCH_T) cnmMemAlloc(prAdapter, -+ RAM_TYPE_MSG, sizeof(MSG_P2P_FUNCTION_SWITCH_T)); -+ -+ if (!prFuncSwitch) { -+ ASSERT(0); /* Can't trigger P2P FSM */ -+ return -ENOMEM; -+ } -+ -+ /* 1.2 fill message */ -+ prFuncSwitch->rMsgHdr.eMsgId = MID_MNY_P2P_FUN_SWITCH; -+ prFuncSwitch->fgIsFuncOn = TRUE; -+ -+ /* 1.3 send message */ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prFuncSwitch, MSG_SEND_METHOD_BUF); -+#endif -+ return 0; -+} /* end of mtk_p2p_wext_set_local_dev_info() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * \brief I/O Control handler for both -+ * IOC_P2P_START_STOP_DISCOVERY & SIOCGIWSCAN -+ * -+ * \param[in] prDev Net device requested. -+ * \param[inout] wrqu Pointer to iwreq_data -+ * -+ * \retval 0 Success. -+ * \retval -EFAULT Setting parameters to driver fail. -+ * \retval -EOPNOTSUPP Key size not supported. -+ * -+ * \note -+ */ -+/*----------------------------------------------------------------------------*/ -+int -+mtk_p2p_wext_discovery_results(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) -+{ -+ struct iw_event iwe; -+ char *current_ev = extra; -+ UINT_32 i; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ P_ADAPTER_T prAdapter = NULL; -+ P_P2P_INFO_T prP2PInfo = (P_P2P_INFO_T) NULL; -+ P_EVENT_P2P_DEV_DISCOVER_RESULT_T prTargetResult = (P_EVENT_P2P_DEV_DISCOVER_RESULT_T) NULL; -+ P_PARAM_VARIABLE_IE_T prDesiredIE = NULL; -+ -+ ASSERT(prDev); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ ASSERT(prGlueInfo); -+ -+ prAdapter = prGlueInfo->prAdapter; -+ ASSERT(prAdapter); -+ -+ prP2PInfo = prAdapter->prP2pInfo; -+ -+ for (i = 0; i < prP2PInfo->u4DeviceNum; i++) { -+ prTargetResult = &prP2PInfo->arP2pDiscoverResult[i]; -+ -+ /* SIOCGIWAP */ -+ iwe.cmd = SIOCGIWAP; -+ iwe.u.ap_addr.sa_family = ARPHRD_ETHER; -+ memcpy(iwe.u.ap_addr.sa_data, prTargetResult->aucInterfaceAddr, 6); -+ -+ current_ev = iwe_stream_add_event(info, current_ev, extra + IW_SCAN_MAX_DATA, &iwe, IW_EV_ADDR_LEN); -+ -+ /* SIOCGIWESSID */ -+ iwe.cmd = SIOCGIWESSID; -+ iwe.u.data.flags = 1; -+ iwe.u.data.length = prTargetResult->u2NameLength; -+ -+ current_ev = iwe_stream_add_point(info, current_ev, -+ extra + IW_SCAN_MAX_DATA, &iwe, prTargetResult->aucName); -+ -+ /* IWEVGENIE for WPA IE */ -+ if (prTargetResult->u2IELength <= 600 && wextSrchDesiredWPAIE(prTargetResult->pucIeBuf, -+ prTargetResult->u2IELength, -+ 0xDD, (PUINT_8 *) &prDesiredIE)) { -+ -+ iwe.cmd = IWEVGENIE; -+ iwe.u.data.flags = 1; -+ iwe.u.data.length = 2 + (__u16) prDesiredIE->ucLength; -+ -+ current_ev = iwe_stream_add_point(info, current_ev, -+ extra + IW_SCAN_MAX_DATA, &iwe, (char *)prDesiredIE); -+ } -+#if CFG_SUPPORT_WPS -+ -+ /* IWEVGENIE for WPS IE */ -+ if ((prTargetResult->u2IELength <= 600) && wextSrchDesiredWPSIE(prTargetResult->pucIeBuf, -+ prTargetResult->u2IELength, -+ 0xDD, (PUINT_8 *) &prDesiredIE)) { -+ -+ iwe.cmd = IWEVGENIE; -+ iwe.u.data.flags = 1; -+ iwe.u.data.length = 2 + (__u16) prDesiredIE->ucLength; -+ -+ current_ev = iwe_stream_add_point(info, current_ev, -+ extra + IW_SCAN_MAX_DATA, &iwe, (char *)prDesiredIE); -+ } -+#endif -+ -+ /* IWEVGENIE for RSN IE */ -+ if ((prTargetResult->u2IELength <= 600) && wextSrchDesiredWPAIE(prTargetResult->pucIeBuf, -+ prTargetResult->u2IELength, -+ 0x30, (PUINT_8 *) &prDesiredIE)) { -+ -+ iwe.cmd = IWEVGENIE; -+ iwe.u.data.flags = 1; -+ iwe.u.data.length = 2 + (__u16) prDesiredIE->ucLength; -+ -+ current_ev = iwe_stream_add_point(info, current_ev, -+ extra + IW_SCAN_MAX_DATA, &iwe, (char *)prDesiredIE); -+ } -+ -+ /* IOC_P2P_GO_WSC_IE */ -+#if 1 -+ /* device capability */ -+ if (1) { -+ UINT_8 data[40]; -+ -+ iwe.cmd = IWEVCUSTOM; -+ iwe.u.data.flags = 0; -+ iwe.u.data.length = 9 + sizeof("p2p_cap="); -+ if (iwe.u.data.length > 40) -+ iwe.u.data.length = 40; -+ -+ snprintf(data, iwe.u.data.length, "p2p_cap=%02x%02x%02x%02x%c", -+ prTargetResult->ucDeviceCapabilityBitmap, prTargetResult->ucGroupCapabilityBitmap, -+ (UINT_8) prTargetResult->u2ConfigMethod, -+ (UINT_8) (prTargetResult->u2ConfigMethod >> 8), '\0'); -+ current_ev = -+ iwe_stream_add_point(info, current_ev, extra + IW_SCAN_MAX_DATA, &iwe, (char *)data); -+ -+ /* printk("%s\n", data); */ -+ kalMemZero(data, 40); -+ -+ iwe.cmd = IWEVCUSTOM; -+ iwe.u.data.flags = 0; -+ iwe.u.data.length = 13 + sizeof("p2p_dev_type="); -+ if (iwe.u.data.length > 40) -+ iwe.u.data.length = 40; -+ -+ snprintf(data, iwe.u.data.length, "p2p_dev_type=%02x%02x%02x%02x%02x%02x%c", -+ (UINT_8) prTargetResult->rPriDevType.u2CategoryID, -+ (UINT_8) prTargetResult->rPriDevType.u2SubCategoryID, -+ (UINT_8) prTargetResult->arSecDevType[0].u2CategoryID, -+ (UINT_8) prTargetResult->arSecDevType[0].u2SubCategoryID, -+ (UINT_8) prTargetResult->arSecDevType[1].u2CategoryID, -+ (UINT_8) prTargetResult->arSecDevType[1].u2SubCategoryID, '\0'); -+ current_ev = -+ iwe_stream_add_point(info, current_ev, extra + IW_SCAN_MAX_DATA, &iwe, (char *)data); -+ /* printk("%s\n", data); */ -+ -+ kalMemZero(data, 40); -+ -+ iwe.cmd = IWEVCUSTOM; -+ iwe.u.data.flags = 0; -+ iwe.u.data.length = 17 + sizeof("p2p_grp_bssid="); -+ if (iwe.u.data.length > 40) -+ iwe.u.data.length = 40; -+ -+ snprintf(data, iwe.u.data.length, "p2p_grp_bssid= %pM %c", -+ prTargetResult->aucBSSID, '\0'); -+ current_ev = iwe_stream_add_point(info, current_ev, -+ extra + IW_SCAN_MAX_DATA, &iwe, (char *)data); -+ /* printk("%s\n", data); */ -+ -+ } -+#endif -+ } -+ -+ /* Length of data */ -+ wrqu->data.length = (current_ev - extra); -+ wrqu->data.flags = 0; -+ -+ return 0; -+} /* end of mtk_p2p_wext_discovery_results() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief P2P Private I/O Control handler (IOC_P2P_WSC_BEACON_PROBE_RSP_IE) -+* -+* \param[in] prDev Net device requested. -+* \param[inout] wrqu Pointer to iwreq_data -+* -+* \retval 0 Success. -+* \retval -EFAULT Setting parameters to driver fail. -+* \retval -EOPNOTSUPP Key size not supported. -+* -+* \note -+*/ -+/*----------------------------------------------------------------------------*/ -+int -+mtk_p2p_wext_wsc_ie(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) -+{ -+ P_ADAPTER_T prAdapter = NULL; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ P_IW_P2P_HOSTAPD_PARAM prHostapdParam = (P_IW_P2P_HOSTAPD_PARAM) extra; -+ -+ ASSERT(prDev); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ ASSERT(prGlueInfo); -+ -+ if (prHostapdParam->len > 0) { -+ if (prHostapdParam->len <= MAX_WSC_IE_LENGTH) { -+ if (copy_from_user -+ (prGlueInfo->prP2PInfo->aucWSCIE[0], prHostapdParam->data, prHostapdParam->len)) { -+ return -EFAULT; -+ } -+ if (copy_from_user -+ (prGlueInfo->prP2PInfo->aucWSCIE[2], prHostapdParam->data, prHostapdParam->len)) { -+ return -EFAULT; -+ } -+ } else { -+ return -E2BIG; -+ } -+ } -+ -+ prGlueInfo->prP2PInfo->u2WSCIELen[0] = prHostapdParam->len; -+ prGlueInfo->prP2PInfo->u2WSCIELen[2] = prHostapdParam->len; -+ -+ prAdapter = prGlueInfo->prAdapter; -+ ASSERT(prAdapter); -+ -+ bssUpdateBeaconContent(prAdapter, NETWORK_TYPE_P2P_INDEX); -+ -+ /* @TODO: send message to P2P-FSM */ -+ -+ return 0; -+} /* end of mtk_p2p_wext_wsc_ie() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief P2P Private I/O Control handler (IOC_P2P_CONNECT_DISCONNECT) -+* -+* \param[in] prDev Net device requested. -+* \param[inout] wrqu Pointer to iwreq_data -+* -+* \retval 0 Success. -+* \retval -EFAULT Setting parameters to driver fail. -+* \retval -EOPNOTSUPP Key size not supported. -+* -+* \note -+*/ -+/*----------------------------------------------------------------------------*/ -+int -+mtk_p2p_wext_connect_disconnect(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) -+{ -+ P_ADAPTER_T prAdapter = NULL; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ struct iw_point *prData = (struct iw_point *)&wrqu->data; -+/* P_IW_P2P_CONNECT_DEVICE prConnectDevice = (P_IW_P2P_CONNECT_DEVICE)extra; */ -+/* P_MSG_HDR_T prMsgHdr; */ -+/* P_MSG_P2P_CONNECTION_REQUEST_T prMsgP2PConnReq; */ -+/* P_MSG_P2P_CONNECTION_ABORT_T prMsgP2PConnAbt; */ -+/* UINT_8 aucBCAddr[] = BC_MAC_ADDR; */ -+ -+ ASSERT(prDev); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ ASSERT(prGlueInfo); -+ -+ prAdapter = prGlueInfo->prAdapter; -+ ASSERT(prAdapter); -+ -+ if (prData->flags == P2P_CONNECT) { -+#if 0 -+ /* indicate P2P-FSM with MID_MNY_P2P_CONNECTION_REQ */ -+ prMsgP2PConnReq = (P_MSG_P2P_CONNECTION_REQUEST_T) cnmMemAlloc(prAdapter, -+ RAM_TYPE_MSG, -+ sizeof(MSG_P2P_CONNECTION_REQUEST_T)); -+ -+ if (!prMsgP2PConnReq) { -+ ASSERT(0); /* Can't trigger P2P FSM */ -+ return -ENOMEM; -+ } -+ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgP2PConnReq, MSG_SEND_METHOD_BUF); -+#endif -+ } else if (prData->flags == P2P_DISCONNECT) { -+#if 0 -+ /* indicate P2P-FSM with MID_MNY_P2P_CONNECTION_ABORT */ -+ prMsgP2PConnAbt = (P_MSG_HDR_T) cnmMemAlloc(prAdapter, -+ RAM_TYPE_MSG, sizeof(MSG_P2P_CONNECTION_ABORT_T)); -+ -+ if (!prMsgP2PConnAbt) { -+ ASSERT(0); /* Can't trigger P2P FSM */ -+ return -ENOMEM; -+ } -+ -+ COPY_MAC_ADDR(prMsgP2PConnAbt->aucTargetID, prConnectDevice->sta_addr); -+ -+ prMsgP2PConnAbt->rMsgHdr.eMsgId = MID_MNY_P2P_CONNECTION_ABORT; -+ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgP2PConnAbt, MSG_SEND_METHOD_BUF); -+#endif -+ } else { -+ return -EINVAL; -+ } -+ -+ return 0; -+} /* end of mtk_p2p_wext_connect_disconnect() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief P2P Private I/O Control handler (IOC_P2P_PASSWORD_READY) -+* -+* \param[in] prDev Net device requested. -+* \param[inout] wrqu Pointer to iwreq_data -+* -+* \retval 0 Success. -+* \retval -EFAULT Setting parameters to driver fail. -+* \retval -EOPNOTSUPP Key size not supported. -+* -+* \note -+*/ -+/*----------------------------------------------------------------------------*/ -+int -+mtk_p2p_wext_password_ready(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) -+{ -+ P_ADAPTER_T prAdapter = NULL; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ P_IW_P2P_PASSWORD_READY prPasswordReady = (P_IW_P2P_PASSWORD_READY) extra; -+ P_P2P_CONNECTION_SETTINGS_T prConnSettings; -+ -+ ASSERT(prDev); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ ASSERT(prGlueInfo); -+ -+ prAdapter = prGlueInfo->prAdapter; -+ ASSERT(prAdapter); -+ -+ prConnSettings = prAdapter->rWifiVar.prP2PConnSettings; -+ -+ /* retrieve IE for Probe Request */ -+ if (prPasswordReady->probe_req_len > 0) { -+ if (prPasswordReady->probe_req_len <= MAX_WSC_IE_LENGTH) { -+ if (copy_from_user -+ (prGlueInfo->prP2PInfo->aucWSCIE[1], prPasswordReady->probe_req_ie, -+ prPasswordReady->probe_req_len)) { -+ return -EFAULT; -+ } -+ } else { -+ return -E2BIG; -+ } -+ } -+ -+ prGlueInfo->prP2PInfo->u2WSCIELen[1] = prPasswordReady->probe_req_len; -+ -+ /* retrieve IE for Probe Response */ -+ if (prPasswordReady->probe_rsp_len > 0) { -+ if (prPasswordReady->probe_rsp_len <= MAX_WSC_IE_LENGTH) { -+ if (copy_from_user -+ (prGlueInfo->prP2PInfo->aucWSCIE[2], prPasswordReady->probe_rsp_ie, -+ prPasswordReady->probe_rsp_len)) { -+ return -EFAULT; -+ } -+ } else { -+ return -E2BIG; -+ } -+ } -+ -+ prGlueInfo->prP2PInfo->u2WSCIELen[2] = prPasswordReady->probe_rsp_len; -+ -+ switch (prPasswordReady->active_config_method) { -+ case 1: -+ prConnSettings->u2LocalConfigMethod = WPS_ATTRI_CFG_METHOD_PUSH_BUTTON; -+ break; -+ case 2: -+ prConnSettings->u2LocalConfigMethod = WPS_ATTRI_CFG_METHOD_KEYPAD; -+ break; -+ case 3: -+ prConnSettings->u2LocalConfigMethod = WPS_ATTRI_CFG_METHOD_DISPLAY; -+ break; -+ default: -+ break; -+ } -+ -+ prConnSettings->fgIsPasswordIDRdy = TRUE; -+ return 0; -+} /* end of mtk_p2p_wext_password_ready() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief P2P Private I/O Control handler (IOC_P2P_GET_REQ_DEVICE_INFO) -+* -+* \param[in] prDev Net device requested. -+* \param[inout] wrqu Pointer to iwreq_data -+* -+* \retval 0 Success. -+* \retval -EFAULT Setting parameters to driver fail. -+* \retval -EOPNOTSUPP Key size not supported. -+* -+* \note -+*/ -+/*----------------------------------------------------------------------------*/ -+int -+mtk_p2p_wext_request_dev_info(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) -+{ -+ P_ADAPTER_T prAdapter = NULL; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ P_IW_P2P_DEVICE_REQ prDeviceReq = (P_IW_P2P_DEVICE_REQ) extra; -+ -+ ASSERT(prDev); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ ASSERT(prGlueInfo); -+ -+ prAdapter = prGlueInfo->prAdapter; -+ ASSERT(prAdapter); -+ -+ /* specify data length */ -+ wrqu->data.length = sizeof(IW_P2P_DEVICE_REQ); -+ -+ /* copy to upper-layer supplied buffer */ -+ kalMemCopy(prDeviceReq->name, prGlueInfo->prP2PInfo->aucConnReqDevName, -+ prGlueInfo->prP2PInfo->u4ConnReqNameLength); -+ prDeviceReq->name_len = prGlueInfo->prP2PInfo->u4ConnReqNameLength; -+ prDeviceReq->name[prDeviceReq->name_len] = '\0'; -+ COPY_MAC_ADDR(prDeviceReq->device_addr, prGlueInfo->prP2PInfo->rConnReqPeerAddr); -+ prDeviceReq->device_type = prGlueInfo->prP2PInfo->ucConnReqDevType; -+ prDeviceReq->config_method = prGlueInfo->prP2PInfo->i4ConnReqConfigMethod; -+ prDeviceReq->active_config_method = prGlueInfo->prP2PInfo->i4ConnReqActiveConfigMethod; -+ -+ return 0; -+} /* end of mtk_p2p_wext_request_dev_info() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief P2P Private I/O Control handler (IOC_P2P_GET_STRUCT) -+* -+* \param[in] prDev Net device requested. -+* \param[inout] wrqu Pointer to iwreq_data -+* -+* \retval 0 Success. -+* \retval -EFAULT Setting parameters to driver fail. -+* \retval -EOPNOTSUPP Key size not supported. -+* -+* \note -+*/ -+/*----------------------------------------------------------------------------*/ -+int -+mtk_p2p_wext_invitation_indicate(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) -+{ -+ P_ADAPTER_T prAdapter = NULL; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ P_IW_P2P_IOCTL_INVITATION_INDICATE prInvIndicate = (P_IW_P2P_IOCTL_INVITATION_INDICATE) extra; -+ -+ ASSERT(prDev); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ ASSERT(prGlueInfo); -+ -+ prAdapter = prGlueInfo->prAdapter; -+ ASSERT(prAdapter); -+ -+ /* specify data length */ -+ wrqu->data.length = sizeof(IW_P2P_IOCTL_INVITATION_INDICATE); -+ -+ /* copy to upper-layer supplied buffer */ -+ kalMemCopy(prInvIndicate->dev_name, prGlueInfo->prP2PInfo->aucConnReqDevName, -+ prGlueInfo->prP2PInfo->u4ConnReqNameLength); -+ kalMemCopy(prInvIndicate->group_bssid, prGlueInfo->prP2PInfo->rConnReqGroupAddr, MAC_ADDR_LEN); -+ prInvIndicate->name_len = prGlueInfo->prP2PInfo->u4ConnReqNameLength; -+ prInvIndicate->dev_name[prInvIndicate->name_len] = '\0'; -+ COPY_MAC_ADDR(prInvIndicate->dev_addr, prGlueInfo->prP2PInfo->rConnReqPeerAddr); -+ prInvIndicate->config_method = prGlueInfo->prP2PInfo->i4ConnReqConfigMethod; -+ prInvIndicate->operating_channel = prGlueInfo->prP2PInfo->ucOperatingChnl; -+ prInvIndicate->invitation_type = prGlueInfo->prP2PInfo->ucInvitationType; -+ -+ return 0; -+} /* end of mtk_p2p_wext_invitation_indicate() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief P2P Private I/O Control handler (IOC_P2P_GET_STRUCT) -+* -+* \param[in] prDev Net device requested. -+* \param[inout] wrqu Pointer to iwreq_data -+* -+* \retval 0 Success. -+* \retval -EFAULT Setting parameters to driver fail. -+* \retval -EOPNOTSUPP Key size not supported. -+* -+* \note -+*/ -+/*----------------------------------------------------------------------------*/ -+int -+mtk_p2p_wext_invitation_status(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) -+{ -+ P_ADAPTER_T prAdapter = NULL; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ P_IW_P2P_IOCTL_INVITATION_STATUS prInvStatus = (P_IW_P2P_IOCTL_INVITATION_STATUS) extra; -+ -+ ASSERT(prDev); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ ASSERT(prGlueInfo); -+ -+ prAdapter = prGlueInfo->prAdapter; -+ ASSERT(prAdapter); -+ -+ /* specify data length */ -+ wrqu->data.length = sizeof(IW_P2P_IOCTL_INVITATION_STATUS); -+ -+ /* copy to upper-layer supplied buffer */ -+ prInvStatus->status_code = prGlueInfo->prP2PInfo->u4InvStatus; -+ -+ return 0; -+} /* end of mtk_p2p_wext_invitation_status() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief indicate an event to supplicant for device found -+* -+* \param[in] prGlueInfo Pointer of GLUE_INFO_T -+* -+* \retval TRUE Success. -+* \retval FALSE Failure -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN kalP2PIndicateFound(IN P_GLUE_INFO_T prGlueInfo) -+{ -+ union iwreq_data evt; -+ UINT_8 aucBuffer[IW_CUSTOM_MAX]; -+ -+ ASSERT(prGlueInfo); -+ -+ memset(&evt, 0, sizeof(evt)); -+ -+ snprintf(aucBuffer, IW_CUSTOM_MAX - 1, "P2P_DVC_FND"); -+ evt.data.length = strlen(aucBuffer); -+ -+ /* indicate IWEVP2PDVCFND event */ -+ wireless_send_event(prGlueInfo->prP2PInfo->prDevHandler, IWEVCUSTOM, &evt, aucBuffer); -+ -+ return FALSE; -+} /* end of kalP2PIndicateFound() */ -+ -+int -+mtk_p2p_wext_set_network_address(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) -+{ -+ P_ADAPTER_T prAdapter = NULL; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ -+ ASSERT(prDev); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ ASSERT(prGlueInfo); -+ -+ prAdapter = prGlueInfo->prAdapter; -+ ASSERT(prAdapter); -+ -+ /* @TODO: invoke wlan_p2p functions */ -+#if 0 -+ rStatus = kalIoctl(prGlueInfo, -+ (PFN_OID_HANDLER_FUNC_REQ) wlanoidSetP2pNetworkAddress, -+ prKey, prKey->u4Length, FALSE, FALSE, TRUE, &u4BufLen); -+#endif -+ -+ return 0; -+ -+} -+ -+int -+mtk_p2p_wext_set_ps_profile(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) -+{ -+ P_ADAPTER_T prAdapter = NULL; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ -+ ASSERT(prDev); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ ASSERT(prGlueInfo); -+ -+ prAdapter = prGlueInfo->prAdapter; -+ ASSERT(prAdapter); -+ -+ /* @TODO: invoke wlan_p2p functions */ -+#if 0 -+ rStatus = kalIoctl(prGlueInfo, -+ (PFN_OID_HANDLER_FUNC_REQ) wlanoidSetP2pPowerSaveProfile, -+ prKey, prKey->u4Length, FALSE, FALSE, TRUE, &u4BufLen); -+#endif -+ -+ return 0; -+ -+} -+ -+int -+mtk_p2p_wext_set_pm_param(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) -+{ -+ P_ADAPTER_T prAdapter = NULL; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ -+ ASSERT(prDev); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ ASSERT(prGlueInfo); -+ -+ prAdapter = prGlueInfo->prAdapter; -+ ASSERT(prAdapter); -+ -+ /* @TODO: invoke wlan_p2p functions */ -+#if 0 -+ rStatus = kalIoctl(prGlueInfo, -+ (PFN_OID_HANDLER_FUNC_REQ) wlanoidSetP2pPowerSaveProfile, -+ prKey, prKey->u4Length, FALSE, FALSE, TRUE, &u4BufLen); -+#endif -+ -+ return 0; -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief P2P Private I/O Control handler (IOC_P2P_SET_INT) -+* -+* \param[in] prDev Net device requested. -+* \param[inout] wrqu Pointer to iwreq_data -+* -+* \retval 0 Success. -+* \retval -EFAULT Setting parameters to driver fail. -+* \retval -EOPNOTSUPP Setting parameters not support. -+* -+* \note -+*/ -+/*----------------------------------------------------------------------------*/ -+int -+mtk_p2p_wext_start_formation(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) -+{ -+ int i4Status = 0; -+ P_ADAPTER_T prAdapter = (P_ADAPTER_T) NULL; -+ P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) NULL; -+/* struct iw_point *prData = (struct iw_point*)&wrqu->data; */ -+ P_IW_P2P_IOCTL_START_FORMATION prIoctlStartFormation = (P_IW_P2P_IOCTL_START_FORMATION) NULL; -+ -+ do { -+ if ((prDev == NULL) || (extra == NULL)) { -+ ASSERT(FALSE); -+ i4Status = -EINVAL; -+ break; -+ } -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ prIoctlStartFormation = (P_IW_P2P_IOCTL_START_FORMATION) extra; -+ -+ if (prGlueInfo == NULL) { -+ i4Status = -EINVAL; -+ break; -+ } -+ -+ prAdapter = prGlueInfo->prAdapter; -+ -+ if (prAdapter == NULL) { -+ i4Status = -EINVAL; -+ break; -+ } -+ -+ } while (FALSE); -+ -+ return i4Status; -+ -+} -+ -+/* mtk_p2p_wext_start_formation */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief P2P Private I/O Control handler (IOC_P2P_SET_INT) -+* -+* \param[in] prDev Net device requested. -+* \param[inout] wrqu Pointer to iwreq_data -+* -+* \retval 0 Success. -+* \retval -EFAULT Setting parameters to driver fail. -+* \retval -EOPNOTSUPP Setting parameters not support. -+* -+* \note -+*/ -+/*----------------------------------------------------------------------------*/ -+int -+mtk_p2p_wext_set_int(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) -+{ -+ int status = 0; -+ UINT_32 u4SubCmd = 0; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ UINT_32 index; -+ INT_32 value; -+ PUINT_32 pu4IntBuf; -+ P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo = (P_P2P_SPECIFIC_BSS_INFO_T) NULL; -+ P_P2P_CONNECTION_SETTINGS_T prP2pConnSettings = (P_P2P_CONNECTION_SETTINGS_T) NULL; -+ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; -+ UINT_32 u4Leng; -+ -+ ASSERT(prDev); -+ ASSERT(wrqu); -+ -+ /* printk("mtk_p2p_wext_set_int\n"); */ -+ pu4IntBuf = (PUINT_32) extra; -+ -+ if (FALSE == GLUE_CHK_PR2(prDev, wrqu)) -+ return -EINVAL; -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ ASSERT(prGlueInfo); -+ -+ prP2pSpecificBssInfo = prGlueInfo->prAdapter->rWifiVar.prP2pSpecificBssInfo; -+ prP2pConnSettings = prGlueInfo->prAdapter->rWifiVar.prP2PConnSettings; -+ prP2pFsmInfo = prGlueInfo->prAdapter->rWifiVar.prP2pFsmInfo; -+ -+ u4SubCmd = (UINT_32) wrqu->mode; -+ index = pu4IntBuf[1]; -+ value = pu4IntBuf[2]; -+ -+ DBGLOG(P2P, INFO, "set parameter, u4SubCmd=%d idx=%d value=%d\n", (INT_16) u4SubCmd, (INT_16) index, value); -+ -+ switch (u4SubCmd) { -+ case PRIV_CMD_INT_P2P_SET: -+ switch (index) { -+ case 0: /* Listen CH */ -+ { -+ UINT_8 ucSuggestChnl = 0; -+ -+ prP2pConnSettings->ucListenChnl = value; -+ -+ /* 20110920 - frog: User configurations are placed in ConnSettings. */ -+ if (rlmFuncFindAvailableChannel -+ (prGlueInfo->prAdapter, value, &ucSuggestChnl, TRUE, TRUE)) { -+ prP2pSpecificBssInfo->ucListenChannel = value; -+ } else { -+ prP2pSpecificBssInfo->ucListenChannel = ucSuggestChnl; -+ } -+ -+ break; -+ } -+ case 1: /* P2p mode */ -+ break; -+ case 4: /* Noa duration */ -+ prP2pSpecificBssInfo->rNoaParam.u4NoaDurationMs = value; -+ /* only to apply setting when setting NOA count */ -+ /* status = mtk_p2p_wext_set_noa_param(prDev, info, wrqu, -+ (char *)&prP2pSpecificBssInfo->rNoaParam); */ -+ break; -+ case 5: /* Noa interval */ -+ prP2pSpecificBssInfo->rNoaParam.u4NoaIntervalMs = value; -+ /* only to apply setting when setting NOA count */ -+ /* status = mtk_p2p_wext_set_noa_param(prDev, info, wrqu, -+ (char *)&prP2pSpecificBssInfo->rNoaParam); */ -+ break; -+ case 6: /* Noa count */ -+ prP2pSpecificBssInfo->rNoaParam.u4NoaCount = value; -+ status = -+ mtk_p2p_wext_set_noa_param(prDev, info, wrqu, (char *)&prP2pSpecificBssInfo->rNoaParam); -+ break; -+ case 100: /* Oper CH */ -+ /* 20110920 - frog: User configurations are placed in ConnSettings. */ -+ prP2pConnSettings->ucOperatingChnl = value; -+ break; -+ case 101: /* Local config Method, for P2P SDK */ -+ /* prP2pConnSettings->u2LocalConfigMethod; */ -+ break; -+ case 102: /* Sigma P2p reset */ -+ kalMemZero(prP2pConnSettings->aucTargetDevAddr, MAC_ADDR_LEN); -+ /* prP2pConnSettings->eConnectionPolicy = ENUM_P2P_CONNECTION_POLICY_AUTO; */ -+ break; -+ case 103: /* WPS MODE */ -+ kalP2PSetWscMode(prGlueInfo, value); -+ break; -+ case 104: /* P2p send persence, duration */ -+ break; -+ case 105: /* P2p send persence, interval */ -+ break; -+ case 106: /* P2P set sleep */ -+ value = 1; -+ kalIoctl(prGlueInfo, -+ wlanoidSetP2pPowerSaveProfile, -+ &value, sizeof(value), FALSE, FALSE, TRUE, TRUE, &u4Leng); -+ break; -+ case 107: /* P2P set opps, CTWindowl */ -+ prP2pSpecificBssInfo->rOppPsParam.u4CTwindowMs = value; -+ status = -+ mtk_p2p_wext_set_oppps_param(prDev, info, wrqu, (char *)&prP2pSpecificBssInfo->rOppPsParam); -+ break; -+ case 108: /* p2p_set_power_save */ -+ kalIoctl(prGlueInfo, -+ wlanoidSetP2pPowerSaveProfile, -+ &value, sizeof(value), FALSE, FALSE, TRUE, TRUE, &u4Leng); -+ -+ break; -+ -+ default: -+ break; -+ } -+ break; -+ default: -+ break; -+ } -+ -+ return status; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief P2P Private I/O Control handler (IOC_P2P_SET_STRUCT) -+* -+* \param[in] prDev Net device requested. -+* \param[inout] wrqu Pointer to iwreq_data -+* -+* \retval 0 Success. -+* \retval -EFAULT Setting parameters to driver fail. -+* \retval -EOPNOTSUPP Key size not supported. -+* -+* \note -+*/ -+/*----------------------------------------------------------------------------*/ -+int -+mtk_p2p_wext_set_struct(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) -+{ -+ int status = 0; -+ UINT_32 u4SubCmd = 0; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ P_IW_P2P_TRANSPORT_STRUCT prP2PReq = NULL; -+ -+ ASSERT(prDev); -+ ASSERT(wrqu); -+ -+ if (FALSE == GLUE_CHK_PR2(prDev, wrqu)) -+ return -EINVAL; -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ ASSERT(prGlueInfo); -+ -+ u4SubCmd = (UINT_32) wrqu->data.flags; -+ -+ kalMemZero(&prGlueInfo->prP2PInfo->aucOidBuf[0], sizeof(prGlueInfo->prP2PInfo->aucOidBuf)); -+ -+ switch (u4SubCmd) { -+ case PRIV_CMD_OID: -+ if (copy_from_user(&(prGlueInfo->prP2PInfo->aucOidBuf[0]), wrqu->data.pointer, wrqu->data.length)) { -+ status = -EFAULT; -+ break; -+ } -+ -+ if (!kalMemCmp(&(prGlueInfo->prP2PInfo->aucOidBuf[0]), extra, wrqu->data.length)) -+ DBGLOG(P2P, INFO, "extra buffer is valid\n"); -+ else -+ DBGLOG(P2P, INFO, "extra 0x%p\n", extra); -+ -+ prP2PReq = (P_IW_P2P_TRANSPORT_STRUCT) (&(prGlueInfo->prP2PInfo->aucOidBuf[0])); -+ switch (prP2PReq->u4CmdId) { -+ case P2P_CMD_ID_SEND_SD_RESPONSE: -+ status = mtk_p2p_wext_send_service_discovery_response(prDev, info, wrqu, (char *)prP2PReq); -+ break; -+ -+ case P2P_CMD_ID_SEND_SD_REQUEST: -+ status = mtk_p2p_wext_send_service_discovery_request(prDev, info, wrqu, (char *)prP2PReq); -+ break; -+ -+ case P2P_CMD_ID_TERMINATE_SD_PHASE: -+ status = mtk_p2p_wext_terminate_service_discovery_phase(prDev, info, wrqu, (char *)prP2PReq); -+ break; -+ -+ case P2P_CMD_ID_INVITATION: -+ if (prP2PReq->inBufferLength == sizeof(IW_P2P_IOCTL_INVITATION_STRUCT)) { -+ /* Do nothing */ -+ /* status = mtk_p2p_wext_invitation_request(prDev, info, wrqu, -+ (char *)(prP2PReq->aucBuffer)); */ -+ } -+ break; -+ -+ case P2P_CMD_ID_INVITATION_ABORT: -+ if (prP2PReq->inBufferLength == sizeof(IW_P2P_IOCTL_ABORT_INVITATION)) { -+ /* Do nothing */ -+ /* status = mtk_p2p_wext_invitation_abort(prDev, info, wrqu, -+ (char *)(prP2PReq->aucBuffer)); */ -+ } -+ break; -+ -+ case P2P_CMD_ID_START_FORMATION: -+ if (prP2PReq->inBufferLength == sizeof(IW_P2P_IOCTL_START_FORMATION)) -+ status = mtk_p2p_wext_start_formation(prDev, info, wrqu, (char *)(prP2PReq->aucBuffer)); -+ break; -+ default: -+ status = -EOPNOTSUPP; -+ } -+ -+ break; -+#if CFG_SUPPORT_ANTI_PIRACY -+ case PRIV_SEC_CHECK_OID: -+ if (wrqu->data.length > 256) { -+ status = -EOPNOTSUPP; -+ break; -+ } -+ if (copy_from_user(&(prGlueInfo->prP2PInfo->aucSecCheck[0]), wrqu->data.pointer, wrqu->data.length)) { -+ status = -EFAULT; -+ break; -+ } -+ -+ if (!kalMemCmp(&(prGlueInfo->prP2PInfo->aucSecCheck[0]), extra, wrqu->data.length)) -+ DBGLOG(P2P, INFO, "extra buffer is valid\n"); -+ else -+ DBGLOG(P2P, INFO, "extra 0x%p\n", extra); -+ prP2PReq = (P_IW_P2P_TRANSPORT_STRUCT) (&(prGlueInfo->prP2PInfo->aucSecCheck[0])); -+ -+ switch (prP2PReq->u4CmdId) { -+ case P2P_CMD_ID_SEC_CHECK: -+ status = mtk_p2p_wext_set_sec_check_request(prDev, info, wrqu, (char *)prP2PReq); -+ break; -+ default: -+ status = -EOPNOTSUPP; -+ } -+ break; -+#endif -+ case PRIV_CMD_P2P_VERSION: -+ if (copy_from_user(&(prGlueInfo->prP2PInfo->aucOidBuf[0]), wrqu->data.pointer, wrqu->data.length)) { -+ status = -EFAULT; -+ break; -+ } -+ -+ if (!kalMemCmp(&(prGlueInfo->prP2PInfo->aucOidBuf[0]), extra, wrqu->data.length)) -+ DBGLOG(P2P, INFO, "extra buffer is valid\n"); -+ else -+ DBGLOG(P2P, INFO, "extra 0x%p\n", extra); -+ -+ prP2PReq = (P_IW_P2P_TRANSPORT_STRUCT) (&(prGlueInfo->prP2PInfo->aucOidBuf[0])); -+ switch (prP2PReq->u4CmdId) { -+ case P2P_CMD_ID_P2P_VERSION: -+ status = mtk_p2p_wext_set_p2p_version(prDev, info, wrqu, (char *)prP2PReq); -+ break; -+ default: -+ status = -EOPNOTSUPP; -+ break; -+ } -+ break; -+ default: -+ status = -EOPNOTSUPP; -+ break; -+ } -+ -+ return status; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief P2P Private I/O Control handler (IOC_P2P_GET_STRUCT) -+* -+* \param[in] prDev Net device requested. -+* \param[inout] wrqu Pointer to iwreq_data -+* -+* \retval 0 Success. -+* \retval -EFAULT Setting parameters to driver fail. -+* \retval -EOPNOTSUPP Key size not supported. -+* -+* \note -+*/ -+/*----------------------------------------------------------------------------*/ -+int -+mtk_p2p_wext_get_struct(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) -+{ -+ int status = 0; -+ UINT_32 u4SubCmd = 0; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ P_IW_P2P_TRANSPORT_STRUCT prP2PReq = NULL; -+ -+ ASSERT(prDev); -+ ASSERT(wrqu); -+ -+ if (!prDev || !wrqu) { -+ DBGLOG(P2P, WARN, "%s(): invalid param(0x%p, 0x%p)\n", __func__, prDev, wrqu); -+ return -EINVAL; -+ } -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ ASSERT(prGlueInfo); -+ -+ u4SubCmd = (UINT_32) wrqu->data.flags; -+ -+ kalMemZero(&(prGlueInfo->prP2PInfo->aucOidBuf[0]), sizeof(prGlueInfo->prP2PInfo->aucOidBuf)); -+ -+ switch (u4SubCmd) { -+ case PRIV_CMD_OID: -+ if (copy_from_user(&(prGlueInfo->prP2PInfo->aucOidBuf[0]), -+ wrqu->data.pointer, sizeof(IW_P2P_TRANSPORT_STRUCT))) { -+ DBGLOG(P2P, ERROR, "%s() copy_from_user oidBuf fail\n", __func__); -+ return -EFAULT; -+ } -+ -+ prP2PReq = (P_IW_P2P_TRANSPORT_STRUCT) (&(prGlueInfo->prP2PInfo->aucOidBuf[0])); -+ -+ switch (prP2PReq->u4CmdId) { -+ case P2P_CMD_ID_GET_SD_REQUEST: -+ status = mtk_p2p_wext_get_service_discovery_request(prDev, info, wrqu, (char *)prP2PReq); -+ break; -+ -+ case P2P_CMD_ID_GET_SD_RESPONSE: -+ status = mtk_p2p_wext_get_service_discovery_response(prDev, info, wrqu, (char *)prP2PReq); -+ break; -+ -+ case P2P_CMD_ID_INVITATION_INDICATE: -+ { -+ status = -+ mtk_p2p_wext_invitation_indicate(prDev, info, wrqu, (char *)(prP2PReq->aucBuffer)); -+ prP2PReq->outBufferLength = wrqu->data.length; -+ if (copy_to_user(wrqu->data.pointer, -+ &(prGlueInfo->prP2PInfo->aucOidBuf[0]), -+ wrqu->data.length + OFFSET_OF(IW_P2P_TRANSPORT_STRUCT, aucBuffer))) { -+ DBGLOG(P2P, ERROR, "%s() copy_to_user() fail\n", __func__); -+ return -EIO; -+ } else { -+ return 0; -+ } -+ break; -+ } -+ case P2P_CMD_ID_INVITATION_STATUS: -+ { -+ status = -+ mtk_p2p_wext_invitation_status(prDev, info, wrqu, (char *)(prP2PReq->aucBuffer)); -+ prP2PReq->outBufferLength = wrqu->data.length; -+ if (copy_to_user(wrqu->data.pointer, -+ &(prGlueInfo->prP2PInfo->aucOidBuf[0]), -+ wrqu->data.length + OFFSET_OF(IW_P2P_TRANSPORT_STRUCT, aucBuffer))) { -+ DBGLOG(P2P, ERROR, "%s() copy_to_user() fail\n", __func__); -+ return -EIO; -+ } else { -+ return 0; -+ } -+ break; -+ } -+ case P2P_CMD_ID_GET_CH_LIST: -+ { -+ UINT_16 i; -+ UINT_8 NumOfChannel = 50; -+ RF_CHANNEL_INFO_T aucChannelList[50]; -+ UINT_8 ucMaxChannelNum = 50; -+ PUINT_8 pucChnlList = (PUINT_8) prP2PReq->aucBuffer; -+ -+ kalGetChnlList(prGlueInfo, BAND_NULL, ucMaxChannelNum, &NumOfChannel, aucChannelList); -+ if (NumOfChannel > 50) -+ NumOfChannel = 50; -+ prP2PReq->outBufferLength = NumOfChannel; -+ /*here must confirm NumOfChannel < 16, for prP2PReq->aucBuffer 16 byte*/ -+ if (NumOfChannel >= 15) { -+ /*DBGLOG(P2P, ERROR, "channel num > 15\n", __func__);*/ -+ ASSERT(FALSE); -+ } -+ -+ for (i = 0; i < NumOfChannel; i++) { -+#if 0 -+ /* 20120208 frog: modify to avoid clockwork warning. */ -+ prP2PReq->aucBuffer[i] = aucChannelList[i].ucChannelNum; -+#else -+ *pucChnlList = aucChannelList[i].ucChannelNum; -+ pucChnlList++; -+#endif -+ } -+ if (copy_to_user(wrqu->data.pointer, -+ &(prGlueInfo->prP2PInfo->aucOidBuf[0]), -+ NumOfChannel + OFFSET_OF(IW_P2P_TRANSPORT_STRUCT, aucBuffer))) { -+ DBGLOG(P2P, ERROR, "%s() copy_to_user() fail\n", __func__); -+ return -EIO; -+ } else { -+ return 0; -+ } -+ break; -+ } -+ -+ case P2P_CMD_ID_GET_OP_CH: -+ { -+ prP2PReq->inBufferLength = 4; -+ -+ status = wlanoidQueryP2pOpChannel(prGlueInfo->prAdapter, -+ prP2PReq->aucBuffer, -+ prP2PReq->inBufferLength, &prP2PReq->outBufferLength); -+ -+ if (status == 0) { /* WLAN_STATUS_SUCCESS */ -+ if (copy_to_user(wrqu->data.pointer, -+ &(prGlueInfo->prP2PInfo->aucOidBuf[0]), -+ prP2PReq->outBufferLength + OFFSET_OF(IW_P2P_TRANSPORT_STRUCT, -+ aucBuffer))) { -+ DBGLOG(P2P, ERROR, "%s() copy_to_user() fail\n", __func__); -+ return -EIO; -+ } -+ } else { -+ if (copy_to_user(wrqu->data.pointer, -+ &(prGlueInfo->prP2PInfo->aucOidBuf[0]), -+ OFFSET_OF(IW_P2P_TRANSPORT_STRUCT, aucBuffer))) { -+ DBGLOG(P2P, ERROR, "%s() copy_to_user() fail\n", __func__); -+ return -EIO; -+ } -+ } -+ break; -+ } -+ -+ default: -+ status = -EOPNOTSUPP; -+ } -+ -+ break; -+#if CFG_SUPPORT_ANTI_PIRACY -+ case PRIV_SEC_CHECK_OID: -+ if (wrqu->data.length > 256) { -+ status = -EOPNOTSUPP; -+ break; -+ } -+ if (copy_from_user(&(prGlueInfo->prP2PInfo->aucSecCheck[0]), -+ wrqu->data.pointer, sizeof(IW_P2P_TRANSPORT_STRUCT))) { -+ DBGLOG(P2P, ERROR, "%s() copy_from_user oidBuf fail\n", __func__); -+ return -EFAULT; -+ } -+ -+ prP2PReq = (P_IW_P2P_TRANSPORT_STRUCT) (&(prGlueInfo->prP2PInfo->aucSecCheck[0])); -+ -+ switch (prP2PReq->u4CmdId) { -+ case P2P_CMD_ID_SEC_CHECK: -+ status = mtk_p2p_wext_get_sec_check_response(prDev, info, wrqu, (char *)prP2PReq); -+ break; -+ default: -+ status = -EOPNOTSUPP; -+ } -+ break; -+#endif -+ case PRIV_CMD_P2P_VERSION: -+ if (copy_from_user(&(prGlueInfo->prP2PInfo->aucOidBuf[0]), -+ wrqu->data.pointer, sizeof(IW_P2P_TRANSPORT_STRUCT))) { -+ DBGLOG(P2P, ERROR, "%s() copy_from_user oidBuf fail\n", __func__); -+ return -EFAULT; -+ } -+ -+ prP2PReq = (P_IW_P2P_TRANSPORT_STRUCT) (&(prGlueInfo->prP2PInfo->aucOidBuf[0])); -+ -+ switch (prP2PReq->u4CmdId) { -+ case P2P_CMD_ID_P2P_VERSION: -+ status = mtk_p2p_wext_get_p2p_version(prDev, info, wrqu, (char *)prP2PReq); -+ break; -+ default: -+ status = -EOPNOTSUPP; -+ break; -+ } -+ -+ /* Copy queried data to user. */ -+ if (status == 0) { /* WLAN_STATUS_SUCCESS */ -+ if (copy_to_user(wrqu->data.pointer, -+ &(prGlueInfo->prP2PInfo->aucOidBuf[0]), -+ prP2PReq->outBufferLength + OFFSET_OF(IW_P2P_TRANSPORT_STRUCT, aucBuffer))) { -+ DBGLOG(P2P, ERROR, "%s() copy_to_user() fail\n", __func__); -+ return -EIO; -+ } -+ } -+ -+ else { -+ if (copy_to_user(wrqu->data.pointer, -+ &(prGlueInfo->prP2PInfo->aucOidBuf[0]), -+ OFFSET_OF(IW_P2P_TRANSPORT_STRUCT, aucBuffer))) { -+ DBGLOG(P2P, ERROR, "%s() copy_to_user() fail\n", __func__); -+ return -EIO; -+ } -+ } -+ -+ break; -+ default: -+ return -EOPNOTSUPP; -+ } -+ -+ return status; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief P2P Private I/O Control handler for -+* getting service discovery request frame from driver -+* -+* \param[in] prDev Net device requested. -+* \param[inout] wrqu Pointer to iwreq_data -+* -+* \retval 0 Success. -+* \retval -EFAULT Setting parameters to driver fail. -+* \retval -EOPNOTSUPP Key size not supported. -+* -+* \note -+*/ -+/*----------------------------------------------------------------------------*/ -+int -+mtk_p2p_wext_get_service_discovery_request(IN struct net_device *prDev, -+ IN struct iw_request_info *info, -+ IN OUT union iwreq_data *wrqu, IN OUT char *extra) -+{ -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ UINT_32 u4QueryInfoLen = 0; -+ P_IW_P2P_TRANSPORT_STRUCT prP2PReq = (P_IW_P2P_TRANSPORT_STRUCT) extra; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ -+ ASSERT(prDev); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ ASSERT(prGlueInfo); -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidGetP2PSDRequest, -+ prP2PReq->aucBuffer, prP2PReq->outBufferLength, TRUE, FALSE, TRUE, TRUE, &u4QueryInfoLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) -+ return -EFAULT; -+ -+ prP2PReq->outBufferLength = u4QueryInfoLen; -+ -+ if (copy_to_user(wrqu->data.pointer, -+ &(prGlueInfo->prP2PInfo->aucOidBuf[0]), -+ u4QueryInfoLen + OFFSET_OF(IW_P2P_TRANSPORT_STRUCT, aucBuffer))) { -+ DBGLOG(P2P, ERROR, "%s() copy_to_user() fail\n", __func__); -+ return -EIO; -+ } else { -+ return 0; -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief P2P Private I/O Control handler for -+* getting service discovery response frame from driver -+* -+* \param[in] prDev Net device requested. -+* \param[inout] wrqu Pointer to iwreq_data -+* -+* \retval 0 Success. -+* \retval -EFAULT Setting parameters to driver fail. -+* \retval -EOPNOTSUPP Key size not supported. -+* -+* \note -+*/ -+/*----------------------------------------------------------------------------*/ -+int -+mtk_p2p_wext_get_service_discovery_response(IN struct net_device *prDev, -+ IN struct iw_request_info *info, -+ IN OUT union iwreq_data *wrqu, IN OUT char *extra) -+{ -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ UINT_32 u4QueryInfoLen = 0; -+ P_IW_P2P_TRANSPORT_STRUCT prP2PReq = (P_IW_P2P_TRANSPORT_STRUCT) extra; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ -+ ASSERT(prDev); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ ASSERT(prGlueInfo); -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidGetP2PSDResponse, -+ prP2PReq->aucBuffer, prP2PReq->outBufferLength, TRUE, FALSE, TRUE, TRUE, &u4QueryInfoLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) -+ return -EFAULT; -+ -+ prP2PReq->outBufferLength = u4QueryInfoLen; -+ -+ if (copy_to_user(wrqu->data.pointer, -+ &(prGlueInfo->prP2PInfo->aucOidBuf[0]), -+ u4QueryInfoLen + OFFSET_OF(IW_P2P_TRANSPORT_STRUCT, aucBuffer))) { -+ DBGLOG(P2P, ERROR, "%s() copy_to_user() fail\n", __func__); -+ return -EIO; -+ } -+ return 0; -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief P2P Private I/O Control handler for -+* sending service discovery request frame -+* -+* \param[in] prDev Net device requested. -+* \param[inout] wrqu Pointer to iwreq_data -+* -+* \retval 0 Success. -+* \retval -EFAULT Setting parameters to driver fail. -+* \retval -EOPNOTSUPP Key size not supported. -+* -+* \note -+*/ -+/*----------------------------------------------------------------------------*/ -+int -+mtk_p2p_wext_send_service_discovery_request(IN struct net_device *prDev, -+ IN struct iw_request_info *info, -+ IN OUT union iwreq_data *wrqu, IN OUT char *extra) -+{ -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ UINT_32 u4SetInfoLen; -+ P_IW_P2P_TRANSPORT_STRUCT prP2PReq = (P_IW_P2P_TRANSPORT_STRUCT) extra; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ -+ ASSERT(prDev); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ ASSERT(prGlueInfo); -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSendP2PSDRequest, -+ prP2PReq->aucBuffer, prP2PReq->inBufferLength, FALSE, FALSE, TRUE, TRUE, &u4SetInfoLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) -+ return -EFAULT; -+ else -+ return 0; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief P2P Private I/O Control handler for -+* sending service discovery response frame -+* -+* \param[in] prDev Net device requested. -+* \param[inout] wrqu Pointer to iwreq_data -+* -+* \retval 0 Success. -+* \retval -EFAULT Setting parameters to driver fail. -+* \retval -EOPNOTSUPP Key size not supported. -+* -+* \note -+*/ -+/*----------------------------------------------------------------------------*/ -+int -+mtk_p2p_wext_send_service_discovery_response(IN struct net_device *prDev, -+ IN struct iw_request_info *info, -+ IN OUT union iwreq_data *wrqu, IN OUT char *extra) -+{ -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ UINT_32 u4SetInfoLen; -+ P_IW_P2P_TRANSPORT_STRUCT prP2PReq = (P_IW_P2P_TRANSPORT_STRUCT) extra; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ -+ ASSERT(prDev); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ ASSERT(prGlueInfo); -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSendP2PSDResponse, -+ prP2PReq->aucBuffer, prP2PReq->inBufferLength, FALSE, FALSE, TRUE, TRUE, &u4SetInfoLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) -+ return -EFAULT; -+ else -+ return 0; -+} -+ -+#if CFG_SUPPORT_ANTI_PIRACY -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief P2P Private I/O Control handler for -+* -+* \param[in] prDev Net device requested. -+* \param[inout] wrqu Pointer to iwreq_data -+* -+* \retval 0 Success. -+* \retval -EFAULT Setting parameters to driver fail. -+* \retval -EOPNOTSUPP Key size not supported. -+* -+* \note -+*/ -+/*----------------------------------------------------------------------------*/ -+int -+mtk_p2p_wext_set_sec_check_request(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) -+{ -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ UINT_32 u4SetInfoLen; -+ P_IW_P2P_TRANSPORT_STRUCT prP2PReq = (P_IW_P2P_TRANSPORT_STRUCT) extra; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ -+ ASSERT(prDev); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ ASSERT(prGlueInfo); -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetSecCheckRequest, -+ prP2PReq->aucBuffer, prP2PReq->inBufferLength, FALSE, FALSE, TRUE, TRUE, &u4SetInfoLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) -+ return -EFAULT; -+ else -+ return 0; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief P2P Private I/O Control handler for -+* -+* \param[in] prDev Net device requested. -+* \param[inout] wrqu Pointer to iwreq_data -+* -+* \retval 0 Success. -+* \retval -EFAULT Setting parameters to driver fail. -+* \retval -EOPNOTSUPP Key size not supported. -+* -+* \note -+*/ -+/*----------------------------------------------------------------------------*/ -+int -+mtk_p2p_wext_get_sec_check_response(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) -+{ -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ UINT_32 u4QueryInfoLen = 0; -+ P_IW_P2P_TRANSPORT_STRUCT prP2PReq = (P_IW_P2P_TRANSPORT_STRUCT) extra; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ -+ ASSERT(prDev); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ ASSERT(prGlueInfo); -+ -+ DBGLOG(P2P, INFO, "mtk_p2p_wext_get_sec_check_response\n"); -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidGetSecCheckResponse, -+ prP2PReq->aucBuffer, prP2PReq->outBufferLength, TRUE, FALSE, TRUE, TRUE, &u4QueryInfoLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) -+ return -EFAULT; -+ -+ prP2PReq->outBufferLength = u4QueryInfoLen; -+ -+ if (copy_to_user(wrqu->data.pointer, -+ prP2PReq->aucBuffer, u4QueryInfoLen + OFFSET_OF(IW_P2P_TRANSPORT_STRUCT, aucBuffer))) { -+ DBGLOG(P2P, ERROR, "%s() copy_to_user() fail\n", __func__); -+ return -EIO; -+ } -+ return 0; -+ -+} -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief P2P Private I/O Control handler for -+* terminating service discovery phase -+* -+* \param[in] prDev Net device requested. -+* \param[inout] wrqu Pointer to iwreq_data -+* -+* \retval 0 Success. -+* \retval -EFAULT Setting parameters to driver fail. -+* \retval -EOPNOTSUPP Key size not supported. -+* -+* \note -+*/ -+/*----------------------------------------------------------------------------*/ -+int -+mtk_p2p_wext_terminate_service_discovery_phase(IN struct net_device *prDev, -+ IN struct iw_request_info *info, -+ IN OUT union iwreq_data *wrqu, IN OUT char *extra) -+{ -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ UINT_32 u4SetInfoLen; -+ P_IW_P2P_TRANSPORT_STRUCT prP2PReq = (P_IW_P2P_TRANSPORT_STRUCT) extra; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ -+ ASSERT(prDev); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ ASSERT(prGlueInfo); -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetP2PTerminateSDPhase, -+ prP2PReq->aucBuffer, prP2PReq->inBufferLength, FALSE, FALSE, TRUE, TRUE, &u4SetInfoLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) -+ return -EFAULT; -+ else -+ return 0; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief P2P Private I/O Control handler for -+* -+* \param[in] prDev Net device requested. -+* \param[inout] wrqu Pointer to iwreq_data -+* -+* \retval 0 Success. -+* \retval -EFAULT Setting parameters to driver fail. -+* \retval -EOPNOTSUPP Key size not supported. -+* -+* \note -+*/ -+/*----------------------------------------------------------------------------*/ -+int -+mtk_p2p_wext_set_noa_param(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) -+{ -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ UINT_32 u4SetInfoLen; -+ /* P_IW_P2P_TRANSPORT_STRUCT prP2PReq = (P_IW_P2P_TRANSPORT_STRUCT)extra; */ -+ P_PARAM_CUSTOM_NOA_PARAM_STRUCT_T prNoaParam = (P_PARAM_CUSTOM_NOA_PARAM_STRUCT_T) extra; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ -+ ASSERT(prDev); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ ASSERT(prGlueInfo); -+ -+ DBGLOG(P2P, INFO, "mtk_p2p_wext_set_noa_param\n"); -+ -+ rStatus = kalIoctl(prGlueInfo, wlanoidSetNoaParam, prNoaParam, /* prP2PReq->aucBuffer, */ -+ sizeof(PARAM_CUSTOM_NOA_PARAM_STRUCT_T), /* prP2PReq->inBufferLength, */ -+ FALSE, FALSE, TRUE, TRUE, &u4SetInfoLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) -+ return -EFAULT; -+ else -+ return 0; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief P2P Private I/O Control handler for -+* -+* \param[in] prDev Net device requested. -+* \param[inout] wrqu Pointer to iwreq_data -+* -+* \retval 0 Success. -+* \retval -EFAULT Setting parameters to driver fail. -+* \retval -EOPNOTSUPP Key size not supported. -+* -+* \note -+*/ -+/*----------------------------------------------------------------------------*/ -+int -+mtk_p2p_wext_set_oppps_param(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) -+{ -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ UINT_32 u4SetInfoLen; -+/* P_IW_P2P_TRANSPORT_STRUCT prP2PReq = (P_IW_P2P_TRANSPORT_STRUCT)extra; */ -+ P_PARAM_CUSTOM_OPPPS_PARAM_STRUCT_T prOppPsParam = (P_PARAM_CUSTOM_OPPPS_PARAM_STRUCT_T) extra; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ -+ ASSERT(prDev); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ ASSERT(prGlueInfo); -+ -+ DBGLOG(P2P, INFO, "mtk_p2p_wext_set_oppps_param\n"); -+ -+ rStatus = kalIoctl(prGlueInfo, wlanoidSetOppPsParam, prOppPsParam, /* prP2PReq->aucBuffer, */ -+ sizeof(PARAM_CUSTOM_OPPPS_PARAM_STRUCT_T), /* prP2PReq->inBufferLength, */ -+ FALSE, FALSE, TRUE, TRUE, &u4SetInfoLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) -+ return -EFAULT; -+ else -+ return 0; -+} -+ -+int -+mtk_p2p_wext_set_p2p_version(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) -+{ -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ P_IW_P2P_TRANSPORT_STRUCT prP2PReq = (P_IW_P2P_TRANSPORT_STRUCT) extra; -+ UINT_32 u4SetInfoLen; -+ -+ ASSERT(prDev); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ ASSERT(prGlueInfo); -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetP2pSupplicantVersion, -+ prP2PReq->aucBuffer, prP2PReq->inBufferLength, FALSE, FALSE, TRUE, TRUE, &u4SetInfoLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) -+ return -EFAULT; -+ else -+ return rStatus; -+ -+} -+ -+/* mtk_p2p_wext_set_p2p_version */ -+ -+int -+mtk_p2p_wext_get_p2p_version(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) -+{ -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ UINT_32 u4QueryInfoLen; -+ P_IW_P2P_TRANSPORT_STRUCT prP2PReq = (P_IW_P2P_TRANSPORT_STRUCT) extra; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ -+ ASSERT(prDev); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ ASSERT(prGlueInfo); -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidQueryP2pVersion, -+ prP2PReq->aucBuffer, prP2PReq->outBufferLength, TRUE, FALSE, TRUE, TRUE, &u4QueryInfoLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) -+ return -EFAULT; -+ else -+ return rStatus; -+ -+} /* mtk_p2p_wext_get_p2p_version */ -+ -+#if CFG_SUPPORT_P2P_RSSI_QUERY -+ -+int -+mtk_p2p_wext_get_rssi(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) -+{ -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ UINT_32 u4QueryInfoLen; -+ struct iw_point *prData = (struct iw_point *)&wrqu->data; -+ UINT_16 u2BufferSize = 0; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ INT_32 i4Rssi; -+ struct iw_statistics *pStats = NULL; -+ -+ ASSERT(prDev); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ ASSERT(prGlueInfo); -+ -+ if (!prGlueInfo) { -+ rStatus = WLAN_STATUS_FAILURE; -+ goto stat_out; -+ } -+ -+ pStats = (struct iw_statistics *)(&(prGlueInfo->rP2pIwStats)); -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidQueryP2pRssi, &i4Rssi, sizeof(i4Rssi), TRUE, TRUE, TRUE, TRUE, &u4QueryInfoLen); -+ -+ u2BufferSize = prData->length; -+ -+ if (u2BufferSize < sizeof(struct iw_statistics)) -+ return -E2BIG; -+ -+ if (copy_to_user(prData->pointer, pStats, sizeof(struct iw_statistics))) -+ rStatus = WLAN_STATUS_FAILURE; -+ -+stat_out: -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) -+ return -EFAULT; -+ else -+ return rStatus; -+ -+} /* mtk_p2p_wext_get_rssi */ -+ -+struct iw_statistics *mtk_p2p_wext_get_wireless_stats(struct net_device *prDev) -+{ -+ WLAN_STATUS rStatus = WLAN_STATUS_FAILURE; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ struct iw_statistics *pStats = NULL; -+ INT_32 i4Rssi; -+ UINT_32 bufLen = 0; -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ ASSERT(prGlueInfo); -+ if (!prGlueInfo) -+ goto stat_out; -+ -+ pStats = (struct iw_statistics *)(&(prGlueInfo->rP2pIwStats)); -+ -+ if (!prDev || !netif_carrier_ok(prDev)) { -+ /* network not connected */ -+ goto stat_out; -+ } -+ -+ rStatus = kalIoctl(prGlueInfo, wlanoidQueryP2pRssi, &i4Rssi, sizeof(i4Rssi), TRUE, TRUE, TRUE, TRUE, &bufLen); -+ -+stat_out: -+ return pStats; -+} /* mtk_p2p_wext_get_wireless_stats */ -+ -+#endif /* CFG_SUPPORT_P2P_RSSI_QUERY */ -+ -+int -+mtk_p2p_wext_set_txpow(IN struct net_device *prDev, -+ IN struct iw_request_info *prIwrInfo, IN OUT union iwreq_data *prTxPow, IN char *pcExtra) -+{ -+ P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) NULL; -+ P_ADAPTER_T prAdapter = (P_ADAPTER_T) NULL; -+#if 0 -+ P_MSG_P2P_FUNCTION_SWITCH_T prMsgFuncSwitch = (P_MSG_P2P_FUNCTION_SWITCH_T) NULL; -+#endif -+ int i4Ret = 0; -+ -+ ASSERT(prDev); -+ ASSERT(prTxPow); -+ -+ do { -+ if ((!prDev) || (!prTxPow)) { -+ i4Ret = -EINVAL; -+ break; -+ } -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ -+ if (!prGlueInfo) { -+ i4Ret = -EINVAL; -+ break; -+ } -+ -+ prAdapter = prGlueInfo->prAdapter; -+#if 0 -+ prMsgFuncSwitch = -+ (P_MSG_P2P_FUNCTION_SWITCH_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, -+ sizeof(MSG_P2P_FUNCTION_SWITCH_T)); -+ if (!prMsgFuncSwitch) { -+ ASSERT(0); -+ return -ENOMEM; -+ } -+ -+ prMsgFuncSwitch->rMsgHdr.eMsgId = MID_MNY_P2P_FUN_SWITCH; -+ -+ if (prTxPow->disabled) { -+ /* Dissolve. */ -+ prMsgFuncSwitch->fgIsFuncOn = FALSE; -+ } else { -+ -+ /* Re-enable function. */ -+ prMsgFuncSwitch->fgIsFuncOn = TRUE; -+ } -+ -+ /* 1.3 send message */ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgFuncSwitch, MSG_SEND_METHOD_BUF); -+#endif -+ -+ } while (FALSE); -+ -+ return i4Ret; -+} /* mtk_p2p_wext_set_txpow */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_p2p_cfg80211.c b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_p2p_cfg80211.c -new file mode 100644 -index 000000000000..4d71e0c59b05 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_p2p_cfg80211.c -@@ -0,0 +1,1935 @@ -+/* -+** Id: @(#) gl_p2p_cfg80211.c@@ -+*/ -+ -+/*! \file gl_p2p_cfg80211.c -+ \brief Main routines of Linux driver interface for Wi-Fi Direct -+ using cfg80211 interface -+ -+ This file contains the main routines of Linux driver for MediaTek Inc. 802.11 -+ Wireless LAN Adapters. -+*/ -+ -+/* -+** Log: gl_p2p_cfg80211.c -+** -+** 01 30 2013 yuche.tsai -+** [ALPS00455459] [GN_WIFI]??wifi direct??????????? -+** Fix possible race condition under GO mode. -+** -+** 09 12 2012 wcpadmin -+** [ALPS00276400] Remove MTK copyright and legal header on GPL/LGPL related packages -+** . -+** -+** 09 05 2012 wh.su -+** [ALPS00351547] [6577JB][WiFi direct]The 3rd device fail to establish p2p connection with GO sometimes -+** sync with the ICS code. -+** -+** 08 31 2012 yuche.tsai -+** [ALPS00349585] [6577JB][WiFi direct][KE]Establish p2p connection while both device have connected to AP previously, -+** one device reboots automatically with KE -+** Fix possible KE when concurrent & disconnect. -+** -+** 08 21 2012 yuche.tsai -+** NULL -+** Fix compile warning. -+** -+** 08 20 2012 yuche.tsai -+** NULL -+** Fix possible KE issue. -+** -+** 08 17 2012 yuche.tsai -+** NULL -+** Fix compile warning. -+** -+** 08 16 2012 yuche.tsai -+** NULL -+** Fix compile warning. -+** -+** 08 14 2012 yuche.tsai -+** NULL -+** Fix p2p bug find on ALPS.JB trunk. -+** -+** 07 26 2012 yuche.tsai -+** [ALPS00324337] [ALPS.JB][Hot-Spot] Driver update for Hot-Spot -+** Update driver code of ALPS.JB for hot-spot. -+** -+** 07 19 2012 yuche.tsai -+** NULL -+** Code update for JB. -+ * -+ * 07 17 2012 yuche.tsai -+ * NULL -+ * Fix compile error for JB. -+ * -+ * 07 17 2012 yuche.tsai -+ * NULL -+ * Compile no error before trial run. -+ * -+ * 09 21 2010 kevin.huang -+ * [WCXRP00000054] [MT6620 Wi-Fi][Driver] Restructure driver for second Interface -+ * Isolate P2P related function for Hardware Software Bundle -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 05 31 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * add cfg80211 interface, which is to replace WE, for further extension -+ * -+** -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+#include "config.h" -+ -+#if CFG_ENABLE_WIFI_DIRECT && CFG_ENABLE_WIFI_DIRECT_CFG_80211 -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "precomp.h" -+#include "gl_cfg80211.h" -+#include "gl_p2p_ioctl.h" -+ -+#ifdef __GNUC__ -+#pragma GCC diagnostic ignored "-Wformat" -+#endif -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+BOOLEAN -+mtk_p2p_cfg80211func_channel_format_switch(IN struct ieee80211_channel *channel, -+ IN enum nl80211_channel_type channel_type, -+ IN P_RF_CHANNEL_INFO_T prRfChnlInfo, IN P_ENUM_CHNL_EXT_T prChnlSco); -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+int mtk_p2p_cfg80211_add_key(struct wiphy *wiphy, -+ struct net_device *ndev, -+ u8 key_index, bool pairwise, const u8 *mac_addr, struct key_params *params) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ INT_32 i4Rslt = -EINVAL; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ UINT_32 u4BufLen = 0; -+ P2P_PARAM_KEY_T rKey; -+ -+ ASSERT(wiphy); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); -+ -+ kalMemZero(&rKey, sizeof(P2P_PARAM_KEY_T)); -+ -+ rKey.u4KeyIndex = key_index; -+ if (mac_addr) { -+ ether_addr_copy(rKey.arBSSID, mac_addr); -+ if ((rKey.arBSSID[0] == 0x00) && (rKey.arBSSID[1] == 0x00) && (rKey.arBSSID[2] == 0x00) && -+ (rKey.arBSSID[3] == 0x00) && (rKey.arBSSID[4] == 0x00) && (rKey.arBSSID[5] == 0x00)) { -+ rKey.arBSSID[0] = 0xff; -+ rKey.arBSSID[1] = 0xff; -+ rKey.arBSSID[2] = 0xff; -+ rKey.arBSSID[3] = 0xff; -+ rKey.arBSSID[4] = 0xff; -+ rKey.arBSSID[5] = 0xff; -+ } -+ if (rKey.arBSSID[0] != 0xFF) { -+ rKey.u4KeyIndex |= BIT(31); -+ if ((rKey.arBSSID[0] != 0x00) || (rKey.arBSSID[1] != 0x00) || (rKey.arBSSID[2] != 0x00) || -+ (rKey.arBSSID[3] != 0x00) || (rKey.arBSSID[4] != 0x00) || (rKey.arBSSID[5] != 0x00)) -+ rKey.u4KeyIndex |= BIT(30); -+ } else { -+ rKey.u4KeyIndex |= BIT(31); -+ } -+ } else { -+ rKey.arBSSID[0] = 0xff; -+ rKey.arBSSID[1] = 0xff; -+ rKey.arBSSID[2] = 0xff; -+ rKey.arBSSID[3] = 0xff; -+ rKey.arBSSID[4] = 0xff; -+ rKey.arBSSID[5] = 0xff; -+ rKey.u4KeyIndex |= BIT(31); /* ???? */ -+ } -+ if (params->key) { -+ /* rKey.aucKeyMaterial[0] = kalMemAlloc(params->key_len, VIR_MEM_TYPE); */ -+ kalMemCopy(rKey.aucKeyMaterial, params->key, params->key_len); -+ } -+ rKey.u4KeyLength = params->key_len; -+ rKey.u4Length = ((ULONG)&(((P_P2P_PARAM_KEY_T) 0)->aucKeyMaterial)) + rKey.u4KeyLength; -+ -+ rStatus = kalIoctl(prGlueInfo, wlanoidSetAddP2PKey, &rKey, rKey.u4Length, FALSE, FALSE, TRUE, TRUE, &u4BufLen); -+ if (rStatus == WLAN_STATUS_SUCCESS) -+ i4Rslt = 0; -+ -+ return i4Rslt; -+} -+ -+int mtk_p2p_cfg80211_get_key(struct wiphy *wiphy, -+ struct net_device *ndev, -+ u8 key_index, -+ bool pairwise, -+ const u8 *mac_addr, void *cookie, void (*callback) (void *cookie, struct key_params *) -+) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ -+ ASSERT(wiphy); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); -+ -+ /* not implemented yet */ -+ -+ return -EINVAL; -+} -+ -+int mtk_p2p_cfg80211_del_key(struct wiphy *wiphy, -+ struct net_device *ndev, u8 key_index, bool pairwise, const u8 *mac_addr) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ PARAM_REMOVE_KEY_T prRemoveKey; -+ INT_32 i4Rslt = -EINVAL; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ UINT_32 u4BufLen = 0; -+ -+ ASSERT(wiphy); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); -+ -+ if (prGlueInfo->ulFlag & GLUE_FLAG_HALT) { -+ i4Rslt = 0; -+ return i4Rslt; -+ } -+ -+ kalMemZero(&prRemoveKey, sizeof(PARAM_REMOVE_KEY_T)); -+ if (mac_addr) -+ memcpy(prRemoveKey.arBSSID, mac_addr, PARAM_MAC_ADDR_LEN); -+ prRemoveKey.u4KeyIndex = key_index; -+ prRemoveKey.u4Length = sizeof(PARAM_REMOVE_KEY_T); -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetRemoveP2PKey, -+ &prRemoveKey, prRemoveKey.u4Length, FALSE, FALSE, TRUE, TRUE, &u4BufLen); -+ -+ if (rStatus == WLAN_STATUS_SUCCESS) -+ i4Rslt = 0; -+ -+ return i4Rslt; -+} -+ -+int -+mtk_p2p_cfg80211_set_default_key(struct wiphy *wiphy, -+ struct net_device *netdev, u8 key_index, bool unicast, bool multicast) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ -+ ASSERT(wiphy); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); -+ -+ /* not implemented yet */ -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+int mtk_p2p_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev, -+ const u8 *mac, struct station_info *sinfo) -+{ -+ INT_32 i4RetRslt = -EINVAL; -+ P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) NULL; -+ P_GL_P2P_INFO_T prP2pGlueInfo = (P_GL_P2P_INFO_T) NULL; -+ P2P_STATION_INFO_T rP2pStaInfo; -+ -+ ASSERT(wiphy); -+ -+ do { -+ if ((wiphy == NULL) || (ndev == NULL) || (sinfo == NULL) || (mac == NULL)) -+ break; -+ -+ DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_get_station\n"); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); -+ prP2pGlueInfo = prGlueInfo->prP2PInfo; -+ -+ sinfo->filled = 0; -+ -+ /* Get station information. */ -+ /* 1. Inactive time? */ -+ p2pFuncGetStationInfo(prGlueInfo->prAdapter, (PUINT_8)mac, &rP2pStaInfo); -+ -+ /* Inactive time. */ -+ sinfo->filled |= NL80211_STA_INFO_INACTIVE_TIME; -+ sinfo->inactive_time = rP2pStaInfo.u4InactiveTime; -+ sinfo->generation = prP2pGlueInfo->i4Generation; -+ -+ i4RetRslt = 0; -+ } while (FALSE); -+ -+ return i4RetRslt; -+} -+ -+int mtk_p2p_cfg80211_scan(struct wiphy *wiphy, struct cfg80211_scan_request *request) -+{ -+ P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) NULL; -+ P_GL_P2P_INFO_T prP2pGlueInfo = (P_GL_P2P_INFO_T) NULL; -+ P_MSG_P2P_SCAN_REQUEST_T prMsgScanRequest = (P_MSG_P2P_SCAN_REQUEST_T) NULL; -+ UINT_32 u4MsgSize = 0, u4Idx = 0; -+ INT_32 i4RetRslt = -EINVAL; -+ P_RF_CHANNEL_INFO_T prRfChannelInfo = (P_RF_CHANNEL_INFO_T) NULL; -+ P_P2P_SSID_STRUCT_T prSsidStruct = (P_P2P_SSID_STRUCT_T) NULL; -+ struct ieee80211_channel *prChannel = NULL; -+ struct cfg80211_ssid *prSsid = NULL; -+ -+ /* [---------Channel---------] [---------SSID---------][---------IE---------] */ -+ DBGLOG(INIT, TRACE, "mtk_p2p_cfg80211_scan\n"); -+ -+ do { -+ if ((wiphy == NULL) || (request == NULL)) -+ break; -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); -+ -+ prP2pGlueInfo = prGlueInfo->prP2PInfo; -+ -+ if (prP2pGlueInfo == NULL) { -+ ASSERT(FALSE); -+ break; -+ } -+ -+ DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_scan.\n"); -+ -+ if (prP2pGlueInfo->prScanRequest != NULL) { -+ /* There have been a scan request on-going processing. */ -+ DBGLOG(P2P, TRACE, "There have been a scan request on-going processing.\n"); -+ break; -+ } -+ -+ prP2pGlueInfo->prScanRequest = request; -+ -+ /* Should find out why the n_channels so many? */ -+ if (request->n_channels > MAXIMUM_OPERATION_CHANNEL_LIST) { -+ request->n_channels = MAXIMUM_OPERATION_CHANNEL_LIST; -+ DBGLOG(P2P, TRACE, "Channel list exceed the maximun support.\n"); -+ } -+ -+ u4MsgSize = sizeof(MSG_P2P_SCAN_REQUEST_T) + -+ (request->n_channels * sizeof(RF_CHANNEL_INFO_T)) + -+ (request->n_ssids * sizeof(PARAM_SSID_T)) + request->ie_len; -+ -+ prMsgScanRequest = cnmMemAlloc(prGlueInfo->prAdapter, RAM_TYPE_MSG, u4MsgSize); -+ -+ if (prMsgScanRequest == NULL) { -+ ASSERT(FALSE); -+ i4RetRslt = -ENOMEM; -+ prP2pGlueInfo->prScanRequest = NULL; -+ DBGLOG(INIT, TRACE, "mtk_p2p_cfg80211_scan Allocate Mem failed\n"); -+ break; -+ } -+ -+ DBGLOG(P2P, TRACE, "Generating scan request message.\n"); -+ -+ prMsgScanRequest->rMsgHdr.eMsgId = MID_MNY_P2P_DEVICE_DISCOVERY; -+ -+ DBGLOG(P2P, INFO, "Requesting channel number:%d.\n", request->n_channels); -+ -+ for (u4Idx = 0; u4Idx < request->n_channels; u4Idx++) { -+ /* Translate Freq from MHz to channel number. */ -+ prRfChannelInfo = &(prMsgScanRequest->arChannelListInfo[u4Idx]); -+ prChannel = request->channels[u4Idx]; -+ -+ prRfChannelInfo->ucChannelNum = nicFreq2ChannelNum(prChannel->center_freq * 1000); -+ DBGLOG(P2P, TRACE, "Scanning Channel:%d, freq: %d\n", -+ prRfChannelInfo->ucChannelNum, prChannel->center_freq); -+ switch (prChannel->band) { -+ case NL80211_BAND_2GHZ: -+ prRfChannelInfo->eBand = BAND_2G4; -+ break; -+ case NL80211_BAND_5GHZ: -+ prRfChannelInfo->eBand = BAND_5G; -+ break; -+ default: -+ DBGLOG(P2P, TRACE, "UNKNOWN Band info from supplicant\n"); -+ prRfChannelInfo->eBand = BAND_NULL; -+ break; -+ } -+ -+ /* Iteration. */ -+ prRfChannelInfo++; -+ } -+ prMsgScanRequest->u4NumChannel = request->n_channels; -+ -+ DBGLOG(P2P, TRACE, "Finish channel list.\n"); -+ -+ /* SSID */ -+ prSsid = request->ssids; -+ prSsidStruct = (P_P2P_SSID_STRUCT_T) prRfChannelInfo; -+ if (prSsidStruct) { -+ if (request->n_ssids) { -+ ASSERT((ULONG) prSsidStruct == (ULONG)&(prMsgScanRequest->arChannelListInfo[u4Idx])); -+ prMsgScanRequest->prSSID = prSsidStruct; -+ } -+ -+ for (u4Idx = 0; u4Idx < request->n_ssids; u4Idx++) { -+ COPY_SSID(prSsidStruct->aucSsid, -+ prSsidStruct->ucSsidLen, request->ssids->ssid, request->ssids->ssid_len); -+ -+ prSsidStruct++; -+ prSsid++; -+ } -+ -+ prMsgScanRequest->i4SsidNum = request->n_ssids; -+ -+ DBGLOG(P2P, TRACE, "Finish SSID list:%d.\n", request->n_ssids); -+ -+ /* IE BUFFERS */ -+ prMsgScanRequest->pucIEBuf = (PUINT_8) prSsidStruct; -+ if (request->ie_len) { -+ kalMemCopy(prMsgScanRequest->pucIEBuf, request->ie, request->ie_len); -+ prMsgScanRequest->u4IELen = request->ie_len; -+ } -+ } -+ -+ DBGLOG(P2P, TRACE, "Finish IE Buffer.\n"); -+#if CFG_AUTO_CHANNEL_SEL_SUPPORT -+ prGlueInfo->prAdapter->rWifiVar.rChnLoadInfo.fgDataReadyBit = FALSE; -+#endif -+ mboxSendMsg(prGlueInfo->prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgScanRequest, MSG_SEND_METHOD_BUF); -+ -+ i4RetRslt = 0; -+ } while (FALSE); -+ -+ return i4RetRslt; -+} /* mtk_p2p_cfg80211_scan */ -+ -+int mtk_p2p_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed) -+{ -+ INT_32 i4Rslt = -EINVAL; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ -+ do { -+ if (wiphy == NULL) -+ break; -+ -+ DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_set_wiphy_params\n"); -+ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); -+ -+ if (changed & WIPHY_PARAM_RETRY_SHORT) { -+ /* TODO: */ -+ DBGLOG(P2P, TRACE, "The RETRY short param is changed.\n"); -+ } -+ -+ if (changed & WIPHY_PARAM_RETRY_LONG) { -+ /* TODO: */ -+ DBGLOG(P2P, TRACE, "The RETRY long param is changed.\n"); -+ } -+ -+ if (changed & WIPHY_PARAM_FRAG_THRESHOLD) { -+ /* TODO: */ -+ DBGLOG(P2P, TRACE, "The RETRY fragmentation threshold is changed.\n"); -+ } -+ -+ if (changed & WIPHY_PARAM_RTS_THRESHOLD) { -+ /* TODO: */ -+ DBGLOG(P2P, TRACE, "The RETRY RTS threshold is changed.\n"); -+ } -+ -+ if (changed & WIPHY_PARAM_COVERAGE_CLASS) { -+ /* TODO: */ -+ DBGLOG(P2P, TRACE, "The coverage class is changed???\n"); -+ } -+ -+ i4Rslt = 0; -+ } while (FALSE); -+ -+ return i4Rslt; -+} /* mtk_p2p_cfg80211_set_wiphy_params */ -+ -+int mtk_p2p_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_ibss_params *params) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ -+ ASSERT(wiphy); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); -+ -+ /* not implemented yet */ -+ -+ return -EINVAL; -+} -+ -+int mtk_p2p_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ -+ ASSERT(wiphy); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); -+ -+ /* not implemented yet */ -+ -+ return -EINVAL; -+} -+ -+int mtk_p2p_cfg80211_set_txpower(struct wiphy *wiphy, -+ struct wireless_dev *wdev, -+ enum nl80211_tx_power_setting type, int mbm) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ -+ ASSERT(wiphy); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); -+ -+ /* not implemented yet */ -+ -+ return -EINVAL; -+} -+ -+int mtk_p2p_cfg80211_get_txpower(struct wiphy *wiphy, -+ struct wireless_dev *wdev, -+ int *dbm) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ -+ ASSERT(wiphy); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); -+ -+ /* not implemented yet */ -+ -+ return -EINVAL; -+} -+ -+int mtk_p2p_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev, bool enabled, int timeout) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ INT_32 value; -+ UINT_32 u4Leng; -+ -+ ASSERT(wiphy); -+ -+ if (enabled) -+ value = 2; -+ else -+ value = 0; -+ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); -+ DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_set_power_mgmt ps=%d.\n", enabled); -+ -+ /* p2p_set_power_save */ -+ kalIoctl(prGlueInfo, wlanoidSetP2pPowerSaveProfile, &value, sizeof(value), FALSE, FALSE, TRUE, TRUE, &u4Leng); -+ return 0; -+} -+ -+/* &&&&&&&&&&&&&&&&&&&&&&&&&& Add for ICS Wi-Fi Direct Support. &&&&&&&&&&&&&&&&&&&&&&& */ -+int mtk_p2p_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_ap_settings *settings) -+{ -+ P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) NULL; -+ INT_32 i4Rslt = -EINVAL; -+ P_MSG_P2P_BEACON_UPDATE_T prP2pBcnUpdateMsg = (P_MSG_P2P_BEACON_UPDATE_T) NULL; -+ P_MSG_P2P_START_AP_T prP2pStartAPMsg = (P_MSG_P2P_START_AP_T) NULL; -+ PUINT_8 pucBuffer = (PUINT_8) NULL; -+ /* P_IE_SSID_T prSsidIE = (P_IE_SSID_T)NULL; */ -+ -+ struct wireless_dev *wdev = dev->ieee80211_ptr; -+ struct cfg80211_chan_def *chandef = &wdev->preset_chandef; -+ -+ do { -+ if ((wiphy == NULL) || (settings == NULL)) -+ break; -+ -+ DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_start_ap.\n"); -+ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); -+ -+#if 1 -+ mtk_p2p_cfg80211_set_channel(wiphy, chandef); -+#else -+ prGlueInfo->prAdapter->rWifiVar.prP2PConnSettings->ucOperatingChnl = -+ (chandef->chan->center_freq - 2407) / 5; -+ prGlueInfo->prAdapter->rWifiVar.prP2PConnSettings->eBand = BAND_2G4; -+#endif -+ -+ prP2pBcnUpdateMsg = (P_MSG_P2P_BEACON_UPDATE_T) cnmMemAlloc(prGlueInfo->prAdapter, -+ RAM_TYPE_MSG, -+ (sizeof(MSG_P2P_BEACON_UPDATE_T) + -+ settings->beacon.head_len + -+ settings->beacon.tail_len)); -+ -+ if (prP2pBcnUpdateMsg == NULL) { -+ ASSERT(FALSE); -+ i4Rslt = -ENOMEM; -+ break; -+ } -+ -+ prP2pBcnUpdateMsg->rMsgHdr.eMsgId = MID_MNY_P2P_BEACON_UPDATE; -+ pucBuffer = prP2pBcnUpdateMsg->aucBuffer; -+ -+ if (settings->beacon.head_len != 0) { -+ kalMemCopy(pucBuffer, settings->beacon.head, settings->beacon.head_len); -+ -+ prP2pBcnUpdateMsg->u4BcnHdrLen = settings->beacon.head_len; -+ -+ prP2pBcnUpdateMsg->pucBcnHdr = pucBuffer; -+ -+ pucBuffer = (PUINT_8) ((ULONG) pucBuffer + (UINT_32) settings->beacon.head_len); -+ } else { -+ prP2pBcnUpdateMsg->u4BcnHdrLen = 0; -+ -+ prP2pBcnUpdateMsg->pucBcnHdr = NULL; -+ } -+ -+ if (settings->beacon.tail_len != 0) { -+ UINT_32 ucLen = settings->beacon.tail_len; -+ -+ prP2pBcnUpdateMsg->pucBcnBody = pucBuffer; -+ -+ /*Add TIM IE */ -+ /* IEEE 802.11 2007 - 7.3.2.6 */ -+ TIM_IE(pucBuffer)->ucId = ELEM_ID_TIM; -+ TIM_IE(pucBuffer)->ucLength = (3 + MAX_LEN_TIM_PARTIAL_BMP) /*((u4N2 - u4N1) + 4) */; -+ /* NOTE: fixed PVB length (AID is allocated from 8 ~ 15 only) */ -+ TIM_IE(pucBuffer)->ucDTIMCount = 0 /*prBssInfo->ucDTIMCount */; /* will be overwrite by FW */ -+ TIM_IE(pucBuffer)->ucDTIMPeriod = 1; -+ TIM_IE(pucBuffer)->ucBitmapControl = 0 /*ucBitmapControl | (UINT_8)u4N1 */; -+ /* will be overwrite by FW */ -+ ucLen += IE_SIZE(pucBuffer); -+ pucBuffer += IE_SIZE(pucBuffer); -+ -+ kalMemCopy(pucBuffer, settings->beacon.tail, settings->beacon.tail_len); -+ -+ prP2pBcnUpdateMsg->u4BcnBodyLen = ucLen; -+ } else { -+ prP2pBcnUpdateMsg->u4BcnBodyLen = 0; -+ -+ prP2pBcnUpdateMsg->pucBcnBody = NULL; -+ } -+ -+ mboxSendMsg(prGlueInfo->prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prP2pBcnUpdateMsg, MSG_SEND_METHOD_BUF); -+ -+ prP2pStartAPMsg = (P_MSG_P2P_START_AP_T) cnmMemAlloc(prGlueInfo->prAdapter, -+ RAM_TYPE_MSG, sizeof(MSG_P2P_START_AP_T)); -+ -+ if (prP2pStartAPMsg == NULL) { -+ ASSERT(FALSE); -+ i4Rslt = -ENOMEM; -+ break; -+ } -+ -+ prP2pStartAPMsg->rMsgHdr.eMsgId = MID_MNY_P2P_START_AP; -+ -+ prP2pStartAPMsg->fgIsPrivacy = settings->privacy; -+ -+ prP2pStartAPMsg->u4BcnInterval = settings->beacon_interval; -+ -+ prP2pStartAPMsg->u4DtimPeriod = settings->dtim_period; -+ -+ /* Copy NO SSID. */ -+ prP2pStartAPMsg->ucHiddenSsidType = settings->hidden_ssid; -+ -+ COPY_SSID(prP2pStartAPMsg->aucSsid, prP2pStartAPMsg->u2SsidLen, settings->ssid, settings->ssid_len); -+ -+ mboxSendMsg(prGlueInfo->prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prP2pStartAPMsg, MSG_SEND_METHOD_BUF); -+ -+ i4Rslt = 0; -+#if CFG_SPM_WORKAROUND_FOR_HOTSPOT -+ if (glIsChipNeedWakelock(prGlueInfo)) -+ KAL_WAKE_LOCK(prGlueInfo->prAdapter, &prGlueInfo->prAdapter->rApWakeLock); -+#endif -+ -+ } while (FALSE); -+ -+ return i4Rslt; -+ -+/* /////////////////////// */ -+ /** -+ * struct cfg80211_ap_settings - AP configuration -+ * -+ * Used to configure an AP interface. -+ * -+ * @beacon: beacon data -+ * @beacon_interval: beacon interval -+ * @dtim_period: DTIM period -+ * @ssid: SSID to be used in the BSS (note: may be %NULL if not provided from -+ * user space) -+ * @ssid_len: length of @ssid -+ * @hidden_ssid: whether to hide the SSID in Beacon/Probe Response frames -+ * @crypto: crypto settings -+ * @privacy: the BSS uses privacy -+ * @auth_type: Authentication type (algorithm) -+ * @inactivity_timeout: time in seconds to determine station's inactivity. -+ */ -+/* struct cfg80211_ap_settings { */ -+/* struct cfg80211_beacon_data beacon; */ -+/* */ -+/* int beacon_interval, dtim_period; */ -+/* const u8 *ssid; */ -+/* size_t ssid_len; */ -+/* enum nl80211_hidden_ssid hidden_ssid; */ -+/* struct cfg80211_crypto_settings crypto; */ -+/* bool privacy; */ -+/* enum nl80211_auth_type auth_type; */ -+/* int inactivity_timeout; */ -+/* }; */ -+/* ////////////////// */ -+ -+ return i4Rslt; -+} /* mtk_p2p_cfg80211_start_ap */ -+ -+int mtk_p2p_cfg80211_change_beacon(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_beacon_data *info) -+{ -+ P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) NULL; -+ INT_32 i4Rslt = -EINVAL; -+ P_MSG_P2P_BEACON_UPDATE_T prP2pBcnUpdateMsg = (P_MSG_P2P_BEACON_UPDATE_T) NULL; -+ PUINT_8 pucBuffer = (PUINT_8) NULL; -+ -+ do { -+ if ((wiphy == NULL) || (info == NULL)) -+ break; -+ -+ DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_change_beacon.\n"); -+ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); -+ -+ prP2pBcnUpdateMsg = (P_MSG_P2P_BEACON_UPDATE_T) cnmMemAlloc(prGlueInfo->prAdapter, -+ RAM_TYPE_MSG, -+ (sizeof(MSG_P2P_BEACON_UPDATE_T) + -+ info->head_len + info->tail_len)); -+ -+ if (prP2pBcnUpdateMsg == NULL) { -+ ASSERT(FALSE); -+ i4Rslt = -ENOMEM; -+ break; -+ } -+ -+ prP2pBcnUpdateMsg->rMsgHdr.eMsgId = MID_MNY_P2P_BEACON_UPDATE; -+ pucBuffer = prP2pBcnUpdateMsg->aucBuffer; -+ -+ if (info->head_len != 0) { -+ kalMemCopy(pucBuffer, info->head, info->head_len); -+ -+ prP2pBcnUpdateMsg->u4BcnHdrLen = info->head_len; -+ -+ prP2pBcnUpdateMsg->pucBcnHdr = pucBuffer; -+ -+ pucBuffer = (PUINT_8) ((ULONG) pucBuffer + (UINT_32) info->head_len); -+ } else { -+ prP2pBcnUpdateMsg->u4BcnHdrLen = 0; -+ -+ prP2pBcnUpdateMsg->pucBcnHdr = NULL; -+ } -+ -+ if (info->tail_len != 0) { -+ UINT_32 ucLen = info->tail_len; -+ -+ prP2pBcnUpdateMsg->pucBcnBody = pucBuffer; -+ -+ /*Add TIM IE */ -+ /* IEEE 802.11 2007 - 7.3.2.6 */ -+ TIM_IE(pucBuffer)->ucId = ELEM_ID_TIM; -+ TIM_IE(pucBuffer)->ucLength = (3 + MAX_LEN_TIM_PARTIAL_BMP) /*((u4N2 - u4N1) + 4) */; -+ /* NOTE: fixed PVB length (AID is allocated from 8 ~ 15 only) */ -+ TIM_IE(pucBuffer)->ucDTIMCount = 0 /*prBssInfo->ucDTIMCount */; /* will be overwrite by FW */ -+ TIM_IE(pucBuffer)->ucDTIMPeriod = 1; -+ TIM_IE(pucBuffer)->ucBitmapControl = 0 /*ucBitmapControl | (UINT_8)u4N1 */; -+ /* will be overwrite by FW */ -+ ucLen += IE_SIZE(pucBuffer); -+ pucBuffer += IE_SIZE(pucBuffer); -+ -+ kalMemCopy(pucBuffer, info->tail, info->tail_len); -+ -+ prP2pBcnUpdateMsg->u4BcnBodyLen = ucLen; -+ } else { -+ prP2pBcnUpdateMsg->u4BcnBodyLen = 0; -+ -+ prP2pBcnUpdateMsg->pucBcnBody = NULL; -+ } -+ -+ mboxSendMsg(prGlueInfo->prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prP2pBcnUpdateMsg, MSG_SEND_METHOD_BUF); -+ -+/* ////////////////////////// */ -+/** -+ * struct cfg80211_beacon_data - beacon data -+ * @head: head portion of beacon (before TIM IE) -+ * or %NULL if not changed -+ * @tail: tail portion of beacon (after TIM IE) -+ * or %NULL if not changed -+ * @head_len: length of @head -+ * @tail_len: length of @tail -+ * @beacon_ies: extra information element(s) to add into Beacon frames or %NULL -+ * @beacon_ies_len: length of beacon_ies in octets -+ * @proberesp_ies: extra information element(s) to add into Probe Response -+ * frames or %NULL -+ * @proberesp_ies_len: length of proberesp_ies in octets -+ * @assocresp_ies: extra information element(s) to add into (Re)Association -+ * Response frames or %NULL -+ * @assocresp_ies_len: length of assocresp_ies in octets -+ * @probe_resp_len: length of probe response template (@probe_resp) -+ * @probe_resp: probe response template (AP mode only) -+ */ -+/* struct cfg80211_beacon_data { */ -+/* const u8 *head, *tail; */ -+/* const u8 *beacon_ies; */ -+/* const u8 *proberesp_ies; */ -+/* const u8 *assocresp_ies; */ -+/* const u8 *probe_resp; */ -+ -+/* size_t head_len, tail_len; */ -+/* size_t beacon_ies_len; */ -+/* size_t proberesp_ies_len; */ -+/* size_t assocresp_ies_len; */ -+/* size_t probe_resp_len; */ -+/* }; */ -+ -+/* ////////////////////////// */ -+ -+ } while (FALSE); -+ -+ return i4Rslt; -+} /* mtk_p2p_cfg80211_change_beacon */ -+ -+int mtk_p2p_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *dev) -+{ -+ P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) NULL; -+ INT_32 i4Rslt = -EINVAL; -+ P_MSG_P2P_SWITCH_OP_MODE_T prP2pSwitchMode = (P_MSG_P2P_SWITCH_OP_MODE_T) NULL; -+ -+ do { -+ if (wiphy == NULL) -+ break; -+ -+ DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_stop_ap.\n"); -+ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); -+ -+ /* Switch OP MOde. */ -+ prP2pSwitchMode = cnmMemAlloc(prGlueInfo->prAdapter, RAM_TYPE_MSG, sizeof(MSG_P2P_SWITCH_OP_MODE_T)); -+ -+ if (prP2pSwitchMode == NULL) { -+ ASSERT(FALSE); -+ i4Rslt = -ENOMEM; -+ break; -+ } -+ -+ prP2pSwitchMode->rMsgHdr.eMsgId = MID_MNY_P2P_STOP_AP; -+ -+ mboxSendMsg(prGlueInfo->prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prP2pSwitchMode, MSG_SEND_METHOD_BUF); -+ -+ i4Rslt = 0; -+#if CFG_SPM_WORKAROUND_FOR_HOTSPOT -+ if (glIsChipNeedWakelock(prGlueInfo)) -+ KAL_WAKE_UNLOCK(prGlueInfo->prAdapter, &prGlueInfo->prAdapter->rApWakeLock); -+#endif -+ } while (FALSE); -+ -+ return i4Rslt; -+} /* mtk_p2p_cfg80211_stop_ap */ -+ -+/* TODO: */ -+int mtk_p2p_cfg80211_deauth(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_deauth_request *req) -+{ -+ P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) NULL; -+ -+ ASSERT(wiphy); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); -+ -+ /* not implemented yet */ -+ DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_deauth.\n"); -+ -+ return -EINVAL; -+} /* mtk_p2p_cfg80211_deauth */ -+ -+/* TODO: */ -+int mtk_p2p_cfg80211_disassoc(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_disassoc_request *req) -+{ -+ P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) NULL; -+ -+ ASSERT(wiphy); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); -+ -+ DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_disassoc.\n"); -+ -+ /* not implemented yet */ -+ -+ return -EINVAL; -+} /* mtk_p2p_cfg80211_disassoc */ -+ -+int mtk_p2p_cfg80211_remain_on_channel(struct wiphy *wiphy, -+ struct wireless_dev *wdev, -+ struct ieee80211_channel *chan, -+ unsigned int duration, u64 *cookie) -+{ -+ INT_32 i4Rslt = -EINVAL; -+ P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) NULL; -+ P_GL_P2P_INFO_T prGlueP2pInfo = (P_GL_P2P_INFO_T) NULL; -+ P_MSG_P2P_CHNL_REQUEST_T prMsgChnlReq = (P_MSG_P2P_CHNL_REQUEST_T) NULL; -+ -+ do { -+ if ((wiphy == NULL) || (wdev == NULL) || (chan == NULL) || (cookie == NULL)) -+ break; -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); -+ prGlueP2pInfo = prGlueInfo->prP2PInfo; -+ -+ *cookie = prGlueP2pInfo->u8Cookie++; -+ -+ prMsgChnlReq = cnmMemAlloc(prGlueInfo->prAdapter, RAM_TYPE_MSG, sizeof(MSG_P2P_CHNL_REQUEST_T)); -+ -+ if (prMsgChnlReq == NULL) { -+ ASSERT(FALSE); -+ i4Rslt = -ENOMEM; -+ break; -+ } -+ -+ DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_remain_on_channel\n"); -+ -+ prMsgChnlReq->rMsgHdr.eMsgId = MID_MNY_P2P_CHNL_REQ; -+ prMsgChnlReq->u8Cookie = *cookie; -+ prMsgChnlReq->u4Duration = duration; -+ -+ mtk_p2p_cfg80211func_channel_format_switch(chan, NL80211_CHAN_HT20, /* 4 KH Need Check */ -+ &prMsgChnlReq->rChannelInfo, &prMsgChnlReq->eChnlSco); -+ -+ mboxSendMsg(prGlueInfo->prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgChnlReq, MSG_SEND_METHOD_BUF); -+ -+ i4Rslt = 0; -+ -+ i4Rslt = 0; -+ } while (FALSE); -+ -+ return i4Rslt; -+} -+ -+/* mtk_p2p_cfg80211_remain_on_channel */ -+int mtk_p2p_cfg80211_cancel_remain_on_channel(struct wiphy *wiphy, -+ struct wireless_dev *wdev, -+ u64 cookie) -+{ -+ INT_32 i4Rslt = -EINVAL; -+ P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) NULL; -+ P_MSG_P2P_CHNL_ABORT_T prMsgChnlAbort = (P_MSG_P2P_CHNL_ABORT_T) NULL; -+ -+ do { -+ if ((wiphy == NULL) || (wdev == NULL)) -+ break; -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); -+ -+ prMsgChnlAbort = cnmMemAlloc(prGlueInfo->prAdapter, RAM_TYPE_MSG, sizeof(MSG_P2P_CHNL_ABORT_T)); -+ -+ if (prMsgChnlAbort == NULL) { -+ ASSERT(FALSE); -+ i4Rslt = -ENOMEM; -+ break; -+ } -+ -+ DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_cancel_remain_on_channel\n"); -+ -+ prMsgChnlAbort->rMsgHdr.eMsgId = MID_MNY_P2P_CHNL_ABORT; -+ prMsgChnlAbort->u8Cookie = cookie; -+ -+ mboxSendMsg(prGlueInfo->prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgChnlAbort, MSG_SEND_METHOD_BUF); -+ -+ i4Rslt = 0; -+ } while (FALSE); -+ -+ return i4Rslt; -+} /* mtk_p2p_cfg80211_cancel_remain_on_channel */ -+ -+int mtk_p2p_cfg80211_mgmt_tx(struct wiphy *wiphy, -+ struct wireless_dev *wdev, -+ struct cfg80211_mgmt_tx_params *params, -+ u64 *cookie) -+{ -+ P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) NULL; -+ P_GL_P2P_INFO_T prGlueP2pInfo = (P_GL_P2P_INFO_T) NULL; -+ INT_32 i4Rslt = -EINVAL; -+ struct _MSG_P2P_EXTEND_LISTEN_INTERVAL_T *prMsgExtListenReq = NULL; -+ P_MSG_P2P_MGMT_TX_REQUEST_T prMsgTxReq = (P_MSG_P2P_MGMT_TX_REQUEST_T) NULL; -+ P_MSDU_INFO_T prMgmtFrame = (P_MSDU_INFO_T) NULL; -+ PUINT_8 pucFrameBuf = (PUINT_8) NULL; -+ -+ do { -+ if ((wiphy == NULL) || (wdev == NULL) || (params == 0) || (cookie == NULL)) -+ break; -+ /* DBGLOG(P2P, TRACE, ("mtk_p2p_cfg80211_mgmt_tx\n")); */ -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); -+ prGlueP2pInfo = prGlueInfo->prP2PInfo; -+ -+ *cookie = prGlueP2pInfo->u8Cookie++; -+ -+ /* Channel & Channel Type & Wait time are ignored. */ -+ prMsgTxReq = cnmMemAlloc(prGlueInfo->prAdapter, RAM_TYPE_MSG, sizeof(MSG_P2P_MGMT_TX_REQUEST_T)); -+ -+ if (prMsgTxReq == NULL) { -+ ASSERT(FALSE); -+ i4Rslt = -ENOMEM; -+ break; -+ } -+ -+ /* Here need to extend the listen interval */ -+ prMsgExtListenReq = cnmMemAlloc(prGlueInfo->prAdapter, RAM_TYPE_MSG, -+ sizeof(struct _MSG_P2P_EXTEND_LISTEN_INTERVAL_T)); -+ if (prMsgExtListenReq) { -+ prMsgExtListenReq->rMsgHdr.eMsgId = MID_MNY_P2P_EXTEND_LISTEN_INTERVAL; -+ prMsgExtListenReq->wait = params->wait; -+ DBGLOG(P2P, INFO, "ext listen, wait: %d\n", prMsgExtListenReq->wait); -+ mboxSendMsg(prGlueInfo->prAdapter, MBOX_ID_0, (P_MSG_HDR_T)prMsgExtListenReq, -+ MSG_SEND_METHOD_BUF); -+ } -+ -+ prMsgTxReq->fgNoneCckRate = FALSE; -+ prMsgTxReq->fgIsWaitRsp = TRUE; -+ -+ prMgmtFrame = cnmMgtPktAlloc(prGlueInfo->prAdapter, (UINT_32) (params->len + MAC_TX_RESERVED_FIELD)); -+ -+ prMsgTxReq->prMgmtMsduInfo = prMgmtFrame; -+ if (prMsgTxReq->prMgmtMsduInfo == NULL) { -+ ASSERT(FALSE); -+ i4Rslt = -ENOMEM; -+ break; -+ } -+ -+ prMsgTxReq->u8Cookie = *cookie; -+ prMsgTxReq->rMsgHdr.eMsgId = MID_MNY_P2P_MGMT_TX; -+ -+ pucFrameBuf = (PUINT_8) ((ULONG) prMgmtFrame->prPacket + MAC_TX_RESERVED_FIELD); -+ -+ kalMemCopy(pucFrameBuf, params->buf, params->len); -+ -+ prMgmtFrame->u2FrameLength = params->len; -+ -+ mboxSendMsg(prGlueInfo->prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgTxReq, MSG_SEND_METHOD_BUF); -+ -+ i4Rslt = 0; -+ } while (FALSE); -+ -+ if ((i4Rslt != 0) && (prMsgTxReq != NULL)) { -+ if (prMsgTxReq->prMgmtMsduInfo != NULL) -+ cnmMgtPktFree(prGlueInfo->prAdapter, prMsgTxReq->prMgmtMsduInfo); -+ -+ cnmMemFree(prGlueInfo->prAdapter, prMsgTxReq); -+ } -+ -+ return i4Rslt; -+} /* mtk_p2p_cfg80211_mgmt_tx */ -+ -+int mtk_p2p_cfg80211_change_bss(struct wiphy *wiphy, struct net_device *dev, struct bss_parameters *params) -+{ -+ P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) NULL; -+ INT_32 i4Rslt = -EINVAL; -+ -+ ASSERT(wiphy); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); -+ -+ switch (params->use_cts_prot) { -+ case -1: -+ DBGLOG(P2P, TRACE, "CTS protection no change\n"); -+ break; -+ case 0: -+ DBGLOG(P2P, TRACE, "CTS protection disable.\n"); -+ break; -+ case 1: -+ DBGLOG(P2P, TRACE, "CTS protection enable\n"); -+ break; -+ default: -+ DBGLOG(P2P, TRACE, "CTS protection unknown\n"); -+ break; -+ } -+ -+ switch (params->use_short_preamble) { -+ case -1: -+ DBGLOG(P2P, TRACE, "Short prreamble no change\n"); -+ break; -+ case 0: -+ DBGLOG(P2P, TRACE, "Short prreamble disable.\n"); -+ break; -+ case 1: -+ DBGLOG(P2P, TRACE, "Short prreamble enable\n"); -+ break; -+ default: -+ DBGLOG(P2P, TRACE, "Short prreamble unknown\n"); -+ break; -+ } -+ -+#if 0 -+ /* not implemented yet */ -+ p2pFuncChangeBssParam(prGlueInfo->prAdapter, -+ prBssInfo->fgIsProtection, -+ prBssInfo->fgIsShortPreambleAllowed, prBssInfo->fgUseShortSlotTime, -+ /* Basic rates */ -+ /* basic rates len */ -+ /* ap isolate */ -+ /* ht opmode. */ -+ ); -+#else -+ i4Rslt = 0; -+#endif -+ -+ return i4Rslt; -+} /* mtk_p2p_cfg80211_change_bss */ -+ -+int mtk_p2p_cfg80211_del_station(struct wiphy *wiphy, struct net_device *dev, struct station_del_parameters *params) -+//int mtk_p2p_cfg80211_del_station(struct wiphy *wiphy, struct net_device *dev, const u8 *mac) -+{ -+ P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) NULL; -+ INT_32 i4Rslt = -EINVAL; -+ P_MSG_P2P_CONNECTION_ABORT_T prDisconnectMsg = (P_MSG_P2P_CONNECTION_ABORT_T) NULL; -+ UINT_8 aucBcMac[] = BC_MAC_ADDR; -+ const UINT_8 *mac = NULL; -+ -+ do { -+ if ((wiphy == NULL) || (dev == NULL)) -+ break; -+ -+ if (params->mac == NULL) -+ mac = aucBcMac; -+ else -+ mac = params->mac; -+ -+ DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_del_station.\n"); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); -+ -+ /* prDisconnectMsg = (P_MSG_P2P_CONNECTION_ABORT_T)kalMemAlloc(sizeof(MSG_P2P_CONNECTION_ABORT_T), -+ VIR_MEM_TYPE); */ -+ prDisconnectMsg = -+ (P_MSG_P2P_CONNECTION_ABORT_T) cnmMemAlloc(prGlueInfo->prAdapter, RAM_TYPE_MSG, -+ sizeof(MSG_P2P_CONNECTION_ABORT_T)); -+ -+ if (prDisconnectMsg == NULL) { -+ ASSERT(FALSE); -+ i4Rslt = -ENOMEM; -+ break; -+ } -+ -+ prDisconnectMsg->rMsgHdr.eMsgId = MID_MNY_P2P_CONNECTION_ABORT; -+ COPY_MAC_ADDR(prDisconnectMsg->aucTargetID, mac); -+ prDisconnectMsg->u2ReasonCode = REASON_CODE_UNSPECIFIED; -+ -+ mboxSendMsg(prGlueInfo->prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prDisconnectMsg, MSG_SEND_METHOD_BUF); -+ -+ i4Rslt = 0; -+ } while (FALSE); -+ -+ return i4Rslt; -+ -+} /* mtk_p2p_cfg80211_del_station */ -+ -+int mtk_p2p_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_connect_params *sme) -+{ -+ INT_32 i4Rslt = -EINVAL; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ P_MSG_P2P_CONNECTION_REQUEST_T prConnReqMsg = (P_MSG_P2P_CONNECTION_REQUEST_T) NULL; -+ -+ do { -+ if ((wiphy == NULL) || (dev == NULL) || (sme == NULL)) -+ break; -+ -+ DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_connect.\n"); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); -+ -+ prConnReqMsg = -+ (P_MSG_P2P_CONNECTION_REQUEST_T) cnmMemAlloc(prGlueInfo->prAdapter, RAM_TYPE_MSG, -+ (sizeof(MSG_P2P_CONNECTION_REQUEST_T) + sme->ie_len)); -+ -+ if (prConnReqMsg == NULL) { -+ ASSERT(FALSE); -+ i4Rslt = -ENOMEM; -+ break; -+ } -+ -+ prConnReqMsg->rMsgHdr.eMsgId = MID_MNY_P2P_CONNECTION_REQ; -+ -+ COPY_SSID(prConnReqMsg->rSsid.aucSsid, prConnReqMsg->rSsid.ucSsidLen, sme->ssid, sme->ssid_len); -+ -+ COPY_MAC_ADDR(prConnReqMsg->aucBssid, sme->bssid); -+ DBGLOG(P2P, INFO, "mtk_p2p_cfg80211_connect to %pM, IE len: %d\n", -+ prConnReqMsg->aucBssid, sme->ie_len); -+ -+ DBGLOG(P2P, TRACE, "Assoc Req IE Buffer Length:%d\n", sme->ie_len); -+ kalMemCopy(prConnReqMsg->aucIEBuf, sme->ie, sme->ie_len); -+ prConnReqMsg->u4IELen = sme->ie_len; -+ -+ mtk_p2p_cfg80211func_channel_format_switch(sme->channel, -+ NL80211_CHAN_NO_HT, -+ &prConnReqMsg->rChannelInfo, &prConnReqMsg->eChnlSco); -+ -+ mboxSendMsg(prGlueInfo->prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prConnReqMsg, MSG_SEND_METHOD_BUF); -+ -+ i4Rslt = 0; -+ } while (FALSE); -+ -+ return i4Rslt; -+} /* mtk_p2p_cfg80211_connect */ -+ -+int mtk_p2p_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev, u16 reason_code) -+{ -+ INT_32 i4Rslt = -EINVAL; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ P_MSG_P2P_CONNECTION_ABORT_T prDisconnMsg = (P_MSG_P2P_CONNECTION_ABORT_T) NULL; -+ UINT_8 aucBCAddr[] = BC_MAC_ADDR; -+ -+ do { -+ if ((wiphy == NULL) || (dev == NULL)) -+ break; -+ -+ DBGLOG(P2P, INFO, "mtk_p2p_cfg80211_disconnect.\n"); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); -+ -+/* prDisconnMsg = (P_MSG_P2P_CONNECTION_ABORT_T)kalMemAlloc(sizeof(P_MSG_P2P_CONNECTION_ABORT_T), VIR_MEM_TYPE); */ -+ prDisconnMsg = -+ (P_MSG_P2P_CONNECTION_ABORT_T) cnmMemAlloc(prGlueInfo->prAdapter, RAM_TYPE_MSG, -+ sizeof(MSG_P2P_CONNECTION_ABORT_T)); -+ -+ if (prDisconnMsg == NULL) { -+ ASSERT(FALSE); -+ i4Rslt = -ENOMEM; -+ DBGLOG(P2P, INFO, "mtk_p2p_cfg80211_disconnect.Allocate Memory Failed.\n"); -+ break; -+ } -+ -+ prDisconnMsg->rMsgHdr.eMsgId = MID_MNY_P2P_CONNECTION_ABORT; -+ prDisconnMsg->u2ReasonCode = reason_code; -+ prDisconnMsg->fgSendDeauth = TRUE; -+ COPY_MAC_ADDR(prDisconnMsg->aucTargetID, aucBCAddr); -+ -+ mboxSendMsg(prGlueInfo->prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prDisconnMsg, MSG_SEND_METHOD_BUF); -+ -+ i4Rslt = 0; -+ } while (FALSE); -+ -+ return i4Rslt; -+} /* mtk_p2p_cfg80211_disconnect */ -+ -+int -+mtk_p2p_cfg80211_change_iface(IN struct wiphy *wiphy, -+ IN struct net_device *ndev, -+ IN enum nl80211_iftype type,/* IN u32 *flags,*/ IN struct vif_params *params) -+{ -+ P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) NULL; -+ INT_32 i4Rslt = -EINVAL; -+ P_MSG_P2P_SWITCH_OP_MODE_T prSwitchModeMsg = (P_MSG_P2P_SWITCH_OP_MODE_T) NULL; -+ -+ do { -+ if ((wiphy == NULL) || (ndev == NULL)) -+ break; -+ -+ DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_change_iface.\n"); -+ -+ if (ndev->ieee80211_ptr) -+ ndev->ieee80211_ptr->iftype = type; -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); -+ -+ /* Switch OP MOde. */ -+ prSwitchModeMsg = -+ (P_MSG_P2P_SWITCH_OP_MODE_T) cnmMemAlloc(prGlueInfo->prAdapter, RAM_TYPE_MSG, -+ sizeof(MSG_P2P_SWITCH_OP_MODE_T)); -+ -+ if (prSwitchModeMsg == NULL) { -+ ASSERT(FALSE); -+ i4Rslt = -ENOMEM; -+ break; -+ } -+ -+ prSwitchModeMsg->rMsgHdr.eMsgId = MID_MNY_P2P_FUN_SWITCH; -+ -+ switch (type) { -+ case NL80211_IFTYPE_P2P_CLIENT: -+ DBGLOG(P2P, TRACE, "NL80211_IFTYPE_P2P_CLIENT.\n"); -+ case NL80211_IFTYPE_STATION: -+ if (type == NL80211_IFTYPE_STATION) -+ DBGLOG(P2P, TRACE, "NL80211_IFTYPE_STATION.\n"); -+ prSwitchModeMsg->eOpMode = OP_MODE_INFRASTRUCTURE; -+ break; -+ case NL80211_IFTYPE_AP: -+ DBGLOG(P2P, TRACE, "NL80211_IFTYPE_AP.\n"); -+ case NL80211_IFTYPE_P2P_GO: -+ if (type == NL80211_IFTYPE_P2P_GO) -+ DBGLOG(P2P, TRACE, "NL80211_IFTYPE_P2P_GO not AP.\n"); -+ prSwitchModeMsg->eOpMode = OP_MODE_ACCESS_POINT; -+ break; -+ default: -+ DBGLOG(P2P, TRACE, "Other type :%d .\n", type); -+ prSwitchModeMsg->eOpMode = OP_MODE_P2P_DEVICE; -+ break; -+ } -+ -+ mboxSendMsg(prGlueInfo->prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prSwitchModeMsg, MSG_SEND_METHOD_BUF); -+ -+ i4Rslt = 0; -+ -+ } while (FALSE); -+ -+ return i4Rslt; -+ -+} /* mtk_p2p_cfg80211_change_iface */ -+ -+int mtk_p2p_cfg80211_set_channel(IN struct wiphy *wiphy, -+ struct cfg80211_chan_def *chandef) -+{ -+ INT_32 i4Rslt = -EINVAL; -+ P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) NULL; -+ RF_CHANNEL_INFO_T rRfChnlInfo; -+ -+ do { -+ if (wiphy == NULL) -+ break; -+ -+ DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_set_channel.\n"); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); -+ mtk_p2p_cfg80211func_channel_format_switch(chandef->chan, chandef->width, &rRfChnlInfo, NULL); -+ p2pFuncSetChannel(prGlueInfo->prAdapter, &rRfChnlInfo); -+ -+ i4Rslt = 0; -+ } while (FALSE); -+ -+ return i4Rslt; -+ -+} -+ -+/* mtk_p2p_cfg80211_set_channel */ -+ -+int -+mtk_p2p_cfg80211_set_bitrate_mask(IN struct wiphy *wiphy, -+ IN struct net_device *dev, -+ IN const u8 *peer, IN const struct cfg80211_bitrate_mask *mask) -+{ -+ INT_32 i4Rslt = -EINVAL; -+ P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) NULL; -+ -+ do { -+ if ((wiphy == NULL) || (dev == NULL) || (mask == NULL)) -+ break; -+ -+ DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_set_bitrate_mask\n"); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); -+ -+ /* TODO: Set bitrate mask of the peer? */ -+ -+ i4Rslt = 0; -+ } while (FALSE); -+ -+ return i4Rslt; -+} /* mtk_p2p_cfg80211_set_bitrate_mask */ -+ -+void mtk_p2p_cfg80211_mgmt_frame_register(IN struct wiphy *wiphy, -+ struct wireless_dev *wdev, -+ IN u16 frame_type, IN bool reg) -+{ -+#if 0 -+ P_MSG_P2P_MGMT_FRAME_REGISTER_T prMgmtFrameRegister = (P_MSG_P2P_MGMT_FRAME_REGISTER_T) NULL; -+#endif -+ P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) NULL; -+ -+ do { -+ if ((wiphy == NULL) || (wdev == NULL)) -+ break; -+ -+ DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_mgmt_frame_register\n"); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); -+ -+ switch (frame_type) { -+ case MAC_FRAME_PROBE_REQ: -+ if (reg) { -+ prGlueInfo->prP2PInfo->u4OsMgmtFrameFilter |= PARAM_PACKET_FILTER_PROBE_REQ; -+ DBGLOG(P2P, TRACE, "Open packet filer probe request\n"); -+ } else { -+ prGlueInfo->prP2PInfo->u4OsMgmtFrameFilter &= ~PARAM_PACKET_FILTER_PROBE_REQ; -+ DBGLOG(P2P, TRACE, "Close packet filer probe request\n"); -+ } -+ break; -+ case MAC_FRAME_ACTION: -+ if (reg) { -+ prGlueInfo->prP2PInfo->u4OsMgmtFrameFilter |= PARAM_PACKET_FILTER_ACTION_FRAME; -+ DBGLOG(P2P, TRACE, "Open packet filer action frame.\n"); -+ } else { -+ prGlueInfo->prP2PInfo->u4OsMgmtFrameFilter &= ~PARAM_PACKET_FILTER_ACTION_FRAME; -+ DBGLOG(P2P, TRACE, "Close packet filer action frame.\n"); -+ } -+ break; -+ default: -+ DBGLOG(P2P, ERROR, "Ask frog to add code for mgmt:%x\n", frame_type); -+ break; -+ } -+ -+ if ((prGlueInfo->prAdapter != NULL) && (prGlueInfo->prAdapter->fgIsP2PRegistered == TRUE)) { -+ -+ /* prGlueInfo->u4Flag |= GLUE_FLAG_FRAME_FILTER; */ -+ set_bit(GLUE_FLAG_FRAME_FILTER_BIT, &prGlueInfo->ulFlag); -+ -+ /* wake up main thread */ -+ wake_up_interruptible(&prGlueInfo->waitq); -+ -+ if (in_interrupt()) -+ DBGLOG(P2P, TRACE, "It is in interrupt level\n"); -+ } -+#if 0 -+ -+ prMgmtFrameRegister = (P_MSG_P2P_MGMT_FRAME_REGISTER_T) cnmMemAlloc(prGlueInfo->prAdapter, -+ RAM_TYPE_MSG, -+ sizeof -+ (MSG_P2P_MGMT_FRAME_REGISTER_T)); -+ -+ if (prMgmtFrameRegister == NULL) { -+ ASSERT(FALSE); -+ break; -+ } -+ -+ prMgmtFrameRegister->rMsgHdr.eMsgId = MID_MNY_P2P_MGMT_FRAME_REGISTER; -+ -+ prMgmtFrameRegister->u2FrameType = frame_type; -+ prMgmtFrameRegister->fgIsRegister = reg; -+ -+ mboxSendMsg(prGlueInfo->prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMgmtFrameRegister, MSG_SEND_METHOD_BUF); -+ -+#endif -+ -+ } while (FALSE); -+ -+} /* mtk_p2p_cfg80211_mgmt_frame_register */ -+ -+BOOLEAN -+mtk_p2p_cfg80211func_channel_format_switch(IN struct ieee80211_channel *channel, -+ IN enum nl80211_channel_type channel_type, -+ IN P_RF_CHANNEL_INFO_T prRfChnlInfo, IN P_ENUM_CHNL_EXT_T prChnlSco) -+{ -+ BOOLEAN fgIsValid = FALSE; -+ -+ do { -+ if (channel == NULL) -+ break; -+ -+ if (prRfChnlInfo) { -+ prRfChnlInfo->ucChannelNum = nicFreq2ChannelNum(channel->center_freq * 1000); -+ -+ switch (channel->band) { -+ case NL80211_BAND_2GHZ: -+ prRfChnlInfo->eBand = BAND_2G4; -+ break; -+ case NL80211_BAND_5GHZ: -+ prRfChnlInfo->eBand = BAND_5G; -+ break; -+ default: -+ prRfChnlInfo->eBand = BAND_2G4; -+ break; -+ } -+ -+ } -+ -+ if (prChnlSco) { -+ -+ switch (channel_type) { -+ case NL80211_CHAN_NO_HT: -+ *prChnlSco = CHNL_EXT_SCN; -+ break; -+ case NL80211_CHAN_HT20: -+ *prChnlSco = CHNL_EXT_SCN; -+ break; -+ case NL80211_CHAN_HT40MINUS: -+ *prChnlSco = CHNL_EXT_SCA; -+ break; -+ case NL80211_CHAN_HT40PLUS: -+ *prChnlSco = CHNL_EXT_SCB; -+ break; -+ default: -+ ASSERT(FALSE); -+ *prChnlSco = CHNL_EXT_SCN; -+ break; -+ } -+ } -+ -+ fgIsValid = TRUE; -+ } while (FALSE); -+ -+ return fgIsValid; -+} -+ -+/* mtk_p2p_cfg80211func_channel_format_switch */ -+ -+#if CONFIG_NL80211_TESTMODE -+int mtk_p2p_cfg80211_testmode_cmd(IN struct wiphy *wiphy, IN struct wireless_dev *wdev, IN void *data, IN int len) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ P_NL80211_DRIVER_TEST_PARAMS prParams = (P_NL80211_DRIVER_TEST_PARAMS) NULL; -+ INT_32 i4Status = -EINVAL; -+ P_P2P_CHNL_REQ_INFO_T prChnlReqInfo = NULL; -+ -+ ASSERT(wiphy); -+ ASSERT(wdev); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); -+ -+ DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_testmode_cmd\n"); -+ -+ if (data && len) { -+ prParams = (P_NL80211_DRIVER_TEST_PARAMS) data; -+ } else { -+ DBGLOG(P2P, ERROR, "mtk_p2p_cfg80211_testmode_cmd, data is NULL\n"); -+ return i4Status; -+ } -+ -+ if (prParams->index >> 24 == 0x01) { -+ /* New version */ -+ } else { -+ /* Old version */ -+ mtk_p2p_cfg80211_testmode_p2p_sigma_pre_cmd(wiphy, data, len); -+ i4Status = 0; -+ return i4Status; -+ } -+ -+ /* Clear the version byte */ -+ prParams->index = prParams->index & ~BITS(24, 31); -+ -+ if (prParams) { -+ switch (prParams->index) { -+ case 1: /* P2P Simga */ -+#if CFG_SUPPORT_HOTSPOT_OPTIMIZATION -+ { -+ P_NL80211_DRIVER_SW_CMD_PARAMS prParamsCmd; -+ -+ prParamsCmd = (P_NL80211_DRIVER_SW_CMD_PARAMS) data; -+ -+ if ((prParamsCmd->adr & 0xffff0000) == 0xffff0000) { -+ i4Status = mtk_p2p_cfg80211_testmode_sw_cmd(wiphy, data, len); -+ break; -+ } -+ } -+#endif -+ i4Status = mtk_p2p_cfg80211_testmode_p2p_sigma_cmd(wiphy, data, len); -+ break; -+#if CFG_SUPPORT_WFD -+ case 2: /* WFD */ -+ i4Status = mtk_p2p_cfg80211_testmode_wfd_update_cmd(wiphy, data, len); -+ break; -+#endif -+ case 3: /* Hotspot Client Management */ -+ i4Status = mtk_p2p_cfg80211_testmode_hotspot_block_cmd(wiphy, data, len); -+ break; -+ case 0x10: -+ i4Status = mtk_cfg80211_testmode_get_sta_statistics(wiphy, data, len, prGlueInfo); -+ break; -+#if 1 -+ case 0x11: /*NFC Beam + Indication */ -+ prChnlReqInfo = &prGlueInfo->prAdapter->rWifiVar.prP2pFsmInfo->rChnlReqInfo; -+ if (data && len) { -+ P_NL80211_DRIVER_SET_NFC_PARAMS prParams = (P_NL80211_DRIVER_SET_NFC_PARAMS) data; -+ -+ prChnlReqInfo->NFC_BEAM = prParams->NFC_Enable; -+ DBGLOG(P2P, INFO, "NFC: BEAM[%d]\n", prChnlReqInfo->NFC_BEAM); -+ } -+ break; -+ case 0x12: /*NFC Beam + Indication */ -+ DBGLOG(P2P, INFO, "NFC: Polling\n"); -+ i4Status = mtk_cfg80211_testmode_get_scan_done(wiphy, data, len, prGlueInfo); -+ break; -+#endif -+#if CFG_AUTO_CHANNEL_SEL_SUPPORT -+ case 0x30: -+ i4Status = mtk_cfg80211_testmode_get_lte_channel(wiphy, data, len, prGlueInfo); -+ break; -+#endif -+ -+ default: -+ i4Status = -EINVAL; -+ break; -+ } -+ } -+ -+ return i4Status; -+} -+ -+int mtk_p2p_cfg80211_testmode_p2p_sigma_pre_cmd(IN struct wiphy *wiphy, IN void *data, IN int len) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ NL80211_DRIVER_TEST_PRE_PARAMS rParams; -+ P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo = (P_P2P_SPECIFIC_BSS_INFO_T) NULL; -+ P_P2P_CONNECTION_SETTINGS_T prP2pConnSettings = (P_P2P_CONNECTION_SETTINGS_T) NULL; -+ UINT_32 index_mode; -+ UINT_32 index; -+ INT_32 value; -+ int status = 0; -+ UINT_32 u4Leng; -+ -+ ASSERT(wiphy); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); -+ -+ kalMemZero(&rParams, sizeof(NL80211_DRIVER_TEST_PRE_PARAMS)); -+ -+ prP2pSpecificBssInfo = prGlueInfo->prAdapter->rWifiVar.prP2pSpecificBssInfo; -+ prP2pConnSettings = prGlueInfo->prAdapter->rWifiVar.prP2PConnSettings; -+ -+ DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_testmode_p2p_sigma_pre_cmd\n"); -+ -+ if (data && len) -+ memcpy(&rParams, data, len); -+ -+ DBGLOG(P2P, TRACE, "NL80211_ATTR_TESTDATA,idx_mode=%d idx=%d value=%u\n", -+ (INT_16) rParams.idx_mode, (INT_16) rParams.idx, rParams.value); -+ -+ index_mode = rParams.idx_mode; -+ index = rParams.idx; -+ value = rParams.value; -+ -+ switch (index) { -+ case 0: /* Listen CH */ -+ break; -+ case 1: /* P2p mode */ -+ break; -+ case 4: /* Noa duration */ -+ prP2pSpecificBssInfo->rNoaParam.u4NoaDurationMs = value; -+ /* only to apply setting when setting NOA count */ -+ /* status = mtk_p2p_wext_set_noa_param(prDev, info, wrqu, (char *)&prP2pSpecificBssInfo->rNoaParam); */ -+ break; -+ case 5: /* Noa interval */ -+ prP2pSpecificBssInfo->rNoaParam.u4NoaIntervalMs = value; -+ /* only to apply setting when setting NOA count */ -+ /* status = mtk_p2p_wext_set_noa_param(prDev, info, wrqu, (char *)&prP2pSpecificBssInfo->rNoaParam); */ -+ break; -+ case 6: /* Noa count */ -+ prP2pSpecificBssInfo->rNoaParam.u4NoaCount = value; -+ /* status = mtk_p2p_wext_set_noa_param(prDev, info, wrqu, (char *)&prP2pSpecificBssInfo->rNoaParam); */ -+ break; -+ case 100: /* Oper CH */ -+ /* 20110920 - frog: User configurations are placed in ConnSettings. */ -+ /* prP2pConnSettings->ucOperatingChnl = value; */ -+ break; -+ case 101: /* Local config Method, for P2P SDK */ -+ prP2pConnSettings->u2LocalConfigMethod = value; -+ break; -+ case 102: /* Sigma P2p reset */ -+ /* kalMemZero(prP2pConnSettings->aucTargetDevAddr, MAC_ADDR_LEN); */ -+ /* prP2pConnSettings->eConnectionPolicy = ENUM_P2P_CONNECTION_POLICY_AUTO; */ -+ p2pFsmUninit(prGlueInfo->prAdapter); -+ p2pFsmInit(prGlueInfo->prAdapter); -+ break; -+ case 103: /* WPS MODE */ -+ kalP2PSetWscMode(prGlueInfo, value); -+ break; -+ case 104: /* P2p send persence, duration */ -+ break; -+ case 105: /* P2p send persence, interval */ -+ break; -+ case 106: /* P2P set sleep */ -+ value = 1; -+ kalIoctl(prGlueInfo, -+ wlanoidSetP2pPowerSaveProfile, &value, sizeof(value), FALSE, FALSE, TRUE, TRUE, &u4Leng); -+ break; -+ case 107: /* P2P set opps, CTWindowl */ -+ prP2pSpecificBssInfo->rOppPsParam.u4CTwindowMs = value; -+ /* status = mtk_p2p_wext_set_oppps_param(prDev,info,wrqu,(char *)&prP2pSpecificBssInfo->rOppPsParam); */ -+ break; -+ case 108: /* p2p_set_power_save */ -+ kalIoctl(prGlueInfo, -+ wlanoidSetP2pPowerSaveProfile, &value, sizeof(value), FALSE, FALSE, TRUE, TRUE, &u4Leng); -+ -+ break; -+ default: -+ break; -+ } -+ -+ return status; -+ -+} -+ -+int mtk_p2p_cfg80211_testmode_p2p_sigma_cmd(IN struct wiphy *wiphy, IN void *data, IN int len) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ P_NL80211_DRIVER_P2P_SIGMA_PARAMS prParams = (P_NL80211_DRIVER_P2P_SIGMA_PARAMS) NULL; -+ P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo = (P_P2P_SPECIFIC_BSS_INFO_T) NULL; -+ P_P2P_CONNECTION_SETTINGS_T prP2pConnSettings = (P_P2P_CONNECTION_SETTINGS_T) NULL; -+ UINT_32 index; -+ INT_32 value; -+ int status = 0; -+ UINT_32 u4Leng; -+ -+ ASSERT(wiphy); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); -+ -+ prP2pSpecificBssInfo = prGlueInfo->prAdapter->rWifiVar.prP2pSpecificBssInfo; -+ prP2pConnSettings = prGlueInfo->prAdapter->rWifiVar.prP2PConnSettings; -+ -+ DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_testmode_p2p_sigma_cmd\n"); -+ -+ if (data && len) { -+ prParams = (P_NL80211_DRIVER_P2P_SIGMA_PARAMS) data; -+ } else { -+ DBGLOG(P2P, ERROR, "mtk_p2p_cfg80211_testmode_p2p_sigma_cmd, data is NULL or len is 0\n"); -+ return -EINVAL; -+ } -+ -+ index = (INT_32) prParams->idx; -+ value = (INT_32) prParams->value; -+ -+ DBGLOG(P2P, TRACE, "NL80211_ATTR_TESTDATA, idx=%d value=%d\n", -+ (INT_32) prParams->idx, (INT_32) prParams->value); -+ -+ switch (index) { -+ case 0: /* Listen CH */ -+ break; -+ case 1: /* P2p mode */ -+ break; -+ case 4: /* Noa duration */ -+ prP2pSpecificBssInfo->rNoaParam.u4NoaDurationMs = value; -+ /* only to apply setting when setting NOA count */ -+ /* status = mtk_p2p_wext_set_noa_param(prDev, info, wrqu, (char *)&prP2pSpecificBssInfo->rNoaParam); */ -+ break; -+ case 5: /* Noa interval */ -+ prP2pSpecificBssInfo->rNoaParam.u4NoaIntervalMs = value; -+ /* only to apply setting when setting NOA count */ -+ /* status = mtk_p2p_wext_set_noa_param(prDev, info, wrqu, (char *)&prP2pSpecificBssInfo->rNoaParam); */ -+ break; -+ case 6: /* Noa count */ -+ prP2pSpecificBssInfo->rNoaParam.u4NoaCount = value; -+ /* status = mtk_p2p_wext_set_noa_param(prDev, info, wrqu, (char *)&prP2pSpecificBssInfo->rNoaParam); */ -+ break; -+ case 100: /* Oper CH */ -+ /* 20110920 - frog: User configurations are placed in ConnSettings. */ -+ /* prP2pConnSettings->ucOperatingChnl = value; */ -+ break; -+ case 101: /* Local config Method, for P2P SDK */ -+ prP2pConnSettings->u2LocalConfigMethod = value; -+ break; -+ case 102: /* Sigma P2p reset */ -+ /* kalMemZero(prP2pConnSettings->aucTargetDevAddr, MAC_ADDR_LEN); */ -+ /* prP2pConnSettings->eConnectionPolicy = ENUM_P2P_CONNECTION_POLICY_AUTO; */ -+ break; -+ case 103: /* WPS MODE */ -+ kalP2PSetWscMode(prGlueInfo, value); -+ break; -+ case 104: /* P2p send persence, duration */ -+ break; -+ case 105: /* P2p send persence, interval */ -+ break; -+ case 106: /* P2P set sleep */ -+ value = 1; -+ kalIoctl(prGlueInfo, -+ wlanoidSetP2pPowerSaveProfile, &value, sizeof(value), FALSE, FALSE, TRUE, TRUE, &u4Leng); -+ break; -+ case 107: /* P2P set opps, CTWindowl */ -+ prP2pSpecificBssInfo->rOppPsParam.u4CTwindowMs = value; -+ /* status = mtk_p2p_wext_set_oppps_param(prDev,info,wrqu,(char *)&prP2pSpecificBssInfo->rOppPsParam); */ -+ break; -+ case 108: /* p2p_set_power_save */ -+ kalIoctl(prGlueInfo, -+ wlanoidSetP2pPowerSaveProfile, &value, sizeof(value), FALSE, FALSE, TRUE, TRUE, &u4Leng); -+ -+ break; -+ case 109: /* Max Clients */ -+ kalP2PSetMaxClients(prGlueInfo, value); -+ break; -+ case 110: /* Hotspot WPS mode */ -+ kalIoctl(prGlueInfo, wlanoidSetP2pWPSmode, &value, sizeof(value), FALSE, FALSE, TRUE, TRUE, &u4Leng); -+ break; -+ default: -+ break; -+ } -+ -+ return status; -+ -+} -+ -+#if CFG_SUPPORT_WFD -+int mtk_p2p_cfg80211_testmode_wfd_update_cmd(IN struct wiphy *wiphy, IN void *data, IN int len) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ P_NL80211_DRIVER_WFD_PARAMS prParams = (P_NL80211_DRIVER_WFD_PARAMS) NULL; -+ int status = 0; -+ P_WFD_CFG_SETTINGS_T prWfdCfgSettings = (P_WFD_CFG_SETTINGS_T) NULL; -+ P_MSG_WFD_CONFIG_SETTINGS_CHANGED_T prMsgWfdCfgUpdate = (P_MSG_WFD_CONFIG_SETTINGS_CHANGED_T) NULL; -+ static UINT_8 prevWfdEnable; -+ -+ ASSERT(wiphy); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); -+ -+ prParams = (P_NL80211_DRIVER_WFD_PARAMS) data; -+ -+ DBGLOG(P2P, INFO, "mtk_p2p_cfg80211_testmode_wfd_update_cmd\n"); -+ -+ /* to reduce log, print when state changed */ -+ if (prevWfdEnable != prParams->WfdEnable) { -+ prevWfdEnable = prParams->WfdEnable; -+ DBGLOG(P2P, INFO, "WFD Enable:%x\n", prParams->WfdEnable); -+ DBGLOG(P2P, INFO, "WFD Session Available:%x\n", prParams->WfdSessionAvailable); -+ DBGLOG(P2P, INFO, "WFD Couple Sink Status:%x\n", prParams->WfdCoupleSinkStatus); -+ /* aucReserved0[2] */ -+ DBGLOG(P2P, INFO, "WFD Device Info:%x\n", prParams->WfdDevInfo); -+ DBGLOG(P2P, INFO, "WFD Control Port:%x\n", prParams->WfdControlPort); -+ DBGLOG(P2P, INFO, "WFD Maximum Throughput:%x\n", prParams->WfdMaximumTp); -+ DBGLOG(P2P, INFO, "WFD Extend Capability:%x\n", prParams->WfdExtendCap); -+ DBGLOG(P2P, INFO, "WFD Couple Sink Addr %pM\n", prParams->WfdCoupleSinkAddress); -+ DBGLOG(P2P, INFO, "WFD Associated BSSID %pM\n", prParams->WfdAssociatedBssid); -+ /* UINT_8 aucVideolp[4]; */ -+ /* UINT_8 aucAudiolp[4]; */ -+ DBGLOG(P2P, INFO, "WFD Video Port:%x\n", prParams->WfdVideoPort); -+ DBGLOG(P2P, INFO, "WFD Audio Port:%x\n", prParams->WfdAudioPort); -+ DBGLOG(P2P, INFO, "WFD Flag:%x\n", prParams->WfdFlag); -+ DBGLOG(P2P, INFO, "WFD Policy:%x\n", prParams->WfdPolicy); -+ DBGLOG(P2P, INFO, "WFD State:%x\n", prParams->WfdState); -+ /* UINT_8 aucWfdSessionInformationIE[24*8]; */ -+ DBGLOG(P2P, INFO, "WFD Session Info Length:%x\n", prParams->WfdSessionInformationIELen); -+ /* UINT_8 aucReserved1[2]; */ -+ DBGLOG(P2P, INFO, "WFD Primary Sink Addr %pM\n", prParams->aucWfdPrimarySinkMac); -+ DBGLOG(P2P, INFO, "WFD Secondary Sink Addr %pM\n", prParams->aucWfdSecondarySinkMac); -+ DBGLOG(P2P, INFO, "WFD Advanced Flag:%x\n", prParams->WfdAdvanceFlag); -+ DBGLOG(P2P, INFO, "WFD Sigma mode:%x\n", prParams->WfdSigmaMode); -+ /* UINT_8 aucReserved2[64]; */ -+ /* UINT_8 aucReserved3[64]; */ -+ /* UINT_8 aucReserved4[64]; */ -+ } -+ -+ prWfdCfgSettings = &(prGlueInfo->prAdapter->rWifiVar.prP2pFsmInfo->rWfdConfigureSettings); -+ -+ kalMemCopy(&prWfdCfgSettings->u4WfdCmdType, &prParams->WfdCmdType, sizeof(WFD_CFG_SETTINGS_T)); -+ -+ prMsgWfdCfgUpdate = cnmMemAlloc(prGlueInfo->prAdapter, RAM_TYPE_MSG, sizeof(MSG_WFD_CONFIG_SETTINGS_CHANGED_T)); -+ -+ if (prMsgWfdCfgUpdate == NULL) { -+ ASSERT(FALSE); -+ return status; -+ } -+ -+ prMsgWfdCfgUpdate->rMsgHdr.eMsgId = MID_MNY_P2P_WFD_CFG_UPDATE; -+ prMsgWfdCfgUpdate->prWfdCfgSettings = prWfdCfgSettings; -+ -+ mboxSendMsg(prGlueInfo->prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgWfdCfgUpdate, MSG_SEND_METHOD_BUF); -+#if 0 /* Test Only */ -+/* prWfdCfgSettings->ucWfdEnable = 1; */ -+/* prWfdCfgSettings->u4WfdFlag |= WFD_FLAGS_DEV_INFO_VALID; */ -+ prWfdCfgSettings->u4WfdFlag |= WFD_FLAGS_DEV_INFO_VALID; -+ prWfdCfgSettings->u2WfdDevInfo = 123; -+ prWfdCfgSettings->u2WfdControlPort = 456; -+ prWfdCfgSettings->u2WfdMaximumTp = 789; -+ -+ prWfdCfgSettings->u4WfdFlag |= WFD_FLAGS_SINK_INFO_VALID; -+ prWfdCfgSettings->ucWfdCoupleSinkStatus = 0xAB; -+ { -+ UINT_8 aucTestAddr[MAC_ADDR_LEN] = { 0x77, 0x66, 0x55, 0x44, 0x33, 0x22 }; -+ -+ COPY_MAC_ADDR(prWfdCfgSettings->aucWfdCoupleSinkAddress, aucTestAddr); -+ } -+ -+ prWfdCfgSettings->u4WfdFlag |= WFD_FLAGS_EXT_CAPABILITY_VALID; -+ prWfdCfgSettings->u2WfdExtendCap = 0xCDE; -+ -+#endif -+ -+ return status; -+ -+} -+#endif /* CFG_SUPPORT_WFD */ -+ -+int mtk_p2p_cfg80211_testmode_hotspot_block_cmd(IN struct wiphy *wiphy, IN void *data, IN int len) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ P_NL80211_DRIVER_HOTSPOT_BLOCK_PARAMS prParams = (P_NL80211_DRIVER_HOTSPOT_BLOCK_PARAMS) NULL; -+ -+ ASSERT(wiphy); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); -+ -+ if (data && len) { -+ prParams = (P_NL80211_DRIVER_HOTSPOT_BLOCK_PARAMS) data; -+ } else { -+ DBGLOG(P2P, ERROR, "mtk_p2p_cfg80211_testmode_hotspot_block_cmd, data is NULL or len is 0\n"); -+ return -EINVAL; -+ } -+ -+ DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_testmode_hotspot_block_cmd\n"); -+ -+ return kalP2PSetBlackList(prGlueInfo, prParams->aucBssid, prParams->ucblocked); -+} -+ -+int mtk_p2p_cfg80211_testmode_sw_cmd(IN struct wiphy *wiphy, IN void *data, IN int len) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ P_NL80211_DRIVER_SW_CMD_PARAMS prParams = (P_NL80211_DRIVER_SW_CMD_PARAMS) NULL; -+ WLAN_STATUS rstatus = WLAN_STATUS_SUCCESS; -+ int fgIsValid = 0; -+ UINT_32 u4SetInfoLen = 0; -+ -+ ASSERT(wiphy); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); -+ -+#if 1 -+ DBGLOG(P2P, TRACE, "--> %s()\n", __func__); -+#endif -+ -+ if (data && len) -+ prParams = (P_NL80211_DRIVER_SW_CMD_PARAMS) data; -+ -+ if (prParams) { -+ if (prParams->set == 1) { -+ rstatus = kalIoctl(prGlueInfo, -+ (PFN_OID_HANDLER_FUNC) wlanoidSetSwCtrlWrite, -+ &prParams->adr, (UINT_32) 8, FALSE, FALSE, TRUE, FALSE, &u4SetInfoLen); -+ } -+ } -+ -+ if (WLAN_STATUS_SUCCESS != rstatus) -+ fgIsValid = -EFAULT; -+ -+ return fgIsValid; -+} -+ -+#endif -+ -+#endif /* CFG_ENABLE_WIFI_DIRECT && CFG_ENABLE_WIFI_DIRECT_CFG_80211 */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_p2p_init.c b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_p2p_init.c -new file mode 100644 -index 000000000000..d0f2d25a4529 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_p2p_init.c -@@ -0,0 +1,433 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -+ -+/* -+** Id: @(#) gl_p2p_init.c@@ -+*/ -+ -+/*! \file gl_p2p_init.c -+ \brief init and exit routines of Linux driver interface for Wi-Fi Direct -+ -+ This file contains the main routines of Linux driver for MediaTek Inc. 802.11 -+ Wireless LAN Adapters. -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+#include "precomp.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+#define P2P_MODE_INF_NAME "p2p%d" -+#if CFG_TC1_FEATURE -+#define AP_MODE_INF_NAME "wlan%d" -+#else -+#define AP_MODE_INF_NAME "ap%d" -+#endif -+/* #define MAX_INF_NAME_LEN 15 */ -+/* #define MIN_INF_NAME_LEN 1 */ -+ -+#define RUNNING_P2P_MODE 0 -+#define RUNNING_AP_MODE 1 -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/* Get interface name and running mode from module insertion parameter -+* Usage: insmod p2p.ko mode=1 -+* default: interface name is p2p%d -+* running mode is P2P -+*/ -+static PUCHAR ifname = P2P_MODE_INF_NAME; -+static UINT_16 mode = RUNNING_P2P_MODE; -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief check interface name parameter is valid or not -+* if invalid, set ifname to P2P_MODE_INF_NAME -+* -+* -+* \retval -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID p2pCheckInterfaceName(VOID) -+{ -+ -+ if (mode) { -+ mode = RUNNING_AP_MODE; -+ ifname = AP_MODE_INF_NAME; -+ } -+#if 0 -+ UINT_32 ifLen = 0; -+ -+ if (ifname) { -+ ifLen = strlen(ifname); -+ -+ if (ifLen > MAX_INF_NAME_LEN) -+ ifname[MAX_INF_NAME_LEN] = '\0'; -+ else if (ifLen < MIN_INF_NAME_LEN) -+ ifname = P2P_MODE_INF_NAME; -+ } else { -+ ifname = P2P_MODE_INF_NAME; -+ } -+#endif -+} -+ -+void p2pHandleSystemSuspend(void) -+{ -+ struct net_device *prDev = NULL; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ UINT_8 ip[4] = { 0 }; -+ UINT_32 u4NumIPv4 = 0; -+#ifdef CONFIG_IPV6 -+ UINT_8 ip6[16] = { 0 }; /* FIX ME: avoid to allocate large memory in stack */ -+ UINT_32 u4NumIPv6 = 0; -+#endif -+ UINT_32 i; -+ P_PARAM_NETWORK_ADDRESS_IP prParamIpAddr; -+ -+ -+ if (!wlanExportGlueInfo(&prGlueInfo)) { -+ DBGLOG(P2P, INFO, "No glue info\n"); -+ return; -+ } -+ -+ ASSERT(prGlueInfo); -+ /* <1> Sanity check and acquire the net_device */ -+ prDev = prGlueInfo->prP2PInfo->prDevHandler; -+ ASSERT(prDev); -+ -+ /* <3> get the IPv4 address */ -+ if (!prDev || !(prDev->ip_ptr) || -+ !((struct in_device *)(prDev->ip_ptr))->ifa_list || -+ !(&(((struct in_device *)(prDev->ip_ptr))->ifa_list->ifa_local))) { -+ DBGLOG(P2P, INFO, "ip is not available.\n"); -+ return; -+ } -+ /* <4> copy the IPv4 address */ -+ kalMemCopy(ip, &(((struct in_device *)(prDev->ip_ptr))->ifa_list->ifa_local), sizeof(ip)); -+ -+ /* todo: traverse between list to find whole sets of IPv4 addresses */ -+ if (!((ip[0] == 0) && (ip[1] == 0) && (ip[2] == 0) && (ip[3] == 0))) -+ u4NumIPv4++; -+#ifdef CONFIG_IPV6 -+ /* <5> get the IPv6 address */ -+ if (!prDev || !(prDev->ip6_ptr) || -+ !((struct in_device *)(prDev->ip6_ptr))->ifa_list || -+ !(&(((struct in_device *)(prDev->ip6_ptr))->ifa_list->ifa_local))) { -+ DBGLOG(P2P, INFO, "ipv6 is not available.\n"); -+ return; -+ } -+ /* <6> copy the IPv6 address */ -+ kalMemCopy(ip6, &(((struct in_device *)(prDev->ip6_ptr))->ifa_list->ifa_local), sizeof(ip6)); -+ DBGLOG(P2P, INFO, "ipv6 is %d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d\n", -+ ip6[0], ip6[1], ip6[2], ip6[3], -+ ip6[4], ip6[5], ip6[6], ip6[7], ip6[8], ip6[9], ip6[10], ip6[11], ip6[12], ip6[13], ip6[14], ip6[15]); -+ /* todo: traverse between list to find whole sets of IPv6 addresses */ -+ -+ if (!((ip6[0] == 0) && (ip6[1] == 0) && (ip6[2] == 0) && (ip6[3] == 0) && (ip6[4] == 0) && (ip6[5] == 0))) -+ ; /* Do nothing */ -+#endif -+ /* <7> set up the ARP filter */ -+ { -+ WLAN_STATUS rStatus = WLAN_STATUS_FAILURE; -+ UINT_32 u4SetInfoLen = 0; -+/* UINT_8 aucBuf[32] = {0}; */ -+ UINT_32 u4Len = OFFSET_OF(PARAM_NETWORK_ADDRESS_LIST, arAddress); -+ P_PARAM_NETWORK_ADDRESS_LIST prParamNetAddrList = (P_PARAM_NETWORK_ADDRESS_LIST) g_aucBufIpAddr; -+ /* aucBuf; */ -+ P_PARAM_NETWORK_ADDRESS prParamNetAddr = prParamNetAddrList->arAddress; -+ -+ kalMemZero(g_aucBufIpAddr, sizeof(g_aucBufIpAddr)); -+ -+ prParamNetAddrList->u4AddressCount = u4NumIPv4; -+#ifdef CONFIG_IPV6 -+ prParamNetAddrList->u4AddressCount += u4NumIPv6; -+#endif -+ -+ prParamNetAddrList->u2AddressType = PARAM_PROTOCOL_ID_TCP_IP; -+ for (i = 0; i < u4NumIPv4; i++) { -+ prParamNetAddr->u2AddressLength = sizeof(PARAM_NETWORK_ADDRESS_IP); /* 4;; */ -+ prParamNetAddr->u2AddressType = PARAM_PROTOCOL_ID_TCP_IP; -+#if 0 -+ kalMemCopy(prParamNetAddr->aucAddress, ip, sizeof(ip)); -+ prParamNetAddr = (P_PARAM_NETWORK_ADDRESS) ((UINT_32) prParamNetAddr + sizeof(ip)); -+ u4Len += OFFSET_OF(PARAM_NETWORK_ADDRESS, aucAddress) + sizeof(ip); -+#else -+ prParamIpAddr = (P_PARAM_NETWORK_ADDRESS_IP) prParamNetAddr->aucAddress; -+ kalMemCopy(&prParamIpAddr->in_addr, ip, sizeof(ip)); -+ -+/* prParamNetAddr = (P_PARAM_NETWORK_ADDRESS)((UINT_32)prParamNetAddr + sizeof(PARAM_NETWORK_ADDRESS)); -+// TODO: frog. The pointer is not right. */ -+ -+ prParamNetAddr = (P_PARAM_NETWORK_ADDRESS) ((ULONG) prParamNetAddr + -+ (ULONG) (prParamNetAddr->u2AddressLength + -+ OFFSET_OF(PARAM_NETWORK_ADDRESS, -+ aucAddress))); -+ -+ u4Len += OFFSET_OF(PARAM_NETWORK_ADDRESS, aucAddress) + sizeof(PARAM_NETWORK_ADDRESS_IP); -+#endif -+ } -+#ifdef CONFIG_IPV6 -+ for (i = 0; i < u4NumIPv6; i++) { -+ prParamNetAddr->u2AddressLength = 6; -+ prParamNetAddr->u2AddressType = PARAM_PROTOCOL_ID_TCP_IP; -+ kalMemCopy(prParamNetAddr->aucAddress, ip6, sizeof(ip6)); -+/* prParamNetAddr = (P_PARAM_NETWORK_ADDRESS)((UINT_32)prParamNetAddr + sizeof(ip6)); */ -+ -+ prParamNetAddr = (P_PARAM_NETWORK_ADDRESS) ((ULONG) prParamNetAddr + -+ (ULONG) (prParamNetAddr->u2AddressLength + -+ OFFSET_OF(PARAM_NETWORK_ADDRESS, -+ aucAddress))); -+ -+ u4Len += OFFSET_OF(PARAM_NETWORK_ADDRESS, aucAddress) + sizeof(ip6); -+ } -+#endif -+ ASSERT(u4Len <= sizeof(g_aucBufIpAddr /*aucBuf */)); -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetP2pSetNetworkAddress, -+ (PVOID) prParamNetAddrList, u4Len, FALSE, FALSE, TRUE, TRUE, &u4SetInfoLen); -+ -+ DBGLOG(INIT, INFO, "IP: %d.%d.%d.%d, rStatus: %u\n", ip[0], ip[1], ip[2], ip[3], rStatus); -+ } -+} -+ -+void p2pHandleSystemResume(void) -+{ -+ struct net_device *prDev = NULL; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ UINT_8 ip[4] = { 0 }; -+#ifdef CONFIG_IPV6 -+ UINT_8 ip6[16] = { 0 }; /* FIX ME: avoid to allocate large memory in stack */ -+#endif -+ -+ if (!wlanExportGlueInfo(&prGlueInfo)) { -+ DBGLOG(P2P, WARN, "no glue info\n"); -+ return; -+ } -+ -+ ASSERT(prGlueInfo); -+ /* <1> Sanity check and acquire the net_device */ -+ prDev = prGlueInfo->prP2PInfo->prDevHandler; -+ ASSERT(prDev); -+ -+ /* <3> get the IPv4 address */ -+ if (!prDev || !(prDev->ip_ptr) || -+ !((struct in_device *)(prDev->ip_ptr))->ifa_list || -+ !(&(((struct in_device *)(prDev->ip_ptr))->ifa_list->ifa_local))) { -+ DBGLOG(P2P, INFO, "ip is not available.\n"); -+ return; -+ } -+ /* <4> copy the IPv4 address */ -+ kalMemCopy(ip, &(((struct in_device *)(prDev->ip_ptr))->ifa_list->ifa_local), sizeof(ip)); -+ -+#ifdef CONFIG_IPV6 -+ /* <5> get the IPv6 address */ -+ if (!prDev || !(prDev->ip6_ptr) || -+ !((struct in_device *)(prDev->ip6_ptr))->ifa_list || -+ !(&(((struct in_device *)(prDev->ip6_ptr))->ifa_list->ifa_local))) { -+ DBGLOG(P2P, INFO, "ipv6 is not available.\n"); -+ return; -+ } -+ /* <6> copy the IPv6 address */ -+ kalMemCopy(ip6, &(((struct in_device *)(prDev->ip6_ptr))->ifa_list->ifa_local), sizeof(ip6)); -+ DBGLOG(P2P, INFO, "ipv6 is %d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d\n", -+ ip6[0], ip6[1], ip6[2], ip6[3], -+ ip6[4], ip6[5], ip6[6], ip6[7], ip6[8], ip6[9], ip6[10], ip6[11], ip6[12], ip6[13], ip6[14], ip6[15]); -+#endif -+ /* <7> clear the ARP filter */ -+ { -+ WLAN_STATUS rStatus = WLAN_STATUS_FAILURE; -+ UINT_32 u4SetInfoLen = 0; -+/* UINT_8 aucBuf[32] = {0}; */ -+ UINT_32 u4Len = sizeof(PARAM_NETWORK_ADDRESS_LIST); -+ P_PARAM_NETWORK_ADDRESS_LIST prParamNetAddrList = (P_PARAM_NETWORK_ADDRESS_LIST) g_aucBufIpAddr; -+ /* aucBuf; */ -+ -+ kalMemZero(g_aucBufIpAddr, sizeof(g_aucBufIpAddr)); -+ -+ prParamNetAddrList->u4AddressCount = 0; -+ prParamNetAddrList->u2AddressType = PARAM_PROTOCOL_ID_TCP_IP; -+ -+ ASSERT(u4Len <= sizeof(g_aucBufIpAddr /*aucBuf */)); -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetP2pSetNetworkAddress, -+ (PVOID) prParamNetAddrList, u4Len, FALSE, FALSE, TRUE, TRUE, &u4SetInfoLen); -+ -+ DBGLOG(INIT, INFO, "IP: %d.%d.%d.%d, rStatus: %u\n", ip[0], ip[1], ip[2], ip[3], rStatus); -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* run p2p init procedure, include register pointer to wlan -+* glue register p2p -+* set p2p registered flag -+* \retval 1 Success -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN p2pLaunch(P_GLUE_INFO_T prGlueInfo) -+{ -+ -+ DBGLOG(P2P, TRACE, "p2pLaunch\n"); -+ -+ if (prGlueInfo->prAdapter->fgIsP2PRegistered == TRUE) { -+ DBGLOG(P2P, INFO, "p2p already registered\n"); -+ return FALSE; -+ } else if (glRegisterP2P(prGlueInfo, ifname, (BOOLEAN) mode)) { -+ prGlueInfo->prAdapter->fgIsP2PRegistered = TRUE; -+ -+ DBGLOG(P2P, TRACE, "Launch success, fgIsP2PRegistered TRUE.\n"); -+ return TRUE; -+ } -+ DBGLOG(P2P, ERROR, "Launch Fail\n"); -+ -+ return FALSE; -+} -+ -+VOID p2pSetMode(IN BOOLEAN fgIsAPMOde) -+{ -+ if (fgIsAPMOde) { -+ mode = RUNNING_AP_MODE; -+ ifname = AP_MODE_INF_NAME; -+ } else { -+ mode = RUNNING_P2P_MODE; -+ ifname = P2P_MODE_INF_NAME; -+ } -+ -+} /* p2pSetMode */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* run p2p exit procedure, include unregister pointer to wlan -+* glue unregister p2p -+* set p2p registered flag -+ -+* \retval 1 Success -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN p2pRemove(P_GLUE_INFO_T prGlueInfo) -+{ -+ if (prGlueInfo->prAdapter->fgIsP2PRegistered == FALSE) { -+ DBGLOG(P2P, INFO, "p2p is not Registered.\n"); -+ return FALSE; -+ } -+ /*Check p2p fsm is stop or not. If not then stop now */ -+ if (IS_P2P_ACTIVE(prGlueInfo->prAdapter)) -+ p2pStopImmediate(prGlueInfo); -+ prGlueInfo->prAdapter->fgIsP2PRegistered = FALSE; -+ glUnregisterP2P(prGlueInfo); -+ /*p2p is removed successfully */ -+ return TRUE; -+ -+} -+ -+#if 0 -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Driver entry point when the driver is configured as a Linux Module, and -+* is called once at module load time, by the user-level modutils -+* application: insmod or modprobe. -+* -+* \retval 0 Success -+*/ -+/*----------------------------------------------------------------------------*/ -+static int initP2P(void) -+{ -+ P_GLUE_INFO_T prGlueInfo; -+ -+ /*check interface name validation */ -+ p2pCheckInterfaceName(); -+ -+ DBGLOG(P2P, INFO, "InitP2P, Ifname: %s, Mode: %s\n", ifname, mode ? "AP" : "P2P"); -+ -+ /*register p2p init & exit function to wlan sub module handler */ -+ wlanSubModRegisterInitExit(p2pLaunch, p2pRemove, P2P_MODULE); -+ -+ /*if wlan is not start yet, do nothing -+ * p2pLaunch will be called by txthread while wlan start -+ */ -+ /*if wlan is not started yet, return FALSE */ -+ if (wlanExportGlueInfo(&prGlueInfo)) { -+ wlanSubModInit(prGlueInfo); -+ return prGlueInfo->prAdapter->fgIsP2PRegistered ? 0 : -EIO; -+ } -+ -+ return 0; -+} /* end of initP2P() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Driver exit point when the driver as a Linux Module is removed. Called -+* at module unload time, by the user level modutils application: rmmod. -+* This is our last chance to clean up after ourselves. -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+/* 1 Module Leave Point */ -+static VOID __exit exitP2P(void) -+{ -+ P_GLUE_INFO_T prGlueInfo; -+ -+ DBGLOG(P2P, INFO, KERN_INFO DRV_NAME "ExitP2P\n"); -+ -+ /*if wlan is not started yet, return FALSE */ -+ if (wlanExportGlueInfo(&prGlueInfo)) -+ wlanSubModExit(prGlueInfo); -+ /*UNregister p2p init & exit function to wlan sub module handler */ -+ wlanSubModRegisterInitExit(NULL, NULL, P2P_MODULE); -+} /* end of exitP2P() */ -+#endif -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_p2p_kal.c b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_p2p_kal.c -new file mode 100644 -index 000000000000..11a417e4c74c ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_p2p_kal.c -@@ -0,0 +1,1314 @@ -+/* -+** Id: @(#) gl_p2p_cfg80211.c@@ -+*/ -+ -+/*! \file gl_p2p_kal.c -+ \brief -+ -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "net/cfg80211.h" -+#include "precomp.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief to retrieve Wi-Fi Direct state from glue layer -+* -+* \param[in] -+* prGlueInfo -+* rPeerAddr -+* \return -+* ENUM_BOW_DEVICE_STATE -+*/ -+/*----------------------------------------------------------------------------*/ -+ENUM_PARAM_MEDIA_STATE_T kalP2PGetState(IN P_GLUE_INFO_T prGlueInfo) -+{ -+ ASSERT(prGlueInfo); -+ -+ return prGlueInfo->prP2PInfo->eState; -+} /* end of kalP2PGetState() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief to update the assoc req to p2p -+* -+* \param[in] -+* prGlueInfo -+* pucFrameBody -+* u4FrameBodyLen -+* fgReassocRequest -+* \return -+* none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+kalP2PUpdateAssocInfo(IN P_GLUE_INFO_T prGlueInfo, -+ IN PUINT_8 pucFrameBody, IN UINT_32 u4FrameBodyLen, IN BOOLEAN fgReassocRequest) -+{ -+ union iwreq_data wrqu; -+ unsigned char *pucExtraInfo = NULL; -+ unsigned char *pucDesiredIE = NULL; -+/* unsigned char aucExtraInfoBuf[200]; */ -+ PUINT_8 cp; -+ -+ memset(&wrqu, 0, sizeof(wrqu)); -+ -+ if (fgReassocRequest) { -+ if (u4FrameBodyLen < 15) { -+ /* -+ printk(KERN_WARNING "frameBodyLen too short:%ld\n", frameBodyLen); -+ */ -+ return; -+ } -+ } else { -+ if (u4FrameBodyLen < 9) { -+ /* -+ printk(KERN_WARNING "frameBodyLen too short:%ld\n", frameBodyLen); -+ */ -+ return; -+ } -+ } -+ -+ cp = pucFrameBody; -+ -+ if (fgReassocRequest) { -+ /* Capability information field 2 */ -+ /* Listen interval field 2 */ -+ /* Current AP address 6 */ -+ cp += 10; -+ u4FrameBodyLen -= 10; -+ } else { -+ /* Capability information field 2 */ -+ /* Listen interval field 2 */ -+ cp += 4; -+ u4FrameBodyLen -= 4; -+ } -+ -+ /* do supplicant a favor, parse to the start of WPA/RSN IE */ -+ if (wextSrchDesiredWPSIE(cp, u4FrameBodyLen, 0xDD, &pucDesiredIE)) { -+ /* printk("wextSrchDesiredWPSIE!!\n"); */ -+ /* WPS IE found */ -+ } else if (wextSrchDesiredWPAIE(cp, u4FrameBodyLen, 0x30, &pucDesiredIE)) { -+ /* printk("wextSrchDesiredWPAIE!!\n"); */ -+ /* RSN IE found */ -+ } else if (wextSrchDesiredWPAIE(cp, u4FrameBodyLen, 0xDD, &pucDesiredIE)) { -+ /* printk("wextSrchDesiredWPAIE!!\n"); */ -+ /* WPA IE found */ -+ } else { -+ /* no WPA/RSN IE found, skip this event */ -+ goto skip_indicate_event; -+ } -+ -+ /* IWEVASSOCREQIE, indicate binary string */ -+ pucExtraInfo = pucDesiredIE; -+ wrqu.data.length = pucDesiredIE[1] + 2; -+ -+ /* Send event to user space */ -+ wireless_send_event(prGlueInfo->prP2PInfo->prDevHandler, IWEVASSOCREQIE, &wrqu, pucExtraInfo); -+ -+skip_indicate_event: -+ return; -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief to set Wi-Fi Direct state in glue layer -+* -+* \param[in] -+* prGlueInfo -+* eBowState -+* rPeerAddr -+* \return -+* none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+kalP2PSetState(IN P_GLUE_INFO_T prGlueInfo, -+ IN ENUM_PARAM_MEDIA_STATE_T eState, IN PARAM_MAC_ADDRESS rPeerAddr, IN UINT_8 ucRole) -+{ -+ union iwreq_data evt; -+ UINT_8 aucBuffer[IW_CUSTOM_MAX]; -+ -+ ASSERT(prGlueInfo); -+ -+ memset(&evt, 0, sizeof(evt)); -+ -+ if (eState == PARAM_MEDIA_STATE_CONNECTED) { -+ prGlueInfo->prP2PInfo->eState = PARAM_MEDIA_STATE_CONNECTED; -+ -+ snprintf(aucBuffer, IW_CUSTOM_MAX - 1, "P2P_STA_CONNECT=%pM ", rPeerAddr); -+ evt.data.length = strlen(aucBuffer); -+ -+ /* indicate in IWECUSTOM event */ -+ wireless_send_event(prGlueInfo->prP2PInfo->prDevHandler, IWEVCUSTOM, &evt, aucBuffer); -+ -+ } else if (eState == PARAM_MEDIA_STATE_DISCONNECTED) { -+ snprintf(aucBuffer, IW_CUSTOM_MAX - 1, "P2P_STA_DISCONNECT=%pM ", rPeerAddr); -+ evt.data.length = strlen(aucBuffer); -+ -+ /* indicate in IWECUSTOM event */ -+ wireless_send_event(prGlueInfo->prP2PInfo->prDevHandler, IWEVCUSTOM, &evt, aucBuffer); -+ } else { -+ ASSERT(0); -+ } -+ -+} /* end of kalP2PSetState() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief to retrieve Wi-Fi Direct operating frequency -+* -+* \param[in] -+* prGlueInfo -+* -+* \return -+* in unit of KHz -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT_32 kalP2PGetFreqInKHz(IN P_GLUE_INFO_T prGlueInfo) -+{ -+ ASSERT(prGlueInfo); -+ -+ return prGlueInfo->prP2PInfo->u4FreqInKHz; -+} /* end of kalP2PGetFreqInKHz() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief to retrieve Bluetooth-over-Wi-Fi role -+* -+* \param[in] -+* prGlueInfo -+* -+* \return -+* 0: P2P Device -+* 1: Group Client -+* 2: Group Owner -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT_8 kalP2PGetRole(IN P_GLUE_INFO_T prGlueInfo) -+{ -+ ASSERT(prGlueInfo); -+ -+ return prGlueInfo->prP2PInfo->ucRole; -+} /* end of kalP2PGetRole() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief to set Wi-Fi Direct role -+* -+* \param[in] -+* prGlueInfo -+* ucResult -+* 0: successful -+* 1: error -+* ucRole -+* 0: P2P Device -+* 1: Group Client -+* 2: Group Owner -+* -+* \return -+* none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+kalP2PSetRole(IN P_GLUE_INFO_T prGlueInfo, -+ IN UINT_8 ucResult, IN PUINT_8 pucSSID, IN UINT_8 ucSSIDLen, IN UINT_8 ucRole) -+{ -+ union iwreq_data evt; -+ UINT_8 aucBuffer[IW_CUSTOM_MAX]; -+ -+ ASSERT(prGlueInfo); -+ ASSERT(ucRole <= 2); -+ -+ memset(&evt, 0, sizeof(evt)); -+ -+ if (ucResult == 0) -+ prGlueInfo->prP2PInfo->ucRole = ucRole; -+ -+ if (pucSSID) -+ snprintf(aucBuffer, IW_CUSTOM_MAX - 1, "P2P_FORMATION_RST=%d%d%d%c%c", ucResult, ucRole, -+ 1 /* persistence or not */ , pucSSID[7], pucSSID[8]); -+ else -+ snprintf(aucBuffer, IW_CUSTOM_MAX - 1, "P2P_FORMATION_RST=%d%d%d%c%c", ucResult, ucRole, -+ 1 /* persistence or not */ , '0', '0'); -+ -+ evt.data.length = strlen(aucBuffer); -+ -+ /* if (pucSSID) */ -+ /* printk("P2P GO SSID DIRECT-%c%c\n", pucSSID[7], pucSSID[8]); */ -+ -+ /* indicate in IWECUSTOM event */ -+ wireless_send_event(prGlueInfo->prP2PInfo->prDevHandler, IWEVCUSTOM, &evt, aucBuffer); -+ -+} /* end of kalP2PSetRole() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief to set the cipher for p2p -+* -+* \param[in] -+* prGlueInfo -+* u4Cipher -+* -+* \return -+* none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID kalP2PSetCipher(IN P_GLUE_INFO_T prGlueInfo, IN UINT_32 u4Cipher) -+{ -+ if ((!prGlueInfo) || (!prGlueInfo->prP2PInfo)) { -+ ASSERT(FALSE); -+ return; -+ } -+ -+ prGlueInfo->prP2PInfo->u4CipherPairwise = u4Cipher; -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief to get the cipher, return for cipher is ccmp -+* -+* \param[in] -+* prGlueInfo -+* -+* \return -+* TRUE: cipher is ccmp -+* FALSE: cipher is none -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN kalP2PGetCipher(IN P_GLUE_INFO_T prGlueInfo) -+{ -+ if ((!prGlueInfo) || (!prGlueInfo->prP2PInfo)) { -+ ASSERT(FALSE); -+ return FALSE; -+ } -+ -+ if (prGlueInfo->prP2PInfo->u4CipherPairwise == IW_AUTH_CIPHER_CCMP) -+ return TRUE; -+ -+ if (prGlueInfo->prP2PInfo->u4CipherPairwise == IW_AUTH_CIPHER_TKIP) -+ return TRUE; -+ -+ return FALSE; -+} -+ -+BOOLEAN kalP2PGetCcmpCipher(IN P_GLUE_INFO_T prGlueInfo) -+{ -+ if ((!prGlueInfo) || (!prGlueInfo->prP2PInfo)) { -+ ASSERT(FALSE); -+ return FALSE; -+ } -+ -+ if (prGlueInfo->prP2PInfo->u4CipherPairwise == IW_AUTH_CIPHER_CCMP) -+ return TRUE; -+ -+ if (prGlueInfo->prP2PInfo->u4CipherPairwise == IW_AUTH_CIPHER_TKIP) -+ return FALSE; -+ -+ return FALSE; -+} -+ -+BOOLEAN kalP2PGetTkipCipher(IN P_GLUE_INFO_T prGlueInfo) -+{ -+ if ((!prGlueInfo) || (!prGlueInfo->prP2PInfo)) { -+ ASSERT(FALSE); -+ return FALSE; -+ } -+ -+ if (prGlueInfo->prP2PInfo->u4CipherPairwise == IW_AUTH_CIPHER_CCMP) -+ return FALSE; -+ -+ if (prGlueInfo->prP2PInfo->u4CipherPairwise == IW_AUTH_CIPHER_TKIP) -+ return TRUE; -+ -+ return FALSE; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief to set the status of WSC -+* -+* \param[in] -+* prGlueInfo -+* -+* \return -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID kalP2PSetWscMode(IN P_GLUE_INFO_T prGlueInfo, IN UINT_8 ucWscMode) -+{ -+ if ((!prGlueInfo) || (!prGlueInfo->prP2PInfo)) { -+ ASSERT(FALSE); -+ return; -+ } -+ -+ prGlueInfo->prP2PInfo->ucWSCRunning = ucWscMode; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief to get the status of WSC -+* -+* \param[in] -+* prGlueInfo -+* -+* \return -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT_8 kalP2PGetWscMode(IN P_GLUE_INFO_T prGlueInfo) -+{ -+ if ((!prGlueInfo) || (!prGlueInfo->prP2PInfo)) { -+ ASSERT(FALSE); -+ return 0; -+ } -+ -+ return prGlueInfo->prP2PInfo->ucWSCRunning; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief to get the wsc ie length -+* -+* \param[in] -+* prGlueInfo -+* ucType : 0 for beacon, 1 for probe req, 2 for probe resp -+* -+* \return -+* The WSC IE length -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT_16 kalP2PCalWSC_IELen(IN P_GLUE_INFO_T prGlueInfo, IN UINT_8 ucType) -+{ -+ ASSERT(prGlueInfo); -+ -+ ASSERT(ucType < 3); -+ -+ return prGlueInfo->prP2PInfo->u2WSCIELen[ucType]; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief to copy the wsc ie setting from p2p supplicant -+* -+* \param[in] -+* prGlueInfo -+* -+* \return -+* The WPS IE length -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID kalP2PGenWSC_IE(IN P_GLUE_INFO_T prGlueInfo, IN UINT_8 ucType, IN PUINT_8 pucBuffer) -+{ -+ P_GL_P2P_INFO_T prGlP2pInfo = (P_GL_P2P_INFO_T) NULL; -+ -+ do { -+ if ((prGlueInfo == NULL) || (ucType >= 3) || (pucBuffer == NULL)) -+ break; -+ -+ prGlP2pInfo = prGlueInfo->prP2PInfo; -+ -+ kalMemCopy(pucBuffer, prGlP2pInfo->aucWSCIE[ucType], prGlP2pInfo->u2WSCIELen[ucType]); -+ -+ } while (FALSE); -+ -+} -+ -+VOID kalP2PUpdateWSC_IE(IN P_GLUE_INFO_T prGlueInfo, IN UINT_8 ucType, IN PUINT_8 pucBuffer, IN UINT_16 u2BufferLength) -+{ -+ P_GL_P2P_INFO_T prGlP2pInfo = (P_GL_P2P_INFO_T) NULL; -+ -+ do { -+ if ((prGlueInfo == NULL) || (ucType >= 3) || ((u2BufferLength > 0) && (pucBuffer == NULL))) -+ break; -+ -+ if (u2BufferLength > 400) { -+ DBGLOG(P2P, ERROR, -+ "Buffer length is not enough, GLUE only 400 bytes but %d received\n", u2BufferLength); -+ ASSERT(FALSE); -+ break; -+ } -+ -+ prGlP2pInfo = prGlueInfo->prP2PInfo; -+ -+ kalMemCopy(prGlP2pInfo->aucWSCIE[ucType], pucBuffer, u2BufferLength); -+ -+ prGlP2pInfo->u2WSCIELen[ucType] = u2BufferLength; -+ -+ } while (FALSE); -+ -+} /* kalP2PUpdateWSC_IE */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief indicate an event to supplicant for device connection request -+* -+* \param[in] prGlueInfo Pointer of GLUE_INFO_T -+* -+* \retval none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID kalP2PIndicateConnReq(IN P_GLUE_INFO_T prGlueInfo, IN PUINT_8 pucDevName, IN INT_32 u4NameLength, -+ IN PARAM_MAC_ADDRESS rPeerAddr, IN UINT_8 ucDevType, /* 0: P2P Device / 1: GC / 2: GO */ -+ IN INT_32 i4ConfigMethod, IN INT_32 i4ActiveConfigMethod) -+{ -+ union iwreq_data evt; -+ UINT_8 aucBuffer[IW_CUSTOM_MAX]; -+ -+ ASSERT(prGlueInfo); -+ -+ /* buffer peer information for later IOC_P2P_GET_REQ_DEVICE_INFO access */ -+ prGlueInfo->prP2PInfo->u4ConnReqNameLength = u4NameLength > 32 ? 32 : u4NameLength; -+ kalMemCopy(prGlueInfo->prP2PInfo->aucConnReqDevName, pucDevName, prGlueInfo->prP2PInfo->u4ConnReqNameLength); -+ COPY_MAC_ADDR(prGlueInfo->prP2PInfo->rConnReqPeerAddr, rPeerAddr); -+ prGlueInfo->prP2PInfo->ucConnReqDevType = ucDevType; -+ prGlueInfo->prP2PInfo->i4ConnReqConfigMethod = i4ConfigMethod; -+ prGlueInfo->prP2PInfo->i4ConnReqActiveConfigMethod = i4ActiveConfigMethod; -+ -+ /* prepare event structure */ -+ memset(&evt, 0, sizeof(evt)); -+ -+ snprintf(aucBuffer, IW_CUSTOM_MAX - 1, "P2P_DVC_REQ"); -+ evt.data.length = strlen(aucBuffer); -+ -+ /* indicate in IWEVCUSTOM event */ -+ wireless_send_event(prGlueInfo->prP2PInfo->prDevHandler, IWEVCUSTOM, &evt, aucBuffer); -+ -+} /* end of kalP2PIndicateConnReq() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Indicate an event to supplicant for device connection request from other device. -+* -+* \param[in] prGlueInfo Pointer of GLUE_INFO_T -+* \param[in] pucGroupBssid Only valid when invitation Type equals to 0. -+* -+* \retval none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+kalP2PInvitationIndication(IN P_GLUE_INFO_T prGlueInfo, -+ IN P_P2P_DEVICE_DESC_T prP2pDevDesc, -+ IN PUINT_8 pucSsid, -+ IN UINT_8 ucSsidLen, -+ IN UINT_8 ucOperatingChnl, IN UINT_8 ucInvitationType, IN PUINT_8 pucGroupBssid) -+{ -+#if 1 -+ union iwreq_data evt; -+ UINT_8 aucBuffer[IW_CUSTOM_MAX]; -+ -+ ASSERT(prGlueInfo); -+ -+ /* buffer peer information for later IOC_P2P_GET_STRUCT access */ -+ prGlueInfo->prP2PInfo->u4ConnReqNameLength = -+ (UINT_32) ((prP2pDevDesc->u2NameLength > 32) ? 32 : prP2pDevDesc->u2NameLength); -+ kalMemCopy(prGlueInfo->prP2PInfo->aucConnReqDevName, prP2pDevDesc->aucName, -+ prGlueInfo->prP2PInfo->u4ConnReqNameLength); -+ COPY_MAC_ADDR(prGlueInfo->prP2PInfo->rConnReqPeerAddr, prP2pDevDesc->aucDeviceAddr); -+ COPY_MAC_ADDR(prGlueInfo->prP2PInfo->rConnReqGroupAddr, pucGroupBssid); -+ prGlueInfo->prP2PInfo->i4ConnReqConfigMethod = (INT_32) (prP2pDevDesc->u2ConfigMethod); -+ prGlueInfo->prP2PInfo->ucOperatingChnl = ucOperatingChnl; -+ prGlueInfo->prP2PInfo->ucInvitationType = ucInvitationType; -+ -+ /* prepare event structure */ -+ memset(&evt, 0, sizeof(evt)); -+ -+ snprintf(aucBuffer, IW_CUSTOM_MAX - 1, "P2P_INV_INDICATE"); -+ evt.data.length = strlen(aucBuffer); -+ -+ /* indicate in IWEVCUSTOM event */ -+ wireless_send_event(prGlueInfo->prP2PInfo->prDevHandler, IWEVCUSTOM, &evt, aucBuffer); -+ return; -+ -+#else -+ P_MSG_P2P_CONNECTION_REQUEST_T prP2pConnReq = (P_MSG_P2P_CONNECTION_REQUEST_T) NULL; -+ P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo = (P_P2P_SPECIFIC_BSS_INFO_T) NULL; -+ P_P2P_CONNECTION_SETTINGS_T prP2pConnSettings = (P_P2P_CONNECTION_SETTINGS_T) NULL; -+ -+ do { -+ ASSERT_BREAK((prGlueInfo != NULL) && (prP2pDevDesc != NULL)); -+ -+ /* Not a real solution */ -+ -+ prP2pSpecificBssInfo = prGlueInfo->prAdapter->rWifiVar.prP2pSpecificBssInfo; -+ prP2pConnSettings = prGlueInfo->prAdapter->rWifiVar.prP2PConnSettings; -+ -+ prP2pConnReq = (P_MSG_P2P_CONNECTION_REQUEST_T) cnmMemAlloc(prGlueInfo->prAdapter, -+ RAM_TYPE_MSG, -+ sizeof(MSG_P2P_CONNECTION_REQUEST_T)); -+ -+ if (prP2pConnReq == NULL) -+ break; -+ -+ kalMemZero(prP2pConnReq, sizeof(MSG_P2P_CONNECTION_REQUEST_T)); -+ -+ prP2pConnReq->rMsgHdr.eMsgId = MID_MNY_P2P_CONNECTION_REQ; -+ -+ prP2pConnReq->eFormationPolicy = ENUM_P2P_FORMATION_POLICY_AUTO; -+ -+ COPY_MAC_ADDR(prP2pConnReq->aucDeviceID, prP2pDevDesc->aucDeviceAddr); -+ -+ prP2pConnReq->u2ConfigMethod = prP2pDevDesc->u2ConfigMethod; -+ -+ if (ucInvitationType == P2P_INVITATION_TYPE_INVITATION) { -+ prP2pConnReq->fgIsPersistentGroup = FALSE; -+ prP2pConnReq->fgIsTobeGO = FALSE; -+ -+ } -+ -+ else if (ucInvitationType == P2P_INVITATION_TYPE_REINVOKE) { -+ DBGLOG(P2P, TRACE, "Re-invoke Persistent Group\n"); -+ prP2pConnReq->fgIsPersistentGroup = TRUE; -+ prP2pConnReq->fgIsTobeGO = (prGlueInfo->prP2PInfo->ucRole == 2) ? TRUE : FALSE; -+ -+ } -+ -+ p2pFsmRunEventDeviceDiscoveryAbort(prGlueInfo->prAdapter, NULL); -+ -+ if (ucOperatingChnl != 0) -+ prP2pSpecificBssInfo->ucPreferredChannel = ucOperatingChnl; -+ -+ if ((ucSsidLen < 32) && (pucSsid != NULL)) -+ COPY_SSID(prP2pConnSettings->aucSSID, prP2pConnSettings->ucSSIDLen, pucSsid, ucSsidLen); -+ -+ mboxSendMsg(prGlueInfo->prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prP2pConnReq, MSG_SEND_METHOD_BUF); -+ -+ } while (FALSE); -+ -+ /* frog add. */ -+ /* TODO: Invitation Indication */ -+ -+ return; -+#endif -+ -+} /* kalP2PInvitationIndication */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Indicate an status to supplicant for device invitation status. -+* -+* \param[in] prGlueInfo Pointer of GLUE_INFO_T -+* -+* \retval none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID kalP2PInvitationStatus(IN P_GLUE_INFO_T prGlueInfo, IN UINT_32 u4InvStatus) -+{ -+ union iwreq_data evt; -+ UINT_8 aucBuffer[IW_CUSTOM_MAX]; -+ -+ ASSERT(prGlueInfo); -+ -+ /* buffer peer information for later IOC_P2P_GET_STRUCT access */ -+ prGlueInfo->prP2PInfo->u4InvStatus = u4InvStatus; -+ -+ /* prepare event structure */ -+ memset(&evt, 0, sizeof(evt)); -+ -+ snprintf(aucBuffer, IW_CUSTOM_MAX - 1, "P2P_INV_STATUS"); -+ evt.data.length = strlen(aucBuffer); -+ -+ /* indicate in IWEVCUSTOM event */ -+ wireless_send_event(prGlueInfo->prP2PInfo->prDevHandler, IWEVCUSTOM, &evt, aucBuffer); -+ -+} /* kalP2PInvitationStatus */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Indicate an event to supplicant for Service Discovery request from other device. -+* -+* \param[in] prGlueInfo Pointer of GLUE_INFO_T -+* -+* \retval none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID kalP2PIndicateSDRequest(IN P_GLUE_INFO_T prGlueInfo, IN PARAM_MAC_ADDRESS rPeerAddr, IN UINT_8 ucSeqNum) -+{ -+ union iwreq_data evt; -+ UINT_8 aucBuffer[IW_CUSTOM_MAX]; -+ -+ ASSERT(prGlueInfo); -+ -+ memset(&evt, 0, sizeof(evt)); -+ -+ snprintf(aucBuffer, IW_CUSTOM_MAX - 1, "P2P_SD_REQ %d", ucSeqNum); -+ evt.data.length = strlen(aucBuffer); -+ -+ /* indicate IWEVP2PSDREQ event */ -+ wireless_send_event(prGlueInfo->prP2PInfo->prDevHandler, IWEVCUSTOM, &evt, aucBuffer); -+ -+} /* end of kalP2PIndicateSDRequest() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Indicate an event to supplicant for Service Discovery response -+* from other device. -+* -+* \param[in] prGlueInfo Pointer of GLUE_INFO_T -+* -+* \retval none -+*/ -+/*----------------------------------------------------------------------------*/ -+void kalP2PIndicateSDResponse(IN P_GLUE_INFO_T prGlueInfo, IN PARAM_MAC_ADDRESS rPeerAddr, IN UINT_8 ucSeqNum) -+{ -+ union iwreq_data evt; -+ UINT_8 aucBuffer[IW_CUSTOM_MAX]; -+ -+ ASSERT(prGlueInfo); -+ -+ memset(&evt, 0, sizeof(evt)); -+ -+ snprintf(aucBuffer, IW_CUSTOM_MAX - 1, "P2P_SD_RESP %d", ucSeqNum); -+ evt.data.length = strlen(aucBuffer); -+ -+ /* indicate IWEVP2PSDREQ event */ -+ wireless_send_event(prGlueInfo->prP2PInfo->prDevHandler, IWEVCUSTOM, &evt, aucBuffer); -+ -+} /* end of kalP2PIndicateSDResponse() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Indicate an event to supplicant for Service Discovery TX Done -+* from other device. -+* -+* \param[in] prGlueInfo Pointer of GLUE_INFO_T -+* \param[in] ucSeqNum Sequence number of the frame -+* \param[in] ucStatus Status code for TX -+* -+* \retval none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID kalP2PIndicateTXDone(IN P_GLUE_INFO_T prGlueInfo, IN UINT_8 ucSeqNum, IN UINT_8 ucStatus) -+{ -+ union iwreq_data evt; -+ UINT_8 aucBuffer[IW_CUSTOM_MAX]; -+ -+ ASSERT(prGlueInfo); -+ -+ memset(&evt, 0, sizeof(evt)); -+ -+ snprintf(aucBuffer, IW_CUSTOM_MAX - 1, "P2P_SD_XMITTED: %d %d", ucSeqNum, ucStatus); -+ evt.data.length = strlen(aucBuffer); -+ -+ /* indicate IWEVP2PSDREQ event */ -+ wireless_send_event(prGlueInfo->prP2PInfo->prDevHandler, IWEVCUSTOM, &evt, aucBuffer); -+ -+} /* end of kalP2PIndicateSDResponse() */ -+ -+struct net_device *kalP2PGetDevHdlr(P_GLUE_INFO_T prGlueInfo) -+{ -+ if ((!prGlueInfo) || (!prGlueInfo->prP2PInfo)) { -+ ASSERT(FALSE); -+ return NULL; -+ } -+ -+ return prGlueInfo->prP2PInfo->prDevHandler; -+} -+ -+#if CFG_SUPPORT_ANTI_PIRACY -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] prAdapter Pointer of ADAPTER_T -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID kalP2PIndicateSecCheckRsp(IN P_GLUE_INFO_T prGlueInfo, IN PUINT_8 pucRsp, IN UINT_16 u2RspLen) -+{ -+ union iwreq_data evt; -+ UINT_8 aucBuffer[IW_CUSTOM_MAX]; -+ -+ ASSERT(prGlueInfo); -+ -+ memset(&evt, 0, sizeof(evt)); -+ snprintf(aucBuffer, IW_CUSTOM_MAX - 1, "P2P_SEC_CHECK_RSP="); -+ -+ kalMemCopy(prGlueInfo->prP2PInfo->aucSecCheckRsp, pucRsp, u2RspLen); -+ evt.data.length = strlen(aucBuffer); -+ -+#if DBG -+ DBGLOG_MEM8(SEC, LOUD, prGlueInfo->prP2PInfo->aucSecCheckRsp, u2RspLen); -+#endif -+ /* indicate in IWECUSTOM event */ -+ wireless_send_event(prGlueInfo->prP2PInfo->prDevHandler, IWEVCUSTOM, &evt, aucBuffer); -+} /* p2pFsmRunEventRxDisassociation */ -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] prAdapter Pointer of ADAPTER_T -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+kalGetChnlList(IN P_GLUE_INFO_T prGlueInfo, -+ IN ENUM_BAND_T eSpecificBand, -+ IN UINT_8 ucMaxChannelNum, IN PUINT_8 pucNumOfChannel, IN P_RF_CHANNEL_INFO_T paucChannelList) -+{ -+ rlmDomainGetChnlList(prGlueInfo->prAdapter, eSpecificBand, FALSE, ucMaxChannelNum, -+ pucNumOfChannel, paucChannelList); -+} /* kalGetChnlList */ -+ -+/* ////////////////////////////////////ICS SUPPORT////////////////////////////////////// */ -+ -+VOID -+kalP2PIndicateChannelReady(IN P_GLUE_INFO_T prGlueInfo, -+ IN UINT_64 u8SeqNum, -+ IN UINT_32 u4ChannelNum, -+ IN ENUM_BAND_T eBand, IN ENUM_CHNL_EXT_T eSco, IN UINT_32 u4Duration) -+{ -+ struct ieee80211_channel *prIEEE80211ChnlStruct = (struct ieee80211_channel *)NULL; -+ RF_CHANNEL_INFO_T rChannelInfo; -+ enum nl80211_channel_type eChnlType = NL80211_CHAN_NO_HT; -+ -+ do { -+ if (prGlueInfo == NULL) -+ break; -+ -+ kalMemZero(&rChannelInfo, sizeof(RF_CHANNEL_INFO_T)); -+ -+ rChannelInfo.ucChannelNum = u4ChannelNum; -+ rChannelInfo.eBand = eBand; -+ -+ prIEEE80211ChnlStruct = kalP2pFuncGetChannelEntry(prGlueInfo->prP2PInfo, &rChannelInfo); -+ -+ kalP2pFuncGetChannelType(eSco, &eChnlType); -+ -+ cfg80211_ready_on_channel(prGlueInfo->prP2PInfo->prWdev, /* struct wireless_dev, */ -+ u8SeqNum, /* u64 cookie, */ -+ prIEEE80211ChnlStruct, /* struct ieee80211_channel * chan, */ -+ u4Duration, /* unsigned int duration, */ -+ GFP_KERNEL); /* gfp_t gfp */ /* allocation flags */ -+ } while (FALSE); -+ -+} /* kalP2PIndicateChannelReady */ -+ -+VOID kalP2PIndicateChannelExpired(IN P_GLUE_INFO_T prGlueInfo, IN P_P2P_CHNL_REQ_INFO_T prChnlReqInfo) -+{ -+ -+ P_GL_P2P_INFO_T prGlueP2pInfo = (P_GL_P2P_INFO_T) NULL; -+ struct ieee80211_channel *prIEEE80211ChnlStruct = (struct ieee80211_channel *)NULL; -+ enum nl80211_channel_type eChnlType = NL80211_CHAN_NO_HT; -+ RF_CHANNEL_INFO_T rRfChannelInfo; -+ -+ do { -+ if ((prGlueInfo == NULL) || (prChnlReqInfo == NULL)) { -+ -+ ASSERT(FALSE); -+ break; -+ } -+ -+ prGlueP2pInfo = prGlueInfo->prP2PInfo; -+ -+ if (prGlueP2pInfo == NULL) { -+ ASSERT(FALSE); -+ break; -+ } -+ -+ DBGLOG(P2P, TRACE, "kalP2PIndicateChannelExpired\n"); -+ -+ rRfChannelInfo.eBand = prChnlReqInfo->eBand; -+ rRfChannelInfo.ucChannelNum = prChnlReqInfo->ucReqChnlNum; -+ -+ prIEEE80211ChnlStruct = kalP2pFuncGetChannelEntry(prGlueP2pInfo, &rRfChannelInfo); -+ -+ kalP2pFuncGetChannelType(prChnlReqInfo->eChnlSco, &eChnlType); -+ -+ cfg80211_remain_on_channel_expired(prGlueP2pInfo->prWdev, /* struct wireless_dev, */ -+ prChnlReqInfo->u8Cookie, prIEEE80211ChnlStruct, GFP_KERNEL); -+ } while (FALSE); -+ -+} /* kalP2PIndicateChannelExpired */ -+ -+VOID kalP2PIndicateScanDone(IN P_GLUE_INFO_T prGlueInfo, IN BOOLEAN fgIsAbort) -+{ -+ P_GL_P2P_INFO_T prGlueP2pInfo = (P_GL_P2P_INFO_T) NULL; -+ struct cfg80211_scan_request *prScanRequest = NULL; -+ struct cfg80211_scan_info info = { -+ .aborted = true, -+ }; -+ -+ GLUE_SPIN_LOCK_DECLARATION(); -+ -+ do { -+ if (prGlueInfo == NULL) { -+ -+ ASSERT(FALSE); -+ break; -+ } -+ -+ prGlueP2pInfo = prGlueInfo->prP2PInfo; -+ -+ if (prGlueP2pInfo == NULL) { -+ ASSERT(FALSE); -+ break; -+ } -+ -+ DBGLOG(INIT, TRACE, "[p2p] scan complete %p\n", prGlueP2pInfo->prScanRequest); -+ -+ GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV); -+ if (prGlueP2pInfo->prScanRequest != NULL) { -+ prScanRequest = prGlueP2pInfo->prScanRequest; -+ prGlueP2pInfo->prScanRequest = NULL; -+ } -+ GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV); -+ -+ /* 2. then CFG80211 Indication */ -+ -+ if (prScanRequest != NULL) { -+ -+ /* report all queued beacon/probe response frames to upper layer */ -+ scanReportBss2Cfg80211(prGlueInfo->prAdapter, BSS_TYPE_P2P_DEVICE, NULL); -+ -+ info.aborted = fgIsAbort; -+ DBGLOG(INIT, TRACE, "DBG:p2p_cfg_scan_done\n"); -+ cfg80211_scan_done(prScanRequest, &info); -+ } -+ -+ } while (FALSE); -+ -+} /* kalP2PIndicateScanDone */ -+ -+VOID -+kalP2PIndicateBssInfo(IN P_GLUE_INFO_T prGlueInfo, -+ IN PUINT_8 pucFrameBuf, -+ IN UINT_32 u4BufLen, IN P_RF_CHANNEL_INFO_T prChannelInfo, IN INT_32 i4SignalStrength) -+{ -+ P_GL_P2P_INFO_T prGlueP2pInfo = (P_GL_P2P_INFO_T) NULL; -+ struct ieee80211_channel *prChannelEntry = (struct ieee80211_channel *)NULL; -+ struct ieee80211_mgmt *prBcnProbeRspFrame = (struct ieee80211_mgmt *)pucFrameBuf; -+ struct cfg80211_bss *prCfg80211Bss = (struct cfg80211_bss *)NULL; -+ -+ do { -+ if ((prGlueInfo == NULL) || (pucFrameBuf == NULL) || (prChannelInfo == NULL)) { -+ ASSERT(FALSE); -+ break; -+ } -+ -+ prGlueP2pInfo = prGlueInfo->prP2PInfo; -+ -+ if (prGlueP2pInfo == NULL) { -+ ASSERT(FALSE); -+ break; -+ } -+ -+ prChannelEntry = kalP2pFuncGetChannelEntry(prGlueP2pInfo, prChannelInfo); -+ -+ if (prChannelEntry == NULL) { -+ DBGLOG(P2P, WARN, "Unknown channel info\n"); -+ break; -+ } -+ /* rChannelInfo.center_freq = nicChannelNum2Freq((UINT_32)prChannelInfo->ucChannelNum) / 1000; */ -+ -+ prCfg80211Bss = cfg80211_inform_bss_frame(prGlueP2pInfo->prWdev->wiphy, /* struct wiphy * wiphy, */ -+ prChannelEntry, -+ prBcnProbeRspFrame, u4BufLen, i4SignalStrength, GFP_KERNEL); -+ -+ /* Return this structure. */ -+ if (!prCfg80211Bss) { -+ DBGLOG(P2P, WARN, "inform bss to cfg80211 failed, bss channel %d, rcpi %d\n", -+ prChannelInfo->ucChannelNum, i4SignalStrength); -+ } else { -+ cfg80211_put_bss(prGlueP2pInfo->prWdev->wiphy, prCfg80211Bss); -+ DBGLOG(P2P, TRACE, "inform bss to cfg80211, bss channel %d, rcpi %d\n", -+ prChannelInfo->ucChannelNum, i4SignalStrength); -+ } -+ } while (FALSE); -+ -+} /* kalP2PIndicateBssInfo */ -+ -+VOID -+kalP2PIndicateMgmtTxStatus(IN P_GLUE_INFO_T prGlueInfo, -+ IN UINT_64 u8Cookie, IN BOOLEAN fgIsAck, IN PUINT_8 pucFrameBuf, IN UINT_32 u4FrameLen) -+{ -+ P_GL_P2P_INFO_T prGlueP2pInfo = (P_GL_P2P_INFO_T) NULL; -+ -+ do { -+ if ((prGlueInfo == NULL) || (pucFrameBuf == NULL) || (u4FrameLen == 0)) { -+ DBGLOG(P2P, TRACE, "Unexpected pointer PARAM. %p, %p, %u.", -+ prGlueInfo, pucFrameBuf, u4FrameLen); -+ ASSERT(FALSE); -+ break; -+ } -+ -+ prGlueP2pInfo = prGlueInfo->prP2PInfo; -+ -+ cfg80211_mgmt_tx_status(prGlueP2pInfo->prWdev, /* struct net_device * dev, */ -+ u8Cookie, pucFrameBuf, u4FrameLen, fgIsAck, GFP_KERNEL); -+ -+ } while (FALSE); -+ -+} /* kalP2PIndicateMgmtTxStatus */ -+ -+VOID kalP2PIndicateRxMgmtFrame(IN P_GLUE_INFO_T prGlueInfo, IN P_SW_RFB_T prSwRfb) -+{ -+#define DBG_P2P_MGMT_FRAME_INDICATION 0 -+ P_GL_P2P_INFO_T prGlueP2pInfo = (P_GL_P2P_INFO_T) NULL; -+ INT_32 i4Freq = 0; -+ UINT_8 ucChnlNum = 0; -+#if DBG_P2P_MGMT_FRAME_INDICATION -+ P_WLAN_MAC_HEADER_T prWlanHeader = (P_WLAN_MAC_HEADER_T) NULL; -+#endif -+ -+ do { -+ if ((prGlueInfo == NULL) || (prSwRfb == NULL)) { -+ ASSERT(FALSE); -+ break; -+ } -+ -+ prGlueP2pInfo = prGlueInfo->prP2PInfo; -+ -+ ucChnlNum = prSwRfb->prHifRxHdr->ucHwChannelNum; -+ -+#if DBG_P2P_MGMT_FRAME_INDICATION -+ -+ prWlanHeader = (P_WLAN_MAC_HEADER_T) prSwRfb->pvHeader; -+ -+ switch (prWlanHeader->u2FrameCtrl) { -+ case MAC_FRAME_PROBE_REQ: -+ DBGLOG(P2P, TRACE, "RX Probe Req at channel %d ", ucChnlNum); -+ break; -+ case MAC_FRAME_PROBE_RSP: -+ DBGLOG(P2P, TRACE, "RX Probe Rsp at channel %d ", ucChnlNum); -+ break; -+ case MAC_FRAME_ACTION: -+ DBGLOG(P2P, TRACE, "RX Action frame at channel %d ", ucChnlNum); -+ break; -+ default: -+ DBGLOG(P2P, TRACE, "RX Packet:%d at channel %d ", prWlanHeader->u2FrameCtrl, ucChnlNum); -+ break; -+ } -+ -+ DBGLOG(P2P, TRACE, "from: %pM\n", prWlanHeader->aucAddr2); -+#endif -+ i4Freq = nicChannelNum2Freq(ucChnlNum) / 1000; -+ -+ cfg80211_rx_mgmt(prGlueP2pInfo->prWdev, /* struct net_device * dev, */ -+ i4Freq, -+ RCPI_TO_dBm(prSwRfb->prHifRxHdr->ucRcpi), -+ prSwRfb->pvHeader, prSwRfb->u2PacketLen, GFP_ATOMIC); -+ } while (FALSE); -+ -+} /* kalP2PIndicateRxMgmtFrame */ -+ -+VOID -+kalP2PGCIndicateConnectionStatus(IN P_GLUE_INFO_T prGlueInfo, -+ IN P_P2P_CONNECTION_REQ_INFO_T prP2pConnInfo, -+ IN PUINT_8 pucRxIEBuf, IN UINT_16 u2RxIELen, IN UINT_16 u2StatusReason, -+ IN WLAN_STATUS eStatus) -+{ -+ P_GL_P2P_INFO_T prGlueP2pInfo = (P_GL_P2P_INFO_T) NULL; -+ -+ do { -+ if (prGlueInfo == NULL) { -+ ASSERT(FALSE); -+ break; -+ } -+ -+ prGlueP2pInfo = prGlueInfo->prP2PInfo; -+ -+ if (prP2pConnInfo) { -+ cfg80211_connect_result(prGlueP2pInfo->prDevHandler, /* struct net_device * dev, */ -+ prP2pConnInfo->aucBssid, prP2pConnInfo->aucIEBuf, -+ prP2pConnInfo->u4BufLength, -+ pucRxIEBuf, u2RxIELen, u2StatusReason, GFP_KERNEL); -+ /* gfp_t gfp */ /* allocation flags */ -+ prP2pConnInfo->fgIsConnRequest = FALSE; -+ } else { -+ /* Disconnect, what if u2StatusReason == 0? */ -+ cfg80211_disconnected(prGlueP2pInfo->prDevHandler, /* struct net_device * dev, */ -+ u2StatusReason, pucRxIEBuf, u2RxIELen, -+ eStatus == WLAN_STATUS_MEDIA_DISCONNECT_LOCALLY ? true : false, -+ GFP_KERNEL); -+ } -+ -+ } while (FALSE); -+ -+} /* kalP2PGCIndicateConnectionStatus */ -+ -+VOID kalP2PGOStationUpdate(IN P_GLUE_INFO_T prGlueInfo, IN P_STA_RECORD_T prCliStaRec, IN BOOLEAN fgIsNew) -+{ -+ P_GL_P2P_INFO_T prP2pGlueInfo = (P_GL_P2P_INFO_T) NULL; -+ struct station_info rStationInfo; -+ -+ memset(&rStationInfo, 0, sizeof(struct station_info)); -+ -+ do { -+ if ((prGlueInfo == NULL) || (prCliStaRec == NULL)) -+ break; -+ -+ prP2pGlueInfo = prGlueInfo->prP2PInfo; -+ -+ if (fgIsNew) { -+ //rStationInfo.filled = STATION_INFO_ASSOC_REQ_IES; -+ rStationInfo.generation = ++prP2pGlueInfo->i4Generation; -+ -+ rStationInfo.assoc_req_ies = prCliStaRec->pucAssocReqIe; -+ rStationInfo.assoc_req_ies_len = prCliStaRec->u2AssocReqIeLen; -+/* rStationInfo.filled |= STATION_INFO_ASSOC_REQ_IES; */ -+ -+ cfg80211_new_sta(prGlueInfo->prP2PInfo->prDevHandler, /* struct net_device * dev, */ -+ prCliStaRec->aucMacAddr, &rStationInfo, GFP_KERNEL); -+ } else { -+ ++prP2pGlueInfo->i4Generation; -+ -+ cfg80211_del_sta(prGlueInfo->prP2PInfo->prDevHandler, /* struct net_device * dev, */ -+ prCliStaRec->aucMacAddr, GFP_KERNEL); -+ } -+ -+ } while (FALSE); -+ -+ return; -+ -+} /* kalP2PGOStationUpdate */ -+ -+BOOLEAN kalP2pFuncGetChannelType(IN ENUM_CHNL_EXT_T rChnlSco, OUT enum nl80211_channel_type *channel_type) -+{ -+ BOOLEAN fgIsValid = FALSE; -+ -+ do { -+ if (channel_type) { -+ -+ switch (rChnlSco) { -+ case CHNL_EXT_SCN: -+ *channel_type = NL80211_CHAN_NO_HT; -+ break; -+ case CHNL_EXT_SCA: -+ *channel_type = NL80211_CHAN_HT40MINUS; -+ break; -+ case CHNL_EXT_SCB: -+ *channel_type = NL80211_CHAN_HT40PLUS; -+ break; -+ default: -+ ASSERT(FALSE); -+ *channel_type = NL80211_CHAN_NO_HT; -+ break; -+ } -+ -+ } -+ -+ fgIsValid = TRUE; -+ } while (FALSE); -+ -+ return fgIsValid; -+} /* kalP2pFuncGetChannelType */ -+ -+struct ieee80211_channel *kalP2pFuncGetChannelEntry(IN P_GL_P2P_INFO_T prP2pInfo, IN P_RF_CHANNEL_INFO_T prChannelInfo) -+{ -+ struct ieee80211_channel *prTargetChannelEntry = (struct ieee80211_channel *)NULL; -+ UINT_32 u4TblSize = 0, u4Idx = 0; -+ struct ieee80211_supported_band **bands; -+ -+ do { -+ if ((prP2pInfo == NULL) || (prChannelInfo == NULL)) -+ break; -+ bands = &prP2pInfo->prWdev->wiphy->bands[0]; -+ switch (prChannelInfo->eBand) { -+ case BAND_2G4: -+ prTargetChannelEntry = bands[NL80211_BAND_2GHZ]->channels; -+ u4TblSize = bands[NL80211_BAND_2GHZ]->n_channels; -+ break; -+ case BAND_5G: -+ prTargetChannelEntry = bands[NL80211_BAND_5GHZ]->channels; -+ u4TblSize = bands[NL80211_BAND_5GHZ]->n_channels; -+ break; -+ default: -+ break; -+ } -+ -+ if (prTargetChannelEntry == NULL) -+ break; -+ -+ for (u4Idx = 0; u4Idx < u4TblSize; u4Idx++, prTargetChannelEntry++) { -+ if (prTargetChannelEntry->hw_value == prChannelInfo->ucChannelNum) -+ break; -+ } -+ -+ if (u4Idx == u4TblSize) { -+ prTargetChannelEntry = NULL; -+ break; -+ } -+ -+ } while (FALSE); -+ -+ return prTargetChannelEntry; -+} /* kalP2pFuncGetChannelEntry */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief to set the block list of Hotspot -+* -+* \param[in] -+* prGlueInfo -+* -+* \return -+*/ -+/*----------------------------------------------------------------------------*/ -+INT_32 kalP2PSetBlackList(IN P_GLUE_INFO_T prGlueInfo, IN PARAM_MAC_ADDRESS rbssid, IN BOOLEAN fgIsblock) -+{ -+ UINT_8 aucNullAddr[] = NULL_MAC_ADDR; -+ UINT_32 i; -+ -+ ASSERT(prGlueInfo); -+ ASSERT(prGlueInfo->prP2PInfo); -+ -+ if (EQUAL_MAC_ADDR(rbssid, aucNullAddr)) -+ return -EINVAL; -+ -+ if (fgIsblock) { -+ for (i = 0; i < 8; i++) { -+ if (EQUAL_MAC_ADDR(&(prGlueInfo->prP2PInfo->aucblackMACList[i]), rbssid)) { -+ break; -+ } else if (EQUAL_MAC_ADDR(&(prGlueInfo->prP2PInfo->aucblackMACList[i]), aucNullAddr)) { -+ COPY_MAC_ADDR(&(prGlueInfo->prP2PInfo->aucblackMACList[i]), rbssid); -+ break; -+ } -+ } -+ if (i >= 8) { -+ DBGLOG(P2P, ERROR, "AP black list is full, cannot block more STA!!\n"); -+ return -ENOBUFS; -+ } -+ } else { -+ for (i = 0; i < 8; i++) { -+ if (EQUAL_MAC_ADDR(&(prGlueInfo->prP2PInfo->aucblackMACList[i]), rbssid)) { -+ COPY_MAC_ADDR(&(prGlueInfo->prP2PInfo->aucblackMACList[i]), aucNullAddr); -+ break; -+ } -+ } -+ if (i >= 8) -+ DBGLOG(P2P, ERROR, "The STA is not found in black list!!\n"); -+ } -+ -+ return 0; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief to compare the black list of Hotspot -+* -+* \param[in] -+* prGlueInfo -+* -+* \return -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN kalP2PCmpBlackList(IN P_GLUE_INFO_T prGlueInfo, IN PARAM_MAC_ADDRESS rbssid) -+{ -+ UINT_8 aucNullAddr[] = NULL_MAC_ADDR; -+ BOOLEAN fgIsExsit = FALSE; -+ UINT_32 i; -+ -+ ASSERT(prGlueInfo); -+ ASSERT(prGlueInfo->prP2PInfo); -+ -+ for (i = 0; i < 8; i++) { -+ if (UNEQUAL_MAC_ADDR(rbssid, aucNullAddr)) { -+ if (EQUAL_MAC_ADDR(&(prGlueInfo->prP2PInfo->aucblackMACList[i]), rbssid)) { -+ fgIsExsit = TRUE; -+ return fgIsExsit; -+ } -+ } -+ } -+ -+ return fgIsExsit; -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief to return the max clients of Hotspot -+* -+* \param[in] -+* prGlueInfo -+* -+* \return -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID kalP2PSetMaxClients(IN P_GLUE_INFO_T prGlueInfo, IN UINT_32 u4MaxClient) -+{ -+ if ((!prGlueInfo) || (!prGlueInfo->prP2PInfo)) { -+ ASSERT(FALSE); -+ return; -+ } -+ -+ if (u4MaxClient == 0 || prGlueInfo->prP2PInfo->ucMaxClients >= P2P_MAXIMUM_CLIENT_COUNT) -+ prGlueInfo->prP2PInfo->ucMaxClients = P2P_MAXIMUM_CLIENT_COUNT; -+ else -+ prGlueInfo->prP2PInfo->ucMaxClients = u4MaxClient; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief to return the max clients of Hotspot -+* -+* \param[in] -+* prGlueInfo -+* -+* \return -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN kalP2PMaxClients(IN P_GLUE_INFO_T prGlueInfo, IN UINT_32 u4NumClient) -+{ -+ if ((!prGlueInfo) || (!prGlueInfo->prP2PInfo)) { -+ ASSERT(FALSE); -+ return FALSE; -+ } -+ -+ if (prGlueInfo->prP2PInfo->ucMaxClients) { -+ if ((UINT_8) u4NumClient > prGlueInfo->prP2PInfo->ucMaxClients) -+ return TRUE; -+ else -+ return FALSE; -+ } -+ -+ return FALSE; -+} -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_proc.c b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_proc.c -new file mode 100644 -index 000000000000..075045f547b7 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_proc.c -@@ -0,0 +1,1020 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux/gl_proc.c#1 -+*/ -+ -+/*! \file "gl_proc.c" -+ \brief This file defines the interface which can interact with users in /proc fs. -+ -+ Detail description. -+*/ -+ -+/* -+** Log: gl_proc.c -+ * -+ * 11 10 2011 cp.wu -+ * [WCXRP00001098] [MT6620 Wi-Fi][Driver] Replace printk by DBG LOG macros in linux porting layer -+ * 1. eliminaite direct calls to printk in porting layer. -+ * 2. replaced by DBGLOG, which would be XLOG on ALPS platforms. -+ * -+ * 12 10 2010 kevin.huang -+ * [WCXRP00000128] [MT6620 Wi-Fi][Driver] Add proc support to Android Driver for debug and driver status check -+ * Add Linux Proc Support -+** \main\maintrunk.MT5921\19 2008-09-02 21:08:37 GMT mtk01461 -+** Fix the compile error of SPRINTF() -+** \main\maintrunk.MT5921\18 2008-08-10 18:48:28 GMT mtk01461 -+** Update for Driver Review -+** \main\maintrunk.MT5921\17 2008-08-04 16:52:01 GMT mtk01461 -+** Add proc dbg print message of DOMAIN_INDEX level -+** \main\maintrunk.MT5921\16 2008-07-10 00:45:16 GMT mtk01461 -+** Remove the check of MCR offset, we may use the MCR address which is not align to DW boundary or proprietary usage. -+** \main\maintrunk.MT5921\15 2008-06-03 20:49:44 GMT mtk01461 -+** \main\maintrunk.MT5921\14 2008-06-02 22:56:00 GMT mtk01461 -+** Rename some functions for linux proc -+** \main\maintrunk.MT5921\13 2008-06-02 20:23:18 GMT mtk01461 -+** Revise PROC mcr read / write for supporting TELNET -+** \main\maintrunk.MT5921\12 2008-03-28 10:40:25 GMT mtk01461 -+** Remove temporary set desired rate in linux proc -+** \main\maintrunk.MT5921\11 2008-01-07 15:07:29 GMT mtk01461 -+** Add User Update Desired Rate Set for QA in Linux -+** \main\maintrunk.MT5921\10 2007-12-11 00:11:14 GMT mtk01461 -+** Fix SPIN_LOCK protection -+** \main\maintrunk.MT5921\9 2007-12-04 18:07:57 GMT mtk01461 -+** Add additional debug category to proc -+** \main\maintrunk.MT5921\8 2007-11-02 01:03:23 GMT mtk01461 -+** Unify TX Path for Normal and IBSS Power Save + IBSS neighbor learning -+** \main\maintrunk.MT5921\7 2007-10-25 18:08:14 GMT mtk01461 -+** Add VOIP SCAN Support & Refine Roaming -+** Revision 1.3 2007/07/05 07:25:33 MTK01461 -+** Add Linux initial code, modify doc, add 11BB, RF init code -+** -+** Revision 1.2 2007/06/27 02:18:51 MTK01461 -+** Update SCAN_FSM, Initial(Can Load Module), Proc(Can do Reg R/W), TX API -+** -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+#include "precomp.h" -+ -+/* #include "wlan_lib.h" */ -+/* #include "debug.h" */ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+#define PROC_WLAN_THERMO "wlanThermo" -+#define PROC_DRV_STATUS "status" -+#define PROC_RX_STATISTICS "rx_statistics" -+#define PROC_TX_STATISTICS "tx_statistics" -+#define PROC_DBG_LEVEL_NAME "dbgLevel" -+#define PROC_NEED_TX_DONE "TxDoneCfg" -+#define PROC_AUTO_PER_CFG "autoPerCfg" -+#define PROC_ROOT_NAME "wlan" -+#define PROC_CMD_DEBUG_NAME "cmdDebug" -+ -+#define PROC_MCR_ACCESS_MAX_USER_INPUT_LEN 20 -+#define PROC_RX_STATISTICS_MAX_USER_INPUT_LEN 10 -+#define PROC_TX_STATISTICS_MAX_USER_INPUT_LEN 10 -+#define PROC_DBG_LEVEL_MAX_USER_INPUT_LEN (20*10) -+#define PROC_DBG_LEVEL_MAX_DISPLAY_STR_LEN 8 -+ -+#define PROC_UID_SHELL 2000 -+#define PROC_GID_WIFI 1010 -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+/* static UINT_32 u4McrOffset; */ -+#if CFG_SUPPORT_THERMO_THROTTLING -+static P_GLUE_INFO_T g_prGlueInfo_proc; -+#endif -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief The PROC function for reading MCR register to User Space, the offset of -+* the MCR is specified in u4McrOffset. -+* -+* \param[in] page Buffer provided by kernel. -+* \param[in out] start Start Address to read(3 methods). -+* \param[in] off Offset. -+* \param[in] count Allowable number to read. -+* \param[out] eof End of File indication. -+* \param[in] data Pointer to the private data structure. -+* -+* \return number of characters print to the buffer from User Space. -+*/ -+/*----------------------------------------------------------------------------*/ -+#if 0 -+static int procMCRRead(char *page, char **start, off_t off, int count, int *eof, void *data) -+{ -+ P_GLUE_INFO_T prGlueInfo; -+ PARAM_CUSTOM_MCR_RW_STRUCT_T rMcrInfo; -+ UINT_32 u4BufLen; -+ char *p = page; -+ UINT_32 u4Count; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ -+ ASSERT(data); -+ -+ /* Kevin: Apply PROC read method 1. */ -+ if (off != 0) -+ return 0; /* To indicate end of file. */ -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv((struct net_device *)data)); -+ -+ rMcrInfo.u4McrOffset = u4McrOffset; -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidQueryMcrRead, -+ (PVOID)&rMcrInfo, sizeof(rMcrInfo), TRUE, TRUE, TRUE, FALSE, &u4BufLen); -+ -+ /* SPRINTF(p, ("MCR (0x%08lxh): 0x%08lx\n", */ -+ /* rMcrInfo.u4McrOffset, rMcrInfo.u4McrData)); */ -+ -+ u4Count = (UINT_32) (p - page); -+ -+ *eof = 1; -+ -+ return (int)u4Count; -+ -+} /* end of procMCRRead() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief The PROC function for writing MCR register to HW or update u4McrOffset -+* for reading MCR later. -+* -+* \param[in] file pointer to file. -+* \param[in] buffer Buffer from user space. -+* \param[in] count Number of characters to write -+* \param[in] data Pointer to the private data structure. -+* -+* \return number of characters write from User Space. -+*/ -+/*----------------------------------------------------------------------------*/ -+static int procMCRWrite(struct file *file, const char *buffer, unsigned long count, void *data) -+{ -+ P_GLUE_INFO_T prGlueInfo; -+ char acBuf[PROC_MCR_ACCESS_MAX_USER_INPUT_LEN + 1]; /* + 1 for "\0" */ -+ int i4CopySize; -+ PARAM_CUSTOM_MCR_RW_STRUCT_T rMcrInfo; -+ UINT_32 u4BufLen; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ -+ ASSERT(data); -+ -+ i4CopySize = (count < (sizeof(acBuf) - 1)) ? count : (sizeof(acBuf) - 1); -+ if (copy_from_user(acBuf, buffer, i4CopySize)) -+ return 0; -+ acBuf[i4CopySize] = '\0'; -+ -+ if (sscanf(acBuf, "0x%lx 0x%lx", &rMcrInfo.u4McrOffset, &rMcrInfo.u4McrData) == 2) { -+ /* NOTE: Sometimes we want to test if bus will still be ok, after accessing -+ * the MCR which is not align to DW boundary. -+ */ -+ /* if (IS_ALIGN_4(rMcrInfo.u4McrOffset)) */ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv((struct net_device *)data)); -+ -+ u4McrOffset = rMcrInfo.u4McrOffset; -+ -+ /* printk("Write 0x%lx to MCR 0x%04lx\n", */ -+ /* rMcrInfo.u4McrOffset, rMcrInfo.u4McrData); */ -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetMcrWrite, -+ (PVOID)&rMcrInfo, sizeof(rMcrInfo), FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ } -+ -+ if (sscanf(acBuf, "0x%lx 0x%lx", &rMcrInfo.u4McrOffset, &rMcrInfo.u4McrData) == 1) { -+ /* if (IS_ALIGN_4(rMcrInfo.u4McrOffset)) */ -+ u4McrOffset = rMcrInfo.u4McrOffset; -+ } -+ -+ return count; -+ -+} /* end of procMCRWrite() */ -+#endif -+ -+#if 0 -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief The PROC function for reading Driver Status to User Space. -+* -+* \param[in] page Buffer provided by kernel. -+* \param[in out] start Start Address to read(3 methods). -+* \param[in] off Offset. -+* \param[in] count Allowable number to read. -+* \param[out] eof End of File indication. -+* \param[in] data Pointer to the private data structure. -+* -+* \return number of characters print to the buffer from User Space. -+*/ -+/*----------------------------------------------------------------------------*/ -+static int procDrvStatusRead(char *page, char **start, off_t off, int count, int *eof, void *data) -+{ -+ P_GLUE_INFO_T prGlueInfo = ((struct net_device *)data)->priv; -+ char *p = page; -+ UINT_32 u4Count; -+ -+ GLUE_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(data); -+ -+ /* Kevin: Apply PROC read method 1. */ -+ if (off != 0) -+ return 0; /* To indicate end of file. */ -+ -+ SPRINTF(p, ("GLUE LAYER STATUS:")); -+ SPRINTF(p, ("\n==================")); -+ -+ SPRINTF(p, ("\n* Number of Pending Frames: %ld\n", prGlueInfo->u4TxPendingFrameNum)); -+ -+ GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_FSM); -+ -+ wlanoidQueryDrvStatusForLinuxProc(prGlueInfo->prAdapter, p, &u4Count); -+ -+ GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_FSM); -+ -+ u4Count += (UINT_32) (p - page); -+ -+ *eof = 1; -+ -+ return (int)u4Count; -+ -+} /* end of procDrvStatusRead() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief The PROC function for reading Driver RX Statistic Counters to User Space. -+* -+* \param[in] page Buffer provided by kernel. -+* \param[in out] start Start Address to read(3 methods). -+* \param[in] off Offset. -+* \param[in] count Allowable number to read. -+* \param[out] eof End of File indication. -+* \param[in] data Pointer to the private data structure. -+* -+* \return number of characters print to the buffer from User Space. -+*/ -+/*----------------------------------------------------------------------------*/ -+static int procRxStatisticsRead(char *page, char **start, off_t off, int count, int *eof, void *data) -+{ -+ P_GLUE_INFO_T prGlueInfo = ((struct net_device *)data)->priv; -+ char *p = page; -+ UINT_32 u4Count; -+ -+ GLUE_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(data); -+ -+ /* Kevin: Apply PROC read method 1. */ -+ if (off != 0) -+ return 0; /* To indicate end of file. */ -+ -+ SPRINTF(p, ("RX STATISTICS (Write 1 to clear):")); -+ SPRINTF(p, ("\n=================================\n")); -+ -+ GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_FSM); -+ -+ wlanoidQueryRxStatisticsForLinuxProc(prGlueInfo->prAdapter, p, &u4Count); -+ -+ GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_FSM); -+ -+ u4Count += (UINT_32) (p - page); -+ -+ *eof = 1; -+ -+ return (int)u4Count; -+ -+} /* end of procRxStatisticsRead() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief The PROC function for reset Driver RX Statistic Counters. -+* -+* \param[in] file pointer to file. -+* \param[in] buffer Buffer from user space. -+* \param[in] count Number of characters to write -+* \param[in] data Pointer to the private data structure. -+* -+* \return number of characters write from User Space. -+*/ -+/*----------------------------------------------------------------------------*/ -+static int procRxStatisticsWrite(struct file *file, const char *buffer, unsigned long count, void *data) -+{ -+ P_GLUE_INFO_T prGlueInfo = ((struct net_device *)data)->priv; -+ char acBuf[PROC_RX_STATISTICS_MAX_USER_INPUT_LEN + 1]; /* + 1 for "\0" */ -+ UINT_32 u4CopySize; -+ UINT_32 u4ClearCounter; -+ -+ GLUE_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(data); -+ -+ u4CopySize = (count < (sizeof(acBuf) - 1)) ? count : (sizeof(acBuf) - 1); -+ copy_from_user(acBuf, buffer, u4CopySize); -+ acBuf[u4CopySize] = '\0'; -+ -+ if (kstrtoint(acBuf, 10, &u4ClearCounter) == 1) { -+ if (u4ClearCounter == 1) { -+ GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_FSM); -+ -+ wlanoidSetRxStatisticsForLinuxProc(prGlueInfo->prAdapter); -+ -+ GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_FSM); -+ } -+ } -+ -+ return count; -+ -+} /* end of procRxStatisticsWrite() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief The PROC function for reading Driver TX Statistic Counters to User Space. -+* -+* \param[in] page Buffer provided by kernel. -+* \param[in out] start Start Address to read(3 methods). -+* \param[in] off Offset. -+* \param[in] count Allowable number to read. -+* \param[out] eof End of File indication. -+* \param[in] data Pointer to the private data structure. -+* -+* \return number of characters print to the buffer from User Space. -+*/ -+/*----------------------------------------------------------------------------*/ -+static int procTxStatisticsRead(char *page, char **start, off_t off, int count, int *eof, void *data) -+{ -+ P_GLUE_INFO_T prGlueInfo = ((struct net_device *)data)->priv; -+ char *p = page; -+ UINT_32 u4Count; -+ -+ GLUE_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(data); -+ -+ /* Kevin: Apply PROC read method 1. */ -+ if (off != 0) -+ return 0; /* To indicate end of file. */ -+ -+ SPRINTF(p, ("TX STATISTICS (Write 1 to clear):")); -+ SPRINTF(p, ("\n=================================\n")); -+ -+ GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_FSM); -+ -+ wlanoidQueryTxStatisticsForLinuxProc(prGlueInfo->prAdapter, p, &u4Count); -+ -+ GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_FSM); -+ -+ u4Count += (UINT_32) (p - page); -+ -+ *eof = 1; -+ -+ return (int)u4Count; -+ -+} /* end of procTxStatisticsRead() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief The PROC function for reset Driver TX Statistic Counters. -+* -+* \param[in] file pointer to file. -+* \param[in] buffer Buffer from user space. -+* \param[in] count Number of characters to write -+* \param[in] data Pointer to the private data structure. -+* -+* \return number of characters write from User Space. -+*/ -+/*----------------------------------------------------------------------------*/ -+static int procTxStatisticsWrite(struct file *file, const char *buffer, unsigned long count, void *data) -+{ -+ P_GLUE_INFO_T prGlueInfo = ((struct net_device *)data)->priv; -+ char acBuf[PROC_RX_STATISTICS_MAX_USER_INPUT_LEN + 1]; /* + 1 for "\0" */ -+ UINT_32 u4CopySize; -+ UINT_32 u4ClearCounter; -+ -+ GLUE_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(data); -+ -+ u4CopySize = (count < (sizeof(acBuf) - 1)) ? count : (sizeof(acBuf) - 1); -+ copy_from_user(acBuf, buffer, u4CopySize); -+ acBuf[u4CopySize] = '\0'; -+ -+ if (kstrtoint(acBuf, 10, &u4ClearCounter) == 1) { -+ if (u4ClearCounter == 1) { -+ GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_FSM); -+ -+ wlanoidSetTxStatisticsForLinuxProc(prGlueInfo->prAdapter); -+ -+ GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_FSM); -+ } -+ } -+ -+ return count; -+ -+} /* end of procTxStatisticsWrite() */ -+#endif -+static struct proc_dir_entry *gprProcRoot; -+static UINT_8 aucDbModuleName[][PROC_DBG_LEVEL_MAX_DISPLAY_STR_LEN] = { -+ "INIT", "HAL", "INTR", "REQ", "TX", "RX", "RFTEST", "EMU", "SW1", "SW2", -+ "SW3", "SW4", "HEM", "AIS", "RLM", "MEM", "CNM", "RSN", "BSS", "SCN", -+ "SAA", "AAA", "P2P", "QM", "SEC", "BOW", "WAPI", "ROAMING", "TDLS", "OID", -+ "NIC" -+}; -+static UINT_8 aucProcBuf[1536]; -+static ssize_t procDbgLevelRead(struct file *filp, char __user *buf, size_t count, loff_t *f_pos) -+{ -+ UINT_8 *temp = &aucProcBuf[0]; -+ UINT_32 u4CopySize = 0; -+ UINT_16 i; -+ UINT_16 u2ModuleNum = 0; -+ -+ /* if *f_ops>0, we should return 0 to make cat command exit */ -+ if (*f_pos > 0) -+ return 0; -+ -+ kalStrCpy(temp, "\nTEMP |LOUD |INFO |TRACE|EVENT|STATE|WARN |ERROR\n" -+ "bit7 |bit6 |bit5 |bit4 |bit3 |bit2 |bit1 |bit0\n\n" -+ "Debug Module\tIndex\tLevel\tDebug Module\tIndex\tLevel\n\n"); -+ temp += kalStrLen(temp); -+ -+ u2ModuleNum = (sizeof(aucDbModuleName) / PROC_DBG_LEVEL_MAX_DISPLAY_STR_LEN) & 0xfe; -+ for (i = 0; i < u2ModuleNum; i += 2) -+ SPRINTF(temp, ("DBG_%s_IDX\t(0x%02x):\t0x%02x\tDBG_%s_IDX\t(0x%02x):\t0x%02x\n", -+ &aucDbModuleName[i][0], i, aucDebugModule[i], -+ &aucDbModuleName[i+1][0], i+1, aucDebugModule[i+1])); -+ -+ if ((sizeof(aucDbModuleName) / PROC_DBG_LEVEL_MAX_DISPLAY_STR_LEN) & 0x1) -+ SPRINTF(temp, ("DBG_%s_IDX\t(0x%02x):\t0x%02x\n", -+ &aucDbModuleName[u2ModuleNum][0], u2ModuleNum, aucDebugModule[u2ModuleNum])); -+ -+ u4CopySize = kalStrLen(aucProcBuf); -+ if (u4CopySize > count) -+ u4CopySize = count; -+ if (copy_to_user(buf, aucProcBuf, u4CopySize)) { -+ kalPrint("copy to user failed\n"); -+ return -EFAULT; -+ } -+ -+ *f_pos += u4CopySize; -+ return (ssize_t)u4CopySize; -+} -+ -+static ssize_t procDbgLevelWrite(struct file *file, const char *buffer, size_t count, loff_t *data) -+{ -+ UINT_32 u4NewDbgModule, u4NewDbgLevel; -+ UINT_8 i = 0; -+ UINT_32 u4CopySize = kalStrLen(aucProcBuf);//sizeof(aucProcBuf); -+ UINT_8 *temp = &aucProcBuf[0]; -+ -+ if (u4CopySize >= count + 1) -+ u4CopySize = count; -+ -+ kalMemSet(aucProcBuf, 0, u4CopySize); -+ -+ if (copy_from_user(aucProcBuf, buffer, u4CopySize)) { -+ kalPrint("error of copy from user\n"); -+ return -EFAULT; -+ } -+ aucProcBuf[u4CopySize] = '\0'; -+ -+ while (temp) { -+ if (sscanf(temp, "0x%x:0x%x", &u4NewDbgModule, &u4NewDbgLevel) != 2) { -+ kalPrint("debug module and debug level should be one byte in length\n"); -+ break; -+ } -+ if (u4NewDbgModule == 0xFF) { -+ for (i = 0; i < DBG_MODULE_NUM; i++) -+ aucDebugModule[i] = u4NewDbgLevel & DBG_CLASS_MASK; -+ -+ break; -+ } else if (u4NewDbgModule >= DBG_MODULE_NUM) { -+ kalPrint("debug module index should less than %d\n", DBG_MODULE_NUM); -+ break; -+ } -+ aucDebugModule[u4NewDbgModule] = u4NewDbgLevel & DBG_CLASS_MASK; -+ temp = kalStrChr(temp, ','); -+ if (!temp) -+ break; -+ temp++; /* skip ',' */ -+ } -+ return count; -+} -+ -+ -+static const struct file_operations dbglevel_ops = { -+ .owner = THIS_MODULE, -+ .read = procDbgLevelRead, -+ .write = procDbgLevelWrite, -+}; -+ -+static ssize_t procTxDoneCfgRead(struct file *filp, char __user *buf, size_t count, loff_t *f_pos) -+{ -+ UINT_8 *temp = &aucProcBuf[0]; -+ UINT_32 u4CopySize = 0; -+ UINT_16 u2TxDoneCfg = 0; -+ -+ /* if *f_ops>0, we should return 0 to make cat command exit */ -+ if (*f_pos > 0) -+ return 0; -+ -+ u2TxDoneCfg = StatsGetCfgTxDone(); -+ SPRINTF(temp, ("Tx Done Configure:\nARP %d\tDNS %d\nTCP %d\tUDP %d\nEAPOL %d\tDHCP %d\nICMP %d\n", -+ !!(u2TxDoneCfg & CFG_ARP), !!(u2TxDoneCfg & CFG_DNS), !!(u2TxDoneCfg & CFG_TCP), -+ !!(u2TxDoneCfg & CFG_UDP), !!(u2TxDoneCfg & CFG_EAPOL), !!(u2TxDoneCfg & CFG_DHCP), -+ !!(u2TxDoneCfg & CFG_ICMP))); -+ -+ u4CopySize = kalStrLen(aucProcBuf); -+ if (u4CopySize > count) -+ u4CopySize = count; -+ if (copy_to_user(buf, aucProcBuf, u4CopySize)) { -+ kalPrint("copy to user failed\n"); -+ return -EFAULT; -+ } -+ -+ *f_pos += u4CopySize; -+ return (ssize_t)u4CopySize; -+} -+ -+static ssize_t procTxDoneCfgWrite(struct file *file, const char *buffer, size_t count, loff_t *data) -+{ -+#define MODULE_NAME_LENGTH 6 -+ -+ UINT_8 i = 0; -+ UINT_32 u4CopySize = kalStrLen(aucProcBuf);//sizeof(aucProcBuf); -+ UINT_8 *temp = &aucProcBuf[0]; -+ UINT_16 u2SetTxDoneCfg = 0; -+ UINT_16 u2ClsTxDoneCfg = 0; -+ UINT_8 aucModule[MODULE_NAME_LENGTH]; -+ UINT_32 u4Enabled; -+ UINT_8 aucModuleArray[][MODULE_NAME_LENGTH] = {"ARP", "DNS", "TCP", "UDP", "EAPOL", "DHCP", "ICMP"}; -+ -+ if (u4CopySize >= count + 1) -+ u4CopySize = count; -+ -+ kalMemSet(aucProcBuf, 0, u4CopySize); -+ if (copy_from_user(aucProcBuf, buffer, u4CopySize)) { -+ kalPrint("error of copy from user\n"); -+ return -EFAULT; -+ } -+ aucProcBuf[u4CopySize] = '\0'; -+ temp = &aucProcBuf[0]; -+ while (temp) { -+ /* pick up a string and teminated after meet : */ -+ if (sscanf(temp, "%s %d", aucModule, &u4Enabled) != 2) { -+ kalPrint("read param fail, aucModule=%s\n", aucModule); -+ break; -+ } -+ for (i = 0; i < sizeof(aucModuleArray)/MODULE_NAME_LENGTH; i++) { -+ if (kalStrniCmp(aucModule, aucModuleArray[i], MODULE_NAME_LENGTH) == 0) { -+ if (u4Enabled) -+ u2SetTxDoneCfg |= 1 << i; -+ else -+ u2ClsTxDoneCfg |= 1 << i; -+ break; -+ } -+ } -+ temp = kalStrChr(temp, ','); -+ if (!temp) -+ break; -+ temp++; /* skip ',' */ -+ } -+ if (u2SetTxDoneCfg) -+ StatsSetCfgTxDone(u2SetTxDoneCfg, TRUE); -+ -+ if (u2ClsTxDoneCfg) -+ StatsSetCfgTxDone(u2ClsTxDoneCfg, FALSE); -+ return count; -+} -+ -+static const struct file_operations proc_txdone_ops = { -+ .owner = THIS_MODULE, -+ .read = procTxDoneCfgRead, -+ .write = procTxDoneCfgWrite, -+}; -+ -+static ssize_t procAutoPerCfgRead(struct file *filp, char __user *buf, size_t count, loff_t *f_pos) -+{ -+ UINT_8 *temp = &aucProcBuf[0]; -+ UINT_32 u4CopySize = 0; -+ -+ /* if *f_ops>0, we should return 0 to make cat command exit */ -+ if (*f_pos > 0) -+ return 0; -+ -+ SPRINTF(temp, ("Auto Performance Configure:\nperiod\tL1\nL2\tL3\n")); -+ -+ u4CopySize = kalStrLen(aucProcBuf); -+ if (u4CopySize > count) -+ u4CopySize = count; -+ if (copy_to_user(buf, aucProcBuf, u4CopySize)) { -+ kalPrint("copy to user failed\n"); -+ return -EFAULT; -+ } -+ -+ *f_pos += u4CopySize; -+ return (ssize_t)u4CopySize; -+} -+ -+static ssize_t procAutoPerCfgWrite(struct file *file, const char *buffer, size_t count, loff_t *data) -+{ -+ DBGLOG(INIT, WARN, "%s\n", __func__); -+ return 0; -+} -+ -+static const struct file_operations auto_per_ops = { -+ .owner = THIS_MODULE, -+ .read = procAutoPerCfgRead, -+ .write = procAutoPerCfgWrite, -+}; -+ -+ -+static ssize_t procCmdDebug(struct file *filp, char __user *buf, size_t count, loff_t *f_pos) -+{ -+ UINT_32 u4CopySize = 0; -+ -+ /* if *f_ops>0, we should return 0 to make cat command exit */ -+ if (*f_pos > 0) -+ return 0; -+ -+ wlanDumpTcResAndTxedCmd(aucProcBuf, sizeof(aucProcBuf)); -+ -+ u4CopySize = kalStrLen(aucProcBuf); -+ if (u4CopySize > count) -+ u4CopySize = count; -+ if (copy_to_user(buf, aucProcBuf, u4CopySize)) { -+ kalPrint("copy to user failed\n"); -+ return -EFAULT; -+ } -+ -+ *f_pos += u4CopySize; -+ return (ssize_t)u4CopySize; -+} -+ -+static const struct file_operations proc_CmdDebug_ops = { -+ .owner = THIS_MODULE, -+ .read = procCmdDebug, -+}; -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function create a PROC fs in linux /proc/net subdirectory. -+* -+* \param[in] prDev Pointer to the struct net_device. -+* \param[in] pucDevName Pointer to the name of net_device. -+* -+* \return N/A -+*/ -+/*----------------------------------------------------------------------------*/ -+ -+#if CFG_SUPPORT_THERMO_THROTTLING -+ -+/** -+ * This function is called then the /proc file is read -+ * -+ */ -+typedef struct _COEX_BUF1 { -+ UINT8 buffer[128]; -+ INT32 availSize; -+} COEX_BUF1, *P_COEX_BUF1; -+ -+COEX_BUF1 gCoexBuf1; -+ -+static ssize_t procfile_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos) -+{ -+ -+ INT32 retval = 0; -+ INT32 i_ret = 0; -+ CHAR *warn_msg = "no data available, please run echo 15 xx > /proc/driver/wmt_psm first\n"; -+ -+ if (*f_pos > 0) { -+ retval = 0; -+ } else { -+ /*len = sprintf(page, "%d\n", g_psm_enable); */ -+#if 1 -+ if (gCoexBuf1.availSize <= 0) { -+ DBGLOG(INIT, WARN, "no data available\n"); -+ retval = strlen(warn_msg) + 1; -+ if (count < retval) -+ retval = count; -+ i_ret = copy_to_user(buf, warn_msg, retval); -+ if (i_ret) { -+ DBGLOG(INIT, ERROR, "copy to buffer failed, ret:%d\n", retval); -+ retval = -EFAULT; -+ goto err_exit; -+ } -+ *f_pos += retval; -+ } else -+#endif -+ { -+ INT32 i = 0; -+ INT32 len = 0; -+ CHAR msg_info[128]; -+ INT32 max_num = 0; -+ /*we do not check page buffer, because there are only 100 bytes in g_coex_buf, no reason page -+ buffer is not enough, a bomb is placed here on unexpected condition */ -+ -+ DBGLOG(INIT, TRACE, "%d bytes available\n", gCoexBuf1.availSize); -+ max_num = ((sizeof(msg_info) > count ? sizeof(msg_info) : count) - 1) / 5; -+ -+ if (max_num > gCoexBuf1.availSize) -+ max_num = gCoexBuf1.availSize; -+ else -+ DBGLOG(INIT, TRACE, -+ "round to %d bytes due to local buffer size limitation\n", max_num); -+ -+ for (i = 0; i < max_num; i++) -+ len += sprintf(msg_info + len, "%d", gCoexBuf1.buffer[i]); -+ -+ len += sprintf(msg_info + len, "\n"); -+ retval = len; -+ -+ i_ret = copy_to_user(buf, msg_info, retval); -+ if (i_ret) { -+ DBGLOG(INIT, ERROR, "copy to buffer failed, ret:%d\n", retval); -+ retval = -EFAULT; -+ goto err_exit; -+ } -+ *f_pos += retval; -+ } -+ } -+ gCoexBuf1.availSize = 0; -+err_exit: -+ -+ return retval; -+} -+ -+#if 1 -+typedef INT32 (*WLAN_DEV_DBG_FUNC)(void); -+static INT32 wlan_get_thermo_power(void); -+static INT32 wlan_get_link_mode(void); -+ -+static const WLAN_DEV_DBG_FUNC wlan_dev_dbg_func[] = { -+ [0] = wlan_get_thermo_power, -+ [1] = wlan_get_link_mode, -+ -+}; -+ -+INT32 wlan_get_thermo_power(void) -+{ -+ P_ADAPTER_T prAdapter; -+ -+ prAdapter = g_prGlueInfo_proc->prAdapter; -+ -+ if (prAdapter->u4AirDelayTotal > 100) -+ gCoexBuf1.buffer[0] = 100; -+ else -+ gCoexBuf1.buffer[0] = prAdapter->u4AirDelayTotal; -+ gCoexBuf1.availSize = 1; -+ DBGLOG(RLM, TRACE, "PROC %s thrmo_power(%d)\n", __func__, gCoexBuf1.buffer[0]); -+ -+ return 0; -+} -+ -+INT32 wlan_get_link_mode(void) -+{ -+ UINT_8 ucLinkMode = 0; -+ P_ADAPTER_T prAdapter; -+ BOOLEAN fgIsAPmode; -+ -+ prAdapter = g_prGlueInfo_proc->prAdapter; -+ fgIsAPmode = p2pFuncIsAPMode(prAdapter->rWifiVar.prP2pFsmInfo); -+ -+ DBGLOG(RLM, TRACE, "PROC %s AIS(%d)P2P(%d)AP(%d)\n", -+ __func__, -+ prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX].eConnectionState, -+ prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX].eConnectionState, fgIsAPmode); -+ -+#if 1 -+ -+ if (prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX].eConnectionState == PARAM_MEDIA_STATE_CONNECTED) -+ ucLinkMode |= BIT(0); -+ if (prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX].eConnectionState == PARAM_MEDIA_STATE_CONNECTED) -+ ucLinkMode |= BIT(1); -+ if (fgIsAPmode) -+ ucLinkMode |= BIT(2); -+ -+#endif -+ gCoexBuf1.buffer[0] = ucLinkMode; -+ gCoexBuf1.availSize = 1; -+ -+ return 0; -+} -+ -+static ssize_t procfile_write(struct file *filp, const char __user *buffer, size_t count, loff_t *f_pos) -+{ -+ char buf[256]; -+ char *pBuf; -+ ULONG len = count; -+ INT32 x = 0, y = 0, z = 0; -+ char *pToken = NULL; -+ char *pDelimiter = " \t"; -+ INT32 i4Ret = 0; -+ -+ if (copy_from_user(gCoexBuf1.buffer, buffer, count)) -+ return -EFAULT; -+ /* gCoexBuf1.availSize = count; */ -+ -+ /* return gCoexBuf1.availSize; */ -+#if 1 -+ DBGLOG(INIT, TRACE, "write parameter len = %d\n\r", (INT32) len); -+ if (len >= sizeof(buf)) { -+ DBGLOG(INIT, ERROR, "input handling fail!\n"); -+ len = sizeof(buf) - 1; -+ return -1; -+ } -+ -+ if (copy_from_user(buf, buffer, len)) -+ return -EFAULT; -+ buf[len] = '\0'; -+ DBGLOG(INIT, TRACE, "write parameter data = %s\n\r", buf); -+ -+ pBuf = buf; -+ pToken = strsep(&pBuf, pDelimiter); -+ -+ if (pToken) /* x = NULL != pToken ? simple_strtol(pToken, NULL, 16) : 0; */ -+ i4Ret = kalkStrtos32(pToken, 16, &x); -+ if (!i4Ret) -+ DBGLOG(INIT, TRACE, "x = 0x%x\n", x); -+ -+#if 1 -+ pToken = strsep(&pBuf, "\t\n "); -+ if (pToken != NULL) { -+ i4Ret = kalkStrtos32(pToken, 16, &y); /* y = simple_strtol(pToken, NULL, 16); */ -+ if (!i4Ret) -+ DBGLOG(INIT, TRACE, "y = 0x%08x\n\r", y); -+ } else { -+ y = 3000; -+ /*efuse, register read write default value */ -+ if (0x11 == x || 0x12 == x || 0x13 == x) -+ y = 0x80000000; -+ } -+ -+ pToken = strsep(&pBuf, "\t\n "); -+ if (pToken != NULL) { -+ i4Ret = kalkStrtos32(pToken, 16, &z); /* z = simple_strtol(pToken, NULL, 16); */ -+ if (!i4Ret) -+ DBGLOG(INIT, TRACE, "z = 0x%08x\n\r", z); -+ } else { -+ z = 10; -+ /*efuse, register read write default value */ -+ if (0x11 == x || 0x12 == x || 0x13 == x) -+ z = 0xffffffff; -+ } -+ -+ DBGLOG(INIT, TRACE, " x(0x%08x), y(0x%08x), z(0x%08x)\n\r", x, y, z); -+#endif -+ -+ if (((sizeof(wlan_dev_dbg_func) / sizeof(wlan_dev_dbg_func[0])) > x) && NULL != wlan_dev_dbg_func[x]) -+ (*wlan_dev_dbg_func[x]) (); -+ else -+ DBGLOG(INIT, ERROR, "no handler defined for command id(0x%08x)\n\r", x); -+#endif -+ -+ /* len = gCoexBuf1.availSize; */ -+ return len; -+} -+#endif -+ static const struct file_operations proc_fops = { -+ .owner = THIS_MODULE, -+ .read = procfile_read, -+ .write = procfile_write, -+ }; -+#endif -+ -+INT_32 procInitFs(VOID) -+{ -+ struct proc_dir_entry *prEntry; -+ -+ if (init_net.proc_net == (struct proc_dir_entry *)NULL) { -+ kalPrint("init proc fs fail: proc_net == NULL\n"); -+ return -ENOENT; -+ } -+ -+ /* -+ * Directory: Root (/proc/net/wlan0) -+ */ -+ -+ gprProcRoot = proc_mkdir(PROC_ROOT_NAME, init_net.proc_net); -+ if (!gprProcRoot) { -+ kalPrint("gprProcRoot == NULL\n"); -+ return -ENOENT; -+ } -+ proc_set_user(gprProcRoot, KUIDT_INIT(PROC_UID_SHELL), KGIDT_INIT(PROC_GID_WIFI)); -+ -+ prEntry = proc_create(PROC_DBG_LEVEL_NAME, 0664, gprProcRoot, &dbglevel_ops); -+ if (prEntry == NULL) { -+ kalPrint("Unable to create /proc entry dbgLevel\n\r"); -+ return -1; -+ } -+ proc_set_user(prEntry, KUIDT_INIT(PROC_UID_SHELL), KGIDT_INIT(PROC_GID_WIFI)); -+ -+ prEntry = proc_create(PROC_NEED_TX_DONE, 0664, gprProcRoot, &proc_txdone_ops); -+ if (prEntry == NULL) { -+ kalPrint("Unable to create /proc entry dbgLevel\n\r"); -+ return -1; -+ } -+ proc_set_user(prEntry, KUIDT_INIT(PROC_UID_SHELL), KGIDT_INIT(PROC_GID_WIFI)); -+ -+ prEntry = proc_create(PROC_AUTO_PER_CFG, 0664, gprProcRoot, &auto_per_ops); -+ if (prEntry == NULL) { -+ kalPrint("Unable to create /proc entry autoPerCfg\n\r"); -+ return -1; -+ } -+ proc_set_user(prEntry, KUIDT_INIT(PROC_UID_SHELL), KGIDT_INIT(PROC_GID_WIFI)); -+ -+ return 0; -+} /* end of procInitProcfs() */ -+ -+INT_32 procUninitProcFs(VOID) -+{ -+ remove_proc_entry(PROC_DBG_LEVEL_NAME, gprProcRoot); -+ remove_proc_subtree(PROC_ROOT_NAME, init_net.proc_net); -+ remove_proc_entry(PROC_AUTO_PER_CFG, gprProcRoot); -+ return 0; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function clean up a PROC fs created by procInitProcfs(). -+* -+* \param[in] prDev Pointer to the struct net_device. -+* \param[in] pucDevName Pointer to the name of net_device. -+* -+* \return N/A -+*/ -+/*----------------------------------------------------------------------------*/ -+INT_32 procRemoveProcfs(VOID) -+{ -+ /* remove root directory (proc/net/wlan0) */ -+ /* remove_proc_entry(pucDevName, init_net.proc_net); */ -+ remove_proc_entry(PROC_WLAN_THERMO, gprProcRoot); -+ remove_proc_entry(PROC_CMD_DEBUG_NAME, gprProcRoot); -+#if CFG_SUPPORT_THERMO_THROTTLING -+ g_prGlueInfo_proc = NULL; -+#endif -+ return 0; -+} /* end of procRemoveProcfs() */ -+ -+INT_32 procCreateFsEntry(P_GLUE_INFO_T prGlueInfo) -+{ -+ struct proc_dir_entry *prEntry; -+ -+ DBGLOG(INIT, TRACE, "[%s]\n", __func__); -+ -+#if CFG_SUPPORT_THERMO_THROTTLING -+ g_prGlueInfo_proc = prGlueInfo; -+#endif -+ -+ prGlueInfo->pProcRoot = gprProcRoot; -+ -+ prEntry = proc_create(PROC_WLAN_THERMO, 0664, gprProcRoot, &proc_fops); -+ if (prEntry == NULL) { -+ DBGLOG(INIT, ERROR, "Unable to create /proc entry\n\r"); -+ return -1; -+ } -+ -+ prEntry = proc_create(PROC_CMD_DEBUG_NAME, 0444, gprProcRoot, &proc_CmdDebug_ops); -+ if (prEntry == NULL) { -+ kalPrint("Unable to create /proc entry dbgLevel\n\r"); -+ return -1; -+ } -+ proc_set_user(prEntry, KUIDT_INIT(PROC_UID_SHELL), KGIDT_INIT(PROC_GID_WIFI)); -+ return 0; -+} -+ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_rst.c b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_rst.c -new file mode 100644 -index 000000000000..f97db8a69fd2 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_rst.c -@@ -0,0 +1,228 @@ -+/* -+** Id: @(#) gl_rst.c@@ -+*/ -+ -+/*! \file gl_rst.c -+ \brief Main routines for supporintg MT6620 whole-chip reset mechanism -+ -+ This file contains the support routines of Linux driver for MediaTek Inc. 802.11 -+ Wireless LAN Adapters. -+*/ -+ -+/* -+** Log: gl_rst.c -+ * -+ * 11 10 2011 cp.wu -+ * [WCXRP00001098] [MT6620 Wi-Fi][Driver] Replace printk by DBG LOG macros in linux porting layer -+ * 1. eliminaite direct calls to printk in porting layer. -+ * 2. replaced by DBGLOG, which would be XLOG on ALPS platforms. -+ * -+ * 04 22 2011 cp.wu -+ * [WCXRP00000598] [MT6620 Wi-Fi][Driver] Implementation of interface for communicating with user space process for -+ * RESET_START and RESET_END events -+ * skip power-off handshaking when RESET indication is received. -+ * -+ * 04 14 2011 cp.wu -+ * [WCXRP00000598] [MT6620 Wi-Fi][Driver] Implementation of interface for communicating with user space process for -+ * RESET_START and RESET_END events -+ * 1. add code to put whole-chip resetting trigger when abnormal firmware assertion is detected -+ * 2. add dummy function for both Win32 and Linux part. -+ * -+ * 03 30 2011 cp.wu -+ * [WCXRP00000598] [MT6620 Wi-Fi][Driver] Implementation of interface for communicating with user space process for -+ * RESET_START and RESET_END events -+ * use netlink unicast instead of broadcast -+ * -+** -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include -+#include -+ -+#include "precomp.h" -+#include "gl_rst.h" -+ -+#if CFG_CHIP_RESET_SUPPORT -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+BOOLEAN fgIsResetting = FALSE; -+UINT_32 g_IsNeedDoChipReset = 0; -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+static RESET_STRUCT_T wifi_rst; -+ -+static void mtk_wifi_reset(struct work_struct *work); -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+static void *glResetCallback(ENUM_WMTDRV_TYPE_T eSrcType, -+ ENUM_WMTDRV_TYPE_T eDstType, -+ ENUM_WMTMSG_TYPE_T eMsgType, void *prMsgBody, unsigned int u4MsgLength); -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * @brief This routine is responsible for -+ * 1. register wifi reset callback -+ * 2. initialize wifi reset work -+ * -+ * @param none -+ * -+ * @retval none -+ */ -+/*----------------------------------------------------------------------------*/ -+VOID glResetInit(VOID) -+{ -+#if (MTK_WCN_SINGLE_MODULE == 0) -+ /* 1. Register reset callback */ -+ mtk_wcn_wmt_msgcb_reg(WMTDRV_TYPE_WIFI, (PF_WMT_CB) glResetCallback); -+#endif /* MTK_WCN_SINGLE_MODULE */ -+ -+ /* 2. Initialize reset work */ -+ INIT_WORK(&(wifi_rst.rst_work), mtk_wifi_reset); -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * @brief This routine is responsible for -+ * 1. deregister wifi reset callback -+ * -+ * @param none -+ * -+ * @retval none -+ */ -+/*----------------------------------------------------------------------------*/ -+VOID glResetUninit(VOID) -+{ -+#if (MTK_WCN_SINGLE_MODULE == 0) -+ /* 1. Deregister reset callback */ -+ mtk_wcn_wmt_msgcb_unreg(WMTDRV_TYPE_WIFI); -+#endif /* MTK_WCN_SINGLE_MODULE */ -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * @brief This routine is invoked when there is reset messages indicated -+ * -+ * @param eSrcType -+ * eDstType -+ * eMsgType -+ * prMsgBody -+ * u4MsgLength -+ * -+ * @retval -+ */ -+/*----------------------------------------------------------------------------*/ -+static void *glResetCallback(ENUM_WMTDRV_TYPE_T eSrcType, -+ ENUM_WMTDRV_TYPE_T eDstType, -+ ENUM_WMTMSG_TYPE_T eMsgType, void *prMsgBody, unsigned int u4MsgLength) -+{ -+ switch (eMsgType) { -+ case WMTMSG_TYPE_RESET: -+ if (u4MsgLength == sizeof(ENUM_WMTRSTMSG_TYPE_T)) { -+ P_ENUM_WMTRSTMSG_TYPE_T prRstMsg = (P_ENUM_WMTRSTMSG_TYPE_T) prMsgBody; -+ -+ switch (*prRstMsg) { -+ case WMTRSTMSG_RESET_START: -+ DBGLOG(INIT, WARN, "Whole chip reset start!\n"); -+ fgIsResetting = TRUE; -+ wifi_reset_start(); -+ break; -+ -+ case WMTRSTMSG_RESET_END: -+ DBGLOG(INIT, WARN, "Whole chip reset end!\n"); -+ fgIsResetting = FALSE; -+ wifi_rst.rst_data = RESET_SUCCESS; -+ schedule_work(&(wifi_rst.rst_work)); -+ break; -+ -+ case WMTRSTMSG_RESET_END_FAIL: -+ DBGLOG(INIT, WARN, "Whole chip reset fail!\n"); -+ fgIsResetting = FALSE; -+ wifi_rst.rst_data = RESET_FAIL; -+ schedule_work(&(wifi_rst.rst_work)); -+ break; -+ -+ default: -+ break; -+ } -+ } -+ break; -+ -+ default: -+ break; -+ } -+ -+ return NULL; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * @brief This routine is called for wifi reset -+ * -+ * @param skb -+ * info -+ * -+ * @retval 0 -+ * nonzero -+ */ -+/*----------------------------------------------------------------------------*/ -+static void mtk_wifi_reset(struct work_struct *work) -+{ -+ RESET_STRUCT_T *rst = container_of(work, RESET_STRUCT_T, rst_work); -+ -+ wifi_reset_end(rst->rst_data); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * @brief This routine is called for generating reset request to WMT -+ * -+ * @param None -+ * -+ * @retval None -+ */ -+/*----------------------------------------------------------------------------*/ -+VOID glSendResetRequest(VOID) -+{ -+ /* WMT thread would trigger whole chip reset itself */ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * @brief This routine is called for checking if connectivity chip is resetting -+ * -+ * @param None -+ * -+ * @retval TRUE -+ * FALSE -+ */ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN kalIsResetting(VOID) -+{ -+ return fgIsResetting; -+} -+ -+#endif /* CFG_CHIP_RESET_SUPPORT */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_vendor.c b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_vendor.c -new file mode 100644 -index 000000000000..862d011a43df ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_vendor.c -@@ -0,0 +1,1220 @@ -+/* -+** Id: @(#) gl_cfg80211.c@@ -+*/ -+ -+/*! \file gl_cfg80211.c -+ \brief Main routines for supporintg MT6620 cfg80211 control interface -+ -+ This file contains the support routines of Linux driver for MediaTek Inc. 802.11 -+ Wireless LAN Adapters. -+*/ -+ -+/* -+** Log: gl_cfg80211.c -+** -+** 09 05 2013 cp.wu -+** correct length to pass to wlanoidSetBssid() -+** -+** 09 04 2013 cp.wu -+** fix typo -+** -+** 09 03 2013 cp.wu -+** add path for reassociation -+** -+** 11 23 2012 yuche.tsai -+** [ALPS00398671] [Acer-Tablet] Remove Wi-Fi Direct completely -+** Fix bug of WiFi may reboot under user load, when WiFi Direct is removed.. -+** -+** 09 12 2012 wcpadmin -+** [ALPS00276400] Remove MTK copyright and legal header on GPL/LGPL related packages -+** . -+** -+** 08 30 2012 chinglan.wang -+** [ALPS00349664] [6577JB][WIFI] Phone can not connect to AP secured with AES via WPS in 802.11n Only -+** . -+ * -+** -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include -+#include -+#include -+ -+#include "gl_os.h" -+#include "wlan_lib.h" -+#include "gl_wext.h" -+#include "precomp.h" -+#include "gl_cfg80211.h" -+#include "gl_vendor.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+static struct nla_policy nla_parse_policy[GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_FLUSH + 1] = { -+ [GSCAN_ATTRIBUTE_NUM_BUCKETS] = {.type = NLA_U32}, -+ [GSCAN_ATTRIBUTE_BASE_PERIOD] = {.type = NLA_U32}, -+ [GSCAN_ATTRIBUTE_BUCKETS_BAND] = {.type = NLA_U32}, -+ [GSCAN_ATTRIBUTE_BUCKET_ID] = {.type = NLA_U32}, -+ [GSCAN_ATTRIBUTE_BUCKET_PERIOD] = {.type = NLA_U32}, -+ [GSCAN_ATTRIBUTE_BUCKET_NUM_CHANNELS] = {.type = NLA_U32}, -+ [GSCAN_ATTRIBUTE_BUCKET_CHANNELS] = {.type = NLA_U32}, -+ [GSCAN_ATTRIBUTE_NUM_AP_PER_SCAN] = {.type = NLA_U32}, -+ [GSCAN_ATTRIBUTE_REPORT_THRESHOLD] = {.type = NLA_U32}, -+ [GSCAN_ATTRIBUTE_NUM_SCANS_TO_CACHE] = {.type = NLA_U32}, -+ [GSCAN_ATTRIBUTE_REPORT_EVENTS] = {.type = NLA_U32}, -+ [GSCAN_ATTRIBUTE_BSSID] = {.type = NLA_UNSPEC}, -+ [GSCAN_ATTRIBUTE_RSSI_LOW] = {.type = NLA_U32}, -+ [GSCAN_ATTRIBUTE_RSSI_HIGH] = {.type = NLA_U32}, -+ [GSCAN_ATTRIBUTE_RSSI_SAMPLE_SIZE] = {.type = NLA_U16}, -+ [GSCAN_ATTRIBUTE_LOST_AP_SAMPLE_SIZE] = {.type = NLA_U32}, -+ [GSCAN_ATTRIBUTE_MIN_BREACHING] = {.type = NLA_U16}, -+ [GSCAN_ATTRIBUTE_NUM_AP] = {.type = NLA_U16}, -+ [GSCAN_ATTRIBUTE_HOTLIST_FLUSH] = {.type = NLA_U8}, -+ [GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_FLUSH] = {.type = NLA_U8}, -+}; -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+int mtk_cfg80211_vendor_get_channel_list(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int data_len) -+{ -+ P_GLUE_INFO_T prGlueInfo; -+ struct nlattr *attr; -+ UINT_32 band = 0; -+ UINT_8 ucNumOfChannel, i, j; -+ RF_CHANNEL_INFO_T aucChannelList[64]; -+ UINT_32 num_channels; -+ wifi_channel channels[64]; -+ struct sk_buff *skb; -+ -+ ASSERT(wiphy && wdev); -+ if ((data == NULL) || !data_len) -+ return -EINVAL; -+ -+ DBGLOG(REQ, INFO, "vendor command: data_len=%d\n", data_len); -+ -+ attr = (struct nlattr *)data; -+ if (attr->nla_type == WIFI_ATTRIBUTE_BAND) -+ band = nla_get_u32(attr); -+ -+ DBGLOG(REQ, INFO, "Get channel list for band: %d\n", band); -+ -+ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); -+ if (!prGlueInfo) -+ return -EFAULT; -+ -+ if (band == 0) { /* 2.4G band */ -+ rlmDomainGetChnlList(prGlueInfo->prAdapter, BAND_2G4, TRUE, -+ 64, &ucNumOfChannel, aucChannelList); -+ } else { /* 5G band */ -+ rlmDomainGetChnlList(prGlueInfo->prAdapter, BAND_5G, TRUE, -+ 64, &ucNumOfChannel, aucChannelList); -+ } -+ -+ kalMemZero(channels, sizeof(channels)); -+ for (i = 0, j = 0; i < ucNumOfChannel; i++) { -+ /* We need to report frequency list to HAL */ -+ channels[j] = nicChannelNum2Freq(aucChannelList[i].ucChannelNum) / 1000; -+ if (channels[j] == 0) -+ continue; -+ else if ((prGlueInfo->prAdapter->rWifiVar.rConnSettings.u2CountryCode == COUNTRY_CODE_TW) && -+ (channels[j] >= 5180 && channels[j] <= 5260)) { -+ /* Taiwan NCC has resolution to follow FCC spec to support 5G Band 1/2/3/4 -+ * (CH36~CH48, CH52~CH64, CH100~CH140, CH149~CH165) -+ * Filter CH36~CH52 for compatible with some old devices. -+ */ -+ continue; -+ } else { -+ DBGLOG(REQ, INFO, "channels[%d] = %d\n", j, channels[j]); -+ j++; -+ } -+ } -+ num_channels = j; -+ -+ skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(channels)); -+ if (!skb) { -+ DBGLOG(REQ, ERROR, "Allocate skb failed\n"); -+ return -ENOMEM; -+ } -+ -+ if (unlikely(nla_put_u32(skb, WIFI_ATTRIBUTE_NUM_CHANNELS, num_channels) < 0)) -+ goto nla_put_failure; -+ -+ if (unlikely(nla_put(skb, WIFI_ATTRIBUTE_CHANNEL_LIST, -+ (sizeof(wifi_channel) * num_channels), channels) < 0)) -+ goto nla_put_failure; -+ -+ return cfg80211_vendor_cmd_reply(skb); -+ -+nla_put_failure: -+ kfree_skb(skb); -+ return -EFAULT; -+} -+ -+int mtk_cfg80211_vendor_set_country_code(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int data_len) -+{ -+ P_GLUE_INFO_T prGlueInfo; -+ WLAN_STATUS rStatus; -+ UINT_32 u4BufLen; -+ struct nlattr *attr; -+ UINT_8 country[2] = {0, 0}; -+ -+ ASSERT(wiphy && wdev); -+ if ((data == NULL) || (data_len == 0)) -+ return -EINVAL; -+ -+ DBGLOG(REQ, INFO, "vendor command: data_len=%d\n", data_len); -+ -+ attr = (struct nlattr *)data; -+ if (attr->nla_type == WIFI_ATTRIBUTE_COUNTRY_CODE) { -+ country[0] = *((PUINT_8)nla_data(attr)); -+ country[1] = *((PUINT_8)nla_data(attr) + 1); -+ } -+ -+ DBGLOG(REQ, INFO, "Set country code: %c%c\n", country[0], country[1]); -+ -+ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); -+ if (!prGlueInfo) -+ return -EFAULT; -+ -+ rStatus = kalIoctl(prGlueInfo, wlanoidSetCountryCode, country, 2, FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ DBGLOG(REQ, ERROR, "Set country code error: %x\n", rStatus); -+ return -EFAULT; -+ } -+ -+ return 0; -+} -+ -+int mtk_cfg80211_vendor_get_gscan_capabilities(struct wiphy *wiphy, -+ struct wireless_dev *wdev, const void *data, int data_len) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ INT_32 i4Status = -EINVAL; -+ PARAM_WIFI_GSCAN_CAPABILITIES_STRUCT_T rGscanCapabilities; -+ struct sk_buff *skb; -+ /* UINT_32 u4BufLen; */ -+ -+ DBGLOG(REQ, TRACE, "%s for vendor command \r\n", __func__); -+ -+ ASSERT(wiphy); -+ ASSERT(wdev); -+ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); -+ -+ skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(rGscanCapabilities)); -+ if (!skb) { -+ DBGLOG(REQ, ERROR, "%s allocate skb failed:%x\n", __func__, i4Status); -+ return -ENOMEM; -+ } -+ -+ kalMemZero(&rGscanCapabilities, sizeof(rGscanCapabilities)); -+ -+ /*rStatus = kalIoctl(prGlueInfo, -+ wlanoidQueryStatistics, -+ &rGscanCapabilities, -+ sizeof(rGscanCapabilities), -+ TRUE, -+ TRUE, -+ TRUE, -+ FALSE, -+ &u4BufLen); */ -+ rGscanCapabilities.max_scan_cache_size = PSCAN_MAX_SCAN_CACHE_SIZE; -+ rGscanCapabilities.max_scan_buckets = GSCAN_MAX_BUCKETS; -+ rGscanCapabilities.max_ap_cache_per_scan = PSCAN_MAX_AP_CACHE_PER_SCAN; -+ rGscanCapabilities.max_rssi_sample_size = 10; -+ rGscanCapabilities.max_scan_reporting_threshold = GSCAN_MAX_REPORT_THRESHOLD; -+ rGscanCapabilities.max_hotlist_aps = MAX_HOTLIST_APS; -+ rGscanCapabilities.max_significant_wifi_change_aps = MAX_SIGNIFICANT_CHANGE_APS; -+ rGscanCapabilities.max_bssid_history_entries = PSCAN_MAX_AP_CACHE_PER_SCAN * PSCAN_MAX_SCAN_CACHE_SIZE; -+ -+ /* NLA_PUT_U8(skb, NL80211_TESTMODE_STA_STATISTICS_INVALID, 0); */ -+ /* NLA_PUT_U32(skb, NL80211_ATTR_VENDOR_ID, GOOGLE_OUI); */ -+ /* NLA_PUT_U32(skb, NL80211_ATTR_VENDOR_SUBCMD, GSCAN_SUBCMD_GET_CAPABILITIES); */ -+ /*NLA_PUT(skb, GSCAN_ATTRIBUTE_CAPABILITIES, sizeof(rGscanCapabilities), &rGscanCapabilities);*/ -+ if (unlikely(nla_put(skb, GSCAN_ATTRIBUTE_CAPABILITIES, -+ sizeof(rGscanCapabilities), &rGscanCapabilities) < 0)) -+ goto nla_put_failure; -+ -+ i4Status = cfg80211_vendor_cmd_reply(skb); -+ return i4Status; -+ -+nla_put_failure: -+ kfree_skb(skb); -+ return i4Status; -+} -+ -+int mtk_cfg80211_vendor_set_config(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int data_len) -+{ -+ WLAN_STATUS rStatus; -+ UINT_32 u4BufLen; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ /* CMD_GSCN_REQ_T rCmdGscnParam; */ -+ -+ /* INT_32 i4Status = -EINVAL; */ -+ P_PARAM_WIFI_GSCAN_CMD_PARAMS prWifiScanCmd = NULL; -+ struct nlattr *attr[GSCAN_ATTRIBUTE_REPORT_EVENTS + 1]; -+ struct nlattr *pbucket, *pchannel; -+ UINT_32 len_basic, len_bucket, len_channel; -+ int i, j, k; -+ -+ ASSERT(wiphy); -+ ASSERT(wdev); -+ if ((data == NULL) || !data_len) -+ goto nla_put_failure; -+ -+ prWifiScanCmd = (P_PARAM_WIFI_GSCAN_CMD_PARAMS) kalMemAlloc(sizeof(PARAM_WIFI_GSCAN_CMD_PARAMS), VIR_MEM_TYPE); -+ if (!prWifiScanCmd) { -+ DBGLOG(REQ, ERROR, "Can not alloc memory for PARAM_WIFI_GSCAN_CMD_PARAMS\n"); -+ return -ENOMEM; -+ } -+ -+ DBGLOG(REQ, INFO, "%s for vendor command: data_len=%d \r\n", __func__, data_len); -+ kalMemZero(prWifiScanCmd, sizeof(PARAM_WIFI_GSCAN_CMD_PARAMS)); -+ kalMemZero(attr, sizeof(struct nlattr *) * (GSCAN_ATTRIBUTE_REPORT_EVENTS + 1)); -+ -+ nla_parse_nested(attr, GSCAN_ATTRIBUTE_REPORT_EVENTS, (struct nlattr *)(data - NLA_HDRLEN), nla_parse_policy,NULL); -+ len_basic = 0; -+ for (k = GSCAN_ATTRIBUTE_NUM_BUCKETS; k <= GSCAN_ATTRIBUTE_REPORT_EVENTS; k++) { -+ if (attr[k]) { -+ switch (k) { -+ case GSCAN_ATTRIBUTE_BASE_PERIOD: -+ prWifiScanCmd->base_period = nla_get_u32(attr[k]); -+ len_basic += NLA_ALIGN(attr[k]->nla_len); -+ break; -+ case GSCAN_ATTRIBUTE_NUM_BUCKETS: -+ prWifiScanCmd->num_buckets = nla_get_u32(attr[k]); -+ len_basic += NLA_ALIGN(attr[k]->nla_len); -+ DBGLOG(REQ, TRACE, "attr=0x%x, num_buckets=%d nla_len=%d, \r\n", -+ *(UINT_32 *) attr[k], prWifiScanCmd->num_buckets, attr[k]->nla_len); -+ break; -+ } -+ } -+ } -+ pbucket = (struct nlattr *)((UINT_8 *) data + len_basic); -+ DBGLOG(REQ, TRACE, "+++basic attribute size=%d pbucket=%p\r\n", len_basic, pbucket); -+ -+ for (i = 0; i < prWifiScanCmd->num_buckets; i++) { -+ if (nla_parse_nested(attr, GSCAN_ATTRIBUTE_REPORT_EVENTS, (struct nlattr *)pbucket, -+ nla_parse_policy,NULL) < 0) -+ goto nla_put_failure; -+ len_bucket = 0; -+ for (k = GSCAN_ATTRIBUTE_NUM_BUCKETS; k <= GSCAN_ATTRIBUTE_REPORT_EVENTS; k++) { -+ if (attr[k]) { -+ switch (k) { -+ case GSCAN_ATTRIBUTE_BUCKETS_BAND: -+ prWifiScanCmd->buckets[i].band = nla_get_u32(attr[k]); -+ len_bucket += NLA_ALIGN(attr[k]->nla_len); -+ break; -+ case GSCAN_ATTRIBUTE_BUCKET_ID: -+ prWifiScanCmd->buckets[i].bucket = nla_get_u32(attr[k]); -+ len_bucket += NLA_ALIGN(attr[k]->nla_len); -+ break; -+ case GSCAN_ATTRIBUTE_BUCKET_PERIOD: -+ prWifiScanCmd->buckets[i].period = nla_get_u32(attr[k]); -+ len_bucket += NLA_ALIGN(attr[k]->nla_len); -+ break; -+ case GSCAN_ATTRIBUTE_REPORT_EVENTS: -+ prWifiScanCmd->buckets[i].report_events = nla_get_u32(attr[k]); -+ len_bucket += NLA_ALIGN(attr[k]->nla_len); -+ break; -+ case GSCAN_ATTRIBUTE_BUCKET_NUM_CHANNELS: -+ prWifiScanCmd->buckets[i].num_channels = nla_get_u32(attr[k]); -+ len_bucket += NLA_ALIGN(attr[k]->nla_len); -+ DBGLOG(REQ, TRACE, "bucket%d: attr=0x%x, num_channels=%d nla_len = %d, \r\n", -+ i, *(UINT_32 *) attr[k], nla_get_u32(attr[k]), attr[k]->nla_len); -+ break; -+ } -+ } -+ } -+ pbucket = (struct nlattr *)((UINT_8 *) pbucket + NLA_HDRLEN); -+ /* request.attr_start(i) as nested attribute */ -+ DBGLOG(REQ, TRACE, "+++pure bucket size=%d pbucket=%p \r\n", len_bucket, pbucket); -+ pbucket = (struct nlattr *)((UINT_8 *) pbucket + len_bucket); -+ /* pure bucket payload, not include channels */ -+ -+ /*don't need to use nla_parse_nested to parse channels */ -+ /* the header of channel in bucket i */ -+ pchannel = (struct nlattr *)((UINT_8 *) pbucket + NLA_HDRLEN); -+ for (j = 0; j < prWifiScanCmd->buckets[i].num_channels; j++) { -+ prWifiScanCmd->buckets[i].channels[j].channel = nla_get_u32(pchannel); -+ len_channel = NLA_ALIGN(pchannel->nla_len); -+ DBGLOG(REQ, TRACE, -+ "attr=0x%x, channel=%d, \r\n", *(UINT_32 *) pchannel, nla_get_u32(pchannel)); -+ -+ pchannel = (struct nlattr *)((UINT_8 *) pchannel + len_channel); -+ } -+ pbucket = pchannel; -+ } -+ -+ DBGLOG(REQ, TRACE, "base_period=%d, num_buckets=%d, bucket0: %d %d %d %d", -+ prWifiScanCmd->base_period, prWifiScanCmd->num_buckets, -+ prWifiScanCmd->buckets[0].bucket, prWifiScanCmd->buckets[0].period, -+ prWifiScanCmd->buckets[0].band, prWifiScanCmd->buckets[0].report_events); -+ -+ DBGLOG(REQ, TRACE, "num_channels=%d, channel0=%d, channel1=%d; num_channels=%d, channel0=%d, channel1=%d", -+ prWifiScanCmd->buckets[0].num_channels, -+ prWifiScanCmd->buckets[0].channels[0].channel, prWifiScanCmd->buckets[0].channels[1].channel, -+ prWifiScanCmd->buckets[1].num_channels, -+ prWifiScanCmd->buckets[1].channels[0].channel, prWifiScanCmd->buckets[1].channels[1].channel); -+ -+ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); -+ ASSERT(prGlueInfo); -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetGSCNAParam, -+ prWifiScanCmd, sizeof(PARAM_WIFI_GSCAN_CMD_PARAMS), FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ kalMemFree(prWifiScanCmd, VIR_MEM_TYPE, sizeof(PARAM_WIFI_GSCAN_CMD_PARAMS)); -+ return 0; -+ -+nla_put_failure: -+ if (prWifiScanCmd != NULL) -+ kalMemFree(prWifiScanCmd, VIR_MEM_TYPE, sizeof(PARAM_WIFI_GSCAN_CMD_PARAMS)); -+ return -1; -+} -+ -+int mtk_cfg80211_vendor_set_scan_config(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int data_len) -+{ -+ WLAN_STATUS rStatus; -+ UINT_32 u4BufLen; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ -+ INT_32 i4Status = -EINVAL; -+ /*PARAM_WIFI_GSCAN_CMD_PARAMS rWifiScanCmd;*/ -+ P_PARAM_WIFI_GSCAN_CMD_PARAMS prWifiScanCmd = NULL; -+ struct nlattr *attr[GSCAN_ATTRIBUTE_NUM_SCANS_TO_CACHE + 1]; -+ /* UINT_32 num_scans = 0; */ /* another attribute */ -+ int k; -+ -+ ASSERT(wiphy); -+ ASSERT(wdev); -+ if ((data == NULL) || !data_len) -+ goto nla_put_failure; -+ DBGLOG(REQ, INFO, "%s for vendor command: data_len=%d \r\n", __func__, data_len); -+ /*kalMemZero(&rWifiScanCmd, sizeof(rWifiScanCmd));*/ -+ prWifiScanCmd = kalMemAlloc(sizeof(PARAM_WIFI_GSCAN_CMD_PARAMS), VIR_MEM_TYPE); -+ if (prWifiScanCmd == NULL) -+ goto nla_put_failure; -+ kalMemZero(prWifiScanCmd, sizeof(PARAM_WIFI_GSCAN_CMD_PARAMS)); -+ kalMemZero(attr, sizeof(struct nlattr *) * (GSCAN_ATTRIBUTE_NUM_SCANS_TO_CACHE + 1)); -+ -+ if (nla_parse_nested(attr, GSCAN_ATTRIBUTE_NUM_SCANS_TO_CACHE, -+ (struct nlattr *)(data - NLA_HDRLEN), nla_parse_policy,NULL) < 0) -+ goto nla_put_failure; -+ for (k = GSCAN_ATTRIBUTE_NUM_AP_PER_SCAN; k <= GSCAN_ATTRIBUTE_NUM_SCANS_TO_CACHE; k++) { -+ if (attr[k]) { -+ switch (k) { -+ case GSCAN_ATTRIBUTE_NUM_AP_PER_SCAN: -+ prWifiScanCmd->max_ap_per_scan = nla_get_u32(attr[k]); -+ break; -+ case GSCAN_ATTRIBUTE_REPORT_THRESHOLD: -+ prWifiScanCmd->report_threshold = nla_get_u32(attr[k]); -+ break; -+ case GSCAN_ATTRIBUTE_NUM_SCANS_TO_CACHE: -+ prWifiScanCmd->num_scans = nla_get_u32(attr[k]); -+ break; -+ } -+ } -+ } -+ DBGLOG(REQ, TRACE, "attr=0x%x, attr2=0x%x ", *(UINT_32 *) attr[GSCAN_ATTRIBUTE_NUM_AP_PER_SCAN], -+ *(UINT_32 *) attr[GSCAN_ATTRIBUTE_REPORT_THRESHOLD]); -+ -+ DBGLOG(REQ, TRACE, "max_ap_per_scan=%d, report_threshold=%d num_scans=%d \r\n", -+ prWifiScanCmd->max_ap_per_scan, prWifiScanCmd->report_threshold, prWifiScanCmd->num_scans); -+ -+ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); -+ ASSERT(prGlueInfo); -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetGSCNAConfig, -+ prWifiScanCmd, sizeof(PARAM_WIFI_GSCAN_CMD_PARAMS), FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ kalMemFree(prWifiScanCmd, VIR_MEM_TYPE, sizeof(PARAM_WIFI_GSCAN_CMD_PARAMS)); -+ return 0; -+ -+nla_put_failure: -+ if (prWifiScanCmd != NULL) -+ kalMemFree(prWifiScanCmd, VIR_MEM_TYPE, sizeof(PARAM_WIFI_GSCAN_CMD_PARAMS)); -+ return i4Status; -+} -+ -+int mtk_cfg80211_vendor_set_significant_change(struct wiphy *wiphy, struct wireless_dev *wdev, -+ const void *data, int data_len) -+{ -+ INT_32 i4Status = -EINVAL; -+ P_PARAM_WIFI_SIGNIFICANT_CHANGE prWifiChangeCmd = NULL; -+ UINT_8 flush = 0; -+ /* struct nlattr *attr[GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_FLUSH + 1]; */ -+ struct nlattr **attr = NULL; -+ struct nlattr *paplist; -+ int i, k; -+ UINT_32 len_basic, len_aplist; -+ -+ ASSERT(wiphy); -+ ASSERT(wdev); -+ if ((data == NULL) || !data_len) -+ goto nla_put_failure; -+ DBGLOG(REQ, INFO, "%s for vendor command: data_len=%d \r\n", __func__, data_len); -+ for (i = 0; i < 6; i++) -+ DBGLOG(REQ, LOUD, "0x%x 0x%x 0x%x 0x%x \r\n", -+ *((UINT_32 *) data + i * 4), *((UINT_32 *) data + i * 4 + 1), -+ *((UINT_32 *) data + i * 4 + 2), *((UINT_32 *) data + i * 4 + 3)); -+ prWifiChangeCmd = kalMemAlloc(sizeof(PARAM_WIFI_SIGNIFICANT_CHANGE), VIR_MEM_TYPE); -+ if (prWifiChangeCmd == NULL) -+ goto nla_put_failure; -+ kalMemZero(prWifiChangeCmd, sizeof(PARAM_WIFI_SIGNIFICANT_CHANGE)); -+ attr = kalMemAlloc(sizeof(struct nlattr *) * (GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_FLUSH + 1), VIR_MEM_TYPE); -+ if (attr == NULL) -+ goto nla_put_failure; -+ kalMemZero(attr, sizeof(struct nlattr *) * (GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_FLUSH + 1)); -+ -+ if (nla_parse_nested(attr, GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_FLUSH, -+ (struct nlattr *)(data - NLA_HDRLEN), nla_parse_policy,NULL) < 0) -+ goto nla_put_failure; -+ len_basic = 0; -+ for (k = GSCAN_ATTRIBUTE_RSSI_SAMPLE_SIZE; k <= GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_FLUSH; k++) { -+ if (attr[k]) { -+ switch (k) { -+ case GSCAN_ATTRIBUTE_RSSI_SAMPLE_SIZE: -+ prWifiChangeCmd->rssi_sample_size = nla_get_u16(attr[k]); -+ len_basic += NLA_ALIGN(attr[k]->nla_len); -+ break; -+ case GSCAN_ATTRIBUTE_LOST_AP_SAMPLE_SIZE: -+ prWifiChangeCmd->lost_ap_sample_size = nla_get_u16(attr[k]); -+ len_basic += NLA_ALIGN(attr[k]->nla_len); -+ break; -+ case GSCAN_ATTRIBUTE_MIN_BREACHING: -+ prWifiChangeCmd->min_breaching = nla_get_u16(attr[k]); -+ len_basic += NLA_ALIGN(attr[k]->nla_len); -+ break; -+ case GSCAN_ATTRIBUTE_NUM_AP: -+ prWifiChangeCmd->num_ap = nla_get_u16(attr[k]); -+ len_basic += NLA_ALIGN(attr[k]->nla_len); -+ DBGLOG(REQ, TRACE, "attr=0x%x, num_ap=%d nla_len=%d, \r\n", -+ *(UINT_32 *) attr[k], prWifiChangeCmd->num_ap, attr[k]->nla_len); -+ break; -+ case GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_FLUSH: -+ flush = nla_get_u8(attr[k]); -+ len_basic += NLA_ALIGN(attr[k]->nla_len); -+ break; -+ } -+ } -+ } -+ paplist = (struct nlattr *)((UINT_8 *) data + len_basic); -+ DBGLOG(REQ, TRACE, "+++basic attribute size=%d flush=%d\r\n", len_basic, flush); -+ -+ if (paplist->nla_type == GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_BSSIDS) -+ paplist = (struct nlattr *)((UINT_8 *) paplist + NLA_HDRLEN); -+ -+ for (i = 0; i < prWifiChangeCmd->num_ap; i++) { -+ if (nla_parse_nested(attr, GSCAN_ATTRIBUTE_RSSI_HIGH, (struct nlattr *)paplist, nla_parse_policy,NULL) < 0) -+ goto nla_put_failure; -+ paplist = (struct nlattr *)((UINT_8 *) paplist + NLA_HDRLEN); -+ /* request.attr_start(i) as nested attribute */ -+ len_aplist = 0; -+ for (k = GSCAN_ATTRIBUTE_BSSID; k <= GSCAN_ATTRIBUTE_RSSI_HIGH; k++) { -+ if (attr[k]) { -+ switch (k) { -+ case GSCAN_ATTRIBUTE_BSSID: -+ kalMemCopy(prWifiChangeCmd->ap[i].bssid, nla_data(attr[k]), sizeof(mac_addr)); -+ len_aplist += NLA_ALIGN(attr[k]->nla_len); -+ break; -+ case GSCAN_ATTRIBUTE_RSSI_LOW: -+ prWifiChangeCmd->ap[i].low = nla_get_u32(attr[k]); -+ len_aplist += NLA_ALIGN(attr[k]->nla_len); -+ break; -+ case GSCAN_ATTRIBUTE_RSSI_HIGH: -+ prWifiChangeCmd->ap[i].high = nla_get_u32(attr[k]); -+ len_aplist += NLA_ALIGN(attr[k]->nla_len); -+ break; -+ } -+ } -+ } -+ if (((i + 1) % 4 == 0) || (i == prWifiChangeCmd->num_ap - 1)) -+ DBGLOG(REQ, TRACE, "ap[%d], len_aplist=%d\n", i, len_aplist); -+ else -+ DBGLOG(REQ, TRACE, "ap[%d], len_aplist=%d \t", i, len_aplist); -+ paplist = (struct nlattr *)((UINT_8 *) paplist + len_aplist); -+ } -+ -+ DBGLOG(REQ, TRACE, -+ "flush=%d, rssi_sample_size=%d lost_ap_sample_size=%d min_breaching=%d", -+ flush, prWifiChangeCmd->rssi_sample_size, prWifiChangeCmd->lost_ap_sample_size, -+ prWifiChangeCmd->min_breaching); -+ DBGLOG(REQ, TRACE, -+ "ap[0].channel=%d low=%d high=%d, ap[1].channel=%d low=%d high=%d", -+ prWifiChangeCmd->ap[0].channel, prWifiChangeCmd->ap[0].low, prWifiChangeCmd->ap[0].high, -+ prWifiChangeCmd->ap[1].channel, prWifiChangeCmd->ap[1].low, prWifiChangeCmd->ap[1].high); -+ kalMemFree(prWifiChangeCmd, VIR_MEM_TYPE, sizeof(PARAM_WIFI_SIGNIFICANT_CHANGE)); -+ kalMemFree(attr, VIR_MEM_TYPE, sizeof(struct nlattr *) * (GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_FLUSH + 1)); -+ return 0; -+ -+nla_put_failure: -+ if (prWifiChangeCmd) -+ kalMemFree(prWifiChangeCmd, VIR_MEM_TYPE, sizeof(PARAM_WIFI_SIGNIFICANT_CHANGE)); -+ if (attr) -+ kalMemFree(attr, VIR_MEM_TYPE, -+ sizeof(struct nlattr *) * (GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_FLUSH + 1)); -+ return i4Status; -+} -+ -+int mtk_cfg80211_vendor_set_hotlist(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int data_len) -+{ -+ /*WLAN_STATUS rStatus;*/ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ CMD_SET_PSCAN_ADD_HOTLIST_BSSID rCmdPscnAddHotlist; -+ -+ INT_32 i4Status = -EINVAL; -+ P_PARAM_WIFI_BSSID_HOTLIST prWifiHotlistCmd = NULL; -+ UINT_8 flush = 0; -+ /* struct nlattr *attr[GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_FLUSH + 1]; */ -+ struct nlattr **attr = NULL; -+ struct nlattr *paplist; -+ int i, k; -+ UINT_32 len_basic, len_aplist; -+ -+ ASSERT(wiphy); -+ ASSERT(wdev); -+ if ((data == NULL) || !data_len) -+ goto nla_put_failure; -+ DBGLOG(REQ, INFO, "%s for vendor command: data_len=%d \r\n", __func__, data_len); -+ for (i = 0; i < 5; i++) -+ DBGLOG(REQ, LOUD, "0x%x 0x%x 0x%x 0x%x \r\n", -+ *((UINT_32 *) data + i * 4), *((UINT_32 *) data + i * 4 + 1), -+ *((UINT_32 *) data + i * 4 + 2), *((UINT_32 *) data + i * 4 + 3)); -+ prWifiHotlistCmd = kalMemAlloc(sizeof(PARAM_WIFI_BSSID_HOTLIST), VIR_MEM_TYPE); -+ if (prWifiHotlistCmd == NULL) -+ goto nla_put_failure; -+ kalMemZero(prWifiHotlistCmd, sizeof(PARAM_WIFI_BSSID_HOTLIST)); -+ attr = kalMemAlloc(sizeof(struct nlattr *) * (GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_FLUSH + 1), VIR_MEM_TYPE); -+ if (attr == NULL) -+ goto nla_put_failure; -+ kalMemZero(attr, sizeof(struct nlattr *) * (GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_FLUSH + 1)); -+ -+ if (nla_parse_nested(attr, GSCAN_ATTRIBUTE_NUM_AP, (struct nlattr *)(data - NLA_HDRLEN), nla_parse_policy,NULL) < 0) -+ goto nla_put_failure; -+ len_basic = 0; -+ for (k = GSCAN_ATTRIBUTE_HOTLIST_FLUSH; k <= GSCAN_ATTRIBUTE_NUM_AP; k++) { -+ if (attr[k]) { -+ switch (k) { -+ case GSCAN_ATTRIBUTE_LOST_AP_SAMPLE_SIZE: -+ prWifiHotlistCmd->lost_ap_sample_size = nla_get_u32(attr[k]); -+ len_basic += NLA_ALIGN(attr[k]->nla_len); -+ break; -+ case GSCAN_ATTRIBUTE_NUM_AP: -+ prWifiHotlistCmd->num_ap = nla_get_u16(attr[k]); -+ len_basic += NLA_ALIGN(attr[k]->nla_len); -+ DBGLOG(REQ, TRACE, "attr=0x%x, num_ap=%d nla_len=%d, \r\n", -+ *(UINT_32 *) attr[k], prWifiHotlistCmd->num_ap, attr[k]->nla_len); -+ break; -+ case GSCAN_ATTRIBUTE_HOTLIST_FLUSH: -+ flush = nla_get_u8(attr[k]); -+ len_basic += NLA_ALIGN(attr[k]->nla_len); -+ break; -+ } -+ } -+ } -+ paplist = (struct nlattr *)((UINT_8 *) data + len_basic); -+ DBGLOG(REQ, TRACE, "+++basic attribute size=%d flush=%d\r\n", len_basic, flush); -+ -+ if (paplist->nla_type == GSCAN_ATTRIBUTE_HOTLIST_BSSIDS) -+ paplist = (struct nlattr *)((UINT_8 *) paplist + NLA_HDRLEN); -+ -+ for (i = 0; i < prWifiHotlistCmd->num_ap; i++) { -+ if (nla_parse_nested(attr, GSCAN_ATTRIBUTE_RSSI_HIGH, (struct nlattr *)paplist, nla_parse_policy,NULL) < 0) -+ goto nla_put_failure; -+ paplist = (struct nlattr *)((UINT_8 *) paplist + NLA_HDRLEN); -+ /* request.attr_start(i) as nested attribute */ -+ len_aplist = 0; -+ for (k = GSCAN_ATTRIBUTE_BSSID; k <= GSCAN_ATTRIBUTE_RSSI_HIGH; k++) { -+ if (attr[k]) { -+ switch (k) { -+ case GSCAN_ATTRIBUTE_BSSID: -+ kalMemCopy(prWifiHotlistCmd->ap[i].bssid, nla_data(attr[k]), sizeof(mac_addr)); -+ len_aplist += NLA_ALIGN(attr[k]->nla_len); -+ break; -+ case GSCAN_ATTRIBUTE_RSSI_LOW: -+ prWifiHotlistCmd->ap[i].low = nla_get_u32(attr[k]); -+ len_aplist += NLA_ALIGN(attr[k]->nla_len); -+ break; -+ case GSCAN_ATTRIBUTE_RSSI_HIGH: -+ prWifiHotlistCmd->ap[i].high = nla_get_u32(attr[k]); -+ len_aplist += NLA_ALIGN(attr[k]->nla_len); -+ break; -+ } -+ } -+ } -+ if (((i + 1) % 4 == 0) || (i == prWifiHotlistCmd->num_ap - 1)) -+ DBGLOG(REQ, TRACE, "ap[%d], len_aplist=%d\n", i, len_aplist); -+ else -+ DBGLOG(REQ, TRACE, "ap[%d], len_aplist=%d \t", i, len_aplist); -+ paplist = (struct nlattr *)((UINT_8 *) paplist + len_aplist); -+ } -+ -+ DBGLOG(REQ, TRACE, -+ "flush=%d, lost_ap_sample_size=%d, Hotlist:ap[0].channel=%d low=%d high=%d, ap[1].channel=%d low=%d high=%d", -+ flush, prWifiHotlistCmd->lost_ap_sample_size, -+ prWifiHotlistCmd->ap[0].channel, prWifiHotlistCmd->ap[0].low, prWifiHotlistCmd->ap[0].high, -+ prWifiHotlistCmd->ap[1].channel, prWifiHotlistCmd->ap[1].low, prWifiHotlistCmd->ap[1].high); -+ -+ memcpy(&(rCmdPscnAddHotlist.aucMacAddr), &(prWifiHotlistCmd->ap[0].bssid), 6 * sizeof(UINT_8)); -+ rCmdPscnAddHotlist.ucFlags = (UINT_8) TRUE; -+ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); -+ ASSERT(prGlueInfo); -+ -+ kalMemFree(prWifiHotlistCmd, VIR_MEM_TYPE, sizeof(PARAM_WIFI_BSSID_HOTLIST)); -+ kalMemFree(attr, VIR_MEM_TYPE, sizeof(struct nlattr *) * (GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_FLUSH + 1)); -+ return 0; -+ -+nla_put_failure: -+ if (prWifiHotlistCmd) -+ kalMemFree(prWifiHotlistCmd, VIR_MEM_TYPE, sizeof(PARAM_WIFI_BSSID_HOTLIST)); -+ if (attr) -+ kalMemFree(attr, VIR_MEM_TYPE, -+ sizeof(struct nlattr *) * (GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_FLUSH + 1)); -+ return i4Status; -+} -+ -+int mtk_cfg80211_vendor_enable_scan(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int data_len) -+{ -+ WLAN_STATUS rStatus; -+ UINT_32 u4BufLen; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ PARAM_WIFI_GSCAN_ACTION_CMD_PARAMS rWifiScanActionCmd; -+ -+ INT_32 i4Status = -EINVAL; -+ struct nlattr *attr; -+ UINT_8 gGScanEn = 0; -+ -+ static UINT_8 k; /* only for test */ -+ -+ ASSERT(wiphy); -+ ASSERT(wdev); -+ if ((data == NULL) || !data_len) -+ goto nla_put_failure; -+ DBGLOG(REQ, INFO, "%s for vendor command: data_len=%d, data=0x%x 0x%x\r\n", -+ __func__, data_len, *((UINT_32 *) data), *((UINT_32 *) data + 1)); -+ -+ attr = (struct nlattr *)data; -+ if (attr->nla_type == GSCAN_ATTRIBUTE_ENABLE_FEATURE) -+ gGScanEn = nla_get_u32(attr); -+ DBGLOG(REQ, INFO, "gGScanEn=%d, \r\n", gGScanEn); -+ -+ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); -+ ASSERT(prGlueInfo); -+ if (gGScanEn == TRUE) -+ rWifiScanActionCmd.ucPscanAct = ENABLE; -+ else -+ rWifiScanActionCmd.ucPscanAct = DISABLE; -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetGSCNAction, -+ &rWifiScanActionCmd, -+ sizeof(PARAM_WIFI_GSCAN_ACTION_CMD_PARAMS), FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ -+ /* mtk_cfg80211_vendor_get_scan_results(wiphy, wdev, data, data_len ); */ -+ -+ return 0; -+ -+ /* only for test */ -+ if (k % 3 == 1) { -+ mtk_cfg80211_vendor_event_significant_change_results(wiphy, wdev, NULL, 0); -+ mtk_cfg80211_vendor_event_hotlist_ap_found(wiphy, wdev, NULL, 0); -+ mtk_cfg80211_vendor_event_hotlist_ap_lost(wiphy, wdev, NULL, 0); -+ } -+ k++; -+ -+ return 0; -+ -+nla_put_failure: -+ return i4Status; -+} -+ -+int mtk_cfg80211_vendor_enable_full_scan_results(struct wiphy *wiphy, struct wireless_dev *wdev, -+ const void *data, int data_len) -+{ -+ INT_32 i4Status = -EINVAL; -+ struct nlattr *attr; -+ UINT_8 gFullScanResultsEn = 0; -+ -+ ASSERT(wiphy); -+ ASSERT(wdev); -+ if ((data == NULL) || !data_len) -+ goto nla_put_failure; -+ DBGLOG(REQ, INFO, "%s for vendor command: data_len=%d, data=0x%x 0x%x\r\n", -+ __func__, data_len, *((UINT_32 *) data), *((UINT_32 *) data + 1)); -+ -+ attr = (struct nlattr *)data; -+ if (attr->nla_type == GSCAN_ENABLE_FULL_SCAN_RESULTS) -+ gFullScanResultsEn = nla_get_u32(attr); -+ DBGLOG(REQ, INFO, "gFullScanResultsEn=%d, \r\n", gFullScanResultsEn); -+ -+ return 0; -+ -+ /* only for test */ -+ mtk_cfg80211_vendor_event_complete_scan(wiphy, wdev, WIFI_SCAN_COMPLETE); -+ mtk_cfg80211_vendor_event_scan_results_available(wiphy, wdev, 4); -+ if (gFullScanResultsEn == TRUE) -+ mtk_cfg80211_vendor_event_full_scan_results(wiphy, wdev, NULL, 0); -+ -+ return 0; -+ -+nla_put_failure: -+ return i4Status; -+} -+ -+int mtk_cfg80211_vendor_get_scan_results(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int data_len) -+{ -+ /*WLAN_STATUS rStatus;*/ -+ UINT_32 u4BufLen; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ PARAM_WIFI_GSCAN_GET_RESULT_PARAMS rGSscnResultParm; -+ -+ INT_32 i4Status = -EINVAL; -+ struct nlattr *attr; -+ UINT_32 get_num = 0, real_num = 0; -+ UINT_8 flush = 0; -+ /*PARAM_WIFI_GSCAN_RESULT result[4], *pResult; -+ struct sk_buff *skb;*/ -+ int i; /*int j;*/ -+ /*UINT_32 scan_id;*/ -+ -+ ASSERT(wiphy); -+ ASSERT(wdev); -+ if ((data == NULL) || !data_len) -+ goto nla_put_failure; -+ DBGLOG(REQ, TRACE, "%s for vendor command: data_len=%d \r\n", __func__, data_len); -+ for (i = 0; i < 2; i++) -+ DBGLOG(REQ, LOUD, "0x%x 0x%x 0x%x 0x%x \r\n", *((UINT_32 *) data + i * 4), -+ *((UINT_32 *) data + i * 4 + 1), *((UINT_32 *) data + i * 4 + 2), -+ *((UINT_32 *) data + i * 4 + 3)); -+ -+ attr = (struct nlattr *)data; -+ if (attr->nla_type == GSCAN_ATTRIBUTE_NUM_OF_RESULTS) { -+ get_num = nla_get_u32(attr); -+ attr = (struct nlattr *)((UINT_8 *) attr + attr->nla_len); -+ } -+ if (attr->nla_type == GSCAN_ATTRIBUTE_FLUSH_RESULTS) { -+ flush = nla_get_u8(attr); -+ attr = (struct nlattr *)((UINT_8 *) attr + attr->nla_len); -+ } -+ DBGLOG(REQ, TRACE, "number=%d, flush=%d \r\n", get_num, flush); -+ -+ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); -+ ASSERT(prGlueInfo); -+ -+ real_num = (get_num < PSCAN_MAX_SCAN_CACHE_SIZE) ? get_num : PSCAN_MAX_SCAN_CACHE_SIZE; -+ get_num = real_num; -+ -+#if 0 /* driver buffer FW results and reports by buffer workaround for FW mismatch with hal results numbers */ -+ g_GetResultsCmdCnt++; -+ DBGLOG(REQ, INFO, -+ "(g_GetResultsCmdCnt [%d], g_GetResultsBufferedCnt [%d]\n", g_GetResultsCmdCnt, -+ g_GetResultsBufferedCnt); -+ -+ BOOLEAN fgIsGetResultFromBuffer = FALSE; -+ UINT_8 BufferedResultReportIndex = 0; -+ -+ if (g_GetResultsBufferedCnt > 0) { -+ -+ DBGLOG(REQ, INFO, -+ "(g_GetResultsBufferedCnt > 0), report buffered results instead of ask from FW\n"); -+ -+ /* reply the results to wifi_hal */ -+ for (i = 0; i < MAX_BUFFERED_GSCN_RESULTS; i++) { -+ -+ if (g_arGscanResultsIndicateNumber[i] > 0) { -+ real_num = g_arGscanResultsIndicateNumber[i]; -+ get_num = real_num; -+ g_arGscanResultsIndicateNumber[i] = 0; -+ fgIsGetResultFromBuffer = TRUE; -+ BufferedResultReportIndex = i; -+ break; -+ } -+ } -+ if (i == MAX_BUFFERED_GSCN_RESULTS) -+ DBGLOG(REQ, TRACE, "all buffered results are invalid, unexpected case \r\n"); -+ DBGLOG(REQ, TRACE, "BufferedResultReportIndex[%d] i = %d real_num[%d] get_num[%d] \r\n", -+ BufferedResultReportIndex, i, real_num, get_num); -+ } -+#endif -+ -+ rGSscnResultParm.get_num = get_num; -+ rGSscnResultParm.flush = flush; -+#if 0/* //driver buffer FW results and reports by buffer workaround for FW results mismatch with hal results number */ -+ if (fgIsGetResultFromBuffer) { -+ nicRxProcessGSCNEvent(prGlueInfo->prAdapter, g_arGscnResultsTempBuffer[BufferedResultReportIndex]); -+ g_GetResultsBufferedCnt--; -+ g_GetResultsCmdCnt--; -+ nicRxReturnRFB(prGlueInfo->prAdapter, g_arGscnResultsTempBuffer[BufferedResultReportIndex]); -+ } else -+#endif -+ { -+ kalIoctl(prGlueInfo, -+ wlanoidGetGSCNResult, -+ &rGSscnResultParm, -+ sizeof(PARAM_WIFI_GSCAN_GET_RESULT_PARAMS), FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ } -+ return 0; -+ -+nla_put_failure: -+ return i4Status; -+} -+ -+int mtk_cfg80211_vendor_get_rtt_capabilities(struct wiphy *wiphy, -+ struct wireless_dev *wdev, const void *data, int data_len) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ INT_32 i4Status = -EINVAL; -+ PARAM_WIFI_RTT_CAPABILITIES rRttCapabilities; -+ struct sk_buff *skb; -+ -+ DBGLOG(REQ, TRACE, "%s for vendor command \r\n", __func__); -+ -+ ASSERT(wiphy); -+ ASSERT(wdev); -+ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); -+ -+ skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(rRttCapabilities)); -+ if (!skb) { -+ DBGLOG(REQ, ERROR, "%s allocate skb failed:%x\n", __func__, i4Status); -+ return -ENOMEM; -+ } -+ -+ kalMemZero(&rRttCapabilities, sizeof(rRttCapabilities)); -+ -+ /*rStatus = kalIoctl(prGlueInfo, -+ wlanoidQueryStatistics, -+ &rRttCapabilities, -+ sizeof(rRttCapabilities), -+ TRUE, -+ TRUE, -+ TRUE, -+ FALSE, -+ &u4BufLen); */ -+ rRttCapabilities.rtt_one_sided_supported = 0; -+ rRttCapabilities.rtt_ftm_supported = 0; -+ rRttCapabilities.lci_support = 0; -+ rRttCapabilities.lcr_support = 0; -+ rRttCapabilities.preamble_support = 0; -+ rRttCapabilities.bw_support = 0; -+ -+ if (unlikely(nla_put(skb, RTT_ATTRIBUTE_CAPABILITIES, -+ sizeof(rRttCapabilities), &rRttCapabilities) < 0)) -+ goto nla_put_failure; -+ -+ i4Status = cfg80211_vendor_cmd_reply(skb); -+ return i4Status; -+ -+nla_put_failure: -+ kfree_skb(skb); -+ return i4Status; -+} -+ -+int mtk_cfg80211_vendor_llstats_get_info(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int data_len) -+{ -+ INT_32 i4Status = -EINVAL; -+ WIFI_RADIO_STAT *pRadioStat; -+ struct sk_buff *skb; -+ UINT_32 u4BufLen; -+ -+ ASSERT(wiphy); -+ ASSERT(wdev); -+ -+ u4BufLen = sizeof(WIFI_RADIO_STAT) + sizeof(WIFI_IFACE_STAT); -+ pRadioStat = kalMemAlloc(u4BufLen, VIR_MEM_TYPE); -+ if (!pRadioStat) { -+ DBGLOG(REQ, ERROR, "%s kalMemAlloc pRadioStat failed\n", __func__); -+ return -ENOMEM; -+ } -+ kalMemZero(pRadioStat, u4BufLen); -+ -+ skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, u4BufLen); -+ if (!skb) { -+ DBGLOG(REQ, TRACE, "%s allocate skb failed:%x\n", __func__, i4Status); -+ return -ENOMEM; -+ } -+ -+ /*rStatus = kalIoctl(prGlueInfo, -+ wlanoidQueryStatistics, -+ &rRadioStat, -+ sizeof(rRadioStat), -+ TRUE, -+ TRUE, -+ TRUE, -+ FALSE, -+ &u4BufLen); */ -+ /* only for test */ -+ pRadioStat->radio = 10; -+ pRadioStat->on_time = 11; -+ pRadioStat->tx_time = 12; -+ pRadioStat->num_channels = 4; -+ -+ /*NLA_PUT(skb, LSTATS_ATTRIBUTE_STATS, u4BufLen, pRadioStat);*/ -+ if (unlikely(nla_put(skb, LSTATS_ATTRIBUTE_STATS, u4BufLen, pRadioStat) < 0)) -+ goto nla_put_failure; -+ -+ i4Status = cfg80211_vendor_cmd_reply(skb); -+ kalMemFree(pRadioStat, VIR_MEM_TYPE, u4BufLen); -+ return -1; /* not support LLS now*/ -+ /* return i4Status; */ -+ -+nla_put_failure: -+ kfree_skb(skb); -+ return i4Status; -+} -+ -+int mtk_cfg80211_vendor_event_complete_scan(struct wiphy *wiphy, struct wireless_dev *wdev, WIFI_SCAN_EVENT complete) -+{ -+ struct sk_buff *skb; -+ -+ ASSERT(wiphy); -+ ASSERT(wdev); -+ /* WIFI_SCAN_EVENT complete_scan; */ -+ -+ DBGLOG(REQ, INFO, "%s for vendor command \r\n", __func__); -+ -+ skb = cfg80211_vendor_event_alloc(wiphy, wdev, sizeof(complete), GSCAN_EVENT_COMPLETE_SCAN, GFP_KERNEL); -+ if (!skb) { -+ DBGLOG(REQ, ERROR, "%s allocate skb failed\n", __func__); -+ return -ENOMEM; -+ } -+ /* complete_scan = WIFI_SCAN_COMPLETE; */ -+ /*NLA_PUT_U32(skb, GSCAN_EVENT_COMPLETE_SCAN, complete);*/ -+ { -+ unsigned int __tmp = complete; -+ -+ if (unlikely(nla_put(skb, GSCAN_EVENT_COMPLETE_SCAN, -+ sizeof(unsigned int), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ -+ cfg80211_vendor_event(skb, GFP_KERNEL); -+ return 0; -+ -+nla_put_failure: -+ kfree_skb(skb); -+ return -1; -+} -+ -+int mtk_cfg80211_vendor_event_scan_results_available(struct wiphy *wiphy, struct wireless_dev *wdev, UINT_32 num) -+{ -+ struct sk_buff *skb; -+ -+ ASSERT(wiphy); -+ ASSERT(wdev); -+ /* UINT_32 scan_result; */ -+ -+ DBGLOG(REQ, INFO, "%s for vendor command %d \r\n", __func__, num); -+ -+ skb = cfg80211_vendor_event_alloc(wiphy, wdev, sizeof(num), GSCAN_EVENT_SCAN_RESULTS_AVAILABLE, GFP_KERNEL); -+ if (!skb) { -+ DBGLOG(REQ, ERROR, "%s allocate skb failed\n", __func__); -+ return -ENOMEM; -+ } -+ /* scan_result = 2; */ -+ /*NLA_PUT_U32(skb, GSCAN_EVENT_SCAN_RESULTS_AVAILABLE, num);*/ -+ { -+ unsigned int __tmp = num; -+ -+ if (unlikely(nla_put(skb, GSCAN_EVENT_SCAN_RESULTS_AVAILABLE, -+ sizeof(unsigned int), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ -+ cfg80211_vendor_event(skb, GFP_KERNEL); -+ return 0; -+ -+nla_put_failure: -+ kfree_skb(skb); -+ return -1; -+} -+ -+int mtk_cfg80211_vendor_event_full_scan_results(struct wiphy *wiphy, struct wireless_dev *wdev, -+ P_PARAM_WIFI_GSCAN_RESULT pdata, UINT_32 data_len) -+{ -+ struct sk_buff *skb; -+ PARAM_WIFI_GSCAN_RESULT result; -+ -+ ASSERT(wiphy); -+ ASSERT(wdev); -+ DBGLOG(REQ, INFO, "%s for vendor command \r\n", __func__); -+ -+ skb = cfg80211_vendor_event_alloc(wiphy, wdev, sizeof(result), GSCAN_EVENT_FULL_SCAN_RESULTS, GFP_KERNEL); -+ if (!skb) { -+ DBGLOG(REQ, ERROR, "%s allocate skb failed\n", __func__); -+ return -ENOMEM; -+ } -+ -+ kalMemZero(&result, sizeof(result)); -+ kalMemCopy(result.ssid, "Gscan_full_test", sizeof("Gscan_full_test")); -+ result.channel = 2437; -+ -+ /* kalMemCopy(&result, pdata, sizeof(PARAM_WIFI_GSCAN_RESULT); */ -+ /*NLA_PUT(skb, GSCAN_EVENT_FULL_SCAN_RESULTS, sizeof(result), &result);*/ -+ if (unlikely(nla_put(skb, GSCAN_EVENT_FULL_SCAN_RESULTS, -+ sizeof(result), &result) < 0)) -+ goto nla_put_failure; -+ -+ cfg80211_vendor_event(skb, GFP_KERNEL); -+ return 0; -+ -+nla_put_failure: -+ kfree_skb(skb); -+ return -1; -+} -+ -+int mtk_cfg80211_vendor_event_significant_change_results(struct wiphy *wiphy, struct wireless_dev *wdev, -+ P_PARAM_WIFI_CHANGE_RESULT pdata, UINT_32 data_len) -+{ -+ struct sk_buff *skb; -+ PARAM_WIFI_CHANGE_RESULT result[2], *presult; -+ -+ ASSERT(wiphy); -+ ASSERT(wdev); -+ DBGLOG(REQ, INFO, "%s for vendor command \r\n", __func__); -+ -+ skb = cfg80211_vendor_event_alloc(wiphy, wdev, sizeof(PARAM_WIFI_CHANGE_RESULT), -+ GSCAN_EVENT_SIGNIFICANT_CHANGE_RESULTS, GFP_KERNEL); -+ if (!skb) { -+ DBGLOG(REQ, ERROR, "%s allocate skb failed\n", __func__); -+ return -ENOMEM; -+ } -+ -+ presult = result; -+ kalMemZero(presult, (sizeof(PARAM_WIFI_CHANGE_RESULT) * 2)); -+ /* only for test */ -+ kalMemCopy(presult->bssid, "213123", sizeof(mac_addr)); -+ presult->channel = 2437; -+ presult->rssi[0] = -45; -+ presult->rssi[1] = -46; -+ presult++; -+ presult->channel = 2439; -+ presult->rssi[0] = -47; -+ presult->rssi[1] = -48; -+ /*NLA_PUT(skb, GSCAN_EVENT_SIGNIFICANT_CHANGE_RESULTS, (sizeof(PARAM_WIFI_CHANGE_RESULT) * 2), result);*/ -+ if (unlikely(nla_put(skb, GSCAN_EVENT_SIGNIFICANT_CHANGE_RESULTS, -+ (sizeof(PARAM_WIFI_CHANGE_RESULT) * 2), result) < 0)) -+ goto nla_put_failure; -+ -+ cfg80211_vendor_event(skb, GFP_KERNEL); -+ return 0; -+ -+nla_put_failure: -+ kfree_skb(skb); -+ return -1; -+} -+ -+int mtk_cfg80211_vendor_event_hotlist_ap_found(struct wiphy *wiphy, struct wireless_dev *wdev, -+ P_PARAM_WIFI_GSCAN_RESULT pdata, UINT_32 data_len) -+{ -+ struct sk_buff *skb; -+ PARAM_WIFI_GSCAN_RESULT result[2], *presult; -+ -+ ASSERT(wiphy); -+ ASSERT(wdev); -+ DBGLOG(REQ, INFO, "%s for vendor command \r\n", __func__); -+ -+ skb = cfg80211_vendor_event_alloc(wiphy, wdev, sizeof(PARAM_WIFI_GSCAN_RESULT), -+ GSCAN_EVENT_HOTLIST_RESULTS_FOUND, GFP_KERNEL); -+ if (!skb) { -+ DBGLOG(REQ, ERROR, "%s allocate skb failed\n", __func__); -+ return -ENOMEM; -+ } -+ -+ presult = result; -+ kalMemZero(presult, (sizeof(PARAM_WIFI_GSCAN_RESULT) * 2)); -+ /* only for test */ -+ kalMemCopy(presult->bssid, "123123", sizeof(mac_addr)); -+ presult->channel = 2441; -+ presult->rssi = -45; -+ presult++; -+ presult->channel = 2443; -+ presult->rssi = -47; -+ /*NLA_PUT(skb, GSCAN_EVENT_HOTLIST_RESULTS_FOUND, (sizeof(PARAM_WIFI_GSCAN_RESULT) * 2), result);*/ -+ if (unlikely(nla_put(skb, GSCAN_EVENT_HOTLIST_RESULTS_FOUND, -+ (sizeof(PARAM_WIFI_GSCAN_RESULT) * 2), result) < 0)) -+ goto nla_put_failure; -+ -+ cfg80211_vendor_event(skb, GFP_KERNEL); -+ return 0; -+ -+nla_put_failure: -+ kfree_skb(skb); -+ return -1; -+} -+ -+int mtk_cfg80211_vendor_event_hotlist_ap_lost(struct wiphy *wiphy, struct wireless_dev *wdev, -+ P_PARAM_WIFI_GSCAN_RESULT pdata, UINT_32 data_len) -+{ -+ struct sk_buff *skb; -+ PARAM_WIFI_GSCAN_RESULT result[2], *presult; -+ -+ ASSERT(wiphy); -+ ASSERT(wdev); -+ DBGLOG(REQ, INFO, "%s for vendor command \r\n", __func__); -+ -+ skb = cfg80211_vendor_event_alloc(wiphy, wdev, sizeof(PARAM_WIFI_GSCAN_RESULT), -+ GSCAN_EVENT_HOTLIST_RESULTS_LOST, GFP_KERNEL); -+ if (!skb) { -+ DBGLOG(REQ, ERROR, "%s allocate skb failed\n", __func__); -+ return -ENOMEM; -+ } -+ -+ presult = result; -+ kalMemZero(presult, (sizeof(PARAM_WIFI_GSCAN_RESULT) * 2)); -+ /* only for test */ -+ kalMemCopy(presult->bssid, "321321", sizeof(mac_addr)); -+ presult->channel = 2445; -+ presult->rssi = -46; -+ presult++; -+ presult->channel = 2447; -+ presult->rssi = -48; -+ /*NLA_PUT(skb, GSCAN_EVENT_HOTLIST_RESULTS_LOST, (sizeof(PARAM_WIFI_GSCAN_RESULT) * 2), result);*/ -+ if (unlikely(nla_put(skb, GSCAN_EVENT_HOTLIST_RESULTS_LOST, -+ (sizeof(PARAM_WIFI_GSCAN_RESULT) * 2), result) < 0)) -+ goto nla_put_failure; -+ -+ cfg80211_vendor_event(skb, GFP_KERNEL); -+ return 0; -+ -+nla_put_failure: -+ kfree_skb(skb); -+ return -1; -+} -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_wext.c b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_wext.c -new file mode 100644 -index 000000000000..1793742e9802 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_wext.c -@@ -0,0 +1,4158 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux/gl_wext.c#3 -+*/ -+ -+/*! \file gl_wext.c -+ \brief ioctl() (mostly Linux Wireless Extensions) routines for STA driver. -+*/ -+ -+/* -+** Log: gl_wext.c -+ * -+ * 06 13 2012 yuche.tsai -+ * NULL -+ * Update maintrunk driver. -+ * Add support for driver compose assoc request frame. -+ * -+ * 01 16 2012 wh.su -+ * [WCXRP00001170] [MT6620 Wi-Fi][Driver] Adding the related code for set/get band ioctl -+ * Adding the template code for set / get band IOCTL (with ICS supplicant_6).. -+ * -+ * 01 05 2012 wh.su -+ * [WCXRP00001153] [MT6620 Wi-Fi][Driver] Adding the get_ch_list and set_tx_power proto type function -+ * Adding the related ioctl / wlan oid function to set the Tx power cfg. -+ * -+ * 01 02 2012 wh.su -+ * [WCXRP00001153] [MT6620 Wi-Fi][Driver] Adding the get_ch_list and set_tx_power proto type function -+ * Adding the proto type function for set_int set_tx_power and get int get_ch_list. -+ * -+ * 11 10 2011 cp.wu -+ * [WCXRP00001098] [MT6620 Wi-Fi][Driver] Replace printk by DBG LOG macros in linux porting layer -+ * 1. eliminaite direct calls to printk in porting layer. -+ * 2. replaced by DBGLOG, which would be XLOG on ALPS platforms. -+ * -+ * 10 12 2011 wh.su -+ * [WCXRP00001036] [MT6620 Wi-Fi][Driver][FW] Adding the 802.11w code for MFP -+ * adding the 802.11w related function and define . -+ * -+ * 09 23 2011 tsaiyuan.hsu -+ * [WCXRP00000979] [MT6620 Wi-Fi][DRV]] stop attempting to connect to config AP after D3 state -+ * avoid entering D3 state after deep sleep. -+ * -+ * 07 28 2011 chinghwa.yu -+ * [WCXRP00000063] Update BCM CoEx design and settings -+ * Add BWCS cmd and event. -+ * -+ * 07 27 2011 wh.su -+ * [WCXRP00000877] [MT6620 Wi-Fi][Driver] Remove the netif_carry_ok check for avoid the wpa_supplicant fail to query -+ * the ap address -+ * Remove the netif check while query bssid and ssid -+ * -+ * 07 26 2011 chinglan.wang -+ * NULL -+ * [MT6620][WiFi Driver] Do not include the WSC IE in the association info packet when not do the wps connection.. -+ * -+ * 07 18 2011 chinghwa.yu -+ * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm -+ * Add CMD/Event for RDD and BWCS. -+ * -+ * 05 17 2011 eddie.chen -+ * [WCXRP00000603] [MT6620 Wi-Fi][DRV] Fix Klocwork warning -+ * Initialize the vairlabes. -+ * -+ * 05 11 2011 jeffrey.chang -+ * [WCXRP00000718] [MT6620 Wi-Fi] modify the behavior of setting tx power -+ * modify set_tx_pow ioctl -+ * -+ * 03 29 2011 terry.wu -+ * [WCXRP00000610] [MT 6620 Wi-Fi][Driver] Fix klocwork waring -+ * [MT6620 Wi-Fi][Driver] Fix klocwork warning. Add Null pointer check on wext_get_essid. Limit the upper bound of -+ * essid storage array. -+ * -+ * 03 21 2011 cp.wu -+ * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer -+ * improve portability for awareness of early version of linux kernel and wireless extension. -+ * -+ * 03 17 2011 chinglan.wang -+ * [WCXRP00000570] [MT6620 Wi-Fi][Driver] Add Wi-Fi Protected Setup v2.0 feature -+ * . -+ * -+ * 03 07 2011 terry.wu -+ * [WCXRP00000521] [MT6620 Wi-Fi][Driver] Remove non-standard debug message -+ * Toggle non-standard debug messages to comments. -+ * -+ * 02 21 2011 wh.su -+ * [WCXRP00000483] [MT6620 Wi-Fi][Driver] Check the kalIoctl return value before doing the memory copy at linux get -+ * essid -+ * fixed the potential error to do a larget memory copy while wlanoid get essid not actually running. -+ * -+ * 02 08 2011 george.huang -+ * [WCXRP00000422] [MT6620 Wi-Fi][Driver] support query power mode OID handler -+ * Support querying power mode OID. -+ * -+ * 01 29 2011 wh.su -+ * [WCXRP00000408] [MT6620 Wi-Fi][Driver] Not doing memory alloc while ioctl set ie with length 0 -+ * not doing mem alloc. while set ie length already 0 -+ * -+ * 01 20 2011 eddie.chen -+ * [WCXRP00000374] [MT6620 Wi-Fi][DRV] SW debug control -+ * Remove debug text. -+ * -+ * 01 20 2011 eddie.chen -+ * [WCXRP00000374] [MT6620 Wi-Fi][DRV] SW debug control -+ * Adjust OID order. -+ * -+ * 01 20 2011 eddie.chen -+ * [WCXRP00000374] [MT6620 Wi-Fi][DRV] SW debug control -+ * Add Oid for sw control debug command -+ * -+ * 01 11 2011 chinglan.wang -+ * NULL -+ * Modify to reslove the CR :[ALPS00028994] Use WEP security to connect Marvell 11N AP. Connection establish -+ * successfully. -+ * Use the WPS function to connect AP, the privacy bit always is set to 1. . -+ * -+ * 01 07 2011 cm.chang -+ * [WCXRP00000336] [MT6620 Wi-Fi][Driver] Add test mode commands in normal phone operation -+ * Add a new compiling option to control if MCR read/write is permitted -+ * -+ * 01 04 2011 cp.wu -+ * [WCXRP00000338] [MT6620 Wi-Fi][Driver] Separate kalMemAlloc into kmalloc and vmalloc implementations to ease -+ * physically continuous memory demands -+ * separate kalMemAlloc() into virtually-continuous and physically-continuous types -+ * to ease slab system pressure -+ * -+ * 01 04 2011 cp.wu -+ * [WCXRP00000338] [MT6620 Wi-Fi][Driver] Separate kalMemAlloc into kmalloc and vmalloc implementations to ease -+ * physically continuous memory demands -+ * separate kalMemAlloc() into virtually-continuous and physically-continuous type to ease slab system pressure -+ * -+ * 12 31 2010 cm.chang -+ * [WCXRP00000336] [MT6620 Wi-Fi][Driver] Add test mode commands in normal phone operation -+ * Add some iwpriv commands to support test mode operation -+ * -+ * 12 15 2010 george.huang -+ * [WCXRP00000152] [MT6620 Wi-Fi] AP mode power saving function -+ * Support set PS profile and set WMM-PS related iwpriv. -+ * -+ * 12 15 2010 george.huang -+ * [WCXRP00000152] [MT6620 Wi-Fi] AP mode power saving function -+ * Allow change PS profile function (through wext_set_power()). -+ * -+ * 12 14 2010 jeffrey.chang -+ * [WCXRP00000262] [MT6620 Wi-Fi][Driver] modify the scan request ioctl to handle hidden SSID -+ * handle hidden SSID -+ * -+ * 12 13 2010 chinglan.wang -+ * NULL -+ * Add WPS 1.0 feature flag to enable the WPS 1.0 function. -+ * -+ * 12 07 2010 cm.chang -+ * [WCXRP00000238] MT6620 Wi-Fi][Driver][FW] Support regulation domain setting from NVRAM and supplicant -+ * Fix compiling error -+ * -+ * 12 07 2010 cm.chang -+ * [WCXRP00000238] MT6620 Wi-Fi][Driver][FW] Support regulation domain setting from NVRAM and supplicant -+ * 1. Country code is from NVRAM or supplicant -+ * 2. Change band definition in CMD/EVENT. -+ * -+ * 11 30 2010 cp.wu -+ * [WCXRP00000213] [MT6620 Wi-Fi][Driver] Implement scanning with specified SSID for wpa_supplicant with ap_scan=1 -+ * . -+ * -+ * 11 08 2010 wh.su -+ * [WCXRP00000171] [MT6620 Wi-Fi][Driver] Add message check code same behavior as mt5921 -+ * add the message check code from mt5921. -+ * -+ * 10 19 2010 jeffrey.chang -+ * [WCXRP00000121] [MT6620 Wi-Fi][Driver] Temporarily disable set power mode ioctl which may cause 6620 to enter power -+ * saving -+ * Temporarily disable set power mode ioctl which may cause MT6620 to enter power saving -+ * -+ * 10 18 2010 jeffrey.chang -+ * [WCXRP00000116] [MT6620 Wi-Fi][Driver] Refine the set_scan ioctl to resolve the Android UI hanging issue -+ * refine the scan ioctl to prevent hanging of Android UI -+ * -+ * 10 01 2010 wh.su -+ * [WCXRP00000067] [MT6620 Wi-Fi][Driver] Support the android+ WAPI function -+ * add the scan result with wapi ie. -+ * -+ * 09 30 2010 wh.su -+ * [WCXRP00000072] [MT6620 Wi-Fi][Driver] Fix TKIP Counter Measure EAPoL callback register issue -+ * fixed the wapi ie assigned issue. -+ * -+ * 09 27 2010 wh.su -+ * NULL -+ * [WCXRP00000067][MT6620 Wi-Fi][Driver] Support the android+ WAPI function. -+ * -+ * 09 21 2010 kevin.huang -+ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning -+ * Eliminate Linux Compile Warning -+ * -+ * 09 09 2010 cp.wu -+ * NULL -+ * add WPS/WPA/RSN IE for Wi-Fi Direct scanning result. -+ * -+ * 09 06 2010 cp.wu -+ * NULL -+ * Androi/Linux: return current operating channel information -+ * -+ * 09 01 2010 wh.su -+ * NULL -+ * adding the wapi support for integration test. -+ * -+ * 08 02 2010 jeffrey.chang -+ * NULL -+ * enable remove key ioctl -+ * -+ * 08 02 2010 jeffrey.chang -+ * NULL -+ * 1) modify tx service thread to avoid busy looping -+ * 2) add spin lock declartion for linux build -+ * -+ * 07 28 2010 jeffrey.chang -+ * NULL -+ * 1) enable encyption ioctls -+ * 2) temporarily disable remove keys ioctl to prevent TX1 busy -+ * -+ * 07 28 2010 jeffrey.chang -+ * NULL -+ * 1) remove unused spinlocks -+ * 2) enable encyption ioctls -+ * 3) fix scan ioctl which may cause supplicant to hang -+ * -+ * 07 19 2010 jeffrey.chang -+ * -+ * add kal api for scanning done -+ * -+ * 07 19 2010 jeffrey.chang -+ * -+ * for linux driver migration -+ * -+ * 07 19 2010 jeffrey.chang -+ * -+ * Linux port modification -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 05 28 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * remove unused macro and debug messages -+ * -+ * 05 14 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * Add dissassoication support for wpa supplicant -+ * -+ * 04 22 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * -+ * 1) modify rx path code for supporting Wi-Fi direct -+ * 2) modify config.h since Linux dont need to consider retaining packet -+ * -+ * 04 21 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * add for private ioctl support -+ * -+ * 04 19 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * Add ioctl of power management -+ * -+ * 04 19 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * remove debug message -+ * -+ * 04 14 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * 1) prGlueInfo->pvInformationBuffer and prGlueInfo->u4InformationBufferLength are no longer used -+ * * 2) fix ioctl -+ * -+ * 04 12 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * remove debug messages for pre-release -+ * -+ * 04 07 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * rWlanInfo should be placed at adapter rather than glue due to most operations -+ * * * * * * * * are done in adapter layer. -+ * -+ * 04 02 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * fix ioctl type -+ * -+ * 04 01 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * enable pmksa cache operation -+ * -+ * 03 31 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * fix ioctl which may cause cmdinfo memory leak -+ * -+ * 03 31 2010 wh.su -+ * [WPD00003816][MT6620 Wi-Fi] Adding the security support -+ * modify the wapi related code for new driver's design. -+ * -+ * 03 30 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * emulate NDIS Pending OID facility -+ * -+ * 03 24 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * initial import for Linux port -+** \main\maintrunk.MT5921\38 2009-10-08 10:33:22 GMT mtk01090 -+** Avoid accessing private data of net_device directly. Replace with netdev_priv(). -+** Add more checking for input parameters and pointers. -+** \main\maintrunk.MT5921\37 2009-09-29 16:49:48 GMT mtk01090 -+** Remove unused variables -+** \main\maintrunk.MT5921\36 2009-09-28 20:19:11 GMT mtk01090 -+** Add private ioctl to carry OID structures. Restructure public/private ioctl interfaces to Linux kernel. -+** \main\maintrunk.MT5921\35 2009-09-03 11:42:30 GMT mtk01088 -+** adding the wapi ioctl support -+** \main\maintrunk.MT5921\34 2009-08-18 22:56:50 GMT mtk01090 -+** Add Linux SDIO (with mmc core) support. -+** Add Linux 2.6.21, 2.6.25, 2.6.26. -+** Fix compile warning in Linux. -+** \main\maintrunk.MT5921\33 2009-05-14 22:43:47 GMT mtk01089 -+** fix compiling warning -+** \main\maintrunk.MT5921\32 2009-05-07 22:26:18 GMT mtk01089 -+** Add mandatory and private IO control for Linux BWCS -+** \main\maintrunk.MT5921\31 2009-02-07 15:11:14 GMT mtk01088 -+** fixed the compiling error -+** \main\maintrunk.MT5921\30 2009-02-07 14:46:51 GMT mtk01088 -+** add the privacy setting from linux supplicant ap selection -+** \main\maintrunk.MT5921\29 2008-11-19 15:18:50 GMT mtk01088 -+** fixed the compling error -+** \main\maintrunk.MT5921\28 2008-11-19 11:56:18 GMT mtk01088 -+** rename some variable with pre-fix to avoid the misunderstanding -+** \main\maintrunk.MT5921\27 2008-08-29 16:59:43 GMT mtk01088 -+** fixed compiling error -+** \main\maintrunk.MT5921\26 2008-08-29 14:55:53 GMT mtk01088 -+** adjust the code for meet the coding style, and add assert check -+** \main\maintrunk.MT5921\25 2008-06-02 11:15:19 GMT mtk01461 -+** Update after wlanoidSetPowerMode changed -+** \main\maintrunk.MT5921\24 2008-05-30 15:13:12 GMT mtk01084 -+** rename wlanoid -+** \main\maintrunk.MT5921\23 2008-03-28 10:40:28 GMT mtk01461 -+** Add set desired rate in Linux STD IOCTL -+** \main\maintrunk.MT5921\22 2008-03-18 10:31:24 GMT mtk01088 -+** add pmkid ioctl and indicate -+** \main\maintrunk.MT5921\21 2008-03-11 15:21:24 GMT mtk01461 -+** \main\maintrunk.MT5921\20 2008-03-11 14:50:55 GMT mtk01461 -+** Refine WPS related priv ioctl for unified interface -+** -+** \main\maintrunk.MT5921\19 2008-03-06 16:30:41 GMT mtk01088 -+** move the configuration code from set essid function, -+** remove the non-used code -+** \main\maintrunk.MT5921\18 2008-02-21 15:47:09 GMT mtk01461 -+** Fix CR[489] -+** \main\maintrunk.MT5921\17 2008-02-12 23:38:31 GMT mtk01461 -+** Add Set Frequency & Channel oid support for Linux -+** \main\maintrunk.MT5921\16 2008-01-24 12:07:34 GMT mtk01461 -+** \main\maintrunk.MT5921\15 2008-01-24 12:00:10 GMT mtk01461 -+** Modify the wext_essid for set up correct information for IBSS, and fix the wrong input ptr for prAdapter -+** \main\maintrunk.MT5921\14 2007-12-06 09:30:12 GMT mtk01425 -+** 1. Branch Test -+** \main\maintrunk.MT5921\13 2007-12-04 18:07:59 GMT mtk01461 -+** fix typo -+** \main\maintrunk.MT5921\12 2007-11-30 17:10:21 GMT mtk01425 -+** 1. Fix compiling erros -+** -+** \main\maintrunk.MT5921\11 2007-11-27 10:43:22 GMT mtk01425 -+** 1. Add WMM-PS setting -+** \main\maintrunk.MT5921\10 2007-11-06 20:33:32 GMT mtk01088 -+** fixed the compiler error -+** \main\maintrunk.MT5921\9 2007-11-06 19:33:15 GMT mtk01088 -+** add WPS code -+** \main\maintrunk.MT5921\8 2007-10-30 12:00:44 GMT MTK01425 -+** 1. Update wlanQueryInformation -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+#include "gl_os.h" -+ -+#include "config.h" -+#include "wlan_oid.h" -+ -+#include "gl_wext.h" -+#include "gl_wext_priv.h" -+ -+#include "precomp.h" -+ -+#if CFG_SUPPORT_WAPI -+#include "gl_sec.h" -+#endif -+ -+/* compatibility to wireless extensions */ -+#ifdef WIRELESS_EXT -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+const long channel_freq[] = { -+ 2412, 2417, 2422, 2427, 2432, 2437, 2442, -+ 2447, 2452, 2457, 2462, 2467, 2472, 2484 -+}; -+ -+ -+#define NUM_CHANNELS (sizeof(channel_freq) / sizeof(channel_freq[0])) -+ -+#define MAX_SSID_LEN 32 -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+/* NOTE: name in iwpriv_args only have 16 bytes */ -+static const struct iw_priv_args rIwPrivTable[] = { -+ {IOCTL_SET_INT, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, ""}, -+ {IOCTL_GET_INT, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, ""}, -+ {IOCTL_SET_INT, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3, 0, ""}, -+ {IOCTL_GET_INT, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3, ""}, -+ {IOCTL_SET_INT, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, ""}, -+ -+ {IOCTL_GET_INT, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, ""}, -+ {IOCTL_GET_INT, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, ""}, -+ -+ {IOCTL_SET_INTS, IW_PRIV_TYPE_INT | 4, 0, ""}, -+ {IOCTL_GET_INT, 0, IW_PRIV_TYPE_INT | 50, ""}, -+ {IOCTL_GET_INT, 0, IW_PRIV_TYPE_CHAR | 16, ""}, -+ -+ {IOCTL_SET_STRING, IW_PRIV_TYPE_CHAR | 256, 0, ""}, -+ -+ /* added for set_oid and get_oid */ -+ {IOCTL_SET_STRUCT, 256, 0, ""}, -+ {IOCTL_GET_STRUCT, 0, 256, ""}, -+ -+ /* sub-ioctl definitions */ -+#if 0 -+ {PRIV_CMD_REG_DOMAIN, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_reg_domain"}, -+ {PRIV_CMD_REG_DOMAIN, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_reg_domain"}, -+#endif -+ -+#if CFG_TCP_IP_CHKSUM_OFFLOAD -+ {PRIV_CMD_CSUM_OFFLOAD, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_tcp_csum"}, -+#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */ -+ -+ {PRIV_CMD_POWER_MODE, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_power_mode"}, -+ {PRIV_CMD_POWER_MODE, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_power_mode"}, -+ -+ {PRIV_CMD_WMM_PS, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3, 0, "set_wmm_ps"}, -+ -+ {PRIV_CMD_TEST_MODE, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_test_mode"}, -+ {PRIV_CMD_TEST_CMD, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "set_test_cmd"}, -+ {PRIV_CMD_TEST_CMD, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, -+ "get_test_result"}, -+#if CFG_SUPPORT_PRIV_MCR_RW -+ {PRIV_CMD_ACCESS_MCR, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "set_mcr"}, -+ {PRIV_CMD_ACCESS_MCR, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, -+ "get_mcr"}, -+#endif -+ {PRIV_CMD_SW_CTRL, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "set_sw_ctrl"}, -+ {PRIV_CMD_SW_CTRL, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, -+ "get_sw_ctrl"}, -+ -+#if CFG_SUPPORT_BCM && CFG_SUPPORT_BCM_BWCS -+ {PRIV_CUSTOM_BWCS_CMD, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_bwcs"}, -+ /* GET STRUCT sub-ioctls commands */ -+ {PRIV_CUSTOM_BWCS_CMD, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, -+ "get_bwcs"}, -+#endif -+ -+ /* SET STRUCT sub-ioctls commands */ -+ {PRIV_CMD_OID, 256, 0, "set_oid"}, -+ /* GET STRUCT sub-ioctls commands */ -+ {PRIV_CMD_OID, 0, 256, "get_oid"}, -+ -+ {PRIV_CMD_BAND_CONFIG, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_band"}, -+ {PRIV_CMD_BAND_CONFIG, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_band"}, -+ -+ {PRIV_CMD_SET_TX_POWER, IW_PRIV_TYPE_INT | 4, 0, "set_txpower"}, -+ {PRIV_CMD_GET_CH_LIST, 0, IW_PRIV_TYPE_INT | 50, "get_ch_list"}, -+ {PRIV_CMD_DUMP_MEM, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, -+ "get_mem"}, -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ {PRIV_CMD_P2P_MODE, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "set_p2p_mode"}, -+#endif -+ {PRIV_CMD_GET_BUILD_DATE_CODE, 0, IW_PRIV_TYPE_CHAR | 16, "get_date_code"}, -+ {PRIV_CMD_GET_DEBUG_CODE, 0, IW_PRIV_TYPE_CHAR | 16, "get_dbg_code"}, -+ /* handle any command with many input parameters */ -+ {PRIV_CMD_OTHER, IW_PRIV_TYPE_CHAR | 256, 0, "set_str_cmd"}, -+ -+ {PRIV_CMD_WFD_DEBUG_CODE, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "set_wfd_dbg_code"}, -+}; -+ -+static const iw_handler rIwPrivHandler[] = { -+ [IOCTL_SET_INT - SIOCIWFIRSTPRIV] = priv_set_int, -+ [IOCTL_GET_INT - SIOCIWFIRSTPRIV] = priv_get_int, -+ [IOCTL_SET_ADDRESS - SIOCIWFIRSTPRIV] = NULL, -+ [IOCTL_GET_ADDRESS - SIOCIWFIRSTPRIV] = NULL, -+ [IOCTL_SET_STR - SIOCIWFIRSTPRIV] = NULL, -+ [IOCTL_GET_STR - SIOCIWFIRSTPRIV] = NULL, -+ [IOCTL_SET_KEY - SIOCIWFIRSTPRIV] = NULL, -+ [IOCTL_GET_KEY - SIOCIWFIRSTPRIV] = NULL, -+ [IOCTL_SET_STRUCT - SIOCIWFIRSTPRIV] = priv_set_struct, -+ [IOCTL_GET_STRUCT - SIOCIWFIRSTPRIV] = priv_get_struct, -+ [IOCTL_SET_STRUCT_FOR_EM - SIOCIWFIRSTPRIV] = priv_set_struct, -+ [IOCTL_SET_INTS - SIOCIWFIRSTPRIV] = priv_set_ints, -+ [IOCTL_GET_INTS - SIOCIWFIRSTPRIV] = priv_get_ints, -+ [IOCTL_SET_STRING - SIOCIWFIRSTPRIV] = priv_set_string, -+}; -+ -+const struct iw_handler_def wext_handler_def = { -+ .num_standard = 0, -+ .num_private = (__u16) sizeof(rIwPrivHandler) / sizeof(iw_handler), -+ .num_private_args = (__u16) sizeof(rIwPrivTable) / sizeof(struct iw_priv_args), -+ .standard = (iw_handler *) NULL, -+ .private = rIwPrivHandler, -+ .private_args = rIwPrivTable, -+ .get_wireless_stats = wext_get_wireless_stats, -+}; -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Find the desired WPA/RSN Information Element according to desiredElemID. -+* -+* \param[in] pucIEStart IE starting address. -+* \param[in] i4TotalIeLen Total length of all the IE. -+* \param[in] ucDesiredElemId Desired element ID. -+* \param[out] ppucDesiredIE Pointer to the desired IE. -+* -+* \retval TRUE Find the desired IE. -+* \retval FALSE Desired IE not found. -+* -+* \note -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN -+wextSrchDesiredWPAIE(IN PUINT_8 pucIEStart, -+ IN INT_32 i4TotalIeLen, IN UINT_8 ucDesiredElemId, OUT PUINT_8 *ppucDesiredIE) -+{ -+ INT_32 i4InfoElemLen; -+ -+ ASSERT(pucIEStart); -+ ASSERT(ppucDesiredIE); -+ -+ while (i4TotalIeLen >= 2) { -+ i4InfoElemLen = (INT_32) pucIEStart[1] + 2; -+ -+ if (pucIEStart[0] == ucDesiredElemId && i4InfoElemLen <= i4TotalIeLen) { -+ if (ucDesiredElemId != 0xDD) { -+ /* Non 0xDD, OK! */ -+ *ppucDesiredIE = &pucIEStart[0]; -+ return TRUE; -+ } -+ /* EID == 0xDD, check WPA IE */ -+ if (pucIEStart[1] >= 4) { -+ if (memcmp(&pucIEStart[2], "\x00\x50\xf2\x01", 4) == 0) { -+ *ppucDesiredIE = &pucIEStart[0]; -+ return TRUE; -+ } -+ } /* check WPA IE length */ -+ /* check EID == 0xDD */ -+ } -+ -+ /* check desired EID */ -+ /* Select next information element. */ -+ i4TotalIeLen -= i4InfoElemLen; -+ pucIEStart += i4InfoElemLen; -+ } -+ -+ return FALSE; -+} /* parseSearchDesiredWPAIE */ -+ -+#if CFG_SUPPORT_WAPI -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Find the desired WAPI Information Element . -+* -+* \param[in] pucIEStart IE starting address. -+* \param[in] i4TotalIeLen Total length of all the IE. -+* \param[out] ppucDesiredIE Pointer to the desired IE. -+* -+* \retval TRUE Find the desired IE. -+* \retval FALSE Desired IE not found. -+* -+* \note -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN wextSrchDesiredWAPIIE(IN PUINT_8 pucIEStart, IN INT_32 i4TotalIeLen, OUT PUINT_8 *ppucDesiredIE) -+{ -+ INT_32 i4InfoElemLen; -+ -+ ASSERT(pucIEStart); -+ ASSERT(ppucDesiredIE); -+ -+ while (i4TotalIeLen >= 2) { -+ i4InfoElemLen = (INT_32) pucIEStart[1] + 2; -+ -+ if (pucIEStart[0] == ELEM_ID_WAPI && i4InfoElemLen <= i4TotalIeLen) { -+ *ppucDesiredIE = &pucIEStart[0]; -+ return TRUE; -+ } -+ -+ /* check desired EID */ -+ /* Select next information element. */ -+ i4TotalIeLen -= i4InfoElemLen; -+ pucIEStart += i4InfoElemLen; -+ } -+ -+ return FALSE; -+} /* wextSrchDesiredWAPIIE */ -+#endif -+ -+#if CFG_SUPPORT_HOTSPOT_2_0 -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Check if exist the desired HS2.0 Information Element according to desiredElemID. -+* -+* \param[in] pucIEStart IE starting address. -+* \param[in] i4TotalIeLen Total length of all the IE. -+* \param[in] ucDesiredElemId Desired element ID. -+* \param[out] ppucDesiredIE Pointer to the desired IE. -+* -+* \retval TRUE Find the desired IE. -+* \retval FALSE Desired IE not found. -+* -+* \note -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN wextIsDesiredHS20IE(IN PUINT_8 pucCurIE, IN INT_32 i4TotalIeLen) -+{ -+ INT_32 i4InfoElemLen; -+ -+ ASSERT(pucCurIE); -+ -+ i4InfoElemLen = (INT_32) pucCurIE[1] + 2; -+ -+ if (pucCurIE[0] == ELEM_ID_VENDOR && i4InfoElemLen <= i4TotalIeLen) { -+ if (pucCurIE[1] >= ELEM_MIN_LEN_HS20_INDICATION) { -+ if (memcmp(&pucCurIE[2], "\x50\x6f\x9a\x10", 4) == 0) -+ return TRUE; -+ } -+ } -+ /* check desired EID */ -+ return FALSE; -+} /* wextIsDesiredHS20IE */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Check if exist the desired interworking Information Element according to desiredElemID. -+* -+* \param[in] pucIEStart IE starting address. -+* \param[in] i4TotalIeLen Total length of all the IE. -+* \param[in] ucDesiredElemId Desired element ID. -+* \param[out] ppucDesiredIE Pointer to the desired IE. -+* -+* \retval TRUE Find the desired IE. -+* \retval FALSE Desired IE not found. -+* -+* \note -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN wextIsDesiredInterworkingIE(IN PUINT_8 pucCurIE, IN INT_32 i4TotalIeLen) -+{ -+ INT_32 i4InfoElemLen; -+ -+ ASSERT(pucCurIE); -+ -+ i4InfoElemLen = (INT_32) pucCurIE[1] + 2; -+ -+ if (pucCurIE[0] == ELEM_ID_INTERWORKING && i4InfoElemLen <= i4TotalIeLen) { -+ switch (pucCurIE[1]) { -+ case IW_IE_LENGTH_ANO: -+ case IW_IE_LENGTH_ANO_HESSID: -+ case IW_IE_LENGTH_ANO_VENUE: -+ case IW_IE_LENGTH_ANO_VENUE_HESSID: -+ return TRUE; -+ -+ default: -+ break; -+ } -+ -+ } -+ /* check desired EID */ -+ return FALSE; -+} /* wextIsDesiredInterworkingIE */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Check if exist the desired Adv Protocol Information Element according to desiredElemID. -+* -+* \param[in] pucIEStart IE starting address. -+* \param[in] i4TotalIeLen Total length of all the IE. -+* \param[in] ucDesiredElemId Desired element ID. -+* \param[out] ppucDesiredIE Pointer to the desired IE. -+* -+* \retval TRUE Find the desired IE. -+* \retval FALSE Desired IE not found. -+* -+* \note -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN wextIsDesiredAdvProtocolIE(IN PUINT_8 pucCurIE, IN INT_32 i4TotalIeLen) -+{ -+ INT_32 i4InfoElemLen; -+ -+ ASSERT(pucCurIE); -+ -+ i4InfoElemLen = (INT_32) pucCurIE[1] + 2; -+ -+ if (pucCurIE[0] == ELEM_ID_ADVERTISEMENT_PROTOCOL && i4InfoElemLen <= i4TotalIeLen) -+ return TRUE; -+ /* check desired EID */ -+ return FALSE; -+} /* wextIsDesiredAdvProtocolIE */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Check if exist the desired Roaming Consortium Information Element according to desiredElemID. -+* -+* \param[in] pucIEStart IE starting address. -+* \param[in] i4TotalIeLen Total length of all the IE. -+* \param[in] ucDesiredElemId Desired element ID. -+* \param[out] ppucDesiredIE Pointer to the desired IE. -+* -+* \retval TRUE Find the desired IE. -+* \retval FALSE Desired IE not found. -+* -+* \note -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN wextIsDesiredRoamingConsortiumIE(IN PUINT_8 pucCurIE, IN INT_32 i4TotalIeLen) -+{ -+ INT_32 i4InfoElemLen; -+ -+ ASSERT(pucCurIE); -+ -+ i4InfoElemLen = (INT_32) pucCurIE[1] + 2; -+ -+ if (pucCurIE[0] == ELEM_ID_ROAMING_CONSORTIUM && i4InfoElemLen <= i4TotalIeLen) -+ return TRUE; -+ /* check desired EID */ -+ return FALSE; -+} /* wextIsDesiredRoamingConsortiumIE */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Find the desired HS2.0 Information Element according to desiredElemID. -+* -+* \param[in] pucIEStart IE starting address. -+* \param[in] i4TotalIeLen Total length of all the IE. -+* \param[in] ucDesiredElemId Desired element ID. -+* \param[out] ppucDesiredIE Pointer to the desired IE. -+* -+* \retval TRUE Find the desired IE. -+* \retval FALSE Desired IE not found. -+* -+* \note -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN wextSrchDesiredHS20IE(IN PUINT_8 pucIEStart, IN INT_32 i4TotalIeLen, OUT PUINT_8 *ppucDesiredIE) -+{ -+ INT_32 i4InfoElemLen; -+ -+ ASSERT(pucIEStart); -+ ASSERT(ppucDesiredIE); -+ -+ while (i4TotalIeLen >= 2) { -+ i4InfoElemLen = (INT_32) pucIEStart[1] + 2; -+ -+ if (pucIEStart[0] == ELEM_ID_VENDOR && i4InfoElemLen <= i4TotalIeLen) { -+ if (pucIEStart[1] >= ELEM_MIN_LEN_HS20_INDICATION) { -+ if (memcmp(&pucIEStart[2], "\x50\x6f\x9a\x10", 4) == 0) { -+ *ppucDesiredIE = &pucIEStart[0]; -+ return TRUE; -+ } -+ } -+ } -+ -+ /* check desired EID */ -+ /* Select next information element. */ -+ i4TotalIeLen -= i4InfoElemLen; -+ pucIEStart += i4InfoElemLen; -+ } -+ -+ return FALSE; -+} /* wextSrchDesiredHS20IE */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Find the desired interworking Information Element according to desiredElemID. -+* -+* \param[in] pucIEStart IE starting address. -+* \param[in] i4TotalIeLen Total length of all the IE. -+* \param[in] ucDesiredElemId Desired element ID. -+* \param[out] ppucDesiredIE Pointer to the desired IE. -+* -+* \retval TRUE Find the desired IE. -+* \retval FALSE Desired IE not found. -+* -+* \note -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN wextSrchDesiredInterworkingIE(IN PUINT_8 pucIEStart, IN INT_32 i4TotalIeLen, OUT PUINT_8 *ppucDesiredIE) -+{ -+ INT_32 i4InfoElemLen; -+ -+ ASSERT(pucIEStart); -+ ASSERT(ppucDesiredIE); -+ -+ while (i4TotalIeLen >= 2) { -+ i4InfoElemLen = (INT_32) pucIEStart[1] + 2; -+ -+ if (pucIEStart[0] == ELEM_ID_INTERWORKING && i4InfoElemLen <= i4TotalIeLen) { -+ *ppucDesiredIE = &pucIEStart[0]; -+ return TRUE; -+ } -+ -+ /* check desired EID */ -+ /* Select next information element. */ -+ i4TotalIeLen -= i4InfoElemLen; -+ pucIEStart += i4InfoElemLen; -+ } -+ -+ return FALSE; -+} /* wextSrchDesiredInterworkingIE */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Find the desired Adv Protocol Information Element according to desiredElemID. -+* -+* \param[in] pucIEStart IE starting address. -+* \param[in] i4TotalIeLen Total length of all the IE. -+* \param[in] ucDesiredElemId Desired element ID. -+* \param[out] ppucDesiredIE Pointer to the desired IE. -+* -+* \retval TRUE Find the desired IE. -+* \retval FALSE Desired IE not found. -+* -+* \note -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN wextSrchDesiredAdvProtocolIE(IN PUINT_8 pucIEStart, IN INT_32 i4TotalIeLen, OUT PUINT_8 *ppucDesiredIE) -+{ -+ INT_32 i4InfoElemLen; -+ -+ ASSERT(pucIEStart); -+ ASSERT(ppucDesiredIE); -+ -+ while (i4TotalIeLen >= 2) { -+ i4InfoElemLen = (INT_32) pucIEStart[1] + 2; -+ -+ if (pucIEStart[0] == ELEM_ID_ADVERTISEMENT_PROTOCOL && i4InfoElemLen <= i4TotalIeLen) { -+ *ppucDesiredIE = &pucIEStart[0]; -+ return TRUE; -+ } -+ -+ /* check desired EID */ -+ /* Select next information element. */ -+ i4TotalIeLen -= i4InfoElemLen; -+ pucIEStart += i4InfoElemLen; -+ } -+ -+ return FALSE; -+} /* wextSrchDesiredAdvProtocolIE */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Find the desired Roaming Consortium Information Element according to desiredElemID. -+* -+* \param[in] pucIEStart IE starting address. -+* \param[in] i4TotalIeLen Total length of all the IE. -+* \param[in] ucDesiredElemId Desired element ID. -+* \param[out] ppucDesiredIE Pointer to the desired IE. -+* -+* \retval TRUE Find the desired IE. -+* \retval FALSE Desired IE not found. -+* -+* \note -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN wextSrchDesiredRoamingConsortiumIE(IN PUINT_8 pucIEStart, IN INT_32 i4TotalIeLen, OUT PUINT_8 *ppucDesiredIE) -+{ -+ INT_32 i4InfoElemLen; -+ -+ ASSERT(pucIEStart); -+ ASSERT(ppucDesiredIE); -+ -+ while (i4TotalIeLen >= 2) { -+ i4InfoElemLen = (INT_32) pucIEStart[1] + 2; -+ -+ if (pucIEStart[0] == ELEM_ID_ROAMING_CONSORTIUM && i4InfoElemLen <= i4TotalIeLen) { -+ *ppucDesiredIE = &pucIEStart[0]; -+ return TRUE; -+ } -+ -+ /* check desired EID */ -+ /* Select next information element. */ -+ i4TotalIeLen -= i4InfoElemLen; -+ pucIEStart += i4InfoElemLen; -+ } -+ -+ return FALSE; -+} /* wextSrchDesiredRoamingConsortiumIE */ -+#endif -+ -+#if CFG_SUPPORT_WPS -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Find the desired WPS Information Element according to desiredElemID. -+* -+* \param[in] pucIEStart IE starting address. -+* \param[in] i4TotalIeLen Total length of all the IE. -+* \param[in] ucDesiredElemId Desired element ID. -+* \param[out] ppucDesiredIE Pointer to the desired IE. -+* -+* \retval TRUE Find the desired IE. -+* \retval FALSE Desired IE not found. -+* -+* \note -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN -+wextSrchDesiredWPSIE(IN PUINT_8 pucIEStart, -+ IN INT_32 i4TotalIeLen, IN UINT_8 ucDesiredElemId, OUT PUINT_8 *ppucDesiredIE) -+{ -+ INT_32 i4InfoElemLen; -+ -+ ASSERT(pucIEStart); -+ ASSERT(ppucDesiredIE); -+ -+ while (i4TotalIeLen >= 2) { -+ i4InfoElemLen = (INT_32) pucIEStart[1] + 2; -+ -+ if (pucIEStart[0] == ucDesiredElemId && i4InfoElemLen <= i4TotalIeLen) { -+ if (ucDesiredElemId != 0xDD) { -+ /* Non 0xDD, OK! */ -+ *ppucDesiredIE = &pucIEStart[0]; -+ return TRUE; -+ } -+ /* EID == 0xDD, check WPS IE */ -+ if (pucIEStart[1] >= 4) { -+ if (memcmp(&pucIEStart[2], "\x00\x50\xf2\x04", 4) == 0) { -+ *ppucDesiredIE = &pucIEStart[0]; -+ return TRUE; -+ } -+ } /* check WPS IE length */ -+ /* check EID == 0xDD */ -+ } -+ -+ /* check desired EID */ -+ /* Select next information element. */ -+ i4TotalIeLen -= i4InfoElemLen; -+ pucIEStart += i4InfoElemLen; -+ } -+ -+ return FALSE; -+} /* parseSearchDesiredWPSIE */ -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Get the name of the protocol used on the air. -+* -+* \param[in] prDev Net device requested. -+* \param[in] prIwrInfo NULL. -+* \param[out] pcName Buffer to store protocol name string -+* \param[in] pcExtra NULL. -+* -+* \retval 0 For success. -+* -+* \note If netif_carrier_ok, protocol name is returned; -+* otherwise, "disconnected" is returned. -+*/ -+/*----------------------------------------------------------------------------*/ -+static int -+wext_get_name(IN struct net_device *prNetDev, IN struct iw_request_info *prIwrInfo, OUT char *pcName, IN char *pcExtra) -+{ -+ ENUM_PARAM_NETWORK_TYPE_T eNetWorkType = PARAM_NETWORK_TYPE_NUM; -+ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ UINT_32 u4BufLen = 0; -+ -+ ASSERT(prNetDev); -+ ASSERT(pcName); -+ if (FALSE == GLUE_CHK_PR2(prNetDev, pcName)) -+ return -EINVAL; -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); -+ -+ if (netif_carrier_ok(prNetDev)) { -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidQueryNetworkTypeInUse, -+ &eNetWorkType, sizeof(eNetWorkType), TRUE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ switch (eNetWorkType) { -+ case PARAM_NETWORK_TYPE_DS: -+ strcpy(pcName, "IEEE 802.11b"); -+ break; -+ case PARAM_NETWORK_TYPE_OFDM24: -+ strcpy(pcName, "IEEE 802.11bgn"); -+ break; -+ case PARAM_NETWORK_TYPE_AUTOMODE: -+ case PARAM_NETWORK_TYPE_OFDM5: -+ strcpy(pcName, "IEEE 802.11abgn"); -+ break; -+ case PARAM_NETWORK_TYPE_FH: -+ default: -+ strcpy(pcName, "IEEE 802.11"); -+ break; -+ } -+ } else { -+ strcpy(pcName, "Disconnected"); -+ } -+ -+ return 0; -+} /* wext_get_name */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief To set the operating channel in the wireless device. -+* -+* \param[in] prDev Net device requested. -+* \param[in] prIwrInfo NULL -+* \param[in] prFreq Buffer to store frequency information -+* \param[in] pcExtra NULL -+* -+* \retval 0 For success. -+* \retval -EOPNOTSUPP If infrastructure mode is not NET NET_TYPE_IBSS. -+* \retval -EINVAL Invalid channel frequency. -+* -+* \note If infrastructure mode is IBSS, new channel frequency is set to device. -+* The range of channel number depends on different regulatory domain. -+*/ -+/*----------------------------------------------------------------------------*/ -+static int -+wext_set_freq(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwReqInfo, IN struct iw_freq *prIwFreq, IN char *pcExtra) -+{ -+ -+#if 0 -+ UINT_32 u4ChnlFreq; /* Store channel or frequency information */ -+ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ UINT_32 u4BufLen = 0; -+ -+ ASSERT(prNetDev); -+ ASSERT(prIwFreq); -+ if (FALSE == GLUE_CHK_PR2(prNetDev, prIwFreq)) -+ return -EINVAL; -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); -+ -+ /* -+ printk("set m:%d, e:%d, i:%d, flags:%d\n", -+ prIwFreq->m, prIwFreq->e, prIwFreq->i, prIwFreq->flags); -+ */ -+ -+ /* If setting by frequency, convert to a channel */ -+ if ((prIwFreq->e == 1) && (prIwFreq->m >= (int)2.412e8) && (prIwFreq->m <= (int)2.484e8)) { -+ -+ /* Change to KHz format */ -+ u4ChnlFreq = (UINT_32) (prIwFreq->m / (KILO / 10)); -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetFrequency, -+ &u4ChnlFreq, sizeof(u4ChnlFreq), FALSE, FALSE, FALSE, &u4BufLen); -+ -+ if (WLAN_STATUS_SUCCESS != rStatus) -+ return -EINVAL; -+ } -+ /* Setting by channel number */ -+ else if ((prIwFreq->m > KILO) || (prIwFreq->e > 0)) -+ return -EOPNOTSUPP; -+ -+ /* Change to channel number format */ -+ u4ChnlFreq = (UINT_32) prIwFreq->m; -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetChannel, &u4ChnlFreq, sizeof(u4ChnlFreq), FALSE, FALSE, FALSE, &u4BufLen); -+ -+ if (WLAN_STATUS_SUCCESS != rStatus) -+ return -EINVAL; -+ -+#endif -+ -+ return 0; -+ -+} /* wext_set_freq */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief To get the operating channel in the wireless device. -+* -+* \param[in] prDev Net device requested. -+* \param[in] prIwrInfo NULL. -+* \param[out] prFreq Buffer to store frequency information. -+* \param[in] pcExtra NULL. -+* -+* \retval 0 If netif_carrier_ok. -+* \retval -ENOTCONN Otherwise -+* -+* \note If netif_carrier_ok, channel frequency information is stored in pFreq. -+*/ -+/*----------------------------------------------------------------------------*/ -+static int -+wext_get_freq(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwrInfo, OUT struct iw_freq *prIwFreq, IN char *pcExtra) -+{ -+ UINT_32 u4Channel = 0; -+ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ UINT_32 u4BufLen = 0; -+ -+ ASSERT(prNetDev); -+ ASSERT(prIwFreq); -+ if (FALSE == GLUE_CHK_PR2(prNetDev, prIwFreq)) -+ return -EINVAL; -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); -+ -+ /* GeorgeKuo: TODO skip checking in IBSS mode */ -+ if (!netif_carrier_ok(prNetDev)) -+ return -ENOTCONN; -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidQueryFrequency, &u4Channel, sizeof(u4Channel), TRUE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ prIwFreq->m = (int)u4Channel; /* freq in KHz */ -+ prIwFreq->e = 3; -+ -+ return 0; -+ -+} /* wext_get_freq */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief To set operating mode. -+* -+* \param[in] prDev Net device requested. -+* \param[in] prIwrInfo NULL. -+* \param[in] pu4Mode Pointer to new operation mode. -+* \param[in] pcExtra NULL. -+* -+* \retval 0 For success. -+* \retval -EOPNOTSUPP If new mode is not supported. -+* -+* \note Device will run in new operation mode if it is valid. -+*/ -+/*----------------------------------------------------------------------------*/ -+static int -+wext_set_mode(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwReqInfo, IN unsigned int *pu4Mode, IN char *pcExtra) -+{ -+ ENUM_PARAM_OP_MODE_T eOpMode; -+ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ UINT_32 u4BufLen = 0; -+ -+ ASSERT(prNetDev); -+ ASSERT(pu4Mode); -+ if (FALSE == GLUE_CHK_PR2(prNetDev, pu4Mode)) -+ return -EINVAL; -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); -+ -+ switch (*pu4Mode) { -+ case IW_MODE_AUTO: -+ eOpMode = NET_TYPE_AUTO_SWITCH; -+ break; -+ -+ case IW_MODE_ADHOC: -+ eOpMode = NET_TYPE_IBSS; -+ break; -+ -+ case IW_MODE_INFRA: -+ eOpMode = NET_TYPE_INFRA; -+ break; -+ -+ default: -+ DBGLOG(REQ, ERROR, "%s(): Set UNSUPPORTED Mode = %d.\n", __func__, *pu4Mode); -+ return -EOPNOTSUPP; -+ } -+ -+ /* printk("%s(): Set Mode = %d\n", __FUNCTION__, *pu4Mode); */ -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetInfrastructureMode, -+ &eOpMode, sizeof(eOpMode), FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ -+ /* after set operation mode, key table are cleared */ -+ -+ /* reset wpa info */ -+ prGlueInfo->rWpaInfo.u4WpaVersion = IW_AUTH_WPA_VERSION_DISABLED; -+ prGlueInfo->rWpaInfo.u4KeyMgmt = 0; -+ prGlueInfo->rWpaInfo.u4CipherGroup = IW_AUTH_CIPHER_NONE; -+ prGlueInfo->rWpaInfo.u4CipherPairwise = IW_AUTH_CIPHER_NONE; -+ prGlueInfo->rWpaInfo.u4AuthAlg = IW_AUTH_ALG_OPEN_SYSTEM; -+#if CFG_SUPPORT_802_11W -+ prGlueInfo->rWpaInfo.u4Mfp = IW_AUTH_MFP_DISABLED; -+#endif -+ -+ return 0; -+} /* wext_set_mode */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief To get operating mode. -+* -+* \param[in] prNetDev Net device requested. -+* \param[in] prIwReqInfo NULL. -+* \param[out] pu4Mode Buffer to store operating mode information. -+* \param[in] pcExtra NULL. -+* -+* \retval 0 If data is valid. -+* \retval -EINVAL Otherwise. -+* -+* \note If netif_carrier_ok, operating mode information is stored in pu4Mode. -+*/ -+/*----------------------------------------------------------------------------*/ -+static int -+wext_get_mode(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwReqInfo, OUT unsigned int *pu4Mode, IN char *pcExtra) -+{ -+ ENUM_PARAM_OP_MODE_T eOpMode = NET_TYPE_NUM; -+ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ UINT_32 u4BufLen = 0; -+ -+ ASSERT(prNetDev); -+ ASSERT(pu4Mode); -+ if (FALSE == GLUE_CHK_PR2(prNetDev, pu4Mode)) -+ return -EINVAL; -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidQueryInfrastructureMode, -+ &eOpMode, sizeof(eOpMode), TRUE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ switch (eOpMode) { -+ case NET_TYPE_IBSS: -+ *pu4Mode = IW_MODE_ADHOC; -+ break; -+ -+ case NET_TYPE_INFRA: -+ *pu4Mode = IW_MODE_INFRA; -+ break; -+ -+ case NET_TYPE_AUTO_SWITCH: -+ *pu4Mode = IW_MODE_AUTO; -+ break; -+ -+ default: -+ DBGLOG(REQ, ERROR, "%s(): Get UNKNOWN Mode.\n", __func__); -+ return -EINVAL; -+ } -+ -+ return 0; -+} /* wext_get_mode */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief To get the valid range for each configurable STA setting value. -+* -+* \param[in] prDev Net device requested. -+* \param[in] prIwrInfo NULL. -+* \param[in] prData Pointer to iw_point structure, not used. -+* \param[out] pcExtra Pointer to buffer which is allocated by caller of this -+* function, wext_support_ioctl() or ioctl_standard_call() in -+* wireless.c. -+* -+* \retval 0 If data is valid. -+* -+* \note The extra buffer (pcExtra) is filled with information from driver. -+*/ -+/*----------------------------------------------------------------------------*/ -+static int -+wext_get_range(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwrInfo, IN struct iw_point *prData, OUT char *pcExtra) -+{ -+ struct iw_range *prRange = NULL; -+ PARAM_RATES_EX aucSuppRate = { 0 }; /* data buffers */ -+ int i = 0; -+ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ UINT_32 u4BufLen = 0; -+ -+ ASSERT(prNetDev); -+ ASSERT(pcExtra); -+ if (FALSE == GLUE_CHK_PR2(prNetDev, pcExtra)) -+ return -EINVAL; -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); -+ -+ prRange = (struct iw_range *)pcExtra; -+ -+ memset(prRange, 0, sizeof(*prRange)); -+ prRange->throughput = 20000000; /* 20Mbps */ -+ prRange->min_nwid = 0; /* not used */ -+ prRange->max_nwid = 0; /* not used */ -+ -+ /* scan_capa not implemented */ -+ -+ /* event_capa[6]: kernel + driver capabilities */ -+ prRange->event_capa[0] = (IW_EVENT_CAPA_K_0 | IW_EVENT_CAPA_MASK(SIOCGIWAP) -+ | IW_EVENT_CAPA_MASK(SIOCGIWSCAN) -+ /* can't display meaningful string in iwlist -+ | IW_EVENT_CAPA_MASK(SIOCGIWTXPOW) -+ | IW_EVENT_CAPA_MASK(IWEVMICHAELMICFAILURE) -+ | IW_EVENT_CAPA_MASK(IWEVASSOCREQIE) -+ | IW_EVENT_CAPA_MASK(IWEVPMKIDCAND) -+ */ -+ ); -+ prRange->event_capa[1] = IW_EVENT_CAPA_K_1; -+ -+ /* report 2.4G channel and frequency only */ -+ prRange->num_channels = (__u16) NUM_CHANNELS; -+ prRange->num_frequency = (__u8) NUM_CHANNELS; -+ for (i = 0; i < NUM_CHANNELS; i++) { -+ /* iwlib takes this number as channel number */ -+ prRange->freq[i].i = i + 1; -+ prRange->freq[i].m = channel_freq[i]; -+ prRange->freq[i].e = 6; /* Values in table in MHz */ -+ } -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidQuerySupportedRates, -+ &aucSuppRate, sizeof(aucSuppRate), TRUE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ for (i = 0; i < IW_MAX_BITRATES && i < PARAM_MAX_LEN_RATES_EX; i++) { -+ if (aucSuppRate[i] == 0) -+ break; -+ prRange->bitrate[i] = (aucSuppRate[i] & 0x7F) * 500000; /* 0.5Mbps */ -+ } -+ prRange->num_bitrates = i; -+ -+ prRange->min_rts = 0; -+ prRange->max_rts = 2347; -+ prRange->min_frag = 256; -+ prRange->max_frag = 2346; -+ -+ prRange->min_pmp = 0; /* power management by driver */ -+ prRange->max_pmp = 0; /* power management by driver */ -+ prRange->min_pmt = 0; /* power management by driver */ -+ prRange->max_pmt = 0; /* power management by driver */ -+ prRange->pmp_flags = IW_POWER_RELATIVE; /* pm default flag */ -+ prRange->pmt_flags = IW_POWER_ON; /* pm timeout flag */ -+ prRange->pm_capa = IW_POWER_ON; /* power management by driver */ -+ -+ prRange->encoding_size[0] = 5; /* wep40 */ -+ prRange->encoding_size[1] = 16; /* tkip */ -+ prRange->encoding_size[2] = 16; /* ckip */ -+ prRange->encoding_size[3] = 16; /* ccmp */ -+ prRange->encoding_size[4] = 13; /* wep104 */ -+ prRange->encoding_size[5] = 16; /* wep128 */ -+ prRange->num_encoding_sizes = 6; -+ prRange->max_encoding_tokens = 6; /* token? */ -+ -+#if WIRELESS_EXT < 17 -+ prRange->txpower_capa = 0x0002; /* IW_TXPOW_RELATIVE */ -+#else -+ prRange->txpower_capa = IW_TXPOW_RELATIVE; -+#endif -+ prRange->num_txpower = 5; -+ prRange->txpower[0] = 0; /* minimum */ -+ prRange->txpower[1] = 25; /* 25% */ -+ prRange->txpower[2] = 50; /* 50% */ -+ prRange->txpower[3] = 100; /* 100% */ -+ -+ prRange->we_version_compiled = WIRELESS_EXT; -+ prRange->we_version_source = WIRELESS_EXT; -+ -+ prRange->retry_capa = IW_RETRY_LIMIT; -+ prRange->retry_flags = IW_RETRY_LIMIT; -+ prRange->min_retry = 7; -+ prRange->max_retry = 7; -+ prRange->r_time_flags = IW_RETRY_ON; -+ prRange->min_r_time = 0; -+ prRange->max_r_time = 0; -+ -+ /* signal strength and link quality */ -+ /* Just define range here, reporting value moved to wext_get_stats() */ -+ prRange->sensitivity = -83; /* fixed value */ -+ prRange->max_qual.qual = 100; /* max 100% */ -+ prRange->max_qual.level = (__u8) (0x100 - 0); /* max 0 dbm */ -+ prRange->max_qual.noise = (__u8) (0x100 - 0); /* max 0 dbm */ -+ -+ /* enc_capa */ -+#if WIRELESS_EXT > 17 -+ prRange->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 | IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP; -+#endif -+ -+ /* min_pms; Minimal PM saving */ -+ /* max_pms; Maximal PM saving */ -+ /* pms_flags; How to decode max/min PM saving */ -+ -+ /* modul_capa; IW_MODUL_* bit field */ -+ /* bitrate_capa; Types of bitrates supported */ -+ -+ return 0; -+} /* wext_get_range */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief To set BSSID of AP to connect. -+* -+* \param[in] prDev Net device requested. -+* \param[in] prIwrInfo NULL. -+* \param[in] prAddr Pointer to struct sockaddr structure containing AP's BSSID. -+* \param[in] pcExtra NULL. -+* -+* \retval 0 For success. -+* -+* \note Desired AP's BSSID is set to driver. -+*/ -+/*----------------------------------------------------------------------------*/ -+static int -+wext_set_ap(IN struct net_device *prDev, -+ IN struct iw_request_info *prIwrInfo, IN struct sockaddr *prAddr, IN char *pcExtra) -+{ -+ return 0; -+} /* wext_set_ap */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief To get AP MAC address. -+* -+* \param[in] prDev Net device requested. -+* \param[in] prIwrInfo NULL. -+* \param[out] prAddr Pointer to struct sockaddr structure storing AP's BSSID. -+* \param[in] pcExtra NULL. -+* -+* \retval 0 If netif_carrier_ok. -+* \retval -ENOTCONN Otherwise. -+* -+* \note If netif_carrier_ok, AP's mac address is stored in pAddr->sa_data. -+*/ -+/*----------------------------------------------------------------------------*/ -+static int -+wext_get_ap(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwrInfo, OUT struct sockaddr *prAddr, IN char *pcExtra) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ UINT_32 u4BufLen = 0; -+ -+ ASSERT(prNetDev); -+ ASSERT(prAddr); -+ if (FALSE == GLUE_CHK_PR2(prNetDev, prAddr)) -+ return -EINVAL; -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); -+ -+ /* if (!netif_carrier_ok(prNetDev)) { */ -+ /* return -ENOTCONN; */ -+ /* } */ -+ -+ if (prGlueInfo->eParamMediaStateIndicated == PARAM_MEDIA_STATE_DISCONNECTED) { -+ /*memset(prAddr, 0, 6);*/ -+ memset(prAddr, 0, sizeof(struct sockaddr)); -+ return 0; -+ } -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidQueryBssid, prAddr->sa_data, ETH_ALEN, TRUE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ return 0; -+} /* wext_get_ap */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief To set mlme operation request. -+* -+* \param[in] prDev Net device requested. -+* \param[in] prIwrInfo NULL. -+* \param[in] prData Pointer of iw_point header. -+* \param[in] pcExtra Pointer to iw_mlme structure mlme request information. -+* -+* \retval 0 For success. -+* \retval -EOPNOTSUPP unsupported IW_MLME_ command. -+* \retval -EINVAL Set MLME Fail, different bssid. -+* -+* \note Driver will start mlme operation if valid. -+*/ -+/*----------------------------------------------------------------------------*/ -+static int -+wext_set_mlme(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwrInfo, IN struct iw_point *prData, IN char *pcExtra) -+{ -+ struct iw_mlme *prMlme = NULL; -+ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ UINT_32 u4BufLen = 0; -+ -+ ASSERT(prNetDev); -+ ASSERT(pcExtra); -+ if (FALSE == GLUE_CHK_PR2(prNetDev, pcExtra)) -+ return -EINVAL; -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); -+ -+ prMlme = (struct iw_mlme *)pcExtra; -+ if (prMlme->cmd == IW_MLME_DEAUTH || prMlme->cmd == IW_MLME_DISASSOC) { -+ if (!netif_carrier_ok(prNetDev)) { -+ DBGLOG(REQ, WARN, "[wifi] Set MLME Deauth/Disassoc, but netif_carrier_off\n"); -+ return 0; -+ } -+ -+ rStatus = kalIoctl(prGlueInfo, wlanoidSetDisassociate, NULL, 0, FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ return 0; -+ } -+ DBGLOG(REQ, WARN, "[wifi] unsupported IW_MLME_ command :%d\n", prMlme->cmd); -+ return -EOPNOTSUPP; -+ -+} /* wext_set_mlme */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief To issue scan request. -+* -+* \param[in] prDev Net device requested. -+* \param[in] prIwrInfo NULL. -+* \param[in] prData NULL. -+* \param[in] pcExtra NULL. -+* -+* \retval 0 For success. -+* \retval -EFAULT Tx power is off. -+* -+* \note Device will start scanning. -+*/ -+/*----------------------------------------------------------------------------*/ -+static int -+wext_set_scan(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwrInfo, IN union iwreq_data *prData, IN char *pcExtra) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ UINT_32 u4BufLen = 0; -+ int essid_len = 0; -+ -+ ASSERT(prNetDev); -+ if (FALSE == GLUE_CHK_DEV(prNetDev)) -+ return -EINVAL; -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); -+ -+#if WIRELESS_EXT > 17 -+ /* retrieve SSID */ -+ if (prData) -+ essid_len = ((struct iw_scan_req *)(((struct iw_point *)prData)->pointer))->essid_len; -+#endif -+ -+ init_completion(&prGlueInfo->rScanComp); -+ -+ /* TODO: parse flags and issue different scan requests? */ -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetBssidListScan, pcExtra, essid_len, FALSE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ /* wait_for_completion_interruptible_timeout(&prGlueInfo->rScanComp, 2 * KAL_HZ); */ -+ /* kalIndicateStatusAndComplete(prGlueInfo, WLAN_STATUS_SCAN_COMPLETE, NULL, 0); */ -+ -+ return 0; -+} /* wext_set_scan */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief To write the ie to buffer -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static inline int snprintf_hex(char *buf, size_t buf_size, const u8 *data, size_t len) -+{ -+ size_t i; -+ char *pos = buf, *end = buf + buf_size; -+ int ret; -+ -+ if (buf_size == 0) -+ return 0; -+ -+ for (i = 0; i < len; i++) { -+ ret = snprintf(pos, end - pos, "%02x", data[i]); -+ if (ret < 0 || ret >= end - pos) { -+ end[-1] = '\0'; -+ return pos - buf; -+ } -+ pos += ret; -+ } -+ end[-1] = '\0'; -+ return pos - buf; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief To get scan results, transform results from driver's format to WE's. -+* -+* \param[in] prDev Net device requested. -+* \param[in] prIwrInfo NULL. -+* \param[out] prData Pointer to iw_point structure, pData->length is the size of -+* pcExtra buffer before used, and is updated after filling scan -+* results. -+* \param[out] pcExtra Pointer to buffer which is allocated by caller of this -+* function, wext_support_ioctl() or ioctl_standard_call() in -+* wireless.c. -+* -+* \retval 0 For success. -+* \retval -ENOMEM If dynamic memory allocation fail. -+* \retval -E2BIG Invalid length. -+* -+* \note Scan results is filled into pcExtra buffer, data size is updated in -+* pData->length. -+*/ -+/*----------------------------------------------------------------------------*/ -+static int -+wext_get_scan(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwrInfo, IN OUT struct iw_point *prData, IN char *pcExtra) -+{ -+ UINT_32 i = 0; -+ UINT_32 j = 0; -+ P_PARAM_BSSID_LIST_EX_T prList = NULL; -+ P_PARAM_BSSID_EX_T prBss = NULL; -+ P_PARAM_VARIABLE_IE_T prDesiredIE = NULL; -+ struct iw_event iwEvent; /* local iw_event buffer */ -+ -+ /* write pointer of extra buffer */ -+ char *pcCur = NULL; -+ /* pointer to the end of last full entry in extra buffer */ -+ char *pcValidEntryEnd = NULL; -+ char *pcEnd = NULL; /* end of extra buffer */ -+ -+ UINT_32 u4AllocBufLen = 0; -+ -+ /* arrange rate information */ -+ UINT_32 u4HighestRate = 0; -+ char aucRatesBuf[64]; -+ UINT_32 u4BufIndex; -+ -+ /* return value */ -+ int ret = 0; -+ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ UINT_32 u4BufLen = 0; -+ -+ ASSERT(prNetDev); -+ ASSERT(prData); -+ ASSERT(pcExtra); -+ if (FALSE == GLUE_CHK_PR3(prNetDev, prData, pcExtra)) -+ return -EINVAL; -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); -+ -+ /* Initialize local variables */ -+ pcCur = pcExtra; -+ pcValidEntryEnd = pcExtra; -+ pcEnd = pcExtra + prData->length; /* end of extra buffer */ -+ -+ /* Allocate another query buffer with the same size of extra buffer */ -+ u4AllocBufLen = prData->length; -+ prList = kalMemAlloc(u4AllocBufLen, VIR_MEM_TYPE); -+ if (prList == NULL) { -+ DBGLOG(REQ, ERROR, "[wifi] no memory for scan list:%d\n", prData->length); -+ ret = -ENOMEM; -+ goto error; -+ } -+ prList->u4NumberOfItems = 0; -+ -+ /* wait scan done */ -+ /* printk ("wait for scan results\n"); */ -+ /* wait_for_completion_interruptible_timeout(&prGlueInfo->rScanComp, 4 * KAL_HZ); */ -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidQueryBssidList, prList, u4AllocBufLen, TRUE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ if (rStatus == WLAN_STATUS_INVALID_LENGTH) { -+ /* Buffer length is not large enough. */ -+ /* printk(KERN_INFO "[wifi] buf:%d result:%ld\n", pData->length, u4BufLen); */ -+ -+#if WIRELESS_EXT >= 17 -+ /* This feature is supported in WE-17 or above, limited by iwlist. -+ ** Return -E2BIG and iwlist will request again with a larger buffer. -+ */ -+ ret = -E2BIG; -+ /* Update length to give application a hint on result length */ -+ prData->length = (__u16) u4BufLen; -+ goto error; -+#else -+ /* Realloc a larger query buffer here, but don't write too much to extra -+ ** buffer when filling it later. -+ */ -+ kalMemFree(prList, VIR_MEM_TYPE, u4AllocBufLen); -+ -+ u4AllocBufLen = u4BufLen; -+ prList = kalMemAlloc(u4AllocBufLen, VIR_MEM_TYPE); -+ if (prList == NULL) { -+ DBGLOG(REQ, ERROR, "[wifi] no memory for larger scan list :%u\n", u4BufLen); -+ ret = -ENOMEM; -+ goto error; -+ } -+ prList->NumberOfItems = 0; -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidQueryBssidList, prList, u4AllocBufLen, TRUE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ if (rStatus == WLAN_STATUS_INVALID_LENGTH) { -+ DBGLOG(REQ, ERROR, "[wifi] larger buf:%u result:%u\n", u4AllocBufLen, u4BufLen); -+ ret = -E2BIG; -+ prData->length = (__u16) u4BufLen; -+ goto error; -+ } -+#endif /* WIRELESS_EXT >= 17 */ -+ -+ } -+ -+ if (prList->u4NumberOfItems > CFG_MAX_NUM_BSS_LIST) { -+ DBGLOG(REQ, WARN, "[wifi] strange scan result count:%u\n", prList->u4NumberOfItems); -+ goto error; -+ } -+ -+ /* Copy required data from pList to pcExtra */ -+ prBss = &prList->arBssid[0]; /* set to the first entry */ -+ for (i = 0; i < prList->u4NumberOfItems; ++i) { -+ /* BSSID */ -+ iwEvent.cmd = SIOCGIWAP; -+ iwEvent.len = IW_EV_ADDR_LEN; -+ if ((pcCur + iwEvent.len) > pcEnd) -+ break; -+ iwEvent.u.ap_addr.sa_family = ARPHRD_ETHER; -+ ether_addr_copy(iwEvent.u.ap_addr.sa_data, prBss->arMacAddress); -+ memcpy(pcCur, &iwEvent, IW_EV_ADDR_LEN); -+ pcCur += IW_EV_ADDR_LEN; -+ -+ /* SSID */ -+ iwEvent.cmd = SIOCGIWESSID; -+ /* Modification to user space pointer(essid.pointer) is not needed. */ -+ iwEvent.u.essid.length = (__u16) prBss->rSsid.u4SsidLen; -+ iwEvent.len = IW_EV_POINT_LEN + iwEvent.u.essid.length; -+ -+ if ((pcCur + iwEvent.len) > pcEnd) -+ break; -+ iwEvent.u.essid.flags = 1; -+ iwEvent.u.essid.pointer = NULL; -+ -+#if WIRELESS_EXT <= 18 -+ memcpy(pcCur, &iwEvent, iwEvent.len); -+#else -+ memcpy(pcCur, &iwEvent, IW_EV_LCP_LEN); -+ memcpy(pcCur + IW_EV_LCP_LEN, &iwEvent.u.data.length, sizeof(struct iw_point) - IW_EV_POINT_OFF); -+#endif -+ memcpy(pcCur + IW_EV_POINT_LEN, prBss->rSsid.aucSsid, iwEvent.u.essid.length); -+ pcCur += iwEvent.len; -+ /* Frequency */ -+ iwEvent.cmd = SIOCGIWFREQ; -+ iwEvent.len = IW_EV_FREQ_LEN; -+ if ((pcCur + iwEvent.len) > pcEnd) -+ break; -+ iwEvent.u.freq.m = prBss->rConfiguration.u4DSConfig; -+ iwEvent.u.freq.e = 3; /* (in KHz) */ -+ iwEvent.u.freq.i = 0; -+ memcpy(pcCur, &iwEvent, IW_EV_FREQ_LEN); -+ pcCur += IW_EV_FREQ_LEN; -+ -+ /* Operation Mode */ -+ iwEvent.cmd = SIOCGIWMODE; -+ iwEvent.len = IW_EV_UINT_LEN; -+ if ((pcCur + iwEvent.len) > pcEnd) -+ break; -+ if (prBss->eOpMode == NET_TYPE_IBSS) -+ iwEvent.u.mode = IW_MODE_ADHOC; -+ else if (prBss->eOpMode == NET_TYPE_INFRA) -+ iwEvent.u.mode = IW_MODE_INFRA; -+ else -+ iwEvent.u.mode = IW_MODE_AUTO; -+ memcpy(pcCur, &iwEvent, IW_EV_UINT_LEN); -+ pcCur += IW_EV_UINT_LEN; -+ -+ /* Quality */ -+ iwEvent.cmd = IWEVQUAL; -+ iwEvent.len = IW_EV_QUAL_LEN; -+ if ((pcCur + iwEvent.len) > pcEnd) -+ break; -+ iwEvent.u.qual.qual = 0; /* Quality not available now */ -+ /* -100 < Rssi < -10, normalized by adding 0x100 */ -+ iwEvent.u.qual.level = 0x100 + prBss->rRssi; -+ iwEvent.u.qual.noise = 0; /* Noise not available now */ -+ iwEvent.u.qual.updated = IW_QUAL_QUAL_INVALID | IW_QUAL_LEVEL_UPDATED | IW_QUAL_NOISE_INVALID; -+ memcpy(pcCur, &iwEvent, IW_EV_QUAL_LEN); -+ pcCur += IW_EV_QUAL_LEN; -+ -+ /* Security Mode */ -+ iwEvent.cmd = SIOCGIWENCODE; -+ iwEvent.len = IW_EV_POINT_LEN; -+ if ((pcCur + iwEvent.len) > pcEnd) -+ break; -+ iwEvent.u.data.pointer = NULL; -+ iwEvent.u.data.flags = 0; -+ iwEvent.u.data.length = 0; -+ if (!prBss->u4Privacy) -+ iwEvent.u.data.flags |= IW_ENCODE_DISABLED; -+#if WIRELESS_EXT <= 18 -+ memcpy(pcCur, &iwEvent, IW_EV_POINT_LEN); -+#else -+ memcpy(pcCur, &iwEvent, IW_EV_LCP_LEN); -+ memcpy(pcCur + IW_EV_LCP_LEN, &iwEvent.u.data.length, sizeof(struct iw_point) - IW_EV_POINT_OFF); -+#endif -+ pcCur += IW_EV_POINT_LEN; -+ -+ /* rearrange rate information */ -+ u4BufIndex = sprintf(aucRatesBuf, "Rates (Mb/s):"); -+ u4HighestRate = 0; -+ for (j = 0; j < PARAM_MAX_LEN_RATES_EX; ++j) { -+ UINT_8 curRate = prBss->rSupportedRates[j] & 0x7F; -+ -+ if (curRate == 0) -+ break; -+ -+ if (curRate > u4HighestRate) -+ u4HighestRate = curRate; -+ -+ if (curRate == RATE_5_5M) -+ u4BufIndex += sprintf(aucRatesBuf + u4BufIndex, " 5.5"); -+ else -+ u4BufIndex += sprintf(aucRatesBuf + u4BufIndex, " %d", curRate / 2); -+#if DBG -+ if (u4BufIndex > sizeof(aucRatesBuf)) { -+ /* printk("rate info too long\n"); */ -+ break; -+ } -+#endif -+ } -+ /* Report Highest Rates */ -+ iwEvent.cmd = SIOCGIWRATE; -+ iwEvent.len = IW_EV_PARAM_LEN; -+ if ((pcCur + iwEvent.len) > pcEnd) -+ break; -+ iwEvent.u.bitrate.value = u4HighestRate * 500000; -+ iwEvent.u.bitrate.fixed = 0; -+ iwEvent.u.bitrate.disabled = 0; -+ iwEvent.u.bitrate.flags = 0; -+ memcpy(pcCur, &iwEvent, iwEvent.len); -+ pcCur += iwEvent.len; -+ -+#if WIRELESS_EXT >= 15 /* IWEVCUSTOM is available in WE-15 or above */ -+ /* Report Residual Rates */ -+ iwEvent.cmd = IWEVCUSTOM; -+ iwEvent.u.data.length = u4BufIndex; -+ iwEvent.len = IW_EV_POINT_LEN + iwEvent.u.data.length; -+ if ((pcCur + iwEvent.len) > pcEnd) -+ break; -+ iwEvent.u.data.flags = 0; -+#if WIRELESS_EXT <= 18 -+ memcpy(pcCur, &iwEvent, IW_EV_POINT_LEN); -+#else -+ memcpy(pcCur, &iwEvent, IW_EV_LCP_LEN); -+ memcpy(pcCur + IW_EV_LCP_LEN, &iwEvent.u.data.length, sizeof(struct iw_point) - IW_EV_POINT_OFF); -+#endif -+ memcpy(pcCur + IW_EV_POINT_LEN, aucRatesBuf, u4BufIndex); -+ pcCur += iwEvent.len; -+#endif /* WIRELESS_EXT >= 15 */ -+ -+ if (wextSrchDesiredWPAIE(&prBss->aucIEs[sizeof(PARAM_FIXED_IEs)], -+ prBss->u4IELength - sizeof(PARAM_FIXED_IEs), -+ 0xDD, (PUINT_8 *) &prDesiredIE)) { -+ iwEvent.cmd = IWEVGENIE; -+ iwEvent.u.data.flags = 1; -+ iwEvent.u.data.length = 2 + (__u16) prDesiredIE->ucLength; -+ iwEvent.len = IW_EV_POINT_LEN + iwEvent.u.data.length; -+ if ((pcCur + iwEvent.len) > pcEnd) -+ break; -+#if WIRELESS_EXT <= 18 -+ memcpy(pcCur, &iwEvent, IW_EV_POINT_LEN); -+#else -+ memcpy(pcCur, &iwEvent, IW_EV_LCP_LEN); -+ memcpy(pcCur + IW_EV_LCP_LEN, -+ &iwEvent.u.data.length, sizeof(struct iw_point) - IW_EV_POINT_OFF); -+#endif -+ memcpy(pcCur + IW_EV_POINT_LEN, prDesiredIE, 2 + prDesiredIE->ucLength); -+ pcCur += iwEvent.len; -+ } -+#if CFG_SUPPORT_WPS /* search WPS IE (0xDD, 221, OUI: 0x0050f204 ) */ -+ if (wextSrchDesiredWPSIE(&prBss->aucIEs[sizeof(PARAM_FIXED_IEs)], -+ prBss->u4IELength - sizeof(PARAM_FIXED_IEs), -+ 0xDD, (PUINT_8 *) &prDesiredIE)) { -+ iwEvent.cmd = IWEVGENIE; -+ iwEvent.u.data.flags = 1; -+ iwEvent.u.data.length = 2 + (__u16) prDesiredIE->ucLength; -+ iwEvent.len = IW_EV_POINT_LEN + iwEvent.u.data.length; -+ if ((pcCur + iwEvent.len) > pcEnd) -+ break; -+#if WIRELESS_EXT <= 18 -+ memcpy(pcCur, &iwEvent, IW_EV_POINT_LEN); -+#else -+ memcpy(pcCur, &iwEvent, IW_EV_LCP_LEN); -+ memcpy(pcCur + IW_EV_LCP_LEN, -+ &iwEvent.u.data.length, sizeof(struct iw_point) - IW_EV_POINT_OFF); -+#endif -+ memcpy(pcCur + IW_EV_POINT_LEN, prDesiredIE, 2 + prDesiredIE->ucLength); -+ pcCur += iwEvent.len; -+ } -+#endif -+ -+ /* Search RSN IE (0x30, 48). pBss->IEs starts from timestamp. */ -+ /* pBss->IEs starts from timestamp */ -+ if (wextSrchDesiredWPAIE(&prBss->aucIEs[sizeof(PARAM_FIXED_IEs)], -+ prBss->u4IELength - sizeof(PARAM_FIXED_IEs), -+ 0x30, (PUINT_8 *) &prDesiredIE)) { -+ -+ iwEvent.cmd = IWEVGENIE; -+ iwEvent.u.data.flags = 1; -+ iwEvent.u.data.length = 2 + (__u16) prDesiredIE->ucLength; -+ iwEvent.len = IW_EV_POINT_LEN + iwEvent.u.data.length; -+ if ((pcCur + iwEvent.len) > pcEnd) -+ break; -+#if WIRELESS_EXT <= 18 -+ memcpy(pcCur, &iwEvent, IW_EV_POINT_LEN); -+#else -+ memcpy(pcCur, &iwEvent, IW_EV_LCP_LEN); -+ memcpy(pcCur + IW_EV_LCP_LEN, -+ &iwEvent.u.data.length, sizeof(struct iw_point) - IW_EV_POINT_OFF); -+#endif -+ memcpy(pcCur + IW_EV_POINT_LEN, prDesiredIE, 2 + prDesiredIE->ucLength); -+ pcCur += iwEvent.len; -+ } -+#if CFG_SUPPORT_WAPI /* Android+ */ -+ if (wextSrchDesiredWAPIIE(&prBss->aucIEs[sizeof(PARAM_FIXED_IEs)], -+ prBss->u4IELength - sizeof(PARAM_FIXED_IEs), (PUINT_8 *) &prDesiredIE)) { -+ -+#if 0 -+ iwEvent.cmd = IWEVGENIE; -+ iwEvent.u.data.flags = 1; -+ iwEvent.u.data.length = 2 + (__u16) prDesiredIE->ucLength; -+ iwEvent.len = IW_EV_POINT_LEN + iwEvent.u.data.length; -+ if ((pcCur + iwEvent.len) > pcEnd) -+ break; -+#if WIRELESS_EXT <= 18 -+ memcpy(pcCur, &iwEvent, IW_EV_POINT_LEN); -+#else -+ memcpy(pcCur, &iwEvent, IW_EV_LCP_LEN); -+ memcpy(pcCur + IW_EV_LCP_LEN, -+ &iwEvent.u.data.length, sizeof(struct iw_point) - IW_EV_POINT_OFF); -+#endif -+ memcpy(pcCur + IW_EV_POINT_LEN, prDesiredIE, 2 + prDesiredIE->ucLength); -+ pcCur += iwEvent.len; -+#else -+ iwEvent.cmd = IWEVCUSTOM; -+ iwEvent.u.data.length = (2 + prDesiredIE->ucLength) * 2 + 8 /* wapi_ie= */; -+ iwEvent.len = IW_EV_POINT_LEN + iwEvent.u.data.length; -+ if ((pcCur + iwEvent.len) > pcEnd) -+ break; -+ iwEvent.u.data.flags = 1; -+ -+ memcpy(pcCur, &iwEvent, IW_EV_LCP_LEN); -+ memcpy(pcCur + IW_EV_LCP_LEN, -+ &iwEvent.u.data.length, sizeof(struct iw_point) - IW_EV_POINT_OFF); -+ -+ pcCur += (IW_EV_POINT_LEN); -+ -+ pcCur += sprintf(pcCur, "wapi_ie="); -+ -+ snprintf_hex(pcCur, pcEnd - pcCur, (UINT_8 *) prDesiredIE, prDesiredIE->ucLength + 2); -+ -+ pcCur += (2 + prDesiredIE->ucLength) * 2 /* iwEvent.len */; -+#endif -+ } -+#endif -+ /* Complete an entry. Update end of valid entry */ -+ pcValidEntryEnd = pcCur; -+ /* Extract next bss */ -+ prBss = (P_PARAM_BSSID_EX_T) ((char *)prBss + prBss->u4Length); -+ } -+ -+ /* Update valid data length for caller function and upper layer -+ * applications. -+ */ -+ prData->length = (pcValidEntryEnd - pcExtra); -+ /* printk(KERN_INFO "[wifi] buf:%d result:%ld\n", pData->length, u4BufLen); */ -+ -+ /* kalIndicateStatusAndComplete(prGlueInfo, WLAN_STATUS_SCAN_COMPLETE, NULL, 0); */ -+ -+error: -+ /* free local query buffer */ -+ if (prList) -+ kalMemFree(prList, VIR_MEM_TYPE, u4AllocBufLen); -+ -+ return ret; -+} /* wext_get_scan */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief To set desired network name ESSID. -+* -+* \param[in] prDev Net device requested. -+* \param[in] prIwrInfo NULL. -+* \param[in] prEssid Pointer of iw_point header. -+* \param[in] pcExtra Pointer to buffer srtoring essid string. -+* -+* \retval 0 If netif_carrier_ok. -+* \retval -E2BIG Essid string length is too big. -+* \retval -EINVAL pcExtra is null pointer. -+* \retval -EFAULT Driver fail to set new essid. -+* -+* \note If string length is ok, device will try connecting to the new network. -+*/ -+/*----------------------------------------------------------------------------*/ -+static int -+wext_set_essid(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwrInfo, IN struct iw_point *prEssid, IN char *pcExtra) -+{ -+ PARAM_SSID_T rNewSsid; -+ UINT_32 cipher; -+ ENUM_PARAM_ENCRYPTION_STATUS_T eEncStatus; -+ ENUM_PARAM_AUTH_MODE_T eAuthMode; -+ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ UINT_32 u4BufLen = 0; -+ -+ ASSERT(prNetDev); -+ ASSERT(prEssid); -+ ASSERT(pcExtra); -+ if (FALSE == GLUE_CHK_PR3(prNetDev, prEssid, pcExtra)) -+ return -EINVAL; -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); -+ -+ if (prEssid->length > IW_ESSID_MAX_SIZE) -+ return -E2BIG; -+ -+ /* set auth mode */ -+ if (prGlueInfo->rWpaInfo.u4WpaVersion == IW_AUTH_WPA_VERSION_DISABLED) { -+ eAuthMode = (prGlueInfo->rWpaInfo.u4AuthAlg == IW_AUTH_ALG_OPEN_SYSTEM) ? -+ AUTH_MODE_OPEN : AUTH_MODE_AUTO_SWITCH; -+ /* printk(KERN_INFO "IW_AUTH_WPA_VERSION_DISABLED->Param_AuthMode%s\n", */ -+ /* (eAuthMode == AUTH_MODE_OPEN) ? "Open" : "Shared"); */ -+ } else { -+ /* set auth mode */ -+ switch (prGlueInfo->rWpaInfo.u4KeyMgmt) { -+ case IW_AUTH_KEY_MGMT_802_1X: -+ eAuthMode = -+ (prGlueInfo->rWpaInfo.u4WpaVersion == IW_AUTH_WPA_VERSION_WPA) ? -+ AUTH_MODE_WPA : AUTH_MODE_WPA2; -+ /* printk("IW_AUTH_KEY_MGMT_802_1X->AUTH_MODE_WPA%s\n", */ -+ /* (eAuthMode == AUTH_MODE_WPA) ? "" : "2"); */ -+ break; -+ case IW_AUTH_KEY_MGMT_PSK: -+ eAuthMode = -+ (prGlueInfo->rWpaInfo.u4WpaVersion == IW_AUTH_WPA_VERSION_WPA) ? -+ AUTH_MODE_WPA_PSK : AUTH_MODE_WPA2_PSK; -+ /* printk("IW_AUTH_KEY_MGMT_PSK->AUTH_MODE_WPA%sPSK\n", */ -+ /* (eAuthMode == AUTH_MODE_WPA_PSK) ? "" : "2"); */ -+ break; -+#if CFG_SUPPORT_WAPI /* Android+ */ -+ case IW_AUTH_KEY_MGMT_WAPI_PSK: -+ break; -+ case IW_AUTH_KEY_MGMT_WAPI_CERT: -+ break; -+#endif -+ -+/* #if defined (IW_AUTH_KEY_MGMT_WPA_NONE) */ -+/* case IW_AUTH_KEY_MGMT_WPA_NONE: */ -+/* eAuthMode = AUTH_MODE_WPA_NONE; */ -+/* //printk("IW_AUTH_KEY_MGMT_WPA_NONE->AUTH_MODE_WPA_NONE\n"); */ -+/* break; */ -+/* #endif */ -+#if CFG_SUPPORT_802_11W -+ case IW_AUTH_KEY_MGMT_802_1X_SHA256: -+ eAuthMode = AUTH_MODE_WPA2; -+ break; -+ case IW_AUTH_KEY_MGMT_PSK_SHA256: -+ eAuthMode = AUTH_MODE_WPA2_PSK; -+ break; -+#endif -+ default: -+ /* printk(KERN_INFO DRV_NAME"strange IW_AUTH_KEY_MGMT : %ld set auto switch\n", */ -+ /* prGlueInfo->rWpaInfo.u4KeyMgmt); */ -+ eAuthMode = AUTH_MODE_AUTO_SWITCH; -+ break; -+ } -+ } -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetAuthMode, &eAuthMode, sizeof(eAuthMode), FALSE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ /* set encryption status */ -+ cipher = prGlueInfo->rWpaInfo.u4CipherGroup | prGlueInfo->rWpaInfo.u4CipherPairwise; -+ if (cipher & IW_AUTH_CIPHER_CCMP) { -+ /* printk("IW_AUTH_CIPHER_CCMP->ENUM_ENCRYPTION3_ENABLED\n"); */ -+ eEncStatus = ENUM_ENCRYPTION3_ENABLED; -+ } else if (cipher & IW_AUTH_CIPHER_TKIP) { -+ /* printk("IW_AUTH_CIPHER_TKIP->ENUM_ENCRYPTION2_ENABLED\n"); */ -+ eEncStatus = ENUM_ENCRYPTION2_ENABLED; -+ } else if (cipher & (IW_AUTH_CIPHER_WEP104 | IW_AUTH_CIPHER_WEP40)) { -+ /* printk("IW_AUTH_CIPHER_WEPx->ENUM_ENCRYPTION1_ENABLED\n"); */ -+ eEncStatus = ENUM_ENCRYPTION1_ENABLED; -+ } else if (cipher & IW_AUTH_CIPHER_NONE) { -+ /* printk("IW_AUTH_CIPHER_NONE->ENUM_ENCRYPTION_DISABLED\n"); */ -+ if (prGlueInfo->rWpaInfo.fgPrivacyInvoke) -+ eEncStatus = ENUM_ENCRYPTION1_ENABLED; -+ else -+ eEncStatus = ENUM_ENCRYPTION_DISABLED; -+ } else { -+ /* printk("unknown IW_AUTH_CIPHER->Param_EncryptionDisabled\n"); */ -+ eEncStatus = ENUM_ENCRYPTION_DISABLED; -+ } -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetEncryptionStatus, -+ &eEncStatus, sizeof(eEncStatus), FALSE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+#if WIRELESS_EXT < 21 -+ /* GeorgeKuo: a length error bug exists in (WE < 21) cases, kernel before -+ ** 2.6.19. Cut the trailing '\0'. -+ */ -+ rNewSsid.u4SsidLen = (prEssid->length) ? prEssid->length - 1 : 0; -+#else -+ rNewSsid.u4SsidLen = prEssid->length; -+#endif -+ kalMemCopy(rNewSsid.aucSsid, pcExtra, rNewSsid.u4SsidLen); -+ -+ /* -+ rNewSsid.aucSsid[rNewSsid.u4SsidLen] = '\0'; -+ printk("set ssid(%lu): %s\n", rNewSsid.u4SsidLen, rNewSsid.aucSsid); -+ */ -+ -+ if (kalIoctl(prGlueInfo, -+ wlanoidSetSsid, -+ (PVOID)&rNewSsid, -+ sizeof(PARAM_SSID_T), FALSE, FALSE, TRUE, FALSE, &u4BufLen) != WLAN_STATUS_SUCCESS) { -+ /* printk(KERN_WARNING "Fail to set ssid\n"); */ -+ return -EFAULT; -+ } -+ -+ return 0; -+} /* wext_set_essid */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief To get current network name ESSID. -+* -+* \param[in] prDev Net device requested. -+* \param[in] prIwrInfo NULL. -+* \param[in] prEssid Pointer to iw_point structure containing essid information. -+* \param[out] pcExtra Pointer to buffer srtoring essid string. -+* -+* \retval 0 If netif_carrier_ok. -+* \retval -ENOTCONN Otherwise. -+* -+* \note If netif_carrier_ok, network essid is stored in pcExtra. -+*/ -+/*----------------------------------------------------------------------------*/ -+/* static PARAM_SSID_T ssid; */ -+static int -+wext_get_essid(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwrInfo, IN struct iw_point *prEssid, OUT char *pcExtra) -+{ -+ /* PARAM_SSID_T ssid; */ -+ -+ P_PARAM_SSID_T prSsid; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ UINT_32 u4BufLen = 0; -+ -+ ASSERT(prNetDev); -+ ASSERT(prEssid); -+ ASSERT(pcExtra); -+ -+ if (FALSE == GLUE_CHK_PR3(prNetDev, prEssid, pcExtra)) -+ return -EINVAL; -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); -+ -+ /* if (!netif_carrier_ok(prNetDev)) { */ -+ /* return -ENOTCONN; */ -+ /* } */ -+ -+ prSsid = kalMemAlloc(sizeof(PARAM_SSID_T), VIR_MEM_TYPE); -+ -+ if (!prSsid) -+ return -ENOMEM; -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidQuerySsid, prSsid, sizeof(PARAM_SSID_T), TRUE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ if ((rStatus == WLAN_STATUS_SUCCESS) && (prSsid->u4SsidLen <= MAX_SSID_LEN)) { -+ kalMemCopy(pcExtra, prSsid->aucSsid, prSsid->u4SsidLen); -+ prEssid->length = prSsid->u4SsidLen; -+ prEssid->flags = 1; -+ } -+ -+ kalMemFree(prSsid, VIR_MEM_TYPE, sizeof(PARAM_SSID_T)); -+ -+ return 0; -+} /* wext_get_essid */ -+ -+#if 0 -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief To set tx desired bit rate. Three cases here -+* iwconfig wlan0 auto -> Set to origianl supported rate set. -+* iwconfig wlan0 18M -> Imply "fixed" case, set to 18Mbps as desired rate. -+* iwconfig wlan0 18M auto -> Set to auto rate lower and equal to 18Mbps -+* -+* \param[in] prNetDev Pointer to the net_device handler. -+* \param[in] prIwReqInfo Pointer to the Request Info. -+* \param[in] prRate Pointer to the Rate Parameter. -+* \param[in] pcExtra Pointer to the extra buffer. -+* -+* \retval 0 Update desired rate. -+* \retval -EINVAL Wrong parameter -+*/ -+/*----------------------------------------------------------------------------*/ -+int -+wext_set_rate(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwReqInfo, IN struct iw_param *prRate, IN char *pcExtra) -+{ -+ PARAM_RATES_EX aucSuppRate = { 0 }; -+ PARAM_RATES_EX aucNewRate = { 0 }; -+ UINT_32 u4NewRateLen = 0; -+ UINT_32 i; -+ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ UINT_32 u4BufLen = 0; -+ -+ ASSERT(prNetDev); -+ ASSERT(prRate); -+ if (FALSE == GLUE_CHK_PR2(prNetDev, prRate)) -+ return -EINVAL; -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); -+ -+ /* -+ printk("value = %d, fixed = %d, disable = %d, flags = %d\n", -+ prRate->value, prRate->fixed, prRate->disabled, prRate->flags); -+ */ -+ -+ rStatus = wlanQueryInformation(prGlueInfo->prAdapter, -+ wlanoidQuerySupportedRates, &aucSuppRate, sizeof(aucSuppRate), &u4BufLen); -+ -+ /* Case: AUTO */ -+ if (prRate->value < 0) { -+ if (prRate->fixed == 0) { -+ /* iwconfig wlan0 rate auto */ -+ -+ /* set full supported rate to device */ -+ /* printk("wlanoidQuerySupportedRates():u4BufLen = %ld\n", u4BufLen); */ -+ rStatus = wlanSetInformation(prGlueInfo->prAdapter, -+ wlanoidSetDesiredRates, -+ &aucSuppRate, sizeof(aucSuppRate), &u4BufLen); -+ return 0; -+ } -+ /* iwconfig wlan0 rate fixed */ -+ -+ /* fix rate to what? DO NOTHING */ -+ return -EINVAL; -+ } -+ -+ aucNewRate[0] = prRate->value / 500000; /* In unit of 500k */ -+ -+ for (i = 0; i < PARAM_MAX_LEN_RATES_EX; i++) { -+ /* check the given value is supported */ -+ if (aucSuppRate[i] == 0) -+ break; -+ -+ if (aucNewRate[0] == aucSuppRate[i]) { -+ u4NewRateLen = 1; -+ break; -+ } -+ } -+ -+ if (u4NewRateLen == 0) { -+ /* the given value is not supported */ -+ /* return error or use given rate as upper bound? */ -+ return -EINVAL; -+ } -+ -+ if (prRate->fixed == 0) { -+ /* add all rates lower than desired rate */ -+ for (i = 0; i < PARAM_MAX_LEN_RATES_EX; ++i) { -+ if (aucSuppRate[i] == 0) -+ break; -+ -+ if (aucSuppRate[i] < aucNewRate[0]) -+ aucNewRate[u4NewRateLen++] = aucSuppRate[i]; -+ } -+ } -+ -+ rStatus = wlanSetInformation(prGlueInfo->prAdapter, -+ wlanoidSetDesiredRates, &aucNewRate, sizeof(aucNewRate), &u4BufLen); -+ return 0; -+} /* wext_set_rate */ -+ -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief To get current tx bit rate. -+* -+* \param[in] prDev Net device requested. -+* \param[in] prIwrInfo NULL. -+* \param[out] prRate Pointer to iw_param structure to store current tx rate. -+* \param[in] pcExtra NULL. -+* -+* \retval 0 If netif_carrier_ok. -+* \retval -ENOTCONN Otherwise. -+* -+* \note If netif_carrier_ok, current tx rate is stored in pRate. -+*/ -+/*----------------------------------------------------------------------------*/ -+static int -+wext_get_rate(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwrInfo, OUT struct iw_param *prRate, IN char *pcExtra) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ UINT_32 u4BufLen = 0; -+ UINT_32 u4Rate = 0; -+ -+ ASSERT(prNetDev); -+ ASSERT(prRate); -+ if (FALSE == GLUE_CHK_PR2(prNetDev, prRate)) -+ return -EINVAL; -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); -+ -+ if (!netif_carrier_ok(prNetDev)) -+ return -ENOTCONN; -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidQueryLinkSpeed, &u4Rate, sizeof(u4Rate), TRUE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) -+ return -EFAULT; -+ -+ prRate->value = u4Rate * 100; /* u4Rate is in unit of 100bps */ -+ prRate->fixed = 0; -+ -+ return 0; -+} /* wext_get_rate */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief To set RTS/CTS theshold. -+* -+* \param[in] prDev Net device requested. -+* \param[in] prIwrInfo NULL. -+* \param[in] prRts Pointer to iw_param structure containing rts threshold. -+* \param[in] pcExtra NULL. -+* -+* \retval 0 For success. -+* \retval -EINVAL Given value is out of range. -+* -+* \note If given value is valid, device will follow the new setting. -+*/ -+/*----------------------------------------------------------------------------*/ -+static int -+wext_set_rts(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwrInfo, IN struct iw_param *prRts, IN char *pcExtra) -+{ -+ PARAM_RTS_THRESHOLD u4RtsThresh; -+ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ UINT_32 u4BufLen = 0; -+ -+ ASSERT(prNetDev); -+ ASSERT(prRts); -+ if (FALSE == GLUE_CHK_PR2(prNetDev, prRts)) -+ return -EINVAL; -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); -+ -+ if (prRts->disabled == 1) -+ u4RtsThresh = 2347; -+ else if (prRts->value < 0 || prRts->value > 2347) -+ return -EINVAL; -+ -+ u4RtsThresh = (PARAM_RTS_THRESHOLD) prRts->value; -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetRtsThreshold, -+ &u4RtsThresh, sizeof(u4RtsThresh), FALSE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ prRts->value = (typeof(prRts->value)) u4RtsThresh; -+ prRts->disabled = (prRts->value > 2347) ? 1 : 0; -+ prRts->fixed = 1; -+ -+ return 0; -+} /* wext_set_rts */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief To get RTS/CTS theshold. -+* -+* \param[in] prDev Net device requested. -+* \param[in] prIwrInfo NULL. -+* \param[out] prRts Pointer to iw_param structure containing rts threshold. -+* \param[in] pcExtra NULL. -+* -+* \retval 0 Success. -+* -+* \note RTS threshold is stored in pRts. -+*/ -+/*----------------------------------------------------------------------------*/ -+static int -+wext_get_rts(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwrInfo, OUT struct iw_param *prRts, IN char *pcExtra) -+{ -+ PARAM_RTS_THRESHOLD u4RtsThresh = 0; -+ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ UINT_32 u4BufLen = 0; -+ -+ ASSERT(prNetDev); -+ ASSERT(prRts); -+ if (FALSE == GLUE_CHK_PR2(prNetDev, prRts)) -+ return -EINVAL; -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidQueryRtsThreshold, -+ &u4RtsThresh, sizeof(u4RtsThresh), TRUE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ prRts->value = (typeof(prRts->value)) u4RtsThresh; -+ prRts->disabled = (prRts->value > 2347 || prRts->value < 0) ? 1 : 0; -+ prRts->fixed = 1; -+ -+ return 0; -+} /* wext_get_rts */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief To get fragmentation threshold. -+* -+* \param[in] prDev Net device requested. -+* \param[in] prIwrInfo NULL. -+* \param[out] prFrag Pointer to iw_param structure containing frag threshold. -+* \param[in] pcExtra NULL. -+* -+* \retval 0 Success. -+* -+* \note RTS threshold is stored in pFrag. Fragmentation is disabled. -+*/ -+/*----------------------------------------------------------------------------*/ -+static int -+wext_get_frag(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwrInfo, OUT struct iw_param *prFrag, IN char *pcExtra) -+{ -+ ASSERT(prFrag); -+ -+ prFrag->value = 2346; -+ prFrag->fixed = 1; -+ prFrag->disabled = 1; -+ return 0; -+} /* wext_get_frag */ -+ -+#if 1 -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief To set TX power, or enable/disable the radio. -+* -+* \param[in] prDev Net device requested. -+* \param[in] prIwrInfo NULL. -+* \param[in] prTxPow Pointer to iw_param structure containing tx power setting. -+* \param[in] pcExtra NULL. -+* -+* \retval 0 Success. -+* -+* \note Tx power is stored in pTxPow. iwconfig wlan0 txpow on/off are used -+* to enable/disable the radio. -+*/ -+/*----------------------------------------------------------------------------*/ -+ -+static int -+wext_set_txpow(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwrInfo, IN struct iw_param *prTxPow, IN char *pcExtra) -+{ -+ int ret = 0; -+ /* PARAM_DEVICE_POWER_STATE ePowerState; */ -+ ENUM_ACPI_STATE_T ePowerState; -+ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ UINT_32 u4BufLen = 0; -+ -+ ASSERT(prNetDev); -+ ASSERT(prTxPow); -+ if (FALSE == GLUE_CHK_PR2(prNetDev, prTxPow)) -+ return -EINVAL; -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); -+ -+ if (prTxPow->disabled) { -+ /* <1> disconnect */ -+ rStatus = kalIoctl(prGlueInfo, wlanoidSetDisassociate, NULL, 0, FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ if (rStatus != WLAN_STATUS_SUCCESS) -+ DBGLOG(REQ, ERROR, "######set disassoc failed\n"); -+ else -+ DBGLOG(REQ, TRACE, "######set assoc ok\n"); -+ /* <2> mark to power state flag */ -+ ePowerState = ACPI_STATE_D0; -+ DBGLOG(REQ, INFO, "set to acpi d3(0)\n"); -+ wlanSetAcpiState(prGlueInfo->prAdapter, ePowerState); -+ -+ } else { -+ ePowerState = ACPI_STATE_D0; -+ DBGLOG(REQ, INFO, "set to acpi d0\n"); -+ wlanSetAcpiState(prGlueInfo->prAdapter, ePowerState); -+ } -+ -+ prGlueInfo->ePowerState = ePowerState; -+ -+ return ret; -+} /* wext_set_txpow */ -+ -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief To get TX power. -+* -+* \param[in] prDev Net device requested. -+* \param[in] prIwrInfo NULL. -+* \param[out] prTxPow Pointer to iw_param structure containing tx power setting. -+* \param[in] pcExtra NULL. -+* -+* \retval 0 Success. -+* -+* \note Tx power is stored in pTxPow. -+*/ -+/*----------------------------------------------------------------------------*/ -+static int -+wext_get_txpow(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwrInfo, OUT struct iw_param *prTxPow, IN char *pcExtra) -+{ -+ /* PARAM_DEVICE_POWER_STATE ePowerState; */ -+ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ -+ ASSERT(prNetDev); -+ ASSERT(prTxPow); -+ if (FALSE == GLUE_CHK_PR2(prNetDev, prTxPow)) -+ return -EINVAL; -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); -+ -+ /* GeorgeKuo: wlanoidQueryAcpiDevicePowerState() reports capability, not -+ * current state. Use GLUE_INFO_T to store state. -+ */ -+ /* ePowerState = prGlueInfo->ePowerState; */ -+ -+ /* TxPow parameters: Fixed at relative 100% */ -+#if WIRELESS_EXT < 17 -+ prTxPow->flags = 0x0002; /* IW_TXPOW_RELATIVE */ -+#else -+ prTxPow->flags = IW_TXPOW_RELATIVE; -+#endif -+ prTxPow->value = 100; -+ prTxPow->fixed = 1; -+ /* prTxPow->disabled = (ePowerState != ParamDeviceStateD3) ? FALSE : TRUE; */ -+ prTxPow->disabled = TRUE; -+ -+ return 0; -+} /* wext_get_txpow */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief To get encryption cipher and key. -+* -+* \param[in] prDev Net device requested. -+* \param[in] prIwrInfo NULL. -+* \param[out] prEnc Pointer to iw_point structure containing securiry information. -+* \param[in] pcExtra Buffer to store key content. -+* -+* \retval 0 Success. -+* -+* \note Securiry information is stored in pEnc except key content. -+*/ -+/*----------------------------------------------------------------------------*/ -+static int -+wext_get_encode(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwrInfo, OUT struct iw_point *prEnc, IN char *pcExtra) -+{ -+#if 1 -+ /* ENUM_ENCRYPTION_STATUS_T eEncMode; */ -+ ENUM_PARAM_ENCRYPTION_STATUS_T eEncMode = ENUM_WEP_ENABLED; -+ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ UINT_32 u4BufLen = 0; -+ -+ ASSERT(prNetDev); -+ ASSERT(prEnc); -+ if (FALSE == GLUE_CHK_PR2(prNetDev, prEnc)) -+ return -EINVAL; -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidQueryEncryptionStatus, -+ &eEncMode, sizeof(eEncMode), TRUE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ switch (eEncMode) { -+ case ENUM_WEP_DISABLED: -+ prEnc->flags = IW_ENCODE_DISABLED; -+ break; -+ case ENUM_WEP_ENABLED: -+ prEnc->flags = IW_ENCODE_ENABLED; -+ break; -+ case ENUM_WEP_KEY_ABSENT: -+ prEnc->flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY; -+ break; -+ default: -+ prEnc->flags = IW_ENCODE_ENABLED; -+ break; -+ } -+ -+ /* Cipher, Key Content, Key ID can't be queried */ -+ prEnc->flags |= IW_ENCODE_NOKEY; -+#endif -+ return 0; -+} /* wext_get_encode */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief To set encryption cipher and key. -+* -+* \param[in] prDev Net device requested. -+* \param[in] prIwrInfo NULL. -+* \param[in] prEnc Pointer to iw_point structure containing securiry information. -+* \param[in] pcExtra Pointer to key string buffer. -+* -+* \retval 0 Success. -+* \retval -EINVAL Key ID error for WEP. -+* \retval -EFAULT Setting parameters to driver fail. -+* \retval -EOPNOTSUPP Key size not supported. -+* -+* \note Securiry information is stored in pEnc. -+*/ -+/*----------------------------------------------------------------------------*/ -+static UINT_8 wepBuf[48]; -+ -+static int -+wext_set_encode(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwrInfo, IN struct iw_point *prEnc, IN char *pcExtra) -+{ -+#if 1 -+ ENUM_PARAM_ENCRYPTION_STATUS_T eEncStatus; -+ ENUM_PARAM_AUTH_MODE_T eAuthMode; -+ /* UINT_8 wepBuf[48]; */ -+ P_PARAM_WEP_T prWepKey = (P_PARAM_WEP_T) wepBuf; -+ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ UINT_32 u4BufLen = 0; -+ -+ ASSERT(prNetDev); -+ ASSERT(prEnc); -+ ASSERT(pcExtra); -+ if (FALSE == GLUE_CHK_PR3(prNetDev, prEnc, pcExtra)) -+ return -EINVAL; -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); -+ -+ /* reset to default mode */ -+ prGlueInfo->rWpaInfo.u4WpaVersion = IW_AUTH_WPA_VERSION_DISABLED; -+ prGlueInfo->rWpaInfo.u4KeyMgmt = 0; -+ prGlueInfo->rWpaInfo.u4CipherPairwise = IW_AUTH_CIPHER_NONE; -+ prGlueInfo->rWpaInfo.u4CipherGroup = IW_AUTH_CIPHER_NONE; -+ prGlueInfo->rWpaInfo.u4AuthAlg = IW_AUTH_ALG_OPEN_SYSTEM; -+#if CFG_SUPPORT_802_11W -+ prGlueInfo->rWpaInfo.u4Mfp = IW_AUTH_MFP_DISABLED; -+#endif -+ -+ /* iwconfig wlan0 key off */ -+ if ((prEnc->flags & IW_ENCODE_MODE) == IW_ENCODE_DISABLED) { -+ eAuthMode = AUTH_MODE_OPEN; -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetAuthMode, -+ &eAuthMode, sizeof(eAuthMode), FALSE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ eEncStatus = ENUM_ENCRYPTION_DISABLED; -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetEncryptionStatus, -+ &eEncStatus, sizeof(eEncStatus), FALSE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ return 0; -+ } -+ -+ /* iwconfig wlan0 key 0123456789 */ -+ /* iwconfig wlan0 key s:abcde */ -+ /* iwconfig wlan0 key 0123456789 [1] */ -+ /* iwconfig wlan0 key 01234567890123456789012345 [1] */ -+ /* check key size for WEP */ -+ if (prEnc->length == 5 || prEnc->length == 13 || prEnc->length == 16) { -+ /* prepare PARAM_WEP key structure */ -+ prWepKey->u4KeyIndex = (prEnc->flags & IW_ENCODE_INDEX) ? (prEnc->flags & IW_ENCODE_INDEX) - 1 : 0; -+ if (prWepKey->u4KeyIndex > 3) { -+ /* key id is out of range */ -+ return -EINVAL; -+ } -+ prWepKey->u4KeyIndex |= 0x80000000; -+ prWepKey->u4Length = 12 + prEnc->length; -+ prWepKey->u4KeyLength = prEnc->length; -+ kalMemCopy(prWepKey->aucKeyMaterial, pcExtra, prEnc->length); -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetAddWep, -+ prWepKey, prWepKey->u4Length, FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ DBGLOG(REQ, ERROR, "wlanoidSetAddWep fail 0x%x\n", rStatus); -+ return -EFAULT; -+ } -+ -+ /* change to auto switch */ -+ prGlueInfo->rWpaInfo.u4AuthAlg = IW_AUTH_ALG_SHARED_KEY | IW_AUTH_ALG_OPEN_SYSTEM; -+ eAuthMode = AUTH_MODE_AUTO_SWITCH; -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetAuthMode, -+ &eAuthMode, sizeof(eAuthMode), FALSE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ /* printk(KERN_INFO DRV_NAME"wlanoidSetAuthMode fail 0x%lx\n", rStatus); */ -+ return -EFAULT; -+ } -+ -+ prGlueInfo->rWpaInfo.u4CipherPairwise = IW_AUTH_CIPHER_WEP104 | IW_AUTH_CIPHER_WEP40; -+ prGlueInfo->rWpaInfo.u4CipherGroup = IW_AUTH_CIPHER_WEP104 | IW_AUTH_CIPHER_WEP40; -+ -+ eEncStatus = ENUM_WEP_ENABLED; -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetEncryptionStatus, -+ &eEncStatus, -+ sizeof(ENUM_PARAM_ENCRYPTION_STATUS_T), FALSE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ /* printk(KERN_INFO DRV_NAME"wlanoidSetEncryptionStatus fail 0x%lx\n", rStatus); */ -+ return -EFAULT; -+ } -+ -+ return 0; -+ } -+#endif -+ return -EOPNOTSUPP; -+} /* wext_set_encode */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief To set power management. -+* -+* \param[in] prDev Net device requested. -+* \param[in] prIwrInfo NULL. -+* \param[in] prPower Pointer to iw_param structure containing tx power setting. -+* \param[in] pcExtra NULL. -+* -+* \retval 0 Success. -+* -+* \note New Power Management Mode is set to driver. -+*/ -+/*----------------------------------------------------------------------------*/ -+static int -+wext_set_power(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwrInfo, IN struct iw_param *prPower, IN char *pcExtra) -+{ -+#if 1 -+ -+ PARAM_POWER_MODE ePowerMode; -+ INT_32 i4PowerValue; -+ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ UINT_32 u4BufLen = 0; -+ -+ ASSERT(prNetDev); -+ ASSERT(prPower); -+ if (FALSE == GLUE_CHK_PR2(prNetDev, prPower)) -+ return -EINVAL; -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); -+ -+ /* printk(KERN_INFO "wext_set_power value(%d) disabled(%d) flag(0x%x)\n", */ -+ /* prPower->value, prPower->disabled, prPower->flags); */ -+ -+ if (prPower->disabled) { -+ ePowerMode = Param_PowerModeCAM; -+ } else { -+ i4PowerValue = prPower->value; -+#if WIRELESS_EXT < 21 -+ i4PowerValue /= 1000000; -+#endif -+ if (i4PowerValue == 0) { -+ ePowerMode = Param_PowerModeCAM; -+ } else if (i4PowerValue == 1) { -+ ePowerMode = Param_PowerModeMAX_PSP; -+ } else if (i4PowerValue == 2) { -+ ePowerMode = Param_PowerModeFast_PSP; -+ } else { -+ DBGLOG(REQ, ERROR, "%s(): unsupported power management mode value = %d.\n", -+ __func__, prPower->value); -+ -+ return -EINVAL; -+ } -+ } -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSet802dot11PowerSaveProfile, -+ &ePowerMode, sizeof(ePowerMode), FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ /* printk(KERN_INFO DRV_NAME"wlanoidSet802dot11PowerSaveProfile fail 0x%lx\n", rStatus); */ -+ return -EFAULT; -+ } -+#endif -+ return 0; -+} /* wext_set_power */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief To get power management. -+* -+* \param[in] prDev Net device requested. -+* \param[in] prIwrInfo NULL. -+* \param[out] prPower Pointer to iw_param structure containing tx power setting. -+* \param[in] pcExtra NULL. -+* -+* \retval 0 Success. -+* -+* \note Power management mode is stored in pTxPow->value. -+*/ -+/*----------------------------------------------------------------------------*/ -+static int -+wext_get_power(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwrInfo, OUT struct iw_param *prPower, IN char *pcExtra) -+{ -+ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ UINT_32 u4BufLen = 0; -+ PARAM_POWER_MODE ePowerMode = Param_PowerModeCAM; -+ -+ ASSERT(prNetDev); -+ ASSERT(prPower); -+ if (FALSE == GLUE_CHK_PR2(prNetDev, prPower)) -+ return -EINVAL; -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); -+ -+#if 0 -+#if defined(_HIF_SDIO) -+ rStatus = sdio_io_ctrl(prGlueInfo, -+ wlanoidQuery802dot11PowerSaveProfile, -+ &ePowerMode, sizeof(ePowerMode), TRUE, TRUE, &u4BufLen); -+#else -+ rStatus = wlanQueryInformation(prGlueInfo->prAdapter, -+ wlanoidQuery802dot11PowerSaveProfile, -+ &ePowerMode, sizeof(ePowerMode), &u4BufLen); -+#endif -+#else -+ rStatus = wlanQueryInformation(prGlueInfo->prAdapter, -+ wlanoidQuery802dot11PowerSaveProfile, -+ &ePowerMode, sizeof(ePowerMode), &u4BufLen); -+#endif -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) -+ return -EFAULT; -+ -+ prPower->value = 0; -+ prPower->disabled = 1; -+ -+ if (Param_PowerModeCAM == ePowerMode) { -+ prPower->value = 0; -+ prPower->disabled = 1; -+ } else if (Param_PowerModeMAX_PSP == ePowerMode) { -+ prPower->value = 1; -+ prPower->disabled = 0; -+ } else if (Param_PowerModeFast_PSP == ePowerMode) { -+ prPower->value = 2; -+ prPower->disabled = 0; -+ } -+ -+ prPower->flags = IW_POWER_PERIOD | IW_POWER_RELATIVE; -+#if WIRELESS_EXT < 21 -+ prPower->value *= 1000000; -+#endif -+ -+ /* printk(KERN_INFO "wext_get_power value(%d) disabled(%d) flag(0x%x)\n", */ -+ /* prPower->value, prPower->disabled, prPower->flags); */ -+ -+ return 0; -+} /* wext_get_power */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief To set authentication parameters. -+* -+* \param[in] prDev Net device requested. -+* \param[in] prIwrInfo NULL. -+* \param[in] rpAuth Pointer to iw_param structure containing authentication information. -+* \param[in] pcExtra Pointer to key string buffer. -+* -+* \retval 0 Success. -+* \retval -EINVAL Key ID error for WEP. -+* \retval -EFAULT Setting parameters to driver fail. -+* \retval -EOPNOTSUPP Key size not supported. -+* -+* \note Securiry information is stored in pEnc. -+*/ -+/*----------------------------------------------------------------------------*/ -+static int -+wext_set_auth(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwrInfo, IN struct iw_param *prAuth, IN char *pcExtra) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ -+ ASSERT(prNetDev); -+ ASSERT(prAuth); -+ if (FALSE == GLUE_CHK_PR2(prNetDev, prAuth)) -+ return -EINVAL; -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); -+ -+ /* Save information to glue info and process later when ssid is set. */ -+ switch (prAuth->flags & IW_AUTH_INDEX) { -+ case IW_AUTH_WPA_VERSION: -+#if CFG_SUPPORT_WAPI -+ if (wlanQueryWapiMode(prGlueInfo->prAdapter)) { -+ prGlueInfo->rWpaInfo.u4WpaVersion = IW_AUTH_WPA_VERSION_DISABLED; -+ prGlueInfo->rWpaInfo.u4AuthAlg = IW_AUTH_ALG_OPEN_SYSTEM; -+ } else { -+ prGlueInfo->rWpaInfo.u4WpaVersion = prAuth->value; -+ } -+#else -+ prGlueInfo->rWpaInfo.u4WpaVersion = prAuth->value; -+#endif -+ break; -+ -+ case IW_AUTH_CIPHER_PAIRWISE: -+ prGlueInfo->rWpaInfo.u4CipherPairwise = prAuth->value; -+ break; -+ -+ case IW_AUTH_CIPHER_GROUP: -+ prGlueInfo->rWpaInfo.u4CipherGroup = prAuth->value; -+ break; -+ -+ case IW_AUTH_KEY_MGMT: -+ prGlueInfo->rWpaInfo.u4KeyMgmt = prAuth->value; -+#if CFG_SUPPORT_WAPI -+ if (prGlueInfo->rWpaInfo.u4KeyMgmt == IW_AUTH_KEY_MGMT_WAPI_PSK || -+ prGlueInfo->rWpaInfo.u4KeyMgmt == IW_AUTH_KEY_MGMT_WAPI_CERT) { -+ UINT_32 u4BufLen; -+ WLAN_STATUS rStatus; -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetWapiMode, -+ &prAuth->value, sizeof(UINT_32), FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ DBGLOG(REQ, INFO, "IW_AUTH_WAPI_ENABLED :%d\n", prAuth->value); -+ } -+#endif -+ if (prGlueInfo->rWpaInfo.u4KeyMgmt == IW_AUTH_KEY_MGMT_WPS) -+ prGlueInfo->fgWpsActive = TRUE; -+ else -+ prGlueInfo->fgWpsActive = FALSE; -+ break; -+ -+ case IW_AUTH_80211_AUTH_ALG: -+ prGlueInfo->rWpaInfo.u4AuthAlg = prAuth->value; -+ break; -+ -+ case IW_AUTH_PRIVACY_INVOKED: -+ prGlueInfo->rWpaInfo.fgPrivacyInvoke = prAuth->value; -+ break; -+#if CFG_SUPPORT_802_11W -+ case IW_AUTH_MFP: -+ /* printk("wext_set_auth IW_AUTH_MFP=%d\n", prAuth->value); */ -+ prGlueInfo->rWpaInfo.u4Mfp = prAuth->value; -+ break; -+#endif -+#if CFG_SUPPORT_WAPI -+ case IW_AUTH_WAPI_ENABLED: -+ { -+ UINT_32 u4BufLen; -+ WLAN_STATUS rStatus; -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetWapiMode, -+ &prAuth->value, sizeof(UINT_32), FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ } -+ DBGLOG(REQ, INFO, "IW_AUTH_WAPI_ENABLED :%d\n", prAuth->value); -+ break; -+#endif -+ default: -+ /* -+ printk(KERN_INFO "[wifi] unsupported IW_AUTH_INDEX :%d\n", prAuth->flags); -+ */ -+ break; -+ } -+ return 0; -+} /* wext_set_auth */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief To set encryption cipher and key. -+* -+* \param[in] prDev Net device requested. -+* \param[in] prIwrInfo NULL. -+* \param[in] prEnc Pointer to iw_point structure containing securiry information. -+* \param[in] pcExtra Pointer to key string buffer. -+* -+* \retval 0 Success. -+* \retval -EINVAL Key ID error for WEP. -+* \retval -EFAULT Setting parameters to driver fail. -+* \retval -EOPNOTSUPP Key size not supported. -+* -+* \note Securiry information is stored in pEnc. -+*/ -+/*----------------------------------------------------------------------------*/ -+#if CFG_SUPPORT_WAPI -+UINT_8 keyStructBuf[320]; /* add/remove key shared buffer */ -+#else -+UINT_8 keyStructBuf[100]; /* add/remove key shared buffer */ -+#endif -+ -+static int -+wext_set_encode_ext(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwrInfo, IN struct iw_point *prEnc, IN char *pcExtra) -+{ -+ P_PARAM_REMOVE_KEY_T prRemoveKey = (P_PARAM_REMOVE_KEY_T) keyStructBuf; -+ P_PARAM_KEY_T prKey = (P_PARAM_KEY_T) keyStructBuf; -+ -+ P_PARAM_WEP_T prWepKey = (P_PARAM_WEP_T) wepBuf; -+ -+ struct iw_encode_ext *prIWEncExt = (struct iw_encode_ext *)pcExtra; -+ -+ ENUM_PARAM_ENCRYPTION_STATUS_T eEncStatus; -+ ENUM_PARAM_AUTH_MODE_T eAuthMode; -+ /* ENUM_PARAM_OP_MODE_T eOpMode = NET_TYPE_AUTO_SWITCH; */ -+ -+#if CFG_SUPPORT_WAPI -+ P_PARAM_WPI_KEY_T prWpiKey = (P_PARAM_WPI_KEY_T) keyStructBuf; -+#endif -+ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ UINT_32 u4BufLen = 0; -+ -+ ASSERT(prNetDev); -+ ASSERT(prEnc); -+ if (FALSE == GLUE_CHK_PR3(prNetDev, prEnc, pcExtra)) -+ return -EINVAL; -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); -+ -+ memset(keyStructBuf, 0, sizeof(keyStructBuf)); -+ -+#if CFG_SUPPORT_WAPI -+ if (prIWEncExt->alg == IW_ENCODE_ALG_SMS4) { -+ if (prEnc->flags & IW_ENCODE_DISABLED) { -+ /* printk(KERN_INFO "[wapi] IW_ENCODE_DISABLED\n"); */ -+ return 0; -+ } -+ /* KeyID */ -+ prWpiKey->ucKeyID = (prEnc->flags & IW_ENCODE_INDEX); -+ prWpiKey->ucKeyID--; -+ if (prWpiKey->ucKeyID > 1) { -+ /* key id is out of range */ -+ /* printk(KERN_INFO "[wapi] add key error: key_id invalid %d\n", prWpiKey->ucKeyID); */ -+ return -EINVAL; -+ } -+ -+ if (prIWEncExt->key_len != 32) { -+ /* key length not valid */ -+ /* printk(KERN_INFO "[wapi] add key error: key_len invalid %d\n", prIWEncExt->key_len); */ -+ return -EINVAL; -+ } -+ /* printk(KERN_INFO "[wapi] %d ext_flags %d\n", prEnc->flags, prIWEncExt->ext_flags); */ -+ -+ if (prIWEncExt->ext_flags & IW_ENCODE_EXT_GROUP_KEY) { -+ prWpiKey->eKeyType = ENUM_WPI_GROUP_KEY; -+ prWpiKey->eDirection = ENUM_WPI_RX; -+ } else if (prIWEncExt->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) { -+ prWpiKey->eKeyType = ENUM_WPI_PAIRWISE_KEY; -+ prWpiKey->eDirection = ENUM_WPI_RX_TX; -+ } -+ -+ /* PN */ -+ { -+ UINT_32 i; -+ -+ for (i = 0; i < IW_ENCODE_SEQ_MAX_SIZE; i++) -+ prWpiKey->aucPN[i] = prIWEncExt->tx_seq[i]; -+ for (i = 0; i < IW_ENCODE_SEQ_MAX_SIZE; i++) -+ prWpiKey->aucPN[IW_ENCODE_SEQ_MAX_SIZE + i] = prIWEncExt->rx_seq[i]; -+ } -+ -+ /* BSSID */ -+ memcpy(prWpiKey->aucAddrIndex, prIWEncExt->addr.sa_data, 6); -+ -+ memcpy(prWpiKey->aucWPIEK, prIWEncExt->key, 16); -+ prWpiKey->u4LenWPIEK = 16; -+ -+ memcpy(prWpiKey->aucWPICK, &prIWEncExt->key[16], 16); -+ prWpiKey->u4LenWPICK = 16; -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetWapiKey, -+ prWpiKey, sizeof(PARAM_WPI_KEY_T), FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ /* Do nothing */ -+ /* printk(KERN_INFO "[wapi] add key error:%lx\n", rStatus); */ -+ } -+ } else -+#endif -+ { -+ -+ if ((prEnc->flags & IW_ENCODE_MODE) == IW_ENCODE_DISABLED) { -+ prRemoveKey->u4Length = sizeof(*prRemoveKey); -+ memcpy(prRemoveKey->arBSSID, prIWEncExt->addr.sa_data, 6); -+ /* -+ printk("IW_ENCODE_DISABLED: ID:%d, Addr:[ %pM ]\n", -+ prRemoveKey->KeyIndex, prRemoveKey->BSSID); -+ */ -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetRemoveKey, -+ prRemoveKey, prRemoveKey->u4Length, FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) -+ DBGLOG(REQ, INFO, "remove key error:%x\n", rStatus); -+ return 0; -+ } -+ /* return 0; */ -+ /* printk ("alg %x\n", prIWEncExt->alg); */ -+ -+ switch (prIWEncExt->alg) { -+ case IW_ENCODE_ALG_NONE: -+ break; -+ case IW_ENCODE_ALG_WEP: -+ /* iwconfig wlan0 key 0123456789 */ -+ /* iwconfig wlan0 key s:abcde */ -+ /* iwconfig wlan0 key 0123456789 [1] */ -+ /* iwconfig wlan0 key 01234567890123456789012345 [1] */ -+ /* check key size for WEP */ -+ if (prIWEncExt->key_len == 5 || prIWEncExt->key_len == 13 || prIWEncExt->key_len == 16) { -+ /* prepare PARAM_WEP key structure */ -+ prWepKey->u4KeyIndex = (prEnc->flags & IW_ENCODE_INDEX) ? -+ (prEnc->flags & IW_ENCODE_INDEX) - 1 : 0; -+ if (prWepKey->u4KeyIndex > 3) { -+ /* key id is out of range */ -+ return -EINVAL; -+ } -+ prWepKey->u4KeyIndex |= 0x80000000; -+ prWepKey->u4Length = 12 + prIWEncExt->key_len; -+ prWepKey->u4KeyLength = prIWEncExt->key_len; -+ /* kalMemCopy(prWepKey->aucKeyMaterial, pcExtra, prIWEncExt->key_len); */ -+ kalMemCopy(prWepKey->aucKeyMaterial, prIWEncExt->key, prIWEncExt->key_len); -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetAddWep, -+ prWepKey, prWepKey->u4Length, FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ DBGLOG(REQ, ERROR, "wlanoidSetAddWep fail 0x%x\n", rStatus); -+ return -EFAULT; -+ } -+ -+ /* change to auto switch */ -+ prGlueInfo->rWpaInfo.u4AuthAlg = IW_AUTH_ALG_SHARED_KEY | IW_AUTH_ALG_OPEN_SYSTEM; -+ eAuthMode = AUTH_MODE_AUTO_SWITCH; -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetAuthMode, -+ &eAuthMode, -+ sizeof(eAuthMode), FALSE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ DBGLOG(REQ, ERROR, "wlanoidSetAuthMode fail 0x%x\n", rStatus); -+ return -EFAULT; -+ } -+ -+ prGlueInfo->rWpaInfo.u4CipherPairwise = IW_AUTH_CIPHER_WEP104 | IW_AUTH_CIPHER_WEP40; -+ prGlueInfo->rWpaInfo.u4CipherGroup = IW_AUTH_CIPHER_WEP104 | IW_AUTH_CIPHER_WEP40; -+ -+ eEncStatus = ENUM_WEP_ENABLED; -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetEncryptionStatus, -+ &eEncStatus, -+ sizeof(ENUM_PARAM_ENCRYPTION_STATUS_T), -+ FALSE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ DBGLOG(REQ, ERROR, "wlanoidSetEncryptionStatus fail 0x%x\n", rStatus); -+ return -EFAULT; -+ } -+ -+ } else { -+ DBGLOG(REQ, INFO, "key length %x\n", prIWEncExt->key_len); -+ DBGLOG(REQ, INFO, "key error\n"); -+ } -+ -+ break; -+ case IW_ENCODE_ALG_TKIP: -+ case IW_ENCODE_ALG_CCMP: -+#if CFG_SUPPORT_802_11W -+ case IW_ENCODE_ALG_AES_CMAC: -+#endif -+ { -+ -+ /* KeyID */ -+ prKey->u4KeyIndex = (prEnc->flags & IW_ENCODE_INDEX) ? -+ (prEnc->flags & IW_ENCODE_INDEX) - 1 : 0; -+#if CFG_SUPPORT_802_11W -+ if (prKey->u4KeyIndex > 5) { -+#else -+ if (prKey->u4KeyIndex > 3) { -+#endif -+ DBGLOG(REQ, ERROR, "key index error:0x%x\n", prKey->u4KeyIndex); -+ /* key id is out of range */ -+ return -EINVAL; -+ } -+ -+ /* bit(31) and bit(30) are shared by pKey and pRemoveKey */ -+ /* Tx Key Bit(31) */ -+ if (prIWEncExt->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) { -+ prKey->u4KeyIndex |= 0x1UL << 31; -+ /* Code style */ -+ } -+ /* Pairwise Key Bit(30) */ -+ if (prIWEncExt->ext_flags & IW_ENCODE_EXT_GROUP_KEY) { -+ /* Do nothing */ -+ /* group key */ -+ } else { -+ /* pairwise key */ -+ prKey->u4KeyIndex |= 0x1UL << 30; -+ } -+ } -+ /* Rx SC Bit(29) */ -+ if (prIWEncExt->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID) { -+ prKey->u4KeyIndex |= 0x1UL << 29; -+ memcpy(&prKey->rKeyRSC, prIWEncExt->rx_seq, IW_ENCODE_SEQ_MAX_SIZE); -+ } -+ -+ /* BSSID */ -+ memcpy(prKey->arBSSID, prIWEncExt->addr.sa_data, 6); -+ -+ /* switch tx/rx MIC key for sta */ -+ if (prIWEncExt->alg == IW_ENCODE_ALG_TKIP && prIWEncExt->key_len == 32) { -+ memcpy(prKey->aucKeyMaterial, prIWEncExt->key, 16); -+ memcpy(((PUINT_8) prKey->aucKeyMaterial) + 16, prIWEncExt->key + 24, 8); -+ memcpy((prKey->aucKeyMaterial) + 24, prIWEncExt->key + 16, 8); -+ } else { -+ memcpy(prKey->aucKeyMaterial, prIWEncExt->key, prIWEncExt->key_len); -+ } -+ -+ prKey->u4KeyLength = prIWEncExt->key_len; -+ prKey->u4Length = ((ULONG)&(((P_PARAM_KEY_T) 0)->aucKeyMaterial)) + prKey->u4KeyLength; -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetAddKey, -+ prKey, prKey->u4Length, FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ DBGLOG(REQ, ERROR, "add key error:%x\n", rStatus); -+ return -EFAULT; -+ } -+ break; -+ } -+ } -+ -+ return 0; -+} /* wext_set_encode_ext */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Set country code -+* -+* \param[in] prNetDev Net device requested. -+* \param[in] prData iwreq.u.data carries country code value. -+* -+* \retval 0 For success. -+* \retval -EEFAULT For fail. -+* -+* \note Country code is stored and channel list is updated based on current country domain. -+*/ -+/*----------------------------------------------------------------------------*/ -+static int wext_set_country(IN struct net_device *prNetDev, IN struct iw_point *prData) -+{ -+ P_GLUE_INFO_T prGlueInfo; -+ WLAN_STATUS rStatus; -+ UINT_32 u4BufLen; -+ UINT_8 aucCountry[2]; -+ -+ ASSERT(prNetDev); -+ -+ /* prData->pointer should be like "COUNTRY US", "COUNTRY EU" -+ * and "COUNTRY JP" -+ */ -+ if (FALSE == GLUE_CHK_PR2(prNetDev, prData) || !prData->pointer || prData->length < 10) -+ return -EINVAL; -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); -+ -+ aucCountry[0] = *((PUINT_8)prData->pointer + 8); -+ aucCountry[1] = *((PUINT_8)prData->pointer + 9); -+ -+ rStatus = kalIoctl(prGlueInfo, wlanoidSetCountryCode, &aucCountry[0], 2, FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ DBGLOG(REQ, ERROR, "Set country code error: %x\n", rStatus); -+ return -EFAULT; -+ } -+ -+ return 0; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief To report the iw private args table to user space. -+* -+* \param[in] prNetDev Net device requested. -+* \param[out] prData iwreq.u.data to carry the private args table. -+* -+* \retval 0 For success. -+* \retval -E2BIG For user's buffer size is too small. -+* \retval -EFAULT For fail. -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static int wext_get_priv(IN struct net_device *prNetDev, OUT struct iw_point *prData) -+{ -+ UINT_16 u2BufferSize = prData->length; -+ -+ /* Update our private args table size */ -+ prData->length = (__u16)sizeof(rIwPrivTable); -+ if (u2BufferSize < prData->length) -+ return -E2BIG; -+ -+ if (prData->length) { -+ if (copy_to_user(prData->pointer, rIwPrivTable, sizeof(rIwPrivTable))) -+ return -EFAULT; -+ } -+ -+ return 0; -+} /* wext_get_priv */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief ioctl() (Linux Wireless Extensions) routines -+* -+* \param[in] prDev Net device requested. -+* \param[in] ifr The ifreq structure for seeting the wireless extension. -+* \param[in] i4Cmd The wireless extension ioctl command. -+* -+* \retval zero On success. -+* \retval -EOPNOTSUPP If the cmd is not supported. -+* \retval -EFAULT If copy_to_user goes wrong. -+* \retval -EINVAL If any value's out of range. -+* -+* \note -+*/ -+/*----------------------------------------------------------------------------*/ -+int wext_support_ioctl(IN struct net_device *prDev, IN struct ifreq *prIfReq, IN int i4Cmd) -+{ -+ struct iwreq *iwr = (struct iwreq *)prIfReq; -+ struct iw_request_info rIwReqInfo; -+ int ret = 0; -+ char *prExtraBuf = NULL; -+ UINT_32 u4ExtraSize = 0; -+ P_GLUE_INFO_T prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ WLAN_STATUS rStatus; -+ UINT_32 u4BufLen; -+ P_PARAM_PMKID_T prPmkid; -+ -+ /* printk("%d CMD:0x%x\n", jiffies_to_msecs(jiffies), i4Cmd); */ -+ -+ rIwReqInfo.cmd = (__u16) i4Cmd; -+ rIwReqInfo.flags = 0; -+ -+ switch (i4Cmd) { -+ case SIOCGIWNAME: /* 0x8B01, get wireless protocol name */ -+ ret = wext_get_name(prDev, &rIwReqInfo, (char *)&iwr->u.name, NULL); -+ break; -+ -+ /* case SIOCSIWNWID: 0x8B02, deprecated */ -+ /* case SIOCGIWNWID: 0x8B03, deprecated */ -+ -+ case SIOCSIWFREQ: /* 0x8B04, set channel */ -+ ret = wext_set_freq(prDev, NULL, &iwr->u.freq, NULL); -+ break; -+ -+ case SIOCGIWFREQ: /* 0x8B05, get channel */ -+ ret = wext_get_freq(prDev, NULL, &iwr->u.freq, NULL); -+ break; -+ -+ case SIOCSIWMODE: /* 0x8B06, set operation mode */ -+ ret = wext_set_mode(prDev, NULL, &iwr->u.mode, NULL); -+ /* ret = 0; */ -+ break; -+ -+ case SIOCGIWMODE: /* 0x8B07, get operation mode */ -+ ret = wext_get_mode(prDev, NULL, &iwr->u.mode, NULL); -+ break; -+ -+ /* case SIOCSIWSENS: 0x8B08, unsupported */ -+ /* case SIOCGIWSENS: 0x8B09, unsupported */ -+ -+ /* case SIOCSIWRANGE: 0x8B0A, unused */ -+ case SIOCGIWRANGE: /* 0x8B0B, get range of parameters */ -+ if (iwr->u.data.pointer != NULL) { -+ /* Buffer size should be large enough */ -+ if (iwr->u.data.length < sizeof(struct iw_range)) { -+ ret = -E2BIG; -+ break; -+ } -+ -+ prExtraBuf = kalMemAlloc(sizeof(struct iw_range), VIR_MEM_TYPE); -+ if (!prExtraBuf) { -+ ret = -ENOMEM; -+ break; -+ } -+ -+ /* reset all fields */ -+ memset(prExtraBuf, 0, sizeof(struct iw_range)); -+ iwr->u.data.length = sizeof(struct iw_range); -+ -+ ret = wext_get_range(prDev, NULL, &iwr->u.data, prExtraBuf); -+ /* Push up to the caller */ -+ if (copy_to_user(iwr->u.data.pointer, prExtraBuf, iwr->u.data.length)) -+ ret = -EFAULT; -+ -+ kalMemFree(prExtraBuf, VIR_MEM_TYPE, sizeof(struct iw_range)); -+ prExtraBuf = NULL; -+ } else { -+ ret = -EINVAL; -+ } -+ break; -+ -+ case SIOCSIWPRIV: /* 0x8B0C, set country code */ -+ ret = wext_set_country(prDev, &iwr->u.data); -+ break; -+ -+ case SIOCGIWPRIV: /* 0x8B0D, get private args table */ -+ ret = wext_get_priv(prDev, &iwr->u.data); -+ break; -+ -+ /* case SIOCSIWSTATS: 0x8B0E, unused */ -+ /* case SIOCGIWSTATS: -+ get statistics, intercepted by wireless_process_ioctl() in wireless.c, -+ redirected to dev_iwstats(), dev->get_wireless_stats(). -+ */ -+ /* case SIOCSIWSPY: 0x8B10, unsupported */ -+ /* case SIOCGIWSPY: 0x8B11, unsupported */ -+ /* case SIOCSIWTHRSPY: 0x8B12, unsupported */ -+ /* case SIOCGIWTHRSPY: 0x8B13, unsupported */ -+ -+ case SIOCSIWAP: /* 0x8B14, set access point MAC addresses (BSSID) */ -+ if (iwr->u.ap_addr.sa_data[0] == 0 && -+ iwr->u.ap_addr.sa_data[1] == 0 && -+ iwr->u.ap_addr.sa_data[2] == 0 && -+ iwr->u.ap_addr.sa_data[3] == 0 && -+ iwr->u.ap_addr.sa_data[4] == 0 && iwr->u.ap_addr.sa_data[5] == 0) { -+ /* WPA Supplicant will set 000000000000 in -+ ** wpa_driver_wext_deinit(), do nothing here or disassoc again? -+ */ -+ ret = 0; -+ break; -+ } -+ ret = wext_set_ap(prDev, NULL, &iwr->u.ap_addr, NULL); -+ -+ break; -+ -+ case SIOCGIWAP: /* 0x8B15, get access point MAC addresses (BSSID) */ -+ ret = wext_get_ap(prDev, NULL, &iwr->u.ap_addr, NULL); -+ break; -+ -+ case SIOCSIWMLME: /* 0x8B16, request MLME operation */ -+ /* Fixed length structure */ -+ if (iwr->u.data.length != sizeof(struct iw_mlme)) { -+ DBGLOG(REQ, ERROR, "MLME buffer strange:%d\n", iwr->u.data.length); -+ ret = -EINVAL; -+ break; -+ } -+ -+ if (!iwr->u.data.pointer) { -+ ret = -EINVAL; -+ break; -+ } -+ -+ prExtraBuf = kalMemAlloc(sizeof(struct iw_mlme), VIR_MEM_TYPE); -+ if (!prExtraBuf) { -+ ret = -ENOMEM; -+ break; -+ } -+ -+ if (copy_from_user(prExtraBuf, iwr->u.data.pointer, sizeof(struct iw_mlme))) -+ ret = -EFAULT; -+ else -+ ret = wext_set_mlme(prDev, NULL, &(iwr->u.data), prExtraBuf); -+ -+ kalMemFree(prExtraBuf, VIR_MEM_TYPE, sizeof(struct iw_mlme)); -+ prExtraBuf = NULL; -+ break; -+ -+ /* case SIOCGIWAPLIST: 0x8B17, deprecated */ -+ case SIOCSIWSCAN: /* 0x8B18, scan request */ -+ if (iwr->u.data.pointer == NULL) -+ ret = wext_set_scan(prDev, NULL, NULL, NULL); -+#if WIRELESS_EXT > 17 -+ else if (iwr->u.data.length == sizeof(struct iw_scan_req)) { -+ prExtraBuf = kalMemAlloc(MAX_SSID_LEN, VIR_MEM_TYPE); -+ if (!prExtraBuf) { -+ ret = -ENOMEM; -+ break; -+ } -+ if (copy_from_user(prExtraBuf, ((struct iw_scan_req *)(iwr->u.data.pointer))->essid, -+ ((struct iw_scan_req *)(iwr->u.data.pointer))->essid_len)) { -+ ret = -EFAULT; -+ } else { -+ ret = wext_set_scan(prDev, NULL, (union iwreq_data *)&(iwr->u.data), prExtraBuf); -+ } -+ -+ kalMemFree(prExtraBuf, VIR_MEM_TYPE, MAX_SSID_LEN); -+ prExtraBuf = NULL; -+ } -+#endif -+ else -+ ret = -EINVAL; -+ break; -+#if 1 -+ case SIOCGIWSCAN: /* 0x8B19, get scan results */ -+ if (!iwr->u.data.pointer || !iwr->u.essid.pointer) { -+ ret = -EINVAL; -+ break; -+ } -+ -+ u4ExtraSize = iwr->u.data.length; -+ /* allocate the same size of kernel buffer to store scan results. */ -+ prExtraBuf = kalMemAlloc(u4ExtraSize, VIR_MEM_TYPE); -+ if (!prExtraBuf) { -+ ret = -ENOMEM; -+ break; -+ } -+ -+ /* iwr->u.data.length may be updated by wext_get_scan() */ -+ ret = wext_get_scan(prDev, NULL, &iwr->u.data, prExtraBuf); -+ if (ret != 0) { -+ if (ret == -E2BIG) -+ DBGLOG(REQ, WARN, "[wifi] wext_get_scan -E2BIG\n"); -+ } else { -+ /* check updated length is valid */ -+ ASSERT(iwr->u.data.length <= u4ExtraSize); -+ if (iwr->u.data.length > u4ExtraSize) { -+ DBGLOG(REQ, INFO, "Updated result length is larger than allocated (%d > %u)\n", -+ iwr->u.data.length, u4ExtraSize); -+ iwr->u.data.length = u4ExtraSize; -+ } -+ -+ if (copy_to_user(iwr->u.data.pointer, prExtraBuf, iwr->u.data.length)) -+ ret = -EFAULT; -+ } -+ -+ kalMemFree(prExtraBuf, VIR_MEM_TYPE, u4ExtraSize); -+ prExtraBuf = NULL; -+ -+ break; -+ -+#endif -+ -+#if 1 -+ case SIOCSIWESSID: /* 0x8B1A, set SSID (network name) */ -+ if (iwr->u.essid.length > IW_ESSID_MAX_SIZE) { -+ ret = -E2BIG; -+ break; -+ } -+ if (!iwr->u.essid.pointer) { -+ ret = -EINVAL; -+ break; -+ } -+ -+ prExtraBuf = kalMemAlloc(IW_ESSID_MAX_SIZE + 4, VIR_MEM_TYPE); -+ if (!prExtraBuf) { -+ ret = -ENOMEM; -+ break; -+ } -+ -+ if (copy_from_user(prExtraBuf, iwr->u.essid.pointer, iwr->u.essid.length)) { -+ ret = -EFAULT; -+ } else { -+ /* Add trailing '\0' for printk */ -+ /* prExtraBuf[iwr->u.essid.length] = 0; */ -+ /* printk(KERN_INFO "wext_set_essid: %s (%d)\n", prExtraBuf, iwr->u.essid.length); */ -+ ret = wext_set_essid(prDev, NULL, &iwr->u.essid, prExtraBuf); -+ /* printk ("set essid %d\n", ret); */ -+ } -+ -+ kalMemFree(prExtraBuf, VIR_MEM_TYPE, IW_ESSID_MAX_SIZE + 4); -+ prExtraBuf = NULL; -+ break; -+ -+#endif -+ -+ case SIOCGIWESSID: /* 0x8B1B, get SSID */ -+ if (!iwr->u.essid.pointer) { -+ ret = -EINVAL; -+ break; -+ } -+ -+ if (iwr->u.essid.length < IW_ESSID_MAX_SIZE) { -+ DBGLOG(REQ, ERROR, "[wifi] iwr->u.essid.length:%d too small\n", iwr->u.essid.length); -+ ret = -E2BIG; /* let caller try larger buffer */ -+ break; -+ } -+ -+ prExtraBuf = kalMemAlloc(IW_ESSID_MAX_SIZE, VIR_MEM_TYPE); -+ if (!prExtraBuf) { -+ ret = -ENOMEM; -+ break; -+ } -+ -+ /* iwr->u.essid.length is updated by wext_get_essid() */ -+ -+ ret = wext_get_essid(prDev, NULL, &iwr->u.essid, prExtraBuf); -+ if (ret == 0) { -+ if (copy_to_user(iwr->u.essid.pointer, prExtraBuf, iwr->u.essid.length)) -+ ret = -EFAULT; -+ } -+ -+ kalMemFree(prExtraBuf, VIR_MEM_TYPE, IW_ESSID_MAX_SIZE); -+ prExtraBuf = NULL; -+ -+ break; -+ -+ /* case SIOCSIWNICKN: 0x8B1C, not supported */ -+ /* case SIOCGIWNICKN: 0x8B1D, not supported */ -+ -+ case SIOCSIWRATE: /* 0x8B20, set default bit rate (bps) */ -+ /* ret = wext_set_rate(prDev, &rIwReqInfo, &iwr->u.bitrate, NULL); */ -+ break; -+ -+ case SIOCGIWRATE: /* 0x8B21, get current bit rate (bps) */ -+ ret = wext_get_rate(prDev, NULL, &iwr->u.bitrate, NULL); -+ break; -+ -+ case SIOCSIWRTS: /* 0x8B22, set rts/cts threshold */ -+ ret = wext_set_rts(prDev, NULL, &iwr->u.rts, NULL); -+ break; -+ -+ case SIOCGIWRTS: /* 0x8B23, get rts/cts threshold */ -+ ret = wext_get_rts(prDev, NULL, &iwr->u.rts, NULL); -+ break; -+ -+ /* case SIOCSIWFRAG: 0x8B24, unsupported */ -+ case SIOCGIWFRAG: /* 0x8B25, get frag threshold */ -+ ret = wext_get_frag(prDev, NULL, &iwr->u.frag, NULL); -+ break; -+ -+ case SIOCSIWTXPOW: /* 0x8B26, set relative tx power (in %) */ -+ ret = wext_set_txpow(prDev, NULL, &iwr->u.txpower, NULL); -+ break; -+ -+ case SIOCGIWTXPOW: /* 0x8B27, get relative tx power (in %) */ -+ ret = wext_get_txpow(prDev, NULL, &iwr->u.txpower, NULL); -+ break; -+ -+ /* case SIOCSIWRETRY: 0x8B28, unsupported */ -+ /* case SIOCGIWRETRY: 0x8B29, unsupported */ -+ -+#if 1 -+ case SIOCSIWENCODE: /* 0x8B2A, set encoding token & mode */ -+ /* Only DISABLED case has NULL pointer and length == 0 */ -+ if (iwr->u.encoding.pointer) { -+ if (iwr->u.encoding.length > 16) { -+ ret = -E2BIG; -+ break; -+ } -+ -+ u4ExtraSize = iwr->u.encoding.length; -+ prExtraBuf = kalMemAlloc(u4ExtraSize, VIR_MEM_TYPE); -+ if (!prExtraBuf) { -+ ret = -ENOMEM; -+ break; -+ } -+ -+ if (copy_from_user(prExtraBuf, iwr->u.encoding.pointer, iwr->u.encoding.length)) -+ ret = -EFAULT; -+ } else if (iwr->u.encoding.length != 0) { -+ ret = -EINVAL; -+ break; -+ } -+ -+ if (ret == 0) -+ ret = wext_set_encode(prDev, NULL, &iwr->u.encoding, prExtraBuf); -+ -+ if (prExtraBuf) { -+ kalMemFree(prExtraBuf, VIR_MEM_TYPE, u4ExtraSize); -+ prExtraBuf = NULL; -+ } -+ break; -+ -+ case SIOCGIWENCODE: /* 0x8B2B, get encoding token & mode */ -+ /* check pointer */ -+ ret = wext_get_encode(prDev, NULL, &iwr->u.encoding, NULL); -+ break; -+ -+ case SIOCSIWPOWER: /* 0x8B2C, set power management */ -+ ret = wext_set_power(prDev, NULL, &iwr->u.power, NULL); -+ break; -+ -+ case SIOCGIWPOWER: /* 0x8B2D, get power management */ -+ ret = wext_get_power(prDev, NULL, &iwr->u.power, NULL); -+ break; -+ -+#if WIRELESS_EXT > 17 -+ case SIOCSIWGENIE: /* 0x8B30, set gen ie */ -+ if (iwr->u.data.pointer == NULL) -+ break; -+ -+ if (0 /* wlanQueryWapiMode(prGlueInfo->prAdapter) */) -+ break; -+ -+ /* Fixed length structure */ -+#if CFG_SUPPORT_WAPI -+ if (iwr->u.data.length > 42 /* The max wapi ie buffer */) { -+ ret = -EINVAL; -+ break; -+ } -+#endif -+ u4ExtraSize = iwr->u.data.length; -+ if (u4ExtraSize == 0) -+ break; -+ -+ prExtraBuf = kalMemAlloc(u4ExtraSize, VIR_MEM_TYPE); -+ if (!prExtraBuf) { -+ ret = -ENOMEM; -+ break; -+ } -+ if (copy_from_user(prExtraBuf, iwr->u.data.pointer, iwr->u.data.length)) { -+ ret = -EFAULT; -+ } else { -+#if CFG_SUPPORT_WAPI -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetWapiAssocInfo, -+ prExtraBuf, -+ u4ExtraSize, FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ /* printk(KERN_INFO "[wapi] set wapi assoc info error:%lx\n", -+ rStatus); */ -+#endif -+#if CFG_SUPPORT_WPS2 -+ PUINT_8 prDesiredIE = NULL; -+ -+ if (wextSrchDesiredWPSIE(prExtraBuf, -+ u4ExtraSize, -+ 0xDD, (PUINT_8 *) &prDesiredIE)) { -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetWSCAssocInfo, -+ prDesiredIE, -+ IE_SIZE(prDesiredIE), -+ FALSE, -+ FALSE, TRUE, FALSE, &u4BufLen); -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ /* printk(KERN_INFO "[WSC] set WSC assoc info -+ error:%lx\n", rStatus); */ -+ } -+ } -+#endif -+#if CFG_SUPPORT_WAPI -+ } -+#endif -+ } -+ kalMemFree(prExtraBuf, VIR_MEM_TYPE, u4ExtraSize); -+ prExtraBuf = NULL; -+ break; -+ -+ case SIOCGIWGENIE: /* 0x8B31, get gen ie, unused */ -+ break; -+ -+#endif -+ -+ case SIOCSIWAUTH: /* 0x8B32, set auth mode params */ -+ ret = wext_set_auth(prDev, NULL, &iwr->u.param, NULL); -+ break; -+ -+ /* case SIOCGIWAUTH: 0x8B33, unused? */ -+ case SIOCSIWENCODEEXT: /* 0x8B34, set extended encoding token & mode */ -+ if (iwr->u.encoding.pointer) { -+ u4ExtraSize = iwr->u.encoding.length; -+ prExtraBuf = kalMemAlloc(u4ExtraSize, VIR_MEM_TYPE); -+ if (!prExtraBuf) { -+ ret = -ENOMEM; -+ break; -+ } -+ -+ if (copy_from_user(prExtraBuf, iwr->u.encoding.pointer, iwr->u.encoding.length)) -+ ret = -EFAULT; -+ } else if (iwr->u.encoding.length != 0) { -+ ret = -EINVAL; -+ break; -+ } -+ -+ if (ret == 0) -+ ret = wext_set_encode_ext(prDev, NULL, &iwr->u.encoding, prExtraBuf); -+ -+ if (prExtraBuf) { -+ kalMemFree(prExtraBuf, VIR_MEM_TYPE, u4ExtraSize); -+ prExtraBuf = NULL; -+ } -+ break; -+ -+ /* case SIOCGIWENCODEEXT: 0x8B35, unused? */ -+ -+ case SIOCSIWPMKSA: /* 0x8B36, pmksa cache operation */ -+#if 1 -+ if (iwr->u.data.pointer) { -+ /* Fixed length structure */ -+ if (iwr->u.data.length != sizeof(struct iw_pmksa)) { -+ ret = -EINVAL; -+ break; -+ } -+ -+ u4ExtraSize = sizeof(struct iw_pmksa); -+ prExtraBuf = kalMemAlloc(u4ExtraSize, VIR_MEM_TYPE); -+ if (!prExtraBuf) { -+ ret = -ENOMEM; -+ break; -+ } -+ -+ if (copy_from_user(prExtraBuf, iwr->u.data.pointer, sizeof(struct iw_pmksa))) { -+ ret = -EFAULT; -+ } else { -+ switch (((struct iw_pmksa *)prExtraBuf)->cmd) { -+ case IW_PMKSA_ADD: -+ /* -+ printk(KERN_INFO "IW_PMKSA_ADD [ %pM ]\n", -+ (((struct iw_pmksa *)pExtraBuf)->bssid.sa_data)); -+ */ -+ prPmkid = -+ (P_PARAM_PMKID_T) kalMemAlloc(8 + sizeof(PARAM_BSSID_INFO_T), -+ VIR_MEM_TYPE); -+ if (!prPmkid) { -+ DBGLOG(REQ, ERROR, "Can not alloc memory for IW_PMKSA_ADD\n"); -+ ret = -ENOMEM; -+ break; -+ } -+ -+ prPmkid->u4Length = 8 + sizeof(PARAM_BSSID_INFO_T); -+ prPmkid->u4BSSIDInfoCount = 1; -+ kalMemCopy(prPmkid->arBSSIDInfo->arBSSID, -+ ((struct iw_pmksa *)prExtraBuf)->bssid.sa_data, 6); -+ kalMemCopy(prPmkid->arBSSIDInfo->arPMKID, -+ ((struct iw_pmksa *)prExtraBuf)->pmkid, IW_PMKID_LEN); -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetPmkid, -+ prPmkid, -+ sizeof(PARAM_PMKID_T), -+ FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) -+ DBGLOG(REQ, ERROR, "add pmkid error:%x\n", rStatus); -+ kalMemFree(prPmkid, VIR_MEM_TYPE, 8 + sizeof(PARAM_BSSID_INFO_T)); -+ break; -+ case IW_PMKSA_REMOVE: -+ /* -+ printk(KERN_INFO "IW_PMKSA_REMOVE [ %pM ]\n", -+ (((struct iw_pmksa *)buf)->bssid.sa_data)); -+ */ -+ break; -+ case IW_PMKSA_FLUSH: -+ /* -+ printk(KERN_INFO "IW_PMKSA_FLUSH\n"); -+ */ -+ prPmkid = (P_PARAM_PMKID_T) kalMemAlloc(8, VIR_MEM_TYPE); -+ if (!prPmkid) { -+ DBGLOG(REQ, ERROR, -+ "Can not alloc memory for IW_PMKSA_FLUSH\n"); -+ ret = -ENOMEM; -+ break; -+ } -+ -+ prPmkid->u4Length = 8; -+ prPmkid->u4BSSIDInfoCount = 0; -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetPmkid, -+ prPmkid, -+ sizeof(PARAM_PMKID_T), -+ FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) -+ DBGLOG(REQ, ERROR, "flush pmkid error:%x\n", rStatus); -+ kalMemFree(prPmkid, VIR_MEM_TYPE, 8); -+ break; -+ default: -+ DBGLOG(REQ, WARN, "UNKNOWN iw_pmksa command:%d\n", -+ ((struct iw_pmksa *)prExtraBuf)->cmd); -+ ret = -EFAULT; -+ break; -+ } -+ } -+ -+ if (prExtraBuf) { -+ kalMemFree(prExtraBuf, VIR_MEM_TYPE, u4ExtraSize); -+ prExtraBuf = NULL; -+ } -+ } else if (iwr->u.data.length != 0) { -+ ret = -EINVAL; -+ break; -+ } -+#endif -+ break; -+ -+#endif -+ -+ default: -+ /* printk(KERN_NOTICE "unsupported IOCTL: 0x%x\n", i4Cmd); */ -+ ret = -EOPNOTSUPP; -+ break; -+ } -+ -+ /* printk("%ld CMD:0x%x ret:%d\n", jiffies_to_msecs(jiffies), i4Cmd, ret); */ -+ -+ return ret; -+} /* wext_support_ioctl */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief To send an event (RAW socket pacekt) to user process actively. -+* -+* \param[in] prGlueInfo Glue layer info. -+* \param[in] u4cmd Whcih event command we want to indicate to user process. -+* \param[in] pData Data buffer to be indicated. -+* \param[in] dataLen Available data size in pData. -+* -+* \return (none) -+* -+* \note Event is indicated to upper layer if cmd is supported and data is valid. -+* Using of kernel symbol wireless_send_event(), which is defined in -+* after WE-14 (2.4.20). -+*/ -+/*----------------------------------------------------------------------------*/ -+void -+wext_indicate_wext_event(IN P_GLUE_INFO_T prGlueInfo, -+ IN unsigned int u4Cmd, IN unsigned char *pucData, IN unsigned int u4dataLen) -+{ -+ union iwreq_data wrqu; -+ unsigned char *pucExtraInfo = NULL; -+#if WIRELESS_EXT >= 15 -+ unsigned char *pucDesiredIE = NULL; -+ unsigned char aucExtraInfoBuf[200]; -+#endif -+#if WIRELESS_EXT < 18 -+ int i; -+#endif -+ -+ memset(&wrqu, 0, sizeof(wrqu)); -+ -+ switch (u4Cmd) { -+ case SIOCGIWTXPOW: -+ memcpy(&wrqu.power, pucData, u4dataLen); -+ break; -+ case SIOCGIWSCAN: -+ complete_all(&prGlueInfo->rScanComp); -+ break; -+ -+ case SIOCGIWAP: -+ if (pucData) -+ ether_addr_copy((u8 *)&(wrqu.ap_addr.sa_data), pucData); -+ /*memcpy(&wrqu.ap_addr.sa_data, pucData, ETH_ALEN);*/ -+ else -+ memset(&wrqu.ap_addr.sa_data, 0, ETH_ALEN); -+ break; -+ -+ case IWEVASSOCREQIE: -+#if WIRELESS_EXT < 15 -+ /* under WE-15, no suitable Event can be used */ -+ goto skip_indicate_event; -+#else -+ /* do supplicant a favor, parse to the start of WPA/RSN IE */ -+ if (wextSrchDesiredWPAIE(pucData, u4dataLen, 0x30, &pucDesiredIE)) { -+ /* RSN IE found */ -+ /* Do nothing */ -+#if 0 -+ } else if (wextSrchDesiredWPSIE(pucData, u4dataLen, 0xDD, &pucDesiredIE)) { -+ /* WPS IE found */ -+ /* Do nothing */ -+#endif -+ } else if (wextSrchDesiredWPAIE(pucData, u4dataLen, 0xDD, &pucDesiredIE)) { -+ /* WPA IE found */ -+ /* Do nothing*/ -+#if CFG_SUPPORT_WAPI /* Android+ */ -+ } else if (wextSrchDesiredWAPIIE(pucData, u4dataLen, &pucDesiredIE)) { -+ /* WAPI IE found */ -+ /* printk("wextSrchDesiredWAPIIE!!\n"); */ -+#endif -+ } else { -+ /* no WPA/RSN IE found, skip this event */ -+ goto skip_indicate_event; -+ } -+#if WIRELESS_EXT < 18 -+ /* under WE-18, only IWEVCUSTOM can be used */ -+ u4Cmd = IWEVCUSTOM; -+ pucExtraInfo = aucExtraInfoBuf; -+ pucExtraInfo += sprintf(pucExtraInfo, "ASSOCINFO(ReqIEs="); -+ /* printk(KERN_DEBUG "assoc info buffer size needed:%d\n", infoElemLen * 2 + 17); */ -+ /* translate binary string to hex string, requirement of IWEVCUSTOM */ -+ for (i = 0; i < pucDesiredIE[1] + 2; ++i) -+ pucExtraInfo += sprintf(pucExtraInfo, "%02x", pucDesiredIE[i]); -+ pucExtraInfo = aucExtraInfoBuf; -+ wrqu.data.length = 17 + (pucDesiredIE[1] + 2) * 2; -+#else -+ /* IWEVASSOCREQIE, indicate binary string */ -+ pucExtraInfo = pucDesiredIE; -+ wrqu.data.length = pucDesiredIE[1] + 2; -+#endif -+#endif /* WIRELESS_EXT < 15 */ -+ break; -+ -+ case IWEVMICHAELMICFAILURE: -+#if WIRELESS_EXT < 15 -+ /* under WE-15, no suitable Event can be used */ -+ goto skip_indicate_event; -+#else -+ if (pucData) { -+ P_PARAM_AUTH_REQUEST_T pAuthReq = (P_PARAM_AUTH_REQUEST_T) pucData; -+ /* under WE-18, only IWEVCUSTOM can be used */ -+ u4Cmd = IWEVCUSTOM; -+ pucExtraInfo = aucExtraInfoBuf; -+ pucExtraInfo += sprintf(pucExtraInfo, "MLME-MICHAELMICFAILURE.indication "); -+ pucExtraInfo += sprintf(pucExtraInfo, -+ "%s", -+ (pAuthReq->u4Flags == PARAM_AUTH_REQUEST_GROUP_ERROR) ? -+ "groupcast " : "unicast "); -+ -+ wrqu.data.length = pucExtraInfo - aucExtraInfoBuf; -+ pucExtraInfo = aucExtraInfoBuf; -+ } -+#endif /* WIRELESS_EXT < 15 */ -+ break; -+ -+ case IWEVPMKIDCAND: -+ if (prGlueInfo->rWpaInfo.u4WpaVersion == IW_AUTH_WPA_VERSION_WPA2 && -+ prGlueInfo->rWpaInfo.u4KeyMgmt == IW_AUTH_KEY_MGMT_802_1X) { -+ -+ /* only used in WPA2 */ -+#if WIRELESS_EXT >= 18 -+ P_PARAM_PMKID_CANDIDATE_T prPmkidCand = (P_PARAM_PMKID_CANDIDATE_T) pucData; -+ -+ struct iw_pmkid_cand rPmkidCand; -+ -+ pucExtraInfo = aucExtraInfoBuf; -+ -+ rPmkidCand.flags = prPmkidCand->u4Flags; -+ rPmkidCand.index = 0; -+ rPmkidCand.bssid.sa_family = 0; -+ kalMemCopy(rPmkidCand.bssid.sa_data, prPmkidCand->arBSSID, 6); -+ -+ kalMemCopy(pucExtraInfo, (PUINT_8) &rPmkidCand, sizeof(struct iw_pmkid_cand)); -+ wrqu.data.length = sizeof(struct iw_pmkid_cand); -+ -+ /* pmkid canadidate list is supported after WE-18 */ -+ /* indicate struct iw_pmkid_cand */ -+#else -+ /* printk(KERN_INFO "IWEVPMKIDCAND event skipped, WE < 18\n"); */ -+ goto skip_indicate_event; -+#endif -+ } else { -+ /* printk(KERN_INFO "IWEVPMKIDCAND event skipped, NOT WPA2\n"); */ -+ goto skip_indicate_event; -+ } -+ break; -+ -+ case IWEVCUSTOM: -+ u4Cmd = IWEVCUSTOM; -+ pucExtraInfo = aucExtraInfoBuf; -+ kalMemCopy(pucExtraInfo, pucData, sizeof(PTA_IPC_T)); -+ wrqu.data.length = sizeof(PTA_IPC_T); -+ break; -+ -+ default: -+ /* printk(KERN_INFO "Unsupported wext event:%x\n", cmd); */ -+ goto skip_indicate_event; -+ } -+ -+ /* Send event to user space */ -+ wireless_send_event(prGlueInfo->prDevHandler, u4Cmd, &wrqu, pucExtraInfo); -+ -+skip_indicate_event: -+ return; -+} /* wext_indicate_wext_event */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief A method of struct net_device, to get the network interface statistical -+* information. -+* -+* Whenever an application needs to get statistics for the interface, this method -+* is called. This happens, for example, when ifconfig or netstat -i is run. -+* -+* \param[in] pDev Pointer to struct net_device. -+* -+* \return net_device_stats buffer pointer. -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+struct iw_statistics *wext_get_wireless_stats(struct net_device *prDev) -+{ -+ -+ WLAN_STATUS rStatus = WLAN_STATUS_FAILURE; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ struct iw_statistics *pStats = NULL; -+ INT_32 i4Rssi; -+ UINT_32 bufLen = 0; -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ ASSERT(prGlueInfo); -+ if (!prGlueInfo) -+ goto stat_out; -+ -+ pStats = (struct iw_statistics *)(&(prGlueInfo->rIwStats)); -+ -+ if (!prDev || !netif_carrier_ok(prDev)) { -+ /* network not connected */ -+ goto stat_out; -+ } -+ -+ rStatus = kalIoctl(prGlueInfo, wlanoidQueryRssi, &i4Rssi, sizeof(i4Rssi), TRUE, TRUE, TRUE, FALSE, &bufLen); -+ -+stat_out: -+ return pStats; -+} /* wlan_get_wireless_stats */ -+ -+ -+#endif /* WIRELESS_EXT */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_wext_priv.c b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_wext_priv.c -new file mode 100644 -index 000000000000..2b6c3df84594 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_wext_priv.c -@@ -0,0 +1,3142 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux/gl_wext_priv.c#4 -+*/ -+ -+/*! \file gl_wext_priv.c -+ \brief This file includes private ioctl support. -+*/ -+ -+/* -+** Log: gl_wext_priv.c -+ * -+ * 07 17 2012 yuche.tsai -+ * NULL -+ * Let netdev bring up. -+ * -+ * 06 13 2012 yuche.tsai -+ * NULL -+ * Update maintrunk driver. -+ * Add support for driver compose assoc request frame. -+ * -+ * 03 20 2012 wh.su -+ * [WCXRP00001153] [MT6620 Wi-Fi][Driver] Adding the get_ch_list and set_tx_power proto type function -+ * [WCXRP00001202] [MT6628 Wi-Fi][FW] Adding the New PN init code -+ * use return to avoid the ioctl return not supported -+ * -+ * 03 02 2012 terry.wu -+ * NULL -+ * Snc CFG80211 modification for ICS migration from branch 2.2. -+ * -+ * 01 16 2012 wh.su -+ * [WCXRP00001170] [MT6620 Wi-Fi][Driver] Adding the related code for set/get band ioctl -+ * Adding the template code for set / get band IOCTL (with ICS supplicant_6).. -+ * -+ * 01 05 2012 wh.su -+ * [WCXRP00001153] [MT6620 Wi-Fi][Driver] Adding the get_ch_list and set_tx_power proto type function -+ * Adding the related ioctl / wlan oid function to set the Tx power cfg. -+ * -+ * 01 02 2012 wh.su -+ * [WCXRP00001153] [MT6620 Wi-Fi][Driver] Adding the get_ch_list and set_tx_power proto type function -+ * Adding the proto type function for set_int set_tx_power and get int get_ch_list. -+ * -+ * 11 10 2011 cp.wu -+ * [WCXRP00001098] [MT6620 Wi-Fi][Driver] Replace printk by DBG LOG macros in linux porting layer -+ * 1. eliminaite direct calls to printk in porting layer. -+ * 2. replaced by DBGLOG, which would be XLOG on ALPS platforms. -+ * -+ * 11 02 2011 chinghwa.yu -+ * [WCXRP00000063] Update BCM CoEx design and settings -+ * Fixed typo. -+ * -+ * 09 20 2011 chinglan.wang -+ * [WCXRP00000989] [WiFi Direct] [Driver] Add a new io control API to start the formation for the sigma test. -+ * . -+ * -+ * 07 28 2011 chinghwa.yu -+ * [WCXRP00000063] Update BCM CoEx design and settings -+ * Add BWCS cmd and event. -+ * -+ * 07 18 2011 chinghwa.yu -+ * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm -+ * Add CMD/Event for RDD and BWCS. -+ * -+ * 03 17 2011 chinglan.wang -+ * [WCXRP00000570] [MT6620 Wi-Fi][Driver] Add Wi-Fi Protected Setup v2.0 feature -+ * . -+ * -+ * 03 07 2011 terry.wu -+ * [WCXRP00000521] [MT6620 Wi-Fi][Driver] Remove non-standard debug message -+ * Toggle non-standard debug messages to comments. -+ * -+ * 01 27 2011 cm.chang -+ * [WCXRP00000402] [MT6620 Wi-Fi][Driver] Enable MCR read/write by iwpriv by default -+ * . -+ * -+ * 01 26 2011 wh.su -+ * [WCXRP00000396] [MT6620 Wi-Fi][Driver] Support Sw Ctrl ioctl at linux -+ * adding the SW cmd ioctl support, use set/get structure ioctl. -+ * -+ * 01 20 2011 eddie.chen -+ * [WCXRP00000374] [MT6620 Wi-Fi][DRV] SW debug control -+ * Adjust OID order. -+ * -+ * 01 20 2011 eddie.chen -+ * [WCXRP00000374] [MT6620 Wi-Fi][DRV] SW debug control -+ * Add Oid for sw control debug command -+ * -+ * 01 07 2011 cm.chang -+ * [WCXRP00000336] [MT6620 Wi-Fi][Driver] Add test mode commands in normal phone operation -+ * Add a new compiling option to control if MCR read/write is permitted -+ * -+ * 12 31 2010 cm.chang -+ * [WCXRP00000336] [MT6620 Wi-Fi][Driver] Add test mode commands in normal phone operation -+ * Add some iwpriv commands to support test mode operation -+ * -+ * 12 15 2010 george.huang -+ * [WCXRP00000152] [MT6620 Wi-Fi] AP mode power saving function -+ * Support set PS profile and set WMM-PS related iwpriv. -+ * -+ * 11 08 2010 wh.su -+ * [WCXRP00000171] [MT6620 Wi-Fi][Driver] Add message check code same behavior as mt5921 -+ * add the message check code from mt5921. -+ * -+ * 10 18 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check -+ * [WCXRP00000086] [MT6620 Wi-Fi][Driver] The mac address is all zero at android -+ * complete implementation of Android NVRAM access -+ * -+ * 09 24 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check -+ * correct typo for NVRAM access. -+ * -+ * 09 23 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check -+ * add skeleton for NVRAM integration -+ * -+ * 08 04 2010 cp.wu -+ * NULL -+ * revert changelist #15371, efuse read/write access will be done by RF test approach -+ * -+ * 08 04 2010 cp.wu -+ * NULL -+ * add OID definitions for EFUSE read/write access. -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 06 01 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * enable OID_CUSTOM_MTK_WIFI_TEST for RFTest & META tool -+ * -+ * 05 29 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * fix private ioctl for rftest -+ * -+ * 04 21 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * add for private ioctl support -+** \main\maintrunk.MT5921\32 2009-10-08 10:33:25 GMT mtk01090 -+** Avoid accessing private data of net_device directly. Replace with netdev_priv(). Add more checking for input -+** parameters and pointers. -+** \main\maintrunk.MT5921\31 2009-09-29 16:46:21 GMT mtk01090 -+** Remove unused functions -+** \main\maintrunk.MT5921\30 2009-09-29 14:46:47 GMT mtk01090 -+** Fix compile warning -+** \main\maintrunk.MT5921\29 2009-09-29 14:28:48 GMT mtk01090 -+** Fix compile warning -+** \main\maintrunk.MT5921\28 2009-09-28 22:21:38 GMT mtk01090 -+** Refine lines to suppress compile warning -+** \main\maintrunk.MT5921\27 2009-09-28 20:19:14 GMT mtk01090 -+** Add private ioctl to carry OID structures. Restructure public/private ioctl interfaces to Linux kernel. -+** \main\maintrunk.MT5921\26 2009-08-18 22:56:53 GMT mtk01090 -+** Add Linux SDIO (with mmc core) support. -+** Add Linux 2.6.21, 2.6.25, 2.6.26. -+** Fix compile warning in Linux. -+** \main\maintrunk.MT5921\25 2009-05-07 22:26:15 GMT mtk01089 -+** Add mandatory and private IO control for Linux BWCS -+** \main\maintrunk.MT5921\24 2009-04-29 10:07:05 GMT mtk01088 -+** fixed the compiling error at linux -+** \main\maintrunk.MT5921\23 2009-04-24 09:09:45 GMT mtk01088 -+** mark the code not used at linux supplicant v0.6.7 -+** \main\maintrunk.MT5921\22 2008-11-24 21:03:51 GMT mtk01425 -+** 1. Add PTA_ENABLED flag -+** \main\maintrunk.MT5921\21 2008-08-29 14:55:59 GMT mtk01088 -+** adjust the code for meet the coding style, and add assert check -+** \main\maintrunk.MT5921\20 2008-07-16 15:23:20 GMT mtk01104 -+** Support GPIO2 mode -+** \main\maintrunk.MT5921\19 2008-07-15 17:43:11 GMT mtk01084 -+** modify variable name -+** \main\maintrunk.MT5921\18 2008-07-14 14:37:58 GMT mtk01104 -+** Add exception handle about length in function priv_set_struct() -+** \main\maintrunk.MT5921\17 2008-07-14 13:55:32 GMT mtk01104 -+** Support PRIV_CMD_BT_COEXIST -+** \main\maintrunk.MT5921\16 2008-07-09 00:20:15 GMT mtk01461 -+** Add priv oid to support WMM_PS_TEST -+** \main\maintrunk.MT5921\15 2008-06-02 11:15:22 GMT mtk01461 -+** Update after wlanoidSetPowerMode changed -+** \main\maintrunk.MT5921\14 2008-05-30 19:31:07 GMT mtk01461 -+** Add IOCTL for Power Mode -+** \main\maintrunk.MT5921\13 2008-05-30 18:57:15 GMT mtk01461 -+** Not use wlanoidSetCSUMOffloadForLinux() -+** \main\maintrunk.MT5921\12 2008-05-30 15:13:18 GMT mtk01084 -+** rename wlanoid -+** \main\maintrunk.MT5921\11 2008-05-29 14:16:31 GMT mtk01084 -+** rename for wlanoidSetBeaconIntervalForLinux -+** \main\maintrunk.MT5921\10 2008-04-17 23:06:37 GMT mtk01461 -+** Add iwpriv support for AdHocMode setting -+** \main\maintrunk.MT5921\9 2008-03-31 21:00:55 GMT mtk01461 -+** Add priv IOCTL for VOIP setting -+** \main\maintrunk.MT5921\8 2008-03-31 13:49:43 GMT mtk01461 -+** Add priv ioctl to turn on / off roaming -+** \main\maintrunk.MT5921\7 2008-03-26 15:35:14 GMT mtk01461 -+** Add CSUM offload priv ioctl for Linux -+** \main\maintrunk.MT5921\6 2008-03-11 14:50:59 GMT mtk01461 -+** Unify priv ioctl -+** \main\maintrunk.MT5921\5 2007-11-06 19:32:30 GMT mtk01088 -+** add WPS code -+** \main\maintrunk.MT5921\4 2007-10-30 12:01:39 GMT MTK01425 -+** 1. Update wlanQueryInformation and wlanSetInformation -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "precomp.h" -+ -+#include "gl_os.h" -+#include "gl_wext_priv.h" -+#if CFG_SUPPORT_WAPI -+#include "gl_sec.h" -+#endif -+#if CFG_ENABLE_WIFI_DIRECT -+#include "gl_p2p_os.h" -+#endif -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+#define NUM_SUPPORTED_OIDS (sizeof(arWlanOidReqTable) / sizeof(WLAN_REQ_ENTRY)) -+#define CMD_START "START" -+#define CMD_STOP "STOP" -+#define CMD_SCAN_ACTIVE "SCAN-ACTIVE" -+#define CMD_SCAN_PASSIVE "SCAN-PASSIVE" -+#define CMD_RSSI "RSSI" -+#define CMD_LINKSPEED "LINKSPEED" -+#define CMD_RXFILTER_START "RXFILTER-START" -+#define CMD_RXFILTER_STOP "RXFILTER-STOP" -+#define CMD_RXFILTER_ADD "RXFILTER-ADD" -+#define CMD_RXFILTER_REMOVE "RXFILTER-REMOVE" -+#define CMD_BTCOEXSCAN_START "BTCOEXSCAN-START" -+#define CMD_BTCOEXSCAN_STOP "BTCOEXSCAN-STOP" -+#define CMD_BTCOEXMODE "BTCOEXMODE" -+#define CMD_SETSUSPENDOPT "SETSUSPENDOPT" -+#define CMD_SETSUSPENDMODE "SETSUSPENDMODE" -+#define CMD_P2P_DEV_ADDR "P2P_DEV_ADDR" -+#define CMD_SETFWPATH "SETFWPATH" -+#define CMD_SETBAND "SETBAND" -+#define CMD_GETBAND "GETBAND" -+#define CMD_COUNTRY "COUNTRY" -+#define CMD_P2P_SET_NOA "P2P_SET_NOA" -+#define CMD_P2P_GET_NOA "P2P_GET_NOA" -+#define CMD_P2P_SET_PS "P2P_SET_PS" -+#define CMD_SET_AP_WPS_P2P_IE "SET_AP_WPS_P2P_IE" -+#define CMD_SETROAMMODE "SETROAMMODE" -+#define CMD_MIRACAST "MIRACAST" -+ -+#define CMD_PNOSSIDCLR_SET "PNOSSIDCLR" -+#define CMD_PNOSETUP_SET "PNOSETUP " -+#define CMD_PNOENABLE_SET "PNOFORCE" -+#define CMD_PNODEBUG_SET "PNODEBUG" -+#define CMD_WLS_BATCHING "WLS_BATCHING" -+ -+#define CMD_OKC_SET_PMK "SET_PMK" -+#define CMD_OKC_ENABLE "OKC_ENABLE" -+ -+/* miracast related definition */ -+#define MIRACAST_MODE_OFF 0 -+#define MIRACAST_MODE_SOURCE 1 -+#define MIRACAST_MODE_SINK 2 -+ -+#ifndef MIRACAST_AMPDU_SIZE -+#define MIRACAST_AMPDU_SIZE 8 -+#endif -+ -+#ifndef MIRACAST_MCHAN_ALGO -+#define MIRACAST_MCHAN_ALGO 1 -+#endif -+ -+#ifndef MIRACAST_MCHAN_BW -+#define MIRACAST_MCHAN_BW 25 -+#endif -+ -+#define CMD_BAND_AUTO 0 -+#define CMD_BAND_5G 1 -+#define CMD_BAND_2G 2 -+#define CMD_BAND_ALL 3 -+ -+/* Mediatek private command */ -+ -+#define CMD_SET_SW_CTRL "SET_SW_CTRL" -+#define CMD_GET_SW_CTRL "GET_SW_CTRL" -+#define CMD_SET_CFG "SET_CFG" -+#define CMD_GET_CFG "GET_CFG" -+#define CMD_SET_CHIP "SET_CHIP" -+#define CMD_GET_CHIP "GET_CHIP" -+#define CMD_SET_DBG_LEVEL "SET_DBG_LEVEL" -+#define CMD_GET_DBG_LEVEL "GET_DBG_LEVEL" -+#define PRIV_CMD_SIZE 512 -+ -+static UINT_32 g_ucMiracastMode = MIRACAST_MODE_OFF; -+ -+typedef struct cmd_tlv { -+ char prefix; -+ char version; -+ char subver; -+ char reserved; -+} cmd_tlv_t; -+ -+typedef struct priv_driver_cmd_s { -+ char buf[PRIV_CMD_SIZE]; -+ int used_len; -+ int total_len; -+} priv_driver_cmd_t; -+ -+#if CFG_SUPPORT_BATCH_SCAN -+#define CMD_BATCH_SET "WLS_BATCHING SET" -+#define CMD_BATCH_GET "WLS_BATCHING GET" -+#define CMD_BATCH_STOP "WLS_BATCHING STOP" -+#endif -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+static int -+priv_get_ndis(IN struct net_device *prNetDev, IN NDIS_TRANSPORT_STRUCT * prNdisReq, OUT PUINT_32 pu4OutputLen); -+ -+static int -+priv_set_ndis(IN struct net_device *prNetDev, IN NDIS_TRANSPORT_STRUCT * prNdisReq, OUT PUINT_32 pu4OutputLen); -+ -+#if 0 /* CFG_SUPPORT_WPS */ -+static int -+priv_set_appie(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, OUT char *pcExtra); -+ -+static int -+priv_set_filter(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, OUT char *pcExtra); -+#endif /* CFG_SUPPORT_WPS */ -+ -+static BOOLEAN reqSearchSupportedOidEntry(IN UINT_32 rOid, OUT P_WLAN_REQ_ENTRY * ppWlanReqEntry); -+ -+#if 0 -+static WLAN_STATUS -+reqExtQueryConfiguration(IN P_GLUE_INFO_T prGlueInfo, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+static WLAN_STATUS -+reqExtSetConfiguration(IN P_GLUE_INFO_T prGlueInfo, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+#endif -+ -+static WLAN_STATUS -+reqExtSetAcpiDevicePowerState(IN P_GLUE_INFO_T prGlueInfo, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+static UINT_8 aucOidBuf[4096] = { 0 }; -+ -+/* OID processing table */ -+/* Order is important here because the OIDs should be in order of -+ increasing value for binary searching. */ -+static WLAN_REQ_ENTRY arWlanOidReqTable[] = { -+ /* -+ {(NDIS_OID)rOid, -+ (PUINT_8)pucOidName, -+ fgQryBufLenChecking, fgSetBufLenChecking, fgIsHandleInGlueLayerOnly, u4InfoBufLen, -+ pfOidQueryHandler, -+ pfOidSetHandler} -+ */ -+ /* General Operational Characteristics */ -+ -+ /* Ethernet Operational Characteristics */ -+ {OID_802_3_CURRENT_ADDRESS, -+ DISP_STRING("OID_802_3_CURRENT_ADDRESS"), -+ TRUE, TRUE, ENUM_OID_DRIVER_CORE, 6, -+ (PFN_OID_HANDLER_FUNC_REQ) wlanoidQueryCurrentAddr, -+ NULL}, -+ -+ /* OID_802_3_MULTICAST_LIST */ -+ /* OID_802_3_MAXIMUM_LIST_SIZE */ -+ /* Ethernet Statistics */ -+ -+ /* NDIS 802.11 Wireless LAN OIDs */ -+ {OID_802_11_SUPPORTED_RATES, -+ DISP_STRING("OID_802_11_SUPPORTED_RATES"), -+ TRUE, FALSE, ENUM_OID_DRIVER_CORE, sizeof(PARAM_RATES_EX), -+ (PFN_OID_HANDLER_FUNC_REQ) wlanoidQuerySupportedRates, -+ NULL} -+ , -+ /* -+ {OID_802_11_CONFIGURATION, -+ DISP_STRING("OID_802_11_CONFIGURATION"), -+ TRUE, TRUE, ENUM_OID_GLUE_EXTENSION, sizeof(PARAM_802_11_CONFIG_T), -+ (PFN_OID_HANDLER_FUNC_REQ)reqExtQueryConfiguration, -+ (PFN_OID_HANDLER_FUNC_REQ)reqExtSetConfiguration}, -+ */ -+ {OID_PNP_SET_POWER, -+ DISP_STRING("OID_PNP_SET_POWER"), -+ TRUE, FALSE, ENUM_OID_GLUE_EXTENSION, sizeof(PARAM_DEVICE_POWER_STATE), -+ NULL, -+ (PFN_OID_HANDLER_FUNC_REQ) reqExtSetAcpiDevicePowerState} -+ , -+ -+ /* Custom OIDs */ -+ {OID_CUSTOM_OID_INTERFACE_VERSION, -+ DISP_STRING("OID_CUSTOM_OID_INTERFACE_VERSION"), -+ TRUE, FALSE, ENUM_OID_DRIVER_CORE, 4, -+ (PFN_OID_HANDLER_FUNC_REQ) wlanoidQueryOidInterfaceVersion, -+ NULL} -+ , -+ -+ /* -+ #if PTA_ENABLED -+ {OID_CUSTOM_BT_COEXIST_CTRL, -+ DISP_STRING("OID_CUSTOM_BT_COEXIST_CTRL"), -+ FALSE, TRUE, ENUM_OID_DRIVER_CORE, sizeof(PARAM_CUSTOM_BT_COEXIST_T), -+ NULL, -+ (PFN_OID_HANDLER_FUNC_REQ)wlanoidSetBtCoexistCtrl}, -+ #endif -+ */ -+ -+ /* -+ {OID_CUSTOM_POWER_MANAGEMENT_PROFILE, -+ DISP_STRING("OID_CUSTOM_POWER_MANAGEMENT_PROFILE"), -+ FALSE, FALSE, ENUM_OID_DRIVER_CORE, 0, -+ (PFN_OID_HANDLER_FUNC_REQ)wlanoidQueryPwrMgmtProfParam, -+ (PFN_OID_HANDLER_FUNC_REQ)wlanoidSetPwrMgmtProfParam}, -+ {OID_CUSTOM_PATTERN_CONFIG, -+ DISP_STRING("OID_CUSTOM_PATTERN_CONFIG"), -+ TRUE, TRUE, ENUM_OID_DRIVER_CORE, sizeof(PARAM_CUSTOM_PATTERN_SEARCH_CONFIG_STRUCT_T), -+ NULL, -+ (PFN_OID_HANDLER_FUNC_REQ)wlanoidSetPatternConfig}, -+ {OID_CUSTOM_BG_SSID_SEARCH_CONFIG, -+ DISP_STRING("OID_CUSTOM_BG_SSID_SEARCH_CONFIG"), -+ FALSE, FALSE, ENUM_OID_DRIVER_CORE, 0, -+ NULL, -+ (PFN_OID_HANDLER_FUNC_REQ)wlanoidSetBgSsidParam}, -+ {OID_CUSTOM_VOIP_SETUP, -+ DISP_STRING("OID_CUSTOM_VOIP_SETUP"), -+ TRUE, TRUE, ENUM_OID_DRIVER_CORE, 4, -+ (PFN_OID_HANDLER_FUNC_REQ)wlanoidQueryVoipConnectionStatus, -+ (PFN_OID_HANDLER_FUNC_REQ)wlanoidSetVoipConnectionStatus}, -+ {OID_CUSTOM_ADD_TS, -+ DISP_STRING("OID_CUSTOM_ADD_TS"), -+ TRUE, TRUE, ENUM_OID_DRIVER_CORE, 4, -+ NULL, -+ (PFN_OID_HANDLER_FUNC_REQ)wlanoidAddTS}, -+ {OID_CUSTOM_DEL_TS, -+ DISP_STRING("OID_CUSTOM_DEL_TS"), -+ TRUE, TRUE, ENUM_OID_DRIVER_CORE, 4, -+ NULL, -+ (PFN_OID_HANDLER_FUNC_REQ)wlanoidDelTS}, -+ */ -+ -+ /* -+ #if CFG_LP_PATTERN_SEARCH_SLT -+ {OID_CUSTOM_SLT, -+ DISP_STRING("OID_CUSTOM_SLT"), -+ FALSE, FALSE, ENUM_OID_DRIVER_CORE, 0, -+ (PFN_OID_HANDLER_FUNC_REQ)wlanoidQuerySltResult, -+ (PFN_OID_HANDLER_FUNC_REQ)wlanoidSetSltMode}, -+ #endif -+ -+ {OID_CUSTOM_ROAMING_EN, -+ DISP_STRING("OID_CUSTOM_ROAMING_EN"), -+ TRUE, TRUE, ENUM_OID_DRIVER_CORE, 4, -+ (PFN_OID_HANDLER_FUNC_REQ)wlanoidQueryRoamingFunction, -+ (PFN_OID_HANDLER_FUNC_REQ)wlanoidSetRoamingFunction}, -+ {OID_CUSTOM_WMM_PS_TEST, -+ DISP_STRING("OID_CUSTOM_WMM_PS_TEST"), -+ TRUE, TRUE, ENUM_OID_DRIVER_CORE, 4, -+ NULL, -+ (PFN_OID_HANDLER_FUNC_REQ)wlanoidSetWiFiWmmPsTest}, -+ {OID_CUSTOM_COUNTRY_STRING, -+ DISP_STRING("OID_CUSTOM_COUNTRY_STRING"), -+ FALSE, FALSE, ENUM_OID_DRIVER_CORE, 0, -+ (PFN_OID_HANDLER_FUNC_REQ)wlanoidQueryCurrentCountry, -+ (PFN_OID_HANDLER_FUNC_REQ)wlanoidSetCurrentCountry}, -+ -+ #if CFG_SUPPORT_802_11D -+ {OID_CUSTOM_MULTI_DOMAIN_CAPABILITY, -+ DISP_STRING("OID_CUSTOM_MULTI_DOMAIN_CAPABILITY"), -+ FALSE, FALSE, ENUM_OID_DRIVER_CORE, 0, -+ (PFN_OID_HANDLER_FUNC_REQ)wlanoidQueryMultiDomainCap, -+ (PFN_OID_HANDLER_FUNC_REQ)wlanoidSetMultiDomainCap}, -+ #endif -+ -+ {OID_CUSTOM_GPIO2_MODE, -+ DISP_STRING("OID_CUSTOM_GPIO2_MODE"), -+ FALSE, TRUE, ENUM_OID_DRIVER_CORE, sizeof(ENUM_PARAM_GPIO2_MODE_T), -+ NULL, -+ (PFN_OID_HANDLER_FUNC_REQ)wlanoidSetGPIO2Mode}, -+ {OID_CUSTOM_CONTINUOUS_POLL, -+ DISP_STRING("OID_CUSTOM_CONTINUOUS_POLL"), -+ FALSE, TRUE, ENUM_OID_DRIVER_CORE, sizeof(PARAM_CONTINUOUS_POLL_T), -+ (PFN_OID_HANDLER_FUNC_REQ)wlanoidQueryContinuousPollInterval, -+ (PFN_OID_HANDLER_FUNC_REQ)wlanoidSetContinuousPollProfile}, -+ {OID_CUSTOM_DISABLE_BEACON_DETECTION, -+ DISP_STRING("OID_CUSTOM_DISABLE_BEACON_DETECTION"), -+ FALSE, TRUE, ENUM_OID_DRIVER_CORE, 4, -+ (PFN_OID_HANDLER_FUNC_REQ)wlanoidQueryDisableBeaconDetectionFunc, -+ (PFN_OID_HANDLER_FUNC_REQ)wlanoidSetDisableBeaconDetectionFunc}, -+ */ -+ -+ /* WPS */ -+ /* -+ {OID_CUSTOM_DISABLE_PRIVACY_CHECK, -+ DISP_STRING("OID_CUSTOM_DISABLE_PRIVACY_CHECK"), -+ FALSE, TRUE, ENUM_OID_DRIVER_CORE, 4, -+ NULL, -+ (PFN_OID_HANDLER_FUNC_REQ)wlanoidSetDisablePriavcyCheck}, -+ */ -+ -+ {OID_CUSTOM_MCR_RW, -+ DISP_STRING("OID_CUSTOM_MCR_RW"), -+ TRUE, TRUE, ENUM_OID_DRIVER_CORE, sizeof(PARAM_CUSTOM_MCR_RW_STRUCT_T), -+ (PFN_OID_HANDLER_FUNC_REQ) wlanoidQueryMcrRead, -+ (PFN_OID_HANDLER_FUNC_REQ) wlanoidSetMcrWrite} -+ , -+ -+ {OID_CUSTOM_EEPROM_RW, -+ DISP_STRING("OID_CUSTOM_EEPROM_RW"), -+ TRUE, TRUE, ENUM_OID_DRIVER_CORE, sizeof(PARAM_CUSTOM_EEPROM_RW_STRUCT_T), -+ (PFN_OID_HANDLER_FUNC_REQ) wlanoidQueryEepromRead, -+ (PFN_OID_HANDLER_FUNC_REQ) wlanoidSetEepromWrite} -+ , -+ -+ {OID_CUSTOM_SW_CTRL, -+ DISP_STRING("OID_CUSTOM_SW_CTRL"), -+ TRUE, TRUE, ENUM_OID_DRIVER_CORE, sizeof(PARAM_CUSTOM_SW_CTRL_STRUCT_T), -+ (PFN_OID_HANDLER_FUNC_REQ) wlanoidQuerySwCtrlRead, -+ (PFN_OID_HANDLER_FUNC_REQ) wlanoidSetSwCtrlWrite} -+ , -+ -+ {OID_CUSTOM_MEM_DUMP, -+ DISP_STRING("OID_CUSTOM_MEM_DUMP"), -+ TRUE, TRUE, ENUM_OID_DRIVER_CORE, sizeof(PARAM_CUSTOM_MEM_DUMP_STRUCT_T), -+ (PFN_OID_HANDLER_FUNC_REQ) wlanoidQueryMemDump, -+ NULL} -+ , -+ -+ {OID_CUSTOM_TEST_MODE, -+ DISP_STRING("OID_CUSTOM_TEST_MODE"), -+ FALSE, FALSE, ENUM_OID_DRIVER_CORE, 0, -+ NULL, -+ (PFN_OID_HANDLER_FUNC_REQ) wlanoidRftestSetTestMode} -+ , -+ -+ /* -+ {OID_CUSTOM_TEST_RX_STATUS, -+ DISP_STRING("OID_CUSTOM_TEST_RX_STATUS"), -+ FALSE, TRUE, ENUM_OID_DRIVER_CORE, sizeof(PARAM_CUSTOM_RFTEST_RX_STATUS_STRUCT_T), -+ (PFN_OID_HANDLER_FUNC_REQ)wlanoidQueryRfTestRxStatus, -+ NULL}, -+ {OID_CUSTOM_TEST_TX_STATUS, -+ DISP_STRING("OID_CUSTOM_TEST_TX_STATUS"), -+ FALSE, TRUE, ENUM_OID_DRIVER_CORE, sizeof(PARAM_CUSTOM_RFTEST_TX_STATUS_STRUCT_T), -+ (PFN_OID_HANDLER_FUNC_REQ)wlanoidQueryRfTestTxStatus, -+ NULL}, -+ */ -+ {OID_CUSTOM_ABORT_TEST_MODE, -+ DISP_STRING("OID_CUSTOM_ABORT_TEST_MODE"), -+ FALSE, FALSE, ENUM_OID_DRIVER_CORE, 0, -+ NULL, -+ (PFN_OID_HANDLER_FUNC_REQ) wlanoidRftestSetAbortTestMode} -+ , -+ {OID_CUSTOM_MTK_WIFI_TEST, -+ DISP_STRING("OID_CUSTOM_MTK_WIFI_TEST"), -+ TRUE, TRUE, ENUM_OID_DRIVER_CORE, sizeof(PARAM_MTK_WIFI_TEST_STRUCT_T), -+ (PFN_OID_HANDLER_FUNC_REQ) wlanoidRftestQueryAutoTest, -+ (PFN_OID_HANDLER_FUNC_REQ) wlanoidRftestSetAutoTest} -+ , -+ -+ /* OID_CUSTOM_EMULATION_VERSION_CONTROL */ -+ -+ /* BWCS */ -+#if CFG_SUPPORT_BCM && CFG_SUPPORT_BCM_BWCS -+ {OID_CUSTOM_BWCS_CMD, -+ DISP_STRING("OID_CUSTOM_BWCS_CMD"), -+ FALSE, FALSE, ENUM_OID_DRIVER_CORE, sizeof(PTA_IPC_T), -+ (PFN_OID_HANDLER_FUNC_REQ) wlanoidQueryBT, -+ (PFN_OID_HANDLER_FUNC_REQ) wlanoidSetBT} -+ , -+#endif -+ -+/* {OID_CUSTOM_SINGLE_ANTENNA, -+ DISP_STRING("OID_CUSTOM_SINGLE_ANTENNA"), -+ FALSE, FALSE, ENUM_OID_DRIVER_CORE, 4, -+ (PFN_OID_HANDLER_FUNC_REQ)wlanoidQueryBtSingleAntenna, -+ (PFN_OID_HANDLER_FUNC_REQ)wlanoidSetBtSingleAntenna}, -+ {OID_CUSTOM_SET_PTA, -+ DISP_STRING("OID_CUSTOM_SET_PTA"), -+ FALSE, FALSE, ENUM_OID_DRIVER_CORE, 4, -+ (PFN_OID_HANDLER_FUNC_REQ)wlanoidQueryPta, -+ (PFN_OID_HANDLER_FUNC_REQ)wlanoidSetPta}, -+ */ -+ -+ {OID_CUSTOM_MTK_NVRAM_RW, -+ DISP_STRING("OID_CUSTOM_MTK_NVRAM_RW"), -+ TRUE, TRUE, ENUM_OID_DRIVER_CORE, sizeof(PARAM_CUSTOM_NVRAM_RW_STRUCT_T), -+ (PFN_OID_HANDLER_FUNC_REQ) wlanoidQueryNvramRead, -+ (PFN_OID_HANDLER_FUNC_REQ) wlanoidSetNvramWrite} -+ , -+ -+ {OID_CUSTOM_CFG_SRC_TYPE, -+ DISP_STRING("OID_CUSTOM_CFG_SRC_TYPE"), -+ FALSE, FALSE, ENUM_OID_DRIVER_CORE, sizeof(ENUM_CFG_SRC_TYPE_T), -+ (PFN_OID_HANDLER_FUNC_REQ) wlanoidQueryCfgSrcType, -+ NULL} -+ , -+ -+ {OID_CUSTOM_EEPROM_TYPE, -+ DISP_STRING("OID_CUSTOM_EEPROM_TYPE"), -+ FALSE, FALSE, ENUM_OID_DRIVER_CORE, sizeof(ENUM_EEPROM_TYPE_T), -+ (PFN_OID_HANDLER_FUNC_REQ) wlanoidQueryEepromType, -+ NULL} -+ , -+ -+#if CFG_SUPPORT_WAPI -+ {OID_802_11_WAPI_MODE, -+ DISP_STRING("OID_802_11_WAPI_MODE"), -+ FALSE, TRUE, ENUM_OID_DRIVER_CORE, 4, -+ NULL, -+ (PFN_OID_HANDLER_FUNC_REQ) wlanoidSetWapiMode} -+ , -+ {OID_802_11_WAPI_ASSOC_INFO, -+ DISP_STRING("OID_802_11_WAPI_ASSOC_INFO"), -+ FALSE, FALSE, ENUM_OID_DRIVER_CORE, 0, -+ NULL, -+ (PFN_OID_HANDLER_FUNC_REQ) wlanoidSetWapiAssocInfo} -+ , -+ {OID_802_11_SET_WAPI_KEY, -+ DISP_STRING("OID_802_11_SET_WAPI_KEY"), -+ FALSE, FALSE, ENUM_OID_DRIVER_CORE, sizeof(PARAM_WPI_KEY_T), -+ NULL, -+ (PFN_OID_HANDLER_FUNC_REQ) wlanoidSetWapiKey} -+ , -+#endif -+ -+#if CFG_SUPPORT_WPS2 -+ {OID_802_11_WSC_ASSOC_INFO, -+ DISP_STRING("OID_802_11_WSC_ASSOC_INFO"), -+ FALSE, FALSE, ENUM_OID_DRIVER_CORE, 0, -+ NULL, -+ (PFN_OID_HANDLER_FUNC_REQ) wlanoidSetWSCAssocInfo} -+ , -+#endif -+}; -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Dispatching function for private ioctl region (SIOCIWFIRSTPRIV ~ -+* SIOCIWLASTPRIV). -+* -+* \param[in] prNetDev Net device requested. -+* \param[in] prIfReq Pointer to ifreq structure. -+* \param[in] i4Cmd Command ID between SIOCIWFIRSTPRIV and SIOCIWLASTPRIV. -+* -+* \retval 0 for success. -+* \retval -EOPNOTSUPP If cmd is not supported. -+* \retval -EFAULT For fail. -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+int priv_support_ioctl(IN struct net_device *prNetDev, IN OUT struct ifreq *prIfReq, IN int i4Cmd) -+{ -+ /* prIfReq is verified in the caller function wlanDoIOCTL() */ -+ struct iwreq *prIwReq = (struct iwreq *)prIfReq; -+ struct iw_request_info rIwReqInfo; -+ -+ /* prDev is verified in the caller function wlanDoIOCTL() */ -+ -+ /* Prepare the call */ -+ rIwReqInfo.cmd = (__u16) i4Cmd; -+ rIwReqInfo.flags = 0; -+ -+ switch (i4Cmd) { -+ case IOCTL_SET_INT: -+ /* NOTE(Kevin): 1/3 INT Type <= IFNAMSIZ, so we don't need copy_from/to_user() */ -+ return priv_set_int(prNetDev, &rIwReqInfo, &(prIwReq->u), (char *)&(prIwReq->u)); -+ -+ case IOCTL_GET_INT: -+ /* NOTE(Kevin): 1/3 INT Type <= IFNAMSIZ, so we don't need copy_from/to_user() */ -+ return priv_get_int(prNetDev, &rIwReqInfo, &(prIwReq->u), (char *)&(prIwReq->u)); -+ -+ case IOCTL_SET_STRUCT: -+ case IOCTL_SET_STRUCT_FOR_EM: -+ return priv_set_struct(prNetDev, &rIwReqInfo, &prIwReq->u, (char *)&(prIwReq->u)); -+ -+ case IOCTL_GET_STRUCT: -+ return priv_get_struct(prNetDev, &rIwReqInfo, &prIwReq->u, (char *)&(prIwReq->u)); -+ -+ default: -+ return -EOPNOTSUPP; -+ -+ } /* end of switch */ -+ -+} /* priv_support_ioctl */ -+ -+#if CFG_SUPPORT_BATCH_SCAN -+ -+EVENT_BATCH_RESULT_T g_rEventBatchResult[CFG_BATCH_MAX_MSCAN]; -+ -+UINT_32 batchChannelNum2Freq(UINT_32 u4ChannelNum) -+{ -+ UINT_32 u4ChannelInMHz; -+ -+ if (u4ChannelNum >= 1 && u4ChannelNum <= 13) -+ u4ChannelInMHz = 2412 + (u4ChannelNum - 1) * 5; -+ else if (u4ChannelNum == 14) -+ u4ChannelInMHz = 2484; -+ else if (u4ChannelNum == 133) -+ u4ChannelInMHz = 3665; /* 802.11y */ -+ else if (u4ChannelNum == 137) -+ u4ChannelInMHz = 3685; /* 802.11y */ -+ else if (u4ChannelNum >= 34 && u4ChannelNum <= 165) -+ u4ChannelInMHz = 5000 + u4ChannelNum * 5; -+ else if (u4ChannelNum >= 183 && u4ChannelNum <= 196) -+ u4ChannelInMHz = 4000 + u4ChannelNum * 5; -+ else -+ u4ChannelInMHz = 0; -+ -+ return u4ChannelInMHz; -+} -+ -+#define TMP_TEXT_LEN_S 40 -+#define TMP_TEXT_LEN_L 60 -+static UCHAR text1[TMP_TEXT_LEN_S], text2[TMP_TEXT_LEN_L], text3[TMP_TEXT_LEN_L]; /* A safe len */ -+ -+WLAN_STATUS -+batchConvertResult(IN P_EVENT_BATCH_RESULT_T prEventBatchResult, -+ OUT PVOID pvBuffer, IN UINT_32 u4MaxBufferLen, OUT PUINT_32 pu4RetLen) -+{ -+ CHAR *p = pvBuffer; -+ CHAR ssid[ELEM_MAX_LEN_SSID + 1]; -+ INT_32 nsize = 0, nsize1, nsize2, nsize3, scancount; -+ INT_32 i, j, nleft; -+ UINT_32 freq; -+ -+ P_EVENT_BATCH_RESULT_ENTRY_T prEntry; -+ P_EVENT_BATCH_RESULT_T pBr; -+ -+ nleft = u4MaxBufferLen - 5; /* -5 for "----\n" */ -+ -+ pBr = prEventBatchResult; -+ scancount = 0; -+ for (j = 0; j < CFG_BATCH_MAX_MSCAN; j++) { -+ scancount += pBr->ucScanCount; -+ pBr++; -+ } -+ -+ nsize1 = kalSnprintf(text1, TMP_TEXT_LEN_S, "scancount=%x\nnextcount=%x\n", scancount, scancount); -+ if (nsize1 < nleft) { -+ p += nsize1 = kalSprintf(p, "%s", text1); -+ nleft -= nsize1; -+ } else -+ goto short_buf; -+ -+ pBr = prEventBatchResult; -+ for (j = 0; j < CFG_BATCH_MAX_MSCAN; j++) { -+ DBGLOG(SCN, TRACE, "convert mscan = %d, apcount=%d, nleft=%d\n", j, pBr->ucScanCount, nleft); -+ -+ if (pBr->ucScanCount == 0) { -+ pBr++; -+ continue; -+ } -+ -+ nleft -= 5; /* -5 for "####\n" */ -+ -+ /* We only support one round scan result now. */ -+ nsize1 = kalSnprintf(text1, TMP_TEXT_LEN_S, "apcount=%d\n", pBr->ucScanCount); -+ if (nsize1 < nleft) { -+ p += nsize1 = kalSprintf(p, "%s", text1); -+ nleft -= nsize1; -+ } else -+ goto short_buf; -+ -+ for (i = 0; i < pBr->ucScanCount; i++) { -+ prEntry = &pBr->arBatchResult[i]; -+ -+ nsize1 = kalSnprintf(text1, TMP_TEXT_LEN_S, "bssid=" MACSTR "\n", -+ prEntry->aucBssid[0], -+ prEntry->aucBssid[1], -+ prEntry->aucBssid[2], -+ prEntry->aucBssid[3], -+ prEntry->aucBssid[4], prEntry->aucBssid[5]); -+ -+ kalMemCopy(ssid, -+ prEntry->aucSSID, -+ (prEntry->ucSSIDLen < ELEM_MAX_LEN_SSID ? prEntry->ucSSIDLen : ELEM_MAX_LEN_SSID)); -+ ssid[(prEntry->ucSSIDLen < -+ (ELEM_MAX_LEN_SSID - 1) ? prEntry->ucSSIDLen : (ELEM_MAX_LEN_SSID - 1))] = '\0'; -+ nsize2 = kalSnprintf(text2, TMP_TEXT_LEN_L, "ssid=%s\n", ssid); -+ -+ freq = batchChannelNum2Freq(prEntry->ucFreq); -+ nsize3 = -+ kalSnprintf(text3, TMP_TEXT_LEN_L, -+ "freq=%u\nlevel=%d\ndist=%u\ndistSd=%u\n====\n", freq, -+ prEntry->cRssi, prEntry->u4Dist, prEntry->u4Distsd); -+ -+ nsize = nsize1 + nsize2 + nsize3; -+ if (nsize < nleft) { -+ -+ kalStrnCpy(p, text1, TMP_TEXT_LEN_S); -+ p += nsize1; -+ -+ kalStrnCpy(p, text2, TMP_TEXT_LEN_L); -+ p += nsize2; -+ -+ kalStrnCpy(p, text3, TMP_TEXT_LEN_L); -+ p += nsize3; -+ -+ nleft -= nsize; -+ } else { -+ DBGLOG(SCN, TRACE, "Warning: Early break! (%d)\n", i); -+ break; /* discard following entries, TODO: apcount? */ -+ } -+ } -+ -+ nsize1 = kalSnprintf(text1, TMP_TEXT_LEN_S, "%s", "####\n"); -+ p += kalSprintf(p, "%s", text1); -+ -+ pBr++; -+ } -+ -+ nsize1 = kalSnprintf(text1, TMP_TEXT_LEN_S, "%s", "----\n"); -+ kalSprintf(p, "%s", text1); -+ -+ *pu4RetLen = u4MaxBufferLen - nleft; -+ DBGLOG(SCN, TRACE, "total len = %d (max len = %d)\n", *pu4RetLen, u4MaxBufferLen); -+ -+ return WLAN_STATUS_SUCCESS; -+ -+short_buf: -+ DBGLOG(SCN, TRACE, -+ "Short buffer issue! %d > %d, %s\n", u4MaxBufferLen + (nsize - nleft), -+ u4MaxBufferLen, (char *)pvBuffer); -+ return WLAN_STATUS_INVALID_LENGTH; -+} -+#endif -+ -+#if CFG_SUPPORT_GET_CH_ENV -+WLAN_STATUS -+scanEnvResult(P_GLUE_INFO_T prGlueInfo, OUT PVOID pvBuffer, IN UINT_32 u4MaxBufferLen, OUT PUINT_32 pu4RetLen) -+{ -+ P_ADAPTER_T prAdapter = NULL; -+ CHAR *p = pvBuffer; -+ INT_32 nsize; -+ INT_32 i, nleft; -+ P_SCAN_INFO_T prScanInfo; -+ P_LINK_T prBSSDescList; -+ P_BSS_DESC_T prBssDesc; -+ CH_ENV_T chEnvInfo[54]; /* 54: from FW define; TODO: sync MAXIMUM_OPERATION_CHANNEL_LIST */ -+ UINT_32 i4GetCh = 0; -+ INT_32 i4Argc = 0; -+ PCHAR apcArgv[WLAN_CFG_ARGV_MAX] = { 0 }; -+ UINT_8 ucTextLen = 40; -+ UCHAR text[ucTextLen]; -+ INT_32 u4Ret; -+ -+ prAdapter = prGlueInfo->prAdapter; -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ prBSSDescList = &prScanInfo->rBSSDescList; -+ -+ kalMemZero(chEnvInfo, sizeof(chEnvInfo)); -+ -+ DBGLOG(SCN, TRACE, "pvBuffer:%s, pu4RetLen:%d\n", (char *)pvBuffer, *pu4RetLen); -+ -+ wlanCfgParseArgument(pvBuffer, &i4Argc, apcArgv); -+ DBGLOG(REQ, LOUD, "argc is %i\n", i4Argc); -+ -+ if (i4Argc >= 2) { -+ u4Ret = kalkStrtou32(apcArgv[1], 0, &i4GetCh); -+ if (u4Ret) -+ DBGLOG(SCN, TRACE, "parse pvBuffer error u4Ret=%d\n", u4Ret); -+ /* i4GetCh = kalStrtoul(apcArgv[1], NULL, 0); */ -+ } -+ -+ nleft = u4MaxBufferLen - 5; /* -5 for "----\n" */ -+ -+ nsize = kalSnprintf(text, ucTextLen, "%s", "scanEnvResult\nResult:1\n");/* Always return 1 for alpha version. */ -+ -+ if (nsize < nleft) { -+ p += nsize = kalSnprintf(p, ucTextLen, "%s", text); -+ nleft -= nsize; -+ } else -+ goto short_buf; -+ -+ /* Search BSS Desc from current SCAN result list. */ -+ LINK_FOR_EACH_ENTRY(prBssDesc, prBSSDescList, rLinkEntry, BSS_DESC_T) { -+ if (prBssDesc->ucChannelNum > 0) { -+ if (prBssDesc->ucChannelNum <= 14) { /* 1~14 */ -+ chEnvInfo[prBssDesc->ucChannelNum - 1].ucChNum = prBssDesc->ucChannelNum; -+ chEnvInfo[prBssDesc->ucChannelNum - 1].ucApNum++; -+ } else if (prBssDesc->ucChannelNum <= 64) { /* 15~22 */ -+ chEnvInfo[prBssDesc->ucChannelNum / 4 + 5].ucChNum = prBssDesc->ucChannelNum; -+ chEnvInfo[prBssDesc->ucChannelNum / 4 + 5].ucApNum++; -+ } else if (prBssDesc->ucChannelNum <= 116) { /* 23~27 */ -+ chEnvInfo[prBssDesc->ucChannelNum / 4 - 3].ucChNum = prBssDesc->ucChannelNum; -+ chEnvInfo[prBssDesc->ucChannelNum / 4 - 3].ucApNum++; -+ } else if (prBssDesc->ucChannelNum <= 140) { /* 28~30 */ -+ chEnvInfo[prBssDesc->ucChannelNum / 4 - 6].ucChNum = prBssDesc->ucChannelNum; -+ chEnvInfo[prBssDesc->ucChannelNum / 4 - 6].ucApNum++; -+ } else if (prBssDesc->ucChannelNum <= 165) { /* 31~35 */ -+ chEnvInfo[(prBssDesc->ucChannelNum - 1) / 4 - 7].ucChNum = prBssDesc->ucChannelNum; -+ chEnvInfo[(prBssDesc->ucChannelNum - 1) / 4 - 7].ucApNum++; -+ } -+ } -+ } -+ -+ for (i = 0; i < 54; i++) { -+ if (chEnvInfo[i].ucChNum != 0) { -+ if (i4GetCh == 0 || (chEnvInfo[i].ucChNum == (UINT_8)i4GetCh)) { -+ DBGLOG(SCN, TRACE, "chNum=%d,apNum=%d\n", chEnvInfo[i].ucChNum, chEnvInfo[i].ucApNum); -+ p += nsize = -+ kalSnprintf(p, ucTextLen, "chNum=%d,apNum=%d\n", chEnvInfo[i].ucChNum, -+ chEnvInfo[i].ucApNum); -+ nleft -= nsize; -+ } -+ } -+ } -+ -+ p += nsize = kalSnprintf(p, ucTextLen, "%s", "----\n"); -+ nleft -= nsize; -+ -+ *pu4RetLen = u4MaxBufferLen - nleft; -+ DBGLOG(SCN, TRACE, "total len = %d (max len = %d)\n", *pu4RetLen, u4MaxBufferLen); -+ -+ return WLAN_STATUS_SUCCESS; -+ -+short_buf: -+ DBGLOG(SCN, TRACE, "Short buffer issue! %d > %d, %s\n", u4MaxBufferLen + (nsize - nleft), u4MaxBufferLen, p); -+ return WLAN_STATUS_INVALID_LENGTH; -+} -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Private ioctl set int handler. -+* -+* \param[in] prNetDev Net device requested. -+* \param[in] prIwReqInfo Pointer to iwreq structure. -+* \param[in] prIwReqData The ioctl data structure, use the field of sub-command. -+* \param[in] pcExtra The buffer with input value -+* -+* \retval 0 For success. -+* \retval -EOPNOTSUPP If cmd is not supported. -+* \retval -EINVAL If a value is out of range. -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static int -+_priv_set_int(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN char *pcExtra) -+{ -+ UINT_32 u4SubCmd; -+ PUINT_32 pu4IntBuf; -+ P_NDIS_TRANSPORT_STRUCT prNdisReq; -+ P_GLUE_INFO_T prGlueInfo; -+ UINT_32 u4BufLen = 0; -+ int status = 0; -+ P_PTA_IPC_T prPtaIpc; -+ -+ ASSERT(prNetDev); -+ ASSERT(prIwReqInfo); -+ ASSERT(prIwReqData); -+ ASSERT(pcExtra); -+ -+ if (FALSE == GLUE_CHK_PR3(prNetDev, prIwReqData, pcExtra)) -+ return -EINVAL; -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); -+ -+ u4SubCmd = (UINT_32) prIwReqData->mode; -+ pu4IntBuf = (PUINT_32) pcExtra; -+ -+ switch (u4SubCmd) { -+ case PRIV_CMD_TEST_MODE: -+ /* printk("TestMode=%ld\n", pu4IntBuf[1]); */ -+ prNdisReq = (P_NDIS_TRANSPORT_STRUCT) &aucOidBuf[0]; -+ -+ if (pu4IntBuf[1] == PRIV_CMD_TEST_MAGIC_KEY) { -+ prNdisReq->ndisOidCmd = OID_CUSTOM_TEST_MODE; -+ } else if (pu4IntBuf[1] == 0) { -+ prNdisReq->ndisOidCmd = OID_CUSTOM_ABORT_TEST_MODE; -+ } else { -+ status = 0; -+ break; -+ } -+ prNdisReq->inNdisOidlength = 0; -+ prNdisReq->outNdisOidLength = 0; -+ -+ /* Execute this OID */ -+ status = priv_set_ndis(prNetDev, prNdisReq, &u4BufLen); -+ break; -+ -+ case PRIV_CMD_TEST_CMD: -+ /* printk("CMD=0x%08lx, data=0x%08lx\n", pu4IntBuf[1], pu4IntBuf[2]); */ -+ prNdisReq = (P_NDIS_TRANSPORT_STRUCT) &aucOidBuf[0]; -+ -+ kalMemCopy(&prNdisReq->ndisOidContent[0], &pu4IntBuf[1], 8); -+ -+ prNdisReq->ndisOidCmd = OID_CUSTOM_MTK_WIFI_TEST; -+ prNdisReq->inNdisOidlength = 8; -+ prNdisReq->outNdisOidLength = 8; -+ -+ /* Execute this OID */ -+ status = priv_set_ndis(prNetDev, prNdisReq, &u4BufLen); -+ break; -+ -+#if CFG_SUPPORT_PRIV_MCR_RW -+ case PRIV_CMD_ACCESS_MCR: -+ /* printk("addr=0x%08lx, data=0x%08lx\n", pu4IntBuf[1], pu4IntBuf[2]); */ -+ prNdisReq = (P_NDIS_TRANSPORT_STRUCT) &aucOidBuf[0]; -+ -+ if (!prGlueInfo->fgMcrAccessAllowed) { -+ if (pu4IntBuf[1] == PRIV_CMD_TEST_MAGIC_KEY && pu4IntBuf[2] == PRIV_CMD_TEST_MAGIC_KEY) -+ prGlueInfo->fgMcrAccessAllowed = TRUE; -+ status = 0; -+ break; -+ } -+ -+ kalMemCopy(&prNdisReq->ndisOidContent[0], &pu4IntBuf[1], 8); -+ -+ prNdisReq->ndisOidCmd = OID_CUSTOM_MCR_RW; -+ prNdisReq->inNdisOidlength = 8; -+ prNdisReq->outNdisOidLength = 8; -+ -+ /* Execute this OID */ -+ status = priv_set_ndis(prNetDev, prNdisReq, &u4BufLen); -+ break; -+#endif -+ -+ case PRIV_CMD_SW_CTRL: -+ /* printk("addr=0x%08lx, data=0x%08lx\n", pu4IntBuf[1], pu4IntBuf[2]); */ -+ prNdisReq = (P_NDIS_TRANSPORT_STRUCT) &aucOidBuf[0]; -+ -+ kalMemCopy(&prNdisReq->ndisOidContent[0], &pu4IntBuf[1], 8); -+ -+ prNdisReq->ndisOidCmd = OID_CUSTOM_SW_CTRL; -+ prNdisReq->inNdisOidlength = 8; -+ prNdisReq->outNdisOidLength = 8; -+ -+ /* Execute this OID */ -+ status = priv_set_ndis(prNetDev, prNdisReq, &u4BufLen); -+ break; -+ -+#if 0 -+ case PRIV_CMD_BEACON_PERIOD: -+ rStatus = wlanSetInformation(prGlueInfo->prAdapter, wlanoidSetBeaconInterval, -+ (PVOID)&pu4IntBuf[1],/* pu4IntBuf[0] is used as input SubCmd */ -+ sizeof(UINT_32), &u4BufLen); -+ break; -+#endif -+ -+#if CFG_TCP_IP_CHKSUM_OFFLOAD -+ case PRIV_CMD_CSUM_OFFLOAD: -+ { -+ UINT_32 u4CSUMFlags; -+ -+ if (pu4IntBuf[1] == 1) -+ u4CSUMFlags = CSUM_OFFLOAD_EN_ALL; -+ else if (pu4IntBuf[1] == 0) -+ u4CSUMFlags = 0; -+ else -+ return -EINVAL; -+ -+ if (kalIoctl(prGlueInfo, -+ wlanoidSetCSUMOffload, -+ (PVOID)&u4CSUMFlags, -+ sizeof(UINT_32), FALSE, FALSE, TRUE, FALSE, &u4BufLen) == WLAN_STATUS_SUCCESS) { -+ if (pu4IntBuf[1] == 1) -+ prNetDev->features |= NETIF_F_HW_CSUM; -+ else if (pu4IntBuf[1] == 0) -+ prNetDev->features &= ~NETIF_F_HW_CSUM; -+ } -+ } -+ break; -+#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */ -+ -+ case PRIV_CMD_POWER_MODE: -+ kalIoctl(prGlueInfo, wlanoidSet802dot11PowerSaveProfile, -+ (PVOID)&pu4IntBuf[1], /* pu4IntBuf[0] is used as input SubCmd */ -+ sizeof(UINT_32), FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ break; -+ -+ case PRIV_CMD_WMM_PS: -+ { -+ PARAM_CUSTOM_WMM_PS_TEST_STRUCT_T rWmmPsTest; -+ -+ rWmmPsTest.bmfgApsdEnAc = (UINT_8) pu4IntBuf[1]; -+ rWmmPsTest.ucIsEnterPsAtOnce = (UINT_8) pu4IntBuf[2]; -+ rWmmPsTest.ucIsDisableUcTrigger = (UINT_8) pu4IntBuf[3]; -+ rWmmPsTest.reserved = 0; -+ -+ kalIoctl(prGlueInfo, -+ wlanoidSetWiFiWmmPsTest, -+ (PVOID)&rWmmPsTest, -+ sizeof(PARAM_CUSTOM_WMM_PS_TEST_STRUCT_T), FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ } -+ break; -+ -+#if 0 -+ case PRIV_CMD_ADHOC_MODE: -+ rStatus = wlanSetInformation(prGlueInfo->prAdapter, wlanoidSetAdHocMode, -+ (PVOID)&pu4IntBuf[1], /* pu4IntBuf[0] is used as input SubCmd */ -+ sizeof(UINT_32), &u4BufLen); -+ break; -+#endif -+ -+ case PRIV_CUSTOM_BWCS_CMD: -+ -+ DBGLOG(REQ, INFO, "pu4IntBuf[1] = %x, size of PTA_IPC_T = %zu.\n", -+ pu4IntBuf[1], sizeof(PARAM_PTA_IPC_T)); -+ -+ prPtaIpc = (P_PTA_IPC_T) aucOidBuf; -+ prPtaIpc->u.aucBTPParams[0] = (UINT_8) (pu4IntBuf[1] >> 24); -+ prPtaIpc->u.aucBTPParams[1] = (UINT_8) (pu4IntBuf[1] >> 16); -+ prPtaIpc->u.aucBTPParams[2] = (UINT_8) (pu4IntBuf[1] >> 8); -+ prPtaIpc->u.aucBTPParams[3] = (UINT_8) (pu4IntBuf[1]); -+ -+ DBGLOG(REQ, INFO, -+ "BCM BWCS CMD : BTPParams[0]=%02x, BTPParams[1]=%02x, BTPParams[2]=%02x, BTPParams[3]=%02x.\n", -+ prPtaIpc->u.aucBTPParams[0], prPtaIpc->u.aucBTPParams[1], prPtaIpc->u.aucBTPParams[2], -+ prPtaIpc->u.aucBTPParams[3]); -+ -+#if 0 -+ status = wlanSetInformation(prGlueInfo->prAdapter, -+ wlanoidSetBT, (PVOID)&aucOidBuf[0], u4CmdLen, &u4BufLen); -+#endif -+ -+ status = wlanoidSetBT(prGlueInfo->prAdapter, -+ (PVOID)&aucOidBuf[0], sizeof(PARAM_PTA_IPC_T), &u4BufLen); -+ -+ if (WLAN_STATUS_SUCCESS != status) -+ status = -EFAULT; -+ -+ break; -+ -+ case PRIV_CMD_BAND_CONFIG: -+ { -+ DBGLOG(REQ, INFO, "CMD set_band=%u\n", (UINT_32) pu4IntBuf[1]); -+ } -+ break; -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ case PRIV_CMD_P2P_MODE: -+ { -+ /* no use, move to set_p2p_mode_handler() */ -+ PARAM_CUSTOM_P2P_SET_STRUCT_T p2pmode; -+ -+ p2pmode.u4Enable = pu4IntBuf[1]; -+ p2pmode.u4Mode = pu4IntBuf[2]; -+ set_p2p_mode_handler(prNetDev, p2pmode); -+#if 0 -+ PARAM_CUSTOM_P2P_SET_STRUCT_T rSetP2P; -+ WLAN_STATUS rWlanStatus = WLAN_STATUS_SUCCESS; -+ BOOLEAN fgIsP2PEnding; -+ -+ GLUE_SPIN_LOCK_DECLARATION(); -+ -+ /* avoid remove & p2p off command simultaneously */ -+ GLUE_ACQUIRE_THE_SPIN_LOCK(&g_p2p_lock); -+ fgIsP2PEnding = g_u4P2PEnding; -+ g_u4P2POnOffing = 1; -+ GLUE_RELEASE_THE_SPIN_LOCK(&g_p2p_lock); -+ -+ if (fgIsP2PEnding == 1) { -+ /* skip the command if we are removing */ -+ GLUE_ACQUIRE_THE_SPIN_LOCK(&g_p2p_lock); -+ g_u4P2POnOffing = 0; -+ GLUE_RELEASE_THE_SPIN_LOCK(&g_p2p_lock); -+ break; -+ } -+ rSetP2P.u4Enable = pu4IntBuf[1]; -+ rSetP2P.u4Mode = pu4IntBuf[2]; -+ -+ if (!rSetP2P.u4Enable) -+ p2pNetUnregister(prGlueInfo, TRUE); -+ -+ /* move out to caller to avoid kalIoctrl & suspend/resume deadlock problem ALPS00844864 */ -+ /* -+ Scenario: -+ 1. System enters suspend/resume but not yet enter wlanearlysuspend() -+ or wlanlateresume(); -+ -+ 2. System switches to do PRIV_CMD_P2P_MODE and execute kalIoctl() -+ and get g_halt_sem then do glRegisterEarlySuspend() or -+ glUnregisterEarlySuspend(); -+ -+ But system suspend/resume procedure is not yet finished so we -+ suspend; -+ -+ 3. System switches back to do suspend/resume procedure and execute -+ kalIoctl(). But driver does not yet release g_halt_sem so system -+ suspend in wlanearlysuspend() or wlanlateresume(); -+ -+ ==> deadlock occurs. -+ */ -+ if ((!rSetP2P.u4Enable) && (g_u4HaltFlag == 0) && (fgIsResetting == FALSE)) { -+ /* fgIsP2PRegistered == TRUE means P2P is enabled */ -+ DBGLOG(P2P, INFO, "p2pEalySuspendReg\n"); -+ p2pEalySuspendReg(prGlueInfo, rSetP2P.u4Enable); /* p2p remove */ -+ } -+ -+ DBGLOG(P2P, INFO, -+ "wlanoidSetP2pMode 0x%p %d %d\n", &rSetP2P, rSetP2P.u4Enable, rSetP2P.u4Mode); -+ rWlanStatus = kalIoctl(prGlueInfo, wlanoidSetP2pMode, -+ (PVOID)&rSetP2P, /* pu4IntBuf[0] is used as input SubCmd */ -+ sizeof(PARAM_CUSTOM_P2P_SET_STRUCT_T), -+ FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ DBGLOG(P2P, INFO, "wlanoidSetP2pMode ok\n"); -+ -+ /* move out to caller to avoid kalIoctrl & suspend/resume deadlock problem ALPS00844864 */ -+ if ((rSetP2P.u4Enable) && (g_u4HaltFlag == 0) && (fgIsResetting == FALSE)) { -+ /* fgIsP2PRegistered == TRUE means P2P on successfully */ -+ p2pEalySuspendReg(prGlueInfo, rSetP2P.u4Enable); /* p2p on */ -+ } -+ -+ if (rSetP2P.u4Enable) -+ p2pNetRegister(prGlueInfo, TRUE); -+ -+ GLUE_ACQUIRE_THE_SPIN_LOCK(&g_p2p_lock); -+ g_u4P2POnOffing = 0; -+ GLUE_RELEASE_THE_SPIN_LOCK(&g_p2p_lock); -+#endif -+ } -+ break; -+#endif -+ -+#if (CFG_SUPPORT_MET_PROFILING == 1) -+ case PRIV_CMD_MET_PROFILING: -+ { -+ /* PARAM_CUSTOM_WFD_DEBUG_STRUCT_T rWfdDebugModeInfo; */ -+ /* rWfdDebugModeInfo.ucWFDDebugMode=(UINT_8)pu4IntBuf[1]; */ -+ /* rWfdDebugModeInfo.u2SNPeriod=(UINT_16)pu4IntBuf[2]; */ -+ /* DBGLOG(REQ, INFO,("WFD Debug Mode:%d Period:%d\n", -+ rWfdDebugModeInfo.ucWFDDebugMode,rWfdDebugModeInfo.u2SNPeriod)); */ -+ prGlueInfo->u8MetProfEnable = (UINT_8) pu4IntBuf[1]; -+ prGlueInfo->u16MetUdpPort = (UINT_16) pu4IntBuf[2]; -+ DBGLOG(REQ, INFO, "MET_PROF: Enable=%d UDP_PORT=%d\n", prGlueInfo->u8MetProfEnable, -+ prGlueInfo->u16MetUdpPort); -+ -+ } -+ break; -+ -+#endif -+ case PRIV_CMD_WFD_DEBUG_CODE: -+ { -+ PARAM_CUSTOM_WFD_DEBUG_STRUCT_T rWfdDebugModeInfo; -+ -+ rWfdDebugModeInfo.ucWFDDebugMode = (UINT_8) pu4IntBuf[1]; -+ rWfdDebugModeInfo.u2SNPeriod = (UINT_16) pu4IntBuf[2]; -+ DBGLOG(REQ, INFO, "WFD Debug Mode:%d Period:%d\n", rWfdDebugModeInfo.ucWFDDebugMode, -+ rWfdDebugModeInfo.u2SNPeriod); -+ kalIoctl(prGlueInfo, wlanoidSetWfdDebugMode, (PVOID)&rWfdDebugModeInfo, -+ sizeof(PARAM_CUSTOM_WFD_DEBUG_STRUCT_T), FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ -+ } -+ break; -+ default: -+ return -EOPNOTSUPP; -+ } -+ -+ return status; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Private ioctl get int handler. -+* -+* \param[in] pDev Net device requested. -+* \param[out] pIwReq Pointer to iwreq structure. -+* \param[in] prIwReqData The ioctl req structure, use the field of sub-command. -+* \param[out] pcExtra The buffer with put the return value -+* -+* \retval 0 For success. -+* \retval -EOPNOTSUPP If cmd is not supported. -+* \retval -EFAULT For fail. -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT_8 gucBufDbgCode[1000]; -+ -+static int -+_priv_get_int(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN OUT char *pcExtra) -+{ -+ UINT_32 u4SubCmd; -+ PUINT_32 pu4IntBuf; -+ P_GLUE_INFO_T prGlueInfo; -+ UINT_32 u4BufLen = 0; -+ int status = 0; -+ P_NDIS_TRANSPORT_STRUCT prNdisReq; -+ -+ ASSERT(prNetDev); -+ ASSERT(prIwReqInfo); -+ ASSERT(prIwReqData); -+ ASSERT(pcExtra); -+ if (FALSE == GLUE_CHK_PR3(prNetDev, prIwReqData, pcExtra)) -+ return -EINVAL; -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); -+ -+ u4SubCmd = (UINT_32) prIwReqData->mode; -+ pu4IntBuf = (PUINT_32) pcExtra; -+ -+ switch (u4SubCmd) { -+ case PRIV_CMD_TEST_CMD: -+ /* printk("CMD=0x%08lx, data=0x%08lx\n", pu4IntBuf[1], pu4IntBuf[2]); */ -+ prNdisReq = (P_NDIS_TRANSPORT_STRUCT) &aucOidBuf[0]; -+ -+ kalMemCopy(&prNdisReq->ndisOidContent[0], &pu4IntBuf[1], 8); -+ -+ prNdisReq->ndisOidCmd = OID_CUSTOM_MTK_WIFI_TEST; -+ prNdisReq->inNdisOidlength = 8; -+ prNdisReq->outNdisOidLength = 8; -+ -+ status = priv_get_ndis(prNetDev, prNdisReq, &u4BufLen); -+ if (status == 0) { -+ /* printk("Result=%ld\n", *(PUINT_32)&prNdisReq->ndisOidContent[4]); */ -+ prIwReqData->mode = *(PUINT_32) &prNdisReq->ndisOidContent[4]; -+ /* -+ if (copy_to_user(prIwReqData->data.pointer, -+ &prNdisReq->ndisOidContent[4], 4)) { -+ printk(KERN_NOTICE "priv_get_int() copy_to_user oidBuf fail(3)\n"); -+ return -EFAULT; -+ } -+ */ -+ } -+ return status; -+ -+#if CFG_SUPPORT_PRIV_MCR_RW -+ case PRIV_CMD_ACCESS_MCR: -+ /* printk("addr=0x%08lx\n", pu4IntBuf[1]); */ -+ prNdisReq = (P_NDIS_TRANSPORT_STRUCT) &aucOidBuf[0]; -+ -+ if (!prGlueInfo->fgMcrAccessAllowed) { -+ status = 0; -+ return status; -+ } -+ -+ kalMemCopy(&prNdisReq->ndisOidContent[0], &pu4IntBuf[1], 8); -+ -+ prNdisReq->ndisOidCmd = OID_CUSTOM_MCR_RW; -+ prNdisReq->inNdisOidlength = 8; -+ prNdisReq->outNdisOidLength = 8; -+ -+ status = priv_get_ndis(prNetDev, prNdisReq, &u4BufLen); -+ if (status == 0) { -+ /* printk("Result=%ld\n", *(PUINT_32)&prNdisReq->ndisOidContent[4]); */ -+ prIwReqData->mode = *(PUINT_32) &prNdisReq->ndisOidContent[4]; -+ } -+ return status; -+#endif -+ -+ case PRIV_CMD_DUMP_MEM: -+ prNdisReq = (P_NDIS_TRANSPORT_STRUCT) &aucOidBuf[0]; -+ -+#if 1 -+ if (!prGlueInfo->fgMcrAccessAllowed) { -+ status = 0; -+ return status; -+ } -+#endif -+ kalMemCopy(&prNdisReq->ndisOidContent[0], &pu4IntBuf[1], 8); -+ -+ prNdisReq->ndisOidCmd = OID_CUSTOM_MEM_DUMP; -+ prNdisReq->inNdisOidlength = 8; -+ prNdisReq->outNdisOidLength = 8; -+ -+ status = priv_get_ndis(prNetDev, prNdisReq, &u4BufLen); -+ if (status == 0) -+ prIwReqData->mode = *(PUINT_32) &prNdisReq->ndisOidContent[0]; -+ return status; -+ -+ case PRIV_CMD_SW_CTRL: -+ /* printk(" addr=0x%08lx\n", pu4IntBuf[1]); */ -+ -+ prNdisReq = (P_NDIS_TRANSPORT_STRUCT) &aucOidBuf[0]; -+ -+ kalMemCopy(&prNdisReq->ndisOidContent[0], &pu4IntBuf[1], 8); -+ -+ prNdisReq->ndisOidCmd = OID_CUSTOM_SW_CTRL; -+ prNdisReq->inNdisOidlength = 8; -+ prNdisReq->outNdisOidLength = 8; -+ -+ status = priv_get_ndis(prNetDev, prNdisReq, &u4BufLen); -+ if (status == 0) { -+ /* printk("Result=%ld\n", *(PUINT_32)&prNdisReq->ndisOidContent[4]); */ -+ prIwReqData->mode = *(PUINT_32) &prNdisReq->ndisOidContent[4]; -+ } -+ return status; -+ -+#if 0 -+ case PRIV_CMD_BEACON_PERIOD: -+ status = wlanQueryInformation(prGlueInfo->prAdapter, -+ wlanoidQueryBeaconInterval, -+ (PVOID) pu4IntBuf, sizeof(UINT_32), &u4BufLen); -+ return status; -+ -+ case PRIV_CMD_POWER_MODE: -+ status = wlanQueryInformation(prGlueInfo->prAdapter, -+ wlanoidQuery802dot11PowerSaveProfile, -+ (PVOID) pu4IntBuf, sizeof(UINT_32), &u4BufLen); -+ return status; -+ -+ case PRIV_CMD_ADHOC_MODE: -+ status = wlanQueryInformation(prGlueInfo->prAdapter, -+ wlanoidQueryAdHocMode, (PVOID) pu4IntBuf, sizeof(UINT_32), &u4BufLen); -+ return status; -+#endif -+ -+ case PRIV_CMD_BAND_CONFIG: -+ DBGLOG(REQ, INFO, "CMD get_band=\n"); -+ prIwReqData->mode = 0; -+ return status; -+ -+ default: -+ break; -+ } -+ -+ u4SubCmd = (UINT_32) prIwReqData->data.flags; -+ -+ switch (u4SubCmd) { -+ case PRIV_CMD_GET_CH_LIST: -+ { -+ UINT_16 i, j = 0; -+ UINT_8 NumOfChannel = 50; -+ UINT_8 ucMaxChannelNum = 50; -+ INT_32 ch[50]; -+ /*RF_CHANNEL_INFO_T aucChannelList[50];*/ -+ P_RF_CHANNEL_INFO_T paucChannelList; -+ P_RF_CHANNEL_INFO_T ChannelList_t; -+ -+ paucChannelList = kalMemAlloc(sizeof(RF_CHANNEL_INFO_T) * 50, VIR_MEM_TYPE); -+ if (paucChannelList == NULL) { -+ DBGLOG(REQ, INFO, "alloc ChannelList fail\n"); -+ return -EFAULT; -+ } -+ kalMemZero(paucChannelList, sizeof(RF_CHANNEL_INFO_T) * 50); -+ kalGetChannelList(prGlueInfo, BAND_NULL, ucMaxChannelNum, &NumOfChannel, paucChannelList); -+ if (NumOfChannel > 50) { -+ ASSERT(0); -+ NumOfChannel = 50; -+ } -+ -+ ChannelList_t = paucChannelList; -+ if (kalIsAPmode(prGlueInfo)) { -+ for (i = 0; i < NumOfChannel; i++) { -+ if ((ChannelList_t->ucChannelNum <= 13) -+ || (ChannelList_t->ucChannelNum == 36 -+ || ChannelList_t->ucChannelNum == 40 -+ || ChannelList_t->ucChannelNum == 44 -+ || ChannelList_t->ucChannelNum == 48)) { -+ ch[j] = (INT_32) ChannelList_t->ucChannelNum; -+ ChannelList_t++; -+ j++; -+ } -+ } -+ } else { -+ for (j = 0; j < NumOfChannel; j++) { -+ ch[j] = (INT_32) ChannelList_t->ucChannelNum; -+ ChannelList_t++; -+ } -+ } -+ -+ kalMemFree(paucChannelList, VIR_MEM_TYPE, sizeof(RF_CHANNEL_INFO_T) * 50); -+ -+ prIwReqData->data.length = j; -+ if (copy_to_user(prIwReqData->data.pointer, ch, NumOfChannel * sizeof(INT_32))) -+ return -EFAULT; -+ else -+ return status; -+ } -+ -+ case PRIV_CMD_GET_BUILD_DATE_CODE: -+ { -+ UINT_8 aucBuffer[16]; -+ -+ if (kalIoctl(prGlueInfo, -+ wlanoidQueryBuildDateCode, -+ (PVOID) aucBuffer, -+ sizeof(UINT_8) * 16, TRUE, TRUE, TRUE, FALSE, &u4BufLen) == WLAN_STATUS_SUCCESS) { -+ prIwReqData->data.length = sizeof(UINT_8) * 16; -+ -+ if (copy_to_user(prIwReqData->data.pointer, aucBuffer, prIwReqData->data.length)) -+ return -EFAULT; -+ else -+ return status; -+ } else { -+ return -EFAULT; -+ } -+ } -+ -+ case PRIV_CMD_GET_DEBUG_CODE: -+ { -+ wlanQueryDebugCode(prGlueInfo->prAdapter); -+ -+ kalMemSet(gucBufDbgCode, '.', sizeof(gucBufDbgCode)); -+ if (copy_to_user(prIwReqData->data.pointer, gucBufDbgCode, prIwReqData->data.length)) -+ return -EFAULT; -+ else -+ return status; -+ } -+ -+ default: -+ return -EOPNOTSUPP; -+ } -+ -+ return status; -+} /* priv_get_int */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Private ioctl set int array handler. -+* -+* \param[in] prNetDev Net device requested. -+* \param[in] prIwReqInfo Pointer to iwreq structure. -+* \param[in] prIwReqData The ioctl data structure, use the field of sub-command. -+* \param[in] pcExtra The buffer with input value -+* -+* \retval 0 For success. -+* \retval -EOPNOTSUPP If cmd is not supported. -+* \retval -EINVAL If a value is out of range. -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static int -+_priv_set_ints(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN char *pcExtra) -+{ -+ UINT_32 u4SubCmd, u4BufLen; -+ P_GLUE_INFO_T prGlueInfo; -+ int status = 0; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ P_SET_TXPWR_CTRL_T prTxpwr; -+ -+ ASSERT(prNetDev); -+ ASSERT(prIwReqInfo); -+ ASSERT(prIwReqData); -+ ASSERT(pcExtra); -+ -+ if (FALSE == GLUE_CHK_PR3(prNetDev, prIwReqData, pcExtra)) -+ return -EINVAL; -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); -+ -+ u4SubCmd = (UINT_32) prIwReqData->data.flags; -+ -+ switch (u4SubCmd) { -+ case PRIV_CMD_SET_TX_POWER: -+ { -+ INT_32 *setting = prIwReqData->data.pointer; -+ UINT_16 i; -+ -+#if 0 -+ DBGLOG(REQ, INFO, "Tx power num = %d\n", prIwReqData->data.length); -+ -+ DBGLOG(REQ, INFO, "Tx power setting = %d %d %d %d\n", -+ setting[0], setting[1], setting[2], setting[3]); -+#endif -+ prTxpwr = &prGlueInfo->rTxPwr; -+ if (setting[0] == 0 && prIwReqData->data.length == 4 /* argc num */) { -+ /* 0 (All networks), 1 (legacy STA), 2 (Hotspot AP), 3 (P2P), 4 (BT over Wi-Fi) */ -+ if (setting[1] == 1 || setting[1] == 0) { -+ if (setting[2] == 0 || setting[2] == 1) -+ prTxpwr->c2GLegacyStaPwrOffset = setting[3]; -+ if (setting[2] == 0 || setting[2] == 2) -+ prTxpwr->c5GLegacyStaPwrOffset = setting[3]; -+ } -+ if (setting[1] == 2 || setting[1] == 0) { -+ if (setting[2] == 0 || setting[2] == 1) -+ prTxpwr->c2GHotspotPwrOffset = setting[3]; -+ if (setting[2] == 0 || setting[2] == 2) -+ prTxpwr->c5GHotspotPwrOffset = setting[3]; -+ } -+ if (setting[1] == 3 || setting[1] == 0) { -+ if (setting[2] == 0 || setting[2] == 1) -+ prTxpwr->c2GP2pPwrOffset = setting[3]; -+ if (setting[2] == 0 || setting[2] == 2) -+ prTxpwr->c5GP2pPwrOffset = setting[3]; -+ } -+ if (setting[1] == 4 || setting[1] == 0) { -+ if (setting[2] == 0 || setting[2] == 1) -+ prTxpwr->c2GBowPwrOffset = setting[3]; -+ if (setting[2] == 0 || setting[2] == 2) -+ prTxpwr->c5GBowPwrOffset = setting[3]; -+ } -+ } else if (setting[0] == 1 && prIwReqData->data.length == 2) { -+ prTxpwr->ucConcurrencePolicy = setting[1]; -+ } else if (setting[0] == 2 && prIwReqData->data.length == 3) { -+ if (setting[1] == 0) { -+ for (i = 0; i < 14; i++) -+ prTxpwr->acTxPwrLimit2G[i] = setting[2]; -+ } else if (setting[1] <= 14) -+ prTxpwr->acTxPwrLimit2G[setting[1] - 1] = setting[2]; -+ } else if (setting[0] == 3 && prIwReqData->data.length == 3) { -+ if (setting[1] == 0) { -+ for (i = 0; i < 4; i++) -+ prTxpwr->acTxPwrLimit5G[i] = setting[2]; -+ } else if (setting[1] <= 4) -+ prTxpwr->acTxPwrLimit5G[setting[1] - 1] = setting[2]; -+ } else if (setting[0] == 4 && prIwReqData->data.length == 2) { -+ if (setting[1] == 0) -+ wlanDefTxPowerCfg(prGlueInfo->prAdapter); -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetTxPower, -+ prTxpwr, -+ sizeof(SET_TXPWR_CTRL_T), TRUE, FALSE, FALSE, FALSE, &u4BufLen); -+ } else -+ return -EFAULT; -+ } -+ return status; -+ default: -+ break; -+ } -+ -+ return status; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Private ioctl get int array handler. -+* -+* \param[in] pDev Net device requested. -+* \param[out] pIwReq Pointer to iwreq structure. -+* \param[in] prIwReqData The ioctl req structure, use the field of sub-command. -+* \param[out] pcExtra The buffer with put the return value -+* -+* \retval 0 For success. -+* \retval -EOPNOTSUPP If cmd is not supported. -+* \retval -EFAULT For fail. -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static int -+_priv_get_ints(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN OUT char *pcExtra) -+{ -+ UINT_32 u4SubCmd; -+ P_GLUE_INFO_T prGlueInfo; -+ int status = 0; -+ INT_32 ch[50]; -+ -+ ASSERT(prNetDev); -+ ASSERT(prIwReqInfo); -+ ASSERT(prIwReqData); -+ ASSERT(pcExtra); -+ if (FALSE == GLUE_CHK_PR3(prNetDev, prIwReqData, pcExtra)) -+ return -EINVAL; -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); -+ -+ u4SubCmd = (UINT_32) prIwReqData->data.flags; -+ -+ switch (u4SubCmd) { -+ case PRIV_CMD_GET_CH_LIST: -+ { -+ UINT_16 i; -+ UINT_8 NumOfChannel = 50; -+ UINT_8 ucMaxChannelNum = 50; -+ /*RF_CHANNEL_INFO_T aucChannelList[50];*/ -+ P_RF_CHANNEL_INFO_T paucChannelList; -+ P_RF_CHANNEL_INFO_T ChannelList_t; -+ -+ paucChannelList = kalMemAlloc(sizeof(RF_CHANNEL_INFO_T) * 50, VIR_MEM_TYPE); -+ if (paucChannelList == NULL) { -+ DBGLOG(REQ, INFO, "alloc fail\n"); -+ return -EINVAL; -+ } -+ kalMemZero(paucChannelList, sizeof(RF_CHANNEL_INFO_T) * 50); -+ -+ kalGetChannelList(prGlueInfo, BAND_NULL, ucMaxChannelNum, &NumOfChannel, paucChannelList); -+ if (NumOfChannel > 50) -+ NumOfChannel = 50; -+ -+ ChannelList_t = paucChannelList; -+ for (i = 0; i < NumOfChannel; i++) { -+ ch[i] = (INT_32) ChannelList_t->ucChannelNum; -+ ChannelList_t++; -+ } -+ -+ kalMemFree(paucChannelList, VIR_MEM_TYPE, sizeof(RF_CHANNEL_INFO_T) * 50); -+ prIwReqData->data.length = NumOfChannel; -+ if (copy_to_user(prIwReqData->data.pointer, ch, NumOfChannel * sizeof(INT_32))) -+ return -EFAULT; -+ else -+ return status; -+ } -+ default: -+ break; -+ } -+ -+ return status; -+} /* priv_get_int */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Private ioctl set structure handler. -+* -+* \param[in] pDev Net device requested. -+* \param[in] prIwReqData Pointer to iwreq_data structure. -+* -+* \retval 0 For success. -+* \retval -EOPNOTSUPP If cmd is not supported. -+* \retval -EINVAL If a value is out of range. -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static int -+_priv_set_struct(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN char *pcExtra) -+{ -+ UINT_32 u4SubCmd = 0; -+ int status = 0; -+ /* WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; */ -+ UINT_32 u4CmdLen = 0; -+ P_NDIS_TRANSPORT_STRUCT prNdisReq; -+ PUINT_32 pu4IntBuf = NULL; -+ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ UINT_32 u4BufLen = 0; -+ -+ ASSERT(prNetDev); -+ /* ASSERT(prIwReqInfo); */ -+ ASSERT(prIwReqData); -+ /* ASSERT(pcExtra); */ -+ -+ kalMemZero(&aucOidBuf[0], sizeof(aucOidBuf)); -+ -+ if (FALSE == GLUE_CHK_PR2(prNetDev, prIwReqData)) -+ return -EINVAL; -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); -+ -+ u4SubCmd = (UINT_32) prIwReqData->data.flags; -+ -+#if 0 -+ DBGLOG(REQ, INFO, "priv_set_struct(): prIwReqInfo->cmd(0x%X), u4SubCmd(%ld)\n", -+ prIwReqInfo->cmd, u4SubCmd); -+#endif -+ -+ switch (u4SubCmd) { -+#if 0 /* PTA_ENABLED */ -+ case PRIV_CMD_BT_COEXIST: -+ u4CmdLen = prIwReqData->data.length * sizeof(UINT_32); -+ ASSERT(sizeof(PARAM_CUSTOM_BT_COEXIST_T) >= u4CmdLen); -+ if (sizeof(PARAM_CUSTOM_BT_COEXIST_T) < u4CmdLen) -+ return -EFAULT; -+ -+ if (copy_from_user(&aucOidBuf[0], prIwReqData->data.pointer, u4CmdLen)) { -+ status = -EFAULT; /* return -EFAULT; */ -+ break; -+ } -+ -+ rStatus = wlanSetInformation(prGlueInfo->prAdapter, -+ wlanoidSetBtCoexistCtrl, (PVOID)&aucOidBuf[0], u4CmdLen, &u4BufLen); -+ if (WLAN_STATUS_SUCCESS != rStatus) -+ status = -EFAULT; -+ break; -+#endif -+ -+ case PRIV_CUSTOM_BWCS_CMD: -+ u4CmdLen = prIwReqData->data.length * sizeof(UINT_32); -+ ASSERT(sizeof(PARAM_PTA_IPC_T) >= u4CmdLen); -+ if (sizeof(PARAM_PTA_IPC_T) < u4CmdLen) -+ return -EFAULT; -+#if CFG_SUPPORT_BCM && CFG_SUPPORT_BCM_BWCS && CFG_SUPPORT_BCM_BWCS_DEBUG -+ DBGLOG(REQ, INFO, -+ "ucCmdLen = %d, size of PTA_IPC_T = %d, prIwReqData->data = 0x%x.\n", u4CmdLen, -+ sizeof(PARAM_PTA_IPC_T), prIwReqData->data); -+ -+ DBGLOG(REQ, INFO, "priv_set_struct(): prIwReqInfo->cmd(0x%X), u4SubCmd(%u)\n", -+ prIwReqInfo->cmd, u4SubCmd); -+ -+ DBGLOG(REQ, INFO, "*pcExtra = 0x%x\n", *pcExtra); -+#endif -+ -+ if (copy_from_user(&aucOidBuf[0], prIwReqData->data.pointer, u4CmdLen)) { -+ status = -EFAULT; /* return -EFAULT; */ -+ break; -+ } -+#if CFG_SUPPORT_BCM && CFG_SUPPORT_BCM_BWCS && CFG_SUPPORT_BCM_BWCS_DEBUG -+ DBGLOG(REQ, INFO, "priv_set_struct(): BWCS CMD = %02x%02x%02x%02x\n", -+ aucOidBuf[2], aucOidBuf[3], aucOidBuf[4], aucOidBuf[5]); -+#endif -+ -+#if 0 -+ status = wlanSetInformation(prGlueInfo->prAdapter, -+ wlanoidSetBT, (PVOID)&aucOidBuf[0], u4CmdLen, &u4BufLen); -+#endif -+ -+#if 1 -+ status = wlanoidSetBT(prGlueInfo->prAdapter, (PVOID)&aucOidBuf[0], u4CmdLen, &u4BufLen); -+#endif -+ -+ if (WLAN_STATUS_SUCCESS != status) -+ status = -EFAULT; -+ -+ break; -+ -+#if CFG_SUPPORT_WPS2 -+ case PRIV_CMD_WSC_PROBE_REQ: -+ { -+ /* retrieve IE for Probe Request */ -+ if (prIwReqData->data.length > 0) { -+ if (copy_from_user(prGlueInfo->aucWSCIE, prIwReqData->data.pointer, -+ prIwReqData->data.length)) { -+ status = -EFAULT; -+ break; -+ } -+ prGlueInfo->u2WSCIELen = prIwReqData->data.length; -+ } else { -+ prGlueInfo->u2WSCIELen = 0; -+ } -+ } -+ break; -+#endif -+ case PRIV_CMD_OID: -+ if (copy_from_user(&aucOidBuf[0], prIwReqData->data.pointer, prIwReqData->data.length)) { -+ status = -EFAULT; -+ break; -+ } -+ if (!kalMemCmp(&aucOidBuf[0], pcExtra, prIwReqData->data.length)) -+ DBGLOG(REQ, INFO, "pcExtra buffer is valid\n"); -+ else -+ DBGLOG(REQ, INFO, "pcExtra 0x%p\n", pcExtra); -+ /* Execute this OID */ -+ status = priv_set_ndis(prNetDev, (P_NDIS_TRANSPORT_STRUCT) &aucOidBuf[0], &u4BufLen); -+ /* Copy result to user space */ -+ ((P_NDIS_TRANSPORT_STRUCT) &aucOidBuf[0])->outNdisOidLength = u4BufLen; -+ -+ if (copy_to_user(prIwReqData->data.pointer, -+ &aucOidBuf[0], OFFSET_OF(NDIS_TRANSPORT_STRUCT, ndisOidContent))) { -+ DBGLOG(REQ, INFO, "copy_to_user oidBuf fail\n"); -+ status = -EFAULT; -+ } -+ -+ break; -+ -+ case PRIV_CMD_SW_CTRL: -+ pu4IntBuf = (PUINT_32) prIwReqData->data.pointer; -+ prNdisReq = (P_NDIS_TRANSPORT_STRUCT) &aucOidBuf[0]; -+ -+ /* kalMemCopy(&prNdisReq->ndisOidContent[0], prIwReqData->data.pointer, 8); */ -+ if (copy_from_user(&prNdisReq->ndisOidContent[0], prIwReqData->data.pointer, -+ prIwReqData->data.length)) { -+ status = -EFAULT; -+ break; -+ } -+ prNdisReq->ndisOidCmd = OID_CUSTOM_SW_CTRL; -+ prNdisReq->inNdisOidlength = 8; -+ prNdisReq->outNdisOidLength = 8; -+ -+ /* Execute this OID */ -+ status = priv_set_ndis(prNetDev, prNdisReq, &u4BufLen); -+ break; -+ -+ default: -+ return -EOPNOTSUPP; -+ } -+ -+ return status; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Private ioctl get struct handler. -+* -+* \param[in] pDev Net device requested. -+* \param[out] pIwReq Pointer to iwreq structure. -+* \param[in] cmd Private sub-command. -+* -+* \retval 0 For success. -+* \retval -EFAULT If copy from user space buffer fail. -+* \retval -EOPNOTSUPP Parameter "cmd" not recognized. -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static int -+_priv_get_struct(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN OUT char *pcExtra) -+{ -+ UINT_32 u4SubCmd = 0; -+ P_NDIS_TRANSPORT_STRUCT prNdisReq = NULL; -+ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ UINT_32 u4BufLen = 0; -+ PUINT_32 pu4IntBuf = NULL; -+ int status = 0; -+ -+ kalMemZero(&aucOidBuf[0], sizeof(aucOidBuf)); -+ -+ ASSERT(prNetDev); -+ ASSERT(prIwReqData); -+ if (!prNetDev || !prIwReqData) { -+ DBGLOG(REQ, INFO, "priv_get_struct(): invalid param(0x%p, 0x%p)\n", prNetDev, prIwReqData); -+ return -EINVAL; -+ } -+ -+ u4SubCmd = (UINT_32) prIwReqData->data.flags; -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); -+ ASSERT(prGlueInfo); -+ if (!prGlueInfo) { -+ DBGLOG(REQ, INFO, "priv_get_struct(): invalid prGlueInfo(0x%p, 0x%p)\n", -+ prNetDev, *((P_GLUE_INFO_T *) netdev_priv(prNetDev))); -+ return -EINVAL; -+ } -+#if 0 -+ DBGLOG(REQ, INFO, "priv_get_struct(): prIwReqInfo->cmd(0x%X), u4SubCmd(%ld)\n", -+ prIwReqInfo->cmd, u4SubCmd); -+#endif -+ memset(aucOidBuf, 0, sizeof(aucOidBuf)); -+ -+ switch (u4SubCmd) { -+ case PRIV_CMD_OID: -+ if (copy_from_user(&aucOidBuf[0], prIwReqData->data.pointer, sizeof(NDIS_TRANSPORT_STRUCT))) { -+ DBGLOG(REQ, INFO, "priv_get_struct() copy_from_user oidBuf fail\n"); -+ return -EFAULT; -+ } -+ -+ prNdisReq = (P_NDIS_TRANSPORT_STRUCT) &aucOidBuf[0]; -+#if 0 -+ DBGLOG(REQ, INFO, "\n priv_get_struct cmd 0x%02x len:%d OID:0x%08x OID Len:%d\n", -+ cmd, pIwReq->u.data.length, ndisReq->ndisOidCmd, ndisReq->inNdisOidlength); -+#endif -+ if (priv_get_ndis(prNetDev, prNdisReq, &u4BufLen) == 0) { -+ prNdisReq->outNdisOidLength = u4BufLen; -+ if (copy_to_user(prIwReqData->data.pointer, -+ &aucOidBuf[0], -+ u4BufLen + sizeof(NDIS_TRANSPORT_STRUCT) - -+ sizeof(prNdisReq->ndisOidContent))) { -+ DBGLOG(REQ, INFO, "priv_get_struct() copy_to_user oidBuf fail(1)\n"); -+ return -EFAULT; -+ } -+ return 0; -+ } -+ prNdisReq->outNdisOidLength = u4BufLen; -+ if (copy_to_user(prIwReqData->data.pointer, -+ &aucOidBuf[0], OFFSET_OF(NDIS_TRANSPORT_STRUCT, ndisOidContent))) { -+ DBGLOG(REQ, INFO, "priv_get_struct() copy_to_user oidBuf fail(2)\n"); -+ } -+ return -EFAULT; -+ -+ case PRIV_CMD_SW_CTRL: -+ pu4IntBuf = (PUINT_32) prIwReqData->data.pointer; -+ prNdisReq = (P_NDIS_TRANSPORT_STRUCT) &aucOidBuf[0]; -+ -+ if (copy_from_user(&prNdisReq->ndisOidContent[0], prIwReqData->data.pointer, -+ prIwReqData->data.length)) { -+ DBGLOG(REQ, INFO, "priv_get_struct() copy_from_user oidBuf fail\n"); -+ return -EFAULT; -+ } -+ -+ prNdisReq->ndisOidCmd = OID_CUSTOM_SW_CTRL; -+ prNdisReq->inNdisOidlength = 8; -+ prNdisReq->outNdisOidLength = 8; -+ -+ status = priv_get_ndis(prNetDev, prNdisReq, &u4BufLen); -+ if (status == 0) { -+ prNdisReq->outNdisOidLength = u4BufLen; -+ /* printk("len=%d Result=%08lx\n", u4BufLen, *(PUINT_32)&prNdisReq->ndisOidContent[4]); */ -+ -+ if (copy_to_user(prIwReqData->data.pointer, -+ &prNdisReq->ndisOidContent[4], -+ 4 /* OFFSET_OF(NDIS_TRANSPORT_STRUCT, ndisOidContent) */)) { -+ DBGLOG(REQ, INFO, "priv_get_struct() copy_to_user oidBuf fail(2)\n"); -+ } -+ } -+ return 0; -+ -+ default: -+ DBGLOG(REQ, WARN, "get struct cmd:0x%x\n", u4SubCmd); -+ return -EOPNOTSUPP; -+ } -+} /* priv_get_struct */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief The routine handles a set operation for a single OID. -+* -+* \param[in] pDev Net device requested. -+* \param[in] ndisReq Ndis request OID information copy from user. -+* \param[out] outputLen_p If the call is successful, returns the number of -+* bytes written into the query buffer. If the -+* call failed due to invalid length of the query -+* buffer, returns the amount of storage needed.. -+* -+* \retval 0 On success. -+* \retval -EOPNOTSUPP If cmd is not supported. -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static int -+priv_set_ndis(IN struct net_device *prNetDev, IN NDIS_TRANSPORT_STRUCT * prNdisReq, OUT PUINT_32 pu4OutputLen) -+{ -+ P_WLAN_REQ_ENTRY prWlanReqEntry = NULL; -+ WLAN_STATUS status = WLAN_STATUS_SUCCESS; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ UINT_32 u4SetInfoLen = 0; -+ -+ ASSERT(prNetDev); -+ ASSERT(prNdisReq); -+ ASSERT(pu4OutputLen); -+ -+ if (!prNetDev || !prNdisReq || !pu4OutputLen) { -+ DBGLOG(REQ, INFO, "priv_set_ndis(): invalid param(0x%p, 0x%p, 0x%p)\n", -+ prNetDev, prNdisReq, pu4OutputLen); -+ return -EINVAL; -+ } -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); -+ ASSERT(prGlueInfo); -+ if (!prGlueInfo) { -+ DBGLOG(REQ, INFO, "priv_set_ndis(): invalid prGlueInfo(0x%p, 0x%p)\n", -+ prNetDev, *((P_GLUE_INFO_T *) netdev_priv(prNetDev))); -+ return -EINVAL; -+ } -+#if 0 -+ DBGLOG(REQ, INFO, "priv_set_ndis(): prNdisReq->ndisOidCmd(0x%lX)\n", prNdisReq->ndisOidCmd); -+#endif -+ -+ if (FALSE == reqSearchSupportedOidEntry(prNdisReq->ndisOidCmd, &prWlanReqEntry)) { -+ /* WARNLOG(("Set OID: 0x%08lx (unknown)\n", prNdisReq->ndisOidCmd)); */ -+ return -EOPNOTSUPP; -+ } -+ -+ if (NULL == prWlanReqEntry->pfOidSetHandler) { -+ /* WARNLOG(("Set %s: Null set handler\n", prWlanReqEntry->pucOidName)); */ -+ return -EOPNOTSUPP; -+ } -+#if 0 -+ DBGLOG(REQ, INFO, "priv_set_ndis(): %s\n", prWlanReqEntry->pucOidName); -+#endif -+ -+ if (prWlanReqEntry->fgSetBufLenChecking) { -+ if (prNdisReq->inNdisOidlength != prWlanReqEntry->u4InfoBufLen) { -+ DBGLOG(REQ, WARN, "Set %s: Invalid length (current=%u, needed=%u)\n", -+ prWlanReqEntry->pucOidName, -+ prNdisReq->inNdisOidlength, prWlanReqEntry->u4InfoBufLen); -+ -+ *pu4OutputLen = prWlanReqEntry->u4InfoBufLen; -+ return -EINVAL; -+ } -+ } -+ -+ if (prWlanReqEntry->eOidMethod == ENUM_OID_GLUE_ONLY) { -+ /* GLUE sw info only */ -+ status = prWlanReqEntry->pfOidSetHandler(prGlueInfo, -+ prNdisReq->ndisOidContent, -+ prNdisReq->inNdisOidlength, &u4SetInfoLen); -+ } else if (prWlanReqEntry->eOidMethod == ENUM_OID_GLUE_EXTENSION) { -+ /* multiple sw operations */ -+ status = prWlanReqEntry->pfOidSetHandler(prGlueInfo, -+ prNdisReq->ndisOidContent, -+ prNdisReq->inNdisOidlength, &u4SetInfoLen); -+ } else if (prWlanReqEntry->eOidMethod == ENUM_OID_DRIVER_CORE) { -+ /* driver core */ -+ -+ status = kalIoctl(prGlueInfo, -+ (PFN_OID_HANDLER_FUNC) prWlanReqEntry->pfOidSetHandler, -+ prNdisReq->ndisOidContent, -+ prNdisReq->inNdisOidlength, FALSE, FALSE, TRUE, FALSE, &u4SetInfoLen); -+ } else { -+ DBGLOG(REQ, INFO, "priv_set_ndis(): unsupported OID method:0x%x\n", prWlanReqEntry->eOidMethod); -+ return -EOPNOTSUPP; -+ } -+ -+ *pu4OutputLen = u4SetInfoLen; -+ -+ switch (status) { -+ case WLAN_STATUS_SUCCESS: -+ break; -+ -+ case WLAN_STATUS_INVALID_LENGTH: -+ /* WARNLOG(("Set %s: Invalid length (current=%ld, needed=%ld)\n", */ -+ /* prWlanReqEntry->pucOidName, */ -+ /* prNdisReq->inNdisOidlength, */ -+ /* u4SetInfoLen)); */ -+ break; -+ } -+ -+ if (WLAN_STATUS_SUCCESS != status) -+ return -EFAULT; -+ -+ return 0; -+} /* priv_set_ndis */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief The routine handles a query operation for a single OID. Basically we -+* return information about the current state of the OID in question. -+* -+* \param[in] pDev Net device requested. -+* \param[in] ndisReq Ndis request OID information copy from user. -+* \param[out] outputLen_p If the call is successful, returns the number of -+* bytes written into the query buffer. If the -+* call failed due to invalid length of the query -+* buffer, returns the amount of storage needed.. -+* -+* \retval 0 On success. -+* \retval -EOPNOTSUPP If cmd is not supported. -+* \retval -EINVAL invalid input parameters -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static int -+priv_get_ndis(IN struct net_device *prNetDev, IN NDIS_TRANSPORT_STRUCT * prNdisReq, OUT PUINT_32 pu4OutputLen) -+{ -+ P_WLAN_REQ_ENTRY prWlanReqEntry = NULL; -+ UINT_32 u4BufLen = 0; -+ WLAN_STATUS status = WLAN_STATUS_SUCCESS; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ -+ ASSERT(prNetDev); -+ ASSERT(prNdisReq); -+ ASSERT(pu4OutputLen); -+ -+ if (!prNetDev || !prNdisReq || !pu4OutputLen) { -+ DBGLOG(REQ, INFO, "priv_get_ndis(): invalid param(0x%p, 0x%p, 0x%p)\n", -+ prNetDev, prNdisReq, pu4OutputLen); -+ return -EINVAL; -+ } -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); -+ ASSERT(prGlueInfo); -+ if (!prGlueInfo) { -+ DBGLOG(REQ, INFO, "priv_get_ndis(): invalid prGlueInfo(0x%p, 0x%p)\n", -+ prNetDev, *((P_GLUE_INFO_T *) netdev_priv(prNetDev))); -+ return -EINVAL; -+ } -+#if 0 -+ DBGLOG(REQ, INFO, "priv_get_ndis(): prNdisReq->ndisOidCmd(0x%lX)\n", prNdisReq->ndisOidCmd); -+#endif -+ -+ if (FALSE == reqSearchSupportedOidEntry(prNdisReq->ndisOidCmd, &prWlanReqEntry)) { -+ /* WARNLOG(("Query OID: 0x%08lx (unknown)\n", prNdisReq->ndisOidCmd)); */ -+ return -EOPNOTSUPP; -+ } -+ -+ if (NULL == prWlanReqEntry->pfOidQueryHandler) { -+ /* WARNLOG(("Query %s: Null query handler\n", prWlanReqEntry->pucOidName)); */ -+ return -EOPNOTSUPP; -+ } -+#if 0 -+ DBGLOG(REQ, INFO, "priv_get_ndis(): %s\n", prWlanReqEntry->pucOidName); -+#endif -+ -+ if (prWlanReqEntry->fgQryBufLenChecking) { -+ if (prNdisReq->inNdisOidlength < prWlanReqEntry->u4InfoBufLen) { -+ /* Not enough room in InformationBuffer. Punt */ -+ /* WARNLOG(("Query %s: Buffer too short (current=%ld, needed=%ld)\n", */ -+ /* prWlanReqEntry->pucOidName, */ -+ /* prNdisReq->inNdisOidlength, */ -+ /* prWlanReqEntry->u4InfoBufLen)); */ -+ -+ *pu4OutputLen = prWlanReqEntry->u4InfoBufLen; -+ -+ status = WLAN_STATUS_INVALID_LENGTH; -+ return -EINVAL; -+ } -+ } -+ -+ if (prWlanReqEntry->eOidMethod == ENUM_OID_GLUE_ONLY) { -+ /* GLUE sw info only */ -+ status = prWlanReqEntry->pfOidQueryHandler(prGlueInfo, -+ prNdisReq->ndisOidContent, -+ prNdisReq->inNdisOidlength, &u4BufLen); -+ } else if (prWlanReqEntry->eOidMethod == ENUM_OID_GLUE_EXTENSION) { -+ /* multiple sw operations */ -+ status = prWlanReqEntry->pfOidQueryHandler(prGlueInfo, -+ prNdisReq->ndisOidContent, -+ prNdisReq->inNdisOidlength, &u4BufLen); -+ } else if (prWlanReqEntry->eOidMethod == ENUM_OID_DRIVER_CORE) { -+ /* driver core */ -+ -+ status = kalIoctl(prGlueInfo, -+ (PFN_OID_HANDLER_FUNC) prWlanReqEntry->pfOidQueryHandler, -+ prNdisReq->ndisOidContent, -+ prNdisReq->inNdisOidlength, TRUE, TRUE, TRUE, FALSE, &u4BufLen); -+ } else { -+ DBGLOG(REQ, INFO, "priv_set_ndis(): unsupported OID method:0x%x\n", prWlanReqEntry->eOidMethod); -+ return -EOPNOTSUPP; -+ } -+ -+ *pu4OutputLen = u4BufLen; -+ -+ switch (status) { -+ case WLAN_STATUS_SUCCESS: -+ break; -+ -+ case WLAN_STATUS_INVALID_LENGTH: -+ /* WARNLOG(("Set %s: Invalid length (current=%ld, needed=%ld)\n", */ -+ /* prWlanReqEntry->pucOidName, */ -+ /* prNdisReq->inNdisOidlength, */ -+ /* u4BufLen)); */ -+ break; -+ } -+ -+ if (WLAN_STATUS_SUCCESS != status) -+ return -EOPNOTSUPP; -+ -+ return 0; -+} /* priv_get_ndis */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Parse command value in a string. -+* -+* @param InStr Pointer to the string buffer. -+* @param OutStr Pointer to the next command value. -+* @param OutLen Record the resident buffer length. -+* -+* @retval Command value. -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT_32 CmdStringDecParse(IN UINT_8 *InStr, OUT UINT_8 **OutStr, OUT UINT_32 *OutLen) -+{ -+ unsigned char Charc, *Buf; -+ unsigned int Num; -+ int Maxloop; -+ int ReadId; -+ int TotalLen; -+ -+ /* init */ -+ Num = 0; -+ Maxloop = 0; -+ ReadId = 0; -+ Buf = (unsigned char *)InStr; -+ TotalLen = *OutLen; -+ *OutStr = Buf; -+ -+ /* sanity check */ -+ if (Buf[0] == 0x00) -+ return 0; -+ -+ /* check the value is decimal or hex */ -+ if ((Buf[ReadId] == 'x') || ((Buf[ReadId] == '0') && (Buf[ReadId + 1] == 'x'))) { -+ /* skip x or 0x */ -+ if (Buf[ReadId] == 'x') -+ ReadId++; -+ else -+ ReadId += 2; -+ -+ /* translate the hex number */ -+ while (Maxloop++ < 10) { -+ Charc = Buf[ReadId]; -+ if ((Charc >= 0x30) && (Charc <= 0x39)) -+ Charc -= 0x30; -+ else if ((Charc >= 'a') && (Charc <= 'f')) -+ Charc -= 'a'; -+ else if ((Charc >= 'A') && (Charc <= 'F')) -+ Charc -= 'A'; -+ else -+ break; /* exit the parsing */ -+ Num = Num * 16 + Charc + 10; -+ ReadId++; -+ TotalLen--; -+ } -+ } else { -+ /* translate the decimal number */ -+ while (Maxloop++ < 10) { -+ Charc = Buf[ReadId]; -+ if ((Charc < 0x30) || (Charc > 0x39)) -+ break; /* exit the parsing */ -+ Charc -= 0x30; -+ Num = Num * 10 + Charc; -+ ReadId++; -+ TotalLen--; -+ } -+ } -+ -+ if (Buf[ReadId] == 0x00) -+ *OutStr = &Buf[ReadId]; -+ else -+ *OutStr = &Buf[ReadId + 1]; /* skip the character: _ */ -+ -+ *OutLen = TotalLen - 1; /* skip the character: _ */ -+ return Num; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Parse command MAC address in a string. -+* -+* @param InStr Pointer to the string buffer. -+* @param OutStr Pointer to the next command value. -+* @param OutLen Record the resident buffer length. -+* -+* @retval Command value. -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT_32 CmdStringMacParse(IN UINT_8 *InStr, OUT UINT_8 **OutStr, OUT UINT_32 *OutLen, OUT UINT_8 *OutMac) -+{ -+ unsigned char Charc, *Buf; -+ unsigned int Num; -+ int Maxloop; -+ int ReadId; -+ int TotalLen; -+ -+ /* init */ -+ Num = 0; -+ Maxloop = 0; -+ ReadId = 0; -+ Buf = (unsigned char *)InStr; -+ TotalLen = *OutLen; -+ *OutStr = Buf; -+ -+ /* sanity check */ -+ if (Buf[0] == 0x00) -+ return 0; -+ -+ /* parse MAC */ -+ while (Maxloop < 6) { -+ Charc = Buf[ReadId]; -+ if ((Charc >= 0x30) && (Charc <= 0x39)) -+ Charc -= 0x30; -+ else if ((Charc >= 'a') && (Charc <= 'f')) -+ Charc = Charc - 'a' + 10; -+ else if ((Charc >= 'A') && (Charc <= 'F')) -+ Charc = Charc - 'A' + 10; -+ else -+ return -1; /* error, exit the parsing */ -+ -+ Num = Charc; -+ ReadId++; -+ TotalLen--; -+ -+ Charc = Buf[ReadId]; -+ if ((Charc >= 0x30) && (Charc <= 0x39)) -+ Charc -= 0x30; -+ else if ((Charc >= 'a') && (Charc <= 'f')) -+ Charc = Charc - 'a' + 10; -+ else if ((Charc >= 'A') && (Charc <= 'F')) -+ Charc = Charc - 'A' + 10; -+ else -+ return -1; /* error, exit the parsing */ -+ -+ Num = Num * 16 + Charc; -+ ReadId += 2; /* skip the character and ':' */ -+ TotalLen -= 2; -+ -+ OutMac[Maxloop] = Num; -+ Maxloop++; -+ } -+ -+ *OutStr = &Buf[ReadId]; /* skip the character: _ */ -+ *OutLen = TotalLen; /* skip the character: _ */ -+ return Num; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief The routine handles a set operation for a single OID. -+* -+* \param[in] pDev Net device requested. -+* \param[in] ndisReq Ndis request OID information copy from user. -+* \param[out] outputLen_p If the call is successful, returns the number of -+* bytes written into the query buffer. If the -+* call failed due to invalid length of the query -+* buffer, returns the amount of storage needed.. -+* -+* \retval 0 On success. -+* \retval -EOPNOTSUPP If cmd is not supported. -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static int -+_priv_set_string(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN char *pcExtra) -+{ -+ P_GLUE_INFO_T GlueInfo; -+ INT_32 Status; -+ UINT_32 Subcmd; -+ UINT_8 *InBuf; -+ UINT_32 InBufLen; -+ -+ /* sanity check */ -+ ASSERT(prNetDev); -+ ASSERT(prIwReqInfo); -+ ASSERT(prIwReqData); -+ ASSERT(pcExtra); -+ -+ /* init */ -+ DBGLOG(REQ, INFO, "priv_set_string (%s)(%d)\n", -+ (UINT8 *) prIwReqData->data.pointer, (INT32) prIwReqData->data.length); -+ -+ if (FALSE == GLUE_CHK_PR3(prNetDev, prIwReqData, pcExtra)) -+ return -EINVAL; -+ GlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); -+ -+ InBuf = aucOidBuf; -+ InBufLen = prIwReqData->data.length; -+ Status = 0; -+ -+ if (copy_from_user(InBuf, prIwReqData->data.pointer, prIwReqData->data.length)) -+ return -EFAULT; -+ -+ Subcmd = CmdStringDecParse(prIwReqData->data.pointer, &InBuf, &InBufLen); -+ DBGLOG(REQ, INFO, "priv_set_string> command = %u\n", (UINT32) Subcmd); -+ -+ /* handle the command */ -+ switch (Subcmd) { -+#if (CFG_SUPPORT_TDLS == 1) -+ case PRIV_CMD_OTHER_TDLS: -+ TdlsexCmd(GlueInfo, InBuf, InBufLen); -+ break; -+#endif /* CFG_SUPPORT_TDLS */ -+ -+#if (CFG_SUPPORT_TXR_ENC == 1) -+ case PRIV_CMD_OTHER_TAR: -+ { -+ rlmCmd(GlueInfo, InBuf, InBufLen); -+ break; -+ } -+#endif /* CFG_SUPPORT_TXR_ENC */ -+ default: -+ break; -+ } -+ -+ return Status; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to search desired OID. -+* -+* \param rOid[in] Desired NDIS_OID -+* \param ppWlanReqEntry[out] Found registered OID entry -+* -+* \retval TRUE: Matched OID is found -+* \retval FALSE: No matched OID is found -+*/ -+/*----------------------------------------------------------------------------*/ -+static BOOLEAN reqSearchSupportedOidEntry(IN UINT_32 rOid, OUT P_WLAN_REQ_ENTRY *ppWlanReqEntry) -+{ -+ INT_32 i, j, k; -+ -+ i = 0; -+ j = NUM_SUPPORTED_OIDS - 1; -+ -+ while (i <= j) { -+ k = (i + j) / 2; -+ -+ if (rOid == arWlanOidReqTable[k].rOid) { -+ *ppWlanReqEntry = &arWlanOidReqTable[k]; -+ return TRUE; -+ } else if (rOid < arWlanOidReqTable[k].rOid) { -+ j = k - 1; -+ } else { -+ i = k + 1; -+ } -+ } -+ -+ return FALSE; -+} /* reqSearchSupportedOidEntry */ -+ -+#if 0 -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to query the radio configuration used in IBSS -+* mode and RF test mode. -+* -+* \param[in] prGlueInfo Pointer to the GLUE_INFO_T structure. -+* \param[out] pvQueryBuffer Pointer to the buffer that holds the result of the query. -+* \param[in] u4QueryBufferLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+static WLAN_STATUS -+reqExtQueryConfiguration(IN P_GLUE_INFO_T prGlueInfo, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ P_PARAM_802_11_CONFIG_T prQueryConfig = (P_PARAM_802_11_CONFIG_T) pvQueryBuffer; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ UINT_32 u4QueryInfoLen = 0; -+ -+ DEBUGFUNC("wlanoidQueryConfiguration"); -+ -+ ASSERT(prGlueInfo); -+ ASSERT(pu4QueryInfoLen); -+ -+ *pu4QueryInfoLen = sizeof(PARAM_802_11_CONFIG_T); -+ if (u4QueryBufferLen < sizeof(PARAM_802_11_CONFIG_T)) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ ASSERT(pvQueryBuffer); -+ -+ kalMemZero(prQueryConfig, sizeof(PARAM_802_11_CONFIG_T)); -+ -+ /* Update the current radio configuration. */ -+ prQueryConfig->u4Length = sizeof(PARAM_802_11_CONFIG_T); -+ -+#if defined(_HIF_SDIO) -+ rStatus = sdio_io_ctrl(prGlueInfo, -+ wlanoidSetBeaconInterval, -+ &prQueryConfig->u4BeaconPeriod, sizeof(UINT_32), TRUE, TRUE, &u4QueryInfoLen); -+#else -+ rStatus = wlanQueryInformation(prGlueInfo->prAdapter, -+ wlanoidQueryBeaconInterval, -+ &prQueryConfig->u4BeaconPeriod, sizeof(UINT_32), &u4QueryInfoLen); -+#endif -+ if (rStatus != WLAN_STATUS_SUCCESS) -+ return rStatus; -+#if defined(_HIF_SDIO) -+ rStatus = sdio_io_ctrl(prGlueInfo, -+ wlanoidQueryAtimWindow, -+ &prQueryConfig->u4ATIMWindow, sizeof(UINT_32), TRUE, TRUE, &u4QueryInfoLen); -+#else -+ rStatus = wlanQueryInformation(prGlueInfo->prAdapter, -+ wlanoidQueryAtimWindow, -+ &prQueryConfig->u4ATIMWindow, sizeof(UINT_32), &u4QueryInfoLen); -+#endif -+ if (rStatus != WLAN_STATUS_SUCCESS) -+ return rStatus; -+#if defined(_HIF_SDIO) -+ rStatus = sdio_io_ctrl(prGlueInfo, -+ wlanoidQueryFrequency, -+ &prQueryConfig->u4DSConfig, sizeof(UINT_32), TRUE, TRUE, &u4QueryInfoLen); -+#else -+ rStatus = wlanQueryInformation(prGlueInfo->prAdapter, -+ wlanoidQueryFrequency, -+ &prQueryConfig->u4DSConfig, sizeof(UINT_32), &u4QueryInfoLen); -+#endif -+ if (rStatus != WLAN_STATUS_SUCCESS) -+ return rStatus; -+ -+ prQueryConfig->rFHConfig.u4Length = sizeof(PARAM_802_11_CONFIG_FH_T); -+ -+ return rStatus; -+ -+} /* end of reqExtQueryConfiguration() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to set the radio configuration used in IBSS -+* mode. -+* -+* \param[in] prGlueInfo Pointer to the GLUE_INFO_T structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+* \retval WLAN_STATUS_NOT_ACCEPTED -+*/ -+/*----------------------------------------------------------------------------*/ -+static WLAN_STATUS -+reqExtSetConfiguration(IN P_GLUE_INFO_T prGlueInfo, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ P_PARAM_802_11_CONFIG_T prNewConfig = (P_PARAM_802_11_CONFIG_T) pvSetBuffer; -+ UINT_32 u4SetInfoLen = 0; -+ -+ DEBUGFUNC("wlanoidSetConfiguration"); -+ -+ ASSERT(prGlueInfo); -+ ASSERT(pu4SetInfoLen); -+ -+ *pu4SetInfoLen = sizeof(PARAM_802_11_CONFIG_T); -+ -+ if (u4SetBufferLen < *pu4SetInfoLen) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ /* OID_802_11_CONFIGURATION. If associated, NOT_ACCEPTED shall be returned. */ -+ if (prGlueInfo->eParamMediaStateIndicated == PARAM_MEDIA_STATE_CONNECTED) -+ return WLAN_STATUS_NOT_ACCEPTED; -+ -+ ASSERT(pvSetBuffer); -+ -+#if defined(_HIF_SDIO) -+ rStatus = sdio_io_ctrl(prGlueInfo, -+ wlanoidSetBeaconInterval, -+ &prNewConfig->u4BeaconPeriod, sizeof(UINT_32), FALSE, TRUE, &u4SetInfoLen); -+#else -+ rStatus = wlanSetInformation(prGlueInfo->prAdapter, -+ wlanoidSetBeaconInterval, -+ &prNewConfig->u4BeaconPeriod, sizeof(UINT_32), &u4SetInfoLen); -+#endif -+ if (rStatus != WLAN_STATUS_SUCCESS) -+ return rStatus; -+#if defined(_HIF_SDIO) -+ rStatus = sdio_io_ctrl(prGlueInfo, -+ wlanoidSetAtimWindow, -+ &prNewConfig->u4ATIMWindow, sizeof(UINT_32), FALSE, TRUE, &u4SetInfoLen); -+#else -+ rStatus = wlanSetInformation(prGlueInfo->prAdapter, -+ wlanoidSetAtimWindow, &prNewConfig->u4ATIMWindow, sizeof(UINT_32), &u4SetInfoLen); -+#endif -+ if (rStatus != WLAN_STATUS_SUCCESS) -+ return rStatus; -+#if defined(_HIF_SDIO) -+ rStatus = sdio_io_ctrl(prGlueInfo, -+ wlanoidSetFrequency, -+ &prNewConfig->u4DSConfig, sizeof(UINT_32), FALSE, TRUE, &u4SetInfoLen); -+#else -+ rStatus = wlanSetInformation(prGlueInfo->prAdapter, -+ wlanoidSetFrequency, &prNewConfig->u4DSConfig, sizeof(UINT_32), &u4SetInfoLen); -+#endif -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) -+ return rStatus; -+ -+ return rStatus; -+ -+} /* end of reqExtSetConfiguration() */ -+ -+#endif -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to set beacon detection function enable/disable state -+* This is mainly designed for usage under BT inquiry state (disable function). -+* -+* \param[in] pvAdapter Pointer to the Adapter structure -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set -+* \param[in] u4SetBufferLen The length of the set buffer -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed due to invalid length of -+* the set buffer, returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_DATA If new setting value is wrong. -+* \retval WLAN_STATUS_INVALID_LENGTH -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static WLAN_STATUS -+reqExtSetAcpiDevicePowerState(IN P_GLUE_INFO_T prGlueInfo, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ -+ ASSERT(prGlueInfo); -+ ASSERT(pvSetBuffer); -+ ASSERT(pu4SetInfoLen); -+ -+ /* WIFI is enabled, when ACPI is D0 (ParamDeviceStateD0 = 1). And vice versa */ -+ -+ /* rStatus = wlanSetInformation(prGlueInfo->prAdapter, */ -+ /* wlanoidSetAcpiDevicePowerState, */ -+ /* pvSetBuffer, */ -+ /* u4SetBufferLen, */ -+ /* pu4SetInfoLen); */ -+ return rStatus; -+} -+ -+int priv_driver_set_chip_config(IN struct net_device *prNetDev, IN char *pcCommand, IN int i4TotalLen) -+{ -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ P_ADAPTER_T prAdapter = NULL; -+ UINT_32 u4BufLen = 0; -+ INT_32 i4BytesWritten = 0; -+ UINT_32 u4CmdLen = 0; -+ UINT_32 u4PrefixLen = 0; -+ /* INT_32 i4Argc = 0; */ -+ /* PCHAR apcArgv[WLAN_CFG_ARGV_MAX] = {0}; */ -+ -+ PARAM_CUSTOM_CHIP_CONFIG_STRUCT_T rChipConfigInfo; -+ -+ ASSERT(prNetDev); -+ if (FALSE == GLUE_CHK_PR2(prNetDev, pcCommand)) -+ return -1; -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); -+ prAdapter = prGlueInfo->prAdapter; -+ DBGLOG(REQ, INFO, "priv_driver_set_chip_config command is %s\n", pcCommand); -+ /* wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); */ -+ /* DBGLOG(REQ, LOUD,("argc is %i\n",i4Argc)); */ -+ /* */ -+ u4CmdLen = kalStrnLen(pcCommand, i4TotalLen); -+ u4PrefixLen = kalStrLen(CMD_SET_CHIP) + 1 /*space */; -+ -+ kalMemZero(&rChipConfigInfo, sizeof(rChipConfigInfo)); -+ -+ /* if(i4Argc >= 2) { */ -+ if (u4CmdLen > u4PrefixLen) { -+ -+ rChipConfigInfo.ucType = CHIP_CONFIG_TYPE_WO_RESPONSE; -+ /* rChipConfigInfo.u2MsgSize = kalStrnLen(apcArgv[1],CHIP_CONFIG_RESP_SIZE); */ -+ rChipConfigInfo.u2MsgSize = u4CmdLen - u4PrefixLen; -+ /* kalStrnCpy(rChipConfigInfo.aucCmd,apcArgv[1],CHIP_CONFIG_RESP_SIZE); */ -+ if (u4PrefixLen <= CHIP_CONFIG_RESP_SIZE) { -+ kalStrnCpy(rChipConfigInfo.aucCmd, pcCommand + u4PrefixLen, -+ CHIP_CONFIG_RESP_SIZE - u4PrefixLen); -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetChipConfig, -+ &rChipConfigInfo, -+ sizeof(rChipConfigInfo), FALSE, FALSE, TRUE, TRUE, &u4BufLen); -+ } else { -+ -+ DBGLOG(REQ, INFO, "%s: kalIoctl Command Len > %d\n", __func__, CHIP_CONFIG_RESP_SIZE); -+ rStatus = WLAN_STATUS_FAILURE; -+ } -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ DBGLOG(REQ, INFO, "%s: kalIoctl ret=%d\n", __func__, rStatus); -+ i4BytesWritten = -1; -+ } -+ } -+ -+ return i4BytesWritten; -+ -+} -+ -+int priv_driver_set_miracast(IN struct net_device *prNetDev, IN char *pcCommand, IN int i4TotalLen) -+{ -+ P_ADAPTER_T prAdapter = NULL; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ UINT_32 i4BytesWritten = 0; -+ /* WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; */ -+ /* UINT_32 u4BufLen = 0; */ -+ INT_32 i4Argc = 0; -+ UINT_32 ucMode = 0; -+ P_WFD_CFG_SETTINGS_T prWfdCfgSettings = (P_WFD_CFG_SETTINGS_T) NULL; -+ P_MSG_WFD_CONFIG_SETTINGS_CHANGED_T prMsgWfdCfgUpdate = (P_MSG_WFD_CONFIG_SETTINGS_CHANGED_T) NULL; -+ PCHAR apcArgv[WLAN_CFG_ARGV_MAX]; -+ INT_32 u4Ret; -+ -+ ASSERT(prNetDev); -+ if (FALSE == GLUE_CHK_PR2(prNetDev, pcCommand)) -+ return -1; -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); -+ -+ DBGLOG(REQ, LOUD, "command is %s\n", pcCommand); -+ wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); -+ DBGLOG(REQ, LOUD, "argc is %i\n", i4Argc); -+ -+ prAdapter = prGlueInfo->prAdapter; -+ if (i4Argc >= 2) { -+ u4Ret = kalkStrtou32(apcArgv[1], 0, &ucMode); /* ucMode = kalStrtoul(apcArgv[1], NULL, 0); */ -+ if (u4Ret) -+ DBGLOG(REQ, LOUD, "parse pcCommand error u4Ret=%d\n", u4Ret); -+ -+ if (g_ucMiracastMode == ucMode) -+ ; -+ /* XXX: continue or skip */ -+ -+ g_ucMiracastMode = ucMode; -+ prMsgWfdCfgUpdate = cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_WFD_CONFIG_SETTINGS_CHANGED_T)); -+ -+ if (prMsgWfdCfgUpdate != NULL) { -+ -+ prWfdCfgSettings = &(prGlueInfo->prAdapter->rWifiVar.prP2pFsmInfo->rWfdConfigureSettings); -+ prMsgWfdCfgUpdate->rMsgHdr.eMsgId = MID_MNY_P2P_WFD_CFG_UPDATE; -+ prMsgWfdCfgUpdate->prWfdCfgSettings = prWfdCfgSettings; -+ -+ if (ucMode == MIRACAST_MODE_OFF) { -+ prWfdCfgSettings->ucWfdEnable = 0; -+ snprintf(pcCommand, i4TotalLen, CMD_SET_CHIP " mira 0"); -+ } else if (ucMode == MIRACAST_MODE_SOURCE) { -+ prWfdCfgSettings->ucWfdEnable = 1; -+ snprintf(pcCommand, i4TotalLen, CMD_SET_CHIP " mira 1"); -+ } else if (ucMode == MIRACAST_MODE_SINK) { -+ prWfdCfgSettings->ucWfdEnable = 2; -+ snprintf(pcCommand, i4TotalLen, CMD_SET_CHIP " mira 2"); -+ } else { -+ prWfdCfgSettings->ucWfdEnable = 0; -+ snprintf(pcCommand, i4TotalLen, CMD_SET_CHIP " mira 0"); -+ } -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgWfdCfgUpdate, MSG_SEND_METHOD_BUF); -+ -+ priv_driver_set_chip_config(prNetDev, pcCommand, i4TotalLen); -+ -+ } /* prMsgWfdCfgUpdate */ -+ else { -+ ASSERT(FALSE); -+ i4BytesWritten = -1; -+ } -+ } -+ -+ /* i4Argc */ -+ return i4BytesWritten; -+} -+ -+int priv_support_driver_cmd(IN struct net_device *prNetDev, IN OUT struct ifreq *prReq, IN int i4Cmd) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ int ret = 0; -+ char *pcCommand = NULL; -+ priv_driver_cmd_t *priv_cmd = NULL; -+ int i4BytesWritten = 0; -+ int i4TotalLen = 0; -+ -+ if (!prReq->ifr_data) { -+ ret = -EINVAL; -+ goto exit; -+ } -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); -+ -+ if (!prGlueInfo) { -+ DBGLOG(REQ, WARN, "No glue info\n"); -+ ret = -EFAULT; -+ goto exit; -+ } -+ if (prGlueInfo->u4ReadyFlag == 0) { -+ ret = -EINVAL; -+ goto exit; -+ } -+ -+ priv_cmd = kzalloc(sizeof(priv_driver_cmd_t), GFP_KERNEL); -+ if (!priv_cmd) { -+ DBGLOG(REQ, WARN, "%s, alloc mem failed\n", __func__); -+ return -ENOMEM; -+ } -+ -+ if (copy_from_user(priv_cmd, prReq->ifr_data, sizeof(priv_driver_cmd_t))) { -+ DBGLOG(REQ, INFO, "%s: copy_from_user fail\n", __func__); -+ ret = -EFAULT; -+ goto exit; -+ } -+ -+ i4TotalLen = priv_cmd->total_len; -+ -+ if (i4TotalLen <= 0) { -+ ret = -EINVAL; -+ DBGLOG(REQ, INFO, "%s: i4TotalLen invalid\n", __func__); -+ goto exit; -+ } -+ -+ pcCommand = priv_cmd->buf; -+ -+ DBGLOG(REQ, INFO, "%s: driver cmd \"%s\" on %s\n", __func__, pcCommand, prReq->ifr_name); -+ -+ i4BytesWritten = priv_driver_cmds(prNetDev, pcCommand, i4TotalLen); -+ -+ if (i4BytesWritten < 0) { -+ DBGLOG(REQ, INFO, "%s: command %s failed; Written is %d\n", -+ __func__, pcCommand, i4BytesWritten); -+ ret = -EFAULT; -+ } -+ -+exit: -+ kfree(priv_cmd); -+ -+ return ret; -+} -+ -+#if CFG_SUPPORT_BATCH_SCAN -+#define CMD_BATCH_SET "WLS_BATCHING SET" -+#define CMD_BATCH_GET "WLS_BATCHING GET" -+#define CMD_BATCH_STOP "WLS_BATCHING STOP" -+#endif -+ -+#if CFG_SUPPORT_GET_CH_ENV -+#define CMD_CH_ENV_GET "CH_ENV_GET" -+#endif -+ -+INT_32 priv_driver_cmds(IN struct net_device *prNetDev, IN PCHAR pcCommand, IN INT_32 i4TotalLen) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ INT_32 i4BytesWritten = 0; -+ INT_32 i4CmdFound = 0; -+ -+ if (FALSE == GLUE_CHK_PR2(prNetDev, pcCommand)) -+ return -1; -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); -+ -+ if (i4CmdFound == 0) { -+ i4CmdFound = 1; -+ -+ if (strnicmp(pcCommand, CMD_MIRACAST, strlen(CMD_MIRACAST)) == 0) -+ i4BytesWritten = priv_driver_set_miracast(prNetDev, pcCommand, i4TotalLen); -+#if CFG_SUPPORT_BATCH_SCAN -+ else if (strnicmp(pcCommand, CMD_BATCH_SET, strlen(CMD_BATCH_SET)) == 0) { -+ kalIoctl(prGlueInfo, -+ wlanoidSetBatchScanReq, -+ (PVOID) pcCommand, i4TotalLen, FALSE, FALSE, TRUE, FALSE, &i4BytesWritten); -+ } else if (strnicmp(pcCommand, CMD_BATCH_GET, strlen(CMD_BATCH_GET)) == 0) { -+ /* strcpy(pcCommand, "BATCH SCAN DATA FROM FIRMWARE"); */ -+ /* i4BytesWritten = strlen("BATCH SCAN DATA FROM FIRMWARE") + 1; */ -+ /* i4BytesWritten = priv_driver_get_linkspeed (prNetDev, pcCommand, i4TotalLen); */ -+ -+ UINT_32 u4BufLen; -+ int i; -+ /* int rlen=0; */ -+ -+ for (i = 0; i < CFG_BATCH_MAX_MSCAN; i++) { -+ g_rEventBatchResult[i].ucScanCount = i + 1; /* for get which mscan */ -+ kalIoctl(prGlueInfo, -+ wlanoidQueryBatchScanResult, -+ (PVOID)&g_rEventBatchResult[i], -+ sizeof(EVENT_BATCH_RESULT_T), TRUE, TRUE, TRUE, FALSE, &u4BufLen); -+ } -+ -+#if 0 -+ DBGLOG(SCN, INFO, "Batch Scan Results, scan count = %u\n", g_rEventBatchResult.ucScanCount); -+ for (i = 0; i < g_rEventBatchResult.ucScanCount; i++) { -+ prEntry = &g_rEventBatchResult.arBatchResult[i]; -+ DBGLOG(SCN, INFO, "Entry %u\n", i); -+ DBGLOG(SCN, INFO, " BSSID = %pM\n", prEntry->aucBssid); -+ DBGLOG(SCN, INFO, " SSID = %s\n", prEntry->aucSSID); -+ DBGLOG(SCN, INFO, " SSID len = %u\n", prEntry->ucSSIDLen); -+ DBGLOG(SCN, INFO, " RSSI = %d\n", prEntry->cRssi); -+ DBGLOG(SCN, INFO, " Freq = %u\n", prEntry->ucFreq); -+ } -+#endif -+ -+ batchConvertResult(&g_rEventBatchResult[0], pcCommand, i4TotalLen, &i4BytesWritten); -+ -+ /* Dump for debug */ -+ /* print_hex_dump(KERN_INFO, "BATCH", DUMP_PREFIX_ADDRESS, 16, 1, pcCommand, -+ i4BytesWritten, TRUE); */ -+ -+ } else if (strnicmp(pcCommand, CMD_BATCH_STOP, strlen(CMD_BATCH_STOP)) == 0) { -+ kalIoctl(prGlueInfo, -+ wlanoidSetBatchScanReq, -+ (PVOID) pcCommand, i4TotalLen, FALSE, FALSE, TRUE, FALSE, &i4BytesWritten); -+ } -+#endif -+#if CFG_SUPPORT_GET_CH_ENV -+ else if (strnicmp(pcCommand, CMD_CH_ENV_GET, strlen(CMD_CH_ENV_GET)) == 0) -+ scanEnvResult(prGlueInfo, pcCommand, i4TotalLen, &i4BytesWritten); -+#endif -+ -+#if 0 -+ -+ else if (strnicmp(pcCommand, CMD_RSSI, strlen(CMD_RSSI)) == 0) { -+ /* i4BytesWritten = wl_android_get_rssi(net, command, i4TotalLen); */ -+ } else if (strnicmp(pcCommand, CMD_LINKSPEED, strlen(CMD_LINKSPEED)) == 0) { -+ i4BytesWritten = priv_driver_get_linkspeed(prNetDev, pcCommand, i4TotalLen); -+ } else if (strnicmp(pcCommand, CMD_PNOSSIDCLR_SET, strlen(CMD_PNOSSIDCLR_SET)) == 0) { -+ /* Do nothing */ -+ } else if (strnicmp(pcCommand, CMD_PNOSETUP_SET, strlen(CMD_PNOSETUP_SET)) == 0) { -+ /* Do nothing */ -+ } else if (strnicmp(pcCommand, CMD_PNOENABLE_SET, strlen(CMD_PNOENABLE_SET)) == 0) { -+ /* Do nothing */ -+ } else if (strnicmp(pcCommand, CMD_SETSUSPENDOPT, strlen(CMD_SETSUSPENDOPT)) == 0) { -+ /* i4BytesWritten = wl_android_set_suspendopt(net, pcCommand, i4TotalLen); */ -+ } else if (strnicmp(pcCommand, CMD_SETSUSPENDMODE, strlen(CMD_SETSUSPENDMODE)) == 0) { -+ i4BytesWritten = priv_driver_set_suspend_mode(prNetDev, pcCommand, i4TotalLen); -+ } else if (strnicmp(pcCommand, CMD_SETBAND, strlen(CMD_SETBAND)) == 0) { -+ i4BytesWritten = priv_driver_set_band(prNetDev, pcCommand, i4TotalLen); -+ } else if (strnicmp(pcCommand, CMD_GETBAND, strlen(CMD_GETBAND)) == 0) { -+ /* i4BytesWritten = wl_android_get_band(net, pcCommand, i4TotalLen); */ -+ } else if (strnicmp(pcCommand, CMD_COUNTRY, strlen(CMD_COUNTRY)) == 0) { -+ i4BytesWritten = priv_driver_set_country(prNetDev, pcCommand, i4TotalLen); -+ } -+ /* Mediatek private command */ -+ else if (strnicmp(pcCommand, CMD_SET_SW_CTRL, strlen(CMD_SET_SW_CTRL)) == 0) { -+ i4BytesWritten = priv_driver_set_sw_ctrl(prNetDev, pcCommand, i4TotalLen); -+ } else if (strnicmp(pcCommand, CMD_GET_SW_CTRL, strlen(CMD_GET_SW_CTRL)) == 0) { -+ i4BytesWritten = priv_driver_get_sw_ctrl(prNetDev, pcCommand, i4TotalLen); -+ } else if (strnicmp(pcCommand, CMD_SET_CFG, strlen(CMD_SET_CFG)) == 0) { -+ i4BytesWritten = priv_driver_set_cfg(prNetDev, pcCommand, i4TotalLen); -+ } else if (strnicmp(pcCommand, CMD_GET_CFG, strlen(CMD_GET_CFG)) == 0) { -+ i4BytesWritten = priv_driver_get_cfg(prNetDev, pcCommand, i4TotalLen); -+ } else if (strnicmp(pcCommand, CMD_SET_CHIP, strlen(CMD_SET_CHIP)) == 0) { -+ i4BytesWritten = priv_driver_set_chip_config(prNetDev, pcCommand, i4TotalLen); -+ } else if (strnicmp(pcCommand, CMD_GET_CHIP, strlen(CMD_GET_CHIP)) == 0) { -+ i4BytesWritten = priv_driver_get_chip_config(prNetDev, pcCommand, i4TotalLen); -+ } else if (strnicmp(pcCommand, CMD_SET_DBG_LEVEL, strlen(CMD_SET_DBG_LEVEL)) == 0) { -+ i4BytesWritten = priv_driver_set_dbg_level(prNetDev, pcCommand, i4TotalLen); -+ } else if (strnicmp(pcCommand, CMD_GET_DBG_LEVEL, strlen(CMD_GET_DBG_LEVEL)) == 0) { -+ i4BytesWritten = priv_driver_get_dbg_level(prNetDev, pcCommand, i4TotalLen); -+ } -+#if CFG_SUPPORT_BATCH_SCAN -+ else if (strnicmp(pcCommand, CMD_BATCH_SET, strlen(CMD_BATCH_SET)) == 0) { -+ kalIoctl(prGlueInfo, -+ wlanoidSetBatchScanReq, -+ (PVOID) pcCommand, i4TotalLen, FALSE, FALSE, TRUE, &i4BytesWritten); -+ } else if (strnicmp(pcCommand, CMD_BATCH_GET, strlen(CMD_BATCH_GET)) == 0) { -+ /* strcpy(pcCommand, "BATCH SCAN DATA FROM FIRMWARE"); */ -+ /* i4BytesWritten = strlen("BATCH SCAN DATA FROM FIRMWARE") + 1; */ -+ /* i4BytesWritten = priv_driver_get_linkspeed (prNetDev, pcCommand, i4TotalLen); */ -+ -+ UINT_32 u4BufLen; -+ int i; -+ /* int rlen=0; */ -+ -+ for (i = 0; i < CFG_BATCH_MAX_MSCAN; i++) { -+ g_rEventBatchResult[i].ucScanCount = i + 1; /* for get which mscan */ -+ kalIoctl(prGlueInfo, -+ wlanoidQueryBatchScanResult, -+ (PVOID)&g_rEventBatchResult[i], -+ sizeof(EVENT_BATCH_RESULT_T), TRUE, TRUE, TRUE, &u4BufLen); -+ } -+ -+#if 0 -+ DBGLOG(SCN, INFO, "Batch Scan Results, scan count = %u\n", g_rEventBatchResult.ucScanCount); -+ for (i = 0; i < g_rEventBatchResult.ucScanCount; i++) { -+ prEntry = &g_rEventBatchResult.arBatchResult[i]; -+ DBGLOG(SCN, INFO, "Entry %u\n", i); -+ DBGLOG(SCN, INFO, " BSSID = %pM\n", prEntry->aucBssid); -+ DBGLOG(SCN, INFO, " SSID = %s\n", prEntry->aucSSID); -+ DBGLOG(SCN, INFO, " SSID len = %u\n", prEntry->ucSSIDLen); -+ DBGLOG(SCN, INFO, " RSSI = %d\n", prEntry->cRssi); -+ DBGLOG(SCN, INFO, " Freq = %u\n", prEntry->ucFreq); -+ } -+#endif -+ -+ batchConvertResult(&g_rEventBatchResult[0], pcCommand, i4TotalLen, &i4BytesWritten); -+ -+ /* Dump for debug */ -+ /* print_hex_dump(KERN_INFO, "BATCH", DUMP_PREFIX_ADDRESS, 16, 1, pcCommand, i4BytesWritten, -+ TRUE); */ -+ -+ } else if (strnicmp(pcCommand, CMD_BATCH_STOP, strlen(CMD_BATCH_STOP)) == 0) { -+ kalIoctl(prGlueInfo, -+ wlanoidSetBatchScanReq, -+ (PVOID) pcCommand, i4TotalLen, FALSE, FALSE, TRUE, &i4BytesWritten); -+ } -+#endif -+ -+#endif -+ -+ else -+ i4CmdFound = 0; -+ } -+ -+ /* i4CmdFound */ -+ if (i4CmdFound == 0) -+ DBGLOG(REQ, TRACE, "Unknown driver command %s - ignored\n", pcCommand); -+ -+ if (i4BytesWritten >= 0) { -+ if ((i4BytesWritten == 0) && (i4TotalLen > 0)) { -+ /* reset the command buffer */ -+ pcCommand[0] = '\0'; -+ } -+ -+ if (i4BytesWritten >= i4TotalLen) { -+ DBGLOG(REQ, INFO, -+ "%s: i4BytesWritten %d > i4TotalLen < %d\n", __func__, i4BytesWritten, i4TotalLen); -+ i4BytesWritten = i4TotalLen; -+ } else { -+ pcCommand[i4BytesWritten] = '\0'; -+ i4BytesWritten++; -+ } -+ } -+ -+ return i4BytesWritten; -+ -+} -+ -+static int compat_priv(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN char *pcExtra, -+ int (*priv_func)(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN char *pcExtra)) -+{ -+ struct iw_point *prIwp; -+ int ret = 0; -+#ifdef CONFIG_COMPAT -+ struct compat_iw_point *iwp_compat = NULL; -+ struct iw_point iwp; -+#endif -+ -+ if (!prIwReqData) -+ return -EINVAL; -+ -+#ifdef CONFIG_COMPAT -+ if (prIwReqInfo->flags & IW_REQUEST_FLAG_COMPAT) { -+ iwp_compat = (struct compat_iw_point *) &prIwReqData->data; -+ iwp.pointer = compat_ptr(iwp_compat->pointer); -+ iwp.length = iwp_compat->length; -+ iwp.flags = iwp_compat->flags; -+ prIwp = &iwp; -+ } else -+#endif -+ prIwp = &prIwReqData->data; -+ -+ -+ ret = priv_func(prNetDev, prIwReqInfo, (union iwreq_data *)prIwp, pcExtra); -+ -+#ifdef CONFIG_COMPAT -+ if (prIwReqInfo->flags & IW_REQUEST_FLAG_COMPAT) { -+ iwp_compat->pointer = ptr_to_compat(iwp.pointer); -+ iwp_compat->length = iwp.length; -+ iwp_compat->flags = iwp.flags; -+ } -+#endif -+ return ret; -+} -+ -+int -+priv_set_int(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN char *pcExtra) -+{ -+ return compat_priv(prNetDev, prIwReqInfo, prIwReqData, pcExtra, _priv_set_int); -+} -+ -+int -+priv_get_int(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN OUT char *pcExtra) -+{ -+ return compat_priv(prNetDev, prIwReqInfo, prIwReqData, pcExtra, _priv_get_int); -+} -+ -+int -+priv_set_ints(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN char *pcExtra) -+{ -+ return compat_priv(prNetDev, prIwReqInfo, prIwReqData, pcExtra, _priv_set_ints); -+} -+ -+int -+priv_get_ints(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN OUT char *pcExtra) -+{ -+ return compat_priv(prNetDev, prIwReqInfo, prIwReqData, pcExtra, _priv_get_ints); -+} -+ -+int -+priv_set_struct(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN char *pcExtra) -+{ -+ return compat_priv(prNetDev, prIwReqInfo, prIwReqData, pcExtra, _priv_set_struct); -+} -+ -+int -+priv_get_struct(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN OUT char *pcExtra) -+{ -+ return compat_priv(prNetDev, prIwReqInfo, prIwReqData, pcExtra, _priv_get_struct); -+} -+ -+int -+priv_set_string(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN char *pcExtra) -+{ -+ return compat_priv(prNetDev, prIwReqInfo, prIwReqData, pcExtra, _priv_set_string); -+} -+ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/ahb.c b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/ahb.c -new file mode 100644 -index 000000000000..c13d24906bf8 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/ahb.c -@@ -0,0 +1,1643 @@ -+/****************************************************************************** -+*[File] ahb.c -+*[Version] v1.0 -+*[Revision Date] 2013-01-16 -+*[Author] -+*[Description] -+* The program provides AHB HIF driver -+*[Copyright] -+* Copyright (C) 2013 MediaTek Incorporation. All Rights Reserved. -+******************************************************************************/ -+ -+/* -+** Log: ahb.c -+ * -+ * 01 16 2013 vend_samp.lin -+ * Port sdio.c to ahb.c on MT6572/MT6582 -+ * 1) Initial version -+ * -+ * 04 12 2012 terry.wu -+ * NULL -+ * Add AEE message support -+ * 1) Show AEE warning(red screen) if SDIO access error occurs -+ * -+ * 02 14 2012 cp.wu -+ * [WCXRP00000851] [MT6628 Wi-Fi][Driver] Add HIFSYS related definition to driver source tree -+ * include correct header file upon setting. -+ * -+ * 11 10 2011 cp.wu -+ * [WCXRP00001098] [MT6620 Wi-Fi][Driver] Replace printk by DBG LOG macros in linux porting layer -+ * 1. eliminaite direct calls to printk in porting layer. -+ * 2. replaced by DBGLOG, which would be XLOG on ALPS platforms. -+ * -+ * 09 20 2011 cp.wu -+ * [WCXRP00000994] [MT6620 Wi-Fi][Driver] dump message for bus error and reset bus error flag while re-initialized -+ * 1. always show error message for SDIO bus errors. -+ * 2. reset bus error flag when re-initialization -+ * -+ * 08 17 2011 cp.wu -+ * [WCXRP00000851] [MT6628 Wi-Fi][Driver] Add HIFSYS related definition to driver source tree -+ * add MT6628 related definitions for Linux/Android driver. -+ * -+ * 05 18 2011 cp.wu -+ * [WCXRP00000702] [MT5931][Driver] Modify initialization sequence for E1 ASIC -+ * add device ID for MT5931. -+ * -+ * 04 08 2011 pat.lu -+ * [WCXRP00000623] [MT6620 Wi-Fi][Driver] use ARCH define to distinguish PC Linux driver -+ * Use CONFIG_X86 instead of PC_LINUX_DRIVER_USE option to have proper compile setting for PC Linux driver -+ * -+ * 03 22 2011 pat.lu -+ * [WCXRP00000592] [MT6620 Wi-Fi][Driver] Support PC Linux Environment Driver Build -+ * Add a compiler option "PC_LINUX_DRIVER_USE" for building driver in PC Linux environment. -+ * -+ * 03 18 2011 cp.wu -+ * [WCXRP00000559] [MT6620 Wi-Fi][Driver] Combine TX/RX DMA buffers into a single one to reduce physically continuous -+ * memory consumption -+ * deprecate CFG_HANDLE_IST_IN_SDIO_CALLBACK. -+ * -+ * 03 15 2011 cp.wu -+ * [WCXRP00000559] [MT6620 Wi-Fi][Driver] Combine TX/RX DMA buffers into a single one to reduce physically continuous -+ * memory consumption -+ * 1. deprecate CFG_HANDLE_IST_IN_SDIO_CALLBACK -+ * 2. Use common coalescing buffer for both TX/RX directions -+ * -+ * -+ * 03 07 2011 terry.wu -+ * [WCXRP00000521] [MT6620 Wi-Fi][Driver] Remove non-standard debug message -+ * Toggle non-standard debug messages to comments. -+ * -+ * 11 15 2010 jeffrey.chang -+ * [WCXRP00000181] [MT6620 Wi-Fi][Driver] fix the driver message "GLUE_FLAG_HALT skip INT" during unloading -+ * Fix GLUE_FALG_HALT message which cause driver to hang -+ * -+ * 11 08 2010 cp.wu -+ * [WCXRP00000166] [MT6620 Wi-Fi][Driver] use SDIO CMD52 for enabling/disabling interrupt to reduce transaction period -+ * correct typo -+ * -+ * 11 08 2010 cp.wu -+ * [WCXRP00000166] [MT6620 Wi-Fi][Driver] use SDIO CMD52 for enabling/disabling interrupt to reduce transaction period -+ * change to use CMD52 for enabling/disabling interrupt to reduce SDIO transaction time -+ * -+ * 11 01 2010 yarco.yang -+ * [WCXRP00000149] [MT6620 WI-Fi][Driver]Fine tune performance on MT6516 platform -+ * Add code to run WlanIST in SDIO callback. -+ * -+ * 10 19 2010 cp.wu -+ * [WCXRP00000122] [MT6620 Wi-Fi][Driver] Preparation for YuSu source tree integration -+ * remove HIF_SDIO_ONE flags because the settings could be merged for runtime detection instead of compile-time. -+ * -+ * 10 19 2010 jeffrey.chang -+ * [WCXRP00000120] [MT6620 Wi-Fi][Driver] Refine linux kernel module to the license of MTK propietary and enable MTK -+ * HIF by default -+ * Refine linux kernel module to the license of MTK and enable MTK HIF -+ * -+ * 08 21 2010 jeffrey.chang -+ * NULL -+ * 1) add sdio two setting -+ * 2) bug fix of sdio glue -+ * -+ * 08 18 2010 jeffrey.chang -+ * NULL -+ * support multi-function sdio -+ * -+ * 08 18 2010 cp.wu -+ * NULL -+ * #if defined(__X86__) is not working, change to use #ifdef CONFIG_X86. -+ * -+ * 08 17 2010 cp.wu -+ * NULL -+ * add ENE SDIO host workaround for x86 linux platform. -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 05 07 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * Fix hotplug bug -+ * -+ * 03 28 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * clear sdio interrupt -+ * -+ * 03 24 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * initial import for Linux port -+** -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include -+/* #include */ -+#include -+/* #include */ -+#include -+/* #include */ -+/* #include */ -+/* #include */ -+ -+#include -+#ifndef CONFIG_X86 -+#include -+#endif -+ -+#ifdef CONFIG_OF -+#include -+#include -+#include -+#else -+ -+#endif -+ -+/* #include -+#include */ -+ -+#include "gl_os.h" -+ -+#if defined(MT6620) -+#include "mt6620_reg.h" -+#elif defined(MT6628) -+#include "mtreg.h" -+#endif -+ -+#if !defined(CONFIG_MTK_CLKMGR) -+#include -+#endif -+ -+/* #define MTK_DMA_BUF_MEMCPY_SUP */ /* no virt_to_phys() use */ -+/* #define HIF_DEBUG_SUP */ -+/* #define HIF_DEBUG_SUP_TX */ -+ -+#ifdef HIF_DEBUG_SUP -+#define HIF_DBG(msg) (printk msg) -+#else -+#define HIF_DBG(msg) -+#endif /* HIF_DEBUG_SUP */ -+ -+#ifdef HIF_DEBUG_SUP_TX -+#define HIF_DBG_TX(msg) (printk msg) -+#else -+#define HIF_DBG_TX(msg) -+#endif /* HIF_DEBUG_SUP */ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+static UINT_32 -+HifAhbDmaEnhanceModeConf(IN GLUE_INFO_T *GlueInfo, IN UINT_32 BurstLen, IN UINT_32 PortId, IN UINT_32 TransByte); -+ -+static irqreturn_t HifAhbISR(IN int Irq, IN void *Arg); -+ -+static int HifAhbProbe(VOID); -+ -+static int HifAhbRemove(VOID); -+ -+#if (MTK_WCN_SINGLE_MODULE == 0) -+static int HifAhbBusCntGet(VOID); -+ -+static int HifAhbBusCntClr(VOID); -+ -+static int HifTxCnt; -+#endif /* MTK_WCN_SINGLE_MODULE */ -+ -+#if (CONF_HIF_DEV_MISC == 1) -+static ssize_t HifAhbMiscRead(IN struct file *Filp, OUT char __user *DstBuf, IN size_t Size, IN loff_t *Ppos); -+ -+static ssize_t HifAhbMiscWrite(IN struct file *Filp, IN const char __user *SrcBuf, IN size_t Size, IN loff_t *Ppos); -+ -+static int HifAhbMiscIoctl(IN struct file *Filp, IN unsigned int Cmd, IN unsigned long arg); -+ -+static int HifAhbMiscOpen(IN struct inode *Inodep, IN struct file *Filp); -+ -+static int HifAhbMiscClose(IN struct inode *Inodep, IN struct file *Filp); -+#else -+ -+static int HifAhbPltmProbe(IN struct platform_device *PDev); -+ -+static int __exit HifAhbPltmRemove(IN struct platform_device *PDev); -+ -+#ifdef CONFIG_PM -+static int HifAhbPltmSuspend(IN struct platform_device *PDev, pm_message_t Message); -+ -+static int HifAhbPltmResume(IN struct platform_device *PDev); -+#endif /* CONFIG_PM */ -+ -+#endif /* CONF_HIF_DEV_MISC */ -+ -+#if (CONF_HIF_LOOPBACK_AUTO == 1) /* only for development test */ -+static VOID HifAhbLoopbkAuto(IN unsigned long arg); -+#endif /* CONF_HIF_LOOPBACK_AUTO */ -+ -+#if (CONF_HIF_DMA_INT == 1) -+static irqreturn_t HifDmaISR(IN int Irq, IN void *Arg); -+#endif /* CONF_HIF_DMA_INT */ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/* initialiation function from other module */ -+static probe_card pfWlanProbe; -+ -+/* release function from other module */ -+static remove_card pfWlanRemove; -+ -+static BOOLEAN WlanDmaFatalErr; -+ -+#if (CONF_HIF_DEV_MISC == 1) -+static const struct file_operations MtkAhbOps = { -+ .owner = THIS_MODULE, -+ .read = HifAhbMiscRead, -+ .write = HifAhbMiscWrite, -+ .unlocked_ioctl = HifAhbMiscIoctl, -+#ifdef CONFIG_COMPAT -+ .compat_ioctl = HifAhbMiscIoctl, -+#endif -+ .open = HifAhbMiscOpen, -+ .release = HifAhbMiscClose, -+}; -+ -+static struct miscdevice MtkAhbDriver = { -+ .minor = MISC_DYNAMIC_MINOR, /* any minor number */ -+ .name = HIF_MOD_NAME, -+ .fops = &MtkAhbOps, -+}; -+#else -+ -+#ifdef CONFIG_OF -+static const struct of_device_id apwifi_of_ids[] = { -+ {.compatible = "mediatek,wifi", .data = (void *)0}, -+ {.compatible = "mediatek,mt7623-wifi", .data = (void *)0x7623}, -+ {} -+}; -+#endif -+ -+struct platform_driver MtkPltmAhbDriver = { -+ .driver = { -+ .name = "mt-wifi", -+ .owner = THIS_MODULE, -+#ifdef CONFIG_OF -+ .of_match_table = apwifi_of_ids, -+#endif -+ }, -+ .probe = HifAhbPltmProbe, -+#ifdef CONFIG_PM -+ .suspend = HifAhbPltmSuspend, -+ .resume = HifAhbPltmResume, -+#else -+ .suspend = NULL, -+ .resume = NULL, -+#endif /* CONFIG_PM */ -+ .remove = __exit_p(HifAhbPltmRemove), -+}; -+ -+static struct platform_device *HifAhbPDev; -+ -+#endif /* CONF_HIF_DEV_MISC */ -+ -+/******************************************************************************* -+* P U B L I C F U N C T I O N S -+******************************************************************************** -+*/ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will register sdio bus to the os -+* -+* \param[in] pfProbe Function pointer to detect card -+* \param[in] pfRemove Function pointer to remove card -+* -+* \return The result of registering HIF driver (WLAN_STATUS_SUCCESS = 0) -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS glRegisterBus(probe_card pfProbe, remove_card pfRemove) -+{ -+ WLAN_STATUS Ret; -+ -+ ASSERT(pfProbe); -+ ASSERT(pfRemove); -+ -+ pfWlanProbe = pfProbe; /* wlan card initialization in other modules = wlanProbe() */ -+ pfWlanRemove = pfRemove; -+ -+#if (CONF_HIF_DEV_MISC == 1) -+ Ret = misc_register(&MtkAhbDriver); -+ if (Ret != 0) -+ return Ret; -+ HifAhbProbe(); -+#else -+ Ret = platform_driver_register(&MtkPltmAhbDriver); -+#endif /* CONF_HIF_DEV_MISC */ -+ -+ return Ret; -+ -+} /* end of glRegisterBus() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will unregister sdio bus to the os -+* -+* \param[in] pfRemove Function pointer to remove card -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID glUnregisterBus(remove_card pfRemove) -+{ -+ ASSERT(pfRemove); -+ -+ pfRemove(); -+ -+#if (CONF_HIF_DEV_MISC == 1) -+ HifAhbRemove(); -+ -+ if ((misc_deregister(&MtkAhbDriver)) != 0) -+ ; -+#else -+ -+ platform_driver_unregister(&MtkPltmAhbDriver); -+#endif /* CONF_HIF_DEV_MISC */ -+ -+ return; -+ -+} /* end of glUnregisterBus() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will inform us whole chip reset start event. -+* -+* \param[in] GlueInfo Pointer to glue info structure -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID glResetHif(GLUE_INFO_T *GlueInfo) -+{ -+ GL_HIF_INFO_T *HifInfo; -+ -+ ASSERT(GlueInfo); -+ HifInfo = &GlueInfo->rHifInfo; -+ if (HifInfo->DmaOps) -+ HifInfo->DmaOps->DmaReset(HifInfo); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function stores hif related info, which is initialized before. -+* -+* \param[in] GlueInfo Pointer to glue info structure -+* \param[in] u4Cookie Pointer to UINT_32 memory base variable for _HIF_HPI -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID glSetHifInfo(GLUE_INFO_T *GlueInfo, ULONG ulCookie) -+{ -+ GL_HIF_INFO_T *HifInfo; -+ const struct of_device_id *of_id; -+ -+ /* Init HIF */ -+ ASSERT(GlueInfo); -+ HifInfo = &GlueInfo->rHifInfo; -+#if (CONF_HIF_DEV_MISC == 1) -+ HifInfo->Dev = MtkAhbDriver.this_device; -+#else -+ HifInfo->Dev = &HifAhbPDev->dev; -+#endif /* CONF_HIF_DEV_MISC */ -+ SET_NETDEV_DEV(GlueInfo->prDevHandler, HifInfo->Dev); -+ -+ HifInfo->HifRegBaseAddr = ioremap(HIF_DRV_BASE, HIF_DRV_LENGTH); -+ HifInfo->McuRegBaseAddr = ioremap(CONN_MCU_DRV_BASE, CONN_MCU_REG_LENGTH); -+ DBGLOG(INIT, INFO, "[WiFi/HIF]HifInfo->HifRegBaseAddr=0x%p, HifInfo->McuRegBaseAddr=0x%p\n", -+ HifInfo->HifRegBaseAddr, HifInfo->McuRegBaseAddr); -+ -+ /* default disable DMA */ -+ HifInfo->fgDmaEnable = FALSE; -+ HifInfo->DmaRegBaseAddr = 0; -+ HifInfo->DmaOps = NULL; -+ of_id = of_match_node(apwifi_of_ids, HifAhbPDev->dev.of_node); -+ if (of_id && of_id->data) { -+ HifInfo->ChipID = (UINT_32)(unsigned long)of_id->data; -+ } else { -+ /* read chip ID */ -+ HifInfo->ChipID = HIF_REG_READL(HifInfo, MCR_WCIR) & 0xFFFF; -+ if (HifInfo->ChipID == 0x0321 || HifInfo->ChipID == 0x0335 || HifInfo->ChipID == 0x0337) -+ HifInfo->ChipID = 0x6735; /* Denali ChipID transition */ -+ if (HifInfo->ChipID == 0x0326) -+ HifInfo->ChipID = 0x6755; -+ } -+ DBGLOG(INIT, INFO, "[WiFi/HIF] ChipID = 0x%x\n", HifInfo->ChipID); -+#ifdef CONFIG_OF -+#if !defined(CONFIG_MTK_CLKMGR) -+ HifInfo->clk_wifi_dma = devm_clk_get(&HifAhbPDev->dev, "wifi-dma"); -+ if (IS_ERR(HifInfo->clk_wifi_dma)) -+ DBGLOG(INIT, ERROR, "[WiFi/HIF][CCF]cannot get HIF clk_wifi_dma clock.\n"); -+ DBGLOG(INIT, TRACE, "[WiFi/HIF][CCF]HIF clk_wifi_dma=0x%p\n", HifInfo->clk_wifi_dma); -+#endif -+#endif -+ -+ /* Init DMA */ -+ WlanDmaFatalErr = 0; /* reset error flag */ -+ -+#if (CONF_MTK_AHB_DMA == 1) -+ spin_lock_init(&HifInfo->DdmaLock); -+ -+ HifPdmaInit(HifInfo); -+#endif /* CONF_MTK_AHB_DMA */ -+ -+ /* Start loopback test after 10 seconds */ -+#if (CONF_HIF_LOOPBACK_AUTO == 1) /* only for development test */ -+ { -+ init_timer(&(HifInfo->HifTmrLoopbkFn)); -+ HifInfo->HifTmrLoopbkFn.function = HifAhbLoopbkAuto; -+ HifInfo->HifTmrLoopbkFn.data = (unsigned long)GlueInfo; -+ -+ init_waitqueue_head(&HifInfo->HifWaitq); -+ HifInfo->HifTaskLoopbkFn = kthread_run(kalDevLoopbkThread, GlueInfo->prDevHandler, "LoopbkThread"); -+ HifInfo->HifLoopbkFlg = 0; -+ -+ /* Note: in FPGA, clock is not accuracy so 3000 here, not 10000 */ -+ HifInfo->HifTmrLoopbkFn.expires = jiffies + MSEC_TO_SYSTIME(30000); -+ add_timer(&(HifInfo->HifTmrLoopbkFn)); -+ -+ HIF_DBG(("[WiFi/HIF] Start loopback test after 10 seconds (jiffies = %u)...\n", jiffies)); -+ } -+#endif /* CONF_HIF_LOOPBACK_AUTO */ -+ -+#if (CONF_HIF_DMA_INT == 1) -+ init_waitqueue_head(&HifInfo->HifDmaWaitq); -+ HifInfo->HifDmaWaitFlg = 0; -+#endif /* CONF_HIF_DMA_INT */ -+ -+} /* end of glSetHifInfo() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function clears hif related info. -+* -+* \param[in] GlueInfo Pointer to glue info structure -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID glClearHifInfo(GLUE_INFO_T *GlueInfo) -+{ -+ iounmap(GlueInfo->rHifInfo.HifRegBaseAddr); -+ iounmap(GlueInfo->rHifInfo.DmaRegBaseAddr); -+ iounmap(GlueInfo->rHifInfo.McuRegBaseAddr); -+ return; -+ -+} /* end of glClearHifInfo() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function clears hif related info. -+* -+* \param[in] GlueInfo Pointer to glue info structure -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID glGetChipInfo(GLUE_INFO_T *GlueInfo, UINT_8 *pucChipBuf) -+{ -+ GL_HIF_INFO_T *HifInfo; -+ -+ HifInfo = &GlueInfo->rHifInfo; -+ DBGLOG(INIT, TRACE, "glGetChipInfo ChipID = 0x%x\n", HifInfo->ChipID); -+ switch (HifInfo->ChipID) { -+ case MTK_CHIP_ID_6571: -+ case MTK_CHIP_ID_8127: -+ case MTK_CHIP_ID_6752: -+ case MTK_CHIP_ID_8163: -+ case MTK_CHIP_ID_6735: -+ case MTK_CHIP_ID_6580: -+ case MTK_CHIP_ID_6755: -+ case MTK_CHIP_ID_7623: -+ kalSprintf(pucChipBuf, "%04x", HifInfo->ChipID); -+ break; -+ default: -+ kalMemCopy(pucChipBuf, "SOC", strlen("SOC")); -+ } -+} /* end of glGetChipInfo() */ -+ -+#if CFG_SPM_WORKAROUND_FOR_HOTSPOT -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function to check if we need wakelock under Hotspot mode. -+* -+* \param[in] GlueInfo Pointer to glue info structure -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN glIsChipNeedWakelock(GLUE_INFO_T *GlueInfo) -+{ -+ GL_HIF_INFO_T *HifInfo; -+ -+ HifInfo = &GlueInfo->rHifInfo; -+ if (HifInfo->ChipID == MTK_CHIP_ID_6572 || HifInfo->ChipID == MTK_CHIP_ID_6582) -+ return TRUE; -+ else -+ return FALSE; -+} /* end of glIsChipNeedWakelock() */ -+#endif /* CFG_SPM_WORKAROUND_FOR_HOTSPOT */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Initialize bus operation and hif related information, request resources. -+* -+* \param[out] pvData A pointer to HIF-specific data type buffer. -+* For eHPI, pvData is a pointer to UINT_32 type and stores a -+* mapped base address. -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN glBusInit(PVOID pvData) -+{ -+ return TRUE; -+} /* end of glBusInit() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Stop bus operation and release resources. -+* -+* \param[in] pvData A pointer to struct net_device. -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID glBusRelease(PVOID pvData) -+{ -+} /* end of glBusRelease() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Setup bus interrupt operation and interrupt handler for os. -+* -+* \param[in] pvData A pointer to struct net_device. -+* \param[in] pfnIsr A pointer to interrupt handler function. -+* \param[in] pvCookie Private data for pfnIsr function. -+* -+* \retval WLAN_STATUS_SUCCESS if success -+* NEGATIVE_VALUE if fail -+*/ -+/*----------------------------------------------------------------------------*/ -+#ifdef CONFIG_OF -+INT_32 glBusSetIrq(PVOID pvData, PVOID pfnIsr, PVOID pvCookie) -+{ -+ struct device_node *node = NULL; -+ unsigned int irq_info[3] = { 0, 0, 0 }; -+ /* unsigned int phy_base; */ -+ unsigned int irq_id = 0; -+ unsigned int irq_flags = 0; -+ -+ struct net_device *prNetDevice; -+ -+ ASSERT(pvData); -+ if (!pvData) -+ return -1; -+ prNetDevice = (struct net_device *)pvData; -+ -+ node = of_find_compatible_node(NULL, NULL, "mediatek,wifi"); -+ if (node) { -+ irq_id = irq_of_parse_and_map(node, 0); -+ DBGLOG(INIT, INFO, "WIFI-OF: get wifi irq(%d)\n", irq_id); -+ } else { -+ DBGLOG(INIT, ERROR, "WIFI-OF: get wifi device node fail\n"); -+ } -+ -+ /* get the interrupt line behaviour */ -+ if (of_property_read_u32_array(node, "interrupts", irq_info, ARRAY_SIZE(irq_info))) { -+ DBGLOG(INIT, ERROR, "WIFI-OF: get interrupt flag from DTS fail\n"); -+ } else { -+ irq_flags = irq_info[2]; -+ DBGLOG(INIT, LOUD, "WIFI-OF: get interrupt flag(0x%x)\n", irq_flags); -+ } -+ -+ /* Register AHB IRQ */ -+ if (request_irq(irq_id, HifAhbISR, irq_flags, HIF_MOD_NAME, prNetDevice)) { -+ DBGLOG(INIT, ERROR, "WIFI-OF: request irq %d fail!\n", irq_id); -+ return -1; -+ } -+ -+ return 0; -+} -+ -+VOID glBusFreeIrq(PVOID pvData, PVOID pvCookie) -+{ -+ struct device_node *node = NULL; -+ unsigned int irq_info[3] = { 0, 0, 0 }; -+ /* unsigned int phy_base; */ -+ unsigned int irq_id = 0; -+ unsigned int irq_flags = 0; -+ -+ struct net_device *prNetDevice; -+ -+ /* Init */ -+ ASSERT(pvData); -+ if (!pvData) -+ return; -+ prNetDevice = (struct net_device *)pvData; -+ -+ node = of_find_compatible_node(NULL, NULL, "mediatek,wifi"); -+ if (node) { -+ irq_id = irq_of_parse_and_map(node, 0); -+ DBGLOG(INIT, INFO, "WIFI-OF: get wifi irq(%d)\n", irq_id); -+ } else { -+ DBGLOG(INIT, ERROR, "WIFI-OF: get wifi device node fail\n"); -+ } -+ -+ /* get the interrupt line behaviour */ -+ if (of_property_read_u32_array(node, "interrupts", irq_info, ARRAY_SIZE(irq_info))) { -+ DBGLOG(INIT, ERROR, "WIFI-OF: get interrupt flag from DTS fail\n"); -+ } else { -+ irq_flags = irq_info[2]; -+ DBGLOG(INIT, LOUD, "WIFI-OF: get interrupt flag(0x%x)\n", irq_flags); -+ } -+ -+ /* Free the IRQ */ -+ free_irq(irq_id, prNetDevice); -+ return; -+ -+} -+#else -+/* the name is different in 72 and 82 */ -+#ifndef MT_WF_HIF_IRQ_ID /* for MT6572/82/92 */ -+#define MT_WF_HIF_IRQ_ID WF_HIF_IRQ_ID -+#endif /* MT_WF_HIF_IRQ_ID */ -+ -+INT_32 glBusSetIrq(PVOID pvData, PVOID pfnIsr, PVOID pvCookie) -+{ -+ int ret = 0; -+ struct net_device *prNetDevice; -+ GLUE_INFO_T *GlueInfo; -+ GL_HIF_INFO_T *HifInfo; -+ -+ /* Init */ -+ ASSERT(pvData); -+ if (!pvData) -+ return -1; -+ -+ prNetDevice = (struct net_device *)pvData; -+ GlueInfo = (GLUE_INFO_T *) pvCookie; -+ ASSERT(GlueInfo); -+ if (!GlueInfo) { -+ DBGLOG(INIT, ERROR, "GlueInfo == NULL!\n"); -+ return -1; -+ } -+ -+ HifInfo = &GlueInfo->rHifInfo; -+ -+ /* Register AHB IRQ */ -+ if (request_irq(MT_WF_HIF_IRQ_ID, HifAhbISR, IRQF_TRIGGER_LOW, HIF_MOD_NAME, prNetDevice)) { -+ DBGLOG(INIT, ERROR, "request irq %d fail!\n", MT_WF_HIF_IRQ_ID); -+ return -1; -+ } -+#if (CONF_HIF_DMA_INT == 1) -+ if (request_irq(MT_GDMA2_IRQ_ID, HifDmaISR, IRQF_TRIGGER_LOW, "AHB_DMA", prNetDevice)) { -+ DBGLOG(INIT, ERROR, "request irq %d fail!\n", MT_GDMA2_IRQ_ID); -+ free_irq(MT_WF_HIF_IRQ_ID, prNetDevice); -+ return -1; -+ } -+#endif /* CONF_HIF_DMA_INT */ -+ -+ return ret; -+ -+} /* end of glBusSetIrq() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Stop bus interrupt operation and disable interrupt handling for os. -+* -+* \param[in] pvData A pointer to struct net_device. -+* \param[in] pvCookie Private data for pfnIsr function. -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID glBusFreeIrq(PVOID pvData, PVOID pvCookie) -+{ -+ struct net_device *prNetDevice; -+ GLUE_INFO_T *GlueInfo; -+ GL_HIF_INFO_T *HifInfo; -+ -+ /* Init */ -+ ASSERT(pvData); -+ if (!pvData) -+ return; -+ -+ prNetDevice = (struct net_device *)pvData; -+ GlueInfo = (GLUE_INFO_T *) pvCookie; -+ ASSERT(GlueInfo); -+ if (!GlueInfo) -+ return; -+ -+ HifInfo = &GlueInfo->rHifInfo; -+ -+ /* Free the IRQ */ -+ free_irq(MT_WF_HIF_IRQ_ID, prNetDevice); -+ return; -+ -+} /* end of glBusreeIrq() */ -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Read a 32-bit device register -+* -+* \param[in] GlueInfo Pointer to the GLUE_INFO_T structure. -+* \param[in] RegOffset Register offset -+* \param[in] pu4Value Pointer to variable used to store read value -+* -+* \retval TRUE operation success -+* \retval FALSE operation fail -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN kalDevRegRead(IN GLUE_INFO_T *GlueInfo, IN UINT_32 RegOffset, OUT UINT_32 *pu4Value) -+{ -+ GL_HIF_INFO_T *HifInfo; -+ -+ /* sanity check and init */ -+ ASSERT(GlueInfo); -+ ASSERT(pu4Value); -+ HifInfo = &GlueInfo->rHifInfo; -+ -+ /* use PIO mode to read register */ -+ if (WlanDmaFatalErr && RegOffset != MCR_WCIR && RegOffset != MCR_WHLPCR) -+ return FALSE; -+ *pu4Value = HIF_REG_READL(HifInfo, RegOffset); -+ -+ if ((RegOffset == MCR_WRDR0) || (RegOffset == MCR_WRDR1)) -+ HIF_DBG(("[WiFi/HIF] kalDevRegRead from Data Port 0 or 1\n")); -+ -+ return TRUE; -+ -+} /* end of kalDevRegRead() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Write a 32-bit device register -+* -+* \param[in] GlueInfo Pointer to the GLUE_INFO_T structure. -+* \param[in] RegOffset Register offset -+* \param[in] RegValue RegValue to be written -+* -+* \retval TRUE operation success -+* \retval FALSE operation fail -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN kalDevRegWrite(IN GLUE_INFO_T *GlueInfo, IN UINT_32 RegOffset, IN UINT_32 RegValue) -+{ -+ GL_HIF_INFO_T *HifInfo; -+ -+ /* sanity check and init */ -+ ASSERT(GlueInfo); -+ HifInfo = &GlueInfo->rHifInfo; -+ -+ /* use PIO mode to write register */ -+ if (WlanDmaFatalErr && RegOffset != MCR_WCIR && RegOffset != MCR_WHLPCR) -+ return FALSE; -+ HIF_REG_WRITEL(HifInfo, RegOffset, RegValue); -+ -+ if ((RegOffset == MCR_WTDR0) || (RegOffset == MCR_WTDR1)) -+ HIF_DBG(("[WiFi/HIF] kalDevRegWrite to Data Port 0 or 1\n")); -+ -+ return TRUE; -+ -+} /* end of kalDevRegWrite() */ -+ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Read device I/O port -+* -+* \param[in] GlueInfo Pointer to the GLUE_INFO_T structure. -+* \param[in] Port I/O port offset -+* \param[in] Size Length to be read -+* \param[out] Buf Pointer to read buffer -+* \param[in] MaxBufSize Length of the buffer valid to be accessed -+* -+* \retval TRUE operation success -+* \retval FALSE operation fail -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN -+kalDevPortRead(IN P_GLUE_INFO_T GlueInfo, IN UINT_16 Port, IN UINT_32 Size, OUT PUINT_8 Buf, IN UINT_32 MaxBufSize) -+{ -+ GL_HIF_INFO_T *HifInfo; -+ UINT_32 u4HSTCRValue = 0; -+ UINT_32 RegWHLPCR = 0; -+ -+ /* sanity check */ -+ if ((WlanDmaFatalErr == 1) || (fgIsResetting == TRUE) || (HifIsFwOwn(GlueInfo->prAdapter) == TRUE)) { -+ DBGLOG(RX, ERROR, "WlanDmaFatalErr: %d, fgIsResetting: %d, HifIsFwOwn: %d\n", -+ WlanDmaFatalErr, fgIsResetting, HifIsFwOwn(GlueInfo->prAdapter)); -+ return FALSE; -+ } -+ /* Init */ -+ ASSERT(GlueInfo); -+ HifInfo = &GlueInfo->rHifInfo; -+ -+ ASSERT(Buf); -+ ASSERT(Size <= MaxBufSize); -+ -+ /* Note: burst length should be equal to the one used in DMA */ -+ if (Port == MCR_WRDR0) -+ u4HSTCRValue = HifAhbDmaEnhanceModeConf(GlueInfo, HIF_BURST_4DW, HIF_TARGET_RXD0, Size); -+ else if (Port == MCR_WRDR1) -+ u4HSTCRValue = HifAhbDmaEnhanceModeConf(GlueInfo, HIF_BURST_4DW, HIF_TARGET_RXD1, Size); -+ else if (Port == MCR_WHISR) -+ u4HSTCRValue = HifAhbDmaEnhanceModeConf(GlueInfo, HIF_BURST_4DW, HIF_TARGET_WHISR, Size); -+ -+ RegWHLPCR = HIF_REG_READL(HifInfo, MCR_WHLPCR); -+ if ((RegWHLPCR & WHLPCR_INT_EN_SET) == 1) -+ HIF_REG_WRITEL(HifInfo, MCR_WHLPCR, WHLPCR_INT_EN_CLR); -+ -+ /* Read */ -+#if (CONF_MTK_AHB_DMA == 1) -+ if ((HifInfo->fgDmaEnable == TRUE) && (HifInfo->DmaOps != NULL) -+ && ((Port == MCR_WRDR0) || (Port == MCR_WRDR1))) { -+ /* only for data port */ -+#ifdef MTK_DMA_BUF_MEMCPY_SUP -+ VOID *DmaVBuf = NULL, *DmaPBuf = NULL; -+#endif /* MTK_DMA_BUF_MEMCPY_SUP */ -+ GL_HIF_DMA_OPS_T *prDmaOps = HifInfo->DmaOps; -+ MTK_WCN_HIF_DMA_CONF DmaConf; -+ UINT_32 LoopCnt; -+ unsigned long PollTimeout; -+#if (CONF_HIF_DMA_INT == 1) -+ INT_32 RtnVal = 0; -+#endif -+ /* config DMA, Port = MCR_WRDR0 or MCR_WRDR1 */ -+ DmaConf.Count = Size; -+ DmaConf.Dir = HIF_DMA_DIR_RX; -+ DmaConf.Src = HIF_DRV_BASE + Port; /* must be physical addr */ -+ -+#ifdef MTK_DMA_BUF_MEMCPY_SUP -+ DmaConf.Dst = kalIOPhyAddrGet(Buf); /* must be physical addr */ -+ -+ /* TODO: use virt_to_phys() */ -+ if (DmaConf.Dst == NULL) { -+ HIF_DBG(("[WiFi/HIF] Use Dma Buffer to RX packet (%d %d)...\n", Size, CFG_RX_MAX_PKT_SIZE)); -+ ASSERT(Size <= CFG_RX_MAX_PKT_SIZE); -+ -+ kalDmaBufGet(&DmaVBuf, &DmaPBuf); -+ DmaConf.Dst = (ULONG) DmaPBuf; -+ } -+#else -+ /* -+ http://kernelnewbies.org/KernelMemoryAllocation -+ Since the cache-coherent mapping may be expensive, also a streaming allocation exists. -+ -+ This is a buffer for one-way communication, which means coherency is limited to -+ flushing the data from the cache after a write finishes. The buffer has to be -+ pre-allocated (e.g. using kmalloc()). DMA for it is set up with dma_map_single(). -+ -+ When the DMA is finished (e.g. when the device has sent an interrupt signaling end of -+ DMA), call dma_unmap_single(). Between map and unmap, the device is in control of the -+ buffer: if you write to the device, do it before dma_map_single(), if you read from -+ it, do it after dma_unmap_single(). -+ */ -+ /* DMA_FROM_DEVICE invalidated (without writeback) the cache */ -+ /* TODO: if dst_off was not cacheline aligned */ -+ DmaConf.Dst = dma_map_single(HifInfo->Dev, Buf, Size, DMA_FROM_DEVICE); -+#endif /* MTK_DMA_BUF_MEMCPY_SUP */ -+ -+ /* start to read data */ -+ AP_DMA_HIF_LOCK(HifInfo); /* lock to avoid other codes config GDMA */ -+ -+ prDmaOps->DmaClockCtrl(TRUE); -+ prDmaOps->DmaConfig(HifInfo, &DmaConf); -+ prDmaOps->DmaStart(HifInfo); -+ -+#if (CONF_HIF_DMA_INT == 1) -+ RtnVal = wait_event_interruptible_timeout(HifInfo->HifDmaWaitq, (HifInfo->HifDmaWaitFlg != 0), 1000); -+ if (RtnVal <= 0) -+ DBGLOG(RX, ERROR, "fatal error1! reset DMA!\n"); -+ HifInfo->HifDmaWaitFlg = 0; -+#else -+ PollTimeout = jiffies + HZ * 5; -+ -+ do { -+ if (time_before(jiffies, PollTimeout)) -+ continue; -+ DBGLOG(RX, INFO, "RX DMA Timeout, HSTCR: 0x%08x, and dump WHISR EnhanceMode data\n", -+ u4HSTCRValue); -+ HifDumpEnhanceModeData(GlueInfo->prAdapter); -+ if (prDmaOps->DmaRegDump != NULL) -+ prDmaOps->DmaRegDump(HifInfo); -+ WlanDmaFatalErr = 1; -+ /* we still need complete dma progress even dma timeout */ -+ break; -+ } while (!prDmaOps->DmaPollIntr(HifInfo)); -+#endif /* CONF_HIF_DMA_INT */ -+ /* we should disable dma interrupt then clear dma interrupt, otherwise, -+ for dma timeout case, interrupt may be set after we clear it */ -+ prDmaOps->DmaStop(HifInfo); -+ prDmaOps->DmaAckIntr(HifInfo); -+ -+ LoopCnt = 0; -+ do { -+ if (LoopCnt++ > 100000) { -+ /* TODO: impossible! reset DMA */ -+ DBGLOG(RX, ERROR, "fatal error2! reset DMA!\n"); -+ break; -+ } -+ } while (prDmaOps->DmaPollStart(HifInfo) != 0); -+ -+ prDmaOps->DmaClockCtrl(FALSE); -+ -+ AP_DMA_HIF_UNLOCK(HifInfo); -+ -+#ifdef MTK_DMA_BUF_MEMCPY_SUP -+ if (DmaVBuf != NULL) -+ kalMemCopy(Buf, DmaVBuf, Size); -+#else -+ dma_unmap_single(HifInfo->Dev, DmaConf.Dst, Size, DMA_FROM_DEVICE); -+#endif /* MTK_DMA_BUF_MEMCPY_SUP */ -+ -+ if ((RegWHLPCR & WHLPCR_INT_EN_SET) == 1) -+ HIF_REG_WRITEL(HifInfo, MCR_WHLPCR, WHLPCR_INT_EN_SET); -+ -+ if (WlanDmaFatalErr) { -+ if (!fgIsResetting) -+ glDoChipReset(); -+ return FALSE; -+ } -+ HIF_DBG(("[WiFi/HIF] DMA RX OK!\n")); -+ } else -+#endif /* CONF_MTK_AHB_DMA */ -+ { -+ UINT_32 IdLoop, MaxLoop; -+ UINT_32 *LoopBuf; -+ -+ /* default PIO mode */ -+ MaxLoop = Size >> 2; -+ if (Size & 0x3) -+ MaxLoop++; -+ LoopBuf = (UINT_32 *) Buf; -+ -+ for (IdLoop = 0; IdLoop < MaxLoop; IdLoop++) { -+ -+ *LoopBuf = HIF_REG_READL(HifInfo, Port); -+ LoopBuf++; -+ } -+ -+ if ((RegWHLPCR & WHLPCR_INT_EN_SET) == 1) -+ HIF_REG_WRITEL(HifInfo, MCR_WHLPCR, WHLPCR_INT_EN_SET); -+ } -+ -+ return TRUE; -+ -+} /* end of kalDevPortRead() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Write device I/O port -+* -+* \param[in] GlueInfo Pointer to the GLUE_INFO_T structure. -+* \param[in] Port I/O port offset -+* \param[in] Size Length to be write -+* \param[in] Buf Pointer to write buffer -+* \param[in] MaxBufSize Length of the buffer valid to be accessed -+* -+* \retval TRUE operation success -+* \retval FALSE operation fail -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN -+kalDevPortWrite(IN P_GLUE_INFO_T GlueInfo, IN UINT_16 Port, IN UINT_32 Size, IN PUINT_8 Buf, IN UINT_32 MaxBufSize) -+{ -+ GL_HIF_INFO_T *HifInfo; -+ UINT_32 u4HSTCRValue = 0; -+ UINT_32 RegWHLPCR = 0; -+ -+ /* sanity check */ -+ if ((WlanDmaFatalErr == 1) || (fgIsResetting == TRUE) || (HifIsFwOwn(GlueInfo->prAdapter) == TRUE)) { -+ DBGLOG(RX, ERROR, "WlanDmaFatalErr: %d, fgIsResetting: %d, HifIsFwOwn: %d\n", -+ WlanDmaFatalErr, fgIsResetting, HifIsFwOwn(GlueInfo->prAdapter)); -+ return FALSE; -+ } -+ -+ /* Init */ -+ ASSERT(GlueInfo); -+ HifInfo = &GlueInfo->rHifInfo; -+ -+ ASSERT(Buf); -+ ASSERT(Size <= MaxBufSize); -+ -+ HifTxCnt++; -+ -+ /* Note: burst length should be equal to the one used in DMA */ -+ if (Port == MCR_WTDR0) -+ u4HSTCRValue = HifAhbDmaEnhanceModeConf(GlueInfo, HIF_BURST_4DW, HIF_TARGET_TXD0, Size); -+ else if (Port == MCR_WTDR1) -+ u4HSTCRValue = HifAhbDmaEnhanceModeConf(GlueInfo, HIF_BURST_4DW, HIF_TARGET_TXD1, Size); -+ /* else other non-data port */ -+ -+ RegWHLPCR = HIF_REG_READL(HifInfo, MCR_WHLPCR); -+ if ((RegWHLPCR & WHLPCR_INT_EN_SET) == 1) -+ HIF_REG_WRITEL(HifInfo, MCR_WHLPCR, WHLPCR_INT_EN_CLR); -+ -+ /* Write */ -+#if (CONF_MTK_AHB_DMA == 1) -+ if ((HifInfo->fgDmaEnable == TRUE) && (HifInfo->DmaOps != NULL) && ((Port == MCR_WTDR0) || -+ (Port == MCR_WTDR1))) { -+ /* only for data port */ -+#ifdef MTK_DMA_BUF_MEMCPY_SUP -+ VOID *DmaVBuf = NULL, *DmaPBuf = NULL; -+#endif /* MTK_DMA_BUF_MEMCPY_SUP */ -+ GL_HIF_DMA_OPS_T *prDmaOps = HifInfo->DmaOps; -+ MTK_WCN_HIF_DMA_CONF DmaConf; -+ UINT_32 LoopCnt; -+ unsigned long PollTimeout; -+#if (CONF_HIF_DMA_INT == 1) -+ INT_32 RtnVal = 0; -+#endif -+ -+ /* config GDMA */ -+ HIF_DBG_TX(("[WiFi/HIF/DMA] Prepare to send data...\n")); -+ DmaConf.Count = Size; -+ DmaConf.Dir = HIF_DMA_DIR_TX; -+ DmaConf.Dst = HIF_DRV_BASE + Port; /* must be physical addr */ -+ -+#ifdef MTK_DMA_BUF_MEMCPY_SUP -+ DmaConf.Src = kalIOPhyAddrGet(Buf); /* must be physical addr */ -+ -+ /* TODO: use virt_to_phys() */ -+ if (DmaConf.Src == NULL) { -+ HIF_DBG_TX(("[WiFi/HIF] Use Dma Buffer to TX packet (%d %d)...\n", Size, CFG_RX_MAX_PKT_SIZE)); -+ ASSERT(Size <= CFG_RX_MAX_PKT_SIZE); -+ -+ kalDmaBufGet(&DmaVBuf, &DmaPBuf); -+ DmaConf.Src = (ULONG) DmaPBuf; -+ -+ kalMemCopy(DmaVBuf, Buf, Size); -+ } -+#else -+ -+ /* DMA_TO_DEVICE writeback the cache */ -+ DmaConf.Src = dma_map_single(HifInfo->Dev, Buf, Size, DMA_TO_DEVICE); -+#endif /* MTK_DMA_BUF_MEMCPY_SUP */ -+ -+ /* start to write */ -+ AP_DMA_HIF_LOCK(HifInfo); -+ -+ prDmaOps->DmaClockCtrl(TRUE); -+ prDmaOps->DmaConfig(HifInfo, &DmaConf); -+ prDmaOps->DmaStart(HifInfo); -+ -+#if (CONF_HIF_DMA_INT == 1) -+ RtnVal = wait_event_interruptible_timeout(HifInfo->HifDmaWaitq, (HifInfo->HifDmaWaitFlg != 0), 1000); -+ if (RtnVal <= 0) -+ DBGLOG(TX, ERROR, "fatal error1! reset DMA!\n"); -+ HifInfo->HifDmaWaitFlg = 0; -+#else -+ -+ LoopCnt = 0; -+ PollTimeout = jiffies + HZ * 5; -+ -+ do { -+ if (time_before(jiffies, PollTimeout)) -+ continue; -+ DBGLOG(TX, INFO, "TX DMA Timeout, HSTCR: 0x%08x\n", u4HSTCRValue); -+ if (prDmaOps->DmaRegDump != NULL) -+ prDmaOps->DmaRegDump(HifInfo); -+ WlanDmaFatalErr = 1; -+ /* we still need complete dma progress even dma timeout */ -+ break; -+ } while (!prDmaOps->DmaPollIntr(HifInfo)); -+#endif /* CONF_HIF_DMA_INT */ -+ /* we should disable dma interrupt then clear dma interrupt, otherwise, -+ for dma timeout case, interrupt may be set after we clear it */ -+ prDmaOps->DmaStop(HifInfo); -+ prDmaOps->DmaAckIntr(HifInfo); -+ -+ LoopCnt = 0; -+ do { -+ if (LoopCnt++ > 100000) { -+ DBGLOG(TX, ERROR, "fatal error2! reset DMA!\n"); -+ break; -+ } -+ } while (prDmaOps->DmaPollStart(HifInfo) != 0); -+ -+ prDmaOps->DmaClockCtrl(FALSE); -+ -+ AP_DMA_HIF_UNLOCK(HifInfo); -+ -+#ifndef MTK_DMA_BUF_MEMCPY_SUP -+ dma_unmap_single(HifInfo->Dev, DmaConf.Src, Size, DMA_TO_DEVICE); -+#endif /* MTK_DMA_BUF_MEMCPY_SUP */ -+ -+ if ((RegWHLPCR & WHLPCR_INT_EN_SET) == 1) -+ HIF_REG_WRITEL(HifInfo, MCR_WHLPCR, WHLPCR_INT_EN_SET); -+ -+ if (WlanDmaFatalErr) { -+ if (!fgIsResetting) -+ glDoChipReset(); -+ return FALSE; -+ } -+ HIF_DBG_TX(("[WiFi/HIF] DMA TX OK!\n")); -+ } else -+#endif /* CONF_MTK_AHB_DMA */ -+ { -+ UINT_32 IdLoop, MaxLoop; -+ UINT_32 *LoopBuf; -+ -+ /* PIO mode */ -+ MaxLoop = Size >> 2; -+ LoopBuf = (UINT_32 *) Buf; -+ -+ HIF_DBG_TX(("[WiFi/HIF/PIO] Prepare to send data (%d 0x%p-0x%p)...\n", -+ Size, LoopBuf, (((UINT8 *) LoopBuf) + (Size & (~0x03))))); -+ -+ if (Size & 0x3) -+ MaxLoop++; -+ -+ for (IdLoop = 0; IdLoop < MaxLoop; IdLoop++) { -+ HIF_REG_WRITEL(HifInfo, Port, *LoopBuf); -+ LoopBuf++; -+ } -+ -+ if ((RegWHLPCR & WHLPCR_INT_EN_SET) == 1) -+ HIF_REG_WRITEL(HifInfo, MCR_WHLPCR, WHLPCR_INT_EN_SET); -+ -+ HIF_DBG_TX(("\n\n")); -+ } -+ -+ return TRUE; -+ -+} /* end of kalDevPortWrite() */ -+ -+/******************************************************************************* -+* P R I V A T E F U N C T I O N S -+******************************************************************************** -+*/ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is a SDIO interrupt callback function -+* -+* \param[in] func pointer to SDIO handle -+* -+* \return void -+*/ -+/*----------------------------------------------------------------------------*/ -+static irqreturn_t HifAhbISR(IN int Irq, IN void *Arg) -+{ -+ struct net_device *prNetDevice = (struct net_device *)Arg; -+ GLUE_INFO_T *GlueInfo; -+ GL_HIF_INFO_T *HifInfo; -+ -+ /* Init */ -+ IsrCnt++; -+ ASSERT(prNetDevice); -+ GlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDevice)); -+ ASSERT(GlueInfo); -+ -+ if (!GlueInfo) -+ return IRQ_HANDLED; -+ -+ HifInfo = &GlueInfo->rHifInfo; -+ -+ GlueInfo->IsrCnt++; -+ -+ if (GlueInfo->ulFlag & GLUE_FLAG_HALT) { -+ HIF_REG_WRITEL(HifInfo, MCR_WHLPCR, WHLPCR_INT_EN_CLR); -+ return IRQ_HANDLED; -+ } -+ -+ HIF_REG_WRITEL(HifInfo, MCR_WHLPCR, WHLPCR_INT_EN_CLR); -+ -+ /* lock 100ms to avoid suspend */ -+ kalHifAhbKalWakeLockTimeout(GlueInfo); -+ -+ /* Wake up main thread */ -+ set_bit(GLUE_FLAG_INT_BIT, &GlueInfo->ulFlag); -+ -+ /* when we got sdio interrupt, we wake up the tx servie thread */ -+ wake_up_interruptible(&GlueInfo->waitq); -+ -+ IsrPassCnt++; -+ GlueInfo->IsrPassCnt++; -+ return IRQ_HANDLED; -+ -+} -+ -+#if (CONF_HIF_DMA_INT == 1) -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is a SDIO interrupt callback function -+* -+* \param[in] func pointer to SDIO handle -+* -+* \return void -+*/ -+/*----------------------------------------------------------------------------*/ -+ -+static irqreturn_t HifDmaISR(IN int Irq, IN void *Arg) -+{ -+ struct net_device *prNetDevice = (struct net_device *)Arg; -+ GLUE_INFO_T *GlueInfo; -+ GL_HIF_INFO_T *HifInfo; -+ -+ /* Init */ -+ ASSERT(prNetDevice); -+ GlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDevice)); -+ ASSERT(GlueInfo); -+ -+ if (!GlueInfo) -+ return IRQ_HANDLED; -+ HifInfo = &GlueInfo->rHifInfo; -+ -+ /* disable interrupt */ -+ HifInfo->DmaOps->DmaAckIntr(HifInfo); -+ -+ /* Wake up main thread */ -+ set_bit(1, &HifInfo->HifDmaWaitFlg); -+ -+ /* when we got sdio interrupt, we wake up the tx servie thread */ -+ wake_up_interruptible(&HifInfo->HifDmaWaitq); -+ -+ return IRQ_HANDLED; -+ -+} -+#endif /* CONF_HIF_DMA_INT */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is a SDIO probe function -+* -+* \param[in] func pointer to SDIO handle -+* \param[in] id pointer to SDIO device id table -+* -+* \return void -+*/ -+/*----------------------------------------------------------------------------*/ -+#if defined(CONFIG_MTK_CLKMGR) -+#if defined(MTK_EXTERNAL_LDO) || defined(MTK_ALPS_BOX_SUPPORT) -+#include -+#endif -+#endif -+ -+static int HifAhbProbe(VOID) -+{ -+ int Ret = 0; -+ -+ DBGLOG(INIT, INFO, "HifAhbProbe()\n"); -+ -+ /* power on WiFi TX PA 3.3V and HIF GDMA clock */ -+ { -+#ifdef CONFIG_MTK_PMIC_MT6397 -+#if defined(CONFIG_MTK_CLKMGR) -+#ifdef MTK_EXTERNAL_LDO -+ /* for 8127 tablet */ -+ mt_set_gpio_mode(GPIO51, GPIO_MODE_04); -+ mt_set_gpio_dir(GPIO51, GPIO_DIR_OUT); -+ mt_set_gpio_pull_enable(GPIO51, GPIO_PULL_ENABLE); -+ mt_set_gpio_pull_select(GPIO51, GPIO_PULL_UP); -+#elif defined(MTK_ALPS_BOX_SUPPORT) -+ /* for 8127 box */ -+ mt_set_gpio_mode(GPIO89, GPIO_MODE_04); -+ mt_set_gpio_dir(GPIO89, GPIO_DIR_OUT); -+ mt_set_gpio_pull_enable(GPIO89, GPIO_PULL_ENABLE); -+ mt_set_gpio_pull_select(GPIO89, GPIO_PULL_UP); -+#else -+ hwPowerOn(MT65XX_POWER_LDO_VGP4, VOL_3300, "WLAN"); -+#endif -+#endif -+#else -+#ifdef CONFIG_OF /*for MT6752 */ -+ mtk_wcn_consys_hw_wifi_paldo_ctrl(1); /* switch to HW mode */ -+#else /*for MT6572/82/92 */ -+ hwPowerOn(MT6323_POWER_LDO_VCN33_WIFI, VOL_3300, "WLAN"); -+ upmu_set_vcn33_on_ctrl_wifi(1); /* switch to HW mode */ -+#endif -+#endif -+ -+ } -+ -+#if (CONF_HIF_DEV_MISC == 1) -+ if (pfWlanProbe((PVOID) &MtkAhbDriver.this_device) != WLAN_STATUS_SUCCESS) { -+#else -+ if (pfWlanProbe((PVOID) &HifAhbPDev->dev) != WLAN_STATUS_SUCCESS) { -+#endif /* CONF_HIF_DEV_MISC */ -+ -+ pfWlanRemove(); -+ Ret = -1; -+ } -+ -+ return Ret; -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will do module remove. -+* -+* \param[in] None -+* -+* \return The result of remove (WLAN_STATUS_SUCCESS = 0) -+*/ -+/*----------------------------------------------------------------------------*/ -+static int HifAhbRemove(VOID) -+{ -+ DBGLOG(INIT, INFO, "HifAhbRemove()\n"); -+ -+ pfWlanRemove(); -+ -+ { -+#ifdef CONFIG_MTK_PMIC_MT6397 -+#if defined(CONFIG_MTK_CLKMGR) -+#ifdef MTK_EXTERNAL_LDO -+ /* for 8127 tablet */ -+ mt_set_gpio_mode(GPIO51, GPIO_MODE_04); -+ mt_set_gpio_dir(GPIO51, GPIO_DIR_OUT); -+ mt_set_gpio_pull_enable(GPIO51, GPIO_PULL_ENABLE); -+ mt_set_gpio_pull_select(GPIO51, GPIO_PULL_DOWN); -+#elif defined(MTK_ALPS_BOX_SUPPORT) -+ /* for 8127 box */ -+ mt_set_gpio_mode(GPIO89, GPIO_MODE_04); -+ mt_set_gpio_dir(GPIO89, GPIO_DIR_OUT); -+ mt_set_gpio_pull_enable(GPIO89, GPIO_PULL_ENABLE); -+ mt_set_gpio_pull_select(GPIO89, GPIO_PULL_DOWN); -+#else -+ hwPowerDown(MT65XX_POWER_LDO_VGP4, "WLAN"); -+#endif -+#endif -+#else -+#ifdef CONFIG_OF /*for MT6752 */ -+ mtk_wcn_consys_hw_wifi_paldo_ctrl(0); /* switch to SW mode */ -+#else /*for MT6572/82/92 */ -+ upmu_set_vcn33_on_ctrl_wifi(0); /* switch to SW mode */ -+ hwPowerDown(MT6323_POWER_LDO_VCN33_WIFI, "WLAN"); -+#endif -+#endif -+ -+ } -+ -+ return 0; -+} -+ -+#if (MTK_WCN_SINGLE_MODULE == 0) -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function gets the TX count pass through HIF AHB bus. -+* -+* \param[in] None -+* -+* \return TX count -+*/ -+/*----------------------------------------------------------------------------*/ -+static int HifAhbBusCntGet(VOID) -+{ -+ return HifTxCnt; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function resets the TX count pass through HIF AHB bus. -+* -+* \param[in] None -+* -+* \return 0 -+*/ -+/*----------------------------------------------------------------------------*/ -+static int HifAhbBusCntClr(VOID) -+{ -+ HifTxCnt = 0; -+ return 0; -+} -+#endif /* MTK_WCN_SINGLE_MODULE */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function configs the DMA TX/RX settings before any real TX/RX. -+* -+* \param[in] GlueInfo Pointer to the GLUE_INFO_T structure. -+* \param[in] BurstLen 0(1DW), 1(4DW), 2(8DW), Others(Reserved) -+* \param[in] PortId 0(TXD0), 1(TXD1), 2(RXD0), 3(RXD1), 4(WHISR enhance) -+* \param[in] TransByte Should be 4-byte align. -+* -+* \return void -+*/ -+/*----------------------------------------------------------------------------*/ -+static UINT_32 HifAhbDmaEnhanceModeConf(IN GLUE_INFO_T * GlueInfo, UINT_32 BurstLen, UINT_32 PortId, UINT_32 TransByte) -+{ -+ GL_HIF_INFO_T *HifInfo; -+ UINT_32 RegHSTCR; -+ -+ ASSERT(GlueInfo); -+ HifInfo = &GlueInfo->rHifInfo; -+ -+ RegHSTCR = HIF_REG_READL(HifInfo, MCR_WHIER); -+ -+ RegHSTCR = HIF_REG_READL(HifInfo, MCR_HSTCR); -+ RegHSTCR = -+ ((BurstLen << HSTCR_AFF_BURST_LEN_OFFSET) & HSTCR_AFF_BURST_LEN) | -+ ((PortId << HSTCR_TRANS_TARGET_OFFSET) & HSTCR_TRANS_TARGET) | -+ (((TransByte & 0x3) == 0) ? (TransByte & HSTCR_HSIF_TRANS_CNT) : ((TransByte + 4) & HSTCR_HSIF_TRANS_CNT)); -+ HIF_REG_WRITEL(HifInfo, MCR_HSTCR, RegHSTCR); -+ return RegHSTCR; -+} -+ -+VOID glSetPowerState(IN GLUE_INFO_T *GlueInfo, IN UINT_32 ePowerMode) -+{ -+ -+} -+ -+#if (CONF_HIF_DEV_MISC == 1) -+/* no use */ -+static ssize_t HifAhbMiscRead(IN struct file *Filp, OUT char __user *DstBuf, IN size_t Size, IN loff_t *Ppos) -+{ -+ return 0; -+} -+ -+static ssize_t HifAhbMiscWrite(IN struct file *Filp, IN const char __user *SrcBuf, IN size_t Size, IN loff_t *Ppos) -+{ -+ return 0; -+} -+ -+static int HifAhbMiscIoctl(IN struct file *Filp, IN unsigned int Cmd, IN unsigned long arg) -+{ -+ return 0; -+} -+ -+static int HifAhbMiscOpen(IN struct inode *Inodep, IN struct file *Filp) -+{ -+ return 0; -+} -+ -+static int HifAhbMiscClose(IN struct inode *Inodep, IN struct file *Filp) -+{ -+ return 0; -+} -+#else -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is called by OS platform device module. -+* -+* \param[in] PDev Pointer to the platform device structure. -+* -+* \return 0 -+*/ -+/*----------------------------------------------------------------------------*/ -+static int HifAhbPltmProbe(IN struct platform_device *PDev) -+{ -+ HifAhbPDev = PDev; -+ -+ DBGLOG(INIT, INFO, "HifAhbPltmProbe\n"); -+ -+#if (CONF_HIF_PMIC_TEST == 1) -+ wmt_set_jtag_for_mcu(); -+ wmt_set_jtag_for_gps(); -+ -+#endif /* CONF_HIF_PMIC_TEST */ -+ -+#if (MTK_WCN_SINGLE_MODULE == 1) -+ HifAhbProbe(); /* only for test purpose without WMT module */ -+ -+#else -+ -+ /* register WiFi function to WMT */ -+ DBGLOG(INIT, INFO, "mtk_wcn_wmt_wlan_reg\n"); -+ { -+ MTK_WCN_WMT_WLAN_CB_INFO WmtCb; -+ -+ WmtCb.wlan_probe_cb = HifAhbProbe; -+ WmtCb.wlan_remove_cb = HifAhbRemove; -+ WmtCb.wlan_bus_cnt_get_cb = HifAhbBusCntGet; -+ WmtCb.wlan_bus_cnt_clr_cb = HifAhbBusCntClr; -+ mtk_wcn_wmt_wlan_reg(&WmtCb); -+ } -+#endif /* MTK_WCN_SINGLE_MODULE */ -+ return 0; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is called by OS platform device module. -+* -+* \param[in] PDev Pointer to the platform device structure. -+* -+* \return 0 -+*/ -+/*----------------------------------------------------------------------------*/ -+static int __exit HifAhbPltmRemove(IN struct platform_device *PDev) -+{ -+#if (MTK_WCN_SINGLE_MODULE == 0) -+ mtk_wcn_wmt_wlan_unreg(); -+#endif /* MTK_WCN_SINGLE_MODULE */ -+ return 0; -+} -+ -+#ifdef CONFIG_PM -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is called by OS platform device module. -+* -+* \param[in] PDev Pointer to the platform device structure. -+* \param[in] Message -+* -+* \return 0 -+*/ -+/*----------------------------------------------------------------------------*/ -+static int HifAhbPltmSuspend(IN struct platform_device *PDev, pm_message_t Message) -+{ -+ return 0; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is called by OS platform device module. -+* -+* \param[in] PDev Pointer to the platform device structure. -+* -+* \return 0 -+*/ -+/*----------------------------------------------------------------------------*/ -+static int HifAhbPltmResume(IN struct platform_device *PDev) -+{ -+ return 0; -+} -+#endif /* CONFIG_PM */ -+ -+#endif /* CONF_HIF_DEV_MISC */ -+ -+#if (CONF_HIF_LOOPBACK_AUTO == 1) -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Trigger to do HIF loopback test. -+* -+* \param[in] arg Pointer to the GLUE_INFO_T structure. -+* -+* \retval None -+*/ -+/*----------------------------------------------------------------------------*/ -+static VOID HifAhbLoopbkAuto(IN unsigned long arg) -+{ -+ -+ P_GLUE_INFO_T GlueInfo = (P_GLUE_INFO_T) arg; -+ GL_HIF_INFO_T *HifInfo = &GlueInfo->rHifInfo; -+ -+ ASSERT(GlueInfo); -+ -+ HIF_DBG(("[WiFi/HIF] Trigger to do loopback test...\n")); -+ -+ set_bit(GLUE_FLAG_HIF_LOOPBK_AUTO_BIT, &HifInfo->HifLoopbkFlg); -+ wake_up_interruptible(&HifInfo->HifWaitq); -+ -+} -+#endif /* CONF_HIF_LOOPBACK_AUTO */ -+ -+VOID glDumpConnSysCpuInfo(P_GLUE_INFO_T prGlueInfo) -+{ -+ GL_HIF_INFO_T *prHifInfo = &prGlueInfo->rHifInfo; -+ unsigned short j; -+ -+ for (j = 0; j < 512; j++) { -+ DBGLOG(INIT, WARN, "0x%08x ", MCU_REG_READL(prHifInfo, CONN_MCU_CPUPCR)); -+ if ((j + 1) % 16 == 0) -+ DBGLOG(INIT, WARN, "\n"); -+ } -+} -+ -+/* End of ahb.c */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/arm.c b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/arm.c -new file mode 100644 -index 000000000000..6b719028ae93 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/arm.c -@@ -0,0 +1,31 @@ -+/****************************************************************************** -+*[File] mt6516-evb.c -+*[Version] v1.0 -+*[Revision Date] 2010-03-01 -+*[Author] -+*[Description] -+* dummy file for build system -+*[Copyright] -+* Copyright (C) 2010 MediaTek Incorporation. All Rights Reserved. -+******************************************************************************/ -+ -+/* -+** Log: mt6516-evb.c -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 04 19 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * remove debug message -+ * -+ * 03 24 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * initial import for Linux port -+** -+*/ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/include/hif.h b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/include/hif.h -new file mode 100644 -index 000000000000..1507d5560040 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/include/hif.h -@@ -0,0 +1,340 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux/hif/sdio/include/hif.h#1 -+*/ -+ -+/*! \file "hif.h" -+ \brief Functions for the driver to register bus and setup the IRQ -+ -+ Functions for the driver to register bus and setup the IRQ -+*/ -+ -+/* -+** Log: hif.h -+ * -+ * 11 01 2010 yarco.yang -+ * [WCXRP00000149] [MT6620 WI-Fi][Driver]Fine tune performance on MT6516 platform -+ * Add GPIO debug function -+ * -+ * 10 19 2010 jeffrey.chang -+ * [WCXRP00000120] [MT6620 Wi-Fi][Driver] Refine linux kernel module to the license of MTK propietary and enable MTK -+ * HIF by default -+ * Refine linux kernel module to the license of MTK and enable MTK HIF -+ * -+ * 08 18 2010 jeffrey.chang -+ * NULL -+ * support multi-function sdio -+ * -+ * 08 17 2010 cp.wu -+ * NULL -+ * add ENE SDIO host workaround for x86 linux platform. -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 03 24 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * initial import for Linux port -+** \main\maintrunk.MT5921\4 2009-10-20 17:38:28 GMT mtk01090 -+** Refine driver unloading and clean up procedure. Block requests, stop main thread and clean up queued requests, -+** and then stop hw. -+** \main\maintrunk.MT5921\3 2009-09-28 20:19:20 GMT mtk01090 -+** Add private ioctl to carry OID structures. Restructure public/private ioctl interfaces to Linux kernel. -+** \main\maintrunk.MT5921\2 2009-08-18 22:57:05 GMT mtk01090 -+** Add Linux SDIO (with mmc core) support. -+** Add Linux 2.6.21, 2.6.25, 2.6.26. -+** Fix compile warning in Linux. -+** \main\maintrunk.MT5921\2 2008-09-22 23:18:17 GMT mtk01461 -+** Update driver for code review -+** Revision 1.1 2007/07/05 07:25:33 MTK01461 -+** Add Linux initial code, modify doc, add 11BB, RF init code -+** -+** Revision 1.3 2007/06/27 02:18:51 MTK01461 -+** Update SCAN_FSM, Initial(Can Load Module), Proc(Can do Reg R/W), TX API -+** -+*/ -+ -+#ifndef _HIF_H -+#define _HIF_H -+ -+#include "gl_typedef.h" -+#include "mtk_porting.h" -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+#define CONF_MTK_AHB_DMA 1 /* PIO mode is default mode if DMA is disabled */ -+ -+#define CONF_HIF_DEV_MISC 0 /* register as misc device */ -+#define CONF_HIF_LOOPBACK_AUTO 0 /* hif loopback test triggered by open() */ -+ /* only for development test */ -+ -+#define CONF_HIF_PMIC_TEST 0 /* test purpose: power on CONNSYS */ -+ -+#define CONF_HIF_DMA_INT 0 /* DMA interrupt mode */ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+extern phys_addr_t gConEmiPhyBase; -+extern BOOLEAN fgIsResetting; -+extern UINT_32 IsrCnt, IsrPassCnt; -+extern int kalDevLoopbkThread(IN void *data); -+ -+#ifdef CONFIG_MTK_PMIC_MT6397 -+#else -+#ifdef CONFIG_OF /*for MT6752 */ -+extern INT_32 mtk_wcn_consys_hw_wifi_paldo_ctrl(UINT_32 enable); -+#else /*for MT6572/82/92 */ -+extern void upmu_set_vcn33_on_ctrl_wifi(UINT_32 val); -+#endif -+#endif -+ -+#if (CONF_HIF_DEV_MISC == 1) -+#else -+/* extern INT32 mtk_wcn_consys_hw_reg_ctrl(UINT32 on, UINT32 co_clock_en); */ -+#endif -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+#ifndef CONN_MCU_CONFIG_BASE -+#define CONN_MCU_CONFIG_BASE 0xF8070000 /* MT6572 */ -+#endif /* CONN_MCU_CONFIG_BASE */ -+ -+#define CONSYS_CPUPCR_REG (CONN_MCU_CONFIG_BASE + 0x00000160) -+#define CONSYS_REG_READ(addr) (*((volatile unsigned int *)(addr))) -+ -+#define CONN_MCU_DRV_BASE 0x18070000 -+#define CONN_MCU_REG_LENGTH 0x0200 -+#define CONN_MCU_CPUPCR 0x0160 -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/* host interface's private data structure, which is attached to os glue -+** layer info structure. -+ */ -+typedef struct _GL_HIF_DMA_OPS_T { /* DMA Operators */ -+ VOID (*DmaConfig)(IN VOID *HifInfo, IN VOID *Conf); -+ -+ VOID (*DmaStart)(IN VOID *HifInfo); -+ -+ VOID (*DmaStop)(IN VOID *HifInfo); -+ -+ MTK_WCN_BOOL (*DmaPollStart)(IN VOID *HifInfo); -+ -+ MTK_WCN_BOOL (*DmaPollIntr)(IN VOID *HifInfo); -+ -+ VOID (*DmaAckIntr)(IN VOID *HifInfo); -+ -+ VOID (*DmaClockCtrl)(IN UINT_32 FlgIsEnabled); -+ -+ VOID (*DmaRegDump)(IN VOID *HifInfo); -+ -+ VOID (*DmaReset)(IN VOID *HifInfo); -+ -+} GL_HIF_DMA_OPS_T; -+ -+typedef struct _GL_HIF_INFO_T { -+ -+ /* General */ -+ VOID *Dev; /* struct device */ -+ -+#define MTK_CHIP_ID_6571 0x6571 -+#define MTK_CHIP_ID_6572 0x6572 -+#define MTK_CHIP_ID_6582 0x6582 -+#define MTK_CHIP_ID_8127 0x8127 -+#define MTK_CHIP_ID_6752 0x6752 -+#define MTK_CHIP_ID_8163 0x8163 -+#define MTK_CHIP_ID_6735 0x6735 -+#define MTK_CHIP_ID_6580 0x6580 -+#define MTK_CHIP_ID_6755 0x6755 -+#define MTK_CHIP_ID_7623 0x7623 -+ -+ UINT_32 ChipID; -+ -+ /* Control flag */ -+ BOOLEAN fgIntReadClear; -+ BOOLEAN fgMbxReadClear; -+ BOOLEAN fgDmaEnable; /* TRUE: DMA mode is used (default) */ -+ -+ /* HIF related */ -+ UINT_8 *HifRegBaseAddr; /* HIF register base */ -+ UINT_8 *McuRegBaseAddr; /* CONN MCU register base */ -+ -+#if (CONF_HIF_LOOPBACK_AUTO == 1) -+ struct timer_list HifTmrLoopbkFn; /* HIF loopback test trigger timer */ -+ wait_queue_head_t HifWaitq; -+ UINT_32 HifLoopbkFlg; -+ struct task_struct *HifTaskLoopbkFn; /* HIF loopback test task */ -+#endif /* CONF_HIF_LOOPBACK_AUTO */ -+ -+#if (CONF_HIF_DMA_INT == 1) -+ wait_queue_head_t HifDmaWaitq; -+ UINT_32 HifDmaWaitFlg; -+#endif /* CONF_HIF_DMA_INT */ -+ -+ /* DMA related */ -+#define AP_DMA_HIF_LOCK(_lock) /* spin_lock_bh(&(_lock)->DdmaLock) */ -+#define AP_DMA_HIF_UNLOCK(_lock) /* spin_unlock_bh(&(_lock)->DdmaLock) */ -+ spinlock_t DdmaLock; /* protect DMA access */ -+ -+ UINT_8 *DmaRegBaseAddr; /* DMA register base */ -+ GL_HIF_DMA_OPS_T *DmaOps; /* DMA Operators */ -+ -+#if !defined(CONFIG_MTK_CLKMGR) -+ struct clk *clk_wifi_dma; -+#endif -+} GL_HIF_INFO_T, *P_GL_HIF_INFO_T; -+ -+#define HIF_MOD_NAME "AHB_SLAVE_HIF" -+ -+#define HIF_DRV_BASE 0x180F0000 -+#define HIF_DRV_LENGTH 0x005c -+ -+typedef enum _MTK_WCN_HIF_BURST_LEN { -+ HIF_BURST_1DW = 0, -+ HIF_BURST_4DW, -+ HIF_BURST_8DW -+} MTK_WCN_HIF_BURST_LEN; -+ -+typedef enum _MTK_WCN_HIF_TXRX_TARGET { -+ HIF_TARGET_TXD0 = 0, -+ HIF_TARGET_TXD1, -+ HIF_TARGET_RXD0, -+ HIF_TARGET_RXD1, -+ HIF_TARGET_WHISR -+} MTK_WCN_HIF_TXRX_TARGET; -+ -+typedef enum _MTK_WCN_HIF_DMA_DIR { -+ HIF_DMA_DIR_TX = 0, -+ HIF_DMA_DIR_RX -+} MTK_WCN_HIF_DMA_DIR; -+ -+typedef struct _MTK_WCN_HIF_DMA_CONF { -+ UINT_32 Count; -+ MTK_WCN_HIF_DMA_DIR Dir; -+ UINT_32 Burst; -+ UINT_32 Wsize; -+ UINT_32 Ratio; -+ UINT_32 Connect; -+ UINT_32 Fix_en; -+ ULONG Src; -+ ULONG Dst; -+} MTK_WCN_HIF_DMA_CONF; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+#define MCU_REG_READL(_hif, _addr) \ -+ readl((volatile UINT_32 *)((_hif)->McuRegBaseAddr + _addr)) -+ -+/* PIO mode HIF register read/write */ -+#define HIF_REG_READL(_hif, _addr) \ -+ readl((volatile UINT_32 *)((_hif)->HifRegBaseAddr + _addr)) -+ -+#define HIF_REG_WRITEL(_hif, _addr, _val) \ -+ writel(_val, ((volatile UINT_32 *)((_hif)->HifRegBaseAddr + _addr))) -+ -+#define HIF_REG_WRITEB(_hif, _addr, _val) \ -+ writeb(_val, ((volatile UINT_32 *)((_hif)->HifRegBaseAddr + _addr))) -+ -+/* PIO mode DMA register read/write */ -+#define HIF_DMAR_READL(_hif, _addr) \ -+ readl((volatile UINT_32 *)((_hif)->DmaRegBaseAddr + _addr)) -+ -+#define HIF_DMAR_WRITEL(_hif, _addr, _val) \ -+ writel(_val, ((volatile UINT_32 *)((_hif)->DmaRegBaseAddr + _addr))) -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+#ifndef MODULE_AHB_DMA -+VOID HifDumpEnhanceModeData(P_ADAPTER_T prAdapter); -+ -+VOID HifRegDump(P_ADAPTER_T prAdapter); -+ -+BOOLEAN HifIsFwOwn(P_ADAPTER_T prAdapter); -+ -+WLAN_STATUS glRegisterBus(probe_card pfProbe, remove_card pfRemove); -+ -+VOID glUnregisterBus(remove_card pfRemove); -+ -+VOID glResetHif(GLUE_INFO_T *GlueInfo); -+ -+VOID glSetHifInfo(P_GLUE_INFO_T prGlueInfo, ULONG ulCookie); -+ -+VOID glClearHifInfo(P_GLUE_INFO_T prGlueInfo); -+ -+VOID glGetChipInfo(GLUE_INFO_T *GlueInfo, UINT_8 *pucChipBuf); -+ -+#if CFG_SPM_WORKAROUND_FOR_HOTSPOT -+BOOLEAN glIsChipNeedWakelock(GLUE_INFO_T *GlueInfo); -+#endif -+ -+BOOLEAN glBusInit(PVOID pvData); -+ -+VOID glBusRelease(PVOID pData); -+ -+INT_32 glBusSetIrq(PVOID pvData, PVOID pfnIsr, PVOID pvCookie); -+ -+VOID glBusFreeIrq(PVOID pvData, PVOID pvCookie); -+ -+VOID glSetPowerState(IN P_GLUE_INFO_T prGlueInfo, IN UINT_32 ePowerMode); -+ -+VOID glDumpConnSysCpuInfo(P_GLUE_INFO_T prGlueInfo); -+ -+#endif /* MODULE_AHB_DMA */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Config GDMA TX/RX. -+* -+* \param[in] DmaRegBaseAddr Pointer to the IO register base. -+* \param[in] Conf Pointer to the DMA operator. -+* -+* \retval NONE -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID HifGdmaInit(GL_HIF_INFO_T *HifInfo); -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Config PDMA TX/RX. -+* -+* \param[in] DmaRegBaseAddr Pointer to the IO register base. -+* \param[in] Conf Pointer to the DMA operator. -+* -+* \retval NONE -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID HifPdmaInit(GL_HIF_INFO_T *HifInfo); -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+#endif /* _HIF_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/include/hif_gdma.h b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/include/hif_gdma.h -new file mode 100644 -index 000000000000..094c07f98eff ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/include/hif_gdma.h -@@ -0,0 +1,154 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux/hif/sdio/include/hif.h#1 -+*/ -+ -+/*! \file "hif_gdma.h" -+ \brief MARCO, definition, structure for GDMA. -+ -+ MARCO, definition, structure for GDMA. -+*/ -+ -+/* -+** Log: hif_gdma.h -+ * -+ * 01 16 2013 vend_samp.lin -+ * Add AHB GDMA support -+ * 1) Initial version -+** -+*/ -+ -+#ifndef _HIF_GDMA_H -+#define _HIF_GDMA_H -+ -+#include "mtk_porting.h" -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+typedef enum _MTK_WCN_HIF_GDMA_BURST_LEN { -+ HIF_GDMA_BURST_1_8 = 0, -+ HIF_GDMA_BURST_2_8, -+ HIF_GDMA_BURST_3_8, -+ HIF_GDMA_BURST_4_8, -+ HIF_GDMA_BURST_5_8, -+ HIF_GDMA_BURST_6_8, -+ HIF_GDMA_BURST_7_8, -+ HIF_GDMA_BURST_8_8 /* same as HIF_GDMA_BURST_7_8 */ -+} MTK_WCN_HIF_GDMA_BURST_LEN; -+ -+typedef enum _MTK_WCN_HIF_GDMA_WRITE_LEN { -+ HIF_GDMA_WRITE_0 = 0, /* transaction size is 1 byte */ -+ HIF_GDMA_WRITE_1, /* transaction size is 2 byte */ -+ HIF_GDMA_WRITE_2, /* transaction size is 4 byte */ -+ HIF_GDMA_WRITE_3 /* transaction size is 1 byte */ -+} MTK_WCN_HIF_GDMA_WRITE_LEN; -+ -+typedef enum _MTK_WCN_HIF_GDMA_RATIO { -+ HIF_GDMA_RATIO_0 = 0, /* 1/2 */ -+ HIF_GDMA_RATIO_1 /* 1/1 */ -+} MTK_WCN_HIF_GDMA_RATIO; -+ -+typedef enum _MTK_WCN_HIF_GDMA_CONNECT { -+ HIF_GDMA_CONNECT_NO = 0, /* no connect */ -+ HIF_GDMA_CONNECT_SET1, /* connect set1 (req/ack) */ -+ HIF_GDMA_CONNECT_SET2, /* connect set2 (req/ack) */ -+ HIF_GDMA_CONNECT_SET3 /* connect set3 (req/ack) */ -+} MTK_WCN_HIF_GDMA_CONNECT; -+ -+/* reference to MT6572_AP_P_DMA_Spec.doc */ -+#define AP_DMA_HIF_BASE 0x11000100 -+ -+#define AP_P_DMA_G_DMA_2_INT_FLAG (0x0000) -+#define AP_P_DMA_G_DMA_2_CON (0x0018) -+#define AP_P_DMA_G_DMA_2_CONNECT (0x0034) -+#define AP_P_DMA_G_DMA_2_LEN1 (0x0024) -+#define AP_P_DMA_G_DMA_2_SRC_ADDR (0x001C) -+#define AP_P_DMA_G_DMA_2_DST_ADDR (0x0020) -+#define AP_P_DMA_G_DMA_2_INT_EN (0x0004) -+#define AP_P_DMA_G_DMA_2_EN (0x0008) -+#define AP_P_DMA_G_DMA_2_RST (0x000C) -+#define AP_P_DMA_G_DMA_2_STOP (0x0010) -+ -+#define AP_DMA_HIF_0_LENGTH 0x0038 -+ -+/* AP_DMA_HIF_0_INT_FLAG */ -+#define ADH_CR_FLAG_0 BIT(0) -+ -+/* AP_DMA_HIF_0_INT_EN */ -+#define ADH_CR_INTEN_FLAG_0 BIT(0) -+ -+/* AP_DMA_HIF_0_EN */ -+#define ADH_CR_EN BIT(0) -+#define ADH_CR_CONN_BUR_EN BIT(1) -+ -+/* AP_DMA_HIF_0_STOP */ -+#define ADH_CR_PAUSE BIT(1) -+#define ADH_CR_STOP BIT(0) -+ -+/* AP_P_DMA_G_DMA_2_CON */ -+#define ADH_CR_FLAG_FINISH BIT(30) -+#define ADH_CR_RSIZE BITS(28, 29) -+#define ADH_CR_RSIZE_OFFSET 28 -+#define ADH_CR_WSIZE BITS(24, 25) -+#define ADH_CR_WSIZE_OFFSET 24 -+#define ADH_CR_BURST_LEN BITS(16, 18) -+#define ADH_CR_BURST_LEN_OFFSET 16 -+#define ADH_CR_WADDR_FIX_EN BIT(3) -+#define ADH_CR_WADDR_FIX_EN_OFFSET 3 -+#define ADH_CR_RADDR_FIX_EN BIT(4) -+#define ADH_CR_RADDR_FIX_EN_OFFSET 4 -+ -+/* AP_P_DMA_G_DMA_2_CONNECT */ -+#define ADH_CR_RATIO BIT(3) -+#define ADH_CR_RATIO_OFFSET 3 -+#define ADH_CR_DIR BIT(2) -+#define ADH_CR_DIR_OFFSET 2 -+#define ADH_CR_CONNECT BITS(0, 1) -+ -+/* AP_DMA_HIF_0_LEN */ -+#define ADH_CR_LEN BITS(0, 19) -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+#endif /* _HIF_GDMA_H */ -+ -+/* End of hif_gdma.h */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/include/hif_pdma.h b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/include/hif_pdma.h -new file mode 100644 -index 000000000000..32224e8f17d8 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/include/hif_pdma.h -@@ -0,0 +1,141 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux/hif/sdio/include/hif.h#1 -+*/ -+ -+/*! \file "hif_pdma.h" -+ \brief MARCO, definition, structure for PDMA. -+ -+ MARCO, definition, structure for PDMA. -+*/ -+ -+/* -+** Log: hif_pdma.h -+ * -+ * 01 16 2013 vend_samp.lin -+ * Add AHB PDMA support -+ * 1) Initial version -+** -+*/ -+ -+#ifndef _HIF_PDMA_H -+#define _HIF_PDMA_H -+ -+#include "mtk_porting.h" -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+typedef enum _MTK_WCN_HIF_PDMA_BURST_LEN { -+ HIF_PDMA_BURST_1_4 = 0, -+ HIF_PDMA_BURST_2_4, -+ HIF_PDMA_BURST_3_4, -+ HIF_PDMA_BURST_4_4 -+} MTK_WCN_HIF_PDMA_BURST_LEN; -+ -+/* reference to MT6572_AP_P_DMA_Spec.doc */ -+#ifdef CONFIG_OF -+/*for MT6752*/ -+#define AP_DMA_HIF_BASE 0x11000080 -+#else -+/*for MT6572/82/92*/ -+#define AP_DMA_HIF_BASE 0x11000180 -+#endif -+ -+#define AP_DMA_HIF_0_INT_FLAG (0x0000) -+#define AP_DMA_HIF_0_INT_EN (0x0004) -+#define AP_DMA_HIF_0_EN (0x0008) -+#define AP_DMA_HIF_0_RST (0x000C) -+#define AP_DMA_HIF_0_STOP (0x0010) -+#define AP_DMA_HIF_0_FLUSH (0x0014) -+#define AP_DMA_HIF_0_CON (0x0018) -+#define AP_DMA_HIF_0_SRC_ADDR (0x001C) -+#define AP_DMA_HIF_0_DST_ADDR (0x0020) -+#define AP_DMA_HIF_0_LEN (0x0024) -+#define AP_DMA_HIF_0_INT_BUF_SIZE (0x0038) -+#define AP_DMA_HIF_0_DEBUG_STATUS (0x0050) -+#define AP_DMA_HIF_0_SRC_ADDR2 (0x0054) -+#define AP_DMA_HIF_0_DST_ADDR2 (0x0058) -+ -+#define AP_DMA_HIF_0_LENGTH 0x0080 -+ -+/* AP_DMA_HIF_0_INT_FLAG */ -+#define ADH_CR_FLAG_0 BIT(0) -+ -+/* AP_DMA_HIF_0_INT_EN */ -+#define ADH_CR_INTEN_FLAG_0 BIT(0) -+ -+/* AP_DMA_HIF_0_EN */ -+#define ADH_CR_EN BIT(0) -+ -+/* AP_DMA_HIF_0_RST */ -+#define ADH_CR_HARD_RST BIT(1) -+#define ADH_CR_WARM_RST BIT(0) -+ -+/* AP_DMA_HIF_0_STOP */ -+#define ADH_CR_PAUSE BIT(1) -+#define ADH_CR_STOP BIT(0) -+ -+/* AP_DMA_HIF_0_FLUSH */ -+#define ADH_CR_FLUSH BIT(0) -+ -+/* AP_DMA_HIF_0_CON */ -+#define ADH_CR_BURST_LEN BITS(16, 17) -+#define ADH_CR_BURST_LEN_OFFSET 16 -+#define ADH_CR_SLOW_CNT BITS(5, 14) -+#define ADH_CR_SLOW_EN BIT(2) -+#define ADH_CR_FIX_EN BIT(1) -+#define ADH_CR_FIX_EN_OFFSET 1 -+#define ADH_CR_DIR BIT(0) -+ -+/* AP_DMA_HIF_0_LEN */ -+#define ADH_CR_LEN BITS(0, 19) -+ -+/* AP_DMA_HIF_0_SRC_ADDR2 */ -+#define ADH_CR_SRC_ADDR2 BIT(0) -+/* AP_DMA_HIF_0_DST_ADDR2 */ -+#define ADH_CR_DST_ADDR2 BIT(0) -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+#endif /* _HIF_PDMA_H */ -+ -+/* End of hif_gdma.h */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/include/mtk_porting.h b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/include/mtk_porting.h -new file mode 100644 -index 000000000000..91557137af9a ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/include/mtk_porting.h -@@ -0,0 +1,91 @@ -+/* porting layer */ -+/* Android */ -+ -+#ifndef _MTK_PORTING_H_ -+#define _MTK_PORTING_H_ -+ -+#include /* include stddef.h for NULL */ -+ -+#define CONF_MTK_AHB_DMA 1 -+ -+/* Type definition for signed integers */ -+/*typedef signed char INT8, *PINT8; -+typedef signed short INT16, *PINT16; -+typedef signed int INT_32, *PINT32;*/ -+ -+/* Type definition for unsigned integers */ -+/*typedef unsigned char UINT8, *PUINT8; -+typedef unsigned short UINT16, *PUINT16; -+typedef unsigned int UINT32, *PUINT32;*/ -+ -+#ifndef VOID -+/*typedef void VOID, *PVOID;*/ -+#endif -+ -+#ifndef IN -+#define IN -+#endif -+ -+#ifndef OUT -+#define OUT -+#endif -+ -+#ifndef INTOUT -+#define INOUT -+#endif -+ -+#ifndef TRUE -+#define TRUE 1 -+#endif -+ -+#ifndef FALSE -+#define FALSE 0 -+#endif -+ -+#ifndef BIT -+#define BIT(n) ((UINT_32) 1U << (n)) -+#endif /* BIT */ -+ -+#ifndef BITS -+/* bits range: for example BITS(16,23) = 0xFF0000 -+ * ==> (BIT(m)-1) = 0x0000FFFF ~(BIT(m)-1) => 0xFFFF0000 -+ * ==> (BIT(n+1)-1) = 0x00FFFFFF -+ */ -+#define BITS(m, n) (~(BIT(m)-1) & ((BIT(n) - 1) | BIT(n))) -+#endif /* BIT */ -+ -+#ifndef BOOLEAN -+#define BOOLEAN unsigned char -+#endif -+ -+typedef int MTK_WCN_BOOL; -+#ifndef MTK_WCN_BOOL_TRUE -+#define MTK_WCN_BOOL_FALSE ((MTK_WCN_BOOL) 0) -+#define MTK_WCN_BOOL_TRUE ((MTK_WCN_BOOL) 1) -+#endif -+ -+typedef int MTK_WCN_MUTEX; -+ -+typedef int MTK_WCN_TIMER; -+ -+/* system APIs */ -+/* mutex */ -+typedef MTK_WCN_MUTEX(*MUTEX_CREATE) (const char *const name); -+typedef INT_32(*MUTEX_DESTROY) (MTK_WCN_MUTEX mtx); -+typedef INT_32(*MUTEX_LOCK) (MTK_WCN_MUTEX mtx); -+typedef INT_32(*MUTEX_UNLOCK) (MTK_WCN_MUTEX mtx, unsigned long flags); -+/* debug */ -+typedef INT_32(*DBG_PRINT) (const char *str, ...); -+typedef INT_32(*DBG_ASSERT) (INT_32 expr, const char *file, INT_32 line); -+/* timer */ -+typedef void (*MTK_WCN_TIMER_CB) (void); -+typedef MTK_WCN_TIMER(*TIMER_CREATE) (const char *const name); -+typedef INT_32(*TIMER_DESTROY) (MTK_WCN_TIMER tmr); -+typedef INT_32(*TIMER_START) (MTK_WCN_TIMER tmr, UINT_32 timeout, MTK_WCN_TIMER_CB tmr_cb, void *param); -+typedef INT_32(*TIMER_STOP) (MTK_WCN_TIMER tmr); -+/* kernel lib */ -+typedef void *(*SYS_MEMCPY) (void *dest, const void *src, UINT_32 n); -+typedef void *(*SYS_MEMSET) (void *s, INT_32 c, UINT_32 n); -+typedef INT_32(*SYS_SPRINTF) (char *str, const char *format, ...); -+ -+#endif /* _MTK_PORTING_H_ */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/mt8127/ahb_pdma.c b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/mt8127/ahb_pdma.c -new file mode 100644 -index 000000000000..94cc05ba3224 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/mt8127/ahb_pdma.c -@@ -0,0 +1,480 @@ -+/****************************************************************************** -+*[File] ahb_pdma.c -+*[Version] v1.0 -+*[Revision Date] 2013-03-13 -+*[Author] -+*[Description] -+* The program provides AHB PDMA driver -+*[Copyright] -+* Copyright (C) 2013 MediaTek Incorporation. All Rights Reserved. -+******************************************************************************/ -+ -+/* -+** Log: ahb_pdma.c -+ * -+ * 03 13 2013 vend_samp.lin -+ * Add AHB PDMA support -+ * 1) Initial version -+** -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+#define MODULE_AHB_DMA -+ -+#include /* constant of kernel version */ -+ -+#include /* bitops.h */ -+ -+#include /* struct timer_list */ -+#include /* jiffies */ -+#include /* udelay and mdelay macro */ -+ -+#if 0 -+#if CONFIG_ANDROID -+#include -+#endif -+#endif -+ -+#include /* IRQT_FALLING */ -+ -+#include /* struct net_device, struct net_device_stats */ -+#include /* for eth_type_trans() function */ -+#include /* struct iw_statistics */ -+#include -+#include /* struct in_device */ -+ -+#include /* struct iphdr */ -+ -+#include /* for memcpy()/memset() function */ -+#include /* for offsetof() macro */ -+ -+#include /* The proc filesystem constants/structures */ -+ -+#include /* for rtnl_lock() and rtnl_unlock() */ -+#include /* kthread_should_stop(), kthread_run() */ -+#include /* for copy_from_user() */ -+#include /* for firmware download */ -+#include -+ -+#include /* for kfifo interface */ -+#include /* for cdev interface */ -+ -+#include /* for firmware download */ -+ -+#include -+ -+#include /* readw and writew */ -+ -+#include -+ -+#if defined(CONFIG_MTK_CLKMGR) -+#include -+#else -+#include -+#endif /* defined(CONFIG_MTK_CLKMGR) */ -+ -+#include "hif.h" -+#include "hif_pdma.h" -+#include "gl_os.h" -+ -+/* #include */ -+ -+/* #if (CONF_MTK_AHB_DMA == 1) */ -+ -+/* #define PDMA_DEBUG_SUP */ -+ -+#ifdef PDMA_DEBUG_SUP -+#define PDMA_DBG pr_debug -+#else -+#define PDMA_DBG(_fmt, ...) -+#endif /* PDMA_DEBUG_SUP */ -+ -+#if !defined(CONFIG_MTK_CLKMGR) -+struct clk *g_clk_wifi_pdma; -+#endif -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+static VOID HifPdmaConfig(IN void *HifInfoSrc, IN void *Conf); -+ -+static VOID HifPdmaStart(IN void *HifInfoSrc); -+ -+static VOID HifPdmaStop(IN void *HifInfoSrc); -+ -+static MTK_WCN_BOOL HifPdmaPollStart(IN void *HifInfoSrc); -+ -+static MTK_WCN_BOOL HifPdmaPollIntr(IN void *HifInfoSrc); -+ -+static VOID HifPdmaAckIntr(IN void *HifInfoSrc); -+ -+static VOID HifPdmaClockCtrl(IN UINT32 FlgIsEnabled); -+ -+static VOID HifPdmaRegDump(IN void *HifInfoSrc); -+ -+static VOID HifPdmaReset(IN void *HifInfoSrc); -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+GL_HIF_DMA_OPS_T HifPdmaOps = { -+ .DmaConfig = HifPdmaConfig, -+ .DmaStart = HifPdmaStart, -+ .DmaStop = HifPdmaStop, -+ .DmaPollStart = HifPdmaPollStart, -+ .DmaPollIntr = HifPdmaPollIntr, -+ .DmaAckIntr = HifPdmaAckIntr, -+ .DmaClockCtrl = HifPdmaClockCtrl, -+ .DmaRegDump = HifPdmaRegDump, -+ .DmaReset = HifPdmaReset -+}; -+ -+/******************************************************************************* -+* P U B L I C F U N C T I O N S -+******************************************************************************** -+*/ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Config PDMA TX/RX. -+* -+* \param[in] prGlueInfo Pointer to the GLUE_INFO_T structure. -+* \param[in] Conf Pointer to the settings. -+* -+* \retval NONE -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID HifPdmaInit(GL_HIF_INFO_T *HifInfo) -+{ -+ /* IO remap PDMA register memory */ -+#ifdef AP_DMA_HIF_BASE -+#undef AP_DMA_HIF_BASE -+#define AP_DMA_HIF_BASE 0x11000180 -+#endif -+ HifInfo->DmaRegBaseAddr = ioremap(AP_DMA_HIF_BASE, AP_DMA_HIF_0_LENGTH); -+ -+ /* assign PDMA operators */ -+ HifInfo->DmaOps = &HifPdmaOps; -+ -+ /* enable PDMA mode */ -+ HifInfo->fgDmaEnable = TRUE; -+ -+ /* Set EMI protection here */ -+#if 0 -+#ifdef MTK_TEE_CCCI_SECURE_SHARE_MEM_SUPPORT -+ DBGLOG(INIT, INFO, "WIFI set EMI MPU for TEE project\n"); -+ emi_mpu_set_region_protection(gConEmiPhyBase, -+ gConEmiPhyBase + SZ_1M / 2, -+ 5, SET_ACCESS_PERMISSON(FORBIDDEN, NO_PROTECTION, FORBIDDEN, FORBIDDEN)); -+#else -+ DBGLOG(INIT, INFO, "WIFI set EMI MPU for non-TEE project\n"); -+ emi_mpu_set_region_protection(gConEmiPhyBase, -+ gConEmiPhyBase + SZ_1M / 2, -+ 4, SET_ACCESS_PERMISSON(FORBIDDEN, NO_PROTECTION, FORBIDDEN, FORBIDDEN)); -+#endif -+#endif -+ -+#if !defined(CONFIG_MTK_CLKMGR) -+ g_clk_wifi_pdma = HifInfo->clk_wifi_dma; -+#endif -+ -+ PDMA_DBG("PDMA> HifPdmaInit ok!\n"); -+} -+ -+/******************************************************************************* -+* P R I V A T E F U N C T I O N S -+******************************************************************************** -+*/ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Config PDMA TX/RX. -+* -+* \param[in] HifInfo Pointer to the GL_HIF_INFO_T structure. -+* \param[in] Param Pointer to the settings. -+* -+* \retval NONE -+*/ -+/*----------------------------------------------------------------------------*/ -+static VOID HifPdmaConfig(IN void *HifInfoSrc, IN void *Param) -+{ -+ GL_HIF_INFO_T *HifInfo = (GL_HIF_INFO_T *) HifInfoSrc; -+ MTK_WCN_HIF_DMA_CONF *Conf = (MTK_WCN_HIF_DMA_CONF *) Param; -+ UINT32 RegVal; -+ -+ /* Assign fixed value */ -+ Conf->Burst = HIF_PDMA_BURST_4_4; /* vs. HIF_BURST_4DW */ -+ Conf->Fix_en = FALSE; -+ -+ /* AP_P_DMA_G_DMA_2_CON */ -+ PDMA_DBG("PDMA> Conf->Dir = %d\n", Conf->Dir); -+ -+ /* AP_DMA_HIF_0_CON */ -+ RegVal = HIF_DMAR_READL(HifInfo, AP_DMA_HIF_0_CON); -+ RegVal &= ~(ADH_CR_BURST_LEN | ADH_CR_FIX_EN | ADH_CR_DIR); -+ RegVal |= (((Conf->Burst << ADH_CR_BURST_LEN_OFFSET) & ADH_CR_BURST_LEN) | -+ (Conf->Fix_en << ADH_CR_FIX_EN_OFFSET) | (Conf->Dir)); -+ HIF_DMAR_WRITEL(HifInfo, AP_DMA_HIF_0_CON, RegVal); -+ PDMA_DBG("PDMA> AP_DMA_HIF_0_CON = 0x%08x\n", RegVal); -+ -+ /* AP_DMA_HIF_0_SRC_ADDR */ -+ HIF_DMAR_WRITEL(HifInfo, AP_DMA_HIF_0_SRC_ADDR, Conf->Src); -+ PDMA_DBG("PDMA> AP_DMA_HIF_0_SRC_ADDR = 0x%08lx\n", Conf->Src); -+ -+ /* AP_DMA_HIF_0_DST_ADDR */ -+ HIF_DMAR_WRITEL(HifInfo, AP_DMA_HIF_0_DST_ADDR, Conf->Dst); -+ PDMA_DBG("PDMA> AP_DMA_HIF_0_DST_ADDR = 0x%08lx\n", Conf->Dst); -+ -+ /* AP_DMA_HIF_0_LEN */ -+ HIF_DMAR_WRITEL(HifInfo, AP_DMA_HIF_0_LEN, (Conf->Count & ADH_CR_LEN)); -+ PDMA_DBG("PDMA> AP_DMA_HIF_0_LEN = %u\n", (UINT_32)(Conf->Count & ADH_CR_LEN)); -+ -+} /* End of HifPdmaConfig */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Start PDMA TX/RX. -+* -+* \param[in] HifInfo Pointer to the GL_HIF_INFO_T structure. -+* -+* \retval NONE -+*/ -+/*----------------------------------------------------------------------------*/ -+static VOID HifPdmaStart(IN void *HifInfoSrc) -+{ -+ GL_HIF_INFO_T *HifInfo = (GL_HIF_INFO_T *) HifInfoSrc; -+ UINT32 RegVal; -+ -+ /* Enable interrupt */ -+ RegVal = HIF_DMAR_READL(HifInfo, AP_DMA_HIF_0_INT_EN); -+ HIF_DMAR_WRITEL(HifInfo, AP_DMA_HIF_0_INT_EN, (RegVal | ADH_CR_INTEN_FLAG_0)); -+ -+ /* Start DMA */ -+ RegVal = HIF_DMAR_READL(HifInfo, AP_DMA_HIF_0_EN); -+ HIF_DMAR_WRITEL(HifInfo, AP_DMA_HIF_0_EN, (RegVal | ADH_CR_EN)); -+ -+ PDMA_DBG("PDMA> HifPdmaStart...\n"); -+ -+} /* End of HifPdmaStart */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Stop PDMA TX/RX. -+* -+* \param[in] HifInfo Pointer to the GL_HIF_INFO_T structure. -+* -+* \retval NONE -+*/ -+/*----------------------------------------------------------------------------*/ -+static VOID HifPdmaStop(IN void *HifInfoSrc) -+{ -+ GL_HIF_INFO_T *HifInfo = (GL_HIF_INFO_T *) HifInfoSrc; -+ UINT32 RegVal; -+/* UINT32 pollcnt; */ -+ -+ /* Disable interrupt */ -+ RegVal = HIF_DMAR_READL(HifInfo, AP_DMA_HIF_0_INT_EN); -+ HIF_DMAR_WRITEL(HifInfo, AP_DMA_HIF_0_INT_EN, (RegVal & ~(ADH_CR_INTEN_FLAG_0))); -+ -+#if 0 /* DE says we donot need to do it */ -+ /* Stop DMA */ -+ RegVal = HIF_DMAR_READL(HifInfo, AP_DMA_HIF_0_STOP); -+ HIF_DMAR_WRITEL(HifInfo, AP_DMA_HIF_0_STOP, (RegVal | ADH_CR_STOP)); -+ -+ /* Polling START bit turn to 0 */ -+ pollcnt = 0; -+ do { -+ RegVal = HIF_DMAR_READL(HifInfo, AP_DMA_HIF_0_EN); -+ if (pollcnt++ > 100000) -+ ; /* TODO: warm reset PDMA */ -+ } while (RegVal & ADH_CR_EN); -+#endif -+ -+} /* End of HifPdmaStop */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Enable PDMA TX/RX. -+* -+* \param[in] HifInfo Pointer to the GL_HIF_INFO_T structure. -+* -+* \retval NONE -+*/ -+/*----------------------------------------------------------------------------*/ -+static MTK_WCN_BOOL HifPdmaPollStart(IN void *HifInfoSrc) -+{ -+ GL_HIF_INFO_T *HifInfo = (GL_HIF_INFO_T *) HifInfoSrc; -+ UINT32 RegVal; -+ -+ RegVal = HIF_DMAR_READL(HifInfo, AP_DMA_HIF_0_EN); -+ return ((RegVal & ADH_CR_EN) != 0) ? TRUE : FALSE; -+ -+} /* End of HifPdmaPollStart */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Poll PDMA TX/RX done. -+* -+* \param[in] HifInfo Pointer to the GL_HIF_INFO_T structure. -+* -+* \retval NONE -+*/ -+/*----------------------------------------------------------------------------*/ -+static MTK_WCN_BOOL HifPdmaPollIntr(IN void *HifInfoSrc) -+{ -+ GL_HIF_INFO_T *HifInfo = (GL_HIF_INFO_T *) HifInfoSrc; -+ UINT32 RegVal; -+ -+ RegVal = HIF_DMAR_READL(HifInfo, AP_DMA_HIF_0_INT_FLAG); -+ return ((RegVal & ADH_CR_FLAG_0) != 0) ? TRUE : FALSE; -+ -+} /* End of HifPdmaPollIntr */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Acknowledge PDMA TX/RX done. -+* -+* \param[in] HifInfo Pointer to the GL_HIF_INFO_T structure. -+* -+* \retval NONE -+*/ -+/*----------------------------------------------------------------------------*/ -+static VOID HifPdmaAckIntr(IN void *HifInfoSrc) -+{ -+ GL_HIF_INFO_T *HifInfo = (GL_HIF_INFO_T *) HifInfoSrc; -+ UINT32 RegVal; -+ -+ /* Write 0 to clear interrupt */ -+ RegVal = HIF_DMAR_READL(HifInfo, AP_DMA_HIF_0_INT_FLAG); -+ HIF_DMAR_WRITEL(HifInfo, AP_DMA_HIF_0_INT_FLAG, (RegVal & ~ADH_CR_FLAG_0)); -+ -+} /* End of HifPdmaAckIntr */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Acknowledge PDMA TX/RX done. -+* -+* \param[in] FlgIsEnabled TRUE: enable; FALSE: disable -+* -+* \retval NONE -+*/ -+/*----------------------------------------------------------------------------*/ -+static VOID HifPdmaClockCtrl(IN UINT32 FlgIsEnabled) -+{ -+#if !defined(CONFIG_MTK_CLKMGR) -+ int ret = 0; -+#endif -+#if defined(CONFIG_MTK_CLKMGR) -+ if (FlgIsEnabled == TRUE) -+ enable_clock(MT_CG_INFRA_APDMA, "WLAN"); -+ else -+ disable_clock(MT_CG_INFRA_APDMA, "WLAN"); -+#else -+ if (FlgIsEnabled == TRUE) { -+ ret = clk_prepare_enable(g_clk_wifi_pdma); -+ if (ret) -+ DBGLOG(INIT, TRACE, "[CCF]clk_prepare_enable ret= %d\n", ret); -+ } else { -+ clk_disable_unprepare(g_clk_wifi_pdma); -+ } -+#endif -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Dump PDMA related registers. -+* -+* \param[in] HifInfo Pointer to the GL_HIF_INFO_T structure. -+* -+* \retval NONE -+*/ -+/*----------------------------------------------------------------------------*/ -+static VOID HifPdmaRegDump(IN void *HifInfoSrc) -+{ -+ GL_HIF_INFO_T *HifInfo = (GL_HIF_INFO_T *) HifInfoSrc; -+ UINT32 RegId, RegVal; -+ UINT32 RegNum = 0; -+ -+ DBGLOG(INIT, INFO, "PDMA> Register content 0x%x=\n\t", AP_DMA_HIF_BASE); -+ for (RegId = 0; RegId < AP_DMA_HIF_0_LENGTH; RegId += 4) { -+ RegVal = HIF_DMAR_READL(HifInfo, RegId); -+ DBGLOG(INIT, INFO, "0x%08x ", RegVal); -+ -+ if (RegNum++ >= 3) { -+ DBGLOG(INIT, INFO, "\n"); -+ DBGLOG(INIT, INFO, "PDMA> Register content 0x%x=\n\t", AP_DMA_HIF_BASE + RegId + 4); -+ RegNum = 0; -+ } -+ } -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Reset DMA. -+* -+* \param[in] HifInfo Pointer to the GL_HIF_INFO_T structure. -+* -+* \retval NONE -+*/ -+/*----------------------------------------------------------------------------*/ -+static VOID HifPdmaReset(IN void *HifInfoSrc) -+{ -+ GL_HIF_INFO_T *HifInfo = (GL_HIF_INFO_T *) HifInfoSrc; -+ UINT32 LoopCnt; -+ -+ /* do warm reset: DMA will wait for current traction finished */ -+ DBGLOG(INIT, INFO, "\nDMA> do warm reset...\n"); -+ -+ /* normally, we need to sure that bit0 of AP_P_DMA_G_DMA_2_EN is 1 here */ -+ -+ HIF_DMAR_WRITEL(HifInfo, AP_DMA_HIF_0_RST, 0x01); -+ -+ for (LoopCnt = 0; LoopCnt < 10000; LoopCnt++) { -+ if (!HifPdmaPollStart(HifInfo)) -+ break; /* reset ok */ -+ } -+ -+ if (HifPdmaPollStart(HifInfo)) { -+ /* do hard reset because warm reset fails */ -+ DBGLOG(INIT, INFO, "\nDMA> do hard reset...\n"); -+ HIF_DMAR_WRITEL(HifInfo, AP_DMA_HIF_0_RST, 0x02); -+ mdelay(1); -+ HIF_DMAR_WRITEL(HifInfo, AP_DMA_HIF_0_RST, 0x00); -+ } -+} -+ -+/* #endif */ /* CONF_MTK_AHB_DMA */ -+ -+/* End of ahb_pdma.c */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_cfg80211.h b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_cfg80211.h -new file mode 100644 -index 000000000000..ec9f46bdab2e ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_cfg80211.h -@@ -0,0 +1,341 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux/include/gl_cfg80211.h#1 -+*/ -+ -+/*! \file gl_cfg80211.h -+ \brief This file is for Portable Driver linux cfg80211 support. -+*/ -+ -+/* -+** Log: gl_cfg80211.h -+** -+** 09 03 2013 cp.wu -+** add path for reassociation -+** -+** 09 12 2012 wcpadmin -+** [ALPS00276400] Remove MTK copyright and legal header on GPL/LGPL related packages -+** . -+** -+** 08 30 2012 chinglan.wang -+** [ALPS00349664] [6577JB][WIFI] Phone can not connect to AP secured with AES via WPS in 802.11n Only -+** . -+ * -+*/ -+ -+#ifndef _GL_CFG80211_H -+#define _GL_CFG80211_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include -+#include -+#include -+#include -+#include -+ -+#include "gl_os.h" -+extern void wlanHandleSystemResume(void); -+extern void wlanHandleSystemSuspend(void); -+extern void p2pHandleSystemResume(void); -+extern void p2pHandleSystemSuspend(void); -+ -+#if CFG_SUPPORT_WAPI -+extern UINT_8 keyStructBuf[1024]; /* add/remove key shared buffer */ -+#else -+extern UINT_8 keyStructBuf[100]; /* add/remove key shared buffer */ -+#endif -+ -+extern struct delayed_work sched_workq; -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+#if CONFIG_NL80211_TESTMODE -+#define NL80211_DRIVER_TESTMODE_VERSION 2 -+#endif -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+#if CONFIG_NL80211_TESTMODE -+ -+typedef struct _NL80211_DRIVER_GET_STA_STATISTICS_PARAMS { -+ NL80211_DRIVER_TEST_MODE_PARAMS hdr; -+ UINT_32 u4Version; -+ UINT_32 u4Flag; -+ UINT_8 aucMacAddr[MAC_ADDR_LEN]; -+} NL80211_DRIVER_GET_STA_STATISTICS_PARAMS, *P_NL80211_DRIVER_GET_STA_STATISTICS_PARAMS; -+ -+typedef struct _NL80211_DRIVER_POORLINK_PARAMS { -+ NL80211_DRIVER_TEST_MODE_PARAMS hdr; -+ INT_8 cRssi; /* cRssi=0 means it is a invalid value. */ -+ UINT_8 ucLinkSpeed; /* ucLinkSpeed=0 means it is a invalid value */ -+ UINT_16 u2Reserved; -+} NL80211_DRIVER_POORLINK_PARAMS, *P_NL80211_DRIVER_POORLINK_PARAMS; -+ -+typedef enum _ENUM_TESTMODE_STA_STATISTICS_ATTR { -+ NL80211_TESTMODE_STA_STATISTICS_INVALID = 0, -+ NL80211_TESTMODE_STA_STATISTICS_VERSION, -+ NL80211_TESTMODE_STA_STATISTICS_MAC, -+ NL80211_TESTMODE_STA_STATISTICS_LINK_SCORE, -+ NL80211_TESTMODE_STA_STATISTICS_FLAG, -+ -+ NL80211_TESTMODE_STA_STATISTICS_PER, -+ NL80211_TESTMODE_STA_STATISTICS_RSSI, -+ NL80211_TESTMODE_STA_STATISTICS_PHY_MODE, -+ NL80211_TESTMODE_STA_STATISTICS_TX_RATE, -+ -+ NL80211_TESTMODE_STA_STATISTICS_TOTAL_CNT, -+ NL80211_TESTMODE_STA_STATISTICS_THRESHOLD_CNT, -+ -+ NL80211_TESTMODE_STA_STATISTICS_AVG_PROCESS_TIME, -+ NL80211_TESTMODE_STA_STATISTICS_MAX_PROCESS_TIME, -+ NL80211_TESTMODE_STA_STATISTICS_AVG_HIF_PROCESS_TIME, -+ NL80211_TESTMODE_STA_STATISTICS_MAX_HIF_PROCESS_TIME, -+ -+ NL80211_TESTMODE_STA_STATISTICS_FAIL_CNT, -+ NL80211_TESTMODE_STA_STATISTICS_TIMEOUT_CNT, -+ NL80211_TESTMODE_STA_STATISTICS_AVG_AIR_TIME, -+ -+ NL80211_TESTMODE_STA_STATISTICS_TC_EMPTY_CNT_ARRAY, -+ NL80211_TESTMODE_STA_STATISTICS_TC_QUE_LEN_ARRAY, -+ -+ NL80211_TESTMODE_STA_STATISTICS_TC_AVG_QUE_LEN_ARRAY, -+ NL80211_TESTMODE_STA_STATISTICS_TC_CUR_QUE_LEN_ARRAY, -+ -+ /* -+ * how many packages TX during statistics interval -+ */ -+ NL80211_TESTMODE_STA_STATISTICS_ENQUEUE, -+ -+ /* -+ * how many packages this TX during statistics interval -+ */ -+ NL80211_TESTMODE_STA_STATISTICS_STA_ENQUEUE, -+ -+ /* -+ * how many packages dequeue during statistics interval -+ */ -+ NL80211_TESTMODE_STA_STATISTICS_DEQUEUE, -+ -+ /* -+ * how many packages this sta dequeue during statistics interval -+ */ -+ NL80211_TESTMODE_STA_STATISTICS_STA_DEQUEUE, -+ -+ /* -+ * how many TC[0-3] resource back from firmware during -+ * statistics interval -+ */ -+ NL80211_TESTMODE_STA_STATISTICS_RB_ARRAY, -+ NL80211_TESTMODE_STA_STATISTICS_NO_TC_ARRAY, -+ NL80211_TESTMODE_STA_STATISTICS_USED_BFCT_ARRAY, -+ NL80211_TESTMODE_STA_STATISTICS_WANTED_BFCT_ARRAY, -+ -+ NL80211_TESTMODE_STA_STATISTICS_IRQ_ISR_CNT, -+ NL80211_TESTMODE_STA_STATISTICS_IRQ_ISR_PASS_CNT, -+ NL80211_TESTMODE_STA_STATISTICS_IRQ_TASK_CNT, -+ NL80211_TESTMODE_STA_STATISTICS_IRQ_AB_CNT, -+ NL80211_TESTMODE_STA_STATISTICS_IRQ_SW_CNT, -+ NL80211_TESTMODE_STA_STATISTICS_IRQ_TX_CNT, -+ NL80211_TESTMODE_STA_STATISTICS_IRQ_RX_CNT, -+ -+ NL80211_TESTMODE_STA_STATISTICS_RESERVED_ARRAY, -+ -+ NL80211_TESTMODE_STA_STATISTICS_NUM -+} ENUM_TESTMODE_STA_STATISTICS_ATTR; -+typedef struct _NL80211_DRIVER_SET_NFC_PARAMS { -+ NL80211_DRIVER_TEST_MODE_PARAMS hdr; -+ UINT_32 NFC_Enable; -+ -+} NL80211_DRIVER_SET_NFC_PARAMS, *P_NL80211_DRIVER_SET_NFC_PARAMS; -+typedef struct _NL80211_DRIVER_GET_SCANDONE_PARAMS { -+ NL80211_DRIVER_TEST_MODE_PARAMS hdr; -+ UINT_32 u4ScanDone; -+ -+} NL80211_DRIVER_GET_SCANDONE_PARAMS, *P_NL80211_DRIVER_GET_SCANDONE_PARAMS; -+ -+typedef enum _ENUM_TESTMODE_LINK_DETECTION_ATTR { -+ NL80211_TESTMODE_LINK_INVALID = 0, -+ NL80211_TESTMODE_LINK_TX_FAIL_CNT, -+ NL80211_TESTMODE_LINK_TX_RETRY_CNT, -+ NL80211_TESTMODE_LINK_TX_MULTI_RETRY_CNT, -+ NL80211_TESTMODE_LINK_ACK_FAIL_CNT, -+ NL80211_TESTMODE_LINK_FCS_ERR_CNT, -+ -+ NL80211_TESTMODE_LINK_DETECT_NUM, -+} ENUM_TESTMODE_LINK_DETECTION_ATTR; -+ -+#if CFG_AUTO_CHANNEL_SEL_SUPPORT -+ -+typedef struct _NL80211_DRIVER_GET_LTE_PARAMS { -+ NL80211_DRIVER_TEST_MODE_PARAMS hdr; -+ UINT_32 u4Version; -+ UINT_32 u4Flag; -+ -+} NL80211_DRIVER_GET_LTE_PARAMS, *P_NL80211_DRIVER_GET_LTE_PARAMS; -+ -+/*typedef enum _ENUM_TESTMODE_AVAILABLE_CHAN_ATTR{ -+ NL80211_TESTMODE_AVAILABLE_CHAN_INVALID = 0, -+ NL80211_TESTMODE_AVAILABLE_CHAN_2G_BASE_1, -+ NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_34, -+ NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_149, -+ NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_184, -+ -+ NL80211_TESTMODE_AVAILABLE_CHAN_NUM, -+}ENUM_TESTMODE_AVAILABLE_CHAN_ATTR;*/ -+ -+#endif -+#endif -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+/* cfg80211 hooks */ -+int -+mtk_cfg80211_change_iface(struct wiphy *wiphy, -+ struct net_device *ndev, enum nl80211_iftype type,/* u32 *flags,*/ struct vif_params *params); -+ -+int -+mtk_cfg80211_add_key(struct wiphy *wiphy, -+ struct net_device *ndev, -+ u8 key_index, bool pairwise, const u8 *mac_addr, struct key_params *params); -+ -+int -+mtk_cfg80211_get_key(struct wiphy *wiphy, -+ struct net_device *ndev, -+ u8 key_index, -+ bool pairwise, -+ const u8 *mac_addr, void *cookie, void (*callback) (void *cookie, struct key_params *) -+); -+ -+int -+mtk_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev, u8 key_index, bool pairwise, const u8 *mac_addr); -+ -+int -+mtk_cfg80211_set_default_key(struct wiphy *wiphy, struct net_device *ndev, u8 key_index, bool unicast, bool multicast); -+ -+int mtk_cfg80211_set_default_mgmt_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index); -+ -+int mtk_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev, const u8 *mac, struct station_info *sinfo); -+ -+int mtk_cfg80211_add_station(struct wiphy *wiphy, struct net_device *ndev, -+ const u8 *mac, struct station_parameters *params); -+ -+int mtk_cfg80211_change_station(struct wiphy *wiphy, struct net_device *ndev, -+ const u8 *mac, struct station_parameters *params); -+ -+int mtk_cfg80211_del_station(struct wiphy *wiphy, struct net_device *ndev, struct station_del_parameters *params); -+//int mtk_cfg80211_del_station(struct wiphy *wiphy, struct net_device *ndev, const u8 *mac); -+ -+int mtk_cfg80211_scan(struct wiphy *wiphy, struct cfg80211_scan_request *request); -+ -+int mtk_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev, struct cfg80211_connect_params *sme); -+ -+int mtk_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *ndev, u16 reason_code); -+ -+int mtk_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev, struct cfg80211_ibss_params *params); -+ -+int mtk_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *ndev); -+ -+int mtk_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *ndev, bool enabled, int timeout); -+ -+int mtk_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *ndev, struct cfg80211_pmksa *pmksa); -+ -+int mtk_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *ndev, struct cfg80211_pmksa *pmksa); -+ -+int mtk_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *ndev); -+ -+int mtk_cfg80211_remain_on_channel(struct wiphy *wiphy, -+ struct wireless_dev *wdev, -+ struct ieee80211_channel *chan, -+ unsigned int duration, u64 *cookie); -+ -+int mtk_cfg80211_cancel_remain_on_channel(struct wiphy *wiphy, struct wireless_dev *wdev, u64 cookie); -+ -+int -+mtk_cfg80211_mgmt_tx(struct wiphy *wiphy, -+ struct wireless_dev *wdev, -+ struct cfg80211_mgmt_tx_params *params, -+ u64 *cookie); -+ -+void mtk_cfg80211_mgmt_frame_register(IN struct wiphy *wiphy, -+ IN struct wireless_dev *wdev, -+ IN u16 frame_type, IN bool reg); -+ -+int mtk_cfg80211_mgmt_tx_cancel_wait(struct wiphy *wiphy, struct wireless_dev *wdev, u64 cookie); -+ -+int mtk_cfg80211_assoc(struct wiphy *wiphy, struct net_device *ndev, struct cfg80211_assoc_request *req); -+ -+int -+mtk_cfg80211_sched_scan_start(IN struct wiphy *wiphy, -+ IN struct net_device *ndev, IN struct cfg80211_sched_scan_request *request); -+ -+int mtk_cfg80211_sched_scan_stop(IN struct wiphy *wiphy, IN struct net_device *ndev,u64 reqid); -+ -+#if CONFIG_NL80211_TESTMODE -+#if CFG_AUTO_CHANNEL_SEL_SUPPORT -+WLAN_STATUS -+wlanoidQueryACSChannelList(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+int -+mtk_cfg80211_testmode_get_lte_channel(IN struct wiphy *wiphy, IN void *data, IN int len, IN P_GLUE_INFO_T prGlueInfo); -+#endif -+int -+mtk_cfg80211_testmode_get_sta_statistics(IN struct wiphy *wiphy, -+ IN void *data, IN int len, IN P_GLUE_INFO_T prGlueInfo); -+ -+int mtk_cfg80211_testmode_get_scan_done(IN struct wiphy *wiphy, IN void *data, IN int len, IN P_GLUE_INFO_T prGlueInfo); -+ -+int mtk_cfg80211_testmode_cmd(IN struct wiphy *wiphy, IN struct wireless_dev *wdev, IN void *data, IN int len); -+ -+int mtk_cfg80211_testmode_sw_cmd(IN struct wiphy *wiphy, IN void *data, IN int len); -+#if CFG_SUPPORT_WAPI -+int mtk_cfg80211_testmode_set_key_ext(IN struct wiphy *wiphy, IN void *data, IN int len); -+#endif -+ -+#if CFG_SUPPORT_HOTSPOT_2_0 -+int mtk_cfg80211_testmode_hs20_cmd(IN struct wiphy *wiphy, IN void *data, IN int len); -+#endif -+ -+#if CFG_ENABLE_WIFI_DIRECT && CFG_ENABLE_WIFI_DIRECT_CFG_80211 -+int mtk_p2p_cfg80211_testmode_sw_cmd(IN struct wiphy *wiphy, IN void *data, IN int len); -+#endif -+ -+#else -+#error "Please ENABLE kernel config (CONFIG_NL80211_TESTMODE) to support Wi-Fi Direct" -+#endif -+int mtk_cfg80211_suspend(struct wiphy *wiphy, struct cfg80211_wowlan *wow); -+int mtk_cfg80211_resume(struct wiphy *wiphy); -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif /* _GL_CFG80211_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_kal.h b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_kal.h -new file mode 100644 -index 000000000000..512e149abf75 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_kal.h -@@ -0,0 +1,1565 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux/include/gl_kal.h#1 -+*/ -+ -+/*! \file gl_kal.h -+ \brief Declaration of KAL functions - kal*() which is provided by GLUE Layer. -+ -+ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. -+*/ -+ -+/* -+** Log: gl_kal.h -+ * -+ * 06 13 2012 yuche.tsai -+ * NULL -+ * Update maintrunk driver. -+ * Add support for driver compose assoc request frame. -+ * -+ * 04 12 2012 terry.wu -+ * NULL -+ * Add AEE message support -+ * 1) Show AEE warning(red screen) if SDIO access error occurs -+ -+ * -+ * 03 02 2012 terry.wu -+ * NULL -+ * Snc CFG80211 modification for ICS migration from branch 2.2. -+ * -+ * 02 06 2012 wh.su -+ * [WCXRP00001177] [MT6620 Wi-Fi][Driver][2.2] Adding the query channel filter for AP mode -+ * adding the channel query filter for AP mode. -+ * -+ * 01 02 2012 wh.su -+ * [WCXRP00001153] [MT6620 Wi-Fi][Driver] Adding the get_ch_list and set_tx_power proto type function -+ * Adding the proto type function for set_int set_tx_power and get int get_ch_list. -+ * -+ * 12 13 2011 cm.chang -+ * [WCXRP00001136] [All Wi-Fi][Driver] Add wake lock for pending timer -+ * Add wake lock if timer timeout value is smaller than 5 seconds -+ * -+ * 11 24 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * adjust the code for Non-DBG and no XLOG. -+ * -+ * 11 22 2011 cp.wu -+ * [WCXRP00001120] [MT6620 Wi-Fi][Driver] Modify roaming to AIS state transition from synchronous to asynchronous -+ * approach to avoid incomplete state termination -+ * 1. change RDD related compile option brace position. -+ * 2. when roaming is triggered, ask AIS to transit immediately only when AIS is in Normal TR state without join -+ * timeout timer ticking -+ * 3. otherwise, insert AIS_REQUEST into pending request queue -+ * -+ * 11 11 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * modify the xlog related code. -+ * -+ * 11 10 2011 eddie.chen -+ * [WCXRP00001096] [MT6620 Wi-Fi][Driver/FW] Enhance the log function (xlog) -+ * Modify the QM xlog level and remove LOG_FUNC. -+ * -+ * 11 10 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * Using the new XLOG define for dum Memory. -+ * -+ * 11 08 2011 eddie.chen -+ * [WCXRP00001096] [MT6620 Wi-Fi][Driver/FW] Enhance the log function (xlog) -+ * Add xlog function. -+ * -+ * 11 08 2011 tsaiyuan.hsu -+ * [WCXRP00001083] [MT6620 Wi-Fi][DRV]] dump debug counter or frames when debugging is triggered -+ * add debug counters, eCurPsProf, for PS. -+ * -+ * 11 08 2011 cm.chang -+ * NULL -+ * Add RLM and CNM debug message for XLOG -+ * -+ * 11 07 2011 tsaiyuan.hsu -+ * [WCXRP00001083] [MT6620 Wi-Fi][DRV]] dump debug counter or frames when debugging is triggered -+ * add debug counters and periodically dump counters for debugging. -+ * -+ * 11 03 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * Add dumpMemory8 at XLOG support. -+ * -+ * 11 02 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * adding the code for XLOG. -+ * -+ * 10 12 2011 wh.su -+ * [WCXRP00001036] [MT6620 Wi-Fi][Driver][FW] Adding the 802.11w code for MFP -+ * adding the 802.11w related function and define . -+ * -+ * 04 18 2011 terry.wu -+ * [WCXRP00000660] [MT6620 Wi-Fi][Driver] Remove flag CFG_WIFI_DIRECT_MOVED -+ * Remove flag CFG_WIFI_DIRECT_MOVED. -+ * -+ * 04 12 2011 cp.wu -+ * [WCXRP00000635] [MT6620 Wi-Fi][Driver] Clear pending security frames when QM clear pending data frames for dedicated -+ * network type -+ * include link.h for linux's port. -+ * -+ * 04 12 2011 cp.wu -+ * [WCXRP00000635] [MT6620 Wi-Fi][Driver] Clear pending security frames when QM clear pending data frames for dedicated -+ * network type -+ * clear pending security frames for dedicated network type when BSS is being deactivated/disconnected -+ * -+ * 04 01 2011 cp.wu -+ * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer -+ * 1. simplify config.h due to aggregation options could be also applied for eHPI/SPI interface -+ * 2. use spin-lock instead of semaphore for protecting eHPI access because of possible access from ISR -+ * 3. request_irq() API has some changes between linux kernel 2.6.12 and 2.6.26 -+ * -+ * 03 16 2011 cp.wu -+ * [WCXRP00000562] [MT6620 Wi-Fi][Driver] I/O buffer pre-allocation to avoid physically continuous memory shortage -+ * after system running for a long period -+ * 1. pre-allocate physical continuous buffer while module is being loaded -+ * 2. use pre-allocated physical continuous buffer for TX/RX DMA transfer -+ * -+ * The windows part remained the same as before, but added similar APIs to hide the difference. -+ * -+ * 03 10 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Add BOW table. -+ * -+ * 03 07 2011 terry.wu -+ * [WCXRP00000521] [MT6620 Wi-Fi][Driver] Remove non-standard debug message -+ * Toggle non-standard debug messages to comments. -+ * -+ * 03 06 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Sync BOW Driver to latest person development branch version.. -+ * -+ * 03 02 2011 cp.wu -+ * [WCXRP00000503] [MT6620 Wi-Fi][Driver] Take RCPI brought by association response as initial RSSI right after -+ * connection is built. -+ * use RCPI brought by ASSOC-RESP after connection is built as initial RCPI to avoid using a uninitialized MAC-RX RCPI. -+ * -+ * 02 24 2011 cp.wu -+ * [WCXRP00000490] [MT6620 Wi-Fi][Driver][Win32] modify kalMsleep() implementation because NdisMSleep() won't sleep -+ * long enough for specified interval such as 500ms -+ * modify cnm_timer and hem_mbox APIs to be thread safe to ease invoking restrictions -+ * -+ * 01 12 2011 cp.wu -+ * [WCXRP00000357] [MT6620 Wi-Fi][Driver][Bluetooth over Wi-Fi] add another net device interface for BT AMP -+ * implementation of separate BT_OVER_WIFI data path. -+ * -+ * 01 04 2011 cp.wu -+ * [WCXRP00000338] [MT6620 Wi-Fi][Driver] Separate kalMemAlloc into kmalloc and vmalloc implementations to ease -+ * physically continuous memory demands -+ * separate kalMemAlloc() into virtually-continuous and physically-continuous type to ease slab system pressure -+ * -+ * 12 31 2010 cp.wu -+ * [WCXRP00000335] [MT6620 Wi-Fi][Driver] change to use milliseconds sleep instead of delay to avoid blocking to system -+ * scheduling -+ * change to use msleep() and shorten waiting interval to reduce blocking to other task while Wi-Fi driver is being -+ * loaded -+ * -+ * 12 31 2010 jeffrey.chang -+ * [WCXRP00000332] [MT6620 Wi-Fi][Driver] add kal sleep function for delay which use blocking call -+ * modify the implementation of kalDelay to msleep -+ * -+ * 12 22 2010 cp.wu -+ * [WCXRP00000283] [MT6620 Wi-Fi][Driver][Wi-Fi Direct] Implementation of interface for supporting Wi-Fi Direct Service -+ * Discovery -+ * 1. header file restructure for more clear module isolation -+ * 2. add function interface definition for implementing Service Discovery callbacks -+ * -+ * 11 30 2010 yuche.tsai -+ * NULL -+ * Invitation & Provision Discovery Indication. -+ * -+ * 11 26 2010 cp.wu -+ * [WCXRP00000209] [MT6620 Wi-Fi][Driver] Modify NVRAM checking mechanism to warning only with necessary data field -+ * checking -+ * 1. NVRAM error is now treated as warning only, thus normal operation is still available but extra scan result used -+ * to indicate user is attached -+ * 2. DPD and TX-PWR are needed fields from now on, if these 2 fields are not available then warning message is shown -+ * -+ * 11 08 2010 cp.wu -+ * [WCXRP00000166] [MT6620 Wi-Fi][Driver] use SDIO CMD52 for enabling/disabling interrupt to reduce transaction period -+ * change to use CMD52 for enabling/disabling interrupt to reduce SDIO transaction time -+ * -+ * 11 01 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000150] [MT6620 Wi-Fi][Driver] -+ * Add implementation for querying current TX rate from firmware auto rate module -+ * 1) Query link speed (TX rate) from firmware directly with buffering mechanism to reduce overhead -+ * 2) Remove CNM CH-RECOVER event handling -+ * 3) cfg read/write API renamed with kal prefix for unified naming rules. -+ * -+ * 10 05 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check -+ * 1) add NVRAM access API -+ * 2) fake scanning result when NVRAM doesn't exist and/or version mismatch. (off by compiler option) -+ * 3) add OID implementation for NVRAM read/write service -+ * -+ * 10 04 2010 wh.su -+ * [WCXRP00000081] [MT6620][Driver] Fix the compiling error at WinXP while enable P2P -+ * add a kal function for set cipher. -+ * -+ * 10 04 2010 wh.su -+ * [WCXRP00000081] [MT6620][Driver] Fix the compiling error at WinXP while enable P2P -+ * fixed compiling error while enable p2p. -+ * -+ * 09 28 2010 wh.su -+ * NULL -+ * [WCXRP00000069][MT6620 Wi-Fi][Driver] Fix some code for phase 1 P2P Demo. -+ * -+ * 09 21 2010 cp.wu -+ * [WCXRP00000053] [MT6620 Wi-Fi][Driver] Reset incomplete and might leads to BSOD when entering RF test with AIS -+ * associated -+ * Do a complete reset with STA-REC null checking for RF test re-entry -+ * -+ * 09 21 2010 kevin.huang -+ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning -+ * Eliminate Linux Compile Warning -+ * -+ * 09 10 2010 wh.su -+ * NULL -+ * fixed the compiling error at win XP. -+ * -+ * 09 07 2010 wh.su -+ * NULL -+ * adding the code for beacon/probe req/ probe rsp wsc ie at p2p. -+ * -+ * 09 06 2010 wh.su -+ * NULL -+ * let the p2p can set the privacy bit at beacon and rsn ie at assoc req at key handshake state. -+ * -+ * 09 03 2010 kevin.huang -+ * NULL -+ * Refine #include sequence and solve recursive/nested #include issue -+ * -+ * 08 06 2010 cp.wu -+ * NULL -+ * driver hook modifications corresponding to ioctl interface change. -+ * -+ * 08 03 2010 cp.wu -+ * NULL -+ * [Wi-Fi Direct Driver Hook] change event indication API to be consistent with supplicant -+ * -+ * 08 03 2010 cp.wu -+ * NULL -+ * [Wi-Fi Direct] add framework for driver hooks -+ * -+ * 08 02 2010 jeffrey.chang -+ * NULL -+ * modify kalSetEvent declaration -+ * -+ * 07 29 2010 cp.wu -+ * NULL -+ * simplify post-handling after TX_DONE interrupt is handled. -+ * -+ * 07 23 2010 cp.wu -+ * -+ * 1) re-enable AIS-FSM beacon timeout handling. -+ * 2) scan done API revised -+ * -+ * 07 23 2010 jeffrey.chang -+ * -+ * fix kal header file -+ * -+ * 07 22 2010 jeffrey.chang -+ * -+ * use different spin lock for security frame -+ * -+ * 07 22 2010 jeffrey.chang -+ * -+ * add new spinlock -+ * -+ * 07 19 2010 jeffrey.chang -+ * -+ * add kal api for scanning done -+ * -+ * 07 19 2010 jeffrey.chang -+ * -+ * modify cmd/data path for new design -+ * -+ * 07 19 2010 jeffrey.chang -+ * -+ * add new kal api -+ * -+ * 07 19 2010 jeffrey.chang -+ * -+ * Linux port modification -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 21 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * change MAC address updating logic. -+ * -+ * 06 18 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Provide cnmMgtPktAlloc() and alloc/free function of msg/buf -+ * -+ * 06 11 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) migrate assoc.c. -+ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness -+ * 3) add configuration options for CNM_MEM and RSN modules -+ * 4) add data path for management frames -+ * 5) eliminate rPacketInfo of MSDU_INFO_T -+ * -+ * 06 07 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * gl_kal merged -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 05 17 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * add basic handling framework for wireless extension ioctls. -+ * -+ * 05 11 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * add ioctl for controlling p2p scan phase parameters -+ * -+ * 05 10 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * fill network type field while doing frame identification. -+ * -+ * 05 10 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * implement basic wi-fi direct framework -+ * -+ * 05 07 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * add basic framework for implementating P2P driver hook. -+ * -+ * 05 07 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * modify kalMemAlloc method -+ * -+ * 04 28 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * change prefix for data structure used to communicate with 802.11 PAL -+ * to avoid ambiguous naming with firmware interface -+ * -+ * 04 27 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * add multiple physical link support -+ * -+ * 04 27 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * follow Linux's firmware framework, and remove unused kal API -+ * -+ * 04 22 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * when acquiring driver-own, wait for up to 8 seconds. -+ * -+ * 04 22 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * -+ * 1) modify rx path code for supporting Wi-Fi direct -+ * 2) modify config.h since Linux dont need to consider retaining packet -+ * -+ * 04 21 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * add for private ioctl support -+ * -+ * 04 20 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * don't need SPIN_LOCK_PWR_CTRL anymore, it will raise IRQL -+ * * and cause SdBusSubmitRequest running at DISPATCH_LEVEL as well. -+ * -+ * 04 14 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * information buffer for query oid/ioctl is now buffered in prCmdInfo -+ * * * * * * * * instead of glue-layer variable to improve multiple oid/ioctl capability -+ * -+ * 04 13 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * add framework for BT-over-Wi-Fi support. -+ * * * * * * * * * * * * * * * * * * * 1) prPendingCmdInfo is replaced by queue for multiple handler -+ * * * * * * * * * * * * * * * * * * * capability -+ * * * * * * * * * * * * * * * * * * * 2) command sequence number is now increased atomically -+ * * * * * * * * * * * * * * * * * * * 3) private data could be hold and taken use for other purpose -+ * -+ * 04 09 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * 1) add spinlock -+ * * * 2) add KAPI for handling association info -+ * -+ * 04 09 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * adding firmware download KAPI -+ * -+ * 04 07 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * finish non-glue layer access to glue variables -+ * -+ * 04 07 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * accessing to firmware load/start address, and access to OID handling information -+ * * * * are now handled in glue layer -+ * -+ * 04 07 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * rWlanInfo should be placed at adapter rather than glue due to most operations -+ * * * * * * * * * are done in adapter layer. -+ * -+ * 04 07 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * eliminate direct access to prGlueInfo->eParamMediaStateIndicated from non-glue layer -+ * -+ * 04 06 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * add KAL API: kalFlushPendingTxPackets(), and take use of the API -+ * -+ * 04 06 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * eliminate direct access to prGlueInfo->rWlanInfo.eLinkAttr.ucMediaStreamMode from non-glue layer. -+ * -+ * 04 06 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * improve none-glue code portability -+ * -+ * 04 06 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * code refine: fgTestMode should be at adapter rather than glue due to the device/fw is also involved -+ * -+ * 04 06 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) for some OID, never do timeout expiration -+ * * * * 2) add 2 kal API for later integration -+ * -+ * 03 30 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * emulate NDIS Pending OID facility -+ * -+ * 03 26 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * [WPD00003826] Initial import for Linux port -+ * adding firmware download KAPI -+ * -+ * 03 24 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * initial import for Linux port -+** \main\maintrunk.MT5921\41 2009-09-28 20:19:23 GMT mtk01090 -+** Add private ioctl to carry OID structures. Restructure public/private ioctl interfaces to Linux kernel. -+** \main\maintrunk.MT5921\40 2009-08-18 22:57:09 GMT mtk01090 -+** Add Linux SDIO (with mmc core) support. -+** Add Linux 2.6.21, 2.6.25, 2.6.26. -+** Fix compile warning in Linux. -+** \main\maintrunk.MT5921\39 2009-06-23 23:19:15 GMT mtk01090 -+** Add build option BUILD_USE_EEPROM and compile option CFG_SUPPORT_EXT_CONFIG for NVRAM support -+** \main\maintrunk.MT5921\38 2009-02-09 14:03:17 GMT mtk01090 -+** Add KAL function kalDevSetPowerState(). It is not implemented yet. Only add an empty macro. -+** -+** \main\maintrunk.MT5921\37 2009-01-22 13:05:59 GMT mtk01088 -+** new defeine to got 1x value at packet reserved field -+** \main\maintrunk.MT5921\36 2008-12-08 16:15:02 GMT mtk01461 -+** Add kalQueryValidBufferLength() macro -+** \main\maintrunk.MT5921\35 2008-11-13 20:33:15 GMT mtk01104 -+** Remove lint warning -+** \main\maintrunk.MT5921\34 2008-10-22 11:05:52 GMT mtk01461 -+** Remove unused macro -+** \main\maintrunk.MT5921\33 2008-10-16 15:48:17 GMT mtk01461 -+** Update driver to fix lint warning -+** \main\maintrunk.MT5921\32 2008-09-02 11:50:51 GMT mtk01461 -+** SPIN_LOCK_SDIO_DDK_TX_QUE -+** \main\maintrunk.MT5921\31 2008-08-29 15:58:30 GMT mtk01088 -+** remove non-used function for code refine -+** \main\maintrunk.MT5921\30 2008-08-21 00:33:29 GMT mtk01461 -+** Update for Driver Review -+** \main\maintrunk.MT5921\29 2008-06-19 13:29:14 GMT mtk01425 -+** 1. Add declaration of SPIN_LOCK_SDIO_DDK_TX_QUE and SPIN_LOCK_SDIO_DDK_RX_QUE -+** \main\maintrunk.MT5921\28 2008-05-30 20:27:34 GMT mtk01461 -+** Rename KAL function -+** \main\maintrunk.MT5921\27 2008-05-30 14:42:05 GMT mtk01461 -+** Remove WMM Assoc Flag in KAL -+** \main\maintrunk.MT5921\26 2008-05-29 14:15:18 GMT mtk01084 -+** remove un-used function -+** \main\maintrunk.MT5921\25 2008-04-23 14:02:20 GMT mtk01084 -+** modify KAL port access function prototype -+** \main\maintrunk.MT5921\24 2008-04-17 23:06:41 GMT mtk01461 -+** Add iwpriv support for AdHocMode setting -+** \main\maintrunk.MT5921\23 2008-04-08 15:38:50 GMT mtk01084 -+** add KAL function to setting pattern search function enable/ disable -+** \main\maintrunk.MT5921\22 2008-03-26 15:34:48 GMT mtk01461 -+** Add update MAC address func -+** \main\maintrunk.MT5921\21 2008-03-18 15:56:15 GMT mtk01084 -+** update ENUM_NIC_INITIAL_PARAM_E -+** \main\maintrunk.MT5921\20 2008-03-18 11:49:28 GMT mtk01084 -+** update function for initial value access -+** \main\maintrunk.MT5921\19 2008-03-18 10:21:31 GMT mtk01088 -+** use kal update associate request at linux -+** \main\maintrunk.MT5921\18 2008-03-14 18:03:41 GMT mtk01084 -+** refine register and port access function -+** \main\maintrunk.MT5921\17 2008-03-11 14:51:02 GMT mtk01461 -+** Add copy_to(from)_user macro -+** \main\maintrunk.MT5921\16 2008-03-06 23:42:21 GMT mtk01385 -+** 1. add Query Registry Mac address function. -+** \main\maintrunk.MT5921\15 2008-02-26 09:48:04 GMT mtk01084 -+** modify KAL set network address/ checksum offload part -+** \main\maintrunk.MT5921\14 2008-01-09 17:54:58 GMT mtk01084 -+** Modify the argument of kalQueryPacketInfo -+** \main\maintrunk.MT5921\13 2007-11-29 02:05:20 GMT mtk01461 -+** Fix Windows RX multiple packet retain problem -+** \main\maintrunk.MT5921\12 2007-11-26 19:43:45 GMT mtk01461 -+** Add OS_TIMESTAMP macro -+** -+** \main\maintrunk.MT5921\11 2007-11-09 16:36:15 GMT mtk01425 -+** 1. Modify for CSUM offloading with Tx Fragment -+** \main\maintrunk.MT5921\10 2007-11-07 18:38:37 GMT mtk01461 -+** Add Tx Fragmentation Support -+** \main\maintrunk.MT5921\9 2007-11-06 19:36:50 GMT mtk01088 -+** add the WPS related code -+** \main\maintrunk.MT5921\8 2007-11-02 01:03:57 GMT mtk01461 -+** Unify TX Path for Normal and IBSS Power Save + IBSS neighbor learning -+** Revision 1.4 2007/07/05 07:25:33 MTK01461 -+** Add Linux initial code, modify doc, add 11BB, RF init code -+** -+** Revision 1.3 2007/06/27 02:18:50 MTK01461 -+** Update SCAN_FSM, Initial(Can Load Module), Proc(Can do Reg R/W), TX API -+** -+** Revision 1.2 2007/06/25 06:16:23 MTK01461 -+** Update illustrations, gl_init.c, gl_kal.c, gl_kal.h, gl_os.h and RX API -+** -+*/ -+ -+#ifndef _GL_KAL_H -+#define _GL_KAL_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "config.h" -+#include "gl_typedef.h" -+#include "gl_os.h" -+#include "link.h" -+#include "nic/mac.h" -+#include "nic/wlan_def.h" -+#include "wlan_lib.h" -+#include "wlan_oid.h" -+#include "gl_wext_priv.h" -+#include -+ -+#if CFG_ENABLE_BT_OVER_WIFI -+#include "nic/bow.h" -+#endif -+ -+#if DBG -+extern int allocatedMemSize; -+#endif -+ -+#if CFG_SUPPORT_MET_PROFILING -+#include "linux/kallsyms.h" -+#include -+#endif -+ -+extern BOOLEAN fgIsUnderSuspend; -+extern UINT_32 TaskIsrCnt; -+extern BOOLEAN fgIsResetting; -+extern int wlanHardStartXmit(struct sk_buff *prSkb, struct net_device *prDev); -+extern UINT_32 u4MemAllocCnt, u4MemFreeCnt; -+ -+ -+extern struct delayed_work sched_workq; -+ -+#if defined(MT6620) && CFG_MULTI_ECOVER_SUPPORT -+extern ENUM_WMTHWVER_TYPE_T mtk_wcn_wmt_hwver_get(VOID); -+#endif -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+/* #define USEC_PER_MSEC (1000) */ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+typedef enum _ENUM_SPIN_LOCK_CATEGORY_E { -+ SPIN_LOCK_FSM = 0, -+ -+ /* FIX ME */ -+ SPIN_LOCK_RX_QUE, -+ SPIN_LOCK_TX_QUE, -+ SPIN_LOCK_CMD_QUE, -+ SPIN_LOCK_TX_RESOURCE, -+ SPIN_LOCK_CMD_RESOURCE, -+ SPIN_LOCK_QM_TX_QUEUE, -+ SPIN_LOCK_CMD_PENDING, -+ SPIN_LOCK_CMD_SEQ_NUM, -+ SPIN_LOCK_TX_MSDU_INFO_LIST, -+ SPIN_LOCK_TXING_MGMT_LIST, -+ SPIN_LOCK_TX_SEQ_NUM, -+ SPIN_LOCK_TX_COUNT, -+ SPIN_LOCK_TXS_COUNT, -+ /* end */ -+ SPIN_LOCK_TX, -+ SPIN_LOCK_IO_REQ, -+ SPIN_LOCK_INT, -+ -+ SPIN_LOCK_MGT_BUF, -+ SPIN_LOCK_MSG_BUF, -+ SPIN_LOCK_STA_REC, -+ -+ SPIN_LOCK_MAILBOX, -+ SPIN_LOCK_TIMER, -+ -+ SPIN_LOCK_BOW_TABLE, -+ -+ SPIN_LOCK_EHPI_BUS, /* only for EHPI */ -+ SPIN_LOCK_NET_DEV, -+ SPIN_LOCK_NUM -+} ENUM_SPIN_LOCK_CATEGORY_E; -+ -+/* event for assoc information update */ -+typedef struct _EVENT_ASSOC_INFO { -+ UINT_8 ucAssocReq; /* 1 for assoc req, 0 for assoc rsp */ -+ UINT_8 ucReassoc; /* 0 for assoc, 1 for reassoc */ -+ UINT_16 u2Length; -+ PUINT_8 pucIe; -+} EVENT_ASSOC_INFO, *P_EVENT_ASSOC_INFO; -+ -+typedef enum _ENUM_KAL_NETWORK_TYPE_INDEX_T { -+ KAL_NETWORK_TYPE_AIS_INDEX = 0, -+#if CFG_ENABLE_WIFI_DIRECT -+ KAL_NETWORK_TYPE_P2P_INDEX, -+#endif -+#if CFG_ENABLE_BT_OVER_WIFI -+ KAL_NETWORK_TYPE_BOW_INDEX, -+#endif -+ KAL_NETWORK_TYPE_INDEX_NUM -+} ENUM_KAL_NETWORK_TYPE_INDEX_T; -+ -+typedef enum _ENUM_KAL_MEM_ALLOCATION_TYPE_E { -+ PHY_MEM_TYPE, /* physically continuous */ -+ VIR_MEM_TYPE, /* virtually continuous */ -+ MEM_TYPE_NUM -+} ENUM_KAL_MEM_ALLOCATION_TYPE; -+ -+#if CONFIG_ANDROID /* Defined in Android kernel source */ -+typedef struct wake_lock KAL_WAKE_LOCK_T, *P_KAL_WAKE_LOCK_T; -+#else -+typedef UINT_32 KAL_WAKE_LOCK_T, *P_KAL_WAKE_LOCK_T; -+#endif -+ -+#if CFG_SUPPORT_AGPS_ASSIST -+typedef enum _ENUM_MTK_AGPS_ATTR { -+ MTK_ATTR_AGPS_INVALID, -+ MTK_ATTR_AGPS_CMD, -+ MTK_ATTR_AGPS_DATA, -+ MTK_ATTR_AGPS_IFINDEX, -+ MTK_ATTR_AGPS_IFNAME, -+ MTK_ATTR_AGPS_MAX -+} ENUM_MTK_CCX_ATTR; -+ -+typedef enum _ENUM_AGPS_EVENT { -+ AGPS_EVENT_WLAN_ON, -+ AGPS_EVENT_WLAN_OFF, -+ AGPS_EVENT_WLAN_AP_LIST, -+ WIFI_EVENT_CHIP_RESET, -+} ENUM_CCX_EVENT; -+BOOLEAN kalIndicateAgpsNotify(P_ADAPTER_T prAdapter, UINT_8 cmd, PUINT_8 data, UINT_16 dataLen); -+#endif -+ -+struct KAL_HALT_CTRL_T { -+ struct semaphore lock; -+ struct task_struct *owner; -+ BOOLEAN fgHalt; -+ BOOLEAN fgHeldByKalIoctl; -+ OS_SYSTIME u4HoldStart; -+}; -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/*----------------------------------------------------------------------------*/ -+/* Macros of bit operation */ -+/*----------------------------------------------------------------------------*/ -+#define KAL_SET_BIT(bitOffset, value) set_bit(bitOffset, &value) -+#define KAL_CLR_BIT(bitOffset, value) clear_bit(bitOffset, &value) -+#define KAL_TEST_AND_CLEAR_BIT(bitOffset, value) test_and_clear_bit(bitOffset, &value) -+#define KAL_TEST_BIT(bitOffset, value) test_bit(bitOffset, &value) -+ -+/*----------------------------------------------------------------------------*/ -+/* Macros of SPIN LOCK operations for using in Driver Layer */ -+/*----------------------------------------------------------------------------*/ -+#define KAL_SPIN_LOCK_DECLARATION() unsigned long __u4Flags -+ -+#define KAL_ACQUIRE_SPIN_LOCK(_prAdapter, _rLockCategory) \ -+ kalAcquireSpinLock(((P_ADAPTER_T)_prAdapter)->prGlueInfo, _rLockCategory, &__u4Flags) -+ -+#define KAL_RELEASE_SPIN_LOCK(_prAdapter, _rLockCategory) \ -+ kalReleaseSpinLock(((P_ADAPTER_T)_prAdapter)->prGlueInfo, _rLockCategory, __u4Flags) -+ -+/*----------------------------------------------------------------------------*/ -+/* Macros for accessing Reserved Fields of native packet */ -+/*----------------------------------------------------------------------------*/ -+#define KAL_GET_PKT_QUEUE_ENTRY(_p) GLUE_GET_PKT_QUEUE_ENTRY(_p) -+#define KAL_GET_PKT_DESCRIPTOR(_prQueueEntry) GLUE_GET_PKT_DESCRIPTOR(_prQueueEntry) -+#define KAL_GET_PKT_TID(_p) GLUE_GET_PKT_TID(_p) -+#define KAL_GET_PKT_IS1X(_p) GLUE_GET_PKT_IS1X(_p) -+#define KAL_GET_PKT_HEADER_LEN(_p) GLUE_GET_PKT_HEADER_LEN(_p) -+#define KAL_GET_PKT_PAYLOAD_LEN(_p) GLUE_GET_PKT_PAYLOAD_LEN(_p) -+#define KAL_GET_PKT_ARRIVAL_TIME(_p) GLUE_GET_PKT_ARRIVAL_TIME(_p) -+ -+/*----------------------------------------------------------------------------*/ -+/* Macros of wake_lock operations for using in Driver Layer */ -+/*----------------------------------------------------------------------------*/ -+#if CONFIG_ANDROID /* Defined in Android kernel source */ -+#define KAL_WAKE_LOCK_INIT(_prAdapter, _prWakeLock, _pcName) \ -+ wake_lock_init(_prWakeLock, WAKE_LOCK_SUSPEND, _pcName) -+ -+#define KAL_WAKE_LOCK_DESTROY(_prAdapter, _prWakeLock) \ -+ wake_lock_destroy(_prWakeLock) -+ -+#define KAL_WAKE_LOCK(_prAdapter, _prWakeLock) \ -+ wake_lock(_prWakeLock) -+ -+#define KAL_WAKE_LOCK_TIMEOUT(_prAdapter, _prWakeLock, _u4Timeout) \ -+ wake_lock_timeout(_prWakeLock, _u4Timeout) -+ -+#define KAL_WAKE_UNLOCK(_prAdapter, _prWakeLock) \ -+ wake_unlock(_prWakeLock) -+ -+#else -+#define KAL_WAKE_LOCK_INIT(_prAdapter, _prWakeLock, _pcName) -+#define KAL_WAKE_LOCK_DESTROY(_prAdapter, _prWakeLock) -+#define KAL_WAKE_LOCK(_prAdapter, _prWakeLock) -+#define KAL_WAKE_LOCK_TIMEOUT(_prAdapter, _prWakeLock, _u4Timeout) -+#define KAL_WAKE_UNLOCK(_prAdapter, _prWakeLock) -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Cache memory allocation -+* -+* \param[in] u4Size Required memory size. -+* \param[in] eMemType Memory allocation type -+* -+* \return Pointer to allocated memory -+* or NULL -+*/ -+/*----------------------------------------------------------------------------*/ -+#if DBG -+#define kalMemAlloc(u4Size, eMemType) ({ \ -+ void *pvAddr; \ -+ if (eMemType == PHY_MEM_TYPE) { \ -+ pvAddr = kmalloc(u4Size, GFP_KERNEL); \ -+ } \ -+ else { \ -+ pvAddr = vmalloc(u4Size); \ -+ } \ -+ if (pvAddr) { \ -+ allocatedMemSize += u4Size; \ -+ DBGLOG(INIT, INFO, "%p(%u) allocated (%s:%s)\n", \ -+ pvAddr, (UINT_32)u4Size, __FILE__, __func__); \ -+ } \ -+ pvAddr; \ -+}) -+#else -+#define kalMemAlloc(u4Size, eMemType) ({ \ -+ void *pvAddr; \ -+ if (eMemType == PHY_MEM_TYPE) { \ -+ pvAddr = kmalloc(u4Size, GFP_KERNEL); \ -+ } \ -+ else { \ -+ pvAddr = vmalloc(u4Size); \ -+ } \ -+ pvAddr; \ -+}) -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Free allocated cache memory -+* -+* \param[in] pvAddr Required memory size. -+* \param[in] eMemType Memory allocation type -+* \param[in] u4Size Allocated memory size. -+* -+* \return - -+*/ -+/*----------------------------------------------------------------------------*/ -+#if DBG -+#define kalMemFree(pvAddr, eMemType, u4Size) \ -+{ \ -+ if (pvAddr) { \ -+ allocatedMemSize -= u4Size; \ -+ DBGLOG(INIT, INFO, "%p(%u) freed (%s:%s)\n", \ -+ pvAddr, (UINT_32)u4Size, __FILE__, __func__); \ -+ } \ -+ if (eMemType == PHY_MEM_TYPE) { \ -+ kfree(pvAddr); \ -+ } \ -+ else { \ -+ vfree(pvAddr); \ -+ } \ -+} -+#else -+#define kalMemFree(pvAddr, eMemType, u4Size) \ -+{ \ -+ if (eMemType == PHY_MEM_TYPE) { \ -+ kfree(pvAddr); \ -+ } \ -+ else { \ -+ vfree(pvAddr); \ -+ } \ -+} -+#endif -+ -+#define kalUdelay(u4USec) udelay(u4USec) -+ -+#define kalMdelay(u4MSec) mdelay(u4MSec) -+#define kalMsleep(u4MSec) msleep(u4MSec) -+ -+/* Copy memory from user space to kernel space */ -+#define kalMemCopyFromUser(_pvTo, _pvFrom, _u4N) copy_from_user(_pvTo, _pvFrom, _u4N) -+ -+/* Copy memory from kernel space to user space */ -+#define kalMemCopyToUser(_pvTo, _pvFrom, _u4N) copy_to_user(_pvTo, _pvFrom, _u4N) -+ -+/* Copy memory block with specific size */ -+#define kalMemCopy(pvDst, pvSrc, u4Size) memcpy(pvDst, pvSrc, u4Size) -+ -+/* Set memory block with specific pattern */ -+#define kalMemSet(pvAddr, ucPattern, u4Size) memset(pvAddr, ucPattern, u4Size) -+ -+/* Compare two memory block with specific length. -+ * Return zero if they are the same. -+ */ -+#define kalMemCmp(pvAddr1, pvAddr2, u4Size) memcmp(pvAddr1, pvAddr2, u4Size) -+ -+/* Zero specific memory block */ -+#define kalMemZero(pvAddr, u4Size) memset(pvAddr, 0, u4Size) -+ -+/* string operation */ -+#define kalStrCpy(dest, src) strcpy(dest, src) -+#define kalStrnCpy(dest, src, n) strncpy(dest, src, n) -+#define kalStrCmp(ct, cs) strcmp(ct, cs) -+#define kalStrnCmp(ct, cs, n) strncmp(ct, cs, n) -+#define kalStrChr(s, c) strchr(s, c) -+#define kalStrrChr(s, c) strrchr(s, c) -+#define kalStrnChr(s, n, c) strnchr(s, n, c) -+#define kalStrLen(s) strlen(s) -+#define kalStrnLen(s, b) strnlen(s, b) -+//#define kalStrniCmp(s1, s2, n) strnicmp(s1, s2, n) -+#define kalStrniCmp(s1, s2, n) strncasecmp(s1, s2, n) -+#define strnicmp(s1, s2, n) strncasecmp(s1, s2, n) -+/* #define kalStrtoul(cp, endp, base) simple_strtoul(cp, endp, base) -+#define kalStrtol(cp, endp, base) simple_strtol(cp, endp, base) */ -+#define kalkStrtou32(cp, base, resp) kstrtou32(cp, base, resp) -+#define kalkStrtos32(cp, base, resp) kstrtos32(cp, base, resp) -+#define kalSnprintf(buf, size, fmt, ...) snprintf(buf, size, fmt, __VA_ARGS__) -+#define kalSprintf(buf, fmt, ...) sprintf(buf, fmt, __VA_ARGS__) -+/* remove for AOSP */ -+/* #define kalSScanf(buf, fmt, ...) sscanf(buf, fmt, __VA_ARGS__) */ -+#define kalStrStr(ct, cs) strstr(ct, cs) -+#define kalStrSep(s, ct) strsep(s, ct) -+#define kalStrCat(dest, src) strcat(dest, src) -+ -+/* defined for wince sdio driver only */ -+#if defined(_HIF_SDIO) -+#define kalDevSetPowerState(prGlueInfo, ePowerMode) glSetPowerState(prGlueInfo, ePowerMode) -+#else -+#define kalDevSetPowerState(prGlueInfo, ePowerMode) -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Notify OS with SendComplete event of the specific packet. Linux should -+* free packets here. -+* -+* \param[in] prGlueInfo Pointer of GLUE Data Structure -+* \param[in] pvPacket Pointer of Packet Handle -+* \param[in] status Status Code for OS upper layer -+* -+* \return - -+*/ -+/*----------------------------------------------------------------------------*/ -+#define kalSendComplete(prGlueInfo, pvPacket, status) \ -+ kalSendCompleteAndAwakeQueue(prGlueInfo, pvPacket) -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is used to locate the starting address of incoming ethernet -+* frame for skb. -+* -+* \param[in] prGlueInfo Pointer of GLUE Data Structure -+* \param[in] pvPacket Pointer of Packet Handle -+* -+* \return starting address of ethernet frame buffer. -+*/ -+/*----------------------------------------------------------------------------*/ -+#define kalQueryBufferPointer(prGlueInfo, pvPacket) \ -+ ((PUINT_8)((struct sk_buff *)pvPacket)->data) -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is used to query the length of valid buffer which is accessible during -+* port read/write. -+* -+* \param[in] prGlueInfo Pointer of GLUE Data Structure -+* \param[in] pvPacket Pointer of Packet Handle -+* -+* \return starting address of ethernet frame buffer. -+*/ -+/*----------------------------------------------------------------------------*/ -+#define kalQueryValidBufferLength(prGlueInfo, pvPacket) \ -+ ((UINT_32)((struct sk_buff *)pvPacket)->end - \ -+ (UINT_32)((struct sk_buff *)pvPacket)->data) -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is used to copy the entire frame from skb to the destination -+* address in the input parameter. -+* -+* \param[in] prGlueInfo Pointer of GLUE Data Structure -+* \param[in] pvPacket Pointer of Packet Handle -+* \param[in] pucDestBuffer Destination Address -+* -+* \return - -+*/ -+/*----------------------------------------------------------------------------*/ -+#define kalCopyFrame(prGlueInfo, pvPacket, pucDestBuffer) \ -+ do {struct sk_buff *skb = (struct sk_buff *)pvPacket; \ -+ memcpy(pucDestBuffer, skb->data, skb->len); } while (0) -+ -+#define kalGetTimeTick() jiffies_to_msecs(jiffies) -+ -+#define kalPrint pr_debug -+ -+#if !DBG -+#define AIS_ERROR_LOGFUNC(_Fmt...) -+#define AIS_WARN_LOGFUNC(_Fmt...) -+#define AIS_INFO_LOGFUNC(_Fmt...) -+#define AIS_STATE_LOGFUNC(_Fmt...) -+#define AIS_EVENT_LOGFUNC(_Fmt...) -+#define AIS_TRACE_LOGFUNC(_Fmt...) -+#define AIS_LOUD_LOGFUNC(_Fmt...) -+#define AIS_TEMP_LOGFUNC(_Fmt...) -+ -+#define INTR_ERROR_LOGFUNC(_Fmt...) -+#define INTR_WARN_LOGFUNC(_Fmt...) -+#define INTR_INFO_LOGFUNC(_Fmt...) -+#define INTR_STATE_LOGFUNC(_Fmt...) -+#define INTR_EVENT_LOGFUNC(_Fmt...) -+#define INTR_TRACE_LOGFUNC(_Fmt...) -+#define INTR_LOUD_LOGFUNC(_Fmt...) -+#define INTR_TEMP_LOGFUNC(_Fmt...) -+ -+#define INIT_ERROR_LOGFUNC(_Fmt...) kalPrint(_Fmt) -+#define INIT_WARN_LOGFUNC(_Fmt...) kalPrint(_Fmt) -+#define INIT_INFO_LOGFUNC(_Fmt...) kalPrint(_Fmt) -+#define INIT_STATE_LOGFUNC(_Fmt...) kalPrint(_Fmt) -+#define INIT_EVENT_LOGFUNC(_Fmt...) kalPrint(_Fmt) -+#define INIT_TRACE_LOGFUNC(_Fmt...) -+#define INIT_LOUD_LOGFUNC(_Fmt...) -+#define INIT_TEMP_LOGFUNC(_Fmt...) -+ -+#define AAA_ERROR_LOGFUNC(_Fmt...) kalPrint(_Fmt) -+#define AAA_WARN_LOGFUNC(_Fmt...) kalPrint(_Fmt) -+#define AAA_INFO_LOGFUNC(_Fmt...) kalPrint(_Fmt) -+#define AAA_STATE_LOGFUNC(_Fmt...) kalPrint(_Fmt) -+#define AAA_EVENT_LOGFUNC(_Fmt...) kalPrint(_Fmt) -+#define AAA_TRACE_LOGFUNC(_Fmt...) kalPrint(_Fmt) -+#define AAA_LOUD_LOGFUNC(_Fmt...) -+#define AAA_TEMP_LOGFUNC(_Fmt...) -+ -+#define ROAMING_ERROR_LOGFUNC(_Fmt...) -+#define ROAMING_WARN_LOGFUNC(_Fmt...) -+#define ROAMING_INFO_LOGFUNC(_Fmt...) -+#define ROAMING_STATE_LOGFUNC(_Fmt...) -+#define ROAMING_EVENT_LOGFUNC(_Fmt...) -+#define ROAMING_TRACE_LOGFUNC(_Fmt...) -+#define ROAMING_LOUD_LOGFUNC(_Fmt...) -+#define ROAMING_TEMP_LOGFUNC(_Fmt...) -+ -+#define REQ_ERROR_LOGFUNC(_Fmt...) -+#define REQ_WARN_LOGFUNC(_Fmt...) -+#define REQ_INFO_LOGFUNC(_Fmt...) -+#define REQ_STATE_LOGFUNC(_Fmt...) -+#define REQ_EVENT_LOGFUNC(_Fmt...) -+#define REQ_TRACE_LOGFUNC(_Fmt...) -+#define REQ_LOUD_LOGFUNC(_Fmt...) -+#define REQ_TEMP_LOGFUNC(_Fmt...) -+ -+#define TX_ERROR_LOGFUNC(_Fmt...) -+#define TX_WARN_LOGFUNC(_Fmt...) -+#define TX_INFO_LOGFUNC(_Fmt...) -+#define TX_STATE_LOGFUNC(_Fmt...) -+#define TX_EVENT_LOGFUNC(_Fmt...) -+#define TX_TRACE_LOGFUNC(_Fmt...) kalPrint(_Fmt) -+#define TX_LOUD_LOGFUNC(_Fmt...) -+#define TX_TEMP_LOGFUNC(_Fmt...) -+ -+#define RX_ERROR_LOGFUNC(_Fmt...) -+#define RX_WARN_LOGFUNC(_Fmt...) -+#define RX_INFO_LOGFUNC(_Fmt...) -+#define RX_STATE_LOGFUNC(_Fmt...) -+#define RX_EVENT_LOGFUNC(_Fmt...) -+#define RX_TRACE_LOGFUNC(_Fmt...) -+#define RX_LOUD_LOGFUNC(_Fmt...) -+#define RX_TEMP_LOGFUNC(_Fmt...) -+ -+#define RFTEST_ERROR_LOGFUNC(_Fmt...) -+#define RFTEST_WARN_LOGFUNC(_Fmt...) -+#define RFTEST_INFO_LOGFUNC(_Fmt...) -+#define RFTEST_STATE_LOGFUNC(_Fmt...) -+#define RFTEST_EVENT_LOGFUNC(_Fmt...) -+#define RFTEST_TRACE_LOGFUNC(_Fmt...) -+#define RFTEST_LOUD_LOGFUNC(_Fmt...) -+#define RFTEST_TEMP_LOGFUNC(_Fmt...) -+ -+#define EMU_ERROR_LOGFUNC(_Fmt...) -+#define EMU_WARN_LOGFUNC(_Fmt...) -+#define EMU_INFO_LOGFUNC(_Fmt...) -+#define EMU_STATE_LOGFUNC(_Fmt...) -+#define EMU_EVENT_LOGFUNC(_Fmt...) -+#define EMU_TRACE_LOGFUNC(_Fmt...) -+#define EMU_LOUD_LOGFUNC(_Fmt...) -+#define EMU_TEMP_LOGFUNC(_Fmt...) -+ -+#define HEM_ERROR_LOGFUNC(_Fmt...) -+#define HEM_WARN_LOGFUNC(_Fmt...) -+#define HEM_INFO_LOGFUNC(_Fmt...) -+#define HEM_STATE_LOGFUNC(_Fmt...) -+#define HEM_EVENT_LOGFUNC(_Fmt...) -+#define HEM_TRACE_LOGFUNC(_Fmt...) -+#define HEM_LOUD_LOGFUNC(_Fmt...) -+#define HEM_TEMP_LOGFUNC(_Fmt...) -+ -+#define RLM_ERROR_LOGFUNC(_Fmt...) -+#define RLM_WARN_LOGFUNC(_Fmt...) -+#define RLM_INFO_LOGFUNC(_Fmt...) -+#define RLM_STATE_LOGFUNC(_Fmt...) -+#define RLM_EVENT_LOGFUNC(_Fmt...) -+#define RLM_TRACE_LOGFUNC(_Fmt...) -+#define RLM_LOUD_LOGFUNC(_Fmt...) -+#define RLM_TEMP_LOGFUNC(_Fmt...) -+ -+#define MEM_ERROR_LOGFUNC(_Fmt...) -+#define MEM_WARN_LOGFUNC(_Fmt...) -+#define MEM_INFO_LOGFUNC(_Fmt...) -+#define MEM_STATE_LOGFUNC(_Fmt...) -+#define MEM_EVENT_LOGFUNC(_Fmt...) -+#define MEM_TRACE_LOGFUNC(_Fmt...) -+#define MEM_LOUD_LOGFUNC(_Fmt...) -+#define MEM_TEMP_LOGFUNC(_Fmt...) -+ -+#define CNM_ERROR_LOGFUNC(_Fmt...) kalPrint(_Fmt) -+#define CNM_WARN_LOGFUNC(_Fmt...) kalPrint(_Fmt) -+#define CNM_INFO_LOGFUNC(_Fmt...) kalPrint(_Fmt) -+#define CNM_STATE_LOGFUNC(_Fmt...) -+#define CNM_EVENT_LOGFUNC(_Fmt...) -+#define CNM_TRACE_LOGFUNC(_Fmt...) -+#define CNM_LOUD_LOGFUNC(_Fmt...) -+#define CNM_TEMP_LOGFUNC(_Fmt...) -+ -+#define RSN_ERROR_LOGFUNC(_Fmt...) -+#define RSN_WARN_LOGFUNC(_Fmt...) -+#define RSN_INFO_LOGFUNC(_Fmt...) -+#define RSN_STATE_LOGFUNC(_Fmt...) -+#define RSN_EVENT_LOGFUNC(_Fmt...) -+#define RSN_TRACE_LOGFUNC(_Fmt...) -+#define RSN_LOUD_LOGFUNC(_Fmt...) -+#define RSN_TEMP_LOGFUNC(_Fmt...) -+ -+#define BSS_ERROR_LOGFUNC(_Fmt...) -+#define BSS_WARN_LOGFUNC(_Fmt...) -+#define BSS_INFO_LOGFUNC(_Fmt...) -+#define BSS_STATE_LOGFUNC(_Fmt...) -+#define BSS_EVENT_LOGFUNC(_Fmt...) -+#define BSS_TRACE_LOGFUNC(_Fmt...) -+#define BSS_LOUD_LOGFUNC(_Fmt...) -+#define BSS_TEMP_LOGFUNC(_Fmt...) -+ -+#define SCN_ERROR_LOGFUNC(_Fmt...) -+#define SCN_WARN_LOGFUNC(_Fmt...) -+#define SCN_INFO_LOGFUNC(_Fmt...) -+#define SCN_STATE_LOGFUNC(_Fmt...) -+#define SCN_EVENT_LOGFUNC(_Fmt...) -+#define SCN_TRACE_LOGFUNC(_Fmt...) -+#define SCN_LOUD_LOGFUNC(_Fmt...) -+#define SCN_TEMP_LOGFUNC(_Fmt...) -+ -+#define SAA_ERROR_LOGFUNC(_Fmt...) -+#define SAA_WARN_LOGFUNC(_Fmt...) -+#define SAA_INFO_LOGFUNC(_Fmt...) -+#define SAA_STATE_LOGFUNC(_Fmt...) -+#define SAA_EVENT_LOGFUNC(_Fmt...) -+#define SAA_TRACE_LOGFUNC(_Fmt...) -+#define SAA_LOUD_LOGFUNC(_Fmt...) -+#define SAA_TEMP_LOGFUNC(_Fmt...) -+ -+#define P2P_ERROR_LOGFUNC(_Fmt...) -+#define P2P_WARN_LOGFUNC(_Fmt...) -+#define P2P_INFO_LOGFUNC(_Fmt...) -+#define P2P_STATE_LOGFUNC(_Fmt...) -+#define P2P_EVENT_LOGFUNC(_Fmt...) -+#define P2P_TRACE_LOGFUNC(_Fmt...) -+#define P2P_LOUD_LOGFUNC(_Fmt...) -+#define P2P_TEMP_LOGFUNC(_Fmt...) -+ -+#define QM_ERROR_LOGFUNC(_Fmt...) kalPrint(_Fmt) -+#define QM_WARN_LOGFUNC(_Fmt...) kalPrint(_Fmt) -+#define QM_INFO_LOGFUNC(_Fmt...) kalPrint(_Fmt) -+#define QM_STATE_LOGFUNC(_Fmt...) -+#define QM_EVENT_LOGFUNC(_Fmt...) -+#define QM_TRACE_LOGFUNC(_Fmt...) kalPrint(_Fmt) -+#define QM_LOUD_LOGFUNC(_Fmt...) -+#define QM_TEMP_LOGFUNC(_Fmt...) -+ -+#define SEC_ERROR_LOGFUNC(_Fmt...) -+#define SEC_WARN_LOGFUNC(_Fmt...) -+#define SEC_INFO_LOGFUNC(_Fmt...) -+#define SEC_STATE_LOGFUNC(_Fmt...) -+#define SEC_EVENT_LOGFUNC(_Fmt...) -+#define SEC_TRACE_LOGFUNC(_Fmt...) -+#define SEC_LOUD_LOGFUNC(_Fmt...) -+#define SEC_TEMP_LOGFUNC(_Fmt...) -+ -+#define BOW_ERROR_LOGFUNC(_Fmt...) -+#define BOW_WARN_LOGFUNC(_Fmt...) -+#define BOW_INFO_LOGFUNC(_Fmt...) -+#define BOW_STATE_LOGFUNC(_Fmt...) -+#define BOW_EVENT_LOGFUNC(_Fmt...) -+#define BOW_TRACE_LOGFUNC(_Fmt...) -+#define BOW_LOUD_LOGFUNC(_Fmt...) -+#define BOW_TEMP_LOGFUNC(_Fmt...) -+ -+#define HAL_ERROR_LOGFUNC(_Fmt...) kalPrint(_Fmt) -+#define HAL_WARN_LOGFUNC(_Fmt...) -+#define HAL_INFO_LOGFUNC(_Fmt...) -+#define HAL_STATE_LOGFUNC(_Fmt...) -+#define HAL_EVENT_LOGFUNC(_Fmt...) -+#define HAL_TRACE_LOGFUNC(_Fmt...) -+#define HAL_LOUD_LOGFUNC(_Fmt...) -+#define HAL_TEMP_LOGFUNC(_Fmt...) -+ -+#define WAPI_ERROR_LOGFUNC(_Fmt...) -+#define WAPI_WARN_LOGFUNC(_Fmt...) -+#define WAPI_INFO_LOGFUNC(_Fmt...) -+#define WAPI_STATE_LOGFUNC(_Fmt...) -+#define WAPI_EVENT_LOGFUNC(_Fmt...) -+#define WAPI_TRACE_LOGFUNC(_Fmt...) -+#define WAPI_LOUD_LOGFUNC(_Fmt...) -+#define WAPI_TEMP_LOGFUNC(_Fmt...) -+ -+#define TDLS_ERROR_LOGFUNC(_Fmt...) kalPrint(_Fmt) -+#define TDLS_WARN_LOGFUNC(_Fmt...) kalPrint(_Fmt) -+#define TDLS_INFO_LOGFUNC(_Fmt...) kalPrint(_Fmt) -+#define TDLS_STATE_LOGFUNC(_Fmt...) -+#define TDLS_EVENT_LOGFUNC(_Fmt...) -+#define TDLS_TRACE_LOGFUNC(_Fmt...) -+#define TDLS_LOUD_LOGFUNC(_Fmt...) -+#define TDLS_TEMP_LOGFUNC(_Fmt...) -+ -+#define SW1_ERROR_LOGFUNC(_Fmt...) -+#define SW1_WARN_LOGFUNC(_Fmt...) -+#define SW1_INFO_LOGFUNC(_Fmt...) -+#define SW1_STATE_LOGFUNC(_Fmt...) -+#define SW1_EVENT_LOGFUNC(_Fmt...) -+#define SW1_TRACE_LOGFUNC(_Fmt...) -+#define SW1_LOUD_LOGFUNC(_Fmt...) -+#define SW1_TEMP_LOGFUNC(_Fmt...) -+ -+#define SW2_ERROR_LOGFUNC(_Fmt...) -+#define SW2_WARN_LOGFUNC(_Fmt...) -+#define SW2_INFO_LOGFUNC(_Fmt...) -+#define SW2_STATE_LOGFUNC(_Fmt...) -+#define SW2_EVENT_LOGFUNC(_Fmt...) -+#define SW2_TRACE_LOGFUNC(_Fmt...) -+#define SW2_LOUD_LOGFUNC(_Fmt...) -+#define SW2_TEMP_LOGFUNC(_Fmt...) -+ -+#define SW3_ERROR_LOGFUNC(_Fmt...) -+#define SW3_WARN_LOGFUNC(_Fmt...) -+#define SW3_INFO_LOGFUNC(_Fmt...) -+#define SW3_STATE_LOGFUNC(_Fmt...) -+#define SW3_EVENT_LOGFUNC(_Fmt...) -+#define SW3_TRACE_LOGFUNC(_Fmt...) -+#define SW3_LOUD_LOGFUNC(_Fmt...) -+#define SW3_TEMP_LOGFUNC(_Fmt...) -+ -+#define SW4_ERROR_LOGFUNC(_Fmt...) -+#define SW4_WARN_LOGFUNC(_Fmt...) -+#define SW4_INFO_LOGFUNC(_Fmt...) -+#define SW4_STATE_LOGFUNC(_Fmt...) -+#define SW4_EVENT_LOGFUNC(_Fmt...) -+#define SW4_TRACE_LOGFUNC(_Fmt...) -+#define SW4_LOUD_LOGFUNC(_Fmt...) -+#define SW4_TEMP_LOGFUNC(_Fmt...) -+#endif -+ -+#define kalBreakPoint() \ -+do { \ -+ BUG(); \ -+ panic("Oops"); \ -+} while (0) -+ -+#if CFG_ENABLE_AEE_MSG -+#define kalSendAeeException aee_kernel_exception -+#define kalSendAeeWarning aee_kernel_warning -+#define kalSendAeeReminding aee_kernel_reminding -+#else -+#define kalSendAeeException(_module, _desc, ...) -+#define kalSendAeeWarning(_module, _desc, ...) -+#define kalSendAeeReminding(_module, _desc, ...) -+#endif -+ -+#define PRINTF_ARG(...) __VA_ARGS__ -+#define SPRINTF(buf, arg) {buf += sprintf((char *)(buf), PRINTF_ARG arg); } -+ -+#define USEC_TO_SYSTIME(_usec) ((_usec) / USEC_PER_MSEC) -+#define MSEC_TO_SYSTIME(_msec) (_msec) -+ -+#define MSEC_TO_JIFFIES(_msec) msecs_to_jiffies(_msec) -+ -+#define KAL_HALT_LOCK_TIMEOUT_NORMAL_CASE 3000 /* 3s */ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+/*----------------------------------------------------------------------------*/ -+/* Routines in gl_kal.c */ -+/*----------------------------------------------------------------------------*/ -+VOID -+kalAcquireSpinLock(IN P_GLUE_INFO_T prGlueInfo, -+ IN ENUM_SPIN_LOCK_CATEGORY_E rLockCategory, OUT unsigned long *pu4Flags); -+ -+VOID kalReleaseSpinLock(IN P_GLUE_INFO_T prGlueInfo, IN ENUM_SPIN_LOCK_CATEGORY_E rLockCategory, IN UINT_32 u4Flags); -+ -+VOID kalUpdateMACAddress(IN P_GLUE_INFO_T prGlueInfo, IN PUINT_8 pucMacAddr); -+ -+VOID kalPacketFree(IN P_GLUE_INFO_T prGlueInfo, IN PVOID pvPacket); -+ -+PVOID kalPacketAlloc(IN P_GLUE_INFO_T prGlueInfo, IN UINT_32 u4Size, OUT PUINT_8 *ppucData); -+ -+VOID kalOsTimerInitialize(IN P_GLUE_INFO_T prGlueInfo, IN PVOID prTimerHandler); -+ -+BOOLEAN kalSetTimer(IN P_GLUE_INFO_T prGlueInfo, IN OS_SYSTIME rInterval); -+ -+WLAN_STATUS -+kalProcessRxPacket(IN P_GLUE_INFO_T prGlueInfo, IN PVOID pvPacket, IN PUINT_8 pucPacketStart, IN UINT_32 u4PacketLen, -+ /* IN PBOOLEAN pfgIsRetain, */ -+ IN BOOLEAN fgIsRetain, IN ENUM_CSUM_RESULT_T aeCSUM[] -+); -+ -+WLAN_STATUS kalRxIndicatePkts(IN P_GLUE_INFO_T prGlueInfo, IN PVOID apvPkts[], IN UINT_8 ucPktNum); -+ -+VOID -+kalIndicateStatusAndComplete(IN P_GLUE_INFO_T prGlueInfo, IN WLAN_STATUS eStatus, IN PVOID pvBuf, IN UINT_32 u4BufLen); -+ -+VOID -+kalUpdateReAssocReqInfo(IN P_GLUE_INFO_T prGlueInfo, -+ IN PUINT_8 pucFrameBody, IN UINT_32 u4FrameBodyLen, IN BOOLEAN fgReassocRequest); -+ -+VOID kalUpdateReAssocRspInfo(IN P_GLUE_INFO_T prGlueInfo, IN PUINT_8 pucFrameBody, IN UINT_32 u4FrameBodyLen); -+ -+#if CFG_TX_FRAGMENT -+BOOLEAN -+kalQueryTxPacketHeader(IN P_GLUE_INFO_T prGlueInfo, -+ IN PVOID pvPacket, OUT PUINT_16 pu2EtherTypeLen, OUT PUINT_8 pucEthDestAddr); -+#endif /* CFG_TX_FRAGMENT */ -+ -+VOID kalSendCompleteAndAwakeQueue(IN P_GLUE_INFO_T prGlueInfo, IN PVOID pvPacket); -+ -+#if CFG_TCP_IP_CHKSUM_OFFLOAD -+VOID kalQueryTxChksumOffloadParam(IN PVOID pvPacket, OUT PUINT_8 pucFlag); -+ -+VOID kalUpdateRxCSUMOffloadParam(IN PVOID pvPacket, IN ENUM_CSUM_RESULT_T eCSUM[] -+); -+#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */ -+ -+BOOLEAN kalRetrieveNetworkAddress(IN P_GLUE_INFO_T prGlueInfo, IN OUT PARAM_MAC_ADDRESS *prMacAddr); -+ -+VOID -+kalReadyOnChannel(IN P_GLUE_INFO_T prGlueInfo, -+ IN UINT_64 u8Cookie, -+ IN ENUM_BAND_T eBand, IN ENUM_CHNL_EXT_T eSco, IN UINT_8 ucChannelNum, IN UINT_32 u4DurationMs); -+ -+VOID -+kalRemainOnChannelExpired(IN P_GLUE_INFO_T prGlueInfo, -+ IN UINT_64 u8Cookie, IN ENUM_BAND_T eBand, IN ENUM_CHNL_EXT_T eSco, IN UINT_8 ucChannelNum); -+ -+VOID -+kalIndicateMgmtTxStatus(IN P_GLUE_INFO_T prGlueInfo, -+ IN UINT_64 u8Cookie, IN BOOLEAN fgIsAck, IN PUINT_8 pucFrameBuf, IN UINT_32 u4FrameLen); -+ -+VOID kalIndicateRxMgmtFrame(IN P_GLUE_INFO_T prGlueInfo, IN P_SW_RFB_T prSwRfb); -+ -+/*----------------------------------------------------------------------------*/ -+/* Routines in interface - ehpi/sdio.c */ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN kalDevRegRead(IN P_GLUE_INFO_T prGlueInfo, IN UINT_32 u4Register, OUT PUINT_32 pu4Value); -+ -+BOOLEAN kalDevRegWrite(P_GLUE_INFO_T prGlueInfo, IN UINT_32 u4Register, IN UINT_32 u4Value); -+ -+BOOLEAN -+kalDevPortRead(IN P_GLUE_INFO_T prGlueInfo, -+ IN UINT_16 u2Port, IN UINT_32 u2Len, OUT PUINT_8 pucBuf, IN UINT_32 u2ValidOutBufSize); -+ -+BOOLEAN -+kalDevPortWrite(P_GLUE_INFO_T prGlueInfo, -+ IN UINT_16 u2Port, IN UINT_32 u2Len, IN PUINT_8 pucBuf, IN UINT_32 u2ValidInBufSize); -+ -+BOOLEAN kalDevWriteWithSdioCmd52(IN P_GLUE_INFO_T prGlueInfo, IN UINT_32 u4Addr, IN UINT_8 ucData); -+ -+void kalDevLoopbkAuto(IN GLUE_INFO_T *GlueInfo); -+ -+#if CFG_SUPPORT_EXT_CONFIG -+UINT_32 kalReadExtCfg(IN P_GLUE_INFO_T prGlueInfo); -+#endif -+ -+BOOLEAN -+kalQoSFrameClassifierAndPacketInfo(IN P_GLUE_INFO_T prGlueInfo, -+ IN P_NATIVE_PACKET prPacket, -+ OUT PUINT_8 pucPriorityParam, -+ OUT PUINT_32 pu4PacketLen, -+ OUT PUINT_8 pucEthDestAddr, -+ OUT PBOOLEAN pfgIs1X, -+ OUT PBOOLEAN pfgIsPAL, OUT PUINT_8 pucNetworkType, -+ OUT PVOID prGenUse); -+ -+VOID -+kalOidComplete(IN P_GLUE_INFO_T prGlueInfo, -+ IN BOOLEAN fgSetQuery, IN UINT_32 u4SetQueryInfoLen, IN WLAN_STATUS rOidStatus); -+ -+WLAN_STATUS -+kalIoctl(IN P_GLUE_INFO_T prGlueInfo, -+ IN PFN_OID_HANDLER_FUNC pfnOidHandler, -+ IN PVOID pvInfoBuf, -+ IN UINT_32 u4InfoBufLen, -+ IN BOOLEAN fgRead, IN BOOLEAN fgWaitResp, IN BOOLEAN fgCmd, IN BOOLEAN fgIsP2pOid, OUT PUINT_32 pu4QryInfoLen); -+ -+VOID kalHandleAssocInfo(IN P_GLUE_INFO_T prGlueInfo, IN P_EVENT_ASSOC_INFO prAssocInfo); -+ -+#if CFG_ENABLE_FW_DOWNLOAD -+ -+PVOID kalFirmwareImageMapping(IN P_GLUE_INFO_T prGlueInfo, OUT PPVOID ppvMapFileBuf, OUT PUINT_32 pu4FileLength); -+ -+VOID kalFirmwareImageUnmapping(IN P_GLUE_INFO_T prGlueInfo, IN PVOID prFwHandle, IN PVOID pvMapFileBuf); -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/* Card Removal Check */ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN kalIsCardRemoved(IN P_GLUE_INFO_T prGlueInfo); -+ -+/*----------------------------------------------------------------------------*/ -+/* TX */ -+/*----------------------------------------------------------------------------*/ -+VOID kalFlushPendingTxPackets(IN P_GLUE_INFO_T prGlueInfo); -+ -+/*----------------------------------------------------------------------------*/ -+/* Media State Indication */ -+/*----------------------------------------------------------------------------*/ -+ENUM_PARAM_MEDIA_STATE_T kalGetMediaStateIndicated(IN P_GLUE_INFO_T prGlueInfo); -+ -+VOID kalSetMediaStateIndicated(IN P_GLUE_INFO_T prGlueInfo, IN ENUM_PARAM_MEDIA_STATE_T eParamMediaStateIndicate); -+ -+/*----------------------------------------------------------------------------*/ -+/* OID handling */ -+/*----------------------------------------------------------------------------*/ -+VOID kalOidCmdClearance(IN P_GLUE_INFO_T prGlueInfo); -+ -+VOID kalOidClearance(IN P_GLUE_INFO_T prGlueInfo); -+ -+VOID kalEnqueueCommand(IN P_GLUE_INFO_T prGlueInfo, IN P_QUE_ENTRY_T prQueueEntry); -+ -+#if CFG_ENABLE_BT_OVER_WIFI -+/*----------------------------------------------------------------------------*/ -+/* Bluetooth over Wi-Fi handling */ -+/*----------------------------------------------------------------------------*/ -+VOID kalIndicateBOWEvent(IN P_GLUE_INFO_T prGlueInfo, IN P_AMPC_EVENT prEvent); -+ -+ENUM_BOW_DEVICE_STATE kalGetBowState(IN P_GLUE_INFO_T prGlueInfo, IN PARAM_MAC_ADDRESS rPeerAddr); -+ -+BOOLEAN kalSetBowState(IN P_GLUE_INFO_T prGlueInfo, IN ENUM_BOW_DEVICE_STATE eBowState, PARAM_MAC_ADDRESS rPeerAddr); -+ -+ENUM_BOW_DEVICE_STATE kalGetBowGlobalState(IN P_GLUE_INFO_T prGlueInfo); -+ -+UINT_32 kalGetBowFreqInKHz(IN P_GLUE_INFO_T prGlueInfo); -+ -+UINT_8 kalGetBowRole(IN P_GLUE_INFO_T prGlueInfo, IN PARAM_MAC_ADDRESS rPeerAddr); -+ -+VOID kalSetBowRole(IN P_GLUE_INFO_T prGlueInfo, IN UINT_8 ucRole, IN PARAM_MAC_ADDRESS rPeerAddr); -+ -+UINT_8 kalGetBowAvailablePhysicalLinkCount(IN P_GLUE_INFO_T prGlueInfo); -+ -+#if CFG_BOW_SEPARATE_DATA_PATH -+/*----------------------------------------------------------------------------*/ -+/* Bluetooth over Wi-Fi Net Device Init/Uninit */ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN kalInitBowDevice(IN P_GLUE_INFO_T prGlueInfo, IN const char *prDevName); -+ -+BOOLEAN kalUninitBowDevice(IN P_GLUE_INFO_T prGlueInfo); -+#endif /* CFG_BOW_SEPARATE_DATA_PATH */ -+#endif /* CFG_ENABLE_BT_OVER_WIFI */ -+ -+/*----------------------------------------------------------------------------*/ -+/* Firmware Download Handling */ -+/*----------------------------------------------------------------------------*/ -+UINT_32 kalGetFwStartAddress(IN P_GLUE_INFO_T prGlueInfo); -+ -+UINT_32 kalGetFwLoadAddress(IN P_GLUE_INFO_T prGlueInfo); -+ -+/*----------------------------------------------------------------------------*/ -+/* Security Frame Clearance */ -+/*----------------------------------------------------------------------------*/ -+VOID kalClearSecurityFrames(IN P_GLUE_INFO_T prGlueInfo); -+ -+VOID kalClearSecurityFramesByNetType(IN P_GLUE_INFO_T prGlueInfo, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx); -+ -+VOID kalSecurityFrameSendComplete(IN P_GLUE_INFO_T prGlueInfo, IN PVOID pvPacket, IN WLAN_STATUS rStatus); -+ -+/*----------------------------------------------------------------------------*/ -+/* Management Frame Clearance */ -+/*----------------------------------------------------------------------------*/ -+VOID kalClearMgmtFrames(IN P_GLUE_INFO_T prGlueInfo); -+ -+VOID kalClearMgmtFramesByNetType(IN P_GLUE_INFO_T prGlueInfo, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx); -+ -+UINT_32 kalGetTxPendingFrameCount(IN P_GLUE_INFO_T prGlueInfo); -+ -+UINT_32 kalGetTxPendingCmdCount(IN P_GLUE_INFO_T prGlueInfo); -+ -+BOOLEAN kalSetTimer(IN P_GLUE_INFO_T prGlueInfo, IN UINT_32 u4Interval); -+ -+BOOLEAN kalCancelTimer(IN P_GLUE_INFO_T prGlueInfo); -+ -+VOID kalScanDone(IN P_GLUE_INFO_T prGlueInfo, IN ENUM_KAL_NETWORK_TYPE_INDEX_T eNetTypeIdx, IN WLAN_STATUS status); -+ -+UINT_32 kalRandomNumber(VOID); -+ -+VOID kalTimeoutHandler(ULONG arg); -+ -+VOID kalSetEvent(P_GLUE_INFO_T pr); -+ -+/*----------------------------------------------------------------------------*/ -+/* NVRAM/Registry Service */ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN kalIsConfigurationExist(IN P_GLUE_INFO_T prGlueInfo); -+ -+P_REG_INFO_T kalGetConfiguration(IN P_GLUE_INFO_T prGlueInfo); -+ -+VOID -+kalGetConfigurationVersion(IN P_GLUE_INFO_T prGlueInfo, -+ OUT PUINT_16 pu2Part1CfgOwnVersion, -+ OUT PUINT_16 pu2Part1CfgPeerVersion, -+ OUT PUINT_16 pu2Part2CfgOwnVersion, OUT PUINT_16 pu2Part2CfgPeerVersion); -+ -+BOOLEAN kalCfgDataRead16(IN P_GLUE_INFO_T prGlueInfo, IN UINT_32 u4Offset, OUT PUINT_16 pu2Data); -+ -+BOOLEAN kalCfgDataWrite16(IN P_GLUE_INFO_T prGlueInfo, IN UINT_32 u4Offset, IN UINT_16 u2Data); -+ -+/*----------------------------------------------------------------------------*/ -+/* WSC Connection */ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN kalWSCGetActiveState(IN P_GLUE_INFO_T prGlueInfo); -+ -+/*----------------------------------------------------------------------------*/ -+/* RSSI Updating */ -+/*----------------------------------------------------------------------------*/ -+VOID -+kalUpdateRSSI(IN P_GLUE_INFO_T prGlueInfo, -+ IN ENUM_KAL_NETWORK_TYPE_INDEX_T eNetTypeIdx, IN INT_8 cRssi, IN INT_8 cLinkQuality); -+ -+/*----------------------------------------------------------------------------*/ -+/* I/O Buffer Pre-allocation */ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN kalInitIOBuffer(VOID); -+ -+VOID kalUninitIOBuffer(VOID); -+ -+PVOID kalAllocateIOBuffer(IN UINT_32 u4AllocSize); -+ -+VOID kalReleaseIOBuffer(IN PVOID pvAddr, IN UINT_32 u4Size); -+ -+VOID -+kalGetChannelList(IN P_GLUE_INFO_T prGlueInfo, -+ IN ENUM_BAND_T eSpecificBand, -+ IN UINT_8 ucMaxChannelNum, IN PUINT_8 pucNumOfChannel, IN P_RF_CHANNEL_INFO_T paucChannelList); -+ -+BOOLEAN kalIsAPmode(IN P_GLUE_INFO_T prGlueInfo); -+ -+ULONG kalIOPhyAddrGet(IN ULONG VirtAddr); -+ -+VOID kalDmaBufGet(OUT VOID **VirtAddr, OUT VOID **PhyAddr); -+ -+#if CFG_SUPPORT_802_11W -+/*----------------------------------------------------------------------------*/ -+/* 802.11W */ -+/*----------------------------------------------------------------------------*/ -+UINT_32 kalGetMfpSetting(IN P_GLUE_INFO_T prGlueInfo); -+#endif -+ -+UINT_32 kalWriteToFile(const PUINT_8 pucPath, BOOLEAN fgDoAppend, PUINT_8 pucData, UINT_32 u4Size); -+ -+/*----------------------------------------------------------------------------*/ -+/* NL80211 */ -+/*----------------------------------------------------------------------------*/ -+VOID -+kalIndicateBssInfo(IN P_GLUE_INFO_T prGlueInfo, -+ IN PUINT_8 pucFrameBuf, IN UINT_32 u4BufLen, IN UINT_8 ucChannelNum, IN INT_32 i4SignalStrength); -+ -+/*----------------------------------------------------------------------------*/ -+/* PNO Support */ -+/*----------------------------------------------------------------------------*/ -+VOID kalSchedScanResults(IN P_GLUE_INFO_T prGlueInfo); -+ -+VOID kalSchedScanStopped(IN P_GLUE_INFO_T prGlueInfo); -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+int tx_thread(void *data); -+ -+VOID kalHifAhbKalWakeLockTimeout(IN P_GLUE_INFO_T prGlueInfo); -+VOID kalMetProfilingStart(IN P_GLUE_INFO_T prGlueInfo, IN struct sk_buff *prSkb); -+VOID kalMetProfilingFinish(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); -+int kalMetInitProcfs(IN P_GLUE_INFO_T prGlueInfo); -+int kalMetRemoveProcfs(void); -+ -+UINT_64 kalGetBootTime(void); -+ -+INT_32 kalReadToFile(const PUINT_8 pucPath, PUINT_8 pucData, UINT_32 u4Size, PUINT_32 pu4ReadSize); -+#if CFG_SUPPORT_WAKEUP_REASON_DEBUG -+BOOLEAN kalIsWakeupByWlan(P_ADAPTER_T prAdapter); -+#endif -+INT_32 kalHaltLock(UINT_32 waitMs); -+INT_32 kalHaltTryLock(VOID); -+VOID kalHaltUnlock(VOID); -+VOID kalSetHalted(BOOLEAN fgHalt); -+BOOLEAN kalIsHalted(VOID); -+ -+INT32 kalPerMonInit(IN P_GLUE_INFO_T prGlueInfo); -+INT32 kalPerMonDisable(IN P_GLUE_INFO_T prGlueInfo); -+INT32 kalPerMonEnable(IN P_GLUE_INFO_T prGlueInfo); -+INT32 kalPerMonStart(IN P_GLUE_INFO_T prGlueInfo); -+INT32 kalPerMonStop(IN P_GLUE_INFO_T prGlueInfo); -+INT32 kalPerMonDestroy(IN P_GLUE_INFO_T prGlueInfo); -+VOID kalPerMonHandler(IN P_ADAPTER_T prAdapter, ULONG ulParam); -+INT32 kalBoostCpu(UINT_32 core_num); -+ -+#endif /* _GL_KAL_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_os.h b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_os.h -new file mode 100644 -index 000000000000..a4321e7f9a11 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_os.h -@@ -0,0 +1,1270 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux/include/gl_os.h#2 -+*/ -+ -+/*! \file gl_os.h -+ \brief List the external reference to OS for GLUE Layer. -+ -+ In this file we define the data structure - GLUE_INFO_T to store those objects -+ we acquired from OS - e.g. TIMER, SPINLOCK, NET DEVICE ... . And all the -+ external reference (header file, extern func() ..) to OS for GLUE Layer should -+ also list down here. -+*/ -+ -+/* -+** Log: gl_os.h -+** -+** 08 20 2012 yuche.tsai -+** NULL -+** Fix possible KE issue. -+** -+** 08 20 2012 yuche.tsai -+** [ALPS00339327] [Rose][6575JB][BSP Package][Free Test][KE][WIFI]There is no response when you tap the turn off/on -+** button,wait a minutes, the device will reboot automatically and "KE" will pop up. -+** Fix possible KE when netlink operate mgmt frame register. -+ * -+ * 04 12 2012 terry.wu -+ * NULL -+ * Add AEE message support -+ * 1) Show AEE warning(red screen) if SDIO access error occurs -+ -+ * -+ * 03 02 2012 terry.wu -+ * NULL -+ * Enable CFG80211 Support. -+ * -+ * 01 05 2012 wh.su -+ * [WCXRP00001153] [MT6620 Wi-Fi][Driver] Adding the get_ch_list and set_tx_power proto type function -+ * Adding the related ioctl / wlan oid function to set the Tx power cfg. -+ * -+ * 12 13 2011 cm.chang -+ * [WCXRP00001136] [All Wi-Fi][Driver] Add wake lock for pending timer -+ * Add wake lock if timer timeout value is smaller than 5 seconds -+ * -+ * 11 18 2011 yuche.tsai -+ * NULL -+ * CONFIG P2P support RSSI query, default turned off. -+ * -+ * 11 16 2011 yuche.tsai -+ * NULL -+ * Avoid using work thread. -+ * -+ * 11 11 2011 yuche.tsai -+ * NULL -+ * Fix work thread cancel issue. -+ * -+ * 10 12 2011 wh.su -+ * [WCXRP00001036] [MT6620 Wi-Fi][Driver][FW] Adding the 802.11w code for MFP -+ * adding the 802.11w related function and define . -+ * -+ * 09 29 2011 terry.wu -+ * NULL -+ * Show DRV_NAME by chip id. -+ * -+ * 04 18 2011 terry.wu -+ * [WCXRP00000660] [MT6620 Wi-Fi][Driver] Remove flag CFG_WIFI_DIRECT_MOVED -+ * Remove flag CFG_WIFI_DIRECT_MOVED. -+ * -+ * 03 29 2011 cp.wu -+ * [WCXRP00000598] [MT6620 Wi-Fi][Driver] Implementation of interface for communicating with user space process for -+ * RESET_START and RESET_END events -+ * implement kernel-to-userspace communication via generic netlink socket for whole-chip resetting mechanism -+ * -+ * 03 21 2011 cp.wu -+ * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer -+ * portability improvement -+ * -+ * 03 17 2011 chinglan.wang -+ * [WCXRP00000570] [MT6620 Wi-Fi][Driver] Add Wi-Fi Protected Setup v2.0 feature -+ * . -+ * -+ * 03 03 2011 jeffrey.chang -+ * [WCXRP00000512] [MT6620 Wi-Fi][Driver] modify the net device relative functions to support the H/W multiple queue -+ * support concurrent network -+ * -+ * 03 03 2011 jeffrey.chang -+ * [WCXRP00000512] [MT6620 Wi-Fi][Driver] modify the net device relative functions to support the H/W multiple queue -+ * modify net device relative functions to support multiple H/W queues -+ * -+ * 03 02 2011 wh.su -+ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code -+ * Add security check code. -+ * -+ * 02 21 2011 cp.wu -+ * [WCXRP00000482] [MT6620 Wi-Fi][Driver] Simplify logic for checking NVRAM existence in driver domain -+ * simplify logic for checking NVRAM existence only once. -+ * -+ * 02 16 2011 jeffrey.chang -+ * NULL -+ * Add query ipv4 and ipv6 address during early suspend and late resume -+ * -+ * 02 10 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Fix kernel API change issue. -+ * Before ALPS 2.2 (2.2 included), kfifo_alloc() is -+ * struct kfifo *kfifo_alloc(unsigned int size, gfp_t gfp_mask, spinlock_t *lock); -+ * After ALPS 2.3, kfifo_alloc() is changed to -+ * int kfifo_alloc(struct kfifo *fifo, unsigned int size, gfp_t gfp_mask); -+ * -+ * 02 09 2011 wh.su -+ * [WCXRP00000433] [MT6620 Wi-Fi][Driver] Remove WAPI structure define for avoid P2P module with structure miss-align -+ * pointer issue -+ * always pre-allio WAPI related structure for align p2p module. -+ * -+ * 02 09 2011 terry.wu -+ * [WCXRP00000383] [MT6620 Wi-Fi][Driver] Separate WiFi and P2P driver into two modules -+ * Halt p2p module init and exit until TxThread finished p2p register and unregister. -+ * -+ * 02 01 2011 cm.chang -+ * [WCXRP00000415] [MT6620 Wi-Fi][Driver] Check if any memory leakage happens when uninitializing in DGB mode -+ * . -+ * -+ * 01 27 2011 cm.chang -+ * [WCXRP00000402] [MT6620 Wi-Fi][Driver] Enable MCR read/write by iwpriv by default -+ * . -+ * -+ * 01 12 2011 cp.wu -+ * [WCXRP00000357] [MT6620 Wi-Fi][Driver][Bluetooth over Wi-Fi] add another net device interface for BT AMP -+ * implementation of separate BT_OVER_WIFI data path. -+ * -+ * 01 12 2011 cp.wu -+ * [WCXRP00000356] [MT6620 Wi-Fi][Driver] fill mac header length for security frames 'cause hardware header translation -+ * needs such information -+ * fill mac header length information for 802.1x frames. -+ * -+ * 01 11 2011 chinglan.wang -+ * NULL -+ * Modify to reslove the CR :[ALPS00028994] Use WEP security to connect Marvell 11N AP. Connection establish -+ * successfully. -+ * Use the WPS function to connect AP, the privacy bit always is set to 1. -+ * -+ * 01 10 2011 cp.wu -+ * [WCXRP00000349] [MT6620 Wi-Fi][Driver] make kalIoctl() of linux port as a thread safe API to avoid potential issues -+ * due to multiple access -+ * use mutex to protect kalIoctl() for thread safe. -+ * -+ * 01 05 2011 cp.wu -+ * [WCXRP00000283] [MT6620 Wi-Fi][Driver][Wi-Fi Direct] Implementation of interface for supporting Wi-Fi Direct Service -+ * Discovery -+ * ioctl implementations for P2P Service Discovery -+ * -+ * 11 04 2010 wh.su -+ * [WCXRP00000164] [MT6620 Wi-Fi][Driver] Support the p2p random SSID -+ * adding the p2p random ssid support. -+ * -+ * 10 18 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000086] [MT6620 Wi-Fi][Driver] -+ * The mac address is all zero at android -+ * complete implementation of Android NVRAM access -+ * -+ * 09 28 2010 wh.su -+ * NULL -+ * [WCXRP00000069][MT6620 Wi-Fi][Driver] Fix some code for phase 1 P2P Demo. -+ * -+ * 09 23 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check -+ * add skeleton for NVRAM integration -+ * -+ * 09 13 2010 cp.wu -+ * NULL -+ * add waitq for poll() and read(). -+ * -+ * 09 07 2010 wh.su -+ * NULL -+ * adding the code for beacon/probe req/ probe rsp wsc ie at p2p. -+ * -+ * 09 06 2010 wh.su -+ * NULL -+ * let the p2p can set the privacy bit at beacon and rsn ie at assoc req at key handshake state. -+ * -+ * 09 03 2010 kevin.huang -+ * NULL -+ * Refine #include sequence and solve recursive/nested #include issue -+ * -+ * 09 01 2010 wh.su -+ * NULL -+ * adding the wapi support for integration test. -+ * -+ * 08 31 2010 kevin.huang -+ * NULL -+ * Use LINK LIST operation to process SCAN result -+ * -+ * 08 23 2010 cp.wu -+ * NULL -+ * revise constant definitions to be matched with implementation (original cmd-event definition is deprecated) -+ * -+ * 08 16 2010 cp.wu -+ * NULL -+ * P2P packets are now marked when being queued into driver, and identified later without checking MAC address -+ * -+ * 08 16 2010 cp.wu -+ * NULL -+ * revised implementation of Wi-Fi Direct io controls. -+ * -+ * 08 11 2010 cp.wu -+ * NULL -+ * 1) do not use in-stack variable for beacon updating. (for MAUI porting) -+ * 2) extending scanning result to 64 instead of 48 -+ * -+ * 08 06 2010 cp.wu -+ * NULL -+ * driver hook modifications corresponding to ioctl interface change. -+ * -+ * 08 03 2010 cp.wu -+ * NULL -+ * [Wi-Fi Direct] add framework for driver hooks -+ * -+ * 08 02 2010 jeffrey.chang -+ * NULL -+ * 1) modify tx service thread to avoid busy looping -+ * 2) add spin lock declartion for linux build -+ * -+ * 07 23 2010 jeffrey.chang -+ * -+ * add new KAL api -+ * -+ * 07 22 2010 jeffrey.chang -+ * -+ * modify tx thread and remove some spinlock -+ * -+ * 07 19 2010 jeffrey.chang -+ * -+ * add security frame pending count -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 06 01 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * add ioctl to configure scan mode for p2p connection -+ * -+ * 05 31 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * add cfg80211 interface, which is to replace WE, for further extension -+ * -+ * 05 14 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * add ioctl framework for Wi-Fi Direct by reusing wireless extension ioctls as well -+ * -+ * 05 11 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * p2p ioctls revised. -+ * -+ * 05 11 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * add ioctl for controlling p2p scan phase parameters -+ * -+ * 05 10 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * implement basic wi-fi direct framework -+ * -+ * 05 07 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * prevent supplicant accessing driver during resume -+ * -+ * 05 07 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * add basic framework for implementating P2P driver hook. -+ * -+ * 05 05 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * change variable names for multiple physical link to match with coding convention -+ * -+ * 04 27 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * identify BT Over Wi-Fi Security frame and mark it as 802.1X frame -+ * -+ * 04 27 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * add multiple physical link support -+ * -+ * 04 27 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * 1) fix firmware download bug -+ * 2) remove query statistics for acelerating firmware download -+ * -+ * 04 27 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * follow Linux's firmware framework, and remove unused kal API -+ * -+ * 04 23 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * surpress compiler warning -+ * -+ * 04 19 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * supporting power management -+ * -+ * 04 14 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * pvInformationBuffer and u4InformationBufferLength are no longer in glue -+ * -+ * 04 13 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * add framework for BT-over-Wi-Fi support. -+ * * * * * * * * * * * * * * * * * * * * 1) prPendingCmdInfo is replaced by queue for multiple -+ * * * * * * * * * * * * * * * * * * * * handler capability -+ * * * * * * * * * * * * * * * * * * * * 2) command sequence number is now increased atomically -+ * * * * * * * * * * * * * * * * * * * * 3) private data could be hold and taken use for other -+ * * * * * * * * * * * * * * * * * * * * purpose -+ * -+ * 04 07 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * rWlanInfo should be placed at adapter rather than glue due to most operations -+ * * * * * * * * * * are done in adapter layer. -+ * -+ * 04 06 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * Tag the packet for QoS on Tx path -+ * -+ * 04 06 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * (1)deliver the kalOidComplete status to upper layer -+ * * (2) fix spin lock -+ * -+ * 04 06 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * add timeout check in the kalOidComplete -+ * -+ * 04 06 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * improve none-glue code portability -+ * -+ * 04 06 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * code refine: fgTestMode should be at adapter rather than glue due to the device/fw is also involved -+ * -+ * 04 06 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * eliminate direct access for prGlueInfo->fgIsCardRemoved in non-glue layer -+ * -+ * 03 30 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * emulate NDIS Pending OID facility -+ * -+ * 03 26 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * [WPD00003826] Initial import for Linux port -+ * adding firmware download related data type -+ * -+ * 03 25 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) correct OID_802_11_CONFIGURATION with frequency setting behavior. -+ * * * * the frequency is used for adhoc connection only -+ * * * * 2) update with SD1 v0.9 CMD/EVENT documentation -+ * -+ * 03 25 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * add Bluetooth-over-Wifi frame header check -+ * -+ * 03 24 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * initial import for Linux port -+** \main\maintrunk.MT5921\30 2009-10-20 17:38:31 GMT mtk01090 -+** Refine driver unloading and clean up procedure. Block requests, stop main thread and clean up queued requests, -+** and then stop hw. -+** \main\maintrunk.MT5921\29 2009-10-08 10:33:33 GMT mtk01090 -+** Avoid accessing private data of net_device directly. Replace with netdev_priv(). Add more checking for input -+** parameters and pointers. -+** \main\maintrunk.MT5921\28 2009-09-28 20:19:26 GMT mtk01090 -+** Add private ioctl to carry OID structures. Restructure public/private ioctl interfaces to Linux kernel. -+** \main\maintrunk.MT5921\27 2009-08-18 22:57:12 GMT mtk01090 -+** Add Linux SDIO (with mmc core) support. -+** Add Linux 2.6.21, 2.6.25, 2.6.26. -+** Fix compile warning in Linux. -+** \main\maintrunk.MT5921\26 2009-07-06 21:42:25 GMT mtk01088 -+** fixed the compiling error at linux -+** \main\maintrunk.MT5921\25 2009-07-06 20:51:46 GMT mtk01088 -+** adding the wapi 1x ether type define -+** \main\maintrunk.MT5921\24 2009-06-23 23:19:18 GMT mtk01090 -+** Add build option BUILD_USE_EEPROM and compile option CFG_SUPPORT_EXT_CONFIG for NVRAM support -+** \main\maintrunk.MT5921\23 2009-02-07 15:05:06 GMT mtk01088 -+** add the privacy flag to ingo driver the supplicant selected ap's security -+** \main\maintrunk.MT5921\22 2009-02-05 15:34:09 GMT mtk01088 -+** fixed the compiling error for using bits marco for only one parameter -+** \main\maintrunk.MT5921\21 2009-01-22 13:02:13 GMT mtk01088 -+** data frame is or not 802.1x value share with tid, using the same reserved byte, provide the function to set and get -+** \main\maintrunk.MT5921\20 2008-10-24 12:04:16 GMT mtk01088 -+** move the config.h from precomp.h to here for lint check -+** \main\maintrunk.MT5921\19 2008-09-22 23:19:02 GMT mtk01461 -+** Update driver for code review -+** \main\maintrunk.MT5921\18 2008-09-05 17:25:13 GMT mtk01461 -+** Update Driver for Code Review -+** \main\maintrunk.MT5921\17 2008-08-01 13:32:47 GMT mtk01084 -+** Prevent redundent driver assertion in driver logic when BUS is detached -+** \main\maintrunk.MT5921\16 2008-05-30 14:41:43 GMT mtk01461 -+** Remove WMM Assoc Flag in KAL -+** \main\maintrunk.MT5921\15 2008-05-29 14:16:25 GMT mtk01084 -+** remoev un-used variable -+** \main\maintrunk.MT5921\14 2008-05-03 15:17:14 GMT mtk01461 -+** Add Media Status variable in Glue Layer -+** \main\maintrunk.MT5921\13 2008-04-24 11:58:41 GMT mtk01461 -+** change threshold to 256 -+** \main\maintrunk.MT5921\12 2008-03-11 14:51:05 GMT mtk01461 -+** Remove redundant GL_CONN_INFO_T -+** \main\maintrunk.MT5921\11 2008-01-07 15:07:41 GMT mtk01461 -+** Adjust the netif stop threshold to 150 -+** \main\maintrunk.MT5921\10 2007-11-26 19:43:46 GMT mtk01461 -+** Add OS_TIMESTAMP macro -+** -+** \main\maintrunk.MT5921\9 2007-11-07 18:38:38 GMT mtk01461 -+** Move definition -+** \main\maintrunk.MT5921\8 2007-11-02 01:04:00 GMT mtk01461 -+** Unify TX Path for Normal and IBSS Power Save + IBSS neighbor learning -+** Revision 1.5 2007/07/12 11:04:28 MTK01084 -+** update macro to delay for ms order -+** -+** Revision 1.4 2007/07/05 07:25:34 MTK01461 -+** Add Linux initial code, modify doc, add 11BB, RF init code -+** -+** Revision 1.3 2007/06/27 02:18:51 MTK01461 -+** Update SCAN_FSM, Initial(Can Load Module), Proc(Can do Reg R/W), TX API -+** -+** Revision 1.2 2007/06/25 06:16:24 MTK01461 -+** Update illustrations, gl_init.c, gl_kal.c, gl_kal.h, gl_os.h and RX API -+** -+*/ -+ -+#ifndef _GL_OS_H -+#define _GL_OS_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+/*------------------------------------------------------------------------------ -+ * Flags for LINUX(OS) dependent -+ *------------------------------------------------------------------------------ -+ */ -+#define CFG_MAX_WLAN_DEVICES 1 /* number of wlan card will coexist */ -+ -+#define CFG_MAX_TXQ_NUM 4 /* number of tx queue for support multi-queue h/w */ -+ -+#define CFG_USE_SPIN_LOCK_BOTTOM_HALF 0 /* 1: Enable use of SPIN LOCK Bottom Half for LINUX -+ 0: Disable - use SPIN LOCK IRQ SAVE instead */ -+ -+#define CFG_TX_PADDING_SMALL_ETH_PACKET 0 /* 1: Enable - Drop ethernet packet if it < 14 bytes. -+ And pad ethernet packet with dummy 0 if it < 60 bytes. -+ 0: Disable */ -+ -+#define CFG_TX_STOP_NETIF_QUEUE_THRESHOLD 256 /* packets */ -+ -+#define CFG_TX_STOP_NETIF_PER_QUEUE_THRESHOLD 256 /* packets */ -+#define CFG_TX_START_NETIF_PER_QUEUE_THRESHOLD 128 /* packets */ -+ -+#define ETH_P_1X 0x888E -+#define IPTOS_PREC_OFFSET 5 -+#define USER_PRIORITY_DEFAULT 0 -+ -+#define ETH_WPI_1X 0x88B4 -+ -+#define ETH_HLEN 14 -+#define ETH_TYPE_LEN_OFFSET 12 -+#define ETH_P_IP 0x0800 -+#define ETH_P_1X 0x888E -+#define ETH_P_PRE_1X 0x88C7 -+#define ETH_P_ARP 0x0806 -+ -+#define ARP_PRO_REQ 1 -+#define ARP_PRO_RSP 2 -+ -+#define IPVERSION 4 -+#define IP_HEADER_LEN 20 -+ -+#define IP_PRO_ICMP 0x01 -+#define IP_PRO_UDP 0x11 -+#define IP_PRO_TCP 0x06 -+ -+#define UDP_PORT_DHCPS 0x43 -+#define UDP_PORT_DHCPC 0x44 -+#define UDP_PORT_DNS 0x35 -+ -+#define IPVH_VERSION_OFFSET 4 /* For Little-Endian */ -+#define IPVH_VERSION_MASK 0xF0 -+#define IPTOS_PREC_OFFSET 5 -+#define IPTOS_PREC_MASK 0xE0 -+ -+#define SOURCE_PORT_LEN 2 -+/* NOTE(Kevin): Without IP Option Length */ -+#define LOOK_AHEAD_LEN (ETH_HLEN + IP_HEADER_LEN + SOURCE_PORT_LEN) -+ -+/* 802.2 LLC/SNAP */ -+#define ETH_LLC_OFFSET (ETH_HLEN) -+#define ETH_LLC_LEN 3 -+#define ETH_LLC_DSAP_SNAP 0xAA -+#define ETH_LLC_SSAP_SNAP 0xAA -+#define ETH_LLC_CONTROL_UNNUMBERED_INFORMATION 0x03 -+ -+/* Bluetooth SNAP */ -+#define ETH_SNAP_OFFSET (ETH_HLEN + ETH_LLC_LEN) -+#define ETH_SNAP_LEN 5 -+#define ETH_SNAP_BT_SIG_OUI_0 0x00 -+#define ETH_SNAP_BT_SIG_OUI_1 0x19 -+#define ETH_SNAP_BT_SIG_OUI_2 0x58 -+ -+#define BOW_PROTOCOL_ID_SECURITY_FRAME 0x0003 -+ -+#if defined(MT6620) -+#define CHIP_NAME "MT6620" -+#elif defined(MT6628) -+#define CHIP_NAME "MT6582" -+#endif -+ -+#define DRV_NAME "["CHIP_NAME"]: " -+ -+#define CONFIG_ANDROID 1 -+/* Define if target platform is Android. -+ * It should already be defined in Android kernel source -+ */ -+ -+/* for CFG80211 IE buffering mechanism */ -+#define CFG_CFG80211_IE_BUF_LEN (512) -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include /* constant of kernel version */ -+ -+#include /* bitops.h */ -+ -+#include /* struct timer_list */ -+#include /* jiffies */ -+#include /* udelay and mdelay macro */ -+ -+#if CONFIG_ANDROID -+#include -+#endif -+ -+#include /* IRQT_FALLING */ -+ -+#include /* struct net_device, struct net_device_stats */ -+#include /* for eth_type_trans() function */ -+#include /* struct iw_statistics */ -+#include -+#include /* struct in_device */ -+ -+#include /* struct iphdr */ -+ -+#include /* for memcpy()/memset() function */ -+#include /* for offsetof() macro */ -+ -+#include /* The proc filesystem constants/structures */ -+ -+#include /* for rtnl_lock() and rtnl_unlock() */ -+#include /* kthread_should_stop(), kthread_run() */ -+#include /* for copy_from_user() */ -+#include /* for firmware download */ -+#include -+ -+#include /* for kfifo interface */ -+#include /* for cdev interface */ -+ -+#include /* for firmware download */ -+ -+#if defined(_HIF_SDIO) -+#include -+#include -+#endif -+ -+#include -+ -+#include -+#include -+ -+#include /* readw and writew */ -+ -+#if WIRELESS_EXT > 12 -+#include -+#endif -+ -+#include "version.h" -+#include "config.h" -+ -+#if CFG_ENABLE_WIFI_DIRECT_CFG_80211 -+#include -+#include -+#endif -+ -+#include -+ -+#if CFG_SUPPORT_HOTSPOT_2_0 -+#include -+#endif -+ -+#include "gl_typedef.h" -+#include "typedef.h" -+#include "queue.h" -+#include "gl_kal.h" -+#include "hif.h" -+#if CFG_CHIP_RESET_SUPPORT -+#include "gl_rst.h" -+#endif -+ -+#if (CFG_SUPPORT_TDLS == 1) -+#include "tdls_extr.h" -+#endif -+#include "debug.h" -+ -+#include "wlan_lib.h" -+#include "wlan_oid.h" -+ -+#if CFG_ENABLE_AEE_MSG -+#include -+#endif -+ -+extern BOOLEAN fgIsBusAccessFailed; -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+#define GLUE_FLAG_HALT BIT(0) -+#define GLUE_FLAG_INT BIT(1) -+#define GLUE_FLAG_OID BIT(2) -+#define GLUE_FLAG_TIMEOUT BIT(3) -+#define GLUE_FLAG_TXREQ BIT(4) -+#define GLUE_FLAG_SUB_MOD_INIT BIT(5) -+#define GLUE_FLAG_SUB_MOD_EXIT BIT(6) -+#define GLUE_FLAG_SUB_MOD_MULTICAST BIT(7) -+#define GLUE_FLAG_FRAME_FILTER BIT(8) -+#define GLUE_FLAG_FRAME_FILTER_AIS BIT(9) -+#define GLUE_FLAG_HIF_LOOPBK_AUTO BIT(10) -+#define GLUE_FLAG_HALT_BIT (0) -+#define GLUE_FLAG_INT_BIT (1) -+#define GLUE_FLAG_OID_BIT (2) -+#define GLUE_FLAG_TIMEOUT_BIT (3) -+#define GLUE_FLAG_TXREQ_BIT (4) -+#define GLUE_FLAG_SUB_MOD_INIT_BIT (5) -+#define GLUE_FLAG_SUB_MOD_EXIT_BIT (6) -+#define GLUE_FLAG_SUB_MOD_MULTICAST_BIT (7) -+#define GLUE_FLAG_FRAME_FILTER_BIT (8) -+#define GLUE_FLAG_FRAME_FILTER_AIS_BIT (9) -+#define GLUE_FLAG_HIF_LOOPBK_AUTO_BIT (10) -+ -+#define GLUE_BOW_KFIFO_DEPTH (1024) -+/* #define GLUE_BOW_DEVICE_NAME "MT6620 802.11 AMP" */ -+#define GLUE_BOW_DEVICE_NAME "ampc0" -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+typedef struct _GL_WPA_INFO_T { -+ UINT_32 u4WpaVersion; -+ UINT_32 u4KeyMgmt; -+ UINT_32 u4CipherGroup; -+ UINT_32 u4CipherPairwise; -+ UINT_32 u4AuthAlg; -+ BOOLEAN fgPrivacyInvoke; -+#if CFG_SUPPORT_802_11W -+ UINT_32 u4Mfp; -+#endif -+} GL_WPA_INFO_T, *P_GL_WPA_INFO_T; -+ -+typedef enum _ENUM_RSSI_TRIGGER_TYPE { -+ ENUM_RSSI_TRIGGER_NONE, -+ ENUM_RSSI_TRIGGER_GREATER, -+ ENUM_RSSI_TRIGGER_LESS, -+ ENUM_RSSI_TRIGGER_TRIGGERED, -+ ENUM_RSSI_TRIGGER_NUM -+} ENUM_RSSI_TRIGGER_TYPE; -+ -+#if CFG_ENABLE_WIFI_DIRECT -+typedef enum _ENUM_SUB_MODULE_IDX_T { -+ P2P_MODULE = 0, -+ SUB_MODULE_NUM -+} ENUM_SUB_MODULE_IDX_T; -+ -+typedef enum _ENUM_NET_REG_STATE_T { -+ ENUM_NET_REG_STATE_UNREGISTERED, -+ ENUM_NET_REG_STATE_REGISTERING, -+ ENUM_NET_REG_STATE_REGISTERED, -+ ENUM_NET_REG_STATE_UNREGISTERING, -+ ENUM_NET_REG_STATE_NUM -+} ENUM_NET_REG_STATE_T; -+ -+#endif -+ -+typedef struct _GL_IO_REQ_T { -+ QUE_ENTRY_T rQueEntry; -+ /* wait_queue_head_t cmdwait_q; */ -+ BOOLEAN fgRead; -+ BOOLEAN fgWaitResp; -+#if CFG_ENABLE_WIFI_DIRECT -+ BOOLEAN fgIsP2pOid; -+#endif -+ P_ADAPTER_T prAdapter; -+ PFN_OID_HANDLER_FUNC pfnOidHandler; -+ PVOID pvInfoBuf; -+ UINT_32 u4InfoBufLen; -+ PUINT_32 pu4QryInfoLen; -+ WLAN_STATUS rStatus; -+ UINT_32 u4Flag; -+} GL_IO_REQ_T, *P_GL_IO_REQ_T; -+ -+#if CFG_ENABLE_BT_OVER_WIFI -+typedef struct _GL_BOW_INFO { -+ BOOLEAN fgIsRegistered; -+ dev_t u4DeviceNumber; /* dynamic device number */ -+/* struct kfifo *prKfifo; */ /* for buffering indicated events */ -+ struct kfifo rKfifo; /* for buffering indicated events */ -+ spinlock_t rSpinLock; /* spin lock for kfifo */ -+ struct cdev cdev; -+ UINT_32 u4FreqInKHz; /* frequency */ -+ -+ UINT_8 aucRole[CFG_BOW_PHYSICAL_LINK_NUM]; /* 0: Responder, 1: Initiator */ -+ ENUM_BOW_DEVICE_STATE aeState[CFG_BOW_PHYSICAL_LINK_NUM]; -+ PARAM_MAC_ADDRESS arPeerAddr[CFG_BOW_PHYSICAL_LINK_NUM]; -+ -+ wait_queue_head_t outq; -+ -+#if CFG_BOW_SEPARATE_DATA_PATH -+ /* Device handle */ -+ struct net_device *prDevHandler; -+ BOOLEAN fgIsNetRegistered; -+#endif -+ -+} GL_BOW_INFO, *P_GL_BOW_INFO; -+#endif -+ -+#if (CFG_SUPPORT_TDLS == 1) -+typedef struct _TDLS_INFO_LINK_T { -+ /* start time when link is built, end time when link is broken */ -+ unsigned long jiffies_start, jiffies_end; -+ -+ /* the peer MAC */ -+ UINT8 aucPeerMac[6]; -+ -+ /* broken reason */ -+ UINT8 ucReasonCode; -+ -+ /* TRUE: torn down is triggerred by us */ -+ UINT8 fgIsFromUs; -+ -+ /* duplicate count; same reason */ -+ UINT8 ucDupCount; -+ -+ /* HT capability */ -+#define TDLS_INFO_LINK_HT_CAP_SUP 0x01 -+ UINT8 ucHtCap; -+#define TDLS_INFO_LINK_HT_BA_SETUP 0x01 -+#define TDLS_INFO_LINK_HT_BA_SETUP_OK 0x02 -+#define TDLS_INFO_LINK_HT_BA_SETUP_DECLINE 0x04 -+#define TDLS_INFO_LINK_HT_BA_PEER 0x10 -+#define TDLS_INFO_LINK_HT_BA_RSP_OK 0x20 -+#define TDLS_INFO_LINK_HT_BA_RSP_DECLINE 0x40 -+ UINT8 ucHtBa[8]; /* TID0 ~ TID7 */ -+} TDLS_INFO_LINK_T; -+ -+typedef struct _TDLS_INFO_T { -+ /* link history */ -+#define TDLS_LINK_HISTORY_MAX 30 -+ TDLS_INFO_LINK_T rLinkHistory[TDLS_LINK_HISTORY_MAX]; -+ UINT32 u4LinkIdx; -+ -+ /* TRUE: support 20/40 bandwidth in TDLS link */ -+ BOOLEAN fgIs2040Sup; -+ -+ /* total TDLS link count */ -+ INT8 cLinkCnt; -+} TDLS_INFO_T; -+#endif /* CFG_SUPPORT_TDLS */ -+ -+/* -+* type definition of pointer to p2p structure -+*/ -+typedef struct _GL_P2P_INFO_T GL_P2P_INFO_T, *P_GL_P2P_INFO_T; -+ -+struct _GLUE_INFO_T { -+ /* Device handle */ -+ struct net_device *prDevHandler; -+ -+ /* Device Index(index of arWlanDevInfo[]) */ -+ INT_32 i4DevIdx; -+ -+ /* Device statistics */ -+ struct net_device_stats rNetDevStats; -+ -+ /* Wireless statistics struct net_device */ -+ struct iw_statistics rIwStats; -+ -+ /* spinlock to sync power save mechanism */ -+ spinlock_t rSpinLock[SPIN_LOCK_NUM]; -+ -+ /* semaphore for ioctl */ -+ struct semaphore ioctl_sem; -+ -+ UINT_64 u8Cookie; -+ -+ ULONG ulFlag; /* GLUE_FLAG_XXX */ -+ UINT_32 u4PendFlag; -+ /* UINT_32 u4TimeoutFlag; */ -+ UINT_32 u4OidCompleteFlag; -+ UINT_32 u4ReadyFlag; /* check if card is ready */ -+ -+ UINT_32 u4OsMgmtFrameFilter; -+ -+ /* Number of pending frames, also used for debuging if any frame is -+ * missing during the process of unloading Driver. -+ * -+ * NOTE(Kevin): In Linux, we also use this variable as the threshold -+ * for manipulating the netif_stop(wake)_queue() func. -+ */ -+ INT_32 ai4TxPendingFrameNumPerQueue[4][CFG_MAX_TXQ_NUM]; -+ INT_32 i4TxPendingFrameNum; -+ INT_32 i4TxPendingSecurityFrameNum; -+ -+ /* current IO request for kalIoctl */ -+ GL_IO_REQ_T OidEntry; -+ -+ /* registry info */ -+ REG_INFO_T rRegInfo; -+ -+ /* firmware */ -+ struct firmware *prFw; -+ -+ /* Host interface related information */ -+ /* defined in related hif header file */ -+ GL_HIF_INFO_T rHifInfo; -+ -+ /*! \brief wext wpa related information */ -+ GL_WPA_INFO_T rWpaInfo; -+ -+ /* Pointer to ADAPTER_T - main data structure of internal protocol stack */ -+ P_ADAPTER_T prAdapter; -+ -+#ifdef WLAN_INCLUDE_PROC -+ struct proc_dir_entry *pProcRoot; -+#endif /* WLAN_INCLUDE_PROC */ -+ -+ /* Indicated media state */ -+ ENUM_PARAM_MEDIA_STATE_T eParamMediaStateIndicated; -+ -+ /* Device power state D0~D3 */ -+ PARAM_DEVICE_POWER_STATE ePowerState; -+ -+ struct completion rScanComp; /* indicate scan complete */ -+ struct completion rHaltComp; /* indicate main thread halt complete */ -+ struct completion rPendComp; /* indicate main thread halt complete */ -+#if CFG_ENABLE_WIFI_DIRECT -+ struct completion rSubModComp; /*indicate sub module init or exit complete */ -+#endif -+ WLAN_STATUS rPendStatus; -+ -+ QUE_T rTxQueue; -+ -+ /* OID related */ -+ QUE_T rCmdQueue; -+ /* PVOID pvInformationBuffer; */ -+ /* UINT_32 u4InformationBufferLength; */ -+ /* PVOID pvOidEntry; */ -+ /* PUINT_8 pucIOReqBuff; */ -+ /* QUE_T rIOReqQueue; */ -+ /* QUE_T rFreeIOReqQueue; */ -+ -+ wait_queue_head_t waitq; -+ struct task_struct *main_thread; -+ -+ struct timer_list tickfn; -+ -+#if CFG_SUPPORT_EXT_CONFIG -+ UINT_16 au2ExtCfg[256]; /* NVRAM data buffer */ -+ UINT_32 u4ExtCfgLength; /* 0 means data is NOT valid */ -+#endif -+ -+#if 1 /* CFG_SUPPORT_WAPI */ -+ /* Should be large than the PARAM_WAPI_ASSOC_INFO_T */ -+ UINT_8 aucWapiAssocInfoIEs[42]; -+ UINT_16 u2WapiAssocInfoIESz; -+#endif -+ -+#if CFG_ENABLE_BT_OVER_WIFI -+ GL_BOW_INFO rBowInfo; -+#endif -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ P_GL_P2P_INFO_T prP2PInfo; -+#if CFG_SUPPORT_P2P_RSSI_QUERY -+ /* Wireless statistics struct net_device */ -+ struct iw_statistics rP2pIwStats; -+#endif -+#endif -+ BOOLEAN fgWpsActive; -+ UINT_8 aucWSCIE[500]; /*for probe req */ -+ UINT_16 u2WSCIELen; -+ UINT_8 aucWSCAssocInfoIE[200]; /*for Assoc req */ -+ UINT_16 u2WSCAssocInfoIELen; -+ -+#if CFG_SUPPORT_HOTSPOT_2_0 -+ UINT_8 aucHS20AssocInfoIE[200]; /*for Assoc req */ -+ UINT_16 u2HS20AssocInfoIELen; -+ UINT_8 ucHotspotConfig; -+ BOOLEAN fgConnectHS20AP; -+#endif -+ -+ /* NVRAM availability */ -+ BOOLEAN fgNvramAvailable; -+ -+ BOOLEAN fgMcrAccessAllowed; -+ -+ /* MAC Address Overridden by IOCTL */ -+ BOOLEAN fgIsMacAddrOverride; -+ PARAM_MAC_ADDRESS rMacAddrOverride; -+ -+ SET_TXPWR_CTRL_T rTxPwr; -+ -+ /* for cfg80211 scan done indication */ -+ struct cfg80211_scan_request *prScanRequest; -+ -+ /* for cfg80211 scheduled scan */ -+ struct cfg80211_sched_scan_request *prSchedScanRequest; -+ -+ /* to indicate registered or not */ -+ BOOLEAN fgIsRegistered; -+ -+ /* for cfg80211 connected indication */ -+ UINT_32 u4RspIeLength; -+ UINT_8 aucRspIe[CFG_CFG80211_IE_BUF_LEN]; -+ -+ UINT_32 u4ReqIeLength; -+ UINT_8 aucReqIe[CFG_CFG80211_IE_BUF_LEN]; -+ -+ KAL_WAKE_LOCK_T rAhbIsrWakeLock; -+ -+#if CFG_SUPPORT_HOTSPOT_2_0 -+ BOOLEAN fgIsDad; -+ UINT_8 aucDADipv4[4]; -+ BOOLEAN fgIs6Dad; -+ UINT_8 aucDADipv6[16]; -+#endif -+#if (CFG_SUPPORT_MET_PROFILING == 1) -+ UINT_8 u8MetProfEnable; -+ INT_16 u16MetUdpPort; -+#endif -+ BOOLEAN fgPoorlinkValid; -+ UINT_64 u8Statistic[2]; -+ UINT_64 u8TotalFailCnt; -+ UINT_32 u4LinkspeedThreshold; -+ INT_32 i4RssiThreshold; -+ INT_32 i4RssiCache; -+ UINT_32 u4LinkSpeedCache; -+ -+#if (CFG_SUPPORT_TDLS == 1) -+ TDLS_INFO_T rTdlsLink; -+ -+ UINT8 aucTdlsHtPeerMac[6]; -+ IE_HT_CAP_T rTdlsHtCap; /* temp to queue HT capability element */ -+ -+ /* -+ [0~7]: jiffies -+ [8~13]: Peer MAC -+ [14]: Reason Code -+ [15]: From us or peer -+ [16]: Duplicate Count -+ */ -+/* UINT8 aucTdlsDisconHistory[TDLS_DISCON_HISTORY_MAX][20]; */ -+/* UINT32 u4TdlsDisconIdx; */ -+#endif /* CFG_SUPPORT_TDLS */ -+ UINT_32 IsrCnt; -+ UINT_32 IsrPassCnt; -+ UINT_32 TaskIsrCnt; -+ -+ UINT_32 IsrPreCnt; -+ UINT_32 IsrPrePassCnt; -+ UINT_32 TaskPreIsrCnt; -+ -+ UINT_32 IsrAbnormalCnt; -+ UINT_32 IsrSoftWareCnt; -+ UINT_32 IsrTxCnt; -+ UINT_32 IsrRxCnt; -+ UINT_64 u8SkbToDriver; -+ UINT_64 u8SkbFreed; -+}; -+ -+typedef irqreturn_t(*PFN_WLANISR) (int irq, void *dev_id, struct pt_regs *regs); -+ -+typedef void (*PFN_LINUX_TIMER_FUNC) (unsigned long); -+ -+/* generic sub module init/exit handler -+* now, we only have one sub module, p2p -+*/ -+#if CFG_ENABLE_WIFI_DIRECT -+typedef BOOLEAN(*SUB_MODULE_INIT) (P_GLUE_INFO_T prGlueInfo); -+typedef BOOLEAN(*SUB_MODULE_EXIT) (P_GLUE_INFO_T prGlueInfo); -+ -+typedef struct _SUB_MODULE_HANDLER { -+ SUB_MODULE_INIT subModInit; -+ SUB_MODULE_EXIT subModExit; -+ BOOLEAN fgIsInited; -+} SUB_MODULE_HANDLER, *P_SUB_MODULE_HANDLER; -+ -+#endif -+ -+ -+#ifdef CONFIG_NL80211_TESTMODE -+enum TestModeCmdType { -+ /* old test mode command id, compatible with exist testmode command */ -+ TESTMODE_CMD_ID_SW_CMD = 1, -+ TESTMODE_CMD_ID_WAPI = 2, -+ TESTMODE_CMD_ID_HS20 = 3, -+ TESTMODE_CMD_ID_POORLINK = 4, -+ TESTMODE_CMD_ID_STATISTICS = 0x10, -+ TESTMODE_CMD_ID_LINK_DETECT = 0x20, -+ /* old test mode command id, compatible with exist testmode command */ -+ -+ /* all new added test mode command should great than TESTMODE_CMD_ID_NEW_BEGIN */ -+ TESTMODE_CMD_ID_NEW_BEGIN = 100, -+ TESTMODE_CMD_ID_SUSPEND = 101, -+}; -+#if CFG_SUPPORT_HOTSPOT_2_0 -+enum Hs20CmdType { -+ HS20_CMD_ID_SET_BSSID_POOL = 0, -+ NUM_OF_HS20_CMD_ID -+}; -+#endif -+ -+typedef struct _NL80211_DRIVER_TEST_MODE_PARAMS { -+ UINT_32 index; -+ UINT_32 buflen; -+} NL80211_DRIVER_TEST_MODE_PARAMS, *P_NL80211_DRIVER_TEST_MODE_PARAMS; -+ -+/*SW CMD */ -+typedef struct _NL80211_DRIVER_SW_CMD_PARAMS { -+ NL80211_DRIVER_TEST_MODE_PARAMS hdr; -+ UINT_8 set; -+ UINT_32 adr; -+ UINT_32 data; -+} NL80211_DRIVER_SW_CMD_PARAMS, *P_NL80211_DRIVER_SW_CMD_PARAMS; -+ -+typedef struct _NL80211_DRIVER_SUSPEND_PARAMS { -+ NL80211_DRIVER_TEST_MODE_PARAMS hdr; -+ UINT_8 suspend; -+} NL80211_DRIVER_SUSPEND_PARAMS, *P_NL80211_DRIVER_SUSPEND_PARAMS; -+struct iw_encode_exts { -+ __u32 ext_flags; /*!< IW_ENCODE_EXT_* */ -+ __u8 tx_seq[IW_ENCODE_SEQ_MAX_SIZE]; /*!< LSB first */ -+ __u8 rx_seq[IW_ENCODE_SEQ_MAX_SIZE]; /*!< LSB first */ -+ __u8 addr[MAC_ADDR_LEN]; /*!< ff:ff:ff:ff:ff:ff for broadcast/multicast -+ * (group) keys or unicast address for -+ * individual keys */ -+ __u16 alg; /*!< IW_ENCODE_ALG_* */ -+ __u16 key_len; -+ __u8 key[32]; -+}; -+ -+/*SET KEY EXT */ -+typedef struct _NL80211_DRIVER_SET_KEY_EXTS { -+ NL80211_DRIVER_TEST_MODE_PARAMS hdr; -+ UINT_8 key_index; -+ UINT_8 key_len; -+ struct iw_encode_exts ext; -+} NL80211_DRIVER_SET_KEY_EXTS, *P_NL80211_DRIVER_SET_KEY_EXTS; -+ -+#if CFG_SUPPORT_HOTSPOT_2_0 -+ -+struct param_hs20_set_bssid_pool { -+ u8 fgBssidPoolIsEnable; -+ u8 ucNumBssidPool; -+ u8 arBssidPool[8][ETH_ALEN]; -+}; -+ -+struct wpa_driver_hs20_data_s { -+ NL80211_DRIVER_TEST_MODE_PARAMS hdr; -+ enum Hs20CmdType CmdType; -+ struct param_hs20_set_bssid_pool hs20_set_bssid_pool; -+}; -+ -+#endif /* CFG_SUPPORT_HOTSPOT_2_0 */ -+ -+#endif -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+/*----------------------------------------------------------------------------*/ -+/* Macros of SPIN LOCK operations for using in Glue Layer */ -+/*----------------------------------------------------------------------------*/ -+#if CFG_USE_SPIN_LOCK_BOTTOM_HALF -+#define GLUE_SPIN_LOCK_DECLARATION() -+#define GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, rLockCategory) \ -+ { \ -+ if (rLockCategory < SPIN_LOCK_NUM) \ -+ spin_lock_bh(&(prGlueInfo->rSpinLock[rLockCategory])); \ -+ } -+#define GLUE_RELEASE_SPIN_LOCK(prGlueInfo, rLockCategory) \ -+ { \ -+ if (rLockCategory < SPIN_LOCK_NUM) \ -+ spin_unlock_bh(&(prGlueInfo->rSpinLock[rLockCategory])); \ -+ } -+#define GLUE_ACQUIRE_THE_SPIN_LOCK(prLock) \ -+ spin_lock_bh(prLock) -+#define GLUE_RELEASE_THE_SPIN_LOCK(prLock) \ -+ spin_unlock_bh(prLock) -+ -+#else /* !CFG_USE_SPIN_LOCK_BOTTOM_HALF */ -+#define GLUE_SPIN_LOCK_DECLARATION() unsigned long __u4Flags = 0 -+#define GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, rLockCategory) \ -+ { \ -+ if (rLockCategory < SPIN_LOCK_NUM) \ -+ spin_lock_irqsave(&(prGlueInfo)->rSpinLock[rLockCategory], __u4Flags); \ -+ } -+#define GLUE_RELEASE_SPIN_LOCK(prGlueInfo, rLockCategory) \ -+ { \ -+ if (rLockCategory < SPIN_LOCK_NUM) \ -+ spin_unlock_irqrestore(&(prGlueInfo->rSpinLock[rLockCategory]), __u4Flags); \ -+ } -+#define GLUE_ACQUIRE_THE_SPIN_LOCK(prLock) \ -+ spin_lock_irqsave(prLock, __u4Flags) -+#define GLUE_RELEASE_THE_SPIN_LOCK(prLock) \ -+ spin_unlock_irqrestore(prLock, __u4Flags) -+#endif /* !CFG_USE_SPIN_LOCK_BOTTOM_HALF */ -+ -+/*----------------------------------------------------------------------------*/ -+/* Macros for accessing Reserved Fields of native packet */ -+/*----------------------------------------------------------------------------*/ -+#define GLUE_CB_OFFSET 4 /* For 64-bit platform, avoiding that the cb -+ isoverwrited by "(prQueueEntry)->prNext = -+ (P_QUE_ENTRY_T)NULL;" in QUEUE_INSERT_TAIL */ -+#define GLUE_GET_PKT_QUEUE_ENTRY(_p) \ -+ (&(((struct sk_buff *)(_p))->cb[0])) -+ -+#define GLUE_GET_PKT_DESCRIPTOR(_prQueueEntry) \ -+ ((P_NATIVE_PACKET) ((ULONG)_prQueueEntry - offsetof(struct sk_buff, cb[0]))) -+ -+#define GLUE_SET_PKT_FLAG_802_11(_p) \ -+ (*((PUINT_8)&(((struct sk_buff *)(_p))->cb[GLUE_CB_OFFSET+4])) |= BIT(7)) -+ -+#define GLUE_SET_PKT_FLAG_1X(_p) \ -+ (*((PUINT_8)&(((struct sk_buff *)(_p))->cb[GLUE_CB_OFFSET+4])) |= BIT(6)) -+ -+#define GLUE_SET_PKT_FLAG_PAL(_p) \ -+ (*((PUINT_8)&(((struct sk_buff *)(_p))->cb[GLUE_CB_OFFSET+4])) |= BIT(5)) -+ -+#define GLUE_SET_PKT_FLAG_P2P(_p) \ -+ (*((PUINT_8)&(((struct sk_buff *)(_p))->cb[GLUE_CB_OFFSET+4])) |= BIT(4)) -+ -+#define GLUE_SET_PKT_TID(_p, _tid) \ -+ (*((PUINT_8)&(((struct sk_buff *)(_p))->cb[GLUE_CB_OFFSET+4])) |= (((UINT_8)((_tid) & (BITS(0, 3)))))) -+ -+#define GLUE_SET_PKT_FRAME_LEN(_p, _u2PayloadLen) \ -+ (*((PUINT_16)&(((struct sk_buff *)(_p))->cb[GLUE_CB_OFFSET+6])) = (UINT_16)(_u2PayloadLen)) -+ -+#define GLUE_GET_PKT_FRAME_LEN(_p) \ -+ (*((PUINT_16)&(((struct sk_buff *)(_p))->cb[GLUE_CB_OFFSET+6]))) -+ -+#define GLUE_GET_PKT_IS_802_11(_p) \ -+ ((*((PUINT_8)&(((struct sk_buff *)(_p))->cb[GLUE_CB_OFFSET+4]))) & (BIT(7))) -+ -+#define GLUE_GET_PKT_IS_1X(_p) \ -+ ((*((PUINT_8)&(((struct sk_buff *)(_p))->cb[GLUE_CB_OFFSET+4]))) & (BIT(6))) -+ -+#define GLUE_GET_PKT_TID(_p) \ -+ ((*((PUINT_8)&(((struct sk_buff *)(_p))->cb[GLUE_CB_OFFSET+4]))) & (BITS(0, 3))) -+ -+#define GLUE_GET_PKT_IS_PAL(_p) \ -+ ((*((PUINT_8)&(((struct sk_buff *)(_p))->cb[GLUE_CB_OFFSET+4]))) & (BIT(5))) -+ -+#define GLUE_GET_PKT_IS_P2P(_p) \ -+ ((*((PUINT_8)&(((struct sk_buff *)(_p))->cb[GLUE_CB_OFFSET+4]))) & (BIT(4))) -+ -+#define GLUE_SET_PKT_HEADER_LEN(_p, _ucMacHeaderLen) \ -+ (*((PUINT_8)&(((struct sk_buff *)(_p))->cb[GLUE_CB_OFFSET+5])) = (UINT_8)(_ucMacHeaderLen)) -+ -+#define GLUE_GET_PKT_HEADER_LEN(_p) \ -+ (*((PUINT_8)&(((struct sk_buff *)(_p))->cb[GLUE_CB_OFFSET+5]))) -+ -+#define GLUE_SET_PKT_ARRIVAL_TIME(_p, _rSysTime) \ -+ (*((POS_SYSTIME)&(((struct sk_buff *)(_p))->cb[GLUE_CB_OFFSET+8])) = (OS_SYSTIME)(_rSysTime)) -+ -+#define GLUE_GET_PKT_ARRIVAL_TIME(_p) \ -+ (*((POS_SYSTIME)&(((struct sk_buff *)(_p))->cb[GLUE_CB_OFFSET+8]))) -+ -+#define GLUE_SET_PKT_XTIME(_p, _rSysTime) \ -+ (*((UINT_64 *)&(((struct sk_buff *)(_p))->cb[GLUE_CB_OFFSET+16])) = (UINT_64)(_rSysTime)) -+ -+#define GLUE_GET_PKT_XTIME(_p) \ -+ (*((UINT_64 *)&(((struct sk_buff *)(_p))->cb[GLUE_CB_OFFSET+16]))) -+ -+/* Check validity of prDev, private data, and pointers */ -+#define GLUE_CHK_DEV(prDev) \ -+ ((prDev && *((P_GLUE_INFO_T *) netdev_priv(prDev))) ? TRUE : FALSE) -+ -+#define GLUE_CHK_PR2(prDev, pr2) \ -+ ((GLUE_CHK_DEV(prDev) && pr2) ? TRUE : FALSE) -+ -+#define GLUE_CHK_PR3(prDev, pr2, pr3) \ -+ ((GLUE_CHK_PR2(prDev, pr2) && pr3) ? TRUE : FALSE) -+ -+#define GLUE_CHK_PR4(prDev, pr2, pr3, pr4) \ -+ ((GLUE_CHK_PR3(prDev, pr2, pr3) && pr4) ? TRUE : FALSE) -+ -+#define GLUE_SET_EVENT(pr) \ -+ kalSetEvent(pr) -+ -+#define GLUE_INC_REF_CNT(_refCount) atomic_inc((atomic_t *)&(_refCount)) -+#define GLUE_DEC_REF_CNT(_refCount) atomic_dec((atomic_t *)&(_refCount)) -+ -+#define DbgPrint(...) -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+#ifdef WLAN_INCLUDE_PROC -+INT_32 procRemoveProcfs(VOID); -+ -+INT_32 procCreateFsEntry(P_GLUE_INFO_T prGlueInfo); -+INT_32 procInitFs(VOID); -+INT_32 procUninitProcFs(VOID); -+ -+#endif /* WLAN_INCLUDE_PROC */ -+ -+#if CFG_ENABLE_BT_OVER_WIFI -+BOOLEAN glRegisterAmpc(P_GLUE_INFO_T prGlueInfo); -+ -+BOOLEAN glUnregisterAmpc(P_GLUE_INFO_T prGlueInfo); -+#endif -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ -+VOID wlanSubModRunInit(P_GLUE_INFO_T prGlueInfo); -+ -+VOID wlanSubModRunExit(P_GLUE_INFO_T prGlueInfo); -+ -+BOOLEAN wlanSubModInit(P_GLUE_INFO_T prGlueInfo); -+ -+BOOLEAN wlanSubModExit(P_GLUE_INFO_T prGlueInfo); -+ -+VOID -+wlanSubModRegisterInitExit(SUB_MODULE_INIT rSubModInit, SUB_MODULE_EXIT rSubModExit, ENUM_SUB_MODULE_IDX_T eSubModIdx); -+ -+BOOLEAN wlanExportGlueInfo(P_GLUE_INFO_T *prGlueInfoExpAddr); -+ -+BOOLEAN wlanIsLaunched(VOID); -+ -+VOID wlanUpdateChannelTable(P_GLUE_INFO_T prGlueInfo); -+ -+#endif -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif /* _GL_OS_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_p2p_ioctl.h b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_p2p_ioctl.h -new file mode 100644 -index 000000000000..a27294e33500 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_p2p_ioctl.h -@@ -0,0 +1,743 @@ -+/* -+** Id: //Department/DaVinci/TRUNK/WiFi_P2P_Driver/os/linux/include/gl_p2p_ioctl.h#9 -+*/ -+ -+/*! \file gl_p2p_ioctl.h -+ \brief This file is for custom ioctls for Wi-Fi Direct only -+*/ -+ -+/* -+** Log: gl_p2p_ioctl.h -+** -+** 07 26 2012 yuche.tsai -+** [ALPS00324337] [ALPS.JB][Hot-Spot] Driver update for Hot-Spot -+** Update driver code of ALPS.JB for hot-spot. -+** -+** 07 19 2012 yuche.tsai -+** NULL -+** Code update for JB. -+ * -+ * 07 17 2012 yuche.tsai -+ * NULL -+ * Compile no error before trial run. -+ * -+ * 06 07 2011 yuche.tsai -+ * [WCXRP00000763] [Volunteer Patch][MT6620][Driver] RX Service Discovery Frame under AP mode Issue -+ * Fix RX SD request under AP mode issue. -+ * -+ * 03 25 2011 wh.su -+ * NULL -+ * Fix P2P IOCTL of multicast address bug, add low power driver stop control. -+ * -+ * 11 22 2011 yuche.tsai -+ * NULL -+ * Update RSSI link quality of P2P Network query method. (Bug fix) -+ * -+ * 11 19 2011 yuche.tsai -+ * NULL -+ * Add RSSI support for P2P network. -+ * -+ * 11 11 2011 yuche.tsai -+ * NULL -+ * Fix work thread cancel issue. -+ * -+ * 11 08 2011 yuche.tsai -+ * [WCXRP00001094] [Volunteer Patch][Driver] Driver version & supplicant version query & set support for service -+ * discovery version check. -+ * Add support for driver version query & p2p supplicant verseion set. -+ * For new service discovery mechanism sync. -+ * -+ * 10 25 2011 cm.chang -+ * [WCXRP00001058] [All Wi-Fi][Driver] Fix sta_rec's phyTypeSet and OBSS scan in AP mode -+ * . -+ * -+ * 10 18 2011 yuche.tsai -+ * [WCXRP00001045] [WiFi Direct][Driver] Check 2.1 branch. -+ * New 2.1 branch -+ -+ * -+ * 08 16 2011 chinglan.wang -+ * NULL -+ * Add the group id information in the invitation indication. -+ * -+ * 08 09 2011 yuche.tsai -+ * [WCXRP00000919] [Volunteer Patch][WiFi Direct][Driver] Invitation New Feature. -+ * Invitation Feature add on. -+ * -+ * 05 04 2011 chinglan.wang -+ * [WCXRP00000698] [MT6620 Wi-Fi][P2P][Driver] Add p2p invitation command for the p2p driver -+ * . -+ * -+ * 03 29 2011 wh.su -+ * [WCXRP00000095] [MT6620 Wi-Fi] [FW] Refine the P2P GO send broadcast protected code -+ * add the set power and get power function sample. -+ * -+ * 03 22 2011 george.huang -+ * [WCXRP00000504] [MT6620 Wi-Fi][FW] Support Sigma CAPI for power saving related command -+ * link with supplicant commands -+ * -+ * 03 07 2011 wh.su -+ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code -+ * rename the define to anti_pviracy. -+ * -+ * 03 02 2011 wh.su -+ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code -+ * Add Security check related code. -+ * -+ * 03 01 2011 wh.su -+ * [WCXRP00000488] [MT6620 Wi-Fi][Driver] Support the SIGMA set p2p parameter to driver -+ * fixed the ioctl sumcmd to meet the p2p_supplicant setting. -+ * -+ * 02 23 2011 wh.su -+ * [WCXRP00000488] [MT6620 Wi-Fi][Driver] Support the SIGMA set p2p parameter to driver -+ * adding the ioctl set int define for p2p parameter. -+ * -+ * 02 22 2011 wh.su -+ * [WCXRP00000488] [MT6620 Wi-Fi][Driver] Support the SIGMA set p2p parameter to driver -+ * adding the ioctl set int from supplicant, and can used to set the p2p parameters -+ * -+ * 02 17 2011 wh.su -+ * [WCXRP00000448] [MT6620 Wi-Fi][Driver] Fixed WSC IE not send out at probe request -+ * adjust the set wsc ie structure. -+ * -+ * 01 05 2011 cp.wu -+ * [WCXRP00000283] [MT6620 Wi-Fi][Driver][Wi-Fi Direct] Implementation of interface for supporting Wi-Fi Direct Service -+ * Discovery -+ * ioctl implementations for P2P Service Discovery -+ * -+ * 12 22 2010 cp.wu -+ * [WCXRP00000283] [MT6620 Wi-Fi][Driver][Wi-Fi Direct] Implementation of interface for supporting Wi-Fi Direct Service -+ * Discovery -+ * 1. header file restructure for more clear module isolation -+ * 2. add function interface definition for implementing Service Discovery callbacks -+ * -+ * 12 15 2010 cp.wu -+ * NULL -+ * invoke nicEnableInterrupt() before leaving from wlanAdapterStart() -+ * -+ * 12 07 2010 cp.wu -+ * [WCXRP00000237] [MT6620 Wi-Fi][Wi-Fi Direct][Driver] Add interface for supporting service discovery -+ * define a pair of i/o control for multiplexing layer -+ * -+ * 11 04 2010 wh.su -+ * [WCXRP00000164] [MT6620 Wi-Fi][Driver] Support the p2p random SSID -+ * adding the p2p random ssid support. -+ * -+ * 10 20 2010 wh.su -+ * [WCXRP00000124] [MT6620 Wi-Fi] [Driver] Support the dissolve P2P Group -+ * Add the code to support disconnect p2p group -+ * -+ * 09 21 2010 kevin.huang -+ * [WCXRP00000054] [MT6620 Wi-Fi][Driver] Restructure driver for second Interface -+ * Isolate P2P related function for Hardware Software Bundle -+ * -+ * 09 10 2010 george.huang -+ * NULL -+ * update iwpriv LP related -+ * -+ * 09 07 2010 wh.su -+ * NULL -+ * adding the code for beacon/probe req/ probe rsp wsc ie at p2p. -+ * -+ * 08 25 2010 cp.wu -+ * NULL -+ * add netdev_ops(NDO) for linux kernel 2.6.31 or greater -+ * -+ * 08 20 2010 yuche.tsai -+ * NULL -+ * Refine a function parameter name. -+ * -+ * 08 19 2010 cp.wu -+ * NULL -+ * add set mac address interface for further possibilities of wpa_supplicant overriding interface address. -+ * -+ * 08 16 2010 george.huang -+ * NULL -+ * add wext handlers to link P2P set PS profile/ network address function (TBD) -+ * -+ * 08 16 2010 cp.wu -+ * NULL -+ * revised implementation of Wi-Fi Direct io controls. -+ * -+ * 08 12 2010 cp.wu -+ * NULL -+ * follow-up with ioctl interface update for Wi-Fi Direct application -+ * -+ * 08 06 2010 cp.wu -+ * NULL -+ * driver hook modifications corresponding to ioctl interface change. -+ * -+ * 08 03 2010 cp.wu -+ * NULL -+ * [Wi-Fi Direct] add framework for driver hooks -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 06 01 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * add ioctl to configure scan mode for p2p connection -+ * -+ * 05 31 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * add cfg80211 interface, which is to replace WE, for further extension -+ * -+ * 05 17 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * implement get scan result. -+ * -+ * 05 14 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * implement wireless extension ioctls in iw_handler form. -+ * -+ * 05 14 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * add ioctl framework for Wi-Fi Direct by reusing wireless extension ioctls as well -+ * -+ * 05 11 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * p2p ioctls revised. -+ * -+ * 05 11 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * add ioctl for controlling p2p scan phase parameters -+ * -+*/ -+ -+#ifndef _GL_P2P_IOCTL_H -+#define _GL_P2P_IOCTL_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include -+#include -+#include -+#if CFG_ENABLE_WIFI_DIRECT_CFG_80211 -+#include -+#include -+#endif -+ -+#include "wlan_oid.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+/* Device private ioctl calls */ -+/* #define SIOCDEVPRIVATE 0x89F0*/ -+#define IOC_GET_PRIVATE_IOCTL_CMD (SIOCDEVPRIVATE+1) -+ -+/* (WirelessExtension) Private I/O Controls */ -+#define IOC_P2P_CFG_DEVICE (SIOCIWFIRSTPRIV+0) -+#define IOC_P2P_PROVISION_COMPLETE (SIOCIWFIRSTPRIV+2) -+#define IOC_P2P_START_STOP_DISCOVERY (SIOCIWFIRSTPRIV+4) -+#define IOC_P2P_DISCOVERY_RESULTS (SIOCIWFIRSTPRIV+5) -+#define IOC_P2P_WSC_BEACON_PROBE_RSP_IE (SIOCIWFIRSTPRIV+6) -+#define IOC_P2P_GO_WSC_IE IOC_P2P_WSC_BEACON_PROBE_RSP_IE -+#define IOC_P2P_CONNECT_DISCONNECT (SIOCIWFIRSTPRIV+8) -+#define IOC_P2P_PASSWORD_READY (SIOCIWFIRSTPRIV+10) -+/* #define IOC_P2P_SET_PWR_MGMT_PARAM (SIOCIWFIRSTPRIV+12) */ -+#define IOC_P2P_SET_INT (SIOCIWFIRSTPRIV+12) -+#define IOC_P2P_GET_STRUCT (SIOCIWFIRSTPRIV+13) -+#define IOC_P2P_SET_STRUCT (SIOCIWFIRSTPRIV+14) -+#define IOC_P2P_GET_REQ_DEVICE_INFO (SIOCIWFIRSTPRIV+15) -+ -+#define PRIV_CMD_INT_P2P_SET 0 -+ -+/* IOC_P2P_PROVISION_COMPLETE (iw_point . flags) */ -+#define P2P_PROVISIONING_SUCCESS 0 -+#define P2P_PROVISIONING_FAIL 1 -+ -+/* IOC_P2P_START_STOP_DISCOVERY (iw_point . flags) */ -+#define P2P_STOP_DISCOVERY 0 -+#define P2P_START_DISCOVERY 1 -+ -+/* IOC_P2P_CONNECT_DISCONNECT (iw_point . flags) */ -+#define P2P_CONNECT 0 -+#define P2P_DISCONNECT 1 -+ -+/* IOC_P2P_START_STOP_DISCOVERY (scan_type) */ -+#define P2P_SCAN_FULL_AND_FIND 0 -+#define P2P_SCAN_FULL 1 -+#define P2P_SCAN_SEARCH_AND_LISTEN 2 -+#define P2P_LISTEN 3 -+ -+/* IOC_P2P_GET_STRUCT/IOC_P2P_SET_STRUCT */ -+#define P2P_SEND_SD_RESPONSE 0 -+#define P2P_GET_SD_REQUEST 1 -+#define P2P_SEND_SD_REQUEST 2 -+#define P2P_GET_SD_RESPONSE 3 -+#define P2P_TERMINATE_SD_PHASE 4 -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+/*----------------------------------------------------------------------------*/ -+/* Wireless Extension: Private I/O Control */ -+/*----------------------------------------------------------------------------*/ -+typedef struct iw_p2p_cfg_device_type { -+ void __user *ssid; -+ UINT_8 ssid_len; -+ UINT_8 pri_device_type[8]; -+ UINT_8 snd_device_type[8]; -+ void __user *device_name; -+ UINT_8 device_name_len; -+ UINT_8 intend; -+ UINT_8 persistence; -+ UINT_8 sec_mode; -+ UINT_8 ch; -+ UINT_8 ch_width; /* 0: 20 Mhz 1:20/40 Mhz auto */ -+ UINT_8 max_scb; -+} IW_P2P_CFG_DEVICE_TYPE, *P_IW_P2P_CFG_DEVICE_TYPE; -+ -+typedef struct iw_p2p_hostapd_param { -+ UINT_8 cmd; -+ UINT_8 rsv[3]; -+ UINT_8 sta_addr[6]; -+ void __user *data; -+ UINT_16 len; -+} IW_P2P_HOSTAPD_PARAM, *P_IW_P2P_HOSTAPD_PARAM; -+ -+typedef struct iw_p2p_req_device_type { -+ UINT_8 scan_type; /* 0: Full scan + Find -+ * 1: Full scan -+ * 2: Scan (Search +Listen) -+ * 3: Listen -+ * other : reserved -+ */ -+ UINT_8 pri_device_type[8]; -+ void __user *probe_req_ie; -+ UINT_16 probe_req_len; -+ void __user *probe_rsp_ie; -+ UINT_16 probe_rsp_len; -+} IW_P2P_REQ_DEVICE_TYPE, *P_IW_P2P_REQ_DEVICE_TYPE; -+ -+typedef struct iw_p2p_connect_device { -+ UINT_8 sta_addr[6]; -+ UINT_8 p2pRole; /* 0: P2P Device, 1:GC, 2: GO */ -+ UINT_8 needProvision; /* 0: Don't needed provision, 1: doing the wsc provision first */ -+ UINT_8 authPeer; /* 1: auth peer invitation request */ -+ UINT_8 intend_config_method; /* Request Peer Device used config method */ -+} IW_P2P_CONNECT_DEVICE, *P_IW_P2P_CONNECT_DEVICE; -+ -+typedef struct iw_p2p_password_ready { -+ UINT_8 active_config_method; -+ void __user *probe_req_ie; -+ UINT_16 probe_req_len; -+ void __user *probe_rsp_ie; -+ UINT_16 probe_rsp_len; -+} IW_P2P_PASSWORD_READY, *P_IW_P2P_PASSWORD_READY; -+ -+typedef struct iw_p2p_device_req { -+ UINT_8 name[33]; -+ UINT_32 name_len; -+ UINT_8 device_addr[6]; -+ UINT_8 device_type; -+ INT_32 config_method; -+ INT_32 active_config_method; -+} IW_P2P_DEVICE_REQ, *P_IW_P2P_DEVICE_REQ; -+ -+typedef struct iw_p2p_transport_struct { -+ UINT_32 u4CmdId; -+ UINT_32 inBufferLength; -+ UINT_32 outBufferLength; -+ UINT_8 aucBuffer[16]; -+} IW_P2P_TRANSPORT_STRUCT, *P_IW_P2P_TRANSPORT_STRUCT; -+ -+/* For Invitation */ -+typedef struct iw_p2p_ioctl_invitation_struct { -+ UINT_8 aucDeviceID[6]; -+ UINT_8 aucGroupID[6]; /* BSSID */ -+ UINT_8 aucSsid[32]; -+ UINT_32 u4SsidLen; -+ UINT_8 ucReinvoke; -+} IW_P2P_IOCTL_INVITATION_STRUCT, *P_IW_P2P_IOCTL_INVITATION_STRUCT; -+ -+typedef struct iw_p2p_ioctl_abort_invitation { -+ UINT_8 dev_addr[6]; -+} IW_P2P_IOCTL_ABORT_INVITATION, *P_IW_P2P_IOCTL_ABORT_INVITATION; -+ -+typedef struct iw_p2p_ioctl_invitation_indicate { -+ UINT_8 dev_addr[6]; -+ UINT_8 group_bssid[6]; -+ INT_32 config_method; /* peer device supported config method */ -+ UINT_8 dev_name[32]; /* for reinvoke */ -+ UINT_32 name_len; -+ UINT_8 operating_channel; /* for re-invoke, target operating channel */ -+ UINT_8 invitation_type; /* invitation or re-invoke */ -+} IW_P2P_IOCTL_INVITATION_INDICATE, *P_IW_P2P_IOCTL_INVITATION_INDICATE; -+ -+typedef struct iw_p2p_ioctl_invitation_status { -+ UINT_32 status_code; -+} IW_P2P_IOCTL_INVITATION_STATUS, *P_IW_P2P_IOCTL_INVITATION_STATUS; -+ -+/* For Formation */ -+typedef struct iw_p2p_ioctl_start_formation { -+ UINT_8 dev_addr[6]; /* bssid */ -+ UINT_8 role; /* 0: P2P Device, 1:GC, 2: GO */ -+ UINT_8 needProvision; /* 0: Don't needed provision, 1: doing the wsc provision first */ -+ UINT_8 auth; /* 1: auth peer invitation request */ -+ UINT_8 config_method; /* Request Peer Device used config method */ -+} IW_P2P_IOCTL_START_FORMATION, *P_IW_P2P_IOCTL_START_FORMATION; -+ -+/* SET_STRUCT / GET_STRUCT */ -+typedef enum _ENUM_P2P_CMD_ID_T { -+ P2P_CMD_ID_SEND_SD_RESPONSE = 0, /* 0x00 (Set) */ -+ P2P_CMD_ID_GET_SD_REQUEST, /* 0x01 (Get) */ -+ P2P_CMD_ID_SEND_SD_REQUEST, /* 0x02 (Set) */ -+ P2P_CMD_ID_GET_SD_RESPONSE, /* 0x03 (Get) */ -+ P2P_CMD_ID_TERMINATE_SD_PHASE, /* 0x04 (Set) */ -+#if 1 /* CFG_SUPPORT_ANTI_PIRACY */ -+ P2P_CMD_ID_SEC_CHECK, /* 0x05(Set) */ -+#endif -+ P2P_CMD_ID_INVITATION, /* 0x06 (Set) */ -+ P2P_CMD_ID_INVITATION_INDICATE, /* 0x07 (Get) */ -+ P2P_CMD_ID_INVITATION_STATUS, /* 0x08 (Get) */ -+ P2P_CMD_ID_INVITATION_ABORT, /* 0x09 (Set) */ -+ P2P_CMD_ID_START_FORMATION, /* 0x0A (Set) */ -+ P2P_CMD_ID_P2P_VERSION, /* 0x0B (Set/Get) */ -+ P2P_CMD_ID_GET_CH_LIST = 12, /* 0x0C (Get) */ -+ P2P_CMD_ID_GET_OP_CH = 14 /* 0x0E (Get) */ -+} ENUM_P2P_CMD_ID_T, *P_ENUM_P2P_CMD_ID_T; -+ -+/* Service Discovery */ -+typedef struct iw_p2p_cmd_send_sd_response { -+ PARAM_MAC_ADDRESS rReceiverAddr; -+ UINT_8 fgNeedTxDoneIndication; -+ UINT_8 ucSeqNum; -+ UINT_16 u2PacketLength; -+ UINT_8 aucPacketContent[0]; /*native 802.11 */ -+} IW_P2P_CMD_SEND_SD_RESPONSE, *P_IW_P2P_CMD_SEND_SD_RESPONSE; -+ -+typedef struct iw_p2p_cmd_get_sd_request { -+ PARAM_MAC_ADDRESS rTransmitterAddr; -+ UINT_16 u2PacketLength; -+ UINT_8 aucPacketContent[0]; /*native 802.11 */ -+} IW_P2P_CMD_GET_SD_REQUEST, *P_IW_P2P_CMD_GET_SD_REQUEST; -+ -+typedef struct iw_p2p_cmd_send_service_discovery_request { -+ PARAM_MAC_ADDRESS rReceiverAddr; -+ UINT_8 fgNeedTxDoneIndication; -+ UINT_8 ucSeqNum; -+ UINT_16 u2PacketLength; -+ UINT_8 aucPacketContent[0]; /*native 802.11 */ -+} IW_P2P_CMD_SEND_SD_REQUEST, *P_IW_P2P_CMD_SEND_SD_REQUEST; -+ -+typedef struct iw_p2p_cmd_get_sd_response { -+ PARAM_MAC_ADDRESS rTransmitterAddr; -+ UINT_16 u2PacketLength; -+ UINT_8 aucPacketContent[0]; /*native 802.11 */ -+} IW_P2P_CMD_GET_SD_RESPONSE, *P_IW_P2P_CMD_GET_SD_RESPONSE; -+ -+typedef struct iw_p2p_cmd_terminate_sd_phase { -+ PARAM_MAC_ADDRESS rPeerAddr; -+} IW_P2P_CMD_TERMINATE_SD_PHASE, *P_IW_P2P_CMD_TERMINATE_SD_PHASE; -+ -+typedef struct iw_p2p_version { -+ UINT_32 u4Version; -+} IW_P2P_VERSION, *P_IW_P2P_VERSION; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+#if CFG_ENABLE_WIFI_DIRECT_CFG_80211 -+extern struct ieee80211_supported_band mtk_band_2ghz; -+extern struct ieee80211_supported_band mtk_band_5ghz; -+extern UINT_32 mtk_cipher_suites[5]; -+#endif -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+#if CFG_ENABLE_WIFI_DIRECT_CFG_80211 -+int mtk_p2p_cfg80211_change_iface(struct wiphy *wiphy, -+ struct net_device *ndev, -+ enum nl80211_iftype type,/* u32 *flags,*/ struct vif_params *params); -+ -+int mtk_p2p_cfg80211_add_key(struct wiphy *wiphy, -+ struct net_device *ndev, -+ u8 key_index, bool pairwise, const u8 *mac_addr, struct key_params *params); -+ -+int mtk_p2p_cfg80211_get_key(struct wiphy *wiphy, -+ struct net_device *ndev, -+ u8 key_index, -+ bool pairwise, -+ const u8 *mac_addr, void *cookie, void (*callback) (void *cookie, struct key_params *) -+); -+ -+int mtk_p2p_cfg80211_del_key(struct wiphy *wiphy, -+ struct net_device *ndev, u8 key_index, bool pairwise, const u8 *mac_addr); -+ -+int -+mtk_p2p_cfg80211_set_default_key(struct wiphy *wiphy, -+ struct net_device *netdev, u8 key_index, bool unicast, bool multicast); -+ -+int mtk_p2p_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev, -+ const u8 *mac, struct station_info *sinfo); -+ -+int mtk_p2p_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed); -+ -+int mtk_p2p_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_connect_params *sme); -+ -+int mtk_p2p_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev, u16 reason_code); -+ -+int mtk_p2p_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_ibss_params *params); -+ -+int mtk_p2p_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev); -+ -+int mtk_p2p_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev, bool enabled, int timeout); -+ -+int mtk_p2p_cfg80211_change_bss(struct wiphy *wiphy, struct net_device *dev, struct bss_parameters *params); -+ -+int mtk_p2p_cfg80211_remain_on_channel(struct wiphy *wiphy, -+ struct wireless_dev *wdev, -+ struct ieee80211_channel *chan, unsigned int duration, u64 *cookie); -+ -+int mtk_p2p_cfg80211_scan(struct wiphy *wiphy, struct cfg80211_scan_request *request); -+ -+int mtk_p2p_cfg80211_cancel_remain_on_channel(struct wiphy *wiphy, struct wireless_dev *wdev, u64 cookie); -+ -+int mtk_p2p_cfg80211_set_txpower(struct wiphy *wiphy, -+ struct wireless_dev *wdev, enum nl80211_tx_power_setting type, int mbm); -+ -+int mtk_p2p_cfg80211_get_txpower(struct wiphy *wiphy, struct wireless_dev *wdev, int *dbm); -+ -+int mtk_p2p_cfg80211_deauth(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_deauth_request *req); -+ -+int mtk_p2p_cfg80211_disassoc(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_disassoc_request *req); -+ -+int mtk_p2p_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_ap_settings *settings); -+ -+int mtk_p2p_cfg80211_change_beacon(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_beacon_data *info); -+ -+int mtk_p2p_cfg80211_mgmt_tx(struct wiphy *wiphy, -+ struct wireless_dev *wdev, -+ struct cfg80211_mgmt_tx_params *params, -+ u64 *cookie); -+ -+int mtk_p2p_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *dev); -+ -+int mtk_p2p_cfg80211_del_station(struct wiphy *wiphy, struct net_device *dev, struct station_del_parameters *params); -+//int mtk_p2p_cfg80211_del_station(struct wiphy *wiphy, struct net_device *dev, const u8 *mac); -+ -+int mtk_p2p_cfg80211_set_channel(struct wiphy *wiphy, struct cfg80211_chan_def *chandef); -+ -+void mtk_p2p_cfg80211_mgmt_frame_register(struct wiphy *wiphy, struct wireless_dev *wdev, u16 frame_type, bool reg); -+ -+int -+mtk_p2p_cfg80211_set_bitrate_mask(IN struct wiphy *wiphy, -+ IN struct net_device *dev, -+ IN const u8 *peer, IN const struct cfg80211_bitrate_mask *mask); -+ -+#ifdef CONFIG_NL80211_TESTMODE -+int mtk_p2p_cfg80211_testmode_cmd(IN struct wiphy *wiphy, IN struct wireless_dev *wdev, IN void *data, IN int len); -+int mtk_p2p_cfg80211_testmode_p2p_sigma_pre_cmd(IN struct wiphy *wiphy, IN void *data, IN int len); -+int mtk_p2p_cfg80211_testmode_p2p_sigma_cmd(IN struct wiphy *wiphy, IN void *data, IN int len); -+ -+#if CFG_SUPPORT_WFD -+int mtk_p2p_cfg80211_testmode_wfd_update_cmd(IN struct wiphy *wiphy, IN void *data, IN int len); -+#endif -+ -+int mtk_p2p_cfg80211_testmode_hotspot_block_cmd(IN struct wiphy *wiphy, IN void *data, IN int len); -+#else -+#error "Please ENABLE kernel config (CONFIG_NL80211_TESTMODE) to support Wi-Fi Direct" -+#endif -+ -+#endif -+ -+/* I/O control handlers */ -+ -+int -+mtk_p2p_wext_get_priv(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); -+ -+int -+mtk_p2p_wext_reconnect(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); -+ -+int -+mtk_p2p_wext_set_auth(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); -+ -+int -+mtk_p2p_wext_set_key(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); -+ -+int -+mtk_p2p_wext_mlme_handler(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); -+ -+int -+mtk_p2p_wext_set_powermode(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); -+ -+int -+mtk_p2p_wext_get_powermode(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); -+ -+/* Private Wireless I/O Controls takes use of iw_handler */ -+int -+mtk_p2p_wext_set_local_dev_info(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); -+ -+int -+mtk_p2p_wext_set_provision_complete(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); -+ -+int -+mtk_p2p_wext_start_stop_discovery(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); -+ -+int -+mtk_p2p_wext_discovery_results(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); -+ -+int -+mtk_p2p_wext_wsc_ie(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); -+ -+int -+mtk_p2p_wext_connect_disconnect(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); -+ -+int -+mtk_p2p_wext_password_ready(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); -+ -+int -+mtk_p2p_wext_request_dev_info(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); -+ -+int -+mtk_p2p_wext_invitation_indicate(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); -+ -+int -+mtk_p2p_wext_invitation_status(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); -+ -+int -+mtk_p2p_wext_set_pm_param(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); -+ -+int -+mtk_p2p_wext_set_ps_profile(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); -+ -+int -+mtk_p2p_wext_set_network_address(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); -+ -+int -+mtk_p2p_wext_set_int(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); -+ -+/* Private Wireless I/O Controls for IOC_SET_STRUCT/IOC_GET_STRUCT */ -+int -+mtk_p2p_wext_set_struct(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); -+ -+int -+mtk_p2p_wext_get_struct(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); -+ -+/* IOC_SET_STRUCT/IOC_GET_STRUCT: Service Discovery */ -+int -+mtk_p2p_wext_get_service_discovery_request(IN struct net_device *prDev, -+ IN struct iw_request_info *info, -+ IN OUT union iwreq_data *wrqu, IN OUT char *extra); -+ -+int -+mtk_p2p_wext_get_service_discovery_response(IN struct net_device *prDev, -+ IN struct iw_request_info *info, -+ IN OUT union iwreq_data *wrqu, IN OUT char *extra); -+ -+int -+mtk_p2p_wext_send_service_discovery_request(IN struct net_device *prDev, -+ IN struct iw_request_info *info, -+ IN OUT union iwreq_data *wrqu, IN OUT char *extra); -+ -+int -+mtk_p2p_wext_send_service_discovery_response(IN struct net_device *prDev, -+ IN struct iw_request_info *info, -+ IN OUT union iwreq_data *wrqu, IN OUT char *extra); -+ -+int -+mtk_p2p_wext_terminate_service_discovery_phase(IN struct net_device *prDev, -+ IN struct iw_request_info *info, -+ IN OUT union iwreq_data *wrqu, IN OUT char *extra); -+ -+#if CFG_SUPPORT_ANTI_PIRACY -+int -+mtk_p2p_wext_set_sec_check_request(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); -+ -+int -+mtk_p2p_wext_get_sec_check_response(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); -+#endif -+ -+int -+mtk_p2p_wext_set_noa_param(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); -+ -+int -+mtk_p2p_wext_set_oppps_param(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); -+ -+int -+mtk_p2p_wext_set_p2p_version(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); -+ -+int -+mtk_p2p_wext_get_p2p_version(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); -+ -+void mtk_p2p_wext_set_Multicastlist(IN P_GLUE_INFO_T prGlueInfo); -+ -+#if CFG_SUPPORT_P2P_RSSI_QUERY -+int -+mtk_p2p_wext_get_rssi(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); -+ -+struct iw_statistics *mtk_p2p_wext_get_wireless_stats(struct net_device *prDev); -+ -+#endif -+ -+int -+mtk_p2p_wext_set_txpow(IN struct net_device *prDev, -+ IN struct iw_request_info *prIwrInfo, IN OUT union iwreq_data *prTxPow, IN char *pcExtra); -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif /* _GL_P2P_IOCTL_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_p2p_kal.h b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_p2p_kal.h -new file mode 100644 -index 000000000000..bf9d8871ef48 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_p2p_kal.h -@@ -0,0 +1,243 @@ -+/* -+** Id: //Department/DaVinci/TRUNK/WiFi_P2P_Driver/os/linux/include/gl_p2p_kal.h#2 -+*/ -+ -+/*! \file gl_p2p_kal.h -+ \brief Declaration of KAL functions for Wi-Fi Direct support -+ - kal*() which is provided by GLUE Layer. -+ -+ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. -+*/ -+ -+/* -+** Log: gl_p2p_kal.h -+** -+** 08 30 2012 chinglan.wang -+** [ALPS00349664] [6577JB][WIFI] Phone can not connect to AP secured with AES via WPS in 802.11n Only -+** . -+ * -+ * 07 17 2012 yuche.tsai -+ * NULL -+ * Compile no error before trial run. -+ * -+ * 10 18 2011 yuche.tsai -+ * [WCXRP00001045] [WiFi Direct][Driver] Check 2.1 branch. -+ * New 2.1 branch -+ -+ * -+ * 08 15 2011 yuche.tsai -+ * [WCXRP00000919] [Volunteer Patch][WiFi Direct][Driver] Invitation New Feature. -+ * Add group BSSID in invitation request indication. -+ * The BSSID is used for APP to decide the configure method. -+ * -+ * 08 09 2011 yuche.tsai -+ * [WCXRP00000919] [Volunteer Patch][WiFi Direct][Driver] Invitation New Feature. -+ * Invitation Feature add on. -+ * -+ * 03 19 2011 terry.wu -+ * [WCXRP00000577] [MT6620 Wi-Fi][Driver][FW] Create V2.0 branch for firmware and driver -+ * create V2.0 p2p driver release based on label "MT6620_WIFI_P2P_DRIVER_V2_0_2100_0319_2011" from main trunk. -+ * -+ * 03 07 2011 wh.su -+ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code -+ * rename the define to anti_pviracy. -+ * -+ * 03 05 2011 wh.su -+ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code -+ * add the code to get the check rsponse and indicate to app. -+ * -+ * 03 02 2011 wh.su -+ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code -+ * Add Security check related code. -+ * -+ * 12 22 2010 cp.wu -+ * [WCXRP00000283] [MT6620 Wi-Fi][Driver][Wi-Fi Direct] Implementation of interface for supporting Wi-Fi Direct Service -+ * Discovery -+ * 1. header file restructure for more clear module isolation -+ * 2. add function interface definition for implementing Service Discovery callbacks -+ * -+*/ -+ -+#ifndef _GL_P2P_KAL_H -+#define _GL_P2P_KAL_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "config.h" -+#include "gl_typedef.h" -+#include "gl_os.h" -+#include "wlan_lib.h" -+#include "wlan_oid.h" -+#include "wlan_p2p.h" -+#include "gl_kal.h" -+#include "gl_wext_priv.h" -+#include "nic/p2p.h" -+ -+#if DBG -+extern int allocatedMemSize; -+#endif -+ -+extern BOOLEAN -+wextSrchDesiredWPAIE(IN PUINT_8 pucIEStart, -+ IN INT_32 i4TotalIeLen, IN UINT_8 ucDesiredElemId, OUT unsigned char **ppucDesiredIE); -+ -+#if CFG_SUPPORT_WPS -+extern BOOLEAN -+wextSrchDesiredWPSIE(IN PUINT_8 pucIEStart, -+ IN INT_32 i4TotalIeLen, IN UINT_8 ucDesiredElemId, OUT unsigned char **ppucDesiredIE); -+#endif -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+BOOLEAN kalP2pFuncGetChannelType(IN ENUM_CHNL_EXT_T rChnlSco, OUT enum nl80211_channel_type *channel_type); -+struct ieee80211_channel *kalP2pFuncGetChannelEntry(IN P_GL_P2P_INFO_T prP2pInfo, IN P_RF_CHANNEL_INFO_T prChannelInfo); -+ -+/* Service Discovery */ -+VOID kalP2PIndicateSDRequest(IN P_GLUE_INFO_T prGlueInfo, IN PARAM_MAC_ADDRESS rPeerAddr, IN UINT_8 ucSeqNum); -+ -+void kalP2PIndicateSDResponse(IN P_GLUE_INFO_T prGlueInfo, IN PARAM_MAC_ADDRESS rPeerAddr, IN UINT_8 ucSeqNum); -+ -+VOID kalP2PIndicateTXDone(IN P_GLUE_INFO_T prGlueInfo, IN UINT_8 ucSeqNum, IN UINT_8 ucStatus); -+ -+/*----------------------------------------------------------------------------*/ -+/* Wi-Fi Direct handling */ -+/*----------------------------------------------------------------------------*/ -+ENUM_PARAM_MEDIA_STATE_T kalP2PGetState(IN P_GLUE_INFO_T prGlueInfo); -+ -+VOID -+kalP2PSetState(IN P_GLUE_INFO_T prGlueInfo, -+ IN ENUM_PARAM_MEDIA_STATE_T eState, IN PARAM_MAC_ADDRESS rPeerAddr, IN UINT_8 ucRole); -+ -+VOID -+kalP2PUpdateAssocInfo(IN P_GLUE_INFO_T prGlueInfo, -+ IN PUINT_8 pucFrameBody, IN UINT_32 u4FrameBodyLen, IN BOOLEAN fgReassocRequest); -+ -+UINT_32 kalP2PGetFreqInKHz(IN P_GLUE_INFO_T prGlueInfo); -+ -+UINT_8 kalP2PGetRole(IN P_GLUE_INFO_T prGlueInfo); -+ -+VOID -+kalP2PSetRole(IN P_GLUE_INFO_T prGlueInfo, -+ IN UINT_8 ucResult, IN PUINT_8 pucSSID, IN UINT_8 ucSSIDLen, IN UINT_8 ucRole); -+ -+VOID kalP2PSetCipher(IN P_GLUE_INFO_T prGlueInfo, IN UINT_32 u4Cipher); -+ -+BOOLEAN kalP2PGetCipher(IN P_GLUE_INFO_T prGlueInfo); -+ -+BOOLEAN kalP2PGetTkipCipher(IN P_GLUE_INFO_T prGlueInfo); -+ -+BOOLEAN kalP2PGetCcmpCipher(IN P_GLUE_INFO_T prGlueInfo); -+ -+VOID kalP2PSetWscMode(IN P_GLUE_INFO_T prGlueInfo, IN UINT_8 ucWscMode); -+ -+UINT_8 kalP2PGetWscMode(IN P_GLUE_INFO_T prGlueInfo); -+ -+UINT_16 kalP2PCalWSC_IELen(IN P_GLUE_INFO_T prGlueInfo, IN UINT_8 ucType); -+ -+VOID kalP2PGenWSC_IE(IN P_GLUE_INFO_T prGlueInfo, IN UINT_8 ucType, IN PUINT_8 pucBuffer); -+ -+VOID kalP2PUpdateWSC_IE(IN P_GLUE_INFO_T prGlueInfo, IN UINT_8 ucType, IN PUINT_8 pucBuffer, IN UINT_16 u2BufferLength); -+ -+BOOLEAN kalP2PIndicateFound(IN P_GLUE_INFO_T prGlueInfo); -+ -+VOID kalP2PIndicateConnReq(IN P_GLUE_INFO_T prGlueInfo, IN PUINT_8 pucDevName, IN INT_32 u4NameLength, -+ IN PARAM_MAC_ADDRESS rPeerAddr, IN UINT_8 ucDevType, /* 0: P2P Device / 1: GC / 2: GO */ -+ IN INT_32 i4ConfigMethod, IN INT_32 i4ActiveConfigMethod); -+ -+VOID kalP2PInvitationStatus(IN P_GLUE_INFO_T prGlueInfo, IN UINT_32 u4InvStatus); -+ -+VOID -+kalP2PInvitationIndication(IN P_GLUE_INFO_T prGlueInfo, -+ IN P_P2P_DEVICE_DESC_T prP2pDevDesc, -+ IN PUINT_8 pucSsid, -+ IN UINT_8 ucSsidLen, -+ IN UINT_8 ucOperatingChnl, IN UINT_8 ucInvitationType, IN PUINT_8 pucGroupBssid); -+ -+struct net_device *kalP2PGetDevHdlr(P_GLUE_INFO_T prGlueInfo); -+ -+VOID -+kalGetChnlList(IN P_GLUE_INFO_T prGlueInfo, -+ IN ENUM_BAND_T eSpecificBand, -+ IN UINT_8 ucMaxChannelNum, IN PUINT_8 pucNumOfChannel, IN P_RF_CHANNEL_INFO_T paucChannelList); -+ -+#if CFG_SUPPORT_ANTI_PIRACY -+VOID kalP2PIndicateSecCheckRsp(IN P_GLUE_INFO_T prGlueInfo, IN PUINT_8 pucRsp, IN UINT_16 u2RspLen); -+#endif -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+VOID -+kalP2PIndicateChannelReady(IN P_GLUE_INFO_T prGlueInfo, -+ IN UINT_64 u8SeqNum, -+ IN UINT_32 u4ChannelNum, -+ IN ENUM_BAND_T eBand, IN ENUM_CHNL_EXT_T eSco, IN UINT_32 u4Duration); -+ -+VOID kalP2PIndicateScanDone(IN P_GLUE_INFO_T prGlueInfo, IN BOOLEAN fgIsAbort); -+ -+VOID -+kalP2PIndicateBssInfo(IN P_GLUE_INFO_T prGlueInfo, -+ IN PUINT_8 pucFrameBuf, -+ IN UINT_32 u4BufLen, IN P_RF_CHANNEL_INFO_T prChannelInfo, IN INT_32 i4SignalStrength); -+ -+VOID kalP2PIndicateRxMgmtFrame(IN P_GLUE_INFO_T prGlueInfo, IN P_SW_RFB_T prSwRfb); -+ -+VOID -+kalP2PIndicateMgmtTxStatus(IN P_GLUE_INFO_T prGlueInfo, -+ IN UINT_64 u8Cookie, IN BOOLEAN fgIsAck, IN PUINT_8 pucFrameBuf, IN UINT_32 u4FrameLen); -+ -+VOID kalP2PIndicateChannelExpired(IN P_GLUE_INFO_T prGlueInfo, IN P_P2P_CHNL_REQ_INFO_T prChnlReqInfo); -+ -+VOID -+kalP2PGCIndicateConnectionStatus(IN P_GLUE_INFO_T prGlueInfo, -+ IN P_P2P_CONNECTION_REQ_INFO_T prP2pConnInfo, -+ IN PUINT_8 pucRxIEBuf, IN UINT_16 u2RxIELen, IN UINT_16 u2StatusReason, -+ IN WLAN_STATUS eStatus); -+ -+VOID kalP2PGOStationUpdate(IN P_GLUE_INFO_T prGlueInfo, IN P_STA_RECORD_T prCliStaRec, IN BOOLEAN fgIsNew); -+ -+INT_32 kalP2PSetBlackList(IN P_GLUE_INFO_T prGlueInfo, IN PARAM_MAC_ADDRESS rbssid, IN BOOLEAN fgIsblock); -+ -+BOOLEAN kalP2PCmpBlackList(IN P_GLUE_INFO_T prGlueInfo, IN PARAM_MAC_ADDRESS rbssid); -+ -+VOID kalP2PSetMaxClients(IN P_GLUE_INFO_T prGlueInfo, IN UINT_32 u4MaxClient); -+ -+BOOLEAN kalP2PMaxClients(IN P_GLUE_INFO_T prGlueInfo, IN UINT_32 u4NumClient); -+ -+#endif /* _GL_P2P_KAL_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_p2p_os.h b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_p2p_os.h -new file mode 100644 -index 000000000000..e5026e7e6eec ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_p2p_os.h -@@ -0,0 +1,242 @@ -+/* -+** Id: -+//Department/DaVinci/TRUNK/MT6620_5931_WiFi_Driver/os/linux/include/gl_p2p_os.h#28 -+*/ -+ -+/*! \file gl_p2p_os.h -+ \brief List the external reference to OS for p2p GLUE Layer. -+ -+ In this file we define the data structure - GLUE_INFO_T to store those objects -+ we acquired from OS - e.g. TIMER, SPINLOCK, NET DEVICE ... . And all the -+ external reference (header file, extern func() ..) to OS for GLUE Layer should -+ also list down here. -+*/ -+ -+#ifndef _GL_P2P_OS_H -+#define _GL_P2P_OS_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include -+#if CFG_ENABLE_WIFI_DIRECT_CFG_80211 -+#include -+#endif -+ -+#include "wlan_oid.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+struct _GL_P2P_INFO_T { -+ -+ /* Device handle */ -+ struct net_device *prDevHandler; -+ -+#if CFG_ENABLE_WIFI_DIRECT_CFG_80211 -+ /* cfg80211 */ -+ struct wireless_dev *prWdev; -+ -+ struct cfg80211_scan_request *prScanRequest; -+ -+ UINT_64 u8Cookie; -+ -+ /* Generation for station list update. */ -+ INT_32 i4Generation; -+ -+ UINT_32 u4OsMgmtFrameFilter; -+ -+#endif -+ -+ /* Device statistics */ -+ struct net_device_stats rNetDevStats; -+ -+ /* glue layer variables */ -+ UINT_32 u4FreqInKHz; /* frequency */ -+ UINT_8 ucRole; /* 0: P2P Device, 1: Group Client, 2: Group Owner */ -+ UINT_8 ucIntent; /* range: 0-15 */ -+ UINT_8 ucScanMode; /* 0: Search & Listen, 1: Scan without probe response */ -+ -+ ENUM_PARAM_MEDIA_STATE_T eState; -+ UINT_32 u4PacketFilter; -+ PARAM_MAC_ADDRESS aucMCAddrList[MAX_NUM_GROUP_ADDR]; -+ -+ /* connection-requested peer information */ -+ UINT_8 aucConnReqDevName[32]; -+ INT_32 u4ConnReqNameLength; -+ PARAM_MAC_ADDRESS rConnReqPeerAddr; -+ PARAM_MAC_ADDRESS rConnReqGroupAddr; /* For invitation group. */ -+ UINT_8 ucConnReqDevType; -+ INT_32 i4ConnReqConfigMethod; -+ INT_32 i4ConnReqActiveConfigMethod; -+ -+ UINT_32 u4CipherPairwise; -+ UINT_8 ucWSCRunning; -+ -+ UINT_8 aucWSCIE[3][400]; /* 0 for beacon, 1 for probe req, 2 for probe response */ -+ UINT_16 u2WSCIELen[3]; -+ -+#if CFG_SUPPORT_WFD -+ UINT_8 aucVenderIE[1024]; /* Save the other IE for prove resp */ -+ UINT_16 u2VenderIELen; -+#endif -+ -+ UINT_8 ucOperatingChnl; -+ UINT_8 ucInvitationType; -+ -+ UINT_32 u4InvStatus; -+ -+ /* For SET_STRUCT/GET_STRUCT */ -+ UINT_8 aucOidBuf[4096]; -+ -+#if 1 /* CFG_SUPPORT_ANTI_PIRACY */ -+ UINT_8 aucSecCheck[256]; -+ UINT_8 aucSecCheckRsp[256]; -+#endif -+ -+ /* Hotspot Client Management */ -+ PARAM_MAC_ADDRESS aucblackMACList[8]; -+ UINT_8 ucMaxClients; -+ -+#if CFG_SUPPORT_HOTSPOT_OPTIMIZATION -+ UINT_32 u4PsLevel; -+#endif -+}; -+ -+#ifdef CONFIG_NL80211_TESTMODE -+typedef struct _NL80211_DRIVER_TEST_PRE_PARAMS { -+ UINT_16 idx_mode; -+ UINT_16 idx; -+ UINT_32 value; -+} NL80211_DRIVER_TEST_PRE_PARAMS, *P_NL80211_DRIVER_TEST_PRE_PARAMS; -+ -+typedef struct _NL80211_DRIVER_TEST_PARAMS { -+ UINT_32 index; -+ UINT_32 buflen; -+} NL80211_DRIVER_TEST_PARAMS, *P_NL80211_DRIVER_TEST_PARAMS; -+ -+/* P2P Sigma*/ -+typedef struct _NL80211_DRIVER_P2P_SIGMA_PARAMS { -+ NL80211_DRIVER_TEST_PARAMS hdr; -+ UINT_32 idx; -+ UINT_32 value; -+} NL80211_DRIVER_P2P_SIGMA_PARAMS, *P_NL80211_DRIVER_P2P_SIGMA_PARAMS; -+ -+/* Hotspot Client Management */ -+typedef struct _NL80211_DRIVER_HOTSPOT_BLOCK_PARAMS { -+ NL80211_DRIVER_TEST_PARAMS hdr; -+ UINT_8 ucblocked; -+ UINT_8 aucBssid[MAC_ADDR_LEN]; -+} NL80211_DRIVER_HOTSPOT_BLOCK_PARAMS, *P_NL80211_DRIVER_HOTSPOT_BLOCK_PARAMS; -+ -+#if CFG_SUPPORT_WFD -+typedef struct _NL80211_DRIVER_WFD_PARAMS { -+ NL80211_DRIVER_TEST_PARAMS hdr; -+ UINT_32 WfdCmdType; -+ UINT_8 WfdEnable; -+ UINT_8 WfdCoupleSinkStatus; -+ UINT_8 WfdSessionAvailable; -+ UINT_8 WfdSigmaMode; -+ UINT_16 WfdDevInfo; -+ UINT_16 WfdControlPort; -+ UINT_16 WfdMaximumTp; -+ UINT_16 WfdExtendCap; -+ UINT_8 WfdCoupleSinkAddress[MAC_ADDR_LEN]; -+ UINT_8 WfdAssociatedBssid[MAC_ADDR_LEN]; -+ UINT_8 WfdVideoIp[4]; -+ UINT_8 WfdAudioIp[4]; -+ UINT_16 WfdVideoPort; -+ UINT_16 WfdAudioPort; -+ UINT_32 WfdFlag; -+ UINT_32 WfdPolicy; -+ UINT_32 WfdState; -+ UINT_8 WfdSessionInformationIE[24 * 8]; /* Include Subelement ID, length */ -+ UINT_16 WfdSessionInformationIELen; -+ UINT_8 aucReserved1[2]; -+ UINT_8 aucWfdPrimarySinkMac[MAC_ADDR_LEN]; -+ UINT_8 aucWfdSecondarySinkMac[MAC_ADDR_LEN]; -+ UINT_32 WfdAdvanceFlag; -+ /* Group 1 64 bytes */ -+ UINT_8 aucWfdLocalIp[4]; -+ UINT_16 WfdLifetimeAc2; /* Unit is 2 TU */ -+ UINT_16 WfdLifetimeAc3; /* Unit is 2 TU */ -+ UINT_16 WfdCounterThreshold; /* Unit is ms */ -+ UINT_8 aucReserved2[54]; -+ /* Group 3 64 bytes */ -+ UINT_8 aucReserved3[64]; -+ /* Group 3 64 bytes */ -+ UINT_8 aucReserved4[64]; -+} NL80211_DRIVER_WFD_PARAMS, *P_NL80211_DRIVER_WFD_PARAMS; -+#endif -+#endif -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+BOOLEAN p2pLaunch(P_GLUE_INFO_T prGlueInfo); -+ -+BOOLEAN p2pRemove(P_GLUE_INFO_T prGlueInfo); -+ -+VOID p2pSetMode(IN BOOLEAN fgIsAPMOde); -+ -+BOOLEAN glRegisterP2P(P_GLUE_INFO_T prGlueInfo, const char *prDevName, BOOLEAN fgIsApMode); -+ -+VOID p2pEalySuspendReg(P_GLUE_INFO_T prGlueInfo, BOOLEAN fgIsEnable); -+ -+BOOLEAN glUnregisterP2P(P_GLUE_INFO_T prGlueInfo); -+ -+BOOLEAN p2pNetRegister(P_GLUE_INFO_T prGlueInfo, BOOLEAN fgIsRtnlLockAcquired); -+ -+BOOLEAN p2pNetUnregister(P_GLUE_INFO_T prGlueInfo, BOOLEAN fgIsRtnlLockAcquired); -+ -+BOOLEAN p2pStopImmediate(P_GLUE_INFO_T prGlueInfo); -+ -+BOOLEAN p2PFreeInfo(P_GLUE_INFO_T prGlueInfo); -+ -+BOOLEAN glP2pCreateWirelessDevice(P_GLUE_INFO_T prGlueInfo); -+ -+VOID glP2pDestroyWirelessDevice(VOID); -+ -+VOID p2pSetMulticastListWorkQueueWrapper(P_GLUE_INFO_T prGlueInfo); -+ -+#endif -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_rst.h b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_rst.h -new file mode 100644 -index 000000000000..f24ceee9e921 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_rst.h -@@ -0,0 +1,133 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux/include/gl_rst.h#1 -+*/ -+ -+/*! \file gl_rst.h -+ \brief Declaration of functions and finite state machine for -+ MT6620 Whole-Chip Reset Mechanism -+*/ -+ -+#ifndef _GL_RST_H -+#define _GL_RST_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "gl_typedef.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+#if 1 -+typedef INT_32(*wmt_wlan_probe_cb) (VOID); -+typedef INT_32(*wmt_wlan_remove_cb) (VOID); -+typedef INT_32(*wmt_wlan_bus_cnt_get_cb) (VOID); -+typedef INT_32(*wmt_wlan_bus_cnt_clr_cb) (VOID); -+ -+typedef struct _MTK_WCN_WMT_WLAN_CB_INFO { -+ wmt_wlan_probe_cb wlan_probe_cb; -+ wmt_wlan_remove_cb wlan_remove_cb; -+ wmt_wlan_bus_cnt_get_cb wlan_bus_cnt_get_cb; -+ wmt_wlan_bus_cnt_clr_cb wlan_bus_cnt_clr_cb; -+} MTK_WCN_WMT_WLAN_CB_INFO, *P_MTK_WCN_WMT_WLAN_CB_INFO; -+ -+extern INT_32 mtk_wcn_wmt_wlan_reg(P_MTK_WCN_WMT_WLAN_CB_INFO pWmtWlanCbInfo); -+extern INT_32 mtk_wcn_wmt_wlan_unreg(VOID); -+#endif -+ -+typedef enum _ENUM_RESET_STATUS_T { -+ RESET_FAIL, -+ RESET_SUCCESS -+} ENUM_RESET_STATUS_T; -+ -+typedef struct _RESET_STRUCT_T { -+ ENUM_RESET_STATUS_T rst_data; -+ struct work_struct rst_work; -+} RESET_STRUCT_T; -+ -+typedef enum _ENUM_WMTRSTMSG_TYPE_T { -+ WMTRSTMSG_RESET_START = 0x0, -+ WMTRSTMSG_RESET_END = 0x1, -+ WMTRSTMSG_RESET_END_FAIL = 0x2, -+ WMTRSTMSG_RESET_MAX, -+ WMTRSTMSG_RESET_INVALID = 0xff -+} ENUM_WMTRSTMSG_TYPE_T, *P_ENUM_WMTRSTMSG_TYPE_T; -+ -+typedef void (*PF_WMT_CB) (ENUM_WMTDRV_TYPE_T, /* Source driver type */ -+ ENUM_WMTDRV_TYPE_T, /* Destination driver type */ -+ ENUM_WMTMSG_TYPE_T, /* Message type */ -+ void *, /* READ-ONLY buffer. Buffer is allocated and freed by WMT_drv. Client -+ can't touch this buffer after this function return. */ -+ unsigned int /* Buffer size in unit of byte */ -+); -+ -+/******************************************************************************* -+* E X T E R N A L F U N C T I O N S -+******************************************************************************** -+*/ -+#define glDoChipReset() \ -+ do { \ -+ if (!kalStrnCmp(current->comm, "mtk_wmtd", 8)) { \ -+ g_IsNeedDoChipReset = 1; \ -+ DBGLOG(INIT, ERROR, "forbid core dump in mtk_wmtd %s line %d\n", __func__, __LINE__); \ -+ break; \ -+ } \ -+ DBGLOG(INIT, ERROR, "Do core dump and chip reset in %s line %d\n", __func__, __LINE__); \ -+ mtk_wcn_wmt_assert(WMTDRV_TYPE_WIFI, 0x40); \ -+ } while (0) -+ -+#if CFG_CHIP_RESET_SUPPORT -+extern int mtk_wcn_wmt_msgcb_reg(ENUM_WMTDRV_TYPE_T eType, PF_WMT_CB pCb); -+extern int mtk_wcn_wmt_msgcb_unreg(ENUM_WMTDRV_TYPE_T eType); -+extern int wifi_reset_start(void); -+extern int wifi_reset_end(ENUM_RESET_STATUS_T); -+#endif -+extern MTK_WCN_BOOL mtk_wcn_wmt_assert(ENUM_WMTDRV_TYPE_T type, UINT32 reason); -+extern BOOLEAN mtk_wcn_set_connsys_power_off_flag(BOOLEAN value); -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+extern UINT_32 g_IsNeedDoChipReset; -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+VOID glResetInit(VOID); -+ -+VOID glResetUninit(VOID); -+ -+VOID glSendResetRequest(VOID); -+ -+BOOLEAN kalIsResetting(VOID); -+ -+#endif /* _GL_RST_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_sec.h b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_sec.h -new file mode 100644 -index 000000000000..3cc57780f201 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_sec.h -@@ -0,0 +1,21 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux/include/gl_sec.h#1 -+*/ -+ -+/*! \file p2p_fsm.h -+ \brief Declaration of functions and finite state machine for P2P Module. -+ -+ Declaration of functions and finite state machine for P2P Module. -+*/ -+ -+#ifndef _GL_SEC_H -+#define _GL_SEC_H -+ -+extern void handle_sec_msg_1(unsigned char *msg_in, int msg_in_len, unsigned char *msg_out, int *msg_out_len); -+extern void handle_sec_msg_2(unsigned char *msg_in, int msg_in_len, unsigned char *msg_out, int *msg_out_len); -+extern void handle_sec_msg_3(unsigned char *msg_in, int msg_in_len, unsigned char *msg_out, int *msg_out_len); -+extern void handle_sec_msg_4(unsigned char *msg_in, int msg_in_len, unsigned char *msg_out, int *msg_out_len); -+extern void handle_sec_msg_5(unsigned char *msg_in, int msg_in_len, unsigned char *msg_out, int *msg_out_len); -+extern void handle_sec_msg_final(unsigned char *msg_in, int msg_in_len, unsigned char *msg_out, int *msg_out_len); -+ -+#endif /* _GL_SEC_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_typedef.h b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_typedef.h -new file mode 100644 -index 000000000000..e9aa3e849eb2 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_typedef.h -@@ -0,0 +1,298 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux/include/gl_typedef.h#1 -+*/ -+ -+/*! \file gl_typedef.h -+ \brief Definition of basic data type(os dependent). -+ -+ In this file we define the basic data type. -+*/ -+ -+/* -+** Log: gl_typedef.h -+ * -+ * 06 22 2012 cp.wu -+ * [WCXRP00001257] [MT6620][MT5931][MT6628][Driver][Linux] Modify KAL_HZ to align ms accuracy -+ * modify KAL_HZ to (1000) for correct definition. -+ * -+ * 03 21 2011 cp.wu -+ * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer -+ * portability improvement -+ * -+ * 02 15 2011 jeffrey.chang -+ * NULL -+ * to support early suspend in android -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 03 24 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * initial import for Linux port -+** \main\maintrunk.MT5921\6 2009-08-18 22:57:14 GMT mtk01090 -+** Add Linux SDIO (with mmc core) support. -+** Add Linux 2.6.21, 2.6.25, 2.6.26. -+** Fix compile warning in Linux. -+** \main\maintrunk.MT5921\5 2008-09-22 23:19:30 GMT mtk01461 -+** Update comment for code review -+** \main\maintrunk.MT5921\4 2008-09-05 17:25:16 GMT mtk01461 -+** Update Driver for Code Review -+** \main\maintrunk.MT5921\3 2007-11-09 11:00:50 GMT mtk01425 -+** 1. Use macro to unify network-to-host and host-to-network related functions -+** Revision 1.3 2007/06/27 02:18:51 MTK01461 -+** Update SCAN_FSM, Initial(Can Load Module), Proc(Can do Reg R/W), TX API -+** -+** Revision 1.2 2007/06/25 06:16:24 MTK01461 -+** Update illustrations, gl_init.c, gl_kal.c, gl_kal.h, gl_os.h and RX API -+** -+*/ -+ -+#ifndef _GL_TYPEDEF_H -+#define _GL_TYPEDEF_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+/* Define HZ of timer tick for function kalGetTimeTick() */ -+#define KAL_HZ (1000) -+ -+/* Miscellaneous Equates */ -+#ifndef FALSE -+#define FALSE ((BOOLEAN) 0) -+#define TRUE ((BOOLEAN) 1) -+#endif /* FALSE */ -+ -+#ifndef NULL -+#if defined(__cplusplus) -+#define NULL 0 -+#else -+#define NULL ((void *) 0) -+#endif -+#endif -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+/* Type definition for void */ -+/*mach/mt_typedefs.h define _TYPEDEFS_H, to avoid compile error*/ -+#ifndef _TYPEDEFS_H -+typedef void VOID; -+#endif -+typedef void *PVOID, **PPVOID; -+ -+/* Type definition for Boolean */ -+typedef unsigned char BOOLEAN, *PBOOLEAN; -+ -+/* Type definition for signed integers */ -+typedef signed char CHAR, *PCHAR, **PPCHAR; -+typedef signed char INT_8, *PINT_8, **PPINT_8; -+typedef signed short INT_16, *PINT_16, **PPINT_16; -+typedef signed int INT_32, *PINT_32, **PPINT_32; -+typedef long LONG, *PLONG, **PPLONG; -+typedef signed long long INT_64, *PINT_64, **PPINT_64; -+ -+/* Type definition for unsigned integers */ -+typedef unsigned char UCHAR, *PUCHAR, **PPUCHAR; -+typedef unsigned char UINT_8, *PUINT_8, **PPUINT_8, *P_UINT_8; -+typedef unsigned short UINT_16, *PUINT_16, **PPUINT_16; -+typedef unsigned int UINT32, *PUINT32; -+typedef unsigned int UINT_32, *PUINT_32, **PPUINT_32; -+typedef unsigned long ULONG, *PULONG, **PPULONG; -+typedef unsigned long long UINT_64, *PUINT_64, **PPUINT_64; -+ -+typedef unsigned int OS_SYSTIME, *POS_SYSTIME, **PPOS_SYSTIME; -+ -+#ifndef _TYPEDEFS_H -+typedef signed char INT8, *PINT8; -+typedef signed short INT16, *PINT16; -+typedef signed int INT32, *PINT32; -+typedef unsigned char UINT8, *PUINT8; -+typedef unsigned short UINT16, *PUINT16; -+typedef unsigned int UINT32, *PUINT32; -+#endif -+ -+/* Type definition of large integer (64bits) union to be comptaible with -+ * Windows definition, so we won't apply our own coding style to these data types. -+ * NOTE: LARGE_INTEGER must NOT be floating variable. -+ * : Check for big-endian compatibility. -+ */ -+typedef union _LARGE_INTEGER { -+ struct { -+ UINT_32 LowPart; -+ INT_32 HighPart; -+ } u; -+ INT_64 QuadPart; -+} LARGE_INTEGER, *PLARGE_INTEGER; -+ -+typedef union _ULARGE_INTEGER { -+ struct { -+ UINT_32 LowPart; -+ UINT_32 HighPart; -+ } u; -+ UINT_64 QuadPart; -+} ULARGE_INTEGER, *PULARGE_INTEGER; -+ -+typedef INT_32(*probe_card) (PVOID pvData); -+typedef VOID(*remove_card) (VOID); -+ -+/* duplicated from wmt_exp.h for better driver isolation */ -+typedef enum _ENUM_WMTDRV_TYPE_T { -+ WMTDRV_TYPE_BT = 0, -+ WMTDRV_TYPE_FM = 1, -+ WMTDRV_TYPE_GPS = 2, -+ WMTDRV_TYPE_WIFI = 3, -+ WMTDRV_TYPE_WMT = 4, -+ WMTDRV_TYPE_STP = 5, -+ WMTDRV_TYPE_SDIO1 = 6, -+ WMTDRV_TYPE_SDIO2 = 7, -+ WMTDRV_TYPE_LPBK = 8, -+ WMTDRV_TYPE_MAX -+} ENUM_WMTDRV_TYPE_T, *P_ENUM_WMTDRV_TYPE_T; -+ -+typedef enum _ENUM_WMTMSG_TYPE_T { -+ WMTMSG_TYPE_POWER_ON = 0, -+ WMTMSG_TYPE_POWER_OFF = 1, -+ WMTMSG_TYPE_RESET = 2, -+ WMTMSG_TYPE_STP_RDY = 3, -+ WMTMSG_TYPE_HW_FUNC_ON = 4, -+ WMTMSG_TYPE_MAX -+} ENUM_WMTMSG_TYPE_T, *P_ENUM_WMTMSG_TYPE_T; -+ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+#define IN /* volatile */ -+#define OUT /* volatile */ -+ -+#define __KAL_ATTRIB_PACKED__ __attribute__((__packed__)) -+#define __KAL_ATTRIB_ALIGN_4__ __aligned(4) -+ -+#ifndef BIT -+#define BIT(n) ((UINT_32) 1U << (n)) -+#endif /* BIT */ -+ -+#ifndef BITS -+/* bits range: for example BITS(16,23) = 0xFF0000 -+ * ==> (BIT(m)-1) = 0x0000FFFF ~(BIT(m)-1) => 0xFFFF0000 -+ * ==> (BIT(n+1)-1) = 0x00FFFFFF -+ */ -+#define BITS(m, n) (~(BIT(m)-1) & ((BIT(n) - 1) | BIT(n))) -+#endif /* BIT */ -+ -+/* This macro returns the byte offset of a named field in a known structure -+ type. -+ _type - structure name, -+ _field - field name of the structure */ -+#ifndef OFFSET_OF -+#define OFFSET_OF(_type, _field) ((ULONG)&(((_type *)0)->_field)) -+#endif /* OFFSET_OF */ -+ -+/* This macro returns the base address of an instance of a structure -+ * given the type of the structure and the address of a field within the -+ * containing structure. -+ * _addrOfField - address of current field of the structure, -+ * _type - structure name, -+ * _field - field name of the structure -+ */ -+#ifndef ENTRY_OF -+#define ENTRY_OF(_addrOfField, _type, _field) \ -+ ((_type *)((PINT_8)(_addrOfField) - (PINT_8)OFFSET_OF(_type, _field))) -+#endif /* ENTRY_OF */ -+ -+/* This macro align the input value to the DW boundary. -+ * _value - value need to check -+ */ -+#ifndef ALIGN_4 -+#define ALIGN_4(_value) (((_value) + 3) & ~3u) -+#endif /* ALIGN_4 */ -+ -+/* This macro check the DW alignment of the input value. -+ * _value - value of address need to check -+ */ -+#ifndef IS_ALIGN_4 -+#define IS_ALIGN_4(_value) (((_value) & 0x3) ? FALSE : TRUE) -+#endif /* IS_ALIGN_4 */ -+ -+#ifndef IS_NOT_ALIGN_4 -+#define IS_NOT_ALIGN_4(_value) (((_value) & 0x3) ? TRUE : FALSE) -+#endif /* IS_NOT_ALIGN_4 */ -+ -+/* This macro evaluate the input length in unit of Double Word(4 Bytes). -+ * _value - value in unit of Byte, output will round up to DW boundary. -+ */ -+#ifndef BYTE_TO_DWORD -+#define BYTE_TO_DWORD(_value) ((_value + 3) >> 2) -+#endif /* BYTE_TO_DWORD */ -+ -+/* This macro evaluate the input length in unit of Byte. -+ * _value - value in unit of DW, output is in unit of Byte. -+ */ -+#ifndef DWORD_TO_BYTE -+#define DWORD_TO_BYTE(_value) ((_value) << 2) -+#endif /* DWORD_TO_BYTE */ -+ -+#if 1 /* Little-Endian */ -+#define CONST_NTOHS(_x) ntohs(_x) -+ -+#define CONST_HTONS(_x) htons(_x) -+ -+#define NTOHS(_x) ntohs(_x) -+ -+#define HTONS(_x) htons(_x) -+ -+#define NTOHL(_x) ntohl(_x) -+ -+#define HTONL(_x) htonl(_x) -+ -+#else /* Big-Endian */ -+ -+#define CONST_NTOHS(_x) -+ -+#define CONST_HTONS(_x) -+ -+#define NTOHS(_x) -+ -+#define HTONS(_x) -+ -+#endif -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif /* _GL_TYPEDEF_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_vendor.h b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_vendor.h -new file mode 100644 -index 000000000000..d8d5b0fb6740 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_vendor.h -@@ -0,0 +1,619 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux/include/gl_vendor.h#1 -+*/ -+ -+/*! \file gl_vendor.h -+ \brief This file is for Portable Driver linux gl_vendor support. -+*/ -+ -+/* -+** Log: gl_vendor.h -+** -+** 10 14 2014 -+** add vendor declaration -+** -+ * -+*/ -+ -+#ifndef _GL_VENDOR_H -+#define _GL_VENDOR_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "gl_os.h" -+ -+#include "wlan_lib.h" -+#include "gl_wext.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+#define GOOGLE_OUI 0x001A11 -+ -+typedef enum { -+ /* Don't use 0 as a valid subcommand */ -+ ANDROID_NL80211_SUBCMD_UNSPECIFIED, -+ -+ /* Define all vendor startup commands between 0x0 and 0x0FFF */ -+ ANDROID_NL80211_SUBCMD_WIFI_RANGE_START = 0x0001, -+ ANDROID_NL80211_SUBCMD_WIFI_RANGE_END = 0x0FFF, -+ -+ /* Define all GScan related commands between 0x1000 and 0x10FF */ -+ ANDROID_NL80211_SUBCMD_GSCAN_RANGE_START = 0x1000, -+ ANDROID_NL80211_SUBCMD_GSCAN_RANGE_END = 0x10FF, -+ -+ /* Define all RTT related commands between 0x1100 and 0x11FF */ -+ ANDROID_NL80211_SUBCMD_RTT_RANGE_START = 0x1100, -+ ANDROID_NL80211_SUBCMD_RTT_RANGE_END = 0x11FF, -+ -+ ANDROID_NL80211_SUBCMD_LSTATS_RANGE_START = 0x1200, -+ ANDROID_NL80211_SUBCMD_LSTATS_RANGE_END = 0x12FF, -+ -+ /* Define all Logger related commands between 0x1400 and 0x14FF */ -+ ANDROID_NL80211_SUBCMD_DEBUG_RANGE_START = 0x1400, -+ ANDROID_NL80211_SUBCMD_DEBUG_RANGE_END = 0x14FF, -+ -+ /* Define all wifi offload related commands between 0x1600 and 0x16FF */ -+ ANDROID_NL80211_SUBCMD_WIFI_OFFLOAD_RANGE_START = 0x1600, -+ ANDROID_NL80211_SUBCMD_WIFI_OFFLOAD_RANGE_END = 0x16FF, -+ -+ /* This is reserved for future usage */ -+ -+} ANDROID_VENDOR_SUB_COMMAND; -+ -+typedef enum { -+ WIFI_SUBCMD_GET_CHANNEL_LIST = ANDROID_NL80211_SUBCMD_WIFI_RANGE_START, -+ -+ WIFI_SUBCMD_GET_FEATURE_SET, /* 0x0001 */ -+ WIFI_SUBCMD_GET_FEATURE_SET_MATRIX, /* 0x0002 */ -+ WIFI_SUBCMD_SET_PNO_RANDOM_MAC_OUI, /* 0x0003 */ -+ WIFI_SUBCMD_NODFS_SET, /* 0x0004 */ -+ WIFI_SUBCMD_SET_COUNTRY_CODE, /* 0x0005 */ -+ /* Add more sub commands here */ -+ -+} WIFI_SUB_COMMAND; -+ -+typedef enum { -+ GSCAN_SUBCMD_GET_CAPABILITIES = ANDROID_NL80211_SUBCMD_GSCAN_RANGE_START, -+ -+ GSCAN_SUBCMD_SET_CONFIG, /* 0x1001 */ -+ GSCAN_SUBCMD_SET_SCAN_CONFIG, /* 0x1002 */ -+ GSCAN_SUBCMD_ENABLE_GSCAN, /* 0x1003 */ -+ GSCAN_SUBCMD_GET_SCAN_RESULTS, /* 0x1004 */ -+ GSCAN_SUBCMD_SCAN_RESULTS, /* 0x1005 */ -+ -+ GSCAN_SUBCMD_SET_HOTLIST, /* 0x1006 */ -+ -+ GSCAN_SUBCMD_SET_SIGNIFICANT_CHANGE_CONFIG, /* 0x1007 */ -+ GSCAN_SUBCMD_ENABLE_FULL_SCAN_RESULTS, /* 0x1008 */ -+ /* Add more sub commands here */ -+ -+} GSCAN_SUB_COMMAND; -+ -+typedef enum { -+ RTT_SUBCMD_SET_CONFIG = ANDROID_NL80211_SUBCMD_RTT_RANGE_START, -+ RTT_SUBCMD_CANCEL_CONFIG, -+ RTT_SUBCMD_GETCAPABILITY, -+} RTT_SUB_COMMAND; -+ -+typedef enum { -+ LSTATS_SUBCMD_GET_INFO = ANDROID_NL80211_SUBCMD_LSTATS_RANGE_START, -+} LSTATS_SUB_COMMAND; -+ -+typedef enum { -+ GSCAN_EVENT_SIGNIFICANT_CHANGE_RESULTS, -+ GSCAN_EVENT_HOTLIST_RESULTS_FOUND, -+ GSCAN_EVENT_SCAN_RESULTS_AVAILABLE, -+ GSCAN_EVENT_FULL_SCAN_RESULTS, -+ RTT_EVENT_COMPLETE, -+ GSCAN_EVENT_COMPLETE_SCAN, -+ GSCAN_EVENT_HOTLIST_RESULTS_LOST -+} WIFI_VENDOR_EVENT; -+ -+typedef enum { -+ WIFI_ATTRIBUTE_BAND, -+ WIFI_ATTRIBUTE_NUM_CHANNELS, -+ WIFI_ATTRIBUTE_CHANNEL_LIST, -+ -+ WIFI_ATTRIBUTE_NUM_FEATURE_SET, -+ WIFI_ATTRIBUTE_FEATURE_SET, -+ WIFI_ATTRIBUTE_PNO_RANDOM_MAC_OUI, -+ WIFI_ATTRIBUTE_NODFS_VALUE, -+ WIFI_ATTRIBUTE_COUNTRY_CODE -+ -+} WIFI_ATTRIBUTE; -+ -+typedef enum { -+ GSCAN_ATTRIBUTE_CAPABILITIES = 1, -+ -+ GSCAN_ATTRIBUTE_NUM_BUCKETS = 10, -+ GSCAN_ATTRIBUTE_BASE_PERIOD, -+ GSCAN_ATTRIBUTE_BUCKETS_BAND, -+ GSCAN_ATTRIBUTE_BUCKET_ID, -+ GSCAN_ATTRIBUTE_BUCKET_PERIOD, -+ GSCAN_ATTRIBUTE_BUCKET_NUM_CHANNELS, -+ GSCAN_ATTRIBUTE_BUCKET_CHANNELS, -+ GSCAN_ATTRIBUTE_NUM_AP_PER_SCAN, -+ GSCAN_ATTRIBUTE_REPORT_THRESHOLD, -+ GSCAN_ATTRIBUTE_NUM_SCANS_TO_CACHE, -+ -+ GSCAN_ATTRIBUTE_ENABLE_FEATURE = 20, -+ GSCAN_ATTRIBUTE_SCAN_RESULTS_COMPLETE, /* indicates no more results */ -+ GSCAN_ATTRIBUTE_FLUSH_FEATURE, /* Flush all the configs */ -+ GSCAN_ENABLE_FULL_SCAN_RESULTS, -+ GSCAN_ATTRIBUTE_REPORT_EVENTS, -+ -+ GSCAN_ATTRIBUTE_NUM_OF_RESULTS = 30, -+ GSCAN_ATTRIBUTE_FLUSH_RESULTS, -+ GSCAN_ATTRIBUTE_SCAN_RESULTS, /* flat array of wifi_scan_result */ -+ GSCAN_ATTRIBUTE_SCAN_ID, /* indicates scan number */ -+ GSCAN_ATTRIBUTE_SCAN_FLAGS, /* indicates if scan was aborted */ -+ GSCAN_ATTRIBUTE_AP_FLAGS, /* flags on significant change event */ -+ -+ GSCAN_ATTRIBUTE_SSID = 40, -+ GSCAN_ATTRIBUTE_BSSID, -+ GSCAN_ATTRIBUTE_CHANNEL, -+ GSCAN_ATTRIBUTE_RSSI, -+ GSCAN_ATTRIBUTE_TIMESTAMP, -+ GSCAN_ATTRIBUTE_RTT, -+ GSCAN_ATTRIBUTE_RTTSD, -+ -+ GSCAN_ATTRIBUTE_HOTLIST_BSSIDS = 50, -+ GSCAN_ATTRIBUTE_RSSI_LOW, -+ GSCAN_ATTRIBUTE_RSSI_HIGH, -+ GSCAN_ATTRIBUTE_HOTLIST_ELEM, -+ GSCAN_ATTRIBUTE_HOTLIST_FLUSH, -+ -+ GSCAN_ATTRIBUTE_RSSI_SAMPLE_SIZE = 60, -+ GSCAN_ATTRIBUTE_LOST_AP_SAMPLE_SIZE, -+ GSCAN_ATTRIBUTE_MIN_BREACHING, -+ GSCAN_ATTRIBUTE_NUM_AP, -+ GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_BSSIDS, -+ GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_FLUSH -+ -+} GSCAN_ATTRIBUTE; -+ -+typedef enum { -+ RTT_ATTRIBUTE_CAPABILITIES = 1, -+ -+ RTT_ATTRIBUTE_TARGET_CNT = 10, -+ RTT_ATTRIBUTE_TARGET_INFO, -+ RTT_ATTRIBUTE_TARGET_MAC, -+ RTT_ATTRIBUTE_TARGET_TYPE, -+ RTT_ATTRIBUTE_TARGET_PEER, -+ RTT_ATTRIBUTE_TARGET_CHAN, -+ RTT_ATTRIBUTE_TARGET_PERIOD, -+ RTT_ATTRIBUTE_TARGET_NUM_BURST, -+ RTT_ATTRIBUTE_TARGET_NUM_FTM_BURST, -+ RTT_ATTRIBUTE_TARGET_NUM_RETRY_FTM, -+ RTT_ATTRIBUTE_TARGET_NUM_RETRY_FTMR, -+ RTT_ATTRIBUTE_TARGET_LCI, -+ RTT_ATTRIBUTE_TARGET_LCR, -+ RTT_ATTRIBUTE_TARGET_BURST_DURATION, -+ RTT_ATTRIBUTE_TARGET_PREAMBLE, -+ RTT_ATTRIBUTE_TARGET_BW, -+ RTT_ATTRIBUTE_RESULTS_COMPLETE = 30, -+ RTT_ATTRIBUTE_RESULTS_PER_TARGET, -+ RTT_ATTRIBUTE_RESULT_CNT, -+ RTT_ATTRIBUTE_RESULT -+} RTT_ATTRIBUTE; -+ -+typedef enum { -+ LSTATS_ATTRIBUTE_STATS = 2, -+} LSTATS_ATTRIBUTE; -+ -+typedef enum { -+ WIFI_BAND_UNSPECIFIED, -+ WIFI_BAND_BG = 1, /* 2.4 GHz */ -+ WIFI_BAND_A = 2, /* 5 GHz without DFS */ -+ WIFI_BAND_A_DFS = 4, /* 5 GHz DFS only */ -+ WIFI_BAND_A_WITH_DFS = 6, /* 5 GHz with DFS */ -+ WIFI_BAND_ABG = 3, /* 2.4 GHz + 5 GHz; no DFS */ -+ WIFI_BAND_ABG_WITH_DFS = 7, /* 2.4 GHz + 5 GHz with DFS */ -+} WIFI_BAND; -+ -+typedef enum { -+ WIFI_SCAN_BUFFER_FULL, -+ WIFI_SCAN_COMPLETE, -+} WIFI_SCAN_EVENT; -+ -+#define GSCAN_MAX_REPORT_THRESHOLD 1024000 -+#define GSCAN_MAX_CHANNELS 8 -+#define GSCAN_MAX_BUCKETS 8 -+#define MAX_HOTLIST_APS 16 -+#define MAX_SIGNIFICANT_CHANGE_APS 16 -+#define PSCAN_MAX_SCAN_CACHE_SIZE 16 -+#define PSCAN_MAX_AP_CACHE_PER_SCAN 16 -+#define PSCAN_VERSION 1 -+ -+#define MAX_BUFFERED_GSCN_RESULTS 5 -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+typedef UINT_64 wifi_timestamp; /* In microseconds (us) */ -+typedef UINT_64 wifi_timespan; /* In nanoseconds (ns) */ -+ -+typedef UINT_8 mac_addr[6]; -+typedef UINT_32 wifi_channel; /* Indicates channel frequency in MHz */ -+typedef INT_32 wifi_rssi; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+typedef struct _PARAM_WIFI_GSCAN_GET_RESULT_PARAMS { -+ UINT_32 get_num; -+ UINT_8 flush; -+} PARAM_WIFI_GSCAN_GET_RESULT_PARAMS, *P_PARAM_WIFI_GSCAN_GET_RESULT_PARAMS; -+ -+typedef struct _PARAM_WIFI_GSCAN_ACTION_CMD_PARAMS { -+ UINT_8 ucPscanAct; -+ UINT_8 aucReserved[3]; -+} PARAM_WIFI_GSCAN_ACTION_CMD_PARAMS, *P_PARAM_WIFI_GSCAN_ACTION_CMD_PARAMS; -+ -+typedef struct _PARAM_WIFI_GSCAN_CAPABILITIES_STRUCT_T { -+ UINT_32 max_scan_cache_size; /* total space allocated for scan (in bytes) */ -+ UINT_32 max_scan_buckets; /* maximum number of channel buckets */ -+ UINT_32 max_ap_cache_per_scan; /* maximum number of APs that can be stored per scan */ -+ UINT_32 max_rssi_sample_size; /* number of RSSI samples used for averaging RSSI */ -+ UINT_32 max_scan_reporting_threshold; /* max possible report_threshold as described */ -+ /* in wifi_scan_cmd_params */ -+ UINT_32 max_hotlist_aps; /* maximum number of entries for hotlist APs */ -+ UINT_32 max_significant_wifi_change_aps; /* maximum number of entries for */ -+ /* significant wifi change APs */ -+ UINT_32 max_bssid_history_entries; /* number of BSSID/RSSI entries that device can hold */ -+} PARAM_WIFI_GSCAN_CAPABILITIES_STRUCT_T, *P_PARAM_WIFI_GSCAN_CAPABILITIES_STRUCT_T; -+ -+typedef struct _PARAM_WIFI_GSCAN_CHANNEL_SPEC { -+ UINT_32 channel; /* frequency */ -+ UINT_32 dwellTimeMs; /* dwell time hint */ -+ UINT_32 passive; /* 0 => active, 1 => passive scan; ignored for DFS */ -+ /* Add channel class */ -+} PARAM_WIFI_GSCAN_CHANNEL_SPEC, *P_PARAM_WIFI_GSCAN_CHANNEL_SPEC; -+ -+typedef struct _PARAM_WIFI_GSCAN_BUCKET_SPEC { -+ UINT_32 bucket; /* bucket index, 0 based */ -+ WIFI_BAND band; /* when UNSPECIFIED, use channel list */ -+ UINT_32 period; /* desired period, in millisecond; if this is too */ -+ /* low, the firmware should choose to generate results as */ -+ /* fast as it can instead of failing the command */ -+ /* report_events semantics - -+ * 0 => report only when scan history is % full -+ * 1 => same as 0 + report a scan completion event after scanning this bucket -+ * 2 => same as 1 + forward scan results (beacons/probe responses + IEs) in real time to HAL -+ * 3 => same as 2 + forward scan results (beacons/probe responses + IEs) in real time to -+ supplicant as well (optional) . */ -+ UINT_8 report_events; -+ -+ UINT_32 num_channels; -+ PARAM_WIFI_GSCAN_CHANNEL_SPEC channels[GSCAN_MAX_CHANNELS]; /* channels to scan; -+ these may include DFS channels */ -+} PARAM_WIFI_GSCAN_BUCKET_SPEC, *P_PARAM_WIFI_GSCAN_BUCKET_SPEC; -+ -+typedef struct _PARAM_WIFI_GSCAN_CMD_PARAMS { -+ UINT_32 base_period; /* base timer period in ms */ -+ UINT_32 max_ap_per_scan; /* number of APs to store in each scan in the */ -+ /* BSSID/RSSI history buffer (keep the highest RSSI APs) */ -+ UINT_32 report_threshold; /* in %, when scan buffer is this much full, wake up AP */ -+ UINT_32 num_scans; -+ UINT_32 num_buckets; -+ PARAM_WIFI_GSCAN_BUCKET_SPEC buckets[GSCAN_MAX_BUCKETS]; -+} PARAM_WIFI_GSCAN_CMD_PARAMS, *P_PARAM_WIFI_GSCAN_CMD_PARAMS; -+ -+typedef struct _PARAM_WIFI_GSCAN_RESULT { -+ wifi_timestamp ts; /* time since boot (in microsecond) when the result was */ -+ /* retrieved */ -+ UINT_8 ssid[32 + 1]; /* null terminated */ -+ mac_addr bssid; -+ wifi_channel channel; /* channel frequency in MHz */ -+ wifi_rssi rssi; /* in db */ -+ wifi_timespan rtt; /* in nanoseconds */ -+ wifi_timespan rtt_sd; /* standard deviation in rtt */ -+ UINT_16 beacon_period; /* period advertised in the beacon */ -+ UINT_16 capability; /* capabilities advertised in the beacon */ -+ UINT_32 ie_length; /* size of the ie_data blob */ -+ UINT_8 ie_data[1]; /* blob of all the information elements found in the */ -+ /* beacon; this data should be a packed list of */ -+ /* wifi_information_element objects, one after the other. */ -+ /* other fields */ -+} PARAM_WIFI_GSCAN_RESULT, *P_PARAM_WIFI_GSCAN_RESULT; -+ -+/* Significant wifi change*/ -+/*typedef struct _PARAM_WIFI_CHANGE_RESULT{ -+ mac_addr bssid; // BSSID -+ wifi_channel channel; // channel frequency in MHz -+ UINT_32 num_rssi; // number of rssi samples -+ wifi_rssi rssi[8]; // RSSI history in db -+} PARAM_WIFI_CHANGE_RESULT, *P_PARAM_WIFI_CHANGE_RESULT;*/ -+ -+typedef struct _PARAM_WIFI_CHANGE_RESULT { -+ UINT_16 flags; -+ UINT_16 channel; -+ mac_addr bssid; /* BSSID */ -+ INT_8 rssi[8]; /* RSSI history in db */ -+} PARAM_WIFI_CHANGE_RESULT, *P_PARAM_WIFI_CHANGE_RESULT; -+ -+typedef struct _PARAM_AP_THRESHOLD { -+ mac_addr bssid; /* AP BSSID */ -+ wifi_rssi low; /* low threshold */ -+ wifi_rssi high; /* high threshold */ -+ wifi_channel channel; /* channel hint */ -+} PARAM_AP_THRESHOLD, *P_PARAM_AP_THRESHOLD; -+ -+typedef struct _PARAM_WIFI_BSSID_HOTLIST { -+ UINT_32 lost_ap_sample_size; -+ UINT_32 num_ap; /* number of hotlist APs */ -+ PARAM_AP_THRESHOLD ap[MAX_HOTLIST_APS]; /* hotlist APs */ -+} PARAM_WIFI_BSSID_HOTLIST, *P_PARAM_WIFI_BSSID_HOTLIST; -+ -+typedef struct _PARAM_WIFI_SIGNIFICANT_CHANGE { -+ UINT_16 rssi_sample_size; /* number of samples for averaging RSSI */ -+ UINT_16 lost_ap_sample_size; /* number of samples to confirm AP loss */ -+ UINT_16 min_breaching; /* number of APs breaching threshold */ -+ UINT_16 num_ap; /* max 64 */ -+ PARAM_AP_THRESHOLD ap[MAX_SIGNIFICANT_CHANGE_APS]; -+} PARAM_WIFI_SIGNIFICANT_CHANGE, *P_PARAM_WIFI_SIGNIFICANT_CHANGE; -+ -+/* RTT Capabilities */ -+typedef struct _PARAM_WIFI_RTT_CAPABILITIES { -+ UINT_8 rtt_one_sided_supported; /* if 1-sided rtt data collection is supported */ -+ UINT_8 rtt_ftm_supported; /* if ftm rtt data collection is supported */ -+ UINT_8 lci_support; /* if initiator supports LCI request. Applies to 2-sided RTT */ -+ UINT_8 lcr_support; /* if initiator supports LCR request. Applies to 2-sided RTT */ -+ UINT_8 preamble_support; /* bit mask indicates what preamble is supported by initiator */ -+ UINT_8 bw_support; /* bit mask indicates what BW is supported by initiator */ -+} PARAM_WIFI_RTT_CAPABILITIES, *P_PARAM_WIFI_RTT_CAPABILITIES; -+ -+/* channel operating width */ -+typedef enum { -+ WIFI_CHAN_WIDTH_20 = 0, -+ WIFI_CHAN_WIDTH_40 = 1, -+ WIFI_CHAN_WIDTH_80 = 2, -+ WIFI_CHAN_WIDTH_160 = 3, -+ WIFI_CHAN_WIDTH_80P80 = 4, -+ WIFI_CHAN_WIDTH_5 = 5, -+ WIFI_CHAN_WIDTH_10 = 6, -+ WIFI_CHAN_WIDTH_INVALID = -1 -+} WIFI_CHANNEL_WIDTH; -+ -+/* channel information */ -+typedef struct { -+ WIFI_CHANNEL_WIDTH width; /* channel width (20, 40, 80, 80+80, 160) */ -+ UINT_32 center_freq; /* primary 20 MHz channel */ -+ UINT_32 center_freq0; /* center frequency (MHz) first segment */ -+ UINT_32 center_freq1; /* center frequency (MHz) second segment */ -+} WIFI_CHANNEL_INFO; -+ -+/* channel statistics */ -+typedef struct { -+ WIFI_CHANNEL_INFO channel; /* channel */ -+ UINT_32 on_time; /* msecs the radio is awake (32 bits number accruing over time) */ -+ UINT_32 cca_busy_time; /* msecs the CCA register is busy (32 bits number accruing over time) */ -+} WIFI_CHANNEL_STAT; -+ -+/* radio statistics */ -+typedef struct { -+ UINT_32 radio; /* wifi radio (if multiple radio supported) */ -+ UINT_32 on_time; /* msecs the radio is awake (32 bits number accruing over time) */ -+ UINT_32 tx_time; /* msecs the radio is transmitting (32 bits number accruing over time) */ -+ UINT_32 rx_time; /* msecs the radio is in active receive (32 bits number accruing over time) */ -+ UINT_32 on_time_scan; /* msecs the radio is awake due to all scan (32 bits number accruing over time) */ -+ UINT_32 on_time_nbd; /* msecs the radio is awake due to NAN (32 bits number accruing over time) */ -+ UINT_32 on_time_gscan; /* msecs the radio is awake due to G?scan (32 bits number accruing over time) */ -+ UINT_32 on_time_roam_scan; /* msecs the radio is awake due to roam?scan -+ (32 bits number accruing over time) */ -+ UINT_32 on_time_pno_scan; /* msecs the radio is awake due to PNO scan -+ (32 bits number accruing over time) */ -+ UINT_32 on_time_hs20; /* msecs the radio is awake due to HS2.0 scans and GAS exchange -+ 32 bits number accruing over time) */ -+ UINT_32 num_channels; /* number of channels */ -+ WIFI_CHANNEL_STAT channels[]; /* channel statistics */ -+} WIFI_RADIO_STAT; -+ -+/* wifi rate */ -+typedef struct { -+ UINT_32 preamble:3; /* 0: OFDM, 1:CCK, 2:HT 3:VHT 4..7 reserved */ -+ UINT_32 nss:2; /* 0:1x1, 1:2x2, 3:3x3, 4:4x4 */ -+ UINT_32 bw:3; /* 0:20MHz, 1:40Mhz, 2:80Mhz, 3:160Mhz */ -+ UINT_32 rateMcsIdx:8; /* OFDM/CCK rate code would be as per ieee std in the units of 0.5mbps */ -+ /* HT/VHT it would be mcs index */ -+ UINT_32 reserved:16; /* reserved */ -+ UINT_32 bitrate; /* units of 100 Kbps */ -+} WIFI_RATE; -+ -+/* per rate statistics */ -+typedef struct { -+ WIFI_RATE rate; /* rate information */ -+ UINT_32 tx_mpdu; /* number of successfully transmitted data pkts (ACK rcvd) */ -+ UINT_32 rx_mpdu; /* number of received data pkts */ -+ UINT_32 mpdu_lost; /* number of data packet losses (no ACK) */ -+ UINT_32 retries; /* total number of data pkt retries */ -+ UINT_32 retries_short; /* number of short data pkt retries */ -+ UINT_32 retries_long; /* number of long data pkt retries */ -+} WIFI_RATE_STAT; -+ -+/*wifi_interface_link_layer_info*/ -+typedef enum { -+ WIFI_DISCONNECTED = 0, -+ WIFI_AUTHENTICATING = 1, -+ WIFI_ASSOCIATING = 2, -+ WIFI_ASSOCIATED = 3, -+ WIFI_EAPOL_STARTED = 4, /* if done by firmware/driver */ -+ WIFI_EAPOL_COMPLETED = 5, /* if done by firmware/driver */ -+} WIFI_CONNECTION_STATE; -+ -+typedef enum { -+ WIFI_ROAMING_IDLE = 0, -+ WIFI_ROAMING_ACTIVE = 1, -+} WIFI_ROAM_STATE; -+ -+typedef enum { -+ WIFI_INTERFACE_STA = 0, -+ WIFI_INTERFACE_SOFTAP = 1, -+ WIFI_INTERFACE_IBSS = 2, -+ WIFI_INTERFACE_P2P_CLIENT = 3, -+ WIFI_INTERFACE_P2P_GO = 4, -+ WIFI_INTERFACE_NAN = 5, -+ WIFI_INTERFACE_MESH = 6, -+ WIFI_INTERFACE_UNKNOWN = -1 -+} WIFI_INTERFACE_MODE; -+ -+typedef struct { -+ WIFI_INTERFACE_MODE mode; /* interface mode */ -+ u8 mac_addr[6]; /* interface mac address (self) */ -+ WIFI_CONNECTION_STATE state; /* connection state (valid for STA, CLI only) */ -+ WIFI_ROAM_STATE roaming; /* roaming state */ -+ u32 capabilities; /* WIFI_CAPABILITY_XXX (self) */ -+ u8 ssid[33]; /* null terminated SSID */ -+ u8 bssid[6]; /* bssid */ -+ u8 ap_country_str[3]; /* country string advertised by AP */ -+ u8 country_str[3]; /* country string for this association */ -+} WIFI_INTERFACE_LINK_LAYER_INFO; -+ -+/* access categories */ -+typedef enum { -+ WIFI_AC_VO = 0, -+ WIFI_AC_VI = 1, -+ WIFI_AC_BE = 2, -+ WIFI_AC_BK = 3, -+ WIFI_AC_MAX = 4, -+} WIFI_TRAFFIC_AC; -+ -+/* wifi peer type */ -+typedef enum { -+ WIFI_PEER_STA, -+ WIFI_PEER_AP, -+ WIFI_PEER_P2P_GO, -+ WIFI_PEER_P2P_CLIENT, -+ WIFI_PEER_NAN, -+ WIFI_PEER_TDLS, -+ WIFI_PEER_INVALID, -+} WIFI_PEER_TYPE; -+ -+/* per peer statistics */ -+typedef struct { -+ WIFI_PEER_TYPE type; /* peer type (AP, TDLS, GO etc.) */ -+ UINT_8 peer_mac_address[6]; /* mac address */ -+ UINT_32 capabilities; /* peer WIFI_CAPABILITY_XXX */ -+ UINT_32 num_rate; /* number of rates */ -+ WIFI_RATE_STAT rate_stats[]; /* per rate statistics, number of entries = num_rate */ -+} WIFI_PEER_INFO; -+ -+/* per access category statistics */ -+typedef struct { -+ WIFI_TRAFFIC_AC ac; /* access category (VI, VO, BE, BK) */ -+ UINT_32 tx_mpdu; /* number of successfully transmitted unicast data pkts (ACK rcvd) */ -+ UINT_32 rx_mpdu; /* number of received unicast mpdus */ -+ UINT_32 tx_mcast; /* number of successfully transmitted multicast data packets */ -+ /* STA case: implies ACK received from AP for the unicast packet in which mcast pkt was sent */ -+ UINT_32 rx_mcast; /* number of received multicast data packets */ -+ UINT_32 rx_ampdu; /* number of received unicast a-mpdus */ -+ UINT_32 tx_ampdu; /* number of transmitted unicast a-mpdus */ -+ UINT_32 mpdu_lost; /* number of data pkt losses (no ACK) */ -+ UINT_32 retries; /* total number of data pkt retries */ -+ UINT_32 retries_short; /* number of short data pkt retries */ -+ UINT_32 retries_long; /* number of long data pkt retries */ -+ UINT_32 contention_time_min; /* data pkt min contention time (usecs) */ -+ UINT_32 contention_time_max; /* data pkt max contention time (usecs) */ -+ UINT_32 contention_time_avg; /* data pkt avg contention time (usecs) */ -+ UINT_32 contention_num_samples; /* num of data pkts used for contention statistics */ -+} WIFI_WMM_AC_STAT; -+ -+/* interface statistics */ -+typedef struct { -+ /* wifi_interface_handle iface; // wifi interface */ -+ WIFI_INTERFACE_LINK_LAYER_INFO info; /* current state of the interface */ -+ UINT_32 beacon_rx; /* access point beacon received count from connected AP */ -+ UINT_32 mgmt_rx; /* access point mgmt frames received count from connected AP (including Beacon) */ -+ UINT_32 mgmt_action_rx; /* action frames received count */ -+ UINT_32 mgmt_action_tx; /* action frames transmit count */ -+ wifi_rssi rssi_mgmt; /* access Point Beacon and Management frames RSSI (averaged) */ -+ wifi_rssi rssi_data; /* access Point Data Frames RSSI (averaged) from connected AP */ -+ wifi_rssi rssi_ack; /* access Point ACK RSSI (averaged) from connected AP */ -+ WIFI_WMM_AC_STAT ac[WIFI_AC_MAX]; /* per ac data packet statistics */ -+ UINT_32 num_peers; /* number of peers */ -+ WIFI_PEER_INFO peer_info[]; /* per peer statistics */ -+} WIFI_IFACE_STAT; -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+int mtk_cfg80211_vendor_get_channel_list(struct wiphy *wiphy, struct wireless_dev *wdev, -+ const void *data, int data_len); -+ -+int mtk_cfg80211_vendor_set_country_code(struct wiphy *wiphy, struct wireless_dev *wdev, -+ const void *data, int data_len); -+ -+int mtk_cfg80211_vendor_get_gscan_capabilities(struct wiphy *wiphy, struct wireless_dev *wdev, -+ const void *data, int data_len); -+ -+int mtk_cfg80211_vendor_set_config(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int data_len); -+ -+int mtk_cfg80211_vendor_set_scan_config(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int data_len); -+ -+int mtk_cfg80211_vendor_set_significant_change(struct wiphy *wiphy, struct wireless_dev *wdev, -+ const void *data, int data_len); -+ -+int mtk_cfg80211_vendor_set_hotlist(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int data_len); -+ -+int mtk_cfg80211_vendor_enable_scan(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int data_len); -+ -+int mtk_cfg80211_vendor_enable_full_scan_results(struct wiphy *wiphy, struct wireless_dev *wdev, -+ const void *data, int data_len); -+ -+int mtk_cfg80211_vendor_get_scan_results(struct wiphy *wiphy, struct wireless_dev *wdev, -+ const void *data, int data_len); -+ -+int mtk_cfg80211_vendor_get_rtt_capabilities(struct wiphy *wiphy, struct wireless_dev *wdev, -+ const void *data, int data_len); -+ -+int mtk_cfg80211_vendor_llstats_get_info(struct wiphy *wiphy, struct wireless_dev *wdev, -+ const void *data, int data_len); -+ -+int mtk_cfg80211_vendor_event_complete_scan(struct wiphy *wiphy, struct wireless_dev *wdev, WIFI_SCAN_EVENT complete); -+ -+int mtk_cfg80211_vendor_event_scan_results_available(struct wiphy *wiphy, struct wireless_dev *wdev, UINT_32 num); -+ -+int mtk_cfg80211_vendor_event_full_scan_results(struct wiphy *wiphy, struct wireless_dev *wdev, -+ P_PARAM_WIFI_GSCAN_RESULT pdata, UINT_32 data_len); -+ -+int mtk_cfg80211_vendor_event_significant_change_results(struct wiphy *wiphy, struct wireless_dev *wdev, -+ P_PARAM_WIFI_CHANGE_RESULT pdata, UINT_32 data_len); -+ -+int mtk_cfg80211_vendor_event_hotlist_ap_found(struct wiphy *wiphy, struct wireless_dev *wdev, -+ P_PARAM_WIFI_GSCAN_RESULT pdata, UINT_32 data_len); -+ -+int mtk_cfg80211_vendor_event_hotlist_ap_lost(struct wiphy *wiphy, struct wireless_dev *wdev, -+ P_PARAM_WIFI_GSCAN_RESULT pdata, UINT_32 data_len); -+ -+#endif /* _GL_VENDOR_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_wext.h b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_wext.h -new file mode 100644 -index 000000000000..827ff92b1581 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_wext.h -@@ -0,0 +1,357 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux/include/gl_wext.h#1 -+*/ -+ -+/*! \file gl_wext.h -+ \brief This file is for Portable Driver linux wireless extension support. -+*/ -+ -+/* -+** Log: gl_wext.h -+ * -+ * 10 12 2011 wh.su -+ * [WCXRP00001036] [MT6620 Wi-Fi][Driver][FW] Adding the 802.11w code for MFP -+ * adding the 802.11w related function and define . -+ * -+ * 09 20 2011 chinglan.wang -+ * [WCXRP00000989] [WiFi Direct] [Driver] Add a new io control API to start the formation for the sigma test. -+ * . -+ * -+ * 09 20 2011 chinglan.wang -+ * [WCXRP00000989] [WiFi Direct] [Driver] Add a new io control API to start the formation for the sigma test. -+ * . -+ * -+ * 01 11 2011 chinglan.wang -+ * NULL -+ * Modify to reslove the CR :[ALPS00028994] Use WEP security to connect Marvell 11N AP. -+ * Connection establish successfully. -+ * Use the WPS function to connect AP, the privacy bit always is set to 1. . -+ * -+ * 09 27 2010 wh.su -+ * NULL -+ * [WCXRP00000067][MT6620 Wi-Fi][Driver] Support the android+ WAPI function. -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 03 31 2010 wh.su -+ * [WPD00003816][MT6620 Wi-Fi] Adding the security support -+ * modify the wapi related code for new driver's design. -+ * -+ * 03 24 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * initial import for Linux port -+** \main\maintrunk.MT5921\12 2009-10-20 17:38:33 GMT mtk01090 -+** Refine driver unloading and clean up procedure. Block requests, stop main thread and clean up queued requests, -+** and then stop hw. -+** \main\maintrunk.MT5921\11 2009-09-28 20:19:28 GMT mtk01090 -+** Add private ioctl to carry OID structures. Restructure public/private ioctl interfaces to Linux kernel. -+** \main\maintrunk.MT5921\10 2009-09-03 12:12:35 GMT mtk01088 -+** adding the function declaration -+** \main\maintrunk.MT5921\9 2009-08-18 22:57:17 GMT mtk01090 -+** Add Linux SDIO (with mmc core) support. -+** Add Linux 2.6.21, 2.6.25, 2.6.26. -+** Fix compile warning in Linux. -+** \main\maintrunk.MT5921\8 2008-08-29 16:59:07 GMT mtk01088 -+** fixed compiling error -+** \main\maintrunk.MT5921\7 2008-08-29 14:13:28 GMT mtk01088 -+** adjust the header file for code refine -+** \main\maintrunk.MT5921\6 2008-03-28 10:40:31 GMT mtk01461 -+** Add set desired rate in Linux STD IOCTL -+** \main\maintrunk.MT5921\5 2008-03-11 14:51:08 GMT mtk01461 -+** Refine private IOCTL functions -+** \main\maintrunk.MT5921\4 2008-02-12 23:45:45 GMT mtk01461 -+** Add Set Frequency & Channel oid support for Linux -+** \main\maintrunk.MT5921\3 2007-11-06 19:36:19 GMT mtk01088 -+** add the WPS related code -+*/ -+ -+#ifndef _GL_WEXT_H -+#define _GL_WEXT_H -+ -+#ifdef WIRELESS_EXT -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+#define KILO 1000 -+#define RATE_5_5M 11 /* 5.5M */ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+typedef struct _PARAM_FIXED_IEs { -+ UINT_8 aucTimestamp[8]; -+ UINT_16 u2BeaconInterval; -+ UINT_16 u2Capabilities; -+} PARAM_FIXED_IEs; -+ -+typedef struct _PARAM_VARIABLE_IE_T { -+ UINT_8 ucElementID; -+ UINT_8 ucLength; -+ UINT_8 aucData[1]; -+} PARAM_VARIABLE_IE_T, *P_PARAM_VARIABLE_IE_T; -+ -+#if WIRELESS_EXT < 18 -+ -+#define SIOCSIWMLME 0x8B16 /* request MLME operation; uses struct iw_mlme */ -+/* MLME requests (SIOCSIWMLME / struct iw_mlme) */ -+#define IW_MLME_DEAUTH 0 -+#define IW_MLME_DISASSOC 1 -+ -+/*! \brief SIOCSIWMLME data */ -+struct iw_mlme { -+ __u16 cmd; /*!< IW_MLME_* */ -+ __u16 reason_code; -+ struct sockaddr addr; -+}; -+ -+#define SIOCSIWAUTH 0x8B32 /* set authentication mode params */ -+#define SIOCGIWAUTH 0x8B33 /* get authentication mode params */ -+/* SIOCSIWAUTH/SIOCGIWAUTH struct iw_param flags */ -+#define IW_AUTH_INDEX 0x0FFF -+#define IW_AUTH_FLAGS 0xF000 -+/* SIOCSIWAUTH/SIOCGIWAUTH parameters (0 .. 4095) -+ * (IW_AUTH_INDEX mask in struct iw_param flags; this is the index of the -+ * parameter that is being set/get to; value will be read/written to -+ * struct iw_param value field) */ -+#define IW_AUTH_WPA_VERSION 0 -+#define IW_AUTH_CIPHER_PAIRWISE 1 -+#define IW_AUTH_CIPHER_GROUP 2 -+#define IW_AUTH_KEY_MGMT 3 -+#define IW_AUTH_TKIP_COUNTERMEASURES 4 -+#define IW_AUTH_DROP_UNENCRYPTED 5 -+#define IW_AUTH_80211_AUTH_ALG 6 -+#define IW_AUTH_WPA_ENABLED 7 -+#define IW_AUTH_RX_UNENCRYPTED_EAPOL 8 -+#define IW_AUTH_ROAMING_CONTROL 9 -+#define IW_AUTH_PRIVACY_INVOKED 10 -+#if CFG_SUPPORT_802_11W -+#define IW_AUTH_MFP 12 -+ -+#define IW_AUTH_MFP_DISABLED 0 /* MFP disabled */ -+#define IW_AUTH_MFP_OPTIONAL 1 /* MFP optional */ -+#define IW_AUTH_MFP_REQUIRED 2 /* MFP required */ -+#endif -+ -+/* IW_AUTH_WPA_VERSION values (bit field) */ -+#define IW_AUTH_WPA_VERSION_DISABLED 0x00000001 -+#define IW_AUTH_WPA_VERSION_WPA 0x00000002 -+#define IW_AUTH_WPA_VERSION_WPA2 0x00000004 -+ -+/* IW_AUTH_PAIRWISE_CIPHER and IW_AUTH_GROUP_CIPHER values (bit field) */ -+#define IW_AUTH_CIPHER_NONE 0x00000001 -+#define IW_AUTH_CIPHER_WEP40 0x00000002 -+#define IW_AUTH_CIPHER_TKIP 0x00000004 -+#define IW_AUTH_CIPHER_CCMP 0x00000008 -+#define IW_AUTH_CIPHER_WEP104 0x00000010 -+ -+/* IW_AUTH_KEY_MGMT values (bit field) */ -+#define IW_AUTH_KEY_MGMT_802_1X 1 -+#define IW_AUTH_KEY_MGMT_PSK 2 -+#define IW_AUTH_KEY_MGMT_WPA_NONE 4 -+ -+/* IW_AUTH_80211_AUTH_ALG values (bit field) */ -+#define IW_AUTH_ALG_OPEN_SYSTEM 0x00000001 -+#define IW_AUTH_ALG_SHARED_KEY 0x00000002 -+#define IW_AUTH_ALG_LEAP 0x00000004 -+ -+/* IW_AUTH_ROAMING_CONTROL values */ -+#define IW_AUTH_ROAMING_ENABLE 0 /* driver/firmware based roaming */ -+#define IW_AUTH_ROAMING_DISABLE 1 /* user space program used for roaming -+ * control */ -+ -+#define SIOCSIWENCODEEXT 0x8B34 /* set encoding token & mode */ -+#define SIOCGIWENCODEEXT 0x8B35 /* get encoding token & mode */ -+/* SIOCSIWENCODEEXT definitions */ -+#define IW_ENCODE_SEQ_MAX_SIZE 8 -+/* struct iw_encode_ext ->alg */ -+#define IW_ENCODE_ALG_NONE 0 -+#define IW_ENCODE_ALG_WEP 1 -+#define IW_ENCODE_ALG_TKIP 2 -+#define IW_ENCODE_ALG_CCMP 3 -+#if CFG_SUPPORT_802_11W -+#define IW_ENCODE_ALG_AES_CMAC 5 -+#endif -+ -+/* struct iw_encode_ext ->ext_flags */ -+#define IW_ENCODE_EXT_TX_SEQ_VALID 0x00000001 -+#define IW_ENCODE_EXT_RX_SEQ_VALID 0x00000002 -+#define IW_ENCODE_EXT_GROUP_KEY 0x00000004 -+#define IW_ENCODE_EXT_SET_TX_KEY 0x00000008 -+ -+struct iw_encode_ext { -+ __u32 ext_flags; /*!< IW_ENCODE_EXT_* */ -+ __u8 tx_seq[IW_ENCODE_SEQ_MAX_SIZE]; /*!< LSB first */ -+ __u8 rx_seq[IW_ENCODE_SEQ_MAX_SIZE]; /*!< LSB first */ -+ struct sockaddr addr; /*!< ff:ff:ff:ff:ff:ff for broadcast/multicast -+ * (group) keys or unicast address for -+ * individual keys */ -+ __u16 alg; /*!< IW_ENCODE_ALG_* */ -+ __u16 key_len; -+ __u8 key[0]; -+}; -+ -+#define SIOCSIWPMKSA 0x8B36 /* PMKSA cache operation */ -+#define IW_PMKSA_ADD 1 -+#define IW_PMKSA_REMOVE 2 -+#define IW_PMKSA_FLUSH 3 -+ -+#define IW_PMKID_LEN 16 -+ -+struct iw_pmksa { -+ __u32 cmd; /*!< IW_PMKSA_* */ -+ struct sockaddr bssid; -+ __u8 pmkid[IW_PMKID_LEN]; -+}; -+ -+#define IWEVGENIE 0x8C05 /* Generic IE (WPA, RSN, WMM, ..) -+ * (scan results); This includes id and -+ * length fields. One IWEVGENIE may -+ * contain more than one IE. Scan -+ * results may contain one or more -+ * IWEVGENIE events. */ -+#define IWEVMICHAELMICFAILURE 0x8C06 /* Michael MIC failure -+ * (struct iw_michaelmicfailure) -+ */ -+#define IWEVASSOCREQIE 0x8C07 /* IEs used in (Re)Association Request. -+ * The data includes id and length -+ * fields and may contain more than one -+ * IE. This event is required in -+ * Managed mode if the driver -+ * generates its own WPA/RSN IE. This -+ * should be sent just before -+ * IWEVREGISTERED event for the -+ * association. */ -+#define IWEVASSOCRESPIE 0x8C08 /* IEs used in (Re)Association -+ * Response. The data includes id and -+ * length fields and may contain more -+ * than one IE. This may be sent -+ * between IWEVASSOCREQIE and -+ * IWEVREGISTERED events for the -+ * association. */ -+#define IWEVPMKIDCAND 0x8C09 /* PMKID candidate for RSN -+ * pre-authentication -+ * (struct iw_pmkid_cand) */ -+ -+#endif /* WIRELESS_EXT < 18 */ -+ -+#if WIRELESS_EXT < 17 -+/* Statistics flags (bitmask in updated) */ -+#define IW_QUAL_QUAL_UPDATED 0x1 /* Value was updated since last read */ -+#define IW_QUAL_LEVEL_UPDATED 0x2 -+#define IW_QUAL_NOISE_UPDATED 0x4 -+#define IW_QUAL_QUAL_INVALID 0x10 /* Driver doesn't provide value */ -+#define IW_QUAL_LEVEL_INVALID 0x20 -+#define IW_QUAL_NOISE_INVALID 0x40 -+#endif -+ -+enum { -+ IEEE80211_FILTER_TYPE_BEACON = 1 << 0, -+ IEEE80211_FILTER_TYPE_PROBE_REQ = 1 << 1, -+ IEEE80211_FILTER_TYPE_PROBE_RESP = 1 << 2, -+ IEEE80211_FILTER_TYPE_ASSOC_REQ = 1 << 3, -+ IEEE80211_FILTER_TYPE_ASSOC_RESP = 1 << 4, -+ IEEE80211_FILTER_TYPE_AUTH = 1 << 5, -+ IEEE80211_FILTER_TYPE_DEAUTH = 1 << 6, -+ IEEE80211_FILTER_TYPE_DISASSOC = 1 << 7, -+ IEEE80211_FILTER_TYPE_ALL = 0xFF /* used to check the valid filter bits */ -+}; -+ -+#if CFG_SUPPORT_WAPI -+#define IW_AUTH_WAPI_ENABLED 0x20 -+#define IW_ENCODE_ALG_SMS4 0x20 -+#endif -+ -+#if CFG_SUPPORT_WAPI /* Android+ */ -+#define IW_AUTH_KEY_MGMT_WAPI_PSK 3 -+#define IW_AUTH_KEY_MGMT_WAPI_CERT 4 -+#endif -+#define IW_AUTH_KEY_MGMT_WPS 5 -+ -+#if CFG_SUPPORT_802_11W -+#define IW_AUTH_KEY_MGMT_802_1X_SHA256 7 -+#define IW_AUTH_KEY_MGMT_PSK_SHA256 8 -+#endif -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+extern const struct iw_handler_def wext_handler_def; -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+/* wireless extensions' ioctls */ -+int wext_support_ioctl(IN struct net_device *prDev, IN struct ifreq *prIfReq, IN int i4Cmd); -+ -+int -+wext_set_rate(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwReqInfo, IN struct iw_param *prRate, IN char *pcExtra); -+ -+void -+wext_indicate_wext_event(IN P_GLUE_INFO_T prGlueInfo, -+ IN unsigned int u4Cmd, IN unsigned char *pucData, IN unsigned int u4DataLen); -+ -+struct iw_statistics *wext_get_wireless_stats(struct net_device *prDev); -+ -+BOOLEAN -+wextSrchDesiredWPAIE(IN PUINT_8 pucIEStart, -+ IN INT_32 i4TotalIeLen, IN UINT_8 ucDesiredElemId, OUT PUINT_8 *ppucDesiredIE); -+ -+#if CFG_SUPPORT_WPS -+BOOLEAN -+wextSrchDesiredWPSIE(IN PUINT_8 pucIEStart, -+ IN INT_32 i4TotalIeLen, IN UINT_8 ucDesiredElemId, OUT PUINT_8 *ppucDesiredIE); -+#endif -+ -+#if CFG_SUPPORT_HOTSPOT_2_0 -+BOOLEAN wextSrchDesiredHS20IE(IN PUINT_8 pucIEStart, IN INT_32 i4TotalIeLen, OUT PUINT_8 *ppucDesiredIE); -+ -+BOOLEAN wextSrchDesiredInterworkingIE(IN PUINT_8 pucIEStart, IN INT_32 i4TotalIeLen, OUT PUINT_8 *ppucDesiredIE); -+ -+BOOLEAN wextSrchDesiredAdvProtocolIE(IN PUINT_8 pucIEStart, IN INT_32 i4TotalIeLen, OUT PUINT_8 *ppucDesiredIE); -+ -+BOOLEAN wextSrchDesiredRoamingConsortiumIE(IN PUINT_8 pucIEStart, IN INT_32 i4TotalIeLen, OUT PUINT_8 *ppucDesiredIE); -+#endif -+ -+#if CFG_SUPPORT_WAPI -+BOOLEAN wextSrchDesiredWAPIIE(IN PUINT_8 pucIEStart, IN INT_32 i4TotalIeLen, OUT PUINT_8 *ppucDesiredIE); -+#endif -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif /* WIRELESS_EXT */ -+ -+#endif /* _GL_WEXT_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_wext_priv.h b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_wext_priv.h -new file mode 100644 -index 000000000000..31933fc6a461 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_wext_priv.h -@@ -0,0 +1,402 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux/include/gl_wext_priv.h#3 -+*/ -+ -+/*! \file gl_wext_priv.h -+ \brief This file includes private ioctl support. -+*/ -+ -+/* -+** Log: gl_wext_priv.h -+ * -+ * 01 16 2012 wh.su -+ * [WCXRP00001170] [MT6620 Wi-Fi][Driver] Adding the related code for set/get band ioctl -+ * Adding the template code for set / get band IOCTL (with ICS supplicant_6).. -+ * -+ * 01 05 2012 wh.su -+ * [WCXRP00001153] [MT6620 Wi-Fi][Driver] Adding the get_ch_list and set_tx_power proto type function -+ * Adding the related ioctl / wlan oid function to set the Tx power cfg. -+ * -+ * 01 02 2012 wh.su -+ * [WCXRP00001153] [MT6620 Wi-Fi][Driver] Adding the get_ch_list and set_tx_power proto type function -+ * Adding the proto type function for set_int set_tx_power and get int get_ch_list. -+ * -+ * 11 08 2011 yuche.tsai -+ * [WCXRP00001094] [Volunteer Patch][Driver] Driver version & supplicant version query & set support for service -+ * discovery version check. -+ * Add a CMD ID for P2P driver version query. -+ * -+ * 03 17 2011 chinglan.wang -+ * [WCXRP00000570] [MT6620 Wi-Fi][Driver] Add Wi-Fi Protected Setup v2.0 feature -+ * . -+ * -+ * 03 02 2011 wh.su -+ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code -+ * Add security check code. -+ * -+ * 01 27 2011 cm.chang -+ * [WCXRP00000402] [MT6620 Wi-Fi][Driver] Enable MCR read/write by iwpriv by default -+ * . -+ * -+ * 01 20 2011 eddie.chen -+ * [WCXRP00000374] [MT6620 Wi-Fi][DRV] SW debug control -+ * Add Oid for sw control debug command -+ * -+ * 01 07 2011 cm.chang -+ * [WCXRP00000336] [MT6620 Wi-Fi][Driver] Add test mode commands in normal phone operation -+ * Add a new compiling option to control if MCR read/write is permitted -+ * -+ * 12 31 2010 cm.chang -+ * [WCXRP00000336] [MT6620 Wi-Fi][Driver] Add test mode commands in normal phone operation -+ * Add some iwpriv commands to support test mode operation -+ * -+ * 11 08 2010 wh.su -+ * [WCXRP00000171] [MT6620 Wi-Fi][Driver] Add message check code same behavior as mt5921 -+ * add the message check code from mt5921. -+ * -+ * 10 18 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000086] [MT6620 Wi-Fi][Driver] -+ * The mac address is all zero at android -+ * complete implementation of Android NVRAM access -+ * -+ * 09 23 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check -+ * add skeleton for NVRAM integration -+ * -+ * 08 04 2010 cp.wu -+ * NULL -+ * revert changelist #15371, efuse read/write access will be done by RF test approach -+ * -+ * 08 04 2010 cp.wu -+ * NULL -+ * add OID definitions for EFUSE read/write access. -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 03 31 2010 wh.su -+ * [WPD00003816][MT6620 Wi-Fi] Adding the security support -+ * modify the wapi related code for new driver's design. -+ * -+ * 03 24 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * initial import for Linux port -+** \main\maintrunk.MT5921\16 2009-09-29 16:47:23 GMT mtk01090 -+** Remove unused functions -+** \main\maintrunk.MT5921\15 2009-09-28 20:19:31 GMT mtk01090 -+** Add private ioctl to carry OID structures. Restructure public/private ioctl interfaces to Linux kernel. -+** \main\maintrunk.MT5921\14 2009-05-07 22:26:06 GMT mtk01089 -+** add private IO control for Linux BWCS -+** \main\maintrunk.MT5921\13 2008-08-29 14:55:20 GMT mtk01088 -+** adjust the code to meet coding style -+** \main\maintrunk.MT5921\12 2008-07-16 15:23:45 GMT mtk01104 -+** Support GPIO2 mode -+** \main\maintrunk.MT5921\11 2008-07-14 13:55:58 GMT mtk01104 -+** Support PRIV_CMD_BT_COEXIST -+** \main\maintrunk.MT5921\10 2008-07-09 00:20:24 GMT mtk01461 -+** Add priv oid to support WMM_PS_TEST -+** \main\maintrunk.MT5921\9 2008-05-30 20:27:24 GMT mtk01461 -+** Add POWER_MODE Private IOCTL cmd -+** \main\maintrunk.MT5921\8 2008-04-17 23:06:44 GMT mtk01461 -+** Add iwpriv support for AdHocMode setting -+** \main\maintrunk.MT5921\7 2008-03-31 21:01:24 GMT mtk01461 -+** Add priv IOCTL for VOIP settings -+** \main\maintrunk.MT5921\6 2008-03-31 13:49:47 GMT mtk01461 -+** add priv ioctl arg definition for turning on / off roaming -+** \main\maintrunk.MT5921\5 2008-03-26 15:35:09 GMT mtk01461 -+** Add CSUM offload priv ioctl for Linux -+** \main\maintrunk.MT5921\4 2008-03-11 14:51:11 GMT mtk01461 -+** Refine private IOCTL functions -+** \main\maintrunk.MT5921\3 2007-11-06 19:36:25 GMT mtk01088 -+** add the WPS related code -+*/ -+ -+#ifndef _GL_WEXT_PRIV_H -+#define _GL_WEXT_PRIV_H -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+/* If it is set to 1, iwpriv will support register read/write */ -+#define CFG_SUPPORT_PRIV_MCR_RW 1 -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+#if CFG_ENABLE_WIFI_DIRECT -+extern int set_p2p_mode_handler(struct net_device *netdev, PARAM_CUSTOM_P2P_SET_STRUCT_T p2pmode); -+#if 0 -+extern BOOLEAN fgIsResetting; -+extern BOOLEAN g_u4HaltFlag; -+extern spinlock_t g_p2p_lock; -+extern int g_u4P2PEnding; -+extern int g_u4P2POnOffing; -+#endif -+#endif -+ -+ -+#if (CFG_SUPPORT_TXR_ENC == 1) -+extern VOID rlmCmd(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); -+#endif /* CFG_SUPPORT_TXR_ENC */ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+/* New wireless extensions API - SET/GET convention (even ioctl numbers are -+ * root only) -+ */ -+#define IOCTL_SET_INT (SIOCIWFIRSTPRIV + 0) -+#define IOCTL_GET_INT (SIOCIWFIRSTPRIV + 1) -+ -+#define IOCTL_SET_ADDRESS (SIOCIWFIRSTPRIV + 2) -+#define IOCTL_GET_ADDRESS (SIOCIWFIRSTPRIV + 3) -+#define IOCTL_SET_STR (SIOCIWFIRSTPRIV + 4) -+#define IOCTL_GET_STR (SIOCIWFIRSTPRIV + 5) -+#define IOCTL_SET_KEY (SIOCIWFIRSTPRIV + 6) -+#define IOCTL_GET_KEY (SIOCIWFIRSTPRIV + 7) -+#define IOCTL_SET_STRUCT (SIOCIWFIRSTPRIV + 8) -+#define IOCTL_GET_STRUCT (SIOCIWFIRSTPRIV + 9) -+#define IOCTL_SET_STRUCT_FOR_EM (SIOCIWFIRSTPRIV + 11) -+#define IOCTL_SET_INTS (SIOCIWFIRSTPRIV + 12) -+#define IOCTL_GET_INTS (SIOCIWFIRSTPRIV + 13) -+#define IOCTL_SET_STRING (SIOCIWFIRSTPRIV + 14) -+ -+#define PRIV_CMD_REG_DOMAIN 0 -+#define PRIV_CMD_BEACON_PERIOD 1 -+#define PRIV_CMD_ADHOC_MODE 2 -+ -+#if CFG_TCP_IP_CHKSUM_OFFLOAD -+#define PRIV_CMD_CSUM_OFFLOAD 3 -+#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */ -+ -+#define PRIV_CMD_ROAMING 4 -+#define PRIV_CMD_VOIP_DELAY 5 -+#define PRIV_CMD_POWER_MODE 6 -+ -+#define PRIV_CMD_WMM_PS 7 -+#define PRIV_CMD_BT_COEXIST 8 -+#define PRIV_GPIO2_MODE 9 -+ -+#define PRIV_CUSTOM_SET_PTA 10 -+#define PRIV_CUSTOM_CONTINUOUS_POLL 11 -+#define PRIV_CUSTOM_SINGLE_ANTENNA 12 -+#define PRIV_CUSTOM_BWCS_CMD 13 -+#define PRIV_CUSTOM_DISABLE_BEACON_DETECTION 14 /* later */ -+#define PRIV_CMD_OID 15 -+#define PRIV_SEC_MSG_OID 16 -+ -+#define PRIV_CMD_TEST_MODE 17 -+#define PRIV_CMD_TEST_CMD 18 -+#define PRIV_CMD_ACCESS_MCR 19 -+#define PRIV_CMD_SW_CTRL 20 -+ -+#if 1 /* ANTI_PRIVCY */ -+#define PRIV_SEC_CHECK_OID 21 -+#endif -+ -+#define PRIV_CMD_WSC_PROBE_REQ 22 -+ -+#define PRIV_CMD_P2P_VERSION 23 -+ -+#define PRIV_CMD_GET_CH_LIST 24 -+ -+#define PRIV_CMD_SET_TX_POWER 25 -+ -+#define PRIV_CMD_BAND_CONFIG 26 -+ -+#define PRIV_CMD_DUMP_MEM 27 -+ -+#define PRIV_CMD_P2P_MODE 28 -+ -+#define PRIV_CMD_GET_BUILD_DATE_CODE 29 -+ -+#define PRIV_CMD_GET_DEBUG_CODE 30 -+ -+#define PRIV_CMD_OTHER 31 -+ -+#define PRIV_CMD_WFD_DEBUG_CODE 32 -+ -+#define PRIV_CMD_MET_PROFILING 33 -+ -+/* other string command ID */ -+#define PRIV_CMD_OTHER_TDLS 0x00 -+#define PRIV_CMD_OTHER_TAR 0x01 /* TX auto rate */ -+ -+/* 802.3 Objects (Ethernet) */ -+#define OID_802_3_CURRENT_ADDRESS 0x01010102 -+ -+/* IEEE 802.11 OIDs */ -+#define OID_802_11_SUPPORTED_RATES 0x0D01020E -+#define OID_802_11_CONFIGURATION 0x0D010211 -+ -+/* PnP and PM OIDs, NDIS default OIDS */ -+#define OID_PNP_SET_POWER 0xFD010101 -+ -+#define OID_CUSTOM_OID_INTERFACE_VERSION 0xFFA0C000 -+ -+/* MT5921 specific OIDs */ -+#define OID_CUSTOM_BT_COEXIST_CTRL 0xFFA0C580 -+#define OID_CUSTOM_POWER_MANAGEMENT_PROFILE 0xFFA0C581 -+#define OID_CUSTOM_PATTERN_CONFIG 0xFFA0C582 -+#define OID_CUSTOM_BG_SSID_SEARCH_CONFIG 0xFFA0C583 -+#define OID_CUSTOM_VOIP_SETUP 0xFFA0C584 -+#define OID_CUSTOM_ADD_TS 0xFFA0C585 -+#define OID_CUSTOM_DEL_TS 0xFFA0C586 -+#define OID_CUSTOM_SLT 0xFFA0C587 -+#define OID_CUSTOM_ROAMING_EN 0xFFA0C588 -+#define OID_CUSTOM_WMM_PS_TEST 0xFFA0C589 -+#define OID_CUSTOM_COUNTRY_STRING 0xFFA0C58A -+#define OID_CUSTOM_MULTI_DOMAIN_CAPABILITY 0xFFA0C58B -+#define OID_CUSTOM_GPIO2_MODE 0xFFA0C58C -+#define OID_CUSTOM_CONTINUOUS_POLL 0xFFA0C58D -+#define OID_CUSTOM_DISABLE_BEACON_DETECTION 0xFFA0C58E -+ -+/* CR1460, WPS privacy bit check disable */ -+#define OID_CUSTOM_DISABLE_PRIVACY_CHECK 0xFFA0C600 -+ -+/* Precedent OIDs */ -+#define OID_CUSTOM_MCR_RW 0xFFA0C801 -+#define OID_CUSTOM_EEPROM_RW 0xFFA0C803 -+#define OID_CUSTOM_SW_CTRL 0xFFA0C805 -+#define OID_CUSTOM_MEM_DUMP 0xFFA0C807 -+ -+/* RF Test specific OIDs */ -+#define OID_CUSTOM_TEST_MODE 0xFFA0C901 -+#define OID_CUSTOM_TEST_RX_STATUS 0xFFA0C903 -+#define OID_CUSTOM_TEST_TX_STATUS 0xFFA0C905 -+#define OID_CUSTOM_ABORT_TEST_MODE 0xFFA0C906 -+#define OID_CUSTOM_MTK_WIFI_TEST 0xFFA0C911 -+ -+/* BWCS */ -+#define OID_CUSTOM_BWCS_CMD 0xFFA0C931 -+#define OID_CUSTOM_SINGLE_ANTENNA 0xFFA0C932 -+#define OID_CUSTOM_SET_PTA 0xFFA0C933 -+ -+/* NVRAM */ -+#define OID_CUSTOM_MTK_NVRAM_RW 0xFFA0C941 -+#define OID_CUSTOM_CFG_SRC_TYPE 0xFFA0C942 -+#define OID_CUSTOM_EEPROM_TYPE 0xFFA0C943 -+ -+#if CFG_SUPPORT_WAPI -+#define OID_802_11_WAPI_MODE 0xFFA0CA00 -+#define OID_802_11_WAPI_ASSOC_INFO 0xFFA0CA01 -+#define OID_802_11_SET_WAPI_KEY 0xFFA0CA02 -+#endif -+ -+#if CFG_SUPPORT_WPS2 -+#define OID_802_11_WSC_ASSOC_INFO 0xFFA0CB00 -+#endif -+ -+/* Define magic key of test mode (Don't change it for future compatibity) */ -+#define PRIV_CMD_TEST_MAGIC_KEY 2011 -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+/* NIC BBCR configuration entry structure */ -+typedef struct _PRIV_CONFIG_ENTRY { -+ UINT_8 ucOffset; -+ UINT_8 ucValue; -+} PRIV_CONFIG_ENTRY, *PPRIV_CONFIG_ENTRY; -+ -+typedef WLAN_STATUS(*PFN_OID_HANDLER_FUNC_REQ) (IN PVOID prAdapter, -+ IN OUT PVOID pvBuf, IN UINT_32 u4BufLen, OUT PUINT_32 pu4OutInfoLen); -+ -+typedef enum _ENUM_OID_METHOD_T { -+ ENUM_OID_GLUE_ONLY, -+ ENUM_OID_GLUE_EXTENSION, -+ ENUM_OID_DRIVER_CORE -+} ENUM_OID_METHOD_T, *P_ENUM_OID_METHOD_T; -+ -+/* OID set/query processing entry */ -+typedef struct _WLAN_REQ_ENTRY { -+ UINT_32 rOid; /* OID */ -+ PUINT_8 pucOidName; /* OID name text */ -+ BOOLEAN fgQryBufLenChecking; -+ BOOLEAN fgSetBufLenChecking; -+ ENUM_OID_METHOD_T eOidMethod; -+ UINT_32 u4InfoBufLen; -+ PFN_OID_HANDLER_FUNC_REQ pfOidQueryHandler; /* PFN_OID_HANDLER_FUNC */ -+ PFN_OID_HANDLER_FUNC_REQ pfOidSetHandler; /* PFN_OID_HANDLER_FUNC */ -+} WLAN_REQ_ENTRY, *P_WLAN_REQ_ENTRY; -+ -+typedef struct _NDIS_TRANSPORT_STRUCT { -+ UINT_32 ndisOidCmd; -+ UINT_32 inNdisOidlength; -+ UINT_32 outNdisOidLength; -+ UINT_8 ndisOidContent[16]; -+} NDIS_TRANSPORT_STRUCT, *P_NDIS_TRANSPORT_STRUCT; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+int -+priv_set_int(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN char *pcExtra); -+ -+int -+priv_get_int(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN OUT char *pcExtra); -+ -+int -+priv_set_ints(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN char *pcExtra); -+ -+int -+priv_get_ints(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN OUT char *pcExtra); -+ -+int -+priv_set_struct(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN char *pcExtra); -+ -+int -+priv_get_struct(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN OUT char *pcExtra); -+ -+UINT_32 CmdStringDecParse(IN UINT_8 *InStr, OUT UINT_8 **OutStr, OUT UINT_32 *OutLen); -+ -+UINT_32 CmdStringMacParse(IN UINT_8 *InStr, OUT UINT_8 **OutStr, OUT UINT_32 *OutLen, OUT UINT_8 *OutMac); -+ -+int -+priv_set_string(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN char *pcExtra); -+ -+int priv_support_ioctl(IN struct net_device *prDev, IN OUT struct ifreq *prReq, IN int i4Cmd); -+ -+int priv_support_driver_cmd(IN struct net_device *prDev, IN OUT struct ifreq *prReq, IN int i4Cmd); -+ -+INT_32 priv_driver_cmds(IN struct net_device *prNetDev, IN PCHAR pcCommand, IN INT_32 i4TotalLen); -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif /* _GL_WEXT_PRIV_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/platform.c b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/platform.c -new file mode 100644 -index 000000000000..fba854cfd68e ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/platform.c -@@ -0,0 +1,542 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux/platform.c#1 -+*/ -+ -+/*! \file "platform.c" -+ \brief This file including the protocol layer privacy function. -+ -+ This file provided the macros and functions library support for the -+ protocol layer security setting from wlan_oid.c and for parse.c and -+ rsn.c and nic_privacy.c -+ -+*/ -+ -+/* -+** Log: platform.c -+ * -+ * 11 14 2011 cm.chang -+ * NULL -+ * Fix compiling warning -+ * -+ * 11 10 2011 cp.wu -+ * [WCXRP00001098] [MT6620 Wi-Fi][Driver] Replace printk by DBG LOG macros in linux porting layer -+ * 1. eliminaite direct calls to printk in porting layer. -+ * 2. replaced by DBGLOG, which would be XLOG on ALPS platforms. -+ * -+ * 09 13 2011 jeffrey.chang -+ * [WCXRP00000983] [MT6620][Wi-Fi Driver] invalid pointer casting causes kernel panic during p2p connection -+ * fix the pointer casting -+ * -+ * 06 29 2011 george.huang -+ * [WCXRP00000818] [MT6620 Wi-Fi][Driver] Remove unused code segment regarding CONFIG_IPV6 -+ * . -+ * -+ * 06 28 2011 george.huang -+ * [WCXRP00000818] [MT6620 Wi-Fi][Driver] Remove unused code segment regarding CONFIG_IPV6 -+ * remove un-used code -+ * -+ * 05 11 2011 jeffrey.chang -+ * NULL -+ * fix build error -+ * -+ * 05 09 2011 jeffrey.chang -+ * [WCXRP00000710] [MT6620 Wi-Fi] Support pattern filter update function on IP address change -+ * support ARP filter through kernel notifier -+ * -+ * 04 08 2011 pat.lu -+ * [WCXRP00000623] [MT6620 Wi-Fi][Driver] use ARCH define to distinguish PC Linux driver -+ * Use CONFIG_X86 instead of PC_LINUX_DRIVER_USE option to have proper compile setting for PC Linux driver -+ * -+ * 03 22 2011 pat.lu -+ * [WCXRP00000592] [MT6620 Wi-Fi][Driver] Support PC Linux Environment Driver Build -+ * Add a compiler option "PC_LINUX_DRIVER_USE" for building driver in PC Linux environment. -+ * -+ * 03 21 2011 cp.wu -+ * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer -+ * improve portability for awareness of early version of linux kernel and wireless extension. -+ * -+ * 03 18 2011 jeffrey.chang -+ * [WCXRP00000512] [MT6620 Wi-Fi][Driver] modify the net device relative functions to support the H/W multiple queue -+ * remove early suspend functions -+ * -+ * 03 03 2011 jeffrey.chang -+ * NULL -+ * add the ARP filter callback -+ * -+ * 02 15 2011 jeffrey.chang -+ * NULL -+ * to support early suspend in android -+ * -+ * 02 01 2011 cp.wu -+ * [WCXRP00000413] [MT6620 Wi-Fi][Driver] Merge 1103 changes on NVRAM file path change to DaVinci main trunk and V1.1 -+ * branch -+ * upon Jason Zhang(NVRAM owner)'s change, ALPS has modified its NVRAM storage from /nvram/... to /data/nvram/... -+ * -+ * 11 01 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000150] [MT6620 Wi-Fi][Driver] -+ * Add implementation for querying current TX rate from firmware auto rate module -+ * 1) Query link speed (TX rate) from firmware directly with buffering mechanism to reduce overhead -+ * 2) Remove CNM CH-RECOVER event handling -+ * 3) cfg read/write API renamed with kal prefix for unified naming rules. -+ * -+ * 10 18 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000086] [MT6620 Wi-Fi][Driver] -+ * The mac address is all zero at android -+ * complete implementation of Android NVRAM access -+ * -+ * 10 05 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check -+ * 1) add NVRAM access API -+ * 2) fake scanning result when NVRAM doesn't exist and/or version mismatch. (off by compiler option) -+ * 3) add OID implementation for NVRAM read/write service -+ * -+** -+*/ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+#include "gl_os.h" -+ -+#ifndef CONFIG_X86 -+#if defined(CONFIG_HAS_EARLY_SUSPEND) -+#include -+#endif -+#endif -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+#define WIFI_NVRAM_FILE_NAME "/etc/firmware/nvram/WIFI" -+#define WIFI_NVRAM_CUSTOM_NAME "/etc/firmware/nvram/WIFI_CUSTOM" -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+static int netdev_event(struct notifier_block *nb, unsigned long notification, void *ptr) -+{ -+ UINT_8 ip[4] = { 0 }; -+ UINT_32 u4NumIPv4 = 0; -+/* #ifdef CONFIG_IPV6 */ -+#if 0 -+ UINT_8 ip6[16] = { 0 }; /* FIX ME: avoid to allocate large memory in stack */ -+ UINT_32 u4NumIPv6 = 0; -+#endif -+ struct in_ifaddr *ifa = (struct in_ifaddr *)ptr; -+ struct net_device *prDev = ifa->ifa_dev->dev; -+ UINT_32 i; -+ P_PARAM_NETWORK_ADDRESS_IP prParamIpAddr; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ -+ if (prDev == NULL) { -+ DBGLOG(REQ, ERROR, "netdev_event: device is empty.\n"); -+ return NOTIFY_DONE; -+ } -+ DBGLOG(REQ, INFO, "netdev_event, addr=%x, notification=%lx, dev_name=%s\n", -+ ifa->ifa_address, notification, prDev->name); -+ if (!fgIsUnderSuspend) -+ return NOTIFY_DONE; -+ if ((strncmp(prDev->name, "p2p", 3) != 0) && (strncmp(prDev->name, "wlan", 4) != 0)) { -+ DBGLOG(REQ, WARN, "netdev_event: not our device\n"); -+ return NOTIFY_DONE; -+ } -+#if 0 /* CFG_SUPPORT_HOTSPOT_2_0 */ -+ { -+ /* printk(KERN_INFO "[netdev_event] IPV4_DAD is unlock now!!\n"); */ -+ prGlueInfo->fgIsDad = FALSE; -+ } -+#endif -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ -+ if (prGlueInfo == NULL) { -+ DBGLOG(REQ, ERROR, "netdev_event: prGlueInfo is empty.\n"); -+ return NOTIFY_DONE; -+ } -+ ASSERT(prGlueInfo); -+ -+ /* <3> get the IPv4 address */ -+ if (!prDev || !(prDev->ip_ptr) || -+ !((struct in_device *)(prDev->ip_ptr))->ifa_list || -+ !(&(((struct in_device *)(prDev->ip_ptr))->ifa_list->ifa_local))) { -+ DBGLOG(REQ, INFO, "ip is not available.\n"); -+ return NOTIFY_DONE; -+ } -+ -+ kalMemCopy(ip, &(((struct in_device *)(prDev->ip_ptr))->ifa_list->ifa_local), sizeof(ip)); -+ DBGLOG(REQ, INFO, "ip is %d.%d.%d.%d\n", ip[0], ip[1], ip[2], ip[3]); -+ -+ /* todo: traverse between list to find whole sets of IPv4 addresses */ -+ if (!((ip[0] == 0) && (ip[1] == 0) && (ip[2] == 0) && (ip[3] == 0))) -+ u4NumIPv4++; -+/* #ifdef CONFIG_IPV6 */ -+#if 0 -+ if (!prDev || !(prDev->ip6_ptr) || -+ !((struct in_device *)(prDev->ip6_ptr))->ifa_list || -+ !(&(((struct in_device *)(prDev->ip6_ptr))->ifa_list->ifa_local))) { -+ DBGLOG(REQ, INFO, "ipv6 is not available.\n"); -+ return NOTIFY_DONE; -+ } -+ -+ kalMemCopy(ip6, &(((struct in_device *)(prDev->ip6_ptr))->ifa_list->ifa_local), sizeof(ip6)); -+ DBGLOG(REQ, INFO, "ipv6 is %d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d\n", -+ ip6[0], ip6[1], ip6[2], ip6[3], -+ ip6[4], ip6[5], ip6[6], ip6[7], ip6[8], ip6[9], ip6[10], ip6[11], ip6[12], ip6[13], ip6[14], ip6[15]); -+ -+ /* todo: traverse between list to find whole sets of IPv6 addresses */ -+ if (!((ip6[0] == 0) && (ip6[1] == 0) && (ip6[2] == 0) && (ip6[3] == 0) && (ip6[4] == 0) && (ip6[5] == 0))) -+ /* u4NumIPv6++; */ -+#endif -+ -+ /* here we can compare the dev with other network's netdev to */ -+ /* set the proper arp filter */ -+ /* */ -+ /* IMPORTANT: please make sure if the context can sleep, if the context can't sleep */ -+ /* we should schedule a kernel thread to do this for us */ -+ -+ /* <7> set up the ARP filter */ -+ { -+ WLAN_STATUS rStatus = WLAN_STATUS_FAILURE; -+ UINT_32 u4SetInfoLen = 0; -+ UINT_8 aucBuf[32] = { 0 }; -+ UINT_32 u4Len = OFFSET_OF(PARAM_NETWORK_ADDRESS_LIST, arAddress); -+ P_PARAM_NETWORK_ADDRESS_LIST prParamNetAddrList = (P_PARAM_NETWORK_ADDRESS_LIST) aucBuf; -+ P_PARAM_NETWORK_ADDRESS prParamNetAddr = prParamNetAddrList->arAddress; -+ -+/* #ifdef CONFIG_IPV6 */ -+#if 0 -+ prParamNetAddrList->u4AddressCount = u4NumIPv4 + u4NumIPv6; -+#else -+ prParamNetAddrList->u4AddressCount = u4NumIPv4; -+#endif -+ prParamNetAddrList->u2AddressType = PARAM_PROTOCOL_ID_TCP_IP; -+ for (i = 0; i < u4NumIPv4; i++) { -+ prParamNetAddr->u2AddressLength = sizeof(PARAM_NETWORK_ADDRESS_IP); /* 4;; */ -+ prParamNetAddr->u2AddressType = PARAM_PROTOCOL_ID_TCP_IP; -+#if 0 -+ kalMemCopy(prParamNetAddr->aucAddress, ip, sizeof(ip)); -+ prParamNetAddr = (P_PARAM_NETWORK_ADDRESS) ((PUINT_8) prParamNetAddr + sizeof(ip)); -+ u4Len += OFFSET_OF(PARAM_NETWORK_ADDRESS, aucAddress) + sizeof(ip); -+#else -+ prParamIpAddr = (P_PARAM_NETWORK_ADDRESS_IP) prParamNetAddr->aucAddress; -+ kalMemCopy(&prParamIpAddr->in_addr, ip, sizeof(ip)); -+ prParamNetAddr = -+ (P_PARAM_NETWORK_ADDRESS) ((PUINT_8) prParamNetAddr + sizeof(PARAM_NETWORK_ADDRESS)); -+ u4Len += OFFSET_OF(PARAM_NETWORK_ADDRESS, aucAddress) + sizeof(PARAM_NETWORK_ADDRESS); -+#endif -+ } -+/* #ifdef CONFIG_IPV6 */ -+#if 0 -+ for (i = 0; i < u4NumIPv6; i++) { -+ prParamNetAddr->u2AddressLength = 6; -+ prParamNetAddr->u2AddressType = PARAM_PROTOCOL_ID_TCP_IP; -+ kalMemCopy(prParamNetAddr->aucAddress, ip6, sizeof(ip6)); -+ prParamNetAddr = (P_PARAM_NETWORK_ADDRESS) ((PUINT_8) prParamNetAddr + sizeof(ip6)); -+ u4Len += OFFSET_OF(PARAM_NETWORK_ADDRESS, aucAddress) + sizeof(ip6); -+ } -+#endif -+ ASSERT(u4Len <= sizeof(aucBuf)); -+ -+ DBGLOG(REQ, INFO, "kalIoctl (0x%p, 0x%p)\n", prGlueInfo, prParamNetAddrList); -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetNetworkAddress, -+ (PVOID) prParamNetAddrList, u4Len, FALSE, FALSE, TRUE, FALSE, &u4SetInfoLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) -+ DBGLOG(REQ, ERROR, "set HW pattern filter fail 0x%x\n", rStatus); -+ } -+ -+ return NOTIFY_DONE; -+ -+} -+ -+/* #if CFG_SUPPORT_HOTSPOT_2_0 */ -+#if 0 -+static int net6dev_event(struct notifier_block *nb, unsigned long notification, void *ptr) -+{ -+ struct inet6_ifaddr *ifa = (struct inet6_ifaddr *)ptr; -+ struct net_device *prDev = ifa->idev->dev; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ -+ if (prDev == NULL) { -+ DBGLOG(REQ, INFO, "net6dev_event: device is empty.\n"); -+ return NOTIFY_DONE; -+ } -+ -+ if ((strncmp(prDev->name, "p2p", 3) != 0) && (strncmp(prDev->name, "wlan", 4) != 0)) { -+ DBGLOG(REQ, INFO, "net6dev_event: xxx\n"); -+ return NOTIFY_DONE; -+ } -+ -+ if (strncmp(prDev->name, "p2p", 3) == 0) { -+ /* because we store the address of prGlueInfo in p2p's private date of net device */ -+ /* *((P_GLUE_INFO_T *) netdev_priv(prGlueInfo->prP2PInfo->prDevHandler)) = prGlueInfo; */ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ } else { /* wlan0 */ -+ prGlueInfo = (P_GLUE_INFO_T) netdev_priv(prDev); -+ } -+ -+ if (prGlueInfo == NULL) { -+ DBGLOG(REQ, INFO, "netdev_event: prGlueInfo is empty.\n"); -+ return NOTIFY_DONE; -+ } -+ /* printk(KERN_INFO "[net6dev_event] IPV6_DAD is unlock now!!\n"); */ -+ prGlueInfo->fgIs6Dad = FALSE; -+ -+ return NOTIFY_DONE; -+} -+#endif -+ -+static struct notifier_block inetaddr_notifier = { -+ .notifier_call = netdev_event, -+}; -+ -+#if 0 /* CFG_SUPPORT_HOTSPOT_2_0 */ -+static struct notifier_block inet6addr_notifier = { -+ .notifier_call = net6dev_event, -+}; -+#endif -+ -+void wlanRegisterNotifier(void) -+{ -+ register_inetaddr_notifier(&inetaddr_notifier); -+ -+#if CFG_SUPPORT_HOTSPOT_2_0 -+ /* register_inet6addr_notifier(&inet6addr_notifier); */ -+#endif -+} -+ -+/* EXPORT_SYMBOL(wlanRegisterNotifier); */ -+ -+void wlanUnregisterNotifier(void) -+{ -+ unregister_inetaddr_notifier(&inetaddr_notifier); -+ -+#if CFG_SUPPORT_HOTSPOT_2_0 -+ /* unregister_inetaddr_notifier(&inet6addr_notifier); */ -+#endif -+} -+ -+/* EXPORT_SYMBOL(wlanUnregisterNotifier); */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Utility function for reading data from files on NVRAM-FS -+* -+* \param[in] -+* filename -+* len -+* offset -+* \param[out] -+* buf -+* \return -+* actual length of data being read -+*/ -+/*----------------------------------------------------------------------------*/ -+static int nvram_read(char *filename, char *buf, ssize_t len, int offset) -+{ -+#if CFG_SUPPORT_NVRAM -+ struct file *fd; -+ int retLen = -1; -+ -+ mm_segment_t old_fs = get_fs(); -+ -+ set_fs(KERNEL_DS); -+ -+ fd = filp_open(filename, O_RDONLY, 0644); -+ -+ if (IS_ERR(fd)) { -+ DBGLOG(INIT, INFO, "[MT6620][nvram_read] : failed to open!!\n"); -+ return -1; -+ } -+ -+ do { -+ //if ((fd->f_op == NULL) || (fd->f_op->read == NULL)) { -+ if ( fd->f_op == NULL ) { -+ DBGLOG(INIT, INFO, "[MT6620][nvram_read] : file can not be read!!\n"); -+ break; -+ } -+ -+ if (fd->f_pos != offset) { -+ if (fd->f_op->llseek) { -+ if (fd->f_op->llseek(fd, offset, 0) != offset) { -+ DBGLOG(INIT, INFO, "[MT6620][nvram_read] : failed to seek!!\n"); -+ break; -+ } -+ } else { -+ fd->f_pos = offset; -+ } -+ } -+ -+ retLen = vfs_read(fd, buf, len, &fd->f_pos); -+ -+ } while (FALSE); -+ -+ filp_close(fd, NULL); -+ -+ set_fs(old_fs); -+ -+ return retLen; -+ -+#else /* !CFG_SUPPORT_NVRAM */ -+ -+ return -EIO; -+ -+#endif -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Utility function for writing data to files on NVRAM-FS -+* -+* \param[in] -+* filename -+* buf -+* len -+* offset -+* \return -+* actual length of data being written -+*/ -+/*----------------------------------------------------------------------------*/ -+static int nvram_write(char *filename, char *buf, ssize_t len, int offset) -+{ -+#if CFG_SUPPORT_NVRAM -+ struct file *fd; -+ int retLen = -1; -+ -+ mm_segment_t old_fs = get_fs(); -+ -+ set_fs(KERNEL_DS); -+ -+ fd = filp_open(filename, O_WRONLY | O_CREAT, 0644); -+ -+ if (IS_ERR(fd)) { -+ DBGLOG(INIT, INFO, "[MT6620][nvram_write] : failed to open!!\n"); -+ return -1; -+ } -+ -+ do { -+ if ((fd->f_op == NULL) || (fd->f_op->write == NULL)) { -+ DBGLOG(INIT, INFO, "[MT6620][nvram_write] : file can not be write!!\n"); -+ break; -+ } -+ /* End of if */ -+ if (fd->f_pos != offset) { -+ if (fd->f_op->llseek) { -+ if (fd->f_op->llseek(fd, offset, 0) != offset) { -+ DBGLOG(INIT, INFO, "[MT6620][nvram_write] : failed to seek!!\n"); -+ break; -+ } -+ } else { -+ fd->f_pos = offset; -+ } -+ } -+ -+ retLen = vfs_write(fd, buf, len, &fd->f_pos); -+ -+ } while (FALSE); -+ -+ filp_close(fd, NULL); -+ -+ set_fs(old_fs); -+ -+ return retLen; -+ -+#else /* !CFG_SUPPORT_NVRAMS */ -+ -+ return -EIO; -+ -+#endif -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief API for reading data on NVRAM -+* -+* \param[in] -+* prGlueInfo -+* u4Offset -+* \param[out] -+* pu2Data -+* \return -+* TRUE -+* FALSE -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN kalCfgDataRead16(IN P_GLUE_INFO_T prGlueInfo, IN UINT_32 u4Offset, OUT PUINT_16 pu2Data) -+{ -+ if (pu2Data == NULL) -+ return FALSE; -+ -+ if (nvram_read(WIFI_NVRAM_FILE_NAME, -+ (char *)pu2Data, sizeof(unsigned short), u4Offset) != sizeof(unsigned short)) { -+ return FALSE; -+ } else { -+ return TRUE; -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief API for writing data on NVRAM -+* -+* \param[in] -+* prGlueInfo -+* u4Offset -+* u2Data -+* \return -+* TRUE -+* FALSE -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN kalCfgDataWrite16(IN P_GLUE_INFO_T prGlueInfo, UINT_32 u4Offset, UINT_16 u2Data) -+{ -+ if (nvram_write(WIFI_NVRAM_FILE_NAME, -+ (char *)&u2Data, sizeof(unsigned short), u4Offset) != sizeof(unsigned short)) { -+ return FALSE; -+ } else { -+ return TRUE; -+ } -+} -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/version.h b/drivers/misc/mediatek/connectivity/wlan/gen2/os/version.h -new file mode 100644 -index 000000000000..9444d415c60e ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/version.h -@@ -0,0 +1,190 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/version.h#1 -+*/ -+ -+/*! \file "version.h" -+ \brief Driver's version definition -+ -+*/ -+ -+/* -+** Log: version.h -+ * -+ * 11 01 2011 chinglan.wang -+ * NULL -+ * Change the version number to v2.0.1.1. -+ * -+ * 08 26 2011 chinglan.wang -+ * NULL -+ * Change the version number to v2.0.0.9.. -+ * -+ * 08 23 2011 chinglan.wang -+ * NULL -+ * Change the version number to v2.0.0.8. -+ * -+ * 08 15 2011 cp.wu -+ * [WCXRP00000851] [MT6628 Wi-Fi][Driver] Add HIFSYS related definition to driver source tree -+ * correct typo. -+ * -+ * 08 15 2011 cp.wu -+ * [WCXRP00000851] [MT6628 Wi-Fi][Driver] Add HIFSYS related definition to driver source tree -+ * for building MT6628 Win32 driver environment -+ * -+ * 08 03 2011 chinglan.wang -+ * NULL -+ * Change the version number to v2.0.0.7. -+ * -+ * 07 24 2011 puff.wen -+ * NULL -+ * [MT5931][Beta 5]Change the version number to v0.2.2.0 -+ * -+ * 06 01 2011 chinglan.wang -+ * NULL -+ * Change the version number to v2.0.0.6.. -+ * -+ * 05 09 2011 chinglan.wang -+ * NULL -+ * Change the version number to v2.0.0.5.. -+ * -+ * 04 19 2011 chinglan.wang -+ * NULL -+ * Change the version number to v2.0.0.4. -+ * -+ * 04 18 2011 chinglan.wang -+ * NULL -+ * Change the version number to v2.0.0.3. -+ * -+ * 03 25 2011 chinglan.wang -+ * NULL -+ * Change the version number to v2.0.0.2. -+ * -+ * 03 21 2011 chinglan.wang -+ * NULL -+ * Change the version number to 2.0.0.1. -+ * -+ * 03 18 2011 chinglan.wang -+ * NULL -+ * Change the version number to v2.0.0.0. -+ * -+ * 02 11 2011 chinglan.wang -+ * NULL -+ * Change to the version 1.2.0.2. -+ * -+ * 02 10 2011 chinglan.wang -+ * NULL -+ * Change the version to 1.2.0.1. -+ * -+ * 02 08 2011 cp.wu -+ * [WCXRP00000427] [MT6620 Wi-Fi][Driver] Modify veresion information to match with release revision number -+ * change version number to v1.2.0.0 for preparing v1.2 software package release. -+ * -+ * 12 10 2010 kevin.huang -+ * [WCXRP00000128] [MT6620 Wi-Fi][Driver] Add proc support to Android Driver for debug and driver status check -+ * Add Linux Proc Support -+ * -+ * 10 07 2010 cp.wu -+ * [WCXRP00000083] [MT5931][Driver][FW] Add necessary logic for MT5931 first connection -+ * [WINDDK] build system changes for MT5931 -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+** \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-12-14 14:10:55 GMT mtk01084 -+** \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-11-17 22:41:00 GMT mtk01084 -+** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-11-13 16:20:33 GMT mtk01084 -+** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 20:27:13 GMT mtk01426 -+** Init for develop -+** -+*/ -+ -+#ifndef _VERSION_H -+#define _VERSION_H -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+#ifndef NIC_AUTHOR -+#define NIC_AUTHOR "NIC_AUTHOR" -+#endif -+#ifndef NIC_DESC -+#define NIC_DESC "NIC_DESC" -+#endif -+ -+#ifndef NIC_NAME -+#if defined(MT6620) -+#define NIC_NAME "MT6620" -+#define NIC_DEVICE_ID "MT6620" -+#define NIC_DEVICE_ID_LOW "mt6620" -+#elif defined(MT6628) -+#define NIC_NAME "MT6582" -+#define NIC_DEVICE_ID "MT6582" -+#define NIC_DEVICE_ID_LOW "mt6582" -+#endif -+#endif -+ -+/* NIC driver information */ -+#define NIC_VENDOR "MediaTek Inc." -+#define NIC_VENDOR_OUI {0x00, 0x0C, 0xE7} -+ -+#if defined(MT6620) -+#define NIC_PRODUCT_NAME "MediaTek Inc. MT6620 Wireless LAN Adapter" -+#define NIC_DRIVER_NAME "MediaTek Inc. MT6620 Wireless LAN Adapter Driver" -+#elif defined(MT6628) -+/* #define NIC_PRODUCT_NAME "MediaTek Inc. MT6628 Wireless LAN Adapter" */ -+/* #define NIC_DRIVER_NAME "MediaTek Inc. MT6628 Wireless LAN Adapter Driver" */ -+#define NIC_PRODUCT_NAME "MediaTek Inc. MT6582 Wireless LAN Adapter" -+#define NIC_DRIVER_NAME "MediaTek Inc. MT6582 Wireless LAN Adapter Driver" -+#endif -+ -+/* Define our driver version */ -+#define NIC_DRIVER_MAJOR_VERSION 2 -+#define NIC_DRIVER_MINOR_VERSION 0 -+#define NIC_DRIVER_VERSION (2, 0, 1, 1) -+#define NIC_DRIVER_VERSION_STRING "2.0.1.1" -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif /* _VERSION_H */ -diff --git a/drivers/misc/mediatek/include/mt-plat/aee.h b/drivers/misc/mediatek/include/mt-plat/aee.h -new file mode 100644 -index 000000000000..d1cf448dafb2 ---- /dev/null -+++ b/drivers/misc/mediatek/include/mt-plat/aee.h -@@ -0,0 +1,284 @@ -+/* -+ * Copyright (C) 2015 MediaTek Inc. -+ * -+ * 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. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#if !defined(__AEE_H__) -+#define __AEE_H__ -+ -+#include -+#include -+ -+#define AEE_MODULE_NAME_LENGTH 64 -+#define AEE_PROCESS_NAME_LENGTH 256 -+#define AEE_BACKTRACE_LENGTH 3072 -+ -+typedef enum { -+ AE_DEFECT_FATAL, -+ AE_DEFECT_EXCEPTION, -+ AE_DEFECT_WARNING, -+ AE_DEFECT_REMINDING, -+ AE_DEFECT_ATTR_END -+} AE_DEFECT_ATTR; -+ -+typedef enum { -+ AE_KE = 0, /* Fatal Exception */ -+ AE_HWT, -+ AE_REBOOT, -+ AE_NE, -+ AE_JE, -+ AE_SWT, -+ AE_EE, -+ AE_EXP_ERR_END, -+ AE_ANR, /* Error or Warning or Defect */ -+ AE_RESMON, -+ AE_MODEM_WARNING, -+ AE_WTF, -+ AE_WRN_ERR_END, -+ AE_MANUAL, /* Manual Raise */ -+ AE_EXP_CLASS_END, -+ -+ AE_KERNEL_PROBLEM_REPORT = 1000, -+ AE_SYSTEM_JAVA_DEFECT, -+ AE_SYSTEM_NATIVE_DEFECT, -+ AE_MANUAL_MRDUMP_KEY, -+} AE_EXP_CLASS; /* General Program Exception Class */ -+ -+typedef enum { -+ AEE_REBOOT_MODE_NORMAL = 0, -+ AEE_REBOOT_MODE_KERNEL_OOPS, -+ AEE_REBOOT_MODE_KERNEL_PANIC, -+ AEE_REBOOT_MODE_NESTED_EXCEPTION, -+ AEE_REBOOT_MODE_WDT, -+ AEE_REBOOT_MODE_MANUAL_KDUMP, -+} AEE_REBOOT_MODE; -+ -+#define AEE_SZ_SYMBOL_L 140 -+#define AEE_SZ_SYMBOL_S 80 -+struct aee_bt_frame { -+ __u64 pc; -+ __u64 lr; -+ __u32 pad[5]; -+ char pc_symbol[AEE_SZ_SYMBOL_S]; /* Now we use different symbol length for PC &LR */ -+ char lr_symbol[AEE_SZ_SYMBOL_L]; -+}; -+ -+/* aee_process_info struct should strictly small than ipanic_buffer, now 4KB */ -+struct aee_process_info { -+ char process_path[AEE_PROCESS_NAME_LENGTH]; -+ char backtrace[AEE_BACKTRACE_LENGTH]; -+ struct aee_bt_frame ke_frame; -+}; -+ -+struct aee_process_bt { -+ __u32 pid; -+ __u32 nr_entries; -+ struct aee_bt_frame *entries; -+}; -+ -+ -+struct aee_thread_reg { -+ pid_t tid; -+ struct pt_regs regs; -+}; -+ -+struct aee_user_thread_stack { -+ pid_t tid; -+ int StackLength; -+ unsigned char *Userthread_Stack; /*8k stack ,define to char only for match 64bit/32bit*/ -+}; -+ -+struct aee_user_thread_maps { -+ pid_t tid; -+ int Userthread_mapsLength; -+ unsigned char *Userthread_maps; /*8k stack ,define to char only for match 64bit/32bit*/ -+}; -+ -+ -+ -+struct aee_oops { -+ struct list_head list; -+ AE_DEFECT_ATTR attr; -+ AE_EXP_CLASS clazz; -+ -+ char module[AEE_MODULE_NAME_LENGTH]; -+ /* consist with struct aee_process_info */ -+ char process_path[AEE_PROCESS_NAME_LENGTH]; -+ char backtrace[AEE_BACKTRACE_LENGTH]; -+ struct aee_bt_frame ke_frame; -+ -+ char *detail; -+ int detail_len; -+ -+ char *console; -+ int console_len; -+ -+ char *android_main; -+ int android_main_len; -+ char *android_radio; -+ int android_radio_len; -+ char *android_system; -+ int android_system_len; -+ -+ char *userspace_info; -+ int userspace_info_len; -+ -+ char *mmprofile; -+ int mmprofile_len; -+ -+ char *mini_rdump; -+ int mini_rdump_len; -+ -+ -+ struct aee_user_thread_stack userthread_stack; -+ struct aee_thread_reg userthread_reg; -+ struct aee_user_thread_maps userthread_maps; -+ -+ int dump_option; -+}; -+ -+struct aee_kernel_api { -+ void (*kernel_reportAPI)(const AE_DEFECT_ATTR attr, const int db_opt, const char *module, -+ const char *msg); -+ void (*md_exception)(const char *assert_type, const int *log, int log_size, const int *phy, -+ int phy_size, const char *detail, const int db_opt); -+ void (*md32_exception)(const char *assert_type, const int *log, int log_size, -+ const int *phy, int phy_size, const char *detail, const int db_opt); -+ void (*combo_exception)(const char *assert_type, const int *log, int log_size, -+ const int *phy, int phy_size, const char *detail, const int db_opt); -+ void (*scp_exception)(const char *assert_type, const int *log, int log_size, -+ const int *phy, int phy_size, const char *detail, const int db_opt); -+}; -+ -+void aee_sram_printk(const char *fmt, ...); -+int aee_nested_printf(const char *fmt, ...); -+void aee_wdt_irq_info(void); -+void aee_wdt_fiq_info(void *arg, void *regs, void *svc_sp); -+void aee_trigger_kdb(void); -+struct aee_oops *aee_oops_create(AE_DEFECT_ATTR attr, AE_EXP_CLASS clazz, const char *module); -+void aee_oops_set_backtrace(struct aee_oops *oops, const char *backtrace); -+void aee_oops_set_process_path(struct aee_oops *oops, const char *process_path); -+void aee_oops_free(struct aee_oops *oops); -+/* powerkey press,modules use bits */ -+#define AE_WDT_Powerkey_DEVICE_PATH "/dev/kick_powerkey" -+#define WDT_SETBY_DEFAULT (0) -+#define WDT_SETBY_Backlight (1<<0) -+#define WDT_SETBY_Display (1<<1) -+#define WDT_SETBY_SF (1<<2) -+#define WDT_SETBY_PM (1<<3) -+#define WDT_SETBY_WMS_DISABLE_PWK_MONITOR (0xAEEAEE00) -+#define WDT_SETBY_WMS_ENABLE_PWK_MONITOR (0xAEEAEE01) -+#define WDT_PWK_HANG_FORCE_HWT (0xAEE0FFFF) -+ -+/* QHQ RT Monitor */ -+#define AEEIOCTL_RT_MON_Kick _IOR('p', 0x0A, int) -+#define AE_WDT_DEVICE_PATH "/dev/RT_Monitor" -+/* QHQ RT Monitor end */ -+ -+/* DB dump option bits, set relative bit to 1 to include related file in db */ -+#define DB_OPT_DEFAULT (0) -+#define DB_OPT_FTRACE (1<<0) -+#define DB_OPT_PRINTK_TOO_MUCH (1<<1) -+#define DB_OPT_NE_JBT_TRACES (1<<2) -+#define DB_OPT_SWT_JBT_TRACES (1<<3) -+#define DB_OPT_VM_TRACES (1<<4) -+#define DB_OPT_DUMPSYS_ACTIVITY (1<<5) -+#define DB_OPT_DUMPSYS_WINDOW (1<<6) -+#define DB_OPT_DUMPSYS_GFXINFO (1<<7) -+#define DB_OPT_DUMPSYS_SURFACEFLINGER (1<<8) -+#define DB_OPT_DISPLAY_HANG_DUMP (1<<9) -+#define DB_OPT_LOW_MEMORY_KILLER (1<<10) -+#define DB_OPT_PROC_MEM (1<<11) -+#define DB_OPT_FS_IO_LOG (1<<12) -+#define DB_OPT_PROCESS_COREDUMP (1<<13) -+#define DB_OPT_VM_HPROF (1<<14) -+#define DB_OPT_PROCMEM (1<<15) -+#define DB_OPT_DUMPSYS_INPUT (1<<16) -+#define DB_OPT_MMPROFILE_BUFFER (1<<17) -+#define DB_OPT_BINDER_INFO (1<<18) -+#define DB_OPT_WCN_ISSUE_INFO (1<<19) -+#define DB_OPT_DUMMY_DUMP (1<<20) -+#define DB_OPT_PID_MEMORY_INFO (1<<21) -+#define DB_OPT_VM_OOME_HPROF (1<<22) -+#define DB_OPT_PID_SMAPS (1<<23) -+#define DB_OPT_PROC_CMDQ_INFO (1<<24) -+#define DB_OPT_PROC_USKTRK (1<<25) -+#define DB_OPT_SF_RTT_DUMP (1<<26) -+#define DB_OPT_PAGETYPE_INFO (1<<27) -+#define DB_OPT_DUMPSYS_PROCSTATS (1<<28) -+#define DB_OPT_DUMP_DISPLAY (1<<29) -+#define DB_OPT_NATIVE_BACKTRACE (1<<30) -+#define DB_OPT_AARCH64 (1<<31) -+ -+#define aee_kernel_exception(module, msg...) \ -+ aee_kernel_exception_api(__FILE__, __LINE__, DB_OPT_DEFAULT, module, msg) -+#define aee_kernel_warning(module, msg...) \ -+ aee_kernel_warning_api(__FILE__, __LINE__, DB_OPT_DEFAULT, module, msg) -+#define aee_kernel_reminding(module, msg...) \ -+ aee_kernel_reminding_api(__FILE__, __LINE__, DB_OPT_DEFAULT, module, msg) -+#define aee_kernel_dal_show(msg) \ -+ aee_kernel_dal_api(__FILE__, __LINE__, msg) -+ -+#define aed_md_exception(log, log_size, phy, phy_size, detail) \ -+ aed_md_exception_api(log, log_size, phy, phy_size, detail, DB_OPT_DEFAULT) -+#define aed_md32_exception(log, log_size, phy, phy_size, detail) \ -+ aed_md32_exception_api(log, log_size, phy, phy_size, detail, DB_OPT_DEFAULT) -+#define aed_scp_exception(log, log_size, phy, phy_size, detail) \ -+ aed_scp_exception_api(log, log_size, phy, phy_size, detail, DB_OPT_DEFAULT) -+#define aed_combo_exception(log, log_size, phy, phy_size, detail) \ -+ aed_combo_exception_api(log, log_size, phy, phy_size, detail, DB_OPT_DEFAULT) -+ -+void aee_kernel_exception_api(const char *file, const int line, const int db_opt, -+ const char *module, const char *msg, ...); -+void aee_kernel_warning_api(const char *file, const int line, const int db_opt, const char *module, -+ const char *msg, ...); -+void aee_kernel_reminding_api(const char *file, const int line, const int db_opt, -+ const char *module, const char *msg, ...); -+void aee_kernel_dal_api(const char *file, const int line, const char *msg); -+ -+void aed_md_exception_api(const int *log, int log_size, const int *phy, int phy_size, -+ const char *detail, const int db_opt); -+void aed_md32_exception_api(const int *log, int log_size, const int *phy, int phy_size, -+ const char *detail, const int db_opt); -+void aed_scp_exception_api(const int *log, int log_size, const int *phy, int phy_size, -+ const char *detail, const int db_opt); -+void aed_combo_exception_api(const int *log, int log_size, const int *phy, int phy_size, -+ const char *detail, const int db_opt); -+ -+void aee_kernel_wdt_kick_Powkey_api(const char *module, int msg); -+int aee_kernel_wdt_kick_api(int kinterval); -+void aee_powerkey_notify_press(unsigned long pressed); -+int aee_kernel_Powerkey_is_press(void); -+ -+void ipanic_recursive_ke(struct pt_regs *regs, struct pt_regs *excp_regs, int cpu); -+ -+/* QHQ RT Monitor */ -+void aee_kernel_RT_Monitor_api(int lParam); -+/* QHQ RT Monitor end */ -+void mt_fiq_printf(const char *fmt, ...); -+void aee_register_api(struct aee_kernel_api *aee_api); -+int aee_in_nested_panic(void); -+void aee_stop_nested_panic(struct pt_regs *regs); -+void aee_wdt_dump_info(void); -+void aee_wdt_printf(const char *fmt, ...); -+ -+void aee_fiq_ipi_cpu_stop(void *arg, void *regs, void *svc_sp); -+ -+#if defined(CONFIG_MTK_AEE_DRAM_CONSOLE) -+void aee_dram_console_reserve_memory(void); -+#else -+static inline void aee_dram_console_reserve_memory(void) -+{ -+} -+#endif -+ -+extern void *aee_excp_regs; /* To store latest exception, in case of stack corruption */ -+#endif /* __AEE_H__ */ -diff --git a/drivers/misc/mediatek/include/mt-plat/mrdump.h b/drivers/misc/mediatek/include/mt-plat/mrdump.h -new file mode 100644 -index 000000000000..b6bdfa2f7617 ---- /dev/null -+++ b/drivers/misc/mediatek/include/mt-plat/mrdump.h -@@ -0,0 +1,204 @@ -+/* -+ * Copyright (C) 2016 MediaTek Inc. -+ * -+ * 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. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+ * See http://www.gnu.org/licenses/gpl-2.0.html for more details. -+ */ -+ -+#if !defined(__MRDUMP_H__) -+#define __MRDUMP_H__ -+ -+#include -+#include -+#include -+#include -+#include -+ -+#ifdef __aarch64__ -+#define reg_pc pc -+#define reg_lr regs[30] -+#define reg_sp sp -+#define reg_fp regs[29] -+#else -+#define reg_pc ARM_pc -+#define reg_lr ARM_lr -+#define reg_sp ARM_sp -+#define reg_ip ARM_ip -+#define reg_fp ARM_fp -+#endif -+ -+#define MRDUMP_CPU_MAX 16 -+ -+#define MRDUMP_DEV_NULL 0 -+#define MRDUMP_DEV_SDCARD 1 -+#define MRDUMP_DEV_EMMC 2 -+ -+#define MRDUMP_FS_NULL 0 -+#define MRDUMP_FS_VFAT 1 -+#define MRDUMP_FS_EXT4 2 -+ -+#define MRDUMP_GO_DUMP "MRDUMP04" -+ -+typedef uint32_t arm32_gregset_t[18]; -+typedef uint64_t aarch64_gregset_t[34]; -+ -+struct mrdump_crash_record { -+ int reboot_mode; -+ -+ char msg[128]; -+ char backtrace[512]; -+ -+ uint32_t fault_cpu; -+ -+ union { -+ arm32_gregset_t arm32_regs; -+ aarch64_gregset_t aarch64_regs; -+ } cpu_regs[MRDUMP_CPU_MAX]; -+}; -+ -+struct mrdump_machdesc { -+ uint32_t crc; -+ -+ uint32_t output_device; -+ -+ uint32_t nr_cpus; -+ -+ uint64_t page_offset; -+ uint64_t high_memory; -+ -+ uint64_t vmalloc_start; -+ uint64_t vmalloc_end; -+ -+ uint64_t modules_start; -+ uint64_t modules_end; -+ -+ uint64_t phys_offset; -+ uint64_t master_page_table; -+ -+ uint32_t output_fstype; -+ uint32_t output_lbaooo; -+}; -+ -+struct mrdump_control_block { -+ char sig[8]; -+ -+ struct mrdump_machdesc machdesc; -+ struct mrdump_crash_record crash_record; -+}; -+ -+/* NOTE!! any change to this struct should be compatible in aed */ -+struct mrdump_mini_reg_desc { -+ unsigned long reg; /* register value */ -+ unsigned long kstart; /* start kernel addr of memory dump */ -+ unsigned long kend; /* end kernel addr of memory dump */ -+ unsigned long pos; /* next pos to dump */ -+ int valid; /* 1: valid regiser, 0: invalid regiser */ -+ int pad; /* reserved */ -+ loff_t offset; /* offset in buffer */ -+}; -+ -+/* it should always be smaller than MRDUMP_MINI_HEADER_SIZE */ -+struct mrdump_mini_header { -+ struct mrdump_mini_reg_desc reg_desc[ELF_NGREG]; -+}; -+ -+#define MRDUMP_MINI_NR_SECTION 60 -+#define MRDUMP_MINI_SECTION_SIZE (32 * 1024) -+#define NT_IPANIC_MISC 4095 -+#define MRDUMP_MINI_NR_MISC 20 -+ -+struct mrdump_mini_elf_misc { -+ unsigned long vaddr; -+ unsigned long paddr; -+ unsigned long start; -+ unsigned long size; -+}; -+ -+#define NOTE_NAME_SHORT 12 -+#define NOTE_NAME_LONG 20 -+ -+struct mrdump_mini_elf_psinfo { -+ struct elf_note note; -+ char name[NOTE_NAME_SHORT]; -+ struct elf_prpsinfo data; -+}; -+ -+struct mrdump_mini_elf_prstatus { -+ struct elf_note note; -+ char name[NOTE_NAME_SHORT]; -+ struct elf_prstatus data; -+}; -+ -+struct mrdump_mini_elf_note { -+ struct elf_note note; -+ char name[NOTE_NAME_LONG]; -+ struct mrdump_mini_elf_misc data; -+}; -+ -+struct mrdump_mini_elf_header { -+ struct elfhdr ehdr; -+ struct elf_phdr phdrs[MRDUMP_MINI_NR_SECTION]; -+ struct mrdump_mini_elf_psinfo psinfo; -+ struct mrdump_mini_elf_prstatus prstatus[NR_CPUS + 1]; -+ struct mrdump_mini_elf_note misc[MRDUMP_MINI_NR_MISC]; -+}; -+ -+typedef struct mrdump_rsvmem_block { -+ phys_addr_t start_addr; -+ phys_addr_t size; -+} mrdump_rsvmem_block_t; -+ -+ -+#define MRDUMP_MINI_HEADER_SIZE ALIGN(sizeof(struct mrdump_mini_elf_header), PAGE_SIZE) -+#define MRDUMP_MINI_DATA_SIZE (MRDUMP_MINI_NR_SECTION * MRDUMP_MINI_SECTION_SIZE) -+#define MRDUMP_MINI_BUF_SIZE (MRDUMP_MINI_HEADER_SIZE + MRDUMP_MINI_DATA_SIZE) -+ -+#ifdef CONFIG_MTK_RAM_CONSOLE_DRAM_ADDR -+#define MRDUMP_MINI_BUF_PADDR (CONFIG_MTK_RAM_CONSOLE_DRAM_ADDR + 0xf0000) -+#else -+#define MRDUMP_MINI_BUF_PADDR 0 -+#endif -+ -+int mrdump_init(void); -+void __mrdump_create_oops_dump(AEE_REBOOT_MODE reboot_mode, struct pt_regs *regs, const char *msg, -+ ...); -+#if defined(CONFIG_MTK_AEE_IPANIC) -+void mrdump_rsvmem(void); -+#else -+static inline void mrdump_rsvmem(void) -+{ -+} -+#endif -+ -+#if defined(CONFIG_MTK_AEE_MRDUMP) -+void aee_kdump_reboot(AEE_REBOOT_MODE, const char *msg, ...); -+#else -+static inline void aee_kdump_reboot(AEE_REBOOT_MODE reboot_mode, const char *msg, ...) -+{ -+} -+#endif -+ -+typedef int (*mrdump_write)(void *buf, int off, int len, int encrypt); -+#if defined(CONFIG_MTK_AEE_IPANIC) -+int mrdump_mini_create_oops_dump(AEE_REBOOT_MODE reboot_mode, mrdump_write write, -+ loff_t sd_offset, const char *msg, va_list ap); -+void mrdump_mini_reserve_memory(void); -+#else -+static inline int mrdump_mini_create_oops_dump(AEE_REBOOT_MODE reboot_mode, mrdump_write write, -+ loff_t sd_offset, const char *msg, va_list ap) -+{ -+ return 0; -+} -+ -+static inline void mrdump_mini_reserve_memory(void) -+{ -+} -+#endif -+ -+#endif -diff --git a/drivers/misc/mediatek/include/mt-plat/mt7622/include/mach/mtk_thermal.h b/drivers/misc/mediatek/include/mt-plat/mt7622/include/mach/mtk_thermal.h -new file mode 100644 -index 000000000000..1b60f007d0fd ---- /dev/null -+++ b/drivers/misc/mediatek/include/mt-plat/mt7622/include/mach/mtk_thermal.h -@@ -0,0 +1,295 @@ -+/* -+ * Copyright (C) 2015 MediaTek Inc. -+ * -+ * 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. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+ -+#ifndef _MT8167_THERMAL_H -+#define _MT8167_THERMAL_H -+ -+#include -+#include -+#include -+#include -+ -+#include -+#include -+ -+#include "sync_write.h" -+ -+extern void __iomem *thermal_base; -+extern void __iomem *auxadc_ts_base; -+extern void __iomem *apmixed_base; -+extern void __iomem *pericfg_base; -+extern int auxadc_ts_phy_base; -+extern int apmixed_phy_base; -+ -+#define THERM_CTRL_BASE_2 thermal_base -+#define AUXADC_BASE_2 auxadc_ts_base -+#define PERICFG_BASE pericfg_base -+#define APMIXED_BASE_2 apmixed_base -+ -+#define MT6752_EVB_BUILD_PASS /*Jerry fix build error FIX_ME*/ -+ -+/******************************************************************************* -+* AUXADC Register Definition -+******************************************************************************/ -+/*AUXADC_BASE: 0xF1001000 from Vincent Liang 2014.5.8*/ -+ -+#define AUXADC_CON0_V (AUXADC_BASE_2 + 0x000) /*yes, 0x11003000*/ -+#define AUXADC_CON1_V (AUXADC_BASE_2 + 0x004) -+#define AUXADC_CON1_SET_V (AUXADC_BASE_2 + 0x008) -+#define AUXADC_CON1_CLR_V (AUXADC_BASE_2 + 0x00C) -+#define AUXADC_CON2_V (AUXADC_BASE_2 + 0x010) -+/*#define AUXADC_CON3_V (AUXADC_BASE_2 + 0x014)*/ -+#define AUXADC_DAT0_V (AUXADC_BASE_2 + 0x014) -+#define AUXADC_DAT1_V (AUXADC_BASE_2 + 0x018) -+#define AUXADC_DAT2_V (AUXADC_BASE_2 + 0x01C) -+#define AUXADC_DAT3_V (AUXADC_BASE_2 + 0x020) -+#define AUXADC_DAT4_V (AUXADC_BASE_2 + 0x024) -+#define AUXADC_DAT5_V (AUXADC_BASE_2 + 0x028) -+#define AUXADC_DAT6_V (AUXADC_BASE_2 + 0x02C) -+#define AUXADC_DAT7_V (AUXADC_BASE_2 + 0x030) -+#define AUXADC_DAT8_V (AUXADC_BASE_2 + 0x034) -+#define AUXADC_DAT9_V (AUXADC_BASE_2 + 0x038) -+#define AUXADC_DAT10_V (AUXADC_BASE_2 + 0x03C) -+#define AUXADC_DAT11_V (AUXADC_BASE_2 + 0x040) -+#define AUXADC_MISC_V (AUXADC_BASE_2 + 0x094) -+ -+#define AUXADC_CON0_P (auxadc_ts_phy_base + 0x000) -+#define AUXADC_CON1_P (auxadc_ts_phy_base + 0x004) -+#define AUXADC_CON1_SET_P (auxadc_ts_phy_base + 0x008) -+#define AUXADC_CON1_CLR_P (auxadc_ts_phy_base + 0x00C) -+#define AUXADC_CON2_P (auxadc_ts_phy_base + 0x010) -+/*#define AUXADC_CON3_P (auxadc_ts_phy_base + 0x014)*/ -+#define AUXADC_DAT0_P (auxadc_ts_phy_base + 0x014) -+#define AUXADC_DAT1_P (auxadc_ts_phy_base + 0x018) -+#define AUXADC_DAT2_P (auxadc_ts_phy_base + 0x01C) -+#define AUXADC_DAT3_P (auxadc_ts_phy_base + 0x020) -+#define AUXADC_DAT4_P (auxadc_ts_phy_base + 0x024) -+#define AUXADC_DAT5_P (auxadc_ts_phy_base + 0x028) -+#define AUXADC_DAT6_P (auxadc_ts_phy_base + 0x02C) -+#define AUXADC_DAT7_P (auxadc_ts_phy_base + 0x030) -+#define AUXADC_DAT8_P (auxadc_ts_phy_base + 0x034) -+#define AUXADC_DAT9_P (auxadc_ts_phy_base + 0x038) -+#define AUXADC_DAT10_P (auxadc_ts_phy_base + 0x03C) -+#define AUXADC_DAT11_P (auxadc_ts_phy_base + 0x040) -+ -+#define AUXADC_MISC_P (auxadc_ts_phy_base + 0x094) -+ -+/******************************************************************************* -+* Peripheral Configuration Register Definition -+******************************************************************************/ -+/*#define PERICFG_BASE (0x10002000)*/ -+#define PERI_GLOBALCON_RST0 (pericfg_base + 0x000) /*yes, 0x10002000*/ -+/******************************************************************************* -+ * APMixedSys Configuration Register Definition -+ ******************************************************************************/ -+#define TS_CON0 (APMIXED_BASE_2 + 0x600) /*yes 0x10209000*/ -+#define TS_CON1 (APMIXED_BASE_2 + 0x604) -+#define TS_CON0_TM (APMIXED_BASE_2 + 0x600) /* yes 0x10209000 */ -+#define TS_CON1_TM (APMIXED_BASE_2 + 0x604) -+#define TS_CON0_P (apmixed_phy_base + 0x600) -+#define TS_CON1_P (apmixed_phy_base + 0x604) -+ -+/******************************************************************************* -+ * Thermal Controller Register Definition -+ ******************************************************************************/ -+#define TEMPMONCTL0 (THERM_CTRL_BASE_2 + 0x000) /*yes 0x1100B000*/ -+#define TEMPMONCTL1 (THERM_CTRL_BASE_2 + 0x004) -+#define TEMPMONCTL2 (THERM_CTRL_BASE_2 + 0x008) -+#define TEMPMONINT (THERM_CTRL_BASE_2 + 0x00C) -+#define TEMPMONINTSTS (THERM_CTRL_BASE_2 + 0x010) -+#define TEMPMONIDET0 (THERM_CTRL_BASE_2 + 0x014) -+#define TEMPMONIDET1 (THERM_CTRL_BASE_2 + 0x018) -+#define TEMPMONIDET2 (THERM_CTRL_BASE_2 + 0x01C) -+#define TEMPH2NTHRE (THERM_CTRL_BASE_2 + 0x024) -+#define TEMPHTHRE (THERM_CTRL_BASE_2 + 0x028) -+#define TEMPCTHRE (THERM_CTRL_BASE_2 + 0x02C) -+#define TEMPOFFSETH (THERM_CTRL_BASE_2 + 0x030) -+#define TEMPOFFSETL (THERM_CTRL_BASE_2 + 0x034) -+#define TEMPMSRCTL0 (THERM_CTRL_BASE_2 + 0x038) -+#define TEMPMSRCTL1 (THERM_CTRL_BASE_2 + 0x03C) -+#define TEMPAHBPOLL (THERM_CTRL_BASE_2 + 0x040) -+#define TEMPAHBTO (THERM_CTRL_BASE_2 + 0x044) -+#define TEMPADCPNP0 (THERM_CTRL_BASE_2 + 0x048) -+#define TEMPADCPNP1 (THERM_CTRL_BASE_2 + 0x04C) -+#define TEMPADCPNP2 (THERM_CTRL_BASE_2 + 0x050) -+#define TEMPADCPNP3 (THERM_CTRL_BASE_2 + 0x0B4) -+ -+#define TEMPADCMUX (THERM_CTRL_BASE_2 + 0x054) -+#define TEMPADCEXT (THERM_CTRL_BASE_2 + 0x058) -+#define TEMPADCEXT1 (THERM_CTRL_BASE_2 + 0x05C) -+#define TEMPADCEN (THERM_CTRL_BASE_2 + 0x060) -+#define TEMPPNPMUXADDR (THERM_CTRL_BASE_2 + 0x064) -+#define TEMPADCMUXADDR (THERM_CTRL_BASE_2 + 0x068) -+#define TEMPADCEXTADDR (THERM_CTRL_BASE_2 + 0x06C) -+#define TEMPADCEXT1ADDR (THERM_CTRL_BASE_2 + 0x070) -+#define TEMPADCENADDR (THERM_CTRL_BASE_2 + 0x074) -+#define TEMPADCVALIDADDR (THERM_CTRL_BASE_2 + 0x078) -+#define TEMPADCVOLTADDR (THERM_CTRL_BASE_2 + 0x07C) -+#define TEMPRDCTRL (THERM_CTRL_BASE_2 + 0x080) -+#define TEMPADCVALIDMASK (THERM_CTRL_BASE_2 + 0x084) -+#define TEMPADCVOLTAGESHIFT (THERM_CTRL_BASE_2 + 0x088) -+#define TEMPADCWRITECTRL (THERM_CTRL_BASE_2 + 0x08C) -+#define TEMPMSR0 (THERM_CTRL_BASE_2 + 0x090) -+#define TEMPMSR1 (THERM_CTRL_BASE_2 + 0x094) -+#define TEMPMSR2 (THERM_CTRL_BASE_2 + 0x098) -+#define TEMPMSR3 (THERM_CTRL_BASE_2 + 0x0B8) -+ -+#define TEMPIMMD0 (THERM_CTRL_BASE_2 + 0x0A0) -+#define TEMPIMMD1 (THERM_CTRL_BASE_2 + 0x0A4) -+#define TEMPIMMD2 (THERM_CTRL_BASE_2 + 0x0A8) -+#define TEMPIMMD3 (THERM_CTRL_BASE_2 + 0x0BC) -+ -+ -+#define TEMPPROTCTL (THERM_CTRL_BASE_2 + 0x0C0) -+#define TEMPPROTTA (THERM_CTRL_BASE_2 + 0x0C4) -+#define TEMPPROTTB (THERM_CTRL_BASE_2 + 0x0C8) -+#define TEMPPROTTC (THERM_CTRL_BASE_2 + 0x0CC) -+ -+#define TEMPSPARE0 (THERM_CTRL_BASE_2 + 0x0F0) -+#define TEMPSPARE1 (THERM_CTRL_BASE_2 + 0x0F4) -+#define TEMPSPARE2 (THERM_CTRL_BASE_2 + 0x0F8) -+#define TEMPSPARE3 (THERM_CTRL_BASE_2 + 0x0FC) -+ -+#define PTPCORESEL (THERM_CTRL_BASE_2 + 0x400) -+#define THERMINTST (THERM_CTRL_BASE_2 + 0x404) -+#define PTPODINTST (THERM_CTRL_BASE_2 + 0x408) -+#define THSTAGE0ST (THERM_CTRL_BASE_2 + 0x40C) -+#define THSTAGE1ST (THERM_CTRL_BASE_2 + 0x410) -+#define THSTAGE2ST (THERM_CTRL_BASE_2 + 0x414) -+#define THAHBST0 (THERM_CTRL_BASE_2 + 0x418) -+#define THAHBST1 (THERM_CTRL_BASE_2 + 0x41C) /*Only for DE debug*/ -+#define PTPSPARE0 (THERM_CTRL_BASE_2 + 0x420) -+#define PTPSPARE1 (THERM_CTRL_BASE_2 + 0x424) -+#define PTPSPARE2 (THERM_CTRL_BASE_2 + 0x428) -+#define PTPSPARE3 (THERM_CTRL_BASE_2 + 0x42C) -+#define THSLPEVEB (THERM_CTRL_BASE_2 + 0x430) -+ -+ -+#define PTPSPARE0_P (thermal_phy_base + 0x420) -+#define PTPSPARE1_P (thermal_phy_base + 0x424) -+#define PTPSPARE2_P (thermal_phy_base + 0x428) -+#define PTPSPARE3_P (thermal_phy_base + 0x42C) -+ -+/******************************************************************************* -+ * Thermal Controller Register Mask Definition -+ ******************************************************************************/ -+#define THERMAL_ENABLE_SEN0 0x1 -+#define THERMAL_ENABLE_SEN1 0x2 -+#define THERMAL_ENABLE_SEN2 0x4 -+#define THERMAL_MONCTL0_MASK 0x00000007 -+ -+#define THERMAL_PUNT_MASK 0x00000FFF -+#define THERMAL_FSINTVL_MASK 0x03FF0000 -+#define THERMAL_SPINTVL_MASK 0x000003FF -+#define THERMAL_MON_INT_MASK 0x0007FFFF -+ -+#define THERMAL_MON_CINTSTS0 0x000001 -+#define THERMAL_MON_HINTSTS0 0x000002 -+#define THERMAL_MON_LOINTSTS0 0x000004 -+#define THERMAL_MON_HOINTSTS0 0x000008 -+#define THERMAL_MON_NHINTSTS0 0x000010 -+#define THERMAL_MON_CINTSTS1 0x000020 -+#define THERMAL_MON_HINTSTS1 0x000040 -+#define THERMAL_MON_LOINTSTS1 0x000080 -+#define THERMAL_MON_HOINTSTS1 0x000100 -+#define THERMAL_MON_NHINTSTS1 0x000200 -+#define THERMAL_MON_CINTSTS2 0x000400 -+#define THERMAL_MON_HINTSTS2 0x000800 -+#define THERMAL_MON_LOINTSTS2 0x001000 -+#define THERMAL_MON_HOINTSTS2 0x002000 -+#define THERMAL_MON_NHINTSTS2 0x004000 -+#define THERMAL_MON_TOINTSTS 0x008000 -+#define THERMAL_MON_IMMDINTSTS0 0x010000 -+#define THERMAL_MON_IMMDINTSTS1 0x020000 -+#define THERMAL_MON_IMMDINTSTS2 0x040000 -+#define THERMAL_MON_FILTINTSTS0 0x080000 -+#define THERMAL_MON_FILTINTSTS1 0x100000 -+#define THERMAL_MON_FILTINTSTS2 0x200000 -+ -+ -+#define THERMAL_tri_SPM_State0 0x20000000 -+#define THERMAL_tri_SPM_State1 0x40000000 -+#define THERMAL_tri_SPM_State2 0x80000000 -+ -+ -+#define THERMAL_MSRCTL0_MASK 0x00000007 -+#define THERMAL_MSRCTL1_MASK 0x00000038 -+#define THERMAL_MSRCTL2_MASK 0x000001C0 -+ -+enum thermal_sensor_name { -+ THERMAL_SENSOR1 = 0,/*TS_MCU1*/ -+ THERMAL_SENSOR_NUM -+}; -+ -+enum thermal_bank_name { -+ THERMAL_BANK0 = 0, /*CPU (TS_MCU1) (TS1)*/ -+ THERMAL_BANK_NUM -+}; -+ -+struct TS_SVS { -+ unsigned int ts_MTS; -+ unsigned int ts_BTS; -+}; -+ -+struct mtk_gpu_power_info { -+ unsigned int gpufreq_khz; -+ unsigned int gpufreq_power; -+}; -+ -+/* svs driver need this function */ -+extern void get_thermal_slope_intercept(struct TS_SVS *ts_info, enum thermal_bank_name ts_bank); -+ -+/* mtk_thermal_platform.c need this */ -+extern void set_taklking_flag(bool flag); -+ -+#define THERMAL_WRAP_WR32(val, addr) mt_reg_sync_writel((val), ((void *)addr)) -+ -+enum MTK_THERMAL_SENSOR_CPU_ID_MET { -+ MTK_THERMAL_SENSOR_TS1 = 0, -+ MTK_THERMAL_SENSOR_TS2, -+ MTK_THERMAL_SENSOR_TS3, -+ MTK_THERMAL_SENSOR_TS4, -+ MTK_THERMAL_SENSOR_TSABB, -+ -+ ATM_CPU_LIMIT, -+ ATM_GPU_LIMIT, -+ -+ MTK_THERMAL_SENSOR_CPU_COUNT -+}; -+ -+extern int tscpu_get_cpu_temp_met(enum MTK_THERMAL_SENSOR_CPU_ID_MET id); -+extern int mtk_gpufreq_register(struct mtk_gpu_power_info *freqs, int num); -+ -+typedef void (*met_thermalsampler_funcMET)(void); -+void mt_thermalsampler_registerCB(met_thermalsampler_funcMET pCB); -+ -+void tscpu_start_thermal(void); -+void tscpu_stop_thermal(void); -+void tscpu_cancel_thermal_timer(void); -+void tscpu_start_thermal_timer(void); -+int mtkts_bts_get_hw_temp(void); -+ -+extern int get_immediate_ts1_wrap(void); -+extern int get_immediate_ts2_wrap(void); -+extern int get_immediate_ts3_wrap(void); -+ -+extern int is_cpu_power_unlimit(void); /* in mtk_ts_cpu.c */ -+extern int is_cpu_power_min(void); /* in mtk_ts_cpu.c */ -+extern int get_cpu_target_tj(void); -+extern int get_cpu_target_offset(void); -+ -+extern int mtktscpu_debug_log; -+ -+#endif -+ -diff --git a/drivers/misc/mediatek/include/mt-plat/mt8127/include/mach/mt_freqhopping.h b/drivers/misc/mediatek/include/mt-plat/mt8127/include/mach/mt_freqhopping.h -new file mode 100644 -index 000000000000..142a007805b9 ---- /dev/null -+++ b/drivers/misc/mediatek/include/mt-plat/mt8127/include/mach/mt_freqhopping.h -@@ -0,0 +1,159 @@ -+/* -+ * Copyright (C) 2011 MediaTek, Inc. -+ * -+ * Author: Holmes Chiou -+ * -+ * This software is licensed under the terms of the GNU General Public -+ * License version 2, as published by the Free Software Foundation, and -+ * may be copied, distributed, and modified under those terms. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ */ -+ -+#ifndef __MT_FREQHOPPING_H__ -+#define __MT_FREQHOPPING_H__ -+ -+#define MT_FHPLL_MAX 6 -+#define MT_SSC_NR_PREDEFINE_SETTING 10 /* TODO: is 10 a good number ? */ -+ -+#define MEMPLL_SSC 0 -+#define MAINPLL_SSC 1 -+ -+#define FHTAG "[FH]" -+ -+#define VERBOSE_DEBUG 0 -+ -+#if VERBOSE_DEBUG -+#define FH_MSG(fmt, args...) \ -+ pr_debug(FHTAG""fmt" <- %s(): L<%d> PID<%s><%d>\n", ##args, __func__, __LINE__, current->comm, current->pid) -+#else -+ -+#if 1 /* log level is 6 xlog */ -+#define FH_MSG(fmt, args...) pr_debug(fmt, ##args) -+#else /* log level is 4 (printk) */ -+#define FH_MSG(fmt, args...) printk(FHTAG""fmt"\n", ##args) -+#endif -+ -+#endif -+ -+/* not support at mt2701 yet */ -+/* DRAMC */ -+#define FULLY_VERSION_FHCTL 0 -+ -+enum FH_FH_STATUS { -+ FH_FH_DISABLE = 0, -+ FH_FH_ENABLE_SSC, -+ FH_FH_ENABLE_DFH, -+ FH_FH_ENABLE_DVFS, -+}; -+ -+enum FH_PLL_STATUS { -+ FH_PLL_DISABLE = 0, -+ FH_PLL_ENABLE = 1 -+}; -+ -+/* TODO: FREQ_MODIFIED should not be here */ -+/* FH_PLL_STATUS_FREQ_MODIFIED = 3 */ -+ -+ -+enum FH_CMD { -+ FH_CMD_ENABLE = 1, -+ FH_CMD_DISABLE, -+ FH_CMD_ENABLE_USR_DEFINED, -+ FH_CMD_DISABLE_USR_DEFINED, -+ FH_CMD_INTERNAL_MAX_CMD, -+/* TODO: do we need these cmds ? -+ * FH_CMD_PLL_ENABLE, -+ * FH_CMD_PLL_DISABLE, -+ * FH_CMD_EXT_ALL_FULL_RANGE_CMD, -+ * FH_CMD_EXT_ALL_HALF_RANGE_CMD, -+ * FH_CMD_EXT_DISABLE_ALL_CMD, -+ * FH_CMD_EXT_DESIGNATED_PLL_FULL_RANGE_CMD, -+ * FH_CMD_EXT_DESIGNATED_PLL_AND_SETTING_CMD -+*/ -+}; -+ -+/* -+ * enum FH_OPCODE{ -+ * FH_OPCODE_ENABLE_WITH_ID = 1, -+ * FH_OPCODE_ENABLE_WITHOUT_ID, -+ * FH_OPCODE_DISABLE, -+ * }; -+*/ -+ -+enum FH_PLL_ID { -+ MT658X_FH_MINIMUMM_PLL = 0, -+ MT658X_FH_ARM_PLL = MT658X_FH_MINIMUMM_PLL, -+ MT658X_FH_MAIN_PLL = 1, -+ MT658X_FH_MEM_PLL = 2, -+ MT658X_FH_MSDC_PLL = 3, -+ MT658X_FH_MM_PLL = 4, /* MT658X_FH_TVD_PLL = 4, */ -+ MT658X_FH_VENC_PLL = 5, /* MT658X_FH_LVDS_PLL = 5, */ -+ /* 8127 FHCTL MB */ -+ MT658X_FH_TVD_PLL = 6, /* MT658X_FH_TVD_PLL = 6, */ -+ MT658X_FH_MAXIMUMM_PLL = MT658X_FH_TVD_PLL, -+ /* 8127 FHCTL ME */ -+ MT658X_FH_PLL_TOTAL_NUM -+}; -+ -+/* keep track the status of each PLL */ -+/* TODO: do we need another "uint mode" for Dynamic FH */ -+typedef struct { -+ unsigned int fh_status; -+ unsigned int pll_status; -+ unsigned int setting_id; -+ unsigned int curr_freq; -+ unsigned int user_defined; -+} fh_pll_t; -+ -+ -+/* Record the owner of enable freq hopping <==TBD */ -+struct freqhopping_pll { -+ union { -+ int mt_pll[MT_FHPLL_MAX]; -+ struct { -+ int mt_arm_fhpll; -+ int mt_main_fhpll; -+ int mt_mem_fhpll; -+ int mt_msdc_fhpll; -+ int mt_mm_fhpll; -+ int mt_venc_fhpll; -+ }; -+ }; -+}; -+ -+struct freqhopping_ssc { -+ unsigned int freq; -+ unsigned int dt; -+ unsigned int df; -+ unsigned int upbnd; -+ unsigned int lowbnd; -+ unsigned int dds; -+}; -+ -+struct freqhopping_ioctl { -+ unsigned int pll_id; -+ struct freqhopping_ssc ssc_setting; /* used only when user-define */ -+ int result; -+}; -+ -+int freqhopping_config(unsigned int pll_id, unsigned long vco_freq, unsigned int enable); -+void mt_freqhopping_init(void); -+void mt_freqhopping_pll_init(void); -+int mt_h2l_mempll(void); -+int mt_l2h_mempll(void); -+int mt_h2l_dvfs_mempll(void); -+int mt_l2h_dvfs_mempll(void); -+int mt_dfs_armpll(unsigned int current_freq, unsigned int target_freq); -+int mt_is_support_DFS_mode(void); -+void mt_fh_popod_save(void); -+void mt_fh_popod_restore(void); -+int mt_fh_dram_overclock(int clk); -+int mt_fh_get_dramc(void); -+unsigned int mt_get_emi_freq(void); -+ -+#endif /* !__MT_FREQHOPPING_H__ */ -diff --git a/drivers/misc/mediatek/include/mt-plat/mt8127/include/mach/mt_spm_mtcmos.h b/drivers/misc/mediatek/include/mt-plat/mt8127/include/mach/mt_spm_mtcmos.h -new file mode 100644 -index 000000000000..0c049db9aa97 ---- /dev/null -+++ b/drivers/misc/mediatek/include/mt-plat/mt8127/include/mach/mt_spm_mtcmos.h -@@ -0,0 +1,37 @@ -+/* -+ * Copyright (c) 2015 MediaTek Inc. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#include -+ -+#define STA_POWER_DOWN 0 -+#define STA_POWER_ON 1 -+ -+/* -+ * 1. for CPU MTCMOS: CPU0, CPU1, CPU2, CPU3, DBG0, CPU4, CPU5, CPU6, CPU7, DBG1, CPUSYS1 -+ * 2. call spm_mtcmos_cpu_lock/unlock() before/after any operations -+ */ -+extern int spm_mtcmos_cpu_init(void); -+extern void spm_mtcmos_cpu_lock(unsigned long *flags); -+extern void spm_mtcmos_cpu_unlock(unsigned long *flags); -+extern int spm_mtcmos_ctrl_cpu(unsigned int cpu, int state, int chkWfiBeforePdn); -+extern int spm_mtcmos_ctrl_cpu0(int state, int chkWfiBeforePdn); -+extern int spm_mtcmos_ctrl_cpu1(int state, int chkWfiBeforePdn); -+extern int spm_mtcmos_ctrl_cpu2(int state, int chkWfiBeforePdn); -+extern int spm_mtcmos_ctrl_cpu3(int state, int chkWfiBeforePdn); -+extern int spm_mtcmos_ctrl_cpu4(int state, int chkWfiBeforePdn); -+extern int spm_mtcmos_ctrl_cpu5(int state, int chkWfiBeforePdn); -+extern int spm_mtcmos_ctrl_cpu6(int state, int chkWfiBeforePdn); -+extern int spm_mtcmos_ctrl_cpu7(int state, int chkWfiBeforePdn); -+extern int spm_mtcmos_ctrl_cpusys0(int state, int chkWfiBeforePdn); -+extern bool spm_cpusys0_can_power_down(void); -diff --git a/drivers/misc/mediatek/include/mt-plat/mt8127/include/mach/mtk_boot_share_page.h b/drivers/misc/mediatek/include/mt-plat/mt8127/include/mach/mtk_boot_share_page.h -new file mode 100644 -index 000000000000..28176b3cd9af ---- /dev/null -+++ b/drivers/misc/mediatek/include/mt-plat/mt8127/include/mach/mtk_boot_share_page.h -@@ -0,0 +1,40 @@ -+/* -+ * Copyright (c) 2015 MediaTek Inc. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#ifndef __MTK_BOOT_SHARE_PAGE_H__ -+#define __MTK_BOOT_SHARE_PAGE_H__ -+ -+#define BOOT_SHARE_BASE (0xC0002000) /* address in linux kernel */ -+#define BOOT_SHARE_SIZE (0x1000) /* page size 4K bytes */ -+ -+#define BOOT_SHARE_MAGIC (0x4545544D) /* MTEE */ -+ -+/* Memory map & defines for boot share page */ -+/* -+ * Note: -+ * 1. BOOT_SHARE_XXXXX_OFST is the address offset related to BOOT_SHARE_BASE -+ */ -+#define BOOT_SHARE_MAGIC1_OFST (0) -+#define BOOT_SHARE_MAGIC1_SIZE (4) -+ -+#define BOOT_SHARE_DEV_INFO_OFST (BOOT_SHARE_MAGIC1_OFST+BOOT_SHARE_MAGIC1_SIZE) -+#define BOOT_SHARE_DEV_INFO_SIZE (16) -+ -+#define BOOT_SHARE_HOTPLUG_OFST (1008) /* 16 bytes for hotplug/jump-reg */ -+#define BOOT_SHARE_HOTPLUG_SIZE (32) -+ -+#define BOOT_SHARE_MAGIC2_OFST (4092) -+#define BOOT_SHARE_MAGIC2_SIZE (4) -+ -+#endif /* __MTK_BOOT_SHARE_PAGE_H__ */ -diff --git a/drivers/misc/mediatek/include/mt-plat/mt8127/include/mach/mtk_thermal.h b/drivers/misc/mediatek/include/mt-plat/mt8127/include/mach/mtk_thermal.h -new file mode 100644 -index 000000000000..eefdaad4aaa5 ---- /dev/null -+++ b/drivers/misc/mediatek/include/mt-plat/mt8127/include/mach/mtk_thermal.h -@@ -0,0 +1,301 @@ -+/* -+ * Copyright (C) 2016 MediaTek Inc. -+ * -+ * 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. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+ * See http://www.gnu.org/licenses/gpl-2.0.html for more details. -+ */ -+ -+#ifndef _MT8127_THERMAL_H -+#define _MT8127_THERMAL_H -+ -+#include -+#include -+#include -+#include -+ -+#include -+#include -+ -+#include "mt-plat/sync_write.h" -+#include -+ -+/* #include */ -+/* #include "../../../../../thermal/mt8127/inc/mt_gpufreq.h" */ -+ -+#if 1 -+extern void __iomem *thermal_base; -+extern void __iomem *auxadc_ts_base; -+extern void __iomem *pericfg_base; -+extern void __iomem *apmixed_ts_base; -+ -+extern int mtktscpu_limited_dmips; -+ -+void __attribute__ ((weak)) mt_gpufreq_thermal_protect(unsigned int limited_power) { -+} -+ -+unsigned int __attribute__ ((weak)) mt_gpufreq_get_cur_freq(void) { -+ return 0; -+} -+ -+u32 __attribute__ ((weak)) get_devinfo_with_index(u32 index) { -+ return 0; -+} -+ -+extern int IMM_GetOneChannelValue(int dwChannel, int data[4], int *rawdata); -+extern int IMM_IsAdcInitReady(void); -+extern int PMIC_IMM_GetOneChannelValue(int dwChannel, int deCount, int trimd); -+extern int thermal_phy_base; -+extern int auxadc_ts_phy_base; -+extern int apmixed_phy_base; -+extern int pericfg_phy_base; -+ -+/* extern int last_abb_t; */ -+/* extern int last_CPU2_t; */ -+extern int get_immediate_temp2_wrap(void); -+extern void mtkts_dump_cali_info(void); -+extern u32 get_devinfo_with_index(u32 index); -+extern int bts_cur_temp; -+ -+#define THERM_CTRL_BASE_2 thermal_base -+#define AUXADC_BASE_2 auxadc_ts_base -+#define PERICFG_BASE_2 pericfg_base -+#define APMIXED_BASE_2 apmixed_ts_base -+#endif -+ -+/******************************************************************************* -+ * AUXADC Register Definition -+ ******************************************************************************/ -+#define AUXADC_CON0_V (AUXADC_BASE_2 + 0x000) /* yes, 0x11001000 */ -+#define AUXADC_CON1_V (AUXADC_BASE_2 + 0x004) -+#define AUXADC_CON1_SET_V (AUXADC_BASE_2 + 0x008) -+#define AUXADC_CON1_CLR_V (AUXADC_BASE_2 + 0x00C) -+#define AUXADC_CON2_V (AUXADC_BASE_2 + 0x010) -+#define AUXADC_DAT0_V (AUXADC_BASE_2 + 0x014) -+#define AUXADC_DAT1_V (AUXADC_BASE_2 + 0x018) -+#define AUXADC_DAT2_V (AUXADC_BASE_2 + 0x01C) -+#define AUXADC_DAT3_V (AUXADC_BASE_2 + 0x020) -+#define AUXADC_DAT4_V (AUXADC_BASE_2 + 0x024) -+#define AUXADC_DAT5_V (AUXADC_BASE_2 + 0x028) -+#define AUXADC_DAT6_V (AUXADC_BASE_2 + 0x02C) -+#define AUXADC_DAT7_V (AUXADC_BASE_2 + 0x030) -+#define AUXADC_DAT8_V (AUXADC_BASE_2 + 0x034) -+#define AUXADC_DAT9_V (AUXADC_BASE_2 + 0x038) -+#define AUXADC_DAT10_V (AUXADC_BASE_2 + 0x03C) -+#define AUXADC_DAT11_V (AUXADC_BASE_2 + 0x040) -+#define AUXADC_MISC_V (AUXADC_BASE_2 + 0x094) -+#define AUXADC_CON0_P (auxadc_ts_phy_base + 0x000) -+#define AUXADC_CON1_P (auxadc_ts_phy_base + 0x004) -+#define AUXADC_CON1_SET_P (auxadc_ts_phy_base + 0x008) -+#define AUXADC_CON1_CLR_P (auxadc_ts_phy_base + 0x00C) -+#define AUXADC_CON2_P (auxadc_ts_phy_base + 0x010) -+#define AUXADC_DAT0_P (auxadc_ts_phy_base + 0x014) -+#define AUXADC_DAT1_P (auxadc_ts_phy_base + 0x018) -+#define AUXADC_DAT2_P (auxadc_ts_phy_base + 0x01C) -+#define AUXADC_DAT3_P (auxadc_ts_phy_base + 0x020) -+#define AUXADC_DAT4_P (auxadc_ts_phy_base + 0x024) -+#define AUXADC_DAT5_P (auxadc_ts_phy_base + 0x028) -+#define AUXADC_DAT6_P (auxadc_ts_phy_base + 0x02C) -+#define AUXADC_DAT7_P (auxadc_ts_phy_base + 0x030) -+#define AUXADC_DAT8_P (auxadc_ts_phy_base + 0x034) -+#define AUXADC_DAT9_P (auxadc_ts_phy_base + 0x038) -+#define AUXADC_DAT10_P (auxadc_ts_phy_base + 0x03C) -+#define AUXADC_DAT11_P (auxadc_ts_phy_base + 0x040) -+#define AUXADC_MISC_P (auxadc_ts_phy_base + 0x094) -+ -+/******************************************************************************* -+ * Peripheral Configuration Register Definition -+ ******************************************************************************/ -+#define PERI_GLOBALCON_RST0 (PERICFG_BASE_2 + 0x000) /* yes, 0x10003000 */ -+ -+/******************************************************************************* -+ * APMixedSys Configuration Register Definition -+ ******************************************************************************/ -+#define TS_CON0 (APMIXED_BASE_2 + 0x600) /* yes 0x10209000 */ -+#define TS_CON1 (APMIXED_BASE_2 + 0x604) -+/******************************************************************************* -+ * Thermal Controller Register Definition -+ ******************************************************************************/ -+#define TEMPMONCTL0 (THERM_CTRL_BASE_2 + 0x000) /* yes 0x1100B000 */ -+#define TEMPMONCTL1 (THERM_CTRL_BASE_2 + 0x004) -+#define TEMPMONCTL2 (THERM_CTRL_BASE_2 + 0x008) -+#define TEMPMONINT (THERM_CTRL_BASE_2 + 0x00C) -+#define TEMPMONINTSTS (THERM_CTRL_BASE_2 + 0x010) -+#define TEMPMONIDET0 (THERM_CTRL_BASE_2 + 0x014) -+#define TEMPMONIDET1 (THERM_CTRL_BASE_2 + 0x018) -+#define TEMPMONIDET2 (THERM_CTRL_BASE_2 + 0x01C) -+#define TEMPH2NTHRE (THERM_CTRL_BASE_2 + 0x024) -+#define TEMPHTHRE (THERM_CTRL_BASE_2 + 0x028) -+#define TEMPCTHRE (THERM_CTRL_BASE_2 + 0x02C) -+#define TEMPOFFSETH (THERM_CTRL_BASE_2 + 0x030) -+#define TEMPOFFSETL (THERM_CTRL_BASE_2 + 0x034) -+#define TEMPMSRCTL0 (THERM_CTRL_BASE_2 + 0x038) -+#define TEMPMSRCTL1 (THERM_CTRL_BASE_2 + 0x03C) -+#define TEMPAHBPOLL (THERM_CTRL_BASE_2 + 0x040) -+#define TEMPAHBTO (THERM_CTRL_BASE_2 + 0x044) -+#define TEMPADCPNP0 (THERM_CTRL_BASE_2 + 0x048) -+#define TEMPADCPNP1 (THERM_CTRL_BASE_2 + 0x04C) -+#define TEMPADCPNP2 (THERM_CTRL_BASE_2 + 0x050) -+#define TEMPADCPNP3 (THERM_CTRL_BASE_2 + 0x0B4) -+ -+#define TEMPADCMUX (THERM_CTRL_BASE_2 + 0x054) -+#define TEMPADCEXT (THERM_CTRL_BASE_2 + 0x058) -+#define TEMPADCEXT1 (THERM_CTRL_BASE_2 + 0x05C) -+#define TEMPADCEN (THERM_CTRL_BASE_2 + 0x060) -+#define TEMPPNPMUXADDR (THERM_CTRL_BASE_2 + 0x064) -+#define TEMPADCMUXADDR (THERM_CTRL_BASE_2 + 0x068) -+#define TEMPADCEXTADDR (THERM_CTRL_BASE_2 + 0x06C) -+#define TEMPADCEXT1ADDR (THERM_CTRL_BASE_2 + 0x070) -+#define TEMPADCENADDR (THERM_CTRL_BASE_2 + 0x074) -+#define TEMPADCVALIDADDR (THERM_CTRL_BASE_2 + 0x078) -+#define TEMPADCVOLTADDR (THERM_CTRL_BASE_2 + 0x07C) -+#define TEMPRDCTRL (THERM_CTRL_BASE_2 + 0x080) -+#define TEMPADCVALIDMASK (THERM_CTRL_BASE_2 + 0x084) -+#define TEMPADCVOLTAGESHIFT (THERM_CTRL_BASE_2 + 0x088) -+#define TEMPADCWRITECTRL (THERM_CTRL_BASE_2 + 0x08C) -+#define TEMPMSR0 (THERM_CTRL_BASE_2 + 0x090) -+#define TEMPMSR1 (THERM_CTRL_BASE_2 + 0x094) -+#define TEMPMSR2 (THERM_CTRL_BASE_2 + 0x098) -+#define TEMPMSR3 (THERM_CTRL_BASE_2 + 0x0B8) -+ -+#define TEMPIMMD0 (THERM_CTRL_BASE_2 + 0x0A0) -+#define TEMPIMMD1 (THERM_CTRL_BASE_2 + 0x0A4) -+#define TEMPIMMD2 (THERM_CTRL_BASE_2 + 0x0A8) -+ -+#define TEMPPROTCTL (THERM_CTRL_BASE_2 + 0x0C0) -+#define TEMPPROTTA (THERM_CTRL_BASE_2 + 0x0C4) -+#define TEMPPROTTB (THERM_CTRL_BASE_2 + 0x0C8) -+#define TEMPPROTTC (THERM_CTRL_BASE_2 + 0x0CC) -+ -+#define TEMPSPARE0 (THERM_CTRL_BASE_2 + 0x0F0) -+#define TEMPSPARE1 (THERM_CTRL_BASE_2 + 0x0F4) -+#define TEMPSPARE2 (THERM_CTRL_BASE_2 + 0x0F8) -+#define TEMPSPARE3 (THERM_CTRL_BASE_2 + 0x0FC) -+ -+#define PTPCORESEL (THERM_CTRL_BASE_2 + 0x400) -+#define THERMINTST (THERM_CTRL_BASE_2 + 0x404) -+#define PTPODINTST (THERM_CTRL_BASE_2 + 0x408) -+#define THSTAGE0ST (THERM_CTRL_BASE_2 + 0x40C) -+#define THSTAGE1ST (THERM_CTRL_BASE_2 + 0x410) -+#define THSTAGE2ST (THERM_CTRL_BASE_2 + 0x414) -+#define THAHBST0 (THERM_CTRL_BASE_2 + 0x418) -+#define THAHBST1 (THERM_CTRL_BASE_2 + 0x41C) /* Only for DE debug */ -+#define PTPSPARE0 (THERM_CTRL_BASE_2 + 0x420) -+#define PTPSPARE1 (THERM_CTRL_BASE_2 + 0x424) -+#define PTPSPARE2 (THERM_CTRL_BASE_2 + 0x428) -+#define PTPSPARE3 (THERM_CTRL_BASE_2 + 0x42C) -+#define THSLPEVEB (THERM_CTRL_BASE_2 + 0x430) -+ -+/******************************************************************************* -+ * Thermal Controller Register Mask Definition -+ ******************************************************************************/ -+#define THERMAL_ENABLE_SEN0 0x1 -+#define THERMAL_ENABLE_SEN1 0x2 -+#define THERMAL_ENABLE_SEN2 0x4 -+#define THERMAL_MONCTL0_MASK 0x00000007 -+ -+#define THERMAL_PUNT_MASK 0x00000FFF -+#define THERMAL_FSINTVL_MASK 0x03FF0000 -+#define THERMAL_SPINTVL_MASK 0x000003FF -+#define THERMAL_MON_INT_MASK 0x0007FFFF -+ -+#define THERMAL_MON_CINTSTS0 0x000001 -+#define THERMAL_MON_HINTSTS0 0x000002 -+#define THERMAL_MON_LOINTSTS0 0x000004 -+#define THERMAL_MON_HOINTSTS0 0x000008 -+#define THERMAL_MON_NHINTSTS0 0x000010 -+#define THERMAL_MON_CINTSTS1 0x000020 -+#define THERMAL_MON_HINTSTS1 0x000040 -+#define THERMAL_MON_LOINTSTS1 0x000080 -+#define THERMAL_MON_HOINTSTS1 0x000100 -+#define THERMAL_MON_NHINTSTS1 0x000200 -+#define THERMAL_MON_CINTSTS2 0x000400 -+#define THERMAL_MON_HINTSTS2 0x000800 -+#define THERMAL_MON_LOINTSTS2 0x001000 -+#define THERMAL_MON_HOINTSTS2 0x002000 -+#define THERMAL_MON_NHINTSTS2 0x004000 -+#define THERMAL_MON_TOINTSTS 0x008000 -+#define THERMAL_MON_IMMDINTSTS0 0x010000 -+#define THERMAL_MON_IMMDINTSTS1 0x020000 -+#define THERMAL_MON_IMMDINTSTS2 0x040000 -+#define THERMAL_MON_FILTINTSTS0 0x080000 -+#define THERMAL_MON_FILTINTSTS1 0x100000 -+#define THERMAL_MON_FILTINTSTS2 0x200000 -+ -+ -+#define THERMAL_tri_SPM_State0 0x20000000 -+#define THERMAL_tri_SPM_State1 0x40000000 -+#define THERMAL_tri_SPM_State2 0x80000000 -+ -+ -+#define THERMAL_MSRCTL0_MASK 0x00000007 -+#define THERMAL_MSRCTL1_MASK 0x00000038 -+#define THERMAL_MSRCTL2_MASK 0x000001C0 -+ -+/* extern int thermal_one_shot_handler(int times); */ -+ -+typedef enum { -+ THERMAL_SENSOR1 = 0, /* TS1 */ -+ THERMAL_SENSOR_NUM -+} thermal_sensor_name; -+ -+struct TS_PTPOD { -+ unsigned int ts_MTS; -+ unsigned int ts_BTS; -+}; -+ -+extern void get_thermal_slope_intercept(struct TS_PTPOD *ts_info); -+extern void set_taklking_flag(bool flag); -+extern int tscpu_get_cpu_temp(void); -+ -+/*5 thermal sensors*/ -+typedef enum { -+ MTK_THERMAL_SENSOR_TS1 = 0, -+ ATM_CPU_LIMIT, -+ ATM_GPU_LIMIT, -+ MTK_THERMAL_SENSOR_CPU_COUNT -+} MTK_THERMAL_SENSOR_CPU_ID_MET; -+ -+struct mtk_cpu_power_info { -+ unsigned int cpufreq_khz; -+ unsigned int cpufreq_ncpu; -+ unsigned int cpufreq_power; -+}; -+extern int mtk_cpufreq_register(struct mtk_cpu_power_info *freqs, int num); -+ -+extern int tscpu_get_cpu_temp_met(MTK_THERMAL_SENSOR_CPU_ID_MET id); -+ -+ -+typedef void (*met_thermalsampler_funcMET) (void); -+void mt_thermalsampler_registerCB(met_thermalsampler_funcMET pCB); -+ -+void tscpu_start_thermal(void); -+void tscpu_stop_thermal(void); -+void tscpu_cancel_thermal_timer(void); -+void tscpu_start_thermal_timer(void); -+int mtkts_AP_get_hw_temp(void); -+ -+extern int amddulthro_backoff(int level); -+/* extern int IMM_GetOneChannelValue(int dwChannel, int data[4], int *rawdata); */ -+/* extern int IMM_IsAdcInitReady(void); */ -+extern int get_immediate_temp2_wrap(void); -+extern void mtkts_dump_cali_info(void); -+extern unsigned int read_dram_temperature(void); -+extern int mtk_thermal_get_cpu_load_sum(void); -+ -+/********************************** -+ * Power table struct for thermal -+ **********************************/ -+struct mt_gpufreq_power_table_info { -+ unsigned int gpufreq_khz; -+ unsigned int gpufreq_volt; -+ unsigned int gpufreq_power; -+}; -+ -+extern int mtk_gpufreq_register(struct mt_gpufreq_power_table_info *freqs, int num); -+#endif -diff --git a/drivers/misc/mediatek/include/mt-plat/mt_sched.h b/drivers/misc/mediatek/include/mt-plat/mt_sched.h -new file mode 100644 -index 000000000000..71206f080548 ---- /dev/null -+++ b/drivers/misc/mediatek/include/mt-plat/mt_sched.h -@@ -0,0 +1,34 @@ -+/* -+* Copyright (C) 2016 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, -+* but WITHOUT ANY WARRANTY; without even the implied warranty of -+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See http://www.gnu.org/licenses/gpl-2.0.html for more details. -+*/ -+ -+#ifdef CONFIG_MTK_SCHED_RQAVG_US -+/* -+ * @cpu: cpu id -+ * @reset: reset the statistic start time after this time query -+ * @use_maxfreq: caculate cpu loading with max cpu max frequency -+ * return: cpu loading as percentage (0~100) -+ */ -+extern unsigned int sched_get_percpu_load(int cpu, bool reset, bool use_maxfreq); -+ -+/* -+ * return: heavy task(loading>90%) number in the system -+ */ -+extern unsigned int sched_get_nr_heavy_task(void); -+ -+/* -+ * @threshold: heavy task loading threshold (0~1023) -+ * return: heavy task(loading>threshold) number in the system -+ */ -+extern unsigned int sched_get_nr_heavy_task_by_threshold(unsigned int threshold); -+#endif /* CONFIG_MTK_SCHED_RQAVG_US */ -+ -diff --git a/drivers/misc/mediatek/include/mt-plat/mtk_io.h b/drivers/misc/mediatek/include/mt-plat/mtk_io.h -new file mode 100644 -index 000000000000..de17db505d3e ---- /dev/null -+++ b/drivers/misc/mediatek/include/mt-plat/mtk_io.h -@@ -0,0 +1,23 @@ -+/* -+ * Copyright (C) 2015 MediaTek Inc. -+ * -+ * 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. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#ifndef __MT_IO_H__ -+#define __MT_IO_H__ -+ -+/* only for arm64 */ -+#ifdef CONFIG_ARM64 -+#define IOMEM(a) ((void __force __iomem *)((a))) -+#endif -+ -+#endif /* !__MT_IO_H__ */ -+ -diff --git a/drivers/misc/mediatek/include/mt-plat/mtk_lpae.h b/drivers/misc/mediatek/include/mt-plat/mtk_lpae.h -new file mode 100644 -index 000000000000..d679c5a1ce73 ---- /dev/null -+++ b/drivers/misc/mediatek/include/mt-plat/mtk_lpae.h -@@ -0,0 +1,62 @@ -+/* -+ * Copyright (C) 2016 MediaTek Inc. -+ * -+ * 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. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#ifndef __MTK_LPAE_H__ -+#define __MTK_LPAE_H__ -+#ifdef CONFIG_MTK_LM_MODE -+ -+#include -+ -+#define INTERAL_MAPPING_OFFSET (0x40000000) -+#define INTERAL_MAPPING_LIMIT (INTERAL_MAPPING_OFFSET + 0x80000000) -+ -+#define MT_OVERFLOW_ADDR_START 0x100000000ULL -+ -+unsigned int __attribute__((weak)) enable_4G(void) -+{ -+ return 0; -+} -+ -+/* For HW modules which support 33-bit address setting */ -+#define CROSS_OVERFLOW_ADDR_TRANSFER(phy_addr, size, ret) \ -+ do { \ -+ ret = 0; \ -+ if (enable_4G()) {\ -+ if (((phys_addr_t)phy_addr < MT_OVERFLOW_ADDR_START)\ -+ && (((phys_addr_t)phy_addr + size) >= MT_OVERFLOW_ADDR_START)) \ -+ ret = MT_OVERFLOW_ADDR_START - phy_addr; \ -+ } \ -+ } while (0) \ -+ -+/* For SPM and MD32 only in ROME */ -+#define MAPPING_DRAM_ACCESS_ADDR(phy_addr) \ -+ do { \ -+ if (enable_4G()) {\ -+ if (phy_addr >= INTERAL_MAPPING_OFFSET && phy_addr < INTERAL_MAPPING_LIMIT) \ -+ phy_addr += INTERAL_MAPPING_OFFSET; \ -+ } \ -+ } while (0)\ -+ -+#else /* !CONFIG_ARM_LPAE */ -+ -+#define CROSS_OVERFLOW_ADDR_TRANSFER(phy_addr, size, ret) -+#define MAPPING_DRAM_ACCESS_ADDR(phy_addr) -+#define MT_OVERFLOW_ADDR_START 0 -+ -+static inline unsigned int enable_4G(void) -+{ -+ return 0; -+} -+ -+#endif -+#endif /*!__MTK_LPAE_H__ */ -diff --git a/drivers/misc/mediatek/include/mt-plat/mtk_mdm_monitor.h b/drivers/misc/mediatek/include/mt-plat/mtk_mdm_monitor.h -new file mode 100644 -index 000000000000..7baafc4329bf ---- /dev/null -+++ b/drivers/misc/mediatek/include/mt-plat/mtk_mdm_monitor.h -@@ -0,0 +1,42 @@ -+/* -+ * Copyright (C) 2015 MediaTek Inc. -+ * -+ * 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. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#ifndef _MTK_MDM_MONITOR_H -+#define _MTK_MDM_MONITOR_H -+ -+struct md_info { -+ char *attribute; -+ int value; -+ char *unit; -+ int invalid_value; -+ int index; -+}; -+ -+extern -+int mtk_mdm_get_md_info(struct md_info **p_inf, int *size); -+ -+extern -+int mtk_mdm_start_query(void); -+ -+extern -+int mtk_mdm_stop_query(void); -+ -+extern -+int mtk_mdm_set_signal_period(int second); -+ -+extern -+int mtk_mdm_set_md1_signal_period(int second); -+ -+extern -+int mtk_mdm_set_md2_signal_period(int second); -+#endif -diff --git a/drivers/misc/mediatek/include/mt-plat/mtk_platform_debug.h b/drivers/misc/mediatek/include/mt-plat/mtk_platform_debug.h -new file mode 100644 -index 000000000000..8f20f38b75d6 ---- /dev/null -+++ b/drivers/misc/mediatek/include/mt-plat/mtk_platform_debug.h -@@ -0,0 +1,28 @@ -+/* -+ * Copyright (C) 2016 MediaTek Inc. -+ * -+ * 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. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#ifndef __MTK_PLATFORM_DEBUG_H__ -+#define __MTK_PLATFORM_DEBUG_H__ -+ -+#ifdef CONFIG_MTK_PLAT_SRAM_FLAG -+/* plat_sram_flag */ -+extern int set_sram_flag_lastpc_valid(void); -+extern int set_sram_flag_dfd_valid(void); -+extern int set_sram_flag_etb_user(unsigned int etb_id, unsigned int user_id); -+#endif -+ -+#ifdef CONFIG_MTK_DFD_INTERNAL_DUMP -+extern int dfd_setup(void); -+#endif -+ -+#endif /* __MTK_PLATFORM_DEBUG_H__ */ -diff --git a/drivers/misc/mediatek/include/mt-plat/mtk_ram_console.h b/drivers/misc/mediatek/include/mt-plat/mtk_ram_console.h -new file mode 100644 -index 000000000000..3a94a1bbcd24 ---- /dev/null -+++ b/drivers/misc/mediatek/include/mt-plat/mtk_ram_console.h -@@ -0,0 +1,162 @@ -+/* -+ * Copyright (C) 2015 MediaTek Inc. -+ * -+ * 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. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#ifndef __MTK_RAM_CONSOLE_H__ -+#define __MTK_RAM_CONSOLE_H__ -+ -+#include -+#include -+ -+typedef enum { -+ AEE_FIQ_STEP_FIQ_ISR_BASE = 1, -+ AEE_FIQ_STEP_WDT_FIQ_INFO = 4, -+ AEE_FIQ_STEP_WDT_FIQ_STACK, -+ AEE_FIQ_STEP_WDT_FIQ_LOOP, -+ AEE_FIQ_STEP_WDT_FIQ_DONE, -+ AEE_FIQ_STEP_WDT_IRQ_INFO = 8, -+ AEE_FIQ_STEP_WDT_IRQ_KICK, -+ AEE_FIQ_STEP_WDT_IRQ_SMP_STOP, -+ AEE_FIQ_STEP_WDT_IRQ_TIME, -+ AEE_FIQ_STEP_WDT_IRQ_STACK, -+ AEE_FIQ_STEP_WDT_IRQ_GIC, -+ AEE_FIQ_STEP_WDT_IRQ_LOCALTIMER, -+ AEE_FIQ_STEP_WDT_IRQ_IDLE, -+ AEE_FIQ_STEP_WDT_IRQ_SCHED, -+ AEE_FIQ_STEP_WDT_IRQ_DONE, -+ AEE_FIQ_STEP_KE_WDT_INFO = 20, -+ AEE_FIQ_STEP_KE_WDT_PERCPU, -+ AEE_FIQ_STEP_KE_WDT_LOG, -+ AEE_FIQ_STEP_KE_SCHED_DEBUG, -+ AEE_FIQ_STEP_KE_EINT_DEBUG, -+ AEE_FIQ_STEP_KE_WDT_DONE, -+ AEE_FIQ_STEP_KE_IPANIC_DIE = 32, -+ AEE_FIQ_STEP_KE_IPANIC_START, -+ AEE_FIQ_STEP_KE_IPANIC_OOP_HEADER, -+ AEE_FIQ_STEP_KE_IPANIC_DETAIL, -+ AEE_FIQ_STEP_KE_IPANIC_CONSOLE, -+ AEE_FIQ_STEP_KE_IPANIC_USERSPACE, -+ AEE_FIQ_STEP_KE_IPANIC_ANDROID, -+ AEE_FIQ_STEP_KE_IPANIC_MMPROFILE, -+ AEE_FIQ_STEP_KE_IPANIC_HEADER, -+ AEE_FIQ_STEP_KE_IPANIC_DONE, -+ AEE_FIQ_STEP_KE_NESTED_PANIC = 64, -+} AEE_FIQ_STEP_NUM; -+ -+#ifdef CONFIG_MTK_RAM_CONSOLE -+extern int aee_rr_curr_fiq_step(void); -+extern void aee_rr_rec_fiq_step(u8 i); -+extern void aee_rr_rec_reboot_mode(u8 mode); -+extern void aee_rr_rec_kdump_params(void *params); -+extern void aee_rr_rec_last_irq_enter(int cpu, int irq, u64 j); -+extern void aee_rr_rec_last_irq_exit(int cpu, int irq, u64 j); -+extern void aee_rr_rec_last_sched_jiffies(int cpu, u64 j, const char *comm); -+extern void aee_sram_fiq_log(const char *msg); -+extern void ram_console_write(struct console *console, const char *s, unsigned int count); -+extern void aee_sram_fiq_save_bin(const char *buffer, size_t len); -+extern void aee_rr_rec_hotplug_footprint(int cpu, u8 fp); -+extern void aee_rr_rec_hotplug_cpu_event(u8 val); -+extern void aee_rr_rec_hotplug_cb_index(u8 val); -+extern void aee_rr_rec_hotplug_cb_fp(unsigned long val); -+#ifdef CONFIG_MTK_EMMC_SUPPORT -+extern void last_kmsg_store_to_emmc(void); -+#endif -+ -+#else -+static inline void aee_rr_rec_hotplug_footprint(int cpu, u8 fp) -+{ -+} -+static inline void aee_rr_rec_hotplug_cpu_event(u8 val) -+{ -+} -+static inline void aee_rr_rec_hotplug_cb_index(u8 val) -+{ -+} -+static inline void aee_rr_rec_hotplug_cb_fp(unsigned long val) -+{ -+} -+static inline int aee_rr_curr_fiq_step(void) -+{ -+ return 0; -+} -+ -+static inline void aee_rr_rec_fiq_step(u8 i) -+{ -+} -+ -+static inline unsigned int aee_rr_curr_exp_type(void) -+{ -+ return 0; -+} -+ -+static inline void aee_rr_rec_exp_type(unsigned int type) -+{ -+} -+ -+static inline void aee_rr_rec_reboot_mode(u8 mode) -+{ -+} -+ -+static inline void aee_rr_rec_kdump_params(void *params) -+{ -+} -+ -+static inline void aee_rr_rec_last_irq_enter(int cpu, int irq, u64 j) -+{ -+} -+ -+static inline void aee_rr_rec_last_irq_exit(int cpu, int irq, u64 j) -+{ -+} -+ -+static inline void aee_rr_rec_last_sched_jiffies(int cpu, u64 j, const char *comm) -+{ -+} -+ -+static inline void aee_sram_fiq_log(const char *msg) -+{ -+} -+ -+static inline void ram_console_write(struct console *console, const char *s, unsigned int count) -+{ -+} -+ -+static inline void aee_sram_fiq_save_bin(unsigned char *buffer, size_t len) -+{ -+} -+ -+#ifdef CONFIG_MTK_EMMC_SUPPORT -+static inline void last_kmsg_store_to_emmc(void) -+{ -+} -+#endif -+ -+#endif /* CONFIG_MTK_RAM_CONSOLE */ -+ -+#ifdef CONFIG_MTK_AEE_IPANIC -+extern int ipanic_kmsg_write(unsigned int part, const char *buf, size_t size); -+extern int ipanic_kmsg_get_next(int *count, u64 *id, enum pstore_type_id *type, struct timespec *time, -+ char **buf, struct pstore_info *psi); -+#else -+static inline int ipanic_kmsg_write(unsigned int part, const char *buf, size_t size) -+{ -+ return 0; -+} -+ -+static inline int ipanic_kmsg_get_next(int *count, u64 *id, enum pstore_type_id *type, struct timespec *time, -+ char **buf, struct pstore_info *psi) -+{ -+ return 0; -+} -+#endif /* CONFIG_MTK_AEE_IPANIC */ -+ -+#endif -diff --git a/drivers/misc/mediatek/include/mt-plat/mtk_rtc.h b/drivers/misc/mediatek/include/mt-plat/mtk_rtc.h -new file mode 100644 -index 000000000000..2181e9989593 ---- /dev/null -+++ b/drivers/misc/mediatek/include/mt-plat/mtk_rtc.h -@@ -0,0 +1,85 @@ -+/* -+ * Copyright (C) 2015 MediaTek Inc. -+ * -+ * 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. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#ifndef MTK_RTC_H -+#define MTK_RTC_H -+ -+#include -+#include -+#include -+ -+typedef enum { -+ RTC_GPIO_USER_WIFI = 8, -+ RTC_GPIO_USER_GPS = 9, -+ RTC_GPIO_USER_BT = 10, -+ RTC_GPIO_USER_FM = 11, -+ RTC_GPIO_USER_PMIC = 12, -+} rtc_gpio_user_t; -+ -+#ifdef CONFIG_MTK_RTC -+ -+/* -+ * NOTE: -+ * 1. RTC_GPIO always exports 32K enabled by some user even if the phone is powered off -+ */ -+ -+extern unsigned long rtc_read_hw_time(void); -+extern void rtc_gpio_enable_32k(rtc_gpio_user_t user); -+extern void rtc_gpio_disable_32k(rtc_gpio_user_t user); -+extern bool rtc_gpio_32k_status(void); -+ -+/* for AUDIOPLL (deprecated) */ -+extern void rtc_enable_abb_32k(void); -+extern void rtc_disable_abb_32k(void); -+ -+/* NOTE: used in Sleep driver to workaround Vrtc-Vore level shifter issue */ -+extern void rtc_enable_writeif(void); -+extern void rtc_disable_writeif(void); -+ -+extern void rtc_mark_recovery(void); -+#if defined(CONFIG_MTK_KERNEL_POWER_OFF_CHARGING) -+extern void rtc_mark_kpoc(void); -+#endif/*if defined(CONFIG_MTK_KERNEL_POWER_OFF_CHARGING)*/ -+extern void rtc_mark_fast(void); -+extern u16 rtc_rdwr_uart_bits(u16 *val); -+extern void rtc_bbpu_power_down(void); -+extern void rtc_read_pwron_alarm(struct rtc_wkalrm *alm); -+extern int get_rtc_spare_fg_value(void); -+extern int set_rtc_spare_fg_value(int val); -+extern void rtc_irq_handler(void); -+extern bool crystal_exist_status(void); -+extern void mt_power_off(void); -+#else/*ifdef CONFIG_MTK_RTC*/ -+#define rtc_read_hw_time() ({ 0; }) -+#define rtc_gpio_enable_32k(user) do {} while (0) -+#define rtc_gpio_disable_32k(user) do {} while (0) -+#define rtc_gpio_32k_status() do {} while (0) -+#define rtc_enable_abb_32k() do {} while (0) -+#define rtc_disable_abb_32k() do {} while (0) -+#define rtc_enable_writeif() do {} while (0) -+#define rtc_disable_writeif() do {} while (0) -+#define rtc_mark_recovery() do {} while (0) -+#if defined(CONFIG_MTK_KERNEL_POWER_OFF_CHARGING) -+#define rtc_mark_kpoc() do {} while (0) -+#endif/*if defined(CONFIG_MTK_KERNEL_POWER_OFF_CHARGING)*/ -+#define rtc_mark_fast() do {} while (0) -+#define rtc_rdwr_uart_bits(val) ({ 0; }) -+#define rtc_bbpu_power_down() do {} while (0) -+#define rtc_read_pwron_alarm(alm) do {} while (0) -+#define get_rtc_spare_fg_value() ({ 0; }) -+#define set_rtc_spare_fg_value(val) ({ 0; }) -+#define rtc_irq_handler() do {} while (0) -+#define crystal_exist_status() do {} while (0) -+__weak void mt_power_off(void); -+#endif/*ifdef CONFIG_MTK_RTC*/ -+#endif -diff --git a/drivers/misc/mediatek/include/mt-plat/mtk_thermal_ext_control.h b/drivers/misc/mediatek/include/mt-plat/mtk_thermal_ext_control.h -new file mode 100644 -index 000000000000..eac6bc713c98 ---- /dev/null -+++ b/drivers/misc/mediatek/include/mt-plat/mtk_thermal_ext_control.h -@@ -0,0 +1,69 @@ -+/* -+ * Copyright (c) 2009 Travis Geiselbrecht -+ * -+ * Permission is hereby granted, free of charge, to any person obtaining -+ * a copy of this software and associated documentation files -+ * (the "Software"), to deal in the Software without restriction, -+ * including without limitation the rights to use, copy, modify, merge, -+ * publish, distribute, sublicense, and/or sell copies of the Software, -+ * and to permit persons to whom the Software is furnished to do so, -+ * subject to the following conditions: -+ * -+ * The above copyright notice and this permission notice shall be -+ * included in all copies or substantial portions of the Software. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+ */ -+ -+#ifndef _MTK_THERMAL_EXT_CONTROL_H -+#define _MTK_THERMAL_EXT_CONTROL_H -+ -+#define THERMAL_MD32_IPI_MSG_BASE 0x1F00 -+#define THERMAL_AP_IPI_MSG_BASE 0x2F00 -+ -+typedef enum { -+ THERMAL_AP_IPI_MSG_SET_TZ_THRESHOLD = THERMAL_AP_IPI_MSG_BASE, -+ THERMAL_AP_IPI_MSG_MD32_START, -+ -+ THERMAL_MD32_IPI_MSG_READY = THERMAL_MD32_IPI_MSG_BASE, -+ THERMAL_MD32_IPI_MSG_MD32_START_ACK, -+ THERMAL_MD32_IPI_MSG_REACH_THRESHOLD, -+} thermal_ipi_msg_id; -+ -+typedef enum { -+/* MTK_THERMAL_EXT_SENSOR_CPU = 0, */ -+ MTK_THERMAL_EXT_SENSOR_ABB = 0, -+ MTK_THERMAL_EXT_SENSOR_PMIC, -+ MTK_THERMAL_EXT_SENSOR_BATTERY, -+ MTK_THERMAL_EXT_SENSOR_COUNT -+} MTK_THERMAL_EXT_SENSOR_ID; -+ -+typedef struct { -+ int id; /* id of this tz */ -+ int polling_delay; /* polling delay of this tz */ -+ long high_trip_point; /* high threshold of this tz */ -+ long low_trip_point; /* low threshold of this tz */ -+} thermal_zone_data; -+ -+typedef struct { -+ int id; /* id of this tz */ -+ long high_trip_point; /* high threshold of this tz */ -+ long low_trip_point; /* low threshold of this tz */ -+ long temperature; /* Current temperature gotten from TS */ -+} thermal_zone_status; -+ -+typedef struct { -+ short id; -+ union { -+ thermal_zone_data tz; -+ thermal_zone_status tz_status; -+ } data; -+} thermal_ipi_msg; -+ -+#endif /* _MTK_THERMAL_EXT_CONTROL_H */ -diff --git a/drivers/misc/mediatek/include/mt-plat/mtk_thermal_monitor.h b/drivers/misc/mediatek/include/mt-plat/mtk_thermal_monitor.h -new file mode 100644 -index 000000000000..7903b49dc419 ---- /dev/null -+++ b/drivers/misc/mediatek/include/mt-plat/mtk_thermal_monitor.h -@@ -0,0 +1,102 @@ -+/* -+ * Copyright (C) 2015 MediaTek Inc. -+ * -+ * 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. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#ifndef _MTK_THERMAL_MONITOR_H -+#define _MTK_THERMAL_MONITOR_H -+ -+#include -+ -+/* -+ * MTK_THERMAL_WRAPPER_BYPASS = 1 (use original Linux Thermal API) -+ * MTK_THERMAL_WRAPPER_BYPASS = 0 (use MTK Thermal API Monitor) -+ */ -+#define MTK_THERMAL_WRAPPER_BYPASS 0 -+ -+#if MTK_THERMAL_WRAPPER_BYPASS -+/* Original LTF API */ -+#define mtk_thermal_zone_device_register thermal_zone_device_register -+#define mtk_thermal_zone_device_unregister thermal_zone_device_unregister -+#define mtk_thermal_cooling_device_unregister thermal_cooling_device_unregister -+#define mtk_thermal_cooling_device_register thermal_cooling_device_register -+#define mtk_thermal_zone_bind_cooling_device thermal_zone_bind_cooling_device -+ -+#else -+ -+struct thermal_cooling_device_ops_extra { -+ int (*set_cur_temp)(struct thermal_cooling_device *, unsigned long); -+}; -+ -+extern -+struct thermal_zone_device *mtk_thermal_zone_device_register_wrapper -+(char *type, int trips, void *devdata, const struct thermal_zone_device_ops *ops, -+int tc1, int tc2, int passive_delay, int polling_delay); -+ -+extern -+void mtk_thermal_zone_device_unregister_wrapper(struct thermal_zone_device *tz); -+ -+extern -+struct thermal_cooling_device *mtk_thermal_cooling_device_register_wrapper -+(char *type, void *devdata, const struct thermal_cooling_device_ops *ops); -+ -+extern -+struct thermal_cooling_device *mtk_thermal_cooling_device_register_wrapper_extra -+(char *type, void *devdata, const struct thermal_cooling_device_ops *ops, -+const struct thermal_cooling_device_ops_extra *ops_ext); -+ -+extern -+int mtk_thermal_cooling_device_add_exit_point -+(struct thermal_cooling_device *cdev, int exit_point); -+ -+extern -+void mtk_thermal_cooling_device_unregister_wrapper(struct thermal_cooling_device *cdev); -+ -+extern int mtk_thermal_zone_bind_cooling_device_wrapper -+(struct thermal_zone_device *tz, int trip, struct thermal_cooling_device *cdev); -+ -+extern int mtk_thermal_zone_bind_trigger_trip(struct thermal_zone_device *tz, int trip, int mode); -+#define mtk_thermal_zone_device_register mtk_thermal_zone_device_register_wrapper -+#define mtk_thermal_zone_device_unregister mtk_thermal_zone_device_unregister_wrapper -+#define mtk_thermal_cooling_device_unregister mtk_thermal_cooling_device_unregister_wrapper -+#define mtk_thermal_cooling_device_register mtk_thermal_cooling_device_register_wrapper -+#define mtk_thermal_zone_bind_cooling_device mtk_thermal_zone_bind_cooling_device_wrapper -+ -+#endif -+ -+typedef enum { -+ MTK_THERMAL_SENSOR_CPU = 0, -+ MTK_THERMAL_SENSOR_ABB, -+ MTK_THERMAL_SENSOR_PMIC, -+ MTK_THERMAL_SENSOR_BATTERY, -+ MTK_THERMAL_SENSOR_MD1, -+ MTK_THERMAL_SENSOR_MD2, -+ MTK_THERMAL_SENSOR_WIFI, -+ MTK_THERMAL_SENSOR_BATTERY2, -+ MTK_THERMAL_SENSOR_BUCK, -+ MTK_THERMAL_SENSOR_AP, -+ MTK_THERMAL_SENSOR_PCB1, -+ MTK_THERMAL_SENSOR_PCB2, -+ MTK_THERMAL_SENSOR_SKIN, -+ MTK_THERMAL_SENSOR_XTAL, -+ MTK_THERMAL_SENSOR_MD_PA, -+ -+ MTK_THERMAL_SENSOR_COUNT -+} MTK_THERMAL_SENSOR_ID; -+ -+extern int mtk_thermal_get_temp(MTK_THERMAL_SENSOR_ID id); -+extern struct proc_dir_entry *mtk_thermal_get_proc_drv_therm_dir_entry(void); -+ -+/* This API function is implemented in mediatek/kernel/drivers/leds/leds.c */ -+extern int setMaxbrightness(int max_level, int enable); -+ -+extern void machine_power_off(void); -+#endif -diff --git a/drivers/misc/mediatek/include/mt-plat/mtk_thermal_platform.h b/drivers/misc/mediatek/include/mt-plat/mtk_thermal_platform.h -new file mode 100644 -index 000000000000..305574031196 ---- /dev/null -+++ b/drivers/misc/mediatek/include/mt-plat/mtk_thermal_platform.h -@@ -0,0 +1,114 @@ -+/* -+ * Copyright (C) 2015 MediaTek Inc. -+ * -+ * 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. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#ifndef _MTK_THERMAL_PLATFORM_H -+#define _MTK_THERMAL_PLATFORM_H -+ -+#include -+#include -+ -+extern -+int mtk_thermal_get_cpu_info(int *nocores, int **cpufreq, int **cpuloading); -+ -+extern -+int mtk_thermal_get_gpu_info(int *nocores, int **gpufreq, int **gpuloading); -+ -+extern -+int mtk_thermal_get_batt_info(int *batt_voltage, int *batt_current, int *batt_temp); -+ -+extern -+int mtk_thermal_get_extra_info(int *no_extra_attr, -+ char ***attr_names, int **attr_values, char ***attr_unit); -+ -+extern -+int mtk_thermal_force_get_batt_temp(void); -+ -+ -+enum { -+ MTK_THERMAL_SCEN_CALL = 0x1 -+}; -+ -+extern -+unsigned int mtk_thermal_set_user_scenarios(unsigned int mask); -+ -+extern -+unsigned int mtk_thermal_clear_user_scenarios(unsigned int mask); -+ -+ -+#if defined(CONFIG_MTK_SMART_BATTERY) -+/* global variable from battery driver... */ -+extern kal_bool gFG_Is_Charging; -+#endif -+ -+extern int force_get_tbat(void); -+#endif /* _MTK_THERMAL_PLATFORM_H */ -+ -+ -+typedef enum { -+ TA_DAEMON_CMD_GET_INIT_FLAG = 0, -+ TA_DAEMON_CMD_SET_DAEMON_PID, -+ TA_DAEMON_CMD_NOTIFY_DAEMON, -+ TA_DAEMON_CMD_NOTIFY_DAEMON_CATMINIT, -+ TA_DAEMON_CMD_SET_TTJ, -+ TA_DAEMON_CMD_GET_TPCB, -+ -+ TA_DAEMON_CMD_TO_KERNEL_NUMBER -+} TA_DAEMON_CTRL_CMD_TO_KERNEL; /*must sync userspace/kernel: TA_DAEMON_CTRL_CMD_FROM_USER*/ -+ -+#define TAD_NL_MSG_T_HDR_LEN 12 -+#define TAD_NL_MSG_MAX_LEN 2048 -+ -+struct tad_nl_msg_t { -+ unsigned int tad_cmd; -+ unsigned int tad_data_len; -+ unsigned int tad_ret_data_len; -+ char tad_data[TAD_NL_MSG_MAX_LEN]; -+}; -+ -+enum { -+ TA_CATMPLUS = 1, -+ TA_CONTINUOUS = 2, -+ TA_CATMPLUS_TTJ = 3 -+}; -+ -+ -+struct cATM_params_t { -+ int CATM_ON; -+ int K_TT; -+ int K_SUM_TT_LOW; -+ int K_SUM_TT_HIGH; -+ int MIN_SUM_TT; -+ int MAX_SUM_TT; -+ int MIN_TTJ; -+ int CATMP_STEADY_TTJ_DELTA; -+}; -+struct continuetm_params_t { -+ int STEADY_TARGET_TJ; -+ int MAX_TARGET_TJ; -+ int TRIP_TPCB; -+ int STEADY_TARGET_TPCB; -+}; -+ -+ -+struct CATM_T { -+ struct cATM_params_t t_catm_par; -+ struct continuetm_params_t t_continuetm_par; -+}; -+extern struct CATM_T thermal_atm_t; -+int wakeup_ta_algo(int flow_state); -+int ta_get_ttj(void); -+ -+extern int mtk_thermal_get_tpcb_target(void); -+extern int tsatm_thermal_get_catm_type(void); -+ -+ -diff --git a/drivers/misc/mediatek/include/mt-plat/mtk_thermal_trace.h b/drivers/misc/mediatek/include/mt-plat/mtk_thermal_trace.h -new file mode 100644 -index 000000000000..1c23a9f4a862 ---- /dev/null -+++ b/drivers/misc/mediatek/include/mt-plat/mtk_thermal_trace.h -@@ -0,0 +1,47 @@ -+/* -+ * Copyright (C) 2015 MediaTek Inc. -+ * -+ * 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. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#undef TRACE_SYSTEM -+#define TRACE_SYSTEM thermal -+ -+#if !defined(_MTK_THERMAL_TRACE_H) || defined(TRACE_HEADER_MULTI_READ) -+#define _MTK_THERMAL_TRACE_H -+ -+#include -+ -+TRACE_EVENT(cooling_device_state, -+ TP_PROTO(int device, unsigned long state), -+ TP_ARGS(device, state), TP_STRUCT__entry(__field(int, device) -+ __field(unsigned long, state) -+ ), -+ TP_fast_assign(__entry->device = device; -+ __entry->state = state;), -+ TP_printk("cooling_device=%d, state=%lu\n", __entry->device, __entry->state) -+); -+ -+TRACE_EVENT(thermal_zone_state, -+ TP_PROTO(int device, int state), -+ TP_ARGS(device, state), TP_STRUCT__entry(__field(int, device) -+ __field(int, state) -+ ), -+ TP_fast_assign(__entry->device = device; -+ __entry->state = state;), -+ TP_printk("thermal_zone=%d, state=%d\n", __entry->device, __entry->state) -+); -+#endif /* _MTK_THERMAL_TRACE_H */ -+ -+/* This part must be outside protection */ -+#undef TRACE_INCLUDE_PATH -+#define TRACE_INCLUDE_PATH . -+#define TRACE_INCLUDE_FILE mach/mtk_thermal_trace -+#include -diff --git a/drivers/misc/mediatek/include/mt-plat/mtk_thermal_typedefs.h b/drivers/misc/mediatek/include/mt-plat/mtk_thermal_typedefs.h -new file mode 100644 -index 000000000000..dfcef3d952fc ---- /dev/null -+++ b/drivers/misc/mediatek/include/mt-plat/mtk_thermal_typedefs.h -@@ -0,0 +1,241 @@ -+/* -+ * Copyright (C) 2015 MediaTek Inc. -+ * -+ * 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. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#ifndef _TYPEDEFS_H -+#define _TYPEDEFS_H -+ -+#include -+ -+/* --------------------------------------------------------------------------- */ -+/* Basic Type Definitions */ -+/* --------------------------------------------------------------------------- */ -+ -+typedef volatile unsigned char *P_kal_uint8; -+typedef volatile unsigned short *P_kal_uint16; -+typedef volatile unsigned int *P_kal_uint32; -+ -+typedef long LONG; -+typedef unsigned char UBYTE; -+typedef short SHORT; -+ -+typedef signed char kal_int8; -+typedef signed short kal_int16; -+typedef signed int kal_int32; -+typedef long long kal_int64; -+typedef unsigned char kal_uint8; -+typedef unsigned short kal_uint16; -+typedef unsigned int kal_uint32; -+typedef unsigned long long kal_uint64; -+typedef char kal_char; -+ -+typedef unsigned int *UINT32P; -+typedef volatile unsigned short *UINT16P; -+typedef volatile unsigned char *UINT8P; -+typedef unsigned char *U8P; -+ -+typedef volatile unsigned char *P_U8; -+typedef volatile signed char *P_S8; -+typedef volatile unsigned short *P_U16; -+typedef volatile signed short *P_S16; -+typedef volatile unsigned int *P_U32; -+typedef volatile signed int *P_S32; -+typedef unsigned long long *P_U64; -+typedef signed long long *P_S64; -+ -+typedef unsigned char U8; -+typedef signed char S8; -+typedef unsigned short U16; -+typedef signed short S16; -+typedef unsigned int U32; -+typedef signed int S32; -+typedef unsigned long long U64; -+typedef signed long long S64; -+/* typedef unsigned char bool; */ -+ -+typedef unsigned char UINT8; -+typedef unsigned short UINT16; -+typedef unsigned int UINT32; -+typedef unsigned short USHORT; -+typedef signed char INT8; -+typedef signed short INT16; -+typedef signed int INT32; -+typedef unsigned int DWORD; -+typedef void VOID; -+typedef unsigned char BYTE; -+typedef float FLOAT; -+ -+typedef char *LPCSTR; -+typedef short *LPWSTR; -+ -+ -+/* --------------------------------------------------------------------------- */ -+/* Constants */ -+/* --------------------------------------------------------------------------- */ -+ -+#ifndef FALSE -+#define FALSE (0) -+#endif -+ -+#ifndef TRUE -+#define TRUE (1) -+#endif -+ -+#ifndef NULL -+#define NULL (0) -+#endif -+ -+/* enum boolean {false, true}; */ -+enum { RX, TX, NONE }; -+ -+#ifndef BOOL -+typedef unsigned char BOOL; -+#endif -+ -+#ifndef BATTERY_BOOL -+#define BATTERY_BOOL -+typedef enum { -+ KAL_FALSE = 0, -+ KAL_TRUE = 1, -+} kal_bool; -+#endif -+ -+/* --------------------------------------------------------------------------- */ -+/* Type Casting */ -+/* --------------------------------------------------------------------------- */ -+ -+#define AS_INT32(x) (*(INT32 *)((void *)x)) -+#define AS_INT16(x) (*(INT16 *)((void *)x)) -+#define AS_INT8(x) (*(INT8 *)((void *)x)) -+ -+#define AS_UINT32(x) (*(UINT32 *)((void *)x)) -+#define AS_UINT16(x) (*(UINT16 *)((void *)x)) -+#define AS_UINT8(x) (*(UINT8 *)((void *)x)) -+ -+ -+/* --------------------------------------------------------------------------- */ -+/* Register Manipulations */ -+/* --------------------------------------------------------------------------- */ -+ -+#define READ_REGISTER_UINT32(reg) \ -+ (*(volatile UINT32 * const)(reg)) -+ -+#define WRITE_REGISTER_UINT32(reg, val) \ -+ ((*(volatile UINT32 * const)(reg)) = (val)) -+ -+#define READ_REGISTER_UINT16(reg) \ -+ ((*(volatile UINT16 * const)(reg))) -+ -+#define WRITE_REGISTER_UINT16(reg, val) \ -+ ((*(volatile UINT16 * const)(reg)) = (val)) -+ -+#define READ_REGISTER_UINT8(reg) \ -+ ((*(volatile UINT8 * const)(reg))) -+ -+#define WRITE_REGISTER_UINT8(reg, val) \ -+ ((*(volatile UINT8 * const)(reg)) = (val)) -+ -+#define INREG8(x) READ_REGISTER_UINT8((UINT8 *)((void *)(x))) -+#define OUTREG8(x, y) WRITE_REGISTER_UINT8((UINT8 *)((void *)(x)), (UINT8)(y)) -+#define SETREG8(x, y) OUTREG8(x, INREG8(x)|(y)) -+#define CLRREG8(x, y) OUTREG8(x, INREG8(x)&~(y)) -+#define MASKREG8(x, y, z) OUTREG8(x, (INREG8(x)&~(y))|(z)) -+ -+#define INREG16(x) READ_REGISTER_UINT16((UINT16 *)((void *)(x))) -+#define OUTREG16(x, y) WRITE_REGISTER_UINT16((UINT16 *)((void *)(x)), (UINT16)(y)) -+#define SETREG16(x, y) OUTREG16(x, INREG16(x)|(y)) -+#define CLRREG16(x, y) OUTREG16(x, INREG16(x)&~(y)) -+#define MASKREG16(x, y, z) OUTREG16(x, (INREG16(x)&~(y))|(z)) -+ -+#define INREG32(x) READ_REGISTER_UINT32((UINT32 *)((void *)(x))) -+#define OUTREG32(x, y) WRITE_REGISTER_UINT32((UINT32 *)((void *)(x)), (UINT32)(y)) -+#define SETREG32(x, y) OUTREG32(x, INREG32(x)|(y)) -+#define CLRREG32(x, y) OUTREG32(x, INREG32(x)&~(y)) -+#define MASKREG32(x, y, z) OUTREG32(x, (INREG32(x)&~(y))|(z)) -+ -+ -+#define DRV_Reg8(addr) INREG8(addr) -+#define DRV_WriteReg8(addr, data) OUTREG8(addr, data) -+#define DRV_SetReg8(addr, data) SETREG8(addr, data) -+#define DRV_ClrReg8(addr, data) CLRREG8(addr, data) -+ -+#define DRV_Reg16(addr) INREG16(addr) -+#define DRV_WriteReg16(addr, data) OUTREG16(addr, data) -+#define DRV_SetReg16(addr, data) SETREG16(addr, data) -+#define DRV_ClrReg16(addr, data) CLRREG16(addr, data) -+ -+#define DRV_Reg32(addr) INREG32(addr) -+#define DRV_WriteReg32(addr, data) OUTREG32(addr, data) -+#define DRV_SetReg32(addr, data) SETREG32(addr, data) -+#define DRV_ClrReg32(addr, data) CLRREG32(addr, data) -+ -+/* !!! DEPRECATED, WILL BE REMOVED LATER !!! */ -+#define DRV_Reg(addr) DRV_Reg16(addr) -+#define DRV_WriteReg(addr, data) DRV_WriteReg16(addr, data) -+#define DRV_SetReg(addr, data) DRV_SetReg16(addr, data) -+#define DRV_ClrReg(addr, data) DRV_ClrReg16(addr, data) -+ -+ -+/* --------------------------------------------------------------------------- */ -+/* Compiler Time Deduction Macros */ -+/* --------------------------------------------------------------------------- */ -+ -+ -+ -+/* --------------------------------------------------------------------------- */ -+/* Assertions */ -+/* --------------------------------------------------------------------------- */ -+ -+/* -+*#ifndef ASSERT -+*#define ASSERT(expr) BUG_ON(!(expr)) -+*#endif -+* -+*#ifndef NOT_IMPLEMENTED -+*#define NOT_IMPLEMENTED() BUG_ON(1) -+*#endif -+*/ -+#define STATIC_ASSERT(pred) STATIC_ASSERT_X(pred, __LINE__) -+#define STATIC_ASSERT_X(pred, line) STATIC_ASSERT_XX(pred, line) -+#define STATIC_ASSERT_XX(pred, line) \ -+extern char assertion_failed_at_##line[(pred) ? 1 : -1] -+ -+/* --------------------------------------------------------------------------- */ -+/* Resolve Compiler Warnings */ -+/* --------------------------------------------------------------------------- */ -+ -+#define NOT_REFERENCED(x) { (x) = (x); } -+ -+ -+/* --------------------------------------------------------------------------- */ -+/* Utilities */ -+/* --------------------------------------------------------------------------- */ -+ -+#define MAXIMUM(A, B) (((A) > (B))?(A):(B)) -+#define MINIMUM(A, B) (((A) < (B))?(A):(B)) -+ -+#define ARY_SIZE(x) (sizeof((x)) / sizeof((x[0]))) -+#define DVT_DELAYMACRO(u4Num) \ -+{ \ -+ UINT32 u4Count = 0; \ -+ for (u4Count = 0; u4Count < u4Num; u4Count++) \ -+ ; \ -+} \ -+ -+#define A68351B 0 -+#define B68351B 1 -+#define B68351D 2 -+#define B68351E 3 -+#define UNKNOWN_IC_VERSION 0xFF -+ -+ -+#endif /* _TYPEDEFS_H */ -diff --git a/drivers/misc/mediatek/include/mt-plat/mtk_wcn_cmb_stub.h b/drivers/misc/mediatek/include/mt-plat/mtk_wcn_cmb_stub.h -new file mode 100644 -index 000000000000..0a4fda191654 ---- /dev/null -+++ b/drivers/misc/mediatek/include/mt-plat/mtk_wcn_cmb_stub.h -@@ -0,0 +1,185 @@ -+/* -+ * Copyright (C) 2015 MediaTek Inc. -+ * -+ * 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. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+/*! \file -+ * \brief Declaration of library functions -+ * -+ * Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. -+*/ -+ -+#ifndef _MTK_WCN_CMB_STUB_H_ -+#define _MTK_WCN_CMB_STUB_H_ -+ -+#include -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+/* Audio GPIO naming style for 73/75/77 */ -+/* #define MTK_WCN_CMB_AUD_IO_NAMING_STYLE_0 1 */ -+/* Audio GPIO naming style for 89/8135 */ -+/* #define MTK_WCN_CMB_AUD_IO_NAMING_STYLE_1 1 */ -+/* Audio GPIO naming style for 6592 */ -+/* #define MTK_WCN_CMB_AUD_IO_NAMING_STYLE_2 1 */ -+/* Audio GPIO naming style for 6595 */ -+#define MTK_WCN_CMB_AUD_IO_NAMING_STYLE_3 1 -+#define MTK_WCN_CMB_FOR_SDIO_1V_AUTOK 1 -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+typedef enum { -+ CMB_STUB_AIF_0 = 0, /* 0000: BT_PCM_OFF & FM analog (line in/out) */ -+ CMB_STUB_AIF_1 = 1, /* 0001: BT_PCM_ON & FM analog (in/out) */ -+ CMB_STUB_AIF_2 = 2, /* 0010: BT_PCM_OFF & FM digital (I2S) */ -+ CMB_STUB_AIF_3 = 3, /* 0011: BT_PCM_ON & FM digital (I2S) (invalid in 73evb & 1.2 phone configuration) */ -+ CMB_STUB_AIF_4 = 4, /* 0100: BT_I2S & FM disable in special projects, e.g. protea*/ -+ CMB_STUB_AIF_MAX = 5, -+} CMB_STUB_AIF_X; -+ -+/*COMBO_CHIP_AUDIO_PIN_CTRL*/ -+typedef enum { -+ CMB_STUB_AIF_CTRL_DIS = 0, -+ CMB_STUB_AIF_CTRL_EN = 1, -+ CMB_STUB_AIF_CTRL_MAX = 2, -+} CMB_STUB_AIF_CTRL; -+ -+typedef enum { -+ COMBO_FUNC_TYPE_BT = 0, -+ COMBO_FUNC_TYPE_FM = 1, -+ COMBO_FUNC_TYPE_GPS = 2, -+ COMBO_FUNC_TYPE_WIFI = 3, -+ COMBO_FUNC_TYPE_WMT = 4, -+ COMBO_FUNC_TYPE_STP = 5, -+ COMBO_FUNC_TYPE_NUM = 6 -+} COMBO_FUNC_TYPE; -+ -+typedef enum { -+ COMBO_IF_UART = 0, -+ COMBO_IF_MSDC = 1, -+ COMBO_IF_BTIF = 2, -+ COMBO_IF_MAX, -+} COMBO_IF; -+ -+typedef void (*wmt_bgf_eirq_cb) (void); -+typedef int (*wmt_aif_ctrl_cb) (CMB_STUB_AIF_X, CMB_STUB_AIF_CTRL); -+typedef void (*wmt_func_ctrl_cb) (unsigned int, unsigned int); -+typedef signed long (*wmt_thermal_query_cb) (void); -+typedef int (*wmt_deep_idle_ctrl_cb) (unsigned int); -+typedef int (*wmt_func_do_reset) (unsigned int); -+ -+/* for DVFS driver do 1v autok */ -+#if MTK_WCN_CMB_FOR_SDIO_1V_AUTOK -+typedef unsigned int (*wmt_get_drv_status)(unsigned int); -+#endif -+ -+typedef void (*msdc_sdio_irq_handler_t) (void *); /* external irq handler */ -+typedef void (*pm_callback_t) (pm_message_t state, void *data); -+ -+struct sdio_ops { -+ void (*sdio_request_eirq)(msdc_sdio_irq_handler_t irq_handler, void *data); -+ void (*sdio_enable_eirq)(void); -+ void (*sdio_disable_eirq)(void); -+ void (*sdio_register_pm)(pm_callback_t pm_cb, void *data); -+}; -+ -+typedef struct _CMB_STUB_CB_ { -+ unsigned int size; /* structure size */ -+ /*wmt_bgf_eirq_cb bgf_eirq_cb; *//* remove bgf_eirq_cb from stub. handle it in platform */ -+ wmt_aif_ctrl_cb aif_ctrl_cb; -+ wmt_func_ctrl_cb func_ctrl_cb; -+ wmt_thermal_query_cb thermal_query_cb; -+ wmt_deep_idle_ctrl_cb deep_idle_ctrl_cb; -+ wmt_func_do_reset wmt_do_reset_cb; -+#if MTK_WCN_CMB_FOR_SDIO_1V_AUTOK -+ wmt_get_drv_status get_drv_status_cb; -+#endif -+} CMB_STUB_CB, *P_CMB_STUB_CB; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+extern struct sdio_ops mt_sdio_ops[4]; -+ -+extern int mtk_wcn_cmb_stub_reg(P_CMB_STUB_CB p_stub_cb); -+extern int mtk_wcn_cmb_stub_unreg(void); -+ -+extern int mtk_wcn_cmb_stub_aif_ctrl(CMB_STUB_AIF_X state, CMB_STUB_AIF_CTRL ctrl); -+ -+static inline int mtk_wcn_cmb_stub_audio_ctrl(CMB_STUB_AIF_X state) -+{ -+/* return mtk_wcn_cmb_stub_aif_ctrl(state, 1); */ -+ return 0; -+} -+ -+extern int mt_combo_plt_enter_deep_idle(COMBO_IF src); -+extern int mt_combo_plt_exit_deep_idle(COMBO_IF src); -+ -+/* Use new mtk_wcn_stub APIs instead of old mt_combo ones for kernel to control -+ * function on/off. -+ */ -+extern void mtk_wcn_cmb_stub_func_ctrl(unsigned int type, unsigned int on); -+extern int mtk_wcn_cmb_stub_query_ctrl(void); -+extern int board_sdio_ctrl(unsigned int sdio_port_num, unsigned int on); -+extern int mtk_wcn_sdio_irq_flag_set(int falg); -+ -+#if MTK_WCN_CMB_FOR_SDIO_1V_AUTOK -+extern int mtk_wcn_cmb_stub_1vautok_for_dvfs(void); -+#endif -+ -+extern int mtk_wcn_wmt_chipid_query(void); -+extern void mtk_wcn_wmt_set_chipid(int chipid); -+ -+/* mtk_uart_pdn_enable -- request uart port enter/exit deep idle mode, this API is defined in uart driver -+ * -+ * @ port - uart port name, Eg: "ttyMT0", "ttyMT1", "ttyMT2" -+ * @ enable - "1", enable deep idle; "0", disable deep idle -+ * -+ * Return 0 if success, else -1 -+ */ -+extern unsigned int mtk_uart_pdn_enable(char *port, int enable); -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif /* _MTK_WCN_CMB_STUB_H_ */ -diff --git a/drivers/misc/mediatek/include/mt-plat/rt-regmap.h b/drivers/misc/mediatek/include/mt-plat/rt-regmap.h -new file mode 100644 -index 000000000000..9a45e23005ca ---- /dev/null -+++ b/drivers/misc/mediatek/include/mt-plat/rt-regmap.h -@@ -0,0 +1,291 @@ -+/* drivers/misc/mediatek/include/mt-plat/rt-regmap.h -+ * Header of Richtek regmap with debugfs Driver -+ * -+ * Copyright (C) 2014 Richtek Technology Corp. -+ * Jeff Chang -+ * -+ * 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. -+ */ -+ -+#ifndef MISC_MEDIATEK_RT_REGMAP_H -+#define MISC_MEDIATEK_RT_REGMAP_H -+ -+#include -+#include -+ -+/* #define RT_REGMAP_VERSION "1.1.11_G" */ -+ -+enum rt_access_mode { -+ RT_1BYTE_MODE = 1, -+ RT_2BYTE_MODE = 2, -+ RT_4BYTE_MODE = 4, -+}; -+ -+/* start : the start address of group -+ * end : the end address of group -+ * mode : access mode (1,2,4 bytes) -+ */ -+struct rt_access_group { -+ u32 start; -+ u32 end; -+ enum rt_access_mode mode; -+}; -+ -+/* rt_reg_type -+ * RT_NORMAL : Write data without mask -+ * Read from cache -+ * RT_WBITS : Write data with mask -+ * Read from cache -+ * RT_VOLATILE : Write data to chip directly -+ * Read data from chip -+ * RT_RESERVE : Reserve registers (Write/Read as RT_NORMAL) -+ */ -+ -+#define RT_REG_TYPE_MASK (0x03) -+#define RT_NORMAL (0x00) -+#define RT_WBITS (0x01) -+#define RT_VOLATILE (0x02) -+#define RT_RESERVE (0x03) -+ -+/* RT_WR_ONCE : write once will check write data and cache data, -+ * if write data = cache data, data will not be writen. -+ */ -+#define RT_WR_ONCE (0x08) -+#define RT_NORMAL_WR_ONCE (RT_NORMAL|RT_WR_ONCE) -+#define RT_WBITS_WR_ONCE (RT_WBITS|RT_WR_ONCE) -+ -+enum rt_data_format { -+ RT_LITTLE_ENDIAN, -+ RT_BIG_ENDIAN, -+}; -+ -+/* rt_regmap_mode -+ * 0 0 0 0 0 0 0 0 -+ * | | | | | | -+ * | | | |__| byte_mode -+ * | |__| || -+ * | || Cache_mode -+ * | Block_mode -+ * Debug_mode -+ */ -+ -+#define RT_BYTE_MODE_MASK (0x01) -+/* 1 byte for each register*/ -+#define RT_SINGLE_BYTE (0 << 0) -+/* multi bytes for each regiseter*/ -+#define RT_MULTI_BYTE (1 << 0) -+ -+#define RT_CACHE_MODE_MASK (0x06) -+/* write to cache and chip synchronously */ -+#define RT_CACHE_WR_THROUGH (0 << 1) -+/* write to cache and chip asynchronously */ -+#define RT_CACHE_WR_BACK (1 << 1) -+/* disable cache */ -+#define RT_CACHE_DISABLE (2 << 1) -+ -+#define RT_IO_BLK_MODE_MASK (0x18) -+/* pass through all write function */ -+#define RT_IO_PASS_THROUGH (0 << 3) -+/* block all write function */ -+#define RT_IO_BLK_ALL (1 << 3) -+/* block cache write function */ -+#define RT_IO_BLK_CACHE (2 << 3) -+/* block chip write function */ -+#define RT_IO_BLK_CHIP (3 << 3) -+ -+#define DBG_MODE_MASK (0x20) -+/* create general debugfs for register map */ -+#define RT_DBG_GENERAL (0 << 5) -+/* create node for each regisetr map by register address*/ -+#define RT_DBG_SPECIAL (1 << 5) -+ -+ -+/* struct rt_register -+ * -+ * Ricktek register map structure for store mapping data -+ * @addr: register address. -+ * @name: register name. -+ * @size: register byte size. -+ * @reg_type: register R/W type ( RT_NORMAL, RT_WBITS, RT_VOLATILE, RT_RESERVE) -+ * @wbit_mask: register writeable bits mask; -+ * @cache_data: cache data for store cache value. -+ */ -+struct rt_register { -+ u32 addr; -+ const char *name; -+ unsigned int size; -+ unsigned char reg_type; -+ unsigned char *wbit_mask; -+ unsigned char *cache_data; -+}; -+ -+/* Declare a rt_register by RT_REG_DECL -+ * @_addr: regisetr address. -+ * @_reg_length: register data length. -+ * @_reg_type: register type (rt_reg_type). -+ * @_mask: register writealbe mask. -+ */ -+#define RT_REG_DECL(_addr, _reg_length, _reg_type, _mask_...) \ -+ static unsigned char rt_writable_mask_##_addr[_reg_length] = _mask_;\ -+ static struct rt_register rt_register_##_addr = { \ -+ .addr = _addr, \ -+ .size = _reg_length,\ -+ .reg_type = _reg_type,\ -+ .wbit_mask = rt_writable_mask_##_addr,\ -+ } -+ -+/* Declare a rt_register by RT_NAMED_REG_DECL -+ * @_name: a name for a rt_register. -+ */ -+#define RT_NAMED_REG_DECL(_addr, _name, _reg_length, _reg_type, _mask_...) \ -+ static unsigned char rt_writable_mask_##_addr[_reg_length] = _mask_;\ -+ static struct rt_register rt_register_##_addr = { \ -+ .addr = _addr, \ -+ .name = _name, \ -+ .size = _reg_length,\ -+ .reg_type = _reg_type,\ -+ .wbit_mask = rt_writable_mask_##_addr,\ -+ } -+ -+#define RT_REG(_addr) (&rt_register_##_addr) -+ -+/* rt_regmap_properties -+ * @name: the name of debug node. -+ * @aliases: alisis name of rt_regmap_device. -+ * @register_num: the number of rt_register_map registers. -+ * @rm: rt_regiseter_map pointer array. -+ * @group: register map access group. -+ * @rt_format: default is little endian. -+ * @rt_regmap_mode: rt_regmap_device mode. -+ * @io_log_en: enable/disable io log -+ */ -+struct rt_regmap_properties { -+ const char *name; -+ const char *aliases; -+ int register_num; -+ struct rt_register **rm; -+ struct rt_access_group *group; -+ enum rt_data_format rt_format; -+ unsigned char rt_regmap_mode; -+ unsigned char io_log_en:1; -+}; -+ -+/* A passing struct for rt_regmap_reg_read and rt_regmap_reg_write function -+ * reg: regmap addr. -+ * mask: mask for update bits. -+ * rt_data: register value. -+ */ -+struct rt_reg_data { -+ u32 reg; -+ u32 mask; -+ union { -+ u32 data_u32; -+ u16 data_u16; -+ u8 data_u8; -+ u8 data[4]; -+ } rt_data; -+}; -+ -+struct rt_regmap_device; -+ -+struct rt_debug_st { -+ void *info; -+ int id; -+}; -+ -+/* basic chip read/write function */ -+struct rt_regmap_fops { -+ int (*read_device)(void *client, u32 addr, int leng, void *dst); -+ int (*write_device)(void *client, u32 addr, int leng, const void *src); -+}; -+ -+/* with slave address */ -+extern struct rt_regmap_device* -+ rt_regmap_device_register_ex(struct rt_regmap_properties *props, -+ struct rt_regmap_fops *rops, -+ struct device *parent, -+ void *client, int slv_addr, void *drvdata); -+ -+static inline struct rt_regmap_device* -+ rt_regmap_device_register(struct rt_regmap_properties *props, -+ struct rt_regmap_fops *rops, -+ struct device *parent, -+ struct i2c_client *client, void *drvdata) -+{ -+ return rt_regmap_device_register_ex(props, rops, parent, -+ client, client->addr, drvdata); -+} -+ -+extern void rt_regmap_device_unregister(struct rt_regmap_device *rd); -+ -+extern int rt_regmap_cache_init(struct rt_regmap_device *rd); -+ -+extern int rt_regmap_cache_reload(struct rt_regmap_device *rd); -+ -+extern int rt_regmap_block_write(struct rt_regmap_device *rd, u32 reg, -+ int bytes, const void *rc); -+extern int rt_asyn_regmap_block_write(struct rt_regmap_device *rd, u32 reg, -+ int bytes, const void *rc); -+extern int rt_regmap_block_read(struct rt_regmap_device *rd, u32 reg, -+ int bytes, void *dst); -+ -+extern int _rt_regmap_reg_read(struct rt_regmap_device *rd, -+ struct rt_reg_data *rrd); -+extern int _rt_regmap_reg_write(struct rt_regmap_device *rd, -+ struct rt_reg_data *rrd); -+extern int _rt_asyn_regmap_reg_write(struct rt_regmap_device *rd, -+ struct rt_reg_data *rrd); -+extern int _rt_regmap_update_bits(struct rt_regmap_device *rd, -+ struct rt_reg_data *rrd); -+ -+static inline int rt_regmap_reg_read(struct rt_regmap_device *rd, -+ struct rt_reg_data *rrd, u32 reg) -+{ -+ rrd->reg = reg; -+ return _rt_regmap_reg_read(rd, rrd); -+}; -+ -+static inline int rt_regmap_reg_write(struct rt_regmap_device *rd, -+ struct rt_reg_data *rrd, u32 reg, const u32 data) -+{ -+ rrd->reg = reg; -+ rrd->rt_data.data_u32 = data; -+ return _rt_regmap_reg_write(rd, rrd); -+}; -+ -+static inline int rt_asyn_regmap_reg_write(struct rt_regmap_device *rd, -+ struct rt_reg_data *rrd, u32 reg, const u32 data) -+{ -+ rrd->reg = reg; -+ rrd->rt_data.data_u32 = data; -+ return _rt_asyn_regmap_reg_write(rd, rrd); -+}; -+ -+static inline int rt_regmap_update_bits(struct rt_regmap_device *rd, -+ struct rt_reg_data *rrd, u32 reg, u32 mask, u32 data) -+{ -+ rrd->reg = reg; -+ rrd->mask = mask; -+ rrd->rt_data.data_u32 = data; -+ return _rt_regmap_update_bits(rd, rrd); -+} -+ -+extern void rt_regmap_cache_backup(struct rt_regmap_device *rd); -+ -+extern void rt_regmap_cache_sync(struct rt_regmap_device *rd); -+extern void rt_regmap_cache_write_back(struct rt_regmap_device *rd, u32 reg); -+ -+extern int rt_is_reg_readable(struct rt_regmap_device *rd, u32 reg); -+extern int rt_is_reg_volatile(struct rt_regmap_device *rd, u32 reg); -+extern int rt_get_regsize(struct rt_regmap_device *rd, u32 reg); -+extern void rt_cache_getlasterror(struct rt_regmap_device *rd, char *buf); -+extern void rt_cache_clrlasterror(struct rt_regmap_device *rd); -+ -+extern int rt_regmap_add_debugfs(struct rt_regmap_device *rd, const char *name, -+ umode_t mode, void *data, const struct file_operations *fops); -+ -+#define to_rt_regmap_device(obj) container_of(obj, struct rt_regmap_device, dev) -+ -+#endif /*MISC_MEDIATEK_RT_REGMAP_H*/ -diff --git a/drivers/misc/mediatek/include/mt-plat/sync_write.h b/drivers/misc/mediatek/include/mt-plat/sync_write.h -new file mode 100644 -index 000000000000..f9e5fe4c23e1 ---- /dev/null -+++ b/drivers/misc/mediatek/include/mt-plat/sync_write.h -@@ -0,0 +1,88 @@ -+/* -+ * Copyright (C) 2015 MediaTek Inc. -+ * -+ * 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. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#ifndef _MT_SYNC_WRITE_H -+#define _MT_SYNC_WRITE_H -+ -+#if defined(__KERNEL__) -+ -+#include -+#include -+ -+/* -+ * Define macros. -+ */ -+#define mt_reg_sync_writel(v, a) \ -+ do { \ -+ __raw_writel((v), (void __force __iomem *)((a))); \ -+ mb(); \ -+ } while (0) -+ -+#define mt_reg_sync_writew(v, a) \ -+ do { \ -+ __raw_writew((v), (void __force __iomem *)((a))); \ -+ mb(); \ -+ } while (0) -+ -+#define mt_reg_sync_writeb(v, a) \ -+ do { \ -+ __raw_writeb((v), (void __force __iomem *)((a))); \ -+ mb(); \ -+ } while (0) -+ -+#ifdef CONFIG_64BIT -+#define mt_reg_sync_writeq(v, a) \ -+ do { \ -+ __raw_writeq((v), (void __force __iomem *)((a))); \ -+ mb(); \ -+ } while (0) -+#endif -+ -+#else /* __KERNEL__ */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+#define mt_reg_sync_writel(v, a) mt65xx_reg_sync_writel(v, a) -+#define mt_reg_sync_writew(v, a) mt65xx_reg_sync_writew(v, a) -+#define mt_reg_sync_writeb(v, a) mt65xx_reg_sync_writeb(v, a) -+ -+#define mb() \ -+ { \ -+ __asm__ __volatile__ ("dsb" : : : "memory"); \ -+ } -+ -+#define mt65xx_reg_sync_writel(v, a) \ -+ do { \ -+ *(volatile unsigned int *)(a) = (v); \ -+ mb(); \ -+ } while (0) -+ -+#define mt65xx_reg_sync_writew(v, a) \ -+ do { \ -+ *(volatile unsigned short *)(a) = (v); \ -+ mb(); \ -+ } while (0) -+ -+#define mt65xx_reg_sync_writeb(v, a) \ -+ do { \ -+ *(volatile unsigned char *)(a) = (v); \ -+ mb(); \ -+ } while (0) -+ -+#endif /* __KERNEL__ */ -+ -+#endif /* !_MT_SYNC_WRITE_H */ -diff --git a/drivers/misc/mediatek/include/mt-plat/wakelock.h b/drivers/misc/mediatek/include/mt-plat/wakelock.h -new file mode 100644 -index 000000000000..f4a698a22880 ---- /dev/null -+++ b/drivers/misc/mediatek/include/mt-plat/wakelock.h -@@ -0,0 +1,67 @@ -+/* include/linux/wakelock.h -+ * -+ * Copyright (C) 2007-2012 Google, Inc. -+ * -+ * This software is licensed under the terms of the GNU General Public -+ * License version 2, as published by the Free Software Foundation, and -+ * may be copied, distributed, and modified under those terms. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ */ -+ -+#ifndef _LINUX_WAKELOCK_H -+#define _LINUX_WAKELOCK_H -+ -+#include -+#include -+ -+/* A wake_lock prevents the system from entering suspend or other low power -+ * states when active. If the type is set to WAKE_LOCK_SUSPEND, the wake_lock -+ * prevents a full system suspend. -+ */ -+ -+enum { -+ WAKE_LOCK_SUSPEND, /* Prevent suspend */ -+ WAKE_LOCK_TYPE_COUNT -+}; -+ -+struct wake_lock { -+ struct wakeup_source ws; -+}; -+ -+static inline void wake_lock_init(struct wake_lock *lock, int type, -+ const char *name) -+{ -+ wakeup_source_init(&lock->ws, name); -+} -+ -+static inline void wake_lock_destroy(struct wake_lock *lock) -+{ -+ wakeup_source_trash(&lock->ws); -+} -+ -+static inline void wake_lock(struct wake_lock *lock) -+{ -+ __pm_stay_awake(&lock->ws); -+} -+ -+static inline void wake_lock_timeout(struct wake_lock *lock, long timeout) -+{ -+ __pm_wakeup_event(&lock->ws, jiffies_to_msecs(timeout)); -+} -+ -+static inline void wake_unlock(struct wake_lock *lock) -+{ -+ __pm_relax(&lock->ws); -+} -+ -+static inline int wake_lock_active(struct wake_lock *lock) -+{ -+ return lock->ws.active; -+} -+ -+#endif -diff --git a/drivers/soc/mediatek/mtk-pmic-wrap.c b/drivers/soc/mediatek/mtk-pmic-wrap.c -index e3df1e96b141..086c9ea8d7cb 100644 ---- a/drivers/soc/mediatek/mtk-pmic-wrap.c -+++ b/drivers/soc/mediatek/mtk-pmic-wrap.c -@@ -1107,6 +1107,22 @@ static const struct of_device_id of_pwrap_match_tbl[] = { - }; - MODULE_DEVICE_TABLE(of, of_pwrap_match_tbl); - -+struct regmap *pwrap_node_to_regmap(struct device_node *np) -+{ -+ struct platform_device *pdev; -+ struct pmic_wrapper *wrp; -+ -+ pdev = of_find_device_by_node(np); -+ -+ if (!pdev) -+ return ERR_PTR(-ENODEV); -+ -+ wrp = platform_get_drvdata(pdev); -+ -+ return wrp->regmap; -+} -+EXPORT_SYMBOL_GPL(pwrap_node_to_regmap); -+ - static int pwrap_probe(struct platform_device *pdev) - { - int ret, irq; -diff --git a/drivers/watchdog/mtk_wdt.c b/drivers/watchdog/mtk_wdt.c -index 7ed417a765c7..43676313f32b 100644 ---- a/drivers/watchdog/mtk_wdt.c -+++ b/drivers/watchdog/mtk_wdt.c -@@ -21,14 +21,34 @@ - #include - #include - #include -+#include - #include - #include - #include -+#include -+#include -+#include - #include -+#include - #include -+#ifdef CONFIG_FIQ_GLUE -+#include -+#include -+#endif - #include - #include -+#include -+#include - #include -+#include -+#include -+#include -+#include -+#include -+#include -+#ifdef CONFIG_MT6397_MISC -+#include -+#endif - - #define WDT_MAX_TIMEOUT 31 - #define WDT_MIN_TIMEOUT 1 -@@ -47,37 +67,167 @@ - #define WDT_MODE_EXRST_EN (1 << 2) - #define WDT_MODE_IRQ_EN (1 << 3) - #define WDT_MODE_AUTO_START (1 << 4) -+#define WDT_MODE_IRQ_LVL (1 << 5) - #define WDT_MODE_DUAL_EN (1 << 6) - #define WDT_MODE_KEY 0x22000000 - -+#define WDT_STATUS 0x0c -+#define WDT_NONRST_REG 0x20 -+#define WDT_NONRST_REG2 0x24 -+ - #define WDT_SWRST 0x14 - #define WDT_SWRST_KEY 0x1209 - -+#define WDT_SWSYSRST 0x18 -+#define WDT_SWSYSRST_KEY 0x88000000 -+ -+#define WDT_REQ_MODE 0x30 -+#define WDT_REQ_MODE_KEY 0x33000000 -+#define WDT_REQ_IRQ_EN 0x34 -+#define WDT_REQ_IRQ_KEY 0x44000000 -+#define WDT_REQ_MODE_DEBUG_EN 0x80000 -+ -+ - #define DRV_NAME "mtk-wdt" --#define DRV_VERSION "1.0" -+#define DRV_VERSION "2.0" - - static bool nowayout = WATCHDOG_NOWAYOUT; - static unsigned int timeout = WDT_MAX_TIMEOUT; - -+struct toprgu_reset { -+ spinlock_t lock; -+ void __iomem *toprgu_swrst_base; -+ int regofs; -+ struct reset_controller_dev rcdev; -+}; -+ - struct mtk_wdt_dev { - struct watchdog_device wdt_dev; - void __iomem *wdt_base; -+ int wdt_irq_id; -+ struct notifier_block restart_handler; -+ struct toprgu_reset reset_controller; - }; - --static int mtk_wdt_restart(struct watchdog_device *wdt_dev, -- unsigned long action, void *data) -+static void __iomem *toprgu_base; -+static struct watchdog_device *wdt_dev; -+ -+static int toprgu_reset_assert(struct reset_controller_dev *rcdev, -+ unsigned long id) - { -- struct mtk_wdt_dev *mtk_wdt = watchdog_get_drvdata(wdt_dev); -+ unsigned int tmp; -+ unsigned long flags; -+ struct toprgu_reset *data = container_of(rcdev, struct toprgu_reset, rcdev); -+ -+ spin_lock_irqsave(&data->lock, flags); -+ -+ tmp = __raw_readl(data->toprgu_swrst_base + data->regofs); -+ tmp |= BIT(id); -+ tmp |= WDT_SWSYSRST_KEY; -+ writel(tmp, data->toprgu_swrst_base + data->regofs); -+ -+ spin_unlock_irqrestore(&data->lock, flags); -+ -+ return 0; -+} -+ -+static int toprgu_reset_deassert(struct reset_controller_dev *rcdev, -+ unsigned long id) -+{ -+ unsigned int tmp; -+ unsigned long flags; -+ struct toprgu_reset *data = container_of(rcdev, struct toprgu_reset, rcdev); -+ -+ spin_lock_irqsave(&data->lock, flags); -+ -+ tmp = __raw_readl(data->toprgu_swrst_base + data->regofs); -+ tmp &= ~BIT(id); -+ tmp |= WDT_SWSYSRST_KEY; -+ writel(tmp, data->toprgu_swrst_base + data->regofs); -+ -+ spin_unlock_irqrestore(&data->lock, flags); -+ -+ return 0; -+} -+ -+static int toprgu_reset(struct reset_controller_dev *rcdev, -+ unsigned long id) -+{ -+ int ret; -+ -+ ret = toprgu_reset_assert(rcdev, id); -+ if (ret) -+ return ret; -+ -+ return toprgu_reset_deassert(rcdev, id); -+} -+ -+static struct reset_control_ops toprgu_reset_ops = { -+ .assert = toprgu_reset_assert, -+ .deassert = toprgu_reset_deassert, -+ .reset = toprgu_reset, -+}; -+ -+static void toprgu_register_reset_controller(struct platform_device *pdev, int regofs) -+{ -+ int ret; -+ struct mtk_wdt_dev *mtk_wdt = platform_get_drvdata(pdev); -+ -+ spin_lock_init(&mtk_wdt->reset_controller.lock); -+ -+ mtk_wdt->reset_controller.toprgu_swrst_base = mtk_wdt->wdt_base; -+ mtk_wdt->reset_controller.regofs = regofs; -+ mtk_wdt->reset_controller.rcdev.owner = THIS_MODULE; -+ mtk_wdt->reset_controller.rcdev.nr_resets = 15; -+ mtk_wdt->reset_controller.rcdev.ops = &toprgu_reset_ops; -+ mtk_wdt->reset_controller.rcdev.of_node = pdev->dev.of_node; -+ -+ ret = reset_controller_register(&mtk_wdt->reset_controller.rcdev); -+ if (ret) -+ pr_err("could not register toprgu reset controller: %d\n", ret); -+} -+ -+static int mtk_reset_handler(struct notifier_block *this, unsigned long mode, -+ void *cmd) -+{ -+ struct mtk_wdt_dev *mtk_wdt; - void __iomem *wdt_base; -+ u32 reg; - -+ mtk_wdt = container_of(this, struct mtk_wdt_dev, restart_handler); - wdt_base = mtk_wdt->wdt_base; - -- while (1) { -- writel(WDT_SWRST_KEY, wdt_base + WDT_SWRST); -- mdelay(5); -+ /* WDT_STATUS will be cleared to zero after writing to WDT_MODE, so we backup it in WDT_NONRST_REG, -+ * and then print it out in mtk_wdt_probe() after reset -+ */ -+ writel(__raw_readl(wdt_base + WDT_STATUS), wdt_base + WDT_NONRST_REG); -+ -+ reg = ioread32(wdt_base + WDT_MODE); -+ reg &= ~(WDT_MODE_DUAL_EN | WDT_MODE_IRQ_EN | WDT_MODE_EN); -+ reg |= WDT_MODE_KEY; -+ iowrite32(reg, wdt_base + WDT_MODE); -+ -+ if (cmd && !strcmp(cmd, "rpmbpk")) { -+ iowrite32(ioread32(wdt_base + WDT_NONRST_REG2) | (1 << 0), wdt_base + WDT_NONRST_REG2); -+ } else if (cmd && !strcmp(cmd, "recovery")) { -+ iowrite32(ioread32(wdt_base + WDT_NONRST_REG2) | (1 << 1), wdt_base + WDT_NONRST_REG2); -+ #ifdef CONFIG_MT6397_MISC -+ mtk_misc_mark_recovery(); -+ #endif -+ } else if (cmd && !strcmp(cmd, "bootloader")) { -+ iowrite32(ioread32(wdt_base + WDT_NONRST_REG2) | (1 << 2), wdt_base + WDT_NONRST_REG2); -+ #ifdef CONFIG_MT6397_MISC -+ mtk_misc_mark_fast(); -+ #endif - } - -- return 0; -+ if (!arm_pm_restart) { -+ while (1) { -+ writel(WDT_SWRST_KEY, wdt_base + WDT_SWRST); -+ mdelay(5); -+ } -+ } -+ return NOTIFY_DONE; - } - - static int mtk_wdt_ping(struct watchdog_device *wdt_dev) -@@ -86,6 +236,7 @@ static int mtk_wdt_ping(struct watchdog_device *wdt_dev) - void __iomem *wdt_base = mtk_wdt->wdt_base; - - iowrite32(WDT_RST_RELOAD, wdt_base + WDT_RST); -+ printk_deferred("[WDK]: kick Ex WDT\n"); - - return 0; - } -@@ -137,7 +288,8 @@ static int mtk_wdt_start(struct watchdog_device *wdt_dev) - return ret; - - reg = ioread32(wdt_base + WDT_MODE); -- reg &= ~(WDT_MODE_IRQ_EN | WDT_MODE_DUAL_EN); -+ reg |= (WDT_MODE_DUAL_EN | WDT_MODE_IRQ_EN | WDT_MODE_EXRST_EN); -+ reg &= ~(WDT_MODE_IRQ_LVL | WDT_MODE_EXT_POL_HIGH); - reg |= (WDT_MODE_EN | WDT_MODE_KEY); - iowrite32(reg, wdt_base + WDT_MODE); - -@@ -157,13 +309,56 @@ static const struct watchdog_ops mtk_wdt_ops = { - .stop = mtk_wdt_stop, - .ping = mtk_wdt_ping, - .set_timeout = mtk_wdt_set_timeout, -- .restart = mtk_wdt_restart, - }; - -+#ifdef CONFIG_FIQ_GLUE -+static void wdt_fiq(void *arg, void *regs, void *svc_sp) -+{ -+ unsigned int wdt_mode_val; -+ void __iomem *wdt_base = ((struct mtk_wdt_dev *)arg)->wdt_base; -+ -+ wdt_mode_val = __raw_readl(wdt_base + WDT_STATUS); -+ writel(wdt_mode_val, wdt_base + WDT_NONRST_REG); -+ -+ aee_wdt_fiq_info(arg, regs, svc_sp); -+} -+#else -+static void wdt_report_info(void) -+{ -+ struct task_struct *task; -+ -+ task = &init_task; -+ pr_debug("Qwdt: -- watchdog time out\n"); -+ -+ for_each_process(task) { -+ if (task->state == 0) { -+ pr_debug("PID: %d, name: %s\n backtrace:\n", task->pid, task->comm); -+ show_stack(task, NULL); -+ pr_debug("\n"); -+ } -+ } -+ -+ pr_debug("backtrace of current task:\n"); -+ show_stack(NULL, NULL); -+ pr_debug("Qwdt: -- watchdog time out\n"); -+} -+ -+static irqreturn_t mtk_wdt_isr(int irq, void *dev_id) -+{ -+ pr_err("fwq mtk_wdt_isr\n"); -+ -+ wdt_report_info(); -+ BUG(); -+ -+ return IRQ_HANDLED; -+} -+#endif -+ - static int mtk_wdt_probe(struct platform_device *pdev) - { - struct mtk_wdt_dev *mtk_wdt; - struct resource *res; -+ unsigned int tmp; - int err; - - mtk_wdt = devm_kzalloc(&pdev->dev, sizeof(*mtk_wdt), GFP_KERNEL); -@@ -174,9 +369,32 @@ static int mtk_wdt_probe(struct platform_device *pdev) - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - mtk_wdt->wdt_base = devm_ioremap_resource(&pdev->dev, res); -+ - if (IS_ERR(mtk_wdt->wdt_base)) - return PTR_ERR(mtk_wdt->wdt_base); - -+ pr_err("MTK_WDT_NONRST_REG(%x)\n", __raw_readl(mtk_wdt->wdt_base + WDT_NONRST_REG)); -+ -+ mtk_wdt->wdt_irq_id = irq_of_parse_and_map(pdev->dev.of_node, 0); -+ if (!mtk_wdt->wdt_irq_id) { -+ pr_err("RGU get IRQ ID failed\n"); -+ return -ENODEV; -+ } -+ -+#ifndef CONFIG_FIQ_GLUE -+ err = request_irq(mtk_wdt->wdt_irq_id, (irq_handler_t)mtk_wdt_isr, IRQF_TRIGGER_NONE, DRV_NAME, mtk_wdt); -+#else -+ mtk_wdt->wdt_irq_id = get_hardware_irq(mtk_wdt->wdt_irq_id); -+ err = request_fiq(mtk_wdt->wdt_irq_id, wdt_fiq, IRQF_TRIGGER_FALLING, mtk_wdt); -+#endif -+ if (err != 0) { -+ pr_err("mtk_wdt_probe : failed to request irq (%d)\n", err); -+ return err; -+ } -+ -+ toprgu_base = mtk_wdt->wdt_base; -+ wdt_dev = &mtk_wdt->wdt_dev; -+ - mtk_wdt->wdt_dev.info = &mtk_wdt_info; - mtk_wdt->wdt_dev.ops = &mtk_wdt_ops; - mtk_wdt->wdt_dev.timeout = WDT_MAX_TIMEOUT; -@@ -186,7 +404,6 @@ static int mtk_wdt_probe(struct platform_device *pdev) - - watchdog_init_timeout(&mtk_wdt->wdt_dev, timeout, &pdev->dev); - watchdog_set_nowayout(&mtk_wdt->wdt_dev, nowayout); -- watchdog_set_restart_priority(&mtk_wdt->wdt_dev, 128); - - watchdog_set_drvdata(&mtk_wdt->wdt_dev, mtk_wdt); - -@@ -196,9 +413,40 @@ static int mtk_wdt_probe(struct platform_device *pdev) - if (unlikely(err)) - return err; - -+ mtk_wdt->restart_handler.notifier_call = mtk_reset_handler; -+ mtk_wdt->restart_handler.priority = 128; -+ -+ if (arm_pm_restart) { -+ dev_info(&pdev->dev, "register restart_handler on reboot_notifier_list for psci reset\n"); -+ err = register_reboot_notifier(&mtk_wdt->restart_handler); -+ if (err != 0) -+ dev_warn(&pdev->dev, -+ "cannot register reboot notifier (err=%d)\n", err); -+ } else { -+ err = register_restart_handler(&mtk_wdt->restart_handler); -+ if (err) -+ dev_warn(&pdev->dev, -+ "cannot register restart handler (err=%d)\n", err); -+ } -+ - dev_info(&pdev->dev, "Watchdog enabled (timeout=%d sec, nowayout=%d)\n", - mtk_wdt->wdt_dev.timeout, nowayout); - -+ writel(WDT_REQ_MODE_KEY | (__raw_readl(mtk_wdt->wdt_base + WDT_REQ_MODE) & -+ (~WDT_REQ_MODE_DEBUG_EN)), mtk_wdt->wdt_base + WDT_REQ_MODE); -+ -+ toprgu_register_reset_controller(pdev, WDT_SWSYSRST); -+ -+ /* enable scpsys thermal and thermal_controller request, and set to reset directly mode */ -+ tmp = ioread32(mtk_wdt->wdt_base + WDT_REQ_MODE) | (1 << 18) | (1 << 0); -+ tmp |= WDT_REQ_MODE_KEY; -+ iowrite32(tmp, mtk_wdt->wdt_base + WDT_REQ_MODE); -+ -+ tmp = ioread32(mtk_wdt->wdt_base + WDT_REQ_IRQ_EN); -+ tmp &= ~((1 << 18) | (1 << 0)); -+ tmp |= WDT_REQ_IRQ_KEY; -+ iowrite32(tmp, mtk_wdt->wdt_base + WDT_REQ_IRQ_EN); -+ - return 0; - } - -@@ -214,8 +462,12 @@ static int mtk_wdt_remove(struct platform_device *pdev) - { - struct mtk_wdt_dev *mtk_wdt = platform_get_drvdata(pdev); - -+ unregister_restart_handler(&mtk_wdt->restart_handler); -+ - watchdog_unregister_device(&mtk_wdt->wdt_dev); - -+ reset_controller_unregister(&mtk_wdt->reset_controller.rcdev); -+ - return 0; - } - -@@ -267,6 +519,95 @@ static struct platform_driver mtk_wdt_driver = { - - module_platform_driver(mtk_wdt_driver); - -+static int wk_proc_cmd_read(struct seq_file *s, void *v) -+{ -+ unsigned int enabled = 1; -+ -+ if (!(ioread32(toprgu_base + WDT_MODE) & WDT_MODE_EN)) -+ enabled = 0; -+ -+ seq_printf(s, "enabled timeout\n%-4d %-8d\n", enabled, wdt_dev->timeout); -+ -+ return 0; -+} -+ -+static int wk_proc_cmd_open(struct inode *inode, struct file *file) -+{ -+ return single_open(file, wk_proc_cmd_read, NULL); -+} -+ -+static ssize_t wk_proc_cmd_write(struct file *file, const char *buf, size_t count, loff_t *data) -+{ -+ int ret; -+ int enable; -+ int timeout; -+ char wk_cmd_buf[256]; -+ -+ if (count == 0) -+ return -1; -+ -+ if (count > 255) -+ count = 255; -+ -+ ret = copy_from_user(wk_cmd_buf, buf, count); -+ if (ret < 0) -+ return -1; -+ -+ wk_cmd_buf[count] = '\0'; -+ -+ pr_debug("Write %s\n", wk_cmd_buf); -+ -+ ret = sscanf(wk_cmd_buf, "%d %d", &enable, &timeout); -+ if (ret != 2) -+ pr_debug("%s: expect 2 numbers\n", __func__); -+ -+ pr_debug("[WDK] enable=%d timeout=%d\n", enable, timeout); -+ -+ if (timeout > 20 && timeout <= WDT_MAX_TIMEOUT) { -+ wdt_dev->timeout = timeout; -+ mtk_wdt_set_timeout(wdt_dev, wdt_dev->timeout); -+ } else { -+ pr_err("[WDK] The timeout(%d) should bigger than 20 and not bigger than %d\n", -+ timeout, WDT_MAX_TIMEOUT); -+ -+ } -+ -+ if (enable == 1) { -+ mtk_wdt_start(wdt_dev); -+ set_bit(WDOG_ACTIVE, &wdt_dev->status); -+ pr_err("[WDK] enable wdt\n"); -+ } else if (enable == 0) { -+ mtk_wdt_stop(wdt_dev); -+ clear_bit(WDOG_ACTIVE, &wdt_dev->status); -+ pr_err("[WDK] disable wdt\n"); -+ } -+ -+ return count; -+} -+ -+static const struct file_operations wk_proc_cmd_fops = { -+ .owner = THIS_MODULE, -+ .open = wk_proc_cmd_open, -+ .read = seq_read, -+ .write = wk_proc_cmd_write, -+ .llseek = seq_lseek, -+ .release = single_release, -+}; -+ -+static int __init wk_proc_init(void) -+{ -+ struct proc_dir_entry *de = proc_create("wdk", 0660, NULL, &wk_proc_cmd_fops); -+ -+ if (!de) -+ pr_err("[wk_proc_init]: create /proc/wdk failed\n"); -+ -+ pr_debug("[WDK] Initialize proc\n"); -+ -+ return 0; -+} -+ -+late_initcall(wk_proc_init); -+ - module_param(timeout, uint, 0); - MODULE_PARM_DESC(timeout, "Watchdog heartbeat in seconds"); - -diff --git a/include/linux/wakelock.h b/include/linux/wakelock.h -new file mode 100644 -index 000000000000..f4a698a22880 ---- /dev/null -+++ b/include/linux/wakelock.h -@@ -0,0 +1,67 @@ -+/* include/linux/wakelock.h -+ * -+ * Copyright (C) 2007-2012 Google, Inc. -+ * -+ * This software is licensed under the terms of the GNU General Public -+ * License version 2, as published by the Free Software Foundation, and -+ * may be copied, distributed, and modified under those terms. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ */ -+ -+#ifndef _LINUX_WAKELOCK_H -+#define _LINUX_WAKELOCK_H -+ -+#include -+#include -+ -+/* A wake_lock prevents the system from entering suspend or other low power -+ * states when active. If the type is set to WAKE_LOCK_SUSPEND, the wake_lock -+ * prevents a full system suspend. -+ */ -+ -+enum { -+ WAKE_LOCK_SUSPEND, /* Prevent suspend */ -+ WAKE_LOCK_TYPE_COUNT -+}; -+ -+struct wake_lock { -+ struct wakeup_source ws; -+}; -+ -+static inline void wake_lock_init(struct wake_lock *lock, int type, -+ const char *name) -+{ -+ wakeup_source_init(&lock->ws, name); -+} -+ -+static inline void wake_lock_destroy(struct wake_lock *lock) -+{ -+ wakeup_source_trash(&lock->ws); -+} -+ -+static inline void wake_lock(struct wake_lock *lock) -+{ -+ __pm_stay_awake(&lock->ws); -+} -+ -+static inline void wake_lock_timeout(struct wake_lock *lock, long timeout) -+{ -+ __pm_wakeup_event(&lock->ws, jiffies_to_msecs(timeout)); -+} -+ -+static inline void wake_unlock(struct wake_lock *lock) -+{ -+ __pm_relax(&lock->ws); -+} -+ -+static inline int wake_lock_active(struct wake_lock *lock) -+{ -+ return lock->ws.active; -+} -+ -+#endif -diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h -index f12fa5245a45..946ccff6ddc0 100644 ---- a/include/net/cfg80211.h -+++ b/include/net/cfg80211.h -@@ -3261,7 +3261,7 @@ enum wiphy_flags { - WIPHY_FLAG_CONTROL_PORT_PROTOCOL = BIT(7), - WIPHY_FLAG_IBSS_RSN = BIT(8), - WIPHY_FLAG_MESH_AUTH = BIT(10), -- /* use hole at 11 */ -+ WIPHY_FLAG_SUPPORTS_SCHED_SCAN = BIT(11), - /* use hole at 12 */ - WIPHY_FLAG_SUPPORTS_FW_ROAM = BIT(13), - WIPHY_FLAG_AP_UAPSD = BIT(14), -diff --git a/include/net/genetlink.h b/include/net/genetlink.h -index 5ac169a735f4..b25568a44e59 100644 ---- a/include/net/genetlink.h -+++ b/include/net/genetlink.h -@@ -144,6 +144,51 @@ struct genl_ops { - }; - - int genl_register_family(struct genl_family *family); -+ -+/** -+ * genl_register_family_with_ops - register a generic netlink family with ops -+ * @family: generic netlink family -+ * @ops: operations to be registered -+ * @n_ops: number of elements to register -+ * -+ * Registers the specified family and operations from the specified table. -+ * Only one family may be registered with the same family name or identifier. -+ * -+ * The family id may equal GENL_ID_GENERATE causing an unique id to -+ * be automatically generated and assigned. -+ * -+ * Either a doit or dumpit callback must be specified for every registered -+ * operation or the function will fail. Only one operation structure per -+ * command identifier may be registered. -+ * -+ * See include/net/genetlink.h for more documenation on the operations -+ * structure. -+ * -+ * Return 0 on success or a negative error code. -+ */ -+static inline int -+_genl_register_family_with_ops_grps(struct genl_family *family, -+ const struct genl_ops *ops, size_t n_ops, -+ const struct genl_multicast_group *mcgrps, -+ size_t n_mcgrps) -+{ -+ family->module = THIS_MODULE; -+ family->ops = ops; -+ family->n_ops = n_ops; -+ family->mcgrps = mcgrps; -+ family->n_mcgrps = n_mcgrps; -+ return genl_register_family(family); -+} -+ -+#define genl_register_family_with_ops(family, ops) \ -+ _genl_register_family_with_ops_grps((family), \ -+ (ops), ARRAY_SIZE(ops), \ -+ NULL, 0) -+#define genl_register_family_with_ops_groups(family, ops, grps) \ -+ _genl_register_family_with_ops_grps((family), \ -+ (ops), ARRAY_SIZE(ops), \ -+ (grps), ARRAY_SIZE(grps)) -+ - int genl_unregister_family(const struct genl_family *family); - void genl_notify(const struct genl_family *family, struct sk_buff *skb, - struct genl_info *info, u32 group, gfp_t flags); -diff --git a/include/soc/mediatek/pmic_wrap.h b/include/soc/mediatek/pmic_wrap.h -new file mode 100644 -index 000000000000..5b5c85272c58 ---- /dev/null -+++ b/include/soc/mediatek/pmic_wrap.h -@@ -0,0 +1,19 @@ -+/* -+ * Copyright (C) 2015 MediaTek Inc. -+ * -+ * 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. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#ifndef __SOC_MEDIATEK_PMIC_WRAP_H -+#define __SOC_MEDIATEK_PMIC_WRAP_H -+ -+extern struct regmap *pwrap_node_to_regmap(struct device_node *np); -+ -+#endif /* __SOC_MEDIATEK_PMIC_WRAP_H */ -diff --git a/include/uapi/linux/genetlink.h b/include/uapi/linux/genetlink.h -index 877f7fa95466..c8456b78cc25 100644 ---- a/include/uapi/linux/genetlink.h -+++ b/include/uapi/linux/genetlink.h -@@ -27,6 +27,7 @@ struct genlmsghdr { - /* - * List of reserved static generic netlink identifiers: - */ -+#define GENL_ID_GENERATE 0 - #define GENL_ID_CTRL NLMSG_MIN_TYPE - #define GENL_ID_VFS_DQUOT (NLMSG_MIN_TYPE + 1) - #define GENL_ID_PMCRAID (NLMSG_MIN_TYPE + 2) --- -2.17.1 - diff --git a/root/target/linux/mediatek/patches-4.14/0233-revert-unexport-vfs_read-write.patch b/root/target/linux/mediatek/patches-4.14/0233-revert-unexport-vfs_read-write.patch deleted file mode 100644 index 5b8e6131..00000000 --- a/root/target/linux/mediatek/patches-4.14/0233-revert-unexport-vfs_read-write.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 16c20209050ce9dc0d67e256c3dfba902868c3ed Mon Sep 17 00:00:00 2001 -From: Nikolay Amiantov -Date: Tue, 3 Jul 2018 12:40:04 +0000 -Subject: [PATCH] Revert "fs: unexport vfs_read and vfs_write" - -This reverts commit bd8df82be66698042d11e7919e244c8d72b042ca. ---- - fs/read_write.c | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/fs/read_write.c b/fs/read_write.c -index 0046d72efe94..62b9c341afa9 100644 ---- a/fs/read_write.c -+++ b/fs/read_write.c -@@ -455,6 +455,8 @@ ssize_t vfs_read(struct file *file, char __user *buf, size_t count, loff_t *pos) - return ret; - } - -+EXPORT_SYMBOL(vfs_read); -+ - static ssize_t new_sync_write(struct file *filp, const char __user *buf, size_t len, loff_t *ppos) - { - struct iovec iov = { .iov_base = (void __user *)buf, .iov_len = len }; -@@ -553,6 +555,8 @@ ssize_t vfs_write(struct file *file, const char __user *buf, size_t count, loff_ - return ret; - } - -+EXPORT_SYMBOL(vfs_write); -+ - static inline loff_t file_pos_read(struct file *file) - { - return file->f_pos; --- -2.17.1 - diff --git a/root/target/linux/mediatek/patches-4.14/0234-fix-mtk-wlan_gen2-module.patch b/root/target/linux/mediatek/patches-4.14/0234-fix-mtk-wlan_gen2-module.patch deleted file mode 100644 index bc957ee1..00000000 --- a/root/target/linux/mediatek/patches-4.14/0234-fix-mtk-wlan_gen2-module.patch +++ /dev/null @@ -1,127 +0,0 @@ -Index: linux-4.14.51/drivers/misc/mediatek/connectivity/common/conn_soc/mt7623/mtk_wcn_consys_hw.c -=================================================================== ---- linux-4.14.51.orig/drivers/misc/mediatek/connectivity/common/conn_soc/mt7623/mtk_wcn_consys_hw.c -+++ linux-4.14.51/drivers/misc/mediatek/connectivity/common/conn_soc/mt7623/mtk_wcn_consys_hw.c -@@ -519,6 +519,9 @@ INT32 mtk_wcn_consys_hw_wifi_paldo_ctrl( - } - - #endif -+ -+EXPORT_SYMBOL(mtk_wcn_consys_hw_wifi_paldo_ctrl); -+ - INT32 mtk_wcn_consys_hw_vcn28_ctrl(UINT32 enable) - { - if (enable) { -Index: linux-4.14.51/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_kal.c -=================================================================== ---- linux-4.14.51.orig/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_kal.c -+++ linux-4.14.51/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_kal.c -@@ -4530,13 +4530,10 @@ INT_32 kalHaltLock(UINT_32 waitMs) - DBGLOG(INIT, ERROR, - "kalIoctl was executed longer than %u ms, show backtrace of tx_thread!\n", - kalGetTimeTick() - rHaltCtrl.u4HoldStart); -- if (prGlueInfo) -- show_stack(prGlueInfo->main_thread, NULL); - } else { - DBGLOG(INIT, ERROR, "halt lock held by %s pid %d longer than %u ms!\n", - rHaltCtrl.owner->comm, rHaltCtrl.owner->pid, - kalGetTimeTick() - rHaltCtrl.u4HoldStart); -- show_stack(rHaltCtrl.owner, NULL); - } - return i4Ret; - } -Index: linux-4.14.51/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_rst.c -=================================================================== ---- linux-4.14.51.orig/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_rst.c -+++ linux-4.14.51/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_rst.c -@@ -58,7 +58,6 @@ - ******************************************************************************** - */ - BOOLEAN fgIsResetting = FALSE; --UINT_32 g_IsNeedDoChipReset = 0; - - /******************************************************************************* - * P R I V A T E D A T A -Index: linux-4.14.51/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/wmt_chrdev_wifi.c -=================================================================== ---- linux-4.14.51.orig/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/wmt_chrdev_wifi.c -+++ linux-4.14.51/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/wmt_chrdev_wifi.c -@@ -44,6 +44,9 @@ MODULE_LICENSE("Dual BSD/GPL"); - #define WIFI_LOG_WARN 1 - #define WIFI_LOG_ERR 0 - -+UINT32 g_IsNeedDoChipReset = 0; -+EXPORT_SYMBOL(g_IsNeedDoChipReset); -+ - UINT32 gDbgLevel = WIFI_LOG_DBG; - - #define WIFI_DBG_FUNC(fmt, arg...)\ -Index: linux-4.14.51/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/Makefile -=================================================================== ---- linux-4.14.51.orig/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/Makefile -+++ linux-4.14.51/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/Makefile -@@ -21,7 +21,11 @@ endif - obj-y += osal.o \ - bgw_desense.o \ - wmt_idc.o --obj-$(CONFIG_MTK_COMBO_BT) += stp_chrdev_bt.o --obj-$(CONFIG_MTK_COMBO_WIFI) += wmt_chrdev_wifi.o -+ifneq ($(CONFIG_MTK_COMBO_BT),) -+ obj-y += stp_chrdev_bt.o -+endif -+ifneq ($(CONFIG_MTK_COMBO_WIFI),) -+ obj-y += wmt_chrdev_wifi.o -+endif - - endif -Index: linux-4.14.51/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/wlan_drv_init.c -=================================================================== ---- linux-4.14.51.orig/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/wlan_drv_init.c -+++ linux-4.14.51/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/wlan_drv_init.c -@@ -25,7 +25,7 @@ int do_wlan_drv_init(int chip_id) - { - int i_ret = 0; - --#ifdef CONFIG_MTK_COMBO_WIFI -+#ifdef MTK_WIFI_ENABLED - int ret = 0; - - WMT_DETECT_INFO_FUNC("start to do wlan module init 0x%x\n", chip_id); -@@ -35,6 +35,7 @@ int do_wlan_drv_init(int chip_id) - WMT_DETECT_INFO_FUNC("WMT-WIFI char dev init, ret:%d\n", ret); - i_ret += ret; - -+#ifdef CONFIG_MTK_COMBO_WIFI - switch (chip_id) { - case 0x6630: - case 0x6797: -@@ -61,13 +62,10 @@ int do_wlan_drv_init(int chip_id) - #endif - break; - } -- -+#endif - WMT_DETECT_INFO_FUNC("finish wlan module init\n"); -- - #else -- - WMT_DETECT_INFO_FUNC("CONFIG_MTK_COMBO_WIFI is not defined\n"); -- - #endif - - return i_ret; -Index: linux-4.14.51/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/Makefile -=================================================================== ---- linux-4.14.51.orig/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/Makefile -+++ linux-4.14.51/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/Makefile -@@ -11,6 +11,10 @@ else ifneq ($(filter "CONSYS_%",$(CONFIG - ccflags-y += -D MTK_WCN_WLAN_GEN2 - endif - -+ifneq ($(CONFIG_MTK_COMBO_WIFI),) -+ ccflags-y += -D MTK_WIFI_ENABLED -+endif -+ - obj-y += conn_drv_init.o - obj-y += common_drv_init.o - obj-y += bluetooth_drv_init.o diff --git a/root/target/linux/mediatek/patches-4.14/0235-mtk_wdt-remove-debug-printk.patch b/root/target/linux/mediatek/patches-4.14/0235-mtk_wdt-remove-debug-printk.patch deleted file mode 100644 index a9f2078c..00000000 --- a/root/target/linux/mediatek/patches-4.14/0235-mtk_wdt-remove-debug-printk.patch +++ /dev/null @@ -1,12 +0,0 @@ -Index: linux-4.14.51/drivers/watchdog/mtk_wdt.c -=================================================================== ---- linux-4.14.51.orig/drivers/watchdog/mtk_wdt.c -+++ linux-4.14.51/drivers/watchdog/mtk_wdt.c -@@ -236,7 +236,6 @@ static int mtk_wdt_ping(struct watchdog_ - void __iomem *wdt_base = mtk_wdt->wdt_base; - - iowrite32(WDT_RST_RELOAD, wdt_base + WDT_RST); -- printk_deferred("[WDK]: kick Ex WDT\n"); - - return 0; - } diff --git a/root/target/linux/mediatek/patches-4.14/0236-mt6625l-rename-wlan.patch b/root/target/linux/mediatek/patches-4.14/0236-mt6625l-rename-wlan.patch deleted file mode 100644 index e1691fd3..00000000 --- a/root/target/linux/mediatek/patches-4.14/0236-mt6625l-rename-wlan.patch +++ /dev/null @@ -1,13 +0,0 @@ -Index: linux-4.14.51/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/wmt_chrdev_wifi.c -=================================================================== ---- linux-4.14.51.orig/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/wmt_chrdev_wifi.c -+++ linux-4.14.51/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/wmt_chrdev_wifi.c -@@ -62,7 +62,7 @@ UINT32 gDbgLevel = WIFI_LOG_DBG; - - #define VERSION "1.0" - --#define WLAN_IFACE_NAME "wlan0" -+#define WLAN_IFACE_NAME "mtkwlan0" - #if CFG_TC1_FEATURE - #define LEGACY_IFACE_NAME "legacy0" - #endif diff --git a/root/target/linux/mediatek/patches-4.14/0237-mt7623-add-HNAT-support.patch b/root/target/linux/mediatek/patches-4.14/0237-mt7623-add-HNAT-support.patch deleted file mode 100644 index 5f71df06..00000000 --- a/root/target/linux/mediatek/patches-4.14/0237-mt7623-add-HNAT-support.patch +++ /dev/null @@ -1,1824 +0,0 @@ -From b3ba09aea285ecdac5228805411f1e7a6c68382a Mon Sep 17 00:00:00 2001 -From: Frank Wunderlich -Date: Sun, 8 Jul 2018 17:27:58 +0200 -Subject: [PATCH] [HNAT] applied full Patch from hnat-branch - ---- - arch/arm/boot/dts/mt7623.dtsi | 9 + - arch/arm/configs/mt7623n_evb_fwu_defconfig | 4 +- - drivers/net/ethernet/mediatek/Kconfig | 7 + - drivers/net/ethernet/mediatek/Makefile | 1 + - drivers/net/ethernet/mediatek/mtk_eth_soc.c | 22 + - .../net/ethernet/mediatek/mtk_hnat/Makefile | 4 + - drivers/net/ethernet/mediatek/mtk_hnat/hnat.c | 329 ++++++++++++ - drivers/net/ethernet/mediatek/mtk_hnat/hnat.h | 427 +++++++++++++++ - .../ethernet/mediatek/mtk_hnat/hnat_debugfs.c | 489 ++++++++++++++++++ - .../ethernet/mediatek/mtk_hnat/hnat_nf_hook.c | 312 +++++++++++ - .../ethernet/mediatek/mtk_hnat/nf_hnat_mtk.h | 44 ++ - net/netfilter/nf_conntrack_proto_tcp.c | 19 + - 12 files changed, 1666 insertions(+), 1 deletion(-) - create mode 100644 drivers/net/ethernet/mediatek/mtk_hnat/Makefile - create mode 100644 drivers/net/ethernet/mediatek/mtk_hnat/hnat.c - create mode 100644 drivers/net/ethernet/mediatek/mtk_hnat/hnat.h - create mode 100644 drivers/net/ethernet/mediatek/mtk_hnat/hnat_debugfs.c - create mode 100644 drivers/net/ethernet/mediatek/mtk_hnat/hnat_nf_hook.c - create mode 100644 drivers/net/ethernet/mediatek/mtk_hnat/nf_hnat_mtk.h - -diff --git a/arch/arm/boot/dts/mt7623.dtsi b/arch/arm/boot/dts/mt7623.dtsi -index 44831a813a48f..1633d19564ca8 100644 ---- a/arch/arm/boot/dts/mt7623.dtsi -+++ b/arch/arm/boot/dts/mt7623.dtsi -@@ -1207,6 +1207,15 @@ - status = "disabled"; - }; - -+ hnat: hnat@1b000000 { -+ compatible = "mediatek,mt7623-hnat"; -+ reg = <0 0x1b100000 0 0x3000>; -+ mtketh-wan = "wan"; -+ resets = <ðsys 0>; -+ reset-names = "mtketh"; -+ }; -+ -+ - crypto: crypto@1b240000 { - compatible = "mediatek,mt7623-crypto"; - reg = <0 0x1b240000 0 0x20000>; -diff --git a/drivers/net/ethernet/mediatek/Kconfig b/drivers/net/ethernet/mediatek/Kconfig -index f9149d2a46940..314c6fe670f81 100644 ---- a/drivers/net/ethernet/mediatek/Kconfig -+++ b/drivers/net/ethernet/mediatek/Kconfig -@@ -14,4 +14,11 @@ config NET_MEDIATEK_SOC - This driver supports the gigabit ethernet MACs in the - MediaTek SoC family. - -+config NET_MEDIATEK_HNAT -+ tristate "MediaTek MT7623 hardware NAT support" -+ depends on NET_MEDIATEK_SOC && NF_CONNTRACK && NF_CONNTRACK_IPV4 && IP_NF_NAT && IP_NF_TARGET_MASQUERADE -+ ---help--- -+ This driver supports the hardware NAT in the -+ MediaTek MT2701/MT7623 chipset family. -+ - endif #NET_VENDOR_MEDIATEK -diff --git a/drivers/net/ethernet/mediatek/Makefile b/drivers/net/ethernet/mediatek/Makefile -index aa3f1c8ccd4ab..355c928f4700e 100644 ---- a/drivers/net/ethernet/mediatek/Makefile -+++ b/drivers/net/ethernet/mediatek/Makefile -@@ -3,3 +3,4 @@ - # - - obj-$(CONFIG_NET_MEDIATEK_SOC) += mtk_eth_soc.o -+obj-$(CONFIG_NET_MEDIATEK_HNAT) += mtk_hnat/ -diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -index e6b6596e6a4a9..de4969cc672c4 100644 ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -24,6 +24,10 @@ - #include - #include - -+#if defined(CONFIG_NET_MEDIATEK_HNAT) || defined(CONFIG_NET_MEDIATEK_HNAT_MODULE) -+#include "mtk_hnat/nf_hnat_mtk.h" -+#endif -+ - #include "mtk_eth_soc.h" - - static int mtk_msg_level = -1; -@@ -699,6 +703,11 @@ static int mtk_tx_map(struct sk_buff *skb, struct net_device *dev, - return -ENOMEM; - - /* set the forward port */ -+#if defined(CONFIG_NET_MEDIATEK_HNAT) || defined(CONFIG_NET_MEDIATEK_HNAT_MODULE) -+ if (HNAT_SKB_CB2(skb)->magic == 0x78681415) -+ fport |= 0x4 << TX_DMA_FPORT_SHIFT; -+ else -+#endif - fport = (mac->id + 1) << TX_DMA_FPORT_SHIFT; - txd4 |= fport; - -@@ -1063,6 +1072,10 @@ static int mtk_poll_rx(struct napi_struct *napi, int budget, - RX_DMA_VID(trxd.rxd3)) - __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), - RX_DMA_VID(trxd.rxd3)); -+#if defined(CONFIG_NET_MEDIATEK_HNAT) || defined(CONFIG_NET_MEDIATEK_HNAT_MODULE) -+ *(u32 *)(skb->head) = trxd.rxd4; -+ skb_hnat_alg(skb) = 0; -+#endif - skb_record_rx_queue(skb, 0); - napi_gro_receive(napi, skb); - -@@ -2000,6 +2013,12 @@ static int mtk_hw_init(struct mtk_eth *eth) - val = mtk_r32(eth, MTK_CDMP_IG_CTRL); - mtk_w32(eth, val | MTK_CDMP_STAG_EN, MTK_CDMP_IG_CTRL); - -+ /* Indicates CDM to parse the MTK special tag from CPU -+ * which also is working out for untag packets. -+ */ -+ val = mtk_r32(eth, MTK_CDMQ_IG_CTRL); -+ mtk_w32(eth, val | MTK_CDMQ_STAG_EN, MTK_CDMQ_IG_CTRL); -+ - /* Enable RX VLan Offloading */ - if (MTK_HW_FEATURES & NETIF_F_HW_VLAN_CTAG_RX) - mtk_w32(eth, 1, MTK_CDMP_EG_CTRL); -@@ -2033,6 +2052,9 @@ static int mtk_hw_init(struct mtk_eth *eth) - /* Enable RX checksum */ - val |= MTK_GDMA_ICS_EN | MTK_GDMA_TCS_EN | MTK_GDMA_UCS_EN; - -+ /* Enable special tag */ -+ val |= BIT(24); -+ - /* setup the mac dma */ - mtk_w32(eth, val, MTK_GDMA_FWD_CFG(i)); - } -diff --git a/drivers/net/ethernet/mediatek/mtk_hnat/Makefile b/drivers/net/ethernet/mediatek/mtk_hnat/Makefile -new file mode 100644 -index 0000000000000..e052abcd43020 ---- /dev/null -+++ b/drivers/net/ethernet/mediatek/mtk_hnat/Makefile -@@ -0,0 +1,4 @@ -+ccflags-y=-Werror -Wno-missing-braces -+ -+obj-$(CONFIG_NET_MEDIATEK_HNAT) += mtkhnat.o -+mtkhnat-objs := hnat.o hnat_nf_hook.o hnat_debugfs.o -diff --git a/drivers/net/ethernet/mediatek/mtk_hnat/hnat.c b/drivers/net/ethernet/mediatek/mtk_hnat/hnat.c -new file mode 100644 -index 0000000000000..22a822737934f ---- /dev/null -+++ b/drivers/net/ethernet/mediatek/mtk_hnat/hnat.c -@@ -0,0 +1,329 @@ -+/* This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; version 2 of the License -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * Copyright (C) 2014-2016 Sean Wang -+ * Copyright (C) 2016-2017 John Crispin -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "hnat.h" -+ -+struct hnat_priv *host; -+ -+static void cr_set_bits(void __iomem * reg, u32 bs) -+{ -+ u32 val = readl(reg); -+ -+ val |= bs; -+ writel(val, reg); -+} -+ -+static void cr_clr_bits(void __iomem * reg, u32 bs) -+{ -+ u32 val = readl(reg); -+ -+ val &= ~bs; -+ writel(val, reg); -+} -+ -+static void cr_set_field(void __iomem * reg, u32 field, u32 val) -+{ -+ unsigned int tv = readl(reg); -+ -+ tv &= ~field; -+ tv |= ((val) << (ffs((unsigned int)field) - 1)); -+ writel(tv, reg); -+} -+ -+static int hnat_start(void) -+{ -+ u32 foe_table_sz; -+ -+ /* mapp the FOE table */ -+ foe_table_sz = FOE_4TB_SIZ * sizeof(struct foe_entry); -+ host->foe_table_cpu = -+ dma_alloc_coherent(host->dev, foe_table_sz, &host->foe_table_dev, -+ GFP_KERNEL); -+ if (!host->foe_table_cpu) -+ return -1; -+ -+ writel(host->foe_table_dev, host->ppe_base + PPE_TB_BASE); -+ memset(host->foe_table_cpu, 0, foe_table_sz); -+ -+ /* setup hashing */ -+ cr_set_field(host->ppe_base + PPE_TB_CFG, TB_ETRY_NUM, TABLE_4K); -+ cr_set_field(host->ppe_base + PPE_TB_CFG, HASH_MODE, HASH_MODE_1); -+ writel(HASH_SEED_KEY, host->ppe_base + PPE_HASH_SEED); -+ cr_set_field(host->ppe_base + PPE_TB_CFG, XMODE, 0); -+ cr_set_field(host->ppe_base + PPE_TB_CFG, TB_ENTRY_SIZE, ENTRY_64B); -+ cr_set_field(host->ppe_base + PPE_TB_CFG, SMA, SMA_FWD_CPU_BUILD_ENTRY); -+ -+ /* set ip proto */ -+ writel(0xFFFFFFFF, host->ppe_base + PPE_IP_PROT_CHK); -+ -+ /* setup caching */ -+ cr_set_field(host->ppe_base + PPE_CAH_CTRL, CAH_X_MODE, 1); -+ cr_set_field(host->ppe_base + PPE_CAH_CTRL, CAH_X_MODE, 0); -+ cr_set_field(host->ppe_base + PPE_CAH_CTRL, CAH_EN, 1); -+ -+ /* enable FOE */ -+ cr_set_bits(host->ppe_base + PPE_FLOW_CFG, -+ BIT_IPV4_NAT_EN | BIT_IPV4_NAPT_EN | -+ BIT_IPV4_NAT_FRAG_EN | BIT_IPV4_HASH_GREK); -+ -+ /* setup FOE aging */ -+ cr_set_field(host->ppe_base + PPE_TB_CFG, NTU_AGE, 1); -+ cr_set_field(host->ppe_base + PPE_TB_CFG, UNBD_AGE, 1); -+ cr_set_field(host->ppe_base + PPE_UNB_AGE, UNB_MNP, 1000); -+ cr_set_field(host->ppe_base + PPE_UNB_AGE, UNB_DLTA, 3); -+ cr_set_field(host->ppe_base + PPE_TB_CFG, TCP_AGE, 1); -+ cr_set_field(host->ppe_base + PPE_TB_CFG, UDP_AGE, 1); -+ cr_set_field(host->ppe_base + PPE_TB_CFG, FIN_AGE, 1); -+ cr_set_field(host->ppe_base + PPE_BND_AGE_0, UDP_DLTA, 5); -+ cr_set_field(host->ppe_base + PPE_BND_AGE_0, NTU_DLTA, 5); -+ cr_set_field(host->ppe_base + PPE_BND_AGE_1, FIN_DLTA, 5); -+ cr_set_field(host->ppe_base + PPE_BND_AGE_1, TCP_DLTA, 5); -+ -+ /* setup FOE ka */ -+ cr_set_field(host->ppe_base + PPE_TB_CFG, KA_CFG, 3); -+ cr_set_field(host->ppe_base + PPE_KA, KA_T, 1); -+ cr_set_field(host->ppe_base + PPE_KA, TCP_KA, 1); -+ cr_set_field(host->ppe_base + PPE_KA, UDP_KA, 1); -+ cr_set_field(host->ppe_base + PPE_BIND_LMT_1, NTU_KA, 1); -+ -+ /* setup FOE rate limit */ -+ cr_set_field(host->ppe_base + PPE_BIND_LMT_0, QURT_LMT, 16383); -+ cr_set_field(host->ppe_base + PPE_BIND_LMT_0, HALF_LMT, 16383); -+ cr_set_field(host->ppe_base + PPE_BIND_LMT_1, FULL_LMT, 16383); -+ cr_set_field(host->ppe_base + PPE_BNDR, BIND_RATE, 1); -+ -+ /* setup FOE cf gen */ -+ cr_set_field(host->ppe_base + PPE_GLO_CFG, PPE_EN, 1); -+ writel(0, host->ppe_base + PPE_DFT_CPORT); // pdma -+ //writel(0x55555555, host->ppe_base + PPE_DFT_CPORT); //qdma -+ cr_set_field(host->ppe_base + PPE_GLO_CFG, TTL0_DRP, 1); -+ -+ /* fwd packets from gmac to PPE */ -+ cr_clr_bits(host->fe_base + GDMA1_FWD_CFG, GDM1_ALL_FRC_MASK); -+ cr_set_bits(host->fe_base + GDMA1_FWD_CFG, -+ BITS_GDM1_ALL_FRC_P_PPE); -+ cr_clr_bits(host->fe_base + GDMA2_FWD_CFG, GDM2_ALL_FRC_MASK); -+ cr_set_bits(host->fe_base + GDMA2_FWD_CFG, -+ BITS_GDM2_ALL_FRC_P_PPE); -+ -+ dev_info(host->dev, "hwnat start\n"); -+ -+ return 0; -+} -+ -+static int ppe_busy_wait(void) -+{ -+ unsigned long t_start = jiffies; -+ u32 r = 0; -+ -+ while (1) { -+ r = readl((host->ppe_base + 0x0)); -+ if (!(r & BIT(31))) -+ return 0; -+ if (time_after(jiffies, t_start + HZ)) -+ break; -+ usleep_range(10, 20); -+ } -+ -+ dev_err(host->dev, "ppe:%s timeout\n", __func__); -+ -+ return -1; -+} -+ -+static void hnat_stop(void) -+{ -+ u32 foe_table_sz; -+ struct foe_entry *entry, *end; -+ u32 r1 = 0, r2 = 0; -+ -+ /* discard all traffic while we disable the PPE */ -+ cr_clr_bits(host->fe_base + GDMA1_FWD_CFG, GDM1_ALL_FRC_MASK); -+ cr_set_bits(host->fe_base + GDMA1_FWD_CFG, -+ BITS_GDM1_ALL_FRC_P_DISCARD); -+ cr_clr_bits(host->fe_base + GDMA2_FWD_CFG, GDM2_ALL_FRC_MASK); -+ cr_set_bits(host->fe_base + GDMA2_FWD_CFG, -+ BITS_GDM2_ALL_FRC_P_DISCARD); -+ -+ if (ppe_busy_wait()) { -+#if 0 -+ reset_control_reset(host->rstc); -+#endif -+ msleep(2000); -+ return; -+ } -+ -+ entry = host->foe_table_cpu; -+ end = host->foe_table_cpu + FOE_4TB_SIZ; -+ while (entry < end) { -+ entry->bfib1.state = INVALID; -+ entry++; -+ } -+ -+ /* disable caching */ -+ cr_set_field(host->ppe_base + PPE_CAH_CTRL, CAH_X_MODE, 1); -+ cr_set_field(host->ppe_base + PPE_CAH_CTRL, CAH_X_MODE, 0); -+ cr_set_field(host->ppe_base + PPE_CAH_CTRL, CAH_EN, 0); -+ -+ /* flush cache has to be ahead of hnat diable --*/ -+ cr_set_field(host->ppe_base + PPE_GLO_CFG, PPE_EN, 0); -+ -+ /* disable FOE */ -+ cr_clr_bits(host->ppe_base + PPE_FLOW_CFG, -+ BIT_IPV4_NAPT_EN | BIT_IPV4_NAT_EN | -+ BIT_IPV4_NAT_FRAG_EN | -+ BIT_FUC_FOE | BIT_FMC_FOE | BIT_FUC_FOE); -+ -+ /* disable FOE aging */ -+ cr_set_field(host->ppe_base + PPE_TB_CFG, NTU_AGE, 0); -+ cr_set_field(host->ppe_base + PPE_TB_CFG, UNBD_AGE, 0); -+ cr_set_field(host->ppe_base + PPE_TB_CFG, TCP_AGE, 0); -+ cr_set_field(host->ppe_base + PPE_TB_CFG, UDP_AGE, 0); -+ cr_set_field(host->ppe_base + PPE_TB_CFG, FIN_AGE, 0); -+ -+ r1 = readl(host->fe_base + 0x100); -+ r2 = readl(host->fe_base + 0x10c); -+ -+ dev_info(host->dev, "0x100 = 0x%x, 0x10c = 0x%x\n", r1, r2); -+ -+ if (((r1 & 0xff00) >> 0x8) >= (r1 & 0xff) || -+ ((r1 & 0xff00) >> 0x8) >= (r2 & 0xff)) { -+ dev_info(host->dev, "reset pse\n"); -+ writel(0x1, host->fe_base + 0x4); -+ } -+ -+ /* free the FOE table */ -+ foe_table_sz = FOE_4TB_SIZ * sizeof(struct foe_entry); -+ dma_free_coherent(NULL, foe_table_sz, host->foe_table_cpu, -+ host->foe_table_dev); -+ writel(0, host->ppe_base + PPE_TB_BASE); -+ -+ if (ppe_busy_wait()) { -+#if 0 -+ reset_control_reset(host->rstc); -+#endif -+ msleep(2000); -+ return; -+ } -+ -+ /* send all traffic back to the DMA engine */ -+ cr_clr_bits(host->fe_base + GDMA1_FWD_CFG, GDM1_ALL_FRC_MASK); -+ cr_set_bits(host->fe_base + GDMA1_FWD_CFG, -+ BITS_GDM1_ALL_FRC_P_CPU_PDMA); -+ cr_clr_bits(host->fe_base + GDMA2_FWD_CFG, GDM2_ALL_FRC_MASK); -+ cr_set_bits(host->fe_base + GDMA2_FWD_CFG, -+ BITS_GDM2_ALL_FRC_P_CPU_PDMA); -+} -+ -+static int hnat_probe(struct platform_device *pdev) -+{ -+ struct net *net; -+ int ret; -+ int err = 0; -+ struct resource *res ; -+ const char *name; -+ struct device_node *np; -+ -+ host = devm_kzalloc(&pdev->dev, sizeof(struct hnat_priv), GFP_KERNEL); -+ if (!host) -+ return -ENOMEM; -+ -+ host->dev = &pdev->dev; -+ np = host->dev->of_node; -+ -+ err = of_property_read_string(np, "mtketh-wan", &name); -+ if (err < 0) -+ return -EINVAL; -+ -+ memcpy(host->wan, (char *)name, IFNAMSIZ); -+ dev_info(&pdev->dev, "wan = %s\n", host->wan); -+ -+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ if (!res) -+ return -ENOENT; -+ -+ host->fe_base = devm_ioremap_nocache(&pdev->dev, res->start, -+ res->end - res->start + 1); -+ if (!host->fe_base) -+ return -EADDRNOTAVAIL; -+ -+ host->ppe_base = host->fe_base + 0xe00; -+ err = hnat_init_debugfs(host); -+ if (err) -+ return err; -+#if 0 -+ host->rstc = devm_reset_control_get(&pdev->dev, NULL); -+ if (IS_ERR(host->rstc)) -+ return PTR_ERR(host->rstc); -+#endif -+ err = hnat_start(); -+ if (err) -+ goto err_out; -+ -+ //err = hnat_register_nf_hooks(); //how to call the function with net-param?? -+ for_each_net(net) { -+ ret=hnat_register_nf_hooks(net); -+ //if (err) -+ if (ret && ret != -ENOENT) -+ goto err_out; -+ } -+ return 0; -+ -+err_out: -+ hnat_stop(); -+ hnat_deinit_debugfs(host); -+ return err; -+} -+ -+static int hnat_remove(struct platform_device *pdev) -+{ -+ struct net *net; -+ //hnat_unregister_nf_hooks(); //how to call the function with net-param?? -+ for_each_net(net) { -+ hnat_unregister_nf_hooks(net); -+ } -+ -+ hnat_stop(); -+ hnat_deinit_debugfs(host); -+ -+ return 0; -+} -+ -+const struct of_device_id of_hnat_match[] = { -+ { .compatible = "mediatek,mt7623-hnat" }, -+ {}, -+}; -+ -+static struct platform_driver hnat_driver = { -+ .probe = hnat_probe, -+ .remove = hnat_remove, -+ .driver = { -+ .name = "mediatek_soc_hnat", -+ .of_match_table = of_hnat_match, -+ }, -+}; -+ -+module_platform_driver(hnat_driver); -+ -+MODULE_LICENSE("GPL v2"); -+MODULE_AUTHOR("Sean Wang "); -+MODULE_AUTHOR("John Crispin "); -+MODULE_DESCRIPTION("Mediatek Hardware NAT"); -diff --git a/drivers/net/ethernet/mediatek/mtk_hnat/hnat.h b/drivers/net/ethernet/mediatek/mtk_hnat/hnat.h -new file mode 100644 -index 0000000000000..336ebb34c325d ---- /dev/null -+++ b/drivers/net/ethernet/mediatek/mtk_hnat/hnat.h -@@ -0,0 +1,427 @@ -+/* This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; version 2 of the License -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * Copyright (C) 2014-2016 Sean Wang -+ * Copyright (C) 2016-2017 John Crispin -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+/*--------------------------------------------------------------------------*/ -+/* Register Offset*/ -+/*--------------------------------------------------------------------------*/ -+#define PPE_GLO_CFG 0x00 -+#define PPE_FLOW_CFG 0x04 -+#define PPE_IP_PROT_CHK 0x08 -+#define PPE_IP_PROT_0 0x0C -+#define PPE_IP_PROT_1 0x10 -+#define PPE_IP_PROT_2 0x14 -+#define PPE_IP_PROT_3 0x18 -+#define PPE_TB_CFG 0x1C -+#define PPE_TB_BASE 0x20 -+#define PPE_TB_USED 0x24 -+#define PPE_BNDR 0x28 -+#define PPE_BIND_LMT_0 0x2C -+#define PPE_BIND_LMT_1 0x30 -+#define PPE_KA 0x34 -+#define PPE_UNB_AGE 0x38 -+#define PPE_BND_AGE_0 0x3C -+#define PPE_BND_AGE_1 0x40 -+#define PPE_HASH_SEED 0x44 -+#define PPE_DFT_CPORT 0x48 -+#define PPE_MCAST_PPSE 0x84 -+#define PPE_MCAST_L_0 0x88 -+#define PPE_MCAST_H_0 0x8C -+#define PPE_MCAST_L_1 0x90 -+#define PPE_MCAST_H_1 0x94 -+#define PPE_MCAST_L_2 0x98 -+#define PPE_MCAST_H_2 0x9C -+#define PPE_MCAST_L_3 0xA0 -+#define PPE_MCAST_H_3 0xA4 -+#define PPE_MCAST_L_4 0xA8 -+#define PPE_MCAST_H_4 0xAC -+#define PPE_MCAST_L_5 0xB0 -+#define PPE_MCAST_H_5 0xB4 -+#define PPE_MCAST_L_6 0xBC -+#define PPE_MCAST_H_6 0xC0 -+#define PPE_MCAST_L_7 0xC4 -+#define PPE_MCAST_H_7 0xC8 -+#define PPE_MCAST_L_8 0xCC -+#define PPE_MCAST_H_8 0xD0 -+#define PPE_MCAST_L_9 0xD4 -+#define PPE_MCAST_H_9 0xD8 -+#define PPE_MCAST_L_A 0xDC -+#define PPE_MCAST_H_A 0xE0 -+#define PPE_MCAST_L_B 0xE4 -+#define PPE_MCAST_H_B 0xE8 -+#define PPE_MCAST_L_C 0xEC -+#define PPE_MCAST_H_C 0xF0 -+#define PPE_MCAST_L_D 0xF4 -+#define PPE_MCAST_H_D 0xF8 -+#define PPE_MCAST_L_E 0xFC -+#define PPE_MCAST_H_E 0xE0 -+#define PPE_MCAST_L_F 0x100 -+#define PPE_MCAST_H_F 0x104 -+#define PPE_MTU_DRP 0x108 -+#define PPE_MTU_VLYR_0 0x10C -+#define PPE_MTU_VLYR_1 0x110 -+#define PPE_MTU_VLYR_2 0x114 -+#define PPE_VPM_TPID 0x118 -+#define PPE_CAH_CTRL 0x120 -+#define PPE_CAH_TAG_SRH 0x124 -+#define PPE_CAH_LINE_RW 0x128 -+#define PPE_CAH_WDATA 0x12C -+#define PPE_CAH_RDATA 0x130 -+ -+#define GDMA1_FWD_CFG 0x500 -+#define GDMA2_FWD_CFG 0x1500 -+/*--------------------------------------------------------------------------*/ -+/* Register Mask*/ -+/*--------------------------------------------------------------------------*/ -+/* PPE_TB_CFG mask */ -+#define TB_ETRY_NUM (0x7 << 0) /* RW */ -+#define TB_ENTRY_SIZE (0x1 << 3) /* RW */ -+#define SMA (0x3 << 4) /* RW */ -+#define NTU_AGE (0x1 << 7) /* RW */ -+#define UNBD_AGE (0x1 << 8) /* RW */ -+#define TCP_AGE (0x1 << 9) /* RW */ -+#define UDP_AGE (0x1 << 10) /* RW */ -+#define FIN_AGE (0x1 << 11) /* RW */ -+#define KA_CFG (0x3<< 12) -+#define HASH_MODE (0x3 << 14) /* RW */ -+#define XMODE (0x3 << 18) /* RW */ -+ -+/*PPE_CAH_CTRL mask*/ -+#define CAH_EN (0x1 << 0) /* RW */ -+#define CAH_X_MODE (0x1 << 9) /* RW */ -+ -+/*PPE_UNB_AGE mask*/ -+#define UNB_DLTA (0xff << 0) /* RW */ -+#define UNB_MNP (0xffff << 16) /* RW */ -+ -+/*PPE_BND_AGE_0 mask*/ -+#define UDP_DLTA (0xffff << 0) /* RW */ -+#define NTU_DLTA (0xffff << 16) /* RW */ -+ -+/*PPE_BND_AGE_1 mask*/ -+#define TCP_DLTA (0xffff << 0) /* RW */ -+#define FIN_DLTA (0xffff << 16) /* RW */ -+ -+/*PPE_KA mask*/ -+#define KA_T (0xffff << 0) /* RW */ -+#define TCP_KA (0xff << 16) /* RW */ -+#define UDP_KA (0xff << 24) /* RW */ -+ -+/*PPE_BIND_LMT_0 mask*/ -+#define QURT_LMT (0x3ff << 0) /* RW */ -+#define HALF_LMT (0x3ff << 16) /* RW */ -+ -+/*PPE_BIND_LMT_1 mask*/ -+#define FULL_LMT (0x3fff << 0) /* RW */ -+#define NTU_KA (0xff << 16) /* RW */ -+ -+/*PPE_BNDR mask*/ -+#define BIND_RATE (0xffff << 0) /* RW */ -+#define PBND_RD_PRD (0xffff << 16) /* RW */ -+ -+/*PPE_GLO_CFG mask*/ -+#define PPE_EN (0x1 << 0) /* RW */ -+#define TTL0_DRP (0x1 << 4) /* RW */ -+ -+/*GDMA1_FWD_CFG mask */ -+#define GDM1_UFRC_MASK (0x7 << 12) /* RW */ -+#define GDM1_BFRC_MASK (0x7 << 8) /*RW*/ -+#define GDM1_MFRC_MASK (0x7 << 4) /*RW*/ -+#define GDM1_OFRC_MASK (0x7 << 0) /*RW*/ -+#define GDM1_ALL_FRC_MASK (GDM1_UFRC_MASK | GDM1_BFRC_MASK | GDM1_MFRC_MASK | GDM1_OFRC_MASK) -+ -+#define GDM2_UFRC_MASK (0x7 << 12) /* RW */ -+#define GDM2_BFRC_MASK (0x7 << 8) /*RW*/ -+#define GDM2_MFRC_MASK (0x7 << 4) /*RW*/ -+#define GDM2_OFRC_MASK (0x7 << 0) /*RW*/ -+#define GDM2_ALL_FRC_MASK (GDM2_UFRC_MASK | GDM2_BFRC_MASK | GDM2_MFRC_MASK | GDM2_OFRC_MASK) -+ -+/*--------------------------------------------------------------------------*/ -+/* Descriptor Structure */ -+/*--------------------------------------------------------------------------*/ -+#define HNAT_SKB_CB(__skb) ((struct hnat_skb_cb *)&((__skb)->cb[40])) -+struct hnat_skb_cb { -+ __u16 iif; -+}; -+ -+struct hnat_unbind_info_blk { -+ u32 time_stamp:8; -+ u32 pcnt:16; /* packet count */ -+ u32 preb:1; -+ u32 pkt_type:3; -+ u32 state:2; -+ u32 udp:1; -+ u32 sta:1; /* static entry */ -+} __attribute__ ((packed)); -+ -+struct hnat_bind_info_blk { -+ u32 time_stamp:15; -+ u32 ka:1; /* keep alive */ -+ u32 vlan_layer:3; -+ u32 psn:1; /* egress packet has PPPoE session */ -+ u32 vpm:1; /* 0:ethertype remark, 1:0x8100(CR default) */ -+ u32 ps:1; /* packet sampling */ -+ u32 cah:1; /* cacheable flag */ -+ u32 rmt:1; /* remove tunnel ip header (6rd/dslite only) */ -+ u32 ttl:1; -+ u32 pkt_type:3; -+ u32 state:2; -+ u32 udp:1; -+ u32 sta:1; /* static entry */ -+} __attribute__ ((packed)); -+ -+struct hnat_info_blk2 { -+ u32 qid:4; /* QID in Qos Port */ -+ u32 fqos:1; /* force to PSE QoS port */ -+ u32 dp:3; /* force to PSE port x -+ 0:PSE,1:GSW, 2:GMAC,4:PPE,5:QDMA,7=DROP */ -+ u32 mcast:1; /* multicast this packet to CPU */ -+ u32 pcpl:1; /* OSBN */ -+ u32 mlen:1; /* 0:post 1:pre packet length in meter */ -+ u32 alen:1; /* 0:post 1:pre packet length in accounting */ -+ u32 port_mg:6; /* port meter group */ -+ u32 port_ag:6; /* port account group */ -+ u32 dscp:8; /* DSCP value */ -+} __attribute__ ((packed)); -+ -+struct hnat_ipv4_hnapt { -+ union { -+ struct hnat_bind_info_blk bfib1; -+ struct hnat_unbind_info_blk udib1; -+ u32 info_blk1; -+ }; -+ u32 sip; -+ u32 dip; -+ u16 dport; -+ u16 sport; -+ union { -+ struct hnat_info_blk2 iblk2; -+ u32 info_blk2; -+ }; -+ u32 new_sip; -+ u32 new_dip; -+ u16 new_dport; -+ u16 new_sport; -+ u32 resv1; -+ u32 resv2; -+ u32 resv3:26; -+ u32 act_dp:6; /* UDF */ -+ u16 vlan1; -+ u16 etype; -+ u32 dmac_hi; -+ u16 vlan2; -+ u16 dmac_lo; -+ u32 smac_hi; -+ u16 pppoe_id; -+ u16 smac_lo; -+} __attribute__ ((packed)); -+ -+struct foe_entry { -+ union { -+ struct hnat_unbind_info_blk udib1; -+ struct hnat_bind_info_blk bfib1; -+ struct hnat_ipv4_hnapt ipv4_hnapt; -+ }; -+}; -+ -+#define HNAT_AC_BYTE_LO(x) (0x2000 + (x * 16)) -+#define HNAT_AC_BYTE_HI(x) (0x2004 + (x * 16)) -+#define HNAT_AC_PACKET(x) (0x2008 + (x * 16)) -+#define HNAT_COUNTER_MAX 64 -+#define HNAT_AC_TIMER_INTERVAL (HZ) -+ -+struct hnat_accounting { -+ u64 bytes; -+ u64 packets; -+}; -+ -+struct hnat_priv { -+ struct device *dev; -+ void __iomem *fe_base; -+ void __iomem *ppe_base; -+ struct foe_entry *foe_table_cpu; -+ dma_addr_t foe_table_dev; -+ u8 enable; -+ u8 enable1; -+ struct dentry *root; -+ struct debugfs_regset32 *regset; -+ -+ struct timer_list ac_timer; -+ struct hnat_accounting acct[HNAT_COUNTER_MAX]; -+ -+ /*devices we plays for*/ -+ char wan[IFNAMSIZ]; -+ -+ struct reset_control *rstc; -+}; -+ -+enum FoeEntryState { -+ INVALID = 0, -+ UNBIND = 1, -+ BIND = 2, -+ FIN = 3 -+}; -+/*--------------------------------------------------------------------------*/ -+/* Common Definition*/ -+/*--------------------------------------------------------------------------*/ -+ -+#define FOE_4TB_SIZ 4096 -+#define HASH_SEED_KEY 0x12345678 -+ -+/*PPE_TB_CFG value*/ -+#define ENTRY_80B 1 -+#define ENTRY_64B 0 -+#define TABLE_1K 0 -+#define TABLE_2K 1 -+#define TABLE_4K 2 -+#define TABLE_8K 3 -+#define TABLE_16K 4 -+#define SMA_DROP 0 /* Drop the packet */ -+#define SMA_DROP2 1 /* Drop the packet */ -+#define SMA_ONLY_FWD_CPU 2 /* Only Forward to CPU */ -+#define SMA_FWD_CPU_BUILD_ENTRY 3 /* Forward to CPU and build new FOE entry */ -+#define HASH_MODE_0 0 -+#define HASH_MODE_1 1 -+#define HASH_MODE_2 2 -+#define HASH_MODE_3 3 -+ -+/*PPE_FLOW_CFG*/ -+#define BIT_FUC_FOE BIT(2) -+#define BIT_FMC_FOE BIT(1) -+#define BIT_FBC_FOE BIT(0) -+#define BIT_IPV4_NAT_EN BIT(12) -+#define BIT_IPV4_NAPT_EN BIT(13) -+#define BIT_IPV4_NAT_FRAG_EN BIT(17) -+#define BIT_IPV4_HASH_GREK BIT(19) -+ -+/*GDMA1_FWD_CFG value */ -+#define BITS_GDM1_UFRC_P_PPE (NR_PPE_PORT << 12) -+#define BITS_GDM1_BFRC_P_PPE (NR_PPE_PORT << 8) -+#define BITS_GDM1_MFRC_P_PPE (NR_PPE_PORT << 4) -+#define BITS_GDM1_OFRC_P_PPE (NR_PPE_PORT << 0) -+#define BITS_GDM1_ALL_FRC_P_PPE (BITS_GDM1_UFRC_P_PPE | BITS_GDM1_BFRC_P_PPE | BITS_GDM1_MFRC_P_PPE | BITS_GDM1_OFRC_P_PPE) -+ -+#define BITS_GDM1_UFRC_P_CPU_PDMA (NR_PDMA_PORT << 12) -+#define BITS_GDM1_BFRC_P_CPU_PDMA (NR_PDMA_PORT << 8) -+#define BITS_GDM1_MFRC_P_CPU_PDMA (NR_PDMA_PORT << 4) -+#define BITS_GDM1_OFRC_P_CPU_PDMA (NR_PDMA_PORT << 0) -+#define BITS_GDM1_ALL_FRC_P_CPU_PDMA (BITS_GDM1_UFRC_P_CPU_PDMA | BITS_GDM1_BFRC_P_CPU_PDMA | BITS_GDM1_MFRC_P_CPU_PDMA | BITS_GDM1_OFRC_P_CPU_PDMA) -+ -+#define BITS_GDM1_UFRC_P_CPU_QDMA (NR_QDMA_PORT << 12) -+#define BITS_GDM1_BFRC_P_CPU_QDMA (NR_QDMA_PORT << 8) -+#define BITS_GDM1_MFRC_P_CPU_QDMA (NR_QDMA_PORT << 4) -+#define BITS_GDM1_OFRC_P_CPU_QDMA (NR_QDMA_PORT << 0) -+#define BITS_GDM1_ALL_FRC_P_CPU_QDMA (BITS_GDM1_UFRC_P_CPU_QDMA | BITS_GDM1_BFRC_P_CPU_QDMA | BITS_GDM1_MFRC_P_CPU_QDMA | BITS_GDM1_OFRC_P_CPU_QDMA) -+ -+#define BITS_GDM1_UFRC_P_DISCARD (NR_DISCARD << 12) -+#define BITS_GDM1_BFRC_P_DISCARD (NR_DISCARD << 8) -+#define BITS_GDM1_MFRC_P_DISCARD (NR_DISCARD << 4) -+#define BITS_GDM1_OFRC_P_DISCARD (NR_DISCARD << 0) -+#define BITS_GDM1_ALL_FRC_P_DISCARD (BITS_GDM1_UFRC_P_DISCARD | BITS_GDM1_BFRC_P_DISCARD | BITS_GDM1_MFRC_P_DISCARD | BITS_GDM1_OFRC_P_DISCARD) -+ -+#define BITS_GDM2_UFRC_P_PPE (NR_PPE_PORT << 12) -+#define BITS_GDM2_BFRC_P_PPE (NR_PPE_PORT << 8) -+#define BITS_GDM2_MFRC_P_PPE (NR_PPE_PORT << 4) -+#define BITS_GDM2_OFRC_P_PPE (NR_PPE_PORT << 0) -+#define BITS_GDM2_ALL_FRC_P_PPE (BITS_GDM2_UFRC_P_PPE | BITS_GDM2_BFRC_P_PPE | BITS_GDM2_MFRC_P_PPE | BITS_GDM2_OFRC_P_PPE) -+ -+#define BITS_GDM2_UFRC_P_CPU_PDMA (NR_PDMA_PORT << 12) -+#define BITS_GDM2_BFRC_P_CPU_PDMA (NR_PDMA_PORT << 8) -+#define BITS_GDM2_MFRC_P_CPU_PDMA (NR_PDMA_PORT << 4) -+#define BITS_GDM2_OFRC_P_CPU_PDMA (NR_PDMA_PORT << 0) -+#define BITS_GDM2_ALL_FRC_P_CPU_PDMA (BITS_GDM2_UFRC_P_CPU_PDMA | BITS_GDM2_BFRC_P_CPU_PDMA | BITS_GDM2_MFRC_P_CPU_PDMA | BITS_GDM2_OFRC_P_CPU_PDMA) -+ -+#define BITS_GDM2_UFRC_P_CPU_QDMA (NR_QDMA_PORT << 12) -+#define BITS_GDM2_BFRC_P_CPU_QDMA (NR_QDMA_PORT << 8) -+#define BITS_GDM2_MFRC_P_CPU_QDMA (NR_QDMA_PORT << 4) -+#define BITS_GDM2_OFRC_P_CPU_QDMA (NR_QDMA_PORT << 0) -+#define BITS_GDM2_ALL_FRC_P_CPU_QDMA (BITS_GDM2_UFRC_P_CPU_QDMA | BITS_GDM2_BFRC_P_CPU_QDMA | BITS_GDM2_MFRC_P_CPU_QDMA | BITS_GDM2_OFRC_P_CPU_QDMA) -+ -+#define BITS_GDM2_UFRC_P_DISCARD (NR_DISCARD << 12) -+#define BITS_GDM2_BFRC_P_DISCARD (NR_DISCARD << 8) -+#define BITS_GDM2_MFRC_P_DISCARD (NR_DISCARD << 4) -+#define BITS_GDM2_OFRC_P_DISCARD (NR_DISCARD << 0) -+#define BITS_GDM2_ALL_FRC_P_DISCARD (BITS_GDM2_UFRC_P_DISCARD | BITS_GDM2_BFRC_P_DISCARD | BITS_GDM2_MFRC_P_DISCARD | BITS_GDM2_OFRC_P_DISCARD) -+ -+#define hnat_is_enabled(host) (host->enable) -+#define hnat_enabled(host) (host->enable = 1) -+#define hnat_disabled(host) (host->enable = 0) -+#define hnat_is_enabled1(host) (host->enable1) -+#define hnat_enabled1(host) (host->enable1 = 1) -+#define hnat_disabled1(host) (host->enable1 = 0) -+ -+#define entry_hnat_is_bound(e) (e->bfib1.state == BIND) -+#define entry_hnat_state(e) (e->bfib1.state) -+ -+#define skb_hnat_is_hashed(skb) (skb_hnat_entry(skb)!=0x3fff && skb_hnat_entry(skb)< FOE_4TB_SIZ) -+#define FROM_GE_LAN(skb) (HNAT_SKB_CB(skb)->iif == FOE_MAGIC_GE_LAN) -+#define FROM_GE_WAN(skb) (HNAT_SKB_CB(skb)->iif == FOE_MAGIC_GE_WAN) -+#define FROM_GE_PPD(skb) (HNAT_SKB_CB(skb)->iif == FOE_MAGIC_GE_PPD) -+#define FOE_MAGIC_GE_WAN 0x7273 -+#define FOE_MAGIC_GE_LAN 0x7272 -+#define FOE_INVALID 0xffff -+ -+#define TCP_FIN_SYN_RST 0x0C /* Ingress packet is TCP fin/syn/rst (for IPv4 NAPT/DS-Lite or IPv6 5T-route/6RD) */ -+#define UN_HIT 0x0D/* FOE Un-hit */ -+#define HIT_UNBIND 0x0E/* FOE Hit unbind */ -+#define HIT_UNBIND_RATE_REACH 0xf -+#define HNAT_HIT_BIND_OLD_DUP_HDR 0x15 -+#define HNAT_HIT_BIND_FORCE_TO_CPU 0x16 -+ -+#define HIT_BIND_KEEPALIVE_MC_NEW_HDR 0x14 -+#define HIT_BIND_KEEPALIVE_DUP_OLD_HDR 0x15 -+#define IPV4_HNAPT 0 -+#define IPV4_HNAT 1 -+#define IP_FORMAT(addr) \ -+ ((unsigned char *)&addr)[3], \ -+ ((unsigned char *)&addr)[2], \ -+ ((unsigned char *)&addr)[1], \ -+ ((unsigned char *)&addr)[0] -+ -+/*PSE Ports*/ -+#define NR_PDMA_PORT 0 -+#define NR_GMAC1_PORT 1 -+#define NR_GMAC2_PORT 2 -+#define NR_PPE_PORT 4 -+#define NR_QDMA_PORT 5 -+#define NR_DISCARD 7 -+#define IS_LAN(dev) (!strncmp(dev->name, "lan", 3)) -+#define IS_WAN(dev) (!strcmp(dev->name, host->wan)) -+#define IS_BR(dev) (!strncmp(dev->name, "br", 2)) -+#define IS_IPV4_HNAPT(x) (((x)->bfib1.pkt_type == IPV4_HNAPT) ? 1: 0) -+#define IS_IPV4_HNAT(x) (((x)->bfib1.pkt_type == IPV4_HNAT) ? 1 : 0) -+#define IS_IPV4_GRP(x) (IS_IPV4_HNAPT(x) | IS_IPV4_HNAT(x)) -+ -+#define es(entry) (entry_state[entry->bfib1.state]) -+#define ei(entry, end) (FOE_4TB_SIZ - (int)(end - entry)) -+#define pt(entry) (packet_type[entry->ipv4_hnapt.bfib1.pkt_type]) -+#define ipv4_smac(mac,e) ({mac[0]=e->ipv4_hnapt.smac_hi[3]; mac[1]=e->ipv4_hnapt.smac_hi[2];\ -+ mac[2]=e->ipv4_hnapt.smac_hi[1]; mac[3]=e->ipv4_hnapt.smac_hi[0];\ -+ mac[4]=e->ipv4_hnapt.smac_lo[1]; mac[5]=e->ipv4_hnapt.smac_lo[0];}) -+#define ipv4_dmac(mac,e) ({mac[0]=e->ipv4_hnapt.dmac_hi[3]; mac[1]=e->ipv4_hnapt.dmac_hi[2];\ -+ mac[2]=e->ipv4_hnapt.dmac_hi[1]; mac[3]=e->ipv4_hnapt.dmac_hi[0];\ -+ mac[4]=e->ipv4_hnapt.dmac_lo[1]; mac[5]=e->ipv4_hnapt.dmac_lo[0];}) -+ -+extern struct hnat_priv *host; -+ -+extern void hnat_deinit_debugfs(struct hnat_priv *h); -+extern int hnat_init_debugfs(struct hnat_priv *h); -+//extern int hnat_register_nf_hooks(void); -+//extern void hnat_unregister_nf_hooks(void); -+extern int hnat_register_nf_hooks(struct net *net); -+extern void hnat_unregister_nf_hooks(struct net *net); -+ -diff --git a/drivers/net/ethernet/mediatek/mtk_hnat/hnat_debugfs.c b/drivers/net/ethernet/mediatek/mtk_hnat/hnat_debugfs.c -new file mode 100644 -index 0000000000000..fbb0380ea0d92 ---- /dev/null -+++ b/drivers/net/ethernet/mediatek/mtk_hnat/hnat_debugfs.c -@@ -0,0 +1,489 @@ -+/* This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; version 2 of the License -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * Copyright (C) 2014-2016 Sean Wang -+ * Copyright (C) 2016-2017 John Crispin -+ */ -+ -+#include -+#include -+#include -+ -+#include "hnat.h" -+ -+static const char *entry_state[] = { -+ "INVALID", -+ "UNBIND", -+ "BIND", -+ "FIN" -+}; -+ -+static const char *packet_type[] = { -+ "IPV4_HNAPT", -+ "IPV4_HNAT", -+ "IPV6_1T_ROUTE", -+ "IPV4_DSLITE", -+ "IPV6_3T_ROUTE", -+ "IPV6_5T_ROUTE", -+ "IPV6_6RD", -+}; -+ -+static int hnat_debug_show(struct seq_file *m, void *private) -+{ -+ struct hnat_priv *h = host; -+ struct foe_entry *entry, *end; -+ -+ entry = h->foe_table_cpu; -+ end = h->foe_table_cpu + FOE_4TB_SIZ; -+ while (entry < end) { -+ if (!entry->bfib1.state) { -+ entry++; -+ continue; -+ } -+ -+ if (IS_IPV4_HNAPT(entry)) { -+ __be32 saddr = htonl(entry->ipv4_hnapt.sip); -+ __be32 daddr = htonl(entry->ipv4_hnapt.dip); -+ __be32 nsaddr = htonl(entry->ipv4_hnapt.new_sip); -+ __be32 ndaddr = htonl(entry->ipv4_hnapt.new_dip); -+ unsigned char h_dest[ETH_ALEN]; -+ unsigned char h_source[ETH_ALEN]; -+ -+ *((u32*) h_source) = swab32(entry->ipv4_hnapt.smac_hi); -+ *((u16*) &h_source[4]) = swab16(entry->ipv4_hnapt.smac_lo); -+ *((u32*) h_dest) = swab32(entry->ipv4_hnapt.dmac_hi); -+ *((u16*) &h_dest[4]) = swab16(entry->ipv4_hnapt.dmac_lo); -+ seq_printf(m, -+ "(%p)0x%05x|state=%s|type=%s|%pI4:%d->%pI4:%d=>%pI4:%d->%pI4:%d|%pM=>%pM|etype=0x%04x|info1=0x%x|info2=0x%x|vlan1=%d|vlan2=%d\n", -+ (void *)h->foe_table_dev + ((void *)(entry) - (void *)h->foe_table_cpu), -+ ei(entry, end), es(entry), pt(entry), -+ &saddr, entry->ipv4_hnapt.sport, -+ &daddr, entry->ipv4_hnapt.dport, -+ &nsaddr, entry->ipv4_hnapt.new_sport, -+ &ndaddr, entry->ipv4_hnapt.new_dport, h_source, -+ h_dest, ntohs(entry->ipv4_hnapt.etype), -+ entry->ipv4_hnapt.info_blk1, -+ entry->ipv4_hnapt.info_blk2, -+ entry->ipv4_hnapt.vlan1, -+ entry->ipv4_hnapt.vlan2); -+ } else -+ seq_printf(m, "0x%05x state=%s\n", -+ ei(entry, end), es(entry)); -+ entry++; -+ } -+ -+ return 0; -+} -+ -+static int hnat_debug_open(struct inode *inode, struct file *file) -+{ -+ return single_open(file, hnat_debug_show, file->private_data); -+} -+ -+static const struct file_operations hnat_debug_fops = { -+ .open = hnat_debug_open, -+ .read = seq_read, -+ .llseek = seq_lseek, -+ .release = single_release, -+}; -+ -+#define QDMA_TX_SCH_TX 0x1a14 -+ -+static ssize_t hnat_sched_show(struct file *file, char __user *user_buf, -+ size_t count, loff_t *ppos) -+{ -+ int id = (int) file->private_data; -+ struct hnat_priv *h = host; -+ u32 reg = readl(h->fe_base + QDMA_TX_SCH_TX); -+ int enable; -+ int max_rate; -+ char *buf; -+ unsigned int len = 0, buf_len = 1500; -+ ssize_t ret_cnt; -+ -+ buf = kzalloc(buf_len, GFP_KERNEL); -+ if (!buf) -+ return -ENOMEM; -+ -+ -+ if (id) -+ reg >>= 16; -+ reg &= 0xffff; -+ enable = !! (reg & BIT(11)); -+ max_rate = ((reg >> 4) & 0x7f); -+ reg &= 0xf; -+ while (reg--) -+ max_rate *= 10; -+ -+ len += scnprintf(buf + len, buf_len - len, -+ "EN\tMAX\n%d\t%d\n", enable, max_rate); -+ -+ if (len > buf_len) -+ len = buf_len; -+ -+ ret_cnt = simple_read_from_buffer(user_buf, count, ppos, buf, len); -+ -+ kfree(buf); -+ return ret_cnt; -+} -+ -+static ssize_t hnat_sched_write(struct file *file, -+ const char __user *buf, size_t length, loff_t *offset) -+{ -+ int id = (int) file->private_data; -+ struct hnat_priv *h = host; -+ char line[64]; -+ int enable, rate, exp = 0, shift = 0; -+ size_t size; -+ u32 reg = readl(h->fe_base + QDMA_TX_SCH_TX); -+ u32 val = 0; -+ -+ if (length > sizeof(line)) -+ return -EINVAL; -+ -+ if (copy_from_user(line, buf, length)) -+ return -EFAULT; -+ -+ sscanf(line, "%d %d", &enable, &rate); -+ -+ while (rate > 127) { -+ rate /= 10; -+ exp++; -+ } -+ -+ if (enable) -+ val |= BIT(11); -+ val |= (rate & 0x7f) << 4; -+ val |= exp & 0xf; -+ if (id) -+ shift = 16; -+ reg &= ~(0xffff << shift); -+ reg |= val << shift; -+ writel(reg, h->fe_base + QDMA_TX_SCH_TX); -+ -+ size = strlen(line); -+ *offset += size; -+ -+ return length; -+} -+ -+static const struct file_operations hnat_sched_fops = { -+ .open = simple_open, -+ .read = hnat_sched_show, -+ .write = hnat_sched_write, -+ .llseek = default_llseek, -+}; -+ -+#define QTX_CFG(x) (0x1800 + (x * 0x10)) -+#define QTX_SCH(x) (0x1804 + (x * 0x10)) -+ -+static ssize_t hnat_queue_show(struct file *file, char __user *user_buf, -+ size_t count, loff_t *ppos) -+{ -+ struct hnat_priv *h = host; -+ int id = (int) file->private_data; -+ u32 reg = readl(h->fe_base + QTX_SCH(id)); -+ u32 cfg = readl(h->fe_base + QTX_CFG(id)); -+ int scheduler = !!(reg & BIT(31)); -+ int min_rate_en = !!(reg & BIT(27)); -+ int min_rate = (reg >> 20) & 0x7f; -+ int min_rate_exp = (reg >> 16) & 0xf; -+ int max_rate_en = !!(reg & BIT(11)); -+ int max_weight = (reg >> 12) & 0xf; -+ int max_rate = (reg >> 4) & 0x7f; -+ int max_rate_exp = reg & 0xf; -+ char *buf; -+ unsigned int len = 0, buf_len = 1500; -+ ssize_t ret_cnt; -+ -+ buf = kzalloc(buf_len, GFP_KERNEL); -+ if (!buf) -+ return -ENOMEM; -+ -+ while (min_rate_exp--) -+ min_rate *= 10; -+ -+ while (max_rate_exp--) -+ max_rate *= 10; -+ -+ len += scnprintf(buf + len, buf_len - len, -+ "scheduler: %d\nhw resv: %d\nsw resv: %d\n", -+ scheduler, (cfg >> 8) & 0xff, cfg & 0xff); -+ len += scnprintf(buf + len, buf_len - len, -+ "\tEN\tRATE\t\tWEIGHT\n"); -+ len += scnprintf(buf + len, buf_len - len, -+ "max\t%d\t%8d\t%d\n", max_rate_en, max_rate, max_weight); -+ len += scnprintf(buf + len, buf_len - len, -+ "min\t%d\t%8d\t-\n", min_rate_en, min_rate); -+ -+ if (len > buf_len) -+ len = buf_len; -+ -+ ret_cnt = simple_read_from_buffer(user_buf, count, ppos, buf, len); -+ -+ kfree(buf); -+ return ret_cnt; -+} -+ -+static ssize_t hnat_queue_write(struct file *file, -+ const char __user *buf, size_t length, loff_t *offset) -+{ -+ int id = (int) file->private_data; -+ struct hnat_priv *h = host; -+ char line[64]; -+ int max_enable, max_rate, max_exp = 0; -+ int min_enable, min_rate, min_exp = 0; -+ int weight; -+ int resv; -+ int scheduler; -+ size_t size; -+ u32 reg = readl(h->fe_base + QTX_SCH(id)); -+ -+ if (length > sizeof(line)) -+ return -EINVAL; -+ -+ if (copy_from_user(line, buf, length)) -+ return -EFAULT; -+ -+ sscanf(line, "%d %d %d %d %d %d %d", &scheduler, &min_enable, &min_rate, &max_enable, &max_rate, &weight, &resv); -+ -+ while (max_rate > 127) { -+ max_rate /= 10; -+ max_exp++; -+ } -+ -+ while (min_rate > 127) { -+ min_rate /= 10; -+ min_exp++; -+ } -+ -+ reg &= 0x70000000; -+ if (scheduler) -+ reg |= BIT(31); -+ if (min_enable) -+ reg |= BIT(27); -+ reg |= (min_rate & 0x7f) << 20; -+ reg |= (min_exp & 0xf) << 16; -+ if (max_enable) -+ reg |= BIT(11); -+ reg |= (weight & 0xf) << 12; -+ reg |= (max_rate & 0x7f) << 4; -+ reg |= max_exp & 0xf; -+ writel(reg, h->fe_base + QTX_SCH(id)); -+ -+ resv &= 0xff; -+ reg = readl(h->fe_base + QTX_CFG(id)); -+ reg &= 0xffff0000; -+ reg |= (resv << 8) | resv; -+ writel(reg, h->fe_base + QTX_CFG(id)); -+ -+ size = strlen(line); -+ *offset += size; -+ -+ return length; -+} -+ -+static const struct file_operations hnat_queue_fops = { -+ .open = simple_open, -+ .read = hnat_queue_show, -+ .write = hnat_queue_write, -+ .llseek = default_llseek, -+}; -+ -+static void hnat_ac_timer_handle(unsigned long priv) -+{ -+ struct hnat_priv *h = (struct hnat_priv*) priv; -+ int i; -+ -+ for (i = 0; i < HNAT_COUNTER_MAX; i++) { -+ u32 b_hi, b_lo; -+ u64 b; -+ -+ b_lo = readl(h->fe_base + HNAT_AC_BYTE_LO(i)); -+ b_hi = readl(h->fe_base + HNAT_AC_BYTE_HI(i)); -+ b = b_hi; -+ b <<= 32; -+ b += b_lo; -+ h->acct[i].bytes += b; -+ h->acct[i].packets += readl(h->fe_base + HNAT_AC_PACKET(i)); -+ } -+ -+ mod_timer(&h->ac_timer, jiffies + HNAT_AC_TIMER_INTERVAL); -+} -+ -+static ssize_t hnat_counter_show(struct file *file, char __user *user_buf, -+ size_t count, loff_t *ppos) -+{ -+ struct hnat_priv *h = host; -+ int id = (int) file->private_data; -+ char *buf; -+ unsigned int len = 0, buf_len = 1500; -+ ssize_t ret_cnt; -+ int id2 = id + (HNAT_COUNTER_MAX / 2); -+ -+ buf = kzalloc(buf_len, GFP_KERNEL); -+ if (!buf) -+ return -ENOMEM; -+ -+ len += scnprintf(buf + len, buf_len - len, -+ "tx pkts : %llu\ntx bytes: %llu\nrx pktks : %llu\nrx bytes : %llu\n", -+ h->acct[id].packets, h->acct[id].bytes, -+ h->acct[id2].packets, h->acct[id2].bytes); -+ -+ if (len > buf_len) -+ len = buf_len; -+ -+ ret_cnt = simple_read_from_buffer(user_buf, count, ppos, buf, len); -+ -+ kfree(buf); -+ return ret_cnt; -+} -+ -+static const struct file_operations hnat_counter_fops = { -+ .open = simple_open, -+ .read = hnat_counter_show, -+ .llseek = default_llseek, -+}; -+ -+#define dump_register(nm) \ -+{ \ -+ .name = __stringify(nm), \ -+ .offset = PPE_ ##nm , \ -+} -+ -+static const struct debugfs_reg32 hnat_regs[] = { -+ dump_register(GLO_CFG), -+ dump_register(FLOW_CFG), -+ dump_register(IP_PROT_CHK), -+ dump_register(IP_PROT_0), -+ dump_register(IP_PROT_1), -+ dump_register(IP_PROT_2), -+ dump_register(IP_PROT_3), -+ dump_register(TB_CFG), -+ dump_register(TB_BASE), -+ dump_register(TB_USED), -+ dump_register(BNDR), -+ dump_register(BIND_LMT_0), -+ dump_register(BIND_LMT_1), -+ dump_register(KA), -+ dump_register(UNB_AGE), -+ dump_register(BND_AGE_0), -+ dump_register(BND_AGE_1), -+ dump_register(HASH_SEED), -+ dump_register(DFT_CPORT), -+ dump_register(MCAST_PPSE), -+ dump_register(MCAST_L_0), -+ dump_register(MCAST_H_0), -+ dump_register(MCAST_L_1), -+ dump_register(MCAST_H_1), -+ dump_register(MCAST_L_2), -+ dump_register(MCAST_H_2), -+ dump_register(MCAST_L_3), -+ dump_register(MCAST_H_3), -+ dump_register(MCAST_L_4), -+ dump_register(MCAST_H_4), -+ dump_register(MCAST_L_5), -+ dump_register(MCAST_H_5), -+ dump_register(MCAST_L_6), -+ dump_register(MCAST_H_6), -+ dump_register(MCAST_L_7), -+ dump_register(MCAST_H_7), -+ dump_register(MCAST_L_8), -+ dump_register(MCAST_H_8), -+ dump_register(MCAST_L_9), -+ dump_register(MCAST_H_9), -+ dump_register(MCAST_L_A), -+ dump_register(MCAST_H_A), -+ dump_register(MCAST_L_B), -+ dump_register(MCAST_H_B), -+ dump_register(MCAST_L_C), -+ dump_register(MCAST_H_C), -+ dump_register(MCAST_L_D), -+ dump_register(MCAST_H_D), -+ dump_register(MCAST_L_E), -+ dump_register(MCAST_H_E), -+ dump_register(MCAST_L_F), -+ dump_register(MCAST_H_F), -+ dump_register(MTU_DRP), -+ dump_register(MTU_VLYR_0), -+ dump_register(MTU_VLYR_1), -+ dump_register(MTU_VLYR_2), -+ dump_register(VPM_TPID), -+ dump_register(VPM_TPID), -+ dump_register(CAH_CTRL), -+ dump_register(CAH_TAG_SRH), -+ dump_register(CAH_LINE_RW), -+ dump_register(CAH_WDATA), -+ dump_register(CAH_RDATA), -+}; -+ -+int hnat_init_debugfs(struct hnat_priv *h) -+{ -+ int ret = 0; -+ struct dentry *root; -+ struct dentry *file; -+ int i; -+ char name[16]; -+ -+ root = debugfs_create_dir("hnat", NULL); -+ if (!root) { -+ dev_err(h->dev, "%s:err at %d\n", __func__, __LINE__); -+ ret = -ENOMEM; -+ goto err0; -+ } -+ h->root = root; -+ h->regset = kzalloc(sizeof(*h->regset), GFP_KERNEL); -+ if (!h->regset) { -+ dev_err(h->dev, "%s:err at %d\n", __func__, __LINE__); -+ ret = -ENOMEM; -+ goto err1; -+ } -+ h->regset->regs = hnat_regs; -+ h->regset->nregs = ARRAY_SIZE(hnat_regs); -+ h->regset->base = h->ppe_base; -+ -+ file = debugfs_create_regset32("regdump", S_IRUGO, root, h->regset); -+ if (!file) { -+ dev_err(h->dev, "%s:err at %d\n", __func__, __LINE__); -+ ret = -ENOMEM; -+ goto err1; -+ } -+ debugfs_create_file("all_entry", S_IRUGO, root, h, &hnat_debug_fops); -+ for (i = 0; i < HNAT_COUNTER_MAX / 2; i++) { -+ snprintf(name, sizeof(name), "counter%d", i); -+ debugfs_create_file(name, S_IRUGO, root, (void *)i, &hnat_counter_fops); -+ } -+ -+ for (i = 0; i < 2; i++) { -+ snprintf(name, sizeof(name), "scheduler%d", i); -+ debugfs_create_file(name, S_IRUGO, root, (void *)i, &hnat_sched_fops); -+ } -+ -+ for (i = 0; i < 16; i++) { -+ snprintf(name, sizeof(name), "queue%d", i); -+ debugfs_create_file(name, S_IRUGO, root, (void *)i, &hnat_queue_fops); -+ } -+ -+ setup_timer(&h->ac_timer, hnat_ac_timer_handle, (unsigned long) h); -+ mod_timer(&h->ac_timer, jiffies + HNAT_AC_TIMER_INTERVAL); -+ -+ return 0; -+ -+ err1: -+ debugfs_remove_recursive(root); -+ err0: -+ return ret; -+} -+ -+void hnat_deinit_debugfs(struct hnat_priv *h) -+{ -+ del_timer(&h->ac_timer); -+ debugfs_remove_recursive(h->root); -+ h->root = NULL; -+} -diff --git a/drivers/net/ethernet/mediatek/mtk_hnat/hnat_nf_hook.c b/drivers/net/ethernet/mediatek/mtk_hnat/hnat_nf_hook.c -new file mode 100644 -index 0000000000000..0ce436ac00e61 ---- /dev/null -+++ b/drivers/net/ethernet/mediatek/mtk_hnat/hnat_nf_hook.c -@@ -0,0 +1,312 @@ -+/* This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; version 2 of the License -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * Copyright (C) 2014-2016 Sean Wang -+ * Copyright (C) 2016-2017 John Crispin -+ */ -+ -+#include -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include "nf_hnat_mtk.h" -+#include "hnat.h" -+ -+#include "../mtk_eth_soc.h" -+ -+static unsigned int skb_to_hnat_info(struct sk_buff *skb, -+ const struct net_device *dev, -+ struct foe_entry *foe) -+{ -+ struct foe_entry entry = { 0 }; -+ int lan = IS_LAN(dev); -+ int wan = IS_WAN(dev); -+ struct ethhdr *eth; -+ struct iphdr *iph; -+ struct tcphdr *tcph; -+ struct udphdr *udph; -+ int tcp = 0; -+ int ipv4 = 0; -+ u32 gmac; -+ -+ eth = eth_hdr(skb); -+ switch (ntohs(eth->h_proto)) { -+ case ETH_P_IP: -+ ipv4 = 1; -+ break; -+ -+ default: -+ return -1; -+ } -+ -+ iph = ip_hdr(skb); -+ switch (iph->protocol) { -+ case IPPROTO_TCP: -+ tcph = tcp_hdr(skb); -+ tcp = 1; -+ break; -+ -+ case IPPROTO_UDP: -+ udph = udp_hdr(skb); -+ break; -+ -+ default: -+ return -1; -+ } -+ -+ entry.ipv4_hnapt.etype = htons(ETH_P_IP); -+ -+ if (lan) { -+ entry.ipv4_hnapt.etype = htons(ETH_P_8021Q); -+ entry.bfib1.vlan_layer = 1; -+ -+ /* lan0-port1, lan1-port2, lan2-port3, lan3-port4 */ -+ entry.ipv4_hnapt.vlan1 = BIT((dev->name[3] - '0')+1); -+ } else if (wan) { -+ entry.ipv4_hnapt.etype = htons(ETH_P_8021Q); -+ entry.bfib1.vlan_layer = 1; -+ -+ /* wan port 0 */ -+ entry.ipv4_hnapt.vlan1 = BIT(0); -+ } -+ -+ if (dev->priv_flags & IFF_802_1Q_VLAN) { -+ struct vlan_dev_priv *vlan = vlan_dev_priv(dev); -+ -+ entry.ipv4_hnapt.etype = htons(ETH_P_8021Q); -+ entry.bfib1.vlan_layer = 1; -+ entry.ipv4_hnapt.vlan2 = vlan->vlan_id; -+ } -+ -+ entry.ipv4_hnapt.dmac_hi = swab32(*((u32*) eth->h_dest)); -+ entry.ipv4_hnapt.dmac_lo = swab16(*((u16*) ð->h_dest[4])); -+ entry.ipv4_hnapt.smac_hi = swab32(*((u32*) eth->h_source)); -+ entry.ipv4_hnapt.smac_lo = swab16(*((u16*) ð->h_source[4])); -+ entry.ipv4_hnapt.pppoe_id = 0; -+ entry.bfib1.psn = 0; -+ entry.ipv4_hnapt.bfib1.vpm = 1; -+ -+ if (ipv4) -+ entry.ipv4_hnapt.bfib1.pkt_type = IPV4_HNAPT; -+ -+ entry.ipv4_hnapt.new_sip = ntohl(iph->saddr); -+ entry.ipv4_hnapt.new_dip = ntohl(iph->daddr); -+ entry.ipv4_hnapt.iblk2.dscp = iph->tos; -+#if defined(CONFIG_NET_MEDIATEK_HW_QOS) -+ entry.ipv4_hnapt.iblk2.qid = skb->mark & 0x7; -+ if (lan) -+ entry.ipv4_hnapt.iblk2.qid += 8; -+ entry.ipv4_hnapt.iblk2.fqos = 1; -+#endif -+ if (tcp) { -+ entry.ipv4_hnapt.new_sport = ntohs(tcph->source); -+ entry.ipv4_hnapt.new_dport = ntohs(tcph->dest); -+ entry.ipv4_hnapt.bfib1.udp = 0; -+ } else { -+ entry.ipv4_hnapt.new_sport = ntohs(udph->source); -+ entry.ipv4_hnapt.new_dport = ntohs(udph->dest); -+ entry.ipv4_hnapt.bfib1.udp = 1; -+ } -+ -+ if (IS_LAN(dev)) -+ gmac = NR_GMAC1_PORT; -+ else if (IS_WAN(dev)) -+ gmac = NR_GMAC2_PORT; -+ -+ if (is_multicast_ether_addr(ð->h_dest[0])) -+ entry.ipv4_hnapt.iblk2.mcast = 1; -+ else -+ entry.ipv4_hnapt.iblk2.mcast = 0; -+ -+ entry.ipv4_hnapt.iblk2.dp = gmac; -+ entry.ipv4_hnapt.iblk2.port_mg = 0x3f; -+ entry.ipv4_hnapt.iblk2.port_ag = (skb->mark >> 3) & 0x1f; -+ if (IS_LAN(dev)) -+ entry.ipv4_hnapt.iblk2.port_ag += 32; -+ entry.bfib1.time_stamp = readl((host->fe_base + 0x0010)) & (0xFFFF); -+ entry.ipv4_hnapt.bfib1.ttl = 1; -+ entry.ipv4_hnapt.bfib1.cah = 1; -+ entry.ipv4_hnapt.bfib1.ka = 1; -+ entry.bfib1.state = BIND; -+ -+ entry.ipv4_hnapt.sip = foe->ipv4_hnapt.sip; -+ entry.ipv4_hnapt.dip = foe->ipv4_hnapt.dip; -+ entry.ipv4_hnapt.sport = foe->ipv4_hnapt.sport; -+ entry.ipv4_hnapt.dport = foe->ipv4_hnapt.dport; -+ -+ memcpy(foe, &entry, sizeof(entry)); -+ -+ return 0; -+} -+ -+static unsigned int mtk_hnat_nf_post_routing(struct sk_buff *skb, -+ const struct net_device *out, -+ unsigned int (*fn)(struct sk_buff *, const struct net_device *), -+ const char *func) -+{ -+ struct foe_entry *entry; -+ struct nf_conn *ct; -+ enum ip_conntrack_info ctinfo; -+ const struct nf_conn_help *help; -+ -+#if 0 -+ if ((skb->mark & 0x7) < 4) -+ return 0; -+#endif -+ -+ ct = nf_ct_get(skb, &ctinfo); -+ if (!ct) -+ return 0; -+ -+ /* rcu_read_lock()ed by nf_hook_slow */ -+ help = nfct_help(ct); -+ if (help && rcu_dereference(help->helper)) -+ return 0; -+ -+ if ((FROM_GE_WAN(skb) || FROM_GE_LAN(skb)) && -+ skb_hnat_is_hashed(skb) && -+ (skb_hnat_reason(skb) == HIT_BIND_KEEPALIVE_DUP_OLD_HDR)) -+ return -1; -+ -+ if ((IS_LAN(out) && FROM_GE_WAN(skb)) || -+ (IS_WAN(out) && FROM_GE_LAN(skb))) { -+ if (!skb_hnat_is_hashed(skb)) -+ return 0; -+ -+ entry = &host->foe_table_cpu[skb_hnat_entry(skb)]; -+ if (entry_hnat_is_bound(entry)) -+ return 0; -+ -+ if (skb_hnat_reason(skb) == HIT_UNBIND_RATE_REACH && -+ skb_hnat_alg(skb) == 0) { -+ if (fn && fn(skb, out)) -+ return 0; -+ skb_to_hnat_info(skb, out, entry); -+ } -+ } -+ -+ return 0; -+} -+ -+static unsigned int mtk_hnat_nf_pre_routing(void *priv, -+ struct sk_buff *skb, -+ const struct nf_hook_state *state) -+{ -+ if (IS_WAN(state->in)) -+ HNAT_SKB_CB(skb)->iif = FOE_MAGIC_GE_WAN; -+ else if (IS_LAN(state->in)) -+ HNAT_SKB_CB(skb)->iif = FOE_MAGIC_GE_LAN; -+ else if (!IS_BR(state->in)) -+ HNAT_SKB_CB(skb)->iif = FOE_INVALID; -+ -+ return NF_ACCEPT; -+} -+ -+static unsigned int hnat_get_nexthop(struct sk_buff *skb, const struct net_device *out) { -+ -+ u32 nexthop; -+ struct neighbour *neigh; -+ struct dst_entry *dst = skb_dst(skb); -+ struct rtable *rt = (struct rtable *)dst; -+ struct net_device *dev = (__force struct net_device *)out; -+ -+ rcu_read_lock_bh(); -+ nexthop = (__force u32) rt_nexthop(rt, ip_hdr(skb)->daddr); -+ neigh = __ipv4_neigh_lookup_noref(dev, nexthop); -+ if (unlikely(!neigh)) { -+ dev_err(host->dev, "%s:++ no neigh\n", __func__); -+ return -1; -+ } -+ -+ /* why do we get all zero ethernet address ? */ -+ if (!is_valid_ether_addr(neigh->ha)){ -+ rcu_read_unlock_bh(); -+ return -1; -+ } -+ -+ memcpy(eth_hdr(skb)->h_dest, neigh->ha, ETH_ALEN); -+ memcpy(eth_hdr(skb)->h_source, out->dev_addr, ETH_ALEN); -+ -+ rcu_read_unlock_bh(); -+ -+ return 0; -+} -+ -+static unsigned int mtk_hnat_ipv4_nf_post_routing(void *priv, -+ struct sk_buff *skb, -+ const struct nf_hook_state *state) -+{ -+ if (!mtk_hnat_nf_post_routing(skb, state->out, hnat_get_nexthop, __func__)) -+ return NF_ACCEPT; -+ -+ return NF_DROP; -+} -+ -+static unsigned int mtk_hnat_br_nf_post_routing(void *priv, -+ struct sk_buff *skb, -+ const struct nf_hook_state *state) -+{ -+ if (!mtk_hnat_nf_post_routing(skb, state->out , 0, __func__)) -+ return NF_ACCEPT; -+ -+ return NF_DROP; -+} -+ -+static struct nf_hook_ops mtk_hnat_nf_ops[] __read_mostly = { -+ { -+ .hook = mtk_hnat_nf_pre_routing, -+ .pf = NFPROTO_IPV4, -+ .hooknum = NF_INET_PRE_ROUTING, -+ .priority = NF_IP_PRI_FIRST, -+ }, { -+ .hook = mtk_hnat_ipv4_nf_post_routing, -+ .pf = NFPROTO_IPV4, -+ .hooknum = NF_INET_POST_ROUTING, -+ .priority = NF_IP_PRI_LAST, -+ }, { -+ .hook = mtk_hnat_nf_pre_routing, -+ .pf = NFPROTO_BRIDGE, -+ .hooknum = NF_BR_PRE_ROUTING, -+ .priority = NF_BR_PRI_FIRST, -+ }, { -+ .hook = mtk_hnat_br_nf_post_routing, -+ .pf = NFPROTO_BRIDGE, -+ .hooknum = NF_BR_POST_ROUTING, -+ .priority = NF_BR_PRI_LAST - 1, -+ }, -+}; -+ -+/* -+int hnat_register_nf_hooks(void) -+{ -+ return nf_register_hooks(mtk_hnat_nf_ops, -+ ARRAY_SIZE(mtk_hnat_nf_ops)); -+} -+ -+void hnat_unregister_nf_hooks(void) -+{ -+ nf_unregister_hooks(mtk_hnat_nf_ops, -+ ARRAY_SIZE(mtk_hnat_nf_ops)); -+} -+*/ -+int hnat_register_nf_hooks(struct net *net) -+{ -+ return nf_register_net_hooks(net,mtk_hnat_nf_ops, -+ ARRAY_SIZE(mtk_hnat_nf_ops)); -+} -+ -+void hnat_unregister_nf_hooks(struct net *net) -+{ -+ nf_unregister_net_hooks(net,mtk_hnat_nf_ops, -+ ARRAY_SIZE(mtk_hnat_nf_ops)); -+} -diff --git a/drivers/net/ethernet/mediatek/mtk_hnat/nf_hnat_mtk.h b/drivers/net/ethernet/mediatek/mtk_hnat/nf_hnat_mtk.h -new file mode 100644 -index 0000000000000..e19812840a840 ---- /dev/null -+++ b/drivers/net/ethernet/mediatek/mtk_hnat/nf_hnat_mtk.h -@@ -0,0 +1,44 @@ -+/* This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; version 2 of the License -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * Copyright (C) 2014-2016 Sean Wang -+ * Copyright (C) 2016-2017 John Crispin -+ */ -+ -+#ifndef NF_HNAT_MTK_H -+#define NF_HNAT_MTK_H -+ -+#include -+#include -+ -+#define HNAT_SKB_CB2(__skb) ((struct hnat_skb_cb2 *)&((__skb)->cb[44])) -+struct hnat_skb_cb2 { -+ __u32 magic; -+}; -+ -+struct hnat_desc { -+ u32 entry:14; -+ u32 crsn:5; -+ u32 sport:4; -+ u32 alg:9; -+} __attribute__ ((packed)); -+ -+#define skb_hnat_magic(skb) (((struct hnat_desc *)(skb->head))->magic) -+#define skb_hnat_reason(skb) (((struct hnat_desc *)(skb->head))->crsn) -+#define skb_hnat_entry(skb) (((struct hnat_desc *)(skb->head))->entry) -+#define skb_hnat_sport(skb) (((struct hnat_desc *)(skb->head))->sport) -+#define skb_hnat_alg(skb) (((struct hnat_desc *)(skb->head))->alg) -+ -+u32 hnat_tx(struct sk_buff *skb); -+u32 hnat_set_skb_info(struct sk_buff *skb, u32 *rxd); -+u32 hnat_reg(struct net_device *, void __iomem *); -+u32 hnat_unreg(void); -+ -+#endif -+ -diff --git a/net/netfilter/nf_conntrack_proto_tcp.c b/net/netfilter/nf_conntrack_proto_tcp.c -index 8febdd48b9f16..9bcc787f8abf3 100644 ---- a/net/netfilter/nf_conntrack_proto_tcp.c -+++ b/net/netfilter/nf_conntrack_proto_tcp.c -@@ -11,6 +11,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -20,6 +21,7 @@ - #include - #include - -+#include - #include - - #include -@@ -51,6 +53,11 @@ static int nf_ct_tcp_max_retrans __read_mostly = 3; - /* FIXME: Examine ipfilter's timeouts and conntrack transitions more - closely. They're more complex. --RR */ - -+#ifndef IPV4_DEVCONF_DFLT -+ #define IPV4_DEVCONF_DFLT(net, attr) \ -+ IPV4_DEVCONF((*net->ipv4.devconf_dflt), attr) -+#endif -+ - static const char *const tcp_conntrack_names[] = { - "NONE", - "SYN_SENT", -@@ -506,6 +513,18 @@ static bool tcp_in_window(const struct nf_conn *ct, - s32 receiver_offset; - bool res, in_recv_win; - -+ if (net) { -+ if ((net->ipv4.devconf_all && net->ipv4.devconf_dflt && net->ipv6.devconf_all) && -+ net->ipv6.devconf_dflt) { -+ if ((IPV4_DEVCONF_DFLT(net, FORWARDING) || -+ IPV4_DEVCONF_ALL(net, FORWARDING)) || -+ (net->ipv6.devconf_all->forwarding || -+ net->ipv6.devconf_dflt->forwarding)) { -+ return true; -+ } -+ } -+ } -+ - /* - * Get the required data from the packet. - */ diff --git a/root/target/linux/mediatek/patches-4.19/0001-adding-defconfig-and-build-script-change-gitignore-m.patch b/root/target/linux/mediatek/patches-4.19/0001-adding-defconfig-and-build-script-change-gitignore-m.patch deleted file mode 100644 index 467141c7..00000000 --- a/root/target/linux/mediatek/patches-4.19/0001-adding-defconfig-and-build-script-change-gitignore-m.patch +++ /dev/null @@ -1,747 +0,0 @@ -From 8196b5b6d823fb8c61268121052826db7fb6ce3c Mon Sep 17 00:00:00 2001 -From: Frank Wunderlich -Date: Mon, 22 Oct 2018 19:06:10 +0200 -Subject: [PATCH 01/77] adding defconfig and build-script, change gitignore, - making kernel compatible with r2-images - ---- - arch/arm/boot/dts/mt7623.dtsi | 42 +- - arch/arm/configs/mt7623n_evb_fwu_defconfig | 651 +++++++++++++++++++++ - 4 files changed, 1200 insertions(+), 22 deletions(-) - create mode 100644 arch/arm/configs/mt7623n_evb_fwu_defconfig - -diff --git a/arch/arm/boot/dts/mt7623.dtsi b/arch/arm/boot/dts/mt7623.dtsi -index 1cdc346a05e8..04228cf9ddbb 100644 ---- a/arch/arm/boot/dts/mt7623.dtsi -+++ b/arch/arm/boot/dts/mt7623.dtsi -@@ -354,6 +354,17 @@ - #io-channel-cells = <1>; - }; - -+ uart2: serial@11004000 { -+ compatible = "mediatek,mt7623-uart", -+ "mediatek,mt6577-uart"; -+ reg = <0 0x11004000 0 0x400>; -+ interrupts = ; -+ clocks = <&pericfg CLK_PERI_UART2_SEL>, -+ <&pericfg CLK_PERI_UART2>; -+ clock-names = "baud", "bus"; -+ status = "disabled"; -+ }; -+ - uart0: serial@11002000 { - compatible = "mediatek,mt7623-uart", - "mediatek,mt6577-uart"; -@@ -376,17 +387,6 @@ - status = "disabled"; - }; - -- uart2: serial@11004000 { -- compatible = "mediatek,mt7623-uart", -- "mediatek,mt6577-uart"; -- reg = <0 0x11004000 0 0x400>; -- interrupts = ; -- clocks = <&pericfg CLK_PERI_UART2_SEL>, -- <&pericfg CLK_PERI_UART2>; -- clock-names = "baud", "bus"; -- status = "disabled"; -- }; -- - uart3: serial@11005000 { - compatible = "mediatek,mt7623-uart", - "mediatek,mt6577-uart"; -@@ -661,24 +661,24 @@ - }; - }; - -- mmc0: mmc@11230000 { -+ mmc1: mmc@11240000 { - compatible = "mediatek,mt7623-mmc", - "mediatek,mt2701-mmc"; -- reg = <0 0x11230000 0 0x1000>; -- interrupts = ; -- clocks = <&pericfg CLK_PERI_MSDC30_0>, -- <&topckgen CLK_TOP_MSDC30_0_SEL>; -+ reg = <0 0x11240000 0 0x1000>; -+ interrupts = ; -+ clocks = <&pericfg CLK_PERI_MSDC30_1>, -+ <&topckgen CLK_TOP_MSDC30_1_SEL>; - clock-names = "source", "hclk"; - status = "disabled"; - }; - -- mmc1: mmc@11240000 { -+ mmc0: mmc@11230000 { - compatible = "mediatek,mt7623-mmc", - "mediatek,mt2701-mmc"; -- reg = <0 0x11240000 0 0x1000>; -- interrupts = ; -- clocks = <&pericfg CLK_PERI_MSDC30_1>, -- <&topckgen CLK_TOP_MSDC30_1_SEL>; -+ reg = <0 0x11230000 0 0x1000>; -+ interrupts = ; -+ clocks = <&pericfg CLK_PERI_MSDC30_0>, -+ <&topckgen CLK_TOP_MSDC30_0_SEL>; - clock-names = "source", "hclk"; - status = "disabled"; - }; -diff --git a/arch/arm/configs/mt7623n_evb_fwu_defconfig b/arch/arm/configs/mt7623n_evb_fwu_defconfig -new file mode 100644 -index 000000000000..09df75013c09 ---- /dev/null -+++ b/arch/arm/configs/mt7623n_evb_fwu_defconfig -@@ -0,0 +1,651 @@ -+CONFIG_LOCALVERSION="-bpi-r2" -+CONFIG_LOCALVERSION_AUTO=n -+ -+#spectre/meltdown -+CONFIG_PAGE_TABLE_ISOLATION=y -+ -+CONFIG_SYSVIPC=y -+CONFIG_IRQ_DOMAIN_DEBUG=y -+CONFIG_NO_HZ=y -+CONFIG_HIGH_RES_TIMERS=y -+CONFIG_CGROUPS=y -+CONFIG_NAMESPACES=y -+ -+#for lxc -+CONFIG_USER_NS=y -+CONFIG_MEMCG=y -+CONFIG_CGROUP_CPUACCT=y -+CONFIG_CGROUP_DEVICE=y -+CONFIG_CGROUP_SCHED=y -+CONFIG_CPUSETS=y -+#some options for docker -+CONFIG_CGROUP_FREEZER=y -+CONFIG_POSIX_MQUEUE=y -+CONFIG_OVERLAY_FS=y -+CONFIG_MEMCG_SWAP=y -+CONFIG_MEMCG_SWAP_ENABLED=y -+CONFIG_BLK_CGROUP=y -+CONFIG_CFS_BANDWIDTH=y -+CONFIG_RT_GROUP_SCHED=y -+CONFIG_CGROUP_PIDS=y -+CONFIG_CGROUP_PERF=y -+CONFIG_CGROUP_NET_CLASSID=y -+CONFIG_CGROUP_NET_PRIO=y -+CONFIG_CFQ_GROUP_IOSCHED=y -+ -+CONFIG_BLK_DEV_INITRD=y -+CONFIG_KALLSYMS_ALL=y -+CONFIG_EMBEDDED=y -+CONFIG_PERF_EVENTS=y -+CONFIG_MODULES=y -+CONFIG_MODULE_FORCE_LOAD=y -+CONFIG_MODULE_UNLOAD=y -+CONFIG_PARTITION_ADVANCED=y -+CONFIG_CMDLINE_PARTITION=y -+CONFIG_ARCH_MEDIATEK=y -+CONFIG_ARM_THUMB=y -+CONFIG_ARM_THUMBEE=y -+CONFIG_ARM_ERRATA_720789=y -+CONFIG_ARM_ERRATA_754322=y -+CONFIG_ARM_ERRATA_754327=y -+CONFIG_ARM_ERRATA_764369=y -+CONFIG_ARM_ERRATA_775420=y -+CONFIG_ARM_ERRATA_798181=y -+ -+CONFIG_PL310_ERRATA_588369=y -+CONFIG_PL310_ERRATA_727915=y -+CONFIG_PL310_ERRATA_753970=y -+CONFIG_PL310_ERRATA_769419=y -+ -+CONFIG_PCI=y -+CONFIG_SMP=y -+CONFIG_HAVE_ARM_ARCH_TIMER=y -+CONFIG_NR_CPUS=16 -+CONFIG_AEABI=y -+CONFIG_HIGHMEM=y -+CONFIG_CMA=y -+CONFIG_FORCE_MAX_ZONEORDER=12 -+CONFIG_ARM_APPENDED_DTB=y -+CONFIG_ARM_ATAG_DTB_COMPAT=y -+CONFIG_CMDLINE="earlyprintk console=ttyS0,115200 vmalloc=496M debug=7 no_console_suspend" -+#CONFIG_CMDLINE_FORCE=y -+ -+CONFIG_IKCONFIG=m -+CONFIG_IKCONFIG_PROC=y -+ -+CONFIG_KEXEC=y -+ -+CONFIG_CPU_FREQ=y -+CONFIG_CPU_FREQ_STAT=y -+CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y -+CONFIG_CPU_FREQ_GOV_PERFORMANCE=y -+CONFIG_CPU_FREQ_GOV_POWERSAVE=y -+CONFIG_CPU_FREQ_GOV_ONDEMAND=y -+CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y -+CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y -+CONFIG_ARM_MEDIATEK_CPUFREQ=y -+ -+CONFIG_VFP=y -+CONFIG_NEON=y -+CONFIG_KERNEL_MODE_NEON=y -+CONFIG_PM_AUTOSLEEP=y -+CONFIG_PM_DEBUG=y -+CONFIG_PM_ADVANCED_DEBUG=y -+CONFIG_APM_EMULATION=y -+ -+CONFIG_NET=y -+CONFIG_DUMMY=m -+CONFIG_PACKET=y -+CONFIG_UNIX=y -+CONFIG_INET=y -+CONFIG_IP_PNP=y -+CONFIG_IP_PNP_DHCP=y -+CONFIG_IP_PNP_BOOTP=y -+CONFIG_IP_PNP_RARP=y -+CONFIG_IPV6_ROUTER_PREF=y -+CONFIG_IPV6_OPTIMISTIC_DAD=y -+CONFIG_INET6_AH=m -+CONFIG_INET6_ESP=m -+CONFIG_INET6_IPCOMP=m -+CONFIG_IPV6_MIP6=m -+CONFIG_IPV6_TUNNEL=m -+CONFIG_IPV6_MULTIPLE_TABLES=y -+CONFIG_BRIDGE=y -+CONFIG_NET_DSA=y -+CONFIG_VLAN_8021Q=y -+CONFIG_NETLINK_DIAG=y -+CONFIG_INET_UDP_DIAG=m -+CONFIG_NET_IPIP=m -+CONFIG_IP_MULTICAST=y -+CONFIG_IP_MROUTE=y -+CONFIG_IP_PIMSM_V1=y -+CONFIG_IP_PIMSM_V2=y -+ -+#added for lxc -+CONFIG_UNIX_DIAG=m -+CONFIG_PACKET_DIAG=m -+ -+ -+CONFIG_IPV6=m -+CONFIG_NETFILTER=y -+CONFIG_NF_CONNTRACK=m -+CONFIG_NF_CONNTRACK_IPV4=m -+CONFIG_NF_CONNTRACK_IPV6=m -+CONFIG_NETFILTER_NETLINK=m -+CONFIG_NF_CT_NETLINK=m -+CONFIG_IP_NF_IPTABLES=m -+CONFIG_NF_LOG_IPV4=m -+CONFIG_NF_REJECT_IPV4=m -+CONFIG_IP6_NF_IPTABLES=m -+CONFIG_NF_LOG_IPV6=m -+CONFIG_NF_REJECT_IPV6=m -+CONFIG_IP_NF_NAT=m -+CONFIG_IP6_NF_NAT=m -+CONFIG_NF_NAT_MASQUERADE_IPV4=m -+CONFIG_NF_NAT_MASQUERADE_IPV6=m -+CONFIG_IP_NF_FILTER=m -+CONFIG_IP6_NF_FILTER=m -+CONFIG_IP_NF_TARGET_MASQUERADE=m -+CONFIG_IP6_NF_TARGET_MASQUERADE=m -+CONFIG_IP_NF_MANGLE=m -+CONFIG_IP6_NF_MANGLE=m -+CONFIG_IP_NF_TARGET_REJECT=m -+CONFIG_IP6_NF_TARGET_REJECT=m -+CONFIG_IP6_NF_MATCH_RT=m -+ -+CONFIG_NETFILTER_SYNPROXY=m -+CONFIG_IP_NF_TARGET_SYNPROXY=m -+CONFIG_IP6_NF_TARGET_SYNPROXY=m -+ -+CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m -+CONFIG_NETFILTER_XT_MATCH_LIMIT=m -+CONFIG_NETFILTER_XT_MATCH_STATE=m -+CONFIG_NETFILTER_XT_TARGET_LOG=m -+CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m -+CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m -+CONFIG_NETFILTER_XT_MATCH_MAC=m -+CONFIG_NETFILTER_XT_MATCH_RECENT=m -+CONFIG_NETFILTER_XT_MATCH_IPRANGE=m -+CONFIG_NETFILTER_XT_MARK=m -+CONFIG_NETFILTER_XT_CONNMARK=m -+CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m -+CONFIG_IP_VS=m -+CONFIG_NETFILTER_XT_MATCH_IPVS=m -+CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m -+ -+CONFIG_NET_MEDIATEK_HNAT=m -+CONFIG_DEBUG_SECTION_MISMATCH=y -+ -+#active ftp-support -+CONFIG_NF_CONNTRACK_FTP=m -+CONFIG_NF_NAT_FTP=m -+ -+ -+CONFIG_SYN_COOKIES=y -+ -+CONFIG_PPP=m -+CONFIG_PPPOE=m -+CONFIG_PPP_FILTER=y -+CONFIG_PPP_DEFLATE=m -+CONFIG_PPP_MPPE=m -+ -+#veth for lxc -+CONFIG_VETH=m -+ -+#for systemd -+CONFIG_AF_KCM=y -+CONFIG_CGROUP_BPF=y -+ -+CONFIG_DEVTMPFS=y -+CONFIG_DEVTMPFS_MOUNT=y -+CONFIG_DMA_CMA=y -+CONFIG_CMA_SIZE_MBYTES=64 -+CONFIG_ARM_CCI400_PMU=y -+CONFIG_MTD=y -+CONFIG_OF_OVERLAY=y -+CONFIG_CONFIGFS_FS=m -+CONFIG_BLK_DEV_LOOP=y -+CONFIG_SRAM=y -+CONFIG_EEPROM_93CX6=y -+CONFIG_IDE=y -+CONFIG_BLK_DEV_SD=y -+CONFIG_ATA=y -+CONFIG_SATA_AHCI=y -+CONFIG_AHCI_MTK=m -+ -+CONFIG_NETDEVICES=y -+CONFIG_NET_DSA_MT7530=y -+CONFIG_NET_VENDOR_MEDIATEK=y -+CONFIG_NET_MEDIATEK_SOC=y -+ -+CONFIG_ICPLUS_PHY=y -+CONFIG_INPUT_EVDEV=y -+CONFIG_INPUT_EVBUG=m -+CONFIG_KEYBOARD_MATRIX=y -+CONFIG_KEYBOARD_SAMSUNG=y -+CONFIG_KEYBOARD_MTK_PMIC=m -+CONFIG_MOUSE_PS2_ELANTECH=y -+CONFIG_MOUSE_PS2_SENTELIC=y -+CONFIG_INPUT_MOUSEDEV=y -+CONFIG_INPUT_MOUSEDEV_PSAUX=y -+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 -+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 -+CONFIG_INPUT_TOUCHSCREEN=y -+# CONFIG_SERIO_SERPORT is not set -+CONFIG_VT_HW_CONSOLE_BINDING=y -+CONFIG_SERIAL_8250=y -+CONFIG_SERIAL_8250_CONSOLE=y -+CONFIG_SERIAL_8250_NR_UARTS=4 -+CONFIG_SERIAL_8250_RUNTIME_UARTS=4 -+CONFIG_SERIAL_8250_MT6577=y -+CONFIG_SERIAL_8250_BTIF=y -+CONFIG_HW_RANDOM=y -+CONFIG_I2C=y -+CONFIG_I2C_MT65XX=y -+CONFIG_PINCTRL_MT2701=y -+# CONFIG_PINCTRL_MT6397 is not set -+# CONFIG_HWMON is not set -+CONFIG_WATCHDOG=y -+CONFIG_MEDIATEK_WATCHDOG=y -+CONFIG_MFD_MT6397=y -+CONFIG_REGULATOR=y -+CONFIG_REGULATOR_MT6323=y -+CONFIG_REGULATOR_FIXED_VOLTAGE=y -+CONFIG_MEDIA_SUPPORT=y -+CONFIG_MEDIA_RC_SUPPORT=y -+CONFIG_RC_DEVICES=y -+CONFIG_IR_MTK=y -+CONFIG_MMC=y -+CONFIG_MMC_MTK=y -+CONFIG_NEW_LEDS=y -+CONFIG_LEDS_CLASS=y -+CONFIG_LEDS_MT6323=y -+CONFIG_LEDS_GPIO=y -+CONFIG_LEDS_PCA963X=y -+CONFIG_LEDS_TRIGGERS=y -+CONFIG_LEDS_TRIGGER_TIMER=y -+CONFIG_LEDS_TRIGGER_ONESHOT=y -+CONFIG_LEDS_TRIGGER_HEARTBEAT=y -+CONFIG_LEDS_TRIGGER_DEFAULT_ON=y -+CONFIG_DMADEVICES=y -+CONFIG_DMATEST=m -+CONFIG_COMMON_CLK_MT2701_HIFSYS=y -+CONFIG_COMMON_CLK_MT2701_ETHSYS=y -+CONFIG_ARM_TIMER_SP804=y -+CONFIG_MTK_IOMMU_V1=y -+CONFIG_MTK_PMIC_WRAP=y -+CONFIG_IIO=y -+CONFIG_RESET_CONTROLLER=y -+CONFIG_PHY_MT65XX_USB3=y -+CONFIG_PSTORE=y -+CONFIG_PSTORE_CONSOLE=y -+CONFIG_PSTORE_PMSG=y -+CONFIG_PSTORE_FTRACE=y -+CONFIG_PSTORE_RAM=y -+CONFIG_PRINTK_TIME=y -+CONFIG_DYNAMIC_DEBUG=y -+CONFIG_DEBUG_INFO=y -+CONFIG_MAGIC_SYSRQ=y -+CONFIG_DETECT_HUNG_TASK=y -+CONFIG_DEBUG_LIST=y -+CONFIG_FUNCTION_TRACER=y -+CONFIG_FTRACE_SYSCALLS=y -+CONFIG_FUNCTION_PROFILER=y -+CONFIG_DEBUG_LL=y -+CONFIG_DEBUG_UART_PHYS=0x11002000 -+CONFIG_DEBUG_UART_VIRT=0xf1002000 -+CONFIG_KEYS=y -+CONFIG_CRYPTO_RSA=y -+CONFIG_CRYPTO_CCM=m -+CONFIG_CRYPTO_GCM=m -+CONFIG_CRYPTO_ECB=m -+CONFIG_CRYPTO_CMAC=m -+CONFIG_CRYPTO_ARC4=m -+CONFIG_CRYPTO_DEFLATE=y -+CONFIG_CRYPTO_LZO=y -+CONFIG_CRC_CCITT=m -+CONFIG_CRC_ITU_T=m -+CONFIG_CRYPTO_DEV_MEDIATEK=y -+ -+#ARM Accelerated Cryptographic Algorithms -+CONFIG_ARM_CRYPTO=y -+CONFIG_CRYPTO_SHA1_ARM=m -+CONFIG_CRYPTO_SHA1_ARM_NEON=m -+CONFIG_CRYPTO_SHA1_ARM_CE=m -+CONFIG_CRYPTO_SHA2_ARM_CE=m -+CONFIG_CRYPTO_SHA512_ARM=m -+CONFIG_CRYPTO_AES_ARM=m -+CONFIG_CRYPTO_AES_ARM_BS=m -+CONFIG_CRYPTO_AES_ARM_CE=m -+CONFIG_CRYPTO_GHASH_ARM_CE=m -+CONFIG_CRYPTO_CRC32_ARM_CE=m -+CONFIG_CRYPTO_CHACHA20_NEON=m -+ -+#LVM -+CONFIG_MD=y -+CONFIG_BLK_DEV_DM=y -+CONFIG_DM_BUFIO=y -+CONFIG_DM_CRYPT=y -+CONFIG_DM_SNAPSHOT=y -+CONFIG_DM_MIRROR=y -+CONFIG_DM_MULTIPATH=y -+CONFIG_DM_MULTIPATH_QL=y -+CONFIG_DM_MULTIPATH_ST=y -+CONFIG_DM_THIN_PROVISIONING=m -+CONFIG_DAX=y -+CONFIG_CRYPTO_CBC=y -+ -+#RAID -+CONFIG_DM_RAID=y -+CONFIG_MD_RAID0=y -+CONFIG_MD_RAID1=y -+CONFIG_MD_RAID10=y -+CONFIG_MD_RAID456=y -+ -+#RamFS -+#CONFIG_INITRAMFS_SOURCE="../rootfs_ttys0_rng.cpio.gz" -+#CONFIG_INITRAMFS_SOURCE="../initramfs.cpio" -+#CONFIG_INITRAMFS_FORCE=y -+ -+#Filesystem -+CONFIG_EXT4_FS=y -+CONFIG_EXT4_FS_POSIX_ACL=y -+CONFIG_EXT4_FS_SECURITY=y -+CONFIG_AUTOFS4_FS=y -+CONFIG_FUSE_FS=m -+CONFIG_MSDOS_FS=m -+CONFIG_VFAT_FS=y -+CONFIG_NTFS_FS=m -+CONFIG_TMPFS=y -+CONFIG_TMPFS_POSIX_ACL=y -+CONFIG_NLS_CODEPAGE_437=y -+CONFIG_NLS_ISO8859_1=y -+CONFIG_NLS_UTF8=y -+CONFIG_CIFS=m -+CONFIG_F2FS_FS=m -+CONFIG_BTRFS_FS=m -+ -+#GPIO -+CONFIG_DEBUG_FS=y -+CONFIG_DEBUG_GPIO=y -+CONFIG_GPIO_SYSFS=y -+ -+#wlan -+CONFIG_MAC80211=y -+CONFIG_CFG80211=y -+ -+#internal wlan (not working yet) -+# CONFIG_MTK_CONN_LTE_IDC_SUPPORT is not set -+#CONFIG_MTK_COMBO=y -+#CONFIG_MTK_COMBO_CHIP_CONSYS_7623=y -+#used in 4.4, but should be set in Kconfig by selecting mt7623 COMBO -+#CONFIG_MTK_PLATFORM="mt7623" -+ -+#CONFIG_MTK_COMBO_COMM=y -+#CONFIG_MTK_COMBO_WIFI=y -+#CONFIG_NL80211_TESTMODE=y -+ -+#internal Bluetooth (also not working yet) -+#CONFIG_BT=y -+#CONFIG_MTK_COMBO_BT=y -+#CONFIG_MTK_COMBO_BT_HCI=y -+#needed for BT? -+#Bluetooth Classic (BR/EDR) features -+CONFIG_BT_BREDR=y -+#Bluetooth High Speed (HS) features -+CONFIG_BT_HS=y -+#Bluetooth Low Energy (LE) features -+CONFIG_BT_LE=y -+#Export Bluetooth internals in debugfs -+CONFIG_BT_DEBUGFS=y -+CONFIG_BT_RFCOMM=m -+CONFIG_BT_RFCOMM_TTY=y -+CONFIG_BT_HIDP=m -+CONFIG_BT_BNEP=m -+ -+#to run bluetoothd rfkill needed -+CONFIG_RFKILL=y -+CONFIG_RFKILL_LEDS=y -+CONFIG_RFKILL_INPUT=y -+CONFIG_RFKILL_GPIO=y -+ -+#if you use a mt76x2 or mt76x3 pcie-card -+#CONFIG_MT76=m -+ -+#pcie -+CONFIG_PCIEPORTBUS=y -+CONFIG_PCIE_MEDIATEK=y -+CONFIG_PHY_MTK_TPHY=y -+ -+CONFIG_I2C_CHARDEV=m -+CONFIG_RTC_CLASS=y -+CONFIG_RTC_DRV_DS1307=m -+CONFIG_RTC_DRV_DS1307_CENTURY=y -+CONFIG_RTC_DRV_MT6397=m -+ -+CONFIG_SPI=y -+CONFIG_SPI_MASTER=y -+CONFIG_SPI_SPIDEV=m -+CONFIG_SPI_MT65XX=m -+ -+CONFIG_PWM=y -+CONFIG_PWM_MEDIATEK=m -+ -+#Temperature sensor driver for mediatek SoCs -+CONFIG_MEDIATEK_MT6577_AUXADC=m -+CONFIG_THERMAL=m -+CONFIG_MTK_THERMAL=m -+CONFIG_MTK_EFUSE=m -+ -+#HDMI -+#CONFIG_DRM=y -+#CONFIG_DRM_ARM=y -+#CONFIG_DRM_MALI_DISPLAY=y -+#CONFIG_DRM_MEDIATEK=y -+#CONFIG_DRM_MEDIATEK_HDMI=y -+#CONFIG_COMMON_CLK_MT2701_MMSYS=y -+#CONFIG_COMMON_CLK_MT2701_IMGSYS=y -+#CONFIG_COMMON_CLK_MT2701_VDECSYS=y -+#CONFIG_FRAMEBUFFER_CONSOLE=y -+#CONFIG_DRM_FBDEV_EMULATION=y -+ -+#Sound -+CONFIG_SOUND=y -+CONFIG_SND=y #alsa core -+CONFIG_SND_SOC=y -+ -+#CONFIG_SOUND_OSS_CORE=y -+#CONFIG_SOUND_OSS_CORE_PRECLAIM=y -+#CONFIG_SND_OSSEMUL=y -+#CONFIG_SND_MIXER_OSS=m -+#CONFIG_SND_PCM_OSS=m #alsa The PCM OSS emulation module. -+ -+#USB/HID -+CONFIG_USB=y -+CONFIG_USB_XHCI_HCD=y -+CONFIG_USB_XHCI_MTK=y -+CONFIG_USB_STORAGE=y -+CONFIG_USB_SERIAL=y -+#CONFIG_NOP_USB_XCEIV=y -+#CONFIG_USB_GPIO_VBUS=y -+#CONFIG_USB_GADGET=y -+#CONFIG_USB_CONFIGFS=y -+CONFIG_USB_CONFIGFS_SERIAL=y -+#CONFIG_USB_CONFIGFS_ACM=y -+#CONFIG_USB_CONFIGFS_OBEX=y -+#CONFIG_USB_CONFIGFS_NCM=y -+#CONFIG_USB_CONFIGFS_ECM=y -+#CONFIG_USB_CONFIGFS_ECM_SUBSET=y -+#CONFIG_USB_CONFIGFS_RNDIS=y -+#CONFIG_USB_CONFIGFS_EEM=y -+CONFIG_USB_CONFIGFS_MASS_STORAGE=y -+ -+CONFIG_HID=y -+CONFIG_HIDRAW=y -+#CONFIG_UHID=m -+CONFIG_HID_GENERIC=y -+ -+CONFIG_USB_HID=y -+#CONFIG_HID_PID=y -+CONFIG_USB_HIDDEV=y -+ -+# CONFIG_USB_OHCI_LITTLE_ENDIAN=y ? -+CONFIG_USB_SUPPORT=y -+CONFIG_USB_COMMON=y -+# CONFIG_USB_ARCH_HAS_HCD=y ? -+ -+#additional NET (e.g. tunneling incl. openvpn,vlan-base-support) -+CONFIG_TUN=m -+#vlan -+CONFIG_BRIDGE_VLAN_FILTERING=y -+CONFIG_VLAN_8021Q_GVRP=y -+CONFIG_VLAN_8021Q_MVRP=y -+CONFIG_NET_L3_MASTER_DEV=y -+CONFIG_IPVLAN=m -+CONFIG_MACVLAN=m -+CONFIG_NET_ACT_VLAN=m -+CONFIG_NET_CLS_ACT=y -+ -+# QoS and/or fair queueing -+CONFIG_NET_SCHED=y -+CONFIG_NET_SCH_CBQ=m -+CONFIG_NET_SCH_HTB=m -+CONFIG_NET_SCH_CSZ=m -+CONFIG_NET_SCH_PRIO=m -+CONFIG_NET_SCH_RED=m -+CONFIG_NET_SCH_SFQ=m -+CONFIG_NET_SCH_TEQL=m -+CONFIG_NET_SCH_TBF=m -+CONFIG_NET_SCH_GRED=m -+CONFIG_NET_SCH_DSMARK=m -+CONFIG_NET_SCH_INGRESS=m -+CONFIG_NET_SCH_NETEM=m -+CONFIG_NET_QOS=y -+CONFIG_NET_ESTIMATOR=y -+CONFIG_NET_CLS=y -+CONFIG_NET_CLS_TCINDEX=m -+CONFIG_NET_CLS_ROUTE4=m -+CONFIG_NET_CLS_ROUTE=y -+CONFIG_NET_CLS_FW=m -+CONFIG_NET_CLS_U32=m -+CONFIG_NET_CLS_RSVP=m -+CONFIG_NET_CLS_RSVP6=m -+CONFIG_NET_CLS_POLICE=y -+ -+#unused drivers which are set by default -+CONFIG_WLAN_VENDOR_ADMTEK=n -+CONFIG_WLAN_VENDOR_ATH=n -+CONFIG_WLAN_VENDOR_ATMEL=n -+CONFIG_WLAN_VENDOR_BROADCOM=n -+CONFIG_WLAN_VENDOR_CISCO=n -+CONFIG_WLAN_VENDOR_INTEL=n -+CONFIG_WLAN_VENDOR_INTERSIL=n -+CONFIG_WLAN_VENDOR_MARVELL=n -+CONFIG_WLAN_VENDOR_REALTEK=n -+CONFIG_WLAN_VENDOR_RALINK=n -+CONFIG_WLAN_VENDOR_RSI=n -+CONFIG_WLAN_VENDOR_ST=n -+CONFIG_WLAN_VENDOR_TI=n -+CONFIG_WLAN_VENDOR_ZYDAS=n -+CONFIG_WLAN_VENDOR_QUANTENNA=n -+# CONFIG_ADAPTEC_STARFIRE is not set -+# CONFIG_NET_VENDOR_ADAPTEC is not set -+# CONFIG_NET_VENDOR_AGERE is not set -+# CONFIG_NET_VENDOR_ALACRITECH is not set -+# CONFIG_NET_VENDOR_ALTEON is not set -+# CONFIG_NET_VENDOR_AMAZON is not set -+# CONFIG_NET_VENDOR_AMD is not set -+# CONFIG_NET_VENDOR_AQUANTIA is not set -+# CONFIG_NET_VENDOR_ARC is not set -+# CONFIG_NET_VENDOR_ATHEROS is not set -+# CONFIG_NET_VENDOR_AURORA is not set -+# CONFIG_NET_CADENCE is not set -+# CONFIG_NET_VENDOR_BROADCOM is not set -+# CONFIG_NET_VENDOR_BROCADE is not set -+# CONFIG_NET_VENDOR_CAVIUM is not set -+# CONFIG_NET_VENDOR_CHELSIO is not set -+# CONFIG_NET_VENDOR_CIRRUS is not set -+# CONFIG_NET_VENDOR_CISCO is not set -+# CONFIG_NET_VENDOR_MELLANOX is not set -+# CONFIG_NET_VENDOR_MICREL is not set -+# CONFIG_NET_VENDOR_MICROCHIP is not set -+# CONFIG_NET_VENDOR_MYRI is not set -+# CONFIG_NET_VENDOR_NATSEMI is not set -+# CONFIG_NET_VENDOR_NETRONOME is not set -+# CONFIG_NET_VENDOR_NVIDIA is not set -+# CONFIG_NET_VENDOR_OKI is not set -+# CONFIG_NET_PACKET_ENGINE is not set -+# CONFIG_NET_VENDOR_QLOGIC is not set -+# CONFIG_NET_VENDOR_QUALCOMM is not set -+# CONFIG_NET_VENDOR_REALTEK is not set -+# CONFIG_NET_VENDOR_RENESAS is not set -+# CONFIG_NET_VENDOR_RDC is not set -+# CONFIG_NET_VENDOR_ROCKER is not set -+# CONFIG_NET_VENDOR_SAMSUNG is not set -+# CONFIG_NET_VENDOR_SEEQ is not set -+# CONFIG_NET_VENDOR_SILAN is not set -+# CONFIG_NET_VENDOR_SIS is not set -+# CONFIG_NET_VENDOR_SOLARFLARE is not set -+# CONFIG_NET_VENDOR_SMSC is not set -+# CONFIG_NET_VENDOR_STMICRO is not set -+# CONFIG_NET_VENDOR_SUN is not set -+# CONFIG_NET_VENDOR_TEHUTI is not set -+# CONFIG_NET_VENDOR_TI is not set -+# CONFIG_NET_VENDOR_VIA is not set -+# CONFIG_NET_VENDOR_WIZNET is not set -+# CONFIG_NET_VENDOR_SYNOPSYS is not set -+# CONFIG_NET_VENDOR_DEC is not set -+# CONFIG_NET_VENDOR_DLINK is not set -+# CONFIG_NET_VENDOR_EMULEX is not set -+# CONFIG_NET_VENDOR_EZCHIP is not set -+# CONFIG_NET_VENDOR_EXAR is not set -+# CONFIG_NET_VENDOR_FARADAY is not set -+# CONFIG_NET_VENDOR_HISILICON is not set -+# CONFIG_NET_VENDOR_HP is not set -+# CONFIG_NET_VENDOR_HUAWEI is not set -+# CONFIG_NET_VENDOR_INTEL is not set -+# CONFIG_NET_VENDOR_MARVELL is not set -+# CONFIG_NET_VENDOR_3COM is not set -+ -+#NFS Client -+CONFIG_NFS_FS=y -+CONFIG_NFS_V2=y -+CONFIG_NFS_V3=y -+CONFIG_NFS_V3_ACL=y -+CONFIG_NFS_V4=y -+CONFIG_NFS_SWAP=y -+CONFIG_NFS_V4_1=y -+CONFIG_NFS_V4_2=y -+CONFIG_PNFS_FILE_LAYOUT=m -+CONFIG_PNFS_BLOCK=m -+CONFIG_PNFS_FLEXFILE_LAYOUT=m -+CONFIG_NFS_V4_1_IMPLEMENTATION_ID_DOMAIN="kernel.org" -+CONFIG_NFS_V4_1_MIGRATION=y -+CONFIG_NFS_USE_LEGACY_DNS=y -+ -+#NFS Server -+CONFIG_NFSD=m -+CONFIG_NFSD_V2_ACL=y -+CONFIG_NFSD_V3=y -+CONFIG_NFSD_V3_ACL=y -+CONFIG_NFSD_V4=y -+CONFIG_NFSD_PNFS=y -+CONFIG_NFSD_BLOCKLAYOUT=y -+CONFIG_NFSD_SCSILAYOUT=y -+CONFIG_NFSD_FLEXFILELAYOUT=y -+CONFIG_NFSD_FAULT_INJECTION=y -+CONFIG_NFS_ACL_SUPPORT=m -+CONFIG_NFS_COMMON=y -+ -+CONFIG_ROOT_NFS=y -+ -+#xfs -+CONFIG_XFS_FS=m -+ -+#RTC/POWER -+CONFIG_POWER_RESET=y -+CONFIG_POWER_RESET_MT6323=y -+CONFIG_POWER_RESET_MT6397_RTC=y -+ -+#CONFIG_NET_MEDIATEK_HW_QOS=m -+ --- -2.19.1 - diff --git a/root/target/linux/mediatek/patches-4.19/0006-wifi-adding-driver-folder.patch b/root/target/linux/mediatek/patches-4.19/0006-wifi-adding-driver-folder.patch deleted file mode 100644 index a9380314..00000000 --- a/root/target/linux/mediatek/patches-4.19/0006-wifi-adding-driver-folder.patch +++ /dev/null @@ -1,216265 +0,0 @@ -From ce8c582c6121469db64197b1b4aa4e4c377c660f Mon Sep 17 00:00:00 2001 -From: Frank Wunderlich -Date: Tue, 23 Oct 2018 13:12:12 +0200 -Subject: [PATCH 06/77] [wifi] adding driver-folder - ---- - drivers/misc/Kconfig | 1 + - drivers/misc/Makefile | 1 + - drivers/misc/mediatek/Kconfig | 11 + - drivers/misc/mediatek/Makefile | 19 + - drivers/misc/mediatek/btif/Kconfig | 4 + - drivers/misc/mediatek/btif/Makefile | 33 + - drivers/misc/mediatek/btif/common/Makefile | 31 + - .../misc/mediatek/btif/common/btif_dma_plat.c | 1436 ++ - drivers/misc/mediatek/btif/common/btif_plat.c | 1396 ++ - .../misc/mediatek/btif/common/inc/mtk_btif.h | 370 + - .../mediatek/btif/common/inc/mtk_btif_exp.h | 280 + - drivers/misc/mediatek/btif/common/mtk_btif.c | 3472 +++++ - .../misc/mediatek/btif/common/mtk_btif_exp.c | 786 ++ - .../btif/common/plat_inc/btif_dma_priv.h | 164 + - .../btif/common/plat_inc/btif_dma_pub.h | 197 + - .../mediatek/btif/common/plat_inc/btif_priv.h | 105 + - .../mediatek/btif/common/plat_inc/btif_pub.h | 237 + - .../btif/common/plat_inc/plat_common.h | 307 + - drivers/misc/mediatek/connectivity/Kconfig | 299 + - drivers/misc/mediatek/connectivity/Makefile | 41 + - .../mediatek/connectivity/common/Makefile | 23 + - .../common/common_detect/Makefile | 47 + - .../common/common_detect/drv_init/Makefile | 22 + - .../common_detect/drv_init/ant_drv_init.c | 38 + - .../drv_init/bluetooth_drv_init.c | 35 + - .../common_detect/drv_init/common_drv_init.c | 103 + - .../common_detect/drv_init/conn_drv_init.c | 80 + - .../common_detect/drv_init/fm_drv_init.c | 33 + - .../common_detect/drv_init/gps_drv_init.c | 35 + - .../common_detect/drv_init/inc/ant_drv_init.h | 20 + - .../drv_init/inc/bluetooth_drv_init.h | 20 + - .../drv_init/inc/common_drv_init.h | 31 + - .../drv_init/inc/conn_drv_init.h | 18 + - .../common_detect/drv_init/inc/fm_drv_init.h | 20 + - .../common_detect/drv_init/inc/gps_drv_init.h | 19 + - .../drv_init/inc/wlan_drv_init.h | 30 + - .../common_detect/drv_init/wlan_drv_init.c | 74 + - .../common/common_detect/mtk_wcn_stub_alps.c | 605 + - .../common/common_detect/sdio_detect.c | 269 + - .../common/common_detect/sdio_detect.h | 43 + - .../common/common_detect/wmt_detect.c | 380 + - .../common/common_detect/wmt_detect.h | 114 + - .../common/common_detect/wmt_detect_pwr.c | 232 + - .../common/common_detect/wmt_detect_pwr.h | 29 + - .../common/common_detect/wmt_gpio.c | 371 + - .../common/common_detect/wmt_gpio.h | 103 + - .../common/common_detect/wmt_stp_exp.c | 480 + - .../common/common_detect/wmt_stp_exp.h | 610 + - .../connectivity/common/conn_soc/Makefile | 65 + - .../common/conn_soc/core/Makefile | 22 + - .../common/conn_soc/core/btm_core.c | 1376 ++ - .../common/conn_soc/core/dbg_core.c | 13 + - .../common/conn_soc/core/include/btm_core.h | 133 + - .../common/conn_soc/core/include/dbg_core.h | 69 + - .../common/conn_soc/core/include/psm_core.h | 251 + - .../common/conn_soc/core/include/stp_core.h | 629 + - .../common/conn_soc/core/include/stp_wmt.h | 89 + - .../common/conn_soc/core/include/wmt_conf.h | 74 + - .../common/conn_soc/core/include/wmt_core.h | 428 + - .../common/conn_soc/core/include/wmt_ctrl.h | 120 + - .../common/conn_soc/core/include/wmt_func.h | 140 + - .../common/conn_soc/core/include/wmt_ic.h | 122 + - .../common/conn_soc/core/include/wmt_lib.h | 300 + - .../common/conn_soc/core/psm_core.c | 1890 +++ - .../common/conn_soc/core/stp_core.c | 3358 +++++ - .../common/conn_soc/core/wmt_conf.c | 529 + - .../common/conn_soc/core/wmt_core.c | 2521 ++++ - .../common/conn_soc/core/wmt_ctrl.c | 1019 ++ - .../common/conn_soc/core/wmt_func.c | 713 + - .../common/conn_soc/core/wmt_ic_soc.c | 2452 ++++ - .../common/conn_soc/core/wmt_lib.c | 1938 +++ - .../common/conn_soc/include/stp_exp.h | 252 + - .../common/conn_soc/include/wmt.h | 19 + - .../common/conn_soc/include/wmt_exp.h | 329 + - .../common/conn_soc/include/wmt_plat.h | 295 + - .../common/conn_soc/linux/Makefile | 6 + - .../conn_soc/linux/include/bgw_desense.h | 74 + - .../common/conn_soc/linux/include/osal.h | 349 + - .../conn_soc/linux/include/osal_typedef.h | 90 + - .../common/conn_soc/linux/include/wmt_idc.h | 97 + - .../common/conn_soc/linux/pri/Makefile | 21 + - .../conn_soc/linux/pri/include/stp_btif.h | 31 + - .../conn_soc/linux/pri/include/stp_dbg.h | 316 + - .../conn_soc/linux/pri/include/wmt_dev.h | 71 + - .../common/conn_soc/linux/pri/stp_btif.c | 279 + - .../common/conn_soc/linux/pri/stp_dbg.c | 2061 +++ - .../common/conn_soc/linux/pri/stp_exp.c | 279 + - .../common/conn_soc/linux/pri/wmt_dev.c | 2566 ++++ - .../common/conn_soc/linux/pri/wmt_exp.c | 610 + - .../common/conn_soc/linux/pub/Makefile | 27 + - .../common/conn_soc/linux/pub/bgw_desense.c | 153 + - .../common/conn_soc/linux/pub/osal.c | 1211 ++ - .../common/conn_soc/linux/pub/stp_chrdev_bt.c | 899 ++ - .../conn_soc/linux/pub/wmt_chrdev_wifi.c | 668 + - .../common/conn_soc/linux/pub/wmt_idc.c | 307 + - .../common/conn_soc/mt7623/Makefile | 25 + - .../mt7623/include/mtk_wcn_consys_hw.h | 287 + - .../conn_soc/mt7623/mtk_wcn_consys_hw.c | 738 ++ - .../common/conn_soc/mt7623/wmt_plat_alps.c | 1071 ++ - .../misc/mediatek/connectivity/wlan/Makefile | 8 + - .../mediatek/connectivity/wlan/gen2/Makefile | 237 + - .../connectivity/wlan/gen2/common/debug.c | 165 + - .../connectivity/wlan/gen2/common/dump.c | 345 + - .../connectivity/wlan/gen2/common/wlan_bow.c | 3442 +++++ - .../connectivity/wlan/gen2/common/wlan_lib.c | 6240 +++++++++ - .../connectivity/wlan/gen2/common/wlan_oid.c | 11050 ++++++++++++++++ - .../connectivity/wlan/gen2/common/wlan_p2p.c | 1654 +++ - .../wlan/gen2/include/CFG_Wifi_File.h | 238 + - .../connectivity/wlan/gen2/include/config.h | 1628 +++ - .../connectivity/wlan/gen2/include/debug.h | 466 + - .../connectivity/wlan/gen2/include/link.h | 368 + - .../wlan/gen2/include/mgmt/aa_fsm.h | 188 + - .../wlan/gen2/include/mgmt/ais_fsm.h | 573 + - .../wlan/gen2/include/mgmt/assoc.h | 112 + - .../wlan/gen2/include/mgmt/auth.h | 125 + - .../wlan/gen2/include/mgmt/bow_fsm.h | 184 + - .../connectivity/wlan/gen2/include/mgmt/bss.h | 265 + - .../connectivity/wlan/gen2/include/mgmt/cnm.h | 258 + - .../wlan/gen2/include/mgmt/cnm_mem.h | 1164 ++ - .../wlan/gen2/include/mgmt/cnm_scan.h | 169 + - .../wlan/gen2/include/mgmt/cnm_timer.h | 235 + - .../wlan/gen2/include/mgmt/hem_mbox.h | 446 + - .../wlan/gen2/include/mgmt/hs20.h | 148 + - .../connectivity/wlan/gen2/include/mgmt/mib.h | 153 + - .../wlan/gen2/include/mgmt/p2p_assoc.h | 55 + - .../wlan/gen2/include/mgmt/p2p_bss.h | 56 + - .../wlan/gen2/include/mgmt/p2p_fsm.h | 2190 +++ - .../wlan/gen2/include/mgmt/p2p_func.h | 155 + - .../wlan/gen2/include/mgmt/p2p_ie.h | 156 + - .../wlan/gen2/include/mgmt/p2p_rlm.h | 74 + - .../wlan/gen2/include/mgmt/p2p_rlm_obss.h | 64 + - .../wlan/gen2/include/mgmt/p2p_scan.h | 81 + - .../wlan/gen2/include/mgmt/p2p_state.h | 43 + - .../wlan/gen2/include/mgmt/privacy.h | 230 + - .../wlan/gen2/include/mgmt/rate.h | 93 + - .../connectivity/wlan/gen2/include/mgmt/rlm.h | 396 + - .../wlan/gen2/include/mgmt/rlm_domain.h | 557 + - .../wlan/gen2/include/mgmt/rlm_obss.h | 150 + - .../wlan/gen2/include/mgmt/rlm_protection.h | 122 + - .../wlan/gen2/include/mgmt/rlm_txpwr_init.h | 1213 ++ - .../wlan/gen2/include/mgmt/roaming_fsm.h | 171 + - .../connectivity/wlan/gen2/include/mgmt/rsn.h | 271 + - .../wlan/gen2/include/mgmt/scan.h | 988 ++ - .../wlan/gen2/include/mgmt/sec_fsm.h | 233 + - .../wlan/gen2/include/mgmt/stats.h | 368 + - .../wlan/gen2/include/mgmt/swcr.h | 187 + - .../wlan/gen2/include/mgmt/tdls.h | 262 + - .../wlan/gen2/include/mgmt/wapi.h | 104 + - .../wlan/gen2/include/mgmt/wlan_typedef.h | 87 + - .../connectivity/wlan/gen2/include/mgmt/wnm.h | 95 + - .../wlan/gen2/include/nic/adapter.h | 1506 +++ - .../connectivity/wlan/gen2/include/nic/bow.h | 322 + - .../wlan/gen2/include/nic/cmd_buf.h | 150 + - .../connectivity/wlan/gen2/include/nic/hal.h | 618 + - .../wlan/gen2/include/nic/hif_rx.h | 220 + - .../wlan/gen2/include/nic/hif_tx.h | 214 + - .../connectivity/wlan/gen2/include/nic/mac.h | 2323 ++++ - .../wlan/gen2/include/nic/mtreg.h | 272 + - .../connectivity/wlan/gen2/include/nic/nic.h | 498 + - .../wlan/gen2/include/nic/nic_rx.h | 420 + - .../wlan/gen2/include/nic/nic_tx.h | 642 + - .../connectivity/wlan/gen2/include/nic/p2p.h | 192 + - .../wlan/gen2/include/nic/p2p_cmd_buf.h | 83 + - .../wlan/gen2/include/nic/p2p_mac.h | 207 + - .../wlan/gen2/include/nic/p2p_nic.h | 62 + - .../wlan/gen2/include/nic/p2p_nic_cmd_event.h | 70 + - .../wlan/gen2/include/nic/que_mgt.h | 971 ++ - .../wlan/gen2/include/nic/wlan_def.h | 1010 ++ - .../wlan/gen2/include/nic_cmd_event.h | 2290 ++++ - .../wlan/gen2/include/nic_init_cmd_event.h | 177 + - .../wlan/gen2/include/p2p_precomp.h | 201 + - .../wlan/gen2/include/p2p_typedef.h | 165 + - .../connectivity/wlan/gen2/include/precomp.h | 388 + - .../connectivity/wlan/gen2/include/pwr_mgt.h | 141 + - .../connectivity/wlan/gen2/include/queue.h | 195 + - .../connectivity/wlan/gen2/include/rftest.h | 294 + - .../wlan/gen2/include/tdls_extr.h | 427 + - .../connectivity/wlan/gen2/include/typedef.h | 244 + - .../connectivity/wlan/gen2/include/wlan_bow.h | 352 + - .../connectivity/wlan/gen2/include/wlan_lib.h | 1001 ++ - .../connectivity/wlan/gen2/include/wlan_oid.h | 1715 +++ - .../connectivity/wlan/gen2/include/wlan_p2p.h | 307 + - .../connectivity/wlan/gen2/mgmt/aaa_fsm.c | 1303 ++ - .../connectivity/wlan/gen2/mgmt/ais_fsm.c | 5039 +++++++ - .../connectivity/wlan/gen2/mgmt/assoc.c | 1932 +++ - .../connectivity/wlan/gen2/mgmt/auth.c | 1211 ++ - .../connectivity/wlan/gen2/mgmt/bss.c | 2521 ++++ - .../connectivity/wlan/gen2/mgmt/cnm.c | 738 ++ - .../connectivity/wlan/gen2/mgmt/cnm_mem.c | 1236 ++ - .../connectivity/wlan/gen2/mgmt/cnm_timer.c | 482 + - .../connectivity/wlan/gen2/mgmt/hem_mbox.c | 816 ++ - .../connectivity/wlan/gen2/mgmt/hs20.c | 498 + - .../connectivity/wlan/gen2/mgmt/mib.c | 111 + - .../connectivity/wlan/gen2/mgmt/p2p_assoc.c | 87 + - .../connectivity/wlan/gen2/mgmt/p2p_bss.c | 58 + - .../connectivity/wlan/gen2/mgmt/p2p_fsm.c | 3139 +++++ - .../connectivity/wlan/gen2/mgmt/p2p_func.c | 3796 ++++++ - .../connectivity/wlan/gen2/mgmt/p2p_ie.c | 612 + - .../connectivity/wlan/gen2/mgmt/p2p_rlm.c | 905 ++ - .../wlan/gen2/mgmt/p2p_rlm_obss.c | 313 + - .../connectivity/wlan/gen2/mgmt/p2p_scan.c | 756 ++ - .../connectivity/wlan/gen2/mgmt/p2p_state.c | 466 + - .../connectivity/wlan/gen2/mgmt/privacy.c | 915 ++ - .../connectivity/wlan/gen2/mgmt/rate.c | 497 + - .../connectivity/wlan/gen2/mgmt/rlm.c | 1858 +++ - .../connectivity/wlan/gen2/mgmt/rlm_domain.c | 1791 +++ - .../connectivity/wlan/gen2/mgmt/rlm_obss.c | 436 + - .../wlan/gen2/mgmt/rlm_protection.c | 105 + - .../connectivity/wlan/gen2/mgmt/roaming_fsm.c | 539 + - .../connectivity/wlan/gen2/mgmt/rsn.c | 2533 ++++ - .../connectivity/wlan/gen2/mgmt/saa_fsm.c | 1788 +++ - .../connectivity/wlan/gen2/mgmt/scan.c | 3103 +++++ - .../connectivity/wlan/gen2/mgmt/scan_fsm.c | 2136 +++ - .../connectivity/wlan/gen2/mgmt/sec_fsm.c | 1112 ++ - .../connectivity/wlan/gen2/mgmt/stats.c | 1342 ++ - .../connectivity/wlan/gen2/mgmt/swcr.c | 1170 ++ - .../connectivity/wlan/gen2/mgmt/tdls.c | 5199 ++++++++ - .../connectivity/wlan/gen2/mgmt/tdls_com.c | 741 ++ - .../connectivity/wlan/gen2/mgmt/wapi.c | 491 + - .../connectivity/wlan/gen2/mgmt/wnm.c | 301 + - .../connectivity/wlan/gen2/nic/cmd_buf.c | 254 + - .../mediatek/connectivity/wlan/gen2/nic/nic.c | 4062 ++++++ - .../wlan/gen2/nic/nic_cmd_event.c | 1636 +++ - .../connectivity/wlan/gen2/nic/nic_pwr_mgt.c | 669 + - .../connectivity/wlan/gen2/nic/nic_rx.c | 3782 ++++++ - .../connectivity/wlan/gen2/nic/nic_tx.c | 2350 ++++ - .../connectivity/wlan/gen2/nic/p2p_nic.c | 192 + - .../connectivity/wlan/gen2/nic/que_mgt.c | 5038 +++++++ - .../connectivity/wlan/gen2/os/linux/gl_bow.c | 1177 ++ - .../wlan/gen2/os/linux/gl_cfg80211.c | 3110 +++++ - .../connectivity/wlan/gen2/os/linux/gl_init.c | 3502 +++++ - .../connectivity/wlan/gen2/os/linux/gl_kal.c | 4799 +++++++ - .../connectivity/wlan/gen2/os/linux/gl_p2p.c | 4672 +++++++ - .../wlan/gen2/os/linux/gl_p2p_cfg80211.c | 1935 +++ - .../wlan/gen2/os/linux/gl_p2p_init.c | 433 + - .../wlan/gen2/os/linux/gl_p2p_kal.c | 1314 ++ - .../connectivity/wlan/gen2/os/linux/gl_proc.c | 1020 ++ - .../connectivity/wlan/gen2/os/linux/gl_rst.c | 228 + - .../wlan/gen2/os/linux/gl_vendor.c | 1220 ++ - .../connectivity/wlan/gen2/os/linux/gl_wext.c | 4158 ++++++ - .../wlan/gen2/os/linux/gl_wext_priv.c | 3142 +++++ - .../wlan/gen2/os/linux/hif/ahb/ahb.c | 1643 +++ - .../wlan/gen2/os/linux/hif/ahb/arm.c | 31 + - .../wlan/gen2/os/linux/hif/ahb/include/hif.h | 340 + - .../gen2/os/linux/hif/ahb/include/hif_gdma.h | 154 + - .../gen2/os/linux/hif/ahb/include/hif_pdma.h | 141 + - .../os/linux/hif/ahb/include/mtk_porting.h | 91 + - .../gen2/os/linux/hif/ahb/mt8127/ahb_pdma.c | 480 + - .../wlan/gen2/os/linux/include/gl_cfg80211.h | 341 + - .../wlan/gen2/os/linux/include/gl_kal.h | 1565 +++ - .../wlan/gen2/os/linux/include/gl_os.h | 1270 ++ - .../wlan/gen2/os/linux/include/gl_p2p_ioctl.h | 743 ++ - .../wlan/gen2/os/linux/include/gl_p2p_kal.h | 243 + - .../wlan/gen2/os/linux/include/gl_p2p_os.h | 242 + - .../wlan/gen2/os/linux/include/gl_rst.h | 133 + - .../wlan/gen2/os/linux/include/gl_sec.h | 21 + - .../wlan/gen2/os/linux/include/gl_typedef.h | 298 + - .../wlan/gen2/os/linux/include/gl_vendor.h | 619 + - .../wlan/gen2/os/linux/include/gl_wext.h | 357 + - .../wlan/gen2/os/linux/include/gl_wext_priv.h | 402 + - .../wlan/gen2/os/linux/platform.c | 542 + - .../connectivity/wlan/gen2/os/version.h | 190 + - drivers/misc/mediatek/include/mt-plat/aee.h | 284 + - .../misc/mediatek/include/mt-plat/mrdump.h | 204 + - .../mt-plat/mt7622/include/mach/mtk_thermal.h | 295 + - .../mt8127/include/mach/mt_freqhopping.h | 159 + - .../mt8127/include/mach/mt_spm_mtcmos.h | 37 + - .../mt8127/include/mach/mtk_boot_share_page.h | 40 + - .../mt-plat/mt8127/include/mach/mtk_thermal.h | 301 + - .../misc/mediatek/include/mt-plat/mt_sched.h | 34 + - .../misc/mediatek/include/mt-plat/mtk_io.h | 23 + - .../misc/mediatek/include/mt-plat/mtk_lpae.h | 62 + - .../include/mt-plat/mtk_mdm_monitor.h | 42 + - .../include/mt-plat/mtk_platform_debug.h | 28 + - .../include/mt-plat/mtk_ram_console.h | 162 + - .../misc/mediatek/include/mt-plat/mtk_rtc.h | 85 + - .../include/mt-plat/mtk_thermal_ext_control.h | 69 + - .../include/mt-plat/mtk_thermal_monitor.h | 102 + - .../include/mt-plat/mtk_thermal_platform.h | 114 + - .../include/mt-plat/mtk_thermal_trace.h | 47 + - .../include/mt-plat/mtk_thermal_typedefs.h | 241 + - .../include/mt-plat/mtk_wcn_cmb_stub.h | 185 + - .../misc/mediatek/include/mt-plat/rt-regmap.h | 291 + - .../mediatek/include/mt-plat/sync_write.h | 88 + - .../misc/mediatek/include/mt-plat/wakelock.h | 67 + - 285 files changed, 213970 insertions(+) - create mode 100644 drivers/misc/mediatek/Kconfig - create mode 100644 drivers/misc/mediatek/Makefile - create mode 100644 drivers/misc/mediatek/btif/Kconfig - create mode 100644 drivers/misc/mediatek/btif/Makefile - create mode 100644 drivers/misc/mediatek/btif/common/Makefile - create mode 100644 drivers/misc/mediatek/btif/common/btif_dma_plat.c - create mode 100644 drivers/misc/mediatek/btif/common/btif_plat.c - create mode 100644 drivers/misc/mediatek/btif/common/inc/mtk_btif.h - create mode 100644 drivers/misc/mediatek/btif/common/inc/mtk_btif_exp.h - create mode 100644 drivers/misc/mediatek/btif/common/mtk_btif.c - create mode 100644 drivers/misc/mediatek/btif/common/mtk_btif_exp.c - create mode 100644 drivers/misc/mediatek/btif/common/plat_inc/btif_dma_priv.h - create mode 100644 drivers/misc/mediatek/btif/common/plat_inc/btif_dma_pub.h - create mode 100644 drivers/misc/mediatek/btif/common/plat_inc/btif_priv.h - create mode 100644 drivers/misc/mediatek/btif/common/plat_inc/btif_pub.h - create mode 100644 drivers/misc/mediatek/btif/common/plat_inc/plat_common.h - create mode 100644 drivers/misc/mediatek/connectivity/Kconfig - create mode 100644 drivers/misc/mediatek/connectivity/Makefile - create mode 100644 drivers/misc/mediatek/connectivity/common/Makefile - create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/Makefile - create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/drv_init/Makefile - create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/drv_init/ant_drv_init.c - create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/drv_init/bluetooth_drv_init.c - create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/drv_init/common_drv_init.c - create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/drv_init/conn_drv_init.c - create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/drv_init/fm_drv_init.c - create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/drv_init/gps_drv_init.c - create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/ant_drv_init.h - create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/bluetooth_drv_init.h - create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/common_drv_init.h - create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/conn_drv_init.h - create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/fm_drv_init.h - create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/gps_drv_init.h - create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/wlan_drv_init.h - create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/drv_init/wlan_drv_init.c - create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/mtk_wcn_stub_alps.c - create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/sdio_detect.c - create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/sdio_detect.h - create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/wmt_detect.c - create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/wmt_detect.h - create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/wmt_detect_pwr.c - create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/wmt_detect_pwr.h - create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/wmt_gpio.c - create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/wmt_gpio.h - create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/wmt_stp_exp.c - create mode 100644 drivers/misc/mediatek/connectivity/common/common_detect/wmt_stp_exp.h - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/Makefile - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/core/Makefile - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/core/btm_core.c - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/core/dbg_core.c - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/core/include/btm_core.h - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/core/include/dbg_core.h - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/core/include/psm_core.h - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/core/include/stp_core.h - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/core/include/stp_wmt.h - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_conf.h - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_core.h - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_ctrl.h - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_func.h - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_ic.h - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_lib.h - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/core/psm_core.c - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/core/stp_core.c - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_conf.c - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_core.c - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_ctrl.c - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_func.c - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_ic_soc.c - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_lib.c - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/include/stp_exp.h - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/include/wmt.h - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/include/wmt_exp.h - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/include/wmt_plat.h - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/linux/Makefile - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/linux/include/bgw_desense.h - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/linux/include/osal.h - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/linux/include/osal_typedef.h - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/linux/include/wmt_idc.h - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/Makefile - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/include/stp_btif.h - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/include/stp_dbg.h - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/include/wmt_dev.h - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/stp_btif.c - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/stp_dbg.c - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/stp_exp.c - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/wmt_dev.c - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/wmt_exp.c - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/Makefile - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/bgw_desense.c - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/osal.c - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/stp_chrdev_bt.c - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/wmt_chrdev_wifi.c - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/wmt_idc.c - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/mt7623/Makefile - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/mt7623/include/mtk_wcn_consys_hw.h - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/mt7623/mtk_wcn_consys_hw.c - create mode 100644 drivers/misc/mediatek/connectivity/common/conn_soc/mt7623/wmt_plat_alps.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/Makefile - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/Makefile - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/common/debug.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/common/dump.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/common/wlan_bow.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/common/wlan_lib.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/common/wlan_oid.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/common/wlan_p2p.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/CFG_Wifi_File.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/config.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/debug.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/link.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/aa_fsm.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/ais_fsm.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/assoc.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/auth.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/bow_fsm.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/bss.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/cnm.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/cnm_mem.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/cnm_scan.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/cnm_timer.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/hem_mbox.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/hs20.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/mib.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_assoc.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_bss.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_fsm.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_func.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_ie.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_rlm.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_rlm_obss.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_scan.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_state.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/privacy.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rate.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rlm.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rlm_domain.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rlm_obss.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rlm_protection.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rlm_txpwr_init.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/roaming_fsm.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rsn.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/scan.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/sec_fsm.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/stats.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/swcr.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/tdls.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/wapi.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/wlan_typedef.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/wnm.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/adapter.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/bow.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/cmd_buf.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/hal.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/hif_rx.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/hif_tx.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/mac.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/mtreg.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/nic.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/nic_rx.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/nic_tx.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/p2p.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/p2p_cmd_buf.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/p2p_mac.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/p2p_nic.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/p2p_nic_cmd_event.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/que_mgt.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/wlan_def.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/nic_cmd_event.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/nic_init_cmd_event.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/p2p_precomp.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/p2p_typedef.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/precomp.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/pwr_mgt.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/queue.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/rftest.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/tdls_extr.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/typedef.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/wlan_bow.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/wlan_lib.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/wlan_oid.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/include/wlan_p2p.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/aaa_fsm.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/ais_fsm.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/assoc.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/auth.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/bss.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/cnm.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/cnm_mem.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/cnm_timer.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/hem_mbox.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/hs20.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/mib.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_assoc.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_bss.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_fsm.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_func.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_ie.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_rlm.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_rlm_obss.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_scan.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_state.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/privacy.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rate.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rlm.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rlm_domain.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rlm_obss.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rlm_protection.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/roaming_fsm.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rsn.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/saa_fsm.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/scan.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/scan_fsm.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/sec_fsm.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/stats.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/swcr.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/tdls.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/tdls_com.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/wapi.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/wnm.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/nic/cmd_buf.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic_cmd_event.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic_pwr_mgt.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic_rx.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic_tx.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/nic/p2p_nic.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/nic/que_mgt.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_bow.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_cfg80211.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_init.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_kal.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_p2p.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_p2p_cfg80211.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_p2p_init.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_p2p_kal.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_proc.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_rst.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_vendor.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_wext.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_wext_priv.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/ahb.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/arm.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/include/hif.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/include/hif_gdma.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/include/hif_pdma.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/include/mtk_porting.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/mt8127/ahb_pdma.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_cfg80211.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_kal.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_os.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_p2p_ioctl.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_p2p_kal.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_p2p_os.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_rst.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_sec.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_typedef.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_vendor.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_wext.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_wext_priv.h - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/platform.c - create mode 100644 drivers/misc/mediatek/connectivity/wlan/gen2/os/version.h - create mode 100644 drivers/misc/mediatek/include/mt-plat/aee.h - create mode 100644 drivers/misc/mediatek/include/mt-plat/mrdump.h - create mode 100644 drivers/misc/mediatek/include/mt-plat/mt7622/include/mach/mtk_thermal.h - create mode 100644 drivers/misc/mediatek/include/mt-plat/mt8127/include/mach/mt_freqhopping.h - create mode 100644 drivers/misc/mediatek/include/mt-plat/mt8127/include/mach/mt_spm_mtcmos.h - create mode 100644 drivers/misc/mediatek/include/mt-plat/mt8127/include/mach/mtk_boot_share_page.h - create mode 100644 drivers/misc/mediatek/include/mt-plat/mt8127/include/mach/mtk_thermal.h - create mode 100644 drivers/misc/mediatek/include/mt-plat/mt_sched.h - create mode 100644 drivers/misc/mediatek/include/mt-plat/mtk_io.h - create mode 100644 drivers/misc/mediatek/include/mt-plat/mtk_lpae.h - create mode 100644 drivers/misc/mediatek/include/mt-plat/mtk_mdm_monitor.h - create mode 100644 drivers/misc/mediatek/include/mt-plat/mtk_platform_debug.h - create mode 100644 drivers/misc/mediatek/include/mt-plat/mtk_ram_console.h - create mode 100644 drivers/misc/mediatek/include/mt-plat/mtk_rtc.h - create mode 100644 drivers/misc/mediatek/include/mt-plat/mtk_thermal_ext_control.h - create mode 100644 drivers/misc/mediatek/include/mt-plat/mtk_thermal_monitor.h - create mode 100644 drivers/misc/mediatek/include/mt-plat/mtk_thermal_platform.h - create mode 100644 drivers/misc/mediatek/include/mt-plat/mtk_thermal_trace.h - create mode 100644 drivers/misc/mediatek/include/mt-plat/mtk_thermal_typedefs.h - create mode 100644 drivers/misc/mediatek/include/mt-plat/mtk_wcn_cmb_stub.h - create mode 100644 drivers/misc/mediatek/include/mt-plat/rt-regmap.h - create mode 100644 drivers/misc/mediatek/include/mt-plat/sync_write.h - create mode 100644 drivers/misc/mediatek/include/mt-plat/wakelock.h - -diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig -index 3726eacdf65d..9008a09172e1 100644 ---- a/drivers/misc/Kconfig -+++ b/drivers/misc/Kconfig -@@ -527,4 +527,5 @@ source "drivers/misc/echo/Kconfig" - source "drivers/misc/cxl/Kconfig" - source "drivers/misc/ocxl/Kconfig" - source "drivers/misc/cardreader/Kconfig" -+source "drivers/misc/mediatek/Kconfig" - endmenu -diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile -index af22bbc3d00c..cdced6d59e2c 100644 ---- a/drivers/misc/Makefile -+++ b/drivers/misc/Makefile -@@ -58,3 +58,4 @@ obj-$(CONFIG_ASPEED_LPC_SNOOP) += aspeed-lpc-snoop.o - obj-$(CONFIG_PCI_ENDPOINT_TEST) += pci_endpoint_test.o - obj-$(CONFIG_OCXL) += ocxl/ - obj-$(CONFIG_MISC_RTSX) += cardreader/ -+obj-$(CONFIG_MTK_COMBO) += mediatek/ -diff --git a/drivers/misc/mediatek/Kconfig b/drivers/misc/mediatek/Kconfig -new file mode 100644 -index 000000000000..4829a6598c7a ---- /dev/null -+++ b/drivers/misc/mediatek/Kconfig -@@ -0,0 +1,11 @@ -+menu "Mediatek Peripherals " -+ -+config MTK_PLATFORM -+ string "MTK platform name" -+source "drivers/misc/mediatek/btif/Kconfig" -+ -+menu "Modem & Connectivity related configs" -+source "drivers/misc/mediatek/connectivity/Kconfig" -+endmenu -+ -+endmenu # CONN -diff --git a/drivers/misc/mediatek/Makefile b/drivers/misc/mediatek/Makefile -new file mode 100644 -index 000000000000..5e7f06db38f2 ---- /dev/null -+++ b/drivers/misc/mediatek/Makefile -@@ -0,0 +1,19 @@ -+# -+# Copyright (C) 2015 MediaTek Inc. -+# -+# 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. -+# -+# This program is distributed in the hope that it will be useful, -+# but WITHOUT ANY WARRANTY; without even the implied warranty of -+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+# GNU General Public License for more details. -+# -+ -+#$(call all-subdir-src-or-makefile) -+subdir-ccflags-y += -Werror -+subdir-ccflags-y += -I$(srctree)/drivers/misc/mediatek/include/mt-plat/ -+ -+obj-$(CONFIG_MTK_COMBO) += connectivity/ -+obj-$(CONFIG_MTK_BTIF) += btif/ -diff --git a/drivers/misc/mediatek/btif/Kconfig b/drivers/misc/mediatek/btif/Kconfig -new file mode 100644 -index 000000000000..908898bd95c3 ---- /dev/null -+++ b/drivers/misc/mediatek/btif/Kconfig -@@ -0,0 +1,4 @@ -+config MTK_BTIF -+ tristate"MediaTek BTIF Driver" -+ help -+ MTK connectivity BTIF driver for A/D die -diff --git a/drivers/misc/mediatek/btif/Makefile b/drivers/misc/mediatek/btif/Makefile -new file mode 100644 -index 000000000000..2be3ab66f426 ---- /dev/null -+++ b/drivers/misc/mediatek/btif/Makefile -@@ -0,0 +1,33 @@ -+# -+# Copyright (C) 2015 MediaTek Inc. -+# -+# 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. -+# -+# This program is distributed in the hope that it will be useful, -+# but WITHOUT ANY WARRANTY; without even the implied warranty of -+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+# GNU General Public License for more details. -+# -+ -+# BTIF driver for AD DIE -+# If KERNELRELEASE is defined, we've been invoked from the -+# kernel build system and can use its language. -+ifneq ($(KERNELRELEASE),) -+ #subdir-ccflags-y can be used in 2.6.34 in the future -+ MTK_PLATFORM := $(subst ",,$(CONFIG_MTK_PLATFORM)) -+ subdir-ccflags-y += -I$(srctree)/drivers/misc/mediatek/include/mt-plat/$(MTK_PLATFORM)/include -+ subdir-ccflags-y += -I$(srctree)/arch/arm/mach-$(MTK_PLATFORM)/include/mach -+ subdir-ccflags-y += -I$(srctree)/drivers/misc/mediatek/include/mt-plat -+ -+ obj-y += common/ -+ -+# Otherwise we were called directly from the command -+# line; invoke the kernel build system. -+else -+ KERNELDIR ?= /lib/modules/$(shell uname -r)/build -+ PWD := $(shell pwd) -+default: -+ $(MAKE) -C $(KERNELDIR) M=$(PWD) modules -+endif -diff --git a/drivers/misc/mediatek/btif/common/Makefile b/drivers/misc/mediatek/btif/common/Makefile -new file mode 100644 -index 000000000000..61e9d4ea9e89 ---- /dev/null -+++ b/drivers/misc/mediatek/btif/common/Makefile -@@ -0,0 +1,31 @@ -+# -+# Copyright (C) 2015 MediaTek Inc. -+# -+# 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. -+# -+# This program is distributed in the hope that it will be useful, -+# but WITHOUT ANY WARRANTY; without even the implied warranty of -+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+# GNU General Public License for more details. -+# -+ -+# BTIF driver for AD DIE -+# If KERNELRELEASE is defined, we've been invoked from the -+# kernel build system and can use its language. -+ifneq ($(KERNELRELEASE),) -+ ccflags-y += -I$(src)/inc -+ ccflags-y += -I$(src)/plat_inc -+ -+ obj-y += btif.o -+ btif-y := mtk_btif.o mtk_btif_exp.o btif_dma_plat.o btif_plat.o -+ -+# Otherwise we were called directly from the command -+# line; invoke the kernel build system. -+else -+ KERNELDIR ?= /lib/modules/$(shell uname -r)/build -+ PWD := $(shell pwd) -+default: -+ $(MAKE) -C $(KERNELDIR) M=$(PWD) modules -+endif -diff --git a/drivers/misc/mediatek/btif/common/btif_dma_plat.c b/drivers/misc/mediatek/btif/common/btif_dma_plat.c -new file mode 100644 -index 000000000000..58be46927953 ---- /dev/null -+++ b/drivers/misc/mediatek/btif/common/btif_dma_plat.c -@@ -0,0 +1,1436 @@ -+/* -+ * Copyright (C) 2015 MediaTek Inc. -+ * -+ * 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. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#include -+#include -+ -+#ifdef DFT_TAG -+#undef DFT_TAG -+#endif -+#define DFT_TAG "MTK-BTIF-DMA" -+ -+#include "btif_dma_priv.h" -+ -+#define DMA_USER_ID "btif_driver" -+ -+/************************************Global variable***********************************/ -+ -+static MTK_BTIF_DMA_VFIFO mtk_tx_dma_vfifo = { -+ .vfifo = { -+ .p_vir_addr = NULL, -+ .phy_addr = 0, -+ .vfifo_size = TX_DMA_VFF_SIZE, -+ .thre = DMA_TX_THRE(TX_DMA_VFF_SIZE), -+ }, -+ .wpt = 0, -+ .last_wpt_wrap = 0, -+ .rpt = 0, -+ .last_rpt_wrap = 0, -+}; -+ -+static MTK_BTIF_IRQ_STR mtk_btif_tx_dma_irq = { -+ .name = "mtk btif tx dma irq", -+ .is_irq_sup = true, -+ .reg_flag = false, -+#ifdef CONFIG_OF -+ .irq_flags = IRQF_TRIGGER_NONE, -+#else -+ .irq_id = MT_DMA_BTIF_TX_IRQ_ID, -+ .sens_type = IRQ_SENS_LVL, -+ .lvl_type = IRQ_LVL_LOW, -+#endif -+ .p_irq_handler = NULL, -+}; -+ -+static MTK_BTIF_DMA_VFIFO mtk_rx_dma_vfifo = { -+ .vfifo = { -+ .p_vir_addr = NULL, -+ .phy_addr = 0, -+ .vfifo_size = RX_DMA_VFF_SIZE, -+ .thre = DMA_RX_THRE(RX_DMA_VFF_SIZE), -+ }, -+ -+ .wpt = 0, -+ .last_wpt_wrap = 0, -+ .rpt = 0, -+ .last_rpt_wrap = 0, -+}; -+ -+static MTK_BTIF_IRQ_STR mtk_btif_rx_dma_irq = { -+ .name = "mtk btif rx dma irq", -+ .is_irq_sup = true, -+ .reg_flag = false, -+#ifdef CONFIG_OF -+ .irq_flags = IRQF_TRIGGER_NONE, -+#else -+ .irq_id = MT_DMA_BTIF_RX_IRQ_ID, -+ .sens_type = IRQ_SENS_LVL, -+ .lvl_type = IRQ_LVL_LOW, -+#endif -+ .p_irq_handler = NULL, -+}; -+ -+static MTK_DMA_INFO_STR mtk_btif_tx_dma = { -+#ifndef CONFIG_OF -+ .base = AP_DMA_BASE + BTIF_TX_DMA_OFFSET, -+#endif -+ .dir = DMA_DIR_TX, -+ .p_irq = &mtk_btif_tx_dma_irq, -+ .p_vfifo = &(mtk_tx_dma_vfifo.vfifo), -+}; -+ -+static MTK_DMA_INFO_STR mtk_btif_rx_dma = { -+#ifndef CONFIG_OF -+ .base = AP_DMA_BASE + BTIF_RX_DMA_OFFSET, -+#endif -+ .dir = DMA_DIR_RX, -+ .p_irq = &mtk_btif_rx_dma_irq, -+ .p_vfifo = &(mtk_rx_dma_vfifo.vfifo), -+}; -+ -+static spinlock_t g_clk_cg_spinlock; /*dma clock's spinlock */ -+ -+/************************************Function declearation***********************************/ -+static int _is_tx_dma_in_flush(P_MTK_DMA_INFO_STR p_dma_info); -+static int _tx_dma_flush(P_MTK_DMA_INFO_STR p_dma_info); -+static int btif_rx_dma_ctrl(P_MTK_DMA_INFO_STR p_dma_info, -+ ENUM_DMA_CTRL ctrl_id); -+static int btif_tx_dma_ctrl(P_MTK_DMA_INFO_STR p_dma_info, -+ ENUM_DMA_CTRL ctrl_id); -+static int btif_rx_dma_ier_ctrl(P_MTK_DMA_INFO_STR p_dma_info, bool en); -+static int btif_tx_dma_ier_ctrl(P_MTK_DMA_INFO_STR p_dma_info, bool en); -+static int hal_rx_dma_dump_reg(P_MTK_DMA_INFO_STR p_dma_info, -+ ENUM_BTIF_REG_ID flag); -+static int hal_tx_dma_dump_reg(P_MTK_DMA_INFO_STR p_dma_info, -+ ENUM_BTIF_REG_ID flag); -+static int is_tx_dma_irq_finish_done(P_MTK_DMA_INFO_STR p_dma_info); -+static int _btif_dma_dump_dbg_reg(void); -+static void hal_btif_tx_dma_vff_set_for_4g(void); -+static void hal_btif_rx_dma_vff_set_for_4g(void); -+ -+/***************************************************************************** -+* FUNCTION -+* hal_tx_dma_ier_ctrl -+* DESCRIPTION -+* BTIF Tx DMA's interrupt enable/disable -+* PARAMETERS -+* p_dma_info [IN] pointer to BTIF dma channel's information -+* enable [IN] control if tx interrupt enabled or not -+* dma_dir [IN] DMA's direction -+* RETURNS -+* 0 means success, negative means fail -+*****************************************************************************/ -+static int hal_btif_dma_ier_ctrl(P_MTK_DMA_INFO_STR p_dma_info, bool en); -+ -+/***************************************************************************** -+* FUNCTION -+* hal_dma_receive_data -+* DESCRIPTION -+* receive data from btif module in DMA polling mode -+* PARAMETERS -+* p_dma_info [IN] pointer to BTIF dma channel's information -+* p_buf [IN/OUT] pointer to rx data buffer -+* max_len [IN] max length of rx buffer -+* RETURNS -+* positive means data is available, 0 means no data available -+*****************************************************************************/ -+#ifndef MTK_BTIF_MARK_UNUSED_API -+static int hal_dma_receive_data(P_MTK_DMA_INFO_STR p_dma_info, -+ unsigned char *p_buf, -+ const unsigned int max_len); -+ -+/************************************Function***********************************/ -+#endif -+ -+#ifdef CONFIG_OF -+static void hal_dma_set_default_setting(ENUM_DMA_DIR dma_dir) -+{ -+ struct device_node *node = NULL; -+ unsigned int irq_info[3] = {0, 0, 0}; -+ unsigned int phy_base; -+ -+ if (dma_dir == DMA_DIR_RX) { -+ node = of_find_compatible_node(NULL, NULL, "mediatek,btif_rx"); -+ if (node) { -+ mtk_btif_rx_dma.p_irq->irq_id = irq_of_parse_and_map(node, 0); -+ /*fixme, be compitable arch 64bits*/ -+ mtk_btif_rx_dma.base = (unsigned long)of_iomap(node, 0); -+ BTIF_INFO_FUNC("get rx_dma irq(%d),register base(0x%lx)\n", -+ mtk_btif_rx_dma.p_irq->irq_id, mtk_btif_rx_dma.base); -+ } else { -+ BTIF_ERR_FUNC("get rx_dma device node fail\n"); -+ } -+ /* get the interrupt line behaviour */ -+ if (of_property_read_u32_array(node, "interrupts", irq_info, ARRAY_SIZE(irq_info))) { -+ BTIF_ERR_FUNC("get interrupt flag from DTS fail\n"); -+ } else { -+ mtk_btif_rx_dma.p_irq->irq_flags = irq_info[2]; -+ BTIF_INFO_FUNC("get interrupt flag(0x%x)\n", -+ mtk_btif_rx_dma.p_irq->irq_flags); -+ } -+ if (of_property_read_u32_index(node, "reg", 1, &phy_base)) { -+ BTIF_ERR_FUNC("get register phy base from DTS fail,dma_dir(%d)\n", -+ dma_dir); -+ } else { -+ BTIF_INFO_FUNC("get register phy base dma_dir(%d)(0x%x)\n", -+ dma_dir, (unsigned int)phy_base); -+ } -+ } else if (dma_dir == DMA_DIR_TX) { -+ node = of_find_compatible_node(NULL, NULL, "mediatek,btif_tx"); -+ if (node) { -+ mtk_btif_tx_dma.p_irq->irq_id = irq_of_parse_and_map(node, 0); -+ /*fixme, be compitable arch 64bits*/ -+ mtk_btif_tx_dma.base = (unsigned long)of_iomap(node, 0); -+ BTIF_INFO_FUNC("get tx_dma irq(%d),register base(0x%lx)\n", -+ mtk_btif_tx_dma.p_irq->irq_id, mtk_btif_tx_dma.base); -+ } else { -+ BTIF_ERR_FUNC("get tx_dma device node fail\n"); -+ } -+ /* get the interrupt line behaviour */ -+ if (of_property_read_u32_array(node, "interrupts", irq_info, ARRAY_SIZE(irq_info))) { -+ BTIF_ERR_FUNC("get interrupt flag from DTS fail\n"); -+ } else { -+ mtk_btif_tx_dma.p_irq->irq_flags = irq_info[2]; -+ BTIF_INFO_FUNC("get interrupt flag(0x%x)\n", -+ mtk_btif_tx_dma.p_irq->irq_flags); -+ } -+ -+ if (of_property_read_u32_index(node, "reg", 1, &phy_base)) { -+ BTIF_ERR_FUNC("get register phy base from DTS fail,dma_dir(%d)\n", -+ dma_dir); -+ } else { -+ BTIF_INFO_FUNC("get register phy base dma_dir(%d)(0x%x)\n", -+ dma_dir, (unsigned int)phy_base); -+ } -+ } -+ -+} -+#endif -+ -+/***************************************************************************** -+* FUNCTION -+* hal_tx_dma_info_get -+* DESCRIPTION -+* get btif tx dma channel's information -+* PARAMETERS -+* dma_dir [IN] DMA's direction -+* RETURNS -+* pointer to btif dma's information structure -+*****************************************************************************/ -+P_MTK_DMA_INFO_STR hal_btif_dma_info_get(ENUM_DMA_DIR dma_dir) -+{ -+ P_MTK_DMA_INFO_STR p_dma_info = NULL; -+ -+ BTIF_TRC_FUNC(); -+#ifdef CONFIG_OF -+ hal_dma_set_default_setting(dma_dir); -+#endif -+ if (dma_dir == DMA_DIR_RX) -+ /*Rx DMA*/ -+ p_dma_info = &mtk_btif_rx_dma; -+ else if (dma_dir == DMA_DIR_TX) -+ /*Tx DMA*/ -+ p_dma_info = &mtk_btif_tx_dma; -+ else -+ /*print error log*/ -+ BTIF_ERR_FUNC("invalid DMA dir (%d)\n", dma_dir); -+ spin_lock_init(&g_clk_cg_spinlock); -+ BTIF_TRC_FUNC(); -+ return p_dma_info; -+} -+ -+/***************************************************************************** -+* FUNCTION -+* hal_btif_clk_ctrl -+* DESCRIPTION -+* control clock output enable/disable of DMA module -+* PARAMETERS -+* p_dma_info [IN] pointer to BTIF dma channel's information -+* RETURNS -+* 0 means success, negative means fail -+*****************************************************************************/ -+int hal_btif_dma_clk_ctrl(P_MTK_DMA_INFO_STR p_dma_info, ENUM_CLOCK_CTRL flag) -+{ -+/*In MTK DMA BTIF channel, there's only one global CG on AP_DMA, no sub channel's CG bit*/ -+/*according to Artis's comment, clock of DMA and BTIF is default off, so we assume it to be off by default*/ -+ int i_ret = 0; -+ unsigned long irq_flag = 0; -+ -+#if MTK_BTIF_ENABLE_CLK_REF_COUNTER -+ static atomic_t s_clk_ref = ATOMIC_INIT(0); -+#else -+ static ENUM_CLOCK_CTRL status = CLK_OUT_DISABLE; -+#endif -+ -+ spin_lock_irqsave(&(g_clk_cg_spinlock), irq_flag); -+ -+#if MTK_BTIF_ENABLE_CLK_CTL -+ -+#if MTK_BTIF_ENABLE_CLK_REF_COUNTER -+ -+ if (flag == CLK_OUT_ENABLE) { -+ if (atomic_inc_return(&s_clk_ref) == 1) { -+#if defined(CONFIG_MTK_CLKMGR) -+ i_ret = enable_clock(MTK_BTIF_APDMA_CLK_CG, DMA_USER_ID); -+#else -+ BTIF_DBG_FUNC("[CCF]enable clk_btif_apdma\n"); -+ i_ret = clk_enable(clk_btif_apdma); -+#endif /* defined(CONFIG_MTK_CLKMGR) */ -+ if (i_ret) { -+ BTIF_WARN_FUNC -+ ("enable_clock for MTK_BTIF_APDMA_CLK_CG failed, ret:%d", -+ i_ret); -+ } -+ } -+ } else if (flag == CLK_OUT_DISABLE) { -+ if (atomic_dec_return(&s_clk_ref) == 0) { -+#if defined(CONFIG_MTK_CLKMGR) -+ i_ret = disable_clock(MTK_BTIF_APDMA_CLK_CG, DMA_USER_ID); -+ if (i_ret) { -+ BTIF_WARN_FUNC -+ ("disable_clock for MTK_BTIF_APDMA_CLK_CG failed, ret:%d", -+ i_ret); -+ } -+#else -+ BTIF_DBG_FUNC("[CCF] clk_disable(clk_btif_apdma) calling\n"); -+ clk_disable(clk_btif_apdma); -+#endif /* defined(CONFIG_MTK_CLKMGR) */ -+ } -+ } else { -+ i_ret = ERR_INVALID_PAR; -+ BTIF_ERR_FUNC("invalid clock ctrl flag (%d)\n", flag); -+ } -+ -+#else -+ -+ if (status == flag) { -+ i_ret = 0; -+ BTIF_DBG_FUNC("dma clock already %s\n", -+ CLK_OUT_ENABLE == -+ status ? "enabled" : "disabled"); -+ } else { -+ if (flag == CLK_OUT_ENABLE) { -+#if defined(CONFIG_MTK_CLKMGR) -+ i_ret = enable_clock(MTK_BTIF_APDMA_CLK_CG, DMA_USER_ID); -+#else -+ BTIF_DBG_FUNC("[CCF]enable clk_btif_apdma\n"); -+ i_ret = clk_enable(clk_btif_apdma); -+#endif /* defined(CONFIG_MTK_CLKMGR) */ -+ status = (i_ret == 0) ? flag : status; -+ if (i_ret) { -+ BTIF_WARN_FUNC -+ ("enable_clock for MTK_BTIF_APDMA_CLK_CG failed, ret:%d", -+ i_ret); -+ } -+ } else if (flag == CLK_OUT_DISABLE) { -+#if defined(CONFIG_MTK_CLKMGR) -+ i_ret = disable_clock(MTK_BTIF_APDMA_CLK_CG, DMA_USER_ID); -+ status = (i_ret == 0) ? flag : status; -+ if (i_ret) { -+ BTIF_WARN_FUNC -+ ("disable_clock for MTK_BTIF_APDMA_CLK_CG failed, ret:%d", -+ i_ret); -+ } -+#else -+ BTIF_DBG_FUNC("[CCF] clk_disable_unprepare(clk_btif_apdma) calling\n"); -+ clk_disable(clk_btif_apdma); -+#endif /* defined(CONFIG_MTK_CLKMGR) */ -+ } else { -+ i_ret = ERR_INVALID_PAR; -+ BTIF_ERR_FUNC("invalid clock ctrl flag (%d)\n", flag); -+ } -+ } -+#endif -+ -+#else -+ -+#if MTK_BTIF_ENABLE_CLK_REF_COUNTER -+ -+#else -+ -+ status = flag; -+#endif -+ -+ i_ret = 0; -+#endif -+ -+ spin_unlock_irqrestore(&(g_clk_cg_spinlock), irq_flag); -+ -+#if MTK_BTIF_ENABLE_CLK_REF_COUNTER -+ if (i_ret == 0) { -+ BTIF_DBG_FUNC("dma clock %s\n", flag == CLK_OUT_ENABLE ? "enabled" : "disabled"); -+ } else { -+ BTIF_ERR_FUNC("%s dma clock failed, ret(%d)\n", -+ flag == CLK_OUT_ENABLE ? "enable" : "disable", i_ret); -+ } -+#else -+ -+ if (i_ret == 0) { -+ BTIF_DBG_FUNC("dma clock %s\n", flag == CLK_OUT_ENABLE ? "enabled" : "disabled"); -+ } else { -+ BTIF_ERR_FUNC("%s dma clock failed, ret(%d)\n", -+ flag == CLK_OUT_ENABLE ? "enable" : "disable", i_ret); -+ } -+#endif -+#if defined(CONFIG_MTK_CLKMGR) -+ BTIF_DBG_FUNC("DMA's clock is %s\n", (clock_is_on(MTK_BTIF_APDMA_CLK_CG) == 0) ? "off" : "on"); -+#endif -+ return i_ret; -+} -+ -+int hal_btif_dma_hw_init(P_MTK_DMA_INFO_STR p_dma_info) -+{ -+ int i_ret = 0; -+ unsigned int dat = 0; -+ unsigned long base = p_dma_info->base; -+ unsigned long addr_h = 0; -+ P_DMA_VFIFO p_vfifo = p_dma_info->p_vfifo; -+ P_MTK_BTIF_DMA_VFIFO p_mtk_dma_vfifo = container_of(p_vfifo, -+ MTK_BTIF_DMA_VFIFO, -+ vfifo); -+ -+ if (p_dma_info->dir == DMA_DIR_RX) { -+ /*Rx DMA*/ -+ /*do hardware reset*/ -+ /* BTIF_SET_BIT(RX_DMA_RST(base), DMA_HARD_RST);*/ -+ /* BTIF_CLR_BIT(RX_DMA_RST(base), DMA_HARD_RST);*/ -+ BTIF_SET_BIT(RX_DMA_RST(base), DMA_WARM_RST); -+ do { -+ dat = BTIF_READ32(RX_DMA_EN(base)); -+ } while (0x01 & dat); -+ /*write vfifo base address to VFF_ADDR*/ -+ btif_reg_sync_writel(p_vfifo->phy_addr, RX_DMA_VFF_ADDR(base)); -+ if (enable_4G()) -+ hal_btif_rx_dma_vff_set_for_4g(); -+ else { -+ addr_h = p_vfifo->phy_addr >> 16; -+ addr_h = addr_h >> 16; -+ btif_reg_sync_writel(addr_h, RX_DMA_VFF_ADDR_H(base)); -+ } -+ /*write vfifo length to VFF_LEN*/ -+ btif_reg_sync_writel(p_vfifo->vfifo_size, RX_DMA_VFF_LEN(base)); -+ /*write wpt to VFF_WPT*/ -+ btif_reg_sync_writel(p_mtk_dma_vfifo->wpt, -+ RX_DMA_VFF_WPT(base)); -+ btif_reg_sync_writel(p_mtk_dma_vfifo->rpt, -+ RX_DMA_VFF_RPT(base)); -+ /*write vff_thre to VFF_THRESHOLD*/ -+ btif_reg_sync_writel(p_vfifo->thre, RX_DMA_VFF_THRE(base)); -+ /*clear Rx DMA's interrupt status*/ -+ BTIF_SET_BIT(RX_DMA_INT_FLAG(base), -+ RX_DMA_INT_DONE | RX_DMA_INT_THRE); -+ -+ /*enable Rx IER by default*/ -+ btif_rx_dma_ier_ctrl(p_dma_info, true); -+ } else { -+/*Tx DMA*/ -+/*do hardware reset*/ -+/* BTIF_SET_BIT(TX_DMA_RST(base), DMA_HARD_RST);*/ -+/* BTIF_CLR_BIT(TX_DMA_RST(base), DMA_HARD_RST);*/ -+ BTIF_SET_BIT(TX_DMA_RST(base), DMA_WARM_RST); -+ do { -+ dat = BTIF_READ32(TX_DMA_EN(base)); -+ } while (0x01 & dat); -+/*write vfifo base address to VFF_ADDR*/ -+ btif_reg_sync_writel(p_vfifo->phy_addr, TX_DMA_VFF_ADDR(base)); -+ if (enable_4G()) -+ hal_btif_tx_dma_vff_set_for_4g(); -+ else { -+ addr_h = p_vfifo->phy_addr >> 16; -+ addr_h = addr_h >> 16; -+ btif_reg_sync_writel(addr_h, TX_DMA_VFF_ADDR_H(base)); -+ } -+/*write vfifo length to VFF_LEN*/ -+ btif_reg_sync_writel(p_vfifo->vfifo_size, TX_DMA_VFF_LEN(base)); -+/*write wpt to VFF_WPT*/ -+ btif_reg_sync_writel(p_mtk_dma_vfifo->wpt, -+ TX_DMA_VFF_WPT(base)); -+ btif_reg_sync_writel(p_mtk_dma_vfifo->rpt, -+ TX_DMA_VFF_RPT(base)); -+/*write vff_thre to VFF_THRESHOLD*/ -+ btif_reg_sync_writel(p_vfifo->thre, TX_DMA_VFF_THRE(base)); -+ -+ BTIF_CLR_BIT(TX_DMA_INT_FLAG(base), TX_DMA_INT_FLAG_MASK); -+ -+ hal_btif_dma_ier_ctrl(p_dma_info, false); -+ } -+ -+ return i_ret; -+} -+ -+/***************************************************************************** -+* FUNCTION -+* hal_tx_dma_ctrl -+* DESCRIPTION -+* enable/disable Tx DMA channel -+* PARAMETERS -+* p_dma_info [IN] pointer to BTIF dma channel's information -+* ctrl_id [IN] enable/disable ID -+* RETURNS -+* 0 means success; negative means fail -+*****************************************************************************/ -+int hal_btif_dma_ctrl(P_MTK_DMA_INFO_STR p_dma_info, ENUM_DMA_CTRL ctrl_id) -+{ -+ unsigned int i_ret = -1; -+ ENUM_DMA_DIR dir = p_dma_info->dir; -+ -+ if (dir == DMA_DIR_RX) -+ i_ret = btif_rx_dma_ctrl(p_dma_info, ctrl_id); -+ else if (dir == DMA_DIR_TX) -+ i_ret = btif_tx_dma_ctrl(p_dma_info, ctrl_id); -+ else { -+ /*TODO: print error log*/ -+ BTIF_ERR_FUNC("invalid dma ctrl id (%d)\n", ctrl_id); -+ i_ret = ERR_INVALID_PAR; -+ } -+ return i_ret; -+} -+ -+int hal_btif_dma_rx_cb_reg(P_MTK_DMA_INFO_STR p_dma_info, -+ dma_rx_buf_write rx_cb) -+{ -+ if (p_dma_info->rx_cb != NULL) { -+ BTIF_DBG_FUNC -+ ("rx_cb already registered, replace (0x%p) with (0x%p)\n", -+ p_dma_info->rx_cb, rx_cb); -+ } -+ p_dma_info->rx_cb = rx_cb; -+ return 0; -+} -+ -+int btif_tx_dma_ctrl(P_MTK_DMA_INFO_STR p_dma_info, ENUM_DMA_CTRL ctrl_id) -+{ -+ unsigned int i_ret = -1; -+ unsigned long base = p_dma_info->base; -+ unsigned int dat; -+ -+ BTIF_TRC_FUNC(); -+ if (ctrl_id == DMA_CTRL_DISABLE) { -+ /*if write 0 to EN bit, DMA will be stopped imediately*/ -+ /*if write 1 to STOP bit, DMA will be stopped after current transaction finished*/ -+ /*BTIF_CLR_BIT(TX_DMA_EN(base), DMA_EN_BIT);*/ -+ BTIF_SET_BIT(TX_DMA_STOP(base), DMA_STOP_BIT); -+ do { -+ dat = BTIF_READ32(TX_DMA_STOP(base)); -+ } while (0x1 & dat); -+ BTIF_DBG_FUNC("BTIF Tx DMA disabled,EN(0x%x),STOP(0x%x)\n", -+ BTIF_READ32(TX_DMA_EN(base)), BTIF_READ32(TX_DMA_STOP(base))); -+ i_ret = 0; -+ } else if (ctrl_id == DMA_CTRL_ENABLE) { -+ BTIF_SET_BIT(TX_DMA_EN(base), DMA_EN_BIT); -+ BTIF_DBG_FUNC("BTIF Tx DMA enabled\n"); -+ i_ret = 0; -+ } else { -+/*TODO: print error log*/ -+ BTIF_ERR_FUNC("invalid DMA ctrl_id (%d)\n", ctrl_id); -+ i_ret = ERR_INVALID_PAR; -+ } -+ BTIF_TRC_FUNC(); -+ return i_ret; -+} -+ -+int btif_rx_dma_ctrl(P_MTK_DMA_INFO_STR p_dma_info, ENUM_DMA_CTRL ctrl_id) -+{ -+ unsigned int i_ret = -1; -+ unsigned long base = p_dma_info->base; -+ unsigned int dat; -+ -+ BTIF_TRC_FUNC(); -+ -+ if (ctrl_id == DMA_CTRL_DISABLE) { -+ /*if write 0 to EN bit, DMA will be stopped imediately*/ -+ /*if write 1 to STOP bit, DMA will be stopped after current transaction finished*/ -+ /*BTIF_CLR_BIT(RX_DMA_EN(base), DMA_EN_BIT);*/ -+ BTIF_SET_BIT(RX_DMA_STOP(base), DMA_STOP_BIT); -+ do { -+ dat = BTIF_READ32(RX_DMA_STOP(base)); -+ } while (0x1 & dat); -+ BTIF_DBG_FUNC("BTIF Rx DMA disabled,EN(0x%x),STOP(0x%x)\n", -+ BTIF_READ32(RX_DMA_EN(base)), BTIF_READ32(RX_DMA_STOP(base))); -+ i_ret = 0; -+ } else if (ctrl_id == DMA_CTRL_ENABLE) { -+ BTIF_SET_BIT(RX_DMA_EN(base), DMA_EN_BIT); -+ BTIF_DBG_FUNC("BTIF Rx DMA enabled\n"); -+ i_ret = 0; -+ } else { -+/*TODO: print error log*/ -+ BTIF_ERR_FUNC("invalid DMA ctrl_id (%d)\n", ctrl_id); -+ i_ret = ERR_INVALID_PAR; -+ } -+ BTIF_TRC_FUNC(); -+ -+ return i_ret; -+} -+ -+/***************************************************************************** -+* FUNCTION -+* hal_tx_vfifo_reset -+* DESCRIPTION -+* reset tx virtual fifo information, except memory information -+* PARAMETERS -+* p_dma_info [IN] pointer to BTIF dma channel's information -+* RETURNS -+* 0 means success, negative means fail -+*****************************************************************************/ -+int hal_btif_vfifo_reset(P_MTK_DMA_INFO_STR p_dma_info) -+{ -+ unsigned int i_ret = -1; -+ P_DMA_VFIFO p_vfifo = p_dma_info->p_vfifo; -+ P_MTK_BTIF_DMA_VFIFO p_mtk_dma_vfifo = container_of(p_vfifo, -+ MTK_BTIF_DMA_VFIFO, -+ vfifo); -+ -+ BTIF_TRC_FUNC(); -+ p_mtk_dma_vfifo->rpt = 0; -+ p_mtk_dma_vfifo->last_rpt_wrap = 0; -+ p_mtk_dma_vfifo->wpt = 0; -+ p_mtk_dma_vfifo->last_wpt_wrap = 0; -+ BTIF_TRC_FUNC(); -+ return i_ret; -+} -+ -+/***************************************************************************** -+* FUNCTION -+* hal_tx_dma_ier_ctrl -+* DESCRIPTION -+* BTIF Tx DMA's interrupt enable/disable -+* PARAMETERS -+* p_dma_info [IN] pointer to BTIF dma channel's information -+* enable [IN] control if tx interrupt enabled or not -+* RETURNS -+* 0 means success, negative means fail -+*****************************************************************************/ -+int hal_btif_dma_ier_ctrl(P_MTK_DMA_INFO_STR p_dma_info, bool en) -+{ -+ unsigned int i_ret = -1; -+ ENUM_DMA_DIR dir = p_dma_info->dir; -+ -+ if (dir == DMA_DIR_RX) { -+ i_ret = btif_rx_dma_ier_ctrl(p_dma_info, en); -+ } else if (dir == DMA_DIR_TX) { -+ i_ret = btif_tx_dma_ier_ctrl(p_dma_info, en); -+ } else { -+/*TODO: print error log*/ -+ BTIF_ERR_FUNC("invalid DMA dma dir (%d)\n", dir); -+ i_ret = ERR_INVALID_PAR; -+ } -+ -+ return i_ret; -+} -+ -+int btif_rx_dma_ier_ctrl(P_MTK_DMA_INFO_STR p_dma_info, bool en) -+{ -+ unsigned int i_ret = -1; -+ unsigned long base = p_dma_info->base; -+ -+ BTIF_TRC_FUNC(); -+ if (!en) { -+ BTIF_CLR_BIT(RX_DMA_INT_EN(base), -+ (RX_DMA_INT_THRE_EN | RX_DMA_INT_DONE_EN)); -+ } else { -+ BTIF_SET_BIT(RX_DMA_INT_EN(base), -+ (RX_DMA_INT_THRE_EN | RX_DMA_INT_DONE_EN)); -+ } -+ i_ret = 0; -+ BTIF_TRC_FUNC(); -+ -+ return i_ret; -+} -+ -+int btif_tx_dma_ier_ctrl(P_MTK_DMA_INFO_STR p_dma_info, bool en) -+{ -+ unsigned int i_ret = -1; -+ unsigned long base = p_dma_info->base; -+ -+ BTIF_TRC_FUNC(); -+ if (!en) -+ BTIF_CLR_BIT(TX_DMA_INT_EN(base), TX_DMA_INTEN_BIT); -+ else -+ BTIF_SET_BIT(TX_DMA_INT_EN(base), TX_DMA_INTEN_BIT); -+ i_ret = 0; -+ BTIF_TRC_FUNC(); -+ -+ return i_ret; -+} -+ -+static int is_tx_dma_irq_finish_done(P_MTK_DMA_INFO_STR p_dma_info) -+{ -+ int tx_irq_done = 0; -+#if MTK_BTIF_ENABLE_CLK_REF_COUNTER -+/*if we enable this clock reference couner, just return , because when enter IRQ handler, DMA's clock will be opened*/ -+ tx_irq_done = 1; -+#else -+ unsigned long flag = 0; -+ unsigned long base = p_dma_info->base; -+ -+ spin_lock_irqsave(&(g_clk_cg_spinlock), flag); -+ tx_irq_done = ((BTIF_READ32(TX_DMA_INT_FLAG(base)) & TX_DMA_INT_FLAG_MASK) == 0) ? 1 : 0; -+ spin_unlock_irqrestore(&(g_clk_cg_spinlock), flag); -+#endif -+ return tx_irq_done; -+} -+ -+/***************************************************************************** -+* FUNCTION -+* hal_tx_dma_irq_handler -+* DESCRIPTION -+* lower level tx interrupt handler -+* PARAMETERS -+* p_dma_info [IN] pointer to BTIF dma channel's information -+* RETURNS -+* 0 means success, negative means fail -+*****************************************************************************/ -+int hal_tx_dma_irq_handler(P_MTK_DMA_INFO_STR p_dma_info) -+{ -+#define MAX_CONTINIOUS_TIMES 512 -+ unsigned int i_ret = -1; -+ unsigned int valid_size = 0; -+ unsigned int vff_len = 0; -+ unsigned int left_len = 0; -+ unsigned long base = p_dma_info->base; -+ static int flush_irq_counter; -+ static struct timeval start_timer; -+ static struct timeval end_timer; -+ unsigned long flag = 0; -+ -+ spin_lock_irqsave(&(g_clk_cg_spinlock), flag); -+ -+#if defined(CONFIG_MTK_CLKMGR) -+ if (clock_is_on(MTK_BTIF_APDMA_CLK_CG) == 0) { -+ spin_unlock_irqrestore(&(g_clk_cg_spinlock), flag); -+ BTIF_ERR_FUNC -+ ("%s: clock is off before irq status clear done!!!\n", -+ __FILE__); -+ return i_ret; -+ } -+#endif -+/*check if Tx VFF Left Size equal to VFIFO size or not*/ -+ vff_len = BTIF_READ32(TX_DMA_VFF_LEN(base)); -+ valid_size = BTIF_READ32(TX_DMA_VFF_VALID_SIZE(base)); -+ left_len = BTIF_READ32(TX_DMA_VFF_LEFT_SIZE(base)); -+ if (flush_irq_counter == 0) -+ do_gettimeofday(&start_timer); -+ if ((valid_size > 0) && (valid_size < 8)) { -+ i_ret = _tx_dma_flush(p_dma_info); -+ flush_irq_counter++; -+ if (flush_irq_counter >= MAX_CONTINIOUS_TIMES) { -+ do_gettimeofday(&end_timer); -+/* -+ * when btif tx fifo cannot accept any data and counts of bytes left in tx vfifo < 8 for a while -+ * we assume that btif cannot send data for a long time -+ * in order not to generate interrupt continiously, which may effect system's performance. -+ * we clear tx flag and disable btif tx interrupt -+ */ -+/*clear interrupt flag*/ -+ BTIF_CLR_BIT(TX_DMA_INT_FLAG(base), -+ TX_DMA_INT_FLAG_MASK); -+/*vFIFO data has been read by DMA controller, just disable tx dma's irq*/ -+ i_ret = hal_btif_dma_ier_ctrl(p_dma_info, false); -+ BTIF_ERR_FUNC -+ ("**********************ERROR, ERROR, ERROR**************************\n"); -+ BTIF_ERR_FUNC -+ ("BTIF Tx IRQ happened %d times (continiously), between %d.%d and %d.%d\n", -+ MAX_CONTINIOUS_TIMES, start_timer.tv_sec, -+ start_timer.tv_usec, end_timer.tv_usec, -+ end_timer.tv_usec); -+ } -+ } else if (vff_len == left_len) { -+ flush_irq_counter = 0; -+/*clear interrupt flag*/ -+ BTIF_CLR_BIT(TX_DMA_INT_FLAG(base), TX_DMA_INT_FLAG_MASK); -+/*vFIFO data has been read by DMA controller, just disable tx dma's irq*/ -+ i_ret = hal_btif_dma_ier_ctrl(p_dma_info, false); -+ } else { -+#if 0 -+ BTIF_ERR_FUNC -+ ("**********************WARNING**************************\n"); -+ BTIF_ERR_FUNC("invalid irq condition, dump register\n"); -+ hal_dma_dump_reg(p_dma_info, REG_TX_DMA_ALL); -+#endif -+ BTIF_DBG_FUNC -+ ("superious IRQ occurs, vff_len(%d), valid_size(%d), left_len(%d)\n", -+ vff_len, valid_size, left_len); -+ } -+ -+ spin_unlock_irqrestore(&(g_clk_cg_spinlock), flag); -+ -+ return i_ret; -+} -+ -+/***************************************************************************** -+* FUNCTION -+* hal_dma_send_data -+* DESCRIPTION -+* send data through btif in DMA mode -+* PARAMETERS -+* p_dma_info [IN] pointer to BTIF dma channel's information -+* p_buf [IN] pointer to rx data buffer -+* max_len [IN] tx buffer length -+* RETURNS -+* 0 means success, negative means fail -+*****************************************************************************/ -+int hal_dma_send_data(P_MTK_DMA_INFO_STR p_dma_info, -+ const unsigned char *p_buf, const unsigned int buf_len) -+{ -+ unsigned int i_ret = -1; -+ unsigned long base = p_dma_info->base; -+ P_DMA_VFIFO p_vfifo = p_dma_info->p_vfifo; -+ unsigned int len_to_send = buf_len; -+ unsigned int ava_len = 0; -+ unsigned int wpt = 0; -+ unsigned int last_wpt_wrap = 0; -+ unsigned int vff_size = 0; -+ unsigned char *p_data = (unsigned char *)p_buf; -+ P_MTK_BTIF_DMA_VFIFO p_mtk_vfifo = container_of(p_vfifo, -+ MTK_BTIF_DMA_VFIFO, -+ vfifo); -+ -+ BTIF_TRC_FUNC(); -+ if ((p_buf == NULL) || (buf_len == 0)) { -+ i_ret = ERR_INVALID_PAR; -+ BTIF_ERR_FUNC("invalid parameters, p_buf:0x%p, buf_len:%d\n", -+ p_buf, buf_len); -+ return i_ret; -+ } -+/*check if tx dma in flush operation? if yes, should wait until DMA finish flush operation*/ -+/*currently uplayer logic will make sure this pre-condition*/ -+/*disable Tx IER, in case Tx irq happens, flush bit may be set in irq handler*/ -+ btif_tx_dma_ier_ctrl(p_dma_info, false); -+ -+ vff_size = p_mtk_vfifo->vfifo.vfifo_size; -+ ava_len = BTIF_READ32(TX_DMA_VFF_LEFT_SIZE(base)); -+ wpt = BTIF_READ32(TX_DMA_VFF_WPT(base)) & DMA_WPT_MASK; -+ last_wpt_wrap = BTIF_READ32(TX_DMA_VFF_WPT(base)) & DMA_WPT_WRAP; -+ -+/* -+ * copy data to vFIFO, Note: ava_len should always large than buf_len, -+ * otherwise common logic layer will not call hal_dma_send_data -+ */ -+ if (buf_len > ava_len) { -+ BTIF_ERR_FUNC -+ ("length to send:(%d) < length available(%d), abnormal!!!---!!!\n", -+ buf_len, ava_len); -+ WARN_ON(buf_len > ava_len); /* this will cause kernel panic */ -+ } -+ -+ len_to_send = buf_len < ava_len ? buf_len : ava_len; -+ if (len_to_send + wpt >= vff_size) { -+ unsigned int tail_len = vff_size - wpt; -+ -+ memcpy((p_mtk_vfifo->vfifo.p_vir_addr + wpt), p_data, tail_len); -+ p_data += tail_len; -+ memcpy(p_mtk_vfifo->vfifo.p_vir_addr, -+ p_data, len_to_send - tail_len); -+/*make sure all data write to memory area tx vfifo locates*/ -+ mb(); -+ -+/*calculate WPT*/ -+ wpt = wpt + len_to_send - vff_size; -+ last_wpt_wrap ^= DMA_WPT_WRAP; -+ } else { -+ memcpy((p_mtk_vfifo->vfifo.p_vir_addr + wpt), -+ p_data, len_to_send); -+/*make sure all data write to memory area tx vfifo locates*/ -+ mb(); -+ -+/*calculate WPT*/ -+ wpt += len_to_send; -+ } -+ p_mtk_vfifo->wpt = wpt; -+ p_mtk_vfifo->last_wpt_wrap = last_wpt_wrap; -+ -+/*make sure tx dma is allowed(tx flush bit is not set) to use before update WPT*/ -+ if (hal_dma_is_tx_allow(p_dma_info)) { -+ /*make sure tx dma enabled*/ -+ hal_btif_dma_ctrl(p_dma_info, DMA_CTRL_ENABLE); -+ -+ /*update WTP to Tx DMA controller's control register*/ -+ btif_reg_sync_writel(wpt | last_wpt_wrap, TX_DMA_VFF_WPT(base)); -+ -+ if ((BTIF_READ32(TX_DMA_VFF_VALID_SIZE(base)) < 8) && -+ (BTIF_READ32(TX_DMA_VFF_VALID_SIZE(base)) > 0)) { -+ /* -+ * 0 < valid size in Tx vFIFO < 8 && TX Flush is not in process? -+ * if yes, set flush bit to DMA -+ */ -+ _tx_dma_flush(p_dma_info); -+ } -+ i_ret = len_to_send; -+ } else { -+/*TODO: print error log*/ -+ BTIF_ERR_FUNC("Tx DMA flush operation is in process, this case should never happen,", -+ "please check if tx operation is allowed before call this API\n"); -+/*if flush operation is in process , we will return 0*/ -+ i_ret = 0; -+ } -+ -+/*Enable Tx IER*/ -+ btif_tx_dma_ier_ctrl(p_dma_info, true); -+ -+ BTIF_TRC_FUNC(); -+ return i_ret; -+} -+ -+/***************************************************************************** -+* FUNCTION -+* hal_dma_is_tx_complete -+* DESCRIPTION -+* get tx complete flag -+* PARAMETERS -+* p_dma_info [IN] pointer to BTIF dma channel's information -+* RETURNS -+* true means tx complete, false means tx in process -+*****************************************************************************/ -+bool hal_dma_is_tx_complete(P_MTK_DMA_INFO_STR p_dma_info) -+{ -+ bool b_ret = -1; -+ unsigned long base = p_dma_info->base; -+ unsigned int valid_size = BTIF_READ32(TX_DMA_VFF_VALID_SIZE(base)); -+ unsigned int inter_size = BTIF_READ32(TX_DMA_INT_BUF_SIZE(base)); -+ unsigned int tx_done = is_tx_dma_irq_finish_done(p_dma_info); -+ -+/* -+ * only when virtual FIFO valid size and Tx channel internal buffer size are both becomes to be 0, -+ * we can identify tx operation finished -+ * confirmed with DE. -+ */ -+ if ((valid_size == 0) && (inter_size == 0) && (tx_done == 1)) { -+ b_ret = true; -+ BTIF_DBG_FUNC("DMA tx finished.\n"); -+ } else { -+ BTIF_DBG_FUNC -+ ("DMA tx is in process. vfifo valid size(%d), dma internal size (%d), tx_done(%d)\n", -+ valid_size, inter_size, tx_done); -+ b_ret = false; -+ } -+ -+ return b_ret; -+} -+ -+/***************************************************************************** -+* FUNCTION -+* hal_dma_get_ava_room -+* DESCRIPTION -+* get tx available room -+* PARAMETERS -+* p_dma_info [IN] pointer to BTIF dma channel's information -+* RETURNS -+* available room size -+*****************************************************************************/ -+int hal_dma_get_ava_room(P_MTK_DMA_INFO_STR p_dma_info) -+{ -+ int i_ret = -1; -+ unsigned long base = p_dma_info->base; -+ -+/*read vFIFO's left size*/ -+ i_ret = BTIF_READ32(TX_DMA_VFF_LEFT_SIZE(base)); -+ BTIF_DBG_FUNC("DMA tx ava room (%d).\n", i_ret); -+ if (i_ret == 0) -+ BTIF_INFO_FUNC("DMA tx vfifo is full.\n"); -+ -+ return i_ret; -+} -+ -+/***************************************************************************** -+* FUNCTION -+* hal_dma_is_tx_allow -+* DESCRIPTION -+* is tx operation allowed by DMA -+* PARAMETERS -+* p_dma_info [IN] pointer to BTIF dma channel's information -+* RETURNS -+* true if tx operation is allowed; false if tx is not allowed -+*****************************************************************************/ -+bool hal_dma_is_tx_allow(P_MTK_DMA_INFO_STR p_dma_info) -+{ -+#define MIN_TX_MB ((26 * 1000000 / 13) / 1000000) -+#define AVE_TX_MB ((26 * 1000000 / 8) / 1000000) -+ -+ bool b_ret = false; -+ unsigned int wait_us = 8 / MIN_TX_MB; /*only ava length */ -+/*see if flush operation is in process*/ -+ b_ret = _is_tx_dma_in_flush(p_dma_info) ? false : true; -+ if (!b_ret) { -+ usleep_range(wait_us, 2 * wait_us); -+ b_ret = _is_tx_dma_in_flush(p_dma_info) ? false : true; -+ } -+ if (!b_ret) -+ BTIF_WARN_FUNC("btif tx dma is not allowed\n"); -+/*after Tx flush operation finished, HW will set DMA_EN back to 0 and stop DMA*/ -+ return b_ret; -+} -+ -+ -+/***************************************************************************** -+* FUNCTION -+* hal_rx_dma_irq_handler -+* DESCRIPTION -+* lower level rx interrupt handler -+* PARAMETERS -+* p_dma_info [IN] pointer to BTIF dma channel's information -+* p_buf [IN/OUT] pointer to rx data buffer -+* max_len [IN] max length of rx buffer -+* RETURNS -+* 0 means success, negative means fail -+*****************************************************************************/ -+int hal_rx_dma_irq_handler(P_MTK_DMA_INFO_STR p_dma_info, -+ unsigned char *p_buf, const unsigned int max_len) -+{ -+ int i_ret = -1; -+ unsigned int valid_len = 0; -+ unsigned int wpt_wrap = 0; -+ unsigned int rpt_wrap = 0; -+ unsigned int wpt = 0; -+ unsigned int rpt = 0; -+ unsigned int tail_len = 0; -+ unsigned int real_len = 0; -+ unsigned long base = p_dma_info->base; -+ P_DMA_VFIFO p_vfifo = p_dma_info->p_vfifo; -+ dma_rx_buf_write rx_cb = p_dma_info->rx_cb; -+ unsigned char *p_vff_buf = NULL; -+ unsigned char *vff_base = p_vfifo->p_vir_addr; -+ unsigned int vff_size = p_vfifo->vfifo_size; -+ P_MTK_BTIF_DMA_VFIFO p_mtk_vfifo = container_of(p_vfifo, -+ MTK_BTIF_DMA_VFIFO, -+ vfifo); -+ unsigned long flag = 0; -+ -+ spin_lock_irqsave(&(g_clk_cg_spinlock), flag); -+#if defined(CONFIG_MTK_CLKMGR) -+ if (clock_is_on(MTK_BTIF_APDMA_CLK_CG) == 0) { -+ spin_unlock_irqrestore(&(g_clk_cg_spinlock), flag); -+ BTIF_ERR_FUNC("%s: clock is off before irq handle done!!!\n", -+ __FILE__); -+ return i_ret; -+ } -+#endif -+/*disable DMA Rx IER*/ -+ hal_btif_dma_ier_ctrl(p_dma_info, false); -+ -+/*clear Rx DMA's interrupt status*/ -+ BTIF_SET_BIT(RX_DMA_INT_FLAG(base), RX_DMA_INT_DONE | RX_DMA_INT_THRE); -+ -+ valid_len = BTIF_READ32(RX_DMA_VFF_VALID_SIZE(base)); -+ rpt = BTIF_READ32(RX_DMA_VFF_RPT(base)); -+ wpt = BTIF_READ32(RX_DMA_VFF_WPT(base)); -+ if ((valid_len == 0) && (rpt == wpt)) { -+ BTIF_DBG_FUNC -+ ("rx interrupt, no data available in Rx DMA, wpt(0x%08x), rpt(0x%08x)\n", -+ rpt, wpt); -+ } -+ -+ i_ret = 0; -+ -+ while ((valid_len > 0) || (rpt != wpt)) { -+ rpt_wrap = rpt & DMA_RPT_WRAP; -+ wpt_wrap = wpt & DMA_WPT_WRAP; -+ rpt &= DMA_RPT_MASK; -+ wpt &= DMA_WPT_MASK; -+ -+/*calcaute length of available data in vFIFO*/ -+ if (wpt_wrap != p_mtk_vfifo->last_wpt_wrap) -+ real_len = wpt + vff_size - rpt; -+ else -+ real_len = wpt - rpt; -+ -+ if (rx_cb != NULL) { -+ tail_len = vff_size - rpt; -+ p_vff_buf = vff_base + rpt; -+ if (tail_len >= real_len) { -+ (*rx_cb) (p_dma_info, p_vff_buf, real_len); -+ } else { -+ (*rx_cb) (p_dma_info, p_vff_buf, tail_len); -+ p_vff_buf = vff_base; -+ (*rx_cb) (p_dma_info, p_vff_buf, real_len - -+ tail_len); -+ } -+ i_ret += real_len; -+ } else -+ BTIF_ERR_FUNC("no rx_cb found, please check your init process\n"); -+ mb(); -+ rpt += real_len; -+ if (rpt >= vff_size) { -+ /*read wrap bit should be revert*/ -+ rpt_wrap ^= DMA_RPT_WRAP; -+ rpt %= vff_size; -+ } -+ rpt |= rpt_wrap; -+/*record wpt, last_wpt_wrap, rpt, last_rpt_wrap*/ -+ p_mtk_vfifo->wpt = wpt; -+ p_mtk_vfifo->last_wpt_wrap = wpt_wrap; -+ -+ p_mtk_vfifo->rpt = rpt; -+ p_mtk_vfifo->last_rpt_wrap = rpt_wrap; -+ -+/*update rpt information to DMA controller*/ -+ btif_reg_sync_writel(rpt, RX_DMA_VFF_RPT(base)); -+ -+/*get vff valid size again and check if rx data is processed completely*/ -+ valid_len = BTIF_READ32(RX_DMA_VFF_VALID_SIZE(base)); -+ -+ rpt = BTIF_READ32(RX_DMA_VFF_RPT(base)); -+ wpt = BTIF_READ32(RX_DMA_VFF_WPT(base)); -+ } -+ -+/*enable DMA Rx IER*/ -+ hal_btif_dma_ier_ctrl(p_dma_info, true); -+ -+ spin_unlock_irqrestore(&(g_clk_cg_spinlock), flag); -+ -+ return i_ret; -+} -+ -+static int hal_tx_dma_dump_reg(P_MTK_DMA_INFO_STR p_dma_info, -+ ENUM_BTIF_REG_ID flag) -+{ -+ int i_ret = -1; -+ unsigned long base = p_dma_info->base; -+ unsigned int int_flag = 0; -+ unsigned int enable = 0; -+ unsigned int stop = 0; -+ unsigned int flush = 0; -+ unsigned int wpt = 0; -+ unsigned int rpt = 0; -+ unsigned int int_buf = 0; -+ unsigned int valid_size = 0; -+ /*unsigned long irq_flag = 0;*/ -+ -+#if defined(CONFIG_MTK_CLKMGR) -+ /*spin_lock_irqsave(&(g_clk_cg_spinlock), irq_flag);*/ -+ if (clock_is_on(MTK_BTIF_APDMA_CLK_CG) == 0) { -+ /*spin_unlock_irqrestore(&(g_clk_cg_spinlock), irq_flag);*/ -+ BTIF_ERR_FUNC("%s: clock is off, this should never happen!!!\n", -+ __FILE__); -+ return i_ret; -+ } -+#endif -+ int_flag = BTIF_READ32(TX_DMA_INT_FLAG(base)); -+ enable = BTIF_READ32(TX_DMA_EN(base)); -+ stop = BTIF_READ32(TX_DMA_STOP(base)); -+ flush = BTIF_READ32(TX_DMA_FLUSH(base)); -+ wpt = BTIF_READ32(TX_DMA_VFF_WPT(base)); -+ rpt = BTIF_READ32(TX_DMA_VFF_RPT(base)); -+ int_buf = BTIF_READ32(TX_DMA_INT_BUF_SIZE(base)); -+ valid_size = BTIF_READ32(TX_DMA_VFF_VALID_SIZE(base)); -+ /*spin_unlock_irqrestore(&(g_clk_cg_spinlock), irq_flag);*/ -+ -+ BTIF_INFO_FUNC("DMA's clock is on\n"); -+ BTIF_INFO_FUNC("Tx DMA's base address: 0x%lx\n", base); -+ -+ if (flag == REG_TX_DMA_ALL) { -+ BTIF_INFO_FUNC("TX_EN(:0x%x\n", enable); -+ BTIF_INFO_FUNC("INT_FLAG:0x%x\n", int_flag); -+ BTIF_INFO_FUNC("TX_STOP:0x%x\n", stop); -+ BTIF_INFO_FUNC("TX_FLUSH:0x%x\n", flush); -+ BTIF_INFO_FUNC("TX_WPT:0x%x\n", wpt); -+ BTIF_INFO_FUNC("TX_RPT:0x%x\n", rpt); -+ BTIF_INFO_FUNC("INT_BUF_SIZE:0x%x\n", int_buf); -+ BTIF_INFO_FUNC("VALID_SIZE:0x%x\n", valid_size); -+ BTIF_INFO_FUNC("INT_EN:0x%x\n", -+ BTIF_READ32(TX_DMA_INT_EN(base))); -+ BTIF_INFO_FUNC("TX_RST:0x%x\n", BTIF_READ32(TX_DMA_RST(base))); -+ BTIF_INFO_FUNC("VFF_ADDR:0x%x\n", -+ BTIF_READ32(TX_DMA_VFF_ADDR(base))); -+ BTIF_INFO_FUNC("VFF_LEN:0x%x\n", -+ BTIF_READ32(TX_DMA_VFF_LEN(base))); -+ BTIF_INFO_FUNC("TX_THRE:0x%x\n", -+ BTIF_READ32(TX_DMA_VFF_THRE(base))); -+ BTIF_INFO_FUNC("W_INT_BUF_SIZE:0x%x\n", -+ BTIF_READ32(TX_DMA_W_INT_BUF_SIZE(base))); -+ BTIF_INFO_FUNC("LEFT_SIZE:0x%x\n", -+ BTIF_READ32(TX_DMA_VFF_LEFT_SIZE(base))); -+ BTIF_INFO_FUNC("DBG_STATUS:0x%x\n", -+ BTIF_READ32(TX_DMA_DEBUG_STATUS(base))); -+ i_ret = 0; -+ } else { -+ BTIF_WARN_FUNC("unknown flag:%d\n", flag); -+ } -+ BTIF_INFO_FUNC("tx dma %s\n", (enable & DMA_EN_BIT) && -+ (!(stop && DMA_STOP_BIT)) ? "enabled" : "stopped"); -+ BTIF_INFO_FUNC("data in tx dma is %s sent by HW\n", -+ ((wpt == rpt) && -+ (int_buf == 0)) ? "completely" : "not completely"); -+ -+ return i_ret; -+} -+ -+static int hal_rx_dma_dump_reg(P_MTK_DMA_INFO_STR p_dma_info, -+ ENUM_BTIF_REG_ID flag) -+{ -+ int i_ret = -1; -+ unsigned long base = p_dma_info->base; -+ unsigned int int_flag = 0; -+ unsigned int enable = 0; -+ unsigned int stop = 0; -+ unsigned int flush = 0; -+ unsigned int wpt = 0; -+ unsigned int rpt = 0; -+ unsigned int int_buf = 0; -+ unsigned int valid_size = 0; -+ /*unsigned long irq_flag = 0;*/ -+#if defined(CONFIG_MTK_CLKMGR) -+ /*spin_lock_irqsave(&(g_clk_cg_spinlock), irq_flag);*/ -+ if (clock_is_on(MTK_BTIF_APDMA_CLK_CG) == 0) { -+ /*spin_unlock_irqrestore(&(g_clk_cg_spinlock), irq_flag);*/ -+ BTIF_ERR_FUNC("%s: clock is off, this should never happen!!!\n", -+ __FILE__); -+ return i_ret; -+ } -+#endif -+ BTIF_INFO_FUNC("dump DMA status register\n"); -+ _btif_dma_dump_dbg_reg(); -+ -+ int_flag = BTIF_READ32(RX_DMA_INT_FLAG(base)); -+ enable = BTIF_READ32(RX_DMA_EN(base)); -+ stop = BTIF_READ32(RX_DMA_STOP(base)); -+ flush = BTIF_READ32(RX_DMA_FLUSH(base)); -+ wpt = BTIF_READ32(RX_DMA_VFF_WPT(base)); -+ rpt = BTIF_READ32(RX_DMA_VFF_RPT(base)); -+ int_buf = BTIF_READ32(RX_DMA_INT_BUF_SIZE(base)); -+ valid_size = BTIF_READ32(RX_DMA_VFF_VALID_SIZE(base)); -+ /*spin_unlock_irqrestore(&(g_clk_cg_spinlock), irq_flag);*/ -+ -+ BTIF_INFO_FUNC("DMA's clock is on\n"); -+ BTIF_INFO_FUNC("Rx DMA's base address: 0x%lx\n", base); -+ -+ if (flag == REG_RX_DMA_ALL) { -+ BTIF_INFO_FUNC("RX_EN(:0x%x\n", enable); -+ BTIF_INFO_FUNC("RX_STOP:0x%x\n", stop); -+ BTIF_INFO_FUNC("RX_FLUSH:0x%x\n", flush); -+ BTIF_INFO_FUNC("INT_FLAG:0x%x\n", int_flag); -+ BTIF_INFO_FUNC("RX_WPT:0x%x\n", wpt); -+ BTIF_INFO_FUNC("RX_RPT:0x%x\n", rpt); -+ BTIF_INFO_FUNC("INT_BUF_SIZE:0x%x\n", int_buf); -+ BTIF_INFO_FUNC("VALID_SIZE:0x%x\n", valid_size); -+ BTIF_INFO_FUNC("INT_EN:0x%x\n", -+ BTIF_READ32(RX_DMA_INT_EN(base))); -+ BTIF_INFO_FUNC("RX_RST:0x%x\n", BTIF_READ32(RX_DMA_RST(base))); -+ BTIF_INFO_FUNC("VFF_ADDR:0x%x\n", -+ BTIF_READ32(RX_DMA_VFF_ADDR(base))); -+ BTIF_INFO_FUNC("VFF_LEN:0x%x\n", -+ BTIF_READ32(RX_DMA_VFF_LEN(base))); -+ BTIF_INFO_FUNC("RX_THRE:0x%x\n", -+ BTIF_READ32(RX_DMA_VFF_THRE(base))); -+ BTIF_INFO_FUNC("RX_FLOW_CTRL_THRE:0x%x\n", -+ BTIF_READ32(RX_DMA_FLOW_CTRL_THRE(base))); -+ BTIF_INFO_FUNC("LEFT_SIZE:0x%x\n", -+ BTIF_READ32(RX_DMA_VFF_LEFT_SIZE(base))); -+ BTIF_INFO_FUNC("DBG_STATUS:0x%x\n", -+ BTIF_READ32(RX_DMA_DEBUG_STATUS(base))); -+ i_ret = 0; -+ } else { -+ BTIF_WARN_FUNC("unknown flag:%d\n", flag); -+ } -+ BTIF_INFO_FUNC("rx dma %s\n", (enable & DMA_EN_BIT) && -+ (!(stop && DMA_STOP_BIT)) ? "enabled" : "stopped"); -+ BTIF_INFO_FUNC("data in rx dma is %s by driver\n", -+ ((wpt == rpt) && -+ (int_buf == 0)) ? "received" : "not received"); -+ -+ return i_ret; -+} -+ -+/***************************************************************************** -+* FUNCTION -+* hal_dma_dump_reg -+* DESCRIPTION -+* dump BTIF module's information when needed -+* PARAMETERS -+* p_dma_info [IN] pointer to BTIF dma channel's information -+* flag [IN] register id flag -+* RETURNS -+* 0 means success, negative means fail -+*****************************************************************************/ -+int hal_dma_dump_reg(P_MTK_DMA_INFO_STR p_dma_info, ENUM_BTIF_REG_ID flag) -+{ -+ unsigned int i_ret = -1; -+ -+ if (p_dma_info->dir == DMA_DIR_TX) -+ i_ret = hal_tx_dma_dump_reg(p_dma_info, flag); -+ else if (p_dma_info->dir == DMA_DIR_RX) -+ i_ret = hal_rx_dma_dump_reg(p_dma_info, flag); -+ else -+ BTIF_WARN_FUNC("unknown dir:%d\n", p_dma_info->dir); -+ -+ return i_ret; -+} -+ -+static int _tx_dma_flush(P_MTK_DMA_INFO_STR p_dma_info) -+{ -+ unsigned int i_ret = -1; -+ unsigned long base = p_dma_info->base; -+ unsigned int stop = BTIF_READ32(TX_DMA_STOP(base)); -+ -+/*in MTK DMA BTIF channel we cannot set STOP and FLUSH bit at the same time*/ -+ if ((stop && DMA_STOP_BIT) != 0) -+ BTIF_ERR_FUNC("BTIF's DMA in stop state, omit flush operation\n"); -+ else { -+ BTIF_DBG_FUNC("flush tx dma\n"); -+ BTIF_SET_BIT(TX_DMA_FLUSH(base), DMA_FLUSH_BIT); -+ i_ret = 0; -+ } -+ return i_ret; -+} -+ -+static int _is_tx_dma_in_flush(P_MTK_DMA_INFO_STR p_dma_info) -+{ -+ bool b_ret = true; -+ unsigned long base = p_dma_info->base; -+ -+/*see if flush operation is in process*/ -+ b_ret = ((DMA_FLUSH_BIT & BTIF_READ32(TX_DMA_FLUSH(base))) != 0) ? true : false; -+ -+ return b_ret; -+} -+ -+int hal_dma_pm_ops(P_MTK_DMA_INFO_STR p_dma_info, MTK_BTIF_PM_OPID opid) -+{ -+ int i_ret = -1; -+ -+ BTIF_INFO_FUNC("op id: %d\n", opid); -+ switch (opid) { -+ case BTIF_PM_DPIDLE_EN: -+ i_ret = 0; -+ break; -+ case BTIF_PM_DPIDLE_DIS: -+ i_ret = 0; -+ break; -+ case BTIF_PM_SUSPEND: -+ i_ret = 0; -+ break; -+ case BTIF_PM_RESUME: -+ i_ret = 0; -+ break; -+ case BTIF_PM_RESTORE_NOIRQ:{ -+ unsigned int flag = 0; -+ P_MTK_BTIF_IRQ_STR p_irq = p_dma_info->p_irq; -+ -+#ifdef CONFIG_OF -+ flag = p_irq->irq_flags; -+#else -+ switch (p_irq->sens_type) { -+ case IRQ_SENS_EDGE: -+ if (p_irq->edge_type == IRQ_EDGE_FALL) -+ flag = IRQF_TRIGGER_FALLING; -+ else if (p_irq->edge_type == IRQ_EDGE_RAISE) -+ flag = IRQF_TRIGGER_RISING; -+ else if (p_irq->edge_type == IRQ_EDGE_BOTH) -+ flag = IRQF_TRIGGER_RISING | -+ IRQF_TRIGGER_FALLING; -+ else -+ flag = IRQF_TRIGGER_FALLING; /*make this as default type */ -+ break; -+ case IRQ_SENS_LVL: -+ if (p_irq->lvl_type == IRQ_LVL_LOW) -+ flag = IRQF_TRIGGER_LOW; -+ else if (p_irq->lvl_type == IRQ_LVL_HIGH) -+ flag = IRQF_TRIGGER_HIGH; -+ else -+ flag = IRQF_TRIGGER_LOW; /*make this as default type */ -+ break; -+ default: -+ flag = IRQF_TRIGGER_LOW; /*make this as default type */ -+ break; -+ } -+#endif -+/* irq_set_irq_type(p_irq->irq_id, flag); */ -+ i_ret = 0; -+ } -+ i_ret = 0; -+ break; -+ default: -+ i_ret = ERR_INVALID_PAR; -+ break; -+ } -+ -+ return i_ret; -+} -+ -+/***************************************************************************** -+* FUNCTION -+* hal_dma_receive_data -+* DESCRIPTION -+* receive data from btif module in DMA polling mode -+* PARAMETERS -+* p_dma_info [IN] pointer to BTIF dma channel's information -+* p_buf [IN/OUT] pointer to rx data buffer -+* max_len [IN] max length of rx buffer -+* RETURNS -+* positive means data is available, 0 means no data available -+*****************************************************************************/ -+#ifndef MTK_BTIF_MARK_UNUSED_API -+int hal_dma_receive_data(P_MTK_DMA_INFO_STR p_dma_info, -+ unsigned char *p_buf, const unsigned int max_len) -+{ -+ unsigned int i_ret = -1; -+ -+ return i_ret; -+} -+#endif -+ -+int _btif_dma_dump_dbg_reg(void) -+{ -+#if 0 -+ static MTK_BTIF_DMA_REG_DMP_DBG g_dma_dbg_regs[] = { -+ {0x10201180, 0x0}, -+ {0x10201184, 0x0}, -+ {0x10201188, 0x0}, -+ {0x1020118C, 0x0}, -+ {0x10201190, 0x0}, -+ {0x1000320C, 0x0}, -+ {0x10003210, 0x0}, -+ {0x10003214, 0x0}, -+ }; -+ -+ int i = 0; -+ char *addr1 = NULL; -+ char *addr2 = NULL; -+ -+ int array_num = ARRAY_SIZE(g_dma_dbg_regs) -+ -+ addr1 = ioremap(g_dma_dbg_regs[0].reg_addr, 0x20); -+ if (addr1) { -+ for (i = 0; i < 5; i++) -+ g_dma_dbg_regs[i].reg_val = *(volatile unsigned int*)(addr1 + i*4); -+ iounmap(addr1); -+ } -+ -+ addr2 = ioremap(g_dma_dbg_regs[5].reg_addr, 0x10); -+ if (addr2) { -+ g_dma_dbg_regs[5].reg_val = *(volatile unsigned int*)(addr2); -+ g_dma_dbg_regs[6].reg_val = *(volatile unsigned int*)(addr2+4); -+ g_dma_dbg_regs[7].reg_val = *(volatile unsigned int*)(addr2+8); -+ iounmap(addr2); -+ } -+ -+ for (i = 0; i < array_num; i++) -+ BTIF_INFO_FUNC("-<0x%lx, 0x%08x>\n", g_dma_dbg_regs[i].reg_addr, g_dma_dbg_regs[i].reg_val); -+#endif -+ return 0; -+} -+ -+static void hal_btif_tx_dma_vff_set_for_4g(void) -+{ -+ BTIF_DBG_FUNC("Set btif tx_vff_addr bit29\n"); -+ BTIF_SET_BIT(TX_DMA_VFF_ADDR_H(mtk_btif_tx_dma.base), DMA_VFF_BIT29_OFFSET); -+ BTIF_DBG_FUNC("Dump value of bit29 0x%x:(0x%x)\n", TX_DMA_VFF_ADDR_H(mtk_btif_tx_dma.base), -+ BTIF_READ32(TX_DMA_VFF_ADDR_H(mtk_btif_tx_dma.base))); -+} -+static void hal_btif_rx_dma_vff_set_for_4g(void) -+{ -+ BTIF_DBG_FUNC("Set btif rx_vff_addr bit29\n"); -+ BTIF_SET_BIT(RX_DMA_VFF_ADDR_H(mtk_btif_rx_dma.base), DMA_VFF_BIT29_OFFSET); -+ BTIF_DBG_FUNC("Dump value of bit29 0x%x:(0x%x)\n", RX_DMA_VFF_ADDR_H(mtk_btif_rx_dma.base), -+ BTIF_READ32(RX_DMA_VFF_ADDR_H(mtk_btif_rx_dma.base))); -+} -+ -diff --git a/drivers/misc/mediatek/btif/common/btif_plat.c b/drivers/misc/mediatek/btif/common/btif_plat.c -new file mode 100644 -index 000000000000..e098e902317c ---- /dev/null -+++ b/drivers/misc/mediatek/btif/common/btif_plat.c -@@ -0,0 +1,1396 @@ -+/* -+ * Copyright (C) 2015 MediaTek Inc. -+ * -+ * 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. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#ifdef DFT_TAG -+#undef DFT_TAG -+#endif -+#define DFT_TAG "MTK-BTIF" -+ -+#define NEW_TX_HANDLING_SUPPORT 1 -+ -+#include "btif_pub.h" -+#include "btif_priv.h" -+ -+#define BTIF_USER_ID "btif_driver" -+ -+static spinlock_t g_clk_cg_spinlock; /*BTIF clock's spinlock */ -+ -+/*-----------------------------BTIF Module Clock and Power Control Defination------------------*/ -+ -+MTK_BTIF_IRQ_STR mtk_btif_irq = { -+ .name = "mtk btif irq", -+ .is_irq_sup = true, -+ .reg_flag = false, -+#ifdef CONFIG_OF -+ .irq_flags = IRQF_TRIGGER_NONE, -+#else -+ .irq_id = MT_BTIF_IRQ_ID, -+ .sens_type = IRQ_SENS_LVL, -+ .lvl_type = IRQ_LVL_LOW, -+#endif -+ .p_irq_handler = NULL, -+}; -+ -+/* -+ * will call clock manager's API export by WCP to control BTIF's clock, -+ * but we may need to access these registers in case of btif clock control logic is wrong in clock manager -+ */ -+ -+MTK_BTIF_INFO_STR mtk_btif = { -+#ifndef CONFIG_OF -+ .base = MTK_BTIF_REG_BASE, -+#endif -+ .p_irq = &mtk_btif_irq, -+ .tx_fifo_size = BTIF_TX_FIFO_SIZE, -+ .rx_fifo_size = BTIF_RX_FIFO_SIZE, -+ .tx_tri_lvl = BTIF_TX_FIFO_THRE, -+ .rx_tri_lvl = BTIF_RX_FIFO_THRE, -+ .rx_data_len = 0, -+ .p_tx_fifo = NULL, -+}; -+#if !(NEW_TX_HANDLING_SUPPORT) -+static bool _btif_is_tx_allow(P_MTK_BTIF_INFO_STR p_btif); -+#endif -+ -+static int btif_rx_irq_handler(P_MTK_BTIF_INFO_STR p_btif_info, -+ unsigned char *p_buf, -+ const unsigned int max_len); -+static int btif_tx_irq_handler(P_MTK_BTIF_INFO_STR p_btif); -+ -+/***************************************************************************** -+* FUNCTION -+* hal_btif_rx_ier_ctrl -+* DESCRIPTION -+* BTIF Rx interrupt enable/disable -+* PARAMETERS -+* p_base [IN] BTIF module's base address -+* enable [IN] control if rx interrupt enabled or not -+* RETURNS -+* 0 means success, negative means fail -+*****************************************************************************/ -+static int hal_btif_rx_ier_ctrl(P_MTK_BTIF_INFO_STR p_btif, bool en); -+ -+/***************************************************************************** -+* FUNCTION -+* hal_btif_tx_ier_ctrl -+* DESCRIPTION -+* BTIF Tx interrupt enable/disable -+* PARAMETERS -+* p_base [IN] BTIF module's base address -+* enable [IN] control if tx interrupt enabled or not -+* RETURNS -+* 0 means success, negative means fail -+*****************************************************************************/ -+static int hal_btif_tx_ier_ctrl(P_MTK_BTIF_INFO_STR p_btif, bool en); -+ -+#ifndef MTK_BTIF_MARK_UNUSED_API -+static int btif_sleep_ctrl(P_MTK_BTIF_INFO_STR p_btif, bool en); -+ -+/***************************************************************************** -+* FUNCTION -+* _btif_receive_data -+* DESCRIPTION -+* receive data from btif module in FIFO polling mode -+* PARAMETERS -+* p_base [IN] BTIF module's base address -+* p_buf [IN/OUT] pointer to rx data buffer -+* max_len [IN] max length of rx buffer -+* RETURNS -+* positive means data is available, 0 means no data available -+*****************************************************************************/ -+static int _btif_receive_data(P_MTK_BTIF_INFO_STR p_btif, -+ unsigned char *p_buf, const unsigned int max_len); -+static int btif_tx_thr_set(P_MTK_BTIF_INFO_STR p_btif, unsigned int thr_count); -+#endif -+ -+static int btif_dump_array(char *string, char *p_buf, int len) -+{ -+ unsigned int idx = 0; -+ unsigned char str[30]; -+ unsigned char *p_str; -+ -+ pr_debug("========dump %s start ========\n", string, len); -+ p_str = &str[0]; -+ for (idx = 0; idx < len; idx++, p_buf++) { -+ sprintf(p_str, "%02x ", *p_buf); -+ p_str += 3; -+ if (7 == (idx % 8)) { -+ *p_str++ = '\n'; -+ *p_str = '\0'; -+ pr_debug("%s", str); -+ p_str = &str[0]; -+ } -+ } -+ if (len % 8) { -+ *p_str++ = '\n'; -+ *p_str = '\0'; -+ pr_debug("%s", str); -+ } -+ pr_debug("========dump %s end========\n", string); -+ return 0; -+} -+ -+#if NEW_TX_HANDLING_SUPPORT -+static int _btif_tx_fifo_init(P_MTK_BTIF_INFO_STR p_btif_info) -+{ -+ int i_ret = -1; -+ -+ spin_lock_init(&(p_btif_info->tx_fifo_spinlock)); -+ -+ if (p_btif_info->p_tx_fifo == NULL) { -+ p_btif_info->p_tx_fifo = kzalloc(sizeof(struct kfifo), -+ GFP_ATOMIC); -+ if (p_btif_info->p_tx_fifo == NULL) { -+ i_ret = -ENOMEM; -+ BTIF_ERR_FUNC("kzalloc for p_btif->p_tx_fifo failed\n"); -+ goto ret; -+ } -+ -+ i_ret = kfifo_alloc(p_btif_info->p_tx_fifo, -+ BTIF_HAL_TX_FIFO_SIZE, GFP_ATOMIC); -+ if (i_ret != 0) { -+ BTIF_ERR_FUNC("kfifo_alloc failed, errno(%d)\n", i_ret); -+ i_ret = -ENOMEM; -+ goto ret; -+ } -+ i_ret = 0; -+ } else { -+ BTIF_WARN_FUNC -+ ("p_btif_info->p_tx_fifo is already init p_btif_info->p_tx_fifo(0x%p)\n", -+ p_btif_info->p_tx_fifo); -+ i_ret = 0; -+ } -+ret: -+ return i_ret; -+} -+ -+static int _get_btif_tx_fifo_room(P_MTK_BTIF_INFO_STR p_btif_info) -+{ -+ int i_ret = 0; -+ unsigned long flag = 0; -+ -+ spin_lock_irqsave(&(p_btif_info->tx_fifo_spinlock), flag); -+ if (p_btif_info->p_tx_fifo == NULL) -+ i_ret = 0; -+ else -+ i_ret = kfifo_avail(p_btif_info->p_tx_fifo); -+ spin_unlock_irqrestore(&(p_btif_info->tx_fifo_spinlock), flag); -+ BTIF_DBG_FUNC("tx kfifo:0x%p, available room:%d\n", p_btif_info->p_tx_fifo, i_ret); -+ return i_ret; -+} -+ -+static int _btif_tx_fifo_reset(P_MTK_BTIF_INFO_STR p_btif_info) -+{ -+ int i_ret = 0; -+ -+ if (p_btif_info->p_tx_fifo != NULL) -+ kfifo_reset(p_btif_info->p_tx_fifo); -+ return i_ret; -+} -+ -+#endif -+ -+#ifdef CONFIG_OF -+static void _btif_set_default_setting(void) -+{ -+ struct device_node *node = NULL; -+ unsigned int irq_info[3] = {0, 0, 0}; -+ unsigned int phy_base; -+ -+ node = of_find_compatible_node(NULL, NULL, "mediatek,mtk-btif"); -+ if (node) { -+ mtk_btif.p_irq->irq_id = irq_of_parse_and_map(node, 0); -+ /*fixme, be compitable arch 64bits*/ -+ mtk_btif.base = (unsigned long)of_iomap(node, 0); -+ BTIF_INFO_FUNC("get btif irq(%d),register base(0x%lx)\n", -+ mtk_btif.p_irq->irq_id, mtk_btif.base); -+ } else { -+ BTIF_ERR_FUNC("get btif device node fail\n"); -+ } -+ -+ /* get the interrupt line behaviour */ -+ if (of_property_read_u32_array(node, "interrupts", irq_info, ARRAY_SIZE(irq_info))) { -+ BTIF_ERR_FUNC("get interrupt flag from DTS fail\n"); -+ } else { -+ mtk_btif.p_irq->irq_flags = irq_info[2]; -+ BTIF_INFO_FUNC("get interrupt flag(0x%x)\n", mtk_btif.p_irq->irq_flags); -+ } -+ -+ if (of_property_read_u32_index(node, "reg", 1, &phy_base)) -+ BTIF_ERR_FUNC("get register phy base from DTS fail\n"); -+ else -+ BTIF_INFO_FUNC("get register phy base(0x%x)\n", (unsigned int)phy_base); -+} -+#endif -+ -+/***************************************************************************** -+* FUNCTION -+* hal_btif_info_get -+* DESCRIPTION -+* get btif's information included base address , irq related information -+* PARAMETERS -+* RETURNS -+* BTIF's information -+*****************************************************************************/ -+P_MTK_BTIF_INFO_STR hal_btif_info_get(void) -+{ -+#if NEW_TX_HANDLING_SUPPORT -+ int i_ret = 0; -+/*tx fifo and fifo lock init*/ -+ i_ret = _btif_tx_fifo_init(&mtk_btif); -+ if (i_ret == 0) -+ BTIF_INFO_FUNC("_btif_tx_fifo_init succeed\n"); -+ else -+ BTIF_ERR_FUNC("_btif_tx_fifo_init failed, i_ret:%d\n", i_ret); -+ -+#endif -+ -+#ifdef CONFIG_OF -+ _btif_set_default_setting(); -+#endif -+ -+ spin_lock_init(&g_clk_cg_spinlock); -+ -+ return &mtk_btif; -+} -+/***************************************************************************** -+* FUNCTION -+* hal_btif_clk_get_and_prepare -+* DESCRIPTION -+* get clock from device tree and prepare for enable/disable control -+* PARAMETERS -+* pdev device pointer -+* RETURNS -+* 0 means success, negative means fail -+*****************************************************************************/ -+#if !defined(CONFIG_MTK_CLKMGR) -+int hal_btif_clk_get_and_prepare(struct platform_device *pdev) -+{ -+ int i_ret = -1; -+ -+ clk_btif = devm_clk_get(&pdev->dev, "main"); -+ if (IS_ERR(clk_btif)) { -+ BTIF_ERR_FUNC("[CCF]cannot get clk_btif clock.\n"); -+ return PTR_ERR(clk_btif); -+ } -+ BTIF_ERR_FUNC("[CCF]clk_btif=%p\n", clk_btif); -+ clk_btif_apdma = devm_clk_get(&pdev->dev, "apdmac"); -+ if (IS_ERR(clk_btif_apdma)) { -+ BTIF_ERR_FUNC("[CCF]cannot get clk_btif_apdma clock.\n"); -+ return PTR_ERR(clk_btif_apdma); -+ } -+ BTIF_ERR_FUNC("[CCF]clk_btif_apdma=%p\n", clk_btif_apdma); -+ -+ i_ret = clk_prepare(clk_btif); -+ if (i_ret != 0) { -+ BTIF_ERR_FUNC("clk_prepare clk_btif failed! ret:%d\n", i_ret); -+ return i_ret; -+ } -+ -+ i_ret = clk_prepare(clk_btif_apdma); -+ if (i_ret != 0) { -+ BTIF_ERR_FUNC("clk_prepare clk_btif_apdma failed! ret:%d\n", i_ret); -+ return i_ret; -+ } -+ return i_ret; -+} -+/***************************************************************************** -+* FUNCTION -+* hal_btif_clk_unprepare -+* DESCRIPTION -+* unprepare btif clock and apdma clock -+* PARAMETERS -+* none -+* RETURNS -+* 0 means success, negative means fail -+*****************************************************************************/ -+int hal_btif_clk_unprepare(void) -+{ -+ clk_unprepare(clk_btif); -+ clk_unprepare(clk_btif_apdma); -+ return 0; -+} -+#endif -+/***************************************************************************** -+* FUNCTION -+* hal_btif_clk_ctrl -+* DESCRIPTION -+* control clock output enable/disable of BTIF module -+* PARAMETERS -+* p_base [IN] BTIF module's base address -+* RETURNS -+* 0 means success, negative means fail -+*****************************************************************************/ -+int hal_btif_clk_ctrl(P_MTK_BTIF_INFO_STR p_btif, ENUM_CLOCK_CTRL flag) -+{ -+/*In MTK BTIF, there's only one global CG on AP_DMA, no sub channel's CG bit*/ -+/*according to Artis's comment, clock of DMA and BTIF is default off, so we assume it to be off by default*/ -+ int i_ret = 0; -+ unsigned long irq_flag = 0; -+ -+#if MTK_BTIF_ENABLE_CLK_REF_COUNTER -+ static atomic_t s_clk_ref = ATOMIC_INIT(0); -+#else -+ static ENUM_CLOCK_CTRL status = CLK_OUT_DISABLE; -+#endif -+ -+ spin_lock_irqsave(&(g_clk_cg_spinlock), irq_flag); -+ -+#if MTK_BTIF_ENABLE_CLK_CTL -+ -+#if MTK_BTIF_ENABLE_CLK_REF_COUNTER -+ -+ if (flag == CLK_OUT_ENABLE) { -+ if (atomic_inc_return(&s_clk_ref) == 1) { -+#if defined(CONFIG_MTK_CLKMGR) -+ i_ret = enable_clock(MTK_BTIF_CG_BIT, BTIF_USER_ID); -+#else -+ BTIF_DBG_FUNC("[CCF]enable clk_btif\n"); -+ i_ret = clk_enable(clk_btif); -+#endif /* defined(CONFIG_MTK_CLKMGR) */ -+ if (i_ret) { -+ BTIF_WARN_FUNC -+ ("enable_clock for MTK_BTIF_CG_BIT failed, ret:%d", -+ i_ret); -+ } -+ } -+ } else if (flag == CLK_OUT_DISABLE) { -+ if (atomic_dec_return(&s_clk_ref) == 0) { -+#if defined(CONFIG_MTK_CLKMGR) -+ i_ret = disable_clock(MTK_BTIF_CG_BIT, BTIF_USER_ID); -+ if (i_ret) { -+ BTIF_WARN_FUNC -+ ("disable_clock for MTK_BTIF_CG_BIT failed, ret:%d", -+ i_ret); -+ } -+#else -+ BTIF_DBG_FUNC("[CCF] clk_disable(clk_btif) calling\n"); -+ clk_disable(clk_btif); -+#endif /* defined(CONFIG_MTK_CLKMGR) */ -+ } -+ } else { -+ i_ret = ERR_INVALID_PAR; -+ BTIF_ERR_FUNC("invalid clock ctrl flag (%d)\n", flag); -+ } -+ -+#else -+ -+ if (status == flag) { -+ i_ret = 0; -+ BTIF_DBG_FUNC("btif clock already %s\n", -+ CLK_OUT_ENABLE == -+ status ? "enabled" : "disabled"); -+ } else { -+ if (flag == CLK_OUT_ENABLE) { -+#if defined(CONFIG_MTK_CLKMGR) -+ i_ret = enable_clock(MTK_BTIF_CG_BIT, BTIF_USER_ID); -+#else -+ BTIF_DBG_FUNC("[CCF]enable clk_btif\n"); -+ i_ret = clk_enable(clk_btif); -+#endif /* defined(CONFIG_MTK_CLKMGR) */ -+ status = (i_ret == 0) ? flag : status; -+ if (i_ret) { -+ BTIF_WARN_FUNC -+ ("enable_clock for MTK_BTIF_CG_BIT failed, ret:%d", -+ i_ret); -+ } -+ } else if (flag == CLK_OUT_DISABLE) { -+#if defined(CONFIG_MTK_CLKMGR) -+ i_ret = disable_clock(MTK_BTIF_CG_BIT, BTIF_USER_ID); -+ status = (i_ret == 0) ? flag : status; -+ if (i_ret) { -+ BTIF_WARN_FUNC -+ ("disable_clock for MTK_BTIF_CG_BIT failed, ret:%d", -+ i_ret); -+ } -+#else -+ BTIF_DBG_FUNC("[CCF] clk_disable(clk_btif) calling\n"); -+ clk_disable(clk_btif); -+#endif /* defined(CONFIG_MTK_CLKMGR) */ -+ } else { -+ i_ret = ERR_INVALID_PAR; -+ BTIF_ERR_FUNC("invalid clock ctrl flag (%d)\n", flag); -+ } -+ } -+#endif -+ -+#else -+ -+#if MTK_BTIF_ENABLE_CLK_REF_COUNTER -+ -+#else -+ -+ status = flag; -+#endif -+ -+ i_ret = 0; -+#endif -+ -+ spin_unlock_irqrestore(&(g_clk_cg_spinlock), irq_flag); -+ -+#if MTK_BTIF_ENABLE_CLK_REF_COUNTER -+ if (i_ret == 0) { -+ BTIF_DBG_FUNC("btif clock %s\n", flag == CLK_OUT_ENABLE ? "enabled" : "disabled"); -+ } else { -+ BTIF_ERR_FUNC("%s btif clock failed, ret(%d)\n", -+ flag == CLK_OUT_ENABLE ? "enable" : "disable", i_ret); -+ } -+#else -+ -+ if (i_ret == 0) { -+ BTIF_DBG_FUNC("btif clock %s\n", flag == CLK_OUT_ENABLE ? "enabled" : "disabled"); -+ } else { -+ BTIF_ERR_FUNC("%s btif clock failed, ret(%d)\n", -+ flag == CLK_OUT_ENABLE ? "enable" : "disable", i_ret); -+ } -+#endif -+#if defined(CONFIG_MTK_CLKMGR) -+ BTIF_DBG_FUNC("BTIF's clock is %s\n", (clock_is_on(MTK_BTIF_CG_BIT) == 0) ? "off" : "on"); -+#endif -+ return i_ret; -+} -+ -+static int btif_new_handshake_ctrl(P_MTK_BTIF_INFO_STR p_btif, bool enable) -+{ -+ unsigned long base = p_btif->base; -+ -+ if (enable == true) -+ BTIF_SET_BIT(BTIF_HANDSHAKE(base), BTIF_HANDSHAKE_EN_HANDSHAKE); -+ else -+ BTIF_CLR_BIT(BTIF_HANDSHAKE(base), BTIF_HANDSHAKE_EN_HANDSHAKE); -+ return true; -+} -+ -+/***************************************************************************** -+* FUNCTION -+* hal_btif_hw_init -+* DESCRIPTION -+* BTIF hardware init -+* PARAMETERS -+* p_base [IN] BTIF module's base address -+* RETURNS -+* 0 means success, negative means fail -+*****************************************************************************/ -+int hal_btif_hw_init(P_MTK_BTIF_INFO_STR p_btif) -+{ -+/*Chaozhong: To be implement*/ -+ int i_ret = -1; -+ unsigned long base = p_btif->base; -+ -+#if NEW_TX_HANDLING_SUPPORT -+ _btif_tx_fifo_reset(p_btif); -+#endif -+ -+/*set to normal mode*/ -+ btif_reg_sync_writel(BTIF_FAKELCR_NORMAL_MODE, BTIF_FAKELCR(base)); -+/*set to newhandshake mode*/ -+ btif_new_handshake_ctrl(p_btif, true); -+/*No need to access: enable sleep mode*/ -+/*No need to access: set Rx timeout count*/ -+/*set Tx threshold*/ -+/*set Rx threshold*/ -+/*disable internal loopback test*/ -+ -+/*set Rx FIFO clear bit to 1*/ -+ BTIF_SET_BIT(BTIF_FIFOCTRL(base), BTIF_FIFOCTRL_CLR_RX); -+/*clear Rx FIFO clear bit to 0*/ -+ BTIF_CLR_BIT(BTIF_FIFOCTRL(base), BTIF_FIFOCTRL_CLR_RX); -+/*set Tx FIFO clear bit to 1*/ -+ BTIF_SET_BIT(BTIF_FIFOCTRL(base), BTIF_FIFOCTRL_CLR_TX); -+/*clear Tx FIFO clear bit to 0*/ -+ BTIF_CLR_BIT(BTIF_FIFOCTRL(base), BTIF_FIFOCTRL_CLR_TX); -+ -+ btif_reg_sync_writel(BTIF_TRI_LVL_TX(p_btif->tx_tri_lvl) -+ | BTIF_TRI_LVL_RX(p_btif->rx_tri_lvl) -+ | BTIF_TRI_LOOP_DIS, BTIF_TRI_LVL(base)); -+ hal_btif_loopback_ctrl(p_btif, false); -+/*disable BTIF Tx DMA mode*/ -+ hal_btif_tx_mode_ctrl(p_btif, false); -+/*disable BTIF Rx DMA mode*/ -+ hal_btif_rx_mode_ctrl(p_btif, false); -+/*auto reset*/ -+ BTIF_SET_BIT(BTIF_DMA_EN(base), BTIF_DMA_EN_AUTORST_EN); -+/*disable Tx IER*/ -+ hal_btif_tx_ier_ctrl(p_btif, false); -+/*enable Rx IER by default*/ -+ hal_btif_rx_ier_ctrl(p_btif, true); -+ -+ i_ret = 0; -+ return i_ret; -+} -+ -+/***************************************************************************** -+* FUNCTION -+* hal_btif_rx_ier_ctrl -+* DESCRIPTION -+* BTIF Rx interrupt enable/disable -+* PARAMETERS -+* p_base [IN] BTIF module's base address -+* enable [IN] control if rx interrupt enabled or not -+* RETURNS -+* 0 means success, negative means fail -+*****************************************************************************/ -+int hal_btif_rx_ier_ctrl(P_MTK_BTIF_INFO_STR p_btif, bool en) -+{ -+ int i_ret = -1; -+ unsigned long base = p_btif->base; -+ -+ if (en == false) -+ BTIF_CLR_BIT(BTIF_IER(base), BTIF_IER_RXFEN); -+ else -+ BTIF_SET_BIT(BTIF_IER(base), BTIF_IER_RXFEN); -+ -+/*TODO:do we need to read back ? Answer: no*/ -+ i_ret = 0; -+ return i_ret; -+} -+ -+/***************************************************************************** -+* FUNCTION -+* hal_btif_tx_ier_ctrl -+* DESCRIPTION -+* BTIF Tx interrupt enable/disable -+* PARAMETERS -+* p_base [IN] BTIF module's base address -+* enable [IN] control if tx interrupt enabled or not -+* RETURNS -+* 0 means success, negative means fail -+*****************************************************************************/ -+int hal_btif_tx_ier_ctrl(P_MTK_BTIF_INFO_STR p_btif, bool en) -+{ -+ int i_ret = -1; -+ unsigned long base = p_btif->base; -+ -+ if (en == false) -+ BTIF_CLR_BIT(BTIF_IER(base), BTIF_IER_TXEEN); -+ else -+ BTIF_SET_BIT(BTIF_IER(base), BTIF_IER_TXEEN); -+ -+/*TODO:do we need to read back ? Answer: no*/ -+ i_ret = 0; -+ -+ return i_ret; -+} -+ -+#ifndef MTK_BTIF_MARK_UNUSED_API -+ -+/***************************************************************************** -+* FUNCTION -+* _btif_receive_data -+* DESCRIPTION -+* receive data from btif module in FIFO polling mode -+* PARAMETERS -+* p_base [IN] BTIF module's base address -+* p_buf [IN/OUT] pointer to rx data buffer -+* max_len [IN] max length of rx buffer -+* RETURNS -+* positive means data is available, 0 means no data available -+*****************************************************************************/ -+int _btif_receive_data(P_MTK_BTIF_INFO_STR p_btif, -+ unsigned char *p_buf, const unsigned int max_len) -+{ -+/*Chaozhong: To be implement*/ -+ int i_ret = -1; -+ -+/*check parameter valid or not*/ -+ if ((p_buf == NULL) || (max_len == 0)) { -+ i_ret = ERR_INVALID_PAR; -+ return i_ret; -+ } -+ i_ret = btif_rx_irq_handler(p_btif, p_buf, max_len); -+ -+ return i_ret; -+} -+ -+int btif_sleep_ctrl(P_MTK_BTIF_INFO_STR p_btif, bool en) -+{ -+ int i_ret = -1; -+ unsigned long base = p_btif->base; -+ -+ if (en == false) -+ BTIF_CLR_BIT(BTIF_SLEEP_EN(base), BTIF_SLEEP_EN_BIT); -+ else -+ BTIF_SET_BIT(BTIF_SLEEP_EN(base), BTIF_SLEEP_EN_BIT); -+ -+/*TODO:do we need to read back ? Answer: no*/ -+/*TODO:do we need to dsb?*/ -+ i_ret = 0; -+ return i_ret; -+} -+ -+static int btif_tx_thr_set(P_MTK_BTIF_INFO_STR p_btif, unsigned int thr_count) -+{ -+ int i_ret = -1; -+ unsigned long base = p_btif->base; -+ unsigned int value = 0; -+ -+/*read BTIF_TRI_LVL*/ -+ value = BTIF_READ32(BTIF_TRI_LVL(base)); -+/*clear Tx threshold bits*/ -+ value &= (~BTIF_TRI_LVL_TX_MASK); -+/*set tx threshold bits*/ -+ value |= BTIF_TRI_LVL_TX(BTIF_TX_FIFO_THRE); -+/*write back to BTIF_TRI_LVL*/ -+ btif_reg_sync_writel(value, BTIF_TRI_LVL(base)); -+ -+ return i_ret; -+} -+ -+/***************************************************************************** -+* FUNCTION -+* btif_rx_fifo_reset -+* DESCRIPTION -+* reset BTIF's rx fifo -+* PARAMETERS -+* p_base [IN] BTIF module's base address -+* ec [IN] control if loopback mode is enabled or not -+* RETURNS -+* 0 means success, negative means fail -+*****************************************************************************/ -+static int btif_rx_fifo_reset(P_MTK_BTIF_INFO_STR p_btif) -+{ -+/*Chaozhong: To be implement*/ -+ int i_ret = -1; -+ unsigned long base = p_btif->base; -+ -+/*set Rx FIFO clear bit to 1*/ -+ BTIF_SET_BIT(BTIF_FIFOCTRL(base), BTIF_FIFOCTRL_CLR_RX); -+ -+/*clear Rx FIFO clear bit to 0*/ -+ BTIF_CLR_BIT(BTIF_FIFOCTRL(base), BTIF_FIFOCTRL_CLR_RX); -+ -+/*TODO:do we need to read back ? Answer: no*/ -+/*TODO:do we need to dsb?*/ -+ i_ret = 0; -+ return i_ret; -+} -+ -+/***************************************************************************** -+* FUNCTION -+* btif_tx_fifo_reset -+* DESCRIPTION -+* reset BTIF's tx fifo -+* PARAMETERS -+* p_base [IN] BTIF module's base address -+* RETURNS -+* 0 means success, negative means fail -+*****************************************************************************/ -+static int btif_tx_fifo_reset(P_MTK_BTIF_INFO_STR p_btif) -+{ -+ int i_ret = -1; -+ unsigned long base = p_btif->base; -+ -+/*set Tx FIFO clear bit to 1*/ -+ BTIF_SET_BIT(BTIF_FIFOCTRL(base), BTIF_FIFOCTRL_CLR_TX); -+ -+/*clear Tx FIFO clear bit to 0*/ -+ BTIF_CLR_BIT(BTIF_FIFOCTRL(base), BTIF_FIFOCTRL_CLR_TX); -+ -+/*TODO:do we need to read back ? Answer: no*/ -+/*TODO:do we need to dsb?*/ -+ i_ret = 0; -+ return i_ret; -+} -+ -+#endif -+ -+/***************************************************************************** -+* FUNCTION -+* hal_btif_loopback_ctrl -+* DESCRIPTION -+* BTIF Tx/Rx loopback mode set, this operation can only be done after set BTIF to normal mode -+* PARAMETERS -+* RETURNS -+* 0 means success, negative means fail -+*****************************************************************************/ -+int hal_btif_loopback_ctrl(P_MTK_BTIF_INFO_STR p_btif, bool en) -+{ -+ int i_ret = -1; -+ unsigned long base = p_btif->base; -+ -+ if (en == false) -+ BTIF_CLR_BIT(BTIF_TRI_LVL(base), BTIF_TRI_LOOP_EN); -+ else -+ BTIF_SET_BIT(BTIF_TRI_LVL(base), BTIF_TRI_LOOP_EN); -+ -+/*TODO:do we need to read back ? Answer: no*/ -+/*TODO:do we need to dsb?*/ -+ i_ret = 0; -+ return i_ret; -+} -+ -+ -+/***************************************************************************** -+* FUNCTION -+* hal_btif_rx_handler -+* DESCRIPTION -+* lower level interrupt handler -+* PARAMETERS -+* p_base [IN] BTIF module's base address -+* p_buf [IN/OUT] pointer to rx data buffer -+* max_len [IN] max length of rx buffer -+* RETURNS -+* 0 means success; negative means fail; positive means rx data length -+*****************************************************************************/ -+int hal_btif_irq_handler(P_MTK_BTIF_INFO_STR p_btif, -+ unsigned char *p_buf, const unsigned int max_len) -+{ -+/*Chaozhong: To be implement*/ -+ int i_ret = -1; -+ unsigned int iir = 0; -+ unsigned int rx_len = 0; -+ unsigned long base = p_btif->base; -+ -+#if 0 -+/*check parameter valid or not*/ -+ if ((p_buf == NULL) || (max_len == 0)) { -+ i_ret = ERR_INVALID_PAR; -+ return i_ret; -+ } -+#endif -+ unsigned long irq_flag = 0; -+ -+ spin_lock_irqsave(&(g_clk_cg_spinlock), irq_flag); -+ -+#if defined(CONFIG_MTK_CLKMGR) -+ if (clock_is_on(MTK_BTIF_CG_BIT) == 0) { -+ spin_unlock_irqrestore(&(g_clk_cg_spinlock), irq_flag); -+ BTIF_ERR_FUNC("%s: clock is off before irq handle done!!!\n", -+ __FILE__); -+ return i_ret; -+ } -+#endif -+/*read interrupt identifier register*/ -+ iir = BTIF_READ32(BTIF_IIR(base)); -+ -+/*is rx interrupt exist?*/ -+#if 0 -+ while ((iir & BTIF_IIR_RX) && (rx_len < max_len)) { -+ rx_len += -+ btif_rx_irq_handler(p_btif, (p_buf + rx_len), -+ (max_len - rx_len)); -+ -+/*update IIR*/ -+ iir = BTIF_READ32(BTIF_IIR(base)); -+ } -+#endif -+ -+ while (iir & (BTIF_IIR_RX | BTIF_IIR_RX_TIMEOUT)) { -+ rx_len += btif_rx_irq_handler(p_btif, p_buf, max_len); -+ -+/*update IIR*/ -+ iir = BTIF_READ32(BTIF_IIR(base)); -+ } -+ -+/*is tx interrupt exist?*/ -+ if (iir & BTIF_IIR_TX_EMPTY) -+ i_ret = btif_tx_irq_handler(p_btif); -+ spin_unlock_irqrestore(&(g_clk_cg_spinlock), irq_flag); -+ -+ i_ret = rx_len != 0 ? rx_len : i_ret; -+ return i_ret; -+} -+ -+int hal_btif_rx_cb_reg(P_MTK_BTIF_INFO_STR p_btif_info, btif_rx_buf_write rx_cb) -+{ -+ if (p_btif_info->rx_cb != NULL) -+ BTIF_DBG_FUNC("rx_cb already registered, replace (0x%p) with (0x%p)\n", -+ p_btif_info->rx_cb, rx_cb); -+ p_btif_info->rx_cb = rx_cb; -+ -+ return 0; -+} -+ -+/***************************************************************************** -+* FUNCTION -+* btif_rx_irq_handler -+* DESCRIPTION -+* lower level rx interrupt handler -+* PARAMETERS -+* p_base [IN] BTIF module's base address -+* RETURNS -+* positive means length of rx data , negative means fail -+*****************************************************************************/ -+static int btif_rx_irq_handler(P_MTK_BTIF_INFO_STR p_btif_info, -+ unsigned char *p_buf, const unsigned int max_len) -+{ -+/*Chaozhong: To be implement*/ -+ int i_ret = 0; -+ unsigned int iir = 0; -+ unsigned int rx_len = 0; -+ unsigned long base = p_btif_info->base; -+ unsigned char rx_buf[256]; -+ unsigned int local_buf_len = 256; -+ btif_rx_buf_write rx_cb = p_btif_info->rx_cb; -+ unsigned int total_len = 0; -+ -+/*read interrupt identifier register*/ -+ iir = BTIF_READ32(BTIF_IIR(base)); -+ while ((iir & (BTIF_IIR_RX | BTIF_IIR_RX_TIMEOUT)) && -+ (rx_len < local_buf_len)) { -+ rx_buf[rx_len] = BTIF_READ8(base); -+ rx_len++; -+/*need to consult CC Hwang for advice */ -+/* -+ * whether we need to do memory barrier here -+ * Ans: no -+ */ -+/* -+ * whether we need to d memory barrier when call BTIF_SET_BIT or BTIF_CLR_BIT -+ * Ans: no -+ */ -+ if (rx_len == local_buf_len) { -+ if (rx_cb) -+ (*rx_cb) (p_btif_info, rx_buf, rx_len); -+ rx_len = 0; -+ total_len += rx_len; -+ } -+ iir = BTIF_READ32(BTIF_IIR(base)); -+ } -+ total_len += rx_len; -+ if (rx_len && rx_cb) -+ (*rx_cb) (p_btif_info, rx_buf, rx_len); -+ -+/* -+ * make sure all data write back to memory, mb or dsb? -+ * need to consult CC Hwang for advice -+ * Ans: no need here -+ */ -+ i_ret = total_len; -+ return i_ret; -+} -+ -+/***************************************************************************** -+* FUNCTION -+* btif_tx_irq_handler -+* DESCRIPTION -+* lower level tx interrupt handler -+* PARAMETERS -+* p_base [IN] BTIF module's base address -+* p_buf [IN/OUT] pointer to rx data buffer -+* max_len [IN] max length of rx buffer -+* RETURNS -+* 0 means success, negative means fail -+*****************************************************************************/ -+static int btif_tx_irq_handler(P_MTK_BTIF_INFO_STR p_btif) -+{ -+ int i_ret = -1; -+ -+#if NEW_TX_HANDLING_SUPPORT -+ int how_many = 0; -+ unsigned int lsr; -+ unsigned int ava_len = 0; -+ unsigned long base = p_btif->base; -+ char local_buf[BTIF_TX_FIFO_SIZE]; -+ char *p_data = local_buf; -+ unsigned long flag = 0; -+ -+ struct kfifo *p_tx_fifo = p_btif->p_tx_fifo; -+ -+/*read LSR and check THER or TEMT, either one is 1 means can accept tx data*/ -+ lsr = BTIF_READ32(BTIF_LSR(base)); -+ -+ if (lsr & BTIF_LSR_TEMT_BIT) -+ /*Tx Holding Register if empty, which means we can write tx FIFO count to BTIF*/ -+ ava_len = BTIF_TX_FIFO_SIZE; -+ else if (lsr & BTIF_LSR_THRE_BIT) -+ /*Tx Holding Register if empty, which means we can write (Tx FIFO count - Tx threshold)to BTIF*/ -+ ava_len = BTIF_TX_FIFO_SIZE - BTIF_TX_FIFO_THRE; -+ else { -+ /*this means data size in tx FIFO is more than Tx threshold, we will not write data to THR*/ -+ ava_len = 0; -+ goto ret; -+ } -+ spin_lock_irqsave(&(p_btif->tx_fifo_spinlock), flag); -+ how_many = kfifo_out(p_tx_fifo, local_buf, ava_len); -+ spin_unlock_irqrestore(&(p_btif->tx_fifo_spinlock), flag); -+ BTIF_DBG_FUNC("BTIF tx size %d done, left:%d\n", how_many, -+ kfifo_avail(p_tx_fifo)); -+ while (how_many--) -+ btif_reg_sync_writeb(*(p_data++), BTIF_THR(base)); -+ -+ spin_lock_irqsave(&(p_btif->tx_fifo_spinlock), flag); -+/*clear Tx enable flag if necessary*/ -+ if (kfifo_is_empty(p_tx_fifo)) { -+ hal_btif_tx_ier_ctrl(p_btif, false); -+ BTIF_DBG_FUNC("BTIF tx FIFO is empty\n"); -+ } -+ spin_unlock_irqrestore(&(p_btif->tx_fifo_spinlock), flag); -+ret: -+#else -+/*clear Tx enable flag*/ -+ hal_btif_tx_ier_ctrl(p_btif, false); -+#endif -+ i_ret = 0; -+ return i_ret; -+} -+ -+/***************************************************************************** -+* FUNCTION -+* hal_btif_tx_mode_ctrl -+* DESCRIPTION -+* set BTIF tx to corresponding mode (PIO/DMA) -+* PARAMETERS -+* p_base [IN] BTIF module's base address -+* mode [IN] rx mode -+* RETURNS -+* 0 means success, negative means fail -+*****************************************************************************/ -+int hal_btif_tx_mode_ctrl(P_MTK_BTIF_INFO_STR p_btif, ENUM_BTIF_MODE mode) -+{ -+ int i_ret = -1; -+ unsigned long base = p_btif->base; -+ -+ if (mode == BTIF_MODE_DMA) -+ /*set to DMA mode*/ -+ BTIF_SET_BIT(BTIF_DMA_EN(base), BTIF_DMA_EN_TX); -+ else -+ /*set to PIO mode*/ -+ BTIF_CLR_BIT(BTIF_DMA_EN(base), BTIF_DMA_EN_TX); -+ -+ i_ret = 0; -+ return i_ret; -+} -+ -+/***************************************************************************** -+* FUNCTION -+* hal_btif_rx_mode_ctrl -+* DESCRIPTION -+* set BTIF rx to corresponding mode (PIO/DMA) -+* PARAMETERS -+* p_base [IN] BTIF module's base address -+* mode [IN] rx mode -+* RETURNS -+* 0 means success, negative means fail -+*****************************************************************************/ -+int hal_btif_rx_mode_ctrl(P_MTK_BTIF_INFO_STR p_btif, ENUM_BTIF_MODE mode) -+{ -+ int i_ret = -1; -+ unsigned long base = p_btif->base; -+ -+ if (mode == BTIF_MODE_DMA) -+ /*set to DMA mode*/ -+ BTIF_SET_BIT(BTIF_DMA_EN(base), BTIF_DMA_EN_RX); -+ else -+ /*set to PIO mode*/ -+ BTIF_CLR_BIT(BTIF_DMA_EN(base), BTIF_DMA_EN_RX); -+ -+ i_ret = 0; -+ return i_ret; -+} -+ -+/***************************************************************************** -+* FUNCTION -+* hal_btif_send_data -+* DESCRIPTION -+* send data through btif in FIFO mode -+* PARAMETERS -+* p_base [IN] BTIF module's base address -+* p_buf [IN] pointer to rx data buffer -+* max_len [IN] tx buffer length -+* RETURNS -+* positive means number of data sent; 0 means no data put to FIFO; negative means error happens -+*****************************************************************************/ -+int hal_btif_send_data(P_MTK_BTIF_INFO_STR p_btif, -+ const unsigned char *p_buf, const unsigned int buf_len) -+{ -+/*Chaozhong: To be implement*/ -+ int i_ret = -1; -+ -+ unsigned int ava_len = 0; -+ unsigned int sent_len = 0; -+ -+#if !(NEW_TX_HANDLING_SUPPORT) -+ unsigned long base = p_btif->base; -+ unsigned int lsr = 0; -+ unsigned int left_len = 0; -+ unsigned char *p_data = (unsigned char *)p_buf; -+#endif -+ -+/*check parameter valid or not*/ -+ if ((p_buf == NULL) || (buf_len == 0)) { -+ i_ret = ERR_INVALID_PAR; -+ return i_ret; -+ } -+#if NEW_TX_HANDLING_SUPPORT -+ ava_len = _get_btif_tx_fifo_room(p_btif); -+ sent_len = buf_len <= ava_len ? buf_len : ava_len; -+ if (sent_len > 0) { -+ int enqueue_len = 0; -+ unsigned long flag = 0; -+ -+ spin_lock_irqsave(&(p_btif->tx_fifo_spinlock), flag); -+ enqueue_len = kfifo_in(p_btif->p_tx_fifo, -+ (unsigned char *)p_buf, sent_len); -+ if (sent_len != enqueue_len) { -+ BTIF_ERR_FUNC("target tx len:%d, len sent:%d\n", -+ sent_len, enqueue_len); -+ } -+ i_ret = enqueue_len; -+ mb(); -+/*enable BTIF Tx IRQ*/ -+ hal_btif_tx_ier_ctrl(p_btif, true); -+ spin_unlock_irqrestore(&(p_btif->tx_fifo_spinlock), flag); -+ BTIF_DBG_FUNC("enqueue len:%d\n", enqueue_len); -+ } else { -+ i_ret = 0; -+ } -+#else -+ while ((_btif_is_tx_allow(p_btif)) && (sent_len < buf_len)) { -+ /*read LSR and check THER or TEMT, either one is 1 means can accept tx data*/ -+ lsr = BTIF_READ32(BTIF_LSR(base)); -+ -+ if (lsr & BTIF_LSR_TEMT_BIT) -+ /*Tx Holding Register if empty, which means we can write tx FIFO count to BTIF*/ -+ ava_len = BTIF_TX_FIFO_SIZE; -+ else if (lsr & BTIF_LSR_THRE_BIT) -+ /*Tx Holding Register if empty, which means we can write (Tx FIFO count - Tx threshold)to BTIF*/ -+ ava_len = BTIF_TX_FIFO_SIZE - BTIF_TX_FIFO_THRE; -+ else { -+ /*this means data size in tx FIFO is more than Tx threshold, we will not write data to THR*/ -+ ava_len = 0; -+ break; -+ } -+ -+ left_len = buf_len - sent_len; -+/*ava_len will be real length will write to BTIF THR*/ -+ ava_len = ava_len > left_len ? left_len : ava_len; -+/*update sent length valud after this operation*/ -+ sent_len += ava_len; -+/* -+ * whether we need memory barrier here? -+ * Ans: No, no memory ordering issue exist, -+ * CPU will make sure logically right -+ */ -+ while (ava_len--) -+ btif_reg_sync_writeb(*(p_data++), BTIF_THR(base)); -+ -+ } -+/* while ((hal_btif_is_tx_allow()) && (sent_len < buf_len)); */ -+ -+ i_ret = sent_len; -+ -+/*enable BTIF Tx IRQ*/ -+ hal_btif_tx_ier_ctrl(p_btif, true); -+#endif -+ return i_ret; -+} -+ -+ -+/***************************************************************************** -+* FUNCTION -+* hal_btif_raise_wak_sig -+* DESCRIPTION -+* raise wakeup signal to counterpart -+* PARAMETERS -+* p_base [IN] BTIF module's base address -+* RETURNS -+* 0 means success, negative means fail -+*****************************************************************************/ -+int hal_btif_raise_wak_sig(P_MTK_BTIF_INFO_STR p_btif) -+{ -+ int i_ret = -1; -+ unsigned long base = p_btif->base; -+#if defined(CONFIG_MTK_CLKMGR) -+ if (clock_is_on(MTK_BTIF_CG_BIT) == 0) { -+ BTIF_ERR_FUNC("%s: clock is off before send wakeup signal!!!\n", -+ __FILE__); -+ return i_ret; -+ } -+#endif -+/*write 0 to BTIF_WAK to pull ap_wakeup_consyss low */ -+ BTIF_CLR_BIT(BTIF_WAK(base), BTIF_WAK_BIT); -+ -+/*wait for a period for longer than 1/32k period, here we use 40us*/ -+ set_current_state(TASK_UNINTERRUPTIBLE); -+ usleep_range(128, 160); -+/* -+ * according to linux/documentation/timers/timers-how-to, we choose usleep_range -+ * SLEEPING FOR ~USECS OR SMALL MSECS ( 10us - 20ms): * Use usleep_range -+ */ -+/*write 1 to pull ap_wakeup_consyss high*/ -+ BTIF_SET_BIT(BTIF_WAK(base), BTIF_WAK_BIT); -+ i_ret = 0; -+ return i_ret; -+} -+ -+/***************************************************************************** -+* FUNCTION -+* hal_btif_dump_reg -+* DESCRIPTION -+* dump BTIF module's information when needed -+* PARAMETERS -+* p_base [IN] BTIF module's base address -+* flag [IN] register id flag -+* RETURNS -+* 0 means success, negative means fail -+*****************************************************************************/ -+int hal_btif_dump_reg(P_MTK_BTIF_INFO_STR p_btif, ENUM_BTIF_REG_ID flag) -+{ -+/*Chaozhong: To be implement*/ -+ int i_ret = -1; -+ int idx = 0; -+ /*unsigned long irq_flag = 0;*/ -+ unsigned long base = p_btif->base; -+ unsigned char reg_map[0xE0 / 4] = { 0 }; -+ unsigned int lsr = 0x0; -+ unsigned int dma_en = 0; -+ -+ /*spin_lock_irqsave(&(g_clk_cg_spinlock), irq_flag);*/ -+#if defined(CONFIG_MTK_CLKMGR) -+ if (clock_is_on(MTK_BTIF_CG_BIT) == 0) { -+ /*spin_unlock_irqrestore(&(g_clk_cg_spinlock), irq_flag);*/ -+ BTIF_ERR_FUNC("%s: clock is off, this should never happen!!!\n", -+ __FILE__); -+ return i_ret; -+ } -+#endif -+ lsr = BTIF_READ32(BTIF_LSR(base)); -+ dma_en = BTIF_READ32(BTIF_DMA_EN(base)); -+ /* -+ * here we omit 1st register which is THR/RBR register to avoid -+ * Rx data read by this debug information accidently -+ */ -+ for (idx = 1; idx < sizeof(reg_map); idx++) -+ reg_map[idx] = BTIF_READ8(p_btif->base + (4 * idx)); -+ /*spin_unlock_irqrestore(&(g_clk_cg_spinlock), irq_flag);*/ -+ BTIF_INFO_FUNC("BTIF's clock is on\n"); -+ BTIF_INFO_FUNC("base address: 0x%lx\n", base); -+ switch (flag) { -+ case REG_BTIF_ALL: -+#if 0 -+ BTIF_INFO_FUNC("BTIF_IER:0x%x\n", BTIF_READ32(BTIF_IER(base))); -+ BTIF_INFO_FUNC("BTIF_IIR:0x%x\n", BTIF_READ32(BTIF_IIR(base))); -+ BTIF_INFO_FUNC("BTIF_FAKELCR:0x%x\n", -+ BTIF_READ32(BTIF_FAKELCR(base))); -+ BTIF_INFO_FUNC("BTIF_LSR:0x%x\n", BTIF_READ32(BTIF_LSR(base))); -+ BTIF_INFO_FUNC("BTIF_SLEEP_EN:0x%x\n", -+ BTIF_READ32(BTIF_SLEEP_EN(base))); -+ BTIF_INFO_FUNC("BTIF_DMA_EN:0x%x\n", -+ BTIF_READ32(BTIF_DMA_EN(base))); -+ BTIF_INFO_FUNC("BTIF_RTOCNT:0x%x\n", -+ BTIF_READ32(BTIF_RTOCNT(base))); -+ BTIF_INFO_FUNC("BTIF_TRI_LVL:0x%x\n", -+ BTIF_READ32(BTIF_TRI_LVL(base))); -+ BTIF_INFO_FUNC("BTIF_WAT_TIME:0x%x\n", -+ BTIF_READ32(BTIF_WAT_TIME(base))); -+ BTIF_INFO_FUNC("BTIF_HANDSHAKE:0x%x\n", -+ BTIF_READ32(BTIF_HANDSHAKE(base))); -+#endif -+ btif_dump_array("BTIF register", reg_map, sizeof(reg_map)); -+ break; -+ default: -+ break; -+ } -+ -+ BTIF_INFO_FUNC("Tx DMA %s\n", -+ (dma_en & BTIF_DMA_EN_TX) ? "enabled" : "disabled"); -+ BTIF_INFO_FUNC("Rx DMA %s\n", -+ (dma_en & BTIF_DMA_EN_RX) ? "enabled" : "disabled"); -+ -+ BTIF_INFO_FUNC("Rx data is %s\n", -+ (lsr & BTIF_LSR_DR_BIT) ? "not empty" : "empty"); -+ BTIF_INFO_FUNC("Tx data is %s\n", -+ (lsr & BTIF_LSR_TEMT_BIT) ? "empty" : "not empty"); -+ -+ return i_ret; -+} -+ -+/***************************************************************************** -+* FUNCTION -+* hal_btif_is_tx_complete -+* DESCRIPTION -+* get tx complete flag -+* PARAMETERS -+* p_base [IN] BTIF module's base address -+* RETURNS -+* true means tx complete, false means tx in process -+*****************************************************************************/ -+bool hal_btif_is_tx_complete(P_MTK_BTIF_INFO_STR p_btif) -+{ -+/*Chaozhong: To be implement*/ -+ bool b_ret = false; -+ unsigned int lsr = 0; -+ unsigned long flags = 0; -+ unsigned long base = p_btif->base; -+ unsigned int tx_empty = 0; -+ unsigned int rx_dr = 0; -+ unsigned int tx_irq_disable = 0; -+ -+/* -+ * 3 conditions allow clock to be disable -+ * 1. if TEMT is set or not -+ * 2. if DR is set or not -+ * 3. Tx IRQ is disabled or not -+ */ -+ lsr = BTIF_READ32(BTIF_LSR(base)); -+ tx_empty = lsr & BTIF_LSR_TEMT_BIT; -+ rx_dr = lsr & BTIF_LSR_DR_BIT; -+ tx_irq_disable = BTIF_READ32(BTIF_IER(base)) & BTIF_IER_TXEEN; -+ -+ b_ret = -+ (tx_empty && (tx_irq_disable == 0) && (rx_dr == 0)) ? true : false; -+ if (!b_ret) { -+ BTIF_DBG_FUNC -+ ("BTIF flag, tx_empty:%d, rx_dr:%d, tx_irq_disable:%d\n", -+ tx_empty, rx_dr, tx_irq_disable); -+ } -+#if NEW_TX_HANDLING_SUPPORT -+ spin_lock_irqsave(&(p_btif->tx_fifo_spinlock), flags); -+/*clear Tx enable flag if necessary*/ -+ if (!(kfifo_is_empty(p_btif->p_tx_fifo))) { -+ BTIF_DBG_FUNC("BTIF tx FIFO is not empty\n"); -+ b_ret = false; -+ } -+ spin_unlock_irqrestore(&(p_btif->tx_fifo_spinlock), flags); -+#endif -+ return b_ret; -+} -+ -+/***************************************************************************** -+* FUNCTION -+* hal_btif_is_tx_allow -+* DESCRIPTION -+* whether tx is allowed -+* PARAMETERS -+* p_base [IN] BTIF module's base address -+* RETURNS -+* true if tx operation is allowed; false if tx is not allowed -+*****************************************************************************/ -+bool hal_btif_is_tx_allow(P_MTK_BTIF_INFO_STR p_btif) -+{ -+#define MIN_TX_MB ((26 * 1000000 / 13) / 1000000) -+#define AVE_TX_MB ((26 * 1000000 / 8) / 1000000) -+ -+/*Chaozhong: To be implement*/ -+ bool b_ret = false; -+ -+#if NEW_TX_HANDLING_SUPPORT -+ unsigned long flags = 0; -+ -+ spin_lock_irqsave(&(p_btif->tx_fifo_spinlock), flags); -+/*clear Tx enable flag if necessary*/ -+ if (kfifo_is_full(p_btif->p_tx_fifo)) { -+ BTIF_WARN_FUNC("BTIF tx FIFO is full\n"); -+ b_ret = false; -+ } else { -+ b_ret = true; -+ } -+ spin_unlock_irqrestore(&(p_btif->tx_fifo_spinlock), flags); -+#else -+ unsigned int lsr = 0; -+ unsigned long base = p_btif->base; -+ unsigned int wait_us = (BTIF_TX_FIFO_SIZE - BTIF_TX_FIFO_THRE) / MIN_TX_MB; /*only ava length */ -+ -+/*read LSR and check THER or TEMT, either one is 1 means can accept tx data*/ -+ lsr = BTIF_READ32(BTIF_LSR(base)); -+ -+ if (!(lsr & (BTIF_LSR_TEMT_BIT | BTIF_LSR_THRE_BIT))) { -+ BTIF_DBG_FUNC("wait for %d ~ %d us\n", wait_us, 3 * wait_us); -+/* usleep_range(wait_us, 3 * 10 * wait_us); */ -+ usleep_range(wait_us, 3 * wait_us); -+ } -+ lsr = BTIF_READ32(BTIF_LSR(base)); -+ b_ret = (lsr & (BTIF_LSR_TEMT_BIT | BTIF_LSR_THRE_BIT)) ? true : false; -+ if (!b_ret) -+ BTIF_DBG_FUNC(" tx is not allowed for the moment\n"); -+ else -+ BTIF_DBG_FUNC(" tx is allowed\n"); -+#endif -+ return b_ret; -+} -+ -+#if !(NEW_TX_HANDLING_SUPPORT) -+ -+static bool _btif_is_tx_allow(P_MTK_BTIF_INFO_STR p_btif) -+{ -+/*Chaozhong: To be implement*/ -+ bool b_ret = false; -+ unsigned long base = p_btif->base; -+ unsigned int lsr = 0; -+ -+/*read LSR and check THER or TEMT, either one is 1 means can accept tx data*/ -+ lsr = BTIF_READ32(BTIF_LSR(base)); -+ b_ret = (lsr & (BTIF_LSR_TEMT_BIT | BTIF_LSR_THRE_BIT)) ? true : false; -+ return b_ret; -+} -+#endif -+ -+int hal_btif_pm_ops(P_MTK_BTIF_INFO_STR p_btif_info, MTK_BTIF_PM_OPID opid) -+{ -+ int i_ret = -1; -+ -+ BTIF_DBG_FUNC("op id: %d\n", opid); -+ switch (opid) { -+ case BTIF_PM_DPIDLE_EN: -+ i_ret = 0; -+ break; -+ case BTIF_PM_DPIDLE_DIS: -+ i_ret = 0; -+ break; -+ case BTIF_PM_SUSPEND: -+ i_ret = 0; -+ break; -+ case BTIF_PM_RESUME: -+ i_ret = 0; -+ break; -+ case BTIF_PM_RESTORE_NOIRQ:{ -+ unsigned int flag = 0; -+ P_MTK_BTIF_IRQ_STR p_irq = p_btif_info->p_irq; -+ -+#ifdef CONFIG_OF -+ flag = p_irq->irq_flags; -+#else -+ switch (p_irq->sens_type) { -+ case IRQ_SENS_EDGE: -+ if (p_irq->edge_type == IRQ_EDGE_FALL) -+ flag = IRQF_TRIGGER_FALLING; -+ else if (p_irq->edge_type == IRQ_EDGE_RAISE) -+ flag = IRQF_TRIGGER_RISING; -+ else if (p_irq->edge_type == IRQ_EDGE_BOTH) -+ flag = IRQF_TRIGGER_RISING | -+ IRQF_TRIGGER_FALLING; -+ else -+ flag = IRQF_TRIGGER_FALLING; /*make this as default type */ -+ break; -+ case IRQ_SENS_LVL: -+ if (p_irq->lvl_type == IRQ_LVL_LOW) -+ flag = IRQF_TRIGGER_LOW; -+ else if (p_irq->lvl_type == IRQ_LVL_HIGH) -+ flag = IRQF_TRIGGER_HIGH; -+ else -+ flag = IRQF_TRIGGER_LOW; /*make this as default type */ -+ break; -+ default: -+ flag = IRQF_TRIGGER_LOW; /*make this as default type */ -+ break; -+ } -+#endif -+/* irq_set_irq_type(p_irq->irq_id, flag); */ -+ i_ret = 0; -+ } -+ break; -+ default: -+ i_ret = ERR_INVALID_PAR; -+ break; -+ } -+ -+ return i_ret; -+} -+void mtk_btif_read_cpu_sw_rst_debug_plat(void) -+{ -+#define CONSYS_AP2CONN_WAKEUP_OFFSET 0x00000064 -+ BTIF_WARN_FUNC("+CONSYS_AP2CONN_WAKEUP_OFFSET(0x%x)\n", -+ BTIF_READ32(mtk_btif.base + CONSYS_AP2CONN_WAKEUP_OFFSET)); -+} -+ -diff --git a/drivers/misc/mediatek/btif/common/inc/mtk_btif.h b/drivers/misc/mediatek/btif/common/inc/mtk_btif.h -new file mode 100644 -index 000000000000..5e2f5a9857d9 ---- /dev/null -+++ b/drivers/misc/mediatek/btif/common/inc/mtk_btif.h -@@ -0,0 +1,370 @@ -+/* -+ * Copyright (C) 2015 MediaTek Inc. -+ * -+ * 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. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#ifndef __MTK_BTIF_H_ -+#define __MTK_BTIF_H_ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include /* gettimeofday */ -+#include -+ -+#include "btif_pub.h" -+#include "btif_dma_pub.h" -+#include "mtk_btif_exp.h" -+ -+#define BTIF_PORT_NR 1 -+#define BTIF_USER_NAME_MAX_LEN 32 -+ -+/*-------------Register Defination Start ---------------*/ -+#if (defined(CONFIG_MTK_GMO_RAM_OPTIMIZE) && !defined(CONFIG_MTK_ENG_BUILD)) -+#define BTIF_RX_BUFFER_SIZE (1024 * 32) -+#else -+#define BTIF_RX_BUFFER_SIZE (1024 * 64) -+#endif -+#define BTIF_TX_FIFO_SIZE (1024 * 4) -+ -+/*------------Register Defination End ----------------*/ -+ -+/*------------BTIF Module Clock and Power Control Defination---------------*/ -+typedef enum _ENUM_BTIF_RX_TYPE_ { -+ BTIF_IRQ_CTX = 0, -+ BTIF_TASKLET_CTX = BTIF_IRQ_CTX + 1, -+ BTIF_THREAD_CTX = BTIF_TASKLET_CTX + 1, -+ BTIF_WQ_CTX = BTIF_THREAD_CTX + 1, -+ BTIF_RX_TYPE_MAX, -+} ENUM_BTIF_RX_TYPE; -+ -+typedef enum _ENUM_BTIF_TX_TYPE_ { -+ BTIF_TX_USER_CTX = 0, -+ BTIF_TX_SINGLE_CTX = BTIF_TX_USER_CTX + 1, -+ BTIF_TX_TYPE_MAX, -+} ENUM_BTIF_TX_TYPE; -+ -+typedef enum _ENUM_BTIF_STATE_ { -+ B_S_OFF = 0, -+ B_S_SUSPEND = B_S_OFF + 1, -+ B_S_DPIDLE = B_S_SUSPEND + 1, -+ B_S_ON = B_S_DPIDLE + 1, -+ B_S_MAX, -+} ENUM_BTIF_STATE; -+ -+#define ENABLE_BTIF_RX_DMA 1 -+#define ENABLE_BTIF_TX_DMA 1 -+ -+#if ENABLE_BTIF_TX_DMA -+#define BTIF_TX_MODE BTIF_MODE_DMA -+#else -+#define BTIF_TX_MODE BTIF_MODE_PIO -+#endif -+ -+#if ENABLE_BTIF_RX_DMA -+#define BTIF_RX_MODE BTIF_MODE_DMA -+#else -+#define BTIF_RX_MODE BTIF_MODE_PIO -+#endif -+ -+#define BTIF_RX_BTM_CTX BTIF_THREAD_CTX/*BTIF_WQ_CTX*//* BTIF_TASKLET_CTX */ -+/* -+ * -- cannot be used because , -+ * mtk_wcn_stp_parser data will call *(stp_if_tx) to send ack, -+ * in which context sleepable lock or usleep operation may be used, -+ * these operation is not allowed in tasklet, may cause schedule_bug -+ */ -+ -+#define BTIF_TX_CTX BTIF_TX_USER_CTX /* BTIF_TX_SINGLE_CTX */ -+ -+#define ENABLE_BTIF_RX_THREAD_RT_SCHED 0 -+#define MAX_BTIF_RXD_TIME_REC 3 -+ -+/*Structure Defination*/ -+ -+/*-----------------BTIF setting--------------*/ -+typedef struct _mtk_btif_setting_ { -+ ENUM_BTIF_MODE tx_mode; /*BTIF Tx Mode Setting */ -+ ENUM_BTIF_MODE rx_mode; /*BTIF Tx Mode Setting */ -+ ENUM_BTIF_RX_TYPE rx_type; /*rx handle type */ -+ ENUM_BTIF_TX_TYPE tx_type; /*tx type */ -+} mtk_btif_setting, *p_mtk_btif_setting; -+/*---------------------------------------------------------------------------*/ -+ -+#if 0 -+/*---------------------------------------------------------------------------*/ -+typedef struct _mtk_btif_register_ { -+ unsigned int iir; /*Interrupt Identification Register */ -+ unsigned int lsr; /*Line Status Register */ -+ unsigned int fake_lcr; /*Fake Lcr Regiseter */ -+ unsigned int fifo_ctrl; /*FIFO Control Register */ -+ unsigned int ier; /*Interrupt Enable Register */ -+ unsigned int sleep_en; /*Sleep Enable Register */ -+ unsigned int rto_counter; /*Rx Timeout Counter Register */ -+ unsigned int dma_en; /*DMA Enalbe Register */ -+ unsigned int tri_lvl; /*Tx/Rx Trigger Level Register */ -+ unsigned int wat_time; /*Async Wait Time Register */ -+ unsigned int handshake; /*New HandShake Mode Register */ -+ unsigned int sleep_wak; /*Sleep Wakeup Reigster */ -+} mtk_btif_register, *p_mtk_btif_register; -+/*---------------------------------------------------------------------------*/ -+ -+#endif -+ -+typedef struct _btif_buf_str_ { -+ unsigned int size; -+ unsigned char *p_buf; -+ /* -+ * For Tx: next Tx data pointer to FIFO; -+ * For Rx: next read data pointer from BTIF user -+ */ -+ unsigned int rd_idx; -+ /* -+ * For Tx: next Tx data pointer from BTIF user; -+ * For Rx: next write data(from FIFO) pointer -+ */ -+ unsigned int wr_idx; -+} btif_buf_str, *p_btif_buf_str; -+ -+/*---------------------------------------------------------------------------*/ -+typedef struct _mtk_btif_dma_ { -+ /*p_mtk_btif*/ void *p_btif; -+ /*BTIF pointer to which DMA belongs */ -+ -+#if 0 -+ unsigned int channel; /*DMA's channel */ -+#endif -+ -+ ENUM_BTIF_DIR dir; /*DMA's direction: */ -+ bool enable; /*DMA enable or disable flag */ -+ -+ P_MTK_DMA_INFO_STR p_dma_info; /*DMA's IRQ information */ -+ -+#if 0 -+ mtk_dma_register register; /*DMA's register */ -+#endif -+ -+ spinlock_t iolock; /*io lock for DMA channel */ -+ atomic_t entry; /* entry count */ -+} mtk_btif_dma, *p_mtk_btif_dma; -+ -+#if (defined(CONFIG_MTK_GMO_RAM_OPTIMIZE) && !defined(CONFIG_MTK_ENG_BUILD)) -+#define BTIF_LOG_ENTRY_NUM 10 -+#else -+#define BTIF_LOG_ENTRY_NUM 30 -+#endif -+ -+#define BTIF_LOG_SZ 1536 -+ -+typedef void (*MTK_BTIF_RX_NOTIFY) (void); -+ -+typedef struct _btif_log_buf_t_ { -+ unsigned int len; -+ struct timeval timer; -+ unsigned char buffer[BTIF_LOG_SZ]; -+} BTIF_LOG_BUF_T, *P_BTIF_LOG_BUF_T; -+ -+typedef struct _btif_log_queue_t_ { -+ ENUM_BTIF_DIR dir; -+ bool enable; -+ bool output_flag; -+ unsigned int in; -+ unsigned int out; -+ unsigned int size; -+ spinlock_t lock; -+ P_BTIF_LOG_BUF_T p_queue[BTIF_LOG_ENTRY_NUM]; -+} BTIF_LOG_QUEUE_T, *P_BTIF_LOG_QUEUE_T; -+ -+/*---------------------------------------------------------------------------*/ -+typedef struct _mtk_btif_ { -+ unsigned int open_counter; /*open counter */ -+ bool enable; /*BTIF module enable flag */ -+ bool lpbk_flag; /*BTIF module enable flag */ -+#if 0 -+ unsigned long base; /* BTIF controller base address */ -+#endif -+ -+ ENUM_BTIF_STATE state; /*BTIF state mechanism */ -+ struct mutex state_mtx; /*lock to BTIF state mechanism's state change */ -+ struct mutex ops_mtx; /*lock to BTIF's open and close */ -+ -+#if 0 -+ mtk_btif_register register; /*BTIF registers */ -+#endif -+ -+ ENUM_BTIF_MODE tx_mode; /* BTIF Tx channel mode */ -+ ENUM_BTIF_MODE rx_mode; /* BTIF Rx channel mode */ -+ struct mutex tx_mtx; /*lock to BTIF's tx process */ -+/*rx handling */ -+ ENUM_BTIF_RX_TYPE btm_type; /*BTIF Rx bottom half context */ -+/*tx handling*/ -+ ENUM_BTIF_TX_TYPE tx_ctx; /*BTIF tx context */ -+/* unsigned char rx_buf[BTIF_RX_BUFFER_SIZE]; */ -+ btif_buf_str btif_buf; -+ spinlock_t rx_irq_spinlock; /*lock for rx irq handling */ -+ -+/*rx workqueue information*/ -+ /*lock to BTIF's rx bottom half when kernel thread is used */ -+ struct mutex rx_mtx; -+ struct workqueue_struct *p_rx_wq; -+ struct work_struct rx_work; -+ -+ struct workqueue_struct *p_tx_wq; -+ struct work_struct tx_work; -+ struct kfifo *p_tx_fifo; -+ -+/*rx tasklet information*/ -+ struct tasklet_struct rx_tasklet; -+ /*lock to BTIF's rx bottom half when tasklet is used */ -+ spinlock_t rx_tasklet_spinlock; -+ -+/*rx thread information*/ -+ struct task_struct *p_task; -+ struct completion rx_comp; -+ -+ mtk_btif_setting *setting; /*BTIF setting */ -+ -+ p_mtk_btif_dma p_tx_dma; /*BTIF Tx channel DMA */ -+ p_mtk_btif_dma p_rx_dma; /*BTIF Rx channel DMA */ -+ -+ MTK_WCN_BTIF_RX_CB rx_cb; /*Rx callback function */ -+ MTK_BTIF_RX_NOTIFY rx_notify; -+ -+ P_MTK_BTIF_INFO_STR p_btif_info; /*BTIF's information */ -+ -+/*Log Tx data to buffer*/ -+ BTIF_LOG_QUEUE_T tx_log; -+ -+/*Log Rx data to buffer*/ -+ BTIF_LOG_QUEUE_T rx_log; -+ -+/* struct list_head *p_user_list; */ -+ struct list_head user_list; -+/* get btif dev pointer*/ -+ void *private_data; -+} mtk_btif, *p_mtk_btif; -+/*---------------------------------------------------------------------------*/ -+ -+/*---------------------------------------------------------------------------*/ -+#if 0 -+/*---------------------------------------------------------------------------*/ -+typedef struct _mtk_dma_register_ { -+ unsigned int int_flag; /*Tx offset:0x0 Rx offset:0x0 */ -+ unsigned int int_enable; /*Tx offset:0x4 Rx offset:0x4 */ -+ unsigned int dma_enable; /*Tx offset:0x8 Rx offset:0x8 */ -+ unsigned int dma_reset; /*Tx offset:0xc Rx offset:0xc */ -+ unsigned int dma_stop; /*Tx offset:0x10 Rx offset:0x10 */ -+ unsigned int dma_flush; /*Tx offset:0x14 Rx offset:0x14 */ -+ unsigned int vff_addr; /*Tx offset:0x1c Rx offset:0x1c */ -+ unsigned int vff_len; /*Tx offset:0x24 Rx offset:0x24 */ -+ unsigned int vff_thr; /*Tx offset:0x28 Rx offset:0x28 */ -+ unsigned int vff_wpt; /*Tx offset:0x2c Rx offset:0x2c */ -+ unsigned int vff_rpt; /*Tx offset:0x30 Rx offset:0x30 */ -+ unsigned int rx_fc_thr; /*Tx:No this register Rx offset:0x34 */ -+ unsigned int int_buf_size; /*Tx offset:0x38 Rx offset:0x38 */ -+ unsigned int vff_valid_size; /*Tx offset:0x3c Rx offset:0x3c */ -+ unsigned int vff_left_size; /*Tx offset:0x40 Rx offset:0x40 */ -+ unsigned int debug_status; /*Tx offset:0x50 Rx offset:0x50 */ -+} mtk_dma_register, *p_mtk_dma_register; -+/*---------------------------------------------------------------------------*/ -+#endif -+ -+/*---------------------------------------------------------------------------*/ -+typedef struct _mtk_btif_user_ { -+ bool enable; /*register its state */ -+ struct list_head entry; /*btif_user's bi-direction list table */ -+ /*BTIF's user, static allocation */ -+ char u_name[BTIF_USER_NAME_MAX_LEN]; -+ unsigned long u_id; -+ p_mtk_btif p_btif; -+} mtk_btif_user, *p_mtk_btif_user; -+ -+/*---------------------------------------------------------------------------*/ -+#define BBS_PTR(ptr, idx) ((ptr->p_buf) + idx) -+ -+#define BBS_SIZE(ptr) ((ptr)->size) -+#define BBS_MASK(ptr) (BBS_SIZE(ptr) - 1) -+#define BBS_COUNT(ptr) ((ptr)->wr_idx >= (ptr)->rd_idx ? (ptr)->wr_idx - \ -+(ptr)->rd_idx : BBS_SIZE(ptr) - \ -+((ptr)->rd_idx - (ptr)->wr_idx)) -+#define BBS_COUNT_CUR(ptr, wr_idx) (wr_idx >= (ptr)->rd_idx ? wr_idx - \ -+(ptr)->rd_idx : BBS_SIZE(ptr) - \ -+((ptr)->rd_idx - wr_idx)) -+ -+#define BBS_LEFT(ptr) (BBS_SIZE(ptr) - BBS_COUNT(ptr)) -+ -+#define BBS_AVL_SIZE(ptr) (BBS_SIZE(ptr) - BBS_COUNT(ptr)) -+#define BBS_FULL(ptr) (BBS_COUNT(ptr) - BBS_SIZE(ptr)) -+#define BBS_EMPTY(ptr) ((ptr)->wr_idx == (ptr)->rd_idx) -+#define BBS_WRITE_MOVE_NEXT(ptr) ((ptr)->wr_idx = \ -+((ptr)->wr_idx + 1) & BBS_MASK(ptr)) -+#define BBS_READ_MOVE_NEXT(ptr) ((ptr)->rd_idx = \ -+((ptr)->rd_idx + 1) & BBS_MASK(ptr)) -+ -+#define BBS_INIT(ptr) \ -+{ \ -+(ptr)->rd_idx = (ptr)->wr_idx = 0; \ -+(ptr)->size = BTIF_RX_BUFFER_SIZE; \ -+} -+ -+ -+#define BTIF_MUTEX_UNLOCK(x) mutex_unlock(x) -+ -+extern mtk_btif g_btif[]; -+ -+int btif_open(p_mtk_btif p_btif); -+int btif_close(p_mtk_btif p_btif); -+int btif_send_data(p_mtk_btif p_btif, -+ const unsigned char *p_buf, unsigned int buf_len); -+int btif_enter_dpidle(p_mtk_btif p_btif); -+int btif_exit_dpidle(p_mtk_btif p_btif); -+int btif_rx_cb_reg(p_mtk_btif p_btif, MTK_WCN_BTIF_RX_CB rx_cb); -+ -+/*for test purpose*/ -+int _btif_suspend(p_mtk_btif p_btif); -+int _btif_resume(p_mtk_btif p_btif); -+int _btif_restore_noirq(p_mtk_btif p_btif); -+ -+int btif_lpbk_ctrl(p_mtk_btif p_btif, bool flag); -+int btif_log_buf_dmp_in(P_BTIF_LOG_QUEUE_T p_log_que, const char *p_buf, -+ int len); -+int btif_dump_data(char *p_buf, int len); -+int btif_log_buf_dmp_out(P_BTIF_LOG_QUEUE_T p_log_que); -+int btif_log_buf_enable(P_BTIF_LOG_QUEUE_T p_log_que); -+int btif_log_buf_disable(P_BTIF_LOG_QUEUE_T p_log_que); -+int btif_log_output_enable(P_BTIF_LOG_QUEUE_T p_log_que); -+int btif_log_output_disable(P_BTIF_LOG_QUEUE_T p_log_que); -+int btif_log_buf_reset(P_BTIF_LOG_QUEUE_T p_log_que); -+int btif_log_buf_init(p_mtk_btif p_btif); -+int btif_dump_reg(p_mtk_btif p_btif); -+int btif_rx_notify_reg(p_mtk_btif p_btif, MTK_BTIF_RX_NOTIFY rx_notify); -+int btif_raise_wak_signal(p_mtk_btif p_btif); -+int btif_clock_ctrl(p_mtk_btif p_btif, int en); -+bool btif_parser_wmt_evt(p_mtk_btif p_btif, -+ const char *sub_str, -+ unsigned int sub_len); -+void mtk_btif_read_cpu_sw_rst_debug(void); -+ -+#endif /*__MTK_BTIF_H_*/ -diff --git a/drivers/misc/mediatek/btif/common/inc/mtk_btif_exp.h b/drivers/misc/mediatek/btif/common/inc/mtk_btif_exp.h -new file mode 100644 -index 000000000000..3752644fe0aa ---- /dev/null -+++ b/drivers/misc/mediatek/btif/common/inc/mtk_btif_exp.h -@@ -0,0 +1,280 @@ -+/* -+ * Copyright (C) 2015 MediaTek Inc. -+ * -+ * 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. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#ifndef _MTK_BTIF_EXP_H_ -+#define _MTK_BTIF_EXP_H_ -+ -+/*--------------marco defination---------------*/ -+#define BTIF_MAX_LEN_PER_PKT 2048 -+#define BTIF_RXD_BE_BLOCKED_DETECT 1 -+/*--------------Enum Defination---------------*/ -+typedef enum _ENUM_BTIF_DPIDLE_ { -+ BTIF_DPIDLE_DISABLE = 0, -+ BTIF_DPIDLE_ENABLE = BTIF_DPIDLE_DISABLE + 1, -+ BTIF_DPIDLE_MAX, -+} ENUM_BTIF_DPIDLE_CTRL; -+ -+typedef enum _ENUM_BTIF_LPBK_MODE_ { -+ BTIF_LPBK_DISABLE = 0, -+ BTIF_LPBK_ENABLE = BTIF_LPBK_DISABLE + 1, -+ BTIF_LPBK_MAX, -+} ENUM_BTIF_LPBK_MODE; -+ -+typedef enum _ENUM_BTIF_DBG_ID_ { -+ BTIF_DISABLE_LOGGER = 0, -+ BTIF_ENABLE_LOGGER = BTIF_DISABLE_LOGGER + 1, -+ BTIF_DUMP_LOG = BTIF_ENABLE_LOGGER + 1, -+ BTIF_CLR_LOG = BTIF_DUMP_LOG + 1, -+ BTIF_DUMP_BTIF_REG = BTIF_CLR_LOG + 1, -+ BTIF_ENABLE_RT_LOG = BTIF_DUMP_BTIF_REG + 1, -+ BTIF_DISABLE_RT_LOG = BTIF_ENABLE_RT_LOG + 1, -+ BTIF_DBG_MAX, -+} ENUM_BTIF_DBG_ID; -+ -+typedef enum _ENUM_BTIF_OP_ERROR_CODE_ { -+ E_BTIF_AGAIN = 0, -+ E_BTIF_FAIL = -1, -+ E_BTIF_BAD_POINTER = -2, -+ E_BTIF_NO_SPACE = -3, -+ E_BTIF_INTR = -4, -+ E_BTIF_INVAL_PARAM = -5, -+ E_BTIF_ALREADY_OPEN = -6, -+ E_BTIF_NOT_OPEN = -7, -+ E_BTIF_INVAL_STATE = -8, -+} ENUM_BTIF_OP_ERROR_CODE; -+ -+/*--------------End of Enum Defination---------------*/ -+ -+/*--------------Type Definition---------------*/ -+ -+typedef int (*MTK_WCN_BTIF_RX_CB) (const unsigned char *p_buf, -+ unsigned int len); -+ -+/*--------------End of Type Definition---------------*/ -+ -+/*--------------Normal Mode API declearation---------------*/ -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_btif_open -+* DESCRIPTION -+* open BTIF interface, will do BTIF module HW and SW initialization -+* PARAMETERS -+* p_owner [IN] pointer to owner who call this API, -+* currently there are 2 owner ("stp" or "btif_tester") -+* may use this module -+* user's id string must be less than 32 bytes -+* for "stp", BTIF will call rx callback function to route rx data to STP module -+* for "stp_tester", BTIF will save rx data -+* and wait for native process to access -+* p_id [IN] BTIF's user id will be put to this address -+* RETURNS -+* int 0 = succeed; others = fail, for detailed information, -+* please see ENUM_BTIF_OP_ERROR_CODE -+* if open success, value p_id will be the only identifier for -+* user to access BTIF's other operations -+* including read/write/dpidle_ctrl/rx_cb_retister -+* this user id is only an identifier used for owner identification -+*****************************************************************************/ -+int mtk_wcn_btif_open(char *p_owner, unsigned long *p_id); -+//EXPORT_SYMBOL(mtk_wcn_btif_open) -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_btif_close -+* DESCRIPTION -+* close BTIF interface, will do BTIF module HW and SW de-initialization -+* once this API is called, p_btif should never be used by BTIF's user again -+* PARAMETERS -+* u_id [IN] BTIF's user id -+* RETURNS -+* int 0 = succeed; -+* others = fail, for detailed information, please see ENUM_BTIF_OP_ERROR_CODE -+*****************************************************************************/ -+int mtk_wcn_btif_close(unsigned long u_id); -+//EXPORT_SYMBOL(mtk_wcn_btif_close) -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_btif_write -+* DESCRIPTION -+* send data throuth BTIF module -+* there's no internal buffer to cache STP data in BTIF driver, -+* if in DMA mode -+* btif driver will check if there's enough space -+* in vFIFO for data to send in DMA mode -+* if yes, put data to vFIFO and return corresponding data length to caller -+* if no, corresponding error code will be returned to called -+* PARAMETERS -+* p_btif [IN] pointer returned by mtk_wcn_btif_open -+* p_buf [IN] pointer to target data to send -+* len [IN] data length (should be less than 2014 bytes per STP package) -+* -+* if in non-DMA mode, BTIF driver will try to write to THR of BTIF controller -+* if btif driver detected that no space is available in Tx FIFO, -+* will return E_BTIF_NO_SPACE, -+* mostly something is wrong with BTIF or consys when this -+* return value is returned -+* RETURNS -+* int positive: data length send through BTIF; -+* negative: please see ENUM_BTIF_OP_ERROR_CODE -+* E_BTIF_AGAIN (0) will be returned to caller if btif does not have -+* enough vFIFO to send data, when caller get 0, -+* he should wait for a moment (5~10ms maybe) and -+* try a few times (maybe 10~20) -+* if still get E_BTIF_AGAIN, should call BTIF's debug API and -+* dump BTIF driver and BTIF/DMA register information to kernel log -+* for debug -+* E_BTIF_BAD_POINTER will be returned to caller if btif is not -+* opened successfully before call this API -+* E_BTIF_INVAL_PARAM will be returned if parameter is not valid -+ -+*****************************************************************************/ -+int mtk_wcn_btif_write(unsigned long u_id, -+ const unsigned char *p_buf, unsigned int len); -+//EXPORT_SYMBOL(mtk_wcn_btif_write) -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_btif_read -+* DESCRIPTION -+* read data from BTIF module -+* PARAMETERS -+* p_btif [IN] pointer returned by mtk_wcn_btif_open -+* p_buf [IN/OUT] pointer to buffer where rx data will be put -+* max_len [IN] max buffer length -+* RETURNS -+* int positive: data length read from BTIF; -+* negative: please see ENUM_BTIF_OP_ERROR_CODE -+*****************************************************************************/ -+int mtk_wcn_btif_read(unsigned long u_id, -+ unsigned char *p_buf, unsigned int max_len); -+//EXPORT_SYMBOL(mtk_wcn_btif_read) -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_btif_dpidle_ctrl -+* DESCRIPTION -+* control if BTIF module allow system enter deepidle state or not -+* PARAMETERS -+* p_btif [IN] pointer returned by mtk_wcn_btif_open -+* en_flag [IN] one of ENUM_BTIF_DPIDLE_CTRL -+* RETURNS -+* int always return 0 -+*****************************************************************************/ -+int mtk_wcn_btif_dpidle_ctrl(unsigned long u_id, ENUM_BTIF_DPIDLE_CTRL en_flag); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_btif_rx_cb_register -+* DESCRIPTION -+* register rx callback function to BTIF module by btif user -+* PARAMETERS -+* p_btif [IN] pointer returned by mtk_wcn_btif_open -+* rx_cb [IN] pointer to stp rx handler callback function, -+* should be comply with MTK_WCN_BTIF_RX_CB -+* RETURNS -+* int 0 = succeed; -+* others = fail, for detailed information, please see ENUM_BTIF_OP_ERROR_CODE -+*****************************************************************************/ -+int mtk_wcn_btif_rx_cb_register(unsigned long u_id, MTK_WCN_BTIF_RX_CB rx_cb); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_btif_wakeup_consys -+* DESCRIPTION -+* once sleep command is sent to con sys, -+* should call this API before send wakeup command to -+* make con sys aware host want to send data to consys -+* PARAMETERS -+* p_btif [IN] pointer returned by mtk_wcn_btif_open -+* RETURNS -+* int 0 = succeed; -+* others = fail, for detailed information, please see ENUM_BTIF_OP_ERROR_CODE -+*****************************************************************************/ -+int mtk_wcn_btif_wakeup_consys(unsigned long u_id); -+ -+/*--------------End of Normal Mode API declearation----------------*/ -+ -+/*--------------Debug Purpose API declearation----------------*/ -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_btif_loopback_ctrl -+* DESCRIPTION -+* enable/disable BTIF internal loopback function, -+* when this function is enabled, -+* data send to btif will be received by btif itself -+* only for debug purpose, should never use this function in normal mode -+* PARAMETERS -+* p_btif [IN] pointer returned by mtk_wcn_btif_open -+* enable [IN] loopback mode control flag, enable or disable, -+* shou be one of ENUM_BTIF_LPBK_MODE -+* RETURNS -+* int 0 = succeed; -+* others = fail, for detailed information, please see ENUM_BTIF_OP_ERROR_CODE -+*****************************************************************************/ -+int mtk_wcn_btif_loopback_ctrl(unsigned long u_id, ENUM_BTIF_LPBK_MODE enable); -+//EXPORT_SYMBOL(mtk_wcn_btif_loopback_ctrl) -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_btif_logger_ctrl -+* DESCRIPTION -+* control BTIF logger function's behavior -+* PARAMETERS -+* p_btif [IN] pointer returned by mtk_wcn_btif_open -+* flag [IN] should be one of ENUM_BTIF_DBG_ID -+* BTIF_DISABLE_LOGGER - disable btif logger -+* BTIF_ENABLE_LOGGER - enable btif logger -+* BTIF_DUMP_LOG - dump log logged by btif -+* BTIF_CLR_LOG - clear btif log buffer -+* BTIF_DUMP_BTIF_REG - dump btif controller's register -+* BTIF_DUMP_DMA_REG - dump DMA controller's register -+* RETURNS -+* int 0 = succeed; -+* others = fail, for detailed information, -+* please see ENUM_BTIF_OP_ERROR_CODE -+*****************************************************************************/ -+int mtk_wcn_btif_dbg_ctrl(unsigned long u_id, ENUM_BTIF_DBG_ID flag); -+//EXPORT_SYMBOL(mtk_wcn_btif_dbg_ctrl); -+/*-----------End of Debug Purpose API declearation------------*/ -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_btif_parser_wmt_evt -+* DESCRIPTION -+* parser wmt sleep/wakeup evt in btif bbs buffer for debug -+* PARAMETERS -+* p_btif [IN] pointer returned by mtk_wcn_btif_open -+* sub_str [IN] the str to be parsered -+* str_len [IN] the length of sub_str -+* RETURNS -+* bool true = succeed; -+* false = fail; -+*****************************************************************************/ -+bool mtk_wcn_btif_parser_wmt_evt(unsigned long u_id, -+ const char *sub_str, unsigned int str_len); -+ -+int mtk_btif_exp_open_test(void); -+int mtk_btif_exp_close_test(void); -+int mtk_btif_exp_write_test(void); -+int mtk_btif_exp_suspend_test(void); -+int mtk_btif_exp_resume_test(void); -+int mtk_btif_exp_enter_dpidle_test(void); -+int mtk_btif_exp_exit_dpidle_test(void); -+int mtk_btif_exp_write_stress_test(unsigned int length, unsigned int loop); -+int mtk_btif_exp_log_debug_test(int flag); -+int mtk_btif_exp_restore_noirq_test(void); -+int btif_wakeup_consys_no_id(void); -+int mtk_btif_exp_clock_ctrl(int en); -+#if BTIF_RXD_BE_BLOCKED_DETECT -+int mtk_btif_rxd_be_blocked_flag_get(void); -+#endif -+void mtk_btif_read_cpu_sw_rst_debug_exp(void); -+#endif /*_MTK_BTIF_EXP_H_*/ -diff --git a/drivers/misc/mediatek/btif/common/mtk_btif.c b/drivers/misc/mediatek/btif/common/mtk_btif.c -new file mode 100644 -index 000000000000..0212ad41049f ---- /dev/null -+++ b/drivers/misc/mediatek/btif/common/mtk_btif.c -@@ -0,0 +1,3472 @@ -+/* -+ * Copyright (C) 2015 MediaTek Inc. -+ * -+ * 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. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+/*-----------linux system header files----------------*/ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+/*#include */ -+/*-----------driver own header files----------------*/ -+#ifdef CONFIG_COMPAT -+#include -+#endif -+#ifdef DFT_TAG -+#undef DFT_TAG -+#endif -+#define DFT_TAG "MTK-BTIF" -+ -+#define BTIF_CDEV_SUPPORT 1 -+ -+#include "btif_pub.h" -+#include "btif_dma_pub.h" -+#include "mtk_btif_exp.h" -+#include "mtk_btif.h" -+ -+/*-----------static function declearation----------------*/ -+static int mtk_btif_probe(struct platform_device *pdev); -+static int mtk_btif_remove(struct platform_device *pdev); -+static int mtk_btif_suspend(struct platform_device *pdev, pm_message_t state); -+static int mtk_btif_resume(struct platform_device *pdev); -+static int mtk_btif_drv_resume(struct device *dev); -+static int mtk_btif_drv_suspend(struct device *pdev); -+ -+static int mtk_btif_restore_noirq(struct device *device); -+static int btif_file_open(struct inode *pinode, struct file *pfile); -+static int btif_file_release(struct inode *pinode, struct file *pfile); -+static ssize_t btif_file_read(struct file *pfile, -+ char __user *buf, size_t count, loff_t *f_ops); -+static unsigned int btif_poll(struct file *filp, poll_table *wait); -+static int _btif_irq_reg(P_MTK_BTIF_IRQ_STR p_irq, -+ mtk_btif_irq_handler irq_handler, void *data); -+static int _btif_irq_free(P_MTK_BTIF_IRQ_STR p_irq, void *data); -+static int _btif_irq_ctrl(P_MTK_BTIF_IRQ_STR p_irq, bool en); -+static int _btif_irq_ctrl_sync(P_MTK_BTIF_IRQ_STR p_irq, bool en); -+static irqreturn_t btif_irq_handler(int irq, void *data); -+static unsigned int btif_pio_rx_data_receiver(P_MTK_BTIF_INFO_STR p_btif_info, -+ unsigned char *p_buf, -+ unsigned int buf_len); -+ -+static irqreturn_t btif_tx_dma_irq_handler(int irq, void *data); -+static irqreturn_t btif_rx_dma_irq_handler(int irq, void *data); -+ -+static unsigned int btif_dma_rx_data_receiver(P_MTK_DMA_INFO_STR p_dma_info, -+ unsigned char *p_buf, -+ unsigned int buf_len); -+static int _btif_controller_tx_setup(p_mtk_btif p_btif); -+static int _btif_controller_tx_free(p_mtk_btif p_btif); -+static int _btif_controller_rx_setup(p_mtk_btif p_btif); -+static int _btif_controller_rx_free(p_mtk_btif p_btif); -+static int _btif_tx_pio_setup(p_mtk_btif p_btif); -+static int _btif_rx_pio_setup(p_mtk_btif p_btif); -+static int _btif_rx_dma_setup(p_mtk_btif p_btif); -+static int _btif_rx_dma_free(p_mtk_btif p_btif); -+static int _btif_tx_dma_setup(p_mtk_btif p_btif); -+static int _btif_tx_dma_free(p_mtk_btif p_btif); -+static int _btif_controller_setup(p_mtk_btif p_btif); -+static int _btif_controller_free(p_mtk_btif p_btif); -+ -+static int _btif_pio_write(p_mtk_btif p_btif, -+ const unsigned char *p_buf, unsigned int buf_len); -+static int _btif_dma_write(p_mtk_btif p_btif, -+ const unsigned char *p_buf, unsigned int buf_len); -+ -+static unsigned int btif_bbs_wr_direct(p_btif_buf_str p_bbs, -+ unsigned char *p_buf, unsigned int buf_len); -+static unsigned int btif_bbs_read(p_btif_buf_str p_bbs, -+ unsigned char *p_buf, unsigned int buf_len); -+static unsigned int btif_bbs_write(p_btif_buf_str p_bbs, -+ unsigned char *p_buf, unsigned int buf_len); -+static void btif_dump_bbs_str(unsigned char *p_str, p_btif_buf_str p_bbs); -+static int _btif_dump_memory(char *str, unsigned char *p_buf, unsigned int buf_len); -+static int _btif_rx_btm_deinit(p_mtk_btif p_btif); -+static int _btif_rx_btm_sched(p_mtk_btif p_btif); -+static int _btif_rx_btm_init(p_mtk_btif p_btif); -+static void btif_rx_tasklet(unsigned long func_data); -+static void btif_rx_worker(struct work_struct *p_work); -+static int btif_rx_thread(void *p_data); -+static int btif_rx_data_consummer(p_mtk_btif p_btif); -+ -+static int _btif_tx_ctx_init(p_mtk_btif p_btif); -+static int _btif_tx_ctx_deinit(p_mtk_btif p_btif); -+static void btif_tx_worker(struct work_struct *p_work); -+ -+static int _btif_state_deinit(p_mtk_btif p_btif); -+static int _btif_state_release(p_mtk_btif p_btif); -+static ENUM_BTIF_STATE _btif_state_get(p_mtk_btif p_btif); -+static int _btif_state_set(p_mtk_btif p_btif, ENUM_BTIF_STATE state); -+static int _btif_state_hold(p_mtk_btif p_btif); -+static int _btif_state_init(p_mtk_btif p_btif); -+ -+static int _btif_dpidle_notify_ctrl(p_mtk_btif p_btif, -+ ENUM_BTIF_DPIDLE_CTRL en_flag); -+static int _btif_enter_dpidle(p_mtk_btif p_btif); -+static int _btif_exit_dpidle(p_mtk_btif p_btif); -+static int _btif_exit_dpidle_from_sus(p_mtk_btif p_btif); -+static int _btif_exit_dpidle_from_dpidle(p_mtk_btif p_btif); -+static int _btif_enter_dpidle_from_on(p_mtk_btif p_btif); -+static int _btif_enter_dpidle_from_sus(p_mtk_btif p_btif); -+ -+#if ENABLE_BTIF_TX_DMA -+static int _btif_vfifo_deinit(p_mtk_btif_dma p_dma); -+static int _btif_vfifo_init(p_mtk_btif_dma p_dma); -+#endif -+ -+static bool _btif_is_tx_complete(p_mtk_btif p_btif); -+static int _btif_init(p_mtk_btif p_btif); -+static int _btif_lpbk_ctrl(p_mtk_btif p_btif, bool flag); -+static int btif_rx_dma_mode_set(int en); -+static int btif_tx_dma_mode_set(int en); -+ -+static int _btif_send_data(p_mtk_btif p_btif, -+ const unsigned char *p_buf, unsigned int buf_len); -+ -+/*-----------end of static function declearation----------------*/ -+ -+static const char *g_state[B_S_MAX] = { -+ "OFF", -+ "SUSPEND", -+ "DPIDLE", -+ "ON", -+}; -+ -+/*-----------BTIF setting--------------*/ -+mtk_btif_setting g_btif_setting[BTIF_PORT_NR] = { -+ { -+ .tx_mode = BTIF_TX_MODE, -+ .rx_mode = BTIF_RX_MODE, -+ .rx_type = BTIF_RX_BTM_CTX, -+ .tx_type = BTIF_TX_CTX, -+ }, -+}; -+ -+mtk_btif g_btif[BTIF_PORT_NR] = { -+ { -+ .open_counter = 0, -+ .state = B_S_OFF, -+ .setting = &g_btif_setting[0], -+ .p_tx_dma = NULL, -+ .p_rx_dma = NULL, -+ .rx_cb = NULL, -+ .p_btif_info = NULL, -+ }, -+}; -+ -+mtk_btif_dma g_dma[BTIF_PORT_NR][BTIF_DIR_MAX] = { -+ { -+ { -+ .p_btif = NULL, -+ .dir = BTIF_TX, -+ .p_dma_info = NULL, -+ .entry = ATOMIC_INIT(0), -+ }, -+ { -+ .p_btif = NULL, -+ .dir = BTIF_RX, -+ .p_dma_info = NULL, -+ .entry = ATOMIC_INIT(0), -+ }, -+ }, -+}; -+ -+#define G_MAX_PKG_LEN (7 * 1024) -+static int g_max_pkg_len = G_MAX_PKG_LEN; /*DMA vFIFO is set to 8 * 1024, we set this to 7/8 * vFIFO size*/ -+static int g_max_pding_data_size = BTIF_RX_BUFFER_SIZE * 3 / 4; -+ -+ -+static int mtk_btif_dbg_lvl = BTIF_LOG_ERR; -+ -+#if BTIF_RXD_BE_BLOCKED_DETECT -+static struct timeval btif_rxd_time_stamp[MAX_BTIF_RXD_TIME_REC]; -+#endif -+/*-----------Platform bus related structures----------------*/ -+#define DRV_NAME "mtk_btif" -+ -+#ifdef CONFIG_OF -+const struct of_device_id apbtif_of_ids[] = { -+ { .compatible = "mediatek,mtk-btif", }, -+ {} -+}; -+#endif -+ -+const struct dev_pm_ops mtk_btif_drv_pm_ops = { -+ .restore_noirq = mtk_btif_restore_noirq, -+ .suspend = mtk_btif_drv_suspend, -+ .resume = mtk_btif_drv_resume, -+}; -+ -+struct platform_driver mtk_btif_dev_drv = { -+ .probe = mtk_btif_probe, -+ .remove = mtk_btif_remove, -+#ifdef CONFIG_PM -+ .suspend = mtk_btif_suspend, -+ .resume = mtk_btif_resume, -+#endif -+ .driver = { -+ .name = DRV_NAME, -+ .owner = THIS_MODULE, -+#ifdef CONFIG_PM -+ .pm = &mtk_btif_drv_pm_ops, -+#endif -+#ifdef CONFIG_OF -+ .of_match_table = apbtif_of_ids, -+#endif -+ } -+}; -+ -+#define BTIF_STATE_RELEASE(x) _btif_state_release(x) -+ -+/*-----------End of Platform bus related structures----------------*/ -+ -+/*-----------platform bus related operation APIs----------------*/ -+ -+static int mtk_btif_probe(struct platform_device *pdev) -+{ -+/*Chaozhong: ToDo: to be implement*/ -+/*register IRQ for BTIF and Tx Rx DMA and disable them by default*/ -+ BTIF_INFO_FUNC("DO BTIF PROBE\n"); -+ platform_set_drvdata(pdev, &g_btif[0]); -+ g_btif[0].private_data = (struct device *)&pdev->dev; -+ -+#if !defined(CONFIG_MTK_CLKMGR) -+ hal_btif_clk_get_and_prepare(pdev); -+#endif -+ -+ return 0; -+} -+ -+static int mtk_btif_remove(struct platform_device *pdev) -+{ -+/*Chaozhong: ToDo: to be implement*/ -+ BTIF_INFO_FUNC("DO BTIF REMOVE\n"); -+ platform_set_drvdata(pdev, NULL); -+ g_btif[0].private_data = NULL; -+ return 0; -+} -+ -+int _btif_suspend(p_mtk_btif p_btif) -+{ -+ int i_ret; -+ -+ if (_btif_state_hold(p_btif)) -+ return E_BTIF_INTR; -+ if (p_btif != NULL) { -+ if (!(p_btif->enable)) -+ i_ret = 0; -+ else { -+ if (_btif_state_get(p_btif) == B_S_ON) { -+ BTIF_ERR_FUNC("BTIF in ON state,", -+ "there are data need to be send or recev,suspend fail\n"); -+ i_ret = -1; -+ } else { -+ /* -+ * before disable BTIF controller and DMA controller -+ * we need to set BTIF to ON state -+ */ -+ i_ret = _btif_exit_dpidle(p_btif); -+ if (i_ret == 0) { -+ i_ret += _btif_controller_free(p_btif); -+ i_ret = _btif_controller_tx_free(p_btif); -+ i_ret += _btif_controller_rx_free(p_btif); -+ } -+ if (i_ret != 0) { -+ BTIF_INFO_FUNC("failed\n"); -+ /*Chaozhong: what if failed*/ -+ } else { -+ BTIF_INFO_FUNC("succeed\n"); -+ i_ret = _btif_state_set(p_btif, B_S_SUSPEND); -+ if (i_ret && _btif_init(p_btif)) { -+ /*Chaozhong:BTIF re-init failed? what to do*/ -+ i_ret = _btif_state_set(p_btif, B_S_OFF); -+ } -+ } -+ } -+ } -+ } else -+ i_ret = -1; -+ BTIF_STATE_RELEASE(p_btif); -+ -+ return i_ret; -+} -+ -+ -+static int mtk_btif_drv_suspend(struct device *dev) -+{ -+ struct platform_device *pdev = to_platform_device(dev); -+ pm_message_t state = PMSG_SUSPEND; -+ -+ return mtk_btif_suspend(pdev, state); -+} -+ -+static int mtk_btif_drv_resume(struct device *dev) -+{ -+ struct platform_device *pdev = to_platform_device(dev); -+ -+ return mtk_btif_resume(pdev); -+} -+ -+static int mtk_btif_suspend(struct platform_device *pdev, pm_message_t state) -+{ -+ int i_ret = 0; -+ p_mtk_btif p_btif = NULL; -+ -+/*Chaozhong: ToDo: to be implement*/ -+ BTIF_DBG_FUNC("++\n"); -+ p_btif = platform_get_drvdata(pdev); -+ i_ret = _btif_suspend(p_btif); -+ BTIF_DBG_FUNC("--, i_ret:%d\n", i_ret); -+ return i_ret; -+} -+ -+int _btif_restore_noirq(p_mtk_btif p_btif) -+{ -+ int i_ret = 0; -+ -+/*BTIF IRQ restore no irq*/ -+ i_ret = hal_btif_pm_ops(p_btif->p_btif_info, BTIF_PM_RESTORE_NOIRQ); -+ if (i_ret == 0) { -+ BTIF_INFO_FUNC("BTIF HW IRQ restore succeed\n"); -+ } else { -+ BTIF_INFO_FUNC("BTIF HW IRQ restore failed, i_ret:%d\n", i_ret); -+ return i_ret; -+ } -+/*BTIF DMA restore no irq*/ -+ if (p_btif->tx_mode & BTIF_MODE_DMA) { -+ i_ret = hal_dma_pm_ops(p_btif->p_tx_dma->p_dma_info, -+ BTIF_PM_RESTORE_NOIRQ); -+ if (i_ret == 0) { -+ BTIF_INFO_FUNC("BTIF Tx DMA IRQ restore succeed\n"); -+ } else { -+ BTIF_INFO_FUNC -+ ("BTIF Tx DMA IRQ restore failed, i_ret:%d\n", -+ i_ret); -+ return i_ret; -+ } -+ } -+ if (p_btif->rx_mode & BTIF_MODE_DMA) { -+ i_ret = hal_dma_pm_ops(p_btif->p_rx_dma->p_dma_info, -+ BTIF_PM_RESTORE_NOIRQ); -+ if (i_ret == 0) { -+ BTIF_INFO_FUNC("BTIF Rx DMA IRQ restore succeed\n"); -+ } else { -+ BTIF_INFO_FUNC -+ ("BTIF Rx DMA IRQ restore failed, i_ret:%d\n", -+ i_ret); -+ return i_ret; -+ } -+ } -+ return i_ret; -+} -+ -+static int mtk_btif_restore_noirq(struct device *dev) -+{ -+ int i_ret = 0; -+ struct platform_device *pdev = to_platform_device(dev); -+ p_mtk_btif p_btif = platform_get_drvdata(pdev); -+ -+ BTIF_INFO_FUNC("++\n"); -+ if (_btif_state_hold(p_btif)) -+ return E_BTIF_INTR; -+ if (p_btif->enable) -+ BTIF_ERR_FUNC("!!!-----------------!BTIF is not closed before IPOH shutdown!!!---------------!\n"); -+ WARN_ON(p_btif->enable); -+ -+ i_ret = _btif_restore_noirq(p_btif); -+ BTIF_STATE_RELEASE(p_btif); -+ BTIF_INFO_FUNC("--\n"); -+ return 0; -+} -+ -+int _btif_resume(p_mtk_btif p_btif) -+{ -+ int i_ret = 0; -+ ENUM_BTIF_STATE state = B_S_MAX; -+ -+ if (_btif_state_hold(p_btif)) -+ return E_BTIF_INTR; -+ if (p_btif != NULL) { -+ state = _btif_state_get(p_btif); -+ if (!(p_btif->enable)) -+ i_ret = 0; -+ else if (state == B_S_SUSPEND) -+ i_ret = _btif_enter_dpidle(p_btif); -+ else -+ BTIF_INFO_FUNC -+ ("BTIF state: %s before resume, do nothing\n", g_state[state]); -+ } else -+ i_ret = -1; -+ BTIF_STATE_RELEASE(p_btif); -+ -+ return i_ret; -+} -+ -+static int mtk_btif_resume(struct platform_device *pdev) -+{ -+ int i_ret = 0; -+ p_mtk_btif p_btif = NULL; -+/*Chaozhong: ToDo: to be implement*/ -+ BTIF_DBG_FUNC("++\n"); -+ p_btif = platform_get_drvdata(pdev); -+ i_ret = _btif_resume(p_btif); -+ BTIF_DBG_FUNC("--, i_ret:%d\n", i_ret); -+ return 0; -+} -+ -+/*-----------device node----------------*/ -+#if BTIF_CDEV_SUPPORT -+ -+dev_t btif_dev; -+struct class *p_btif_class; -+struct device *p_btif_dev; -+const char *p_btif_dev_name = "btif"; -+static struct semaphore wr_mtx; -+static struct semaphore rd_mtx; -+unsigned char wr_buf[2048]; -+unsigned char rd_buf[2048]; -+static int rx_notify_flag; -+static DECLARE_WAIT_QUEUE_HEAD(btif_wq); -+static int btif_file_open(struct inode *pinode, struct file *pfile); -+static int btif_file_release(struct inode *pinode, struct file *pfile); -+static ssize_t btif_file_read(struct file *pfile, -+ char __user *buf, size_t count, loff_t *f_ops); -+ -+static ssize_t btif_file_write(struct file *filp, -+ const char __user *buf, size_t count, loff_t *f_pos); -+static long btif_unlocked_ioctl(struct file *filp, unsigned int cmd, -+ unsigned long arg); -+#ifdef CONFIG_COMPAT -+static long btif_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); -+#endif -+static struct cdev btif_dev_c; -+static wait_queue_head_t btif_read_inq; /* read queues */ -+ -+const struct file_operations mtk_btif_fops = { -+ .owner = THIS_MODULE, -+ .open = btif_file_open, -+ .release = btif_file_release, -+ .read = btif_file_read, -+ .write = btif_file_write, -+ .unlocked_ioctl = btif_unlocked_ioctl, -+#ifdef CONFIG_COMPAT -+ .compat_ioctl = btif_compat_ioctl, -+#endif -+ .poll = btif_poll, -+}; -+ -+static int btif_chrdev_init(void) -+{ -+ int i_ret; -+ -+ int i_err; -+ -+ /* alloc device number dynamically */ -+ i_ret = alloc_chrdev_region(&btif_dev, 0, 1, p_btif_dev_name); -+ if (i_ret) { -+ BTIF_ERR_FUNC("devuce number allocation failed, i_ret:%d\n", -+ i_ret); -+ } else { -+ BTIF_INFO_FUNC("devuce number allocation succeed\n"); -+ } -+ cdev_init(&btif_dev_c, &mtk_btif_fops); -+ btif_dev_c.owner = THIS_MODULE; -+ i_err = cdev_add(&btif_dev_c, btif_dev, 1); -+ if (i_err) { -+ BTIF_ERR_FUNC("error add btif dev to kernel, error code:%d\n", -+ i_err); -+ unregister_chrdev_region(btif_dev, 1); -+ btif_dev = 0; -+ return -1; -+ } -+ BTIF_INFO_FUNC("add btif dev to kernel succeed\n"); -+ -+ p_btif_class = class_create(THIS_MODULE, p_btif_dev_name); -+ if (IS_ERR(p_btif_class)) { -+ BTIF_ERR_FUNC("error happened when doing class_create\n"); -+ unregister_chrdev_region(btif_dev, 1); -+ btif_dev = 0; -+ return -2; -+ } -+ BTIF_INFO_FUNC("create class for btif succeed\n"); -+ -+ p_btif_dev = device_create(p_btif_class, -+ NULL, btif_dev, 0, p_btif_dev_name); -+ if (IS_ERR(p_btif_dev)) { -+ BTIF_ERR_FUNC("error happened when doing device_create\n"); -+ class_destroy(p_btif_class); -+ p_btif_class = NULL; -+ unregister_chrdev_region(btif_dev, 1); -+ btif_dev = 0; -+ return -3; -+ } -+ BTIF_INFO_FUNC("create device for btif succeed\n"); -+ -+ return 0; -+} -+ -+void btif_rx_notify_cb(void) -+{ -+ BTIF_DBG_FUNC("++\n"); -+ rx_notify_flag = 1; -+ wake_up(&btif_wq); -+ wake_up_interruptible(&btif_read_inq); -+ BTIF_DBG_FUNC("--\n"); -+} -+ -+unsigned int btif_poll(struct file *filp, poll_table *wait) -+{ -+ unsigned int mask = 0; -+ unsigned int ava_len = 0; -+/* btif_bbs_read(&(g_btif[0].btif_buf), rd_buf, sizeof(rd_buf)); */ -+ unsigned int wr_idx = g_btif[0].btif_buf.wr_idx; -+ -+/* BTIF_Rx_IRQ_Disable(); */ -+ ava_len = BBS_COUNT_CUR(&(g_btif[0].btif_buf), wr_idx); -+ BTIF_INFO_FUNC("++\n"); -+ if (ava_len == 0) { -+ poll_wait(filp, &btif_read_inq, wait); -+ wr_idx = g_btif[0].btif_buf.wr_idx; -+ ava_len = BBS_COUNT_CUR(&(g_btif[0].btif_buf), wr_idx); -+/* btif_bbs_read(&(g_btif[0].btif_buf), rd_buf, sizeof(rd_buf)); */ -+ if (ava_len) -+ mask |= POLLIN | POLLRDNORM; /* readable */ -+ } else { -+ mask |= POLLIN | POLLRDNORM; /* readable */ -+ } -+/*make for writable*/ -+ mask |= POLLOUT | POLLWRNORM; /* writable */ -+ BTIF_INFO_FUNC("--, mask:%d\n", mask); -+ return mask; -+} -+ -+static int _btif_file_open(void) -+{ -+ int i_ret = -1; -+ p_mtk_btif p_btif = &g_btif[0]; -+ -+ BTIF_INFO_FUNC("++\n"); -+ -+/*Chaozhong: ToDo: to be implement*/ -+ i_ret = btif_open(p_btif); -+ if ((i_ret != 0) && (i_ret != E_BTIF_ALREADY_OPEN)) { -+ BTIF_ERR_FUNC("btif_open failed, error code:%d\n", i_ret); -+ } else { -+ BTIF_INFO_FUNC("btif_open succeed\n"); -+ i_ret = 0; -+ } -+/*semaphore for read and write operation init*/ -+ sema_init(&wr_mtx, 1); -+ sema_init(&rd_mtx, 1); -+ -+/*buffer for read and write init*/ -+ memset(wr_buf, 0, sizeof(wr_buf)); -+ memset(rd_buf, 0, sizeof(rd_buf)); -+ init_waitqueue_head(&(btif_read_inq)); -+ btif_rx_notify_reg(p_btif, btif_rx_notify_cb); -+ BTIF_INFO_FUNC("--\n"); -+ return i_ret; -+} -+ -+static int _btif_file_close(void) -+{ -+ int i_ret = -1; -+ -+ BTIF_INFO_FUNC("++\n"); -+/*Chaozhong: ToDo: to be implement*/ -+ i_ret = btif_close(&g_btif[0]); -+ if (i_ret != 0) -+ BTIF_ERR_FUNC("btif_close failed, error code:%d\n", i_ret); -+ else -+ BTIF_INFO_FUNC("btif_close succeed\n"); -+ -+ BTIF_INFO_FUNC("--\n"); -+ return i_ret; -+} -+ -+static int btif_file_open(struct inode *pinode, struct file *pfile) -+{ -+ int i_ret = -1; -+ -+ BTIF_INFO_FUNC("pid:%d\n", current->pid); -+ i_ret = 0; -+ return i_ret; -+} -+ -+static int btif_file_release(struct inode *pinode, struct file *pfile) -+{ -+ int i_ret = -1; -+ -+ BTIF_INFO_FUNC("pid:%d\n", current->pid); -+ i_ret = 0; -+ return i_ret; -+} -+ -+static ssize_t btif_file_read(struct file *pfile, -+ char __user *buf, size_t count, loff_t *f_ops) -+{ -+ int i_ret = 0; -+ int rd_len = 0; -+ -+ BTIF_INFO_FUNC("++\n"); -+ down(&rd_mtx); -+ rd_len = btif_bbs_read(&(g_btif[0].btif_buf), rd_buf, sizeof(rd_buf)); -+ while (rd_len == 0) { -+ if (pfile->f_flags & O_NONBLOCK) -+ break; -+ -+ wait_event(btif_wq, rx_notify_flag != 0); -+ rx_notify_flag = 0; -+ rd_len = -+ btif_bbs_read(&(g_btif[0].btif_buf), rd_buf, -+ sizeof(rd_buf)); -+ } -+ -+ if (rd_len == 0) -+ i_ret = 0; -+ else if ((rd_len > 0) && (copy_to_user(buf, rd_buf, rd_len) == 0)) -+ i_ret = rd_len; -+ else -+ i_ret = -EFAULT; -+ -+ up(&rd_mtx); -+ BTIF_INFO_FUNC("--, i_ret:%d\n", i_ret); -+ return i_ret; -+} -+ -+ssize_t btif_file_write(struct file *filp, -+ const char __user *buf, size_t count, loff_t *f_pos) -+{ -+ int i_ret = 0; -+ int copy_size = 0; -+ -+ copy_size = count > sizeof(wr_buf) ? sizeof(wr_buf) : count; -+ -+ BTIF_INFO_FUNC("++\n"); -+ down(&wr_mtx); -+ if (copy_from_user(&wr_buf[0], &buf[0], copy_size)) -+ i_ret = -EFAULT; -+ else -+ i_ret = btif_send_data(&g_btif[0], wr_buf, copy_size); -+ -+ up(&wr_mtx); -+ BTIF_INFO_FUNC("--, i_ret:%d\n", i_ret); -+ -+ return i_ret; -+} -+#ifdef CONFIG_COMPAT -+long btif_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) -+{ -+ long ret; -+ -+ BTIF_INFO_FUNC("cmd[0x%x]\n", cmd); -+ ret = btif_unlocked_ioctl(filp, cmd, arg); -+ return ret; -+} -+#endif -+long btif_unlocked_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) -+{ -+#define BTIF_IOC_MAGIC 0xb0 -+#define BTIF_IOCTL_OPEN _IOW(BTIF_IOC_MAGIC, 1, int) -+#define BTIF_IOCTL_CLOSE _IOW(BTIF_IOC_MAGIC, 2, int) -+#define BTIF_IOCTL_LPBK_CTRL _IOWR(BTIF_IOC_MAGIC, 3, int) -+#define BTIF_IOCTL_LOG_FUNC_CTRL _IOWR(BTIF_IOC_MAGIC, 4, int) -+#define BTIF_IOCTL_RT_LOG_CTRL _IOWR(BTIF_IOC_MAGIC, 5, int) -+#define BTIF_IOCTL_LOG_DUMP _IOWR(BTIF_IOC_MAGIC, 6, int) -+#define BTIF_IOCTL_REG_DUMP _IOWR(BTIF_IOC_MAGIC, 7, int) -+#define BTIF_IOCTL_DMA_CTRL _IOWR(BTIF_IOC_MAGIC, 8, int) -+ -+ long ret = 0; -+/* unsigned char p_buf[NAME_MAX + 1]; */ -+ p_mtk_btif p_btif = &g_btif[0]; -+ -+ BTIF_INFO_FUNC("++\n"); -+ BTIF_DBG_FUNC("cmd (%u), arg (0x%lx)\n", cmd, arg); -+ -+ switch (cmd) { -+ case BTIF_IOCTL_OPEN: -+ ret = _btif_file_open(); -+ break; -+ case BTIF_IOCTL_CLOSE: -+ ret = _btif_file_close(); -+ break; -+ case BTIF_IOCTL_LPBK_CTRL: -+ ret = btif_lpbk_ctrl(p_btif, arg == 0 ? 0 : 1); -+ break; -+ case BTIF_IOCTL_LOG_FUNC_CTRL: -+ if (arg == 0) { -+ ret += btif_log_buf_disable(&p_btif->tx_log); -+ ret += btif_log_buf_disable(&p_btif->rx_log); -+ } else { -+ ret += btif_log_buf_enable(&p_btif->tx_log); -+ ret += btif_log_buf_enable(&p_btif->rx_log); -+ } -+ break; -+ case BTIF_IOCTL_RT_LOG_CTRL: -+ if (arg == 0) { -+ ret += btif_log_output_disable(&p_btif->tx_log); -+ ret += btif_log_output_disable(&p_btif->rx_log); -+ } else { -+ ret += btif_log_output_enable(&p_btif->tx_log); -+ ret += btif_log_output_enable(&p_btif->rx_log); -+ } -+ break; -+ case BTIF_IOCTL_LOG_DUMP: -+ -+ ret += btif_log_buf_dmp_out(&p_btif->tx_log); -+ ret += btif_log_buf_dmp_out(&p_btif->rx_log); -+ break; -+ case BTIF_IOCTL_REG_DUMP: -+ ret += btif_dump_reg(p_btif); -+ break; -+ case BTIF_IOCTL_DMA_CTRL: -+ if (arg == 0) { -+ ret += btif_tx_dma_mode_set(0); -+ ret += btif_rx_dma_mode_set(0); -+ } else { -+ ret += btif_tx_dma_mode_set(1); -+ ret += btif_rx_dma_mode_set(1); -+ } -+ break; -+ default: -+ BTIF_INFO_FUNC("unknown cmd(%d)\n", cmd); -+ ret = -2; -+ break; -+ } -+ BTIF_INFO_FUNC("--\n"); -+ return ret; -+} -+ -+#endif -+ -+/*-----------device property----------------*/ -+//static ssize_t driver_flag_read(struct device_driver *drv, char *buf) -+static ssize_t flag_show(struct device_driver *drv, char *buf) -+{ -+ return sprintf(buf, "btif driver debug level:%d\n", mtk_btif_dbg_lvl); -+} -+ -+//static ssize_t driver_flag_set(struct device_driver *drv, -+static ssize_t flag_store(struct device_driver *drv, -+ const char *buffer, size_t count) -+{ -+ char buf[256]; -+ char *p_buf; -+ unsigned long len = count; -+ long x = 0; -+ long y = 0; -+ long z = 0; -+ int result = 0; -+ char *p_token = NULL; -+ char *p_delimiter = " \t"; -+ -+ BTIF_INFO_FUNC("buffer = %s, count = %zd\n", buffer, count); -+ if (len >= sizeof(buf)) { -+ BTIF_ERR_FUNC("input handling fail!\n"); -+ len = sizeof(buf) - 1; -+ return -1; -+ } -+ -+ memcpy(buf, buffer, sizeof(buf)); -+ p_buf = buf; -+ -+ p_token = strsep(&p_buf, p_delimiter); -+ if (p_token != NULL) { -+ result = kstrtol(p_token, 16, &x); -+ BTIF_INFO_FUNC("x = 0x%08x\n\r", x); -+ } else -+ x = 0; -+/* x = (NULL != p_token) ? kstrtol(p_token, 16, NULL) : 0;*/ -+ -+ p_token = strsep(&p_buf, "\t\n "); -+ if (p_token != NULL) { -+ result = kstrtol(p_token, 16, &y); -+ BTIF_INFO_FUNC("y = 0x%08x\n\r", y); -+ } else -+ y = 0; -+ -+ p_token = strsep(&p_buf, "\t\n "); -+ if (p_token != NULL) -+ result = kstrtol(p_token, 16, &z); -+ else -+ z = 0; -+ -+ BTIF_INFO_FUNC("x(0x%08x), y(0x%08x), z(0x%08x)\n\r", x, y, z); -+ -+ switch (x) { -+ case 1: -+ mtk_btif_exp_open_test(); -+ break; -+ case 2: -+ mtk_btif_exp_close_test(); -+ break; -+ case 3: -+ mtk_btif_exp_write_test(); -+ break; -+ case 4: -+ mtk_btif_exp_enter_dpidle_test(); -+ break; -+ case 5: -+ mtk_btif_exp_exit_dpidle_test(); -+ break; -+ case 6: -+ mtk_btif_exp_suspend_test(); -+ break; -+ case 7: -+ mtk_btif_exp_resume_test(); -+ break; -+ case 8: -+ if (y > BTIF_LOG_LOUD) -+ mtk_btif_dbg_lvl = BTIF_LOG_LOUD; -+ else if (y < BTIF_LOG_ERR) -+ mtk_btif_dbg_lvl = BTIF_LOG_WARN; -+ else -+ mtk_btif_dbg_lvl = y; -+ BTIF_ERR_FUNC("mtk_btif_dbg_lvl set to %d\n", mtk_btif_dbg_lvl); -+ break; -+ case 9: -+ mtk_btif_exp_open_test(); -+ mtk_btif_exp_write_test(); -+ mtk_btif_exp_close_test(); -+ break; -+ case 0xa: -+ mtk_btif_exp_log_debug_test(y); -+ break; -+ case 0xb: -+ btif_tx_dma_mode_set(1); -+ btif_rx_dma_mode_set(1); -+ break; -+ case 0xc: -+ btif_tx_dma_mode_set(0); -+ btif_rx_dma_mode_set(0); -+ break; -+ case 0xd: -+ mtk_btif_exp_restore_noirq_test(); -+ break; -+ case 0xe: -+ btif_wakeup_consys_no_id(); -+ break; -+ case 0xf: -+ mtk_btif_exp_clock_ctrl(y); -+ break; -+ case 0x10: -+ y = y > G_MAX_PKG_LEN ? G_MAX_PKG_LEN : y; -+ y = y < 1024 ? 1024 : y; -+ BTIF_INFO_FUNC("g_max_pkg_len is set to %d\n", y); -+ g_max_pkg_len = y; -+ break; -+ case 0x11: -+ y = y > BTIF_RX_BUFFER_SIZE ? BTIF_RX_BUFFER_SIZE : y; -+ y = y < 1024 ? 1024 : y; -+ BTIF_INFO_FUNC("g_max_pding_data_size is set to %d\n", y); -+ g_max_pding_data_size = y; -+ break; -+ default: -+ mtk_btif_exp_open_test(); -+ mtk_btif_exp_write_stress_test(3030, 1); -+ mtk_btif_exp_close_test(); -+ BTIF_WARN_FUNC("not supported.\n"); -+ break; -+ } -+ -+ return count; -+} -+ -+//FWU: driver_ATTR dropped in 4.14 -+//static DRIVER_ATTR(flag, S_IRUGO | S_IWUSR, driver_flag_read, driver_flag_set); -+static DRIVER_ATTR_RW(flag); -+ -+/*-----------End of platform bus related operation APIs------------*/ -+ -+/*-----------------------platform driver ----------------*/ -+ -+int _btif_irq_reg(P_MTK_BTIF_IRQ_STR p_irq, -+ mtk_btif_irq_handler irq_handler, void *data) -+{ -+ int i_ret = -1; -+ unsigned int irq_id; -+ unsigned int flag; -+ -+ if ((p_irq == NULL) || (irq_handler == NULL)) -+ return E_BTIF_INVAL_PARAM; -+ -+ if (!(p_irq->is_irq_sup)) { -+ BTIF_WARN_FUNC("%s is not supported\n", p_irq->name); -+ return 0; -+ } -+ -+ irq_id = p_irq->irq_id; -+ -+#ifdef CONFIG_OF -+ flag = p_irq->irq_flags; -+#else -+ switch (p_irq->sens_type) { -+ case IRQ_SENS_EDGE: -+ if (p_irq->edge_type == IRQ_EDGE_FALL) -+ flag = IRQF_TRIGGER_FALLING; -+ else if (p_irq->edge_type == IRQ_EDGE_RAISE) -+ flag = IRQF_TRIGGER_RISING; -+ else if (p_irq->edge_type == IRQ_EDGE_BOTH) -+ flag = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING; -+ else -+ /*make this as default type */ -+ flag = IRQF_TRIGGER_FALLING; -+ break; -+ case IRQ_SENS_LVL: -+ if (p_irq->lvl_type == IRQ_LVL_LOW) -+ flag = IRQF_TRIGGER_LOW; -+ else if (p_irq->lvl_type == IRQ_LVL_HIGH) -+ flag = IRQF_TRIGGER_HIGH; -+ else -+ /*make this as default type */ -+ flag = IRQF_TRIGGER_LOW; -+ break; -+ default: -+ /*make this as default type */ -+ flag = IRQF_TRIGGER_LOW; -+ break; -+ } -+#endif -+ -+ p_irq->p_irq_handler = irq_handler; -+ i_ret = request_irq(irq_id, -+ (irq_handler_t) irq_handler, -+ flag, p_irq->name, data); -+ if (i_ret) -+ return i_ret; -+ -+ p_irq->reg_flag = true; -+ return 0; -+} -+ -+int _btif_irq_free(P_MTK_BTIF_IRQ_STR p_irq, void *data) -+{ -+ int i_ret = 0; -+ unsigned int eint_num = p_irq->irq_id; -+ -+ if ((p_irq->is_irq_sup) && (p_irq->reg_flag)) { -+ _btif_irq_ctrl(p_irq, false); -+ free_irq(eint_num, data); -+ p_irq->reg_flag = false; -+ } -+/*do nothing for this operation*/ -+ return i_ret; -+} -+ -+int _btif_irq_ctrl(P_MTK_BTIF_IRQ_STR p_irq, bool en) -+{ -+ unsigned int eint_num = p_irq->irq_id; -+ -+ if (en) -+ enable_irq(eint_num); -+ else -+ disable_irq_nosync(eint_num); -+ -+ return 0; -+} -+ -+int _btif_irq_ctrl_sync(P_MTK_BTIF_IRQ_STR p_irq, bool en) -+{ -+ unsigned int eint_num = p_irq->irq_id; -+ -+ if (en) -+ enable_irq(eint_num); -+ else -+ disable_irq(eint_num); -+ -+ return 0; -+} -+ -+ -+irqreturn_t btif_irq_handler(int irq, void *data) -+{ -+/*search BTIF? just use index 0*/ -+/*Chaozhong: do we need lock here?*/ -+ -+ p_mtk_btif p_btif = (p_mtk_btif) data; /*&(g_btif[index]); */ -+ -+ BTIF_DBG_FUNC("++, p_btif(0x%p)\n", data); -+ -+ _btif_irq_ctrl(p_btif->p_btif_info->p_irq, false); -+ -+#if MTK_BTIF_ENABLE_CLK_REF_COUNTER -+ hal_btif_clk_ctrl(p_btif->p_btif_info, CLK_OUT_ENABLE); -+#endif -+ -+ hal_btif_irq_handler(p_btif->p_btif_info, NULL, 0); -+ -+#if MTK_BTIF_ENABLE_CLK_REF_COUNTER -+ hal_btif_clk_ctrl(p_btif->p_btif_info, CLK_OUT_DISABLE); -+#endif -+ -+ _btif_irq_ctrl(p_btif->p_btif_info->p_irq, true); -+ _btif_rx_btm_sched(p_btif); -+ -+ BTIF_DBG_FUNC("--\n"); -+ return IRQ_HANDLED; -+} -+ -+irqreturn_t btif_tx_dma_irq_handler(int irq, void *data) -+{ -+/*search BTIF? just use index 0*/ -+ -+ p_mtk_btif p_btif = (p_mtk_btif) data; /*&(g_btif[index]); */ -+ p_mtk_btif_dma p_tx_dma = p_btif->p_tx_dma; -+ P_MTK_DMA_INFO_STR p_dma_info = p_tx_dma->p_dma_info; -+ -+ BTIF_DBG_FUNC("++, p_btif(0x%p)\n", data); -+ _btif_irq_ctrl(p_dma_info->p_irq, false); -+ -+#if MTK_BTIF_ENABLE_CLK_REF_COUNTER -+ hal_btif_dma_clk_ctrl(p_dma_info, CLK_OUT_ENABLE); -+#endif -+ -+ hal_tx_dma_irq_handler(p_dma_info); -+ -+#if MTK_BTIF_ENABLE_CLK_REF_COUNTER -+ hal_btif_dma_clk_ctrl(p_dma_info, CLK_OUT_DISABLE); -+#endif -+ _btif_irq_ctrl(p_dma_info->p_irq, true); -+ BTIF_DBG_FUNC("--\n"); -+ return IRQ_HANDLED; -+} -+ -+irqreturn_t btif_rx_dma_irq_handler(int irq, void *data) -+{ -+/*search BTIF? just use index 0*/ -+ -+ p_mtk_btif p_btif = (p_mtk_btif) data; /*&(g_btif[index]); */ -+ p_mtk_btif_dma p_rx_dma = p_btif->p_rx_dma; -+ P_MTK_DMA_INFO_STR p_rx_dma_info = p_rx_dma->p_dma_info; -+ -+ BTIF_DBG_FUNC("++, p_btif(0x%p)\n", data); -+ -+ _btif_irq_ctrl(p_rx_dma_info->p_irq, false); -+ -+#if MTK_BTIF_ENABLE_CLK_REF_COUNTER -+ hal_btif_clk_ctrl(p_btif->p_btif_info, CLK_OUT_ENABLE); -+ hal_btif_dma_clk_ctrl(p_rx_dma_info, CLK_OUT_ENABLE); -+#endif -+ -+ hal_rx_dma_irq_handler(p_rx_dma_info, NULL, 0); -+ -+#if MTK_BTIF_ENABLE_CLK_REF_COUNTER -+ hal_btif_dma_clk_ctrl(p_rx_dma_info, CLK_OUT_DISABLE); -+ hal_btif_clk_ctrl(p_btif->p_btif_info, CLK_OUT_DISABLE); -+#endif -+ -+ _btif_irq_ctrl(p_rx_dma_info->p_irq, true); -+ -+ _btif_rx_btm_sched(p_btif); -+ -+ BTIF_DBG_FUNC("--\n"); -+ -+ return IRQ_HANDLED; -+} -+ -+unsigned int btif_dma_rx_data_receiver(P_MTK_DMA_INFO_STR p_dma_info, -+ unsigned char *p_buf, -+ unsigned int buf_len) -+{ -+ unsigned int index = 0; -+ p_mtk_btif p_btif = &(g_btif[index]); -+ -+#if 0 -+ _btif_dump_memory("", p_buf, buf_len); -+#endif -+ -+ btif_bbs_write(&(p_btif->btif_buf), p_buf, buf_len); -+/*save DMA Rx packet here*/ -+ if (buf_len > 0) -+ btif_log_buf_dmp_in(&p_btif->rx_log, p_buf, buf_len); -+ -+ return 0; -+} -+ -+unsigned int btif_pio_rx_data_receiver(P_MTK_BTIF_INFO_STR p_btif_info, -+ unsigned char *p_buf, -+ unsigned int buf_len) -+{ -+ unsigned int index = 0; -+ p_mtk_btif p_btif = &(g_btif[index]); -+ -+#if 0 -+ _btif_dump_memory("", p_buf, buf_len); -+#endif -+ btif_bbs_write(&(p_btif->btif_buf), p_buf, buf_len); -+ -+/*save PIO Rx packet here*/ -+ if (buf_len > 0) -+ btif_log_buf_dmp_in(&p_btif->rx_log, p_buf, buf_len); -+ -+ return 0; -+} -+ -+bool btif_parser_wmt_evt(p_mtk_btif p_btif, -+ const char *sub_str, -+ unsigned int str_len) -+{ -+ unsigned int data_cnt = 0; -+ unsigned int copy_cnt = 0; -+ char *local_buf = NULL; -+ bool b_ret = false; -+ p_btif_buf_str p_bbs = &(p_btif->btif_buf); -+ unsigned int wr_idx = p_bbs->wr_idx; -+ unsigned int rd_idx = p_bbs->rd_idx; -+ -+ data_cnt = copy_cnt = BBS_COUNT(p_bbs); -+ -+ if (data_cnt < str_len) { -+ BTIF_WARN_FUNC("there is not enough data for parser,need(%d),have(%d)\n", str_len, data_cnt); -+ return false; -+ } -+ BTIF_INFO_FUNC("data count in bbs buffer:%d,wr_idx(%d),rd_idx(%d)\n", data_cnt, wr_idx, rd_idx); -+ local_buf = vmalloc((data_cnt + 3) & ~0x3UL); -+ if (!local_buf) { -+ BTIF_WARN_FUNC("vmalloc memory fail\n"); -+ return false; -+ } -+ -+ if (wr_idx >= rd_idx) { -+ memcpy(local_buf, BBS_PTR(p_bbs, rd_idx), copy_cnt); -+ } else { -+ unsigned int tail_len = BBS_SIZE(p_bbs) - rd_idx; -+ -+ BTIF_INFO_FUNC("tail_Len(%d)\n", tail_len); -+ memcpy(local_buf, BBS_PTR(p_bbs, rd_idx), tail_len); -+ memcpy(local_buf + tail_len, BBS_PTR(p_bbs, 0), copy_cnt - tail_len); -+ } -+ -+ do { -+ int i = 0; -+ int j = 0; -+ int k = 0; -+ int d = 0; -+ -+ BTIF_INFO_FUNC("sub_str_len:%d\n", str_len); -+ for (i = 0; i < copy_cnt; i++) { -+ BTIF_DBG_FUNC("i:%d\n", i); -+ k = i; -+ while (1) { -+ if ((j >= str_len) || (k >= copy_cnt) || (sub_str[j++] != local_buf[k++])) -+ break; -+ } -+ -+ if (j == str_len) { -+ for (d = i; d < (str_len + i); d++) -+ BTIF_INFO_FUNC("0x%2x", local_buf[d]); -+ BTIF_INFO_FUNC("find sub str index:%d\n", i); -+ b_ret = true; -+ break; -+ } -+ if (j < str_len) -+ j = 0; -+ } -+ -+ } while (0); -+ -+ vfree(local_buf); -+ return b_ret; -+} -+int _btif_controller_tx_setup(p_mtk_btif p_btif) -+{ -+ int i_ret = -1; -+ -+ if (p_btif->tx_mode == BTIF_MODE_DMA) { -+ i_ret = _btif_tx_dma_setup(p_btif); -+ if (i_ret) { -+ BTIF_ERR_FUNC("_btif_tx_dma_setup failed,i_ret(%d),", -+ "set tx to PIO mode\n", i_ret); -+ i_ret = _btif_tx_pio_setup(p_btif); -+ } -+ } else -+/*enable Tx PIO mode*/ -+ i_ret = _btif_tx_pio_setup(p_btif); -+ -+ return i_ret; -+} -+ -+int _btif_controller_tx_free(p_mtk_btif p_btif) -+{ -+ int i_ret = -1; -+ -+ if (p_btif->tx_mode == BTIF_MODE_DMA) { -+ i_ret = _btif_tx_dma_free(p_btif); -+ if (i_ret) { -+ BTIF_ERR_FUNC("_btif_tx_dma_free failed, i_ret(%d)\n", -+ i_ret); -+ } -+ } else { -+/*do nothing for Tx PIO mode*/ -+ } -+ return i_ret; -+} -+ -+int _btif_controller_rx_setup(p_mtk_btif p_btif) -+{ -+ int i_ret = -1; -+ -+ if (p_btif->rx_mode == BTIF_MODE_DMA) { -+ i_ret = _btif_rx_dma_setup(p_btif); -+ if (i_ret) { -+ BTIF_ERR_FUNC("_btif_tx_dma_setup failed, i_ret(%d),", -+ "set tx to PIO mode\n", i_ret); -+ i_ret = _btif_rx_pio_setup(p_btif); -+ } -+ } else { -+/*enable Tx PIO mode*/ -+ i_ret = _btif_rx_pio_setup(p_btif); -+ } -+ return i_ret; -+} -+ -+int _btif_controller_rx_free(p_mtk_btif p_btif) -+{ -+ int i_ret = -1; -+ -+ if (p_btif->rx_mode == BTIF_MODE_DMA) { -+ i_ret = _btif_rx_dma_free(p_btif); -+ if (i_ret) { -+ BTIF_ERR_FUNC("_btif_rx_dma_free failed, i_ret(%d)\n", -+ i_ret); -+ } -+ } else { -+/*do nothing for Rx PIO mode*/ -+ } -+ return i_ret; -+} -+ -+int _btif_tx_pio_setup(p_mtk_btif p_btif) -+{ -+ int i_ret = -1; -+ P_MTK_BTIF_INFO_STR p_btif_info = p_btif->p_btif_info; -+ -+/*set Tx to PIO mode*/ -+ p_btif->tx_mode = BTIF_MODE_PIO; -+/*enable Tx PIO mode*/ -+ i_ret = hal_btif_tx_mode_ctrl(p_btif_info, BTIF_MODE_PIO); -+ return i_ret; -+} -+ -+int _btif_rx_pio_setup(p_mtk_btif p_btif) -+{ -+ int i_ret = -1; -+ P_MTK_BTIF_INFO_STR p_btif_info = p_btif->p_btif_info; -+ P_MTK_BTIF_IRQ_STR p_btif_irq = p_btif_info->p_irq; -+ -+ p_btif->rx_mode = BTIF_MODE_PIO; -+/*Enable Rx IRQ*/ -+ _btif_irq_ctrl(p_btif_irq, true); -+/*enable Rx PIO mode*/ -+ i_ret = hal_btif_rx_mode_ctrl(p_btif_info, BTIF_MODE_PIO); -+ return i_ret; -+} -+ -+int _btif_rx_dma_setup(p_mtk_btif p_btif) -+{ -+ int i_ret = -1; -+ P_MTK_BTIF_INFO_STR p_btif_info = NULL; -+ P_MTK_BTIF_IRQ_STR p_btif_irq = NULL; -+ P_MTK_DMA_INFO_STR p_dma_info = p_btif->p_rx_dma->p_dma_info; -+ -+ p_btif_info = p_btif->p_btif_info; -+ p_btif_irq = p_dma_info->p_irq; -+ -+/*vFIFO reset*/ -+ hal_btif_vfifo_reset(p_dma_info); -+ -+ i_ret = hal_btif_dma_clk_ctrl(p_dma_info, CLK_OUT_ENABLE); -+ if (i_ret) { -+ BTIF_ERR_FUNC("hal_btif_dma_clk_ctrl failed, i_ret(%d),", -+ "set rx to pio mode\n", i_ret); -+/*DMA control failed set Rx to PIO mode*/ -+ return _btif_rx_pio_setup(p_btif); -+ } -+/*hardware init*/ -+ hal_btif_dma_hw_init(p_dma_info); -+ -+ hal_btif_dma_rx_cb_reg(p_dma_info, -+ (dma_rx_buf_write) btif_dma_rx_data_receiver); -+ -+/*DMA controller enable*/ -+ i_ret = hal_btif_dma_ctrl(p_dma_info, DMA_CTRL_ENABLE); -+ if (i_ret) { -+ BTIF_ERR_FUNC("hal_btif_dma_ctrl failed, i_ret(%d),", -+ "set rx to pio mode\n", i_ret); -+ hal_btif_dma_clk_ctrl(p_dma_info, CLK_OUT_DISABLE); -+/*DMA control failed set Rx to PIO mode*/ -+ i_ret = _btif_rx_pio_setup(p_btif); -+ } else { -+/*enable Rx DMA mode*/ -+ hal_btif_rx_mode_ctrl(p_btif_info, BTIF_MODE_DMA); -+ -+/*DMA Rx IRQ register*/ -+ _btif_irq_reg(p_btif_irq, btif_rx_dma_irq_handler, p_btif); -+#if 0 -+/*Enable DMA Rx IRQ*/ -+ _btif_irq_ctrl(p_btif_irq, true); -+#endif -+ BTIF_DBG_FUNC("succeed\n"); -+ } -+ return i_ret; -+} -+ -+int _btif_rx_dma_free(p_mtk_btif p_btif) -+{ -+ P_MTK_DMA_INFO_STR p_dma_info = p_btif->p_rx_dma->p_dma_info; -+ P_MTK_BTIF_IRQ_STR p_irq = p_btif->p_rx_dma->p_dma_info->p_irq; -+ -+ hal_btif_dma_rx_cb_reg(p_dma_info, (dma_rx_buf_write) NULL); -+ _btif_irq_free(p_irq, p_btif); -+/*disable BTIF Rx DMA channel*/ -+ hal_btif_dma_ctrl(p_dma_info, DMA_CTRL_DISABLE); -+/*disable clock output*/ -+ return hal_btif_dma_clk_ctrl(p_dma_info, CLK_OUT_DISABLE); -+} -+ -+int _btif_tx_dma_setup(p_mtk_btif p_btif) -+{ -+ int i_ret = -1; -+ P_MTK_BTIF_INFO_STR p_btif_info = p_btif->p_btif_info; -+ P_MTK_DMA_INFO_STR p_dma_info = p_btif->p_tx_dma->p_dma_info; -+ P_MTK_BTIF_IRQ_STR p_btif_irq = p_dma_info->p_irq; -+ -+/*vFIFO reset*/ -+ hal_btif_vfifo_reset(p_dma_info); -+ -+ i_ret = hal_btif_dma_clk_ctrl(p_dma_info, CLK_OUT_ENABLE); -+ if (i_ret) { -+ BTIF_ERR_FUNC("hal_btif_dma_clk_ctrl failed, i_ret(%d)\n", -+ i_ret); -+ return i_ret; -+ } -+/*DMA controller setup*/ -+ hal_btif_dma_hw_init(p_dma_info); -+ -+/*DMA HW Enable*/ -+ i_ret = hal_btif_dma_ctrl(p_dma_info, DMA_CTRL_ENABLE); -+ if (i_ret) { -+ BTIF_ERR_FUNC("hal_btif_dma_ctrl failed, i_ret(%d),", -+ "set tx to pio mode\n", i_ret); -+ -+#if !(MTK_BTIF_ENABLE_CLK_REF_COUNTER) -+ hal_btif_dma_clk_ctrl(p_dma_info, CLK_OUT_DISABLE); -+#endif -+ -+ _btif_tx_pio_setup(p_btif); -+ } else { -+ hal_btif_tx_mode_ctrl(p_btif_info, BTIF_MODE_DMA); -+/*DMA Tx IRQ register*/ -+ _btif_irq_reg(p_btif_irq, btif_tx_dma_irq_handler, p_btif); -+#if 0 -+/*disable DMA Tx IRQ*/ -+ _btif_irq_ctrl(p_btif_irq, false); -+#endif -+ -+ BTIF_DBG_FUNC("succeed\n"); -+ } -+ return i_ret; -+} -+ -+int _btif_tx_dma_free(p_mtk_btif p_btif) -+{ -+ P_MTK_DMA_INFO_STR p_dma_info = p_btif->p_tx_dma->p_dma_info; -+ P_MTK_BTIF_IRQ_STR p_irq = p_btif->p_tx_dma->p_dma_info->p_irq; -+ -+ _btif_irq_free(p_irq, p_btif); -+/*disable BTIF Tx DMA channel*/ -+ hal_btif_dma_ctrl(p_dma_info, DMA_CTRL_DISABLE); -+/*disable clock output*/ -+ return hal_btif_dma_clk_ctrl(p_dma_info, CLK_OUT_DISABLE); -+} -+ -+int btif_lpbk_ctrl(p_mtk_btif p_btif, bool flag) -+{ -+ int i_ret = -1; -+ -+/*hold state mechine lock*/ -+ if (_btif_state_hold(p_btif)) -+ return E_BTIF_INTR; -+#if 0 -+ state = _btif_state_get(p_btif); -+ if (p_btif->enable && B_S_ON == state) -+ i_ret = _btif_lpbk_ctrl(p_btif, flag); -+ else -+ i_ret = E_BTIF_INVAL_STATE; -+#endif -+ i_ret = _btif_exit_dpidle(p_btif); -+ if (i_ret == 0) -+ i_ret = _btif_lpbk_ctrl(p_btif, flag); -+ else -+ i_ret = E_BTIF_INVAL_STATE; -+ -+ BTIF_STATE_RELEASE(p_btif); -+ return i_ret; -+} -+ -+int _btif_lpbk_ctrl(p_mtk_btif p_btif, bool flag) -+{ -+ int i_ret = -1; -+ -+ if (flag) { -+ i_ret = hal_btif_loopback_ctrl(p_btif->p_btif_info, true); -+ BTIF_DBG_FUNC("loopback function enabled\n"); -+ } else { -+ i_ret = hal_btif_loopback_ctrl(p_btif->p_btif_info, false); -+ BTIF_DBG_FUNC("loopback function disabled\n"); -+ } -+ if (i_ret == 0) -+ p_btif->lpbk_flag = flag; -+ -+ return i_ret; -+} -+ -+int btif_clock_ctrl(p_mtk_btif p_btif, int en) -+{ -+ int i_ret = 0; -+ P_MTK_BTIF_INFO_STR p_btif_info = p_btif->p_btif_info; -+ ENUM_CLOCK_CTRL ctrl_flag = en == 0 ? CLK_OUT_DISABLE : CLK_OUT_ENABLE; -+ -+ i_ret = hal_btif_clk_ctrl(p_btif_info, ctrl_flag); -+ -+ if (p_btif->rx_mode == BTIF_MODE_DMA) -+ i_ret += hal_btif_dma_clk_ctrl(p_btif->p_rx_dma->p_dma_info, ctrl_flag); -+ -+ if (p_btif->tx_mode == BTIF_MODE_DMA) -+ i_ret += hal_btif_dma_clk_ctrl(p_btif->p_tx_dma->p_dma_info, ctrl_flag); -+ -+ return i_ret; -+} -+ -+int _btif_controller_setup(p_mtk_btif p_btif) -+{ -+ int i_ret = -1; -+ P_MTK_BTIF_INFO_STR p_btif_info = p_btif->p_btif_info; -+ P_MTK_BTIF_IRQ_STR p_btif_irq = p_btif_info->p_irq; -+ -+/*BTIF rx buffer init*/ -+/* memset(p_btif->rx_buf, 0, BTIF_RX_BUFFER_SIZE); */ -+ BBS_INIT(&(p_btif->btif_buf)); -+/************************************************/ -+ hal_btif_rx_cb_reg(p_btif_info, -+ (btif_rx_buf_write) btif_pio_rx_data_receiver); -+ -+ i_ret = hal_btif_clk_ctrl(p_btif_info, CLK_OUT_ENABLE); -+ if (i_ret) { -+ BTIF_ERR_FUNC("hal_btif_clk_ctrl failed, i_ret(%d)\n", i_ret); -+ return i_ret; -+ } -+/*BTIF controller init*/ -+ i_ret = hal_btif_hw_init(p_btif_info); -+ if (i_ret) { -+ hal_btif_clk_ctrl(p_btif_info, CLK_OUT_DISABLE); -+ BTIF_ERR_FUNC("hal_btif_hw_init failed, i_ret(%d)\n", i_ret); -+ return i_ret; -+ } -+ _btif_lpbk_ctrl(p_btif, p_btif->lpbk_flag); -+/*BTIF IRQ register*/ -+ i_ret = _btif_irq_reg(p_btif_irq, btif_irq_handler, p_btif); -+ if (i_ret) { -+ hal_btif_clk_ctrl(p_btif_info, CLK_OUT_DISABLE); -+ -+ BTIF_ERR_FUNC("_btif_irq_reg failed, i_ret(%d)\n", i_ret); -+ return i_ret; -+ } -+ -+/*disable IRQ*/ -+ _btif_irq_ctrl(p_btif_irq, false); -+ i_ret = 0; -+ BTIF_DBG_FUNC("succeed\n"); -+ return i_ret; -+} -+ -+int _btif_controller_free(p_mtk_btif p_btif) -+{ -+/*No need to set BTIF to PIO mode, only enable BTIF CG*/ -+ hal_btif_rx_cb_reg(p_btif->p_btif_info, (btif_rx_buf_write) NULL); -+ _btif_irq_free(p_btif->p_btif_info->p_irq, p_btif); -+ return hal_btif_clk_ctrl(p_btif->p_btif_info, CLK_OUT_DISABLE); -+} -+ -+int _btif_init(p_mtk_btif p_btif) -+{ -+ int i_ret = 0; -+ -+ i_ret = _btif_controller_setup(p_btif); -+ if (i_ret) { -+ BTIF_ERR_FUNC("_btif_controller_init failed, i_ret(%d)\n", -+ i_ret); -+ _btif_dpidle_notify_ctrl(p_btif, BTIF_DPIDLE_ENABLE); -+ BTIF_STATE_RELEASE(p_btif); -+ return i_ret; -+ } -+ -+ i_ret = _btif_controller_tx_setup(p_btif); -+ if (i_ret) { -+ BTIF_ERR_FUNC("_btif_controller_tx_setup failed, i_ret(%d)\n", -+ i_ret); -+ _btif_controller_free(p_btif); -+ _btif_dpidle_notify_ctrl(p_btif, BTIF_DPIDLE_ENABLE); -+ BTIF_STATE_RELEASE(p_btif); -+ return i_ret; -+ } -+ -+ i_ret = _btif_controller_rx_setup(p_btif); -+ if (i_ret) { -+ BTIF_ERR_FUNC("_btif_controller_tx_setup failed, i_ret(%d)\n", -+ i_ret); -+ _btif_controller_tx_free(p_btif); -+ _btif_controller_free(p_btif); -+ _btif_dpidle_notify_ctrl(p_btif, BTIF_DPIDLE_ENABLE); -+ BTIF_STATE_RELEASE(p_btif); -+ return i_ret; -+ } -+ return i_ret; -+} -+ -+int btif_open(p_mtk_btif p_btif) -+{ -+ int i_ret = -1; -+ -+ if (p_btif->enable) -+ return E_BTIF_ALREADY_OPEN; -+ -+/*hold state mechine lock*/ -+ if (_btif_state_hold(p_btif)) -+ return E_BTIF_INTR; -+/*disable deepidle*/ -+ _btif_dpidle_notify_ctrl(p_btif, BTIF_DPIDLE_DISABLE); -+ -+ i_ret = _btif_init(p_btif); -+ if (i_ret == 0) { -+ /*set BTIF's enable flag*/ -+ p_btif->enable = true; -+ _btif_state_set(p_btif, B_S_ON); -+ } else { -+ _btif_dpidle_notify_ctrl(p_btif, BTIF_DPIDLE_ENABLE); -+ } -+ btif_log_buf_reset(&p_btif->tx_log); -+ btif_log_buf_reset(&p_btif->rx_log); -+ -+ BTIF_STATE_RELEASE(p_btif); -+ -+ BTIF_DBG_FUNC("BTIF's Tx Mode:%d, Rx Mode(%d)\n", -+ p_btif->tx_mode, p_btif->rx_mode); -+ return i_ret; -+} -+ -+int btif_close(p_mtk_btif p_btif) -+{ -+ int i_ret = 0; -+ -+ if (!(p_btif->enable)) -+ return E_BTIF_NOT_OPEN; -+ -+/*hold state mechine lock*/ -+ if (_btif_state_hold(p_btif)) -+ return E_BTIF_INTR; -+/*always set state back to B_S_ON before do close operation*/ -+ _btif_exit_dpidle(p_btif); -+/*set BTIF's state to disable state*/ -+ p_btif->enable = false; -+ -+ _btif_controller_free(p_btif); -+ _btif_controller_tx_free(p_btif); -+ _btif_controller_rx_free(p_btif); -+ -+/*reset BTIF's rx_cb function*/ -+ p_btif->rx_cb = NULL; -+ p_btif->rx_notify = NULL; -+ p_btif->lpbk_flag = false; -+ -+/*set state mechine to B_S_OFF*/ -+ _btif_state_set(p_btif, B_S_OFF); -+ -+ btif_log_buf_disable(&p_btif->tx_log); -+ btif_log_buf_disable(&p_btif->rx_log); -+ -+ BTIF_STATE_RELEASE(p_btif); -+ -+ return i_ret; -+} -+ -+int _btif_exit_dpidle(p_mtk_btif p_btif) -+{ -+ int i_ret = -1; -+ ENUM_BTIF_STATE state = B_S_MAX; -+ -+ state = _btif_state_get(p_btif); -+ switch (state) { -+ case B_S_DPIDLE: -+ i_ret = _btif_exit_dpidle_from_dpidle(p_btif); -+ break; -+ case B_S_SUSPEND: -+/*in suspend state, need to do reinit of btif*/ -+ i_ret = _btif_exit_dpidle_from_sus(p_btif); -+ break; -+ case B_S_OFF: -+ i_ret = _btif_init(p_btif); -+ break; -+ case B_S_ON: -+ i_ret = 0; /* for btif_close case */ -+ break; -+ default: -+ i_ret = E_BTIF_INVAL_PARAM; -+ BTIF_INFO_FUNC("invalid state change:%d->\n", state, B_S_ON); -+ break; -+ } -+ -+ if (i_ret == 0) -+ i_ret = _btif_state_set(p_btif, B_S_ON); -+ return i_ret; -+} -+ -+int btif_exit_dpidle(p_mtk_btif p_btif) -+{ -+ int i_ret = 0; -+ -+/*hold state mechine lock*/ -+ if (_btif_state_hold(p_btif)) -+ return E_BTIF_INTR; -+ i_ret = _btif_exit_dpidle(p_btif); -+ BTIF_STATE_RELEASE(p_btif); -+ return i_ret; -+} -+ -+int _btif_enter_dpidle(p_mtk_btif p_btif) -+{ -+ int i_ret = 0; -+ ENUM_BTIF_STATE state = B_S_MAX; -+ -+ state = _btif_state_get(p_btif); -+ if (state == B_S_ON) { -+ i_ret = _btif_enter_dpidle_from_on(p_btif); -+ } else if (state == B_S_SUSPEND) { -+ /*do reinit and enter deepidle*/ -+ i_ret = _btif_enter_dpidle_from_sus(p_btif); -+ } else if (state == B_S_DPIDLE) { -+ /*do nothing*/ -+ i_ret = 0; -+ } else { -+ BTIF_WARN_FUNC("operation is not allowed, current state:%d\n", -+ state); -+ i_ret = E_BTIF_INVAL_STATE; -+ } -+/*anyway, set to B_S_DPIDLE state*/ -+ if (i_ret == 0) -+ i_ret = _btif_state_set(p_btif, B_S_DPIDLE); -+ return i_ret; -+} -+ -+int btif_enter_dpidle(p_mtk_btif p_btif) -+{ -+ int i_ret = 0; -+ -+/*hold state mechine lock*/ -+ if (_btif_state_hold(p_btif)) -+ return E_BTIF_INTR; -+ i_ret = _btif_enter_dpidle(p_btif); -+ BTIF_STATE_RELEASE(p_btif); -+ return i_ret; -+} -+ -+int _btif_exit_dpidle_from_dpidle(p_mtk_btif p_btif) -+{ -+ int i_ret = 0; -+ -+/*in dpidle state, only need to open related clock*/ -+ if (p_btif->tx_mode == BTIF_MODE_DMA) { -+ /*enable BTIF Tx DMA's clock*/ -+ i_ret += hal_btif_dma_clk_ctrl(p_btif->p_tx_dma->p_dma_info, -+ CLK_OUT_ENABLE); -+ } -+ if (p_btif->rx_mode == BTIF_MODE_DMA) { -+ /*enable BTIF Rx DMA's clock*/ -+ i_ret += hal_btif_dma_clk_ctrl(p_btif->p_rx_dma->p_dma_info, -+ CLK_OUT_ENABLE); -+ } -+/*enable BTIF's clock*/ -+ i_ret += hal_btif_clk_ctrl(p_btif->p_btif_info, CLK_OUT_ENABLE); -+ -+ if (i_ret != 0) -+ BTIF_WARN_FUNC("failed, i_ret:%d\n", i_ret); -+ return i_ret; -+} -+ -+int _btif_exit_dpidle_from_sus(p_mtk_btif p_btif) -+{ -+/*in suspend state, need to do driver re-init*/ -+ -+ int i_ret = _btif_init(p_btif); -+ -+ return i_ret; -+} -+ -+int _btif_enter_dpidle_from_sus(p_mtk_btif p_btif) -+{ -+/*do driiver reinit*/ -+ int i_ret = _btif_init(p_btif); -+ -+ if (i_ret == 0) -+ i_ret = _btif_enter_dpidle_from_on(p_btif); -+ return i_ret; -+} -+ -+int _btif_enter_dpidle_from_on(p_mtk_btif p_btif) -+{ -+#define MAX_WAIT_TIME_MS 5000 -+/* -+ * this max wait time cannot exceed 12s, -+ * because dpm will monitor each device's -+ * resume/suspend process by start up a watch dog timer of 12s -+ * incase of one driver's suspend/resume process block other device's suspend/resume -+ */ -+ int i_ret = 0; -+ unsigned int retry = 0; -+ unsigned int wait_period = 1; -+ unsigned int max_retry = MAX_WAIT_TIME_MS / wait_period; -+ struct timeval timer_start; -+ struct timeval timer_now; -+ -+ do_gettimeofday(&timer_start); -+ -+ while ((!_btif_is_tx_complete(p_btif)) && (retry < max_retry)) { -+ do_gettimeofday(&timer_now); -+ if ((MAX_WAIT_TIME_MS/1000) <= (timer_now.tv_sec - timer_start.tv_sec)) { -+ BTIF_WARN_FUNC("max retry timer expired, timer_start.tv_sec:%d, timer_now.tv_sec:%d,", -+ "retry:%d\n", timer_start.tv_sec, timer_now.tv_sec, retry); -+ break; -+ } -+ msleep(wait_period); -+ retry++; -+ } -+ -+ if (retry < max_retry) { -+ if (p_btif->tx_mode == BTIF_MODE_DMA) { -+ /*disable BTIF Tx DMA's clock*/ -+ i_ret += -+ hal_btif_dma_clk_ctrl(p_btif->p_tx_dma->p_dma_info, -+ CLK_OUT_DISABLE); -+ } -+ if (p_btif->rx_mode == BTIF_MODE_DMA) { -+ /*disable BTIF Rx DMA's clock*/ -+ i_ret += -+ hal_btif_dma_clk_ctrl(p_btif->p_rx_dma->p_dma_info, -+ CLK_OUT_DISABLE); -+ } -+/*disable BTIF's clock*/ -+ i_ret += -+ hal_btif_clk_ctrl(p_btif->p_btif_info, CLK_OUT_DISABLE); -+ -+ if (i_ret) -+ BTIF_WARN_FUNC("failed, i_ret:%d\n", i_ret); -+ } else -+ i_ret = -1; -+ -+ return i_ret; -+} -+ -+int _btif_dpidle_notify_ctrl(p_mtk_btif p_btif, ENUM_BTIF_DPIDLE_CTRL en_flag) -+{ -+/*call WCP's API to control deepidle's enable/disable*/ -+ if (en_flag == BTIF_DPIDLE_DISABLE) -+ hal_btif_pm_ops(p_btif->p_btif_info, BTIF_PM_DPIDLE_DIS); -+ else -+ hal_btif_pm_ops(p_btif->p_btif_info, BTIF_PM_DPIDLE_EN); -+ -+ return 0; -+} -+ -+int btif_rx_cb_reg(p_mtk_btif p_btif, MTK_WCN_BTIF_RX_CB rx_cb) -+{ -+ if (p_btif->rx_cb) { -+ BTIF_WARN_FUNC -+ ("rx cb already exist, rewrite from (0x%p) to (0x%p)\n", -+ p_btif->rx_cb, rx_cb); -+ } -+ p_btif->rx_cb = rx_cb; -+ -+ return 0; -+} -+ -+int btif_raise_wak_signal(p_mtk_btif p_btif) -+{ -+ int i_ret = 0; -+ P_MTK_BTIF_INFO_STR p_btif_info = p_btif->p_btif_info; -+ -+#if MTK_BTIF_ENABLE_CLK_REF_COUNTER -+ hal_btif_clk_ctrl(p_btif->p_btif_info, CLK_OUT_ENABLE); -+#endif -+ -+ i_ret = hal_btif_raise_wak_sig(p_btif_info); -+ -+#if MTK_BTIF_ENABLE_CLK_REF_COUNTER -+ hal_btif_clk_ctrl(p_btif_info, CLK_OUT_DISABLE); -+#endif -+ return i_ret; -+} -+ -+bool _btif_is_tx_complete(p_mtk_btif p_btif) -+{ -+ bool b_ret = false; -+ ENUM_BTIF_MODE tx_mode = p_btif->tx_mode; -+ -+/* -+ * make sure BTIF tx finished in PIO mode -+ * make sure BTIF tx finished and DMA tx finished in DMA mode -+ */ -+ if (tx_mode == BTIF_MODE_DMA) { -+ b_ret = hal_dma_is_tx_complete(p_btif->p_tx_dma->p_dma_info); -+ if (b_ret == false) { -+ BTIF_DBG_FUNC("Tx DMA is not finished\n"); -+ return b_ret; -+ } -+ } -+ -+ b_ret = hal_btif_is_tx_complete(p_btif->p_btif_info); -+ if (b_ret == false) { -+ BTIF_DBG_FUNC("BTIF Tx is not finished\n"); -+ return b_ret; -+ } -+ b_ret = true; -+ return b_ret; -+} -+ -+/*--------------------------------Functions-------------------------------------------*/ -+ -+#if ENABLE_BTIF_TX_DMA -+static int _btif_vfifo_init(p_mtk_btif_dma p_dma) -+{ -+ P_DMA_VFIFO p_vfifo = NULL; -+ struct device *dev = NULL; -+ p_mtk_btif p_btif = NULL; -+ -+ if (p_dma == NULL) { -+ BTIF_ERR_FUNC("p_dma is NULL\n"); -+ return E_BTIF_INVAL_PARAM; -+ } -+ -+ p_btif = (p_mtk_btif)p_dma->p_btif; -+ -+ if (p_btif == NULL) { -+ BTIF_ERR_FUNC("invalid parameter: p_btif(0x%p)\n", p_btif); -+ return E_BTIF_INVAL_PARAM; -+ } -+ -+ dev = (struct device *)p_btif->private_data; -+ if (dev == NULL) -+ BTIF_WARN_FUNC("Null dev pointer!!!!\n"); -+ -+ p_vfifo = p_dma->p_dma_info->p_vfifo; -+ if (p_vfifo->p_vir_addr != NULL) { -+ BTIF_ERR_FUNC -+ ("BTIF vFIFO memory already allocated, do nothing\n"); -+ return E_BTIF_BAD_POINTER; -+ } -+ -+/*vFIFO memory allocation*/ -+ p_vfifo->p_vir_addr = dma_zalloc_coherent(dev, -+ p_vfifo->vfifo_size, -+ &p_vfifo->phy_addr, GFP_DMA | GFP_DMA32); -+ if (p_vfifo->p_vir_addr == NULL) { -+ BTIF_ERR_FUNC("alloc vFIFO memory for BTIF failed\n"); -+ return E_BTIF_FAIL; -+ } -+ -+ if (sizeof(dma_addr_t) == sizeof(unsigned long long)) -+ BTIF_INFO_FUNC("alloc vFIFO for BTIF succeed in arch64,vir addr:0x%p,", -+ "phy addr:0x%llx\n", p_vfifo->p_vir_addr, p_vfifo->phy_addr); -+ else -+ BTIF_INFO_FUNC("alloc vFIFO for BTIF succeed in arch32,vir addr:0x%p,", -+ "phy addr:0x%08x\n", p_vfifo->p_vir_addr, p_vfifo->phy_addr); -+ -+ return 0; -+} -+#endif -+#if ENABLE_BTIF_TX_DMA -+static int _btif_vfifo_deinit(p_mtk_btif_dma p_dma) -+{ -+ P_DMA_VFIFO p_vfifo = NULL; -+ struct device *dev = NULL; -+ p_mtk_btif p_btif = NULL; -+ -+ if (p_dma == NULL) { -+ BTIF_ERR_FUNC("p_dma is NULL\n"); -+ return E_BTIF_INVAL_PARAM; -+ } -+ -+ -+ p_btif = (p_mtk_btif)p_dma->p_btif; -+ if (p_btif == NULL) { -+ BTIF_ERR_FUNC("invalid parameter: p_btif(0x%p)\n", p_btif); -+ return E_BTIF_INVAL_PARAM; -+ } -+ -+ dev = (struct device *)p_btif->private_data; -+ if (dev == NULL) -+ BTIF_WARN_FUNC("Null dev pointer!!!!\n"); -+ -+ p_vfifo = p_dma->p_dma_info->p_vfifo; -+ -+/*free DMA memory if allocated successfully before*/ -+ if (p_vfifo->p_vir_addr != NULL) { -+ dma_free_coherent(dev, -+ p_vfifo->vfifo_size, -+ p_vfifo->p_vir_addr, p_vfifo->phy_addr); -+ p_vfifo->p_vir_addr = NULL; -+ } -+ -+ return 0; -+} -+#endif -+ -+static int _btif_state_init(p_mtk_btif p_btif) -+{ -+ if (p_btif == NULL) { -+ BTIF_ERR_FUNC("p_btif is NULL\n"); -+ return E_BTIF_INVAL_PARAM; -+ } -+ p_btif->state = B_S_OFF; -+ mutex_init(&(p_btif->state_mtx)); -+ -+ return 0; -+} -+ -+static int _btif_state_hold(p_mtk_btif p_btif) -+{ -+ return mutex_lock_killable(&(p_btif->state_mtx)); -+} -+ -+static int _btif_state_set(p_mtk_btif p_btif, ENUM_BTIF_STATE state) -+{ -+/*chaozhong: To do: need to finished state mechine here*/ -+ int i_ret = 0; -+ int ori_state = p_btif->state; -+ -+ if (ori_state == state) { -+ BTIF_INFO_FUNC("already in %s state\n", g_state[state]); -+ return i_ret; -+ } -+ if ((state >= B_S_OFF) && (state < B_S_MAX)) { -+ BTIF_DBG_FUNC("%s->%s request\n", g_state[ori_state], -+ g_state[state]); -+ if (state == B_S_ON) -+ _btif_dpidle_notify_ctrl(p_btif, BTIF_DPIDLE_DISABLE); -+ switch (ori_state) { -+ case B_S_ON: -+/*B_S_ON can only be switched to B_S_OFF, B_S_SUSPEND and B_S_DPIDLE*/ -+/*B_S_ON->B_S_OFF : do nothing here*/ -+/* -+ * B_S_ON->B_S_DPLE : disable clock backup -+ * BTIF and DMA controller's register if necessary -+ */ -+ if (state == B_S_DPIDLE) { -+ /*clock controlled id done in _btif_enter_dpidle*/ -+ p_btif->state = state; -+ i_ret = 0; -+ } else if (state == B_S_OFF) { -+ /*clock controlled is done in btif_close*/ -+ p_btif->state = state; -+ i_ret = 0; -+ } else if (state == B_S_SUSPEND) { -+ /*clock controlled is done in btif_close*/ -+ p_btif->state = state; -+ i_ret = 0; -+ } else { -+ BTIF_ERR_FUNC("%s->%s is not allowed\n", -+ g_state[ori_state], -+ g_state[state]); -+ i_ret = E_BTIF_INVAL_STATE; -+ } -+ break; -+ case B_S_DPIDLE: -+/*B_S_DPIDLE can only be switched to B_S_ON and B_S_SUSPEND*/ -+/*B_S_DPIDLE-> B_S_ON: do nothing for this moment*/ -+/* -+ * B_S_DPIDLE-> B_S_SUSPEND: -+ * disable clock backup BTIF and DMA controller's register if necessary -+ */ -+ if (state == B_S_ON) { -+ /*clock controlled id done in _btif_exit_dpidle*/ -+ p_btif->state = state; -+ i_ret = 0; -+ } else if (state == B_S_SUSPEND) { -+ /*clock controlled is done in _btif_exit_dpidle*/ -+ p_btif->state = state; -+ i_ret = 0; -+ } else { -+ BTIF_ERR_FUNC("%s->%s is not allowed\n", -+ g_state[ori_state], -+ g_state[state]); -+ i_ret = E_BTIF_INVAL_STATE; -+ } -+ break; -+ -+ case B_S_SUSPEND: -+/*B_S_SUSPEND can be switched to B_S_IDLE and B_S_ON*/ -+/*reinit BTIF controller and DMA controller*/ -+ if (state == B_S_DPIDLE) { -+ /* -+ * system call resume API, do resume operation, -+ * change to deepidle state -+ */ -+ p_btif->state = state; -+ i_ret = 0; -+ } else if (state == B_S_ON) { -+ /* -+ * when stp want to send data before -+ * system do resume operation -+ */ -+ p_btif->state = state; -+ i_ret = 0; -+ } else { -+ BTIF_ERR_FUNC("%s->%s is not allowed\n", -+ g_state[ori_state], -+ g_state[state]); -+ i_ret = E_BTIF_INVAL_STATE; -+ } -+ break; -+ -+ case B_S_OFF:{ -+/*B_S_OFF can only be switched to B_S_ON*/ -+ if (state == B_S_ON) { -+ /*clock controlled is done in btif_open*/ -+ p_btif->state = state; -+ i_ret = 0; -+ } else { -+ BTIF_ERR_FUNC("%s->%s is not allowed\n", -+ g_state[ori_state], -+ g_state[state]); -+ i_ret = E_BTIF_INVAL_STATE; -+ } -+ } -+ break; -+ default: -+/*no this possibility*/ -+ BTIF_ERR_FUNC -+ ("state change request is not allowed, this should never happen\n"); -+ break; -+ } -+ -+ if (state != B_S_ON) -+ _btif_dpidle_notify_ctrl(p_btif, BTIF_DPIDLE_ENABLE); -+ -+ } else { -+ i_ret = E_BTIF_INVAL_PARAM; -+ BTIF_ERR_FUNC("invalid state:%d, do nothing\n", state); -+ } -+ return i_ret; -+} -+ -+static ENUM_BTIF_STATE _btif_state_get(p_mtk_btif p_btif) -+{ -+ return p_btif->state; -+} -+ -+static int _btif_state_release(p_mtk_btif p_btif) -+{ -+ int i_ret = 0; -+ -+ BTIF_MUTEX_UNLOCK(&(p_btif->state_mtx)); -+ return i_ret; -+} -+ -+static int _btif_state_deinit(p_mtk_btif p_btif) -+{ -+ if (p_btif == NULL) { -+ BTIF_ERR_FUNC("p_btif is NULL\n"); -+ return E_BTIF_INVAL_PARAM; -+ } -+ p_btif->state = B_S_OFF; -+ mutex_destroy(&(p_btif->state_mtx)); -+ -+ return 0; -+} -+ -+static int btif_rx_data_consummer(p_mtk_btif p_btif) -+{ -+ unsigned int length = 0; -+ unsigned char *p_buf = NULL; -+/*get BTIF rx buffer's information*/ -+ p_btif_buf_str p_bbs = &(p_btif->btif_buf); -+/* -+ * wr_idx of btif_buf may be modified in IRQ handler, -+ * in order not to be effected by case in which irq interrupt this operation, -+ * we record wr_idx here -+ */ -+ unsigned int wr_idx = p_bbs->wr_idx; -+ -+ length = BBS_COUNT_CUR(p_bbs, wr_idx); -+ -+/*make sure length of rx buffer data > 0*/ -+ do { -+ if (length > 0) { -+ /* -+ * check if rx_cb empty or not, if registered , -+ * call user's rx callback to handle these data -+ */ -+ if (p_btif->rx_cb) { -+ if (p_bbs->rd_idx <= wr_idx) { -+ p_buf = BBS_PTR(p_bbs, p_bbs->rd_idx); -+ /* p_buf = &(p_bbs->buf[p_bbs->rd_idx]); */ -+ /* length = BBS_COUNT(p_bbs); */ -+ length = (wr_idx >= (p_bbs)->rd_idx) ? -+ (wr_idx - (p_bbs)->rd_idx) : -+ BBS_SIZE(p_bbs) - -+ ((p_bbs)->rd_idx - wr_idx); -+ if (p_btif->rx_cb) -+ (*(p_btif->rx_cb)) (p_buf, length); -+ else -+ BTIF_ERR_FUNC("p_btif->rx_cb is NULL\n"); -+ /*update rx data read index*/ -+ p_bbs->rd_idx = wr_idx; -+ } else { -+ unsigned int len_tail = -+ BBS_SIZE(p_bbs) - (p_bbs)->rd_idx; -+ /*p_buf = &(p_bbs->buf[p_bbs->->rd_idx]);*/ -+ p_buf = BBS_PTR(p_bbs, p_bbs->rd_idx); -+ if (p_btif->rx_cb) -+ (*(p_btif->rx_cb)) (p_buf, len_tail); -+ else -+ BTIF_ERR_FUNC("p_btif->rx_cb is NULL\n"); -+ length = BBS_COUNT_CUR(p_bbs, wr_idx); -+ length -= len_tail; -+ /*p_buf = &(p_bbs->buf[0]);*/ -+ p_buf = BBS_PTR(p_bbs, 0); -+ if (p_btif->rx_cb) -+ (*(p_btif->rx_cb)) (p_buf, length); -+ else -+ BTIF_ERR_FUNC("p_btif->rx_cb is NULL\n"); -+ /*update rx data read index*/ -+ p_bbs->rd_idx = wr_idx; -+ } -+ } else if (p_btif->rx_notify != NULL) { -+ (*p_btif->rx_notify) (); -+ } else { -+ BTIF_WARN_FUNC -+ ("p_btif:0x%p, both rx_notify and rx_cb are NULL\n", -+ p_btif); -+ break; -+ } -+ } else { -+ BTIF_DBG_FUNC("length:%d\n", length); -+ break; -+ } -+ wr_idx = p_bbs->wr_idx; -+ length = BBS_COUNT_CUR(p_bbs, wr_idx); -+ } while (1); -+ return length; -+} -+ -+#if BTIF_RXD_BE_BLOCKED_DETECT -+static int mtk_btif_rxd_be_blocked_by_timer(void) -+{ -+ int ret = 0; -+ int counter = 0; -+ unsigned int i; -+ struct timeval now; -+ int time_gap[MAX_BTIF_RXD_TIME_REC]; -+ -+ do_gettimeofday(&now); -+ -+ for (i = 0; i < MAX_BTIF_RXD_TIME_REC; i++) { -+ BTIF_INFO_FUNC("btif_rxd_time_stamp[%d]=%d.%d\n", i, -+ btif_rxd_time_stamp[i].tv_sec, btif_rxd_time_stamp[i].tv_usec); -+ if (now.tv_sec >= btif_rxd_time_stamp[i].tv_sec) { -+ time_gap[i] = now.tv_sec - btif_rxd_time_stamp[i].tv_sec; -+ time_gap[i] *= 1000000; /*second*/ -+ if (now.tv_usec >= btif_rxd_time_stamp[i].tv_usec) -+ time_gap[i] += now.tv_usec - btif_rxd_time_stamp[i].tv_usec; -+ else -+ time_gap[i] += 1000000 - now.tv_usec + btif_rxd_time_stamp[i].tv_usec; -+ -+ if (time_gap[i] > 1000000) -+ counter++; -+ BTIF_INFO_FUNC("time_gap[%d]=%d,counter:%d\n", i, time_gap[i], counter); -+ } else { -+ time_gap[i] = 0; -+ BTIF_ERR_FUNC("abnormal case now:%d < time_stamp[%d]:%d\n", now.tv_sec, -+ i, btif_rxd_time_stamp[i].tv_usec); -+ } -+ } -+ if (counter > (MAX_BTIF_RXD_TIME_REC - 2)) -+ ret = 1; -+ return ret; -+} -+static int mtk_btif_rxd_be_blocked_by_data(void) -+{ -+ unsigned int out_index = 0; -+ unsigned int in_index = 0; -+ unsigned int dump_size = 0; -+ unsigned int len = 0; -+ unsigned long flags; -+ unsigned int sync_pkt_n = 0; -+ P_BTIF_LOG_BUF_T p_log_buf = NULL; -+ P_BTIF_LOG_QUEUE_T p_log_que = NULL; -+ p_mtk_btif p_btif = &(g_btif[0]); -+ -+ p_log_que = &p_btif->rx_log; -+ spin_lock_irqsave(&p_log_que->lock, flags); -+ in_index = p_log_que->in; -+ dump_size = p_log_que->size; -+ out_index = p_log_que->size >= -+ BTIF_LOG_ENTRY_NUM ? in_index : (BTIF_LOG_ENTRY_NUM - -+ p_log_que->size + -+ in_index) % BTIF_LOG_ENTRY_NUM; -+ if (dump_size != 0) { -+ while (dump_size--) { -+ p_log_buf = p_log_que->p_queue[0] + out_index; -+ len = p_log_buf->len; -+ if (len > BTIF_LOG_SZ) -+ len = BTIF_LOG_SZ; -+ if ((0x7f == *(p_log_buf->buffer)) && (0x7f == *(p_log_buf->buffer + 1))) { -+ sync_pkt_n++; -+ BTIF_INFO_FUNC("tx pkt_count:%d is sync pkt\n", out_index); -+ } -+ out_index++; -+ out_index %= BTIF_LOG_ENTRY_NUM; -+ } -+ } -+ if (sync_pkt_n == 0) -+ BTIF_ERR_FUNC("there is no sync pkt in BTIF buffer\n"); -+ else -+ BTIF_ERR_FUNC("there are %d sync pkt in BTIF buffer\n", sync_pkt_n); -+ spin_unlock_irqrestore(&p_log_que->lock, flags); -+ return sync_pkt_n; -+} -+ -+int mtk_btif_rxd_be_blocked_flag_get(void) -+{ -+ int ret = 0; -+ int condition1 = 0, condition2 = 0; -+ -+ condition1 = mtk_btif_rxd_be_blocked_by_timer(); -+ condition2 = mtk_btif_rxd_be_blocked_by_data(); -+ if (condition1 && condition2) { -+ BTIF_ERR_FUNC("btif_rxd thread be blocked too long!\n"); -+ ret = 1; -+ } -+ return ret; -+} -+#endif -+static int btif_rx_thread(void *p_data) -+{ -+#if BTIF_RXD_BE_BLOCKED_DETECT -+ unsigned int i = 0; -+#endif -+ p_mtk_btif p_btif = (p_mtk_btif)p_data; -+ -+ -+ while (1) { -+ wait_for_completion_interruptible(&p_btif->rx_comp); -+ -+ if (kthread_should_stop()) { -+ BTIF_WARN_FUNC("btif rx thread stoping ...\n"); -+ break; -+ } -+#ifdef BTIF_RXD_BE_BLOCKED_DETECT -+ do_gettimeofday(&btif_rxd_time_stamp[i]); -+ i++; -+ if (i >= MAX_BTIF_RXD_TIME_REC) -+ i = 0; -+#endif -+ btif_rx_data_consummer(p_btif); -+ } -+ return 0; -+} -+ -+static void btif_rx_worker(struct work_struct *p_work) -+{ -+/*get mtk_btif's pointer*/ -+ p_mtk_btif p_btif = container_of(p_work, mtk_btif, rx_work); -+ -+ BTIF_DBG_FUNC("p_btif:0x%p\n", p_btif); -+/*lock rx_mutex*/ -+ -+ if (mutex_lock_killable(&(p_btif->rx_mtx))) { -+ BTIF_ERR_FUNC("mutex_lock_killable return failed\n"); -+ return; -+ } -+ btif_rx_data_consummer(p_btif); -+ BTIF_MUTEX_UNLOCK(&(p_btif->rx_mtx)); -+} -+ -+static void btif_tx_worker(struct work_struct *p_work) -+{ -+ int i_ret = 0; -+ int leng_sent = 0; -+/*tx fifo out*/ -+ int how_much_get = 0; -+ unsigned char local_buf[384]; -+ -+/*get mtk_btif's pointer*/ -+ p_mtk_btif p_btif = container_of(p_work, mtk_btif, tx_work); -+ -+ BTIF_DBG_FUNC("p_btif:0x%p\n", p_btif); -+ -+ if (mutex_lock_killable(&(p_btif->tx_mtx))) { -+ BTIF_ERR_FUNC("mutex_lock_killable return failed\n"); -+ return; -+ } -+ how_much_get = -+ kfifo_out(p_btif->p_tx_fifo, local_buf, sizeof(local_buf)); -+ do { -+ while (leng_sent < how_much_get) { -+ i_ret = _btif_send_data(p_btif, -+ local_buf + leng_sent, -+ how_much_get - leng_sent); -+ if (i_ret > 0) { -+ leng_sent += i_ret; -+ } else if (i_ret == 0) { -+ BTIF_WARN_FUNC -+ ("_btif_send_data return 0, retry\n"); -+ } else { -+ BTIF_WARN_FUNC -+ ("btif send data fail,reset tx fifo, i_ret(%d)\n", -+ i_ret); -+ kfifo_reset(p_btif->p_tx_fifo); -+ break; -+ } -+ } -+ how_much_get = -+ kfifo_out(p_btif->p_tx_fifo, local_buf, sizeof(local_buf)); -+ leng_sent = 0; -+ } while (how_much_get > 0); -+ BTIF_MUTEX_UNLOCK(&(p_btif->tx_mtx)); -+} -+ -+static void btif_rx_tasklet(unsigned long func_data) -+{ -+ unsigned long flags; -+/*get mtk_btif's pointer*/ -+ p_mtk_btif p_btif = (p_mtk_btif) func_data; -+ -+ BTIF_DBG_FUNC("p_btif:0x%p\n", p_btif); -+/*lock rx_spinlock*/ -+ spin_lock_irqsave(&p_btif->rx_tasklet_spinlock, flags); -+ btif_rx_data_consummer(p_btif); -+ spin_unlock_irqrestore(&p_btif->rx_tasklet_spinlock, flags); -+} -+ -+static int _btif_tx_ctx_init(p_mtk_btif p_btif) -+{ -+ int i_ret = -1; -+ -+ if (p_btif == NULL) { -+ BTIF_ERR_FUNC("p_btif is NULL\n"); -+ return E_BTIF_INVAL_PARAM; -+ } -+ -+ if (p_btif->tx_ctx == BTIF_TX_SINGLE_CTX) { -+ p_btif->p_tx_wq = create_singlethread_workqueue("btif_txd"); -+ -+ if (!(p_btif->p_tx_wq)) { -+ BTIF_ERR_FUNC -+ ("create_singlethread_workqueue for tx thread fail\n"); -+ i_ret = -ENOMEM; -+ goto btm_init_err; -+ } -+ mutex_init(&(p_btif->tx_mtx)); -+/* init btif tx work */ -+ INIT_WORK(&(p_btif->tx_work), btif_tx_worker); -+ BTIF_INFO_FUNC("btif_tx_worker init succeed\n"); -+ -+ p_btif->p_tx_fifo = kzalloc(sizeof(struct kfifo), GFP_ATOMIC); -+ if (p_btif->p_tx_fifo == NULL) { -+ i_ret = -ENOMEM; -+ BTIF_ERR_FUNC("kzalloc for p_btif->p_tx_fifo failed\n"); -+ goto btm_init_err; -+ } -+ -+ i_ret = kfifo_alloc(p_btif->p_tx_fifo, -+ BTIF_TX_FIFO_SIZE, GFP_ATOMIC); -+ if (i_ret != 0) { -+ BTIF_ERR_FUNC("kfifo_alloc failed, errno(%d)\n", i_ret); -+ i_ret = -ENOMEM; -+ goto btm_init_err; -+ } -+ } else if (p_btif->tx_ctx == BTIF_TX_USER_CTX) { -+ BTIF_INFO_FUNC -+ ("nothing is done when btif tx in user's thread\n"); -+ } else { -+ BTIF_ERR_FUNC("unsupported tx context type:%d\n", -+ p_btif->tx_ctx); -+ goto btm_init_err; -+ } -+ -+ BTIF_INFO_FUNC("succeed\n"); -+ -+ i_ret = 0; -+ return i_ret; -+btm_init_err: -+ if (p_btif->tx_ctx == BTIF_TX_SINGLE_CTX) { -+ if (p_btif->p_tx_wq) { -+ destroy_workqueue(p_btif->p_tx_wq); -+ p_btif->p_tx_wq = NULL; -+ BTIF_INFO_FUNC("btif_tx_workqueue destroyed\n"); -+ } -+ kfree(p_btif->p_tx_fifo); -+ } -+ return i_ret; -+} -+ -+static int _btif_tx_ctx_deinit(p_mtk_btif p_btif) -+{ -+ int i_ret = 0; -+ -+ if (p_btif->tx_ctx == BTIF_TX_SINGLE_CTX) { -+ if (p_btif->p_tx_wq) { -+ destroy_workqueue(p_btif->p_tx_wq); -+ p_btif->p_tx_wq = NULL; -+ BTIF_INFO_FUNC("btif_tx_workqueue destroyed\n"); -+ } -+ if (p_btif->p_tx_fifo) { -+ kfifo_free(p_btif->p_tx_fifo); -+ kfree(p_btif->p_tx_fifo); -+ p_btif->p_tx_fifo = NULL; -+ } -+ } -+ return i_ret; -+} -+ -+static int _btif_rx_btm_init(p_mtk_btif p_btif) -+{ -+ int i_ret = -1; -+ -+ if (p_btif == NULL) { -+ BTIF_ERR_FUNC("p_btif is NULL\n"); -+ return E_BTIF_INVAL_PARAM; -+ } -+ -+ if (p_btif->btm_type == BTIF_THREAD_CTX) { -+ init_completion(&p_btif->rx_comp); -+ -+ /*create kernel thread for later rx data handle*/ -+ p_btif->p_task = kthread_create(btif_rx_thread, p_btif, "btif_rxd"); -+ if (p_btif->p_task == NULL) { -+ BTIF_ERR_FUNC("kthread_create fail\n"); -+ i_ret = -ENOMEM; -+ goto btm_init_err; -+ } -+ -+#if ENABLE_BTIF_RX_THREAD_RT_SCHED -+ { -+ int i_ret = -1; -+ int policy = SCHED_FIFO; -+ struct sched_param param; -+ -+ param.sched_priority = MAX_RT_PRIO - 20; -+ i_ret = sched_setscheduler(p_btif->p_task, policy, ¶m); -+ if (i_ret != 0) -+ BTIF_WARN_FUNC("set RT to btif_rxd workqueue failed\n"); -+ else -+ BTIF_INFO_FUNC("set RT to btif_rxd workqueue succeed\n"); -+ } -+#endif -+ -+ wake_up_process(p_btif->p_task); -+ BTIF_INFO_FUNC("btif_rxd start to work!\n"); -+ } else if (p_btif->btm_type == BTIF_WQ_CTX) { -+ p_btif->p_rx_wq = create_singlethread_workqueue("btif_rxwq"); -+ if (!(p_btif->p_rx_wq)) { -+ BTIF_ERR_FUNC("create_singlethread_workqueue fail\n"); -+ i_ret = -ENOMEM; -+ goto btm_init_err; -+ } -+ mutex_init(&(p_btif->rx_mtx)); -+ /* init btif rx work */ -+ INIT_WORK(&(p_btif->rx_work), btif_rx_worker); -+ BTIF_INFO_FUNC("btif_rx_worker init succeed\n"); -+ } else if (p_btif->btm_type == BTIF_TASKLET_CTX) { -+ /*init rx tasklet*/ -+ tasklet_init(&(p_btif->rx_tasklet), btif_rx_tasklet, -+ (unsigned long)p_btif); -+ spin_lock_init(&(p_btif->rx_tasklet_spinlock)); -+ BTIF_INFO_FUNC("btif_rx_tasklet init succeed\n"); -+ } else { -+ BTIF_ERR_FUNC("unsupported rx context type:%d\n", -+ p_btif->btm_type); -+ } -+ -+/*spinlock init*/ -+ spin_lock_init(&(p_btif->rx_irq_spinlock)); -+ BTIF_INFO_FUNC("rx_spin_lock init succeed\n"); -+ -+ i_ret = 0; -+ return i_ret; -+btm_init_err: -+ if (p_btif->btm_type == BTIF_THREAD_CTX) { -+ /*do nothing*/ -+ BTIF_INFO_FUNC("failed\n"); -+ } else if (p_btif->btm_type == BTIF_WQ_CTX) { -+ if (p_btif->p_rx_wq) { -+ destroy_workqueue(p_btif->p_rx_wq); -+ p_btif->p_rx_wq = NULL; -+ BTIF_INFO_FUNC("btif_rx_workqueue destroyed\n"); -+ } -+ } -+ return i_ret; -+} -+ -+static int _btif_rx_btm_sched(p_mtk_btif p_btif) -+{ -+ if (p_btif == NULL) { -+ BTIF_ERR_FUNC("p_btif is NULL\n"); -+ return E_BTIF_INVAL_PARAM; -+ } -+ -+ if (p_btif->btm_type == BTIF_THREAD_CTX) { -+ complete(&p_btif->rx_comp); -+ BTIF_DBG_FUNC("schedule btif_rx_thread\n"); -+ } else if (p_btif->btm_type == BTIF_WQ_CTX) { -+ queue_work(p_btif->p_rx_wq, &(p_btif->rx_work)); -+ BTIF_DBG_FUNC("schedule btif_rx_worker\n"); -+ } else if (p_btif->btm_type == BTIF_TASKLET_CTX) { -+ /*schedule it!*/ -+ tasklet_schedule(&(p_btif->rx_tasklet)); -+ BTIF_DBG_FUNC("schedule btif_rx_tasklet\n"); -+ } else { -+ BTIF_ERR_FUNC("unsupported rx context type:%d\n", -+ p_btif->btm_type); -+ } -+ -+ return 0; -+} -+ -+static int _btif_rx_btm_deinit(p_mtk_btif p_btif) -+{ -+ if (p_btif == NULL) { -+ BTIF_ERR_FUNC("p_btif is NULL\n"); -+ return E_BTIF_INVAL_PARAM; -+ } -+ if (p_btif->btm_type == BTIF_THREAD_CTX) { -+ if (p_btif->p_task != NULL) { -+ BTIF_INFO_FUNC("signaling btif rx thread to stop ...\n"); -+ kthread_stop(p_btif->p_task); -+ } -+ } else if (p_btif->btm_type == BTIF_WQ_CTX) { -+ if (p_btif->p_rx_wq) { -+ cancel_work_sync(&(p_btif->rx_work)); -+ BTIF_INFO_FUNC("btif_rx_worker cancelled\n"); -+ destroy_workqueue(p_btif->p_rx_wq); -+ p_btif->p_rx_wq = NULL; -+ BTIF_INFO_FUNC("btif_rx_workqueue destroyed\n"); -+ } -+ mutex_destroy(&(p_btif->rx_mtx)); -+ } else if (p_btif->btm_type == BTIF_TASKLET_CTX) { -+ tasklet_kill(&(p_btif->rx_tasklet)); -+ BTIF_INFO_FUNC("rx_tasklet killed\n"); -+ } else { -+ BTIF_ERR_FUNC("unsupported rx context type:%d\n", -+ p_btif->btm_type); -+ } -+ -+ spin_lock_init(&(p_btif->rx_irq_spinlock)); -+ -+ return 0; -+} -+ -+ -+void btif_dump_bbs_str(unsigned char *p_str, p_btif_buf_str p_bbs) -+{ -+ BTIF_INFO_FUNC -+ ("%s UBS:0x%p\n Size:0x%p\n read:0x%08x\n write:0x%08x\n", -+ p_str, p_bbs, p_bbs->size, p_bbs->rd_idx, p_bbs->wr_idx); -+} -+ -+unsigned int btif_bbs_write(p_btif_buf_str p_bbs, -+ unsigned char *p_buf, unsigned int buf_len) -+{ -+/*in IRQ context, so read operation won't interrupt this operation*/ -+ -+ unsigned int wr_len = 0; -+ -+ unsigned int emp_len = BBS_LEFT(p_bbs); -+ unsigned int ava_len = emp_len - 1; -+ p_mtk_btif p_btif = container_of(p_bbs, mtk_btif, btif_buf); -+ -+ if (ava_len <= 0) { -+ BTIF_ERR_FUNC -+ ("no empty space left for write, (%d)ava_len, (%d)to write\n", -+ ava_len, buf_len); -+ hal_btif_dump_reg(p_btif->p_btif_info, REG_BTIF_ALL); -+ hal_dma_dump_reg(p_btif->p_rx_dma->p_dma_info, REG_RX_DMA_ALL); -+ return 0; -+ } -+ -+ if (ava_len < buf_len) { -+ BTIF_ERR_FUNC("BTIF overrun, (%d)empty, (%d)needed\n", -+ emp_len, buf_len); -+ hal_btif_dump_reg(p_btif->p_btif_info, REG_BTIF_ALL); -+ hal_dma_dump_reg(p_btif->p_rx_dma->p_dma_info, REG_RX_DMA_ALL); -+ _btif_dump_memory("", p_buf, buf_len); -+ } -+ -+ if (buf_len >= g_max_pkg_len) { -+ BTIF_WARN_FUNC("buf_len too long, (%d)ava_len, (%d)to write\n", -+ ava_len, buf_len); -+ hal_btif_dump_reg(p_btif->p_btif_info, REG_BTIF_ALL); -+ hal_dma_dump_reg(p_btif->p_rx_dma->p_dma_info, REG_RX_DMA_ALL); -+ _btif_dump_memory("", p_buf, buf_len); -+ } -+ -+ wr_len = min(buf_len, ava_len); -+ btif_bbs_wr_direct(p_bbs, p_buf, wr_len); -+ -+ if (BBS_COUNT(p_bbs) >= g_max_pding_data_size) { -+ BTIF_WARN_FUNC("Rx buf_len too long, size(%d)\n", -+ BBS_COUNT(p_bbs)); -+ btif_dump_bbs_str("Rx buffer tooo long", p_bbs); -+ hal_btif_dump_reg(p_btif->p_btif_info, REG_BTIF_ALL); -+ hal_dma_dump_reg(p_btif->p_rx_dma->p_dma_info, REG_RX_DMA_ALL); -+ _btif_dump_memory("", p_buf, buf_len); -+ BBS_INIT(p_bbs); -+ } -+ -+ return wr_len; -+} -+ -+unsigned int btif_bbs_read(p_btif_buf_str p_bbs, -+ unsigned char *p_buf, unsigned int buf_len) -+{ -+ unsigned int rd_len = 0; -+ unsigned int ava_len = 0; -+ unsigned int wr_idx = p_bbs->wr_idx; -+ -+ ava_len = BBS_COUNT_CUR(p_bbs, wr_idx); -+ if (ava_len >= 4096) { -+ BTIF_WARN_FUNC("ava_len too long, size(%d)\n", ava_len); -+ btif_dump_bbs_str("Rx buffer tooo long", p_bbs); -+ } -+ if (ava_len != 0) { -+ if (buf_len >= ava_len) { -+ rd_len = ava_len; -+ if (wr_idx >= (p_bbs)->rd_idx) { -+ memcpy(p_buf, BBS_PTR(p_bbs, -+ p_bbs->rd_idx), -+ ava_len); -+ (p_bbs)->rd_idx = wr_idx; -+ } else { -+ unsigned int tail_len = BBS_SIZE(p_bbs) - -+ (p_bbs)->rd_idx; -+ memcpy(p_buf, BBS_PTR(p_bbs, -+ p_bbs->rd_idx), -+ tail_len); -+ memcpy(p_buf + tail_len, BBS_PTR(p_bbs, -+ 0), ava_len - tail_len); -+ (p_bbs)->rd_idx = wr_idx; -+ } -+ } else { -+ rd_len = buf_len; -+ if (wr_idx >= (p_bbs)->rd_idx) { -+ memcpy(p_buf, BBS_PTR(p_bbs, -+ p_bbs->rd_idx), -+ rd_len); -+ (p_bbs)->rd_idx = (p_bbs)->rd_idx + rd_len; -+ } else { -+ unsigned int tail_len = BBS_SIZE(p_bbs) - -+ (p_bbs)->rd_idx; -+ if (tail_len >= rd_len) { -+ memcpy(p_buf, BBS_PTR(p_bbs, p_bbs->rd_idx), -+ rd_len); -+ (p_bbs)->rd_idx = -+ ((p_bbs)->rd_idx + rd_len) & (BBS_MASK(p_bbs)); -+ } else { -+ memcpy(p_buf, BBS_PTR(p_bbs, p_bbs->rd_idx), tail_len); -+ memcpy(p_buf + tail_len, -+ (p_bbs)->p_buf, rd_len - tail_len); -+ (p_bbs)->rd_idx = rd_len - tail_len; -+ } -+ } -+ } -+ } -+ mb(); -+ return rd_len; -+} -+ -+unsigned int btif_bbs_wr_direct(p_btif_buf_str p_bbs, -+ unsigned char *p_buf, unsigned int buf_len) -+{ -+ unsigned int tail_len = 0; -+ unsigned int l = 0; -+ unsigned int tmp_wr_idx = p_bbs->wr_idx; -+ -+ tail_len = BBS_SIZE(p_bbs) - (tmp_wr_idx & BBS_MASK(p_bbs)); -+ -+ l = min(tail_len, buf_len); -+ -+ memcpy((p_bbs->p_buf) + (tmp_wr_idx & BBS_MASK(p_bbs)), p_buf, l); -+ memcpy(p_bbs->p_buf, p_buf + l, buf_len - l); -+ -+ mb(); -+ -+ tmp_wr_idx += buf_len; -+ tmp_wr_idx &= BBS_MASK(p_bbs); -+ p_bbs->wr_idx = tmp_wr_idx; -+ -+ mb(); -+ return buf_len; -+} -+ -+int _btif_dma_write(p_mtk_btif p_btif, -+ const unsigned char *p_buf, unsigned int buf_len) -+{ -+ unsigned int i_ret = 0; -+ unsigned int retry = 0; -+ unsigned int max_tx_retry = 10; -+ -+ P_MTK_DMA_INFO_STR p_dma_info = p_btif->p_tx_dma->p_dma_info; -+ -+ _btif_irq_ctrl_sync(p_dma_info->p_irq, false); -+ do { -+ /*wait until tx is allowed*/ -+ while (!hal_dma_is_tx_allow(p_dma_info) && -+ (retry < max_tx_retry)) { -+ retry++; -+ if (retry >= max_tx_retry) { -+ BTIF_ERR_FUNC("wait for tx allowed timeout\n"); -+ break; -+ } -+ } -+ if (retry >= max_tx_retry) -+ break; -+ -+ if (buf_len <= hal_dma_get_ava_room(p_dma_info)) -+ i_ret = hal_dma_send_data(p_dma_info, p_buf, buf_len); -+ else -+ i_ret = 0; -+ } while (0); -+ _btif_irq_ctrl_sync(p_dma_info->p_irq, true); -+ return i_ret; -+} -+ -+int _btif_pio_write(p_mtk_btif p_btif, -+ const unsigned char *p_buf, unsigned int buf_len) -+{ -+ unsigned int i_ret = 0; -+ unsigned int sent_len = 0; -+ unsigned int retry = 0; -+ unsigned int max_tx_retry = 10; -+ P_MTK_BTIF_INFO_STR p_btif_info = p_btif->p_btif_info; -+ -+ while ((sent_len < buf_len)) { -+ if (hal_btif_is_tx_allow(p_btif_info)) { -+ i_ret = hal_btif_send_data(p_btif_info, -+ p_buf + sent_len, -+ buf_len - sent_len); -+ if (i_ret > 0) { -+ sent_len += i_ret; -+ BTIF_DBG_FUNC("lent sent:%d, total sent:%d\n", -+ i_ret, sent_len); -+ retry = 0; -+ } -+ } -+ if ((++retry > max_tx_retry) || (i_ret < 0)) { -+ BTIF_INFO_FUNC("exceed retry times limit :%d\n", retry); -+ break; -+ } -+ } -+ i_ret = sent_len; -+ return i_ret; -+} -+ -+int _btif_dump_memory(char *str, unsigned char *p_buf, unsigned int buf_len) -+{ -+ unsigned int idx = 0; -+ -+ pr_debug("%s:, length:%d\n", str, buf_len); -+ for (idx = 0; idx < buf_len;) { -+ pr_debug("%02x ", p_buf[idx]); -+ idx++; -+ if (idx % 8 == 0) -+ pr_debug("\n"); -+ } -+ return 0; -+} -+ -+int btif_send_data(p_mtk_btif p_btif, -+ const unsigned char *p_buf, unsigned int buf_len) -+{ -+ int i_ret = 0; -+ -+ if (p_btif->tx_ctx == BTIF_TX_USER_CTX) { -+ i_ret = _btif_send_data(p_btif, p_buf, buf_len); -+ } else if (p_btif->tx_ctx == BTIF_TX_SINGLE_CTX) { -+ int length = 0; -+/*tx fifo in*/ -+ length = kfifo_in(p_btif->p_tx_fifo, -+ (unsigned char *)p_buf, buf_len); -+ if (length == buf_len) { -+ queue_work(p_btif->p_tx_wq, &(p_btif->tx_work)); -+ BTIF_DBG_FUNC("schedule btif_tx_worker\n"); -+ i_ret = length; -+ } else { -+ i_ret = 0; -+ BTIF_ERR_FUNC("fifo in failed, target len(%d),in len(%d),", -+ "don't schedule btif_tx_worker\n", buf_len, length); -+ } -+ } else { -+ BTIF_ERR_FUNC("invalid btif tx context:%d\n", p_btif->tx_ctx); -+ i_ret = 0; -+ } -+ -+ return i_ret; -+} -+ -+int _btif_send_data(p_mtk_btif p_btif, -+ const unsigned char *p_buf, unsigned int buf_len) -+{ -+ int i_ret = 0; -+ unsigned int state = 0; -+ -+/*make sure BTIF in ON state before doing tx operation*/ -+ if (_btif_state_hold(p_btif)) -+ return E_BTIF_INTR; -+ state = _btif_state_get(p_btif); -+ -+ if (state != B_S_ON) -+ i_ret = _btif_exit_dpidle(p_btif); -+ -+ if (i_ret != 0) { -+ i_ret = E_BTIF_INVAL_STATE; -+ } else if (p_btif->tx_mode == BTIF_MODE_DMA) { -+ /*_btif_dump_memory("tx data:", p_buf, buf_len);*/ -+ i_ret = _btif_dma_write(p_btif, p_buf, buf_len); -+ } else if (p_btif->tx_mode == BTIF_MODE_PIO) { -+ /*_btif_dump_memory("tx data:", p_buf, buf_len);*/ -+ i_ret = _btif_pio_write(p_btif, p_buf, buf_len); -+ } else { -+ BTIF_ERR_FUNC("invalid tx mode:%d\n", p_btif->tx_mode); -+ i_ret = 0; -+ } -+ -+/*save Tx packet here*/ -+ if (i_ret > 0) -+ btif_log_buf_dmp_in(&p_btif->tx_log, p_buf, i_ret); -+ -+ BTIF_STATE_RELEASE(p_btif); -+ return i_ret; -+} -+ -+int btif_dump_reg(p_mtk_btif p_btif) -+{ -+ int i_ret = 0; -+ unsigned int ori_state = 0; -+ -+/*make sure BTIF in ON state before doing tx operation*/ -+ if (_btif_state_hold(p_btif)) -+ return E_BTIF_INTR; -+ ori_state = _btif_state_get(p_btif); -+ -+ if (ori_state == B_S_OFF) { -+ i_ret = E_BTIF_INVAL_STATE; -+ BTIF_ERR_FUNC -+ ("BTIF in OFF state, ", -+ "should no need to dump register, ", -+ "please check wmt's operation is okay or not.\n"); -+ goto dmp_reg_err; -+ } -+ -+ if ((ori_state != B_S_ON) && (ori_state < B_S_MAX)) { -+ BTIF_ERR_FUNC("BTIF's original state is %s, not B_S_ON\n", g_state[ori_state]); -+ BTIF_ERR_FUNC("!!!!---<<>>---!!!"); -+ i_ret = _btif_exit_dpidle(p_btif); -+ } -+ -+ if (i_ret != 0) { -+ i_ret = E_BTIF_INVAL_STATE; -+ BTIF_ERR_FUNC("switch to B_S_ON failed\n"); -+ goto dmp_reg_err; -+ } -+ -+/*dump BTIF register*/ -+ hal_btif_dump_reg(p_btif->p_btif_info, REG_BTIF_ALL); -+ -+/*dump BTIF Tx DMA channel register if in DMA mode*/ -+ if (p_btif->tx_mode == BTIF_MODE_DMA) -+ hal_dma_dump_reg(p_btif->p_tx_dma->p_dma_info, REG_TX_DMA_ALL); -+ else -+ BTIF_INFO_FUNC("BTIF Tx in PIO mode,no need to dump Tx DMA's register\n"); -+ -+/*dump BTIF Rx DMA channel register if in DMA mode*/ -+ if (p_btif->rx_mode == BTIF_MODE_DMA) -+ hal_dma_dump_reg(p_btif->p_rx_dma->p_dma_info, REG_RX_DMA_ALL); -+ else -+ BTIF_INFO_FUNC("BTIF Rx in PIO mode,no need to dump Rx DMA's register\n"); -+ -+ switch (ori_state) { -+ case B_S_SUSPEND: -+/*return to dpidle state*/ -+/* break; */ -+ case B_S_DPIDLE: -+/*return to dpidle state*/ -+ _btif_enter_dpidle(p_btif); -+ break; -+ case B_S_ON: -+/*nothing needs to be done*/ -+ break; -+ default: -+ break; -+ } -+ -+dmp_reg_err: -+ -+ BTIF_STATE_RELEASE(p_btif); -+ return i_ret; -+} -+ -+int btif_rx_notify_reg(p_mtk_btif p_btif, MTK_BTIF_RX_NOTIFY rx_notify) -+{ -+ if (p_btif->rx_notify) { -+ BTIF_WARN_FUNC -+ ("rx cb already exist, rewrite from (0x%p) to (0x%p)\n", -+ p_btif->rx_notify, rx_notify); -+ } -+ p_btif->rx_notify = rx_notify; -+ -+ return 0; -+} -+ -+int btif_dump_data(char *p_buf, int len) -+{ -+ unsigned int idx = 0; -+ unsigned char str[30]; -+ unsigned char *p_str; -+ -+ p_str = &str[0]; -+ for (idx = 0; idx < len; idx++, p_buf++) { -+ sprintf(p_str, "%02x ", *p_buf); -+ p_str += 3; -+ if (7 == (idx % 8)) { -+ *p_str++ = '\n'; -+ *p_str = '\0'; -+ pr_debug("%s", str); -+ p_str = &str[0]; -+ } -+ } -+ if (len % 8) { -+ *p_str++ = '\n'; -+ *p_str = '\0'; -+ pr_debug("%s", str); -+ } -+ return 0; -+} -+ -+int btif_log_buf_dmp_in(P_BTIF_LOG_QUEUE_T p_log_que, const char *p_buf, -+ int len) -+{ -+ P_BTIF_LOG_BUF_T p_log_buf = NULL; -+ char *dir = NULL; -+ struct timeval *p_timer = NULL; -+ unsigned long flags; -+ bool output_flag = false; -+ -+ BTIF_DBG_FUNC("++\n"); -+ -+ if ((p_log_que == NULL) || (p_buf == NULL) || (len == 0)) { -+ BTIF_ERR_FUNC("invalid parameter, p_log_que(0x%x), buf(0x%x), ", -+ "len(%d)\n", p_log_que, p_buf, len); -+ return 0; -+ } -+ if (!(p_log_que->enable)) -+ return 0; -+ -+ dir = p_log_que->dir == BTIF_TX ? "Tx" : "Rx"; -+ output_flag = p_log_que->output_flag; -+ -+ spin_lock_irqsave(&(p_log_que->lock), flags); -+ -+/*get next log buffer for record usage*/ -+ p_log_buf = p_log_que->p_queue[0] + p_log_que->in; -+ p_timer = &p_log_buf->timer; -+ -+/*log time stamp*/ -+ do_gettimeofday(p_timer); -+ -+/*record data information including length and content*/ -+ p_log_buf->len = len; -+ memcpy(p_log_buf->buffer, p_buf, len > BTIF_LOG_SZ ? BTIF_LOG_SZ : len); -+ -+/*update log queue size information*/ -+ p_log_que->size++; -+ p_log_que->size = p_log_que->size > -+ BTIF_LOG_ENTRY_NUM ? BTIF_LOG_ENTRY_NUM : p_log_que->size; -+ -+/*update log queue index information*/ -+ p_log_que->in++; -+ p_log_que->in %= BTIF_LOG_ENTRY_NUM; -+ -+ spin_unlock_irqrestore(&p_log_que->lock, flags); -+ -+/*check if log dynamic output function is enabled or not*/ -+ if (output_flag) { -+ pr_debug("BTIF-DBG, dir:%s, %d.%ds len:%d\n", -+ dir, (int)p_timer->tv_sec, (int)p_timer->tv_usec, len); -+/*output buffer content*/ -+ btif_dump_data((char *)p_buf, len); -+ } -+ BTIF_DBG_FUNC("--\n"); -+ -+ return 0; -+} -+ -+int btif_log_buf_dmp_out(P_BTIF_LOG_QUEUE_T p_log_que) -+{ -+ P_BTIF_LOG_BUF_T p_log_buf = NULL; -+ unsigned int out_index = 0; -+ unsigned int in_index = 0; -+ unsigned int dump_size = 0; -+ unsigned char *p_buf = NULL; -+ unsigned int len = 0; -+ unsigned int pkt_count = 0; -+ unsigned char *p_dir = NULL; -+ struct timeval *p_timer = NULL; -+ unsigned long flags; -+ -+#if 0 /* no matter enable or not, we allowed output */ -+ if (!(p_log_que->enable)) -+ return; -+#endif -+ BTIF_DBG_FUNC("++\n"); -+ -+ spin_lock_irqsave(&p_log_que->lock, flags); -+ in_index = p_log_que->in; -+ dump_size = p_log_que->size; -+ out_index = p_log_que->size >= -+ BTIF_LOG_ENTRY_NUM ? in_index : (BTIF_LOG_ENTRY_NUM - -+ p_log_que->size + -+ in_index) % BTIF_LOG_ENTRY_NUM; -+ p_dir = p_log_que->dir == BTIF_TX ? "Tx" : "Rx"; -+ -+ BTIF_INFO_FUNC("btif %s log buffer size:%d\n", p_dir, dump_size); -+ -+ if (dump_size != 0) { -+ while (dump_size--) { -+ p_log_buf = p_log_que->p_queue[0] + out_index; -+ -+ len = p_log_buf->len; -+ p_buf = p_log_buf->buffer; -+ p_timer = &p_log_buf->timer; -+ -+ len = len > BTIF_LOG_SZ ? BTIF_LOG_SZ : len; -+ -+ BTIF_INFO_FUNC("dir:%s, pkt_count:%d, %d.%ds len:%d\n", -+ p_dir, -+ pkt_count++, -+ (int)p_timer->tv_sec, -+ (int)p_timer->tv_usec, len); -+/*output buffer content*/ -+ btif_dump_data(p_log_buf->buffer, len); -+ out_index++; -+ out_index %= BTIF_LOG_ENTRY_NUM; -+ } -+ } -+ spin_unlock_irqrestore(&p_log_que->lock, flags); -+ BTIF_DBG_FUNC("--\n"); -+ -+ return 0; -+} -+ -+int btif_log_buf_enable(P_BTIF_LOG_QUEUE_T p_log_que) -+{ -+ unsigned long flags; -+ -+ spin_lock_irqsave(&p_log_que->lock, flags); -+ p_log_que->enable = true; -+ spin_unlock_irqrestore(&p_log_que->lock, flags); -+ BTIF_INFO_FUNC("enable %s log function\n", -+ p_log_que->dir == BTIF_TX ? "Tx" : "Rx"); -+ return 0; -+} -+ -+int btif_log_buf_disable(P_BTIF_LOG_QUEUE_T p_log_que) -+{ -+ unsigned long flags; -+ -+ spin_lock_irqsave(&p_log_que->lock, flags); -+ p_log_que->enable = false; -+ spin_unlock_irqrestore(&p_log_que->lock, flags); -+ BTIF_INFO_FUNC("disable %s log function\n", -+ p_log_que->dir == BTIF_TX ? "Tx" : "Rx"); -+ return 0; -+} -+ -+int btif_log_output_enable(P_BTIF_LOG_QUEUE_T p_log_que) -+{ -+ unsigned long flags; -+ -+ spin_lock_irqsave(&p_log_que->lock, flags); -+ p_log_que->output_flag = true; -+ spin_unlock_irqrestore(&p_log_que->lock, flags); -+ BTIF_INFO_FUNC("%s log rt output enabled\n", -+ p_log_que->dir == BTIF_TX ? "Tx" : "Rx"); -+ return 0; -+} -+ -+int btif_log_output_disable(P_BTIF_LOG_QUEUE_T p_log_que) -+{ -+ unsigned long flags; -+ -+ spin_lock_irqsave(&p_log_que->lock, flags); -+ p_log_que->output_flag = false; -+ spin_unlock_irqrestore(&p_log_que->lock, flags); -+ BTIF_INFO_FUNC("%s log rt output disabled\n", -+ p_log_que->dir == BTIF_TX ? "Tx" : "Rx"); -+ return 0; -+} -+ -+int btif_log_buf_reset(P_BTIF_LOG_QUEUE_T p_log_que) -+{ -+ unsigned long flags; -+ -+ spin_lock_irqsave(&p_log_que->lock, flags); -+ -+/*tx log buffer init*/ -+ p_log_que->in = 0; -+ p_log_que->out = 0; -+ p_log_que->size = 0; -+ p_log_que->enable = true; -+ memset((p_log_que->p_queue[0]), 0, sizeof(BTIF_LOG_BUF_T)); -+ -+ spin_unlock_irqrestore(&p_log_que->lock, flags); -+ BTIF_DBG_FUNC("reset %s log buffer\n", -+ p_log_que->dir == BTIF_TX ? "Tx" : "Rx"); -+ return 0; -+} -+ -+int btif_log_buf_init(p_mtk_btif p_btif) -+{ -+/*tx log buffer init*/ -+ p_btif->tx_log.dir = BTIF_TX; -+ p_btif->tx_log.in = 0; -+ p_btif->tx_log.out = 0; -+ p_btif->tx_log.size = 0; -+ p_btif->tx_log.output_flag = false; -+ p_btif->tx_log.enable = true; -+ spin_lock_init(&(p_btif->tx_log.lock)); -+ BTIF_DBG_FUNC("tx_log.p_queue:0x%p\n", p_btif->tx_log.p_queue[0]); -+ memset((p_btif->tx_log.p_queue[0]), 0, sizeof(BTIF_LOG_BUF_T)); -+ -+/*rx log buffer init*/ -+ p_btif->rx_log.dir = BTIF_RX; -+ p_btif->rx_log.in = 0; -+ p_btif->rx_log.out = 0; -+ p_btif->rx_log.size = 0; -+ p_btif->rx_log.output_flag = false; -+ p_btif->rx_log.enable = true; -+ spin_lock_init(&(p_btif->rx_log.lock)); -+ BTIF_DBG_FUNC("rx_log.p_queue:0x%p\n", p_btif->rx_log.p_queue[0]); -+ memset((p_btif->rx_log.p_queue[0]), 0, sizeof(BTIF_LOG_BUF_T)); -+ -+ return 0; -+} -+ -+int btif_tx_dma_mode_set(int en) -+{ -+ int index = 0; -+ ENUM_BTIF_MODE mode = (en == 1) ? BTIF_MODE_DMA : BTIF_MODE_PIO; -+ -+ for (index = 0; index < BTIF_PORT_NR; index++) -+ g_btif[index].tx_mode = mode; -+ -+ return 0; -+} -+ -+int btif_rx_dma_mode_set(int en) -+{ -+ int index = 0; -+ ENUM_BTIF_MODE mode = (en == 1) ? BTIF_MODE_DMA : BTIF_MODE_PIO; -+ -+ for (index = 0; index < BTIF_PORT_NR; index++) -+ g_btif[index].rx_mode = mode; -+ -+ return 0; -+} -+ -+static int BTIF_init(void) -+{ -+ int i_ret = -1; -+ int index = 0; -+ p_mtk_btif_dma p_tx_dma = NULL; -+ p_mtk_btif_dma p_rx_dma = NULL; -+ unsigned char *p_btif_buffer = NULL; -+ unsigned char *p_tx_queue = NULL; -+ unsigned char *p_rx_queue = NULL; -+ -+ BTIF_DBG_FUNC("++\n"); -+ -+/*Platform Driver initialization*/ -+ i_ret = platform_driver_register(&mtk_btif_dev_drv); -+ if (i_ret) { -+ BTIF_ERR_FUNC("BTIF platform driver registered failed, ret(%d)\n", i_ret); -+ goto err_exit1; -+ } -+ -+ i_ret = driver_create_file(&mtk_btif_dev_drv.driver, &driver_attr_flag); -+ if (i_ret) -+ BTIF_ERR_FUNC("BTIF pdriver_create_file failed, ret(%d)\n", i_ret); -+ -+/*SW init*/ -+ for (index = 0; index < BTIF_PORT_NR; index++) { -+ p_btif_buffer = kmalloc(BTIF_RX_BUFFER_SIZE, GFP_ATOMIC); -+ if (!p_btif_buffer) { -+ BTIF_ERR_FUNC("p_btif_buffer kmalloc memory fail\n"); -+ return -1; -+ } -+ BTIF_INFO_FUNC("p_btif_buffer get memory 0x%p\n", p_btif_buffer); -+ p_tx_queue = kmalloc_array(BTIF_LOG_ENTRY_NUM, sizeof(BTIF_LOG_BUF_T), GFP_ATOMIC); -+ if (!p_tx_queue) { -+ BTIF_ERR_FUNC("p_tx_queue kmalloc memory fail\n"); -+ kfree(p_btif_buffer); -+ return -1; -+ } -+ BTIF_INFO_FUNC("p_tx_queue get memory 0x%p\n", p_tx_queue); -+ p_rx_queue = kmalloc_array(BTIF_LOG_ENTRY_NUM, sizeof(BTIF_LOG_BUF_T), GFP_ATOMIC); -+ if (!p_rx_queue) { -+ BTIF_ERR_FUNC("p_rx_queue kmalloc memory fail\n"); -+ kfree(p_btif_buffer); -+ kfree(p_tx_queue); -+ return -1; -+ } -+ BTIF_INFO_FUNC("p_rx_queue get memory 0x%p\n", p_rx_queue); -+ -+ INIT_LIST_HEAD(&(g_btif[index].user_list)); -+ BBS_INIT(&(g_btif[index].btif_buf)); -+ g_btif[index].enable = false; -+ g_btif[index].open_counter = 0; -+ g_btif[index].setting = &g_btif_setting[index]; -+ g_btif[index].p_btif_info = hal_btif_info_get(); -+ g_btif[index].tx_mode = g_btif_setting[index].tx_mode; -+ g_btif[index].rx_mode = g_btif_setting[index].rx_mode; -+ g_btif[index].btm_type = g_btif_setting[index].rx_type; -+ g_btif[index].tx_ctx = g_btif_setting[index].tx_type; -+ g_btif[index].lpbk_flag = false; -+ g_btif[index].rx_cb = NULL; -+ g_btif[index].rx_notify = NULL; -+ g_btif[index].btif_buf.p_buf = p_btif_buffer; -+ g_btif[index].tx_log.p_queue[0] = (P_BTIF_LOG_BUF_T) p_tx_queue; -+ g_btif[index].rx_log.p_queue[0] = (P_BTIF_LOG_BUF_T) p_rx_queue; -+ btif_log_buf_init(&g_btif[index]); -+ -+#if !(MTK_BTIF_ENABLE_CLK_REF_COUNTER) -+/*enable BTIF clock gating by default*/ -+ i_ret = hal_btif_clk_ctrl(g_btif[index].p_btif_info, -+ CLK_OUT_DISABLE); -+ if (i_ret != 0) { -+ BTIF_ERR_FUNC("BTIF controller CG failed\n"); -+ goto err_exit2; -+ } -+#endif -+ -+/* -+ * viftual FIFO memory must be physical continious, -+ * because DMA will access it directly without MMU -+ */ -+#if ENABLE_BTIF_TX_DMA -+ p_tx_dma = &g_dma[index][BTIF_TX]; -+ g_btif[index].p_tx_dma = p_tx_dma; -+ p_tx_dma->dir = BTIF_TX; -+ p_tx_dma->p_btif = &(g_btif[index]); -+ -+/*DMA Tx vFIFO initialization*/ -+ p_tx_dma->p_dma_info = hal_btif_dma_info_get(DMA_DIR_TX); -+/*spinlock init*/ -+ spin_lock_init(&(p_tx_dma->iolock)); -+/*entry setup*/ -+ atomic_set(&(p_tx_dma->entry), 0); -+/*vFIFO initialization*/ -+ i_ret = _btif_vfifo_init(p_tx_dma); -+ if (i_ret != 0) { -+ BTIF_ERR_FUNC("BTIF Tx vFIFO allocation failed\n"); -+ goto err_exit2; -+ } -+ -+#if !(MTK_BTIF_ENABLE_CLK_REF_COUNTER) -+/*enable BTIF Tx DMA channel's clock gating by default*/ -+ i_ret = hal_btif_dma_clk_ctrl(p_tx_dma->p_dma_info, -+ CLK_OUT_DISABLE); -+ if (i_ret != 0) { -+ BTIF_ERR_FUNC("BTIF Tx DMA's CG failed\n"); -+ goto err_exit2; -+ } -+#endif -+ -+#else -+ g_btif[index].p_tx_dma = NULL; -+/*force tx mode to DMA no matter what it is in default setting*/ -+ g_btif[index].tx_mode = BTIF_MODE_PIO; -+#endif -+ -+#if ENABLE_BTIF_RX_DMA -+ p_rx_dma = &g_dma[index][BTIF_RX]; -+ g_btif[index].p_rx_dma = p_rx_dma; -+ p_rx_dma->p_btif = &(g_btif[index]); -+ p_rx_dma->dir = BTIF_RX; -+ -+/*DMA Tx vFIFO initialization*/ -+ p_rx_dma->p_dma_info = hal_btif_dma_info_get(DMA_DIR_RX); -+/*spinlock init*/ -+ spin_lock_init(&(p_rx_dma->iolock)); -+/*entry setup*/ -+ atomic_set(&(p_rx_dma->entry), 0); -+/*vFIFO initialization*/ -+ i_ret = _btif_vfifo_init(p_rx_dma); -+ if (i_ret != 0) { -+ BTIF_ERR_FUNC("BTIF Rx vFIFO allocation failed\n"); -+ goto err_exit2; -+ } -+ -+#if !(MTK_BTIF_ENABLE_CLK_REF_COUNTER) -+/*enable BTIF Tx DMA channel's clock gating by default*/ -+ i_ret = hal_btif_dma_clk_ctrl(p_rx_dma->p_dma_info, -+ CLK_OUT_DISABLE); -+ if (i_ret != 0) { -+ BTIF_ERR_FUNC("BTIF Rx DMA's CG failed\n"); -+ goto err_exit2; -+ } -+#endif -+ -+#else -+ g_btif[index].p_rx_dma = NULL; -+/*force rx mode to DMA no matter what it is in default setting*/ -+ g_btif[index].rx_mode = BTIF_MODE_PIO; -+ -+#endif -+/*PM state mechine initialization*/ -+ i_ret = _btif_state_init(&(g_btif[index])); -+ if (i_ret != 0) { -+ BTIF_ERR_FUNC("BTIF state mechanism init failed\n"); -+ goto err_exit2; -+ } -+ -+/*Rx bottom half initialization*/ -+ i_ret = _btif_rx_btm_init(&(g_btif[index])); -+ if (i_ret != 0) { -+ BTIF_ERR_FUNC("BTIF Rx btm init failed\n"); -+ goto err_exit3; -+ } -+ i_ret = _btif_tx_ctx_init(&(g_btif[index])); -+ if (i_ret != 0) { -+ BTIF_ERR_FUNC("BTIF Tx context init failed\n"); -+ goto err_exit4; -+ } -+/*Character Device initialization*/ -+/*Chaozhong: ToDo: to be initialized*/ -+ -+ mutex_init(&g_btif[index].ops_mtx); -+ } -+ -+/*Debug purpose initialization*/ -+ -+#if BTIF_CDEV_SUPPORT -+ btif_chrdev_init(); -+#endif -+ -+ return 0; -+ -+err_exit4: -+ for (index = 0; index < BTIF_PORT_NR; index++) -+ _btif_tx_ctx_deinit(&(g_btif[index])); -+ -+err_exit3: -+ for (index = 0; index < BTIF_PORT_NR; index++) { -+ _btif_rx_btm_deinit(&(g_btif[index])); -+ -+ _btif_state_deinit(&(g_btif[index])); -+ } -+ -+err_exit2: -+ for (index = 0; index < BTIF_PORT_NR; index++) { -+ p_tx_dma = &g_dma[index][BTIF_TX]; -+ p_rx_dma = &g_dma[index][BTIF_RX]; -+#if ENABLE_BTIF_TX_DMA -+ _btif_vfifo_deinit(p_tx_dma); -+#endif -+ -+#if ENABLE_BTIF_RX_DMA -+ _btif_vfifo_deinit(p_rx_dma); -+#endif -+ g_btif[index].open_counter = 0; -+ g_btif[index].enable = false; -+ } -+ driver_remove_file(&mtk_btif_dev_drv.driver, &driver_attr_flag); -+ platform_driver_unregister(&mtk_btif_dev_drv); -+ -+err_exit1: -+ i_ret = -1; -+ BTIF_DBG_FUNC("--\n"); -+ return i_ret; -+} -+ -+static void BTIF_exit(void) -+{ -+ unsigned int index = 0; -+ p_mtk_btif_dma p_tx_dma = NULL; -+ p_mtk_btif_dma p_rx_dma = NULL; -+ -+ BTIF_DBG_FUNC("++\n"); -+ -+ for (index = 0; index < BTIF_PORT_NR; index++) { -+ g_btif[index].open_counter = 0; -+ g_btif[index].enable = false; -+ p_tx_dma = &g_dma[index][BTIF_TX]; -+ p_rx_dma = &g_dma[index][BTIF_RX]; -+#if ENABLE_BTIF_TX_DMA -+ _btif_vfifo_deinit(p_tx_dma); -+#endif -+ -+#if ENABLE_BTIF_RX_DMA -+ _btif_vfifo_deinit(p_rx_dma); -+#endif -+ _btif_state_deinit(&(g_btif[index])); -+ -+ _btif_rx_btm_deinit(&(g_btif[index])); -+ -+ mutex_destroy(&g_btif[index].ops_mtx); -+ } -+ -+#if !defined(CONFIG_MTK_CLKMGR) -+ hal_btif_clk_unprepare(); -+#endif -+ -+ driver_remove_file(&mtk_btif_dev_drv.driver, &driver_attr_flag); -+ platform_driver_unregister(&mtk_btif_dev_drv); -+ BTIF_DBG_FUNC("--\n"); -+} -+ -+int mtk_btif_hal_get_log_lvl(void) -+{ -+ return mtk_btif_dbg_lvl; -+} -+ -+void mtk_btif_read_cpu_sw_rst_debug(void) -+{ -+ mtk_btif_read_cpu_sw_rst_debug_plat(); -+} -+ -+/*---------------------------------------------------------------------------*/ -+ -+module_init(BTIF_init); -+module_exit(BTIF_exit); -+ -+/*---------------------------------------------------------------------------*/ -+ -+MODULE_AUTHOR("MBJ/WCN/SE/SS1/Chaozhong.Liang"); -+MODULE_DESCRIPTION("MTK BTIF Driver$1.0$"); -+MODULE_LICENSE("GPL"); -+ -+/*---------------------------------------------------------------------------*/ -diff --git a/drivers/misc/mediatek/btif/common/mtk_btif_exp.c b/drivers/misc/mediatek/btif/common/mtk_btif_exp.c -new file mode 100644 -index 000000000000..c0df44558357 ---- /dev/null -+++ b/drivers/misc/mediatek/btif/common/mtk_btif_exp.c -@@ -0,0 +1,786 @@ -+/* -+ * Copyright (C) 2015 MediaTek Inc. -+ * -+ * 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. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#ifdef DFT_TAG -+#undef DFT_TAG -+#endif -+#define DFT_TAG "MTK-BTIF-EXP" -+ -+/*#include "mtk_btif_exp.h"*/ -+#include "mtk_btif.h" -+ -+/*---------------------------------Function----------------------------------*/ -+ -+p_mtk_btif btif_exp_srh_id(unsigned long u_id) -+{ -+ int index = 0; -+ p_mtk_btif p_btif = NULL; -+ struct list_head *p_list = NULL; -+ struct list_head *tmp = NULL; -+ p_mtk_btif_user p_user = NULL; -+ -+ for (index = 0; (index < BTIF_PORT_NR) && (p_btif == NULL); index++) { -+ p_list = &(g_btif[index].user_list); -+ list_for_each(tmp, p_list) { -+ p_user = container_of(tmp, mtk_btif_user, entry); -+ if (u_id == p_user->u_id) { -+ p_btif = p_user->p_btif; -+ BTIF_DBG_FUNC -+ ("BTIF's user id(0x%p), p_btif(0x%p)\n", -+ p_user->u_id, p_btif); -+ break; -+ } -+ } -+ } -+ if (p_btif == NULL) { -+ BTIF_INFO_FUNC -+ ("no btif structure found for BTIF's user id(0x%lx)\n", -+ u_id); -+ } -+ return p_btif; -+} -+ -+/*-----Normal Mode API declearation-------*/ -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_btif_open -+* DESCRIPTION -+* open BTIF interface, will do BTIF module HW and SW initialization -+* PARAMETERS -+* p_owner [IN] pointer to owner who call this API, -+* currently there are 2 owner ("stp" or "btif_tester") -+* may use this module -+* for "stp", BTIF will call rx callback function to route rx data to STP module -+* for "stp_tester", BTIF will save rx data and wait for native process to access -+* p_id [IN] BTIF's user id will be put to this address -+* RETURNS -+* int 0 = BTIF module initialization fail; negative = BTIF module initialization success -+* if open success, value p_id will be the only identifier -+* for user to access BTIF's other operations -+* including read/write/dpidle_ctrl/rx_cb_retister -+* this user id is only an identifier used for owner identification -+*****************************************************************************/ -+int mtk_wcn_btif_open(char *p_owner, unsigned long *p_id) -+{ -+ int i_ret = -1; -+ unsigned int index = 0; -+ p_mtk_btif_user p_new_user = NULL; -+ p_mtk_btif p_btif = &g_btif[index]; -+ struct list_head *p_user_list = &(p_btif->user_list); -+ -+ BTIF_DBG_FUNC("++"); -+ BTIF_DBG_FUNC("p_btif(0x%p)\n", p_btif); -+ -+ if (mutex_lock_killable(&(p_btif->ops_mtx))) { -+ BTIF_ERR_FUNC("mutex_lock_killable return failed\n"); -+ return E_BTIF_INTR; -+ } -+ if ((p_owner == NULL) || (p_id == NULL)) { -+ if (p_id) -+ *p_id = 0; -+ BTIF_ERR_FUNC("parameter invalid, p_owner(0x%p), p_id(0x%p)\n", -+ p_owner, p_id); -+ BTIF_MUTEX_UNLOCK(&(p_btif->ops_mtx)); -+ return E_BTIF_INVAL_PARAM; -+ } -+ -+/*check if btif is already opened or not, if yes, just return fail*/ -+ if (!list_empty(p_user_list)) { -+ struct list_head *pos; -+ p_mtk_btif_user p_user; -+ -+ BTIF_ERR_FUNC("BTIF's user list is not empty\n"); -+ list_for_each(pos, p_user_list) { -+ p_user = container_of(pos, mtk_btif_user, entry); -+ BTIF_INFO_FUNC("BTIF's user id(0x%lx), name(%s)\n", -+ p_user->u_id, p_user->u_name); -+ } -+/*leave p_id alone*/ -+ BTIF_MUTEX_UNLOCK(&(p_btif->ops_mtx)); -+ return E_BTIF_ALREADY_OPEN; -+ } -+ p_new_user = vmalloc(sizeof(mtk_btif_user)); -+ -+ if (p_new_user != NULL) { -+ INIT_LIST_HEAD(&(p_new_user->entry)); -+ p_new_user->enable = false; -+ p_new_user->p_btif = p_btif; -+ p_new_user->u_id = (unsigned long)p_new_user; -+ strncpy(p_new_user->u_name, p_owner, sizeof(p_new_user->u_name) - 1); -+ p_new_user->u_name[sizeof(p_new_user->u_name) - 1] = '\0'; -+ BTIF_DBG_FUNC("owner name:%s, recorded name:%s\n", -+ p_owner, p_new_user->u_name); -+ -+ i_ret = btif_open(p_btif); -+ if (i_ret) { -+ BTIF_ERR_FUNC("btif_open failed, i_ret(%d)\n", i_ret); -+ *p_id = 0; -+/*free btif new user's structure*/ -+ vfree(p_new_user); -+ p_new_user = NULL; -+ } else { -+ BTIF_INFO_FUNC("btif_open succeed\n"); -+ *p_id = p_new_user->u_id; -+/*mark enable flag to true*/ -+ p_new_user->enable = true; -+/*add to uer lsit*/ -+ list_add_tail(&(p_new_user->entry), p_user_list); -+ } -+ } else { -+ *p_id = 0; -+ i_ret = -ENOMEM; -+ BTIF_ERR_FUNC("allocate memory for mtk_btif_user failed\n"); -+ } -+ BTIF_MUTEX_UNLOCK(&(p_btif->ops_mtx)); -+ BTIF_DBG_FUNC("--"); -+ return i_ret; -+} -+EXPORT_SYMBOL(mtk_wcn_btif_open); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_btif_close -+* DESCRIPTION -+* close BTIF interface, will do BTIF module HW and SW de-initialization -+* once this API is called, p_btif should never be used by BTIF's user again -+* PARAMETERS -+* u_id [IN] BTIF's user id -+* RETURNS -+* int 0 = succeed; -+* others = fail, -+* for detailed information, please see ENUM_BTIF_OP_ERROR_CODE -+*****************************************************************************/ -+int mtk_wcn_btif_close(unsigned long u_id) -+{ -+ int i_ret = -1; -+ p_mtk_btif p_btif = NULL; -+ struct list_head *pos = NULL; -+ struct list_head *p_user_list = NULL; -+ -+ BTIF_DBG_FUNC("++"); -+ p_btif = btif_exp_srh_id(u_id); -+ -+ if (p_btif == NULL) -+ return E_BTIF_INVAL_PARAM; -+ -+ if (mutex_lock_killable(&(p_btif->ops_mtx))) { -+ BTIF_ERR_FUNC("mutex_lock_killable return failed\n"); -+ return E_BTIF_INTR; -+ } -+ p_user_list = &(p_btif->user_list); -+ list_for_each(pos, p_user_list) { -+ p_mtk_btif_user p_user = -+ container_of(pos, mtk_btif_user, entry); -+ -+ if (p_user->u_id == u_id) { -+ BTIF_INFO_FUNC -+ ("user who's id is 0x%lx deleted from user list\n", -+ u_id); -+ list_del(pos); -+ vfree(p_user); -+ i_ret = btif_close(p_btif); -+ if (i_ret) -+ BTIF_WARN_FUNC("BTIF close failed"); -+ break; -+ } -+ } -+ BTIF_MUTEX_UNLOCK(&(p_btif->ops_mtx)); -+ BTIF_DBG_FUNC("--"); -+ return 0; -+} -+EXPORT_SYMBOL(mtk_wcn_btif_close); -+ -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_btif_write -+* DESCRIPTION -+* send data throuth BTIF module -+* there's no internal buffer to cache STP data in BTIF driver, -+* if in DMA mode -+* btif driver will check if there's enough space in vFIFO for data to send in DMA mode -+* if yes, put data to vFIFO and return corresponding data length to caller -+* if no, corresponding error code will be returned to called -+* PARAMETERS -+* p_btif [IN] pointer returned by mtk_wcn_btif_open -+* p_buf [IN] pointer to target data to send -+* len [IN] data length (should be less than 2014 bytes per STP package) -+* -+* if in non-DMA mode, BTIF driver will try to write to THR of BTIF controller -+* if btif driver detected that no space is available in Tx FIFO, -+* will return E_BTIF_NO_SPACE, mostly something is wrong with BTIF or -+* consys when this return value is returned -+* RETURNS -+* int positive: data length send through BTIF; -+* negative: please see ENUM_BTIF_OP_ERROR_CODE -+* E_BTIF_AGAIN (0) will be returned to caller -+* if btif does not have enough vFIFO to send data, -+* when caller get 0, he should wait for a moment -+* (5~10ms maybe) and try a few times (maybe 10~20) -+* if still get E_BTIF_AGAIN, -+* should call BTIF's debug API and dump BTIF driver -+* and BTIF/DMA register information to kernel log for debug -+* E_BTIF_BAD_POINTER will be returned to caller -+* if btif is not opened successfully before call this API -+* E_BTIF_INVAL_PARAM will be returned if parameter is not valid -+ -+*****************************************************************************/ -+int mtk_wcn_btif_write(unsigned long u_id, -+ const unsigned char *p_buf, unsigned int len) -+{ -+ int i_ret = -1; -+ p_mtk_btif p_btif = NULL; -+ -+ BTIF_DBG_FUNC("++"); -+ p_btif = btif_exp_srh_id(u_id); -+ -+ if (p_btif == NULL) -+ return E_BTIF_INVAL_PARAM; -+ if (p_buf == NULL) { -+ BTIF_ERR_FUNC("invalid p_buf (0x%p)\n", p_buf); -+ return E_BTIF_INVAL_PARAM; -+ } -+ if ((len == 0) || (len > BTIF_MAX_LEN_PER_PKT)) { -+ BTIF_ERR_FUNC("invalid buffer length(%d)\n", len); -+ return E_BTIF_INVAL_PARAM; -+ } -+ -+ i_ret = btif_send_data(p_btif, p_buf, len); -+ BTIF_DBG_FUNC("--, i_ret:%d\n", i_ret); -+ return i_ret; -+} -+EXPORT_SYMBOL(mtk_wcn_btif_write); -+ -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_btif_read -+* DESCRIPTION -+* read data from BTIF module -+* PARAMETERS -+* p_btif [IN] pointer returned by mtk_wcn_btif_open -+* p_buf [IN/OUT] pointer to buffer where rx data will be put -+* max_len [IN] max buffer length -+* RETURNS -+* int positive: data length read from BTIF; -+* negative: please see ENUM_BTIF_OP_ERROR_CODE -+*****************************************************************************/ -+int mtk_wcn_btif_read(unsigned long u_id, -+ unsigned char *p_buf, unsigned int max_len) -+{ -+ return 0; -+} -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_btif_dpidle_ctrl -+* DESCRIPTION -+* control if BTIF module allow system enter deepidle state or not -+* PARAMETERS -+* p_btif [IN] pointer returned by mtk_wcn_btif_open -+* en_flag [IN] one of ENUM_BTIF_DPIDLE_CTRL -+* RETURNS -+* int always return 0 -+*****************************************************************************/ -+int mtk_wcn_btif_dpidle_ctrl(unsigned long u_id, ENUM_BTIF_DPIDLE_CTRL en_flag) -+{ -+ int i_ret = -1; -+ p_mtk_btif p_btif = NULL; -+ -+ p_btif = btif_exp_srh_id(u_id); -+ -+ if (p_btif == NULL) -+ return E_BTIF_INVAL_PARAM; -+ -+ if (en_flag == BTIF_DPIDLE_DISABLE) -+ i_ret = btif_exit_dpidle(p_btif); -+ else -+ i_ret = btif_enter_dpidle(p_btif); -+ -+ return i_ret; -+} -+EXPORT_SYMBOL(mtk_wcn_btif_dpidle_ctrl); -+ -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_btif_rx_cb_register -+* DESCRIPTION -+* register rx callback function to BTIF module by btif user -+* PARAMETERS -+* p_btif [IN] pointer returned by mtk_wcn_btif_open -+* rx_cb [IN] pointer to stp rx handler callback function, -+* should be comply with MTK_WCN_BTIF_RX_CB -+* RETURNS -+* int 0 = succeed; -+* others = fail, for detailed information, -+* please see ENUM_BTIF_OP_ERROR_CODE -+*****************************************************************************/ -+int mtk_wcn_btif_rx_cb_register(unsigned long u_id, MTK_WCN_BTIF_RX_CB rx_cb) -+{ -+ int i_ret = -1; -+ p_mtk_btif p_btif = NULL; -+ -+ p_btif = btif_exp_srh_id(u_id); -+ -+ if (p_btif == NULL) -+ return E_BTIF_INVAL_PARAM; -+ -+ i_ret = btif_rx_cb_reg(p_btif, rx_cb); -+ -+ return i_ret; -+} -+EXPORT_SYMBOL(mtk_wcn_btif_rx_cb_register); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_btif_wakeup_consys -+* DESCRIPTION -+* once sleep command is sent to con sys, -+* should call this API before send wakeup command -+* to make con sys aware host want to send data to consys -+* PARAMETERS -+* p_btif [IN] pointer returned by mtk_wcn_btif_open -+* RETURNS -+* int 0 = succeed; others = fail, for detailed information, please see ENUM_BTIF_OP_ERROR_CODE -+*****************************************************************************/ -+int mtk_wcn_btif_wakeup_consys(unsigned long u_id) -+{ -+ int i_ret = -1; -+ p_mtk_btif p_btif = NULL; -+ -+ p_btif = btif_exp_srh_id(u_id); -+ -+ if (p_btif == NULL) -+ return E_BTIF_INVAL_PARAM; -+ -+/*i_ret = hal_btif_raise_wak_sig(p_btif->p_btif_info);*/ -+ i_ret = btif_raise_wak_signal(p_btif); -+ -+ return i_ret; -+} -+EXPORT_SYMBOL(mtk_wcn_btif_wakeup_consys); -+ -+ -+/***************End of Normal Mode API declearation**********/ -+ -+/***************Debug Purpose API declearation**********/ -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_btif_loopback_ctrl -+* DESCRIPTION -+* enable/disable BTIF internal loopback function, -+* when this function is enabled data send to btif -+* will be received by btif itself -+* only for debug purpose, should never use this function in normal mode -+* PARAMETERS -+* p_btif [IN] pointer returned by mtk_wcn_btif_open -+* enable [IN] loopback mode control flag, enable or disable, -+* shou be one of ENUM_BTIF_LPBK_MODE -+* RETURNS -+* int 0 = succeed; -+* others = fail, for detailed information, please see ENUM_BTIF_OP_ERROR_CODE -+*****************************************************************************/ -+int mtk_wcn_btif_loopback_ctrl(unsigned long u_id, ENUM_BTIF_LPBK_MODE enable) -+{ -+ int i_ret = -1; -+ p_mtk_btif p_btif = NULL; -+ -+ p_btif = btif_exp_srh_id(u_id); -+ -+ if (p_btif == NULL) -+ return E_BTIF_INVAL_PARAM; -+ i_ret = -+ btif_lpbk_ctrl(p_btif, enable == BTIF_LPBK_ENABLE ? true : false); -+ -+ return i_ret; -+} -+EXPORT_SYMBOL(mtk_wcn_btif_loopback_ctrl); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_btif_logger_ctrl -+* DESCRIPTION -+* control BTIF logger function's behavior -+* PARAMETERS -+* p_btif [IN] pointer returned by mtk_wcn_btif_open -+* flag [IN] should be one of ENUM_BTIF_DBG_ID -+* BTIF_DISABLE_LOGGER - disable btif logger -+* BTIF_ENABLE_LOGGER - enable btif logger -+* BTIF_DUMP_LOG - dump log logged by btif -+* BTIF_CLR_LOG - clear btif log buffer -+* BTIF_DUMP_BTIF_REG - dump btif controller's register -+* BTIF_DUMP_DMA_REG - dump DMA controller's register -+* RETURNS -+* int 0 = succeed; others = fail, for detailed information, please see ENUM_BTIF_OP_ERROR_CODE -+*****************************************************************************/ -+int mtk_wcn_btif_dbg_ctrl(unsigned long u_id, ENUM_BTIF_DBG_ID flag) -+{ -+ int i_ret = -1; -+ p_mtk_btif p_btif = NULL; -+ -+ p_btif = btif_exp_srh_id(u_id); -+ -+ if (p_btif == NULL) -+ return E_BTIF_INVAL_PARAM; -+ -+ i_ret = 0; -+ switch (flag) { -+ case BTIF_DISABLE_LOGGER:{ -+ BTIF_INFO_FUNC -+ ("disable btif log function for both Tx and Rx\n"); -+ btif_log_buf_disable(&p_btif->tx_log); -+ btif_log_buf_disable(&p_btif->rx_log); -+ } -+ break; -+ case BTIF_ENABLE_LOGGER:{ -+ BTIF_INFO_FUNC -+ ("enable btif log function for both Tx and Rx\n"); -+ btif_log_buf_enable(&p_btif->tx_log); -+ btif_log_buf_enable(&p_btif->rx_log); -+ } -+ break; -+ case BTIF_DUMP_LOG:{ -+ BTIF_INFO_FUNC("dump btif log for both Tx and Rx\n"); -+ btif_log_buf_dmp_out(&p_btif->tx_log); -+ btif_log_buf_dmp_out(&p_btif->rx_log); -+ } -+ break; -+ -+ case BTIF_CLR_LOG:{ -+ BTIF_INFO_FUNC("clear btif log for both Tx and Rx\n"); -+ btif_log_buf_reset(&p_btif->tx_log); -+ btif_log_buf_reset(&p_btif->rx_log); -+ } -+ break; -+ case BTIF_DUMP_BTIF_REG: -+ /*TBD*/ btif_dump_reg(p_btif); -+ break; -+ case BTIF_ENABLE_RT_LOG: -+ BTIF_INFO_FUNC -+ ("enable btif real time log for both Tx and Rx\n"); -+ btif_log_output_enable(&p_btif->tx_log); -+ btif_log_output_enable(&p_btif->rx_log); -+ break; -+ case BTIF_DISABLE_RT_LOG: -+ BTIF_INFO_FUNC -+ ("disable btif real time log for both Tx and Rx\n"); -+ btif_log_output_disable(&p_btif->tx_log); -+ btif_log_output_disable(&p_btif->rx_log); -+ break; -+ default: -+ BTIF_INFO_FUNC("not supported flag:%d\n", flag); -+ i_ret = -2; -+ break; -+ } -+ -+ return i_ret; -+} -+EXPORT_SYMBOL(mtk_wcn_btif_dbg_ctrl); -+ -+bool mtk_wcn_btif_parser_wmt_evt(unsigned long u_id, -+ const char *sub_str, unsigned int str_len) -+{ -+ bool b_ret = false; -+ p_mtk_btif p_btif = NULL; -+ -+ p_btif = btif_exp_srh_id(u_id); -+ -+ if (p_btif == NULL) -+ return E_BTIF_INVAL_PARAM; -+ b_ret = btif_parser_wmt_evt(p_btif, sub_str, str_len); -+ BTIF_INFO_FUNC("parser wmt evt %s\n", b_ret ? "ok" : "fail"); -+ -+ return b_ret; -+} -+ -+/**********End of Debug Purpose API declearation**********/ -+ -+int btif_open_no_id(void) -+{ -+ int i_ret = 0; -+ p_mtk_btif p_btif = &g_btif[0]; -+ -+ i_ret = btif_open(p_btif); -+ -+ if (i_ret) -+ BTIF_ERR_FUNC("btif_open failed, i_ret(%d)\n", i_ret); -+ else -+ BTIF_INFO_FUNC("btif_open succeed\n"); -+ -+ return i_ret; -+} -+ -+int btif_close_no_id(void) -+{ -+ int i_ret = 0; -+ p_mtk_btif p_btif = &g_btif[0]; -+ -+ i_ret = btif_close(p_btif); -+ -+ if (i_ret) -+ BTIF_ERR_FUNC("btif_close failed, i_ret(%d)\n", i_ret); -+ else -+ BTIF_INFO_FUNC("btif_close succeed\n"); -+ return i_ret; -+} -+ -+int btif_write_no_id(const unsigned char *p_buf, unsigned int len) -+{ -+ int i_ret = -1; -+ p_mtk_btif p_btif = &g_btif[0]; -+ -+ BTIF_DBG_FUNC("++"); -+ -+ if (p_buf == NULL) { -+ BTIF_ERR_FUNC("invalid p_buf (0x%p)\n", p_buf); -+ return E_BTIF_INVAL_PARAM; -+ } -+ if ((len == 0) || (len > BTIF_MAX_LEN_PER_PKT)) { -+ BTIF_ERR_FUNC("invalid buffer length(%d)\n", len); -+ return E_BTIF_INVAL_PARAM; -+ } -+ -+ i_ret = btif_send_data(p_btif, p_buf, len); -+ BTIF_DBG_FUNC("--, i_ret:%d\n", i_ret); -+ return i_ret; -+} -+ -+int btif_dpidle_ctrl_no_id(ENUM_BTIF_DPIDLE_CTRL en_flag) -+{ -+ int i_ret = -1; -+ p_mtk_btif p_btif = &g_btif[0]; -+ -+ if (en_flag == BTIF_DPIDLE_DISABLE) -+ i_ret = btif_exit_dpidle(p_btif); -+ else -+ i_ret = btif_enter_dpidle(p_btif); -+ -+ return i_ret; -+} -+ -+int btif_wakeup_consys_no_id(void) -+{ -+ int i_ret = -1; -+ p_mtk_btif p_btif = &g_btif[0]; -+ -+/*i_ret = hal_btif_raise_wak_sig(p_btif->p_btif_info);*/ -+ i_ret = btif_raise_wak_signal(p_btif); -+ -+ return i_ret; -+} -+ -+int btif_loopback_ctrl_no_id(ENUM_BTIF_LPBK_MODE enable) -+{ -+ int i_ret = -1; -+ p_mtk_btif p_btif = &g_btif[0]; -+ -+ i_ret = -+ btif_lpbk_ctrl(p_btif, enable == BTIF_LPBK_ENABLE ? true : false); -+ -+ return i_ret; -+} -+ -+int btif_dbg_ctrl_no_id(ENUM_BTIF_DBG_ID flag) -+{ -+ int i_ret = -1; -+ p_mtk_btif p_btif = &g_btif[0]; -+ -+ i_ret = 0; -+ switch (flag) { -+ case BTIF_DISABLE_LOGGER:{ -+ BTIF_INFO_FUNC -+ ("disable btif log function for both Tx and Rx\n"); -+ btif_log_buf_disable(&p_btif->tx_log); -+ btif_log_buf_disable(&p_btif->rx_log); -+ } -+ break; -+ case BTIF_ENABLE_LOGGER:{ -+ BTIF_INFO_FUNC -+ ("enable btif log function for both Tx and Rx\n"); -+ btif_log_buf_enable(&p_btif->tx_log); -+ btif_log_buf_enable(&p_btif->rx_log); -+ } -+ break; -+ case BTIF_DUMP_LOG:{ -+ BTIF_INFO_FUNC("dump btif log for both Tx and Rx\n"); -+ btif_log_buf_dmp_out(&p_btif->tx_log); -+ btif_log_buf_dmp_out(&p_btif->rx_log); -+ } -+ break; -+ -+ case BTIF_CLR_LOG:{ -+ BTIF_INFO_FUNC("clear btif log for both Tx and Rx\n"); -+ btif_log_buf_reset(&p_btif->tx_log); -+ btif_log_buf_reset(&p_btif->rx_log); -+ } -+ break; -+ case BTIF_DUMP_BTIF_REG: -+ /*TBD*/ btif_dump_reg(p_btif); -+ break; -+ case BTIF_ENABLE_RT_LOG: -+ BTIF_INFO_FUNC -+ ("enable btif real time log for both Tx and Rx\n"); -+ btif_log_output_enable(&p_btif->tx_log); -+ btif_log_output_enable(&p_btif->rx_log); -+ break; -+ case BTIF_DISABLE_RT_LOG: -+ BTIF_INFO_FUNC -+ ("disable btif real time log for both Tx and Rx\n"); -+ btif_log_output_disable(&p_btif->tx_log); -+ btif_log_output_disable(&p_btif->rx_log); -+ break; -+ default: -+ BTIF_INFO_FUNC("not supported flag:%d\n", flag); -+ i_ret = -2; -+ break; -+ } -+ -+ return i_ret; -+} -+ -+int mtk_btif_exp_open_test(void) -+{ -+ int i_ret = 0; -+ -+ i_ret = btif_open_no_id(); -+ if (i_ret < 0) { -+ BTIF_INFO_FUNC("mtk_wcn_btif_open failed\n"); -+ return -1; -+ } -+ -+ BTIF_INFO_FUNC("mtk_wcn_btif_open succeed\n"); -+ -+ return i_ret; -+} -+ -+int mtk_btif_exp_close_test(void) -+{ -+ int i_ret = 0; -+ -+ i_ret = btif_close_no_id(); -+ if (i_ret < 0) { -+ BTIF_INFO_FUNC("mtk_wcn_btif_close failed\n"); -+ return -1; -+ } -+ -+ BTIF_INFO_FUNC("mtk_wcn_btif_close succeed\n"); -+ -+ return i_ret; -+} -+ -+int mtk_btif_exp_write_test(void) -+{ -+ return mtk_btif_exp_write_stress_test(100, 10); -+} -+ -+int mtk_btif_exp_write_stress_test(unsigned int length, unsigned int max_loop) -+{ -+#define BUF_LEN 1024 -+ int i_ret = 0; -+ int idx = 0; -+ int buf_len = length > BUF_LEN ? BUF_LEN : length; -+ int loop = max_loop > 1000000 ? 1000000 : max_loop; -+ unsigned char *buffer; -+ -+ buffer = kmalloc(BUF_LEN, GFP_KERNEL); -+ if (!buffer) { -+ BTIF_ERR_FUNC("btif tester kmalloc failed\n"); -+ return -1; -+ } -+ -+ for (idx = 0; idx < buf_len; idx++) -+ /* btif_stress_test_buf[idx] = BUF_LEN -idx; */ -+ *(buffer + idx) = idx % 255; -+ i_ret = btif_loopback_ctrl_no_id(BTIF_LPBK_ENABLE); -+ BTIF_INFO_FUNC("mtk_wcn_btif_loopback_ctrl returned %d\n", i_ret); -+ while (loop--) { -+ i_ret = btif_write_no_id(buffer, buf_len); -+ BTIF_INFO_FUNC("mtk_wcn_btif_write left loop:%d, i_ret:%d\n", -+ loop, i_ret); -+ if (i_ret != buf_len) { -+ BTIF_INFO_FUNC -+ ("mtk_wcn_btif_write failed, target len %d, sent len: %d\n", -+ buf_len, i_ret); -+ break; -+ } -+ buf_len--; -+ if (buf_len <= 0) -+ buf_len = length > BUF_LEN ? BUF_LEN : length; -+ } -+ kfree(buffer); -+ return i_ret; -+} -+ -+int mtk_btif_exp_suspend_test(void) -+{ -+ int i_ret = 0; -+ p_mtk_btif p_btif = &g_btif[0]; -+ -+ i_ret = _btif_suspend(p_btif); -+ return i_ret; -+} -+ -+int mtk_btif_exp_restore_noirq_test(void) -+{ -+ int i_ret = 0; -+ p_mtk_btif p_btif = &g_btif[0]; -+ -+ i_ret = _btif_restore_noirq(p_btif); -+ return i_ret; -+} -+ -+int mtk_btif_exp_clock_ctrl(int en) -+{ -+ int i_ret = 0; -+ p_mtk_btif p_btif = &g_btif[0]; -+ -+ i_ret = btif_clock_ctrl(p_btif, en); -+ return i_ret; -+} -+ -+int mtk_btif_exp_resume_test(void) -+{ -+ int i_ret = 0; -+ p_mtk_btif p_btif = &g_btif[0]; -+ -+ i_ret = _btif_resume(p_btif); -+ return i_ret; -+} -+ -+int mtk_btif_exp_enter_dpidle_test(void) -+{ -+ return btif_dpidle_ctrl_no_id(BTIF_DPIDLE_ENABLE); -+} -+ -+int mtk_btif_exp_exit_dpidle_test(void) -+{ -+ return btif_dpidle_ctrl_no_id(BTIF_DPIDLE_DISABLE); -+} -+ -+int mtk_btif_exp_log_debug_test(int flag) -+{ -+ int i_ret = 0; -+ -+ i_ret = btif_dbg_ctrl_no_id(flag); -+ return i_ret; -+} -+ -+void mtk_btif_read_cpu_sw_rst_debug_exp(void) -+{ -+ mtk_btif_read_cpu_sw_rst_debug(); -+} -+ -+/************End of Function**********/ -diff --git a/drivers/misc/mediatek/btif/common/plat_inc/btif_dma_priv.h b/drivers/misc/mediatek/btif/common/plat_inc/btif_dma_priv.h -new file mode 100644 -index 000000000000..97756f684ab4 ---- /dev/null -+++ b/drivers/misc/mediatek/btif/common/plat_inc/btif_dma_priv.h -@@ -0,0 +1,164 @@ -+/* -+ * Copyright (C) 2015 MediaTek Inc. -+ * -+ * 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. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#ifndef __HAL_BTIF_DMA_H_ -+#define __HAL_BTIF_DMA_H_ -+ -+#include -+#include "btif_dma_pub.h" -+ -+#if defined(CONFIG_MTK_CLKMGR) -+#if defined(CONFIG_ARCH_MT6580) -+#define MTK_BTIF_APDMA_CLK_CG MT_CG_APDMA_SW_CG -+#elif defined(CONFIG_ARCH_MT6735) || defined(CONFIG_ARCH_MT6735M) || defined(CONFIG_ARCH_MT6753) -+#define MTK_BTIF_APDMA_CLK_CG MT_CG_PERI_APDMA -+#endif -+#else -+extern struct clk *clk_btif_apdma; /*btif apdma clock*/ -+#endif /* !defined(CONFIG_MTK_CLKMGR) */ -+ -+#define TX_DMA_VFF_SIZE (1024 * 8) /*Tx vFIFO Len must be 8 Byte allignment */ -+#define RX_DMA_VFF_SIZE (1024 * 8) /*Rx vFIFO Len must be 8 Byte allignment */ -+ -+#define DMA_TX_THRE(n) (n - 7) /*Tx Trigger Level */ -+#define DMA_RX_THRE(n) ((n) * 3 / 4) /*Rx Trigger Level */ -+ -+/**********************************Hardware related defination**************************/ -+#ifndef CONFIG_OF -+/*DMA channel's offset refer to AP_DMA's base address*/ -+#define BTIF_TX_DMA_OFFSET 0x880 -+#define BTIF_RX_DMA_OFFSET 0x900 -+#endif -+ -+/*Register Address Mapping*/ -+#define DMA_INT_FLAG_OFFSET 0x00 -+#define DMA_INT_EN_OFFSET 0x04 -+#define DMA_EN_OFFSET 0x08 -+#define DMA_RST_OFFSET 0x0C -+#define DMA_STOP_OFFSET 0x10 -+#define DMA_FLUSH_OFFSET 0x14 -+ -+#define DMA_BASE_OFFSET 0x1C -+#define DMA_LEN_OFFSET 0x24 -+ -+#define DMA_THRE_OFFSET 0x28 -+#define DMA_WPT_OFFSET 0x2C -+#define DMA_RPT_OFFSET 0x30 -+#define DMA_VALID_OFFSET 0x3C -+#define DMA_LEFT_OFFSET 0x40 -+#define DMA_VFF_BIT29_OFFSET 0x01 -+ -+#define TX_DMA_INT_FLAG(base) (unsigned long)(base + 0x0) /*BTIF Tx Virtual FIFO Interrupt Flag Register */ -+#define TX_DMA_INT_EN(base) (unsigned long)(base + 0x4) /*BTIF Tx Virtual FIFO Interrupt Enable Register */ -+#define TX_DMA_EN(base) (unsigned long)(base + DMA_EN_OFFSET)/*BTIF Tx Virtual FIFO Enable Register */ -+#define TX_DMA_RST(base) (unsigned long)(base + DMA_RST_OFFSET)/*BTIF Tx Virtual FIFO Reset Register */ -+#define TX_DMA_STOP(base) (unsigned long)(base + DMA_STOP_OFFSET)/*BTIF Tx Virtual FIFO STOP Register */ -+#define TX_DMA_FLUSH(base) (unsigned long)(base + DMA_FLUSH_OFFSET)/*BTIF Tx Virtual FIFO Flush Register */ -+#define TX_DMA_VFF_ADDR(base) (unsigned long)(base + 0x1C) /*BTIF Tx Virtual FIFO Base Address Register */ -+#define TX_DMA_VFF_LEN(base) (unsigned long)(base + 0x24) /*BTIF Tx Virtual FIFO Length Register */ -+#define TX_DMA_VFF_THRE(base) (unsigned long)(base + 0x28) /*BTIF Tx Virtual FIFO Threshold Register */ -+#define TX_DMA_VFF_WPT(base) (unsigned long)(base + 0x2C) /*BTIF Tx Virtual FIFO Write Pointer Register */ -+#define TX_DMA_VFF_RPT(base) (unsigned long)(base + 0x30) /*BTIF Tx Virtual FIFO Read Pointer Register */ -+#define TX_DMA_W_INT_BUF_SIZE(base) (unsigned long)(base + 0x34) -+/*BTIF Tx Virtual FIFO Internal Tx Write Buffer Size Register */ -+#define TX_DMA_INT_BUF_SIZE(base) (unsigned long)(base + 0x38) -+/*BTIF Tx Virtual FIFO Internal Tx Buffer Size Register */ -+ -+#define TX_DMA_VFF_VALID_SIZE(base) (unsigned long)(base + 0x3C) /*BTIF Tx Virtual FIFO Valid Size Register */ -+#define TX_DMA_VFF_LEFT_SIZE(base) (unsigned long)(base + 0x40) /*BTIF Tx Virtual FIFO Left Size Register */ -+#define TX_DMA_DEBUG_STATUS(base) (unsigned long)(base + 0x50) /*BTIF Tx Virtual FIFO Debug Status Register */ -+#define TX_DMA_VFF_ADDR_H(base) (unsigned long)(base + 0x54) /*BTIF Tx Virtual FIFO Base High Address Register */ -+ -+/*Rx Register Address Mapping*/ -+#define RX_DMA_INT_FLAG(base) (unsigned long)(base + 0x0) /*BTIF Rx Virtual FIFO Interrupt Flag Register */ -+#define RX_DMA_INT_EN(base) (unsigned long)(base + 0x4) /*BTIF Rx Virtual FIFO Interrupt Enable Register */ -+#define RX_DMA_EN(base) (unsigned long)(base + DMA_EN_OFFSET) /*BTIF Rx Virtual FIFO Enable Register */ -+#define RX_DMA_RST(base) (unsigned long)(base + DMA_RST_OFFSET) /*BTIF Rx Virtual FIFO Reset Register */ -+#define RX_DMA_STOP(base) (unsigned long)(base + DMA_STOP_OFFSET) /*BTIF Rx Virtual FIFO Stop Register */ -+#define RX_DMA_FLUSH(base) (unsigned long)(base + DMA_FLUSH_OFFSET) /*BTIF Rx Virtual FIFO Flush Register */ -+#define RX_DMA_VFF_ADDR(base) (unsigned long)(base + 0x1C) /*BTIF Rx Virtual FIFO Base Address Register */ -+#define RX_DMA_VFF_LEN(base) (unsigned long)(base + 0x24) /*BTIF Rx Virtual FIFO Length Register */ -+#define RX_DMA_VFF_THRE(base) (unsigned long)(base + 0x28) /*BTIF Rx Virtual FIFO Threshold Register */ -+#define RX_DMA_VFF_WPT(base) (unsigned long)(base + 0x2C) /*BTIF Rx Virtual FIFO Write Pointer Register */ -+#define RX_DMA_VFF_RPT(base) (unsigned long)(base + 0x30) /*BTIF Rx Virtual FIFO Read Pointer Register */ -+#define RX_DMA_FLOW_CTRL_THRE(base) (unsigned long)(base + 0x34) /*BTIF Rx Virtual FIFO Flow Control Register */ -+#define RX_DMA_INT_BUF_SIZE(base) (unsigned long)(base + 0x38) /*BTIF Rx Virtual FIFO Internal Buffer Register */ -+#define RX_DMA_VFF_VALID_SIZE(base) (unsigned long)(base + 0x3C) /*BTIF Rx Virtual FIFO Valid Size Register */ -+#define RX_DMA_VFF_LEFT_SIZE(base) (unsigned long)(base + 0x40) /*BTIF Rx Virtual FIFO Left Size Register */ -+#define RX_DMA_DEBUG_STATUS(base) (unsigned long)(base + 0x50) /*BTIF Rx Virtual FIFO Debug Status Register */ -+#define RX_DMA_VFF_ADDR_H(base) (unsigned long)(base + 0x54) /*BTIF Rx Virtual FIFO Base High Address Register */ -+ -+#define DMA_EN_BIT (0x1) -+#define DMA_STOP_BIT (0x1) -+#define DMA_RST_BIT (0x1) -+#define DMA_FLUSH_BIT (0x1) -+ -+#define DMA_WARM_RST (0x1 << 0) -+#define DMA_HARD_RST (0x1 << 1) -+ -+#define DMA_WPT_MASK (0x0000FFFF) -+#define DMA_WPT_WRAP (0x00010000) -+ -+#define DMA_RPT_MASK (0x0000FFFF) -+#define DMA_RPT_WRAP (0x00010000) -+ -+/*APDMA BTIF Tx Reg Ctrl Bit*/ -+#define TX_DMA_INT_FLAG_MASK (0x1) -+ -+#define TX_DMA_INTEN_BIT (0x1) -+ -+#define TX_DMA_ADDR_MASK (0xFFFFFFF8) -+#define TX_DMA_LEN_MASK (0x0000FFF8) -+ -+#define TX_DMA_THRE_MASK (0x0000FFFF) -+ -+#define TX_DMA_W_INT_BUF_MASK (0x000000FF) -+ -+#define TX_DMA_VFF_VALID_MASK (0x0000FFFF) -+#define TX_DMA_VFF_LEFT_MASK (0x0000FFFF) -+ -+/*APDMA BTIF Rx Reg Ctrl Bit*/ -+#define RX_DMA_INT_THRE (0x1 << 0) -+#define RX_DMA_INT_DONE (0x1 << 1) -+ -+#define RX_DMA_INT_THRE_EN (0x1 << 0) -+#define RX_DMA_INT_DONE_EN (0x1 << 1) -+ -+#define RX_DMA_ADDR_MASK (0xFFFFFFF8) -+#define RX_DMA_LEN_MASK (0x0000FFF8) -+ -+#define RX_DMA_THRE_MASK (0x0000FFFF) -+ -+#define RX_DMA_FLOW_CTRL_THRE_MASK (0x000000FF) -+ -+#define RX_DMA_INT_BUF_SIZE_MASK (0x0000001F) -+ -+#define RX_DMA_VFF_VALID_MASK (0x0000001F) -+ -+#define RX_DMA_VFF_LEFT_MASK (0x0000FFFF) -+ -+typedef struct _MTK_BTIF_DMA_VFIFO_ { -+ DMA_VFIFO vfifo; -+ unsigned int wpt; /*DMA's write pointer, which is maintained by SW for Tx DMA and HW for Rx DMA */ -+ unsigned int last_wpt_wrap; /*last wrap bit for wpt */ -+ unsigned int rpt; /*DMA's read pointer, which is maintained by HW for Tx DMA and SW for Rx DMA */ -+ unsigned int last_rpt_wrap; /*last wrap bit for rpt */ -+} MTK_BTIF_DMA_VFIFO, *P_MTK_BTIF_DMA_VFIFO; -+ -+/*for DMA debug purpose*/ -+typedef struct _MTK_BTIF_DMA_REG_DMP_DBG_ { -+ unsigned long reg_addr; -+ unsigned int reg_val; -+} MTK_BTIF_DMA_REG_DMP_DBG, *P_MTK_BTIF_DMA_REG_DMP_DBG; -+ -+#endif /*__HAL_BTIF_DMA_H_*/ -diff --git a/drivers/misc/mediatek/btif/common/plat_inc/btif_dma_pub.h b/drivers/misc/mediatek/btif/common/plat_inc/btif_dma_pub.h -new file mode 100644 -index 000000000000..0773f2ce387a ---- /dev/null -+++ b/drivers/misc/mediatek/btif/common/plat_inc/btif_dma_pub.h -@@ -0,0 +1,197 @@ -+/* -+ * Copyright (C) 2015 MediaTek Inc. -+ * -+ * 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. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#ifndef __HAL_BTIFD_DMA_PUB_H_ -+#define __HAL_BTIFD_DMA_PUB_H_ -+ -+#include -+ -+#include "plat_common.h" -+ -+typedef enum _ENUM_DMA_CTRL_ { -+ DMA_CTRL_DISABLE = 0, -+ DMA_CTRL_ENABLE = DMA_CTRL_DISABLE + 1, -+ DMA_CTRL_BOTH, -+} ENUM_DMA_CTRL; -+ -+/***************************************************************************** -+* FUNCTION -+* hal_tx_dma_info_get -+* DESCRIPTION -+* get btif tx dma channel's information -+* PARAMETERS -+* dma_dir [IN] DMA's direction -+* RETURNS -+* pointer to btif dma's information structure -+*****************************************************************************/ -+P_MTK_DMA_INFO_STR hal_btif_dma_info_get(ENUM_DMA_DIR dma_dir); -+ -+/***************************************************************************** -+* FUNCTION -+* hal_btif_dma_hw_init -+* DESCRIPTION -+* control clock output enable/disable of DMA module -+* PARAMETERS -+* p_dma_info [IN] pointer to BTIF dma channel's information -+* RETURNS -+* 0 means success, negative means fail -+*****************************************************************************/ -+int hal_btif_dma_hw_init(P_MTK_DMA_INFO_STR p_dma_info); -+ -+/***************************************************************************** -+* FUNCTION -+* hal_btif_clk_ctrl -+* DESCRIPTION -+* control clock output enable/disable of DMA module -+* PARAMETERS -+* p_dma_info [IN] pointer to BTIF dma channel's information -+* RETURNS -+* 0 means success, negative means fail -+*****************************************************************************/ -+int hal_btif_dma_clk_ctrl(P_MTK_DMA_INFO_STR p_dma_info, ENUM_CLOCK_CTRL flag); -+ -+/***************************************************************************** -+* FUNCTION -+* hal_tx_dma_ctrl -+* DESCRIPTION -+* enable/disable Tx DMA channel -+* PARAMETERS -+* p_dma_info [IN] pointer to BTIF dma channel's information -+* ctrl_id [IN] enable/disable ID -+* dma_dir [IN] DMA's direction -+* RETURNS -+* 0 means success; negative means fail -+*****************************************************************************/ -+int hal_btif_dma_ctrl(P_MTK_DMA_INFO_STR p_dma_info, ENUM_DMA_CTRL ctrl_id); -+ -+/***************************************************************************** -+* FUNCTION -+* hal_btif_dma_rx_cb_reg -+* DESCRIPTION -+* register rx callback function to dma module -+* PARAMETERS -+* p_dma_info [IN] pointer to BTIF dma channel's information -+* rx_cb [IN] function pointer to btif -+* RETURNS -+* 0 means success; negative means fail -+*****************************************************************************/ -+int hal_btif_dma_rx_cb_reg(P_MTK_DMA_INFO_STR p_dma_info, -+ dma_rx_buf_write rx_cb); -+ -+/***************************************************************************** -+* FUNCTION -+* hal_tx_vfifo_reset -+* DESCRIPTION -+* reset tx virtual fifo information, except memory information -+* PARAMETERS -+* p_dma_info [IN] pointer to BTIF dma channel's information -+* dma_dir [IN] DMA's direction -+* RETURNS -+* 0 means success, negative means fail -+*****************************************************************************/ -+int hal_btif_vfifo_reset(P_MTK_DMA_INFO_STR p_dma_info); -+ -+/***************************************************************************** -+* FUNCTION -+* hal_tx_dma_irq_handler -+* DESCRIPTION -+* lower level tx interrupt handler -+* PARAMETERS -+* p_dma_info [IN] pointer to BTIF dma channel's information -+* RETURNS -+* 0 means success, negative means fail -+*****************************************************************************/ -+int hal_tx_dma_irq_handler(P_MTK_DMA_INFO_STR p_dma_info); -+ -+/***************************************************************************** -+* FUNCTION -+* hal_dma_send_data -+* DESCRIPTION -+* send data through btif in DMA mode -+* PARAMETERS -+* p_dma_info [IN] pointer to BTIF dma channel's information -+* p_buf [IN] pointer to rx data buffer -+* max_len [IN] tx buffer length -+* RETURNS -+* 0 means success, negative means fail -+*****************************************************************************/ -+int hal_dma_send_data(P_MTK_DMA_INFO_STR p_dma_info, -+ const unsigned char *p_buf, const unsigned int buf_len); -+ -+/***************************************************************************** -+* FUNCTION -+* hal_dma_is_tx_complete -+* DESCRIPTION -+* get tx complete flag -+* PARAMETERS -+* p_dma_info [IN] pointer to BTIF dma channel's information -+* RETURNS -+* true means tx complete, false means tx in process -+*****************************************************************************/ -+bool hal_dma_is_tx_complete(P_MTK_DMA_INFO_STR p_dma_info); -+ -+/***************************************************************************** -+* FUNCTION -+* hal_dma_get_ava_room -+* DESCRIPTION -+* get tx available room -+* PARAMETERS -+* p_dma_info [IN] pointer to BTIF dma channel's information -+* RETURNS -+* available room size -+*****************************************************************************/ -+int hal_dma_get_ava_room(P_MTK_DMA_INFO_STR p_dma_info); -+ -+/***************************************************************************** -+* FUNCTION -+* hal_dma_is_tx_allow -+* DESCRIPTION -+* is tx operation allowed by DMA -+* PARAMETERS -+* p_dma_info [IN] pointer to BTIF dma channel's information -+* RETURNS -+* true if tx operation is allowed; false if tx is not allowed -+*****************************************************************************/ -+bool hal_dma_is_tx_allow(P_MTK_DMA_INFO_STR p_dma_info); -+ -+/***************************************************************************** -+* FUNCTION -+* hal_rx_dma_irq_handler -+* DESCRIPTION -+* lower level rx interrupt handler -+* PARAMETERS -+* p_dma_info [IN] pointer to BTIF dma channel's information -+* p_buf [IN/OUT] pointer to rx data buffer -+* max_len [IN] max length of rx buffer -+* RETURNS -+* 0 means success, negative means fail -+*****************************************************************************/ -+int hal_rx_dma_irq_handler(P_MTK_DMA_INFO_STR p_dma_info, -+ unsigned char *p_buf, const unsigned int max_len); -+ -+/***************************************************************************** -+* FUNCTION -+* hal_dma_dump_reg -+* DESCRIPTION -+* dump BTIF module's information when needed -+* PARAMETERS -+* p_dma_info [IN] pointer to BTIF dma channel's information -+* flag [IN] register id flag -+* RETURNS -+* 0 means success, negative means fail -+*****************************************************************************/ -+int hal_dma_dump_reg(P_MTK_DMA_INFO_STR p_dma_info, ENUM_BTIF_REG_ID flag); -+ -+int hal_dma_pm_ops(P_MTK_DMA_INFO_STR p_dma_info, MTK_BTIF_PM_OPID opid); -+ -+#endif /*__HAL_BTIFD_DMA_PUB_H_*/ -diff --git a/drivers/misc/mediatek/btif/common/plat_inc/btif_priv.h b/drivers/misc/mediatek/btif/common/plat_inc/btif_priv.h -new file mode 100644 -index 000000000000..51fe58a82b49 ---- /dev/null -+++ b/drivers/misc/mediatek/btif/common/plat_inc/btif_priv.h -@@ -0,0 +1,105 @@ -+/* -+ * Copyright (C) 2015 MediaTek Inc. -+ * -+ * 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. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#ifndef __HAL_BTIF_H_ -+#define __HAL_BTIF_H_ -+ -+#ifndef CONFIG_OF -+#define MTK_BTIF_REG_BASE BTIF_BASE -+#endif -+ -+#if defined(CONFIG_MTK_CLKMGR) -+#if defined(CONFIG_ARCH_MT6580) -+#define MTK_BTIF_CG_BIT MT_CG_BTIF_SW_CG -+#elif defined(CONFIG_ARCH_MT6735) || defined(CONFIG_ARCH_MT6735M) || defined(CONFIG_ARCH_MT6753) -+#define MTK_BTIF_CG_BIT MT_CG_PERI_BTIF -+#endif -+#else -+struct clk *clk_btif_apdma; /*btif apdma clock*/ -+struct clk *clk_btif; /*btif clock*/ -+#endif /* !defined(CONFIG_MTK_CLKMGR) */ -+ -+#define BTIF_RBR(base) (unsigned long)(base + 0x0) /*RX Buffer Register: read only */ -+#define BTIF_THR(base) (unsigned long)(base + 0x0) /*Rx Holding Register: write only */ -+#define BTIF_IER(base) (unsigned long)(base + 0x4) /*Interrupt Enable Register: read/write */ -+#define BTIF_IIR(base) (unsigned long)(base + 0x8) /*Interrupt Identification Register: read only */ -+#define BTIF_FIFOCTRL(base) (unsigned long)(base + 0x8) /*FIFO Control Register: write only */ -+#define BTIF_FAKELCR(base) (unsigned long)(base + 0xC) /*FAKE LCR Register: read/write */ -+#define BTIF_LSR(base) (unsigned long)(base + 0x14) /*Line Status Register: read only */ -+#define BTIF_SLEEP_EN(base) (unsigned long)(base + 0x48) /*Sleep Enable Register: read/write */ -+#define BTIF_DMA_EN(base) (unsigned long)(base + 0x4C) /*DMA Enable Register: read/write */ -+#define BTIF_RTOCNT(base) (unsigned long)(base + 0x54) /*Rx Timeout Count Register: read/write */ -+#define BTIF_TRI_LVL(base) (unsigned long)(base + 0x60) /*Tx/Rx Trigger Level Control Register: read/write */ -+#define BTIF_WAK(base) (unsigned long)(base + 0x64) /*BTIF module wakeup Register: write only */ -+#define BTIF_WAT_TIME(base) (unsigned long)(base + 0x68) /*BTIF ASYNC Wait Time Control Register: read/write */ -+#define BTIF_HANDSHAKE(base) (unsigned long)(base + 0x6C) /*BTIF New Handshake Control Register: read/write */ -+ -+/*BTIF_IER bits*/ -+#define BTIF_IER_TXEEN (0x1 << 1) /*1: Tx holding register is empty */ -+#define BTIF_IER_RXFEN (0x1 << 0) /*1: Rx buffer contains data */ -+ -+/*BTIF_IIR bits*/ -+#define BTIF_IIR_NINT (0x1 << 0) /*No INT Pending */ -+#define BTIF_IIR_TX_EMPTY (0x1 << 1) /*Tx Holding Register empty */ -+#define BTIF_IIR_RX (0x1 << 2) /*Rx data received */ -+#define BTIF_IIR_RX_TIMEOUT (0x11 << 2) /*Rx data received */ -+ -+/*BTIF_LSR bits*/ -+#define BTIF_LSR_DR_BIT (0x1 << 0) -+#define BTIF_LSR_THRE_BIT (0x1 << 5) -+#define BTIF_LSR_TEMT_BIT (0x1 << 6) -+ -+/*BTIF_FIFOCTRL bits*/ -+#define BTIF_FIFOCTRL_CLR_TX (0x1 << 2) /*Clear Tx FIRO */ -+#define BTIF_FIFOCTRL_CLR_RX (0x1 << 1) /*Clear Rx FIRO */ -+ -+/*BTIF_FAKELCR bits*/ -+#define BTIF_FAKELCR_NORMAL_MODE 0x0 -+ -+/*BTIF_SLEEP_EN bits*/ -+#define BTIF_SLEEP_EN_BIT (0x1 << 0) /*enable Sleep mode */ -+#define BTIF_SLEEP_DIS_BIT (0x0) /*disable sleep mode */ -+ -+/*BTIF_DMA_EN bits*/ -+#define BTIF_DMA_EN_RX (0x1 << 0) /*Enable Rx DMA */ -+#define BTIF_DMA_EN_TX (0x1 << 1) /*Enable Tx DMA */ -+#define BTIF_DMA_EN_AUTORST_EN (0x1 << 2) /*1: timeout counter will be auto reset */ -+#define BTIF_DMA_EN_AUTORST_DIS (0x0 << 2) /* -+ * 0: after Rx timeout happens, -+ * SW shall reset the interrupt by reading BTIF 0x4C -+ */ -+ -+/*BTIF_TRI_LVL bits*/ -+#define BTIF_TRI_LVL_TX_MASK ((0xf) << 0) -+#define BTIF_TRI_LVL_RX_MASK ((0x7) << 4) -+ -+#define BTIF_TRI_LVL_TX(x) ((x & 0xf) << 0) -+#define BTIF_TRI_LVL_RX(x) ((x & 0x7) << 4) -+ -+#define BTIF_TRI_LOOP_EN (0x1 << 7) -+#define BTIF_TRI_LOOP_DIS (0x0 << 7) -+ -+/*BTIF_WAK bits*/ -+#define BTIF_WAK_BIT (0x1 << 0) -+ -+/*BTIF_HANDSHAKE bits*/ -+#define BTIF_HANDSHAKE_EN_HANDSHAKE 1 -+#define BTIF_HANDSHAKE_DIS_HANDSHAKE 0 -+ -+#define BTIF_TX_FIFO_SIZE 16 -+#define BTIF_RX_FIFO_SIZE 8 -+ -+#define BTIF_TX_FIFO_THRE (BTIF_TX_FIFO_SIZE / 2) -+#define BTIF_RX_FIFO_THRE 0x1 /* 0x5 */ -+ -+#endif /*__HAL_BTIF_H_*/ -diff --git a/drivers/misc/mediatek/btif/common/plat_inc/btif_pub.h b/drivers/misc/mediatek/btif/common/plat_inc/btif_pub.h -new file mode 100644 -index 000000000000..1555d5a50c38 ---- /dev/null -+++ b/drivers/misc/mediatek/btif/common/plat_inc/btif_pub.h -@@ -0,0 +1,237 @@ -+/* -+ * Copyright (C) 2015 MediaTek Inc. -+ * -+ * 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. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#ifndef __HAL_BTIF_PUB_H_ -+#define __HAL_BTIF_PUB_H_ -+ -+#include "plat_common.h" -+ -+/*Enum Defination*/ -+/*BTIF Mode Enum */ -+typedef enum _ENUM_BTIF_MODE_ { -+ BTIF_MODE_PIO = 0, -+ BTIF_MODE_DMA = BTIF_MODE_PIO + 1, -+ BTIF_MODE_MAX, -+} ENUM_BTIF_MODE; -+ -+/***************************************************************************** -+* FUNCTION -+* hal_btif_info_get -+* DESCRIPTION -+* get btif's information included base address , irq related information -+* PARAMETERS -+* RETURNS -+* BTIF's information -+*****************************************************************************/ -+P_MTK_BTIF_INFO_STR hal_btif_info_get(void); -+ -+#if 0 /*included in hal_btif_info_get */ -+/***************************************************************************** -+* FUNCTION -+* hal_btif_get_irq -+* DESCRIPTION -+* get BTIF module's IRQ information -+* PARAMETERS -+* RETURNS -+* pointer to BTIF's irq structure -+*****************************************************************************/ -+P_MTK_BTIF_IRQ_STR hal_btif_get_irq(void); -+#endif -+ -+#if !defined(CONFIG_MTK_CLKMGR) -+/***************************************************************************** -+* FUNCTION -+* hal_btif_clk_get_and_prepare -+* DESCRIPTION -+* get clock from device tree and prepare for enable/disable control -+* PARAMETERS -+* pdev device pointer -+* RETURNS -+* 0 means success, negative means fail -+*****************************************************************************/ -+int hal_btif_clk_get_and_prepare(struct platform_device *pdev); -+/***************************************************************************** -+* FUNCTION -+* hal_btif_clk_unprepare -+* DESCRIPTION -+* unprepare btif clock and apdma clock -+* PARAMETERS -+* none -+* RETURNS -+* 0 means success, negative means fail -+*****************************************************************************/ -+int hal_btif_clk_unprepare(void); -+#endif -+/***************************************************************************** -+* FUNCTION -+* hal_btif_clk_ctrl -+* DESCRIPTION -+* control clock output enable/disable of BTIF module -+* PARAMETERS -+* p_base [IN] BTIF module's base address -+* RETURNS -+* 0 means success, negative means fail -+*****************************************************************************/ -+int hal_btif_clk_ctrl(P_MTK_BTIF_INFO_STR p_btif, ENUM_CLOCK_CTRL flag); -+ -+/***************************************************************************** -+* FUNCTION -+* hal_btif_hw_init -+* DESCRIPTION -+* BTIF module init, after this step, BTIF should enable to do tx/rx with PIO -+* mode -+* PARAMETERS -+* p_base [IN] BTIF module's base address -+* RETURNS -+* 0 means success, negative means fail -+*****************************************************************************/ -+int hal_btif_hw_init(P_MTK_BTIF_INFO_STR p_btif); -+ -+/***************************************************************************** -+* FUNCTION -+* hal_btif_rx_cb_reg -+* DESCRIPTION -+* BTIF rx callback register API -+* PARAMETERS -+* p_btif_info [IN] pointer to BTIF's information -+* rx_cb [IN] rx callback function -+* RETURNS -+* 0 means success, negative means fail -+*****************************************************************************/ -+int hal_btif_rx_cb_reg(P_MTK_BTIF_INFO_STR p_btif_info, -+ btif_rx_buf_write rx_cb); -+ -+/***************************************************************************** -+* FUNCTION -+* hal_btif_loopback_ctrl -+* DESCRIPTION -+* BTIF Tx/Rx loopback mode set, this operation can only be done -+* after set BTIF to normal mode -+* PARAMETERS -+* RETURNS -+* 0 means success, negative means fail -+*****************************************************************************/ -+int hal_btif_loopback_ctrl(P_MTK_BTIF_INFO_STR p_btif, bool en); -+ -+/***************************************************************************** -+* FUNCTION -+* hal_btif_rx_handler -+* DESCRIPTION -+* lower level interrupt handler -+* PARAMETERS -+* p_base [IN] BTIF module's base address -+* p_buf [IN/OUT] pointer to rx data buffer -+* max_len [IN] max length of rx buffer -+* RETURNS -+* 0 means success; negative means fail; positive means rx data length -+*****************************************************************************/ -+int hal_btif_irq_handler(P_MTK_BTIF_INFO_STR p_btif, -+ unsigned char *p_buf, const unsigned int max_len); -+ -+/***************************************************************************** -+* FUNCTION -+* hal_btif_tx_mode_ctrl -+* DESCRIPTION -+* set BTIF tx to corresponding mode (PIO/DMA) -+* PARAMETERS -+* p_base [IN] BTIF module's base address -+* mode [IN] rx mode -+* RETURNS -+* 0 means success, negative means fail -+*****************************************************************************/ -+int hal_btif_tx_mode_ctrl(P_MTK_BTIF_INFO_STR p_btif, ENUM_BTIF_MODE mode); -+ -+/***************************************************************************** -+* FUNCTION -+* hal_btif_rx_mode_ctrl -+* DESCRIPTION -+* set BTIF rx to corresponding mode (PIO/DMA) -+* PARAMETERS -+* p_base [IN] BTIF module's base address -+* mode [IN] rx mode -+* RETURNS -+* 0 means success, negative means fail -+*****************************************************************************/ -+int hal_btif_rx_mode_ctrl(P_MTK_BTIF_INFO_STR p_btif, ENUM_BTIF_MODE mode); -+ -+/***************************************************************************** -+* FUNCTION -+* hal_btif_send_data -+* DESCRIPTION -+* send data through btif in FIFO mode -+* PARAMETERS -+* p_base [IN] BTIF module's base address -+* p_buf [IN] pointer to rx data buffer -+* max_len [IN] tx buffer length -+* RETURNS -+* positive means number of data sent; -+* 0 means no data put to FIFO; -+* negative means error happens -+*****************************************************************************/ -+int hal_btif_send_data(P_MTK_BTIF_INFO_STR p_btif, -+ const unsigned char *p_buf, const unsigned int buf_len); -+ -+/***************************************************************************** -+* FUNCTION -+* hal_btif_raise_wak_sig -+* DESCRIPTION -+* raise wakeup signal to counterpart -+* PARAMETERS -+* p_base [IN] BTIF module's base address -+* RETURNS -+* 0 means success, negative means fail -+*****************************************************************************/ -+int hal_btif_raise_wak_sig(P_MTK_BTIF_INFO_STR p_btif); -+ -+/***************************************************************************** -+* FUNCTION -+* hal_btif_dump_reg -+* DESCRIPTION -+* dump BTIF module's information when needed -+* PARAMETERS -+* p_base [IN] BTIF module's base address -+* flag [IN] register id flag -+* RETURNS -+* 0 means success, negative means fail -+*****************************************************************************/ -+int hal_btif_dump_reg(P_MTK_BTIF_INFO_STR p_btif, ENUM_BTIF_REG_ID flag); -+ -+/***************************************************************************** -+* FUNCTION -+* hal_btif_is_tx_complete -+* DESCRIPTION -+* get tx complete flag -+* PARAMETERS -+* p_base [IN] BTIF module's base address -+* RETURNS -+* true means tx complete, false means tx in process -+*****************************************************************************/ -+bool hal_btif_is_tx_complete(P_MTK_BTIF_INFO_STR p_btif); -+ -+/***************************************************************************** -+* FUNCTION -+* hal_btif_is_tx_allow -+* DESCRIPTION -+* whether tx is allowed -+* PARAMETERS -+* p_base [IN] BTIF module's base address -+* RETURNS -+* true if tx operation is allowed; false if tx is not allowed -+*****************************************************************************/ -+bool hal_btif_is_tx_allow(P_MTK_BTIF_INFO_STR p_btif); -+ -+int hal_btif_pm_ops(P_MTK_BTIF_INFO_STR p_btif, MTK_BTIF_PM_OPID opid); -+ -+void mtk_btif_read_cpu_sw_rst_debug_plat(void); -+ -+#endif /*__HAL_BTIF_PUB_H_*/ -diff --git a/drivers/misc/mediatek/btif/common/plat_inc/plat_common.h b/drivers/misc/mediatek/btif/common/plat_inc/plat_common.h -new file mode 100644 -index 000000000000..2a1462cb32ff ---- /dev/null -+++ b/drivers/misc/mediatek/btif/common/plat_inc/plat_common.h -@@ -0,0 +1,307 @@ -+/* -+ * Copyright (C) 2015 MediaTek Inc. -+ * -+ * 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. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#ifndef __HAL_PUB_H_ -+#define __HAL_PUB_H_ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#ifdef CONFIG_OF -+#include -+#include -+#include -+#else -+#include -+#include -+#endif -+#if defined(CONFIG_MTK_CLKMGR) -+#include -+#else -+#include -+#include -+#endif /* defined(CONFIG_MTK_CLKMGR) */ -+#include -+ -+extern int mtk_btif_hal_get_log_lvl(void); -+ -+#define MTK_BTIF_MARK_UNUSED_API -+ -+typedef irq_handler_t mtk_btif_irq_handler; -+ -+#define MTK_BTIF_ENABLE_CLK_CTL 1 -+#define MTK_BTIF_ENABLE_CLK_REF_COUNTER 1 -+ -+#define DBG_LOG_STR_SIZE 256 -+ -+/*Log defination*/ -+static int hal_log_print(const char *str, ...) -+{ -+ va_list args; -+ char temp_sring[DBG_LOG_STR_SIZE]; -+ -+ va_start(args, str); -+ vsnprintf(temp_sring, DBG_LOG_STR_SIZE, str, args); -+ va_end(args); -+ -+ pr_err("%s", temp_sring); -+ -+ return 0; -+} -+ -+#define BTIF_LOG_LOUD 4 -+#define BTIF_LOG_DBG 3 -+#define BTIF_LOG_INFO 2 -+#define BTIF_LOG_WARN 1 -+#define BTIF_LOG_ERR 0 -+ -+#ifndef DFT_TAG -+#define DFT_TAG "[BTIF-DFT]" -+#endif -+ -+#define BTIF_LOUD_FUNC(fmt, arg ...) \ -+do { \ -+ if (mtk_btif_hal_get_log_lvl() >= BTIF_LOG_LOUD) \ -+ hal_log_print(DFT_TAG "[L]%s:" fmt, \ -+ __func__, ## arg); \ -+} while (0) -+ -+#define BTIF_INFO_FUNC(fmt, arg ...) \ -+do { \ -+ if (mtk_btif_hal_get_log_lvl() >= BTIF_LOG_INFO)\ -+ hal_log_print(DFT_TAG "[I]%s:" fmt, \ -+ __func__, ## arg); \ -+} while (0) -+ -+#define BTIF_WARN_FUNC(fmt, arg ...) \ -+do { \ -+ if (mtk_btif_hal_get_log_lvl() >= BTIF_LOG_WARN)\ -+ hal_log_print(DFT_TAG "[W]%s:" fmt, \ -+ __func__, ## arg); \ -+} while (0) -+ -+#define BTIF_ERR_FUNC(fmt, arg ...)\ -+do {\ -+ if (mtk_btif_hal_get_log_lvl() >= BTIF_LOG_ERR)\ -+ hal_log_print(DFT_TAG "[E]%s(%d):" fmt,\ -+ __func__, __LINE__, ## arg);\ -+} while (0) -+ -+#define BTIF_DBG_FUNC(fmt, arg ...) \ -+do { \ -+ if (mtk_btif_hal_get_log_lvl() >= BTIF_LOG_DBG) \ -+ hal_log_print(DFT_TAG "[D]%s:" fmt, \ -+ __func__, ## arg); \ -+} while (0) -+ -+#define BTIF_TRC_FUNC(f) \ -+do { \ -+ if (mtk_btif_hal_get_log_lvl() >= BTIF_LOG_DBG) \ -+ hal_log_print(DFT_TAG "<%s> <%d>\n", \ -+ __func__, __LINE__); \ -+} while (0) -+ -+/*-----------------------------------Enum Defination--------------------------------*/ -+/*IRQ sensetive type */ -+typedef enum _ENUM_IRQ_SENS_TYPE_ { -+ IRQ_SENS_EDGE = 0, -+ IRQ_SENS_LVL = IRQ_SENS_EDGE + 1, -+ IRQ_SENS_TYPE_MAX -+} ENUM_IRQ_SENS_TYPE; -+ -+/*IRQ level trigger type */ -+typedef enum _ENUM_IRQ_LVL_TYPE_ { -+ IRQ_LVL_LOW = 0, -+ IRQ_LVL_HIGH = IRQ_LVL_LOW + 1, -+ IRQ_LVL_MAX -+} ENUM_IRQ_LVL; -+ -+/*IRQ edge trigger type */ -+typedef enum _ENUM_IRQ_EDGE_TYPE_ { -+ IRQ_EDGE_FALL = 0, -+ IRQ_EDGE_RAISE = IRQ_EDGE_FALL + 1, -+ IRQ_EDGE_BOTH = IRQ_EDGE_RAISE + 1, -+ IRQ_EDGE_MAX -+} ENUM_IRQ_EDGE; -+ -+typedef enum _ENUM_CLOCK_CTRL_ { -+ CLK_OUT_DISABLE = 0, -+ CLK_OUT_ENABLE = CLK_OUT_DISABLE + 1, -+ CLK_OUT_MAX -+} ENUM_CLOCK_CTRL; -+ -+/*Error No. table */ -+typedef enum _ENUM_ERROR_CODE_ { -+ ERR_NO_ERROR = 0, -+ ERR_INVALID_PAR = ERR_NO_ERROR - 1, -+ ERR_MAX = ERR_INVALID_PAR - 1, -+} ENUM_ERROR_CODE; -+ -+typedef enum _ENUM_BTIF_DIR_ { -+ BTIF_TX = 0, -+ BTIF_RX = BTIF_TX + 1, -+ BTIF_DIR_MAX, -+} ENUM_BTIF_DIR; -+ -+typedef enum _ENUM_DMA_DIR_ { -+ DMA_DIR_RX = 0, -+ DMA_DIR_TX = DMA_DIR_RX + 1, -+ DMA_DIR_BOTH, -+} ENUM_DMA_DIR; -+ -+typedef enum _ENUM_BTIF_REG_ID_ { -+ REG_IIR = 0, /*Interrupt Identification Register */ -+ REG_LSR = 1, /*Line Status Register */ -+ REG_FAKE_LCR = 2, /*Fake Lcr Regiseter */ -+ REG_FIFO_CTRL = 3, /*FIFO Control Register */ -+ REG_IER = 4, /*Interrupt Enable Register */ -+ REG_SLEEP_EN = 5, /*Sleep Enable Register */ -+ REG_RTO_COUNTER = 6, /*Rx Timeout Counter Register */ -+ REG_DMA_EN = 7, /*DMA Enalbe Register */ -+ REG_TRIG_LVL = 8, /*Tx/Rx Trigger Level Register */ -+ REG_WAT_TIME = 9, /*Async Wait Time Register */ -+ REG_HANDSHAKE = 10, /*New HandShake Mode Register */ -+ REG_SLP_WAK = 11, /*Sleep Wakeup Reigster */ -+ REG_BTIF_ALL = 12, /*all btif controller's registers */ -+ REG_TX_DMA_ALL = 13, -+ REG_RX_DMA_ALL = 14, -+ REG_MAX -+} ENUM_BTIF_REG_ID; -+ -+typedef enum _MTK_BTIF_PM_OPID_ { -+ BTIF_PM_DPIDLE_EN, -+ BTIF_PM_DPIDLE_DIS, -+ BTIF_PM_SUSPEND, -+ BTIF_PM_RESUME, -+ BTIF_PM_RESTORE_NOIRQ, -+} MTK_BTIF_PM_OPID; -+ -+#define BTIF_HAL_TX_FIFO_SIZE (1024 * 4) -+ -+/*-----------------------------------Enum Defination End--------------------------------*/ -+ -+/*****************************structure definition***************************/ -+/*IRQ related information*/ -+typedef struct _MTK_BTIF_IRQ_STR_ { -+ const char *name; -+ bool is_irq_sup; -+ unsigned int irq_id; -+#ifdef CONFIG_OF -+ unsigned int irq_flags; -+#else -+ ENUM_IRQ_SENS_TYPE sens_type; -+ union { -+ ENUM_IRQ_LVL lvl_type; -+ ENUM_IRQ_EDGE edge_type; -+ }; -+#endif -+ bool reg_flag; -+ irq_handler_t p_irq_handler; -+} MTK_BTIF_IRQ_STR, *P_MTK_BTIF_IRQ_STR; -+ -+typedef struct _DMA_VFIFO_ { -+ /*[Driver Access] vFIFO memory'svirtual address */ -+ unsigned char *p_vir_addr; -+ /*[HW Access] dma handle , physically address, set to DMA's HW Register */ -+ dma_addr_t phy_addr; -+ /*DMA's vFIFO size */ -+ unsigned int vfifo_size; -+ /*DMA's threshold value */ -+ unsigned int thre; -+} DMA_VFIFO, *P_DMA_VFIFO; -+ -+typedef unsigned int (*dma_rx_buf_write) (void *p_dma_info, -+ unsigned char *p_buf, -+ unsigned int buf_len); -+typedef unsigned int (*btif_rx_buf_write) (void *p_btif_info, -+ unsigned char *p_buf, -+ unsigned int buf_len); -+ -+/*DMA related information*/ -+typedef struct _MTK_DMA_INFO_STR_ { -+ unsigned long base; -+ ENUM_DMA_DIR dir; -+ P_MTK_BTIF_IRQ_STR p_irq; -+ dma_rx_buf_write rx_cb; -+ P_DMA_VFIFO p_vfifo; -+} MTK_DMA_INFO_STR, *P_MTK_DMA_INFO_STR; -+ -+/*DMA related information*/ -+typedef struct _MTK_BTIF_INFO_STR_ { -+ unsigned long base; /*base address */ -+ P_MTK_BTIF_IRQ_STR p_irq; /*irq related information */ -+ -+ unsigned int tx_fifo_size; /*BTIF tx FIFO size */ -+ unsigned int rx_fifo_size; /*BTIF rx FIFO size */ -+ -+ unsigned int tx_tri_lvl; /*BTIFtx trigger level in FIFO mode */ -+ unsigned int rx_tri_lvl; /*BTIFrx trigger level in FIFO mode */ -+ -+ unsigned int clk_gat_addr; /*clock gating address */ -+ unsigned int set_bit; /*enable clock gating bit */ -+ unsigned int clr_bit; /*clear clock gating bit */ -+ -+ unsigned int rx_data_len; /*rx data length */ -+ -+ btif_rx_buf_write rx_cb; -+ -+ struct kfifo *p_tx_fifo; /*tx fifo */ -+ spinlock_t tx_fifo_spinlock; /*tx fifo spinlock */ -+} MTK_BTIF_INFO_STR, *P_MTK_BTIF_INFO_STR; -+ -+/**********End of Structure Definition***********/ -+ -+/***********register operation***********/ -+#ifdef __KERNEL__ -+/*byte write <1 byte> */ -+#define btif_reg_sync_writeb(v, a) mt_reg_sync_writeb(v, a) -+/*word write <2 byte> */ -+#define btif_reg_sync_writew(v, a) mt_reg_sync_writew(v, a) -+/*long write <4 byte> */ -+#define btif_reg_sync_writel(v, a) mt_reg_sync_writel(v, a) -+#else -+/*byte write <1 byte> */ -+#define btif_reg_sync_writeb(v, a) mt65xx_reg_sync_writeb(v, a) -+/*word write <2 byte> */ -+#define btif_reg_sync_writew(v, a) mt65xx_reg_sync_writew(v, a) -+/*long write <4 byte> */ -+#define btif_reg_sync_writel(v, a) mt65xx_reg_sync_writel(v, a) -+#endif -+#define BTIF_READ8(REG) __raw_readb((unsigned char *)(REG)) -+#define BTIF_READ16(REG) __raw_readw((unsigned short *)(REG)) -+#define BTIF_READ32(REG) __raw_readl((unsigned int *)(REG)) -+ -+#define BTIF_SET_BIT(REG, BITVAL) do { \ -+*((volatile unsigned int *)(REG)) |= ((unsigned int)(BITVAL)); \ -+mb(); /**/ \ -+} \ -+while (0) -+#define BTIF_CLR_BIT(REG, BITVAL) do { \ -+(*(volatile unsigned int *)(REG)) &= ~((unsigned int)(BITVAL)); \ -+mb(); /**/\ -+} \ -+while (0) -+ -+/***********end of register operation *********/ -+ -+#endif /*__HAL_PUB_H_*/ -diff --git a/drivers/misc/mediatek/connectivity/Kconfig b/drivers/misc/mediatek/connectivity/Kconfig -new file mode 100644 -index 000000000000..4a944b1f0ebe ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/Kconfig -@@ -0,0 +1,299 @@ -+config MTK_COMBO -+ tristate "MediaTek Connectivity Combo Chip Support" -+ help -+ MTK connectivity combo chip driver for MT66xx -+ -+# -+# MTK Combo Chip Selection -+# -+ -+choice -+ prompt "Select Chip" -+ depends on MTK_COMBO -+ -+config MTK_COMBO_CHIP_MT6620 -+ bool "MT6620" -+ help -+ this config is used to decided combo chip version -+ in current platform -+ is -+ MT6620 -+ -+config MTK_COMBO_CHIP_MT6628 -+ bool "MT6628" -+ help -+ this config is used to decided combo chip version -+ in current platform -+ is -+ MT6628 -+ -+config MTK_COMBO_CHIP_MT6630 -+ bool "MT6630" -+ help -+ this config is used to decided combo chip version -+ in current platform -+ is -+ MT6630 -+ -+config MTK_COMBO_CHIP_CONSYS_6572 -+ bool "CONSYS_6572" -+ help -+ this config is used to decided SOC consys version -+ in current platform -+ is -+ MT6572 -+ -+config MTK_COMBO_CHIP_CONSYS_6582 -+ bool "CONSYS_6582" -+ help -+ this config is used to decided SOC consys version -+ in current platform -+ is -+ MT6582 -+ -+config MTK_COMBO_CHIP_CONSYS_8127 -+ bool "CONSYS_8127" -+ help -+ this config is used to decided SOC consys version -+ in current platform -+ is -+ MT6572 -+ -+config MTK_COMBO_CHIP_CONSYS_7623 -+ bool "CONSYS_7623" -+ #select MTK_PLATFORM::="mt7623" -+ help -+ this config is used to decide SOC consys version -+ in current platform is MT7623 and prepare proper -+ system services like radio power on/off and firmware -+ download for the Bluetotoh and Wifi. -+ -+ -+config MTK_COMBO_CHIP_CONSYS_6752 -+ bool "CONSYS_6752" -+ help -+ this config is used to decided SOC consys version -+ in current platform -+ is -+ MT6752 -+ -+config MTK_COMBO_CHIP_CONSYS_6592 -+ bool "CONSYS_6592" -+ help -+ this config is used to decided SOC consys version -+ in current platform -+ is -+ MT6592 -+ -+config MTK_COMBO_CHIP_CONSYS_8163 -+ bool "CONSYS_8163" -+ help -+ this config is used to decided SOC consys version -+ in current platform -+ is -+ MT8163 -+ -+config MTK_COMBO_CHIP_CONSYS_6735 -+ bool "CONSYS_6735" -+ help -+ this config is used to decided SOC consys version -+ in current platform -+ is -+ MT6735 -+ -+config MTK_COMBO_CHIP_CONSYS_6755 -+ bool "CONSYS_6755" -+ help -+ this config is used to decided SOC consys version -+ in current platform -+ is -+ MT6755 -+ -+config MTK_COMBO_CHIP_CONSYS_6580 -+ bool "CONSYS_6580" -+ help -+ this config is used to decided SOC consys version -+ in current platform -+ is -+ MT6580 -+ -+config MTK_COMBO_CHIP_CONSYS_6797 -+ bool "CONSYS_6797" -+ help -+ this config is used to decided SOC consys version -+ in current platform -+ is -+ MT6797 -+endchoice -+ -+config MTK_COMBO_CHIP -+ string -+ default "MT6620" if MTK_COMBO_CHIP_MT6620 -+ default "MT6628" if MTK_COMBO_CHIP_MT6628 -+ default "MT6630" if MTK_COMBO_CHIP_MT6630 -+ default "CONSYS_6572" if MTK_COMBO_CHIP_CONSYS_6572 -+ default "CONSYS_6582" if MTK_COMBO_CHIP_CONSYS_6582 -+ default "CONSYS_8127" if MTK_COMBO_CHIP_CONSYS_8127 -+ default "CONSYS_7623" if MTK_COMBO_CHIP_CONSYS_7623 -+ default "CONSYS_6752" if MTK_COMBO_CHIP_CONSYS_6752 -+ default "CONSYS_6755" if MTK_COMBO_CHIP_CONSYS_6755 -+ default "CONSYS_6592" if MTK_COMBO_CHIP_CONSYS_6592 -+ default "CONSYS_8163" if MTK_COMBO_CHIP_CONSYS_8163 -+ default "CONSYS_6735" if MTK_COMBO_CHIP_CONSYS_6735 -+ default "CONSYS_6580" if MTK_COMBO_CHIP_CONSYS_6580 -+ default "CONSYS_6797" if MTK_COMBO_CHIP_CONSYS_6797 -+ help -+ this feature is used to identify combo chip version or SOC chip -+ consys version. -+ -+# -+# Target Platform Selection -+# -+config MTK_COMBO_PLAT_PATH -+ string "Platform folder name" -+ depends on MTK_COMBO -+ default "sample" if MTK_COMBO_PLAT_SAMPLE -+ help -+ Specify platform folder under common driver platform folder: -+ mtk_wcn_combo/common/platform/* -+ -+# -+# MTK COMBO Chip Configuration -+# -+config MTK_COMBO_COMM -+ depends on MTK_COMBO -+ tristate "MediaTek Combo Chip Common part driver" -+ help -+ MediaTek combo chip common part driver -+ -+#config MTK_COMBO_COMM_PS -+# depends on MTK_COMBO_COMM -+# bool "Enable PS support" -+# default n -+# help -+# Enable PS support of common UART interface -+ -+config MTK_COMBO_COMM_UART -+ depends on MTK_COMBO_COMM -+ tristate "Common interface UART" -+ help -+ Use UART for common part interface type -+ -+config MTK_COMBO_COMM_SDIO -+ depends on MTK_COMBO_COMM -+ tristate "Common interface SDIO" -+ help -+ Use SDIO for common part interface type -+ -+config MTK_COMBO_COMM_NPWR -+ depends on MTK_COMBO_COMM -+ bool "Enable NPWR support" -+ default n -+ help -+ Enable NPWR support of new power on swquence -+ -+config MTK_COMBO_COMM_APO -+ depends on MTK_COMBO_COMM -+ bool "Enable always power on support" -+ #default y -+ help -+ Enable chip will always power on -+ -+config MTK_COMBO_BT -+ tristate "MediaTek Combo Chip BT driver" -+ depends on BT && MTK_COMBO -+ select MTK_BTIF -+ help -+ MTK BT /dev/stpbt driver for Bluedroid -+ -+config MTK_COMBO_BT_HCI -+ tristate "MediaTek Combo Chip BlueZ driver" -+ depends on BT && MTK_COMBO -+ select MTK_BTIF -+ help -+ MTK BT driver for BlueZ -+ -+config MTK_COMBO_WIFI -+ tristate "MediaTek combo chip Wi-Fi support" -+ depends on MTK_COMBO -+ select MTK_BTIF -+ select WIRELESS_EXT -+ select WEXT_PRIV -+ -+config MTK_WAPI_SUPPORT -+ bool "MTK_WAPI_SUPPORT" -+ depends on MTK_COMBO_WIFI -+ #default y -+ help -+ if it is set to TRUE: Support WAPI (WLAN Authentication and -+ Privacy Infrastructure) -+ -+config MTK_PASSPOINT_R1_SUPPORT -+ bool "MTK_PASSPOINT_R1_SUPPORT" -+ depends on MTK_COMBO_WIFI -+ help -+ Support Passpoint R1 (Hotspot 2.0 R1) -+ -+config MTK_PASSPOINT_R2_SUPPORT -+ bool "MTK_PASSPOINT_R2_SUPPORT" -+ depends on MTK_COMBO_WIFI -+ help -+ Support Passpoint R2 -+ -+config MTK_WIFI_MCC_SUPPORT -+ bool "MTK_WIFI_MCC_SUPPORT" -+ depends on MTK_COMBO_WIFI -+ #default y -+ help -+ if it is set to TRUE, wlan will support Multi-Channel Concurrency, -+ otherwise, only support Single Channel Concurrency -+ -+config MTK_DHCPV6C_WIFI -+ bool "MTK_DHCPV6C_WIFI" -+ help -+ no: disable this feature -+ -+config MTK_CONN_LTE_IDC_SUPPORT -+ bool "MediaTek CONN LTE IDC support" -+ select MTK_CONN_MD -+ #default y -+ help -+ This option enables CONN LTE IDC support -+ -+menuconfig GPS -+ tristate "GPS drivers" -+ #default y -+ ---help--- -+ Say Y here for supporting GPS. -+ -+if GPS -+config MTK_GPS -+ tristate "MediaTek GPS driver" -+ #default y -+ ---help--- -+ MTK GPS driver -+ To switch gps nmea port driver. -+ Set "yes" to turn on. -+ Set "no" to turn off. -+endif # GPS -+ -+config MTK_GPS_SUPPORT -+ tristate "MediaTek GPS driver" -+ select MTK_GPS -+ help -+ to switch GPS feature on the platform. -+ Set "yes" to turn on and set "no" -+ (with MTK_AGPS_APP=no at the same time) -+ to turn off. -+ -+config MTK_GPS_REGISTER_SETTING -+ tristate "MediaTek GPS Register Setting" -+ depends on MTK_COMBO_GPS -+ help -+ GPS register settings. -+ -+config MTK_GPS_EMI -+ tristate "MediaTek GPS EMI Driver" -+ depends on MTK_COMBO_GPS -+ help -+ GPS EMI driver is for MNL OFFLOAD feature. -diff --git a/drivers/misc/mediatek/connectivity/Makefile b/drivers/misc/mediatek/connectivity/Makefile -new file mode 100644 -index 000000000000..0947788d189a ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/Makefile -@@ -0,0 +1,41 @@ -+# -+# Copyright (C) 2015 MediaTek Inc. -+# -+# 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. -+# -+# This program is distributed in the hope that it will be useful, -+# but WITHOUT ANY WARRANTY; without even the implied warranty of -+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+# GNU General Public License for more details. -+# -+ -+# Connectivity combo driver -+# If KERNELRELEASE is defined, we've been invoked from the -+# kernel build system and can use its language. -+ifneq ($(KERNELRELEASE),) -+subdir-ccflags-y += -D MTK_WCN_REMOVE_KERNEL_MODULE -+ifeq ($(CONFIG_ARM64), y) -+subdir-ccflags-y += -D CONFIG_MTK_WCN_ARM64 -+endif -+ -+ifeq ($(CONFIG_MTK_CONN_LTE_IDC_SUPPORT),y) -+ subdir-ccflags-y += -D WMT_IDC_SUPPORT=1 -+else -+ subdir-ccflags-y += -D WMT_IDC_SUPPORT=0 -+endif -+ subdir-ccflags-y += -D MTK_WCN_WMT_STP_EXP_SYMBOL_ABSTRACT -+ -+ obj-y += common/ -+ obj-$(CONFIG_MTK_COMBO_WIFI) += wlan/ -+ obj-n := dummy.o -+ -+# Otherwise we were called directly from the command line; -+# invoke the kernel build system. -+else -+ KERNELDIR ?= /lib/modules/$(shell uname -r)/build -+ PWD := $(shell pwd) -+default: -+ $(MAKE) -C $(KERNELDIR) M=$(PWD) modules -+endif -diff --git a/drivers/misc/mediatek/connectivity/common/Makefile b/drivers/misc/mediatek/connectivity/common/Makefile -new file mode 100644 -index 000000000000..622b74430e13 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/Makefile -@@ -0,0 +1,23 @@ -+subdir-ccflags-y += -Werror -I$(srctree)/drivers/misc/mediatek/include/mt-plat/$(MTK_PLATFORM)/include -+subdir-ccflags-y += -Werror -I$(srctree)/drivers/misc/mediatek/include/mt-plat -+ -+#ifneq ($(filter "MT6620E3",$(CONFIG_MTK_COMBO_CHIP)),) -+# obj-y += combo/ -+#endif -+#ifneq ($(filter "MT6628",$(CONFIG_MTK_COMBO_CHIP)),) -+# subdir-ccflags-y += -D MT6628 -+# subdir-ccflags-y += -D MERGE_INTERFACE_SUPPORT -+# obj-y += combo/ -+#endif -+#ifneq ($(filter "MT6630",$(CONFIG_MTK_COMBO_CHIP)),) -+# subdir-ccflags-y += -D MT6630 -+#ifneq ($(CONFIG_ARCH_MT2601),y) -+# subdir-ccflags-y += -D MERGE_INTERFACE_SUPPORT -+#endif -+# obj-y += combo/ -+#endif -+ifneq ($(filter "CONSYS_%",$(CONFIG_MTK_COMBO_CHIP)),) -+ obj-y += conn_soc/ -+endif -+ -+obj-y += common_detect/ -diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/Makefile b/drivers/misc/mediatek/connectivity/common/common_detect/Makefile -new file mode 100644 -index 000000000000..8d7dc690affd ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/common_detect/Makefile -@@ -0,0 +1,47 @@ -+subdir-ccflags-y += -I$(srctree)/arch/arm/mach-$(MTK_PLATFORM)/$(ARCH_MTK_PROJECT)/dct/dct -+subdir-ccflags-y += -DWMT_PLAT_ALPS=1 -+ -+COMBO_CHIP_SUPPORT := false -+ifneq ($(filter "MT6620E3",$(CONFIG_MTK_COMBO_CHIP)),) -+ COMBO_CHIP_SUPPORT := true -+endif -+ifneq ($(filter "MT6628",$(CONFIG_MTK_COMBO_CHIP)),) -+ COMBO_CHIP_SUPPORT := true -+endif -+ifneq ($(filter "MT6630",$(CONFIG_MTK_COMBO_CHIP)),) -+ COMBO_CHIP_SUPPORT := true -+endif -+ifeq ($(COMBO_CHIP_SUPPORT), true) -+ subdir-ccflags-y += -D MTK_WCN_COMBO_CHIP_SUPPORT -+ ccflags-y += -I$(src)/../combo/linux/include -+endif -+ -+ifneq ($(filter "CONSYS_%",$(CONFIG_MTK_COMBO_CHIP)),) -+ subdir-ccflags-y += -D MTK_WCN_SOC_CHIP_SUPPORT -+ ccflags-y += -I$(src)/../conn_soc/linux/include -+endif -+ -+ -+ifeq ($(CONFIG_MTK_COMBO),y) -+ ccflags-y += -I$(src)/drv_init/inc -+ obj-y += mtk_wcn_stub_alps.o -+ obj-y += wmt_stp_exp.o -+ obj-y += wmt_gpio.o -+ -+ obj-y += wmt_detect.o -+ obj-y += sdio_detect.o -+ obj-y += wmt_detect_pwr.o -+ -+ obj-y += drv_init/ -+endif -+ -+ifeq ($(CONFIG_MTK_COMBO),m) -+ obj-y += mtk_wcn_stub_alps.o -+ obj-y += wmt_stp_exp.o -+ obj-y += wmt_gpio.o -+ -+ obj-$(CONFIG_MTK_COMBO) += mtk_wmt_detect.o -+ mtk_wmt_detect-objs := wmt_detect.o -+ mtk_wmt_detect-objs += sdio_detect.o -+ mtk_wmt_detect-objs += wmt_detect_pwr.o -+endif -diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/Makefile b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/Makefile -new file mode 100644 -index 000000000000..bb84384b9a24 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/Makefile -@@ -0,0 +1,22 @@ -+ifeq ($(CONFIG_MTK_COMBO),y) -+ ccflags-y += -I$(src)/inc/ -+ ccflags-y += -I$(src)/../ -+ -+ifneq ($(filter "MT6630",$(CONFIG_MTK_COMBO_CHIP)),) -+ ccflags-y += -D MTK_WCN_WLAN_GEN3 -+endif -+ifneq ($(filter "CONSYS_6797",$(CONFIG_MTK_COMBO_CHIP)),) -+ ccflags-y += -D MTK_WCN_WLAN_GEN3 -+else ifneq ($(filter "CONSYS_%",$(CONFIG_MTK_COMBO_CHIP)),) -+ ccflags-y += -D MTK_WCN_WLAN_GEN2 -+endif -+ -+ obj-y += conn_drv_init.o -+ obj-y += common_drv_init.o -+ obj-y += bluetooth_drv_init.o -+ obj-y += gps_drv_init.o -+ obj-y += fm_drv_init.o -+ obj-y += wlan_drv_init.o -+ obj-($(CONFIG_MTK_COMBO_ANT)) += ant_drv_init.o -+ -+endif -diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/ant_drv_init.c b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/ant_drv_init.c -new file mode 100644 -index 000000000000..aa453f9397a4 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/ant_drv_init.c -@@ -0,0 +1,38 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -+ -+#ifdef DFT_TAG -+#undef DFT_TAG -+#endif -+#define DFT_TAG "[ANT-MOD-INIT]" -+ -+#include "wmt_detect.h" -+#include "ant_drv_init.h" -+ -+int do_ant_drv_init(int chip_id) -+{ -+ int i_ret = -1; -+ -+ WMT_DETECT_INFO_FUNC("start to do ANT driver init\n"); -+ switch (chip_id) { -+ case 0x6630: -+ case 0x6797: -+ i_ret = mtk_wcn_stpant_drv_init(); -+ WMT_DETECT_INFO_FUNC("finish ANT driver init, i_ret:%d\n", i_ret); -+ break; -+ default: -+ WMT_DETECT_ERR_FUNC("chipid is not 6630,ANT is not supported!\n"); -+ } -+ return i_ret; -+} -diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/bluetooth_drv_init.c b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/bluetooth_drv_init.c -new file mode 100644 -index 000000000000..47b055433443 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/bluetooth_drv_init.c -@@ -0,0 +1,35 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -+ -+#ifdef DFT_TAG -+#undef DFT_TAG -+#endif -+#define DFT_TAG "[BT-MOD-INIT]" -+ -+#include "wmt_detect.h" -+#include "bluetooth_drv_init.h" -+ -+int do_bluetooth_drv_init(int chip_id) -+{ -+ int i_ret = -1; -+ -+#if defined(CONFIG_MTK_COMBO_BT) || defined(CONFIG_MTK_COMBO_BT_HCI) -+ WMT_DETECT_INFO_FUNC("start to do bluetooth driver init\n"); -+ i_ret = mtk_wcn_stpbt_drv_init(); -+ WMT_DETECT_INFO_FUNC("finish bluetooth driver init, i_ret:%d\n", i_ret); -+#else -+ WMT_DETECT_INFO_FUNC("CONFIG_MTK_COMBO_BT is not defined\n"); -+#endif -+ return i_ret; -+} -diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/common_drv_init.c b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/common_drv_init.c -new file mode 100644 -index 000000000000..f9c332ea266b ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/common_drv_init.c -@@ -0,0 +1,103 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -+ -+#ifdef DFT_TAG -+#undef DFT_TAG -+#endif -+#define DFT_TAG "[WMT-MOD-INIT]" -+ -+#include "wmt_detect.h" -+#include "common_drv_init.h" -+ -+static int do_combo_common_drv_init(int chip_id) -+{ -+ int i_ret = 0; -+ -+#ifdef MTK_WCN_COMBO_CHIP_SUPPORT -+ int i_ret_tmp = 0; -+ -+ WMT_DETECT_DBG_FUNC("start to do combo driver init, chipid:0x%08x\n", chip_id); -+ -+ /* HIF-SDIO driver init */ -+ i_ret_tmp = mtk_wcn_hif_sdio_drv_init(); -+ i_ret += i_ret_tmp; -+ WMT_DETECT_DBG_FUNC("HIF-SDIO driver init, i_ret:%d\n", i_ret); -+ -+ /* WMT driver init */ -+ i_ret_tmp = mtk_wcn_combo_common_drv_init(); -+ i_ret += i_ret_tmp; -+ WMT_DETECT_DBG_FUNC("COMBO COMMON driver init, i_ret:%d\n", i_ret); -+ -+ /* STP-UART driver init */ -+ i_ret_tmp = mtk_wcn_stp_uart_drv_init(); -+ i_ret += i_ret_tmp; -+ WMT_DETECT_DBG_FUNC("STP-UART driver init, i_ret:%d\n", i_ret); -+ -+ /* STP-SDIO driver init */ -+ i_ret_tmp = mtk_wcn_stp_sdio_drv_init(); -+ i_ret += i_ret_tmp; -+ WMT_DETECT_DBG_FUNC("STP-SDIO driver init, i_ret:%d\n", i_ret); -+ -+#else -+ i_ret = -1; -+ WMT_DETECT_ERR_FUNC("COMBO chip is not supported, please check CONFIG_MTK_COMBO_CHIP in kernel config\n"); -+#endif -+ WMT_DETECT_DBG_FUNC("finish combo driver init\n"); -+ return i_ret; -+} -+ -+static int do_soc_common_drv_init(int chip_id) -+{ -+ int i_ret = 0; -+ -+#ifdef MTK_WCN_SOC_CHIP_SUPPORT -+ int i_ret_tmp = 0; -+ -+ WMT_DETECT_DBG_FUNC("start to do soc common driver init, chipid:0x%08x\n", chip_id); -+ -+ /* WMT driver init */ -+ i_ret_tmp = mtk_wcn_soc_common_drv_init(); -+ i_ret += i_ret_tmp; -+ WMT_DETECT_DBG_FUNC("COMBO COMMON driver init, i_ret:%d\n", i_ret); -+ -+#else -+ i_ret = -1; -+ WMT_DETECT_ERR_FUNC("SOC chip is not supported, please check CONFIG_MTK_COMBO_CHIP in kernel config\n"); -+#endif -+ -+ WMT_DETECT_DBG_FUNC("TBD........\n"); -+ return i_ret; -+} -+ -+int do_common_drv_init(int chip_id) -+{ -+ int i_ret = 0; -+ -+ WMT_DETECT_INFO_FUNC("start to do common driver init, chipid:0x%08x\n", chip_id); -+ -+ switch (chip_id) { -+ case 0x6620: -+ case 0x6628: -+ case 0x6630: -+ i_ret = do_combo_common_drv_init(chip_id); -+ break; -+ default: -+ i_ret = do_soc_common_drv_init(chip_id); -+ break; -+ } -+ -+ WMT_DETECT_INFO_FUNC("finish common driver init\n"); -+ -+ return i_ret; -+} -diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/conn_drv_init.c b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/conn_drv_init.c -new file mode 100644 -index 000000000000..8112d2a1d95e ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/conn_drv_init.c -@@ -0,0 +1,80 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -+ -+#ifdef DFT_TAG -+#undef DFT_TAG -+#endif -+#define DFT_TAG "[WCN-MOD-INIT]" -+ -+#include "wmt_detect.h" -+#include "conn_drv_init.h" -+#include "common_drv_init.h" -+#include "fm_drv_init.h" -+#include "wlan_drv_init.h" -+#include "bluetooth_drv_init.h" -+#include "gps_drv_init.h" -+#include "ant_drv_init.h" -+ -+int __weak do_wlan_drv_init(int chip_id) -+{ -+ WMT_DETECT_ERR_FUNC("Can not find wlan module for chip: %d !\n", chip_id); -+ return 0; -+} -+ -+int __weak do_ant_drv_init(int chip_id) -+{ -+ WMT_DETECT_DBG_FUNC("Chip: %d can not support ANT !\n", chip_id); -+ return 0; -+} -+ -+int do_connectivity_driver_init(int chip_id) -+{ -+ int i_ret = 0; -+ int tmp_ret = 0; -+ -+ tmp_ret = do_common_drv_init(chip_id); -+ i_ret += tmp_ret; -+ if (tmp_ret) { -+ WMT_DETECT_ERR_FUNC("do common driver init failed, ret:%d\n", tmp_ret); -+ WMT_DETECT_ERR_FUNC("abort connectivity driver init, because common part is not ready\n"); -+ return i_ret; -+ } -+ -+ tmp_ret = do_bluetooth_drv_init(chip_id); -+ i_ret += tmp_ret; -+ if (tmp_ret) -+ WMT_DETECT_ERR_FUNC("do common driver init failed, ret:%d\n", tmp_ret); -+ -+ tmp_ret = do_gps_drv_init(chip_id); -+ i_ret += tmp_ret; -+ if (tmp_ret) -+ WMT_DETECT_ERR_FUNC("do common driver init failed, ret:%d\n", tmp_ret); -+ -+ tmp_ret = do_fm_drv_init(chip_id); -+ i_ret += tmp_ret; -+ if (tmp_ret) -+ WMT_DETECT_ERR_FUNC("do fm module init failed, ret:%d\n", tmp_ret); -+ -+ tmp_ret = do_wlan_drv_init(chip_id); -+ i_ret += tmp_ret; -+ if (tmp_ret) -+ WMT_DETECT_ERR_FUNC("do wlan module init failed, ret:%d\n", tmp_ret); -+ -+ tmp_ret = do_ant_drv_init(chip_id); -+ i_ret += tmp_ret; -+ if (tmp_ret) -+ WMT_DETECT_ERR_FUNC("do ANT module init failed, ret:%d\n", tmp_ret); -+ -+ return i_ret; -+} -diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/fm_drv_init.c b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/fm_drv_init.c -new file mode 100644 -index 000000000000..069c1cf13bba ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/fm_drv_init.c -@@ -0,0 +1,33 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -+ -+#ifdef DFT_TAG -+#undef DFT_TAG -+#endif -+#define DFT_TAG "[FM-MOD-INIT]" -+ -+#include "wmt_detect.h" -+#include "fm_drv_init.h" -+ -+int do_fm_drv_init(int chip_id) -+{ -+ WMT_DETECT_INFO_FUNC("start to do fm module init\n"); -+ -+#ifdef CONFIG_MTK_FMRADIO -+ mtk_wcn_fm_init(); -+#endif -+ -+ WMT_DETECT_INFO_FUNC("finish fm module init\n"); -+ return 0; -+} -diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/gps_drv_init.c b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/gps_drv_init.c -new file mode 100644 -index 000000000000..6da1d70a3ca6 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/gps_drv_init.c -@@ -0,0 +1,35 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -+ -+#ifdef DFT_TAG -+#undef DFT_TAG -+#endif -+#define DFT_TAG "[GPS-MOD-INIT]" -+ -+#include "wmt_detect.h" -+#include "gps_drv_init.h" -+ -+int do_gps_drv_init(int chip_id) -+{ -+ int i_ret = -1; -+#ifdef CONFIG_MTK_COMBO_GPS -+ WMT_DETECT_INFO_FUNC("start to do gps driver init\n"); -+ i_ret = mtk_wcn_stpgps_drv_init(); -+ WMT_DETECT_INFO_FUNC("finish gps driver init, i_ret:%d\n", i_ret); -+#else -+ WMT_DETECT_INFO_FUNC("CONFIG_MTK_COMBO_GPS is not defined\n"); -+#endif -+ return i_ret; -+ -+} -diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/ant_drv_init.h b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/ant_drv_init.h -new file mode 100644 -index 000000000000..4a436a236290 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/ant_drv_init.h -@@ -0,0 +1,20 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -+ -+#ifndef _ANT_DRIVER_INIT_H_ -+#define _ANT_DRIVER_INIT_H_ -+ -+extern int do_ant_drv_init(int chip_id); -+extern int mtk_wcn_stpant_drv_init(void); -+#endif -diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/bluetooth_drv_init.h b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/bluetooth_drv_init.h -new file mode 100644 -index 000000000000..8a847d361fc8 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/bluetooth_drv_init.h -@@ -0,0 +1,20 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -+ -+#ifndef _BLUETOOTH_DRIVER_INIT_H_ -+#define _BLUETOOTH_DRIVER_INIT_H_ -+ -+extern int do_bluetooth_drv_init(int chip_id); -+extern int mtk_wcn_stpbt_drv_init(void); -+#endif -diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/common_drv_init.h b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/common_drv_init.h -new file mode 100644 -index 000000000000..ea01bd633c3c ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/common_drv_init.h -@@ -0,0 +1,31 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -+ -+#ifndef _COMMON_DRV_INIT_H_ -+#define _COMMON_DRV_INIT_H_ -+extern int do_common_drv_init(int chip_id); -+ -+/*defined in common part driver*/ -+#ifdef MTK_WCN_COMBO_CHIP_SUPPORT -+extern int mtk_wcn_combo_common_drv_init(void); -+extern int mtk_wcn_hif_sdio_drv_init(void); -+extern int mtk_wcn_stp_uart_drv_init(void); -+extern int mtk_wcn_stp_sdio_drv_init(void); -+#endif -+ -+#ifdef MTK_WCN_SOC_CHIP_SUPPORT -+extern int mtk_wcn_soc_common_drv_init(void); -+#endif -+ -+#endif -diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/conn_drv_init.h b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/conn_drv_init.h -new file mode 100644 -index 000000000000..971193eade9e ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/conn_drv_init.h -@@ -0,0 +1,18 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -+ -+#ifndef _CONNECTIVITY_DRV_INIT_H_ -+#define _CONNECTIVITY_DRV_INIT_H_ -+extern int do_connectivity_driver_init(int chip_id); -+#endif -diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/fm_drv_init.h b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/fm_drv_init.h -new file mode 100644 -index 000000000000..f6ea30addc5d ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/fm_drv_init.h -@@ -0,0 +1,20 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -+ -+#ifndef _FM_DRV_INIT_H_ -+#define _FM_DRV_INIT_H_ -+extern int do_fm_drv_init(int chip_id); -+extern int mtk_wcn_fm_init(void); -+extern void mtk_wcn_fm_exit(void); -+#endif -diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/gps_drv_init.h b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/gps_drv_init.h -new file mode 100644 -index 000000000000..006ce072c53b ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/gps_drv_init.h -@@ -0,0 +1,19 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -+ -+#ifndef _GPS_DRIVER_INIT_H_ -+#define _GPS_DRIVER_INIT_H_ -+extern int do_gps_drv_init(int chip_id); -+extern int mtk_wcn_stpgps_drv_init(void); -+#endif -diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/wlan_drv_init.h b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/wlan_drv_init.h -new file mode 100644 -index 000000000000..cb71b50bf950 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/inc/wlan_drv_init.h -@@ -0,0 +1,30 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -+ -+#ifndef _WLAN_DRV_INIT_H_ -+#define _WLAN_DRV_INIT_H_ -+ -+ -+extern int do_wlan_drv_init(int chip_id); -+ -+extern int mtk_wcn_wmt_wifi_init(void); -+ -+#ifdef MTK_WCN_WLAN_GEN2 -+extern int mtk_wcn_wlan_gen2_init(void); -+#endif -+#ifdef MTK_WCN_WLAN_GEN3 -+extern int mtk_wcn_wlan_gen3_init(void); -+#endif -+ -+#endif -diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/wlan_drv_init.c b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/wlan_drv_init.c -new file mode 100644 -index 000000000000..5b0d039a4a42 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/wlan_drv_init.c -@@ -0,0 +1,74 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -+ -+#ifdef DFT_TAG -+#undef DFT_TAG -+#endif -+#define DFT_TAG "[WLAN-MOD-INIT]" -+ -+#include "wmt_detect.h" -+#include "wlan_drv_init.h" -+ -+ -+int do_wlan_drv_init(int chip_id) -+{ -+ int i_ret = 0; -+ -+#ifdef CONFIG_MTK_COMBO_WIFI -+ int ret = 0; -+ -+ WMT_DETECT_INFO_FUNC("start to do wlan module init 0x%x\n", chip_id); -+ -+ /* WMT-WIFI char dev init */ -+ ret = mtk_wcn_wmt_wifi_init(); -+ WMT_DETECT_INFO_FUNC("WMT-WIFI char dev init, ret:%d\n", ret); -+ i_ret += ret; -+ -+ switch (chip_id) { -+ case 0x6630: -+ case 0x6797: -+#ifdef MTK_WCN_WLAN_GEN3 -+ /* WLAN driver init */ -+ ret = mtk_wcn_wlan_gen3_init(); -+ WMT_DETECT_INFO_FUNC("WLAN-GEN3 driver init, ret:%d\n", ret); -+ i_ret += ret; -+#else -+ WMT_DETECT_ERR_FUNC("WLAN-GEN3 driver is not supported, please check CONFIG_MTK_COMBO_CHIP\n"); -+ i_ret = -1; -+#endif -+ break; -+ -+ default: -+#ifdef MTK_WCN_WLAN_GEN2 -+ /* WLAN driver init */ -+ ret = mtk_wcn_wlan_gen2_init(); -+ WMT_DETECT_INFO_FUNC("WLAN-GEN2 driver init, ret:%d\n", ret); -+ i_ret += ret; -+#else -+ WMT_DETECT_ERR_FUNC("WLAN-GEN2 driver is not supported, please check CONFIG_MTK_COMBO_CHIP\n"); -+ i_ret = -1; -+#endif -+ break; -+ } -+ -+ WMT_DETECT_INFO_FUNC("finish wlan module init\n"); -+ -+#else -+ -+ WMT_DETECT_INFO_FUNC("CONFIG_MTK_COMBO_WIFI is not defined\n"); -+ -+#endif -+ -+ return i_ret; -+} -diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/mtk_wcn_stub_alps.c b/drivers/misc/mediatek/connectivity/common/common_detect/mtk_wcn_stub_alps.c -new file mode 100644 -index 000000000000..fa8d437686f2 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/common_detect/mtk_wcn_stub_alps.c -@@ -0,0 +1,605 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -+ -+/*! \file -+ \brief Declaration of library functions -+ -+ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+#define CMB_STUB_DBG_LOG 3 -+#define CMB_STUB_INFO_LOG 2 -+#define CMB_STUB_WARN_LOG 1 -+ -+int gCmbStubLogLevel = CMB_STUB_INFO_LOG; -+ -+#define CMB_STUB_LOG_INFO(fmt, arg...) \ -+do { \ -+ if (gCmbStubLogLevel >= CMB_STUB_INFO_LOG) \ -+ pr_warn(fmt, ##arg); \ -+} while (0) -+#define CMB_STUB_LOG_WARN(fmt, arg...) \ -+do { \ -+ if (gCmbStubLogLevel >= CMB_STUB_WARN_LOG) \ -+ pr_warn(fmt, ##arg); \ -+} while (0) -+#define CMB_STUB_LOG_DBG(fmt, arg...) \ -+do { \ -+ if (gCmbStubLogLevel >= CMB_STUB_DBG_LOG) \ -+ pr_debug(fmt, ##arg); \ -+} while (0) -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include "wmt_detect.h" -+ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+#ifndef MTK_WCN_CMB_FOR_SDIO_1V_AUTOK -+#define MTK_WCN_CMB_FOR_SDIO_1V_AUTOK 0 -+#endif -+ -+#if MTK_WCN_CMB_FOR_SDIO_1V_AUTOK -+struct work_struct *g_sdio_1v_autok_wk = NULL; -+#endif -+int gConnectivityChipId = -1; -+ -+#ifdef MTK_WCN_COMBO_CHIP_SUPPORT -+/* -+* current used uart port name, default is "ttyMT2", -+* will be changed when wmt driver init -+*/ -+char *wmt_uart_port_desc = "ttyMT2"; -+EXPORT_SYMBOL(wmt_uart_port_desc); -+#endif -+ -+static void mtk_wcn_cmb_sdio_request_eirq(msdc_sdio_irq_handler_t irq_handler, void *data); -+static void mtk_wcn_cmb_sdio_enable_eirq(void); -+static void mtk_wcn_cmb_sdio_disable_eirq(void); -+static void mtk_wcn_cmb_sdio_register_pm(pm_callback_t pm_cb, void *data); -+ -+struct sdio_ops mt_sdio_ops[4] = { -+ {NULL, NULL, NULL, NULL}, -+ {NULL, NULL, NULL, NULL}, -+ {mtk_wcn_cmb_sdio_request_eirq, mtk_wcn_cmb_sdio_enable_eirq, -+ mtk_wcn_cmb_sdio_disable_eirq, mtk_wcn_cmb_sdio_register_pm}, -+ {mtk_wcn_cmb_sdio_request_eirq, mtk_wcn_cmb_sdio_enable_eirq, -+ mtk_wcn_cmb_sdio_disable_eirq, mtk_wcn_cmb_sdio_register_pm} -+}; -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+static wmt_aif_ctrl_cb cmb_stub_aif_ctrl_cb; -+static wmt_func_ctrl_cb cmb_stub_func_ctrl_cb; -+static wmt_thermal_query_cb cmb_stub_thermal_ctrl_cb; -+static CMB_STUB_AIF_X cmb_stub_aif_stat = CMB_STUB_AIF_0; -+static wmt_deep_idle_ctrl_cb cmb_stub_deep_idle_ctrl_cb; -+#if MTK_WCN_CMB_FOR_SDIO_1V_AUTOK -+static wmt_get_drv_status cmb_stub_drv_status_ctrl_cb; -+#endif -+static wmt_func_do_reset cmb_stub_do_reset_cb; -+/* A temp translation table between COMBO_AUDIO_STATE_X and CMB_STUB_AIF_X. -+ * This is used for ALPS backward compatible ONLY!!! Remove this table, related -+ * functions, and type definition after modifying other kernel built-in modules, -+ * such as AUDIO. [FixMe][GeorgeKuo] -+ */ -+#if 0 -+static CMB_STUB_AIF_X audio2aif[] = { -+ [COMBO_AUDIO_STATE_0] = CMB_STUB_AIF_0, -+ [COMBO_AUDIO_STATE_1] = CMB_STUB_AIF_1, -+ [COMBO_AUDIO_STATE_2] = CMB_STUB_AIF_2, -+ [COMBO_AUDIO_STATE_3] = CMB_STUB_AIF_3, -+}; -+#endif -+static msdc_sdio_irq_handler_t mtk_wcn_cmb_sdio_eirq_handler; -+static atomic_t sdio_claim_irq_enable_flag; -+static atomic_t irq_enable_flag; -+static pm_callback_t mtk_wcn_cmb_sdio_pm_cb; -+static void *mtk_wcn_cmb_sdio_pm_data; -+static void *mtk_wcn_cmb_sdio_eirq_data; -+ -+static u32 wifi_irq = 0xffffffff; -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+#if MTK_WCN_CMB_FOR_SDIO_1V_AUTOK -+static void mtk_wcn_cmb_stub_1v_autok_work(struct work_struct *work) -+{ -+ CMB_STUB_LOG_WARN("++enter++\n"); -+ mtk_wcn_cmb_stub_func_ctrl(11, 1); -+ mtk_wcn_cmb_stub_func_ctrl(11, 0); -+ CMB_STUB_LOG_WARN("--exit--\n"); -+} -+ -+/*! -+ * \brief A function for Getting current driver status:on/off -+ * -+ * \param driver type:0/bt,1/fm,2/gps,3/wifi,11/autok->run wmt turn on/off wifi flow -+ * -+ * \retval 0/off,2/on,-1/null pointer -+ */ -+static int mtk_wcn_cmb_stub_drv_status(unsigned int type) -+{ -+ int ret = -1; -+ -+ if (cmb_stub_drv_status_ctrl_cb) -+ ret = (*cmb_stub_drv_status_ctrl_cb) (type); -+ else -+ CMB_STUB_LOG_WARN("cmb_stub_drv_status_ctrl_cb is NULL\n"); -+ return ret; -+} -+ -+/*! -+ * \brief A 1v AutoK function for kernel DVFS driver calling when screen off -+ * -+ * \param void -+ * -+ * \retval int,mt6630 state:0/off,1/power on,2/func on, -1/null -+ */ -+int mtk_wcn_cmb_stub_1vautok_for_dvfs(void) -+{ -+ int wmt_status; -+ -+ CMB_STUB_LOG_WARN("DVFS driver call sdio 1v autok\n"); -+ -+ wmt_status = mtk_wcn_cmb_stub_drv_status(4); -+ CMB_STUB_LOG_WARN("current mt6630 status is %d\n", wmt_status); -+ if (0 == wmt_status) { -+ if (g_sdio_1v_autok_wk) -+ schedule_work(g_sdio_1v_autok_wk); -+ else -+ CMB_STUB_LOG_WARN("g_sdio_1v_autok_wk is NULL\n"); -+ } else if ((2 == wmt_status) || (1 == wmt_status)) { -+ CMB_STUB_LOG_WARN("mt6630 is on state,skip AUTOK\n"); -+ } else { -+ CMB_STUB_LOG_WARN("mt6630 is unknown state(%d)\n", wmt_status); -+ } -+ -+ return wmt_status; -+ -+} -+#endif -+/*! -+ * \brief A registration function for WMT-PLAT to register itself to CMB-STUB. -+ * -+ * An MTK-WCN-CMB-STUB registration function provided to WMT-PLAT to register -+ * itself and related callback functions when driver being loaded into kernel. -+ * -+ * \param p_stub_cb a pointer carrying CMB_STUB_CB information -+ * -+ * \retval 0 operation success -+ * \retval -1 invalid parameters -+ */ -+int mtk_wcn_cmb_stub_reg(P_CMB_STUB_CB p_stub_cb) -+{ -+ if ((!p_stub_cb) -+ || (p_stub_cb->size != sizeof(CMB_STUB_CB))) { -+ CMB_STUB_LOG_WARN("[cmb_stub] invalid p_stub_cb:0x%p size(%d)\n", -+ p_stub_cb, (p_stub_cb) ? p_stub_cb->size : 0); -+ return -1; -+ } -+ -+ CMB_STUB_LOG_DBG("[cmb_stub] registered, p_stub_cb:0x%p size(%d)\n", p_stub_cb, p_stub_cb->size); -+ -+ cmb_stub_aif_ctrl_cb = p_stub_cb->aif_ctrl_cb; -+ cmb_stub_func_ctrl_cb = p_stub_cb->func_ctrl_cb; -+ cmb_stub_thermal_ctrl_cb = p_stub_cb->thermal_query_cb; -+ cmb_stub_deep_idle_ctrl_cb = p_stub_cb->deep_idle_ctrl_cb; -+ cmb_stub_do_reset_cb = p_stub_cb->wmt_do_reset_cb; -+#if MTK_WCN_CMB_FOR_SDIO_1V_AUTOK -+ cmb_stub_drv_status_ctrl_cb = p_stub_cb->get_drv_status_cb; -+ g_sdio_1v_autok_wk = vmalloc(sizeof(struct work_struct)); -+ if (!g_sdio_1v_autok_wk) -+ CMB_STUB_LOG_WARN("vmalloc work_struct(%zd) fail\n", sizeof(struct work_struct)); -+ else -+ INIT_WORK(g_sdio_1v_autok_wk, mtk_wcn_cmb_stub_1v_autok_work); -+ -+#endif -+ -+ return 0; -+} -+EXPORT_SYMBOL(mtk_wcn_cmb_stub_reg); -+/*! -+ * \brief A unregistration function for WMT-PLAT to unregister from CMB-STUB. -+ * -+ * An MTK-WCN-CMB-STUB unregistration function provided to WMT-PLAT to -+ * unregister itself and clear callback function references. -+ * -+ * \retval 0 operation success -+ */ -+int mtk_wcn_cmb_stub_unreg(void) -+{ -+ cmb_stub_aif_ctrl_cb = NULL; -+ cmb_stub_func_ctrl_cb = NULL; -+ cmb_stub_thermal_ctrl_cb = NULL; -+ cmb_stub_deep_idle_ctrl_cb = NULL; -+ cmb_stub_do_reset_cb = NULL; -+ CMB_STUB_LOG_INFO("[cmb_stub] unregistered\n"); /* KERN_DEBUG */ -+ -+#if MTK_WCN_CMB_FOR_SDIO_1V_AUTOK -+ if (g_sdio_1v_autok_wk) { -+ vfree(g_sdio_1v_autok_wk); -+ g_sdio_1v_autok_wk = NULL; -+ } -+#endif -+ -+ return 0; -+} -+EXPORT_SYMBOL(mtk_wcn_cmb_stub_unreg); -+ -+/* stub functions for kernel to control audio path pin mux */ -+int mtk_wcn_cmb_stub_aif_ctrl(CMB_STUB_AIF_X state, CMB_STUB_AIF_CTRL ctrl) -+{ -+ int ret; -+ -+ if ((CMB_STUB_AIF_MAX <= state) -+ || (CMB_STUB_AIF_CTRL_MAX <= ctrl)) { -+ -+ CMB_STUB_LOG_WARN("[cmb_stub] aif_ctrl invalid (%d, %d)\n", state, ctrl); -+ return -1; -+ } -+ -+ /* avoid the early interrupt before we register the eirq_handler */ -+ if (cmb_stub_aif_ctrl_cb) { -+ ret = (*cmb_stub_aif_ctrl_cb) (state, ctrl); -+ CMB_STUB_LOG_INFO("[cmb_stub] aif_ctrl_cb state(%d->%d) ctrl(%d) ret(%d)\n", -+ cmb_stub_aif_stat, state, ctrl, ret); /* KERN_DEBUG */ -+ -+ cmb_stub_aif_stat = state; -+ } else { -+ CMB_STUB_LOG_WARN("[cmb_stub] aif_ctrl_cb null\n"); -+ ret = -2; -+ } -+ return ret; -+} -+EXPORT_SYMBOL(mtk_wcn_cmb_stub_aif_ctrl); -+ -+/* Use a temp translation table between COMBO_AUDIO_STATE_X and CMB_STUB_AIF_X -+ * for ALPS backward compatible ONLY!!! Remove this table, related functions, -+ * and type definition after modifying other kernel built-in modules, such as -+ * AUDIO. [FixMe][GeorgeKuo] -+ */ -+ -+void mtk_wcn_cmb_stub_func_ctrl(unsigned int type, unsigned int on) -+{ -+ if (cmb_stub_func_ctrl_cb) -+ (*cmb_stub_func_ctrl_cb) (type, on); -+ else -+ CMB_STUB_LOG_WARN("[cmb_stub] func_ctrl_cb null\n"); -+} -+EXPORT_SYMBOL(mtk_wcn_cmb_stub_func_ctrl); -+ -+int mtk_wcn_cmb_stub_query_ctrl(void) -+{ -+ signed long temp = 0; -+ -+ if (cmb_stub_thermal_ctrl_cb) -+ temp = (*cmb_stub_thermal_ctrl_cb) (); -+ else -+ CMB_STUB_LOG_WARN("[cmb_stub] thermal_ctrl_cb null\n"); -+ -+ return temp; -+} -+ -+/*platform-related APIs*/ -+/* void clr_device_working_ability(UINT32 clockId, MT6573_STATE state); */ -+/* void set_device_working_ability(UINT32 clockId, MT6573_STATE state); */ -+ -+static int _mt_combo_plt_do_deep_idle(COMBO_IF src, int enter) -+{ -+ int ret = -1; -+ -+#if 0 -+ if (src != COMBO_IF_UART && src != COMBO_IF_MSDC && src != COMBO_IF_BTIF) { -+ CMB_STUB_LOG_WARN("src = %d is error\n", src); -+ return ret; -+ } -+ if (src >= 0 && src < COMBO_IF_MAX) -+ CMB_STUB_LOG_INFO("src = %s, to enter deep idle? %d\n", combo_if_name[src], enter); -+#endif -+ /*TODO: For Common SDIO configuration, we need to do some judgement between STP and WIFI -+ to decide if the msdc will enter deep idle safely */ -+ -+ switch (src) { -+ case COMBO_IF_UART: -+ if (enter == 0) { -+ /* clr_device_working_ability(MT65XX_PDN_PERI_UART3, DEEP_IDLE_STATE); */ -+ /* disable_dpidle_by_bit(MT65XX_PDN_PERI_UART2); */ -+#ifdef MTK_WCN_COMBO_CHIP_SUPPORT -+#if 0 -+ ret = mtk_uart_pdn_enable(wmt_uart_port_desc, 0); -+ if (ret < 0) -+ CMB_STUB_LOG_WARN("[CMB] %s exit deep idle failed\n", wmt_uart_port_desc); -+#endif -+#endif -+ } else { -+ /* set_device_working_ability(MT65XX_PDN_PERI_UART3, DEEP_IDLE_STATE); */ -+ /* enable_dpidle_by_bit(MT65XX_PDN_PERI_UART2); */ -+#ifdef MTK_WCN_COMBO_CHIP_SUPPORT -+#if 0 -+ ret = mtk_uart_pdn_enable(wmt_uart_port_desc, 1); -+ if (ret < 0) -+ CMB_STUB_LOG_WARN("[CMB] %s enter deep idle failed\n", wmt_uart_port_desc); -+#endif -+#endif -+ } -+ ret = 0; -+ break; -+ -+ case COMBO_IF_MSDC: -+ if (enter == 0) { -+ /* for common sdio hif */ -+ /* clr_device_working_ability(MT65XX_PDN_PERI_MSDC2, DEEP_IDLE_STATE); */ -+ } else { -+ /* for common sdio hif */ -+ /* set_device_working_ability(MT65XX_PDN_PERI_MSDC2, DEEP_IDLE_STATE); */ -+ } -+ ret = 0; -+ break; -+ -+ case COMBO_IF_BTIF: -+ if (cmb_stub_deep_idle_ctrl_cb) -+ ret = (*cmb_stub_deep_idle_ctrl_cb) (enter); -+ else -+ CMB_STUB_LOG_WARN("NULL function pointer\n"); -+ -+ if (ret) -+ CMB_STUB_LOG_WARN("%s deep idle fail(%d)\n", enter == 1 ? "enter" : "exit", ret); -+ else -+ CMB_STUB_LOG_DBG("%s deep idle ok(%d)\n", enter == 1 ? "enter" : "exit", ret); -+ break; -+ default: -+ break; -+ } -+ -+ return ret; -+} -+ -+int mt_combo_plt_enter_deep_idle(COMBO_IF src) -+{ -+ /* return 0; */ -+ /* TODO: [FixMe][GeorgeKuo] handling this depends on common UART or common SDIO */ -+ return _mt_combo_plt_do_deep_idle(src, 1); -+} -+EXPORT_SYMBOL(mt_combo_plt_enter_deep_idle); -+ -+int mt_combo_plt_exit_deep_idle(COMBO_IF src) -+{ -+ /* return 0; */ -+ /* TODO: [FixMe][GeorgeKuo] handling this depends on common UART or common SDIO */ -+ return _mt_combo_plt_do_deep_idle(src, 0); -+} -+EXPORT_SYMBOL(mt_combo_plt_exit_deep_idle); -+ -+int mtk_wcn_wmt_chipid_query(void) -+{ -+ return gConnectivityChipId; -+} -+EXPORT_SYMBOL(mtk_wcn_wmt_chipid_query); -+ -+void mtk_wcn_wmt_set_chipid(int chipid) -+{ -+ CMB_STUB_LOG_INFO("set current consys chipid (0x%x)\n", chipid); -+ gConnectivityChipId = chipid; -+} -+EXPORT_SYMBOL(mtk_wcn_wmt_set_chipid); -+ -+int mtk_wcn_cmb_stub_do_reset(unsigned int type) -+{ -+ if (cmb_stub_do_reset_cb) -+ return (*cmb_stub_do_reset_cb) (type); -+ else -+ return -1; -+} -+EXPORT_SYMBOL(mtk_wcn_cmb_stub_do_reset); -+ -+static void mtk_wcn_cmb_sdio_enable_eirq(void) -+{ -+ if (atomic_read(&irq_enable_flag)) -+ CMB_STUB_LOG_DBG("wifi eint has been enabled\n"); -+ else { -+ atomic_set(&irq_enable_flag, 1); -+ if (wifi_irq != 0xfffffff) { -+ enable_irq(wifi_irq); -+ CMB_STUB_LOG_DBG(" enable WIFI EINT irq %d !!\n", wifi_irq); -+ } -+ } -+} -+ -+static void mtk_wcn_cmb_sdio_disable_eirq(void) -+{ -+ if (!atomic_read(&irq_enable_flag)) -+ CMB_STUB_LOG_DBG("wifi eint has been disabled!\n"); -+ else { -+ if (wifi_irq != 0xfffffff) { -+ disable_irq_nosync(wifi_irq); -+ CMB_STUB_LOG_DBG("disable WIFI EINT irq %d !!\n", wifi_irq); -+ } -+ atomic_set(&irq_enable_flag, 0); -+ } -+} -+ -+irqreturn_t mtk_wcn_cmb_sdio_eirq_handler_stub(int irq, void *data) -+{ -+ if ((NULL != mtk_wcn_cmb_sdio_eirq_handler)&&(0 != atomic_read(&sdio_claim_irq_enable_flag))) -+ mtk_wcn_cmb_sdio_eirq_handler(mtk_wcn_cmb_sdio_eirq_data); -+ return IRQ_HANDLED; -+} -+ -+static void mtk_wcn_cmb_sdio_request_eirq(msdc_sdio_irq_handler_t irq_handler, void *data) -+{ -+ struct device_node *node; -+ int ret = -EINVAL; -+#if 0 -+ unsigned int gpio_wifi_eint_pin; -+#endif -+ -+ CMB_STUB_LOG_INFO("enter %s\n", __func__); -+ mtk_wcn_sdio_irq_flag_set(0); -+ atomic_set(&irq_enable_flag, 0); -+ mtk_wcn_cmb_sdio_eirq_data = data; -+ mtk_wcn_cmb_sdio_eirq_handler = irq_handler; -+ -+ node = (struct device_node *)of_find_compatible_node(NULL, NULL, "mediatek,connectivity-combo"); -+ if (node) { -+#if 0 -+ gpio_wifi_eint_pin = of_get_gpio(node, 5); -+ CMB_STUB_LOG_INFO("WIFI EINT pin %d !!\n", gpio_wifi_eint_pin); -+ wifi_irq = gpio_to_irq(gpio_wifi_eint_pin); -+#else -+ wifi_irq = irq_of_parse_and_map(node, 0);/* get wifi eint num */ -+#endif -+#if 1 -+ ret = request_irq(wifi_irq, mtk_wcn_cmb_sdio_eirq_handler_stub, IRQF_TRIGGER_LOW, -+ "WIFI-eint", NULL); -+ CMB_STUB_LOG_DBG("WIFI EINT irq %d !!\n", wifi_irq); -+#endif -+ -+ if (ret) -+ CMB_STUB_LOG_WARN("WIFI EINT IRQ LINE NOT AVAILABLE!!\n"); -+ else -+ mtk_wcn_cmb_sdio_disable_eirq();/*not ,chip state is power off*/ -+ } else -+ CMB_STUB_LOG_WARN("[%s] can't find connectivity compatible node\n", __func__); -+ -+ CMB_STUB_LOG_INFO("exit %s\n", __func__); -+} -+ -+static void mtk_wcn_cmb_sdio_register_pm(pm_callback_t pm_cb, void *data) -+{ -+ CMB_STUB_LOG_DBG("mtk_wcn_cmb_sdio_register_pm (0x%p, 0x%p)\n", pm_cb, data); -+ /* register pm change callback */ -+ mtk_wcn_cmb_sdio_pm_cb = pm_cb; -+ mtk_wcn_cmb_sdio_pm_data = data; -+} -+ -+static void mtk_wcn_cmb_sdio_on(int sdio_port_num) -+{ -+ pm_message_t state = {.event = PM_EVENT_USER_RESUME }; -+ -+ CMB_STUB_LOG_INFO("mtk_wcn_cmb_sdio_on (%d)\n", sdio_port_num); -+ -+ /* 1. disable sdio eirq */ -+ mtk_wcn_cmb_sdio_disable_eirq(); -+ -+ /* 2. call sd callback */ -+ if (mtk_wcn_cmb_sdio_pm_cb) { -+ /* pr_warn("mtk_wcn_cmb_sdio_pm_cb(PM_EVENT_USER_RESUME, 0x%p, 0x%p)\n", -+ * mtk_wcn_cmb_sdio_pm_cb, mtk_wcn_cmb_sdio_pm_data); */ -+ mtk_wcn_cmb_sdio_pm_cb(state, mtk_wcn_cmb_sdio_pm_data); -+ } else -+ CMB_STUB_LOG_WARN("mtk_wcn_cmb_sdio_on no sd callback!!\n"); -+} -+ -+static void mtk_wcn_cmb_sdio_off(int sdio_port_num) -+{ -+ pm_message_t state = {.event = PM_EVENT_USER_SUSPEND }; -+ -+ CMB_STUB_LOG_INFO("mtk_wcn_cmb_sdio_off (%d)\n", sdio_port_num); -+ -+ /* 1. call sd callback */ -+ if (mtk_wcn_cmb_sdio_pm_cb) { -+ /* pr_warn("mtk_wcn_cmb_sdio_off(PM_EVENT_USER_SUSPEND, 0x%p, 0x%p)\n", -+ * mtk_wcn_cmb_sdio_pm_cb, mtk_wcn_cmb_sdio_pm_data); */ -+ mtk_wcn_cmb_sdio_pm_cb(state, mtk_wcn_cmb_sdio_pm_data); -+ } else -+ CMB_STUB_LOG_WARN("mtk_wcn_cmb_sdio_off no sd callback!!\n"); -+ -+ /* 2. disable sdio eirq */ -+ mtk_wcn_cmb_sdio_disable_eirq(); -+} -+ -+int board_sdio_ctrl(unsigned int sdio_port_num, unsigned int on) -+{ -+ CMB_STUB_LOG_DBG("mt_mtk_wcn_cmb_sdio_ctrl (%d, %d)\n", sdio_port_num, on); -+ if (on) { -+#if 1 -+ CMB_STUB_LOG_DBG("board_sdio_ctrl force off before on\n"); -+ mtk_wcn_cmb_sdio_off(sdio_port_num); -+#else -+ CMB_STUB_LOG_WARN("skip sdio off before on\n"); -+#endif -+ /* off -> on */ -+ mtk_wcn_cmb_sdio_on(sdio_port_num); -+ if (wifi_irq != 0xfffffff) -+ irq_set_irq_wake(wifi_irq, 1); -+ else -+ CMB_STUB_LOG_WARN("wifi_irq is not available\n"); -+ } else { -+ if (wifi_irq != 0xfffffff) -+ irq_set_irq_wake(wifi_irq, 0); -+ else -+ CMB_STUB_LOG_WARN("wifi_irq is not available\n"); -+ /* on -> off */ -+ mtk_wcn_cmb_sdio_off(sdio_port_num); -+ } -+ -+ return 0; -+} -+EXPORT_SYMBOL(board_sdio_ctrl); -+ -+int mtk_wcn_sdio_irq_flag_set(int flag) -+{ -+ if (0 != flag) -+ atomic_set(&sdio_claim_irq_enable_flag, 1); -+ else -+ atomic_set(&sdio_claim_irq_enable_flag, 0); -+ -+ CMB_STUB_LOG_DBG("sdio_claim_irq_enable_flag:%d\n", atomic_read(&sdio_claim_irq_enable_flag)); -+ -+ return atomic_read(&sdio_claim_irq_enable_flag); -+} -+EXPORT_SYMBOL(mtk_wcn_sdio_irq_flag_set); -diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/sdio_detect.c b/drivers/misc/mediatek/connectivity/common/common_detect/sdio_detect.c -new file mode 100644 -index 000000000000..7ac5ac73ef5d ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/common_detect/sdio_detect.c -@@ -0,0 +1,269 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -+ -+#ifdef DFT_TAG -+#undef DFT_TAG -+#endif -+#define DFT_TAG "[SDIO-DETECT]" -+ -+#include "wmt_detect.h" -+ -+#if MTK_HIF_SDIO_AUTOK_ENABLED -+#include -+#endif -+ -+unsigned int gComboChipId = -1; -+struct sdio_func *g_func = NULL; -+ -+MTK_WCN_HIF_SDIO_CHIP_INFO gChipInfoArray[] = { -+ /* MT6620 *//* Not an SDIO standard class device */ -+ {{SDIO_DEVICE(0x037A, 0x020A)}, 0x6620}, /* SDIO1:FUNC1:WIFI */ -+ {{SDIO_DEVICE(0x037A, 0x020B)}, 0x6620}, /* SDIO2:FUNC1:BT+FM+GPS */ -+ {{SDIO_DEVICE(0x037A, 0x020C)}, 0x6620}, /* 2-function (SDIO2:FUNC1:BT+FM+GPS, FUNC2:WIFI) */ -+ -+ /* MT6628 *//* SDIO1: Wi-Fi, SDIO2: BGF */ -+ {{SDIO_DEVICE(0x037A, 0x6628)}, 0x6628}, -+ -+ /* MT6630 *//* SDIO1: Wi-Fi, SDIO2: BGF */ -+ {{SDIO_DEVICE(0x037A, 0x6630)}, 0x6630}, -+ -+}; -+ -+/* Supported SDIO device table */ -+static const struct sdio_device_id mtk_sdio_id_tbl[] = { -+ /* MT6618 *//* Not an SDIO standard class device */ -+ {SDIO_DEVICE(0x037A, 0x018A)}, /* SDIO1:WIFI */ -+ {SDIO_DEVICE(0x037A, 0x018B)}, /* SDIO2:FUNC1:BT+FM */ -+ {SDIO_DEVICE(0x037A, 0x018C)}, /* 2-function (SDIO2:FUNC1:BT+FM, FUNC2:WIFI) */ -+ -+ /* MT6619 *//* Not an SDIO standard class device */ -+ {SDIO_DEVICE(0x037A, 0x6619)}, /* SDIO2:FUNC1:BT+FM+GPS */ -+ -+ /* MT6620 *//* Not an SDIO standard class device */ -+ {SDIO_DEVICE(0x037A, 0x020A)}, /* SDIO1:FUNC1:WIFI */ -+ {SDIO_DEVICE(0x037A, 0x020B)}, /* SDIO2:FUNC1:BT+FM+GPS */ -+ {SDIO_DEVICE(0x037A, 0x020C)}, /* 2-function (SDIO2:FUNC1:BT+FM+GPS, FUNC2:WIFI) */ -+ -+ /* MT5921 *//* Not an SDIO standard class device */ -+ {SDIO_DEVICE(0x037A, 0x5921)}, -+ -+ /* MT6628 *//* SDIO1: Wi-Fi, SDIO2: BGF */ -+ {SDIO_DEVICE(0x037A, 0x6628)}, -+ -+ /* MT6630 *//* SDIO1: Wi-Fi, SDIO2: BGF */ -+ {SDIO_DEVICE(0x037A, 0x6630)}, -+ { /* end: all zeroes */ }, -+}; -+ -+static int sdio_detect_probe(struct sdio_func *func, const struct sdio_device_id *id); -+ -+static void sdio_detect_remove(struct sdio_func *func); -+ -+static struct sdio_driver mtk_sdio_client_drv = { -+ .name = "mtk_sdio_client", /* MTK SDIO Client Driver */ -+ .id_table = mtk_sdio_id_tbl, /* all supported struct sdio_device_id table */ -+ .probe = sdio_detect_probe, -+ .remove = sdio_detect_remove, -+}; -+ -+static int hif_sdio_match_chipid_by_dev_id(const struct sdio_device_id *id); -+ -+int hif_sdio_is_chipid_valid(int chipId) -+{ -+ int index = -1; -+ -+ int left = 0; -+ int middle = 0; -+ int right = sizeof(gChipInfoArray) / sizeof(gChipInfoArray[0]) - 1; -+ -+ if ((chipId < gChipInfoArray[left].chipId) || (chipId > gChipInfoArray[right].chipId)) -+ return index; -+ -+ middle = (left + right) / 2; -+ -+ while (left <= right) { -+ if (chipId > gChipInfoArray[middle].chipId) { -+ left = middle + 1; -+ } else if (chipId < gChipInfoArray[middle].chipId) { -+ right = middle - 1; -+ } else { -+ index = middle; -+ break; -+ } -+ middle = (left + right) / 2; -+ } -+ -+ if (0 > index) -+ WMT_DETECT_ERR_FUNC("no supported chipid found\n"); -+ else -+ WMT_DETECT_INFO_FUNC("index:%d, chipId:0x%x\n", index, gChipInfoArray[index].chipId); -+ -+ return index; -+} -+ -+int hif_sdio_match_chipid_by_dev_id(const struct sdio_device_id *id) -+{ -+ int maxIndex = sizeof(gChipInfoArray) / sizeof(gChipInfoArray[0]); -+ int index = 0; -+ struct sdio_device_id *localId = NULL; -+ int chipId = -1; -+ -+ for (index = 0; index < maxIndex; index++) { -+ localId = &(gChipInfoArray[index].deviceId); -+ if ((localId->vendor == id->vendor) && (localId->device == id->device)) { -+ chipId = gChipInfoArray[index].chipId; -+ WMT_DETECT_INFO_FUNC -+ ("valid chipId found, index(%d), vendor id(0x%x), device id(0x%x), chip id(0x%x)\n", index, -+ localId->vendor, localId->device, chipId); -+ gComboChipId = chipId; -+ mtk_wcn_wmt_set_chipid(gComboChipId); -+ break; -+ } -+ } -+ if (0 > chipId) { -+ WMT_DETECT_ERR_FUNC("No valid chipId found, vendor id(0x%x), device id(0x%x)\n", id->vendor, -+ id->device); -+ } -+ -+ return chipId; -+} -+ -+int sdio_detect_query_chipid(int waitFlag) -+{ -+ unsigned int timeSlotMs = 200; -+ unsigned int maxTimeSlot = 15; -+ unsigned int counter = 0; -+ /* gComboChipId = 0x6628; */ -+ if (0 == waitFlag) -+ return gComboChipId; -+ if (0 <= hif_sdio_is_chipid_valid(gComboChipId)) -+ return gComboChipId; -+ -+ while (counter < maxTimeSlot) { -+ if (0 <= hif_sdio_is_chipid_valid(gComboChipId)) -+ break; -+ msleep(timeSlotMs); -+ counter++; -+ } -+ -+ return gComboChipId; -+} -+ -+int sdio_detect_do_autok(int chipId) -+{ -+ int i_ret = 0; -+ -+#if MTK_HIF_SDIO_AUTOK_ENABLED -+#if 0 -+ BOOTMODE boot_mode; -+ -+ boot_mode = get_boot_mode(); -+ -+ if (boot_mode == META_BOOT) { -+ WMT_DETECT_INFO_FUNC("omit autok in meta mode\n"); -+ return 0; -+ } -+#endif -+ if (0x6630 == chipId) { -+#ifdef CONFIG_SDIOAUTOK_SUPPORT -+ if (NULL != g_func) { -+ WMT_DETECT_INFO_FUNC("wait_sdio_autok_ready++\n"); -+ i_ret = wait_sdio_autok_ready(g_func->card->host); -+ WMT_DETECT_INFO_FUNC("wait_sdio_autok_ready--\n"); -+ if (0 == i_ret) { -+ WMT_DETECT_INFO_FUNC("wait_sdio_autok_ready return success\n"); -+ } else { -+ WMT_DETECT_INFO_FUNC("wait_sdio_autok_ready return fail, i_ret:%d\n", i_ret); -+ gComboChipId = -1; -+ } -+ } else { -+ WMT_DETECT_INFO_FUNC("g_func NULL, omit autok\n"); -+ } -+#else -+ i_ret = 0; -+ WMT_DETECT_INFO_FUNC("MTK_SDIOAUTOK_SUPPORT not defined\n"); -+#endif -+ } else { -+ WMT_DETECT_INFO_FUNC("MT%x does not support SDIO3.0 autoK is not needed\n", chipId); -+ } -+#else -+ i_ret = 0; -+ WMT_DETECT_INFO_FUNC("MTK_HIF_SDIO_AUTOK_ENABLED is not defined\n"); -+#endif -+ return i_ret; -+} -+ -+/*! -+ * \brief hif_sdio probe function -+ * -+ * hif_sdio probe function called by mmc driver when any matched SDIO function -+ * is detected by it. -+ * -+ * \param func -+ * \param id -+ * -+ * \retval 0 register successfully -+ * \retval < 0 list error code here -+ */ -+static int sdio_detect_probe(struct sdio_func *func, const struct sdio_device_id *id) -+{ -+ int chipId = 0; -+ -+ WMT_DETECT_INFO_FUNC("vendor(0x%x) device(0x%x) num(0x%x)\n", func->vendor, func->device, func->num); -+ chipId = hif_sdio_match_chipid_by_dev_id(id); -+ -+ if ((0x6630 == chipId) && (1 == func->num)) { -+ int ret = 0; -+ -+ g_func = func; -+ WMT_DETECT_INFO_FUNC("autok function detected, func:0x%p\n", g_func); -+ -+ sdio_claim_host(func); -+ ret = sdio_enable_func(func); -+ sdio_release_host(func); -+ if (ret) -+ WMT_DETECT_ERR_FUNC("sdio_enable_func failed!\n"); -+ } -+ -+ return 0; -+} -+ -+static void sdio_detect_remove(struct sdio_func *func) -+{ -+ if (g_func == func) { -+ sdio_claim_host(func); -+ sdio_disable_func(func); -+ sdio_release_host(func); -+ g_func = NULL; -+ } -+ WMT_DETECT_INFO_FUNC("do sdio remove\n"); -+} -+ -+int sdio_detect_init(void) -+{ -+ int ret = -1; -+ /* register to mmc driver */ -+ ret = sdio_register_driver(&mtk_sdio_client_drv); -+ WMT_DETECT_INFO_FUNC("sdio_register_driver() ret=%d\n", ret); -+ return 0; -+} -+ -+int sdio_detect_exit(void) -+{ -+ g_func = NULL; -+ /* register to mmc driver */ -+ sdio_unregister_driver(&mtk_sdio_client_drv); -+ WMT_DETECT_INFO_FUNC("sdio_unregister_driver\n"); -+ return 0; -+} -diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/sdio_detect.h b/drivers/misc/mediatek/connectivity/common/common_detect/sdio_detect.h -new file mode 100644 -index 000000000000..3a0bff9def1b ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/common_detect/sdio_detect.h -@@ -0,0 +1,43 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -+ -+#ifndef _SDIO_DETECT_H_ -+#define _SDIO_DETECT_H_ -+ -+#include -+#include -+#include -+#include -+#include -+ -+#ifdef CONFIG_SDIOAUTOK_SUPPORT -+#define MTK_HIF_SDIO_AUTOK_ENABLED 1 -+extern int wait_sdio_autok_ready(void *); -+#else -+#define MTK_HIF_SDIO_AUTOK_ENABLED 0 -+#endif -+ -+typedef struct _MTK_WCN_HIF_SDIO_CHIP_INFO_ { -+ struct sdio_device_id deviceId; -+ unsigned int chipId; -+} MTK_WCN_HIF_SDIO_CHIP_INFO, *P_MTK_WCN_HIF_SDIO_CHIP_INFO; -+ -+extern int sdio_detect_exit(void); -+extern int sdio_detect_init(void); -+extern int sdio_detect_query_chipid(int waitFlag); -+extern int hif_sdio_is_chipid_valid(int chipId); -+ -+extern int sdio_detect_do_autok(int chipId); -+ -+#endif -diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/wmt_detect.c b/drivers/misc/mediatek/connectivity/common/common_detect/wmt_detect.c -new file mode 100644 -index 000000000000..487852df8f20 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/common_detect/wmt_detect.c -@@ -0,0 +1,380 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -+ -+#include -+#include -+ -+#ifdef DFT_TAG -+#undef DFT_TAG -+#endif -+#define DFT_TAG "[WMT-DETECT]" -+ -+#include "wmt_detect.h" -+#include "wmt_gpio.h" -+ -+#if MTK_WCN_REMOVE_KO -+#include "conn_drv_init.h" -+#endif -+#ifdef CONFIG_COMPAT -+#include -+#endif -+ -+#define WMT_DETECT_MAJOR 154 -+#define WMT_DETECT_DEV_NUM 1 -+#define WMT_DETECT_DRVIER_NAME "mtk_wcn_detect" -+#define WMT_DETECT_DEVICE_NAME "wmtdetect" -+ -+struct class *pDetectClass = NULL; -+struct device *pDetectDev = NULL; -+static int gWmtDetectMajor = WMT_DETECT_MAJOR; -+static struct cdev gWmtDetectCdev; -+unsigned int gWmtDetectDbgLvl = WMT_DETECT_LOG_INFO; -+ -+ -+#ifdef MTK_WCN_COMBO_CHIP_SUPPORT -+inline unsigned int wmt_plat_get_soc_chipid(void) -+{ -+ WMT_DETECT_INFO_FUNC("no soc chip supported, due to MTK_WCN_SOC_CHIP_SUPPORT is not set.\n"); -+ return -1; -+} -+#endif -+ -+static int wmt_detect_open(struct inode *inode, struct file *file) -+{ -+ WMT_DETECT_INFO_FUNC("open major %d minor %d (pid %d)\n", imajor(inode), iminor(inode), current->pid); -+ -+ return 0; -+} -+ -+static int wmt_detect_close(struct inode *inode, struct file *file) -+{ -+ WMT_DETECT_INFO_FUNC("close major %d minor %d (pid %d)\n", imajor(inode), iminor(inode), current->pid); -+ -+ return 0; -+} -+ -+static ssize_t wmt_detect_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos) -+{ -+ WMT_DETECT_INFO_FUNC(" ++\n"); -+ WMT_DETECT_INFO_FUNC(" --\n"); -+ -+ return 0; -+} -+ -+ssize_t wmt_detect_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos) -+{ -+ WMT_DETECT_INFO_FUNC(" ++\n"); -+ WMT_DETECT_INFO_FUNC(" --\n"); -+ -+ return 0; -+} -+ -+static long wmt_detect_unlocked_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) -+{ -+ int retval = 0; -+ -+ WMT_DETECT_INFO_FUNC("cmd (%d),arg(%ld)\n", cmd, arg); -+ -+ switch (cmd) { -+ case COMBO_IOCTL_GET_CHIP_ID: -+ /*just get chipid from sdio-detect module */ -+ /*check if external combo chip exists or not */ -+ /*if yes, just return combo chip id */ -+ /*if no, get soc chipid */ -+ retval = mtk_wcn_wmt_chipid_query(); -+ break; -+ -+ case COMBO_IOCTL_SET_CHIP_ID: -+ mtk_wcn_wmt_set_chipid(arg); -+ -+ break; -+ -+ case COMBO_IOCTL_EXT_CHIP_PWR_ON: -+ retval = wmt_detect_ext_chip_pwr_on(); -+ break; -+ -+ case COMBO_IOCTL_EXT_CHIP_DETECT: -+ retval = wmt_detect_ext_chip_detect(); -+ break; -+ -+ case COMBO_IOCTL_EXT_CHIP_PWR_OFF: -+ retval = wmt_detect_ext_chip_pwr_off(); -+ break; -+ -+ case COMBO_IOCTL_DO_SDIO_AUDOK: -+ retval = sdio_detect_do_autok(arg); -+ break; -+ -+ case COMBO_IOCTL_GET_SOC_CHIP_ID: -+ retval = wmt_plat_get_soc_chipid(); -+ /*get soc chipid by HAL interface */ -+ break; -+ -+ case COMBO_IOCTL_MODULE_CLEANUP: -+#if (MTK_WCN_REMOVE_KO) -+ /*deinit SDIO-DETECT module */ -+ retval = sdio_detect_exit(); -+#else -+ WMT_DETECT_INFO_FUNC("no MTK_WCN_REMOVE_KO defined\n"); -+#endif -+ break; -+ -+ case COMBO_IOCTL_DO_MODULE_INIT: -+#if (MTK_WCN_REMOVE_KO) -+ /*deinit SDIO-DETECT module */ -+ retval = do_connectivity_driver_init(arg); -+#else -+ WMT_DETECT_INFO_FUNC("no MTK_WCN_REMOVE_KO defined\n"); -+#endif -+ break; -+ -+ default: -+ WMT_DETECT_WARN_FUNC("unknown cmd (%d)\n", cmd); -+ retval = 0; -+ break; -+ } -+ return retval; -+} -+#ifdef CONFIG_COMPAT -+static long WMT_compat_detect_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) -+{ -+ long ret; -+ -+ WMT_DETECT_INFO_FUNC("cmd (%d)\n", cmd); -+ ret = wmt_detect_unlocked_ioctl(filp, cmd, arg); -+ return ret; -+} -+#endif -+const struct file_operations gWmtDetectFops = { -+ .open = wmt_detect_open, -+ .release = wmt_detect_close, -+ .read = wmt_detect_read, -+ .write = wmt_detect_write, -+ .unlocked_ioctl = wmt_detect_unlocked_ioctl, -+#ifdef CONFIG_COMPAT -+ .compat_ioctl = WMT_compat_detect_ioctl, -+#endif -+}; -+ -+int wmt_detect_ext_chip_pwr_on(void) -+{ -+ /*pre power on external chip */ -+ /* wmt_plat_pwr_ctrl(FUNC_ON); */ -+#ifdef MTK_WCN_COMBO_CHIP_SUPPORT -+ WMT_DETECT_INFO_FUNC("++\n"); -+ if (0 != wmt_detect_chip_pwr_ctrl(1)) -+ return -1; -+ if (0 != wmt_detect_sdio_pwr_ctrl(1)) -+ return -2; -+ return 0; -+#else -+ WMT_DETECT_INFO_FUNC("combo chip is not supported\n"); -+ return -1; -+#endif -+} -+ -+int wmt_detect_ext_chip_pwr_off(void) -+{ -+ /*pre power off external chip */ -+ /* wmt_plat_pwr_ctrl(FUNC_OFF); */ -+#ifdef MTK_WCN_COMBO_CHIP_SUPPORT -+ WMT_DETECT_INFO_FUNC("--\n"); -+ wmt_detect_sdio_pwr_ctrl(0); -+ return wmt_detect_chip_pwr_ctrl(0); -+#else -+ WMT_DETECT_INFO_FUNC("combo chip is not supported\n"); -+ return 0; -+#endif -+} -+ -+int wmt_detect_ext_chip_detect(void) -+{ -+ int iRet = -1; -+ unsigned int chipId = -1; -+ /*if there is no external combo chip, return -1 */ -+ int bgfEintStatus = -1; -+ -+ WMT_DETECT_INFO_FUNC("++\n"); -+ /*wait for a stable time */ -+ msleep(20); -+ -+ /*read BGF_EINT_PIN status */ -+ bgfEintStatus = wmt_detect_read_ext_cmb_status(); -+ -+ if (0 == bgfEintStatus) { -+ /*external chip does not exist */ -+ WMT_DETECT_INFO_FUNC("external combo chip not detected\n"); -+ } else if (1 == bgfEintStatus) { -+ /*combo chip exists */ -+ WMT_DETECT_INFO_FUNC("external combo chip detected\n"); -+ -+ /*detect chipid by sdio_detect module */ -+ chipId = sdio_detect_query_chipid(1); -+ if (0 <= hif_sdio_is_chipid_valid(chipId)) -+ WMT_DETECT_INFO_FUNC("valid external combo chip id (0x%x)\n", chipId); -+ else -+ WMT_DETECT_INFO_FUNC("invalid external combo chip id (0x%x)\n", chipId); -+ iRet = 0; -+ } else { -+ /*Error exists */ -+ WMT_DETECT_ERR_FUNC("error happens when detecting combo chip\n"); -+ } -+ WMT_DETECT_INFO_FUNC("--\n"); -+ /*return 0 */ -+ return iRet; -+ /*todo: if there is external combo chip, power on chip return 0 */ -+} -+ -+#ifdef MTK_WCN_COMBO_CHIP_SUPPORT -+static int wmt_detect_probe(struct platform_device *pdev) -+{ -+ int ret = 0; -+ -+ WMT_DETECT_ERR_FUNC("platform name: %s\n", pdev->name); -+ ret = wmt_gpio_init(pdev); -+ if (-1 == ret) -+ WMT_DETECT_ERR_FUNC("gpio init fail ret:%d\n", ret); -+ return ret; -+} -+ -+static int wmt_detect_remove(struct platform_device *pdev) -+{ -+ wmt_gpio_deinit(); -+ return 0; -+} -+#endif -+ -+#ifdef MTK_WCN_COMBO_CHIP_SUPPORT -+static struct of_device_id wmt_detect_match[] = { -+ { .compatible = "mediatek,connectivity-combo", }, -+ {} -+}; -+MODULE_DEVICE_TABLE(of, wmt_detect_match); -+ -+static struct platform_driver wmt_detect_driver = { -+ .probe = wmt_detect_probe, -+ .remove = wmt_detect_remove, -+ .driver = { -+ .owner = THIS_MODULE, -+ .name = "mediatek,connectivity-combo", -+ .of_match_table = wmt_detect_match, -+ }, -+}; -+#endif -+ -+/*module_platform_driver(wmt_detect_driver);*/ -+static int wmt_detect_driver_init(void) -+{ -+ dev_t devID = MKDEV(gWmtDetectMajor, 0); -+ int cdevErr = -1; -+ int ret = -1; -+ -+ ret = register_chrdev_region(devID, WMT_DETECT_DEV_NUM, WMT_DETECT_DRVIER_NAME); -+ if (ret) { -+ WMT_DETECT_ERR_FUNC("fail to register chrdev\n"); -+ return ret; -+ } -+ -+ cdev_init(&gWmtDetectCdev, &gWmtDetectFops); -+ gWmtDetectCdev.owner = THIS_MODULE; -+ -+ cdevErr = cdev_add(&gWmtDetectCdev, devID, WMT_DETECT_DEV_NUM); -+ if (cdevErr) { -+ WMT_DETECT_ERR_FUNC("cdev_add() fails (%d)\n", cdevErr); -+ goto err1; -+ } -+ -+ pDetectClass = class_create(THIS_MODULE, WMT_DETECT_DEVICE_NAME); -+ if (IS_ERR(pDetectClass)) { -+ WMT_DETECT_ERR_FUNC("class create fail, error code(%ld)\n", PTR_ERR(pDetectClass)); -+ goto err1; -+ } -+ -+ pDetectDev = device_create(pDetectClass, NULL, devID, NULL, WMT_DETECT_DEVICE_NAME); -+ if (IS_ERR(pDetectDev)) { -+ WMT_DETECT_ERR_FUNC("device create fail, error code(%ld)\n", PTR_ERR(pDetectDev)); -+ goto err2; -+ } -+ -+ WMT_DETECT_INFO_FUNC("driver(major %d) installed success\n", gWmtDetectMajor); -+ -+ /*init SDIO-DETECT module */ -+ sdio_detect_init(); -+ -+#ifdef MTK_WCN_COMBO_CHIP_SUPPORT -+ ret = platform_driver_register(&wmt_detect_driver); -+ if (ret) -+ WMT_DETECT_ERR_FUNC("platform driver register fail ret:%d\n", ret); -+#endif -+ -+ return 0; -+ -+err2: -+ -+ if (pDetectClass) { -+ class_destroy(pDetectClass); -+ pDetectClass = NULL; -+ } -+ -+err1: -+ -+ if (cdevErr == 0) -+ cdev_del(&gWmtDetectCdev); -+ -+ if (ret == 0) { -+ unregister_chrdev_region(devID, WMT_DETECT_DEV_NUM); -+ gWmtDetectMajor = -1; -+ } -+ -+ WMT_DETECT_ERR_FUNC("fail\n"); -+ -+ return -1; -+} -+ -+static void wmt_detect_driver_exit(void) -+{ -+ dev_t dev = MKDEV(gWmtDetectMajor, 0); -+ -+ if (pDetectDev) { -+ device_destroy(pDetectClass, dev); -+ pDetectDev = NULL; -+ } -+ -+ if (pDetectClass) { -+ class_destroy(pDetectClass); -+ pDetectClass = NULL; -+ } -+ -+ cdev_del(&gWmtDetectCdev); -+ unregister_chrdev_region(dev, WMT_DETECT_DEV_NUM); -+ -+#if !(MTK_WCN_REMOVE_KO) -+/*deinit SDIO-DETECT module*/ -+ sdio_detect_exit(); -+#endif -+ -+#ifdef MTK_WCN_COMBO_CHIP_SUPPORT -+ platform_driver_unregister(&wmt_detect_driver); -+#endif -+ -+ WMT_DETECT_INFO_FUNC("done\n"); -+} -+ -+module_init(wmt_detect_driver_init); -+module_exit(wmt_detect_driver_exit); -+ -+MODULE_LICENSE("GPL"); -+MODULE_AUTHOR("Zhiguo.Niu & Chaozhong.Liang @ MBJ/WCNSE/SS1"); -+ -+module_param(gWmtDetectMajor, uint, 0); -diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/wmt_detect.h b/drivers/misc/mediatek/connectivity/common/common_detect/wmt_detect.h -new file mode 100644 -index 000000000000..7e152bfd39ec ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/common_detect/wmt_detect.h -@@ -0,0 +1,114 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -+ -+#ifndef _WMT_DETECT_H_ -+#define _WMT_DETECT_H_ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+#ifdef MTK_WCN_REMOVE_KERNEL_MODULE -+#define MTK_WCN_REMOVE_KO 1 -+#else -+#define MTK_WCN_REMOVE_KO 0 -+#endif -+ -+#include "sdio_detect.h" -+#include "wmt_detect_pwr.h" -+#include -+ -+#define WMT_DETECT_LOG_LOUD 4 -+#define WMT_DETECT_LOG_DBG 3 -+#define WMT_DETECT_LOG_INFO 2 -+#define WMT_DETECT_LOG_WARN 1 -+#define WMT_DETECT_LOG_ERR 0 -+ -+extern unsigned int gWmtDetectDbgLvl; -+ -+#define WMT_DETECT_LOUD_FUNC(fmt, arg...) \ -+do { \ -+ if (gWmtDetectDbgLvl >= WMT_DETECT_LOG_LOUD) \ -+ pr_debug(DFT_TAG"[L]%s:" fmt, __func__ , ##arg); \ -+} while (0) -+#define WMT_DETECT_DBG_FUNC(fmt, arg...) \ -+do { \ -+ if (gWmtDetectDbgLvl >= WMT_DETECT_LOG_DBG) \ -+ pr_debug(DFT_TAG"[D]%s:" fmt, __func__ , ##arg); \ -+} while (0) -+#define WMT_DETECT_INFO_FUNC(fmt, arg...) \ -+do { \ -+ if (gWmtDetectDbgLvl >= WMT_DETECT_LOG_INFO) \ -+ pr_err(DFT_TAG"[I]%s:" fmt, __func__ , ##arg); \ -+} while (0) -+#define WMT_DETECT_WARN_FUNC(fmt, arg...) \ -+do { \ -+ if (gWmtDetectDbgLvl >= WMT_DETECT_LOG_WARN) \ -+ pr_warn(DFT_TAG"[W]%s(%d):" fmt, __func__ , __LINE__, ##arg); \ -+} while (0) -+#define WMT_DETECT_ERR_FUNC(fmt, arg...) \ -+do { \ -+ if (gWmtDetectDbgLvl >= WMT_DETECT_LOG_ERR) \ -+ pr_err(DFT_TAG"[E]%s(%d):" fmt, __func__ , __LINE__, ##arg); \ -+} while (0) -+ -+#define WMT_IOC_MAGIC 'w' -+#define COMBO_IOCTL_GET_CHIP_ID _IOR(WMT_IOC_MAGIC, 0, int) -+#define COMBO_IOCTL_SET_CHIP_ID _IOW(WMT_IOC_MAGIC, 1, int) -+#define COMBO_IOCTL_EXT_CHIP_DETECT _IOR(WMT_IOC_MAGIC, 2, int) -+#define COMBO_IOCTL_GET_SOC_CHIP_ID _IOR(WMT_IOC_MAGIC, 3, int) -+#define COMBO_IOCTL_DO_MODULE_INIT _IOR(WMT_IOC_MAGIC, 4, int) -+#define COMBO_IOCTL_MODULE_CLEANUP _IOR(WMT_IOC_MAGIC, 5, int) -+#define COMBO_IOCTL_EXT_CHIP_PWR_ON _IOR(WMT_IOC_MAGIC, 6, int) -+#define COMBO_IOCTL_EXT_CHIP_PWR_OFF _IOR(WMT_IOC_MAGIC, 7, int) -+#define COMBO_IOCTL_DO_SDIO_AUDOK _IOR(WMT_IOC_MAGIC, 8, int) -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+********************************************************************************/ -+extern int wmt_detect_ext_chip_detect(void); -+extern int wmt_detect_ext_chip_pwr_on(void); -+extern int wmt_detect_ext_chip_pwr_off(void); -+ -+#ifdef MTK_WCN_SOC_CHIP_SUPPORT -+extern unsigned int wmt_plat_get_soc_chipid(void); -+#endif -+ -+#ifdef MTK_WCN_COMBO_CHIP_SUPPORT -+/* mtk_uart_pdn_enable -- request uart port enter/exit deep idle mode, this API is defined in uart driver -+ * -+ * @ port - uart port name, Eg: "ttyMT0", "ttyMT1", "ttyMT2" -+ * @ enable - "1", enable deep idle; "0", disable deep idle -+ * -+ * Return 0 if success, else -1 -+ */ -+extern unsigned int mtk_uart_pdn_enable(char *port, int enable); -+#endif -+ -+#endif -diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/wmt_detect_pwr.c b/drivers/misc/mediatek/connectivity/common/common_detect/wmt_detect_pwr.c -new file mode 100644 -index 000000000000..1dcb7ed358bc ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/common_detect/wmt_detect_pwr.c -@@ -0,0 +1,232 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -+ -+#include -+ -+#ifdef DFT_TAG -+#undef DFT_TAG -+#endif -+#define DFT_TAG "[WMT-DETECT]" -+ -+#include "wmt_detect.h" -+#include "wmt_gpio.h" -+ -+#define INVALID_PIN_ID (0xFFFFFFFF) -+ -+/*copied form WMT module*/ -+static int wmt_detect_dump_pin_conf(void) -+{ -+ WMT_DETECT_DBG_FUNC("[WMT-DETECT]=>dump wmt pin configuration start<=\n"); -+ -+ WMT_DETECT_INFO_FUNC("LDO(GPIO%d), PMU(GPIO%d), PMUV28(GPIO%d)\n", -+ gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_LDO_EN_PIN].gpio_num, -+ gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_PMU_EN_PIN].gpio_num, -+ gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_PMUV28_EN_PIN].gpio_num); -+ -+ WMT_DETECT_INFO_FUNC("RST(GPIO%d), BGF_EINT(GPIO%d), BGF_EINT_NUM(%d)\n", -+ gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_RST_PIN].gpio_num, -+ gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_BGF_EINT_PIN].gpio_num, -+ gpio_to_irq(gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_BGF_EINT_PIN].gpio_num)); -+ -+ WMT_DETECT_INFO_FUNC("WIFI_EINT(GPIO%d), WIFI_EINT_NUM(%d)\n", -+ gpio_ctrl_info.gpio_ctrl_state[GPIO_WIFI_EINT_PIN].gpio_num, -+ gpio_to_irq(gpio_ctrl_info.gpio_ctrl_state[GPIO_WIFI_EINT_PIN].gpio_num)); -+ -+ WMT_DETECT_DBG_FUNC("[WMT-PLAT]=>dump wmt pin configuration ends<=\n"); -+ -+ return 0; -+} -+ -+int _wmt_detect_output_low(unsigned int id) -+{ -+ if (INVALID_PIN_ID != gpio_ctrl_info.gpio_ctrl_state[id].gpio_num) { -+ gpio_direction_output(gpio_ctrl_info.gpio_ctrl_state[id].gpio_num, 0); -+ WMT_DETECT_DBG_FUNC("WMT-DETECT: set GPIO%d to output %d\n", -+ gpio_ctrl_info.gpio_ctrl_state[id].gpio_num, -+ gpio_get_value(gpio_ctrl_info.gpio_ctrl_state[id].gpio_num)); -+ } -+ -+ return 0; -+} -+ -+int _wmt_detect_output_high(unsigned int id) -+{ -+ if (INVALID_PIN_ID != gpio_ctrl_info.gpio_ctrl_state[id].gpio_num) { -+ gpio_direction_output(gpio_ctrl_info.gpio_ctrl_state[id].gpio_num, 1); -+ WMT_DETECT_DBG_FUNC("WMT-DETECT: set GPIO%d to output %d\n", -+ gpio_ctrl_info.gpio_ctrl_state[id].gpio_num, -+ gpio_get_value(gpio_ctrl_info.gpio_ctrl_state[id].gpio_num)); -+ } -+ -+ return 0; -+} -+ -+int _wmt_detect_read_gpio_input(unsigned int id) -+{ -+ int retval = 0; -+ -+ if (INVALID_PIN_ID != gpio_ctrl_info.gpio_ctrl_state[id].gpio_num) { -+ retval = gpio_get_value(gpio_ctrl_info.gpio_ctrl_state[id].gpio_num); -+ WMT_DETECT_DBG_FUNC("WMT-DETECT: get GPIO%d val%d\n", -+ gpio_ctrl_info.gpio_ctrl_state[id].gpio_num, retval); -+ } -+ -+ return retval; -+} -+ -+/*This power on sequence must support all combo chip's basic power on sequence -+ * 1. LDO control is a must, if external LDO exist -+ * 2. PMU control is a must -+ * 3. RST control is a must -+ * 4. WIFI_EINT pin control is a must, used for GPIO mode for EINT status checkup -+ * 5. RTC32k clock control is a must -+ * */ -+static int wmt_detect_chip_pwr_on(void) -+{ -+ int retval = -1; -+ /*setting validiation check*/ -+ if ((INVALID_PIN_ID == gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_PMU_EN_PIN].gpio_num) || -+ (INVALID_PIN_ID == gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_RST_PIN].gpio_num) || -+ (INVALID_PIN_ID == gpio_ctrl_info.gpio_ctrl_state[GPIO_WIFI_EINT_PIN].gpio_num)) { -+ WMT_DETECT_ERR_FUNC("WMT-DETECT: either PMU(%d) or RST(%d) or WIFI_EINT(%d) is not set\n", -+ gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_PMU_EN_PIN].gpio_num, -+ gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_RST_PIN].gpio_num, -+ gpio_ctrl_info.gpio_ctrl_state[GPIO_WIFI_EINT_PIN].gpio_num); -+ -+ return retval; -+ } -+ /*set LDO/PMU/RST to output 0, no pull*/ -+ if (INVALID_PIN_ID != gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_LDO_EN_PIN].gpio_num) -+ _wmt_detect_output_low(GPIO_COMBO_LDO_EN_PIN); -+ if (gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_PMU_EN_PIN].gpio_state[GPIO_PULL_DIS]) { -+ pinctrl_select_state(gpio_ctrl_info.pinctrl_info, -+ gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_PMU_EN_PIN].gpio_state[GPIO_PULL_DIS]); -+ WMT_DETECT_INFO_FUNC("wmt_gpio:set GPIO_COMBO_PMU_EN_PIN to GPIO_PULL_DIS done!\n"); -+ } else -+ WMT_DETECT_ERR_FUNC("wmt_gpio:set GPIO_COMBO_PMU_EN_PIN to GPIO_PULL_DIS fail, is NULL!\n"); -+ _wmt_detect_output_low(GPIO_COMBO_PMU_EN_PIN); -+ if (gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_RST_PIN].gpio_state[GPIO_PULL_DIS]) { -+ pinctrl_select_state(gpio_ctrl_info.pinctrl_info, -+ gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_RST_PIN].gpio_state[GPIO_PULL_DIS]); -+ WMT_DETECT_INFO_FUNC("wmt_gpio:set GPIO_COMBO_RST_PIN to GPIO_PULL_DIS done!\n"); -+ } else -+ WMT_DETECT_ERR_FUNC("wmt_gpio:set GPIO_COMBO_RST_PIN to GPIO_PULL_DIS fail, is NULL!\n"); -+ _wmt_detect_output_low(GPIO_COMBO_RST_PIN); -+ -+#if 0 -+ _wmt_detect_output_high(GPIO_WIFI_EINT_PIN); -+#endif -+ -+ /*pull high LDO*/ -+ if (INVALID_PIN_ID != gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_LDO_EN_PIN].gpio_num) -+ _wmt_detect_output_high(GPIO_COMBO_LDO_EN_PIN); -+ /*sleep for LDO stable time*/ -+ msleep(MAX_LDO_STABLE_TIME); -+ -+ /*export RTC clock, sleep for RTC stable time*/ -+ rtc_gpio_enable_32k(RTC_GPIO_USER_GPS); -+ msleep(MAX_RTC_STABLE_TIME); -+ /*PMU output low, RST output low, to make chip power off completely*/ -+ /*always done*/ -+ /*sleep for power off stable time*/ -+ msleep(MAX_OFF_STABLE_TIME); -+ /*PMU output high, and sleep for reset stable time*/ -+ _wmt_detect_output_high(GPIO_COMBO_PMU_EN_PIN); -+#ifdef CONFIG_MTK_COMBO_COMM_NPWR -+ if ((gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_I2S_DAT_PIN].gpio_num != INVALID_PIN_ID) && -+ (gpio_ctrl_info.gpio_ctrl_state[GPIO_PCM_DAISYNC_PIN].gpio_num != INVALID_PIN_ID)) { -+ msleep(20); -+ _wmt_detect_output_high(GPIO_PCM_DAISYNC_PIN); -+ -+ msleep(20); -+ _wmt_detect_output_high(GPIO_COMBO_I2S_DAT_PIN); -+ -+ msleep(20); -+ _wmt_detect_output_low(GPIO_COMBO_I2S_DAT_PIN); -+ -+ msleep(20); -+ _wmt_detect_output_low(GPIO_PCM_DAISYNC_PIN); -+ -+ msleep(20); -+ } -+#endif -+ msleep(MAX_RST_STABLE_TIME); -+ /*RST output high, and sleep for power on stable time */ -+ _wmt_detect_output_high(GPIO_COMBO_RST_PIN); -+ msleep(MAX_ON_STABLE_TIME); -+ -+ retval = 0; -+ return retval; -+} -+ -+static int wmt_detect_chip_pwr_off(void) -+{ -+ -+ /*set RST pin to input low status*/ -+ if (INVALID_PIN_ID != gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_LDO_EN_PIN].gpio_num) -+ _wmt_detect_output_low(GPIO_COMBO_LDO_EN_PIN); -+ /*set RST pin to input low status*/ -+ if (INVALID_PIN_ID != gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_RST_PIN].gpio_num) -+ _wmt_detect_output_low(GPIO_COMBO_RST_PIN); -+ /*set PMU pin to input low status*/ -+ if (INVALID_PIN_ID != gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_PMU_EN_PIN].gpio_num) -+ _wmt_detect_output_low(GPIO_COMBO_PMU_EN_PIN); -+ return 0; -+} -+ -+int wmt_detect_read_ext_cmb_status(void) -+{ -+ int retval = 0; -+ /*read WIFI_EINT pin status*/ -+ if (INVALID_PIN_ID == gpio_ctrl_info.gpio_ctrl_state[GPIO_WIFI_EINT_PIN].gpio_num) { -+ retval = 0; -+ WMT_DETECT_ERR_FUNC("WMT-DETECT: no WIFI_EINT pin set\n"); -+ } else { -+ retval = _wmt_detect_read_gpio_input(GPIO_WIFI_EINT_PIN); -+ WMT_DETECT_ERR_FUNC("WMT-DETECT: WIFI_EINT input status:%d\n", retval); -+ } -+ return retval; -+} -+ -+int wmt_detect_chip_pwr_ctrl(int on) -+{ -+ int retval = -1; -+ -+ if (0 == on) { -+ /*power off combo chip */ -+ retval = wmt_detect_chip_pwr_off(); -+ } else { -+ wmt_detect_dump_pin_conf(); -+ /*power on combo chip */ -+ retval = wmt_detect_chip_pwr_on(); -+ } -+ return retval; -+} -+ -+int wmt_detect_sdio_pwr_ctrl(int on) -+{ -+ int retval = -1; -+#ifdef MTK_WCN_COMBO_CHIP_SUPPORT -+ if (0 == on) { -+ /*power off SDIO slot */ -+ retval = board_sdio_ctrl(1, 0); -+ } else { -+ /*power on SDIO slot */ -+ retval = board_sdio_ctrl(1, 1); -+ } -+#else -+ WMT_DETECT_WARN_FUNC("WMT-DETECT: MTK_WCN_COMBO_CHIP_SUPPORT is not set\n"); -+#endif -+ return retval; -+} -diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/wmt_detect_pwr.h b/drivers/misc/mediatek/connectivity/common/common_detect/wmt_detect_pwr.h -new file mode 100644 -index 000000000000..32e661520fd0 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/common_detect/wmt_detect_pwr.h -@@ -0,0 +1,29 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -+ -+#ifndef __WMT_DETECT_PWR_H_ -+#define __WMT_DETECT_PWR_H_ -+ -+#define MAX_RTC_STABLE_TIME 100 -+#define MAX_LDO_STABLE_TIME 100 -+#define MAX_RST_STABLE_TIME 30 -+#define MAX_OFF_STABLE_TIME 10 -+#define MAX_ON_STABLE_TIME 30 -+ -+extern int board_sdio_ctrl(unsigned int sdio_port_num, unsigned int on); -+extern int wmt_detect_chip_pwr_ctrl(int on); -+extern int wmt_detect_sdio_pwr_ctrl(int on); -+extern int wmt_detect_read_ext_cmb_status(void); -+ -+#endif -diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/wmt_gpio.c b/drivers/misc/mediatek/connectivity/common/common_detect/wmt_gpio.c -new file mode 100644 -index 000000000000..3a79e1e9d15a ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/common_detect/wmt_gpio.c -@@ -0,0 +1,371 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -+ -+#include "wmt_gpio.h" -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+const PUINT8 gpio_state_name[GPIO_PIN_ID_MAX][GPIO_STATE_MAX] = {{"gpio_ldo_en_pull_dis", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "gpio_ldo_en_in_pulldown", -+ ""}, -+ {"gpio_pmuv28_pull_dis", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "gpio_pmuv28_in_pulldown", -+ ""}, -+ {"gpio_pmu_en_pull_dis", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "gpio_pmu_en_in_pulldown", -+ ""}, -+ {"gpio_rst_pull_dis", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ ""}, -+ {"", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "gpio_bgf_eint_in_pulldown", -+ "gpio_bgf_eint_in_pullup"}, -+ {"", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "gpio_wifi_eint_in_pull_dis", -+ "", -+ "gpio_wifi_eint_in_pullup"}, -+ {"", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "gpio_all_eint_in_pulldown", -+ "gpio_all_eint_in_pullup"}, -+ {"gpio_urxd_uart_pull_dis", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "gpio_urxd_gpio_in_pull_dis", -+ "", -+ "gpio_urxd_gpio_in_pullup"}, -+ {"gpio_utxd_uart_pull_dis", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ ""}, -+ {"gpio_pcm_daiclk_pull_dis", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ ""}, -+ {"gpio_pcm_daipcmin_pull_dis", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ ""}, -+ {"gpio_pcm_daipcmout_pull_dis", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ ""}, -+ {"gpio_pcm_daisync_pull_dis", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ ""}, -+ {"gpio_i2s_ck_pull_dis", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ ""}, -+ {"gpio_i2s_ws_pull_dis", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ ""}, -+ {"gpio_i2s_dat_pull_dis", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ ""}, -+ {"gpio_gps_sync_pull_dis", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ ""}, -+ {"gpio_gps_lna_pull_dis", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ ""} -+}; -+ -+const PUINT8 gpio_pin_name[GPIO_PIN_ID_MAX] = {"gpio_combo_ldo_en_pin", -+ "gpio_combo_pmuv28_en_pin", -+ "gpio_combo_pmu_en_pin", -+ "gpio_combo_rst_pin", -+ "gpio_combo_bgf_eint_pin", -+ "gpio_wifi_eint_pin", -+ "gpio_all_eint_pin", -+ "gpio_combo_urxd_pin", -+ "gpio_combo_utxd_pin", -+ "gpio_pcm_daiclk_pin", -+ "gpio_pcm_daipcmin_pin", -+ "gpio_pcm_daipcmout_pin", -+ "gpio_pcm_daisync_pin", -+ "gpio_combo_i2s_ck_pin", -+ "gpio_combo_i2s_ws_pin", -+ "gpio_combo_i2s_dat_pin", -+ "gpio_gps_sync_pin", -+ "gpio_gps_lna_pin"}; -+ -+GPIO_CTRL_INFO gpio_ctrl_info; -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+INT32 wmt_gpio_init(struct platform_device *pdev) -+{ -+ INT32 iret = 0; -+ UINT32 i, j; -+ struct device_node *node; -+ -+ node = of_find_compatible_node(NULL, NULL, "mediatek,connectivity-combo"); -+ if (!node) { -+ for (i = 0; i < GPIO_PIN_ID_MAX; i++) -+ gpio_ctrl_info.gpio_ctrl_state[i].gpio_num = DEFAULT_PIN_ID; -+ pr_err("wmt_gpio:can't find device tree node!\n"); -+ iret = -1; -+ goto err; -+ } -+ -+ gpio_ctrl_info.pinctrl_info = devm_pinctrl_get(&pdev->dev); -+ if (gpio_ctrl_info.pinctrl_info) { -+ for (i = 0; i < GPIO_PIN_ID_MAX; i++) { -+ gpio_ctrl_info.gpio_ctrl_state[i].gpio_num = of_get_named_gpio(node, -+ gpio_pin_name[i], 0); -+ if (gpio_ctrl_info.gpio_ctrl_state[i].gpio_num < 0) -+ gpio_ctrl_info.gpio_ctrl_state[i].gpio_num = DEFAULT_PIN_ID; -+ if (DEFAULT_PIN_ID != gpio_ctrl_info.gpio_ctrl_state[i].gpio_num) { -+ for (j = 0; j < GPIO_STATE_MAX; j++) { -+ if (0 != strlen(gpio_state_name[i][j])) { -+ gpio_ctrl_info.gpio_ctrl_state[i].gpio_state[j] = -+ pinctrl_lookup_state(gpio_ctrl_info.pinctrl_info, -+ gpio_state_name[i][j]); -+ } else -+ gpio_ctrl_info.gpio_ctrl_state[i].gpio_state[j] = NULL; -+ } -+ } -+ } -+ -+ pr_err("wmt_gpio: gpio init start!\n"); -+ -+ if (gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_PMU_EN_PIN].gpio_state[GPIO_PULL_DIS]) { -+ pinctrl_select_state(gpio_ctrl_info.pinctrl_info, -+ gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_PMU_EN_PIN]. -+ gpio_state[GPIO_PULL_DIS]); -+ pr_err("wmt_gpio:set GPIO_COMBO_PMU_EN_PIN to GPIO_PULL_DIS done!\n"); -+ } else -+ pr_err("wmt_gpio:set GPIO_COMBO_PMU_EN_PIN to GPIO_PULL_DIS fail, is NULL!\n"); -+ -+ if (DEFAULT_PIN_ID != gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_PMU_EN_PIN].gpio_num) { -+ gpio_direction_output(gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_PMU_EN_PIN].gpio_num, -+ 0); -+ pr_err("wmt_gpio:set GPIO_COMBO_PMU_EN_PIN out to 0: %d!\n", -+ gpio_get_value(gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_PMU_EN_PIN].gpio_num)); -+ } -+ -+ if (gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_RST_PIN].gpio_state[GPIO_PULL_DIS]) { -+ pinctrl_select_state(gpio_ctrl_info.pinctrl_info, -+ gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_RST_PIN].gpio_state[GPIO_PULL_DIS]); -+ pr_err("wmt_gpio:set GPIO_COMBO_RST_PIN to GPIO_PULL_DIS done!\n"); -+ } else -+ pr_err("wmt_gpio:set GPIO_COMBO_RST_PIN to GPIO_PULL_DIS fail, is NULL!\n"); -+ -+ if (DEFAULT_PIN_ID != gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_RST_PIN].gpio_num) { -+ gpio_direction_output(gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_RST_PIN].gpio_num, -+ 0); -+ pr_err("wmt_gpio:set GPIO_COMBO_RST_PIN out to 0: %d!\n", -+ gpio_get_value(gpio_ctrl_info.gpio_ctrl_state[GPIO_COMBO_RST_PIN].gpio_num)); -+ } -+ -+ if (gpio_ctrl_info.gpio_ctrl_state[GPIO_WIFI_EINT_PIN].gpio_state[GPIO_IN_PULLUP]) { -+ pinctrl_select_state(gpio_ctrl_info.pinctrl_info, -+ gpio_ctrl_info.gpio_ctrl_state[GPIO_WIFI_EINT_PIN].gpio_state[GPIO_IN_PULLUP]); -+ pr_err("wmt_gpio:set GPIO_WIFI_EINT_PIN to GPIO_IN_PULLUP done!\n"); -+ } else -+ pr_err("wmt_gpio:set GPIO_WIFI_EINT_PIN to GPIO_IN_PULLUP fail, is NULL!\n"); -+ -+ if (gpio_ctrl_info.gpio_ctrl_state[GPIO_PCM_DAICLK_PIN].gpio_state[GPIO_PULL_DIS]) { -+ pinctrl_select_state(gpio_ctrl_info.pinctrl_info, -+ gpio_ctrl_info.gpio_ctrl_state[GPIO_PCM_DAICLK_PIN].gpio_state[GPIO_PULL_DIS]); -+ pr_err("wmt_gpio:set GPIO_PCM_DAICLK_PIN to GPIO_PULL_DIS done!\n"); -+ } else -+ pr_err("wmt_gpio:set GPIO_PCM_DAICLK_PIN to GPIO_PULL_DIS fail, is NULL!\n"); -+ -+ if (gpio_ctrl_info.gpio_ctrl_state[GPIO_PCM_DAIPCMIN_PIN].gpio_state[GPIO_PULL_DIS]) { -+ pinctrl_select_state(gpio_ctrl_info.pinctrl_info, -+ gpio_ctrl_info.gpio_ctrl_state[GPIO_PCM_DAIPCMIN_PIN]. -+ gpio_state[GPIO_PULL_DIS]); -+ pr_err("wmt_gpio:set GPIO_PCM_DAIPCMIN_PIN to GPIO_PULL_DIS done!\n"); -+ } else -+ pr_err("wmt_gpio:set GPIO_PCM_DAIPCMIN_PIN to GPIO_PULL_DIS fail, is NULL!\n"); -+ -+ if (gpio_ctrl_info.gpio_ctrl_state[GPIO_PCM_DAIPCMOUT_PIN].gpio_state[GPIO_PULL_DIS]) { -+ pinctrl_select_state(gpio_ctrl_info.pinctrl_info, -+ gpio_ctrl_info.gpio_ctrl_state[GPIO_PCM_DAIPCMOUT_PIN]. -+ gpio_state[GPIO_PULL_DIS]); -+ pr_err("wmt_gpio:set GPIO_PCM_DAIPCMOUT_PIN to GPIO_PULL_DIS done!\n"); -+ } else -+ pr_err("wmt_gpio:set GPIO_PCM_DAIPCMOUT_PIN to GPIO_PULL_DIS fail, is NULL!\n"); -+ -+ if (gpio_ctrl_info.gpio_ctrl_state[GPIO_PCM_DAISYNC_PIN].gpio_state[GPIO_PULL_DIS]) { -+ pinctrl_select_state(gpio_ctrl_info.pinctrl_info, -+ gpio_ctrl_info.gpio_ctrl_state[GPIO_PCM_DAISYNC_PIN]. -+ gpio_state[GPIO_PULL_DIS]); -+ pr_err("wmt_gpio:set GPIO_PCM_DAISYNC_PIN to GPIO_PULL_DIS done!\n"); -+ } else -+ pr_err("wmt_gpio:set GPIO_PCM_DAISYNC_PIN to GPIO_PULL_DIS fail, is NULL!\n"); -+ -+ pr_err("wmt_gpio: gpio init done!\n"); -+ } else { -+ pr_err("wmt_gpio:can't find pinctrl dev!\n"); -+ iret = -1; -+ } -+err: -+ return iret; -+} -+ -+INT32 wmt_gpio_deinit(VOID) -+{ -+ INT32 iret = 0; -+ UINT32 i; -+ UINT32 j; -+ -+ for (i = 0; i < GPIO_PIN_ID_MAX; i++) { -+ gpio_ctrl_info.gpio_ctrl_state[i].gpio_num = DEFAULT_PIN_ID; -+ if (DEFAULT_PIN_ID != gpio_ctrl_info.gpio_ctrl_state[i].gpio_num) { -+ for (j = 0; j < GPIO_STATE_MAX; j++) { -+ if (0 != strlen(gpio_state_name[i][j])) -+ gpio_ctrl_info.gpio_ctrl_state[i].gpio_state[j] = NULL; -+ } -+ } -+ } -+ if (gpio_ctrl_info.pinctrl_info) { -+ devm_pinctrl_put(gpio_ctrl_info.pinctrl_info); -+ gpio_ctrl_info.pinctrl_info = NULL; -+ } -+ -+ return iret; -+} -diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/wmt_gpio.h b/drivers/misc/mediatek/connectivity/common/common_detect/wmt_gpio.h -new file mode 100644 -index 000000000000..cd935bfddd99 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/common_detect/wmt_gpio.h -@@ -0,0 +1,103 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -+ -+#ifndef _WMT_GPIO_H_ -+#define _WMT_GPIO_H_ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include "osal.h" -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+#define DEFAULT_PIN_ID (0xffffffff) -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+typedef enum _ENUM_GPIO_PIN_ID { -+ GPIO_COMBO_LDO_EN_PIN = 0, -+ GPIO_COMBO_PMUV28_EN_PIN, -+ GPIO_COMBO_PMU_EN_PIN, -+ GPIO_COMBO_RST_PIN, -+ GPIO_COMBO_BGF_EINT_PIN, -+ GPIO_WIFI_EINT_PIN, -+ GPIO_COMBO_ALL_EINT_PIN, -+ GPIO_COMBO_URXD_PIN, -+ GPIO_COMBO_UTXD_PIN, -+ GPIO_PCM_DAICLK_PIN, -+ GPIO_PCM_DAIPCMIN_PIN, -+ GPIO_PCM_DAIPCMOUT_PIN, -+ GPIO_PCM_DAISYNC_PIN, -+ GPIO_COMBO_I2S_CK_PIN, -+ GPIO_COMBO_I2S_WS_PIN, -+ GPIO_COMBO_I2S_DAT_PIN, -+ GPIO_GPS_SYNC_PIN, -+ GPIO_GPS_LNA_PIN, -+ GPIO_PIN_ID_MAX -+} ENUM_GPIO_PIN_ID, *P_ENUM_GPIO_PIN_ID; -+ -+typedef enum _ENUM_GPIO_STATE_ID { -+ GPIO_PULL_DIS = 0, -+ GPIO_PULL_DOWN, -+ GPIO_PULL_UP, -+ GPIO_OUT_LOW, -+ GPIO_OUT_HIGH, -+ GPIO_IN_DIS, -+ GPIO_IN_EN, -+ GPIO_IN_PULL_DIS, -+ GPIO_IN_PULLDOWN, -+ GPIO_IN_PULLUP, -+ GPIO_STATE_MAX, -+} ENUM_GPIO_STATE_ID, *P_ENUM_GPIO_STATE_ID; -+ -+typedef struct _GPIO_CTRL_STATE { -+ INT32 gpio_num; -+ struct pinctrl_state *gpio_state[GPIO_STATE_MAX]; -+} GPIO_CTRL_STATE, *P_GPIO_CTRL_STATE; -+ -+typedef struct _GPIO_CTRL_INFO { -+ struct pinctrl *pinctrl_info; -+ GPIO_CTRL_STATE gpio_ctrl_state[GPIO_PIN_ID_MAX]; -+} GPIO_CTRL_INFO, *P_GPIO_CTRL_INFO; -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+extern const PUINT8 gpio_state_name[GPIO_PIN_ID_MAX][GPIO_STATE_MAX]; -+extern const PUINT8 gpio_pin_name[GPIO_PIN_ID_MAX]; -+extern GPIO_CTRL_INFO gpio_ctrl_info; -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+INT32 wmt_gpio_init(struct platform_device *pdev); -+ -+INT32 wmt_gpio_deinit(VOID); -+ -+#endif -diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/wmt_stp_exp.c b/drivers/misc/mediatek/connectivity/common/common_detect/wmt_stp_exp.c -new file mode 100644 -index 000000000000..4fc3144b3ba6 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/common_detect/wmt_stp_exp.c -@@ -0,0 +1,480 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -+#include "osal_typedef.h" -+#include "wmt_stp_exp.h" -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+#ifdef DFT_TAG -+#undef DFT_TAG -+#endif -+#define DFT_TAG "[WMT-STP-EXP]" -+ -+#define WMT_STP_EXP_INFO_FUNC(fmt, arg...) pr_debug(DFT_TAG "[I]%s: " fmt, __func__ , ##arg) -+#define WMT_STP_EXP_WARN_FUNC(fmt, arg...) pr_warn(DFT_TAG "[W]%s: " fmt, __func__ , ##arg) -+#define WMT_STP_EXP_ERR_FUNC(fmt, arg...) pr_err(DFT_TAG "[E]%s(%d):ERROR! " fmt, __func__ , __LINE__, ##arg) -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+#ifdef MTK_WCN_WMT_STP_EXP_SYMBOL_ABSTRACT -+/*STP exp*/ -+MTK_WCN_STP_SEND_DATA mtk_wcn_stp_send_data_f = NULL; -+MTK_WCN_STP_SEND_DATA mtk_wcn_stp_send_data_raw_f = NULL; -+MTK_WCN_STP_PARSER_DATA mtk_wcn_stp_parser_data_f = NULL; -+MTK_WCN_STP_RECV_DATA mtk_wcn_stp_receive_data_f = NULL; -+MTK_WCN_STP_IS_RXQ_EMPTY mtk_wcn_stp_is_rxqueue_empty_f = NULL; -+MTK_WCN_STP_IS_RDY mtk_wcn_stp_is_ready_f = NULL; -+MTK_WCN_STP_SET_BLUEZ mtk_wcn_stp_set_bluez_f = NULL; -+MTK_WCN_STP_REG_IF_TX mtk_wcn_stp_if_tx_f = NULL; -+MTK_WCN_STP_REG_IF_RX mtk_wcn_stp_if_rx_f = NULL; -+MTK_WCN_STP_REG_EVENT_CB mtk_wcn_stp_reg_event_cb_f = NULL; -+MTK_WCN_STP_RGE_TX_EVENT_CB mtk_wcn_stp_reg_tx_event_cb_f = NULL; -+MTK_WCN_STP_COREDUMP_START_GET mtk_wcn_stp_coredump_start_get_f = NULL; -+ -+/*WMT exp*/ -+MTK_WCN_WMT_FUNC_CTRL mtk_wcn_wmt_func_on_f = NULL; -+MTK_WCN_WMT_FUNC_CTRL mtk_wcn_wmt_func_off_f = NULL; -+MTK_WCN_WMT_THERM_CTRL mtk_wcn_wmt_therm_ctrl_f = NULL; -+MTK_WCN_WMT_HWVER_GET mtk_wcn_wmt_hwver_get_f = NULL; -+MTK_WCN_WMT_DSNS_CTRL mtk_wcn_wmt_dsns_ctrl_f = NULL; -+MTK_WCN_WMT_MSGCB_REG mtk_wcn_wmt_msgcb_reg_f = NULL; -+MTK_WCN_WMT_MSGCB_UNREG mtk_wcn_wmt_msgcb_unreg_f = NULL; -+MTK_WCN_WMT_SDIO_OP_REG mtk_wcn_wmt_sdio_op_reg_f = NULL; -+MTK_WCN_WMT_SDIO_HOST_AWAKE mtk_wcn_wmt_sdio_host_awake_f = NULL; -+MTK_WCN_WMT_ASSERT mtk_wcn_wmt_assert_f = NULL; -+MTK_WCN_WMT_ASSERT_TIMEOUT mtk_wcn_wmt_assert_timeout_f = NULL; -+MTK_WCN_WMT_IC_INFO_GET mtk_wcn_wmt_ic_info_get_f = NULL; -+MTK_WCN_WMT_PSM_CTRL mtk_wcn_wmt_psm_ctrl_f = NULL; -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+UINT32 mtk_wcn_stp_exp_cb_reg(P_MTK_WCN_STP_EXP_CB_INFO pStpExpCb) -+{ -+ WMT_STP_EXP_INFO_FUNC("call stp exp cb reg\n"); -+ -+ mtk_wcn_stp_send_data_f = pStpExpCb->stp_send_data_cb; -+ mtk_wcn_stp_send_data_raw_f = pStpExpCb->stp_send_data_raw_cb; -+ mtk_wcn_stp_parser_data_f = pStpExpCb->stp_parser_data_cb; -+ mtk_wcn_stp_receive_data_f = pStpExpCb->stp_receive_data_cb; -+ mtk_wcn_stp_is_rxqueue_empty_f = pStpExpCb->stp_is_rxqueue_empty_cb; -+ mtk_wcn_stp_is_ready_f = pStpExpCb->stp_is_ready_cb; -+ mtk_wcn_stp_set_bluez_f = pStpExpCb->stp_set_bluez_cb; -+ mtk_wcn_stp_if_tx_f = pStpExpCb->stp_if_tx_cb; -+ mtk_wcn_stp_if_rx_f = pStpExpCb->stp_if_rx_cb; -+ mtk_wcn_stp_reg_event_cb_f = pStpExpCb->stp_reg_event_cb; -+ mtk_wcn_stp_reg_tx_event_cb_f = pStpExpCb->stp_reg_tx_event_cb; -+ mtk_wcn_stp_coredump_start_get_f = pStpExpCb->stp_coredump_start_get_cb; -+ -+ return 0; -+} -+EXPORT_SYMBOL(mtk_wcn_stp_exp_cb_reg); -+ -+UINT32 mtk_wcn_stp_exp_cb_unreg(VOID) -+{ -+ WMT_STP_EXP_INFO_FUNC("call stp exp cb unreg\n"); -+ -+ mtk_wcn_stp_send_data_f = NULL; -+ mtk_wcn_stp_send_data_raw_f = NULL; -+ mtk_wcn_stp_parser_data_f = NULL; -+ mtk_wcn_stp_receive_data_f = NULL; -+ mtk_wcn_stp_is_rxqueue_empty_f = NULL; -+ mtk_wcn_stp_is_ready_f = NULL; -+ mtk_wcn_stp_set_bluez_f = NULL; -+ mtk_wcn_stp_if_tx_f = NULL; -+ mtk_wcn_stp_if_rx_f = NULL; -+ mtk_wcn_stp_reg_event_cb_f = NULL; -+ mtk_wcn_stp_reg_tx_event_cb_f = NULL; -+ mtk_wcn_stp_coredump_start_get_f = NULL; -+ -+ return 0; -+} -+EXPORT_SYMBOL(mtk_wcn_stp_exp_cb_unreg); -+ -+INT32 mtk_wcn_stp_send_data(const PUINT8 buffer, const UINT32 length, const UINT8 type) -+{ -+ INT32 ret = -1; -+ -+ if (mtk_wcn_stp_send_data_f) { -+ ret = (*mtk_wcn_stp_send_data_f) (buffer, length, type); -+ /* WMT_STP_EXP_INFO_FUNC("mtk_wcn_stp_send_data_f send data(%d)\n",ret); */ -+ } else { -+ WMT_STP_EXP_ERR_FUNC("mtk_wcn_stp_send_data_f cb is null\n"); -+ } -+ -+ return ret; -+ -+} -+EXPORT_SYMBOL(mtk_wcn_stp_send_data); -+ -+INT32 mtk_wcn_stp_send_data_raw(const PUINT8 buffer, const UINT32 length, const UINT8 type) -+{ -+ INT32 ret = -1; -+ -+ if (mtk_wcn_stp_send_data_raw_f) -+ ret = (*mtk_wcn_stp_send_data_raw_f) (buffer, length, type); -+ else -+ WMT_STP_EXP_ERR_FUNC("mtk_wcn_stp_send_data_raw_f cb is null\n"); -+ -+ return ret; -+} -+EXPORT_SYMBOL(mtk_wcn_stp_send_data_raw); -+ -+INT32 mtk_wcn_stp_parser_data(PUINT8 buffer, UINT32 length) -+{ -+ INT32 ret = -1; -+ -+ if (mtk_wcn_stp_parser_data_f) -+ ret = (*mtk_wcn_stp_parser_data_f) (buffer, length); -+ else -+ WMT_STP_EXP_ERR_FUNC("mtk_wcn_stp_parser_data_f cb is null\n"); -+ -+ return ret; -+} -+EXPORT_SYMBOL(mtk_wcn_stp_parser_data); -+ -+INT32 mtk_wcn_stp_receive_data(PUINT8 buffer, UINT32 length, UINT8 type) -+{ -+ INT32 ret = -1; -+ -+ if (mtk_wcn_stp_receive_data_f) -+ ret = (*mtk_wcn_stp_receive_data_f) (buffer, length, type); -+ else -+ WMT_STP_EXP_ERR_FUNC("mtk_wcn_stp_receive_data_f cb is null\n"); -+ -+ return ret; -+} -+EXPORT_SYMBOL(mtk_wcn_stp_receive_data); -+ -+MTK_WCN_BOOL mtk_wcn_stp_is_rxqueue_empty(UINT8 type) -+{ -+ MTK_WCN_BOOL ret = MTK_WCN_BOOL_FALSE; -+ -+ if (mtk_wcn_stp_is_rxqueue_empty_f) -+ ret = (*mtk_wcn_stp_is_rxqueue_empty_f) (type); -+ else -+ WMT_STP_EXP_ERR_FUNC("mtk_wcn_stp_is_rxqueue_empty_f cb is null\n"); -+ -+ return ret; -+} -+EXPORT_SYMBOL(mtk_wcn_stp_is_rxqueue_empty); -+ -+MTK_WCN_BOOL mtk_wcn_stp_is_ready(void) -+{ -+ MTK_WCN_BOOL ret = MTK_WCN_BOOL_FALSE; -+ -+ if (mtk_wcn_stp_is_ready_f) -+ ret = (*mtk_wcn_stp_is_ready_f) (); -+ else -+ WMT_STP_EXP_ERR_FUNC("mtk_wcn_stp_is_ready_f cb is null\n"); -+ -+ return ret; -+} -+EXPORT_SYMBOL(mtk_wcn_stp_is_ready); -+ -+void mtk_wcn_stp_set_bluez(MTK_WCN_BOOL flags) -+{ -+ -+ if (mtk_wcn_stp_set_bluez_f) -+ (*mtk_wcn_stp_set_bluez_f) (flags); -+ else -+ WMT_STP_EXP_ERR_FUNC("mtk_wcn_stp_set_bluez_f cb is null\n"); -+ -+} -+EXPORT_SYMBOL(mtk_wcn_stp_set_bluez); -+ -+INT32 mtk_wcn_stp_register_if_tx(ENUM_STP_TX_IF_TYPE stp_if, MTK_WCN_STP_IF_TX func) -+{ -+ INT32 ret = -1; -+ -+ if (mtk_wcn_stp_if_tx_f) -+ ret = (*mtk_wcn_stp_if_tx_f) (stp_if, func); -+ else -+ WMT_STP_EXP_ERR_FUNC("mtk_wcn_stp_if_tx_f cb is null\n"); -+ -+ return ret; -+} -+EXPORT_SYMBOL(mtk_wcn_stp_register_if_tx); -+ -+INT32 mtk_wcn_stp_register_if_rx(MTK_WCN_STP_IF_RX func) -+{ -+ INT32 ret = -1; -+ -+ if (mtk_wcn_stp_if_rx_f) -+ ret = (*mtk_wcn_stp_if_rx_f) (func); -+ else -+ WMT_STP_EXP_ERR_FUNC("mtk_wcn_stp_if_rx_f cb is null\n"); -+ -+ return ret; -+} -+EXPORT_SYMBOL(mtk_wcn_stp_register_if_rx); -+ -+INT32 mtk_wcn_stp_register_event_cb(INT32 type, MTK_WCN_STP_EVENT_CB func) -+{ -+ INT32 ret = -1; -+ -+ if (mtk_wcn_stp_reg_event_cb_f) -+ ret = (*mtk_wcn_stp_reg_event_cb_f) (type, func); -+ else -+ WMT_STP_EXP_ERR_FUNC("mtk_wcn_stp_reg_event_cb_f cb is null\n"); -+ -+ return ret; -+} -+EXPORT_SYMBOL(mtk_wcn_stp_register_event_cb); -+ -+INT32 mtk_wcn_stp_register_tx_event_cb(INT32 type, MTK_WCN_STP_EVENT_CB func) -+{ -+ INT32 ret = -1; -+ -+ if (mtk_wcn_stp_reg_tx_event_cb_f) -+ ret = (*mtk_wcn_stp_reg_tx_event_cb_f) (type, func); -+ else -+ WMT_STP_EXP_ERR_FUNC("mtk_wcn_stp_reg_tx_event_cb_f cb is null\n"); -+ -+ return ret; -+} -+EXPORT_SYMBOL(mtk_wcn_stp_register_tx_event_cb); -+ -+INT32 mtk_wcn_stp_coredump_start_get(VOID) -+{ -+ INT32 ret = -1; -+ -+ if (mtk_wcn_stp_coredump_start_get_f) -+ ret = (*mtk_wcn_stp_coredump_start_get_f) (); -+ else -+ WMT_STP_EXP_ERR_FUNC("mtk_wcn_stp_coredump_start_get_f cb is null\n"); -+ -+ return ret; -+} -+EXPORT_SYMBOL(mtk_wcn_stp_coredump_start_get); -+ -+UINT32 mtk_wcn_wmt_exp_cb_reg(P_MTK_WCN_WMT_EXP_CB_INFO pWmtExpCb) -+{ -+ WMT_STP_EXP_INFO_FUNC("call wmt exp cb reg\n"); -+ -+ mtk_wcn_wmt_func_on_f = pWmtExpCb->wmt_func_on_cb; -+ mtk_wcn_wmt_func_off_f = pWmtExpCb->wmt_func_off_cb; -+ mtk_wcn_wmt_therm_ctrl_f = pWmtExpCb->wmt_therm_ctrl_cb; -+ mtk_wcn_wmt_hwver_get_f = pWmtExpCb->wmt_hwver_get_cb; -+ mtk_wcn_wmt_dsns_ctrl_f = pWmtExpCb->wmt_dsns_ctrl_cb; -+ mtk_wcn_wmt_msgcb_reg_f = pWmtExpCb->wmt_msgcb_reg_cb; -+ mtk_wcn_wmt_msgcb_unreg_f = pWmtExpCb->wmt_msgcb_unreg_cb; -+ mtk_wcn_wmt_sdio_op_reg_f = pWmtExpCb->wmt_sdio_op_reg_cb; -+ mtk_wcn_wmt_sdio_host_awake_f = pWmtExpCb->wmt_sdio_host_awake_cb; -+ mtk_wcn_wmt_assert_f = pWmtExpCb->wmt_assert_cb; -+ mtk_wcn_wmt_assert_timeout_f = pWmtExpCb->wmt_assert_timeout_cb; -+ mtk_wcn_wmt_ic_info_get_f = pWmtExpCb->wmt_ic_info_get_cb; -+ mtk_wcn_wmt_psm_ctrl_f = pWmtExpCb->wmt_psm_ctrl_cb; -+ return 0; -+} -+EXPORT_SYMBOL(mtk_wcn_wmt_exp_cb_reg); -+ -+UINT32 mtk_wcn_wmt_exp_cb_unreg(VOID) -+{ -+ WMT_STP_EXP_INFO_FUNC("call wmt exp cb unreg\n"); -+ -+ mtk_wcn_wmt_func_on_f = NULL; -+ mtk_wcn_wmt_func_off_f = NULL; -+ mtk_wcn_wmt_therm_ctrl_f = NULL; -+ mtk_wcn_wmt_hwver_get_f = NULL; -+ mtk_wcn_wmt_dsns_ctrl_f = NULL; -+ mtk_wcn_wmt_msgcb_reg_f = NULL; -+ mtk_wcn_wmt_msgcb_unreg_f = NULL; -+ mtk_wcn_wmt_sdio_op_reg_f = NULL; -+ mtk_wcn_wmt_sdio_host_awake_f = NULL; -+ mtk_wcn_wmt_assert_f = NULL; -+ mtk_wcn_wmt_assert_timeout_f = NULL; -+ mtk_wcn_wmt_ic_info_get_f = NULL; -+ mtk_wcn_wmt_psm_ctrl_f = NULL; -+ -+ return 0; -+} -+EXPORT_SYMBOL(mtk_wcn_wmt_exp_cb_unreg); -+ -+MTK_WCN_BOOL mtk_wcn_wmt_func_off(ENUM_WMTDRV_TYPE_T type) -+{ -+ MTK_WCN_BOOL ret = MTK_WCN_BOOL_FALSE; -+ -+ if (mtk_wcn_wmt_func_off_f) -+ ret = (*mtk_wcn_wmt_func_off_f) (type); -+ else -+ WMT_STP_EXP_ERR_FUNC("mtk_wcn_wmt_func_off_f cb is null\n"); -+ -+ return ret; -+} -+EXPORT_SYMBOL(mtk_wcn_wmt_func_off); -+ -+MTK_WCN_BOOL mtk_wcn_wmt_func_on(ENUM_WMTDRV_TYPE_T type) -+{ -+ MTK_WCN_BOOL ret = MTK_WCN_BOOL_FALSE; -+ -+ if (mtk_wcn_wmt_func_on_f) { -+ ret = (*mtk_wcn_wmt_func_on_f) (type); -+ WMT_STP_EXP_INFO_FUNC("mtk_wcn_wmt_func_on_f type(%d)\n", type); -+ } else -+ WMT_STP_EXP_ERR_FUNC("mtk_wcn_wmt_func_on_f cb is null\n"); -+ -+ return ret; -+} -+EXPORT_SYMBOL(mtk_wcn_wmt_func_on); -+ -+INT8 mtk_wcn_wmt_therm_ctrl(ENUM_WMTTHERM_TYPE_T eType) -+{ -+ INT32 ret = -1; -+ -+ if (mtk_wcn_wmt_therm_ctrl_f) -+ ret = (*mtk_wcn_wmt_therm_ctrl_f) (eType); -+ else -+ WMT_STP_EXP_ERR_FUNC("mtk_wcn_wmt_therm_ctrl_f cb is null\n"); -+ -+ return ret; -+} -+EXPORT_SYMBOL(mtk_wcn_wmt_therm_ctrl); -+ -+ENUM_WMTHWVER_TYPE_T mtk_wcn_wmt_hwver_get(VOID) -+{ -+ ENUM_WMTHWVER_TYPE_T ret = WMTHWVER_INVALID; -+ -+ if (mtk_wcn_wmt_hwver_get_f) -+ ret = (*mtk_wcn_wmt_hwver_get_f) (); -+ else -+ WMT_STP_EXP_ERR_FUNC("mtk_wcn_wmt_hwver_get_f cb is null\n"); -+ -+ return ret; -+} -+EXPORT_SYMBOL(mtk_wcn_wmt_hwver_get); -+ -+MTK_WCN_BOOL mtk_wcn_wmt_dsns_ctrl(ENUM_WMTDSNS_TYPE_T eType) -+{ -+ MTK_WCN_BOOL ret = MTK_WCN_BOOL_FALSE; -+ -+ if (mtk_wcn_wmt_dsns_ctrl_f) -+ ret = (*mtk_wcn_wmt_dsns_ctrl_f) (eType); -+ else -+ WMT_STP_EXP_ERR_FUNC("mtk_wcn_wmt_dsns_ctrl_f cb is null\n"); -+ -+ return ret; -+} -+EXPORT_SYMBOL(mtk_wcn_wmt_dsns_ctrl); -+ -+INT32 mtk_wcn_wmt_msgcb_reg(ENUM_WMTDRV_TYPE_T eType, PF_WMT_CB pCb) -+{ -+ INT32 ret = 0; -+ -+ if (mtk_wcn_wmt_msgcb_reg_f) -+ ret = (*mtk_wcn_wmt_msgcb_reg_f) (eType, pCb); -+ else -+ WMT_STP_EXP_ERR_FUNC("mtk_wcn_wmt_msgcb_reg_f cb is null\n"); -+ -+ return ret; -+} -+EXPORT_SYMBOL(mtk_wcn_wmt_msgcb_reg); -+ -+INT32 mtk_wcn_wmt_msgcb_unreg(ENUM_WMTDRV_TYPE_T eType) -+{ -+ INT32 ret = 0; -+ -+ if (mtk_wcn_wmt_msgcb_unreg_f) -+ ret = (*mtk_wcn_wmt_msgcb_unreg_f) (eType); -+ else -+ WMT_STP_EXP_ERR_FUNC("mtk_wcn_wmt_msgcb_unreg_f cb is null\n"); -+ -+ return ret; -+} -+EXPORT_SYMBOL(mtk_wcn_wmt_msgcb_unreg); -+ -+INT32 mtk_wcn_stp_wmt_sdio_op_reg(PF_WMT_SDIO_PSOP own_cb) -+{ -+ INT32 ret = -1; -+ -+ if (mtk_wcn_wmt_sdio_op_reg_f) -+ ret = (*mtk_wcn_wmt_sdio_op_reg_f) (own_cb); -+ else -+ WMT_STP_EXP_ERR_FUNC("mtk_wcn_wmt_sdio_op_reg_f cb is null\n"); -+ -+ return ret; -+} -+EXPORT_SYMBOL(mtk_wcn_stp_wmt_sdio_op_reg); -+ -+INT32 mtk_wcn_stp_wmt_sdio_host_awake(VOID) -+{ -+ INT32 ret = -1; -+ -+ if (mtk_wcn_wmt_sdio_host_awake_f) -+ ret = (*mtk_wcn_wmt_sdio_host_awake_f) (); -+ else -+ WMT_STP_EXP_ERR_FUNC("mtk_wcn_wmt_sdio_host_awake_f cb is null\n"); -+ -+ return ret; -+} -+EXPORT_SYMBOL(mtk_wcn_stp_wmt_sdio_host_awake); -+ -+MTK_WCN_BOOL mtk_wcn_wmt_assert(ENUM_WMTDRV_TYPE_T type, UINT32 reason) -+{ -+ MTK_WCN_BOOL ret = MTK_WCN_BOOL_FALSE; -+ -+ if (mtk_wcn_wmt_assert_f) -+ ret = (*mtk_wcn_wmt_assert_f) (type, reason); -+ else -+ WMT_STP_EXP_ERR_FUNC("mtk_wcn_wmt_assert_f cb is null\n"); -+ -+ return ret; -+} -+EXPORT_SYMBOL(mtk_wcn_wmt_assert); -+ -+MTK_WCN_BOOL mtk_wcn_wmt_assert_timeout(ENUM_WMTDRV_TYPE_T type, UINT32 reason, INT32 timeout) -+{ -+ MTK_WCN_BOOL ret = MTK_WCN_BOOL_FALSE; -+ -+ if (mtk_wcn_wmt_assert_timeout_f) -+ ret = (*mtk_wcn_wmt_assert_timeout_f)(type, reason, timeout); -+ else -+ WMT_STP_EXP_ERR_FUNC("mtk_wcn_wmt_assert_timeout_f cb is null\n"); -+ return ret; -+} -+EXPORT_SYMBOL(mtk_wcn_wmt_assert_timeout); -+ -+UINT32 mtk_wcn_wmt_ic_info_get(ENUM_WMT_CHIPINFO_TYPE_T type) -+{ -+ UINT32 ret = 0; -+ -+ if (mtk_wcn_wmt_ic_info_get_f) -+ ret = (*mtk_wcn_wmt_ic_info_get_f) (type); -+ else -+ WMT_STP_EXP_ERR_FUNC("mtk_wcn_wmt_ic_info_get_f cb is null\n"); -+ -+ return ret; -+} -+EXPORT_SYMBOL(mtk_wcn_wmt_ic_info_get); -+ -+INT32 mtk_wcn_wmt_psm_ctrl(MTK_WCN_BOOL flag) -+{ -+ UINT32 ret = 0; -+ -+ if (mtk_wcn_wmt_psm_ctrl_f) -+ ret = (*mtk_wcn_wmt_psm_ctrl_f)(flag); -+ else -+ WMT_STP_EXP_ERR_FUNC("mtk_wcn_wmt_psm_ctrl_f cb is null\n"); -+ -+ return ret; -+} -+EXPORT_SYMBOL(mtk_wcn_wmt_psm_ctrl); -+ -+#endif -diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/wmt_stp_exp.h b/drivers/misc/mediatek/connectivity/common/common_detect/wmt_stp_exp.h -new file mode 100644 -index 000000000000..1c3dc8965298 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/common_detect/wmt_stp_exp.h -@@ -0,0 +1,610 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -+ -+#ifndef _WMT_STP_EXP_H_ -+#define _WMT_STP_EXP_H_ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include "osal_typedef.h" -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+#ifndef MTK_WCN_CMB_FOR_SDIO_1V_AUTOK -+#define MTK_WCN_CMB_FOR_SDIO_1V_AUTOK 0 -+#endif -+ -+#ifdef MTK_WCN_WMT_STP_EXP_SYMBOL_ABSTRACT -+ -+#if (WMT_IDC_SUPPORT) -+#define CFG_WMT_LTE_COEX_HANDLING 1 -+#define CFG_WMT_LTE_ENABLE_MSGID_MAPPING 0 -+#else -+#define CFG_WMT_LTE_COEX_HANDLING 0 -+#endif -+ -+/*from stp_exp.h*/ -+#define BT_TASK_INDX (0) -+#define FM_TASK_INDX (1) -+#define GPS_TASK_INDX (2) -+#define WIFI_TASK_INDX (3) -+#define WMT_TASK_INDX (4) -+#define STP_TASK_INDX (5) -+#define INFO_TASK_INDX (6) -+#define ANT_TASK_INDX (7) -+#if CFG_WMT_LTE_COEX_HANDLING -+#define COEX_TASK_INDX (8) -+#define MTKSTP_MAX_TASK_NUM (9) -+#else -+#define MTKSTP_MAX_TASK_NUM (8) -+#endif -+ -+#define MTKSTP_BUFFER_SIZE (16384) /* Size of RX Queue */ -+/*end from stp_exp.h*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+********************************************************************************/ -+ -+/*moved from stp_exp.h*/ -+typedef void (*MTK_WCN_STP_EVENT_CB) (void); -+typedef INT32(*MTK_WCN_STP_IF_TX) (const PUINT8 data, const UINT32 size, PUINT32 written_size); -+/* export for HIF driver */ -+typedef void (*MTK_WCN_STP_IF_RX) (const PUINT8 data, INT32 size); -+ -+typedef enum { -+ STP_UART_IF_TX = 0, -+ STP_SDIO_IF_TX = 1, -+ STP_BTIF_IF_TX = 2, -+ STP_MAX_IF_TX -+} ENUM_STP_TX_IF_TYPE; -+ -+/*end moved from stp_exp.h*/ -+ -+typedef INT32(*MTK_WCN_STP_SEND_DATA) (const PUINT8 buffer, const UINT32 length, const UINT8 type); -+typedef INT32(*MTK_WCN_STP_PARSER_DATA) (PUINT8 buffer, UINT32 length); -+typedef INT32(*MTK_WCN_STP_RECV_DATA) (PUINT8 buffer, UINT32 length, UINT8 type); -+typedef MTK_WCN_BOOL(*MTK_WCN_STP_IS_RXQ_EMPTY) (UINT8 type); -+typedef MTK_WCN_BOOL(*MTK_WCN_STP_IS_RDY) (VOID); -+typedef VOID(*MTK_WCN_STP_SET_BLUEZ) (MTK_WCN_BOOL flags); -+typedef INT32(*MTK_WCN_STP_REG_IF_TX) (ENUM_STP_TX_IF_TYPE stp_if, MTK_WCN_STP_IF_TX func); -+typedef INT32(*MTK_WCN_STP_REG_IF_RX) (MTK_WCN_STP_IF_RX func); -+typedef INT32(*MTK_WCN_STP_REG_EVENT_CB) (INT32 type, MTK_WCN_STP_EVENT_CB func); -+typedef INT32(*MTK_WCN_STP_RGE_TX_EVENT_CB) (INT32 type, MTK_WCN_STP_EVENT_CB func); -+typedef INT32(*MTK_WCN_STP_COREDUMP_START_GET)(VOID); -+ -+typedef struct _MTK_WCN_STP_EXP_CB_INFO_ { -+ MTK_WCN_STP_SEND_DATA stp_send_data_cb; -+ MTK_WCN_STP_SEND_DATA stp_send_data_raw_cb; -+ MTK_WCN_STP_PARSER_DATA stp_parser_data_cb; -+ MTK_WCN_STP_RECV_DATA stp_receive_data_cb; -+ MTK_WCN_STP_IS_RXQ_EMPTY stp_is_rxqueue_empty_cb; -+ MTK_WCN_STP_IS_RDY stp_is_ready_cb; -+ MTK_WCN_STP_SET_BLUEZ stp_set_bluez_cb; -+ MTK_WCN_STP_REG_IF_TX stp_if_tx_cb; -+ MTK_WCN_STP_REG_IF_RX stp_if_rx_cb; -+ MTK_WCN_STP_REG_EVENT_CB stp_reg_event_cb; -+ MTK_WCN_STP_RGE_TX_EVENT_CB stp_reg_tx_event_cb; -+ MTK_WCN_STP_COREDUMP_START_GET stp_coredump_start_get_cb; -+} MTK_WCN_STP_EXP_CB_INFO, *P_MTK_WCN_STP_EXP_CB_INFO; -+ -+/*moved from wmt_exp.h*/ -+ -+typedef enum _ENUM_WMTDRV_TYPE_T { -+ WMTDRV_TYPE_BT = 0, -+ WMTDRV_TYPE_FM = 1, -+ WMTDRV_TYPE_GPS = 2, -+ WMTDRV_TYPE_WIFI = 3, -+ WMTDRV_TYPE_WMT = 4, -+ WMTDRV_TYPE_ANT = 5, -+ WMTDRV_TYPE_STP = 6, -+ WMTDRV_TYPE_SDIO1 = 7, -+ WMTDRV_TYPE_SDIO2 = 8, -+ WMTDRV_TYPE_LPBK = 9, -+ WMTDRV_TYPE_COREDUMP = 10, -+#if MTK_WCN_CMB_FOR_SDIO_1V_AUTOK -+ WMTDRV_TYPE_AUTOK = 11, -+#endif -+ WMTDRV_TYPE_MAX -+} ENUM_WMTDRV_TYPE_T, *P_ENUM_WMTDRV_TYPE_T; -+ -+typedef enum _ENUM_WMTDSNS_TYPE_T { -+ WMTDSNS_FM_DISABLE = 0, -+ WMTDSNS_FM_ENABLE = 1, -+ WMTDSNS_FM_GPS_DISABLE = 2, -+ WMTDSNS_FM_GPS_ENABLE = 3, -+ WMTDSNS_MAX -+} ENUM_WMTDSNS_TYPE_T, *P_ENUM_WMTDSNS_TYPE_T; -+ -+typedef enum _ENUM_WMTHWVER_TYPE_T { -+ WMTHWVER_E1 = 0x0, -+ WMTHWVER_E2 = 0x1, -+ WMTHWVER_E3 = 0x2, -+ WMTHWVER_E4 = 0x3, -+ WMTHWVER_E5 = 0x4, -+ WMTHWVER_E6 = 0x5, -+ WMTHWVER_E7 = 0x6, -+ WMTHWVER_MAX, -+ WMTHWVER_INVALID = 0xff -+} ENUM_WMTHWVER_TYPE_T, *P_ENUM_WMTHWVER_TYPE_T; -+ -+typedef enum _ENUM_WMTTHERM_TYPE_T { -+ WMTTHERM_ZERO = 0, -+ WMTTHERM_ENABLE = WMTTHERM_ZERO + 1, -+ WMTTHERM_READ = WMTTHERM_ENABLE + 1, -+ WMTTHERM_DISABLE = WMTTHERM_READ + 1, -+ WMTTHERM_MAX -+} ENUM_WMTTHERM_TYPE_T, *P_ENUM_WMTTHERM_TYPE_T; -+ -+typedef enum _ENUM_WMTMSG_TYPE_T { -+ WMTMSG_TYPE_POWER_ON = 0, -+ WMTMSG_TYPE_POWER_OFF = 1, -+ WMTMSG_TYPE_RESET = 2, -+ WMTMSG_TYPE_STP_RDY = 3, -+ WMTMSG_TYPE_HW_FUNC_ON = 4, -+ WMTMSG_TYPE_MAX -+} ENUM_WMTMSG_TYPE_T, *P_ENUM_WMTMSG_TYPE_T; -+ -+typedef void (*PF_WMT_CB) (ENUM_WMTDRV_TYPE_T, /* Source driver type */ -+ ENUM_WMTDRV_TYPE_T, /* Destination driver type */ -+ ENUM_WMTMSG_TYPE_T, /* Message type */ -+ VOID *, /* READ-ONLY buffer. Buffer is allocated and freed by WMT_drv. Client -+ can't touch this buffer after this function return. */ -+ UINT32 /* Buffer size in unit of byte */ -+); -+ -+typedef enum _SDIO_PS_OP { -+ OWN_SET = 0, -+ OWN_CLR = 1, -+ OWN_STATE = 2, -+} SDIO_PS_OP; -+ -+typedef INT32(*PF_WMT_SDIO_PSOP) (SDIO_PS_OP); -+ -+typedef enum _ENUM_WMTCHIN_TYPE_T { -+ WMTCHIN_CHIPID = 0x0, -+ WMTCHIN_HWVER = WMTCHIN_CHIPID + 1, -+ WMTCHIN_MAPPINGHWVER = WMTCHIN_HWVER + 1, -+ WMTCHIN_FWVER = WMTCHIN_MAPPINGHWVER + 1, -+ WMTCHIN_MAX, -+ -+} ENUM_WMT_CHIPINFO_TYPE_T, *P_ENUM_WMT_CHIPINFO_TYPE_T; -+ -+/*end moved from wmt_exp.h*/ -+ -+typedef MTK_WCN_BOOL(*MTK_WCN_WMT_FUNC_CTRL) (ENUM_WMTDRV_TYPE_T type); -+typedef INT8(*MTK_WCN_WMT_THERM_CTRL) (ENUM_WMTTHERM_TYPE_T eType); -+typedef ENUM_WMTHWVER_TYPE_T(*MTK_WCN_WMT_HWVER_GET) (VOID); -+typedef MTK_WCN_BOOL(*MTK_WCN_WMT_DSNS_CTRL) (ENUM_WMTDSNS_TYPE_T eType); -+typedef INT32(*MTK_WCN_WMT_MSGCB_REG) (ENUM_WMTDRV_TYPE_T eType, PF_WMT_CB pCb); -+typedef INT32(*MTK_WCN_WMT_MSGCB_UNREG) (ENUM_WMTDRV_TYPE_T eType); -+typedef INT32(*MTK_WCN_WMT_SDIO_OP_REG) (PF_WMT_SDIO_PSOP own_cb); -+typedef INT32(*MTK_WCN_WMT_SDIO_HOST_AWAKE) (VOID); -+typedef MTK_WCN_BOOL(*MTK_WCN_WMT_ASSERT) (ENUM_WMTDRV_TYPE_T type, UINT32 reason); -+typedef MTK_WCN_BOOL(*MTK_WCN_WMT_ASSERT_TIMEOUT)(ENUM_WMTDRV_TYPE_T type, -+ UINT32 reason, INT32 timeout); -+typedef UINT32(*MTK_WCN_WMT_IC_INFO_GET) (ENUM_WMT_CHIPINFO_TYPE_T type); -+typedef INT32 (*MTK_WCN_WMT_PSM_CTRL)(MTK_WCN_BOOL flag); -+ -+typedef struct _MTK_WCN_WMT_EXP_CB_INFO_ { -+ MTK_WCN_WMT_FUNC_CTRL wmt_func_on_cb; -+ MTK_WCN_WMT_FUNC_CTRL wmt_func_off_cb; -+ MTK_WCN_WMT_THERM_CTRL wmt_therm_ctrl_cb; -+ MTK_WCN_WMT_HWVER_GET wmt_hwver_get_cb; -+ MTK_WCN_WMT_DSNS_CTRL wmt_dsns_ctrl_cb; -+ MTK_WCN_WMT_MSGCB_REG wmt_msgcb_reg_cb; -+ MTK_WCN_WMT_MSGCB_UNREG wmt_msgcb_unreg_cb; -+ MTK_WCN_WMT_SDIO_OP_REG wmt_sdio_op_reg_cb; -+ MTK_WCN_WMT_SDIO_HOST_AWAKE wmt_sdio_host_awake_cb; -+ MTK_WCN_WMT_ASSERT wmt_assert_cb; -+ MTK_WCN_WMT_ASSERT_TIMEOUT wmt_assert_timeout_cb; -+ MTK_WCN_WMT_IC_INFO_GET wmt_ic_info_get_cb; -+ MTK_WCN_WMT_PSM_CTRL wmt_psm_ctrl_cb; -+} MTK_WCN_WMT_EXP_CB_INFO, *P_MTK_WCN_WMT_EXP_CB_INFO; -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/*exp for WMT/STP register callback*/ -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_exp_cb_reg -+* DESCRIPTION -+* stp driver reigster exp symbols -+* PARAMETERS -+* pStpExpCb [IN] stp callback structure pointer -+* RETURNS -+* UINT32 = 0: OK -+*****************************************************************************/ -+UINT32 mtk_wcn_stp_exp_cb_reg(P_MTK_WCN_STP_EXP_CB_INFO pStpExpCb); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_exp_cb_unreg -+* DESCRIPTION -+* stp driver unreigster exp symbols -+* PARAMETERS -+* VOID -+* RETURNS -+* UINT32 = 0: OK -+*****************************************************************************/ -+UINT32 mtk_wcn_stp_exp_cb_unreg(VOID); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_wmt_exp_cb_reg -+* DESCRIPTION -+* WMT driver reigster exp symbols -+* PARAMETERS -+* pStpExpCb [IN] wmt callback structure pointer -+* RETURNS -+* UINT32 = 0: OK -+*****************************************************************************/ -+UINT32 mtk_wcn_wmt_exp_cb_reg(P_MTK_WCN_WMT_EXP_CB_INFO pWmtExpCb); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_exp_cb_unreg -+* DESCRIPTION -+* wmt driver unreigster exp symbols -+* PARAMETERS -+* VOID -+* RETURNS -+* UINT32 = 0: OK -+*****************************************************************************/ -+UINT32 mtk_wcn_wmt_exp_cb_unreg(VOID); -+ -+/*stp exp symbols*/ -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_send_data -+* DESCRIPTION -+* subfunction send data through STP -+* PARAMETERS -+* buffer [IN] data buffer -+* length [IN] data buffer length -+* type [IN] subfunction type -+* RETURNS -+* INT32 >= 0: length transmitted; < 0: error -+*****************************************************************************/ -+extern INT32 mtk_wcn_stp_send_data(const PUINT8 buffer, const UINT32 length, const UINT8 type); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_send_data_raw -+* DESCRIPTION -+* subfunction send data through STP without seq/ack -+* PARAMETERS -+* buffer [IN] data buffer -+* length [IN] data buffer length -+* type [IN] subfunction type -+* RETURNS -+* INT32 >= 0: length transmitted; < 0: error -+*****************************************************************************/ -+extern INT32 mtk_wcn_stp_send_data_raw(const PUINT8 buffer, const UINT32 length, const UINT8 type); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_parser_data -+* DESCRIPTION -+* push data to serial transport protocol parser engine -+* PARAMETERS -+* buffer [IN] data buffer -+* length [IN] data buffer length -+* RETURNS -+* void -+*****************************************************************************/ -+extern INT32 mtk_wcn_stp_parser_data(PUINT8 buffer, UINT32 length); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_receive_data -+* DESCRIPTION -+* receive data from serial protocol engine -+* PARAMETERS -+* buffer [IN] data buffer -+* length [IN] data buffer length -+* RETURNS -+* INT32 >= 0: size of data received; < 0: error -+*****************************************************************************/ -+extern INT32 mtk_wcn_stp_receive_data(PUINT8 buffer, UINT32 length, UINT8 type); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_is_rxqueue_empty -+* DESCRIPTION -+* Is certain rx queue empty? -+* PARAMETERS -+* type [IN] subfunction type -+* RETURNS -+* INT32 0: queue is NOT empyt; !0: queue is empty -+*****************************************************************************/ -+extern MTK_WCN_BOOL mtk_wcn_stp_is_rxqueue_empty(UINT8 type); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_is_enable -+* DESCRIPTION -+* Is STP ready? -+* PARAMETERS -+* none. -+* RETURNS -+* MTK_WCN_BOOL TRUE:ready, FALSE:not ready -+*****************************************************************************/ -+extern MTK_WCN_BOOL mtk_wcn_stp_is_ready(void); -+ -+/***************************************************************************** -+* FUNCTION -+* set_bluetooth_rx_interface -+* DESCRIPTION -+* Set bluetooth rx interface -+* PARAMETERS -+* rx interface type -+* RETURNS -+* void -+*****************************************************************************/ -+extern void mtk_wcn_stp_set_bluez(MTK_WCN_BOOL flags); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_register_if_tx -+* DESCRIPTION -+* regiter Tx event callback function -+* PARAMETERS -+* stp_if: SDIO or UART, fnnc: Call back function -+* RETURNS -+* INT32: 0:successful , -1: fail -+*****************************************************************************/ -+extern INT32 mtk_wcn_stp_register_if_tx(ENUM_STP_TX_IF_TYPE stp_if, MTK_WCN_STP_IF_TX func); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_register_if_rx -+* DESCRIPTION -+* regiter Rx event callback function -+* PARAMETERS -+* stp_if: SDIO or UART, fnnc: Call back function -+* RETURNS -+* INT32: 0:successful , -1: fail -+*****************************************************************************/ -+extern INT32 mtk_wcn_stp_register_if_rx(MTK_WCN_STP_IF_RX func); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_register_event_cb -+* DESCRIPTION -+* regiter Rx event callback function -+* PARAMETERS -+* func -+* RETURNS -+* INT32: 0:successful , -1: fail -+*****************************************************************************/ -+extern INT32 mtk_wcn_stp_register_event_cb(INT32 type, MTK_WCN_STP_EVENT_CB func); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_register_tx_event_cb -+* DESCRIPTION -+* regiter Tx event callback function -+* PARAMETERS -+* func -+* RETURNS -+* INT32: 0:successful , -1: fail -+*****************************************************************************/ -+extern INT32 mtk_wcn_stp_register_tx_event_cb(INT32 type, MTK_WCN_STP_EVENT_CB func); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_coredump_start_get -+* DESCRIPTION -+* get coredump flag is set or not -+* PARAMETERS -+* VOID -+* RETURNS -+* INT32: 0:coredump flag is not set , 1: coredump flag is set -+*****************************************************************************/ -+extern INT32 mtk_wcn_stp_coredump_start_get(VOID); -+ -+/*wmt exp symbols*/ -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_wmt_func_off -+* DESCRIPTION -+* wmt turn off subsystem -+* PARAMETERS -+* type [IN] subsystem type -+* RETURNS -+* MTK_WCN_BOOL_TRUE: OK; MTK_WCN_BOOL_FALSE:error -+*****************************************************************************/ -+extern MTK_WCN_BOOL mtk_wcn_wmt_func_off(ENUM_WMTDRV_TYPE_T type); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_wmt_func_on -+* DESCRIPTION -+* wmt turn on subsystem -+* PARAMETERS -+* type [IN] subsystem type -+* RETURNS -+* MTK_WCN_BOOL_TRUE: OK; MTK_WCN_BOOL_FALSE:error -+*****************************************************************************/ -+extern MTK_WCN_BOOL mtk_wcn_wmt_func_on(ENUM_WMTDRV_TYPE_T type); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_wmt_therm_ctrl -+* DESCRIPTION -+* query chip temperature by WMT CMD -+* PARAMETERS -+* eType [IN] thermal ctrl type -+* RETURNS -+* >=0: chip temperature; 0xff:error -+*****************************************************************************/ -+extern INT8 mtk_wcn_wmt_therm_ctrl(ENUM_WMTTHERM_TYPE_T eType); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_wmt_hwver_get -+* DESCRIPTION -+* get chip hardware version -+* PARAMETERS -+* VOID -+* RETURNS -+* >=0: chip hw version; 0xff:error -+*****************************************************************************/ -+extern ENUM_WMTHWVER_TYPE_T mtk_wcn_wmt_hwver_get(VOID); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_wmt_ic_info_get -+* DESCRIPTION -+* get chip hardware version or f/w version -+* PARAMETERS -+* type : which kind of information is needed -+* RETURNS -+* f/w version or hw version information -+*****************************************************************************/ -+extern UINT32 mtk_wcn_wmt_ic_info_get(ENUM_WMT_CHIPINFO_TYPE_T type); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_wmt_dsns_ctrl -+* DESCRIPTION -+* fm dsns cmd ctrl -+* PARAMETERS -+* eType [IN] fm dsns ctrl type -+* RETURNS -+* MTK_WCN_BOOL_TRUE: OK; MTK_WCN_BOOL_FALSE:error -+*****************************************************************************/ -+extern MTK_WCN_BOOL mtk_wcn_wmt_dsns_ctrl(ENUM_WMTDSNS_TYPE_T eType); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_wmt_msgcb_reg -+* DESCRIPTION -+* used for subsystem register chip reset callback for received wmt reset msg. -+* PARAMETERS -+* eType [IN] subsystem type -+* pCb [IN] rst callback -+* RETURNS -+* 1: OK; 0:error -+*****************************************************************************/ -+extern INT32 mtk_wcn_wmt_msgcb_reg(ENUM_WMTDRV_TYPE_T eType, PF_WMT_CB pCb); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_wmt_msgcb_unreg -+* DESCRIPTION -+* used for subsystem unregister chip reset callback for received wmt reset msg. -+* PARAMETERS -+* eType [IN] subsystem type -+* RETURNS -+* 1: OK; 0:error -+*****************************************************************************/ -+extern INT32 mtk_wcn_wmt_msgcb_unreg(ENUM_WMTDRV_TYPE_T eType); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_wmt_sdio_op_reg -+* DESCRIPTION -+* used to register callback for set sdio ownership. -+* PARAMETERS -+* own_cb [IN] set owner ship callback -+* RETURNS -+* always return 0; -+*****************************************************************************/ -+extern INT32 mtk_wcn_stp_wmt_sdio_op_reg(PF_WMT_SDIO_PSOP own_cb); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_wmt_sdio_host_awake -+* DESCRIPTION -+* handing host awake when link is stp sdio? -+* PARAMETERS -+* VOID -+* RETURNS -+* always return 0; -+*****************************************************************************/ -+extern INT32 mtk_wcn_stp_wmt_sdio_host_awake(VOID); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_wmt_assert -+* DESCRIPTION -+* host trigger firmware assert -+* PARAMETERS -+* type [IN] subsystem driver type -+* reason [IN] trigger assert reason -+* RETURNS -+* MTK_WCN_BOOL_TRUE: OK; MTK_WCN_BOOL_FALSE:error -+*****************************************************************************/ -+extern MTK_WCN_BOOL mtk_wcn_wmt_assert(ENUM_WMTDRV_TYPE_T type, UINT32 reason); -+ -+/***************************************************************************** -+ * * FUNCTION -+ * * mtk_wcn_wmt_assert_timeout -+ * * DESCRIPTION -+ * * host trigger firmware assert -+ * * PARAMETERS -+ * * type [IN] subsystem driver type -+ * * reason [IN] trigger assert reason -+ * * timeout [IN] trigger assert timeout data -+ * * RETURNS -+ * * MTK_WCN_BOOL_TRUE: OK; MTK_WCN_BOOL_FALSE:error -+ * *****************************************************************************/ -+extern MTK_WCN_BOOL mtk_wcn_wmt_assert_timeout(ENUM_WMTDRV_TYPE_T type, -+ UINT32 reason, INT32 timeout); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_wmt_psm_ctrl -+* DESCRIPTION -+* disable/enable psm -+* PARAMETERS -+* flag [IN] disable:0, enable:1 -+* RETURNS -+* always return 0; -+*****************************************************************************/ -+extern INT32 mtk_wcn_wmt_psm_ctrl(MTK_WCN_BOOL flag); -+ -+#endif -+ -+#endif -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/Makefile b/drivers/misc/mediatek/connectivity/common/conn_soc/Makefile -new file mode 100644 -index 000000000000..286bfd4bfed3 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/Makefile -@@ -0,0 +1,65 @@ -+subdir-ccflags-y += \ -+ -I$(src)/linux/include \ -+ -I$(src)/linux/pri/include \ -+ -I$(src)/core/include \ -+ -I$(src)/include \ -+ -I$(src)/../common_detect \ -+ -I$(srctree)/drivers/misc/mediatek/btif/common/inc -+ -+subdir-ccflags-y += -I$(srctree)/drivers/misc/mediatek/eccci/ -+subdir-ccflags-y += -I$(srctree)/drivers/misc/mediatek/eccci/$(MTK_PLATFORM) -+subdir-ccflags-y += -I$(srctree)/drivers/misc/mediatek/eemcs/ -+subdir-ccflags-y += -I$(srctree)/drivers/misc/mediatek/conn_md/include -+ -+EXT_FLAG=_soc -+COMMON_SRC_PATH := $(src) -+COMMON_OBJ_PATH := $(src) -+ -+ifeq ($(CONFIG_ARCH_MT6580), y) -+subdir-ccflags-y += -D CFG_WMT_READ_EFUSE_VCN33 -+endif -+ -+ifeq ($(CONFIG_MTK_COMBO), m) -+# WMT DRIVER -+obj-$(CONFIG_MTK_COMBO) += mtk_stp_wmt$(EXT_FLAG).o -+# WMT DRIVER-core part -+mtk_stp_wmt$(EXT_FLAG)-objs := core/wmt_core.o core/wmt_ctrl.o core/wmt_func.o core/wmt_ic_soc.o core/wmt_lib.o core/wmt_conf.o -+ -+ -+# WMT DRIVER-linux private part -+mtk_stp_wmt$(EXT_FLAG)-objs += linux/pri/wmt_dev.o linux/pri/wmt_exp.o -+mtk_stp_wmt$(EXT_FLAG)-objs += linux/pri/stp_btif.o -+ -+ -+# WMT DRIVER-OSAL -+mtk_stp_wmt$(EXT_FLAG)-objs += linux/pub/osal.o linux/pub/bgw_desense.o -+# WMT DRIVER-platform implementation -+# ccflags-y += -D WMT_PLAT_ALPS -+# mtk_stp_wmt$(EXT_FLAG)-objs += platform/alps/wmt_plat_alps.o -+ -+# mtk_stp_wmt$(EXT_FLAG)-objs += platform/alps/mtk_wcn_consys_hw.o -+ -+ -+mtk_stp_wmt$(EXT_FLAG)-objs += linux/pri/stp_exp.o core/stp_core.o core/psm_core.o core/btm_core.o linux/pri/stp_dbg.o -+ -+# WMT stub part (built-in kernel image) -+# obj-y += platform/alps/mtk_wcn_consys_stub_alps.o -+ -+ -+ -+obj-$(CONFIG_MTK_COMBO_BT) += mtk_stp_bt$(EXT_FLAG).o -+mtk_stp_bt$(EXT_FLAG)-objs := linux/pub/stp_chrdev_bt.o -+ -+ -+obj-$(CONFIG_MTK_COMBO_WIFI) += mtk_wmt_wifi$(EXT_FLAG).o -+mtk_wmt_wifi$(EXT_FLAG)-objs := linux/pub/wmt_chrdev_wifi.o -+ -+endif -+ -+ifeq ($(CONFIG_MTK_COMBO), y) -+# subdir-ccflags-y += -D WMT_PLAT_ALPS -+obj-y += core/ -+obj-y += linux/ -+#obj-y += $(subst ",,$(CONFIG_MTK_PLATFORM))/ -+obj-y += mt7623/ -+endif -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/core/Makefile b/drivers/misc/mediatek/connectivity/common/conn_soc/core/Makefile -new file mode 100644 -index 000000000000..9df71b9e163e ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/core/Makefile -@@ -0,0 +1,22 @@ -+ifeq ($(CONFIG_MTK_COMBO), y) -+ -+ccflags-y += \ -+ -I$(src)/../linux/include \ -+ -I$(src)/../linux/pri/include \ -+ -I$(src)/../core/include \ -+ -I$(src)/../include \ -+ -I$(src)/../../common_detect \ -+ -I$(srctree)/drivers/misc/mediatek/btif/common/inc \ -+ -+obj-y += wmt_core.o \ -+ wmt_ctrl.o \ -+ wmt_func.o \ -+ wmt_ic_soc.o \ -+ wmt_lib.o \ -+ wmt_conf.o \ -+ btm_core.o \ -+ dbg_core.o \ -+ psm_core.o \ -+ stp_core.o -+ -+endif -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/core/btm_core.c b/drivers/misc/mediatek/connectivity/common/conn_soc/core/btm_core.c -new file mode 100644 -index 000000000000..4946b682d826 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/core/btm_core.c -@@ -0,0 +1,1376 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -+#include -+ -+#include "osal_typedef.h" -+#include "osal.h" -+#include "stp_dbg.h" -+#include "stp_core.h" -+#include "btm_core.h" -+#include "wmt_plat.h" -+ -+#define PFX_BTM "[STP-BTM] " -+#define STP_BTM_LOG_LOUD 4 -+#define STP_BTM_LOG_DBG 3 -+#define STP_BTM_LOG_INFO 2 -+#define STP_BTM_LOG_WARN 1 -+#define STP_BTM_LOG_ERR 0 -+ -+INT32 gBtmDbgLevel = STP_BTM_LOG_INFO; -+ -+#define STP_BTM_LOUD_FUNC(fmt, arg...) \ -+do { \ -+ if (gBtmDbgLevel >= STP_BTM_LOG_LOUD) \ -+ pr_debug(PFX_BTM "%s: " fmt, __func__ , ##arg); \ -+} while (0) -+#define STP_BTM_DBG_FUNC(fmt, arg...) \ -+do { \ -+ if (gBtmDbgLevel >= STP_BTM_LOG_DBG) \ -+ pr_debug(PFX_BTM "%s: " fmt, __func__ , ##arg); \ -+} while (0) -+#define STP_BTM_INFO_FUNC(fmt, arg...) \ -+do { \ -+ if (gBtmDbgLevel >= STP_BTM_LOG_INFO) \ -+ pr_debug(PFX_BTM "[I]%s: " fmt, __func__ , ##arg); \ -+} while (0) -+#define STP_BTM_WARN_FUNC(fmt, arg...) \ -+do { \ -+ if (gBtmDbgLevel >= STP_BTM_LOG_WARN) \ -+ pr_warn(PFX_BTM "[W]%s: " fmt, __func__ , ##arg); \ -+} while (0) -+#define STP_BTM_ERR_FUNC(fmt, arg...) \ -+do { \ -+ if (gBtmDbgLevel >= STP_BTM_LOG_ERR) \ -+ pr_err(PFX_BTM "[E]%s(%d):ERROR! " fmt, __func__ , __LINE__, ##arg); \ -+} while (0) -+#define STP_BTM_TRC_FUNC(f) \ -+do { \ -+ if (gBtmDbgLevel >= STP_BTM_LOG_DBG) \ -+ pr_debug(PFX_BTM "<%s> <%d>\n", __func__, __LINE__); \ -+} while (0) -+ -+#define ASSERT(expr) -+ -+MTKSTP_BTM_T stp_btm_i; -+MTKSTP_BTM_T *stp_btm = &stp_btm_i; -+ -+const char *g_btm_op_name[] = { -+ "STP_OPID_BTM_RETRY", -+ "STP_OPID_BTM_RST", -+ "STP_OPID_BTM_DBG_DUMP", -+ "STP_OPID_BTM_DUMP_TIMEOUT", -+ "STP_OPID_BTM_POLL_CPUPCR", -+ "STP_OPID_BTM_PAGED_DUMP", -+ "STP_OPID_BTM_FULL_DUMP", -+ "STP_OPID_BTM_PAGED_TRACE", -+ "STP_OPID_BTM_FORCE_FW_ASSERT", -+#if CFG_WMT_LTE_COEX_HANDLING -+ "STP_OPID_BTM_WMT_LTE_COEX", -+#endif -+ "STP_OPID_BTM_EXIT" -+}; -+ -+#if 0 -+static char *_stp_pkt_type(int type) -+{ -+ -+ static char s[10]; -+ -+ switch (type) { -+ case WMT_TASK_INDX: -+ osal_memcpy(s, "WMT", strlen("WMT") + 1); -+ break; -+ case BT_TASK_INDX: -+ osal_memcpy(s, "BT", strlen("BT") + 1); -+ break; -+ case GPS_TASK_INDX: -+ osal_memcpy(s, "GPS", strlen("GPS") + 1); -+ break; -+ case FM_TASK_INDX: -+ osal_memcpy(s, "FM", strlen("FM") + 1); -+ break; -+ default: -+ osal_memcpy(s, "UNKNOWN", strlen("UNKNOWN") + 1); -+ break; -+ } -+ -+ return s; -+} -+#endif -+ -+static INT32 _stp_btm_put_dump_to_nl(void) -+{ -+#define NUM_FETCH_ENTRY 8 -+ -+ static UINT8 buf[2048]; -+ static UINT8 tmp[2048]; -+ -+ UINT32 buf_len; -+ STP_PACKET_T *pkt; -+ STP_DBG_HDR_T *hdr; -+ INT32 len; -+ INT32 remain = 0, index = 0; -+ INT32 retry = 0, rc = 0, nl_retry = 0; -+ -+ STP_BTM_INFO_FUNC("Enter..\n"); -+ -+ index = 0; -+ tmp[index++] = '['; -+ tmp[index++] = 'M'; -+ tmp[index++] = ']'; -+ -+ do { -+ index = 3; -+ remain = stp_dbg_dmp_out_ex(&buf[0], &buf_len); -+ if (buf_len > 0) { -+ pkt = (STP_PACKET_T *) buf; -+ hdr = &pkt->hdr; -+ len = pkt->hdr.len; -+ osal_memcpy(&tmp[index], &len, 2); -+ index += 2; -+ if (hdr->dbg_type == STP_DBG_FW_DMP) { -+ osal_memcpy(&tmp[index], pkt->raw, len); -+ -+ if (len <= 1500) { -+ /* pr_warn("\n%s\n+++\n", tmp); */ -+ /* pr_warn("send coredump len:%d\n", len); */ -+ /* pr_warn("send coredump:%s\n", tmp); */ -+ rc = stp_dbg_nl_send((PINT8)&tmp, 2, len+5); -+ -+ while (rc) { -+ nl_retry++; -+ if (nl_retry > 1000) -+ break; -+ STP_BTM_WARN_FUNC -+ ("**dump send fails, and retry again.**\n"); -+ osal_sleep_ms(3); -+ rc = stp_dbg_nl_send((PINT8)&tmp, 2, len+5); -+ if (!rc) -+ STP_BTM_WARN_FUNC("****retry again ok!**\n"); -+ } -+ /* schedule(); */ -+ } else { -+ STP_BTM_INFO_FUNC("dump entry length is over long\n"); -+ BUG_ON(0); -+ } -+ retry = 0; -+ } -+ } else { -+ retry++; -+ osal_sleep_ms(100); -+ } -+ } while ((remain > 0) || (retry < 2)); -+ -+ STP_BTM_INFO_FUNC("Exit..\n"); -+ return 0; -+} -+ -+#define SUB_PKT_SIZE 1024 -+#define SUB_PKT_HEADER 5 /*'[M]',3Bytes; len,2Bytes*/ -+ -+INT32 _stp_btm_put_emi_dump_to_nl(PUINT8 data_buf, INT32 dump_len) -+{ -+ static UINT8 tmp[SUB_PKT_SIZE + SUB_PKT_HEADER]; -+ -+ INT32 remain = dump_len, index = 0; -+ INT32 rc = 0, nl_retry = 0; -+ INT32 len; -+ INT32 offset = 0; -+ -+ STP_BTM_INFO_FUNC("Enter..\n"); -+ -+ if (dump_len > 0) { -+ index = 0; -+ tmp[index++] = '['; -+ tmp[index++] = 'M'; -+ tmp[index++] = ']'; -+ -+ do { -+ index = 3; -+ if (remain >= SUB_PKT_SIZE) -+ len = SUB_PKT_SIZE; -+ else -+ len = remain; -+ remain -= len; -+ -+ osal_memcpy(&tmp[index], &len, 2); -+ index += 2; -+ osal_memcpy(&tmp[index], data_buf + offset, len); -+ offset += len; -+ STP_BTM_DBG_FUNC -+ ("send %d remain %d\n", len, remain); -+ -+ rc = stp_dbg_nl_send((PINT8)&tmp, 2, len + SUB_PKT_HEADER); -+ while (rc) { -+ nl_retry++; -+ if (nl_retry > 1000) -+ break; -+ STP_BTM_WARN_FUNC -+ ("**dump send fails, and retry again.**\n"); -+ osal_sleep_ms(3); -+ rc = stp_dbg_nl_send((PINT8)&tmp, 2, len + SUB_PKT_HEADER); -+ if (!rc) { -+ STP_BTM_WARN_FUNC -+ ("****retry again ok!**\n"); -+ } -+ } -+ /* schedule(); */ -+ } while (remain > 0); -+ } else -+ STP_BTM_INFO_FUNC("dump entry length is 0\n"); -+ -+ STP_BTM_INFO_FUNC("Exit..\n"); -+ return 0; -+} -+ -+static INT32 _stp_btm_put_dump_to_aee(void) -+{ -+ static UINT8 buf[2048]; -+ static UINT8 tmp[2048]; -+ -+ UINT32 buf_len; -+ STP_PACKET_T *pkt; -+ STP_DBG_HDR_T *hdr; -+ INT32 remain = 0; -+ INT32 retry = 0; -+ INT32 ret = 0; -+ -+ STP_BTM_INFO_FUNC("Enter..\n"); -+ -+ do { -+ remain = stp_dbg_dmp_out_ex(&buf[0], &buf_len); -+ if (buf_len > 0) { -+ pkt = (STP_PACKET_T *) buf; -+ hdr = &pkt->hdr; -+ if (hdr->dbg_type == STP_DBG_FW_DMP) { -+ memcpy(&tmp[0], pkt->raw, pkt->hdr.len); -+ -+ if (pkt->hdr.len <= 1500) { -+ tmp[pkt->hdr.len] = '\n'; -+ tmp[pkt->hdr.len + 1] = '\0'; -+ -+ ret = stp_dbg_aee_send(tmp, pkt->hdr.len, 0); -+ } else { -+ STP_BTM_INFO_FUNC("dump entry length is over long\n"); -+ BUG_ON(0); -+ } -+ retry = 0; -+ } -+ } else { -+ retry++; -+ msleep(100); -+ } -+ } while ((remain > 0) || (retry < 2)); -+ -+ STP_BTM_INFO_FUNC("Exit..\n"); -+ return ret; -+} -+ -+#if 0 -+INT32 _stp_trigger_firmware_assert_via_emi(VOID) -+{ -+ PUINT8 p_virtual_addr = NULL; -+ INT32 status = -1; -+ INT32 i = 0, j = 0; -+ -+ do { -+ STP_BTM_INFO_FUNC("[Force Assert] stp_trigger_firmware_assert_via_emi -->\n"); -+ p_virtual_addr = wmt_plat_get_emi_virt_add(EXP_APMEM_CTRL_HOST_OUTBAND_ASSERT_W1); -+ if (!p_virtual_addr) { -+ STP_BTM_ERR_FUNC("get virtual address fail\n"); -+ return -1; -+ } -+ -+ CONSYS_REG_WRITE(p_virtual_addr, EXP_APMEM_HOST_OUTBAND_ASSERT_MAGIC_W1); -+ STP_BTM_INFO_FUNC("[Force Assert] stp_trigger_firmware_assert_via_emi <--\n"); -+#if 1 -+ /* wait for firmware assert */ -+ osal_sleep_ms(50); -+ /* if firmware is not assert self, host driver helps it. */ -+ do { -+ if (0 != mtk_wcn_stp_coredump_start_get()) { -+ status = 0; -+ break; -+ } -+ -+ mtk_wcn_stp_wakeup_consys(); -+ STP_BTM_INFO_FUNC("[Force Assert] wakeup consys (%d)\n", i); -+ stp_dbg_poll_cpupcr(5, 1, 1); -+ osal_sleep_ms(5); -+ -+ i++; -+ if (i > 20) { -+ i = 0; -+ break; -+ } -+ } while (1); -+#endif -+ -+ if (0 != mtk_wcn_stp_coredump_start_get()) { -+ status = 0; -+ break; -+ } -+ -+ j++; -+ if (j > 8) { -+ j = 0; -+ break; -+ } -+ } while (1); -+ -+ return status; -+} -+#else -+INT32 _stp_trigger_firmware_assert_via_emi(VOID) -+{ -+ INT32 status = -1; -+ INT32 j = 0; -+ -+ wmt_plat_force_trigger_assert(STP_FORCE_TRG_ASSERT_DEBUG_PIN); -+ -+ do { -+ if (0 != mtk_wcn_stp_coredump_start_get()) { -+ status = 0; -+ break; -+ } -+ -+ stp_dbg_poll_cpupcr(5, 1, 1); -+ stp_dbg_poll_dmaregs(5, 1); -+ j++; -+ STP_BTM_INFO_FUNC("Wait for assert message (%d)\n", j); -+ osal_sleep_ms(20); -+ if (j > 49) { /* wait for 1 second */ -+ stp_dbg_set_fw_info("host trigger fw assert timeout", -+ osal_strlen("host trigger fw assert timeout"), -+ STP_HOST_TRIGGER_ASSERT_TIMEOUT); -+ wcn_core_dump_timeout(); /* trigger collect SYS_FTRACE */ -+ break; -+ } -+ } while (1); -+ -+ return status; -+} -+#endif -+ -+#define COMBO_DUMP2AEE -+#if 1 -+#define STP_DBG_PAGED_DUMP_BUFFER_SIZE (32*1024*sizeof(char)) -+UINT8 g_paged_dump_buffer[STP_DBG_PAGED_DUMP_BUFFER_SIZE] = { 0 }; -+ -+#define STP_DBG_PAGED_TRACE_SIZE (2048*sizeof(char)) -+UINT8 g_paged_trace_buffer[STP_DBG_PAGED_TRACE_SIZE] = { 0 }; -+ -+UINT32 g_paged_dump_len = 0; -+UINT32 g_paged_trace_len = 0; -+VOID _stp_dump_emi_dump_buffer(UINT8 *buffer, UINT32 len) -+{ -+ UINT32 i = 0; -+ -+ if (len > 16) -+ len = 16; -+ for (i = 0; i < len; i++) { -+ if (i % 16 == 0 && i != 0) -+ pr_cont("\n "); -+ -+ if (buffer[i] == ']' || buffer[i] == '[' || buffer[i] == ',') -+ pr_cont("%c", buffer[i]); -+ else -+ pr_cont("0x%02x ", buffer[i]); -+ } -+} -+#endif -+static INT32 _stp_btm_handler(MTKSTP_BTM_T *stp_btm, P_STP_BTM_OP pStpOp) -+{ -+ INT32 ret = -1; -+ INT32 dump_sink = 1; /* core dump target, 0: aee; 1: netlink */ -+ INT32 Ret = 0; -+ static UINT32 counter; -+ UINT32 full_dump_left = STP_FULL_DUMP_TIME; -+ UINT32 page_counter = 0; -+ UINT32 packet_num = STP_PAGED_DUMP_TIME_LIMIT/100; -+ UINT32 dump_num = 0; -+ ENUM_STP_FW_ISSUE_TYPE issue_type; -+ P_CONSYS_EMI_ADDR_INFO p_ecsi; -+ -+ p_ecsi = wmt_plat_get_emi_phy_add(); -+ osal_assert(p_ecsi); -+ if (NULL == pStpOp) -+ return -1; -+ -+ switch (pStpOp->opId) { -+ case STP_OPID_BTM_EXIT: -+ /* TODO: clean all up? */ -+ ret = 0; -+ break; -+ -+ /*tx timeout retry */ -+ case STP_OPID_BTM_RETRY: -+ stp_do_tx_timeout(); -+ ret = 0; -+ -+ break; -+ -+ /*whole chip reset */ -+ case STP_OPID_BTM_RST: -+ STP_BTM_INFO_FUNC("whole chip reset start!\n"); -+ STP_BTM_INFO_FUNC("....+\n"); -+ if (stp_btm->wmt_notify) { -+ stp_btm->wmt_notify(BTM_RST_OP); -+ ret = 0; -+ } else { -+ STP_BTM_ERR_FUNC("stp_btm->wmt_notify is NULL."); -+ ret = -1; -+ } -+ -+ STP_BTM_INFO_FUNC("whole chip reset end!\n"); -+ -+ break; -+ -+ case STP_OPID_BTM_DBG_DUMP: -+ /*Notify the wmt to get dump data */ -+ STP_BTM_DBG_FUNC("wmt dmp notification\n"); -+ dump_sink = ((stp_btm->wmt_notify(BTM_GET_AEE_SUPPORT_FLAG) == MTK_WCN_BOOL_TRUE) ? 0 : 1); -+ -+ if (dump_sink == 0) -+ _stp_btm_put_dump_to_aee(); -+ else if (dump_sink == 1) -+ _stp_btm_put_dump_to_nl(); -+ else -+ STP_BTM_ERR_FUNC("unknown sink %d\n", dump_sink); -+ -+ break; -+ -+ case STP_OPID_BTM_DUMP_TIMEOUT: -+ /* Flush dump data, and reset compressor */ -+ STP_BTM_INFO_FUNC("Flush dump data\n"); -+ wcn_core_dump_flush(0, MTK_WCN_BOOL_TRUE); -+ break; -+ -+ case STP_OPID_BTM_POLL_CPUPCR: -+ do { -+ UINT32 times; -+ UINT32 sleep; -+ -+ times = pStpOp->au4OpData[0]; -+ sleep = pStpOp->au4OpData[1]; -+ -+ ret = stp_dbg_poll_cpupcr(times, sleep, 0); -+ ret += stp_dbg_poll_dmaregs(times, sleep); -+ } while (0); -+ break; -+ -+ case STP_OPID_BTM_PAGED_DUMP: -+ g_paged_dump_len = 0; -+ issue_type = STP_FW_ASSERT_ISSUE; -+ /*packet number depend on dump_num get from register:0xf0080044 ,support jade*/ -+ wcn_core_dump_deinit_gcoredump(); -+ dump_num = wmt_plat_get_dump_info(p_ecsi->p_ecso->emi_apmem_ctrl_chip_page_dump_num); -+ if (dump_num != 0) { -+ packet_num = dump_num; -+ STP_BTM_WARN_FUNC("get consys dump num packet_num(%d)\n", packet_num); -+ } else { -+ STP_BTM_ERR_FUNC("can not get consys dump num and default num is 35\n"); -+ } -+ Ret = wcn_core_dump_init_gcoredump(packet_num, STP_CORE_DUMP_TIMEOUT); -+ if (Ret) { -+ STP_BTM_ERR_FUNC("core dump init fail\n"); -+ break; -+ } -+ wmt_plat_set_host_dump_state(STP_HOST_DUMP_NOT_START); -+ page_counter = 0; -+ do { -+ UINT32 loop_cnt1 = 0; -+ UINT32 loop_cnt2 = 0; -+ ENUM_HOST_DUMP_STATE host_state; -+ ENUM_CHIP_DUMP_STATE chip_state; -+ UINT32 dump_phy_addr = 0; -+ UINT8 *dump_vir_addr = NULL; -+ UINT32 dump_len = 0; -+ UINT32 isEnd = 0; -+ -+ host_state = (ENUM_HOST_DUMP_STATE)wmt_plat_get_dump_info( -+ p_ecsi->p_ecso->emi_apmem_ctrl_host_sync_state); -+ if (STP_HOST_DUMP_NOT_START == host_state) { -+ counter++; -+ STP_BTM_INFO_FUNC("counter(%d)\n", counter); -+ osal_sleep_ms(100); -+ } else { -+ counter = 0; -+ } -+ while (1) { -+ chip_state = (ENUM_CHIP_DUMP_STATE)wmt_plat_get_dump_info( -+ p_ecsi->p_ecso->emi_apmem_ctrl_chip_sync_state); -+ if (STP_CHIP_DUMP_PUT_DONE == chip_state) { -+ STP_BTM_INFO_FUNC("chip put done\n"); -+ break; -+ } -+ STP_BTM_INFO_FUNC("waiting chip put done\n"); -+ STP_BTM_INFO_FUNC("chip_state: %d\n", chip_state); -+ loop_cnt1++; -+ osal_sleep_ms(5); -+ -+ if (loop_cnt1 > 10) -+ goto paged_dump_end; -+ -+ } -+ -+ wmt_plat_set_host_dump_state(STP_HOST_DUMP_GET); -+ -+ dump_phy_addr = wmt_plat_get_dump_info( -+ p_ecsi->p_ecso->emi_apmem_ctrl_chip_sync_addr); -+ -+ if (!dump_phy_addr) { -+ STP_BTM_ERR_FUNC("get paged dump phy address fail\n"); -+ ret = -1; -+ break; -+ } -+ -+ dump_vir_addr = wmt_plat_get_emi_virt_add(dump_phy_addr - p_ecsi->emi_phy_addr); -+ if (!dump_vir_addr) { -+ STP_BTM_ERR_FUNC("get paged dump phy address fail\n"); -+ ret = -2; -+ break; -+ } -+ dump_len = wmt_plat_get_dump_info( -+ p_ecsi->p_ecso->emi_apmem_ctrl_chip_sync_len); -+ STP_BTM_INFO_FUNC("dump_phy_ddr(%08x),dump_vir_add(0x%p),dump_len(%d)\n", -+ dump_phy_addr, dump_vir_addr, dump_len); -+ -+ /*move dump info according to dump_addr & dump_len */ -+#if 1 -+ osal_memcpy(&g_paged_dump_buffer[0], dump_vir_addr, dump_len); -+ _stp_dump_emi_dump_buffer(&g_paged_dump_buffer[0], dump_len); -+ -+ if (0 == page_counter) { /* do fw assert infor paser in first paged dump */ -+ if (1 == stp_dbg_get_host_trigger_assert()) -+ issue_type = STP_HOST_TRIGGER_FW_ASSERT; -+ -+ ret = stp_dbg_set_fw_info(&g_paged_dump_buffer[0], 512, issue_type); -+ if (ret) { -+ STP_BTM_ERR_FUNC("set fw issue infor fail(%d),maybe fw warm reset...\n", ret); -+ stp_dbg_set_fw_info("Fw Warm reset", osal_strlen("Fw Warm reset"), -+ STP_FW_WARM_RST_ISSUE); -+ } -+ } -+ -+ if (dump_len <= 32 * 1024) { -+ pr_err("g_coredump_mode: %d!\n", g_coredump_mode); -+ if (1 == g_coredump_mode) -+ ret = stp_dbg_aee_send(&g_paged_dump_buffer[0], dump_len, 0); -+ else if (2 == g_coredump_mode) -+ ret = _stp_btm_put_emi_dump_to_nl(&g_paged_dump_buffer[0], dump_len); -+ else{ -+ STP_BTM_INFO_FUNC("coredump is disabled!\n"); -+ return 0; -+ } -+ if (ret == 0) -+ STP_BTM_INFO_FUNC("aee send ok!\n"); -+ else if (ret == 1) -+ STP_BTM_INFO_FUNC("aee send fisish!\n"); -+ else -+ STP_BTM_ERR_FUNC("aee send error!\n"); -+ } else -+ STP_BTM_ERR_FUNC("dump len is over than 32K(%d)\n", dump_len); -+ -+ g_paged_dump_len += dump_len; -+ STP_BTM_INFO_FUNC("dump len update(%d)\n", g_paged_dump_len); -+#endif -+ wmt_plat_update_host_sync_num(); -+ wmt_plat_set_host_dump_state(STP_HOST_DUMP_GET_DONE); -+ -+ STP_BTM_INFO_FUNC("host sync num(%d),chip sync num(%d)\n", -+ wmt_plat_get_dump_info( -+ p_ecsi->p_ecso->emi_apmem_ctrl_host_sync_num), -+ wmt_plat_get_dump_info( -+ p_ecsi->p_ecso->emi_apmem_ctrl_chip_sync_num)); -+ -+ page_counter++; -+ STP_BTM_INFO_FUNC("\n\n++ paged dump counter(%d) ++\n\n\n", page_counter); -+ -+ while (1) { -+ chip_state = (ENUM_CHIP_DUMP_STATE)wmt_plat_get_dump_info( -+ p_ecsi->p_ecso->emi_apmem_ctrl_chip_sync_state); -+ if (STP_CHIP_DUMP_END == chip_state) { -+ STP_BTM_INFO_FUNC("chip put end\n"); -+ wmt_plat_set_host_dump_state(STP_HOST_DUMP_END); -+ break; -+ } -+ STP_BTM_INFO_FUNC("waiting chip put end\n"); -+ -+ loop_cnt2++; -+ osal_sleep_ms(10); -+ -+ if (loop_cnt2 > 10) -+ goto paged_dump_end; -+ } -+ -+paged_dump_end: -+ wmt_plat_set_host_dump_state(STP_HOST_DUMP_NOT_START); -+ -+ if (counter > packet_num) { -+ isEnd = wmt_plat_get_dump_info( -+ p_ecsi->p_ecso->emi_apmem_ctrl_chip_paded_dump_end); -+ -+ if (isEnd) { -+ STP_BTM_INFO_FUNC("paged dump end\n"); -+ -+ STP_BTM_INFO_FUNC("\n\n paged dump print ++\n\n"); -+ _stp_dump_emi_dump_buffer(&g_paged_dump_buffer[0], g_paged_dump_len); -+ STP_BTM_INFO_FUNC("\n\n paged dump print --\n\n"); -+ STP_BTM_INFO_FUNC("\n\n paged dump size = %d, paged dump page number = %d\n\n", -+ g_paged_dump_len, page_counter); -+ counter = 0; -+ ret = 0; -+ } else { -+ STP_BTM_ERR_FUNC("paged dump fail\n"); -+ wmt_plat_set_host_dump_state(STP_HOST_DUMP_NOT_START); -+ stp_dbg_poll_cpupcr(5, 5, 0); -+ stp_dbg_poll_dmaregs(5, 1); -+ counter = 0; -+ ret = -1; -+ } -+ break; -+ } -+ -+ } while (1); -+ -+ break; -+ -+ case STP_OPID_BTM_FULL_DUMP: -+ -+ wmt_plat_set_host_dump_state(STP_HOST_DUMP_NOT_START); -+ do { -+ UINT32 loop_cnt1 = 0; -+ UINT32 loop_cnt2 = 0; -+ ENUM_CHIP_DUMP_STATE chip_state; -+ UINT32 dump_phy_addr = 0; -+ UINT8 *dump_vir_addr = NULL; -+ UINT32 dump_len = 0; -+ UINT32 isFail = 0; -+ -+ while (1) { -+ chip_state = (ENUM_CHIP_DUMP_STATE)wmt_plat_get_dump_info( -+ p_ecsi->p_ecso->emi_apmem_ctrl_chip_sync_state); -+ if (STP_CHIP_DUMP_PUT_DONE == chip_state) -+ break; -+ -+ loop_cnt1++; -+ osal_sleep_ms(10); -+ -+ if (loop_cnt1 > 10) { -+ isFail = 1; -+ goto full_dump_end; -+ } -+ } -+ -+ wmt_plat_set_host_dump_state(STP_HOST_DUMP_GET); -+ -+ dump_phy_addr = wmt_plat_get_dump_info(p_ecsi->p_ecso->emi_apmem_ctrl_chip_sync_addr); -+ if (!dump_phy_addr) { -+ STP_BTM_ERR_FUNC("get phy dump address fail\n"); -+ ret = -1; -+ break; -+ } -+ -+ dump_vir_addr = wmt_plat_get_emi_virt_add(dump_phy_addr - p_ecsi->emi_phy_addr); -+ if (!dump_vir_addr) { -+ STP_BTM_ERR_FUNC("get vir dump address fail\n"); -+ ret = -2; -+ break; -+ } -+ dump_len = wmt_plat_get_dump_info(p_ecsi->p_ecso->emi_apmem_ctrl_chip_sync_len); -+ /*move dump info according to dump_addr & dump_len */ -+ wmt_plat_update_host_sync_num(); -+ wmt_plat_set_host_dump_state(STP_HOST_DUMP_GET_DONE); -+ -+ STP_BTM_INFO_FUNC("host sync num(%d),chip sync num(%d)\n", -+ wmt_plat_get_dump_info( -+ p_ecsi->p_ecso->emi_apmem_ctrl_host_sync_num), -+ wmt_plat_get_dump_info( -+ p_ecsi->p_ecso->emi_apmem_ctrl_chip_sync_num)); -+ -+ while (1) { -+ chip_state = (ENUM_CHIP_DUMP_STATE)wmt_plat_get_dump_info( -+ p_ecsi->p_ecso->emi_apmem_ctrl_chip_sync_state); -+ if (STP_CHIP_DUMP_END == chip_state) { -+ wmt_plat_set_host_dump_state(STP_HOST_DUMP_END); -+ break; -+ } -+ loop_cnt2++; -+ osal_sleep_ms(10); -+ -+ if (loop_cnt2 > 10) { -+ isFail = 1; -+ goto full_dump_end; -+ } -+ } -+ wmt_plat_set_host_dump_state(STP_HOST_DUMP_NOT_START); -+full_dump_end: -+ if (isFail) { -+ STP_BTM_ERR_FUNC("full dump fail\n"); -+ wmt_plat_set_host_dump_state(STP_HOST_DUMP_NOT_START); -+ ret = -1; -+ break; -+ } -+ } while (--full_dump_left > 0); -+ if (0 == full_dump_left) { -+ STP_BTM_INFO_FUNC("full dump end\n"); -+ ret = 0; -+ } -+ break; -+ case STP_OPID_BTM_PAGED_TRACE: -+ g_paged_trace_len = 0; -+ do { -+ UINT32 ctrl_val = 0; -+ UINT32 loop_cnt1 = 0; -+ UINT32 buffer_start = 0; -+ UINT32 buffer_idx = 0; -+ UINT8 *dump_vir_addr = NULL; -+ -+ while (loop_cnt1 < 10) { -+ ctrl_val = wmt_plat_get_dump_info(p_ecsi->p_ecso->emi_apmem_ctrl_state); -+ if (0x8 == ctrl_val) -+ break; -+ osal_sleep_ms(10); -+ loop_cnt1++; -+ } -+ -+ if (loop_cnt1 >= 10) { -+ STP_BTM_ERR_FUNC("polling CTRL STATE fail\n"); -+ ret = -1; -+ break; -+ } -+ -+ buffer_start = wmt_plat_get_dump_info( -+ p_ecsi->p_ecso->emi_apmem_ctrl_chip_print_buff_start); -+ buffer_idx = wmt_plat_get_dump_info( -+ p_ecsi->p_ecso->emi_apmem_ctrl_chip_print_buff_idx); -+ /* buffer_len = buffer_idx - buffer_start; */ -+ g_paged_trace_len = buffer_idx; -+ STP_BTM_INFO_FUNC("paged trace buffer addr(%08x),buffer_len(%d)\n", buffer_start, buffer_idx); -+ dump_vir_addr = wmt_plat_get_emi_virt_add(buffer_start - p_ecsi->emi_phy_addr); -+ if (!dump_vir_addr) { -+ STP_BTM_ERR_FUNC("get vir dump address fail\n"); -+ ret = -2; -+ break; -+ } -+ osal_memcpy(&g_paged_trace_buffer[0], dump_vir_addr, -+ buffer_idx < STP_DBG_PAGED_TRACE_SIZE ? buffer_idx : STP_DBG_PAGED_TRACE_SIZE); -+ /*moving paged trace according to buffer_start & buffer_len */ -+ do { -+ int i = 0; -+ int dump_len = 0; -+ -+ dump_len = -+ buffer_idx < STP_DBG_PAGED_TRACE_SIZE ? buffer_idx : STP_DBG_PAGED_TRACE_SIZE; -+ pr_warn("\n\n -- paged trace hex output --\n\n"); -+ for (i = 0; i < dump_len; i++) { -+ if (i % 16 == 0) -+ pr_cont("\n"); -+ -+ pr_cont("%02x ", g_paged_trace_buffer[i]); -+ } -+ pr_warn("\n\n -- paged trace ascii output --\n\n"); -+ for (i = 0; i < dump_len; i++) { -+ if (i % 64 == 0) -+ pr_cont("\n"); -+ pr_cont("%c", g_paged_trace_buffer[i]); -+ } -+ } while (0); -+ /*move parser fw assert infor to paged dump in the one paged dump */ -+ /* ret = stp_dbg_set_fw_info(&g_paged_trace_buffer[0],g_paged_trace_len,issue_type); */ -+ ret = 0; -+ -+ } while (0); -+ mtk_wcn_stp_ctx_restore(); -+ break; -+ -+#if CFG_WMT_LTE_COEX_HANDLING -+ case STP_OPID_BTM_WMT_LTE_COEX: -+ ret = wmt_idc_msg_to_lte_handing(); -+ break; -+#endif -+ default: -+ ret = -1; -+ break; -+ } -+ -+ return ret; -+} -+ -+static P_OSAL_OP _stp_btm_get_op(MTKSTP_BTM_T *stp_btm, P_OSAL_OP_Q pOpQ) -+{ -+ P_OSAL_OP pOp; -+ /* INT32 ret = 0; */ -+ -+ if (!pOpQ) { -+ STP_BTM_WARN_FUNC("!pOpQ\n"); -+ return NULL; -+ } -+ -+ osal_lock_unsleepable_lock(&(stp_btm->wq_spinlock)); -+ /* acquire lock success */ -+ RB_GET(pOpQ, pOp); -+ osal_unlock_unsleepable_lock(&(stp_btm->wq_spinlock)); -+ -+ if (!pOp) -+ STP_BTM_WARN_FUNC("RB_GET fail\n"); -+ -+ return pOp; -+} -+ -+static INT32 _stp_btm_put_op(MTKSTP_BTM_T *stp_btm, P_OSAL_OP_Q pOpQ, P_OSAL_OP pOp) -+{ -+ INT32 ret; -+ -+ if (!pOpQ || !pOp) { -+ STP_BTM_WARN_FUNC("invalid input param: 0x%p, 0x%p\n", pOpQ, pOp); -+ return 0; /* ;MTK_WCN_BOOL_FALSE; */ -+ } -+ -+ ret = 0; -+ -+ osal_lock_unsleepable_lock(&(stp_btm->wq_spinlock)); -+ /* acquire lock success */ -+ if (!RB_FULL(pOpQ)) -+ RB_PUT(pOpQ, pOp); -+ else -+ ret = -1; -+ -+ osal_unlock_unsleepable_lock(&(stp_btm->wq_spinlock)); -+ -+ if (ret) { -+ STP_BTM_WARN_FUNC("RB_FULL(0x%p) %d ,rFreeOpQ = %p, rActiveOpQ = %p\n", -+ pOpQ, -+ RB_COUNT(pOpQ), -+ &stp_btm->rFreeOpQ, -+ &stp_btm->rActiveOpQ); -+ return 0; -+ } -+ /* STP_BTM_WARN_FUNC("RB_COUNT = %d\n",RB_COUNT(pOpQ)); */ -+ return 1; -+ -+} -+ -+P_OSAL_OP _stp_btm_get_free_op(MTKSTP_BTM_T *stp_btm) -+{ -+ P_OSAL_OP pOp; -+ -+ if (stp_btm) { -+ pOp = _stp_btm_get_op(stp_btm, &stp_btm->rFreeOpQ); -+ if (pOp) -+ osal_memset(&pOp->op, 0, sizeof(pOp->op)); -+ -+ return pOp; -+ } else -+ return NULL; -+} -+ -+INT32 _stp_btm_put_act_op(MTKSTP_BTM_T *stp_btm, P_OSAL_OP pOp) -+{ -+ INT32 bRet = 0; -+ INT32 bCleanup = 0; -+ long wait_ret = -1; -+ -+ P_OSAL_SIGNAL pSignal = NULL; -+ -+ if (!stp_btm || !pOp) { -+ STP_BTM_ERR_FUNC("Input NULL pointer\n"); -+ return bRet; -+ } -+ do { -+ pSignal = &pOp->signal; -+ -+ if (pSignal->timeoutValue) { -+ pOp->result = -9; -+ osal_signal_init(&pOp->signal); -+ } -+ -+ /* put to active Q */ -+ bRet = _stp_btm_put_op(stp_btm, &stp_btm->rActiveOpQ, pOp); -+ if (0 == bRet) { -+ STP_BTM_WARN_FUNC("put active queue fail\n"); -+ bCleanup = 1; /* MTK_WCN_BOOL_TRUE; */ -+ break; -+ } -+ -+ /* wake up wmtd */ -+ osal_trigger_event(&stp_btm->STPd_event); -+ -+ if (pSignal->timeoutValue == 0) { -+ bRet = 1; /* MTK_WCN_BOOL_TRUE; */ -+ /* clean it in wmtd */ -+ break; -+ } -+ -+ /* wait result, clean it here */ -+ bCleanup = 1; /* MTK_WCN_BOOL_TRUE; */ -+ -+ /* check result */ -+ wait_ret = osal_wait_for_signal_timeout(&pOp->signal); -+ -+ STP_BTM_DBG_FUNC("wait completion:%ld\n", wait_ret); -+ if (!wait_ret) { -+ STP_BTM_ERR_FUNC("wait completion timeout\n"); -+ /* TODO: how to handle it? retry? */ -+ } else { -+ if (pOp->result) -+ STP_BTM_WARN_FUNC("op(%d) result:%d\n", pOp->op.opId, pOp->result); -+ -+ bRet = (pOp->result) ? 0 : 1; -+ } -+ } while (0); -+ -+ if (bCleanup) { -+ /* put Op back to freeQ */ -+ _stp_btm_put_op(stp_btm, &stp_btm->rFreeOpQ, pOp); -+ } -+ bRet = (pOp->result) ? 0 : 1; -+ return bRet; -+} -+ -+static INT32 _stp_btm_wait_for_msg(void *pvData) -+{ -+ MTKSTP_BTM_T *stp_btm = (MTKSTP_BTM_T *) pvData; -+ -+ return (!RB_EMPTY(&stp_btm->rActiveOpQ)) || osal_thread_should_stop(&stp_btm->BTMd); -+} -+ -+static INT32 _stp_btm_proc(void *pvData) -+{ -+ MTKSTP_BTM_T *stp_btm = (MTKSTP_BTM_T *) pvData; -+ P_OSAL_OP pOp; -+ INT32 id; -+ INT32 result; -+ -+ if (!stp_btm) { -+ STP_BTM_WARN_FUNC("!stp_btm\n"); -+ return -1; -+ } -+ -+ for (;;) { -+ pOp = NULL; -+ -+ osal_wait_for_event(&stp_btm->STPd_event, _stp_btm_wait_for_msg, (void *)stp_btm); -+ -+ if (osal_thread_should_stop(&stp_btm->BTMd)) { -+ STP_BTM_INFO_FUNC("should stop now...\n"); -+ /* TODO: clean up active opQ */ -+ break; -+ } -+ -+ /* get Op from activeQ */ -+ pOp = _stp_btm_get_op(stp_btm, &stp_btm->rActiveOpQ); -+ -+ if (!pOp) { -+ STP_BTM_WARN_FUNC("get_lxop activeQ fail\n"); -+ continue; -+ } -+ -+ id = osal_op_get_id(pOp); -+ -+ STP_BTM_DBG_FUNC("======> lxop_get_opid = %d, %s, remaining count = *%d*\n", -+ id, (id >= osal_array_size(g_btm_op_name)) ? ("???") : (g_btm_op_name[id]), -+ RB_COUNT(&stp_btm->rActiveOpQ)); -+ -+ if (id >= STP_OPID_BTM_NUM) { -+ STP_BTM_WARN_FUNC("abnormal opid id: 0x%x\n", id); -+ result = -1; -+ goto handler_done; -+ } -+ -+ result = _stp_btm_handler(stp_btm, &pOp->op); -+ -+handler_done: -+ -+ if (result) { -+ STP_BTM_WARN_FUNC("opid id(0x%x)(%s) error(%d)\n", id, -+ (id >= osal_array_size(g_btm_op_name)) ? ("???") : (g_btm_op_name[id]), -+ result); -+ } -+ -+ if (osal_op_is_wait_for_signal(pOp)) { -+ osal_op_raise_signal(pOp, result); -+ } else { -+ /* put Op back to freeQ */ -+ _stp_btm_put_op(stp_btm, &stp_btm->rFreeOpQ, pOp); -+ } -+ -+ if (STP_OPID_BTM_EXIT == id) { -+ break; -+ } else if (STP_OPID_BTM_RST == id) { -+ /* prevent multi reset case */ -+ stp_btm_reset_btm_wq(stp_btm); -+ mtk_wcn_stp_coredump_start_ctrl(0); -+ } -+ } -+ -+ STP_BTM_INFO_FUNC("exits\n"); -+ -+ return 0; -+}; -+ -+static inline INT32 _stp_btm_notify_wmt_rst_wq(MTKSTP_BTM_T *stp_btm) -+{ -+ -+ P_OSAL_OP pOp; -+ INT32 bRet; -+ INT32 retval; -+ -+ if (stp_btm == NULL) -+ return STP_BTM_OPERATION_FAIL; -+ -+ pOp = _stp_btm_get_free_op(stp_btm); -+ if (!pOp) { -+ STP_BTM_WARN_FUNC("get_free_lxop fail\n"); -+ return -1; /* break; */ -+ } -+ pOp->op.opId = STP_OPID_BTM_RST; -+ pOp->signal.timeoutValue = 0; -+ bRet = _stp_btm_put_act_op(stp_btm, pOp); -+ STP_BTM_DBG_FUNC("OPID(%d) type(%zd) bRet(%d)\n\n", pOp->op.opId, pOp->op.au4OpData[0], bRet); -+ retval = (0 == bRet) ? STP_BTM_OPERATION_FAIL : STP_BTM_OPERATION_SUCCESS; -+ -+ return retval; -+} -+ -+static inline INT32 _stp_btm_notify_stp_retry_wq(MTKSTP_BTM_T *stp_btm) -+{ -+ -+ P_OSAL_OP pOp; -+ INT32 bRet; -+ INT32 retval; -+ -+ if (stp_btm == NULL) -+ return STP_BTM_OPERATION_FAIL; -+ -+ pOp = _stp_btm_get_free_op(stp_btm); -+ if (!pOp) { -+ STP_BTM_WARN_FUNC("get_free_lxop fail\n"); -+ return -1; /* break; */ -+ } -+ pOp->op.opId = STP_OPID_BTM_RETRY; -+ pOp->signal.timeoutValue = 0; -+ bRet = _stp_btm_put_act_op(stp_btm, pOp); -+ STP_BTM_DBG_FUNC("OPID(%d) type(%zd) bRet(%d)\n\n", pOp->op.opId, pOp->op.au4OpData[0], bRet); -+ retval = (0 == bRet) ? STP_BTM_OPERATION_FAIL : STP_BTM_OPERATION_SUCCESS; -+ -+ return retval; -+} -+ -+static inline INT32 _stp_btm_notify_coredump_timeout_wq(MTKSTP_BTM_T *stp_btm) -+{ -+ -+ P_OSAL_OP pOp; -+ INT32 bRet; -+ INT32 retval; -+ -+ if (!stp_btm) -+ return STP_BTM_OPERATION_FAIL; -+ -+ pOp = _stp_btm_get_free_op(stp_btm); -+ if (!pOp) { -+ STP_BTM_WARN_FUNC("get_free_lxop fail\n"); -+ return -1; /* break; */ -+ } -+ pOp->op.opId = STP_OPID_BTM_DUMP_TIMEOUT; -+ pOp->signal.timeoutValue = 0; -+ bRet = _stp_btm_put_act_op(stp_btm, pOp); -+ STP_BTM_DBG_FUNC("OPID(%d) type(%zd) bRet(%d)\n\n", pOp->op.opId, pOp->op.au4OpData[0], bRet); -+ retval = (0 == bRet) ? STP_BTM_OPERATION_FAIL : STP_BTM_OPERATION_SUCCESS; -+ -+ return retval; -+} -+ -+static inline INT32 _stp_btm_dump_type(MTKSTP_BTM_T *stp_btm, ENUM_STP_BTM_OPID_T opid) -+{ -+ P_OSAL_OP pOp; -+ INT32 bRet; -+ INT32 retval; -+ -+ pOp = _stp_btm_get_free_op(stp_btm); -+ if (!pOp) { -+ STP_BTM_WARN_FUNC("get_free_lxop fail\n"); -+ return -1; /* break; */ -+ } -+ -+ pOp->op.opId = opid; -+ pOp->signal.timeoutValue = 0; -+ bRet = _stp_btm_put_act_op(stp_btm, pOp); -+ STP_BTM_DBG_FUNC("OPID(%d) type(%zd) bRet(%d)\n\n", pOp->op.opId, pOp->op.au4OpData[0], bRet); -+ retval = (0 == bRet) ? STP_BTM_OPERATION_FAIL : STP_BTM_OPERATION_SUCCESS; -+ -+ return retval; -+} -+ -+static inline INT32 _stp_btm_notify_wmt_dmp_wq(MTKSTP_BTM_T *stp_btm) -+{ -+ -+ INT32 retval; -+#if 0 -+ UINT32 dump_type; -+ UINT8 *virtual_addr = NULL; -+#endif -+ if (stp_btm == NULL) -+ return STP_BTM_OPERATION_FAIL; -+ -+#if 1 /* Paged dump */ -+ STP_BTM_INFO_FUNC("paged dump start++\n"); -+ retval = _stp_btm_dump_type(stp_btm, STP_OPID_BTM_PAGED_DUMP); -+ if (retval) -+ STP_BTM_ERR_FUNC("paged dump fail\n"); -+#else -+ virtual_addr = wmt_plat_get_emi_virt_add(EXP_APMEM_CTRL_CHIP_SYNC_ADDR); -+ if (!virtual_addr) { -+ STP_BTM_ERR_FUNC("get dump type virtual addr fail\n"); -+ return -1; -+ } -+ dump_type = CONSYS_REG_READ(virtual_addr); -+ STP_BTM_INFO_FUNC("dump type:%08x\n", dump_type); -+ -+ if ((dump_type & 0xfffff) == (CONSYS_PAGED_DUMP_START_ADDR & 0xfffff)) { -+ STP_BTM_INFO_FUNC("do paged dump\n"); -+ retval = _stp_btm_dump_type(stp_btm, STP_OPID_BTM_PAGED_DUMP); -+ if (retval) { -+ STP_BTM_ERR_FUNC("paged dump fail,do full dump\n"); -+ _stp_btm_dump_type(stp_btm, STP_OPID_BTM_FULL_DUMP); -+ } -+ } else if ((dump_type & 0xfffff) == (CONSYS_FULL_DUMP_START_ADDR & 0xfffff)) { -+ STP_BTM_INFO_FUNC("do full dump\n"); -+ retval = _stp_btm_dump_type(stp_btm, STP_OPID_BTM_FULL_DUMP); -+ } else { -+ STP_BTM_INFO_FUNC("do normal dump\n"); -+ retval = _stp_btm_dump_type(stp_btm, STP_OPID_BTM_DBG_DUMP); -+ } -+#endif -+ -+ return retval; -+} -+ -+static inline INT32 _stp_notify_btm_poll_cpupcr(MTKSTP_BTM_T *stp_btm, UINT32 times, UINT32 sleep) -+{ -+ -+ P_OSAL_OP pOp; -+ INT32 bRet; -+ INT32 retval; -+ -+ if (stp_btm == NULL) -+ return STP_BTM_OPERATION_FAIL; -+ -+ pOp = _stp_btm_get_free_op(stp_btm); -+ if (!pOp) { -+ /* STP_BTM_WARN_FUNC("get_free_lxop fail\n"); */ -+ return -1; /* break; */ -+ } -+ pOp->op.opId = STP_OPID_BTM_POLL_CPUPCR; -+ pOp->signal.timeoutValue = 0; -+ pOp->op.au4OpData[0] = times; -+ pOp->op.au4OpData[1] = sleep; -+ bRet = _stp_btm_put_act_op(stp_btm, pOp); -+ STP_BTM_DBG_FUNC("OPID(%d) type(%zd) bRet(%d)\n\n", pOp->op.opId, pOp->op.au4OpData[0], bRet); -+ retval = (0 == bRet) ? STP_BTM_OPERATION_FAIL : STP_BTM_OPERATION_SUCCESS; -+ -+ return retval; -+} -+ -+static inline INT32 _stp_btm_notify_wmt_trace_wq(MTKSTP_BTM_T *stp_btm) -+{ -+ P_OSAL_OP pOp; -+ INT32 bRet; -+ INT32 retval; -+ -+ if (stp_btm == NULL) -+ return STP_BTM_OPERATION_FAIL; -+ -+ pOp = _stp_btm_get_free_op(stp_btm); -+ if (!pOp) { -+ /* STP_BTM_WARN_FUNC("get_free_lxop fail\n"); */ -+ return -1; /* break; */ -+ } -+ pOp->op.opId = STP_OPID_BTM_PAGED_TRACE; -+ pOp->signal.timeoutValue = 0; -+ bRet = _stp_btm_put_act_op(stp_btm, pOp); -+ STP_BTM_DBG_FUNC("OPID(%d) type(%zd) bRet(%d)\n\n", pOp->op.opId, pOp->op.au4OpData[0], bRet); -+ retval = (0 == bRet) ? STP_BTM_OPERATION_FAIL : STP_BTM_OPERATION_SUCCESS; -+ -+ return retval; -+} -+ -+static inline INT32 _stp_btm_do_fw_assert_via_emi(MTKSTP_BTM_T *stp_btm) -+{ -+ INT32 ret = -1; -+ -+ ret = _stp_trigger_firmware_assert_via_emi(); -+ -+ return ret; -+ -+} -+ -+INT32 stp_btm_notify_wmt_rst_wq(MTKSTP_BTM_T *stp_btm) -+{ -+ return _stp_btm_notify_wmt_rst_wq(stp_btm); -+} -+ -+INT32 stp_btm_notify_stp_retry_wq(MTKSTP_BTM_T *stp_btm) -+{ -+ return _stp_btm_notify_stp_retry_wq(stp_btm); -+} -+ -+INT32 stp_btm_notify_coredump_timeout_wq(MTKSTP_BTM_T *stp_btm) -+{ -+ return _stp_btm_notify_coredump_timeout_wq(stp_btm); -+} -+ -+INT32 stp_btm_notify_wmt_dmp_wq(MTKSTP_BTM_T *stp_btm) -+{ -+ return _stp_btm_notify_wmt_dmp_wq(stp_btm); -+} -+ -+INT32 stp_btm_notify_wmt_trace_wq(MTKSTP_BTM_T *stp_btm) -+{ -+ return _stp_btm_notify_wmt_trace_wq(stp_btm); -+} -+ -+INT32 stp_notify_btm_poll_cpupcr(MTKSTP_BTM_T *stp_btm, UINT32 times, UINT32 sleep) -+{ -+ return _stp_notify_btm_poll_cpupcr(stp_btm, times, sleep); -+} -+ -+INT32 stp_notify_btm_poll_cpupcr_ctrl(UINT32 en) -+{ -+ return stp_dbg_poll_cuppcr_ctrl(en); -+} -+ -+INT32 stp_notify_btm_do_fw_assert_via_emi(MTKSTP_BTM_T *stp_btm) -+{ -+ INT32 ret = -1; -+#if BTIF_RXD_BE_BLOCKED_DETECT -+ if (is_btif_rxd_be_blocked()) -+ ret = wcn_btif_rxd_blocked_collect_ftrace(); /* trigger collect SYS_FTRACE */ -+ else -+#endif -+ ret = _stp_btm_do_fw_assert_via_emi(stp_btm); -+ return ret; -+} -+ -+#if CFG_WMT_LTE_COEX_HANDLING -+ -+static inline INT32 _stp_notify_btm_handle_wmt_lte_coex(MTKSTP_BTM_T *stp_btm) -+{ -+ P_OSAL_OP pOp; -+ INT32 bRet; -+ INT32 retval; -+ -+ if (stp_btm == NULL) -+ return STP_BTM_OPERATION_FAIL; -+ -+ pOp = _stp_btm_get_free_op(stp_btm); -+ if (!pOp) { -+ /* STP_BTM_WARN_FUNC("get_free_lxop fail\n"); */ -+ return -1; /* break; */ -+ } -+ pOp->op.opId = STP_OPID_BTM_WMT_LTE_COEX; -+ pOp->signal.timeoutValue = 0; -+ bRet = _stp_btm_put_act_op(stp_btm, pOp); -+ STP_BTM_DBG_FUNC("OPID(%d) type(%zd) bRet(%d)\n\n", pOp->op.opId, pOp->op.au4OpData[0], bRet); -+ retval = (0 == bRet) ? STP_BTM_OPERATION_FAIL : STP_BTM_OPERATION_SUCCESS; -+ -+ return retval; -+} -+ -+INT32 stp_notify_btm_handle_wmt_lte_coex(MTKSTP_BTM_T *stp_btm) -+{ -+ return _stp_notify_btm_handle_wmt_lte_coex(stp_btm); -+} -+ -+#endif -+MTKSTP_BTM_T *stp_btm_init(void) -+{ -+ INT32 i = 0x0; -+ INT32 ret = -1; -+ -+ osal_unsleepable_lock_init(&stp_btm->wq_spinlock); -+ osal_event_init(&stp_btm->STPd_event); -+ stp_btm->wmt_notify = wmt_lib_btm_cb; -+ -+ RB_INIT(&stp_btm->rFreeOpQ, STP_BTM_OP_BUF_SIZE); -+ RB_INIT(&stp_btm->rActiveOpQ, STP_BTM_OP_BUF_SIZE); -+ -+ /* Put all to free Q */ -+ for (i = 0; i < STP_BTM_OP_BUF_SIZE; i++) { -+ osal_signal_init(&(stp_btm->arQue[i].signal)); -+ _stp_btm_put_op(stp_btm, &stp_btm->rFreeOpQ, &(stp_btm->arQue[i])); -+ } -+ -+ /*Generate PSM thread, to servie STP-CORE for packet retrying and core dump receiving */ -+ stp_btm->BTMd.pThreadData = (VOID *) stp_btm; -+ stp_btm->BTMd.pThreadFunc = (VOID *) _stp_btm_proc; -+ osal_memcpy(stp_btm->BTMd.threadName, BTM_THREAD_NAME, osal_strlen(BTM_THREAD_NAME)); -+ -+ ret = osal_thread_create(&stp_btm->BTMd); -+ if (ret < 0) { -+ STP_BTM_ERR_FUNC("osal_thread_create fail...\n"); -+ goto ERR_EXIT1; -+ } -+ -+ /* Start STPd thread */ -+ ret = osal_thread_run(&stp_btm->BTMd); -+ if (ret < 0) { -+ STP_BTM_ERR_FUNC("osal_thread_run FAILS\n"); -+ goto ERR_EXIT1; -+ } -+ -+ return stp_btm; -+ -+ERR_EXIT1: -+ -+ return NULL; -+ -+} -+ -+INT32 stp_btm_deinit(MTKSTP_BTM_T *stp_btm) -+{ -+ -+ INT32 ret = -1; -+ -+ STP_BTM_INFO_FUNC("btm deinit\n"); -+ -+ if (!stp_btm) -+ return STP_BTM_OPERATION_FAIL; -+ -+ ret = osal_thread_destroy(&stp_btm->BTMd); -+ if (ret < 0) { -+ STP_BTM_ERR_FUNC("osal_thread_destroy FAILS\n"); -+ return STP_BTM_OPERATION_FAIL; -+ } -+ -+ return STP_BTM_OPERATION_SUCCESS; -+} -+ -+INT32 stp_btm_reset_btm_wq(MTKSTP_BTM_T *stp_btm) -+{ -+ UINT32 i = 0; -+ -+ osal_lock_unsleepable_lock(&(stp_btm->wq_spinlock)); -+ RB_INIT(&stp_btm->rFreeOpQ, STP_BTM_OP_BUF_SIZE); -+ RB_INIT(&stp_btm->rActiveOpQ, STP_BTM_OP_BUF_SIZE); -+ osal_unlock_unsleepable_lock(&(stp_btm->wq_spinlock)); -+ /* Put all to free Q */ -+ for (i = 0; i < STP_BTM_OP_BUF_SIZE; i++) { -+ osal_signal_init(&(stp_btm->arQue[i].signal)); -+ _stp_btm_put_op(stp_btm, &stp_btm->rFreeOpQ, &(stp_btm->arQue[i])); -+ } -+ -+ return 0; -+} -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/core/dbg_core.c b/drivers/misc/mediatek/connectivity/common/conn_soc/core/dbg_core.c -new file mode 100644 -index 000000000000..246448b38b31 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/core/dbg_core.c -@@ -0,0 +1,13 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/btm_core.h b/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/btm_core.h -new file mode 100644 -index 000000000000..9a429b4af1e3 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/btm_core.h -@@ -0,0 +1,133 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -+ -+/*! \file -+ \brief Declaration of library functions -+ -+ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. -+*/ -+ -+#ifndef _BTM_CORE_H -+#define _BTM_CORE_H -+ -+#include "osal_typedef.h" -+#include "osal.h" -+#include "stp_wmt.h" -+#include "wmt_plat.h" -+#include "wmt_idc.h" -+#include "mtk_btif_exp.h" -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+#define STP_BTM_OPERATION_FAIL (-1) -+#define STP_BTM_OPERATION_SUCCESS (0) -+ -+#define STP_BTM_OP_BUF_SIZE (64) -+ -+#define BTM_THREAD_NAME "mtk_stp_btm" -+ -+#define STP_PAGED_DUMP_TIME_LIMIT 3500 -+#define STP_FULL_DUMP_TIME 3 -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+typedef enum _ENUM_STP_BTM_OPID_T { -+ STP_OPID_BTM_RETRY = 0x0, -+ STP_OPID_BTM_RST = 0x1, -+ STP_OPID_BTM_DBG_DUMP = 0x2, -+ STP_OPID_BTM_DUMP_TIMEOUT = 0x3, -+ STP_OPID_BTM_POLL_CPUPCR = 0x4, -+ STP_OPID_BTM_PAGED_DUMP = 0x5, -+ STP_OPID_BTM_FULL_DUMP = 0x6, -+ STP_OPID_BTM_PAGED_TRACE = 0x7, -+ STP_OPID_BTM_FORCE_FW_ASSERT = 0x8, -+#if CFG_WMT_LTE_COEX_HANDLING -+ STP_OPID_BTM_WMT_LTE_COEX = 0x9, -+#endif -+ STP_OPID_BTM_EXIT, -+ STP_OPID_BTM_NUM -+} ENUM_STP_BTM_OPID_T, *P_ENUM_STP_BTM_OPID_T; -+ -+typedef OSAL_OP_DAT STP_BTM_OP; -+typedef P_OSAL_OP_DAT P_STP_BTM_OP; -+ -+typedef struct mtk_stp_btm { -+ OSAL_THREAD BTMd; /* main thread (wmtd) handle */ -+ OSAL_EVENT STPd_event; -+ OSAL_UNSLEEPABLE_LOCK wq_spinlock; -+ -+ OSAL_OP_Q rFreeOpQ; /* free op queue */ -+ OSAL_OP_Q rActiveOpQ; /* active op queue */ -+ OSAL_OP arQue[STP_BTM_OP_BUF_SIZE]; /* real op instances */ -+ -+ /*wmt_notify */ -+ INT32 (*wmt_notify)(MTKSTP_BTM_WMT_OP_T); -+} MTKSTP_BTM_T; -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+INT32 stp_btm_notify_wmt_rst_wq(MTKSTP_BTM_T *stp_btm); -+INT32 stp_btm_notify_stp_retry_wq(MTKSTP_BTM_T *stp_btm); -+INT32 stp_btm_notify_coredump_timeout_wq(MTKSTP_BTM_T *stp_btm); -+INT32 stp_btm_notify_wmt_dmp_wq(MTKSTP_BTM_T *stp_btm); -+INT32 stp_btm_deinit(MTKSTP_BTM_T *stp_btm); -+INT32 stp_btm_reset_btm_wq(MTKSTP_BTM_T *stp_btm); -+INT32 stp_notify_btm_poll_cpupcr(MTKSTP_BTM_T *stp_btm, UINT32 times, UINT32 sleep); -+INT32 stp_notify_btm_poll_cpupcr_ctrl(UINT32 en); -+INT32 stp_btm_notify_wmt_trace_wq(MTKSTP_BTM_T *stp_btm); -+INT32 stp_notify_btm_do_fw_assert_via_emi(MTKSTP_BTM_T *stp_btm); -+INT32 stp_notify_btm_handle_wmt_lte_coex(MTKSTP_BTM_T *stp_btm); -+INT32 wcn_psm_flag_trigger_collect_ftrace(void); -+#if BTIF_RXD_BE_BLOCKED_DETECT -+INT32 wcn_btif_rxd_blocked_collect_ftrace(void); -+MTK_WCN_BOOL is_btif_rxd_be_blocked(void); -+#endif -+MTKSTP_BTM_T *stp_btm_init(void); -+extern unsigned int g_coredump_mode; -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/dbg_core.h b/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/dbg_core.h -new file mode 100644 -index 000000000000..d8c6ebe9c4b0 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/dbg_core.h -@@ -0,0 +1,69 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -+ -+/*! \file -+ \brief Declaration of library functions -+ -+ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. -+*/ -+ -+#ifndef _DBG_CORE_H -+#define _DBG_CORE_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/psm_core.h b/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/psm_core.h -new file mode 100644 -index 000000000000..fe92f25e92c1 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/psm_core.h -@@ -0,0 +1,251 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -+ -+/*! \file -+ \brief Declaration of library functions -+ -+ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. -+*/ -+ -+#ifndef _PSM_CORE_H -+#define _PSM_CORE_H -+ -+#include "osal_typedef.h" -+#include "osal.h" -+#include "stp_wmt.h" -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+#define PFX_PSM "[STP-PSM] " -+#define STP_PSM_LOG_LOUD 4 -+#define STP_PSM_LOG_DBG 3 -+#define STP_PSM_LOG_INFO 2 -+#define STP_PSM_LOG_WARN 1 -+#define STP_PSM_LOG_ERR 0 -+ -+#define ASSERT(expr) -+#define STP_PSM_FIFO_SIZE 0x2000 /* 8kbytes */ -+#define STP_PSM_TX_SIZE 0x800 /* 2kbytes */ -+ -+#define STP_PSM_OPERATION_FAIL (-1) -+#define STP_PSM_OPERATION_SUCCESS (0) -+ -+#define STP_PSM_PACKET_SIZE_MAX (2000) -+ -+#define PSM_HANDLING 127 -+ -+#define STP_PSM_WMT_PS_TASK_HANDLING_TIME 30 /* 20 milli-seconds */ -+#define STP_PSM_IDLE_TIME_SLEEP 30 /* temporary for stress testing */ -+#define STP_PSM_IDLE_TIME_SLEEP_1000 1000 /* for high speed transmission e.g. BT OPP*/ -+#define STP_PSM_SDIO_IDLE_TIME_SLEEP 100 /* temporary for SDIO stress testing */ -+#define STP_PSM_WAIT_EVENT_TIMEOUT 6000 -+#if 0 -+#define STP_PSM_WMT_EVENT_SLEEP_EN (0x1UL << 0) -+#define STP_PSM_WMT_EVENT_WAKEUP_EN (0x1UL << 1) -+#define STP_PSM_BLOCK_DATA_EN (0x1UL << 2) -+#define STP_PSM_WMT_EVENT_DISABLE_MONITOR (0x1UL << 3) -+#define STP_PSM_WMT_EVENT_ROLL_BACK_EN (0x1UL << 4) -+#define STP_PSM_RESET_EN (0x1UL << 5) -+#define STP_PSM_WMT_EVENT_HOST_WAKEUP_EN (0x1UL << 6) -+#define STP_PSM_WMT_EVENT_DISABLE_MONITOR_TX_HIGH_DENSITY (0x1UL << 7) -+#define STP_PSM_WMT_EVENT_DISABLE_MONITOR_RX_HIGH_DENSITY (0x1UL << 8) -+#endif -+ -+#define STP_PSM_WMT_EVENT_SLEEP_EN (0) -+#define STP_PSM_WMT_EVENT_WAKEUP_EN (1) -+#define STP_PSM_BLOCK_DATA_EN (2) -+#define STP_PSM_WMT_EVENT_DISABLE_MONITOR (3) -+#define STP_PSM_WMT_EVENT_ROLL_BACK_EN (4) -+#define STP_PSM_RESET_EN (5) -+#define STP_PSM_WMT_EVENT_HOST_WAKEUP_EN (6) -+#define STP_PSM_WMT_EVENT_DISABLE_MONITOR_TX_HIGH_DENSITY (7) -+#define STP_PSM_WMT_EVENT_DISABLE_MONITOR_RX_HIGH_DENSITY (8) -+ -+#define STP_PSM_DBG_SIZE (16) -+ -+/* OP command ring buffer : must be power of 2 */ -+#define STP_OP_BUF_SIZE (16) -+ -+#define PSM_THREAD_NAME "mtk_stp_psm" -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+typedef enum { -+ ACT = 0, -+ ACT_INACT, -+ INACT, -+ INACT_ACT, -+ STP_PSM_MAX_STATE, -+} MTKSTP_PSM_STATE_T; -+ -+typedef enum _ENUM_STP_OPID_T { -+ STP_OPID_PSM_SLEEP = 0, -+ STP_OPID_PSM_WAKEUP, -+ STP_OPID_PSM_HOST_AWAKE, -+ STP_OPID_PSM_EXIT, -+ STP_OPID_PSM_NUM, -+ STP_OPID_PSM_INALID = STP_OPID_PSM_NUM, -+} ENUM_STP_OPID_T, *P_ENUM_STP_OPID_T; -+ -+typedef enum { -+ MON = 0, -+ UNMON, -+} MTKSTP_PSM_MONSTATE_T; -+ -+typedef INT32(*wmt_notify_t) (MTKSTP_PSM_ACTION_T action); -+typedef INT32(*stp_tx_cb_t) (unsigned char *buffer, UINT32 length, UINT8 type); -+ -+typedef OSAL_OP_DAT STP_OP; -+typedef P_OSAL_OP_DAT P_STP_OP; -+ -+typedef struct mtk_stp_psm { -+ OSAL_THREAD PSMd; /* main thread (wmtd) handle */ -+ OSAL_EVENT STPd_event; -+ -+ OSAL_OP_Q rFreeOpQ; /* free op queue */ -+ OSAL_OP_Q rActiveOpQ; /* active op queue */ -+ OSAL_OP arQue[STP_OP_BUF_SIZE]; /* real op instances */ -+ -+ /* OSAL_OP current_active_op; */ -+ /* P_OSAL_OP current_active_op; */ -+ UINT32 last_active_opId; -+ MTKSTP_PSM_STATE_T work_state; /*working state */ -+ OSAL_BIT_OP_VAR flag; -+ -+ /* in normal cases, sleep op is always enabled; -+ * but in error cases, we can't execute sleep cmd, -+ * Eg: FW assert, core dump -+ */ -+ INT32 sleep_en; -+ -+/* OSAL_UNSLEEPABLE_LOCK flagSpinlock; */ -+ INT32 idle_time_to_sleep; -+ OSAL_WAKE_LOCK wake_lock; -+ OSAL_TIMER psm_timer; /*monitor if active */ -+ OSAL_EVENT wait_wmt_q; -+ OSAL_FIFO hold_fifo; -+ OSAL_SLEEPABLE_LOCK hold_fifo_spinlock_global; -+ OSAL_UNSLEEPABLE_LOCK wq_spinlock; -+ OSAL_SLEEPABLE_LOCK stp_psm_lock; -+ INT32 (*wmt_notify)(MTKSTP_PSM_ACTION_T action); -+ INT32 (*stp_tx_cb)(unsigned char *buffer, UINT32 length, UINT8 type); -+ -+ MTK_WCN_BOOL (*is_wmt_quick_ps_support)(VOID); -+ UINT8 out_buf[STP_PSM_TX_SIZE]; -+} MTKSTP_PSM_T; -+ -+typedef struct { -+ UINT32 prev_flag; -+ UINT32 cur_flag; -+ UINT32 line_num; -+ UINT32 package_no; -+ UINT32 sec; -+ UINT32 usec; -+ UINT32 pid; -+} STP_PSM_ENTRY_T; -+ -+typedef struct stp_psm_record { -+ STP_PSM_ENTRY_T queue[STP_PSM_DBG_SIZE]; -+ UINT32 in; -+ UINT32 out; -+ UINT32 size; -+ OSAL_UNSLEEPABLE_LOCK lock; -+} STP_PSM_RECORD_T; -+ -+typedef struct stp_psm_opid_record { -+ STP_PSM_ENTRY_T queue[STP_PSM_DBG_SIZE]; -+ UINT32 in; -+ UINT32 out; -+ UINT32 size; -+ OSAL_UNSLEEPABLE_LOCK lock; -+} STP_PSM_OPID_RECORD, *P_STP_PSM_OPID_RECORD; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+#define PSM_USE_COUNT_PACKAGE 0 -+ -+#if PSM_USE_COUNT_PACKAGE -+#define MTK_COMBO_PSM_RX_TH_DEFAULT (1600) -+#define MTK_COMBO_PSM_TX_TH_DEFAULT (300) -+INT32 stp_psm_disable_by_tx_rx_density(MTKSTP_PSM_T *stp_psm, INT32 dir); -+#else -+#define SAMPLE_DURATION 1 /*1 second */ -+#define RTX_SPEED_THRESHOLD 50000 /*50KB/s */ -+INT32 stp_psm_disable_by_tx_rx_density(MTKSTP_PSM_T *stp_psm, INT32 dir, INT32 length); -+#endif -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+/*stp-psm external function*/ -+INT32 stp_psm_notify_stp(MTKSTP_PSM_T *stp_psm, const MTKSTP_PSM_ACTION_T action); -+INT32 stp_psm_notify_wmt_wakeup(MTKSTP_PSM_T *stp_psm); -+INT32 stp_psm_notify_wmt_sleep(MTKSTP_PSM_T *stp_psm); -+ -+INT32 stp_psm_start_monitor(MTKSTP_PSM_T *stp_psm); -+INT32 stp_psm_is_to_block_traffic(MTKSTP_PSM_T *stp_psm); -+INT32 stp_psm_is_disable(MTKSTP_PSM_T *stp_psm); -+INT32 stp_psm_has_pending_data(MTKSTP_PSM_T *stp_psm); -+INT32 stp_psm_release_data(MTKSTP_PSM_T *stp_psm); -+INT32 stp_psm_hold_data(MTKSTP_PSM_T *stp_psm, const UINT8 *buffer, const UINT32 len, const UINT8 type); -+INT32 stp_psm_do_wakeup(MTKSTP_PSM_T *stp_psm); -+INT32 stp_psm_reset(MTKSTP_PSM_T *stp_psm); -+INT32 stp_psm_disable(MTKSTP_PSM_T *stp_psm); -+INT32 stp_psm_enable(MTKSTP_PSM_T *stp_psm, INT32 idle_time_to_sleep); -+struct mtk_stp_psm *stp_psm_init(void); -+INT32 stp_psm_deinit(MTKSTP_PSM_T *stp_psm); -+MTK_WCN_BOOL mtk_wcn_stp_psm_dbg_level(UINT32 dbglevel); -+INT32 stp_psm_sleep_for_thermal(MTKSTP_PSM_T *stp_psm); -+INT32 stp_psm_thread_lock_aquire(MTKSTP_PSM_T *stp_psm); -+INT32 stp_psm_thread_lock_release(MTKSTP_PSM_T *stp_psm); -+INT32 stp_psm_set_state(MTKSTP_PSM_T *stp_psm, MTKSTP_PSM_STATE_T state); -+MTK_WCN_BOOL stp_psm_is_quick_ps_support(VOID); -+ -+INT32 stp_psm_set_sleep_enable(MTKSTP_PSM_T *stp_psm); -+INT32 stp_psm_set_sleep_disable(MTKSTP_PSM_T *stp_psm); -+INT32 stp_psm_check_sleep_enable(MTKSTP_PSM_T *stp_psm); -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/stp_core.h b/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/stp_core.h -new file mode 100644 -index 000000000000..eaa5ce773e33 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/stp_core.h -@@ -0,0 +1,629 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -+ -+/*! \file -+ \brief Declaration of library functions -+ -+ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. -+*/ -+ -+#ifndef _STP_CORE_H -+#define _STP_CORE_H -+ -+#include "osal_typedef.h" -+#include "osal.h" -+#include "stp_exp.h" -+#include "psm_core.h" -+#include "btm_core.h" -+#include "stp_btif.h" -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+#define CFG_STP_CORE_CTX_SPIN_LOCK (0) -+ -+#define WMT_LTE_COEX_FLAG (0x16) -+ -+/*configure using SPINLOCK or just mutex for STP-CORE tx*/ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+#define CONFIG_POWER_SAVING_SUPPORT -+ -+#ifdef PFX -+#undef PFX -+#endif -+#define PFX "[STP] " -+ -+#define STP_LOG_DBG 4 -+#define STP_LOG_PKHEAD 3 -+#define STP_LOG_INFO 2 -+#define STP_LOG_WARN 1 -+#define STP_LOG_ERR 0 -+ -+extern unsigned int gStpDbgLvl; -+ -+#define STP_DBG_FUNC(fmt, arg...)\ -+do { \ -+ if (gStpDbgLvl >= STP_LOG_DBG) \ -+ osal_dbg_print(PFX "%s: " fmt, __func__ , ##arg); \ -+} while (0) -+#define STP_INFO_FUNC(fmt, arg...) \ -+do { \ -+ if (gStpDbgLvl >= STP_LOG_INFO) \ -+ osal_dbg_print(PFX "%s:[I] " fmt, __func__ , ##arg); \ -+} while (0) -+#define STP_WARN_FUNC(fmt, arg...) \ -+do { \ -+ if (gStpDbgLvl >= STP_LOG_WARN) \ -+ osal_warn_print(PFX "%s:[W] " fmt, __func__ , ##arg); \ -+} while (0) -+#define STP_ERR_FUNC(fmt, arg...) \ -+do { \ -+ if (gStpDbgLvl >= STP_LOG_ERR) \ -+ osal_err_print(PFX "%s:[E] " fmt, __func__ , ##arg); \ -+} while (0) -+#define STP_TRC_FUNC(f) \ -+do { \ -+ if (gStpDbgLvl >= STP_LOG_DBG) \ -+ osal_dbg_print(PFX "<%s> <%d>\n", __func__, __LINE__); \ -+} while (0) -+ -+#define STP_DUMP_PACKET_HEAD(a, b, c) \ -+do { \ -+ if (gStpDbgLvl >= STP_LOG_PKHEAD) \ -+ stp_dump_data(a, b, c); \ -+} while (0) -+#define STP_TRACE_FUNC(fmt, arg...) \ -+do { \ -+ if (gStpDbgLvl >= STP_LOG_DBG) \ -+ osal_dbg_print(PFX "%s: " fmt, __func__ , ##arg); \ -+} while (0) -+ -+#define STP_MODE_BIT(x) (0x1UL << x) -+#define MTKSTP_UART_FULL_MODE STP_MODE_BIT(0) -+#define MTKSTP_UART_MAND_MODE STP_MODE_BIT(1) -+#define MTKSTP_BTIF_FULL_MODE STP_MODE_BIT(2) -+#define MTKSTP_BTIF_MAND_MODE STP_MODE_BIT(3) -+#define MTKSTP_SDIO_MODE STP_MODE_BIT(4) -+ -+#define MTKSTP_BUFFER_SIZE (16384) -+ -+/*To check function driver's status by the the interface*/ -+/*Operation definition*/ -+#define OP_FUNCTION_ACTIVE 0 -+ -+/*Driver's status*/ -+#define STATUS_OP_INVALID 0 -+#define STATUS_FUNCTION_INVALID 1 -+ -+#define STATUS_FUNCTION_ACTIVE 31 -+#define STATUS_FUNCTION_INACTIVE 32 -+ -+#define MTKSTP_CRC_SIZE (2) -+#define MTKSTP_HEADER_SIZE (4) -+#define MTKSTP_SEQ_SIZE (8) -+ -+/*#define MTKSTP_WINSIZE (4)*/ -+#define MTKSTP_WINSIZE (7) -+#define MTKSTP_TX_TIMEOUT (180) /*TODO: Baudrate to decide this */ -+#define MTKSTP_RETRY_LIMIT (10) -+ -+#define INDEX_INC(idx) \ -+{ \ -+ idx++; \ -+ idx &= 0x7; \ -+} -+ -+#define INDEX_DEC(idx) \ -+{ \ -+ idx--; \ -+ idx &= 0x7; \ -+} -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+typedef INT32(*IF_TX) (const PUINT8 data, const UINT32 size, PUINT32 written_size); -+/* event/signal */ -+typedef INT32(*EVENT_SET) (UINT8 function_type); -+typedef INT32(*EVENT_TX_RESUME) (UINT8 winspace); -+typedef INT32(*FUNCTION_STATUS) (UINT8 type, UINT8 op); -+typedef INT32(*WMT_NOTIFY_FUNC_T) (UINT32 action); -+typedef INT32(*BTM_NOTIFY_WMT_FUNC_T) (INT32); -+ -+#if CFG_STP_CORE_CTX_SPIN_LOCK -+typedef OSAL_UNSLEEPABLE_LOCK STP_CTX_LOCK, *PSTP_CTX_LOCK; -+#else -+typedef OSAL_SLEEPABLE_LOCK STP_CTX_LOCK, *PSTP_CTX_LOCK; -+#endif -+ -+typedef struct { -+ /* common interface */ -+ IF_TX cb_if_tx; -+ /* event/signal */ -+ EVENT_SET cb_event_set; -+ EVENT_TX_RESUME cb_event_tx_resume; -+ FUNCTION_STATUS cb_check_funciton_status; -+} mtkstp_callback; -+ -+typedef enum { -+ MTKSTP_SYNC = 0, -+ MTKSTP_SEQ, -+ MTKSTP_ACK, -+ MTKSTP_NAK, -+ MTKSTP_TYPE, -+ MTKSTP_LENGTH, -+ MTKSTP_CHECKSUM, -+ MTKSTP_DATA, -+ MTKSTP_CRC1, -+ MTKSTP_CRC2, -+ MTKSTP_RESYNC1, -+ MTKSTP_RESYNC2, -+ MTKSTP_RESYNC3, -+ MTKSTP_RESYNC4, -+ MTKSTP_FW_MSG, -+} mtkstp_parser_state; -+ -+typedef struct { -+ mtkstp_parser_state state; -+ UINT8 seq; -+ UINT8 ack; -+ UINT8 nak; -+ UINT8 type; -+ UINT16 length; -+ UINT8 checksum; -+ UINT16 crc; -+#if 1 -+ UINT8 wmtsubtype; -+#endif -+} mtkstp_parser_context_struct; -+ -+typedef struct { -+ UINT8 txseq; /* last tx pkt's seq + 1 */ -+ UINT8 txack; /* last tx pkt's ack */ -+ UINT8 rxack; /* last rx pkt's ack */ -+ UINT8 winspace; /* current sliding window size */ -+ UINT8 expected_rxseq; /* last rx pkt's seq + 1 */ -+ UINT8 retry_times; -+} mtkstp_sequence_context_struct; -+ -+typedef struct { -+ /* MTK_WCN_MUTEX mtx; */ -+ OSAL_UNSLEEPABLE_LOCK mtx; -+ UINT8 buffer[MTKSTP_BUFFER_SIZE]; -+ UINT32 read_p; -+ UINT32 write_p; -+} mtkstp_ring_buffer_struct; -+ -+typedef struct { -+ UINT8 inband_rst_set; -+ UINT32 rx_counter; /* size of current processing pkt in rx_buf[] */ -+ UINT8 rx_buf[MTKSTP_BUFFER_SIZE]; /* input buffer of STP, room for current processing pkt */ -+ UINT32 tx_read; /* read ptr of tx_buf[] */ -+ UINT32 tx_write; /* write ptr of tx_buf[] */ -+ UINT8 tx_buf[MTKSTP_BUFFER_SIZE]; /* output buffer of STP */ -+ UINT32 tx_start_addr[MTKSTP_SEQ_SIZE]; /* ptr of each pkt in tx_buf[] */ -+ UINT32 tx_length[MTKSTP_SEQ_SIZE]; /* length of each pkt in tx_buf[] */ -+ mtkstp_ring_buffer_struct ring[MTKSTP_MAX_TASK_NUM]; /* ring buffers for each function driver */ -+ mtkstp_parser_context_struct parser; /* current rx pkt's content */ -+ mtkstp_sequence_context_struct sequence; /* state machine's current status */ -+ /* MTK_WCN_MUTEX stp_mutex; */ -+ /* OSAL_UNSLEEPABLE_LOCK stp_mutex; */ -+ STP_CTX_LOCK stp_mutex; -+ /* MTK_WCN_TIMER tx_timer; // timer for tx timeout handling */ -+ OSAL_TIMER tx_timer; -+ -+ MTKSTP_PSM_T *psm; -+ MTKSTP_BTM_T *btm; -+ UINT8 f_enable; /* default disabled */ -+ UINT8 f_ready; /* default non-ready */ -+ UINT8 f_pending_type; -+ UINT8 f_coredump; /*block tx flag, for now, only when f/w assert happens, we will set this bit on */ -+ UINT8 en_coredump; -+ /* Flag to identify Blueztooth is Bluez/or MTK Stack */ -+ MTK_WCN_BOOL f_bluez; -+ MTK_WCN_BOOL f_dbg_en; -+ MTK_WCN_BOOL f_autorst_en; -+ -+ /* Flag to identify STP by SDIO or UART */ -+ UINT32 f_mode; -+ -+ /* Flag to indicate the last WMT CLOSE */ -+ UINT32 f_wmt_last_close; -+ -+ /* Flag to indicate evt err has triggered assert or not */ -+ UINT32 f_evt_err_assert; -+} mtkstp_context_struct; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+INT32 stp_send_data_no_ps(UINT8 *buffer, UINT32 length, UINT8 type); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_init -+* DESCRIPTION -+* init STP kernel -+* PARAMETERS -+* cb_func [IN] function pointers of system APIs -+* RETURNS -+* INT32 0 = success, others = failure -+*****************************************************************************/ -+extern INT32 mtk_wcn_stp_init(const mtkstp_callback * const cb_func); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_deinit -+* DESCRIPTION -+* deinit STP kernel -+* PARAMETERS -+* void -+* RETURNS -+* INT32 0 = success, others = failure -+*****************************************************************************/ -+extern INT32 mtk_wcn_stp_deinit(void); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_enable -+* DESCRIPTION -+* enable/disable STP -+* PARAMETERS -+* value [IN] 0 = disable, others = enable -+* RETURNS -+* INT32 0 = success, others = error -+*****************************************************************************/ -+extern INT32 mtk_wcn_stp_enable(INT32 value); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_ready -+* DESCRIPTION -+* ready/non-ready STP -+* PARAMETERS -+* value [IN] 0 = non-ready, others = ready -+* RETURNS -+* INT32 0 = success, others = error -+*****************************************************************************/ -+extern INT32 mtk_wcn_stp_ready(INT32 value); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_coredump_start_ctrl -+* DESCRIPTION -+* set f/w assert flag in STP context -+* PARAMETERS -+* value [IN] 0=assert end, others=assert begins -+* RETURNS -+* INT32 0=success, others=error -+*****************************************************************************/ -+extern INT32 mtk_wcn_stp_coredump_start_ctrl(UINT32 value); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_coredump_start_get -+* DESCRIPTION -+* get f/w assert flag in STP context -+* PARAMETERS -+* VOID -+* RETURNS -+* INT32 0= f/w assert flag is not set, others=f/w assert flag is set -+*****************************************************************************/ -+extern INT32 mtk_wcn_stp_coredump_start_get(VOID); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_send_data_raw -+* DESCRIPTION -+* send raw data to common interface, bypass STP -+* PARAMETERS -+* buffer [IN] data buffer -+* length [IN] data buffer length -+* type [IN] subfunction type -+* RETURNS -+* INT32 length transmitted -+*****************************************************************************/ -+extern INT32 mtk_wcn_stp_send_data_raw(const PUINT8 buffer, const UINT32 length, const UINT8 type); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_set_sdio_mode -+* DESCRIPTION -+* Set stp for SDIO mode -+* PARAMETERS -+* sdio_flag [IN] sdio mode flag (TRUE:SDIO mode, FALSE:UART mode) -+* RETURNS -+* void -+*****************************************************************************/ -+extern void mtk_wcn_stp_set_mode(UINT32 sdio_flag); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_is_uart_fullset_mode -+* DESCRIPTION -+* Is stp use UART Fullset mode? -+* PARAMETERS -+* none. -+* RETURNS -+* MTK_WCN_BOOL TRUE:UART Fullset, FALSE:UART Fullset -+*****************************************************************************/ -+extern MTK_WCN_BOOL mtk_wcn_stp_is_uart_fullset_mode(void); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_is_uart_mand_mode -+* DESCRIPTION -+* Is stp use UART Mandatory mode? -+* PARAMETERS -+* none. -+* RETURNS -+* MTK_WCN_BOOL TRUE:UART Mandatory, FALSE:UART Mandatory -+*****************************************************************************/ -+extern MTK_WCN_BOOL mtk_wcn_stp_is_uart_mand_mode(void); -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_is_btif_fullset_mode -+* DESCRIPTION -+* Is stp use BTIF Fullset mode? -+* PARAMETERS -+* none. -+* RETURNS -+* MTK_WCN_BOOL TRUE:BTIF Fullset, FALSE:BTIF Fullset -+*****************************************************************************/ -+extern MTK_WCN_BOOL mtk_wcn_stp_is_btif_fullset_mode(void); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_is_btif_mand_mode -+* DESCRIPTION -+* Is stp use BTIF Mandatory mode? -+* PARAMETERS -+* none. -+* RETURNS -+* MTK_WCN_BOOL TRUE:BTIF Mandatory, FALSE:BTIF Mandatory -+*****************************************************************************/ -+extern MTK_WCN_BOOL mtk_wcn_stp_is_btif_mand_mode(void); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_is_sdio_mode -+* DESCRIPTION -+* Is stp use SDIO mode? -+* PARAMETERS -+* none. -+* RETURNS -+* MTK_WCN_BOOL TRUE:SDIO mode, FALSE:UART mode -+*****************************************************************************/ -+extern MTK_WCN_BOOL mtk_wcn_stp_is_sdio_mode(void); -+ -+/***************************************************************************** -+* FUNCTION -+* stp_send_inband_reset -+* DESCRIPTION -+* To sync to oringnal stp state with f/w stp -+* PARAMETERS -+* none. -+* RETURNS -+* none -+*****************************************************************************/ -+extern void mtk_wcn_stp_inband_reset(void); -+ -+/***************************************************************************** -+* FUNCTION -+* stp_send_inband_reset -+* DESCRIPTION -+* To send testing command to chip -+* PARAMETERS -+* none. -+* RETURNS -+* none -+*****************************************************************************/ -+extern void mtk_wcn_stp_test_cmd(INT32 no); -+ -+/***************************************************************************** -+* FUNCTION -+* stp_send_inband_reset -+* DESCRIPTION -+* To control STP debugging mechanism -+* PARAMETERS -+* func_no: function control, func_op: dumpping filer, func_param: dumpping parameter -+* RETURNS -+* none -+*****************************************************************************/ -+extern void mtk_wcn_stp_debug_ctrl(INT32 func_no, INT32 func_op, INT32 func_param); -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_flush -+* DESCRIPTION -+* flush all stp context -+* PARAMETERS -+* none. -+* RETURNS -+* none -+*****************************************************************************/ -+extern void mtk_wcn_stp_flush_context(void); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_rx_queue -+* DESCRIPTION -+* flush all stp rx queue -+* PARAMETERS -+* none. -+* RETURNS -+* none -+*****************************************************************************/ -+extern void mtk_wcn_stp_flush_rx_queue(UINT32 type); -+ -+/***************************************************************************** -+* FUNCTION -+* set stp debugging mdoe -+* DESCRIPTION -+* set stp debugging mdoe -+* PARAMETERS -+* dbg_mode: switch to dbg mode ? -+* RETURNS -+* void -+*****************************************************************************/ -+extern void mtk_wcn_stp_set_dbg_mode(MTK_WCN_BOOL dbg_mode); -+ -+/***************************************************************************** -+* FUNCTION -+* set stp auto reset mdoe -+* DESCRIPTION -+* set stp auto reset mdoe -+* PARAMETERS -+* auto_rst: switch to auto reset mode ? -+* RETURNS -+* void -+*****************************************************************************/ -+extern void mtk_wcn_stp_set_auto_rst(MTK_WCN_BOOL auto_rst); -+ -+/*stp_psm support*/ -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_psm_notify_stp -+* DESCRIPTION -+* WMT notification to STP that power saving job is done or not -+* PARAMETERS -+* -+* RETURNS -+* 0: Sccuess Negative value: Fail -+*****************************************************************************/ -+extern int mtk_wcn_stp_psm_notify_stp(const UINT32 action); -+ -+extern int mtk_wcn_stp_set_psm_state(MTKSTP_PSM_STATE_T state); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_psm_enabla -+* DESCRIPTION -+* enable STP PSM -+* PARAMETERS -+* int idle_time_to_sleep: IDLE time to sleep -+* RETURNS -+* 0: Sccuess Negative value: Fail -+*****************************************************************************/ -+extern int mtk_wcn_stp_psm_enable(int idle_time_to_sleep); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_psm_disable -+* DESCRIPTION -+* disable STP PSM -+* PARAMETERS -+* void -+* RETURNS -+* 0: Sccuess Negative value: Fail -+*****************************************************************************/ -+extern int mtk_wcn_stp_psm_disable(void); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_psm_reset -+* DESCRIPTION -+* reset STP PSM (used on whole chip reset) -+* PARAMETERS -+* void -+* RETURNS -+* 0: Sccuess Negative value: Fail -+*****************************************************************************/ -+extern int mtk_wcn_stp_psm_reset(void); -+extern void stp_do_tx_timeout(void); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_btm_get_dmp -+* DESCRIPTION -+* get stp dump related information -+* PARAMETERS -+* buffer: dump placement, len: dump size -+* RETURNS -+* 0: Success Negative Value: Fail -+*****************************************************************************/ -+extern int mtk_wcn_stp_btm_get_dmp(char *buf, int *len); -+ -+extern int mtk_wcn_stp_dbg_enable(void); -+ -+extern int mtk_wcn_stp_dbg_disable(void); -+ -+extern void mtk_wcn_stp_set_if_tx_type(ENUM_STP_TX_IF_TYPE stp_if_type); -+ -+extern int mtk_wcn_sys_if_rx(UINT8 *data, INT32 size); -+ -+extern MTK_WCN_BOOL mtk_wcn_stp_dbg_level(UINT32 dbglevel); -+ -+extern INT32 mtk_wcn_stp_dbg_dump_package(VOID); -+ -+extern int stp_drv_init(void); -+ -+extern void stp_drv_exit(void); -+ -+extern INT32 mtk_wcn_stp_dbg_log_ctrl(UINT32 on); -+ -+extern INT32 mtk_wcn_stp_coredump_flag_ctrl(UINT32 on); -+ -+extern INT32 mtk_wcn_stp_coredump_flag_get(VOID); -+extern INT32 mtk_wcn_stp_notify_sleep_for_thermal(void); -+ -+extern INT32 mtk_wcn_stp_set_wmt_last_close(UINT32 value); -+ -+/*stp btif API declared*/ -+extern INT32 mtk_wcn_stp_open_btif(VOID); -+extern INT32 mtk_wcn_stp_close_btif(VOID); -+extern INT32 mtk_wcn_stp_rxcb_register(MTK_WCN_BTIF_RX_CB rx_cb); -+extern INT32 mtk_wcn_stp_tx(UINT8 *pBuf, UINT32 len, UINT32 *written_len); -+extern INT32 mtk_wcn_stp_wakeup_consys(VOID); -+extern INT32 mtk_wcn_stp_dpidle_ctrl(ENUM_BTIF_DPIDLE_CTRL en_flag); -+extern INT32 mtk_wcn_stp_lpbk_ctrl(ENUM_BTIF_LPBK_MODE mode); -+extern INT32 mtk_wcn_stp_logger_ctrl(ENUM_BTIF_DBG_ID flag); -+extern VOID mtk_wcn_stp_ctx_save(VOID); -+extern VOID mtk_wcn_stp_ctx_restore(VOID); -+extern INT32 mtk_wcn_stp_wmt_evt_err_trg_assert(VOID); -+extern VOID mtk_wcn_stp_set_wmt_evt_err_trg_assert(UINT32 value); -+extern UINT32 mtk_wcn_stp_get_wmt_evt_err_trg_assert(VOID); -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif /* _STP_CORE_H_ */ -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/stp_wmt.h b/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/stp_wmt.h -new file mode 100644 -index 000000000000..94b3d8a597ac ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/stp_wmt.h -@@ -0,0 +1,89 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -+ -+/*! \file -+ \brief Declaration of library functions -+ -+ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. -+*/ -+ -+#ifndef _STP_WMT_H -+#define _STP_WMT_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+typedef enum { -+ BTM_RST_OP = 0, -+ BTM_DMP_OP = 1, -+ BTM_GET_AEE_SUPPORT_FLAG = 2, -+ BTM_MAX_OP, -+} MTKSTP_BTM_WMT_OP_T; -+ -+typedef enum { -+ SLEEP = 0, -+ HOST_AWAKE, -+ WAKEUP, -+ EIRQ, -+ ROLL_BACK, -+ STP_PSM_MAX_ACTION -+} MTKSTP_PSM_ACTION_T; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+extern MTK_WCN_BOOL wmt_lib_btm_cb(MTKSTP_BTM_WMT_OP_T op); -+ -+extern INT32 wmt_lib_ps_stp_cb(MTKSTP_PSM_ACTION_T action); -+extern MTK_WCN_BOOL wmt_lib_is_quick_ps_support(VOID); -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif /* _STP_WMT_H_ */ -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_conf.h b/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_conf.h -new file mode 100644 -index 000000000000..4c64b6b5e65b ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_conf.h -@@ -0,0 +1,74 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -+ -+/*! \file -+ \brief Declaration of library functions -+ -+ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. -+*/ -+ -+#ifndef _WMT_CONF_H_ -+#define _WMT_CONF_H_ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+#define CUST_CFG_WMT "WMT_SOC.cfg" -+#define CUST_CFG_WMT_PREFIX "/system/etc/firmware/" -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+INT32 wmt_conf_read_file(VOID); -+P_WMT_GEN_CONF wmt_conf_get_cfg(VOID); -+INT32 wmt_conf_set_cfg_file(const char *name); -+ -+#endif /* _WMT_CONF_H_ */ -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_core.h b/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_core.h -new file mode 100644 -index 000000000000..cca52a15cc98 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_core.h -@@ -0,0 +1,428 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -+ -+/*! \file -+ \brief Declaration of library functions -+ -+ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. -+*/ -+ -+#ifndef _WMT_CORE_H_ -+#define _WMT_CORE_H_ -+ -+#include "osal.h" -+#include "wmt_ctrl.h" -+#include "wmt_exp.h" -+#include "wmt_plat.h" -+/* TODO: [GeorgeKuo][FixMe] remove temporarily */ -+/* for AIF state definition */ -+/* #include "mtk_wcn_cmb_stub.h" */ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+#define CFG_CORE_MT6620_SUPPORT 0 /* whether MT6620 is supported or not */ -+ -+#define CFG_CORE_MT6628_SUPPORT 0 /* whether MT6628 is supported or not */ -+ -+#define CFG_CORE_SOC_SUPPORT 1 -+ -+/* TODO:[ChangeFeature][George] move this definition outside so that wmt_dev can remove wmt_core.h inclusion. */ -+#define defaultPatchName "mt66xx_patch_hdr.bin" -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+#define BCNT_PATCH_BUF_HEADROOM (8) -+ -+#define DWCNT_HIF_CONF (4) -+#define DWCNT_STRAP_CONF (4) -+#define DWCNT_RESERVED (8) -+#define DWCNT_CTRL_DATA (16) -+ -+#if 0 /* TODO: [obsolete][GeorgeKuo]: remove ubsolete definitions */ -+#define WMT_SET (1) -+#define WMT_QUERY (0) -+#define WMT_PKT_FMT_RAW (1) -+#define WMT_PKT_FMT_STP (0) -+#endif -+ -+#define WMT_FUNC_CTRL_ON (MTK_WCN_BOOL_TRUE) -+#define WMT_FUNC_CTRL_OFF (MTK_WCN_BOOL_FALSE) -+ -+#define WMT_HDR_LEN (4) /* header length */ -+#define WMT_STS_LEN (1) /* status length */ -+#define WMT_FLAG_LEN (1) -+#define WMT_HIF_UART_INFO_LEN (4) -+#define WMT_FUNC_CTRL_PARAM_LEN (1) -+ -+#define WMT_DEFAULT_BAUD_RATE (115200) -+ -+#define INIT_CMD(c, e, s) {.cmd = c, .cmdSz = sizeof(c), .evt = e, .evtSz = sizeof(e), .str = s} -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+typedef enum _ENUM_WMT_FM_T { -+ WMT_FM_INVALID = 0, -+ WMT_FM_I2C = 1, -+ WMT_FM_COMM = 2, -+ WMT_FM_MAX -+} ENUM_WMT_FM_T, *P_ENUM_WMT_FM_T; -+ -+typedef enum _ENUM_WMT_HIF_T { -+ WMT_HIF_UART = 0, -+ WMT_HIF_SDIO = 1, -+ WMT_HIF_BTIF = 2, -+ WMT_HIF_MAX -+} ENUM_WMT_HIF_T, *P_ENUM_WMT_HIF_T; -+ -+#if 0 /* [George] moved to wmt_exp.h for hif_sdio's use */ -+typedef enum { -+ WMT_SDIO_SLOT_INVALID = 0, -+ WMT_SDIO_SLOT_SDIO1 = 1, /* Wi-Fi dedicated SDIO1 */ -+ WMT_SDIO_SLOT_SDIO2 = 2, -+ WMT_SDIO_SLOT_MAX -+} WMT_SDIO_SLOT_NUM; -+ -+typedef enum { -+ WMT_SDIO_FUNC_STP = 0, -+ WMT_SDIO_FUNC_WIFI = 1, -+ WMT_SDIO_FUNC_MAX -+} WMT_SDIO_FUNC_TYPE; -+#endif -+ -+typedef enum _ENUM_WMT_OPID_T { -+ WMT_OPID_HIF_CONF = 0, -+ WMT_OPID_PWR_ON = 1, -+ WMT_OPID_PWR_OFF = 2, -+ WMT_OPID_FUNC_ON = 3, -+ WMT_OPID_FUNC_OFF = 4, -+ WMT_OPID_REG_RW = 5, /* TODO:[ChangeFeature][George] is this OP obsoleted? */ -+ WMT_OPID_EXIT = 6, -+ WMT_OPID_PWR_SV = 7, -+ WMT_OPID_DSNS = 8, -+ WMT_OPID_LPBK = 9, -+ WMT_OPID_CMD_TEST = 10, -+ WMT_OPID_HW_RST = 11, -+ WMT_OPID_SW_RST = 12, -+ WMT_OPID_BAUD_RST = 13, -+ WMT_OPID_STP_RST = 14, -+ WMT_OPID_THERM_CTRL = 15, -+ WMT_OPID_EFUSE_RW = 16, -+ WMT_OPID_GPIO_CTRL = 17, -+ WMT_OPID_FW_COREDMP = 18, -+ WMT_OPID_GPIO_STATE = 19, -+ WMT_OPID_BGW_DS = 20, -+ WMT_OPID_SET_MCU_CLK = 21, -+ WMT_OPID_ADIE_LPBK_TEST = 22, -+#if CFG_WMT_LTE_COEX_HANDLING -+ WMT_OPID_IDC_MSG_HANDLING = 23, -+#endif -+#ifdef CONFIG_MTK_COMBO_ANT -+ WMT_OPID_ANT_RAM_DOWN = 24, -+ WMT_OPID_ANT_RAM_STA_GET = 25, -+#endif -+ WMT_OPID_MAX -+} ENUM_WMT_OPID_T, *P_ENUM_WMT_OPID_T; -+ -+typedef OSAL_OP_DAT WMT_OP; -+typedef P_OSAL_OP_DAT P_WMT_OP; -+ -+typedef struct _WMT_HIF_CONF { -+ UINT32 hifType; /* HIF Type */ -+ UINT32 au4HifConf[DWCNT_HIF_CONF]; /* HIF Config */ -+ UINT32 au4StrapConf[DWCNT_STRAP_CONF]; /* Strap Config */ -+} WMT_HIF_CONF, *P_WMT_HIF_CONF; -+ -+typedef INT32(*WMT_OPID_FUNC) (P_WMT_OP); -+ -+typedef struct _WMT_GEN_CONF { -+ UINT8 cfgExist; -+ -+ UINT8 coex_wmt_ant_mode; -+ UINT8 coex_wmt_ext_component; -+ UINT8 coex_wmt_wifi_time_ctl; -+ UINT8 coex_wmt_ext_pta_dev_on; -+ /*mt6592 and LTE coex filter mode setting */ -+ UINT8 coex_wmt_filter_mode; -+ -+ UINT8 coex_bt_rssi_upper_limit; -+ UINT8 coex_bt_rssi_mid_limit; -+ UINT8 coex_bt_rssi_lower_limit; -+ UINT8 coex_bt_pwr_high; -+ UINT8 coex_bt_pwr_mid; -+ UINT8 coex_bt_pwr_low; -+ -+ UINT8 coex_wifi_rssi_upper_limit; -+ UINT8 coex_wifi_rssi_mid_limit; -+ UINT8 coex_wifi_rssi_lower_limit; -+ UINT8 coex_wifi_pwr_high; -+ UINT8 coex_wifi_pwr_mid; -+ UINT8 coex_wifi_pwr_low; -+ -+ UINT8 coex_ext_pta_hi_tx_tag; -+ UINT8 coex_ext_pta_hi_rx_tag; -+ UINT8 coex_ext_pta_lo_tx_tag; -+ UINT8 coex_ext_pta_lo_rx_tag; -+ UINT16 coex_ext_pta_sample_t1; -+ UINT16 coex_ext_pta_sample_t2; -+ UINT8 coex_ext_pta_wifi_bt_con_trx; -+ -+ UINT32 coex_misc_ext_pta_on; -+ UINT32 coex_misc_ext_feature_set; -+ /*GPS LNA setting */ -+ UINT8 wmt_gps_lna_pin; -+ UINT8 wmt_gps_lna_enable; -+ /*Power on sequence */ -+ UINT8 pwr_on_rtc_slot; -+ UINT8 pwr_on_ldo_slot; -+ UINT8 pwr_on_rst_slot; -+ UINT8 pwr_on_off_slot; -+ UINT8 pwr_on_on_slot; -+ UINT8 co_clock_flag; -+ -+ /* Combo chip side SDIO driving setting */ -+ UINT32 sdio_driving_cfg; -+ -+} WMT_GEN_CONF, *P_WMT_GEN_CONF; -+ -+typedef enum _ENUM_DRV_STS_ { -+#if 0 -+ DRV_STS_INVALID = 0, -+ DRV_STS_UNREG = 1, /* Initial State */ -+#endif -+ DRV_STS_POWER_OFF = 0, /* initial state */ -+ DRV_STS_POWER_ON = 1, /* powered on, only WMT */ -+ DRV_STS_FUNC_ON = 2, /* FUNC ON */ -+ DRV_STS_MAX -+} ENUM_DRV_STS, *P_ENUM_DRV_STS; -+ -+typedef enum _WMT_IC_PIN_ID_ { -+ WMT_IC_PIN_AUDIO = 0, -+ WMT_IC_PIN_EEDI = 1, -+ WMT_IC_PIN_EEDO = 2, -+ WMT_IC_PIN_GSYNC = 3, -+ WMT_IC_PIN_MAX -+} WMT_IC_PIN_ID, *P_WMT_IC_PIN_ID; -+ -+typedef enum _WMT_IC_PIN_STATE_ { -+ WMT_IC_PIN_EN = 0, -+ WMT_IC_PIN_DIS = 1, -+ WMT_IC_AIF_0 = 2, /* = CMB_STUB_AIF_0, */ -+ WMT_IC_AIF_1 = 3, /* = CMB_STUB_AIF_1, */ -+ WMT_IC_AIF_2 = 4, /* = CMB_STUB_AIF_2, */ -+ WMT_IC_AIF_3 = 5, /* = CMB_STUB_AIF_3, */ -+ WMT_IC_PIN_MUX = 6, -+ WMT_IC_PIN_GPIO = 7, -+ WMT_IC_PIN_GPIO_HIGH = 8, -+ WMT_IC_PIN_GPIO_LOW = 9, -+ WMT_IC_PIN_STATE_MAX -+} WMT_IC_PIN_STATE, *P_WMT_IC_PIN_STATE; -+ -+typedef enum _WMT_CO_CLOCK_ { -+ WMT_CO_CLOCK_DIS = 0, -+ WMT_CO_CLOCK_EN = 1, -+ WMT_CO_CLOCK_MAX -+} WMT_CO_CLOCK, *P_WMT_CO_CLOCK; -+ -+typedef INT32(*SW_INIT) (P_WMT_HIF_CONF pWmtHifConf); -+typedef INT32(*SW_DEINIT) (P_WMT_HIF_CONF pWmtHifConf); -+typedef INT32(*IC_PIN_CTRL) (WMT_IC_PIN_ID id, WMT_IC_PIN_STATE state, UINT32 flag); -+typedef INT32(*IC_VER_CHECK) (VOID); -+typedef INT32(*CO_CLOCK_CTRL) (WMT_CO_CLOCK on); -+typedef MTK_WCN_BOOL(*IS_QUICK_SLEEP_SUPPORT) (VOID); -+typedef MTK_WCN_BOOL(*IS_AEE_DUMP_SUPPORT) (VOID); -+ -+typedef struct _WMT_IC_OPS_ { -+ UINT32 icId; -+ SW_INIT sw_init; -+ SW_DEINIT sw_deinit; -+ IC_PIN_CTRL ic_pin_ctrl; -+ IC_VER_CHECK ic_ver_check; -+ CO_CLOCK_CTRL co_clock_ctrl; -+ IS_QUICK_SLEEP_SUPPORT is_quick_sleep; -+ IS_AEE_DUMP_SUPPORT is_aee_dump_support; -+} WMT_IC_OPS, *P_WMT_IC_OPS; -+ -+typedef struct _WMT_CTX_ { -+ ENUM_DRV_STS eDrvStatus[WMTDRV_TYPE_MAX]; /* Controlled driver status */ -+ UINT32 wmtInfoBit; /* valid info bit */ -+ WMT_HIF_CONF wmtHifConf; /* HIF information */ -+ -+ /* Pointer to WMT_IC_OPS. Shall be assigned to a correct table in stp_init -+ * if and only if getting chip id successfully. hwver and fwver are kept in -+ * WMT-IC module only. -+ */ -+ P_WMT_IC_OPS p_ic_ops; -+} WMT_CTX, *P_WMT_CTX; -+ -+/* TODO:[ChangeFeature][George] remove WMT_PKT. replace it with hardcoded arrays. */ -+/* Using this struct relies on compiler's implementation and pack() settings */ -+typedef struct _WMT_PKT_ { -+ UINT8 eType; /* PKT_TYPE_* */ -+ UINT8 eOpCode; /* OPCODE_* */ -+ UINT16 u2SduLen; /* 2 bytes length, little endian */ -+ UINT8 aucParam[32]; -+} WMT_PKT, *P_WMT_PKT; -+ -+/* WMT Packet Format */ -+typedef enum _ENUM_PKT_TYPE { -+ PKT_TYPE_INVALID = 0, -+ PKT_TYPE_CMD = 1, -+ PKT_TYPE_EVENT = 2, -+ _PKT_TYPE_MAX -+} ENUM_PKT_TYPE, *P_ENUM_PKT_TYPE; -+ -+typedef enum _ENUM_OPCODE { -+ OPCODE_INVALID = 0, -+ OPCODE_PATCH = 1, -+ OPCODE_TEST = 2, -+ OPCODE_WAKEUP = 3, -+ OPCODE_HIF = 4, -+ OPCODE_STRAP_CONF = 5, -+ OPCODE_FUNC_CTRL = 6, -+ OPCODE_RESET = 7, -+ OPCODE_INT = 8, -+ OPCODE_MAX -+} ENUM_OPCODE, *P_ENUM_OPCODE; -+ -+typedef enum { -+ WMT_STP_CONF_EN = 0, -+ WMT_STP_CONF_RDY = 1, -+ WMT_STP_CONF_MODE = 2, -+ WMT_STP_CONF_MAX -+} WMT_STP_CONF_TYPE; -+ -+struct init_script { -+ UINT8 *cmd; -+ UINT32 cmdSz; -+ UINT8 *evt; -+ UINT32 evtSz; -+ UINT8 *str; -+}; -+ -+typedef struct _WMT_PATCH { -+ UINT8 ucDateTime[16]; -+ UINT8 ucPLat[4]; -+ UINT16 u2HwVer; -+ UINT16 u2SwVer; -+ UINT32 u4PatchVer; -+} WMT_PATCH, *P_WMT_PATCH; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+#if CFG_CORE_MT6620_SUPPORT -+extern WMT_IC_OPS wmt_ic_ops_mt6620; -+#endif -+ -+#if CFG_CORE_MT6628_SUPPORT -+extern WMT_IC_OPS wmt_ic_ops_mt6628; -+#endif -+ -+#if CFG_CORE_SOC_SUPPORT -+extern WMT_IC_OPS wmt_ic_ops_soc; -+#endif -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+extern INT32 wmt_core_init(VOID); -+extern INT32 wmt_core_deinit(VOID); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_wmtd -+* DESCRIPTION -+* deinit STP kernel -+* PARAMETERS -+* void -+* RETURNS -+* INT32 0 = success, others = failure -+*****************************************************************************/ -+extern INT32 wmt_core_opid(P_WMT_OP pWmtOp); -+ -+extern INT32 wmt_core_ctrl(ENUM_WMT_CTRL_T ctrId, unsigned long *pPa1, unsigned long *pPa2); -+ -+extern INT32 wmt_core_func_ctrl_cmd(ENUM_WMTDRV_TYPE_T type, MTK_WCN_BOOL fgEn); -+ -+extern INT32 wmt_core_reg_rw_raw(UINT32 isWrite, UINT32 offset, PUINT32 pVal, UINT32 mask); -+ -+extern VOID wmt_core_dump_data(PUINT8 pData, PUINT8 pTitle, UINT32 len); -+ -+extern MTK_WCN_BOOL wmt_core_patch_check(UINT32 u4PatchVer, UINT32 u4HwVer); -+ -+extern INT32 wmt_core_init_script(struct init_script *script, INT32 count); -+ -+extern INT32 wmt_core_rx(PUINT8 pBuf, UINT32 bufLen, UINT32 *readSize); -+ -+extern INT32 wmt_core_tx(const PUINT8 pData, UINT32 size, PUINT32 writtenSize, MTK_WCN_BOOL bRawFlag); -+extern MTK_WCN_BOOL wmt_core_is_quick_ps_support(void); -+ -+extern MTK_WCN_BOOL wmt_core_get_aee_dump_flag(void); -+ -+#if CFG_CORE_INTERNAL_TXRX -+extern INT32 wmt_core_lpbk_do_stp_init(void); -+extern INT32 wmt_core_lpbk_do_stp_deinit(void); -+#endif -+ -+extern VOID wmt_core_set_coredump_state(ENUM_DRV_STS state); -+#if CFG_WMT_LTE_COEX_HANDLING -+extern VOID wmt_core_set_flag_for_test(UINT32 enable); -+extern UINT32 wmt_core_get_flag_for_test(VOID); -+#endif -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+static _osal_inline_ MTK_WCN_BOOL wmt_core_ic_ops_check(P_WMT_IC_OPS p_ops) -+{ -+ if (!p_ops) -+ return MTK_WCN_BOOL_FALSE; -+ -+ if ((NULL == p_ops->sw_init) -+ || (NULL == p_ops->sw_deinit) -+ || (NULL == p_ops->ic_ver_check) -+ || (NULL == p_ops->ic_pin_ctrl)) -+ return MTK_WCN_BOOL_FALSE; -+ else -+ return MTK_WCN_BOOL_TRUE; -+} -+ -+#endif /* _WMT_CORE_H_ */ -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_ctrl.h b/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_ctrl.h -new file mode 100644 -index 000000000000..0ff3d6058c39 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_ctrl.h -@@ -0,0 +1,120 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -+ -+/*! \file -+ \brief Declaration of library functions -+ -+ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. -+*/ -+ -+#ifndef _WMT_CTRL_H_ -+#define _WMT_CTRL_H_ -+ -+#include "osal.h" -+#include "wmt_stp_exp.h" -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+#define DWCNT_CTRL_DATA (16) -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+typedef struct _WMT_CTRL_DATA_ { -+ SIZE_T ctrlId; -+ SIZE_T au4CtrlData[DWCNT_CTRL_DATA]; -+} WMT_CTRL_DATA, *P_WMT_CTRL_DATA; -+ -+typedef enum _ENUM_WMT_CTRL_T { -+ WMT_CTRL_HW_PWR_OFF = 0, /* whole chip power off */ -+ WMT_CTRL_HW_PWR_ON = 1, /* whole chip power on */ -+ WMT_CTRL_HW_RST = 2, /* whole chip rst */ -+ WMT_CTRL_STP_CLOSE = 3, -+ WMT_CTRL_STP_OPEN = 4, -+ WMT_CTRL_STP_CONF = 5, -+ WMT_CTRL_FREE_PATCH = 6, -+ WMT_CTRL_GET_PATCH = 7, -+ WMT_CTRL_GET_PATCH_NAME = 8, -+ WMT_CTRL_HWIDVER_SET = 9, /* TODO: rename this and add chip id information in addition to chip version */ -+ WMT_CTRL_STP_RST = 10, -+ WMT_CTRL_GET_WMT_CONF = 11, -+ WMT_CTRL_TX = 12, /* [FixMe][GeorgeKuo]: to be removed by Sean's stp integration */ -+ WMT_CTRL_RX = 13, /* [FixMe][GeorgeKuo]: to be removed by Sean's stp integration */ -+ WMT_CTRL_RX_FLUSH = 14, /* [FixMe][SeanWang]: to be removed by Sean's stp integration */ -+ WMT_CTRL_GPS_SYNC_SET = 15, -+ WMT_CTRL_GPS_LNA_SET = 16, -+ WMT_CTRL_PATCH_SEARCH = 17, -+ WMT_CTRL_CRYSTAL_TRIMING_GET = 18, -+ WMT_CTRL_CRYSTAL_TRIMING_PUT = 19, -+ WMT_CTRL_HW_STATE_DUMP = 20, -+ WMT_CTRL_GET_PATCH_NUM = 21, -+ WMT_CTRL_GET_PATCH_INFO = 22, -+ WMT_CTRL_SOC_PALDO_CTRL = 23, -+ WMT_CTRL_SOC_WAKEUP_CONSYS = 24, -+ WMT_CTRL_SET_STP_DBG_INFO = 25, -+ WMT_CTRL_BGW_DESENSE_CTRL = 26, -+ WMT_CTRL_EVT_ERR_TRG_ASSERT = 27, -+#if CFG_WMT_LTE_COEX_HANDLING -+ WMT_CTRL_GET_TDM_REQ_ANTSEL = 28, -+#endif -+ WMT_CTRL_EVT_PARSER = 29, -+ WMT_CTRL_MAX -+} ENUM_WMT_CTRL_T, *P_ENUM_WMT_CTRL_T; -+ -+typedef INT32(*WMT_CTRL_FUNC) (P_WMT_CTRL_DATA); -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+extern INT32 wmt_ctrl(P_WMT_CTRL_DATA pWmtCtrlData); -+ -+extern INT32 wmt_ctrl_tx_ex(const PUINT8 pData, const UINT32 size, PUINT32 writtenSize, const MTK_WCN_BOOL bRawFlag); -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif /* _WMT_CTRL_H_ */ -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_func.h b/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_func.h -new file mode 100644 -index 000000000000..d586f442e7ef ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_func.h -@@ -0,0 +1,140 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -+ -+/*! \file -+ \brief Declaration of library functions -+ -+ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. -+*/ -+ -+#ifndef _WMT_FUNC_H_ -+#define _WMT_FUNC_H_ -+ -+#include "osal_typedef.h" -+#include "osal.h" -+#include "wmt_core.h" -+#include "wmt_plat.h" -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+#if 1 /* defined(CONFIG_MTK_COMBO_HCI_DRIVER) || defined(CONFIG_MTK_COMBO_BT) */ -+#define CFG_FUNC_BT_SUPPORT 1 -+#else -+#define CFG_FUNC_BT_SUPPORT 0 -+#endif -+ -+#if 1 /* defined(CONFIG_MTK_COMBO_FM) */ -+#define CFG_FUNC_FM_SUPPORT 1 -+#else -+#define CFG_FUNC_FM_SUPPORT 0 -+#endif -+ -+#if 1 /* defined(CONFIG_MTK_COMBO_GPS) */ -+#define CFG_FUNC_GPS_SUPPORT 1 -+#else -+#define CFG_FUNC_GPS_SUPPORT 0 -+#endif -+ -+#if 1 /* defined(CONFIG_MTK_COMBO_WIFI) */ -+#define CFG_FUNC_WIFI_SUPPORT 1 -+#else -+#define CFG_FUNC_WIFI_SUPPORT 0 -+#endif -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+typedef INT32(*SUBSYS_FUNC_ON) (P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf); -+typedef INT32(*SUBSYS_FUNC_OFF) (P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf); -+ -+typedef struct _WMT_FUNC_OPS_ { -+ SUBSYS_FUNC_ON func_on; -+ SUBSYS_FUNC_OFF func_off; -+} WMT_FUNC_OPS, *P_WMT_FUNC_OPS; -+ -+typedef struct _CMB_PIN_CTRL_REG_ { -+ UINT32 regAddr; -+ UINT32 regValue; -+ UINT32 regMask; -+ -+} CMB_PIN_CTRL_REG, *P_CMB_PIN_CTRL_REG; -+ -+typedef struct _CMB_PIN_CTRL_ { -+ UINT32 pinId; -+ UINT32 regNum; -+ P_CMB_PIN_CTRL_REG pFuncOnArray; -+ P_CMB_PIN_CTRL_REG pFuncOffArray; -+ -+} CMB_PIN_CTRL, *P_CMB_PIN_CTRL; -+ -+typedef enum _ENUM_CMP_PIN_ID_ { -+ CMB_PIN_EEDI_ID = 0, -+ CMB_PIN_EEDO_ID = 1, -+ CMB_PIN_GSYNC_ID = 2, -+} ENUM_CMP_PIN_ID, *P_ENUM_CMP_PIN_ID; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+#if CFG_FUNC_BT_SUPPORT -+extern WMT_FUNC_OPS wmt_func_bt_ops; -+#endif -+ -+#if CFG_FUNC_FM_SUPPORT -+extern WMT_FUNC_OPS wmt_func_fm_ops; -+#endif -+ -+#if CFG_FUNC_GPS_SUPPORT -+extern WMT_FUNC_OPS wmt_func_gps_ops; -+#endif -+ -+#if CFG_FUNC_WIFI_SUPPORT -+extern WMT_FUNC_OPS wmt_func_wifi_ops; -+#endif -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif /* _WMT_FUNC_H_ */ -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_ic.h b/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_ic.h -new file mode 100644 -index 000000000000..901becfdb92f ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_ic.h -@@ -0,0 +1,122 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -+ -+/*! \file -+ \brief Declaration of library functions -+ -+ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. -+*/ -+ -+#ifndef _WMT_IC_H_ -+#define _WMT_IC_H_ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+#include "wmt_core.h" -+#include "wmt_exp.h" -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+#define WMT_IC_NAME_MT6620 "MT6620" -+#define WMT_IC_NAME_MT6628 "MT6628" -+#define WMT_IC_NAME_DEFAULT "SOC_CONSYS" -+ -+#define WMT_IC_VER_E1 "E1" -+#define WMT_IC_VER_E2 "E2" -+#define WMT_IC_VER_E3 "E3" -+#define WMT_IC_VER_E4 "E4" -+#define WMT_IC_VER_E5 "E5" -+#define WMT_IC_VER_E6 "E6" -+ -+#define WMT_IC_PATCH_DUMMY_EXT "_ex" -+#define WMT_IC_PATCH_NO_EXT "" -+#define WMT_IC_PATCH_E1_EXT "_e1" -+#define WMT_IC_PATCH_E2_EXT "_e2" -+#define WMT_IC_PATCH_E3_EXT "_e3" -+#define WMT_IC_PATCH_E4_EXT "_e4" -+#define WMT_IC_PATCH_E5_EXT "_e5" -+#define WMT_IC_PATCH_E6_EXT "_e6" -+ -+#define WMT_IC_PATCH_TAIL "_hdr.bin" -+ -+#define WMT_IC_INVALID_CHIP_ID 0xFFFF -+ -+#define MAJORNUM(x) (x & 0x00F0) -+#define MINORNUM(x) (x & 0x000F) -+ -+/******************************************************************************* -+* R E G I S T E R M A P -+******************************************************************************** -+*/ -+/* General definition used for ALL/UNKNOWN CHIPS */ -+/* Now MT6620 uses these definitions */ -+#define GEN_CONFG_BASE (0x80000000UL) -+#define GEN_HVR (GEN_CONFG_BASE + 0x0UL) /* HW_VER */ -+#define GEN_FVR (GEN_CONFG_BASE + 0x4UL) /* FW_VER */ -+#define GEN_VER_MASK (0x0000FFFFUL) /* HW_VER and FW_VER valid bits mask */ -+#define GEN_HCR (GEN_CONFG_BASE + 0x8UL) /* HW_CODE, chip id */ -+#define GEN_HCR_MASK (0x0000FFFFUL) /* HW_CODE valid bits mask */ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+typedef struct _WMT_IC_INFO_S { -+ UINT32 u4HwVer; /* u4HwId */ -+ PUINT8 cChipName; -+ PUINT8 cChipVersion; -+ PUINT8 cPatchNameExt; -+ MTK_WCN_BOOL bPsmSupport; -+ MTK_WCN_BOOL bWorkWithoutPatch; -+ ENUM_WMTHWVER_TYPE_T eWmtHwVer; -+} WMT_IC_INFO_S, *P_WMT_IC_INFO_S; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif /* _WMT_IC_H_ */ -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_lib.h b/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_lib.h -new file mode 100644 -index 000000000000..b0c05cf3a252 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/core/include/wmt_lib.h -@@ -0,0 +1,300 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -+ -+/*! \file -+ \brief Declaration of library functions -+ -+ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. -+*/ -+ -+#ifndef _WMT_LIB_H_ -+#define _WMT_LIB_H_ -+ -+#include "osal.h" -+#include "wmt_core.h" -+#include "wmt_exp.h" -+#include -+#include "stp_wmt.h" -+#include "wmt_plat.h" -+#include "wmt_idc.h" -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+#define WMT_OP_BUF_SIZE (16) -+ -+typedef enum _ENUM_WMTRSTRET_TYPE_T { -+ WMTRSTRET_SUCCESS = 0x0, -+ WMTRSTRET_FAIL = 0x1, -+ WMTRSTRET_ONGOING = 0x2, -+ WMTRSTRET_MAX -+} ENUM_WMTRSTRET_TYPE_T, *P_ENUM_WMTRSTRET_TYPE_T; -+ -+/* -+3(retry times) * 180 (STP retry time out) -++ 10 (firmware process time) + -+10 (transmit time) + -+10 (uart process -> WMT response pool) + -+230 (others) -+*/ -+#define WMT_LIB_RX_TIMEOUT 20000 /*800-->cover v1.2phone BT function on time (~830ms) */ -+/* -+open wifi during wifi power on procedure -+(because wlan is insert to system after mtk_hif_sdio module, -+so wifi card is not registered to hif module -+when mtk_wcn_wmt_func_on is called by wifi through rfkill) -+*/ -+#define MAX_WIFI_ON_TIME 55000 -+ -+#define WMT_PWRON_RTY_DFT 2 -+#define MAX_RETRY_TIME_DUE_TO_RX_TIMEOUT (WMT_PWRON_RTY_DFT * WMT_LIB_RX_TIMEOUT) -+#define MAX_EACH_FUNC_ON_WHEN_CHIP_POWER_ON_ALREADY WMT_LIB_RX_TIMEOUT /*each WMT command */ -+#define MAX_FUNC_ON_TIME \ -+ (MAX_WIFI_ON_TIME + MAX_RETRY_TIME_DUE_TO_RX_TIMEOUT + MAX_EACH_FUNC_ON_WHEN_CHIP_POWER_ON_ALREADY * 3) -+ -+#define MAX_EACH_FUNC_OFF (WMT_LIB_RX_TIMEOUT + 1000) /*1000->WMT_LIB_RX_TIMEOUT + 1000, logical judgement */ -+#define MAX_FUNC_OFF_TIME (MAX_EACH_FUNC_OFF * 4) -+ -+#define MAX_EACH_WMT_CMD (WMT_LIB_RX_TIMEOUT + 1000) /*1000->WMT_LIB_RX_TIMEOUT + 1000, logical judgement */ -+ -+#define MAX_GPIO_CTRL_TIME (2000) /* [FixMe][GeorgeKuo] a temp value */ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/* AIF FLAG definition */ -+/* bit(0): share pin or not */ -+#define WMT_LIB_AIF_FLAG_MASK (0x1UL) -+#define WMT_LIB_AIF_FLAG_SHARE (0x1UL << 0) -+#define WMT_LIB_AIF_FLAG_SEPARATE (0x0UL << 0) -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/* bit field offset definition */ -+typedef enum { -+ WMT_STAT_PWR = 0, /* is powered on */ -+ WMT_STAT_STP_REG = 1, /* is STP driver registered: */ -+ WMT_STAT_STP_OPEN = 2, /* is STP opened: default FALSE */ -+ WMT_STAT_STP_EN = 3, /* is STP enabled: default FALSE */ -+ WMT_STAT_STP_RDY = 4, /* is STP ready for client: default FALSE */ -+ WMT_STAT_RX = 5, /* is rx data available */ -+ WMT_STAT_CMD = 6, /* is cmd string to be read */ -+ WMT_STAT_RST_ON = 7, -+ WMT_STAT_MAX -+} WMT_STAT; -+ -+typedef enum _ENUM_WMTRSTSRC_TYPE_T { -+ WMTRSTSRC_RESET_BT = 0x0, -+ WMTRSTSRC_RESET_FM = 0x1, -+ WMTRSTSRC_RESET_GPS = 0x2, -+ WMTRSTSRC_RESET_WIFI = 0x3, -+ WMTRSTSRC_RESET_STP = 0x4, -+ WMTRSTSRC_RESET_TEST = 0x5, -+ WMTRSTSRC_RESET_MAX -+} ENUM_WMTRSTSRC_TYPE_T, *P_ENUM_WMTRSTSRC_TYPE_T; -+ -+typedef struct { -+ PF_WMT_CB fDrvRst[4]; -+} WMT_FDRV_CB, *P_WMT_FDRV_CB; -+ -+typedef struct { -+ UINT32 dowloadSeq; -+ UINT8 addRess[4]; -+ UINT8 patchName[256]; -+} WMT_PATCH_INFO, *P_WMT_PATCH_INFO; -+ -+/* OS independent wrapper for WMT_OP */ -+typedef struct _DEV_WMT_ { -+ -+ OSAL_SLEEPABLE_LOCK psm_lock; -+ OSAL_SLEEPABLE_LOCK idc_lock; -+ /* WMTd thread information */ -+ /* struct task_struct *pWmtd; */ -+ OSAL_THREAD thread; /* main thread (wmtd) handle */ -+ /* wait_queue_head_t rWmtdWq; */ -+ OSAL_EVENT rWmtdWq; /*WMTd command wait queue */ -+ /* ULONG state; */ -+ OSAL_BIT_OP_VAR state; /* bit field of WMT_STAT */ -+ -+ /* STP context information */ -+ /* wait_queue_head_t rWmtRxWq; */ -+ OSAL_EVENT rWmtRxWq; /* STP Rx wait queue */ -+ /* WMT_STP_FUNC rStpFunc; */ -+ WMT_FDRV_CB rFdrvCb; /* STP functions */ -+ -+ /* WMT Configurations */ -+ WMT_HIF_CONF rWmtHifConf; -+ WMT_GEN_CONF rWmtGenConf; -+ -+ /* Patch information */ -+ UINT8 cPatchName[NAME_MAX + 1]; -+ UINT8 cFullPatchName[NAME_MAX + 1]; -+ UINT32 patchNum; -+ -+ const osal_firmware *pPatch; -+ -+ UINT8 cWmtcfgName[NAME_MAX + 1]; -+ const osal_firmware *pWmtCfg; -+ -+ const osal_firmware *pNvram; -+ -+ /* Current used UART port description */ -+ INT8 cUartName[NAME_MAX + 1]; -+ -+ OSAL_OP_Q rFreeOpQ; /* free op queue */ -+ OSAL_OP_Q rActiveOpQ; /* active op queue */ -+ OSAL_OP arQue[WMT_OP_BUF_SIZE]; /* real op instances */ -+ P_OSAL_OP pCurOP; /* current op */ -+ -+ /* cmd str buffer */ -+ UINT8 cCmd[NAME_MAX + 1]; -+ INT32 cmdResult; -+ /* struct completion cmd_comp; */ -+ /* wait_queue_head_t cmd_wq; */ -+ OSAL_SIGNAL cmdResp; /* read command queues */ -+ OSAL_EVENT cmdReq; -+ -+ /* WMT loopback Thread Information */ -+ /* WMT_CMB_VER combo_ver; */ -+ /* P_WMT_CMB_CHIP_INFO_S pChipInfo; */ -+ UINT32 chip_id; -+ UINT32 hw_ver; -+ UINT32 fw_ver; -+ /* TODO: [FixMe][GeorgeKuo] remove this translated version code in the */ -+ /* future. Just return the above 3 info to querist */ -+ ENUM_WMTHWVER_TYPE_T eWmtHwVer; -+ -+ P_WMT_PATCH_INFO pWmtPatchInfo; -+} DEV_WMT, *P_DEV_WMT; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+extern DEV_WMT gDevWmt; -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+extern INT32 wmt_lib_init(VOID); -+extern INT32 wmt_lib_deinit(VOID); -+extern INT32 wmt_lib_tx(PUINT8 data, UINT32 size, PUINT32 writtenSize); -+extern INT32 wmt_lib_tx_raw(PUINT8 data, UINT32 size, PUINT32 writtenSize); -+extern INT32 wmt_lib_rx(PUINT8 buff, UINT32 buffLen, PUINT32 readSize); -+extern VOID wmt_lib_flush_rx(VOID); -+ -+#if CFG_WMT_PS_SUPPORT -+extern INT32 wmt_lib_ps_set_idle_time(UINT32 psIdleTime); -+extern INT32 wmt_lib_ps_init(VOID); -+extern INT32 wmt_lib_ps_deinit(VOID); -+extern INT32 wmt_lib_ps_enable(VOID); -+extern INT32 wmt_lib_ps_ctrl(UINT32 state); -+ -+extern INT32 wmt_lib_ps_disable(VOID); -+extern VOID wmt_lib_ps_irq_cb(VOID); -+#endif -+extern VOID wmt_lib_ps_set_sdio_psop(PF_WMT_SDIO_PSOP own_cb); -+ -+/* LXOP functions: */ -+extern P_OSAL_OP wmt_lib_get_free_op(VOID); -+extern INT32 wmt_lib_put_op_to_free_queue(P_OSAL_OP pOp); -+extern MTK_WCN_BOOL wmt_lib_put_act_op(P_OSAL_OP pOp); -+ -+/* extern ENUM_WMTHWVER_TYPE_T wmt_lib_get_hwver (VOID); */ -+extern UINT32 wmt_lib_get_icinfo(ENUM_WMT_CHIPINFO_TYPE_T type); -+ -+extern MTK_WCN_BOOL wmt_lib_is_therm_ctrl_support(VOID); -+extern MTK_WCN_BOOL wmt_lib_is_dsns_ctrl_support(VOID); -+extern INT32 wmt_lib_trigger_cmd_signal(INT32 result); -+extern PUINT8 wmt_lib_get_cmd(VOID); -+extern P_OSAL_EVENT wmt_lib_get_cmd_event(VOID); -+extern INT32 wmt_lib_set_patch_name(PUINT8 cPatchName); -+extern INT32 wmt_lib_set_hif(unsigned long hifconf); -+extern P_WMT_HIF_CONF wmt_lib_get_hif(VOID); -+extern MTK_WCN_BOOL wmt_lib_get_cmd_status(VOID); -+ -+/* GeorgeKuo: replace set_chip_gpio() with more specific ones */ -+#if 0 /* moved to wmt_exp.h */ -+extern INT32 wmt_lib_set_aif(CMB_STUB_AIF_X aif, MTK_WCN_BOOL share); /* set AUDIO interface options */ -+#endif -+extern INT32 wmt_lib_host_awake_get(VOID); -+extern INT32 wmt_lib_host_awake_put(VOID); -+extern UINT32 wmt_lib_dbg_level_set(UINT32 level); -+ -+extern INT32 wmt_lib_msgcb_reg(ENUM_WMTDRV_TYPE_T eType, PF_WMT_CB pCb); -+ -+extern INT32 wmt_lib_msgcb_unreg(ENUM_WMTDRV_TYPE_T eType); -+ENUM_WMTRSTRET_TYPE_T wmt_lib_cmb_rst(ENUM_WMTRSTSRC_TYPE_T src); -+MTK_WCN_BOOL wmt_lib_sw_rst(INT32 baudRst); -+MTK_WCN_BOOL wmt_lib_hw_rst(VOID); -+INT32 wmt_lib_reg_rw(UINT32 isWrite, UINT32 offset, PUINT32 pvalue, UINT32 mask); -+INT32 wmt_lib_efuse_rw(UINT32 isWrite, UINT32 offset, PUINT32 pvalue, UINT32 mask); -+ -+extern INT32 DISABLE_PSM_MONITOR(void); -+extern VOID ENABLE_PSM_MONITOR(void); -+extern INT32 wmt_lib_notify_stp_sleep(void); -+extern void wmt_lib_psm_lock_release(void); -+extern INT32 wmt_lib_psm_lock_aquire(void); -+extern VOID wmt_lib_idc_lock_release(VOID); -+extern INT32 wmt_lib_idc_lock_aquire(VOID); -+extern INT32 wmt_lib_set_stp_wmt_last_close(UINT32 value); -+ -+extern VOID wmt_lib_set_patch_num(UINT32 num); -+extern VOID wmt_lib_set_patch_info(P_WMT_PATCH_INFO pPatchinfo); -+extern INT32 wmt_lib_set_current_op(P_DEV_WMT pWmtDev, P_OSAL_OP pOp); -+extern P_OSAL_OP wmt_lib_get_current_op(P_DEV_WMT pWmtDev); -+extern PUINT8 wmt_lib_get_fwinfor_from_emi(UINT8 section, UINT32 offset, PUINT8 buff, UINT32 len); -+extern INT32 wmt_lib_poll_cpupcr(UINT32 count, UINT16 sleep, UINT16 toAee); -+extern PUINT8 wmt_lib_get_cpupcr_xml_format(PUINT32 len); -+extern INT32 wmt_lib_register_thermal_ctrl_cb(thermal_query_ctrl_cb thermal_ctrl); -+extern UINT32 wmt_lib_set_host_assert_info(UINT32 type, UINT32 reason, UINT32 en); -+extern INT8 wmt_lib_co_clock_get(VOID); -+extern UINT32 wmt_lib_soc_set_wifiver(UINT32 wifiver); -+ -+#if CFG_WMT_LTE_COEX_HANDLING -+extern MTK_WCN_BOOL wmt_lib_handle_idc_msg(ipc_ilm_t *idc_infor); -+#endif -+#if CFG_WMT_PS_SUPPORT -+extern UINT32 wmt_lib_quick_sleep_ctrl(UINT32 en); -+#endif -+#if CONSYS_ENALBE_SET_JTAG -+extern UINT32 wmt_lib_jtag_flag_set(UINT32 en); -+#endif -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif /* _WMT_LIB_H_ */ -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/core/psm_core.c b/drivers/misc/mediatek/connectivity/common/conn_soc/core/psm_core.c -new file mode 100644 -index 000000000000..c826c513e2bd ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/core/psm_core.c -@@ -0,0 +1,1890 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -+#include "osal_typedef.h" -+#include "osal.h" -+#include "psm_core.h" -+#include "stp_core.h" -+#include -+ -+INT32 gPsmDbgLevel = STP_PSM_LOG_INFO; -+MTKSTP_PSM_T stp_psm_i; -+MTKSTP_PSM_T *stp_psm = &stp_psm_i; -+ -+STP_PSM_RECORD_T *g_stp_psm_dbg = NULL; -+static UINT32 g_record_num; -+ -+P_STP_PSM_OPID_RECORD g_stp_psm_opid_dbg = NULL; -+static UINT32 g_opid_record_num; -+ -+#define STP_PSM_LOUD_FUNC(fmt, arg...) \ -+do { \ -+ if (gPsmDbgLevel >= STP_PSM_LOG_LOUD) \ -+ pr_debug(PFX_PSM "%s: " fmt, __func__ , ##arg); \ -+} while (0) -+#define STP_PSM_DBG_FUNC(fmt, arg...) \ -+do { \ -+ if (gPsmDbgLevel >= STP_PSM_LOG_DBG) \ -+ pr_debug(PFX_PSM "%s: " fmt, __func__ , ##arg); \ -+} while (0) -+#define STP_PSM_INFO_FUNC(fmt, arg...) \ -+do { \ -+ if (gPsmDbgLevel >= STP_PSM_LOG_INFO) \ -+ pr_debug(PFX_PSM "[I]%s: " fmt, __func__ , ##arg); \ -+} while (0) -+#define STP_PSM_WARN_FUNC(fmt, arg...) \ -+do { \ -+ if (gPsmDbgLevel >= STP_PSM_LOG_WARN) \ -+ pr_warn(PFX_PSM "[W]%s: " fmt, __func__ , ##arg); \ -+} while (0) -+#define STP_PSM_ERR_FUNC(fmt, arg...) \ -+do { \ -+ if (gPsmDbgLevel >= STP_PSM_LOG_ERR) \ -+ pr_err(PFX_PSM "[E]%s(%d):ERROR! " fmt, __func__ , __LINE__, ##arg); \ -+} while (0) -+#define STP_PSM_TRC_FUNC(f) \ -+do { \ -+ if (gPsmDbgLevel >= STP_PSM_LOG_DBG) \ -+ pr_debug(PFX_PSM "<%s> <%d>\n", __func__, __LINE__); \ -+} while (0) -+ -+static inline INT32 _stp_psm_notify_wmt(MTKSTP_PSM_T *stp_psm, const MTKSTP_PSM_ACTION_T action); -+static INT32 _stp_psm_thread_lock_aquire(MTKSTP_PSM_T *stp_psm); -+static INT32 _stp_psm_thread_lock_release(MTKSTP_PSM_T *stp_psm); -+static INT32 _stp_psm_dbg_dmp_in(STP_PSM_RECORD_T *stp_psm_dbg, UINT32 flag, UINT32 line_num); -+static INT32 _stp_psm_dbg_out_printk(STP_PSM_RECORD_T *stp_psm_dbg); -+ -+static INT32 _stp_psm_opid_dbg_dmp_in(P_STP_PSM_OPID_RECORD p_opid_dbg, UINT32 opid, UINT32 line_num); -+static INT32 _stp_psm_opid_dbg_out_printk(P_STP_PSM_OPID_RECORD p_opid_dbg); -+ -+static const char *g_psm_state[STP_PSM_MAX_STATE] = { -+ "ACT", -+ "ACT_INACT", -+ "INACT", -+ "INACT_ACT" -+}; -+ -+static const char *g_psm_action[STP_PSM_MAX_ACTION] = { -+ "SLEEP", -+ "HOST_AWAKE", -+ "WAKEUP", -+ "EIRQ", -+ "ROLL_BACK" -+}; -+ -+static const char *g_psm_op_name[STP_OPID_PSM_NUM] = { -+ "STP_OPID_PSM_SLEEP", -+ "STP_OPID_PSM_WAKEUP", -+ "STP_OPID_PSM_HOST_AWAKE", -+ "STP_OPID_PSM_EXIT" -+}; -+ -+static int _stp_psm_release_data(MTKSTP_PSM_T *stp_psm); -+ -+static inline int _stp_psm_get_state(MTKSTP_PSM_T *stp_psm); -+ -+static int _stp_psm_is_redundant_active_op(P_OSAL_OP pOp, P_OSAL_OP_Q pOpQ); -+ -+static int _stp_psm_clean_up_redundant_active_op(P_OSAL_OP_Q pOpQ); -+static MTK_WCN_BOOL _stp_psm_is_quick_ps_support(VOID); -+ -+MTK_WCN_BOOL mtk_wcn_stp_psm_dbg_level(UINT32 dbglevel) -+{ -+ if (dbglevel <= 4) { -+ gPsmDbgLevel = dbglevel; -+ STP_PSM_INFO_FUNC("gPsmDbgLevel = %d\n", gPsmDbgLevel); -+ return true; -+ } -+ STP_PSM_INFO_FUNC("invalid psm debug level. gPsmDbgLevel = %d\n", gPsmDbgLevel); -+ -+ return false; -+} -+ -+static INT32 _stp_psm_handler(MTKSTP_PSM_T *stp_psm, P_STP_OP pStpOp) -+{ -+ INT32 ret = -1; -+ -+ /* if (NULL == pStpOp) */ -+ /* { */ -+ /* return -1; */ -+ /* } */ -+ ret = _stp_psm_thread_lock_aquire(stp_psm); -+ if (ret) { -+ STP_PSM_ERR_FUNC("--->lock psm_thread_lock failed ret=%d\n", ret); -+ return ret; -+ } -+ -+ switch (pStpOp->opId) { -+ case STP_OPID_PSM_EXIT: -+ /* TODO: clean all up? */ -+ ret = 0; -+ break; -+ -+ case STP_OPID_PSM_SLEEP: -+ if (stp_psm_check_sleep_enable(stp_psm) > 0) -+ ret = _stp_psm_notify_wmt(stp_psm, SLEEP); -+ else -+ STP_PSM_INFO_FUNC("cancel sleep request\n"); -+ -+ break; -+ -+ case STP_OPID_PSM_WAKEUP: -+ ret = _stp_psm_notify_wmt(stp_psm, WAKEUP); -+ break; -+ -+ case STP_OPID_PSM_HOST_AWAKE: -+ ret = _stp_psm_notify_wmt(stp_psm, HOST_AWAKE); -+ break; -+ -+ default: -+ STP_PSM_ERR_FUNC("invalid operation id (%d)\n", pStpOp->opId); -+ ret = -1; -+ break; -+ } -+ _stp_psm_thread_lock_release(stp_psm); -+ return ret; -+} -+ -+static P_OSAL_OP _stp_psm_get_op(MTKSTP_PSM_T *stp_psm, P_OSAL_OP_Q pOpQ) -+{ -+ P_OSAL_OP pOp; -+ -+ if (!pOpQ) { -+ STP_PSM_WARN_FUNC("pOpQ == NULL\n"); -+ return NULL; -+ } -+ -+ osal_lock_unsleepable_lock(&(stp_psm->wq_spinlock)); -+ /* acquire lock success */ -+ RB_GET(pOpQ, pOp); -+ -+ if ((pOpQ == &stp_psm->rActiveOpQ) && (NULL != pOp)) { -+ /* stp_psm->current_active_op = pOp; */ -+ stp_psm->last_active_opId = pOp->op.opId; -+ } -+ osal_unlock_unsleepable_lock(&(stp_psm->wq_spinlock)); -+ -+ if ((pOpQ == &stp_psm->rActiveOpQ) && (NULL != pOp)) -+ STP_PSM_DBG_FUNC("last_active_opId(%d)\n", stp_psm->last_active_opId); -+ -+ if (!pOp) -+ STP_PSM_WARN_FUNC("RB_GET fail\n"); -+ -+ return pOp; -+} -+ -+static INT32 _stp_psm_dump_active_q(P_OSAL_OP_Q pOpQ) -+{ -+ UINT32 read_idx; -+ UINT32 write_idx; -+ UINT32 opId; -+ -+ if (pOpQ == &stp_psm->rActiveOpQ) { -+ read_idx = stp_psm->rActiveOpQ.read; -+ write_idx = stp_psm->rActiveOpQ.write; -+ -+ STP_PSM_DBG_FUNC("Active op list:++\n"); -+ while ((read_idx & RB_MASK(pOpQ)) != (write_idx & RB_MASK(pOpQ))) { -+ opId = pOpQ->queue[read_idx & RB_MASK(pOpQ)]->op.opId; -+ if (opId < STP_OPID_PSM_NUM) -+ STP_PSM_DBG_FUNC("%s\n", g_psm_op_name[opId]); -+ else -+ STP_PSM_WARN_FUNC("Unknown OP Id\n"); -+ -+ ++read_idx; -+ } -+ STP_PSM_DBG_FUNC("Active op list:--\n"); -+ } else { -+ STP_PSM_DBG_FUNC("%s: not active queue, dont dump\n", __func__); -+ } -+ -+ return 0; -+} -+ -+static int _stp_psm_is_redundant_active_op(P_OSAL_OP pOp, P_OSAL_OP_Q pOpQ) -+{ -+ unsigned int opId = 0; -+ unsigned int prev_opId = 0; -+ -+ /* if((pOpQ == &stp_psm->rActiveOpQ) && (NULL != stp_psm->current_active_op)) */ -+ if ((pOpQ == &stp_psm->rActiveOpQ) && (STP_OPID_PSM_INALID != stp_psm->last_active_opId)) { -+ opId = pOp->op.opId; -+ -+ if (opId == STP_OPID_PSM_SLEEP) { -+ if (RB_EMPTY(pOpQ)) { -+ /* prev_opId = stp_psm->current_active_op->op.opId; */ -+ prev_opId = stp_psm->last_active_opId; -+ } else { -+ prev_opId = pOpQ->queue[(pOpQ->write - 1) & RB_MASK(pOpQ)]->op.opId; -+ } -+ -+ if (prev_opId == STP_OPID_PSM_SLEEP) { -+ STP_PSM_DBG_FUNC("redundant sleep opId found\n"); -+ return 1; -+ } else { -+ return 0; -+ } -+ } else { -+ if (RB_EMPTY(pOpQ)) { -+ /* prev_opId = stp_psm->current_active_op->op.opId; */ -+ prev_opId = stp_psm->last_active_opId; -+ } else { -+ prev_opId = pOpQ->queue[(pOpQ->write - 1) & RB_MASK(pOpQ)]->op.opId; -+ } -+ -+ if (((opId == STP_OPID_PSM_WAKEUP) && (prev_opId == STP_OPID_PSM_WAKEUP)) || -+ ((opId == STP_OPID_PSM_HOST_AWAKE) && (prev_opId == STP_OPID_PSM_WAKEUP)) || -+ ((opId == STP_OPID_PSM_HOST_AWAKE) && (prev_opId == STP_OPID_PSM_HOST_AWAKE)) || -+ ((opId == STP_OPID_PSM_WAKEUP) && (prev_opId == STP_OPID_PSM_HOST_AWAKE)) -+ ) { -+ STP_PSM_DBG_FUNC("redundant opId found, opId(%d), preOpid(%d)\n", opId, prev_opId); -+ return 1; -+ } else { -+ return 0; -+ } -+ } -+ } else { -+ return 0; -+ } -+ -+} -+ -+static int _stp_psm_clean_up_redundant_active_op(P_OSAL_OP_Q pOpQ) -+{ -+ unsigned int prev_opId = 0; -+ unsigned int prev_prev_opId = 0; -+ -+ P_OSAL_OP pOp; -+ P_OSAL_OP_Q pFreeOpQ = &stp_psm->rFreeOpQ; -+ -+ if (pOpQ == &stp_psm->rActiveOpQ) { -+ /* sleep , wakeup | sleep, --> null | sleep (x) */ -+ /* wakeup , sleep , wakeup | sleep --> wakeup | sleep (v) */ -+ /* sleep , wakeup , sleep | wakeup --> sleep | wakeup (v) */ -+ /* xxx, sleep | sleep --> xxx, sleep (v) */ -+ /* xxx, wakeup | wakeup --> xxx, wakeup (v) */ -+ /* xxx, awake | awake --> xxx, awake (v) --> should never happen */ -+ while (RB_COUNT(pOpQ) > 2) { -+ prev_opId = pOpQ->queue[(pOpQ->write - 1) & RB_MASK(pOpQ)]->op.opId; -+ prev_prev_opId = pOpQ->queue[(pOpQ->write - 2) & RB_MASK(pOpQ)]->op.opId; -+ -+ if ((prev_opId == STP_OPID_PSM_SLEEP && prev_prev_opId == STP_OPID_PSM_WAKEUP) || -+ (prev_opId == STP_OPID_PSM_SLEEP && prev_prev_opId == STP_OPID_PSM_HOST_AWAKE) || -+ (prev_opId == STP_OPID_PSM_WAKEUP && prev_prev_opId == STP_OPID_PSM_SLEEP) || -+ (prev_opId == STP_OPID_PSM_HOST_AWAKE && prev_prev_opId == STP_OPID_PSM_SLEEP) -+ ) { -+ RB_GET(pOpQ, pOp); -+ RB_PUT(pFreeOpQ, pOp); -+ RB_GET(pOpQ, pOp); -+ RB_PUT(pFreeOpQ, pOp); -+ } else if (prev_opId == prev_prev_opId) { -+ RB_GET(pOpQ, pOp); -+ STP_PSM_DBG_FUNC("redundant opId(%d) found, remove it\n", pOp->op.opId); -+ RB_PUT(pFreeOpQ, pOp); -+ } -+ } -+ } -+ -+ return 0; -+} -+ -+static INT32 _stp_psm_put_op(MTKSTP_PSM_T *stp_psm, P_OSAL_OP_Q pOpQ, P_OSAL_OP pOp) -+{ -+ INT32 ret; -+ -+ /* if (!pOpQ || !pOp) */ -+ /* { */ -+ /* STP_PSM_WARN_FUNC("pOpQ = 0x%p, pLxOp = 0x%p\n", pOpQ, pOp); */ -+ /* return 0; */ -+ /* } */ -+ ret = 0; -+ -+ osal_lock_unsleepable_lock(&(stp_psm->wq_spinlock)); -+ /* acquire lock success */ -+ if (pOpQ == &stp_psm->rActiveOpQ) { -+ if (!_stp_psm_is_redundant_active_op(pOp, pOpQ)) { -+ /* acquire lock success */ -+ if (!RB_FULL(pOpQ)) { -+ RB_PUT(pOpQ, pOp); -+ STP_PSM_DBG_FUNC("opId(%d) enqueue\n", pOp->op.opId); -+ } else { -+ STP_PSM_INFO_FUNC("************ Active Queue Full ************\n"); -+ ret = -1; -+ } -+ -+ _stp_psm_clean_up_redundant_active_op(pOpQ); -+ } else { -+ /*redundant opId, mark ret as success */ -+ P_OSAL_OP_Q pFreeOpQ = &stp_psm->rFreeOpQ; -+ -+ if (!RB_FULL(pFreeOpQ)) -+ RB_PUT(pFreeOpQ, pOp); -+ else -+ osal_assert(!RB_FULL(pFreeOpQ)); -+ -+ ret = 0; -+ } -+ } else { -+ if (!RB_FULL(pOpQ)) -+ RB_PUT(pOpQ, pOp); -+ else -+ ret = -1; -+ -+ } -+ -+ if (pOpQ == &stp_psm->rActiveOpQ) -+ _stp_psm_dump_active_q(&stp_psm->rActiveOpQ); -+ -+ -+ osal_unlock_unsleepable_lock(&(stp_psm->wq_spinlock)); -+ STP_PSM_DBG_FUNC("stp_psm do unlock,active queue? (%s)\n", (pOpQ == &stp_psm->rActiveOpQ) ? "y" : "n"); -+ -+ if (ret) { -+ STP_PSM_WARN_FUNC("RB_FULL, RB_COUNT=%d , RB_SIZE=%d\n", RB_COUNT(pOpQ), RB_SIZE(pOpQ)); -+ return 0; -+ } else -+ return 1; -+ -+} -+ -+P_OSAL_OP _stp_psm_get_free_op(MTKSTP_PSM_T *stp_psm) -+{ -+ P_OSAL_OP pOp; -+ -+ if (stp_psm) { -+ pOp = _stp_psm_get_op(stp_psm, &stp_psm->rFreeOpQ); -+ if (pOp) -+ osal_memset(&pOp->op, 0, sizeof(pOp->op)); -+ -+ return pOp; -+ } else -+ return NULL; -+ -+} -+ -+INT32 _stp_psm_put_act_op(MTKSTP_PSM_T *stp_psm, P_OSAL_OP pOp) -+{ -+ INT32 bRet = 0; /* MTK_WCN_BOOL_FALSE; */ -+ INT32 bCleanup = 0; /* MTK_WCN_BOOL_FALSE; */ -+ INT32 wait_ret = -1; -+ P_OSAL_SIGNAL pSignal = NULL; -+ -+ do { -+ if (!stp_psm || !pOp) { -+ STP_PSM_ERR_FUNC("stp_psm = %p, pOp = %p\n", stp_psm, pOp); -+ break; -+ } -+ -+ pSignal = &pOp->signal; -+ -+ if (pSignal->timeoutValue) { -+ pOp->result = -9; -+ osal_signal_init(&pOp->signal); -+ } -+ -+ /* put to active Q */ -+ bRet = _stp_psm_put_op(stp_psm, &stp_psm->rActiveOpQ, pOp); -+ -+ if (0 == bRet) { -+ STP_PSM_WARN_FUNC("+++++++++++ Put op Active queue Fail\n"); -+ bCleanup = 1; /* MTK_WCN_BOOL_TRUE; */ -+ break; -+ } -+ _stp_psm_opid_dbg_dmp_in(g_stp_psm_opid_dbg, pOp->op.opId, __LINE__); -+ -+ /* wake up wmtd */ -+ osal_trigger_event(&stp_psm->STPd_event); -+ -+ if (pSignal->timeoutValue == 0) { -+ bRet = 1; /* MTK_WCN_BOOL_TRUE; */ -+ /* clean it in wmtd */ -+ break; -+ } -+ -+ /* wait result, clean it here */ -+ bCleanup = 1; /* MTK_WCN_BOOL_TRUE; */ -+ -+ /* check result */ -+ wait_ret = osal_wait_for_signal_timeout(&pOp->signal); -+ STP_PSM_DBG_FUNC("wait completion:%d\n", wait_ret); -+ if (!wait_ret) { -+ STP_PSM_ERR_FUNC("wait completion timeout\n"); -+ /* TODO: how to handle it? retry? */ -+ } else { -+ if (pOp->result) -+ STP_PSM_WARN_FUNC("op(%d) result:%d\n", pOp->op.opId, pOp->result); -+ /* op completes, check result */ -+ bRet = (pOp->result) ? 0 : 1; -+ } -+ } while (0); -+ -+ if (bCleanup) { -+ /* put Op back to freeQ */ -+ bRet = _stp_psm_put_op(stp_psm, &stp_psm->rFreeOpQ, pOp); -+ if (bRet == 0) -+ STP_PSM_WARN_FUNC("+++++++++++ Put op active free fail, maybe disable/enable psm\n"); -+ } -+ -+ return bRet; -+} -+ -+static INT32 _stp_psm_wait_for_msg(void *pvData) -+{ -+ MTKSTP_PSM_T *stp_psm = (MTKSTP_PSM_T *) pvData; -+ -+ STP_PSM_DBG_FUNC("%s: stp_psm->rActiveOpQ = %d\n", __func__, RB_COUNT(&stp_psm->rActiveOpQ)); -+ -+ return (!RB_EMPTY(&stp_psm->rActiveOpQ)) || osal_thread_should_stop(&stp_psm->PSMd); -+} -+ -+static INT32 _stp_psm_proc(void *pvData) -+{ -+ MTKSTP_PSM_T *stp_psm = (MTKSTP_PSM_T *) pvData; -+ P_OSAL_OP pOp; -+ UINT32 id; -+ INT32 result; -+ -+ if (!stp_psm) { -+ STP_PSM_WARN_FUNC("!stp_psm\n"); -+ return -1; -+ } -+/* STP_PSM_INFO_FUNC("wmtd starts running: pWmtDev(0x%p) [pol, rt_pri, n_pri, pri]=[%d, %d, %d, %d]\n", */ -+/* stp_psm, current->policy, current->rt_priority, current->normal_prio, current->prio); */ -+ -+ for (;;) { -+ -+ pOp = NULL; -+ -+ osal_wait_for_event(&stp_psm->STPd_event, _stp_psm_wait_for_msg, (void *)stp_psm); -+ -+ /* we set reset flag when calling stp_reset after cleanup all op. */ -+ if (osal_test_bit(STP_PSM_RESET_EN, &stp_psm->flag)) { -+ osal_clear_bit(STP_PSM_RESET_EN, &stp_psm->flag); -+ _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); -+ } -+ if (osal_thread_should_stop(&stp_psm->PSMd)) { -+ STP_PSM_INFO_FUNC("should stop now...\n"); -+ /* TODO: clean up active opQ */ -+ break; -+ } -+ -+ /* get Op from activeQ */ -+ pOp = _stp_psm_get_op(stp_psm, &stp_psm->rActiveOpQ); -+ if (!pOp) { -+ STP_PSM_WARN_FUNC("+++++++++++ Get op from activeQ fail, maybe disable/enable psm\n"); -+ continue; -+ } -+ -+ id = osal_op_get_id(pOp); -+ -+ if (id >= STP_OPID_PSM_NUM) { -+ STP_PSM_WARN_FUNC("abnormal opid id: 0x%x\n", id); -+ result = -1; -+ goto handler_done; -+ } -+ -+ result = _stp_psm_handler(stp_psm, &pOp->op); -+ -+handler_done: -+ -+ if (result) { -+ STP_PSM_WARN_FUNC("opid id(0x%x)(%s) error(%d)\n", id, -+ (id >= 4) ? ("???") : (g_psm_op_name[id]), result); -+ } -+ -+ if (osal_op_is_wait_for_signal(pOp)) -+ osal_op_raise_signal(pOp, result); -+ else { -+ /* put Op back to freeQ */ -+ if (_stp_psm_put_op(stp_psm, &stp_psm->rFreeOpQ, pOp) == 0) -+ STP_PSM_WARN_FUNC("+++++++++++ Put op to FreeOpQ fail, maybe disable/enable psm\n"); -+ } -+ -+ if (STP_OPID_PSM_EXIT == id) -+ break; -+ } -+ STP_PSM_INFO_FUNC("exits\n"); -+ -+ return 0; -+}; -+ -+static inline INT32 _stp_psm_get_time(void) -+{ -+ if (gPsmDbgLevel >= STP_PSM_LOG_LOUD) -+ osal_printtimeofday(">>>"); -+ -+ return 0; -+} -+ -+static inline INT32 _stp_psm_get_state(MTKSTP_PSM_T *stp_psm) -+{ -+ -+ if (stp_psm == NULL) -+ return STP_PSM_OPERATION_FAIL; -+ -+ if (stp_psm->work_state < STP_PSM_MAX_STATE) -+ return stp_psm->work_state; -+ STP_PSM_ERR_FUNC("work_state = %d, invalid\n", stp_psm->work_state); -+ -+ return STP_PSM_OPERATION_FAIL; -+} -+ -+static inline INT32 _stp_psm_set_state(MTKSTP_PSM_T *stp_psm, const MTKSTP_PSM_STATE_T state) -+{ -+ if (stp_psm == NULL) -+ return STP_PSM_OPERATION_FAIL; -+ -+ if (stp_psm->work_state < STP_PSM_MAX_STATE) { -+ _stp_psm_get_time(); -+ /* STP_PSM_INFO_FUNC("work_state = %s --> %s\n", -+ * g_psm_state[stp_psm->work_state], g_psm_state[state]); -+ */ -+ -+ stp_psm->work_state = state; -+ if (stp_psm->work_state != ACT) { -+ /* osal_lock_unsleepable_lock(&stp_psm->flagSpinlock); */ -+ osal_set_bit(STP_PSM_BLOCK_DATA_EN, &stp_psm->flag); -+ _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); -+ /* osal_unlock_unsleepable_lock(&stp_psm->flagSpinlock); */ -+ } -+ } else -+ STP_PSM_ERR_FUNC("work_state = %d, invalid\n", stp_psm->work_state); -+ -+ -+ return STP_PSM_OPERATION_SUCCESS; -+} -+ -+static inline INT32 _stp_psm_start_monitor(MTKSTP_PSM_T *stp_psm) -+{ -+ -+ if (!stp_psm) -+ return STP_PSM_OPERATION_FAIL; -+ -+ if (osal_test_bit(STP_PSM_WMT_EVENT_DISABLE_MONITOR, &stp_psm->flag)) { -+ STP_PSM_DBG_FUNC("STP-PSM DISABLE, DONT restart monitor!\n\r"); -+ return STP_PSM_OPERATION_SUCCESS; -+ } -+ -+ STP_PSM_LOUD_FUNC("start monitor\n"); -+ osal_timer_modify(&stp_psm->psm_timer, stp_psm->idle_time_to_sleep); -+ -+ return STP_PSM_OPERATION_SUCCESS; -+} -+ -+static inline INT32 _stp_psm_stop_monitor(MTKSTP_PSM_T *stp_psm) -+{ -+ -+ if (!stp_psm) -+ return STP_PSM_OPERATION_FAIL; -+ -+ STP_PSM_DBG_FUNC("stop monitor\n"); -+ osal_timer_stop_sync(&stp_psm->psm_timer); -+ -+ return STP_PSM_OPERATION_SUCCESS; -+} -+ -+INT32 _stp_psm_hold_data(MTKSTP_PSM_T *stp_psm, const UINT8 *buffer, const UINT32 len, const UINT8 type) -+{ -+ INT32 available_space = 0; -+ INT32 needed_space = 0; -+ UINT8 delimiter[] = { 0xbb, 0xbb }; -+ -+ if (!stp_psm) -+ return STP_PSM_OPERATION_FAIL; -+ -+ osal_lock_sleepable_lock(&stp_psm->hold_fifo_spinlock_global); -+ -+ available_space = STP_PSM_FIFO_SIZE - osal_fifo_len(&stp_psm->hold_fifo); -+ needed_space = len + sizeof(UINT8) + sizeof(UINT32) + 2; -+ -+ /* STP_PSM_INFO_FUNC("*******FIFO Available(%d), Need(%d)\n", available_space, needed_space); */ -+ -+ if (available_space < needed_space) { -+ STP_PSM_ERR_FUNC("FIFO Available!! Reset FIFO\n"); -+ osal_fifo_reset(&stp_psm->hold_fifo); -+ } -+ /* type */ -+ osal_fifo_in(&stp_psm->hold_fifo, (PUINT8) &type, sizeof(UINT8)); -+ /* length */ -+ osal_fifo_in(&stp_psm->hold_fifo, (PUINT8) &len, sizeof(UINT32)); -+ /* buffer */ -+ osal_fifo_in(&stp_psm->hold_fifo, (PUINT8) buffer, len); -+ /* delimiter */ -+ osal_fifo_in(&stp_psm->hold_fifo, (PUINT8) delimiter, 2); -+ -+ osal_unlock_sleepable_lock(&stp_psm->hold_fifo_spinlock_global); -+ -+ return len; -+ -+} -+ -+INT32 _stp_psm_has_pending_data(MTKSTP_PSM_T *stp_psm) -+{ -+ return osal_fifo_len(&stp_psm->hold_fifo); -+} -+ -+INT32 _stp_psm_release_data(MTKSTP_PSM_T *stp_psm) -+{ -+ -+ INT32 i = 20; /*Max buffered packet number */ -+ INT32 ret = 0; -+ UINT8 type = 0; -+ UINT32 len = 0; -+ UINT8 delimiter[2]; -+ -+ /* STP_PSM_ERR_FUNC("++++++++++release data++len=%d\n", osal_fifo_len(&stp_psm->hold_fifo)); */ -+ while (osal_fifo_len(&stp_psm->hold_fifo) && i > 0) { -+ /* acquire spinlock */ -+ osal_lock_sleepable_lock(&stp_psm->hold_fifo_spinlock_global); -+ -+ ret = osal_fifo_out(&stp_psm->hold_fifo, (PUINT8) &type, sizeof(UINT8)); -+ ret = osal_fifo_out(&stp_psm->hold_fifo, (PUINT8) &len, sizeof(UINT32)); -+ -+ if (len > STP_PSM_PACKET_SIZE_MAX) { -+ STP_PSM_ERR_FUNC("***psm packet's length too Long!****\n"); -+ STP_PSM_INFO_FUNC("***reset psm's fifo***\n"); -+ } else { -+ osal_memset(stp_psm->out_buf, 0, STP_PSM_TX_SIZE); -+ ret = osal_fifo_out(&stp_psm->hold_fifo, (PUINT8) stp_psm->out_buf, len); -+ } -+ -+ ret = osal_fifo_out(&stp_psm->hold_fifo, (PUINT8) delimiter, 2); -+ -+ if (delimiter[0] == 0xbb && delimiter[1] == 0xbb) { -+ /* osal_buffer_dump(stp_psm->out_buf, "psm->out_buf", len, 32); */ -+ stp_send_data_no_ps(stp_psm->out_buf, len, type); -+ } else { -+ STP_PSM_ERR_FUNC("***psm packet fifo parsing fail****\n"); -+ STP_PSM_INFO_FUNC("***reset psm's fifo***\n"); -+ -+ osal_fifo_reset(&stp_psm->hold_fifo); -+ } -+ i--; -+ osal_unlock_sleepable_lock(&stp_psm->hold_fifo_spinlock_global); -+ } -+ return STP_PSM_OPERATION_SUCCESS; -+} -+ -+static inline INT32 _stp_psm_notify_wmt_host_awake_wq(MTKSTP_PSM_T *stp_psm) -+{ -+ -+ P_OSAL_OP pOp; -+ INT32 bRet; -+ INT32 retval; -+ -+ if (stp_psm == NULL) -+ return STP_PSM_OPERATION_FAIL; -+ -+ pOp = _stp_psm_get_free_op(stp_psm); -+ if (!pOp) { -+ STP_PSM_WARN_FUNC("get_free_lxop fail\n"); -+ return -1; /* break; */ -+ } -+ -+ pOp->op.opId = STP_OPID_PSM_HOST_AWAKE; -+ pOp->signal.timeoutValue = 0; -+ bRet = _stp_psm_put_act_op(stp_psm, pOp); -+ -+ STP_PSM_DBG_FUNC("OPID(%d) type(%zd) bRet(%d)\n\n", pOp->op.opId, pOp->op.au4OpData[0], bRet); -+ -+ retval = (0 == bRet) ? (STP_PSM_OPERATION_FAIL) : 0; -+ -+ return retval; -+} -+ -+static inline INT32 _stp_psm_notify_wmt_wakeup_wq(MTKSTP_PSM_T *stp_psm) -+{ -+ P_OSAL_OP pOp; -+ INT32 bRet; -+ INT32 retval; -+ -+ if (stp_psm == NULL) -+ return STP_PSM_OPERATION_FAIL; -+ -+ pOp = _stp_psm_get_free_op(stp_psm); -+ if (!pOp) { -+ STP_PSM_WARN_FUNC("get_free_lxop fail\n"); -+ return -1; /* break; */ -+ } -+ -+ pOp->op.opId = STP_OPID_PSM_WAKEUP; -+ pOp->signal.timeoutValue = 0; -+ bRet = _stp_psm_put_act_op(stp_psm, pOp); -+ if (0 == bRet) { -+ STP_PSM_WARN_FUNC("OPID(%d) type(%zd) bRet(%s)\n\n", -+ pOp->op.opId, pOp->op.au4OpData[0], "fail"); -+ } -+ retval = (0 == bRet) ? (STP_PSM_OPERATION_FAIL) : (STP_PSM_OPERATION_SUCCESS); -+ -+ return retval; -+} -+ -+static inline INT32 _stp_psm_notify_wmt_sleep_wq(MTKSTP_PSM_T *stp_psm) -+{ -+ P_OSAL_OP pOp; -+ INT32 bRet; -+ INT32 retval; -+ -+ if (stp_psm == NULL) -+ return STP_PSM_OPERATION_FAIL; -+ -+ if (osal_test_bit(STP_PSM_WMT_EVENT_DISABLE_MONITOR_TX_HIGH_DENSITY, &stp_psm->flag)) -+ return 0; -+#if PSM_USE_COUNT_PACKAGE -+ if (osal_test_bit(STP_PSM_WMT_EVENT_DISABLE_MONITOR_RX_HIGH_DENSITY, &stp_psm->flag)) -+ return 0; -+#endif -+ if (osal_test_bit(STP_PSM_WMT_EVENT_DISABLE_MONITOR, &stp_psm->flag)) -+ return 0; -+ -+ pOp = _stp_psm_get_free_op(stp_psm); -+ if (!pOp) { -+ STP_PSM_WARN_FUNC("get_free_lxop fail\n"); -+ return -1; /* break; */ -+ } -+ -+ pOp->op.opId = STP_OPID_PSM_SLEEP; -+ pOp->signal.timeoutValue = 0; -+ bRet = _stp_psm_put_act_op(stp_psm, pOp); -+ -+ STP_PSM_DBG_FUNC("OPID(%d) type(%zd) bRet(%d)\n\n", pOp->op.opId, pOp->op.au4OpData[0], bRet); -+ -+ retval = (0 == bRet) ? (STP_PSM_OPERATION_FAIL) : 1; -+ -+ return retval; -+} -+ -+/*internal function*/ -+ -+static inline INT32 _stp_psm_reset(MTKSTP_PSM_T *stp_psm) -+{ -+ INT32 i = 0; -+ P_OSAL_OP_Q pOpQ; -+ P_OSAL_OP pOp; -+ -+ STP_PSM_DBG_FUNC("PSM MODE RESET=============================>\n\r"); -+ -+ STP_PSM_DBG_FUNC("_stp_psm_reset\n"); -+ STP_PSM_DBG_FUNC("reset-wake_lock(%d)\n", osal_wake_lock_count(&stp_psm->wake_lock)); -+ osal_wake_unlock(&stp_psm->wake_lock); -+ STP_PSM_DBG_FUNC("reset-wake_lock(%d)\n", osal_wake_lock_count(&stp_psm->wake_lock)); -+ -+ /* --> disable psm <--// */ -+ stp_psm->flag.data = 0; -+ osal_set_bit(STP_PSM_WMT_EVENT_DISABLE_MONITOR, &stp_psm->flag); -+ _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); -+ _stp_psm_stop_monitor(stp_psm); -+ -+ /* --> prepare the op list <--// */ -+ osal_lock_unsleepable_lock(&(stp_psm->wq_spinlock)); -+ RB_INIT(&stp_psm->rFreeOpQ, STP_OP_BUF_SIZE); -+ RB_INIT(&stp_psm->rActiveOpQ, STP_OP_BUF_SIZE); -+ -+ /* stp_psm->current_active_op = NULL; */ -+ stp_psm->last_active_opId = STP_OPID_PSM_INALID; -+ -+ pOpQ = &stp_psm->rFreeOpQ; -+ for (i = 0; i < STP_OP_BUF_SIZE; i++) { -+ if (!RB_FULL(pOpQ)) { -+ pOp = &stp_psm->arQue[i]; -+ RB_PUT(pOpQ, pOp); -+ } -+ } -+ osal_unlock_unsleepable_lock(&(stp_psm->wq_spinlock)); -+ -+ /* --> clean up interal data structure<--// */ -+ _stp_psm_set_state(stp_psm, ACT); -+ -+ osal_lock_sleepable_lock(&stp_psm->hold_fifo_spinlock_global); -+ osal_fifo_reset(&stp_psm->hold_fifo); -+ osal_unlock_sleepable_lock(&stp_psm->hold_fifo_spinlock_global); -+ -+ /* --> stop psm thread wait <--// */ -+ osal_set_bit(STP_PSM_RESET_EN, &stp_psm->flag); -+ _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); -+ osal_trigger_event(&stp_psm->wait_wmt_q); -+ -+ STP_PSM_DBG_FUNC("PSM MODE RESET<============================\n\r"); -+ -+ return STP_PSM_OPERATION_SUCCESS; -+} -+ -+static INT32 _stp_psm_wait_wmt_event(void *pvData) -+{ -+ MTKSTP_PSM_T *stp_psm = (MTKSTP_PSM_T *) pvData; -+ -+ STP_PSM_DBG_FUNC("%s, stp_psm->flag= %ld\n", __func__, stp_psm->flag.data); -+ -+ return (osal_test_bit(STP_PSM_WMT_EVENT_SLEEP_EN, &stp_psm->flag)) || -+ (osal_test_bit(STP_PSM_WMT_EVENT_WAKEUP_EN, &stp_psm->flag)) || -+ (osal_test_bit(STP_PSM_WMT_EVENT_ROLL_BACK_EN, &stp_psm->flag)) || -+ (osal_test_bit(STP_PSM_RESET_EN, &stp_psm->flag)); -+} -+ -+static inline INT32 _stp_psm_wait_wmt_event_wq(MTKSTP_PSM_T *stp_psm) -+{ -+ -+ INT32 retval = 0; -+ -+ if (stp_psm == NULL) -+ return STP_PSM_OPERATION_FAIL; -+ -+ osal_wait_for_event_timeout(&stp_psm->wait_wmt_q, _stp_psm_wait_wmt_event, (void *)stp_psm); -+ -+ if (osal_test_bit(STP_PSM_WMT_EVENT_WAKEUP_EN, &stp_psm->flag)) { -+ osal_clear_bit(STP_PSM_WMT_EVENT_WAKEUP_EN, &stp_psm->flag); -+ _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); -+/* osal_lock_unsleepable_lock(&stp_psm->flagSpinlock); */ -+ /* STP send data here: STP enqueue data to psm buffer. */ -+ _stp_psm_release_data(stp_psm); -+ /* STP send data here: STP enqueue data to psm buffer. We release packet by the next one. */ -+ osal_clear_bit(STP_PSM_BLOCK_DATA_EN, &stp_psm->flag); -+ _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); -+ /* STP send data here: STP sends data directly without PSM. */ -+ _stp_psm_set_state(stp_psm, ACT); -+/* osal_unlock_unsleepable_lock(&stp_psm->flagSpinlock); */ -+ -+ if (stp_psm_is_quick_ps_support()) -+ stp_psm_notify_wmt_sleep(stp_psm); -+ else -+ _stp_psm_start_monitor(stp_psm); -+ } else if (osal_test_bit(STP_PSM_WMT_EVENT_SLEEP_EN, &stp_psm->flag)) { -+ osal_clear_bit(STP_PSM_WMT_EVENT_SLEEP_EN, &stp_psm->flag); -+ _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); -+ _stp_psm_set_state(stp_psm, INACT); -+ -+ STP_PSM_DBG_FUNC("mt_combo_plt_enter_deep_idle++\n"); -+ mt_combo_plt_enter_deep_idle(COMBO_IF_BTIF); -+ STP_PSM_DBG_FUNC("mt_combo_plt_enter_deep_idle--\n"); -+ -+ STP_PSM_DBG_FUNC("sleep-wake_lock(%d)\n", osal_wake_lock_count(&stp_psm->wake_lock)); -+ osal_wake_unlock(&stp_psm->wake_lock); -+ STP_PSM_DBG_FUNC("sleep-wake_lock#(%d)\n", osal_wake_lock_count(&stp_psm->wake_lock)); -+ } else if (osal_test_bit(STP_PSM_WMT_EVENT_ROLL_BACK_EN, &stp_psm->flag)) { -+ osal_clear_bit(STP_PSM_WMT_EVENT_ROLL_BACK_EN, &stp_psm->flag); -+ _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); -+ if (_stp_psm_get_state(stp_psm) == ACT_INACT) { -+ /* osal_lock_unsleepable_lock(&stp_psm->flagSpinlock); */ -+ _stp_psm_release_data(stp_psm); -+ osal_clear_bit(STP_PSM_BLOCK_DATA_EN, &stp_psm->flag); -+ _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); -+ _stp_psm_set_state(stp_psm, ACT); -+ /* osal_unlock_unsleepable_lock(&stp_psm->flagSpinlock); */ -+ } else if (_stp_psm_get_state(stp_psm) == INACT_ACT) { -+ _stp_psm_set_state(stp_psm, INACT); -+ STP_PSM_INFO_FUNC("[WARNING]PSM state rollback due too wakeup fail\n"); -+ } -+ } else if (osal_test_bit(STP_PSM_RESET_EN, &stp_psm->flag)) { -+ osal_clear_bit(STP_PSM_WMT_EVENT_ROLL_BACK_EN, &stp_psm->flag); -+ _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); -+ } else { -+ STP_PSM_ERR_FUNC("flag = %ld<== Abnormal flag be set!!\n\r", stp_psm->flag.data); -+ STP_PSM_ERR_FUNC("state = %d, flag = %ld\n", stp_psm->work_state, stp_psm->flag.data); -+ wcn_psm_flag_trigger_collect_ftrace(); /* trigger collect SYS_FTRACE */ -+ _stp_psm_dbg_out_printk(g_stp_psm_dbg); -+ } -+ retval = STP_PSM_OPERATION_SUCCESS; -+ -+ return retval; -+} -+ -+static inline INT32 _stp_psm_notify_stp(MTKSTP_PSM_T *stp_psm, const MTKSTP_PSM_ACTION_T action) -+{ -+ -+ INT32 retval = 0; -+ -+ if (action == EIRQ) { -+ STP_PSM_DBG_FUNC("Call _stp_psm_notify_wmt_host_awake_wq\n\r"); -+ -+ _stp_psm_notify_wmt_host_awake_wq(stp_psm); -+ -+ return STP_PSM_OPERATION_FAIL; -+ } -+ -+ if ((_stp_psm_get_state(stp_psm) < STP_PSM_MAX_STATE) && (_stp_psm_get_state(stp_psm) >= 0)) { -+ STP_PSM_DBG_FUNC("state = %s, action=%s\n\r", g_psm_state[_stp_psm_get_state(stp_psm)], -+ g_psm_action[action]); -+ } -+ /* If STP trigger WAKEUP and SLEEP, to do the job below */ -+ switch (_stp_psm_get_state(stp_psm)) { -+ /* stp trigger */ -+ case ACT_INACT: -+ -+ if (action == SLEEP) { -+ STP_PSM_LOUD_FUNC("Action = %s, ACT_INACT state, ready to INACT\n\r", g_psm_action[action]); -+ osal_clear_bit(STP_PSM_WMT_EVENT_WAKEUP_EN, &stp_psm->flag); -+ _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); -+ osal_set_bit(STP_PSM_WMT_EVENT_SLEEP_EN, &stp_psm->flag); -+ _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); -+ /* wake_up(&stp_psm->wait_wmt_q); */ -+ osal_trigger_event(&stp_psm->wait_wmt_q); -+ } else if (action == ROLL_BACK) { -+ STP_PSM_LOUD_FUNC("Action = %s, ACT_INACT state, back to ACT\n\r", g_psm_action[action]); -+ /* stp_psm->flag &= ~STP_PSM_WMT_EVENT_ROLL_BACK_EN; */ -+ osal_set_bit(STP_PSM_WMT_EVENT_ROLL_BACK_EN, &stp_psm->flag); -+ _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); -+ /* wake_up(&stp_psm->wait_wmt_q); */ -+ osal_trigger_event(&stp_psm->wait_wmt_q); -+ } else { -+ if (action < STP_PSM_MAX_ACTION) { -+ STP_PSM_ERR_FUNC("Action = %s, ACT_INACT state, the case should not happens\n\r", -+ g_psm_action[action]); -+ STP_PSM_ERR_FUNC("state = %d, flag = %ld\n", stp_psm->work_state, stp_psm->flag.data); -+ } else { -+ STP_PSM_ERR_FUNC("Invalid Action!!\n\r"); -+ } -+ _stp_psm_dbg_out_printk(g_stp_psm_dbg); -+ retval = STP_PSM_OPERATION_FAIL; -+ } -+ break; -+ /* stp trigger */ -+ -+ case INACT_ACT: -+ -+ if (action == WAKEUP) { -+ STP_PSM_LOUD_FUNC("Action = %s, INACT_ACT state, ready to ACT\n\r", g_psm_action[action]); -+ osal_clear_bit(STP_PSM_WMT_EVENT_SLEEP_EN, &stp_psm->flag); -+ _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); -+ osal_set_bit(STP_PSM_WMT_EVENT_WAKEUP_EN, &stp_psm->flag); -+ _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); -+ /* wake_up(&stp_psm->wait_wmt_q); */ -+ osal_trigger_event(&stp_psm->wait_wmt_q); -+ } else if (action == HOST_AWAKE) { -+ STP_PSM_LOUD_FUNC("Action = %s, INACT_ACT state, ready to ACT\n\r", g_psm_action[action]); -+ osal_clear_bit(STP_PSM_WMT_EVENT_SLEEP_EN, &stp_psm->flag); -+ _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); -+ osal_set_bit(STP_PSM_WMT_EVENT_WAKEUP_EN, &stp_psm->flag); -+ _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); -+ /* wake_up(&stp_psm->wait_wmt_q); */ -+ osal_trigger_event(&stp_psm->wait_wmt_q); -+ } else if (action == ROLL_BACK) { -+ STP_PSM_LOUD_FUNC("Action = %s, INACT_ACT state, back to INACT\n\r", g_psm_action[action]); -+ osal_set_bit(STP_PSM_WMT_EVENT_ROLL_BACK_EN, &stp_psm->flag); -+ _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); -+ /* wake_up(&stp_psm->wait_wmt_q); */ -+ osal_trigger_event(&stp_psm->wait_wmt_q); -+ } else { -+ if (action < STP_PSM_MAX_ACTION) { -+ STP_PSM_ERR_FUNC("Action = %s, INACT_ACT state, the case should not happens\n\r", -+ g_psm_action[action]); -+ STP_PSM_ERR_FUNC("state = %d, flag = %ld\n", stp_psm->work_state, stp_psm->flag.data); -+ } else { -+ STP_PSM_ERR_FUNC("Invalid Action!!\n\r"); -+ } -+ _stp_psm_dbg_out_printk(g_stp_psm_dbg); -+ retval = STP_PSM_OPERATION_FAIL; -+ } -+ break; -+ -+ case INACT: -+ -+ if (action < STP_PSM_MAX_ACTION) { -+ STP_PSM_ERR_FUNC("Action = %s, INACT state, the case should not happens\n\r", -+ g_psm_action[action]); -+ STP_PSM_ERR_FUNC("state = %d, flag = %ld\n", stp_psm->work_state, stp_psm->flag.data); -+ } else { -+ STP_PSM_ERR_FUNC("Invalid Action!!\n\r"); -+ } -+ _stp_psm_dbg_out_printk(g_stp_psm_dbg); -+ retval = -1; -+ -+ break; -+ -+ case ACT: -+ -+ if (action < STP_PSM_MAX_ACTION) { -+ STP_PSM_ERR_FUNC("Action = %s, ACT state, the case should not happens\n\r", -+ g_psm_action[action]); -+ STP_PSM_ERR_FUNC("state = %d, flag = %ld\n", stp_psm->work_state, stp_psm->flag.data); -+ } else { -+ STP_PSM_ERR_FUNC("Invalid Action!!\n\r"); -+ } -+ _stp_psm_dbg_out_printk(g_stp_psm_dbg); -+ retval = STP_PSM_OPERATION_FAIL; -+ -+ break; -+ -+ default: -+ -+ /*invalid */ -+ if (action < STP_PSM_MAX_ACTION) { -+ STP_PSM_ERR_FUNC("Action = %s, Invalid state, the case should not happens\n\r", -+ g_psm_action[action]); -+ STP_PSM_ERR_FUNC("state = %d, flag = %ld\n", stp_psm->work_state, stp_psm->flag.data); -+ } else { -+ STP_PSM_ERR_FUNC("Invalid Action!!\n\r"); -+ } -+ _stp_psm_dbg_out_printk(g_stp_psm_dbg); -+ retval = STP_PSM_OPERATION_FAIL; -+ -+ break; -+ } -+ -+ return retval; -+ -+} -+ -+static inline INT32 _stp_psm_notify_wmt(MTKSTP_PSM_T *stp_psm, const MTKSTP_PSM_ACTION_T action) -+{ -+ INT32 ret = 0; -+ -+ if (stp_psm == NULL) -+ return STP_PSM_OPERATION_FAIL; -+ -+ switch (_stp_psm_get_state(stp_psm)) { -+ case ACT: -+ -+ if (action == SLEEP) { -+ if (osal_test_bit(STP_PSM_WMT_EVENT_DISABLE_MONITOR, &stp_psm->flag)) { -+ STP_PSM_ERR_FUNC("psm monitor disabled, can't do sleep op\n"); -+ return STP_PSM_OPERATION_FAIL; -+ } -+ -+ _stp_psm_set_state(stp_psm, ACT_INACT); -+ -+ _stp_psm_release_data(stp_psm); -+ -+ if (stp_psm->wmt_notify) { -+ stp_psm->wmt_notify(SLEEP); -+ _stp_psm_wait_wmt_event_wq(stp_psm); -+ } else { -+ STP_PSM_ERR_FUNC("stp_psm->wmt_notify = NULL\n"); -+ ret = STP_PSM_OPERATION_FAIL; -+ } -+ } else if (action == WAKEUP || action == HOST_AWAKE) { -+ STP_PSM_INFO_FUNC("In ACT state, dont do WAKEUP/HOST_AWAKE again\n"); -+ _stp_psm_release_data(stp_psm); -+ } else { -+ STP_PSM_ERR_FUNC("invalid operation, the case should not happen\n"); -+ STP_PSM_ERR_FUNC("state = %d, flag = %ld\n", stp_psm->work_state, stp_psm->flag.data); -+ _stp_psm_dbg_out_printk(g_stp_psm_dbg); -+ ret = STP_PSM_OPERATION_FAIL; -+ -+ } -+ -+ break; -+ -+ case INACT: -+ -+ if (action == WAKEUP) { -+ _stp_psm_set_state(stp_psm, INACT_ACT); -+ -+ if (stp_psm->wmt_notify) { -+ STP_PSM_DBG_FUNC("wakeup +wake_lock(%d)\n", osal_wake_lock_count(&stp_psm->wake_lock)); -+ osal_wake_lock(&stp_psm->wake_lock); -+ STP_PSM_DBG_FUNC("wakeup +wake_lock(%d)#\n", osal_wake_lock_count(&stp_psm->wake_lock)); -+ -+ STP_PSM_DBG_FUNC("mt_combo_plt_exit_deep_idle++\n"); -+ mt_combo_plt_exit_deep_idle(COMBO_IF_BTIF); -+ STP_PSM_DBG_FUNC("mt_combo_plt_exit_deep_idle--\n"); -+ -+ stp_psm->wmt_notify(WAKEUP); -+ _stp_psm_wait_wmt_event_wq(stp_psm); -+ } else { -+ STP_PSM_ERR_FUNC("stp_psm->wmt_notify = NULL\n"); -+ ret = STP_PSM_OPERATION_FAIL; -+ } -+ } else if (action == HOST_AWAKE) { -+ _stp_psm_set_state(stp_psm, INACT_ACT); -+ -+ if (stp_psm->wmt_notify) { -+ STP_PSM_DBG_FUNC("host awake +wake_lock(%d)\n", -+ osal_wake_lock_count(&stp_psm->wake_lock)); -+ osal_wake_lock(&stp_psm->wake_lock); -+ STP_PSM_DBG_FUNC("host awake +wake_lock(%d)#\n", -+ osal_wake_lock_count(&stp_psm->wake_lock)); -+ -+ STP_PSM_DBG_FUNC("mt_combo_plt_exit_deep_idle++\n"); -+ mt_combo_plt_exit_deep_idle(COMBO_IF_BTIF); -+ STP_PSM_DBG_FUNC("mt_combo_plt_exit_deep_idle--\n"); -+ -+ stp_psm->wmt_notify(HOST_AWAKE); -+ _stp_psm_wait_wmt_event_wq(stp_psm); -+ } else { -+ STP_PSM_ERR_FUNC("stp_psm->wmt_notify = NULL\n"); -+ ret = STP_PSM_OPERATION_FAIL; -+ } -+ } else if (action == SLEEP) { -+ STP_PSM_INFO_FUNC("In INACT state, dont do SLEEP again\n"); -+ } else { -+ STP_PSM_ERR_FUNC("invalid operation, the case should not happen\n"); -+ STP_PSM_ERR_FUNC("state = %d, flag = %ld\n", stp_psm->work_state, stp_psm->flag.data); -+ _stp_psm_dbg_out_printk(g_stp_psm_dbg); -+ ret = STP_PSM_OPERATION_FAIL; -+ } -+ -+ break; -+ -+ default: -+ -+ /*invalid */ -+ STP_PSM_ERR_FUNC("invalid state, the case should not happen\n"); -+ STP_PSM_ERR_FUNC("state = %d, flag = %ld\n", stp_psm->work_state, stp_psm->flag.data); -+ _stp_psm_dbg_out_printk(g_stp_psm_dbg); -+ ret = STP_PSM_OPERATION_FAIL; -+ -+ break; -+ } -+ return ret; -+} -+ -+static inline void _stp_psm_stp_is_idle(/*unsigned long data*/struct timer_list *t) -+{ -+ //MTKSTP_PSM_T *stp_psm = (MTKSTP_PSM_T *) data; -+ MTKSTP_PSM_T *stp_psm = from_timer(stp_psm,t,psm_timer.timer); -+ -+ osal_clear_bit(STP_PSM_WMT_EVENT_DISABLE_MONITOR_RX_HIGH_DENSITY, &stp_psm->flag); -+ _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); -+ osal_clear_bit(STP_PSM_WMT_EVENT_DISABLE_MONITOR_TX_HIGH_DENSITY, &stp_psm->flag); -+ _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); -+ if (osal_test_bit(STP_PSM_WMT_EVENT_DISABLE_MONITOR, &stp_psm->flag)) { -+ STP_PSM_DBG_FUNC("STP-PSM DISABLE!\n"); -+ return; -+ } -+ -+ if (1 == _stp_psm_notify_wmt_sleep_wq(stp_psm)) -+ STP_PSM_INFO_FUNC("**IDLE is over %d msec, go to sleep!!!**\n", stp_psm->idle_time_to_sleep); -+} -+ -+static inline INT32 _stp_psm_init_monitor(MTKSTP_PSM_T *stp_psm) -+{ -+ if (!stp_psm) -+ return STP_PSM_OPERATION_FAIL; -+ -+ STP_PSM_INFO_FUNC("init monitor\n"); -+ -+ stp_psm->psm_timer.timeoutHandler = _stp_psm_stp_is_idle; -+ stp_psm->psm_timer.timeroutHandlerData = (unsigned long)stp_psm; -+ osal_timer_create(&stp_psm->psm_timer); -+ -+ return STP_PSM_OPERATION_SUCCESS; -+} -+ -+static inline INT32 _stp_psm_deinit_monitor(MTKSTP_PSM_T *stp_psm) -+{ -+ -+ if (!stp_psm) -+ return STP_PSM_OPERATION_FAIL; -+ -+ STP_PSM_INFO_FUNC("deinit monitor\n"); -+ -+ osal_timer_stop_sync(&stp_psm->psm_timer); -+ -+ return 0; -+} -+ -+static inline INT32 _stp_psm_is_to_block_traffic(MTKSTP_PSM_T *stp_psm) -+{ -+ INT32 iRet = -1; -+ -+/* osal_lock_unsleepable_lock(&stp_psm->flagSpinlock); */ -+ -+ if (osal_test_bit(STP_PSM_BLOCK_DATA_EN, &stp_psm->flag)) -+ iRet = 1; -+ else -+ iRet = 0; -+ -+/* osal_unlock_unsleepable_lock(&stp_psm->flagSpinlock); */ -+ return iRet; -+} -+ -+static inline INT32 _stp_psm_is_disable(MTKSTP_PSM_T *stp_psm) -+{ -+ if (osal_test_bit(STP_PSM_WMT_EVENT_DISABLE_MONITOR, &stp_psm->flag)) -+ return 1; -+ else -+ return 0; -+} -+ -+static inline INT32 _stp_psm_do_wait(MTKSTP_PSM_T *stp_psm, MTKSTP_PSM_STATE_T state) -+{ -+ -+#define POLL_WAIT 20 /* 200 */ -+#define POLL_WAIT_TIME 2000 -+ -+ INT32 i = 0; -+ INT32 limit = POLL_WAIT_TIME / POLL_WAIT; -+ -+ while (_stp_psm_get_state(stp_psm) != state && i < limit) { -+ osal_sleep_ms(POLL_WAIT); -+ i++; -+ STP_PSM_INFO_FUNC("STP is waiting state for %s, i=%d, state = %d\n", g_psm_state[state], i, -+ _stp_psm_get_state(stp_psm)); -+ } -+ -+ if (i == limit) { -+ STP_PSM_WARN_FUNC("-Wait for %s takes %d msec\n", g_psm_state[state], i * POLL_WAIT); -+ _stp_psm_opid_dbg_out_printk(g_stp_psm_opid_dbg); -+ return STP_PSM_OPERATION_FAIL; -+ } -+ STP_PSM_DBG_FUNC("+Total waits for %s takes %d msec\n", g_psm_state[state], i * POLL_WAIT); -+ /* _stp_psm_dbg_out_printk(g_stp_psm_opid_dbg); */ -+ return STP_PSM_OPERATION_SUCCESS; -+} -+ -+static inline INT32 _stp_psm_do_wakeup(MTKSTP_PSM_T *stp_psm) -+{ -+ -+ INT32 ret = 0; -+ INT32 retry = 10; -+ P_OSAL_OP_Q pOpQ; -+ P_OSAL_OP pOp; -+ -+ STP_PSM_LOUD_FUNC("*** Do Force Wakeup!***\n\r"); -+ -+ /* <1>If timer is active, we will stop it. */ -+ _stp_psm_stop_monitor(stp_psm); -+ -+ osal_lock_unsleepable_lock(&(stp_psm->wq_spinlock)); -+ -+ pOpQ = &stp_psm->rFreeOpQ; -+ -+ while (!RB_EMPTY(&stp_psm->rActiveOpQ)) { -+ RB_GET(&stp_psm->rActiveOpQ, pOp); -+ if (NULL != pOp && !RB_FULL(pOpQ)) { -+ STP_PSM_DBG_FUNC("opid = %d\n", pOp->op.opId); -+ RB_PUT(pOpQ, pOp); -+ } else { -+ STP_PSM_ERR_FUNC("clear up active queue fail, freeQ full\n"); -+ } -+ } -+ osal_unlock_unsleepable_lock(&(stp_psm->wq_spinlock)); -+ /* <5>We issue wakeup request into op queue. and wait for active. */ -+ do { -+ ret = _stp_psm_notify_wmt_wakeup_wq(stp_psm); -+ -+ if (ret == STP_PSM_OPERATION_SUCCESS) { -+ ret = _stp_psm_do_wait(stp_psm, ACT); -+ -+ /* STP_PSM_INFO_FUNC("<< wait ret = %d, num of activeQ = %d\n", -+ * ret, RB_COUNT(&stp_psm->rActiveOpQ)); -+ */ -+ if (ret == STP_PSM_OPERATION_SUCCESS) -+ break; -+ } else -+ STP_PSM_ERR_FUNC("_stp_psm_notify_wmt_wakeup_wq fail!!\n"); -+ -+ /* STP_PSM_INFO_FUNC("retry = %d\n", retry); */ -+ retry--; -+ -+ if (retry == 0) -+ break; -+ } while (1); -+ -+ if (retry == 0) -+ return STP_PSM_OPERATION_FAIL; -+ else -+ return STP_PSM_OPERATION_SUCCESS; -+} -+ -+static inline INT32 _stp_psm_disable(MTKSTP_PSM_T *stp_psm) -+{ -+ INT32 ret = STP_PSM_OPERATION_FAIL; -+ -+ STP_PSM_DBG_FUNC("PSM Disable start\n\r"); -+ -+ osal_set_bit(STP_PSM_WMT_EVENT_DISABLE_MONITOR, &stp_psm->flag); -+ _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); -+ ret = _stp_psm_do_wakeup(stp_psm); -+ if (ret == STP_PSM_OPERATION_SUCCESS) -+ STP_PSM_DBG_FUNC("PSM Disable Success\n"); -+ else -+ STP_PSM_ERR_FUNC("***PSM Disable Fail***\n"); -+ -+ return ret; -+} -+ -+static inline INT32 _stp_psm_enable(MTKSTP_PSM_T *stp_psm, INT32 idle_time_to_sleep) -+{ -+ INT32 ret = STP_PSM_OPERATION_FAIL; -+ -+ STP_PSM_LOUD_FUNC("PSM Enable start\n\r"); -+ -+ osal_set_bit(STP_PSM_WMT_EVENT_DISABLE_MONITOR, &stp_psm->flag); -+ _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); -+ -+ ret = _stp_psm_do_wakeup(stp_psm); -+ if (ret == STP_PSM_OPERATION_SUCCESS) { -+ osal_clear_bit(STP_PSM_WMT_EVENT_DISABLE_MONITOR, &stp_psm->flag); -+ _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); -+ stp_psm->idle_time_to_sleep = idle_time_to_sleep; -+ -+ if (osal_wake_lock_count(&stp_psm->wake_lock) == 0) { -+ STP_PSM_DBG_FUNC("psm_en+wake_lock(%d)\n", osal_wake_lock_count(&stp_psm->wake_lock)); -+ osal_wake_lock(&stp_psm->wake_lock); -+ STP_PSM_DBG_FUNC("psm_en+wake_lock(%d)#\n", osal_wake_lock_count(&stp_psm->wake_lock)); -+ } -+ -+ _stp_psm_start_monitor(stp_psm); -+ -+ STP_PSM_DBG_FUNC("PSM Enable succeed\n\r"); -+ } else -+ STP_PSM_ERR_FUNC("***PSM Enable Fail***\n"); -+ -+ return ret; -+} -+ -+INT32 _stp_psm_thread_lock_aquire(MTKSTP_PSM_T *stp_psm) -+{ -+ return osal_lock_sleepable_lock(&stp_psm->stp_psm_lock); -+} -+ -+INT32 _stp_psm_thread_lock_release(MTKSTP_PSM_T *stp_psm) -+{ -+ osal_unlock_sleepable_lock(&stp_psm->stp_psm_lock); -+ return 0; -+} -+ -+MTK_WCN_BOOL _stp_psm_is_quick_ps_support(VOID) -+{ -+ if (stp_psm->is_wmt_quick_ps_support) -+ return (*(stp_psm->is_wmt_quick_ps_support)) (); -+ -+ STP_PSM_DBG_FUNC("stp_psm->is_wmt_quick_ps_support is NULL, return false\n\r"); -+ return MTK_WCN_BOOL_FALSE; -+} -+ -+MTK_WCN_BOOL stp_psm_is_quick_ps_support(VOID) -+{ -+ return _stp_psm_is_quick_ps_support(); -+} -+ -+#if PSM_USE_COUNT_PACKAGE -+int stp_psm_disable_by_tx_rx_density(MTKSTP_PSM_T *stp_psm, int dir) -+{ -+ -+ /* easy the variable maintain beween stp tx, rx thread. */ -+ /* so we create variable for tx, rx respectively. */ -+ -+ static int tx_cnt; -+ static int rx_cnt; -+ static int is_tx_first = 1; -+ static int is_rx_first = 1; -+ static unsigned long tx_end_time; -+ static unsigned long rx_end_time; -+ -+ /* */ -+ /* BT A2DP TX CNT = 220, RX CNT = 843 */ -+ /* BT FTP Transferring TX CNT = 574, RX CNT = 2233 (1228~1588) */ -+ /* BT FTP Receiving TX CNT = 204, RX CNT = 3301 (2072~2515) */ -+ /* BT OPP Tx TX_CNT= 330, RX CNT = 1300~1800 */ -+ /* BT OPP Rx TX_CNT= (109~157), RX CNT = 1681~2436 */ -+ if (dir == 0) { /* tx */ -+ -+ tx_cnt++; -+ -+ if (((long)jiffies - (long)tx_end_time >= 0) || (is_tx_first)) { -+ tx_end_time = jiffies + (3 * HZ); -+ STP_PSM_INFO_FUNC("tx cnt = %d in the previous 3 sec\n", tx_cnt); -+ /* if(tx_cnt > 400)//for high traffic , not to do sleep. */ -+ if (tx_cnt > 300) { -+ osal_set_bit(STP_PSM_WMT_EVENT_DISABLE_MONITOR_TX_HIGH_DENSITY, &stp_psm->flag); -+ _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); -+ stp_psm_start_monitor(stp_psm); -+ } else { -+ osal_clear_bit(STP_PSM_WMT_EVENT_DISABLE_MONITOR_TX_HIGH_DENSITY, &stp_psm->flag); -+ _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); -+ } -+ tx_cnt = 0; -+ if (is_tx_first) -+ is_tx_first = 0; -+ } -+ } else { -+ rx_cnt++; -+ -+ if (((long)jiffies - (long)rx_end_time >= 0) || (is_rx_first)) { -+ rx_end_time = jiffies + (3 * HZ); -+ STP_PSM_INFO_FUNC("rx cnt = %d in the previous 3 sec\n", rx_cnt); -+ -+ /* if(rx_cnt > 2000)//for high traffic , not to do sleep. */ -+ if (rx_cnt > 1200) { /* for high traffic , not to do sleep. */ -+ osal_set_bit(STP_PSM_WMT_EVENT_DISABLE_MONITOR_RX_HIGH_DENSITY, &stp_psm->flag); -+ _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); -+ stp_psm_start_monitor(stp_psm); -+ } else { -+ osal_clear_bit(STP_PSM_WMT_EVENT_DISABLE_MONITOR_RX_HIGH_DENSITY, &stp_psm->flag); -+ _stp_psm_dbg_dmp_in(g_stp_psm_dbg, stp_psm->flag.data, __LINE__); -+ } -+ rx_cnt = 0; -+ if (is_rx_first) -+ is_rx_first = 0; -+ } -+ } -+ -+ return 0; -+} -+ -+#else -+static struct timeval tv_now, tv_end; -+static INT32 sample_start; -+static INT32 tx_sum_len; -+static INT32 rx_sum_len; -+ -+INT32 stp_psm_disable_by_tx_rx_density(MTKSTP_PSM_T *stp_psm, INT32 dir, INT32 length) -+{ -+ if (sample_start) { -+ if (dir) -+ rx_sum_len += length; -+ else -+ tx_sum_len += length; -+ -+ do_gettimeofday(&tv_now); -+ /* STP_PSM_INFO_FUNC("tv_now:%d.%d tv_end:%d.%d\n", -+ * tv_now.tv_sec,tv_now.tv_usec,tv_end.tv_sec,tv_end.tv_usec); -+ */ -+ if (((tv_now.tv_sec == tv_end.tv_sec) && (tv_now.tv_usec > tv_end.tv_usec)) || -+ (tv_now.tv_sec > tv_end.tv_sec)) { -+ STP_PSM_INFO_FUNC("STP speed rx:%d tx:%d\n", rx_sum_len, tx_sum_len); -+ if ((rx_sum_len + tx_sum_len) > RTX_SPEED_THRESHOLD) { -+ /* STP_PSM_INFO_FUNC("High speed,Disable monitor\n"); */ -+ osal_set_bit(STP_PSM_WMT_EVENT_DISABLE_MONITOR_TX_HIGH_DENSITY, &stp_psm->flag); -+ stp_psm->idle_time_to_sleep = STP_PSM_IDLE_TIME_SLEEP_1000; -+ stp_psm_start_monitor(stp_psm); -+ } else { -+ /* STP_PSM_INFO_FUNC("Low speed,Enable monitor\n"); */ -+ stp_psm->idle_time_to_sleep = STP_PSM_IDLE_TIME_SLEEP; -+ osal_clear_bit(STP_PSM_WMT_EVENT_DISABLE_MONITOR_TX_HIGH_DENSITY, &stp_psm->flag); -+ } -+ sample_start = 0; -+ rx_sum_len = 0; -+ tx_sum_len = 0; -+ } -+ } else { -+ sample_start = 1; -+ do_gettimeofday(&tv_now); -+ tv_end = tv_now; -+ tv_end.tv_sec += SAMPLE_DURATION; -+ } -+ -+ return 0; -+} -+#endif -+ -+/*external function for WMT module to do sleep/wakeup*/ -+INT32 stp_psm_set_state(MTKSTP_PSM_T *stp_psm, MTKSTP_PSM_STATE_T state) -+{ -+ return _stp_psm_set_state(stp_psm, state); -+} -+ -+INT32 stp_psm_thread_lock_aquire(MTKSTP_PSM_T *stp_psm) -+{ -+ return _stp_psm_thread_lock_aquire(stp_psm); -+} -+ -+INT32 stp_psm_thread_lock_release(MTKSTP_PSM_T *stp_psm) -+{ -+ return _stp_psm_thread_lock_release(stp_psm); -+} -+ -+INT32 stp_psm_do_wakeup(MTKSTP_PSM_T *stp_psm) -+{ -+ return _stp_psm_do_wakeup(stp_psm); -+} -+ -+INT32 stp_psm_notify_stp(MTKSTP_PSM_T *stp_psm, const MTKSTP_PSM_ACTION_T action) -+{ -+ -+ return _stp_psm_notify_stp(stp_psm, action); -+} -+ -+INT32 stp_psm_notify_wmt_wakeup(MTKSTP_PSM_T *stp_psm) -+{ -+ return _stp_psm_notify_wmt_wakeup_wq(stp_psm); -+} -+ -+int stp_psm_notify_wmt_sleep(MTKSTP_PSM_T *stp_psm) -+{ -+ -+ return _stp_psm_notify_wmt_sleep_wq(stp_psm); -+} -+ -+INT32 stp_psm_start_monitor(MTKSTP_PSM_T *stp_psm) -+{ -+ return _stp_psm_start_monitor(stp_psm); -+} -+ -+INT32 stp_psm_is_to_block_traffic(MTKSTP_PSM_T *stp_psm) -+{ -+ return _stp_psm_is_to_block_traffic(stp_psm); -+} -+ -+INT32 stp_psm_is_disable(MTKSTP_PSM_T *stp_psm) -+{ -+ return _stp_psm_is_disable(stp_psm); -+} -+ -+INT32 stp_psm_has_pending_data(MTKSTP_PSM_T *stp_psm) -+{ -+ return _stp_psm_has_pending_data(stp_psm); -+} -+ -+INT32 stp_psm_release_data(MTKSTP_PSM_T *stp_psm) -+{ -+ return _stp_psm_release_data(stp_psm); -+} -+ -+INT32 stp_psm_hold_data(MTKSTP_PSM_T *stp_psm, const UINT8 *buffer, const UINT32 len, const UINT8 type) -+{ -+ return _stp_psm_hold_data(stp_psm, buffer, len, type); -+} -+ -+INT32 stp_psm_disable(MTKSTP_PSM_T *stp_psm) -+{ -+ return _stp_psm_disable(stp_psm); -+} -+ -+INT32 stp_psm_enable(MTKSTP_PSM_T *stp_psm, INT32 idle_time_to_sleep) -+{ -+ return _stp_psm_enable(stp_psm, idle_time_to_sleep); -+} -+ -+INT32 stp_psm_reset(MTKSTP_PSM_T *stp_psm) -+{ -+ stp_psm_set_sleep_enable(stp_psm); -+ -+ return _stp_psm_reset(stp_psm); -+} -+ -+INT32 stp_psm_sleep_for_thermal(MTKSTP_PSM_T *stp_psm) -+{ -+ return _stp_psm_notify_wmt_sleep_wq(stp_psm); -+} -+ -+INT32 stp_psm_set_sleep_enable(MTKSTP_PSM_T *stp_psm) -+{ -+ INT32 ret = 0; -+ -+ if (stp_psm) { -+ stp_psm->sleep_en = 1; -+ STP_PSM_DBG_FUNC("\n"); -+ ret = 0; -+ } else { -+ STP_PSM_INFO_FUNC("Null pointer\n"); -+ ret = -1; -+ } -+ -+ return ret; -+} -+ -+INT32 stp_psm_set_sleep_disable(MTKSTP_PSM_T *stp_psm) -+{ -+ INT32 ret = 0; -+ -+ if (stp_psm) { -+ stp_psm->sleep_en = 0; -+ STP_PSM_DBG_FUNC("\n"); -+ ret = 0; -+ } else { -+ STP_PSM_INFO_FUNC("Null pointer\n"); -+ ret = -1; -+ } -+ -+ return ret; -+} -+ -+/* stp_psm_check_sleep_enable - to check if sleep cmd is enabled or not -+ * @ stp_psm - pointer of psm -+ * -+ * return 1 if sleep is enabled; else return 0 if disabled; else error code -+ */ -+INT32 stp_psm_check_sleep_enable(MTKSTP_PSM_T *stp_psm) -+{ -+ INT32 ret = 0; -+ -+ if (stp_psm) { -+ ret = stp_psm->sleep_en; -+ STP_PSM_DBG_FUNC("%s\n", ret ? "enabled" : "disabled"); -+ } else { -+ STP_PSM_INFO_FUNC("Null pointer\n"); -+ ret = -1; -+ } -+ -+ return ret; -+} -+ -+static INT32 _stp_psm_dbg_dmp_in(STP_PSM_RECORD_T *stp_psm_dbg, UINT32 flag, UINT32 line_num) -+{ -+ INT32 index = 0; -+ struct timeval now; -+ -+ if (stp_psm_dbg) { -+ osal_lock_unsleepable_lock(&stp_psm_dbg->lock); -+ do_gettimeofday(&now); -+ index = stp_psm_dbg->in - 1; -+ index = (index + STP_PSM_DBG_SIZE) % STP_PSM_DBG_SIZE; -+ STP_PSM_DBG_FUNC("index(%d)\n", index); -+ stp_psm_dbg->queue[stp_psm_dbg->in].prev_flag = stp_psm_dbg->queue[index].cur_flag; -+ stp_psm_dbg->queue[stp_psm_dbg->in].cur_flag = flag; -+ stp_psm_dbg->queue[stp_psm_dbg->in].line_num = line_num; -+ stp_psm_dbg->queue[stp_psm_dbg->in].package_no = g_record_num++; -+ stp_psm_dbg->queue[stp_psm_dbg->in].sec = now.tv_sec; -+ stp_psm_dbg->queue[stp_psm_dbg->in].usec = now.tv_usec; -+ stp_psm_dbg->size++; -+ STP_PSM_DBG_FUNC("pre_Flag = %d, cur_flag = %d\n", stp_psm_dbg->queue[stp_psm_dbg->in].prev_flag, -+ stp_psm_dbg->queue[stp_psm_dbg->in].cur_flag); -+ stp_psm_dbg->size = (stp_psm_dbg->size > STP_PSM_DBG_SIZE) ? STP_PSM_DBG_SIZE : stp_psm_dbg->size; -+ stp_psm_dbg->in = (stp_psm_dbg->in >= (STP_PSM_DBG_SIZE - 1)) ? (0) : (stp_psm_dbg->in + 1); -+ STP_PSM_DBG_FUNC("record size = %d, in = %d num = %d\n", stp_psm_dbg->size, stp_psm_dbg->in, line_num); -+ -+ osal_unlock_unsleepable_lock(&stp_psm_dbg->lock); -+ } -+ return 0; -+} -+ -+static INT32 _stp_psm_dbg_out_printk(STP_PSM_RECORD_T *stp_psm_dbg) -+{ -+ -+ UINT32 dumpSize = 0; -+ UINT32 inIndex = 0; -+ UINT32 outIndex = 0; -+ -+ if (!stp_psm_dbg) { -+ STP_PSM_ERR_FUNC("NULL g_stp_psm_dbg reference\n"); -+ return -1; -+ } -+ osal_lock_unsleepable_lock(&stp_psm_dbg->lock); -+ -+ inIndex = stp_psm_dbg->in; -+ dumpSize = stp_psm_dbg->size; -+ if (STP_PSM_DBG_SIZE == dumpSize) -+ outIndex = inIndex; -+ else -+ outIndex = ((inIndex + STP_PSM_DBG_SIZE) - dumpSize) % STP_PSM_DBG_SIZE; -+ -+ STP_PSM_INFO_FUNC("loged record size = %d, in(%d), out(%d)\n", dumpSize, inIndex, outIndex); -+ while (dumpSize > 0) { -+ -+ pr_debug("STP-PSM:%d.%ds, n(%d)pre_flag(%d)cur_flag(%d)line_no(%d)\n", -+ stp_psm_dbg->queue[outIndex].sec, -+ stp_psm_dbg->queue[outIndex].usec, -+ stp_psm_dbg->queue[outIndex].package_no, -+ stp_psm_dbg->queue[outIndex].prev_flag, -+ stp_psm_dbg->queue[outIndex].cur_flag, stp_psm_dbg->queue[outIndex].line_num); -+ -+ outIndex = (outIndex >= (STP_PSM_DBG_SIZE - 1)) ? (0) : (outIndex + 1); -+ dumpSize--; -+ -+ } -+ -+ osal_unlock_unsleepable_lock(&stp_psm_dbg->lock); -+ -+ return 0; -+} -+ -+static INT32 _stp_psm_opid_dbg_dmp_in(P_STP_PSM_OPID_RECORD p_opid_dbg, UINT32 opid, UINT32 line_num) -+{ -+ INT32 index = 0; -+ struct timeval now; -+ -+ if (p_opid_dbg) { -+ osal_lock_unsleepable_lock(&p_opid_dbg->lock); -+ do_gettimeofday(&now); -+ index = p_opid_dbg->in - 1; -+ index = (index + STP_PSM_DBG_SIZE) % STP_PSM_DBG_SIZE; -+ STP_PSM_DBG_FUNC("index(%d)\n", index); -+ p_opid_dbg->queue[p_opid_dbg->in].prev_flag = p_opid_dbg->queue[index].cur_flag; -+ p_opid_dbg->queue[p_opid_dbg->in].cur_flag = opid; -+ p_opid_dbg->queue[p_opid_dbg->in].line_num = line_num; -+ p_opid_dbg->queue[p_opid_dbg->in].package_no = g_opid_record_num++; -+ p_opid_dbg->queue[p_opid_dbg->in].sec = now.tv_sec; -+ p_opid_dbg->queue[p_opid_dbg->in].usec = now.tv_usec; -+ p_opid_dbg->queue[p_opid_dbg->in].pid = current->pid; -+ p_opid_dbg->size++; -+ STP_PSM_DBG_FUNC("pre_opid = %d, cur_opid = %d\n", p_opid_dbg->queue[p_opid_dbg->in].prev_flag, -+ p_opid_dbg->queue[p_opid_dbg->in].cur_flag); -+ p_opid_dbg->size = (p_opid_dbg->size > STP_PSM_DBG_SIZE) ? STP_PSM_DBG_SIZE : p_opid_dbg->size; -+ p_opid_dbg->in = (p_opid_dbg->in >= (STP_PSM_DBG_SIZE - 1)) ? (0) : (p_opid_dbg->in + 1); -+ STP_PSM_DBG_FUNC("opid record size = %d, in = %d num = %d\n", p_opid_dbg->size, p_opid_dbg->in, -+ line_num); -+ -+ osal_unlock_unsleepable_lock(&p_opid_dbg->lock); -+ } -+ return 0; -+ -+} -+ -+static INT32 _stp_psm_opid_dbg_out_printk(P_STP_PSM_OPID_RECORD p_opid_dbg) -+{ -+ UINT32 dumpSize = 0; -+ UINT32 inIndex = 0; -+ UINT32 outIndex = 0; -+ -+ if (!p_opid_dbg) { -+ STP_PSM_ERR_FUNC("NULL p_opid_dbg reference\n"); -+ return -1; -+ } -+ osal_lock_unsleepable_lock(&p_opid_dbg->lock); -+ -+ inIndex = p_opid_dbg->in; -+ dumpSize = p_opid_dbg->size; -+ if (STP_PSM_DBG_SIZE == dumpSize) -+ outIndex = inIndex; -+ else -+ outIndex = ((inIndex + STP_PSM_DBG_SIZE) - dumpSize) % STP_PSM_DBG_SIZE; -+ -+ STP_PSM_INFO_FUNC("loged record size = %d, in(%d), out(%d)\n", dumpSize, inIndex, outIndex); -+ while (dumpSize > 0) { -+ -+ pr_debug("STP-PSM:%d.%ds, n(%d)pre_flag(%d)cur_flag(%d)line_no(%d) pid(%d)\n", -+ p_opid_dbg->queue[outIndex].sec, -+ p_opid_dbg->queue[outIndex].usec, -+ p_opid_dbg->queue[outIndex].package_no, -+ p_opid_dbg->queue[outIndex].prev_flag, -+ p_opid_dbg->queue[outIndex].cur_flag, -+ p_opid_dbg->queue[outIndex].line_num, p_opid_dbg->queue[outIndex].pid); -+ -+ outIndex = (outIndex >= (STP_PSM_DBG_SIZE - 1)) ? (0) : (outIndex + 1); -+ dumpSize--; -+ -+ } -+ -+ osal_unlock_unsleepable_lock(&p_opid_dbg->lock); -+ -+ return 0; -+ -+} -+ -+MTKSTP_PSM_T *stp_psm_init(void) -+{ -+ INT32 err = 0; -+ INT32 i = 0; -+ INT32 ret = -1; -+ -+ STP_PSM_INFO_FUNC("psm init\n"); -+ -+ stp_psm->work_state = ACT; -+ stp_psm->wmt_notify = wmt_lib_ps_stp_cb; -+ stp_psm->is_wmt_quick_ps_support = wmt_lib_is_quick_ps_support; -+ stp_psm->idle_time_to_sleep = STP_PSM_IDLE_TIME_SLEEP; -+ stp_psm->flag.data = 0; -+ stp_psm->stp_tx_cb = NULL; -+ stp_psm_set_sleep_enable(stp_psm); -+ -+ ret = osal_fifo_init(&stp_psm->hold_fifo, NULL, STP_PSM_FIFO_SIZE); -+ if (ret < 0) { -+ STP_PSM_ERR_FUNC("FIFO INIT FAILS\n"); -+ goto ERR_EXIT4; -+ } -+ -+ osal_fifo_reset(&stp_psm->hold_fifo); -+ osal_sleepable_lock_init(&stp_psm->hold_fifo_spinlock_global); -+ osal_unsleepable_lock_init(&stp_psm->wq_spinlock); -+ osal_sleepable_lock_init(&stp_psm->stp_psm_lock); -+ -+/* osal_unsleepable_lock_init(&stp_psm->flagSpinlock); */ -+ -+ osal_memcpy(stp_psm->wake_lock.name, "MT662x", 6); -+ osal_wake_lock_init(&stp_psm->wake_lock); -+ -+ osal_event_init(&stp_psm->STPd_event); -+ RB_INIT(&stp_psm->rFreeOpQ, STP_OP_BUF_SIZE); -+ RB_INIT(&stp_psm->rActiveOpQ, STP_OP_BUF_SIZE); -+ /* Put all to free Q */ -+ for (i = 0; i < STP_OP_BUF_SIZE; i++) { -+ osal_signal_init(&(stp_psm->arQue[i].signal)); -+ _stp_psm_put_op(stp_psm, &stp_psm->rFreeOpQ, &(stp_psm->arQue[i])); -+ } -+ /* stp_psm->current_active_op = NULL; */ -+ stp_psm->last_active_opId = STP_OPID_PSM_INALID; -+ /*Generate BTM thread, to servie STP-CORE and WMT-CORE for sleeping, waking up and host awake */ -+ stp_psm->PSMd.pThreadData = (VOID *) stp_psm; -+ stp_psm->PSMd.pThreadFunc = (VOID *) _stp_psm_proc; -+ osal_memcpy(stp_psm->PSMd.threadName, PSM_THREAD_NAME, osal_strlen(PSM_THREAD_NAME)); -+ -+ ret = osal_thread_create(&stp_psm->PSMd); -+ if (ret < 0) { -+ STP_PSM_ERR_FUNC("osal_thread_create fail...\n"); -+ goto ERR_EXIT5; -+ } -+ /* init_waitqueue_head(&stp_psm->wait_wmt_q); */ -+ stp_psm->wait_wmt_q.timeoutValue = STP_PSM_WAIT_EVENT_TIMEOUT; -+ osal_event_init(&stp_psm->wait_wmt_q); -+ -+ err = _stp_psm_init_monitor(stp_psm); -+ if (err) { -+ STP_PSM_ERR_FUNC("__stp_psm_init ERROR\n"); -+ goto ERR_EXIT6; -+ } -+ /* Start STPd thread */ -+ ret = osal_thread_run(&stp_psm->PSMd); -+ if (ret < 0) { -+ STP_PSM_ERR_FUNC("osal_thread_run FAILS\n"); -+ goto ERR_EXIT6; -+ } -+ /* psm disable in default */ -+ _stp_psm_disable(stp_psm); -+ -+ g_stp_psm_dbg = (STP_PSM_RECORD_T *) osal_malloc(osal_sizeof(STP_PSM_RECORD_T)); -+ if (!g_stp_psm_dbg) { -+ STP_PSM_ERR_FUNC("stp psm dbg allocate memory fail!\n"); -+ return NULL; -+ } -+ osal_memset(g_stp_psm_dbg, 0, osal_sizeof(STP_PSM_RECORD_T)); -+ osal_unsleepable_lock_init(&g_stp_psm_dbg->lock); -+ -+ g_stp_psm_opid_dbg = (STP_PSM_OPID_RECORD *) osal_malloc(osal_sizeof(STP_PSM_OPID_RECORD)); -+ if (!g_stp_psm_opid_dbg) { -+ STP_PSM_ERR_FUNC("stp psm dbg allocate memory fail!\n"); -+ return NULL; -+ } -+ osal_memset(g_stp_psm_opid_dbg, 0, osal_sizeof(STP_PSM_OPID_RECORD)); -+ osal_unsleepable_lock_init(&g_stp_psm_opid_dbg->lock); -+ -+ return stp_psm; -+ -+ERR_EXIT6: -+ -+ ret = osal_thread_destroy(&stp_psm->PSMd); -+ if (ret < 0) { -+ STP_PSM_ERR_FUNC("osal_thread_destroy FAILS\n"); -+ goto ERR_EXIT5; -+ } -+ERR_EXIT5: -+ osal_fifo_deinit(&stp_psm->hold_fifo); -+ERR_EXIT4: -+ -+ return NULL; -+} -+ -+INT32 stp_psm_deinit(MTKSTP_PSM_T *stp_psm) -+{ -+ INT32 ret = -1; -+ -+ STP_PSM_INFO_FUNC("psm deinit\n"); -+ -+ if (g_stp_psm_dbg) { -+ osal_unsleepable_lock_deinit(&g_stp_psm_dbg->lock); -+ osal_free(g_stp_psm_dbg); -+ g_stp_psm_dbg = NULL; -+ } -+ -+ if (!stp_psm) -+ return STP_PSM_OPERATION_FAIL; -+ -+ ret = osal_thread_destroy(&stp_psm->PSMd); -+ if (ret < 0) -+ STP_PSM_ERR_FUNC("osal_thread_destroy FAILS\n"); -+ -+ ret = _stp_psm_deinit_monitor(stp_psm); -+ if (ret < 0) -+ STP_PSM_ERR_FUNC("_stp_psm_deinit_monitor ERROR\n"); -+ -+ osal_wake_lock_deinit(&stp_psm->wake_lock); -+ osal_fifo_deinit(&stp_psm->hold_fifo); -+ osal_sleepable_lock_deinit(&stp_psm->hold_fifo_spinlock_global); -+ osal_unsleepable_lock_deinit(&stp_psm->wq_spinlock); -+ osal_sleepable_lock_deinit(&stp_psm->stp_psm_lock); -+/* osal_unsleepable_lock_deinit(&stp_psm->flagSpinlock); */ -+ -+ return STP_PSM_OPERATION_SUCCESS; -+} -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/core/stp_core.c b/drivers/misc/mediatek/connectivity/common/conn_soc/core/stp_core.c -new file mode 100644 -index 000000000000..a3c24ca14441 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/core/stp_core.c -@@ -0,0 +1,3358 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -+ -+#include "osal_typedef.h" -+#include "stp_core.h" -+#include "psm_core.h" -+#include "btm_core.h" -+#include "stp_dbg.h" -+#include "stp_btif.h" -+ -+#define PFX "[STP] " -+#define STP_LOG_DBG 4 -+#define STP_LOG_PKHEAD 3 -+#define STP_LOG_INFO 2 -+#define STP_LOG_WARN 1 -+#define STP_LOG_ERR 0 -+ -+#define STP_DEL_SIZE 2 /* STP delimiter length */ -+ -+UINT32 gStpDbgLvl = STP_LOG_INFO; -+unsigned int g_coredump_mode = 0; -+#define REMOVE_USELESS_LOG 1 -+ -+#define STP_POLL_CPUPCR_NUM 16 -+#define STP_POLL_CPUPCR_DELAY 10 -+#define STP_RETRY_OPTIMIZE 0 -+ -+/* global variables */ -+static const UINT8 stp_delimiter[STP_DEL_SIZE] = { 0x55, 0x55 }; -+ -+static INT32 fgEnableNak; /* 0=enable NAK; 1=disable NAK */ -+static INT32 fgEnableDelimiter; /* 0=disable Delimiter; 1=enable Delimiter */ -+#if STP_RETRY_OPTIMIZE -+static UINT32 g_retry_times; -+#endif -+/* common interface */ -+static IF_TX sys_if_tx; -+/* event/signal */ -+static EVENT_SET sys_event_set; -+static EVENT_TX_RESUME sys_event_tx_resume; -+static FUNCTION_STATUS sys_check_function_status; -+/* kernel lib */ -+/* int g_block_tx = 0; */ -+static mtkstp_context_struct stp_core_ctx = { 0 }; -+ -+#define STP_PSM_CORE(x) ((x).psm) -+#define STP_SET_PSM_CORE(x, v) ((x).psm = (v)) -+ -+#define STP_BTM_CORE(x) ((x).btm) -+#define STP_SET_BTM_CORE(x, v) ((x).btm = (v)) -+ -+#define STP_IS_ENABLE(x) ((x).f_enable != 0) -+#define STP_NOT_ENABLE(x) ((x).f_enable == 0) -+#define STP_SET_ENABLE(x, v) ((x).f_enable = (v)) -+ -+#define STP_IS_READY(x) ((x).f_ready != 0) -+#define STP_NOT_READY(x) ((x).f_ready == 0) -+#define STP_SET_READY(x, v) ((x).f_ready = (v)) -+ -+#define STP_PENDING_TYPE(x) ((x).f_pending_type) -+#define STP_SET_PENDING_TYPE(x, v) ((x).f_pending_type = (v)) -+ -+#define STP_BLUE_ANGEL (0) -+#define STP_BLUE_Z (1) -+#define STP_BT_STK(x) ((x).f_bluez) -+#define STP_BT_STK_IS_BLUEZ(x) ((x).f_bluez == (STP_BLUE_Z)) -+#define STP_SET_BT_STK(x, v) ((x).f_bluez = (v)) -+ -+#define STP_IS_ENABLE_DBG(x) ((x).f_dbg_en != 0) -+#define STP_NOT_ENABLE_DBG(x) ((x).f_dbg_en == 0) -+#define STP_SET_ENABLE_DBG(x, v) ((x).f_dbg_en = (v)) -+ -+#define STP_IS_ENABLE_RST(x) ((x).f_autorst_en != 0) -+#define STP_NOT_ENABLE_RST(x) ((x).f_autorst_en == 0) -+#define STP_SET_ENABLE_RST(x, v) ((x).f_autorst_en = (v)) -+ -+#define STP_SUPPORT_PROTOCOL(x) ((x).f_mode) -+#define STP_SET_SUPPORT_PROTOCOL(x, v) ((x).f_mode = (v)) -+ -+#define STP_FW_COREDUMP_FLAG(x) ((x).f_coredump) -+#define STP_SET_FW_COREDUMP_FLAG(x, v) ((x).f_coredump = (v)) -+#define STP_ENABLE_FW_COREDUMP(x, v) ((x).en_coredump = (v)) -+#define STP_ENABLE_FW_COREDUMP_FLAG(x) ((x).en_coredump) -+ -+#define STP_WMT_LAST_CLOSE(x) ((x).f_wmt_last_close) -+#define STP_SET_WMT_LAST_CLOSE(x, v) ((x).f_wmt_last_close = (v)) -+ -+#define STP_EVT_ERR_ASSERT(x) ((x).f_evt_err_assert) -+#define STP_SET_EVT_ERR_ASSERT(x, v) ((x).f_evt_err_assert = (v)) -+ -+/*[PatchNeed]Need to calculate the timeout value*/ -+static UINT32 mtkstp_tx_timeout = MTKSTP_TX_TIMEOUT; -+static mtkstp_parser_state prev_state = -1; -+ -+#define CONFIG_DEBUG_STP_TRAFFIC_SUPPORT -+#ifdef CONFIG_DEBUG_STP_TRAFFIC_SUPPORT -+static MTKSTP_DBG_T *g_mtkstp_dbg; -+#endif -+static VOID stp_dbg_pkt_log(INT32 type, INT32 txAck, INT32 seq, INT32 crc, INT32 dir, const UINT8 *pBuf, INT32 len); -+static MTK_WCN_BOOL stp_check_crc(UINT8 *buffer, UINT32 length, UINT16 crc); -+static VOID stp_update_tx_queue(UINT32 txseq); -+static VOID stp_rest_ctx_state(VOID); -+static VOID stp_change_rx_state(mtkstp_parser_state next); -+static void stp_tx_timeout_handler(/*unsigned long data*/ struct timer_list *t); -+static VOID stp_dump_data(const UINT8 *buf, const UINT8 *title, const UINT32 len); -+static VOID stp_dump_tx_queue(UINT32 txseq); -+static INT32 stp_is_apply_powersaving(VOID); -+/*static INT32 stp_is_privileges_cmd(const UINT8 *buffer, const UINT32 length, const UINT8 type);*/ -+static MTK_WCN_BOOL stp_is_tx_res_available(UINT32 length); -+static VOID stp_add_to_tx_queue(const UINT8 *buffer, UINT32 length); -+static INT32 stp_add_to_rx_queue(UINT8 *buffer, UINT32 length, UINT8 type); -+static VOID stp_send_tx_queue(UINT32 txseq); -+static VOID stp_send_ack(UINT8 txAck, UINT8 nak); -+static INT32 stp_process_rxack(VOID); -+static VOID stp_process_packet(VOID); -+ -+/*private functions*/ -+ -+static INT32 stp_ctx_lock_init(mtkstp_context_struct *pctx) -+{ -+#if CFG_STP_CORE_CTX_SPIN_LOCK -+ return osal_unsleepable_lock_init(&((pctx)->stp_mutex)); -+#else -+ osal_sleepable_lock_init(&((pctx)->stp_mutex)); -+ return 0; -+#endif -+} -+ -+static INT32 stp_ctx_lock_deinit(mtkstp_context_struct *pctx) -+{ -+#if CFG_STP_CORE_CTX_SPIN_LOCK -+ return osal_unsleepable_lock_deinit(&((pctx)->stp_mutex)); -+#else -+ return osal_sleepable_lock_deinit(&((pctx)->stp_mutex)); -+#endif -+} -+ -+static INT32 stp_ctx_lock(mtkstp_context_struct *pctx) -+{ -+#if CFG_STP_CORE_CTX_SPIN_LOCK -+ return osal_lock_unsleepable_lock(&((pctx)->stp_mutex)); -+#else -+ return osal_lock_sleepable_lock(&((pctx)->stp_mutex)); -+#endif -+} -+ -+static INT32 stp_ctx_unlock(mtkstp_context_struct *pctx) -+{ -+#if CFG_STP_CORE_CTX_SPIN_LOCK -+ return osal_unlock_unsleepable_lock(&((pctx)->stp_mutex)); -+#else -+ return osal_unlock_sleepable_lock(&((pctx)->stp_mutex)); -+#endif -+} -+ -+MTK_WCN_BOOL mtk_wcn_stp_dbg_level(UINT32 dbglevel) -+{ -+ if (dbglevel <= 4) { -+ gStpDbgLvl = dbglevel; -+ STP_INFO_FUNC("gStpDbgLvl = %d\n", gStpDbgLvl); -+ return MTK_WCN_BOOL_TRUE; -+ } -+ STP_INFO_FUNC("invalid stp debug level. gStpDbgLvl = %d\n", gStpDbgLvl); -+ -+ return MTK_WCN_BOOL_FALSE; -+} -+ -+#if !(REMOVE_USELESS_LOG) -+static UINT8 *stp_type_to_dbg_string(UINT32 type) -+{ -+ UINT8 *type_name = NULL; -+ -+ if (type == BT_TASK_INDX) -+ type_name = "< BT>"; -+ else if (type == GPS_TASK_INDX) -+ type_name = ""; -+ else if (type == WMT_TASK_INDX) -+ type_name = ""; -+ else if (type == FM_TASK_INDX) -+ type_name = "< FM>"; -+ else if (type == ANT_TASK_INDX) -+ type_name = ""; -+ -+ return type_name; -+} -+#endif -+#if 0 -+/***************************************************************************** -+* FUNCTION -+* crc16 -+* DESCRIPTION -+* Compute the CRC-16 for the data buffer -+* PARAMETERS -+* crc [IN] previous CRC value -+* buffer [IN] data buffer -+* length [IN] data buffer length -+* RETURNS -+* the updated CRC value -+*****************************************************************************/ -+static UINT16 crc16(const UINT8 *buffer, const UINT32 length) -+{ -+ UINT32 crc, i; -+ -+ /* FIXME: Add STP checksum feature */ -+ crc = 0; -+ for (i = 0; i < length; i++, buffer++) -+ crc = (crc >> 8) ^ crc16_table[(crc ^ (*buffer)) & 0xff]; -+ -+ return crc; -+} -+ -+#endif -+ -+VOID stp_dbg_pkt_log(INT32 type, INT32 txAck, INT32 seq, INT32 crc, INT32 dir, const UINT8 *pBuf, INT32 len) -+{ -+ -+#ifndef CONFIG_LOG_STP_INTERNAL -+ return; -+#endif -+ -+ if (STP_IS_ENABLE_DBG(stp_core_ctx)) { -+ stp_dbg_log_pkt(g_mtkstp_dbg, STP_DBG_PKT, type, /* type */ -+ txAck, /* ack */ -+ seq, /* seq */ -+ crc, /* crc */ -+ dir, /* dir */ -+ len, /* len */ -+ pBuf); /* body */ -+ } else { -+ STP_DBG_FUNC("stp_dbg not enabled"); -+ } -+} -+ -+/***************************************************************************** -+* FUNCTION -+* stp_check_crc -+* DESCRIPTION -+* check the check sum of packet payload -+* PARAMETERS -+* pdata [IN] the data want to check -+* length [IN] the length of pdata -+* crc [IN] the crc of pdata -+* RETURNS -+* KAL_TRUE crc is ok -+* KAL_FALSE crc is wrong -+*****************************************************************************/ -+static MTK_WCN_BOOL stp_check_crc(UINT8 *buffer, UINT32 length, UINT16 crc) -+{ -+ /*----------------------------------------------------------------*/ -+ /* Local Variables */ -+ /*----------------------------------------------------------------*/ -+ UINT16 checksum; -+ -+ /*----------------------------------------------------------------*/ -+ /* Code Body */ -+ /*----------------------------------------------------------------*/ -+ -+ /* FIXME: Add STP feature: check or skip crc */ -+ -+ checksum = osal_crc16(buffer, length); -+ if (checksum == crc) -+ return MTK_WCN_BOOL_TRUE; -+ -+ STP_ERR_FUNC("CRC fail, length = %d, rx = %x, calc = %x \r\n", length, crc, checksum); -+ return MTK_WCN_BOOL_FALSE; -+ -+} -+ -+/***************************************************************************** -+* FUNCTION -+* stp_update_tx_queue -+* DESCRIPTION -+* update packet's ACK field -+* PARAMETERS -+* txseq [IN] index of the tx packet which we want to update -+* RETURNS -+* void -+*****************************************************************************/ -+static void stp_update_tx_queue(UINT32 txseq) -+{ -+ INT32 tx_read, i; -+ UINT8 checksum = 0; -+ -+ tx_read = stp_core_ctx.tx_start_addr[txseq]; -+ stp_core_ctx.tx_buf[tx_read] &= 0xf8; -+ stp_core_ctx.tx_buf[tx_read] |= stp_core_ctx.sequence.txack; -+ -+ for (i = 0; i < 3; i++) { -+ checksum += stp_core_ctx.tx_buf[tx_read]; -+ tx_read++; -+ if (tx_read >= MTKSTP_BUFFER_SIZE) -+ tx_read -= MTKSTP_BUFFER_SIZE; -+ -+ } -+ -+ stp_core_ctx.tx_buf[tx_read] = checksum; -+ -+} -+ -+/***************************************************************************** -+* FUNCTION -+* stp_rest_ctx_state -+* DESCRIPTION -+* Reset stp context state variables only. Mutex and timer resources are not touched. -+* -+* PARAMETERS -+* void -+* RETURNS -+* void -+*****************************************************************************/ -+static VOID stp_rest_ctx_state(VOID) -+{ -+ INT32 i; -+ -+ /* osal_lock_unsleepable_lock(&stp_core_ctx.stp_mutex); */ -+ stp_ctx_lock(&stp_core_ctx); -+ stp_core_ctx.rx_counter = 0; -+ -+ /*reset rx buffer pointer */ -+ for (i = 0; i < MTKSTP_MAX_TASK_NUM; i++) { -+ stp_core_ctx.ring[i].read_p = 0; -+ stp_core_ctx.ring[i].write_p = 0; -+ } -+ -+ /*reset tx buffer pointer */ -+ stp_core_ctx.tx_write = 0; -+ stp_core_ctx.tx_read = 0; -+ -+ /*reset STP protocol context */ -+ stp_core_ctx.parser.state = MTKSTP_SYNC; -+ stp_core_ctx.sequence.txseq = 0; -+ stp_core_ctx.sequence.txack = 7; -+ stp_core_ctx.sequence.rxack = 7; -+ stp_core_ctx.sequence.winspace = MTKSTP_WINSIZE; -+ stp_core_ctx.sequence.expected_rxseq = 0; -+ stp_core_ctx.sequence.retry_times = 0; -+ stp_core_ctx.inband_rst_set = 0; -+ -+ /* osal_unlock_unsleepable_lock(&stp_core_ctx.stp_mutex); */ -+ stp_ctx_unlock(&stp_core_ctx); -+} -+ -+/***************************************************************************** -+* FUNCTION -+* stp_change_rx_state -+* DESCRIPTION -+* change the rx fsm of STP to "next" -+* PARAMETERS -+* next [IN] the next state of rx fsm -+* RETURNS -+* void -+*****************************************************************************/ -+static VOID stp_change_rx_state(mtkstp_parser_state next) -+{ -+ prev_state = stp_core_ctx.parser.state; -+ stp_core_ctx.parser.state = next; -+ -+} -+ -+/* static void stp_tx_timeout_handler(void){ */ -+static void stp_tx_timeout_handler(/*unsigned long data*/struct timer_list *t) -+{ -+ STP_WARN_FUNC("call retry btm retry wq ...\n"); -+ /*shorten the softirq lattency */ -+ stp_btm_notify_stp_retry_wq(STP_BTM_CORE(stp_core_ctx)); -+ STP_WARN_FUNC("call retry btm retry wq ...#\n"); -+} -+ -+VOID stp_do_tx_timeout(VOID) -+{ -+ UINT32 seq; -+ UINT32 ret; -+ INT32 iRet; -+ ENUM_STP_FW_ISSUE_TYPE issue_type; -+ UINT8 resync[4]; -+ -+ STP_WARN_FUNC("==============================================================================\n"); -+ -+ /* osal_lock_unsleepable_lock(&stp_core_ctx.stp_mutex); */ -+ stp_ctx_lock(&stp_core_ctx); -+ -+#if STP_RETRY_OPTIMIZE -+ if ((g_retry_times != 0) && (stp_core_ctx.sequence.retry_times == 0)) { -+ STP_INFO_FUNC("STP TX timeout has been recoveryed by resend,record_retry_time(%d)\n", g_retry_times); -+ g_retry_times = 0; -+ stp_ctx_unlock(&stp_core_ctx); -+ return; -+ } -+#endif -+ if (stp_core_ctx.sequence.retry_times > (MTKSTP_RETRY_LIMIT)) { -+ STP_INFO_FUNC("STP retry times(%d) have reached retry limit,stop it\n", -+ stp_core_ctx.sequence.retry_times); -+ stp_ctx_unlock(&stp_core_ctx); -+ return; -+ } -+#if STP_RETRY_OPTIMIZE -+ else -+ STP_DBG_FUNC("current TX timeout package has not received ACK yet,retry_times(%d)\n", -+ g_retry_times); -+#endif -+ /*polling cpupcr when no ack occurs at first retry */ -+ stp_notify_btm_poll_cpupcr(STP_BTM_CORE(stp_core_ctx), STP_POLL_CPUPCR_NUM, STP_POLL_CPUPCR_DELAY); -+ -+ seq = stp_core_ctx.sequence.rxack; -+ INDEX_INC(seq); -+ -+ if (seq != stp_core_ctx.sequence.txseq) { -+ osal_memset(&resync[0], 127, 4); -+ (*sys_if_tx) (&resync[0], 4, &ret); -+ if (ret != 4) { -+ STP_ERR_FUNC("mtkstp_tx_timeout_handler: send resync fail\n"); -+ osal_assert(0); -+ } -+ -+ do { -+ STP_WARN_FUNC("[stp.ctx]*rxack (=last rx ack) = %d\n\r", stp_core_ctx.sequence.rxack); -+ STP_WARN_FUNC("[stp.ctx]txack (=last rx seq)= %d\n\r", stp_core_ctx.sequence.txack); -+ STP_WARN_FUNC("[stp.ctx]*txseq (=next tx seq)= %d\n\r", stp_core_ctx.sequence.txseq); -+ STP_WARN_FUNC("Resend STP packet from %d -> %d\n\r", seq, -+ (stp_core_ctx.sequence.txseq <= 0) ? (7) : (stp_core_ctx.sequence.txseq - 1)); -+ stp_dump_tx_queue(seq); -+ -+ stp_send_tx_queue(seq); -+ INDEX_INC(seq); -+ } while (seq != stp_core_ctx.sequence.txseq); -+ -+ } -+ -+ osal_timer_stop(&stp_core_ctx.tx_timer); -+ osal_timer_start(&stp_core_ctx.tx_timer, mtkstp_tx_timeout); -+ -+ if (stp_core_ctx.sequence.winspace == MTKSTP_WINSIZE) { -+ osal_timer_stop(&stp_core_ctx.tx_timer); -+ STP_ERR_FUNC("mtkstp_tx_timeout_handler: wmt_stop_timer\n"); -+ } else { -+ stp_core_ctx.sequence.retry_times++; -+ STP_ERR_FUNC("mtkstp_tx_timeout_handler, retry = %d\n", stp_core_ctx.sequence.retry_times); -+#if STP_RETRY_OPTIMIZE -+ g_retry_times = stp_core_ctx.sequence.retry_times; -+#endif -+ /*If retry too much, try to recover STP by return back to initializatin state */ -+ /*And not to retry again */ -+ if (stp_core_ctx.sequence.retry_times > MTKSTP_RETRY_LIMIT) { -+#if STP_RETRY_OPTIMIZE -+ g_retry_times = 0; -+#endif -+ osal_timer_stop(&stp_core_ctx.tx_timer); -+ stp_ctx_unlock(&stp_core_ctx); -+ -+ STP_ERR_FUNC("mtkstp_tx_timeout_handler: wmt_stop_timer\n"); -+ -+ STP_ERR_FUNC("TX retry limit = %d\n", MTKSTP_RETRY_LIMIT); -+ osal_assert(0); -+ mtk_wcn_stp_dbg_dump_package(); -+ -+ /*Whole Chip Reset Procedure Invoke */ -+ /*if(STP_NOT_ENABLE_DBG(stp_core_ctx)) */ -+ -+ if (0 == mtk_wcn_stp_get_wmt_evt_err_trg_assert()) { -+ stp_psm_disable(STP_PSM_CORE(stp_core_ctx)); -+ mtk_wcn_stp_set_wmt_evt_err_trg_assert(1); -+ stp_dbg_set_host_assert_info(4, 36, 1); -+ STP_INFO_FUNC("**STP NoAck trigger firmware assert**\n"); -+ iRet = stp_notify_btm_do_fw_assert_via_emi(STP_BTM_CORE(stp_core_ctx)); -+ -+ if (iRet) { -+ STP_ERR_FUNC("host tigger fw assert fail(%d), do noack handle flow\n", iRet); -+ mtk_wcn_stp_set_wmt_evt_err_trg_assert(0); -+ issue_type = STP_FW_NOACK_ISSUE; -+ iRet = stp_dbg_set_fw_info("STP NoAck", osal_strlen("STP NoAck"), issue_type); -+ -+ osal_dbg_assert_aee("[SOC_CONNSYS]NoAck", -+ "**[WCN_ISSUE_INFO]STP Tx Timeout**\n F/W has NO any RESPONSE. Please check F/W status first\n"); -+ if (STP_IS_ENABLE_RST(stp_core_ctx)) { -+ STP_SET_READY(stp_core_ctx, 0); -+ stp_btm_notify_wmt_rst_wq(STP_BTM_CORE(stp_core_ctx)); -+ } else { -+ STP_INFO_FUNC("No to launch whole chip reset! for debugging purpose\n"); -+ } -+ } -+ } else { -+ STP_INFO_FUNC("do trigger assert & chip reset in wmt\n"); -+ } -+ return; -+ } -+ } -+ -+ /* osal_unlock_unsleepable_lock(&stp_core_ctx.stp_mutex); */ -+ stp_ctx_unlock(&stp_core_ctx); -+ STP_WARN_FUNC("==============================================================================#\n"); -+} -+ -+static VOID stp_dump_data(const UINT8 *buf, const UINT8 *title, const UINT32 len) -+{ -+ osal_buffer_dump(buf, title, len, 32); -+} -+ -+/***************************************************************************** -+ * FUNCTION -+ * stp_tx_timeout_handler -+ * DESCRIPTION -+ * tx timeout handler, send resync & retransmitt -+ * PARAMETERS -+ * void -+ * RETURNS -+ * void -+ *****************************************************************************/ -+static VOID stp_dump_tx_queue(UINT32 txseq) -+{ -+ INT32 tx_read, tx_length, last_len; -+ -+ tx_read = stp_core_ctx.tx_start_addr[txseq]; -+ tx_length = stp_core_ctx.tx_length[txseq]; -+ -+ STP_ERR_FUNC("tx_seq=%d ..", txseq); -+ -+ if (tx_read + tx_length < MTKSTP_BUFFER_SIZE) { -+ stp_dump_data(&stp_core_ctx.tx_buf[tx_read], "tx_q", (tx_length >= 8) ? (8) : (tx_length)); -+ } else { -+ last_len = MTKSTP_BUFFER_SIZE - tx_read; -+ stp_dump_data(&stp_core_ctx.tx_buf[tx_read], "tx_q_0", (last_len >= 8) ? (8) : (last_len)); -+ stp_dump_data(&stp_core_ctx.tx_buf[0], "tx_q_0", -+ ((tx_length - last_len) ? (8) : (tx_length - last_len))); -+ } -+} -+ -+/***************************************************************************** -+* FUNCTION -+* stp_is_apply_powersaving -+* DESCRIPTION -+* Check if STP support power saving mode. -+* PARAMETERS -+* -+* RETURNS -+* True: support power saving False: not support power saving -+*****************************************************************************/ -+static INT32 stp_is_apply_powersaving(VOID) -+{ -+ -+ if (STP_IS_READY(stp_core_ctx) && !stp_psm_is_disable(STP_PSM_CORE(stp_core_ctx))) { -+ /* osal_dbg_print("apply power saving\n"); */ -+ return MTK_WCN_BOOL_TRUE; -+ } -+ if (mtk_wcn_stp_is_sdio_mode()) -+ return MTK_WCN_BOOL_FALSE; -+ -+ STP_DBG_FUNC("not apply power saving\n"); -+ return MTK_WCN_BOOL_FALSE; -+} -+#if 0 -+/***************************************************************************** -+* FUNCTION -+* stp_is_privileges_cmd -+* DESCRIPTION -+* Check if the data is privilege command -+* PARAMETERS -+* -+* RETURNS -+* True/False -+*****************************************************************************/ -+static INT32 stp_is_privileges_cmd(const UINT8 *buffer, const UINT32 length, const UINT8 type) -+{ -+ typedef struct privileges_cmd { -+ UINT32 length; -+ UINT8 type; -+ UINT8 buf[7]; /* MAX length of target command is only 5 currently */ -+ } p_cmd_t; -+ -+ p_cmd_t p_cmd_table[] = { -+ {0x05, WMT_TASK_INDX, {0x01, 0x03, 0x01, 0x00, 0x01} }, /* sleep command */ -+ {0x05, WMT_TASK_INDX, {0x01, 0x03, 0x01, 0x00, 0x02} }, /* host_awake command */ -+ }; -+ -+ UINT32 i; -+ UINT32 size = sizeof(p_cmd_table) / sizeof(p_cmd_table[0]); -+ -+ for (i = 0; i < size; i++) { -+ if (type != p_cmd_table[i].type) -+ continue; -+ -+ if (length != p_cmd_table[i].length) -+ continue; -+ -+ if (osal_memcmp(p_cmd_table[i].buf, buffer, length)) -+ continue; -+ -+ /* matched entry is found */ -+ STP_DBG_FUNC("It's p_cmd_t\n"); -+ return MTK_WCN_BOOL_TRUE; -+ } -+ -+ return MTK_WCN_BOOL_FALSE; -+} -+#endif -+/***************************************************************************** -+* FUNCTION -+* tx_queue_room_available -+* DESCRIPTION -+* check room if available, -+* PARAMETERS -+* buffer [IN] data buffer -+* length [IN] data buffer length -+* RETURNS -+* void -+*****************************************************************************/ -+static MTK_WCN_BOOL stp_is_tx_res_available(UINT32 length) -+{ -+ UINT32 roomLeft; -+ -+ /* -+ Get available space of TX Queue -+ */ -+ if (stp_core_ctx.tx_read <= stp_core_ctx.tx_write) -+ roomLeft = MTKSTP_BUFFER_SIZE - stp_core_ctx.tx_write + stp_core_ctx.tx_read - 1; -+ else -+ roomLeft = stp_core_ctx.tx_read - stp_core_ctx.tx_write - 1; -+ -+ if (roomLeft < length) { -+ STP_ERR_FUNC("%s: tx queue room shortage\n", __func__); -+ return MTK_WCN_BOOL_FALSE; -+ } else -+ return MTK_WCN_BOOL_TRUE; -+} -+ -+/***************************************************************************** -+* FUNCTION -+* stp_add_to_tx_queue -+* DESCRIPTION -+* put data to tx queue -+* PARAMETERS -+* buffer [IN] data buffer -+* length [IN] data buffer length -+* RETURNS -+* void -+*****************************************************************************/ -+static VOID stp_add_to_tx_queue(const UINT8 *buffer, UINT32 length) -+{ -+ UINT32 last_len; -+ -+ /* Get available space of TX Queue */ -+ if (length + stp_core_ctx.tx_write < MTKSTP_BUFFER_SIZE) { -+ osal_memcpy(stp_core_ctx.tx_buf + stp_core_ctx.tx_write, buffer, length); -+ stp_core_ctx.tx_write += length; -+ } else { -+ last_len = MTKSTP_BUFFER_SIZE - stp_core_ctx.tx_write; -+ osal_memcpy(stp_core_ctx.tx_buf + stp_core_ctx.tx_write, buffer, last_len); -+ osal_memcpy(stp_core_ctx.tx_buf, buffer + last_len, length - last_len); -+ -+ stp_core_ctx.tx_write = length - last_len; -+ } -+ -+} -+ -+/***************************************************************************** -+* FUNCTION -+* stp_add_to_rx_queue -+* DESCRIPTION -+* put data to corresponding task's rx queue and notify corresponding task -+* PARAMETERS -+* buffer [IN] data buffer -+* length [IN] data buffer length -+* type [IN] corresponding task index -+* RETURNS -+* INT32 0=success, others=error -+*****************************************************************************/ -+static INT32 stp_add_to_rx_queue(UINT8 *buffer, UINT32 length, UINT8 type) -+{ -+ UINT32 roomLeft, last_len; -+ -+ osal_lock_unsleepable_lock(&stp_core_ctx.ring[type].mtx); -+ -+ if (stp_core_ctx.ring[type].read_p <= stp_core_ctx.ring[type].write_p) -+ roomLeft = MTKSTP_BUFFER_SIZE - stp_core_ctx.ring[type].write_p + stp_core_ctx.ring[type].read_p - 1; -+ else -+ roomLeft = stp_core_ctx.ring[type].read_p - stp_core_ctx.ring[type].write_p - 1; -+ -+ if (roomLeft < length) { -+ osal_unlock_unsleepable_lock(&stp_core_ctx.ring[type].mtx); -+ STP_ERR_FUNC("Queue is full !!!, type = %d\n", type); -+ osal_assert(0); -+ return -1; -+ } -+ -+ if (length + stp_core_ctx.ring[type].write_p < MTKSTP_BUFFER_SIZE) { -+ osal_memcpy(stp_core_ctx.ring[type].buffer + stp_core_ctx.ring[type].write_p, buffer, length); -+ stp_core_ctx.ring[type].write_p += length; -+ } else { -+ last_len = MTKSTP_BUFFER_SIZE - stp_core_ctx.ring[type].write_p; -+ osal_memcpy(stp_core_ctx.ring[type].buffer + stp_core_ctx.ring[type].write_p, buffer, last_len); -+ osal_memcpy(stp_core_ctx.ring[type].buffer, buffer + last_len, length - last_len); -+ stp_core_ctx.ring[type].write_p = length - last_len; -+ } -+ -+ osal_unlock_unsleepable_lock(&stp_core_ctx.ring[type].mtx); -+ -+ return 0; -+} -+ -+/***************************************************************************** -+* FUNCTION -+* stp_send_tx_queue -+* DESCRIPTION -+* send data in tx buffer to common interface -+* PARAMETERS -+* txseq [IN] sequence number of outgoing packet in tx buffer -+* RETURNS -+* void -+*****************************************************************************/ -+static VOID stp_send_tx_queue(UINT32 txseq) -+{ -+ UINT32 ret; -+ INT32 tx_read, tx_length, last_len; -+ -+ tx_read = stp_core_ctx.tx_start_addr[txseq]; -+ tx_length = stp_core_ctx.tx_length[txseq]; -+ -+ stp_update_tx_queue(txseq); -+ -+ if (tx_read + tx_length < MTKSTP_BUFFER_SIZE) { -+ -+ (*sys_if_tx) (&stp_core_ctx.tx_buf[tx_read], tx_length, &ret); -+ -+ if (ret != tx_length) { -+ STP_ERR_FUNC("stp_send_tx_queue, %d/%d\n", tx_length, ret); -+ osal_assert(0); -+ } -+ } else { -+ last_len = MTKSTP_BUFFER_SIZE - tx_read; -+ (*sys_if_tx) (&stp_core_ctx.tx_buf[tx_read], last_len, &ret); -+ -+ if (ret != last_len) { -+ STP_ERR_FUNC("stp_send_tx_queue, %d/%d\n", last_len, ret); -+ osal_assert(0); -+ } -+ -+ (*sys_if_tx) (&stp_core_ctx.tx_buf[0], tx_length - last_len, &ret); -+ -+ if (ret != tx_length - last_len) { -+ STP_ERR_FUNC("stp_send_tx_queue, %d/%d\n", tx_length - last_len, ret); -+ osal_assert(0); -+ } -+ } -+ -+} -+ -+/***************************************************************************** -+* FUNCTION -+* stp_send_ack -+* DESCRIPTION -+* send ack packet to the peer -+* PARAMETERS -+* txAck [IN] Ack number -+* nak [IN] 0 = ack; !0 = NAK -+* RETURNS -+* void -+*****************************************************************************/ -+static VOID stp_send_ack(UINT8 txAck, UINT8 nak) -+{ -+ UINT8 mtkstp_header[MTKSTP_HEADER_SIZE]; -+ UINT32 ret; -+ INT32 iStatus; -+ -+ mtkstp_header[0] = 0x80 + (0 << 3) + txAck; /* stp_core_ctx.sequence.txack; */ -+ -+ if (fgEnableNak == 0) -+ mtkstp_header[1] = 0x00; /* disable NAK */ -+ else -+ mtkstp_header[1] = ((nak == 0) ? 0x00 : 0x80); -+ -+ mtkstp_header[2] = 0; -+ mtkstp_header[3] = (mtkstp_header[0] + mtkstp_header[1] + mtkstp_header[2]) & 0xff; -+ -+ stp_dbg_pkt_log(STP_TASK_INDX, txAck, 0, 0, PKT_DIR_TX, NULL, 0); -+ -+ if (fgEnableDelimiter == 1) { -+ iStatus = (*sys_if_tx) ((PUINT8) &stp_delimiter[0], STP_DEL_SIZE, &ret); -+ STP_DUMP_PACKET_HEAD((PUINT8) &stp_delimiter[0], "tx del", STP_DEL_SIZE); -+ if (ret != STP_DEL_SIZE) { -+ STP_ERR_FUNC("stp_send_ack, %d/%d status %d\n", STP_DEL_SIZE, ret, iStatus); -+ osal_assert(0); -+ } -+ } -+ -+ iStatus = (*sys_if_tx) (&mtkstp_header[0], MTKSTP_HEADER_SIZE, &ret); -+ -+ if (ret != MTKSTP_HEADER_SIZE) { -+ STP_ERR_FUNC("stp_send_ack, %d/%d status %d\n", MTKSTP_HEADER_SIZE, ret, iStatus); -+ osal_assert(0); -+ } -+ -+} -+ -+INT32 stp_send_data_no_ps(UINT8 *buffer, UINT32 length, UINT8 type) -+{ -+ UINT8 mtkstp_header[MTKSTP_HEADER_SIZE], temp[2]; -+ UINT8 *p_tx_buf = NULL; -+ UINT16 crc; -+ INT32 ret = 0; -+ -+ /* osal_lock_unsleepable_lock(&stp_core_ctx.stp_mutex); */ -+ stp_ctx_lock(&stp_core_ctx); -+ -+ /*Only WMT can set raw data */ -+ if (STP_NOT_ENABLE(stp_core_ctx) && WMT_TASK_INDX != type) { -+ /* no op */ -+ /* NULL; */ -+ } else if (STP_NOT_ENABLE(stp_core_ctx) && WMT_TASK_INDX == type) { -+ /* ret = mtk_wcn_stp_send_data_raw(buffer, length, type); */ -+ /* NULL; */ -+ } -+ /* STP over SDIO */ -+ else if ((mtk_wcn_stp_is_sdio_mode() || mtk_wcn_stp_is_btif_mand_mode()) && STP_IS_ENABLE(stp_core_ctx)) { -+ osal_printtimeofday("[ STP][SDIO][ B][W]"); -+ -+ mtkstp_header[0] = 0x80; -+ mtkstp_header[1] = (type << 4) + (((length) >> 8) & 0x0f); -+ mtkstp_header[2] = (length) & 0xff; -+ mtkstp_header[3] = 0x00; -+ -+ p_tx_buf = &stp_core_ctx.tx_buf[0]; -+ osal_memcpy(p_tx_buf, mtkstp_header, MTKSTP_HEADER_SIZE); -+ p_tx_buf += MTKSTP_HEADER_SIZE; -+ -+ osal_memcpy(p_tx_buf, buffer, length); -+ p_tx_buf += length; -+ -+ temp[0] = 0x00; -+ temp[1] = 0x00; -+ osal_memcpy(p_tx_buf, temp, 2); -+ stp_dbg_pkt_log(type, -+ stp_core_ctx.sequence.txack, -+ stp_core_ctx.sequence.txseq, 0, PKT_DIR_TX, buffer, length); -+ (*sys_if_tx) (&stp_core_ctx.tx_buf[0], (MTKSTP_HEADER_SIZE + length + 2), &ret); -+ if ((MTKSTP_HEADER_SIZE + length + 2) != ret) { -+ STP_ERR_FUNC("stp send tx packet: %d, maybe stp_if_tx == NULL\n", ret); -+ osal_assert(0); -+ ret = 0; -+ } else { -+ ret = (INT32) length; -+ } -+ -+ osal_printtimeofday("[ STP][SDIO][ E][W]"); -+ } -+ /* STP over BTIF OR UART */ -+ else if ((mtk_wcn_stp_is_btif_fullset_mode()) && STP_IS_ENABLE(stp_core_ctx)) { -+ -+ if ((stp_core_ctx.sequence.winspace > 0) && -+ (stp_is_tx_res_available(MTKSTP_HEADER_SIZE + length + MTKSTP_CRC_SIZE))) { -+ mtkstp_header[0] = 0x80 + (stp_core_ctx.sequence.txseq << 3) + stp_core_ctx.sequence.txack; -+ mtkstp_header[1] = (type << 4) + ((length & 0xf00) >> 8); -+ mtkstp_header[2] = length & 0xff; -+ mtkstp_header[3] = (mtkstp_header[0] + mtkstp_header[1] + mtkstp_header[2]) & 0xff; -+ -+ stp_core_ctx.tx_start_addr[stp_core_ctx.sequence.txseq] = stp_core_ctx.tx_write; -+ stp_core_ctx.tx_length[stp_core_ctx.sequence.txseq] = MTKSTP_HEADER_SIZE + length + 2; -+ -+ if (fgEnableDelimiter == 1) { -+ stp_core_ctx.tx_length[stp_core_ctx.sequence.txseq] += STP_DEL_SIZE; -+ stp_add_to_tx_queue(&stp_delimiter[0], STP_DEL_SIZE); -+ } -+ -+ stp_add_to_tx_queue(mtkstp_header, MTKSTP_HEADER_SIZE); -+ -+ /*Make Payload */ -+ stp_add_to_tx_queue(buffer, length); -+ -+ /*Make CRC */ -+ crc = osal_crc16(buffer, length); -+ temp[0] = crc & 0xff; -+ temp[1] = (crc & 0xff00) >> 8; -+ stp_add_to_tx_queue(temp, 2); -+ -+ stp_dbg_pkt_log(type, -+ stp_core_ctx.sequence.txack, -+ stp_core_ctx.sequence.txseq, crc, PKT_DIR_TX, buffer, length); -+ -+ /*Kick to UART */ -+ stp_send_tx_queue(stp_core_ctx.sequence.txseq); -+ INDEX_INC(stp_core_ctx.sequence.txseq); -+ stp_core_ctx.sequence.winspace--; -+ -+ /*Setup the Retry Timer */ -+ osal_timer_stop(&stp_core_ctx.tx_timer); -+ if (stp_core_ctx.sequence.winspace != MTKSTP_WINSIZE) -+ osal_timer_start(&stp_core_ctx.tx_timer, mtkstp_tx_timeout); -+ else -+ STP_ERR_FUNC("mtk_wcn_stp_send_data: wmt_stop_timer\n"); -+ -+ ret = (INT32) length; -+ } else { -+ /* No winspace to send. Let caller retry */ -+ STP_ERR_FUNC("%s: There is no winspace/txqueue to send !!!\n", __func__); -+ ret = 0; -+ } -+ } -+ -+ stp_ctx_unlock(&stp_core_ctx); -+ /* osal_unlock_unsleepable_lock(&stp_core_ctx.stp_mutex); */ -+ -+ return ret; -+} -+ -+/***************************************************************************** -+* FUNCTION -+* stp_process_rxack -+* DESCRIPTION -+* process ack packet -+* PARAMETERS -+* void -+* RETURNS -+* INT32 0=success, others=error -+*****************************************************************************/ -+static INT32 stp_process_rxack(VOID) -+{ -+ INT32 j, k; -+ UINT8 rxack; -+ INT32 fgResult = (-1); -+ -+ if (stp_core_ctx.sequence.rxack != stp_core_ctx.parser.ack) { -+ j = k = 0; -+ rxack = stp_core_ctx.sequence.rxack; -+ INDEX_INC(rxack); -+ while (rxack != stp_core_ctx.sequence.txseq) { -+ j++; -+ if (rxack == stp_core_ctx.parser.ack) { -+ k = 1; -+ break; -+ } -+ INDEX_INC(rxack); -+ } -+ if (k == 1) { -+ stp_core_ctx.sequence.rxack = stp_core_ctx.parser.ack; -+ stp_core_ctx.tx_read = stp_core_ctx.tx_start_addr[rxack] + stp_core_ctx.tx_length[rxack]; -+ if (stp_core_ctx.tx_read >= MTKSTP_BUFFER_SIZE) -+ stp_core_ctx.tx_read -= MTKSTP_BUFFER_SIZE; -+ -+ stp_core_ctx.sequence.winspace += j; -+ stp_core_ctx.sequence.retry_times = 0; -+ -+ osal_timer_stop(&stp_core_ctx.tx_timer); -+ if (stp_core_ctx.sequence.winspace != MTKSTP_WINSIZE) -+ osal_timer_start(&stp_core_ctx.tx_timer, mtkstp_tx_timeout); -+ -+ fgResult = 0; -+ } -+ } -+ -+ return fgResult; -+} -+ -+/***************************************************************************** -+* FUNCTION -+* stp_process_packet -+* DESCRIPTION -+* process STP packet -+* PARAMETERS -+* void -+* RETURNS -+* void -+*****************************************************************************/ -+static VOID stp_process_packet(VOID) -+{ -+ INT32 fgTriggerResume = (-1); -+ UINT8 txAck = 0; -+ static INT32 fgRxOk; -+ MTK_WCN_BOOL b; -+ MTK_WCN_BOOL is_function_active = 0; -+ static INT32 stp_process_packet_fail_count; -+ INT32 iRet = -1; -+ -+ stp_dbg_pkt_log(stp_core_ctx.parser.type, -+ stp_core_ctx.parser.ack, -+ stp_core_ctx.parser.seq, -+ stp_core_ctx.parser.crc, PKT_DIR_RX, stp_core_ctx.rx_buf, stp_core_ctx.parser.length); -+ /*Optimization */ -+ /*If bluez, direct send packet to hci_core not through RX buffer! */ -+ if ((stp_core_ctx.sequence.expected_rxseq == stp_core_ctx.parser.seq) && -+ (stp_core_ctx.parser.type == BT_TASK_INDX) && STP_BT_STK_IS_BLUEZ(stp_core_ctx)) { -+ /*Indicate packet to hci_stp */ -+ STP_DBG_FUNC("Send Packet to BT_SUBFUCTION, len = %d\n", stp_core_ctx.rx_counter); -+ -+ b = mtk_wcn_sys_if_rx(stp_core_ctx.rx_buf, stp_core_ctx.rx_counter); -+ if (b) -+ STP_ERR_FUNC("mtk_wcn_sys_if_rx is NULL\n"); -+ -+ /* osal_lock_unsleepable_lock(&stp_core_ctx.stp_mutex); */ -+ stp_ctx_lock(&stp_core_ctx); -+ /*Process rx ack */ -+ fgTriggerResume = stp_process_rxack(); -+ stp_core_ctx.sequence.txack = stp_core_ctx.parser.seq; -+ INDEX_INC(stp_core_ctx.sequence.expected_rxseq); -+ txAck = stp_core_ctx.sequence.txack; -+ -+ /*Send ack back */ -+ stp_send_ack(txAck, 0); -+ -+ /* osal_unlock_unsleepable_lock(&stp_core_ctx.stp_mutex); */ -+ stp_ctx_unlock(&stp_core_ctx); -+ fgRxOk = 0; -+ } -+ /* sequence matches expected, enqueue packet */ -+ else if (stp_core_ctx.sequence.expected_rxseq == stp_core_ctx.parser.seq) { -+ is_function_active = -+ ((*sys_check_function_status) (stp_core_ctx.parser.type, OP_FUNCTION_ACTIVE) == -+ STATUS_FUNCTION_ACTIVE); -+ /*If type is valid and function works, then try to enqueue */ -+ if ((stp_core_ctx.parser.type < MTKSTP_MAX_TASK_NUM) && (is_function_active == MTK_WCN_BOOL_TRUE)) { -+ if (stp_core_ctx.parser.type == BT_TASK_INDX) { -+ static const UINT8 rst_buf[7] = { 0x04, 0x0e, 0x04, 0x01, 0x3, 0xc, 0x00 }; -+ -+ if (!osal_strncmp(stp_core_ctx.rx_buf, rst_buf, 7)) -+ osal_printtimeofday("############ BT Rest end <--"); -+ } -+ -+ stp_ctx_lock(&stp_core_ctx); -+ -+ fgTriggerResume = stp_process_rxack(); -+ stp_core_ctx.sequence.txack = stp_core_ctx.parser.seq; -+ INDEX_INC(stp_core_ctx.sequence.expected_rxseq); -+ -+ /*Send tx ack */ -+ txAck = stp_core_ctx.sequence.txack; -+ stp_send_ack(txAck, 0); -+ -+ stp_ctx_unlock(&stp_core_ctx); -+#if CFG_WMT_LTE_COEX_HANDLING -+ if ((stp_core_ctx.parser.type == WMT_TASK_INDX) && -+ (stp_core_ctx.parser.wmtsubtype == WMT_LTE_COEX_FLAG)) { -+ fgRxOk = -+ stp_add_to_rx_queue(stp_core_ctx.rx_buf, stp_core_ctx.rx_counter, COEX_TASK_INDX); -+ } else { -+ fgRxOk = -+ stp_add_to_rx_queue(stp_core_ctx.rx_buf, stp_core_ctx.rx_counter, -+ stp_core_ctx.parser.type); -+ } -+#else -+ if ((stp_core_ctx.parser.type == WMT_TASK_INDX) && -+ (stp_core_ctx.parser.wmtsubtype == WMT_LTE_COEX_FLAG)) { -+ STP_WARN_FUNC("BT/WIFI & LTE coex in non-LTE projects,drop it...\n"); -+ } else { -+ fgRxOk = -+ stp_add_to_rx_queue(stp_core_ctx.rx_buf, stp_core_ctx.rx_counter, -+ stp_core_ctx.parser.type); -+ } -+#endif -+ } else { -+ if (is_function_active == MTK_WCN_BOOL_FALSE) { -+ STP_ERR_FUNC("function type = %d is inactive, so no en-queue to rx\n", -+ stp_core_ctx.parser.type); -+ fgRxOk = 0; /*drop packet */ -+ } else { -+ STP_ERR_FUNC("mtkstp_process_packet: type = %x, the type is invalid\n", -+ stp_core_ctx.parser.type); -+ fgRxOk = 0; /*drop packet */ -+ } -+ stp_ctx_lock(&stp_core_ctx); -+ -+ fgTriggerResume = stp_process_rxack(); -+ stp_core_ctx.sequence.txack = stp_core_ctx.parser.seq; -+ INDEX_INC(stp_core_ctx.sequence.expected_rxseq); -+ -+ /*Send tx ack */ -+ txAck = stp_core_ctx.sequence.txack; -+ stp_send_ack(txAck, 0); -+ -+ stp_ctx_unlock(&stp_core_ctx); -+ } -+ -+ /* enqueue successfully */ -+ if (fgRxOk == 0) { -+ stp_process_packet_fail_count = 0; -+ /*notify corresponding subfunction of incoming data */ -+#if CFG_WMT_LTE_COEX_HANDLING -+ if ((stp_core_ctx.parser.type == WMT_TASK_INDX) && -+ (stp_core_ctx.parser.wmtsubtype == WMT_LTE_COEX_FLAG)) { -+#if 1 -+ STP_DBG_FUNC -+ ("WMT/LTE package:[0x%2x][0x%2x][0x%2x][0x%2x][0x%2x][0x%2x][0x%2x][0x%2x]\n", -+ stp_core_ctx.rx_buf[0], stp_core_ctx.rx_buf[1], stp_core_ctx.rx_buf[2], -+ stp_core_ctx.rx_buf[3], stp_core_ctx.rx_buf[4], stp_core_ctx.rx_buf[5], -+ stp_core_ctx.rx_buf[6], stp_core_ctx.rx_buf[7]); -+#endif -+ stp_notify_btm_handle_wmt_lte_coex(STP_BTM_CORE(stp_core_ctx)); -+ } else { -+ (*sys_event_set) (stp_core_ctx.parser.type); -+ } -+#else -+ if ((stp_core_ctx.parser.type == WMT_TASK_INDX) && -+ (stp_core_ctx.parser.wmtsubtype == WMT_LTE_COEX_FLAG)) { -+ STP_WARN_FUNC("omit BT/WIFI & LTE coex msg handling in non-LTE projects\n"); -+ } else { -+ (*sys_event_set) (stp_core_ctx.parser.type); -+ } -+#endif -+ } else { -+ stp_process_packet_fail_count++; -+ /*Queue is full */ -+ if (stp_core_ctx.parser.type == GPS_TASK_INDX) { -+ /*Clear Rx Queue if GPS */ -+ mtk_wcn_stp_flush_rx_queue(GPS_TASK_INDX); -+ } else { -+ /*notify corresponding subfunction of incoming data */ -+ (*sys_event_set) (stp_core_ctx.parser.type); -+ } -+ /*enqueue fail, don't send ack and wait for peer retry */ -+ STP_ERR_FUNC("Enqueue to Rx queue fail, maybe function %d queue is full\n", -+ stp_core_ctx.parser.type); -+ } -+ } -+ /*sequence not match && previous packet enqueue successfully, send the previous ACK */ -+ else if (fgRxOk == 0) { -+ STP_ERR_FUNC("mtkstp_process_packet: expected_rxseq = %d, parser.seq = %d\n", -+ stp_core_ctx.sequence.expected_rxseq, stp_core_ctx.parser.seq); -+ stp_process_packet_fail_count++; -+ -+ stp_ctx_lock(&stp_core_ctx); -+ /* osal_lock_unsleepable_lock(&stp_core_ctx.stp_mutex); */ -+ txAck = stp_core_ctx.sequence.txack; -+ stp_send_ack(txAck, 1); -+ stp_ctx_unlock(&stp_core_ctx); -+ /* osal_unlock_unsleepable_lock(&stp_core_ctx.stp_mutex); */ -+ STP_ERR_FUNC -+ ("sequence not match && previous packet enqueue successfully, send the previous ACK (ack no =%d)\n", -+ txAck); -+ } -+ /*sequence not match && previous packet enqueue failed, do nothing, make the other side timeout */ -+ else { -+ stp_process_packet_fail_count++; -+ STP_ERR_FUNC -+ ("sequence not match && previous packet enqueue failed, do nothing, make the other side timeout\n"); -+ } -+ -+ if (fgTriggerResume == 0) { -+ /*[PatchNeed]Just Notificaiton, not blocking call */ -+ /* notify adaptation layer for possible tx resume mechanism */ -+ (*sys_event_tx_resume) (stp_core_ctx.sequence.winspace); -+ } -+ -+ if (stp_process_packet_fail_count > MTKSTP_RETRY_LIMIT) { -+ stp_process_packet_fail_count = 0; -+ STP_ERR_FUNC("The process packet fail count > 10 lastly\n\r, whole chip reset\n\r"); -+ mtk_wcn_stp_dbg_dump_package(); -+ /*Whole Chip Reset Procedure Invoke */ -+ /*if(STP_NOT_ENABLE_DBG(stp_core_ctx)) */ -+ if (0 == mtk_wcn_stp_get_wmt_evt_err_trg_assert()) { -+ stp_psm_disable(STP_PSM_CORE(stp_core_ctx)); -+ mtk_wcn_stp_set_wmt_evt_err_trg_assert(1); -+ stp_dbg_set_host_assert_info(4, 37, 1); -+ STP_INFO_FUNC("**Ack Miss trigger firmware assert**\n"); -+ iRet = stp_notify_btm_do_fw_assert_via_emi(STP_BTM_CORE(stp_core_ctx)); -+ if (iRet) { -+ mtk_wcn_stp_set_wmt_evt_err_trg_assert(0); -+ /* (*sys_dbg_assert_aee)("[MT662x]Ack Miss", "**STP Ack Miss**\n Ack Miss.\n"); */ -+ osal_dbg_assert_aee("[SOC_CONSYS]Ack Miss", -+ "**[WCN_ISSUE_INFO]STP Ack Miss**\n Ack Miss.\n"); -+ -+ if (STP_IS_ENABLE_RST(stp_core_ctx)) { -+ STP_SET_READY(stp_core_ctx, 0); -+ stp_btm_notify_wmt_rst_wq(STP_BTM_CORE(stp_core_ctx)); -+ } else { -+ STP_INFO_FUNC("No to launch whole chip reset! for debugging purpose\n"); -+ } -+ } -+ } -+ } -+ -+} -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_init -+* DESCRIPTION -+* init STP kernel -+* PARAMETERS -+* cb_func [IN] function pointers of system APIs -+* RETURNS -+* INT32 0 = success, others = failure -+*****************************************************************************/ -+INT32 mtk_wcn_stp_init(const mtkstp_callback * const cb_func) -+{ -+ INT32 ret = 0; -+ INT32 i = 0; -+ -+ /* Function pointer to point to the currently used transmission interface -+ */ -+ sys_if_tx = cb_func->cb_if_tx; -+ -+ /* Used to inform the function driver has received the corresponding type of information */ -+ sys_event_set = cb_func->cb_event_set; -+ -+ /* Used to inform the function driver can continue to send information and -+ STP has resources to deal with -+ */ -+ sys_event_tx_resume = cb_func->cb_event_tx_resume; -+ -+ /* STP driver determines whether the function is enable. If not enable and -+ STP has received the kind of information, and STP have the right to put it away. -+ */ -+ sys_check_function_status = cb_func->cb_check_funciton_status; -+ -+ /* osal_unsleepable_lock_init(&stp_core_ctx.stp_mutex); */ -+ stp_ctx_lock_init(&stp_core_ctx); -+ /* Setup timer to be used to check if f/w receive the data in the specific time -+ interval after being sent -+ */ -+ for (i = 0; i < MTKSTP_MAX_TASK_NUM; i++) -+ osal_unsleepable_lock_init(&stp_core_ctx.ring[i].mtx); -+ -+ stp_core_ctx.tx_timer.timeoutHandler = stp_tx_timeout_handler; -+ stp_core_ctx.tx_timer.timeroutHandlerData = 0; -+ osal_timer_create(&stp_core_ctx.tx_timer); -+ -+ STP_SET_BT_STK(stp_core_ctx, 0); -+ STP_SET_ENABLE(stp_core_ctx, 0); -+ STP_SET_ENABLE_DBG(stp_core_ctx, 0); -+ STP_SET_ENABLE_RST(stp_core_ctx, 0); -+ STP_SET_PENDING_TYPE(stp_core_ctx, 0); -+ STP_SET_READY(stp_core_ctx, 0); -+ STP_SET_SUPPORT_PROTOCOL(stp_core_ctx, 0); -+ STP_SET_PSM_CORE(stp_core_ctx, stp_psm_init()); -+ STP_SET_FW_COREDUMP_FLAG(stp_core_ctx, 0); -+ STP_ENABLE_FW_COREDUMP(stp_core_ctx, 0); -+ STP_SET_WMT_LAST_CLOSE(stp_core_ctx, 0); -+ STP_SET_EVT_ERR_ASSERT(stp_core_ctx, 0); -+ -+ if (!STP_PSM_CORE(stp_core_ctx)) { -+ ret = (-3); -+ goto ERROR; -+ } -+ -+ STP_SET_BTM_CORE(stp_core_ctx, stp_btm_init()); -+ if (!STP_BTM_CORE(stp_core_ctx)) { -+ STP_ERR_FUNC("STP_BTM_CORE(stp_core_ctx) initialization fail!\n"); -+ ret = (-3); -+ goto ERROR; -+ } -+ -+ if (STP_BTM_CORE(stp_core_ctx) != NULL) -+ g_mtkstp_dbg = stp_dbg_init(STP_BTM_CORE(stp_core_ctx)); -+ else -+ g_mtkstp_dbg = stp_dbg_init(NULL); -+ -+ if (!g_mtkstp_dbg) { -+ STP_ERR_FUNC("g_mtkstp_dbg initialization fail!\n"); -+ ret = (-3); -+ goto ERROR; -+ } -+ STP_SET_ENABLE_RST(stp_core_ctx, 1); -+#ifdef CONFIG_LOG_STP_INTERNAL -+ mtk_wcn_stp_dbg_enable(); -+#else -+ mtk_wcn_stp_dbg_enable(); -+#endif -+ goto RETURN; -+ -+ERROR: -+ stp_psm_deinit(STP_PSM_CORE(stp_core_ctx)); -+ -+RETURN: -+ return ret; -+ -+} -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_deinit -+* DESCRIPTION -+* deinit STP kernel -+* PARAMETERS -+* void -+* RETURNS -+* INT32 0 = success, others = failure -+*****************************************************************************/ -+INT32 mtk_wcn_stp_deinit(void) -+{ -+ UINT32 i = 0; -+ -+ sys_if_tx = NULL; -+ sys_event_set = NULL; -+ sys_event_tx_resume = NULL; -+ sys_check_function_status = NULL; -+ -+ stp_dbg_deinit(g_mtkstp_dbg); -+ stp_btm_deinit(STP_BTM_CORE(stp_core_ctx)); -+ stp_psm_deinit(STP_PSM_CORE(stp_core_ctx)); -+ -+ for (i = 0; i < MTKSTP_MAX_TASK_NUM; i++) -+ osal_unsleepable_lock_deinit(&stp_core_ctx.ring[i].mtx); -+ -+ stp_ctx_lock_deinit(&stp_core_ctx); -+ return 0; -+} -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_btm_get_dmp -+* DESCRIPTION -+* get stp dump related information -+* PARAMETERS -+* buffer: dump placement, len: dump size -+* RETURNS -+* 0: Success Negative Value: Fail -+*****************************************************************************/ -+ -+int mtk_wcn_stp_btm_get_dmp(char *buf, int *len) -+{ -+ return stp_dbg_dmp_out(g_mtkstp_dbg, buf, len); -+} -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_psm_notify_stp -+* DESCRIPTION -+* WMT notification to STP that power saving job is done or not -+* PARAMETERS -+* -+* RETURNS -+* 0: Sccuess Negative value: Fail -+*****************************************************************************/ -+int mtk_wcn_stp_psm_notify_stp(const MTKSTP_PSM_ACTION_T action) -+{ -+ return stp_psm_notify_stp(STP_PSM_CORE(stp_core_ctx), action); -+} -+ -+int mtk_wcn_stp_set_psm_state(MTKSTP_PSM_STATE_T state) -+{ -+ return stp_psm_set_state(STP_PSM_CORE(stp_core_ctx), state); -+} -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_psm_enable -+* DESCRIPTION -+* enable STP sleep/wakeup support -+* PARAMETERS -+* void -+* RETURNS -+* 0: Sccuess Negative value: Fail -+*****************************************************************************/ -+INT32 mtk_wcn_stp_psm_enable(INT32 idle_time_to_sleep) -+{ -+#if 0 -+ if (MTK_WCN_BOOL_TRUE == stp_psm_is_quick_ps_support()) { -+ if (mtk_wcn_stp_is_ready()) -+ return stp_psm_enable(STP_PSM_CORE(stp_core_ctx), idle_time_to_sleep); -+ STP_WARN_FUNC("STP Not Ready, Dont do Sleep/Wakeup\n"); -+ return -1; -+ } -+ if (mtk_wcn_stp_is_ready() && mtk_wcn_stp_is_btif_fullset_mode()) { -+ return stp_psm_enable(STP_PSM_CORE(stp_core_ctx), idle_time_to_sleep); -+ } else if (mtk_wcn_stp_is_sdio_mode()) { -+ stp_psm_enable(STP_PSM_CORE(stp_core_ctx), idle_time_to_sleep); -+ STP_DBG_FUNC("PSM is not support under SDIO mode\n"); -+ return 0; -+ } -+ STP_WARN_FUNC("STP Not Ready, Dont do Sleep/Wakeup\n"); -+ return -1; -+ -+#else -+ if (mtk_wcn_stp_is_ready() && mtk_wcn_stp_is_btif_fullset_mode()) { -+ return stp_psm_enable(STP_PSM_CORE(stp_core_ctx), idle_time_to_sleep); -+ } else if (mtk_wcn_stp_is_sdio_mode()) { -+ stp_psm_enable(STP_PSM_CORE(stp_core_ctx), idle_time_to_sleep); -+ STP_DBG_FUNC("PSM is not support under SDIO mode\n"); -+ return 0; -+ } -+ STP_WARN_FUNC("STP Not Ready, Dont do Sleep/Wakeup\n"); -+ return -1; -+#endif -+} -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_psm_disable -+* DESCRIPTION -+* disable STP sleep/wakeup support -+* PARAMETERS -+* void -+* RETURNS -+* 0: Sccuess Negative value: Fail -+*****************************************************************************/ -+extern INT32 mtk_wcn_stp_psm_disable(VOID) -+{ -+#if 0 -+ if (MTK_WCN_BOOL_TRUE == stp_psm_is_quick_ps_support()) { -+ if (mtk_wcn_stp_is_ready()) -+ return stp_psm_disable(STP_PSM_CORE(stp_core_ctx)); -+ STP_WARN_FUNC("STP Not Ready, Dont do Sleep/Wakeup\n"); -+ return -1; -+ } -+ if (mtk_wcn_stp_is_ready() && mtk_wcn_stp_is_btif_fullset_mode()) { -+ return stp_psm_disable(STP_PSM_CORE(stp_core_ctx)); -+ } else if (mtk_wcn_stp_is_sdio_mode()) { -+ stp_psm_disable(STP_PSM_CORE(stp_core_ctx)); -+ return 0; -+ } -+ STP_WARN_FUNC("STP Not Ready, Dont do Sleep/Wakeup\n"); -+ return -1; -+ -+#else -+ if (mtk_wcn_stp_is_ready() && mtk_wcn_stp_is_btif_fullset_mode()) { -+ return stp_psm_disable(STP_PSM_CORE(stp_core_ctx)); -+ } else if (mtk_wcn_stp_is_sdio_mode()) { -+ stp_psm_disable(STP_PSM_CORE(stp_core_ctx)); -+ return 0; -+ } -+ STP_DBG_FUNC("STP Not Ready, Dont do Sleep/Wakeup\n"); -+ return 0; -+ -+#endif -+} -+ -+extern INT32 mtk_wcn_stp_psm_reset(VOID) -+{ -+ return stp_psm_reset(STP_PSM_CORE(stp_core_ctx)); -+} -+ -+extern INT32 mtk_wcn_stp_dbg_disable(VOID) -+{ -+ if (STP_IS_ENABLE_DBG(stp_core_ctx)) { -+ STP_DBG_FUNC("STP dbg mode is turned off\n"); -+ STP_SET_ENABLE_DBG(stp_core_ctx, 0); -+ stp_dbg_disable(g_mtkstp_dbg); -+ } else { -+ STP_WARN_FUNC("STP dbg mode has been turned off\n"); -+ } -+ -+ return 0; -+} -+ -+extern INT32 mtk_wcn_stp_dbg_enable(VOID) -+{ -+ if (STP_NOT_ENABLE_DBG(stp_core_ctx)) { -+ STP_DBG_FUNC("STP dbg mode is turned on\n"); -+ STP_SET_ENABLE_DBG(stp_core_ctx, 1); -+ stp_dbg_enable(g_mtkstp_dbg); -+ } else { -+ STP_WARN_FUNC("STP dbg mode has been turned on\n"); -+ } -+ -+ return 0; -+} -+ -+INT32 mtk_wcn_stp_dbg_log_ctrl(UINT32 on) -+{ -+ stp_dbg_log_ctrl(on); -+ return 0; -+} -+ -+INT32 mtk_wcn_stp_coredump_flag_ctrl(UINT32 on) -+{ -+ STP_ENABLE_FW_COREDUMP(stp_core_ctx, on); -+ STP_INFO_FUNC("coredump function mode: %d.\n", on); -+ g_coredump_mode = on; -+ return 0; -+} -+ -+INT32 mtk_wcn_stp_coredump_flag_get(VOID) -+{ -+ return STP_ENABLE_FW_COREDUMP_FLAG(stp_core_ctx); -+} -+ -+static INT32 stp_parser_data_in_mand_mode(UINT32 length, UINT8 *p_data) -+{ -+ UINT8 padding_len = 0; -+ INT32 remain_length; /* GeorgeKuo: sync from MAUI, change to unsigned */ -+ MTK_WCN_BOOL is_function_active = 0; -+ INT32 i = length; -+ -+ while (i > 0) { -+ switch (stp_core_ctx.parser.state) { -+ case MTKSTP_SYNC: /* b'10 */ -+ /* if (((*p_data & 0x80) == 0x80) && ((*p_data & 0x40) == 0x00)) */ -+ /* if(*p_data == 0x80) */ -+ if ((*p_data & 0x80) == 0x80) { -+ /* STP_DBG_FUNC("[STP] STP Packet Start =========>\n"); */ -+ if (*p_data != 0x80) -+ STP_WARN_FUNC("SDIO not 0x80!!(0x%x)\n", *p_data); -+ -+ if (i >= 4) { -+#if !(REMOVE_USELESS_LOG) -+ /*print header, when get the full STP header */ -+ UINT32 type = (*(p_data + 1) & 0x70) >> 4; -+ UINT8 *type_name = ""; -+ -+ type_name = stp_type_to_dbg_string(type); -+ STP_DBG_FUNC( -+ "STP Rx Header: [%02x %02x %02x %02x] type=%s, len=%d, seq=%d, ack=%d\n", -+ *p_data, *(p_data + 1), *(p_data + 2), *(p_data + 3), -+ type_name, ((*(p_data + 1) & 0x0f) << 8) + *(p_data + 2), -+ (*p_data & 0x38) >> 3, *p_data & 0x07); -+#endif -+ } else { -+ STP_WARN_FUNC("STP Rx: discard due to i < 4 (%d)\n", i); -+ } -+ -+ /* STP_DBG_FUNC("[STP] sync->nak\n"); */ -+ stp_change_rx_state(MTKSTP_NAK); -+ stp_core_ctx.rx_counter++; -+ } else { -+ STP_WARN_FUNC("sync to sync!!(0x%x)\n", *p_data); -+ stp_change_rx_state(MTKSTP_SYNC); -+ } -+ break; -+ -+ case MTKSTP_NAK: -+ /* STP_DBG_FUNC("[STP] nak->length\n"); */ -+ stp_change_rx_state(MTKSTP_LENGTH); -+ stp_core_ctx.parser.type = (*p_data & 0x70) >> 4; -+ if (stp_core_ctx.parser.type <= MTKSTP_MAX_TASK_NUM) { -+ stp_core_ctx.parser.length = (*p_data & 0x0f) << 8; -+ stp_core_ctx.rx_counter++; -+ } else { -+ STP_WARN_FUNC("nak to sync\n"); -+ stp_change_rx_state(MTKSTP_SYNC); -+ } -+ break; -+ -+ case MTKSTP_LENGTH: -+ /* STP_DBG_FUNC("[STP] length -> checksum\n"); */ -+ stp_change_rx_state(MTKSTP_CHECKSUM); -+ stp_core_ctx.parser.length += *p_data; -+ -+ /*Valid length checking */ -+ if (stp_core_ctx.parser.length < 2000) { -+ stp_core_ctx.rx_counter++; -+ } else { -+ STP_WARN_FUNC("The length of STP packet is not valid !!! length = %d\n", -+ stp_core_ctx.parser.length); -+ stp_change_rx_state(MTKSTP_SYNC); -+ stp_core_ctx.rx_counter = 0; -+ /* return -1; */ -+ } -+ -+ break; -+ -+ case MTKSTP_CHECKSUM: -+ -+ if ((stp_core_ctx.parser.type == STP_TASK_INDX) || -+ (stp_core_ctx.parser.type == INFO_TASK_INDX)) { -+ stp_change_rx_state(MTKSTP_FW_MSG); -+ stp_core_ctx.rx_counter = 0; -+ i -= 1; -+ if (i != 0) -+ p_data += 1; -+ -+ continue; -+ } -+ -+ if (stp_core_ctx.parser.length == 0) { -+ STP_WARN_FUNC("checksum to sync\n"); -+ stp_change_rx_state(MTKSTP_SYNC); -+ stp_core_ctx.rx_counter = 0; -+ } else { -+ /* STP_DBG_FUNC("[STP] checksum->data\n"); */ -+ stp_change_rx_state(MTKSTP_DATA); -+ stp_core_ctx.rx_counter = 0; -+ } -+ break; -+ -+ case MTKSTP_DATA: -+ -+ /* block copy instead of byte copy */ -+ if (stp_core_ctx.parser.length < stp_core_ctx.rx_counter) { -+ STP_ERR_FUNC("Abnormal length in STP_DATA phase 0x%x, 0x%x\n", -+ stp_core_ctx.parser.length, stp_core_ctx.rx_counter); -+ osal_assert(0); -+ } -+ remain_length = stp_core_ctx.parser.length - stp_core_ctx.rx_counter; -+ if (i >= remain_length) { -+ /*boundary checking */ -+ if (stp_core_ctx.rx_counter + remain_length >= MTKSTP_BUFFER_SIZE) { -+ STP_ERR_FUNC("Abnormal!! Memory operation over boundary!!\n"); -+ stp_change_rx_state(MTKSTP_SYNC); -+ stp_core_ctx.rx_counter = 0; -+ return -1; -+ } -+ -+ osal_memcpy(stp_core_ctx.rx_buf + stp_core_ctx.rx_counter, p_data, -+ remain_length); -+ i -= remain_length; -+ p_data += remain_length; -+ stp_core_ctx.rx_counter = stp_core_ctx.parser.length; -+ stp_core_ctx.parser.state = MTKSTP_CRC1; -+ continue; -+ -+ } else { /* only copy by data length */ -+ -+ /*fixed klocwork insight issue */ -+ /*boundary checking */ -+ if (i + stp_core_ctx.rx_counter >= MTKSTP_BUFFER_SIZE) { -+ STP_ERR_FUNC("Abnormal!! Memory operation over boundary 2!!\n"); -+ stp_core_ctx.rx_counter = 0; -+ return -1; -+ } -+ -+ osal_memcpy(stp_core_ctx.rx_buf + stp_core_ctx.rx_counter, p_data, i); -+ stp_core_ctx.rx_counter += i; /* all remain buffer are data */ -+ i = 0; -+ p_data += i; -+ continue; -+ } -+ break; -+ -+ case MTKSTP_CRC1: -+ stp_change_rx_state(MTKSTP_CRC2); -+ break; -+ -+ case MTKSTP_CRC2: -+#if 1 -+ if (stp_core_ctx.parser.type == WMT_TASK_INDX) { -+ stp_core_ctx.parser.wmtsubtype = stp_core_ctx.rx_buf[1]; -+ STP_DBG_FUNC("wmt sub type (0x%x)\n", stp_core_ctx.parser.wmtsubtype); -+ } -+#endif -+ /*SDIO mode do it. */ -+ if (mtk_wcn_stp_is_sdio_mode()) { -+ /*STP packet 4-bytes alignment */ -+ /*Discard padding bytes , otherwise make parser state machine disorder */ -+ if (i <= 4) { -+ /*STP_DBG_FUNC("STP last block padding %d bytes\n", i-1); */ -+ p_data += (i - 1); -+ i -= (i - 1); -+ } else { -+ padding_len = (0x04 - ((stp_core_ctx.parser.length + 6) & 0x03)) & 0x03; -+ p_data += padding_len; -+ i -= padding_len; -+ /*STP_DBG_FUNC("STP Agg padding %d bytes\n", padding_len); */ -+ } -+ } -+ stp_dbg_pkt_log(stp_core_ctx.parser.type, -+ 0, 0, 0, PKT_DIR_RX, stp_core_ctx.rx_buf, stp_core_ctx.rx_counter); -+ if ((stp_core_ctx.parser.type == BT_TASK_INDX) && STP_BT_STK_IS_BLUEZ(stp_core_ctx)) { -+ int b; -+ -+ /*Indicate packet to hci_stp */ -+ if (gStpDbgLvl >= STP_LOG_DBG) { -+ stp_dump_data(stp_core_ctx.rx_buf, "indicate_to_bt_core", -+ stp_core_ctx.rx_counter); -+ } -+ -+ b = mtk_wcn_sys_if_rx(stp_core_ctx.rx_buf, stp_core_ctx.rx_counter); -+ if (b) -+ STP_ERR_FUNC("mtk_wcn_sys_if_rx is NULL\n"); -+ -+ } else { -+ -+ is_function_active = ( -+ (*sys_check_function_status)(stp_core_ctx.parser.type, OP_FUNCTION_ACTIVE) -+ == STATUS_FUNCTION_ACTIVE); -+ -+ /*check type and function if active? */ -+ if ((stp_core_ctx.parser.type < MTKSTP_MAX_TASK_NUM) -+ && (is_function_active == MTK_WCN_BOOL_TRUE)) { -+#if CFG_WMT_LTE_COEX_HANDLING -+ if ((stp_core_ctx.parser.type == WMT_TASK_INDX) -+ && stp_core_ctx.parser.wmtsubtype == WMT_LTE_COEX_FLAG) { -+ STP_INFO_FUNC("wmt/lte coex package!\n"); -+ stp_add_to_rx_queue(stp_core_ctx.rx_buf, -+ stp_core_ctx.rx_counter, COEX_TASK_INDX); -+ stp_notify_btm_handle_wmt_lte_coex(STP_BTM_CORE(stp_core_ctx)); -+ } else { -+ stp_add_to_rx_queue(stp_core_ctx.rx_buf, -+ stp_core_ctx.rx_counter, -+ stp_core_ctx.parser.type); -+ -+ /*notify corresponding subfunction of incoming data */ -+ (*sys_event_set) (stp_core_ctx.parser.type); -+ } -+#else -+ if ((stp_core_ctx.parser.type == WMT_TASK_INDX) -+ && stp_core_ctx.parser.wmtsubtype == WMT_LTE_COEX_FLAG) { -+ STP_WARN_FUNC -+ ("omit BT/WIFI & LTE coex msg handling in non-LTE projects\n"); -+ } else { -+ stp_add_to_rx_queue(stp_core_ctx.rx_buf, -+ stp_core_ctx.rx_counter, -+ stp_core_ctx.parser.type); -+ -+ /*notify corresponding subfunction of incoming data */ -+ (*sys_event_set) (stp_core_ctx.parser.type); -+ } -+#endif -+ } else { -+ if (is_function_active == MTK_WCN_BOOL_FALSE) { -+ STP_ERR_FUNC -+ ("function type = %d is inactive, so no en-queue to rx\n", -+ stp_core_ctx.parser.type); -+ } else { -+ STP_ERR_FUNC -+ ("mtkstp_process_packet: type = %x, the type is invalid\n", -+ stp_core_ctx.parser.type); -+ } -+ } -+ } -+ -+ /* STP_DBG_FUNC("[STP] crc2->sync\n"); */ -+ /* STP_DBG_FUNC("[STP] STP Packet End <=========\n"); */ -+ stp_core_ctx.rx_counter = 0; -+ stp_change_rx_state(MTKSTP_SYNC); -+ -+ break; -+ -+ case MTKSTP_FW_MSG: -+ -+ /*f/w assert and exception information */ -+ if (stp_core_ctx.parser.length < stp_core_ctx.rx_counter) { -+ STP_ERR_FUNC("Abnormal length in STP_DATA phase 0x%x, 0x%x\n", -+ stp_core_ctx.parser.length, stp_core_ctx.rx_counter); -+ } -+ -+ remain_length = stp_core_ctx.parser.length - stp_core_ctx.rx_counter; -+ -+ if (i >= remain_length) { -+ osal_memcpy(stp_core_ctx.rx_buf + stp_core_ctx.rx_counter, p_data, -+ remain_length); -+ i -= remain_length; -+ p_data += remain_length; -+ stp_core_ctx.rx_counter = stp_core_ctx.parser.length; -+ *(stp_core_ctx.rx_buf + stp_core_ctx.rx_counter) = '\0'; -+ /*Trace32 Dump */ -+ if (stp_core_ctx.parser.type == STP_TASK_INDX) { -+ /* g_block_tx = 1; */ -+ mtk_wcn_stp_coredump_start_ctrl(1); -+ pr_debug("[len=%d][type=%d]\n%s\n", stp_core_ctx.rx_counter, -+ stp_core_ctx.parser.type, stp_core_ctx.rx_buf); -+ /*use paged dump or full dump */ -+ stp_btm_notify_wmt_dmp_wq(stp_core_ctx.btm); -+#if 0 -+ stp_dbg_log_pkt(g_mtkstp_dbg, STP_DBG_FW_DMP /*STP_DBG_FW_ASSERT */ , 5, -+ 0, 0, 0, 0, -+ (stp_core_ctx.rx_counter + 1), stp_core_ctx.rx_buf); -+#endif -+ } -+ -+ /*discard CRC */ -+ /* we will discard antoher CRC on the outer switch procedure. */ -+ if (i >= 1) { -+ STP_INFO_FUNC("crc discard.. i = %d\n", i); -+ i -= 1; -+ if (i > 0) -+ p_data += 1; -+ -+ } -+ -+ /*STP packet 4-bytes alignment */ -+ /*Discard padding bytes , otherwise make parser state machine disorder */ -+ if (i <= 4) { -+ STP_INFO_FUNC -+ ("\n[STP]FW_EVENT========= block padding %d bytes =========\n", -+ i - 1); -+ p_data += (i - 1); -+ i -= (i - 1); -+ } else { -+ padding_len = (0x04 - ((stp_core_ctx.parser.length + 6) & 0x03)) & 0x03; -+ p_data += padding_len; -+ i -= padding_len; -+ STP_INFO_FUNC -+ ("\n[STP]FW_EVENT========= STP Agg padding %d bytes =========\n", -+ padding_len); -+ } -+ stp_change_rx_state(MTKSTP_SYNC); -+ -+ } else { /* only copy by data length */ -+ -+ STP_ERR_FUNC("raw data doesn't contain full stp packet!!\n"); -+ } -+ break; -+ default: -+ break; -+ } -+ p_data++; -+ i--; -+ } -+ -+ return 0; -+} -+ -+static INT32 stp_parser_data_in_full_mode(UINT32 length, UINT8 *p_data) -+{ -+ INT32 remain_length; /* GeorgeKuo: sync from MAUI, change to unsigned */ -+ INT32 i = length; -+ -+ while (i > 0) { -+ switch (stp_core_ctx.parser.state) { -+ -+ case MTKSTP_RESYNC1: /* RESYNC must be 4 _continuous_ 0x7f */ -+ if (*p_data == 0x7f) -+ stp_change_rx_state(MTKSTP_RESYNC2); -+ else -+ stp_change_rx_state(MTKSTP_RESYNC1); -+ break; -+ case MTKSTP_RESYNC2: -+ if (*p_data == 0x7f) -+ stp_change_rx_state(MTKSTP_RESYNC3); -+ else -+ stp_change_rx_state(MTKSTP_RESYNC1); -+ break; -+ case MTKSTP_RESYNC3: -+ if (*p_data == 0x7f) -+ stp_change_rx_state(MTKSTP_RESYNC4); -+ else -+ stp_change_rx_state(MTKSTP_RESYNC1); -+ break; -+ case MTKSTP_RESYNC4: -+ if (*p_data == 0x7f) -+ stp_change_rx_state(MTKSTP_SYNC); -+ else -+ stp_change_rx_state(MTKSTP_RESYNC1); -+ break; -+ case MTKSTP_SYNC: /* b'10 */ -+ STP_DUMP_PACKET_HEAD(p_data, "rx (uart):", length > 4 ? 4 : length); -+ if (((*p_data & 0x80) == 0x80) && ((*p_data & 0x40) == 0x00)) { -+ stp_change_rx_state(MTKSTP_NAK); -+ stp_core_ctx.parser.seq = (*p_data & 0x38) >> 3; -+ stp_core_ctx.parser.ack = *p_data & 0x07; -+ stp_core_ctx.rx_buf[0] = *p_data; -+ /* Geoge FIXME: WHY comment the following line? */ -+ /* stp_core_ctx.rx_counter++; */ -+ -+ if (i >= 4 && gStpDbgLvl >= STP_LOG_DBG) { -+ /*print header, when get the full STP header */ -+#if !(REMOVE_USELESS_LOG) -+ int type = (*(p_data + 1) & 0x70) >> 4; -+ char *type_name = ""; -+ -+ type_name = stp_type_to_dbg_string(type); -+ -+ STP_DBG_FUNC -+ ("STP Rx Header: [%02x %02x %02x %02x] type=%s, len=%d, seq=%d, ack=%d\n", -+ *p_data, *(p_data + 1), *(p_data + 2), *(p_data + 3), type_name, -+ ((*(p_data + 1) & 0x0f) << 8) + *(p_data + 2), -+ (*p_data & 0x38) >> 3, *p_data & 0x07); -+#endif -+ } else { -+ STP_DBG_FUNC("STP Rx: discard due to i < 4\n"); -+ } -+ } else if ((*p_data == 0x7f) && (prev_state == MTKSTP_RESYNC4)) { -+ /* if this 0x7f is continuous to resync pattern */ -+ /* skip this continuous 0x7f, remain current & prev state */ -+ osal_assert(0); -+ STP_ERR_FUNC("MTKSTP_SYNC: continuous resync pattern, buff = %x\n", *p_data); -+ } else if (*p_data == 0x7f) { /* a start of 0x7f, maybe this is resync pattern */ -+ stp_change_rx_state(MTKSTP_RESYNC2); -+ osal_assert(0); -+ STP_ERR_FUNC("MTKSTP_SYNC: go to MTKSTP_RESYNC2, buff = %x\n", *p_data); -+ } else if (*p_data == 0x55) { /* STP delimiter */ -+ /* do nothing for delimiter */ -+ } else { /* unexpected, go to resync1 */ -+ osal_assert(0); -+ STP_ERR_FUNC("MTKSTP_SYNC: unexpected data, buff = %x\n", *p_data); -+ } -+ break; -+ -+ case MTKSTP_NAK: -+ /* (*sys_dbg_print)("MTKSTP_NAK : mtk_wcn_stp_parser_data, buff = %x", *p_data); */ -+ if (fgEnableNak == 0) -+ stp_core_ctx.parser.nak = 0; /* disable NAK */ -+ else -+ stp_core_ctx.parser.nak = (*p_data & 0x80) >> 7; -+ -+ stp_core_ctx.parser.type = (*p_data & 0x70) >> 4; -+ stp_core_ctx.parser.length = (*p_data & 0x0f) << 8; -+ stp_core_ctx.rx_buf[1] = *p_data; -+ /* Geoge FIXME: WHY comment the following line? */ -+ /*stp_core_ctx.rx_counter++; */ -+ if (stp_core_ctx.parser.nak) -+ STP_ERR_FUNC("MTKSTP_NAK TRUE: mtk_wcn_stp_parser_data, buff = %x\n", *p_data); -+ -+ if (stp_core_ctx.parser.type < MTKSTP_MAX_TASK_NUM) -+ stp_change_rx_state(MTKSTP_LENGTH); -+ else -+ stp_change_rx_state(MTKSTP_SYNC); -+ break; -+ -+ case MTKSTP_LENGTH: -+ /* (*sys_dbg_print)("MTKSTP_LENGTH : mtk_wcn_stp_parser_data, buff = %x", *p_data); */ -+ stp_change_rx_state(MTKSTP_CHECKSUM); -+ stp_core_ctx.parser.length += *p_data; -+ -+ /*Valid length checking */ -+ if (stp_core_ctx.parser.length > 2048) { -+ STP_ERR_FUNC("The length of STP packet is not valid !!! length = %d\n", -+ stp_core_ctx.parser.length); -+ stp_change_rx_state(MTKSTP_RESYNC1); -+ stp_core_ctx.rx_counter = 0; -+ STP_TRACE_FUNC("--\n"); -+ return -1; -+ } -+ -+ stp_core_ctx.rx_buf[2] = *p_data; -+ /* Geoge FIXME: WHY comment the following line? */ -+ /*stp_core_ctx.rx_counter++; */ -+ break; -+ -+ case MTKSTP_CHECKSUM: -+ /* (*sys_dbg_print)("MTKSTP_CHECKSUM : mtk_wcn_stp_parser_data, buff = %x", *p_data); */ -+ if ((stp_core_ctx.parser.type == STP_TASK_INDX) || -+ (stp_core_ctx.parser.type == INFO_TASK_INDX)) { -+ stp_change_rx_state(MTKSTP_FW_MSG); -+ stp_core_ctx.rx_counter = 0; -+ i -= 1; -+ if (i != 0) -+ p_data += 1; -+ -+ continue; -+ } -+ -+ if (((stp_core_ctx.rx_buf[0] + -+ stp_core_ctx.rx_buf[1] + stp_core_ctx.rx_buf[2]) & 0xff) == *p_data) { -+ /* header only packet */ -+ if (stp_core_ctx.parser.length == 0) { -+ INT32 fgTriggerResume = (-1); -+ -+ /* osal_lock_unsleepable_lock(&stp_core_ctx.stp_mutex); */ -+ stp_ctx_lock(&stp_core_ctx); -+ if (stp_core_ctx.inband_rst_set == 0) { -+ stp_dbg_pkt_log(STP_TASK_INDX, -+ stp_core_ctx.parser.ack, -+ stp_core_ctx.parser.seq, -+ 5, /* STP type id */ -+ PKT_DIR_RX, -+ NULL, -+ 0); -+ fgTriggerResume = stp_process_rxack(); -+ } else { -+ STP_WARN_FUNC -+ ("Now it's inband reset process and drop ACK packet.\n"); -+ } -+ -+ if (fgTriggerResume == 0) { -+ /* notify adaptation layer for -+ * possible tx resume mechanism -+ */ -+ (*sys_event_tx_resume) (stp_core_ctx.sequence.winspace); -+ } -+ stp_ctx_unlock(&stp_core_ctx); -+ /* osal_unlock_unsleepable_lock(&stp_core_ctx.stp_mutex); */ -+ stp_change_rx_state(MTKSTP_SYNC); -+ stp_core_ctx.rx_counter = 0; -+ } else { -+ stp_change_rx_state(MTKSTP_DATA); -+ stp_core_ctx.rx_counter = 0; -+ } -+ } else { -+ STP_ERR_FUNC("The checksum of header is error !!! %02x %02x %02x %02x\n", -+ stp_core_ctx.rx_buf[0], stp_core_ctx.rx_buf[1], -+ stp_core_ctx.rx_buf[2], *p_data); -+ /* George FIXME: error handling mechanism shall be refined */ -+ stp_change_rx_state(MTKSTP_RESYNC1); -+ stp_core_ctx.rx_counter = 0; -+ -+ /* since checksum error is usually related to interface -+ * buffer overflow, so we just let timeout mechanism to -+ * handle such error. -+ */ -+ STP_TRACE_FUNC("--\n"); -+ /* return and purge COMM port */ -+ return -1; -+ /*stp_send_ack(1); NAK mechanism is removed */ -+ } -+ break; -+ -+ case MTKSTP_DATA: -+#if 0 -+ if (stp_core_ctx.rx_counter < stp_core_ctx.parser.length) { -+ stp_core_ctx.rx_buf[stp_core_ctx.rx_counter] = *p_data; -+ stp_core_ctx.rx_counter++; -+ } -+ if (stp_core_ctx.rx_counter == stp_core_ctx.parser.length) -+ stp_change_rx_state(MTKSTP_CRC1); -+#else -+ /* block copy instead of byte copy */ -+ if (stp_core_ctx.parser.length < stp_core_ctx.rx_counter) { -+ STP_ERR_FUNC("Abnormal length in STP_DATA phase 0x%x, 0x%x\n", -+ stp_core_ctx.parser.length, stp_core_ctx.rx_counter); -+ osal_assert(0); -+ } -+ remain_length = stp_core_ctx.parser.length - stp_core_ctx.rx_counter; -+ if (i >= remain_length) { -+ osal_memcpy(stp_core_ctx.rx_buf + stp_core_ctx.rx_counter, p_data, -+ remain_length); -+ -+ i -= remain_length; -+ p_data += remain_length; -+ stp_core_ctx.rx_counter = stp_core_ctx.parser.length; -+ stp_core_ctx.parser.state = MTKSTP_CRC1; -+ continue; -+ } else { /* only copy by data length */ -+ -+ /*fixed klocwork insight issue */ -+ if (i + stp_core_ctx.rx_counter >= MTKSTP_BUFFER_SIZE) { -+ STP_ERR_FUNC -+ ("Fail to handle Packet, maybe it doesn't follow STP protocol.\n"); -+ stp_change_rx_state(MTKSTP_RESYNC1); -+ stp_core_ctx.rx_counter = 0; -+ STP_TRACE_FUNC("--\n"); -+ return -1; -+ } -+ -+ osal_memcpy(stp_core_ctx.rx_buf + stp_core_ctx.rx_counter, p_data, i); -+ stp_core_ctx.rx_counter += i; /* all remain buffer are data */ -+ i = 0; -+ p_data += i; -+ continue; -+ } -+#endif -+ break; -+ -+ case MTKSTP_CRC1: -+ stp_change_rx_state(MTKSTP_CRC2); -+ stp_core_ctx.parser.crc = *p_data; -+ break; -+ case MTKSTP_CRC2: -+ stp_change_rx_state(MTKSTP_SYNC); -+ stp_core_ctx.parser.crc += (*p_data) << 8; -+#if 1 -+ if (stp_core_ctx.parser.type == WMT_TASK_INDX) { -+ stp_core_ctx.parser.wmtsubtype = stp_core_ctx.rx_buf[1]; -+ STP_DBG_FUNC("wmt sub type is (0x%x)\n", stp_core_ctx.parser.wmtsubtype); -+ } -+#endif -+ if (stp_check_crc(stp_core_ctx.rx_buf, stp_core_ctx.rx_counter, stp_core_ctx.parser.crc) -+ == MTK_WCN_BOOL_TRUE) { -+ if (stp_core_ctx.inband_rst_set == 0) -+ stp_process_packet(); -+ else -+ STP_WARN_FUNC("Now it's inband reset process and drop packet.\n"); -+ } else { -+ STP_ERR_FUNC("The CRC of packet is error !!!\n"); -+ /* George FIXME: error handling mechanism shall be refined */ -+ stp_change_rx_state(MTKSTP_RESYNC1); -+ stp_core_ctx.rx_counter = 0; -+ -+ /* since checksum error is usually related to interface -+ * buffer overflow, so we just let timeout mechanism to -+ * handle such error. -+ */ -+ STP_TRACE_FUNC("--\n"); -+ /* return and purge COMM port */ -+ return -1; -+ /*stp_send_ack(1); NAK mechanism is removed */ -+ } -+ break; -+ -+ case MTKSTP_FW_MSG: -+#if CFG_WMT_DUMP_INT_STATUS -+ if (MTK_WCN_BOOL_TRUE == wmt_plat_dump_BGF_irq_status()) -+ wmt_plat_BGF_irq_dump_status(); -+#endif -+ if (STP_IS_READY(stp_core_ctx)) -+ mtk_wcn_stp_dbg_dump_package(); -+ -+ STP_SET_READY(stp_core_ctx, 0); -+ /*stp inband reset */ -+ if (stp_core_ctx.parser.type == STP_TASK_INDX && -+ stp_core_ctx.parser.seq == 0 && -+ stp_core_ctx.parser.ack == 0 && -+ stp_core_ctx.parser.length == 0 && stp_core_ctx.inband_rst_set == 1) { -+ STP_INFO_FUNC("Inband reset event get! Resync STP with firmware!\n\r"); -+ stp_rest_ctx_state(); -+ stp_change_rx_state(MTKSTP_RESYNC1); -+ stp_core_ctx.inband_rst_set = 0; -+ /* STP_INFO_FUNC("Restart STP Timer\n\r"); */ -+ /* (*sys_timer_start)(stp_core_ctx.tx_timer, -+ * mtkstp_tx_timeout, -+ * (MTK_WCN_TIMER_CB)stp_tx_timeout_handler, -+ * NULL); -+ */ -+ STP_TRACE_FUNC("--\n"); -+ return 0; -+ } -+ -+ /*f/w assert and exception information */ -+ if (stp_core_ctx.parser.length < stp_core_ctx.rx_counter) { -+ STP_ERR_FUNC("Abnormal length in STP_DATA phase 0x%x, 0x%x\n", -+ stp_core_ctx.parser.length, stp_core_ctx.rx_counter); -+ osal_assert(0); -+ } -+ -+ remain_length = stp_core_ctx.parser.length - stp_core_ctx.rx_counter; -+ if (i >= remain_length) { -+ osal_memcpy(stp_core_ctx.rx_buf + stp_core_ctx.rx_counter, p_data, -+ remain_length); -+ i -= remain_length; -+ p_data += remain_length; -+ stp_core_ctx.rx_counter = stp_core_ctx.parser.length; -+ stp_change_rx_state(MTKSTP_SYNC); -+ *(stp_core_ctx.rx_buf + stp_core_ctx.rx_counter) = '\0'; -+ /* STP_ERR_FUNC("%s [%d]\n", stp_core_ctx.rx_buf, stp_core_ctx.rx_counter); */ -+#if 0 -+ if ((stp_core_ctx.rx_counter == 1) && (stp_core_ctx.rx_buf[0] == 0xFF)) { -+ /* For MT6620, enable/disable coredump function is controlled by -+ * firmware for the moment, we need to set coredump enable flag -+ * to be 1 after see firmware send a pariticallar character(0xff) -+ * before any coredump packet is sent -+ */ -+ mtk_wcn_stp_coredump_flag_ctrl(1); -+ } -+#endif -+ /*Trace32 Dump */ -+ if (STP_IS_ENABLE_DBG(stp_core_ctx) && -+ (stp_core_ctx.parser.type == STP_TASK_INDX)) { -+ if (0 != stp_core_ctx.rx_counter) { -+ STP_SET_READY(stp_core_ctx, 0); -+ mtk_wcn_stp_ctx_save(); -+ STP_INFO_FUNC("++ start to read paged dump and paged trace ++\n"); -+ stp_btm_notify_wmt_dmp_wq(stp_core_ctx.btm); -+ stp_btm_notify_wmt_trace_wq(stp_core_ctx.btm); -+ STP_INFO_FUNC("++ start to read paged dump and paged trace --\n"); -+ -+ } -+ STP_INFO_FUNC("[len=%d][type=%d]\n%s\n", stp_core_ctx.rx_counter, -+ stp_core_ctx.parser.type, stp_core_ctx.rx_buf); -+ } -+ -+ /*Runtime FW Log */ -+ else if (STP_IS_ENABLE_DBG(stp_core_ctx) -+ && (stp_core_ctx.parser.type == INFO_TASK_INDX)) { -+ stp_dbg_log_pkt(g_mtkstp_dbg, STP_DBG_FW_LOG, STP_TASK_INDX, 5, 0, 0, 0, -+ (stp_core_ctx.rx_counter + 1), stp_core_ctx.rx_buf); -+ mtk_wcn_stp_dbg_dump_package(); -+ } -+ /*Normal mode: whole chip reset */ -+ else { -+ /*Aee Kernel Warning Message Shown First */ -+ /* (*sys_dbg_assert_aee)("[MT662x]f/w Assert", stp_core_ctx.rx_buf); */ -+ mtk_wcn_stp_coredump_start_ctrl(0); -+ mtk_wcn_stp_dbg_dump_package(); -+ -+ osal_dbg_assert_aee(stp_core_ctx.rx_buf, stp_core_ctx.rx_buf); -+ /*Whole Chip Reset Procedure Invoke */ -+ if (STP_IS_ENABLE_RST(stp_core_ctx)) { -+ STP_SET_READY(stp_core_ctx, 0); -+ stp_btm_notify_wmt_rst_wq(STP_BTM_CORE(stp_core_ctx)); -+ } else { -+ STP_INFO_FUNC -+ ("No to launch whole chip reset! for debugging purpose\n"); -+ } -+ } -+ /*discard CRC */ -+ if (i >= 2) { -+ STP_DBG_FUNC("crc discard.. i = %d\n", i); -+ i -= 2; -+ if (i > 0) -+ p_data += 2; -+ } -+ continue; -+ } else { /* only copy by data length */ -+ -+ /*fixed klocwork insight issue */ -+ if (i + stp_core_ctx.rx_counter >= MTKSTP_BUFFER_SIZE) { -+ STP_ERR_FUNC -+ ("Fail to handle Packet, maybe it doesn't follow STP protocol.\n"); -+ stp_change_rx_state(MTKSTP_RESYNC1); -+ stp_core_ctx.rx_counter = 0; -+ return -1; -+ } -+ osal_memcpy(stp_core_ctx.rx_buf + stp_core_ctx.rx_counter, p_data, i); -+ stp_core_ctx.rx_counter += i; /* all remain buffer are data */ -+ i = 0; -+ p_data += i; -+ continue; -+ } -+ -+ break; -+ default: -+ break; -+ } -+ p_data++; -+ i--; -+ } -+ -+ return 0; -+} -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_parser_data -+* DESCRIPTION -+* push data to serial transport protocol parser engine -+* PARAMETERS -+* buffer [IN] data buffer -+* length [IN] data buffer length -+* RETURNS -+* int 0 = success; -1 = crc/checksum error -+*****************************************************************************/ -+#if STP_EXP_HID_API_EXPORT -+int _mtk_wcn_stp_parser_data(UINT8 *buffer, UINT32 length) -+#else -+int mtk_wcn_stp_parser_data(UINT8 *buffer, UINT32 length) -+#endif -+{ -+ /*----------------------------------------------------------------*/ -+ /* Local Variables */ -+ /*----------------------------------------------------------------*/ -+ INT32 i; -+ UINT8 *p_data; -+ INT32 ret = 0; -+#ifdef DEBUG_DUMP_PACKET_HEAD -+ static UINT32 counter; -+ -+ STP_TRACE_FUNC("++, rx (cnt=%d,len=%d)\n", ++counter, length); -+#endif -+ -+#if 0 -+#ifdef CONFIG_POWER_SAVING_SUPPORT -+ if (stp_is_apply_powersaving()) { -+ /* If now chip is awake, to restart monitor! */ -+ if (!stp_psm_is_to_block_traffic(STP_PSM_CORE(stp_core_ctx))) { -+ STP_DBG_FUNC("To restart moinotr when rx\n\r"); -+ stp_psm_start_monitor(STP_PSM_CORE(stp_core_ctx)); -+ } -+ } -+#endif -+#endif -+ -+ /*----------------------------------------------------------------*/ -+ /* Code Body */ -+ /*----------------------------------------------------------------*/ -+ /* George FIXME: WHY or HOW can we reduct the locked region? */ -+ /*flags = (*sys_mutex_lock)(stp_core_ctx.stp_mutex); */ -+ i = length; -+ p_data = (UINT8 *) buffer; -+ -+/* stp_dump_data(buffer, "rx queue", length); */ -+ -+ /*STP is not enabled and only WMT can use Raw data path */ -+ if (STP_NOT_ENABLE(stp_core_ctx) && WMT_TASK_INDX == STP_PENDING_TYPE(stp_core_ctx)) { -+ /* route to task who send command */ -+ stp_add_to_rx_queue(buffer, length, STP_PENDING_TYPE(stp_core_ctx)); -+ -+ /* mike: notify corresponding subfunction of incoming data */ -+ (*sys_event_set) (STP_PENDING_TYPE(stp_core_ctx)); -+ } -+ /* STP over SDIO */ -+ else if ((mtk_wcn_stp_is_sdio_mode() || mtk_wcn_stp_is_btif_mand_mode()) && STP_IS_ENABLE(stp_core_ctx)) { -+#if !(REMOVE_USELESS_LOG) -+ if (gStpDbgLvl >= STP_LOG_DBG) -+ stp_dump_data(buffer, "sdio parser_in", length); -+#endif -+ /* STP_DBG_FUNC("sdio stp parser data length = %d\n", length); */ -+ ret = stp_parser_data_in_mand_mode(i, p_data); -+ } -+ /* STP over UART */ -+ else if (mtk_wcn_stp_is_btif_fullset_mode() && STP_IS_ENABLE(stp_core_ctx)) -+ ret = stp_parser_data_in_full_mode(i, p_data); -+ -+ /* George FIXME: WHY or HOW can we reduct the locked region? */ -+ /*(*sys_mutex_unlock)(stp_core_ctx.stp_mutex, flags); */ -+ STP_TRACE_FUNC("--\n"); -+ return ret; -+} -+#if !STP_EXP_HID_API_EXPORT -+EXPORT_SYMBOL(mtk_wcn_stp_parser_data); -+#endif -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_enable -+* DESCRIPTION -+* enable/disable STP -+* PARAMETERS -+* value [IN] 0=disable, others=enable -+* RETURNS -+* INT32 0=success, others=error -+*****************************************************************************/ -+INT32 mtk_wcn_stp_enable(INT32 value) -+{ -+ STP_DBG_FUNC("%s: set the current enable = (%d)\n", __func__, value); -+ -+ stp_rest_ctx_state(); -+ STP_SET_ENABLE(stp_core_ctx, value); -+ if (!value) { -+ mtk_wcn_stp_psm_reset(); -+ } else { -+/* g_block_tx = 0; */ -+ mtk_wcn_stp_coredump_start_ctrl(0); -+ } -+ return 0; -+} -+ -+INT32 mtk_wcn_stp_dbg_dump_package(VOID) -+{ -+ if (STP_NOT_ENABLE(stp_core_ctx)) { -+ STP_INFO_FUNC("STP dbg mode is off\n"); -+ -+ } else { -+ STP_INFO_FUNC("STP dbg mode is on\n"); -+ /* if (0 == g_block_tx) */ -+ if (0 == mtk_wcn_stp_coredump_start_get()) { -+ mtk_wcn_consys_stp_btif_logger_ctrl(BTIF_DUMP_LOG); -+ mtk_wcn_consys_stp_btif_logger_ctrl(BTIF_DUMP_BTIF_REG); -+ stp_dbg_dmp_printk(g_mtkstp_dbg); -+ } else { -+ STP_INFO_FUNC("assert start flag is set, disable packet dump function\n"); -+ } -+ } -+ return 0; -+} -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_ready -+* DESCRIPTION -+* ready/un-ready STP -+* PARAMETERS -+* value [IN] 0=un-ready, others=ready -+* RETURNS -+* INT32 0=success, others=error -+*****************************************************************************/ -+INT32 mtk_wcn_stp_ready(INT32 value) -+{ -+ STP_DBG_FUNC("set ready (%d)\n", value); -+ -+ STP_SET_READY(stp_core_ctx, value); -+ /*if whole chip reset, reset the debuggine mode */ -+#ifndef CONFIG_LOG_STP_INTERNAL -+ /* mtk_wcn_stp_dbg_disable(); */ -+#endif -+ -+ if (stp_is_apply_powersaving()) { -+ STP_INFO_FUNC("Restart the stp-psm monitor !!\n"); -+ stp_psm_disable(STP_PSM_CORE(stp_core_ctx)); -+ } -+ -+ return 0; -+} -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_coredump_start_ctrl -+* DESCRIPTION -+* set f/w assert flag in STP context -+* PARAMETERS -+* value [IN] 0=assert end, others=assert begins -+* RETURNS -+* INT32 0=success, others=error -+*****************************************************************************/ -+INT32 mtk_wcn_stp_coredump_start_ctrl(UINT32 value) -+{ -+ STP_DBG_FUNC("set f/w assert (%d)\n", value); -+ -+ STP_SET_FW_COREDUMP_FLAG(stp_core_ctx, value); -+ -+ return 0; -+} -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_coredump_start_get -+* DESCRIPTION -+* get f/w assert flag in STP context -+* PARAMETERS -+* VOID -+* RETURNS -+* INT32 0= f/w assert flag is not set, others=f/w assert flag is set -+*****************************************************************************/ -+#if STP_EXP_HID_API_EXPORT -+INT32 _mtk_wcn_stp_coredump_start_get(VOID) -+#else -+INT32 mtk_wcn_stp_coredump_start_get(VOID) -+#endif -+{ -+ return STP_FW_COREDUMP_FLAG(stp_core_ctx); -+} -+ -+/* mtk_wcn_stp_set_wmt_last_close -- set the state of link(UART or SDIO) -+ * @ value - 1, link already be closed; 0, link is open -+ * -+ * Return 0 if success; else error code -+ */ -+INT32 mtk_wcn_stp_set_wmt_last_close(UINT32 value) -+{ -+ STP_INFO_FUNC("set wmt_last_close flag (%d)\n", value); -+ -+ STP_SET_WMT_LAST_CLOSE(stp_core_ctx, value); -+ -+ return 0; -+} -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_send_data -+* DESCRIPTION -+* subfunction send data through STP -+* PARAMETERS -+* buffer [IN] data buffer -+* length [IN] data buffer length -+* type [IN] subfunction type -+* RETURNS -+* INT32 > 0: length transmitted; = 0: error -+*****************************************************************************/ -+#if STP_EXP_HID_API_EXPORT -+INT32 _mtk_wcn_stp_send_data(const PUINT8 buffer, const UINT32 length, const UINT8 type) -+#else -+INT32 mtk_wcn_stp_send_data(const PUINT8 buffer, const UINT32 length, const UINT8 type) -+#endif -+{ -+ UINT8 mtkstp_header[MTKSTP_HEADER_SIZE], temp[2]; -+ UINT8 *p_tx_buf = NULL; -+ UINT16 crc; -+ INT32 ret = 0; -+ MTK_WCN_BOOL is_quick_enable = MTK_WCN_BOOL_TRUE; -+ -+ /* osal_buffer_dump(buffer,"tx", length, 32); */ -+ -+ if (0 != STP_WMT_LAST_CLOSE(stp_core_ctx)) { -+ STP_ERR_FUNC("WMT lats close,should not have tx request!\n"); -+ return length; -+ } -+ /* if(g_block_tx) */ -+ if (0 != mtk_wcn_stp_coredump_start_get()) { -+ STP_ERR_FUNC("STP fw coredump start flag set...\n"); -+ return length; -+ } -+#ifdef CONFIG_POWER_SAVING_SUPPORT -+ is_quick_enable = stp_psm_is_quick_ps_support(); -+ STP_DBG_FUNC("is quick sleep enable:%s\n", is_quick_enable ? "yes" : "no"); -+ if (MTK_WCN_BOOL_TRUE == is_quick_enable) { -+ if (type != WMT_TASK_INDX) { -+#if PSM_USE_COUNT_PACKAGE -+ stp_psm_disable_by_tx_rx_density(STP_PSM_CORE(stp_core_ctx), 0); -+#else -+ stp_psm_disable_by_tx_rx_density(STP_PSM_CORE(stp_core_ctx), 0, length); -+#endif -+ } -+ /* if(stp_is_apply_powersaving()) */ -+ { -+ if (type == WMT_TASK_INDX) -+ goto DONT_MONITOR; -+ /*-----------------------------STP_PSM_Lock----------------------------------------*/ -+ ret = stp_psm_thread_lock_aquire(STP_PSM_CORE(stp_core_ctx)); -+ if (ret) { -+ STP_ERR_FUNC("--->lock psm_thread_lock failed ret=%d\n", ret); -+ return ret; -+ } -+ -+ if (!stp_psm_is_to_block_traffic(STP_PSM_CORE(stp_core_ctx))) { -+ if (stp_psm_has_pending_data(STP_PSM_CORE(stp_core_ctx))) { -+ STP_WARN_FUNC("***** Release psm hold data before send normal data *****\n"); -+ stp_psm_release_data(STP_PSM_CORE(stp_core_ctx)); -+ } -+ } else { -+ ret = stp_psm_hold_data(STP_PSM_CORE(stp_core_ctx), buffer, length, type); -+ stp_psm_notify_wmt_wakeup(STP_PSM_CORE(stp_core_ctx)); -+ /*-----------------------------STP_PSM_UnLock----------------------------------------*/ -+ stp_psm_thread_lock_release(STP_PSM_CORE(stp_core_ctx)); -+ return ret; -+ } -+ } -+ } else { -+ /* if(stp_is_apply_powersaving()) */ -+ { -+ if (type == WMT_TASK_INDX) -+ goto DONT_MONITOR; -+ /* If now chip is awake, to restart monitor! */ -+ /* STP_INFO_FUNC("check if block traffic !!\n"); */ -+ /*-----------------------------STP_PSM_Lock----------------------------------------*/ -+ ret = stp_psm_thread_lock_aquire(STP_PSM_CORE(stp_core_ctx)); -+ if (ret) { -+ STP_ERR_FUNC("--->lock psm_thread_lock failed ret=%d\n", ret); -+ return ret; -+ } -+ -+ if (!stp_psm_is_to_block_traffic(STP_PSM_CORE(stp_core_ctx))) { -+ /* STP_INFO_FUNC("not to block !!\n"); */ -+ if (stp_psm_has_pending_data(STP_PSM_CORE(stp_core_ctx))) { -+ STP_WARN_FUNC("***** Release psm hold data before send normal data *****\n"); -+ stp_psm_release_data(STP_PSM_CORE(stp_core_ctx)); -+ } -+ stp_psm_start_monitor(STP_PSM_CORE(stp_core_ctx)); -+ } else { -+ /* STP_INFO_FUNC("to block !!\n"); */ -+ -+ /* STP_INFO_FUNC("*****hold data in psm queue data length = %d\n", -+ * length); -+ */ -+ /* stp_dump_data(buffer, "Hold in psm queue", length); */ -+ /* hold datas */ -+ ret = stp_psm_hold_data(STP_PSM_CORE(stp_core_ctx), buffer, length, type); -+ /* wmt notification */ -+ STP_INFO_FUNC("#####Type = %d, to inform WMT to wakeup chip, ret = %d:0x%2x,0x%2x\n", -+ type, ret, *buffer, *(buffer + 1)); -+ stp_psm_notify_wmt_wakeup(STP_PSM_CORE(stp_core_ctx)); -+ /* STP_INFO_FUNC("*********Type = %d, to inform WMT to wakeup chip>end\n", type); */ -+ /*-----------------------------STP_PSM_UnLock----------------------------------------*/ -+ stp_psm_thread_lock_release(STP_PSM_CORE(stp_core_ctx)); -+ return ret; -+ } -+ } -+ } -+DONT_MONITOR: -+#endif -+ if (type == BT_TASK_INDX) { -+ static const UINT8 rst_buf[4] = { 0x01, 0x03, 0x0c, 0x00 }; -+ -+ if (!osal_strncmp(buffer, rst_buf, 4)) -+ osal_printtimeofday("############ BT Rest start -->"); -+ } -+ /* osal_lock_unsleepable_lock(&stp_core_ctx.stp_mutex); */ -+ stp_ctx_lock(&stp_core_ctx); -+ /*Only WMT can set raw data */ -+ if (STP_NOT_ENABLE(stp_core_ctx) && WMT_TASK_INDX != type) { -+ /* no-op */ -+ /* NULL; */ -+ } else if (STP_NOT_ENABLE(stp_core_ctx) && WMT_TASK_INDX == type) { -+ /* ret = mtk_wcn_stp_send_data_raw(buffer, length, type); */ -+ /* NULL; */ -+ } -+ /* STP over SDIO */ -+ else if ((mtk_wcn_stp_is_sdio_mode() || mtk_wcn_stp_is_btif_mand_mode()) && STP_IS_ENABLE(stp_core_ctx)) { -+ -+ /* osal_printtimeofday("[ STP][SDIO][ B][W]"); */ -+ -+ mtkstp_header[0] = 0x80; -+ mtkstp_header[1] = (type << 4) + (((length) >> 8) & 0x0f); -+ mtkstp_header[2] = (length) & 0xff; -+ mtkstp_header[3] = 0x00; -+ -+ /* HEADER */ -+ p_tx_buf = &stp_core_ctx.tx_buf[0]; -+ osal_memcpy(p_tx_buf, mtkstp_header, MTKSTP_HEADER_SIZE); -+ p_tx_buf += MTKSTP_HEADER_SIZE; -+ -+ /* PAYLOAD */ -+ osal_memcpy(p_tx_buf, buffer, length); -+ p_tx_buf += length; -+ -+ /* CRC */ -+ temp[0] = 0x00; -+ temp[1] = 0x00; -+ osal_memcpy(p_tx_buf, temp, 2); -+ stp_dbg_pkt_log(type, 0, 0, 0, PKT_DIR_TX, buffer, length); -+ (*sys_if_tx) (&stp_core_ctx.tx_buf[0], (MTKSTP_HEADER_SIZE + length + 2), &ret); -+ -+ if ((MTKSTP_HEADER_SIZE + length + 2) != ret) { -+ STP_ERR_FUNC("stp send tx packet: %d, maybe stp_if_tx == NULL\n", ret); -+ osal_assert(0); -+ ret = 0; -+ } else { -+ ret = (INT32) length; -+ } -+ -+ /* osal_printtimeofday("[ STP][SDIO][ E][W]"); */ -+ } -+ /* STP over UART */ -+ else if (mtk_wcn_stp_is_btif_fullset_mode() && STP_IS_ENABLE(stp_core_ctx)) { -+ -+ /* osal_printtimeofday("[ STP][UART][ B][W]"); */ -+ /* STP_INFO_FUNC("Write byte %d\n", length); */ -+ -+ if ((stp_core_ctx.sequence.winspace > 0) && -+ (stp_core_ctx.inband_rst_set == 0) && -+ (stp_is_tx_res_available(MTKSTP_HEADER_SIZE + length + MTKSTP_CRC_SIZE))) { -+ /*Make Header */ -+ /* (*sys_dbg_print)("mtk_wcn_stp_send_data 1, txseq = %d, winspace = %d", -+ * stp_core_ctx.sequence.txseq, stp_core_ctx.sequence.winspace); -+ */ -+ mtkstp_header[0] = 0x80 + (stp_core_ctx.sequence.txseq << 3) + stp_core_ctx.sequence.txack; -+ mtkstp_header[1] = (type << 4) + ((length & 0xf00) >> 8); -+ mtkstp_header[2] = length & 0xff; -+ mtkstp_header[3] = (mtkstp_header[0] + mtkstp_header[1] + mtkstp_header[2]) & 0xff; -+ stp_core_ctx.tx_start_addr[stp_core_ctx.sequence.txseq] = stp_core_ctx.tx_write; -+ stp_core_ctx.tx_length[stp_core_ctx.sequence.txseq] = MTKSTP_HEADER_SIZE + length + 2; -+ if (fgEnableDelimiter == 1) { -+ stp_core_ctx.tx_length[stp_core_ctx.sequence.txseq] += STP_DEL_SIZE; -+ stp_add_to_tx_queue(&stp_delimiter[0], STP_DEL_SIZE); -+ } -+ stp_add_to_tx_queue(mtkstp_header, MTKSTP_HEADER_SIZE); -+ -+ /*Make Payload */ -+ stp_add_to_tx_queue(buffer, length); -+ -+ /*Make CRC */ -+ crc = osal_crc16(buffer, length); -+ temp[0] = crc & 0xff; -+ temp[1] = (crc & 0xff00) >> 8; -+ stp_add_to_tx_queue(temp, 2); -+ stp_dbg_pkt_log(type, -+ stp_core_ctx.sequence.txack, -+ stp_core_ctx.sequence.txseq, crc, PKT_DIR_TX, buffer, length); -+ -+ /*Kick to UART */ -+ stp_send_tx_queue(stp_core_ctx.sequence.txseq); -+ -+ INDEX_INC(stp_core_ctx.sequence.txseq); -+ stp_core_ctx.sequence.winspace--; -+ -+ /*Setup the Retry Timer */ -+ osal_timer_stop(&stp_core_ctx.tx_timer); -+ if (stp_core_ctx.sequence.winspace != MTKSTP_WINSIZE) -+ osal_timer_start(&stp_core_ctx.tx_timer, mtkstp_tx_timeout); -+ else -+ STP_ERR_FUNC("mtk_wcn_stp_send_data: wmt_stop_timer\n"); -+ -+ ret = (INT32) length; -+ } else { -+ /* -+ No winspace to send. Let caller retry -+ */ -+ if (stp_core_ctx.inband_rst_set == 1) -+ STP_WARN_FUNC("Now it's inband reset process and drop sent packet.\n"); -+ else -+ STP_ERR_FUNC("There is no winspace/txqueue to send !!!\n"); -+ -+ ret = 0; -+ } -+ -+ /* osal_printtimeofday("[ STP][UART][ E][W]"); */ -+ } -+ /* osal_unlock_unsleepable_lock(&stp_core_ctx.stp_mutex); */ -+ stp_ctx_unlock(&stp_core_ctx); -+ -+#ifdef CONFIG_POWER_SAVING_SUPPORT -+ -+ if (MTK_WCN_BOOL_TRUE == is_quick_enable) { -+ if (type != WMT_TASK_INDX) { -+ stp_psm_notify_wmt_sleep(STP_PSM_CORE(stp_core_ctx)); -+ /*-----------------------STP_PSM_UnLock-------------------------*/ -+ stp_psm_thread_lock_release(STP_PSM_CORE(stp_core_ctx)); -+ } -+ } else { -+ /* if(stp_is_apply_powersaving()) */ -+ /* { */ -+ if (type != WMT_TASK_INDX) { -+ -+ /*--------------------STP_PSM_UnLock--------------------------*/ -+ stp_psm_thread_lock_release(STP_PSM_CORE(stp_core_ctx)); -+ } -+ /* } */ -+ } -+#endif -+ -+ return ret; -+} -+#if !STP_EXP_HID_API_EXPORT -+EXPORT_SYMBOL(mtk_wcn_stp_send_data); -+#endif -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_send_data_raw -+* DESCRIPTION -+* send raw data to common interface, bypass STP -+* PARAMETERS -+* buffer [IN] data buffer -+* length [IN] data buffer length -+* type [IN] subfunction type -+* RETURNS -+* INT32 >= 0: length transmitted; < 0: error -+*****************************************************************************/ -+#if STP_EXP_HID_API_EXPORT -+INT32 _mtk_wcn_stp_send_data_raw(const PUINT8 buffer, const UINT32 length, const UINT8 type) -+#else -+INT32 mtk_wcn_stp_send_data_raw(const PUINT8 buffer, const UINT32 length, const UINT8 type) -+#endif -+{ -+ UINT32 written = 0; -+ INT32 ret = 0; -+ -+ if (0 != STP_WMT_LAST_CLOSE(stp_core_ctx)) { -+ STP_ERR_FUNC("WMT lats close,should not have tx request!"); -+ return length; -+ } -+ -+ STP_DBG_FUNC("mtk_wcn_stp_send_data_raw, type = %d, data = %x %x %x %x %x %x ", type, buffer[0], buffer[1], -+ buffer[2], buffer[3], buffer[4], buffer[5]); -+ STP_SET_PENDING_TYPE(stp_core_ctx, type); /* remember tx type, forward following rx to this type */ -+ -+ /* osal_lock_unsleepable_lock(&stp_core_ctx.stp_mutex); */ -+ stp_ctx_lock(&stp_core_ctx); -+ stp_dbg_pkt_log(type, 0, 0, 0, PKT_DIR_TX, buffer, 1); -+ (*sys_if_tx) (&buffer[0], length, &written); -+ /* osal_unlock_unsleepable_lock(&stp_core_ctx.stp_mutex); */ -+ stp_ctx_unlock(&stp_core_ctx); -+ -+ if (written == 0) -+ stp_dump_data(&buffer[0], "tx raw failed:", length); -+ -+ if (written == length) -+ ret = (INT32) written; -+ else -+ ret = (-1); -+ -+ return ret; -+} -+#if !STP_EXP_HID_API_EXPORT -+EXPORT_SYMBOL(mtk_wcn_stp_send_data_raw); -+#endif -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_receive_data -+* DESCRIPTION -+* receive data from serial protocol engine -+* PARAMETERS -+* buffer [IN] data buffer -+* length [IN] data buffer length -+* type [IN] subfunction type -+* RETURNS -+* INT32 >= 0: size of data received; < 0: error -+*****************************************************************************/ -+#if STP_EXP_HID_API_EXPORT -+INT32 _mtk_wcn_stp_receive_data(UINT8 *buffer, UINT32 length, UINT8 type) -+#else -+INT32 mtk_wcn_stp_receive_data(UINT8 *buffer, UINT32 length, UINT8 type) -+#endif -+{ -+ /* GeorgeKuo modify: reduce "if" branch */ -+ UINT16 copyLen = 0; -+ UINT16 tailLen = 0; -+ -+ osal_lock_unsleepable_lock(&stp_core_ctx.ring[type].mtx); -+ -+ while (stp_core_ctx.ring[type].read_p != stp_core_ctx.ring[type].write_p) { -+ /* GeorgeKuo modify: reduce if branch */ -+ if (stp_core_ctx.ring[type].write_p > stp_core_ctx.ring[type].read_p) { -+ copyLen = stp_core_ctx.ring[type].write_p - stp_core_ctx.ring[type].read_p; -+ if (copyLen > length) -+ copyLen = length; -+ -+ osal_memcpy(buffer, stp_core_ctx.ring[type].buffer + stp_core_ctx.ring[type].read_p, copyLen); -+ stp_core_ctx.ring[type].read_p += copyLen; -+ } else { -+ tailLen = MTKSTP_BUFFER_SIZE - stp_core_ctx.ring[type].read_p; -+ if (tailLen > length) { /* exclude equal case to skip wrap check */ -+ copyLen = length; -+ osal_memcpy(buffer, stp_core_ctx.ring[type].buffer + stp_core_ctx.ring[type].read_p, -+ copyLen); -+ stp_core_ctx.ring[type].read_p += copyLen; -+ } else { -+ /* part 1: copy tailLen */ -+ osal_memcpy(buffer, stp_core_ctx.ring[type].buffer + stp_core_ctx.ring[type].read_p, -+ tailLen); -+ -+ buffer += tailLen; /* update buffer offset */ -+ -+ /* part 2: check if head length is enough */ -+ copyLen = length - tailLen; -+ copyLen = -+ (stp_core_ctx.ring[type].write_p < -+ copyLen) ? stp_core_ctx.ring[type].write_p : copyLen; -+ -+ if (copyLen) -+ osal_memcpy(buffer, stp_core_ctx.ring[type].buffer + 0, copyLen); -+ -+ /* Update read_p final position */ -+ stp_core_ctx.ring[type].read_p = copyLen; -+ -+ /* update return length: head + tail */ -+ copyLen += tailLen; -+ } -+ } -+ break; -+ } -+ -+ osal_unlock_unsleepable_lock(&stp_core_ctx.ring[type].mtx); -+ -+ if ((MTK_WCN_BOOL_TRUE == stp_psm_is_quick_ps_support()) && (type != WMT_TASK_INDX)) { -+#if PSM_USE_COUNT_PACKAGE -+ stp_psm_disable_by_tx_rx_density(STP_PSM_CORE(stp_core_ctx), 1); -+#else -+ stp_psm_disable_by_tx_rx_density(STP_PSM_CORE(stp_core_ctx), 1, copyLen); -+#endif -+ } -+ -+ return copyLen; -+} -+#if !STP_EXP_HID_API_EXPORT -+EXPORT_SYMBOL(mtk_wcn_stp_receive_data); -+#endif -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_is_rxqueue_empty -+* DESCRIPTION -+* Is certain rx queue empty? -+* PARAMETERS -+* type [IN] subfunction type -+* RETURNS -+* INT32 0: queue is NOT empyt; !0: queue is empty -+*****************************************************************************/ -+#if STP_EXP_HID_API_EXPORT -+INT32 _mtk_wcn_stp_is_rxqueue_empty(UINT8 type) -+#else -+INT32 mtk_wcn_stp_is_rxqueue_empty(UINT8 type) -+#endif -+{ -+ INT32 ret; -+ -+ osal_lock_unsleepable_lock(&stp_core_ctx.ring[type].mtx); -+ -+ if (stp_core_ctx.ring[type].read_p == stp_core_ctx.ring[type].write_p) -+ ret = 1; /* queue is empty */ -+ else -+ ret = 0; /* queue is not empty */ -+ -+ osal_unlock_unsleepable_lock(&stp_core_ctx.ring[type].mtx); -+ -+ return ret; -+} -+#if !STP_EXP_HID_API_EXPORT -+EXPORT_SYMBOL(mtk_wcn_stp_is_rxqueue_empty); -+#endif -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_set_sdio_mode -+* DESCRIPTION -+* Set stp for SDIO mode -+* PARAMETERS -+* sdio_flag [IN] sdio mode flag (TRUE:SDIO mode, FALSE:UART mode) -+* RETURNS -+* void -+*****************************************************************************/ -+ -+void mtk_wcn_stp_set_mode(UINT32 mode) -+{ -+ STP_SET_SUPPORT_PROTOCOL(stp_core_ctx, mode); -+ -+ STP_DBG_FUNC("STP_SUPPORT_PROTOCOL = %08x\n", STP_SUPPORT_PROTOCOL(stp_core_ctx)); -+} -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_is_uart_fullset_mode -+* DESCRIPTION -+* Is stp use UART fullset mode? -+* PARAMETERS -+* none. -+* RETURNS -+* MTK_WCN_BOOL TRUE:Uart Fullset mode, FALSE:Not UART Fullset mode -+*****************************************************************************/ -+MTK_WCN_BOOL mtk_wcn_stp_is_uart_fullset_mode(void) -+{ -+ /* -+ bit 0: uart fullset mode -+ bit 1: uart mandatory mode -+ bit 2: sdio mode -+ */ -+ if (STP_SUPPORT_PROTOCOL(stp_core_ctx) & MTKSTP_UART_FULL_MODE) -+ return MTK_WCN_BOOL_TRUE; -+ else -+ return MTK_WCN_BOOL_FALSE; -+} -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_is_uart_mand_mode -+* DESCRIPTION -+* Is stp use UART mandatory mode? -+* PARAMETERS -+* none. -+* RETURNS -+* MTK_WCN_BOOL TRUE:Uart Mandatory mode, FALSE:Not UART Mandotary mode -+*****************************************************************************/ -+MTK_WCN_BOOL mtk_wcn_stp_is_uart_mand_mode(void) -+{ -+ /* -+ bit 0: uart fullset mode -+ bit 1: uart mandatory mode -+ bit 2: sdio mode -+ */ -+ if (STP_SUPPORT_PROTOCOL(stp_core_ctx) & MTKSTP_UART_MAND_MODE) -+ return MTK_WCN_BOOL_TRUE; -+ else -+ return MTK_WCN_BOOL_FALSE; -+} -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_is_btif_fullset_mode -+* DESCRIPTION -+* Is stp use BTIF fullset mode? -+* PARAMETERS -+* none. -+* RETURNS -+* MTK_WCN_BOOL TRUE:BTIF Fullset mode, FALSE:Not BTIF Fullset mode -+*****************************************************************************/ -+MTK_WCN_BOOL mtk_wcn_stp_is_btif_fullset_mode(void) -+{ -+ -+ if (STP_SUPPORT_PROTOCOL(stp_core_ctx) & MTKSTP_BTIF_FULL_MODE) -+ return MTK_WCN_BOOL_TRUE; -+ else -+ return MTK_WCN_BOOL_FALSE; -+} -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_is_btif_mand_mode -+* DESCRIPTION -+* Is stp use BTIF mandatory mode? -+* PARAMETERS -+* none. -+* RETURNS -+* MTK_WCN_BOOL TRUE:BTIF Mandatory mode, FALSE:Not BTIF Mandotary mode -+*****************************************************************************/ -+ -+MTK_WCN_BOOL mtk_wcn_stp_is_btif_mand_mode(void) -+{ -+ -+ if (STP_SUPPORT_PROTOCOL(stp_core_ctx) & MTKSTP_BTIF_MAND_MODE) -+ return MTK_WCN_BOOL_TRUE; -+ else -+ return MTK_WCN_BOOL_FALSE; -+} -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_is_sdio_mode -+* DESCRIPTION -+* Is stp use SDIO mode? -+* PARAMETERS -+* none. -+* RETURNS -+* MTK_WCN_BOOL TRUE:SDIO mode, FALSE:UART mode -+*****************************************************************************/ -+MTK_WCN_BOOL mtk_wcn_stp_is_sdio_mode(void) -+{ -+ /* -+ bit 0: uart fullset mode -+ bit 1: uart mandatory mode -+ bit 2: sdio mode -+ */ -+ if (STP_SUPPORT_PROTOCOL(stp_core_ctx) & MTKSTP_SDIO_MODE) -+ return MTK_WCN_BOOL_TRUE; -+ else -+ return MTK_WCN_BOOL_FALSE; -+} -+ -+/***************************************************************************** -+* FUNCTION -+* stp_send_inband_reset -+* DESCRIPTION -+* To sync to oringnal stp state with f/w stp -+* PARAMETERS -+* none. -+* RETURNS -+* none -+*****************************************************************************/ -+void mtk_wcn_stp_inband_reset(void) -+{ -+ UINT8 inband_reset_packet[64]; -+ UINT32 txseq = 0; -+ UINT32 txack = 0; -+ UINT32 crc = 0; -+ UINT32 ret = 0; -+ UINT32 reset_payload_len = 0; -+ -+ /*512 bytes */ -+ UINT8 reset_payload[] = { -+ 0xc0, 0x01, 0xc0, 0xde, 0x3e, 0xd1, 0xa7, 0xef -+ }; -+ -+ /* osal_lock_unsleepable_lock(&stp_core_ctx.stp_mutex); */ -+ stp_ctx_lock(&stp_core_ctx); -+ -+ /*RESYNC*/ inband_reset_packet[0] = 0x7f; -+ inband_reset_packet[1] = 0x7f; -+ inband_reset_packet[2] = 0x7f; -+ inband_reset_packet[3] = 0x7f; -+ inband_reset_packet[4] = 0x7f; -+ inband_reset_packet[5] = 0x7f; -+ inband_reset_packet[6] = 0x7f; -+ inband_reset_packet[7] = 0x7f; -+ -+ /*header */ -+ reset_payload_len = sizeof(reset_payload) / sizeof(reset_payload[0]); -+ inband_reset_packet[8] = 0x80 + (txseq << 3) + txack; -+ inband_reset_packet[9] = (STP_TASK_INDX << 4) + ((reset_payload_len & 0xf00) >> 8); -+ inband_reset_packet[10] = reset_payload_len & 0xff; -+ inband_reset_packet[11] = (inband_reset_packet[8] + inband_reset_packet[9] + inband_reset_packet[10]) & 0xff; -+ -+ /*payload */ -+ osal_memcpy(&inband_reset_packet[12], reset_payload, reset_payload_len); -+ -+ /*crc */ -+ crc = osal_crc16(&reset_payload[0], reset_payload_len); -+ inband_reset_packet[12 + reset_payload_len] = crc & 0xff; -+ inband_reset_packet[12 + reset_payload_len + 1] = (crc & 0xff00) >> 8; -+ -+ (*sys_if_tx) (&inband_reset_packet[0], 14 + reset_payload_len, &ret); -+ -+ if (ret != (14 + reset_payload_len)) -+ STP_ERR_FUNC("Inband sending error, sending %d , but ret = %d\n", 10 + reset_payload_len, ret); -+ -+ stp_core_ctx.inband_rst_set = 1; -+ stp_ctx_unlock(&stp_core_ctx); -+ /* osal_unlock_unsleepable_lock(&stp_core_ctx.stp_mutex); */ -+} -+ -+void mtk_wcn_stp_debug_ctrl(INT32 op, INT32 filter, INT32 filter_param) -+{ -+ /*nothing at now*/ -+} -+ -+void mtk_wcn_stp_test_cmd(INT32 cmd_no) -+{ -+ UINT8 test_packet[64]; -+ UINT32 txseq = 0; -+ UINT32 txack = 0; -+ UINT32 crc = 0; -+ UINT32 ret = 0; -+ UINT32 reset_payload_len = 0; -+ -+ UINT8 test_payload[] = { -+ 0xAA, 0xAA, 0xC0, 0xDE, 0x3E, 0xD1, 0xA7, 0xEF -+ }; -+/* */ -+/* select your test command by cmd_no */ -+/* */ -+ if (cmd_no == 0) { -+ /* to test new command to chip */ -+ /* osal_lock_unsleepable_lock(&stp_core_ctx.stp_mutex); */ -+ stp_ctx_lock(&stp_core_ctx); -+ -+ /*RESYNC*/ test_packet[0] = 0x7f; -+ test_packet[1] = 0x7f; -+ test_packet[2] = 0x7f; -+ test_packet[3] = 0x7f; -+ test_packet[4] = 0x7f; -+ test_packet[5] = 0x7f; -+ test_packet[6] = 0x7f; -+ test_packet[7] = 0x7f; -+ -+ /*header */ -+ reset_payload_len = sizeof(test_payload) / sizeof(test_payload[0]); -+ test_packet[8] = 0x80 + (txseq << 3) + txack; -+ test_packet[9] = (STP_TASK_INDX << 4) + ((reset_payload_len & 0xf00) >> 8); -+ test_packet[10] = reset_payload_len & 0xff; -+ test_packet[11] = (test_packet[8] + test_packet[9] + test_packet[10]) & 0xff; -+ -+ /*payload */ -+ osal_memcpy(&test_packet[12], test_payload, reset_payload_len); -+ -+ /*crc */ -+ crc = osal_crc16(&test_payload[0], reset_payload_len); -+ test_packet[12 + reset_payload_len] = crc & 0xff; -+ test_packet[12 + reset_payload_len + 1] = (crc & 0xff00) >> 8; -+ -+ (*sys_if_tx) (&test_packet[0], 14 + reset_payload_len, &ret); -+ if (ret != (14 + reset_payload_len)) { -+ STP_ERR_FUNC("stp test sending error, sending %d , but ret = %d\n", 10 + reset_payload_len, -+ ret); -+ } -+ /* osal_unlock_unsleepable_lock(&stp_core_ctx.stp_mutex); */ -+ stp_ctx_unlock(&stp_core_ctx); -+ } -+ -+} -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_flush_context -+* DESCRIPTION -+* Flush STP Context -+* PARAMETERS -+* none. -+* RETURNS -+* none -+*****************************************************************************/ -+void mtk_wcn_stp_flush_context(void) -+{ -+ stp_rest_ctx_state(); -+} -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_flush_rx_queue -+* DESCRIPTION -+* Flush STP Rx Queue -+* PARAMETERS -+* none. -+* RETURNS -+* none -+*****************************************************************************/ -+ -+void mtk_wcn_stp_flush_rx_queue(UINT32 type) -+{ -+ osal_lock_unsleepable_lock(&stp_core_ctx.ring[type].mtx); -+ if (type < MTKSTP_MAX_TASK_NUM) { -+ stp_core_ctx.ring[type].read_p = 0; -+ stp_core_ctx.ring[type].write_p = 0; -+ } -+ osal_unlock_unsleepable_lock(&stp_core_ctx.ring[type].mtx); -+} -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_is_enable -+* DESCRIPTION -+* STP is ready? -+* PARAMETERS -+* none. -+* RETURNS -+* none -+*****************************************************************************/ -+#if STP_EXP_HID_API_EXPORT -+MTK_WCN_BOOL _mtk_wcn_stp_is_ready(void) -+#else -+MTK_WCN_BOOL mtk_wcn_stp_is_ready(void) -+#endif -+{ -+ return STP_IS_READY(stp_core_ctx); -+} -+#if !STP_EXP_HID_API_EXPORT -+EXPORT_SYMBOL(mtk_wcn_stp_is_ready); -+#endif -+/***************************************************************************** -+* FUNCTION -+* set_bluetooth_rx_interface -+* DESCRIPTION -+* Set bluetooth rx interface -+* PARAMETERS -+* rx interface type -+* RETURNS -+* void -+*****************************************************************************/ -+#if STP_EXP_HID_API_EXPORT -+void _mtk_wcn_stp_set_bluez(MTK_WCN_BOOL bluez_flag) -+#else -+void mtk_wcn_stp_set_bluez(MTK_WCN_BOOL bluez_flag) -+#endif -+{ -+ /* g_mtkstp_bluez_flag = bluez_flag; */ -+ STP_SET_BT_STK(stp_core_ctx, bluez_flag); -+} -+#if !STP_EXP_HID_API_EXPORT -+EXPORT_SYMBOL(mtk_wcn_stp_set_bluez); -+#endif -+/***************************************************************************** -+* FUNCTION -+* set stp debugging mdoe -+* DESCRIPTION -+* set stp debugging mdoe -+* PARAMETERS -+* dbg_mode: switch to dbg mode ? -+* RETURNS -+* void -+*****************************************************************************/ -+void mtk_wcn_stp_set_dbg_mode(MTK_WCN_BOOL dbg_mode) -+{ -+ STP_SET_ENABLE_DBG(stp_core_ctx, dbg_mode); -+} -+ -+/***************************************************************************** -+* FUNCTION -+* set stp auto reset mdoe -+* DESCRIPTION -+* set stp auto reset mdoe -+* PARAMETERS -+* auto_rst: switch to auto reset mode ? -+* RETURNS -+* void -+*****************************************************************************/ -+void mtk_wcn_stp_set_auto_rst(MTK_WCN_BOOL auto_rst) -+{ -+ STP_SET_ENABLE_RST(stp_core_ctx, auto_rst); -+} -+ -+INT32 mtk_wcn_stp_notify_sleep_for_thermal(void) -+{ -+ return stp_psm_sleep_for_thermal(STP_PSM_CORE(stp_core_ctx)); -+} -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_open_btif -+* DESCRIPTION -+* init btif hw & sw by owner stp -+* PARAMETERS -+* VOID -+* RETURNS -+* INT32 0-success,other fail. -+*****************************************************************************/ -+INT32 mtk_wcn_stp_open_btif(VOID) -+{ -+ return mtk_wcn_consys_stp_btif_open(); -+} -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_open_close -+* DESCRIPTION -+* close btif hw & sw by owner stp -+* PARAMETERS -+* VOID -+* RETURNS -+* INT32 0-success,other fail. -+*****************************************************************************/ -+INT32 mtk_wcn_stp_close_btif(VOID) -+{ -+ return mtk_wcn_consys_stp_btif_close(); -+} -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_rx_cb_register -+* DESCRIPTION -+* register stp rx cb to btif -+* PARAMETERS -+* MTK_WCN_BTIF_RX_CB stp rx handle function -+* RETURNS -+* INT32 0-success,other fail. -+*****************************************************************************/ -+INT32 mtk_wcn_stp_rxcb_register(MTK_WCN_BTIF_RX_CB rx_cb) -+{ -+ return mtk_wcn_consys_stp_btif_rx_cb_register(rx_cb); -+} -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_tx -+* DESCRIPTION -+* send stp package by btif -+* PARAMETERS -+* pBuf:package buffer pointer,len:package length -+* written_len:package written length -+* RETURNS -+* INT32 package length-success,other fail. -+*****************************************************************************/ -+INT32 mtk_wcn_stp_tx(UINT8 *pBuf, UINT32 len, UINT32 *written_len) -+{ -+ INT32 iRet = -1; -+ -+ iRet = mtk_wcn_consys_stp_btif_tx(pBuf, len, written_len); -+ return iRet; -+} -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_wakeup_consys -+* DESCRIPTION -+* STP wakeup consys by btif -+* PARAMETERS -+* VOID -+* RETURNS -+* INT32 0-success,other fail. -+*****************************************************************************/ -+INT32 mtk_wcn_stp_wakeup_consys(VOID) -+{ -+ /*log wakeup int for debug */ -+ stp_dbg_pkt_log(7, 0, 0, 0, PKT_DIR_TX, NULL, 0); -+ return mtk_wcn_consys_stp_btif_wakeup(); -+} -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_dpidle_ctrl -+* DESCRIPTION -+* decide AP enter or exit deep idle -+* PARAMETERS -+* en_flag:1,enter,0,exit -+* RETURNS -+* always 0 -+*****************************************************************************/ -+INT32 mtk_wcn_stp_dpidle_ctrl(ENUM_BTIF_DPIDLE_CTRL en_flag) -+{ -+ mtk_wcn_consys_stp_btif_dpidle_ctrl(en_flag); -+ -+ return 0; -+} -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_lpbk_ctrl -+* DESCRIPTION -+* enable stp internal lpbk test or not -+* PARAMETERS -+* mode:1,enable,0,disabel -+* RETURNS -+* INT32 0-success,other fail. -+*****************************************************************************/ -+INT32 mtk_wcn_stp_lpbk_ctrl(ENUM_BTIF_LPBK_MODE mode) -+{ -+ return mtk_wcn_consys_stp_btif_lpbk_ctrl(mode); -+} -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_logger_ctrl -+* DESCRIPTION -+* dump btif buffer or register status when No ACK or assert occurs -+* PARAMETERS -+* flag:see enum value in ENUM_BTIF_DBG_ID -+* RETURNS -+* INT32 0-success,other fail. -+*****************************************************************************/ -+INT32 mtk_wcn_stp_logger_ctrl(ENUM_BTIF_DBG_ID flag) -+{ -+ return mtk_wcn_consys_stp_btif_logger_ctrl(flag); -+} -+ -+VOID mtk_wcn_stp_ctx_save(void) -+{ -+ STP_INFO_FUNC("start ++\n"); -+ mtk_wcn_stp_coredump_start_ctrl(1); -+ stp_psm_set_sleep_disable(stp_core_ctx.psm); -+ STP_INFO_FUNC("exit --\n"); -+} -+ -+VOID mtk_wcn_stp_ctx_restore(void) -+{ -+ STP_INFO_FUNC("start ++\n"); -+ stp_psm_set_sleep_enable(stp_core_ctx.psm); -+ stp_btm_reset_btm_wq(STP_BTM_CORE(stp_core_ctx)); -+ -+ if (STP_IS_ENABLE_RST(stp_core_ctx)) -+ stp_btm_notify_wmt_rst_wq(STP_BTM_CORE(stp_core_ctx)); -+ else -+ STP_INFO_FUNC("No to launch whole chip reset! for debugging purpose\n"); -+#if STP_RETRY_OPTIMIZE -+ g_retry_times = 0; -+#endif -+ STP_INFO_FUNC("exit --\n"); -+} -+ -+INT32 mtk_wcn_stp_wmt_evt_err_trg_assert(void) -+{ -+ INT32 ret = -1; -+ -+ if (mtk_wcn_stp_coredump_start_get() != 0) { -+ STP_INFO_FUNC("firmware assert has been triggered\n"); -+ return 0; -+ } -+ -+ ret = stp_notify_btm_do_fw_assert_via_emi(STP_BTM_CORE(stp_core_ctx)); -+ if (ret) { -+ STP_ERR_FUNC("evt err trigger assert fail,do chip reset to recovery\n"); -+ -+ mtk_wcn_stp_set_wmt_evt_err_trg_assert(0); -+ if (STP_IS_ENABLE_RST(stp_core_ctx)) -+ stp_btm_notify_wmt_rst_wq(STP_BTM_CORE(stp_core_ctx)); -+ else -+ STP_INFO_FUNC("No to launch whole chip reset! for debugging purpose\n"); -+ } -+ -+ return ret; -+} -+ -+VOID mtk_wcn_stp_set_wmt_evt_err_trg_assert(UINT32 value) -+{ -+ STP_INFO_FUNC("set evt err tigger assert flag to %d\n", value); -+ STP_SET_EVT_ERR_ASSERT(stp_core_ctx, value); -+} -+ -+UINT32 mtk_wcn_stp_get_wmt_evt_err_trg_assert(void) -+{ -+ return STP_EVT_ERR_ASSERT(stp_core_ctx); -+} -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_conf.c b/drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_conf.c -new file mode 100644 -index 000000000000..3009bd26df41 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_conf.c -@@ -0,0 +1,529 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -+ -+#ifdef DFT_TAG -+#undef DFT_TAG -+#endif -+#define DFT_TAG "[WMT-CONF]" -+ -+#include "osal_typedef.h" -+/* #include "osal.h" */ -+#include "wmt_lib.h" -+#include "wmt_dev.h" -+#include "wmt_conf.h" -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+struct parse_data { -+ PINT8 name; -+ INT32 (*parser)(P_DEV_WMT pWmtDev, const struct parse_data *data, const PINT8 value); -+ PINT8 (*writer)(P_DEV_WMT pWmtDev, const struct parse_data *data); -+ /*PINT8 param1, *param2, *param3; */ -+ /* TODO:[FixMe][George] CLARIFY WHAT SHOULD BE USED HERE!!! */ -+ PINT8 param1; -+ PINT8 param2; -+ PINT8 param3; -+}; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/****************************************************************************** -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************* -+*/ -+static INT32 wmt_conf_parse_char(P_DEV_WMT pWmtDev, const struct parse_data *data, const PINT8 pos); -+ -+static PINT8 wmt_conf_write_char(P_DEV_WMT pWmtDev, const struct parse_data *data); -+ -+static INT32 wmt_conf_parse_short(P_DEV_WMT pWmtDev, const struct parse_data *data, const PINT8 pos); -+ -+static PINT8 wmt_conf_write_short(P_DEV_WMT pWmtDev, const struct parse_data *data); -+ -+static INT32 wmt_conf_parse_int(P_DEV_WMT pWmtDev, const struct parse_data *data, const PINT8 pos); -+ -+static PINT8 wmt_conf_write_int(P_DEV_WMT pWmtDev, const struct parse_data *data); -+ -+static INT32 wmt_conf_parse_pair(P_DEV_WMT pWmtDev, const PINT8 pKey, const PINT8 pVal); -+ -+static INT32 wmt_conf_parse(P_DEV_WMT pWmtDev, const PINT8 pInBuf, UINT32 size); -+ -+#define OFFSET(v) ((void *) &((P_DEV_WMT) 0)->v) -+ -+#define CHAR(f) \ -+{ \ -+ #f, \ -+ wmt_conf_parse_char, \ -+ wmt_conf_write_char, \ -+ OFFSET(rWmtGenConf.f), \ -+ NULL, \ -+ NULL \ -+} -+/* #define CHAR(f) _CHAR(f), NULL, NULL} */ -+ -+#define SHORT(f) \ -+{ \ -+ #f, \ -+ wmt_conf_parse_short, \ -+ wmt_conf_write_short, \ -+ OFFSET(rWmtGenConf.f), \ -+ NULL, \ -+ NULL \ -+} -+/* #define SHORT(f) _SHORT(f), NULL, NULL */ -+ -+#define INT(f) \ -+{ \ -+ #f, \ -+ wmt_conf_parse_int, \ -+ wmt_conf_write_int, \ -+ OFFSET(rWmtGenConf.f), \ -+ NULL, \ -+ NULL \ -+} -+/* #define INT(f) _INT(f), NULL, NULL */ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+static const struct parse_data wmtcfg_fields[] = { -+ CHAR(coex_wmt_ant_mode), -+ CHAR(coex_wmt_ext_component), -+ CHAR(coex_wmt_wifi_time_ctl), -+ CHAR(coex_wmt_ext_pta_dev_on), -+ CHAR(coex_wmt_filter_mode), -+ -+ CHAR(coex_bt_rssi_upper_limit), -+ CHAR(coex_bt_rssi_mid_limit), -+ CHAR(coex_bt_rssi_lower_limit), -+ CHAR(coex_bt_pwr_high), -+ CHAR(coex_bt_pwr_mid), -+ CHAR(coex_bt_pwr_low), -+ -+ CHAR(coex_wifi_rssi_upper_limit), -+ CHAR(coex_wifi_rssi_mid_limit), -+ CHAR(coex_wifi_rssi_lower_limit), -+ CHAR(coex_wifi_pwr_high), -+ CHAR(coex_wifi_pwr_mid), -+ CHAR(coex_wifi_pwr_low), -+ -+ CHAR(coex_ext_pta_hi_tx_tag), -+ CHAR(coex_ext_pta_hi_rx_tag), -+ CHAR(coex_ext_pta_lo_tx_tag), -+ CHAR(coex_ext_pta_lo_rx_tag), -+ SHORT(coex_ext_pta_sample_t1), -+ SHORT(coex_ext_pta_sample_t2), -+ CHAR(coex_ext_pta_wifi_bt_con_trx), -+ -+ INT(coex_misc_ext_pta_on), -+ INT(coex_misc_ext_feature_set), -+ -+ CHAR(wmt_gps_lna_pin), -+ CHAR(wmt_gps_lna_enable), -+ -+ CHAR(pwr_on_rtc_slot), -+ CHAR(pwr_on_ldo_slot), -+ CHAR(pwr_on_rst_slot), -+ CHAR(pwr_on_off_slot), -+ CHAR(pwr_on_on_slot), -+ CHAR(co_clock_flag), -+ -+ INT(sdio_driving_cfg), -+ -+}; -+ -+#define NUM_WMTCFG_FIELDS (osal_sizeof(wmtcfg_fields) / osal_sizeof(wmtcfg_fields[0])) -+ -+static int wmt_conf_parse_char(P_DEV_WMT pWmtDev, const struct parse_data *data, const PINT8 pos) -+{ -+ PINT8 dst; -+ long res; -+ int ret; -+ -+ dst = (PINT8) (((PUINT8) pWmtDev) + (long)data->param1); -+ -+ if ((osal_strlen(pos) > 2) && ((*pos) == '0') && (*(pos + 1) == 'x')) { -+ ret = osal_strtol(pos + 2, 16, &res); -+ if (ret) -+ WMT_ERR_FUNC("fail(%d)\n", ret); -+ *dst = res; -+ WMT_DBG_FUNC("wmtcfg==> %s=0x%x\n", data->name, *dst); -+ } else { -+ ret = osal_strtol(pos, 10, &res); -+ if (ret) -+ WMT_ERR_FUNC("fail(%d)\n", ret); -+ *dst = res; -+ WMT_DBG_FUNC("wmtcfg==> %s=%d\n", data->name, *dst); -+ } -+ return 0; -+} -+ -+static PINT8 wmt_conf_write_char(P_DEV_WMT pWmtDev, const struct parse_data *data) -+{ -+ PINT8 src; -+ INT32 res; -+ PINT8 value; -+ -+ src = (PINT8) (((PUINT8) pWmtDev) + (long)data->param1); -+ -+ value = osal_malloc(20); -+ if (value == NULL) -+ return NULL; -+ res = osal_snprintf(value, 20, "0x%x", *src); -+ if (res < 0 || res >= 20) { -+ osal_free(value); -+ return NULL; -+ } -+ value[20 - 1] = '\0'; -+ return value; -+} -+ -+static int wmt_conf_parse_short(P_DEV_WMT pWmtDev, const struct parse_data *data, const PINT8 pos) -+{ -+ PUINT16 dst; -+ long res; -+ int ret; -+ -+ dst = (PINT16) (((PUINT8) pWmtDev) + (long)data->param1); -+ -+ /* WMT_INFO_FUNC(">strlen(pos)=%d\n", strlen(pos)); */ -+ -+ if ((osal_strlen(pos) > 2) && ((*pos) == '0') && (*(pos + 1) == 'x')) { -+ ret = osal_strtol(pos + 2, 16, &res); -+ if (ret) -+ WMT_ERR_FUNC("fail(%d)\n", ret); -+ *dst = res; -+ WMT_DBG_FUNC("wmtcfg==> %s=0x%x\n", data->name, *dst); -+ } else { -+ ret = osal_strtol(pos, 10, &res); -+ if (ret) -+ WMT_ERR_FUNC("fail(%d)\n", ret); -+ *dst = res; -+ WMT_DBG_FUNC("wmtcfg==> %s=%d\n", data->name, *dst); -+ } -+ -+ return 0; -+} -+ -+static PINT8 wmt_conf_write_short(P_DEV_WMT pWmtDev, const struct parse_data *data) -+{ -+ PINT16 src; -+ INT32 res; -+ PINT8 value; -+ -+ /* TODO: [FixMe][George] FIX COMPILE WARNING HERE! */ -+ src = (PINT16) (((PUINT8) pWmtDev) + (long)data->param1); -+ -+ value = osal_malloc(20); -+ if (value == NULL) -+ return NULL; -+ res = osal_snprintf(value, 20, "0x%x", *src); -+ if (res < 0 || res >= 20) { -+ osal_free(value); -+ return NULL; -+ } -+ value[20 - 1] = '\0'; -+ return value; -+} -+ -+static int wmt_conf_parse_int(P_DEV_WMT pWmtDev, const struct parse_data *data, const PINT8 pos) -+{ -+ PUINT32 dst; -+ long res; -+ int ret; -+ -+ dst = (PINT32) (((PUINT8) pWmtDev) + (long)data->param1); -+ -+ /* WMT_INFO_FUNC(">strlen(pos)=%d\n", strlen(pos)); */ -+ -+ if ((osal_strlen(pos) > 2) && ((*pos) == '0') && (*(pos + 1) == 'x')) { -+ ret = osal_strtol(pos + 2, 16, &res); -+ if (ret) -+ WMT_ERR_FUNC("fail(%d)\n", ret); -+ *dst = res; -+ WMT_DBG_FUNC("wmtcfg==> %s=0x%x\n", data->name, *dst); -+ } else { -+ ret = osal_strtol(pos, 10, &res); -+ if (ret) -+ WMT_ERR_FUNC("fail(%d)\n", ret); -+ *dst = res; -+ WMT_DBG_FUNC("wmtcfg==> %s=%d\n", data->name, *dst); -+ } -+ -+ return 0; -+} -+ -+static PINT8 wmt_conf_write_int(P_DEV_WMT pWmtDev, const struct parse_data *data) -+{ -+ PINT32 src; -+ INT32 res; -+ PINT8 value; -+ -+ src = (PUINT32) (((PUINT8) pWmtDev) + (long)data->param1); -+ -+ value = osal_malloc(20); -+ if (value == NULL) -+ return NULL; -+ res = osal_snprintf(value, 20, "0x%x", *src); -+ if (res < 0 || res >= 20) { -+ osal_free(value); -+ return NULL; -+ } -+ value[20 - 1] = '\0'; -+ return value; -+} -+ -+static INT32 wmt_conf_parse_pair(P_DEV_WMT pWmtDev, const PINT8 pKey, const PINT8 pVal) -+{ -+ int i = 0; -+ int ret = 0; -+ -+ /* WMT_INFO_FUNC( DBG_NAME "cfg(%s) val(%s)\n", pKey, pVal); */ -+ -+ for (i = 0; i < NUM_WMTCFG_FIELDS; i++) { -+ const struct parse_data *field = &wmtcfg_fields[i]; -+ -+ if (osal_strcmp(pKey, field->name) != 0) -+ continue; -+ if (field->parser(pWmtDev, field, pVal)) { -+ WMT_ERR_FUNC("failed to parse %s '%s'.\n", pKey, pVal); -+ ret = -1; -+ } -+ break; -+ } -+ if (i == NUM_WMTCFG_FIELDS) { -+ WMT_ERR_FUNC("unknown field '%s'.\n", pKey); -+ ret = -1; -+ } -+ -+ return ret; -+} -+ -+static INT32 wmt_conf_parse(P_DEV_WMT pWmtDev, const PINT8 pInBuf, UINT32 size) -+{ -+ PINT8 pch; -+ PINT8 pBuf; -+ PINT8 pLine; -+ PINT8 pKey; -+ PINT8 pVal; -+ PINT8 pPos; -+ INT32 ret = 0; -+ INT32 i = 0; -+ PINT8 pa = NULL; -+ -+ pBuf = osal_malloc(size); -+ if (!pBuf) -+ return -1; -+ -+ osal_memcpy(pBuf, pInBuf, size); -+ pBuf[size] = '\0'; -+ -+ pch = pBuf; -+ /* pch is to be updated by strsep(). Keep pBuf unchanged!! */ -+ -+#if 0 -+ { -+ PINT8 buf_ptr = pBuf; -+ INT32 k = 0; -+ -+ WMT_INFO_FUNC("%s len=%d", "wmcfg.content:", size); -+ for (k = 0; k < size; k++) { -+ /* if(k%16 == 0) WMT_INFO_FUNC("\n"); */ -+ WMT_INFO_FUNC("%c", buf_ptr[k]); -+ } -+ WMT_INFO_FUNC("--end\n"); -+ } -+#endif -+ -+ while ((pLine = osal_strsep(&pch, "\r\n")) != NULL) { -+ /* pch is updated to the end of pLine by strsep() and updated to '\0' */ -+ /*WMT_INFO_FUNC("strsep offset(%d), char(%d, '%c' )\n", pLine-pBuf, *pLine, *pLine); */ -+ /* parse each line */ -+ -+ /* WMT_INFO_FUNC("==> Line = (%s)\n", pLine); */ -+ -+ if (!*pLine) -+ continue; -+ -+ pVal = osal_strchr(pLine, '='); -+ if (!pVal) { -+ WMT_WARN_FUNC("mal-format cfg string(%s)\n", pLine); -+ continue; -+ } -+ -+ /* |<-pLine->|'='<-pVal->|'\n' ('\0')| */ -+ *pVal = '\0'; /* replace '=' with '\0' to get key */ -+ /* |<-pKey->|'\0'|<-pVal->|'\n' ('\0')| */ -+ pKey = pLine; -+ -+ if ((pVal - pBuf) < size) -+ pVal++; -+ -+ /*key handling */ -+ pPos = pKey; -+ /*skip space characeter */ -+ while (((*pPos) == ' ') || ((*pPos) == '\t') || ((*pPos) == '\n')) { -+ if ((pPos - pBuf) >= size) -+ break; -+ pPos++; -+ } -+ /*key head */ -+ pKey = pPos; -+ while (((*pPos) != ' ') && ((*pPos) != '\t') && ((*pPos) != '\0') && ((*pPos) != '\n')) { -+ if ((pPos - pBuf) >= size) -+ break; -+ pPos++; -+ } -+ /*key tail */ -+ (*pPos) = '\0'; -+ -+ /*value handling */ -+ pPos = pVal; -+ /*skip space characeter */ -+ while (((*pPos) == ' ') || ((*pPos) == '\t') || ((*pPos) == '\n')) { -+ if ((pPos - pBuf) >= size) -+ break; -+ pPos++; -+ } -+ /*value head */ -+ pVal = pPos; -+ while (((*pPos) != ' ') && ((*pPos) != '\t') && ((*pPos) != '\0') && ((*pPos) != '\n')) { -+ if ((pPos - pBuf) >= size) -+ break; -+ pPos++; -+ } -+ /*value tail */ -+ (*pPos) = '\0'; -+ -+ /* WMT_DBG_FUNC("parse (key: #%s#, value: #%s#)\n", pKey, pVal); */ -+ ret = wmt_conf_parse_pair(pWmtDev, pKey, pVal); -+ WMT_DBG_FUNC("parse (%s, %s, %d)\n", pKey, pVal, ret); -+ if (ret) -+ WMT_WARN_FUNC("parse fail (%s, %s, %d)\n", pKey, pVal, ret); -+ } -+ -+ for (i = 0; i < NUM_WMTCFG_FIELDS; i++) { -+ const struct parse_data *field = &wmtcfg_fields[i]; -+ -+ pa = field->writer(pWmtDev, field); -+ if (pa) { -+ WMT_DBG_FUNC("#%d(%s)=>%s\n", i, field->name, pa); -+ osal_free(pa); -+ } else { -+ WMT_ERR_FUNC("failed to parse '%s'.\n", field->name); -+ } -+ } -+ osal_free(pBuf); -+ return 0; -+} -+ -+INT32 wmt_conf_set_cfg_file(const char *name) -+{ -+ if (NULL == name) { -+ WMT_ERR_FUNC("name is NULL\n"); -+ return -1; -+ } -+ if (osal_strlen(name) >= osal_sizeof(gDevWmt.cWmtcfgName)) { -+ WMT_ERR_FUNC("name is too long, length=%d, expect to < %d\n", osal_strlen(name), -+ osal_sizeof(gDevWmt.cWmtcfgName)); -+ return -2; -+ } -+ osal_memset(&gDevWmt.cWmtcfgName[0], 0, osal_sizeof(gDevWmt.cWmtcfgName)); -+ osal_strcpy(&(gDevWmt.cWmtcfgName[0]), name); -+ WMT_ERR_FUNC("WMT config file is set to (%s)\n", &(gDevWmt.cWmtcfgName[0])); -+ -+ return 0; -+} -+ -+INT32 wmt_conf_read_file(VOID) -+{ -+ INT32 ret = -1; -+ -+ osal_memset(&gDevWmt.rWmtGenConf, 0, osal_sizeof(gDevWmt.rWmtGenConf)); -+ osal_memset(&gDevWmt.pWmtCfg, 0, osal_sizeof(gDevWmt.pWmtCfg)); -+ -+#if 1 -+ osal_memset(&gDevWmt.cWmtcfgName[0], 0, osal_sizeof(gDevWmt.cWmtcfgName)); -+ -+ osal_strncat(&(gDevWmt.cWmtcfgName[0]), CUST_CFG_WMT_PREFIX, osal_sizeof(CUST_CFG_WMT_PREFIX)); -+ osal_strncat(&(gDevWmt.cWmtcfgName[0]), CUST_CFG_WMT, osal_sizeof(CUST_CFG_WMT)); -+#endif -+ -+ if (!osal_strlen(&(gDevWmt.cWmtcfgName[0]))) { -+ WMT_ERR_FUNC("empty Wmtcfg name\n"); -+ osal_assert(0); -+ return ret; -+ } -+ WMT_DBG_FUNC("WMT config file:%s\n", &(gDevWmt.cWmtcfgName[0])); -+ if (0 == wmt_dev_patch_get(&gDevWmt.cWmtcfgName[0], (osal_firmware **) &gDevWmt.pWmtCfg, 0)) { -+ /*get full name patch success */ -+ WMT_DBG_FUNC("get full file name(%s) buf(0x%p) size(%d)\n", -+ &gDevWmt.cWmtcfgName[0], gDevWmt.pWmtCfg->data, gDevWmt.pWmtCfg->size); -+ -+ if (0 == wmt_conf_parse(&gDevWmt, (const PINT8)gDevWmt.pWmtCfg->data, gDevWmt.pWmtCfg->size)) { -+ /*config file exists */ -+ gDevWmt.rWmtGenConf.cfgExist = 1; -+ -+ WMT_DBG_FUNC("&gDevWmt.rWmtGenConf=%p\n", &gDevWmt.rWmtGenConf); -+ ret = 0; -+ } else { -+ WMT_ERR_FUNC("wmt conf parsing fail\n"); -+ osal_assert(0); -+ ret = -1; -+ } -+ wmt_dev_patch_put((osal_firmware **) &gDevWmt.pWmtCfg); -+/* -+ if (gDevWmt.pWmtCfg) -+ { -+ if (gDevWmt.pWmtCfg->data) -+ { -+ osal_free(gDevWmt.pWmtCfg->data); -+ } -+ osal_free(gDevWmt.pWmtCfg); -+ gDevWmt.pWmtCfg = 0; -+ } -+*/ -+ return ret; -+ } -+ WMT_ERR_FUNC("read %s file fails\n", &(gDevWmt.cWmtcfgName[0])); -+ osal_assert(0); -+ -+ gDevWmt.rWmtGenConf.cfgExist = 0; -+ return ret; -+} -+ -+P_WMT_GEN_CONF wmt_conf_get_cfg(VOID) -+{ -+ if (0 == gDevWmt.rWmtGenConf.cfgExist) -+ return NULL; -+ -+ return &gDevWmt.rWmtGenConf; -+} -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_core.c b/drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_core.c -new file mode 100644 -index 000000000000..cca6729d53a0 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_core.c -@@ -0,0 +1,2521 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -+/*! \file -+ \brief Declaration of library functions -+ -+ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+#ifdef DFT_TAG -+#undef DFT_TAG -+#endif -+#define DFT_TAG "[WMT-CORE]" -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "osal_typedef.h" -+ -+#include "wmt_lib.h" -+#include "wmt_core.h" -+#include "wmt_ctrl.h" -+#include "wmt_ic.h" -+#include "wmt_conf.h" -+ -+#include "wmt_func.h" -+#include "stp_core.h" -+#include "psm_core.h" -+ -+ -+P_WMT_FUNC_OPS gpWmtFuncOps[4] = { -+#if CFG_FUNC_BT_SUPPORT -+ [0] = &wmt_func_bt_ops, -+#else -+ [0] = NULL, -+#endif -+ -+#if CFG_FUNC_FM_SUPPORT -+ [1] = &wmt_func_fm_ops, -+#else -+ [1] = NULL, -+#endif -+ -+#if CFG_FUNC_GPS_SUPPORT -+ [2] = &wmt_func_gps_ops, -+#else -+ [2] = NULL, -+#endif -+ -+#if CFG_FUNC_WIFI_SUPPORT -+ [3] = &wmt_func_wifi_ops, -+#else -+ [3] = NULL, -+#endif -+ -+}; -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/* TODO:[FixMe][GeorgeKuo]: is it an MT6620 only or general general setting? -+*move to wmt_ic_6620 temporarily. -+*/ -+/* BT Port 2 Feature. */ -+/* #define CFG_WMT_BT_PORT2 (1) */ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+static WMT_CTX gMtkWmtCtx; -+static UINT8 gLpbkBuf[1024+5] = { 0 }; -+#ifdef CONFIG_MTK_COMBO_ANT -+static UINT8 gAntBuf[1024] = { 0 }; -+#define CFG_CHECK_WMT_RESULT (1) -+#endif -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+static INT32 opfunc_hif_conf(P_WMT_OP pWmtOp); -+static INT32 opfunc_pwr_on(P_WMT_OP pWmtOp); -+static INT32 opfunc_pwr_off(P_WMT_OP pWmtOp); -+static INT32 opfunc_func_on(P_WMT_OP pWmtOp); -+static INT32 opfunc_func_off(P_WMT_OP pWmtOp); -+static INT32 opfunc_reg_rw(P_WMT_OP pWmtOp); -+static INT32 opfunc_exit(P_WMT_OP pWmtOp); -+static INT32 opfunc_pwr_sv(P_WMT_OP pWmtOp); -+static INT32 opfunc_dsns(P_WMT_OP pWmtOp); -+static INT32 opfunc_lpbk(P_WMT_OP pWmtOp); -+static INT32 opfunc_cmd_test(P_WMT_OP pWmtOp); -+static INT32 opfunc_hw_rst(P_WMT_OP pWmtOp); -+static INT32 opfunc_sw_rst(P_WMT_OP pWmtOp); -+static INT32 opfunc_stp_rst(P_WMT_OP pWmtOp); -+static INT32 opfunc_therm_ctrl(P_WMT_OP pWmtOp); -+static INT32 opfunc_efuse_rw(P_WMT_OP pWmtOp); -+static INT32 opfunc_therm_ctrl(P_WMT_OP pWmtOp); -+static INT32 opfunc_gpio_ctrl(P_WMT_OP pWmtOp); -+static INT32 opfunc_pin_state(P_WMT_OP pWmtOp); -+static INT32 opfunc_bgw_ds(P_WMT_OP pWmtOp); -+static INT32 opfunc_set_mcu_clk(P_WMT_OP pWmtOp); -+static INT32 opfunc_adie_lpbk_test(P_WMT_OP pWmtOp); -+#if CFG_WMT_LTE_COEX_HANDLING -+static INT32 opfunc_idc_msg_handling(P_WMT_OP pWmtOp); -+#endif -+#ifdef CONFIG_MTK_COMBO_ANT -+static INT32 opfunc_ant_ram_down(P_WMT_OP pWmtOp); -+static INT32 opfunc_ant_ram_stat_get(P_WMT_OP pWmtOp); -+#endif -+static VOID wmt_core_dump_func_state(PINT8 pSource); -+static INT32 wmt_core_stp_init(VOID); -+static INT32 wmt_core_stp_deinit(VOID); -+static INT32 wmt_core_hw_check(VOID); -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+static const UINT8 WMT_SLEEP_CMD[] = { 0x01, 0x03, 0x01, 0x00, 0x01 }; -+static const UINT8 WMT_SLEEP_EVT[] = { 0x02, 0x03, 0x02, 0x00, 0x00, 0x01 }; -+ -+static const UINT8 WMT_HOST_AWAKE_CMD[] = { 0x01, 0x03, 0x01, 0x00, 0x02 }; -+static const UINT8 WMT_HOST_AWAKE_EVT[] = { 0x02, 0x03, 0x02, 0x00, 0x00, 0x02 }; -+ -+static const UINT8 WMT_WAKEUP_CMD[] = { 0xFF }; -+static const UINT8 WMT_WAKEUP_EVT[] = { 0x02, 0x03, 0x02, 0x00, 0x00, 0x03 }; -+ -+static UINT8 WMT_THERM_CMD[] = { 0x01, 0x11, 0x01, 0x00, -+ 0x00 /*thermal sensor operation */ -+}; -+static UINT8 WMT_THERM_CTRL_EVT[] = { 0x02, 0x11, 0x01, 0x00, 0x00 }; -+static UINT8 WMT_THERM_READ_EVT[] = { 0x02, 0x11, 0x02, 0x00, 0x00, 0x00 }; -+ -+static UINT8 WMT_EFUSE_CMD[] = { 0x01, 0x0D, 0x08, 0x00, -+ 0x01, /*[4]operation, 0:init, 1:write 2:read */ -+ 0x01, /*[5]Number of register setting */ -+ 0xAA, 0xAA, /*[6-7]Address */ -+ 0xBB, 0xBB, 0xBB, 0xBB /*[8-11] Value */ -+}; -+ -+static UINT8 WMT_EFUSE_EVT[] = { 0x02, 0x0D, 0x08, 0x00, -+ 0xAA, /*[4]operation, 0:init, 1:write 2:read */ -+ 0xBB, /*[5]Number of register setting */ -+ 0xCC, 0xCC, /*[6-7]Address */ -+ 0xDD, 0xDD, 0xDD, 0xDD /*[8-11] Value */ -+}; -+ -+static UINT8 WMT_DSNS_CMD[] = { 0x01, 0x0E, 0x02, 0x00, 0x01, -+ 0x00 /*desnse type */ -+}; -+static UINT8 WMT_DSNS_EVT[] = { 0x02, 0x0E, 0x01, 0x00, 0x00 }; -+ -+/* TODO:[NewFeature][GeorgeKuo] Update register group in ONE CMD/EVT */ -+static UINT8 WMT_SET_REG_CMD[] = { 0x01, 0x08, 0x10, 0x00 /*length */ -+ , 0x00 /*op: w(1) & r(2) */ -+ , 0x01 /*type: reg */ -+ , 0x00 /*res */ -+ , 0x01 /*1 register */ -+ , 0x00, 0x00, 0x00, 0x00 /* addr */ -+ , 0x00, 0x00, 0x00, 0x00 /* value */ -+ , 0xFF, 0xFF, 0xFF, 0xFF /*mask */ -+}; -+ -+static UINT8 WMT_SET_REG_WR_EVT[] = { 0x02, 0x08, 0x04, 0x00 /*length */ -+ , 0x00 /*S: 0 */ -+ , 0x00 /*type: reg */ -+ , 0x00 /*rev */ -+ , 0x01 /*1 register */ -+ /* , 0x00, 0x00, 0x00, 0x00 */ /* addr */ -+ /* , 0x00, 0x00, 0x00, 0x00 */ /* value */ -+}; -+ -+static UINT8 WMT_SET_REG_RD_EVT[] = { 0x02, 0x08, 0x04, 0x00 /*length */ -+ , 0x00 /*S: 0 */ -+ , 0x00 /*type: reg */ -+ , 0x00 /*rev */ -+ , 0x01 /*1 register */ -+ , 0x00, 0x00, 0x00, 0x00 /* addr */ -+ , 0x00, 0x00, 0x00, 0x00 /* value */ -+}; -+ -+#ifdef CONFIG_MTK_COMBO_ANT -+static UINT8 WMT_ANT_RAM_STA_GET_CMD[] = { 0x01, 0x06, 0x02, 0x00, 0x05, 0x02 -+}; -+ -+static UINT8 WMT_ANT_RAM_STA_GET_EVT[] = { 0x02, 0x06, 0x03, 0x00 /*length */ -+ , 0x05, 0x02, 0x00 /*S: result */ -+}; -+ -+static UINT8 WMT_ANT_RAM_DWN_CMD[] = { 0x01, 0x15, 0x00, 0x00, 0x01 -+}; -+ -+static UINT8 WMT_ANT_RAM_DWN_EVT[] = { 0x02, 0x15, 0x01, 0x00 /*length */ -+ , 0x00 -+}; -+#endif -+ -+/* GeorgeKuo: Use designated initializers described in -+ * http://gcc.gnu.org/onlinedocs/gcc-4.0.4/gcc/Designated-Inits.html -+ */ -+ -+static const WMT_OPID_FUNC wmt_core_opfunc[] = { -+ [WMT_OPID_HIF_CONF] = opfunc_hif_conf, -+ [WMT_OPID_PWR_ON] = opfunc_pwr_on, -+ [WMT_OPID_PWR_OFF] = opfunc_pwr_off, -+ [WMT_OPID_FUNC_ON] = opfunc_func_on, -+ [WMT_OPID_FUNC_OFF] = opfunc_func_off, -+ [WMT_OPID_REG_RW] = opfunc_reg_rw, /* TODO:[ChangeFeature][George] is this OP obsoleted? */ -+ [WMT_OPID_EXIT] = opfunc_exit, -+ [WMT_OPID_PWR_SV] = opfunc_pwr_sv, -+ [WMT_OPID_DSNS] = opfunc_dsns, -+ [WMT_OPID_LPBK] = opfunc_lpbk, -+ [WMT_OPID_CMD_TEST] = opfunc_cmd_test, -+ [WMT_OPID_HW_RST] = opfunc_hw_rst, -+ [WMT_OPID_SW_RST] = opfunc_sw_rst, -+ [WMT_OPID_STP_RST] = opfunc_stp_rst, -+ [WMT_OPID_THERM_CTRL] = opfunc_therm_ctrl, -+ [WMT_OPID_EFUSE_RW] = opfunc_efuse_rw, -+ [WMT_OPID_GPIO_CTRL] = opfunc_gpio_ctrl, -+ [WMT_OPID_GPIO_STATE] = opfunc_pin_state, -+ [WMT_OPID_BGW_DS] = opfunc_bgw_ds, -+ [WMT_OPID_SET_MCU_CLK] = opfunc_set_mcu_clk, -+ [WMT_OPID_ADIE_LPBK_TEST] = opfunc_adie_lpbk_test, -+#if CFG_WMT_LTE_COEX_HANDLING -+ [WMT_OPID_IDC_MSG_HANDLING] = opfunc_idc_msg_handling, -+#endif -+#ifdef CONFIG_MTK_COMBO_ANT -+ [WMT_OPID_ANT_RAM_DOWN] = opfunc_ant_ram_down, -+ [WMT_OPID_ANT_RAM_STA_GET] = opfunc_ant_ram_stat_get, -+#endif -+}; -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+INT32 wmt_core_init(VOID) -+{ -+ INT32 i = 0; -+ -+ osal_memset(&gMtkWmtCtx, 0, osal_sizeof(gMtkWmtCtx)); -+ /* gMtkWmtCtx.p_ops is cleared to NULL */ -+ -+ /* default FUNC_OFF state */ -+ for (i = 0; i < WMTDRV_TYPE_MAX; ++i) { -+ /* WinMo is default to DRV_STS_UNREG; */ -+ gMtkWmtCtx.eDrvStatus[i] = DRV_STS_POWER_OFF; -+ } -+ -+ return 0; -+} -+ -+INT32 wmt_core_deinit(VOID) -+{ -+ /* return to init state */ -+ osal_memset(&gMtkWmtCtx, 0, osal_sizeof(gMtkWmtCtx)); -+ /* gMtkWmtCtx.p_ops is cleared to NULL */ -+ return 0; -+} -+ -+/* TODO: [ChangeFeature][George] Is wmt_ctrl a good interface? maybe not...... */ -+/* parameters shall be copied in/from ctrl buffer, which is also a size-wasting buffer. */ -+INT32 wmt_core_tx(const PUINT8 pData, const UINT32 size, PUINT32 writtenSize, const MTK_WCN_BOOL bRawFlag) -+{ -+ INT32 iRet; -+#if 0 /* Test using direct function call instead of wmt_ctrl() interface */ -+ WMT_CTRL_DATA ctrlData; -+ -+ ctrlData.ctrlId = WMT_CTRL_TX; -+ ctrlData.au4CtrlData[0] = (UINT32) pData; -+ ctrlData.au4CtrlData[1] = size; -+ ctrlData.au4CtrlData[2] = (UINT32) writtenSize; -+ ctrlData.au4CtrlData[3] = bRawFlag; -+ -+ iRet = wmt_ctrl(&ctrlData); -+ if (iRet) { -+ /* ERROR */ -+ WMT_ERR_FUNC("WMT-CORE: wmt_core_ctrl failed: WMT_CTRL_TX, iRet:%d\n", iRet); -+ /* (*sys_dbg_assert)(0, __FILE__, __LINE__); */ -+ osal_assert(0); -+ } -+#endif -+ iRet = wmt_ctrl_tx_ex(pData, size, writtenSize, bRawFlag); -+ if (0 == *writtenSize) { -+ INT32 retry_times = 0; -+ INT32 max_retry_times = 3; -+ INT32 retry_delay_ms = 360; -+ -+ WMT_WARN_FUNC("WMT-CORE: wmt_ctrl_tx_ex failed and written ret:%d, maybe no winspace in STP layer\n", -+ *writtenSize); -+ while ((0 == *writtenSize) && (retry_times < max_retry_times)) { -+ WMT_ERR_FUNC("WMT-CORE: retrying, wait for %d ms\n", retry_delay_ms); -+ osal_sleep_ms(retry_delay_ms); -+ -+ iRet = wmt_ctrl_tx_ex(pData, size, writtenSize, bRawFlag); -+ retry_times++; -+ } -+ } -+ return iRet; -+} -+ -+INT32 wmt_core_rx(PUINT8 pBuf, UINT32 bufLen, UINT32 *readSize) -+{ -+ INT32 iRet; -+ WMT_CTRL_DATA ctrlData; -+ -+ ctrlData.ctrlId = WMT_CTRL_RX; -+ ctrlData.au4CtrlData[0] = (SIZE_T) pBuf; -+ ctrlData.au4CtrlData[1] = bufLen; -+ ctrlData.au4CtrlData[2] = (SIZE_T) readSize; -+ -+ iRet = wmt_ctrl(&ctrlData); -+ if (iRet) { -+ /* ERROR */ -+ WMT_ERR_FUNC("WMT-CORE: wmt_core_ctrl failed: WMT_CTRL_RX, iRet:%d\n", iRet); -+ mtk_wcn_stp_dbg_dump_package(); -+ osal_assert(0); -+ } -+ return iRet; -+} -+ -+INT32 wmt_core_rx_flush(UINT32 type) -+{ -+ INT32 iRet; -+ WMT_CTRL_DATA ctrlData; -+ -+ ctrlData.ctrlId = WMT_CTRL_RX_FLUSH; -+ ctrlData.au4CtrlData[0] = (UINT32) type; -+ -+ iRet = wmt_ctrl(&ctrlData); -+ if (iRet) { -+ /* ERROR */ -+ WMT_ERR_FUNC("WMT-CORE: wmt_core_ctrl failed: WMT_CTRL_RX_FLUSH, iRet:%d\n", iRet); -+ osal_assert(0); -+ } -+ return iRet; -+} -+ -+INT32 wmt_core_func_ctrl_cmd(ENUM_WMTDRV_TYPE_T type, MTK_WCN_BOOL fgEn) -+{ -+ INT32 iRet = 0; -+ UINT32 u4WmtCmdPduLen; -+ UINT32 u4WmtEventPduLen; -+ UINT32 u4ReadSize; -+ UINT32 u4WrittenSize; -+ WMT_PKT rWmtPktCmd; -+ WMT_PKT rWmtPktEvent; -+ MTK_WCN_BOOL fgFail; -+ -+ /* TODO:[ChangeFeature][George] remove WMT_PKT. replace it with hardcoded arrays. */ -+ /* Using this struct relies on compiler's implementation and pack() settings */ -+ osal_memset(&rWmtPktCmd, 0, osal_sizeof(rWmtPktCmd)); -+ osal_memset(&rWmtPktEvent, 0, osal_sizeof(rWmtPktEvent)); -+ -+ rWmtPktCmd.eType = (UINT8) PKT_TYPE_CMD; -+ rWmtPktCmd.eOpCode = (UINT8) OPCODE_FUNC_CTRL; -+ -+ /* Flag field: driver type */ -+ rWmtPktCmd.aucParam[0] = (UINT8) type; -+ /* Parameter field: ON/OFF */ -+ rWmtPktCmd.aucParam[1] = (fgEn == WMT_FUNC_CTRL_ON) ? 1 : 0; -+ rWmtPktCmd.u2SduLen = WMT_FLAG_LEN + WMT_FUNC_CTRL_PARAM_LEN; /* (2) */ -+ -+ /* WMT Header + WMT SDU */ -+ u4WmtCmdPduLen = WMT_HDR_LEN + rWmtPktCmd.u2SduLen; /* (6) */ -+ u4WmtEventPduLen = WMT_HDR_LEN + WMT_STS_LEN; /* (5) */ -+ -+ do { -+ fgFail = MTK_WCN_BOOL_TRUE; -+/* iRet = (*kal_stp_tx)((PUINT8)&rWmtPktCmd, u4WmtCmdPduLen, &u4WrittenSize); */ -+ iRet = wmt_core_tx((PUINT8) &rWmtPktCmd, u4WmtCmdPduLen, &u4WrittenSize, MTK_WCN_BOOL_FALSE); -+ if (iRet) { -+ WMT_ERR_FUNC("WMT-CORE: wmt_func_ctrl_cmd kal_stp_tx failed\n"); -+ break; -+ } -+ -+ iRet = wmt_core_rx((PUINT8) &rWmtPktEvent, u4WmtEventPduLen, &u4ReadSize); -+ if (iRet) { -+ WMT_ERR_FUNC("WMT-CORE: wmt_func_ctrl_cmd kal_stp_rx failed\n"); -+ break; -+ } -+ -+ /* Error Checking */ -+ if (PKT_TYPE_EVENT != rWmtPktEvent.eType) { -+ WMT_ERR_FUNC("WMT-CORE: wmt_func_ctrl_cmd PKT_TYPE_EVENT != rWmtPktEvent.eType %d\n", -+ rWmtPktEvent.eType); -+ break; -+ } -+ -+ if (rWmtPktCmd.eOpCode != rWmtPktEvent.eOpCode) { -+ WMT_ERR_FUNC -+ ("WMT-CORE: wmt_func_ctrl_cmd rWmtPktCmd.eOpCode(0x%x) != rWmtPktEvent.eType(0x%x)\n", -+ rWmtPktCmd.eOpCode, rWmtPktEvent.eOpCode); -+ break; -+ } -+ -+ if (u4WmtEventPduLen != (rWmtPktEvent.u2SduLen + WMT_HDR_LEN)) { -+ WMT_ERR_FUNC -+ ("WMT-CORE: wmt_func_ctrl_cmd u4WmtEventPduLen(0x%x) != rWmtPktEvent.u2SduLen(0x%x)+4\n", -+ u4WmtEventPduLen, rWmtPktEvent.u2SduLen); -+ break; -+ } -+ /* Status field of event check */ -+ if (0 != rWmtPktEvent.aucParam[0]) { -+ WMT_ERR_FUNC("WMT-CORE: wmt_func_ctrl_cmd, 0 != status(%d)\n", rWmtPktEvent.aucParam[0]); -+ break; -+ } -+ -+ fgFail = MTK_WCN_BOOL_FALSE; -+ } while (0); -+ -+ if (MTK_WCN_BOOL_FALSE == fgFail) { -+ /* WMT_INFO_FUNC("WMT-CORE: wmt_func_ctrl_cmd OK!\n"); */ -+ return 0; -+ } -+ WMT_ERR_FUNC("WMT-CORE: wmt_func_ctrl_cmd 0x%x FAIL\n", rWmtPktCmd.aucParam[0]); -+ return -3; -+} -+ -+INT32 wmt_core_opid_handler(P_WMT_OP pWmtOp) -+{ -+ UINT32 opId; -+ INT32 ret; -+ -+ opId = pWmtOp->opId; -+ -+ if (wmt_core_opfunc[opId]) { -+ ret = (*(wmt_core_opfunc[opId])) (pWmtOp); /*wmtCoreOpidHandlerPack[].opHandler */ -+ return ret; -+ } -+ WMT_ERR_FUNC("WMT-CORE: null handler (%d)\n", pWmtOp->opId); -+ return -2; -+ -+} -+ -+INT32 wmt_core_opid(P_WMT_OP pWmtOp) -+{ -+ -+ /*sanity check */ -+ if (NULL == pWmtOp) { -+ WMT_ERR_FUNC("null pWmtOP\n"); -+ /*print some message with error info */ -+ return -1; -+ } -+ -+ if (WMT_OPID_MAX <= pWmtOp->opId) { -+ WMT_ERR_FUNC("WMT-CORE: invalid OPID(%d)\n", pWmtOp->opId); -+ return -2; -+ } -+ /* TODO: [FixMe][GeorgeKuo] do sanity check to const function table when init and skip checking here */ -+ return wmt_core_opid_handler(pWmtOp); -+} -+ -+INT32 wmt_core_ctrl(ENUM_WMT_CTRL_T ctrId, unsigned long *pPa1, unsigned long *pPa2) -+{ -+ INT32 iRet = -1; -+ WMT_CTRL_DATA ctrlData; -+ SIZE_T val1 = (pPa1) ? *pPa1 : 0; -+ SIZE_T val2 = (pPa2) ? *pPa2 : 0; -+ -+ ctrlData.ctrlId = (SIZE_T) ctrId; -+ ctrlData.au4CtrlData[0] = val1; -+ ctrlData.au4CtrlData[1] = val2; -+ -+ iRet = wmt_ctrl(&ctrlData); -+ if (iRet) { -+ /* ERROR */ -+ WMT_ERR_FUNC("WMT-CORE: wmt_core_ctrl failed: id(%d), type(%d), value(%d) iRet:(%d)\n", ctrId, val1, -+ val2, iRet); -+ osal_assert(0); -+ } else { -+ if (pPa1) -+ *pPa1 = ctrlData.au4CtrlData[0]; -+ if (pPa2) -+ *pPa2 = ctrlData.au4CtrlData[1]; -+ } -+ return iRet; -+} -+ -+VOID wmt_core_dump_data(PUINT8 pData, PUINT8 pTitle, UINT32 len) -+{ -+ PUINT8 ptr = pData; -+ INT32 k = 0; -+ -+ WMT_INFO_FUNC("%s len=%d\n", pTitle, len); -+ for (k = 0; k < len; k++) { -+ if (k % 16 == 0) -+ WMT_INFO_FUNC("\n"); -+ WMT_INFO_FUNC("0x%02x ", *ptr); -+ ptr++; -+ } -+ WMT_INFO_FUNC("--end\n"); -+} -+ -+/*! -+ * \brief An WMT-CORE function to support read, write, and read after write to -+ * an internal register. -+ * -+ * Detailed description. -+ * -+ * \param isWrite 1 for write, 0 for read -+ * \param offset of register to be written or read -+ * \param pVal a pointer to the 32-bit value to be writtern or read -+ * \param mask a 32-bit mask to be applied for the read or write operation -+ * -+ * \retval 0 operation success -+ * \retval -1 invalid parameters -+ * \retval -2 tx cmd fail -+ * \retval -3 rx event fail -+ * \retval -4 read check error -+ */ -+INT32 wmt_core_reg_rw_raw(UINT32 isWrite, UINT32 offset, PUINT32 pVal, UINT32 mask) -+{ -+ INT32 iRet; -+ UINT32 u4Res; -+ UINT32 evtLen; -+ UINT8 evtBuf[16] = { 0 }; -+ -+ WMT_SET_REG_CMD[4] = (isWrite) ? 0x1 : 0x2; /* w:1, r:2 */ -+ osal_memcpy(&WMT_SET_REG_CMD[8], &offset, 4); /* offset */ -+ osal_memcpy(&WMT_SET_REG_CMD[12], pVal, 4); /* [2] is var addr */ -+ osal_memcpy(&WMT_SET_REG_CMD[16], &mask, 4); /* mask */ -+ -+ /* send command */ -+ iRet = wmt_core_tx(WMT_SET_REG_CMD, sizeof(WMT_SET_REG_CMD), &u4Res, MTK_WCN_BOOL_FALSE); -+ if ((iRet) || (u4Res != sizeof(WMT_SET_REG_CMD))) { -+ WMT_ERR_FUNC("Tx REG_CMD fail!(%d) len (%d, %d)\n", iRet, u4Res, sizeof(WMT_SET_REG_CMD)); -+ return -2; -+ } -+ -+ /* receive event */ -+ evtLen = (isWrite) ? sizeof(WMT_SET_REG_WR_EVT) : sizeof(WMT_SET_REG_RD_EVT); -+ iRet = wmt_core_rx(evtBuf, evtLen, &u4Res); -+ if ((iRet) || (u4Res != evtLen)) { -+ WMT_ERR_FUNC("Rx REG_EVT fail!(%d) len(%d, %d)\n", iRet, u4Res, evtLen); -+ return -3; -+ } -+ -+ if (!isWrite) { -+ UINT32 rxEvtAddr; -+ UINT32 txCmdAddr; -+ -+ osal_memcpy(&txCmdAddr, &WMT_SET_REG_CMD[8], 4); -+ osal_memcpy(&rxEvtAddr, &evtBuf[8], 4); -+ -+ /* check read result */ -+ if (txCmdAddr != rxEvtAddr) { -+ WMT_ERR_FUNC("Check read addr fail (0x%08x, 0x%08x)\n", rxEvtAddr, txCmdAddr); -+ return -4; -+ } -+ WMT_DBG_FUNC("Check read addr(0x%08x) ok\n", rxEvtAddr); -+ -+ osal_memcpy(pVal, &evtBuf[12], 4); -+ } -+ -+ /* no error here just return 0 */ -+ return 0; -+} -+ -+INT32 wmt_core_init_script(struct init_script *script, INT32 count) -+{ -+ UINT8 evtBuf[256]; -+ UINT32 u4Res; -+ INT32 i = 0; -+ INT32 iRet; -+ -+ for (i = 0; i < count; i++) { -+ WMT_DBG_FUNC("WMT-CORE: init_script operation %s start\n", script[i].str); -+ /* CMD */ -+ /* iRet = (*kal_stp_tx)(script[i].cmd, script[i].cmdSz, &u4Res); */ -+ iRet = wmt_core_tx(script[i].cmd, script[i].cmdSz, &u4Res, MTK_WCN_BOOL_FALSE); -+ if (iRet || (u4Res != script[i].cmdSz)) { -+ WMT_ERR_FUNC("WMT-CORE: write (%s) iRet(%d) cmd len err(%d, %d)\n", script[i].str, iRet, u4Res, -+ script[i].cmdSz); -+ break; -+ } -+ /* EVENT BUF */ -+ osal_memset(evtBuf, 0, sizeof(evtBuf)); -+ iRet = wmt_core_rx(evtBuf, script[i].evtSz, &u4Res); -+ if (iRet || (u4Res != script[i].evtSz)) { -+ WMT_ERR_FUNC("WMT-CORE: read (%s) iRet(%d) evt len err(rx:%d, exp:%d)\n", script[i].str, iRet, -+ u4Res, script[i].evtSz); -+ mtk_wcn_stp_dbg_dump_package(); -+ break; -+ } -+ /* RESULT */ -+ if (0x14 != evtBuf[1]) { /* workaround RF calibration data EVT,do not care this EVT */ -+ if (osal_memcmp(evtBuf, script[i].evt, script[i].evtSz) != 0) { -+ WMT_ERR_FUNC("WMT-CORE:compare %s result error\n", script[i].str); -+ WMT_ERR_FUNC -+ ("WMT-CORE:rx(%d):[%02X,%02X,%02X,%02X,%02X] exp(%d):[%02X,%02X,%02X,%02X,%02X]\n", -+ u4Res, evtBuf[0], evtBuf[1], evtBuf[2], evtBuf[3], evtBuf[4], script[i].evtSz, -+ script[i].evt[0], script[i].evt[1], script[i].evt[2], script[i].evt[3], -+ script[i].evt[4]); -+ mtk_wcn_stp_dbg_dump_package(); -+ break; -+ } -+ } -+ WMT_DBG_FUNC("init_script operation %s ok\n", script[i].str); -+ } -+ -+ return (i == count) ? 0 : -1; -+} -+ -+static INT32 wmt_core_stp_init(VOID) -+{ -+ INT32 iRet = -1; -+ unsigned long ctrlPa1; -+ unsigned long ctrlPa2; -+ UINT8 co_clock_type; -+ P_WMT_CTX pctx = &gMtkWmtCtx; -+ P_WMT_GEN_CONF pWmtGenConf = NULL; -+ -+ wmt_conf_read_file(); -+ pWmtGenConf = wmt_conf_get_cfg(); -+ if (!(pctx->wmtInfoBit & WMT_OP_HIF_BIT)) { -+ WMT_ERR_FUNC("WMT-CORE: no hif info!\n"); -+ osal_assert(0); -+ return -1; -+ } -+ /* 4 <1> open stp */ -+ ctrlPa1 = 0; -+ ctrlPa2 = 0; -+ iRet = wmt_core_ctrl(WMT_CTRL_STP_OPEN, &ctrlPa1, &ctrlPa2); -+ if (iRet) { -+ WMT_ERR_FUNC("WMT-CORE: wmt open stp\n"); -+ return -2; -+ } -+ /* 4 <1.5> disable and un-ready stp */ -+ ctrlPa1 = WMT_STP_CONF_EN; -+ ctrlPa2 = 0; -+ iRet += wmt_core_ctrl(WMT_CTRL_STP_CONF, &ctrlPa1, &ctrlPa2); -+ ctrlPa1 = WMT_STP_CONF_RDY; -+ ctrlPa2 = 0; -+ iRet += wmt_core_ctrl(WMT_CTRL_STP_CONF, &ctrlPa1, &ctrlPa2); -+ -+ /* 4 <2> set mode and enable */ -+ if (WMT_HIF_BTIF == pctx->wmtHifConf.hifType) { -+ ctrlPa1 = WMT_STP_CONF_MODE; -+ ctrlPa2 = MTKSTP_BTIF_MAND_MODE; -+ iRet += wmt_core_ctrl(WMT_CTRL_STP_CONF, &ctrlPa1, &ctrlPa2); -+ } -+ -+ ctrlPa1 = WMT_STP_CONF_EN; -+ ctrlPa2 = 1; -+ iRet += wmt_core_ctrl(WMT_CTRL_STP_CONF, &ctrlPa1, &ctrlPa2); -+ if (iRet) { -+ WMT_ERR_FUNC("WMT-CORE: stp_init <1><2> fail:%d\n", iRet); -+ return -3; -+ } -+ /* TODO: [ChangeFeature][GeorgeKuo] can we apply raise UART baud rate firstly for ALL supported chips??? */ -+ -+ iRet = wmt_core_hw_check(); -+ if (iRet) { -+ WMT_ERR_FUNC("hw_check fail:%d\n", iRet); -+ return -4; -+ } -+ /* mtkWmtCtx.p_ic_ops is identified and checked ok */ -+ if ((NULL != pctx->p_ic_ops->co_clock_ctrl) && (pWmtGenConf != NULL)) { -+ co_clock_type = (pWmtGenConf->co_clock_flag & 0x0f); -+ (*(pctx->p_ic_ops->co_clock_ctrl)) (co_clock_type == 0 ? WMT_CO_CLOCK_DIS : WMT_CO_CLOCK_EN); -+ } else { -+ WMT_WARN_FUNC("pctx->p_ic_ops->co_clock_ctrl(0x%x), pWmtGenConf(0x%x)\n", pctx->p_ic_ops->co_clock_ctrl, -+ pWmtGenConf); -+ } -+ osal_assert(NULL != pctx->p_ic_ops->sw_init); -+ if (NULL != pctx->p_ic_ops->sw_init) { -+ iRet = (*(pctx->p_ic_ops->sw_init)) (&pctx->wmtHifConf); -+ } else { -+ WMT_ERR_FUNC("gMtkWmtCtx.p_ic_ops->sw_init is NULL\n"); -+ return -5; -+ } -+ if (iRet) { -+ WMT_ERR_FUNC("gMtkWmtCtx.p_ic_ops->sw_init fail:%d\n", iRet); -+ return -6; -+ } -+ /* 4 <10> set stp ready */ -+ ctrlPa1 = WMT_STP_CONF_RDY; -+ ctrlPa2 = 1; -+ iRet = wmt_core_ctrl(WMT_CTRL_STP_CONF, &ctrlPa1, &ctrlPa2); -+ -+ return iRet; -+} -+ -+static INT32 wmt_core_stp_deinit(VOID) -+{ -+ INT32 iRet; -+ unsigned long ctrlPa1; -+ unsigned long ctrlPa2; -+ -+ WMT_DBG_FUNC(" start\n"); -+ -+ if (NULL == gMtkWmtCtx.p_ic_ops) { -+ WMT_WARN_FUNC("gMtkWmtCtx.p_ic_ops is NULL\n"); -+ goto deinit_ic_ops_done; -+ } -+ if (NULL != gMtkWmtCtx.p_ic_ops->sw_deinit) { -+ iRet = (*(gMtkWmtCtx.p_ic_ops->sw_deinit)) (&gMtkWmtCtx.wmtHifConf); -+ /* unbind WMT-IC */ -+ gMtkWmtCtx.p_ic_ops = NULL; -+ } else { -+ WMT_ERR_FUNC("gMtkWmtCtx.p_ic_ops->sw_init is NULL\n"); -+ } -+ -+deinit_ic_ops_done: -+ -+ /* 4 <1> un-ready, disable, and close stp. */ -+ ctrlPa1 = WMT_STP_CONF_RDY; -+ ctrlPa2 = 0; -+ iRet = wmt_core_ctrl(WMT_CTRL_STP_CONF, &ctrlPa1, &ctrlPa2); -+ ctrlPa1 = WMT_STP_CONF_EN; -+ ctrlPa2 = 0; -+ iRet += wmt_core_ctrl(WMT_CTRL_STP_CONF, &ctrlPa1, &ctrlPa2); -+ ctrlPa1 = 0; -+ ctrlPa2 = 0; -+ iRet += wmt_core_ctrl(WMT_CTRL_STP_CLOSE, &ctrlPa1, &ctrlPa2); -+ -+ if (iRet) -+ WMT_WARN_FUNC("end with fail:%d\n", iRet); -+ -+ return iRet; -+} -+ -+static VOID wmt_core_dump_func_state(PINT8 pSource) -+{ -+ WMT_WARN_FUNC("[%s]status(b:%d f:%d g:%d w:%d lpbk:%d coredump:%d wmt:%d stp:%d)\n", -+ (pSource == NULL ? (PINT8) "CORE" : pSource), -+ gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_BT], -+ gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_FM], -+ gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_GPS], -+ gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WIFI], -+ gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_LPBK], -+ gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_COREDUMP], -+ gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT], gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_STP] -+ ); -+ return; -+ -+} -+ -+MTK_WCN_BOOL wmt_core_patch_check(UINT32 u4PatchVer, UINT32 u4HwVer) -+{ -+ if (MAJORNUM(u4HwVer) != MAJORNUM(u4PatchVer)) { -+ /*major no. does not match */ -+ WMT_ERR_FUNC("WMT-CORE: chip version(0x%d) does not match patch version(0x%d)\n", u4HwVer, u4PatchVer); -+ return MTK_WCN_BOOL_FALSE; -+ } -+ return MTK_WCN_BOOL_TRUE; -+} -+ -+static INT32 wmt_core_hw_check(VOID) -+{ -+ UINT32 chipid; -+ P_WMT_IC_OPS p_ops; -+ INT32 iret; -+ -+ /* 1. get chip id */ -+ chipid = 0; -+ WMT_LOUD_FUNC("before read hwcode (chip id)\n"); -+ iret = wmt_core_reg_rw_raw(0, GEN_HCR, &chipid, GEN_HCR_MASK); /* read 0x80000008 */ -+ if (iret) { -+ WMT_ERR_FUNC("get hwcode (chip id) fail (%d)\n", iret); -+ return -2; -+ } -+ WMT_DBG_FUNC("get hwcode (chip id) (0x%x)\n", chipid); -+ -+ /* TODO:[ChangeFeature][George]: use a better way to select a correct ops table based on chip id */ -+ switch (chipid) { -+#if CFG_CORE_MT6620_SUPPORT -+ case 0x6620: -+ p_ops = &wmt_ic_ops_mt6620; -+ break; -+#endif -+#if CFG_CORE_MT6628_SUPPORT -+ case 0x6628: -+ p_ops = &wmt_ic_ops_mt6628; -+ break; -+#endif -+#if CFG_CORE_SOC_SUPPORT -+ case 0x6572: -+ case 0x6582: -+ case 0x6592: -+ case 0x8127: -+ case 0x6571: -+ case 0x6752: -+ case 0x0279: -+ case 0x0326: -+ case 0x0321: -+ case 0x0335: -+ case 0x0337: -+ case 0x8163: -+ case 0x6580: -+ p_ops = &wmt_ic_ops_soc; -+ break; -+#endif -+ default: -+ p_ops = (P_WMT_IC_OPS) NULL; -+#if CFG_CORE_SOC_SUPPORT -+ if (0x7f90 == chipid - 0x600) { -+ p_ops = &wmt_ic_ops_soc; -+ chipid -= 0xf6d; -+ } -+#endif -+ break; -+ } -+ -+ if (NULL == p_ops) { -+ WMT_ERR_FUNC("unsupported chip id (hw_code): 0x%x\n", chipid); -+ return -3; -+ } else if (MTK_WCN_BOOL_FALSE == wmt_core_ic_ops_check(p_ops)) { -+ WMT_ERR_FUNC -+ ("chip id(0x%x) with null operation fp: init(0x%p), deinit(0x%p), pin_ctrl(0x%p), ver_chk(0x%p)\n", -+ chipid, p_ops->sw_init, p_ops->sw_deinit, p_ops->ic_pin_ctrl, p_ops->ic_ver_check); -+ return -4; -+ } -+ WMT_DBG_FUNC("chip id(0x%x) fp: init(0x%p), deinit(0x%p), pin_ctrl(0x%p), ver_chk(0x%p)\n", -+ chipid, p_ops->sw_init, p_ops->sw_deinit, p_ops->ic_pin_ctrl, p_ops->ic_ver_check); -+ -+ wmt_ic_ops_soc.icId = chipid; -+ WMT_DBG_FUNC("wmt_ic_ops_soc.icId(0x%x)\n", wmt_ic_ops_soc.icId); -+ iret = p_ops->ic_ver_check(); -+ if (iret) { -+ WMT_ERR_FUNC("chip id(0x%x) ver_check error:%d\n", chipid, iret); -+ return -5; -+ } -+ -+ WMT_DBG_FUNC("chip id(0x%x) ver_check ok\n", chipid); -+ gMtkWmtCtx.p_ic_ops = p_ops; -+ return 0; -+} -+ -+static INT32 opfunc_hif_conf(P_WMT_OP pWmtOp) -+{ -+ if (!(pWmtOp->u4InfoBit & WMT_OP_HIF_BIT)) { -+ WMT_ERR_FUNC("WMT-CORE: no HIF_BIT in WMT_OP!\n"); -+ return -1; -+ } -+ -+ if (gMtkWmtCtx.wmtInfoBit & WMT_OP_HIF_BIT) { -+ WMT_ERR_FUNC("WMT-CORE: WMT HIF already exist. overwrite! old (%d), new(%d))\n", -+ gMtkWmtCtx.wmtHifConf.hifType, pWmtOp->au4OpData[0]); -+ } else { -+ gMtkWmtCtx.wmtInfoBit |= WMT_OP_HIF_BIT; -+ WMT_ERR_FUNC("WMT-CORE: WMT HIF info added\n"); -+ } -+ -+ osal_memcpy(&gMtkWmtCtx.wmtHifConf, &pWmtOp->au4OpData[0], osal_sizeof(gMtkWmtCtx.wmtHifConf)); -+ return 0; -+ -+} -+ -+static INT32 opfunc_pwr_on(P_WMT_OP pWmtOp) -+{ -+ -+ INT32 iRet; -+ unsigned long ctrlPa1; -+ unsigned long ctrlPa2; -+ INT32 retry = WMT_PWRON_RTY_DFT; -+ -+ if (DRV_STS_POWER_OFF != gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT]) { -+ WMT_ERR_FUNC("WMT-CORE: already powered on, WMT DRV_STS_[0x%x]\n", -+ gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT]); -+ osal_assert(0); -+ return -1; -+ } -+ /* TODO: [FixMe][GeorgeKuo]: clarify the following is reqiured or not! */ -+ if (pWmtOp->u4InfoBit & WMT_OP_HIF_BIT) -+ opfunc_hif_conf(pWmtOp); -+ -+pwr_on_rty: -+ /* power on control */ -+ ctrlPa1 = 0; -+ ctrlPa2 = 0; -+ iRet = wmt_core_ctrl(WMT_CTRL_HW_PWR_ON, &ctrlPa1, &ctrlPa2); -+ if (iRet) { -+ WMT_ERR_FUNC("WMT-CORE: WMT_CTRL_HW_PWR_ON fail iRet(%d)\n", iRet); -+ if (0 == retry--) { -+ WMT_INFO_FUNC("WMT-CORE: retry (%d)\n", retry); -+ goto pwr_on_rty; -+ } -+ return -1; -+ } -+ gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT] = DRV_STS_POWER_ON; -+ -+ /* init stp */ -+ iRet = wmt_core_stp_init(); -+ if (iRet) { -+ WMT_ERR_FUNC("WMT-CORE: wmt_core_stp_init fail (%d)\n", iRet); -+ osal_assert(0); -+ -+ /* deinit stp */ -+ iRet = wmt_core_stp_deinit(); -+ iRet = opfunc_pwr_off(pWmtOp); -+ if (iRet) -+ WMT_ERR_FUNC("WMT-CORE: opfunc_pwr_off fail during pwr_on retry\n"); -+ -+ if (0 < retry--) { -+ WMT_INFO_FUNC("WMT-CORE: retry (%d)\n", retry); -+ goto pwr_on_rty; -+ } -+ iRet = -2; -+ return iRet; -+ } -+ -+ WMT_DBG_FUNC("WMT-CORE: WMT [FUNC_ON]\n"); -+ gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT] = DRV_STS_FUNC_ON; -+ -+ /* What to do when state is changed from POWER_OFF to POWER_ON? -+ * 1. STP driver does s/w reset -+ * 2. UART does 0xFF wake up -+ * 3. SDIO does re-init command(changed to trigger by host) -+ */ -+ return iRet; -+ -+} -+ -+static INT32 opfunc_pwr_off(P_WMT_OP pWmtOp) -+{ -+ -+ INT32 iRet; -+ unsigned long ctrlPa1; -+ unsigned long ctrlPa2; -+ -+ if (DRV_STS_POWER_OFF == gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT]) { -+ WMT_WARN_FUNC("WMT-CORE: WMT already off, WMT DRV_STS_[0x%x]\n", -+ gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT]); -+ osal_assert(0); -+ return -1; -+ } -+ if (MTK_WCN_BOOL_FALSE == g_pwr_off_flag) { -+ WMT_WARN_FUNC("CONNSYS power off be disabled, maybe need trigger core dump!\n"); -+ osal_assert(0); -+ return -2; -+ } -+ -+ /* wmt and stp are initialized successfully */ -+ if (DRV_STS_FUNC_ON == gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT]) { -+ iRet = wmt_core_stp_deinit(); -+ if (iRet) { -+ WMT_WARN_FUNC("wmt_core_stp_deinit fail (%d)\n", iRet); -+ /*should let run to power down chip */ -+ } -+ } -+ gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT] = DRV_STS_POWER_ON; -+ -+ /* power off control */ -+ ctrlPa1 = 0; -+ ctrlPa2 = 0; -+ iRet = wmt_core_ctrl(WMT_CTRL_HW_PWR_OFF, &ctrlPa1, &ctrlPa2); -+ if (iRet) -+ WMT_WARN_FUNC("HW_PWR_OFF fail (%d)\n", iRet); -+ WMT_WARN_FUNC("HW_PWR_OFF ok\n"); -+ -+ /*anyway, set to POWER_OFF state */ -+ gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT] = DRV_STS_POWER_OFF; -+ return iRet; -+ -+} -+ -+static INT32 opfunc_func_on(P_WMT_OP pWmtOp) -+{ -+ INT32 iRet = -1; -+ INT32 iPwrOffRet = -1; -+ UINT32 drvType; -+ -+ drvType = pWmtOp->au4OpData[0]; -+ -+ /* Check abnormal type */ -+ if (WMTDRV_TYPE_COREDUMP < drvType) { -+ WMT_ERR_FUNC("abnormal Fun(%d)\n", drvType); -+ osal_assert(0); -+ return -1; -+ } -+ -+ /* Check abnormal state */ -+ if ((DRV_STS_POWER_OFF > gMtkWmtCtx.eDrvStatus[drvType]) -+ || (DRV_STS_MAX <= gMtkWmtCtx.eDrvStatus[drvType])) { -+ WMT_ERR_FUNC("func(%d) status[0x%x] abnormal\n", drvType, gMtkWmtCtx.eDrvStatus[drvType]); -+ osal_assert(0); -+ return -2; -+ } -+ -+ /* check if func already on */ -+ if (DRV_STS_FUNC_ON == gMtkWmtCtx.eDrvStatus[drvType]) { -+ WMT_WARN_FUNC("func(%d) already on\n", drvType); -+ return 0; -+ } -+ /*enable power off flag, if flag=0, power off connsys will not be executed */ -+ mtk_wcn_set_connsys_power_off_flag(MTK_WCN_BOOL_TRUE); -+ /* check if chip power on is needed */ -+ if (DRV_STS_FUNC_ON != gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT]) { -+ iRet = opfunc_pwr_on(pWmtOp); -+ -+ if (iRet) { -+ WMT_ERR_FUNC("func(%d) pwr_on fail(%d)\n", drvType, iRet); -+ osal_assert(0); -+ -+ /* check all sub-func and do power off */ -+ return -3; -+ } -+ } -+ -+ if (WMTDRV_TYPE_WMT > drvType) { -+ if (NULL != gpWmtFuncOps[drvType] && NULL != gpWmtFuncOps[drvType]->func_on) { -+ iRet = (*(gpWmtFuncOps[drvType]->func_on)) (gMtkWmtCtx.p_ic_ops, wmt_conf_get_cfg()); -+ if (0 != iRet) -+ gMtkWmtCtx.eDrvStatus[drvType] = DRV_STS_POWER_OFF; -+ else -+ gMtkWmtCtx.eDrvStatus[drvType] = DRV_STS_FUNC_ON; -+ } else { -+ WMT_WARN_FUNC("WMT-CORE: ops for type(%d) not found\n", drvType); -+ iRet = -5; -+ } -+ } else { -+ if (WMTDRV_TYPE_LPBK == drvType) -+ gMtkWmtCtx.eDrvStatus[drvType] = DRV_STS_FUNC_ON; -+ else if (WMTDRV_TYPE_COREDUMP == drvType) -+ gMtkWmtCtx.eDrvStatus[drvType] = DRV_STS_FUNC_ON; -+ iRet = 0; -+ } -+ -+ if (iRet) { -+ WMT_ERR_FUNC("WMT-CORE:type(0x%x) function on failed, ret(%d)\n", drvType, iRet); -+ osal_assert(0); -+ /* FIX-ME:[Chaozhong Liang], Error handling? check subsystem state and do pwr off if necessary? */ -+ /* check all sub-func and do power off */ -+ if ((DRV_STS_POWER_OFF == gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_BT]) && -+ (DRV_STS_POWER_OFF == gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_GPS]) && -+ (DRV_STS_POWER_OFF == gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_FM]) && -+ (DRV_STS_POWER_OFF == gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WIFI]) && -+ (DRV_STS_POWER_OFF == gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_LPBK]) && -+ (DRV_STS_POWER_OFF == gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_COREDUMP])) { -+ WMT_INFO_FUNC("WMT-CORE:Fun(%d) [POWER_OFF] and power down chip\n", drvType); -+ mtk_wcn_wmt_system_state_reset(); -+ -+ iPwrOffRet = opfunc_pwr_off(pWmtOp); -+ if (iPwrOffRet) { -+ WMT_ERR_FUNC("WMT-CORE: wmt_pwr_off fail(%d) when turn off func(%d)\n", iPwrOffRet, -+ drvType); -+ osal_assert(0); -+ } -+ } -+ return iRet; -+ } -+ -+ wmt_core_dump_func_state("AF FUNC ON"); -+ -+ return 0; -+} -+ -+static INT32 opfunc_func_off(P_WMT_OP pWmtOp) -+{ -+ -+ INT32 iRet = -1; -+ UINT32 drvType; -+ -+ drvType = pWmtOp->au4OpData[0]; -+ /* Check abnormal type */ -+ if (WMTDRV_TYPE_COREDUMP < drvType) { -+ WMT_ERR_FUNC("WMT-CORE: abnormal Fun(%d) in wmt_func_off\n", drvType); -+ osal_assert(0); -+ return -1; -+ } -+ -+ /* Check abnormal state */ -+ if (DRV_STS_MAX <= gMtkWmtCtx.eDrvStatus[drvType]) { -+ WMT_ERR_FUNC("WMT-CORE: Fun(%d) DRV_STS_[0x%x] abnormal in wmt_func_off\n", -+ drvType, gMtkWmtCtx.eDrvStatus[drvType]); -+ osal_assert(0); -+ return -2; -+ } -+ -+ if (DRV_STS_FUNC_ON != gMtkWmtCtx.eDrvStatus[drvType]) { -+ WMT_WARN_FUNC("WMT-CORE: Fun(%d) DRV_STS_[0x%x] already non-FUN_ON in wmt_func_off\n", -+ drvType, gMtkWmtCtx.eDrvStatus[drvType]); -+ /* needs to check 4 subsystem's state? */ -+ return 0; -+ } else if (WMTDRV_TYPE_WMT > drvType) { -+ if (NULL != gpWmtFuncOps[drvType] && NULL != gpWmtFuncOps[drvType]->func_off) { -+ iRet = (*(gpWmtFuncOps[drvType]->func_off)) (gMtkWmtCtx.p_ic_ops, wmt_conf_get_cfg()); -+ } else { -+ WMT_WARN_FUNC("WMT-CORE: ops for type(%d) not found\n", drvType); -+ iRet = -3; -+ } -+ } else { -+ if (WMTDRV_TYPE_LPBK == drvType) -+ gMtkWmtCtx.eDrvStatus[drvType] = DRV_STS_POWER_OFF; -+ else if (WMTDRV_TYPE_COREDUMP == drvType) -+ gMtkWmtCtx.eDrvStatus[drvType] = DRV_STS_POWER_OFF; -+ iRet = 0; -+ } -+ -+ /* shall we put device state to POWER_OFF state when fail? */ -+ gMtkWmtCtx.eDrvStatus[drvType] = DRV_STS_POWER_OFF; -+ -+ if (iRet) { -+ WMT_ERR_FUNC("WMT-CORE: type(0x%x) function off failed, ret(%d)\n", drvType, iRet); -+ osal_assert(0); -+ /* no matter subsystem function control fail or not, -+ *chip should be powered off when no subsystem is active -+ */ -+ /* return iRet; */ -+ } -+ -+ /* check all sub-func and do power off */ -+ if ((DRV_STS_POWER_OFF == gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_BT]) && -+ (DRV_STS_POWER_OFF == gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_GPS]) && -+ (DRV_STS_POWER_OFF == gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_FM]) && -+ (DRV_STS_POWER_OFF == gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WIFI]) && -+ (DRV_STS_POWER_OFF == gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_LPBK]) && -+ (DRV_STS_POWER_OFF == gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_COREDUMP])) { -+ WMT_INFO_FUNC("WMT-CORE:Fun(%d) [POWER_OFF] and power down chip\n", drvType); -+ -+ iRet = opfunc_pwr_off(pWmtOp); -+ if (iRet) { -+ WMT_ERR_FUNC("WMT-CORE: wmt_pwr_off fail(%d) when turn off func(%d)\n", iRet, drvType); -+ osal_assert(0); -+ } -+ } -+ -+ wmt_core_dump_func_state("AF FUNC OFF"); -+ return iRet; -+} -+ -+/* TODO:[ChangeFeature][George] is this OP obsoleted? */ -+static INT32 opfunc_reg_rw(P_WMT_OP pWmtOp) -+{ -+ INT32 iret; -+ -+ if (DRV_STS_FUNC_ON != gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT]) { -+ WMT_ERR_FUNC("reg_rw when WMT is powered off\n"); -+ return -1; -+ } -+ iret = wmt_core_reg_rw_raw(pWmtOp->au4OpData[0], -+ pWmtOp->au4OpData[1], (PUINT32) pWmtOp->au4OpData[2], pWmtOp->au4OpData[3]); -+ -+ return iret; -+} -+ -+static INT32 opfunc_exit(P_WMT_OP pWmtOp) -+{ -+ /* TODO: [FixMe][George] is ok to leave this function empty??? */ -+ WMT_WARN_FUNC("EMPTY FUNCTION\n"); -+ return 0; -+} -+ -+static INT32 opfunc_pwr_sv(P_WMT_OP pWmtOp) -+{ -+ INT32 ret = -1; -+ UINT32 u4_result = 0; -+ UINT32 evt_len; -+ UINT8 evt_buf[16] = { 0 }; -+ unsigned long ctrlPa1 = 0; -+ unsigned long ctrlPa2 = 0; -+ -+ typedef INT32(*STP_PSM_CB) (INT32); -+ STP_PSM_CB psm_cb = NULL; -+ -+ if (SLEEP == pWmtOp->au4OpData[0]) { -+ WMT_DBG_FUNC("**** Send sleep command\n"); -+ /* mtk_wcn_stp_set_psm_state(ACT_INACT); */ -+ /* (*kal_stp_flush_rx)(WMT_TASK_INDX); */ -+ ret = wmt_core_tx((PUINT8) &WMT_SLEEP_CMD[0], sizeof(WMT_SLEEP_CMD), &u4_result, 0); -+ if (ret || (u4_result != sizeof(WMT_SLEEP_CMD))) { -+ WMT_ERR_FUNC("wmt_core: SLEEP_CMD ret(%d) cmd len err(%d, %d) ", ret, u4_result, -+ sizeof(WMT_SLEEP_CMD)); -+ goto pwr_sv_done; -+ } -+ -+ evt_len = sizeof(WMT_SLEEP_EVT); -+ ret = wmt_core_rx(evt_buf, evt_len, &u4_result); -+ if (ret || (u4_result != evt_len)) { -+ unsigned long type = WMTDRV_TYPE_WMT; -+ unsigned long reason = 33; -+ unsigned long ctrlpa = 1; -+ -+ wmt_core_rx_flush(WMT_TASK_INDX); -+ WMT_ERR_FUNC("wmt_core: read SLEEP_EVT fail(%d) len(%d, %d)", ret, u4_result, evt_len); -+ mtk_wcn_stp_dbg_dump_package(); -+ ret = wmt_core_ctrl(WMT_CTRL_EVT_PARSER, &ctrlpa, 0); -+ if (!ret) { /* parser ok */ -+ reason = 38; /* host schedule issue reason code */ -+ WMT_WARN_FUNC("This evt error may be caused by system schedule issue\n"); -+ } -+ wmt_core_ctrl(WMT_CTRL_EVT_ERR_TRG_ASSERT, &type, &reason); -+ goto pwr_sv_done; -+ } -+ -+ if (osal_memcmp(evt_buf, WMT_SLEEP_EVT, sizeof(WMT_SLEEP_EVT)) != 0) { -+ WMT_ERR_FUNC("wmt_core: compare WMT_SLEEP_EVT error\n"); -+ wmt_core_rx_flush(WMT_TASK_INDX); -+ WMT_ERR_FUNC("wmt_core: rx(%d):[%02X,%02X,%02X,%02X,%02X,%02X]\n", -+ u4_result, -+ evt_buf[0], -+ evt_buf[1], -+ evt_buf[2], -+ evt_buf[3], -+ evt_buf[4], -+ evt_buf[5]); -+ WMT_ERR_FUNC("wmt_core: exp(%d):[%02X,%02X,%02X,%02X,%02X,%02X]\n", -+ sizeof(WMT_SLEEP_EVT), -+ WMT_SLEEP_EVT[0], -+ WMT_SLEEP_EVT[1], -+ WMT_SLEEP_EVT[2], -+ WMT_SLEEP_EVT[3], -+ WMT_SLEEP_EVT[4], -+ WMT_SLEEP_EVT[5]); -+ mtk_wcn_stp_dbg_dump_package(); -+ goto pwr_sv_done; -+ } else { -+ WMT_DBG_FUNC("Send sleep command OK!\n"); -+ } -+ } else if (pWmtOp->au4OpData[0] == WAKEUP) { -+ WMT_DBG_FUNC("wakeup connsys by btif"); -+ -+ ret = wmt_core_ctrl(WMT_CTRL_SOC_WAKEUP_CONSYS, &ctrlPa1, &ctrlPa2); -+ if (ret) { -+ WMT_ERR_FUNC("wmt-core:WAKEUP_CONSYS by BTIF fail(%d)", ret); -+ goto pwr_sv_done; -+ } -+#if 0 -+ WMT_DBG_FUNC("**** Send wakeup command\n"); -+ ret = wmt_core_tx(WMT_WAKEUP_CMD, sizeof(WMT_WAKEUP_CMD), &u4_result, 1); -+ -+ if (ret || (u4_result != sizeof(WMT_WAKEUP_CMD))) { -+ wmt_core_rx_flush(WMT_TASK_INDX); -+ WMT_ERR_FUNC("wmt_core: WAKEUP_CMD ret(%d) cmd len err(%d, %d) ", ret, u4_result, -+ sizeof(WMT_WAKEUP_CMD)); -+ goto pwr_sv_done; -+ } -+#endif -+ evt_len = sizeof(WMT_WAKEUP_EVT); -+ ret = wmt_core_rx(evt_buf, evt_len, &u4_result); -+ if (ret || (u4_result != evt_len)) { -+ unsigned long type = WMTDRV_TYPE_WMT; -+ unsigned long reason = 34; -+ unsigned long ctrlpa = 2; -+ -+ WMT_ERR_FUNC("wmt_core: read WAKEUP_EVT fail(%d) len(%d, %d)", ret, u4_result, evt_len); -+ mtk_wcn_stp_dbg_dump_package(); -+ ret = wmt_core_ctrl(WMT_CTRL_EVT_PARSER, &ctrlpa, 0); -+ if (!ret) { /* parser ok */ -+ reason = 39; /* host schedule issue reason code */ -+ WMT_WARN_FUNC("This evt error may be caused by system schedule issue\n"); -+ } -+ wmt_core_ctrl(WMT_CTRL_EVT_ERR_TRG_ASSERT, &type, &reason); -+ goto pwr_sv_done; -+ } -+ -+ if (osal_memcmp(evt_buf, WMT_WAKEUP_EVT, sizeof(WMT_WAKEUP_EVT)) != 0) { -+ WMT_ERR_FUNC("wmt_core: compare WMT_WAKEUP_EVT error\n"); -+ wmt_core_rx_flush(WMT_TASK_INDX); -+ WMT_ERR_FUNC("wmt_core: rx(%d):[%02X,%02X,%02X,%02X,%02X,%02X]\n", -+ u4_result, -+ evt_buf[0], -+ evt_buf[1], -+ evt_buf[2], -+ evt_buf[3], -+ evt_buf[4], -+ evt_buf[5]); -+ WMT_ERR_FUNC("wmt_core: exp(%d):[%02X,%02X,%02X,%02X,%02X,%02X]\n", -+ sizeof(WMT_WAKEUP_EVT), -+ WMT_WAKEUP_EVT[0], -+ WMT_WAKEUP_EVT[1], -+ WMT_WAKEUP_EVT[2], -+ WMT_WAKEUP_EVT[3], -+ WMT_WAKEUP_EVT[4], -+ WMT_WAKEUP_EVT[5]); -+ mtk_wcn_stp_dbg_dump_package(); -+ goto pwr_sv_done; -+ } else { -+ WMT_DBG_FUNC("Send wakeup command OK!\n"); -+ } -+ } else if (pWmtOp->au4OpData[0] == HOST_AWAKE) { -+ -+ WMT_DBG_FUNC("**** Send host awake command\n"); -+ -+ psm_cb = (STP_PSM_CB) pWmtOp->au4OpData[1]; -+ /* (*kal_stp_flush_rx)(WMT_TASK_INDX); */ -+ ret = wmt_core_tx((PUINT8) WMT_HOST_AWAKE_CMD, sizeof(WMT_HOST_AWAKE_CMD), &u4_result, 0); -+ if (ret || (u4_result != sizeof(WMT_HOST_AWAKE_CMD))) { -+ WMT_ERR_FUNC("wmt_core: HOST_AWAKE_CMD ret(%d) cmd len err(%d, %d) ", ret, u4_result, -+ sizeof(WMT_HOST_AWAKE_CMD)); -+ goto pwr_sv_done; -+ } -+ -+ evt_len = sizeof(WMT_HOST_AWAKE_EVT); -+ ret = wmt_core_rx(evt_buf, evt_len, &u4_result); -+ if (ret || (u4_result != evt_len)) { -+ unsigned long type = WMTDRV_TYPE_WMT; -+ unsigned long reason = 35; -+ unsigned long ctrlpa = 3; -+ -+ wmt_core_rx_flush(WMT_TASK_INDX); -+ WMT_ERR_FUNC("wmt_core: read HOST_AWAKE_EVT fail(%d) len(%d, %d)", ret, u4_result, evt_len); -+ mtk_wcn_stp_dbg_dump_package(); -+ ret = wmt_core_ctrl(WMT_CTRL_EVT_PARSER, &ctrlpa, 0); -+ if (!ret) { /* parser ok */ -+ reason = 40; /* host schedule issue reason code */ -+ WMT_WARN_FUNC("This evt error may be caused by system schedule issue\n"); -+ } -+ wmt_core_ctrl(WMT_CTRL_EVT_ERR_TRG_ASSERT, &type, &reason); -+ goto pwr_sv_done; -+ } -+ -+ if (osal_memcmp(evt_buf, WMT_HOST_AWAKE_EVT, sizeof(WMT_HOST_AWAKE_EVT)) != 0) { -+ WMT_ERR_FUNC("wmt_core: compare WMT_HOST_AWAKE_EVT error\n"); -+ wmt_core_rx_flush(WMT_TASK_INDX); -+ WMT_ERR_FUNC("wmt_core: rx(%d):[%02X,%02X,%02X,%02X,%02X,%02X]\n", -+ u4_result, -+ evt_buf[0], -+ evt_buf[1], -+ evt_buf[2], -+ evt_buf[3], -+ evt_buf[4], -+ evt_buf[5]); -+ WMT_ERR_FUNC("wmt_core: exp(%d):[%02X,%02X,%02X,%02X,%02X,%02X]\n", -+ sizeof(WMT_HOST_AWAKE_EVT), -+ WMT_HOST_AWAKE_EVT[0], -+ WMT_HOST_AWAKE_EVT[1], -+ WMT_HOST_AWAKE_EVT[2], -+ WMT_HOST_AWAKE_EVT[3], -+ WMT_HOST_AWAKE_EVT[4], -+ WMT_HOST_AWAKE_EVT[5]); -+ mtk_wcn_stp_dbg_dump_package(); -+ /* goto pwr_sv_done; */ -+ } else { -+ WMT_DBG_FUNC("Send host awake command OK!\n"); -+ } -+ } -+pwr_sv_done: -+ -+ if (pWmtOp->au4OpData[0] < STP_PSM_MAX_ACTION) { -+ psm_cb = (STP_PSM_CB) pWmtOp->au4OpData[1]; -+ WMT_DBG_FUNC("Do STP-CB! %d %p / %p\n", pWmtOp->au4OpData[0], (PVOID) pWmtOp->au4OpData[1], -+ (PVOID) psm_cb); -+ if (NULL != psm_cb) { -+ psm_cb(pWmtOp->au4OpData[0]); -+ } else { -+ WMT_ERR_FUNC("fatal error !!!, psm_cb = %p, god, someone must have corrupted our memory.\n", -+ psm_cb); -+ } -+ } -+ -+ return ret; -+} -+ -+static INT32 opfunc_dsns(P_WMT_OP pWmtOp) -+{ -+ -+ INT32 iRet = -1; -+ UINT32 u4Res; -+ UINT32 evtLen; -+ UINT8 evtBuf[16] = { 0 }; -+ -+ WMT_DSNS_CMD[4] = (UINT8) pWmtOp->au4OpData[0]; -+ WMT_DSNS_CMD[5] = (UINT8) pWmtOp->au4OpData[1]; -+ -+ /* send command */ -+ /* iRet = (*kal_stp_tx)(WMT_DSNS_CMD, osal_sizeof(WMT_DSNS_CMD), &u4Res); */ -+ iRet = wmt_core_tx((PUINT8) WMT_DSNS_CMD, osal_sizeof(WMT_DSNS_CMD), &u4Res, MTK_WCN_BOOL_FALSE); -+ if (iRet || (u4Res != osal_sizeof(WMT_DSNS_CMD))) { -+ WMT_ERR_FUNC("WMT-CORE: DSNS_CMD iRet(%d) cmd len err(%d, %d)\n", iRet, u4Res, -+ osal_sizeof(WMT_DSNS_CMD)); -+ return iRet; -+ } -+ -+ evtLen = osal_sizeof(WMT_DSNS_EVT); -+ -+ iRet = wmt_core_rx(evtBuf, evtLen, &u4Res); -+ if (iRet || (u4Res != evtLen)) { -+ WMT_ERR_FUNC("WMT-CORE: read DSNS_EVT fail(%d) len(%d, %d)\n", iRet, u4Res, evtLen); -+ mtk_wcn_stp_dbg_dump_package(); -+ return iRet; -+ } -+ -+ if (osal_memcmp(evtBuf, WMT_DSNS_EVT, osal_sizeof(WMT_DSNS_EVT)) != 0) { -+ WMT_ERR_FUNC("WMT-CORE: compare WMT_DSNS_EVT error\n"); -+ WMT_ERR_FUNC("WMT-CORE: rx(%d):[%02X,%02X,%02X,%02X,%02X] exp(%d):[%02X,%02X,%02X,%02X,%02X]\n", -+ u4Res, evtBuf[0], evtBuf[1], evtBuf[2], evtBuf[3], evtBuf[4], -+ osal_sizeof(WMT_DSNS_EVT), WMT_DSNS_EVT[0], WMT_DSNS_EVT[1], WMT_DSNS_EVT[2], -+ WMT_DSNS_EVT[3], WMT_DSNS_EVT[4]); -+ } else { -+ WMT_INFO_FUNC("Send WMT_DSNS_CMD command OK!\n"); -+ } -+ -+ return iRet; -+} -+ -+#if CFG_CORE_INTERNAL_TXRX -+INT32 wmt_core_lpbk_do_stp_init(void) -+{ -+ INT32 iRet = 0; -+ unsigned long ctrlPa1 = 0; -+ unsigned long ctrlPa2 = 0; -+ -+ ctrlPa1 = 0; -+ ctrlPa2 = 0; -+ iRet = wmt_core_ctrl(WMT_CTRL_STP_OPEN, &ctrlPa1, &ctrlPa2); -+ if (iRet) { -+ WMT_ERR_FUNC("WMT-CORE: wmt open stp\n"); -+ return -1; -+ } -+ -+ ctrlPa1 = WMT_STP_CONF_MODE; -+ ctrlPa2 = MTKSTP_BTIF_MAND_MODE; -+ iRet += wmt_core_ctrl(WMT_CTRL_STP_CONF, &ctrlPa1, &ctrlPa2); -+ -+ ctrlPa1 = WMT_STP_CONF_EN; -+ ctrlPa2 = 1; -+ iRet += wmt_core_ctrl(WMT_CTRL_STP_CONF, &ctrlPa1, &ctrlPa2); -+ if (iRet) { -+ WMT_ERR_FUNC("WMT-CORE: stp_init <1><2> fail:%d\n", iRet); -+ return -2; -+ } -+} -+ -+INT32 wmt_core_lpbk_do_stp_deinit(void) -+{ -+ INT32 iRet = 0; -+ unsigned long ctrlPa1 = 0; -+ unsigned long ctrlPa2 = 0; -+ -+ ctrlPa1 = 0; -+ ctrlPa2 = 0; -+ iRet = wmt_core_ctrl(WMT_CTRL_STP_CLOSE, &ctrlPa1, &ctrlPa2); -+ if (iRet) { -+ WMT_ERR_FUNC("WMT-CORE: wmt open stp\n"); -+ return -1; -+ } -+ -+ return 0; -+} -+#endif -+static INT32 opfunc_lpbk(P_WMT_OP pWmtOp) -+{ -+ -+ INT32 iRet; -+ UINT32 u4WrittenSize = 0; -+ UINT32 u4ReadSize = 0; -+ UINT32 buf_length = 0; -+ UINT32 *pbuffer = NULL; -+ UINT16 len_in_cmd; -+ -+ /* UINT32 offset; */ -+ UINT8 WMT_TEST_LPBK_CMD[] = { 0x1, 0x2, 0x0, 0x0, 0x7 }; -+ UINT8 WMT_TEST_LPBK_EVT[] = { 0x2, 0x2, 0x0, 0x0, 0x0 }; -+ -+ /* UINT8 lpbk_buf[1024 + 5] = {0}; */ -+ MTK_WCN_BOOL fgFail; -+ -+ buf_length = pWmtOp->au4OpData[0]; /* packet length */ -+ pbuffer = (VOID *) pWmtOp->au4OpData[1]; /* packet buffer pointer */ -+ WMT_DBG_FUNC("WMT-CORE: -->wmt_do_lpbk\n"); -+ -+#if 0 -+ osal_memcpy(&WMT_TEST_LPBK_EVT[0], &WMT_TEST_LPBK_CMD[0], osal_sizeof(WMT_TEST_LPBK_CMD)); -+#endif -+#if !CFG_CORE_INTERNAL_TXRX -+ /*check if WMTDRV_TYPE_LPBK function is already on */ -+ if (DRV_STS_FUNC_ON != gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_LPBK] -+ || buf_length + osal_sizeof(WMT_TEST_LPBK_CMD) > osal_sizeof(gLpbkBuf)) { -+ WMT_ERR_FUNC("WMT-CORE: abnormal LPBK in wmt_do_lpbk\n"); -+ osal_assert(0); -+ return -2; -+ } -+#endif -+ /*package loopback for STP */ -+ -+ /* init buffer */ -+ osal_memset(gLpbkBuf, 0, osal_sizeof(gLpbkBuf)); -+ -+ len_in_cmd = buf_length + 1; /* add flag field */ -+ -+ osal_memcpy(&WMT_TEST_LPBK_CMD[2], &len_in_cmd, 2); -+ osal_memcpy(&WMT_TEST_LPBK_EVT[2], &len_in_cmd, 2); -+ -+ /* wmt cmd */ -+ osal_memcpy(gLpbkBuf, WMT_TEST_LPBK_CMD, osal_sizeof(WMT_TEST_LPBK_CMD)); -+ osal_memcpy(gLpbkBuf + osal_sizeof(WMT_TEST_LPBK_CMD), pbuffer, buf_length); -+ -+ do { -+ fgFail = MTK_WCN_BOOL_TRUE; -+ /*send packet through STP */ -+ -+ /* iRet = (*kal_stp_tx)( -+ *(PUINT8)gLpbkBuf, -+ *osal_sizeof(WMT_TEST_LPBK_CMD) + buf_length, -+ *&u4WrittenSize); -+ */ -+ iRet = wmt_core_tx((PUINT8) gLpbkBuf, -+ (osal_sizeof(WMT_TEST_LPBK_CMD) + buf_length), -+ &u4WrittenSize, -+ MTK_WCN_BOOL_FALSE); -+ if (iRet) { -+ WMT_ERR_FUNC("opfunc_lpbk wmt_core_tx failed\n"); -+ break; -+ } -+ WMT_INFO_FUNC("opfunc_lpbk wmt_core_tx OK\n"); -+ -+ /*receive firmware response from STP */ -+ iRet = wmt_core_rx((PUINT8) gLpbkBuf, (osal_sizeof(WMT_TEST_LPBK_EVT) + buf_length), &u4ReadSize); -+ if (iRet) { -+ WMT_ERR_FUNC("opfunc_lpbk wmt_core_rx failed\n"); -+ break; -+ } -+ WMT_INFO_FUNC("opfunc_lpbk wmt_core_rx OK\n"); -+ /*check if loopback response ok or not */ -+ if (u4ReadSize != (osal_sizeof(WMT_TEST_LPBK_CMD) + buf_length)) { -+ WMT_ERR_FUNC("lpbk event read size wrong(%d, %d)\n", u4ReadSize, -+ (osal_sizeof(WMT_TEST_LPBK_CMD) + buf_length)); -+ break; -+ } -+ WMT_INFO_FUNC("lpbk event read size right(%d, %d)\n", u4ReadSize, -+ (osal_sizeof(WMT_TEST_LPBK_CMD) + buf_length)); -+ -+ if (osal_memcmp(WMT_TEST_LPBK_EVT, gLpbkBuf, osal_sizeof(WMT_TEST_LPBK_EVT))) { -+ WMT_ERR_FUNC("WMT-CORE WMT_TEST_LPBK_EVT error! read len %d [%02x,%02x,%02x,%02x,%02x]\n", -+ (INT32) u4ReadSize, gLpbkBuf[0], gLpbkBuf[1], gLpbkBuf[2], gLpbkBuf[3], gLpbkBuf[4] -+ ); -+ break; -+ } -+ pWmtOp->au4OpData[0] = u4ReadSize - osal_sizeof(WMT_TEST_LPBK_EVT); -+ osal_memcpy((VOID *) pWmtOp->au4OpData[1], gLpbkBuf + osal_sizeof(WMT_TEST_LPBK_CMD), buf_length); -+ fgFail = MTK_WCN_BOOL_FALSE; -+ } while (0); -+ /*return result */ -+ /* WMT_DBG_FUNC("WMT-CORE: <--wmt_do_lpbk, fgFail = %d\n", fgFail); */ -+ return fgFail; -+ -+} -+ -+static INT32 opfunc_cmd_test(P_WMT_OP pWmtOp) -+{ -+ -+ INT32 iRet = 0; -+ UINT32 cmdNo = 0; -+ UINT32 cmdNoPa = 0; -+ -+ UINT8 tstCmd[64]; -+ UINT8 tstEvt[64]; -+ UINT8 tstEvtTmp[64]; -+ UINT32 u4Res; -+ SIZE_T tstCmdSz = 0; -+ SIZE_T tstEvtSz = 0; -+ -+ UINT8 *pRes = NULL; -+ UINT32 resBufRoom = 0; -+ /*test command list */ -+ /*1 */ -+ UINT8 WMT_ASSERT_CMD[] = { 0x01, 0x02, 0x01, 0x00, 0x08 }; -+ UINT8 WMT_ASSERT_EVT[] = { 0x02, 0x02, 0x00, 0x00, 0x00 }; -+ UINT8 WMT_NOACK_CMD[] = { 0x01, 0x02, 0x01, 0x00, 0x0A }; -+ UINT8 WMT_NOACK_EVT[] = { 0x02, 0x02, 0x00, 0x00, 0x00 }; -+ UINT8 WMT_WARNRST_CMD[] = { 0x01, 0x02, 0x01, 0x00, 0x0B }; -+ UINT8 WMT_WARNRST_EVT[] = { 0x02, 0x02, 0x00, 0x00, 0x00 }; -+ UINT8 WMT_FWLOGTST_CMD[] = { 0x01, 0x02, 0x01, 0x00, 0x0C }; -+ UINT8 WMT_FWLOGTST_EVT[] = { 0x02, 0x02, 0x00, 0x00, 0x00 }; -+ -+ UINT8 WMT_EXCEPTION_CMD[] = { 0x01, 0x02, 0x01, 0x00, 0x09 }; -+ UINT8 WMT_EXCEPTION_EVT[] = { 0x02, 0x02, 0x00, 0x00, 0x00 }; -+ /*2 */ -+ UINT8 WMT_COEXDBG_CMD[] = { 0x01, 0x10, 0x02, 0x00, -+ 0x08, -+ 0xAA /*Debugging Parameter */ -+ }; -+ UINT8 WMT_COEXDBG_1_EVT[] = { 0x02, 0x10, 0x05, 0x00, -+ 0x00, -+ 0xAA, 0xAA, 0xAA, 0xAA /*event content */ -+ }; -+ UINT8 WMT_COEXDBG_2_EVT[] = { 0x02, 0x10, 0x07, 0x00, -+ 0x00, -+ 0xAA, 0xAA, 0xAA, 0xAA, 0xBB, 0xBB /*event content */ -+ }; -+ UINT8 WMT_COEXDBG_3_EVT[] = { 0x02, 0x10, 0x0B, 0x00, -+ 0x00, -+ 0xAA, 0xAA, 0xAA, 0xAA, 0xBB, 0xBB, 0xBB, 0xBB /*event content */ -+ }; -+ /*test command list -end */ -+ -+ cmdNo = pWmtOp->au4OpData[0]; -+ -+ WMT_INFO_FUNC("Send Test command %d!\n", cmdNo); -+ if (cmdNo == 0) { -+ /*dead command */ -+ WMT_INFO_FUNC("Send Assert command !\n"); -+ tstCmdSz = osal_sizeof(WMT_ASSERT_CMD); -+ tstEvtSz = osal_sizeof(WMT_ASSERT_EVT); -+ osal_memcpy(tstCmd, WMT_ASSERT_CMD, tstCmdSz); -+ osal_memcpy(tstEvt, WMT_ASSERT_EVT, tstEvtSz); -+ } else if (cmdNo == 1) { -+ /*dead command */ -+ WMT_INFO_FUNC("Send Exception command !\n"); -+ tstCmdSz = osal_sizeof(WMT_EXCEPTION_CMD); -+ tstEvtSz = osal_sizeof(WMT_EXCEPTION_EVT); -+ osal_memcpy(tstCmd, WMT_EXCEPTION_CMD, tstCmdSz); -+ osal_memcpy(tstEvt, WMT_EXCEPTION_EVT, tstEvtSz); -+ } else if (cmdNo == 2) { -+ cmdNoPa = pWmtOp->au4OpData[1]; -+ pRes = (PUINT8) pWmtOp->au4OpData[2]; -+ resBufRoom = pWmtOp->au4OpData[3]; -+ if (cmdNoPa <= 0xf) { -+ WMT_INFO_FUNC("Send Coexistence Debug command [0x%x]!\n", cmdNoPa); -+ tstCmdSz = osal_sizeof(WMT_COEXDBG_CMD); -+ osal_memcpy(tstCmd, WMT_COEXDBG_CMD, tstCmdSz); -+ if (tstCmdSz > 5) -+ tstCmd[5] = cmdNoPa; -+ -+ /*setup the expected event length */ -+ if (cmdNoPa <= 0x4) { -+ tstEvtSz = osal_sizeof(WMT_COEXDBG_1_EVT); -+ osal_memcpy(tstEvt, WMT_COEXDBG_1_EVT, tstEvtSz); -+ } else if (cmdNoPa == 0x5) { -+ tstEvtSz = osal_sizeof(WMT_COEXDBG_2_EVT); -+ osal_memcpy(tstEvt, WMT_COEXDBG_2_EVT, tstEvtSz); -+ } else if (cmdNoPa >= 0x6 && cmdNoPa <= 0xf) { -+ tstEvtSz = osal_sizeof(WMT_COEXDBG_3_EVT); -+ osal_memcpy(tstEvt, WMT_COEXDBG_3_EVT, tstEvtSz); -+ } else { -+ -+ } -+ } else { -+ WMT_ERR_FUNC("cmdNoPa is wrong\n"); -+ return iRet; -+ } -+ } else if (cmdNo == 3) { -+ /*dead command */ -+ WMT_INFO_FUNC("Send No Ack command !\n"); -+ tstCmdSz = osal_sizeof(WMT_NOACK_CMD); -+ tstEvtSz = osal_sizeof(WMT_NOACK_EVT); -+ osal_memcpy(tstCmd, WMT_NOACK_CMD, tstCmdSz); -+ osal_memcpy(tstEvt, WMT_NOACK_EVT, tstEvtSz); -+ } else if (cmdNo == 4) { -+ /*dead command */ -+ WMT_INFO_FUNC("Send Warm reset command !\n"); -+ tstCmdSz = osal_sizeof(WMT_WARNRST_CMD); -+ tstEvtSz = osal_sizeof(WMT_WARNRST_EVT); -+ osal_memcpy(tstCmd, WMT_WARNRST_CMD, tstCmdSz); -+ osal_memcpy(tstEvt, WMT_WARNRST_EVT, tstEvtSz); -+ } else if (cmdNo == 5) { -+ /*dead command */ -+ WMT_INFO_FUNC("Send f/w log test command !\n"); -+ tstCmdSz = osal_sizeof(WMT_FWLOGTST_CMD); -+ tstEvtSz = osal_sizeof(WMT_FWLOGTST_EVT); -+ osal_memcpy(tstCmd, WMT_FWLOGTST_CMD, tstCmdSz); -+ osal_memcpy(tstEvt, WMT_FWLOGTST_EVT, tstEvtSz); -+ } -+ -+ else { -+ /*Placed youer test WMT command here, easiler to integrate and test with F/W side */ -+ } -+ -+ /* send command */ -+ /* iRet = (*kal_stp_tx)(tstCmd, tstCmdSz, &u4Res); */ -+ iRet = wmt_core_tx((PUINT8) tstCmd, tstCmdSz, &u4Res, MTK_WCN_BOOL_FALSE); -+ if (iRet || (u4Res != tstCmdSz)) { -+ WMT_ERR_FUNC("WMT-CORE: wmt_cmd_test iRet(%d) cmd len err(%d, %d)\n", iRet, u4Res, tstCmdSz); -+ return -1; -+ } -+ -+ if ((cmdNo == 0) || (cmdNo == 1) || cmdNo == 3) { -+ WMT_INFO_FUNC("WMT-CORE: not to rx event for assert command\n"); -+ return 0; -+ } -+ -+ iRet = wmt_core_rx(tstEvtTmp, tstEvtSz, &u4Res); -+ -+ /*Event Post Handling */ -+ if (cmdNo == 2) { -+ WMT_INFO_FUNC("#=========================================================#\n"); -+ WMT_INFO_FUNC("coext debugging id = %d", cmdNoPa); -+ if (tstEvtSz > 5) { -+ wmt_core_dump_data(&tstEvtTmp[5], "coex debugging ", tstEvtSz - 5); -+ } else { -+ /* error log */ -+ WMT_ERR_FUNC("error coex debugging event\n"); -+ } -+ /*put response to buffer for shell to read */ -+ if (pRes != NULL && resBufRoom > 0) { -+ pWmtOp->au4OpData[3] = resBufRoom < tstEvtSz - 5 ? resBufRoom : tstEvtSz - 5; -+ osal_memcpy(pRes, &tstEvtTmp[5], pWmtOp->au4OpData[3]); -+ } else -+ pWmtOp->au4OpData[3] = 0; -+ WMT_INFO_FUNC("#=========================================================#\n"); -+ } -+ -+ return iRet; -+ -+} -+ -+static INT32 opfunc_hw_rst(P_WMT_OP pWmtOp) -+{ -+ -+ INT32 iRet = -1; -+ unsigned long ctrlPa1; -+ unsigned long ctrlPa2; -+ -+ wmt_core_dump_func_state("BE HW RST"); -+ /*-->Reset WMT data structure*/ -+ /* gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_BT] = DRV_STS_POWER_OFF; */ -+ gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_FM] = DRV_STS_POWER_OFF; -+ gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_GPS] = DRV_STS_POWER_OFF; -+ /* gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WIFI] = DRV_STS_POWER_OFF; */ -+ gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_LPBK] = DRV_STS_POWER_OFF; -+ gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_STP] = DRV_STS_POWER_OFF; -+ gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_COREDUMP] = DRV_STS_POWER_OFF; -+ /*enable power off flag, if flag=0, power off connsys will not be executed */ -+ mtk_wcn_set_connsys_power_off_flag(MTK_WCN_BOOL_TRUE); -+ /* if wmt is poweroff, we need poweron chip first */ -+ /* Zhiguo : this action also needed in BTIF interface to avoid KE */ -+#if 1 -+ if (DRV_STS_POWER_OFF == gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT]) { -+ WMT_WARN_FUNC("WMT-CORE: WMT is off, need re-poweron\n"); -+ /* power on control */ -+ ctrlPa1 = 0; -+ ctrlPa2 = 0; -+ iRet = wmt_core_ctrl(WMT_CTRL_HW_PWR_ON, &ctrlPa1, &ctrlPa2); -+ if (iRet) { -+ WMT_ERR_FUNC("WMT-CORE: WMT_CTRL_HW_PWR_ON fail iRet(%d)\n", iRet); -+ return -1; -+ } -+ gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT] = DRV_STS_POWER_ON; -+ } -+#endif -+ if (gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_BT] == DRV_STS_FUNC_ON) { -+ -+ ctrlPa1 = BT_PALDO; -+ ctrlPa2 = PALDO_OFF; -+ iRet = wmt_core_ctrl(WMT_CTRL_SOC_PALDO_CTRL, &ctrlPa1, &ctrlPa2); -+ if (iRet) -+ WMT_ERR_FUNC("WMT-CORE: wmt_ctrl_soc_paldo_ctrl failed(%d)(%d)(%d)\n", iRet, ctrlPa1, ctrlPa2); -+ -+ gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_BT] = DRV_STS_POWER_OFF; -+ } -+ -+ if (gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WIFI] == DRV_STS_FUNC_ON) { -+ -+ if (NULL != gpWmtFuncOps[WMTDRV_TYPE_WIFI] && NULL != gpWmtFuncOps[WMTDRV_TYPE_WIFI]->func_off) { -+ iRet = gpWmtFuncOps[WMTDRV_TYPE_WIFI]->func_off(gMtkWmtCtx.p_ic_ops, wmt_conf_get_cfg()); -+ if (iRet) { -+ WMT_ERR_FUNC("WMT-CORE: turn off WIFI func fail (%d)\n", iRet); -+ -+ /* check all sub-func and do power off */ -+ } else { -+ WMT_INFO_FUNC("wmt core: turn off WIFI func ok!!\n"); -+ } -+ } -+ gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WIFI] = DRV_STS_POWER_OFF; -+ } -+#if 0 -+ /*<4>Power off Combo chip */ -+ ctrlPa1 = 0; -+ ctrlPa2 = 0; -+ iRet = wmt_core_ctrl(WMT_CTRL_HW_RST, &ctrlPa1, &ctrlPa2); -+ if (iRet) -+ WMT_ERR_FUNC("WMT-CORE: [HW RST] WMT_CTRL_POWER_OFF fail (%d)", iRet); -+ WMT_INFO_FUNC("WMT-CORE: [HW RST] WMT_CTRL_POWER_OFF ok (%d)", iRet); -+#endif -+ gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT] = DRV_STS_POWER_OFF; -+ -+ /*-->PesetCombo chip*/ -+ iRet = wmt_core_ctrl(WMT_CTRL_HW_RST, &ctrlPa1, &ctrlPa2); -+ if (iRet) -+ WMT_ERR_FUNC("WMT-CORE: -->[HW RST] fail iRet(%d)\n", iRet); -+ WMT_WARN_FUNC("WMT-CORE: -->[HW RST] ok\n"); -+ -+ gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT] = DRV_STS_POWER_ON; -+ -+ /* 4 close stp */ -+ ctrlPa1 = 0; -+ ctrlPa2 = 0; -+ iRet = wmt_core_ctrl(WMT_CTRL_STP_CLOSE, &ctrlPa1, &ctrlPa2); -+ if (iRet) { -+ if (iRet == -2) { -+ WMT_INFO_FUNC("WMT-CORE:stp should have be closed\n"); -+ return 0; -+ } -+ WMT_ERR_FUNC("WMT-CORE: wmt close stp failed\n"); -+ return -1; -+ } -+ -+ wmt_core_dump_func_state("AF HW RST"); -+ return iRet; -+ -+} -+ -+static INT32 opfunc_sw_rst(P_WMT_OP pWmtOp) -+{ -+ INT32 iRet = 0; -+ -+ iRet = wmt_core_stp_init(); -+ if (!iRet) -+ gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT] = DRV_STS_FUNC_ON; -+ return iRet; -+} -+ -+static INT32 opfunc_stp_rst(P_WMT_OP pWmtOp) -+{ -+ -+ return 0; -+} -+ -+static INT32 opfunc_therm_ctrl(P_WMT_OP pWmtOp) -+{ -+ -+ INT32 iRet = -1; -+ UINT32 u4Res; -+ UINT32 evtLen; -+ UINT8 evtBuf[16] = { 0 }; -+ -+ WMT_THERM_CMD[4] = pWmtOp->au4OpData[0]; /*CMD type, refer to ENUM_WMTTHERM_TYPE_T */ -+ -+ /* send command */ -+ /* iRet = (*kal_stp_tx)(WMT_THERM_CMD, osal_sizeof(WMT_THERM_CMD), &u4Res); */ -+ iRet = wmt_core_tx((PUINT8) WMT_THERM_CMD, osal_sizeof(WMT_THERM_CMD), &u4Res, MTK_WCN_BOOL_FALSE); -+ if (iRet || (u4Res != osal_sizeof(WMT_THERM_CMD))) { -+ WMT_ERR_FUNC("WMT-CORE: THERM_CTRL_CMD iRet(%d) cmd len err(%d, %d)\n", iRet, u4Res, -+ osal_sizeof(WMT_THERM_CMD)); -+ return iRet; -+ } -+ -+ evtLen = 16; -+ -+ iRet = wmt_core_rx(evtBuf, evtLen, &u4Res); -+ if (iRet || ((u4Res != osal_sizeof(WMT_THERM_CTRL_EVT)) && (u4Res != osal_sizeof(WMT_THERM_READ_EVT)))) { -+ WMT_ERR_FUNC("WMT-CORE: read THERM_CTRL_EVT/THERM_READ_EVENT fail(%d) len(%d, %d)\n", iRet, u4Res, -+ evtLen); -+ mtk_wcn_stp_dbg_dump_package(); -+ return iRet; -+ } -+ if (u4Res == osal_sizeof(WMT_THERM_CTRL_EVT)) { -+ if (osal_memcmp(evtBuf, WMT_THERM_CTRL_EVT, osal_sizeof(WMT_THERM_CTRL_EVT)) != 0) { -+ WMT_ERR_FUNC("WMT-CORE: compare WMT_THERM_CTRL_EVT error\n"); -+ WMT_ERR_FUNC("WMT-CORE: rx(%d):[%02X,%02X,%02X,%02X,%02X] exp(%d):[%02X,%02X,%02X,%02X,%02X]\n", -+ u4Res, evtBuf[0], evtBuf[1], evtBuf[2], evtBuf[3], evtBuf[4], -+ osal_sizeof(WMT_THERM_CTRL_EVT), WMT_THERM_CTRL_EVT[0], WMT_THERM_CTRL_EVT[1], -+ WMT_THERM_CTRL_EVT[2], WMT_THERM_CTRL_EVT[3], WMT_THERM_CTRL_EVT[4]); -+ pWmtOp->au4OpData[1] = MTK_WCN_BOOL_FALSE; /*will return to function driver */ -+ mtk_wcn_stp_dbg_dump_package(); -+ } else { -+ WMT_DBG_FUNC("Send WMT_THERM_CTRL_CMD command OK!\n"); -+ pWmtOp->au4OpData[1] = MTK_WCN_BOOL_TRUE; /*will return to function driver */ -+ } -+ } else { -+ /*no need to judge the real thermal value */ -+ if (osal_memcmp(evtBuf, WMT_THERM_READ_EVT, osal_sizeof(WMT_THERM_READ_EVT) - 1) != 0) { -+ WMT_ERR_FUNC("WMT-CORE: compare WMT_THERM_READ_EVT error\n"); -+ WMT_ERR_FUNC("WMT-CORE: rx(%d):[%02X,%02X,%02X,%02X,%02X,%02X] exp(%d):[%02X,%02X,%02X,%02X]\n", -+ u4Res, evtBuf[0], evtBuf[1], evtBuf[2], evtBuf[3], evtBuf[4], evtBuf[5], -+ osal_sizeof(WMT_THERM_READ_EVT), WMT_THERM_READ_EVT[0], WMT_THERM_READ_EVT[1], -+ WMT_THERM_READ_EVT[2], WMT_THERM_READ_EVT[3]); -+ pWmtOp->au4OpData[1] = 0xFF; /*will return to function driver */ -+ mtk_wcn_stp_dbg_dump_package(); -+ } else { -+ WMT_DBG_FUNC("Send WMT_THERM_READ_CMD command OK!\n"); -+ pWmtOp->au4OpData[1] = evtBuf[5]; /*will return to function driver */ -+ } -+ } -+ -+ return iRet; -+ -+} -+ -+static INT32 opfunc_efuse_rw(P_WMT_OP pWmtOp) -+{ -+ -+ INT32 iRet = -1; -+ UINT32 u4Res; -+ UINT32 evtLen; -+ UINT8 evtBuf[16] = { 0 }; -+ -+ if (DRV_STS_FUNC_ON != gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT]) { -+ WMT_ERR_FUNC("WMT-CORE: wmt_efuse_rw fail: chip is powered off\n"); -+ return -1; -+ } -+ -+ WMT_EFUSE_CMD[4] = (pWmtOp->au4OpData[0]) ? 0x1 : 0x2; /* w:2, r:1 */ -+ osal_memcpy(&WMT_EFUSE_CMD[6], (PUINT8) &pWmtOp->au4OpData[1], 2); /* address */ -+ osal_memcpy(&WMT_EFUSE_CMD[8], (PUINT32) pWmtOp->au4OpData[2], 4); /* value */ -+ -+ wmt_core_dump_data(&WMT_EFUSE_CMD[0], "efuse_cmd", osal_sizeof(WMT_EFUSE_CMD)); -+ -+ /* send command */ -+ /* iRet = (*kal_stp_tx)(WMT_EFUSE_CMD, osal_sizeof(WMT_EFUSE_CMD), &u4Res); */ -+ iRet = wmt_core_tx((PUINT8) WMT_EFUSE_CMD, osal_sizeof(WMT_EFUSE_CMD), &u4Res, MTK_WCN_BOOL_FALSE); -+ if (iRet || (u4Res != osal_sizeof(WMT_EFUSE_CMD))) { -+ WMT_ERR_FUNC("WMT-CORE: EFUSE_CMD iRet(%d) cmd len err(%d, %d)\n", iRet, u4Res, -+ osal_sizeof(WMT_EFUSE_CMD)); -+ return iRet; -+ } -+ -+ evtLen = (pWmtOp->au4OpData[0]) ? osal_sizeof(WMT_EFUSE_EVT) : osal_sizeof(WMT_EFUSE_EVT); -+ -+ iRet = wmt_core_rx(evtBuf, evtLen, &u4Res); -+ if (iRet || (u4Res != evtLen)) -+ WMT_ERR_FUNC("WMT-CORE: read REG_EVB fail(%d) len(%d, %d)\n", iRet, u4Res, evtLen); -+ wmt_core_dump_data(&evtBuf[0], "efuse_evt", osal_sizeof(evtBuf)); -+ -+ return iRet; -+ -+} -+ -+static INT32 opfunc_gpio_ctrl(P_WMT_OP pWmtOp) -+{ -+ INT32 iRet = -1; -+ WMT_IC_PIN_ID id; -+ WMT_IC_PIN_STATE stat; -+ UINT32 flag; -+ -+ if (DRV_STS_FUNC_ON != gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_WMT]) { -+ WMT_ERR_FUNC("WMT-CORE: wmt_gpio_ctrl fail: chip is powered off\n"); -+ return -1; -+ } -+ -+ if (!gMtkWmtCtx.p_ic_ops->ic_pin_ctrl) { -+ WMT_ERR_FUNC("WMT-CORE: error, gMtkWmtCtx.p_ic_ops->ic_pin_ctrl(NULL)\n"); -+ return -1; -+ } -+ -+ id = pWmtOp->au4OpData[0]; -+ stat = pWmtOp->au4OpData[1]; -+ flag = pWmtOp->au4OpData[2]; -+ -+ WMT_INFO_FUNC("ic pin id:%d, stat:%d, flag:0x%x\n", id, stat, flag); -+ -+ iRet = (*(gMtkWmtCtx.p_ic_ops->ic_pin_ctrl)) (id, stat, flag); -+ -+ return iRet; -+} -+ -+MTK_WCN_BOOL wmt_core_is_quick_ps_support(void) -+{ -+ P_WMT_CTX pctx = &gMtkWmtCtx; -+ -+ if ((NULL != pctx->p_ic_ops) && (NULL != pctx->p_ic_ops->is_quick_sleep)) -+ return (*(pctx->p_ic_ops->is_quick_sleep)) (); -+ -+ return MTK_WCN_BOOL_FALSE; -+} -+ -+MTK_WCN_BOOL wmt_core_get_aee_dump_flag(void) -+{ -+ MTK_WCN_BOOL bRet = MTK_WCN_BOOL_FALSE; -+ P_WMT_CTX pctx = &gMtkWmtCtx; -+ -+ if ((NULL != pctx->p_ic_ops) && (NULL != pctx->p_ic_ops->is_aee_dump_support)) -+ bRet = (*(pctx->p_ic_ops->is_aee_dump_support)) (); -+ else -+ bRet = MTK_WCN_BOOL_FALSE; -+ -+ return bRet; -+} -+ -+INT32 opfunc_pin_state(P_WMT_OP pWmtOp) -+{ -+ -+ unsigned long ctrlPa1 = 0; -+ unsigned long ctrlPa2 = 0; -+ UINT32 iRet = 0; -+ -+ iRet = wmt_core_ctrl(WMT_CTRL_HW_STATE_DUMP, &ctrlPa1, &ctrlPa2); -+ return iRet; -+} -+ -+static INT32 opfunc_bgw_ds(P_WMT_OP pWmtOp) -+{ -+ INT32 iRet = -1; -+ UINT32 u4WrittenSize = 0; -+ UINT32 u4ReadSize = 0; -+ UINT32 buf_len = 0; -+ UINT8 *buffer = NULL; -+ UINT8 evt_buffer[8] = { 0 }; -+ MTK_WCN_BOOL fgFail; -+ -+ UINT8 WMT_BGW_DESENSE_CMD[] = { -+ 0x01, 0x0e, 0x0f, 0x00, -+ 0x02, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00 -+ }; -+ UINT8 WMT_BGW_DESENSE_EVT[] = { 0x02, 0x0e, 0x01, 0x00, 0x00 }; -+ -+ buf_len = pWmtOp->au4OpData[0]; -+ buffer = (PUINT8) pWmtOp->au4OpData[1]; -+ -+ osal_memcpy(&WMT_BGW_DESENSE_CMD[5], buffer, buf_len); -+ -+ do { -+ fgFail = MTK_WCN_BOOL_TRUE; -+ -+ iRet = -+ wmt_core_tx(&WMT_BGW_DESENSE_CMD[0], osal_sizeof(WMT_BGW_DESENSE_CMD), &u4WrittenSize, -+ MTK_WCN_BOOL_FALSE); -+ if (iRet || (u4WrittenSize != osal_sizeof(WMT_BGW_DESENSE_CMD))) { -+ WMT_ERR_FUNC("bgw desense tx CMD fail(%d),size(%d)\n", iRet, u4WrittenSize); -+ break; -+ } -+ -+ iRet = wmt_core_rx(evt_buffer, osal_sizeof(WMT_BGW_DESENSE_EVT), &u4ReadSize); -+ if (iRet || (u4ReadSize != osal_sizeof(WMT_BGW_DESENSE_EVT))) { -+ WMT_ERR_FUNC("bgw desense rx EVT fail(%d),size(%d)\n", iRet, u4ReadSize); -+ break; -+ } -+ -+ if (osal_memcmp(evt_buffer, WMT_BGW_DESENSE_EVT, osal_sizeof(WMT_BGW_DESENSE_EVT)) != 0) { -+ WMT_ERR_FUNC -+ ("bgw desense WMT_BGW_DESENSE_EVT compare fail:0x%02x,0x%02x,0x%02x,0x%02x,0x%02x\n", -+ evt_buffer[0], evt_buffer[1], evt_buffer[2], evt_buffer[3], evt_buffer[4]); -+ break; -+ } -+ -+ fgFail = MTK_WCN_BOOL_FALSE; -+ -+ } while (0); -+ -+ return fgFail; -+} -+ -+static INT32 opfunc_set_mcu_clk(P_WMT_OP pWmtOp) -+{ -+ UINT32 kind = 0; -+ INT32 iRet = -1; -+ UINT32 u4WrittenSize = 0; -+ UINT32 u4ReadSize = 0; -+ UINT8 evt_buffer[12] = { 0 }; -+ MTK_WCN_BOOL fgFail; -+ PUINT8 set_mcu_clk_str[] = { -+ "Enable MCU PLL", -+ "SET MCU CLK to 26M", -+ "SET MCU CLK to 37M", -+ "SET MCU CLK to 64M", -+ "SET MCU CLK to 69M", -+ "SET MCU CLK to 104M", -+ "SET MCU CLK to 118.857M", -+ "SET MCU CLK to 138.67M", -+ "Disable MCU PLL" -+ }; -+ UINT8 WMT_SET_MCU_CLK_CMD[] = { -+ 0x01, 0x08, 0x10, 0x00, -+ 0x01, 0x01, 0x00, 0x01, -+ 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, -+ 0xff, 0xff, 0xff, 0xff -+ }; -+ UINT8 WMT_SET_MCU_CLK_EVT[] = { 0x02, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01 }; -+ -+ UINT8 WMT_EN_MCU_CLK_CMD[] = { 0x34, 0x03, 0x00, 0x80, 0x00, 0x00, 0x01, 0x00 }; /* enable pll clk */ -+ UINT8 WMT_26_MCU_CLK_CMD[] = { 0x0c, 0x01, 0x00, 0x80, 0x00, 0x4d, 0x84, 0x00 }; /* set 26M */ -+ UINT8 WMT_37_MCU_CLK_CMD[] = { 0x0c, 0x01, 0x00, 0x80, 0x1e, 0x4d, 0x84, 0x00 }; /* set 37.8M */ -+ UINT8 WMT_64_MCU_CLK_CMD[] = { 0x0c, 0x01, 0x00, 0x80, 0x1d, 0x4d, 0x84, 0x00 }; /* set 64M */ -+ UINT8 WMT_69_MCU_CLK_CMD[] = { 0x0c, 0x01, 0x00, 0x80, 0x1c, 0x4d, 0x84, 0x00 }; /* set 69M */ -+ UINT8 WMT_104_MCU_CLK_CMD[] = { 0x0c, 0x01, 0x00, 0x80, 0x5b, 0x4d, 0x84, 0x00 }; /* set 104M */ -+ UINT8 WMT_108_MCU_CLK_CMD[] = { 0x0c, 0x01, 0x00, 0x80, 0x5a, 0x4d, 0x84, 0x00 }; /* set 118.857M */ -+ UINT8 WMT_138_MCU_CLK_CMD[] = { 0x0c, 0x01, 0x00, 0x80, 0x59, 0x4d, 0x84, 0x00 }; /* set 138.67M */ -+ UINT8 WMT_DIS_MCU_CLK_CMD[] = { 0x34, 0x03, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00 }; /* disable pll clk */ -+ -+ kind = pWmtOp->au4OpData[0]; -+ WMT_INFO_FUNC("do %s\n", set_mcu_clk_str[kind]); -+ -+ switch (kind) { -+ case 0: -+ osal_memcpy(&WMT_SET_MCU_CLK_CMD[8], &WMT_EN_MCU_CLK_CMD[0], osal_sizeof(WMT_EN_MCU_CLK_CMD)); -+ break; -+ case 1: -+ osal_memcpy(&WMT_SET_MCU_CLK_CMD[8], &WMT_26_MCU_CLK_CMD[0], osal_sizeof(WMT_26_MCU_CLK_CMD)); -+ break; -+ case 2: -+ osal_memcpy(&WMT_SET_MCU_CLK_CMD[8], &WMT_37_MCU_CLK_CMD[0], osal_sizeof(WMT_37_MCU_CLK_CMD)); -+ break; -+ case 3: -+ osal_memcpy(&WMT_SET_MCU_CLK_CMD[8], &WMT_64_MCU_CLK_CMD[0], osal_sizeof(WMT_64_MCU_CLK_CMD)); -+ break; -+ case 4: -+ osal_memcpy(&WMT_SET_MCU_CLK_CMD[8], &WMT_69_MCU_CLK_CMD[0], osal_sizeof(WMT_69_MCU_CLK_CMD)); -+ break; -+ case 5: -+ osal_memcpy(&WMT_SET_MCU_CLK_CMD[8], &WMT_104_MCU_CLK_CMD[0], osal_sizeof(WMT_104_MCU_CLK_CMD)); -+ break; -+ case 6: -+ osal_memcpy(&WMT_SET_MCU_CLK_CMD[8], &WMT_108_MCU_CLK_CMD[0], osal_sizeof(WMT_108_MCU_CLK_CMD)); -+ break; -+ case 7: -+ osal_memcpy(&WMT_SET_MCU_CLK_CMD[8], &WMT_138_MCU_CLK_CMD[0], osal_sizeof(WMT_138_MCU_CLK_CMD)); -+ break; -+ case 8: -+ osal_memcpy(&WMT_SET_MCU_CLK_CMD[8], &WMT_DIS_MCU_CLK_CMD[0], osal_sizeof(WMT_DIS_MCU_CLK_CMD)); -+ break; -+ default: -+ WMT_ERR_FUNC("unknown kind\n"); -+ break; -+ } -+ -+ do { -+ fgFail = MTK_WCN_BOOL_TRUE; -+ -+ iRet = -+ wmt_core_tx(&WMT_SET_MCU_CLK_CMD[0], osal_sizeof(WMT_SET_MCU_CLK_CMD), &u4WrittenSize, -+ MTK_WCN_BOOL_FALSE); -+ if (iRet || (u4WrittenSize != osal_sizeof(WMT_SET_MCU_CLK_CMD))) { -+ WMT_ERR_FUNC("WMT_SET_MCU_CLK_CMD fail(%d),size(%d)\n", iRet, u4WrittenSize); -+ break; -+ } -+ -+ iRet = wmt_core_rx(evt_buffer, osal_sizeof(WMT_SET_MCU_CLK_EVT), &u4ReadSize); -+ if (iRet || (u4ReadSize != osal_sizeof(WMT_SET_MCU_CLK_EVT))) { -+ WMT_ERR_FUNC("WMT_SET_MCU_CLK_EVT fail(%d),size(%d)\n", iRet, u4ReadSize); -+ break; -+ } -+ -+ if (osal_memcmp(evt_buffer, WMT_SET_MCU_CLK_EVT, osal_sizeof(WMT_SET_MCU_CLK_EVT)) != 0) { -+ WMT_ERR_FUNC("WMT_SET_MCU_CLK_EVT compare fail:0x%02x,0x%02x,0x%02x,0x%02x,0x%02x\n", -+ evt_buffer[0], evt_buffer[1], evt_buffer[2], evt_buffer[3], evt_buffer[4], -+ evt_buffer[5], evt_buffer[6], evt_buffer[7]); -+ break; -+ } -+ -+ fgFail = MTK_WCN_BOOL_FALSE; -+ -+ } while (0); -+ -+ if (MTK_WCN_BOOL_FALSE == fgFail) -+ WMT_INFO_FUNC("wmt-core:%s: ok!\n", set_mcu_clk_str[kind]); -+ -+ WMT_INFO_FUNC("wmt-core:%s: fail!\n", set_mcu_clk_str[kind]); -+ -+ return fgFail; -+} -+ -+static INT32 opfunc_adie_lpbk_test(P_WMT_OP pWmtOp) -+{ -+ UINT8 *buffer = NULL; -+ MTK_WCN_BOOL fgFail; -+ UINT32 u4Res; -+ UINT32 aDieChipid = 0; -+ UINT8 soc_adie_chipid_cmd[] = { 0x01, 0x13, 0x04, 0x00, 0x02, 0x04, 0x24, 0x00 }; -+ UINT8 soc_adie_chipid_evt[] = { 0x02, 0x13, 0x09, 0x00, 0x00, 0x02, 0x04, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00 }; -+ UINT8 evtbuf[20]; -+ INT32 iRet = -1; -+ -+ buffer = (PUINT8) pWmtOp->au4OpData[1]; -+ -+ do { -+ fgFail = MTK_WCN_BOOL_TRUE; -+ -+ /* read A die chipid by wmt cmd */ -+ iRet = -+ wmt_core_tx((PUINT8) &soc_adie_chipid_cmd[0], osal_sizeof(soc_adie_chipid_cmd), &u4Res, -+ MTK_WCN_BOOL_FALSE); -+ if (iRet || (u4Res != osal_sizeof(soc_adie_chipid_cmd))) { -+ WMT_ERR_FUNC("wmt_core:read A die chipid CMD fail(%d),size(%d)\n", iRet, u4Res); -+ break; -+ } -+ osal_memset(evtbuf, 0, osal_sizeof(evtbuf)); -+ iRet = wmt_core_rx(evtbuf, osal_sizeof(soc_adie_chipid_evt), &u4Res); -+ if (iRet || (u4Res != osal_sizeof(soc_adie_chipid_evt))) { -+ WMT_ERR_FUNC("wmt_core:read A die chipid EVT fail(%d),size(%d)\n", iRet, u4Res); -+ break; -+ } -+ osal_memcpy(&aDieChipid, &evtbuf[u4Res - 2], 2); -+ osal_memcpy(buffer, &evtbuf[u4Res - 2], 2); -+ pWmtOp->au4OpData[0] = 2; -+ WMT_INFO_FUNC("get SOC A die chipid(0x%x)\n", aDieChipid); -+ -+ fgFail = MTK_WCN_BOOL_FALSE; -+ -+ } while (0); -+ -+ return fgFail; -+} -+ -+#if CFG_WMT_LTE_COEX_HANDLING -+static INT32 opfunc_idc_msg_handling(P_WMT_OP pWmtOp) -+{ -+ MTK_WCN_BOOL fgFail; -+ UINT32 u4Res; -+ UINT8 host_lte_btwf_coex_cmd[] = { 0x01, 0x10, 0x00, 0x00, 0x00 }; -+ UINT8 host_lte_btwf_coex_evt[] = { 0x02, 0x10, 0x01, 0x00, 0x00 }; -+ UINT8 *pTxBuf = NULL; -+ UINT8 evtbuf[8] = { 0 }; -+ INT32 iRet = -1; -+ UINT16 msg_len = 0; -+ UINT32 total_len = 0; -+ UINT32 index = 0; -+ UINT8 *msg_local_buffer = NULL; -+ -+ msg_local_buffer = kmalloc(1300, GFP_KERNEL); -+ if (!msg_local_buffer) { -+ WMT_ERR_FUNC("msg_local_buffer kmalloc memory fail\n"); -+ return 0; -+ } -+ -+ pTxBuf = (UINT8 *) pWmtOp->au4OpData[0]; -+ if (NULL == pTxBuf) { -+ WMT_ERR_FUNC("idc msg buffer is NULL\n"); -+ return -1; -+ } -+ iRet = wmt_lib_idc_lock_aquire(); -+ if (iRet) { -+ WMT_ERR_FUNC("--->lock idc_lock failed, ret=%d\n", iRet); -+ return iRet; -+ } -+ osal_memcpy(&msg_len, &pTxBuf[0], osal_sizeof(msg_len)); -+ if (msg_len > 1200) { -+ wmt_lib_idc_lock_release(); -+ WMT_ERR_FUNC("abnormal idc msg len:%d\n", msg_len); -+ return -2; -+ } -+ msg_len += 1; /*flag byte */ -+ -+ osal_memcpy(&host_lte_btwf_coex_cmd[2], &msg_len, 2); -+ host_lte_btwf_coex_cmd[4] = (pWmtOp->au4OpData[1] & 0x00ff); -+ osal_memcpy(&msg_local_buffer[0], &host_lte_btwf_coex_cmd[0], osal_sizeof(host_lte_btwf_coex_cmd)); -+ osal_memcpy(&msg_local_buffer[osal_sizeof(host_lte_btwf_coex_cmd)], -+ &pTxBuf[osal_sizeof(msg_len)], msg_len - 1); -+ -+ wmt_lib_idc_lock_release(); -+ total_len = osal_sizeof(host_lte_btwf_coex_cmd) + msg_len - 1; -+ -+ WMT_DBG_FUNC("wmt_core:idc msg payload len form lte(%d),wmt msg total len(%d)\n", msg_len - 1, -+ total_len); -+ WMT_DBG_FUNC("wmt_core:idc msg payload:\n"); -+ -+ for (index = 0; index < total_len; index++) -+ WMT_DBG_FUNC("0x%02x ", msg_local_buffer[index]); -+ -+ -+ do { -+ fgFail = MTK_WCN_BOOL_TRUE; -+ -+ /* read A die chipid by wmt cmd */ -+ iRet = wmt_core_tx((PUINT8) &msg_local_buffer[0], total_len, &u4Res, MTK_WCN_BOOL_FALSE); -+ if (iRet || (u4Res != total_len)) { -+ WMT_ERR_FUNC("wmt_core:send lte idc msg to connsys fail(%d),size(%d)\n", iRet, u4Res); -+ break; -+ } -+ osal_memset(evtbuf, 0, osal_sizeof(evtbuf)); -+ iRet = wmt_core_rx(evtbuf, osal_sizeof(host_lte_btwf_coex_evt), &u4Res); -+ if (iRet || (u4Res != osal_sizeof(host_lte_btwf_coex_evt))) { -+ WMT_ERR_FUNC("wmt_core:recv host_lte_btwf_coex_evt fail(%d),size(%d)\n", iRet, u4Res); -+ break; -+ } -+ -+ fgFail = MTK_WCN_BOOL_FALSE; -+ -+ } while (0); -+ kfree(msg_local_buffer); -+ return fgFail; -+} -+#endif -+ -+VOID wmt_core_set_coredump_state(ENUM_DRV_STS state) -+{ -+ WMT_INFO_FUNC("wmt-core: set coredump state(%d)\n", state); -+ gMtkWmtCtx.eDrvStatus[WMTDRV_TYPE_COREDUMP] = state; -+} -+#ifdef CONFIG_MTK_COMBO_ANT -+INT32 opfunc_ant_ram_down(P_WMT_OP pWmtOp) -+{ -+ INT32 iRet = 0; -+ size_t ctrlPa1 = pWmtOp->au4OpData[0]; -+ UINT32 ctrlPa2 = pWmtOp->au4OpData[1]; -+ PUINT8 pbuf = (PUINT8) ctrlPa1; -+ UINT32 fragSeq = 0; -+ UINT16 fragSize = 0; -+ UINT16 wmtCmdLen; -+ UINT16 wmtPktLen; -+ UINT32 u4Res = 0; -+ UINT8 antEvtBuf[osal_sizeof(WMT_ANT_RAM_DWN_EVT)]; -+#if 1 -+ UINT32 ctrlPa3 = pWmtOp->au4OpData[2]; -+ -+ do { -+ fragSize = ctrlPa2; -+ fragSeq = ctrlPa3; -+ gAntBuf[5] = fragSeq; -+ -+ -+ wmtPktLen = fragSize + sizeof(WMT_ANT_RAM_DWN_CMD) + 1; -+ -+ /*WMT command length cal */ -+ wmtCmdLen = wmtPktLen - 4; -+#if 0 -+ WMT_ANT_RAM_DWN_CMD[2] = wmtCmdLen & 0xFF; -+ WMT_ANT_RAM_DWN_CMD[3] = (wmtCmdLen & 0xFF00) >> 16; -+#else -+ osal_memcpy(&WMT_ANT_RAM_DWN_CMD[2], &wmtCmdLen, 2); -+#endif -+ -+ -+ -+ WMT_ANT_RAM_DWN_CMD[4] = 1; /*RAM CODE download */ -+ -+ osal_memcpy(gAntBuf, WMT_ANT_RAM_DWN_CMD, sizeof(WMT_ANT_RAM_DWN_CMD)); -+ -+ /*copy ram code content to global buffer */ -+ osal_memcpy(&gAntBuf[osal_sizeof(WMT_ANT_RAM_DWN_CMD) + 1], pbuf, fragSize); -+ -+ iRet = wmt_core_tx(gAntBuf, wmtPktLen, &u4Res, MTK_WCN_BOOL_FALSE); -+ if (iRet || (u4Res != wmtPktLen)) { -+ WMT_ERR_FUNC("wmt_core: write fragSeq(%d) size(%d, %d) fail(%d)\n", fragSeq, -+ wmtPktLen, u4Res, iRet); -+ iRet = -4; -+ break; -+ } -+ WMT_DBG_FUNC("wmt_core: write fragSeq(%d) size(%d, %d) ok\n", -+ fragSeq, wmtPktLen, u4Res); -+ -+ osal_memset(antEvtBuf, 0, sizeof(antEvtBuf)); -+ -+ WMT_ANT_RAM_DWN_EVT[4] = 0; /*download result; 0 */ -+ -+ iRet = wmt_core_rx(antEvtBuf, sizeof(WMT_ANT_RAM_DWN_EVT), &u4Res); -+ if (iRet || (u4Res != sizeof(WMT_ANT_RAM_DWN_EVT))) { -+ WMT_ERR_FUNC("wmt_core: read WMT_ANT_RAM_DWN_EVT length(%zu, %d) fail(%d)\n", -+ sizeof(WMT_ANT_RAM_DWN_EVT), u4Res, iRet); -+ iRet = -5; -+ break; -+ } -+#if CFG_CHECK_WMT_RESULT -+ if (osal_memcmp(antEvtBuf, WMT_ANT_RAM_DWN_EVT, sizeof(WMT_ANT_RAM_DWN_EVT)) != 0) { -+ WMT_ERR_FUNC("wmt_core: compare WMT_ANT_RAM_DWN_EVT result error\n"); -+ WMT_ERR_FUNC("rx(%d):[%02X,%02X,%02X,%02X,%02X] exp(%zu):[%02X,%02X,%02X,%02X,%02X]\n", -+ u4Res, antEvtBuf[0], antEvtBuf[1], antEvtBuf[2], antEvtBuf[3], -+ antEvtBuf[4], sizeof(WMT_ANT_RAM_DWN_EVT), WMT_ANT_RAM_DWN_EVT[0], -+ WMT_ANT_RAM_DWN_EVT[1], WMT_ANT_RAM_DWN_EVT[2], WMT_ANT_RAM_DWN_EVT[3], -+ WMT_ANT_RAM_DWN_EVT[4]); -+ iRet = -6; -+ break; -+ } -+#endif -+ WMT_DBG_FUNC("wmt_core: read WMT_ANT_RAM_DWN_EVT length(%zu, %d) ok\n", -+ sizeof(WMT_ANT_RAM_DWN_EVT), u4Res); -+ -+ } while (0); -+#else -+ UINT32 patchSize = ctrlPa2; -+ UINT32 patchSizePerFrag = 1000; -+ UINT32 offset; -+ UINT32 fragNum = 0; -+ /*cal patch fragNum */ -+ fragNum = (patchSize + patchSizePerFrag - 1) / patchSizePerFrag; -+ if (2 >= fragNum) { -+ WMT_WARN_FUNC("ANT ramcode size(%d) too short\n", patchSize); -+ return -1; -+ } -+ -+ while (fragSeq < fragNum) { -+ /*update fragNum */ -+ fragSeq++; -+ -+ if (1 == fragSeq) { -+ fragSize = patchSizePerFrag; -+ /*first package */ -+ gAntBuf[5] = 1; /*RAM CODE start */ -+ } else if (fragNum == fragSeq) { -+ /*last package */ -+ fragSize = patchSizePerFrag; -+ gAntBuf[5] = 3; /*RAM CODE end */ -+ } else { -+ /*middle package */ -+ fragSize = patchSize - ((fragNum - 1) * patchSizePerFrag); -+ gAntBuf[5] = 2; /*RAM CODE confinue */ -+ } -+ wmtPktLen = fragSize + sizeof(WMT_ANT_RAM_OP_CMD) + 1; -+ -+ /*WMT command length cal */ -+ wmtCmdLen = wmtPktLen - 4; -+ -+ WMT_ANT_RAM_OP_CMD[2] = wmtCmdLen & 0xFF; -+ WMT_ANT_RAM_OP_CMD[3] = (wmtCmdLen & 0xFF00) >> 16; -+ -+ WMT_ANT_RAM_OP_CMD[4] = 1; /*RAM CODE download */ -+ -+ osal_memcpy(gAntBuf, WMT_ANT_RAM_OP_CMD, sizeof(WMT_ANT_RAM_OP_CMD)); -+ -+ /*copy ram code content to global buffer */ -+ osal_memcpy(&gAntBuf[6], pbuf, fragSize); -+ -+ /*update offset */ -+ offset += fragSize; -+ pbuf += offset; -+ -+ iRet = wmt_core_tx(gAntBuf, wmtPktLen, &u4Res, MTK_WCN_BOOL_FALSE); -+ if (iRet || (u4Res != wmtPktLen)) { -+ WMT_ERR_FUNC("wmt_core: write fragSeq(%d) size(%d, %d) fail(%d)\n", fragSeq, -+ wmtPktLen, u4Res, iRet); -+ iRet = -4; -+ break; -+ } -+ WMT_DBG_FUNC("wmt_core: write fragSeq(%d) size(%d, %d) ok\n", -+ fragSeq, wmtPktLen, u4Res); -+ -+ osal_memset(antEvtBuf, 0, sizeof(antEvtBuf)); -+ -+ WMT_SET_RAM_OP_EVT[4] = 0; /*download result; 0 */ -+ -+ iRet = wmt_core_rx(antEvtBuf, sizeof(WMT_SET_RAM_OP_EVT), &u4Res); -+ if (iRet || (u4Res != sizeof(WMT_SET_RAM_OP_EVT))) { -+ WMT_ERR_FUNC("wmt_core: read WMT_SET_RAM_OP_EVT length(%d, %d) fail(%d)\n", -+ sizeof(WMT_SET_RAM_OP_EVT), u4Res, iRet); -+ iRet = -5; -+ break; -+ } -+#if CFG_CHECK_WMT_RESULT -+ if (osal_memcmp(antEvtBuf, WMT_SET_RAM_OP_EVT, sizeof(WMT_SET_RAM_OP_EVT)) != 0) { -+ WMT_ERR_FUNC("wmt_core: compare WMT_SET_RAM_OP_EVT result error\n"); -+ WMT_ERR_FUNC("rx(%d):[%02X,%02X,%02X,%02X,%02X] exp(%d):[%02X,%02X,%02X,%02X,%02X]\n", -+ u4Res, antEvtBuf[0], antEvtBuf[1], antEvtBuf[2], antEvtBuf[3], -+ antEvtBuf[4], sizeof(WMT_SET_RAM_OP_EVT), WMT_SET_RAM_OP_EVT[0], -+ WMT_SET_RAM_OP_EVT[1], WMT_SET_RAM_OP_EVT[2], WMT_SET_RAM_OP_EVT[3], -+ WMT_SET_RAM_OP_EVT[4]); -+ iRet = -6; -+ break; -+ } -+#endif -+ WMT_DBG_FUNC("wmt_core: read WMT_SET_RAM_OP_EVT length(%d, %d) ok\n", -+ sizeof(WMT_SET_RAM_OP_EVT), u4Res); -+ -+ -+ } -+ if (fragSeq != fragNum) -+ iRet = -7; -+#endif -+ return iRet; -+} -+ -+ -+INT32 opfunc_ant_ram_stat_get(P_WMT_OP pWmtOp) -+{ -+ INT32 iRet = 0; -+ UINT32 u4Res = 0; -+ UINT32 wmtPktLen = osal_sizeof(WMT_ANT_RAM_STA_GET_CMD); -+ UINT32 u4AntRamStatus = 0; -+ UINT8 antEvtBuf[osal_sizeof(WMT_ANT_RAM_STA_GET_EVT)]; -+ -+ -+ iRet = wmt_core_tx(WMT_ANT_RAM_STA_GET_CMD, wmtPktLen, &u4Res, MTK_WCN_BOOL_FALSE); -+ if (iRet || (u4Res != wmtPktLen)) { -+ WMT_ERR_FUNC -+ ("wmt_core: write wmt and ramcode status query command failed, (%d, %d), iRet(%d)\n", -+ wmtPktLen, u4Res, iRet); -+ iRet = -4; -+ return iRet; -+ } -+ -+ -+ iRet = wmt_core_rx(antEvtBuf, sizeof(WMT_ANT_RAM_STA_GET_EVT), &u4Res); -+ if (iRet || (u4Res != sizeof(WMT_ANT_RAM_STA_GET_EVT))) { -+ WMT_ERR_FUNC("wmt_core: read WMT_ANT_RAM_STA_GET_EVT length(%zu, %d) fail(%d)\n", -+ sizeof(WMT_ANT_RAM_STA_GET_EVT), u4Res, iRet); -+ iRet = -5; -+ return iRet; -+ } -+#if CFG_CHECK_WMT_RESULT -+ if (osal_memcmp(antEvtBuf, WMT_ANT_RAM_STA_GET_EVT, sizeof(WMT_ANT_RAM_STA_GET_EVT) - 1) != -+ 0) { -+ WMT_ERR_FUNC("wmt_core: compare WMT_ANT_RAM_STA_GET_EVT result error\n"); -+ WMT_ERR_FUNC("rx(%d):[%02X,%02X,%02X,%02X,%02X] exp(%zu):[%02X,%02X,%02X,%02X,%02X]\n", -+ u4Res, antEvtBuf[0], antEvtBuf[1], antEvtBuf[2], antEvtBuf[3], antEvtBuf[4], -+ sizeof(WMT_ANT_RAM_STA_GET_EVT), WMT_ANT_RAM_STA_GET_EVT[0], -+ WMT_ANT_RAM_STA_GET_EVT[1], WMT_ANT_RAM_STA_GET_EVT[2], -+ WMT_ANT_RAM_STA_GET_EVT[3], WMT_ANT_RAM_STA_GET_EVT[4]); -+ iRet = -6; -+ return iRet; -+ } -+#endif -+ if (0 == iRet) { -+ u4AntRamStatus = antEvtBuf[sizeof(WMT_ANT_RAM_STA_GET_EVT) - 1]; -+ pWmtOp->au4OpData[2] = u4AntRamStatus; -+ WMT_INFO_FUNC("ANT ram code %s\n", -+ 1 == u4AntRamStatus ? "exist already" : "not exist"); -+ } -+ return iRet; -+} -+#endif -+ -+#if CFG_WMT_LTE_COEX_HANDLING -+/*TEST CODE*/ -+static UINT32 g_open_wmt_lte_flag; -+VOID wmt_core_set_flag_for_test(UINT32 enable) -+{ -+ WMT_INFO_FUNC("%s wmt_lte_flag\n", enable ? "enable" : "disable"); -+ g_open_wmt_lte_flag = enable; -+} -+ -+UINT32 wmt_core_get_flag_for_test(VOID) -+{ -+ return g_open_wmt_lte_flag; -+} -+#endif -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_ctrl.c b/drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_ctrl.c -new file mode 100644 -index 000000000000..fa603c208e59 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_ctrl.c -@@ -0,0 +1,1019 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -+ -+/*! \file -+ \brief Declaration of library functions -+ -+ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+#ifdef DFT_TAG -+#undef DFT_TAG -+#endif -+#define DFT_TAG "[WMT-CTRL]" -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "osal_typedef.h" -+#include "osal.h" -+ -+#include "wmt_ctrl.h" -+#include "wmt_core.h" -+#include "wmt_ic.h" -+#include "wmt_lib.h" -+#include "wmt_dev.h" -+#include "wmt_plat.h" -+#include "stp_core.h" -+#include "stp_dbg.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+/* moved to wmt_ctrl.h */ -+/*static INT32 wmt_ctrl_tx_ex (UINT8 *pData, UINT32 size, UINT32 *writtenSize, MTK_WCN_BOOL bRawFlag);*/ -+ -+static INT32 wmt_ctrl_stp_conf_ex(WMT_STP_CONF_TYPE type, UINT32 value); -+ -+static INT32 wmt_ctrl_hw_pwr_off(P_WMT_CTRL_DATA); -+static INT32 wmt_ctrl_hw_pwr_on(P_WMT_CTRL_DATA); -+static INT32 wmt_ctrl_hw_rst(P_WMT_CTRL_DATA); -+static INT32 wmt_ctrl_stp_close(P_WMT_CTRL_DATA); -+static INT32 wmt_ctrl_stp_open(P_WMT_CTRL_DATA); -+static INT32 wmt_ctrl_stp_conf(P_WMT_CTRL_DATA); -+static INT32 wmt_ctrl_free_patch(P_WMT_CTRL_DATA); -+static INT32 wmt_ctrl_get_patch(P_WMT_CTRL_DATA); -+#if 0 -+static INT32 wmt_ctrl_host_baudrate_set(P_WMT_CTRL_DATA); -+static INT32 wmt_ctrl_sdio_hw(P_WMT_CTRL_DATA); -+static INT32 wmt_ctrl_sdio_func(P_WMT_CTRL_DATA); -+#endif -+static INT32 wmt_ctrl_hwidver_set(P_WMT_CTRL_DATA); -+static INT32 wmt_ctrl_stp_rst(P_WMT_CTRL_DATA); -+static INT32 wmt_ctrl_get_wmt_conf(P_WMT_CTRL_DATA); -+static INT32 wmt_ctrl_others(P_WMT_CTRL_DATA); -+static INT32 wmt_ctrl_tx(P_WMT_CTRL_DATA); -+static INT32 wmt_ctrl_rx(P_WMT_CTRL_DATA); -+static INT32 wmt_ctrl_patch_search(P_WMT_CTRL_DATA); -+static INT32 wmt_ctrl_crystal_triming_put(P_WMT_CTRL_DATA pWmtCtrlData); -+static INT32 wmt_ctrl_crystal_triming_get(P_WMT_CTRL_DATA pWmtCtrlData); -+static INT32 wmt_ctrl_hw_state_show(P_WMT_CTRL_DATA pWmtCtrlData); -+static INT32 wmt_ctrl_get_patch_num(P_WMT_CTRL_DATA); -+static INT32 wmt_ctrl_get_patch_info(P_WMT_CTRL_DATA); -+static INT32 wmt_ctrl_soc_paldo_ctrl(P_WMT_CTRL_DATA); -+static INT32 wmt_ctrl_soc_wakeup_consys(P_WMT_CTRL_DATA); -+static INT32 wmt_ctrl_set_stp_dbg_info(P_WMT_CTRL_DATA); -+static INT32 wmt_ctrl_bgw_desense_ctrl(P_WMT_CTRL_DATA); -+static INT32 wmt_ctrl_evt_err_trg_assert(P_WMT_CTRL_DATA); -+static INT32 wmt_ctrl_evt_parser(P_WMT_CTRL_DATA pWmtCtrlData); -+#if CFG_WMT_LTE_COEX_HANDLING -+static INT32 wmt_ctrl_get_tdm_req_antsel(P_WMT_CTRL_DATA); -+#endif -+ -+static INT32 wmt_ctrl_rx_flush(P_WMT_CTRL_DATA); -+ -+static INT32 wmt_ctrl_gps_sync_set(P_WMT_CTRL_DATA pData); -+ -+static INT32 wmt_ctrl_gps_lna_set(P_WMT_CTRL_DATA pData); -+ -+static INT32 wmt_ctrl_get_patch_name(P_WMT_CTRL_DATA pWmtCtrlData); -+ -+/* TODO: [FixMe][GeorgeKuo]: remove unused function */ -+/*static INT32 wmt_ctrl_hwver_get(P_WMT_CTRL_DATA);*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/* GeorgeKuo: Use designated initializers described in -+ * http://gcc.gnu.org/onlinedocs/gcc-4.0.4/gcc/Designated-Inits.html -+ */ -+static const WMT_CTRL_FUNC wmt_ctrl_func[] = { -+ [WMT_CTRL_HW_PWR_OFF] = wmt_ctrl_hw_pwr_off, -+ [WMT_CTRL_HW_PWR_ON] = wmt_ctrl_hw_pwr_on, -+ [WMT_CTRL_HW_RST] = wmt_ctrl_hw_rst, -+ [WMT_CTRL_STP_CLOSE] = wmt_ctrl_stp_close, -+ [WMT_CTRL_STP_OPEN] = wmt_ctrl_stp_open, -+ [WMT_CTRL_STP_CONF] = wmt_ctrl_stp_conf, -+ [WMT_CTRL_FREE_PATCH] = wmt_ctrl_free_patch, -+ [WMT_CTRL_GET_PATCH] = wmt_ctrl_get_patch, -+ [WMT_CTRL_GET_PATCH_NAME] = wmt_ctrl_get_patch_name, -+ [WMT_CTRL_HWIDVER_SET] = wmt_ctrl_hwidver_set, -+ [WMT_CTRL_STP_RST] = wmt_ctrl_stp_rst, -+ [WMT_CTRL_GET_WMT_CONF] = wmt_ctrl_get_wmt_conf, -+ [WMT_CTRL_TX] = wmt_ctrl_tx, -+ [WMT_CTRL_RX] = wmt_ctrl_rx, -+ [WMT_CTRL_RX_FLUSH] = wmt_ctrl_rx_flush, -+ [WMT_CTRL_GPS_SYNC_SET] = wmt_ctrl_gps_sync_set, -+ [WMT_CTRL_GPS_LNA_SET] = wmt_ctrl_gps_lna_set, -+ [WMT_CTRL_PATCH_SEARCH] = wmt_ctrl_patch_search, -+ [WMT_CTRL_CRYSTAL_TRIMING_GET] = wmt_ctrl_crystal_triming_get, -+ [WMT_CTRL_CRYSTAL_TRIMING_PUT] = wmt_ctrl_crystal_triming_put, -+ [WMT_CTRL_HW_STATE_DUMP] = wmt_ctrl_hw_state_show, -+ [WMT_CTRL_GET_PATCH_NUM] = wmt_ctrl_get_patch_num, -+ [WMT_CTRL_GET_PATCH_INFO] = wmt_ctrl_get_patch_info, -+ [WMT_CTRL_SOC_PALDO_CTRL] = wmt_ctrl_soc_paldo_ctrl, -+ [WMT_CTRL_SOC_WAKEUP_CONSYS] = wmt_ctrl_soc_wakeup_consys, -+ [WMT_CTRL_SET_STP_DBG_INFO] = wmt_ctrl_set_stp_dbg_info, -+ [WMT_CTRL_BGW_DESENSE_CTRL] = wmt_ctrl_bgw_desense_ctrl, -+ [WMT_CTRL_EVT_ERR_TRG_ASSERT] = wmt_ctrl_evt_err_trg_assert, -+#if CFG_WMT_LTE_COEX_HANDLING -+ [WMT_CTRL_GET_TDM_REQ_ANTSEL] = wmt_ctrl_get_tdm_req_antsel, -+#endif -+ [WMT_CTRL_EVT_PARSER] = wmt_ctrl_evt_parser, -+ [WMT_CTRL_MAX] = wmt_ctrl_others, -+}; -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+INT32 wmt_ctrl(P_WMT_CTRL_DATA pWmtCtrlData) -+{ -+ UINT32 ctrlId; -+ -+ if (NULL == pWmtCtrlData) { -+ osal_assert(0); -+ return -1; -+ } -+ -+ ctrlId = pWmtCtrlData->ctrlId; -+ /*1sanity check, including wmtCtrlId */ -+ if ((NULL == pWmtCtrlData) -+ || (WMT_CTRL_MAX <= ctrlId)) -+ /* || (ctrlId < WMT_CTRL_HW_PWR_OFF) ) [FixMe][GeorgeKuo]: useless comparison */ -+ { -+ osal_assert(NULL != pWmtCtrlData); -+ osal_assert(WMT_CTRL_MAX > ctrlId); -+ /* osal_assert(ctrlId >= WMT_CTRL_HW_PWR_OFF); [FixMe][GeorgeKuo]: useless comparison */ -+ return -2; -+ } -+ /* TODO: [FixMe][GeorgeKuo] do sanity check to const function table when init and skip checking here */ -+ if (wmt_ctrl_func[ctrlId]) { -+ /*call servicd handling API */ -+ return (*(wmt_ctrl_func[ctrlId])) (pWmtCtrlData); /* serviceHandlerPack[ctrlId].serviceHandler */ -+ } -+ osal_assert(NULL != wmt_ctrl_func[ctrlId]); -+ return -3; -+ -+} -+ -+INT32 wmt_ctrl_tx(P_WMT_CTRL_DATA pWmtCtrlData /*UINT8 *pData, UINT32 size, UINT32 *writtenSize */) -+{ -+ UINT8 *pData = (PUINT8) pWmtCtrlData->au4CtrlData[0]; -+ UINT32 size = pWmtCtrlData->au4CtrlData[1]; -+ PUINT32 writtenSize = (PUINT32) pWmtCtrlData->au4CtrlData[2]; -+ MTK_WCN_BOOL bRawFlag = pWmtCtrlData->au4CtrlData[3]; -+ -+ return wmt_ctrl_tx_ex(pData, size, writtenSize, bRawFlag); -+} -+ -+INT32 wmt_ctrl_rx(P_WMT_CTRL_DATA pWmtCtrlData /*UINT8 *pBuff, UINT32 buffLen, UINT32 *readSize */) -+{ -+ P_DEV_WMT pDev = &gDevWmt; /* single instance */ -+ INT32 readLen; -+ long waitRet = -1; -+ PUINT8 pBuff = (PUINT8) pWmtCtrlData->au4CtrlData[0]; -+ UINT32 buffLen = pWmtCtrlData->au4CtrlData[1]; -+ PUINT32 readSize = (PUINT32) pWmtCtrlData->au4CtrlData[2]; -+ -+ if (readSize) -+ *readSize = 0; -+ -+ /* sanity check */ -+ if (!buffLen) { -+ WMT_WARN_FUNC("buffLen = 0\n"); -+ osal_assert(buffLen); -+ return 0; -+ } -+#if 0 -+ if (!pDev) { -+ WMT_WARN_FUNC("gpDevWmt = NULL\n"); -+ osal_assert(pDev); -+ return -1; -+ } -+#endif -+ -+ if (!osal_test_bit(WMT_STAT_STP_OPEN, &pDev->state)) { -+ WMT_WARN_FUNC("state(0x%lx)\n", pDev->state); -+ osal_assert(osal_test_bit(WMT_STAT_STP_OPEN, &pDev->state)); -+ return -2; -+ } -+ -+ /* sanity ok, proceeding rx operation */ -+ /* read_len = mtk_wcn_stp_receive_data(data, size, WMT_TASK_INDX); */ -+ readLen = mtk_wcn_stp_receive_data(pBuff, buffLen, WMT_TASK_INDX); -+ -+ while (readLen == 0) { /* got nothing, wait for STP's signal */ -+ WMT_LOUD_FUNC("before wmt_dev_rx_timeout\n"); -+ /* iRet = wait_event_interruptible(pdev->rWmtRxWq, osal_test_bit(WMT_STAT_RX, &pdev->state)); */ -+ /* waitRet = wait_event_interruptible_timeout( -+ * pDev->rWmtRxWq, -+ * osal_test_bit(WMT_STAT_RX, &pdev->state), -+ * msecs_to_jiffies(WMT_LIB_RX_TIMEOUT)); -+ */ -+ pDev->rWmtRxWq.timeoutValue = WMT_LIB_RX_TIMEOUT; -+ /* waitRet = osal_wait_for_event_bit_timeout(&pDev->rWmtRxWq, &pDev->state, WMT_STAT_RX); */ -+ waitRet = wmt_dev_rx_timeout(&pDev->rWmtRxWq); -+ -+ WMT_LOUD_FUNC("wmt_dev_rx_timeout returned\n"); -+ -+ if (0 == waitRet) { -+ WMT_ERR_FUNC("wmt_dev_rx_timeout: timeout,jiffies(%lu),timeoutvalue(%d)\n", -+ jiffies, pDev->rWmtRxWq.timeoutValue); -+ return -1; -+ } else if (waitRet < 0) { -+ WMT_WARN_FUNC("wmt_dev_rx_timeout: interrupted by signal (%ld)\n", waitRet); -+ return waitRet; -+ } -+ WMT_DBG_FUNC("wmt_dev_rx_timeout, iRet(%ld)\n", waitRet); -+ /* read_len = mtk_wcn_stp_receive_data(data, size, WMT_TASK_INDX); */ -+ readLen = mtk_wcn_stp_receive_data(pBuff, buffLen, WMT_TASK_INDX); -+ -+ if (0 == readLen) -+ WMT_WARN_FUNC("wmt_ctrl_rx be signaled, but no rx data(%ld)\n", waitRet); -+ -+ } -+ -+ if (readSize) -+ *readSize = readLen; -+ -+ return 0; -+ -+} -+ -+INT32 wmt_ctrl_tx_ex(const PUINT8 pData, const UINT32 size, PUINT32 writtenSize, const MTK_WCN_BOOL bRawFlag) -+{ -+ P_DEV_WMT pDev = &gDevWmt; /* single instance */ -+ INT32 iRet; -+ -+ if (NULL != writtenSize) -+ *writtenSize = 0; -+ -+ /* sanity check */ -+ if (0 == size) { -+ WMT_WARN_FUNC("size to tx is 0\n"); -+ osal_assert(size); -+ return -1; -+ } -+ -+ /* if STP is not enabled yet, can't use this function. Use tx_raw instead */ -+ if (!osal_test_bit(WMT_STAT_STP_OPEN, &pDev->state) || !osal_test_bit(WMT_STAT_STP_EN, &pDev->state)) { -+ WMT_ERR_FUNC("wmt state(0x%lx)\n", pDev->state); -+ osal_assert(osal_test_bit(WMT_STAT_STP_EN, &pDev->state)); -+ osal_assert(osal_test_bit(WMT_STAT_STP_OPEN, &pDev->state)); -+ return -2; -+ } -+ -+ /* sanity ok, proceeding tx operation */ -+ /*retval = mtk_wcn_stp_send_data(data, size, WMTDRV_TYPE_WMT); */ -+ mtk_wcn_stp_flush_rx_queue(WMT_TASK_INDX); -+ if (bRawFlag) -+ iRet = mtk_wcn_stp_send_data_raw(pData, size, WMT_TASK_INDX); -+ else -+ iRet = mtk_wcn_stp_send_data(pData, size, WMT_TASK_INDX); -+ -+ if (iRet != size) { -+ WMT_WARN_FUNC("write(%d) written(%d)\n", size, iRet); -+ osal_assert(iRet == size); -+ } -+ -+ if (writtenSize) -+ *writtenSize = iRet; -+ -+ return 0; -+ -+} -+ -+INT32 wmt_ctrl_rx_flush(P_WMT_CTRL_DATA pWmtCtrlData) -+{ -+ UINT32 type = pWmtCtrlData->au4CtrlData[0]; -+ -+ WMT_INFO_FUNC("flush rx %d queue\n", type); -+ mtk_wcn_stp_flush_rx_queue(type); -+ -+ return 0; -+} -+ -+INT32 wmt_ctrl_hw_pwr_off(P_WMT_CTRL_DATA pWmtCtrlData) -+{ -+ INT32 iret; -+ -+/*psm should be disabled before wmt_ic_deinit*/ -+ P_DEV_WMT pDev = &gDevWmt; -+ -+ if (osal_test_and_clear_bit(WMT_STAT_PWR, &pDev->state)) { -+ WMT_DBG_FUNC("on->off\n"); -+ iret = wmt_plat_pwr_ctrl(FUNC_OFF); -+ } else { -+ WMT_WARN_FUNC("already off\n"); -+ iret = 0; -+ } -+ -+ return iret; -+} -+ -+INT32 wmt_ctrl_hw_pwr_on(P_WMT_CTRL_DATA pWmtCtrlData) -+{ -+ INT32 iret; -+ /*psm should be enabled right after wmt_ic_init */ -+ P_DEV_WMT pDev = &gDevWmt; -+ if (osal_test_and_set_bit(WMT_STAT_PWR, &pDev->state)) { -+ WMT_WARN_FUNC("already on\n"); -+ iret = 0; -+ } else { -+ WMT_DBG_FUNC("off->on\n"); -+ iret = wmt_plat_pwr_ctrl(FUNC_ON); -+ } -+ -+ return iret; -+} -+ -+INT32 wmt_ctrl_ul_cmd(P_DEV_WMT pWmtDev, const UINT8 *pCmdStr) -+{ -+ INT32 waitRet = -1; -+ P_OSAL_SIGNAL pCmdSignal; -+ P_OSAL_EVENT pCmdReq; -+ -+ if (osal_test_and_set_bit(WMT_STAT_CMD, &pWmtDev->state)) { -+ WMT_WARN_FUNC("cmd buf is occupied by (%s)\n", pWmtDev->cCmd); -+ return -1; -+ } -+ -+ /* indicate baud rate change to user space app */ -+#if 0 -+ INIT_COMPLETION(pWmtDev->cmd_comp); -+ pWmtDev->cmd_result = -1; -+ strncpy(pWmtDev->cCmd, pCmdStr, NAME_MAX); -+ pWmtDev->cCmd[NAME_MAX] = '\0'; -+ wake_up_interruptible(&pWmtDev->cmd_wq); -+#endif -+ -+ pCmdSignal = &pWmtDev->cmdResp; -+ osal_signal_init(pCmdSignal); -+ pCmdSignal->timeoutValue = 2000; -+ osal_strncpy(pWmtDev->cCmd, pCmdStr, NAME_MAX); -+ pWmtDev->cCmd[NAME_MAX] = '\0'; -+ -+ pCmdReq = &pWmtDev->cmdReq; -+ -+ osal_trigger_event(&pWmtDev->cmdReq); -+ WMT_DBG_FUNC("str(%s) request ok\n", pCmdStr); -+ -+/* waitRet = wait_for_completion_interruptible_timeout(&pWmtDev->cmd_comp, msecs_to_jiffies(2000)); */ -+ waitRet = osal_wait_for_signal_timeout(pCmdSignal); -+ WMT_LOUD_FUNC("wait signal iRet:%d\n", waitRet); -+ if (0 == waitRet) { -+ WMT_ERR_FUNC("wait signal timeout\n"); -+ return -2; -+ } -+ -+ WMT_DBG_FUNC("str(%s) result(%d)\n", pCmdStr, pWmtDev->cmdResult); -+ -+ return pWmtDev->cmdResult; -+} -+ -+INT32 wmt_ctrl_hw_rst(P_WMT_CTRL_DATA pWmtCtrlData) -+{ -+ wmt_plat_pwr_ctrl(FUNC_RST); -+ return 0; -+} -+ -+INT32 wmt_ctrl_hw_state_show(P_WMT_CTRL_DATA pWmtCtrlData) -+{ -+ wmt_plat_pwr_ctrl(FUNC_STAT); -+ return 0; -+} -+ -+INT32 wmt_ctrl_stp_close(P_WMT_CTRL_DATA pWmtCtrlData) -+{ -+ P_DEV_WMT pDev = &gDevWmt; /* single instance */ -+ INT32 iRet = 0; -+ /* un-register to STP-core for rx */ -+ iRet = mtk_wcn_stp_register_event_cb(WMT_TASK_INDX, NULL); /* mtk_wcn_stp_register_event_cb */ -+ if (iRet) { -+ WMT_WARN_FUNC("stp_reg cb unregister fail(%d)\n", iRet); -+ return -1; -+ } -+ -+ /*un-register rxcb to btif */ -+ iRet = mtk_wcn_stp_rxcb_register(NULL); -+ if (iRet) { -+ WMT_WARN_FUNC("mtk_wcn_stp_rxcb_unregister fail(%d)\n", iRet); -+ return -2; -+ } -+ -+ iRet = mtk_wcn_stp_close_btif(); -+ if (iRet) { -+ WMT_WARN_FUNC("mtk_wcn_stp_close_btif fail(%d)\n", iRet); -+ return -3; -+ } -+ osal_clear_bit(WMT_STAT_STP_OPEN, &pDev->state); -+ -+ return 0; -+} -+ -+INT32 wmt_ctrl_stp_open(P_WMT_CTRL_DATA pWmtCtrlData) -+{ -+ P_DEV_WMT pDev = &gDevWmt; /* single instance */ -+ INT32 iRet; -+ -+ iRet = mtk_wcn_stp_open_btif(); -+ if (iRet) { -+ WMT_WARN_FUNC("mtk_wcn_stp_open_btif fail(%d)\n", iRet); -+ return -1; -+ } -+ -+ /*register stp rx call back to btif */ -+ iRet = mtk_wcn_stp_rxcb_register((MTK_WCN_BTIF_RX_CB) mtk_wcn_stp_parser_data); -+ if (iRet) { -+ WMT_WARN_FUNC("mtk_wcn_stp_rxcb_register fail(%d)\n", iRet); -+ return -2; -+ } -+ /* register to STP-core for rx */ -+ iRet = mtk_wcn_stp_register_event_cb(WMT_TASK_INDX, wmt_dev_rx_event_cb); -+ if (iRet) { -+ WMT_WARN_FUNC("stp_reg cb fail(%d)\n", iRet); -+ return -3; -+ } -+ -+ osal_set_bit(WMT_STAT_STP_OPEN, &pDev->state); -+ -+#if 0 -+ iRet = mtk_wcn_stp_lpbk_ctrl(1); -+#endif -+ -+ return 0; -+} -+ -+INT32 wmt_ctrl_patch_search(P_WMT_CTRL_DATA pWmtCtrlData) -+{ -+ P_DEV_WMT pDev = &gDevWmt; /* single instance */ -+ INT32 iRet; -+ UINT8 cmdStr[NAME_MAX + 1] = { 0 }; -+ -+ osal_snprintf(cmdStr, NAME_MAX, "srh_patch"); -+ iRet = wmt_ctrl_ul_cmd(pDev, cmdStr); -+ if (iRet) { -+ WMT_WARN_FUNC("wmt_ctrl_ul_cmd fail(%d)\n", iRet); -+ return -1; -+ } -+ return 0; -+} -+ -+INT32 wmt_ctrl_get_patch_num(P_WMT_CTRL_DATA pWmtCtrlData) -+{ -+ P_DEV_WMT pDev = &gDevWmt; /* single instance */ -+ -+ pWmtCtrlData->au4CtrlData[0] = pDev->patchNum; -+ return 0; -+} -+ -+INT32 wmt_ctrl_get_patch_info(P_WMT_CTRL_DATA pWmtCtrlData) -+{ -+ P_DEV_WMT pDev = &gDevWmt; /* single instance */ -+ UINT32 downLoadSeq = 0; -+ P_WMT_PATCH_INFO pPatchinfo = NULL; -+ PUINT8 pNbuf = NULL; -+ PUINT8 pAbuf = NULL; -+ -+ downLoadSeq = pWmtCtrlData->au4CtrlData[0]; -+ WMT_DBG_FUNC("download seq is %d\n", downLoadSeq); -+ -+ pPatchinfo = pDev->pWmtPatchInfo + downLoadSeq - 1; -+ pNbuf = (PUINT8) pWmtCtrlData->au4CtrlData[1]; -+ pAbuf = (PUINT8) pWmtCtrlData->au4CtrlData[2]; -+ if (pPatchinfo) { -+ osal_memcpy(pNbuf, pPatchinfo->patchName, osal_sizeof(pPatchinfo->patchName)); -+ osal_memcpy(pAbuf, pPatchinfo->addRess, osal_sizeof(pPatchinfo->addRess)); -+ WMT_DBG_FUNC("get 4 address bytes is 0x%2x,0x%2x,0x%2x,0x%2x", pAbuf[0], pAbuf[1], pAbuf[2], pAbuf[3]); -+ } else { -+ WMT_ERR_FUNC("NULL patchinfo pointer\n"); -+ } -+ -+ return 0; -+} -+ -+INT32 wmt_ctrl_soc_paldo_ctrl(P_WMT_CTRL_DATA pWmtCtrlData) -+{ -+ INT32 iRet = 0; -+ ENUM_PALDO_TYPE ept = pWmtCtrlData->au4CtrlData[0]; -+ ENUM_PALDO_OP epo = pWmtCtrlData->au4CtrlData[1]; -+ -+ WMT_DBG_FUNC("ept(%d),epo(%d)\n", ept, epo); -+ iRet = wmt_plat_soc_paldo_ctrl(ept, epo); -+ if (iRet) { -+ if (PMIC_CHIPID_PALDO == ept) { -+ /* special handling for PMIC CHIPID */ -+ pWmtCtrlData->au4CtrlData[2] = iRet; -+ } else { -+ /* for other PA handling */ -+ WMT_ERR_FUNC("soc palod ctrl fail(%d)\n", iRet); -+ } -+ } -+ -+ return iRet; -+} -+ -+INT32 wmt_ctrl_soc_wakeup_consys(P_WMT_CTRL_DATA pWmtCtrlData) -+{ -+ INT32 iRet = 0; -+ -+ iRet = mtk_wcn_stp_wakeup_consys(); -+ if (iRet) -+ WMT_ERR_FUNC("soc palod ctrl fail(%d)\n", iRet); -+ -+ return iRet; -+} -+ -+INT32 wmt_ctrl_stp_conf_ex(WMT_STP_CONF_TYPE type, UINT32 value) -+{ -+ INT32 iRet = -1; -+ -+ switch (type) { -+ case WMT_STP_CONF_EN: -+ iRet = mtk_wcn_stp_enable(value); -+ break; -+ -+ case WMT_STP_CONF_RDY: -+ iRet = mtk_wcn_stp_ready(value); -+ break; -+ -+ case WMT_STP_CONF_MODE: -+ mtk_wcn_stp_set_mode(value); -+ iRet = 0; -+ break; -+ -+ default: -+ WMT_WARN_FUNC("invalid type(%d) value(%d)\n", type, value); -+ break; -+ } -+ return iRet; -+} -+ -+INT32 wmt_ctrl_stp_conf(P_WMT_CTRL_DATA pWmtCtrlData) -+{ -+ INT32 iRet = -1; -+ P_DEV_WMT pDev = &gDevWmt; /* single instance */ -+ UINT32 type; -+ UINT32 value; -+ -+ if (!osal_test_bit(WMT_STAT_STP_OPEN, &pDev->state)) { -+ WMT_WARN_FUNC("CTRL_STP_ENABLE but invalid Handle of WmtStp\n"); -+ return -1; -+ } -+ -+ type = pWmtCtrlData->au4CtrlData[0]; -+ value = pWmtCtrlData->au4CtrlData[1]; -+ iRet = wmt_ctrl_stp_conf_ex(type, value); -+ -+ if (!iRet) { -+ if (WMT_STP_CONF_EN == type) { -+ if (value) { -+ osal_set_bit(WMT_STAT_STP_EN, &pDev->state); -+ WMT_DBG_FUNC("enable STP\n"); -+ } else { -+ osal_clear_bit(WMT_STAT_STP_EN, &pDev->state); -+ WMT_DBG_FUNC("disable STP\n"); -+ } -+ } -+ } -+ -+ return iRet; -+} -+ -+INT32 wmt_ctrl_free_patch(P_WMT_CTRL_DATA pWmtCtrlData) -+{ -+ UINT32 patchSeq = pWmtCtrlData->au4CtrlData[0]; -+ -+ WMT_DBG_FUNC("BF free patch, gDevWmt.pPatch(0x%08x)\n", gDevWmt.pPatch); -+ if (NULL != gDevWmt.pPatch) -+ wmt_dev_patch_put((osal_firmware **) &(gDevWmt.pPatch)); -+ -+ WMT_DBG_FUNC("AF free patch, gDevWmt.pPatch(0x%08x)\n", gDevWmt.pPatch); -+ if (patchSeq == gDevWmt.patchNum) { -+ WMT_DBG_FUNC("the %d patch has been download\n", patchSeq); -+ wmt_dev_patch_info_free(); -+ } -+ return 0; -+} -+ -+INT32 wmt_ctrl_get_patch_name(P_WMT_CTRL_DATA pWmtCtrlData) -+{ -+ PUINT8 pBuf = (PUINT8) pWmtCtrlData->au4CtrlData[0]; -+ -+ osal_memcpy(pBuf, gDevWmt.cPatchName, osal_sizeof(gDevWmt.cPatchName)); -+ return 0; -+} -+ -+INT32 wmt_ctrl_crystal_triming_put(P_WMT_CTRL_DATA pWmtCtrlData) -+{ -+ WMT_DBG_FUNC("BF free patch, gDevWmt.pPatch(0x%08x)\n", gDevWmt.pPatch); -+ if (NULL != gDevWmt.pNvram) -+ wmt_dev_patch_put((osal_firmware **) &(gDevWmt.pNvram)); -+ -+ WMT_DBG_FUNC("AF free patch, gDevWmt.pNvram(0x%08x)\n", gDevWmt.pNvram); -+ return 0; -+} -+ -+INT32 wmt_ctrl_crystal_triming_get(P_WMT_CTRL_DATA pWmtCtrlData) -+{ -+ INT32 iRet = 0x0; -+ PUINT8 pFileName = (PUINT8) pWmtCtrlData->au4CtrlData[0]; -+ PPUINT8 ppBuf = (PPUINT8) pWmtCtrlData->au4CtrlData[1]; -+ PUINT32 pSize = (PUINT32) pWmtCtrlData->au4CtrlData[2]; -+ -+ osal_firmware *pNvram = NULL; -+ -+ if ((NULL == pFileName) || (NULL == pSize)) { -+ WMT_ERR_FUNC("parameter error, pFileName(0x%08x), pSize(0x%08x)\n", pFileName, pSize); -+ iRet = -1; -+ return iRet; -+ } -+ if (0 == wmt_dev_patch_get(pFileName, &pNvram, 0)) { -+ *ppBuf = (PUINT8) (pNvram)->data; -+ *pSize = (pNvram)->size; -+ gDevWmt.pNvram = pNvram; -+ return 0; -+ } -+ return -1; -+ -+} -+ -+INT32 wmt_ctrl_get_patch(P_WMT_CTRL_DATA pWmtCtrlData) -+{ -+ UINT8 *pFullPatchName = NULL; -+ UINT8 *pDefPatchName = NULL; -+ PUINT8 *ppBuf = (PUINT8 *) pWmtCtrlData->au4CtrlData[2]; -+ PUINT32 pSize = (PUINT32) pWmtCtrlData->au4CtrlData[3]; -+ -+ osal_firmware *pPatch = NULL; -+ -+ pFullPatchName = (PUINT8) pWmtCtrlData->au4CtrlData[1]; -+ WMT_DBG_FUNC("BF get patch, pPatch(0x%08x)\n", pPatch); -+ if ((NULL != pFullPatchName) -+ && (0 == wmt_dev_patch_get(pFullPatchName, &pPatch, BCNT_PATCH_BUF_HEADROOM))) { -+ /*get full name patch success */ -+ WMT_DBG_FUNC("get full patch name(%s) buf(0x%p) size(%d)\n", -+ pFullPatchName, (pPatch)->data, (pPatch)->size); -+ WMT_DBG_FUNC("AF get patch, pPatch(0x%08x)\n", pPatch); -+ *ppBuf = (PUINT8) (pPatch)->data; -+ *pSize = (pPatch)->size; -+ gDevWmt.pPatch = pPatch; -+ return 0; -+ } -+ -+ pDefPatchName = (PUINT8) pWmtCtrlData->au4CtrlData[0]; -+ if ((NULL != pDefPatchName) -+ && (0 == wmt_dev_patch_get(pDefPatchName, &pPatch, BCNT_PATCH_BUF_HEADROOM))) { -+ WMT_DBG_FUNC("get def patch name(%s) buf(0x%p) size(%d)\n", -+ pDefPatchName, (pPatch)->data, (pPatch)->size); -+ WMT_DBG_FUNC("AF get patch, pPatch(0x%08x)\n", pPatch); -+ /*get full name patch success */ -+ *ppBuf = (PUINT8) (pPatch)->data; -+ *pSize = (pPatch)->size; -+ gDevWmt.pPatch = pPatch; -+ return 0; -+ } -+ return -1; -+ -+} -+ -+/*do not need contol uart because B/G/F send/receive data by BTIF*/ -+#if 0 -+INT32 wmt_ctrl_host_baudrate_set(P_WMT_CTRL_DATA pWmtCtrlData) -+{ -+ INT32 iRet = -1; -+ char cmdStr[NAME_MAX + 1] = { 0 }; -+ UINT32 u4Baudrate = pWmtCtrlData->au4CtrlData[0]; -+ UINT32 u4FlowCtrl = pWmtCtrlData->au4CtrlData[1]; -+ -+ WMT_DBG_FUNC("baud(%d), flowctrl(%d)\n", u4Baudrate, u4FlowCtrl); -+ -+ if (osal_test_bit(WMT_STAT_STP_OPEN, &gDevWmt.state)) { -+ osal_snprintf(cmdStr, NAME_MAX, "baud_%d_%d", u4Baudrate, u4FlowCtrl); -+ iRet = wmt_ctrl_ul_cmd(&gDevWmt, cmdStr); -+ if (iRet) { -+ WMT_WARN_FUNC("CTRL_BAUDRATE baud(%d), flowctrl(%d) fail(%d)\n", -+ u4Baudrate, pWmtCtrlData->au4CtrlData[1], iRet); -+ } else { -+ WMT_DBG_FUNC("CTRL_BAUDRATE baud(%d), flowctrl(%d) ok\n", u4Baudrate, u4FlowCtrl); -+ } -+ } else { -+ WMT_INFO_FUNC("CTRL_BAUDRATE but invalid Handle of WmtStp\n"); -+ } -+ return iRet; -+} -+#endif -+/*do not need control SDIO because wifi send/receive data by sdio*/ -+#if 0 -+INT32 wmt_ctrl_sdio_hw(P_WMT_CTRL_DATA pWmtCtrlData) -+{ -+ INT32 iRet = 0; -+ UINT32 statBit = WMT_STAT_SDIO1_ON; -+ P_DEV_WMT pDev = &gDevWmt; /* single instance */ -+ -+ WMT_SDIO_SLOT_NUM sdioSlotNum = pWmtCtrlData->au4CtrlData[0]; -+ ENUM_FUNC_STATE funcState = pWmtCtrlData->au4CtrlData[1]; -+ -+ if ((WMT_SDIO_SLOT_INVALID == sdioSlotNum) -+ || (WMT_SDIO_SLOT_MAX <= sdioSlotNum)) { -+ WMT_WARN_FUNC("CTRL_SDIO_SLOT(%d) but invalid slot num\n", sdioSlotNum); -+ return -1; -+ } -+ -+ WMT_DBG_FUNC("WMT_CTRL_SDIO_HW (0x%x, %d)\n", sdioSlotNum, funcState); -+ -+ if (WMT_SDIO_SLOT_SDIO2 == sdioSlotNum) -+ statBit = WMT_STAT_SDIO2_ON; -+ -+ if (funcState) { -+ if (osal_test_and_set_bit(statBit, &pDev->state)) { -+ WMT_WARN_FUNC("CTRL_SDIO_SLOT slotNum(%d) already ON\n", sdioSlotNum); -+ /* still return 0 */ -+ iRet = 0; -+ } else { -+ iRet = wmt_plat_sdio_ctrl(sdioSlotNum, FUNC_ON); -+ } -+ } else { -+ if (osal_test_and_clear_bit(statBit, &pDev->state)) { -+ iRet = wmt_plat_sdio_ctrl(sdioSlotNum, FUNC_OFF); -+ } else { -+ WMT_WARN_FUNC("CTRL_SDIO_SLOT slotNum(%d) already OFF\n", sdioSlotNum); -+ /* still return 0 */ -+ iRet = 0; -+ } -+ } -+ -+ return iRet; -+} -+ -+INT32 wmt_ctrl_sdio_func(P_WMT_CTRL_DATA pWmtCtrlData) -+{ -+ INT32 iRet = -1; -+ UINT32 statBit = WMT_STAT_SDIO_WIFI_ON; -+ INT32 retry = 10; -+ P_DEV_WMT pDev = &gDevWmt; /* single instance */ -+ WMT_SDIO_FUNC_TYPE sdioFuncType = pWmtCtrlData->au4CtrlData[0]; -+ UINT32 u4On = pWmtCtrlData->au4CtrlData[1]; -+ -+ if (WMT_SDIO_FUNC_MAX <= sdioFuncType) { -+ WMT_ERR_FUNC("CTRL_SDIO_FUNC, invalid func type (%d)\n", sdioFuncType); -+ return -1; -+ } -+ -+ if (WMT_SDIO_FUNC_STP == sdioFuncType) -+ statBit = WMT_STAT_SDIO_STP_ON; -+ -+ if (u4On) { -+ if (osal_test_bit(statBit, &pDev->state)) { -+ WMT_WARN_FUNC("CTRL_SDIO_FUNC(%d) but already ON\n", sdioFuncType); -+ iRet = 0; -+ } else { -+ while (retry-- > 0 && iRet != 0) { -+ if (iRet) { -+ /* sleep 150ms before sdio slot ON ready */ -+ osal_sleep_ms(150); -+ } -+ iRet = mtk_wcn_hif_sdio_wmt_control(sdioFuncType, MTK_WCN_BOOL_TRUE); -+ if (HIF_SDIO_ERR_NOT_PROBED == iRet) { -+ /* not probed case, retry */ -+ continue; -+ } else if (HIF_SDIO_ERR_CLT_NOT_REG == iRet) { -+ /* For WiFi, client not reg yet, no need to retry, -+ *WiFi function can work any time when wlan.ko -+ *is insert into system -+ */ -+ iRet = 0; -+ } else { -+ /* other fail cases, stop */ -+ break; -+ } -+ } -+ if (!retry || iRet) { -+ WMT_ERR_FUNC("mtk_wcn_hif_sdio_wmt_control(%d, TRUE) fail(%d) retry(%d)\n", -+ sdioFuncType, iRet, retry); -+ } else { -+ osal_set_bit(statBit, &pDev->state); -+ } -+ } -+ } else { -+ if (osal_test_bit(statBit, &pDev->state)) { -+ iRet = mtk_wcn_hif_sdio_wmt_control(sdioFuncType, MTK_WCN_BOOL_FALSE); -+ if (iRet) -+ WMT_ERR_FUNC("mtk_wcn_hif_sdio_wmt_control(%d, FALSE) fail(%d)\n", sdioFuncType, iRet); -+ /*any way, set to OFF state */ -+ osal_clear_bit(statBit, &pDev->state); -+ } else { -+ WMT_WARN_FUNC("CTRL_SDIO_FUNC(%d) but already OFF\n", sdioFuncType); -+ iRet = 0; -+ } -+ } -+ -+ return iRet; -+} -+#endif -+ -+ -+INT32 wmt_ctrl_hwidver_set(P_WMT_CTRL_DATA pWmtCtrlData) -+{ -+ P_DEV_WMT pDev = &gDevWmt; /* single instance */ -+ -+ /* input sanity check is done in wmt_ctrl() */ -+ pDev->chip_id = (pWmtCtrlData->au4CtrlData[0] & 0xFFFF0000) >> 16; -+ pDev->hw_ver = pWmtCtrlData->au4CtrlData[0] & 0x0000FFFF; -+ pDev->fw_ver = pWmtCtrlData->au4CtrlData[1] & 0x0000FFFF; -+ -+ /* TODO: [FixMe][GeorgeKuo] remove translated ENUM_WMTHWVER_TYPE_T in the future!!! */ -+ /* Only use hw_ver read from hw. */ -+ pDev->eWmtHwVer = (ENUM_WMTHWVER_TYPE_T) (pWmtCtrlData->au4CtrlData[1] & 0xFFFF0000) >> 16; -+ -+ return 0; -+} -+ -+INT32 wmt_ctrl_set_stp_dbg_info(P_WMT_CTRL_DATA pWmtCtrlData) -+{ -+ UINT8 *pRomVer = NULL; -+ P_WMT_PATCH pPatch = NULL; -+ UINT32 chipID = 0; -+ -+ chipID = pWmtCtrlData->au4CtrlData[0]; -+ pRomVer = (PUINT8) (pWmtCtrlData->au4CtrlData[1]); -+ pPatch = (P_WMT_PATCH) (pWmtCtrlData->au4CtrlData[2]); -+ if (!pRomVer) { -+ WMT_ERR_FUNC("pRomVer null pointer\n"); -+ return -1; -+ } -+ if (!pPatch) { -+ WMT_ERR_FUNC("pPatch null pointer\n"); -+ return -2; -+ } -+ WMT_DBG_FUNC("chipid(0x%x),rom(%s),patch date(%s),patch plat(%s)\n", chipID, pRomVer, pPatch->ucDateTime, -+ pPatch->ucPLat); -+ return stp_dbg_set_version_info(chipID, pRomVer, &(pPatch->ucDateTime[0]), &(pPatch->ucPLat[0])); -+} -+ -+static INT32 wmt_ctrl_bgw_desense_ctrl(P_WMT_CTRL_DATA pWmtCtrlData) -+{ -+ UINT32 cmd = pWmtCtrlData->au4CtrlData[0]; -+ -+ WMT_INFO_FUNC("wmt-ctrl:send native cmd(%d)\n", cmd); -+ wmt_dev_send_cmd_to_daemon(cmd); -+ -+ return 0; -+} -+ -+static INT32 wmt_ctrl_evt_err_trg_assert(P_WMT_CTRL_DATA pWmtCtrlData) -+{ -+ INT32 iRet = -1; -+ -+ ENUM_WMTDRV_TYPE_T drv_type; -+ UINT32 reason = 0; -+ -+ drv_type = pWmtCtrlData->au4CtrlData[0]; -+ reason = pWmtCtrlData->au4CtrlData[1]; -+ WMT_WARN_FUNC("wmt-ctrl:drv_type(%d),reason(%d)\n", drv_type, reason); -+ -+ if (0 == mtk_wcn_stp_get_wmt_evt_err_trg_assert()) { -+ mtk_wcn_stp_set_wmt_evt_err_trg_assert(1); -+ wmt_lib_set_host_assert_info(drv_type, reason, 1); -+ -+ iRet = mtk_wcn_stp_wmt_evt_err_trg_assert(); -+ if (iRet) -+ mtk_wcn_stp_set_wmt_evt_err_trg_assert(0); -+ } else { -+ /* maybe assert triggered by stp noack*/ -+ WMT_INFO_FUNC("do trigger assert & chip reset in stp noack\n"); -+ } -+ return 0; -+} -+ -+#if CFG_WMT_LTE_COEX_HANDLING -+static INT32 wmt_ctrl_get_tdm_req_antsel(P_WMT_CTRL_DATA pWmtCtrlData) -+{ -+ INT32 antsel_index = wmt_plat_get_tdm_antsel_index(); -+ -+ if (0 <= antsel_index) -+ pWmtCtrlData->au4CtrlData[0] = antsel_index; -+ else -+ pWmtCtrlData->au4CtrlData[0] = 0xff; -+ -+ WMT_INFO_FUNC("get tdm req antsel index is %d\n", antsel_index); -+ -+ return 0; -+} -+#endif -+ -+static INT32 wmt_ctrl_evt_parser(P_WMT_CTRL_DATA pWmtCtrlData) -+{ -+ INT32 ret = -1; -+ UINT32 evt_idx = (UINT32) pWmtCtrlData->au4CtrlData[0]; -+ UINT8 *p_buf = NULL; -+ -+ static UINT8 sleep_evt[] = { 0x02, 0x03, 0x02, 0x00, 0x00, 0x01 }; -+ static UINT8 wakeup_evt[] = { 0x02, 0x03, 0x02, 0x00, 0x00, 0x03 }; -+ static UINT8 hostawake_evt[] = { 0x02, 0x03, 0x02, 0x00, 0x00, 0x02 }; -+ static UINT8 *evt_array[] = { sleep_evt, wakeup_evt, hostawake_evt }; -+ -+ p_buf = evt_array[evt_idx - 1]; -+ -+ WMT_INFO_FUNC("evt index:%d,p_buf:%p\n", evt_idx, p_buf); -+ -+ ret = mtk_wcn_consys_stp_btif_parser_wmt_evt(p_buf, 6); -+ if (ret == 1) { -+ WMT_INFO_FUNC("parser wmt evt from BTIF buf is OK\n"); -+ return 0; -+ } -+ WMT_ERR_FUNC("parser wmt evt from BTIF buf fail(%d)\n", ret); -+ return -1; -+} -+ -+static INT32 wmt_ctrl_gps_sync_set(P_WMT_CTRL_DATA pData) -+{ -+ INT32 iret; -+ -+ WMT_INFO_FUNC("ctrl GPS_SYNC(%d)\n", (0 == pData->au4CtrlData[0]) ? PIN_STA_DEINIT : PIN_STA_MUX); -+ iret = wmt_plat_gpio_ctrl(PIN_GPS_SYNC, (0 == pData->au4CtrlData[0]) ? PIN_STA_DEINIT : PIN_STA_MUX); -+ -+ if (iret) { -+ WMT_WARN_FUNC("ctrl GPS_SYNC(%d) fail!(%d) ignore it...\n", -+ (0 == pData->au4CtrlData[0]) ? PIN_STA_DEINIT : PIN_STA_MUX, iret); -+ } -+ -+ return 0; -+} -+ -+static INT32 wmt_ctrl_gps_lna_set(P_WMT_CTRL_DATA pData) -+{ -+ INT32 iret; -+ -+ WMT_INFO_FUNC("ctrl GPS_LNA(%d)\n", (0 == pData->au4CtrlData[0]) ? PIN_STA_DEINIT : PIN_STA_OUT_H); -+ iret = wmt_plat_gpio_ctrl(PIN_GPS_LNA, (0 == pData->au4CtrlData[0]) ? PIN_STA_DEINIT : PIN_STA_OUT_H); -+ -+ if (iret) { -+ WMT_WARN_FUNC("ctrl GPS_SYNC(%d) fail!(%d) ignore it...\n", -+ (0 == pData->au4CtrlData[0]) ? PIN_STA_DEINIT : PIN_STA_OUT_H, iret); -+ } -+ -+ return 0; -+} -+ -+INT32 wmt_ctrl_stp_rst(P_WMT_CTRL_DATA pWmtCtrlData) -+{ -+ return 0; -+} -+ -+INT32 wmt_ctrl_get_wmt_conf(P_WMT_CTRL_DATA pWmtCtrlData) -+{ -+ P_DEV_WMT pDev = &gDevWmt; /* single instance */ -+ -+ pWmtCtrlData->au4CtrlData[0] = (SIZE_T) &pDev->rWmtGenConf; -+ -+ return 0; -+} -+ -+INT32 wmt_ctrl_others(P_WMT_CTRL_DATA pWmtCtrlData) -+{ -+ WMT_ERR_FUNC("wmt_ctrl_others, invalid CTRL ID (%d)\n", pWmtCtrlData->ctrlId); -+ return -1; -+} -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_func.c b/drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_func.c -new file mode 100644 -index 000000000000..d42d572c9292 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_func.c -@@ -0,0 +1,713 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -+ -+/*! \file -+ \brief Declaration of library functions -+ -+ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+#ifdef DFT_TAG -+#undef DFT_TAG -+#endif -+#define DFT_TAG "[WMT-FUNC]" -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "osal_typedef.h" -+ -+#include "wmt_func.h" -+#include "wmt_lib.h" -+#include "wmt_core.h" -+#include "wmt_exp.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+#if CFG_FUNC_BT_SUPPORT -+ -+static INT32 wmt_func_bt_on(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf); -+static INT32 wmt_func_bt_off(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf); -+ -+WMT_FUNC_OPS wmt_func_bt_ops = { -+ /* BT subsystem function on/off */ -+ .func_on = wmt_func_bt_on, -+ .func_off = wmt_func_bt_off -+}; -+#endif -+ -+#if CFG_FUNC_FM_SUPPORT -+ -+static INT32 wmt_func_fm_on(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf); -+static INT32 wmt_func_fm_off(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf); -+ -+WMT_FUNC_OPS wmt_func_fm_ops = { -+ /* FM subsystem function on/off */ -+ .func_on = wmt_func_fm_on, -+ .func_off = wmt_func_fm_off -+}; -+#endif -+ -+#if CFG_FUNC_GPS_SUPPORT -+ -+static INT32 wmt_func_gps_on(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf); -+static INT32 wmt_func_gps_off(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf); -+ -+WMT_FUNC_OPS wmt_func_gps_ops = { -+ /* GPS subsystem function on/off */ -+ .func_on = wmt_func_gps_on, -+ .func_off = wmt_func_gps_off -+}; -+ -+#endif -+ -+#if CFG_FUNC_WIFI_SUPPORT -+static INT32 wmt_func_wifi_on(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf); -+static INT32 wmt_func_wifi_off(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf); -+ -+WMT_FUNC_OPS wmt_func_wifi_ops = { -+ /* Wi-Fi subsystem function on/off */ -+ .func_on = wmt_func_wifi_on, -+ .func_off = wmt_func_wifi_off -+}; -+#endif -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+#if CFG_FUNC_GPS_SUPPORT -+CMB_PIN_CTRL_REG eediPinOhRegs[] = { -+ { -+ /* pull down ctrl register */ -+ .regAddr = 0x80050020, -+ .regValue = ~(0x1 << 5), -+ .regMask = 0x00000020, -+ }, -+ { -+ /* pull up ctrl register */ -+ .regAddr = 0x80050000, -+ .regValue = 0x1 << 5, -+ .regMask = 0x00000020, -+ }, -+ { -+ /* iomode ctrl register */ -+ .regAddr = 0x80050110, -+ .regValue = 0x1 << 0, -+ .regMask = 0x00000007, -+ }, -+ { -+ /* output high/low ctrl register */ -+ .regAddr = 0x80050040, -+ .regValue = 0x1 << 5, -+ .regMask = 0x00000020, -+ } -+ -+}; -+ -+CMB_PIN_CTRL_REG eediPinOlRegs[] = { -+ { -+ .regAddr = 0x80050020, -+ .regValue = 0x1 << 5, -+ .regMask = 0x00000020UL, -+ }, -+ { -+ .regAddr = 0x80050000, -+ .regValue = ~(0x1 << 5), -+ .regMask = 0x00000020, -+ }, -+ { -+ .regAddr = 0x80050110, -+ .regValue = 0x1 << 0, -+ .regMask = 0x00000007, -+ }, -+ { -+ .regAddr = 0x80050040, -+ .regValue = ~(0x1 << 5), -+ .regMask = 0x00000020, -+ } -+}; -+ -+CMB_PIN_CTRL_REG eedoPinOhRegs[] = { -+ { -+ .regAddr = 0x80050020, -+ .regValue = ~(0x1 << 7), -+ .regMask = 0x00000080UL, -+ }, -+ { -+ .regAddr = 0x80050000, -+ .regValue = 0x1 << 7, -+ .regMask = 0x00000080UL, -+ }, -+ { -+ .regAddr = 0x80050110, -+ .regValue = 0x1 << 12, -+ .regMask = 0x00007000UL, -+ }, -+ { -+ .regAddr = 0x80050040, -+ .regValue = 0x1 << 7, -+ .regMask = 0x00000080, -+ } -+}; -+ -+CMB_PIN_CTRL_REG eedoPinOlRegs[] = { -+ { -+ .regAddr = 0x80050020, -+ .regValue = 0x1 << 7, -+ .regMask = 0x00000080, -+ }, -+ { -+ .regAddr = 0x80050000, -+ .regValue = ~(0x1 << 7), -+ .regMask = 0x00000080, -+ }, -+ { -+ .regAddr = 0x80050110, -+ .regValue = 0x1 << 12, -+ .regMask = 0x00007000, -+ }, -+ { -+ .regAddr = 0x80050040, -+ .regValue = ~(0x1 << 7), -+ .regMask = 0x00000080, -+ } -+ -+}; -+ -+CMB_PIN_CTRL_REG gsyncPinOnRegs[] = { -+ { -+ .regAddr = 0x80050110, -+ .regValue = 0x3 << 20, -+ .regMask = 0x7 << 20, -+ } -+ -+}; -+ -+CMB_PIN_CTRL_REG gsyncPinOffRegs[] = { -+ { -+ .regAddr = 0x80050110, -+ .regValue = 0x0 << 20, -+ .regMask = 0x7 << 20, -+ } -+}; -+ -+/* templete usage for GPIO control */ -+CMB_PIN_CTRL gCmbPinCtrl[3] = { -+ { -+ .pinId = CMB_PIN_EEDI_ID, -+ .regNum = 4, -+ .pFuncOnArray = eediPinOhRegs, -+ .pFuncOffArray = eediPinOlRegs, -+ }, -+ { -+ .pinId = CMB_PIN_EEDO_ID, -+ .regNum = 4, -+ .pFuncOnArray = eedoPinOhRegs, -+ .pFuncOffArray = eedoPinOlRegs, -+ }, -+ { -+ .pinId = CMB_PIN_GSYNC_ID, -+ .regNum = 1, -+ .pFuncOnArray = gsyncPinOnRegs, -+ .pFuncOffArray = gsyncPinOffRegs, -+ } -+}; -+#endif -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#if CFG_FUNC_BT_SUPPORT -+ -+INT32 _osal_inline_ wmt_func_bt_ctrl(ENUM_FUNC_STATE funcState) -+{ -+ /*only need to send turn BT subsystem wmt command */ -+ return wmt_core_func_ctrl_cmd(WMTDRV_TYPE_BT, (FUNC_ON == funcState) ? MTK_WCN_BOOL_TRUE : MTK_WCN_BOOL_FALSE); -+} -+ -+INT32 wmt_func_bt_on(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf) -+{ -+ /* return wmt_func_bt_ctrl(FUNC_ON); */ -+ INT32 iRet = -1; -+ unsigned long ctrlPa1; -+ unsigned long ctrlPa2; -+ -+ ctrlPa1 = BT_PALDO; -+ ctrlPa2 = PALDO_ON; -+ iRet = wmt_core_ctrl(WMT_CTRL_SOC_PALDO_CTRL, &ctrlPa1, &ctrlPa2); -+ if (iRet) { -+ WMT_ERR_FUNC("wmt-func: wmt_ctrl_soc_paldo_ctrl failed(%d)(%d)(%d)\n", iRet, ctrlPa1, ctrlPa2); -+ return -1; -+ } -+ iRet = wmt_core_func_ctrl_cmd(WMTDRV_TYPE_BT, MTK_WCN_BOOL_TRUE); -+ if (iRet) { -+ WMT_ERR_FUNC("wmt-func: wmt_core_func_ctrl_cmd(bt_on) failed(%d)\n", iRet); -+ ctrlPa1 = BT_PALDO; -+ ctrlPa2 = PALDO_OFF; -+ wmt_core_ctrl(WMT_CTRL_SOC_PALDO_CTRL, &ctrlPa1, &ctrlPa2); -+ -+ /*do coredump when bt on fail */ -+ wmt_core_set_coredump_state(DRV_STS_FUNC_ON); -+ ctrlPa1 = WMTDRV_TYPE_BT; -+ ctrlPa2 = 32; -+ wmt_core_ctrl(WMT_CTRL_EVT_ERR_TRG_ASSERT, &ctrlPa1, &ctrlPa2); -+ return -2; -+ } -+ osal_set_bit(WMT_BT_ON, &gBtWifiGpsState); -+ if (osal_test_bit(WMT_GPS_ON, &gBtWifiGpsState)) { -+ /* send msg to GPS native for sending de-sense CMD */ -+ ctrlPa1 = 1; -+ ctrlPa2 = 0; -+ wmt_core_ctrl(WMT_CTRL_BGW_DESENSE_CTRL, &ctrlPa1, &ctrlPa2); -+ } -+ return 0; -+} -+ -+INT32 wmt_func_bt_off(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf) -+{ -+ /* return wmt_func_bt_ctrl(FUNC_OFF); */ -+ INT32 iRet1 = -1; -+ INT32 iRet2 = -1; -+ unsigned long ctrlPa1; -+ unsigned long ctrlPa2; -+ -+ iRet1 = wmt_core_func_ctrl_cmd(WMTDRV_TYPE_BT, MTK_WCN_BOOL_FALSE); -+ if (iRet1) -+ WMT_ERR_FUNC("wmt-func: wmt_core_func_ctrl_cmd(bt_off) failed(%d)\n", iRet1); -+ -+ ctrlPa1 = BT_PALDO; -+ ctrlPa2 = PALDO_OFF; -+ iRet2 = wmt_core_ctrl(WMT_CTRL_SOC_PALDO_CTRL, &ctrlPa1, &ctrlPa2); -+ if (iRet2) -+ WMT_ERR_FUNC("wmt-func: wmt_ctrl_soc_paldo_ctrl(bt_off) failed(%d)\n", iRet2); -+ -+ if (iRet1 + iRet2) { -+ /*do coredump when bt off fail */ -+ wmt_core_set_coredump_state(DRV_STS_FUNC_ON); -+ ctrlPa1 = WMTDRV_TYPE_BT; -+ ctrlPa2 = 32; -+ wmt_core_ctrl(WMT_CTRL_EVT_ERR_TRG_ASSERT, &ctrlPa1, &ctrlPa2); -+ return -1; -+ } -+ -+ osal_clear_bit(WMT_BT_ON, &gBtWifiGpsState); -+ if ((!osal_test_bit(WMT_WIFI_ON, &gBtWifiGpsState)) && (osal_test_bit(WMT_GPS_ON, &gBtWifiGpsState))) { -+ /* send msg to GPS native for stopping send de-sense CMD */ -+ ctrlPa1 = 0; -+ ctrlPa2 = 0; -+ wmt_core_ctrl(WMT_CTRL_BGW_DESENSE_CTRL, &ctrlPa1, &ctrlPa2); -+ } -+ return 0; -+} -+ -+#endif -+ -+#if CFG_FUNC_GPS_SUPPORT -+ -+INT32 _osal_inline_ wmt_func_gps_ctrl(ENUM_FUNC_STATE funcState) -+{ -+ /*send turn GPS subsystem wmt command */ -+ return wmt_core_func_ctrl_cmd(WMTDRV_TYPE_GPS, (FUNC_ON == funcState) ? MTK_WCN_BOOL_TRUE : MTK_WCN_BOOL_FALSE); -+} -+ -+INT32 wmt_func_gps_pre_ctrl(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf, ENUM_FUNC_STATE funcStatus) -+{ -+ UINT32 i = 0; -+ INT32 iRet = 0; -+ UINT32 regAddr = 0; -+ UINT32 regValue = 0; -+ UINT32 regMask = 0; -+ UINT32 regNum = 0; -+ P_CMB_PIN_CTRL_REG pReg; -+ P_CMB_PIN_CTRL pCmbPinCtrl = &gCmbPinCtrl[CMB_PIN_GSYNC_ID]; -+ WMT_CTRL_DATA ctrlData; -+ WMT_IC_PIN_ID wmtIcPinId = WMT_IC_PIN_MAX; -+ /* sanity check */ -+ if (FUNC_ON != funcStatus && FUNC_OFF != funcStatus) { -+ WMT_ERR_FUNC("invalid funcStatus(%d)\n", funcStatus); -+ return -1; -+ } -+ /* turn on GPS sync function on both side */ -+ ctrlData.ctrlId = WMT_CTRL_GPS_SYNC_SET; -+ ctrlData.au4CtrlData[0] = (FUNC_ON == funcStatus) ? 1 : 0; -+ iRet = wmt_ctrl(&ctrlData); -+ if (iRet) { -+ /*we suppose this would never print */ -+ WMT_ERR_FUNC("ctrl GPS_SYNC_SET(%d) fail, ret(%d)\n", funcStatus, iRet); -+ /* TODO:[FixMe][George] error handling? */ -+ return -2; -+ } -+ WMT_INFO_FUNC("ctrl GPS_SYNC_SET(%d) ok\n", funcStatus); -+ -+ -+ if ((NULL == pOps->ic_pin_ctrl) || -+ (0 > pOps->ic_pin_ctrl( -+ WMT_IC_PIN_GSYNC, -+ FUNC_ON == funcStatus ? WMT_IC_PIN_MUX : WMT_IC_PIN_GPIO, -+ 1))) { /*WMT_IC_PIN_GSYNC */ -+ pCmbPinCtrl = &gCmbPinCtrl[CMB_PIN_GSYNC_ID]; -+ regNum = pCmbPinCtrl->regNum; -+ for (i = 0; i < regNum; i++) { -+ if (FUNC_ON == funcStatus) -+ pReg = &pCmbPinCtrl->pFuncOnArray[i]; -+ else -+ pReg = &pCmbPinCtrl->pFuncOffArray[i]; -+ -+ regAddr = pReg->regAddr; -+ regValue = pReg->regValue; -+ regMask = pReg->regMask; -+ -+ iRet = wmt_core_reg_rw_raw(1, regAddr, ®Value, regMask); -+ if (iRet) { -+ WMT_ERR_FUNC("set reg for GPS_SYNC function fail(%d)\n", iRet); -+ /* TODO:[FixMe][Chaozhong] error handling? */ -+ return -2; -+ } -+ -+ } -+ } else { -+ WMT_INFO_FUNC("set reg for GPS_SYNC function okay by chip ic_pin_ctrl\n"); -+ } -+ WMT_INFO_FUNC("ctrl combo chip gps sync function succeed\n"); -+ /* turn on GPS lna ctrl function */ -+ if (NULL != pConf) { -+ if (0 == pConf->wmt_gps_lna_enable) { -+ -+ WMT_INFO_FUNC("host pin used for gps lna\n"); -+ /* host LNA ctrl pin needed */ -+ ctrlData.ctrlId = WMT_CTRL_GPS_LNA_SET; -+ ctrlData.au4CtrlData[0] = FUNC_ON == funcStatus ? 1 : 0; -+ iRet = wmt_ctrl(&ctrlData); -+ if (iRet) { -+ /*we suppose this would never print */ -+ WMT_ERR_FUNC("ctrl host GPS_LNA output high fail, ret(%d)\n", iRet); -+ /* TODO:[FixMe][Chaozhong] error handling? */ -+ return -3; -+ } -+ WMT_INFO_FUNC("ctrl host gps lna function succeed\n"); -+ } else { -+ WMT_INFO_FUNC("combo chip pin(%s) used for gps lna\n", -+ 0 == pConf->wmt_gps_lna_pin ? "EEDI" : "EEDO"); -+ wmtIcPinId = 0 == pConf->wmt_gps_lna_pin ? WMT_IC_PIN_EEDI : WMT_IC_PIN_EEDO; -+ if ((NULL == pOps->ic_pin_ctrl) || -+ (0 > pOps->ic_pin_ctrl( -+ wmtIcPinId, -+ FUNC_ON == funcStatus ? WMT_IC_PIN_GPIO_HIGH : WMT_IC_PIN_GPIO_LOW, -+ 1))) { /*WMT_IC_PIN_GSYNC */ -+ if (0 == pConf->wmt_gps_lna_pin) { -+ /* EEDI needed */ -+ pCmbPinCtrl = &gCmbPinCtrl[CMB_PIN_EEDI_ID]; -+ } else if (1 == pConf->wmt_gps_lna_pin) { -+ /* EEDO needed */ -+ pCmbPinCtrl = &gCmbPinCtrl[CMB_PIN_EEDO_ID]; -+ } -+ regNum = pCmbPinCtrl->regNum; -+ for (i = 0; i < regNum; i++) { -+ if (FUNC_ON == funcStatus) -+ pReg = &pCmbPinCtrl->pFuncOnArray[i]; -+ else -+ pReg = &pCmbPinCtrl->pFuncOffArray[i]; -+ regAddr = pReg->regAddr; -+ regValue = pReg->regValue; -+ regMask = pReg->regMask; -+ -+ iRet = wmt_core_reg_rw_raw(1, regAddr, ®Value, regMask); -+ if (iRet) { -+ WMT_ERR_FUNC("set reg for GPS_LNA function fail(%d)\n", iRet); -+ /* TODO:[FixMe][Chaozhong] error handling? */ -+ return -3; -+ } -+ } -+ WMT_INFO_FUNC("ctrl combo chip gps lna succeed\n"); -+ } else { -+ WMT_INFO_FUNC("set reg for GPS_LNA function okay by chip ic_pin_ctrl\n"); -+ } -+ } -+ } -+ return 0; -+ -+} -+ -+INT32 wmt_func_gps_pre_on(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf) -+{ -+ return wmt_func_gps_pre_ctrl(pOps, pConf, FUNC_ON); -+} -+ -+INT32 wmt_func_gps_pre_off(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf) -+{ -+ -+ return wmt_func_gps_pre_ctrl(pOps, pConf, FUNC_OFF); -+} -+ -+INT32 wmt_func_gps_on(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf) -+{ -+ INT32 iRet = 0; -+ unsigned long ctrlPa1; -+ unsigned long ctrlPa2; -+ UINT8 co_clock_type = (pConf->co_clock_flag & 0x0f); -+ -+ if ((co_clock_type) && (0 == pConf->wmt_gps_lna_enable)) { /* use SOC external LNA */ -+ if (!osal_test_bit(WMT_FM_ON, &gGpsFmState)) { -+ ctrlPa1 = GPS_PALDO; -+ ctrlPa2 = PALDO_ON; -+ wmt_core_ctrl(WMT_CTRL_SOC_PALDO_CTRL, &ctrlPa1, &ctrlPa2); -+ } else { -+ WMT_INFO_FUNC("LDO VCN28 has been turn on by FM\n"); -+ } -+ } -+ -+ iRet = wmt_func_gps_pre_on(pOps, pConf); -+ if (0 == iRet) { -+ iRet = wmt_func_gps_ctrl(FUNC_ON); -+ if (!iRet) { -+ osal_set_bit(WMT_GPS_ON, &gBtWifiGpsState); -+ if ((osal_test_bit(WMT_BT_ON, &gBtWifiGpsState)) -+ || (osal_test_bit(WMT_WIFI_ON, &gBtWifiGpsState))) { -+ /* send msg to GPS native for sending de-sense CMD */ -+ ctrlPa1 = 1; -+ ctrlPa2 = 0; -+ wmt_core_ctrl(WMT_CTRL_BGW_DESENSE_CTRL, &ctrlPa1, &ctrlPa2); -+ } -+ -+ if ((co_clock_type) && (0 == pConf->wmt_gps_lna_enable)) /* use SOC external LNA */ -+ osal_set_bit(WMT_GPS_ON, &gGpsFmState); -+ } -+ } -+ return iRet; -+} -+ -+INT32 wmt_func_gps_off(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf) -+{ -+ INT32 iRet = 0; -+ unsigned long ctrlPa1 = 0; -+ unsigned long ctrlPa2 = 0; -+ UINT8 co_clock_type = (pConf->co_clock_flag & 0x0f); -+ -+ iRet = wmt_func_gps_pre_off(pOps, pConf); -+ if (0 == iRet) { -+ iRet = wmt_func_gps_ctrl(FUNC_OFF); -+ if (!iRet) { -+ osal_clear_bit(WMT_GPS_ON, &gBtWifiGpsState); -+ if ((osal_test_bit(WMT_BT_ON, &gBtWifiGpsState)) -+ || (osal_test_bit(WMT_WIFI_ON, &gBtWifiGpsState))) { -+ /* send msg to GPS native for stop sending de-sense CMD */ -+ ctrlPa1 = 0; -+ ctrlPa2 = 0; -+ wmt_core_ctrl(WMT_CTRL_BGW_DESENSE_CTRL, &ctrlPa1, &ctrlPa2); -+ } -+ } -+ } -+ -+ if ((co_clock_type) && (0 == pConf->wmt_gps_lna_enable)) { /* use SOC external LNA */ -+ if (osal_test_bit(WMT_FM_ON, &gGpsFmState)) -+ WMT_INFO_FUNC("FM is still on, do not turn off LDO VCN28\n"); -+ else { -+ ctrlPa1 = GPS_PALDO; -+ ctrlPa2 = PALDO_OFF; -+ wmt_core_ctrl(WMT_CTRL_SOC_PALDO_CTRL, &ctrlPa1, &ctrlPa2); -+ } -+ -+ osal_clear_bit(WMT_GPS_ON, &gGpsFmState); -+ } -+ -+ return iRet; -+ -+} -+#endif -+ -+#if CFG_FUNC_FM_SUPPORT -+ -+INT32 _osal_inline_ wmt_func_fm_ctrl(ENUM_FUNC_STATE funcState) -+{ -+ /*only need to send turn FM subsystem wmt command */ -+ return wmt_core_func_ctrl_cmd(WMTDRV_TYPE_FM, (FUNC_ON == funcState) ? MTK_WCN_BOOL_TRUE : MTK_WCN_BOOL_FALSE); -+} -+ -+INT32 wmt_func_fm_on(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf) -+{ -+ /* return wmt_func_fm_ctrl(FUNC_ON); */ -+ unsigned long ctrlPa1 = 0; -+ unsigned long ctrlPa2 = 0; -+ INT32 iRet = -1; -+ UINT8 co_clock_type = (pConf->co_clock_flag & 0x0f); -+ -+ if (co_clock_type) { -+ if (!osal_test_bit(WMT_GPS_ON, &gGpsFmState)) { -+ ctrlPa1 = FM_PALDO; -+ ctrlPa2 = PALDO_ON; -+ wmt_core_ctrl(WMT_CTRL_SOC_PALDO_CTRL, &ctrlPa1, &ctrlPa2); -+ } else { -+ WMT_INFO_FUNC("LDO VCN28 has been turn on by GPS\n"); -+ } -+ } -+ -+ iRet = wmt_core_func_ctrl_cmd(WMTDRV_TYPE_FM, MTK_WCN_BOOL_TRUE); -+ if (!iRet) { -+ if (co_clock_type) -+ osal_set_bit(WMT_FM_ON, &gGpsFmState); -+ } -+ -+ return iRet; -+} -+ -+INT32 wmt_func_fm_off(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf) -+{ -+ /* return wmt_func_fm_ctrl(FUNC_OFF); */ -+ unsigned long ctrlPa1 = 0; -+ unsigned long ctrlPa2 = 0; -+ INT32 iRet = -1; -+ UINT8 co_clock_type = (pConf->co_clock_flag & 0x0f); -+ -+ iRet = wmt_core_func_ctrl_cmd(WMTDRV_TYPE_FM, MTK_WCN_BOOL_FALSE); -+ -+ if (co_clock_type) { -+ if (osal_test_bit(WMT_GPS_ON, &gGpsFmState)) { -+ WMT_INFO_FUNC("GPS is still on, do not turn off LDO VCN28\n"); -+ } else { -+ ctrlPa1 = FM_PALDO; -+ ctrlPa2 = PALDO_OFF; -+ wmt_core_ctrl(WMT_CTRL_SOC_PALDO_CTRL, &ctrlPa1, &ctrlPa2); -+ } -+ -+ osal_clear_bit(WMT_FM_ON, &gGpsFmState); -+ } -+ -+ return iRet; -+} -+ -+#endif -+ -+#if CFG_FUNC_WIFI_SUPPORT -+ -+/*in soc, wmt turn on wifi directly, no not need operate SDIO*/ -+#if 0 -+INT32 wmt_func_wifi_ctrl(ENUM_FUNC_STATE funcState) -+{ -+ INT32 iRet = 0; -+ unsigned long ctrlPa1 = WMT_SDIO_FUNC_WIFI; -+ unsigned long ctrlPa2 = (FUNC_ON == funcState) ? 1 : 0; /* turn on Wi-Fi driver */ -+ -+ iRet = wmt_core_ctrl(WMT_CTRL_SDIO_FUNC, &ctrlPa1, &ctrlPa2); -+ if (iRet) { -+ WMT_ERR_FUNC("WMT-FUNC: turn on WIFI function fail (%d)", iRet); -+ return -1; -+ } -+ return 0; -+} -+#endif -+ -+INT32 wmt_func_wifi_on(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf) -+{ -+ int iRet = 0; -+ unsigned long ctrlPa1; -+ unsigned long ctrlPa2; -+ -+ if (NULL != mtk_wcn_wlan_probe) { -+ -+ WMT_WARN_FUNC("WMT-FUNC: wmt wlan func on before wlan probe\n"); -+ iRet = (*mtk_wcn_wlan_probe) (); -+ if (iRet) { -+ WMT_ERR_FUNC("WMT-FUNC: wmt call wlan probe fail(%d)\n", iRet); -+ iRet = -1; -+ } else { -+ WMT_WARN_FUNC("WMT-FUNC: wmt call wlan probe ok\n"); -+ } -+ } else { -+ WMT_ERR_FUNC("WMT-FUNC: null pointer mtk_wcn_wlan_probe\n"); -+ gWifiProbed = 1; -+ iRet = -2; -+ } -+ -+ if (!iRet) { -+ osal_set_bit(WMT_WIFI_ON, &gBtWifiGpsState); -+ if (osal_test_bit(WMT_GPS_ON, &gBtWifiGpsState)) { -+ /* send msg to GPS native for sending de-sense CMD */ -+ ctrlPa1 = 1; -+ ctrlPa2 = 0; -+ wmt_core_ctrl(WMT_CTRL_BGW_DESENSE_CTRL, &ctrlPa1, &ctrlPa2); -+ } -+ } -+ return iRet; -+#if 0 -+ return wmt_func_wifi_ctrl(FUNC_ON); -+#endif -+} -+ -+INT32 wmt_func_wifi_off(P_WMT_IC_OPS pOps, P_WMT_GEN_CONF pConf) -+{ -+ int iRet = 0; -+ -+ unsigned long ctrlPa1 = 0; -+ unsigned long ctrlPa2 = 0; -+ -+ if (NULL != mtk_wcn_wlan_remove) { -+ -+ WMT_WARN_FUNC("WMT-FUNC: wmt wlan func on before wlan remove\n"); -+ iRet = (*mtk_wcn_wlan_remove) (); -+ if (iRet) { -+ WMT_ERR_FUNC("WMT-FUNC: wmt call wlan remove fail(%d)\n", iRet); -+ iRet = -1; -+ } else { -+ WMT_WARN_FUNC("WMT-FUNC: wmt call wlan remove ok\n"); -+ } -+ } else { -+ WMT_ERR_FUNC("WMT-FUNC: null pointer mtk_wcn_wlan_remove\n"); -+ iRet = -2; -+ } -+ -+ if (!iRet) { -+ osal_clear_bit(WMT_WIFI_ON, &gBtWifiGpsState); -+ if ((!osal_test_bit(WMT_BT_ON, &gBtWifiGpsState)) && (osal_test_bit(WMT_GPS_ON, &gBtWifiGpsState))) { -+ /* send msg to GPS native for stopping send de-sense CMD */ -+ ctrlPa1 = 0; -+ ctrlPa2 = 0; -+ wmt_core_ctrl(WMT_CTRL_BGW_DESENSE_CTRL, &ctrlPa1, &ctrlPa2); -+ } -+ } -+ return iRet; -+#if 0 -+ return wmt_func_wifi_ctrl(FUNC_OFF); -+#endif -+} -+#endif -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_ic_soc.c b/drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_ic_soc.c -new file mode 100644 -index 000000000000..c07052bce8e6 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_ic_soc.c -@@ -0,0 +1,2452 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -+ -+/*! \file -+ \brief Declaration of library functions -+ -+ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+#ifdef DFT_TAG -+#undef DFT_TAG -+#endif -+#define DFT_TAG "[WMT-IC]" -+#define CFG_IC_SOC 1 -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "osal_typedef.h" -+#include "wmt_ic.h" -+#include "wmt_core.h" -+#include "wmt_lib.h" -+#include "stp_core.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+#define DEFAULT_PATCH_FRAG_SIZE (1000) -+#define WMT_PATCH_FRAG_1ST (0x1) -+#define WMT_PATCH_FRAG_MID (0x2) -+#define WMT_PATCH_FRAG_LAST (0x3) -+ -+#define CFG_CHECK_WMT_RESULT (1) -+/* BT Port 2 Feature. this command does not need -+ * after coex command is downconfirmed by LC, -+ */ -+#define CFG_WMT_BT_PORT2 (0) -+ -+#define CFG_SET_OPT_REG (0) -+#define CFG_WMT_I2S_DBGUART_SUPPORT (0) -+#define CFG_SET_OPT_REG_SWLA (0) -+#define CFG_SET_OPT_REG_MCUCLK (0) -+#define CFG_SET_OPT_REG_MCUIRQ (0) -+ -+#define CFG_SUBSYS_COEX_NEED 0 -+ -+#define CFG_WMT_COREDUMP_ENABLE 0 -+ -+#define CFG_WMT_MULTI_PATCH (1) -+ -+#define CFG_WMT_CRYSTAL_TIMING_SET (0) -+ -+#define CFG_WMT_SDIO_DRIVING_SET (0) -+ -+#define CFG_WMT_UART_HIF_USE (0) -+ -+#define CFG_WMT_WIFI_5G_SUPPORT (1) -+ -+#define CFG_WMT_PATCH_DL_OPTM (1) -+#if CFG_WMT_LTE_COEX_HANDLING -+#define CFG_WMT_FILTER_MODE_SETTING (1) -+#else -+#define CFG_WMT_FILTER_MODE_SETTING (0) -+#endif -+#define MTK_WCN_CMB_MERGE_INTERFACE_SUPPORT (0) -+ -+#define CFG_WMT_POWER_ON_DLM (1) -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+static UINT8 gFullPatchName[NAME_MAX + 1]; -+static const WMT_IC_INFO_S *gp_soc_info; -+static WMT_PATCH gp_soc_patch_info; -+static WMT_CO_CLOCK gCoClockEn = WMT_CO_CLOCK_DIS; -+#if 0 -+static UINT8 WMT_WAKEUP_DIS_GATE_CMD[] = { 0x1, 0x3, 0x01, 0x00, 0x04 }; -+static UINT8 WMT_WAKEUP_DIS_GATE_EVT[] = { 0x2, 0x3, 0x02, 0x0, 0x0, 0x04 }; -+ -+static UINT8 WMT_WAKEUP_EN_GATE_CMD[] = { 0x1, 0x3, 0x01, 0x00, 0x05 }; -+static UINT8 WMT_WAKEUP_EN_GATE_EVT[] = { 0x2, 0x3, 0x02, 0x0, 0x0, 0x05 }; -+#endif -+ -+#if CFG_WMT_UART_HIF_USE -+static UINT8 WMT_QUERY_BAUD_CMD[] = { 0x01, 0x04, 0x01, 0x00, 0x02 }; -+static UINT8 WMT_QUERY_BAUD_EVT_115200[] = { 0x02, 0x04, 0x06, 0x00, 0x00, 0x02, 0x00, 0xC2, 0x01, 0x00 }; -+static UINT8 WMT_QUERY_BAUD_EVT_X[] = { 0x02, 0x04, 0x06, 0x00, 0x00, 0x02, 0xAA, 0xAA, 0xAA, 0xBB }; -+static UINT8 WMT_SET_BAUD_CMD_X[] = { 0x01, 0x04, 0x05, 0x00, 0x01, 0xAA, 0xAA, 0xAA, 0xBB }; -+static UINT8 WMT_SET_BAUD_EVT[] = { 0x02, 0x04, 0x02, 0x00, 0x00, 0x01 }; -+static UINT8 WMT_SET_WAKEUP_WAKE_CMD_RAW[] = { 0xFF }; -+static UINT8 WMT_SET_WAKEUP_WAKE_EVT[] = { 0x02, 0x03, 0x02, 0x00, 0x00, 0x03 }; -+#endif -+static UINT8 WMT_QUERY_STP_CMD[] = { 0x01, 0x04, 0x01, 0x00, 0x04 }; -+static UINT8 WMT_QUERY_STP_EVT_DEFAULT[] = { 0x02, 0x04, 0x06, 0x00, 0x00, 0x04, 0x11, 0x00, 0x00, 0x00 }; -+static UINT8 WMT_QUERY_STP_EVT[] = { 0x02, 0x04, 0x06, 0x00, 0x00, 0x04, 0xDF, 0x0E, 0x68, 0x01 }; -+static UINT8 WMT_PATCH_CMD[] = { 0x01, 0x01, 0x00, 0x00, 0x00 }; -+static UINT8 WMT_PATCH_EVT[] = { 0x02, 0x01, 0x01, 0x00, 0x00 }; -+static UINT8 WMT_RESET_CMD[] = { 0x01, 0x07, 0x01, 0x00, 0x04 }; -+static UINT8 WMT_RESET_EVT[] = { 0x02, 0x07, 0x01, 0x00, 0x00 }; -+ -+#if CFG_WMT_BT_PORT2 -+static UINT8 WMT_BTP2_CMD[] = { 0x01, 0x10, 0x03, 0x00, 0x01, 0x03, 0x01 }; -+static UINT8 WMT_BTP2_EVT[] = { 0x02, 0x10, 0x01, 0x00, 0x00 }; -+#endif -+ -+/*soc patial patch address cmd & evt need firmware owner provide*/ -+#if CFG_WMT_MULTI_PATCH -+static UINT8 WMT_PATCH_ADDRESS_CMD[] = { -+ 0x01, 0x08, 0x10, 0x00, -+ 0x01, 0x01, 0x00, 0x01, -+ 0x3c, 0x02, 0x09, 0x02, -+ 0x00, 0x00, 0x00, 0x00, -+ 0xff, 0xff, 0xff, 0xff -+}; -+static UINT8 WMT_PATCH_ADDRESS_EVT[] = { 0x02, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01 }; -+ -+static UINT8 WMT_PATCH_P_ADDRESS_CMD[] = { -+ 0x01, 0x08, 0x10, 0x00, -+ 0x01, 0x01, 0x00, 0x01, -+ 0xc4, 0x04, 0x09, 0x02, -+ 0x00, 0x3f, 0x00, 0x01, -+ 0xff, 0xff, 0xff, 0xff -+}; -+static UINT8 WMT_PATCH_P_ADDRESS_EVT[] = { 0x02, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01 }; -+#endif -+ -+/*coex cmd/evt++*/ -+static UINT8 WMT_COEX_SETTING_CONFIG_CMD[] = { 0x01, 0x10, 0x02, 0x00, 0x01, 0x00 }; -+static UINT8 WMT_COEX_SETTING_CONFIG_EVT[] = { 0x02, 0x10, 0x01, 0x00, 0x00 }; -+ -+#if CFG_SUBSYS_COEX_NEED -+static UINT8 WMT_BT_COEX_SETTING_CONFIG_CMD[] = { 0x01, 0x10, 0x0B, -+ 0x00, 0x02, -+ 0x00, 0x00, 0x00, 0x00, -+ 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0xAA -+}; -+static UINT8 WMT_BT_COEX_SETTING_CONFIG_EVT[] = { 0x02, 0x10, 0x01, 0x00, 0x00 }; -+ -+static UINT8 WMT_WIFI_COEX_SETTING_CONFIG_CMD[] = { 0x01, 0x10, 0x0C, -+ 0x00, 0x03, -+ 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0xAA -+}; -+static UINT8 WMT_WIFI_COEX_SETTING_CONFIG_EVT[] = { 0x02, 0x10, 0x01, 0x00, 0x00 }; -+ -+static UINT8 WMT_PTA_COEX_SETTING_CONFIG_CMD[] = { 0x01, 0x10, 0x0A, -+ 0x00, 0x04, -+ 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xEE, 0xFF, 0xFF, 0xFE -+}; -+static UINT8 WMT_PTA_COEX_SETTING_CONFIG_EVT[] = { 0x02, 0x10, 0x01, 0x00, 0x00 }; -+ -+static UINT8 WMT_MISC_COEX_SETTING_CONFIG_CMD[] = { 0x01, 0x10, 0x09, -+ 0x00, 0x05, -+ 0xAA, 0xAA, 0xAA, 0xAA, -+ 0xBB, 0xBB, 0xBB, 0xBB -+}; -+static UINT8 WMT_MISC_COEX_SETTING_CONFIG_EVT[] = { 0x02, 0x10, 0x01, 0x00, 0x00 }; -+#endif -+ -+/*coex cmd/evt--*/ -+static UINT8 WMT_SET_STP_CMD[] = { 0x01, 0x04, 0x05, 0x00, 0x03, 0xDF, 0x0E, 0x68, 0x01 }; -+static UINT8 WMT_SET_STP_EVT[] = { 0x02, 0x04, 0x02, 0x00, 0x00, 0x03 }; -+static UINT8 WMT_STRAP_CONF_CMD_FM_COMM[] = { 0x01, 0x05, 0x02, 0x00, 0x02, 0x02 }; -+static UINT8 WMT_STRAP_CONF_EVT[] = { 0x02, 0x05, 0x02, 0x00, 0x00, 0x02 }; -+ -+#if 0 -+static UINT8 WMT_SET_OSC32K_BYPASS_CMD[] = { 0x01, 0x0A, 0x01, 0x00, 0x05 }; -+static UINT8 WMT_SET_OSC32K_BYPASS_EVT[] = { 0x02, 0x0A, 0x01, 0x00, 0x00 }; -+#endif -+ -+#if 0 -+/* to enable dump feature */ -+static UINT8 WMT_CORE_DUMP_EN_CMD[] = { 0x01, 0x0F, 0x02, 0x00, 0x03, 0x01 }; -+static UINT8 WMT_CORE_DUMP_EN_EVT[] = { 0x02, 0x0F, 0x01, 0x00, 0x00 }; -+ -+/* to get system stack dump when f/w assert */ -+static UINT8 WMT_CORE_DUMP_LEVEL_01_CMD[] = { 0x1, 0x0F, 0x07, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; -+static UINT8 WMT_CORE_DUMP_LEVEL_01_EVT[] = { 0x2, 0x0F, 0x01, 0x00, 0x00 }; -+ -+/* to get task and system stack dump when f/w assert */ -+static UINT8 WMT_CORE_DUMP_LEVEL_02_CMD[] = { 0x1, 0x0F, 0x07, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; -+static UINT8 WMT_CORE_DUMP_LEVEL_02_EVT[] = { 0x2, 0x0F, 0x01, 0x00, 0x00 }; -+ -+/* to get bt related memory dump when f/w assert */ -+static UINT8 WMT_CORE_DUMP_LEVEL_03_CMD[] = { 0x1, 0x0F, 0x07, 0x00, 0x03, 0x00, 0x00, 0x09, 0xF0, 0x00, 0x0A }; -+static UINT8 WMT_CORE_DUMP_LEVEL_03_EVT[] = { 0x2, 0x0F, 0x01, 0x00, 0x00 }; -+#endif -+/* to get full dump when f/w assert */ -+static UINT8 WMT_CORE_DUMP_LEVEL_04_CMD[] = { 0x1, 0x0F, 0x07, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; -+static UINT8 WMT_CORE_DUMP_LEVEL_04_EVT[] = { 0x2, 0x0F, 0x01, 0x00, 0x00 }; -+ -+static UINT8 WMT_CORE_CO_CLOCK_CMD[] = { 0x1, 0x0A, 0x02, 0x00, 0x08, 0x03 }; -+static UINT8 WMT_CORE_CO_CLOCK_EVT[] = { 0x2, 0x0A, 0x01, 0x00, 0x00 }; -+ -+static UINT8 WMT_CORE_START_RF_CALIBRATION_CMD[] = { 0x1, 0x14, 0x1, 0x00, 0x01 }; -+static UINT8 WMT_CORE_START_RF_CALIBRATION_EVT[] = { 0x2, 0x14, 0x02, 0x00, 0x00, 0x01 }; -+ -+#if (MTK_WCN_CMB_MERGE_INTERFACE_SUPPORT) -+static UINT8 WMT_SET_I2S_SLAVE_REG_CMD[] = { 0x01, 0x08, 0x10, 0x00 /*length */ -+ , 0x01 /* op: w */ -+ , 0x01 /*type: reg */ -+ , 0x00 /*rev */ -+ , 0x01 /*1 registers */ -+ , 0x78, 0x00, 0x05, 0x80 /*addr:0x80050078 */ -+ , 0x00, 0x00, 0x11, 0x01 /*value:0x11010000 */ -+ , 0x00, 0x00, 0x77, 0x07 /*mask:0x07770000 */ -+}; -+ -+static UINT8 WMT_SET_I2S_SLAVE_REG_EVT[] = { 0x02, 0x08, 0x04, 0x00 /*length */ -+ , 0x00 /*S: 0 */ -+ , 0x00 /*type: reg */ -+ , 0x00 /*rev */ -+ , 0x01 /*1 registers */ -+}; -+ -+static UINT8 WMT_SET_DAI_TO_PAD_REG_CMD[] = { 0x01, 0x08, 0x10, 0x00 /*length */ -+ , 0x01 /* op: w */ -+ , 0x01 /*type: reg */ -+ , 0x00 /*rev */ -+ , 0x01 /*1 registers */ -+ , 0x74, 0x00, 0x05, 0x80 /*addr:0x80050074 */ -+ , 0x44, 0x44, 0x00, 0x00 /*value:0x11010000 */ -+ , 0x77, 0x77, 0x00, 0x00 /*mask:0x07770000 */ -+}; -+ -+static UINT8 WMT_SET_DAI_TO_PAD_REG_EVT[] = { 0x02, 0x08, 0x04, 0x00 /*length */ -+ , 0x00 /*S: 0 */ -+ , 0x00 /*type: reg */ -+ , 0x00 /*rev */ -+ , 0x01 /*1 registers */ -+}; -+ -+static UINT8 WMT_SET_DAI_REG_CMD[] = { 0x01, 0x08, 0x10, 0x00 /*length */ -+ , 0x01 /* op: w */ -+ , 0x01 /*type: reg */ -+ , 0x00 /*rev */ -+ , 0x01 /*1 registers */ -+ , 0xA0, 0x00, 0x05, 0x80 /*addr:0x80050074 */ -+ , 0x04, 0x00, 0x00, 0x00 /*value:0x11010000 */ -+ , 0x04, 0x00, 0x00, 0x00 /*mask:0x07770000 */ -+}; -+ -+static UINT8 WMT_SET_DAI_REG_EVT[] = { 0x02, 0x08, 0x04, 0x00 /*length */ -+ , 0x00 /*S: 0 */ -+ , 0x00 /*type: reg */ -+ , 0x00 /*rev */ -+ , 0x01 /*1 registers */ -+}; -+#endif -+ -+#if !(CFG_IC_SOC) /* For MT6628 no need to set ALLEINT registers, done in f/w */ -+/* enable all interrupt */ -+static UINT8 WMT_SET_ALLINT_REG_CMD[] = { 0x01, 0x08, 0x10, 0x00 /*length */ -+ , 0x01 /* op: w */ -+ , 0x01 /*type: reg */ -+ , 0x00 /*rev */ -+ , 0x01 /*1 registers */ -+ , 0x00, 0x03, 0x05, 0x80 /*addr:0x80050300 */ -+ , 0x00, 0xC4, 0x00, 0x00 /*value:0x0000C400 */ -+ , 0x00, 0xC4, 0x00, 0x00 /*mask:0x0000C400 */ -+}; -+ -+static UINT8 WMT_SET_ALLINT_REG_EVT[] = { 0x02, 0x08, 0x04, 0x00 /*length */ -+ , 0x00 /*S: 0 */ -+ , 0x00 /*type: reg */ -+ , 0x00 /*rev */ -+ , 0x01 /*1 registers */ -+}; -+ -+#endif -+ -+#if CFG_SET_OPT_REG_SWLA /* enable swla: eesk(7) eecs(8) oscen(19) sck0(24) scs0(25) */ -+static UINT8 WMT_SET_SWLA_REG_CMD[] = { 0x01, 0x08, 0x1C, 0x00 /*length */ -+ , 0x01 /* op: w */ -+ , 0x01 /*type: reg */ -+ , 0x00 /*rev */ -+ , 0x02 /*2 registers */ -+ , 0x10, 0x01, 0x05, 0x80 /*addr:0x80050110 */ -+ , 0x10, 0x10, 0x01, 0x00 /*value:0x00011010 */ -+ , 0xF0, 0xF0, 0x0F, 0x00 /*mask:0x000FF0F0 */ -+ , 0x40, 0x01, 0x05, 0x80 /*addr:0x80050140 */ -+ , 0x00, 0x10, 0x01, 0x00 /*value:0x00011000 */ -+ , 0x00, 0xF0, 0x0F, 0x00 /*mask:0x000FF000 */ -+}; -+ -+static UINT8 WMT_SET_SWLA_REG_EVT[] = { 0x02, 0x08, 0x04, 0x00 /*length */ -+ , 0x00 /*S: 0 */ -+ , 0x00 /*type: reg */ -+ , 0x00 /*rev */ -+ , 0x02 /*2 registers */ -+}; -+#endif -+ -+#if CFG_SET_OPT_REG_MCUCLK /* enable mcu clk: antsel_4, eedi */ -+static UINT8 WMT_SET_MCUCLK_REG_CMD[] = { 0x01, 0x08, (4 + 12 * 4), 0x00 /*length */ -+ , 0x01 /* op: w */ -+ , 0x01 /* type: reg */ -+ , 0x00 /* rev */ -+ , 0x04 /* 4 registers */ -+ , 0x00, 0x04, 0x00, 0x80 /* addr:0x8000 0400 */ -+ , 0x00, 0x14, 0x00, 0x00 /* value:0x0000 1400(osc, hclk), 0x0000 1501(PLL, en) */ -+ , 0xFF, 0xFF, 0x00, 0x00 /* mask:0x0000 FFFF */ -+ , 0x80, 0x01, 0x05, 0x80 /* addr:0x8005 0180 */ -+ , 0x12, 0x13, 0x00, 0x00 /* value:0x0000 1312(osc, hclk), 0x0000 1a19(PLL, en) */ -+ , 0xFF, 0xFF, 0x00, 0x00 /* mask:0x0000 FFFF */ -+ , 0x00, 0x01, 0x05, 0x80 /* addr:0x8005 0100 */ -+ , 0x00, 0x00, 0x02, 0x00 /* value:0x0002 0000 */ -+ , 0x00, 0x00, 0x0F, 0x00 /* mask:0x000F 0000 */ -+ , 0x10, 0x01, 0x05, 0x80 /* addr:0x8005 0110 */ -+ , 0x02, 0x00, 0x00, 0x00 /* value:0x0000 0002 */ -+ , 0x0F, 0x00, 0x00, 0x00 /* mask:0x0000 000F */ -+}; -+ -+static UINT8 WMT_SET_MCUCLK_REG_EVT[] = { 0x02, 0x08, 0x04, 0x00 /*length */ -+ , 0x00 /* S: 0 */ -+ , 0x00 /* type: reg */ -+ , 0x00 /* rev */ -+ , 0x04 /* 4 registers */ -+}; -+#endif -+ -+#if CFG_WMT_I2S_DBGUART_SUPPORT /* register write for debug uart */ -+static UINT8 WMT_SET_DBGUART_REG_CMD[] = { 0x01, 0x08, 0x1C, 0x00 /*length */ -+ , 0x01 /* op: w */ -+ , 0x01 /*type: reg */ -+ , 0x00 /*rev */ -+ , 0x02 /*2 registers */ -+ , 0x30, 0x01, 0x05, 0x80 /*addr:0x80050130 */ -+ , 0x00, 0x00, 0x00, 0x00 /*value:0x00000000 */ -+ , 0xF0, 0x0F, 0x00, 0x00 /*mask:0x00000FF0 */ -+ , 0x40, 0x01, 0x05, 0x80 /*addr:0x80050140 */ -+ , 0x00, 0x01, 0x00, 0x00 /*value:0x00000100 */ -+ , 0x00, 0x01, 0x00, 0x00 /*mask:0x00000100 */ -+}; -+ -+static UINT8 WMT_SET_DBGUART_REG_EVT[] = { 0x02, 0x08, 0x04, 0x00 /*length */ -+ , 0x00 /*S: 0 */ -+ , 0x00 /*type: reg */ -+ , 0x00 /*rev */ -+ , 0x02 /*2 registers */ -+}; -+#endif -+ -+#if CFG_SET_OPT_REG_MCUIRQ /* enable mcu irq: antsel_4, wlan_act */ -+#if 1 /* Ray */ -+static UINT8 WMT_SET_MCUIRQ_REG_CMD[] = { 0x01, 0x08, (4 + 12 * 4), 0x00 /*length */ -+ , 0x01 /* op: w */ -+ , 0x01 /* type: reg */ -+ , 0x00 /* rev */ -+ , 0x04 /* 4 registers */ -+ , 0x00, 0x04, 0x00, 0x80 /* addr:0x8000_0400 */ -+ , 0x03, 0x14, 0x00, 0x00 /* value:0x0000_1403 check confg debug flag 3 low word */ -+ , 0xFF, 0xFF, 0x00, 0x00 /* mask:0x0000_FFFF */ -+ /* cirq_int_n */ -+ , 0x10, 0x01, 0x05, 0x80 /* addr:0x8005_0110 */ -+ , 0x02, 0x00, 0x00, 0x00 /* value:0x0000_0002 set EEDI as cirq_int_n debug flag (monitor flag2) */ -+ , 0x07, 0x00, 0x00, 0x00 /* mask:0x0000_0007 */ -+ , 0x00, 0x01, 0x05, 0x80 /* addr:0x8005_0100 */ -+ , 0x00, 0x00, 0x02, 0x00 /* value:0x0002_0000 (ANTSEL4=>monitor flag 0, ahb_x2_gt_ck debug flag) */ -+ , 0x00, 0x00, 0x07, 0x00 /* mask:0x0007_0000 */ -+ /* 1. ARM irq_b, monitor flag 0 */ -+ , 0x80, 0x01, 0x05, 0x80 /* addr:0x8005_0180 */ -+ , 0x1F, 0x1E, 0x00, 0x00 /* value:0x0000_1E1F check mcusys debug flag */ -+ , 0x7F, 0x7F, 0x00, 0x00 /* mask:0x0000_7F7F */ -+}; -+ -+static UINT8 WMT_SET_MCUIRQ_REG_EVT[] = { 0x02, 0x08, 0x04, 0x00 /*length */ -+ , 0x00 /* S: 0 */ -+ , 0x00 /* type: reg */ -+ , 0x00 /* rev */ -+ , 0x04 /* 5 registers */ -+}; -+#elif 0 /* KC */ -+static UINT8 WMT_SET_MCUIRQ_REG_CMD[] = { 0x01, 0x08, (4 + 12 * 5), 0x00 /*length */ -+ , 0x01 /* op: w */ -+ , 0x01 /* type: reg */ -+ , 0x00 /* rev */ -+ , 0x05 /* 5 registers */ -+ , 0x00, 0x04, 0x00, 0x80 /* addr:0x8000_0400 */ -+ , 0x00, 0x02, 0x00, 0x00 /* value:0x0000_0200 [15:8]=0x2 arm irq_b, 0xA irq_bus[5] bt_timcon_irq_b */ -+ , 0x00, 0xFF, 0x00, 0x00 /* mask:0x0000_FF00 */ -+ /* 1. ARM irq_b, monitor flag 0 */ -+ , 0x80, 0x01, 0x05, 0x80 /* addr:0x8005_0180 */ -+ , 0x18, 0x00, 0x00, 0x00 /* value:0x0000_0018 [6:0]=001_1000 (monitor flag 0 select, MCUSYS, SEL:8) */ -+ , 0x7F, 0x00, 0x00, 0x00 /* mask:0x0000_007F */ -+ , 0x00, 0x01, 0x05, 0x80 /* addr:0x8005_0100 */ -+ , 0x00, 0x00, 0x02, 0x00 /* value:0x0002_0000 (ANTSEL4=>monitor flag 0) */ -+ , 0x00, 0x00, 0x07, 0x00 /* mask:0x0007_0000 */ -+ /* 2. irq_bus[5] bt_timcon_irq_b monitor flag 15 */ -+ , 0xB0, 0x01, 0x05, 0x80 /* addr:0x8005_01B0 */ -+ , 0x00, 0x00, 0x00, 0x16 /* value:0x1600_0000 [30:24]=001_0110 (monitor flag 15 select, MCUSYS, SEL:6) */ -+ , 0x00, 0x00, 0x00, 0x7F /* mask:0x7F00_0000 */ -+ , 0x30, 0x01, 0x05, 0x80 /* addr:0x8005_0130 */ -+ , 0x00, 0x20, 0x00, 0x00 /* value:0x0000_2000 (WLAN_ACT=>monitor flag 15) */ -+ , 0x00, 0x70, 0x00, 0x00 /* mask:0x0000_7000 */ -+}; -+ -+static UINT8 WMT_SET_MCUIRQ_REG_EVT[] = { 0x02, 0x08, 0x04, 0x00 /*length */ -+ , 0x00 /* S: 0 */ -+ , 0x00 /* type: reg */ -+ , 0x00 /* rev */ -+ , 0x05 /* 5 registers */ -+}; -+#endif -+#endif -+ -+#if CFG_WMT_CRYSTAL_TIMING_SET -+static UINT8 WMT_SET_CRYSTAL_TRIMING_CMD[] = { 0x01, 0x12, 0x02, 0x00, 0x01, 0x00 }; -+static UINT8 WMT_SET_CRYSTAL_TRIMING_EVT[] = { 0x02, 0x12, 0x02, 0x00, 0x01, 0x00 }; -+ -+static UINT8 WMT_GET_CRYSTAL_TRIMING_CMD[] = { 0x01, 0x12, 0x02, 0x00, 0x00, 0x00 }; -+static UINT8 WMT_GET_CRYSTAL_TRIMING_EVT[] = { 0x02, 0x12, 0x02, 0x00, 0x00, 0x00 }; -+#endif -+ -+#ifdef CFG_WMT_READ_EFUSE_VCN33 -+static UINT8 WMT_GET_EFUSE_VCN33_CMD[] = { 0x01, 0x12, 0x02, 0x00, 0x04, 0x00 }; -+static UINT8 WMT_GET_EFUSE_VCN33_EVT[] = { 0x02, 0x12, 0x02, 0x00, 0x04, 0x00 }; -+#endif -+ -+/* set sdio driving */ -+#if CFG_WMT_SDIO_DRIVING_SET -+static UINT8 WMT_SET_SDIO_DRV_REG_CMD[] = { 0x01, 0x08, 0x10, 0x00 /*length */ -+ , 0x01 /* op: w */ -+ , 0x01 /*type: reg */ -+ , 0x00 /*rev */ -+ , 0x01 /*1 registers */ -+ , 0x50, 0x00, 0x05, 0x80 /*addr:0x80050050 */ -+ , 0x44, 0x44, 0x04, 0x00 /*value:0x00044444 */ -+ , 0x77, 0x77, 0x07, 0x00 /*mask:0x00077777 */ -+}; -+ -+static UINT8 WMT_SET_SDIO_DRV_REG_EVT[] = { 0x02, 0x08, 0x04, 0x00 /*length */ -+ , 0x00 /*S: 0 */ -+ , 0x00 /*type: reg */ -+ , 0x00 /*rev */ -+ , 0x01 /*1 registers */ -+}; -+#endif -+ -+#if CFG_WMT_WIFI_5G_SUPPORT -+static UINT8 WMT_GET_SOC_ADIE_CHIPID_CMD[] = { 0x01, 0x13, 0x04, 0x00, 0x02, 0x04, 0x24, 0x00 }; -+static UINT8 WMT_GET_SOC_ADIE_CHIPID_EVT[] = { -+ 0x02, 0x13, 0x09, 0x00, 0x00, 0x02, 0x04, 0x24, -+ 0x00, 0x00, 0x00, 0x00, 0x00 -+}; -+static UINT8 WMT_GET_SOC_6625_L_CMD[] = { 0x01, 0x13, 0x04, 0x00, 0x02, 0x04, 0x20, 0x01 }; -+static UINT8 WMT_GET_SOC_6625_L_EVT[] = { -+ 0x02, 0x13, 0x09, 0x00, 0x00, 0x02, 0x04, 0x20, -+ 0x01, 0x00, 0x00, 0x00, 0x00 -+}; -+#endif -+ -+#if CFG_WMT_PATCH_DL_OPTM -+static UINT8 WMT_SET_MCU_CLK_EN_CMD[] = { -+ 0x01, 0x08, 0x10, 0x00, -+ 0x01, 0x01, 0x00, 0x01, -+ 0x34, 0x03, 0x00, 0x80, -+ 0x00, 0x00, 0x01, 0x00, -+ 0xff, 0xff, 0xff, 0xff -+}; -+static UINT8 WMT_SET_MCU_CLK_EN_EVT[] = { 0x02, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01 }; -+ -+static UINT8 WMT_SET_MCU_CLK_138_CMD[] = { -+ 0x01, 0x08, 0x10, 0x00, -+ 0x01, 0x01, 0x00, 0x01, -+ 0x0c, 0x01, 0x00, 0x80, -+ 0x59, 0x4d, 0x84, 0x00, -+ 0xff, 0xff, 0xff, 0xff -+}; -+static UINT8 WMT_SET_MCU_CLK_138_EVT[] = { 0x02, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01 }; -+ -+static UINT8 WMT_SET_MCU_CLK_26_CMD[] = { -+ 0x01, 0x08, 0x10, 0x00, -+ 0x01, 0x01, 0x00, 0x01, -+ 0x0c, 0x01, 0x00, 0x80, -+ 0x00, 0x4d, 0x84, 0x00, -+ 0xff, 0xff, 0xff, 0xff -+}; -+static UINT8 WMT_SET_MCU_CLK_26_EVT[] = { 0x02, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01 }; -+ -+static UINT8 WMT_SET_MCU_CLK_DIS_CMD[] = { -+ 0x01, 0x08, 0x10, 0x00, -+ 0x01, 0x01, 0x00, 0x01, -+ 0x34, 0x03, 0x00, 0x80, -+ 0x00, 0x00, 0x00, 0x00, -+ 0xff, 0xff, 0xff, 0xff -+}; -+static UINT8 WMT_SET_MCU_CLK_DIS_EVT[] = { 0x02, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01 }; -+ -+/*only for 6797,enable high clock frequency*/ -+/*CLK EN*/ -+static UINT8 WMT_SET_MCU_CLK_EN_6797[] = { -+ 0x01, 0x08, 0x10, 0x00, 0x01, 0x01, 0x00, 0x01, -+ 0x10, 0x11, 0x02, 0x81, 0x00, 0x00, 0x00, 0x10, -+ 0x00, 0x00, 0x00, 0x10 -+}; -+/*RATIO SET*/ -+static UINT8 WMT_SET_MCU_RATIO_SET_6797[] = { -+ 0x01, 0x08, 0x10, 0x00, 0x01, 0x01, 0x00, 0x01, -+ 0x0c, 0x01, 0x00, 0x80, 0x40, 0x00, 0x00, 0x00, -+ 0xc0, 0x00, 0x00, 0x00 -+}; -+/*DIV SET*/ -+static UINT8 WMT_SET_MCU_DIV_SET_6797[] = { -+ 0x01, 0x08, 0x10, 0x00, 0x01, 0x01, 0x00, 0x01, -+ 0x18, 0x11, 0x02, 0x80, 0x07, 0x00, 0x00, 0x00, -+ 0x3f, 0x00, 0x00, 0x00 -+}; -+/*HCLK SET*/ -+static UINT8 WMT_SET_MCU_HCLK_SET_6797[] = { -+ 0x01, 0x08, 0x10, 0x00, 0x01, 0x01, 0x00, 0x01, -+ 0x00, 0x11, 0x02, 0x81, 0x04, 0x00, 0x00, 0x00, -+ 0x07, 0x00, 0x00, 0x00 -+}; -+ -+/*Change clock to 26MHz*/ -+/*HCLK DIS*/ -+static UINT8 WMT_SET_MCU_HCLK_DIS_6797[] = { -+ 0x01, 0x08, 0x10, 0x00, 0x01, 0x01, 0x00, 0x01, -+ 0x00, 0x11, 0x02, 0x81, 0x00, 0x00, 0x00, 0x00, -+ 0x07, 0x00, 0x00, 0x00 -+}; -+/*RATIO DIS*/ -+static UINT8 WMT_SET_MCU_RATIO_DIS_6797[] = { -+ 0x01, 0x08, 0x10, 0x00, 0x01, 0x01, 0x00, 0x01, -+ 0x0c, 0x01, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, -+ 0xc0, 0x00, 0x00, 0x00 -+}; -+/*CLK DIS*/ -+static UINT8 WMT_SET_MCU_CLK_DIS_6797[] = { -+ 0x01, 0x08, 0x10, 0x00, 0x01, 0x01, 0x00, 0x01, -+ 0x10, 0x11, 0x02, 0x81, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x10 -+}; -+ -+static UINT8 WMT_SET_MCU_CLK_EVT_6797[] = { -+ 0x02, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01 -+}; -+ -+#endif -+ -+#if CFG_WMT_FILTER_MODE_SETTING -+static UINT8 WMT_COEX_EXT_COMPONENT_CMD[] = {0x01, 0x10, 0x03, 0x00, 0x0d, 0x00, 0x00}; -+static UINT8 WMT_COEX_FILTER_SPEC_CMD_TEST[] = { -+ 0x01, 0x10, 0x45, 0x00, 0x11, 0x00, 0x00, 0x01, -+ 0x00, 0x11, 0x11, 0x16, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x63, 0x63, 0x63, 0x00, 0x39, 0x43, 0x63, -+ 0x63, 0x02, 0x02, 0x03, 0x00, 0x01, 0x01, 0x01, -+ 0x01, 0x0e, 0x0e, 0x0e, 0x00, 0x0a, 0x0c, 0x0e, -+ 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; -+static UINT8 WMT_COEX_LTE_FREQ_IDX_TABLE_CMD[] = { -+ 0x01, 0x10, 0x21, 0x00, 0x12, 0xfc, 0x08, 0x15, -+ 0x09, 0x2e, 0x09, 0x47, 0x09, 0xc4, 0x09, 0xd4, -+ 0x09, 0xe3, 0x09, 0x5a, 0x0a, 0x14, 0x09, 0x2d, -+ 0x09, 0x46, 0x09, 0x60, 0x09, 0xd3, 0x09, 0xe2, -+ 0x09, 0x59, 0x0a, 0x8B, 0x0a}; -+static UINT8 WMT_COEX_LTE_CHAN_UNSAFE_CMD[] = { 0x01, 0x10, 0x02, 0x00, 0x13, 0x00 }; -+static UINT8 WMT_COEX_IS_LTE_L_CMD[] = { 0x01, 0x10, 0x02, 0x00, 0x21, 0x01 }; -+ -+#if 0 -+static UINT8 WMT_COEX_SPLIT_FILTER_CMD_TEST[] = { -+ 0x01, 0x10, 0x19, 0x00, 0x0F, 0x00, 0x00, 0x00, -+ 0x00, 0x6c, 0x09, 0x8a, 0x09, 0x8a, 0x09, 0x9e, -+ 0x09, 0x01, 0x07, 0x07, 0x0b, 0x07, 0x07, 0x00, -+ 0x32, 0x27, 0x4e, 0x27, 0x32 -+}; -+ -+static UINT8 WMT_COEX_FILTER_SPEC_CMD_TEST[] = { -+ 0x01, 0x10, 0x45, 0x00, 0x11, 0x00, 0x00, 0x01, -+ 0x00, 0x07, 0x07, 0x07, 0x54, 0x54, 0x00, 0x00, -+ 0x00, 0x50, 0x50, 0x50, 0x54, 0x54, 0x39, 0x39, -+ 0x39, 0x02, 0x02, 0x02, 0x0e, 0x0e, 0x01, 0x01, -+ 0x01, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0a, 0x0a, -+ 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00 -+}; -+ -+static UINT8 WMT_COEX_LTE_FREQ_IDX_TABLE_CMD_TEST[] = { -+ 0x01, 0x10, 0x21, 0x00, 0x12, 0xfc, 0x08, 0x15, -+ 0x09, 0x2e, 0x09, 0x47, 0x09, 0xc4, 0x09, 0xdd, -+ 0x09, 0xf6, 0x09, 0x0f, 0xaf, 0x14, 0x09, 0x2d, -+ 0x09, 0x46, 0x09, 0x5f, 0x09, 0xdd, 0x09, 0xf5, -+ 0x09, 0x0d, 0x0a, 0x27, 0x0a -+}; -+static UINT8 WMT_COEX_LTE_CHAN_UNSAFE_CMD_TEST[] = { 0x01, 0x10, 0x02, 0x00, 0x13, 0x00 }; -+static UINT8 WMT_COEX_EXT_COMPONENT_CMD_TEST[] = { 0x01, 0x10, 0x03, 0x00, 0x0d, 0x7f, 0x03 }; -+#endif -+ -+static UINT8 WMT_COEX_FILTER_SPEC_CMD_0[] = { -+ 0x01, 0x10, 0x45, 0x00, 0x11, 0x00, 0x00, 0x01, -+ 0x00, 0x16, 0x16, 0x16, 0x16, 0x00, 0x00, 0x00, -+ 0x00, 0x63, 0x63, 0x63, 0x63, 0x3c, 0x3c, 0x3c, -+ 0x3c, 0x04, 0x04, 0x04, 0x04, 0x01, 0x01, 0x01, -+ 0x01, 0x0e, 0x0e, 0x0e, 0x0e, 0x0b, 0x0b, 0x0b, -+ 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00 -+}; -+ -+static UINT8 WMT_COEX_LTE_FREQ_IDX_TABLE_CMD_0[] = { -+ 0x01, 0x10, 0x21, 0x00, 0x12, 0xfc, 0x08, 0x15, -+ 0x09, 0x2e, 0x09, 0x47, 0x09, 0xc4, 0x09, 0xdd, -+ 0x09, 0xf6, 0x09, 0x0f, 0x0a, 0x14, 0x09, 0x2d, -+ 0x09, 0x46, 0x09, 0x5f, 0x09, 0xdd, 0x09, 0xf5, -+ 0x09, 0x0d, 0x0a, 0x27, 0x0a -+}; -+static UINT8 WMT_COEX_TDM_REQ_ANTSEL_NUM_CMD[] = { 0x01, 0x10, 0x02, 0x00, 0x14, 0x00 }; -+static UINT8 WMT_COEX_IS_LTE_PROJ_CMD[] = { 0x01, 0x10, 0x02, 0x00, 0x15, 0x01 }; -+static UINT8 WMT_COEX_SPLIT_MODE_EVT[] = { 0x02, 0x10, 0x01, 0x00, 0x00 }; -+ -+static UINT8 WMT_COEX_FILTER_SPEC_CMD_6752[] = { -+ 0x01, 0x10, 0x45, 0x00, 0x11, 0x00, 0x00, 0x01, -+ 0x00, 0x11, 0x11, 0x16, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x63, 0x63, 0x63, 0x00, 0x39, 0x43, 0x63, -+ 0x63, 0x02, 0x02, 0x03, 0x00, 0x01, 0x01, 0x01, -+ 0x01, 0x0E, 0x0E, 0x0E, 0x00, 0x0A, 0x0C, 0x0E, -+ 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00 -+}; -+ -+static UINT8 WMT_COEX_LTE_FREQ_IDX_TABLE_CMD_6752[] = { -+ 0x01, 0x10, 0x21, 0x00, 0x12, 0xFC, 0x08, 0x15, -+ 0x09, 0x2E, 0x09, 0x47, 0x09, 0xC4, 0x09, 0xD4, -+ 0x09, 0xE3, 0x09, 0x5A, 0x0A, 0x14, 0x09, 0x2D, -+ 0x09, 0x46, 0x09, 0x60, 0x09, 0xD3, 0x09, 0xE2, -+ 0x09, 0x59, 0x0A, 0x8B, 0x0A -+}; -+#endif -+ -+#if CFG_WMT_POWER_ON_DLM -+static UINT8 WMT_POWER_CTRL_DLM_CMD1[] = { -+ 0x01, 0x08, 0x10, 0x00, -+ 0x01, 0x01, 0x00, 0x01, -+ 0x60, 0x00, 0x10, 0x80, -+ 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x0f, 0x00, 0x00 -+}; -+ -+static UINT8 WMT_POWER_CTRL_DLM_CMD2[] = { -+ 0x01, 0x08, 0x10, 0x00, -+ 0x01, 0x01, 0x00, 0x01, -+ 0x60, 0x00, 0x10, 0x80, -+ 0x00, 0x00, 0x00, 0x00, -+ 0xf0, 0x00, 0x00, 0x00 -+}; -+ -+static UINT8 WMT_POWER_CTRL_DLM_CMD3[] = { -+ 0x01, 0x08, 0x10, 0x00, -+ 0x01, 0x01, 0x00, 0x01, -+ 0x60, 0x00, 0x10, 0x80, -+ 0x00, 0x00, 0x00, 0x00, -+ 0x08, 0x00, 0x00, 0x00 -+}; -+static UINT8 WMT_POWER_CTRL_DLM_EVT[] = { 0x02, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01 }; -+#endif -+ -+#if (!CFG_IC_SOC) -+ -+/* stp sdio init scripts */ -+static struct init_script init_table_1_1[] = { -+ /* table_1_1 is only applied to common SDIO interface */ -+ INIT_CMD(WMT_SET_ALLINT_REG_CMD, WMT_SET_ALLINT_REG_EVT, "enable all interrupt"), -+ /* applied to MT6628 ? */ -+ INIT_CMD(WMT_WAKEUP_DIS_GATE_CMD, WMT_WAKEUP_DIS_GATE_EVT, "disable gating"), -+}; -+ -+#endif -+ -+static struct init_script init_table_1_2[] = { -+ INIT_CMD(WMT_QUERY_STP_CMD, WMT_QUERY_STP_EVT_DEFAULT, "query stp default"), -+}; -+ -+#if CFG_WMT_UART_HIF_USE -+static struct init_script init_table_2[] = { -+ INIT_CMD(WMT_QUERY_BAUD_CMD, WMT_QUERY_BAUD_EVT_X, "query baud X"), -+}; -+#endif -+ -+static struct init_script init_table_3[] = { -+ INIT_CMD(WMT_RESET_CMD, WMT_RESET_EVT, "wmt reset"), -+#if CFG_WMT_BT_PORT2 -+ INIT_CMD(WMT_BTP2_CMD, WMT_BTP2_EVT, "set bt port2"), -+#endif -+}; -+ -+#if CFG_WMT_CRYSTAL_TIMING_SET -+static struct init_script set_crystal_timing_script[] = { -+ INIT_CMD(WMT_SET_CRYSTAL_TRIMING_CMD, WMT_SET_CRYSTAL_TRIMING_EVT, "set crystal trim value"), -+}; -+ -+static struct init_script get_crystal_timing_script[] = { -+ INIT_CMD(WMT_GET_CRYSTAL_TRIMING_CMD, WMT_GET_CRYSTAL_TRIMING_EVT, "get crystal trim value"), -+}; -+#endif -+#ifdef CFG_WMT_READ_EFUSE_VCN33 -+static struct init_script get_efuse_vcn33_script[] = { -+ INIT_CMD(WMT_GET_EFUSE_VCN33_CMD, WMT_GET_EFUSE_VCN33_EVT, "get efuse vcn33 value"), -+}; -+#endif -+ -+static struct init_script init_table_4[] = { -+ INIT_CMD(WMT_SET_STP_CMD, WMT_SET_STP_EVT, "set stp"), -+}; -+ -+static struct init_script init_table_5[] = { -+ INIT_CMD(WMT_QUERY_STP_CMD, WMT_QUERY_STP_EVT, "query stp"), -+}; -+ -+static struct init_script init_table_5_1[] = { -+ INIT_CMD(WMT_STRAP_CONF_CMD_FM_COMM, WMT_STRAP_CONF_EVT, "configure FM comm"), -+}; -+ -+static struct init_script init_table_6[] = { -+ INIT_CMD(WMT_CORE_DUMP_LEVEL_04_CMD, WMT_CORE_DUMP_LEVEL_04_EVT, "setup core dump level"), -+}; -+ -+static struct init_script calibration_table[] = { -+ INIT_CMD(WMT_CORE_START_RF_CALIBRATION_CMD, WMT_CORE_START_RF_CALIBRATION_EVT, "start RF calibration data"), -+}; -+ -+#if CFG_WMT_PATCH_DL_OPTM -+static struct init_script set_mcuclk_table_1[] = { -+ INIT_CMD(WMT_SET_MCU_CLK_EN_CMD, WMT_SET_MCU_CLK_EN_EVT, "enable set mcu clk"), -+ INIT_CMD(WMT_SET_MCU_CLK_138_CMD, WMT_SET_MCU_CLK_138_EVT, "set mcu clk to 138.67MH"), -+}; -+ -+static struct init_script set_mcuclk_table_2[] = { -+ INIT_CMD(WMT_SET_MCU_CLK_26_CMD, WMT_SET_MCU_CLK_26_EVT, "set mcu clk to 26MH"), -+ INIT_CMD(WMT_SET_MCU_CLK_DIS_CMD, WMT_SET_MCU_CLK_DIS_EVT, "disable set mcu clk"), -+}; -+ -+static struct init_script set_mcuclk_table_3[] = { -+ INIT_CMD(WMT_SET_MCU_CLK_EN_6797, WMT_SET_MCU_CLK_EVT_6797, "enable set mcu clk"), -+ INIT_CMD(WMT_SET_MCU_RATIO_SET_6797, WMT_SET_MCU_CLK_EVT_6797, "mcu ratio set"), -+ INIT_CMD(WMT_SET_MCU_DIV_SET_6797, WMT_SET_MCU_CLK_EVT_6797, "mcu div set"), -+ INIT_CMD(WMT_SET_MCU_HCLK_SET_6797, WMT_SET_MCU_CLK_EVT_6797, "set mcu clk to hclk"), -+}; -+static struct init_script set_mcuclk_table_4[] = { -+ INIT_CMD(WMT_SET_MCU_HCLK_DIS_6797, WMT_SET_MCU_CLK_EVT_6797, "disable mcu hclk"), -+ INIT_CMD(WMT_SET_MCU_RATIO_DIS_6797, WMT_SET_MCU_CLK_EVT_6797, "disable mcu ratio set"), -+ INIT_CMD(WMT_SET_MCU_CLK_DIS_6797, WMT_SET_MCU_CLK_EVT_6797, "disable mcu clk set"), -+}; -+ -+#endif -+ -+#if CFG_WMT_FILTER_MODE_SETTING -+static struct init_script set_wifi_lte_coex_table_1[] = { -+ INIT_CMD(WMT_COEX_FILTER_SPEC_CMD_6752, WMT_COEX_SPLIT_MODE_EVT, "wifi lte coex filter spec"), -+ INIT_CMD(WMT_COEX_LTE_FREQ_IDX_TABLE_CMD_6752, WMT_COEX_SPLIT_MODE_EVT, "wifi lte freq idx"), -+ INIT_CMD(WMT_COEX_IS_LTE_PROJ_CMD, WMT_COEX_SPLIT_MODE_EVT, "set LTE project"), -+}; -+ -+static struct init_script set_wifi_lte_coex_table_2[] = { -+ INIT_CMD(WMT_COEX_EXT_COMPONENT_CMD, WMT_COEX_SPLIT_MODE_EVT, "wifi lte ext component"), -+ INIT_CMD(WMT_COEX_FILTER_SPEC_CMD_TEST, WMT_COEX_SPLIT_MODE_EVT, "wifi lte coex filter"), -+ INIT_CMD(WMT_COEX_LTE_FREQ_IDX_TABLE_CMD, WMT_COEX_SPLIT_MODE_EVT, "wifi lte freq id table"), -+ INIT_CMD(WMT_COEX_LTE_CHAN_UNSAFE_CMD, WMT_COEX_SPLIT_MODE_EVT, "wifi lte unsafe channel"), -+ INIT_CMD(WMT_COEX_IS_LTE_L_CMD, WMT_COEX_SPLIT_MODE_EVT, "wifi coex is L branch"), -+}; -+ -+static struct init_script set_wifi_lte_coex_table_0[] = { -+#if 0 -+ INIT_CMD(WMT_COEX_SPLIT_FILTER_CMD_TEST, WMT_COEX_SPLIT_MODE_EVT, "wifi lte coex split filter"), -+ INIT_CMD(WMT_COEX_FILTER_SPEC_CMD_TEST, WMT_COEX_SPLIT_MODE_EVT, "wifi lte coex filter spec"), -+ INIT_CMD(WMT_COEX_LTE_FREQ_IDX_TABLE_CMD_TEST, WMT_COEX_SPLIT_MODE_EVT, "wifi lte freq idx"), -+ INIT_CMD(WMT_COEX_LTE_CHAN_UNSAFE_CMD_TEST, WMT_COEX_SPLIT_MODE_EVT, "wifi lte channel unsafe"), -+ INIT_CMD(WMT_COEX_EXT_COMPONENT_CMD_TEST, WMT_COEX_SPLIT_MODE_EVT, "wifi coex ext component"), -+#endif -+ INIT_CMD(WMT_COEX_FILTER_SPEC_CMD_0, WMT_COEX_SPLIT_MODE_EVT, "def wifi lte coex filter spec"), -+ INIT_CMD(WMT_COEX_LTE_FREQ_IDX_TABLE_CMD_0, WMT_COEX_SPLIT_MODE_EVT, "def wifi lte freq idx"), -+}; -+ -+static struct init_script get_tdm_req_antsel_num_table[] = { -+ INIT_CMD(WMT_COEX_TDM_REQ_ANTSEL_NUM_CMD, WMT_COEX_SPLIT_MODE_EVT, "get tdm req antsel num"), -+}; -+#endif -+ -+#if CFG_SET_OPT_REG -+static struct init_script set_registers[] = { -+ /* INIT_CMD(WMT_SET_GPS_REG_CMD, WMT_SET_GPS_REG_EVT, "set wmt registers"), */ -+ /* INIT_CMD(WMT_SET_SDIODRV_REG_CMD, WMT_SET_SDIODRV_REG_EVT, "set SDIO driving registers") */ -+#if CFG_WMT_I2S_DBGUART_SUPPORT -+ INIT_CMD(WMT_SET_DBGUART_REG_CMD, WMT_SET_DBGUART_REG_EVT, "set debug uart registers"), -+#endif -+#if CFG_SET_OPT_REG_SWLA -+ INIT_CMD(WMT_SET_SWLA_REG_CMD, WMT_SET_SWLA_REG_EVT, "set swla registers"), -+#endif -+#if CFG_SET_OPT_REG_MCUCLK -+ INIT_CMD(WMT_SET_MCUCLK_REG_CMD, WMT_SET_MCUCLK_REG_EVT, "set mcuclk dbg registers"), -+#endif -+#if CFG_SET_OPT_REG_MCUIRQ -+ INIT_CMD(WMT_SET_MCUIRQ_REG_CMD, WMT_SET_MCUIRQ_REG_EVT, "set mcu irq dbg registers"), -+#endif -+}; -+#endif -+ -+static struct init_script coex_table[] = { -+ INIT_CMD(WMT_COEX_SETTING_CONFIG_CMD, WMT_COEX_SETTING_CONFIG_EVT, "coex_wmt"), -+ -+#if CFG_SUBSYS_COEX_NEED -+/* no need in MT6628 */ -+ INIT_CMD(WMT_BT_COEX_SETTING_CONFIG_CMD, WMT_BT_COEX_SETTING_CONFIG_EVT, "coex_bt"), -+ INIT_CMD(WMT_WIFI_COEX_SETTING_CONFIG_CMD, WMT_WIFI_COEX_SETTING_CONFIG_EVT, "coex_wifi"), -+ INIT_CMD(WMT_PTA_COEX_SETTING_CONFIG_CMD, WMT_PTA_COEX_SETTING_CONFIG_EVT, "coex_ext_pta"), -+ INIT_CMD(WMT_MISC_COEX_SETTING_CONFIG_CMD, WMT_MISC_COEX_SETTING_CONFIG_EVT, "coex_misc"), -+#endif -+}; -+ -+static struct init_script osc_type_table[] = { -+ INIT_CMD(WMT_CORE_CO_CLOCK_CMD, WMT_CORE_CO_CLOCK_EVT, "osc_type"), -+}; -+ -+#if (MTK_WCN_CMB_MERGE_INTERFACE_SUPPORT) -+static struct init_script merge_pcm_table[] = { -+ INIT_CMD(WMT_SET_I2S_SLAVE_REG_CMD, WMT_SET_I2S_SLAVE_REG_EVT, "I2S_Slave"), -+ INIT_CMD(WMT_SET_DAI_TO_PAD_REG_CMD, WMT_SET_DAI_TO_PAD_REG_EVT, "DAI_PAD"), -+ INIT_CMD(WMT_SET_DAI_REG_CMD, WMT_SET_DAI_REG_EVT, "DAI_EVT"), -+}; -+#endif -+ -+#if CFG_WMT_SDIO_DRIVING_SET -+static struct init_script sdio_driving_table[] = { -+ INIT_CMD(WMT_SET_SDIO_DRV_REG_CMD, WMT_SET_SDIO_DRV_REG_EVT, "sdio_driving"), -+}; -+#endif -+ -+#if CFG_WMT_POWER_ON_DLM -+static struct init_script wmt_power_on_dlm_table[] = { -+ INIT_CMD(WMT_POWER_CTRL_DLM_CMD1, WMT_POWER_CTRL_DLM_EVT, "power on dlm cmd1"), -+ INIT_CMD(WMT_POWER_CTRL_DLM_CMD2, WMT_POWER_CTRL_DLM_EVT, "power on dlm cmd2"), -+ INIT_CMD(WMT_POWER_CTRL_DLM_CMD3, WMT_POWER_CTRL_DLM_EVT, "power on dlm cmd3") -+}; -+#endif -+ -+/* SOC Chip Version and Info Table */ -+static const WMT_IC_INFO_S mtk_wcn_soc_info_table[] = { -+ { -+ .u4HwVer = 0x8A00, -+ .cChipName = WMT_IC_NAME_DEFAULT, -+ .cChipVersion = WMT_IC_VER_E1, -+ .cPatchNameExt = WMT_IC_PATCH_E1_EXT, -+ /* need to refine? */ -+ .eWmtHwVer = WMTHWVER_E1, -+ .bWorkWithoutPatch = MTK_WCN_BOOL_FALSE, -+ .bPsmSupport = MTK_WCN_BOOL_TRUE, -+ }, -+ { -+ .u4HwVer = 0x8A01, -+ .cChipName = WMT_IC_NAME_DEFAULT, -+ .cChipVersion = WMT_IC_VER_E2, -+ .cPatchNameExt = WMT_IC_PATCH_E1_EXT, -+ .eWmtHwVer = WMTHWVER_E2, -+ .bWorkWithoutPatch = MTK_WCN_BOOL_FALSE, -+ .bPsmSupport = MTK_WCN_BOOL_TRUE, -+ }, -+ { -+ .u4HwVer = 0x8B01, -+ .cChipName = WMT_IC_NAME_DEFAULT, -+ .cChipVersion = WMT_IC_VER_E3, -+ .cPatchNameExt = WMT_IC_PATCH_E1_EXT, -+ .eWmtHwVer = WMTHWVER_E3, -+ .bWorkWithoutPatch = MTK_WCN_BOOL_FALSE, -+ .bPsmSupport = MTK_WCN_BOOL_TRUE, -+ } -+}; -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+static INT32 mtk_wcn_soc_sw_init(P_WMT_HIF_CONF pWmtHifConf); -+ -+static INT32 mtk_wcn_soc_sw_deinit(P_WMT_HIF_CONF pWmtHifConf); -+ -+static INT32 mtk_wcn_soc_pin_ctrl(WMT_IC_PIN_ID id, WMT_IC_PIN_STATE state, UINT32 flag); -+ -+static INT32 mtk_wcn_soc_aif_ctrl(WMT_IC_PIN_STATE state, UINT32 flag); -+ -+static INT32 mtk_wcn_soc_ver_check(VOID); -+ -+static const WMT_IC_INFO_S *mtk_wcn_soc_find_wmt_ic_info(const UINT32 hw_ver); -+ -+static INT32 wmt_stp_init_coex(VOID); -+ -+#if CFG_WMT_FILTER_MODE_SETTING -+static INT32 wmt_stp_wifi_lte_coex(VOID); -+#endif -+ -+#if CFG_WMT_MULTI_PATCH -+static INT32 mtk_wcn_soc_patch_dwn(UINT32 index); -+static INT32 mtk_wcn_soc_patch_info_prepare(VOID); -+#else -+static INT32 mtk_wcn_soc_patch_dwn(VOID); -+#endif -+ -+static INT32 mtk_wcn_soc_co_clock_ctrl(WMT_CO_CLOCK on); -+static WMT_CO_CLOCK mtk_wcn_soc_co_clock_get(VOID); -+ -+#if CFG_WMT_CRYSTAL_TIMING_SET -+static INT32 mtk_wcn_soc_crystal_triming_set(VOID); -+#endif -+ -+static MTK_WCN_BOOL mtk_wcn_soc_quick_sleep_flag_get(VOID); -+ -+static MTK_WCN_BOOL mtk_wcn_soc_aee_dump_flag_get(VOID); -+ -+#if CFG_WMT_SDIO_DRIVING_SET -+static INT32 mtk_wcn_soc_set_sdio_driving(void); -+#endif -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/* SOC Operation Function Table */ -+WMT_IC_OPS wmt_ic_ops_soc = { -+ .icId = 0x0000, /* soc may have mt6572/82/71/83,but they have the same sw init flow */ -+ .sw_init = mtk_wcn_soc_sw_init, -+ .sw_deinit = mtk_wcn_soc_sw_deinit, -+ .ic_pin_ctrl = mtk_wcn_soc_pin_ctrl, -+ .ic_ver_check = mtk_wcn_soc_ver_check, -+ .co_clock_ctrl = mtk_wcn_soc_co_clock_ctrl, -+ .is_quick_sleep = mtk_wcn_soc_quick_sleep_flag_get, -+ .is_aee_dump_support = mtk_wcn_soc_aee_dump_flag_get, -+}; -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+static INT32 mtk_wcn_soc_sw_init(P_WMT_HIF_CONF pWmtHifConf) -+{ -+ INT32 iRet = -1; -+ unsigned long ctrlPa1; -+ unsigned long ctrlPa2; -+ UINT32 hw_ver; -+ WMT_CTRL_DATA ctrlData; -+#ifdef CFG_WMT_READ_EFUSE_VCN33 -+ UINT32 efuse_d3_vcn33 = 2; /*default voltage is 3.5V*/ -+#endif -+#if CFG_WMT_MULTI_PATCH -+ UINT32 patch_num = 0; -+ UINT32 patch_index = 0; -+#endif -+#if CFG_WMT_WIFI_5G_SUPPORT -+ UINT32 dDieChipid = 0; -+ UINT32 aDieChipid = 0; -+ UINT8 evtbuf[20]; -+ UINT32 u4Res; -+ UINT32 pmicChipid = 0; -+#endif -+ WMT_DBG_FUNC(" start\n"); -+ -+ osal_assert(NULL != gp_soc_info); -+ if ((NULL == gp_soc_info) -+ || (NULL == pWmtHifConf) -+ ) { -+ WMT_ERR_FUNC("null pointers: gp_soc_info(0x%p), pWmtHifConf(0x%p)\n", gp_soc_info, pWmtHifConf); -+ return -1; -+ } -+ -+ hw_ver = gp_soc_info->u4HwVer; -+ -+ /* 4 <3.2> start init for BTIF */ -+ if (WMT_HIF_BTIF == pWmtHifConf->hifType) { -+ /* 1. Query chip STP default options (TEST-ONLY) */ -+ /* WMT_DBG_FUNC("WMT-CORE: init_table_1_2 set chip baud:%d", pWmtHifConf->au4HifConf[0]); */ -+ iRet = wmt_core_init_script(init_table_1_2, osal_array_size(init_table_1_2)); -+ if (iRet) { -+ WMT_ERR_FUNC("init_table_1_2 fail(%d)\n", iRet); -+ osal_assert(0); -+ return -2; -+ } -+ /* 2. Set chip STP options */ -+ iRet = wmt_core_init_script(init_table_4, osal_array_size(init_table_4)); -+ if (iRet) { -+ WMT_ERR_FUNC("init_table_4 fail(%d)\n", iRet); -+ return -3; -+ } -+ -+ /* 3. Enable host full mode */ -+ ctrlPa1 = WMT_STP_CONF_MODE; -+ ctrlPa2 = MTKSTP_BTIF_FULL_MODE; -+ iRet = wmt_core_ctrl(WMT_CTRL_STP_CONF, &ctrlPa1, &ctrlPa2); -+ ctrlPa1 = WMT_STP_CONF_EN; -+ ctrlPa2 = 1; -+ iRet += wmt_core_ctrl(WMT_CTRL_STP_CONF, &ctrlPa1, &ctrlPa2); -+ if (iRet) { -+ WMT_ERR_FUNC("enable host STP-BTIF-FULL mode fail(%d)\n", iRet); -+ return -4; -+ } -+ WMT_DBG_FUNC("enable host STP-BTIF-FULL mode\n"); -+ /*4. wait for 10ms, enough for chip do mechanism switch.(at least 2ms is needed) */ -+ osal_sleep_ms(10); -+ /* 5. Query chip STP options (TEST-ONLY) */ -+ iRet = wmt_core_init_script(init_table_5, osal_array_size(init_table_5)); -+ if (iRet) { -+ WMT_ERR_FUNC("init_table_5 fail(%d)\n", iRet); -+ return -5; -+ } -+ } -+#if CFG_WMT_POWER_ON_DLM -+ iRet = wmt_core_init_script(wmt_power_on_dlm_table, osal_array_size(wmt_power_on_dlm_table)); -+ if (iRet) -+ WMT_ERR_FUNC("wmt_power_on_dlm_table fail(%d)\n", iRet); -+ WMT_DBG_FUNC("wmt_power_on_dlm_table ok\n"); -+#endif -+ /* 6. download patch */ -+#if CFG_WMT_MULTI_PATCH -+ /* 6.1 Let launcher to search patch info */ -+ iRet = mtk_wcn_soc_patch_info_prepare(); -+ if (iRet) { -+ WMT_ERR_FUNC("patch info perpare fail(%d)\n", iRet); -+ return -6; -+ } -+ -+ /* 6.2 Read patch number */ -+ ctrlPa1 = 0; -+ ctrlPa2 = 0; -+ wmt_core_ctrl(WMT_CTRL_GET_PATCH_NUM, &ctrlPa1, &ctrlPa2); -+ patch_num = ctrlPa1; -+ WMT_DBG_FUNC("patch total num = [%d]\n", patch_num); -+ -+#if CFG_WMT_PATCH_DL_OPTM -+ if (0x0279 == wmt_ic_ops_soc.icId) { -+ iRet = wmt_core_init_script(set_mcuclk_table_3, osal_array_size(set_mcuclk_table_3)); -+ if (iRet) -+ WMT_ERR_FUNC("set_mcuclk_table_3 fail(%d)\n", iRet); -+ } else { -+ iRet = wmt_core_init_script(set_mcuclk_table_1, osal_array_size(set_mcuclk_table_1)); -+ if (iRet) -+ WMT_ERR_FUNC("set_mcuclk_table_1 fail(%d)\n", iRet); -+ } -+#endif -+ /* 6.3 Multi-patch Patch download */ -+ for (patch_index = 0; patch_index < patch_num; patch_index++) { -+ iRet = mtk_wcn_soc_patch_dwn(patch_index); -+ if (iRet) { -+ WMT_ERR_FUNC("patch dwn fail (%d),patch_index(%d)\n", iRet, patch_index); -+ return -7; -+ } -+ iRet = wmt_core_init_script(init_table_3, osal_array_size(init_table_3)); -+ if (iRet) { -+ WMT_ERR_FUNC("init_table_3 fail(%d)\n", iRet); -+ return -8; -+ } -+ } -+ -+#if CFG_WMT_PATCH_DL_OPTM -+ if (0x0279 == wmt_ic_ops_soc.icId) { -+ iRet = wmt_core_init_script(set_mcuclk_table_4, osal_array_size(set_mcuclk_table_4)); -+ if (iRet) -+ WMT_ERR_FUNC("set_mcuclk_table_4 fail(%d)\n", iRet); -+ } else { -+ iRet = wmt_core_init_script(set_mcuclk_table_2, osal_array_size(set_mcuclk_table_2)); -+ if (iRet) -+ WMT_ERR_FUNC("set_mcuclk_table_2 fail(%d)\n", iRet); -+ } -+#endif -+ -+#else -+ /* 6.3 Patch download */ -+ iRet = mtk_wcn_soc_patch_dwn(); -+ /* If patch download fail, we just ignore this error and let chip init process goes on */ -+ if (iRet) -+ WMT_ERR_FUNC("patch dwn fail (%d), just omit\n", iRet); -+ -+ /* 6.4. WMT Reset command */ -+ iRet = wmt_core_init_script(init_table_3, osal_array_size(init_table_3)); -+ if (iRet) { -+ WMT_ERR_FUNC("init_table_3 fail(%d)\n", iRet); -+ return -8; -+ } -+#endif -+ -+#ifdef CFG_WMT_READ_EFUSE_VCN33 -+ /*get CrystalTiming value before set it */ -+ iRet = wmt_core_tx(get_efuse_vcn33_script[0].cmd, get_efuse_vcn33_script[0].cmdSz, &u4Res, -+ MTK_WCN_BOOL_FALSE); -+ if (iRet || (u4Res != get_efuse_vcn33_script[0].cmdSz)) { -+ WMT_ERR_FUNC("WMT-CORE: write (%s) iRet(%d) cmd len err(%d, %d)\n", -+ get_efuse_vcn33_script[0].str, iRet, u4Res, get_efuse_vcn33_script[0].cmdSz); -+ } -+ /* EVENT BUF */ -+ osal_memset(get_efuse_vcn33_script[0].evt, 0, get_efuse_vcn33_script[0].evtSz); -+ iRet = wmt_core_rx(get_efuse_vcn33_script[0].evt, get_efuse_vcn33_script[0].evtSz, &u4Res); -+ if (iRet || (u4Res != get_efuse_vcn33_script[0].evtSz)) { -+ WMT_ERR_FUNC("WMT-CORE: read (%s) iRet(%d) evt len err(rx:%d, exp:%d)\n", -+ get_efuse_vcn33_script[0].str, iRet, u4Res, get_efuse_vcn33_script[0].evtSz); -+ mtk_wcn_stp_dbg_dump_package(); -+ } -+ efuse_d3_vcn33 = WMT_GET_EFUSE_VCN33_EVT[5] & 0x03; -+ WMT_INFO_FUNC("Read efuse to set PMIC voltage:(%d)\n", efuse_d3_vcn33); -+ wmt_set_pmic_voltage(efuse_d3_vcn33); -+#endif -+ -+#if CFG_WMT_FILTER_MODE_SETTING -+ if ((0x6580 == wmt_ic_ops_soc.icId) || -+ (0x8163 == wmt_ic_ops_soc.icId) || -+ (0x6752 == wmt_ic_ops_soc.icId) || -+ (0x6582 == wmt_ic_ops_soc.icId) || -+ (0x6592 == wmt_ic_ops_soc.icId) || -+ (0x0279 == wmt_ic_ops_soc.icId) || -+ (0x0326 == wmt_ic_ops_soc.icId) || -+ (0x0321 == wmt_ic_ops_soc.icId) || (0x0335 == wmt_ic_ops_soc.icId) || (0x0337 == wmt_ic_ops_soc.icId)) { -+ wmt_stp_wifi_lte_coex(); -+ WMT_DBG_FUNC("wmt_stp_wifi_lte_coex done!\n"); -+ } -+ if ((0x6582 == wmt_ic_ops_soc.icId) || (0x6592 == wmt_ic_ops_soc.icId)) { -+ /*get gpio tdm req antsel number */ -+ ctrlPa1 = 0; -+ ctrlPa2 = 0; -+ wmt_core_ctrl(WMT_CTRL_GET_TDM_REQ_ANTSEL, &ctrlPa1, &ctrlPa2); -+ WMT_INFO_FUNC("get GPIO TDM REQ ANTSEL number(%d)\n", ctrlPa1); -+ /*set gpio tdm req antsel number to firmware */ -+ WMT_COEX_TDM_REQ_ANTSEL_NUM_CMD[5] = ctrlPa1; -+ iRet = wmt_core_init_script(get_tdm_req_antsel_num_table, -+ osal_array_size(get_tdm_req_antsel_num_table)); -+ if (iRet) -+ WMT_ERR_FUNC("get_tdm_req_antsel_num_table fail(%d)\n", iRet); -+ } -+#endif -+ /* 7. start RF calibration data */ -+ ctrlPa1 = BT_PALDO; -+ ctrlPa2 = PALDO_ON; -+ iRet = wmt_core_ctrl(WMT_CTRL_SOC_PALDO_CTRL, &ctrlPa1, &ctrlPa2); -+ ctrlPa1 = WIFI_PALDO; -+ ctrlPa2 = PALDO_ON; -+ iRet = wmt_core_ctrl(WMT_CTRL_SOC_PALDO_CTRL, &ctrlPa1, &ctrlPa2); -+ -+ iRet = wmt_core_init_script(calibration_table, osal_array_size(calibration_table)); -+ if (iRet) { -+ /* pwrap_read(0x0210,&ctrlPa1); */ -+ /* pwrap_read(0x0212,&ctrlPa2); */ -+ WMT_ERR_FUNC("power status: 210:(%d),212:(%d)!\n", ctrlPa1, ctrlPa2); -+ WMT_ERR_FUNC("calibration_table fail(%d)\n", iRet); -+ return -9; -+ } -+ -+ ctrlPa1 = BT_PALDO; -+ ctrlPa2 = PALDO_OFF; -+ iRet = wmt_core_ctrl(WMT_CTRL_SOC_PALDO_CTRL, &ctrlPa1, &ctrlPa2); -+ ctrlPa1 = WIFI_PALDO; -+ ctrlPa2 = PALDO_OFF; -+ iRet = wmt_core_ctrl(WMT_CTRL_SOC_PALDO_CTRL, &ctrlPa1, &ctrlPa2); -+ -+ iRet = wmt_stp_init_coex(); -+ if (iRet) { -+ WMT_ERR_FUNC("init_coex fail(%d)\n", iRet); -+ return -10; -+ } -+ WMT_DBG_FUNC("init_coex ok\n"); -+ -+#if CFG_WMT_CRYSTAL_TIMING_SET -+ mtk_wcn_soc_crystal_triming_set(); -+#endif -+ -+#if CFG_WMT_SDIO_DRIVING_SET -+ mtk_wcn_soc_set_sdio_driving(); -+#endif -+ -+ if (WMT_CO_CLOCK_EN == mtk_wcn_soc_co_clock_get()) { -+ WMT_INFO_FUNC("co-clock enabled.\n"); -+ -+ iRet = wmt_core_init_script(osc_type_table, osal_array_size(osc_type_table)); -+ if (iRet) { -+ WMT_ERR_FUNC("osc_type_table fail(%d), goes on\n", iRet); -+ return -11; -+ } -+ } else { -+ WMT_WARN_FUNC("co-clock disabled.\n"); -+ } -+#if (MTK_WCN_CMB_MERGE_INTERFACE_SUPPORT) -+ iRet = wmt_core_init_script(merge_pcm_table, osal_array_size(merge_pcm_table)); -+ if (iRet) { -+ WMT_ERR_FUNC("merge_pcm_table fail(%d), goes on\n", iRet); -+ return -12; -+ } -+#endif -+ -+ /* 15. Set FM strap */ -+ WMT_STRAP_CONF_CMD_FM_COMM[5] = (UINT8) pWmtHifConf->au4StrapConf[0]; -+ WMT_STRAP_CONF_EVT[5] = (UINT8) pWmtHifConf->au4StrapConf[0]; -+ iRet = wmt_core_init_script(init_table_5_1, osal_array_size(init_table_5_1)); -+ if (iRet) { -+ WMT_ERR_FUNC("init_table_5_1 fm mode(%d) fail(%d)\n", pWmtHifConf->au4StrapConf[0], iRet); -+ return -13; -+ } -+ WMT_DBG_FUNC("set fm mode (%d) ok\n", pWmtHifConf->au4StrapConf[0]); -+ -+#if CFG_SET_OPT_REG /*set registers */ -+ iRet = wmt_core_init_script(set_registers, osal_array_size(set_registers)); -+ if (iRet) { -+ WMT_ERR_FUNC("set_registers fail(%d)", iRet); -+ return -14; -+ } -+#endif -+ -+#if CFG_WMT_COREDUMP_ENABLE -+ /*Open Core Dump Function @QC begin */ -+ mtk_wcn_stp_coredump_flag_ctrl(1); -+#endif -+ if (0 != mtk_wcn_stp_coredump_flag_get()) { -+ iRet = wmt_core_init_script(init_table_6, osal_array_size(init_table_6)); -+ if (iRet) { -+ WMT_ERR_FUNC("init_table_6 core dump setting fail(%d)\n", iRet); -+ return -15; -+ } -+ WMT_DBG_FUNC("enable soc_consys firmware coredump\n"); -+ } else { -+ WMT_DBG_FUNC("disable soc_consys firmware coredump\n"); -+ } -+ -+#if CFG_WMT_WIFI_5G_SUPPORT -+ dDieChipid = wmt_ic_ops_soc.icId; -+ WMT_DBG_FUNC("current SOC chipid is 0x%x\n", dDieChipid); -+ if (0x6592 == dDieChipid) { -+ /* read A die chipid by wmt cmd */ -+ iRet = -+ wmt_core_tx((PUINT8) &WMT_GET_SOC_ADIE_CHIPID_CMD[0], sizeof(WMT_GET_SOC_ADIE_CHIPID_CMD), &u4Res, -+ MTK_WCN_BOOL_FALSE); -+ if (iRet || (u4Res != sizeof(WMT_GET_SOC_ADIE_CHIPID_CMD))) { -+ WMT_ERR_FUNC("wmt_core:read A die chipid CMD fail(%d),size(%d)\n", iRet, u4Res); -+ return -16; -+ } -+ osal_memset(evtbuf, 0, sizeof(evtbuf)); -+ iRet = wmt_core_rx(evtbuf, sizeof(WMT_GET_SOC_ADIE_CHIPID_EVT), &u4Res); -+ if (iRet || (u4Res != sizeof(WMT_GET_SOC_ADIE_CHIPID_EVT))) { -+ WMT_ERR_FUNC("wmt_core:read A die chipid EVT fail(%d),size(%d)\n", iRet, u4Res); -+ return -17; -+ } -+ -+ osal_memcpy(&aDieChipid, &evtbuf[u4Res - 2], 2); -+ WMT_INFO_FUNC("get SOC A die chipid(0x%x)\n", aDieChipid); -+ -+ if (0x6625 == aDieChipid) { -+ iRet = -+ wmt_core_tx((PUINT8) &WMT_GET_SOC_6625_L_CMD[0], sizeof(WMT_GET_SOC_6625_L_CMD), &u4Res, -+ MTK_WCN_BOOL_FALSE); -+ if (iRet || (u4Res != sizeof(WMT_GET_SOC_6625_L_CMD))) -+ WMT_ERR_FUNC("wmt_core:read A die efuse CMD fail(%d),size(%d)\n", iRet, u4Res); -+ osal_memset(evtbuf, 0, sizeof(evtbuf)); -+ iRet = wmt_core_rx(evtbuf, sizeof(WMT_GET_SOC_6625_L_EVT), &u4Res); -+ if (iRet || (u4Res != sizeof(WMT_GET_SOC_6625_L_EVT))) -+ WMT_ERR_FUNC("wmt_core:read A die efuse EVT fail(%d),size(%d)\n", iRet, u4Res); -+ -+ WMT_INFO_FUNC("read SOC Adie Efuse(0x120) value:0x%2x,0x%2x,0x%2x,0x%2x -> %s\n", -+ evtbuf[u4Res - 4], evtbuf[u4Res - 3], evtbuf[u4Res - 2], evtbuf[u4Res - 1], -+ evtbuf[u4Res - 2] == 0x31 ? "MT6625L" : "MT6625"); -+ } -+ /* get PMIC chipid */ -+ -+ ctrlData.ctrlId = WMT_CTRL_SOC_PALDO_CTRL; -+ ctrlData.au4CtrlData[0] = PMIC_CHIPID_PALDO; -+ ctrlData.au4CtrlData[1] = 0; -+ iRet = wmt_ctrl(&ctrlData); -+ if (iRet < 0) { -+ WMT_ERR_FUNC("wmt_core: read PMIC chipid fail(%d)\n", iRet); -+ return -18; -+ } -+ pmicChipid = ctrlData.au4CtrlData[2]; -+ WMT_INFO_FUNC("current PMIC chipid(0x%x)\n", pmicChipid); -+ -+ /* MT6625 & MT6322, write 1 to 0x0414[12] */ -+ /* MT6625 & MT6323, assert */ -+ /* MT6627 & (MT6322 or MT6323),write 0 to 0x0414[12] */ -+ -+ switch (aDieChipid) { -+ case 0x6625: -+ if (0x6322 == pmicChipid) { -+ WMT_INFO_FUNC("wmt-core:enable wifi 5G support\n"); -+ ctrlPa1 = WIFI_5G_PALDO; -+ ctrlPa2 = PALDO_ON; -+ wmt_core_ctrl(WMT_CTRL_SOC_PALDO_CTRL, &ctrlPa1, &ctrlPa2); -+ } else if (0x6323 == pmicChipid) { -+ osal_assert(0); -+ } else { -+ WMT_WARN_FUNC("wmt-core: unknown PMIC chipid\n"); -+ } -+ break; -+ case 0x6627: -+ if ((0x6322 == pmicChipid) || (0x6323 == pmicChipid)) { -+ WMT_INFO_FUNC("wmt-core: disable wifi 5G support\n"); -+ ctrlPa1 = WIFI_5G_PALDO; -+ ctrlPa2 = PALDO_OFF; -+ wmt_core_ctrl(WMT_CTRL_SOC_PALDO_CTRL, &ctrlPa1, &ctrlPa2); -+ } else { -+ WMT_WARN_FUNC("wmt-core: unknown PMIC chipid\n"); -+ } -+ break; -+ default: -+ WMT_WARN_FUNC("wmt-core: unknown A die chipid(0x%x)\n", aDieChipid); -+ break; -+ } -+ } -+#endif -+ -+#if 1 -+ ctrlData.ctrlId = WMT_CTRL_SET_STP_DBG_INFO; -+ ctrlData.au4CtrlData[0] = wmt_ic_ops_soc.icId; -+ ctrlData.au4CtrlData[1] = (SIZE_T) gp_soc_info->cChipVersion; -+ ctrlData.au4CtrlData[2] = (SIZE_T) &gp_soc_patch_info; -+ iRet = wmt_ctrl(&ctrlData); -+ if (iRet) { -+ WMT_ERR_FUNC("set dump info fail(%d)\n", iRet); -+ return -19; -+ } -+#endif -+ -+#if CFG_WMT_PS_SUPPORT -+ osal_assert(NULL != gp_soc_info); -+ if (NULL != gp_soc_info) { -+ if (MTK_WCN_BOOL_FALSE != gp_soc_info->bPsmSupport) -+ wmt_lib_ps_enable(); -+ else -+ wmt_lib_ps_disable(); -+ } -+#endif -+ -+ return 0; -+} -+ -+static INT32 mtk_wcn_soc_sw_deinit(P_WMT_HIF_CONF pWmtHifConf) -+{ -+ WMT_DBG_FUNC(" start\n"); -+ -+#if CFG_WMT_PS_SUPPORT -+ osal_assert(NULL != gp_soc_info); -+ if ((NULL != gp_soc_info) -+ && (MTK_WCN_BOOL_FALSE != gp_soc_info->bPsmSupport)) { -+ wmt_lib_ps_disable(); -+ } -+#endif -+ -+ gp_soc_info = NULL; -+ -+ return 0; -+} -+ -+static INT32 mtk_wcn_soc_aif_ctrl(WMT_IC_PIN_STATE state, UINT32 flag) -+{ -+ INT32 ret = -1; -+ UINT32 val; -+ -+ if ((flag & WMT_LIB_AIF_FLAG_MASK) == WMT_LIB_AIF_FLAG_SHARE) { -+ WMT_INFO_FUNC("PCM & I2S PIN SHARE\n"); -+#if 0 -+ switch (state) { -+ case WMT_IC_AIF_0: -+ /* BT_PCM_OFF & FM line in/out */ -+ val = 0x00000770; -+ ret = wmt_core_reg_rw_raw(1, 0x80050140, &val, 0x00000FF0); -+ val = 0x00000000; -+ ret += wmt_core_reg_rw_raw(1, 0x80050150, &val, 0x00000800); -+ break; -+ -+ case WMT_IC_AIF_1: -+ /* BT_PCM_ON & FM line in/out */ -+ val = 0x00000700; -+ ret = wmt_core_reg_rw_raw(1, 0x80050140, &val, 0x00000FF0); -+ val = 0x00000000; -+ ret += wmt_core_reg_rw_raw(1, 0x80050150, &val, 0x00000800); -+ break; -+ -+ case WMT_IC_AIF_2: -+ /* BT_PCM_OFF & FM I2S */ -+ val = 0x00000710; -+ ret = wmt_core_reg_rw_raw(1, 0x80050140, &val, 0x00000FF0); -+ val = 0x00000800; /* 800:3-wire, 000: 4-wire */ -+ ret += wmt_core_reg_rw_raw(1, 0x80050150, &val, 0x00000800); -+ break; -+ default: -+ WMT_ERR_FUNC("unsupported state (%d)\n", state); -+ ret = -1; -+ break; -+ } -+#else -+ WMT_WARN_FUNC("TBD!!"); -+ ret = 0; -+#endif -+ } else { -+ /*PCM & I2S separate */ -+ WMT_INFO_FUNC("PCM & I2S PIN SEPARATE\n"); -+#if 0 -+ switch (state) { -+ case WMT_IC_AIF_0: -+ /* BT_PCM_OFF & FM line in/out */ -+ val = 0x00000770; -+ ret = wmt_core_reg_rw_raw(1, 0x80050140, &val, 0x00000FF0); -+ val = 0x00000000; -+ ret += wmt_core_reg_rw_raw(1, 0x80050150, &val, 0x00000800); -+ break; -+ -+ case WMT_IC_AIF_1: -+ /* BT_PCM_ON & FM line in/out */ -+ val = 0x00000700; -+ ret = wmt_core_reg_rw_raw(1, 0x80050140, &val, 0x00000FF0); -+ val = 0x00000000; -+ ret += wmt_core_reg_rw_raw(1, 0x80050150, &val, 0x00000800); -+ break; -+ -+ case WMT_IC_AIF_2: -+ /* BT_PCM_OFF & FM I2S */ -+ val = 0x00000070; -+ ret = wmt_core_reg_rw_raw(1, 0x80050140, &val, 0x00000FF0); -+ val = 0x00000800; /* 800:3-wire, 000: 4-wire */ -+ ret += wmt_core_reg_rw_raw(1, 0x80050150, &val, 0x00000800); -+ -+ break; -+ case WMT_IC_AIF_3: -+ val = 0x00000000; -+ ret = wmt_core_reg_rw_raw(1, 0x80050140, &val, 0x00000FF0); -+ val = 0x00000800; /* 800:3-wire, 000: 4-wire */ -+ ret += wmt_core_reg_rw_raw(1, 0x80050150, &val, 0x00000800); -+ -+ break; -+ default: -+ WMT_ERR_FUNC("unsupported state (%d)\n", state); -+ ret = -1; -+ break; -+ } -+#else -+ switch (state) { -+ case WMT_IC_AIF_0: -+ /* BT_PCM_OFF & FM line in/out */ -+ ret = 0; -+ break; -+ case WMT_IC_AIF_1: -+ /* BT_PCM_ON & FM line in/out */ -+ ret = 0; -+ break; -+ -+ case WMT_IC_AIF_2: -+ /* BT_PCM_OFF & FM I2S */ -+ val = 0x01110000; -+ ret = wmt_core_reg_rw_raw(1, 0x80050078, &val, 0x0FFF0000); -+ -+ break; -+ case WMT_IC_AIF_3: -+ ret = 0; -+ break; -+ -+ default: -+ WMT_ERR_FUNC("unsupported state (%d)\n", state); -+ ret = -1; -+ break; -+ } -+#endif -+ } -+ -+ if (!ret) -+ WMT_WARN_FUNC("new state(%d) fail(%d)\n", state, ret); -+ WMT_INFO_FUNC("new state(%d) ok\n", state); -+ -+ return ret; -+} -+ -+static INT32 mtk_wcn_soc_gps_sync_ctrl(WMT_IC_PIN_STATE state, UINT32 flag) -+{ -+ INT32 iRet = -1; -+ UINT32 uVal = 0; -+ -+ /* mt6797 can not access reg:0x80050078 and no need to do GPS SYNC */ -+ if (0x0279 != wmt_ic_ops_soc.icId) { -+ if (WMT_IC_PIN_MUX == state) -+ uVal = 0x1 << 28; -+ else -+ uVal = 0x5 << 28; -+ iRet = wmt_core_reg_rw_raw(1, 0x80050078, &uVal, 0x7 << 28); -+ if (iRet) -+ WMT_ERR_FUNC("gps_sync pin ctrl failed, iRet(%d)\n", iRet); -+ } else -+ WMT_INFO_FUNC("This chip no need to sync GPS and MODEM!\n"); -+ -+ /* anyway, we return 0 */ -+ return 0; -+} -+ -+static INT32 mtk_wcn_soc_pin_ctrl(WMT_IC_PIN_ID id, WMT_IC_PIN_STATE state, UINT32 flag) -+{ -+ INT32 ret; -+ -+ WMT_DBG_FUNC("ic pin id:%d, state:%d, flag:0x%x\n", id, state, flag); -+ -+ ret = -1; -+ switch (id) { -+ case WMT_IC_PIN_AUDIO: -+ ret = mtk_wcn_soc_aif_ctrl(state, flag); -+ break; -+ -+ case WMT_IC_PIN_EEDI: -+ WMT_WARN_FUNC("TBD!!"); -+ /* We just return 0 here, prevent from WMT-FUNC do other register read/write */ -+ ret = 0; -+ break; -+ -+ case WMT_IC_PIN_EEDO: -+ WMT_WARN_FUNC("TBD!!"); -+ /* We just return 0 here, prevent from WMT-FUNC do other register read/write */ -+ ret = 0; -+ break; -+ case WMT_IC_PIN_GSYNC: -+ ret = mtk_wcn_soc_gps_sync_ctrl(state, flag); -+ break; -+ default: -+ break; -+ } -+ WMT_INFO_FUNC("ret = (%d)\n", ret); -+ -+ return ret; -+} -+ -+INT32 mtk_wcn_soc_co_clock_ctrl(WMT_CO_CLOCK on) -+{ -+ INT32 iRet = 0; -+ -+ if ((WMT_CO_CLOCK_DIS <= on) && (WMT_CO_CLOCK_MAX > on)) { -+ gCoClockEn = on; -+ } else { -+ WMT_DBG_FUNC("0x%x: error parameter:%d\n", wmt_ic_ops_soc.icId, on); -+ iRet = -1; -+ } -+ WMT_DBG_FUNC("0x%x: Co-clock %s\n", wmt_ic_ops_soc.icId, -+ (gCoClockEn == WMT_CO_CLOCK_DIS) ? "disabled" : "enabled"); -+ -+ return iRet; -+} -+ -+static MTK_WCN_BOOL mtk_wcn_soc_quick_sleep_flag_get(VOID) -+{ -+ return MTK_WCN_BOOL_TRUE; -+} -+ -+static MTK_WCN_BOOL mtk_wcn_soc_aee_dump_flag_get(VOID) -+{ -+ return MTK_WCN_BOOL_FALSE; -+} -+ -+WMT_CO_CLOCK mtk_wcn_soc_co_clock_get(VOID) -+{ -+ return gCoClockEn; -+} -+ -+static INT32 mtk_wcn_soc_ver_check(VOID) -+{ -+ UINT32 hw_ver; -+ UINT32 fw_ver; -+ INT32 iret; -+ const WMT_IC_INFO_S *p_info; -+ unsigned long ctrlPa1; -+ unsigned long ctrlPa2; -+ -+ /* 1. identify chip versions: HVR(HW_VER) and FVR(FW_VER) */ -+ WMT_LOUD_FUNC("0x%x: before read hw_ver (hw version)\n", wmt_ic_ops_soc.icId); -+ iret = wmt_core_reg_rw_raw(0, GEN_HVR, &hw_ver, GEN_VER_MASK); -+ if (iret) { -+ WMT_ERR_FUNC("0x%x: read hw_ver fail:%d\n", wmt_ic_ops_soc.icId, iret); -+ return -2; -+ } -+ WMT_WARN_FUNC("0x%x: read hw_ver (hw version) (0x%x)\n", wmt_ic_ops_soc.icId, hw_ver); -+ -+ WMT_LOUD_FUNC("0x%x: before fw_ver (rom version)\n", wmt_ic_ops_soc.icId); -+ wmt_core_reg_rw_raw(0, GEN_FVR, &fw_ver, GEN_VER_MASK); -+ if (iret) { -+ WMT_ERR_FUNC("0x%x: read fw_ver fail:%d\n", wmt_ic_ops_soc.icId, iret); -+ return -2; -+ } -+ WMT_WARN_FUNC("0x%x: read fw_ver (rom version) (0x%x)\n", wmt_ic_ops_soc.icId, fw_ver); -+ -+ p_info = mtk_wcn_soc_find_wmt_ic_info(hw_ver); -+ if (NULL == p_info) { -+ WMT_ERR_FUNC("0x%x: hw_ver(0x%x) find wmt ic info fail\n", wmt_ic_ops_soc.icId); -+ return -3; -+ } -+ WMT_WARN_FUNC("0x%x: ic info: %s.%s (0x%x/0x%x, WMTHWVER:%d, patch_ext:%s)\n", -+ wmt_ic_ops_soc.icId, p_info->cChipName, p_info->cChipVersion, -+ hw_ver, fw_ver, p_info->eWmtHwVer, p_info->cPatchNameExt); -+ -+ /* hw id & version */ -+ ctrlPa1 = (wmt_ic_ops_soc.icId << 16) | (hw_ver & 0x0000FFFF); -+ /* translated hw version & fw rom version */ -+ ctrlPa2 = ((UINT32) (p_info->eWmtHwVer) << 16) | (fw_ver & 0x0000FFFF); -+ -+ iret = wmt_core_ctrl(WMT_CTRL_HWIDVER_SET, &ctrlPa1, &ctrlPa2); -+ if (iret) -+ WMT_WARN_FUNC("0x%x: WMT_CTRL_HWIDVER_SET fail(%d)\n", wmt_ic_ops_soc.icId, iret); -+ -+ gp_soc_info = p_info; -+ return 0; -+} -+ -+static const WMT_IC_INFO_S *mtk_wcn_soc_find_wmt_ic_info(const UINT32 hw_ver) -+{ -+ /* match chipversion with u4HwVer item in mtk_wcn_soc_info_table */ -+ const UINT32 size = osal_array_size(mtk_wcn_soc_info_table); -+ INT32 index = 0; -+ -+ /* George: reverse the search order to favor newer version products -+ * TODO:[FixMe][GeorgeKuo] Remove full match once API wmt_lib_get_hwver() -+ * is changed correctly in the future!! -+ * Leave full match here is a workaround for GPS to distinguish E3/E4 ICs. -+ */ -+ index = size - 1; -+ /* full match */ -+ while ((0 <= index) && (hw_ver != mtk_wcn_soc_info_table[index].u4HwVer)) -+ --index; -+ if (0 <= index) { -+ WMT_DBG_FUNC("found ic info(0x%x) by full match! index:%d\n", hw_ver, index); -+ return &mtk_wcn_soc_info_table[index]; -+ } -+ -+ WMT_WARN_FUNC("find no ic info for (0x%x) by full match!try major num match!\n", hw_ver); -+ -+ /* George: The ONLY CORRECT method to find supported hw table. Match MAJOR -+ * NUM only can help us support future minor hw ECO, or fab switch, etc. -+ * FULL matching eliminate such flexibility and software package have to be -+ * updated EACH TIME even when minor hw ECO or fab switch!!! -+ */ -+ /* George: reverse the search order to favor newer version products */ -+ index = size - 1; -+ /* major num match */ -+ while ((0 <= index) && -+ (MAJORNUM(hw_ver) != MAJORNUM(mtk_wcn_soc_info_table[index].u4HwVer))) { -+ --index; -+ } -+ if (0 <= index) { -+ WMT_DBG_FUNC("0x%x: found ic info for hw_ver(0x%x) by major num! index:%d\n", -+ wmt_ic_ops_soc.icId, hw_ver, index); -+ return &mtk_wcn_soc_info_table[index]; -+ } -+ -+ WMT_ERR_FUNC("0x%x: find no ic info for hw_ver(0x%x) by full match nor major num match!\n", -+ wmt_ic_ops_soc.icId, hw_ver); -+ WMT_ERR_FUNC("Set default chip version: E1!\n"); -+ return &mtk_wcn_soc_info_table[0]; -+} -+ -+#if CFG_WMT_FILTER_MODE_SETTING -+static INT32 wmt_stp_wifi_lte_coex(VOID) -+{ -+ INT32 iRet; -+ unsigned long addr; -+ WMT_GEN_CONF *pWmtGenConf; -+ -+ /*Get wmt config */ -+ iRet = wmt_core_ctrl(WMT_CTRL_GET_WMT_CONF, &addr, 0); -+ if (iRet) { -+ WMT_ERR_FUNC("ctrl GET_WMT_CONF fail(%d)\n", iRet); -+ return -2; -+ } -+ WMT_DBG_FUNC("ctrl GET_WMT_CONF ok(0x%08lx)\n", addr); -+ -+ pWmtGenConf = (P_WMT_GEN_CONF) addr; -+ -+ /*Check if WMT.cfg exists */ -+ if (pWmtGenConf->cfgExist == 0) { -+ WMT_INFO_FUNC("cfgExist == 0, skip config chip\n"); -+ /*if WMT.cfg not existed, still return success and adopt the default value */ -+ return 0; -+ } -+ -+ osal_sleep_ms(5); -+ -+ if (pWmtGenConf->coex_wmt_filter_mode == 0) { -+ if ((0x6752 == wmt_ic_ops_soc.icId) || -+ (0x6580 == wmt_ic_ops_soc.icId) || -+ (0x8163 == wmt_ic_ops_soc.icId) || -+ (0x0326 == wmt_ic_ops_soc.icId) || -+ (0x0321 == wmt_ic_ops_soc.icId) || -+ (0x0335 == wmt_ic_ops_soc.icId) || (0x0337 == wmt_ic_ops_soc.icId)) { -+ iRet = -+ wmt_core_init_script(set_wifi_lte_coex_table_1, osal_array_size(set_wifi_lte_coex_table_1)); -+ WMT_DBG_FUNC("wmt_core:set_wifi_lte_coex_table_1 %s(%d)\n", iRet ? "fail" : "ok", iRet); -+ } else if (0x0279 == wmt_ic_ops_soc.icId) { -+ /* add WMT_COXE_CONFIG_EXT_COMPONENT_OPCODE command for 2G4 eLNA demand*/ -+ if (pWmtGenConf->coex_wmt_ext_component) { -+ WMT_INFO_FUNC("coex_wmt_ext_component:0x%x\n", pWmtGenConf->coex_wmt_ext_component); -+ set_wifi_lte_coex_table_2[0].cmd[5] = pWmtGenConf->coex_wmt_ext_component; -+ } -+ iRet = -+ wmt_core_init_script(set_wifi_lte_coex_table_2, osal_array_size(set_wifi_lte_coex_table_2)); -+ WMT_DBG_FUNC("wmt_core:set_wifi_lte_coex_table_2 %s(%d)\n", iRet ? "fail" : "ok", iRet); -+ } else { -+ iRet = -+ wmt_core_init_script(set_wifi_lte_coex_table_0, osal_array_size(set_wifi_lte_coex_table_0)); -+ WMT_DBG_FUNC("wmt_core:set_wifi_lte_coex_table_0 %s(%d)\n", iRet ? "fail" : "ok", iRet); -+ } -+ } -+ -+ return iRet; -+} -+#endif -+ -+static INT32 wmt_stp_init_coex(VOID) -+{ -+ INT32 iRet; -+ unsigned long addr; -+ WMT_GEN_CONF *pWmtGenConf; -+ -+#define COEX_WMT 0 -+ -+#if CFG_SUBSYS_COEX_NEED -+ /* no need for MT6628 */ -+#define COEX_BT 1 -+#define COEX_WIFI 2 -+#define COEX_PTA 3 -+#define COEX_MISC 4 -+#endif -+ /*Get wmt config */ -+ iRet = wmt_core_ctrl(WMT_CTRL_GET_WMT_CONF, &addr, 0); -+ if (iRet) { -+ WMT_ERR_FUNC("ctrl GET_WMT_CONF fail(%d)\n", iRet); -+ return -2; -+ } -+ WMT_INFO_FUNC("ctrl GET_WMT_CONF ok(0x%08lx)\n", addr); -+ -+ pWmtGenConf = (P_WMT_GEN_CONF) addr; -+ -+ /*Check if WMT.cfg exists */ -+ if (pWmtGenConf->cfgExist == 0) { -+ WMT_INFO_FUNC("cfgExist == 0, skip config chip\n"); -+ /*if WMT.cfg not existed, still return success and adopt the default value */ -+ return 0; -+ } -+ -+ /*Dump the coex-related info */ -+ WMT_DBG_FUNC("coex_wmt:0x%x\n", pWmtGenConf->coex_wmt_ant_mode); -+#if CFG_SUBSYS_COEX_NEED -+ WMT_DBG_FUNC("coex_bt:0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n", -+ pWmtGenConf->coex_bt_rssi_upper_limit, -+ pWmtGenConf->coex_bt_rssi_mid_limit, -+ pWmtGenConf->coex_bt_rssi_lower_limit, -+ pWmtGenConf->coex_bt_pwr_high, pWmtGenConf->coex_bt_pwr_mid, pWmtGenConf->coex_bt_pwr_low); -+ WMT_DBG_FUNC("coex_wifi:0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n", -+ pWmtGenConf->coex_wifi_rssi_upper_limit, -+ pWmtGenConf->coex_wifi_rssi_mid_limit, -+ pWmtGenConf->coex_wifi_rssi_lower_limit, -+ pWmtGenConf->coex_wifi_pwr_high, pWmtGenConf->coex_wifi_pwr_mid, pWmtGenConf->coex_wifi_pwr_low); -+ WMT_DBG_FUNC("coex_ext_pta:0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n", -+ pWmtGenConf->coex_ext_pta_hi_tx_tag, -+ pWmtGenConf->coex_ext_pta_hi_rx_tag, -+ pWmtGenConf->coex_ext_pta_lo_tx_tag, -+ pWmtGenConf->coex_ext_pta_lo_rx_tag, -+ pWmtGenConf->coex_ext_pta_sample_t1, -+ pWmtGenConf->coex_ext_pta_sample_t2, pWmtGenConf->coex_ext_pta_wifi_bt_con_trx); -+ WMT_DBG_FUNC("coex_misc:0x%x 0x%x 0x%x\n", -+ pWmtGenConf->coex_misc_ext_pta_on, pWmtGenConf->coex_misc_ext_feature_set); -+#endif -+ -+ /*command adjustion due to WMT.cfg */ -+ coex_table[COEX_WMT].cmd[5] = pWmtGenConf->coex_wmt_ant_mode; -+ if (gWmtDbgLvl >= WMT_LOG_DBG) -+ wmt_core_dump_data(&coex_table[COEX_WMT].cmd[0], coex_table[COEX_WMT].str, coex_table[COEX_WMT].cmdSz); -+ -+#if CFG_SUBSYS_COEX_NEED -+ coex_table[COEX_BT].cmd[9] = pWmtGenConf->coex_bt_rssi_upper_limit; -+ coex_table[COEX_BT].cmd[10] = pWmtGenConf->coex_bt_rssi_mid_limit; -+ coex_table[COEX_BT].cmd[11] = pWmtGenConf->coex_bt_rssi_lower_limit; -+ coex_table[COEX_BT].cmd[12] = pWmtGenConf->coex_bt_pwr_high; -+ coex_table[COEX_BT].cmd[13] = pWmtGenConf->coex_bt_pwr_mid; -+ coex_table[COEX_BT].cmd[14] = pWmtGenConf->coex_bt_pwr_low; -+ if (gWmtDbgLvl >= WMT_LOG_DBG) -+ wmt_core_dump_data(&coex_table[COEX_BT].cmd[0], coex_table[COEX_BT].str, coex_table[COEX_BT].cmdSz); -+ -+ coex_table[COEX_WIFI].cmd[10] = pWmtGenConf->coex_wifi_rssi_upper_limit; -+ coex_table[COEX_WIFI].cmd[11] = pWmtGenConf->coex_wifi_rssi_mid_limit; -+ coex_table[COEX_WIFI].cmd[12] = pWmtGenConf->coex_wifi_rssi_lower_limit; -+ coex_table[COEX_WIFI].cmd[13] = pWmtGenConf->coex_wifi_pwr_high; -+ coex_table[COEX_WIFI].cmd[14] = pWmtGenConf->coex_wifi_pwr_mid; -+ coex_table[COEX_WIFI].cmd[15] = pWmtGenConf->coex_wifi_pwr_low; -+ if (gWmtDbgLvl >= WMT_LOG_DBG) -+ wmt_core_dump_data(&coex_table[COEX_WIFI].cmd[0], -+ coex_table[COEX_WIFI].str, coex_table[COEX_WIFI].cmdSz); -+ -+ coex_table[COEX_PTA].cmd[5] = pWmtGenConf->coex_ext_pta_hi_tx_tag; -+ coex_table[COEX_PTA].cmd[6] = pWmtGenConf->coex_ext_pta_hi_rx_tag; -+ coex_table[COEX_PTA].cmd[7] = pWmtGenConf->coex_ext_pta_lo_tx_tag; -+ coex_table[COEX_PTA].cmd[8] = pWmtGenConf->coex_ext_pta_lo_rx_tag; -+ coex_table[COEX_PTA].cmd[9] = ((pWmtGenConf->coex_ext_pta_sample_t1 & 0xff00) >> 8); -+ coex_table[COEX_PTA].cmd[10] = ((pWmtGenConf->coex_ext_pta_sample_t1 & 0x00ff) >> 0); -+ coex_table[COEX_PTA].cmd[11] = ((pWmtGenConf->coex_ext_pta_sample_t2 & 0xff00) >> 8); -+ coex_table[COEX_PTA].cmd[12] = ((pWmtGenConf->coex_ext_pta_sample_t2 & 0x00ff) >> 0); -+ coex_table[COEX_PTA].cmd[13] = pWmtGenConf->coex_ext_pta_wifi_bt_con_trx; -+ if (gWmtDbgLvl >= WMT_LOG_DBG) -+ wmt_core_dump_data(&coex_table[COEX_PTA].cmd[0], coex_table[COEX_PTA].str, coex_table[COEX_PTA].cmdSz); -+ -+ osal_memcpy(&coex_table[COEX_MISC].cmd[5], &pWmtGenConf->coex_misc_ext_pta_on, -+ sizeof(pWmtGenConf->coex_misc_ext_pta_on)); -+ osal_memcpy(&coex_table[COEX_MISC].cmd[9], &pWmtGenConf->coex_misc_ext_feature_set, -+ sizeof(pWmtGenConf->coex_misc_ext_feature_set)); -+ -+ wmt_core_dump_data(&coex_table[COEX_MISC].cmd[0], coex_table[COEX_MISC].str, coex_table[COEX_MISC].cmdSz); -+#endif -+ -+ iRet = wmt_core_init_script(coex_table, sizeof(coex_table) / sizeof(coex_table[0])); -+ -+ return iRet; -+} -+ -+#if CFG_WMT_SDIO_DRIVING_SET -+static INT32 mtk_wcn_soc_set_sdio_driving(void) -+{ -+ INT32 ret = 0; -+ -+ unsigned long addr; -+ WMT_GEN_CONF *pWmtGenConf; -+ UINT32 drv_val = 0; -+ -+ /*Get wmt config */ -+ ret = wmt_core_ctrl(WMT_CTRL_GET_WMT_CONF, &addr, 0); -+ if (ret) { -+ WMT_ERR_FUNC("ctrl GET_WMT_CONF fail(%d)\n", ret); -+ return -1; -+ } -+ WMT_INFO_FUNC("ctrl GET_WMT_CONF ok(0x%08lx)\n", addr); -+ -+ pWmtGenConf = (P_WMT_GEN_CONF) addr; -+ -+ /*Check if WMT.cfg exists */ -+ if (pWmtGenConf->cfgExist == 0) { -+ WMT_INFO_FUNC("cfgExist == 0, skip config chip\n"); -+ /*if WMT.cfg not existed, still return success and adopt the default value */ -+ return 0; -+ } -+ -+ drv_val = pWmtGenConf->sdio_driving_cfg; -+ -+ /*Dump the sdio driving related info */ -+ WMT_INFO_FUNC("sdio driving:0x%x\n", drv_val); -+ -+ sdio_driving_table[0].cmd[12] = (UINT8) ((drv_val & 0x00000077UL) >> 0); /* DAT0 and DAT1 */ -+ sdio_driving_table[0].cmd[13] = (UINT8) ((drv_val & 0x00007700UL) >> 8); /* DAT2 and DAT3 */ -+ sdio_driving_table[0].cmd[14] = (UINT8) ((drv_val & 0x00070000UL) >> 16); /* CMD */ -+ -+ ret = wmt_core_init_script(sdio_driving_table, sizeof(sdio_driving_table) / sizeof(sdio_driving_table[0])); -+ -+ return ret; -+} -+#endif -+ -+#if CFG_WMT_CRYSTAL_TIMING_SET -+static INT32 mtk_wcn_soc_crystal_triming_set(VOID) -+{ -+ INT32 iRet = 0; -+ PUINT8 pbuf = NULL; -+ UINT32 bufLen = 0; -+ WMT_CTRL_DATA ctrlData; -+ UINT32 uCryTimOffset = 0x6D; -+ MTK_WCN_BOOL bIsNvramExist = MTK_WCN_BOOL_FALSE; -+ INT8 cCrystalTimingOffset = 0x0; -+ UINT8 cCrystalTiming = 0x0; -+ INT32 iCrystalTiming = 0x0; -+ MTK_WCN_BOOL bIsCrysTrimEnabled = MTK_WCN_BOOL_FALSE; -+ UINT32 u4Res; -+ -+ bIsNvramExist = MTK_WCN_BOOL_FALSE; -+ /**/ ctrlData.ctrlId = WMT_CTRL_CRYSTAL_TRIMING_GET; -+ ctrlData.au4CtrlData[0] = (UINT32) "/data/nvram/APCFG/APRDEB/WIFI"; -+ ctrlData.au4CtrlData[1] = (UINT32) &pbuf; -+ ctrlData.au4CtrlData[2] = (UINT32) &bufLen; -+ -+ iRet = wmt_ctrl(&ctrlData); -+ if (0 != iRet) { -+ WMT_ERR_FUNC("0x%x: WMT_CTRL_CRYSTAL_TRIMING_GET fail:%d\n", wmt_ic_ops_soc.icId, iRet); -+ bIsNvramExist = MTK_WCN_BOOL_FALSE; -+ bIsCrysTrimEnabled = MTK_WCN_BOOL_FALSE; -+ cCrystalTimingOffset = 0x0; -+ cCrystalTiming = 0x0; -+ iRet = -1; -+ } else { -+ WMT_DBG_FUNC("0x%x: nvram pBuf(0x%08x), bufLen(%d)\n", wmt_ic_ops_soc.icId, pbuf, bufLen); -+ if (bufLen < (uCryTimOffset + 1)) { -+ WMT_ERR_FUNC("0x%x: nvram len(%d) too short, crystalTimging value offset(%d)\n", -+ wmt_ic_ops_soc.icId, bufLen, uCryTimOffset); -+ bIsNvramExist = MTK_WCN_BOOL_FALSE; -+ bIsCrysTrimEnabled = MTK_WCN_BOOL_FALSE; -+ cCrystalTimingOffset = 0x0; -+ cCrystalTiming = 0x0; -+ } else { -+ bIsNvramExist = MTK_WCN_BOOL_TRUE; -+ cCrystalTimingOffset = *(pbuf + uCryTimOffset); -+ if (cCrystalTimingOffset & 0x80) { -+ bIsCrysTrimEnabled = MTK_WCN_BOOL_TRUE; -+ cCrystalTimingOffset = (UINT8) cCrystalTimingOffset & 0x7f; -+ } -+ WMT_DBG_FUNC("cCrystalTimingOffset (%d), bIsCrysTrimEnabled(%d)\n", cCrystalTimingOffset, -+ bIsCrysTrimEnabled); -+ } -+ ctrlData.ctrlId = WMT_CTRL_CRYSTAL_TRIMING_PUT; -+ ctrlData.au4CtrlData[0] = (UINT32) "/data/nvram/APCFG/APRDEB/WIFI"; -+ iRet = wmt_ctrl(&ctrlData); -+ if (0 != iRet) { -+ WMT_ERR_FUNC("0x%x: WMT_CTRL_CRYSTAL_TRIMING_PUT fail:%d\n", wmt_ic_ops_soc.icId, iRet); -+ iRet = -2; -+ } else { -+ WMT_DBG_FUNC("0x%x: WMT_CTRL_CRYSTAL_TRIMING_PUT succeed\n", wmt_ic_ops_soc.icId); -+ } -+ } -+ if ((MTK_WCN_BOOL_TRUE == bIsNvramExist) && (MTK_WCN_BOOL_TRUE == bIsCrysTrimEnabled)) { -+ /*get CrystalTiming value before set it */ -+ iRet = -+ wmt_core_tx(get_crystal_timing_script[0].cmd, get_crystal_timing_script[0].cmdSz, &u4Res, -+ MTK_WCN_BOOL_FALSE); -+ if (iRet || (u4Res != get_crystal_timing_script[0].cmdSz)) { -+ WMT_ERR_FUNC("WMT-CORE: write (%s) iRet(%d) cmd len err(%d, %d)\n", -+ get_crystal_timing_script[0].str, iRet, u4Res, get_crystal_timing_script[0].cmdSz); -+ iRet = -3; -+ goto done; -+ } -+ /* EVENT BUF */ -+ osal_memset(get_crystal_timing_script[0].evt, 0, get_crystal_timing_script[0].evtSz); -+ iRet = wmt_core_rx(get_crystal_timing_script[0].evt, get_crystal_timing_script[0].evtSz, &u4Res); -+ if (iRet || (u4Res != get_crystal_timing_script[0].evtSz)) { -+ WMT_ERR_FUNC("WMT-CORE: read (%s) iRet(%d) evt len err(rx:%d, exp:%d)\n", -+ get_crystal_timing_script[0].str, iRet, u4Res, get_crystal_timing_script[0].evtSz); -+ mtk_wcn_stp_dbg_dump_package(); -+ iRet = -4; -+ goto done; -+ } -+ -+ iCrystalTiming = WMT_GET_CRYSTAL_TRIMING_EVT[5] & 0x7f; -+ if (cCrystalTimingOffset & 0x40) { -+ /*nagative offset value */ -+ iCrystalTiming = iCrystalTiming + cCrystalTimingOffset - 128; -+ } else { -+ iCrystalTiming += cCrystalTimingOffset; -+ } -+ WMT_DBG_FUNC("iCrystalTiming (0x%x)\n", iCrystalTiming); -+ cCrystalTiming = iCrystalTiming > 0x7f ? 0x7f : iCrystalTiming; -+ cCrystalTiming = iCrystalTiming < 0 ? 0 : iCrystalTiming; -+ WMT_DBG_FUNC("cCrystalTiming (0x%x)\n", cCrystalTiming); -+ /* set_crystal_timing_script */ -+ WMT_SET_CRYSTAL_TRIMING_CMD[5] = cCrystalTiming; -+ WMT_GET_CRYSTAL_TRIMING_EVT[5] = cCrystalTiming; -+ -+ iRet = wmt_core_init_script(set_crystal_timing_script, osal_array_size(set_crystal_timing_script)); -+ if (iRet) { -+ WMT_ERR_FUNC("set_crystal_timing_script fail(%d)\n", iRet); -+ iRet = -5; -+ } else { -+ WMT_DBG_FUNC("set crystal timing value (0x%x) succeed\n", WMT_SET_CRYSTAL_TRIMING_CMD[5]); -+ iRet = -+ wmt_core_init_script(get_crystal_timing_script, osal_array_size(get_crystal_timing_script)); -+ if (iRet) { -+ WMT_ERR_FUNC("get_crystal_timing_script fail(%d)\n", iRet); -+ iRet = -6; -+ } else { -+ WMT_INFO_FUNC("succeed, updated crystal timing value (0x%x)\n", -+ WMT_GET_CRYSTAL_TRIMING_EVT[5]); -+ iRet = 0x0; -+ } -+ } -+ } -+done: -+ return iRet; -+} -+#endif -+ -+#if CFG_WMT_MULTI_PATCH -+static INT32 mtk_wcn_soc_patch_info_prepare(VOID) -+{ -+ INT32 iRet = -1; -+ WMT_CTRL_DATA ctrlData; -+ -+ ctrlData.ctrlId = WMT_CTRL_PATCH_SEARCH; -+ iRet = wmt_ctrl(&ctrlData); -+ -+ return iRet; -+} -+ -+static INT32 mtk_wcn_soc_patch_dwn(UINT32 index) -+{ -+ INT32 iRet = -1; -+ P_WMT_PATCH patchHdr; -+ PUINT8 pbuf; -+ UINT32 patchSize; -+ UINT32 fragSeq; -+ UINT32 fragNum; -+ UINT16 fragSize = 0; -+ UINT16 cmdLen; -+ UINT32 offset; -+ UINT32 u4Res; -+ UINT8 evtBuf[8]; -+ UINT8 addressevtBuf[12]; -+ UINT8 addressByte[4]; -+ PINT8 cDataTime = NULL; -+ /*PINT8 cPlat = NULL; */ -+ UINT16 u2HwVer = 0; -+ UINT16 u2SwVer = 0; -+ UINT32 u4PatchVer = 0; -+ UINT32 patchSizePerFrag = 0; -+ WMT_CTRL_DATA ctrlData; -+ -+ /*1.check hardware information */ -+ if (NULL == gp_soc_info) { -+ WMT_ERR_FUNC("null gp_soc_info!\n"); -+ return -1; -+ } -+ -+ osal_memset(gFullPatchName, 0, osal_sizeof(gFullPatchName)); -+ -+ ctrlData.ctrlId = WMT_CTRL_GET_PATCH_INFO; -+ ctrlData.au4CtrlData[0] = index + 1; -+ ctrlData.au4CtrlData[1] = (SIZE_T) &gFullPatchName; -+ ctrlData.au4CtrlData[2] = (SIZE_T) &addressByte; -+ iRet = wmt_ctrl(&ctrlData); -+ WMT_DBG_FUNC("the %d time valid patch found: (%s)\n", index + 1, gFullPatchName); -+ -+ /* <2.2> read patch content */ -+ ctrlData.ctrlId = WMT_CTRL_GET_PATCH; -+ ctrlData.au4CtrlData[0] = (SIZE_T) NULL; -+ ctrlData.au4CtrlData[1] = (SIZE_T) &gFullPatchName; -+ ctrlData.au4CtrlData[2] = (SIZE_T) &pbuf; -+ ctrlData.au4CtrlData[3] = (SIZE_T) &patchSize; -+ iRet = wmt_ctrl(&ctrlData); -+ if (iRet) { -+ WMT_ERR_FUNC("wmt_core: WMT_CTRL_GET_PATCH fail:%d\n", iRet); -+ iRet -= 1; -+ goto done; -+ } -+ -+ /* |<-BCNT_PATCH_BUF_HEADROOM(8) bytes dummy allocated->|<-patch file->| */ -+ pbuf += BCNT_PATCH_BUF_HEADROOM; -+ /* patch file with header: -+ * |<-patch header: 28 Bytes->|<-patch body: X Bytes ----->| -+ */ -+ patchHdr = (P_WMT_PATCH) pbuf; -+ /* check patch file information */ -+ -+ cDataTime = patchHdr->ucDateTime; -+ u2HwVer = patchHdr->u2HwVer; -+ u2SwVer = patchHdr->u2SwVer; -+ u4PatchVer = patchHdr->u4PatchVer; -+ /*cPlat = &patchHdr->ucPLat[0]; */ -+ -+ cDataTime[15] = '\0'; -+ if (index == 0) { -+ WMT_DBG_FUNC("===========================================\n"); -+ WMT_INFO_FUNC("[Patch]BuiltTime = %s, HVer = 0x%x, SVer = 0x%x, PhVer = 0x%04x,Platform = %c%c%c%c\n", -+ cDataTime, ((u2HwVer & 0x00ff) << 8) | ((u2HwVer & 0xff00) >> 8), -+ ((u2SwVer & 0x00ff) << 8) | ((u2SwVer & 0xff00) >> 8), -+ ((u4PatchVer & 0xff000000) >> 24) | ((u4PatchVer & 0x00ff0000) >> 16), -+ patchHdr->ucPLat[0], patchHdr->ucPLat[1], patchHdr->ucPLat[2], patchHdr->ucPLat[3]); -+ WMT_DBG_FUNC("[Consys Patch] Hw Ver = 0x%x\n", ((u2HwVer & 0x00ff) << 8) | ((u2HwVer & 0xff00) >> 8)); -+ WMT_DBG_FUNC("[Consys Patch] Sw Ver = 0x%x\n", ((u2SwVer & 0x00ff) << 8) | ((u2SwVer & 0xff00) >> 8)); -+ WMT_DBG_FUNC("[Consys Patch] Ph Ver = 0x%04x\n", -+ ((u4PatchVer & 0xff000000) >> 24) | ((u4PatchVer & 0x00ff0000) >> 16)); -+ WMT_DBG_FUNC("[Consys Patch] Platform = %c%c%c%c\n", patchHdr->ucPLat[0], patchHdr->ucPLat[1], -+ patchHdr->ucPLat[2], patchHdr->ucPLat[3]); -+ WMT_DBG_FUNC("===========================================\n"); -+ } -+ -+ /* remove patch header: -+ * |<-patch body: X Bytes (X=patchSize)--->| -+ */ -+ patchSize -= sizeof(WMT_PATCH); -+ pbuf += sizeof(WMT_PATCH); -+ patchSizePerFrag = DEFAULT_PATCH_FRAG_SIZE; -+ /* reserve 1st patch cmd space before patch body -+ * |<-WMT_CMD: 5Bytes->|<-patch body: X Bytes (X=patchSize)----->| -+ */ -+ /* gp_soc_patch_info = patchHdr; */ -+ osal_memcpy(&gp_soc_patch_info, patchHdr, osal_sizeof(WMT_PATCH)); -+ pbuf -= sizeof(WMT_PATCH_CMD); -+ -+ fragNum = patchSize / patchSizePerFrag; -+ fragNum += ((fragNum * patchSizePerFrag) == patchSize) ? 0 : 1; -+ -+ WMT_DBG_FUNC("patch size(%d) fragNum(%d)\n", patchSize, fragNum); -+ -+ /*send wmt part patch address command */ -+ if (0x6752 == wmt_ic_ops_soc.icId || -+ 0x8127 == wmt_ic_ops_soc.icId || -+ 0x7623 == wmt_ic_ops_soc.icId || -+ 0x6571 == wmt_ic_ops_soc.icId || -+ 0x0326 == wmt_ic_ops_soc.icId || -+ 0x0321 == wmt_ic_ops_soc.icId || -+ 0x0335 == wmt_ic_ops_soc.icId || -+ 0x0337 == wmt_ic_ops_soc.icId || 0x8163 == wmt_ic_ops_soc.icId || 0x6580 == wmt_ic_ops_soc.icId) { -+ /* MT6571 patch RAM base */ -+ WMT_PATCH_ADDRESS_CMD[8] = 0x40; -+ WMT_PATCH_P_ADDRESS_CMD[8] = 0xc8; -+ } -+ /*send wmt part patch address command */ -+ if (0x0279 == wmt_ic_ops_soc.icId) { -+ /* MT6797 patch RAM base */ -+ WMT_PATCH_ADDRESS_CMD[8] = 0x08; -+ WMT_PATCH_ADDRESS_CMD[9] = 0x05; -+ WMT_PATCH_P_ADDRESS_CMD[8] = 0x2c; -+ WMT_PATCH_P_ADDRESS_CMD[9] = 0x0b; -+ } -+ -+ /*send wmt part patch address command */ -+ iRet = -+ wmt_core_tx((PUINT8) &WMT_PATCH_ADDRESS_CMD[0], sizeof(WMT_PATCH_ADDRESS_CMD), &u4Res, MTK_WCN_BOOL_FALSE); -+ if (iRet || (u4Res != sizeof(WMT_PATCH_ADDRESS_CMD))) { -+ WMT_ERR_FUNC("wmt_core:wmt patch address CMD fail(%d),size(%d)\n", iRet, u4Res); -+ iRet -= 1; -+ goto done; -+ } -+ osal_memset(addressevtBuf, 0, sizeof(addressevtBuf)); -+ iRet = wmt_core_rx(addressevtBuf, sizeof(WMT_PATCH_ADDRESS_EVT), &u4Res); -+ if (iRet || (u4Res != sizeof(WMT_PATCH_ADDRESS_EVT))) { -+ WMT_ERR_FUNC("wmt_core:wmt patch address EVT fail(%d),size(%d)\n", iRet, u4Res); -+ iRet -= 1; -+ goto done; -+ } -+#if CFG_CHECK_WMT_RESULT -+ if (osal_memcmp(addressevtBuf, WMT_PATCH_ADDRESS_EVT, osal_sizeof(WMT_PATCH_ADDRESS_EVT)) != 0) { -+ WMT_ERR_FUNC("wmt_core: write WMT_PATCH_ADDRESS_CMD status fail\n"); -+ iRet -= 1; -+ goto done; -+ } -+#endif -+ -+ /*send part patch address command */ -+ osal_memcpy(&WMT_PATCH_P_ADDRESS_CMD[12], addressByte, osal_sizeof(addressByte)); -+ WMT_DBG_FUNC("4 bytes address command:0x%02x,0x%02x,0x%02x,0x%02x", -+ WMT_PATCH_P_ADDRESS_CMD[12], -+ WMT_PATCH_P_ADDRESS_CMD[13], WMT_PATCH_P_ADDRESS_CMD[14], WMT_PATCH_P_ADDRESS_CMD[15]); -+ iRet = -+ wmt_core_tx((PUINT8) &WMT_PATCH_P_ADDRESS_CMD[0], sizeof(WMT_PATCH_P_ADDRESS_CMD), &u4Res, -+ MTK_WCN_BOOL_FALSE); -+ if (iRet || (u4Res != sizeof(WMT_PATCH_P_ADDRESS_CMD))) { -+ WMT_ERR_FUNC("wmt_core:wmt part patch address CMD fail(%d),size(%d),index(%d)\n", iRet, u4Res, index); -+ iRet -= 1; -+ goto done; -+ } -+ osal_memset(addressevtBuf, 0, sizeof(addressevtBuf)); -+ iRet = wmt_core_rx(addressevtBuf, sizeof(WMT_PATCH_P_ADDRESS_EVT), &u4Res); -+ if (iRet || (u4Res != sizeof(WMT_PATCH_P_ADDRESS_EVT))) { -+ WMT_ERR_FUNC("wmt_core:wmt patch address EVT fail(%d),size(%d),index(%d)\n", iRet, u4Res, index); -+ iRet -= 1; -+ goto done; -+ } -+#if CFG_CHECK_WMT_RESULT -+ if (osal_memcmp(addressevtBuf, WMT_PATCH_P_ADDRESS_EVT, osal_sizeof(WMT_PATCH_ADDRESS_EVT)) != 0) { -+ WMT_ERR_FUNC("wmt_core: write WMT_PATCH_ADDRESS_CMD status fail,index(%d)\n", index); -+ iRet -= 1; -+ goto done; -+ } -+#endif -+ -+ /* send all fragments */ -+ offset = sizeof(WMT_PATCH_CMD); -+ fragSeq = 0; -+ while (fragSeq < fragNum) { -+ WMT_DBG_FUNC("patch size(%d) fragNum(%d)\n", patchSize, fragNum); -+ if (fragSeq == (fragNum - 1)) { -+ /* last fragment */ -+ fragSize = patchSize - fragSeq * patchSizePerFrag; -+ WMT_PATCH_CMD[4] = WMT_PATCH_FRAG_LAST; -+ } else { -+ fragSize = patchSizePerFrag; -+ WMT_PATCH_CMD[4] = (fragSeq == 0) ? WMT_PATCH_FRAG_1ST : WMT_PATCH_FRAG_MID; -+ } -+ /* update length field in CMD:flag+frag */ -+ cmdLen = 1 + fragSize; -+ osal_memcpy(&WMT_PATCH_CMD[2], &cmdLen, 2); -+ /* copy patch CMD to buf (overwrite last 5-byte in prev frag) */ -+ osal_memcpy(pbuf + offset - sizeof(WMT_PATCH_CMD), WMT_PATCH_CMD, sizeof(WMT_PATCH_CMD)); -+ -+ /* iRet = -+ *(*kal_stp_tx)(pbuf + offset - sizeof(WMT_PATCH_CMD), fragSize + sizeof(WMT_PATCH_CMD), -+ *&u4Res); -+ */ -+ iRet = -+ wmt_core_tx(pbuf + offset - sizeof(WMT_PATCH_CMD), fragSize + sizeof(WMT_PATCH_CMD), -+ &u4Res, MTK_WCN_BOOL_FALSE); -+ if (iRet || (u4Res != fragSize + sizeof(WMT_PATCH_CMD))) { -+ WMT_ERR_FUNC("wmt_core: write fragSeq(%d) size(%d, %d) fail(%d)\n", fragSeq, -+ fragSize + sizeof(WMT_PATCH_CMD), u4Res, iRet); -+ iRet -= 1; -+ break; -+ } -+ WMT_DBG_FUNC("wmt_core: write fragSeq(%d) size(%d, %d) ok\n", -+ fragSeq, fragSize + sizeof(WMT_PATCH_CMD), u4Res); -+ -+ osal_memset(evtBuf, 0, sizeof(evtBuf)); -+ /* iRet = (*kal_stp_rx)(evtBuf, sizeof(WMT_PATCH_EVT), &u4Res); */ -+ iRet = wmt_core_rx(evtBuf, sizeof(WMT_PATCH_EVT), &u4Res); -+ if (iRet || (u4Res != sizeof(WMT_PATCH_EVT))) { -+ WMT_ERR_FUNC("wmt_core: read WMT_PATCH_EVT length(%d, %d) fail(%d)\n", sizeof(WMT_PATCH_EVT), -+ u4Res, iRet); -+ iRet -= 1; -+ break; -+ } -+#if CFG_CHECK_WMT_RESULT -+ if (osal_memcmp(evtBuf, WMT_PATCH_EVT, sizeof(WMT_PATCH_EVT)) != 0) { -+ WMT_ERR_FUNC("wmt_core: compare WMT_PATCH_EVT error rx(%d):[%02X,%02X,%02X,%02X,%02X]\n", -+ u4Res, -+ evtBuf[0], -+ evtBuf[1], -+ evtBuf[2], -+ evtBuf[3], -+ evtBuf[4]); -+ WMT_ERR_FUNC("wmt_core: exp(%d):[%02X,%02X,%02X,%02X,%02X]\n", -+ sizeof(WMT_PATCH_EVT), -+ WMT_PATCH_EVT[0], -+ WMT_PATCH_EVT[1], -+ WMT_PATCH_EVT[2], -+ WMT_PATCH_EVT[3], -+ WMT_PATCH_EVT[4]); -+ iRet -= 1; -+ break; -+ } -+#endif -+ WMT_DBG_FUNC("wmt_core: read WMT_PATCH_EVT length(%d, %d) ok\n", sizeof(WMT_PATCH_EVT), u4Res); -+ offset += patchSizePerFrag; -+ ++fragSeq; -+ } -+ -+ WMT_WARN_FUNC("wmt_core: patch dwn:%d frag(%d, %d) %s\n", -+ iRet, fragSeq, fragSize, (!iRet && (fragSeq == fragNum)) ? "ok" : "fail"); -+ -+ if (fragSeq != fragNum) -+ iRet -= 1; -+done: -+ /* WMT_CTRL_FREE_PATCH always return 0 */ -+ /* wmt_core_ctrl(WMT_CTRL_FREE_PATCH, NULL, NULL); */ -+ ctrlData.ctrlId = WMT_CTRL_FREE_PATCH; -+ ctrlData.au4CtrlData[0] = index + 1; -+ wmt_ctrl(&ctrlData); -+ -+ return iRet; -+} -+ -+#else -+static INT32 mtk_wcn_soc_patch_dwn(VOID) -+{ -+ INT32 iRet = -1; -+ P_WMT_PATCH patchHdr; -+ PUINT8 pbuf; -+ UINT32 patchSize; -+ UINT32 fragSeq; -+ UINT32 fragNum; -+ UINT16 fragSize = 0; -+ UINT16 cmdLen; -+ UINT32 offset; -+ UINT32 u4Res; -+ UINT8 evtBuf[8]; -+ PINT8 cDataTime = NULL; -+ /*PINT8 cPlat = NULL; */ -+ UINT16 u2HwVer = 0; -+ UINT16 u2SwVer = 0; -+ UINT32 u4PatchVer = 0; -+ UINT32 patchSizePerFrag = 0; -+ WMT_CTRL_DATA ctrlData; -+ -+ /*1.check hardware information */ -+ if (NULL == gp_soc_info) { -+ WMT_ERR_FUNC("null gp_soc_info!\n"); -+ return -1; -+ } -+ /* <2> search patch and read patch content */ -+ /* <2.1> search patch */ -+ ctrlData.ctrlId = WMT_CTRL_PATCH_SEARCH; -+ iRet = wmt_ctrl(&ctrlData); -+ if (0 == iRet) { -+ /* patch with correct Hw Ver Major Num found */ -+ ctrlData.ctrlId = WMT_CTRL_GET_PATCH_NAME; -+ ctrlData.au4CtrlData[0] = (UINT32) &gFullPatchName; -+ iRet = wmt_ctrl(&ctrlData); -+ -+ WMT_INFO_FUNC("valid patch found: (%s)\n", gFullPatchName); -+ /* <2.2> read patch content */ -+ ctrlData.ctrlId = WMT_CTRL_GET_PATCH; -+ ctrlData.au4CtrlData[0] = (UINT32) NULL; -+ ctrlData.au4CtrlData[1] = (UINT32) &gFullPatchName; -+ -+ } else { -+ iRet -= 1; -+ return iRet; -+ } -+ ctrlData.au4CtrlData[2] = (UINT32) &pbuf; -+ ctrlData.au4CtrlData[3] = (UINT32) &patchSize; -+ iRet = wmt_ctrl(&ctrlData); -+ if (iRet) { -+ WMT_ERR_FUNC("wmt_core: WMT_CTRL_GET_PATCH fail:%d\n", iRet); -+ iRet -= 1; -+ goto done; -+ } -+ -+ /* |<-BCNT_PATCH_BUF_HEADROOM(8) bytes dummy allocated->|<-patch file->| */ -+ pbuf += BCNT_PATCH_BUF_HEADROOM; -+ /* patch file with header: -+ * |<-patch header: 28 Bytes->|<-patch body: X Bytes ----->| -+ */ -+ patchHdr = (P_WMT_PATCH) pbuf; -+ /* check patch file information */ -+ -+ cDataTime = patchHdr->ucDateTime; -+ u2HwVer = patchHdr->u2HwVer; -+ u2SwVer = patchHdr->u2SwVer; -+ u4PatchVer = patchHdr->u4PatchVer; -+ /*cPlat = &patchHdr->ucPLat[0]; */ -+ -+ cDataTime[15] = '\0'; -+ WMT_DBG_FUNC("===========================================\n"); -+ WMT_INFO_FUNC("[ConsysPatch]BuiltTime = %s, HVer = 0x%x, SVer = 0x%x, PhVer = 0x%04x,Platform = %c%c%c%c\n", -+ cDataTime, ((u2HwVer & 0x00ff) << 8) | ((u2HwVer & 0xff00) >> 8), -+ ((u2SwVer & 0x00ff) << 8) | ((u2SwVer & 0xff00) >> 8), -+ ((u4PatchVer & 0xff000000) >> 24) | ((u4PatchVer & 0x00ff0000) >> 16), -+ patchHdr->ucPLat[0], patchHdr->ucPLat[1], patchHdr->ucPLat[2], patchHdr->ucPLat[3]); -+ WMT_DBG_FUNC("[Consys Patch] Hw Ver = 0x%x\n", ((u2HwVer & 0x00ff) << 8) | ((u2HwVer & 0xff00) >> 8)); -+ WMT_DBG_FUNC("[Consys Patch] Sw Ver = 0x%x\n", ((u2SwVer & 0x00ff) << 8) | ((u2SwVer & 0xff00) >> 8)); -+ WMT_DBG_FUNC("[Consys Patch] Ph Ver = 0x%04x\n", -+ ((u4PatchVer & 0xff000000) >> 24) | ((u4PatchVer & 0x00ff0000) >> 16)); -+ WMT_DBG_FUNC("[Consys Patch] Platform = %c%c%c%c\n", patchHdr->ucPLat[0], patchHdr->ucPLat[1], -+ patchHdr->ucPLat[2], patchHdr->ucPLat[3]); -+ WMT_DBG_FUNC("===========================================\n"); -+ -+ /* remove patch header: -+ * |<-patch body: X Bytes (X=patchSize)--->| -+ */ -+ patchSize -= sizeof(WMT_PATCH); -+ pbuf += sizeof(WMT_PATCH); -+ patchSizePerFrag = DEFAULT_PATCH_FRAG_SIZE; -+ /* reserve 1st patch cmd space before patch body -+ * |<-WMT_CMD: 5Bytes->|<-patch body: X Bytes (X=patchSize)----->| -+ */ -+ pbuf -= sizeof(WMT_PATCH_CMD); -+ -+ fragNum = patchSize / patchSizePerFrag; -+ fragNum += ((fragNum * patchSizePerFrag) == patchSize) ? 0 : 1; -+ -+ WMT_DBG_FUNC("patch size(%d) fragNum(%d)\n", patchSize, fragNum); -+ -+ /* send all fragments */ -+ offset = sizeof(WMT_PATCH_CMD); -+ fragSeq = 0; -+ while (fragSeq < fragNum) { -+ WMT_DBG_FUNC("patch size(%d) fragNum(%d)\n", patchSize, fragNum); -+ if (fragSeq == (fragNum - 1)) { -+ /* last fragment */ -+ fragSize = patchSize - fragSeq * patchSizePerFrag; -+ WMT_PATCH_CMD[4] = WMT_PATCH_FRAG_LAST; -+ } else { -+ fragSize = patchSizePerFrag; -+ WMT_PATCH_CMD[4] = (fragSeq == 0) ? WMT_PATCH_FRAG_1ST : WMT_PATCH_FRAG_MID; -+ } -+ /* update length field in CMD:flag+frag */ -+ cmdLen = 1 + fragSize; -+ osal_memcpy(&WMT_PATCH_CMD[2], &cmdLen, 2); -+ /* copy patch CMD to buf (overwrite last 5-byte in prev frag) */ -+ osal_memcpy(pbuf + offset - sizeof(WMT_PATCH_CMD), WMT_PATCH_CMD, sizeof(WMT_PATCH_CMD)); -+ -+ /* iRet = -+ * (*kal_stp_tx)(pbuf + offset - sizeof(WMT_PATCH_CMD), fragSize + sizeof(WMT_PATCH_CMD), -+ * &u4Res); -+ */ -+ iRet = -+ wmt_core_tx(pbuf + offset - sizeof(WMT_PATCH_CMD), fragSize + sizeof(WMT_PATCH_CMD), &u4Res, -+ MTK_WCN_BOOL_FALSE); -+ if (iRet || (u4Res != fragSize + sizeof(WMT_PATCH_CMD))) { -+ WMT_ERR_FUNC("wmt_core: write fragSeq(%d) size(%d, %d) fail(%d)\n", fragSeq, -+ fragSize + sizeof(WMT_PATCH_CMD), u4Res, iRet); -+ iRet -= 1; -+ break; -+ } -+ WMT_DBG_FUNC("wmt_core: write fragSeq(%d) size(%d, %d) ok\n", -+ fragSeq, fragSize + sizeof(WMT_PATCH_CMD), u4Res); -+ -+ osal_memset(evtBuf, 0, sizeof(evtBuf)); -+ /* iRet = (*kal_stp_rx)(evtBuf, sizeof(WMT_PATCH_EVT), &u4Res); */ -+ iRet = wmt_core_rx(evtBuf, sizeof(WMT_PATCH_EVT), &u4Res); -+ if (iRet || (u4Res != sizeof(WMT_PATCH_EVT))) { -+ WMT_ERR_FUNC("wmt_core: read WMT_PATCH_EVT length(%d, %d) fail(%d)\n", sizeof(WMT_PATCH_EVT), -+ u4Res, iRet); -+ iRet -= 1; -+ break; -+ } -+#if CFG_CHECK_WMT_RESULT -+ if (osal_memcmp(evtBuf, WMT_PATCH_EVT, sizeof(WMT_PATCH_EVT)) != 0) { -+ WMT_ERR_FUNC("wmt_core: compare WMT_PATCH_EVT error rx(%d):[%02X,%02X,%02X,%02X,%02X]\n", -+ u4Res, -+ evtBuf[0], -+ evtBuf[1], -+ evtBuf[2], -+ evtBuf[3], -+ evtBuf[4]); -+ WMT_ERR_FUNC("wmt_core: exp(%d):[%02X,%02X,%02X,%02X,%02X]\n", -+ sizeof(WMT_PATCH_EVT), -+ WMT_PATCH_EVT[0], -+ WMT_PATCH_EVT[1], -+ WMT_PATCH_EVT[2], -+ WMT_PATCH_EVT[3], -+ WMT_PATCH_EVT[4]); -+ iRet -= 1; -+ break; -+ } -+#endif -+ WMT_DBG_FUNC("wmt_core: read WMT_PATCH_EVT length(%d, %d) ok\n", sizeof(WMT_PATCH_EVT), u4Res); -+ offset += patchSizePerFrag; -+ ++fragSeq; -+ } -+ -+ WMT_WARN_FUNC("wmt_core: patch dwn:%d frag(%d, %d) %s\n", -+ iRet, fragSeq, fragSize, (!iRet && (fragSeq == fragNum)) ? "ok" : "fail"); -+ -+ if (fragSeq != fragNum) -+ iRet -= 1; -+done: -+ /* WMT_CTRL_FREE_PATCH always return 0 */ -+ wmt_core_ctrl(WMT_CTRL_FREE_PATCH, NULL, NULL); -+ -+ return iRet; -+} -+ -+#endif -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_lib.c b/drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_lib.c -new file mode 100644 -index 000000000000..747ed64af2d2 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/core/wmt_lib.c -@@ -0,0 +1,1938 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -+/*! \file -+ \brief Declaration of library functions -+ -+ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+#ifdef DFT_TAG -+#undef DFT_TAG -+#endif -+#define DFT_TAG "[WMT-LIB]" -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "osal_typedef.h" -+ -+#include "wmt_dev.h" -+#include "wmt_lib.h" -+#include "wmt_conf.h" -+#include "wmt_core.h" -+#include "wmt_plat.h" -+ -+#include "stp_core.h" -+#include "btm_core.h" -+#include "psm_core.h" -+#include "stp_dbg.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/* A table for translation: CMB_STUB_AIF_X=>WMT_IC_PIN_STATE */ -+static const WMT_IC_PIN_STATE cmb_aif2pin_stat[] = { -+ [CMB_STUB_AIF_0] = WMT_IC_AIF_0, -+ [CMB_STUB_AIF_1] = WMT_IC_AIF_1, -+ [CMB_STUB_AIF_2] = WMT_IC_AIF_2, -+ [CMB_STUB_AIF_3] = WMT_IC_AIF_3, -+}; -+ -+#if CFG_WMT_PS_SUPPORT -+static UINT32 gPsIdleTime = STP_PSM_IDLE_TIME_SLEEP; -+static UINT32 gPsEnable = 1; -+static PF_WMT_SDIO_PSOP sdio_own_ctrl; -+#endif -+ -+#define WMT_STP_CPUPCR_BUF_SIZE 6144 -+static UINT8 g_cpupcr_buf[WMT_STP_CPUPCR_BUF_SIZE] = { 0 }; -+ -+static UINT32 g_quick_sleep_ctrl = 1; -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+DEV_WMT gDevWmt; -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+#if CFG_WMT_PS_SUPPORT -+static MTK_WCN_BOOL wmt_lib_ps_action(MTKSTP_PSM_ACTION_T action); -+static MTK_WCN_BOOL wmt_lib_ps_do_sleep(VOID); -+static MTK_WCN_BOOL wmt_lib_ps_do_wakeup(VOID); -+static MTK_WCN_BOOL wmt_lib_ps_do_host_awake(VOID); -+static INT32 wmt_lib_ps_handler(MTKSTP_PSM_ACTION_T action); -+#endif -+ -+static MTK_WCN_BOOL wmt_lib_put_op(P_OSAL_OP_Q pOpQ, P_OSAL_OP pLxOp); -+ -+static P_OSAL_OP wmt_lib_get_op(P_OSAL_OP_Q pOpQ); -+ -+static INT32 wmtd_thread(PVOID pvData); -+ -+static INT32 wmt_lib_pin_ctrl(WMT_IC_PIN_ID id, WMT_IC_PIN_STATE stat, UINT32 flag); -+static MTK_WCN_BOOL wmt_lib_hw_state_show(VOID); -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+INT32 wmt_lib_idc_lock_aquire(VOID) -+{ -+ return osal_lock_sleepable_lock(&gDevWmt.idc_lock); -+} -+ -+VOID wmt_lib_idc_lock_release(VOID) -+{ -+ osal_unlock_sleepable_lock(&gDevWmt.idc_lock); -+} -+INT32 wmt_lib_psm_lock_aquire(void) -+{ -+ return osal_lock_sleepable_lock(&gDevWmt.psm_lock); -+} -+ -+void wmt_lib_psm_lock_release(void) -+{ -+ osal_unlock_sleepable_lock(&gDevWmt.psm_lock); -+} -+ -+INT32 DISABLE_PSM_MONITOR(void) -+{ -+ INT32 ret = 0; -+ -+ /* osal_lock_sleepable_lock(&gDevWmt.psm_lock); */ -+ ret = wmt_lib_psm_lock_aquire(); -+ if (ret) { -+ WMT_ERR_FUNC("--->lock psm_lock failed, ret=%d\n", ret); -+ return ret; -+ } -+#if CFG_WMT_PS_SUPPORT -+ ret = wmt_lib_ps_disable(); -+ if (ret) { -+ WMT_ERR_FUNC("wmt_lib_ps_disable fail, ret=%d\n", ret); -+ wmt_lib_psm_lock_release(); -+ } -+#endif -+ -+ return ret; -+} -+ -+void ENABLE_PSM_MONITOR(void) -+{ -+#if CFG_WMT_PS_SUPPORT -+ wmt_lib_ps_enable(); -+#endif -+ /* osal_unlock_sleepable_lock(&gDevWmt.psm_lock); */ -+ wmt_lib_psm_lock_release(); -+} -+ -+INT32 wmt_lib_init(VOID) -+{ -+ INT32 iRet; -+ UINT32 i; -+ P_DEV_WMT pDevWmt; -+ P_OSAL_THREAD pThraed; -+ -+ /* create->init->start */ -+ /* 1. create: static allocation with zero initialization */ -+ pDevWmt = &gDevWmt; -+ osal_memset(&gDevWmt, 0, sizeof(gDevWmt)); -+ -+ iRet = wmt_conf_read_file(); -+ if (iRet) { -+ WMT_ERR_FUNC("read wmt config file fail(%d)\n", iRet); -+ return -1; -+ } -+ -+ pThraed = &gDevWmt.thread; -+ -+ /* Create mtk_wmtd thread */ -+ osal_strncpy(pThraed->threadName, "mtk_wmtd", sizeof(pThraed->threadName)); -+ pThraed->pThreadData = (VOID *) pDevWmt; -+ pThraed->pThreadFunc = (VOID *) wmtd_thread; -+ iRet = osal_thread_create(pThraed); -+ if (iRet) { -+ WMT_ERR_FUNC("osal_thread_create(0x%p) fail(%d)\n", pThraed, iRet); -+ return -2; -+ } -+ -+ /* 2. initialize */ -+ /* Initialize wmt_core */ -+ -+ iRet = wmt_core_init(); -+ if (iRet) { -+ WMT_ERR_FUNC("wmt_core_init() fail(%d)\n", iRet); -+ return -1; -+ } -+ -+ /* Initialize WMTd Thread Information: Thread */ -+ osal_event_init(&pDevWmt->rWmtdWq); -+ osal_sleepable_lock_init(&pDevWmt->psm_lock); -+ osal_sleepable_lock_init(&pDevWmt->idc_lock); -+ osal_sleepable_lock_init(&pDevWmt->rActiveOpQ.sLock); -+ osal_sleepable_lock_init(&pDevWmt->rFreeOpQ.sLock); -+ pDevWmt->state.data = 0; -+ -+ /* Initialize op queue */ -+ RB_INIT(&pDevWmt->rFreeOpQ, WMT_OP_BUF_SIZE); -+ RB_INIT(&pDevWmt->rActiveOpQ, WMT_OP_BUF_SIZE); -+ /* Put all to free Q */ -+ for (i = 0; i < WMT_OP_BUF_SIZE; i++) { -+ osal_signal_init(&(pDevWmt->arQue[i].signal)); -+ wmt_lib_put_op(&pDevWmt->rFreeOpQ, &(pDevWmt->arQue[i])); -+ } -+ -+ /* initialize stp resources */ -+ osal_event_init(&pDevWmt->rWmtRxWq); -+ -+ /*function driver callback */ -+ for (i = 0; i < WMTDRV_TYPE_WIFI; i++) -+ pDevWmt->rFdrvCb.fDrvRst[i] = NULL; -+ -+ pDevWmt->hw_ver = WMTHWVER_MAX; -+ WMT_INFO_FUNC("***********Init, hw->ver = %x\n", pDevWmt->hw_ver); -+ -+ /* TODO:[FixMe][GeorgeKuo]: wmt_lib_conf_init */ -+ /* initialize default configurations */ -+ /* i4Result = wmt_lib_conf_init(VOID); */ -+ /* WMT_WARN_FUNC("wmt_drv_conf_init(%d)\n", i4Result); */ -+ -+ osal_signal_init(&pDevWmt->cmdResp); -+ osal_event_init(&pDevWmt->cmdReq); -+ -+ /* initialize platform resources */ -+ if (0 != gDevWmt.rWmtGenConf.cfgExist) -+ iRet = wmt_plat_init(gDevWmt.rWmtGenConf.co_clock_flag & 0x0f); -+ else -+ iRet = wmt_plat_init(0); -+ -+ if (iRet) { -+ WMT_ERR_FUNC("wmt_plat_init() fail(%d)\n", iRet); -+ return -3; -+ } -+#if CFG_WMT_PS_SUPPORT -+ iRet = wmt_lib_ps_init(); -+ if (iRet) { -+ WMT_ERR_FUNC("wmt_lib_ps_init() fail(%d)\n", iRet); -+ return -4; -+ } -+#endif -+ -+ /* 3. start: start running mtk_wmtd */ -+ iRet = osal_thread_run(pThraed); -+ if (iRet) { -+ WMT_ERR_FUNC("osal_thread_run(0x%p) fail(%d)\n", pThraed, iRet); -+ return -5; -+ } -+ -+ /*4. register irq callback to WMT-PLAT */ -+ wmt_plat_irq_cb_reg(wmt_lib_ps_irq_cb); -+ -+ /*5. register audio if control callback to WMT-PLAT */ -+ wmt_plat_aif_cb_reg(wmt_lib_set_aif); -+ -+ /*6. register function control callback to WMT-PLAT */ -+ wmt_plat_func_ctrl_cb_reg(mtk_wcn_wmt_func_ctrl_for_plat); -+ -+ wmt_plat_deep_idle_ctrl_cb_reg(mtk_wcn_consys_stp_btif_dpidle_ctrl); -+ /*7 reset gps/bt state */ -+ -+ mtk_wcn_wmt_system_state_reset(); -+ -+#ifdef MTK_WCN_WMT_STP_EXP_SYMBOL_ABSTRACT -+ mtk_wcn_wmt_exp_init(); -+#endif -+ -+#if CFG_WMT_LTE_COEX_HANDLING -+ wmt_idc_init(); -+#endif -+ WMT_DBG_FUNC("init success\n"); -+ return 0; -+} -+ -+INT32 wmt_lib_deinit(VOID) -+{ -+ INT32 iRet; -+ P_DEV_WMT pDevWmt; -+ P_OSAL_THREAD pThraed; -+ INT32 i; -+ INT32 iResult; -+ -+ pDevWmt = &gDevWmt; -+ pThraed = &gDevWmt.thread; -+ iResult = 0; -+ -+ /* stop->deinit->destroy */ -+ -+ /* 1. stop: stop running mtk_wmtd */ -+ iRet = osal_thread_stop(pThraed); -+ if (iRet) { -+ WMT_ERR_FUNC("osal_thread_stop(0x%p) fail(%d)\n", pThraed, iRet); -+ iResult += 1; -+ } -+ -+ /* 2. deinit: */ -+ -+#if CFG_WMT_PS_SUPPORT -+ iRet = wmt_lib_ps_deinit(); -+ if (iRet) { -+ WMT_ERR_FUNC("wmt_lib_ps_deinit fail(%d)\n", iRet); -+ iResult += 2; -+ } -+#endif -+ -+ iRet = wmt_plat_deinit(); -+ if (iRet) { -+ WMT_ERR_FUNC("wmt_plat_deinit fail(%d)\n", iRet); -+ iResult += 4; -+ } -+ -+ osal_event_deinit(&pDevWmt->cmdReq); -+ osal_signal_deinit(&pDevWmt->cmdResp); -+ -+ /* de-initialize stp resources */ -+ osal_event_deinit(&pDevWmt->rWmtRxWq); -+ -+ for (i = 0; i < WMT_OP_BUF_SIZE; i++) -+ osal_signal_deinit(&(pDevWmt->arQue[i].signal)); -+ -+ -+ osal_sleepable_lock_deinit(&pDevWmt->rFreeOpQ.sLock); -+ osal_sleepable_lock_deinit(&pDevWmt->rActiveOpQ.sLock); -+ osal_sleepable_lock_deinit(&pDevWmt->idc_lock); -+ osal_sleepable_lock_deinit(&pDevWmt->psm_lock); -+ osal_event_deinit(&pDevWmt->rWmtdWq); -+ -+ iRet = wmt_core_deinit(); -+ if (iRet) { -+ WMT_ERR_FUNC("wmt_core_deinit fail(%d)\n", iRet); -+ iResult += 8; -+ } -+ -+ /* 3. destroy */ -+ iRet = osal_thread_destroy(pThraed); -+ if (iRet) { -+ WMT_ERR_FUNC("osal_thread_stop(0x%p) fail(%d)\n", pThraed, iRet); -+ iResult += 16; -+ } -+ osal_memset(&gDevWmt, 0, sizeof(gDevWmt)); -+ -+#ifdef MTK_WCN_WMT_STP_EXP_SYMBOL_ABSTRACT -+ mtk_wcn_wmt_exp_deinit(); -+#endif -+ -+#if CFG_WMT_LTE_COEX_HANDLING -+ wmt_idc_deinit(); -+#endif -+ -+ return iResult; -+} -+ -+VOID wmt_lib_flush_rx(VOID) -+{ -+ mtk_wcn_stp_flush_rx_queue(WMT_TASK_INDX); -+} -+ -+INT32 wmt_lib_trigger_cmd_signal(INT32 result) -+{ -+ P_OSAL_SIGNAL pSignal = &gDevWmt.cmdResp; -+ -+ gDevWmt.cmdResult = result; -+ osal_raise_signal(pSignal); -+ WMT_DBG_FUNC("wakeup cmdResp\n"); -+ return 0; -+} -+ -+P_OSAL_EVENT wmt_lib_get_cmd_event(VOID) -+{ -+ return &gDevWmt.cmdReq; -+} -+ -+INT32 wmt_lib_set_patch_name(PUINT8 cPatchName) -+{ -+ osal_strncpy(gDevWmt.cPatchName, cPatchName, NAME_MAX); -+ return 0; -+} -+ -+INT32 wmt_lib_set_hif(unsigned long hifconf) -+{ -+ UINT32 val; -+ P_WMT_HIF_CONF pHif = &gDevWmt.rWmtHifConf; -+ -+ val = hifconf & 0xF; -+ if (STP_UART_FULL == val) { -+ pHif->hifType = WMT_HIF_UART; -+ val = (hifconf >> 8); -+ pHif->au4HifConf[0] = val; -+ pHif->au4HifConf[1] = val; -+ mtk_wcn_stp_set_if_tx_type(STP_UART_IF_TX); -+ } else if (STP_SDIO == val) { -+ pHif->hifType = WMT_HIF_SDIO; -+ mtk_wcn_stp_set_if_tx_type(STP_SDIO_IF_TX); -+ } else if (STP_BTIF_FULL == val) { -+ pHif->hifType = WMT_HIF_BTIF; -+ mtk_wcn_stp_set_if_tx_type(STP_BTIF_IF_TX); -+ } else { -+ WMT_WARN_FUNC("invalid stp mode: %u\n", val); -+ mtk_wcn_stp_set_if_tx_type(STP_MAX_IF_TX); -+ return -1; -+ } -+ -+ val = (hifconf & 0xF0) >> 4; -+ if (WMT_FM_COMM == val) { -+ pHif->au4StrapConf[0] = WMT_FM_COMM; -+ } else if (WMT_FM_I2C == val) { -+ pHif->au4StrapConf[0] = WMT_FM_I2C; -+ } else { -+ WMT_WARN_FUNC("invalid fm mode: %u\n", val); -+ return -2; -+ } -+ -+ WMT_WARN_FUNC("new hifType: %d, fm:%d\n", pHif->hifType, pHif->au4StrapConf[0]); -+ return 0; -+} -+ -+P_WMT_HIF_CONF wmt_lib_get_hif(VOID) -+{ -+ return &gDevWmt.rWmtHifConf; -+} -+ -+PUINT8 wmt_lib_get_cmd(VOID) -+{ -+ if (osal_test_and_clear_bit(WMT_STAT_CMD, &gDevWmt.state)) -+ return gDevWmt.cCmd; -+ -+ return NULL; -+} -+ -+MTK_WCN_BOOL wmt_lib_get_cmd_status(VOID) -+{ -+ return osal_test_bit(WMT_STAT_CMD, &gDevWmt.state) ? MTK_WCN_BOOL_TRUE : MTK_WCN_BOOL_FALSE; -+} -+ -+#if CFG_WMT_PS_SUPPORT -+INT32 wmt_lib_ps_set_idle_time(UINT32 psIdleTime) -+{ -+ gPsIdleTime = psIdleTime; -+ return gPsIdleTime; -+} -+ -+INT32 wmt_lib_ps_ctrl(UINT32 state) -+{ -+ if (0 == state) { -+ wmt_lib_ps_disable(); -+ gPsEnable = 0; -+ } else { -+ gPsEnable = 1; -+ wmt_lib_ps_enable(); -+ } -+ return 0; -+} -+ -+INT32 wmt_lib_ps_enable(VOID) -+{ -+ if (gPsEnable) -+ mtk_wcn_stp_psm_enable(gPsIdleTime); -+ -+ return 0; -+} -+ -+INT32 wmt_lib_ps_disable(VOID) -+{ -+ if (gPsEnable) -+ return mtk_wcn_stp_psm_disable(); -+ -+ return 0; -+} -+ -+INT32 wmt_lib_ps_init(VOID) -+{ -+ /* mtk_wcn_stp_psm_register_wmt_cb(wmt_lib_ps_stp_cb); */ -+ return 0; -+} -+ -+INT32 wmt_lib_ps_deinit(VOID) -+{ -+ /* mtk_wcn_stp_psm_unregister_wmt_cb(); */ -+ return 0; -+} -+ -+static MTK_WCN_BOOL wmt_lib_ps_action(MTKSTP_PSM_ACTION_T action) -+{ -+ P_OSAL_OP lxop; -+ MTK_WCN_BOOL bRet; -+ UINT32 u4Wait; -+ P_OSAL_SIGNAL pSignal; -+ -+ lxop = wmt_lib_get_free_op(); -+ if (!lxop) { -+ WMT_WARN_FUNC("get_free_lxop fail\n"); -+ return MTK_WCN_BOOL_FALSE; -+ } -+ pSignal = &lxop->signal; -+ pSignal->timeoutValue = 0; -+ lxop->op.opId = WMT_OPID_PWR_SV; -+ lxop->op.au4OpData[0] = action; -+ lxop->op.au4OpData[1] = (SIZE_T) mtk_wcn_stp_psm_notify_stp; -+ u4Wait = 0; -+ bRet = wmt_lib_put_act_op(lxop); -+ return bRet; -+} -+ -+#if CFG_WMT_LTE_COEX_HANDLING -+MTK_WCN_BOOL wmt_lib_handle_idc_msg(ipc_ilm_t *idc_infor) -+{ -+ P_OSAL_OP lxop; -+ MTK_WCN_BOOL bRet = MTK_WCN_BOOL_FALSE; -+ P_OSAL_SIGNAL pSignal; -+ INT32 ret = 0; -+ UINT16 msg_len = 0; -+ static UINT8 msg_local_buffer[1300]; -+#if CFG_WMT_LTE_ENABLE_MSGID_MAPPING -+ MTK_WCN_BOOL unknown_msgid = MTK_WCN_BOOL_FALSE; -+#endif -+ WMT_DBG_FUNC("idc_infor from conn_md is 0x%p\n", idc_infor); -+ ret = wmt_lib_idc_lock_aquire(); -+ if (ret) { -+ WMT_ERR_FUNC("--->lock idc_lock failed, ret=%d\n", ret); -+ return MTK_WCN_BOOL_FALSE; -+ } -+ msg_len = idc_infor->local_para_ptr->msg_len - osal_sizeof(local_para_struct); -+ osal_memcpy(&msg_local_buffer[0], &msg_len, osal_sizeof(msg_len)); -+ osal_memcpy(&msg_local_buffer[osal_sizeof(msg_len)], -+ &(idc_infor->local_para_ptr->data[0]), msg_len - 1); -+ wmt_lib_idc_lock_release(); -+ lxop = wmt_lib_get_free_op(); -+ if (!lxop) { -+ WMT_WARN_FUNC("get_free_lxop fail\n"); -+ return MTK_WCN_BOOL_FALSE; -+ } -+ pSignal = &lxop->signal; -+ pSignal->timeoutValue = MAX_EACH_WMT_CMD; -+ lxop->op.opId = WMT_OPID_IDC_MSG_HANDLING; -+ lxop->op.au4OpData[0] = (size_t) msg_local_buffer; -+ /*msg opcode fill rule is still not clrear,need scott comment */ -+ /***********************************************************/ -+ WMT_DBG_FUNC("ilm msg id is (0x%08x)\n", idc_infor->msg_id); -+ -+#if CFG_WMT_LTE_ENABLE_MSGID_MAPPING -+ switch (idc_infor->msg_id) { -+ case IPC_MSG_ID_EL1_LTE_DEFAULT_PARAM_IND: -+ lxop->op.au4OpData[1] = WMT_IDC_TX_OPCODE_LTE_PARA; -+ break; -+ case IPC_MSG_ID_EL1_LTE_OPER_FREQ_PARAM_IND: -+ lxop->op.au4OpData[1] = WMT_IDC_TX_OPCODE_LTE_FREQ; -+ break; -+ case IPC_MSG_ID_EL1_WIFI_MAX_PWR_IND: -+ lxop->op.au4OpData[1] = WMT_IDC_TX_OPCODE_WIFI_MAX_POWER; -+ break; -+ case IPC_MSG_ID_EL1_LTE_TX_IND: -+ lxop->op.au4OpData[1] = WMT_IDC_TX_OPCODE_LTE_INDICATION; -+ break; -+ case IPC_MSG_ID_EL1_LTE_CONNECTION_STATUS_IND: -+ lxop->op.au4OpData[1] = WMT_IDC_TX_OPCODE_LTE_CONNECTION_STAS; -+ break; -+ default: -+ unknown_msgid = MTK_WCN_BOOL_TRUE; -+ break; -+ } -+ -+ if (MTK_WCN_BOOL_FALSE == unknown_msgid) { -+ /*wake up chip first */ -+ if (DISABLE_PSM_MONITOR()) { -+ WMT_ERR_FUNC("wake up failed\n"); -+ wmt_lib_put_op_to_free_queue(lxop); -+ return MTK_WCN_BOOL_FALSE; -+ } -+ -+ bRet = wmt_lib_put_act_op(lxop); -+ ENABLE_PSM_MONITOR(); -+ if (MTK_WCN_BOOL_FALSE == bRet) -+ WMT_WARN_FUNC("WMT_OPID_IDC_MSG_HANDLING fail(%d)\n", bRet); -+ else -+ WMT_DBG_FUNC("OPID(%d) type(%d) ok\n", lxop->op.opId, lxop->op.au4OpData[1]); -+ } else { -+ bRet = MTK_WCN_BOOL_FALSE; -+ wmt_lib_put_op_to_free_queue(lxop); -+ WMT_ERR_FUNC("unknown msgid from LTE(%d)\n", idc_infor->msg_id); -+ } -+#else -+ if ((idc_infor->msg_id >= IPC_EL1_MSG_ID_BEGIN) -+ && (idc_infor->msg_id <= IPC_EL1_MSG_ID_BEGIN + IPC_EL1_MSG_ID_RANGE)) { -+ lxop->op.au4OpData[1] = idc_infor->msg_id - IPC_EL1_MSG_ID_BEGIN + LTE_MSG_ID_OFFSET - 1; -+ -+ WMT_DBG_FUNC("LTE->CONN:(0x%x->0x%zx)\n", idc_infor->msg_id, lxop->op.au4OpData[1]); -+ /*wake up chip first */ -+ if (DISABLE_PSM_MONITOR()) { -+ WMT_ERR_FUNC("wake up failed\n"); -+ wmt_lib_put_op_to_free_queue(lxop); -+ return MTK_WCN_BOOL_FALSE; -+ } -+ -+ bRet = wmt_lib_put_act_op(lxop); -+ ENABLE_PSM_MONITOR(); -+ if (MTK_WCN_BOOL_FALSE == bRet) { -+ WMT_WARN_FUNC("WMT_OPID_IDC_MSG_HANDLING fail(%d)\n", bRet); -+ } else { -+ WMT_DBG_FUNC("wmt_lib_handle_idc_msg OPID(%d) type(%d) ok\n", -+ lxop->op.opId, lxop->op.au4OpData[1]); -+ } -+ } else { -+ wmt_lib_put_op_to_free_queue(lxop); -+ WMT_ERR_FUNC("msgid(%d) out of range,wmt drop it!\n", idc_infor->msg_id); -+ } -+#endif -+ -+ return bRet; -+} -+#endif -+ -+static MTK_WCN_BOOL wmt_lib_ps_do_sleep(VOID) -+{ -+ return wmt_lib_ps_action(SLEEP); -+} -+ -+static MTK_WCN_BOOL wmt_lib_ps_do_wakeup(VOID) -+{ -+ return wmt_lib_ps_action(WAKEUP); -+} -+ -+static MTK_WCN_BOOL wmt_lib_ps_do_host_awake(VOID) -+{ -+#if 1 -+ return wmt_lib_ps_action(WAKEUP); -+#else -+ return wmt_lib_ps_action(HOST_AWAKE); -+#endif -+} -+ -+/* extern int g_block_tx; */ -+static INT32 wmt_lib_ps_handler(MTKSTP_PSM_ACTION_T action) -+{ -+ INT32 ret; -+ -+ ret = 0; /* TODO:[FixMe][George] initial value or compile warning? */ -+ /* if(g_block_tx && (action == SLEEP)) */ -+ if ((0 != mtk_wcn_stp_coredump_start_get()) && (action == SLEEP)) { -+ mtk_wcn_stp_psm_notify_stp(SLEEP); -+ return ret; -+ } -+ -+ /*MT662x Not Ready */ -+ if (!mtk_wcn_stp_is_ready()) { -+ WMT_DBG_FUNC("MT662x Not Ready, Dont Send Sleep/Wakeup Command\n"); -+ mtk_wcn_stp_psm_notify_stp(ROLL_BACK); -+ return 0; -+ } -+ -+ if (SLEEP == action) { -+ WMT_DBG_FUNC("send op-----------> sleep job\n"); -+ -+ if (!mtk_wcn_stp_is_sdio_mode()) { -+ ret = wmt_lib_ps_do_sleep(); -+ WMT_DBG_FUNC("enable host eirq\n"); -+ wmt_plat_eirq_ctrl(PIN_BGF_EINT, PIN_STA_EINT_EN); -+#if CFG_WMT_DUMP_INT_STATUS -+ if (MTK_WCN_BOOL_TRUE == wmt_plat_dump_BGF_irq_status()) -+ wmt_plat_BGF_irq_dump_status(); -+#endif -+ } else { -+ /* ret = mtk_wcn_stp_sdio_do_own_set(); */ -+ if (sdio_own_ctrl) { -+ ret = (*sdio_own_ctrl) (OWN_SET); -+ } else { -+ WMT_ERR_FUNC("sdio_own_ctrl is not registered\n"); -+ ret = -1; -+ } -+ -+ if (!ret) { -+ mtk_wcn_stp_psm_notify_stp(SLEEP); -+ } else if (ret == -2) { -+ mtk_wcn_stp_psm_notify_stp(ROLL_BACK); -+ WMT_WARN_FUNC("===[SDIO-PS] rollback due to tx busy===%%\n"); -+ } else { -+ mtk_wcn_stp_psm_notify_stp(SLEEP); -+ WMT_ERR_FUNC("===[SDIO-PS] set own fails!===%%\n"); -+ } -+ } -+ -+ WMT_DBG_FUNC("send op<---------- sleep job\n"); -+ } else if (WAKEUP == action) { -+ WMT_DBG_FUNC("send op --------> wake job\n"); -+ -+ if (!mtk_wcn_stp_is_sdio_mode()) { -+ WMT_DBG_FUNC("disable host eirq\n"); -+#if CFG_WMT_DUMP_INT_STATUS -+ if (MTK_WCN_BOOL_TRUE == wmt_plat_dump_BGF_irq_status()) -+ wmt_plat_BGF_irq_dump_status(); -+#endif -+ wmt_plat_eirq_ctrl(PIN_BGF_EINT, PIN_STA_EINT_DIS); -+ ret = wmt_lib_ps_do_wakeup(); -+ } else { -+ /* ret = mtk_wcn_stp_sdio_do_own_clr(); */ -+ -+ if (sdio_own_ctrl) { -+ ret = (*sdio_own_ctrl) (OWN_CLR); -+ } else { -+ WMT_ERR_FUNC("sdio_own_ctrl is not registered\n"); -+ ret = -1; -+ } -+ -+ if (!ret) { -+ mtk_wcn_stp_psm_notify_stp(WAKEUP); -+ } else { -+ mtk_wcn_stp_psm_notify_stp(WAKEUP); -+ WMT_ERR_FUNC("===[SDIO-PS] set own back fails!===%%\n"); -+ } -+ } -+ -+ WMT_DBG_FUNC("send op<---------- wake job\n"); -+ } else if (HOST_AWAKE == action) { -+ WMT_DBG_FUNC("send op-----------> host awake job\n"); -+ -+ if (!mtk_wcn_stp_is_sdio_mode()) { -+ WMT_DBG_FUNC("disable host eirq\n"); -+ /* IRQ already disabled */ -+ /* wmt_plat_eirq_ctrl(PIN_BGF_EINT, PIN_STA_EINT_DIS); */ -+#if 0 -+ if (MTK_WCN_BOOL_TRUE == wmt_plat_dump_BGF_irq_status()) -+ wmt_plat_BGF_irq_dump_status(); -+#endif -+ ret = wmt_lib_ps_do_host_awake(); -+ } else { -+ WMT_DBG_FUNC("[SDIO-PS] SDIO host awake! ####\n"); -+ -+ /* ret = mtk_wcn_stp_sdio_do_own_clr(); */ -+ -+ if (sdio_own_ctrl) { -+ ret = (*sdio_own_ctrl) (OWN_CLR); -+ } else { -+ WMT_ERR_FUNC("sdio_own_ctrl is not registered\n"); -+ ret = -1; -+ } -+ -+ /* Here we set ret to 0 directly */ -+ ret = 0; -+ if (!ret) { -+ mtk_wcn_stp_psm_notify_stp(HOST_AWAKE); -+ } else { -+ mtk_wcn_stp_psm_notify_stp(HOST_AWAKE); -+ WMT_ERR_FUNC("===[SDIO-PS]set own back fails!===%%\n"); -+ } -+ } -+ -+ WMT_DBG_FUNC("send op<----------- host awake job\n"); -+ } else if (EIRQ == action) { -+ WMT_DBG_FUNC("send op -------------> eirq job\n"); -+ -+ if (!mtk_wcn_stp_is_sdio_mode()) { -+ WMT_DBG_FUNC("disable host eirq\n"); -+ /* Disable interrupt */ -+ /* wmt_plat_eirq_ctrl(PIN_BGF_EINT, PIN_STA_EINT_DIS); */ -+ ret = mtk_wcn_stp_psm_notify_stp(EIRQ); -+ } else { -+ WMT_ERR_FUNC("[SDIO-PS]sdio own-back eirq!######\n"); -+ ret = mtk_wcn_stp_psm_notify_stp(EIRQ); -+ } -+ -+ WMT_DBG_FUNC("send op<----------- eirq job\n"); -+ } -+ -+ return ret; -+} -+#endif /* end of CFG_WMT_PS_SUPPORT */ -+ -+INT32 wmt_lib_ps_stp_cb(MTKSTP_PSM_ACTION_T action) -+{ -+#if CFG_WMT_PS_SUPPORT -+ return wmt_lib_ps_handler(action); -+#else -+ WMT_WARN_FUNC("CFG_WMT_PS_SUPPORT is not set\n"); -+ return 0; -+#endif -+} -+ -+MTK_WCN_BOOL wmt_lib_is_quick_ps_support(VOID) -+{ -+ if ((g_quick_sleep_ctrl) && (wmt_dev_get_early_suspend_state() == MTK_WCN_BOOL_TRUE)) -+ return wmt_core_is_quick_ps_support(); -+ else -+ return MTK_WCN_BOOL_FALSE; -+} -+ -+VOID wmt_lib_ps_irq_cb(VOID) -+{ -+#if CFG_WMT_PS_SUPPORT -+ wmt_lib_ps_handler(EIRQ); -+#else -+ WMT_DBG_FUNC("CFG_WMT_PS_SUPPORT is not set\n"); -+ return; -+#endif -+} -+ -+VOID wmt_lib_ps_set_sdio_psop(PF_WMT_SDIO_PSOP own_cb) -+{ -+#if CFG_WMT_PS_SUPPORT -+ sdio_own_ctrl = own_cb; -+#endif -+} -+ -+UINT32 wmt_lib_wait_event_checker(P_OSAL_THREAD pThread) -+{ -+ P_DEV_WMT pDevWmt; -+ -+ if (pThread) { -+ pDevWmt = (P_DEV_WMT) (pThread->pThreadData); -+ return !RB_EMPTY(&pDevWmt->rActiveOpQ); -+ } -+ WMT_ERR_FUNC("pThread(NULL)\n"); -+ return 0; -+} -+ -+static INT32 wmtd_thread(void *pvData) -+{ -+ P_DEV_WMT pWmtDev = (P_DEV_WMT) pvData; -+ P_OSAL_EVENT pEvent = NULL; -+ P_OSAL_OP pOp; -+ INT32 iResult; -+ -+ if (NULL == pWmtDev) { -+ WMT_ERR_FUNC("pWmtDev(NULL)\n"); -+ return -1; -+ } -+ WMT_INFO_FUNC("wmtd thread starts\n"); -+ -+ pEvent = &(pWmtDev->rWmtdWq); -+ -+ for (;;) { -+ pOp = NULL; -+ pEvent->timeoutValue = 0; -+/* osal_thread_wait_for_event(&pWmtDev->thread, pEvent);*/ -+ osal_thread_wait_for_event(&pWmtDev->thread, pEvent, wmt_lib_wait_event_checker); -+ -+ if (osal_thread_should_stop(&pWmtDev->thread)) { -+ WMT_INFO_FUNC("wmtd thread should stop now...\n"); -+ /* TODO: clean up active opQ */ -+ break; -+ } -+ -+ /* get Op from activeQ */ -+ pOp = wmt_lib_get_op(&pWmtDev->rActiveOpQ); -+ if (!pOp) { -+ WMT_WARN_FUNC("get_lxop activeQ fail\n"); -+ continue; -+ } -+#if 0 /* wmt_core_opid_handler will do sanity check on opId, so no usage here */ -+ id = lxop_get_opid(pLxOp); -+ if (id >= WMT_OPID_MAX) { -+ WMT_WARN_FUNC("abnormal opid id: 0x%x\n", id); -+ iResult = -1; -+ goto handlerDone; -+ } -+#endif -+ -+ if (osal_test_bit(WMT_STAT_RST_ON, &pWmtDev->state)) { -+ /* when whole chip reset, only HW RST and SW RST cmd can execute */ -+ if ((pOp->op.opId == WMT_OPID_HW_RST) || (pOp->op.opId == WMT_OPID_SW_RST) -+ || (pOp->op.opId == WMT_OPID_GPIO_STATE)) { -+ iResult = wmt_core_opid(&pOp->op); -+ } else { -+ iResult = -2; -+ WMT_WARN_FUNC("Whole chip resetting, opid (%d) failed, iRet(%d)\n", pOp->op.opId, -+ iResult); -+ } -+ } else { -+ wmt_lib_set_current_op(pWmtDev, pOp); -+ iResult = wmt_core_opid(&pOp->op); -+ wmt_lib_set_current_op(pWmtDev, NULL); -+ } -+ -+ if (iResult) -+ WMT_WARN_FUNC("opid (%d) failed, iRet(%d)\n", pOp->op.opId, iResult); -+ -+ if (osal_op_is_wait_for_signal(pOp)) { -+ osal_op_raise_signal(pOp, iResult); -+ } else { -+ /* put Op back to freeQ */ -+ wmt_lib_put_op(&pWmtDev->rFreeOpQ, pOp); -+ } -+ -+ if (WMT_OPID_EXIT == pOp->op.opId) { -+ WMT_INFO_FUNC("wmtd thread received exit signal\n"); -+ break; -+ } -+ } -+ -+ WMT_INFO_FUNC("wmtd thread exits succeed\n"); -+ -+ return 0; -+}; -+ -+static MTK_WCN_BOOL wmt_lib_put_op(P_OSAL_OP_Q pOpQ, P_OSAL_OP pOp) -+{ -+ INT32 iRet; -+ -+ if (!pOpQ || !pOp) { -+ WMT_WARN_FUNC("invalid input param: pOpQ(0x%p), pLxOp(0x%p)\n", pOpQ, pOp); -+ osal_assert(pOpQ); -+ osal_assert(pOp); -+ return MTK_WCN_BOOL_FALSE; -+ } -+ -+ iRet = osal_lock_sleepable_lock(&pOpQ->sLock); -+ if (iRet) { -+ WMT_WARN_FUNC("osal_lock_sleepable_lock iRet(%d)\n", iRet); -+ return MTK_WCN_BOOL_FALSE; -+ } -+#if 0 -+ if (pOpQ == &gDevWmt.rFreeOpQ) -+ WMT_INFO_FUNC("current wmt free queue count is(%d),opid(%d)\n", RB_COUNT(pOpQ), pOp->op.opId); -+#endif -+ /* acquire lock success */ -+ if (!RB_FULL(pOpQ)) -+ RB_PUT(pOpQ, pOp); -+ else -+ iRet = -1; -+ -+ osal_unlock_sleepable_lock(&pOpQ->sLock); -+ -+ if (iRet) { -+ WMT_WARN_FUNC("RB_FULL(0x%p)\n", pOpQ); -+ return MTK_WCN_BOOL_FALSE; -+ } else { -+ return MTK_WCN_BOOL_TRUE; -+ } -+} -+ -+static P_OSAL_OP wmt_lib_get_op(P_OSAL_OP_Q pOpQ) -+{ -+ P_OSAL_OP pOp; -+ INT32 iRet; -+ -+ if (NULL == pOpQ) { -+ WMT_ERR_FUNC("pOpQ = NULL\n"); -+ osal_assert(pOpQ); -+ return NULL; -+ } -+ -+ iRet = osal_lock_sleepable_lock(&pOpQ->sLock); -+ if (iRet) { -+ WMT_ERR_FUNC("osal_lock_sleepable_lock iRet(%d)\n", iRet); -+ return NULL; -+ } -+ -+ /* acquire lock success */ -+ RB_GET(pOpQ, pOp); -+ osal_unlock_sleepable_lock(&pOpQ->sLock); -+ -+ if (NULL == pOp) { -+ WMT_WARN_FUNC("RB_GET return NULL\n"); -+ osal_assert(pOp); -+ } -+ -+ return pOp; -+} -+ -+INT32 wmt_lib_put_op_to_free_queue(P_OSAL_OP pOp) -+{ -+ P_DEV_WMT pWmtDev = &gDevWmt; -+ -+ if (MTK_WCN_BOOL_FALSE == wmt_lib_put_op(&pWmtDev->rFreeOpQ, pOp)) -+ return -1; -+ else -+ return 0; -+} -+ -+P_OSAL_OP wmt_lib_get_free_op(VOID) -+{ -+ P_OSAL_OP pOp = NULL; -+ P_DEV_WMT pDevWmt = &gDevWmt; -+ -+ osal_assert(pDevWmt); -+ -+ pOp = wmt_lib_get_op(&pDevWmt->rFreeOpQ); -+ if (pOp) -+ osal_memset(&pOp->op, 0, osal_sizeof(pOp->op)); -+ return pOp; -+} -+ -+MTK_WCN_BOOL wmt_lib_put_act_op(P_OSAL_OP pOp) -+{ -+ P_DEV_WMT pWmtDev = &gDevWmt; -+ MTK_WCN_BOOL bRet = MTK_WCN_BOOL_FALSE; -+ MTK_WCN_BOOL bCleanup = MTK_WCN_BOOL_FALSE; -+ P_OSAL_SIGNAL pSignal = NULL; -+ long waitRet = -1; -+ P_OSAL_THREAD pThread; -+ -+ osal_assert(pWmtDev); -+ osal_assert(pOp); -+ -+ do { -+ if (!pWmtDev || !pOp) { -+ WMT_ERR_FUNC("pWmtDev(0x%p), pOp(0x%p)\n", pWmtDev, pOp); -+ break; -+ } -+ if ((0 != mtk_wcn_stp_coredump_start_get()) && -+ (WMT_OPID_HW_RST != pOp->op.opId) && -+ (WMT_OPID_SW_RST != pOp->op.opId) && (WMT_OPID_GPIO_STATE != pOp->op.opId)) { -+ bCleanup = MTK_WCN_BOOL_TRUE; -+ WMT_WARN_FUNC("block tx flag is set\n"); -+ break; -+ } -+ pSignal = &pOp->signal; -+/* pOp->u4WaitMs = u4WaitMs; */ -+ if (pSignal->timeoutValue) { -+ pOp->result = -9; -+ osal_signal_init(pSignal); -+ } -+ -+ /* put to active Q */ -+ bRet = wmt_lib_put_op(&pWmtDev->rActiveOpQ, pOp); -+ if (MTK_WCN_BOOL_FALSE == bRet) { -+ WMT_WARN_FUNC("put to active queue fail\n"); -+ bCleanup = MTK_WCN_BOOL_TRUE; -+ break; -+ } -+ -+ /* wake up wmtd */ -+ /* wake_up_interruptible(&pWmtDev->rWmtdWq); */ -+ osal_trigger_event(&pWmtDev->rWmtdWq); -+ -+ if (0 == pSignal->timeoutValue) { -+ bRet = MTK_WCN_BOOL_TRUE; -+ /* clean it in wmtd */ -+ break; -+ } -+ /* wait result, clean it here */ -+ bCleanup = MTK_WCN_BOOL_TRUE; -+ -+ /* check result */ -+ /* wait_ret = wait_for_completion_interruptible_timeout(&pOp->comp, msecs_to_jiffies(u4WaitMs)); */ -+ /* wait_ret = wait_for_completion_timeout(&pOp->comp, msecs_to_jiffies(u4WaitMs)); */ -+ waitRet = osal_wait_for_signal_timeout(pSignal); -+ WMT_DBG_FUNC("osal_wait_for_signal_timeout:%ld\n", waitRet); -+ -+ /* if (unlikely(!wait_ret)) { */ -+ if (0 == waitRet) { -+ pThread = &gDevWmt.thread; -+ WMT_ERR_FUNC -+ ("wait completion timeout, opId(%d), show wmtd_thread stack!\n", pOp->op.opId); -+ /* TODO: how to handle it? retry? */ -+ wcn_wmtd_timeout_collect_ftrace(); /* trigger collect SYS_FTRACE */ -+ osal_thread_show_stack(pThread); -+ } else { -+ if (pOp->result) -+ WMT_WARN_FUNC("opId(%d) result:%d\n", pOp->op.opId, pOp->result); -+ } -+ /* op completes, check result */ -+ bRet = (pOp->result) ? MTK_WCN_BOOL_FALSE : MTK_WCN_BOOL_TRUE; -+ } while (0); -+ -+ if (bCleanup) { -+ /* put Op back to freeQ */ -+ wmt_lib_put_op(&pWmtDev->rFreeOpQ, pOp); -+ } -+ -+ return bRet; -+} -+ -+/* TODO:[ChangeFeature][George] is this function obsoleted? */ -+#if 0 -+INT32 wmt_lib_reg_rw(UINT32 isWrite, UINT32 offset, PUINT32 pvalue, UINT32 mask) -+{ -+ P_WMT_LXOP lxop; -+ MTK_WCN_BOOL bRet; -+ PUINT32 plv = NULL; -+ UINT32 pbuf[2]; -+ P_OSAL_EVENT pSignal = NULL; -+ -+ if (!pvalue) { -+ WMT_WARN_FUNC("!pvalue\n"); -+ return -1; -+ } -+ lxop = wmt_lib_get_free_lxop(); -+ if (!lxop) { -+ WMT_WARN_FUNC("get_free_lxop fail\n"); -+ -+ return -1; -+ } -+ -+ plv = (PUINT32) (((UINT32) pbuf + 0x3) & ~0x3UL); -+ *plv = *pvalue; -+ pSignal = &lxop->signal; -+ WMT_DBG_FUNC("OPID_REG_RW isWrite(%d) offset(0x%x) value(0x%x) mask(0x%x)\n", isWrite, offset, *pvalue, mask); -+ -+ lxop->op.opId = WMT_OPID_REG_RW; -+ lxop->op.au4OpData[0] = isWrite; -+ lxop->op.au4OpData[1] = offset; -+ lxop->op.au4OpData[2] = (UINT32) plv; -+ lxop->op.au4OpData[3] = mask; -+ pSignal->timeoutValue = MAX_EACH_WMT_CMD; -+ -+ DISABLE_PSM_MONITOR(); -+ bRet = wmt_lib_put_act_lxop(lxop); -+ ENABLE_PSM_MONITOR(); -+ -+ if (MTK_WCN_BOOL_FALSE != bRet) { -+ WMT_DBG_FUNC("OPID_REG_RW isWrite(%u) offset(0x%x) value(0x%x) mask(0x%x) ok\n", -+ isWrite, offset, *plv, mask); -+ if (!isWrite) -+ *pvalue = *plv; -+ } else { -+ WMT_WARN_FUNC("OPID_REG_RW isWrite(%u) offset(0x%x) value(0x%x) mask(0x%x) bRet(%d)\n", -+ isWrite, offset, *plv, mask, bRet); -+ } -+ -+ return bRet; -+} -+#endif -+ -+/* TODO:[ChangeFeature][George] is this function obsoleted? */ -+#if 0 -+static VOID wmt_lib_clear_chip_id(VOID) -+{ -+/* -+ gDevWmt.pChipInfo = NULL; -+*/ -+ gDevWmt.hw_ver = WMTHWVER_INVALID; -+} -+#endif -+ -+/* TODO: [FixMe][GeorgeKuo]: change this API to report real chip id, hw_ver, and */ -+/* fw_ver instead of WMT-translated WMTHWVER */ -+ENUM_WMTHWVER_TYPE_T wmt_lib_get_hwver(VOID) -+{ -+/* -+ P_WMT_CMB_CHIP_INFO_S pChipInfo = NULL; -+ P_DEV_WMT pWmtDev = gpDevWmt; -+ pChipInfo = wmt_lib_get_chip_info(pWmtDev); -+ return pChipInfo != NULL ? pChipInfo->eHwVersion : WMTHWVER_INVALID; -+ */ -+ return gDevWmt.eWmtHwVer; -+} -+ -+UINT32 wmt_lib_get_icinfo(ENUM_WMT_CHIPINFO_TYPE_T index) -+{ -+ if (WMTCHIN_CHIPID == index) -+ return gDevWmt.chip_id; -+ else if (WMTCHIN_HWVER == index) -+ return gDevWmt.hw_ver; -+ else if (WMTCHIN_MAPPINGHWVER == index) -+ return gDevWmt.eWmtHwVer; -+ else if (WMTCHIN_FWVER == index) -+ return gDevWmt.fw_ver; -+ -+ return 0; -+ -+} -+ -+PUINT8 wmt_lib_def_patch_name(VOID) -+{ -+ WMT_INFO_FUNC("wmt-lib: use default patch name (%s)\n", gDevWmt.cPatchName); -+ return gDevWmt.cPatchName; -+} -+ -+MTK_WCN_BOOL wmt_lib_is_therm_ctrl_support(VOID) -+{ -+ MTK_WCN_BOOL bIsSupportTherm = MTK_WCN_BOOL_TRUE; -+ /* TODO:[FixMe][GeorgeKuo]: move IC-dependent checking to ic-implementation file */ -+ if (((0x6620 == gDevWmt.chip_id) && (WMTHWVER_E3 > gDevWmt.eWmtHwVer)) -+ || (WMTHWVER_INVALID == gDevWmt.eWmtHwVer)) { -+ WMT_ERR_FUNC("thermal command fail: chip version(WMTHWVER_TYPE:%d) is not valid\n", gDevWmt.eWmtHwVer); -+ bIsSupportTherm = MTK_WCN_BOOL_FALSE; -+ } -+ if (!mtk_wcn_stp_is_ready()) { -+ WMT_ERR_FUNC("thermal command can not be send: STP is not ready\n"); -+ bIsSupportTherm = MTK_WCN_BOOL_FALSE; -+ } -+ -+ return bIsSupportTherm; -+} -+ -+MTK_WCN_BOOL wmt_lib_is_dsns_ctrl_support(VOID) -+{ -+ /* TODO:[FixMe][GeorgeKuo]: move IC-dependent checking to ic-implementation file */ -+ if (((0x6620 == gDevWmt.chip_id) && (WMTHWVER_E3 > gDevWmt.eWmtHwVer)) -+ || (WMTHWVER_INVALID == gDevWmt.eWmtHwVer)) { -+ WMT_ERR_FUNC("thermal command fail: chip version(WMTHWVER_TYPE:%d) is not valid\n", gDevWmt.eWmtHwVer); -+ return MTK_WCN_BOOL_FALSE; -+ } -+ -+ return MTK_WCN_BOOL_TRUE; -+} -+ -+/*! -+ * \brief Update combo chip pin settings (GPIO) -+ * -+ * An internal library function to support various settings for chip GPIO. It is -+ * updated in a grouping way: configure all required pins in a single call. -+ * -+ * \param id desired pin ID to be controlled -+ * \param stat desired pin states to be set -+ * \param flag supplementary options for this operation -+ * -+ * \retval 0 operation success -+ * \retval -1 invalid id -+ * \retval -2 invalid stat -+ * \retval < 0 error for operation fail -+ */ -+static INT32 wmt_lib_pin_ctrl(WMT_IC_PIN_ID id, WMT_IC_PIN_STATE stat, UINT32 flag) -+{ -+ P_OSAL_OP pOp; -+ MTK_WCN_BOOL bRet; -+ P_OSAL_SIGNAL pSignal; -+ -+ /* input sanity check */ -+ if (WMT_IC_PIN_MAX <= id) { -+ WMT_ERR_FUNC("invalid ic pin id(%d)\n", id); -+ return -1; -+ } -+ if (WMT_IC_PIN_STATE_MAX <= stat) { -+ WMT_ERR_FUNC("invalid ic pin state (%d)\n", stat); -+ return -2; -+ } -+ -+ pOp = wmt_lib_get_free_op(); -+ if (!pOp) { -+ WMT_WARN_FUNC("get_free_lxop fail\n"); -+ return MTK_WCN_BOOL_FALSE; -+ } -+ -+ WMT_DBG_FUNC("call WMT_OPID_GPIO_CTRL (ic pin id:%d, stat:%d, flag:0x%x)\n", id, stat, flag); -+ -+ pSignal = &pOp->signal; -+ pOp->op.opId = WMT_OPID_GPIO_CTRL; -+ pOp->op.au4OpData[0] = id; -+ pOp->op.au4OpData[1] = stat; -+ pOp->op.au4OpData[2] = flag; -+ pSignal->timeoutValue = MAX_EACH_WMT_CMD; -+ -+ /*wake up chip first */ -+ if (DISABLE_PSM_MONITOR()) { -+ WMT_ERR_FUNC("wake up failed\n"); -+ wmt_lib_put_op_to_free_queue(pOp); -+ return -1; -+ } -+ -+ bRet = wmt_lib_put_act_op(pOp); -+ ENABLE_PSM_MONITOR(); -+ if (MTK_WCN_BOOL_FALSE == bRet) -+ WMT_WARN_FUNC("PIN_ID(%d) PIN_STATE(%d) flag(%d) fail\n", id, stat, flag); -+ else -+ WMT_DBG_FUNC("OPID(%d) type(%d) ok\n", pOp->op.opId, pOp->op.au4OpData[0]); -+ -+ return 0; -+} -+ -+INT32 wmt_lib_reg_rw(UINT32 isWrite, UINT32 offset, PUINT32 pvalue, UINT32 mask) -+{ -+ P_OSAL_OP pOp; -+ MTK_WCN_BOOL bRet; -+ UINT32 value; -+ P_OSAL_SIGNAL pSignal; -+ -+ if (!pvalue) { -+ WMT_WARN_FUNC("!pvalue\n"); -+ return -1; -+ } -+ -+ pOp = wmt_lib_get_free_op(); -+ if (!pOp) { -+ WMT_WARN_FUNC("get_free_lxop fail\n"); -+ return -1; -+ } -+ -+ pSignal = &pOp->signal; -+ pSignal->timeoutValue = MAX_EACH_WMT_CMD; -+ value = *pvalue; -+ WMT_DBG_FUNC("OPID_REG_RW isWrite(%u) offset(0x%x) value(0x%x) mask(0x%x)\n\n", isWrite, offset, *pvalue, mask); -+ pOp->op.opId = WMT_OPID_REG_RW; -+ pOp->op.au4OpData[0] = isWrite; -+ pOp->op.au4OpData[1] = offset; -+ pOp->op.au4OpData[2] = (SIZE_T)&value; -+ pOp->op.au4OpData[3] = mask; -+ if (DISABLE_PSM_MONITOR()) { -+ WMT_ERR_FUNC("wake up failed\n"); -+ wmt_lib_put_op_to_free_queue(pOp); -+ return -1; -+ } -+ -+ bRet = wmt_lib_put_act_op(pOp); -+ ENABLE_PSM_MONITOR(); -+ -+ if (MTK_WCN_BOOL_FALSE != bRet) { -+ WMT_DBG_FUNC("OPID_REG_RW isWrite(%u) offset(0x%x) value(0x%x) mask(0x%x) ok\n", -+ isWrite, offset, value, mask); -+ if (!isWrite) -+ *pvalue = value; -+ -+ return 0; -+ } -+ WMT_WARN_FUNC("OPID_REG_RW isWrite(%u) offset(0x%x) value(0x%x) mask(0x%x) bRet(%d)\n", -+ isWrite, offset, value, mask, bRet); -+ return -1; -+} -+ -+INT32 wmt_lib_efuse_rw(UINT32 isWrite, UINT32 offset, PUINT32 pvalue, UINT32 mask) -+{ -+ P_OSAL_OP pOp; -+ MTK_WCN_BOOL bRet; -+ UINT32 value; -+ P_OSAL_SIGNAL pSignal; -+ -+ if (!pvalue) { -+ WMT_WARN_FUNC("!pvalue\n"); -+ return -1; -+ } -+ -+ pOp = wmt_lib_get_free_op(); -+ if (!pOp) { -+ WMT_WARN_FUNC("get_free_lxop fail\n"); -+ return -1; -+ } -+ -+ pSignal = &pOp->signal; -+ pSignal->timeoutValue = MAX_EACH_WMT_CMD; -+ value = *pvalue; -+ WMT_DBG_FUNC("OPID_EFUSE_RW isWrite(%u) offset(0x%x) value(0x%x) mask(0x%x)\n\n", -+ isWrite, offset, *pvalue, mask); -+ pOp->op.opId = WMT_OPID_EFUSE_RW; -+ pOp->op.au4OpData[0] = isWrite; -+ pOp->op.au4OpData[1] = offset; -+ pOp->op.au4OpData[2] = (SIZE_T)&value; -+ pOp->op.au4OpData[3] = mask; -+ if (DISABLE_PSM_MONITOR()) { -+ WMT_ERR_FUNC("wake up failed\n"); -+ wmt_lib_put_op_to_free_queue(pOp); -+ return -1; -+ } -+ -+ bRet = wmt_lib_put_act_op(pOp); -+ ENABLE_PSM_MONITOR(); -+ -+ if (MTK_WCN_BOOL_FALSE != bRet) { -+ WMT_DBG_FUNC("OPID_EFUSE_RW isWrite(%u) offset(0x%x) value(0x%x) mask(0x%x) ok\n", -+ isWrite, offset, value, mask); -+ if (!isWrite) -+ *pvalue = value; -+ -+ return 0; -+ } -+ WMT_WARN_FUNC("OPID_REG_RW isWrite(%u) offset(0x%x) value(0x%x) mask(0x%x) bRet(%d)\n", -+ isWrite, offset, value, mask, bRet); -+ return -1; -+ -+} -+ -+/*! -+ * \brief update combo chip AUDIO Interface (AIF) settings -+ * -+ * A library function to support updating chip AUDIO pin settings. A group of -+ * pins is updated as a whole. -+ * -+ * \param aif desired audio interface state to use -+ * \param flag whether audio pin is shared or not -+ * -+ * \retval 0 operation success -+ * \retval -1 invalid aif -+ * \retval < 0 error for invalid parameters or operation fail -+ */ -+INT32 wmt_lib_set_aif(CMB_STUB_AIF_X aif, MTK_WCN_BOOL share) -+{ -+ if (CMB_STUB_AIF_MAX <= aif) { -+ WMT_ERR_FUNC("invalid aif (%d)\n", aif); -+ return -1; -+ } -+ WMT_DBG_FUNC("call pin_ctrl for aif:%d, share:%d\n", aif, (MTK_WCN_BOOL_TRUE == share) ? 1 : 0); -+ /* Translate CMB_STUB_AIF_X into WMT_IC_PIN_STATE by array */ -+ return wmt_lib_pin_ctrl(WMT_IC_PIN_AUDIO, -+ cmb_aif2pin_stat[aif], -+ (MTK_WCN_BOOL_TRUE == share) ? WMT_LIB_AIF_FLAG_SHARE : WMT_LIB_AIF_FLAG_SEPARATE); -+} -+ -+INT32 wmt_lib_host_awake_get(VOID) -+{ -+ return wmt_plat_wake_lock_ctrl(WL_OP_GET); -+} -+ -+INT32 wmt_lib_host_awake_put(VOID) -+{ -+ return wmt_plat_wake_lock_ctrl(WL_OP_PUT); -+} -+ -+MTK_WCN_BOOL wmt_lib_btm_cb(MTKSTP_BTM_WMT_OP_T op) -+{ -+ MTK_WCN_BOOL bRet = MTK_WCN_BOOL_FALSE; -+ -+ if (op == BTM_RST_OP) { -+ /* high priority, not to enqueue into the queue of wmtd */ -+ WMT_INFO_FUNC("Invoke whole chip reset from stp_btm!!!\n"); -+ wmt_lib_cmb_rst(WMTRSTSRC_RESET_STP); -+ bRet = MTK_WCN_BOOL_TRUE; -+ } else if (op == BTM_DMP_OP) { -+ -+ WMT_WARN_FUNC("TBD!!!\n"); -+ } else if (op == BTM_GET_AEE_SUPPORT_FLAG) { -+ bRet = wmt_core_get_aee_dump_flag(); -+ } -+ return bRet; -+} -+ -+MTK_WCN_BOOL wmt_cdev_rstmsg_snd(ENUM_WMTRSTMSG_TYPE_T msg) -+{ -+ -+ INT32 i = 0; -+ P_DEV_WMT pDevWmt = &gDevWmt; -+ PUINT8 drv_name[] = { -+ "DRV_TYPE_BT", -+ "DRV_TYPE_FM", -+ "DRV_TYPE_GPS", -+ "DRV_TYPE_WIFI" -+ }; -+ -+ for (i = 0; i <= WMTDRV_TYPE_WIFI; i++) { -+ /* <1> check if reset callback is registered */ -+ if (pDevWmt->rFdrvCb.fDrvRst[i]) { -+ /* <2> send the msg to this subfucntion */ -+ /*src, dst, msg_type, msg_data, msg_size */ -+ pDevWmt->rFdrvCb.fDrvRst[i] (WMTDRV_TYPE_WMT, i, WMTMSG_TYPE_RESET, &msg, -+ sizeof(ENUM_WMTRSTMSG_TYPE_T)); -+ WMT_INFO_FUNC("type = %s, msg sent\n", drv_name[i]); -+ } else { -+ WMT_DBG_FUNC("type = %s, unregistered\n", drv_name[i]); -+ } -+ } -+ -+ return MTK_WCN_BOOL_TRUE; -+} -+ -+VOID wmt_lib_state_init(VOID) -+{ -+ /* UINT32 i = 0; */ -+ P_DEV_WMT pDevWmt = &gDevWmt; -+ P_OSAL_OP pOp; -+ -+ /* Initialize op queue */ -+ /* RB_INIT(&pDevWmt->rFreeOpQ, WMT_OP_BUF_SIZE); */ -+ /* RB_INIT(&pDevWmt->rActiveOpQ, WMT_OP_BUF_SIZE); */ -+ -+ while (!RB_EMPTY(&pDevWmt->rActiveOpQ)) { -+#if 0 -+ osal_signal_init(&(pOp->signal)); -+ wmt_lib_put_op(&pDevWmt->rFreeOpQ, pOp); -+#endif -+ pOp = wmt_lib_get_op(&pDevWmt->rActiveOpQ); -+ if (pOp) { -+ if (osal_op_is_wait_for_signal(pOp)) -+ osal_op_raise_signal(pOp, -1); -+ else -+ wmt_lib_put_op(&pDevWmt->rFreeOpQ, pOp); -+ } -+ } -+ -+ /* Put all to free Q */ -+ /* -+ for (i = 0; i < WMT_OP_BUF_SIZE; i++) { -+ osal_signal_init(&(pDevWmt->arQue[i].signal)); -+ wmt_lib_put_op(&pDevWmt->rFreeOpQ, &(pDevWmt->arQue[i])); -+ } */ -+} -+ -+#if 0 -+INT32 wmt_lib_sdio_ctrl(UINT32 on) -+{ -+ -+ P_OSAL_OP pOp; -+ MTK_WCN_BOOL bRet; -+ P_OSAL_SIGNAL pSignal; -+ -+ pOp = wmt_lib_get_free_op(); -+ if (!pOp) { -+ WMT_WARN_FUNC("get_free_lxop fail\n"); -+ return MTK_WCN_BOOL_FALSE; -+ } -+ -+ WMT_DBG_FUNC("call WMT_OPID_SDIO_CTRL\n"); -+ -+ pSignal = &pOp->signal; -+ pOp->op.opId = WMT_OPID_SDIO_CTRL; -+ pOp->op.au4OpData[0] = on; -+ pSignal->timeoutValue = MAX_GPIO_CTRL_TIME; -+ -+ bRet = wmt_lib_put_act_op(pOp); -+ if (MTK_WCN_BOOL_FALSE == bRet) { -+ WMT_WARN_FUNC("WMT_OPID_SDIO_CTRL failed\n"); -+ return -1; -+ } -+ WMT_DBG_FUNC("OPID(WMT_OPID_SDIO_CTRL)ok\n"); -+ -+ return 0; -+} -+#endif -+ -+MTK_WCN_BOOL wmt_lib_hw_state_show(VOID) -+{ -+ P_OSAL_OP pOp; -+ MTK_WCN_BOOL bRet; -+ P_OSAL_SIGNAL pSignal; -+ -+ pOp = wmt_lib_get_free_op(); -+ if (!pOp) { -+ WMT_WARN_FUNC("get_free_lxop fail\n"); -+ return MTK_WCN_BOOL_FALSE; -+ } -+ -+ WMT_DBG_FUNC("call WMT_OPID_HW_STATE_SHOW\n"); -+ -+ pSignal = &pOp->signal; -+ pOp->op.opId = WMT_OPID_GPIO_STATE; -+ pSignal->timeoutValue = MAX_GPIO_CTRL_TIME; -+ -+ bRet = wmt_lib_put_act_op(pOp); -+ if (MTK_WCN_BOOL_FALSE == bRet) { -+ WMT_WARN_FUNC("WMT_OPID_HW_STATE_SHOW failed\n"); -+ return MTK_WCN_BOOL_FALSE; -+ } -+ WMT_DBG_FUNC("OPID(WMT_OPID_HW_STATE_SHOW)ok\n"); -+ return MTK_WCN_BOOL_TRUE; -+} -+ -+MTK_WCN_BOOL wmt_lib_hw_rst(VOID) -+{ -+ -+ P_OSAL_OP pOp; -+ MTK_WCN_BOOL bRet; -+ P_OSAL_SIGNAL pSignal; -+ P_DEV_WMT pDevWmt = &gDevWmt; -+ -+ wmt_lib_state_init(); -+ -+ osal_clear_bit(WMT_STAT_STP_REG, &pDevWmt->state); -+ osal_clear_bit(WMT_STAT_STP_OPEN, &pDevWmt->state); -+ osal_clear_bit(WMT_STAT_STP_EN, &pDevWmt->state); -+ osal_clear_bit(WMT_STAT_STP_RDY, &pDevWmt->state); -+ osal_clear_bit(WMT_STAT_RX, &pDevWmt->state); -+ osal_clear_bit(WMT_STAT_CMD, &pDevWmt->state); -+ -+ /*Before do hardware reset, we show GPIO state to check if others modified our pin state accidentially */ -+ wmt_lib_hw_state_show(); -+ pOp = wmt_lib_get_free_op(); -+ if (!pOp) { -+ WMT_WARN_FUNC("get_free_lxop fail\n"); -+ return MTK_WCN_BOOL_FALSE; -+ } -+ -+ WMT_DBG_FUNC("call WMT_OPID_HW_RST\n"); -+ -+ pSignal = &pOp->signal; -+ pOp->op.opId = WMT_OPID_HW_RST; -+ pSignal->timeoutValue = MAX_GPIO_CTRL_TIME; -+ -+ bRet = wmt_lib_put_act_op(pOp); -+ if (MTK_WCN_BOOL_FALSE == bRet) { -+ WMT_WARN_FUNC("WMT_OPID_HW_RST failed\n"); -+ return MTK_WCN_BOOL_FALSE; -+ } -+ WMT_DBG_FUNC("OPID(WMT_OPID_HW_RST)ok\n"); -+ return MTK_WCN_BOOL_TRUE; -+} -+ -+MTK_WCN_BOOL wmt_lib_sw_rst(INT32 baudRst) -+{ -+ -+ P_OSAL_OP pOp; -+ MTK_WCN_BOOL bRet; -+ P_OSAL_SIGNAL pSignal; -+ -+ /* <1> wmt state reset */ -+ wmt_lib_state_init(); -+ -+ /* <2> Reset STP data structure */ -+ WMT_DBG_FUNC("Cleanup STP context\n"); -+ mtk_wcn_stp_flush_context(); -+ /* <3> Reset STP-PSM data structure */ -+ WMT_DBG_FUNC("Cleanup STP-PSM context\n"); -+ mtk_wcn_stp_psm_reset(); -+ -+ /* <4> do sw reset in wmt-core */ -+ pOp = wmt_lib_get_free_op(); -+ if (!pOp) { -+ WMT_WARN_FUNC("get_free_lxop fail\n"); -+ return MTK_WCN_BOOL_FALSE; -+ } -+ -+ WMT_DBG_FUNC("call WMT_OPID_SW_RST\n"); -+ -+ pSignal = &pOp->signal; -+ pSignal->timeoutValue = MAX_FUNC_ON_TIME; -+ -+ pOp->op.opId = WMT_OPID_SW_RST; -+ pOp->op.au4OpData[0] = baudRst; -+ -+ bRet = wmt_lib_put_act_op(pOp); -+ if (MTK_WCN_BOOL_FALSE == bRet) { -+ WMT_WARN_FUNC("WMT_OPID_SW_RST failed\n"); -+ return MTK_WCN_BOOL_FALSE; -+ } -+ WMT_DBG_FUNC("OPID(WMT_OPID_SW_RST)ok\n"); -+ return MTK_WCN_BOOL_TRUE; -+} -+ -+ENUM_WMTRSTRET_TYPE_T wmt_lib_cmb_rst(ENUM_WMTRSTSRC_TYPE_T src) -+{ -+#define RETRYTIMES 10 -+ MTK_WCN_BOOL bRet; -+ ENUM_WMTRSTRET_TYPE_T retval = WMTRSTRET_MAX; -+ ENUM_WMTRSTMSG_TYPE_T rstMsg = WMTRSTMSG_RESET_MAX; -+ INT32 retries = RETRYTIMES; -+ P_DEV_WMT pDevWmt = &gDevWmt; -+ P_OSAL_OP pOp; -+ PUINT8 srcName[] = { "WMTRSTSRC_RESET_BT", -+ "WMTRSTSRC_RESET_FM", -+ "WMTRSTSRC_RESET_GPS", -+ "WMTRSTSRC_RESET_WIFI", -+ "WMTRSTSRC_RESET_STP", -+ "WMTRSTSRC_RESET_TEST" -+ }; -+ -+ if (src < WMTRSTSRC_RESET_MAX) -+ WMT_INFO_FUNC("reset source = %s\n", srcName[src]); -+ -+ if (WMTRSTSRC_RESET_TEST == src) { -+ pOp = wmt_lib_get_current_op(pDevWmt); -+ if (pOp && ((WMT_OPID_FUNC_ON == pOp->op.opId) -+ || (WMT_OPID_FUNC_OFF == pOp->op.opId))) { -+ WMT_INFO_FUNC("can't do reset by test src when func on/off\n"); -+ return -1; -+ } -+ } -+ /* <1> Consider the multi-context combo_rst case. */ -+ if (osal_test_and_set_bit(WMT_STAT_RST_ON, &pDevWmt->state)) { -+ retval = WMTRSTRET_ONGOING; -+ goto rstDone; -+ } -+ /* <2> Block all STP request */ -+ mtk_wcn_stp_enable(0); -+ -+ /* <3> RESET_START notification */ -+ bRet = wmt_cdev_rstmsg_snd(WMTRSTMSG_RESET_START); -+ if (bRet == MTK_WCN_BOOL_FALSE) { -+ WMT_ERR_FUNC("[whole chip reset] fail at wmt_lib_rstmsg_snd!\n"); -+ retval = WMTRSTRET_FAIL; -+ goto rstDone; -+ } -+ /* wakeup blocked opid */ -+ pOp = wmt_lib_get_current_op(pDevWmt); -+ if (osal_op_is_wait_for_signal(pOp)) -+ osal_op_raise_signal(pOp, -1); -+ -+ /* wakeup blocked cmd */ -+ wmt_dev_rx_event_cb(); -+ -+ /* <4> retry until reset flow successful */ -+ while (retries > 0) { -+ /* <4.1> reset combo hw */ -+ bRet = wmt_lib_hw_rst(); -+ if (bRet == MTK_WCN_BOOL_FALSE) { -+ WMT_ERR_FUNC("[whole chip reset] fail at wmt_lib_hw_rst!\n"); -+ retries--; -+ continue; -+ } -+ /* <4.2> reset driver/combo sw */ -+ bRet = wmt_lib_sw_rst(1); -+ if (bRet == MTK_WCN_BOOL_FALSE) { -+ WMT_ERR_FUNC("[whole chip reset] fail at wmt_lib_sw_rst!\n"); -+ retries--; -+ continue; -+ } -+ break; -+ } -+ -+ osal_clear_bit(WMT_STAT_RST_ON, &pDevWmt->state); -+ -+ if (bRet == MTK_WCN_BOOL_FALSE) { -+ rstMsg = WMTRSTMSG_RESET_END_FAIL; -+ WMT_WARN_FUNC("[whole chip reset] fail! retries = %d\n", RETRYTIMES - retries); -+ } else { -+ rstMsg = WMTRSTMSG_RESET_END; -+ WMT_INFO_FUNC("[whole chip reset] ok! retries = %d\n", RETRYTIMES - retries); -+ } -+ -+ /* <5> RESET_END notification */ -+ bRet = wmt_cdev_rstmsg_snd(rstMsg); -+ if (bRet == MTK_WCN_BOOL_FALSE) { -+ WMT_ERR_FUNC("[whole chip reset] fail at wmt_lib_rstmsg_snd!\n"); -+ retval = WMTRSTRET_FAIL; -+ } else { -+ retval = WMTRSTMSG_RESET_END == rstMsg ? WMTRSTRET_SUCCESS : WMTRSTRET_FAIL; -+ } -+ mtk_wcn_stp_coredump_start_ctrl(0); -+ mtk_wcn_stp_set_wmt_evt_err_trg_assert(0); -+rstDone: -+ if (osal_test_and_clear_bit(WMT_STAT_RST_ON, &pDevWmt->state)) -+ WMT_WARN_FUNC("[whole chip reset] retval = %d\n", retval); -+ -+ return retval; -+} -+ -+MTK_WCN_BOOL wmt_lib_msgcb_reg(ENUM_WMTDRV_TYPE_T eType, PF_WMT_CB pCb) -+{ -+ -+ MTK_WCN_BOOL bRet = MTK_WCN_BOOL_FALSE; -+ P_DEV_WMT pWmtDev = &gDevWmt; -+ -+ if (eType >= 0 && eType <= WMTDRV_TYPE_WIFI) { -+ WMT_DBG_FUNC("reg ok!\n"); -+ pWmtDev->rFdrvCb.fDrvRst[eType] = pCb; -+ bRet = MTK_WCN_BOOL_TRUE; -+ } else { -+ WMT_WARN_FUNC("reg fail!\n"); -+ } -+ -+ return bRet; -+} -+ -+MTK_WCN_BOOL wmt_lib_msgcb_unreg(ENUM_WMTDRV_TYPE_T eType) -+{ -+ MTK_WCN_BOOL bRet = MTK_WCN_BOOL_FALSE; -+ P_DEV_WMT pWmtDev = &gDevWmt; -+ -+ if (eType >= 0 && eType <= WMTDRV_TYPE_WIFI) { -+ WMT_DBG_FUNC("unreg ok!\n"); -+ pWmtDev->rFdrvCb.fDrvRst[eType] = NULL; -+ bRet = MTK_WCN_BOOL_TRUE; -+ } else { -+ WMT_WARN_FUNC("unreg fail!\n"); -+ } -+ -+ return bRet; -+} -+ -+UINT32 wmt_lib_dbg_level_set(UINT32 level) -+{ -+ gWmtDbgLvl = level > WMT_LOG_LOUD ? WMT_LOG_LOUD : level; -+ return 0; -+} -+ -+INT32 wmt_lib_set_stp_wmt_last_close(UINT32 value) -+{ -+ return mtk_wcn_stp_set_wmt_last_close(value); -+} -+ -+INT32 wmt_lib_notify_stp_sleep(void) -+{ -+ INT32 iRet = 0x0; -+ -+ iRet = wmt_lib_psm_lock_aquire(); -+ if (iRet) { -+ WMT_ERR_FUNC("--->lock psm_lock failed, iRet=%d\n", iRet); -+ return iRet; -+ } -+ -+ iRet = mtk_wcn_stp_notify_sleep_for_thermal(); -+ wmt_lib_psm_lock_release(); -+ -+ return iRet; -+} -+ -+VOID wmt_lib_set_patch_num(UINT32 num) -+{ -+ P_DEV_WMT pWmtDev = &gDevWmt; -+ -+ pWmtDev->patchNum = num; -+} -+ -+VOID wmt_lib_set_patch_info(P_WMT_PATCH_INFO pPatchinfo) -+{ -+ P_DEV_WMT pWmtDev = &gDevWmt; -+ -+ if (pPatchinfo) -+ pWmtDev->pWmtPatchInfo = pPatchinfo; -+ -+} -+ -+INT32 wmt_lib_set_current_op(P_DEV_WMT pWmtDev, P_OSAL_OP pOp) -+{ -+ if (pWmtDev) { -+ pWmtDev->pCurOP = pOp; -+ WMT_DBG_FUNC("pOp=0x%p\n", pOp); -+ return 0; -+ } -+ WMT_ERR_FUNC("Invalid pointer\n"); -+ return -1; -+} -+ -+P_OSAL_OP wmt_lib_get_current_op(P_DEV_WMT pWmtDev) -+{ -+ if (pWmtDev) -+ return pWmtDev->pCurOP; -+ -+ WMT_ERR_FUNC("Invalid pointer\n"); -+ return NULL; -+} -+ -+UINT8 *wmt_lib_get_fwinfor_from_emi(UINT8 section, UINT32 offset, UINT8 *buf, UINT32 len) -+{ -+ UINT8 *pAddr = NULL; -+ UINT32 sublen1 = 0; -+ UINT32 sublen2 = 0; -+ P_CONSYS_EMI_ADDR_INFO p_consys_info; -+ -+ p_consys_info = wmt_plat_get_emi_phy_add(); -+ osal_assert(p_consys_info); -+ -+ if (section == 0) { -+ pAddr = wmt_plat_get_emi_virt_add(0x0); -+ if (len > 1024) -+ len = 1024; -+ if (!pAddr) { -+ WMT_ERR_FUNC("wmt-lib: get EMI virtual base address fail\n"); -+ } else { -+ WMT_INFO_FUNC("vir addr(0x%p)\n", pAddr); -+ osal_memcpy(&buf[0], pAddr, len); -+ } -+ } else { -+ if (offset >= 0x7fff) -+ offset = 0x0; -+ -+ if (offset + len > 32768) { -+ pAddr = wmt_plat_get_emi_virt_add(offset + p_consys_info->paged_trace_off); -+ if (!pAddr) { -+ WMT_ERR_FUNC("wmt-lib: get part1 EMI virtual base address fail\n"); -+ } else { -+ WMT_INFO_FUNC("part1 vir addr(0x%p)\n", pAddr); -+ sublen1 = 0x7fff - offset; -+ osal_memcpy(&buf[0], pAddr, sublen1); -+ } -+ pAddr = wmt_plat_get_emi_virt_add(p_consys_info->paged_trace_off); -+ if (!pAddr) { -+ WMT_ERR_FUNC("wmt-lib: get part2 EMI virtual base address fail\n"); -+ } else { -+ WMT_INFO_FUNC("part2 vir addr(0x%p)\n", pAddr); -+ sublen2 = len - sublen1; -+ osal_memcpy(&buf[sublen1], pAddr, sublen2); -+ } -+ } else { -+ pAddr = wmt_plat_get_emi_virt_add(offset + p_consys_info->paged_trace_off); -+ if (!pAddr) { -+ WMT_ERR_FUNC("wmt-lib: get EMI virtual base address fail\n"); -+ } else { -+ WMT_INFO_FUNC("vir addr(0x%p)\n", pAddr); -+ osal_memcpy(&buf[0], pAddr, len); -+ } -+ } -+ } -+ -+ return 0; -+} -+ -+INT32 wmt_lib_poll_cpupcr(UINT32 count, UINT16 sleep, UINT16 toAee) -+{ -+ ENUM_STP_FW_ISSUE_TYPE issue_type; -+ -+ issue_type = STP_DBG_PROC_TEST; -+ -+ stp_dbg_poll_cpupcr(count, sleep, 1); -+ -+ if (toAee) { -+ stp_dbg_set_fw_info("STP ProcTest", osal_strlen("STP ProcTest"), issue_type); -+ osal_dbg_assert_aee("[SOC_CONSYS]ProcTest", -+ "**[WCN_ISSUE_INFO]STP Tx Timeout**\n Polling CPUPCR for FW debug usage\n"); -+ } else { -+ WMT_INFO_FUNC("wmt_lib:do not pass cpupcr to AEE\n"); -+ } -+ return 0; -+} -+ -+UINT8 *wmt_lib_get_cpupcr_xml_format(UINT32 *len) -+{ -+ PUINT8 temp; -+ UINT32 i = 0; -+ -+ osal_memset(&g_cpupcr_buf[0], 0, WMT_STP_CPUPCR_BUF_SIZE); -+ temp = g_cpupcr_buf; -+ stp_dbg_cpupcr_infor_format(&temp, len); -+ -+ pr_debug("print xml buffer,len(%d):\n\n", *len); -+ for (i = 0; i < *len; i++) -+ pr_cont("%c", g_cpupcr_buf[i]); -+ -+ return &g_cpupcr_buf[0]; -+} -+ -+UINT32 wmt_lib_set_host_assert_info(UINT32 type, UINT32 reason, UINT32 en) -+{ -+ return stp_dbg_set_host_assert_info(type, reason, en); -+} -+ -+INT32 wmt_lib_register_thermal_ctrl_cb(thermal_query_ctrl_cb thermal_ctrl) -+{ -+ wmt_plat_thermal_ctrl_cb_reg(thermal_ctrl); -+ return 0; -+} -+ -+INT8 wmt_lib_co_clock_get(void) -+{ -+ if (gDevWmt.rWmtGenConf.cfgExist) -+ return gDevWmt.rWmtGenConf.co_clock_flag; -+ else -+ return -1; -+} -+ -+#if CFG_WMT_PS_SUPPORT -+UINT32 wmt_lib_quick_sleep_ctrl(UINT32 en) -+{ -+ WMT_WARN_FUNC("%s quick sleep mode\n", en ? "enable" : "disable"); -+ g_quick_sleep_ctrl = en; -+ return 0; -+} -+#endif -+ -+#if CONSYS_ENALBE_SET_JTAG -+UINT32 wmt_lib_jtag_flag_set(UINT32 en) -+{ -+ return wmt_plat_jtag_flag_ctrl(en); -+} -+#endif -+ -+UINT32 wmt_lib_soc_set_wifiver(UINT32 wifiver) -+{ -+ return stp_dbg_set_wifiver(wifiver); -+} -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/include/stp_exp.h b/drivers/misc/mediatek/connectivity/common/conn_soc/include/stp_exp.h -new file mode 100644 -index 000000000000..b1b5285638f9 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/include/stp_exp.h -@@ -0,0 +1,252 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -+ -+/*! \file -+ \brief Declaration of library functions -+ -+ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. -+*/ -+ -+#ifndef _STP_EXP_H_ -+#define _STP_EXP_H_ -+ -+#include "osal_typedef.h" -+#include "osal.h" -+#include "wmt_stp_exp.h" -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+#ifndef MTK_WCN_WMT_STP_EXP_SYMBOL_ABSTRACT -+ -+#define BT_TASK_INDX (0) -+#define FM_TASK_INDX (1) -+#define GPS_TASK_INDX (2) -+#define WIFI_TASK_INDX (3) -+#define WMT_TASK_INDX (4) -+#define STP_TASK_INDX (5) -+#define INFO_TASK_INDX (6) -+#define ANT_TASK_INDX (7) -+#if CFG_WMT_LTE_COEX_HANDLING -+#define COEX_TASK_INDX (8) -+#define MTKSTP_MAX_TASK_NUM (9) -+#else -+#define MTKSTP_MAX_TASK_NUM (8) -+#endif -+ -+#define MTKSTP_BUFFER_SIZE (16384) /* Size of RX Queue */ -+ -+#define STP_EXP_HID_API_EXPORT 0 -+ -+#else -+ -+#define STP_EXP_HID_API_EXPORT 1 -+ -+#endif -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+#ifndef MTK_WCN_WMT_STP_EXP_SYMBOL_ABSTRACT -+typedef void (*MTK_WCN_STP_EVENT_CB) (void); -+typedef INT32 (*MTK_WCN_STP_IF_TX) (const UINT8 *data, const UINT32 size, UINT32 *written_size); -+/* export for HIF driver */ -+typedef void (*MTK_WCN_STP_IF_RX) (const UINT8 *data, INT32 size); -+ -+typedef enum { -+ STP_UART_IF_TX = 0, -+ STP_SDIO_IF_TX = 1, -+ STP_BTIF_IF_TX = 2, -+ STP_MAX_IF_TX -+} ENUM_STP_TX_IF_TYPE; -+#endif -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+#ifndef MTK_WCN_WMT_STP_EXP_SYMBOL_ABSTRACT -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_receive_data -+* DESCRIPTION -+* receive data from serial protocol engine -+* PARAMETERS -+* buffer [IN] data buffer -+* length [IN] data buffer length -+* RETURNS -+* INT32 >= 0: size of data received; < 0: error -+*****************************************************************************/ -+extern INT32 mtk_wcn_stp_receive_data(UINT8 *buffer, UINT32 length, UINT8 type); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_send_data -+* DESCRIPTION -+* subfunction send data through STP -+* PARAMETERS -+* buffer [IN] data buffer -+* length [IN] data buffer length -+* type [IN] subfunction type -+* RETURNS -+* INT32 >= 0: length transmitted; < 0: error -+*****************************************************************************/ -+extern INT32 mtk_wcn_stp_send_data(const PUINT8 buffer, const UINT32 length, const UINT8 type); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_is_rxqueue_empty -+* DESCRIPTION -+* Is certain rx queue empty? -+* PARAMETERS -+* type [IN] subfunction type -+* RETURNS -+* INT32 0: queue is NOT empyt; !0: queue is empty -+*****************************************************************************/ -+extern MTK_WCN_BOOL mtk_wcn_stp_is_rxqueue_empty(UINT8 type); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_is_enable -+* DESCRIPTION -+* Is STP ready? -+* PARAMETERS -+* none. -+* RETURNS -+* MTK_WCN_BOOL TRUE:ready, FALSE:not ready -+*****************************************************************************/ -+extern MTK_WCN_BOOL mtk_wcn_stp_is_ready(void); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_parser_data -+* DESCRIPTION -+* push data to serial transport protocol parser engine -+* PARAMETERS -+* buffer [IN] data buffer -+* length [IN] data buffer length -+* RETURNS -+* void -+*****************************************************************************/ -+extern int mtk_wcn_stp_parser_data(UINT8 *buffer, UINT32 length); -+ -+/***************************************************************************** -+* FUNCTION -+* set_bluetooth_rx_interface -+* DESCRIPTION -+* Set bluetooth rx interface -+* PARAMETERS -+* rx interface type -+* RETURNS -+* void -+*****************************************************************************/ -+extern void mtk_wcn_stp_set_bluez(MTK_WCN_BOOL sdio_flag); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_register_tx_event_cb -+* DESCRIPTION -+* regiter Tx event callback function -+* PARAMETERS -+* func -+* RETURNS -+* int: 0:successful , -1: fail -+*****************************************************************************/ -+extern int mtk_wcn_stp_register_tx_event_cb(int type, MTK_WCN_STP_EVENT_CB func); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_register_event_cb -+* DESCRIPTION -+* regiter Rx event callback function -+* PARAMETERS -+* func -+* RETURNS -+* int: 0:successful , -1: fail -+*****************************************************************************/ -+extern int mtk_wcn_stp_register_event_cb(int type, MTK_WCN_STP_EVENT_CB func); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_register_if_tx -+* DESCRIPTION -+* regiter Tx event callback function -+* PARAMETERS -+* stp_if: SDIO or UART, fnnc: Call back function -+* RETURNS -+* int: 0:successful , -1: fail -+*****************************************************************************/ -+extern int mtk_wcn_stp_register_if_tx(ENUM_STP_TX_IF_TYPE stp_if, MTK_WCN_STP_IF_TX func); -+ -+/***************************************************************************** -+* FUNCTION -+* mtk_wcn_stp_register_if_rx -+* DESCRIPTION -+* regiter Rx event callback function -+* PARAMETERS -+* stp_if: SDIO or UART, fnnc: Call back function -+* RETURNS -+* int: 0:successful , -1: fail -+*****************************************************************************/ -+extern int mtk_wcn_stp_register_if_rx(MTK_WCN_STP_IF_RX func); -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#else -+extern INT32 _mtk_wcn_stp_receive_data(PUINT8 buffer, UINT32 length, UINT8 type); -+extern INT32 _mtk_wcn_stp_send_data_raw(const PUINT8 buffer, const UINT32 length, const UINT8 type); -+extern INT32 _mtk_wcn_stp_send_data(const PUINT8 buffer, const UINT32 length, const UINT8 type); -+extern MTK_WCN_BOOL _mtk_wcn_stp_is_rxqueue_empty(UINT8 type); -+extern MTK_WCN_BOOL _mtk_wcn_stp_is_ready(void); -+extern INT32 _mtk_wcn_stp_parser_data(UINT8 *buffer, UINT32 length); -+extern void _mtk_wcn_stp_set_bluez(MTK_WCN_BOOL sdio_flag); -+extern INT32 _mtk_wcn_stp_register_tx_event_cb(INT32 type, MTK_WCN_STP_EVENT_CB func); -+extern INT32 _mtk_wcn_stp_register_event_cb(INT32 type, MTK_WCN_STP_EVENT_CB func); -+extern INT32 _mtk_wcn_stp_register_if_tx(ENUM_STP_TX_IF_TYPE stp_if, MTK_WCN_STP_IF_TX func); -+extern INT32 _mtk_wcn_stp_register_if_rx(MTK_WCN_STP_IF_RX func); -+extern INT32 _mtk_wcn_stp_coredump_start_get(VOID); -+ -+#endif -+ -+#endif /* _WMT_EXP_H_ */ -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/include/wmt.h b/drivers/misc/mediatek/connectivity/common/conn_soc/include/wmt.h -new file mode 100644 -index 000000000000..6d10c3ff2659 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/include/wmt.h -@@ -0,0 +1,19 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -+ -+#ifndef _MTKWMT_H_ -+#define _MTKWMT_H_ -+#include "wmt_core.h" -+ -+#endif /*_MTKWMT_H_*/ -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/include/wmt_exp.h b/drivers/misc/mediatek/connectivity/common/conn_soc/include/wmt_exp.h -new file mode 100644 -index 000000000000..06238e07879f ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/include/wmt_exp.h -@@ -0,0 +1,329 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -+ -+/*! \file -+ \brief Declaration of library functions -+ -+ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. -+*/ -+ -+#ifndef _WMT_EXP_H_ -+#define _WMT_EXP_H_ -+ -+#include -+#include "osal.h" -+#include "wmt_plat.h" -+#include "wmt_stp_exp.h" -+/* not to reference to internal wmt */ -+/* #include "wmt_core.h" */ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+#if 1 /* moved from wmt_lib.h */ -+#ifndef DFT_TAG -+#define DFT_TAG "[WMT-DFT]" -+#endif -+ -+#define WMT_LOUD_FUNC(fmt, arg...) \ -+do { \ -+ if (gWmtDbgLvl >= WMT_LOG_LOUD) \ -+ osal_dbg_print(DFT_TAG "[L]%s:" fmt, __func__ , ##arg); \ -+} while (0) -+#define WMT_INFO_FUNC(fmt, arg...) \ -+do { \ -+ if (gWmtDbgLvl >= WMT_LOG_INFO) \ -+ osal_dbg_print(DFT_TAG "[I]%s:" fmt, __func__ , ##arg); \ -+} while (0) -+#define WMT_WARN_FUNC(fmt, arg...) \ -+do { \ -+ if (gWmtDbgLvl >= WMT_LOG_WARN) \ -+ osal_warn_print(DFT_TAG "[W]%s:" fmt, __func__ , ##arg); \ -+} while (0) -+#define WMT_ERR_FUNC(fmt, arg...) \ -+do { \ -+ if (gWmtDbgLvl >= WMT_LOG_ERR) \ -+ osal_err_print(DFT_TAG "[E]%s(%d):" fmt, __func__ , __LINE__, ##arg); \ -+} while (0) -+#define WMT_DBG_FUNC(fmt, arg...) \ -+do { \ -+ if (gWmtDbgLvl >= WMT_LOG_DBG) \ -+ osal_dbg_print(DFT_TAG "[D]%s:" fmt, __func__ , ##arg); \ -+} while (0) -+#define WMT_TRC_FUNC(f) \ -+do { \ -+ if (gWmtDbgLvl >= WMT_LOG_DBG) \ -+ osal_dbg_print(DFT_TAG "<%s> <%d>\n", __func__, __LINE__); \ -+} while (0) -+ -+#endif -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#if 1 /* moved from wmt_lib.h */ -+extern UINT32 gWmtDbgLvl; -+#endif -+extern OSAL_BIT_OP_VAR gBtWifiGpsState; -+extern OSAL_BIT_OP_VAR gGpsFmState; -+extern UINT32 gWifiProbed; -+extern MTK_WCN_BOOL g_pwr_off_flag; -+extern UINT32 g_IsNeedDoChipReset; -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+#if 1 /* moved from wmt_lib.h */ -+#define WMT_LOG_LOUD 4 -+#define WMT_LOG_DBG 3 -+#define WMT_LOG_INFO 2 -+#define WMT_LOG_WARN 1 -+#define WMT_LOG_ERR 0 -+#endif -+#define CFG_CORE_INTERNAL_TXRX 0 /*just do TX/RX in host side */ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+#ifndef MTK_WCN_WMT_STP_EXP_SYMBOL_ABSTRACT -+typedef enum _ENUM_WMTDRV_TYPE_T { -+ WMTDRV_TYPE_BT = 0, -+ WMTDRV_TYPE_FM = 1, -+ WMTDRV_TYPE_GPS = 2, -+ WMTDRV_TYPE_WIFI = 3, -+ WMTDRV_TYPE_WMT = 4, -+ WMTDRV_TYPE_STP = 5, -+ WMTDRV_TYPE_LPBK = 6, -+ WMTDRV_TYPE_COREDUMP = 7, -+ WMTDRV_TYPE_MAX -+} ENUM_WMTDRV_TYPE_T, *P_ENUM_WMTDRV_TYPE_T; -+ -+/* TODO: [ChangeFeature][GeorgeKuo] Reconsider usage of this type */ -+/* TODO: how do we extend for new chip and newer revision? */ -+/* TODO: This way is hard to extend */ -+typedef enum _ENUM_WMTHWVER_TYPE_T { -+ WMTHWVER_E1 = 0x0, -+ WMTHWVER_E2 = 0x1, -+ WMTHWVER_E3 = 0x2, -+ WMTHWVER_E4 = 0x3, -+ WMTHWVER_E5 = 0x4, -+ WMTHWVER_E6 = 0x5, -+ WMTHWVER_MAX, -+ WMTHWVER_INVALID = 0xff -+} ENUM_WMTHWVER_TYPE_T, *P_ENUM_WMTHWVER_TYPE_T; -+ -+typedef enum _ENUM_WMTDSNS_TYPE_T { -+ WMTDSNS_FM_DISABLE = 0, -+ WMTDSNS_FM_ENABLE = 1, -+ WMTDSNS_FM_GPS_DISABLE = 2, -+ WMTDSNS_FM_GPS_ENABLE = 3, -+ WMTDSNS_MAX -+} ENUM_WMTDSNS_TYPE_T, *P_ENUM_WMTDSNS_TYPE_T; -+ -+typedef enum _ENUM_WMTTHERM_TYPE_T { -+ WMTTHERM_ZERO = 0, -+ WMTTHERM_ENABLE = WMTTHERM_ZERO + 1, -+ WMTTHERM_READ = WMTTHERM_ENABLE + 1, -+ WMTTHERM_DISABLE = WMTTHERM_READ + 1, -+ WMTTHERM_MAX -+} ENUM_WMTTHERM_TYPE_T, *P_ENUM_WMTTHERM_TYPE_T; -+ -+typedef enum _ENUM_WMTMSG_TYPE_T { -+ WMTMSG_TYPE_POWER_ON = 0, -+ WMTMSG_TYPE_POWER_OFF = 1, -+ WMTMSG_TYPE_RESET = 2, -+ WMTMSG_TYPE_STP_RDY = 3, -+ WMTMSG_TYPE_HW_FUNC_ON = 4, -+ WMTMSG_TYPE_MAX -+} ENUM_WMTMSG_TYPE_T, *P_ENUM_WMTMSG_TYPE_T; -+ -+typedef void (*PF_WMT_CB) (ENUM_WMTDRV_TYPE_T, /* Source driver type */ -+ ENUM_WMTDRV_TYPE_T, /* Destination driver type */ -+ ENUM_WMTMSG_TYPE_T, /* Message type */ -+ VOID *, /* READ-ONLY buffer. Buffer is allocated and freed by WMT_drv. Client -+ can't touch this buffer after this function return. */ -+ UINT32 /* Buffer size in unit of byte */ -+); -+ -+typedef enum _SDIO_PS_OP { -+ OWN_SET = 0, -+ OWN_CLR = 1, -+ OWN_STATE = 2, -+} SDIO_PS_OP; -+ -+typedef INT32(*PF_WMT_SDIO_PSOP) (SDIO_PS_OP); -+ -+typedef enum _ENUM_WMTCHIN_TYPE_T { -+ WMTCHIN_CHIPID = 0x0, -+ WMTCHIN_HWVER = WMTCHIN_CHIPID + 1, -+ WMTCHIN_MAPPINGHWVER = WMTCHIN_HWVER + 1, -+ WMTCHIN_FWVER = WMTCHIN_MAPPINGHWVER + 1, -+ WMTCHIN_MAX, -+ -+} ENUM_WMT_CHIPINFO_TYPE_T, *P_ENUM_WMT_CHIPINFO_TYPE_T; -+ -+#endif -+ -+typedef enum _ENUM_WMTRSTMSG_TYPE_T { -+ WMTRSTMSG_RESET_START = 0x0, -+ WMTRSTMSG_RESET_END = 0x1, -+ WMTRSTMSG_RESET_END_FAIL = 0x2, -+ WMTRSTMSG_RESET_MAX, -+ WMTRSTMSG_RESET_INVALID = 0xff -+} ENUM_WMTRSTMSG_TYPE_T, *P_ENUM_WMTRSTMSG_TYPE_T; -+ -+typedef enum _ENUM_BT_GPS_ONOFF_STATE_T { -+ WMT_BT_ON = 0, -+ WMT_GPS_ON = 1, -+ WMT_WIFI_ON = 2, -+ WMT_FM_ON = 3, -+ WMT_BT_GPS_STATE_MAX, -+ WMT_BT_GPS_STATE_INVALID = 0xff -+} ENUM_BT_GPS_ONOFF_STATE_T, *P_ENUM_BT_GPS_ONOFF_STATE_T; -+ -+#if 1 /* moved from wmt_core.h */ -+typedef enum { -+ WMT_SDIO_SLOT_INVALID = 0, -+ WMT_SDIO_SLOT_SDIO1 = 1, /* Wi-Fi dedicated SDIO1 */ -+ WMT_SDIO_SLOT_SDIO2 = 2, -+ WMT_SDIO_SLOT_MAX -+} WMT_SDIO_SLOT_NUM; -+ -+typedef enum { -+ WMT_SDIO_FUNC_STP = 0, -+ WMT_SDIO_FUNC_WIFI = 1, -+ WMT_SDIO_FUNC_MAX -+} WMT_SDIO_FUNC_TYPE; -+#endif -+ -+typedef INT32(*wmt_wlan_probe_cb) (VOID); -+typedef INT32(*wmt_wlan_remove_cb) (VOID); -+typedef INT32(*wmt_wlan_bus_cnt_get_cb) (VOID); -+typedef INT32(*wmt_wlan_bus_cnt_clr_cb) (VOID); -+ -+typedef struct _MTK_WCN_WMT_WLAN_CB_INFO { -+ wmt_wlan_probe_cb wlan_probe_cb; -+ wmt_wlan_remove_cb wlan_remove_cb; -+ wmt_wlan_bus_cnt_get_cb wlan_bus_cnt_get_cb; -+ wmt_wlan_bus_cnt_clr_cb wlan_bus_cnt_clr_cb; -+} MTK_WCN_WMT_WLAN_CB_INFO, *P_MTK_WCN_WMT_WLAN_CB_INFO; -+ -+#ifdef CONFIG_MTK_COMBO_ANT -+typedef enum _ENUM_WMT_ANT_RAM_CTRL_T { -+ WMT_ANT_RAM_GET_STATUS = 0, -+ WMT_ANT_RAM_DOWNLOAD = WMT_ANT_RAM_GET_STATUS + 1, -+ WMT_ANT_RAM_CTRL_MAX -+} ENUM_WMT_ANT_RAM_CTRL, *P_ENUM_WMT_ANT_RAM_CTRL; -+ -+typedef enum _ENUM_WMT_ANT_RAM_SEQ_T { -+ WMT_ANT_RAM_START_PKT = 1, -+ WMT_ANT_RAM_CONTINUE_PKT = WMT_ANT_RAM_START_PKT + 1, -+ WMT_ANT_RAM_END_PKT = WMT_ANT_RAM_CONTINUE_PKT + 1, -+ WMT_ANT_RAM_SEQ_MAX -+} ENUM_WMT_ANT_RAM_SEQ, *P_ENUM_WMT_ANT_RAM_SEQ; -+ -+typedef enum _ENUM_WMT_ANT_RAM_STATUS_T { -+ WMT_ANT_RAM_NOT_EXIST = 0, -+ WMT_ANT_RAM_EXIST = WMT_ANT_RAM_NOT_EXIST + 1, -+ WMT_ANT_RAM_DOWN_OK = WMT_ANT_RAM_EXIST + 1, -+ WMT_ANT_RAM_DOWN_FAIL = WMT_ANT_RAM_DOWN_OK + 1, -+ WMT_ANT_RAM_PARA_ERR = WMT_ANT_RAM_DOWN_FAIL + 1, -+ WMT_ANT_RAM_OP_ERR = WMT_ANT_RAM_PARA_ERR + 1, -+ WMT_ANT_RAM_MAX -+} ENUM_WMT_ANT_RAM_STATUS, *P_ENUM_WMT_ANT_RAM_STATUS; -+#endif -+ -+extern INT32 mtk_wcn_wmt_wlan_reg(P_MTK_WCN_WMT_WLAN_CB_INFO pWmtWlanCbInfo); -+extern INT32 mtk_wcn_wmt_wlan_unreg(VOID); -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+extern wmt_wlan_probe_cb mtk_wcn_wlan_probe; -+extern wmt_wlan_remove_cb mtk_wcn_wlan_remove; -+extern wmt_wlan_bus_cnt_get_cb mtk_wcn_wlan_bus_tx_cnt; -+extern wmt_wlan_bus_cnt_clr_cb mtk_wcn_wlan_bus_tx_cnt_clr; -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+/*subsystem function ctrl APIs*/ -+extern MTK_WCN_BOOL mtk_wcn_wmt_assert(ENUM_WMTDRV_TYPE_T type, UINT32 reason); -+ -+#ifndef MTK_WCN_WMT_STP_EXP_SYMBOL_ABSTRACT -+#define WMT_EXP_HID_API_EXPORT 0 -+ -+extern MTK_WCN_BOOL mtk_wcn_wmt_func_off(ENUM_WMTDRV_TYPE_T type); -+ -+extern MTK_WCN_BOOL mtk_wcn_wmt_func_on(ENUM_WMTDRV_TYPE_T type); -+ -+extern MTK_WCN_BOOL mtk_wcn_wmt_dsns_ctrl(ENUM_WMTDSNS_TYPE_T eType); -+ -+extern MTK_WCN_BOOL mtk_wcn_wmt_assert(ENUM_WMTDRV_TYPE_T type, UINT32 reason); -+ -+extern INT32 mtk_wcn_wmt_msgcb_reg(ENUM_WMTDRV_TYPE_T eType, PF_WMT_CB pCb); -+ -+extern INT32 mtk_wcn_wmt_msgcb_unreg(ENUM_WMTDRV_TYPE_T eType); -+ -+extern INT32 mtk_wcn_stp_wmt_sdio_op_reg(PF_WMT_SDIO_PSOP own_cb); -+ -+extern INT32 mtk_wcn_stp_wmt_sdio_host_awake(VOID); -+/* -+return value: -+enable/disable thermal sensor function: true(1)/false(0) -+read thermal sensor function: thermal value -+ -+*/ -+extern INT8 mtk_wcn_wmt_therm_ctrl(ENUM_WMTTHERM_TYPE_T eType); -+ -+extern ENUM_WMTHWVER_TYPE_T mtk_wcn_wmt_hwver_get(VOID); -+ -+#else -+#define WMT_EXP_HID_API_EXPORT 1 -+#endif -+ -+#ifdef CONFIG_MTK_COMBO_ANT -+extern ENUM_WMT_ANT_RAM_STATUS mtk_wcn_wmt_ant_ram_ctrl(ENUM_WMT_ANT_RAM_CTRL ctrlId, PUINT8 pBuf, -+ UINT32 length, ENUM_WMT_ANT_RAM_SEQ seq); -+#endif -+extern INT32 wmt_lib_set_aif(CMB_STUB_AIF_X aif, MTK_WCN_BOOL share); /* set AUDIO interface options */ -+extern VOID wmt_lib_ps_irq_cb(VOID); -+ -+extern VOID mtk_wcn_wmt_func_ctrl_for_plat(UINT32 on, ENUM_WMTDRV_TYPE_T type); -+ -+extern INT32 mtk_wcn_wmt_system_state_reset(VOID); -+extern MTK_WCN_BOOL mtk_wcn_set_connsys_power_off_flag(MTK_WCN_BOOL value); -+#ifdef MTK_WCN_WMT_STP_EXP_SYMBOL_ABSTRACT -+extern VOID mtk_wcn_wmt_exp_init(VOID); -+extern VOID mtk_wcn_wmt_exp_deinit(VOID); -+#endif -+extern INT8 mtk_wcn_wmt_co_clock_flag_get(VOID); -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif /* _WMT_EXP_H_ */ -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/include/wmt_plat.h b/drivers/misc/mediatek/connectivity/common/conn_soc/include/wmt_plat.h -new file mode 100644 -index 000000000000..075496cac54f ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/include/wmt_plat.h -@@ -0,0 +1,295 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -+ -+/*! \file -+ \brief Declaration of library functions -+ -+ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. -+*/ -+ -+#ifndef _WMT_PLAT_H_ -+#define _WMT_PLAT_H_ -+#include "osal_typedef.h" -+#include "stp_exp.h" -+#include -+ -+/* #include "mtk_wcn_consys_hw.h" */ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+#if 1 /* moved from wmt_exp.h */ -+#ifndef DFT_TAG -+#define DFT_TAG "[WMT-DFT]" -+#endif -+ -+#define WMT_PLAT_LOG_LOUD 4 -+#define WMT_PLAT_LOG_DBG 3 -+#define WMT_PLAT_LOG_INFO 2 -+#define WMT_PLAT_LOG_WARN 1 -+#define WMT_PLAT_LOG_ERR 0 -+ -+extern UINT32 wmtPlatLogLvl; -+ -+#define WMT_PLAT_LOUD_FUNC(fmt, arg...) \ -+do { \ -+ if (wmtPlatLogLvl >= WMT_PLAT_LOG_LOUD) \ -+ pr_debug(DFT_TAG "[L]%s:" fmt, __func__ , ##arg); \ -+} while (0) -+#define WMT_PLAT_INFO_FUNC(fmt, arg...) \ -+do { \ -+ if (wmtPlatLogLvl >= WMT_PLAT_LOG_INFO) \ -+ pr_debug(DFT_TAG "[I]%s:" fmt, __func__ , ##arg); \ -+} while (0) -+#define WMT_PLAT_WARN_FUNC(fmt, arg...) \ -+do { \ -+ if (wmtPlatLogLvl >= WMT_PLAT_LOG_WARN) \ -+ pr_warn(DFT_TAG "[W]%s:" fmt, __func__ , ##arg); \ -+} while (0) -+#define WMT_PLAT_ERR_FUNC(fmt, arg...) \ -+do { \ -+ if (wmtPlatLogLvl >= WMT_PLAT_LOG_ERR) \ -+ pr_err(DFT_TAG "[E]%s(%d):" fmt, __func__ , __LINE__, ##arg); \ -+} while (0) -+#define WMT_PLAT_DBG_FUNC(fmt, arg...) \ -+do { \ -+ if (wmtPlatLogLvl >= WMT_PLAT_LOG_DBG) \ -+ pr_debug(DFT_TAG "[D]%s:" fmt, __func__ , ##arg); \ -+} while (0) -+ -+#endif -+ -+#define CFG_WMT_PS_SUPPORT 1 /* moved from wmt_exp.h */ -+ -+#define CFG_WMT_DUMP_INT_STATUS 0 -+#define CONSYS_ENALBE_SET_JTAG 1 -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+typedef enum _ENUM_FUNC_STATE_ { -+ FUNC_ON = 0, -+ FUNC_OFF = 1, -+ FUNC_RST = 2, -+ FUNC_STAT = 3, -+ FUNC_CTRL_MAX, -+} ENUM_FUNC_STATE, *P_ENUM_FUNC_STATE; -+ -+typedef enum _ENUM_PIN_ID_ { -+ PIN_BGF_EINT = 0, -+ PIN_I2S_GRP = 1, -+ PIN_GPS_SYNC = 2, -+ PIN_GPS_LNA = 3, -+#if CFG_WMT_LTE_COEX_HANDLING -+ PIN_TDM_REQ = 4, -+#endif -+ PIN_ID_MAX -+} ENUM_PIN_ID, *P_ENUM_PIN_ID; -+ -+typedef enum _ENUM_PIN_STATE_ { -+ PIN_STA_INIT = 0, -+ PIN_STA_OUT_L = 1, -+ PIN_STA_OUT_H = 2, -+ PIN_STA_IN_L = 3, -+ PIN_STA_MUX = 4, -+ PIN_STA_EINT_EN = 5, -+ PIN_STA_EINT_DIS = 6, -+ PIN_STA_DEINIT = 7, -+ PIN_STA_SHOW = 8, -+ PIN_STA_MAX -+} ENUM_PIN_STATE, *P_ENUM_PIN_STATE; -+ -+typedef enum _CMB_IF_TYPE_ { -+ CMB_IF_UART = 0, -+ CMB_IF_WIFI_SDIO = 1, -+ CMB_IF_BGF_SDIO = 2, -+ CMB_IF_BGWF_SDIO = 3, -+ CMB_IF_TYPE_MAX -+} CMB_IF_TYPE, *P_CMB_IF_TYPE; -+ -+typedef INT32(*fp_set_pin) (ENUM_PIN_STATE); -+ -+typedef enum _ENUM_WL_OP_ { -+ WL_OP_GET = 0, -+ WL_OP_PUT = 1, -+ WL_OP_MAX -+} ENUM_WL_OP, *P_ENUM_WL_OP; -+ -+typedef enum _ENUM_PALDO_TYPE_ { -+ BT_PALDO = 0, -+ WIFI_PALDO = 1, -+ FM_PALDO = 2, -+ GPS_PALDO = 3, -+ PMIC_CHIPID_PALDO = 4, -+ WIFI_5G_PALDO = 5, -+ PALDO_TYPE_MAX -+} ENUM_PALDO_TYPE, *P_ENUM_PALDO_TYPE; -+ -+typedef enum _ENUM_PALDO_OP_ { -+ PALDO_OFF = 0, -+ PALDO_ON = 1, -+ PALDO_OP_MAX -+} ENUM_PALDO_OP, *P_ENUM_PALDO_OP; -+ -+typedef enum _ENUM_HOST_DUMP_STATE_T { -+ STP_HOST_DUMP_NOT_START = 0, -+ STP_HOST_DUMP_GET = 1, -+ STP_HOST_DUMP_GET_DONE = 2, -+ STP_HOST_DUMP_END = 3, -+ STP_HOST_DUMP_MAX -+} ENUM_HOST_DUMP_STATE, *P_ENUM_HOST_DUMP_STATE_T; -+ -+typedef enum _ENUM_FORCE_TRG_ASSERT_T { -+ STP_FORCE_TRG_ASSERT_EMI = 0, -+ STP_FORCE_TRG_ASSERT_DEBUG_PIN = 1, -+ STP_FORCE_TRG_ASSERT_MAX = 2 -+} ENUM_FORCE_TRG_ASSERT_T, *P_ENUM_FORCE_TRG_ASSERT_T; -+ -+typedef enum _ENUM_CHIP_DUMP_STATE_T { -+ STP_CHIP_DUMP_NOT_START = 0, -+ STP_CHIP_DUMP_PUT = 1, -+ STP_CHIP_DUMP_PUT_DONE = 2, -+ STP_CHIP_DUMP_END = 3, -+ STP_CHIP_DUMP_MAX -+} ENUM_CHIP_DUMP_STATE, *P_ENUM_CHIP_DUMP_STATE_T; -+ -+typedef struct _EMI_CTRL_STATE_OFFSET_ { -+ UINT32 emi_apmem_ctrl_state; -+ UINT32 emi_apmem_ctrl_host_sync_state; -+ UINT32 emi_apmem_ctrl_host_sync_num; -+ UINT32 emi_apmem_ctrl_chip_sync_state; -+ UINT32 emi_apmem_ctrl_chip_sync_num; -+ UINT32 emi_apmem_ctrl_chip_sync_addr; -+ UINT32 emi_apmem_ctrl_chip_sync_len; -+ UINT32 emi_apmem_ctrl_chip_print_buff_start; -+ UINT32 emi_apmem_ctrl_chip_print_buff_len; -+ UINT32 emi_apmem_ctrl_chip_print_buff_idx; -+ UINT32 emi_apmem_ctrl_chip_int_status; -+ UINT32 emi_apmem_ctrl_chip_paded_dump_end; -+ UINT32 emi_apmem_ctrl_host_outband_assert_w1; -+ UINT32 emi_apmem_ctrl_chip_page_dump_num; -+} EMI_CTRL_STATE_OFFSET, *P_EMI_CTRL_STATE_OFFSET; -+ -+typedef struct _BGF_IRQ_BALANCE_ { -+ UINT32 counter; -+ unsigned long flags; -+ spinlock_t lock; -+} BGF_IRQ_BALANCE, *P_BGF_IRQ_BALANCE; -+ -+typedef struct _CONSYS_EMI_ADDR_INFO_ { -+ UINT32 emi_phy_addr; -+ UINT32 paged_trace_off; -+ UINT32 paged_dump_off; -+ UINT32 full_dump_off; -+ P_EMI_CTRL_STATE_OFFSET p_ecso; -+} CONSYS_EMI_ADDR_INFO, *P_CONSYS_EMI_ADDR_INFO; -+ -+typedef struct _GPIO_TDM_REQ_INFO_ { -+ UINT32 ant_sel_index; -+ UINT32 gpio_number; -+ UINT32 cr_address; -+} GPIO_TDM_REQ_INFO, *P_GPIO_TDM_REQ_INFO; -+ -+typedef VOID(*irq_cb) (VOID); -+typedef INT32(*device_audio_if_cb) (CMB_STUB_AIF_X aif, MTK_WCN_BOOL share); -+typedef VOID(*func_ctrl_cb) (UINT32 on, UINT32 type); -+typedef long (*thermal_query_ctrl_cb) (VOID); -+typedef INT32(*deep_idle_ctrl_cb) (UINT32); -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+extern UINT32 gWmtDbgLvl; -+extern struct device *wmt_dev; -+#ifdef CFG_WMT_READ_EFUSE_VCN33 -+extern INT32 wmt_set_pmic_voltage(UINT32 level); -+#endif -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+INT32 wmt_plat_init(UINT32 co_clock_type); -+ -+INT32 wmt_plat_deinit(VOID); -+ -+INT32 wmt_plat_pwr_ctrl(ENUM_FUNC_STATE state); -+ -+INT32 wmt_plat_gpio_ctrl(ENUM_PIN_ID id, ENUM_PIN_STATE state); -+ -+INT32 wmt_plat_eirq_ctrl(ENUM_PIN_ID id, ENUM_PIN_STATE state); -+ -+INT32 wmt_plat_wake_lock_ctrl(ENUM_WL_OP opId); -+ -+INT32 wmt_plat_audio_ctrl(CMB_STUB_AIF_X state, CMB_STUB_AIF_CTRL ctrl); -+ -+VOID wmt_plat_irq_cb_reg(irq_cb bgf_irq_cb); -+VOID wmt_plat_aif_cb_reg(device_audio_if_cb aif_ctrl_cb); -+VOID wmt_plat_func_ctrl_cb_reg(func_ctrl_cb subsys_func_ctrl); -+VOID wmt_plat_thermal_ctrl_cb_reg(thermal_query_ctrl_cb thermal_query_ctrl); -+VOID wmt_plat_deep_idle_ctrl_cb_reg(deep_idle_ctrl_cb deep_idle_ctrl); -+ -+INT32 wmt_plat_soc_paldo_ctrl(ENUM_PALDO_TYPE ePt, ENUM_PALDO_OP ePo); -+UINT8 *wmt_plat_get_emi_virt_add(UINT32 offset); -+#if CONSYS_ENALBE_SET_JTAG -+UINT32 wmt_plat_jtag_flag_ctrl(UINT32 en); -+#endif -+#if CFG_WMT_DUMP_INT_STATUS -+VOID wmt_plat_BGF_irq_dump_status(VOID); -+MTK_WCN_BOOL wmt_plat_dump_BGF_irq_status(VOID); -+#endif -+P_CONSYS_EMI_ADDR_INFO wmt_plat_get_emi_phy_add(VOID); -+UINT32 wmt_plat_read_cpupcr(VOID); -+UINT32 wmt_plat_read_dmaregs(UINT32); -+INT32 wmt_plat_set_host_dump_state(ENUM_HOST_DUMP_STATE state); -+UINT32 wmt_plat_force_trigger_assert(ENUM_FORCE_TRG_ASSERT_T type); -+INT32 wmt_plat_update_host_sync_num(VOID); -+INT32 wmt_plat_get_dump_info(UINT32 offset); -+UINT32 wmt_plat_get_soc_chipid(VOID); -+INT32 wmt_plat_set_dbg_mode(UINT32 flag); -+VOID wmt_plat_set_dynamic_dumpmem(UINT32 *buf); -+#if CFG_WMT_LTE_COEX_HANDLING -+INT32 wmt_plat_get_tdm_antsel_index(VOID); -+#endif -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif /* _WMT_PLAT_H_ */ -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/linux/Makefile b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/Makefile -new file mode 100644 -index 000000000000..905207118938 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/Makefile -@@ -0,0 +1,6 @@ -+ifeq ($(CONFIG_MTK_COMBO), y) -+ -+obj-y += pub/ -+obj-y += pri/ -+ -+endif -\ No newline at end of file -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/linux/include/bgw_desense.h b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/include/bgw_desense.h -new file mode 100644 -index 000000000000..95d1ab02a9fa ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/include/bgw_desense.h -@@ -0,0 +1,74 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -+ -+#ifndef __BGW_DESENSE_H_ -+#define __BGW_DESENSE_H_ -+ -+#ifdef MSG -+#undef MSG -+#endif -+ -+#ifdef ERR -+#undef ERR -+#endif -+ -+#define PFX1 "[BWG] " -+#define MSG(fmt, arg ...) pr_debug(PFX1 "[D]%s: " fmt, __func__ , ##arg) -+#define ERR(fmt, arg ...) pr_debug(PFX1 "[D]%s: " fmt, __func__ , ##arg) -+ -+#ifdef NETLINK_TEST -+#undef NETLINK_TEST -+#endif -+ -+#define NETLINK_TEST 17 -+ -+#ifdef MAX_NL_MSG_LEN -+#undef MAX_NL_MSG_LEN -+#endif -+ -+#define MAX_NL_MSG_LEN 1024 -+ -+ -+#ifdef ON -+#undef ON -+#endif -+#ifdef OFF -+#undef OFF -+#endif -+#ifdef ACK -+#undef ACK -+#endif -+ -+#define ON 1 -+#define OFF 0 -+#define ACK 2 -+ -+/* -+used send command to native process -+ -+parameter: command could be macro ON: enable co-exist; OFF: disable co-exist; -+ACK: after get native process init message send ACK -+ -+*/ -+extern void send_command_to_daemon(const int command); -+ -+/* -+before use kernel socket, please call init socket first -+return value: 0: ok; -1: fail -+*/ -+extern int bgw_init_socket(void); -+ -+extern void bgw_destroy_netlink_kernel(void); -+ -+#endif -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/linux/include/osal.h b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/include/osal.h -new file mode 100644 -index 000000000000..cf3e830003ac ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/include/osal.h -@@ -0,0 +1,349 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -+ -+/*! \file -+ \brief Declaration of library functions -+ -+ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. -+*/ -+ -+#ifndef _OSAL_H_ -+#define _OSAL_H_ -+ -+#include -+#include -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+#define OS_BIT_OPS_SUPPORT 1 -+ -+#define _osal_inline_ inline -+ -+#define MAX_THREAD_NAME_LEN 16 -+#define MAX_WAKE_LOCK_NAME_LEN 16 -+#define OSAL_OP_BUF_SIZE 64 -+ -+#if (defined(CONFIG_MTK_GMO_RAM_OPTIMIZE) && !defined(CONFIG_MT_ENG_BUILD)) -+#define OSAL_OP_DATA_SIZE 8 -+#else -+#define OSAL_OP_DATA_SIZE 32 -+#endif -+ -+#define DBG_LOG_STR_SIZE 256 -+ -+#define osal_sizeof(x) sizeof(x) -+ -+#define osal_array_size(x) (sizeof(x)/sizeof(x[0])) -+ -+#ifndef NAME_MAX -+#define NAME_MAX 256 -+#endif -+ -+#define WMT_OP_BIT(x) (0x1UL << x) -+#define WMT_OP_HIF_BIT WMT_OP_BIT(0) -+ -+#define RB_SIZE(prb) ((prb)->size) -+#define RB_MASK(prb) (RB_SIZE(prb) - 1) -+#define RB_COUNT(prb) ((prb)->write - (prb)->read) -+#define RB_FULL(prb) (RB_COUNT(prb) >= RB_SIZE(prb)) -+#define RB_EMPTY(prb) ((prb)->write == (prb)->read) -+ -+#define RB_INIT(prb, qsize) \ -+do { \ -+ (prb)->read = (prb)->write = 0; \ -+ (prb)->size = (qsize); \ -+} while (0) -+ -+#define RB_PUT(prb, value) \ -+do { \ -+ if (!RB_FULL(prb)) { \ -+ (prb)->queue[(prb)->write & RB_MASK(prb)] = value; \ -+ ++((prb)->write); \ -+ } \ -+ else { \ -+ osal_assert(!RB_FULL(prb)); \ -+ } \ -+} while (0) -+ -+#define RB_GET(prb, value) \ -+do { \ -+ if (!RB_EMPTY(prb)) { \ -+ value = (prb)->queue[(prb)->read & RB_MASK(prb)]; \ -+ ++((prb)->read); \ -+ if (RB_EMPTY(prb)) { \ -+ (prb)->read = (prb)->write = 0; \ -+ } \ -+ } \ -+ else { \ -+ value = NULL; \ -+ osal_assert(!RB_EMPTY(prb)); \ -+ } \ -+} while (0) -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+//typedef VOID(*P_TIMEOUT_HANDLER) (unsigned long); -+typedef VOID(*P_TIMEOUT_HANDLER) (struct timer_list *t); -+typedef INT32(*P_COND) (VOID *); -+ -+typedef struct _OSAL_TIMER_ { -+ struct timer_list timer; -+ P_TIMEOUT_HANDLER timeoutHandler; -+ unsigned long timeroutHandlerData; -+} OSAL_TIMER, *P_OSAL_TIMER; -+ -+typedef struct _OSAL_UNSLEEPABLE_LOCK_ { -+ spinlock_t lock; -+ unsigned long flag; -+} OSAL_UNSLEEPABLE_LOCK, *P_OSAL_UNSLEEPABLE_LOCK; -+ -+typedef struct _OSAL_SLEEPABLE_LOCK_ { -+ struct mutex lock; -+} OSAL_SLEEPABLE_LOCK, *P_OSAL_SLEEPABLE_LOCK; -+ -+typedef struct _OSAL_SIGNAL_ { -+ struct completion comp; -+ UINT32 timeoutValue; -+} OSAL_SIGNAL, *P_OSAL_SIGNAL; -+ -+typedef struct _OSAL_EVENT_ { -+ wait_queue_head_t waitQueue; -+/* VOID *pWaitQueueData; */ -+ UINT32 timeoutValue; -+ INT32 waitFlag; -+ -+} OSAL_EVENT, *P_OSAL_EVENT; -+ -+typedef struct _OSAL_THREAD_ { -+ struct task_struct *pThread; -+ VOID *pThreadFunc; -+ VOID *pThreadData; -+ char threadName[MAX_THREAD_NAME_LEN]; -+} OSAL_THREAD, *P_OSAL_THREAD; -+ -+typedef struct _OSAL_FIFO_ { -+ /*fifo definition */ -+ VOID *pFifoBody; -+ spinlock_t fifoSpinlock; -+ /*fifo operations */ -+ INT32 (*FifoInit)(struct _OSAL_FIFO_ *pFifo, UINT8 *buf, UINT32); -+ INT32 (*FifoDeInit)(struct _OSAL_FIFO_ *pFifo); -+ INT32 (*FifoReset)(struct _OSAL_FIFO_ *pFifo); -+ INT32 (*FifoSz)(struct _OSAL_FIFO_ *pFifo); -+ INT32 (*FifoAvailSz)(struct _OSAL_FIFO_ *pFifo); -+ INT32 (*FifoLen)(struct _OSAL_FIFO_ *pFifo); -+ INT32 (*FifoIsEmpty)(struct _OSAL_FIFO_ *pFifo); -+ INT32 (*FifoIsFull)(struct _OSAL_FIFO_ *pFifo); -+ INT32 (*FifoDataIn)(struct _OSAL_FIFO_ *pFifo, const VOID *buf, UINT32 len); -+ INT32 (*FifoDataOut)(struct _OSAL_FIFO_ *pFifo, void *buf, UINT32 len); -+} OSAL_FIFO, *P_OSAL_FIFO; -+ -+typedef struct firmware osal_firmware; -+ -+typedef struct _OSAL_OP_DAT { -+ UINT32 opId; /* Event ID */ -+ UINT32 u4InfoBit; /* Reserved */ -+ SIZE_T au4OpData[OSAL_OP_DATA_SIZE]; /* OP Data */ -+} OSAL_OP_DAT, *P_OSAL_OP_DAT; -+ -+typedef struct _OSAL_LXOP_ { -+ OSAL_OP_DAT op; -+ OSAL_SIGNAL signal; -+ INT32 result; -+} OSAL_OP, *P_OSAL_OP; -+ -+typedef struct _OSAL_LXOP_Q { -+ OSAL_SLEEPABLE_LOCK sLock; -+ UINT32 write; -+ UINT32 read; -+ UINT32 size; -+ P_OSAL_OP queue[OSAL_OP_BUF_SIZE]; -+} OSAL_OP_Q, *P_OSAL_OP_Q; -+ -+typedef struct _OSAL_WAKE_LOCK_ { -+ #ifdef CONFIG_PM_WAKELOCKS -+ struct wakeup_source wake_lock; -+ #else -+ struct wake_lock wake_lock; -+ #endif -+ UINT8 name[MAX_WAKE_LOCK_NAME_LEN]; -+} OSAL_WAKE_LOCK, *P_OSAL_WAKE_LOCK; -+#if 1 -+typedef struct _OSAL_BIT_OP_VAR_ { -+ unsigned long data; -+ OSAL_UNSLEEPABLE_LOCK opLock; -+} OSAL_BIT_OP_VAR, *P_OSAL_BIT_OP_VAR; -+#else -+#define OSAL_BIT_OP_VAR unsigned long -+#define P_OSAL_BIT_OP_VAR unsigned long * -+ -+#endif -+typedef UINT32(*P_OSAL_EVENT_CHECKER) (P_OSAL_THREAD pThread); -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+extern UINT32 osal_strlen(const char *str); -+extern INT32 osal_strcmp(const char *dst, const char *src); -+extern INT32 osal_strncmp(const char *dst, const char *src, UINT32 len); -+extern char *osal_strcpy(char *dst, const char *src); -+extern char *osal_strncpy(char *dst, const char *src, UINT32 len); -+extern char *osal_strcat(char *dst, const char *src); -+extern char *osal_strncat(char *dst, const char *src, UINT32 len); -+extern char *osal_strchr(const char *str, UINT8 c); -+extern char *osal_strsep(char **str, const char *c); -+extern int osal_strtol(const char *str, UINT32 adecimal, long *res); -+extern INT32 osal_snprintf(char *buf, UINT32 len, const char *fmt, ...); -+extern char *osal_strstr(char *str1, const char *str2); -+ -+extern INT32 osal_err_print(const char *str, ...); -+extern INT32 osal_dbg_print(const char *str, ...); -+extern INT32 osal_warn_print(const char *str, ...); -+ -+extern INT32 osal_dbg_assert(INT32 expr, const char *file, INT32 line); -+extern INT32 osal_sprintf(char *str, const char *format, ...); -+extern VOID *osal_malloc(UINT32 size); -+extern VOID osal_free(const VOID *dst); -+extern VOID *osal_memset(VOID *buf, INT32 i, UINT32 len); -+extern VOID *osal_memcpy(VOID *dst, const VOID *src, UINT32 len); -+extern INT32 osal_memcmp(const VOID *buf1, const VOID *buf2, UINT32 len); -+ -+extern INT32 osal_sleep_ms(UINT32 ms); -+extern INT32 osal_udelay(UINT32 us); -+extern INT32 osal_timer_create(P_OSAL_TIMER); -+extern INT32 osal_timer_start(P_OSAL_TIMER, UINT32); -+extern INT32 osal_timer_stop(P_OSAL_TIMER); -+extern INT32 osal_timer_stop_sync(P_OSAL_TIMER pTimer); -+extern INT32 osal_timer_modify(P_OSAL_TIMER, UINT32); -+extern INT32 osal_timer_delete(P_OSAL_TIMER); -+ -+extern INT32 osal_fifo_init(P_OSAL_FIFO pFifo, UINT8 *buffer, UINT32 size); -+extern VOID osal_fifo_deinit(P_OSAL_FIFO pFifo); -+extern INT32 osal_fifo_reset(P_OSAL_FIFO pFifo); -+extern UINT32 osal_fifo_in(P_OSAL_FIFO pFifo, PUINT8 buffer, UINT32 size); -+extern UINT32 osal_fifo_out(P_OSAL_FIFO pFifo, PUINT8 buffer, UINT32 size); -+extern UINT32 osal_fifo_len(P_OSAL_FIFO pFifo); -+extern UINT32 osal_fifo_sz(P_OSAL_FIFO pFifo); -+extern UINT32 osal_fifo_avail(P_OSAL_FIFO pFifo); -+extern UINT32 osal_fifo_is_empty(P_OSAL_FIFO pFifo); -+extern UINT32 osal_fifo_is_full(P_OSAL_FIFO pFifo); -+ -+extern INT32 osal_wake_lock_init(P_OSAL_WAKE_LOCK plock); -+extern INT32 osal_wake_lock(P_OSAL_WAKE_LOCK plock); -+extern INT32 osal_wake_unlock(P_OSAL_WAKE_LOCK plock); -+extern INT32 osal_wake_lock_count(P_OSAL_WAKE_LOCK plock); -+extern INT32 osal_wake_lock_deinit(P_OSAL_WAKE_LOCK plock); -+ -+#if defined(CONFIG_PROVE_LOCKING) -+#define osal_unsleepable_lock_init(l) { spin_lock_init(&((l)->lock)); } -+#else -+extern INT32 osal_unsleepable_lock_init(P_OSAL_UNSLEEPABLE_LOCK); -+#endif -+extern INT32 osal_lock_unsleepable_lock(P_OSAL_UNSLEEPABLE_LOCK); -+extern INT32 osal_unlock_unsleepable_lock(P_OSAL_UNSLEEPABLE_LOCK); -+extern INT32 osal_unsleepable_lock_deinit(P_OSAL_UNSLEEPABLE_LOCK); -+ -+#if defined(CONFIG_PROVE_LOCKING) -+#define osal_sleepable_lock_init(l) { mutex_init(&((l)->lock)); } -+#else -+extern INT32 osal_sleepable_lock_init(P_OSAL_SLEEPABLE_LOCK); -+#endif -+extern INT32 osal_lock_sleepable_lock(P_OSAL_SLEEPABLE_LOCK); -+extern INT32 osal_unlock_sleepable_lock(P_OSAL_SLEEPABLE_LOCK); -+extern INT32 osal_sleepable_lock_deinit(P_OSAL_SLEEPABLE_LOCK); -+ -+extern INT32 osal_signal_init(P_OSAL_SIGNAL); -+extern INT32 osal_wait_for_signal(P_OSAL_SIGNAL); -+extern INT32 osal_wait_for_signal_timeout(P_OSAL_SIGNAL); -+extern INT32 osal_raise_signal(P_OSAL_SIGNAL); -+extern INT32 osal_signal_deinit(P_OSAL_SIGNAL); -+ -+extern INT32 osal_event_init(P_OSAL_EVENT); -+extern INT32 osal_wait_for_event(P_OSAL_EVENT, P_COND, void *); -+extern INT32 osal_wait_for_event_timeout(P_OSAL_EVENT, P_COND, void *); -+extern INT32 osal_trigger_event(P_OSAL_EVENT); -+ -+extern INT32 osal_event_deinit(P_OSAL_EVENT); -+ -+extern INT32 osal_thread_create(P_OSAL_THREAD); -+extern INT32 osal_thread_run(P_OSAL_THREAD); -+extern INT32 osal_thread_should_stop(P_OSAL_THREAD); -+extern INT32 osal_thread_stop(P_OSAL_THREAD); -+/*extern INT32 osal_thread_wait_for_event(P_OSAL_THREAD, P_OSAL_EVENT);*/ -+extern INT32 osal_thread_wait_for_event(P_OSAL_THREAD, P_OSAL_EVENT, P_OSAL_EVENT_CHECKER); -+/*check pOsalLxOp and OSAL_THREAD_SHOULD_STOP*/ -+extern INT32 osal_thread_destroy(P_OSAL_THREAD); -+ -+extern INT32 osal_clear_bit(UINT32 bitOffset, P_OSAL_BIT_OP_VAR pData); -+extern INT32 osal_set_bit(UINT32 bitOffset, P_OSAL_BIT_OP_VAR pData); -+extern INT32 osal_test_bit(UINT32 bitOffset, P_OSAL_BIT_OP_VAR pData); -+extern INT32 osal_test_and_clear_bit(UINT32 bitOffset, P_OSAL_BIT_OP_VAR pData); -+extern INT32 osal_test_and_set_bit(UINT32 bitOffset, P_OSAL_BIT_OP_VAR pData); -+ -+extern INT32 osal_dbg_assert_aee(const char *module, const char *detail_description); -+extern INT32 osal_gettimeofday(PINT32 sec, PINT32 usec); -+extern INT32 osal_printtimeofday(const PUINT8 prefix); -+ -+extern VOID osal_buffer_dump(const UINT8 *buf, const UINT8 *title, UINT32 len, UINT32 limit); -+ -+extern UINT32 osal_op_get_id(P_OSAL_OP pOp); -+extern MTK_WCN_BOOL osal_op_is_wait_for_signal(P_OSAL_OP pOp); -+extern VOID osal_op_raise_signal(P_OSAL_OP pOp, INT32 result); -+extern VOID osal_set_op_result(P_OSAL_OP pOp, INT32 result); -+extern UINT16 osal_crc16(const UINT8 *buffer, const UINT32 length); -+extern VOID osal_thread_show_stack(P_OSAL_THREAD pThread); -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#define osal_assert(condition) \ -+do { \ -+ if (!(condition)) \ -+ osal_err_print("%s, %d, (%s)\n", __FILE__, __LINE__, #condition); \ -+} while (0) -+ -+#endif /* _OSAL_H_ */ -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/linux/include/osal_typedef.h b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/include/osal_typedef.h -new file mode 100644 -index 000000000000..b3a9c57e062d ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/include/osal_typedef.h -@@ -0,0 +1,90 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -+ -+/*! \file -+ \brief Declaration of library functions -+ -+ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. -+*/ -+ -+#ifndef _OSAL_TYPEDEF_H_ -+#define _OSAL_TYPEDEF_H_ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#ifdef CONFIG_EARLYSUSPEND -+#include -+#else -+#include -+#endif -+#include -+#include -+#ifdef WMT_PLAT_ALPS -+#include -+#endif -+#include -+#ifdef CONFIG_PM_WAKELOCKS -+#include -+#else -+#include -+#endif -+#include -+ -+#ifndef _TYPEDEFS_H /*fix redifine */ -+typedef char INT8; -+#endif -+ -+typedef void VOID, *PVOID, **PPVOID; -+typedef char *PINT8, **PPINT8; -+typedef short INT16, *PINT16, **PPINT16; -+typedef int INT32, *PINT32, **PPINT32; -+typedef long long INT64, *PINT64, **PPINT64; -+ -+typedef unsigned char UINT8, *PUINT8, **PPUINT8; -+typedef unsigned short UINT16, *PUINT16, **PPUINT16; -+typedef unsigned int UINT32, *PUINT32, **PPUINT32; -+typedef unsigned long long UINT64, *PUINT64, **PPUINT64; -+ -+typedef size_t SIZE_T; -+ -+typedef int MTK_WCN_BOOL; -+#ifndef MTK_WCN_BOOL_TRUE -+#define MTK_WCN_BOOL_FALSE ((MTK_WCN_BOOL) 0) -+#define MTK_WCN_BOOL_TRUE ((MTK_WCN_BOOL) 1) -+#endif -+ -+#endif /*_OSAL_TYPEDEF_H_*/ -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/linux/include/wmt_idc.h b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/include/wmt_idc.h -new file mode 100644 -index 000000000000..17be778484c1 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/include/wmt_idc.h -@@ -0,0 +1,97 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -+ -+#ifndef _WMT_IDC_H_ -+#define _WMT_IDC_H_ -+ -+#include "osal_typedef.h" -+#include "osal.h" -+#include "wmt_stp_exp.h" -+ -+#if CFG_WMT_LTE_COEX_HANDLING -+ -+#include "wmt_stp_exp.h" -+#include "conn_md_exp.h" -+ -+#define LTE_IDC_BUFFER_MAX_SIZE 1024 -+/*comment from firmware owner,max pckage num is 5,but should not happened*/ -+#define WMT_IDC_RX_MAX_LEN 384 -+#define LTE_MSG_ID_OFFSET 0x30 -+ -+typedef enum { -+ WMT_IDC_TX_OPCODE_MIN = 0, -+ WMT_IDC_TX_OPCODE_LTE_PARA = 0x0a, -+ WMT_IDC_TX_OPCODE_LTE_FREQ = 0x0b, -+ WMT_IDC_TX_OPCODE_WIFI_MAX_POWER = 0x0c, -+ WMT_IDC_TX_OPCODE_DEBUG_MONITOR = 0x0e, -+ WMT_IDC_TX_OPCODE_SPLIT_FILTER = 0x0f, -+ WMT_IDC_TX_OPCODE_LTE_CONNECTION_STAS = 0x16, -+ WMT_IDC_TX_OPCODE_LTE_HW_IF_INDICATION = 0x17, -+ WMT_IDC_TX_OPCODE_LTE_INDICATION = 0x20, -+ WMT_IDC_TX_OPCODE_MAX -+} WMT_IDC_TX_OPCODE; -+ -+typedef enum { -+ WMT_IDC_RX_OPCODE_BTWF_DEF_PARA = 0x0, -+ WMT_IDC_RX_OPCODE_BTWF_CHAN_RAN = 0x1, -+ /* WMT_IDC_RX_OPCODE_TDM_REQ = 0x10, */ -+ WMT_IDC_RX_OPCODE_DEBUG_MONITOR = 0x02, -+ WMT_IDC_RX_OPCODE_LTE_FREQ_IDX_TABLE = 0x03, -+ WMT_IDC_RX_OPCODE_BTWF_PROFILE_IND = 0x04, -+ WMT_IDC_RX_OPCODE_UART_PIN_SEL = 0x05, -+ WMT_IDC_RX_OPCODE_MAX -+} WMT_IDC_RX_OPCODE; -+ -+#if (CFG_WMT_LTE_ENABLE_MSGID_MAPPING == 0) -+typedef enum { -+ IPC_L4C_MSG_ID_INVALID = IPC_L4C_MSG_ID_BEGIN, -+ IPC_L4C_MSG_ID_END, -+ IPC_EL1_MSG_ID_INVALID = IPC_EL1_MSG_ID_BEGIN, -+ /* below are EL1 IPC messages sent from AP */ -+ IPC_MSG_ID_EL1_LTE_TX_ALLOW_IND, -+ IPC_MSG_ID_EL1_WIFIBT_OPER_DEFAULT_PARAM_IND, -+ IPC_MSG_ID_EL1_WIFIBT_OPER_FREQ_IND, -+ IPC_MSG_ID_EL1_WIFIBT_FREQ_IDX_TABLE_IND, -+ IPC_MSG_ID_EL1_WIFIBT_PROFILE_IND, -+ -+ /* below are EL1 messages sent to AP */ -+ IPC_MSG_ID_EL1_LTE_DEFAULT_PARAM_IND, -+ IPC_MSG_ID_EL1_LTE_OPER_FREQ_PARAM_IND, -+ IPC_MSG_ID_EL1_WIFI_MAX_PWR_IND, -+ IPC_MSG_ID_EL1_LTE_TX_IND, -+ IPC_MSG_ID_EL1_LTE_CONNECTION_STATUS_IND, -+ IPC_MSG_ID_EL1_PIN_TYPE_IND, -+ IPC_MSG_ID_EL1_LTE_HW_INTERFACE_IND, -+ IPC_MSG_ID_EL1_DUMMY13_IND, -+ IPC_MSG_ID_EL1_DUMMY14_IND, -+ IPC_MSG_ID_EL1_DUMMY15_IND, -+ IPC_EL1_MSG_ID_END, -+} IPC_MSG_ID_CODE; -+#endif -+ -+typedef struct _MTK_WCN_WMT_IDC_INFO_ { -+ ipc_ilm_t iit; -+ CONN_MD_BRIDGE_OPS ops; -+ UINT8 buffer[LTE_IDC_BUFFER_MAX_SIZE]; -+} MTK_WCN_WMT_IDC_INFO, *P_MTK_WCN_WMT_IDC_INFO; -+ -+extern INT32 wmt_idc_init(VOID); -+extern INT32 wmt_idc_deinit(VOID); -+extern INT32 wmt_idc_msg_from_lte_handing(ipc_ilm_t *ilm); -+extern INT32 wmt_idc_msg_to_lte_handing(VOID); -+extern UINT32 wmt_idc_msg_to_lte_handing_for_test(UINT8 *p_buf, UINT32 len); -+ -+#endif /* endif CFG_WMT_LTE_COEX_HANDLING */ -+ -+#endif /* _WMT_IDC_H_ */ -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/Makefile b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/Makefile -new file mode 100644 -index 000000000000..ff0f0b0aefda ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/Makefile -@@ -0,0 +1,21 @@ -+ifeq ($(CONFIG_MTK_COMBO), y) -+ -+ccflags-y += \ -+ -I$(src)/../../linux/include \ -+ -I$(src)/../../linux/pri/include \ -+ -I$(src)/../../core/include \ -+ -I$(src)/../../include \ -+ -I$(src)/../include \ -+ -I$(src)/../../../common_detect \ -+ -I$(srctree)/drivers/misc/mediatek/btif/common/inc \ -+ -I$(srctree)/drivers/misc/mediatek/mach/$(MTK_PLATFORM)/include/mach -+ -+ccflags-y += -DWMT_CREATE_NODE_DYNAMIC=1 -+ -+obj-y += stp_btif.o \ -+ stp_dbg.o \ -+ stp_exp.o \ -+ wmt_dev.o \ -+ wmt_exp.o -+ -+endif -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/include/stp_btif.h b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/include/stp_btif.h -new file mode 100644 -index 000000000000..3730fbba6928 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/include/stp_btif.h -@@ -0,0 +1,31 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -+ -+#ifndef _STP_BTIF_H_ -+#define _STP_BTIF_H_ -+ -+#include "osal_typedef.h" -+#include "mtk_btif_exp.h" -+ -+extern INT32 mtk_wcn_consys_stp_btif_open(VOID); -+extern INT32 mtk_wcn_consys_stp_btif_close(VOID); -+extern INT32 mtk_wcn_consys_stp_btif_rx_cb_register(MTK_WCN_BTIF_RX_CB rx_cb); -+extern INT32 mtk_wcn_consys_stp_btif_tx(const UINT8 *pBuf, const UINT32 len, UINT32 *written_len); -+extern INT32 mtk_wcn_consys_stp_btif_wakeup(VOID); -+extern INT32 mtk_wcn_consys_stp_btif_dpidle_ctrl(ENUM_BTIF_DPIDLE_CTRL en_flag); -+extern INT32 mtk_wcn_consys_stp_btif_lpbk_ctrl(ENUM_BTIF_LPBK_MODE mode); -+extern INT32 mtk_wcn_consys_stp_btif_logger_ctrl(ENUM_BTIF_DBG_ID flag); -+extern MTK_WCN_BOOL mtk_wcn_consys_stp_btif_parser_wmt_evt(const UINT8 *str, UINT32 len); -+ -+#endif -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/include/stp_dbg.h b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/include/stp_dbg.h -new file mode 100644 -index 000000000000..de5684a16853 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/include/stp_dbg.h -@@ -0,0 +1,316 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -+ -+#ifndef _STP_DEBUG_H_ -+#define _STP_DEBUG_H_ -+ -+#include -+#include "osal.h" -+ -+#define CONFIG_LOG_STP_INTERNAL -+ -+#if 1 /* #ifndef CONFIG_LOG_STP_INTERNAL */ -+#define STP_PKT_SZ 16 -+#define STP_DMP_SZ 2048 -+#define STP_PKT_NO 2048 -+ -+#define STP_DBG_LOG_ENTRY_NUM 60 -+#define STP_DBG_LOG_ENTRY_SZ 64 -+ -+#else -+ -+#define STP_PKT_SZ 16 -+#define STP_DMP_SZ 16 -+#define STP_PKT_NO 16 -+ -+#define STP_DBG_LOG_ENTRY_NUM 28 -+#define STP_DBG_LOG_ENTRY_SZ 64 -+ -+#endif -+ -+typedef enum { -+ STP_DBG_EN = 0, -+ STP_DBG_PKT = 1, -+ STP_DBG_DR = 2, -+ STP_DBG_FW_ASSERT = 3, -+ STP_DBG_FW_LOG = 4, -+ STP_DBG_FW_DMP = 5, -+ STP_DBG_MAX -+} STP_DBG_OP_T; -+ -+typedef enum { -+ STP_DBG_PKT_FIL_ALL = 0, -+ STP_DBG_PKT_FIL_BT = 1, -+ STP_DBG_PKT_FIL_GPS = 2, -+ STP_DBG_PKT_FIL_FM = 3, -+ STP_DBG_PKT_FIL_WMT = 4, -+ STP_DBG_PKT_FIL_MAX -+} STP_DBG_PKT_FIL_T; -+ -+static char *const gStpDbgType[] = { -+ "< BT>", -+ "< FM>", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "", -+ "" -+}; -+ -+typedef enum { -+ STP_DBG_DR_MAX = 0, -+} STP_DBG_DR_FIL_T; -+ -+typedef enum { -+ STP_DBG_FW_MAX = 0, -+} STP_DBG_FW_FIL_T; -+ -+typedef enum { -+ PKT_DIR_RX = 0, -+ PKT_DIR_TX -+} STP_DBG_PKT_DIR_T; -+ -+/*simple log system ++*/ -+ -+typedef struct { -+ /*type: 0. pkt trace 1. fw info -+ * 2. assert info 3. trace32 dump . -+ * -1. linked to the the previous -+ */ -+ int id; -+ int len; -+ char buffer[STP_DBG_LOG_ENTRY_SZ]; -+} MTKSTP_LOG_ENTRY_T; -+ -+typedef struct log_sys { -+ MTKSTP_LOG_ENTRY_T queue[STP_DBG_LOG_ENTRY_NUM]; -+ unsigned int size; -+ unsigned int in; -+ unsigned int out; -+ spinlock_t lock; -+} MTKSTP_LOG_SYS_T; -+/*--*/ -+ -+typedef struct stp_dbg_pkt_hdr { -+ /* packet information */ -+ unsigned int sec; -+ unsigned int usec; -+ unsigned int dbg_type; -+ unsigned int dmy; -+ unsigned int no; -+ unsigned int dir; -+ -+ /* packet content */ -+ unsigned int type; -+ unsigned int len; -+ unsigned int ack; -+ unsigned int seq; -+ unsigned int chs; -+ unsigned int crc; -+} STP_DBG_HDR_T; -+ -+typedef struct stp_dbg_pkt { -+ struct stp_dbg_pkt_hdr hdr; -+ unsigned char raw[STP_DMP_SZ]; -+} STP_PACKET_T; -+ -+typedef struct mtkstp_dbg_t { -+ /*log_sys */ -+ int pkt_trace_no; -+ void *btm; -+ int is_enable; -+ MTKSTP_LOG_SYS_T *logsys; -+} MTKSTP_DBG_T; -+ -+/* extern void aed_combo_exception(const int *, int, const int *, int, const char *); */ -+ -+#define STP_CORE_DUMP_TIMEOUT (5*60*1000) /* default 5minutes */ -+#define STP_OJB_NAME_SZ 20 -+#define STP_CORE_DUMP_INFO_SZ 500 -+#define STP_CORE_DUMP_INIT_SIZE 1 -+typedef enum wcn_compress_algorithm_t { -+ GZIP = 0, -+ BZIP2 = 1, -+ RAR = 2, -+ LMA = 3, -+ MAX -+} WCN_COMPRESS_ALG_T; -+ -+typedef INT32 (*COMPRESS_HANDLER) (void *worker, UINT8 *in_buf, INT32 in_sz, UINT8 *out_buf, INT32 *out_sz, -+ INT32 finish); -+typedef struct wcn_compressor_t { -+ /* current object name */ -+ UINT8 name[STP_OJB_NAME_SZ + 1]; -+ -+ /* buffer for raw data, named L1 */ -+ PUINT8 L1_buf; -+ INT32 L1_buf_sz; -+ INT32 L1_pos; -+ -+ /* target buffer, named L2 */ -+ PUINT8 L2_buf; -+ INT32 L2_buf_sz; -+ INT32 L2_pos; -+ -+ /* compress state */ -+ UINT8 f_done; -+ UINT16 reserved; -+ UINT32 uncomp_size; -+ UINT32 crc32; -+ -+ /* compress algorithm */ -+ UINT8 f_compress_en; -+ WCN_COMPRESS_ALG_T compress_type; -+ void *worker; -+ COMPRESS_HANDLER handler; -+} WCN_COMPRESSOR_T, *P_WCN_COMPRESSOR_T; -+ -+P_WCN_COMPRESSOR_T wcn_compressor_init(PUINT8 name, INT32 L1_buf_sz, INT32 L2_buf_sz); -+INT32 wcn_compressor_deinit(P_WCN_COMPRESSOR_T compressor); -+INT32 wcn_compressor_in(P_WCN_COMPRESSOR_T compressor, PUINT8 buf, INT32 len, INT32 finish); -+INT32 wcn_compressor_out(P_WCN_COMPRESSOR_T compressor, PUINT8 *pbuf, PINT32 len); -+INT32 wcn_compressor_reset(P_WCN_COMPRESSOR_T compressor, UINT8 enable, WCN_COMPRESS_ALG_T type); -+ -+typedef enum core_dump_state_t { -+ CORE_DUMP_INIT = 0, -+ CORE_DUMP_DOING, -+ CORE_DUMP_TIMEOUT, -+ CORE_DUMP_DONE, -+ CORE_DUMP_MAX -+} CORE_DUMP_STA; -+ -+typedef struct core_dump_t { -+ /* compress dump data and buffered */ -+ P_WCN_COMPRESSOR_T compressor; -+ -+ /* timer for monitor timeout */ -+ OSAL_TIMER dmp_timer; -+ UINT32 timeout; -+ -+ OSAL_SLEEPABLE_LOCK dmp_lock; -+ -+ /* state machine for core dump flow */ -+ CORE_DUMP_STA sm; -+ -+ /* dump info */ -+ INT8 info[STP_CORE_DUMP_INFO_SZ + 1]; -+} WCN_CORE_DUMP_T, *P_WCN_CORE_DUMP_T; -+ -+typedef enum _ENUM_STP_FW_ISSUE_TYPE_ { -+ STP_FW_ISSUE_TYPE_INVALID = 0x0, -+ STP_FW_ASSERT_ISSUE = 0x1, -+ STP_FW_NOACK_ISSUE = 0x2, -+ STP_FW_WARM_RST_ISSUE = 0x3, -+ STP_DBG_PROC_TEST = 0x4, -+ STP_HOST_TRIGGER_FW_ASSERT = 0x5, -+ STP_HOST_TRIGGER_ASSERT_TIMEOUT = 0x6, -+ STP_FW_ISSUE_TYPE_MAX -+} ENUM_STP_FW_ISSUE_TYPE, *P_ENUM_STP_FW_ISSUE_TYPE; -+ -+/* this was added for support dmareg's issue */ -+typedef enum _ENUM_DMA_ISSUE_TYPE_ { -+ CONNSYS_CLK_GATE_STATUS = 0x00, -+ CONSYS_EMI_STATUS, -+ SYSRAM1, -+ SYSRAM2, -+ SYSRAM3, -+ DMA_REGS_MAX -+} ENUM_DMA_ISSUE_TYPE; -+#define STP_PATCH_TIME_SIZE 12 -+#define STP_DBG_CPUPCR_NUM 512 -+#define STP_DBG_DMAREGS_NUM 16 -+#define STP_PATCH_BRANCH_SZIE 8 -+#define STP_ASSERT_INFO_SIZE 64 -+#define STP_DBG_ROM_VER_SIZE 4 -+#define STP_ASSERT_TYPE_SIZE 32 -+ -+typedef struct stp_dbg_host_assert_t { -+ UINT32 drv_type; -+ UINT32 reason; -+ UINT32 assert_from_host; -+} STP_DBG_HOST_ASSERT_T, *P_STP_DBG_HOST_ASSERT_T; -+ -+typedef struct stp_dbg_cpupcr_t { -+ UINT32 chipId; -+ UINT8 romVer[STP_DBG_ROM_VER_SIZE]; -+ UINT8 patchVer[STP_PATCH_TIME_SIZE]; -+ UINT8 branchVer[STP_PATCH_BRANCH_SZIE]; -+ UINT32 wifiVer; -+ UINT32 count; -+ UINT32 stop_flag; -+ UINT32 buffer[STP_DBG_CPUPCR_NUM]; -+ UINT8 assert_info[STP_ASSERT_INFO_SIZE]; -+ UINT32 fwTaskId; -+ UINT32 fwRrq; -+ UINT32 fwIsr; -+ STP_DBG_HOST_ASSERT_T host_assert_info; -+ UINT8 assert_type[STP_ASSERT_TYPE_SIZE]; -+ ENUM_STP_FW_ISSUE_TYPE issue_type; -+ OSAL_SLEEPABLE_LOCK lock; -+} STP_DBG_CPUPCR_T, *P_STP_DBG_CPUPCR_T; -+ -+typedef struct stp_dbg_dmaregs_t { -+ UINT32 count; -+ UINT32 dmaIssue[DMA_REGS_MAX][STP_DBG_DMAREGS_NUM]; -+ OSAL_SLEEPABLE_LOCK lock; -+} STP_DBG_DMAREGS_T, *P_STP_DBG_DMAREGS_T; -+ -+typedef enum _ENUM_ASSERT_INFO_PARSER_TYPE_ { -+ STP_DBG_ASSERT_INFO = 0x0, -+ STP_DBG_FW_TASK_ID = 0x1, -+ STP_DBG_FW_ISR = 0x2, -+ STP_DBG_FW_IRQ = 0x3, -+ STP_DBG_ASSERT_TYPE = 0x4, -+ STP_DBG_PARSER_TYPE_MAX -+} ENUM_ASSERT_INFO_PARSER_TYPE, *P_ENUM_ASSERT_INFO_PARSER_TYPE; -+ -+P_WCN_CORE_DUMP_T wcn_core_dump_init(UINT32 packet_num, UINT32 timeout); -+INT32 wcn_core_dump_deinit(P_WCN_CORE_DUMP_T dmp); -+INT32 wcn_core_dump_in(P_WCN_CORE_DUMP_T dmp, PUINT8 buf, INT32 len); -+INT32 wcn_core_dump_out(P_WCN_CORE_DUMP_T dmp, PUINT8 *pbuf, PINT32 len); -+INT32 wcn_core_dump_reset(P_WCN_CORE_DUMP_T dmp, UINT32 timeout); -+INT32 wcn_core_dump_timeout(void); -+INT32 wcn_wmtd_timeout_collect_ftrace(void); -+ -+extern INT32 wcn_core_dump_init_gcoredump(UINT32 packet_num, UINT32 timeout); -+extern INT32 wcn_core_dump_deinit_gcoredump(VOID); -+extern INT32 wcn_core_dump_flush(INT32 rst, MTK_WCN_BOOL is_coredump_timeout); -+extern int stp_dbg_enable(MTKSTP_DBG_T *stp_dbg); -+extern int stp_dbg_disable(MTKSTP_DBG_T *stp_dbg); -+extern MTKSTP_DBG_T *stp_dbg_init(void *); -+extern int stp_dbg_deinit(MTKSTP_DBG_T *stp_dbg); -+extern int stp_dbg_dmp_out_ex(char *buf, int *len); -+extern int stp_dbg_dmp_out(MTKSTP_DBG_T *stp_dbg, char *buf, int *len); -+extern int stp_dbg_dmp_printk(MTKSTP_DBG_T *stp_dbg); -+extern char stp_dbg_nl_send(PINT8 aucMsg, UINT8 cmd, INT32 len); -+ -+extern INT32 stp_dbg_aee_send(unsigned char *aucMsg, INT32 len, INT32 cmd); -+extern INT32 _stp_btm_put_emi_dump_to_nl(PUINT8 data_buf, INT32 dump_len); -+extern int -+stp_dbg_log_pkt(MTKSTP_DBG_T *stp_dbg, -+ int dbg_type, int type, int ack_no, int seq_no, int crc, int dir, int len, const unsigned char *body); -+extern int stp_dbg_log_ctrl(unsigned int on); -+extern INT32 stp_dbg_poll_cpupcr(UINT32 times, UINT32 sleep, UINT32 cmd); -+extern INT32 stp_dbg_poll_dmaregs(UINT32 times, UINT32 sleep); -+extern INT32 stp_dbg_poll_cuppcr_ctrl(UINT32 en); -+extern INT32 stp_dbg_set_version_info(UINT32 chipid, PUINT8 pRomVer, PUINT8 pPatchVer, -+ PUINT8 pPatchBrh); -+extern INT32 stp_dbg_set_wifiver(UINT32 wifiver); -+extern INT32 stp_dbg_cpupcr_infor_format(PPUINT8 buf, PUINT32 len); -+extern INT32 stp_dbg_set_fw_info(PUINT8 assert_info, UINT32 len, ENUM_STP_FW_ISSUE_TYPE issue_type); -+extern INT32 stp_dbg_set_host_assert_info(UINT32 drv_type, UINT32 reason, UINT32 en); -+extern UINT32 stp_dbg_get_host_trigger_assert(VOID); -+#endif /* end of _STP_DEBUG_H_ */ -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/include/wmt_dev.h b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/include/wmt_dev.h -new file mode 100644 -index 000000000000..5788eb355549 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/include/wmt_dev.h -@@ -0,0 +1,71 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -+ -+#ifndef _WMT_DEV_H_ -+#define _WMT_DEV_H_ -+ -+#include "osal.h" -+ -+#define STP_UART_FULL 0x01 -+#define STP_UART_MAND 0x02 -+#define STP_BTIF_FULL 0x03 -+#define STP_SDIO 0x04 -+ -+#define CFG_WMT_DBG_SUPPORT 1 /* support wmt_dbg or not */ -+#define CFG_WMT_PROC_FOR_AEE 1 -+ -+extern VOID wmt_dev_rx_event_cb(VOID); -+extern INT32 wmt_dev_rx_timeout(P_OSAL_EVENT pEvent); -+extern INT32 wmt_dev_patch_get(PUINT8 pPatchName, osal_firmware **ppPatch, INT32 padSzBuf); -+extern INT32 wmt_dev_patch_put(osal_firmware **ppPatch); -+extern VOID wmt_dev_patch_info_free(VOID); -+extern VOID wmt_dev_send_cmd_to_daemon(UINT32 cmd); -+extern MTK_WCN_BOOL wmt_dev_get_early_suspend_state(VOID); -+ -+#if CFG_WMT_DBG_SUPPORT -+typedef struct _COEX_BUF { -+ UINT8 buffer[128]; -+ INT32 availSize; -+} COEX_BUF, *P_COEX_BUF; -+ -+typedef enum _ENUM_CMD_TYPE_T { -+ WMTDRV_CMD_ASSERT = 0, -+ WMTDRV_CMD_EXCEPTION = 1, -+ WMTDRV_CMD_COEXDBG_00 = 2, -+ WMTDRV_CMD_COEXDBG_01 = 3, -+ WMTDRV_CMD_COEXDBG_02 = 4, -+ WMTDRV_CMD_COEXDBG_03 = 5, -+ WMTDRV_CMD_COEXDBG_04 = 6, -+ WMTDRV_CMD_COEXDBG_05 = 7, -+ WMTDRV_CMD_COEXDBG_06 = 8, -+ WMTDRV_CMD_COEXDBG_07 = 9, -+ WMTDRV_CMD_COEXDBG_08 = 10, -+ WMTDRV_CMD_COEXDBG_09 = 11, -+ WMTDRV_CMD_COEXDBG_10 = 12, -+ WMTDRV_CMD_COEXDBG_11 = 13, -+ WMTDRV_CMD_COEXDBG_12 = 14, -+ WMTDRV_CMD_COEXDBG_13 = 15, -+ WMTDRV_CMD_COEXDBG_14 = 16, -+ WMTDRV_CMD_COEXDBG_15 = 17, -+ WMTDRV_CMD_NOACK_TEST = 18, -+ WMTDRV_CMD_WARNRST_TEST = 19, -+ WMTDRV_CMD_FWTRACE_TEST = 20, -+ WMTDRV_CMD_MAX -+} ENUM_WMTDRV_CMD_T, *P_ENUM_WMTDRV_CMD_T; -+ -+#endif -+ -+typedef INT32(*WMT_DEV_DBG_FUNC) (INT32 par1, INT32 par2, INT32 par3); -+ -+#endif /*_WMT_DEV_H_*/ -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/stp_btif.c b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/stp_btif.c -new file mode 100644 -index 000000000000..76debb4674f9 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/stp_btif.c -@@ -0,0 +1,279 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -+ -+/*file: stp_btif, mainly control stp & btif interaction*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+#ifdef DFT_TAG -+#undef DFT_TAG -+#endif -+#define DFT_TAG "[STP-BTIF]" -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "osal_typedef.h" -+#include "wmt_exp.h" -+#include "stp_exp.h" -+#include "stp_btif.h" -+ -+#include -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+#define BTIF_OWNER_NAME "CONSYS_STP" -+ -+#define STP_MAX_PACKAGE_ALLOWED (2000) -+ -+#define STP_BTIF_TX_RTY_LMT (10) -+#define STP_BTIF_TX_RTY_DLY (5) -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+unsigned long stpBtifId = 0; -+unsigned long *pBtifRef = &stpBtifId; -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+INT32 mtk_wcn_consys_stp_btif_open(VOID) -+{ -+ INT32 iRet = -1; -+ -+ iRet = mtk_wcn_btif_open(BTIF_OWNER_NAME, pBtifRef); -+ if (iRet) { -+ WMT_WARN_FUNC("STP open btif fail(%d)\n", iRet); -+ return -1; -+ } -+ WMT_DBG_FUNC("STP open bitf OK\n"); -+ -+ mtk_wcn_stp_register_if_tx(STP_BTIF_IF_TX, (MTK_WCN_STP_IF_TX) mtk_wcn_consys_stp_btif_tx); -+ -+ return 0; -+} -+ -+INT32 mtk_wcn_consys_stp_btif_close(VOID) -+{ -+ INT32 iRet = 0; -+ -+ if (!stpBtifId) { -+ WMT_WARN_FUNC("NULL BTIF ID reference!\n"); -+ iRet = -1; -+ } else { -+ iRet = mtk_wcn_btif_close(stpBtifId); -+ if (iRet) { -+ WMT_WARN_FUNC("STP close btif fail(%d)\n", iRet); -+ iRet = -2; -+ } else { -+ stpBtifId = 0; -+ WMT_DBG_FUNC("STP close btif OK\n"); -+ } -+ } -+ return iRet; -+} -+ -+INT32 mtk_wcn_consys_stp_btif_rx_cb_register(MTK_WCN_BTIF_RX_CB rx_cb) -+{ -+ INT32 iRet = 0; -+ -+ if (!stpBtifId) { -+ WMT_WARN_FUNC("NULL BTIF ID reference\n!"); -+ iRet = -1; -+ } else { -+ iRet = mtk_wcn_btif_rx_cb_register(stpBtifId, rx_cb); -+ if (iRet) { -+ WMT_WARN_FUNC("STP register rxcb to btif fail(%d)\n", iRet); -+ iRet = -2; -+ } else { -+ WMT_DBG_FUNC("STP register rxcb to btif OK\n"); -+ } -+ } -+ return iRet; -+} -+ -+INT32 mtk_wcn_consys_stp_btif_tx(const UINT8 *pBuf, const UINT32 len, UINT32 *written_len) -+{ -+ INT32 retry_left = STP_BTIF_TX_RTY_LMT; -+ INT32 wr_count = 0; -+ INT32 written = 0; -+ -+ if (!stpBtifId) { -+ WMT_WARN_FUNC("NULL BTIF ID reference!\n"); -+ return -1; -+ } -+ -+ if (len == 0) { -+ *written_len = 0; -+ WMT_INFO_FUNC("special case for STP-CORE,pbuf(%p)\n", pBuf); -+ return 0; -+ } -+ -+ *written_len = 0; -+ -+ if (len > STP_MAX_PACKAGE_ALLOWED) { -+ WMT_WARN_FUNC("abnormal pacage length,len(%d),pid[%d/%s]\n", len, current->pid, current->comm); -+ return -2; -+ } -+ wr_count = mtk_wcn_btif_write(stpBtifId, pBuf, len); -+ -+ if (wr_count < 0) { -+ WMT_ERR_FUNC("mtk_wcn_btif_write err(%d)\n", wr_count); -+ *written_len = 0; -+ return -3; -+ } -+ if (wr_count == len) { -+ /*perfect case */ -+ *written_len = wr_count; -+ return wr_count; -+ } -+ -+ while ((retry_left--) && (wr_count < len)) { -+ osal_sleep_ms(STP_BTIF_TX_RTY_DLY); -+ written = mtk_wcn_btif_write(stpBtifId, pBuf + wr_count, len - wr_count); -+ if (written < 0) { -+ WMT_ERR_FUNC("mtk_wcn_btif_write err(%d)when do recovered\n", written); -+ break; -+ } -+ wr_count += written; -+ } -+ -+ if (wr_count == len) { -+ WMT_INFO_FUNC("recovered,len(%d),retry_left(%d)\n", len, retry_left); -+ /*recovered case */ -+ *written_len = wr_count; -+ return wr_count; -+ } -+ -+ WMT_ERR_FUNC("stp btif write fail,len(%d),written(%d),retry_left(%d),pid[%d/%s]\n", -+ len, wr_count, retry_left, current->pid, current->comm); -+ *written_len = 0; -+ return -wr_count; -+} -+ -+INT32 mtk_wcn_consys_stp_btif_rx(UINT8 *pBuf, UINT32 len) -+{ -+ return 0; -+} -+ -+INT32 mtk_wcn_consys_stp_btif_wakeup(VOID) -+{ -+ INT32 iRet = 0; -+ -+ if (!stpBtifId) { -+ WMT_WARN_FUNC("NULL BTIF ID reference!\n"); -+ iRet = -1; -+ } else { -+ iRet = mtk_wcn_btif_wakeup_consys(stpBtifId); -+ if (iRet) { -+ WMT_WARN_FUNC("STP btif wakeup consys fail(%d)\n", iRet); -+ iRet = -2; -+ } else { -+ WMT_DBG_FUNC("STP btif wakeup consys ok\n"); -+ } -+ } -+ -+ return iRet; -+} -+ -+INT32 mtk_wcn_consys_stp_btif_dpidle_ctrl(ENUM_BTIF_DPIDLE_CTRL en_flag) -+{ -+ INT32 iRet = 0; -+ -+ if (!stpBtifId) { -+ WMT_WARN_FUNC("NULL BTIF ID reference!\n"); -+ iRet = -1; -+ } else { -+ mtk_wcn_btif_dpidle_ctrl(stpBtifId, en_flag); -+ WMT_DBG_FUNC("stp btif dpidle ctrl done,en_flag(%d)\n", en_flag); -+ } -+ -+ return iRet; -+} -+ -+INT32 mtk_wcn_consys_stp_btif_lpbk_ctrl(ENUM_BTIF_LPBK_MODE mode) -+{ -+ INT32 iRet = 0; -+ -+ if (!stpBtifId) { -+ WMT_WARN_FUNC("NULL BTIF ID reference!\n"); -+ iRet = -1; -+ } else { -+ iRet = mtk_wcn_btif_loopback_ctrl(stpBtifId, mode); -+ if (iRet) { -+ WMT_WARN_FUNC("STP btif lpbk ctrl fail(%d)\n", iRet); -+ iRet = -2; -+ } else { -+ WMT_INFO_FUNC("stp btif lpbk ctrl ok,mode(%d)\n", mode); -+ } -+ } -+ -+ return iRet; -+} -+ -+INT32 mtk_wcn_consys_stp_btif_logger_ctrl(ENUM_BTIF_DBG_ID flag) -+{ -+ INT32 iRet = 0; -+ -+ if (!stpBtifId) { -+ WMT_WARN_FUNC("NULL BTIF ID reference!\n"); -+ iRet = -1; -+ } else { -+ iRet = mtk_wcn_btif_dbg_ctrl(stpBtifId, flag); -+ if (iRet) { -+ WMT_WARN_FUNC("STP btif log dbg ctrl fail(%d)\n", iRet); -+ iRet = -2; -+ } else { -+ WMT_INFO_FUNC("stp btif log dbg ctrl ok,flag(%d)\n", flag); -+ } -+ } -+ -+ return iRet; -+} -+ -+INT32 mtk_wcn_consys_stp_btif_parser_wmt_evt(const UINT8 *str, UINT32 len) -+{ -+ if (!stpBtifId) { -+ WMT_WARN_FUNC("NULL BTIF ID reference!\n"); -+ return -1; -+ } else { -+ return (INT32) mtk_wcn_btif_parser_wmt_evt(stpBtifId, str, len); -+ } -+} -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/stp_dbg.c b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/stp_dbg.c -new file mode 100644 -index 000000000000..fdb610cc3897 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/stp_dbg.c -@@ -0,0 +1,2061 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -+#include /* GFP_KERNEL */ -+#include /* init_timer, add_time, del_timer_sync */ -+#include /* gettimeofday */ -+#include -+#include /* kzalloc */ -+#include /* task's status */ -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+ -+#include "osal_typedef.h" -+#include "stp_dbg.h" -+/* #include "stp_btm.h" */ -+#include "btm_core.h" -+#include "wmt_plat.h" -+ -+#define PFX_STP_DBG "[STPDbg]" -+#define STP_DBG_LOG_LOUD 4 -+#define STP_DBG_LOG_DBG 3 -+#define STP_DBG_LOG_INFO 2 -+#define STP_DBG_LOG_WARN 1 -+#define STP_DBG_LOG_ERR 0 -+ -+unsigned int gStpDbgDbgLevel = STP_DBG_LOG_INFO; -+unsigned int gStpDbgLogOut = 0; -+ -+#define STP_DBG_LOUD_FUNC(fmt, arg...) \ -+do { \ -+ if (gStpDbgDbgLevel >= STP_DBG_LOG_LOUD) \ -+ pr_debug(PFX_STP_DBG "%s: " fmt, __func__ , ##arg); \ -+} while (0) -+#define STP_DBG_DBG_FUNC(fmt, arg...) \ -+do { \ -+ if (gStpDbgDbgLevel >= STP_DBG_LOG_DBG) \ -+ pr_debug(PFX_STP_DBG "%s: " fmt, __func__ , ##arg); \ -+} while (0) -+#define STP_DBG_INFO_FUNC(fmt, arg...) \ -+do { \ -+ if (gStpDbgDbgLevel >= STP_DBG_LOG_INFO) \ -+ pr_debug(PFX_STP_DBG "%s: " fmt, __func__ , ##arg); \ -+} while (0) -+#define STP_DBG_WARN_FUNC(fmt, arg...) \ -+do { \ -+ if (gStpDbgDbgLevel >= STP_DBG_LOG_WARN) \ -+ pr_warn(PFX_STP_DBG "%s: " fmt, __func__ , ##arg); \ -+} while (0) -+#define STP_DBG_ERR_FUNC(fmt, arg...) \ -+do { \ -+ if (gStpDbgDbgLevel >= STP_DBG_LOG_ERR) \ -+ pr_err(PFX_STP_DBG "%s: " fmt, __func__ , ##arg); \ -+} while (0) -+#define STP_DBG_TRC_FUNC(f) \ -+do { \ -+ if (gStpDbgDbgLevel >= STP_DBG_LOG_DBG) \ -+ pr_debug(PFX_STP_DBG "<%s> <%d>\n", __func__, __LINE__); \ -+} while (0) -+ -+MTKSTP_DBG_T *g_stp_dbg = NULL; -+ -+#define STP_DBG_FAMILY_NAME "STP_DBG" -+#define MAX_BIND_PROCESS (4) -+#ifdef WMT_PLAT_ALPS -+#define STP_DBG_AEE_EXP_API (1) -+#else -+#define STP_DBG_AEE_EXP_API (0) -+#endif -+enum { -+ __STP_DBG_ATTR_INVALID, -+ STP_DBG_ATTR_MSG, -+ __STP_DBG_ATTR_MAX, -+}; -+#define STP_DBG_ATTR_MAX (__STP_DBG_ATTR_MAX - 1) -+ -+enum { -+ __STP_DBG_COMMAND_INVALID, -+ STP_DBG_COMMAND_BIND, -+ STP_DBG_COMMAND_RESET, -+ __STP_DBG_COMMAND_MAX, -+}; -+#define MTK_WIFI_COMMAND_MAX (__STP_DBG_COMMAND_MAX - 1) -+ -+static struct genl_family stp_dbg_gnl_family = { -+ .id = GENL_ID_GENERATE, -+ .hdrsize = 0, -+ .name = STP_DBG_FAMILY_NAME, -+ .version = 1, -+ .maxattr = STP_DBG_ATTR_MAX, -+}; -+ -+static void stp_dbg_nl_init(void); -+static void stp_dbg_nl_deinit(void); -+static int stp_dbg_nl_bind(struct sk_buff *skb, struct genl_info *info); -+static int stp_dbg_nl_reset(struct sk_buff *skb, struct genl_info *info); -+ -+/* attribute policy */ -+static struct nla_policy stp_dbg_genl_policy[STP_DBG_ATTR_MAX + 1] = { -+ [STP_DBG_ATTR_MSG] = {.type = NLA_NUL_STRING}, -+}; -+ -+/* operation definition */ -+#if 0 -+static struct genl_ops stp_dbg_gnl_ops_bind = { -+ .cmd = STP_DBG_COMMAND_BIND, -+ .flags = 0, -+ .policy = stp_dbg_genl_policy, -+ .doit = stp_dbg_nl_bind, -+ .dumpit = NULL, -+}; -+ -+static struct genl_ops stp_dbg_gnl_ops_reset = { -+ .cmd = STP_DBG_COMMAND_RESET, -+ .flags = 0, -+ .policy = stp_dbg_genl_policy, -+ .doit = stp_dbg_nl_reset, -+ .dumpit = NULL, -+}; -+#endif -+static struct genl_ops stp_dbg_gnl_ops_array[] = { -+ { -+ .cmd = STP_DBG_COMMAND_BIND, -+ .flags = 0, -+ .policy = stp_dbg_genl_policy, -+ .doit = stp_dbg_nl_bind, -+ .dumpit = NULL, -+ }, -+ { -+ .cmd = STP_DBG_COMMAND_RESET, -+ .flags = 0, -+ .policy = stp_dbg_genl_policy, -+ .doit = stp_dbg_nl_reset, -+ .dumpit = NULL, -+ }, -+}; -+ -+#if 0 -+#define E2S(x) #x -+static char *dmaRegsStr[] = { -+ E2S(CONNSYS_CLK_GATE_STATUS), -+ E2S(CONSYS_EMI_STATUS), -+ E2S(SYSRAM1), -+ E2S(SYSRAM2), -+ E2S(SYSRAM3) -+}; -+#endif -+static unsigned int stp_dbg_seqnum; -+static int num_bind_process; -+static pid_t bind_pid[MAX_BIND_PROCESS]; -+ -+static P_WCN_CORE_DUMP_T g_core_dump; -+ -+static P_STP_DBG_CPUPCR_T g_stp_dbg_cpupcr; -+ -+/* just show in log at present */ -+static P_STP_DBG_DMAREGS_T g_stp_dbg_dmaregs; -+ -+/* core_dump_timeout_handler - handler of coredump timeout -+ * @ data - core dump object's pointer -+ * -+ * No return value -+ */ -+static void core_dump_timeout_handler(/*unsigned long data*/struct timer_list *t) -+{ -+ //P_WCN_CORE_DUMP_T dmp = (P_WCN_CORE_DUMP_T) data; -+ P_WCN_CORE_DUMP_T dmp = from_timer(dmp,t,dmp_timer.timer); -+ -+ STP_DBG_INFO_FUNC(" start\n"); -+ -+ stp_btm_notify_coredump_timeout_wq(g_stp_dbg->btm); -+ -+ STP_DBG_INFO_FUNC(" end\n"); -+ -+ if (dmp) -+ dmp->sm = CORE_DUMP_TIMEOUT; -+} -+ -+/* wcn_core_dump_init - create core dump sys -+ * @ timeout - core dump time out value -+ * -+ * Return object pointer if success, else NULL -+ */ -+P_WCN_CORE_DUMP_T wcn_core_dump_init(UINT32 packet_num, UINT32 timeout) -+{ -+#define KBYTES (1024*sizeof(char)) -+#define L1_BUF_SIZE (32*KBYTES) -+ -+ P_WCN_CORE_DUMP_T core_dmp = NULL; -+ -+ core_dmp = (P_WCN_CORE_DUMP_T) osal_malloc(sizeof(WCN_CORE_DUMP_T)); -+ if (!core_dmp) { -+ STP_DBG_ERR_FUNC("alloc mem failed!\n"); -+ goto fail; -+ } -+ -+ osal_memset(core_dmp, 0, sizeof(WCN_CORE_DUMP_T)); -+ -+ core_dmp->compressor = wcn_compressor_init("core_dump_compressor", L1_BUF_SIZE, 18*packet_num*KBYTES); -+ if (!core_dmp->compressor) { -+ STP_DBG_ERR_FUNC("create compressor failed!\n"); -+ goto fail; -+ } -+ wcn_compressor_reset(core_dmp->compressor, 1, GZIP); -+ -+ core_dmp->dmp_timer.timeoutHandler = core_dump_timeout_handler; -+ core_dmp->dmp_timer.timeroutHandlerData = (unsigned long)core_dmp; -+ osal_timer_create(&core_dmp->dmp_timer); -+ core_dmp->timeout = timeout; -+ -+ osal_sleepable_lock_init(&core_dmp->dmp_lock); -+ -+ core_dmp->sm = CORE_DUMP_INIT; -+ STP_DBG_INFO_FUNC("create coredump object OK!\n"); -+ -+ return core_dmp; -+ -+fail: -+ if (core_dmp && core_dmp->compressor) { -+ wcn_compressor_deinit(core_dmp->compressor); -+ core_dmp->compressor = NULL; -+ } -+ if (core_dmp) -+ osal_free(core_dmp); -+ -+ return NULL; -+} -+INT32 wcn_core_dump_init_gcoredump(UINT32 packet_num, UINT32 timeout) -+{ -+ INT32 Ret = 0; -+ -+ g_core_dump = wcn_core_dump_init(packet_num, timeout); -+ if (g_core_dump == NULL) -+ Ret = -1; -+ return Ret; -+} -+ -+/* wcn_core_dump_deinit - destroy core dump object -+ * @ dmp - pointer of object -+ * -+ * Retunr 0 if success, else error code -+ */ -+INT32 wcn_core_dump_deinit(P_WCN_CORE_DUMP_T dmp) -+{ -+ if (dmp && dmp->compressor) { -+ wcn_compressor_deinit(dmp->compressor); -+ dmp->compressor = NULL; -+ } -+ -+ if (dmp) { -+ osal_sleepable_lock_deinit(&dmp->dmp_lock); -+ osal_timer_stop(&dmp->dmp_timer); -+ osal_free(dmp); -+ } -+ -+ return 0; -+} -+ -+INT32 wcn_core_dump_deinit_gcoredump(VOID) -+{ -+ wcn_core_dump_deinit(g_core_dump); -+ return 0; -+} -+ -+static INT32 wcn_core_dump_check_end(PUINT8 buf, INT32 len) -+{ -+ if (strnstr(buf, "coredump end", len)) -+ return 1; -+ else -+ return 0; -+} -+ -+/* wcn_core_dump_in - add a packet to compressor buffer -+ * @ dmp - pointer of object -+ * @ buf - input buffer -+ * @ len - data length -+ * -+ * Retunr 0 if success; return 1 if find end string; else error code -+ */ -+INT32 wcn_core_dump_in(P_WCN_CORE_DUMP_T dmp, PUINT8 buf, INT32 len) -+{ -+ INT32 ret = 0; -+ INT32 tmp; -+ -+#define INFO_HEAD ";SOC_CONSYS FW CORE, " -+ -+ if ((!dmp) || (!buf)) { -+ STP_DBG_ERR_FUNC("invalid pointer!\n"); -+ return -1; -+ } -+ -+ ret = osal_lock_sleepable_lock(&dmp->dmp_lock); -+ if (ret) { -+ STP_DBG_ERR_FUNC("--->lock dmp->dmp_lock failed, ret=%d\n", ret); -+ return ret; -+ } -+ -+ switch (dmp->sm) { -+ case CORE_DUMP_INIT: -+ wcn_compressor_reset(dmp->compressor, 1, GZIP); -+ osal_timer_start(&dmp->dmp_timer, STP_CORE_DUMP_TIMEOUT); -+ -+ /* first package, copy to info buffer */ -+ osal_strcpy(&dmp->info[0], INFO_HEAD); -+ -+ if (NULL == (strnstr(buf, "", 32))) { -+ osal_memcpy(&dmp->info[osal_strlen(INFO_HEAD)], "Fw warm reset exception...", -+ osal_strlen("Fw warm reset exception...")); -+ dmp->info[osal_strlen(INFO_HEAD) + osal_strlen("Fw warm reset exception...") + 1] = '\0'; -+ } else { -+ char *pStr = buf; -+ char *pDtr = NULL; -+ -+ pDtr = osal_strchr(pStr, '-'); -+ if (NULL != pDtr) { -+ tmp = pDtr - pStr; -+ osal_memcpy(&dmp->info[osal_strlen(INFO_HEAD)], buf, tmp); -+ dmp->info[osal_strlen(dmp->info) + 1] = '\0'; -+ } else { -+ tmp = STP_CORE_DUMP_INFO_SZ - osal_strlen(INFO_HEAD); -+ tmp = (len > tmp) ? tmp : len; -+ osal_memcpy(&dmp->info[osal_strlen(INFO_HEAD)], buf, tmp); -+ dmp->info[STP_CORE_DUMP_INFO_SZ] = '\0'; -+ } -+ -+ } -+ /* show coredump start info on UI */ -+ /* osal_dbg_assert_aee("MT662x f/w coredump start", "MT662x firmware coredump start"); */ -+#if STP_DBG_AEE_EXP_API -+ aee_kernel_dal_show("SOC_CONSYS coredump start ....\n"); -+#endif -+ /* parsing data, and check end srting */ -+ ret = wcn_core_dump_check_end(buf, len); -+ if (ret == 1) { -+ STP_DBG_INFO_FUNC("core dump end!\n"); -+ dmp->sm = CORE_DUMP_DONE; -+ wcn_compressor_in(dmp->compressor, buf, len, 0); -+ } else { -+ dmp->sm = CORE_DUMP_DOING; -+ wcn_compressor_in(dmp->compressor, buf, len, 0); -+ } -+ break; -+ -+ case CORE_DUMP_DOING: -+ /* parsing data, and check end srting */ -+ ret = wcn_core_dump_check_end(buf, len); -+ if (ret == 1) { -+ STP_DBG_INFO_FUNC("core dump end!\n"); -+ dmp->sm = CORE_DUMP_DONE; -+ wcn_compressor_in(dmp->compressor, buf, len, 0); -+ } else { -+ dmp->sm = CORE_DUMP_DOING; -+ wcn_compressor_in(dmp->compressor, buf, len, 0); -+ } -+ break; -+ -+ case CORE_DUMP_DONE: -+ wcn_compressor_reset(dmp->compressor, 1, GZIP); -+ osal_timer_start(&dmp->dmp_timer, STP_CORE_DUMP_TIMEOUT); -+ wcn_compressor_in(dmp->compressor, buf, len, 0); -+ dmp->sm = CORE_DUMP_DOING; -+ break; -+ -+ case CORE_DUMP_TIMEOUT: -+ break; -+ default: -+ break; -+ } -+ -+ osal_unlock_sleepable_lock(&dmp->dmp_lock); -+ -+ return ret; -+} -+ -+/* wcn_core_dump_out - get compressed data from compressor buffer -+ * @ dmp - pointer of object -+ * @ pbuf - target buffer's pointer -+ * @ len - data length -+ * -+ * Retunr 0 if success; else error code -+ */ -+INT32 wcn_core_dump_out(P_WCN_CORE_DUMP_T dmp, PUINT8 *pbuf, PINT32 plen) -+{ -+ INT32 ret = 0; -+ -+ if ((!dmp) || (!pbuf) || (!plen)) { -+ STP_DBG_ERR_FUNC("invalid pointer!\n"); -+ return -1; -+ } -+ -+ ret = osal_lock_sleepable_lock(&dmp->dmp_lock); -+ if (ret) { -+ STP_DBG_ERR_FUNC("--->lock dmp->dmp_lock failed, ret=%d\n", ret); -+ return ret; -+ } -+ -+ ret = wcn_compressor_out(dmp->compressor, pbuf, plen); -+ -+ osal_unlock_sleepable_lock(&dmp->dmp_lock); -+ -+ return ret; -+} -+ -+/* wcn_core_dump_reset - reset core dump sys -+ * @ dmp - pointer of object -+ * @ timeout - core dump time out value -+ * -+ * Retunr 0 if success, else error code -+ */ -+INT32 wcn_core_dump_reset(P_WCN_CORE_DUMP_T dmp, UINT32 timeout) -+{ -+ if (!dmp) { -+ STP_DBG_ERR_FUNC("invalid pointer!\n"); -+ return -1; -+ } -+ -+ dmp->sm = CORE_DUMP_INIT; -+ dmp->timeout = timeout; -+ osal_timer_stop(&dmp->dmp_timer); -+ wcn_compressor_reset(dmp->compressor, 1, GZIP); -+ osal_memset(dmp->info, 0, STP_CORE_DUMP_INFO_SZ + 1); -+ -+ wcn_core_dump_deinit(dmp); -+ g_core_dump = wcn_core_dump_init(STP_CORE_DUMP_INIT_SIZE, STP_CORE_DUMP_TIMEOUT); -+ -+ return 0; -+} -+ -+/* wcn_wmtd_timeout_collect_ftrace - wmtd timeout ,this func can collect SYS_FTRACE -+ * -+ * Retunr 0 if success -+ */ -+#define WMTD_TIMEOUT_INFO_HEAD "Wait wmtd complation timeout ,just collect SYS_FTRACE to DB" -+INT32 wcn_wmtd_timeout_collect_ftrace(void) -+{ -+ PUINT8 pbuf; -+ INT32 len; -+ -+ pbuf = "Wait wmtd complation timeout"; -+ len = osal_strlen("Wait wmtd complation timeout"); -+ osal_strcpy(&g_core_dump->info[0], WMTD_TIMEOUT_INFO_HEAD); -+#ifdef WMT_PLAT_ALPS -+ aed_combo_exception(NULL, 0, (const int *)pbuf, len, (const char *)g_core_dump->info); -+#endif -+ return 0; -+} -+/* wcn_psm_flag_trigger_collect_ftrace - wmtd timeout ,this func can collect SYS_FTRACE -+ * -+ * Retunr 0 if success -+ */ -+#define PSM_ABNORMAL_FLAG_INFO_HEAD "Abnormal PSM flag be set ,just collect SYS_FTRACE to DB" -+INT32 wcn_psm_flag_trigger_collect_ftrace(void) -+{ -+ PUINT8 pbuf; -+ INT32 len; -+ -+ pbuf = "Abnormal PSM flag be set"; -+ len = osal_strlen("Abnormal PSM flag be set"); -+ osal_strcpy(&g_core_dump->info[0], PSM_ABNORMAL_FLAG_INFO_HEAD); -+#ifdef WMT_PLAT_ALPS -+ aed_combo_exception(NULL, 0, (const int *)pbuf, len, (const char *)g_core_dump->info); -+#endif -+ return 0; -+} -+#if BTIF_RXD_BE_BLOCKED_DETECT -+MTK_WCN_BOOL is_btif_rxd_be_blocked(void) -+{ -+ MTK_WCN_BOOL flag = MTK_WCN_BOOL_FALSE; -+ -+ if (mtk_btif_rxd_be_blocked_flag_get()) -+ flag = MTK_WCN_BOOL_TRUE; -+ return flag; -+} -+/* wcn_btif_rxd_blocked_collect_ftrace - btif rxd be blocked,this func can collect SYS_FTRACE -+ * -+ * Retunr 0 if success -+ */ -+#define BTIF_RXD_BLOCKED_INFO_HEAD "Btif_rxd thread be blocked too long,just collect SYS_FTRACE to DB" -+INT32 wcn_btif_rxd_blocked_collect_ftrace(void) -+{ -+ PUINT8 pbuf; -+ INT32 len; -+ -+ pbuf = "Btif_rxd thread be blocked too long"; -+ len = osal_strlen("Btif_rxd thread be blocked too long"); -+ osal_strcpy(&g_core_dump->info[0], BTIF_RXD_BLOCKED_INFO_HEAD); -+#ifdef WMT_PLAT_ALPS -+ aed_combo_exception(NULL, 0, (const int *)pbuf, len, (const char *)g_core_dump->info); -+#endif -+ return 0; -+} -+#endif -+/* wcn_core_dump_timeout - wait for FW assert info timeout ,this func can collect SYS_FTRACE -+ * -+ * Retunr 0 if success -+ */ -+#define TIMEOUT_INFO_HEAD "Trigger assert timeout ,just collect SYS_FTRACE to DB" -+INT32 wcn_core_dump_timeout(void) -+{ -+ PUINT8 pbuf; -+ INT32 len; -+ -+ pbuf = "Trigger assert timeout"; -+ len = osal_strlen("Trigger assert timeout"); -+ osal_strcpy(&g_core_dump->info[0], TIMEOUT_INFO_HEAD); -+#ifdef WMT_PLAT_ALPS -+ aed_combo_exception(NULL, 0, (const int *)pbuf, len, (const char *)g_core_dump->info); -+#endif -+ return 0; -+} -+ -+#define ENABLE_F_TRACE 0 -+/* wcn_core_dump_flush - Fulsh dump data and reset core dump sys -+ * -+ * Retunr 0 if success, else error code -+ */ -+INT32 wcn_core_dump_flush(INT32 rst, MTK_WCN_BOOL coredump_is_timeout) -+{ -+ PUINT8 pbuf = NULL; -+ INT32 len = 0; -+ -+ if (!g_core_dump) { -+ STP_DBG_ERR_FUNC("invalid pointer!\n"); -+ return -1; -+ } -+ -+ wcn_core_dump_out(g_core_dump, &pbuf, &len); -+ STP_DBG_INFO_FUNC("buf 0x%zx, len %d\n", (SIZE_T) pbuf, len); -+#ifdef WMT_PLAT_ALPS -+ /* show coredump end info on UI */ -+ /* osal_dbg_assert_aee("MT662x f/w coredump end", "MT662x firmware coredump ends"); */ -+#if STP_DBG_AEE_EXP_API -+ if (coredump_is_timeout) -+ aee_kernel_dal_show("++ SOC_CONSYS coredump tiemout ,pass received coredump to AEE ++\n"); -+ else -+ aee_kernel_dal_show("++ SOC_CONSYS coredump get successfully ++\n"); -+ /* call AEE driver API */ -+#if ENABLE_F_TRACE -+ aed_combo_exception_api(NULL, 0, (const int *)pbuf, len, (const char *)g_core_dump->info, DB_OPT_FTRACE); -+#else -+ aed_combo_exception(NULL, 0, (const int *)pbuf, len, (const char *)g_core_dump->info); -+#endif -+ -+#endif -+ -+#endif // WMT_PLAT_ALPS -+ -+ /* reset */ -+ wcn_core_dump_reset(g_core_dump, STP_CORE_DUMP_TIMEOUT); -+ -+ return 0; -+} -+ -+static INT32 wcn_gzip_compressor(void *worker, UINT8 *in_buf, INT32 in_sz, UINT8 *out_buf, INT32 *out_sz, -+ INT32 finish) -+{ -+ INT32 ret = 0; -+ z_stream *stream = NULL; -+ INT32 tmp = *out_sz; -+ -+ STP_DBG_INFO_FUNC("need to compressor :buf 0x%zx, size %d\n", (SIZE_T) in_buf, in_sz); -+ STP_DBG_INFO_FUNC("before compressor,avalible buf: 0x%zx, size %d\n", (SIZE_T) out_buf, tmp); -+ -+ stream = (z_stream *) worker; -+ if (!stream) { -+ STP_DBG_ERR_FUNC("invalid workspace!\n"); -+ return -1; -+ } -+ -+ if (in_sz > 0) { -+#if 0 -+ ret = zlib_deflateReset(stream); -+ if (ret != Z_OK) { -+ STP_DBG_ERR_FUNC("reset failed!\n"); -+ return -2; -+ } -+#endif -+ -+ stream->next_in = in_buf; -+ stream->avail_in = in_sz; -+ stream->next_out = out_buf; -+ stream->avail_out = tmp; -+ -+ zlib_deflate(stream, Z_FULL_FLUSH); -+ -+ if (finish) { -+ while (1) { -+ int val = zlib_deflate(stream, Z_FINISH); -+ -+ if (val == Z_OK) -+ continue; -+ else if (val == Z_STREAM_END) -+ break; -+ STP_DBG_ERR_FUNC("finish operation failed %d\n", val); -+ return -3; -+ } -+ } -+ -+ *out_sz = tmp - stream->avail_out; -+ } -+ -+ STP_DBG_INFO_FUNC("after compressor,avalible buf: 0x%zx, compress rate %d -> %d\n", (SIZE_T) out_buf, in_sz, -+ *out_sz); -+ -+ return ret; -+} -+ -+/* wcn_compressor_init - create a compressor and do init -+ * @ name - compressor's name -+ * @ L1_buf_sz - L1 buffer size -+ * @ L2_buf_sz - L2 buffer size -+ * -+ * Retunr object's pointer if success, else NULL -+ */ -+P_WCN_COMPRESSOR_T wcn_compressor_init(PUINT8 name, INT32 L1_buf_sz, INT32 L2_buf_sz) -+{ -+ z_stream *pstream = NULL; -+ P_WCN_COMPRESSOR_T compress = NULL; -+ -+ compress = (P_WCN_COMPRESSOR_T) osal_malloc(sizeof(WCN_COMPRESSOR_T)); -+ if (!compress) { -+ STP_DBG_ERR_FUNC("alloc compressor failed!\n"); -+ goto fail; -+ } -+ -+ osal_memset(compress, 0, sizeof(WCN_COMPRESSOR_T)); -+ osal_memcpy(compress->name, name, STP_OJB_NAME_SZ); -+ -+ compress->f_compress_en = 0; -+ compress->compress_type = GZIP; -+ -+ if (compress->compress_type == GZIP) { -+ compress->worker = osal_malloc(sizeof(z_stream)); -+ if (!compress->worker) { -+ STP_DBG_ERR_FUNC("alloc stream failed!\n"); -+ goto fail; -+ } -+ pstream = (z_stream *) compress->worker; -+ -+ pstream->workspace = osal_malloc(zlib_deflate_workspacesize(MAX_WBITS, MAX_MEM_LEVEL)); -+ if (!pstream->workspace) { -+ STP_DBG_ERR_FUNC("alloc workspace failed!\n"); -+ goto fail; -+ } -+ zlib_deflateInit2(pstream, Z_DEFAULT_COMPRESSION, Z_DEFLATED, -MAX_WBITS, -+ DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY); -+ } -+ -+ compress->handler = wcn_gzip_compressor; -+ compress->L1_buf_sz = L1_buf_sz; -+ compress->L2_buf_sz = L2_buf_sz; -+ compress->L1_pos = 0; -+ compress->L2_pos = 0; -+ compress->uncomp_size = 0; -+ compress->crc32 = 0xffffffffUL; -+ -+ compress->L1_buf = osal_malloc(compress->L1_buf_sz); -+ if (!compress->L1_buf) { -+ STP_DBG_ERR_FUNC("alloc %d bytes for L1 buf failed!\n", compress->L1_buf_sz); -+ goto fail; -+ } -+ -+ compress->L2_buf = osal_malloc(compress->L2_buf_sz); -+ if (!compress->L2_buf) { -+ STP_DBG_ERR_FUNC("alloc %d bytes for L2 buf failed!\n", compress->L2_buf_sz); -+ goto fail; -+ } -+ -+ STP_DBG_INFO_FUNC("create compressor OK! L1 %d bytes, L2 %d bytes\n", L1_buf_sz, L2_buf_sz); -+ return compress; -+ -+fail: -+ if (compress) { -+ if (compress->L2_buf) { -+ osal_free(compress->L2_buf); -+ compress->L2_buf = NULL; -+ } -+ -+ if (compress->L1_buf) { -+ osal_free(compress->L1_buf); -+ compress->L1_buf = NULL; -+ } -+ -+ if (compress->worker) { -+ pstream = (z_stream *) compress->worker; -+ if ((compress->compress_type == GZIP) && pstream->workspace) { -+ zlib_deflateEnd(pstream); -+ osal_free(pstream->workspace); -+ } -+ osal_free(compress->worker); -+ compress->worker = NULL; -+ } -+ -+ if (compress->worker) { -+ osal_free(compress->worker); -+ compress->worker = NULL; -+ } -+ -+ osal_free(compress); -+ compress = NULL; -+ } -+ -+ STP_DBG_ERR_FUNC("init failed!\n"); -+ -+ return NULL; -+} -+ -+/* wcn_compressor_deinit - distroy a compressor -+ * @ cprs - compressor's pointer -+ * -+ * Retunr 0 if success, else NULL -+ */ -+INT32 wcn_compressor_deinit(P_WCN_COMPRESSOR_T cprs) -+{ -+ z_stream *pstream = NULL; -+ -+ if (cprs) { -+ if (cprs->L2_buf) { -+ osal_free(cprs->L2_buf); -+ cprs->L2_buf = NULL; -+ } -+ -+ if (cprs->L1_buf) { -+ osal_free(cprs->L1_buf); -+ cprs->L1_buf = NULL; -+ } -+ -+ if (cprs->worker) { -+ pstream = (z_stream *) cprs->worker; -+ if ((cprs->compress_type == GZIP) && pstream->workspace) { -+ zlib_deflateEnd(pstream); -+ osal_free(pstream->workspace); -+ } -+ osal_free(cprs->worker); -+ cprs->worker = NULL; -+ } -+ -+ cprs->handler = NULL; -+ -+ osal_free(cprs); -+ } -+ -+ STP_DBG_INFO_FUNC("destroy OK\n"); -+ -+ return 0; -+} -+ -+/* wcn_compressor_in - put in a raw data, and compress L1 buffer if need -+ * @ cprs - compressor's pointer -+ * @ buf - raw data buffer -+ * @ len - raw data length -+ * @ finish - core dump finish or not, 1: finished; 0: not finish -+ * -+ * Retunr 0 if success, else NULL -+ */ -+INT32 wcn_compressor_in(P_WCN_COMPRESSOR_T cprs, PUINT8 buf, INT32 len, INT32 finish) -+{ -+ INT32 tmp_len = 0; -+ INT32 ret = 0; -+ -+ if (!cprs) { -+ STP_DBG_ERR_FUNC("invalid para!\n"); -+ return -1; -+ } -+ -+ cprs->uncomp_size += len; -+ -+ /* check L1 buf valid space */ -+ if (len > (cprs->L1_buf_sz - cprs->L1_pos)) { -+ STP_DBG_INFO_FUNC("L1 buffer full\n"); -+ -+ if (cprs->f_compress_en && cprs->handler) { -+ /* need compress */ -+ /* compress L1 buffer, and put result to L2 buffer */ -+ tmp_len = cprs->L2_buf_sz - cprs->L2_pos; -+ ret = -+ cprs->handler(cprs->worker, cprs->L1_buf, cprs->L1_pos, &cprs->L2_buf[cprs->L2_pos], -+ &tmp_len, finish); -+ if (!ret) { -+ cprs->crc32 = (crc32(cprs->crc32, cprs->L1_buf, cprs->L1_pos)); -+ cprs->L2_pos += tmp_len; -+ if (cprs->L2_pos > cprs->L2_buf_sz) -+ STP_DBG_ERR_FUNC("coredump size too large(%d), L2 buf overflow\n", -+ cprs->L2_pos); -+ -+ if (finish) { -+ /* Add 8 byte suffix -+ === -+ 32 bits UNCOMPRESS SIZE -+ 32 bits CRC -+ */ -+ *(uint32_t *) (&cprs->L2_buf[cprs->L2_pos]) = (cprs->crc32 ^ 0xffffffffUL); -+ *(uint32_t *) (&cprs->L2_buf[cprs->L2_pos + 4]) = cprs->uncomp_size; -+ cprs->L2_pos += 8; -+ } -+ STP_DBG_INFO_FUNC("compress OK!\n"); -+ } else -+ STP_DBG_ERR_FUNC("compress error!\n"); -+ } else { -+ /* no need compress */ -+ /* Flush L1 buffer to L2 buffer */ -+ STP_DBG_INFO_FUNC("No need do compress, Put to L2 buf\n"); -+ -+ tmp_len = cprs->L2_buf_sz - cprs->L2_pos; -+ tmp_len = (cprs->L1_pos > tmp_len) ? tmp_len : cprs->L1_pos; -+ osal_memcpy(&cprs->L2_buf[cprs->L2_pos], cprs->L1_buf, tmp_len); -+ cprs->L2_pos += tmp_len; -+ } -+ -+ /* reset L1 buf pos */ -+ cprs->L1_pos = 0; -+ -+ /* put curren data to L1 buf */ -+ if (len > cprs->L1_buf_sz) { -+ STP_DBG_ERR_FUNC("len=%d, too long err!\n", len); -+ } else { -+ STP_DBG_INFO_FUNC("L1 Flushed, and Put %d bytes to L1 buf\n", len); -+ osal_memcpy(&cprs->L1_buf[cprs->L1_pos], buf, len); -+ cprs->L1_pos += len; -+ } -+ } else { -+ /* put to L1 buffer */ -+ STP_DBG_INFO_FUNC("Put %d bytes to L1 buf\n", len); -+ -+ osal_memcpy(&cprs->L1_buf[cprs->L1_pos], buf, len); -+ cprs->L1_pos += len; -+ } -+ -+ return ret; -+} -+ -+/* wcn_compressor_out - get the result data from L2 buffer -+ * @ cprs - compressor's pointer -+ * @ pbuf - point to L2 buffer -+ * @ plen - out len -+ * -+ * Retunr 0 if success, else NULL -+ */ -+INT32 wcn_compressor_out(P_WCN_COMPRESSOR_T cprs, PUINT8 *pbuf, PINT32 plen) -+{ -+ INT32 ret = 0; -+ INT32 tmp_len = 0; -+ -+ if ((!cprs) || (!pbuf) || (!plen)) { -+ STP_DBG_ERR_FUNC("invalid para!\n"); -+ return -1; -+ } -+ /* check if there's L1 data need flush to L2 buffer */ -+ if (cprs->L1_pos > 0) { -+ tmp_len = cprs->L2_buf_sz - cprs->L2_pos; -+ -+ if (cprs->f_compress_en && cprs->handler) { -+ /* need compress */ -+ ret = -+ cprs->handler(cprs->worker, cprs->L1_buf, cprs->L1_pos, &cprs->L2_buf[cprs->L2_pos], -+ &tmp_len, 1); -+ -+ if (!ret) { -+ cprs->crc32 = (crc32(cprs->crc32, cprs->L1_buf, cprs->L1_pos)); -+ cprs->L2_pos += tmp_len; -+ -+ /* Add 8 byte suffix -+ === -+ 32 bits UNCOMPRESS SIZE -+ 32 bits CRC -+ */ -+ *(uint32_t *) (&cprs->L2_buf[cprs->L2_pos]) = (cprs->crc32 ^ 0xffffffffUL); -+ *(uint32_t *) (&cprs->L2_buf[cprs->L2_pos + 4]) = cprs->uncomp_size; -+ cprs->L2_pos += 8; -+ -+ STP_DBG_INFO_FUNC("compress OK!\n"); -+ } else { -+ STP_DBG_ERR_FUNC("compress error!\n"); -+ } -+ } else { -+ /* no need compress */ -+ tmp_len = (cprs->L1_pos > tmp_len) ? tmp_len : cprs->L1_pos; -+ osal_memcpy(&cprs->L2_buf[cprs->L2_pos], cprs->L1_buf, tmp_len); -+ cprs->L2_pos += tmp_len; -+ } -+ -+ cprs->L1_pos = 0; -+ } -+ -+ *pbuf = cprs->L2_buf; -+ *plen = cprs->L2_pos; -+ -+ STP_DBG_INFO_FUNC("0x%zx, len %d\n", (SIZE_T)*pbuf, *plen); -+ -+ return 0; -+} -+ -+/* wcn_compressor_reset - reset compressor -+ * @ cprs - compressor's pointer -+ * @ enable - enable/disable compress -+ * @ type - compress algorithm -+ * -+ * Retunr 0 if success, else NULL -+ */ -+INT32 wcn_compressor_reset(P_WCN_COMPRESSOR_T cprs, UINT8 enable, WCN_COMPRESS_ALG_T type) -+{ -+ if (!cprs) { -+ STP_DBG_ERR_FUNC("invalid para!\n"); -+ return -1; -+ } -+ -+ cprs->f_compress_en = enable; -+ /* cprs->f_compress_en = 0; // disable compress for test */ -+ cprs->compress_type = type; -+ cprs->L1_pos = 0; -+ cprs->L2_pos = 0; -+ cprs->uncomp_size = 0; -+ cprs->crc32 = 0xffffffffUL; -+ -+ /* zlib_deflateEnd((z_stream*)cprs->worker); */ -+ -+ STP_DBG_INFO_FUNC("OK! compress algorithm %d\n", type); -+ -+ return 0; -+} -+ -+static void stp_dbg_dump_data(unsigned char *pBuf, char *title, int len) -+{ -+ int k = 0; -+ -+ pr_debug(" %s-len:%d\n", title, len); -+ -+ for (k = 0; k < len; k++) { -+ if (k % 16 == 0 && k != 0) -+ pr_cont("\n "); -+ pr_cont("0x%02x ", pBuf[k]); -+ } -+ pr_debug("--end\n"); -+} -+ -+static int _stp_dbg_enable(MTKSTP_DBG_T *stp_dbg) -+{ -+ -+ unsigned long flags; -+ -+ spin_lock_irqsave(&(stp_dbg->logsys->lock), flags); -+ stp_dbg->pkt_trace_no = 0; -+ stp_dbg->is_enable = 1; -+ spin_unlock_irqrestore(&(stp_dbg->logsys->lock), flags); -+ -+ return 0; -+} -+ -+static int _stp_dbg_disable(MTKSTP_DBG_T *stp_dbg) -+{ -+ -+ unsigned long flags; -+ -+ spin_lock_irqsave(&(stp_dbg->logsys->lock), flags); -+ stp_dbg->pkt_trace_no = 0; -+ memset(stp_dbg->logsys, 0, sizeof(MTKSTP_LOG_SYS_T)); -+ stp_dbg->is_enable = 0; -+ spin_unlock_irqrestore(&(stp_dbg->logsys->lock), flags); -+ -+ return 0; -+} -+ -+static int _stp_dbg_dmp_in(MTKSTP_DBG_T *stp_dbg, char *buf, int len) -+{ -+ unsigned long flags; -+ STP_DBG_HDR_T *pHdr = NULL; -+ char *pBuf = NULL; -+ unsigned int length = 0; -+ unsigned int internalFlag = stp_dbg->logsys->size < STP_DBG_LOG_ENTRY_NUM; -+ /* #ifdef CONFIG_LOG_STP_INTERNAL */ -+ /* Here we record log in this circle buffer, if buffer is full , -+ select to overlap earlier log, logic should be okay */ -+ internalFlag = 1; -+ /* #endif */ -+ spin_lock_irqsave(&(stp_dbg->logsys->lock), flags); -+ -+ if (internalFlag) { -+ stp_dbg->logsys->queue[stp_dbg->logsys->in].id = 0; -+ stp_dbg->logsys->queue[stp_dbg->logsys->in].len = len; -+ memset(&(stp_dbg->logsys->queue[stp_dbg->logsys->in].buffer[0]), -+ 0, ((len >= STP_DBG_LOG_ENTRY_SZ) ? (STP_DBG_LOG_ENTRY_SZ) : (len))); -+ memcpy(&(stp_dbg->logsys->queue[stp_dbg->logsys->in].buffer[0]), -+ buf, ((len >= STP_DBG_LOG_ENTRY_SZ) ? (STP_DBG_LOG_ENTRY_SZ) : (len))); -+ -+ stp_dbg->logsys->size++; -+ stp_dbg->logsys->size = -+ (stp_dbg->logsys->size > STP_DBG_LOG_ENTRY_NUM) ? STP_DBG_LOG_ENTRY_NUM : stp_dbg->logsys->size; -+ -+ if (0 != gStpDbgLogOut) { -+ pHdr = (STP_DBG_HDR_T *) &(stp_dbg->logsys->queue[stp_dbg->logsys->in].buffer[0]); -+ pBuf = (char *)&(stp_dbg->logsys->queue[stp_dbg->logsys->in].buffer[0]) + sizeof(STP_DBG_HDR_T); -+ length = stp_dbg->logsys->queue[stp_dbg->logsys->in].len - sizeof(STP_DBG_HDR_T); -+ pr_debug("STP-DBG:%d.%ds, %s:pT%sn(%d)l(%d)s(%d)a(%d)\n", -+ pHdr->sec, -+ pHdr->usec, -+ pHdr->dir == PKT_DIR_TX ? "Tx" : "Rx", -+ gStpDbgType[pHdr->type], pHdr->no, pHdr->len, pHdr->seq, pHdr->ack); -+ if (0 < length) -+ stp_dbg_dump_data(pBuf, pHdr->dir == PKT_DIR_TX ? "Tx" : "Rx", length); -+ } -+ stp_dbg->logsys->in = -+ (stp_dbg->logsys->in >= (STP_DBG_LOG_ENTRY_NUM - 1)) ? (0) : (stp_dbg->logsys->in + 1); -+ STP_DBG_DBG_FUNC("logsys size = %d, in = %d\n", stp_dbg->logsys->size, stp_dbg->logsys->in); -+ } else { -+ STP_DBG_WARN_FUNC("logsys FULL!\n"); -+ } -+ -+ spin_unlock_irqrestore(&(stp_dbg->logsys->lock), flags); -+ -+ return 0; -+} -+ -+int stp_gdb_notify_btm_dmp_wq(MTKSTP_DBG_T *stp_dbg) -+{ -+ int retval = 0; -+/* #ifndef CONFIG_LOG_STP_INTERNAL */ -+ -+ if (stp_dbg->btm != NULL) -+ retval += stp_btm_notify_wmt_dmp_wq((MTKSTP_BTM_T *) stp_dbg->btm); -+/* #endif */ -+ -+ return retval; -+} -+ -+int stp_dbg_log_ctrl(unsigned int on) -+{ -+ if (on != 0) { -+ gStpDbgLogOut = 1; -+ pr_debug("STP-DBG: enable pkt log dump out.\n"); -+ } else { -+ gStpDbgLogOut = 0; -+ pr_debug("STP-DBG: disable pkt log dump out.\n"); -+ } -+ return 0; -+} -+ -+int stp_dbg_dmp_in(MTKSTP_DBG_T *stp_dbg, char *buf, int len) -+{ -+ return _stp_dbg_dmp_in(stp_dbg, buf, len); -+} -+ -+int stp_dbg_dmp_printk(MTKSTP_DBG_T *stp_dbg) -+{ -+#define MAX_DMP_NUM 80 -+ unsigned long flags; -+ char *pBuf = NULL; -+ int len = 0; -+ STP_DBG_HDR_T *pHdr = NULL; -+ UINT32 dumpSize = 0; -+ UINT32 inIndex = 0; -+ UINT32 outIndex = 0; -+ -+ spin_lock_irqsave(&(stp_dbg->logsys->lock), flags); -+ /* Not to dequeue from loging system */ -+ inIndex = stp_dbg->logsys->in; -+ dumpSize = stp_dbg->logsys->size; -+ if (STP_DBG_LOG_ENTRY_NUM == dumpSize) -+ outIndex = inIndex; -+ else -+ outIndex = ((inIndex + STP_DBG_LOG_ENTRY_NUM) - dumpSize) % STP_DBG_LOG_ENTRY_NUM; -+ -+ if (dumpSize > MAX_DMP_NUM) { -+ -+ outIndex += (dumpSize - MAX_DMP_NUM); -+ outIndex %= STP_DBG_LOG_ENTRY_NUM; -+ dumpSize = MAX_DMP_NUM; -+ -+ } -+ STP_DBG_INFO_FUNC("loged packet size = %d, in(%d), out(%d)\n", dumpSize, inIndex, outIndex); -+ while (dumpSize > 0) { -+ pHdr = (STP_DBG_HDR_T *) &(stp_dbg->logsys->queue[outIndex].buffer[0]); -+ pBuf = &(stp_dbg->logsys->queue[outIndex].buffer[0]) + sizeof(STP_DBG_HDR_T); -+ len = stp_dbg->logsys->queue[outIndex].len - sizeof(STP_DBG_HDR_T); -+ len = len > STP_PKT_SZ ? STP_PKT_SZ : len; -+ pr_debug("STP-DBG:%d.%ds, %s:pT%sn(%d)l(%d)s(%d)a(%d)\n", -+ pHdr->sec, -+ pHdr->usec, -+ pHdr->dir == PKT_DIR_TX ? "Tx" : "Rx", -+ gStpDbgType[pHdr->type], pHdr->no, pHdr->len, pHdr->seq, pHdr->ack); -+ -+ if (0 < len) -+ stp_dbg_dump_data(pBuf, pHdr->dir == PKT_DIR_TX ? "Tx" : "Rx", len); -+ outIndex = (outIndex >= (STP_DBG_LOG_ENTRY_NUM - 1)) ? (0) : (outIndex + 1); -+ dumpSize--; -+ -+ } -+ -+ spin_unlock_irqrestore(&(stp_dbg->logsys->lock), flags); -+ -+ return 0; -+} -+ -+int stp_dbg_dmp_out_ex(char *buf, int *len) -+{ -+ return stp_dbg_dmp_out(g_stp_dbg, buf, len); -+} -+ -+int stp_dbg_dmp_out(MTKSTP_DBG_T *stp_dbg, char *buf, int *len) -+{ -+ -+ unsigned long flags; -+ int remaining = 0; -+ *len = 0; -+ spin_lock_irqsave(&(stp_dbg->logsys->lock), flags); -+ -+ if (stp_dbg->logsys->size > 0) { -+ memcpy(buf, &(stp_dbg->logsys->queue[stp_dbg->logsys->out].buffer[0]), -+ stp_dbg->logsys->queue[stp_dbg->logsys->out].len); -+ -+ (*len) = stp_dbg->logsys->queue[stp_dbg->logsys->out].len; -+ stp_dbg->logsys->out = -+ (stp_dbg->logsys->out >= (STP_DBG_LOG_ENTRY_NUM - 1)) ? (0) : (stp_dbg->logsys->out + 1); -+ stp_dbg->logsys->size--; -+ -+ STP_DBG_DBG_FUNC("logsys size = %d, out = %d\n", stp_dbg->logsys->size, stp_dbg->logsys->out); -+ } else { -+ STP_DBG_LOUD_FUNC("logsys EMPTY!\n"); -+ } -+ -+ remaining = (stp_dbg->logsys->size == 0) ? (0) : (1); -+ -+ spin_unlock_irqrestore(&(stp_dbg->logsys->lock), flags); -+ -+ return remaining; -+} -+ -+static int stp_dbg_fill_hdr(struct stp_dbg_pkt_hdr *hdr, int type, int ack, int seq, int crc, int dir, int len, -+ int dbg_type) -+{ -+ -+ struct timeval now; -+ -+ if (!hdr) { -+ STP_DBG_ERR_FUNC("function invalid\n"); -+ return -EINVAL; -+ } -+ do_gettimeofday(&now); -+ hdr->dbg_type = dbg_type; -+ hdr->ack = ack; -+ hdr->seq = seq; -+ hdr->sec = now.tv_sec; -+ hdr->usec = now.tv_usec; -+ hdr->crc = crc; -+ hdr->dir = dir; /* rx */ -+ hdr->dmy = 0xffffffff; -+ hdr->len = len; -+ hdr->type = type; -+ return 0; -+ -+} -+ -+static int stp_dbg_add_pkt(MTKSTP_DBG_T *stp_dbg, struct stp_dbg_pkt_hdr *hdr, const unsigned char *body) -+{ -+ /* fix the frame size large issues. */ -+ static struct stp_dbg_pkt stp_pkt; -+ uint32_t hdr_sz = sizeof(struct stp_dbg_pkt_hdr); -+ uint32_t body_sz = 0; -+ -+ BUG_ON(!stp_dbg); -+ -+ if (hdr->dbg_type == STP_DBG_PKT) -+ body_sz = (hdr->len <= STP_PKT_SZ) ? (hdr->len) : (STP_PKT_SZ); -+ else -+ body_sz = (hdr->len <= STP_DMP_SZ) ? (hdr->len) : (STP_DMP_SZ); -+ -+ hdr->no = stp_dbg->pkt_trace_no++; -+ memcpy((uint8_t *) &stp_pkt.hdr, (uint8_t *) hdr, hdr_sz); -+ if (body != NULL) -+ memcpy((uint8_t *) &stp_pkt.raw[0], body, body_sz); -+ -+ _stp_dbg_dmp_in(stp_dbg, (char *)&stp_pkt, hdr_sz + body_sz); -+ /* Only FW DMP MSG should inform BTM-CORE to dump packet to native process */ -+ if (hdr->dbg_type == STP_DBG_FW_DMP) -+ stp_gdb_notify_btm_dmp_wq(stp_dbg); -+ -+ return 0; -+} -+ -+int stp_dbg_log_pkt(MTKSTP_DBG_T *stp_dbg, int dbg_type, -+ int type, int ack_no, int seq_no, int crc, int dir, int len, const unsigned char *body) -+{ -+ -+ struct stp_dbg_pkt_hdr hdr; -+ -+ if (stp_dbg->is_enable == 0) { -+ /*dbg is disable,and not to log */ -+ } else { -+ hdr.no = 0; -+ hdr.chs = 0; -+ stp_dbg_fill_hdr(&hdr, -+ (int)type, (int)ack_no, (int)seq_no, (int)crc, (int)dir, (int)len, (int)dbg_type); -+ -+ stp_dbg_add_pkt(stp_dbg, &hdr, body); -+ } -+ -+ return 0; -+} -+ -+int stp_dbg_enable(MTKSTP_DBG_T *stp_dbg) -+{ -+ return _stp_dbg_enable(stp_dbg); -+} -+ -+int stp_dbg_disable(MTKSTP_DBG_T *stp_dbg) -+{ -+ return _stp_dbg_disable(stp_dbg); -+} -+ -+static void stp_dbg_nl_init(void) -+{ -+#if 0 -+ if (genl_register_family(&stp_dbg_gnl_family) != 0) { -+ STP_DBG_ERR_FUNC("%s(): GE_NELINK family registration fail\n", __func__); -+ } else { -+ if (genl_register_ops(&stp_dbg_gnl_family, &stp_dbg_gnl_ops_bind) != 0) -+ STP_DBG_ERR_FUNC("%s(): BIND operation registration fail\n", __func__); -+ -+ if (genl_register_ops(&stp_dbg_gnl_family, &stp_dbg_gnl_ops_reset) != 0) -+ STP_DBG_ERR_FUNC("%s(): RESET operation registration fail\n", __func__); -+ -+ } -+#endif -+ if (genl_register_family_with_ops(&stp_dbg_gnl_family, stp_dbg_gnl_ops_array) != 0) -+ STP_DBG_ERR_FUNC("%s(): GE_NELINK family registration fail\n", __func__); -+} -+ -+static void stp_dbg_nl_deinit(void) -+{ -+ genl_unregister_family(&stp_dbg_gnl_family); -+} -+ -+static int stp_dbg_nl_bind(struct sk_buff *skb, struct genl_info *info) -+{ -+ struct nlattr *na; -+ char *mydata; -+ -+ if (info == NULL) -+ goto out; -+ -+ STP_DBG_INFO_FUNC("%s():->\n", __func__); -+ -+ na = info->attrs[STP_DBG_ATTR_MSG]; -+ -+ if (na) -+ mydata = (char *)nla_data(na); -+ -+ if (num_bind_process < MAX_BIND_PROCESS) { -+ bind_pid[num_bind_process] = info->snd_portid; -+ num_bind_process++; -+ STP_DBG_INFO_FUNC("%s():-> pid = %d\n", __func__, info->snd_portid); -+ } else { -+ STP_DBG_ERR_FUNC("%s(): exceeding binding limit %d\n", __func__, MAX_BIND_PROCESS); -+ } -+ -+out: -+ return 0; -+} -+ -+static int stp_dbg_nl_reset(struct sk_buff *skb, struct genl_info *info) -+{ -+ STP_DBG_ERR_FUNC("%s(): should not be invoked\n", __func__); -+ -+ return 0; -+} -+ -+INT8 stp_dbg_nl_send(PINT8 aucMsg, UINT8 cmd, INT32 len) -+{ -+ struct sk_buff *skb = NULL; -+ void *msg_head = NULL; -+ int rc = -1; -+ int i; -+ -+ if (num_bind_process == 0) { -+ /* no listening process */ -+ STP_DBG_ERR_FUNC("%s(): the process is not invoked\n", __func__); -+ return 0; -+ } -+ -+ for (i = 0; i < num_bind_process; i++) { -+ skb = genlmsg_new(2048, GFP_KERNEL); -+ -+ if (skb) { -+ msg_head = genlmsg_put(skb, 0, stp_dbg_seqnum++, &stp_dbg_gnl_family, 0, cmd); -+ if (msg_head == NULL) { -+ nlmsg_free(skb); -+ STP_DBG_ERR_FUNC("%s(): genlmsg_put fail...\n", __func__); -+ return -1; -+ } -+ -+ rc = nla_put(skb, STP_DBG_ATTR_MSG, len, aucMsg); -+ if (rc != 0) { -+ nlmsg_free(skb); -+ STP_DBG_ERR_FUNC("%s(): nla_put_string fail...%d\n", __func__, rc); -+ return -1; -+ } -+ -+ /* finalize the message */ -+ genlmsg_end(skb, msg_head); -+ -+ /* sending message */ -+ rc = genlmsg_unicast(&init_net, skb, bind_pid[i]); -+ if (rc != 0) { -+ STP_DBG_ERR_FUNC("%s(): genlmsg_unicast fail...\n", __func__); -+ return -1; -+ } -+ } else { -+ STP_DBG_ERR_FUNC("%s(): genlmsg_new fail...\n", __func__); -+ return -1; -+ } -+ } -+ -+ return 0; -+} -+ -+INT32 stp_dbg_aee_send(unsigned char *aucMsg, INT32 len, INT32 cmd) -+{ -+ INT32 ret = 0; -+ -+ /* buffered to compressor */ -+ ret = wcn_core_dump_in(g_core_dump, aucMsg, len); -+ if (ret == 1) -+ wcn_core_dump_flush(0, MTK_WCN_BOOL_FALSE); -+ -+ return ret; -+} -+ -+UINT8 *_stp_dbg_id_to_task(UINT32 id) -+{ -+ UINT8 *taskStr[] = { -+ "Task_WMT", -+ "Task_BT", -+ "Task_Wifi", -+ "Task_Tst", -+ "Task_FM", -+ "Task_Idle", -+ "Task_DrvStp", -+ "Task_DrvBtif", -+ "Task_NatBt" -+ }; -+ return taskStr[id]; -+} -+ -+INT32 _stp_dbg_parser_assert_str(PINT8 str, ENUM_ASSERT_INFO_PARSER_TYPE type) -+{ -+ char *pStr = NULL; -+ char *pDtr = NULL; -+ char *pTemp = NULL; -+ char *pTemp2 = NULL; -+ char tempBuf[64] = { 0 }; -+ UINT32 len = 0; -+ long res; -+ INT32 ret; -+ -+ PUINT8 parser_sub_string[] = { -+ " ", -+ "id=", -+ "isr=", -+ "irq=", -+ "rc=" -+ }; -+ -+ if (!str) { -+ STP_DBG_ERR_FUNC("NULL string source\n"); -+ return -1; -+ } -+ -+ if (!g_stp_dbg_cpupcr) { -+ STP_DBG_ERR_FUNC("NULL pointer\n"); -+ return -2; -+ } -+ -+ pStr = str; -+ STP_DBG_DBG_FUNC("source infor:%s\n", pStr); -+ switch (type) { -+ case STP_DBG_ASSERT_INFO: -+ pDtr = osal_strstr(pStr, parser_sub_string[type]); -+ if (NULL != pDtr) { -+ pDtr += osal_strlen(parser_sub_string[type]); -+ pTemp = osal_strchr(pDtr, ' '); -+ } else { -+ STP_DBG_ERR_FUNC("parser str is NULL,substring(%s)\n", parser_sub_string[type]); -+ return -3; -+ } -+ len = pTemp - pDtr; -+ osal_memcpy(&g_stp_dbg_cpupcr->assert_info[0], "assert@", osal_strlen("assert@")); -+ osal_memcpy(&g_stp_dbg_cpupcr->assert_info[osal_strlen("assert@")], pDtr, len); -+ g_stp_dbg_cpupcr->assert_info[osal_strlen("assert@") + len] = '_'; -+ -+ pTemp = osal_strchr(pDtr, '#'); -+ pTemp += 1; -+ -+ pTemp2 = osal_strchr(pTemp, ' '); -+ osal_memcpy(&g_stp_dbg_cpupcr->assert_info[osal_strlen("assert@") + len + 1], pTemp, pTemp2 - pTemp); -+ g_stp_dbg_cpupcr->assert_info[osal_strlen("assert@") + len + 1 + pTemp2 - pTemp] = '\0'; -+ STP_DBG_INFO_FUNC("assert info:%s\n", &g_stp_dbg_cpupcr->assert_info[0]); -+ break; -+ case STP_DBG_FW_TASK_ID: -+ pDtr = osal_strstr(pStr, parser_sub_string[type]); -+ if (NULL != pDtr) { -+ pDtr += osal_strlen(parser_sub_string[type]); -+ pTemp = osal_strchr(pDtr, ' '); -+ } else { -+ STP_DBG_ERR_FUNC("parser str is NULL,substring(%s)\n", parser_sub_string[type]); -+ return -3; -+ } -+ len = pTemp - pDtr; -+ osal_memcpy(&tempBuf[0], pDtr, len); -+ tempBuf[len] = '\0'; -+ ret = osal_strtol(tempBuf, 16, &res); -+ if (ret) { -+ STP_DBG_ERR_FUNC("get fw task id fail(%d)\n", ret); -+ return -4; -+ } -+ g_stp_dbg_cpupcr->fwTaskId = (UINT32)res; -+ -+ STP_DBG_INFO_FUNC("fw task id :%x\n", (UINT32)res); -+ break; -+ case STP_DBG_FW_ISR: -+ pDtr = osal_strstr(pStr, parser_sub_string[type]); -+ if (NULL != pDtr) { -+ pDtr += osal_strlen(parser_sub_string[type]); -+ pTemp = osal_strchr(pDtr, ','); -+ } else { -+ STP_DBG_ERR_FUNC("parser str is NULL,substring(%s)\n", parser_sub_string[type]); -+ return -3; -+ } -+ len = pTemp - pDtr; -+ osal_memcpy(&tempBuf[0], pDtr, len); -+ tempBuf[len] = '\0'; -+ ret = osal_strtol(tempBuf, 16, &res); -+ if (ret) { -+ STP_DBG_ERR_FUNC("get fw isr id fail(%d)\n", ret); -+ return -4; -+ } -+ g_stp_dbg_cpupcr->fwIsr = (UINT32)res; -+ -+ STP_DBG_INFO_FUNC("fw isr str:%x\n", (UINT32)res); -+ break; -+ case STP_DBG_FW_IRQ: -+ pDtr = osal_strstr(pStr, parser_sub_string[type]); -+ if (NULL != pDtr) { -+ pDtr += osal_strlen(parser_sub_string[type]); -+ pTemp = osal_strchr(pDtr, ','); -+ } else { -+ STP_DBG_ERR_FUNC("parser str is NULL,substring(%s)\n", parser_sub_string[type]); -+ return -3; -+ } -+ len = pTemp - pDtr; -+ osal_memcpy(&tempBuf[0], pDtr, len); -+ tempBuf[len] = '\0'; -+ ret = osal_strtol(tempBuf, 16, &res); -+ if (ret) { -+ STP_DBG_ERR_FUNC("get fw irq id fail(%d)\n", ret); -+ return -4; -+ } -+ g_stp_dbg_cpupcr->fwRrq = (UINT32)res; -+ -+ STP_DBG_INFO_FUNC("fw irq value:%x\n", (UINT32)res); -+ break; -+ case STP_DBG_ASSERT_TYPE: -+ pDtr = osal_strstr(pStr, parser_sub_string[type]); -+ if (NULL != pDtr) { -+ pDtr += osal_strlen(parser_sub_string[type]); -+ pTemp = osal_strchr(pDtr, ','); -+ } else { -+ STP_DBG_ERR_FUNC("parser str is NULL,substring(%s)\n", parser_sub_string[type]); -+ return -3; -+ } -+ len = pTemp - pDtr; -+ osal_memcpy(&tempBuf[0], pDtr, len); -+ tempBuf[len] = '\0'; -+ -+ if (0 == osal_memcmp(tempBuf, "*", len)) -+ osal_memcpy(&g_stp_dbg_cpupcr->assert_type[0], "general assert", osal_strlen("general assert")); -+ if (0 == osal_memcmp(tempBuf, "Watch Dog Timeout", len)) -+ osal_memcpy(&g_stp_dbg_cpupcr->assert_type[0], "wdt", osal_strlen("wdt")); -+ if (0 == osal_memcmp(tempBuf, "RB_FULL", osal_strlen("RB_FULL"))) { -+ osal_memcpy(&g_stp_dbg_cpupcr->assert_type[0], tempBuf, len); -+ -+ pDtr = osal_strstr(&g_stp_dbg_cpupcr->assert_type[0], "RB_FULL("); -+ if (NULL != pDtr) { -+ pDtr += osal_strlen("RB_FULL("); -+ pTemp = osal_strchr(pDtr, ')'); -+ } else { -+ STP_DBG_ERR_FUNC("parser str is NULL,substring(RB_FULL()\n"); -+ return -4; -+ } -+ len = pTemp - pDtr; -+ osal_memcpy(&tempBuf[0], pDtr, len); -+ tempBuf[len] = '\0'; -+ ret = osal_strtol(tempBuf, 16, &res); -+ if (ret) { -+ STP_DBG_ERR_FUNC("get fw task id fail(%d)\n", ret); -+ return -5; -+ } -+ g_stp_dbg_cpupcr->fwTaskId = (UINT32)res; -+ -+ STP_DBG_INFO_FUNC("update fw task id :%x\n", (UINT32)res); -+ } -+ -+ STP_DBG_INFO_FUNC("fw asert type:%s\n", g_stp_dbg_cpupcr->assert_type); -+ break; -+ default: -+ STP_DBG_ERR_FUNC("unknown parser type\n"); -+ break; -+ } -+ -+ return 0; -+} -+ -+P_STP_DBG_CPUPCR_T stp_dbg_cpupcr_init(VOID) -+{ -+ P_STP_DBG_CPUPCR_T pSdCpupcr = NULL; -+ -+ pSdCpupcr = (P_STP_DBG_CPUPCR_T) osal_malloc(osal_sizeof(STP_DBG_CPUPCR_T)); -+ if (!pSdCpupcr) { -+ STP_DBG_ERR_FUNC("stp dbg cpupcr allocate memory fail!\n"); -+ return NULL; -+ } -+ -+ osal_memset(pSdCpupcr, 0, osal_sizeof(STP_DBG_CPUPCR_T)); -+ -+ osal_sleepable_lock_init(&pSdCpupcr->lock); -+ -+ return pSdCpupcr; -+} -+ -+P_STP_DBG_DMAREGS_T stp_dbg_dmaregs_init(VOID) -+{ -+ P_STP_DBG_DMAREGS_T pDmaRegs = NULL; -+ -+ pDmaRegs = (P_STP_DBG_DMAREGS_T) osal_malloc(osal_sizeof(STP_DBG_DMAREGS_T)); -+ if (!pDmaRegs) { -+ STP_DBG_ERR_FUNC("stp dbg dmareg allocate memory fail!\n"); -+ return NULL; -+ } -+ -+ osal_memset(pDmaRegs, 0, osal_sizeof(STP_DBG_DMAREGS_T)); -+ -+ osal_sleepable_lock_init(&pDmaRegs->lock); -+ -+ return pDmaRegs; -+} -+ -+VOID stp_dbg_cpupcr_deinit(P_STP_DBG_CPUPCR_T pCpupcr) -+{ -+ if (pCpupcr) { -+ osal_sleepable_lock_deinit(&pCpupcr->lock); -+ osal_free(pCpupcr); -+ pCpupcr = NULL; -+ } -+} -+ -+VOID stp_dbg_dmaregs_deinit(P_STP_DBG_DMAREGS_T pDmaRegs) -+{ -+ if (pDmaRegs) { -+ osal_sleepable_lock_deinit(&pDmaRegs->lock); -+ osal_free(pDmaRegs); -+ pDmaRegs = NULL; -+ } -+} -+ -+INT32 stp_dbg_poll_cpupcr(UINT32 times, UINT32 sleep, UINT32 cmd) -+{ -+ INT32 i = 0; -+ -+ if (!g_stp_dbg_cpupcr) { -+ STP_DBG_ERR_FUNC("NULL reference pointer\n"); -+ return -1; -+ } -+ -+ if (!cmd) { -+ if (g_stp_dbg_cpupcr->count + times > STP_DBG_CPUPCR_NUM) -+ times = STP_DBG_CPUPCR_NUM - g_stp_dbg_cpupcr->count; -+ -+ osal_lock_sleepable_lock(&g_stp_dbg_cpupcr->lock); -+ -+ for (i = 0; i < times; i++) { -+ STP_DBG_INFO_FUNC("i:%d,cpupcr:%08x\n", i, wmt_plat_read_cpupcr()); -+ /* osal_memcpy( -+ * &g_stp_dbg_cpupcr->buffer[i], -+ * (UINT8*)(CONSYS_REG_READ(CONSYS_CPUPCR_REG)), -+ * osal_sizeof(UINT32)); -+ */ -+ g_stp_dbg_cpupcr->buffer[g_stp_dbg_cpupcr->count + i] = wmt_plat_read_cpupcr(); -+ osal_sleep_ms(sleep); -+ } -+ g_stp_dbg_cpupcr->count += times; -+ -+ osal_unlock_sleepable_lock(&g_stp_dbg_cpupcr->lock); -+ } else { -+ STP_DBG_INFO_FUNC("stp-dbg: for proc test polling cpupcr\n"); -+ if (times > STP_DBG_CPUPCR_NUM) -+ times = STP_DBG_CPUPCR_NUM; -+ -+ osal_lock_sleepable_lock(&g_stp_dbg_cpupcr->lock); -+ g_stp_dbg_cpupcr->count = 0; -+ for (i = 0; i < times; i++) { -+ STP_DBG_INFO_FUNC("i:%d,cpupcr:%08x\n", i, wmt_plat_read_cpupcr()); -+ /* osal_memcpy( -+ * &g_stp_dbg_cpupcr->buffer[i], -+ * (UINT8*)(CONSYS_REG_READ(CONSYS_CPUPCR_REG)), -+ * osal_sizeof(UINT32)); -+ */ -+ g_stp_dbg_cpupcr->buffer[i] = wmt_plat_read_cpupcr(); -+ osal_sleep_ms(sleep); -+ } -+ g_stp_dbg_cpupcr->count = times; -+ -+ osal_unlock_sleepable_lock(&g_stp_dbg_cpupcr->lock); -+ -+ } -+ return 0; -+} -+ -+INT32 stp_dbg_poll_dmaregs(UINT32 times, UINT32 sleep) -+{ -+#if 0 -+ INT32 i = 0; -+ -+ if (!g_stp_dbg_dmaregs) { -+ STP_DBG_ERR_FUNC("NULL reference pointer\n"); -+ return -1; -+ } -+ -+ osal_lock_sleepable_lock(&g_stp_dbg_dmaregs->lock); -+ -+ if (g_stp_dbg_dmaregs->count + times > STP_DBG_DMAREGS_NUM) { -+ if (g_stp_dbg_dmaregs->count > STP_DBG_DMAREGS_NUM) { -+ STP_DBG_ERR_FUNC("g_stp_dbg_dmaregs->count:%d must less than STP_DBG_DMAREGS_NUM:%d\n", -+ g_stp_dbg_dmaregs->count, STP_DBG_DMAREGS_NUM); -+ g_stp_dbg_dmaregs->count = 0; -+ STP_DBG_ERR_FUNC("g_stp_dbg_dmaregs->count be set default value 0\n"); -+ } -+ times = STP_DBG_DMAREGS_NUM - g_stp_dbg_dmaregs->count; -+ } -+ if (times > STP_DBG_DMAREGS_NUM) { -+ STP_DBG_ERR_FUNC("times overflow, set default value:0\n"); -+ times = 0; -+ } -+ STP_DBG_WARN_FUNC("---------Now Polling DMA relative Regs -------------\n"); -+ for (i = 0; i < times; i++) { -+ INT32 k = 0; -+ -+ for (; k < DMA_REGS_MAX; k++) { -+ STP_DBG_WARN_FUNC("times:%d,i:%d reg: %s, regs:%08x\n", times, i, dmaRegsStr[k], -+ wmt_plat_read_dmaregs(k)); -+ /* g_stp_dbg_dmaregs->dmaIssue[k][g_stp_dbg_dmaregs->count + i] = wmt_plat_read_dmaregs(k); */ -+ } -+ osal_sleep_ms(sleep); -+ } -+ STP_DBG_WARN_FUNC("---------Polling DMA relative Regs End-------------\n"); -+ g_stp_dbg_dmaregs->count += times; -+ -+ osal_unlock_sleepable_lock(&g_stp_dbg_dmaregs->lock); -+#else -+ return 0; -+#endif -+} -+ -+INT32 stp_dbg_poll_cuppcr_ctrl(UINT32 en) -+{ -+ -+ STP_DBG_INFO_FUNC("%s polling cpupcr\n", en == 0 ? "start" : "stop"); -+ -+ osal_lock_sleepable_lock(&g_stp_dbg_cpupcr->lock); -+ g_stp_dbg_cpupcr->stop_flag = en; -+ osal_unlock_sleepable_lock(&g_stp_dbg_cpupcr->lock); -+ return 0; -+} -+ -+INT32 stp_dbg_set_version_info(UINT32 chipid, UINT8 *pRomVer, UINT8 *pPatchVer, UINT8 *pPatchBrh) -+{ -+ if (g_stp_dbg_cpupcr) { -+ osal_lock_sleepable_lock(&g_stp_dbg_cpupcr->lock); -+ g_stp_dbg_cpupcr->chipId = chipid; -+ -+ if (pRomVer) -+ osal_memcpy(g_stp_dbg_cpupcr->romVer, pRomVer, 2); -+ if (pPatchVer) -+ osal_memcpy(g_stp_dbg_cpupcr->patchVer, pPatchVer, 8); -+ if (pPatchBrh) -+ osal_memcpy(g_stp_dbg_cpupcr->branchVer, pPatchBrh, 4); -+ -+ osal_unlock_sleepable_lock(&g_stp_dbg_cpupcr->lock); -+ } else { -+ STP_DBG_ERR_FUNC("NULL pointer\n"); -+ return -1; -+ } -+ STP_DBG_INFO_FUNC("chipid(0x%x),romver(%s),patchver(%s),branchver(%s)\n", g_stp_dbg_cpupcr->chipId, -+ &g_stp_dbg_cpupcr->romVer[0], &g_stp_dbg_cpupcr->patchVer[0], &g_stp_dbg_cpupcr->branchVer[0]); -+ return 0; -+} -+INT32 stp_dbg_set_wifiver(UINT32 wifiver) -+{ -+ if (g_stp_dbg_cpupcr) { -+ osal_lock_sleepable_lock(&g_stp_dbg_cpupcr->lock); -+ g_stp_dbg_cpupcr->wifiVer = wifiver; -+ osal_unlock_sleepable_lock(&g_stp_dbg_cpupcr->lock); -+ } else { -+ STP_DBG_ERR_FUNC("NULL pointer\n"); -+ return -1; -+ } -+ STP_DBG_INFO_FUNC("wifiver(%x)\n", g_stp_dbg_cpupcr->wifiVer); -+ return 0; -+} -+ -+INT32 stp_dbg_set_host_assert_info(UINT32 drv_type, UINT32 reason, UINT32 en) -+{ -+ osal_lock_sleepable_lock(&g_stp_dbg_cpupcr->lock); -+ -+ g_stp_dbg_cpupcr->host_assert_info.assert_from_host = en; -+ g_stp_dbg_cpupcr->host_assert_info.drv_type = drv_type; -+ g_stp_dbg_cpupcr->host_assert_info.reason = reason; -+ -+ osal_unlock_sleepable_lock(&g_stp_dbg_cpupcr->lock); -+ -+ return 0; -+} -+ -+UINT32 stp_dbg_get_host_trigger_assert(VOID) -+{ -+ return g_stp_dbg_cpupcr->host_assert_info.assert_from_host; -+} -+ -+INT32 stp_dbg_set_fw_info(UINT8 *issue_info, UINT32 len, ENUM_STP_FW_ISSUE_TYPE issue_type) -+{ -+ ENUM_ASSERT_INFO_PARSER_TYPE type_index; -+ PUINT8 tempbuf = NULL; -+ UINT32 i = 0; -+ INT32 iRet = 0; -+ -+ if (NULL == issue_info) { -+ STP_DBG_ERR_FUNC("null issue infor\n"); -+ return -1; -+ } -+ STP_DBG_INFO_FUNC("issue type(%d)\n", issue_type); -+ g_stp_dbg_cpupcr->issue_type = issue_type; -+ osal_memset(&g_stp_dbg_cpupcr->assert_info[0], 0, STP_ASSERT_INFO_SIZE); -+ -+ /*print patch version when assert happened */ -+ STP_DBG_INFO_FUNC("=======================================\n"); -+ STP_DBG_INFO_FUNC("[consys patch]patch version:%s\n", g_stp_dbg_cpupcr->patchVer); -+ STP_DBG_INFO_FUNC("[consys patch]ALPS branch:%s\n", g_stp_dbg_cpupcr->branchVer); -+ STP_DBG_INFO_FUNC("=======================================\n"); -+ -+ if ((STP_FW_ASSERT_ISSUE == issue_type) || -+ (STP_HOST_TRIGGER_FW_ASSERT == issue_type) || (STP_HOST_TRIGGER_ASSERT_TIMEOUT == issue_type)) { -+ if ((STP_FW_ASSERT_ISSUE == issue_type) || (STP_HOST_TRIGGER_FW_ASSERT == issue_type)) { -+ tempbuf = osal_malloc(len + 1); -+ if (!tempbuf) -+ return -2; -+ -+ osal_memcpy(&tempbuf[0], issue_info, len); -+ -+ for (i = 0; i < len; i++) { -+ if (tempbuf[i] == '\0') -+ tempbuf[i] = '?'; -+ } -+ -+ tempbuf[len] = '\0'; -+ -+ for (type_index = STP_DBG_ASSERT_INFO; type_index < STP_DBG_PARSER_TYPE_MAX; type_index++) -+ iRet += _stp_dbg_parser_assert_str(&tempbuf[0], type_index); -+ -+ if (iRet) -+ STP_DBG_ERR_FUNC("passert assert infor fail(%d)\n", iRet); -+ -+ } -+ if ((STP_HOST_TRIGGER_FW_ASSERT == issue_type) || (STP_HOST_TRIGGER_ASSERT_TIMEOUT == issue_type)) { -+ switch (g_stp_dbg_cpupcr->host_assert_info.drv_type) { -+ case 0: -+ STP_DBG_INFO_FUNC("BT trigger assert\n"); -+ osal_lock_sleepable_lock(&g_stp_dbg_cpupcr->lock); -+ if (31 != g_stp_dbg_cpupcr->host_assert_info.reason) -+ /*BT firmware trigger assert */ -+ { -+ g_stp_dbg_cpupcr->fwTaskId = 1; -+ -+ } else -+ /*BT stack trigger assert */ -+ { -+ g_stp_dbg_cpupcr->fwTaskId = 8; -+ } -+ -+ g_stp_dbg_cpupcr->host_assert_info.assert_from_host = 0; -+ /* g_stp_dbg_cpupcr->host_assert_info.drv_type = 0; */ -+ /* g_stp_dbg_cpupcr->host_assert_info.reason = 0; */ -+ -+ osal_unlock_sleepable_lock(&g_stp_dbg_cpupcr->lock); -+ -+ break; -+ case 4: -+ STP_DBG_INFO_FUNC("WMT trigger assert\n"); -+ osal_lock_sleepable_lock(&g_stp_dbg_cpupcr->lock); -+ if (STP_HOST_TRIGGER_ASSERT_TIMEOUT == issue_type) -+ osal_memcpy(&g_stp_dbg_cpupcr->assert_info[0], issue_info, len); -+ -+ if ((38 == g_stp_dbg_cpupcr->host_assert_info.reason) || -+ (39 == g_stp_dbg_cpupcr->host_assert_info.reason) || -+ (40 == g_stp_dbg_cpupcr->host_assert_info.reason)) -+ g_stp_dbg_cpupcr->fwTaskId = 6; /* HOST schedule reason trigger */ -+ else -+ g_stp_dbg_cpupcr->fwTaskId = 0; /* Must be firmware reason */ -+ g_stp_dbg_cpupcr->host_assert_info.assert_from_host = 0; -+ osal_unlock_sleepable_lock(&g_stp_dbg_cpupcr->lock); -+ break; -+ default: -+ break; -+ } -+ -+ } -+ osal_free(tempbuf); -+ } else if (STP_FW_NOACK_ISSUE == issue_type) { -+ osal_lock_sleepable_lock(&g_stp_dbg_cpupcr->lock); -+ osal_memcpy(&g_stp_dbg_cpupcr->assert_info[0], issue_info, len); -+ g_stp_dbg_cpupcr->fwTaskId = 6; -+ g_stp_dbg_cpupcr->fwRrq = 0; -+ g_stp_dbg_cpupcr->fwIsr = 0; -+ osal_unlock_sleepable_lock(&g_stp_dbg_cpupcr->lock); -+ } else if (STP_DBG_PROC_TEST == issue_type) { -+ osal_lock_sleepable_lock(&g_stp_dbg_cpupcr->lock); -+ osal_memcpy(&g_stp_dbg_cpupcr->assert_info[0], issue_info, len); -+ g_stp_dbg_cpupcr->fwTaskId = 0; -+ g_stp_dbg_cpupcr->fwRrq = 0; -+ g_stp_dbg_cpupcr->fwIsr = 0; -+ osal_unlock_sleepable_lock(&g_stp_dbg_cpupcr->lock); -+ } else if (STP_FW_WARM_RST_ISSUE == issue_type) { -+ osal_lock_sleepable_lock(&g_stp_dbg_cpupcr->lock); -+ osal_memcpy(&g_stp_dbg_cpupcr->assert_info[0], issue_info, len); -+ g_stp_dbg_cpupcr->fwTaskId = 0; -+ g_stp_dbg_cpupcr->fwRrq = 0; -+ g_stp_dbg_cpupcr->fwIsr = 0; -+ osal_unlock_sleepable_lock(&g_stp_dbg_cpupcr->lock); -+ } else { -+ STP_DBG_ERR_FUNC("invalid issue type(%d)\n", issue_type); -+ return -3; -+ } -+ -+ return iRet; -+} -+ -+INT32 stp_dbg_cpupcr_infor_format(PPUINT8 buf, PUINT32 str_len) -+{ -+ UINT32 len = 0; -+ UINT32 i = 0; -+ -+ if (!g_stp_dbg_cpupcr) { -+ STP_DBG_ERR_FUNC("NULL pointer\n"); -+ return -1; -+ } -+ -+ /*format common information about issue */ -+ len = osal_sprintf(*buf, "
\n\t"); -+ len += osal_sprintf(*buf + len, "\n\t\tMT%x\n\t\n\t", g_stp_dbg_cpupcr->chipId); -+ len += osal_sprintf(*buf + len, "\n\t\t"); -+ len += osal_sprintf(*buf + len, "%s\n\t\t", g_stp_dbg_cpupcr->romVer); -+ if (!(osal_memcmp(g_stp_dbg_cpupcr->branchVer, "ALPS", strlen("ALPS")))) -+ len += osal_sprintf(*buf + len, "Internal Dev\n\t\t", g_stp_dbg_cpupcr->branchVer); -+ else -+ len += osal_sprintf(*buf + len, "W%sMP\n\t\t", g_stp_dbg_cpupcr->branchVer); -+ -+ len += osal_sprintf(*buf + len, "%s\n\t\t", g_stp_dbg_cpupcr->patchVer); -+ -+ if (0 == g_stp_dbg_cpupcr->wifiVer) -+ len += osal_sprintf(*buf + len, "NULL\n\t"); -+ else -+ len += osal_sprintf(*buf + len, "0x%X.%X\n\t", -+ (UINT8)((g_stp_dbg_cpupcr->wifiVer & 0xFF00)>>8), (UINT8)(g_stp_dbg_cpupcr->wifiVer & 0xFF)); -+ -+ len += osal_sprintf(*buf + len, "\n\t"); -+ -+ /*format issue information: no ack, assert */ -+ len += osal_sprintf(*buf + len, "\n\t\t\n\t\t\t"); -+ if ((STP_FW_NOACK_ISSUE == g_stp_dbg_cpupcr->issue_type) || -+ (STP_DBG_PROC_TEST == g_stp_dbg_cpupcr->issue_type) || -+ (STP_FW_WARM_RST_ISSUE == g_stp_dbg_cpupcr->issue_type)) { -+ len += -+ osal_sprintf(*buf + len, "%s\n\t\t\n\t\t\n\t\t\t", -+ g_stp_dbg_cpupcr->assert_info); -+ len += osal_sprintf(*buf + len, "NULL\n\t\t\n\t\n\t"); -+ len += osal_sprintf(*buf + len, "\n\t\tNULL\n\t\t"); -+ len += osal_sprintf(*buf + len, "NULL\n\t\t"); -+ len += -+ osal_sprintf(*buf + len, "\n\t\t\t%s\n\t\t\t", -+ _stp_dbg_id_to_task(g_stp_dbg_cpupcr->fwTaskId)); -+ len += osal_sprintf(*buf + len, "IRQ_0x%x\n\t\t\t", g_stp_dbg_cpupcr->fwRrq); -+ len += osal_sprintf(*buf + len, "0x%x\n\t\t\t", g_stp_dbg_cpupcr->fwIsr); -+ len += osal_sprintf(*buf + len, "NULL\n\t\t\t"); -+ len += osal_sprintf(*buf + len, "NULL\n\t\t\t"); -+ } else if ((STP_FW_ASSERT_ISSUE == g_stp_dbg_cpupcr->issue_type) || -+ (STP_HOST_TRIGGER_FW_ASSERT == g_stp_dbg_cpupcr->issue_type) || -+ (STP_HOST_TRIGGER_ASSERT_TIMEOUT == g_stp_dbg_cpupcr->issue_type)) { -+ len += -+ osal_sprintf(*buf + len, "%s\n\t\t\n\t\t\n\t\t\t", -+ g_stp_dbg_cpupcr->assert_info); -+ len += osal_sprintf(*buf + len, "%s\n\t\t\n\t\n\t", g_stp_dbg_cpupcr->assert_type); -+ len += osal_sprintf(*buf + len, "\n\t\tNULL\n\t\t"); -+ len += osal_sprintf(*buf + len, "NULL\n\t\t"); -+ len += -+ osal_sprintf(*buf + len, "\n\t\t\t%s\n\t\t\t", -+ _stp_dbg_id_to_task(g_stp_dbg_cpupcr->fwTaskId)); -+ if (32 == g_stp_dbg_cpupcr->host_assert_info.reason || 33 == g_stp_dbg_cpupcr->host_assert_info.reason -+ || 34 == g_stp_dbg_cpupcr->host_assert_info.reason -+ || 35 == g_stp_dbg_cpupcr->host_assert_info.reason -+ || 36 == g_stp_dbg_cpupcr->host_assert_info.reason -+ || 37 == g_stp_dbg_cpupcr->host_assert_info.reason -+ || 38 == g_stp_dbg_cpupcr->host_assert_info.reason -+ || 39 == g_stp_dbg_cpupcr->host_assert_info.reason -+ || 40 == g_stp_dbg_cpupcr->host_assert_info.reason) { -+ /*handling wmt turn on/off bt cmd has ack but no evt issue */ -+ /*one of both the irqx and irs is nULL, then use task to find MOF */ -+ len += osal_sprintf(*buf + len, "NULL\n\t\t\t"); -+ } else { -+ len += osal_sprintf(*buf + len, "IRQ_0x%x\n\t\t\t", g_stp_dbg_cpupcr->fwRrq); -+ } -+ len += osal_sprintf(*buf + len, "0x%x\n\t\t\t", g_stp_dbg_cpupcr->fwIsr); -+ -+ if (STP_FW_ASSERT_ISSUE == g_stp_dbg_cpupcr->issue_type) { -+ len += osal_sprintf(*buf + len, "NULL\n\t\t\t"); -+ len += osal_sprintf(*buf + len, "NULL\n\t\t\t"); -+ } -+ -+ if ((STP_HOST_TRIGGER_FW_ASSERT == g_stp_dbg_cpupcr->issue_type) || -+ (STP_HOST_TRIGGER_ASSERT_TIMEOUT == g_stp_dbg_cpupcr->issue_type)) { -+ len += -+ osal_sprintf(*buf + len, "%d\n\t\t\t", -+ g_stp_dbg_cpupcr->host_assert_info.drv_type); -+ len += -+ osal_sprintf(*buf + len, "%d\n\t\t\t", -+ g_stp_dbg_cpupcr->host_assert_info.reason); -+ } -+ } else { -+ len += osal_sprintf(*buf + len, "NULL\n\t\t\n\t\t\n\t\t\t"); -+ len += osal_sprintf(*buf + len, "NULL\n\t\t\n\t\n\t"); -+ len += osal_sprintf(*buf + len, "\n\t\tNULL\n\t\t"); -+ len += osal_sprintf(*buf + len, "NULL\n\t\t"); -+ len += osal_sprintf(*buf + len, "\n\t\t\tNULL\n\t\t\t"); -+ len += osal_sprintf(*buf + len, "NULL\n\t\t\t"); -+ len += osal_sprintf(*buf + len, "NULL\n\t\t\t"); -+ len += osal_sprintf(*buf + len, "NULL\n\t\t\t"); -+ len += osal_sprintf(*buf + len, "NULL\n\t\t\t"); -+ } -+ -+ len += osal_sprintf(*buf + len, ""); -+ STP_DBG_INFO_FUNC("stp-dbg:sub len1 for debug(%d)\n", len); -+ -+ if (!g_stp_dbg_cpupcr->count) -+ len += osal_sprintf(*buf + len, "NULL"); -+ else { -+ for (i = 0; i < g_stp_dbg_cpupcr->count; i++) -+ len += osal_sprintf(*buf + len, "%08x,", g_stp_dbg_cpupcr->buffer[i]); -+ } -+ STP_DBG_INFO_FUNC("stp-dbg:sub len2 for debug(%d)\n", len); -+ len += osal_sprintf(*buf + len, "\n\t\t\t"); -+ len += osal_sprintf(*buf + len, "NULL\n\t\t\n\t\n
\n"); -+ STP_DBG_INFO_FUNC("buffer len[%d]\n", len); -+ /* STP_DBG_INFO_FUNC("Format infor:\n%s\n",*buf); */ -+ *str_len = len; -+ -+ osal_lock_sleepable_lock(&g_stp_dbg_cpupcr->lock); -+ osal_memset(&g_stp_dbg_cpupcr->buffer[0], 0, STP_DBG_CPUPCR_NUM); -+ g_stp_dbg_cpupcr->count = 0; -+ g_stp_dbg_cpupcr->host_assert_info.reason = 0; -+ g_stp_dbg_cpupcr->host_assert_info.drv_type = 0; -+ osal_unlock_sleepable_lock(&g_stp_dbg_cpupcr->lock); -+ -+ return 0; -+ -+} -+ -+MTKSTP_DBG_T *stp_dbg_init(void *btm_half) -+{ -+ -+ MTKSTP_DBG_T *stp_dbg = NULL; -+ -+ STP_DBG_INFO_FUNC("stp-dbg init\n"); -+ -+ stp_dbg = kzalloc(sizeof(MTKSTP_DBG_T), GFP_KERNEL); -+ if (stp_dbg == NULL) -+ goto ERR_EXIT1; -+ if (IS_ERR(stp_dbg)) { -+ STP_DBG_ERR_FUNC("-ENOMEM\n"); -+ goto ERR_EXIT1; -+ } -+ -+ stp_dbg->logsys = vmalloc(sizeof(MTKSTP_LOG_SYS_T)); -+ if (stp_dbg->logsys == NULL) -+ goto ERR_EXIT2; -+ if (IS_ERR(stp_dbg->logsys)) { -+ STP_DBG_ERR_FUNC("-ENOMEM stp_gdb->logsys\n"); -+ goto ERR_EXIT2; -+ } -+ memset(stp_dbg->logsys, 0, sizeof(MTKSTP_LOG_SYS_T)); -+ spin_lock_init(&(stp_dbg->logsys->lock)); -+ stp_dbg->pkt_trace_no = 0; -+ stp_dbg->is_enable = 0; -+ g_stp_dbg = stp_dbg; -+ -+ if (btm_half != NULL) -+ stp_dbg->btm = btm_half; -+ else -+ stp_dbg->btm = NULL; -+ -+ -+ /* bind to netlink */ -+ stp_dbg_nl_init(); -+ g_core_dump = wcn_core_dump_init(STP_CORE_DUMP_INIT_SIZE, STP_CORE_DUMP_TIMEOUT); -+ g_stp_dbg_cpupcr = stp_dbg_cpupcr_init(); -+ g_stp_dbg_dmaregs = stp_dbg_dmaregs_init(); -+ -+ return stp_dbg; -+ -+ERR_EXIT2: -+ kfree(stp_dbg); -+ return NULL; -+ -+ERR_EXIT1: -+ kfree(stp_dbg); -+ return NULL; -+} -+ -+int stp_dbg_deinit(MTKSTP_DBG_T *stp_dbg) -+{ -+ -+ STP_DBG_INFO_FUNC("stp-dbg deinit\n"); -+ -+ wcn_core_dump_deinit(g_core_dump); -+ -+ stp_dbg_cpupcr_deinit(g_stp_dbg_cpupcr); -+ stp_dbg_dmaregs_deinit(g_stp_dbg_dmaregs); -+ /* unbind with netlink */ -+ stp_dbg_nl_deinit(); -+ -+ if (stp_dbg->logsys) -+ vfree(stp_dbg->logsys); -+ -+ kfree(stp_dbg); -+ -+ return 0; -+} -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/stp_exp.c b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/stp_exp.c -new file mode 100644 -index 000000000000..f7f4aff010d4 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/stp_exp.c -@@ -0,0 +1,279 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include /* udelay() */ -+ -+#include -+ -+ -+#include "osal_typedef.h" -+#include "stp_core.h" -+#include "stp_exp.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+static MTK_WCN_STP_IF_TX stp_uart_if_tx; -+static MTK_WCN_STP_IF_TX stp_sdio_if_tx; -+static MTK_WCN_STP_IF_TX stp_btif_if_tx; -+static ENUM_STP_TX_IF_TYPE g_stp_if_type = STP_MAX_IF_TX; -+static MTK_WCN_STP_IF_RX stp_if_rx; -+static MTK_WCN_STP_EVENT_CB event_callback_tbl[MTKSTP_MAX_TASK_NUM] = { 0x0 }; -+static MTK_WCN_STP_EVENT_CB tx_event_callback_tbl[MTKSTP_MAX_TASK_NUM] = { 0x0 }; -+ -+/****************************************************************************** -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************* -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+INT32 mtk_wcn_sys_if_rx(UINT8 *data, INT32 size) -+{ -+ if (stp_if_rx == 0x0) -+ return -1; -+ -+ (*stp_if_rx) (data, size); -+ return 0; -+} -+ -+static INT32 mtk_wcn_sys_if_tx(const PUINT8 data, const UINT32 size, PUINT32 written_size) -+{ -+ -+ if (STP_UART_IF_TX == g_stp_if_type) -+ return stp_uart_if_tx != NULL ? (*stp_uart_if_tx) (data, size, written_size) : -1; -+ else if (STP_SDIO_IF_TX == g_stp_if_type) -+ return stp_sdio_if_tx != NULL ? (*stp_sdio_if_tx) (data, size, written_size) : -1; -+ else if (STP_BTIF_IF_TX == g_stp_if_type) -+ return stp_btif_if_tx != NULL ? (*stp_btif_if_tx) (data, size, written_size) : -1; -+ /*if (g_stp_if_type >= STP_MAX_IF_TX) *//* George: remove ALWAYS TRUE condition */ -+ return -1; -+} -+ -+static INT32 mtk_wcn_sys_event_set(UINT8 function_type) -+{ -+ if ((function_type < MTKSTP_MAX_TASK_NUM) && (event_callback_tbl[function_type] != 0x0)) { -+ (*event_callback_tbl[function_type]) (); -+ } else { -+ /* FIXME: error handling */ -+ pr_err("[%s] STP set event fail. It seems the function is not active.\n", __func__); -+ } -+ -+ return 0; -+} -+ -+static INT32 mtk_wcn_sys_event_tx_resume(UINT8 winspace) -+{ -+ int type = 0; -+ -+ for (type = 0; type < MTKSTP_MAX_TASK_NUM; type++) { -+ if (tx_event_callback_tbl[type]) -+ tx_event_callback_tbl[type] (); -+ } -+ -+ return 0; -+} -+ -+static INT32 mtk_wcn_sys_check_function_status(UINT8 type, UINT8 op) -+{ -+ -+ /* op == FUNCTION_ACTIVE, to check if funciton[type] is active ? */ -+ if (!(type < MTKSTP_MAX_TASK_NUM)) -+ return STATUS_FUNCTION_INVALID; -+ -+ if (op == OP_FUNCTION_ACTIVE) { -+ if (event_callback_tbl[type] != 0x0) -+ return STATUS_FUNCTION_ACTIVE; -+ else -+ return STATUS_FUNCTION_INACTIVE; -+ -+ } -+ /* you can define more operation here ..., to queury function's status/information */ -+ -+ return STATUS_OP_INVALID; -+} -+ -+#if STP_EXP_HID_API_EXPORT -+INT32 _mtk_wcn_stp_register_if_rx(MTK_WCN_STP_IF_RX func) -+#else -+INT32 mtk_wcn_stp_register_if_rx(MTK_WCN_STP_IF_RX func) -+#endif -+{ -+ stp_if_rx = func; -+ -+ return 0; -+} -+#if !STP_EXP_HID_API_EXPORT -+EXPORT_SYMBOL(mtk_wcn_stp_register_if_rx); -+#endif -+ -+VOID mtk_wcn_stp_set_if_tx_type(ENUM_STP_TX_IF_TYPE stp_if_type) -+{ -+ static const char * const ifType[] = { -+ "UART", -+ "SDIO", -+ "BTIF", -+ "UNKNOWN" -+ }; -+ g_stp_if_type = stp_if_type; -+ pr_debug("[%s] set STP_IF_TX to %s.\n", __func__, ifType[stp_if_type]); -+} -+ -+#if STP_EXP_HID_API_EXPORT -+INT32 _mtk_wcn_stp_register_if_tx(ENUM_STP_TX_IF_TYPE stp_if, MTK_WCN_STP_IF_TX func) -+#else -+INT32 mtk_wcn_stp_register_if_tx(ENUM_STP_TX_IF_TYPE stp_if, MTK_WCN_STP_IF_TX func) -+#endif -+{ -+ if (STP_UART_IF_TX == stp_if) { -+ stp_uart_if_tx = func; -+ } else if (STP_SDIO_IF_TX == stp_if) { -+ stp_sdio_if_tx = func; -+ } else if (STP_BTIF_IF_TX == stp_if) { -+ stp_btif_if_tx = func; -+ } else { -+ pr_debug("[%s] STP_IF_TX(%d) out of boundary.\n", __func__, stp_if); -+ return -1; -+ } -+ -+ return 0; -+} -+#if !STP_EXP_HID_API_EXPORT -+EXPORT_SYMBOL(mtk_wcn_stp_register_if_tx); -+#endif -+ -+#if STP_EXP_HID_API_EXPORT -+INT32 _mtk_wcn_stp_register_event_cb(INT32 type, MTK_WCN_STP_EVENT_CB func) -+#else -+INT32 mtk_wcn_stp_register_event_cb(INT32 type, MTK_WCN_STP_EVENT_CB func) -+#endif -+{ -+ if (type < MTKSTP_MAX_TASK_NUM) { -+ event_callback_tbl[type] = func; -+ -+ /*clear rx queue */ -+ pr_debug("Flush type = %d Rx Queue\n", type); -+ mtk_wcn_stp_flush_rx_queue(type); -+ } -+ -+ return 0; -+} -+#if !STP_EXP_HID_API_EXPORT -+EXPORT_SYMBOL(mtk_wcn_stp_register_event_cb); -+#endif -+ -+#if STP_EXP_HID_API_EXPORT -+INT32 _mtk_wcn_stp_register_tx_event_cb(INT32 type, MTK_WCN_STP_EVENT_CB func) -+#else -+INT32 mtk_wcn_stp_register_tx_event_cb(INT32 type, MTK_WCN_STP_EVENT_CB func) -+#endif -+{ -+ if (type < MTKSTP_MAX_TASK_NUM) -+ tx_event_callback_tbl[type] = func; -+ else -+ BUG_ON(0); -+ -+ return 0; -+} -+#if !STP_EXP_HID_API_EXPORT -+EXPORT_SYMBOL(mtk_wcn_stp_register_tx_event_cb); -+#endif -+ -+INT32 stp_drv_init(VOID) -+{ -+ INT32 ret = 0; -+ -+ mtkstp_callback cb = { -+ .cb_if_tx = mtk_wcn_sys_if_tx, -+ .cb_event_set = mtk_wcn_sys_event_set, -+ .cb_event_tx_resume = mtk_wcn_sys_event_tx_resume, -+ .cb_check_funciton_status = mtk_wcn_sys_check_function_status -+ }; -+ -+#ifdef MTK_WCN_WMT_STP_EXP_SYMBOL_ABSTRACT -+ MTK_WCN_STP_EXP_CB_INFO stpExpCb = { -+ .stp_send_data_cb = _mtk_wcn_stp_send_data, -+ .stp_send_data_raw_cb = _mtk_wcn_stp_send_data_raw, -+ .stp_parser_data_cb = _mtk_wcn_stp_parser_data, -+ .stp_receive_data_cb = _mtk_wcn_stp_receive_data, -+ .stp_is_rxqueue_empty_cb = _mtk_wcn_stp_is_rxqueue_empty, -+ .stp_is_ready_cb = _mtk_wcn_stp_is_ready, -+ .stp_set_bluez_cb = _mtk_wcn_stp_set_bluez, -+ .stp_if_tx_cb = _mtk_wcn_stp_register_if_tx, -+ .stp_if_rx_cb = _mtk_wcn_stp_register_if_rx, -+ .stp_reg_event_cb = _mtk_wcn_stp_register_event_cb, -+ .stp_reg_tx_event_cb = _mtk_wcn_stp_register_tx_event_cb, -+ .stp_coredump_start_get_cb = _mtk_wcn_stp_coredump_start_get, -+ }; -+#endif -+ -+ ret = mtk_wcn_stp_init(&cb); -+#ifdef MTK_WCN_WMT_STP_EXP_SYMBOL_ABSTRACT -+ mtk_wcn_stp_exp_cb_reg(&stpExpCb); -+#endif -+ return ret; -+} -+ -+VOID stp_drv_exit(VOID) -+{ -+ mtk_wcn_stp_deinit(); -+ -+#ifdef MTK_WCN_WMT_STP_EXP_SYMBOL_ABSTRACT -+ mtk_wcn_stp_exp_cb_unreg(); -+#endif -+ -+} -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/wmt_dev.c b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/wmt_dev.c -new file mode 100644 -index 000000000000..f70c88796f09 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/wmt_dev.c -@@ -0,0 +1,2566 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -+ -+/*! \file -+ \brief brief description -+ -+ Detailed descriptions here. -+ -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+#ifdef DFT_TAG -+#undef DFT_TAG -+#endif -+#define DFT_TAG "[WMT-DEV]" -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+#include "osal_typedef.h" -+#include "osal.h" -+#include "wmt_dev.h" -+#include "wmt_core.h" -+#include "wmt_exp.h" -+#include "wmt_lib.h" -+#include "wmt_conf.h" -+#include "psm_core.h" -+#include "stp_core.h" -+#include "stp_exp.h" -+#include "bgw_desense.h" -+#include -+#include "wmt_idc.h" -+#ifdef CONFIG_COMPAT -+#include -+#endif -+#if WMT_CREATE_NODE_DYNAMIC -+#include -+#endif -+#define BUF_LEN_MAX 384 -+#include -+#ifdef CONFIG_COMPAT -+#define COMPAT_WMT_IOCTL_SET_PATCH_NAME _IOW(WMT_IOC_MAGIC, 4, compat_uptr_t) -+#define COMPAT_WMT_IOCTL_LPBK_TEST _IOWR(WMT_IOC_MAGIC, 8, compat_uptr_t) -+#define COMPAT_WMT_IOCTL_SET_PATCH_INFO _IOW(WMT_IOC_MAGIC, 15, compat_uptr_t) -+#define COMPAT_WMT_IOCTL_PORT_NAME _IOWR(WMT_IOC_MAGIC, 20, compat_uptr_t) -+#define COMPAT_WMT_IOCTL_WMT_CFG_NAME _IOWR(WMT_IOC_MAGIC, 21, compat_uptr_t) -+#define COMPAT_WMT_IOCTL_SEND_BGW_DS_CMD _IOW(WMT_IOC_MAGIC, 25, compat_uptr_t) -+#define COMPAT_WMT_IOCTL_ADIE_LPBK_TEST _IOWR(WMT_IOC_MAGIC, 26, compat_uptr_t) -+#endif -+ -+#define WMT_IOC_MAGIC 0xa0 -+#define WMT_IOCTL_SET_PATCH_NAME _IOW(WMT_IOC_MAGIC, 4, char*) -+#define WMT_IOCTL_SET_STP_MODE _IOW(WMT_IOC_MAGIC, 5, int) -+#define WMT_IOCTL_FUNC_ONOFF_CTRL _IOW(WMT_IOC_MAGIC, 6, int) -+#define WMT_IOCTL_LPBK_POWER_CTRL _IOW(WMT_IOC_MAGIC, 7, int) -+#define WMT_IOCTL_LPBK_TEST _IOWR(WMT_IOC_MAGIC, 8, char*) -+#define WMT_IOCTL_GET_CHIP_INFO _IOR(WMT_IOC_MAGIC, 12, int) -+#define WMT_IOCTL_SET_LAUNCHER_KILL _IOW(WMT_IOC_MAGIC, 13, int) -+#define WMT_IOCTL_SET_PATCH_NUM _IOW(WMT_IOC_MAGIC, 14, int) -+#define WMT_IOCTL_SET_PATCH_INFO _IOW(WMT_IOC_MAGIC, 15, char*) -+#define WMT_IOCTL_PORT_NAME _IOWR(WMT_IOC_MAGIC, 20, char*) -+#define WMT_IOCTL_WMT_CFG_NAME _IOWR(WMT_IOC_MAGIC, 21, char*) -+#define WMT_IOCTL_WMT_QUERY_CHIPID _IOR(WMT_IOC_MAGIC, 22, int) -+#define WMT_IOCTL_WMT_TELL_CHIPID _IOW(WMT_IOC_MAGIC, 23, int) -+#define WMT_IOCTL_WMT_COREDUMP_CTRL _IOW(WMT_IOC_MAGIC, 24, int) -+#define WMT_IOCTL_SEND_BGW_DS_CMD _IOW(WMT_IOC_MAGIC, 25, char*) -+#define WMT_IOCTL_ADIE_LPBK_TEST _IOWR(WMT_IOC_MAGIC, 26, char*) -+#define WMT_IOCTL_FW_DBGLOG_CTRL _IOR(WMT_IOC_MAGIC, 29, int) -+#define WMT_IOCTL_DYNAMIC_DUMP_CTRL _IOR(WMT_IOC_MAGIC, 30, char*) -+ -+#define MTK_WMT_VERSION "SOC Consys WMT Driver - v1.0" -+#define MTK_WMT_DATE "2013/01/20" -+#define WMT_DEV_MAJOR 190 /* never used number */ -+#define WMT_DEV_NUM 1 -+#define WMT_DEV_INIT_TO_MS (2 * 1000) -+#define DYNAMIC_DUMP_BUF 109 -+ -+#if CFG_WMT_DBG_SUPPORT -+#define WMT_DBG_PROCNAME "driver/wmt_dbg" -+#endif -+ -+#define WMT_DRIVER_NAME "mtk_stp_wmt" -+ -+P_OSAL_EVENT gpRxEvent = NULL; -+ -+UINT32 u4RxFlag = 0x0; -+static atomic_t gRxCount = ATOMIC_INIT(0); -+ -+/* Linux UINT8 device */ -+static int gWmtMajor = WMT_DEV_MAJOR; -+static struct cdev gWmtCdev; -+static atomic_t gWmtRefCnt = ATOMIC_INIT(0); -+/* WMT driver information */ -+static UINT8 gLpbkBuf[1024+5] = { 0 }; -+ -+static UINT32 gLpbkBufLog; /* George LPBK debug */ -+static INT32 gWmtInitDone; -+static wait_queue_head_t gWmtInitWq; -+ -+P_WMT_PATCH_INFO pPatchInfo = NULL; -+UINT32 pAtchNum = 0; -+ -+#if (defined(CONFIG_MTK_GMO_RAM_OPTIMIZE) && !defined(CONFIG_MT_ENG_BUILD)) -+#define WMT_EMI_DEBUG_BUF_SIZE (8*1024) -+#else -+#define WMT_EMI_DEBUG_BUF_SIZE (32*1024) -+#endif -+ -+static UINT8 gEmiBuf[WMT_EMI_DEBUG_BUF_SIZE]; -+UINT8 *buf_emi; -+ -+#if CFG_WMT_PROC_FOR_AEE -+static struct proc_dir_entry *gWmtAeeEntry; -+#define WMT_AEE_PROCNAME "driver/wmt_aee" -+#define WMT_PROC_AEE_SIZE 3072 -+static UINT32 g_buf_len; -+static UINT8 *pBuf; -+#endif -+ -+#if WMT_CREATE_NODE_DYNAMIC -+struct class *wmt_class = NULL; -+struct device *wmt_dev = NULL; -+#endif -+ -+#if CFG_WMT_DBG_SUPPORT -+static struct proc_dir_entry *gWmtDbgEntry; -+COEX_BUF gCoexBuf; -+ -+static INT32 wmt_dbg_psm_ctrl(INT32 par1, INT32 par2, INT32 par3); -+static INT32 wmt_dbg_quick_sleep_ctrl(INT32 par1, INT32 par2, INT32 par3); -+static INT32 wmt_dbg_dsns_ctrl(INT32 par1, INT32 par2, INT32 par3); -+static INT32 wmt_dbg_hwver_get(INT32 par1, INT32 par2, INT32 par3); -+static INT32 wmt_dbg_inband_rst(INT32 par1, INT32 par2, INT32 par3); -+static INT32 wmt_dbg_chip_rst(INT32 par1, INT32 par2, INT32 par3); -+static INT32 wmt_dbg_func_ctrl(INT32 par1, INT32 par2, INT32 par3); -+static INT32 wmt_dbg_raed_chipid(INT32 par1, INT32 par2, INT32 par3); -+static INT32 wmt_dbg_wmt_dbg_level(INT32 par1, INT32 par2, INT32 par3); -+static INT32 wmt_dbg_stp_dbg_level(INT32 par1, INT32 par2, INT32 par3); -+static INT32 wmt_dbg_reg_read(INT32 par1, INT32 par2, INT32 par3); -+static INT32 wmt_dbg_reg_write(INT32 par1, INT32 par2, INT32 par3); -+static INT32 wmt_dbg_coex_test(INT32 par1, INT32 par2, INT32 par3); -+static INT32 wmt_dbg_assert_test(INT32 par1, INT32 par2, INT32 par3); -+static INT32 wmt_dbg_cmd_test_api(ENUM_WMTDRV_CMD_T cmd); -+static INT32 wmt_dbg_rst_ctrl(INT32 par1, INT32 par2, INT32 par3); -+static INT32 wmt_dbg_ut_test(INT32 par1, INT32 par2, INT32 par3); -+static INT32 wmt_dbg_efuse_read(INT32 par1, INT32 par2, INT32 par3); -+static INT32 wmt_dbg_efuse_write(INT32 par1, INT32 par2, INT32 par3); -+static INT32 wmt_dbg_sdio_ctrl(INT32 par1, INT32 par2, INT32 par3); -+static INT32 wmt_dbg_stp_dbg_ctrl(INT32 par1, INT32 par2, INT32 par3); -+static INT32 wmt_dbg_stp_dbg_log_ctrl(INT32 par1, INT32 par2, INT32 par3); -+static INT32 wmt_dbg_wmt_assert_ctrl(INT32 par1, INT32 par2, INT32 par3); -+ -+#if CFG_CORE_INTERNAL_TXRX -+static INT32 wmt_dbg_internal_lpbk_test(INT32 par1, INT32 par2, INT32 par3); -+#endif -+static INT32 wmt_dbg_fwinfor_from_emi(INT32 par1, INT32 par2, INT32 par3); -+static INT32 wmt_dbg_set_mcu_clock(INT32 par1, INT32 par2, INT32 par3); -+static INT32 wmt_dbg_poll_cpupcr(INT32 par1, INT32 par2, INT32 par3); -+#if CONSYS_ENALBE_SET_JTAG -+static INT32 wmt_dbg_jtag_flag_ctrl(INT32 par1, INT32 par2, INT32 par3); -+#endif -+#if CFG_WMT_LTE_COEX_HANDLING -+static INT32 wmt_dbg_lte_coex_test(INT32 par1, INT32 par2, INT32 par3); -+#endif -+#endif -+static void wmt_dbg_fwinfor_print_buff(UINT32 len) -+{ -+ UINT32 i = 0; -+ UINT32 idx = 0; -+ -+ for (i = 0; i < len; i++) { -+ buf_emi[idx] = gEmiBuf[i]; -+ if (gEmiBuf[i] == '\n') { -+ pr_cont("%s", buf_emi); -+ osal_memset(buf_emi, 0, BUF_LEN_MAX); -+ idx = 0; -+ } else { -+ idx++; -+ } -+ if (idx == BUF_LEN_MAX-1) { -+ buf_emi[idx] = '\0'; -+ pr_cont("%s", buf_emi); -+ osal_memset(buf_emi, 0, BUF_LEN_MAX); -+ idx = 0; -+ } -+ } -+} -+ -+/*LCM on/off ctrl for wmt varabile*/ -+static struct work_struct gPwrOnOffWork; -+UINT32 g_es_lr_flag_for_quick_sleep = 1; /* for ctrl quick sleep flag */ -+UINT32 g_es_lr_flag_for_lpbk_onoff = 0; /* for ctrl lpbk on off */ -+OSAL_SLEEPABLE_LOCK g_es_lr_lock; -+ -+#ifdef CONFIG_EARLYSUSPEND -+ -+static void wmt_dev_early_suspend(struct early_suspend *h) -+{ -+ osal_lock_sleepable_lock(&g_es_lr_lock); -+ g_es_lr_flag_for_quick_sleep = 1; -+ g_es_lr_flag_for_lpbk_onoff = 0; -+ osal_unlock_sleepable_lock(&g_es_lr_lock); -+ -+ WMT_WARN_FUNC("@@@@@@@@@@wmt enter early suspend@@@@@@@@@@@@@@\n"); -+ -+ schedule_work(&gPwrOnOffWork); -+} -+ -+static void wmt_dev_late_resume(struct early_suspend *h) -+{ -+ osal_lock_sleepable_lock(&g_es_lr_lock); -+ g_es_lr_flag_for_quick_sleep = 0; -+ g_es_lr_flag_for_lpbk_onoff = 1; -+ osal_unlock_sleepable_lock(&g_es_lr_lock); -+ -+ WMT_WARN_FUNC("@@@@@@@@@@wmt enter late resume@@@@@@@@@@@@@@\n"); -+ -+ schedule_work(&gPwrOnOffWork); -+ -+} -+ -+struct early_suspend wmt_early_suspend_handler = { -+ .suspend = wmt_dev_early_suspend, -+ .resume = wmt_dev_late_resume, -+}; -+ -+#else -+ -+static struct notifier_block wmt_fb_notifier; -+static int wmt_fb_notifier_callback(struct notifier_block *self, unsigned long event, void *data) -+{ -+ struct fb_event *evdata = data; -+ INT32 blank; -+ -+ WMT_DBG_FUNC("wmt_fb_notifier_callback\n"); -+ -+ /* If we aren't interested in this event, skip it immediately ... */ -+ if (event != FB_EVENT_BLANK) -+ return 0; -+ -+ blank = *(INT32 *)evdata->data; -+ WMT_DBG_FUNC("fb_notify(blank=%d)\n", blank); -+ -+ switch (blank) { -+ case FB_BLANK_UNBLANK: -+ osal_lock_sleepable_lock(&g_es_lr_lock); -+ g_es_lr_flag_for_quick_sleep = 0; -+ g_es_lr_flag_for_lpbk_onoff = 1; -+ osal_unlock_sleepable_lock(&g_es_lr_lock); -+ WMT_WARN_FUNC("@@@@@@@@@@wmt enter UNBLANK @@@@@@@@@@@@@@\n"); -+ schedule_work(&gPwrOnOffWork); -+ break; -+ case FB_BLANK_POWERDOWN: -+ osal_lock_sleepable_lock(&g_es_lr_lock); -+ g_es_lr_flag_for_quick_sleep = 1; -+ g_es_lr_flag_for_lpbk_onoff = 0; -+ osal_unlock_sleepable_lock(&g_es_lr_lock); -+ WMT_WARN_FUNC("@@@@@@@@@@wmt enter early POWERDOWN @@@@@@@@@@@@@@\n"); -+ schedule_work(&gPwrOnOffWork); -+ break; -+ default: -+ break; -+ } -+ return 0; -+} -+#endif -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+static void wmt_pwr_on_off_handler(struct work_struct *work) -+{ -+ INT32 retryCounter = 1; -+ -+ WMT_DBG_FUNC("wmt_pwr_on_off_handler start to run\n"); -+ -+ osal_lock_sleepable_lock(&g_es_lr_lock); -+ -+ if (g_es_lr_flag_for_lpbk_onoff) { -+ do { -+ if (MTK_WCN_BOOL_FALSE == mtk_wcn_wmt_func_on(WMTDRV_TYPE_LPBK)) { -+ WMT_WARN_FUNC("WMT turn on LPBK fail, retrying, retryCounter left:%d!\n", retryCounter); -+ retryCounter--; -+ osal_sleep_ms(1000); -+ } else { -+ WMT_INFO_FUNC("WMT turn on LPBK suceed\n"); -+ break; -+ } -+ } while (retryCounter > 0); -+ } else { -+ if (MTK_WCN_BOOL_FALSE == mtk_wcn_wmt_func_off(WMTDRV_TYPE_LPBK)) -+ WMT_WARN_FUNC("WMT turn off LPBK fail\n"); -+ else -+ WMT_DBG_FUNC("WMT turn off LPBK suceed\n"); -+ -+ } -+ -+ osal_unlock_sleepable_lock(&g_es_lr_lock); -+ -+} -+ -+ -+MTK_WCN_BOOL wmt_dev_get_early_suspend_state(void) -+{ -+ MTK_WCN_BOOL bRet = (0 == g_es_lr_flag_for_quick_sleep) ? MTK_WCN_BOOL_FALSE : MTK_WCN_BOOL_TRUE; -+ /* WMT_INFO_FUNC("bRet:%d\n", bRet); */ -+ return bRet; -+} -+ -+#if CFG_WMT_DBG_SUPPORT -+ -+static const WMT_DEV_DBG_FUNC wmt_dev_dbg_func[] = { -+ [0] = wmt_dbg_psm_ctrl, -+ [1] = wmt_dbg_quick_sleep_ctrl, -+ [2] = wmt_dbg_dsns_ctrl, -+ [3] = wmt_dbg_hwver_get, -+ [4] = wmt_dbg_assert_test, -+ [5] = wmt_dbg_inband_rst, -+ [6] = wmt_dbg_chip_rst, -+ [7] = wmt_dbg_func_ctrl, -+ [8] = wmt_dbg_raed_chipid, -+ [9] = wmt_dbg_wmt_dbg_level, -+ [0xa] = wmt_dbg_stp_dbg_level, -+ [0xb] = wmt_dbg_reg_read, -+ [0xc] = wmt_dbg_reg_write, -+ [0xd] = wmt_dbg_coex_test, -+ [0xe] = wmt_dbg_rst_ctrl, -+ [0xf] = wmt_dbg_ut_test, -+ [0x10] = wmt_dbg_efuse_read, -+ [0x11] = wmt_dbg_efuse_write, -+ [0x12] = wmt_dbg_sdio_ctrl, -+ [0x13] = wmt_dbg_stp_dbg_ctrl, -+ [0x14] = wmt_dbg_stp_dbg_log_ctrl, -+ [0x15] = wmt_dbg_wmt_assert_ctrl, -+ [0x16] = wmt_dbg_fwinfor_from_emi, -+ [0x17] = wmt_dbg_set_mcu_clock, -+ [0x18] = wmt_dbg_poll_cpupcr, -+ [0x19] = wmt_dbg_jtag_flag_ctrl, -+#if CFG_WMT_LTE_COEX_HANDLING -+ [0x20] = wmt_dbg_lte_coex_test, -+#endif -+}; -+ -+INT32 wmt_dbg_psm_ctrl(INT32 par1, INT32 par2, INT32 par3) -+{ -+#if CFG_WMT_PS_SUPPORT -+ if (0 == par2) { -+ wmt_lib_ps_ctrl(0); -+ WMT_INFO_FUNC("disable PSM\n"); -+ } else { -+ par2 = (1 > par2 || 20000 < par2) ? STP_PSM_IDLE_TIME_SLEEP : par2; -+ wmt_lib_ps_set_idle_time(par2); -+ wmt_lib_ps_ctrl(1); -+ WMT_WARN_FUNC("enable PSM, idle to sleep time = %d ms\n", par2); -+ } -+#else -+ WMT_INFO_FUNC("WMT PS not supported\n"); -+#endif -+ return 0; -+} -+ -+INT32 wmt_dbg_quick_sleep_ctrl(INT32 par1, INT32 par2, INT32 par3) -+{ -+#if CFG_WMT_PS_SUPPORT -+ UINT32 en_flag = par2; -+ -+ wmt_lib_quick_sleep_ctrl(en_flag); -+#else -+ WMT_WARN_FUNC("WMT PS not supported\n"); -+#endif -+ return 0; -+} -+ -+INT32 wmt_dbg_dsns_ctrl(INT32 par1, INT32 par2, INT32 par3) -+{ -+ if (WMTDSNS_FM_DISABLE <= par2 && WMTDSNS_MAX > par2) { -+ WMT_INFO_FUNC("DSNS type (%d)\n", par2); -+ mtk_wcn_wmt_dsns_ctrl(par2); -+ } else { -+ WMT_WARN_FUNC("invalid DSNS type\n"); -+ } -+ return 0; -+} -+ -+INT32 wmt_dbg_hwver_get(INT32 par1, INT32 par2, INT32 par3) -+{ -+ WMT_INFO_FUNC("query chip version\n"); -+ mtk_wcn_wmt_hwver_get(); -+ return 0; -+} -+ -+INT32 wmt_dbg_assert_test(INT32 par1, INT32 par2, INT32 par3) -+{ -+ if (0 == par3) { -+ /* par2 = 0: send assert command */ -+ /* par2 != 0: send exception command */ -+ return wmt_dbg_cmd_test_api(0 == par2 ? 0 : 1); -+ } else if (1 == par3) { -+ /* send noack command */ -+ return wmt_dbg_cmd_test_api(18); -+ } else if (2 == par3) { -+ /* warn reset test */ -+ return wmt_dbg_cmd_test_api(19); -+ } else if (3 == par3) { -+ /* firmware trace test */ -+ return wmt_dbg_cmd_test_api(20); -+ } -+ { -+ INT32 sec = 8; -+ INT32 times = 0; -+ -+ times = par3; -+ do { -+ WMT_INFO_FUNC("Send Assert Command per 8 secs!!\n"); -+ wmt_dbg_cmd_test_api(0); -+ osal_sleep_ms(sec * 1000); -+ } while (--times); -+ } -+ return 0; -+} -+ -+INT32 wmt_dbg_cmd_test_api(ENUM_WMTDRV_CMD_T cmd) -+{ -+ -+ P_OSAL_OP pOp = NULL; -+ MTK_WCN_BOOL bRet = MTK_WCN_BOOL_FALSE; -+ P_OSAL_SIGNAL pSignal; -+ -+ pOp = wmt_lib_get_free_op(); -+ if (!pOp) { -+ WMT_WARN_FUNC("get_free_lxop fail\n"); -+ return MTK_WCN_BOOL_FALSE; -+ } -+ -+ pSignal = &pOp->signal; -+ -+ pOp->op.opId = WMT_OPID_CMD_TEST; -+ -+ pSignal->timeoutValue = MAX_EACH_WMT_CMD; -+ /*this test command should be run with usb cable connected, so no host awake is needed */ -+ /* wmt_lib_host_awake_get(); */ -+ switch (cmd) { -+ case WMTDRV_CMD_ASSERT: -+ pOp->op.au4OpData[0] = 0; -+ break; -+ case WMTDRV_CMD_EXCEPTION: -+ pOp->op.au4OpData[0] = 1; -+ break; -+ case WMTDRV_CMD_NOACK_TEST: -+ pOp->op.au4OpData[0] = 3; -+ break; -+ case WMTDRV_CMD_WARNRST_TEST: -+ pOp->op.au4OpData[0] = 4; -+ break; -+ case WMTDRV_CMD_FWTRACE_TEST: -+ pOp->op.au4OpData[0] = 5; -+ break; -+ default: -+ if (WMTDRV_CMD_COEXDBG_00 <= cmd && WMTDRV_CMD_COEXDBG_15 >= cmd) { -+ pOp->op.au4OpData[0] = 2; -+ pOp->op.au4OpData[1] = cmd - 2; -+ } else { -+ pOp->op.au4OpData[0] = 0xff; -+ pOp->op.au4OpData[1] = 0xff; -+ } -+ pOp->op.au4OpData[2] = (SIZE_T) gCoexBuf.buffer; -+ pOp->op.au4OpData[3] = osal_sizeof(gCoexBuf.buffer); -+ break; -+ } -+ WMT_INFO_FUNC("CMD_TEST, opid(%d), par(%d, %d)\n", pOp->op.opId, pOp->op.au4OpData[0], pOp->op.au4OpData[1]); -+ /*wake up chip first */ -+ if (DISABLE_PSM_MONITOR()) { -+ WMT_ERR_FUNC("wake up failed\n"); -+ wmt_lib_put_op_to_free_queue(pOp); -+ return -1; -+ } -+ bRet = wmt_lib_put_act_op(pOp); -+ ENABLE_PSM_MONITOR(); -+ if ((cmd != WMTDRV_CMD_ASSERT) && -+ (cmd != WMTDRV_CMD_EXCEPTION) && -+ (cmd != WMTDRV_CMD_NOACK_TEST) && (cmd != WMTDRV_CMD_WARNRST_TEST) && (cmd != WMTDRV_CMD_FWTRACE_TEST)) { -+ if (MTK_WCN_BOOL_FALSE == bRet) { -+ gCoexBuf.availSize = 0; -+ } else { -+ gCoexBuf.availSize = pOp->op.au4OpData[3]; -+ WMT_INFO_FUNC("gCoexBuf.availSize = %d\n", gCoexBuf.availSize); -+ } -+ } -+ /* wmt_lib_host_awake_put(); */ -+ WMT_INFO_FUNC("CMD_TEST, opid (%d), par(%d, %d), ret(%d), result(%s)\n", -+ pOp->op.opId, -+ pOp->op.au4OpData[0], -+ pOp->op.au4OpData[1], bRet, MTK_WCN_BOOL_FALSE == bRet ? "failed" : "succeed"); -+ -+ return 0; -+} -+ -+INT32 wmt_dbg_inband_rst(INT32 par1, INT32 par2, INT32 par3) -+{ -+ if (0 == par2) { -+ WMT_INFO_FUNC("inband reset test!!\n"); -+ mtk_wcn_stp_inband_reset(); -+ } else { -+ WMT_INFO_FUNC("STP context reset in host side!!\n"); -+ mtk_wcn_stp_flush_context(); -+ } -+ -+ return 0; -+} -+ -+INT32 wmt_dbg_chip_rst(INT32 par1, INT32 par2, INT32 par3) -+{ -+ if (0 == par2) { -+ if (mtk_wcn_stp_is_ready()) { -+ WMT_INFO_FUNC("whole chip reset test\n"); -+ wmt_lib_cmb_rst(WMTRSTSRC_RESET_TEST); -+ } else { -+ WMT_INFO_FUNC("STP not ready , not to launch whole chip reset test\n"); -+ } -+ } else if (1 == par2) { -+ WMT_INFO_FUNC("chip hardware reset test\n"); -+ wmt_lib_hw_rst(); -+ } else { -+ WMT_INFO_FUNC("chip software reset test\n"); -+ wmt_lib_sw_rst(1); -+ } -+ return 0; -+} -+ -+INT32 wmt_dbg_func_ctrl(INT32 par1, INT32 par2, INT32 par3) -+{ -+ if (WMTDRV_TYPE_WMT > par2 || WMTDRV_TYPE_LPBK == par2) { -+ if (0 == par3) { -+ WMT_INFO_FUNC("function off test, type(%d)\n", par2); -+ mtk_wcn_wmt_func_off(par2); -+ } else { -+ WMT_INFO_FUNC("function on test, type(%d)\n", par2); -+ mtk_wcn_wmt_func_on(par2); -+ } -+ } else { -+ WMT_INFO_FUNC("function ctrl test, invalid type(%d)\n", par2); -+ } -+ return 0; -+} -+ -+INT32 wmt_dbg_raed_chipid(INT32 par1, INT32 par2, INT32 par3) -+{ -+ WMT_INFO_FUNC("chip version = %d\n", wmt_lib_get_icinfo(WMTCHIN_MAPPINGHWVER)); -+ return 0; -+} -+ -+INT32 wmt_dbg_wmt_dbg_level(INT32 par1, INT32 par2, INT32 par3) -+{ -+ par2 = (WMT_LOG_ERR <= par2 && WMT_LOG_LOUD >= par2) ? par2 : WMT_LOG_INFO; -+ wmt_lib_dbg_level_set(par2); -+ WMT_INFO_FUNC("set wmt log level to %d\n", par2); -+ return 0; -+} -+ -+INT32 wmt_dbg_stp_dbg_level(INT32 par1, INT32 par2, INT32 par3) -+{ -+ par2 = (0 <= par2 && 4 >= par2) ? par2 : 2; -+ mtk_wcn_stp_dbg_level(par2); -+ WMT_INFO_FUNC("set stp log level to %d\n", par2); -+ return 0; -+ -+} -+ -+INT32 wmt_dbg_reg_read(INT32 par1, INT32 par2, INT32 par3) -+{ -+ /* par2-->register address */ -+ /* par3-->register mask */ -+ UINT32 value = 0x0; -+ UINT32 iRet = -1; -+#if 0 -+ DISABLE_PSM_MONITOR(); -+ iRet = wmt_core_reg_rw_raw(0, par2, &value, par3); -+ ENABLE_PSM_MONITOR(); -+#endif -+ iRet = wmt_lib_reg_rw(0, par2, &value, par3); -+ WMT_INFO_FUNC("read combo chip register (0x%08x) with mask (0x%08x) %s, value = 0x%08x\n", -+ par2, par3, iRet != 0 ? "failed" : "succeed", iRet != 0 ? -1 : value); -+ return 0; -+} -+ -+INT32 wmt_dbg_reg_write(INT32 par1, INT32 par2, INT32 par3) -+{ -+ /* par2-->register address */ -+ /* par3-->value to set */ -+ UINT32 iRet = -1; -+#if 0 -+ DISABLE_PSM_MONITOR(); -+ iRet = wmt_core_reg_rw_raw(1, par2, &par3, 0xffffffff); -+ ENABLE_PSM_MONITOR(); -+#endif -+ iRet = wmt_lib_reg_rw(1, par2, &par3, 0xffffffff); -+ WMT_INFO_FUNC("write combo chip register (0x%08x) with value (0x%08x) %s\n", -+ par2, par3, iRet != 0 ? "failed" : "succeed"); -+ return 0; -+} -+ -+INT32 wmt_dbg_efuse_read(INT32 par1, INT32 par2, INT32 par3) -+{ -+ /* par2-->efuse address */ -+ /* par3-->register mask */ -+ UINT32 value = 0x0; -+ UINT32 iRet = -1; -+ -+ iRet = wmt_lib_efuse_rw(0, par2, &value, par3); -+ WMT_INFO_FUNC("read combo chip efuse (0x%08x) with mask (0x%08x) %s, value = 0x%08x\n", -+ par2, par3, iRet != 0 ? "failed" : "succeed", iRet != 0 ? -1 : value); -+ return 0; -+} -+ -+INT32 wmt_dbg_efuse_write(INT32 par1, INT32 par2, INT32 par3) -+{ -+ /* par2-->efuse address */ -+ /* par3-->value to set */ -+ UINT32 iRet = -1; -+ -+ iRet = wmt_lib_efuse_rw(1, par2, &par3, 0xffffffff); -+ WMT_INFO_FUNC("write combo chip efuse (0x%08x) with value (0x%08x) %s\n", -+ par2, par3, iRet != 0 ? "failed" : "succeed"); -+ return 0; -+} -+ -+INT32 wmt_dbg_sdio_ctrl(INT32 par1, INT32 par2, INT32 par3) -+{ -+/*remove sdio card detect/remove control because of btif is used*/ -+#if 0 -+ INT32 iRet = -1; -+ -+ iRet = wmt_lib_sdio_ctrl(0 != par2 ? 1 : 0); -+ WMT_INFO_FUNC("ctrl SDIO function %s\n", 0 == iRet ? "succeed" : "failed"); -+#endif -+ return 0; -+} -+ -+INT32 wmt_dbg_stp_dbg_ctrl(INT32 par1, INT32 par2, INT32 par3) -+{ -+ if (1 < par2) { -+ mtk_wcn_stp_dbg_dump_package(); -+ return 0; -+ } -+ WMT_INFO_FUNC("%s stp debug function\n", 0 == par2 ? "disable" : "enable"); -+ if (0 == par2) -+ mtk_wcn_stp_dbg_disable(); -+ else if (1 == par2) -+ mtk_wcn_stp_dbg_enable(); -+ -+ return 0; -+} -+ -+INT32 wmt_dbg_stp_dbg_log_ctrl(INT32 par1, INT32 par2, INT32 par3) -+{ -+ mtk_wcn_stp_dbg_log_ctrl(0 != par2 ? 1 : 0); -+ return 0; -+} -+ -+INT32 wmt_dbg_wmt_assert_ctrl(INT32 par1, INT32 par2, INT32 par3) -+{ -+ mtk_wcn_stp_coredump_flag_ctrl(0 != par2 ? 1 : 0); -+ return 0; -+} -+ -+INT32 wmt_dbg_fwinfor_from_emi(INT32 par1, INT32 par2, INT32 par3) -+{ -+ UINT32 offset = 0; -+ UINT32 len = 0; -+ UINT32 *pAddr = NULL; -+ UINT32 cur_idx_pagedtrace; -+ static UINT32 prev_idx_pagedtrace; -+ MTK_WCN_BOOL isBreak = MTK_WCN_BOOL_TRUE; -+ -+ offset = par2; -+ len = par3; -+ -+ buf_emi = kmalloc(sizeof(UINT8) * BUF_LEN_MAX, GFP_KERNEL); -+ if (!buf_emi) { -+ WMT_ERR_FUNC("buf kmalloc memory fail\n"); -+ return 0; -+ } -+ osal_memset(buf_emi, 0, BUF_LEN_MAX); -+ osal_memset(&gEmiBuf[0], 0, WMT_EMI_DEBUG_BUF_SIZE); -+ wmt_lib_get_fwinfor_from_emi(0, offset, &gEmiBuf[0], 0x100); -+ -+ if (offset == 1) { -+ do { -+ pAddr = (PUINT32) wmt_plat_get_emi_virt_add(0x24); -+ cur_idx_pagedtrace = *pAddr; -+ -+ if (cur_idx_pagedtrace > prev_idx_pagedtrace) { -+ len = cur_idx_pagedtrace - prev_idx_pagedtrace; -+ wmt_lib_get_fwinfor_from_emi(1, prev_idx_pagedtrace, &gEmiBuf[0], len); -+ wmt_dbg_fwinfor_print_buff(len); -+ prev_idx_pagedtrace = cur_idx_pagedtrace; -+ } -+ -+ if (cur_idx_pagedtrace < prev_idx_pagedtrace) { -+ if (prev_idx_pagedtrace >= 0x8000) { -+ pr_debug("++ prev_idx_pagedtrace invalid ...++\n\\n"); -+ prev_idx_pagedtrace = 0x8000 - 1; -+ continue; -+ } -+ -+ len = 0x8000 - prev_idx_pagedtrace - 1; -+ wmt_lib_get_fwinfor_from_emi(1, prev_idx_pagedtrace, &gEmiBuf[0], len); -+ pr_debug("\n\n -- CONNSYS paged trace ascii output (cont...) --\n\n"); -+ wmt_dbg_fwinfor_print_buff(len); -+ -+ len = cur_idx_pagedtrace; -+ wmt_lib_get_fwinfor_from_emi(1, 0x0, &gEmiBuf[0], len); -+ pr_debug("\n\n -- CONNSYS paged trace ascii output (end) --\n\n"); -+ wmt_dbg_fwinfor_print_buff(len); -+ prev_idx_pagedtrace = cur_idx_pagedtrace; -+ } -+ msleep(100); -+ } while (isBreak); -+ } -+ -+ pr_debug("\n\n -- control word --\n\n"); -+ wmt_dbg_fwinfor_print_buff(256); -+ if (len > 1024 * 4) -+ len = 1024 * 4; -+ -+ WMT_WARN_FUNC("get fw infor from emi at offset(0x%x),len(0x%x)\n", offset, len); -+ osal_memset(&gEmiBuf[0], 0, WMT_EMI_DEBUG_BUF_SIZE); -+ wmt_lib_get_fwinfor_from_emi(1, offset, &gEmiBuf[0], len); -+ -+ pr_debug("\n\n -- paged trace hex output --\n\n"); -+ wmt_dbg_fwinfor_print_buff(len); -+ pr_debug("\n\n -- paged trace ascii output --\n\n"); -+ wmt_dbg_fwinfor_print_buff(len); -+ kfree(buf_emi); -+ return 0; -+} -+ -+INT32 wmt_dbg_coex_test(INT32 par1, INT32 par2, INT32 par3) -+{ -+ WMT_INFO_FUNC("coexistance test cmd!!\n"); -+ return wmt_dbg_cmd_test_api(par2 + WMTDRV_CMD_COEXDBG_00); -+} -+ -+INT32 wmt_dbg_rst_ctrl(INT32 par1, INT32 par2, INT32 par3) -+{ -+ WMT_INFO_FUNC("%s audo rst\n", 0 == par2 ? "disable" : "enable"); -+ mtk_wcn_stp_set_auto_rst(0 == par2 ? 0 : 1); -+ return 0; -+} -+ -+INT32 wmt_dbg_ut_test(INT32 par1, INT32 par2, INT32 par3) -+{ -+ -+ INT32 i = 0; -+ INT32 j = 0; -+ INT32 iRet = 0; -+ -+ i = 20; -+ while ((i--) > 0) { -+ WMT_INFO_FUNC("#### UT WMT and STP Function On/Off .... %d\n", i); -+ j = 10; -+ while ((j--) > 0) { -+ WMT_INFO_FUNC("#### BT On .... (%d, %d)\n", i, j); -+ iRet = mtk_wcn_wmt_func_on(WMTDRV_TYPE_BT); -+ if (iRet == MTK_WCN_BOOL_FALSE) -+ break; -+ -+ WMT_INFO_FUNC("#### GPS On .... (%d, %d)\n", i, j); -+ iRet = mtk_wcn_wmt_func_on(WMTDRV_TYPE_GPS); -+ if (iRet == MTK_WCN_BOOL_FALSE) -+ break; -+ -+ WMT_INFO_FUNC("#### FM On .... (%d, %d)\n", i, j); -+ iRet = mtk_wcn_wmt_func_on(WMTDRV_TYPE_FM); -+ if (iRet == MTK_WCN_BOOL_FALSE) -+ break; -+ -+ WMT_INFO_FUNC("#### WIFI On .... (%d, %d)\n", i, j); -+ iRet = mtk_wcn_wmt_func_on(WMTDRV_TYPE_WIFI); -+ if (iRet == MTK_WCN_BOOL_FALSE) -+ break; -+ -+ WMT_INFO_FUNC("#### BT Off .... (%d, %d)\n", i, j); -+ iRet = mtk_wcn_wmt_func_off(WMTDRV_TYPE_BT); -+ if (iRet == MTK_WCN_BOOL_FALSE) -+ break; -+ -+ WMT_INFO_FUNC("#### GPS Off ....(%d, %d)\n", i, j); -+ iRet = mtk_wcn_wmt_func_off(WMTDRV_TYPE_GPS); -+ if (iRet == MTK_WCN_BOOL_FALSE) -+ break; -+ -+ WMT_INFO_FUNC("#### FM Off .... (%d, %d)\n", i, j); -+ iRet = mtk_wcn_wmt_func_off(WMTDRV_TYPE_FM); -+ if (iRet == MTK_WCN_BOOL_FALSE) -+ break; -+ -+ WMT_INFO_FUNC("#### WIFI Off ....(%d, %d)\n", i, j); -+ iRet = mtk_wcn_wmt_func_off(WMTDRV_TYPE_WIFI); -+ if (iRet == MTK_WCN_BOOL_FALSE) -+ break; -+ -+ } -+ if (iRet == MTK_WCN_BOOL_FALSE) -+ break; -+ -+ } -+ if (iRet == MTK_WCN_BOOL_FALSE) -+ WMT_INFO_FUNC("#### UT FAIL!!\n"); -+ else -+ WMT_INFO_FUNC("#### UT PASS!!\n"); -+ -+ return iRet; -+} -+ -+#if CFG_CORE_INTERNAL_TXRX -+ -+struct lpbk_package { -+ long payload_length; -+ unsigned char out_payload[2048]; -+ unsigned char in_payload[2048]; -+}; -+ -+static INT32 wmt_internal_loopback(INT32 count, INT32 max) -+{ -+ int ret = 0; -+ int loop; -+ int offset; -+ struct lpbk_package lpbk_buffer; -+ P_OSAL_OP pOp; -+ P_OSAL_SIGNAL pSignal = NULL; -+ -+ for (loop = 0; loop < count; loop++) { -+ /* <1> init buffer */ -+ osal_memset((void *)&lpbk_buffer, 0, sizeof(struct lpbk_package)); -+ lpbk_buffer.payload_length = max; -+ for (offset = 0; offset < max; offset++) -+ lpbk_buffer.out_payload[offset] = (offset + 1) /*for test use: begin from 1 */ & 0xFF; -+ -+ -+ memcpy(&gLpbkBuf[0], &lpbk_buffer.out_payload[0], max); -+ -+ pOp = wmt_lib_get_free_op(); -+ if (!pOp) { -+ WMT_WARN_FUNC("get_free_lxop fail\n"); -+ ret = -1; -+ break; -+ } -+ pSignal = &pOp->signal; -+ pOp->op.opId = WMT_OPID_LPBK; -+ pOp->op.au4OpData[0] = lpbk_buffer.payload_length; /* packet length */ -+ pOp->op.au4OpData[1] = (UINT32) &gLpbkBuf[0]; -+ pSignal->timeoutValue = MAX_EACH_WMT_CMD; -+ WMT_INFO_FUNC("OPID(%d) type(%d) start\n", pOp->op.opId, pOp->op.au4OpData[0]); -+ if (DISABLE_PSM_MONITOR()) { -+ WMT_ERR_FUNC("wake up failed,OPID(%d) type(%d) abort\n", pOp->op.opId, pOp->op.au4OpData[0]); -+ wmt_lib_put_op_to_free_queue(pOp); -+ ret = -2; -+ } -+ -+ ret = wmt_lib_put_act_op(pOp); -+ ENABLE_PSM_MONITOR(); -+ if (MTK_WCN_BOOL_FALSE == ret) { -+ WMT_WARN_FUNC("OPID(%d) type(%d)fail\n", pOp->op.opId, pOp->op.au4OpData[0]); -+ ret = -3; -+ break; -+ } -+ WMT_INFO_FUNC("OPID(%d) length(%d) ok\n", pOp->op.opId, pOp->op.au4OpData[0]); -+ -+ memcpy(&lpbk_buffer.in_payload[0], &gLpbkBuf[0], max); -+ -+ ret = pOp->op.au4OpData[0]; -+ /*<3> compare result */ -+ if (memcmp(lpbk_buffer.in_payload, lpbk_buffer.out_payload, lpbk_buffer.payload_length)) { -+ WMT_INFO_FUNC("[%s] WMT_TEST_LPBK_CMD payload compare error\n", __func__); -+ ret = -4; -+ break; -+ } -+ WMT_ERR_FUNC("[%s] exec WMT_TEST_LPBK_CMD succeed(loop = %d, size = %ld)\n", __func__, loop, -+ lpbk_buffer.payload_length); -+ -+ } -+ -+ if (loop != count) -+ WMT_ERR_FUNC("fail at loop(%d) buf_length(%d)\n", loop, max); -+ -+ -+ return ret; -+} -+ -+INT32 wmt_dbg_internal_lpbk_test(INT32 par1, INT32 par2, INT32 par3) -+{ -+ UINT32 count; -+ UINT32 length; -+ -+ count = par1; -+ length = par2; -+ -+ WMT_INFO_FUNC("count[%d],length[%d]\n", count, length); -+ -+ wmt_core_lpbk_do_stp_init(); -+ -+ wmt_internal_loopback(count, length); -+ -+ wmt_core_lpbk_do_stp_deinit(); -+ return 0; -+} -+#endif -+ -+static INT32 wmt_dbg_set_mcu_clock(INT32 par1, INT32 par2, INT32 par3) -+{ -+ int ret = 0; -+ P_OSAL_OP pOp; -+ P_OSAL_SIGNAL pSignal = NULL; -+ UINT32 kind = 0; -+ -+ kind = par2; -+ pOp = wmt_lib_get_free_op(); -+ if (!pOp) { -+ WMT_WARN_FUNC("get_free_lxop fail\n"); -+ return -1; -+ } -+ pSignal = &pOp->signal; -+ pOp->op.opId = WMT_OPID_SET_MCU_CLK; -+ pOp->op.au4OpData[0] = kind; -+ pSignal->timeoutValue = MAX_EACH_WMT_CMD; -+ -+ WMT_INFO_FUNC("OPID(%d) kind(%d) start\n", pOp->op.opId, pOp->op.au4OpData[0]); -+ if (DISABLE_PSM_MONITOR()) { -+ WMT_ERR_FUNC("wake up failed,OPID(%d) kind(%d) abort\n", pOp->op.opId, pOp->op.au4OpData[0]); -+ wmt_lib_put_op_to_free_queue(pOp); -+ return -2; -+ } -+ -+ ret = wmt_lib_put_act_op(pOp); -+ ENABLE_PSM_MONITOR(); -+ if (MTK_WCN_BOOL_FALSE == ret) { -+ WMT_WARN_FUNC("OPID(%d) kind(%d)fail(%d)\n", pOp->op.opId, pOp->op.au4OpData[0], ret); -+ return -3; -+ } -+ WMT_INFO_FUNC("OPID(%d) kind(%d) ok\n", pOp->op.opId, pOp->op.au4OpData[0]); -+ -+ return ret; -+} -+ -+static INT32 wmt_dbg_poll_cpupcr(INT32 par1, INT32 par2, INT32 par3) -+{ -+ UINT32 count = 0; -+ UINT16 sleep = 0; -+ UINT16 toAee = 0; -+ -+ count = par2; -+ sleep = (par3 & 0xF0) >> 4; -+ toAee = (par3 & 0x0F); -+ -+ WMT_INFO_FUNC("polling count[%d],polling sleep[%d],toaee[%d]\n", count, sleep, toAee); -+ wmt_lib_poll_cpupcr(count, sleep, toAee); -+ -+ return 0; -+} -+ -+#if CONSYS_ENALBE_SET_JTAG -+static INT32 wmt_dbg_jtag_flag_ctrl(INT32 par1, INT32 par2, INT32 par3) -+{ -+ UINT32 en_flag = par2; -+ -+ wmt_lib_jtag_flag_set(en_flag); -+ return 0; -+} -+#endif -+ -+#if CFG_WMT_LTE_COEX_HANDLING -+static INT32 wmt_dbg_lte_to_wmt_test(UINT32 opcode, UINT32 msg_len) -+{ -+ ipc_ilm_t ilm; -+ local_para_struct *p_buf_str; -+ INT32 i = 0; -+ INT32 iRet = -1; -+ -+ WMT_INFO_FUNC("opcode(0x%02x),msg_len(%d)\n", opcode, msg_len); -+ p_buf_str = osal_malloc(osal_sizeof(local_para_struct) + msg_len); -+ if (NULL == p_buf_str) { -+ WMT_ERR_FUNC("kmalloc for local para ptr structure failed.\n"); -+ return -1; -+ } -+ p_buf_str->msg_len = msg_len; -+ for (i = 0; i < msg_len; i++) -+ p_buf_str->data[i] = i; -+ -+ ilm.local_para_ptr = p_buf_str; -+ ilm.msg_id = opcode; -+ -+ iRet = wmt_lib_handle_idc_msg(&ilm); -+ osal_free(p_buf_str); -+ return iRet; -+ -+} -+ -+static INT32 wmt_dbg_lte_coex_test(INT32 par1, INT32 par2, INT32 par3) -+{ -+ UINT8 *local_buffer = NULL; -+ UINT32 handle_len; -+ INT32 iRet = -1; -+ static UINT8 wmt_to_lte_test_evt1[] = { 0x02, 0x16, 0x0d, 0x00, -+ 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, -+ 0xa, 0xb -+ }; -+ static UINT8 wmt_to_lte_test_evt2[] = { 0x02, 0x16, 0x09, 0x00, -+ 0x01, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 -+ }; -+ static UINT8 wmt_to_lte_test_evt3[] = { 0x02, 0x16, 0x02, 0x00, -+ 0x02, 0xff -+ }; -+ static UINT8 wmt_to_lte_test_evt4[] = { 0x02, 0x16, 0x0d, 0x00, -+ 0x03, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, -+ 0xa, 0xb -+ }; -+ -+ local_buffer = kmalloc(512, GFP_KERNEL); -+ if (!local_buffer) { -+ WMT_ERR_FUNC("local_buffer kmalloc memory fail\n"); -+ return 0; -+ } -+ -+ if (par2 == 1) { -+ handle_len = -+ wmt_idc_msg_to_lte_handing_for_test(&wmt_to_lte_test_evt1[0], osal_sizeof(wmt_to_lte_test_evt1)); -+ if (handle_len != osal_sizeof(wmt_to_lte_test_evt1)) { -+ WMT_ERR_FUNC("par2=1,wmt send to lte msg fail:handle_len(%d),buff_len(%d)\n", -+ handle_len, osal_sizeof(wmt_to_lte_test_evt1)); -+ } else { -+ WMT_INFO_FUNC("par2=1,wmt send to lte msg OK! send_len(%d)\n", handle_len); -+ } -+ } -+ if (par2 == 2) { -+ osal_memcpy(&local_buffer[0], &wmt_to_lte_test_evt1[0], osal_sizeof(wmt_to_lte_test_evt1)); -+ osal_memcpy(&local_buffer[osal_sizeof(wmt_to_lte_test_evt1)], -+ &wmt_to_lte_test_evt2[0], osal_sizeof(wmt_to_lte_test_evt2)); -+ -+ handle_len = -+ wmt_idc_msg_to_lte_handing_for_test(&local_buffer[0], -+ osal_sizeof(wmt_to_lte_test_evt1) + -+ osal_sizeof(wmt_to_lte_test_evt2)); -+ if (handle_len != osal_sizeof(wmt_to_lte_test_evt1) + osal_sizeof(wmt_to_lte_test_evt2)) { -+ WMT_ERR_FUNC("par2=2,wmt send to lte msg fail:handle_len(%d),buff_len(%d)\n", -+ handle_len, osal_sizeof(wmt_to_lte_test_evt1) + osal_sizeof(wmt_to_lte_test_evt2)); -+ } else { -+ WMT_INFO_FUNC("par2=1,wmt send to lte msg OK! send_len(%d)\n", handle_len); -+ } -+ } -+ if (par2 == 3) { -+ osal_memcpy(&local_buffer[0], &wmt_to_lte_test_evt1[0], osal_sizeof(wmt_to_lte_test_evt1)); -+ osal_memcpy(&local_buffer[osal_sizeof(wmt_to_lte_test_evt1)], -+ &wmt_to_lte_test_evt2[0], osal_sizeof(wmt_to_lte_test_evt2)); -+ osal_memcpy(&local_buffer[osal_sizeof(wmt_to_lte_test_evt1) + osal_sizeof(wmt_to_lte_test_evt2)], -+ &wmt_to_lte_test_evt3[0], osal_sizeof(wmt_to_lte_test_evt3)); -+ -+ handle_len = wmt_idc_msg_to_lte_handing_for_test(&local_buffer[0], osal_sizeof(wmt_to_lte_test_evt1) + -+ osal_sizeof(wmt_to_lte_test_evt2) + -+ osal_sizeof(wmt_to_lte_test_evt3)); -+ if (handle_len != -+ osal_sizeof(wmt_to_lte_test_evt1) + osal_sizeof(wmt_to_lte_test_evt2) + -+ osal_sizeof(wmt_to_lte_test_evt3)) { -+ WMT_ERR_FUNC("par2=3,wmt send to lte msg fail:handle_len(%d),buff_len(%d)\n", handle_len, -+ osal_sizeof(wmt_to_lte_test_evt1) + osal_sizeof(wmt_to_lte_test_evt2) + -+ osal_sizeof(wmt_to_lte_test_evt3)); -+ } else { -+ WMT_INFO_FUNC("par3=1,wmt send to lte msg OK! send_len(%d)\n", handle_len); -+ } -+ } -+ if (par2 == 4) { -+ handle_len = -+ wmt_idc_msg_to_lte_handing_for_test(&wmt_to_lte_test_evt4[0], osal_sizeof(wmt_to_lte_test_evt4)); -+ if (handle_len != osal_sizeof(wmt_to_lte_test_evt4)) { -+ WMT_ERR_FUNC("par2=1,wmt send to lte msg fail:handle_len(%d),buff_len(%d)\n", -+ handle_len, osal_sizeof(wmt_to_lte_test_evt4)); -+ } else { -+ WMT_INFO_FUNC("par2=1,wmt send to lte msg OK! send_len(%d)\n", handle_len); -+ } -+ } -+ if (par2 == 5) { -+ if (par3 >= 1024) -+ par3 = 1024; -+ -+ iRet = wmt_dbg_lte_to_wmt_test(IPC_MSG_ID_EL1_LTE_DEFAULT_PARAM_IND, par3); -+ WMT_INFO_FUNC("IPC_MSG_ID_EL1_LTE_DEFAULT_PARAM_IND test result(%d)\n", iRet); -+ } -+ if (par2 == 6) { -+ if (par3 >= 1024) -+ par3 = 1024; -+ -+ iRet = wmt_dbg_lte_to_wmt_test(IPC_MSG_ID_EL1_LTE_OPER_FREQ_PARAM_IND, par3); -+ WMT_INFO_FUNC("IPC_MSG_ID_EL1_LTE_OPER_FREQ_PARAM_IND test result(%d)\n", iRet); -+ } -+ if (par2 == 7) { -+ if (par3 >= 1024) -+ par3 = 1024; -+ -+ iRet = wmt_dbg_lte_to_wmt_test(IPC_MSG_ID_EL1_WIFI_MAX_PWR_IND, par3); -+ WMT_INFO_FUNC("IPC_MSG_ID_EL1_WIFI_MAX_PWR_IND test result(%d)\n", iRet); -+ } -+ if (par2 == 8) { -+ if (par3 >= 1024) -+ par3 = 1024; -+ -+ iRet = wmt_dbg_lte_to_wmt_test(IPC_MSG_ID_EL1_LTE_TX_IND, par3); -+ WMT_INFO_FUNC("IPC_MSG_ID_EL1_LTE_TX_IND test result(%d)\n", iRet); -+ } -+ if (par2 == 9) { -+ if (par3 > 0) -+ wmt_core_set_flag_for_test(1); -+ else -+ wmt_core_set_flag_for_test(0); -+ } -+ return 0; -+ kfree(local_buffer); -+} -+#endif -+ -+static ssize_t wmt_dev_dbg_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos) -+{ -+ -+ INT32 retval = 0; -+ INT32 i_ret = 0; -+ PINT8 warn_msg = "no data available, please run echo 15 xx > /proc/driver/wmt_psm first\n"; -+ -+ if (*f_pos > 0) { -+ retval = 0; -+ } else { -+ /*len = sprintf(page, "%d\n", g_psm_enable); */ -+ if (gCoexBuf.availSize <= 0) { -+ WMT_INFO_FUNC("no data available, please run echo 15 xx > /proc/driver/wmt_psm first\n"); -+ retval = osal_strlen(warn_msg) + 1; -+ if (count < retval) -+ retval = count; -+ -+ i_ret = copy_to_user(buf, warn_msg, retval); -+ if (i_ret) { -+ WMT_ERR_FUNC("copy to buffer failed, ret:%d\n", retval); -+ retval = -EFAULT; -+ goto err_exit; -+ } -+ *f_pos += retval; -+ } else { -+ INT32 i = 0; -+ INT32 len = 0; -+ INT8 msg_info[128]; -+ INT32 max_num = 0; -+ /*we do not check page buffer, because there are only -+ * 100 bytes in g_coex_buf, no reason page buffer is not -+ * enough, a bomb is placed here on unexpected condition -+ */ -+ -+ WMT_INFO_FUNC("%d bytes available\n", gCoexBuf.availSize); -+ max_num = ((osal_sizeof(msg_info) > count ? osal_sizeof(msg_info) : count) - 1) / 5; -+ -+ if (max_num > gCoexBuf.availSize) -+ max_num = gCoexBuf.availSize; -+ else -+ WMT_INFO_FUNC("round to %d bytes due to local buffer size limitation\n", max_num); -+ -+ -+ for (i = 0; i < max_num; i++) -+ len += osal_sprintf(msg_info + len, "0x%02x ", gCoexBuf.buffer[i]); -+ -+ -+ len += osal_sprintf(msg_info + len, "\n"); -+ retval = len; -+ -+ i_ret = copy_to_user(buf, msg_info, retval); -+ if (i_ret) { -+ WMT_ERR_FUNC("copy to buffer failed, ret:%d\n", retval); -+ retval = -EFAULT; -+ goto err_exit; -+ } -+ *f_pos += retval; -+ -+ } -+ } -+ gCoexBuf.availSize = 0; -+err_exit: -+ -+ return retval; -+} -+ -+static ssize_t wmt_dev_dbg_write(struct file *filp, const char __user *buffer, size_t count, loff_t *f_pos) -+{ -+ INT8 buf[256]; -+ PINT8 pBuf; -+ ssize_t len = count; -+ INT32 x = 0, y = 0, z = 0; -+ PINT8 pToken = NULL; -+ PINT8 pDelimiter = " \t"; -+ long res; -+ INT32 ret; -+ -+ WMT_INFO_FUNC("write parameter len = %d\n\r", (INT32) len); -+ if (len >= osal_sizeof(buf)) { -+ WMT_ERR_FUNC("input handling fail!\n"); -+ len = osal_sizeof(buf) - 1; -+ return -1; -+ } -+ -+ if (copy_from_user(buf, buffer, len)) -+ return -EFAULT; -+ -+ buf[len] = '\0'; -+ WMT_INFO_FUNC("write parameter data = %s\n\r", buf); -+ -+ pBuf = buf; -+ pToken = osal_strsep(&pBuf, pDelimiter); -+ -+ if (pToken != NULL) { -+ ret = osal_strtol(pToken, 16, &res); -+ if (ret) { -+ WMT_ERR_FUNC("get x fail(%d)\n", ret); -+ x = 0; -+ } -+ x = res; -+ } else { -+ x = 0; -+ } -+ -+ pToken = osal_strsep(&pBuf, "\t\n "); -+ if (pToken != NULL) { -+ ret = osal_strtol(pToken, 16, &res); -+ if (ret) { -+ WMT_ERR_FUNC("get y fail(%d)\n", ret); -+ y = 0; -+ } -+ y = res; -+ WMT_INFO_FUNC("y = 0x%08x\n\r", y); -+ } else { -+ y = 3000; -+ /*efuse, register read write default value */ -+ if (0x11 == x || 0x12 == x || 0x13 == x) -+ y = 0x80000000; -+ -+ } -+ -+ pToken = osal_strsep(&pBuf, "\t\n "); -+ if (pToken != NULL) { -+ ret = osal_strtol(pToken, 16, &res); -+ if (ret) { -+ WMT_ERR_FUNC("get z fail(%d)\n", ret); -+ z = 0; -+ } -+ z = res; -+ } else { -+ z = 10; -+ /*efuse, register read write default value */ -+ if (0x11 == x || 0x12 == x || 0x13 == x) -+ z = 0xffffffff; -+ -+ } -+ -+ WMT_WARN_FUNC("x(0x%08x), y(0x%08x), z(0x%08x)\n\r", x, y, z); -+ -+ if (osal_array_size(wmt_dev_dbg_func) > x && NULL != wmt_dev_dbg_func[x]) -+ (*wmt_dev_dbg_func[x]) (x, y, z); -+ else -+ WMT_WARN_FUNC("no handler defined for command id(0x%08x)\n\r", x); -+ -+ return len; -+} -+ -+INT32 wmt_dev_dbg_setup(VOID) -+{ -+ static const struct file_operations wmt_dbg_fops = { -+ .owner = THIS_MODULE, -+ .read = wmt_dev_dbg_read, -+ .write = wmt_dev_dbg_write, -+ }; -+ gWmtDbgEntry = proc_create(WMT_DBG_PROCNAME, 0664, NULL, &wmt_dbg_fops); -+ if (gWmtDbgEntry == NULL) { -+ WMT_ERR_FUNC("Unable to create /proc entry\n\r"); -+ return -1; -+ } -+ return 0; -+} -+ -+INT32 wmt_dev_dbg_remove(VOID) -+{ -+ if (NULL != gWmtDbgEntry) -+ remove_proc_entry(WMT_DBG_PROCNAME, NULL); -+ -+#if CFG_WMT_PS_SUPPORT -+ wmt_lib_ps_deinit(); -+#endif -+ return 0; -+} -+#endif -+ -+#if CFG_WMT_PROC_FOR_AEE -+ -+static ssize_t wmt_dev_proc_for_aee_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos) -+{ -+ INT32 retval = 0; -+ UINT32 len = 0; -+ -+ WMT_INFO_FUNC("%s: count %d pos %lld\n", __func__, count, *f_pos); -+ -+ if (0 == *f_pos) { -+ pBuf = wmt_lib_get_cpupcr_xml_format(&len); -+ g_buf_len = len; -+ WMT_INFO_FUNC("wmt_dev:wmt for aee buffer len(%d)\n", g_buf_len); -+ } -+ -+ if (g_buf_len >= count) { -+ -+ retval = copy_to_user(buf, pBuf, count); -+ if (retval) { -+ WMT_ERR_FUNC("copy to aee buffer failed, ret:%d\n", retval); -+ retval = -EFAULT; -+ goto err_exit; -+ } -+ -+ *f_pos += count; -+ g_buf_len -= count; -+ pBuf += count; -+ WMT_INFO_FUNC("wmt_dev:after read,wmt for aee buffer len(%d)\n", g_buf_len); -+ -+ retval = count; -+ } else if (0 != g_buf_len) { -+ -+ retval = copy_to_user(buf, pBuf, g_buf_len); -+ if (retval) { -+ WMT_ERR_FUNC("copy to aee buffer failed, ret:%d\n", retval); -+ retval = -EFAULT; -+ goto err_exit; -+ } -+ -+ *f_pos += g_buf_len; -+ len = g_buf_len; -+ g_buf_len = 0; -+ pBuf += len; -+ retval = len; -+ WMT_INFO_FUNC("wmt_dev:after read,wmt for aee buffer len(%d)\n", g_buf_len); -+ } else { -+ WMT_INFO_FUNC("wmt_dev: no data available for aee\n"); -+ retval = 0; -+ } -+err_exit: -+ return retval; -+} -+ -+static ssize_t wmt_dev_proc_for_aee_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos) -+{ -+ WMT_TRC_FUNC(); -+ return 0; -+} -+ -+INT32 wmt_dev_proc_for_aee_setup(VOID) -+{ -+ static const struct file_operations wmt_aee_fops = { -+ .owner = THIS_MODULE, -+ .read = wmt_dev_proc_for_aee_read, -+ .write = wmt_dev_proc_for_aee_write, -+ }; -+ -+ gWmtDbgEntry = proc_create(WMT_AEE_PROCNAME, 0664, NULL, &wmt_aee_fops); -+ if (gWmtDbgEntry == NULL) { -+ WMT_ERR_FUNC("Unable to create /proc entry\n\r"); -+ return -1; -+ } -+ -+ return 0; -+} -+ -+INT32 wmt_dev_proc_for_aee_remove(VOID) -+{ -+ if (NULL != gWmtAeeEntry) -+ remove_proc_entry(WMT_AEE_PROCNAME, NULL); -+ -+ return 0; -+} -+#endif -+ -+VOID wmt_dev_rx_event_cb(VOID) -+{ -+ u4RxFlag = 1; -+ atomic_inc(&gRxCount); -+ if (NULL != gpRxEvent) { -+ /* u4RxFlag = 1; */ -+ /* atomic_inc(&gRxCount); */ -+ wake_up_interruptible(&gpRxEvent->waitQueue); -+ } else { -+ /* WMT_ERR_FUNC("null gpRxEvent, flush rx!\n"); */ -+ /* wmt_lib_flush_rx(); */ -+ } -+} -+ -+INT32 wmt_dev_rx_timeout(P_OSAL_EVENT pEvent) -+{ -+ -+ UINT32 ms = pEvent->timeoutValue; -+ long lRet = 0; -+ -+ gpRxEvent = pEvent; -+ if (0 != ms) -+ lRet = wait_event_interruptible_timeout(gpRxEvent->waitQueue, 0 != u4RxFlag, msecs_to_jiffies(ms)); -+ else -+ lRet = wait_event_interruptible(gpRxEvent->waitQueue, u4RxFlag != 0); -+ -+ u4RxFlag = 0; -+/* gpRxEvent = NULL; */ -+ if (atomic_dec_return(&gRxCount)) { -+ WMT_ERR_FUNC("gRxCount != 0 (%d), reset it!\n", atomic_read(&gRxCount)); -+ atomic_set(&gRxCount, 0); -+ } -+ -+ return lRet; -+} -+ -+INT32 wmt_dev_read_file(PUINT8 pName, const PPUINT8 ppBufPtr, INT32 offset, INT32 padSzBuf) -+{ -+ INT32 iRet = -1; -+ struct file *fd; -+ /* ssize_t iRet; */ -+ INT32 file_len; -+ INT32 read_len; -+ PVOID pBuf; -+ mm_segment_t fs; -+ -+ /* struct cred *cred = get_task_cred(current); */ -+ //const struct cred *cred = get_current_cred(); -+ -+ if (!ppBufPtr) { -+ WMT_ERR_FUNC("invalid ppBufptr!\n"); -+ return -1; -+ } -+ *ppBufPtr = NULL; -+ -+ fd = filp_open(pName, O_RDONLY, 0); -+ if (IS_ERR(fd)) { -+ WMT_ERR_FUNC("error code:%d\n", PTR_ERR(fd)); -+ return -2; -+ } -+ -+ if(fd->f_op == NULL) { -+ printk(KERN_ERR "invalid file op \r\n"); -+ return -3; -+ } -+ -+#if 0 -+ if (!fd || IS_ERR(fd) || !fd->f_op || !fd->f_op->read) { -+ WMT_ERR_FUNC("failed to open or read!(0x%p, %d, %d, %d)\n", fd, PTR_ERR(fd), cred->fsuid, cred->fsgid); -+ if (IS_ERR(fd)) -+ WMT_ERR_FUNC("error code:%d\n", PTR_ERR(fd)); -+ return -1; -+ } -+#endif -+ file_len = fd->f_path.dentry->d_inode->i_size; -+ file_len = fd->f_op->llseek(fd, 0, 2); -+ fd->f_op->llseek(fd, 0, 0); -+ pBuf = vmalloc((file_len + BCNT_PATCH_BUF_HEADROOM + 3) & ~0x3UL); -+ if (!pBuf) { -+ WMT_ERR_FUNC("failed to vmalloc(%d)\n", (INT32) ((file_len + 3) & ~0x3UL)); -+ goto read_file_done; -+ } -+ -+ do { -+ if (fd->f_pos != offset) { -+ if (fd->f_op->llseek) { -+ if (fd->f_op->llseek(fd, offset, 0) != offset) { -+ WMT_ERR_FUNC("failed to seek!!\n"); -+ goto read_file_done; -+ } -+ } else { -+ fd->f_pos = offset; -+ } -+ } -+ -+ fs=get_fs(); -+ read_len = vfs_read(fd, pBuf + padSzBuf, file_len, &fd->f_pos); -+ set_fs(fs); -+ if (read_len != file_len) -+ WMT_WARN_FUNC("read abnormal: read_len(%d), file_len(%d)\n", read_len, file_len); -+ -+ } while (false); -+ -+ iRet = 0; -+ *ppBufPtr = pBuf; -+ -+read_file_done: -+ if (iRet) { -+ if (pBuf) -+ vfree(pBuf); -+ -+ } -+ -+ filp_close(fd, NULL); -+ -+ return (iRet) ? iRet : read_len; -+} -+ -+/* TODO: [ChangeFeature][George] refine this function name for general filesystem read operation, not patch only. */ -+INT32 wmt_dev_patch_get(PUINT8 pPatchName, osal_firmware **ppPatch, INT32 padSzBuf) -+{ -+ INT32 iRet = -1; -+ osal_firmware *pfw; -+ uid_t orig_uid; -+ gid_t orig_gid; -+ -+ /* struct cred *cred = get_task_cred(current); */ -+ struct cred *cred = (struct cred *)get_current_cred(); -+ -+ mm_segment_t orig_fs = get_fs(); -+ -+ if (*ppPatch) { -+ WMT_WARN_FUNC("f/w patch already exists\n"); -+ if ((*ppPatch)->data) -+ vfree((*ppPatch)->data); -+ -+ kfree(*ppPatch); -+ *ppPatch = NULL; -+ } -+ -+ if (!osal_strlen(pPatchName)) { -+ WMT_ERR_FUNC("empty f/w name\n"); -+ osal_assert((osal_strlen(pPatchName) > 0)); -+ return -1; -+ } -+ -+ pfw = kzalloc(sizeof(osal_firmware), /*GFP_KERNEL */ GFP_ATOMIC); -+ if (!pfw) { -+ WMT_ERR_FUNC("kzalloc(%d) fail\n", sizeof(osal_firmware)); -+ return -2; -+ } -+ -+ orig_uid = cred->fsuid.val; -+ orig_gid = cred->fsgid.val; -+ cred->fsuid.val = cred->fsgid.val = 0; -+ -+ set_fs(get_ds()); -+ -+ /* load patch file from fs */ -+ iRet = wmt_dev_read_file(pPatchName, (const PPUINT8)&pfw->data, 0, padSzBuf); -+ set_fs(orig_fs); -+ -+ cred->fsuid.val = orig_uid; -+ cred->fsgid.val = orig_gid; -+ -+ -+ if (iRet > 0) { -+ pfw->size = iRet; -+ *ppPatch = pfw; -+ WMT_DBG_FUNC("load (%s) to addr(0x%p) success\n", pPatchName, pfw->data); -+ return 0; -+ } -+ kfree(pfw); -+ *ppPatch = NULL; -+ WMT_ERR_FUNC("load file (%s) fail, iRet(%d)\n", pPatchName, iRet); -+ return -1; -+} -+ -+INT32 wmt_dev_patch_put(osal_firmware **ppPatch) -+{ -+ if (NULL != *ppPatch) { -+ if ((*ppPatch)->data) -+ vfree((*ppPatch)->data); -+ -+ kfree(*ppPatch); -+ *ppPatch = NULL; -+ } -+ return 0; -+} -+ -+VOID wmt_dev_patch_info_free(VOID) -+{ -+ -+ kfree(pPatchInfo); -+ pPatchInfo = NULL; -+ -+} -+ -+MTK_WCN_BOOL wmt_dev_is_file_exist(PUINT8 pFileName) -+{ -+ struct file *fd = NULL; -+ /* ssize_t iRet; */ -+ INT32 fileLen = -1; -+ const struct cred *cred = get_current_cred(); -+ -+ if (pFileName == NULL) { -+ WMT_ERR_FUNC("invalid file name pointer(%p)\n", pFileName); -+ return MTK_WCN_BOOL_FALSE; -+ } -+ if (osal_strlen(pFileName) < osal_strlen(defaultPatchName)) { -+ WMT_ERR_FUNC("invalid file name(%s)\n", pFileName); -+ return MTK_WCN_BOOL_FALSE; -+ } -+ /* struct cred *cred = get_task_cred(current); */ -+ -+ fd = filp_open(pFileName, O_RDONLY, 0); -+ if (!fd || IS_ERR(fd) || !fd->f_op || !fd->f_op->read) { -+ WMT_ERR_FUNC("failed to open or read(%s)!(0x%p, %d, %d)\n", pFileName, fd, cred->fsuid, cred->fsgid); -+ return MTK_WCN_BOOL_FALSE; -+ } -+ fileLen = fd->f_path.dentry->d_inode->i_size; -+ filp_close(fd, NULL); -+ fd = NULL; -+ if (fileLen <= 0) { -+ WMT_ERR_FUNC("invalid file(%s), length(%d)\n", pFileName, fileLen); -+ return MTK_WCN_BOOL_FALSE; -+ } -+ WMT_ERR_FUNC("valid file(%s), length(%d)\n", pFileName, fileLen); -+ return true; -+ -+} -+ -+/* static unsigned long count_last_access_sdio = 0; */ -+static unsigned long count_last_access_btif; -+static unsigned long jiffies_last_poll; -+ -+#if 0 -+static INT32 wmt_dev_tra_sdio_update(void) -+{ -+ count_last_access_sdio += 1; -+ /* WMT_INFO_FUNC("jiffies_last_access_sdio: jiffies = %ul\n", jiffies); */ -+ -+ return 0; -+} -+#endif -+ -+extern INT32 wmt_dev_tra_bitf_update(void) -+{ -+ count_last_access_btif += 1; -+ /* WMT_INFO_FUNC("jiffies_last_access_btif: jiffies = %ul\n", jiffies); */ -+ -+ return 0; -+} -+ -+static UINT32 wmt_dev_tra_ahb_poll(void) -+{ -+#define TIME_THRESHOLD_TO_TEMP_QUERY 3000 -+#define COUNT_THRESHOLD_TO_TEMP_QUERY 200 -+ -+ unsigned long ahb_during_count = 0; -+ unsigned long poll_during_time = 0; -+ -+ /* if (jiffies > jiffies_last_poll) */ -+ if (time_after(jiffies, jiffies_last_poll)) -+ poll_during_time = jiffies - jiffies_last_poll; -+ else -+ poll_during_time = 0xffffffff; -+ -+ -+ WMT_DBG_FUNC("**jiffies_to_mesecs(0xffffffff) = %lu\n", jiffies_to_msecs(0xffffffff)); -+ -+ if (jiffies_to_msecs(poll_during_time) < TIME_THRESHOLD_TO_TEMP_QUERY) { -+ WMT_DBG_FUNC("**poll_during_time = %lu < %lu, not to query\n", -+ jiffies_to_msecs(poll_during_time), TIME_THRESHOLD_TO_TEMP_QUERY); -+ return -1; -+ } -+ /* ahb_during_count = count_last_access_sdio; */ -+ if (NULL == mtk_wcn_wlan_bus_tx_cnt) { -+ WMT_ERR_FUNC("WMT-DEV:mtk_wcn_wlan_bus_tx_cnt null pointer\n"); -+ return -1; -+ } -+ ahb_during_count = (*mtk_wcn_wlan_bus_tx_cnt) (); -+ -+ if (ahb_during_count < COUNT_THRESHOLD_TO_TEMP_QUERY) { -+ WMT_DBG_FUNC("**ahb_during_count = %lu < %lu, not to query\n", -+ ahb_during_count, COUNT_THRESHOLD_TO_TEMP_QUERY); -+ return -2; -+ } -+ -+ if (NULL == mtk_wcn_wlan_bus_tx_cnt_clr) { -+ WMT_ERR_FUNC("WMT-DEV:mtk_wcn_wlan_bus_tx_cnt_clr null pointer\n"); -+ return -3; -+ } -+ (*mtk_wcn_wlan_bus_tx_cnt_clr) (); -+ /* count_last_access_sdio = 0; */ -+ jiffies_last_poll = jiffies; -+ -+ WMT_INFO_FUNC("**poll_during_time = %lu > %lu, ahb_during_count = %lu > %lu, query\n", -+ jiffies_to_msecs(poll_during_time), TIME_THRESHOLD_TO_TEMP_QUERY, -+ jiffies_to_msecs(ahb_during_count), COUNT_THRESHOLD_TO_TEMP_QUERY); -+ -+ return 0; -+} -+ -+long wmt_dev_tm_temp_query(void) -+{ -+#define HISTORY_NUM 5 -+#define TEMP_THRESHOLD 65 -+#define REFRESH_TIME 300 /* sec */ -+ -+ static INT32 temp_table[HISTORY_NUM] = { 99 }; /* not query yet. */ -+ static INT32 idx_temp_table; -+ static struct timeval query_time, now_time; -+ -+ INT8 query_cond = 0; -+ INT32 current_temp = 0; -+ INT32 index = 0; -+ long return_temp = 0; -+ /* Query condition 1: */ -+ /* If we have the high temperature records on the past, we continue to query/monitor */ -+ /* the real temperature until cooling */ -+ for (index = 0; index < HISTORY_NUM; index++) { -+ if (temp_table[index] >= TEMP_THRESHOLD) { -+ query_cond = 1; -+ WMT_DBG_FUNC("temperature table is still initial value, we should query temp temperature..\n"); -+ } -+ } -+ -+ do_gettimeofday(&now_time); -+#if 1 -+ /* Query condition 2: */ -+ /* Moniter the ahb bus activity to decide if we have the need to query temperature. */ -+ if (!query_cond) { -+ if (wmt_dev_tra_ahb_poll() == 0) { -+ query_cond = 1; -+ WMT_INFO_FUNC("ahb traffic , we must query temperature..\n"); -+ } else { -+ WMT_DBG_FUNC("ahb idle traffic ....\n"); -+ } -+ -+ /* only WIFI tx power might make temperature varies largely */ -+#if 0 -+ if (!query_cond) { -+ last_access_time = wmt_dev_tra_uart_poll(); -+ if (jiffies_to_msecs(last_access_time) < TIME_THRESHOLD_TO_TEMP_QUERY) { -+ query_cond = 1; -+ WMT_DBG_FUNC("uart busy traffic , we must query temperature..\n"); -+ } else { -+ WMT_DBG_FUNC("uart still idle traffic , we don't query temp temperature..\n"); -+ } -+ } -+#endif -+ } -+#endif -+ /* Query condition 3: */ -+ /* If the query time exceeds the a certain of period, refresh temp table. */ -+ /* */ -+ if (!query_cond) { -+ /* time overflow, we refresh temp table again for simplicity! */ -+ if ((now_time.tv_sec < query_time.tv_sec) || -+ ((now_time.tv_sec > query_time.tv_sec) && (now_time.tv_sec - query_time.tv_sec) > REFRESH_TIME)) { -+ query_cond = 1; -+ -+ WMT_INFO_FUNC("It is long time (> %d sec) not to query, we must query temp temperature..\n", -+ REFRESH_TIME); -+ for (index = 0; index < HISTORY_NUM; index++) -+ temp_table[index] = 99; -+ -+ } -+ } -+ -+ if (query_cond) { -+ /* update the temperature record */ -+ mtk_wcn_wmt_therm_ctrl(WMTTHERM_ENABLE); -+ current_temp = mtk_wcn_wmt_therm_ctrl(WMTTHERM_READ); -+ mtk_wcn_wmt_therm_ctrl(WMTTHERM_DISABLE); -+ idx_temp_table = (idx_temp_table + 1) % HISTORY_NUM; -+ temp_table[idx_temp_table] = current_temp; -+ do_gettimeofday(&query_time); -+ -+ WMT_INFO_FUNC("[Thermal] current_temp = 0x%x\n", (current_temp & 0xFF)); -+ } else { -+ current_temp = temp_table[idx_temp_table]; -+ idx_temp_table = (idx_temp_table + 1) % HISTORY_NUM; -+ temp_table[idx_temp_table] = current_temp; -+ } -+ -+ /* */ -+ /* Dump information */ -+ /* */ -+ WMT_DBG_FUNC("[Thermal] idx_temp_table = %d\n", idx_temp_table); -+ WMT_DBG_FUNC("[Thermal] now.time = %d, query.time = %d, REFRESH_TIME = %d\n", now_time.tv_sec, -+ query_time.tv_sec, REFRESH_TIME); -+ -+ WMT_DBG_FUNC("[0] = %d, [1] = %d, [2] = %d, [3] = %d, [4] = %d\n----\n", -+ temp_table[0], temp_table[1], temp_table[2], temp_table[3], temp_table[4]); -+ -+ return_temp = ((current_temp & 0x80) == 0x0) ? current_temp : (-1) * (current_temp & 0x7f); -+ -+ return return_temp; -+} -+ -+ssize_t WMT_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos) -+{ -+ INT32 iRet = 0; -+ UINT8 wrBuf[NAME_MAX + 1] = { 0 }; -+ INT32 copySize = (count < NAME_MAX) ? count : NAME_MAX; -+ -+ WMT_LOUD_FUNC("count:%d copySize:%d\n", count, copySize); -+ -+ if (copySize > 0) { -+ if (copy_from_user(wrBuf, buf, copySize)) { -+ iRet = -EFAULT; -+ goto write_done; -+ } -+ iRet = copySize; -+ wrBuf[NAME_MAX] = '\0'; -+ -+ if (!strncasecmp(wrBuf, "ok", NAME_MAX)) { -+ WMT_DBG_FUNC("resp str ok\n"); -+ /* pWmtDevCtx->cmd_result = 0; */ -+ wmt_lib_trigger_cmd_signal(0); -+ } else { -+ WMT_WARN_FUNC("warning resp str (%s)\n", wrBuf); -+ /* pWmtDevCtx->cmd_result = -1; */ -+ wmt_lib_trigger_cmd_signal(-1); -+ } -+ /* complete(&pWmtDevCtx->cmd_comp); */ -+ -+ } -+ -+write_done: -+ return iRet; -+} -+ -+ssize_t WMT_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos) -+{ -+ INT32 iRet = 0; -+ PUINT8 pCmd = NULL; -+ UINT32 cmdLen = 0; -+ -+ pCmd = wmt_lib_get_cmd(); -+ -+ if (pCmd != NULL) { -+ cmdLen = osal_strlen(pCmd) < NAME_MAX ? osal_strlen(pCmd) : NAME_MAX; -+ WMT_DBG_FUNC("cmd str(%s)\n", pCmd); -+ if (copy_to_user(buf, pCmd, cmdLen)) -+ iRet = -EFAULT; -+ else -+ iRet = cmdLen; -+ -+ } -+#if 0 -+ if (test_and_clear_bit(WMT_STAT_CMD, &pWmtDevCtx->state)) { -+ iRet = osal_strlen(localBuf) < NAME_MAX ? osal_strlen(localBuf) : NAME_MAX; -+ /* we got something from STP driver */ -+ WMT_DBG_FUNC("copy cmd to user by read:%s\n", localBuf); -+ if (copy_to_user(buf, localBuf, iRet)) { -+ iRet = -EFAULT; -+ goto read_done; -+ } -+ } -+#endif -+ return iRet; -+} -+ -+unsigned int WMT_poll(struct file *filp, poll_table *wait) -+{ -+ UINT32 mask = 0; -+ P_OSAL_EVENT pEvent = wmt_lib_get_cmd_event(); -+ -+ poll_wait(filp, &pEvent->waitQueue, wait); -+ /* empty let select sleep */ -+ if (MTK_WCN_BOOL_TRUE == wmt_lib_get_cmd_status()) -+ mask |= POLLIN | POLLRDNORM; /* readable */ -+ -+#if 0 -+ if (test_bit(WMT_STAT_CMD, &pWmtDevCtx->state)) -+ mask |= POLLIN | POLLRDNORM; /* readable */ -+ -+#endif -+ mask |= POLLOUT | POLLWRNORM; /* writable */ -+ return mask; -+} -+ -+/* INT32 WMT_ioctl(struct inode *inode, struct file *filp, UINT32 cmd, unsigned long arg) */ -+long WMT_unlocked_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) -+{ -+ -+ INT32 iRet = 0; -+ UINT8 *pBuffer = NULL; -+ -+ WMT_DBG_FUNC("cmd (%u), arg (0x%lx)\n", cmd, arg); -+ switch (cmd) { -+ case WMT_IOCTL_SET_PATCH_NAME: /* patch location */ -+ { -+ -+ pBuffer = kmalloc(NAME_MAX + 1, GFP_KERNEL); -+ if (!pBuffer) { -+ WMT_ERR_FUNC("pBuffer kmalloc memory fail\n"); -+ return 0; -+ } -+ if (copy_from_user(pBuffer, (void *)arg, NAME_MAX)) { -+ iRet = -EFAULT; -+ kfree(pBuffer); -+ break; -+ } -+ pBuffer[NAME_MAX] = '\0'; -+ wmt_lib_set_patch_name(pBuffer); -+ kfree(pBuffer); -+ } -+ break; -+ -+ case WMT_IOCTL_SET_STP_MODE: /* stp/hif/fm mode */ -+ -+ /* set hif conf */ -+ do { -+ P_OSAL_OP pOp; -+ MTK_WCN_BOOL bRet; -+ P_OSAL_SIGNAL pSignal = NULL; -+ P_WMT_HIF_CONF pHif = NULL; -+ -+ iRet = wmt_lib_set_hif(arg); -+ if (0 != iRet) { -+ WMT_INFO_FUNC("wmt_lib_set_hif fail\n"); -+ break; -+ } -+ -+ pOp = wmt_lib_get_free_op(); -+ if (!pOp) { -+ WMT_INFO_FUNC("get_free_lxop fail\n"); -+ break; -+ } -+ pSignal = &pOp->signal; -+ pOp->op.opId = WMT_OPID_HIF_CONF; -+ -+ pHif = wmt_lib_get_hif(); -+ -+ osal_memcpy(&pOp->op.au4OpData[0], pHif, sizeof(WMT_HIF_CONF)); -+ pOp->op.u4InfoBit = WMT_OP_HIF_BIT; -+ pSignal->timeoutValue = 0; -+ -+ bRet = wmt_lib_put_act_op(pOp); -+ WMT_DBG_FUNC("WMT_OPID_HIF_CONF result(%d)\n", bRet); -+ iRet = (MTK_WCN_BOOL_FALSE == bRet) ? -EFAULT : 0; -+ } while (0); -+ -+ break; -+ -+ case WMT_IOCTL_FUNC_ONOFF_CTRL: /* test turn on/off func */ -+ -+ do { -+ MTK_WCN_BOOL bRet = MTK_WCN_BOOL_FALSE; -+ -+ if (arg & 0x80000000) -+ bRet = mtk_wcn_wmt_func_on(arg & 0xF); -+ else -+ bRet = mtk_wcn_wmt_func_off(arg & 0xF); -+ -+ iRet = (MTK_WCN_BOOL_FALSE == bRet) ? -EFAULT : 0; -+ } while (0); -+ -+ break; -+ -+ case WMT_IOCTL_LPBK_POWER_CTRL: -+ /*switch Loopback function on/off -+ arg: bit0 = 1:turn loopback function on -+ bit0 = 0:turn loopback function off -+ */ -+ do { -+ MTK_WCN_BOOL bRet = MTK_WCN_BOOL_FALSE; -+ -+ if (arg & 0x01) -+ bRet = mtk_wcn_wmt_func_on(WMTDRV_TYPE_LPBK); -+ else -+ bRet = mtk_wcn_wmt_func_off(WMTDRV_TYPE_LPBK); -+ -+ iRet = (MTK_WCN_BOOL_FALSE == bRet) ? -EFAULT : 0; -+ } while (0); -+ -+ break; -+ -+ case WMT_IOCTL_LPBK_TEST: -+ do { -+ P_OSAL_OP pOp; -+ MTK_WCN_BOOL bRet; -+ UINT32 u4Wait; -+ /* UINT8 lpbk_buf[1024] = {0}; */ -+ UINT32 effectiveLen = 0; -+ P_OSAL_SIGNAL pSignal = NULL; -+ -+ if (copy_from_user(&effectiveLen, (void *)arg, sizeof(effectiveLen))) { -+ iRet = -EFAULT; -+ WMT_ERR_FUNC("copy_from_user failed at %d\n", __LINE__); -+ break; -+ } -+ if (effectiveLen > sizeof(gLpbkBuf)) { -+ iRet = -EFAULT; -+ WMT_ERR_FUNC("length is too long\n"); -+ break; -+ } -+ WMT_DBG_FUNC("len = %d\n", effectiveLen); -+ -+ pOp = wmt_lib_get_free_op(); -+ if (!pOp) { -+ WMT_WARN_FUNC("get_free_lxop fail\n"); -+ iRet = -EFAULT; -+ break; -+ } -+ u4Wait = 2000; -+ if (copy_from_user(&gLpbkBuf[0], (void *)arg + sizeof(unsigned long), effectiveLen)) { -+ WMT_ERR_FUNC("copy_from_user failed at %d\n", __LINE__); -+ iRet = -EFAULT; -+ break; -+ } -+ pSignal = &pOp->signal; -+ pOp->op.opId = WMT_OPID_LPBK; -+ pOp->op.au4OpData[0] = effectiveLen; /* packet length */ -+ pOp->op.au4OpData[1] = (SIZE_T) &gLpbkBuf[0]; /* packet buffer pointer */ -+ memcpy(&gLpbkBufLog, &gLpbkBuf[((effectiveLen >= 4) ? effectiveLen - 4 : 0)], 4); -+ pSignal->timeoutValue = MAX_EACH_WMT_CMD; -+ WMT_INFO_FUNC("OPID(%d) type(%d) start\n", pOp->op.opId, pOp->op.au4OpData[0]); -+ if (DISABLE_PSM_MONITOR()) { -+ WMT_ERR_FUNC("wake up failed,OPID(%d) type(%d) abort\n", -+ pOp->op.opId, pOp->op.au4OpData[0]); -+ wmt_lib_put_op_to_free_queue(pOp); -+ return -1; -+ } -+ -+ bRet = wmt_lib_put_act_op(pOp); -+ ENABLE_PSM_MONITOR(); -+ if (MTK_WCN_BOOL_FALSE == bRet) { -+ WMT_WARN_FUNC("OPID(%d) type(%d) buf tail(0x%08x) fail\n", -+ pOp->op.opId, pOp->op.au4OpData[0], gLpbkBufLog); -+ iRet = -1; -+ break; -+ } -+ WMT_INFO_FUNC("OPID(%d) length(%d) ok\n", pOp->op.opId, pOp->op.au4OpData[0]); -+ iRet = pOp->op.au4OpData[0]; -+ if (copy_to_user((void *)arg + sizeof(SIZE_T) + sizeof(UINT8[2048]), gLpbkBuf, iRet)) { -+ iRet = -EFAULT; -+ break; -+ } -+ -+ } while (0); -+ -+ break; -+ -+ case WMT_IOCTL_ADIE_LPBK_TEST: -+ do { -+ P_OSAL_OP pOp; -+ MTK_WCN_BOOL bRet; -+ P_OSAL_SIGNAL pSignal = NULL; -+ -+ pOp = wmt_lib_get_free_op(); -+ if (!pOp) { -+ WMT_WARN_FUNC("get_free_lxop fail\n"); -+ iRet = -EFAULT; -+ break; -+ } -+ -+ pSignal = &pOp->signal; -+ pOp->op.opId = WMT_OPID_ADIE_LPBK_TEST; -+ pOp->op.au4OpData[0] = 0; -+ pOp->op.au4OpData[1] = (SIZE_T) &gLpbkBuf[0]; -+ pSignal->timeoutValue = MAX_EACH_WMT_CMD; -+ WMT_INFO_FUNC("OPID(%d) start\n", pOp->op.opId); -+ if (DISABLE_PSM_MONITOR()) { -+ WMT_ERR_FUNC("wake up failed,OPID(%d)abort\n", pOp->op.opId); -+ wmt_lib_put_op_to_free_queue(pOp); -+ return -1; -+ } -+ -+ bRet = wmt_lib_put_act_op(pOp); -+ ENABLE_PSM_MONITOR(); -+ if (MTK_WCN_BOOL_FALSE == bRet) { -+ WMT_WARN_FUNC("OPID(%d) fail\n", pOp->op.opId); -+ iRet = -1; -+ break; -+ } -+ WMT_INFO_FUNC("OPID(%d) length(%d) ok\n", pOp->op.opId, pOp->op.au4OpData[0]); -+ iRet = pOp->op.au4OpData[0]; -+ if (copy_to_user((void *)arg + sizeof(SIZE_T), gLpbkBuf, iRet)) { -+ iRet = -EFAULT; -+ break; -+ } -+ -+ } while (0); -+ -+ break; -+ -+ case 10: -+ { -+ pBuffer = kmalloc(NAME_MAX + 1, GFP_KERNEL); -+ if (!pBuffer) { -+ WMT_ERR_FUNC("pBuffer kmalloc memory fail\n"); -+ return 0; -+ } -+ wmt_lib_host_awake_get(); -+ mtk_wcn_stp_coredump_start_ctrl(1); -+ osal_strcpy(pBuffer, "MT662x f/w coredump start-"); -+ if (copy_from_user -+ (pBuffer + osal_strlen(pBuffer), (void *)arg, NAME_MAX - osal_strlen(pBuffer))) { -+ /* osal_strcpy(pBuffer, "MT662x f/w assert core dump start"); */ -+ WMT_ERR_FUNC("copy assert string failed\n"); -+ } -+ pBuffer[NAME_MAX] = '\0'; -+ osal_dbg_assert_aee(pBuffer, pBuffer); -+ kfree(pBuffer); -+ } -+ break; -+ case 11: -+ { -+ osal_dbg_assert_aee("MT662x f/w coredump end", "MT662x firmware coredump ends"); -+ wmt_lib_host_awake_put(); -+ } -+ break; -+ -+ case WMT_IOCTL_GET_CHIP_INFO: -+ { -+ if (0 == arg) -+ return wmt_lib_get_icinfo(WMTCHIN_CHIPID); -+ else if (1 == arg) -+ return wmt_lib_get_icinfo(WMTCHIN_HWVER); -+ else if (2 == arg) -+ return wmt_lib_get_icinfo(WMTCHIN_FWVER); -+ -+ } -+ break; -+ -+ case WMT_IOCTL_SET_LAUNCHER_KILL:{ -+ if (1 == arg) { -+ WMT_INFO_FUNC("launcher may be killed,block abnormal stp tx.\n"); -+ wmt_lib_set_stp_wmt_last_close(1); -+ } else { -+ wmt_lib_set_stp_wmt_last_close(0); -+ } -+ -+ } -+ break; -+ -+ case WMT_IOCTL_SET_PATCH_NUM:{ -+ pAtchNum = arg; -+ WMT_DBG_FUNC(" get patch num from launcher = %d\n", pAtchNum); -+ wmt_lib_set_patch_num(pAtchNum); -+ pPatchInfo = kcalloc(pAtchNum, sizeof(WMT_PATCH_INFO), GFP_ATOMIC); -+ if (!pPatchInfo) { -+ WMT_ERR_FUNC("allocate memory fail!\n"); -+ break; -+ } -+ } -+ break; -+ -+ case WMT_IOCTL_SET_PATCH_INFO:{ -+ WMT_PATCH_INFO wMtPatchInfo; -+ P_WMT_PATCH_INFO pTemp = NULL; -+ UINT32 dWloadSeq; -+ static UINT32 counter; -+ -+ if (!pPatchInfo) { -+ WMT_ERR_FUNC("NULL patch info pointer\n"); -+ break; -+ } -+ -+ if (copy_from_user(&wMtPatchInfo, (void *)arg, sizeof(WMT_PATCH_INFO))) { -+ WMT_ERR_FUNC("copy_from_user failed at %d\n", __LINE__); -+ iRet = -EFAULT; -+ break; -+ } -+ -+ dWloadSeq = wMtPatchInfo.dowloadSeq; -+ WMT_DBG_FUNC( -+ "patch dl seq %d,name %s,address info 0x%02x,0x%02x,0x%02x,0x%02x\n", -+ dWloadSeq, wMtPatchInfo.patchName, -+ wMtPatchInfo.addRess[0], -+ wMtPatchInfo.addRess[1], -+ wMtPatchInfo.addRess[2], -+ wMtPatchInfo.addRess[3]); -+ osal_memcpy(pPatchInfo + dWloadSeq - 1, &wMtPatchInfo, sizeof(WMT_PATCH_INFO)); -+ pTemp = pPatchInfo + dWloadSeq - 1; -+ if (++counter == pAtchNum) { -+ wmt_lib_set_patch_info(pPatchInfo); -+ counter = 0; -+ } -+ } -+ break; -+ -+ case WMT_IOCTL_WMT_COREDUMP_CTRL: -+ mtk_wcn_stp_coredump_flag_ctrl(arg); -+ break; -+ case WMT_IOCTL_WMT_QUERY_CHIPID: -+ { -+ iRet = mtk_wcn_wmt_chipid_query(); -+ WMT_WARN_FUNC("chipid = 0x%x\n", iRet); -+ } -+ break; -+ case WMT_IOCTL_SEND_BGW_DS_CMD: -+ do { -+ P_OSAL_OP pOp; -+ MTK_WCN_BOOL bRet; -+ UINT8 desense_buf[14] = { 0 }; -+ UINT32 effectiveLen = 14; -+ P_OSAL_SIGNAL pSignal = NULL; -+ -+ pOp = wmt_lib_get_free_op(); -+ if (!pOp) { -+ WMT_WARN_FUNC("get_free_lxop fail\n"); -+ iRet = -EFAULT; -+ break; -+ } -+ if (copy_from_user(&desense_buf[0], (void *)arg, effectiveLen)) { -+ WMT_ERR_FUNC("copy_from_user failed at %d\n", __LINE__); -+ iRet = -EFAULT; -+ break; -+ } -+ pSignal = &pOp->signal; -+ pOp->op.opId = WMT_OPID_BGW_DS; -+ pOp->op.au4OpData[0] = effectiveLen; /* packet length */ -+ pOp->op.au4OpData[1] = (SIZE_T) &desense_buf[0]; /* packet buffer pointer */ -+ pSignal->timeoutValue = MAX_EACH_WMT_CMD; -+ WMT_INFO_FUNC("OPID(%d) start\n", pOp->op.opId); -+ if (DISABLE_PSM_MONITOR()) { -+ WMT_ERR_FUNC("wake up failed,opid(%d) abort\n", pOp->op.opId); -+ wmt_lib_put_op_to_free_queue(pOp); -+ return -1; -+ } -+ -+ bRet = wmt_lib_put_act_op(pOp); -+ ENABLE_PSM_MONITOR(); -+ if (MTK_WCN_BOOL_FALSE == bRet) { -+ WMT_WARN_FUNC("OPID(%d) fail\n", pOp->op.opId); -+ iRet = -1; -+ break; -+ } -+ WMT_INFO_FUNC("OPID(%d) length(%d) ok\n", pOp->op.opId, pOp->op.au4OpData[0]); -+ iRet = pOp->op.au4OpData[0]; -+ -+ } while (0); -+ -+ break; -+ case WMT_IOCTL_FW_DBGLOG_CTRL: -+ { -+ iRet = wmt_plat_set_dbg_mode(arg); -+ if (iRet == 0) -+ wmt_dbg_fwinfor_from_emi(0, 1, 0); -+ } -+ break; -+ case WMT_IOCTL_DYNAMIC_DUMP_CTRL: -+ { -+ UINT32 i = 0, j = 0, k = 0; -+ UINT8 *pBuf = NULL; -+ UINT32 int_buf[10]; -+ char Buffer[10][11]; -+ -+ pBuf = kmalloc(DYNAMIC_DUMP_BUF + 1, GFP_KERNEL); -+ if (!pBuf) { -+ WMT_ERR_FUNC("pBuf kmalloc memory fail\n"); -+ return 0; -+ } -+ if (copy_from_user(pBuf, (void *)arg, DYNAMIC_DUMP_BUF)) { -+ iRet = -EFAULT; -+ kfree(pBuf); -+ break; -+ } -+ pBuf[DYNAMIC_DUMP_BUF] = '\0'; -+ WMT_INFO_FUNC("get dynamic dump data from property(%s)\n", pBuf); -+ memset(Buffer, 0, 10*11); -+ for (i = 0; i < DYNAMIC_DUMP_BUF; i++) { -+ if (pBuf[i] == '/') { -+ k = 0; -+ j++; -+ } else { -+ Buffer[j][k] = pBuf[i]; -+ k++; -+ } -+ } -+ for (j = 0; j < 10; j++) { -+ iRet = kstrtou32(Buffer[j], 0, &int_buf[j]); -+ if (iRet) { -+ WMT_ERR_FUNC("string convert fail(%d)\n", iRet); -+ break; -+ } -+ WMT_INFO_FUNC("dynamic dump data buf[%d]:(0x%x)\n", j, int_buf[j]); -+ } -+ wmt_plat_set_dynamic_dumpmem(int_buf); -+ kfree(pBuf); -+ } -+ break; -+ default: -+ iRet = -EINVAL; -+ WMT_WARN_FUNC("unknown cmd (%d)\n", cmd); -+ break; -+ } -+ -+ return iRet; -+} -+#ifdef CONFIG_COMPAT -+long WMT_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) -+{ -+ long ret; -+ WMT_INFO_FUNC("cmd[0x%x]\n", cmd); -+ switch (cmd) { -+ case COMPAT_WMT_IOCTL_SET_PATCH_NAME: -+ ret = WMT_unlocked_ioctl(filp, WMT_IOCTL_SET_PATCH_NAME, (unsigned long)compat_ptr(arg)); -+ break; -+ case COMPAT_WMT_IOCTL_LPBK_TEST: -+ ret = WMT_unlocked_ioctl(filp, WMT_IOCTL_LPBK_TEST, (unsigned long)compat_ptr(arg)); -+ break; -+ case COMPAT_WMT_IOCTL_SET_PATCH_INFO: -+ ret = WMT_unlocked_ioctl(filp, WMT_IOCTL_SET_PATCH_INFO, (unsigned long)compat_ptr(arg)); -+ break; -+ case COMPAT_WMT_IOCTL_PORT_NAME: -+ ret = WMT_unlocked_ioctl(filp, WMT_IOCTL_PORT_NAME, (unsigned long)compat_ptr(arg)); -+ break; -+ case COMPAT_WMT_IOCTL_WMT_CFG_NAME: -+ ret = WMT_unlocked_ioctl(filp, WMT_IOCTL_WMT_CFG_NAME, (unsigned long)compat_ptr(arg)); -+ break; -+ case COMPAT_WMT_IOCTL_SEND_BGW_DS_CMD: -+ ret = WMT_unlocked_ioctl(filp, WMT_IOCTL_SEND_BGW_DS_CMD, (unsigned long)compat_ptr(arg)); -+ break; -+ default: { -+ ret = WMT_unlocked_ioctl(filp, cmd, arg); -+ break; -+ } -+ } -+ return ret; -+} -+#endif -+static int WMT_open(struct inode *inode, struct file *file) -+{ -+ long ret; -+ -+ WMT_INFO_FUNC("major %d minor %d (pid %d)\n", imajor(inode), iminor(inode), current->pid); -+ ret = wait_event_timeout(gWmtInitWq, gWmtInitDone != 0, msecs_to_jiffies(WMT_DEV_INIT_TO_MS)); -+ if (!ret) { -+ WMT_WARN_FUNC("wait_event_timeout (%d)ms,(%d)jiffies,return -EIO\n", -+ WMT_DEV_INIT_TO_MS, msecs_to_jiffies(WMT_DEV_INIT_TO_MS)); -+ return -EIO; -+ } -+ -+ if (atomic_inc_return(&gWmtRefCnt) == 1) -+ WMT_INFO_FUNC("1st call\n"); -+ -+ return 0; -+} -+ -+static int WMT_close(struct inode *inode, struct file *file) -+{ -+ WMT_INFO_FUNC("major %d minor %d (pid %d)\n", imajor(inode), iminor(inode), current->pid); -+ -+ if (atomic_dec_return(&gWmtRefCnt) == 0) -+ WMT_INFO_FUNC("last call\n"); -+ -+ return 0; -+} -+ -+const struct file_operations gWmtFops = { -+ .open = WMT_open, -+ .release = WMT_close, -+ .read = WMT_read, -+ .write = WMT_write, -+/* .ioctl = WMT_ioctl, */ -+ .unlocked_ioctl = WMT_unlocked_ioctl, -+#ifdef CONFIG_COMPAT -+ .compat_ioctl = WMT_compat_ioctl, -+#endif -+ .poll = WMT_poll, -+}; -+ -+void wmt_dev_bgw_desense_init(VOID) -+{ -+ bgw_init_socket(); -+} -+ -+void wmt_dev_bgw_desense_deinit(VOID) -+{ -+ bgw_destroy_netlink_kernel(); -+} -+ -+void wmt_dev_send_cmd_to_daemon(UINT32 cmd) -+{ -+ send_command_to_daemon(cmd); -+} -+ -+static int WMT_init(void) -+{ -+ dev_t devID = MKDEV(gWmtMajor, 0); -+ INT32 cdevErr = -1; -+ INT32 ret = -1; -+ -+ WMT_INFO_FUNC("WMT Version= %s DATE=%s\n", MTK_WMT_VERSION, MTK_WMT_DATE); -+ /* Prepare a UINT8 device */ -+ /*static allocate chrdev */ -+ gWmtInitDone = 0; -+ init_waitqueue_head((wait_queue_head_t *) &gWmtInitWq); -+ stp_drv_init(); -+ -+ ret = register_chrdev_region(devID, WMT_DEV_NUM, WMT_DRIVER_NAME); -+ if (ret) { -+ WMT_ERR_FUNC("fail to register chrdev\n"); -+ return ret; -+ } -+ cdev_init(&gWmtCdev, &gWmtFops); -+ gWmtCdev.owner = THIS_MODULE; -+ cdevErr = cdev_add(&gWmtCdev, devID, WMT_DEV_NUM); -+ if (cdevErr) { -+ WMT_ERR_FUNC("cdev_add() fails (%d)\n", cdevErr); -+ goto error; -+ } -+ WMT_INFO_FUNC("driver(major %d) installed\n", gWmtMajor); -+#if WMT_CREATE_NODE_DYNAMIC -+ wmt_class = class_create(THIS_MODULE, "stpwmt"); -+ if (IS_ERR(wmt_class)) -+ goto error; -+ wmt_dev = device_create(wmt_class, NULL, devID, NULL, "stpwmt"); -+ if (IS_ERR(wmt_dev)) -+ goto error; -+#endif -+ -+#if 0 -+ pWmtDevCtx = wmt_drv_create(); -+ if (!pWmtDevCtx) { -+ WMT_ERR_FUNC("wmt_drv_create() fails\n"); -+ goto error; -+ } -+ ret = wmt_drv_init(pWmtDevCtx); -+ if (ret) { -+ WMT_ERR_FUNC("wmt_drv_init() fails (%d)\n", ret); -+ goto error; -+ } -+ WMT_INFO_FUNC("stp_btmcb_reg\n"); -+ wmt_cdev_btmcb_reg(); -+ ret = wmt_drv_start(pWmtDevCtx); -+ if (ret) { -+ WMT_ERR_FUNC("wmt_drv_start() fails (%d)\n", ret); -+ goto error; -+ } -+#endif -+ ret = wmt_lib_init(); -+ if (ret) { -+ WMT_ERR_FUNC("wmt_lib_init() fails (%d)\n", ret); -+ goto error; -+ } -+#if CFG_WMT_DBG_SUPPORT -+ wmt_dev_dbg_setup(); -+#endif -+ -+#if CFG_WMT_PROC_FOR_AEE -+ wmt_dev_proc_for_aee_setup(); -+#endif -+ -+ WMT_INFO_FUNC("wmt_dev register thermal cb\n"); -+ wmt_lib_register_thermal_ctrl_cb(wmt_dev_tm_temp_query); -+ wmt_dev_bgw_desense_init(); -+ gWmtInitDone = 1; -+ wake_up(&gWmtInitWq); -+ osal_sleepable_lock_init(&g_es_lr_lock); -+ INIT_WORK(&gPwrOnOffWork, wmt_pwr_on_off_handler); -+#ifdef CONFIG_EARLYSUSPEND -+ register_early_suspend(&wmt_early_suspend_handler); -+ WMT_INFO_FUNC("register_early_suspend finished\n"); -+#else -+ wmt_fb_notifier.notifier_call = wmt_fb_notifier_callback; -+ ret = fb_register_client(&wmt_fb_notifier); -+ if (ret) -+ WMT_ERR_FUNC("wmt register fb_notifier failed! ret(%d)\n", ret); -+ else -+ WMT_INFO_FUNC("wmt register fb_notifier OK!\n"); -+#endif -+ WMT_INFO_FUNC("success\n"); -+ return 0; -+ -+error: -+ wmt_lib_deinit(); -+#if CFG_WMT_DBG_SUPPORT -+ wmt_dev_dbg_remove(); -+#endif -+#if WMT_CREATE_NODE_DYNAMIC -+ if (!(IS_ERR(wmt_dev))) -+ device_destroy(wmt_class, devID); -+ if (!(IS_ERR(wmt_class))) { -+ class_destroy(wmt_class); -+ wmt_class = NULL; -+ } -+#endif -+ -+ if (cdevErr == 0) -+ cdev_del(&gWmtCdev); -+ -+ if (ret == 0) { -+ unregister_chrdev_region(devID, WMT_DEV_NUM); -+ gWmtMajor = -1; -+ } -+ -+ WMT_ERR_FUNC("fail\n"); -+ -+ return -1; -+} -+ -+static void WMT_exit(void) -+{ -+ dev_t dev = MKDEV(gWmtMajor, 0); -+ -+ osal_sleepable_lock_deinit(&g_es_lr_lock); -+#ifdef CONFIG_EARLYSUSPEND -+ unregister_early_suspend(&wmt_early_suspend_handler); -+ WMT_INFO_FUNC("unregister_early_suspend finished\n"); -+#else -+ fb_unregister_client(&wmt_fb_notifier); -+#endif -+ -+ wmt_dev_bgw_desense_deinit(); -+ -+ wmt_lib_register_thermal_ctrl_cb(NULL); -+ -+ wmt_lib_deinit(); -+ -+#if CFG_WMT_DBG_SUPPORT -+ wmt_dev_dbg_remove(); -+#endif -+ -+#if CFG_WMT_PROC_FOR_AEE -+ wmt_dev_proc_for_aee_remove(); -+#endif -+#if WMT_CREATE_NODE_DYNAMIC -+ if (wmt_dev) { -+ device_destroy(wmt_class, dev); -+ wmt_dev = NULL; -+ } -+ if (wmt_class) { -+ class_destroy(wmt_class); -+ wmt_class = NULL; -+ } -+#endif -+ cdev_del(&gWmtCdev); -+ unregister_chrdev_region(dev, WMT_DEV_NUM); -+ gWmtMajor = -1; -+ -+ stp_drv_exit(); -+ -+ WMT_INFO_FUNC("done\n"); -+} -+ -+#ifdef MTK_WCN_REMOVE_KERNEL_MODULE -+ -+int mtk_wcn_soc_common_drv_init(void) -+{ -+ return WMT_init(); -+ -+} -+EXPORT_SYMBOL(mtk_wcn_soc_common_drv_init); -+void mtk_wcn_soc_common_drv_exit(void) -+{ -+ return WMT_exit(); -+} -+EXPORT_SYMBOL(mtk_wcn_soc_common_drv_exit); -+ -+#else -+module_init(WMT_init); -+module_exit(WMT_exit); -+#endif -+MODULE_LICENSE("GPL"); -+MODULE_AUTHOR("MediaTek Inc WCN"); -+MODULE_DESCRIPTION("MTK WCN combo driver for WMT function"); -+ -+module_param(gWmtMajor, uint, 0); -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/wmt_exp.c b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/wmt_exp.c -new file mode 100644 -index 000000000000..8d5c23732c1c ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pri/wmt_exp.c -@@ -0,0 +1,610 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -+ -+/*! \file -+ \brief Declaration of library functions -+ -+ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+#ifdef DFT_TAG -+#undef DFT_TAG -+#endif -+#define DFT_TAG "[WMT-EXP]" -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "osal_typedef.h" -+ -+#include -+#include -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+wmt_wlan_probe_cb mtk_wcn_wlan_probe = NULL; -+wmt_wlan_remove_cb mtk_wcn_wlan_remove = NULL; -+wmt_wlan_bus_cnt_get_cb mtk_wcn_wlan_bus_tx_cnt = NULL; -+wmt_wlan_bus_cnt_clr_cb mtk_wcn_wlan_bus_tx_cnt_clr = NULL; -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+OSAL_BIT_OP_VAR gBtWifiGpsState; -+OSAL_BIT_OP_VAR gGpsFmState; -+UINT32 gWifiProbed = 0; -+UINT32 gWmtDbgLvl = WMT_LOG_ERR; -+MTK_WCN_BOOL g_pwr_off_flag = MTK_WCN_BOOL_TRUE; -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+static MTK_WCN_BOOL mtk_wcn_wmt_func_ctrl(ENUM_WMTDRV_TYPE_T type, ENUM_WMT_OPID_T opId); -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+static MTK_WCN_BOOL mtk_wcn_wmt_func_ctrl(ENUM_WMTDRV_TYPE_T type, ENUM_WMT_OPID_T opId) -+{ -+ P_OSAL_OP pOp; -+ MTK_WCN_BOOL bRet; -+ P_OSAL_SIGNAL pSignal; -+ -+ pOp = wmt_lib_get_free_op(); -+ if (!pOp) { -+ WMT_WARN_FUNC("get_free_lxop fail\n"); -+ return MTK_WCN_BOOL_FALSE; -+ } -+ -+ pSignal = &pOp->signal; -+ -+ pOp->op.opId = opId; -+ pOp->op.au4OpData[0] = type; -+ if (WMTDRV_TYPE_WIFI == type) -+ pSignal->timeoutValue = 4000; -+ /*donot block system server/init/netd from longer than 5s, in case of ANR happens*/ -+ else -+ pSignal->timeoutValue = (WMT_OPID_FUNC_ON == pOp->op.opId) ? MAX_FUNC_ON_TIME : MAX_FUNC_OFF_TIME; -+ -+ WMT_INFO_FUNC("OPID(%d) type(%d) start\n", pOp->op.opId, pOp->op.au4OpData[0]); -+ -+ /*do not check return value, we will do this either way */ -+ wmt_lib_host_awake_get(); -+ /*wake up chip first */ -+ if (DISABLE_PSM_MONITOR()) { -+ WMT_ERR_FUNC("wake up failed,OPID(%d) type(%d) abort\n", pOp->op.opId, pOp->op.au4OpData[0]); -+ wmt_lib_put_op_to_free_queue(pOp); -+ wmt_lib_host_awake_put(); -+ return MTK_WCN_BOOL_FALSE; -+ } -+ -+ bRet = wmt_lib_put_act_op(pOp); -+ ENABLE_PSM_MONITOR(); -+ wmt_lib_host_awake_put(); -+ -+ if (MTK_WCN_BOOL_FALSE == bRet) -+ WMT_WARN_FUNC("OPID(%d) type(%d) fail\n", pOp->op.opId, pOp->op.au4OpData[0]); -+ else -+ WMT_WARN_FUNC("OPID(%d) type(%d) ok\n", pOp->op.opId, pOp->op.au4OpData[0]); -+ -+ return bRet; -+} -+ -+#if WMT_EXP_HID_API_EXPORT -+MTK_WCN_BOOL _mtk_wcn_wmt_func_off(ENUM_WMTDRV_TYPE_T type) -+#else -+MTK_WCN_BOOL mtk_wcn_wmt_func_off(ENUM_WMTDRV_TYPE_T type) -+#endif -+{ -+ MTK_WCN_BOOL ret; -+ -+ if (type == WMTDRV_TYPE_BT) -+ osal_printtimeofday("############ BT OFF ====>"); -+ -+ ret = mtk_wcn_wmt_func_ctrl(type, WMT_OPID_FUNC_OFF); -+ -+ if (type == WMTDRV_TYPE_BT) -+ osal_printtimeofday("############ BT OFF <===="); -+ -+ return ret; -+} -+#if !WMT_EXP_HID_API_EXPORT -+EXPORT_SYMBOL(mtk_wcn_wmt_func_off); -+#endif -+ -+#if WMT_EXP_HID_API_EXPORT -+MTK_WCN_BOOL _mtk_wcn_wmt_func_on(ENUM_WMTDRV_TYPE_T type) -+#else -+MTK_WCN_BOOL mtk_wcn_wmt_func_on(ENUM_WMTDRV_TYPE_T type) -+#endif -+{ -+ MTK_WCN_BOOL ret; -+ -+ if (type == WMTDRV_TYPE_BT) -+ osal_printtimeofday("############ BT ON ====>"); -+ -+ ret = mtk_wcn_wmt_func_ctrl(type, WMT_OPID_FUNC_ON); -+ -+ if (type == WMTDRV_TYPE_BT) -+ osal_printtimeofday(" ############BT ON <===="); -+ -+ return ret; -+} -+#if !WMT_EXP_HID_API_EXPORT -+EXPORT_SYMBOL(mtk_wcn_wmt_func_on); -+#endif -+ -+VOID mtk_wcn_wmt_func_ctrl_for_plat(UINT32 on, ENUM_WMTDRV_TYPE_T type) -+{ -+ if (on) -+ mtk_wcn_wmt_func_on(type); -+ else -+ mtk_wcn_wmt_func_off(type); -+} -+ -+/* -+return value: -+enable/disable thermal sensor function: true(1)/false(0) -+read thermal sensor function:thermal value -+ -+*/ -+#if WMT_EXP_HID_API_EXPORT -+INT8 _mtk_wcn_wmt_therm_ctrl(ENUM_WMTTHERM_TYPE_T eType) -+#else -+INT8 mtk_wcn_wmt_therm_ctrl(ENUM_WMTTHERM_TYPE_T eType) -+#endif -+{ -+ P_OSAL_OP pOp; -+ P_WMT_OP pOpData; -+ MTK_WCN_BOOL bRet; -+ P_OSAL_SIGNAL pSignal; -+ -+ /*parameter validation check */ -+ if (WMTTHERM_MAX < eType || WMTTHERM_ENABLE > eType) { -+ WMT_ERR_FUNC("invalid thermal control command (%d)\n", eType); -+ return MTK_WCN_BOOL_FALSE; -+ } -+ -+ /*check if chip support thermal control function or not */ -+ bRet = wmt_lib_is_therm_ctrl_support(); -+ if (MTK_WCN_BOOL_FALSE == bRet) { -+ WMT_ERR_FUNC("thermal ctrl function not supported\n"); -+ return MTK_WCN_BOOL_FALSE; -+ } -+ -+ pOp = wmt_lib_get_free_op(); -+ if (!pOp) { -+ WMT_WARN_FUNC("get_free_lxop fail\n"); -+ return MTK_WCN_BOOL_FALSE; -+ } -+ -+ pSignal = &pOp->signal; -+ pOpData = &pOp->op; -+ pOpData->opId = WMT_OPID_THERM_CTRL; -+ /*parameter fill */ -+ pOpData->au4OpData[0] = eType; -+ pSignal->timeoutValue = MAX_EACH_WMT_CMD; -+ -+ WMT_INFO_FUNC("OPID(%d) type(%d) start\n", pOp->op.opId, pOp->op.au4OpData[0]); -+ -+ if (DISABLE_PSM_MONITOR()) { -+ WMT_ERR_FUNC("wake up failed,OPID(%d) type(%d) abort!\n", pOp->op.opId, pOp->op.au4OpData[0]); -+ wmt_lib_put_op_to_free_queue(pOp); -+ return -1; -+ } -+ -+ bRet = wmt_lib_put_act_op(pOp); -+ ENABLE_PSM_MONITOR(); -+ -+ if (MTK_WCN_BOOL_FALSE == bRet) { -+ WMT_WARN_FUNC("OPID(%d) type(%d) fail\n\n", pOpData->opId, pOpData->au4OpData[0]); -+ /*0xFF means read error occurs */ -+ /*will return to function driver */ -+ pOpData->au4OpData[1] = (eType == WMTTHERM_READ) ? 0xFF : MTK_WCN_BOOL_FALSE; -+ } else { -+ WMT_INFO_FUNC("OPID(%d) type(%d) return(%d) ok\n\n", -+ pOpData->opId, pOpData->au4OpData[0], pOpData->au4OpData[1]); -+ } -+ /*return value will be put to lxop->op.au4OpData[1] */ -+ WMT_DBG_FUNC("therm ctrl type(%d), iRet(0x%08x)\n", eType, pOpData->au4OpData[1]); -+ return (INT8) pOpData->au4OpData[1]; -+} -+#if !WMT_EXP_HID_API_EXPORT -+EXPORT_SYMBOL(mtk_wcn_wmt_therm_ctrl); -+#endif -+ -+#if WMT_EXP_HID_API_EXPORT -+ENUM_WMTHWVER_TYPE_T _mtk_wcn_wmt_hwver_get(VOID) -+#else -+ENUM_WMTHWVER_TYPE_T mtk_wcn_wmt_hwver_get(VOID) -+#endif -+{ -+ /* TODO: [ChangeFeature][GeorgeKuo] Reconsider usage of this type */ -+ /* TODO: how do we extend for new chip and newer revision? */ -+ /* TODO: This way is hard to extend */ -+ return wmt_lib_get_icinfo(WMTCHIN_MAPPINGHWVER); -+} -+#if !WMT_EXP_HID_API_EXPORT -+EXPORT_SYMBOL(mtk_wcn_wmt_hwver_get); -+#endif -+ -+#if WMT_EXP_HID_API_EXPORT -+MTK_WCN_BOOL _mtk_wcn_wmt_dsns_ctrl(ENUM_WMTDSNS_TYPE_T eType) -+#else -+MTK_WCN_BOOL mtk_wcn_wmt_dsns_ctrl(ENUM_WMTDSNS_TYPE_T eType) -+#endif -+{ -+ P_OSAL_OP pOp; -+ P_WMT_OP pOpData; -+ MTK_WCN_BOOL bRet; -+ P_OSAL_SIGNAL pSignal; -+ -+ if (WMTDSNS_MAX <= eType) { -+ WMT_ERR_FUNC("invalid desense control command (%d)\n", eType); -+ return MTK_WCN_BOOL_FALSE; -+ } -+ -+ /*check if chip support thermal control function or not */ -+ bRet = wmt_lib_is_dsns_ctrl_support(); -+ if (MTK_WCN_BOOL_FALSE == bRet) { -+ WMT_ERR_FUNC("thermal ctrl function not supported\n"); -+ return MTK_WCN_BOOL_FALSE; -+ } -+ -+ pOp = wmt_lib_get_free_op(); -+ if (!pOp) { -+ WMT_WARN_FUNC("get_free_lxop fail\n"); -+ return MTK_WCN_BOOL_FALSE; -+ } -+ -+ pSignal = &pOp->signal; -+ pOpData = &pOp->op; -+ pOpData->opId = WMT_OPID_DSNS; -+ pSignal->timeoutValue = MAX_EACH_WMT_CMD; -+ /*parameter fill */ -+ if ((WMTDSNS_FM_DISABLE <= eType) && (WMTDSNS_FM_GPS_ENABLE >= eType)) { -+ pOpData->au4OpData[0] = WMTDRV_TYPE_FM; -+ pOpData->au4OpData[1] = eType; -+ } -+ -+ WMT_INFO_FUNC("OPID(%d) type(%d) start\n", pOp->op.opId, pOp->op.au4OpData[0]); -+ -+ if (DISABLE_PSM_MONITOR()) { -+ WMT_ERR_FUNC("wake up failed,OPID(%d) type(%d) abort\n", pOp->op.opId, pOp->op.au4OpData[0]); -+ wmt_lib_put_op_to_free_queue(pOp); -+ return MTK_WCN_BOOL_FALSE; -+ } -+ -+ bRet = wmt_lib_put_act_op(pOp); -+ ENABLE_PSM_MONITOR(); -+ -+ if (MTK_WCN_BOOL_FALSE == bRet) -+ WMT_WARN_FUNC("OPID(%d) type(%d) fail\n\n", pOpData->opId, pOpData->au4OpData[0]); -+ else -+ WMT_INFO_FUNC("OPID(%d) type(%d) ok\n\n", pOpData->opId, pOpData->au4OpData[0]); -+ -+ return bRet; -+} -+#if !WMT_EXP_HID_API_EXPORT -+EXPORT_SYMBOL(mtk_wcn_wmt_dsns_ctrl); -+#endif -+ -+#if WMT_EXP_HID_API_EXPORT -+INT32 _mtk_wcn_wmt_msgcb_reg(ENUM_WMTDRV_TYPE_T eType, PF_WMT_CB pCb) -+#else -+INT32 mtk_wcn_wmt_msgcb_reg(ENUM_WMTDRV_TYPE_T eType, PF_WMT_CB pCb) -+#endif -+{ -+ return (INT32) wmt_lib_msgcb_reg(eType, pCb); -+} -+#if !WMT_EXP_HID_API_EXPORT -+EXPORT_SYMBOL(mtk_wcn_wmt_msgcb_reg); -+#endif -+ -+#if WMT_EXP_HID_API_EXPORT -+INT32 _mtk_wcn_wmt_msgcb_unreg(ENUM_WMTDRV_TYPE_T eType) -+#else -+INT32 mtk_wcn_wmt_msgcb_unreg(ENUM_WMTDRV_TYPE_T eType) -+#endif -+{ -+ return (INT32) wmt_lib_msgcb_unreg(eType); -+} -+#if !WMT_EXP_HID_API_EXPORT -+EXPORT_SYMBOL(mtk_wcn_wmt_msgcb_unreg); -+#endif -+ -+#if WMT_EXP_HID_API_EXPORT -+INT32 _mtk_wcn_stp_wmt_sdio_op_reg(PF_WMT_SDIO_PSOP own_cb) -+#else -+INT32 mtk_wcn_stp_wmt_sdio_op_reg(PF_WMT_SDIO_PSOP own_cb) -+#endif -+{ -+ wmt_lib_ps_set_sdio_psop(own_cb); -+ return 0; -+} -+#if !WMT_EXP_HID_API_EXPORT -+EXPORT_SYMBOL(mtk_wcn_stp_wmt_sdio_op_reg); -+#endif -+ -+#if WMT_EXP_HID_API_EXPORT -+INT32 _mtk_wcn_stp_wmt_sdio_host_awake(VOID) -+#else -+INT32 mtk_wcn_stp_wmt_sdio_host_awake(VOID) -+#endif -+{ -+ wmt_lib_ps_irq_cb(); -+ return 0; -+} -+#if !WMT_EXP_HID_API_EXPORT -+EXPORT_SYMBOL(mtk_wcn_stp_wmt_sdio_host_awake); -+#endif -+ -+#if WMT_EXP_HID_API_EXPORT -+MTK_WCN_BOOL _mtk_wcn_wmt_assert(ENUM_WMTDRV_TYPE_T type, UINT32 reason) -+#else -+MTK_WCN_BOOL mtk_wcn_wmt_assert(ENUM_WMTDRV_TYPE_T type, UINT32 reason) -+#endif -+{ -+ P_OSAL_OP pOp = NULL; -+ MTK_WCN_BOOL bRet = MTK_WCN_BOOL_FALSE; -+ P_OSAL_SIGNAL pSignal; -+ -+ pOp = wmt_lib_get_free_op(); -+ if (!pOp) { -+ WMT_WARN_FUNC("get_free_lxop fail\n"); -+ return MTK_WCN_BOOL_FALSE; -+ } -+ -+ wmt_lib_set_host_assert_info(type, reason, 1); -+ -+ pSignal = &pOp->signal; -+ -+ pOp->op.opId = WMT_OPID_CMD_TEST; -+ -+ pSignal->timeoutValue = MAX_EACH_WMT_CMD; -+ /*this test command should be run with usb cable connected, so no host awake is needed */ -+ /* wmt_lib_host_awake_get(); */ -+ pOp->op.au4OpData[0] = 0; -+ -+ /*wake up chip first */ -+ if (DISABLE_PSM_MONITOR()) { -+ WMT_ERR_FUNC("wake up failed,assert flow abort\n"); -+ wmt_lib_put_op_to_free_queue(pOp); -+ return MTK_WCN_BOOL_FALSE; -+ } -+ -+ bRet = wmt_lib_put_act_op(pOp); -+ ENABLE_PSM_MONITOR(); -+ -+ /* wmt_lib_host_awake_put(); */ -+ WMT_INFO_FUNC("CMD_TEST, opid (%d), par(%d, %d), ret(%d), result(%s)\n", -+ pOp->op.opId, -+ pOp->op.au4OpData[0], -+ pOp->op.au4OpData[1], bRet, MTK_WCN_BOOL_FALSE == bRet ? "failed" : "succeed"); -+ -+ return bRet; -+} -+#if !WMT_EXP_HID_API_EXPORT -+EXPORT_SYMBOL(mtk_wcn_wmt_assert); -+#endif -+ -+INT8 mtk_wcn_wmt_co_clock_flag_get(void) -+{ -+ return wmt_lib_co_clock_get(); -+} -+EXPORT_SYMBOL(mtk_wcn_wmt_co_clock_flag_get); -+ -+INT32 mtk_wcn_wmt_system_state_reset(void) -+{ -+ osal_memset(&gBtWifiGpsState, 0, osal_sizeof(gBtWifiGpsState)); -+ osal_memset(&gGpsFmState, 0, osal_sizeof(gGpsFmState)); -+ -+ return 0; -+} -+ -+INT32 mtk_wcn_wmt_wlan_reg(P_MTK_WCN_WMT_WLAN_CB_INFO pWmtWlanCbInfo) -+{ -+ INT32 iRet = -1; -+ -+ if (!pWmtWlanCbInfo) { -+ WMT_ERR_FUNC("wlan cb info in null!\n"); -+ return -1; -+ } -+ -+ WMT_INFO_FUNC("wmt wlan cb register\n"); -+ mtk_wcn_wlan_probe = pWmtWlanCbInfo->wlan_probe_cb; -+ mtk_wcn_wlan_remove = pWmtWlanCbInfo->wlan_remove_cb; -+ mtk_wcn_wlan_bus_tx_cnt = pWmtWlanCbInfo->wlan_bus_cnt_get_cb; -+ mtk_wcn_wlan_bus_tx_cnt_clr = pWmtWlanCbInfo->wlan_bus_cnt_clr_cb; -+ -+ if (gWifiProbed) { -+ WMT_INFO_FUNC("wlan has been done power on,call probe directly\n"); -+ iRet = (*mtk_wcn_wlan_probe) (); -+ if (!iRet) { -+ WMT_INFO_FUNC("call wlan probe OK when do wlan register to wmt\n"); -+ gWifiProbed = 0; -+ } else { -+ WMT_ERR_FUNC("call wlan probe fail(%d) when do wlan register to wmt\n", iRet); -+ return -2; -+ } -+ } -+ return 0; -+} -+EXPORT_SYMBOL(mtk_wcn_wmt_wlan_reg); -+ -+INT32 mtk_wcn_wmt_wlan_unreg(void) -+{ -+ WMT_INFO_FUNC("wmt wlan cb unregister\n"); -+ mtk_wcn_wlan_probe = NULL; -+ mtk_wcn_wlan_remove = NULL; -+ mtk_wcn_wlan_bus_tx_cnt = NULL; -+ mtk_wcn_wlan_bus_tx_cnt_clr = NULL; -+ -+ return 0; -+} -+EXPORT_SYMBOL(mtk_wcn_wmt_wlan_unreg); -+ -+MTK_WCN_BOOL mtk_wcn_set_connsys_power_off_flag(MTK_WCN_BOOL value) -+{ -+ g_pwr_off_flag = value; -+ if (g_pwr_off_flag) -+ WMT_DBG_FUNC("enable connsys power off flag\n"); -+ else -+ WMT_INFO_FUNC("disable connsys power off, maybe need trigger coredump!\n"); -+ return g_pwr_off_flag; -+} -+EXPORT_SYMBOL(mtk_wcn_set_connsys_power_off_flag); -+ -+#ifdef MTK_WCN_WMT_STP_EXP_SYMBOL_ABSTRACT -+VOID mtk_wcn_wmt_exp_init(void) -+{ -+ MTK_WCN_WMT_EXP_CB_INFO wmtExpCb = { -+ -+ .wmt_func_on_cb = _mtk_wcn_wmt_func_on, -+ .wmt_func_off_cb = _mtk_wcn_wmt_func_off, -+ .wmt_therm_ctrl_cb = _mtk_wcn_wmt_therm_ctrl, -+ .wmt_hwver_get_cb = _mtk_wcn_wmt_hwver_get, -+ .wmt_dsns_ctrl_cb = _mtk_wcn_wmt_dsns_ctrl, -+ .wmt_msgcb_reg_cb = _mtk_wcn_wmt_msgcb_reg, -+ .wmt_msgcb_unreg_cb = _mtk_wcn_wmt_msgcb_unreg, -+ .wmt_sdio_op_reg_cb = _mtk_wcn_stp_wmt_sdio_op_reg, -+ .wmt_sdio_host_awake_cb = _mtk_wcn_stp_wmt_sdio_host_awake, -+ .wmt_assert_cb = _mtk_wcn_wmt_assert -+ }; -+ -+ mtk_wcn_wmt_exp_cb_reg(&wmtExpCb); -+} -+ -+VOID mtk_wcn_wmt_exp_deinit(void) -+{ -+ mtk_wcn_wmt_exp_cb_unreg(); -+} -+#ifdef CONFIG_MTK_COMBO_ANT -+/* -+ ctrlId: get ram code status opId or ram code download opId -+ pBuf: pointer to ANT ram code -+ length: total length of ANT ram code -+*/ -+ENUM_WMT_ANT_RAM_STATUS mtk_wcn_wmt_ant_ram_ctrl(ENUM_WMT_ANT_RAM_CTRL ctrlId, PUINT8 pBuf, -+ UINT32 length, ENUM_WMT_ANT_RAM_SEQ seq) -+{ -+ ENUM_WMT_ANT_RAM_STATUS eRet = 0; -+ P_OSAL_OP pOp = NULL; -+ MTK_WCN_BOOL bRet = MTK_WCN_BOOL_FALSE; -+ P_OSAL_SIGNAL pSignal; -+ -+ /*1. parameter validation check */ -+ /*for WMT_ANT_RAM_GET_STATUS, ignore pBuf and length */ -+ /*for WMT_ANT_RAM_DOWNLOAD, -+ pBuf must not be NULL, kernel space memory pointer -+ length must be large than 0 */ -+ -+ if ((WMT_ANT_RAM_GET_STATUS > ctrlId) || (WMT_ANT_RAM_CTRL_MAX <= ctrlId)) { -+ WMT_ERR_FUNC("error ctrlId:%d detected.\n", ctrlId); -+ eRet = WMT_ANT_RAM_PARA_ERR; -+ return eRet; -+ } -+ -+ if ((WMT_ANT_RAM_DOWNLOAD == ctrlId) && -+ ((NULL == pBuf) || -+ (0 >= length) || -+ (1000 < length) || (seq >= WMT_ANT_RAM_SEQ_MAX) || (seq < WMT_ANT_RAM_START_PKT))) { -+ eRet = WMT_ANT_RAM_PARA_ERR; -+ WMT_ERR_FUNC -+ ("error parameter detected, ctrlId:%d, pBuf:%p,length(0x%x),seq(%d) .\n", -+ ctrlId, pBuf, length, seq); -+ return eRet; -+ } -+ /*get WMT opId */ -+ pOp = wmt_lib_get_free_op(); -+ if (!pOp) { -+ WMT_DBG_FUNC("get_free_lxop fail\n"); -+ return MTK_WCN_BOOL_FALSE; -+ } -+ -+ pSignal = &pOp->signal; -+ pSignal->timeoutValue = -+ (WMT_ANT_RAM_DOWNLOAD == ctrlId) ? MAX_FUNC_ON_TIME : MAX_EACH_WMT_CMD; -+ -+ pOp->op.opId = -+ (WMT_ANT_RAM_DOWNLOAD == ctrlId) ? WMT_OPID_ANT_RAM_DOWN : WMT_OPID_ANT_RAM_STA_GET; -+ pOp->op.au4OpData[0] = (size_t) pBuf; -+ pOp->op.au4OpData[1] = length; -+ pOp->op.au4OpData[2] = seq; -+ -+ -+ /*disable PSM monitor */ -+ if (DISABLE_PSM_MONITOR()) { -+ WMT_ERR_FUNC("wake up failed\n"); -+ wmt_lib_put_op_to_free_queue(pOp); -+ return MTK_WCN_BOOL_FALSE; -+ } -+ /*wakeup wmtd thread */ -+ bRet = wmt_lib_put_act_op(pOp); -+ -+ /*enable PSM monitor */ -+ ENABLE_PSM_MONITOR(); -+ -+ WMT_DBG_FUNC("CMD_TEST, opid (%d), ret(%d),retVal(%zu) result(%s)\n", -+ pOp->op.opId, -+ bRet, -+ pOp->op.au4OpData[2], MTK_WCN_BOOL_FALSE == bRet ? "failed" : "succeed"); -+ -+ /*check return value and return result */ -+ if (MTK_WCN_BOOL_FALSE == bRet) { -+ eRet = WMT_ANT_RAM_OP_ERR; -+ } else { -+ eRet = (WMT_ANT_RAM_DOWNLOAD == ctrlId) ? -+ WMT_ANT_RAM_DOWN_OK : -+ ((1 == pOp->op.au4OpData[2]) ? WMT_ANT_RAM_EXIST : WMT_ANT_RAM_NOT_EXIST); -+ } -+ -+ return eRet; -+ -+} -+EXPORT_SYMBOL(mtk_wcn_wmt_ant_ram_ctrl); -+#endif -+ -+#endif -+VOID mtk_wcn_wmt_set_wifi_ver(UINT32 Value) -+{ -+ wmt_lib_soc_set_wifiver(Value); -+} -+EXPORT_SYMBOL(mtk_wcn_wmt_set_wifi_ver); -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/Makefile b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/Makefile -new file mode 100644 -index 000000000000..eb37baf87b02 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/Makefile -@@ -0,0 +1,27 @@ -+ifeq ($(CONFIG_MTK_COMBO), y) -+ -+ccflags-y += \ -+ -I$(src)/../../linux/include \ -+ -I$(src)/../../linux/pri/include \ -+ -I$(src)/../../core/include \ -+ -I$(src)/../../include \ -+ -I$(src)/../include \ -+ -I$(src)/../../../common_detect \ -+ -I$(srctree)/drivers/misc/mediatek/include/mt-plat/$(MTK_PLATFORM)/include/mach \ -+ -DMTK_BT_HCI=1 -+ -+ccflags-y += -DWMT_CREATE_NODE_DYNAMIC=1 -+ -+ifeq ($(CONFIG_MTK_TC1_FEATURE), y) -+ ccflags-y += -DCFG_TC1_FEATURE=1 -+else -+ ccflags-y += -DCFG_TC1_FEATURE=0 -+endif -+ -+obj-y += osal.o \ -+ bgw_desense.o \ -+ wmt_idc.o -+obj-$(CONFIG_MTK_COMBO_BT) += stp_chrdev_bt.o -+obj-$(CONFIG_MTK_COMBO_WIFI) += wmt_chrdev_wifi.o -+ -+endif -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/bgw_desense.c b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/bgw_desense.c -new file mode 100644 -index 000000000000..11e45aa13087 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/bgw_desense.c -@@ -0,0 +1,153 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -+ -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include "bgw_desense.h" -+ -+static struct sock *g_nl_sk; -+/* static struct sockaddr_nl src_addr, des_addr; */ -+/* static struct iovec iov; */ -+static int pid; -+/* static struct msghdr msg; */ -+ -+void bgw_destroy_netlink_kernel(void) -+{ -+ if (g_nl_sk != NULL) { -+ /* sock_release(g_nl_sk->sk_socket); */ -+ netlink_kernel_release(g_nl_sk); -+ MSG("release socket\n"); -+ return; -+ } -+ ERR("no socket yet\n"); -+} -+ -+void send_command_to_daemon(const int command /*struct sk_buff *skb */) -+{ -+/* -+ struct iphdr *iph; -+ struct ethhdr *ehdr; -+ */ -+ struct nlmsghdr *nlh; -+ struct sk_buff *nl_skb; -+ int res; -+ -+ MSG("here we will send command to native daemon\n"); -+/* if(skb == NULL) -+ { -+ ERR("invalid sk_buff\n"); -+ return; -+ } -+*/ -+ if (!g_nl_sk) { -+ ERR("invalid socket\n"); -+ return; -+ } -+ if (pid == 0) { -+ ERR("invalid native process pid\n"); -+ return; -+ } -+ /*alloc data buffer for sending to native */ -+ /*malloc data space at least 1500 bytes, which is ethernet data length */ -+ nl_skb = alloc_skb(NLMSG_SPACE(MAX_NL_MSG_LEN), GFP_ATOMIC); -+ if (nl_skb == NULL) { -+ ERR("malloc skb error\n"); -+ return; -+ } -+ MSG("malloc data space done\n"); -+ /* -+ ehdr = eth_hdr(skb); -+ iph = ip_hdr(skb); -+ */ -+ -+/* nlh = NLMSG_PUT(nl_skb, 0, 0, 0, NLMSG_SPACE(1500)-sizeof(struct nlmsghdr)); */ -+ nlh = nlmsg_put(nl_skb, 0, 0, 0, MAX_NL_MSG_LEN, 0); -+ if (nlh == NULL) { -+ MSG("nlh is NULL\n"); -+ kfree_skb(nl_skb); -+ return; -+ } -+ NETLINK_CB(nl_skb).portid = 0; -+ -+/* memcpy(NLMSG_DATA(nlh), ACK, 5); */ -+ *(char *)NLMSG_DATA(nlh) = command; -+ res = netlink_unicast(g_nl_sk, nl_skb, pid, MSG_DONTWAIT); -+ if (res == 0) { -+ MSG("send to user space process error\n"); -+ return; -+ } -+ ERR("send to user space process done, data length = %d\n", res); -+} -+ -+static void nl_data_handler(struct sk_buff *__skb) -+{ -+ struct sk_buff *skb; -+ struct nlmsghdr *nlh; -+ int i; -+ int len; -+ char str[128]; -+ -+ MSG("we got netlink message\n"); -+ len = NLMSG_SPACE(MAX_NL_MSG_LEN); -+ skb = skb_get(__skb); -+ if (skb == NULL) -+ ERR("skb_get return NULL"); -+ if (skb->len >= NLMSG_SPACE(0)) { /*presume there is 5byte payload at leaset */ -+ MSG("length is enough\n"); -+ nlh = nlmsg_hdr(skb); /* point to data which include in skb */ -+ memcpy(str, NLMSG_DATA(nlh), sizeof(str)); -+ for (i = 0; i < 3; i++) -+ MSG("str[%d = %c]", i, str[i]); -+ MSG("str[0] = %d, str[1] = %d, str[2] = %d\n", str[0], str[1], str[2]); -+ if (str[0] == 'B' && str[1] == 'G' && str[2] == 'W') { -+ MSG("got native daemon init command, record it's pid\n"); -+ pid = nlh->nlmsg_pid; /*record the native process PID */ -+ MSG("native daemon pid is %d\n", pid); -+ } else { -+ ERR("this is not BGW message, ignore it\n"); -+ return; -+ } -+ } else { -+ ERR("not engouth data length\n"); -+ return; -+ } -+ -+ kfree_skb(skb); -+ -+ send_command_to_daemon(ACK); -+} -+ -+int bgw_init_socket(void) -+{ -+ struct netlink_kernel_cfg cfg; -+ -+ memset(&cfg, 0, sizeof(cfg)); -+ cfg.input = nl_data_handler; -+ -+ g_nl_sk = __netlink_kernel_create(&init_net, NETLINK_TEST, THIS_MODULE, &cfg); -+ -+ if (g_nl_sk == NULL) { -+ ERR("netlink_kernel_create error\n"); -+ return -1; -+ } -+ MSG("netlink_kernel_create ok\n"); -+ return 0; -+} -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/osal.c b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/osal.c -new file mode 100644 -index 000000000000..959b68de2431 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/osal.c -@@ -0,0 +1,1211 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -+ -+/*! \file -+ \brief Declaration of library functions -+ -+ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "osal_typedef.h" -+#include "osal.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/* CRC table for the CRC-16. The poly is 0x8005 (x^16 + x^15 + x^2 + 1) */ -+static UINT16 const crc16_table[256] = { -+ 0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241, -+ 0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440, -+ 0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40, -+ 0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841, -+ 0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40, -+ 0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41, -+ 0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641, -+ 0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040, -+ 0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240, -+ 0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441, -+ 0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41, -+ 0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840, -+ 0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41, -+ 0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40, -+ 0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640, -+ 0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041, -+ 0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240, -+ 0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441, -+ 0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41, -+ 0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840, -+ 0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41, -+ 0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40, -+ 0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1, 0xB681, 0x7640, -+ 0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041, -+ 0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241, -+ 0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440, -+ 0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40, -+ 0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841, -+ 0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40, -+ 0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41, -+ 0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641, -+ 0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040 -+}; -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+/*string operations*/ -+_osal_inline_ UINT32 osal_strlen(const char *str) -+{ -+ return strlen(str); -+} -+ -+_osal_inline_ INT32 osal_strcmp(const char *dst, const char *src) -+{ -+ return strcmp(dst, src); -+} -+ -+_osal_inline_ INT32 osal_strncmp(const char *dst, const char *src, UINT32 len) -+{ -+ return strncmp(dst, src, len); -+} -+ -+_osal_inline_ char *osal_strcpy(char *dst, const char *src) -+{ -+ return strcpy(dst, src); -+} -+ -+_osal_inline_ char *osal_strncpy(char *dst, const char *src, UINT32 len) -+{ -+ return strncpy(dst, src, len); -+} -+ -+_osal_inline_ char *osal_strcat(char *dst, const char *src) -+{ -+ return strcat(dst, src); -+} -+ -+_osal_inline_ char *osal_strncat(char *dst, const char *src, UINT32 len) -+{ -+ return strncat(dst, src, len); -+} -+ -+_osal_inline_ char *osal_strchr(const char *str, UINT8 c) -+{ -+ return strchr(str, c); -+} -+ -+_osal_inline_ char *osal_strsep(char **str, const char *c) -+{ -+ return strsep(str, c); -+} -+ -+_osal_inline_ int osal_strtol(const char *str, UINT32 adecimal, long *res) -+{ -+ return kstrtol(str, adecimal, res); -+} -+ -+_osal_inline_ char *osal_strstr(char *str1, const char *str2) -+{ -+ return strstr(str1, str2); -+} -+ -+INT32 osal_snprintf(char *buf, UINT32 len, const char *fmt, ...) -+{ -+ INT32 iRet = 0; -+ va_list args; -+ -+ /*va_start(args, fmt); */ -+ va_start(args, fmt); -+ /*iRet = snprintf(buf, len, fmt, args); */ -+ iRet = vsnprintf(buf, len, fmt, args); -+ va_end(args); -+ -+ return iRet; -+} -+ -+INT32 osal_err_print(const char *str, ...) -+{ -+ va_list args; -+ char tempString[DBG_LOG_STR_SIZE]; -+ -+ va_start(args, str); -+ vsnprintf(tempString, DBG_LOG_STR_SIZE, str, args); -+ va_end(args); -+ -+ pr_err("%s", tempString); -+ -+ return 0; -+} -+ -+INT32 osal_dbg_print(const char *str, ...) -+{ -+ va_list args; -+ char tempString[DBG_LOG_STR_SIZE]; -+ -+ va_start(args, str); -+ vsnprintf(tempString, DBG_LOG_STR_SIZE, str, args); -+ va_end(args); -+ -+ pr_debug("%s", tempString); -+ -+ return 0; -+} -+ -+INT32 osal_warn_print(const char *str, ...) -+{ -+ va_list args; -+ char tempString[DBG_LOG_STR_SIZE]; -+ -+ va_start(args, str); -+ vsnprintf(tempString, DBG_LOG_STR_SIZE, str, args); -+ va_end(args); -+ -+ pr_warn("%s", tempString); -+ -+ return 0; -+} -+ -+INT32 osal_dbg_assert(INT32 expr, const char *file, INT32 line) -+{ -+ if (!expr) { -+ pr_warn("%s (%d)\n", file, line); -+ /*BUG_ON(!expr); */ -+#ifdef CFG_COMMON_GPIO_DBG_PIN -+/* package this part */ -+ mt_set_gpio_out(GPIO70, GPIO_OUT_ZERO); -+ pr_warn("toggle GPIO70\n"); -+ udelay(10); -+ mt_set_gpio_out(GPIO70, GPIO_OUT_ONE); -+#endif -+ return 1; -+ } -+ return 0; -+ -+} -+ -+INT32 osal_dbg_assert_aee(const char *module, const char *detail_description) -+{ -+ osal_err_print("[WMT-ASSERT]" "[E][Module]:%s, [INFO]%s\n", module, detail_description); -+ -+#ifdef WMT_PLAT_ALPS -+ /* aee_kernel_warning(module,detail_description); */ -+ aee_kernel_warning_api(__FILE__, __LINE__, DB_OPT_WCN_ISSUE_INFO, module, detail_description); -+#endif -+ return 0; -+} -+ -+INT32 osal_sprintf(char *str, const char *format, ...) -+{ -+ INT32 iRet = 0; -+ va_list args; -+ -+ va_start(args, format); -+ iRet = vsnprintf(str, DBG_LOG_STR_SIZE, format, args); -+ va_end(args); -+ -+ return iRet; -+} -+ -+_osal_inline_ VOID *osal_malloc(UINT32 size) -+{ -+ return vmalloc(size); -+} -+ -+_osal_inline_ VOID osal_free(const VOID *dst) -+{ -+ vfree(dst); -+} -+ -+_osal_inline_ VOID *osal_memset(VOID *buf, INT32 i, UINT32 len) -+{ -+ return memset(buf, i, len); -+} -+ -+_osal_inline_ VOID *osal_memcpy(VOID *dst, const VOID *src, UINT32 len) -+{ -+#ifdef CONFIG_MTK_WCN_ARM64 -+ char *tmp; -+ const char *s; -+ size_t i; -+ -+ tmp = dst; -+ s = src; -+ for (i = 0; i < len; i++) -+ tmp[i] = s[i]; -+ -+ return dst; -+ -+#else -+ return memcpy(dst, src, len); -+#endif -+} -+ -+_osal_inline_ INT32 osal_memcmp(const VOID *buf1, const VOID *buf2, UINT32 len) -+{ -+ return memcmp(buf1, buf2, len); -+} -+ -+_osal_inline_ UINT16 osal_crc16(const UINT8 *buffer, const UINT32 length) -+{ -+ UINT16 crc = 0; -+ UINT32 i = 0; -+ -+ /* FIXME: Add STP checksum feature */ -+ crc = 0; -+ for (i = 0; i < length; i++, buffer++) -+ crc = (crc >> 8) ^ crc16_table[(crc ^ (*buffer)) & 0xff]; -+ -+ return crc; -+} -+ -+_osal_inline_ VOID osal_thread_show_stack(P_OSAL_THREAD pThread) -+{ -+ return show_stack(pThread->pThread, NULL); -+} -+ -+/* -+ *OSAL layer Thread Opeartion related APIs -+ * -+ * -+*/ -+_osal_inline_ INT32 osal_thread_create(P_OSAL_THREAD pThread) -+{ -+ pThread->pThread = kthread_create(pThread->pThreadFunc, pThread->pThreadData, pThread->threadName); -+ if (NULL == pThread->pThread) -+ return -1; -+ -+ return 0; -+} -+ -+_osal_inline_ INT32 osal_thread_run(P_OSAL_THREAD pThread) -+{ -+ if (pThread->pThread) { -+ wake_up_process(pThread->pThread); -+ return 0; -+ } else { -+ return -1; -+ } -+} -+ -+_osal_inline_ INT32 osal_thread_stop(P_OSAL_THREAD pThread) -+{ -+ INT32 iRet; -+ -+ if ((pThread) && (pThread->pThread)) { -+ iRet = kthread_stop(pThread->pThread); -+ /* pThread->pThread = NULL; */ -+ return iRet; -+ } -+ return -1; -+} -+ -+_osal_inline_ INT32 osal_thread_should_stop(P_OSAL_THREAD pThread) -+{ -+ if ((pThread) && (pThread->pThread)) -+ return kthread_should_stop(); -+ else -+ return 1; -+ -+} -+ -+_osal_inline_ INT32 -+osal_thread_wait_for_event(P_OSAL_THREAD pThread, P_OSAL_EVENT pEvent, P_OSAL_EVENT_CHECKER pChecker) -+{ -+ /* P_DEV_WMT pDevWmt;*/ -+ -+ if ((pThread) && (pThread->pThread) && (pEvent) && (pChecker)) { -+ /* pDevWmt = (P_DEV_WMT)(pThread->pThreadData);*/ -+ return wait_event_interruptible(pEvent->waitQueue, (/*!RB_EMPTY(&pDevWmt->rActiveOpQ) || */ -+ osal_thread_should_stop(pThread) -+ || (*pChecker) (pThread))); -+ } -+ return -1; -+} -+ -+_osal_inline_ INT32 osal_thread_destroy(P_OSAL_THREAD pThread) -+{ -+ if (pThread && (pThread->pThread)) { -+ kthread_stop(pThread->pThread); -+ pThread->pThread = NULL; -+ } -+ return 0; -+} -+ -+/* -+ *OSAL layer Signal Opeartion related APIs -+ *initialization -+ *wait for signal -+ *wait for signal timerout -+ *raise signal -+ *destroy a signal -+ * -+*/ -+ -+_osal_inline_ INT32 osal_signal_init(P_OSAL_SIGNAL pSignal) -+{ -+ if (pSignal) { -+ init_completion(&pSignal->comp); -+ return 0; -+ } else { -+ return -1; -+ } -+} -+ -+_osal_inline_ INT32 osal_wait_for_signal(P_OSAL_SIGNAL pSignal) -+{ -+ if (pSignal) { -+ wait_for_completion_interruptible(&pSignal->comp); -+ return 0; -+ } else { -+ return -1; -+ } -+} -+ -+_osal_inline_ INT32 osal_wait_for_signal_timeout(P_OSAL_SIGNAL pSignal) -+{ -+ /* return wait_for_completion_interruptible_timeout(&pSignal->comp, msecs_to_jiffies(pSignal->timeoutValue)); */ -+ /* [ChangeFeature][George] gps driver may be closed by -ERESTARTSYS. -+ * Avoid using *interruptible" version in order to complete our jobs, such -+ * as function off gracefully. -+ */ -+ return wait_for_completion_timeout(&pSignal->comp, msecs_to_jiffies(pSignal->timeoutValue)); -+} -+ -+_osal_inline_ INT32 osal_raise_signal(P_OSAL_SIGNAL pSignal) -+{ -+ /* TODO:[FixMe][GeorgeKuo]: DO sanity check here!!! */ -+ complete(&pSignal->comp); -+ return 0; -+} -+ -+_osal_inline_ INT32 osal_signal_deinit(P_OSAL_SIGNAL pSignal) -+{ -+ /* TODO:[FixMe][GeorgeKuo]: DO sanity check here!!! */ -+ pSignal->timeoutValue = 0; -+ return 0; -+} -+ -+/* -+ *OSAL layer Event Opeartion related APIs -+ *initialization -+ *wait for signal -+ *wait for signal timerout -+ *raise signal -+ *destroy a signal -+ * -+*/ -+ -+INT32 osal_event_init(P_OSAL_EVENT pEvent) -+{ -+ init_waitqueue_head(&pEvent->waitQueue); -+ -+ return 0; -+} -+ -+INT32 osal_wait_for_event(P_OSAL_EVENT pEvent, INT32(*condition) (PVOID), void *cond_pa) -+{ -+ return wait_event_interruptible(pEvent->waitQueue, condition(cond_pa)); -+} -+ -+INT32 osal_wait_for_event_timeout(P_OSAL_EVENT pEvent, INT32(*condition) (PVOID), void *cond_pa) -+{ -+ return wait_event_interruptible_timeout(pEvent->waitQueue, condition(cond_pa), -+ msecs_to_jiffies(pEvent->timeoutValue)); -+} -+ -+INT32 osal_trigger_event(P_OSAL_EVENT pEvent) -+{ -+ INT32 ret = 0; -+ -+ wake_up_interruptible(&pEvent->waitQueue); -+ return ret; -+} -+ -+INT32 osal_event_deinit(P_OSAL_EVENT pEvent) -+{ -+ return 0; -+} -+ -+_osal_inline_ long osal_wait_for_event_bit_set(P_OSAL_EVENT pEvent, unsigned long *pState, UINT32 bitOffset) -+{ -+ UINT32 ms = pEvent->timeoutValue; -+ -+ if (ms != 0) { -+ return wait_event_interruptible_timeout(pEvent->waitQueue, test_bit(bitOffset, pState), -+ msecs_to_jiffies(ms)); -+ } else { -+ return wait_event_interruptible(pEvent->waitQueue, test_bit(bitOffset, pState)); -+ } -+ -+} -+ -+_osal_inline_ long osal_wait_for_event_bit_clr(P_OSAL_EVENT pEvent, unsigned long *pState, UINT32 bitOffset) -+{ -+ UINT32 ms = pEvent->timeoutValue; -+ -+ if (ms != 0) { -+ return wait_event_interruptible_timeout(pEvent->waitQueue, !test_bit(bitOffset, pState), -+ msecs_to_jiffies(ms)); -+ } else { -+ return wait_event_interruptible(pEvent->waitQueue, !test_bit(bitOffset, pState)); -+ } -+ -+} -+ -+/* -+ *bit test and set/clear operations APIs -+ * -+ * -+*/ -+#if OS_BIT_OPS_SUPPORT -+#define osal_bit_op_lock(x) -+#define osal_bit_op_unlock(x) -+#else -+ -+_osal_inline_ INT32 osal_bit_op_lock(P_OSAL_UNSLEEPABLE_LOCK pLock) -+{ -+ -+ return 0; -+} -+ -+_osal_inline_ INT32 osal_bit_op_unlock(P_OSAL_UNSLEEPABLE_LOCK pLock) -+{ -+ -+ return 0; -+} -+#endif -+_osal_inline_ INT32 osal_clear_bit(UINT32 bitOffset, P_OSAL_BIT_OP_VAR pData) -+{ -+ osal_bit_op_lock(&(pData->opLock)); -+ clear_bit(bitOffset, &pData->data); -+ osal_bit_op_unlock(&(pData->opLock)); -+ return 0; -+} -+ -+_osal_inline_ INT32 osal_set_bit(UINT32 bitOffset, P_OSAL_BIT_OP_VAR pData) -+{ -+ osal_bit_op_lock(&(pData->opLock)); -+ set_bit(bitOffset, &pData->data); -+ osal_bit_op_unlock(&(pData->opLock)); -+ return 0; -+} -+ -+_osal_inline_ INT32 osal_test_bit(UINT32 bitOffset, P_OSAL_BIT_OP_VAR pData) -+{ -+ UINT32 iRet = 0; -+ -+ osal_bit_op_lock(&(pData->opLock)); -+ iRet = test_bit(bitOffset, &pData->data); -+ osal_bit_op_unlock(&(pData->opLock)); -+ return iRet; -+} -+ -+_osal_inline_ INT32 osal_test_and_clear_bit(UINT32 bitOffset, P_OSAL_BIT_OP_VAR pData) -+{ -+ UINT32 iRet = 0; -+ -+ osal_bit_op_lock(&(pData->opLock)); -+ iRet = test_and_clear_bit(bitOffset, &pData->data); -+ osal_bit_op_unlock(&(pData->opLock)); -+ return iRet; -+ -+} -+ -+_osal_inline_ INT32 osal_test_and_set_bit(UINT32 bitOffset, P_OSAL_BIT_OP_VAR pData) -+{ -+ UINT32 iRet = 0; -+ -+ osal_bit_op_lock(&(pData->opLock)); -+ iRet = test_and_set_bit(bitOffset, &pData->data); -+ osal_bit_op_unlock(&(pData->opLock)); -+ return iRet; -+} -+ -+/* -+ *tiemr operations APIs -+ *create -+ *stop -+ * modify -+ *create -+ *delete -+ * -+*/ -+ -+INT32 osal_timer_create(P_OSAL_TIMER pTimer) -+{ -+ struct timer_list *timer = &pTimer->timer; -+ -+ /*init_timer(timer); -+ timer->function = pTimer->timeoutHandler; -+ timer->data = (unsigned long)pTimer->timeroutHandlerData;*/ -+ timer_setup(timer,pTimer->timeoutHandler,0); -+ return 0; -+} -+ -+INT32 osal_timer_start(P_OSAL_TIMER pTimer, UINT32 ms) -+{ -+ -+ struct timer_list *timer = &pTimer->timer; -+ -+ timer->expires = jiffies + (ms / (1000 / HZ)); -+ add_timer(timer); -+ return 0; -+} -+ -+INT32 osal_timer_stop(P_OSAL_TIMER pTimer) -+{ -+ struct timer_list *timer = &pTimer->timer; -+ -+ del_timer(timer); -+ return 0; -+} -+ -+INT32 osal_timer_stop_sync(P_OSAL_TIMER pTimer) -+{ -+ struct timer_list *timer = &pTimer->timer; -+ -+ del_timer_sync(timer); -+ return 0; -+} -+ -+INT32 osal_timer_modify(P_OSAL_TIMER pTimer, UINT32 ms) -+{ -+ -+ mod_timer(&pTimer->timer, jiffies + (ms) / (1000 / HZ)); -+ return 0; -+} -+ -+INT32 _osal_fifo_init(OSAL_FIFO *pFifo, UINT8 *buf, UINT32 size) -+{ -+ struct kfifo *fifo = NULL; -+ INT32 ret = -1; -+ -+ if (!pFifo) { -+ pr_err("pFifo must be !NULL\n"); -+ return -1; -+ } -+ if (pFifo->pFifoBody) { -+ pr_err("pFifo->pFifoBody must be NULL\n"); -+ pr_err("pFifo(0x%p), pFifo->pFifoBody(0x%p)\n", pFifo, pFifo->pFifoBody); -+ return -1; -+ } -+ fifo = kzalloc(sizeof(struct kfifo), GFP_ATOMIC); -+ if (!buf) { -+ /*fifo's buffer is not ready, we allocate automatically */ -+ ret = kfifo_alloc(fifo, size, /*GFP_KERNEL */ GFP_ATOMIC); -+ } else { -+ if (is_power_of_2(size)) { -+ kfifo_init(fifo, buf, size); -+ ret = 0; -+ } else { -+ kfifo_free(fifo); -+ fifo = NULL; -+ ret = -1; -+ } -+ } -+ -+ pFifo->pFifoBody = fifo; -+ return (ret < 0) ? (-1) : (0); -+} -+ -+INT32 _osal_fifo_deinit(OSAL_FIFO *pFifo) -+{ -+ struct kfifo *fifo = NULL; -+ -+ if (!pFifo || !pFifo->pFifoBody) { -+ pr_err("%s:pFifo = NULL or pFifo->pFifoBody = NULL, error\n", __func__); -+ return -1; -+ } -+ -+ fifo = (struct kfifo *)pFifo->pFifoBody; -+ -+ if (fifo) -+ kfifo_free(fifo); -+ -+ return 0; -+} -+ -+INT32 _osal_fifo_size(OSAL_FIFO *pFifo) -+{ -+ struct kfifo *fifo = NULL; -+ INT32 ret = 0; -+ -+ if (!pFifo || !pFifo->pFifoBody) { -+ pr_err("%s:pFifo = NULL or pFifo->pFifoBody = NULL, error\n", __func__); -+ return -1; -+ } -+ -+ fifo = (struct kfifo *)pFifo->pFifoBody; -+ -+ if (fifo) -+ ret = kfifo_size(fifo); -+ -+ return ret; -+} -+ -+/*returns unused bytes in fifo*/ -+INT32 _osal_fifo_avail_size(OSAL_FIFO *pFifo) -+{ -+ struct kfifo *fifo = NULL; -+ INT32 ret = 0; -+ -+ if (!pFifo || !pFifo->pFifoBody) { -+ pr_err("%s:pFifo = NULL or pFifo->pFifoBody = NULL, error\n", __func__); -+ return -1; -+ } -+ -+ fifo = (struct kfifo *)pFifo->pFifoBody; -+ -+ if (fifo) -+ ret = kfifo_avail(fifo); -+ -+ return ret; -+} -+ -+/*returns used bytes in fifo*/ -+INT32 _osal_fifo_len(OSAL_FIFO *pFifo) -+{ -+ struct kfifo *fifo = NULL; -+ INT32 ret = 0; -+ -+ if (!pFifo || !pFifo->pFifoBody) { -+ pr_err("%s:pFifo = NULL or pFifo->pFifoBody = NULL, error\n", __func__); -+ return -1; -+ } -+ -+ fifo = (struct kfifo *)pFifo->pFifoBody; -+ -+ if (fifo) -+ ret = kfifo_len(fifo); -+ -+ return ret; -+} -+ -+INT32 _osal_fifo_is_empty(OSAL_FIFO *pFifo) -+{ -+ struct kfifo *fifo = NULL; -+ INT32 ret = 0; -+ -+ if (!pFifo || !pFifo->pFifoBody) { -+ pr_err("%s:pFifo = NULL or pFifo->pFifoBody = NULL, error\n", __func__); -+ return -1; -+ } -+ -+ fifo = (struct kfifo *)pFifo->pFifoBody; -+ -+ if (fifo) -+ ret = kfifo_is_empty(fifo); -+ -+ return ret; -+} -+ -+INT32 _osal_fifo_is_full(OSAL_FIFO *pFifo) -+{ -+ struct kfifo *fifo = NULL; -+ INT32 ret = 0; -+ -+ if (!pFifo || !pFifo->pFifoBody) { -+ pr_err("%s:pFifo = NULL or pFifo->pFifoBody = NULL, error\n", __func__); -+ return -1; -+ } -+ -+ fifo = (struct kfifo *)pFifo->pFifoBody; -+ -+ if (fifo) -+ ret = kfifo_is_full(fifo); -+ -+ return ret; -+} -+ -+INT32 _osal_fifo_data_in(OSAL_FIFO *pFifo, const VOID *buf, UINT32 len) -+{ -+ struct kfifo *fifo = NULL; -+ INT32 ret = 0; -+ -+ if (!pFifo || !pFifo->pFifoBody) { -+ pr_err("%s:pFifo = NULL or pFifo->pFifoBody = NULL, error\n", __func__); -+ return -1; -+ } -+ -+ fifo = (struct kfifo *)pFifo->pFifoBody; -+ -+ if (fifo && buf && (len <= _osal_fifo_avail_size(pFifo))) { -+ ret = kfifo_in(fifo, buf, len); -+ } else { -+ pr_err("%s: kfifo_in, error, len = %d, _osal_fifo_avail_size = %d, buf=%p\n", -+ __func__, len, _osal_fifo_avail_size(pFifo), buf); -+ -+ ret = 0; -+ } -+ -+ return ret; -+} -+ -+INT32 _osal_fifo_data_out(OSAL_FIFO *pFifo, void *buf, UINT32 len) -+{ -+ struct kfifo *fifo = NULL; -+ INT32 ret = 0; -+ -+ if (!pFifo || !pFifo->pFifoBody) { -+ pr_err("%s:pFifo = NULL or pFifo->pFifoBody = NULL, error\n", __func__); -+ return -1; -+ } -+ -+ fifo = (struct kfifo *)pFifo->pFifoBody; -+ -+ if (fifo && buf && (len <= _osal_fifo_len(pFifo))) { -+ ret = kfifo_out(fifo, buf, len); -+ } else { -+ pr_err("%s: kfifo_out, error, len = %d, osal_fifo_len = %d, buf=%p\n", -+ __func__, len, _osal_fifo_len(pFifo), buf); -+ -+ ret = 0; -+ } -+ -+ return ret; -+} -+ -+INT32 _osal_fifo_reset(OSAL_FIFO *pFifo) -+{ -+ struct kfifo *fifo = NULL; -+ -+ if (!pFifo || !pFifo->pFifoBody) { -+ pr_err("%s:pFifo = NULL or pFifo->pFifoBody = NULL, error\n", __func__); -+ return -1; -+ } -+ -+ fifo = (struct kfifo *)pFifo->pFifoBody; -+ -+ if (fifo) -+ kfifo_reset(fifo); -+ -+ return 0; -+} -+ -+INT32 osal_fifo_init(P_OSAL_FIFO pFifo, UINT8 *buffer, UINT32 size) -+{ -+ if (!pFifo) { -+ pr_err("%s:pFifo = NULL, error\n", __func__); -+ return -1; -+ } -+ -+ pFifo->FifoInit = _osal_fifo_init; -+ pFifo->FifoDeInit = _osal_fifo_deinit; -+ pFifo->FifoSz = _osal_fifo_size; -+ pFifo->FifoAvailSz = _osal_fifo_avail_size; -+ pFifo->FifoLen = _osal_fifo_len; -+ pFifo->FifoIsEmpty = _osal_fifo_is_empty; -+ pFifo->FifoIsFull = _osal_fifo_is_full; -+ pFifo->FifoDataIn = _osal_fifo_data_in; -+ pFifo->FifoDataOut = _osal_fifo_data_out; -+ pFifo->FifoReset = _osal_fifo_reset; -+ -+ if (NULL != pFifo->pFifoBody) { -+ pr_err("%s:Because pFifo room is avialable, we clear the room and allocate them again.\n", __func__); -+ pFifo->FifoDeInit(pFifo->pFifoBody); -+ pFifo->pFifoBody = NULL; -+ } -+ -+ pFifo->FifoInit(pFifo, buffer, size); -+ -+ return 0; -+} -+ -+VOID osal_fifo_deinit(P_OSAL_FIFO pFifo) -+{ -+ if (pFifo) -+ pFifo->FifoDeInit(pFifo); -+ else { -+ pr_err("%s:pFifo = NULL, error\n", __func__); -+ return; -+ } -+ kfree(pFifo->pFifoBody); -+} -+ -+INT32 osal_fifo_reset(P_OSAL_FIFO pFifo) -+{ -+ INT32 ret = -1; -+ -+ if (pFifo) { -+ ret = pFifo->FifoReset(pFifo); -+ } else { -+ pr_err("%s:pFifo = NULL, error\n", __func__); -+ ret = -1; -+ } -+ return ret; -+} -+ -+UINT32 osal_fifo_in(P_OSAL_FIFO pFifo, PUINT8 buffer, UINT32 size) -+{ -+ UINT32 ret = 0; -+ -+ if (pFifo) { -+ ret = pFifo->FifoDataIn(pFifo, buffer, size); -+ } else { -+ pr_err("%s:pFifo = NULL, error\n", __func__); -+ ret = 0; -+ } -+ -+ return ret; -+} -+ -+UINT32 osal_fifo_out(P_OSAL_FIFO pFifo, PUINT8 buffer, UINT32 size) -+{ -+ UINT32 ret = 0; -+ -+ if (pFifo) { -+ ret = pFifo->FifoDataOut(pFifo, buffer, size); -+ } else { -+ pr_err("%s:pFifo = NULL, error\n", __func__); -+ ret = 0; -+ } -+ -+ return ret; -+} -+ -+UINT32 osal_fifo_len(P_OSAL_FIFO pFifo) -+{ -+ UINT32 ret = 0; -+ -+ if (pFifo) { -+ ret = pFifo->FifoLen(pFifo); -+ } else { -+ pr_err("%s:pFifo = NULL, error\n", __func__); -+ ret = 0; -+ } -+ -+ return ret; -+} -+ -+UINT32 osal_fifo_sz(P_OSAL_FIFO pFifo) -+{ -+ UINT32 ret = 0; -+ -+ if (pFifo) { -+ ret = pFifo->FifoSz(pFifo); -+ } else { -+ pr_err("%s:pFifo = NULL, error\n", __func__); -+ ret = 0; -+ } -+ -+ return ret; -+} -+ -+UINT32 osal_fifo_avail(P_OSAL_FIFO pFifo) -+{ -+ UINT32 ret = 0; -+ -+ if (pFifo) { -+ ret = pFifo->FifoAvailSz(pFifo); -+ } else { -+ pr_err("%s:pFifo = NULL, error\n", __func__); -+ ret = 0; -+ } -+ -+ return ret; -+} -+ -+UINT32 osal_fifo_is_empty(P_OSAL_FIFO pFifo) -+{ -+ UINT32 ret = 0; -+ -+ if (pFifo) { -+ ret = pFifo->FifoIsEmpty(pFifo); -+ } else { -+ pr_err("%s:pFifo = NULL, error\n", __func__); -+ ret = 0; -+ } -+ -+ return ret; -+} -+ -+UINT32 osal_fifo_is_full(P_OSAL_FIFO pFifo) -+{ -+ UINT32 ret = 0; -+ -+ if (pFifo) { -+ ret = pFifo->FifoIsFull(pFifo); -+ } else { -+ pr_err("%s:pFifo = NULL, error\n", __func__); -+ ret = 0; -+ } -+ return ret; -+} -+ -+INT32 osal_wake_lock_init(P_OSAL_WAKE_LOCK pLock) -+{ -+ if (!pLock) -+ return -1; -+ -+ #ifdef CONFIG_PM_WAKELOCKS -+ wakeup_source_init(&pLock->wake_lock, pLock->name); -+ #else -+ wake_lock_init(&pLock->wake_lock, WAKE_LOCK_SUSPEND, pLock->name); -+ #endif -+ return 0; -+} -+ -+INT32 osal_wake_lock_deinit(P_OSAL_WAKE_LOCK pLock) -+{ -+ if (!pLock) -+ return -1; -+ -+ #ifdef CONFIG_PM_WAKELOCKS -+ wakeup_source_trash(&pLock->wake_lock); -+ #else -+ wake_lock_destroy(&pLock->wake_lock); -+ #endif -+ return 0; -+} -+ -+INT32 osal_wake_lock(P_OSAL_WAKE_LOCK pLock) -+{ -+ if (!pLock) -+ return -1; -+ -+ #ifdef CONFIG_PM_WAKELOCKS -+ __pm_stay_awake(&pLock->wake_lock); -+ #else -+ wake_lock(&pLock->wake_lock); -+ #endif -+ -+ return 0; -+} -+ -+INT32 osal_wake_unlock(P_OSAL_WAKE_LOCK pLock) -+{ -+ if (!pLock) -+ return -1; -+ -+ #ifdef CONFIG_PM_WAKELOCKS -+ __pm_relax(&pLock->wake_lock); -+ #else -+ wake_unlock(&pLock->wake_lock); -+ #endif -+ -+ return 0; -+ -+} -+ -+INT32 osal_wake_lock_count(P_OSAL_WAKE_LOCK pLock) -+{ -+ INT32 count = 0; -+ -+ if (!pLock) -+ return -1; -+ -+ #ifdef CONFIG_PM_WAKELOCKS -+ count = pLock->wake_lock.active; -+ #else -+ count = wake_lock_active(&pLock->wake_lock); -+ #endif -+ return count; -+} -+ -+/* -+ *sleepable lock operations APIs -+ *init -+ *lock -+ *unlock -+ *destroy -+ * -+*/ -+ -+#if !defined(CONFIG_PROVE_LOCKING) -+INT32 osal_unsleepable_lock_init(P_OSAL_UNSLEEPABLE_LOCK pUSL) -+{ -+ spin_lock_init(&(pUSL->lock)); -+ return 0; -+} -+#endif -+ -+INT32 osal_lock_unsleepable_lock(P_OSAL_UNSLEEPABLE_LOCK pUSL) -+{ -+ spin_lock_irqsave(&(pUSL->lock), pUSL->flag); -+ return 0; -+} -+ -+INT32 osal_unlock_unsleepable_lock(P_OSAL_UNSLEEPABLE_LOCK pUSL) -+{ -+ spin_unlock_irqrestore(&(pUSL->lock), pUSL->flag); -+ return 0; -+} -+ -+INT32 osal_unsleepable_lock_deinit(P_OSAL_UNSLEEPABLE_LOCK pUSL) -+{ -+ return 0; -+} -+ -+/* -+ *unsleepable operations APIs -+ *init -+ *lock -+ *unlock -+ *destroy -+ -+ * -+*/ -+ -+#if !defined(CONFIG_PROVE_LOCKING) -+INT32 osal_sleepable_lock_init(P_OSAL_SLEEPABLE_LOCK pSL) -+{ -+ mutex_init(&pSL->lock); -+ return 0; -+} -+#endif -+ -+INT32 osal_lock_sleepable_lock(P_OSAL_SLEEPABLE_LOCK pSL) -+{ -+ return mutex_lock_killable(&pSL->lock); -+} -+ -+INT32 osal_unlock_sleepable_lock(P_OSAL_SLEEPABLE_LOCK pSL) -+{ -+ mutex_unlock(&pSL->lock); -+ return 0; -+} -+ -+INT32 osal_sleepable_lock_deinit(P_OSAL_SLEEPABLE_LOCK pSL) -+{ -+ mutex_destroy(&pSL->lock); -+ return 0; -+} -+ -+INT32 osal_sleep_ms(UINT32 ms) -+{ -+ msleep(ms); -+ return 0; -+} -+ -+INT32 osal_udelay(UINT32 us) -+{ -+ udelay(us); -+ return 0; -+} -+ -+INT32 osal_gettimeofday(PINT32 sec, PINT32 usec) -+{ -+ INT32 ret = 0; -+ struct timeval now; -+ -+ do_gettimeofday(&now); -+ -+ if (sec != NULL) -+ *sec = now.tv_sec; -+ else -+ ret = -1; -+ -+ if (usec != NULL) -+ *usec = now.tv_usec; -+ else -+ ret = -1; -+ -+ return ret; -+} -+ -+INT32 osal_printtimeofday(const PUINT8 prefix) -+{ -+ INT32 ret; -+ INT32 sec; -+ INT32 usec; -+ -+ ret = osal_gettimeofday(&sec, &usec); -+ ret += osal_dbg_print("%s>sec=%d, usec=%d\n", prefix, sec, usec); -+ -+ return ret; -+} -+ -+VOID osal_buffer_dump(const UINT8 *buf, const UINT8 *title, const UINT32 len, const UINT32 limit) -+{ -+ INT32 k; -+ UINT32 dump_len; -+ -+ pr_warn("start of dump>[%s] len=%d, limit=%d,", title, len, limit); -+ -+ dump_len = ((0 != limit) && (len > limit)) ? limit : len; -+#if 0 -+ if (limit != 0) -+ len = (len > limit) ? (limit) : (len); -+ -+#endif -+ -+ for (k = 0; k < dump_len; k++) { -+ if ((k != 0) && (k % 16 == 0)) -+ pr_cont("\n"); -+ pr_cont("0x%02x ", buf[k]); -+ } -+ pr_warn("op.opId : 0xFFFFFFFF; -+} -+ -+MTK_WCN_BOOL osal_op_is_wait_for_signal(P_OSAL_OP pOp) -+{ -+ return (pOp && pOp->signal.timeoutValue) ? MTK_WCN_BOOL_TRUE : MTK_WCN_BOOL_FALSE; -+} -+ -+VOID osal_op_raise_signal(P_OSAL_OP pOp, INT32 result) -+{ -+ if (pOp) { -+ pOp->result = result; -+ osal_raise_signal(&pOp->signal); -+ } -+} -+ -+VOID osal_set_op_result(P_OSAL_OP pOp, INT32 result) -+{ -+ if (pOp) -+ pOp->result = result; -+ -+} -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/stp_chrdev_bt.c b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/stp_chrdev_bt.c -new file mode 100644 -index 000000000000..190fa3944d80 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/stp_chrdev_bt.c -@@ -0,0 +1,899 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#if WMT_CREATE_NODE_DYNAMIC -+#include -+#endif -+#include -+ -+#include "osal_typedef.h" -+#include "stp_exp.h" -+#include "wmt_exp.h" -+ -+MODULE_LICENSE("Dual BSD/GPL"); -+ -+#ifdef MTK_BT_HCI -+#define MTK_BT_DEBUG 0 -+#include -+#include -+#endif -+ -+ -+#define BT_DRIVER_NAME "mtk_stp_BT_chrdev" -+#define BT_DEV_MAJOR 192 /* Never used number */ -+ -+#define PFX "[MTK-BT] " -+#define BT_LOG_DBG 3 -+#define BT_LOG_INFO 2 -+#define BT_LOG_WARN 1 -+#define BT_LOG_ERR 0 -+ -+#define COMBO_IOC_MAGIC 0xb0 -+#define COMBO_IOCTL_FW_ASSERT _IOWR(COMBO_IOC_MAGIC, 0, int) -+#define COMBO_IOCTL_BT_IC_HW_VER _IOWR(COMBO_IOC_MAGIC, 1, void*) -+#define COMBO_IOCTL_BT_IC_FW_VER _IOWR(COMBO_IOC_MAGIC, 2, void*) -+#define COMBO_IOC_BT_HWVER _IOWR(COMBO_IOC_MAGIC, 3, void*) -+ -+static UINT32 gDbgLevel = BT_LOG_INFO; -+ -+#define BT_DBG_FUNC(fmt, arg...) \ -+ do { if (gDbgLevel >= BT_LOG_DBG) \ -+ pr_debug(PFX "%s: " fmt, __func__ , ##arg); \ -+ } while (0) -+#define BT_INFO_FUNC(fmt, arg...) \ -+ do { if (gDbgLevel >= BT_LOG_INFO) \ -+ pr_warn(PFX "%s: " fmt, __func__ , ##arg); \ -+ } while (0) -+#define BT_WARN_FUNC(fmt, arg...) \ -+ do { if (gDbgLevel >= BT_LOG_WARN) \ -+ pr_err(PFX "%s: " fmt, __func__ , ##arg); \ -+ } while (0) -+#define BT_ERR_FUNC(fmt, arg...) \ -+ do { if (gDbgLevel >= BT_LOG_ERR) \ -+ pr_err(PFX "%s: " fmt, __func__ , ##arg); \ -+ } while (0) -+ -+#define VERSION "1.0" -+ -+#ifdef MTK_BT_HCI -+ -+#define NUM_REASSEMBLY 32 -+struct mtk_hci { -+ struct hci_dev *hdev; -+ struct work_struct work; -+ struct sk_buff_head txq; -+ struct sk_buff *reassembly[NUM_REASSEMBLY]; -+}; -+ -+static struct mtk_hci mtk_hci; -+ -+#endif -+ -+#if WMT_CREATE_NODE_DYNAMIC -+struct class *stpbt_class = NULL; -+struct device *stpbt_dev = NULL; -+#endif -+ -+static INT32 BT_devs = 1; /* Device count */ -+static INT32 BT_major = BT_DEV_MAJOR; /* Dynamic allocation */ -+module_param(BT_major, uint, 0); -+static struct cdev BT_cdev; -+ -+#define BT_BUFFER_SIZE 2048 -+static UINT8 i_buf[BT_BUFFER_SIZE]; /* Input buffer of read() */ -+static UINT8 o_buf[BT_BUFFER_SIZE]; /* Output buffer of write() */ -+ -+static struct semaphore wr_mtx, rd_mtx; -+/* Wait queue for poll and read */ -+static wait_queue_head_t inq; -+static DECLARE_WAIT_QUEUE_HEAD(BT_wq); -+static INT32 flag; -+/* Reset flag for whole chip reset senario */ -+static volatile INT32 rstflag; -+ -+#ifdef MTK_BT_HCI -+static int hci_reassembly(struct hci_dev *hdev, int type, void *data, -+ int count, __u8 index) -+{ -+ int len = 0; -+ int hlen = 0; -+ int offset = 0; -+ int remain = count; -+ struct sk_buff *skb; -+ struct bt_skb_cb *scb; -+ u16 opcode = 0; -+ unsigned char *pdata = data; -+ -+ struct mtk_hci *info = NULL; -+ struct hci_event_hdr *ehdr = NULL; -+ struct hci_ev_cmd_complete *ev = NULL; -+ struct hci_rp_read_local_ext_features *ext = NULL; -+ -+ info = hci_get_drvdata(hdev); -+ if ( NULL == info ) { -+ printk(KERN_ERR "mtk_bt_hci: invalid info point\n"); -+ return 0; -+ } -+ -+ if ((type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT) || -+ index >= NUM_REASSEMBLY) -+ return -EILSEQ; -+ -+ skb = info->reassembly[index]; -+ -+ if (!skb) { -+ switch (type) { -+ case HCI_ACLDATA_PKT: -+ len = HCI_MAX_FRAME_SIZE; -+ hlen = HCI_ACL_HDR_SIZE; -+ break; -+ case HCI_EVENT_PKT: -+ len = HCI_MAX_EVENT_SIZE; -+ hlen = HCI_EVENT_HDR_SIZE; -+ break; -+ case HCI_SCODATA_PKT: -+ len = HCI_MAX_SCO_SIZE; -+ hlen = HCI_SCO_HDR_SIZE; -+ break; -+ } -+ -+ skb = bt_skb_alloc(len, GFP_ATOMIC); -+ if (!skb) -+ return -ENOMEM; -+ -+ scb = (void *) skb->cb; -+ scb->expect = hlen; -+ scb->pkt_type = type; -+ -+ info->reassembly[index] = skb; -+ } -+ -+ while (count) { -+ scb = (void *) skb->cb; -+ len = min_t(uint, scb->expect, count); -+ -+ /* -+ * Workaround for MT7623+MT6625 BT: the max page in response of cmd READ_LOCAL_EXT_FEATURES -+ * should be 1, instead of 2, so changing it to 1 here -+ */ -+ -+ if (HCI_EVENT_PKT == type) -+ { -+ ehdr = (void *)pdata; -+ offset = sizeof(struct hci_event_hdr); -+ if ( HCI_EV_CMD_COMPLETE == ehdr->evt) -+ { -+ ev = (struct hci_ev_cmd_complete *)&pdata[offset]; -+ -+ offset += sizeof(struct hci_ev_cmd_complete); -+ -+ opcode = __le16_to_cpu(ev->opcode); -+ if(HCI_OP_READ_LOCAL_EXT_FEATURES == opcode) { -+ ext = (struct hci_rp_read_local_ext_features *) &pdata[offset]; -+ if( !ext->status && ext->max_page >= 2) { -+ pr_info("%s: this workaround is applied for mediatek BT\n", __func__); -+ ext->max_page = 1; -+ } -+ } -+ -+ } -+ } -+ -+ memcpy(skb_put(skb, len), data, len); -+ -+ count -= len; -+ data += len; -+ scb->expect -= len; -+ remain = count; -+ -+ switch (type) { -+ case HCI_EVENT_PKT: -+ if (skb->len == HCI_EVENT_HDR_SIZE) { -+ struct hci_event_hdr *h = hci_event_hdr(skb); -+ -+ scb->expect = h->plen; -+ -+ if (skb_tailroom(skb) < scb->expect) { -+ kfree_skb(skb); -+ info->reassembly[index] = NULL; -+ return -ENOMEM; -+ } -+ } -+ -+ break; -+ -+ case HCI_ACLDATA_PKT: -+ if (skb->len == HCI_ACL_HDR_SIZE) { -+ struct hci_acl_hdr *h = hci_acl_hdr(skb); -+ -+ scb->expect = __le16_to_cpu(h->dlen); -+ -+ if (skb_tailroom(skb) < scb->expect) { -+ kfree_skb(skb); -+ info->reassembly[index] = NULL; -+ return -ENOMEM; -+ } -+ } -+ break; -+ -+ case HCI_SCODATA_PKT: -+ if (skb->len == HCI_SCO_HDR_SIZE) { -+ struct hci_sco_hdr *h = hci_sco_hdr(skb); -+ -+ scb->expect = h->dlen; -+ -+ if (skb_tailroom(skb) < scb->expect) { -+ kfree_skb(skb); -+ info->reassembly[index] = NULL; -+ return -ENOMEM; -+ } -+ } -+ break; -+ } -+ -+ if (scb->expect == 0) { -+ /* Complete frame */ -+ -+ bt_cb(skb)->pkt_type = type; -+ hci_recv_frame(hdev, skb); -+ -+ info->reassembly[index] = NULL; -+ return remain; -+ } -+ } -+ -+ return remain; -+} -+ -+int hci_recv_fragment(struct hci_dev *hdev, int type, void *data, int count) -+{ -+ int rem = 0; -+ -+ if (type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT) -+ return -EILSEQ; -+ -+ while (count) { -+ rem = hci_reassembly(hdev, type, data, count, type - 1); -+ if (rem < 0) -+ return rem; -+ -+ data += (count - rem); -+ count = rem; -+ } -+ -+ return rem; -+} -+#endif -+ -+#ifdef MTK_BT_HCI -+void -+hex_dump(char *prefix, char *p, int len) -+{ -+ int i; -+ -+ pr_err("%s ", prefix); -+ for (i = 0; i < len; i++) -+ pr_err("%02x ", (*p++ & 0xff)); -+ pr_err("\n"); -+} -+ -+static int -+mtk_bt_hci_open(struct hci_dev *hdev) -+{ -+ int err = 0; -+ -+#if MTK_BT_DEBUG == 1 -+ pr_err("# %s\n", __func__); -+#endif -+ -+ err = mtk_wcn_wmt_func_on(WMTDRV_TYPE_BT); -+ if (err != MTK_WCN_BOOL_TRUE) { -+ pr_err("%s func on failed with %d\n", __func__, err); -+ return -ENODEV; -+ } -+ -+ set_bit(HCI_RUNNING, &hdev->flags); -+ -+ mtk_wcn_stp_set_bluez(1); -+ -+ return 0; -+} -+ -+static int -+mtk_bt_hci_close(struct hci_dev *hdev) -+{ -+ int err = 0; -+ -+#if MTK_BT_DEBUG == 1 -+ pr_err("# %s\n", __func__); -+#endif -+ -+ mtk_wcn_stp_set_bluez(0); -+ -+ clear_bit(HCI_RUNNING, &hdev->flags); -+ -+ err = mtk_wcn_wmt_func_off(WMTDRV_TYPE_BT); -+ if (err != MTK_WCN_BOOL_TRUE) { -+ pr_err("%s func off failed with %d\n", __func__, err); -+ return -EIO; -+ } -+ -+ return 0; -+} -+ -+static void -+mtk_bt_hci_work(struct work_struct *work) -+{ -+ int err; -+ struct sk_buff *skb; -+ -+#if MTK_BT_DEBUG == 1 -+ pr_err("# %s\n", __func__); -+#endif -+ -+ while ((skb = skb_dequeue(&mtk_hci.txq))) { -+ skb_push(skb, 1); -+ skb->data[0] = bt_cb(skb)->pkt_type; -+ -+#if MTK_BT_DEBUG == 1 -+ hex_dump(">>", skb->data, skb->len); -+#endif -+ -+ err = mtk_wcn_stp_send_data(skb->data, skb->len, BT_TASK_INDX); -+ if (err < 0) { -+ pr_err("%s err=%d\n", __func__, err); -+ mtk_hci.hdev->stat.err_tx++; -+ skb_queue_head(&mtk_hci.txq, skb); -+ break; -+ } -+ -+ mtk_hci.hdev->stat.byte_tx += skb->len; -+ kfree_skb(skb); -+ } -+} -+ -+static int -+mtk_bt_hci_send(struct hci_dev *hdev, struct sk_buff *skb) -+{ -+#if MTK_BT_DEBUG == 1 -+ pr_err("# %s\n", __func__); -+#endif -+ -+ if (mtk_hci.hdev && !test_bit(HCI_RUNNING, &mtk_hci.hdev->flags)) -+ return -EBUSY; -+ -+ switch (bt_cb(skb)->pkt_type) { -+ case HCI_COMMAND_PKT: -+ mtk_hci.hdev->stat.cmd_tx++; -+ break; -+ -+ case HCI_ACLDATA_PKT: -+ mtk_hci.hdev->stat.acl_tx++; -+ break; -+ -+ case HCI_SCODATA_PKT: -+ mtk_hci.hdev->stat.sco_tx++; -+ break; -+ -+ default: -+ return -EILSEQ; -+ } -+ -+ skb_queue_tail(&mtk_hci.txq, skb); -+ schedule_work(&mtk_hci.work); -+ -+ return 0; -+} -+ -+static int -+mtk_bt_hci_flush(struct hci_dev *hdev) -+{ -+ pr_err("%s: todo\n", __func__); -+ -+ return 0; -+} -+ -+static void -+mtk_bt_hci_receive(const PUINT8 data, INT32 size) -+{ -+ int err; -+ -+#if MTK_BT_DEBUG == 1 -+ pr_err("# %s\n", __func__); -+ hex_dump("<<", data, size); -+#endif -+ -+ err = hci_recv_fragment(mtk_hci.hdev, data[0], (void *)&data[1], size - 1); -+ if (err < 0) -+ pr_err("%s: hci_recv_fragment failed with %d\n", __func__, err); -+ -+ if (mtk_hci.hdev) -+ mtk_hci.hdev->stat.byte_rx += size - 1; -+} -+ -+static void -+mtk_bt_hci_notify(struct hci_dev *hdev, unsigned int evt) -+{ -+ static const char * const notify_str[] = { -+ "null", -+ "HCI_NOTIFY_CONN_ADD", -+ "HCI_NOTIFY_CONN_DEL", -+ "HCI_NOTIFY_VOICE_SETTING" -+ }; -+ -+ if (evt > HCI_NOTIFY_VOICE_SETTING) -+ pr_info("%s event=0x%x\n", __func__, evt); -+ else -+ pr_info("%s event(%d)=%s\n", __func__, evt, notify_str[evt]); -+} -+#endif -+ -+#ifdef MTK_BT_HCI -+ -+int mtk_bt_hci_init(void) -+{ -+ INT32 hci_err = 0; -+ -+ mtk_hci.hdev = hci_alloc_dev(); -+ if (!(mtk_hci.hdev)) { -+ mtk_hci.hdev = NULL; -+ BT_ERR_FUNC("%s hci_alloc_dev failed\n", __func__); -+ return -ENOMEM; -+ } -+ -+ mtk_hci.hdev->bus = HCI_SDIO; -+ mtk_hci.hdev->open = mtk_bt_hci_open; -+ mtk_hci.hdev->close = mtk_bt_hci_close; -+ mtk_hci.hdev->send = mtk_bt_hci_send; -+ mtk_hci.hdev->flush = mtk_bt_hci_flush; -+ mtk_hci.hdev->notify = mtk_bt_hci_notify; -+ SET_HCIDEV_DEV(mtk_hci.hdev, stpbt_dev); -+ -+ hci_set_drvdata(mtk_hci.hdev, &mtk_hci); -+ -+ mtk_wcn_stp_register_if_rx(mtk_bt_hci_receive); -+ -+ hci_err = hci_register_dev(mtk_hci.hdev); -+ if (hci_err) { -+ BT_ERR_FUNC("%s hci_register_dev failed with %d\n", __func__, hci_err); -+ hci_free_dev(mtk_hci.hdev); -+ mtk_hci.hdev = NULL; -+ return hci_err; -+ } -+ -+ skb_queue_head_init(&mtk_hci.txq); -+ INIT_WORK(&mtk_hci.work, mtk_bt_hci_work); -+ -+ return 0; -+} -+#endif -+ -+ -+static VOID bt_cdev_rst_cb(ENUM_WMTDRV_TYPE_T src, -+ ENUM_WMTDRV_TYPE_T dst, ENUM_WMTMSG_TYPE_T type, PVOID buf, UINT32 sz) -+{ -+ /* -+ Handle whole chip reset messages -+ */ -+ ENUM_WMTRSTMSG_TYPE_T rst_msg; -+ -+ if (sz <= sizeof(ENUM_WMTRSTMSG_TYPE_T)) { -+ memcpy((PINT8)&rst_msg, (PINT8)buf, sz); -+ BT_DBG_FUNC("src = %d, dst = %d, type = %d, buf = 0x%x sz = %d, max = %d\n", src, -+ dst, type, rst_msg, sz, WMTRSTMSG_RESET_MAX); -+ if ((src == WMTDRV_TYPE_WMT) && (dst == WMTDRV_TYPE_BT) -+ && (type == WMTMSG_TYPE_RESET)) { -+ if (rst_msg == WMTRSTMSG_RESET_START) { -+ BT_INFO_FUNC("BT reset start!\n"); -+ rstflag = 1; -+ wake_up_interruptible(&inq); -+ -+ } else if (rst_msg == WMTRSTMSG_RESET_END) { -+ BT_INFO_FUNC("BT reset end!\n"); -+ rstflag = 2; -+ wake_up_interruptible(&inq); -+ } -+ } -+ } else { -+ /* Invalid message format */ -+ BT_WARN_FUNC("Invalid message format!\n"); -+ } -+} -+ -+VOID BT_event_cb(VOID) -+{ -+ BT_DBG_FUNC("BT_event_cb()\n"); -+ -+ flag = 1; -+ -+ /* -+ * Finally, wake up any reader blocked in poll or read -+ */ -+ wake_up_interruptible(&inq); -+ wake_up(&BT_wq); -+} -+ -+unsigned int BT_poll(struct file *filp, poll_table *wait) -+{ -+ UINT32 mask = 0; -+ -+/* down(&wr_mtx); */ -+ /* -+ * The buffer is circular; it is considered full -+ * if "wp" is right behind "rp". "left" is 0 if the -+ * buffer is empty, and it is "1" if it is completely full. -+ */ -+ if (mtk_wcn_stp_is_rxqueue_empty(BT_TASK_INDX)) { -+ poll_wait(filp, &inq, wait); -+ -+ if (!mtk_wcn_stp_is_rxqueue_empty(BT_TASK_INDX) || rstflag) -+ /* BT Rx queue has valid data, or whole chip reset occurs */ -+ mask |= POLLIN | POLLRDNORM; /* Readable */ -+ } else { -+ mask |= POLLIN | POLLRDNORM; /* Readable */ -+ } -+ -+ /* Do we need condition here? */ -+ mask |= POLLOUT | POLLWRNORM; /* Writable */ -+/* up(&wr_mtx); */ -+ return mask; -+} -+ -+ssize_t BT_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos) -+{ -+ INT32 retval = 0; -+ INT32 write_size; -+ INT32 written = 0; -+ -+ down(&wr_mtx); -+ -+ BT_DBG_FUNC("%s: count %zd pos %lld\n", __func__, count, *f_pos); -+ if (rstflag) { -+ if (rstflag == 1) { /* Reset start */ -+ retval = -88; -+ BT_INFO_FUNC("%s: detect whole chip reset start\n", __func__); -+ } else if (rstflag == 2) { /* Reset end */ -+ retval = -99; -+ BT_INFO_FUNC("%s: detect whole chip reset end\n", __func__); -+ } -+ goto OUT; -+ } -+ -+ if (count > 0) { -+ if (count < BT_BUFFER_SIZE) { -+ write_size = count; -+ } else { -+ write_size = BT_BUFFER_SIZE; -+ BT_ERR_FUNC("%s: count > BT_BUFFER_SIZE\n", __func__); -+ } -+ -+ if (copy_from_user(&o_buf[0], &buf[0], write_size)) { -+ retval = -EFAULT; -+ goto OUT; -+ } -+ -+ written = mtk_wcn_stp_send_data(&o_buf[0], write_size, BT_TASK_INDX); -+ if (0 == written) { -+ retval = -ENOSPC; -+ /* No space is available, native program should not call BT_write with no delay */ -+ BT_ERR_FUNC -+ ("Packet length %zd, sent length %d, retval = %d\n", -+ count, written, retval); -+ } else { -+ retval = written; -+ } -+ -+ } else { -+ retval = -EFAULT; -+ BT_ERR_FUNC("Packet length %zd is not allowed, retval = %d\n", count, retval); -+ } -+ -+OUT: -+ up(&wr_mtx); -+ return retval; -+} -+ -+ssize_t BT_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos) -+{ -+ static int chip_reset_count; -+ INT32 retval = 0; -+ -+ down(&rd_mtx); -+ -+ BT_DBG_FUNC("%s: count %zd pos %lld\n", __func__, count, *f_pos); -+ if (rstflag) { -+ if (rstflag == 1) { /* Reset start */ -+ retval = -88; -+ if ((chip_reset_count%500) == 0) -+ BT_INFO_FUNC("%s: detect whole chip reset start, %d\n", __func__, chip_reset_count); -+ chip_reset_count++; -+ } else if (rstflag == 2) { /* Reset end */ -+ retval = -99; -+ BT_INFO_FUNC("%s: detect whole chip reset end\n", __func__); -+ chip_reset_count = 0; -+ } -+ goto OUT; -+ } -+ -+ if (count > BT_BUFFER_SIZE) { -+ count = BT_BUFFER_SIZE; -+ BT_ERR_FUNC("%s: count > BT_BUFFER_SIZE\n", __func__); -+ } -+ -+ retval = mtk_wcn_stp_receive_data(i_buf, count, BT_TASK_INDX); -+ -+ while (retval == 0) { /* Got nothing, wait for STP's signal */ -+ /* -+ * If nonblocking mode, return directly. -+ * O_NONBLOCK is specified during open() -+ */ -+ if (filp->f_flags & O_NONBLOCK) { -+ BT_DBG_FUNC("Non-blocking BT_read\n"); -+ retval = -EAGAIN; -+ goto OUT; -+ } -+ -+ BT_DBG_FUNC("%s: wait_event 1\n", __func__); -+ wait_event(BT_wq, flag != 0); -+ BT_DBG_FUNC("%s: wait_event 2\n", __func__); -+ flag = 0; -+ retval = mtk_wcn_stp_receive_data(i_buf, count, BT_TASK_INDX); -+ BT_DBG_FUNC("%s: mtk_wcn_stp_receive_data returns %d\n", __func__, retval); -+ } -+ -+ /* Got something from STP driver */ -+ if (copy_to_user(buf, i_buf, retval)) { -+ retval = -EFAULT; -+ goto OUT; -+ } -+ -+OUT: -+ up(&rd_mtx); -+ BT_DBG_FUNC("%s: retval = %d\n", __func__, retval); -+ return retval; -+} -+ -+/* int BT_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) */ -+long BT_unlocked_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) -+{ -+ INT32 retval = 0; -+ MTK_WCN_BOOL bRet = MTK_WCN_BOOL_TRUE; -+ ENUM_WMTHWVER_TYPE_T hw_ver_sym = WMTHWVER_INVALID; -+ -+ BT_DBG_FUNC("%s: cmd: 0x%x\n", __func__, cmd); -+ -+ switch (cmd) { -+ case COMBO_IOC_BT_HWVER: -+ /* Get combo HW version */ -+ hw_ver_sym = mtk_wcn_wmt_hwver_get(); -+ BT_INFO_FUNC("%s: HW version = %d, sizeof(hw_ver_sym) = %zd\n", -+ __func__, hw_ver_sym, sizeof(hw_ver_sym)); -+ if (copy_to_user((int __user *)arg, &hw_ver_sym, sizeof(hw_ver_sym))) -+ retval = -EFAULT; -+ break; -+ -+ case COMBO_IOCTL_FW_ASSERT: -+ /* Trigger FW assert for debug */ -+ BT_INFO_FUNC("%s: Host trigger FW assert......, reason:%lu\n", __func__, arg); -+ bRet = mtk_wcn_wmt_assert(WMTDRV_TYPE_BT, arg); -+ if (bRet == MTK_WCN_BOOL_TRUE) { -+ BT_INFO_FUNC("Host trigger FW assert succeed\n"); -+ retval = 0; -+ } else { -+ BT_ERR_FUNC("Host trigger FW assert Failed\n"); -+ retval = (-EBUSY); -+ } -+ break; -+ case COMBO_IOCTL_BT_IC_HW_VER: -+ retval = mtk_wcn_wmt_ic_info_get(WMTCHIN_HWVER); -+ break; -+ case COMBO_IOCTL_BT_IC_FW_VER: -+ retval = mtk_wcn_wmt_ic_info_get(WMTCHIN_FWVER); -+ break; -+ default: -+ retval = -EFAULT; -+ BT_ERR_FUNC("Unknown cmd (%d)\n", cmd); -+ break; -+ } -+ -+ return retval; -+} -+ -+long BT_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) -+{ -+ return BT_unlocked_ioctl(filp, cmd, arg); -+} -+ -+static int BT_open(struct inode *inode, struct file *file) -+{ -+ BT_INFO_FUNC("%s: major %d minor %d pid %d\n", __func__, imajor(inode), iminor(inode), current->pid); -+ -+ /* Turn on BT */ -+ if (MTK_WCN_BOOL_FALSE == mtk_wcn_wmt_func_on(WMTDRV_TYPE_BT)) { -+ BT_WARN_FUNC("WMT turn on BT fail!\n"); -+ return -ENODEV; -+ } -+ -+ BT_INFO_FUNC("WMT turn on BT OK!\n"); -+ rstflag = 0; -+ -+ if (mtk_wcn_stp_is_ready()) { -+ -+ mtk_wcn_stp_set_bluez(0); -+ -+ BT_INFO_FUNC("Now it's in MTK Bluetooth Mode\n"); -+ BT_INFO_FUNC("STP is ready!\n"); -+ -+ BT_DBG_FUNC("Register BT event callback!\n"); -+ mtk_wcn_stp_register_event_cb(BT_TASK_INDX, BT_event_cb); -+ } else { -+ BT_ERR_FUNC("STP is not ready\n"); -+ mtk_wcn_wmt_func_off(WMTDRV_TYPE_BT); -+ return -ENODEV; -+ } -+ -+ BT_DBG_FUNC("Register BT reset callback!\n"); -+ mtk_wcn_wmt_msgcb_reg(WMTDRV_TYPE_BT, bt_cdev_rst_cb); -+ -+ /* init_MUTEX(&wr_mtx); */ -+ sema_init(&wr_mtx, 1); -+ /* init_MUTEX(&rd_mtx); */ -+ sema_init(&rd_mtx, 1); -+ BT_INFO_FUNC("%s: finish\n", __func__); -+ -+ return 0; -+} -+ -+static int BT_close(struct inode *inode, struct file *file) -+{ -+ BT_INFO_FUNC("%s: major %d minor %d pid %d\n", __func__, imajor(inode), iminor(inode), current->pid); -+ rstflag = 0; -+ mtk_wcn_wmt_msgcb_unreg(WMTDRV_TYPE_BT); -+ mtk_wcn_stp_register_event_cb(BT_TASK_INDX, NULL); -+ -+ if (MTK_WCN_BOOL_FALSE == mtk_wcn_wmt_func_off(WMTDRV_TYPE_BT)) { -+ BT_ERR_FUNC("WMT turn off BT fail!\n"); -+ return -EIO; /* Mostly, native program will not check this return value. */ -+ } -+ -+ BT_INFO_FUNC("WMT turn off BT OK!\n"); -+ -+ return 0; -+} -+ -+const struct file_operations BT_fops = { -+ .open = BT_open, -+ .release = BT_close, -+ .read = BT_read, -+ .write = BT_write, -+ /* .ioctl = BT_ioctl, */ -+ .unlocked_ioctl = BT_unlocked_ioctl, -+ .compat_ioctl = BT_compat_ioctl, -+ .poll = BT_poll -+}; -+ -+ -+ -+static int BT_init(void) -+{ -+ dev_t dev = MKDEV(BT_major, 0); -+ INT32 alloc_ret = 0; -+ INT32 cdev_err = 0; -+ -+ /* Static allocate char device */ -+ alloc_ret = register_chrdev_region(dev, 1, BT_DRIVER_NAME); -+ if (alloc_ret) { -+ BT_ERR_FUNC("%s: Failed to register char device\n", __func__); -+ return alloc_ret; -+ } -+ -+ cdev_init(&BT_cdev, &BT_fops); -+ BT_cdev.owner = THIS_MODULE; -+ -+ cdev_err = cdev_add(&BT_cdev, dev, BT_devs); -+ if (cdev_err) -+ goto error; -+ -+#if WMT_CREATE_NODE_DYNAMIC -+ stpbt_class = class_create(THIS_MODULE, "stpbt"); -+ if (IS_ERR(stpbt_class)) -+ goto error; -+ stpbt_dev = device_create(stpbt_class, NULL, dev, NULL, "stpbt"); -+ if (IS_ERR(stpbt_dev)) -+ goto error; -+#endif -+ -+ BT_INFO_FUNC("%s driver(major %d) installed\n", BT_DRIVER_NAME, BT_major); -+ -+ /* Init wait queue */ -+ init_waitqueue_head(&(inq)); -+ -+#ifdef MTK_BT_HCI -+ mtk_bt_hci_init(); -+#endif -+ -+ return 0; -+ -+error: -+#if WMT_CREATE_NODE_DYNAMIC -+ if (!IS_ERR(stpbt_dev)) -+ device_destroy(stpbt_class, dev); -+ if (!IS_ERR(stpbt_class)) { -+ class_destroy(stpbt_class); -+ stpbt_class = NULL; -+ } -+#endif -+ if (cdev_err == 0) -+ cdev_del(&BT_cdev); -+ -+ if (alloc_ret == 0) -+ unregister_chrdev_region(dev, BT_devs); -+ -+ return -1; -+} -+ -+static void BT_exit(void) -+{ -+ dev_t dev = MKDEV(BT_major, 0); -+ -+#if WMT_CREATE_NODE_DYNAMIC -+ if (stpbt_dev) { -+ device_destroy(stpbt_class, dev); -+ stpbt_dev = NULL; -+ } -+ if (stpbt_class) { -+ class_destroy(stpbt_class); -+ stpbt_class = NULL; -+ } -+#endif -+ -+ cdev_del(&BT_cdev); -+ unregister_chrdev_region(dev, BT_devs); -+ -+ BT_INFO_FUNC("%s driver removed\n", BT_DRIVER_NAME); -+} -+ -+#ifdef MTK_WCN_REMOVE_KERNEL_MODULE -+ -+int mtk_wcn_stpbt_drv_init(void) -+{ -+ return BT_init(); -+} -+EXPORT_SYMBOL(mtk_wcn_stpbt_drv_init); -+ -+void mtk_wcn_stpbt_drv_exit(void) -+{ -+ return BT_exit(); -+} -+EXPORT_SYMBOL(mtk_wcn_stpbt_drv_exit); -+ -+#else -+ -+module_init(BT_init); -+module_exit(BT_exit); -+ -+#endif -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/wmt_chrdev_wifi.c b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/wmt_chrdev_wifi.c -new file mode 100644 -index 000000000000..3c7b2969c98a ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/wmt_chrdev_wifi.c -@@ -0,0 +1,668 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "wmt_exp.h" -+#include "stp_exp.h" -+ -+MODULE_LICENSE("Dual BSD/GPL"); -+ -+#define WIFI_DRIVER_NAME "mtk_wmt_WIFI_chrdev" -+#define WIFI_DEV_MAJOR 155 -+ -+#define PFX "[MTK-WIFI] " -+#define WIFI_LOG_DBG 3 -+#define WIFI_LOG_INFO 2 -+#define WIFI_LOG_WARN 1 -+#define WIFI_LOG_ERR 0 -+ -+UINT32 gDbgLevel = WIFI_LOG_DBG; -+ -+#define WIFI_DBG_FUNC(fmt, arg...)\ -+ do {if (gDbgLevel >= WIFI_LOG_DBG) printk(PFX "%s: " fmt, __func__ , ##arg); } while (0) -+#define WIFI_INFO_FUNC(fmt, arg...)\ -+ do {if (gDbgLevel >= WIFI_LOG_INFO) printk(PFX "%s: " fmt, __func__ , ##arg); } while (0) -+#define WIFI_WARN_FUNC(fmt, arg...)\ -+ do {if (gDbgLevel >= WIFI_LOG_WARN) printk(PFX "%s: " fmt, __func__ , ##arg); } while (0) -+#define WIFI_ERR_FUNC(fmt, arg...)\ -+ do {if (gDbgLevel >= WIFI_LOG_ERR) printk(PFX "%s: " fmt, __func__ , ##arg); } while (0) -+#define WIFI_TRC_FUNC(f)\ -+ do {if (gDbgLevel >= WIFI_LOG_DBG) printk(PFX "<%s> <%d>\n", __func__, __LINE__); } while (0) -+ -+#define VERSION "1.0" -+ -+#define WLAN_IFACE_NAME "wlan0" -+#if CFG_TC1_FEATURE -+#define LEGACY_IFACE_NAME "legacy0" -+#endif -+ -+enum { -+ WLAN_MODE_HALT, -+ WLAN_MODE_AP, -+ WLAN_MODE_STA_P2P, -+ WLAN_MODE_MAX -+}; -+static INT32 wlan_mode = WLAN_MODE_HALT; -+static INT32 powered; -+static INT8 *ifname = WLAN_IFACE_NAME; -+#if CFG_TC1_FEATURE -+volatile INT32 wlan_if_changed = 0; -+EXPORT_SYMBOL(wlan_if_changed); -+#endif -+ -+typedef enum _ENUM_RESET_STATUS_T { -+ RESET_FAIL, -+ RESET_SUCCESS -+} ENUM_RESET_STATUS_T; -+ -+/* -+ * enable = 1, mode = 0 => init P2P network -+ * enable = 1, mode = 1 => init Soft AP network -+ * enable = 0 => uninit P2P/AP network -+ */ -+typedef struct _PARAM_CUSTOM_P2P_SET_STRUCT_T { -+ UINT32 u4Enable; -+ UINT32 u4Mode; -+} PARAM_CUSTOM_P2P_SET_STRUCT_T, *P_PARAM_CUSTOM_P2P_SET_STRUCT_T; -+typedef INT32(*set_p2p_mode) (struct net_device *netdev, PARAM_CUSTOM_P2P_SET_STRUCT_T p2pmode); -+ -+static set_p2p_mode pf_set_p2p_mode; -+VOID register_set_p2p_mode_handler(set_p2p_mode handler) -+{ -+ WIFI_INFO_FUNC("(pid %d) register set p2p mode handler %p\n", current->pid, handler); -+ pf_set_p2p_mode = handler; -+} -+EXPORT_SYMBOL(register_set_p2p_mode_handler); -+ -+/* For dynamical debug level setting */ -+/* copy of debug.h in wlan driver */ -+#define DBG_CLASS_ERROR BIT(0) -+#define DBG_CLASS_WARN BIT(1) -+#define DBG_CLASS_STATE BIT(2) -+#define DBG_CLASS_EVENT BIT(3) -+#define DBG_CLASS_TRACE BIT(4) -+#define DBG_CLASS_INFO BIT(5) -+#define DBG_CLASS_LOUD BIT(6) -+#define DBG_CLASS_TEMP BIT(7) -+#define DBG_CLASS_MASK BITS(0, 7) -+ -+typedef enum _ENUM_DBG_MODULE_T { -+ DBG_INIT_IDX = 0, /* For driver initial */ -+ DBG_HAL_IDX, /* For HAL(HW) Layer */ -+ DBG_INTR_IDX, /* For Interrupt */ -+ DBG_REQ_IDX, -+ DBG_TX_IDX, -+ DBG_RX_IDX, -+ DBG_RFTEST_IDX, /* For RF test mode */ -+ DBG_EMU_IDX, /* Developer specific */ -+ -+ DBG_SW1_IDX, /* Developer specific */ -+ DBG_SW2_IDX, /* Developer specific */ -+ DBG_SW3_IDX, /* Developer specific */ -+ DBG_SW4_IDX, /* Developer specific */ -+ -+ DBG_HEM_IDX, /* HEM */ -+ DBG_AIS_IDX, /* AIS */ -+ DBG_RLM_IDX, /* RLM */ -+ DBG_MEM_IDX, /* RLM */ -+ DBG_CNM_IDX, /* CNM */ -+ DBG_RSN_IDX, /* RSN */ -+ DBG_BSS_IDX, /* BSS */ -+ DBG_SCN_IDX, /* SCN */ -+ DBG_SAA_IDX, /* SAA */ -+ DBG_AAA_IDX, /* AAA */ -+ DBG_P2P_IDX, /* P2P */ -+ DBG_QM_IDX, /* QUE_MGT */ -+ DBG_SEC_IDX, /* SEC */ -+ DBG_BOW_IDX, /* BOW */ -+ DBG_WAPI_IDX, /* WAPI */ -+ DBG_ROAMING_IDX, /* ROAMING */ -+ -+ DBG_MODULE_NUM /* Notice the XLOG check */ -+} ENUM_DBG_MODULE_T; -+/* end */ -+typedef VOID(*set_dbg_level) (UINT8 modules[DBG_MODULE_NUM]); -+ -+UINT8 wlan_dbg_level[DBG_MODULE_NUM]; -+static set_dbg_level pf_set_dbg_level; -+VOID register_set_dbg_level_handler(set_dbg_level handler) -+{ -+ pf_set_dbg_level = handler; -+} -+EXPORT_SYMBOL(register_set_dbg_level_handler); -+ -+static INT32 WIFI_devs = 1; -+static INT32 WIFI_major = WIFI_DEV_MAJOR; -+module_param(WIFI_major, uint, 0); -+static struct cdev WIFI_cdev; -+volatile INT32 retflag = 0; -+static struct semaphore wr_mtx; -+ -+#define WMT_CHECK_DO_CHIP_RESET() \ -+do { \ -+ if (g_IsNeedDoChipReset) { \ -+ g_IsNeedDoChipReset = 0; \ -+ WIFI_ERR_FUNC("Do core dump and chip reset in %s line %d\n", __func__, __LINE__); \ -+ mtk_wcn_wmt_assert(WMTDRV_TYPE_WIFI, 40); \ -+ } \ -+} while (0) -+ -+/******************************************************************* -+ * WHOLE CHIP RESET PROCEDURE: -+ * -+ * WMTRSTMSG_RESET_START callback -+ * -> wlanRemove -+ * -> WMTRSTMSG_RESET_END callback -+ * -+ ******************************************************************* -+*/ -+/*-----------------------------------------------------------------*/ -+/* -+ * Receiving RESET_START message -+ */ -+/*-----------------------------------------------------------------*/ -+INT32 wifi_reset_start(VOID) -+{ -+ struct net_device *netdev = NULL; -+ PARAM_CUSTOM_P2P_SET_STRUCT_T p2pmode; -+ -+ down(&wr_mtx); -+ -+ if (powered == 1) { -+ netdev = dev_get_by_name(&init_net, ifname); -+ if (netdev == NULL) { -+ WIFI_ERR_FUNC("Fail to get %s net device\n", ifname); -+ } else { -+ p2pmode.u4Enable = 0; -+ p2pmode.u4Mode = 0; -+ -+ if (pf_set_p2p_mode) { -+ if (pf_set_p2p_mode(netdev, p2pmode) != 0) -+ WIFI_ERR_FUNC("Turn off p2p/ap mode fail"); -+ else -+ WIFI_INFO_FUNC("Turn off p2p/ap mode"); -+ } -+ dev_put(netdev); -+ netdev = NULL; -+ } -+ } else { -+ /* WIFI is off before whole chip reset, do nothing */ -+ } -+ -+ return 0; -+} -+EXPORT_SYMBOL(wifi_reset_start); -+ -+/*-----------------------------------------------------------------*/ -+/* -+ * Receiving RESET_END/RESET_END_FAIL message -+ */ -+/*-----------------------------------------------------------------*/ -+INT32 wifi_reset_end(ENUM_RESET_STATUS_T status) -+{ -+ struct net_device *netdev = NULL; -+ PARAM_CUSTOM_P2P_SET_STRUCT_T p2pmode; -+ INT32 wait_cnt = 0; -+ INT32 ret = -1; -+ -+ if (status == RESET_FAIL) { -+ /* whole chip reset fail, donot recover WIFI */ -+ ret = 0; -+ up(&wr_mtx); -+ } else if (status == RESET_SUCCESS) { -+ WIFI_WARN_FUNC("WIFI state recovering...\n"); -+ -+ if (powered == 1) { -+ /* WIFI is on before whole chip reset, reopen it now */ -+ if (MTK_WCN_BOOL_FALSE == mtk_wcn_wmt_func_on(WMTDRV_TYPE_WIFI)) { -+ WIFI_ERR_FUNC("WMT turn on WIFI fail!\n"); -+ goto done; -+ } else { -+ WIFI_INFO_FUNC("WMT turn on WIFI success!\n"); -+ } -+ -+ if (pf_set_p2p_mode == NULL) { -+ WIFI_ERR_FUNC("Set p2p mode handler is NULL\n"); -+ goto done; -+ } -+ -+ netdev = dev_get_by_name(&init_net, ifname); -+ while (netdev == NULL && wait_cnt < 10) { -+ WIFI_ERR_FUNC("Fail to get %s net device, sleep 300ms\n", ifname); -+ msleep(300); -+ wait_cnt++; -+ netdev = dev_get_by_name(&init_net, ifname); -+ } -+ if (wait_cnt >= 10) { -+ WIFI_ERR_FUNC("Get %s net device timeout\n", ifname); -+ goto done; -+ } -+ -+ if (wlan_mode == WLAN_MODE_STA_P2P) { -+ p2pmode.u4Enable = 1; -+ p2pmode.u4Mode = 0; -+ if (pf_set_p2p_mode(netdev, p2pmode) != 0) { -+ WIFI_ERR_FUNC("Set wlan mode fail\n"); -+ } else { -+ WIFI_WARN_FUNC("Set wlan mode %d\n", WLAN_MODE_STA_P2P); -+ ret = 0; -+ } -+ } else if (wlan_mode == WLAN_MODE_AP) { -+ p2pmode.u4Enable = 1; -+ p2pmode.u4Mode = 1; -+ if (pf_set_p2p_mode(netdev, p2pmode) != 0) { -+ WIFI_ERR_FUNC("Set wlan mode fail\n"); -+ } else { -+ WIFI_WARN_FUNC("Set wlan mode %d\n", WLAN_MODE_AP); -+ ret = 0; -+ } -+ } -+done: -+ if (netdev != NULL) -+ dev_put(netdev); -+ } else { -+ /* WIFI is off before whole chip reset, do nothing */ -+ ret = 0; -+ } -+ up(&wr_mtx); -+ } -+ -+ return ret; -+} -+EXPORT_SYMBOL(wifi_reset_end); -+ -+static int WIFI_open(struct inode *inode, struct file *file) -+{ -+ WIFI_INFO_FUNC("%s: major %d minor %d (pid %d)\n", __func__, imajor(inode), iminor(inode), current->pid); -+ -+ return 0; -+} -+ -+static int WIFI_close(struct inode *inode, struct file *file) -+{ -+ WIFI_INFO_FUNC("%s: major %d minor %d (pid %d)\n", __func__, imajor(inode), iminor(inode), current->pid); -+ retflag = 0; -+ -+ return 0; -+} -+ -+ssize_t WIFI_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos) -+{ -+ INT32 retval = -EIO; -+ INT8 local[12] = { 0 }; -+ struct net_device *netdev = NULL; -+ PARAM_CUSTOM_P2P_SET_STRUCT_T p2pmode; -+ INT32 wait_cnt = 0; -+ -+ down(&wr_mtx); -+ if (count <= 0) { -+ WIFI_ERR_FUNC("WIFI_write invalid param\n"); -+ goto done; -+ } -+ -+ if (0 == copy_from_user(local, buf, (count > sizeof(local)) ? sizeof(local) : count)) { -+ local[11] = 0; -+ WIFI_INFO_FUNC("WIFI_write %s\n", local); -+ -+ if (local[0] == '0') { -+ if (powered == 0) { -+ WIFI_INFO_FUNC("WIFI is already power off!\n"); -+ retval = count; -+ wlan_mode = WLAN_MODE_HALT; -+ goto done; -+ } -+ -+ netdev = dev_get_by_name(&init_net, ifname); -+ if (netdev == NULL) { -+ WIFI_ERR_FUNC("Fail to get %s net device\n", ifname); -+ } else { -+ p2pmode.u4Enable = 0; -+ p2pmode.u4Mode = 0; -+ -+ if (pf_set_p2p_mode) { -+ if (pf_set_p2p_mode(netdev, p2pmode) != 0) { -+ WIFI_ERR_FUNC("Turn off p2p/ap mode fail"); -+ } else { -+ WIFI_INFO_FUNC("Turn off p2p/ap mode"); -+ wlan_mode = WLAN_MODE_HALT; -+ } -+ } -+ dev_put(netdev); -+ netdev = NULL; -+ } -+ -+ if (MTK_WCN_BOOL_FALSE == mtk_wcn_wmt_func_off(WMTDRV_TYPE_WIFI)) { -+ WIFI_ERR_FUNC("WMT turn off WIFI fail!\n"); -+ WMT_CHECK_DO_CHIP_RESET(); -+ } else { -+ WIFI_INFO_FUNC("WMT turn off WIFI OK!\n"); -+ powered = 0; -+ retval = count; -+ wlan_mode = WLAN_MODE_HALT; -+#if CFG_TC1_FEATURE -+ ifname = WLAN_IFACE_NAME; -+ wlan_if_changed = 0; -+#endif -+ } -+ } else if (local[0] == '1') { -+ if (powered == 1) { -+ WIFI_INFO_FUNC("WIFI is already power on!\n"); -+ retval = count; -+ goto done; -+ } -+ -+ if (MTK_WCN_BOOL_FALSE == mtk_wcn_wmt_func_on(WMTDRV_TYPE_WIFI)) { -+ WIFI_ERR_FUNC("WMT turn on WIFI fail!\n"); -+ WMT_CHECK_DO_CHIP_RESET(); -+ } else { -+ powered = 1; -+ retval = count; -+ WIFI_INFO_FUNC("WMT turn on WIFI success!\n"); -+ wlan_mode = WLAN_MODE_HALT; -+ } -+ } else if (local[0] == 'D') { -+ INT32 k = 0; -+ /* -+ * 0: no debug -+ * 1: common debug output -+ * 2: more detials -+ * 3: verbose -+ */ -+ switch (local[1]) { -+ case '0': -+ for (k = 0; k < DBG_MODULE_NUM; k++) -+ wlan_dbg_level[k] = 0; -+ if (pf_set_dbg_level) -+ pf_set_dbg_level(wlan_dbg_level); -+ break; -+ case '1': -+ for (k = 0; k < DBG_MODULE_NUM; k++) { -+ wlan_dbg_level[k] = DBG_CLASS_ERROR | -+ DBG_CLASS_WARN | -+ DBG_CLASS_STATE | DBG_CLASS_EVENT | DBG_CLASS_TRACE | DBG_CLASS_INFO; -+ } -+ wlan_dbg_level[DBG_TX_IDX] &= ~(DBG_CLASS_EVENT | DBG_CLASS_TRACE | DBG_CLASS_INFO); -+ wlan_dbg_level[DBG_RX_IDX] &= ~(DBG_CLASS_EVENT | DBG_CLASS_TRACE | DBG_CLASS_INFO); -+ wlan_dbg_level[DBG_REQ_IDX] &= ~(DBG_CLASS_EVENT | DBG_CLASS_TRACE | DBG_CLASS_INFO); -+ wlan_dbg_level[DBG_INTR_IDX] = 0; -+ wlan_dbg_level[DBG_MEM_IDX] = 0; -+ if (pf_set_dbg_level) -+ pf_set_dbg_level(wlan_dbg_level); -+ break; -+ case '2': -+ for (k = 0; k < DBG_MODULE_NUM; k++) { -+ wlan_dbg_level[k] = DBG_CLASS_ERROR | -+ DBG_CLASS_WARN | -+ DBG_CLASS_STATE | DBG_CLASS_EVENT | DBG_CLASS_TRACE | DBG_CLASS_INFO; -+ } -+ wlan_dbg_level[DBG_INTR_IDX] = 0; -+ wlan_dbg_level[DBG_MEM_IDX] = 0; -+ if (pf_set_dbg_level) -+ pf_set_dbg_level(wlan_dbg_level); -+ break; -+ case '3': -+ for (k = 0; k < DBG_MODULE_NUM; k++) { -+ wlan_dbg_level[k] = DBG_CLASS_ERROR | -+ DBG_CLASS_WARN | -+ DBG_CLASS_STATE | -+ DBG_CLASS_EVENT | DBG_CLASS_TRACE | DBG_CLASS_INFO | DBG_CLASS_LOUD; -+ } -+ if (pf_set_dbg_level) -+ pf_set_dbg_level(wlan_dbg_level); -+ break; -+ default: -+ break; -+ } -+ } else if (local[0] == 'S' || local[0] == 'P' || local[0] == 'A') { -+ if (powered == 0) { -+ /* If WIFI is off, turn on WIFI first */ -+ if (MTK_WCN_BOOL_FALSE == mtk_wcn_wmt_func_on(WMTDRV_TYPE_WIFI)) { -+ WIFI_ERR_FUNC("WMT turn on WIFI fail!\n"); -+ WMT_CHECK_DO_CHIP_RESET(); -+ goto done; -+ } else { -+ powered = 1; -+ WIFI_INFO_FUNC("WMT turn on WIFI success!\n"); -+ wlan_mode = WLAN_MODE_HALT; -+ } -+ } -+ -+ if (pf_set_p2p_mode == NULL) { -+ WIFI_ERR_FUNC("Set p2p mode handler is NULL\n"); -+ goto done; -+ } -+ -+ netdev = dev_get_by_name(&init_net, ifname); -+ while (netdev == NULL && wait_cnt < 10) { -+ WIFI_ERR_FUNC("Fail to get %s net device, sleep 300ms\n", ifname); -+ msleep(300); -+ wait_cnt++; -+ netdev = dev_get_by_name(&init_net, ifname); -+ } -+ if (wait_cnt >= 10) { -+ WIFI_ERR_FUNC("Get %s net device timeout\n", ifname); -+ goto done; -+ } -+ -+ if ((wlan_mode == WLAN_MODE_STA_P2P && (local[0] == 'S' || local[0] == 'P')) || -+ (wlan_mode == WLAN_MODE_AP && (local[0] == 'A'))) { -+ WIFI_INFO_FUNC("WIFI is already in mode %d!\n", wlan_mode); -+ retval = count; -+ goto done; -+ } -+ -+ if ((wlan_mode == WLAN_MODE_AP && (local[0] == 'S' || local[0] == 'P')) || -+ (wlan_mode == WLAN_MODE_STA_P2P && (local[0] == 'A'))) { -+ p2pmode.u4Enable = 0; -+ p2pmode.u4Mode = 0; -+ if (pf_set_p2p_mode(netdev, p2pmode) != 0) { -+ WIFI_ERR_FUNC("Turn off p2p/ap mode fail"); -+ goto done; -+ } -+ } -+ -+ if (local[0] == 'S' || local[0] == 'P') { -+#if CFG_TC1_FEATURE -+ /* Restore NIC name to wlan0 */ -+ rtnl_lock(); -+ if (strcmp(ifname, WLAN_IFACE_NAME) != 0) { -+ if (dev_change_name(netdev, WLAN_IFACE_NAME) != 0) { -+ WIFI_ERR_FUNC("netdev name change to %s fail\n", WLAN_IFACE_NAME); -+ rtnl_unlock(); -+ goto done; -+ } else { -+ WIFI_INFO_FUNC("netdev name changed %s --> %s\n", ifname, -+ WLAN_IFACE_NAME); -+ ifname = WLAN_IFACE_NAME; -+ wlan_if_changed = 0; -+ } -+ } -+ rtnl_unlock(); -+#endif -+ p2pmode.u4Enable = 1; -+ p2pmode.u4Mode = 0; -+ if (pf_set_p2p_mode(netdev, p2pmode) != 0) { -+ WIFI_ERR_FUNC("Set wlan mode fail\n"); -+ } else { -+ WIFI_INFO_FUNC("Set wlan mode %d --> %d\n", wlan_mode, WLAN_MODE_STA_P2P); -+ wlan_mode = WLAN_MODE_STA_P2P; -+ retval = count; -+ } -+ } else if (local[0] == 'A') { -+#if CFG_TC1_FEATURE -+ /* Change NIC name to legacy0, since wlan0 is used for AP */ -+ rtnl_lock(); -+ if (strcmp(ifname, LEGACY_IFACE_NAME) != 0) { -+ if (dev_change_name(netdev, LEGACY_IFACE_NAME) != 0) { -+ WIFI_ERR_FUNC("netdev name change to %s fail\n", LEGACY_IFACE_NAME); -+ rtnl_unlock(); -+ goto done; -+ } else { -+ WIFI_INFO_FUNC("netdev name changed %s --> %s\n", ifname, -+ LEGACY_IFACE_NAME); -+ ifname = LEGACY_IFACE_NAME; -+ wlan_if_changed = 1; -+ } -+ } -+ rtnl_unlock(); -+#endif -+ p2pmode.u4Enable = 1; -+ p2pmode.u4Mode = 1; -+ if (pf_set_p2p_mode(netdev, p2pmode) != 0) { -+ WIFI_ERR_FUNC("Set wlan mode fail\n"); -+ } else { -+ WIFI_INFO_FUNC("Set wlan mode %d --> %d\n", wlan_mode, WLAN_MODE_AP); -+ wlan_mode = WLAN_MODE_AP; -+ retval = count; -+ } -+ } -+ dev_put(netdev); -+ netdev = NULL; -+ } -+ } -+done: -+ if (netdev != NULL) -+ dev_put(netdev); -+ -+ up(&wr_mtx); -+ return retval; -+} -+ -+const struct file_operations WIFI_fops = { -+ .open = WIFI_open, -+ .release = WIFI_close, -+ .write = WIFI_write, -+}; -+ -+#if WMT_CREATE_NODE_DYNAMIC -+struct class *wmtwifi_class = NULL; -+#endif -+ -+static int WIFI_init(void) -+{ -+ dev_t dev = MKDEV(WIFI_major, 0); -+ INT32 alloc_ret = 0; -+ INT32 cdev_err = 0; -+#if WMT_CREATE_NODE_DYNAMIC -+ struct device *wmtwifi_dev = NULL; -+#endif -+ -+ /* static allocate chrdev */ -+ alloc_ret = register_chrdev_region(dev, 1, WIFI_DRIVER_NAME); -+ if (alloc_ret) { -+ WIFI_ERR_FUNC("Fail to register chrdev\n"); -+ return alloc_ret; -+ } -+ -+ cdev_init(&WIFI_cdev, &WIFI_fops); -+ WIFI_cdev.owner = THIS_MODULE; -+ -+ cdev_err = cdev_add(&WIFI_cdev, dev, WIFI_devs); -+ if (cdev_err) -+ goto error; -+ -+#if WMT_CREATE_NODE_DYNAMIC /* mknod replace */ -+ wmtwifi_class = class_create(THIS_MODULE, "wmtWifi"); -+ if (IS_ERR(wmtwifi_class)) -+ goto error; -+ wmtwifi_dev = device_create(wmtwifi_class, NULL, dev, NULL, "wmtWifi"); -+ if (wmtwifi_dev == NULL) -+ goto error; -+ if (IS_ERR(wmtwifi_dev)) -+ goto error; -+#endif -+ -+ sema_init(&wr_mtx, 1); -+ -+ WIFI_INFO_FUNC("%s driver(major %d) installed.\n", WIFI_DRIVER_NAME, WIFI_major); -+ retflag = 0; -+ wlan_mode = WLAN_MODE_HALT; -+ pf_set_p2p_mode = NULL; -+ -+ return 0; -+ -+error: -+#if WMT_CREATE_NODE_DYNAMIC -+ if (!IS_ERR(wmtwifi_dev)) -+ device_destroy(wmtwifi_class, dev); -+ if (!IS_ERR(wmtwifi_class)) { -+ class_destroy(wmtwifi_class); -+ wmtwifi_class = NULL; -+ } -+#endif -+ -+ if (cdev_err == 0) -+ cdev_del(&WIFI_cdev); -+ -+ if (alloc_ret == 0) -+ unregister_chrdev_region(dev, WIFI_devs); -+ -+ return -1; -+} -+ -+static void WIFI_exit(void) -+{ -+ dev_t dev = MKDEV(WIFI_major, 0); -+ -+ retflag = 0; -+ -+#if WMT_CREATE_NODE_DYNAMIC -+ device_destroy(wmtwifi_class, dev); -+ class_destroy(wmtwifi_class); -+ wmtwifi_class = NULL; -+#endif -+ -+ cdev_del(&WIFI_cdev); -+ unregister_chrdev_region(dev, WIFI_devs); -+ -+ WIFI_INFO_FUNC("%s driver removed.\n", WIFI_DRIVER_NAME); -+} -+ -+#ifdef MTK_WCN_REMOVE_KERNEL_MODULE -+ -+INT32 mtk_wcn_wmt_wifi_init(VOID) -+{ -+ return WIFI_init(); -+} -+EXPORT_SYMBOL(mtk_wcn_wmt_wifi_init); -+ -+VOID mtk_wcn_wmt_wifi_exit(VOID) -+{ -+ return WIFI_exit(); -+} -+EXPORT_SYMBOL(mtk_wcn_wmt_wifi_exit); -+ -+#else -+ -+module_init(WIFI_init); -+module_exit(WIFI_exit); -+ -+#endif -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/wmt_idc.c b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/wmt_idc.c -new file mode 100644 -index 000000000000..641e516f603d ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/wmt_idc.c -@@ -0,0 +1,307 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -+ -+#include "osal_typedef.h" -+#include "wmt_idc.h" -+#include "wmt_lib.h" -+ -+#if CFG_WMT_LTE_COEX_HANDLING -+ -+MTK_WCN_WMT_IDC_INFO gWmtIdcInfo; -+ -+INT32 wmt_idc_init(VOID) -+{ -+ INT32 iRet; -+ -+ osal_memset(&gWmtIdcInfo, 0, osal_sizeof(gWmtIdcInfo)); -+ gWmtIdcInfo.iit.src_mod_id = AP_MOD_WMT; -+ gWmtIdcInfo.iit.dest_mod_id = MD_MOD_EL1; -+ gWmtIdcInfo.iit.sap_id = 0; -+ gWmtIdcInfo.ops.rx_cb = wmt_idc_msg_from_lte_handing; -+ -+ iRet = mtk_conn_md_bridge_reg(gWmtIdcInfo.iit.src_mod_id, &gWmtIdcInfo.ops); -+ if (iRet) { -+ WMT_ERR_FUNC("mtk_conn_md_bridge_reg fail(%d)\n", iRet); -+ return -1; -+ } -+ /* mtk_wcn_stp_flush_rx_queue(COEX_TASK_INDX); */ -+ return 0; -+ -+} -+ -+INT32 wmt_idc_deinit(VOID) -+{ -+ INT32 iRet; -+ -+ iRet = mtk_conn_md_bridge_unreg(gWmtIdcInfo.iit.src_mod_id); -+ if (iRet) -+ WMT_ERR_FUNC("mtk_conn_md_bridge_unreg fail(%d)\n", iRet); -+ -+ osal_memset(&gWmtIdcInfo, 0, osal_sizeof(gWmtIdcInfo)); -+ -+ return 0; -+} -+ -+INT32 wmt_idc_msg_from_lte_handing(ipc_ilm_t *ilm) -+{ -+ MTK_WCN_BOOL bRet; -+ -+ if (NULL == ilm) { -+ WMT_ERR_FUNC("NULL pointer\n"); -+ return -1; -+ } -+ if (mtk_wcn_stp_is_ready()) { -+ bRet = wmt_lib_handle_idc_msg(ilm); -+ if (MTK_WCN_BOOL_FALSE == bRet) { -+ WMT_ERR_FUNC("wmt handing idc msg fail\n"); -+ return -2; -+ } -+ } else { -+ WMT_INFO_FUNC("Received LTE msg,but STP is not ready,drop it!\n"); -+ } -+ return 0; -+} -+ -+VOID wmt_idc_dump_debug_msg(UINT8 *str, UINT8 *p_buf, UINT32 buf_len) -+{ -+ UINT32 idx = 0; -+ -+ WMT_DBG_FUNC("%s:, length:%d\n", str, buf_len); -+ -+ WMT_DBG_FUNC("ASCII output:\n"); -+ -+ for (idx = 0; idx < buf_len;) { -+ WMT_DBG_FUNC("%c", p_buf[idx]); -+ idx++; -+ if (0 == idx % 16) -+ WMT_DBG_FUNC("\n"); -+ } -+ -+ WMT_DBG_FUNC("HEX output:\n"); -+ -+ for (idx = 0; idx < buf_len;) { -+ WMT_DBG_FUNC("%02x ", p_buf[idx]); -+ idx++; -+ if (0 == idx % 16) -+ WMT_DBG_FUNC("\n"); -+ } -+} -+ -+INT32 wmt_idc_msg_to_lte_handing(VOID) -+{ -+ UINT32 readlen = 0; -+ local_para_struct *p_lps = NULL; -+ UINT8 *p_data = NULL; -+ UINT8 opcode = 0; -+ UINT16 msg_len = 0; -+ UINT32 handle_len = 0; -+#if CFG_WMT_LTE_ENABLE_MSGID_MAPPING -+ MTK_WCN_BOOL unknown_msgid = MTK_WCN_BOOL_FALSE; -+#endif -+ readlen = mtk_wcn_stp_receive_data(&gWmtIdcInfo.buffer[0], LTE_IDC_BUFFER_MAX_SIZE, COEX_TASK_INDX); -+ if (readlen == 0) { -+ osal_sleep_ms(5); -+ readlen = mtk_wcn_stp_receive_data(&gWmtIdcInfo.buffer[0], LTE_IDC_BUFFER_MAX_SIZE, COEX_TASK_INDX); -+ } -+ -+ if (readlen > 0) { -+ WMT_DBG_FUNC("read data len from fw(%d)\n", readlen); -+ wmt_idc_dump_debug_msg("WMT->LTE from STP buffer", &gWmtIdcInfo.buffer[0], readlen); -+ p_data = &gWmtIdcInfo.buffer[0]; -+ -+ while (handle_len < readlen) { -+ p_data += 2; /*omit direction & opcode 2 bytes */ -+ osal_memcpy(&msg_len, p_data, 2); -+ msg_len -= 1; /*flag byte */ -+ WMT_DBG_FUNC("current raw data len(%d) from connsys firmware\n", msg_len); -+ -+ p_data += 2; /*length: 2 bytes */ -+ -+ /*how to handle flag(msg type) need to Scott comment */ -+ /************************************************/ -+ -+ if (*p_data == WMT_IDC_RX_OPCODE_DEBUG_MONITOR) -+ /*do not need transfer to LTE */ -+ { -+ p_data += 1; /*flag : 1 byte */ -+ /*need to handle these debug message */ -+ wmt_idc_dump_debug_msg("WIFI DEBUG MONITOR", p_data, msg_len); -+ } else -+ /*need to transfer to LTE */ -+ { -+ p_lps = -+ (local_para_struct *) osal_malloc(osal_sizeof(local_para_struct) + -+ osal_sizeof(UINT8) * msg_len); -+ if (NULL == p_lps) { -+ WMT_ERR_FUNC("allocate local_para_struct memory fail\n"); -+ return -1; -+ } -+ -+ p_lps->msg_len = msg_len + osal_sizeof(local_para_struct); -+ -+ opcode = *p_data; -+ WMT_DBG_FUNC("current opcode(%d) to LTE\n", opcode); -+ -+ p_data += 1; /*flag : 1 byte */ -+ osal_memcpy(p_lps->data, p_data, msg_len); -+ -+ gWmtIdcInfo.iit.local_para_ptr = p_lps; -+ -+#if CFG_WMT_LTE_ENABLE_MSGID_MAPPING -+ switch (opcode) { -+ case WMT_IDC_RX_OPCODE_BTWF_DEF_PARA: -+ gWmtIdcInfo.iit.msg_id = IPC_MSG_ID_EL1_WIFIBT_OPER_DEFAULT_PARAM_IND; -+ break; -+ case WMT_IDC_RX_OPCODE_BTWF_CHAN_RAN: -+ gWmtIdcInfo.iit.msg_id = IPC_MSG_ID_EL1_WIFIBT_OPER_FREQ_IND; -+ break; -+ case WMT_IDC_RX_OPCODE_LTE_FREQ_IDX_TABLE: -+ gWmtIdcInfo.iit.msg_id = IPC_MSG_ID_EL1_WIFIBT_FREQ_IDX_TABLE_IND; -+ break; -+ case WMT_IDC_RX_OPCODE_BTWF_PROFILE_IND: -+ gWmtIdcInfo.iit.msg_id = IPC_MSG_ID_EL1_WIFIBT_PROFILE_IND; -+ break; -+ case WMT_IDC_RX_OPCODE_UART_PIN_SEL: -+ gWmtIdcInfo.iit.msg_id = IPC_MSG_ID_EL1_PIN_TYPE_IND; -+ break; -+ /* case WMT_IDC_RX_OPCODE_TDM_REQ: */ -+ /* gWmtIdcInfo.iit.msg_id = IPC_MSG_ID_EL1_WIFIBT_OPER_FREQ_IND; */ -+ /* break; */ -+ default: -+ unknown_msgid = MTK_WCN_BOOL_TRUE; -+ WMT_ERR_FUNC("unknown opcode(%d) from connsys firmware\n", opcode); -+ break; -+ } -+ if (MTK_WCN_BOOL_FALSE == unknown_msgid) { -+ /*handling flag value in wmt cmd */ -+ mtk_conn_md_bridge_send_msg(&gWmtIdcInfo.iit); -+ } -+#else -+ if (opcode >= LTE_MSG_ID_OFFSET) { -+ gWmtIdcInfo.iit.msg_id = opcode + IPC_EL1_MSG_ID_BEGIN - LTE_MSG_ID_OFFSET + 1; -+ /*handling flag value in wmt cmd */ -+ mtk_conn_md_bridge_send_msg(&gWmtIdcInfo.iit); -+ WMT_DBG_FUNC("CONN->LTE: (0x%x->0x%x)\n", opcode, gWmtIdcInfo.iit.msg_id); -+ } else { -+ WMT_ERR_FUNC("opcode(%d)from connsys fw is out of range,drop it!\n", opcode); -+ } -+#endif -+ osal_free(p_lps); -+ } -+ -+ p_data += msg_len; /*point to next package header */ -+ -+ handle_len += (msg_len + 5); -+ } -+ -+ } else { -+ WMT_ERR_FUNC("there is no coex data in stp buffer\n"); -+ } -+ -+ osal_memset(&gWmtIdcInfo.buffer[0], 0, LTE_IDC_BUFFER_MAX_SIZE); -+ -+ return 0; -+} -+ -+UINT32 wmt_idc_msg_to_lte_handing_for_test(UINT8 *p_buf, UINT32 len) -+{ -+ UINT32 readlen = len; -+ local_para_struct *p_lps = NULL; -+ UINT8 *p_data = NULL; -+ UINT8 opcode = 0; -+ UINT16 msg_len = 0; -+ UINT32 handle_len = 0; -+ MTK_WCN_BOOL unknown_msgid = MTK_WCN_BOOL_FALSE; -+ -+ osal_memcpy(&gWmtIdcInfo.buffer[0], p_buf, len); -+ -+ if (readlen > 0) { -+ WMT_DBG_FUNC("read data len from fw(%d)\n", readlen); -+ p_data = &gWmtIdcInfo.buffer[0]; -+ -+ while (handle_len < readlen) { -+ p_data += 2; /*omit direction & opcode 2 bytes */ -+ osal_memcpy(&msg_len, p_data, 2); -+ msg_len -= 1; /*flag byte */ -+ WMT_DBG_FUNC("current raw data len(%d) from connsys firmware\n", msg_len); -+ -+ p_data += 2; /*length: 2 bytes */ -+ -+ /*how to handle flag(msg type) need to Scott comment */ -+ /************************************************/ -+ -+ if (*p_data == WMT_IDC_RX_OPCODE_DEBUG_MONITOR) -+ /*do not need transfer to LTE */ -+ { -+ p_data += 1; /*flag : 1 byte */ -+ /*need to handle these debug message */ -+ wmt_idc_dump_debug_msg("WIFI DEBUG MONITOR", p_data, msg_len); -+ } else -+ /*need to transfer to LTE */ -+ { -+ p_lps = -+ (local_para_struct *) osal_malloc(osal_sizeof(local_para_struct) + -+ osal_sizeof(UINT8) * msg_len); -+ if (NULL == p_lps) { -+ WMT_ERR_FUNC("allocate local_para_struct memory fail\n"); -+ return -1; -+ } -+ -+ p_lps->msg_len = msg_len + osal_sizeof(local_para_struct); -+ -+ opcode = *p_data; -+ WMT_DBG_FUNC("current opcode(%d) to LTE\n", opcode); -+ -+ p_data += 1; /*flag : 1 byte */ -+ osal_memcpy(p_lps->data, p_data, msg_len); -+ -+ gWmtIdcInfo.iit.local_para_ptr = p_lps; -+ -+ switch (opcode) { -+ case WMT_IDC_RX_OPCODE_BTWF_DEF_PARA: -+ gWmtIdcInfo.iit.msg_id = IPC_MSG_ID_EL1_WIFIBT_OPER_DEFAULT_PARAM_IND; -+ break; -+ case WMT_IDC_RX_OPCODE_BTWF_CHAN_RAN: -+ gWmtIdcInfo.iit.msg_id = IPC_MSG_ID_EL1_WIFIBT_OPER_FREQ_IND; -+ break; -+ /* case WMT_IDC_RX_OPCODE_TDM_REQ: */ -+ /* gWmtIdcInfo.iit.msg_id = IPC_MSG_ID_EL1_WIFIBT_OPER_FREQ_IND; */ -+ /* break; */ -+ default: -+ unknown_msgid = MTK_WCN_BOOL_TRUE; -+ WMT_ERR_FUNC("unknown opcode(%d) from connsys firmware\n", opcode); -+ break; -+ } -+ if (MTK_WCN_BOOL_FALSE == unknown_msgid) { -+ /*handling flag value in wmt cmd */ -+ mtk_conn_md_bridge_send_msg(&gWmtIdcInfo.iit); -+ } -+ osal_free(p_lps); -+ } -+ -+ p_data += msg_len; /*point to next package header */ -+ -+ handle_len += (msg_len + 5); -+ } -+ -+ } else { -+ WMT_ERR_FUNC("there is no coex data in stp buffer\n"); -+ } -+ -+ osal_memset(&gWmtIdcInfo.buffer[0], 0, LTE_IDC_BUFFER_MAX_SIZE); -+ -+ return handle_len; -+} -+ -+#endif -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/mt7623/Makefile b/drivers/misc/mediatek/connectivity/common/conn_soc/mt7623/Makefile -new file mode 100644 -index 000000000000..c201e8291b8e ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/mt7623/Makefile -@@ -0,0 +1,25 @@ -+# WMT HAL driver for MT7623 -+ -+ccflags-y += \ -+ -I$(src)/include \ -+ -I$(src)/../linux/include \ -+ -I$(src)/../include \ -+ -I$(src)/../../common_detect -+ -+ ifeq ($(CONFIG_MTK_CLKMGR),y) -+ ccflags-y += -I$(srctree)/drivers/misc/mediatek/include/mt-plat/$(MTK_PLATFORM)/include/mach -+ endif -+ #ifeq ($(CONFIG_MTK_EMI_MPU),y) -+ ccflags-y += -I$(srctree)/drivers/misc/mediatek/include/mt-plat/$(MTK_PLATFORM)/include/mach -+ #endif -+ -+subdir-ccflags-y += -D MTK_WCN_WMT_STP_EXP_SYMBOL_ABSTRACT -+ -+ifeq ($(CONFIG_MTK_CONN_LTE_IDC_SUPPORT),y) -+ subdir-ccflags-y += -DWMT_IDC_SUPPORT=1 -+else -+ subdir-ccflags-y += -DWMT_IDC_SUPPORT=0 -+endif -+ -+obj-y += mtk_wcn_consys_hw.o -+obj-y += wmt_plat_alps.o -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/mt7623/include/mtk_wcn_consys_hw.h b/drivers/misc/mediatek/connectivity/common/conn_soc/mt7623/include/mtk_wcn_consys_hw.h -new file mode 100644 -index 000000000000..94d6af9d0b3e ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/mt7623/include/mtk_wcn_consys_hw.h -@@ -0,0 +1,287 @@ -+/*! \file -+ \brief Declaration of library functions -+ -+ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. -+*/ -+ -+#ifndef _MTK_WCN_CONSYS_HW_H_ -+#define _MTK_WCN_CONSYS_HW_H_ -+ -+#include -+/*#include */ -+#include "wmt_plat.h" -+ -+/*device tree mode*/ -+#ifdef CONFIG_OF -+/* #if 1 */ -+#include -+#include -+#include -+#include -+#endif -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+#define CONSYS_BT_WIFI_SHARE_V33 0 -+#define CONSYS_PMIC_CTRL_ENABLE 1 -+#define CONSYS_PMIC_CTRL_UPMU 1 -+#define CONSYS_EMI_MPU_SETTING 0 -+#define CONSYS_AHB_CLK_MAGEMENT 1 -+#define CONSYS_USE_PLATFORM_WRITE 1 -+#define CONSYS_PWR_ON_OFF_API_AVAILABLE 1 -+#define CONSYS_CLOCK_BUF_CTRL 0 -+#if defined(CONFIG_MTK_LEGACY) -+#define CONFIG_MTK_PMIC_LEGACY 0 -+#endif -+#define CONFIG_RESET_CONTROL 1 -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/*tag start:new platform need to make sure these define */ -+#define PLATFORM_SOC_CHIP 0x7623 -+/*tag end*/ -+ -+#ifdef CONFIG_OF -+ -+struct CONSYS_BASE_ADDRESS { -+ SIZE_T mcu_base; -+ SIZE_T ap_rgu_base; -+ SIZE_T topckgen_base; -+ SIZE_T spm_base; -+}; -+ -+/*TOPCKGEN_BASE*/ -+#define CONSYS_TOP_CLKCG_CLR_OFFSET 0x00000084 -+#define CONSYS_TOP_CLKCG_SET_OFFSET 0x00000054 -+#define CONSYS_WD_SYS_RST_OFFSET 0x00000018 -+#define CONSYS_AP2CONN_OSC_EN_OFFSET 0x00000800 -+#define CONSYS_EMI_MAPPING_OFFSET 0x00000310 -+/*AP_RGU_BASE*/ -+#define CONSYS_CPU_SW_RST_OFFSET 0x00000018 -+/*SPM_BASE*/ -+#define CONSYS_PWRON_CONFG_EN_OFFSET 0x00000000 -+#define CONSYS_TOP1_PWR_CTRL_OFFSET 0x00000280 -+#define CONSYS_PWR_CONN_ACK_OFFSET 0x0000060c -+#define CONSYS_PWR_CONN_ACK_S_OFFSET 0x00000610 -+/*CONN_MCU_CONFIG_BASE*/ -+#define CONSYS_CHIP_ID_OFFSET 0x00000008 -+#define CONSYS_ROM_RAM_DELSEL_OFFSET 0x00000114 -+#define CONSYS_MCU_CFG_ACR_OFFSET 0x00000110 -+#define CONSYS_CPUPCR_OFFSET 0x00000160 -+/*AXI bus*/ -+ -+#define CONSYS_TOPAXI_PROT_EN_OFFSET 0x1220 -+#define CONSYS_TOPAXI_PROT_STA1_OFFSET 0x0228 -+#endif -+ -+#define CONSYS_SET_BIT(REG, BITVAL) (*((volatile UINT32*)(REG)) |= ((UINT32)(BITVAL))) -+#define CONSYS_CLR_BIT(REG, BITVAL) ((*(volatile UINT32*)(REG)) &= ~((UINT32)(BITVAL))) -+#define CONSYS_CLR_BIT_WITH_KEY(REG, BITVAL, KEY) {\ -+ UINT32 val = (*(volatile UINT32*)(REG)); \ -+ val &= ~((UINT32)(BITVAL)); \ -+ val |= ((UINT32)(KEY)); \ -+ (*(volatile UINT32*)(REG)) = val;\ -+} -+#define CONSYS_REG_READ(addr) (*((volatile UINT32*)(addr))) -+#if CONSYS_USE_PLATFORM_WRITE -+#define CONSYS_REG_WRITE(addr, data) mt_reg_sync_writel(data, addr) -+#else -+#define CONSYS_REG_WRITE(addr, data) (*((volatile UINT32*)(addr)) = (UINT32)(data)) -+#endif -+ -+/*tag start: connsys register base address (hard code, no use) */ -+#define AP_RGU_BASE 0xF0007000 -+#define TOPCKGEN_BASE 0xF0000000 -+#define SPM_BASE 0xF0006000 -+#define CONN_MCU_CONFIG_BASE 0xF8070000 -+/*GIC Interrupt ID*/ -+#define MT_CONN2AP_BTIF_WAKEUP_IRQ_ID 237 -+/*tag end*/ -+ -+/*connsys register offset define(hard code mode)*/ -+#if 1 -+ /*top clock gating control register */ -+#define CONSYS_TOP_CLKCG_CLR_REG (TOPCKGEN_BASE + 0x00000084) -+#define CONSYS_TOP_CLKCG_SET_REG (TOPCKGEN_BASE + 0x00000054) -+#define CONSYS_TOP_CLKCG_BIT (0x1 << 26) -+ -+ /*SPM clock gating control register */ -+#define CONSYS_PWRON_CONFG_EN_REG (SPM_BASE + 0x00000000) -+#define CONSYS_PWRON_CONFG_EN_VALUE (0x0b160001) -+#define CONSYS_PWRON_CONFG_DIS_VALUE (0x0b160000) -+#endif -+ -+#define CONSYS_CPU_SW_RST_REG (AP_RGU_BASE + 0x00000018) -+#define CONSYS_TOP1_PWR_CTRL_REG (SPM_BASE + 0x00000280) -+#define CONSYS_PWR_CONN_ACK_REG (SPM_BASE + 0x0000060c) -+#define CONSYS_PWR_CONN_ACK_S_REG (SPM_BASE + 0x00000610) -+ -+#define CONSYS_WD_SYS_RST_REG (TOPCKGEN_BASE + 0x00000018) -+#define CONSYS_CHIP_ID_REG (CONN_MCU_CONFIG_BASE + 0x00000008) -+#define CONSYS_ROM_RAM_DELSEL_REG (CONN_MCU_CONFIG_BASE + 0x00000114) -+#define CONSYS_MCU_CFG_ACR_REG (CONN_MCU_CONFIG_BASE + 0x00000110) -+#define CONSYS_AFE_REG (CONN_TOP_CR_BASE + 0x00002000) -+#define CONSYS_AFE_REG_DIG_RCK_01 (CONSYS_AFE_REG + 0x00000010) -+#define CONSYS_AFE_REG_WBG_PLL_02 (CONSYS_AFE_REG + 0x00000028) -+#define CONSYS_AFE_REG_WBG_WB_TX_01 (CONSYS_AFE_REG + 0x0000003c) -+#define CONSYS_AFE_REG_DIG_RCK_01_VALUE (0x174b0160) -+#define CONSYS_AFE_REG_WBG_PLL_02_VALUE (0x844083fe) -+#define CONSYS_AFE_REG_WBG_WB_TX_01_VALUE (0x7fc39a20) -+ -+#define CONSYS_TOPAXI_PROT_EN (TOPCKGEN_BASE + 0x0220) -+#define CONSYS_TOPAXI_PROT_STA1 (TOPCKGEN_BASE + 0x0228) -+#define CONSYS_PROT_MASK ((0x1<<13) | (0x1<<14) | (0x1<<15)) /* bit 13, 14, 15 */ -+/*CONSYS_CPU_SW_RST_REG*/ -+#define CONSYS_CPU_SW_RST_BIT (0x1 << 12) -+#define CONSYS_CPU_SW_RST_CTRL_KEY (0x88 << 24) -+ -+/*CONSYS_TOP1_PWR_CTRL_REG*/ -+#define CONSYS_SPM_PWR_RST_BIT (0x1 << 0) -+#define CONSYS_SPM_PWR_ISO_S_BIT (0x1 << 1) -+#define CONSYS_SPM_PWR_ON_BIT (0x1 << 2) -+#define CONSYS_SPM_PWR_ON_S_BIT (0x1 << 3) -+#define CONSYS_CLK_CTRL_BIT (0x1 << 4) -+#define CONSYS_SRAM_CONN_PD_BIT (0x1 << 8) -+ -+/*CONSYS_PWR_CONN_ACK_REG*/ -+#define CONSYS_PWR_ON_ACK_BIT (0x1 << 1) -+ -+/*CONSYS_PWR_CONN_ACK_S_REG*/ -+#define CONSYS_PWR_CONN_ACK_S_BIT (0x1 << 1) -+ -+/*CONSYS_WD_SYS_RST_REG*/ -+#define CONSYS_WD_SYS_RST_CTRL_KEY (0x88 << 24) -+#define CONSYS_WD_SYS_RST_BIT (0x1 << 9) -+ -+/*CONSYS_MCU_CFG_ACR_REG*/ -+#define CONSYS_MCU_CFG_ACR_MBIST_BIT (0x1 << 18) -+ -+/* EMI part mapping & ctrl*/ -+#define KBYTE (1024*sizeof(char)) -+#define CONSYS_EMI_AP_PHY_OFFSET (0x80000) -+#define CONSYS_EMI_AP_PHY_BASE (0x80080000) -+#define CONSYS_EMI_FW_PHY_BASE (0xf0080000) -+#define CONSYS_EMI_MEM_SIZE (343*KBYTE) /*coredump space , 343K is enough */ -+#define CONSYS_EMI_PAGED_TRACE_OFFSET (0x400) -+#define CONSYS_EMI_PAGED_DUMP_OFFSET (0x8400) -+#define CONSYS_EMI_FULL_DUMP_OFFSET (0x10400) -+ -+/*cpupcr*/ -+#define CONSYS_CPUPCR_REG (CONN_MCU_CONFIG_BASE + 0x00000160) -+/*emi mapping*/ -+#define CONSYS_EMI_MAPPING (TOPCKGEN_BASE + 0x1310) -+ -+/*control app2cnn_osc_en*/ -+#define CONSYS_AP2CONN_OSC_EN_REG (TOPCKGEN_BASE + 0x00001800) -+#define CONSYS_AP2CONN_OSC_EN_BIT (0x1 << 16) -+#define CONSYS_AP2CONN_WAKEUP_BIT (0x1 << 17) -+ -+/*paged dump address start*/ -+#define CONSYS_PAGED_DUMP_START_ADDR (0xf0088400) -+#define CONSYS_PAGED_DUMP_SIZE (32*KBYTE) -+ -+/*full dump address start*/ -+#define CONSYS_FULL_DUMP_START_ADDR (0xf0090400) -+#define CONSYS_FULL_DUMP_DLM_LEN (0x1f000) -+#define CONSYS_FULL_DUMP_SYSB2_START (CONSYS_FULL_DUMP_START_ADDR + CONSYS_FULL_DUMP_DLM_LEN) -+#define CONSYS_FULL_DUMP_SYSB2_LEN (0x6800) -+#define CONSYS_FULL_DUMP_SYSB3_START (CONSYS_FULL_DUMP_SYSB2_START + CONSYS_FULL_DUMP_SYSB2_LEN) -+#define CONSYS_FULL_DUMP_SYSB3_LEN (0x16800) -+ -+/*force fw assert pattern*/ -+#define EXP_APMEM_HOST_OUTBAND_ASSERT_MAGIC_W1 (0x19b30bb1) -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+typedef enum _ENUM_EMI_CTRL_STATE_OFFSET_ { -+ EXP_APMEM_CTRL_STATE = 0x0, -+ EXP_APMEM_CTRL_HOST_SYNC_STATE = 0x4, -+ EXP_APMEM_CTRL_HOST_SYNC_NUM = 0x8, -+ EXP_APMEM_CTRL_CHIP_SYNC_STATE = 0xc, -+ EXP_APMEM_CTRL_CHIP_SYNC_NUM = 0x10, -+ EXP_APMEM_CTRL_CHIP_SYNC_ADDR = 0x14, -+ EXP_APMEM_CTRL_CHIP_SYNC_LEN = 0x18, -+ EXP_APMEM_CTRL_CHIP_PRINT_BUFF_START = 0x1c, -+ EXP_APMEM_CTRL_CHIP_PRINT_BUFF_LEN = 0x20, -+ EXP_APMEM_CTRL_CHIP_PRINT_BUFF_IDX = 0x24, -+ EXP_APMEM_CTRL_CHIP_INT_STATUS = 0x28, -+ EXP_APMEM_CTRL_CHIP_PAGED_DUMP_END = 0x2c, -+ EXP_APMEM_CTRL_HOST_OUTBAND_ASSERT_W1 = 0x30, -+ EXP_APMEM_CTRL_CHIP_DYNAMIC_DUMP = 0x48, -+ EXP_APMEM_CTRL_MAX -+} ENUM_EMI_CTRL_STATE_OFFSET, *P_ENUM_EMI_CTRL_STATE_OFFSET; -+ -+#if CONSYS_BT_WIFI_SHARE_V33 -+typedef struct _BT_WIFI_V33_STATUS_ { -+ UINT32 counter; -+ UINT32 flags; -+ spinlock_t lock; -+} BT_WIFI_V33_STATUS; -+ -+#endif -+ -+typedef enum _CONSYS_GPS_CO_CLOCK_TYPE_ { -+ GPS_TCXO_TYPE = 0, -+ GPS_CO_TSX_TYPE = 1, -+ GPS_CO_DCXO_TYPE = 2, -+ GPS_CO_VCTCXO_TYPE = 3, -+ GPS_CO_CLOCK_TYPE_MAX -+} CONSYS_GPS_CO_CLOCK_TYPE, *P_CONSYS_GPS_CO_CLOCK_TYPE; -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+extern struct CONSYS_BASE_ADDRESS conn_reg; -+#if CONSYS_BT_WIFI_SHARE_V33 -+extern BT_WIFI_V33_STATUS gBtWifiV33; -+#endif -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+extern INT32 mtk_wcn_consys_hw_init(VOID); -+extern INT32 mtk_wcn_consys_hw_deinit(VOID); -+extern INT32 mtk_wcn_consys_hw_pwr_off(VOID); -+extern INT32 mtk_wcn_consys_hw_pwr_on(UINT32 co_clock_type); -+extern INT32 mtk_wcn_consys_hw_rst(UINT32 co_clock_type); -+extern INT32 mtk_wcn_consys_hw_bt_paldo_ctrl(UINT32 enable); -+extern INT32 mtk_wcn_consys_hw_wifi_paldo_ctrl(UINT32 enable); -+extern INT32 mtk_wcn_consys_hw_vcn28_ctrl(UINT32 enable); -+extern INT32 mtk_wcn_consys_hw_state_show(VOID); -+extern UINT8 *mtk_wcn_consys_emi_virt_addr_get(UINT32 ctrl_state_offset); -+#if CONSYS_ENALBE_SET_JTAG -+extern UINT32 mtk_wcn_consys_jtag_flag_ctrl(UINT32 en); -+#endif -+extern UINT32 mtk_wcn_consys_soc_chipid(VOID); -+#if !defined(CONFIG_MTK_GPIO_LEGACY) -+extern struct pinctrl *mtk_wcn_consys_get_pinctrl(VOID); -+#endif -+extern INT32 mtk_wcn_consys_set_dynamic_dump(PUINT32 buf); -+#endif /* _MTK_WCN_CMB_HW_H_ */ -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/mt7623/mtk_wcn_consys_hw.c b/drivers/misc/mediatek/connectivity/common/conn_soc/mt7623/mtk_wcn_consys_hw.c -new file mode 100644 -index 000000000000..53b69a7b3e87 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/mt7623/mtk_wcn_consys_hw.c -@@ -0,0 +1,738 @@ -+/*! \file -+ \brief Declaration of library functions -+ -+ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+#ifdef DFT_TAG -+#undef DFT_TAG -+#endif -+#define DFT_TAG "[WMT-CONSYS-HW]" -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include -+#include -+#include -+#include "osal_typedef.h" -+#include "mtk_wcn_consys_hw.h" -+#include -+#include -+#include -+#if CONSYS_EMI_MPU_SETTING -+#include -+#endif -+ -+#include -+#include -+#ifdef CONFIG_MTK_HIBERNATION -+#include -+#endif -+ -+#include -+ -+#if CONSYS_CLOCK_BUF_CTRL -+#include -+#endif -+ -+#include -+#include -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+static INT32 mtk_wmt_probe(struct platform_device *pdev); -+static INT32 mtk_wmt_remove(struct platform_device *pdev); -+ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+struct CONSYS_BASE_ADDRESS conn_reg; -+static phys_addr_t gConEmiPhyBase; -+static UINT8 __iomem *pEmibaseaddr; -+static struct clk *clk_infra_conn_main; /*ctrl infra_connmcu_bus clk */ -+static struct platform_device *my_pdev; -+static struct reset_control *rstc; -+static struct regulator *reg_VCN18; -+static struct regulator *reg_VCN28; -+static struct regulator *reg_VCN33_BT; -+static struct regulator *reg_VCN33_WIFI; -+static struct pinctrl *consys_pinctrl; -+static struct pinctrl *mt6625_spi_pinctrl; -+static struct pinctrl_state *mt6625_spi_default; -+static struct regmap *pmic_regmap; -+#define DYNAMIC_DUMP_GROUP_NUM 5 -+ -+static const struct of_device_id apwmt_of_ids[] = { -+ {.compatible = "mediatek,mt7623-consys",} -+}; -+MODULE_DEVICE_TABLE(of, apwmt_of_ids); -+ -+static struct platform_driver mtk_wmt_dev_drv = { -+ .probe = mtk_wmt_probe, -+ .remove = mtk_wmt_remove, -+ .driver = { -+ .name = "mt7623consys", -+ .owner = THIS_MODULE, -+ .of_match_table = of_match_ptr(apwmt_of_ids), -+ }, -+}; -+ -+static INT32 mtk_wmt_probe(struct platform_device *pdev) -+{ -+ int ret = 0; -+ struct device_node *node = NULL; -+ -+ pm_runtime_enable(&pdev->dev); -+ my_pdev = pdev; -+ mt6625_spi_pinctrl = devm_pinctrl_get(&pdev->dev); -+ if (IS_ERR(mt6625_spi_pinctrl)) { -+ ret = PTR_ERR(mt6625_spi_pinctrl); -+ WMT_PLAT_ERR_FUNC("Wmt cannot find pinctrl!\n"); -+ goto set_pin_exit; -+ } -+ mt6625_spi_default = pinctrl_lookup_state(mt6625_spi_pinctrl, "consys_pins_default"); -+ if (IS_ERR(mt6625_spi_default)) { -+ ret = PTR_ERR(mt6625_spi_default); -+ WMT_PLAT_ERR_FUNC("Wmt Cannot find pinctrl default!\n"); -+ goto set_pin_exit; -+ } -+ pinctrl_select_state(mt6625_spi_pinctrl, mt6625_spi_default); -+set_pin_exit: -+ -+ node = of_parse_phandle(pdev->dev.of_node, "mediatek,pwrap-regmap", 0); -+ if (node) { -+ pmic_regmap = pwrap_node_to_regmap(node); -+ if (IS_ERR(pmic_regmap)) -+ goto set_pmic_wrap_exit; -+ } else { -+ WMT_PLAT_ERR_FUNC("Pwrap node has not register regmap.\n"); -+ goto set_pmic_wrap_exit; -+ } -+set_pmic_wrap_exit: -+ -+ clk_infra_conn_main = devm_clk_get(&pdev->dev, "consysbus"); -+ if (IS_ERR(clk_infra_conn_main)) { -+ WMT_PLAT_ERR_FUNC("sean debug [CCF]cannot get clk_infra_conn_main clock.\n"); -+ return PTR_ERR(clk_infra_conn_main); -+ } -+ WMT_PLAT_DBG_FUNC("[CCF]clk_infra_conn_main=%p\n", clk_infra_conn_main); -+ -+ reg_VCN18 = devm_regulator_get(&pdev->dev, "vcn18"); -+ if (IS_ERR(reg_VCN18)) { -+ ret = PTR_ERR(reg_VCN18); -+ WMT_PLAT_ERR_FUNC("Regulator_get VCN_1V8 fail, ret=%d\n", ret); -+ } -+ reg_VCN28 = devm_regulator_get(&pdev->dev, "vcn28"); -+ if (IS_ERR(reg_VCN28)) { -+ ret = PTR_ERR(reg_VCN28); -+ WMT_PLAT_ERR_FUNC("Regulator_get VCN_2V8 fail, ret=%d\n", ret); -+ } -+ reg_VCN33_BT = devm_regulator_get(&pdev->dev, "vcn33_bt"); -+ if (IS_ERR(reg_VCN33_BT)) { -+ ret = PTR_ERR(reg_VCN33_BT); -+ WMT_PLAT_ERR_FUNC("Regulator_get VCN33_BT fail, ret=%d\n", ret); -+ } -+ reg_VCN33_WIFI = devm_regulator_get(&pdev->dev, "vcn33_wifi"); -+ if (IS_ERR(reg_VCN33_WIFI)) { -+ ret = PTR_ERR(reg_VCN33_WIFI); -+ WMT_PLAT_ERR_FUNC("Regulator_get VCN33_WIFI fail, ret=%d\n", ret); -+ } -+ -+ rstc = devm_reset_control_get(&pdev->dev, "connsys"); -+ if (IS_ERR(rstc)) { -+ ret = PTR_ERR(rstc); -+ WMT_PLAT_ERR_FUNC("CanNot get consys reset. ret=%d\n", ret); -+ return PTR_ERR(rstc); -+ } -+ -+ consys_pinctrl = devm_pinctrl_get(&pdev->dev); -+ if (IS_ERR(consys_pinctrl)) { -+ ret = PTR_ERR(consys_pinctrl); -+ WMT_PLAT_ERR_FUNC("CanNot find consys pinctrl. ret=%d\n", ret); -+ return PTR_ERR(consys_pinctrl); -+ } -+ return 0; -+} -+ -+static INT32 mtk_wmt_remove(struct platform_device *pdev) -+{ -+ pm_runtime_disable(&pdev->dev); -+ -+ return 0; -+} -+ -+VOID mtk_wcn_consys_power_on(VOID) -+{ -+ INT32 iRet = -1; -+printk(KERN_ALERT "DEBUG: Passed %s %d \n",__FUNCTION__,__LINE__); -+ iRet = pm_runtime_get_sync(&my_pdev->dev); -+printk(KERN_ALERT "DEBUG: Passed %s %d \n",__FUNCTION__,__LINE__); -+ if (iRet) -+ WMT_PLAT_ERR_FUNC("pm_runtime_get_sync() fail(%d)\n", iRet); -+ else -+ WMT_PLAT_INFO_FUNC("pm_runtime_get_sync() CONSYS ok\n"); -+ -+ iRet = device_init_wakeup(&my_pdev->dev, true); -+printk(KERN_ALERT "DEBUG: Passed %s %d \n",__FUNCTION__,__LINE__); -+ if (iRet) -+ WMT_PLAT_ERR_FUNC("device_init_wakeup(true) fail.\n"); -+ else -+ WMT_PLAT_INFO_FUNC("device_init_wakeup(true) CONSYS ok\n"); -+} -+ -+VOID mtk_wcn_consys_power_off(VOID) -+{ -+ INT32 iRet = -1; -+ -+ iRet = pm_runtime_put_sync(&my_pdev->dev); -+ if (iRet) -+ WMT_PLAT_ERR_FUNC("pm_runtime_put_sync() fail.\n"); -+ else -+ WMT_PLAT_INFO_FUNC("pm_runtime_put_sync() CONSYS ok\n"); -+ -+ iRet = device_init_wakeup(&my_pdev->dev, false); -+ if (iRet) -+ WMT_PLAT_ERR_FUNC("device_init_wakeup(false) fail.\n"); -+ else -+ WMT_PLAT_INFO_FUNC("device_init_wakeup(false) CONSYS ok\n"); -+} -+ -+INT32 mtk_wcn_consys_hw_reg_ctrl(UINT32 on, UINT32 co_clock_type) -+{ -+ UINT32 retry = 10; -+ UINT32 consysHwChipId = 0; -+ -+ WMT_PLAT_DBG_FUNC("CONSYS-HW-REG-CTRL(0x%08x),start\n", on); -+ if (on) { -+ WMT_PLAT_DBG_FUNC("++\n"); -+printk(KERN_ALERT "DEBUG: Passed %s %d \n",__FUNCTION__,__LINE__); -+ /*need PMIC driver provide new API protocol */ -+ /*1.AP power on VCN_1V8 LDO (with PMIC_WRAP API) VCN_1V8 */ -+ regulator_set_mode(reg_VCN18, REGULATOR_MODE_STANDBY); -+printk(KERN_ALERT "DEBUG: Passed %s %d \n",__FUNCTION__,__LINE__); -+ /* VOL_DEFAULT, VOL_1200, VOL_1300, VOL_1500, VOL_1800... */ -+ if (reg_VCN18) { -+printk(KERN_ALERT "DEBUG: Passed %s %d \n",__FUNCTION__,__LINE__); -+ regulator_set_voltage(reg_VCN18, 1800000, 1800000); -+printk(KERN_ALERT "DEBUG: Passed %s %d \n",__FUNCTION__,__LINE__); -+ if (regulator_enable(reg_VCN18)) -+ WMT_PLAT_ERR_FUNC("enable VCN18 fail\n"); -+ else -+ WMT_PLAT_DBG_FUNC("enable VCN18 ok\n"); -+ } -+ udelay(150); -+printk(KERN_ALERT "DEBUG: Passed %s %d \n",__FUNCTION__,__LINE__); -+ if (co_clock_type) { -+ /*step0,clk buf ctrl */ -+ WMT_PLAT_INFO_FUNC("co clock type(%d),turn on clk buf\n", co_clock_type); -+#if CONSYS_CLOCK_BUF_CTRL -+ clk_buf_ctrl(CLK_BUF_CONN, 1); -+#endif -+ /*if co-clock mode: */ -+ /*2.set VCN28 to SW control mode (with PMIC_WRAP API) */ -+ /*turn on VCN28 LDO only when FMSYS is activated" */ -+ regmap_update_bits(pmic_regmap, 0x41C, 0x1 << 14, 0x0 << 14);/*V28*/ -+ } else { -+ /*if NOT co-clock: */ -+ /*2.1.switch VCN28 to HW control mode (with PMIC_WRAP API) */ -+ regmap_update_bits(pmic_regmap, 0x41C, 0x1 << 14, 0x1 << 14);/*V28*/ -+ /*2.2.turn on VCN28 LDO (with PMIC_WRAP API)" */ -+ /*fix vcn28 not balance warning */ -+ if (reg_VCN28) { -+ regulator_set_voltage(reg_VCN28, 2800000, 2800000); -+ if (regulator_enable(reg_VCN28)) -+ WMT_PLAT_ERR_FUNC("enable VCN_2V8 fail!\n"); -+ else -+ WMT_PLAT_DBG_FUNC("enable VCN_2V8 ok\n"); -+ } -+ } -+ -+ /*3.assert CONNSYS CPU SW reset 0x10007018 "[12]=1'b1 [31:24]=8'h88 (key)" */ -+printk(KERN_ALERT "DEBUG: Passed %s %d \n",__FUNCTION__,__LINE__); -+ reset_control_reset(rstc); -+printk(KERN_ALERT "DEBUG: Passed %s %d \n",__FUNCTION__,__LINE__); -+ mtk_wcn_consys_power_on(); -+printk(KERN_ALERT "DEBUG: Passed %s %d \n",__FUNCTION__,__LINE__); -+ /*11.26M is ready now, delay 10us for mem_pd de-assert */ -+ udelay(10); -+ /*enable AP bus clock : connmcu_bus_pd API: enable_clock() ++?? */ -+ clk_prepare_enable(clk_infra_conn_main); -+printk(KERN_ALERT "DEBUG: Passed %s %d \n",__FUNCTION__,__LINE__); -+ WMT_PLAT_DBG_FUNC("[CCF]enable clk_infra_conn_main\n"); -+ /*12.poll CONNSYS CHIP ID until chipid is returned 0x18070008 */ -+ while (retry-- > 0) { -+ consysHwChipId = CONSYS_REG_READ(conn_reg.mcu_base + CONSYS_CHIP_ID_OFFSET) - 0xf6d; -+ -+ if ((consysHwChipId == 0x0321) || (consysHwChipId == 0x0335) || (consysHwChipId == 0x0337)) { -+ WMT_PLAT_INFO_FUNC("retry(%d)consys chipId(0x%08x)\n", retry, consysHwChipId); -+ break; -+ } -+ if ((consysHwChipId == 0x8163) || (consysHwChipId == 0x8127) || (consysHwChipId == 0x7623)) { -+ WMT_PLAT_INFO_FUNC("retry(%d)consys chipId(0x%08x)\n", retry, consysHwChipId); -+ break; -+ } -+ -+ WMT_PLAT_ERR_FUNC("Read CONSYS chipId(0x%08x)", consysHwChipId); -+ msleep(20); -+ } -+ -+ if ((0 == retry) || (0 == consysHwChipId)) -+ WMT_PLAT_ERR_FUNC("Maybe has a consys power on issue,(0x%08x)\n", consysHwChipId); -+ -+ msleep(40); -+ -+ } else { -+ -+ clk_disable_unprepare(clk_infra_conn_main); -+ WMT_PLAT_DBG_FUNC("[CCF] clk_disable_unprepare(clk_infra_conn_main) calling\n"); -+ mtk_wcn_consys_power_off(); -+ -+ if (co_clock_type) { -+ /*VCN28 has been turned off by GPS OR FM */ -+#if CONSYS_CLOCK_BUF_CTRL -+ clk_buf_ctrl(CLK_BUF_CONN, 0); -+#endif -+ } else { -+ regmap_update_bits(pmic_regmap, 0x41C, 0x1 << 14, 0x0 << 14);/*V28*/ -+ /*turn off VCN28 LDO (with PMIC_WRAP API)" */ -+ if (reg_VCN28) { -+ if (regulator_disable(reg_VCN28)) -+ WMT_PLAT_ERR_FUNC("disable VCN_2V8 fail!\n"); -+ else -+ WMT_PLAT_DBG_FUNC("disable VCN_2V8 ok\n"); -+ } -+ } -+ -+ /*AP power off MT6625L VCN_1V8 LDO */ -+ regulator_set_mode(reg_VCN18, REGULATOR_MODE_STANDBY); -+ if (reg_VCN18) { -+ if (regulator_disable(reg_VCN18)) -+ WMT_PLAT_ERR_FUNC("disable VCN_1V8 fail!\n"); -+ else -+ WMT_PLAT_DBG_FUNC("disable VCN_1V8 ok\n"); -+ } -+ -+ } -+ WMT_PLAT_DBG_FUNC("CONSYS-HW-REG-CTRL(0x%08x),finish\n", on); -+ return 0; -+} -+ -+INT32 mtk_wcn_consys_hw_gpio_ctrl(UINT32 on) -+{ -+ INT32 iRet = 0; -+ -+ WMT_PLAT_DBG_FUNC("CONSYS-HW-GPIO-CTRL(0x%08x), start\n", on); -+ -+ if (on) { -+ -+ /* TODO: [FixMe][GeorgeKuo] double check if BGF_INT is implemented ok */ -+ /* iRet += wmt_plat_gpio_ctrl(PIN_BGF_EINT, PIN_STA_MUX); */ -+ iRet += wmt_plat_eirq_ctrl(PIN_BGF_EINT, PIN_STA_INIT); -+ iRet += wmt_plat_eirq_ctrl(PIN_BGF_EINT, PIN_STA_EINT_DIS); -+ WMT_PLAT_DBG_FUNC("CONSYS-HW, BGF IRQ registered and disabled\n"); -+ -+ } else { -+ -+ /* set bgf eint/all eint to deinit state, namely input low state */ -+ iRet += wmt_plat_eirq_ctrl(PIN_BGF_EINT, PIN_STA_EINT_DIS); -+ iRet += wmt_plat_eirq_ctrl(PIN_BGF_EINT, PIN_STA_DEINIT); -+ WMT_PLAT_DBG_FUNC("CONSYS-HW, BGF IRQ unregistered and disabled\n"); -+ /* iRet += wmt_plat_gpio_ctrl(PIN_BGF_EINT, PIN_STA_DEINIT); */ -+ } -+ WMT_PLAT_DBG_FUNC("CONSYS-HW-GPIO-CTRL(0x%08x), finish\n", on); -+ return iRet; -+ -+} -+ -+INT32 mtk_wcn_consys_hw_pwr_on(UINT32 co_clock_type) -+{ -+ INT32 iRet = 0; -+ -+ WMT_PLAT_INFO_FUNC("CONSYS-HW-PWR-ON, start\n"); -+ -+ iRet += mtk_wcn_consys_hw_reg_ctrl(1, co_clock_type); -+ iRet += mtk_wcn_consys_hw_gpio_ctrl(1); -+ -+ WMT_PLAT_INFO_FUNC("CONSYS-HW-PWR-ON, finish(%d)\n", iRet); -+ return iRet; -+} -+ -+INT32 mtk_wcn_consys_hw_pwr_off(VOID) -+{ -+ INT32 iRet = 0; -+ -+ WMT_PLAT_INFO_FUNC("CONSYS-HW-PWR-OFF, start\n"); -+ -+ iRet += mtk_wcn_consys_hw_reg_ctrl(0, 0); -+ iRet += mtk_wcn_consys_hw_gpio_ctrl(0); -+ -+ WMT_PLAT_INFO_FUNC("CONSYS-HW-PWR-OFF, finish(%d)\n", iRet); -+ return iRet; -+} -+ -+INT32 mtk_wcn_consys_hw_rst(UINT32 co_clock_type) -+{ -+ INT32 iRet = 0; -+ -+ WMT_PLAT_INFO_FUNC("CONSYS-HW, hw_rst start, eirq should be disabled before this step\n"); -+ -+ /*1. do whole hw power off flow */ -+ iRet += mtk_wcn_consys_hw_reg_ctrl(0, co_clock_type); -+ -+ /*2. do whole hw power on flow */ -+ iRet += mtk_wcn_consys_hw_reg_ctrl(1, co_clock_type); -+ -+ WMT_PLAT_INFO_FUNC("CONSYS-HW, hw_rst finish, eirq should be enabled after this step\n"); -+ return iRet; -+} -+ -+#if CONSYS_BT_WIFI_SHARE_V33 -+INT32 mtk_wcn_consys_hw_bt_paldo_ctrl(UINT32 enable) -+{ -+ /* spin_lock_irqsave(&gBtWifiV33.lock,gBtWifiV33.flags); */ -+ if (enable) { -+ if (1 == gBtWifiV33.counter) { -+ gBtWifiV33.counter++; -+ WMT_PLAT_DBG_FUNC("V33 has been enabled,counter(%d)\n", gBtWifiV33.counter); -+ } else if (2 == gBtWifiV33.counter) { -+ WMT_PLAT_DBG_FUNC("V33 has been enabled,counter(%d)\n", gBtWifiV33.counter); -+ } else { -+#if CONSYS_PMIC_CTRL_ENABLE -+ /*do BT PMIC on,depenency PMIC API ready */ -+ /*switch BT PALDO control from SW mode to HW mode:0x416[5]-->0x1 */ -+ /* VOL_DEFAULT, VOL_3300, VOL_3400, VOL_3500, VOL_3600 */ -+ hwPowerOn(MT6323_POWER_LDO_VCN33, VOL_3300, "wcn_drv"); -+ upmu_set_vcn33_on_ctrl_bt(1); -+#endif -+ WMT_PLAT_INFO_FUNC("WMT do BT/WIFI v3.3 on\n"); -+ gBtWifiV33.counter++; -+ } -+ -+ } else { -+ if (1 == gBtWifiV33.counter) { -+ /*do BT PMIC off */ -+ /*switch BT PALDO control from HW mode to SW mode:0x416[5]-->0x0 */ -+#if CONSYS_PMIC_CTRL_ENABLE -+ upmu_set_vcn33_on_ctrl_bt(0); -+ hwPowerDown(MT6323_POWER_LDO_VCN33, "wcn_drv"); -+#endif -+ WMT_PLAT_INFO_FUNC("WMT do BT/WIFI v3.3 off\n"); -+ gBtWifiV33.counter--; -+ } else if (2 == gBtWifiV33.counter) { -+ gBtWifiV33.counter--; -+ WMT_PLAT_DBG_FUNC("V33 no need disabled,counter(%d)\n", gBtWifiV33.counter); -+ } else { -+ WMT_PLAT_DBG_FUNC("V33 has been disabled,counter(%d)\n", gBtWifiV33.counter); -+ } -+ -+ } -+ /* spin_unlock_irqrestore(&gBtWifiV33.lock,gBtWifiV33.flags); */ -+ return 0; -+} -+ -+INT32 mtk_wcn_consys_hw_wifi_paldo_ctrl(UINT32 enable) -+{ -+ mtk_wcn_consys_hw_bt_paldo_ctrl(enable); -+ return 0; -+} -+ -+#else -+INT32 mtk_wcn_consys_hw_bt_paldo_ctrl(UINT32 enable) -+{ -+ -+ if (enable) { -+ /*do BT PMIC on,depenency PMIC API ready */ -+ /*switch BT PALDO control from SW mode to HW mode:0x416[5]-->0x1 */ -+ if (reg_VCN33_BT) { -+ regulator_set_voltage(reg_VCN33_BT, 3300000, 3300000); -+ if (regulator_enable(reg_VCN33_BT)) -+ WMT_PLAT_ERR_FUNC("WMT do BT PMIC on fail!\n"); -+ } -+ regmap_update_bits(pmic_regmap, 0x416, 0x1 << 5, 0x1 << 5);/*BT*/ -+ WMT_PLAT_INFO_FUNC("WMT do BT PMIC on\n"); -+ } else { -+ /*do BT PMIC off */ -+ /*switch BT PALDO control from HW mode to SW mode:0x416[5]-->0x0 */ -+ regmap_update_bits(pmic_regmap, 0x416, 0x1 << 5, 0x0 << 5);/*BT*/ -+ if (reg_VCN33_BT) -+ if (regulator_disable(reg_VCN33_BT)) -+ WMT_PLAT_ERR_FUNC("WMT do BT PMIC off fail!\n"); -+ WMT_PLAT_INFO_FUNC("WMT do BT PMIC off\n"); -+ } -+ -+ return 0; -+ -+} -+ -+INT32 mtk_wcn_consys_hw_wifi_paldo_ctrl(UINT32 enable) -+{ -+ -+ if (enable) { -+ /*do WIFI PMIC on,depenency PMIC API ready */ -+ /*switch WIFI PALDO control from SW mode to HW mode:0x418[14]-->0x1 */ -+ if (reg_VCN33_WIFI) { -+ regulator_set_voltage(reg_VCN33_WIFI, 3300000, 3300000); -+ if (regulator_enable(reg_VCN33_WIFI)) -+ WMT_PLAT_ERR_FUNC("WMT do WIFI PMIC on fail!\n"); -+ else -+ WMT_PLAT_INFO_FUNC("WMT do WIFI PMIC on !\n"); -+ } -+ regmap_update_bits(pmic_regmap, 0x418, 0x1 << 14, 0x1 << 14);/*WIFI*/ -+ WMT_PLAT_INFO_FUNC("WMT do WIFI PMIC on\n"); -+ } else { -+ /*do WIFI PMIC off */ -+ /*switch WIFI PALDO control from HW mode to SW mode:0x418[14]-->0x0 */ -+ regmap_update_bits(pmic_regmap, 0x418, 0x1 << 14, 0x0 << 14);/*WIFI*/ -+ if (reg_VCN33_WIFI) -+ if (regulator_disable(reg_VCN33_WIFI)) -+ WMT_PLAT_ERR_FUNC("WMT do WIFI PMIC off fail!\n"); -+ WMT_PLAT_INFO_FUNC("WMT do WIFI PMIC off\n"); -+ } -+ -+ return 0; -+} -+ -+#endif -+INT32 mtk_wcn_consys_hw_vcn28_ctrl(UINT32 enable) -+{ -+ if (enable) { -+ /*in co-clock mode,need to turn on vcn28 when fm on */ -+ if (reg_VCN28) { -+ regulator_set_voltage(reg_VCN28, 2800000, 2800000); -+ if (regulator_enable(reg_VCN28)) -+ WMT_PLAT_ERR_FUNC("WMT do VCN28 PMIC on fail!\n"); -+ } -+ WMT_PLAT_INFO_FUNC("turn on vcn28 for fm/gps usage in co-clock mode\n"); -+ } else { -+ /*in co-clock mode,need to turn off vcn28 when fm off */ -+ if (reg_VCN28) -+ if (regulator_disable(reg_VCN28)) -+ WMT_PLAT_ERR_FUNC("WMT do VCN28 PMIC off fail!\n"); -+ WMT_PLAT_INFO_FUNC("turn off vcn28 for fm/gps usage in co-clock mode\n"); -+ } -+ return 0; -+} -+ -+INT32 mtk_wcn_consys_hw_state_show(VOID) -+{ -+ return 0; -+} -+ -+INT32 mtk_wcn_consys_hw_restore(struct device *device) -+{ -+ UINT32 addrPhy = 0; -+ -+ if (gConEmiPhyBase) { -+ -+#if CONSYS_EMI_MPU_SETTING -+ /*set MPU for EMI share Memory */ -+ WMT_PLAT_INFO_FUNC("setting MPU for EMI share memory\n"); -+ -+#if 0 -+ emi_mpu_set_region_protection(gConEmiPhyBase + SZ_1M/2, -+ gConEmiPhyBase + SZ_1M, -+ 5, -+ SET_ACCESS_PERMISSON(FORBIDDEN, NO_PROTECTION, FORBIDDEN, NO_PROTECTION)); -+ -+ -+#else -+ WMT_PLAT_WARN_FUNC("not define platform config\n"); -+#endif -+ -+#endif -+ /*consys to ap emi remapping register:10001310, cal remapping address */ -+ addrPhy = (gConEmiPhyBase & 0xFFF00000) >> 20; -+ -+ /*enable consys to ap emi remapping bit12 */ -+ addrPhy = addrPhy | 0x1000; -+ -+ CONSYS_REG_WRITE(conn_reg.topckgen_base + CONSYS_EMI_MAPPING_OFFSET, -+ CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_EMI_MAPPING_OFFSET) | addrPhy); -+ -+ WMT_PLAT_INFO_FUNC("CONSYS_EMI_MAPPING dump in restore cb(0x%08x)\n", -+ CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_EMI_MAPPING_OFFSET)); -+ -+#if 1 -+ pEmibaseaddr = ioremap_nocache(gConEmiPhyBase + CONSYS_EMI_AP_PHY_OFFSET, CONSYS_EMI_MEM_SIZE); -+#else -+ pEmibaseaddr = ioremap_nocache(CONSYS_EMI_AP_PHY_BASE, CONSYS_EMI_MEM_SIZE); -+#endif -+ if (pEmibaseaddr) { -+ WMT_PLAT_INFO_FUNC("EMI mapping OK(0x%p)\n", pEmibaseaddr); -+ memset_io(pEmibaseaddr, 0, CONSYS_EMI_MEM_SIZE); -+ } else { -+ WMT_PLAT_ERR_FUNC("EMI mapping fail\n"); -+ } -+ } else { -+ WMT_PLAT_ERR_FUNC("consys emi memory address gConEmiPhyBase invalid\n"); -+ } -+ -+ return 0; -+} -+ -+/*Reserved memory by device tree!*/ -+int reserve_memory_consys_fn(struct reserved_mem *rmem) -+{ -+ WMT_PLAT_WARN_FUNC(" name: %s, base: 0x%llx, size: 0x%llx\n", rmem->name, -+ (unsigned long long)rmem->base, (unsigned long long)rmem->size); -+ gConEmiPhyBase = rmem->base; -+ return 0; -+} -+ -+RESERVEDMEM_OF_DECLARE(reserve_memory_test, "mediatek,consys-reserve-memory", reserve_memory_consys_fn); -+ -+ -+INT32 mtk_wcn_consys_hw_init(void) -+{ -+ -+ INT32 iRet = -1; -+ UINT32 addrPhy = 0; -+ INT32 i = 0; -+ struct device_node *node = NULL; -+ -+ node = of_find_compatible_node(NULL, NULL, "mediatek,mt7623-consys"); -+ if (node) { -+ /* registers base address */ -+ conn_reg.mcu_base = (SIZE_T) of_iomap(node, i); -+ WMT_PLAT_DBG_FUNC("Get mcu register base(0x%zx)\n", conn_reg.mcu_base); -+ i++; -+ -+ conn_reg.topckgen_base = (SIZE_T) of_iomap(node, i); -+ WMT_PLAT_DBG_FUNC("Get topckgen register base(0x%zx)\n", conn_reg.topckgen_base); -+ i++; -+ } else { -+ WMT_PLAT_ERR_FUNC("[%s] can't find CONSYS compatible node\n", __func__); -+ return iRet; -+ } -+ if (gConEmiPhyBase) { -+#if CONSYS_EMI_MPU_SETTING -+ /*set MPU for EMI share Memory */ -+ WMT_PLAT_INFO_FUNC("setting MPU for EMI share memory\n"); -+ -+#if 0 -+ emi_mpu_set_region_protection(gConEmiPhyBase + SZ_1M/2, -+ gConEmiPhyBase + SZ_1M, -+ 5, -+ SET_ACCESS_PERMISSON(FORBIDDEN, NO_PROTECTION, FORBIDDEN, NO_PROTECTION)); -+#else -+ WMT_PLAT_WARN_FUNC("not define platform config\n"); -+#endif -+ -+#endif -+ WMT_PLAT_DBG_FUNC("get consys start phy address(0x%zx)\n", (SIZE_T) gConEmiPhyBase); -+ -+ /*consys to ap emi remapping register:10001310, cal remapping address */ -+ addrPhy = (gConEmiPhyBase & 0xFFF00000) >> 20; -+ -+ /*enable consys to ap emi remapping bit12 */ -+ addrPhy = addrPhy | 0x1000; -+ -+ CONSYS_REG_WRITE(conn_reg.topckgen_base + CONSYS_EMI_MAPPING_OFFSET, -+ CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_EMI_MAPPING_OFFSET) | addrPhy); -+ -+ WMT_PLAT_INFO_FUNC("CONSYS_EMI_MAPPING dump(0x%08x)\n", -+ CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_EMI_MAPPING_OFFSET)); -+ -+#if 1 -+ pEmibaseaddr = ioremap_nocache(gConEmiPhyBase + CONSYS_EMI_AP_PHY_OFFSET, CONSYS_EMI_MEM_SIZE); -+#else -+ pEmibaseaddr = ioremap_nocache(CONSYS_EMI_AP_PHY_BASE, CONSYS_EMI_MEM_SIZE); -+#endif -+ /* pEmibaseaddr = ioremap_nocache(0x80090400,270*KBYTE); */ -+ if (pEmibaseaddr) { -+ WMT_PLAT_INFO_FUNC("EMI mapping OK(0x%p)\n", pEmibaseaddr); -+ memset_io(pEmibaseaddr, 0, CONSYS_EMI_MEM_SIZE); -+ iRet = 0; -+ } else { -+ WMT_PLAT_ERR_FUNC("EMI mapping fail\n"); -+ } -+ } else { -+ WMT_PLAT_ERR_FUNC("consys emi memory address gConEmiPhyBase invalid\n"); -+ } -+#ifdef CONFIG_MTK_HIBERNATION -+ WMT_PLAT_INFO_FUNC("register connsys restore cb for complying with IPOH function\n"); -+ register_swsusp_restore_noirq_func(ID_M_CONNSYS, mtk_wcn_consys_hw_restore, NULL); -+#endif -+ iRet = platform_driver_register(&mtk_wmt_dev_drv); -+ if (iRet) -+ WMT_PLAT_ERR_FUNC("WMT platform driver registered failed(%d)\n", iRet); -+ return iRet; -+} -+ -+INT32 mtk_wcn_consys_hw_deinit(void) -+{ -+ if (pEmibaseaddr) { -+ iounmap(pEmibaseaddr); -+ pEmibaseaddr = NULL; -+ } -+#ifdef CONFIG_MTK_HIBERNATION -+ unregister_swsusp_restore_noirq_func(ID_M_CONNSYS); -+#endif -+ -+ platform_driver_unregister(&mtk_wmt_dev_drv); -+ return 0; -+} -+ -+UINT8 *mtk_wcn_consys_emi_virt_addr_get(UINT32 ctrl_state_offset) -+{ -+ UINT8 *p_virtual_addr = NULL; -+ -+ if (!pEmibaseaddr) { -+ WMT_PLAT_ERR_FUNC("EMI base address is NULL\n"); -+ return NULL; -+ } -+ WMT_PLAT_DBG_FUNC("ctrl_state_offset(%08x)\n", ctrl_state_offset); -+ p_virtual_addr = pEmibaseaddr + ctrl_state_offset; -+ -+ return p_virtual_addr; -+} -+ -+UINT32 mtk_wcn_consys_soc_chipid(void) -+{ -+ return PLATFORM_SOC_CHIP; -+} -+ -+struct pinctrl *mtk_wcn_consys_get_pinctrl() -+{ -+ return consys_pinctrl; -+} -+INT32 mtk_wcn_consys_set_dynamic_dump(PUINT32 str_buf) -+{ -+ PUINT8 vir_addr = NULL; -+ -+ vir_addr = mtk_wcn_consys_emi_virt_addr_get(EXP_APMEM_CTRL_CHIP_DYNAMIC_DUMP); -+ if (!vir_addr) { -+ WMT_PLAT_ERR_FUNC("get vir address fail\n"); -+ return -2; -+ } -+ memcpy(vir_addr, str_buf, DYNAMIC_DUMP_GROUP_NUM*8); -+ WMT_PLAT_INFO_FUNC("dynamic dump register value(0x%08x)\n", CONSYS_REG_READ(vir_addr)); -+ return 0; -+} -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/mt7623/wmt_plat_alps.c b/drivers/misc/mediatek/connectivity/common/conn_soc/mt7623/wmt_plat_alps.c -new file mode 100644 -index 000000000000..7163dc18a255 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/mt7623/wmt_plat_alps.c -@@ -0,0 +1,1071 @@ -+/*! \file -+ \brief Declaration of library functions -+ -+ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+#ifdef DFT_TAG -+#undef DFT_TAG -+#endif -+#define DFT_TAG "[WMT-PLAT]" -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include -+#include -+/* ALPS header files */ -+/*#include */ -+/*#include */ -+#if defined(CONFIG_MTK_GPIO_LEGACY) -+#include -+#endif -+#include -+ -+/* MTK_WCN_COMBO header files */ -+#include "osal_typedef.h" -+#include "mtk_wcn_consys_hw.h" -+#include "stp_dbg.h" -+ -+#define CFG_WMT_WAKELOCK_SUPPORT 1 -+ -+#ifdef CONFIG_MTK_MT6306_SUPPORT -+#define MTK_WCN_MT6306_IS_READY 1 -+#else -+#define MTK_WCN_MT6306_IS_READY 0 -+#endif -+ -+#if MTK_WCN_MT6306_IS_READY -+#include -+ -+#ifdef GPIO_GPS_LNA_PIN -+#undef GPIO_GPS_LNA_PIN -+#endif -+ -+#define GPIO_GPS_LNA_PIN GPIO7 -+#endif -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+EMI_CTRL_STATE_OFFSET mtk_wcn_emi_state_off = { -+ .emi_apmem_ctrl_state = EXP_APMEM_CTRL_STATE, -+ .emi_apmem_ctrl_host_sync_state = EXP_APMEM_CTRL_HOST_SYNC_STATE, -+ .emi_apmem_ctrl_host_sync_num = EXP_APMEM_CTRL_HOST_SYNC_NUM, -+ .emi_apmem_ctrl_chip_sync_state = EXP_APMEM_CTRL_CHIP_SYNC_STATE, -+ .emi_apmem_ctrl_chip_sync_num = EXP_APMEM_CTRL_CHIP_SYNC_NUM, -+ .emi_apmem_ctrl_chip_sync_addr = EXP_APMEM_CTRL_CHIP_SYNC_ADDR, -+ .emi_apmem_ctrl_chip_sync_len = EXP_APMEM_CTRL_CHIP_SYNC_LEN, -+ .emi_apmem_ctrl_chip_print_buff_start = EXP_APMEM_CTRL_CHIP_PRINT_BUFF_START, -+ .emi_apmem_ctrl_chip_print_buff_len = EXP_APMEM_CTRL_CHIP_PRINT_BUFF_LEN, -+ .emi_apmem_ctrl_chip_print_buff_idx = EXP_APMEM_CTRL_CHIP_PRINT_BUFF_IDX, -+ .emi_apmem_ctrl_chip_int_status = EXP_APMEM_CTRL_CHIP_INT_STATUS, -+ .emi_apmem_ctrl_chip_paded_dump_end = EXP_APMEM_CTRL_CHIP_PAGED_DUMP_END, -+ .emi_apmem_ctrl_host_outband_assert_w1 = EXP_APMEM_CTRL_HOST_OUTBAND_ASSERT_W1, -+}; -+ -+CONSYS_EMI_ADDR_INFO mtk_wcn_emi_addr_info = { -+ .emi_phy_addr = CONSYS_EMI_FW_PHY_BASE, -+ .paged_trace_off = CONSYS_EMI_PAGED_TRACE_OFFSET, -+ .paged_dump_off = CONSYS_EMI_PAGED_DUMP_OFFSET, -+ .full_dump_off = CONSYS_EMI_FULL_DUMP_OFFSET, -+ .p_ecso = &mtk_wcn_emi_state_off, -+}; -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+static VOID wmt_plat_bgf_eirq_cb(VOID); -+ -+static INT32 wmt_plat_bgf_eint_ctrl(ENUM_PIN_STATE state); -+static INT32 wmt_plat_i2s_ctrl(ENUM_PIN_STATE state); -+static INT32 wmt_plat_gps_sync_ctrl(ENUM_PIN_STATE state); -+static INT32 wmt_plat_gps_lna_ctrl(ENUM_PIN_STATE state); -+ -+static INT32 wmt_plat_dump_pin_conf(VOID); -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+UINT32 gCoClockFlag = 0; -+BGF_IRQ_BALANCE gbgfIrqBle; -+UINT32 wmtPlatLogLvl = WMT_PLAT_LOG_DBG; -+#if CONSYS_BT_WIFI_SHARE_V33 -+BT_WIFI_V33_STATUS gBtWifiV33; -+#endif -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+#if CFG_WMT_WAKELOCK_SUPPORT -+static struct mutex gOsSLock; -+#ifdef CONFIG_PM_WAKELOCKS -+static struct wakeup_source wmtWakeLock; -+#else -+static struct wake_lock wmtWakeLock; -+#endif -+#endif -+ -+irq_cb wmt_plat_bgf_irq_cb = NULL; -+device_audio_if_cb wmt_plat_audio_if_cb = NULL; -+func_ctrl_cb wmt_plat_func_ctrl_cb = NULL; -+thermal_query_ctrl_cb wmt_plat_thermal_query_ctrl_cb = NULL; -+deep_idle_ctrl_cb wmt_plat_deep_idle_ctrl_cb = NULL; -+ -+static const fp_set_pin gfp_set_pin_table[] = { -+ [PIN_BGF_EINT] = wmt_plat_bgf_eint_ctrl, -+ [PIN_I2S_GRP] = wmt_plat_i2s_ctrl, -+ [PIN_GPS_SYNC] = wmt_plat_gps_sync_ctrl, -+ [PIN_GPS_LNA] = wmt_plat_gps_lna_ctrl, -+}; -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+/*! -+ * \brief audio control callback function for CMB_STUB on ALPS -+ * -+ * A platform function required for dynamic binding with CMB_STUB on ALPS. -+ * -+ * \param state desired audio interface state to use -+ * \param flag audio interface control options -+ * -+ * \retval 0 operation success -+ * \retval -1 invalid parameters -+ * \retval < 0 error for operation fail -+ */ -+INT32 wmt_plat_audio_ctrl(CMB_STUB_AIF_X state, CMB_STUB_AIF_CTRL ctrl) -+{ -+ INT32 iRet = 0; -+ UINT32 pinShare = 0; -+ -+ /* input sanity check */ -+ if ((CMB_STUB_AIF_MAX <= state) -+ || (CMB_STUB_AIF_CTRL_MAX <= ctrl)) { -+ return -1; -+ } -+ -+ iRet = 0; -+ -+ /* set host side first */ -+ switch (state) { -+ case CMB_STUB_AIF_0: -+ /* BT_PCM_OFF & FM line in/out */ -+ iRet += wmt_plat_gpio_ctrl(PIN_I2S_GRP, PIN_STA_DEINIT); -+ break; -+ -+ case CMB_STUB_AIF_1: -+ iRet += wmt_plat_gpio_ctrl(PIN_I2S_GRP, PIN_STA_DEINIT); -+ break; -+ -+ case CMB_STUB_AIF_2: -+ iRet += wmt_plat_gpio_ctrl(PIN_I2S_GRP, PIN_STA_INIT); -+ break; -+ -+ case CMB_STUB_AIF_3: -+ iRet += wmt_plat_gpio_ctrl(PIN_I2S_GRP, PIN_STA_INIT); -+ break; -+ -+ default: -+ /* FIXME: move to cust folder? */ -+ WMT_PLAT_ERR_FUNC("invalid state [%d]\n", state); -+ iRet = -1; -+ break; -+ } -+ -+ if (CMB_STUB_AIF_CTRL_EN == ctrl) { -+ WMT_PLAT_INFO_FUNC("call chip aif setting\n"); -+ /* need to control chip side GPIO */ -+ if (NULL != wmt_plat_audio_if_cb) { -+ iRet += (*wmt_plat_audio_if_cb) (state, (pinShare) ? MTK_WCN_BOOL_TRUE : MTK_WCN_BOOL_FALSE); -+ } else { -+ WMT_PLAT_WARN_FUNC("wmt_plat_audio_if_cb is not registered\n"); -+ iRet -= 1; -+ } -+ -+ } else { -+ WMT_PLAT_INFO_FUNC("skip chip aif setting\n"); -+ } -+ -+ return iRet; -+ -+} -+ -+static VOID wmt_plat_func_ctrl(UINT32 type, UINT32 on) -+{ -+ if (wmt_plat_func_ctrl_cb) -+ (*wmt_plat_func_ctrl_cb) (on, type); -+} -+ -+static long wmt_plat_thermal_ctrl(VOID) -+{ -+ long temp = 0; -+ -+ if (wmt_plat_thermal_query_ctrl_cb) -+ temp = (*wmt_plat_thermal_query_ctrl_cb) (); -+ -+ return temp; -+} -+ -+static INT32 wmt_plat_deep_idle_ctrl(UINT32 dpilde_ctrl) -+{ -+ INT32 iRet = -1; -+ -+ if (wmt_plat_deep_idle_ctrl_cb) -+ iRet = (*wmt_plat_deep_idle_ctrl_cb) (dpilde_ctrl); -+ -+ return iRet; -+} -+ -+static VOID wmt_plat_bgf_eirq_cb(VOID) -+{ -+#if CFG_WMT_PS_SUPPORT -+/* #error "need to disable EINT here" */ -+ /* wmt_lib_ps_irq_cb(); */ -+ if (NULL != wmt_plat_bgf_irq_cb) -+ (*(wmt_plat_bgf_irq_cb)) (); -+ else -+ WMT_PLAT_WARN_FUNC("WMT-PLAT: wmt_plat_bgf_irq_cb not registered\n"); -+#else -+ return; -+#endif -+ -+} -+ -+irqreturn_t wmt_plat_bgf_irq_isr(INT32 i, VOID *arg) -+{ -+#if CFG_WMT_PS_SUPPORT -+ wmt_plat_eirq_ctrl(PIN_BGF_EINT, PIN_STA_EINT_DIS); -+ wmt_plat_bgf_eirq_cb(); -+#else -+ WMT_PLAT_INFO_FUNC("skip irq handing because psm is disable"); -+#endif -+ return IRQ_HANDLED; -+} -+ -+VOID wmt_plat_irq_cb_reg(irq_cb bgf_irq_cb) -+{ -+ wmt_plat_bgf_irq_cb = bgf_irq_cb; -+} -+EXPORT_SYMBOL(wmt_plat_irq_cb_reg); -+ -+VOID wmt_plat_aif_cb_reg(device_audio_if_cb aif_ctrl_cb) -+{ -+ wmt_plat_audio_if_cb = aif_ctrl_cb; -+} -+EXPORT_SYMBOL(wmt_plat_aif_cb_reg); -+ -+VOID wmt_plat_func_ctrl_cb_reg(func_ctrl_cb subsys_func_ctrl) -+{ -+ wmt_plat_func_ctrl_cb = subsys_func_ctrl; -+} -+EXPORT_SYMBOL(wmt_plat_func_ctrl_cb_reg); -+ -+VOID wmt_plat_thermal_ctrl_cb_reg(thermal_query_ctrl_cb thermal_query_ctrl) -+{ -+ wmt_plat_thermal_query_ctrl_cb = thermal_query_ctrl; -+} -+EXPORT_SYMBOL(wmt_plat_thermal_ctrl_cb_reg); -+ -+VOID wmt_plat_deep_idle_ctrl_cb_reg(deep_idle_ctrl_cb deep_idle_ctrl) -+{ -+ wmt_plat_deep_idle_ctrl_cb = deep_idle_ctrl; -+} -+EXPORT_SYMBOL(wmt_plat_deep_idle_ctrl_cb_reg); -+ -+UINT32 wmt_plat_soc_co_clock_flag_get(VOID) -+{ -+ return gCoClockFlag; -+} -+ -+static UINT32 wmt_plat_soc_co_clock_flag_set(UINT32 flag) -+{ -+ gCoClockFlag = flag; -+ return 0; -+} -+ -+INT32 wmt_plat_init(UINT32 co_clock_type) -+{ -+ CMB_STUB_CB stub_cb; -+ INT32 iret; -+ /*init wmt function ctrl wakelock if wake lock is supported by host platform */ -+ -+ wmt_plat_soc_co_clock_flag_set(co_clock_type); -+ -+ stub_cb.aif_ctrl_cb = wmt_plat_audio_ctrl; -+ stub_cb.func_ctrl_cb = wmt_plat_func_ctrl; -+ stub_cb.thermal_query_cb = wmt_plat_thermal_ctrl; -+ stub_cb.deep_idle_ctrl_cb = wmt_plat_deep_idle_ctrl; -+ stub_cb.size = sizeof(stub_cb); -+ -+ /* register to cmb_stub */ -+ iret = mtk_wcn_cmb_stub_reg(&stub_cb); -+#ifdef CFG_WMT_WAKELOCK_SUPPORT -+#ifdef CONFIG_PM_WAKELOCKS -+ wakeup_source_init(&wmtWakeLock, "wmtFuncCtrl"); -+#else -+ wake_lock_init(&wmtWakeLock, WAKE_LOCK_SUSPEND, "wmtFuncCtrl"); -+#endif -+ mutex_init(&gOsSLock); -+#endif -+ -+#if CONSYS_BT_WIFI_SHARE_V33 -+ gBtWifiV33.counter = 0; -+ spin_lock_init(&gBtWifiV33.lock); -+#endif -+ -+ iret += mtk_wcn_consys_hw_init(); -+ -+ spin_lock_init(&gbgfIrqBle.lock); -+ WMT_PLAT_DBG_FUNC("WMT-PLAT: ALPS platform init (%d)\n", iret); -+ -+ return 0; -+} -+EXPORT_SYMBOL(wmt_plat_init); -+ -+INT32 wmt_plat_deinit(VOID) -+{ -+ INT32 iret = 0; -+ /* 2. unreg to cmb_stub */ -+ iret = mtk_wcn_cmb_stub_unreg(); -+printk(KERN_ALERT "DEBUG: Passed %s %d now calling wmt wakelock deinit\n",__FUNCTION__,__LINE__); -+ /*3. wmt wakelock deinit */ -+#ifdef CFG_WMT_WAKELOCK_SUPPORT -+#ifdef CONFIG_PM_WAKELOCKS -+printk(KERN_ALERT "DEBUG: Passed %s %d now calling wakeup_source_trash\n",__FUNCTION__,__LINE__); -+ wakeup_source_trash(&wmtWakeLock); -+#else -+printk(KERN_ALERT "DEBUG: Passed %s %d now calling wake lock destroy %d\n",__FUNCTION__,__LINE__,(int)&wmtWakeLock); -+//destroy calls wakeup_source_trash with &lock->ws -+printk(KERN_ALERT "DEBUG: Passed %s %d now wmtWakeLock:%d\n",__FUNCTION__,__LINE__,(int)&wmtWakeLock); -+printk(KERN_ALERT "DEBUG: Passed %s %d now wmtWakeLock->ws: %d\n",__FUNCTION__,__LINE__,(int)&(wmtWakeLock.ws)); -+ wake_lock_destroy(&wmtWakeLock); -+#endif -+printk(KERN_ALERT "DEBUG: Passed %s %d now calling mutex_destroy\n",__FUNCTION__,__LINE__); -+ mutex_destroy(&gOsSLock); -+ WMT_PLAT_DBG_FUNC("destroy wmtWakeLock\n"); -+#endif -+printk(KERN_ALERT "DEBUG: Passed %s %d now calling consys hw deinit\n",__FUNCTION__,__LINE__); -+ -+ iret += mtk_wcn_consys_hw_deinit(); -+ -+ WMT_PLAT_DBG_FUNC("WMT-PLAT: ALPS platform init (%d)\n", iret); -+ -+ return 0; -+} -+EXPORT_SYMBOL(wmt_plat_deinit); -+ -+static INT32 wmt_plat_dump_pin_conf(VOID) -+{ -+ WMT_PLAT_DBG_FUNC("[WMT-PLAT]=>dump wmt pin configuration start<=\n"); -+#if defined(CONFIG_MTK_GPIO_LEGACY) -+ -+#ifdef GPIO_COMBO_BGF_EINT_PIN -+ WMT_PLAT_DBG_FUNC("BGF_EINT(GPIO%d)\n", GPIO_COMBO_BGF_EINT_PIN); -+#else -+ WMT_PLAT_DBG_FUNC("BGF_EINT(not defined)\n"); -+#endif -+ -+#ifdef CUST_EINT_COMBO_BGF_NUM -+ WMT_PLAT_DBG_FUNC("BGF_EINT_NUM(%d)\n", CUST_EINT_COMBO_BGF_NUM); -+#else -+ WMT_PLAT_DBG_FUNC("BGF_EINT_NUM(not defined)\n"); -+#endif -+ -+#ifdef GPIO_COMBO_URXD_PIN -+ WMT_PLAT_DBG_FUNC("UART_RX(GPIO%d)\n", GPIO_COMBO_URXD_PIN); -+#else -+ WMT_PLAT_DBG_FUNC("UART_RX(not defined)\n"); -+#endif -+#if defined(FM_DIGITAL_INPUT) || defined(FM_DIGITAL_OUTPUT) -+#ifdef GPIO_COMBO_I2S_CK_PIN -+ WMT_PLAT_DBG_FUNC("I2S_CK(GPIO%d)\n", GPIO_COMBO_I2S_CK_PIN); -+#else -+ WMT_PLAT_DBG_FUNC("I2S_CK(not defined)\n"); -+#endif -+#ifdef GPIO_COMBO_I2S_WS_PIN -+ WMT_PLAT_DBG_FUNC("I2S_WS(GPIO%d)\n", GPIO_COMBO_I2S_WS_PIN); -+#else -+ WMT_PLAT_DBG_FUNC("I2S_WS(not defined)\n"); -+#endif -+#ifdef GPIO_COMBO_I2S_DAT_PIN -+ WMT_PLAT_DBG_FUNC("I2S_DAT(GPIO%d)\n", GPIO_COMBO_I2S_DAT_PIN); -+#else -+ WMT_PLAT_DBG_FUNC("I2S_DAT(not defined)\n"); -+#endif -+#else /* FM_ANALOG_INPUT || FM_ANALOG_OUTPUT */ -+ WMT_PLAT_DBG_FUNC("FM digital mode is not set, no need for I2S GPIOs\n"); -+#endif -+#ifdef GPIO_GPS_SYNC_PIN -+ WMT_PLAT_DBG_FUNC("GPS_SYNC(GPIO%d)\n", GPIO_GPS_SYNC_PIN); -+#else -+ WMT_PLAT_DBG_FUNC("GPS_SYNC(not defined)\n"); -+#endif -+ -+#ifdef GPIO_GPS_LNA_PIN -+ WMT_PLAT_INFO_FUNC("GPS_LNA(GPIO%d)\n", GPIO_GPS_LNA_PIN); -+#else -+ WMT_PLAT_INFO_FUNC("GPS_LNA(not defined)\n"); -+#endif -+ -+#else /* #if defined(CONFIG_MTK_GPIO_LEGACY) */ -+#endif -+ WMT_PLAT_DBG_FUNC("[WMT-PLAT]=>dump wmt pin configuration emds<=\n"); -+ return 0; -+} -+ -+INT32 wmt_plat_pwr_ctrl(ENUM_FUNC_STATE state) -+{ -+ INT32 ret = -1; -+ -+ switch (state) { -+ case FUNC_ON: -+ /* TODO:[ChangeFeature][George] always output this or by request throuth /proc or sysfs? */ -+ wmt_plat_dump_pin_conf(); -+ ret = mtk_wcn_consys_hw_pwr_on(gCoClockFlag); -+ break; -+ -+ case FUNC_OFF: -+ ret = mtk_wcn_consys_hw_pwr_off(); -+ break; -+ -+ case FUNC_RST: -+ ret = mtk_wcn_consys_hw_rst(gCoClockFlag); -+ break; -+ case FUNC_STAT: -+ ret = mtk_wcn_consys_hw_state_show(); -+ break; -+ default: -+ WMT_PLAT_WARN_FUNC("WMT-PLAT:Warnning, invalid state(%d) in pwr_ctrl\n", state); -+ break; -+ } -+ -+ return ret; -+} -+EXPORT_SYMBOL(wmt_plat_pwr_ctrl); -+ -+INT32 wmt_plat_eirq_ctrl(ENUM_PIN_ID id, ENUM_PIN_STATE state) -+{ -+#ifdef CONFIG_OF -+ struct device_node *node; -+ unsigned int irq_info[3] = { 0, 0, 0 }; -+#endif -+ INT32 iret = -EINVAL; -+ static INT32 bgf_irq_num = -1; -+ static UINT32 bgf_irq_flag; -+ /* TODO: [ChangeFeature][GeorgeKuo]: use another function to handle this, as done in gpio_ctrls */ -+ -+ if ((PIN_STA_INIT != state) -+ && (PIN_STA_DEINIT != state) -+ && (PIN_STA_EINT_EN != state) -+ && (PIN_STA_EINT_DIS != state)) { -+ WMT_PLAT_WARN_FUNC("WMT-PLAT:invalid PIN_STATE(%d) in eirq_ctrl for PIN(%d)\n", state, id); -+ return -1; -+ } -+ -+ switch (id) { -+ case PIN_BGF_EINT: -+ -+ if (PIN_STA_INIT == state) { -+#ifdef CONFIG_OF -+ node = of_find_compatible_node(NULL, NULL, "mediatek,mt7623-consys"); -+ if (node) { -+ bgf_irq_num = irq_of_parse_and_map(node, 0); -+ /* get the interrupt line behaviour */ -+ if (of_property_read_u32_array(node, "interrupts", irq_info, ARRAY_SIZE(irq_info))) { -+ WMT_PLAT_ERR_FUNC("get irq flags from DTS fail!!\n"); -+ return iret; -+ } -+ bgf_irq_flag = irq_info[2]; -+ WMT_PLAT_INFO_FUNC("get irq id(%d) and irq trigger flag(%d) from DT\n", bgf_irq_num, -+ bgf_irq_flag); -+ } else { -+ WMT_PLAT_ERR_FUNC("[%s] can't find CONSYS compatible node\n", __func__); -+ return iret; -+ } -+#else -+ bgf_irq_num = MT_CONN2AP_BTIF_WAKEUP_IRQ_ID; -+ bgf_irq_flag = IRQF_TRIGGER_LOW; -+#endif -+ iret = request_irq(bgf_irq_num, wmt_plat_bgf_irq_isr, bgf_irq_flag, "BTIF_WAKEUP_IRQ", NULL); -+ if (iret) { -+ WMT_PLAT_ERR_FUNC("request_irq fail,irq_no(%d),iret(%d)\n", bgf_irq_num, iret); -+ return iret; -+ } -+ gbgfIrqBle.counter = 1; -+ -+ } else if (PIN_STA_EINT_EN == state) { -+ -+ spin_lock_irqsave(&gbgfIrqBle.lock, gbgfIrqBle.flags); -+ if (gbgfIrqBle.counter) { -+ WMT_PLAT_DBG_FUNC("BGF INT has been enabled,counter(%d)\n", gbgfIrqBle.counter); -+ } else { -+ enable_irq(bgf_irq_num); -+ gbgfIrqBle.counter++; -+ } -+ WMT_PLAT_DBG_FUNC("WMT-PLAT:BGFInt (en)\n"); -+ spin_unlock_irqrestore(&gbgfIrqBle.lock, gbgfIrqBle.flags); -+ } else if (PIN_STA_EINT_DIS == state) { -+ spin_lock_irqsave(&gbgfIrqBle.lock, gbgfIrqBle.flags); -+ if (!gbgfIrqBle.counter) { -+ WMT_PLAT_INFO_FUNC("BGF INT has been disabled,counter(%d)\n", gbgfIrqBle.counter); -+ } else { -+ disable_irq_nosync(bgf_irq_num); -+ gbgfIrqBle.counter--; -+ } -+ WMT_PLAT_DBG_FUNC("WMT-PLAT:BGFInt (dis)\n"); -+ spin_unlock_irqrestore(&gbgfIrqBle.lock, gbgfIrqBle.flags); -+ } else { -+ free_irq(bgf_irq_num, NULL); -+ /* de-init: nothing to do in ALPS, such as un-registration... */ -+ } -+ iret = 0; -+ break; -+ -+ default: -+ WMT_PLAT_WARN_FUNC("WMT-PLAT:unsupported EIRQ(PIN_ID:%d) in eirq_ctrl\n", id); -+ iret = -1; -+ break; -+ } -+ -+ return iret; -+} -+EXPORT_SYMBOL(wmt_plat_eirq_ctrl); -+ -+INT32 wmt_plat_gpio_ctrl(ENUM_PIN_ID id, ENUM_PIN_STATE state) -+{ -+ if ((PIN_ID_MAX > id) -+ && (PIN_STA_MAX > state)) { -+ -+ /* TODO: [FixMe][GeorgeKuo] do sanity check to const function table when init and skip checking here */ -+ if (gfp_set_pin_table[id]) -+ return (*(gfp_set_pin_table[id])) (state); /* .handler */ -+ WMT_PLAT_WARN_FUNC("WMT-PLAT: null fp for gpio_ctrl(%d)\n", id); -+ return -2; -+ } -+ return -1; -+} -+EXPORT_SYMBOL(wmt_plat_gpio_ctrl); -+ -+INT32 wmt_plat_bgf_eint_ctrl(ENUM_PIN_STATE state) -+{ -+#if defined(CONFIG_MTK_GPIO_LEGACY) -+#ifdef GPIO_COMBO_BGF_EINT_PIN -+ switch (state) { -+ case PIN_STA_INIT: -+ /*set to gpio input low, pull down enable */ -+ mt_set_gpio_mode(GPIO_COMBO_BGF_EINT_PIN, GPIO_COMBO_BGF_EINT_PIN_M_GPIO); -+ mt_set_gpio_dir(GPIO_COMBO_BGF_EINT_PIN, GPIO_DIR_IN); -+ mt_set_gpio_pull_select(GPIO_COMBO_BGF_EINT_PIN, GPIO_PULL_DOWN); -+ mt_set_gpio_pull_enable(GPIO_COMBO_BGF_EINT_PIN, GPIO_PULL_ENABLE); -+ WMT_PLAT_DBG_FUNC("WMT-PLAT:BGFInt init(in pd)\n"); -+ break; -+ -+ case PIN_STA_MUX: -+ mt_set_gpio_mode(GPIO_COMBO_BGF_EINT_PIN, GPIO_COMBO_BGF_EINT_PIN_M_GPIO); -+ mt_set_gpio_pull_enable(GPIO_COMBO_BGF_EINT_PIN, GPIO_PULL_ENABLE); -+ mt_set_gpio_pull_select(GPIO_COMBO_BGF_EINT_PIN, GPIO_PULL_UP); -+ mt_set_gpio_mode(GPIO_COMBO_BGF_EINT_PIN, GPIO_COMBO_BGF_EINT_PIN_M_EINT); -+ WMT_PLAT_DBG_FUNC("WMT-PLAT:BGFInt mux (eint)\n"); -+ break; -+ -+ case PIN_STA_IN_L: -+ case PIN_STA_DEINIT: -+ /*set to gpio input low, pull down enable */ -+ mt_set_gpio_mode(GPIO_COMBO_BGF_EINT_PIN, GPIO_COMBO_BGF_EINT_PIN_M_GPIO); -+ mt_set_gpio_dir(GPIO_COMBO_BGF_EINT_PIN, GPIO_DIR_IN); -+ mt_set_gpio_pull_select(GPIO_COMBO_BGF_EINT_PIN, GPIO_PULL_DOWN); -+ mt_set_gpio_pull_enable(GPIO_COMBO_BGF_EINT_PIN, GPIO_PULL_ENABLE); -+ WMT_PLAT_DBG_FUNC("WMT-PLAT:BGFInt deinit(in pd)\n"); -+ break; -+ -+ default: -+ WMT_PLAT_WARN_FUNC("WMT-PLAT:Warnning, invalid state(%d) on BGF EINT\n", state); -+ break; -+ } -+#else -+ WMT_PLAT_INFO_FUNC("WMT-PLAT:BGF EINT not defined\n"); -+#endif -+#else /* #if defined(CONFIG_MTK_GPIO_LEGACY) */ -+#endif -+ return 0; -+} -+ -+static INT32 wmt_plat_gps_sync_ctrl(ENUM_PIN_STATE state) -+{ -+#if defined(CONFIG_MTK_GPIO_LEGACY) -+ -+#ifdef GPIO_GPS_SYNC_PIN -+#ifndef GPIO_GPS_SYNC_PIN_M_GPS_SYNC -+#ifdef GPIO_GPS_SYNC_PIN_M_MD1_GPS_SYNC -+#define GPIO_GPS_SYNC_PIN_M_GPS_SYNC GPIO_GPS_SYNC_PIN_M_MD1_GPS_SYNC -+#else -+#ifdef GPIO_GPS_SYNC_PIN_M_MD2_GPS_SYNC -+#define GPIO_GPS_SYNC_PIN_M_GPS_SYNC GPIO_GPS_SYNC_PIN_M_MD2_GPS_SYNC -+#endif -+#endif -+#endif -+ switch (state) { -+ case PIN_STA_INIT: -+ case PIN_STA_DEINIT: -+ mt_set_gpio_mode(GPIO_GPS_SYNC_PIN, GPIO_GPS_SYNC_PIN_M_GPIO); -+ mt_set_gpio_dir(GPIO_GPS_SYNC_PIN, GPIO_DIR_OUT); -+ mt_set_gpio_out(GPIO_GPS_SYNC_PIN, GPIO_OUT_ZERO); -+ break; -+ -+ case PIN_STA_MUX: -+ mt_set_gpio_mode(GPIO_GPS_SYNC_PIN, GPIO_GPS_SYNC_PIN_M_GPS_SYNC); -+ break; -+ -+ default: -+ break; -+ } -+#endif -+ -+#else /* #if defined(CONFIG_MTK_GPIO_LEGACY) */ -+#endif -+ return 0; -+} -+ -+#if MTK_WCN_MT6306_IS_READY -+/* MT6306 GPIO7 is GPIO_GPS_LNA_EN, for K2 common phone pin modification */ -+static INT32 wmt_plat_gps_lna_ctrl(ENUM_PIN_STATE state) -+{ -+#ifdef GPIO_GPS_LNA_PIN -+ switch (state) { -+ case PIN_STA_INIT: -+ case PIN_STA_DEINIT: -+ WMT_PLAT_ERR_FUNC("Gps LNA pin ctrl %d!\n", state); -+ mt6306_set_gpio_dir(GPIO_GPS_LNA_PIN, GPIO_DIR_OUT); -+ mt6306_set_gpio_out(GPIO_GPS_LNA_PIN, GPIO_OUT_ZERO); -+ break; -+ case PIN_STA_OUT_H: -+ WMT_PLAT_ERR_FUNC("Gps LNA pin output high!\n"); -+ mt6306_set_gpio_out(GPIO_GPS_LNA_PIN, GPIO_OUT_ONE); -+ break; -+ case PIN_STA_OUT_L: -+ WMT_PLAT_ERR_FUNC("Gps LNA pin output low!\n"); -+ mt6306_set_gpio_out(GPIO_GPS_LNA_PIN, GPIO_OUT_ZERO); -+ break; -+ default: -+ WMT_PLAT_WARN_FUNC("%d mode not defined for gps lna pin !!!\n", state); -+ break; -+ } -+ return 0; -+#else -+ WMT_PLAT_WARN_FUNC("host gps lna pin not defined!!!\n"); -+ return 0; -+#endif -+} -+#else -+ -+static INT32 wmt_plat_gps_lna_ctrl(ENUM_PIN_STATE state) -+{ -+#if !defined(CONFIG_MTK_GPIO_LEGACY) -+ static struct pinctrl_state *gps_lna_init; -+ static struct pinctrl_state *gps_lna_oh; -+ static struct pinctrl_state *gps_lna_ol; -+ static struct pinctrl *consys_pinctrl; -+ -+ WMT_PLAT_DBG_FUNC("ENTER++\n"); -+ consys_pinctrl = mtk_wcn_consys_get_pinctrl(); -+ if (NULL == consys_pinctrl) { -+ WMT_PLAT_ERR_FUNC("get consys pinctrl fail\n"); -+ return -1; -+ } -+ -+ gps_lna_init = pinctrl_lookup_state(consys_pinctrl, "gps_lna_state_init"); -+ if (NULL == gps_lna_init) { -+ WMT_PLAT_ERR_FUNC("Cannot find gps lna pin init state!\n"); -+ return -2; -+ } -+ -+ gps_lna_oh = pinctrl_lookup_state(consys_pinctrl, "gps_lna_state_oh"); -+ if (NULL == gps_lna_oh) { -+ WMT_PLAT_ERR_FUNC("Cannot find gps lna pin oh state!\n"); -+ return -3; -+ } -+ -+ gps_lna_ol = pinctrl_lookup_state(consys_pinctrl, "gps_lna_state_ol"); -+ if (NULL == gps_lna_ol) { -+ WMT_PLAT_ERR_FUNC("Cannot find gps lna pin ol state!\n"); -+ return -4; -+ } -+ -+ switch (state) { -+ case PIN_STA_INIT: -+ case PIN_STA_DEINIT: -+ pinctrl_select_state(consys_pinctrl, gps_lna_init); -+ WMT_PLAT_INFO_FUNC("set gps lna to init\n"); -+ break; -+ case PIN_STA_OUT_H: -+ pinctrl_select_state(consys_pinctrl, gps_lna_oh); -+ WMT_PLAT_INFO_FUNC("set gps lna to oh\n"); -+ break; -+ case PIN_STA_OUT_L: -+ pinctrl_select_state(consys_pinctrl, gps_lna_ol); -+ WMT_PLAT_INFO_FUNC("set gps lna to ol\n"); -+ break; -+ -+ default: -+ WMT_PLAT_WARN_FUNC("%d mode not defined for gps lna pin !!!\n", state); -+ break; -+ } -+ return 0; -+#else -+#ifdef GPIO_GPS_LNA_PIN -+ switch (state) { -+ case PIN_STA_INIT: -+ case PIN_STA_DEINIT: -+ mt_set_gpio_pull_enable(GPIO_GPS_LNA_PIN, GPIO_PULL_DISABLE); -+ mt_set_gpio_dir(GPIO_GPS_LNA_PIN, GPIO_DIR_OUT); -+ mt_set_gpio_mode(GPIO_GPS_LNA_PIN, GPIO_GPS_LNA_PIN_M_GPIO); -+ mt_set_gpio_out(GPIO_GPS_LNA_PIN, GPIO_OUT_ZERO); -+ break; -+ case PIN_STA_OUT_H: -+ mt_set_gpio_out(GPIO_GPS_LNA_PIN, GPIO_OUT_ONE); -+ break; -+ case PIN_STA_OUT_L: -+ mt_set_gpio_out(GPIO_GPS_LNA_PIN, GPIO_OUT_ZERO); -+ break; -+ -+ default: -+ WMT_PLAT_WARN_FUNC("%d mode not defined for gps lna pin !!!\n", state); -+ break; -+ } -+ return 0; -+#else -+ WMT_PLAT_WARN_FUNC("host gps lna pin not defined!!!\n"); -+ return 0; -+#endif -+#endif /* !defined(CONFIG_MTK_GPIO_LEGACY) */ -+} -+#endif -+ -+INT32 wmt_plat_i2s_ctrl(ENUM_PIN_STATE state) -+{ -+ /* TODO: [NewFeature][GeorgeKuo]: GPIO_I2Sx is changed according to different project. */ -+ /* TODO: provide a translation table in board_custom.h for different ALPS project customization. */ -+#if defined(CONFIG_MTK_GPIO_LEGACY) -+ -+#if defined(FM_DIGITAL_INPUT) || defined(FM_DIGITAL_OUTPUT) -+#if defined(GPIO_COMBO_I2S_CK_PIN) -+ switch (state) { -+ case PIN_STA_INIT: -+ case PIN_STA_MUX: -+ mt_set_gpio_mode(GPIO_COMBO_I2S_CK_PIN, GPIO_COMBO_I2S_CK_PIN_M_I2S0_CK); -+ mt_set_gpio_mode(GPIO_COMBO_I2S_WS_PIN, GPIO_COMBO_I2S_WS_PIN_M_I2S0_WS); -+ mt_set_gpio_mode(GPIO_COMBO_I2S_DAT_PIN, GPIO_COMBO_I2S_DAT_PIN_M_I2S0_DAT); -+ WMT_PLAT_DBG_FUNC("WMT-PLAT:I2S init (I2S0 system)\n"); -+ break; -+ case PIN_STA_IN_L: -+ case PIN_STA_DEINIT: -+ mt_set_gpio_mode(GPIO_COMBO_I2S_CK_PIN, GPIO_COMBO_I2S_CK_PIN_M_GPIO); -+ mt_set_gpio_dir(GPIO_COMBO_I2S_CK_PIN, GPIO_DIR_OUT); -+ mt_set_gpio_out(GPIO_COMBO_I2S_CK_PIN, GPIO_OUT_ZERO); -+ -+ mt_set_gpio_mode(GPIO_COMBO_I2S_WS_PIN, GPIO_COMBO_I2S_WS_PIN_M_GPIO); -+ mt_set_gpio_dir(GPIO_COMBO_I2S_WS_PIN, GPIO_DIR_OUT); -+ mt_set_gpio_out(GPIO_COMBO_I2S_WS_PIN, GPIO_OUT_ZERO); -+ -+ mt_set_gpio_mode(GPIO_COMBO_I2S_DAT_PIN, GPIO_COMBO_I2S_DAT_PIN_M_GPIO); -+ mt_set_gpio_dir(GPIO_COMBO_I2S_DAT_PIN, GPIO_DIR_OUT); -+ mt_set_gpio_out(GPIO_COMBO_I2S_DAT_PIN, GPIO_OUT_ZERO); -+ WMT_PLAT_DBG_FUNC("WMT-PLAT:I2S deinit (out 0)\n"); -+ break; -+ default: -+ WMT_PLAT_WARN_FUNC("WMT-PLAT:Warnning, invalid state(%d) on I2S Group\n", state); -+ break; -+ } -+#else -+ WMT_PLAT_ERR_FUNC("[MT6620]Error:FM digital mode set, but no I2S GPIOs defined\n"); -+#endif -+#else -+ WMT_PLAT_INFO_FUNC -+ ("[MT6620]warnning:FM digital mode is not set, no I2S GPIO settings should be modified by combo driver\n"); -+#endif -+ -+#else /* #if defined(CONFIG_MTK_GPIO_LEGACY) */ -+#endif -+ return 0; -+} -+ -+INT32 wmt_plat_wake_lock_ctrl(ENUM_WL_OP opId) -+{ -+#ifdef CFG_WMT_WAKELOCK_SUPPORT -+ static INT32 counter; -+ INT32 status; -+ INT32 ret = 0; -+ -+ ret = mutex_lock_killable(&gOsSLock); -+ if (ret) { -+ WMT_PLAT_ERR_FUNC("--->lock gOsSLock failed, ret=%d\n", ret); -+ return ret; -+ } -+ -+ if (WL_OP_GET == opId) -+ ++counter; -+ else if (WL_OP_PUT == opId) -+ --counter; -+ -+ mutex_unlock(&gOsSLock); -+ if (WL_OP_GET == opId && counter == 1) { -+ #ifdef CONFIG_PM_WAKELOCKS -+ __pm_stay_awake(&wmtWakeLock); -+ status = wmtWakeLock.active; -+ #else -+ wake_lock(&wmtWakeLock); -+ status = wake_lock_active(&wmtWakeLock); -+ #endif -+ WMT_PLAT_DBG_FUNC("WMT-PLAT: after wake_lock(%d), counter(%d)\n", status, counter); -+ -+ } else if (WL_OP_PUT == opId && counter == 0) { -+ #ifdef CONFIG_PM_WAKELOCKS -+ __pm_relax(&wmtWakeLock); -+ status = wmtWakeLock.active; -+ #else -+ wake_unlock(&wmtWakeLock); -+ status = wake_lock_active(&wmtWakeLock); -+ #endif -+ WMT_PLAT_DBG_FUNC("WMT-PLAT: after wake_unlock(%d), counter(%d)\n", status, counter); -+ } else { -+ #ifdef CONFIG_PM_WAKELOCKS -+ status = wmtWakeLock.active; -+ #else -+ status = wake_lock_active(&wmtWakeLock); -+ #endif -+ WMT_PLAT_WARN_FUNC("WMT-PLAT: wakelock status(%d), counter(%d)\n", status, counter); -+ } -+ return 0; -+#else -+ WMT_PLAT_WARN_FUNC("WMT-PLAT: host awake function is not supported.\n"); -+ return 0; -+ -+#endif -+} -+EXPORT_SYMBOL(wmt_plat_wake_lock_ctrl); -+ -+INT32 wmt_plat_soc_paldo_ctrl(ENUM_PALDO_TYPE ePt, ENUM_PALDO_OP ePo) -+{ -+ INT32 iRet = 0; -+ -+ switch (ePt) { -+ -+ case BT_PALDO: -+ iRet = mtk_wcn_consys_hw_bt_paldo_ctrl(ePo); -+ break; -+ case WIFI_PALDO: -+ iRet = mtk_wcn_consys_hw_wifi_paldo_ctrl(ePo); -+ break; -+ case FM_PALDO: -+ case GPS_PALDO: -+ iRet = mtk_wcn_consys_hw_vcn28_ctrl(ePo); -+ break; -+ default: -+ WMT_PLAT_WARN_FUNC("WMT-PLAT:Warnning, invalid type(%d) in palod_ctrl\n", ePt); -+ break; -+ } -+ return iRet; -+} -+EXPORT_SYMBOL(wmt_plat_soc_paldo_ctrl); -+ -+UINT8 *wmt_plat_get_emi_virt_add(UINT32 offset) -+{ -+ return mtk_wcn_consys_emi_virt_addr_get(offset); -+} -+EXPORT_SYMBOL(wmt_plat_get_emi_virt_add); -+ -+P_CONSYS_EMI_ADDR_INFO wmt_plat_get_emi_phy_add(VOID) -+{ -+ return &mtk_wcn_emi_addr_info; -+} -+EXPORT_SYMBOL(wmt_plat_get_emi_phy_add); -+ -+#if CONSYS_ENALBE_SET_JTAG -+UINT32 wmt_plat_jtag_flag_ctrl(UINT32 en) -+{ -+ return 0; -+} -+EXPORT_SYMBOL(wmt_plat_jtag_flag_ctrl); -+#endif -+ -+#if CFG_WMT_DUMP_INT_STATUS -+VOID wmt_plat_BGF_irq_dump_status(VOID) -+{ -+ WMT_PLAT_INFO_FUNC("this function is null in MT8127\n"); -+} -+EXPORT_SYMBOL(wmt_plat_BGF_irq_dump_status); -+ -+MTK_WCN_BOOL wmt_plat_dump_BGF_irq_status(VOID) -+{ -+ return MTK_WCN_BOOL_FALSE; -+} -+EXPORT_SYMBOL(wmt_plat_dump_BGF_irq_status); -+#endif -+ -+UINT32 wmt_plat_read_cpupcr(void) -+{ -+ return CONSYS_REG_READ(conn_reg.mcu_base + CONSYS_CPUPCR_OFFSET); -+} -+EXPORT_SYMBOL(wmt_plat_read_cpupcr); -+ -+UINT32 wmt_plat_read_dmaregs(UINT32 type) -+{ -+ return 0; -+#if 0 -+ switch (type) { -+ case CONNSYS_CLK_GATE_STATUS: -+ return CONSYS_REG_READ(CONNSYS_CLK_GATE_STATUS_REG); -+ case CONSYS_EMI_STATUS: -+ return CONSYS_REG_READ(CONSYS_EMI_STATUS_REG); -+ case SYSRAM1: -+ return CONSYS_REG_READ(SYSRAM1_REG); -+ case SYSRAM2: -+ return CONSYS_REG_READ(SYSRAM2_REG); -+ case SYSRAM3: -+ return CONSYS_REG_READ(SYSRAM3_REG); -+ default: -+ return 0; -+ } -+#endif -+} -+ -+INT32 wmt_plat_set_host_dump_state(ENUM_HOST_DUMP_STATE state) -+{ -+ PUINT8 p_virtual_addr = NULL; -+ -+ p_virtual_addr = wmt_plat_get_emi_virt_add(EXP_APMEM_CTRL_HOST_SYNC_STATE); -+ if (!p_virtual_addr) { -+ WMT_PLAT_ERR_FUNC("get virtual address fail\n"); -+ return -1; -+ } -+ -+ CONSYS_REG_WRITE(p_virtual_addr, state); -+ -+ return 0; -+} -+EXPORT_SYMBOL(wmt_plat_set_host_dump_state); -+ -+UINT32 wmt_plat_force_trigger_assert(ENUM_FORCE_TRG_ASSERT_T type) -+{ -+ PUINT8 p_virtual_addr = NULL; -+ -+ switch (type) { -+ case STP_FORCE_TRG_ASSERT_EMI: -+ -+ WMT_PLAT_INFO_FUNC("[Force Assert] stp_trigger_firmware_assert_via_emi -->\n"); -+ p_virtual_addr = wmt_plat_get_emi_virt_add(EXP_APMEM_CTRL_HOST_OUTBAND_ASSERT_W1); -+ if (!p_virtual_addr) { -+ WMT_PLAT_ERR_FUNC("get virtual address fail\n"); -+ return -1; -+ } -+ -+ CONSYS_REG_WRITE(p_virtual_addr, EXP_APMEM_HOST_OUTBAND_ASSERT_MAGIC_W1); -+ WMT_PLAT_INFO_FUNC("[Force Assert] stp_trigger_firmware_assert_via_emi <--\n"); -+ break; -+ case STP_FORCE_TRG_ASSERT_DEBUG_PIN: -+ -+ CONSYS_REG_WRITE(conn_reg.topckgen_base + CONSYS_AP2CONN_OSC_EN_OFFSET, -+ CONSYS_REG_READ(conn_reg.topckgen_base + -+ CONSYS_AP2CONN_OSC_EN_OFFSET) & ~CONSYS_AP2CONN_WAKEUP_BIT); -+ WMT_PLAT_INFO_FUNC("enable:dump CONSYS_AP2CONN_OSC_EN_REG(0x%x)\n", -+ CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_AP2CONN_OSC_EN_OFFSET)); -+ usleep_range(64, 96); -+ CONSYS_REG_WRITE(conn_reg.topckgen_base + CONSYS_AP2CONN_OSC_EN_OFFSET, -+ CONSYS_REG_READ(conn_reg.topckgen_base + -+ CONSYS_AP2CONN_OSC_EN_OFFSET) | CONSYS_AP2CONN_WAKEUP_BIT); -+ WMT_PLAT_INFO_FUNC("disable:dump CONSYS_AP2CONN_OSC_EN_REG(0x%x)\n", -+ CONSYS_REG_READ(conn_reg.topckgen_base + CONSYS_AP2CONN_OSC_EN_OFFSET)); -+ -+ break; -+ default: -+ WMT_PLAT_ERR_FUNC("unknown force trigger assert type\n"); -+ break; -+ } -+ -+ return 0; -+} -+EXPORT_SYMBOL(wmt_plat_force_trigger_assert); -+ -+INT32 wmt_plat_update_host_sync_num(VOID) -+{ -+ PUINT8 p_virtual_addr = NULL; -+ UINT32 sync_num = 0; -+ -+ p_virtual_addr = wmt_plat_get_emi_virt_add(EXP_APMEM_CTRL_HOST_SYNC_NUM); -+ if (!p_virtual_addr) { -+ WMT_PLAT_ERR_FUNC("get virtual address fail\n"); -+ return -1; -+ } -+ -+ sync_num = CONSYS_REG_READ(p_virtual_addr); -+ CONSYS_REG_WRITE(p_virtual_addr, sync_num + 1); -+ -+ return 0; -+} -+EXPORT_SYMBOL(wmt_plat_update_host_sync_num); -+ -+INT32 wmt_plat_get_dump_info(UINT32 offset) -+{ -+ PUINT8 p_virtual_addr = NULL; -+ -+ p_virtual_addr = wmt_plat_get_emi_virt_add(offset); -+ if (!p_virtual_addr) { -+ WMT_PLAT_ERR_FUNC("get virtual address fail\n"); -+ return -1; -+ } -+ WMT_PLAT_INFO_FUNC("connsys_reg_read (0x%x), (0x%p), (0x%x)\n", CONSYS_REG_READ(p_virtual_addr), p_virtual_addr, -+ offset); -+ return CONSYS_REG_READ(p_virtual_addr); -+} -+EXPORT_SYMBOL(wmt_plat_get_dump_info); -+ -+UINT32 wmt_plat_get_soc_chipid(void) -+{ -+ UINT32 chipId = mtk_wcn_consys_soc_chipid(); -+ -+ WMT_PLAT_INFO_FUNC("current SOC chip:0x%x\n", chipId); -+ return chipId; -+} -+EXPORT_SYMBOL(wmt_plat_get_soc_chipid); -+ -+#if CFG_WMT_LTE_COEX_HANDLING -+INT32 wmt_plat_get_tdm_antsel_index(VOID) -+{ -+ WMT_PLAT_INFO_FUNC("not support LTE in this platform\n"); -+ return 0; -+} -+EXPORT_SYMBOL(wmt_plat_get_tdm_antsel_index); -+#endif -+INT32 wmt_plat_set_dbg_mode(UINT32 flag) -+{ -+ return -1; -+} -+VOID wmt_plat_set_dynamic_dumpmem(UINT32 *buf) -+{ -+ mtk_wcn_consys_set_dynamic_dump(buf); -+} -diff --git a/drivers/misc/mediatek/connectivity/wlan/Makefile b/drivers/misc/mediatek/connectivity/wlan/Makefile -new file mode 100644 -index 000000000000..2961aeb073ea ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/Makefile -@@ -0,0 +1,8 @@ -+ifeq ($(CONFIG_MTK_COMBO_WIFI),y) -+ subdir-ccflags-y += -D MTK_WCN_BUILT_IN_DRIVER -+endif -+ -+ifneq ($(filter "CONSYS_%",$(CONFIG_MTK_COMBO_CHIP)),) -+#$(warning include gen2) -+ obj-y += gen2/ -+endif -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/Makefile b/drivers/misc/mediatek/connectivity/wlan/gen2/Makefile -new file mode 100644 -index 000000000000..b86ab49fce3a ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/Makefile -@@ -0,0 +1,237 @@ -+# --------------------------------------------------- -+# Compile Options -+# --------------------------------------------------- -+ccflags-y += -DLINUX -DMT6628 -+ -+ccflags-y += -DCFG_SUPPORT_AGPS_ASSIST=1 -+ccflags-y += -DCFG_SUPPORT_TSF_USING_BOOTTIME=1 -+ccflags-y += -DCFG_P2P_LEGACY_COEX_REVISE=1 -+ccflags-y += -DARP_MONITER_ENABLE=1 -+ -+ifeq ($(CONFIG_MTK_WAPI_SUPPORT), y) -+ ccflags-y += -DCFG_SUPPORT_WAPI=1 -+else -+ ccflags-y += -DCFG_SUPPORT_WAPI=0 -+endif -+ -+ifeq ($(CONFIG_MTK_WIFI_MCC_SUPPORT), y) -+ ccflags-y += -DCFG_SUPPORT_MCC=1 -+else -+ ccflags-y += -DCFG_SUPPORT_MCC=0 -+endif -+ -+ifeq ($(CONFIG_HAVE_XLOG_FEATURE), y) -+ ccflags-y += -DCFG_SUPPORT_XLOG=1 -+else -+ ccflags-y += -DCFG_SUPPORT_XLOG=0 -+endif -+ -+ifeq ($(CONFIG_MTK_AEE_FEATURE), y) -+ ccflags-y += -DCFG_SUPPORT_AEE=1 -+else -+ ccflags-y += -DCFG_SUPPORT_AEE=0 -+endif -+ -+#ifeq ($(CONFIG_MTK_COMBO_WIFI_HIF_SDIO1), y) -+# ccflags-y += -D_HIF_SDIO=1 -+#endif -+ -+ifeq ($(CONFIG_MTK_PASSPOINT_R1_SUPPORT), y) -+ ccflags-y += -DCFG_SUPPORT_HOTSPOT_2_0=1 -+ ccflags-y += -DCFG_HS20_DEBUG=1 -+ ccflags-y += -DCFG_ENABLE_GTK_FRAME_FILTER=1 -+else -+ ccflags-y += -DCFG_SUPPORT_HOTSPOT_2_0=0 -+ ccflags-y += -DCFG_HS20_DEBUG=0 -+ ccflags-y += -DCFG_ENABLE_GTK_FRAME_FILTER=0 -+endif -+ -+MTK_MET_PROFILING_SUPPORT = no -+ifeq ($(MTK_MET_PROFILING_SUPPORT), yes) -+ ccflags-y += -DCFG_SUPPORT_MET_PROFILING=1 -+else -+ ccflags-y += -DCFG_SUPPORT_MET_PROFILING=0 -+endif -+ -+ifeq ($(CONFIG_MTK_TC1_FEATURE), y) -+ifeq ($(CONFIG_MTK_GPT_SCHEME_SUPPORT), y) -+ ccflags-y += -I$(srctree)/drivers/misc/mediatek/tc1_interface/gpt -+else -+ ccflags-y += -I$(srctree)/drivers/misc/mediatek/tc1_interface/pmt -+endif -+ ccflags-y += -DCFG_TC1_FEATURE=1 -+ ccflags-y += -DCFG_SUPPORT_CFG_FILE=1 -+else -+ ccflags-y += -DCFG_TC1_FEATURE=0 -+endif -+ -+MTK_SRAM_SIZE_OPTION=0 -+ifeq ($(CONFIG_ARCH_MT6755), y) -+ MTK_SRAM_SIZE_OPTION=2 -+endif -+ifeq ($(CONFIG_ARCH_MT6735), y) -+ MTK_SRAM_SIZE_OPTION=1 -+endif -+ifeq ($(CONFIG_ARCH_MT6735M), y) -+ MTK_SRAM_SIZE_OPTION=1 -+endif -+ifeq ($(CONFIG_ARCH_MT6753), y) -+ MTK_SRAM_SIZE_OPTION=1 -+endif -+ifeq ($(CONFIG_ARCH_MT6580), y) -+ MTK_SRAM_SIZE_OPTION=1 -+endif -+ifeq ($(CONFIG_ARCH_MT8163), y) -+ MTK_SRAM_SIZE_OPTION=1 -+endif -+ccflags-y += -DCFG_SRAM_SIZE_OPTION=$(MTK_SRAM_SIZE_OPTION) -+ -+ifeq ($(strip $(TRUSTONIC_TEE_SUPPORT)),yes) -+ifeq ($(strip $(MTK_TEE_CCCI_SECURE_SHARE_MEM_SUPPORT)),yes) -+ ccflags-y += -DTRUSTONIC_TEE_SUPPORT -+ ccflags-y += -DMTK_TEE_CCCI_SECURE_SHARE_MEM_SUPPORT -+endif -+endif -+ -+ccflags-y += -D_HIF_SDIO=1 -+ -+ccflags-y += -DDBG=0 -+ccflags-y += -I$(src)/os -I$(src)/os/linux/include -I$(src)/os/linux/hif/ahb/include -+ccflags-y += -I$(src)/include -I$(src)/include/nic -I$(src)/include/mgmt -+ccflags-y += -I$(srctree)/drivers/misc/mediatek/base/power/include -+ccflags-y += -I$(srctree)/drivers/misc/mediatek/include/ -+ -+MODULE_NAME := wlan_gen2 -+obj-$(CONFIG_MTK_COMBO_WIFI) += $(MODULE_NAME).o -+#obj-m += $(MODULE_NAME).o if CONFIG_MTK_COMBO_WIFI=m ==> obj-m means ko module, not build in obj-y -+ -+# --------------------------------------------------- -+# Directory List -+# --------------------------------------------------- -+COMMON_DIR := common/ -+OS_DIR := os/linux/ -+HIF_DIR := os/linux/hif/ahb/ -+NIC_DIR := nic/ -+MGMT_DIR := mgmt/ -+DMA_DIR := ../../../../platform/$(call lc,$(MTK_PLATFORM))/kernel/drivers/wifi/ -+PLAT_DIR := os/linux/plat/$(MTK_PLATFORM)/ -+HIF_AHB_PDMA := $(HIF_DIR)$(MTK_PLATFORM)/ -+#$(call lc,$(MTK_PLATFORM)) -+ -+ -+# --------------------------------------------------- -+# Objects List -+# --------------------------------------------------- -+ -+COMMON_OBJS := $(COMMON_DIR)dump.o \ -+ $(COMMON_DIR)wlan_lib.o \ -+ $(COMMON_DIR)wlan_oid.o \ -+ $(COMMON_DIR)wlan_bow.o \ -+ $(COMMON_DIR)debug.o -+ -+NIC_OBJS := $(NIC_DIR)nic.o \ -+ $(NIC_DIR)nic_tx.o \ -+ $(NIC_DIR)nic_rx.o \ -+ $(NIC_DIR)nic_pwr_mgt.o \ -+ $(NIC_DIR)cmd_buf.o \ -+ $(NIC_DIR)que_mgt.o \ -+ $(NIC_DIR)nic_cmd_event.o -+ -+OS_OBJS := $(OS_DIR)gl_init.o \ -+ $(OS_DIR)gl_kal.o \ -+ $(OS_DIR)gl_bow.o \ -+ $(OS_DIR)gl_wext.o \ -+ $(OS_DIR)gl_wext_priv.o \ -+ $(OS_DIR)gl_rst.o \ -+ $(OS_DIR)gl_cfg80211.o \ -+ $(OS_DIR)gl_vendor.o \ -+ $(OS_DIR)platform.o \ -+ $(OS_DIR)gl_proc.o -+ -+MGMT_OBJS := $(MGMT_DIR)ais_fsm.o \ -+ $(MGMT_DIR)aaa_fsm.o \ -+ $(MGMT_DIR)assoc.o \ -+ $(MGMT_DIR)auth.o \ -+ $(MGMT_DIR)bss.o \ -+ $(MGMT_DIR)cnm.o \ -+ $(MGMT_DIR)cnm_timer.o \ -+ $(MGMT_DIR)cnm_mem.o \ -+ $(MGMT_DIR)hem_mbox.o \ -+ $(MGMT_DIR)mib.o \ -+ $(MGMT_DIR)privacy.o \ -+ $(MGMT_DIR)rate.o \ -+ $(MGMT_DIR)rlm.o \ -+ $(MGMT_DIR)rlm_domain.o \ -+ $(MGMT_DIR)rlm_obss.o \ -+ $(MGMT_DIR)rlm_protection.o \ -+ $(MGMT_DIR)rsn.o \ -+ $(MGMT_DIR)saa_fsm.o \ -+ $(MGMT_DIR)scan.o \ -+ $(MGMT_DIR)scan_fsm.o \ -+ $(MGMT_DIR)sec_fsm.o \ -+ $(MGMT_DIR)swcr.o \ -+ $(MGMT_DIR)swcr.o \ -+ $(MGMT_DIR)roaming_fsm.o \ -+ $(MGMT_DIR)hs20.o -+ -+# --------------------------------------------------- -+# TDLS Objects List -+# --------------------------------------------------- -+MGMT_OBJS += $(MGMT_DIR)tdls.o \ -+ $(MGMT_DIR)tdls_com.o -+ -+# --------------------------------------------------- -+# STATS Objects List -+# --------------------------------------------------- -+MGMT_OBJS += $(MGMT_DIR)stats.o -+ -+# --------------------------------------------------- -+# P2P Objects List -+# --------------------------------------------------- -+ -+COMMON_OBJS += $(COMMON_DIR)wlan_p2p.o -+ -+NIC_OBJS += $(NIC_DIR)p2p_nic.o -+ -+OS_OBJS += $(OS_DIR)gl_p2p.o \ -+ $(OS_DIR)gl_p2p_cfg80211.o \ -+ $(OS_DIR)gl_p2p_init.o \ -+ $(OS_DIR)gl_p2p_kal.o -+ -+MGMT_OBJS += $(MGMT_DIR)p2p_assoc.o \ -+ $(MGMT_DIR)p2p_bss.o \ -+ $(MGMT_DIR)p2p_fsm.o \ -+ $(MGMT_DIR)p2p_func.o \ -+ $(MGMT_DIR)p2p_rlm.o \ -+ $(MGMT_DIR)p2p_rlm_obss.o \ -+ $(MGMT_DIR)p2p_scan.o \ -+ $(MGMT_DIR)p2p_ie.o \ -+ $(MGMT_DIR)p2p_state.o -+ -+ -+ifeq ($(CONFIG_MTK_WAPI_SUPPORT), y) -+MGMT_OBJS += $(MGMT_DIR)wapi.o -+endif -+ -+ifeq ($(WLAN_PROC), y) -+OS_OBJS += gl_proc.o -+endif -+ -+#$(warning $(CONFIG_MACH_MT7623)) -+ -+ifeq ($(CONFIG_MACH_MT7623), y) -+HIF_AHB_PDMA = $(HIF_DIR)mt8127/ -+endif -+HIF_OBJS := $(HIF_DIR)arm.o \ -+ $(HIF_DIR)ahb.o \ -+ $(HIF_AHB_PDMA)ahb_pdma.o -+ifeq ($(CONFIG_ARCH_MT6755), y) -+PLAT_OBJS := $(PLAT_DIR)plat_priv.o -+$(MODULE_NAME)-objs += $(PLAT_OBJS) -+endif -+$(MODULE_NAME)-objs += $(COMMON_OBJS) -+$(MODULE_NAME)-objs += $(NIC_OBJS) -+$(MODULE_NAME)-objs += $(OS_OBJS) -+$(MODULE_NAME)-objs += $(HIF_OBJS) -+$(MODULE_NAME)-objs += $(MGMT_OBJS) -+ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/common/debug.c b/drivers/misc/mediatek/connectivity/wlan/gen2/common/debug.c -new file mode 100644 -index 000000000000..e31e0b86d231 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/common/debug.c -@@ -0,0 +1,165 @@ -+#include "precomp.h" -+#include "gl_kal.h" -+ -+struct COMMAND { -+ UINT_8 ucCID; -+ BOOLEAN fgSetQuery; -+ BOOLEAN fgNeedResp; -+ UINT_8 ucCmdSeqNum; -+}; -+ -+struct SECURITY_FRAME { -+ UINT_16 u2EthType; -+ UINT_16 u2Reserved; -+}; -+ -+struct MGMT_FRAME { -+ UINT_16 u2FrameCtl; -+ UINT_16 u2DurationID; -+}; -+ -+struct TC_RES_RELEASE_ENTRY { -+ UINT_64 u8RelaseTime; -+ UINT_32 u4RelCID; -+ UINT_8 ucTc4RelCnt; -+ UINT_8 ucAvailableTc4; -+}; -+ -+struct CMD_TRACE_ENTRY { -+ UINT_64 u8TxTime; -+ COMMAND_TYPE eCmdType; -+ union { -+ struct COMMAND rCmd; -+ struct SECURITY_FRAME rSecFrame; -+ struct MGMT_FRAME rMgmtFrame; -+ } u; -+}; -+ -+#define TC_RELEASE_TRACE_BUF_MAX_NUM 100 -+#define TXED_CMD_TRACE_BUF_MAX_NUM 100 -+ -+static struct TC_RES_RELEASE_ENTRY *gprTcReleaseTraceBuffer; -+static struct CMD_TRACE_ENTRY *gprCmdTraceEntry; -+VOID wlanDebugInit(VOID) -+{ -+ /* debug for command/tc4 resource begin */ -+ gprTcReleaseTraceBuffer = -+ kalMemAlloc(TC_RELEASE_TRACE_BUF_MAX_NUM * sizeof(struct TC_RES_RELEASE_ENTRY), PHY_MEM_TYPE); -+ kalMemZero(gprTcReleaseTraceBuffer, TC_RELEASE_TRACE_BUF_MAX_NUM * sizeof(struct TC_RES_RELEASE_ENTRY)); -+ gprCmdTraceEntry = kalMemAlloc(TXED_CMD_TRACE_BUF_MAX_NUM * sizeof(struct CMD_TRACE_ENTRY), PHY_MEM_TYPE); -+ kalMemZero(gprCmdTraceEntry, TXED_CMD_TRACE_BUF_MAX_NUM * sizeof(struct CMD_TRACE_ENTRY)); -+ /* debug for command/tc4 resource end */ -+} -+ -+VOID wlanDebugUninit(VOID) -+{ -+ /* debug for command/tc4 resource begin */ -+ kalMemFree(gprTcReleaseTraceBuffer, PHY_MEM_TYPE, -+ TC_RELEASE_TRACE_BUF_MAX_NUM * sizeof(struct TC_RES_RELEASE_ENTRY)); -+ kalMemFree(gprCmdTraceEntry, PHY_MEM_TYPE, TXED_CMD_TRACE_BUF_MAX_NUM * sizeof(struct CMD_TRACE_ENTRY)); -+ /* debug for command/tc4 resource end */ -+} -+ -+VOID wlanTraceTxCmd(P_CMD_INFO_T prCmd) -+{ -+ static UINT_16 u2CurEntry; -+ struct CMD_TRACE_ENTRY *prCurCmd = &gprCmdTraceEntry[u2CurEntry]; -+ -+ prCurCmd->u8TxTime = sched_clock(); -+ prCurCmd->eCmdType = prCmd->eCmdType; -+ if (prCmd->eCmdType == COMMAND_TYPE_MANAGEMENT_FRAME) { -+ P_WLAN_MAC_MGMT_HEADER_T prMgmt = (P_WLAN_MAC_MGMT_HEADER_T)((P_MSDU_INFO_T)prCmd->prPacket)->prPacket; -+ -+ prCurCmd->u.rMgmtFrame.u2FrameCtl = prMgmt->u2FrameCtrl; -+ prCurCmd->u.rMgmtFrame.u2DurationID = prMgmt->u2Duration; -+ } else if (prCmd->eCmdType == COMMAND_TYPE_SECURITY_FRAME) { -+ PUINT_8 pucPkt = (PUINT_8)((struct sk_buff *)prCmd->prPacket)->data; -+ -+ prCurCmd->u.rSecFrame.u2EthType = -+ (pucPkt[ETH_TYPE_LEN_OFFSET] << 8) | (pucPkt[ETH_TYPE_LEN_OFFSET + 1]); -+ } else { -+ prCurCmd->u.rCmd.ucCID = prCmd->ucCID; -+ prCurCmd->u.rCmd.ucCmdSeqNum = prCmd->ucCmdSeqNum; -+ prCurCmd->u.rCmd.fgNeedResp = prCmd->fgNeedResp; -+ prCurCmd->u.rCmd.fgSetQuery = prCmd->fgSetQuery; -+ } -+ u2CurEntry++; -+ if (u2CurEntry == TC_RELEASE_TRACE_BUF_MAX_NUM) -+ u2CurEntry = 0; -+} -+ -+VOID wlanTraceReleaseTcRes(P_ADAPTER_T prAdapter, PUINT_8 aucTxRlsCnt, UINT_8 ucAvailable) -+{ -+ static UINT_16 u2CurEntry; -+ struct TC_RES_RELEASE_ENTRY *prCurBuf = &gprTcReleaseTraceBuffer[u2CurEntry]; -+ -+ HAL_MCR_RD(prAdapter, MCR_D2HRM2R, &prCurBuf->u4RelCID); -+ prCurBuf->u8RelaseTime = sched_clock(); -+ prCurBuf->ucTc4RelCnt = aucTxRlsCnt[TC4_INDEX]; -+ prCurBuf->ucAvailableTc4 = ucAvailable; -+ u2CurEntry++; -+ if (u2CurEntry == TXED_CMD_TRACE_BUF_MAX_NUM) -+ u2CurEntry = 0; -+} -+ -+VOID wlanDumpTcResAndTxedCmd(PUINT_8 pucBuf, UINT_32 maxLen) -+{ -+ UINT_16 i = 0; -+ struct CMD_TRACE_ENTRY *prCmd = gprCmdTraceEntry; -+ struct TC_RES_RELEASE_ENTRY *prTcRel = gprTcReleaseTraceBuffer; -+ -+ if (pucBuf) { -+ int bufLen = 0; -+ -+ for (; i < TXED_CMD_TRACE_BUF_MAX_NUM/2; i++) { -+ bufLen = snprintf(pucBuf, maxLen, -+ "%d: Time %llu, Type %d, Content %08x; %d: Time %llu, Type %d, Content %08x\n", -+ i*2, prCmd[i*2].u8TxTime, prCmd[i*2].eCmdType, *(PUINT_32)(&prCmd[i*2].u.rCmd.ucCID), -+ i*2+1, prCmd[i*2+1].u8TxTime, prCmd[i*2+1].eCmdType, -+ *(PUINT_32)(&prCmd[i*2+1].u.rCmd.ucCID)); -+ if (bufLen <= 0 || (UINT_32)bufLen >= maxLen) -+ break; -+ pucBuf += bufLen; -+ maxLen -= bufLen; -+ } -+ for (i = 0; i < TC_RELEASE_TRACE_BUF_MAX_NUM/2; i++) { -+ bufLen = snprintf(pucBuf, maxLen, -+ "%d: Time %llu, Tc4Cnt %d, Free %d, CID %08x; %d: Time %llu, Tc4Cnt %d, Free %d CID %08x\n", -+ i*2, prTcRel[i*2].u8RelaseTime, prTcRel[i*2].ucTc4RelCnt, prTcRel[i*2].ucAvailableTc4, -+ prTcRel[i*2].u4RelCID, -+ i*2+1, prTcRel[i*2+1].u8RelaseTime, prTcRel[i*2+1].ucTc4RelCnt, -+ prTcRel[i*2+1].ucAvailableTc4, prTcRel[i*2+1].u4RelCID); -+ if (bufLen <= 0 || (UINT_32)bufLen >= maxLen) -+ break; -+ pucBuf += bufLen; -+ maxLen -= bufLen; -+ } -+ return; -+ } -+ for (; i < TXED_CMD_TRACE_BUF_MAX_NUM/4; i++) { -+ LOG_FUNC("%d: Time %llu, Type %d, Content %08x; %d: Time %llu, Type %d, Content %08x; ", -+ i*4, prCmd[i*4].u8TxTime, prCmd[i*4].eCmdType, -+ *(PUINT_32)(&prCmd[i*4].u.rCmd.ucCID), -+ i*4+1, prCmd[i*4+1].u8TxTime, prCmd[i*4+1].eCmdType, -+ *(PUINT_32)(&prCmd[i*4+1].u.rCmd.ucCID)); -+ LOG_FUNC("%d: Time %llu, Type %d, Content %08x; %d: Time %llu, Type %d, Content %08x\n", -+ i*4+2, prCmd[i*4+2].u8TxTime, prCmd[i*4+2].eCmdType, -+ *(PUINT_32)(&prCmd[i*4+2].u.rCmd.ucCID), -+ i*4+3, prCmd[i*4+3].u8TxTime, prCmd[i*4+3].eCmdType, -+ *(PUINT_32)(&prCmd[i*4+3].u.rCmd.ucCID)); -+ } -+ for (i = 0; i < TC_RELEASE_TRACE_BUF_MAX_NUM/4; i++) { -+ LOG_FUNC( -+ "%d: Time %llu, Tc4Cnt %d, Free %d, CID %08x; %d: Time %llu, Tc4Cnt %d, Free %d, CID %08x;", -+ i*4, prTcRel[i*4].u8RelaseTime, prTcRel[i*4].ucTc4RelCnt, -+ prTcRel[i*4].ucAvailableTc4, prTcRel[i*4].u4RelCID, -+ i*4+1, prTcRel[i*4+1].u8RelaseTime, prTcRel[i*4+1].ucTc4RelCnt, -+ prTcRel[i*4+1].ucAvailableTc4, prTcRel[i*4+1].u4RelCID); -+ LOG_FUNC( -+ " %d: Time %llu, Tc4Cnt %d, Free %d, CID %08x; %d: Time %llu, Tc4Cnt %d, Free %d, CID %08x\n", -+ i*4+2, prTcRel[i*4+2].u8RelaseTime, prTcRel[i*4+2].ucTc4RelCnt, -+ prTcRel[i*4+2].ucAvailableTc4, prTcRel[i*4+2].u4RelCID, -+ i*4+3, prTcRel[i*4+3].u8RelaseTime, prTcRel[i*4+3].ucTc4RelCnt, -+ prTcRel[i*4+3].ucAvailableTc4, prTcRel[i*4+3].u4RelCID); -+ } -+} -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/common/dump.c b/drivers/misc/mediatek/connectivity/wlan/gen2/common/dump.c -new file mode 100644 -index 000000000000..486ba239f16a ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/common/dump.c -@@ -0,0 +1,345 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/common/dump.c#1 -+*/ -+ -+/*! \file "dump.c" -+ \brief Provide memory dump function for debugging. -+ -+ Provide memory dump function for debugging. -+*/ -+ -+/* -+** Log: dump.c -+ * -+ * 11 24 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * Adjust code for DBG and CONFIG_XLOG. -+ * -+ * 11 10 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * Using the new XLOG define for dum Memory. -+ * -+ * 11 03 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * Add dumpMemory8 at XLOG support. -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 19:58:51 GMT mtk01426 -+** Init develop -+** -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "precomp.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to dump a segment of memory in bytes. -+* -+* \param[in] pucStartAddr Pointer to the starting address of the memory to be dumped. -+* \param[in] u4Length Length of the memory to be dumped. -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID dumpMemory8(IN PUINT_8 pucStartAddr, IN UINT_32 u4Length) -+{ -+ ASSERT(pucStartAddr); -+ -+ LOG_FUNC("DUMP8 ADDRESS: %p, Length: %u\n", pucStartAddr, u4Length); -+ -+ while (u4Length > 0) { -+ if (u4Length >= 16) { -+ LOG_FUNC( -+ "(%p) %02x %02x %02x %02x %02x %02x %02x %02x - %02x %02x %02x %02x %02x %02x %02x %02x\n", -+ pucStartAddr, pucStartAddr[0], pucStartAddr[1], pucStartAddr[2], pucStartAddr[3], -+ pucStartAddr[4], pucStartAddr[5], pucStartAddr[6], pucStartAddr[7], pucStartAddr[8], -+ pucStartAddr[9], pucStartAddr[10], pucStartAddr[11], pucStartAddr[12], pucStartAddr[13], -+ pucStartAddr[14], pucStartAddr[15]); -+ u4Length -= 16; -+ pucStartAddr += 16; -+ } else { -+ switch (u4Length) { -+ case 1: -+ LOG_FUNC("(%p) %02x\n", pucStartAddr, pucStartAddr[0]); -+ break; -+ case 2: -+ LOG_FUNC("(%p) %02x %02x\n", pucStartAddr, pucStartAddr[0], pucStartAddr[1]); -+ break; -+ case 3: -+ LOG_FUNC("(%p) %02x %02x %02x\n", -+ pucStartAddr, pucStartAddr[0], pucStartAddr[1], pucStartAddr[2]); -+ break; -+ case 4: -+ LOG_FUNC("(%p) %02x %02x %02x %02x\n", -+ pucStartAddr, -+ pucStartAddr[0], pucStartAddr[1], pucStartAddr[2], pucStartAddr[3]); -+ break; -+ case 5: -+ LOG_FUNC("(%p) %02x %02x %02x %02x %02x\n", -+ pucStartAddr, -+ pucStartAddr[0], pucStartAddr[1], pucStartAddr[2], pucStartAddr[3], -+ pucStartAddr[4]); -+ break; -+ case 6: -+ LOG_FUNC("(%p) %02x %02x %02x %02x %02x %02x\n", -+ pucStartAddr, -+ pucStartAddr[0], pucStartAddr[1], pucStartAddr[2], pucStartAddr[3], -+ pucStartAddr[4], pucStartAddr[5]); -+ break; -+ case 7: -+ LOG_FUNC("(%p) %02x %02x %02x %02x %02x %02x %02x\n", -+ pucStartAddr, -+ pucStartAddr[0], pucStartAddr[1], pucStartAddr[2], pucStartAddr[3], -+ pucStartAddr[4], pucStartAddr[5], pucStartAddr[6]); -+ break; -+ case 8: -+ LOG_FUNC("(%p) %02x %02x %02x %02x %02x %02x %02x %02x\n", -+ pucStartAddr, -+ pucStartAddr[0], pucStartAddr[1], pucStartAddr[2], pucStartAddr[3], -+ pucStartAddr[4], pucStartAddr[5], pucStartAddr[6], pucStartAddr[7]); -+ break; -+ case 9: -+ LOG_FUNC("(%p) %02x %02x %02x %02x %02x %02x %02x %02x - %02x\n", -+ pucStartAddr, -+ pucStartAddr[0], pucStartAddr[1], pucStartAddr[2], pucStartAddr[3], -+ pucStartAddr[4], pucStartAddr[5], pucStartAddr[6], pucStartAddr[7], -+ pucStartAddr[8]); -+ break; -+ case 10: -+ LOG_FUNC("(%p) %02x %02x %02x %02x %02x %02x %02x %02x - %02x %02x\n", -+ pucStartAddr, -+ pucStartAddr[0], pucStartAddr[1], pucStartAddr[2], pucStartAddr[3], -+ pucStartAddr[4], pucStartAddr[5], pucStartAddr[6], pucStartAddr[7], -+ pucStartAddr[8], pucStartAddr[9]); -+ break; -+ case 11: -+ LOG_FUNC("(%p) %02x %02x %02x %02x %02x %02x %02x %02x - %02x %02x %02x\n", -+ pucStartAddr, -+ pucStartAddr[0], pucStartAddr[1], pucStartAddr[2], pucStartAddr[3], -+ pucStartAddr[4], pucStartAddr[5], pucStartAddr[6], pucStartAddr[7], -+ pucStartAddr[8], pucStartAddr[9], pucStartAddr[10]); -+ break; -+ case 12: -+ LOG_FUNC("(%p) %02x %02x %02x %02x %02x %02x %02x %02x - %02x %02x %02x %02x\n", -+ pucStartAddr, -+ pucStartAddr[0], pucStartAddr[1], pucStartAddr[2], pucStartAddr[3], -+ pucStartAddr[4], pucStartAddr[5], pucStartAddr[6], pucStartAddr[7], -+ pucStartAddr[8], pucStartAddr[9], pucStartAddr[10], pucStartAddr[11]); -+ break; -+ case 13: -+ LOG_FUNC("(%p) %02x %02x %02x %02x %02x %02x %02x %02x - %02x %02x %02x %02x %02x\n", -+ pucStartAddr, -+ pucStartAddr[0], pucStartAddr[1], pucStartAddr[2], pucStartAddr[3], -+ pucStartAddr[4], pucStartAddr[5], pucStartAddr[6], pucStartAddr[7], -+ pucStartAddr[8], pucStartAddr[9], pucStartAddr[10], pucStartAddr[11], -+ pucStartAddr[12]); -+ break; -+ case 14: -+ LOG_FUNC("(%p) %02x %02x %02x %02x %02x %02x %02x %02x - %02x %02x %02x %02x %02x %02x\n", -+ pucStartAddr, pucStartAddr[0], pucStartAddr[1], pucStartAddr[2], pucStartAddr[3], -+ pucStartAddr[4], pucStartAddr[5], pucStartAddr[6], pucStartAddr[7], -+ pucStartAddr[8], pucStartAddr[9], pucStartAddr[10], pucStartAddr[11], -+ pucStartAddr[12], pucStartAddr[13]); -+ break; -+ case 15: -+ LOG_FUNC( -+ "(%p) %02x %02x %02x %02x %02x %02x %02x %02x - %02x %02x %02x %02x %02x %02x %02x\n", -+ pucStartAddr, pucStartAddr[0], pucStartAddr[1], pucStartAddr[2], pucStartAddr[3], -+ pucStartAddr[4], pucStartAddr[5], pucStartAddr[6], pucStartAddr[7], -+ pucStartAddr[8], pucStartAddr[9], pucStartAddr[10], pucStartAddr[11], -+ pucStartAddr[12], pucStartAddr[13], pucStartAddr[14]); -+ break; -+ /* -+ default: -+ break; -+ */ -+ } -+ u4Length = 0; -+ } -+ } -+ -+ LOG_FUNC("\n"); -+ -+} /* end of dumpMemory8() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to dump a segment of memory in double words. -+* -+* \param[in] pucStartAddr Pointer to the starting address of the memory to be dumped. -+* \param[in] u4Length Length of the memory to be dumped. -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID dumpMemory32(IN PUINT_32 pu4StartAddr, IN UINT_32 u4Length) -+{ -+ PUINT_8 pucAddr; -+ -+ ASSERT(pu4StartAddr); -+ -+ LOG_FUNC("DUMP32 ADDRESS: %p, Length: %u\n", pu4StartAddr, u4Length); -+ -+ if (IS_NOT_ALIGN_4((ULONG) pu4StartAddr)) { -+ UINT_32 u4ProtrudeLen = sizeof(UINT_32) - ((ULONG) pu4StartAddr % 4); -+ -+ u4ProtrudeLen = ((u4Length < u4ProtrudeLen) ? u4Length : u4ProtrudeLen); -+ LOG_FUNC("pu4StartAddr is not at DW boundary.\n"); -+ pucAddr = (PUINT_8) &pu4StartAddr[0]; -+ -+ switch (u4ProtrudeLen) { -+ case 1: -+ LOG_FUNC("(%p) %02x------\n", pu4StartAddr, pucAddr[0]); -+ break; -+ case 2: -+ LOG_FUNC("(%p) %02x%02x----\n", pu4StartAddr, pucAddr[1], pucAddr[0]); -+ break; -+ case 3: -+ LOG_FUNC("(%p) %02x%02x%02x--\n", pu4StartAddr, pucAddr[2], pucAddr[1], pucAddr[0]); -+ break; -+ default: -+ break; -+ } -+ -+ u4Length -= u4ProtrudeLen; -+ pu4StartAddr = (PUINT_32) ((ULONG) pu4StartAddr + u4ProtrudeLen); -+ } -+ -+ while (u4Length > 0) { -+ if (u4Length >= 16) { -+ LOG_FUNC("(%p) %08x %08x %08x %08x\n", -+ pu4StartAddr, pu4StartAddr[0], pu4StartAddr[1], pu4StartAddr[2], pu4StartAddr[3]); -+ pu4StartAddr += 4; -+ u4Length -= 16; -+ } else { -+ switch (u4Length) { -+ case 1: -+ pucAddr = (PUINT_8) &pu4StartAddr[0]; -+ LOG_FUNC("(%p) ------%02x\n", pu4StartAddr, pucAddr[0]); -+ break; -+ case 2: -+ pucAddr = (PUINT_8) &pu4StartAddr[0]; -+ LOG_FUNC("(%p) ----%02x%02x\n", pu4StartAddr, pucAddr[1], pucAddr[0]); -+ break; -+ case 3: -+ pucAddr = (PUINT_8) &pu4StartAddr[0]; -+ LOG_FUNC("(%p) --%02x%02x%02x\n", pu4StartAddr, pucAddr[2], pucAddr[1], pucAddr[0]); -+ break; -+ case 4: -+ LOG_FUNC("(%p) %08x\n", pu4StartAddr, pu4StartAddr[0]); -+ break; -+ case 5: -+ pucAddr = (PUINT_8) &pu4StartAddr[1]; -+ LOG_FUNC("(%p) %08x ------%02x\n", pu4StartAddr, pu4StartAddr[0], pucAddr[0]); -+ break; -+ case 6: -+ pucAddr = (PUINT_8) &pu4StartAddr[1]; -+ LOG_FUNC("(%p) %08x ----%02x%02x\n", -+ pu4StartAddr, pu4StartAddr[0], pucAddr[1], pucAddr[0]); -+ break; -+ case 7: -+ pucAddr = (PUINT_8) &pu4StartAddr[1]; -+ LOG_FUNC("(%p) %08x --%02x%02x%02x\n", -+ pu4StartAddr, pu4StartAddr[0], pucAddr[2], pucAddr[1], pucAddr[0]); -+ break; -+ case 8: -+ LOG_FUNC("(%p) %08x %08x\n", pu4StartAddr, pu4StartAddr[0], pu4StartAddr[1]); -+ break; -+ case 9: -+ pucAddr = (PUINT_8) &pu4StartAddr[2]; -+ LOG_FUNC("(%p) %08x %08x ------%02x\n", -+ pu4StartAddr, pu4StartAddr[0], pu4StartAddr[1], pucAddr[0]); -+ break; -+ case 10: -+ pucAddr = (PUINT_8) &pu4StartAddr[2]; -+ LOG_FUNC("(%p) %08x %08x ----%02x%02x\n", -+ pu4StartAddr, pu4StartAddr[0], pu4StartAddr[1], pucAddr[1], pucAddr[0]); -+ break; -+ case 11: -+ pucAddr = (PUINT_8) &pu4StartAddr[2]; -+ LOG_FUNC("(%p) %08x %08x --%02x%02x%02x\n", -+ pu4StartAddr, -+ pu4StartAddr[0], pu4StartAddr[1], pucAddr[2], pucAddr[1], pucAddr[0]); -+ break; -+ case 12: -+ LOG_FUNC("(%p) %08x %08x %08x\n", -+ pu4StartAddr, pu4StartAddr[0], pu4StartAddr[1], pu4StartAddr[2]); -+ break; -+ case 13: -+ pucAddr = (PUINT_8) &pu4StartAddr[3]; -+ LOG_FUNC("(%p) %08x %08x %08x ------%02x\n", -+ pu4StartAddr, pu4StartAddr[0], pu4StartAddr[1], pu4StartAddr[2], pucAddr[0]); -+ break; -+ case 14: -+ pucAddr = (PUINT_8) &pu4StartAddr[3]; -+ LOG_FUNC("(%p) %08x %08x %08x ----%02x%02x\n", -+ pu4StartAddr, -+ pu4StartAddr[0], pu4StartAddr[1], pu4StartAddr[2], pucAddr[1], pucAddr[0]); -+ break; -+ case 15: -+ pucAddr = (PUINT_8) &pu4StartAddr[3]; -+ LOG_FUNC("(%p) %08x %08x %08x --%02x%02x%02x\n", -+ pu4StartAddr, -+ pu4StartAddr[0], pu4StartAddr[1], pu4StartAddr[2], -+ pucAddr[2], pucAddr[1], pucAddr[0]); -+ break; -+ /* -+ default: -+ break; -+ */ -+ } -+ u4Length = 0; -+ } -+ } -+ -+} /* end of dumpMemory32() */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/common/wlan_bow.c b/drivers/misc/mediatek/connectivity/wlan/gen2/common/wlan_bow.c -new file mode 100644 -index 000000000000..21bd849827e1 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/common/wlan_bow.c -@@ -0,0 +1,3442 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/common/wlan_bow.c#1 -+*/ -+ -+/*! \file wlan_bow.c -+ \brief This file contains the 802.11 PAL commands processing routines for -+ MediaTek Inc. 802.11 Wireless LAN Adapters. -+*/ -+ -+/* -+** Log: wlan_bow.c -+ * -+ * 03 02 2012 terry.wu -+ * NULL -+ * Sync CFG80211 modification from branch 2,2. -+ * -+ * 01 16 2012 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Support BOW for 5GHz band. -+ * -+ * 01 09 2012 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * [ALPS00110632] [Rose][LCA42][Cross Feature][Bluetooth]The "KE" pops up after the device reboots automatically.(once) -+ * -+ * Fix bow link disconnected event dereference. -+ * -+ * 09 29 2011 cm.chang -+ * NULL -+ * Change the function prototype of rlmDomainGetChnlList() -+ * -+ * 07 06 2011 terry.wu -+ * [WCXRP00000735] [MT6620 Wi-Fi][BoW][FW/Driver] Protect BoW connection establishment -+ * Improve BoW connection establishment speed. -+ * -+ * 06 23 2011 cp.wu -+ * [WCXRP00000798] [MT6620 Wi-Fi][Firmware] Follow-ups for WAPI frequency offset workaround in firmware SCN module -+ * change parameter name from PeerAddr to BSSID -+ * -+ * 06 21 2011 terry.wu -+ * NULL -+ * Fix BoW KE. -+ * -+ * 06 20 2011 terry.wu -+ * NULL -+ * Add BoW Rate Limitation. -+ * -+ * 06 20 2011 cp.wu -+ * [WCXRP00000798] [MT6620 Wi-Fi][Firmware] Follow-ups for WAPI frequency offset workaround in firmware SCN module -+ * 1. specify target's BSSID when requesting channel privilege. -+ * 2. pass BSSID information to firmware domain -+ * -+ * 06 17 2011 terry.wu -+ * NULL -+ * Add BoW 11N support. -+ * -+ * 06 07 2011 cp.wu -+ * [WCXRP00000681] [MT5931][Firmware] HIF code size reduction -+ * aware more compile options. -+ * -+ * 05 25 2011 terry.wu -+ * [WCXRP00000735] [MT6620 Wi-Fi][BoW][FW/Driver] Protect BoW connection establishment -+ * Add BoW Cancel Scan Request and Turn On deactive network function. -+ * -+ * 05 23 2011 terry.wu -+ * [WCXRP00000735] [MT6620 Wi-Fi][BoW][FW/Driver] Protect BoW connection establishment -+ * Add some BoW error handling. -+ * -+ * 05 22 2011 terry.wu -+ * [WCXRP00000735] [MT6620 Wi-Fi][BoW][FW/Driver] Protect BoW connection establishment -+ * . -+ * -+ * 05 22 2011 terry.wu -+ * [WCXRP00000735] [MT6620 Wi-Fi][BoW][FW/Driver] Protect BoW connection establishment -+ * Only reply probe response to its peer or mached SSID for BoW AP. -+ * -+ * 05 22 2011 terry.wu -+ * [WCXRP00000735] [MT6620 Wi-Fi][BoW][FW/Driver] Protect BoW connection establishment -+ * Add BoW SAA retry and disable disconnect event when AAA fail . -+ * -+ * 05 21 2011 terry.wu -+ * [WCXRP00000735] [MT6620 Wi-Fi][BoW][FW/Driver] Protect BoW connection establishment -+ * Protect BoW connection establishment. -+ * -+ * 05 17 2011 terry.wu -+ * [WCXRP00000730] [MT6620 Wi-Fi][BoW] Send deauth while disconnecting -+ * Send deauth while disconnecting BoW link. -+ * -+ * 05 17 2011 terry.wu -+ * [WCXRP00000707] [MT6620 Wi-Fi][Driver] Fix BoW Multiple Physical Link connect/disconnect issue -+ * Fix wrong StaRec state of BoW . -+ * -+ * 05 06 2011 terry.wu -+ * [WCXRP00000707] [MT6620 Wi-Fi][Driver] Fix BoW Multiple Physical Link connect/disconnect issue -+ * Fix BoW Multiple Physical Link connect/disconnect issue. -+ * -+ * 05 03 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Use kalMemAlloc to allocate event buffer for kalIndicateBOWEvent. -+ * -+ * 04 15 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Fix prAssocRspSwRfb casting. -+ * -+ * 04 15 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Add BOW short range mode. -+ * -+ * 04 12 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Add WMM IE for BOW initiator data. -+ * -+ * 04 10 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Change Link disconnection event procedure for hotspot and change skb length check to 1514 bytes. -+ * -+ * 04 09 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Change Link connection event procedure and change skb length check to 1512 bytes. -+ * -+ * 03 28 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Simplify link disconnected routine, remove link disconnected other routine. -+ * -+ * 03 27 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Support multiple physical link. -+ * -+ * 03 27 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Add new feature - multiple physical link support. -+ * -+ * 02 22 2011 wh.su -+ * [WCXRP00000486] [MT6620 Wi-Fi][BOW] Fixed the bow send frame but not encrypted issue -+ * fixed the BOW packet sending without encrypted issue. -+ * -+ * 02 21 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Fix BOW link disconnection bug. -+ * -+ * 02 16 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Add bowNotifyAllLinkDisconnected interface and change channel grant procedure for bow starting. -+ * -+ * 02 11 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Update BOW channel granted function. -+ * -+ * 02 10 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Fix kernel API change issue. -+ * Before ALPS 2.2 (2.2 included), kfifo_alloc() is -+ * struct kfifo *kfifo_alloc(unsigned int size, gfp_t gfp_mask, spinlock_t *lock); -+ * After ALPS 2.3, kfifo_alloc() is changed to -+ * int kfifo_alloc(struct kfifo *fifo, unsigned int size, gfp_t gfp_mask); -+ * -+ * 02 09 2011 cp.wu -+ * [WCXRP00000430] [MT6620 Wi-Fi][Firmware][Driver] Create V1.2 branch for MT6620E1 and MT6620E3 -+ * create V1.2 driver branch based on label MT6620_WIFI_DRIVER_V1_2_110209_1031 -+ * with BOW and P2P enabled as default -+ * -+ * 02 08 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Replace kfifo_get and kfifo_put with kfifo_out and kfifo_in. -+ * Update BOW get MAC status, remove returning event for AIS network type. -+ * -+ * 01 26 2011 cm.chang -+ * [WCXRP00000395] [MT6620 Wi-Fi][Driver][FW] Search STA_REC with additional net type index argument -+ * . -+ * -+ * 01 11 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Update BOW Activity Report structure and bug fix. -+ * -+ * 01 10 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Update BOW to support multiple physical link. -+ * -+ * 12 08 2010 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Support concurrent networks. -+ * -+ * 12 07 2010 cm.chang -+ * [WCXRP00000239] MT6620 Wi-Fi][Driver][FW] Merge concurrent branch back to maintrunk -+ * 1. BSSINFO include RLM parameter -+ * 2. free all sta records when network is disconnected -+ * -+ * 11 11 2010 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Fix BoW timer assert issue. -+ * -+ * 10 18 2010 chinghwa.yu -+ * [WCXRP00000110] [MT6620 Wi-Fi] [Driver] Fix BoW Connected event size -+ * Fix for event returnning Band. -+ * -+ * 10 18 2010 chinghwa.yu -+ * [WCXRP00000110] [MT6620 Wi-Fi] [Driver] Fix BoW Connected event size -+ * Fix wrong BoW event size. -+ * -+ * 10 04 2010 cp.wu -+ * [WCXRP00000077] [MT6620 Wi-Fi][Driver][FW] Eliminate use of ENUM_NETWORK_TYPE_T and replaced -+ * by ENUM_NETWORK_TYPE_INDEX_T only remove ENUM_NETWORK_TYPE_T definitions -+ * -+ * 09 27 2010 chinghwa.yu -+ * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000065] Update BoW design and settings -+ * Update BCM/BoW design and settings. -+ * -+ * 09 16 2010 chinghwa.yu -+ * NULL -+ * Fix bowResponderScanDone error when prBssDesc is NULL. -+ * -+ * 09 14 2010 chinghwa.yu -+ * NULL -+ * Add bowRunEventAAAComplete. -+ * -+ * 09 14 2010 cp.wu -+ * NULL -+ * indicate correct AIS network information for PAL. -+ * -+ * 09 03 2010 kevin.huang -+ * NULL -+ * Refine #include sequence and solve recursive/nested #include issue -+ * -+ * 08 24 2010 cm.chang -+ * NULL -+ * Support RLM initail channel of Ad-hoc, P2P and BOW -+ * -+ * 08 24 2010 chinghwa.yu -+ * NULL -+ * Initialize nicActivateNetwork(prAdapter as soon as bow is starting.. -+ * -+ * 08 24 2010 chinghwa.yu -+ * NULL -+ * Update BOW for the 1st time. -+ * -+ * 08 23 2010 cp.wu -+ * NULL -+ * revise constant definitions to be matched with implementation (original cmd-event definition is deprecated) -+ * -+ * 07 30 2010 cp.wu -+ * NULL -+ * 1) BoW wrapper: use definitions instead of hard-coded constant for error code -+ * 2) AIS-FSM: eliminate use of desired RF parameters, use prTargetBssDesc instead -+ * 3) add handling for RX_PKT_DESTINATION_HOST_WITH_FORWARD for GO-broadcast frames -+ * -+ * 07 15 2010 cp.wu -+ * -+ * sync. bluetooth-over-Wi-Fi interface to driver interface document v0.2.6. -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 25 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add API in que_mgt to retrieve sta-rec index for security frames. -+ * -+ * 06 24 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 802.1x and bluetooth-over-Wi-Fi security frames are now delievered to firmware via command path instead of data path. -+ * -+ * 06 11 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) migrate assoc.c. -+ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness -+ * 3) add configuration options for CNM_MEM and RSN modules -+ * 4) add data path for management frames -+ * 5) eliminate rPacketInfo of MSDU_INFO_T -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 05 17 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * 1) add timeout handler mechanism for pending command packets -+ * 2) add p2p add/removal key -+ * -+ * 05 13 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * add NULL OID implementation for WOL-related OIDs. -+ * -+ * 05 13 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * 1) all BT physical handles shares the same RSSI/Link Quality. -+ * 2) simplify BT command composing -+ * -+ * 04 28 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * change prefix for data structure used to communicate with 802.11 PAL -+ * to avoid ambiguous naming with firmware interface -+ * -+ * 04 27 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * add multiple physical link support -+ * -+ * 04 14 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * information buffer for query oid/ioctl is now buffered in prCmdInfo -+ * instead of glue-layer variable to improve multiple oid/ioctl capability -+ * -+ * 04 13 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * add framework for BT-over-Wi-Fi support. -+ * * 1) prPendingCmdInfo is replaced by queue for multiple handler capability -+ * * 2) command sequence number is now increased atomically -+ * * 3) private data could be hold and taken use for other purpose -+** -+*/ -+ -+/****************************************************************************** -+* C O M P I L E R F L A G S -+******************************************************************************* -+*/ -+ -+/****************************************************************************** -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************* -+*/ -+#include "precomp.h" -+ -+#if CFG_ENABLE_BT_OVER_WIFI -+ -+/****************************************************************************** -+* C O N S T A N T S -+******************************************************************************* -+*/ -+ -+/****************************************************************************** -+* D A T A T Y P E S -+******************************************************************************* -+*/ -+ -+/****************************************************************************** -+* P U B L I C D A T A -+******************************************************************************* -+*/ -+ -+static UINT_32 g_u4LinkCount; -+static UINT_32 g_u4Beaconing; -+static BOW_TABLE_T arBowTable[CFG_BOW_PHYSICAL_LINK_NUM]; -+ -+/****************************************************************************** -+* P R I V A T E D A T A -+******************************************************************************* -+*/ -+ -+const BOW_CMD_T arBowCmdTable[] = { -+ {BOW_CMD_ID_GET_MAC_STATUS, bowCmdGetMacStatus}, -+ {BOW_CMD_ID_SETUP_CONNECTION, bowCmdSetupConnection}, -+ {BOW_CMD_ID_DESTROY_CONNECTION, bowCmdDestroyConnection}, -+ {BOW_CMD_ID_SET_PTK, bowCmdSetPTK}, -+ {BOW_CMD_ID_READ_RSSI, bowCmdReadRSSI}, -+ {BOW_CMD_ID_READ_LINK_QUALITY, bowCmdReadLinkQuality}, -+ {BOW_CMD_ID_SHORT_RANGE_MODE, bowCmdShortRangeMode}, -+ {BOW_CMD_ID_GET_CHANNEL_LIST, bowCmdGetChannelList}, -+}; -+ -+/****************************************************************************** -+* M A C R O S -+******************************************************************************* -+*/ -+ -+/****************************************************************************** -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************* -+*/ -+ -+/****************************************************************************** -+* F U N C T I O N S -+******************************************************************************* -+*/ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief command packet generation utility -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] ucCID Command ID -+* \param[in] fgSetQuery Set or Query -+* \param[in] fgNeedResp Need for response -+* \param[in] pfCmdDoneHandler Function pointer when command is done -+* \param[in] u4SetQueryInfoLen The length of the set/query buffer -+* \param[in] pucInfoBuffer Pointer to set/query buffer -+* -+* -+* \retval WLAN_STATUS_PENDING -+* \retval WLAN_STATUS_FAILURE -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSendSetQueryBowCmd(IN P_ADAPTER_T prAdapter, -+ IN UINT_8 ucCID, -+ IN BOOLEAN fgSetQuery, -+ IN BOOLEAN fgNeedResp, -+ IN PFN_CMD_DONE_HANDLER pfCmdDoneHandler, -+ IN PFN_CMD_TIMEOUT_HANDLER pfCmdTimeoutHandler, -+ IN UINT_32 u4SetQueryInfoLen, IN PUINT_8 pucInfoBuffer, IN UINT_8 ucSeqNumber) -+{ -+ P_GLUE_INFO_T prGlueInfo; -+ P_CMD_INFO_T prCmdInfo; -+ P_WIFI_CMD_T prWifiCmd; -+ UINT_8 ucCmdSeqNum; -+ -+ ASSERT(prAdapter); -+ -+ prGlueInfo = prAdapter->prGlueInfo; -+ ASSERT(prGlueInfo); -+ -+ DBGLOG(REQ, TRACE, "Command ID = 0x%08X\n", ucCID); -+ -+ prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, (CMD_HDR_SIZE + u4SetQueryInfoLen)); -+ -+ if (!prCmdInfo) { -+ DBGLOG(INIT, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); -+ return WLAN_STATUS_FAILURE; -+ } -+ /* increase command sequence number */ -+ ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter); -+ DBGLOG(REQ, TRACE, "ucCmdSeqNum =%d\n", ucCmdSeqNum); -+ -+ /* Setup common CMD Info Packet */ -+ prCmdInfo->eCmdType = COMMAND_TYPE_NETWORK_IOCTL; -+ prCmdInfo->eNetworkType = NETWORK_TYPE_BOW_INDEX; -+ prCmdInfo->u2InfoBufLen = (UINT_16) (CMD_HDR_SIZE + u4SetQueryInfoLen); -+ prCmdInfo->pfCmdDoneHandler = pfCmdDoneHandler; -+ prCmdInfo->pfCmdTimeoutHandler = pfCmdTimeoutHandler; -+ prCmdInfo->fgIsOid = FALSE; -+ prCmdInfo->ucCID = ucCID; -+ prCmdInfo->fgSetQuery = fgSetQuery; -+ prCmdInfo->fgNeedResp = fgNeedResp; -+ prCmdInfo->fgDriverDomainMCR = FALSE; -+ prCmdInfo->ucCmdSeqNum = ucCmdSeqNum; -+ prCmdInfo->u4SetInfoLen = u4SetQueryInfoLen; -+ prCmdInfo->pvInformationBuffer = NULL; -+ prCmdInfo->u4InformationBufferLength = 0; -+ prCmdInfo->u4PrivateData = (UINT_32) ucSeqNumber; -+ -+ /* Setup WIFI_CMD_T (no payload) */ -+ prWifiCmd = (P_WIFI_CMD_T) (prCmdInfo->pucInfoBuffer); -+ prWifiCmd->u2TxByteCount_UserPriority = prCmdInfo->u2InfoBufLen; -+ prWifiCmd->ucCID = prCmdInfo->ucCID; -+ prWifiCmd->ucSetQuery = prCmdInfo->fgSetQuery; -+ prWifiCmd->ucSeqNum = prCmdInfo->ucCmdSeqNum; -+ -+ if (u4SetQueryInfoLen > 0 && pucInfoBuffer != NULL) -+ kalMemCopy(prWifiCmd->aucBuffer, pucInfoBuffer, u4SetQueryInfoLen); -+ /* insert into prCmdQueue */ -+ kalEnqueueCommand(prGlueInfo, (P_QUE_ENTRY_T) prCmdInfo); -+ -+ /* wakeup txServiceThread later */ -+ GLUE_SET_EVENT(prGlueInfo); -+ return WLAN_STATUS_PENDING; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to dispatch command coming from 802.11 PAL -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] prCmd Pointer to the buffer that holds the command -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS wlanbowHandleCommand(IN P_ADAPTER_T prAdapter, IN P_AMPC_COMMAND prCmd) -+{ -+ WLAN_STATUS retval = WLAN_STATUS_FAILURE; -+ UINT_16 i; -+ -+ ASSERT(prAdapter); -+ -+ for (i = 0; i < sizeof(arBowCmdTable) / sizeof(BOW_CMD_T); i++) { -+ if ((arBowCmdTable[i].uCmdID == prCmd->rHeader.ucCommandId) && arBowCmdTable[i].pfCmdHandle) { -+ retval = arBowCmdTable[i].pfCmdHandle(prAdapter, prCmd); -+ break; -+ } -+ } -+ -+ return retval; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This is command handler for BOW_CMD_ID_GET_MAC_STATUS -+* coming from 802.11 PAL -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] prCmd Pointer to the buffer that holds the command -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS bowCmdGetMacStatus(IN P_ADAPTER_T prAdapter, IN P_AMPC_COMMAND prCmd) -+{ -+ P_AMPC_EVENT prEvent; -+ P_BOW_MAC_STATUS prMacStatus; -+ UINT_8 idx = 0; -+ UINT_8 ucPrimaryChannel; -+ ENUM_BAND_T eBand; -+ ENUM_CHNL_EXT_T eBssSCO; -+ UINT_8 ucNumOfChannel = 0; /* MAX_BOW_NUMBER_OF_CHANNEL; */ -+ -+ RF_CHANNEL_INFO_T aucChannelList[MAX_BOW_NUMBER_OF_CHANNEL]; -+ -+ ASSERT(prAdapter); -+ -+ /* 3 <1> If LinkCount != 0 -> OK (optional) */ -+ -+ eBand = BAND_2G4; -+ eBssSCO = CHNL_EXT_SCN; -+ -+ /* fill event header */ -+ prEvent = (P_AMPC_EVENT) kalMemAlloc((sizeof(AMPC_EVENT) + sizeof(BOW_MAC_STATUS)), VIR_MEM_TYPE); -+ if (!prEvent) { -+ ASSERT(FALSE); -+ return WLAN_STATUS_FAILURE; -+ } -+ prEvent->rHeader.ucEventId = BOW_EVENT_ID_MAC_STATUS; -+ prEvent->rHeader.ucSeqNumber = prCmd->rHeader.ucSeqNumber; -+ prEvent->rHeader.u2PayloadLength = sizeof(BOW_MAC_STATUS); -+ -+ /* fill event body */ -+ prMacStatus = (P_BOW_MAC_STATUS) (prEvent->aucPayload); -+ kalMemZero(prMacStatus, sizeof(BOW_MAC_STATUS)); -+ -+ /* 3 <2> Call CNM to decide if BOW available. */ -+ if (cnmBowIsPermitted(prAdapter)) -+ prMacStatus->ucAvailability = TRUE; -+ else -+ prMacStatus->ucAvailability = FALSE; -+ -+ memcpy(prMacStatus->aucMacAddr, prAdapter->rWifiVar.aucDeviceAddress, PARAM_MAC_ADDR_LEN); -+ -+ if (cnmPreferredChannel(prAdapter, &eBand, &ucPrimaryChannel, &eBssSCO)) { -+#if CFG_BOW_TEST -+ DBGLOG(BOW, TRACE, "bowCmdGetMacStatus, Get preferred channel.\n"); -+#endif -+ -+ prMacStatus->ucNumOfChannel = 1; -+ prMacStatus->arChannelList[0].ucChannelBand = eBand; -+ prMacStatus->arChannelList[0].ucChannelNum = ucPrimaryChannel; -+ } else { -+#if CFG_BOW_TEST -+ DBGLOG(BOW, TRACE, -+ "bowCmdGetMacStatus, Get channel list. Current number of channel, %d.\n", ucNumOfChannel); -+#endif -+ -+ rlmDomainGetChnlList(prAdapter, BAND_2G4, FALSE, MAX_BOW_NUMBER_OF_CHANNEL_2G4, -+ &ucNumOfChannel, aucChannelList); -+ -+ if (ucNumOfChannel > 0) { -+ for (idx = 0; idx < ucNumOfChannel; idx++) { -+ prMacStatus->arChannelList[idx].ucChannelBand = aucChannelList[idx].eBand; -+ prMacStatus->arChannelList[idx].ucChannelNum = aucChannelList[idx].ucChannelNum; -+ } -+ -+ prMacStatus->ucNumOfChannel = ucNumOfChannel; -+ } -+ -+ rlmDomainGetChnlList(prAdapter, BAND_5G, FALSE, MAX_BOW_NUMBER_OF_CHANNEL_5G, -+ &ucNumOfChannel, aucChannelList); -+ -+ if (ucNumOfChannel > 0) { -+ for (idx = 0; idx < ucNumOfChannel; idx++) { -+ prMacStatus->arChannelList[prMacStatus->ucNumOfChannel + idx].ucChannelBand = -+ aucChannelList[idx].eBand; -+ prMacStatus->arChannelList[prMacStatus->ucNumOfChannel + idx].ucChannelNum = -+ aucChannelList[idx].ucChannelNum; -+ } -+ -+ prMacStatus->ucNumOfChannel = prMacStatus->ucNumOfChannel + ucNumOfChannel; -+ -+ } -+ } -+ -+#if CFG_BOW_TEST -+ DBGLOG(BOW, TRACE, -+ "ucNumOfChannel,eBand,aucChannelList,%x,%x,%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x.\n", -+ ucNumOfChannel, aucChannelList[0].eBand, aucChannelList[0].ucChannelNum, aucChannelList[1].ucChannelNum, -+ aucChannelList[2].ucChannelNum, aucChannelList[3].ucChannelNum, aucChannelList[4].ucChannelNum, -+ aucChannelList[5].ucChannelNum, aucChannelList[6].ucChannelNum, aucChannelList[7].ucChannelNum, -+ aucChannelList[8].ucChannelNum, aucChannelList[9].ucChannelNum, aucChannelList[10].ucChannelNum, -+ aucChannelList[11].ucChannelNum, aucChannelList[12].ucChannelNum, aucChannelList[13].ucChannelNum, -+ aucChannelList[14].ucChannelNum, aucChannelList[15].ucChannelNum, aucChannelList[16].ucChannelNum, -+ aucChannelList[17].ucChannelNum)); -+ -+ DBGLOG(BOW, TRACE, -+ "prMacStatus->ucNumOfChannel, eBand, %x, %x.\n", -+ prMacStatus->ucNumOfChannel, prMacStatus->arChannelList[0].ucChannelBand); -+ DBGLOG(BOW, TRACE, -+ "prMacStatus->arChannelList, %x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x.\n", -+ prMacStatus->arChannelList[0].ucChannelNum, prMacStatus->arChannelList[1].ucChannelNum, -+ prMacStatus->arChannelList[2].ucChannelNum, prMacStatus->arChannelList[3].ucChannelNum, -+ prMacStatus->arChannelList[4].ucChannelNum, prMacStatus->arChannelList[5].ucChannelNum, -+ prMacStatus->arChannelList[6].ucChannelNum, prMacStatus->arChannelList[7].ucChannelNum, -+ prMacStatus->arChannelList[8].ucChannelNum, prMacStatus->arChannelList[9].ucChannelNum, -+ prMacStatus->arChannelList[10].ucChannelNum, prMacStatus->arChannelList[11].ucChannelNum, -+ prMacStatus->arChannelList[12].ucChannelNum, prMacStatus->arChannelList[13].ucChannelNum, -+ prMacStatus->arChannelList[14].ucChannelNum, prMacStatus->arChannelList[15].ucChannelNum, -+ prMacStatus->arChannelList[16].ucChannelNum, prMacStatus->arChannelList[17].ucChannelNum)); -+ -+ DBGLOG(BOW, TRACE, "prMacStatus->ucNumOfChannel, %x.\n", prMacStatus->ucNumOfChannel); -+ DBGLOG(BOW, TRACE, -+ "prMacStatus->arChannelList[0].ucChannelBand, %x.\n", prMacStatus->arChannelList[0].ucChannelBand); -+ DBGLOG(BOW, TRACE, -+ "prMacStatus->arChannelList[0].ucChannelNum, %x.\n", prMacStatus->arChannelList[0].ucChannelNum); -+ DBGLOG(BOW, TRACE, "prMacStatus->ucAvailability, %x.\n", prMacStatus->ucAvailability); -+ DBGLOG(BOW, TRACE, "prMacStatus->aucMacAddr, %x:%x:%x:%x:%x:%x.\n", -+ prMacStatus->aucMacAddr[0], -+ prMacStatus->aucMacAddr[1], -+ prMacStatus->aucMacAddr[2], -+ prMacStatus->aucMacAddr[3], prMacStatus->aucMacAddr[4], prMacStatus->aucMacAddr[5])); -+#endif -+ -+ kalIndicateBOWEvent(prAdapter->prGlueInfo, prEvent); -+ -+ kalMemFree(prEvent, VIR_MEM_TYPE, (sizeof(AMPC_EVENT) + sizeof(BOW_MAC_STATUS))); -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This is command handler for BOW_CMD_ID_SETUP_CONNECTION -+* coming from 802.11 PAL -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] prCmd Pointer to the buffer that holds the command -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS bowCmdSetupConnection(IN P_ADAPTER_T prAdapter, IN P_AMPC_COMMAND prCmd) -+{ -+ P_BOW_SETUP_CONNECTION prBowSetupConnection; -+ CMD_BT_OVER_WIFI rCmdBtOverWifi; -+ P_BOW_FSM_INFO_T prBowFsmInfo; -+ BOW_TABLE_T rBowTable; -+ -+ UINT_8 ucBowTableIdx = 0; -+ -+ ASSERT(prAdapter); -+ -+ prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); -+ prBowSetupConnection = (P_BOW_SETUP_CONNECTION) &(prCmd->aucPayload[0]); -+ -+ /* parameter size check */ -+ if (prCmd->rHeader.u2PayloadLength != sizeof(BOW_SETUP_CONNECTION)) { -+ wlanbowCmdEventSetStatus(prAdapter, prCmd, BOWCMD_STATUS_INVALID); -+ return WLAN_STATUS_INVALID_LENGTH; -+ } -+ /* 3 <1> If ucLinkCount >= 4 -> Fail. */ -+ if (g_u4LinkCount >= CFG_BOW_PHYSICAL_LINK_NUM) { -+ wlanbowCmdEventSetStatus(prAdapter, prCmd, BOWCMD_STATUS_UNACCEPTED); -+ return WLAN_STATUS_NOT_ACCEPTED; -+ } -+ /* 3 <2> Call CNM, check if BOW is available. */ -+ if (!cnmBowIsPermitted(prAdapter)) { -+ wlanbowCmdEventSetStatus(prAdapter, prCmd, BOWCMD_STATUS_UNACCEPTED); -+ return WLAN_STATUS_NOT_ACCEPTED; -+ } -+ /* 3 <3> Lookup BOW Table, if Peer MAC address exist and valid -> Fail. */ -+ if (bowCheckBowTableIfVaild(prAdapter, prBowSetupConnection->aucPeerAddress)) { -+ wlanbowCmdEventSetStatus(prAdapter, prCmd, BOWCMD_STATUS_UNACCEPTED); -+ return WLAN_STATUS_NOT_ACCEPTED; -+ } -+ -+ if (EQUAL_MAC_ADDR(prBowSetupConnection->aucPeerAddress, prAdapter->rWifiVar.aucDeviceAddress)) { -+ wlanbowCmdEventSetStatus(prAdapter, prCmd, BOWCMD_STATUS_INVALID); -+ return WLAN_STATUS_NOT_ACCEPTED; -+ } -+ /* fill CMD_BT_OVER_WIFI */ -+ rCmdBtOverWifi.ucAction = BOW_SETUP_CMD; -+ rCmdBtOverWifi.ucChannelNum = prBowSetupConnection->ucChannelNum; -+ COPY_MAC_ADDR(rCmdBtOverWifi.rPeerAddr, prBowSetupConnection->aucPeerAddress); -+ rCmdBtOverWifi.u2BeaconInterval = prBowSetupConnection->u2BeaconInterval; -+ rCmdBtOverWifi.ucTimeoutDiscovery = prBowSetupConnection->ucTimeoutDiscovery; -+ rCmdBtOverWifi.ucTimeoutInactivity = prBowSetupConnection->ucTimeoutInactivity; -+ rCmdBtOverWifi.ucRole = prBowSetupConnection->ucRole; -+ rCmdBtOverWifi.PAL_Capabilities = prBowSetupConnection->ucPAL_Capabilities; -+ rCmdBtOverWifi.cMaxTxPower = prBowSetupConnection->cMaxTxPower; -+ -+ if (prBowSetupConnection->ucChannelNum > 14) -+ rCmdBtOverWifi.ucChannelBand = BAND_5G; -+ else -+ rCmdBtOverWifi.ucChannelBand = BAND_2G4; -+ -+ COPY_MAC_ADDR(prBowFsmInfo->aucPeerAddress, prBowSetupConnection->aucPeerAddress); -+ -+#if CFG_BOW_PHYSICAL_LINK_NUM > 1 -+ /*Channel check for supporting multiple physical link */ -+ if (g_u4LinkCount > 0) { -+ if (prBowSetupConnection->ucChannelNum != prBowFsmInfo->ucPrimaryChannel) { -+ wlanbowCmdEventSetStatus(prAdapter, prCmd, BOWCMD_STATUS_UNACCEPTED); -+ return WLAN_STATUS_NOT_ACCEPTED; -+ } -+ } -+#endif -+ -+ prBowFsmInfo->ucPrimaryChannel = prBowSetupConnection->ucChannelNum; -+ prBowFsmInfo->eBand = rCmdBtOverWifi.ucChannelBand; -+ prBowFsmInfo->u2BeaconInterval = prBowSetupConnection->u2BeaconInterval; -+ prBowFsmInfo->ucRole = prBowSetupConnection->ucRole; -+ -+ if (prBowSetupConnection->ucPAL_Capabilities > 0) -+ prBowFsmInfo->fgSupportQoS = TRUE; -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "bowCmdSetupConnection.\n"); -+ DBGLOG(BOW, EVENT, "rCmdBtOverWifi Channel Number - 0x%x.\n", rCmdBtOverWifi.ucChannelNum); -+ DBGLOG(BOW, EVENT, "rCmdBtOverWifi Peer address - %x:%x:%x:%x:%x:%x.\n", rCmdBtOverWifi.rPeerAddr[0], -+ rCmdBtOverWifi.rPeerAddr[1], -+ rCmdBtOverWifi.rPeerAddr[2], -+ rCmdBtOverWifi.rPeerAddr[3], rCmdBtOverWifi.rPeerAddr[4], rCmdBtOverWifi.rPeerAddr[5]); -+ DBGLOG(BOW, EVENT, "rCmdBtOverWifi Beacon interval - 0x%x.\n", rCmdBtOverWifi.u2BeaconInterval); -+ DBGLOG(BOW, EVENT, "rCmdBtOverWifi Timeout activity - 0x%x.\n", rCmdBtOverWifi.ucTimeoutDiscovery); -+ DBGLOG(BOW, EVENT, "rCmdBtOverWifi Timeout inactivity - 0x%x.\n", rCmdBtOverWifi.ucTimeoutInactivity); -+ DBGLOG(BOW, EVENT, "rCmdBtOverWifi Role - 0x%x.\n", rCmdBtOverWifi.ucRole); -+ DBGLOG(BOW, EVENT, "rCmdBtOverWifi PAL capability - 0x%x.\n", rCmdBtOverWifi.PAL_Capabilities); -+ DBGLOG(BOW, EVENT, "rCmdBtOverWifi Max Tx power - 0x%x.\n", rCmdBtOverWifi.cMaxTxPower); -+#endif -+ -+ /* 3 <4> Get a free BOW entry, mark as Valid, fill in Peer MAC address, LinkCount += 1, state == Starting. */ -+ if (!bowGetBowTableFreeEntry(prAdapter, &ucBowTableIdx)) { -+ wlanbowCmdEventSetStatus(prAdapter, prCmd, BOWCMD_STATUS_UNACCEPTED); -+ return WLAN_STATUS_NOT_ACCEPTED; -+ } -+ -+ prBowFsmInfo->prTargetBssDesc = NULL; -+ -+ kalMemZero(&rBowTable, sizeof(BOW_TABLE_T)); -+ -+ COPY_MAC_ADDR(rBowTable.aucPeerAddress, prBowSetupConnection->aucPeerAddress); -+ /* owTable.eState = BOW_DEVICE_STATE_ACQUIRING_CHANNEL; */ -+ rBowTable.fgIsValid = TRUE; -+ rBowTable.ucAcquireID = prBowFsmInfo->ucSeqNumOfChReq; -+ /* rBowTable.ucRole = prBowSetupConnection->ucRole; */ -+ /* rBowTable.ucChannelNum = prBowSetupConnection->ucChannelNum; */ -+ bowSetBowTableContent(prAdapter, ucBowTableIdx, &rBowTable); -+ -+ kalSetBowRole(prAdapter->prGlueInfo, rCmdBtOverWifi.ucRole, prBowSetupConnection->aucPeerAddress); -+ -+ GLUE_INC_REF_CNT(g_u4LinkCount); -+ -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "bowStarting, g_u4LinkCount, %x.\n", g_u4LinkCount); -+#endif -+ -+ if (g_u4LinkCount == 1) { -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "bowStarting, cnmTimerInitTimer.\n"); -+ DBGLOG(BOW, EVENT, "prBowFsmInfo->u2BeaconInterval, %d.\n", prBowFsmInfo->u2BeaconInterval); -+#endif -+ cnmTimerInitTimer(prAdapter, -+ &prBowFsmInfo->rStartingBeaconTimer, -+ (PFN_MGMT_TIMEOUT_FUNC) bowSendBeacon, (ULONG) NULL); -+ -+ cnmTimerInitTimer(prAdapter, -+ &prBowFsmInfo->rChGrantedTimer, -+ (PFN_MGMT_TIMEOUT_FUNC) bowChGrantedTimeout, (ULONG) NULL); -+ -+ /* Reset Global Variable */ -+ g_u4Beaconing = 0; -+ -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "bowCmdSetupConnection, g_u4LinkCount, %x.\n", g_u4LinkCount); -+ DBGLOG(BOW, EVENT, "kalInitBowDevice, bow0\n"); -+#endif -+#if CFG_BOW_SEPARATE_DATA_PATH -+ kalInitBowDevice(prAdapter->prGlueInfo, BOWDEVNAME); -+#endif -+ -+ /*Active BoW Network */ -+ SET_NET_ACTIVE(prAdapter, NETWORK_TYPE_BOW_INDEX); -+ SET_NET_PWR_STATE_ACTIVE(prAdapter, NETWORK_TYPE_BOW_INDEX); -+ nicActivateNetwork(prAdapter, NETWORK_TYPE_BOW_INDEX); -+ -+ } -+ -+ if (rCmdBtOverWifi.ucRole == BOW_INITIATOR) { -+ bowSetBowTableState(prAdapter, prBowSetupConnection->aucPeerAddress, -+ BOW_DEVICE_STATE_ACQUIRING_CHANNEL); -+ bowRequestCh(prAdapter); -+ } else { -+ bowSetBowTableState(prAdapter, prBowSetupConnection->aucPeerAddress, BOW_DEVICE_STATE_SCANNING); -+ bowResponderScan(prAdapter); -+ } -+ -+ wlanbowCmdEventSetStatus(prAdapter, prCmd, BOWCMD_STATUS_SUCCESS); -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This is command handler for BOW_CMD_ID_DESTROY_CONNECTION -+* coming from 802.11 PAL -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] prCmd Pointer to the buffer that holds the command -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS bowCmdDestroyConnection(IN P_ADAPTER_T prAdapter, IN P_AMPC_COMMAND prCmd) -+{ -+ P_BOW_DESTROY_CONNECTION prBowDestroyConnection; -+ CMD_BT_OVER_WIFI rCmdBtOverWifi; -+ P_BOW_FSM_INFO_T prBowFsmInfo; -+#if CFG_BOW_TEST -+ UINT_8 ucIdx; -+#endif -+ -+ ASSERT(prAdapter); -+ -+ prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); -+ -+ /* 3 <1> If LinkCount == 0 ->Fail (Optional) */ -+ if (g_u4LinkCount == 0) { -+ wlanbowCmdEventSetStatus(prAdapter, prCmd, BOWCMD_STATUS_UNACCEPTED); -+ return WLAN_STATUS_NOT_ACCEPTED; -+ } -+ /* parameter size check */ -+ if (prCmd->rHeader.u2PayloadLength != sizeof(BOW_DESTROY_CONNECTION)) { -+ wlanbowCmdEventSetStatus(prAdapter, prCmd, BOWCMD_STATUS_UNACCEPTED); -+ return WLAN_STATUS_INVALID_LENGTH; -+ } -+ /* 3 <2> Lookup BOW table, check if is not exist (Valid and Peer MAC address) -> Fail */ -+ prBowDestroyConnection = (P_BOW_DESTROY_CONNECTION) &(prCmd->aucPayload[0]); -+ -+ if (!bowCheckBowTableIfVaild(prAdapter, prBowDestroyConnection->aucPeerAddress)) { -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "bowCmdDestroyConnection, bowCheckIfVaild, not accepted.\n"); -+#endif -+ return WLAN_STATUS_NOT_ACCEPTED; -+ } -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, -+ "bowCmdDestroyConnection, destroy Peer address - %x:%x:%x:%x:%x:%x.\n", -+ prBowDestroyConnection->aucPeerAddress[0], prBowDestroyConnection->aucPeerAddress[1], -+ prBowDestroyConnection->aucPeerAddress[2], prBowDestroyConnection->aucPeerAddress[3], -+ prBowDestroyConnection->aucPeerAddress[4], prBowDestroyConnection->aucPeerAddress[5])); -+#endif -+ -+ /* fill CMD_BT_OVER_WIFI */ -+ rCmdBtOverWifi.ucAction = 2; -+ COPY_MAC_ADDR(rCmdBtOverWifi.rPeerAddr, prBowDestroyConnection->aucPeerAddress); -+ COPY_MAC_ADDR(prBowFsmInfo->aucPeerAddress, prBowDestroyConnection->aucPeerAddress); -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, -+ "bowCmdDestroyConnection, rCmdBtOverWifi.rPeerAddr - %x:%x:%x:%x:%x:%x.\n", rCmdBtOverWifi.rPeerAddr[0], -+ rCmdBtOverWifi.rPeerAddr[1], rCmdBtOverWifi.rPeerAddr[2], rCmdBtOverWifi.rPeerAddr[3], -+ rCmdBtOverWifi.rPeerAddr[4], rCmdBtOverWifi.rPeerAddr[5]); -+#endif -+ -+#if CFG_BOW_TEST -+ for (ucIdx = 0; ucIdx < 11; ucIdx++) { -+ DBGLOG(BOW, EVENT, -+ "BoW receiving PAL packet delta time vs packet number -- %d ms vs %x.\n", ucIdx, -+ g_arBowRevPalPacketTime[ucIdx]); -+ } -+#endif -+ -+ wlanbowCmdEventSetStatus(prAdapter, prCmd, BOWCMD_STATUS_SUCCESS); -+ -+ return wlanoidSendSetQueryBowCmd(prAdapter, -+ CMD_ID_CMD_BT_OVER_WIFI, -+ TRUE, -+ FALSE, -+ wlanbowCmdEventLinkDisconnected, -+ wlanbowCmdTimeoutHandler, -+ sizeof(CMD_BT_OVER_WIFI), -+ (PUINT_8)&rCmdBtOverWifi, prCmd->rHeader.ucSeqNumber); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This is command handler for BOW_CMD_ID_SET_PTK -+* coming from 802.11 PAL -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] prCmd Pointer to the buffer that holds the command -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS bowCmdSetPTK(IN P_ADAPTER_T prAdapter, IN P_AMPC_COMMAND prCmd) -+{ -+ P_BOW_SET_PTK prBowSetPTK; -+ CMD_802_11_KEY rCmdKey; -+ -+ ASSERT(prAdapter); -+ -+ /* parameter size check */ -+ if (prCmd->rHeader.u2PayloadLength != sizeof(BOW_SET_PTK)) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ prBowSetPTK = (P_BOW_SET_PTK) &(prCmd->aucPayload[0]); -+ -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "prBowSetPTK->aucPeerAddress, %x:%x:%x:%x:%x:%x.\n", -+ prBowSetPTK->aucPeerAddress[0], -+ prBowSetPTK->aucPeerAddress[1], -+ prBowSetPTK->aucPeerAddress[2], -+ prBowSetPTK->aucPeerAddress[3], -+ prBowSetPTK->aucPeerAddress[4], prBowSetPTK->aucPeerAddress[5])); -+ -+ DBGLOG(BOW, EVENT, -+ "rCmdKey.ucIsAuthenticator, %x.\n", kalGetBowRole(prAdapter->prGlueInfo, prBowSetPTK->aucPeerAddress)); -+#endif -+ -+ if (!bowCheckBowTableIfVaild(prAdapter, prBowSetPTK->aucPeerAddress)) { -+ wlanbowCmdEventSetStatus(prAdapter, prCmd, BOWCMD_STATUS_UNACCEPTED); -+ -+ return WLAN_STATUS_NOT_ACCEPTED; -+ } -+ -+ if (bowGetBowTableState(prAdapter, prBowSetPTK->aucPeerAddress) != BOW_DEVICE_STATE_CONNECTED) { -+ wlanbowCmdEventSetStatus(prAdapter, prCmd, BOWCMD_STATUS_FAILURE); -+ -+ return WLAN_STATUS_NOT_ACCEPTED; -+ } -+ /* fill CMD_802_11_KEY */ -+ rCmdKey.ucAddRemove = 1; /* add */ -+ rCmdKey.ucTxKey = 1; -+ rCmdKey.ucKeyType = 1; -+ rCmdKey.ucIsAuthenticator = kalGetBowRole(prAdapter->prGlueInfo, prBowSetPTK->aucPeerAddress); -+ COPY_MAC_ADDR(rCmdKey.aucPeerAddr, prBowSetPTK->aucPeerAddress); -+ rCmdKey.ucNetType = NETWORK_TYPE_BOW_INDEX; /* BT Over Wi-Fi */ -+ rCmdKey.ucAlgorithmId = CIPHER_SUITE_CCMP; /* AES */ -+ rCmdKey.ucKeyId = 0; -+ rCmdKey.ucKeyLen = 16; /* AES = 128bit */ -+ kalMemCopy(rCmdKey.aucKeyMaterial, prBowSetPTK->aucTemporalKey, 16); -+ -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "prBowSetPTK->aucTemporalKey, %x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x.\n", -+ prBowSetPTK->aucTemporalKey[0], -+ prBowSetPTK->aucTemporalKey[1], -+ prBowSetPTK->aucTemporalKey[2], -+ prBowSetPTK->aucTemporalKey[3], -+ prBowSetPTK->aucTemporalKey[4], -+ prBowSetPTK->aucTemporalKey[5], -+ prBowSetPTK->aucTemporalKey[6], -+ prBowSetPTK->aucTemporalKey[7], -+ prBowSetPTK->aucTemporalKey[8], -+ prBowSetPTK->aucTemporalKey[9], -+ prBowSetPTK->aucTemporalKey[10], -+ prBowSetPTK->aucTemporalKey[11], -+ prBowSetPTK->aucTemporalKey[12], -+ prBowSetPTK->aucTemporalKey[13], -+ prBowSetPTK->aucTemporalKey[14], prBowSetPTK->aucTemporalKey[15])); -+ -+ DBGLOG(BOW, EVENT, "rCmdKey.aucKeyMaterial, %x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x.\n", -+ rCmdKey.aucKeyMaterial[0], -+ rCmdKey.aucKeyMaterial[1], -+ rCmdKey.aucKeyMaterial[2], -+ rCmdKey.aucKeyMaterial[3], -+ rCmdKey.aucKeyMaterial[4], -+ rCmdKey.aucKeyMaterial[5], -+ rCmdKey.aucKeyMaterial[6], -+ rCmdKey.aucKeyMaterial[7], -+ rCmdKey.aucKeyMaterial[8], -+ rCmdKey.aucKeyMaterial[9], -+ rCmdKey.aucKeyMaterial[10], -+ rCmdKey.aucKeyMaterial[11], -+ rCmdKey.aucKeyMaterial[12], -+ rCmdKey.aucKeyMaterial[13], rCmdKey.aucKeyMaterial[14], rCmdKey.aucKeyMaterial[15])); -+#endif -+ -+ return wlanoidSendSetQueryBowCmd(prAdapter, -+ CMD_ID_ADD_REMOVE_KEY, -+ TRUE, -+ FALSE, -+ wlanbowCmdEventSetCommon, -+ wlanbowCmdTimeoutHandler, -+ sizeof(CMD_802_11_KEY), (PUINT_8)&rCmdKey, prCmd->rHeader.ucSeqNumber); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This is command handler for BOW_CMD_ID_READ_RSSI -+* coming from 802.11 PAL -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] prCmd Pointer to the buffer that holds the command -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS bowCmdReadRSSI(IN P_ADAPTER_T prAdapter, IN P_AMPC_COMMAND prCmd) -+{ -+ P_BOW_READ_RSSI prBowReadRSSI; -+ -+ ASSERT(prAdapter); -+ -+ /* parameter size check */ -+ if (prCmd->rHeader.u2PayloadLength != sizeof(BOW_READ_RSSI)) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ prBowReadRSSI = (P_BOW_READ_RSSI) &(prCmd->aucPayload[0]); -+ -+ return wlanoidSendSetQueryBowCmd(prAdapter, -+ CMD_ID_GET_LINK_QUALITY, -+ FALSE, -+ TRUE, -+ wlanbowCmdEventReadRssi, -+ wlanbowCmdTimeoutHandler, 0, NULL, prCmd->rHeader.ucSeqNumber); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This is command handler for BOW_CMD_ID_READ_LINK_QUALITY -+* coming from 802.11 PAL -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] prCmd Pointer to the buffer that holds the command -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS bowCmdReadLinkQuality(IN P_ADAPTER_T prAdapter, IN P_AMPC_COMMAND prCmd) -+{ -+ P_BOW_READ_LINK_QUALITY prBowReadLinkQuality; -+ -+ ASSERT(prAdapter); -+ -+ /* parameter size check */ -+ if (prCmd->rHeader.u2PayloadLength != sizeof(P_BOW_READ_LINK_QUALITY)) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ prBowReadLinkQuality = (P_BOW_READ_LINK_QUALITY) &(prCmd->aucPayload[0]); -+ -+ return wlanoidSendSetQueryBowCmd(prAdapter, -+ CMD_ID_GET_LINK_QUALITY, -+ FALSE, -+ TRUE, -+ wlanbowCmdEventReadLinkQuality, -+ wlanbowCmdTimeoutHandler, 0, NULL, prCmd->rHeader.ucSeqNumber); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This is command handler for BOW_CMD_ID_SHORT_RANGE_MODE -+* coming from 802.11 PAL -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] prCmd Pointer to the buffer that holds the command -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS bowCmdShortRangeMode(IN P_ADAPTER_T prAdapter, IN P_AMPC_COMMAND prCmd) -+{ -+ P_BOW_SHORT_RANGE_MODE prBowShortRangeMode; -+ CMD_TX_PWR_T rTxPwrParam; -+ -+ ASSERT(prAdapter); -+ -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "bowCmdShortRangeMode.\n"); -+#endif -+ -+ prBowShortRangeMode = (P_BOW_SHORT_RANGE_MODE) &(prCmd->aucPayload[0]); -+ -+ /* parameter size check */ -+ if (prCmd->rHeader.u2PayloadLength != sizeof(BOW_SHORT_RANGE_MODE)) { -+ wlanbowCmdEventSetStatus(prAdapter, prCmd, BOWCMD_STATUS_UNACCEPTED); -+ return WLAN_STATUS_INVALID_LENGTH; -+ } -+ -+ if (!bowCheckBowTableIfVaild(prAdapter, prBowShortRangeMode->aucPeerAddress)) { -+ wlanbowCmdEventSetStatus(prAdapter, prCmd, BOWCMD_STATUS_UNACCEPTED); -+ return WLAN_STATUS_NOT_ACCEPTED; -+ } -+ -+ if (bowGetBowTableState(prAdapter, prBowShortRangeMode->aucPeerAddress) != BOW_DEVICE_STATE_CONNECTED) { -+ wlanbowCmdEventSetStatus(prAdapter, prCmd, BOWCMD_STATUS_FAILURE); -+ return WLAN_STATUS_NOT_ACCEPTED; -+ } -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "prBowShortRangeMode->aucPeerAddress, %x:%x:%x:%x:%x:%x.\n", -+ prBowShortRangeMode->aucPeerAddress[0], -+ prBowShortRangeMode->aucPeerAddress[1], -+ prBowShortRangeMode->aucPeerAddress[2], -+ prBowShortRangeMode->aucPeerAddress[3], -+ prBowShortRangeMode->aucPeerAddress[4], prBowShortRangeMode->aucPeerAddress[5])); -+#endif -+ -+ rTxPwrParam.cTxPwr2G4Cck = (prBowShortRangeMode->cTxPower << 1); -+ -+ rTxPwrParam.cTxPwr2G4OFDM_BPSK = (prBowShortRangeMode->cTxPower << 1); -+ rTxPwrParam.cTxPwr2G4OFDM_QPSK = (prBowShortRangeMode->cTxPower << 1); -+ rTxPwrParam.cTxPwr2G4OFDM_16QAM = (prBowShortRangeMode->cTxPower << 1); -+ -+ rTxPwrParam.cTxPwr2G4OFDM_48Mbps = (prBowShortRangeMode->cTxPower << 1); -+ rTxPwrParam.cTxPwr2G4OFDM_54Mbps = (prBowShortRangeMode->cTxPower << 1); -+ -+ rTxPwrParam.cTxPwr2G4HT20_BPSK = (prBowShortRangeMode->cTxPower << 1); -+ rTxPwrParam.cTxPwr2G4HT20_QPSK = (prBowShortRangeMode->cTxPower << 1); -+ rTxPwrParam.cTxPwr2G4HT20_16QAM = (prBowShortRangeMode->cTxPower << 1); -+ rTxPwrParam.cTxPwr2G4HT20_MCS5 = (prBowShortRangeMode->cTxPower << 1); -+ rTxPwrParam.cTxPwr2G4HT20_MCS6 = (prBowShortRangeMode->cTxPower << 1); -+ rTxPwrParam.cTxPwr2G4HT20_MCS7 = (prBowShortRangeMode->cTxPower << 1); -+ -+ rTxPwrParam.cTxPwr2G4HT40_BPSK = (prBowShortRangeMode->cTxPower << 1); -+ rTxPwrParam.cTxPwr2G4HT40_QPSK = (prBowShortRangeMode->cTxPower << 1); -+ rTxPwrParam.cTxPwr2G4HT40_16QAM = (prBowShortRangeMode->cTxPower << 1); -+ rTxPwrParam.cTxPwr2G4HT40_MCS5 = (prBowShortRangeMode->cTxPower << 1); -+ rTxPwrParam.cTxPwr2G4HT40_MCS6 = (prBowShortRangeMode->cTxPower << 1); -+ rTxPwrParam.cTxPwr2G4HT40_MCS7 = (prBowShortRangeMode->cTxPower << 1); -+ -+ rTxPwrParam.cTxPwr5GOFDM_BPSK = (prBowShortRangeMode->cTxPower << 1); -+ rTxPwrParam.cTxPwr5GOFDM_QPSK = (prBowShortRangeMode->cTxPower << 1); -+ rTxPwrParam.cTxPwr5GOFDM_16QAM = (prBowShortRangeMode->cTxPower << 1); -+ rTxPwrParam.cTxPwr5GOFDM_48Mbps = (prBowShortRangeMode->cTxPower << 1); -+ rTxPwrParam.cTxPwr5GOFDM_54Mbps = (prBowShortRangeMode->cTxPower << 1); -+ -+ rTxPwrParam.cTxPwr5GHT20_BPSK = (prBowShortRangeMode->cTxPower << 1); -+ rTxPwrParam.cTxPwr5GHT20_QPSK = (prBowShortRangeMode->cTxPower << 1); -+ rTxPwrParam.cTxPwr5GHT20_16QAM = (prBowShortRangeMode->cTxPower << 1); -+ rTxPwrParam.cTxPwr5GHT20_MCS5 = (prBowShortRangeMode->cTxPower << 1); -+ rTxPwrParam.cTxPwr5GHT20_MCS6 = (prBowShortRangeMode->cTxPower << 1); -+ rTxPwrParam.cTxPwr5GHT20_MCS7 = (prBowShortRangeMode->cTxPower << 1); -+ rTxPwrParam.cTxPwr5GHT40_BPSK = (prBowShortRangeMode->cTxPower << 1); -+ rTxPwrParam.cTxPwr5GHT40_QPSK = (prBowShortRangeMode->cTxPower << 1); -+ rTxPwrParam.cTxPwr5GHT40_16QAM = (prBowShortRangeMode->cTxPower << 1); -+ rTxPwrParam.cTxPwr5GHT40_MCS5 = (prBowShortRangeMode->cTxPower << 1); -+ rTxPwrParam.cTxPwr5GHT40_MCS6 = (prBowShortRangeMode->cTxPower << 1); -+ rTxPwrParam.cTxPwr5GHT40_MCS7 = (prBowShortRangeMode->cTxPower << 1); -+ -+ if (nicUpdateTxPower(prAdapter, &rTxPwrParam) == WLAN_STATUS_SUCCESS) { -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "bowCmdShortRangeMode, %x.\n", WLAN_STATUS_SUCCESS); -+#endif -+ wlanbowCmdEventSetStatus(prAdapter, prCmd, BOWCMD_STATUS_SUCCESS); -+ return WLAN_STATUS_SUCCESS; -+ } -+ wlanbowCmdEventSetStatus(prAdapter, prCmd, BOWCMD_STATUS_FAILURE); -+ return WLAN_STATUS_FAILURE; -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This is command handler for BOW_CMD_ID_GET_CHANNEL_LIST -+* coming from 802.11 PAL -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] prCmd Pointer to the buffer that holds the command -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS bowCmdGetChannelList(IN P_ADAPTER_T prAdapter, IN P_AMPC_COMMAND prCmd) -+{ -+ ASSERT(prAdapter); -+ -+ /* not supported yet */ -+ return WLAN_STATUS_FAILURE; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This is generic command done handler -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] prCmdInfo Pointer to the buffer that holds the command info -+* \param[in] pucEventBuf Pointer to the set buffer OR event buffer -+* -+* \retval none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID wlanbowCmdEventSetStatus(IN P_ADAPTER_T prAdapter, IN P_AMPC_COMMAND prCmd, IN UINT_8 ucEventBuf) -+{ -+ P_AMPC_EVENT prEvent; -+ P_BOW_COMMAND_STATUS prBowCmdStatus; -+ -+ ASSERT(prAdapter); -+ -+ /* fill event header */ -+ prEvent = (P_AMPC_EVENT) kalMemAlloc((sizeof(AMPC_EVENT) + sizeof(BOW_COMMAND_STATUS)), VIR_MEM_TYPE); -+ if (!prEvent) { -+ ASSERT(FALSE); -+ return; -+ } -+ prEvent->rHeader.ucEventId = BOW_EVENT_ID_COMMAND_STATUS; -+ prEvent->rHeader.ucSeqNumber = prCmd->rHeader.ucSeqNumber; -+ prEvent->rHeader.u2PayloadLength = sizeof(BOW_COMMAND_STATUS); -+ -+ /* fill event body */ -+ prBowCmdStatus = (P_BOW_COMMAND_STATUS) (prEvent->aucPayload); -+ kalMemZero(prBowCmdStatus, sizeof(BOW_COMMAND_STATUS)); -+ -+ prBowCmdStatus->ucStatus = ucEventBuf; -+ -+ kalIndicateBOWEvent(prAdapter->prGlueInfo, prEvent); -+ -+ kalMemFree(prEvent, VIR_MEM_TYPE, (sizeof(AMPC_EVENT) + sizeof(BOW_COMMAND_STATUS))); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This is generic command done handler -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] prCmdInfo Pointer to the buffer that holds the command info -+* \param[in] pucEventBuf Pointer to the set buffer OR event buffer -+* -+* \retval none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID wlanbowCmdEventSetCommon(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) -+{ -+ P_AMPC_EVENT prEvent; -+ P_BOW_COMMAND_STATUS prBowCmdStatus; -+ -+ ASSERT(prAdapter); -+ -+ /* fill event header */ -+ prEvent = (P_AMPC_EVENT) kalMemAlloc((sizeof(AMPC_EVENT) + sizeof(BOW_COMMAND_STATUS)), VIR_MEM_TYPE); -+ if (!prEvent) { -+ ASSERT(FALSE); -+ return; -+ } -+ prEvent->rHeader.ucEventId = BOW_EVENT_ID_COMMAND_STATUS; -+ prEvent->rHeader.ucSeqNumber = (UINT_8) prCmdInfo->u4PrivateData; -+ prEvent->rHeader.u2PayloadLength = sizeof(BOW_COMMAND_STATUS); -+ -+ /* fill event body */ -+ prBowCmdStatus = (P_BOW_COMMAND_STATUS) (prEvent->aucPayload); -+ kalMemZero(prBowCmdStatus, sizeof(BOW_COMMAND_STATUS)); -+ -+ prBowCmdStatus->ucStatus = BOWCMD_STATUS_SUCCESS; -+ -+ kalIndicateBOWEvent(prAdapter->prGlueInfo, prEvent); -+ -+ kalMemFree(prEvent, VIR_MEM_TYPE, (sizeof(AMPC_EVENT) + sizeof(BOW_COMMAND_STATUS))); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief command done handler for CMD_ID_CMD_BT_OVER_WIFI -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] prCmdInfo Pointer to the buffer that holds the command info -+* \param[in] pucEventBuf Pointer to the set buffer OR event buffer -+* -+* \retval none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID wlanbowCmdEventLinkConnected(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) -+{ -+ P_AMPC_EVENT prEvent; -+ P_BOW_LINK_CONNECTED prBowLinkConnected; -+ P_BOW_FSM_INFO_T prBowFsmInfo; -+ P_BSS_INFO_T prBssInfo; -+ -+ ASSERT(prAdapter); -+ -+ prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_BOW_INDEX]); -+ -+ /* fill event header */ -+ prEvent = (P_AMPC_EVENT) kalMemAlloc((sizeof(AMPC_EVENT) + sizeof(BOW_LINK_CONNECTED)), VIR_MEM_TYPE); -+ if (!prEvent) { -+ ASSERT(FALSE); -+ return; -+ } -+ prEvent->rHeader.ucEventId = BOW_EVENT_ID_LINK_CONNECTED; -+ prEvent->rHeader.ucSeqNumber = (UINT_8) prCmdInfo->u4PrivateData; -+ prEvent->rHeader.u2PayloadLength = sizeof(BOW_LINK_CONNECTED); -+ -+ /* fill event body */ -+ prBowLinkConnected = (P_BOW_LINK_CONNECTED) (prEvent->aucPayload); -+ kalMemZero(prBowLinkConnected, sizeof(BOW_LINK_CONNECTED)); -+ prBowLinkConnected->rChannel.ucChannelNum = prBssInfo->ucPrimaryChannel; -+ prBowLinkConnected->rChannel.ucChannelBand = prBssInfo->eBand; -+ COPY_MAC_ADDR(prBowLinkConnected->aucPeerAddress, prBowFsmInfo->aucPeerAddress); -+ -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "prEvent->rHeader.ucEventId, 0x%x\n", prEvent->rHeader.ucEventId); -+ DBGLOG(BOW, EVENT, "prEvent->rHeader.ucSeqNumber, 0x%x\n", prEvent->rHeader.ucSeqNumber); -+ DBGLOG(BOW, EVENT, "prEvent->rHeader.u2PayloadLength, 0x%x\n", prEvent->rHeader.u2PayloadLength); -+ DBGLOG(BOW, EVENT, -+ "prBowLinkConnected->rChannel.ucChannelNum, 0x%x\n", prBowLinkConnected->rChannel.ucChannelNum); -+ DBGLOG(BOW, EVENT, -+ "prBowLinkConnected->rChannel.ucChannelBand, 0x%x\n", prBowLinkConnected->rChannel.ucChannelBand); -+ DBGLOG(BOW, EVENT, -+ "wlanbowCmdEventLinkConnected, prBowFsmInfo->aucPeerAddress, %x:%x:%x:%x:%x:%x.\n", -+ prBowFsmInfo->aucPeerAddress[0], prBowFsmInfo->aucPeerAddress[1], prBowFsmInfo->aucPeerAddress[2], -+ prBowFsmInfo->aucPeerAddress[3], prBowFsmInfo->aucPeerAddress[4], prBowFsmInfo->aucPeerAddress[5]); -+ DBGLOG(BOW, EVENT, -+ "wlanbowCmdEventLinkConnected, prBowLinkConnected->aucPeerAddress, %x:%x:%x:%x:%x:%x.\n", -+ prBowLinkConnected->aucPeerAddress[0], prBowLinkConnected->aucPeerAddress[1], -+ prBowLinkConnected->aucPeerAddress[2], prBowLinkConnected->aucPeerAddress[3], -+ prBowLinkConnected->aucPeerAddress[4], prBowLinkConnected->aucPeerAddress[5])); -+ DBGLOG(BOW, EVENT, "wlanbowCmdEventLinkConnected, g_u4LinkCount, %x.\n", g_u4LinkCount); -+#endif -+ -+ /*Indicate Event to PAL */ -+ kalIndicateBOWEvent(prAdapter->prGlueInfo, prEvent); -+ kalMemFree(prEvent, VIR_MEM_TYPE, (sizeof(AMPC_EVENT) + sizeof(BOW_LINK_CONNECTED))); -+ -+ /*Release channel if granted */ -+ if (prBowFsmInfo->fgIsChannelGranted) { -+ cnmTimerStopTimer(prAdapter, &prBowFsmInfo->rChGrantedTimer); -+ /* bowReleaseCh(prAdapter); */ -+ /*Requested, not granted yet */ -+ } else if (prBowFsmInfo->fgIsChannelRequested) { -+ prBowFsmInfo->fgIsChannelRequested = FALSE; -+ } -+ -+ /* set to connected status */ -+ bowSetBowTableState(prAdapter, prBowFsmInfo->aucPeerAddress, BOW_DEVICE_STATE_CONNECTED); -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief command done handler for CMD_ID_CMD_BT_OVER_WIFI -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] prCmdInfo Pointer to the buffer that holds the command info -+* \param[in] pucEventBuf Pointer to the set buffer OR event buffer -+* -+* \retval none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID wlanbowCmdEventLinkDisconnected(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) -+{ -+ P_AMPC_EVENT prEvent; -+ P_BOW_LINK_DISCONNECTED prBowLinkDisconnected; -+ P_BOW_FSM_INFO_T prBowFsmInfo; -+ BOW_TABLE_T rBowTable; -+ UINT_8 ucBowTableIdx; -+ ENUM_BOW_DEVICE_STATE eFsmState; -+ BOOLEAN fgSendDeauth = FALSE; -+ -+ ASSERT(prAdapter); -+ -+ prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); -+ eFsmState = bowGetBowTableState(prAdapter, prBowFsmInfo->aucPeerAddress); -+ -+ if (eFsmState == BOW_DEVICE_STATE_DISCONNECTED) { -+ /*do nothing */ -+ return; -+ } -+ /*Cancel scan */ -+ else if (eFsmState == BOW_DEVICE_STATE_SCANNING && !(prBowFsmInfo->fgIsChannelRequested)) { -+ bowResponderCancelScan(prAdapter, FALSE); -+ bowSetBowTableState(prAdapter, prBowFsmInfo->aucPeerAddress, BOW_DEVICE_STATE_DISCONNECTING); -+ return; -+ } -+ /* fill event header */ -+ prEvent = (P_AMPC_EVENT) kalMemAlloc((sizeof(AMPC_EVENT) + sizeof(BOW_LINK_DISCONNECTED)), VIR_MEM_TYPE); -+ if (!prEvent) { -+ ASSERT(FALSE); -+ return; -+ } -+ prEvent->rHeader.ucEventId = BOW_EVENT_ID_LINK_DISCONNECTED; -+ if ((prCmdInfo->u4PrivateData)) -+ prEvent->rHeader.ucSeqNumber = (UINT_8) prCmdInfo->u4PrivateData; -+ else -+ prEvent->rHeader.ucSeqNumber = 0; -+ -+ prEvent->rHeader.u2PayloadLength = sizeof(BOW_LINK_DISCONNECTED); -+ -+ /* fill event body */ -+ prBowLinkDisconnected = (P_BOW_LINK_DISCONNECTED) (prEvent->aucPayload); -+ kalMemZero(prBowLinkDisconnected, sizeof(BOW_LINK_DISCONNECTED)); -+ prBowLinkDisconnected->ucReason = 0x0; -+ COPY_MAC_ADDR(prBowLinkDisconnected->aucPeerAddress, prBowFsmInfo->aucPeerAddress); -+ -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "prEvent->rHeader.ucEventId, 0x%x\n", prEvent->rHeader.ucEventId); -+ DBGLOG(BOW, EVENT, "prEvent->rHeader.ucSeqNumber, 0x%x\n", prEvent->rHeader.ucSeqNumber); -+ DBGLOG(BOW, EVENT, "prEvent->rHeader.u2PayloadLength, 0x%x\n", prEvent->rHeader.u2PayloadLength); -+ -+ DBGLOG(BOW, EVENT, "wlanbowCmdEventLinkDisconnected, prBowFsmInfo->aucPeerAddress, %x:%x:%x:%x:%x:%x.\n", -+ prBowFsmInfo->aucPeerAddress[0], -+ prBowFsmInfo->aucPeerAddress[1], -+ prBowFsmInfo->aucPeerAddress[2], -+ prBowFsmInfo->aucPeerAddress[3], -+ prBowFsmInfo->aucPeerAddress[4], prBowFsmInfo->aucPeerAddress[5])); -+ -+ DBGLOG(BOW, EVENT, -+ "wlanbowCmdEventLinkDisconnected, prBowLinkDisconnected->aucPeerAddress, %x:%x:%x:%x:%x:%x.\n", -+ prBowLinkDisconnected->aucPeerAddress[0], prBowLinkDisconnected->aucPeerAddress[1], -+ prBowLinkDisconnected->aucPeerAddress[2], prBowLinkDisconnected->aucPeerAddress[3], -+ prBowLinkDisconnected->aucPeerAddress[4], prBowLinkDisconnected->aucPeerAddress[5])); -+ -+ DBGLOG(BOW, EVENT, "wlanbowCmdEventLinkDisconnected, g_u4LinkCount, %x.\n", g_u4LinkCount); -+#endif -+ -+ /*Indicate BoW event to PAL */ -+#if 0 -+ kalIndicateBOWEvent(prAdapter->prGlueInfo, prEvent); -+ kalMemFree(prEvent, VIR_MEM_TYPE, (sizeof(AMPC_EVENT) + sizeof(BOW_LINK_DISCONNECTED))); -+#endif -+ -+ /* set to disconnected status */ -+ prBowFsmInfo->prTargetStaRec = -+ cnmGetStaRecByAddress(prAdapter, NETWORK_TYPE_BOW_INDEX, prBowLinkDisconnected->aucPeerAddress); -+ if (!(prBowFsmInfo->prTargetStaRec)) { -+ kalMemFree(prEvent, VIR_MEM_TYPE, (sizeof(AMPC_EVENT) + sizeof(BOW_LINK_DISCONNECTED))); -+ ASSERT(FALSE); -+ return; -+ } -+ -+ /*Release channel if granted */ -+ if (prBowFsmInfo->fgIsChannelGranted) { -+ cnmTimerStopTimer(prAdapter, &prBowFsmInfo->rChGrantedTimer); -+ bowReleaseCh(prAdapter); -+ /*Requested, not granted yet */ -+ } else if (prBowFsmInfo->fgIsChannelRequested) { -+ prBowFsmInfo->fgIsChannelRequested = FALSE; -+ /* bowReleaseCh(prAdapter); */ -+ } -+#if 1 -+ /*Send Deauth to connected peer */ -+ if (eFsmState == BOW_DEVICE_STATE_CONNECTED && (prBowFsmInfo->prTargetStaRec->ucStaState == STA_STATE_3)) { -+ fgSendDeauth = TRUE; -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, -+ "wlanbowCmdEventLinkDisconnected, bowGetBowTableState, %x.\n", -+ bowGetBowTableState(prAdapter, prBowLinkDisconnected->aucPeerAddress)); -+#endif -+ authSendDeauthFrame(prAdapter, -+ prBowFsmInfo->prTargetStaRec, -+ (P_SW_RFB_T) NULL, -+ REASON_CODE_DEAUTH_LEAVING_BSS, (PFN_TX_DONE_HANDLER) bowDisconnectLink); -+ } -+#endif -+ -+#if 0 -+ /* 3 <3>Stop this link; flush Tx; -+ * send deAuthentication -> abort. SAA, AAA. need to check BOW table state == Connected. -+ */ -+ if (prAdapter->prGlueInfo->i4TxPendingFrameNum > 0) -+ kalFlushPendingTxPackets(prAdapter->prGlueInfo); -+ -+ /* flush pending security frames */ -+ if (prAdapter->prGlueInfo->i4TxPendingSecurityFrameNum > 0) -+ kalClearSecurityFrames(prAdapter->prGlueInfo); -+#endif -+ -+ /*Update BoW table */ -+ bowGetBowTableEntryByPeerAddress(prAdapter, prBowLinkDisconnected->aucPeerAddress, &ucBowTableIdx); -+ rBowTable.fgIsValid = FALSE; -+ rBowTable.eState = BOW_DEVICE_STATE_DISCONNECTED; -+ kalMemZero(rBowTable.aucPeerAddress, sizeof(rBowTable.aucPeerAddress)); -+ bowSetBowTableContent(prAdapter, ucBowTableIdx, &rBowTable); -+ -+ /*Indicate BoW event to PAL */ -+ kalIndicateBOWEvent(prAdapter->prGlueInfo, prEvent); -+ kalMemFree(prEvent, VIR_MEM_TYPE, (sizeof(AMPC_EVENT) + sizeof(BOW_LINK_DISCONNECTED))); -+ -+ /*Decrease link count */ -+ GLUE_DEC_REF_CNT(g_u4LinkCount); -+ -+ /*If no need to send deauth, DO disconnect now */ -+ /*If need to send deauth, DO disconnect at deauth Tx done */ -+ if (!fgSendDeauth) -+ bowDisconnectLink(prAdapter, NULL, TX_RESULT_SUCCESS); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief command done handler for CMD_ID_CMD_BT_OVER_WIFI -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] prCmdInfo Pointer to the buffer that holds the command info -+* \param[in] pucEventBuf Pointer to the set buffer OR event buffer -+* -+* \retval none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID wlanbowCmdEventSetSetupConnection(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) -+{ -+ P_AMPC_EVENT prEvent; -+ P_BOW_COMMAND_STATUS prBowCmdStatus; -+ P_WIFI_CMD_T prWifiCmd; -+ P_CMD_BT_OVER_WIFI prCmdBtOverWifi; -+ P_BOW_FSM_INFO_T prBowFsmInfo; -+ -+ ASSERT(prAdapter); -+ -+ prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); -+ -+ /* restore original command for rPeerAddr */ -+ prWifiCmd = (P_WIFI_CMD_T) (prCmdInfo->pucInfoBuffer); -+ prCmdBtOverWifi = (P_CMD_BT_OVER_WIFI) (prWifiCmd->aucBuffer); -+ -+ /* fill event header */ -+ prEvent = (P_AMPC_EVENT) kalMemAlloc((sizeof(AMPC_EVENT) + sizeof(BOW_COMMAND_STATUS)), VIR_MEM_TYPE); -+ if (!prEvent) { -+ ASSERT(FALSE); -+ return; -+ } -+ prEvent->rHeader.ucEventId = BOW_EVENT_ID_COMMAND_STATUS; -+ prEvent->rHeader.ucSeqNumber = (UINT_8) prCmdInfo->u4PrivateData; -+ prEvent->rHeader.u2PayloadLength = sizeof(BOW_COMMAND_STATUS); -+ -+ /* fill event body */ -+ prBowCmdStatus = (P_BOW_COMMAND_STATUS) (prEvent->aucPayload); -+ kalMemZero(prBowCmdStatus, sizeof(BOW_COMMAND_STATUS)); -+ prBowCmdStatus->ucStatus = BOWCMD_STATUS_SUCCESS; -+ -+ /*Indicate BoW event to PAL */ -+ kalIndicateBOWEvent(prAdapter->prGlueInfo, prEvent); -+ kalMemFree(prEvent, VIR_MEM_TYPE, (sizeof(AMPC_EVENT) + sizeof(BOW_COMMAND_STATUS))); -+ -+ /* set to starting status */ -+ kalSetBowState(prAdapter->prGlueInfo, BOW_DEVICE_STATE_STARTING, prCmdBtOverWifi->rPeerAddr); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This is the command done handler for BOW_CMD_ID_READ_LINK_QUALITY -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] prCmdInfo Pointer to the buffer that holds the command info -+* \param[in] pucEventBuf Pointer to the set buffer OR event buffer -+* -+* \retval none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID wlanbowCmdEventReadLinkQuality(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) -+{ -+ P_EVENT_LINK_QUALITY prLinkQuality; -+ P_AMPC_EVENT prEvent; -+ P_BOW_LINK_QUALITY prBowLinkQuality; -+ -+ ASSERT(prAdapter); -+ -+ prLinkQuality = (P_EVENT_LINK_QUALITY) pucEventBuf; -+ -+ /* fill event header */ -+ prEvent = (P_AMPC_EVENT) kalMemAlloc((sizeof(AMPC_EVENT) + sizeof(BOW_LINK_QUALITY)), VIR_MEM_TYPE); -+ if (!prEvent) { -+ ASSERT(FALSE); -+ return; -+ } -+ prEvent->rHeader.ucEventId = BOW_EVENT_ID_LINK_QUALITY; -+ prEvent->rHeader.ucSeqNumber = (UINT_8) prCmdInfo->u4PrivateData; -+ prEvent->rHeader.u2PayloadLength = sizeof(BOW_LINK_QUALITY); -+ -+ /* fill event body */ -+ prBowLinkQuality = (P_BOW_LINK_QUALITY) (prEvent->aucPayload); -+ kalMemZero(prBowLinkQuality, sizeof(BOW_LINK_QUALITY)); -+ prBowLinkQuality->ucLinkQuality = (UINT_8) prLinkQuality->cLinkQuality; -+ -+ kalIndicateBOWEvent(prAdapter->prGlueInfo, prEvent); -+ -+ kalMemFree(prEvent, VIR_MEM_TYPE, (sizeof(AMPC_EVENT) + sizeof(BOW_LINK_QUALITY))); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This is the command done handler for BOW_CMD_ID_READ_RSSI -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] prCmdInfo Pointer to the buffer that holds the command info -+* \param[in] pucEventBuf Pointer to the set buffer OR event buffer -+* -+* \retval none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID wlanbowCmdEventReadRssi(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) -+{ -+ P_EVENT_LINK_QUALITY prLinkQuality; -+ P_AMPC_EVENT prEvent; -+ P_BOW_RSSI prBowRssi; -+ -+ ASSERT(prAdapter); -+ -+ prLinkQuality = (P_EVENT_LINK_QUALITY) pucEventBuf; -+ -+ /* fill event header */ -+ prEvent = (P_AMPC_EVENT) kalMemAlloc((sizeof(AMPC_EVENT) + sizeof(BOW_LINK_QUALITY)), VIR_MEM_TYPE); -+ if (!prEvent) { -+ ASSERT(FALSE); -+ return; -+ } -+ prEvent->rHeader.ucEventId = BOW_EVENT_ID_RSSI; -+ prEvent->rHeader.ucSeqNumber = (UINT_8) prCmdInfo->u4PrivateData; -+ prEvent->rHeader.u2PayloadLength = sizeof(BOW_RSSI); -+ -+ /* fill event body */ -+ prBowRssi = (P_BOW_RSSI) (prEvent->aucPayload); -+ kalMemZero(prBowRssi, sizeof(BOW_RSSI)); -+ prBowRssi->cRssi = (INT_8) prLinkQuality->cRssi; -+ -+ kalIndicateBOWEvent(prAdapter->prGlueInfo, prEvent); -+ -+ kalMemFree(prEvent, VIR_MEM_TYPE, (sizeof(AMPC_EVENT) + sizeof(BOW_LINK_QUALITY))); -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This is the default command timeout handler -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] prCmdInfo Pointer to the buffer that holds the command info -+* -+* \retval none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID wlanbowCmdTimeoutHandler(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo) -+{ -+ P_AMPC_EVENT prEvent; -+ P_BOW_COMMAND_STATUS prBowCmdStatus; -+ -+ ASSERT(prAdapter); -+ -+ /* fill event header */ -+ prEvent = (P_AMPC_EVENT) kalMemAlloc((sizeof(AMPC_EVENT) + sizeof(BOW_COMMAND_STATUS)), VIR_MEM_TYPE); -+ if (!prEvent) { -+ ASSERT(FALSE); -+ return; -+ } -+ prEvent->rHeader.ucEventId = BOW_EVENT_ID_COMMAND_STATUS; -+ prEvent->rHeader.ucSeqNumber = (UINT_8) prCmdInfo->u4PrivateData; -+ prEvent->rHeader.u2PayloadLength = sizeof(BOW_COMMAND_STATUS); -+ -+ /* fill event body */ -+ prBowCmdStatus = (P_BOW_COMMAND_STATUS) (prEvent->aucPayload); -+ kalMemZero(prBowCmdStatus, sizeof(BOW_COMMAND_STATUS)); -+ -+ prBowCmdStatus->ucStatus = BOWCMD_STATUS_TIMEOUT; /* timeout */ -+ -+ kalIndicateBOWEvent(prAdapter->prGlueInfo, prEvent); -+ -+ kalMemFree(prEvent, VIR_MEM_TYPE, (sizeof(AMPC_EVENT) + sizeof(BOW_COMMAND_STATUS))); -+ -+} -+ -+VOID bowStopping(IN P_ADAPTER_T prAdapter) -+{ -+ P_BOW_FSM_INFO_T prBowFsmInfo; -+ P_BSS_INFO_T prBowBssInfo; -+ -+ ASSERT(prAdapter); -+ -+ prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); -+ prBowBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_BOW_INDEX]); -+ -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "bowStoping.\n"); -+ DBGLOG(BOW, EVENT, "bowStoping, SSID %s.\n", prBowBssInfo->aucSSID); -+ DBGLOG(BOW, EVENT, "bowStoping, prBowBssInfo->aucBSSID, %x:%x:%x:%x:%x:%x.\n", -+ prBowBssInfo->aucBSSID[0], -+ prBowBssInfo->aucBSSID[1], -+ prBowBssInfo->aucBSSID[2], -+ prBowBssInfo->aucBSSID[3], prBowBssInfo->aucBSSID[4], prBowBssInfo->aucBSSID[5])); -+ DBGLOG(BOW, EVENT, "bowStoping, prBssInfo->aucOwnMacAddr, %x:%x:%x:%x:%x:%x.\n", -+ prBowBssInfo->aucOwnMacAddr[0], -+ prBowBssInfo->aucOwnMacAddr[1], -+ prBowBssInfo->aucOwnMacAddr[2], -+ prBowBssInfo->aucOwnMacAddr[3], -+ prBowBssInfo->aucOwnMacAddr[4], prBowBssInfo->aucOwnMacAddr[5])); -+ DBGLOG(BOW, EVENT, "bowStoping, prAdapter->rWifiVar.aucDeviceAddress, %x:%x:%x:%x:%x:%x.\n", -+ prAdapter->rWifiVar.aucDeviceAddress[0], -+ prAdapter->rWifiVar.aucDeviceAddress[1], -+ prAdapter->rWifiVar.aucDeviceAddress[2], -+ prAdapter->rWifiVar.aucDeviceAddress[3], -+ prAdapter->rWifiVar.aucDeviceAddress[4], prAdapter->rWifiVar.aucDeviceAddress[5])); -+ DBGLOG(BOW, EVENT, "bowStopping, g_u4LinkCount, %x.\n", g_u4LinkCount); -+ DBGLOG(BOW, EVENT, "prBowFsmInfo->aucPeerAddress, %x:%x:%x:%x:%x:%x.\n", prBowFsmInfo->aucPeerAddress[0], -+ prBowFsmInfo->aucPeerAddress[1], -+ prBowFsmInfo->aucPeerAddress[2], -+ prBowFsmInfo->aucPeerAddress[3], -+ prBowFsmInfo->aucPeerAddress[4], prBowFsmInfo->aucPeerAddress[5])); -+ kalPrint("BoW Stoping,[%d,%d]\n", g_u4LinkCount, g_u4Beaconing); -+#endif -+ -+ if (g_u4LinkCount == 0) { -+ /*Stop beaconing */ -+ GLUE_DEC_REF_CNT(g_u4Beaconing); -+ -+ /*Deactive BoW network */ -+ /* prBowBssInfo->fgIsNetActive = FALSE; */ -+ /* prBowBssInfo->fgIsBeaconActivated = FALSE; */ -+ nicPmIndicateBssAbort(prAdapter, NETWORK_TYPE_BOW_INDEX); -+ bowChangeMediaState(prAdapter, PARAM_MEDIA_STATE_DISCONNECTED); -+ nicUpdateBss(prAdapter, NETWORK_TYPE_BOW_INDEX); -+ /*temp solution for FW hal_pwr_mgt.c#3037 ASSERT */ -+ nicDeactivateNetwork(prAdapter, NETWORK_TYPE_BOW_INDEX); -+ SET_NET_PWR_STATE_IDLE(prAdapter, NETWORK_TYPE_BOW_INDEX); -+ UNSET_NET_ACTIVE(prAdapter, NETWORK_TYPE_BOW_INDEX); -+ -+ } -+ -+} -+ -+VOID bowStarting(IN P_ADAPTER_T prAdapter) -+{ -+ P_BOW_FSM_INFO_T prBowFsmInfo; -+ P_BSS_INFO_T prBssInfo; -+ -+ ASSERT(prAdapter); -+ -+ prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); -+ -+ if (g_u4LinkCount == 1) { -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "BoW Starting.\n"); -+ DBGLOG(BOW, EVENT, "BoW channel granted.\n"); -+#endif -+ -+#if 0 -+ /*Active BoW Network */ -+ SET_NET_ACTIVE(prAdapter, NETWORK_TYPE_BOW_INDEX); -+ SET_NET_PWR_STATE_ACTIVE(prAdapter, NETWORK_TYPE_BOW_INDEX); -+ nicActivateNetwork(prAdapter, NETWORK_TYPE_BOW_INDEX); -+#endif -+ -+ /* 3 <1> Update BSS_INFO_T per Network Basis */ -+ /* 4 <1.1> Setup Operation Mode */ -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_BOW_INDEX]); -+ prBssInfo->ucNetTypeIndex = NETWORK_TYPE_BOW_INDEX; -+ prBssInfo->eCurrentOPMode = OP_MODE_BOW; -+ -+ /* 4 <1.2> Setup SSID */ -+ COPY_MAC_ADDR(prBssInfo->aucOwnMacAddr, prAdapter->rWifiVar.aucDeviceAddress); -+ COPY_MAC_ADDR(prBssInfo->aucBSSID, prAdapter->rWifiVar.aucDeviceAddress); -+ prBssInfo->ucSSIDLen = BOW_SSID_LEN; -+ bowAssignSsid(prBssInfo->aucSSID, prBssInfo->aucOwnMacAddr); -+ -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "SSID %s.\n", prBssInfo->aucSSID); -+ DBGLOG(BOW, EVENT, "prBssInfo->aucBSSID, %x:%x:%x:%x:%x:%x.\n", -+ prBssInfo->aucBSSID[0], -+ prBssInfo->aucBSSID[1], -+ prBssInfo->aucBSSID[2], -+ prBssInfo->aucBSSID[3], prBssInfo->aucBSSID[4], prBssInfo->aucBSSID[5])); -+ DBGLOG(BOW, EVENT, "prBssInfo->aucOwnMacAddr, %x:%x:%x:%x:%x:%x.\n", -+ prBssInfo->aucOwnMacAddr[0], -+ prBssInfo->aucOwnMacAddr[1], -+ prBssInfo->aucOwnMacAddr[2], -+ prBssInfo->aucOwnMacAddr[3], -+ prBssInfo->aucOwnMacAddr[4], prBssInfo->aucOwnMacAddr[5])); -+ DBGLOG(BOW, EVENT, "prAdapter->rWifiVar.aucDeviceAddress, %x:%x:%x:%x:%x:%x.\n", -+ prAdapter->rWifiVar.aucDeviceAddress[0], -+ prAdapter->rWifiVar.aucDeviceAddress[1], -+ prAdapter->rWifiVar.aucDeviceAddress[2], -+ prAdapter->rWifiVar.aucDeviceAddress[3], -+ prAdapter->rWifiVar.aucDeviceAddress[4], prAdapter->rWifiVar.aucDeviceAddress[5])); -+#endif -+ -+ /* 4 <1.3> Clear current AP's STA_RECORD_T and current AID */ -+ prBssInfo->prStaRecOfAP = (P_STA_RECORD_T) NULL; -+ prBssInfo->u2AssocId = 0; -+ -+ /* 4 <1.4> Setup Channel, Band and Phy Attributes */ -+ prBssInfo->ucPrimaryChannel = prBowFsmInfo->ucPrimaryChannel; -+ if (prBowFsmInfo->eBand == BAND_2G4) -+ prBssInfo->eBand = BAND_2G4; -+ else -+ prBssInfo->eBand = BAND_5G; -+ -+#if CFG_BOW_SUPPORT_11N -+ /* Depend on eBand */ -+ prBssInfo->ucPhyTypeSet = prAdapter->rWifiVar.ucAvailablePhyTypeSet & PHY_TYPE_SET_802_11BGN; -+ /* Depend on eCurrentOPMode and ucPhyTypeSet */ -+ prBssInfo->ucConfigAdHocAPMode = AP_MODE_MIXED_11BG; -+ -+ prBssInfo->ucNonHTBasicPhyType = (UINT_8) -+ rNonHTApModeAttributes[prBssInfo->ucConfigAdHocAPMode].ePhyTypeIndex; -+ prBssInfo->u2BSSBasicRateSet = rNonHTApModeAttributes[prBssInfo->ucConfigAdHocAPMode].u2BSSBasicRateSet; -+ -+ prBssInfo->u2OperationalRateSet = -+ rNonHTPhyAttributes[prBssInfo->ucNonHTBasicPhyType].u2SupportedRateSet; -+ -+ rateGetDataRatesFromRateSet(prBssInfo->u2OperationalRateSet, -+ prBssInfo->u2BSSBasicRateSet, -+ prBssInfo->aucAllSupportedRates, &prBssInfo->ucAllSupportedRatesLen); -+ -+#else -+ if (prBssInfo->eBand == BAND_2G4) { -+ /* Depend on eBand */ -+ prBssInfo->ucPhyTypeSet = PHY_TYPE_SET_802_11BG; -+ /* Depend on eCurrentOPMode and ucPhyTypeSet */ -+ prBssInfo->ucConfigAdHocAPMode = AP_MODE_MIXED_11BG; -+ -+ /* RATE_SET_ERP; */ -+ prBssInfo->u2BSSBasicRateSet = BASIC_RATE_SET_ERP; -+ prBssInfo->u2OperationalRateSet = RATE_SET_ERP; -+ prBssInfo->ucNonHTBasicPhyType = PHY_TYPE_ERP_INDEX; -+ } else { -+ /* Depend on eBand */ -+ /* prBssInfo->ucPhyTypeSet = PHY_TYPE_SET_802_11BG; */ -+ /* Depend on eCurrentOPMode and ucPhyTypeSet */ -+ /* prBssInfo->ucConfigAdHocAPMode = AP_MODE_MIXED_11BG; */ -+ /* Depend on eBand */ -+ prBssInfo->ucPhyTypeSet = PHY_TYPE_SET_802_11A; -+ /* Depend on eCurrentOPMode and ucPhyTypeSet */ -+ prBssInfo->ucConfigAdHocAPMode = AP_MODE_11A; -+ -+ /* RATE_SET_ERP; */ -+ /* prBssInfo->u2BSSBasicRateSet = BASIC_RATE_SET_ERP; */ -+ /* prBssInfo->u2OperationalRateSet = RATE_SET_ERP; */ -+ -+ /* RATE_SET_ERP; */ -+ prBssInfo->u2BSSBasicRateSet = BASIC_RATE_SET_OFDM; -+ prBssInfo->u2OperationalRateSet = RATE_SET_OFDM; -+ prBssInfo->ucNonHTBasicPhyType = PHY_TYPE_OFDM_INDEX; -+ } -+ -+#endif -+ prBssInfo->fgErpProtectMode = FALSE; -+ -+ /* 4 <1.5> Setup MIB for current BSS */ -+ prBssInfo->u2BeaconInterval = prBowFsmInfo->u2BeaconInterval; -+ prBssInfo->ucDTIMPeriod = DOT11_DTIM_PERIOD_DEFAULT; -+ prBssInfo->u2ATIMWindow = 0; -+ prBssInfo->ucBeaconTimeoutCount = 0; -+ if (prBowFsmInfo->fgSupportQoS) { -+ prAdapter->rWifiVar.fgSupportQoS = TRUE; -+ prBssInfo->fgIsQBSS = TRUE; -+ } -+ /* 3 <2> Update BSS_INFO_T common part */ -+#if CFG_SUPPORT_AAA -+ bssInitForAP(prAdapter, prBssInfo, TRUE); -+ nicQmUpdateWmmParms(prAdapter, NETWORK_TYPE_BOW_INDEX); -+#endif /* CFG_SUPPORT_AAA */ -+ prBssInfo->fgIsNetActive = TRUE; -+ prBssInfo->fgIsBeaconActivated = TRUE; -+ -+ /* 3 <3> Set MAC HW */ -+ -+ /* 4 <2> Initiate BSS_INFO_T - common part */ -+ BOW_BSS_INFO_INIT(prAdapter, NETWORK_TYPE_BOW_INDEX); -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, -+ "prBowFsmInfo->aucPeerAddress, %x:%x:%x:%x:%x:%x.\n", prBowFsmInfo->aucPeerAddress[0], -+ prBowFsmInfo->aucPeerAddress[1], prBowFsmInfo->aucPeerAddress[2], -+ prBowFsmInfo->aucPeerAddress[3], prBowFsmInfo->aucPeerAddress[4], -+ prBowFsmInfo->aucPeerAddress[5])); -+#endif -+ -+ /* 4 <3.1> use command packets to inform firmware */ -+ rlmBssInitForAPandIbss(prAdapter, prBssInfo); -+ nicUpdateBss(prAdapter, NETWORK_TYPE_BOW_INDEX); -+ -+ /* 4 <3.2> Update AdHoc PM parameter */ -+ nicPmIndicateBssCreated(prAdapter, NETWORK_TYPE_BOW_INDEX); -+ -+ /* 4 <3.1> Reset HW TSF Update Mode and Beacon Mode */ -+ -+ /* 4 <3.2> Setup BSSID */ -+ /* TODO: rxmSetRxFilterBSSID0 */ -+/* rxmSetRxFilterBSSID0(prBssInfo->ucHwBssidId, prBssInfo->aucBSSID); */ -+ -+ /* 4 <3.3> Setup RX Filter to accept Probe Request */ -+ /* TODO: f get/set RX filter. */ -+ -+#if 0 -+ { -+ UINT_32 u4RxFilter; -+ -+ if (halMacRxGetRxFilters(&u4RxFilter) == HAL_STATUS_SUCCESS) { -+ -+ u4RxFilter &= ~BIT(RXFILTER_DROP_PROBE_REQ); -+ -+ halMacRxSetRxFilters(u4RxFilter); -+ } -+ } -+#endif -+ } -+ -+ /*Update BoW Table */ -+ bowSetBowTableState(prAdapter, prBowFsmInfo->aucPeerAddress, BOW_DEVICE_STATE_STARTING); -+ -+#if CFG_BOW_TEST -+ kalPrint("BoW Starting,[%d,%d]\n", g_u4LinkCount, g_u4Beaconing); -+ DBGLOG(BOW, EVENT, "bowStarting, g_u4LinkCount, %x.\n", g_u4LinkCount); -+#endif -+ -+ /*Start beaconing */ -+ if (g_u4Beaconing < 1) { -+ GLUE_INC_REF_CNT(g_u4Beaconing); -+ bssSendBeaconProbeResponse(prAdapter, NETWORK_TYPE_BOW_INDEX, NULL, 0); -+ cnmTimerStartTimer(prAdapter, &prBowFsmInfo->rStartingBeaconTimer, prBowFsmInfo->u2BeaconInterval); -+ } -+#if 0 -+ /*Responder: Start to scan Initiator */ -+ if (prBowFsmInfo->ucRole == BOW_RESPONDER) { -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "bowStarting responder, start scan result searching.\n"); -+#endif -+ cnmTimerStopTimer(prAdapter, &prBowFsmInfo->rChGrantedTimer); -+ bowReleaseCh(prAdapter); -+ bowResponderScan(prAdapter); -+ } -+ /*Initiator: Request channel, wait for responder */ -+ else { -+ /* Todo:: Nothing*/ -+ /* bowRequestCh(prAdapter); */ -+ } -+#endif -+ -+} -+ -+VOID bowAssignSsid(IN PUINT_8 pucSsid, IN PUINT_8 puOwnMacAddr) -+{ -+ UINT_8 i; -+ UINT_8 aucSSID[] = BOW_WILDCARD_SSID; -+ -+ kalMemCopy(pucSsid, aucSSID, BOW_WILDCARD_SSID_LEN); -+ -+ for (i = 0; i < 6; i++) { -+ pucSsid[(3 * i) + 3] = 0x2D; -+ if ((*(puOwnMacAddr + i) >> 4) < 0xA) -+ *(pucSsid + (3 * i) + 4) = (*(puOwnMacAddr + i) >> 4) + 0x30; -+ else -+ *(pucSsid + (3 * i) + 4) = (*(puOwnMacAddr + i) >> 4) + 0x57; -+ -+ if ((*(puOwnMacAddr + i) & 0x0F) < 0xA) -+ pucSsid[(3 * i) + 5] = (*(puOwnMacAddr + i) & 0x0F) + 0x30; -+ else -+ pucSsid[(3 * i) + 5] = (*(puOwnMacAddr + i) & 0x0F) + 0x57; -+ } -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will validate the Rx Probe Request Frame and then return -+* result to BSS to indicate if need to send the corresponding Probe Response -+* Frame if the specified conditions were matched. -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* @param[in] prSwRfb Pointer to SW RFB data structure. -+* @param[out] pu4ControlFlags Control flags for replying the Probe Response -+* -+* @retval TRUE Reply the Probe Response -+* @retval FALSE Don't reply the Probe Response -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN bowValidateProbeReq(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, OUT PUINT_32 pu4ControlFlags) -+{ -+ P_WLAN_MAC_MGMT_HEADER_T prMgtHdr; -+ P_BOW_FSM_INFO_T prBowFsmInfo; -+ P_BSS_INFO_T prBssInfo; -+ P_IE_SSID_T prIeSsid = (P_IE_SSID_T) NULL; -+ PUINT_8 pucIE; -+ UINT_16 u2IELength; -+ UINT_16 u2Offset = 0; -+ BOOLEAN fgReplyProbeResp = FALSE; -+ -+ ASSERT(prSwRfb); -+ ASSERT(pu4ControlFlags); -+ -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_BOW_INDEX]); -+ prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); -+ -+#if 0 /* CFG_BOW_TEST */ -+ DBGLOG(BOW, EVENT, "bowValidateProbeReq.\n"); -+#endif -+ -+ /* 4 <1> Parse Probe Req IE and Get IE ptr (SSID, Supported Rate IE, ...) */ -+ prMgtHdr = (P_WLAN_MAC_MGMT_HEADER_T) prSwRfb->pvHeader; -+ -+ u2IELength = prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen; -+ pucIE = (PUINT_8) ((ULONG) prSwRfb->pvHeader + prSwRfb->u2HeaderLen); -+ -+ IE_FOR_EACH(pucIE, u2IELength, u2Offset) { -+ if (ELEM_ID_SSID == IE_ID(pucIE)) { -+ if ((!prIeSsid) && (IE_LEN(pucIE) <= ELEM_MAX_LEN_SSID)) -+ prIeSsid = (P_IE_SSID_T) pucIE; -+ break; -+ } -+ } /* end of IE_FOR_EACH */ -+ -+ IE_FOR_EACH(pucIE, u2IELength, u2Offset) { -+ if (ELEM_ID_SSID == IE_ID(pucIE)) { -+ if ((!prIeSsid) && (IE_LEN(pucIE) <= ELEM_MAX_LEN_SSID)) -+ prIeSsid = (P_IE_SSID_T) pucIE; -+ break; -+ } -+ } /* end of IE_FOR_EACH */ -+ -+ /* 4 <2> Check network conditions */ -+ /*If BoW AP is beaconing */ -+ if (prBssInfo->eCurrentOPMode == OP_MODE_BOW && g_u4Beaconing > 0) { -+ -+ /*Check the probe requset sender is our peer */ -+ if (bowCheckBowTableIfVaild(prAdapter, prMgtHdr->aucSrcAddr)) -+ fgReplyProbeResp = TRUE; -+ /*Check the probe request target SSID is our SSID */ -+ else if ((prIeSsid) && -+ EQUAL_SSID(prBssInfo->aucSSID, prBssInfo->ucSSIDLen, prIeSsid->aucSSID, prIeSsid->ucLength)) -+ fgReplyProbeResp = TRUE; -+ else -+ fgReplyProbeResp = FALSE; -+ } -+ -+ return fgReplyProbeResp; -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will indicate an Event of "Media Disconnect" to HOST -+* -+* @param[in] u4Param Unused timer parameter -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID bowSendBeacon(IN P_ADAPTER_T prAdapter, IN ULONG ulParam) -+{ -+ P_BOW_FSM_INFO_T prBowFsmInfo; -+ -+ prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); -+ -+ if ((g_u4Beaconing != 0) && (g_u4LinkCount > 0) && (g_u4LinkCount < CFG_BOW_PHYSICAL_LINK_NUM)) { -+ /* Send beacon */ -+ bssSendBeaconProbeResponse(prAdapter, NETWORK_TYPE_BOW_INDEX, NULL, 0); -+ cnmTimerStartTimer(prAdapter, &prBowFsmInfo->rStartingBeaconTimer, prBowFsmInfo->u2BeaconInterval); -+ } -+#if CFG_BOW_TEST -+ else -+ kalPrint("BoW Send Beacon,[%d,%d]\n", g_u4LinkCount, g_u4Beaconing); -+#endif -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will indicate an Event of "Media Disconnect" to HOST -+* -+* @param[in] u4Param Unused timer parameter -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID bowResponderScan(IN P_ADAPTER_T prAdapter) -+{ -+ P_BOW_FSM_INFO_T prBowFsmInfo; -+ P_MSG_SCN_SCAN_REQ prScanReqMsg; -+ P_BSS_INFO_T prBssInfo; -+ -+ ASSERT(prAdapter); -+ -+ prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_BOW_INDEX]); -+ -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "bowResponderScan.\n"); -+ kalPrint("BOW SCAN [REQ:%d]\n", prBowFsmInfo->ucSeqNumOfScanReq + 1); -+#endif -+ -+ prScanReqMsg = (P_MSG_SCN_SCAN_REQ) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_SCN_SCAN_REQ)); -+ -+ if (!prScanReqMsg) { -+ ASSERT(0); /* Can't trigger SCAN FSM */ -+ return; -+ } -+ -+ /*Fill scan message */ -+ prScanReqMsg->rMsgHdr.eMsgId = MID_BOW_SCN_SCAN_REQ; -+ prScanReqMsg->ucSeqNum = ++prBowFsmInfo->ucSeqNumOfScanReq; -+ prScanReqMsg->ucNetTypeIndex = (UINT_8) NETWORK_TYPE_BOW_INDEX; -+ prScanReqMsg->eScanType = SCAN_TYPE_ACTIVE_SCAN; -+ prScanReqMsg->ucSSIDType = SCAN_REQ_SSID_SPECIFIED; -+ prScanReqMsg->ucSSIDLength = BOW_SSID_LEN; -+ bowAssignSsid(prScanReqMsg->aucSSID, prBowFsmInfo->aucPeerAddress); -+ prScanReqMsg->ucChannelListNum = 1; -+ -+ if (prBowFsmInfo->eBand == BAND_2G4) { -+ prScanReqMsg->eScanChannel = SCAN_CHANNEL_SPECIFIED; -+ prScanReqMsg->arChnlInfoList[0].eBand = BAND_2G4; -+ } else { -+ prScanReqMsg->eScanChannel = SCAN_CHANNEL_5G; -+ prScanReqMsg->arChnlInfoList[0].eBand = BAND_5G; -+ } -+ -+ prScanReqMsg->arChnlInfoList[0].ucChannelNum = prBowFsmInfo->ucPrimaryChannel; -+ prScanReqMsg->u2IELen = 0; -+ -+ /*Send scan message */ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prScanReqMsg, MSG_SEND_METHOD_BUF); -+ -+ /*Change state to SCANNING */ -+ bowSetBowTableState(prAdapter, prBowFsmInfo->aucPeerAddress, BOW_DEVICE_STATE_SCANNING); -+ -+ /* prBowFsmInfo->fgTryScan = FALSE; */ /* Will enable background sleep for infrastructure */ -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID bowResponderScanDone(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) -+{ -+ P_MSG_SCN_SCAN_DONE prScanDoneMsg; -+ P_BOW_FSM_INFO_T prBowFsmInfo; -+ P_BSS_DESC_T prBssDesc; -+ UINT_8 ucSeqNumOfCompMsg; -+ P_CONNECTION_SETTINGS_T prConnSettings; -+ ENUM_BOW_DEVICE_STATE eFsmState; -+ ENUM_SCAN_STATUS eScanStatus; -+ -+ ASSERT(prAdapter); -+ ASSERT(prMsgHdr); -+ -+ prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); -+ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); -+ prScanDoneMsg = (P_MSG_SCN_SCAN_DONE) prMsgHdr; -+ eFsmState = bowGetBowTableState(prAdapter, prBowFsmInfo->aucPeerAddress); -+ -+ ASSERT(prScanDoneMsg->ucNetTypeIndex == NETWORK_TYPE_BOW_INDEX); -+ -+ ucSeqNumOfCompMsg = prScanDoneMsg->ucSeqNum; -+ eScanStatus = prScanDoneMsg->eScanStatus; -+ -+ cnmMemFree(prAdapter, prMsgHdr); -+ -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "bowResponderScanDone.\n"); -+ kalPrint("BOW SCAN [DONE:%d]\n", ucSeqNumOfCompMsg); -+#endif -+ -+ if (eScanStatus == SCAN_STATUS_CANCELLED) { -+#if CFG_BOW_TEST -+ kalPrint("BOW SCAN [CANCELLED:%d]\n", ucSeqNumOfCompMsg); -+#endif -+ if (eFsmState == BOW_DEVICE_STATE_DISCONNECTING) { -+ wlanoidSendSetQueryBowCmd(prAdapter, -+ CMD_ID_CMD_BT_OVER_WIFI, -+ TRUE, -+ FALSE, -+ wlanbowCmdEventLinkDisconnected, -+ wlanbowCmdTimeoutHandler, 0, NULL, 0); -+ } -+ return; -+ } else if (eFsmState == BOW_DEVICE_STATE_DISCONNECTED) { -+ /* bowDisconnectLink(prAdapter, NULL, TX_RESULT_SUCCESS); */ -+ return; -+ } else if (ucSeqNumOfCompMsg != prBowFsmInfo->ucSeqNumOfScanReq) { -+ DBGLOG(BOW, EVENT, "Sequence no. of BOW Responder scan done is not matched.\n"); -+ return; -+ } -+ prConnSettings->fgIsScanReqIssued = FALSE; -+ prBssDesc = scanSearchBssDescByBssid(prAdapter, prBowFsmInfo->aucPeerAddress); -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "End scan result searching.\n"); -+#endif -+ -+ /* Initiator is FOUND */ -+ if (prBssDesc != NULL) { -+ /* (prBssDesc->aucBSSID != NULL)) */ -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "Search Bow Peer address - %x:%x:%x:%x:%x:%x.\n", prBssDesc->aucBSSID[0], -+ prBssDesc->aucBSSID[1], -+ prBssDesc->aucBSSID[2], -+ prBssDesc->aucBSSID[3], prBssDesc->aucBSSID[4], prBssDesc->aucBSSID[5]); -+ DBGLOG(BOW, EVENT, "Starting to join initiator.\n"); -+#endif -+ /*Set target BssDesc */ -+ prBowFsmInfo->prTargetBssDesc = prBssDesc; -+ /*Request channel to do JOIN */ -+ bowSetBowTableState(prAdapter, prBowFsmInfo->aucPeerAddress, -+ BOW_DEVICE_STATE_ACQUIRING_CHANNEL); -+ bowRequestCh(prAdapter); -+ } -+ /*Initiator is NOT FOUND */ -+ else { -+ /*Scan again, until PAL timeout */ -+ bowResponderScan(prAdapter); -+#if 0 -+ wlanoidSendSetQueryBowCmd(prAdapter, -+ CMD_ID_CMD_BT_OVER_WIFI, -+ TRUE, -+ FALSE, -+ wlanbowCmdEventLinkDisconnected, -+ wlanbowCmdTimeoutHandler, 0, NULL, 0); -+#endif -+ } -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Function for cancelling scan request. There is another option to extend channel privilige -+* for another purpose. -+* -+* @param fgIsChannelExtention - Keep the channel previlege, but can cancel scan timer. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID bowResponderCancelScan(IN P_ADAPTER_T prAdapter, IN BOOLEAN fgIsChannelExtention) -+{ -+ -+ P_MSG_SCN_SCAN_CANCEL prScanCancel = (P_MSG_SCN_SCAN_CANCEL) NULL; -+ P_BOW_FSM_INFO_T prBowFsmInfo = (P_BOW_FSM_INFO_T) NULL; -+ -+ DEBUGFUNC("bowResponderCancelScan()"); -+ -+ do { -+ ASSERT(prAdapter); -+ -+ prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); -+ -+ if (TRUE) { -+#if CFG_BOW_TEST -+ kalPrint("BOW SCAN [CANCEL:%d]\n", prBowFsmInfo->ucSeqNumOfScanReq); -+#endif -+ /* There is a channel privilege on hand. */ -+ -+ DBGLOG(P2P, TRACE, "BOW Cancel Scan\n"); -+ -+ prScanCancel = -+ (P_MSG_SCN_SCAN_CANCEL) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_SCN_SCAN_CANCEL)); -+ if (!prScanCancel) { -+ /* Buffer not enough, can not cancel scan request. */ -+ DBGLOG(P2P, TRACE, "Buffer not enough, can not cancel scan.\n"); -+ ASSERT(FALSE); -+ break; -+ } -+ -+ prScanCancel->rMsgHdr.eMsgId = MID_BOW_SCN_SCAN_CANCEL; -+ prScanCancel->ucNetTypeIndex = NETWORK_TYPE_BOW_INDEX; -+ prScanCancel->ucSeqNum = prBowFsmInfo->ucSeqNumOfScanReq; -+#if CFG_ENABLE_WIFI_DIRECT -+ prScanCancel->fgIsChannelExt = fgIsChannelExtention; -+#endif -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prScanCancel, MSG_SEND_METHOD_BUF); -+ -+ } -+ -+ } while (FALSE); -+ -+} /* bowResponderCancelScan */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Initialization of JOIN STATE -+* -+* @param[in] prBssDesc The pointer of BSS_DESC_T which is the BSS we will try to join with. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID bowResponderJoin(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBssDesc) -+{ -+ P_BOW_FSM_INFO_T prBowFsmInfo; -+ P_BSS_INFO_T prBssInfo; -+ P_CONNECTION_SETTINGS_T prConnSettings; -+ P_STA_RECORD_T prStaRec; -+ P_MSG_JOIN_REQ_T prJoinReqMsg; -+ -+ ASSERT(prBssDesc); -+ ASSERT(prAdapter); -+ -+ DBGLOG(BOW, EVENT, "Starting bowResponderJoin.\n"); -+ -+ prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_BOW_INDEX]); -+ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); -+ -+ /* 4 <1> We are going to connect to this BSS. */ -+ prBssDesc->fgIsConnecting = TRUE; -+ bowSetBowTableState(prAdapter, prBowFsmInfo->aucPeerAddress, BOW_DEVICE_STATE_CONNECTING); -+ -+ /* 4 <2> Setup corresponding STA_RECORD_T */ -+ /*Support First JOIN and retry */ -+ prStaRec = bssCreateStaRecFromBssDesc(prAdapter, STA_TYPE_BOW_AP, NETWORK_TYPE_BOW_INDEX, prBssDesc); -+ if (!prStaRec) -+ return; -+ -+ prBowFsmInfo->prTargetStaRec = prStaRec; -+ -+ /* 4 <3> Update ucAvailableAuthTypes which we can choice during SAA */ -+ prStaRec->fgIsReAssoc = FALSE; -+ prBowFsmInfo->ucAvailableAuthTypes = (UINT_8) AUTH_TYPE_OPEN_SYSTEM; -+ prStaRec->ucTxAuthAssocRetryLimit = TX_AUTH_ASSOCI_RETRY_LIMIT; -+ -+ /* 4 <4> Use an appropriate Authentication Algorithm Number among the ucAvailableAuthTypes */ -+ if (prBowFsmInfo->ucAvailableAuthTypes & (UINT_8) AUTH_TYPE_OPEN_SYSTEM) { -+ -+ DBGLOG(BOW, LOUD, "JOIN INIT: Try to do Authentication with AuthType == OPEN_SYSTEM.\n"); -+ prBowFsmInfo->ucAvailableAuthTypes &= ~(UINT_8) AUTH_TYPE_OPEN_SYSTEM; -+ -+ prStaRec->ucAuthAlgNum = (UINT_8) AUTH_ALGORITHM_NUM_OPEN_SYSTEM; -+ } else { -+ ASSERT(0); -+ } -+ -+ /* 4 <4.1> sync. to firmware domain */ -+ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); -+ -+ /* 4 <5> Overwrite Connection Setting for eConnectionPolicy */ -+ if (prBssDesc->ucSSIDLen) { -+ COPY_SSID(prConnSettings->aucSSID, prConnSettings->ucSSIDLen, prBssDesc->aucSSID, prBssDesc->ucSSIDLen); -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "bowResponderJoin, SSID %s.\n", prBssDesc->aucSSID); -+ DBGLOG(BOW, EVENT, "bowResponderJoin, SSID %s.\n", prConnSettings->aucSSID); -+#endif -+ } -+ /* 4 <6> Send a Msg to trigger SAA to start JOIN process. */ -+ prJoinReqMsg = (P_MSG_JOIN_REQ_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_JOIN_REQ_T)); -+ if (!prJoinReqMsg) { -+ -+ ASSERT(0); /* Can't trigger SAA FSM */ -+ return; -+ } -+ -+ prJoinReqMsg->rMsgHdr.eMsgId = MID_BOW_SAA_FSM_START; -+ prJoinReqMsg->ucSeqNum = ++prBowFsmInfo->ucSeqNumOfReqMsg; -+ prJoinReqMsg->prStaRec = prStaRec; -+ -+ prBssInfo->prStaRecOfAP = prStaRec; -+ -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "prStaRec->eStaType, %x.\n", prStaRec->eStaType); -+ DBGLOG(BOW, INFO, "BoW trigger SAA [%pM]\n", prStaRec->aucMacAddr); -+#endif -+ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prJoinReqMsg, MSG_SEND_METHOD_BUF); -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will handle the Join Complete Event from SAA FSM for BOW FSM -+* -+* @param[in] prMsgHdr Message of Join Complete of SAA FSM. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID bowFsmRunEventJoinComplete(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) -+{ -+ P_MSG_JOIN_COMP_T prJoinCompMsg; -+ P_BOW_FSM_INFO_T prBowFsmInfo; -+ P_STA_RECORD_T prStaRec; -+ P_SW_RFB_T prAssocRspSwRfb; -+ P_BSS_INFO_T prBssInfo; -+ P_WLAN_ASSOC_RSP_FRAME_T prAssocRspFrame = (P_WLAN_ASSOC_RSP_FRAME_T) NULL; -+ UINT_16 u2IELength; -+ PUINT_8 pucIE; -+ P_BSS_INFO_T prBowBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_BOW_INDEX]); -+ -+ ASSERT(prAdapter); -+ ASSERT(prMsgHdr); -+ -+ prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); -+ prJoinCompMsg = (P_MSG_JOIN_COMP_T) prMsgHdr; -+ prStaRec = prJoinCompMsg->prStaRec; -+ -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "Start bowfsmRunEventJoinComplete.\n"); -+ DBGLOG(BOW, EVENT, "bowfsmRunEventJoinComplete ptr check\n"); -+ DBGLOG(BOW, EVENT, "prMsgHdr %x\n", prMsgHdr); -+ DBGLOG(BOW, EVENT, "prAdapter %x\n", prAdapter); -+ DBGLOG(BOW, EVENT, "prBowFsmInfo %x\n", prBowFsmInfo); -+ DBGLOG(BOW, EVENT, "prStaRec %x\n", prStaRec); -+#endif -+ -+ ASSERT(prStaRec); -+ ASSERT(prBowFsmInfo); -+ -+ /* Check SEQ NUM */ -+ if (prJoinCompMsg->ucSeqNum == prBowFsmInfo->ucSeqNumOfReqMsg) { -+ COPY_MAC_ADDR(prBowFsmInfo->aucPeerAddress, prStaRec->aucMacAddr); -+ -+ /* 4 <1> JOIN was successful */ -+ if (prJoinCompMsg->rJoinStatus == WLAN_STATUS_SUCCESS) { -+ prAssocRspSwRfb = prJoinCompMsg->prSwRfb; -+ prAssocRspFrame = (P_WLAN_ASSOC_RSP_FRAME_T) prAssocRspSwRfb->pvHeader; -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_BOW_INDEX]); -+ -+ u2IELength = (UINT_16) ((prAssocRspSwRfb->u2PacketLen - prAssocRspSwRfb->u2HeaderLen) - -+ (OFFSET_OF(WLAN_ASSOC_RSP_FRAME_T, aucInfoElem[0]) - -+ WLAN_MAC_MGMT_HEADER_LEN)); -+ pucIE = prAssocRspFrame->aucInfoElem; -+ -+ prStaRec->eStaType = STA_TYPE_BOW_AP; -+ prStaRec->u2DesiredNonHTRateSet &= prBowBssInfo->u2OperationalRateSet; -+ prStaRec->ucDesiredPhyTypeSet = prStaRec->ucPhyTypeSet & prBowBssInfo->ucPhyTypeSet; -+#if CFG_BOW_RATE_LIMITATION -+ /* 4 <1.2>Update Rate Set */ -+ /*Limit Rate Set to 24M, 48M, 54M */ -+ prStaRec->u2DesiredNonHTRateSet &= (RATE_SET_BIT_24M | RATE_SET_BIT_48M | RATE_SET_BIT_54M); -+ /*If peer cannot support the above rate set, fix on the available highest rate */ -+ if (prStaRec->u2DesiredNonHTRateSet == 0) { -+ UINT_8 ucHighestRateIndex; -+ -+ if (rateGetHighestRateIndexFromRateSet -+ (prBowBssInfo->u2OperationalRateSet, &ucHighestRateIndex)) { -+ prStaRec->u2DesiredNonHTRateSet = BIT(ucHighestRateIndex); -+ } -+ } -+#endif -+ -+ /* 4 <1.1> Change FW's Media State immediately. */ -+ bowChangeMediaState(prAdapter, PARAM_MEDIA_STATE_CONNECTED); -+ -+ mqmProcessAssocRsp(prAdapter, prAssocRspSwRfb, pucIE, u2IELength); -+ -+ /* 4 <1.2> Update HT information and set channel */ -+ /* Record HT related parameters in rStaRec and rBssInfo -+ * Note: it shall be called before nicUpdateBss() -+ */ -+#if CFG_BOW_SUPPORT_11N -+ rlmProcessAssocRsp(prAdapter, prAssocRspSwRfb, pucIE, u2IELength); -+#endif -+ -+ /* 4 <1.3> Update BSS_INFO_T */ -+ nicUpdateBss(prAdapter, NETWORK_TYPE_BOW_INDEX); -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "Finish bowUpdateBssInfoForJOIN.\n"); -+#endif -+ /* 4 <1.4> Activate current AP's STA_RECORD_T in Driver. */ -+ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_3); -+ -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "bowFsmRunEventJoinComplete, qmActivateStaRec.\n"); -+#endif -+ -+ /* 4 <1.7> Set the Next State of BOW FSM */ -+ wlanoidSendSetQueryBowCmd(prAdapter, -+ CMD_ID_CMD_BT_OVER_WIFI, -+ TRUE, -+ FALSE, -+ wlanbowCmdEventLinkConnected, wlanbowCmdTimeoutHandler, 0, NULL, 0); -+ } -+ /* 4 <2> JOIN was not successful */ -+ else { -+ /*Retry */ -+ bowResponderJoin(prAdapter, prBowFsmInfo->prTargetBssDesc); -+#if 0 -+ wlanoidSendSetQueryBowCmd(prAdapter, -+ CMD_ID_CMD_BT_OVER_WIFI, -+ TRUE, -+ FALSE, -+ wlanbowCmdEventLinkDisconnected, -+ wlanbowCmdTimeoutHandler, 0, NULL, 0); -+#endif -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "Start bowfsmRunEventJoinComplete -- Join failed.\n"); -+ DBGLOG(BOW, INFO, "BoW trigger SAA REJOIN\n"); -+#endif -+ } -+ } -+ -+ cnmMemFree(prAdapter, prMsgHdr); -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will indicate the Media State to HOST -+* -+* @param[in] eConnectionState Current Media State -+* @param[in] fgDelayIndication Set TRUE for postponing the Disconnect Indication. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+bowIndicationOfMediaStateToHost(IN P_ADAPTER_T prAdapter, -+ IN ENUM_PARAM_MEDIA_STATE_T eConnectionState, IN BOOLEAN fgDelayIndication) -+{ -+ EVENT_CONNECTION_STATUS rEventConnStatus; -+ P_CONNECTION_SETTINGS_T prConnSettings; -+ P_BSS_INFO_T prBssInfo; -+ P_BOW_FSM_INFO_T prBowFsmInfo; -+ -+ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_BOW_INDEX]); -+ prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); -+ -+ /* NOTE(Kevin): Move following line to bowChangeMediaState() macro per CM's request. */ -+ /* prBowBssInfo->eConnectionState = eConnectionState; */ -+ -+ /* For indicating the Disconnect Event only if current media state is -+ * disconnected and we didn't do indication yet. -+ */ -+ if (prBssInfo->eConnectionState == PARAM_MEDIA_STATE_DISCONNECTED) { -+ if (prBssInfo->eConnectionStateIndicated == eConnectionState) -+ return; -+ } -+ -+ if (!fgDelayIndication) { -+ /* 4 <0> Cancel Delay Timer */ -+ cnmTimerStopTimer(prAdapter, &prBowFsmInfo->rIndicationOfDisconnectTimer); -+ -+ /* 4 <1> Fill EVENT_CONNECTION_STATUS */ -+ rEventConnStatus.ucMediaStatus = (UINT_8) eConnectionState; -+ -+ if (eConnectionState == PARAM_MEDIA_STATE_CONNECTED) { -+ rEventConnStatus.ucReasonOfDisconnect = DISCONNECT_REASON_CODE_RESERVED; -+ -+ if (prBssInfo->eCurrentOPMode == OP_MODE_BOW) { -+ rEventConnStatus.ucInfraMode = (UINT_8) NET_TYPE_INFRA; -+ rEventConnStatus.u2AID = prBssInfo->u2AssocId; -+ rEventConnStatus.u2ATIMWindow = 0; -+ } else if (prBssInfo->eCurrentOPMode == OP_MODE_IBSS) { -+ rEventConnStatus.ucInfraMode = (UINT_8) NET_TYPE_IBSS; -+ rEventConnStatus.u2AID = 0; -+ rEventConnStatus.u2ATIMWindow = prBssInfo->u2ATIMWindow; -+ } else { -+ ASSERT(0); -+ } -+ -+ COPY_SSID(rEventConnStatus.aucSsid, -+ rEventConnStatus.ucSsidLen, prConnSettings->aucSSID, prConnSettings->ucSSIDLen); -+ -+ COPY_MAC_ADDR(rEventConnStatus.aucBssid, prBssInfo->aucBSSID); -+ -+ rEventConnStatus.u2BeaconPeriod = prBssInfo->u2BeaconInterval; -+ rEventConnStatus.u4FreqInKHz = nicChannelNum2Freq(prBssInfo->ucPrimaryChannel); -+ -+ switch (prBssInfo->ucNonHTBasicPhyType) { -+ case PHY_TYPE_HR_DSSS_INDEX: -+ rEventConnStatus.ucNetworkType = (UINT_8) PARAM_NETWORK_TYPE_DS; -+ break; -+ -+ case PHY_TYPE_ERP_INDEX: -+ rEventConnStatus.ucNetworkType = (UINT_8) PARAM_NETWORK_TYPE_OFDM24; -+ break; -+ -+ case PHY_TYPE_OFDM_INDEX: -+ rEventConnStatus.ucNetworkType = (UINT_8) PARAM_NETWORK_TYPE_OFDM5; -+ break; -+ -+ default: -+ ASSERT(0); -+ rEventConnStatus.ucNetworkType = (UINT_8) PARAM_NETWORK_TYPE_DS; -+ break; -+ } -+ } else { -+#if CFG_PRIVACY_MIGRATION -+ /* Clear the pmkid cache while media disconnect */ -+ secClearPmkid(prAdapter); -+#endif -+ -+ rEventConnStatus.ucReasonOfDisconnect = prBssInfo->ucReasonOfDisconnect; -+ -+ } -+ -+ /* 4 <2> Indication */ -+ nicMediaStateChange(prAdapter, NETWORK_TYPE_BOW_INDEX, &rEventConnStatus); -+ prBssInfo->eConnectionStateIndicated = eConnectionState; -+ } else { -+ /* NOTE: Only delay the Indication of Disconnect Event */ -+ ASSERT(eConnectionState == PARAM_MEDIA_STATE_DISCONNECTED); -+ -+ DBGLOG(BOW, INFO, "Postpone the indication of Disconnect for %d seconds\n", -+ prConnSettings->ucDelayTimeOfDisconnectEvent); -+ -+ cnmTimerStartTimer(prAdapter, -+ &prBowFsmInfo->rIndicationOfDisconnectTimer, -+ SEC_TO_MSEC(prConnSettings->ucDelayTimeOfDisconnectEvent)); -+ } -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will indicate the Event of Tx Fail of AAA Module. -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* @param[in] prStaRec Pointer to the STA_RECORD_T -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID bowRunEventAAATxFail(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec) -+{ -+ P_BSS_INFO_T prBssInfo; -+ -+ ASSERT(prAdapter); -+ ASSERT(prStaRec); -+ -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "bowRunEventAAATxFail , bssRemoveStaRecFromClientList.\n"); -+ DBGLOG(BOW, INFO, "BoW AAA TxFail, target state %d\n", prStaRec->ucStaState + 1); -+#endif -+ -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]); -+ bssRemoveStaRecFromClientList(prAdapter, prBssInfo, prStaRec); -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will indicate the Event of Successful Completion of AAA Module. -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* @param[in] prStaRec Pointer to the STA_RECORD_T -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS bowRunEventAAAComplete(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec) -+{ -+ P_BOW_FSM_INFO_T prBowFsmInfo; -+ -+ ASSERT(prStaRec); -+ -+ prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); -+ -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "bowRunEventAAAComplete, cnmStaRecChangeState, STA_STATE_3.\n"); -+ DBGLOG(BOW, INFO, "BoW AAA complete [%pM]\n", prStaRec->aucMacAddr); -+#endif -+ -+ /*Update BssInfo to connected */ -+ bowChangeMediaState(prAdapter, PARAM_MEDIA_STATE_CONNECTED); -+ nicUpdateBss(prAdapter, NETWORK_TYPE_BOW_INDEX); -+ -+ /*Update StaRec to State3 */ -+ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_3); -+ -+ /*Connected */ -+ wlanoidSendSetQueryBowCmd(prAdapter, -+ CMD_ID_CMD_BT_OVER_WIFI, -+ TRUE, FALSE, wlanbowCmdEventLinkConnected, wlanbowCmdTimeoutHandler, 0, NULL, 0); -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will handle RxDeauth -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* @param[in] prStaRec Pointer to the STA_RECORD_T -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+ -+WLAN_STATUS bowRunEventRxDeAuth(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN P_SW_RFB_T prSwRfb) -+{ -+ P_BSS_INFO_T prBowBssInfo; -+ P_BOW_FSM_INFO_T prBowFsmInfo; -+ ENUM_BOW_DEVICE_STATE eFsmState; -+ -+ ASSERT(prAdapter); -+ -+ prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); -+ prBowBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_BOW_INDEX]); -+ -+ if (!IS_STA_IN_BOW(prStaRec)) -+ return WLAN_STATUS_NOT_ACCEPTED; -+ -+ eFsmState = bowGetBowTableState(prAdapter, prStaRec->aucMacAddr); -+ -+ if (eFsmState == BOW_DEVICE_STATE_DISCONNECTED) { -+ /*do nothing */ -+ return WLAN_STATUS_NOT_ACCEPTED; -+ } -+ -+ if (prStaRec->ucStaState > STA_STATE_1) { -+ -+ if (STA_STATE_3 == prStaRec->ucStaState) { -+ /* P_MSG_AIS_ABORT_T prAisAbortMsg; */ -+ -+ /* NOTE(Kevin): Change state immediately to avoid starvation of -+ * MSG buffer because of too many deauth frames before changing -+ * the STA state. -+ */ -+ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); -+ } -+ -+ COPY_MAC_ADDR(prBowFsmInfo->aucPeerAddress, prStaRec->aucMacAddr); -+ -+ wlanoidSendSetQueryBowCmd(prAdapter, -+ CMD_ID_CMD_BT_OVER_WIFI, -+ TRUE, -+ FALSE, wlanbowCmdEventLinkDisconnected, wlanbowCmdTimeoutHandler, 0, NULL, 0); -+ -+ return WLAN_STATUS_SUCCESS; -+ } -+ -+ return WLAN_STATUS_NOT_ACCEPTED; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function handle BoW Link disconnect. -+* -+* \param[in] pMsduInfo Pointer to the Msdu Info -+* \param[in] rStatus The Tx done status -+* -+* \return - -+* -+* \note after receive deauth frame, callback function call this -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID bowDisconnectLink(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus) -+{ -+ P_BOW_FSM_INFO_T prBowFsmInfo; -+ P_STA_RECORD_T prStaRec; -+ -+ ASSERT(prAdapter); -+ -+ prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); -+ -+ /*Free target StaRec */ -+ if (prMsduInfo) -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); -+ else -+ prStaRec = prBowFsmInfo->prTargetStaRec; -+ -+ if (prStaRec) -+ /* cnmStaRecFree(prAdapter, prStaRec, TRUE); */ -+ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); -+ kalPrint("bowDisconnectLink\n"); -+ /*No one connected */ -+ if (g_u4LinkCount == 0 && g_u4Beaconing != 0) { -+ cnmTimerStopTimer(prAdapter, &prBowFsmInfo->rStartingBeaconTimer); -+ bowStopping(prAdapter); -+ kalPrint("bowStopping\n"); -+ /*Restore TxPower from Short range mode */ -+#if CFG_SUPPORT_NVRAM && 0 -+ wlanLoadManufactureData(prAdapter, kalGetConfiguration(prAdapter->prGlueInfo)); -+#endif -+ /*Uninit BoW Interface */ -+#if CFG_BOW_SEPARATE_DATA_PATH -+ kalUninitBowDevice(prAdapter->prGlueInfo); -+#endif -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will validate the Rx Assoc Req Frame and then return -+* the status code to AAA to indicate if need to perform following actions -+* when the specified conditions were matched. -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* @param[in] prSwRfb Pointer to SW RFB data structure. -+* @param[out] pu2StatusCode The Status Code of Validation Result -+* -+* @retval TRUE Reply the Assoc Resp -+* @retval FALSE Don't reply the Assoc Resp -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN bowValidateAssocReq(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, OUT PUINT_16 pu2StatusCode) -+{ -+ BOOLEAN fgReplyAssocResp = FALSE; -+ P_BSS_INFO_T prBowBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_BOW_INDEX]); -+ P_STA_RECORD_T prStaRec = (P_STA_RECORD_T) NULL; -+ P_BOW_FSM_INFO_T prBowFsmInfo; -+ P_WLAN_ASSOC_REQ_FRAME_T prAssocReqFrame = (P_WLAN_ASSOC_REQ_FRAME_T) NULL; -+ OS_SYSTIME rCurrentTime; -+ static OS_SYSTIME rLastRejectAssocTime; -+ -+ ASSERT(prAdapter); -+ -+ prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); -+ prAssocReqFrame = (P_WLAN_ASSOC_REQ_FRAME_T) prSwRfb->pvHeader; -+ *pu2StatusCode = STATUS_CODE_REQ_DECLINED; -+ -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "bowValidateAssocReq, prBowFsmInfo->aucPeerAddress, %x:%x:%x:%x:%x:%x.\n", -+ prBowFsmInfo->aucPeerAddress[0], -+ prBowFsmInfo->aucPeerAddress[1], -+ prBowFsmInfo->aucPeerAddress[2], -+ prBowFsmInfo->aucPeerAddress[3], -+ prBowFsmInfo->aucPeerAddress[4], prBowFsmInfo->aucPeerAddress[5])); -+ DBGLOG(BOW, EVENT, "bowValidateAssocReq, prAssocReqFrame->aucSrcAddr, %x:%x:%x:%x:%x:%x.\n", -+ prAssocReqFrame->aucSrcAddr[0], -+ prAssocReqFrame->aucSrcAddr[1], -+ prAssocReqFrame->aucSrcAddr[2], -+ prAssocReqFrame->aucSrcAddr[3], -+ prAssocReqFrame->aucSrcAddr[4], prAssocReqFrame->aucSrcAddr[5])); -+#endif -+ -+ /*Assoc Accept */ -+ while (EQUAL_MAC_ADDR(prAssocReqFrame->aucSrcAddr, prBowFsmInfo->aucPeerAddress)) { -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "bowValidateAssocReq, return wlanbowCmdEventLinkConnected.\n"); -+#endif -+ /*Update StaRec */ -+ prStaRec = cnmGetStaRecByAddress(prAdapter, -+ (UINT_8) NETWORK_TYPE_BOW_INDEX, prAssocReqFrame->aucSrcAddr); -+ if (!prStaRec) -+ break; -+ prStaRec->eStaType = STA_TYPE_BOW_CLIENT; -+ prStaRec->u2DesiredNonHTRateSet &= prBowBssInfo->u2OperationalRateSet; -+ prStaRec->ucDesiredPhyTypeSet = prStaRec->ucPhyTypeSet & prBowBssInfo->ucPhyTypeSet; -+ -+#if CFG_BOW_RATE_LIMITATION -+ /*Limit Rate Set to 24M, 48M, 54M */ -+ prStaRec->u2DesiredNonHTRateSet &= (RATE_SET_BIT_24M | RATE_SET_BIT_48M | RATE_SET_BIT_54M); -+ /*If peer cannot support the above rate set, fix on the available highest rate */ -+ if (prStaRec->u2DesiredNonHTRateSet == 0) { -+ UINT_8 ucHighestRateIndex; -+ -+ if (rateGetHighestRateIndexFromRateSet(prBowBssInfo->u2OperationalRateSet, &ucHighestRateIndex)) -+ prStaRec->u2DesiredNonHTRateSet = BIT(ucHighestRateIndex); -+ else { -+ /*If no available rate is found, DECLINE the association */ -+ *pu2StatusCode = STATUS_CODE_ASSOC_DENIED_RATE_NOT_SUPPORTED; -+ break; -+ } -+ } -+#endif -+ prStaRec->ucNetTypeIndex = NETWORK_TYPE_BOW_INDEX; -+ -+ /*Undpate BssInfo to FW */ -+ bowChangeMediaState(prAdapter, PARAM_MEDIA_STATE_CONNECTED); -+ nicUpdateBss(prAdapter, NETWORK_TYPE_BOW_INDEX); -+ -+ /*reply successful */ -+ *pu2StatusCode = STATUS_CODE_SUCCESSFUL; -+ fgReplyAssocResp = TRUE; -+ break; -+ } -+ -+ /*Reject Assoc */ -+ if (*pu2StatusCode != STATUS_CODE_SUCCESSFUL) { -+ /*Reply Assoc with reject every 5s */ -+ rCurrentTime = kalGetTimeTick(); -+ if (CHECK_FOR_TIMEOUT(rCurrentTime, rLastRejectAssocTime, MSEC_TO_SYSTIME(5000)) || -+ rLastRejectAssocTime == 0) { -+ fgReplyAssocResp = TRUE; -+ rLastRejectAssocTime = rCurrentTime; -+ } -+ } -+ -+ return fgReplyAssocResp; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will validate the Rx Auth Frame and then return -+* the status code to AAA to indicate if need to perform following actions -+* when the specified conditions were matched. -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* @param[in] prSwRfb Pointer to SW RFB data structure. -+* @param[in] pprStaRec Pointer to pointer of STA_RECORD_T structure. -+* @param[out] pu2StatusCode The Status Code of Validation Result -+* -+* @retval TRUE Reply the Auth -+* @retval FALSE Don't reply the Auth -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN -+bowValidateAuth(IN P_ADAPTER_T prAdapter, -+ IN P_SW_RFB_T prSwRfb, IN PP_STA_RECORD_T pprStaRec, OUT PUINT_16 pu2StatusCode) -+{ -+ BOOLEAN fgReplyAuth = FALSE; -+ P_BSS_INFO_T prBowBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_BOW_INDEX]); -+ P_STA_RECORD_T prStaRec = (P_STA_RECORD_T) NULL; -+ P_BOW_FSM_INFO_T prBowFsmInfo; -+ P_WLAN_AUTH_FRAME_T prAuthFrame = (P_WLAN_AUTH_FRAME_T) NULL; -+ OS_SYSTIME rCurrentTime; -+ static OS_SYSTIME rLastRejectAuthTime; -+ -+ /* TODO(Kevin): Call BoW functions to check .. -+ 1. Check we are BoW now. -+ 2. Check we can accept connection from thsi peer -+ 3. Check Black List here. -+ */ -+ -+ prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); -+ prAuthFrame = (P_WLAN_AUTH_FRAME_T) prSwRfb->pvHeader; -+ -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "bowValidateAuth, prBowFsmInfo->aucPeerAddress, %x:%x:%x:%x:%x:%x.\n", -+ prBowFsmInfo->aucPeerAddress[0], -+ prBowFsmInfo->aucPeerAddress[1], -+ prBowFsmInfo->aucPeerAddress[2], -+ prBowFsmInfo->aucPeerAddress[3], -+ prBowFsmInfo->aucPeerAddress[4], prBowFsmInfo->aucPeerAddress[5])); -+ DBGLOG(BOW, EVENT, "bowValidateAuth, prAuthFrame->aucSrcAddr, %x:%x:%x:%x:%x:%x.\n", -+ prAuthFrame->aucSrcAddr[0], -+ prAuthFrame->aucSrcAddr[1], -+ prAuthFrame->aucSrcAddr[2], -+ prAuthFrame->aucSrcAddr[3], prAuthFrame->aucSrcAddr[4], prAuthFrame->aucSrcAddr[5])); -+#endif -+ -+ prStaRec = cnmGetStaRecByAddress(prAdapter, (UINT_8) NETWORK_TYPE_BOW_INDEX, prAuthFrame->aucSrcAddr); -+ if (!prStaRec) { -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "bowValidateAuth, cnmStaRecAlloc.\n"); -+#endif -+ prStaRec = cnmStaRecAlloc(prAdapter, (UINT_8) NETWORK_TYPE_BOW_INDEX); -+ -+ /* TODO(Kevin): Error handling of allocation of STA_RECORD_T for -+ * exhausted case and do removal of unused STA_RECORD_T. -+ */ -+ if (!prStaRec) -+ return fgReplyAuth; -+ COPY_MAC_ADDR(prStaRec->aucMacAddr, prAuthFrame->aucSrcAddr); -+ prSwRfb->ucStaRecIdx = prStaRec->ucIndex; -+ prBowBssInfo->prStaRecOfAP = prStaRec; -+ -+ /* NOTE(Kevin): Better to change state here, not at TX Done */ -+ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "bowValidateAuth, cnmStaRecChangeState.\n"); -+#endif -+ } else { -+ prSwRfb->ucStaRecIdx = prStaRec->ucIndex; -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "bowValidateAuth, prStaRec->ucIndex, %x.\n", prStaRec->ucIndex); -+#endif -+ bssRemoveStaRecFromClientList(prAdapter, prBowBssInfo, prStaRec); -+ } -+ -+ if (EQUAL_MAC_ADDR(prAuthFrame->aucSrcAddr, prBowFsmInfo->aucPeerAddress)) { -+ -+ prStaRec->eStaType = STA_TYPE_BOW_CLIENT; -+ prStaRec->ucNetTypeIndex = NETWORK_TYPE_BOW_INDEX; -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "bowValidateAuth, prStaRec->eStaType, %x.\n", prStaRec->eStaType); -+ DBGLOG(BOW, EVENT, "bowValidateAuth, prStaRec->ucNetTypeIndex, %x.\n", prStaRec->ucNetTypeIndex); -+#endif -+ /* Update Station Record - Status/Reason Code */ -+ prStaRec->u2StatusCode = STATUS_CODE_SUCCESSFUL; -+ prStaRec->ucJoinFailureCount = 0; -+ *pprStaRec = prStaRec; -+ *pu2StatusCode = STATUS_CODE_SUCCESSFUL; -+ fgReplyAuth = TRUE; -+ } else { -+ cnmStaRecFree(prAdapter, prStaRec, FALSE); -+ *pu2StatusCode = STATUS_CODE_REQ_DECLINED; -+ -+ /*Reply auth with reject every 5s */ -+ rCurrentTime = kalGetTimeTick(); -+ if (CHECK_FOR_TIMEOUT(rCurrentTime, rLastRejectAuthTime, MSEC_TO_SYSTIME(5000)) || -+ rLastRejectAuthTime == 0) { -+ fgReplyAuth = TRUE; -+ rLastRejectAuthTime = rCurrentTime; -+ } -+ } -+ -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "bowValidateAuth, fgReplyAuth, %x.\n", fgReplyAuth); -+#endif -+ return fgReplyAuth; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is invoked when CNM granted channel privilege -+* -+* \param[in] prAdapter Pointer of ADAPTER_T -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID bowRunEventChGrant(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) -+{ -+ P_BSS_INFO_T prBowBssInfo; -+ P_BOW_FSM_INFO_T prBowFsmInfo; -+ P_MSG_CH_GRANT_T prMsgChGrant; -+ UINT_8 ucTokenID; -+ UINT_32 u4GrantInterval; -+ ENUM_BOW_DEVICE_STATE eFsmState; -+ -+ ASSERT(prAdapter); -+ ASSERT(prMsgHdr); -+ -+ prBowBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_BOW_INDEX]); -+ prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); -+ prMsgChGrant = (P_MSG_CH_GRANT_T) prMsgHdr; -+ ucTokenID = prMsgChGrant->ucTokenID; -+ u4GrantInterval = prMsgChGrant->u4GrantInterval; -+ -+ /* 1. free message */ -+ cnmMemFree(prAdapter, prMsgHdr); -+ prBowFsmInfo->fgIsChannelGranted = TRUE; -+ -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "Entering bowRunEventChGrant.\n"); -+#endif -+ -+ eFsmState = bowGetBowTableState(prAdapter, prBowFsmInfo->aucPeerAddress); -+ -+ /*Release channel */ -+ if ((!prBowFsmInfo->fgIsChannelRequested) || -+ (prBowFsmInfo->ucSeqNumOfChReq != ucTokenID) || -+ (eFsmState == BOW_DEVICE_STATE_DISCONNECTED) || (eFsmState == BOW_DEVICE_STATE_DISCONNECTING)) { -+#if CFG_BOW_TEST -+ DBGLOG(BOW, INFO, "BoW Channel [GIVE UP:%d]\n", ucTokenID); -+ DBGLOG(BOW, INFO, "[Requested:%d][ucSeqNumOfChReq:%d][eFsmState:%d]\n", -+ prBowFsmInfo->fgIsChannelRequested, prBowFsmInfo->ucSeqNumOfChReq, eFsmState); -+#endif -+ bowReleaseCh(prAdapter); -+ return; -+ } -+ -+ /* 2. channel privilege has been approved */ -+ prBowFsmInfo->u4ChGrantedInterval = u4GrantInterval; -+ -+#if 0 -+ cnmTimerStartTimer(prAdapter, -+ &prBowFsmInfo->rChGrantedTimer, -+ prBowFsmInfo->u4ChGrantedInterval - BOW_JOIN_CH_GRANT_THRESHOLD); -+#else -+ cnmTimerStartTimer(prAdapter, -+ &prBowFsmInfo->rChGrantedTimer, BOW_JOIN_CH_REQUEST_INTERVAL - BOW_JOIN_CH_GRANT_THRESHOLD); -+#endif -+ -+ /* 3.2 set local variable to indicate join timer is ticking */ -+ prBowFsmInfo->fgIsInfraChannelFinished = FALSE; -+ -+#if CFG_BOW_TEST -+ DBGLOG(BOW, INFO, "BoW Channel [GRANTED:%d].\n", ucTokenID); -+#endif -+ -+ if (eFsmState == BOW_DEVICE_STATE_ACQUIRING_CHANNEL) { -+ bowStarting(prAdapter); -+ bowReleaseCh(prAdapter); -+ if (prBowFsmInfo->ucRole == BOW_RESPONDER) -+ bowResponderJoin(prAdapter, prBowFsmInfo->prTargetBssDesc); -+ } else { -+ /*update bssinfo */ -+ nicUpdateBss(prAdapter, NETWORK_TYPE_BOW_INDEX); -+ bowReleaseCh(prAdapter); -+ } -+ -+} /* end of aisFsmRunEventChGrant() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is to inform CNM for channel privilege requesting -+* has been released -+* -+* \param[in] prAdapter Pointer of ADAPTER_T -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID bowRequestCh(IN P_ADAPTER_T prAdapter) -+{ -+ P_BOW_FSM_INFO_T prBowFsmInfo; -+ P_MSG_CH_REQ_T prMsgChReq; -+ -+ ASSERT(prAdapter); -+ -+ prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); -+ -+ if (prBowFsmInfo->fgIsChannelGranted == FALSE) { -+ -+#if CFG_BOW_TEST -+ DBGLOG(BOW, INFO, "BoW channel [REQUEST:%d], %d, %d.\n", prBowFsmInfo->ucSeqNumOfChReq + 1, -+ prBowFsmInfo->ucPrimaryChannel, prBowFsmInfo->eBand); -+#endif -+ prMsgChReq = (P_MSG_CH_REQ_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_CH_REQ_T)); -+ -+ if (!prMsgChReq) { -+ ASSERT(0); /* Can't indicate CNM for channel acquiring */ -+ return; -+ } -+ -+ prMsgChReq->rMsgHdr.eMsgId = MID_MNY_CNM_CH_REQ; -+ prMsgChReq->ucNetTypeIndex = NETWORK_TYPE_BOW_INDEX; -+ prMsgChReq->ucTokenID = ++prBowFsmInfo->ucSeqNumOfChReq; -+ prMsgChReq->eReqType = CH_REQ_TYPE_JOIN; -+#if 0 -+ prMsgChReq->u4MaxInterval = BOW_JOIN_CH_REQUEST_INTERVAL; -+#else -+ prMsgChReq->u4MaxInterval = 1; -+#endif -+ /* prBowFsmInfo->prTargetBssDesc->ucChannelNum; */ -+ prMsgChReq->ucPrimaryChannel = prBowFsmInfo->ucPrimaryChannel; -+ /* prBowFsmInfo->prTargetBssDesc->eSco; */ -+ prMsgChReq->eRfSco = CHNL_EXT_SCN; -+ /* prBowFsmInfo->prTargetBssDesc->eBand; */ -+ prMsgChReq->eRfBand = prBowFsmInfo->eBand; -+ COPY_MAC_ADDR(prMsgChReq->aucBSSID, prBowFsmInfo->aucPeerAddress); -+ -+ prBowFsmInfo->fgIsChannelRequested = TRUE; -+ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgChReq, MSG_SEND_METHOD_BUF); -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is to inform BOW that channel privilege is granted -+* has been released -+* -+* \param[in] prAdapter Pointer of ADAPTER_T -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID bowReleaseCh(IN P_ADAPTER_T prAdapter) -+{ -+ P_BOW_FSM_INFO_T prBowFsmInfo; -+ P_MSG_CH_ABORT_T prMsgChAbort; -+ -+ ASSERT(prAdapter); -+ -+ prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); -+ -+ if (prBowFsmInfo->fgIsChannelGranted != FALSE || prBowFsmInfo->fgIsChannelRequested != FALSE) { -+#if CFG_BOW_TEST -+ DBGLOG(BOW, INFO, "BoW channel [RELEASE:%d] %d, %d.\n", prBowFsmInfo->ucSeqNumOfChReq, -+ prBowFsmInfo->ucPrimaryChannel, prBowFsmInfo->eBand); -+#endif -+ -+ prBowFsmInfo->fgIsChannelRequested = FALSE; -+ prBowFsmInfo->fgIsChannelGranted = FALSE; -+ -+ /* 1. return channel privilege to CNM immediately */ -+ prMsgChAbort = (P_MSG_CH_ABORT_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_CH_ABORT_T)); -+ if (!prMsgChAbort) { -+ ASSERT(0); /* Can't release Channel to CNM */ -+ return; -+ } -+ -+ prMsgChAbort->rMsgHdr.eMsgId = MID_MNY_CNM_CH_ABORT; -+ prMsgChAbort->ucNetTypeIndex = NETWORK_TYPE_BOW_INDEX; -+ prMsgChAbort->ucTokenID = prBowFsmInfo->ucSeqNumOfChReq; -+ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgChAbort, MSG_SEND_METHOD_BUF); -+ } -+ -+} /* end of aisFsmReleaseCh() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will indicate an Event of "Media Disconnect" to HOST -+* -+* @param[in] u4Param Unused timer parameter -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID bowChGrantedTimeout(IN P_ADAPTER_T prAdapter, IN ULONG ulParam) -+{ -+ P_BOW_FSM_INFO_T prBowFsmInfo; -+ ENUM_BOW_DEVICE_STATE eFsmState; -+ -+ ASSERT(prAdapter); -+ -+ prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); -+ -+#if CFG_BOW_TEST -+ DBGLOG(BOW, INFO, "BoW Channel [TIMEOUT]\n"); -+#endif -+#if 1 -+ /* bowReleaseCh(prAdapter); */ -+ eFsmState = bowGetBowTableState(prAdapter, prBowFsmInfo->aucPeerAddress); -+ -+ /*If connecting is not completed, request CH again */ -+ if ((eFsmState == BOW_DEVICE_STATE_CONNECTING) || (eFsmState == BOW_DEVICE_STATE_STARTING)) -+ bowRequestCh(prAdapter); -+#endif -+} -+ -+BOOLEAN bowNotifyAllLinkDisconnected(IN P_ADAPTER_T prAdapter) -+{ -+ UINT_8 ucBowTableIdx = 0; -+ CMD_INFO_T rCmdInfo; -+ -+ ASSERT(prAdapter); -+ -+ kalMemZero(&rCmdInfo, sizeof(CMD_INFO_T)); -+ -+ while (ucBowTableIdx < CFG_BOW_PHYSICAL_LINK_NUM) { -+ if (arBowTable[ucBowTableIdx].fgIsValid) { -+ COPY_MAC_ADDR(prAdapter->rWifiVar.rBowFsmInfo.aucPeerAddress, -+ arBowTable[ucBowTableIdx].aucPeerAddress); -+ -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, -+ "bowNotifyAllLinkDisconnected, arBowTable[%x].aucPeerAddress, %x:%x:%x:%x:%x:%x.\n", -+ ucBowTableIdx, arBowTable[ucBowTableIdx].aucPeerAddress[0], -+ arBowTable[ucBowTableIdx].aucPeerAddress[1], -+ arBowTable[ucBowTableIdx].aucPeerAddress[2], -+ arBowTable[ucBowTableIdx].aucPeerAddress[3], -+ arBowTable[ucBowTableIdx].aucPeerAddress[4], -+ arBowTable[ucBowTableIdx].aucPeerAddress[5])); -+ DBGLOG(BOW, EVENT, -+ "bowNotifyAllLinkDisconnected, arBowTable[%x].fgIsValid, %x.\n", ucBowTableIdx, -+ arBowTable[ucBowTableIdx].fgIsValid); -+#endif -+#if 1 -+ wlanoidSendSetQueryBowCmd(prAdapter, -+ CMD_ID_CMD_BT_OVER_WIFI, -+ TRUE, -+ FALSE, -+ wlanbowCmdEventLinkDisconnected, -+ wlanbowCmdTimeoutHandler, 0, NULL, 0); -+#else -+ wlanbowCmdEventLinkDisconnected(prAdapter, &rCmdInfo, NULL); -+#endif -+ } -+ -+ ucBowTableIdx += 1; -+ } -+ -+ return TRUE; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief to retrieve Bluetooth-over-Wi-Fi state from glue layer -+* -+* \param[in] -+* prGlueInfo -+* rPeerAddr -+* \return -+* ENUM_BOW_DEVICE_STATE -+*/ -+/*----------------------------------------------------------------------------*/ -+ -+BOOLEAN bowCheckBowTableIfVaild(IN P_ADAPTER_T prAdapter, IN UINT_8 aucPeerAddress[6]) -+{ -+ UINT_8 idx; -+ -+ KAL_SPIN_LOCK_DECLARATION(); -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_BOW_TABLE); -+ -+ for (idx = 0; idx < CFG_BOW_PHYSICAL_LINK_NUM; idx++) { -+ if (arBowTable[idx].fgIsValid && EQUAL_MAC_ADDR(arBowTable[idx].aucPeerAddress, aucPeerAddress)) { -+ -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "kalCheckBowifVaild, aucPeerAddress %x, %x:%x:%x:%x:%x:%x.\n", idx, -+ aucPeerAddress[0], -+ aucPeerAddress[1], -+ aucPeerAddress[2], -+ aucPeerAddress[3], aucPeerAddress[4], aucPeerAddress[5])); -+ -+ DBGLOG(BOW, EVENT, -+ "kalCheckBowifVaild, arBowTable[idx].aucPeerAddress %x, %x:%x:%x:%x:%x:%x.\n", idx, -+ arBowTable[idx].aucPeerAddress[0], arBowTable[idx].aucPeerAddress[1], -+ arBowTable[idx].aucPeerAddress[2], arBowTable[idx].aucPeerAddress[3], -+ arBowTable[idx].aucPeerAddress[4], arBowTable[idx].aucPeerAddress[5])); -+ -+ DBGLOG(BOW, EVENT, -+ "kalCheckBowifVaild, arBowTable[idx].fgIsValid, %x, %x.\n", idx, -+ arBowTable[idx].fgIsValid); -+ -+#endif -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_BOW_TABLE); -+ return TRUE; -+ } -+ } -+ -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_BOW_TABLE); -+ return FALSE; -+} -+ -+BOOLEAN bowGetBowTableContent(IN P_ADAPTER_T prAdapter, IN UINT_8 ucBowTableIdx, OUT P_BOW_TABLE_T prBowTable) -+{ -+ KAL_SPIN_LOCK_DECLARATION(); -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_BOW_TABLE); -+ -+ if (arBowTable[ucBowTableIdx].fgIsValid) { -+ -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, -+ "bowGetBowTableContent, arBowTable[idx].fgIsValid, %x, %x.\n", ucBowTableIdx, -+ arBowTable[ucBowTableIdx].fgIsValid); -+ DBGLOG(BOW, INFO, "GET State [%d]\n", arBowTable[ucBowTableIdx].eState); -+#endif -+ prBowTable = &(arBowTable[ucBowTableIdx]); -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_BOW_TABLE); -+ -+ return TRUE; -+ } -+ -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_BOW_TABLE); -+ -+ return FALSE; -+} -+ -+BOOLEAN bowSetBowTableContent(IN P_ADAPTER_T prAdapter, IN UINT_8 ucBowTableIdx, IN P_BOW_TABLE_T prBowTable) -+{ -+ KAL_SPIN_LOCK_DECLARATION(); -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_BOW_TABLE); -+ -+ COPY_MAC_ADDR(arBowTable[ucBowTableIdx].aucPeerAddress, prBowTable->aucPeerAddress); -+ arBowTable[ucBowTableIdx].eState = prBowTable->eState; -+ arBowTable[ucBowTableIdx].fgIsValid = prBowTable->fgIsValid; -+ arBowTable[ucBowTableIdx].ucAcquireID = prBowTable->ucAcquireID; -+ -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_BOW_TABLE); -+ -+ kalSetBowState(prAdapter->prGlueInfo, prBowTable->eState, prBowTable->aucPeerAddress); -+ /* kalSetBowRole(prAdapter->prGlueInfo, prBowTable->ucRole, prBowTable->aucPeerAddress); */ -+ -+#if CFG_BOW_TEST -+ DBGLOG(BOW, INFO, "SET State [%d]\n", arBowTable[ucBowTableIdx].eState); -+ DBGLOG(BOW, EVENT, -+ "kalCheckBowifVaild, arBowTable[ucBowTableIdx].fgIsValid, %x, %x.\n", ucBowTableIdx, -+ arBowTable[ucBowTableIdx].fgIsValid); -+#endif -+ -+ return TRUE; -+ -+} -+ -+BOOLEAN -+bowGetBowTableEntryByPeerAddress(IN P_ADAPTER_T prAdapter, IN UINT_8 aucPeerAddress[6], OUT PUINT_8 pucBowTableIdx) -+{ -+ UINT_8 idx; -+ -+ KAL_SPIN_LOCK_DECLARATION(); -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_BOW_TABLE); -+ -+ for (idx = 0; idx < CFG_BOW_PHYSICAL_LINK_NUM; idx++) { -+ if (arBowTable[idx].fgIsValid && EQUAL_MAC_ADDR(arBowTable[idx].aucPeerAddress, aucPeerAddress)) { -+ -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "kalCheckBowifVaild, aucPeerAddress %x, %x:%x:%x:%x:%x:%x.\n", idx, -+ aucPeerAddress[0], -+ aucPeerAddress[1], -+ aucPeerAddress[2], -+ aucPeerAddress[3], aucPeerAddress[4], aucPeerAddress[5])); -+ DBGLOG(BOW, EVENT, -+ "kalCheckBowifVaild, arBowTable[idx].aucPeerAddress %x, %x:%x:%x:%x:%x:%x.\n", idx, -+ arBowTable[idx].aucPeerAddress[0], arBowTable[idx].aucPeerAddress[1], -+ arBowTable[idx].aucPeerAddress[2], arBowTable[idx].aucPeerAddress[3], -+ arBowTable[idx].aucPeerAddress[4], arBowTable[idx].aucPeerAddress[5])); -+ DBGLOG(BOW, EVENT, -+ "kalCheckBowifVaild, arBowTable[idx].fgIsValid, %x, %x.\n", idx, -+ arBowTable[idx].fgIsValid); -+#endif -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_BOW_TABLE); -+ -+ *pucBowTableIdx = idx; -+ -+ return TRUE; -+ } -+ } -+ -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_BOW_TABLE); -+ -+ return FALSE; -+} -+ -+BOOLEAN bowGetBowTableFreeEntry(IN P_ADAPTER_T prAdapter, OUT PUINT_8 pucBowTableIdx) -+{ -+ UINT_8 idx; -+ -+ KAL_SPIN_LOCK_DECLARATION(); -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_BOW_TABLE); -+ -+ for (idx = 0; idx < CFG_BOW_PHYSICAL_LINK_NUM; idx++) { -+ if (!arBowTable[idx].fgIsValid) { -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, -+ "bowGetBowTableFreeEntry, arBowTable[idx].fgIsValid, %x, %x.\n", idx, -+ arBowTable[idx].fgIsValid); -+#endif -+ *pucBowTableIdx = idx; -+ arBowTable[idx].fgIsValid = TRUE; -+ -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_BOW_TABLE); -+ -+ return TRUE; -+ } -+ } -+ -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_BOW_TABLE); -+ -+ return FALSE; -+} -+ -+ENUM_BOW_DEVICE_STATE bowGetBowTableState(IN P_ADAPTER_T prAdapter, IN UINT_8 aucPeerAddress[6]) -+{ -+ UINT_8 idx; -+ -+ KAL_SPIN_LOCK_DECLARATION(); -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_BOW_TABLE); -+ -+ for (idx = 0; idx < CFG_BOW_PHYSICAL_LINK_NUM; idx++) { -+ if (arBowTable[idx].fgIsValid && EQUAL_MAC_ADDR(arBowTable[idx].aucPeerAddress, aucPeerAddress)) { -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "bowGetState, aucPeerAddress %x, %x:%x:%x:%x:%x:%x.\n", idx, -+ aucPeerAddress[0], -+ aucPeerAddress[1], -+ aucPeerAddress[2], -+ aucPeerAddress[3], aucPeerAddress[4], aucPeerAddress[5])); -+ DBGLOG(BOW, EVENT, "bowGetState, arBowTable[idx].aucPeerAddress %x, %x:%x:%x:%x:%x:%x.\n", idx, -+ arBowTable[idx].aucPeerAddress[0], -+ arBowTable[idx].aucPeerAddress[1], -+ arBowTable[idx].aucPeerAddress[2], -+ arBowTable[idx].aucPeerAddress[3], -+ arBowTable[idx].aucPeerAddress[4], arBowTable[idx].aucPeerAddress[5])); -+ DBGLOG(BOW, EVENT, -+ "bowGetState, arBowTable[idx].fgIsValid, %x, %x.\n", idx, arBowTable[idx].fgIsValid); -+ DBGLOG(BOW, EVENT, -+ "bowGetState, arBowTable[idx].eState;, %x, %x.\n", idx, arBowTable[idx].eState); -+ DBGLOG(BOW, INFO, "GET State [%d]\n", arBowTable[idx].eState); -+#endif -+ -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_BOW_TABLE); -+ -+ return arBowTable[idx].eState; -+ } -+ } -+ -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_BOW_TABLE); -+ -+ return BOW_DEVICE_STATE_DISCONNECTED; -+} -+ -+BOOLEAN bowSetBowTableState(IN P_ADAPTER_T prAdapter, IN UINT_8 aucPeerAddress[6], IN ENUM_BOW_DEVICE_STATE eState) -+{ -+ UINT_8 ucBowTableIdx; -+ -+ if (bowGetBowTableEntryByPeerAddress(prAdapter, aucPeerAddress, &ucBowTableIdx)) { -+ KAL_SPIN_LOCK_DECLARATION(); -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_BOW_TABLE); -+ -+ arBowTable[ucBowTableIdx].eState = eState; -+#if CFG_BOW_TEST -+ DBGLOG(BOW, INFO, "SET State [%d]\n", eState); -+#endif -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_BOW_TABLE); -+ -+ kalSetBowState(prAdapter->prGlueInfo, eState, aucPeerAddress); -+ return TRUE; -+ } -+ return FALSE; -+} -+ -+#endif -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/common/wlan_lib.c b/drivers/misc/mediatek/connectivity/wlan/gen2/common/wlan_lib.c -new file mode 100644 -index 000000000000..1c59f861047e ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/common/wlan_lib.c -@@ -0,0 +1,6240 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/common/wlan_lib.c#2 -+*/ -+/*! \file wlan_lib.c -+ \brief Internal driver stack will export the required procedures here for GLUE Layer. -+ -+ This file contains all routines which are exported from MediaTek 802.11 Wireless -+ LAN driver stack to GLUE Layer. -+*/ -+ -+/* -+** Log: wlan_lib.c -+** -+** 08 15 2012 eason.tsai -+** [ALPS00338170] [Need Patch] [Volunteer Patch] modify build warning -+** fix build waring for codechange -+ * -+ * 07 13 2012 cp.wu -+ * [WCXRP00001259] [MT6620 Wi-Fi][Driver][Firmware] Send a signal to firmware for termination -+ * after SDIO error has happened -+ * [driver domain] add force reset by host-to-device interrupt mechanism -+ * -+ * 06 11 2012 cp.wu -+ * [WCXRP00001252] [MT6620 Wi-Fi][Driver] Add debug message while encountering firmware response timeout -+ * output message while timeout event occurs -+ * -+ * 06 11 2012 eason.tsai -+ * NULL -+ * change from binay to hex code -+ * -+ * 06 08 2012 eason.tsai -+ * NULL -+ * Nvram context covert from 6620 to 6628 for old 6620 meta tool -+ * -+ * 05 11 2012 cp.wu -+ * [WCXRP00001237] [MT6620 Wi-Fi][Driver] Show MAC address and MAC address source for ACS's convenience -+ * show MAC address & source while initiliazation -+ * -+ * 03 29 2012 eason.tsai -+ * [WCXRP00001216] [MT6628 Wi-Fi][Driver]add conditional define -+ * add conditional define. -+ * -+ * 03 04 2012 eason.tsai -+ * NULL -+ * modify the cal fail report code. -+ * -+ * 03 02 2012 terry.wu -+ * NULL -+ * Sync CFG80211 modification from branch 2,2. -+ * -+ * 01 16 2012 cp.wu -+ * [WCXRP00001169] [MT6620 Wi-Fi][Driver] API and behavior modification for preferred band -+ * configuration with corresponding network configuration correct scan result removing policy. -+ * -+ * 01 16 2012 cp.wu -+ * [MT6620 Wi-Fi][Driver] API and behavior modification for preferred band configuration with -+ * corresponding network configuration add wlanSetPreferBandByNetwork() for glue layer to invoke -+ * for setting preferred band configuration corresponding to network type. -+ * -+ * 01 05 2012 wh.su -+ * [WCXRP00001153] [MT6620 Wi-Fi][Driver] Adding the get_ch_list and set_tx_power proto type function -+ * Adding the related ioctl / wlan oid function to set the Tx power cfg. -+ * -+ * 11 28 2011 cp.wu -+ * [WCXRP00001125] [MT6620 Wi-Fi][Firmware] Strengthen Wi-Fi power off sequence to have a clearroom environment -+ * when returining to ROM code -+ * 1. Due to firmware now stops HIF DMA for powering off, do not try to receive any packet from firmware -+ * 2. Take use of prAdapter->fgIsEnterD3ReqIssued for tracking whether it is powering off or not -+ * -+ * 11 14 2011 cm.chang -+ * [WCXRP00001104] [All Wi-Fi][FW] Show init process by HW mail-box register -+ * Show FW initial ID when timeout to wait for ready bit -+ * -+ * 11 11 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * modify the xlog related code. -+ * -+ * 10 18 2011 cp.wu -+ * [WCXRP00001022] [MT6628 Driver][Firmware Download] Add multi section independent download functionality -+ * when powering off, always clear pending interrupts, then wait for RDY to be de-asserted -+ * -+ * 10 14 2011 cp.wu -+ * [WCXRP00001022] [MT6628 Driver][Firmware Download] Add multi section independent download functionality -+ * shorten the packet length for firmware download if no more than 2048 bytes. -+ * -+ * 10 03 2011 cp.wu -+ * [WCXRP00001022] [MT6628 Driver][Firmware Download] Add multi section independent download functionality -+ * add firmware download path in divided scatters. -+ * -+ * 10 03 2011 cp.wu -+ * [MT6628 Driver][Firmware Download] Add multi section independent download functionality -+ * add firmware downloading aggregated path. -+ * -+ * 09 30 2011 cm.chang -+ * [WCXRP00001020] [MT6620 Wi-Fi][Driver] Handle secondary channel offset of AP in 5GHz band -+ * . -+ * -+ * 09 20 2011 cp.wu -+ * [WCXRP00000994] [MT6620 Wi-Fi][Driver] dump message for bus error and reset bus error flag while re-initialized -+ * 1. always show error message for SDIO bus errors. -+ * 2. reset bus error flag when re-initialization -+ * -+ * 08 26 2011 cm.chang -+ * [WCXRP00000952] [MT5931 Wi-Fi][FW] Handshake with BWCS before DPD/TX power calibration -+ * Fix compiling error for WinXP MT5931 driver -+ * -+ * 08 25 2011 chinghwa.yu -+ * [WCXRP00000063] Update BCM CoEx design and settings -+ * Add BWCS Sync ready for WinXP. -+ * -+ * 08 25 2011 chinghwa.yu -+ * [WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm -+ * Add DFS switch. -+ * -+ * 08 24 2011 chinghwa.yu -+ * [WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm -+ * Update RDD test mode cases. -+ * -+ * 08 19 2011 cp.wu -+ * [WCXRP00000702] [MT5931][Driver] Modify initialization sequence for E1 ASIC -+ * escape from normal path if any error is occurred. -+ * -+ * 08 15 2011 cp.wu -+ * [WCXRP00000851] [MT6628 Wi-Fi][Driver] Add HIFSYS related definition to driver source tree -+ * reuse firmware download logic of MT6620 for MT6628. -+ * -+ * 08 15 2011 cp.wu -+ * [WCXRP00000913] [MT6620 Wi-Fi] create repository of source code dedicated for MT6620 E6 ASIC -+ * support to load different firmware image for E3/E4/E5 and E6 ASIC on win32 platforms. -+ * -+ * 08 02 2011 yuche.tsai -+ * [WCXRP00000896] [Volunteer Patch][WiFi Direct][Driver] GO with multiple client, TX deauth to a -+ * disconnecting device issue. -+ * Fix GO send deauth frame issue. -+ * -+ * 07 22 2011 jeffrey.chang -+ * [WCXRP00000864] [MT5931] Add command to adjust OSC stable time -+ * modify driver to set OSC stable time after f/w download -+ * -+ * 07 18 2011 chinghwa.yu -+ * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm -+ * Add CMD/Event for RDD and BWCS. -+ * -+ * 06 24 2011 cp.wu -+ * [WCXRP00000812] [MT6620 Wi-Fi][Driver] not show NVRAM when there is no valid MAC address in NVRAM content -+ * if there is no valid address in chip, generate a new one from driver domain instead of firmware domain -+ * due to sufficient randomness -+ * -+ * 06 23 2011 cp.wu -+ * [WCXRP00000812] [MT6620 Wi-Fi][Driver] not show NVRAM when there is no valid MAC address in NVRAM content -+ * check with firmware for valid MAC address. -+ * -+ * 06 20 2011 cp.wu -+ * [WCXRP00000702] [MT5931][Driver] Modify initialization sequence for E1 ASIC -+ * disable whole-chip resetting mechanism due to the need of further ECO to work as expected. -+ * -+ * 05 31 2011 cp.wu -+ * [WCXRP00000749] [MT6620 Wi-Fi][Driver] Add band edge tx power control to Wi-Fi NVRAM -+ * changed to use non-zero checking for valid bit in NVRAM content -+ * -+ * 05 27 2011 cp.wu -+ * [WCXRP00000749] [MT6620 Wi-Fi][Driver] Add band edge tx power control to Wi-Fi NVRAM -+ * invoke CMD_ID_SET_EDGE_TXPWR_LIMIT when there is valid data exist in NVRAM content. -+ * -+ * 05 18 2011 cp.wu -+ * [WCXRP00000734] [MT6620 Wi-Fi][Driver] Pass PHY_PARAM in NVRAM to firmware domain -+ * pass PHY_PARAM in NVRAM from driver to firmware. -+ * -+ * 05 11 2011 cp.wu -+ * [WCXRP00000718] [MT6620 Wi-Fi] modify the behavior of setting tx power -+ * correct assertion. -+ * -+ * 05 11 2011 cp.wu -+ * [WCXRP00000718] [MT6620 Wi-Fi] modify the behavior of setting tx power -+ * ACPI APIs migrate to wlan_lib.c for glue layer to invoke. -+ * -+ * 05 11 2011 cm.chang -+ * [WCXRP00000717] [MT5931 Wi-Fi][Driver] Handle wrong NVRAM content about AP bandwidth setting -+ * . -+ * -+ * 05 05 2011 cp.wu -+ * [WCXRP00000702] [MT5931][Driver] Modify initialization sequence for E1 ASIC -+ * change delay from 100ms to 120ms upon DE's suggestion. -+ * -+ * 05 05 2011 cp.wu -+ * [WCXRP00000702] [MT5931][Driver] Modify initialization sequence for E1 ASIC -+ * add delay after whole-chip resetting for MT5931 E1 ASIC. -+ * -+ * 04 22 2011 cp.wu -+ * [WCXRP00000598] [MT6620 Wi-Fi][Driver] Implementation of interface for communicating with user space -+ * process for RESET_START and RESET_END events skip power-off handshaking when RESET indication is received. -+ * -+ * 04 22 2011 george.huang -+ * [WCXRP00000621] [MT6620 Wi-Fi][Driver] Support P2P supplicant to set power mode -+ * . -+ * -+ * 04 18 2011 cp.wu -+ * [WCXRP00000636] [WHQL][MT5931 Driver] 2c_PMHibernate (hang on 2h) -+ * 1) add API for glue layer to query ACPI state -+ * 2) Windows glue should not access to hardware after switched into D3 state -+ * -+ * 04 15 2011 cp.wu -+ * [WCXRP00000654] [MT6620 Wi-Fi][Driver] Add loop termination criterion for wlanAdapterStop(). -+ * add loop termination criteria for wlanAdapterStop(). -+ * -+ * 04 12 2011 eddie.chen -+ * [WCXRP00000617] [MT6620 Wi-Fi][DRV/FW] Fix for sigma -+ * Fix the sta index in processing security frame -+ * Simple flow control for TC4 to avoid mgt frames for PS STA to occupy the TC4 -+ * Add debug message. -+ * -+ * 04 12 2011 cp.wu -+ * [WCXRP00000631] [MT6620 Wi-Fi][Driver] Add an API for QM to retrieve current TC counter value and processing -+ * frame dropping cases for TC4 path -+ * 1. add nicTxGetResource() API for QM to make decisions. -+ * 2. if management frames is decided by QM for dropping, the call back is invoked to indicate such a case. -+ * -+ * 04 06 2011 cp.wu -+ * [WCXRP00000616] [MT6620 Wi-Fi][Driver] Free memory to pool and kernel in case any unexpected failure -+ * happend inside wlanAdapterStart invoke nicReleaseAdapterMemory() as failure handling in case -+ * wlanAdapterStart() failed unexpectedly -+ * -+ * 03 29 2011 wh.su -+ * [WCXRP00000248] [MT6620 Wi-Fi][FW]Fixed the Klockwork error -+ * fixed the kclocwork error. -+ * -+ * 03 15 2011 cp.wu -+ * [WCXRP00000559] [MT6620 Wi-Fi][Driver] Combine TX/RX DMA buffers into a single one to reduce physically -+ * continuous memory consumption -+ * 1. deprecate CFG_HANDLE_IST_IN_SDIO_CALLBACK -+ * 2. Use common coalescing buffer for both TX/RX directions -+ * -+ * -+ * 03 10 2011 cp.wu -+ * [WCXRP00000532] [MT6620 Wi-Fi][Driver] Migrate NVRAM configuration procedures from MT6620 E2 to MT6620 E3 -+ * deprecate configuration used by MT6620 E2 -+ * -+ * 03 07 2011 terry.wu -+ * [WCXRP00000521] [MT6620 Wi-Fi][Driver] Remove non-standard debug message -+ * Toggle non-standard debug messages to comments. -+ * -+ * 02 25 2011 cp.wu -+ * [WCXRP00000496] [MT5931][Driver] Apply host-triggered chip reset before initializing firmware download procedures -+ * apply host-triggered chip reset mechanism before initializing firmware download procedures. -+ * -+ * 02 17 2011 eddie.chen -+ * [WCXRP00000458] [MT6620 Wi-Fi][Driver] BOW Concurrent - ProbeResp was exist in other channel -+ * 1) Change GetFrameAction decision when BSS is absent. -+ * 2) Check channel and resource in processing ProbeRequest -+ * -+ * 02 16 2011 cm.chang -+ * [WCXRP00000447] [MT6620 Wi-Fi][FW] Support new NVRAM update mechanism -+ * . -+ * -+ * 02 01 2011 george.huang -+ * [WCXRP00000333] [MT5931][FW] support SRAM power control drivers -+ * init variable for CTIA. -+ * -+ * 01 27 2011 george.huang -+ * [WCXRP00000355] [MT6620 Wi-Fi] Set WMM-PS related setting with qualifying AP capability -+ * Support current measure mode, assigned by registry (XP only). -+ * -+ * 01 24 2011 cp.wu -+ * [WCXRP00000382] [MT6620 Wi-Fi][Driver] Track forwarding packet number with notifying tx thread for serving -+ * 1. add an extra counter for tracking pending forward frames. -+ * 2. notify TX service thread as well when there is pending forward frame -+ * 3. correct build errors leaded by introduction of Wi-Fi direct separation module -+ * -+ * 01 12 2011 cm.chang -+ * [WCXRP00000354] [MT6620 Wi-Fi][Driver][FW] Follow NVRAM bandwidth setting -+ * User-defined bandwidth is for 2.4G and 5G individually -+ * -+ * 01 10 2011 cp.wu -+ * [WCXRP00000351] [MT6620 Wi-Fi][Driver] remove from scanning result in OID handling layer when the -+ * corresponding BSS is disconnected due to beacon timeout remove from scanning result when the BSS -+ * is disconnected due to beacon timeout. -+ * -+ * 01 04 2011 cp.wu -+ * [WCXRP00000338] [MT6620 Wi-Fi][Driver] Separate kalMemAlloc into kmalloc and vmalloc implementations to -+ * ease physically continuous memory demands separate kalMemAlloc() into virtually-continuous -+ * and physically-continuous type to ease slab system pressure -+ * -+ * 12 31 2010 cp.wu -+ * [WCXRP00000327] [MT6620 Wi-Fi][Driver] Improve HEC WHQA 6972 workaround coverage in driver side -+ * while being unloaded, clear all pending interrupt then set LP-own to firmware -+ * -+ * 12 31 2010 cp.wu -+ * [WCXRP00000335] [MT6620 Wi-Fi][Driver] change to use milliseconds sleep instead of delay -+ * to avoid blocking to system scheduling change to use msleep() and shorten waiting interval -+ * to reduce blocking to other task while Wi-Fi driver is being loaded -+ * -+ * 12 28 2010 cp.wu -+ * [WCXRP00000269] [MT6620 Wi-Fi][Driver][Firmware] Prepare for v1.1 branch release -+ * report EEPROM used flag via NIC_CAPABILITY -+ * -+ * 12 28 2010 cp.wu -+ * [WCXRP00000269] [MT6620 Wi-Fi][Driver][Firmware] Prepare for v1.1 branch release -+ * integrate with 'EEPROM used' flag for reporting correct capability to Engineer Mode/META and other tools -+ * -+ * 12 22 2010 eddie.chen -+ * [WCXRP00000218] [MT6620 Wi-Fi][Driver] Add auto rate window control in registry -+ * Remove controling auto rate from initial setting. The initial setting is defined by FW code. -+ * -+ * 12 15 2010 cp.wu -+ * NULL -+ * sync. with ALPS code by enabling interrupt just before leaving wlanAdapterStart() -+ * -+ * 12 08 2010 yuche.tsai -+ * [WCXRP00000245] [MT6620][Driver] Invitation & Provision Discovery Feature Check-in -+ * Change Param name for invitation connection. -+ * -+ * 12 07 2010 cm.chang -+ * [WCXRP00000238] MT6620 Wi-Fi][Driver][FW] Support regulation domain setting from NVRAM and supplicant -+ * 1. Country code is from NVRAM or supplicant -+ * 2. Change band definition in CMD/EVENT. -+ * -+ * 11 03 2010 cp.wu -+ * [WCXRP00000083] [MT5931][Driver][FW] Add necessary logic for MT5931 first connection -+ * 1) use 8 buffers for MT5931 which is equipped with less memory -+ * 2) modify MT5931 debug level to TRACE when download is successful -+ * -+ * 11 02 2010 cp.wu -+ * [WCXRP00000083] [MT5931][Driver][FW] Add necessary logic for MT5931 first connection -+ * for MT5931, adapter initialization is done *after* firmware is downloaded. -+ * -+ * 11 02 2010 cp.wu -+ * [WCXRP00000083] [MT5931][Driver][FW] Add necessary logic for MT5931 first connection -+ * correct MT5931 firmware download procedure: -+ * MT5931 will download firmware first then acquire LP-OWN -+ * -+ * 11 02 2010 cp.wu -+ * [WCXRP00000083] [MT5931][Driver][FW] Add necessary logic for MT5931 first connection -+ * 1) update MT5931 firmware encryption tool. (using 64-bytes unit) -+ * 2) update MT5931 firmware download procedure -+ * -+ * 11 01 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version -+ * Check[WCXRP00000150] [MT6620 Wi-Fi][Driver] Add implementation for querying -+ * current TX rate from firmware auto rate module -+ * 1) Query link speed (TX rate) from firmware directly with buffering mechanism to reduce overhead -+ * 2) Remove CNM CH-RECOVER event handling -+ * 3) cfg read/write API renamed with kal prefix for unified naming rules. -+ * -+ * 11 01 2010 yarco.yang -+ * [WCXRP00000149] [MT6620 WI-Fi][Driver]Fine tune performance on MT6516 platform -+ * Add code to run WlanIST in SDIO callback. -+ * -+ * 10 27 2010 george.huang -+ * [WCXRP00000127] [MT6620 Wi-Fi][Driver] Add a registry to disable Beacon Timeout function -+ * for SQA test by using E1 EVB -+ * Support registry option for disable beacon lost detection. -+ * -+ * 10 26 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version -+ * Check[WCXRP00000137] [MT6620 Wi-Fi] [FW] Support NIC capability query command -+ * 1) update NVRAM content template to ver 1.02 -+ * 2) add compile option for querying NIC capability (default: off) -+ * 3) modify AIS 5GHz support to run-time option, which could be turned on by registry or NVRAM setting -+ * 4) correct auto-rate compiler error under linux (treat warning as error) -+ * 5) simplify usage of NVRAM and REG_INFO_T -+ * 6) add version checking between driver and firmware -+ * -+ * 10 26 2010 eddie.chen -+ * [WCXRP00000134] [MT6620 Wi-Fi][Driver] Add a registry to enable auto rate for SQA test by using E1 EVB -+ * Add auto rate parameter in registry. -+ * -+ * 10 25 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check -+ * add option for enable/disable TX PWR gain adjustment (default: off) -+ * -+ * 10 18 2010 cp.wu -+ * [WCXRP00000117] [MT6620 Wi-Fi][Driver] Add logic for suspending driver when MT6620 is not responding anymore -+ * 1. when wlanAdapterStop() failed to send POWER CTRL command to firmware, do not poll for ready bit dis-assertion -+ * 2. shorten polling count for shorter response time -+ * 3. if bad I/O operation is detected during TX resource polling, then further operation is aborted as well -+ * -+ * 10 18 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version -+ * Check[WCXRP00000086] [MT6620 Wi-Fi][Driver] The mac address is all zero at android -+ * complete implementation of Android NVRAM access -+ * -+ * 10 15 2010 cp.wu -+ * [WCXRP00000103] [MT6620 Wi-Fi][Driver] Driver crashed when using WZC to connect to AP#B with connection with AP#A -+ * bugfix: always reset pointer to IEbuf to zero when keeping scanning result for the connected AP -+ * -+ * 10 08 2010 cp.wu -+ * [WCXRP00000084] [MT6620 Wi-Fi][Driver][FW] Add fixed rate support for distance test -+ * adding fixed rate support for distance test. (from registry setting) -+ * -+ * 10 07 2010 cp.wu -+ * [WCXRP00000083] [MT5931][Driver][FW] Add necessary logic for MT5931 first connection -+ * add firmware download for MT5931. -+ * -+ * 10 06 2010 cp.wu -+ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning -+ * divide a single function into 2 part to surpress a weird compiler warning from gcc-4.4.0 -+ * -+ * 10 06 2010 cp.wu -+ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning -+ * code reorganization to improve isolation between GLUE and CORE layers. -+ * -+ * 10 05 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check -+ * load manufacture data when CFG_SUPPORT_NVRAM is set to 1 -+ * -+ * 10 04 2010 cp.wu -+ * [WCXRP00000077] [MT6620 Wi-Fi][Driver][FW] Eliminate use of ENUM_NETWORK_TYPE_T and replaced -+ * by ENUM_NETWORK_TYPE_INDEX_T only -+ * remove ENUM_NETWORK_TYPE_T definitions -+ * -+ * 09 29 2010 wh.su -+ * [WCXRP00000072] [MT6620 Wi-Fi][Driver] Fix TKIP Counter Measure EAPoL callback register issue -+ * [MT6620 Wi-Fi][Driver] Fix TKIP Counter Measure EAPoL callback register issue. -+ * -+ * 09 24 2010 cp.wu -+ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning -+ * eliminate unused variables which lead gcc to argue -+ * -+ * 09 24 2010 cp.wu -+ * [WCXRP00000057] [MT6620 Wi-Fi][Driver] Modify online scan to a run-time switchable feature -+ * Modify online scan as a run-time adjustable option (for Windows, in registry) -+ * -+ * 09 23 2010 cp.wu -+ * [WCXRP00000051] [MT6620 Wi-Fi][Driver] WHQL test fail in MAC address changed item -+ * use firmware reported mac address right after wlanAdapterStart() as permanent address -+ * -+ * 09 23 2010 cp.wu -+ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning -+ * eliminate reference of CFG_RESPONSE_MAX_PKT_SIZE -+ * -+ * 09 21 2010 cp.wu -+ * [WCXRP00000053] [MT6620 Wi-Fi][Driver] Reset incomplete and might leads to BSOD when entering RF test with -+ * AIS associated -+ * Do a complete reset with STA-REC null checking for RF test re-entry -+ * -+ * 09 21 2010 kevin.huang -+ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning -+ * Eliminate Linux Compile Warning -+ * -+ * 09 13 2010 cp.wu -+ * NULL -+ * acquire & release power control in oid handing wrapper. -+ * -+ * 09 09 2010 cp.wu -+ * NULL -+ * move IE to buffer head when the IE pointer is not pointed at head. -+ * -+ * 09 08 2010 cp.wu -+ * NULL -+ * use static memory pool for storing IEs of scanning result. -+ * -+ * 09 01 2010 cp.wu -+ * NULL -+ * HIFSYS Clock Source Workaround -+ * -+ * 09 01 2010 wh.su -+ * NULL -+ * adding the wapi support for integration test. -+ * -+ * 09 01 2010 cp.wu -+ * NULL -+ * move HIF CR initialization from where after sdioSetupCardFeature() to wlanAdapterStart() -+ * -+ * 08 30 2010 cp.wu -+ * NULL -+ * eliminate klockwork errors -+ * -+ * 08 26 2010 yuche.tsai -+ * NULL -+ * Add AT GO test configure mode under WinXP. -+ * Please enable 1. CFG_ENABLE_WIFI_DIRECT, 2. CFG_TEST_WIFI_DIRECT_GO, 3. CFG_SUPPORT_AAA -+ * -+ * 08 25 2010 george.huang -+ * NULL -+ * update OID/ registry control path for PM related settings -+ * -+ * 08 24 2010 cp.wu -+ * NULL -+ * 1) initialize variable for enabling short premable/short time slot. -+ * 2) add compile option for disabling online scan -+ * -+ * 08 13 2010 cp.wu -+ * NULL -+ * correction issue: desired phy type not initialized as ABGN mode. -+ * -+ * 08 12 2010 cp.wu -+ * NULL -+ * [AIS-FSM] honor registry setting for adhoc running mode. (A/B/G) -+ * -+ * 08 10 2010 cm.chang -+ * NULL -+ * Support EEPROM read/write in RF test mode -+ * -+ * 08 03 2010 cp.wu -+ * NULL -+ * surpress compilation warning. -+ * -+ * 08 03 2010 cp.wu -+ * NULL -+ * Centralize mgmt/system service procedures into independent calls. -+ * -+ * 07 30 2010 cp.wu -+ * NULL -+ * 1) BoW wrapper: use definitions instead of hard-coded constant for error code -+ * 2) AIS-FSM: eliminate use of desired RF parameters, use prTargetBssDesc instead -+ * 3) add handling for RX_PKT_DESTINATION_HOST_WITH_FORWARD for GO-broadcast frames -+ * -+ * 07 29 2010 cp.wu -+ * NULL -+ * eliminate u4FreqInKHz usage, combined into rConnections.ucAdHoc* -+ * -+ * 07 28 2010 cp.wu -+ * NULL -+ * 1) eliminate redundant variable eOPMode in prAdapter->rWlanInfo -+ * 2) change nicMediaStateChange() API prototype -+ * -+ * 07 21 2010 cp.wu -+ * -+ * 1) change BG_SCAN to ONLINE_SCAN for consistent term -+ * 2) only clear scanning result when scan is permitted to do -+ * -+ * 07 19 2010 cm.chang -+ * -+ * Set RLM parameters and enable CNM channel manager -+ * -+ * 07 19 2010 jeffrey.chang -+ * -+ * Linux port modification -+ * -+ * 07 13 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration. -+ * Reduce unnecessary type casting -+ * -+ * 07 13 2010 cp.wu -+ * -+ * use multiple queues to keep 1x/MMPDU/CMD's strict order even when there is incoming 1x frames. -+ * -+ * 07 13 2010 cp.wu -+ * -+ * 1) MMPDUs are now sent to MT6620 by CMD queue for keeping strict order of 1X/MMPDU/CMD packets -+ * 2) integrate with qmGetFrameAction() for deciding which MMPDU/1X could pass checking for sending -+ * 2) enhance CMD_INFO_T descriptor number from 10 to 32 to avoid descriptor underflow under concurrent -+ * network operation -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 07 05 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) ignore RSN checking when RSN is not turned on. -+ * 2) set STA-REC deactivation callback as NULL -+ * 3) add variable initialization API based on PHY configuration -+ * -+ * 07 02 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) for event packet, no need to fill RFB. -+ * 2) when wlanAdapterStart() failed, no need to initialize state machines -+ * 3) after Beacon/ProbeResp parsing, corresponding BSS_DESC_T should be marked as IE-parsed -+ * -+ * 07 01 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Support sync command of STA_REC -+ * -+ * 07 01 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add scan uninitialization procedure -+ * -+ * 06 25 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add API in que_mgt to retrieve sta-rec index for security frames. -+ * -+ * 06 24 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 802.1x and bluetooth-over-Wi-Fi security frames are now delievered to firmware via command path instead of data path. -+ * -+ * 06 23 2010 yarco.yang -+ * [WPD00003837][MT6620]Data Path Refine -+ * Merge g_arStaRec[] into adapter->arStaRec[] -+ * -+ * 06 21 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * initialize mbox & ais_fsm in wlanAdapterStart() -+ * -+ * 06 21 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * change MAC address updating logic. -+ * -+ * 06 21 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * simplify timer usage. -+ * -+ * 06 11 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) migrate assoc.c. -+ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness -+ * 3) add configuration options for CNM_MEM and RSN modules -+ * 4) add data path for management frames -+ * 5) eliminate rPacketInfo of MSDU_INFO_T -+ * -+ * 06 10 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) eliminate CFG_CMD_EVENT_VERSION_0_9 -+ * 2) when disconnected, indicate nic directly (no event is needed) -+ * -+ * 06 08 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * cnm_timer has been migrated. -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 05 28 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * disable interrupt then send power control command packet. -+ * -+ * 05 24 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) when stopping adapter, wait til RDY bit has been cleaerd. -+ * 2) set TASK_OFFLOAD as driver-core OIDs -+ * -+ * 05 20 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) integrate OID_GEN_NETWORK_LAYER_ADDRESSES with CMD_ID_SET_IP_ADDRESS -+ * 2) buffer statistics data for 2 seconds -+ * 3) use default value for adhoc parameters instead of 0 -+ * -+ * 05 19 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) do not take timeout mechanism for power mode oids -+ * 2) retrieve network type from connection status -+ * 3) after disassciation, set radio state to off -+ * 4) TCP option over IPv6 is supported -+ * -+ * 05 17 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * add CFG_STARTUP_DEBUG for debugging starting up issue. -+ * -+ * 05 17 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * 1) add timeout handler mechanism for pending command packets -+ * 2) add p2p add/removal key -+ * -+ * 04 23 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * surpress compiler warning -+ * -+ * 04 20 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * roll-back to rev.60. -+ * -+ * 04 20 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) remove redundant firmware image unloading -+ * 2) use compile-time macros to separate logic related to accquiring own -+ * -+ * 04 16 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * treat BUS access failure as kind of card removal. -+ * -+ * 04 14 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * always set fw-own before driver is unloaded. -+ * -+ * 04 13 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * add framework for BT-over-Wi-Fi support. -+ * * * 1) prPendingCmdInfo is replaced by queue for multiple handler capability -+ * * * 2) command sequence number is now increased atomically -+ * * * 3) private data could be hold and taken use for other purpose -+ * -+ * 04 07 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * finish non-glue layer access to glue variables -+ * -+ * 04 07 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * rWlanInfo should be placed at adapter rather than glue due to most operations -+ * are done in adapter layer. -+ * -+ * 04 06 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * ePowerCtrl is not necessary as a glue variable. -+ * -+ * 04 06 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * add timeout check in the kalOidComplete -+ * -+ * 04 06 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * improve none-glue code portability -+ * -+ * 04 06 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * improve none-glue code portability -+ * -+ * 04 06 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * code refine: fgTestMode should be at adapter rather than glue due to the device/fw is also involved -+ * -+ * 04 06 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * eliminate direct access for prGlueInfo->fgIsCardRemoved in non-glue layer -+ * -+ * 04 06 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) for some OID, never do timeout expiration -+ * 2) add 2 kal API for later integration -+ * -+ * 04 06 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) eliminate unused definitions -+ * 2) ready bit will be polled for limited iteration -+ * -+ * 04 06 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * kalOidComplete is not necessary in linux -+ * -+ * 04 01 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * change to use pass-in prRegInfo instead of accessing prGlueInfo directly -+ * -+ * 04 01 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * change to use WIFI_TCM_ALWAYS_ON as firmware image -+ * -+ * 04 01 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * . -+ * -+ * 03 31 2010 wh.su -+ * [WPD00003816][MT6620 Wi-Fi] Adding the security support -+ * modify the wapi related code for new driver's design. -+ * -+ * 03 30 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * adding none-glue code portability -+ * -+ * 03 30 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * adding non-glue code portability -+ * -+ * 03 29 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * improve non-glue code portability -+ * -+ * 03 25 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * firmware download load address & start address are now configured from config.h -+ * due to the different configurations on FPGA and ASIC -+ * -+ * 03 24 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * [WPD00003826] Initial import for Linux port -+ * initial import for Linux port -+ * -+ * 03 24 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * initial import for Linux port -+ * -+ * 03 22 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * only send CMD_NIC_POWER_CTRL in wlanAdapterStop() when card is not removed and is not in D3 state -+ * -+ * 03 22 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * always send CMD_NIC_POWER_CTRL packet when nic is being halted -+ * -+ * 03 19 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) add ACPI D0/D3 state switching support -+ * 2) use more formal way to handle interrupt when the status is retrieved from enhanced RX response -+ * -+* 03 12 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * add two option for ACK and ENCRYPTION for firmware download -+ * -+ * 03 11 2010 cp.wu -+ * [WPD00003821][BUG] Host driver stops processing RX packets from HIF RX0 -+ * add RX starvation warning debug message controlled by CFG_HIF_RX_STARVATION_WARNING -+ * -+ * 03 08 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) add another spin-lock to protect MsduInfoList due to it might be accessed by different thread. -+ * 2) change own-back acquiring procedure to wait for up to 16.67 seconds -+ * -+ * 03 03 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * when starting adapter, read local adminsitrated address from registry and send to firmware via CMD_BASIC_CONFIG. -+ * -+ * 03 02 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) the use of prPendingOid revised, all accessing are now protected by spin lock -+ * 2) ensure wlanReleasePendingOid will clear all command queues -+ * -+ * 03 02 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * add mutex to avoid multiple access to qmTxQueue simultaneously. -+ * -+ * 03 01 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * add command/event definitions for initial states -+ * -+ * 02 24 2010 tehuang.liu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * Added code for QM_TEST_MODE -+ * -+ * 02 24 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * correct function name .. -+ * -+ * 02 24 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * separate wlanProcesQueuePacket() into 2 APIs upon request -+ * -+ * 02 23 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * add new API: wlanProcessQueuedPackets() -+ * -+ * 02 11 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * correct wlanAdapterStart -+ * -+ * 02 11 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1. add logic for firmware download -+ * 2. firmware image filename and start/load address are now retrieved from registry -+ * -+ * 02 10 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * implement host-side firmware download logic -+ * -+ * 02 10 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) remove unused function in nic_rx.c [which has been handled in que_mgt.c] -+ * 2) firmware image length is now retrieved via NdisFileOpen -+ * 3) firmware image is not structured by (P_IMG_SEC_HDR_T) anymore -+ * 4) nicRxWaitResponse() revised -+ * 5) another set of TQ counter default value is added for fw-download state -+ * 6) Wi-Fi load address is now retrieved from registry too -+ * -+ * 02 09 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1. Permanent and current MAC address are now retrieved by CMD/EVENT packets instead of hard-coded address -+ * 2. follow MSDN defined behavior when associates to another AP -+ * 3. for firmware download, packet size could be up to 2048 bytes -+ * -+ * 02 08 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * prepare for implementing fw download logic -+ * -+ * 02 03 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * wlanoidSetFrequency is now implemented by RF test command. -+ * -+ * 02 03 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * QueryRssi is no longer w/o hardware access, it is now implemented by command/event handling loop -+ * -+ * 02 03 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1. clear prPendingCmdInfo properly -+ * 2. while allocating memory for cmdinfo, no need to add extra 4 bytes. -+ * -+ * 01 28 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * allow MCR read/write OIDs in RF test mode -+ * -+ * 01 27 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) implement timeout mechanism when OID is pending for longer than 1 second -+ * 2) allow OID_802_11_CONFIGURATION to be executed when RF test mode is turned on -+ * -+ * 01 27 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1. eliminate improper variable in rHifInfo -+ * 2. block TX/ordinary OID when RF test mode is engaged -+ * 3. wait until firmware finish operation when entering into and leaving from RF test mode -+ * 4. correct some HAL implementation -+ * -+ * 01 26 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * Under WinXP with SDIO, use prGlueInfo->rHifInfo.pvInformationBuffer instead of prGlueInfo->pvInformationBuffer -+** \main\maintrunk.MT6620WiFiDriver_Prj\36 2009-12-10 16:54:36 GMT mtk02752 -+** code clean -+** \main\maintrunk.MT6620WiFiDriver_Prj\35 2009-12-09 20:04:59 GMT mtk02752 -+** only report as connected when CFG_HIF_EMULATION_TEST is set to 1 -+** \main\maintrunk.MT6620WiFiDriver_Prj\34 2009-12-08 17:39:41 GMT mtk02752 -+** wlanoidRftestQueryAutoTest could be executed without touching hardware -+** \main\maintrunk.MT6620WiFiDriver_Prj\33 2009-12-03 16:10:26 GMT mtk01461 -+** Add debug message -+** \main\maintrunk.MT6620WiFiDriver_Prj\32 2009-12-02 22:05:33 GMT mtk02752 -+** kalOidComplete() will decrease i4OidPendingCount -+** \main\maintrunk.MT6620WiFiDriver_Prj\31 2009-12-01 23:02:36 GMT mtk02752 -+** remove unnecessary spinlock -+** \main\maintrunk.MT6620WiFiDriver_Prj\30 2009-12-01 22:50:38 GMT mtk02752 -+** use TC4 for command, maintein i4OidPendingCount -+** \main\maintrunk.MT6620WiFiDriver_Prj\29 2009-11-27 12:45:34 GMT mtk02752 -+** prCmdInfo should be freed when invoking wlanReleasePendingOid() to clear pending oid -+** \main\maintrunk.MT6620WiFiDriver_Prj\28 2009-11-24 19:55:51 GMT mtk02752 -+** wlanSendPacket & wlanRetransmitOfPendingFrames is only used in old data path -+** \main\maintrunk.MT6620WiFiDriver_Prj\27 2009-11-23 17:59:55 GMT mtk02752 -+** clear prPendingOID inside wlanSendCommand() when the OID didn't need to be replied. -+** \main\maintrunk.MT6620WiFiDriver_Prj\26 2009-11-23 14:45:29 GMT mtk02752 -+** add another version of wlanSendCommand() for command-sending only without blocking for response -+** \main\maintrunk.MT6620WiFiDriver_Prj\25 2009-11-17 22:40:44 GMT mtk01084 -+** \main\maintrunk.MT6620WiFiDriver_Prj\24 2009-11-11 10:14:56 GMT mtk01084 -+** modify place to invoke wlanIst -+** \main\maintrunk.MT6620WiFiDriver_Prj\23 2009-10-30 18:17:07 GMT mtk01084 -+** fix compiler warning -+** \main\maintrunk.MT6620WiFiDriver_Prj\22 2009-10-29 19:46:15 GMT mtk01084 -+** invoke interrupt process routine -+** \main\maintrunk.MT6620WiFiDriver_Prj\21 2009-10-13 21:58:24 GMT mtk01084 -+** modify for new HW architecture -+** \main\maintrunk.MT6620WiFiDriver_Prj\20 2009-09-09 17:26:01 GMT mtk01084 -+** \main\maintrunk.MT6620WiFiDriver_Prj\19 2009-05-20 12:21:27 GMT mtk01461 -+** Add SeqNum check when process Event Packet -+** \main\maintrunk.MT6620WiFiDriver_Prj\18 2009-05-19 10:38:44 GMT mtk01461 -+** Add wlanReleasePendingOid() for mpReset() if there is a pending OID and no available TX resource to send it. -+** \main\maintrunk.MT6620WiFiDriver_Prj\17 2009-04-29 15:41:34 GMT mtk01461 -+** Add handle of EVENT of CMD Result in wlanSendCommand() -+** \main\maintrunk.MT6620WiFiDriver_Prj\16 2009-04-22 09:11:23 GMT mtk01461 -+** Fix wlanSendCommand() for Driver Domain CR -+** \main\maintrunk.MT6620WiFiDriver_Prj\15 2009-04-21 09:33:56 GMT mtk01461 -+** Update wlanSendCommand() for Driver Domain Response and handle Event Packet, -+** wlanQuery/SetInformation() for enqueue CMD_INFO_T -+** \main\maintrunk.MT6620WiFiDriver_Prj\14 2009-04-17 20:00:08 GMT mtk01461 -+** Update wlanImageSectionDownload for optimized CMD process -+** \main\maintrunk.MT6620WiFiDriver_Prj\13 2009-04-14 20:50:51 GMT mtk01426 -+** Fixed compile error -+** \main\maintrunk.MT6620WiFiDriver_Prj\12 2009-04-13 16:38:40 GMT mtk01084 -+** add wifi start function -+** \main\maintrunk.MT6620WiFiDriver_Prj\11 2009-04-13 14:26:44 GMT mtk01084 -+** modify a parameter about FW download length -+** \main\maintrunk.MT6620WiFiDriver_Prj\10 2009-04-10 21:53:42 GMT mtk01461 -+** Update wlanSendCommand() -+** \main\maintrunk.MT6620WiFiDriver_Prj\9 2009-04-08 16:51:04 GMT mtk01084 -+** Update for the image download part -+** \main\maintrunk.MT6620WiFiDriver_Prj\8 2009-04-01 10:32:47 GMT mtk01461 -+** Add wlanSendLeftClusteredFrames() for SDIO_TX_ENHANCE -+** \main\maintrunk.MT6620WiFiDriver_Prj\7 2009-03-23 21:44:13 GMT mtk01461 -+** Refine TC assignment for WmmAssoc flag -+** \main\maintrunk.MT6620WiFiDriver_Prj\6 2009-03-23 16:51:57 GMT mtk01084 -+** modify the input argument of caller to RECLAIM_POWER_CONTROL_TO_PM() -+** \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-03-23 00:27:13 GMT mtk01461 -+** Add reference code of FW Image Download -+** \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-03-19 18:32:37 GMT mtk01084 -+** update for basic power management functions -+** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-03-16 09:09:08 GMT mtk01461 -+** Update TX PATH API -+** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 16:28:45 GMT mtk01426 -+** Init develop -+** -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "precomp.h" -+#include "mgmt/ais_fsm.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+/* 6.1.1.2 Interpretation of priority parameter in MAC service primitives */ -+/* Static convert the Priority Parameter/TID(User Priority/TS Identifier) to Traffic Class */ -+const UINT_8 aucPriorityParam2TC[] = { -+ TC1_INDEX, -+ TC0_INDEX, -+ TC0_INDEX, -+ TC1_INDEX, -+ TC2_INDEX, -+ TC2_INDEX, -+ TC3_INDEX, -+ TC3_INDEX -+}; -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+typedef struct _CODE_MAPPING_T { -+ UINT_32 u4RegisterValue; -+ INT_32 i4TxpowerOffset; -+} CODE_MAPPING_T, *P_CODE_MAPPING_T; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+BOOLEAN fgIsBusAccessFailed = FALSE; -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+#define SIGNED_EXTEND(n, _sValue) \ -+ (((_sValue) & BIT((n)-1)) ? ((_sValue) | BITS(n, 31)) : \ -+ ((_sValue) & ~BITS(n, 31))) -+ -+/* TODO: Check */ -+/* OID set handlers without the need to access HW register */ -+PFN_OID_HANDLER_FUNC apfnOidSetHandlerWOHwAccess[] = { -+ wlanoidSetChannel, -+ wlanoidSetBeaconInterval, -+ wlanoidSetAtimWindow, -+ wlanoidSetFrequency, -+}; -+ -+/* TODO: Check */ -+/* OID query handlers without the need to access HW register */ -+PFN_OID_HANDLER_FUNC apfnOidQueryHandlerWOHwAccess[] = { -+ wlanoidQueryBssid, -+ wlanoidQuerySsid, -+ wlanoidQueryInfrastructureMode, -+ wlanoidQueryAuthMode, -+ wlanoidQueryEncryptionStatus, -+ wlanoidQueryPmkid, -+ wlanoidQueryNetworkTypeInUse, -+ wlanoidQueryBssidList, -+ wlanoidQueryAcpiDevicePowerState, -+ wlanoidQuerySupportedRates, -+ wlanoidQueryDesiredRates, -+ wlanoidQuery802dot11PowerSaveProfile, -+ wlanoidQueryBeaconInterval, -+ wlanoidQueryAtimWindow, -+ wlanoidQueryFrequency, -+}; -+ -+/* OID set handlers allowed in RF test mode */ -+PFN_OID_HANDLER_FUNC apfnOidSetHandlerAllowedInRFTest[] = { -+ wlanoidRftestSetTestMode, -+ wlanoidRftestSetAbortTestMode, -+ wlanoidRftestSetAutoTest, -+ wlanoidSetMcrWrite, -+ wlanoidSetEepromWrite -+}; -+ -+/* OID query handlers allowed in RF test mode */ -+PFN_OID_HANDLER_FUNC apfnOidQueryHandlerAllowedInRFTest[] = { -+ wlanoidRftestQueryAutoTest, -+ wlanoidQueryMcrRead, -+ wlanoidQueryEepromRead -+} -+ -+; -+ -+PFN_OID_HANDLER_FUNC apfnOidWOTimeoutCheck[] = { -+ wlanoidRftestSetTestMode, -+ wlanoidRftestSetAbortTestMode, -+ wlanoidSetAcpiDevicePowerState, -+}; -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+#if 0 /* no use */ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This is a private routine, which is used to check if HW access is needed -+* for the OID query/ set handlers. -+* -+* \param[IN] pfnOidHandler Pointer to the OID handler. -+* \param[IN] fgSetInfo It is a Set information handler. -+* -+* \retval TRUE This function needs HW access -+* \retval FALSE This function does not need HW access -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN wlanIsHandlerNeedHwAccess(IN PFN_OID_HANDLER_FUNC pfnOidHandler, IN BOOLEAN fgSetInfo) -+{ -+ PFN_OID_HANDLER_FUNC *apfnOidHandlerWOHwAccess; -+ UINT_32 i; -+ UINT_32 u4NumOfElem; -+ -+ if (fgSetInfo) { -+ apfnOidHandlerWOHwAccess = apfnOidSetHandlerWOHwAccess; -+ u4NumOfElem = sizeof(apfnOidSetHandlerWOHwAccess) / sizeof(PFN_OID_HANDLER_FUNC); -+ } else { -+ apfnOidHandlerWOHwAccess = apfnOidQueryHandlerWOHwAccess; -+ u4NumOfElem = sizeof(apfnOidQueryHandlerWOHwAccess) / sizeof(PFN_OID_HANDLER_FUNC); -+ } -+ -+ for (i = 0; i < u4NumOfElem; i++) { -+ if (apfnOidHandlerWOHwAccess[i] == pfnOidHandler) -+ return FALSE; -+ } -+ -+ return TRUE; -+} /* wlanIsHandlerNeedHwAccess */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to set flag for later handling card -+* ejected event. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* -+* \return (none) -+* -+* \note When surprised removal happens, Glue layer should invoke this -+* function to notify WPDD not to do any hw access. -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID wlanCardEjected(IN P_ADAPTER_T prAdapter) -+{ -+ DEBUGFUNC("wlanCardEjected"); -+ /* INITLOG(("\n")); */ -+ -+ ASSERT(prAdapter); -+ -+ /* mark that the card is being ejected, NDIS will shut us down soon */ -+ nicTxRelease(prAdapter); -+ -+} /* wlanCardEjected */ -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Create adapter object -+* -+* \param prAdapter This routine is call to allocate the driver software objects. -+* If fails, return NULL. -+* \retval NULL If it fails, NULL is returned. -+* \retval NOT NULL If the adapter was initialized successfully. -+*/ -+/*----------------------------------------------------------------------------*/ -+P_ADAPTER_T wlanAdapterCreate(IN P_GLUE_INFO_T prGlueInfo) -+{ -+ P_ADAPTER_T prAdpater = (P_ADAPTER_T) NULL; -+ -+ DEBUGFUNC("wlanAdapterCreate"); -+ -+ do { -+ prAdpater = (P_ADAPTER_T) kalMemAlloc(sizeof(ADAPTER_T), VIR_MEM_TYPE); -+ -+ if (!prAdpater) { -+ DBGLOG(INIT, ERROR, "Allocate ADAPTER memory ==> FAILED\n"); -+ break; -+ } -+ -+ kalMemZero(prAdpater, sizeof(ADAPTER_T)); -+ prAdpater->prGlueInfo = prGlueInfo; -+ -+ } while (FALSE); -+ -+ return prAdpater; -+} /* wlanAdapterCreate */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Destroy adapter object -+* -+* \param prAdapter This routine is call to destroy the driver software objects. -+* If fails, return NULL. -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID wlanAdapterDestroy(IN P_ADAPTER_T prAdapter) -+{ -+ -+ if (!prAdapter) -+ return; -+ -+ kalMemFree(prAdapter, VIR_MEM_TYPE, sizeof(ADAPTER_T)); -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Initialize the adapter. The sequence is -+* 1. Disable interrupt -+* 2. Read adapter configuration from EEPROM and registry, verify chip ID. -+* 3. Create NIC Tx/Rx resource. -+* 4. Initialize the chip -+* 5. Initialize the protocol -+* 6. Enable Interrupt -+* -+* \param prAdapter Pointer of Adapter Data Structure -+* -+* \retval WLAN_STATUS_SUCCESS: Success -+* \retval WLAN_STATUS_FAILURE: Failed -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanAdapterStart(IN P_ADAPTER_T prAdapter, -+ IN P_REG_INFO_T prRegInfo, IN PVOID pvFwImageMapFile, IN UINT_32 u4FwImageFileLength) -+{ -+ WLAN_STATUS u4Status = WLAN_STATUS_SUCCESS; -+ UINT_32 i, u4Value = 0; -+ UINT_32 u4WHISR = 0; -+ UINT_8 aucTxCount[8]; -+#if CFG_ENABLE_FW_DOWNLOAD -+ UINT_32 u4FwLoadAddr, u4ImgSecSize; -+#if CFG_ENABLE_FW_DIVIDED_DOWNLOAD -+ UINT_32 j; -+ P_FIRMWARE_DIVIDED_DOWNLOAD_T prFwHead; -+ BOOLEAN fgValidHead; -+ const UINT_32 u4CRCOffset = offsetof(FIRMWARE_DIVIDED_DOWNLOAD_T, u4NumOfEntries); -+#endif -+#endif -+ enum Adapter_Start_Fail_Reason { -+ ALLOC_ADAPTER_MEM_FAIL, -+ DRIVER_OWN_FAIL, -+ INIT_ADAPTER_FAIL, -+ RAM_CODE_DOWNLOAD_FAIL, -+ WAIT_FIRMWARE_READY_FAIL, -+ FAIL_REASON_MAX -+ } eFailReason; -+ ASSERT(prAdapter); -+ -+ DEBUGFUNC("wlanAdapterStart"); -+ -+ eFailReason = FAIL_REASON_MAX; -+ /* 4 <0> Reset variables in ADAPTER_T */ -+ prAdapter->fgIsFwOwn = TRUE; -+ prAdapter->fgIsEnterD3ReqIssued = FALSE; -+ -+ QUEUE_INITIALIZE(&(prAdapter->rPendingCmdQueue)); -+ -+ /* Initialize rWlanInfo */ -+ kalMemSet(&(prAdapter->rWlanInfo), 0, sizeof(WLAN_INFO_T)); -+ -+ /* 4 <0.1> reset fgIsBusAccessFailed */ -+ fgIsBusAccessFailed = FALSE; -+ prAdapter->ulSuspendFlag = 0; -+ -+ do { -+ u4Status = nicAllocateAdapterMemory(prAdapter); -+ if (u4Status != WLAN_STATUS_SUCCESS) { -+ DBGLOG(INIT, ERROR, "nicAllocateAdapterMemory Error!\n"); -+ u4Status = WLAN_STATUS_FAILURE; -+ eFailReason = ALLOC_ADAPTER_MEM_FAIL; -+ break; -+ } -+ -+ prAdapter->u4OsPacketFilter = PARAM_PACKET_FILTER_SUPPORTED; -+ -+ DBGLOG(INIT, TRACE, "wlanAdapterStart(): Acquiring LP-OWN %d\n", fgIsResetting); -+ ACQUIRE_POWER_CONTROL_FROM_PM(prAdapter); -+ -+#if !CFG_ENABLE_FULL_PM -+ nicpmSetDriverOwn(prAdapter); -+#endif -+ -+ if (prAdapter->fgIsFwOwn == TRUE) { -+ DBGLOG(INIT, ERROR, "nicpmSetDriverOwn() failed!\n"); -+ u4Status = WLAN_STATUS_FAILURE; -+ eFailReason = DRIVER_OWN_FAIL; -+ break; -+ } -+ /* 4 <1> Initialize the Adapter */ -+ u4Status = nicInitializeAdapter(prAdapter); -+ if (u4Status != WLAN_STATUS_SUCCESS) { -+ DBGLOG(INIT, ERROR, "nicInitializeAdapter failed!\n"); -+ u4Status = WLAN_STATUS_FAILURE; -+ eFailReason = INIT_ADAPTER_FAIL; -+ break; -+ } -+ -+ /* init wake lock before interrupt enable and tx thread */ -+ KAL_WAKE_LOCK_INIT(prAdapter, &prAdapter->rTxThreadWakeLock, "WLAN TX THREAD"); -+ -+ /* 4 <2> Initialize System Service (MGMT Memory pool and STA_REC) */ -+ nicInitSystemService(prAdapter); -+ -+ /* 4 <3> Initialize Tx */ -+ nicTxInitialize(prAdapter); -+ wlanDefTxPowerCfg(prAdapter); -+ -+ /* 4 <4> Initialize Rx */ -+ nicRxInitialize(prAdapter); -+ -+#if CFG_ENABLE_FW_DOWNLOAD -+ if (pvFwImageMapFile == NULL) { -+ DBGLOG(INIT, ERROR, "No Firmware found!\n"); -+ u4Status = WLAN_STATUS_FAILURE; -+ eFailReason = RAM_CODE_DOWNLOAD_FAIL; -+ break; -+ } -+ -+ /* 1. disable interrupt, download is done by polling mode only */ -+ nicDisableInterrupt(prAdapter); -+ -+ /* 2. Initialize Tx Resource to fw download state */ -+ nicTxInitResetResource(prAdapter); -+ -+ /* 3. FW download here */ -+ u4FwLoadAddr = prRegInfo->u4LoadAddress; -+ -+#if CFG_ENABLE_FW_DIVIDED_DOWNLOAD -+ /* 3a. parse file header for decision of divided firmware download or not */ -+ prFwHead = (P_FIRMWARE_DIVIDED_DOWNLOAD_T) pvFwImageMapFile; -+ -+ if (prFwHead->u4Signature == MTK_WIFI_SIGNATURE && -+ prFwHead->u4CRC == wlanCRC32((PUINT_8) pvFwImageMapFile + u4CRCOffset, -+ u4FwImageFileLength - u4CRCOffset)) { -+ fgValidHead = TRUE; -+ } else { -+ fgValidHead = FALSE; -+ } -+ -+ /* 3b. engage divided firmware downloading */ -+ if (fgValidHead == TRUE) { -+ DBGLOG(INIT, TRACE, "wlanAdapterStart(): fgValidHead == TRUE\n"); -+ -+ for (i = 0; i < prFwHead->u4NumOfEntries; i++) { -+ -+#if CFG_START_ADDRESS_IS_1ST_SECTION_ADDR -+ if (i == 0) { -+ prRegInfo->u4StartAddress = prFwHead->arSection[i].u4DestAddr; -+ DBGLOG(INIT, TRACE, -+ "wlanAdapterStart(): FW start address 0x%08x\n", -+ prRegInfo->u4StartAddress); -+ } -+#endif -+ -+#if CFG_ENABLE_FW_DOWNLOAD_AGGREGATION -+ if (wlanImageSectionDownloadAggregated(prAdapter, -+ prFwHead->arSection[i].u4DestAddr, -+ prFwHead->arSection[i].u4Length, -+ (PUINT_8) pvFwImageMapFile + -+ prFwHead->arSection[i].u4Offset) != -+ WLAN_STATUS_SUCCESS) { -+ DBGLOG(INIT, ERROR, "Firmware scatter download failed!\n"); -+ u4Status = WLAN_STATUS_FAILURE; -+ } -+#else -+ for (j = 0; j < prFwHead->arSection[i].u4Length; j += CMD_PKT_SIZE_FOR_IMAGE) { -+ if (j + CMD_PKT_SIZE_FOR_IMAGE < prFwHead->arSection[i].u4Length) -+ u4ImgSecSize = CMD_PKT_SIZE_FOR_IMAGE; -+ else -+ u4ImgSecSize = prFwHead->arSection[i].u4Length - j; -+ -+ if (wlanImageSectionDownload(prAdapter, -+ prFwHead->arSection[i].u4DestAddr + j, -+ u4ImgSecSize, -+ (PUINT_8) pvFwImageMapFile + -+ prFwHead->arSection[i].u4Offset + j) != -+ WLAN_STATUS_SUCCESS) { -+ DBGLOG(INIT, ERROR, -+ "Firmware scatter download failed %d!\n", (int)i); -+ u4Status = WLAN_STATUS_FAILURE; -+ break; -+ } -+ } -+#endif -+ -+ /* escape from loop if any pending error occurs */ -+ if (u4Status == WLAN_STATUS_FAILURE) -+ break; -+ } -+ } else -+#endif -+#if CFG_ENABLE_FW_DOWNLOAD_AGGREGATION -+ if (wlanImageSectionDownloadAggregated(prAdapter, -+ u4FwLoadAddr, -+ u4FwImageFileLength, -+ (PUINT_8) pvFwImageMapFile) != -+ WLAN_STATUS_SUCCESS) { -+ DBGLOG(INIT, ERROR, "Firmware scatter download failed!\n"); -+ u4Status = WLAN_STATUS_FAILURE; -+ } -+#else -+ for (i = 0; i < u4FwImageFileLength; i += CMD_PKT_SIZE_FOR_IMAGE) { -+ if (i + CMD_PKT_SIZE_FOR_IMAGE < u4FwImageFileLength) -+ u4ImgSecSize = CMD_PKT_SIZE_FOR_IMAGE; -+ else -+ u4ImgSecSize = u4FwImageFileLength - i; -+ -+ if (wlanImageSectionDownload(prAdapter, -+ u4FwLoadAddr + i, -+ u4ImgSecSize, -+ (PUINT_8) pvFwImageMapFile + i) != -+ WLAN_STATUS_SUCCESS) { -+ DBGLOG(INIT, ERROR, "Firmware scatter download failed!\n"); -+ u4Status = WLAN_STATUS_FAILURE; -+ break; -+ } -+ } -+#endif -+ -+ if (u4Status != WLAN_STATUS_SUCCESS) { -+ eFailReason = RAM_CODE_DOWNLOAD_FAIL; -+ break; -+ } -+#if !CFG_ENABLE_FW_DOWNLOAD_ACK -+ /* Send INIT_CMD_ID_QUERY_PENDING_ERROR command and wait for response */ -+ if (wlanImageQueryStatus(prAdapter) != WLAN_STATUS_SUCCESS) { -+ DBGLOG(INIT, ERROR, "Firmware download failed!\n"); -+ u4Status = WLAN_STATUS_FAILURE; -+ break; -+ } -+#endif -+ -+ /* 4. send Wi-Fi Start command */ -+ DBGLOG(INIT, INFO, " send Wi-Fi Start command\n"); -+#if CFG_OVERRIDE_FW_START_ADDRESS -+ wlanConfigWifiFunc(prAdapter, TRUE, prRegInfo->u4StartAddress); -+#else -+ wlanConfigWifiFunc(prAdapter, FALSE, 0); -+#endif -+#endif -+ -+ DBGLOG(INIT, TRACE, "wlanAdapterStart(): Waiting for Ready bit..\n"); -+ /* 4 <5> check Wi-Fi FW asserts ready bit */ -+ i = 0; -+ while (1) { -+ HAL_MCR_RD(prAdapter, MCR_WCIR, &u4Value); -+ -+ if (u4Value & WCIR_WLAN_READY) { -+ DBGLOG(INIT, TRACE, "Ready bit asserted\n"); -+ break; -+ } else if (kalIsCardRemoved(prAdapter->prGlueInfo) == TRUE || fgIsBusAccessFailed == TRUE) { -+ u4Status = WLAN_STATUS_FAILURE; -+ eFailReason = WAIT_FIRMWARE_READY_FAIL; -+ break; -+ } else if (i >= CFG_RESPONSE_POLLING_TIMEOUT) { -+ UINT_32 u4MailBox0; -+ -+ nicGetMailbox(prAdapter, 0, &u4MailBox0); -+ DBGLOG(INIT, ERROR, "Waiting for Ready bit: Timeout, ID=%u\n", -+ (u4MailBox0 & 0x0000FFFF)); -+ u4Status = WLAN_STATUS_FAILURE; -+ eFailReason = WAIT_FIRMWARE_READY_FAIL; -+ break; -+ } -+ i++; -+ kalMsleep(10); -+ } -+ -+ if (u4Status == WLAN_STATUS_SUCCESS) { -+ /* 1. reset interrupt status */ -+ HAL_READ_INTR_STATUS(prAdapter, 4, (PUINT_8)&u4WHISR); -+ if (HAL_IS_TX_DONE_INTR(u4WHISR)) -+ HAL_READ_TX_RELEASED_COUNT(prAdapter, aucTxCount); -+ -+ /* 2. reset TX Resource for normal operation */ -+ nicTxResetResource(prAdapter); -+ -+ /* 3. query for permanent address by polling */ -+ wlanQueryPermanentAddress(prAdapter); -+ -+#if (CFG_SUPPORT_NIC_CAPABILITY == 1) -+ /* 4. query for NIC capability */ -+ wlanQueryNicCapability(prAdapter); -+#endif -+ /* 4.1 query for compiler flags */ -+ wlanQueryCompileFlags(prAdapter); -+ -+ /* 5. Override network address */ -+ wlanUpdateNetworkAddress(prAdapter); -+ -+ /* 6. indicate disconnection as default status */ -+ kalIndicateStatusAndComplete(prAdapter->prGlueInfo, WLAN_STATUS_MEDIA_DISCONNECT, NULL, 0); -+ } -+ -+ RECLAIM_POWER_CONTROL_TO_PM(prAdapter, FALSE); -+ -+ if (u4Status != WLAN_STATUS_SUCCESS) { -+ eFailReason = WAIT_FIRMWARE_READY_FAIL; -+ break; -+ } -+ -+ /* OID timeout timer initialize */ -+ cnmTimerInitTimer(prAdapter, -+ &prAdapter->rOidTimeoutTimer, -+ (PFN_MGMT_TIMEOUT_FUNC) wlanReleasePendingOid, (ULONG) NULL); -+ -+ /* Return Indicated Rfb list timer */ -+ cnmTimerInitTimer(prAdapter, -+ &prAdapter->rReturnIndicatedRfbListTimer, -+ (PFN_MGMT_TIMEOUT_FUNC) wlanReturnIndicatedPacketsTimeOut, (ULONG) NULL); -+ -+ /* Power state initialization */ -+ prAdapter->fgWiFiInSleepyState = FALSE; -+ prAdapter->rAcpiState = ACPI_STATE_D0; -+ -+ /* Online scan option */ -+ if (prRegInfo->fgDisOnlineScan == 0) -+ prAdapter->fgEnOnlineScan = TRUE; -+ else -+ prAdapter->fgEnOnlineScan = FALSE; -+ -+ /* Beacon lost detection option */ -+ if (prRegInfo->fgDisBcnLostDetection != 0) -+ prAdapter->fgDisBcnLostDetection = TRUE; -+ -+ /* Load compile time constant */ -+ prAdapter->rWlanInfo.u2BeaconPeriod = CFG_INIT_ADHOC_BEACON_INTERVAL; -+ prAdapter->rWlanInfo.u2AtimWindow = CFG_INIT_ADHOC_ATIM_WINDOW; -+ -+#if 1 /* set PM parameters */ -+ prAdapter->fgEnArpFilter = prRegInfo->fgEnArpFilter; -+ prAdapter->u4PsCurrentMeasureEn = prRegInfo->u4PsCurrentMeasureEn; -+ -+ prAdapter->u4UapsdAcBmp = prRegInfo->u4UapsdAcBmp; -+ -+ prAdapter->u4MaxSpLen = prRegInfo->u4MaxSpLen; -+ -+ DBGLOG(INIT, TRACE, "[1] fgEnArpFilter:0x%x, u4UapsdAcBmp:0x%x, u4MaxSpLen:0x%x", -+ prAdapter->fgEnArpFilter, prAdapter->u4UapsdAcBmp, prAdapter->u4MaxSpLen); -+ -+ prAdapter->fgEnCtiaPowerMode = FALSE; -+ -+#if CFG_SUPPORT_DBG_POWERMODE -+ prAdapter->fgEnDbgPowerMode = FALSE; -+#endif -+ -+#endif -+ -+ /* MGMT Initialization */ -+ nicInitMGMT(prAdapter, prRegInfo); -+ -+ /* Enable WZC Disassociation */ -+ prAdapter->rWifiVar.fgSupportWZCDisassociation = TRUE; -+ -+ /* Apply Rate Setting */ -+ if ((ENUM_REGISTRY_FIXED_RATE_T) (prRegInfo->u4FixedRate) < FIXED_RATE_NUM) -+ prAdapter->rWifiVar.eRateSetting = (ENUM_REGISTRY_FIXED_RATE_T) (prRegInfo->u4FixedRate); -+ else -+ prAdapter->rWifiVar.eRateSetting = FIXED_RATE_NONE; -+ -+ if (prAdapter->rWifiVar.eRateSetting == FIXED_RATE_NONE) { -+ /* Enable Auto (Long/Short) Preamble */ -+ prAdapter->rWifiVar.ePreambleType = PREAMBLE_TYPE_AUTO; -+ } else if ((prAdapter->rWifiVar.eRateSetting >= FIXED_RATE_MCS0_20M_400NS && -+ prAdapter->rWifiVar.eRateSetting <= FIXED_RATE_MCS7_20M_400NS) -+ || (prAdapter->rWifiVar.eRateSetting >= FIXED_RATE_MCS0_40M_400NS && -+ prAdapter->rWifiVar.eRateSetting <= FIXED_RATE_MCS32_400NS)) { -+ /* Force Short Preamble */ -+ prAdapter->rWifiVar.ePreambleType = PREAMBLE_TYPE_SHORT; -+ } else { -+ /* Force Long Preamble */ -+ prAdapter->rWifiVar.ePreambleType = PREAMBLE_TYPE_LONG; -+ } -+ -+ /* Disable Hidden SSID Join */ -+ prAdapter->rWifiVar.fgEnableJoinToHiddenSSID = FALSE; -+ -+ /* Enable Short Slot Time */ -+ prAdapter->rWifiVar.fgIsShortSlotTimeOptionEnable = TRUE; -+ -+ /* configure available PHY type set */ -+ nicSetAvailablePhyTypeSet(prAdapter); -+ -+#if 1 /* set PM parameters */ -+ { -+#if CFG_SUPPORT_PWR_MGT -+ prAdapter->u4PowerMode = prRegInfo->u4PowerMode; -+ prAdapter->rWlanInfo.arPowerSaveMode[NETWORK_TYPE_P2P_INDEX].ucNetTypeIndex = -+ NETWORK_TYPE_P2P_INDEX; -+ prAdapter->rWlanInfo.arPowerSaveMode[NETWORK_TYPE_P2P_INDEX].ucPsProfile = ENUM_PSP_FAST_SWITCH; -+#else -+ prAdapter->u4PowerMode = ENUM_PSP_CONTINUOUS_ACTIVE; -+#endif -+ -+ nicConfigPowerSaveProfile(prAdapter, NETWORK_TYPE_AIS_INDEX, /* FIXIT */ -+ prAdapter->u4PowerMode, FALSE); -+ } -+ -+#endif -+ -+#if CFG_SUPPORT_NVRAM -+ /* load manufacture data */ -+ wlanLoadManufactureData(prAdapter, prRegInfo); -+#endif -+ -+#ifdef CONFIG_MTK_TC1_FEATURE /* 1 //keep alive packet time change from default 30secs to 20secs. //TC01// */ -+ { -+ CMD_SW_DBG_CTRL_T rCmdSwCtrl; -+ -+ rCmdSwCtrl.u4Id = 0x90100000; -+ rCmdSwCtrl.u4Data = 30; -+ DBGLOG(INIT, TRACE, "wlanAdapterStart Keepaliveapcket 0x%x, %d\n", -+ rCmdSwCtrl.u4Id, rCmdSwCtrl.u4Data); -+ wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SW_DBG_CTRL, -+ TRUE, -+ FALSE, -+ FALSE, -+ NULL, NULL, sizeof(CMD_SW_DBG_CTRL_T), (PUINT_8) (&rCmdSwCtrl), NULL, 0); -+ } -+#endif -+ -+#if 0 -+ /* Update Auto rate parameters in FW */ -+ nicRlmArUpdateParms(prAdapter, -+ prRegInfo->u4ArSysParam0, -+ prRegInfo->u4ArSysParam1, prRegInfo->u4ArSysParam2, prRegInfo->u4ArSysParam3); -+#endif -+ -+#if (MT6620_E1_ASIC_HIFSYS_WORKAROUND == 1) -+ /* clock gating workaround */ -+ prAdapter->fgIsClockGatingEnabled = FALSE; -+#endif -+ -+ } while (FALSE); -+ -+ if (u4Status == WLAN_STATUS_SUCCESS) { -+ /* restore to hardware default */ -+ HAL_SET_INTR_STATUS_READ_CLEAR(prAdapter); -+ HAL_SET_MAILBOX_READ_CLEAR(prAdapter, FALSE); -+ -+ /* Enable interrupt */ -+ nicEnableInterrupt(prAdapter); -+ -+ } else { -+ /* release allocated memory */ -+ switch (eFailReason) { -+ case WAIT_FIRMWARE_READY_FAIL: -+ DBGLOG(INIT, ERROR, "Wait firmware ready fail, FailReason: %d\n", -+ eFailReason); -+ g_IsNeedDoChipReset = 1; -+ kalSendAeeWarning("[Wait firmware ready fail!]", __func__); -+ KAL_WAKE_LOCK_DESTROY(prAdapter, &prAdapter->rTxThreadWakeLock); -+ nicRxUninitialize(prAdapter); -+ nicTxRelease(prAdapter); -+ /* System Service Uninitialization */ -+ nicUninitSystemService(prAdapter); -+ nicReleaseAdapterMemory(prAdapter); -+ break; -+ case RAM_CODE_DOWNLOAD_FAIL: -+ DBGLOG(INIT, ERROR, "Ram code download fail, FailReason: %d\n", -+ eFailReason); -+ g_IsNeedDoChipReset = 1; -+ kalSendAeeWarning("[Ram code download fail!]", __func__); -+ KAL_WAKE_LOCK_DESTROY(prAdapter, &prAdapter->rTxThreadWakeLock); -+ nicRxUninitialize(prAdapter); -+ nicTxRelease(prAdapter); -+ /* System Service Uninitialization */ -+ nicUninitSystemService(prAdapter); -+ nicReleaseAdapterMemory(prAdapter); -+ break; -+ case INIT_ADAPTER_FAIL: -+ nicReleaseAdapterMemory(prAdapter); -+ break; -+ case DRIVER_OWN_FAIL: -+ nicReleaseAdapterMemory(prAdapter); -+ break; -+ case ALLOC_ADAPTER_MEM_FAIL: -+ break; -+ default: -+ break; -+ } -+ } -+ -+ return u4Status; -+} /* wlanAdapterStart */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Uninitialize the adapter -+* -+* \param prAdapter Pointer of Adapter Data Structure -+* -+* \retval WLAN_STATUS_SUCCESS: Success -+* \retval WLAN_STATUS_FAILURE: Failed -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS wlanAdapterStop(IN P_ADAPTER_T prAdapter) -+{ -+ UINT_32 i, u4Value = 0; -+ WLAN_STATUS u4Status = WLAN_STATUS_SUCCESS; -+ -+ ASSERT(prAdapter); -+ -+#if (MT6620_E1_ASIC_HIFSYS_WORKAROUND == 1) -+ if (prAdapter->fgIsClockGatingEnabled == TRUE) -+ nicDisableClockGating(prAdapter); -+#endif -+ -+ /* MGMT - unitialization */ -+ nicUninitMGMT(prAdapter); -+ -+ if (prAdapter->rAcpiState == ACPI_STATE_D0 && -+#if (CFG_CHIP_RESET_SUPPORT == 1) -+ kalIsResetting() == FALSE && -+#endif -+ kalIsCardRemoved(prAdapter->prGlueInfo) == FALSE) { -+ -+ /* 0. Disable interrupt, this can be done without Driver own */ -+ nicDisableInterrupt(prAdapter); -+ -+ ACQUIRE_POWER_CONTROL_FROM_PM(prAdapter); -+ -+ /* 1. Set CMD to FW to tell WIFI to stop (enter power off state) */ -+ /* the command must be issue to firmware even in wlanRemove() */ -+ if (prAdapter->fgIsFwOwn == FALSE && wlanSendNicPowerCtrlCmd(prAdapter, 1) == WLAN_STATUS_SUCCESS) { -+ /* 2. Clear pending interrupt */ -+ i = 0; -+ while (i < CFG_IST_LOOP_COUNT && nicProcessIST(prAdapter) != WLAN_STATUS_NOT_INDICATING) { -+ i++; -+ }; -+ -+ /* 3. Wait til RDY bit has been cleaerd */ -+ i = 0; -+ while (1) { -+ HAL_MCR_RD(prAdapter, MCR_WCIR, &u4Value); -+ -+ if ((u4Value & WCIR_WLAN_READY) == 0) -+ break; -+ else if (kalIsCardRemoved(prAdapter->prGlueInfo) == TRUE -+ || fgIsBusAccessFailed == TRUE || i >= CFG_RESPONSE_POLLING_TIMEOUT) { -+ g_IsNeedDoChipReset = 1; -+ kalSendAeeWarning("[Read WCIR_WLAN_READY fail!]", __func__); -+ break; -+ } -+ i++; -+ kalMsleep(10); -+ } -+ } -+ -+ /* 4. Set Onwership to F/W */ -+ nicpmSetFWOwn(prAdapter, FALSE); -+ -+#if CFG_FORCE_RESET_UNDER_BUS_ERROR -+ if (HAL_TEST_FLAG(prAdapter, ADAPTER_FLAG_HW_ERR) == TRUE) { -+ /* force acquire firmware own */ -+ kalDevRegWrite(prAdapter->prGlueInfo, MCR_WHLPCR, WHLPCR_FW_OWN_REQ_CLR); -+ -+ /* delay for 10ms */ -+ kalMdelay(10); -+ -+ /* force firmware reset via software interrupt */ -+ kalDevRegWrite(prAdapter->prGlueInfo, MCR_WSICR, WSICR_H2D_SW_INT_SET); -+ -+ /* force release firmware own */ -+ kalDevRegWrite(prAdapter->prGlueInfo, MCR_WHLPCR, WHLPCR_FW_OWN_REQ_SET); -+ } -+#endif -+ -+ RECLAIM_POWER_CONTROL_TO_PM(prAdapter, FALSE); -+ } -+ -+ nicRxUninitialize(prAdapter); -+ -+ nicTxRelease(prAdapter); -+ -+ /* System Service Uninitialization */ -+ nicUninitSystemService(prAdapter); -+ -+ nicReleaseAdapterMemory(prAdapter); -+ -+#if defined(_HIF_SPI) -+ /* Note: restore the SPI Mode Select from 32 bit to default */ -+ nicRestoreSpiDefMode(prAdapter); -+#endif -+ -+ return u4Status; -+} /* wlanAdapterStop */ -+ -+#if 0 -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is called by ISR (interrupt). -+* -+* \param prAdapter Pointer of Adapter Data Structure -+* -+* \retval TRUE: NIC's interrupt -+* \retval FALSE: Not NIC's interrupt -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN wlanISR(IN P_ADAPTER_T prAdapter, IN BOOLEAN fgGlobalIntrCtrl) -+{ -+ ASSERT(prAdapter); -+ -+ if (fgGlobalIntrCtrl) { -+ nicDisableInterrupt(prAdapter); -+ -+ /* wlanIST(prAdapter); */ -+ } -+ -+ return TRUE; -+} -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is called by IST (task_let). -+* -+* \param prAdapter Pointer of Adapter Data Structure -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID wlanIST(IN P_ADAPTER_T prAdapter) -+{ -+ ASSERT(prAdapter); -+ -+ /* wake up CONNSYS */ -+ ACQUIRE_POWER_CONTROL_FROM_PM(prAdapter); -+ -+ /* handle interrupts */ -+ nicProcessIST(prAdapter); -+ -+ /* re-enable HIF interrupts */ -+ nicEnableInterrupt(prAdapter); -+ -+ /* CONNSYS can decide to sleep */ -+ RECLAIM_POWER_CONTROL_TO_PM(prAdapter, FALSE); -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will check command queue to find out if any could be dequeued -+* and/or send to HIF to MT6620 -+* -+* \param prAdapter Pointer of Adapter Data Structure -+* \param prCmdQue Pointer of Command Queue (in Glue Layer) -+* -+* \retval WLAN_STATUS_SUCCESS -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS wlanProcessCommandQueue(IN P_ADAPTER_T prAdapter, IN P_QUE_T prCmdQue) -+{ -+ WLAN_STATUS rStatus; -+ QUE_T rTempCmdQue, rMergeCmdQue, rStandInCmdQue; -+ P_QUE_T prTempCmdQue, prMergeCmdQue, prStandInCmdQue; -+ P_QUE_ENTRY_T prQueueEntry; -+ P_CMD_INFO_T prCmdInfo; -+ P_MSDU_INFO_T prMsduInfo; -+ ENUM_FRAME_ACTION_T eFrameAction = FRAME_ACTION_DROP_PKT; -+ -+ KAL_SPIN_LOCK_DECLARATION(); -+ -+ /* sanity check */ -+ ASSERT(prAdapter); -+ ASSERT(prCmdQue); -+ -+ /* init */ -+ prTempCmdQue = &rTempCmdQue; -+ prMergeCmdQue = &rMergeCmdQue; -+ prStandInCmdQue = &rStandInCmdQue; -+ -+ QUEUE_INITIALIZE(prTempCmdQue); -+ QUEUE_INITIALIZE(prMergeCmdQue); -+ QUEUE_INITIALIZE(prStandInCmdQue); -+ -+ /* 4 <1> Move whole list of CMD_INFO to the temp queue */ -+ /* copy all commands to prTempCmdQue and empty prCmdQue */ -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_QUE); -+ QUEUE_MOVE_ALL(prTempCmdQue, prCmdQue); -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_QUE); -+ -+ /* 4 <2> Dequeue from head and check it is able to be sent */ -+ /* remove the first one */ -+ QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T); -+ -+ while (prQueueEntry) { -+ prCmdInfo = (P_CMD_INFO_T) prQueueEntry; -+ -+ /* check how to handle the command: drop, queue, or tx */ -+ switch (prCmdInfo->eCmdType) { -+ case COMMAND_TYPE_GENERAL_IOCTL: -+ case COMMAND_TYPE_NETWORK_IOCTL: -+ /* command packet will be always sent */ -+ eFrameAction = FRAME_ACTION_TX_PKT; -+ break; -+ -+ case COMMAND_TYPE_SECURITY_FRAME: -+ /* inquire with QM */ -+ eFrameAction = qmGetFrameAction(prAdapter, -+ prCmdInfo->eNetworkType, -+ prCmdInfo->ucStaRecIndex, NULL, FRAME_TYPE_802_1X); -+ break; -+ -+ case COMMAND_TYPE_MANAGEMENT_FRAME: -+ /* inquire with QM */ -+ prMsduInfo = (P_MSDU_INFO_T) (prCmdInfo->prPacket); -+ -+ eFrameAction = qmGetFrameAction(prAdapter, -+ prMsduInfo->ucNetworkType, -+ prMsduInfo->ucStaRecIndex, prMsduInfo, FRAME_TYPE_MMPDU); -+ break; -+ -+ default: -+ ASSERT(0); -+ break; -+ } -+ -+ /* 4 <3> handling upon dequeue result */ -+ if (eFrameAction == FRAME_ACTION_DROP_PKT) { -+ if (prCmdInfo->eCmdType == COMMAND_TYPE_SECURITY_FRAME) -+ DBGLOG(TX, WARN, "Drop Security frame seqNo=%d\n", -+ prCmdInfo->ucCmdSeqNum); -+ wlanReleaseCommand(prAdapter, prCmdInfo); -+ } else if (eFrameAction == FRAME_ACTION_QUEUE_PKT) { -+ if (prCmdInfo->eCmdType == COMMAND_TYPE_SECURITY_FRAME) -+ DBGLOG(TX, INFO, "Queue Security frame seqNo=%d\n", -+ prCmdInfo->ucCmdSeqNum); -+ QUEUE_INSERT_TAIL(prMergeCmdQue, prQueueEntry); -+ } else if (eFrameAction == FRAME_ACTION_TX_PKT) { -+ /* 4 <4> Send the command */ -+ rStatus = wlanSendCommand(prAdapter, prCmdInfo); -+ -+ if (rStatus == WLAN_STATUS_RESOURCES) { -+ /* no more TC4 resource for further transmission */ -+ QUEUE_INSERT_TAIL(prMergeCmdQue, prQueueEntry); -+ DBGLOG(TX, EVENT, "No TC4 resource to send cmd, CID=%d, SEQ=%d, CMD type=%d, OID=%d\n", -+ prCmdInfo->ucCID, prCmdInfo->ucCmdSeqNum, -+ prCmdInfo->eCmdType, prCmdInfo->fgIsOid); -+ break; -+ } else if (rStatus == WLAN_STATUS_PENDING) { -+ /* command packet which needs further handling upon response */ -+ /* i.e. we need to wait for FW's response */ -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_PENDING); -+ QUEUE_INSERT_TAIL(&(prAdapter->rPendingCmdQueue), prQueueEntry); -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_PENDING); -+ } else { -+ /* send success or fail */ -+ P_CMD_INFO_T prCmdInfo = (P_CMD_INFO_T) prQueueEntry; -+ -+ if (rStatus == WLAN_STATUS_SUCCESS) { -+ /* send success */ -+ if (prCmdInfo->pfCmdDoneHandler) { -+ prCmdInfo->pfCmdDoneHandler(prAdapter, prCmdInfo, -+ prCmdInfo->pucInfoBuffer); -+ } -+ } else { -+ /* send fail */ -+ if (prCmdInfo->fgIsOid) { -+ kalOidComplete(prAdapter->prGlueInfo, prCmdInfo->fgSetQuery, -+ prCmdInfo->u4SetInfoLen, rStatus); -+ } -+ DBGLOG(TX, WARN, "Send CMD, status=%u, CID=%d, SEQ=%d, CMD type=%d, OID=%d\n", -+ rStatus, prCmdInfo->ucCID, prCmdInfo->ucCmdSeqNum, -+ prCmdInfo->eCmdType, prCmdInfo->fgIsOid); -+ } -+ -+ /* free the command memory */ -+ cmdBufFreeCmdInfo(prAdapter, prCmdInfo); -+ } -+ } else { -+ -+ /* impossible, wrong eFrameAction */ -+ ASSERT(0); -+ } -+ -+ QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T); -+ } -+ -+ /* 4 <3> Merge back to original queue */ -+ /* 4 <3.1> Merge prMergeCmdQue & prTempCmdQue */ -+ QUEUE_CONCATENATE_QUEUES(prMergeCmdQue, prTempCmdQue); -+ -+ /* 4 <3.2> Move prCmdQue to prStandInQue, due to prCmdQue might differ due to incoming 802.1X frames */ -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_QUE); -+ -+ /* ??? here, prCmdQue shall be empty, why QUEUE_MOVE_ALL ??? */ -+ QUEUE_MOVE_ALL(prStandInCmdQue, prCmdQue); -+ -+ /* 4 <3.3> concatenate prStandInQue to prMergeCmdQue */ -+ QUEUE_CONCATENATE_QUEUES(prMergeCmdQue, prStandInCmdQue); -+ -+ /* 4 <3.4> then move prMergeCmdQue to prCmdQue */ -+ QUEUE_MOVE_ALL(prCmdQue, prMergeCmdQue); -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_QUE); -+ -+ return WLAN_STATUS_SUCCESS; -+} /* end of wlanProcessCommandQueue() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will take CMD_INFO_T which carry some information of -+* incoming OID and notify the NIC_TX to send CMD. -+* -+* \param prAdapter Pointer of Adapter Data Structure -+* \param prCmdInfo Pointer of P_CMD_INFO_T -+* -+* \retval WLAN_STATUS_SUCCESS : CMD was written to HIF and be freed(CMD Done) immediately. -+* \retval WLAN_STATUS_RESOURCE : No resource for current command, need to wait for previous -+* frame finishing their transmission. -+* \retval WLAN_STATUS_FAILURE : Get failure while access HIF or been rejected. -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS wlanSendCommand(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo) -+{ -+ P_TX_CTRL_T prTxCtrl; -+ UINT_8 ucTC; /* "Traffic Class" SW(Driver) resource classification */ -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ BOOLEAN pfgIsSecOrMgmt = FALSE; -+ -+ /* sanity check */ -+ ASSERT(prAdapter); -+ ASSERT(prCmdInfo); -+ -+ /* init */ -+ prTxCtrl = &prAdapter->rTxCtrl; -+ -+ /* DbgPrint("wlanSendCommand()\n"); */ -+ /* */ -+ /* */ -+#if DBG && 0 -+ LOG_FUNC("wlanSendCommand()\n"); -+ LOG_FUNC("CmdType %u NetworkType %u StaRecIndex %u Oid %u CID 0x%x SetQuery %u NeedResp %u CmdSeqNum %u\n", -+ prCmdInfo->eCmdType, -+ prCmdInfo->eNetworkType, -+ prCmdInfo->ucStaRecIndex, -+ prCmdInfo->fgIsOid, -+ prCmdInfo->ucCID, prCmdInfo->fgSetQuery, prCmdInfo->fgNeedResp, prCmdInfo->ucCmdSeqNum); -+#endif -+ -+#if (MT6620_E1_ASIC_HIFSYS_WORKAROUND == 1) -+ if (prAdapter->fgIsClockGatingEnabled == TRUE) -+ nicDisableClockGating(prAdapter); -+#endif -+ -+ do { -+ /* <0> card removal check */ -+ if (kalIsCardRemoved(prAdapter->prGlueInfo) == TRUE || fgIsBusAccessFailed == TRUE) { -+ rStatus = WLAN_STATUS_FAILURE; -+ break; -+ } -+ /* <1> Normal case of sending CMD Packet */ -+ if (!prCmdInfo->fgDriverDomainMCR) { -+ /* <1.1> Assign Traffic Class(TC) = TC4. */ -+ ucTC = TC4_INDEX; -+ -+ if ((prCmdInfo->eCmdType == COMMAND_TYPE_SECURITY_FRAME) || -+ (prCmdInfo->eCmdType == COMMAND_TYPE_MANAGEMENT_FRAME)) -+ pfgIsSecOrMgmt = TRUE; -+ -+ /* <1.2> Check if pending packet or resource was exhausted */ -+ rStatus = nicTxAcquireResource(prAdapter, ucTC, pfgIsSecOrMgmt); -+ if (rStatus == WLAN_STATUS_RESOURCES) { -+ DbgPrint("NO Resource:%d\n", ucTC); -+ break; -+ } -+ /* <1.3> Forward CMD_INFO_T to NIC Layer */ -+ rStatus = nicTxCmd(prAdapter, prCmdInfo, ucTC); -+ -+ /* <1.4> Set Pending in response to Query Command/Need Response */ -+ if (rStatus == WLAN_STATUS_SUCCESS) { -+ if ((!prCmdInfo->fgSetQuery) || (prCmdInfo->fgNeedResp)) -+ rStatus = WLAN_STATUS_PENDING; -+ } -+ } -+ /* <2> "Special case" for access Driver Domain MCR */ -+ else { -+ -+ P_CMD_ACCESS_REG prCmdAccessReg; -+ -+ prCmdAccessReg = (P_CMD_ACCESS_REG) (prCmdInfo->pucInfoBuffer + CMD_HDR_SIZE); -+ -+ if (prCmdInfo->fgSetQuery) { -+ /* address is in DWORD unit */ -+ HAL_MCR_WR(prAdapter, (prCmdAccessReg->u4Address & BITS(2, 31)), -+ prCmdAccessReg->u4Data); -+ } else { -+ P_CMD_ACCESS_REG prEventAccessReg; -+ UINT_32 u4Address; -+ -+ u4Address = prCmdAccessReg->u4Address; -+ prEventAccessReg = (P_CMD_ACCESS_REG) prCmdInfo->pucInfoBuffer; -+ prEventAccessReg->u4Address = u4Address; -+ /* address is in DWORD unit */ -+ HAL_MCR_RD(prAdapter, prEventAccessReg->u4Address & BITS(2, 31), -+ &prEventAccessReg->u4Data); -+ } -+ } -+ -+ } while (FALSE); -+ -+#if (MT6620_E1_ASIC_HIFSYS_WORKAROUND == 1) -+ if (prAdapter->fgIsClockGatingEnabled == FALSE) -+ nicEnableClockGating(prAdapter); -+#endif -+ -+ return rStatus; -+} /* end of wlanSendCommand() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * \brief This function will release thd CMD_INFO upon its attribution -+ * -+ * \param prAdapter Pointer of Adapter Data Structure -+ * \param prCmdInfo Pointer of CMD_INFO_T -+ * -+ * \return (none) -+ */ -+/*----------------------------------------------------------------------------*/ -+VOID wlanReleaseCommand(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo) -+{ -+ P_TX_CTRL_T prTxCtrl; -+ P_MSDU_INFO_T prMsduInfo; -+ -+ ASSERT(prAdapter); -+ ASSERT(prCmdInfo); -+ -+ prTxCtrl = &prAdapter->rTxCtrl; -+ -+ switch (prCmdInfo->eCmdType) { -+ case COMMAND_TYPE_GENERAL_IOCTL: -+ case COMMAND_TYPE_NETWORK_IOCTL: -+ if (prCmdInfo->fgIsOid) { -+ /* for OID command, we need to do complete() to wake up kalIoctl() */ -+ kalOidComplete(prAdapter->prGlueInfo, -+ prCmdInfo->fgSetQuery, prCmdInfo->u4SetInfoLen, WLAN_STATUS_FAILURE); -+ } -+ break; -+ -+ case COMMAND_TYPE_SECURITY_FRAME: -+ /* free packets in kalSecurityFrameSendComplete() */ -+ kalSecurityFrameSendComplete(prAdapter->prGlueInfo, prCmdInfo->prPacket, WLAN_STATUS_FAILURE); -+ break; -+ -+ case COMMAND_TYPE_MANAGEMENT_FRAME: -+ prMsduInfo = (P_MSDU_INFO_T) prCmdInfo->prPacket; -+ -+ /* invoke callbacks */ -+ if (prMsduInfo->pfTxDoneHandler != NULL) -+ prMsduInfo->pfTxDoneHandler(prAdapter, prMsduInfo, TX_RESULT_DROPPED_IN_DRIVER); -+ -+ GLUE_DEC_REF_CNT(prTxCtrl->i4TxMgmtPendingNum); -+ cnmMgtPktFree(prAdapter, prMsduInfo); -+ break; -+ -+ default: -+ /* impossible, shall not be here */ -+ ASSERT(0); -+ break; -+ } -+ -+ /* free command buffer and return the command header to command pool */ -+ cmdBufFreeCmdInfo(prAdapter, prCmdInfo); -+ -+} /* end of wlanReleaseCommand() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will search the CMD Queue to look for the pending OID and -+* compelete it immediately when system request a reset. -+* -+* \param prAdapter ointer of Adapter Data Structure -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID wlanReleasePendingOid(IN P_ADAPTER_T prAdapter, IN ULONG ulData) -+{ -+ P_QUE_T prCmdQue; -+ QUE_T rTempCmdQue; -+ P_QUE_T prTempCmdQue = &rTempCmdQue; -+ P_QUE_ENTRY_T prQueueEntry = (P_QUE_ENTRY_T) NULL; -+ P_CMD_INFO_T prCmdInfo = (P_CMD_INFO_T) NULL; -+ -+ KAL_SPIN_LOCK_DECLARATION(); -+ -+ DEBUGFUNC("wlanReleasePendingOid"); -+ -+ ASSERT(prAdapter); -+ -+ DBGLOG(OID, ERROR, "OID Timeout! Releasing pending OIDs ..\n"); -+ -+ do { -+ /* 1: Handle OID commands in pending queue */ -+ /* Clear Pending OID in prAdapter->rPendingCmdQueue */ -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_PENDING); -+ -+ /* move all pending commands to prTempCmdQue and empty prCmdQue */ -+ prCmdQue = &prAdapter->rPendingCmdQueue; -+ QUEUE_MOVE_ALL(prTempCmdQue, prCmdQue); -+ -+ /* get first pending command */ -+ QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T); -+ -+ while (prQueueEntry) { -+ prCmdInfo = (P_CMD_INFO_T) prQueueEntry; -+ -+ if (prCmdInfo->fgIsOid) { -+ if (prCmdInfo->pfCmdTimeoutHandler) { -+ prCmdInfo->pfCmdTimeoutHandler(prAdapter, prCmdInfo); -+ } else { -+ /* send complete() to wake up kalIoctl() */ -+ kalOidComplete(prAdapter->prGlueInfo, -+ prCmdInfo->fgSetQuery, 0, WLAN_STATUS_FAILURE); -+ } -+ -+ /* free command memory */ -+ cmdBufFreeCmdInfo(prAdapter, prCmdInfo); -+ } else { -+ /* nothing to do so re-queue it to prCmdQue */ -+ QUEUE_INSERT_TAIL(prCmdQue, prQueueEntry); -+ } -+ -+ QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T); -+ } -+ -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_PENDING); -+ -+ /* 2: Clear pending OID staying in command queue */ -+ kalOidCmdClearance(prAdapter->prGlueInfo); -+ -+ /* 3: Do complete(), do we need this? because we have completed in kalOidComplete */ -+ kalOidClearance(prAdapter->prGlueInfo); -+ -+ } while (FALSE); -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will search the CMD Queue to look for the pending CMD/OID for specific -+* NETWORK TYPE and compelete it immediately when system request a reset. -+* -+* \param prAdapter ointer of Adapter Data Structure -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID wlanReleasePendingCMDbyNetwork(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkType) -+{ -+ P_QUE_T prCmdQue; -+ QUE_T rTempCmdQue; -+ P_QUE_T prTempCmdQue = &rTempCmdQue; -+ P_QUE_ENTRY_T prQueueEntry = (P_QUE_ENTRY_T) NULL; -+ P_CMD_INFO_T prCmdInfo = (P_CMD_INFO_T) NULL; -+ -+ KAL_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(prAdapter); -+ -+ /* only free commands from the network interface, AIS, P2P, or BOW */ -+ -+ do { -+ /* 1: Clear Pending OID in prAdapter->rPendingCmdQueue */ -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_PENDING); -+ -+ prCmdQue = &prAdapter->rPendingCmdQueue; -+ QUEUE_MOVE_ALL(prTempCmdQue, prCmdQue); -+ -+ QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T); -+ while (prQueueEntry) { -+ prCmdInfo = (P_CMD_INFO_T) prQueueEntry; -+ -+ DBGLOG(P2P, TRACE, "Pending CMD for Network Type:%d\n", prCmdInfo->eNetworkType); -+ -+ if (prCmdInfo->eNetworkType == eNetworkType) { -+ if (prCmdInfo->pfCmdTimeoutHandler) { -+ prCmdInfo->pfCmdTimeoutHandler(prAdapter, prCmdInfo); -+ } else -+ kalOidComplete(prAdapter->prGlueInfo, -+ prCmdInfo->fgSetQuery, 0, WLAN_STATUS_FAILURE); -+ -+ cmdBufFreeCmdInfo(prAdapter, prCmdInfo); -+ } else { -+ QUEUE_INSERT_TAIL(prCmdQue, prQueueEntry); -+ } -+ -+ QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T); -+ } -+ -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_PENDING); -+ -+ } while (FALSE); -+ -+} /* wlanReleasePendingCMDbyNetwork */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Return the packet buffer and reallocate one to the RFB -+* -+* \param prAdapter Pointer of Adapter Data Structure -+* \param pvPacket Pointer of returned packet -+* -+* \retval WLAN_STATUS_SUCCESS: Success -+* \retval WLAN_STATUS_FAILURE: Failed -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID wlanReturnPacket(IN P_ADAPTER_T prAdapter, IN PVOID pvPacket) -+{ -+ P_RX_CTRL_T prRxCtrl; -+ P_SW_RFB_T prSwRfb = NULL; -+ -+ KAL_SPIN_LOCK_DECLARATION(); -+ -+ DEBUGFUNC("wlanReturnPacket"); -+ -+ ASSERT(prAdapter); -+ -+ prRxCtrl = &prAdapter->rRxCtrl; -+ ASSERT(prRxCtrl); -+ -+ /* free the packet */ -+ if (pvPacket) { -+ kalPacketFree(prAdapter->prGlueInfo, pvPacket); -+ RX_ADD_CNT(prRxCtrl, RX_DATA_RETURNED_COUNT, 1); -+#if CFG_NATIVE_802_11 -+ if (GLUE_TEST_FLAG(prAdapter->prGlueInfo, GLUE_FLAG_HALT)) { -+ /*Todo:: nothing*/ -+ /*Todo:: nothing*/ -+ } -+#endif -+ } -+ -+ /* free the packet control block */ -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); -+ QUEUE_REMOVE_HEAD(&prRxCtrl->rIndicatedRfbList, prSwRfb, P_SW_RFB_T); -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); -+ if (!prSwRfb) { -+ ASSERT(0); -+ return; -+ } -+ -+ if (nicRxSetupRFB(prAdapter, prSwRfb)) { -+ ASSERT(0); -+ /* return; // Don't return here or it would lost SwRfb --kc */ -+ if (!timerPendingTimer(&prAdapter->rReturnIndicatedRfbListTimer)) { -+ DBGLOG(RX, WARN, -+ "wlanReturnPacket, Start ReturnIndicatedRfbList Timer (%ds)\n", -+ RX_RETURN_INDICATED_RFB_TIMEOUT_SEC); -+ cnmTimerStartTimer(prAdapter, &prAdapter->rReturnIndicatedRfbListTimer, -+ SEC_TO_MSEC(RX_RETURN_INDICATED_RFB_TIMEOUT_SEC)); -+ } -+ } -+ nicRxReturnRFB(prAdapter, prSwRfb); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Return the indicated packet buffer and reallocate one to the RFB -+* -+* \param prAdapter Pointer of Adapter Data Structure -+* \param pvPacket Pointer of returned packet -+* -+* \retval WLAN_STATUS_SUCCESS: Success -+* \retval WLAN_STATUS_FAILURE: Failed -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID wlanReturnIndicatedPacketsTimeOut(IN P_ADAPTER_T prAdapter, IN ULONG ulData) -+{ -+ P_RX_CTRL_T prRxCtrl; -+ P_SW_RFB_T prSwRfb = NULL; -+ -+ KAL_SPIN_LOCK_DECLARATION(); -+ WLAN_STATUS status = WLAN_STATUS_SUCCESS; -+ P_QUE_T prQueList; -+ -+ DEBUGFUNC("wlanReturnIndicatedPacketsTimeOut"); -+ DBGLOG(RX, WARN, "wlanReturnIndicatedPacketsTimeOut"); -+ -+ ASSERT(prAdapter); -+ -+ prRxCtrl = &prAdapter->rRxCtrl; -+ ASSERT(prRxCtrl); -+ -+ prQueList = &prRxCtrl->rIndicatedRfbList; -+ DBGLOG(RX, WARN, "IndicatedRfbList num = %u\n", (unsigned int)prQueList->u4NumElem); -+ -+ while (QUEUE_IS_NOT_EMPTY(&prRxCtrl->rIndicatedRfbList)) { -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); -+ QUEUE_REMOVE_HEAD(&prRxCtrl->rIndicatedRfbList, prSwRfb, P_SW_RFB_T); -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); -+ -+ if (nicRxSetupRFB(prAdapter, prSwRfb)) { -+ status = WLAN_STATUS_RESOURCES; -+ ASSERT(0); -+ } -+ nicRxReturnRFB(prAdapter, prSwRfb); -+ if (status == WLAN_STATUS_RESOURCES) -+ break; -+ } -+ if (status == WLAN_STATUS_RESOURCES) { -+ DBGLOG(RX, WARN, "Start ReturnIndicatedRfbList Timer (%ds)\n", RX_RETURN_INDICATED_RFB_TIMEOUT_SEC); -+ /* restart timer */ -+ cnmTimerStartTimer(prAdapter, -+ &prAdapter->rReturnIndicatedRfbListTimer, -+ SEC_TO_MSEC(RX_RETURN_INDICATED_RFB_TIMEOUT_SEC)); -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is a required function that returns information about -+* the capabilities and status of the driver and/or its network adapter. -+* -+* \param[IN] prAdapter Pointer to the Adapter structure. -+* \param[IN] pfnOidQryHandler Function pointer for the OID query handler. -+* \param[IN] pvInfoBuf Points to a buffer for return the query information. -+* \param[IN] u4QueryBufferLen Specifies the number of bytes at pvInfoBuf. -+* \param[OUT] pu4QueryInfoLen Points to the number of bytes it written or is needed. -+* -+* \retval WLAN_STATUS_xxx Different WLAN_STATUS code returned by different handlers. -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanQueryInformation(IN P_ADAPTER_T prAdapter, -+ IN PFN_OID_HANDLER_FUNC pfnOidQryHandler, -+ IN PVOID pvInfoBuf, IN UINT_32 u4InfoBufLen, OUT PUINT_32 pu4QryInfoLen) -+{ -+ WLAN_STATUS status = WLAN_STATUS_FAILURE; -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4QryInfoLen); -+ -+ /* ignore any OID request after connected, under PS current measurement mode */ -+ /* note: return WLAN_STATUS_FAILURE or WLAN_STATUS_SUCCESS for -+ * blocking OIDs during current measurement -+ */ -+ if (prAdapter->u4PsCurrentMeasureEn && -+ (prAdapter->prGlueInfo->eParamMediaStateIndicated == PARAM_MEDIA_STATE_CONNECTED)) -+ return WLAN_STATUS_SUCCESS; -+#if 1 -+ /* most OID handler will just queue a command packet */ -+ status = pfnOidQryHandler(prAdapter, pvInfoBuf, u4InfoBufLen, pu4QryInfoLen); -+#else -+ if (wlanIsHandlerNeedHwAccess(pfnOidQryHandler, FALSE)) { -+ ACQUIRE_POWER_CONTROL_FROM_PM(prAdapter); -+ -+ /* Reset sleepy state */ -+ if (prAdapter->fgWiFiInSleepyState == TRUE) -+ prAdapter->fgWiFiInSleepyState = FALSE; -+ -+ status = pfnOidQryHandler(prAdapter, pvInfoBuf, u4InfoBufLen, pu4QryInfoLen); -+ -+ RECLAIM_POWER_CONTROL_TO_PM(prAdapter, FALSE); -+ } else -+ status = pfnOidQryHandler(prAdapter, pvInfoBuf, u4InfoBufLen, pu4QryInfoLen); -+#endif -+ -+ return status; -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is a required function that allows bound protocol drivers, -+* or NDIS, to request changes in the state information that the miniport -+* maintains for particular object identifiers, such as changes in multicast -+* addresses. -+* -+* \param[IN] prAdapter Pointer to the Glue info structure. -+* \param[IN] pfnOidSetHandler Points to the OID set handlers. -+* \param[IN] pvInfoBuf Points to a buffer containing the OID-specific data for the set. -+* \param[IN] u4InfoBufLen Specifies the number of bytes at prSetBuffer. -+* \param[OUT] pu4SetInfoLen Points to the number of bytes it read or is needed. -+* -+* \retval WLAN_STATUS_xxx Different WLAN_STATUS code returned by different handlers. -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanSetInformation(IN P_ADAPTER_T prAdapter, -+ IN PFN_OID_HANDLER_FUNC pfnOidSetHandler, -+ IN PVOID pvInfoBuf, IN UINT_32 u4InfoBufLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ WLAN_STATUS status = WLAN_STATUS_FAILURE; -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ /* ignore any OID request after connected, under PS current measurement mode */ -+ /* note: return WLAN_STATUS_FAILURE or WLAN_STATUS_SUCCESS for blocking -+ * OIDs during current measurement -+ */ -+ if (prAdapter->u4PsCurrentMeasureEn && -+ (prAdapter->prGlueInfo->eParamMediaStateIndicated == PARAM_MEDIA_STATE_CONNECTED)) -+ return WLAN_STATUS_SUCCESS; -+#if 1 -+ /* most OID handler will just queue a command packet -+ * for power state transition OIDs, handler will acquire power control by itself -+ */ -+ status = pfnOidSetHandler(prAdapter, pvInfoBuf, u4InfoBufLen, pu4SetInfoLen); -+#else -+ if (wlanIsHandlerNeedHwAccess(pfnOidSetHandler, TRUE)) { -+ ACQUIRE_POWER_CONTROL_FROM_PM(prAdapter); -+ -+ /* Reset sleepy state */ -+ if (prAdapter->fgWiFiInSleepyState == TRUE) -+ prAdapter->fgWiFiInSleepyState = FALSE; -+ -+ status = pfnOidSetHandler(prAdapter, pvInfoBuf, u4InfoBufLen, pu4SetInfoLen); -+ -+ RECLAIM_POWER_CONTROL_TO_PM(prAdapter, FALSE); -+ } else { -+ status = pfnOidSetHandler(prAdapter, pvInfoBuf, u4InfoBufLen, pu4SetInfoLen); -+ } -+#endif -+ -+ return status; -+} -+ -+#if CFG_SUPPORT_WAPI -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is a used to query driver's config wapi mode or not -+* -+* \param[IN] prAdapter Pointer to the Glue info structure. -+* -+* \retval TRUE for use wapi mode -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN wlanQueryWapiMode(IN P_ADAPTER_T prAdapter) -+{ -+ ASSERT(prAdapter); -+ -+ return prAdapter->rWifiVar.rConnSettings.fgWapiMode; -+} -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is called to set RX filter to Promiscuous Mode. -+* -+* \param[IN] prAdapter Pointer to the Adapter structure. -+* \param[IN] fgEnablePromiscuousMode Enable/ disable RX Promiscuous Mode. -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID wlanSetPromiscuousMode(IN P_ADAPTER_T prAdapter, IN BOOLEAN fgEnablePromiscuousMode) -+{ -+ ASSERT(prAdapter); -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is called to set RX filter to allow to receive -+* broadcast address packets. -+* -+* \param[IN] prAdapter Pointer to the Adapter structure. -+* \param[IN] fgEnableBroadcast Enable/ disable broadcast packet to be received. -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID wlanRxSetBroadcast(IN P_ADAPTER_T prAdapter, IN BOOLEAN fgEnableBroadcast) -+{ -+ ASSERT(prAdapter); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is called to send out CMD_NIC_POWER_CTRL command packet -+* -+* \param[IN] prAdapter Pointer to the Adapter structure. -+* \param[IN] ucPowerMode refer to CMD/EVENT document -+* -+* \return WLAN_STATUS_SUCCESS -+* \return WLAN_STATUS_FAILURE -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS wlanSendNicPowerCtrlCmd(IN P_ADAPTER_T prAdapter, IN UINT_8 ucPowerMode) -+{ -+ WLAN_STATUS status = WLAN_STATUS_SUCCESS; -+ P_GLUE_INFO_T prGlueInfo; -+ P_CMD_INFO_T prCmdInfo; -+ P_WIFI_CMD_T prWifiCmd; -+ UINT_8 ucTC, ucCmdSeqNum; -+ -+ ASSERT(prAdapter); -+ -+ prGlueInfo = prAdapter->prGlueInfo; -+ -+ /* 1. Prepare CMD */ -+ prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, (CMD_HDR_SIZE + sizeof(CMD_NIC_POWER_CTRL))); -+ if (!prCmdInfo) { -+ DBGLOG(INIT, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); -+ return WLAN_STATUS_FAILURE; -+ } -+ -+ /* 2.1 increase command sequence number */ -+ ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter); -+ DBGLOG(REQ, TRACE, "ucCmdSeqNum =%d\n", ucCmdSeqNum); -+ -+ /* 2.2 Setup common CMD Info Packet */ -+ prCmdInfo->eCmdType = COMMAND_TYPE_GENERAL_IOCTL; -+ prCmdInfo->u2InfoBufLen = (UINT_16) (CMD_HDR_SIZE + sizeof(CMD_NIC_POWER_CTRL)); -+ prCmdInfo->pfCmdDoneHandler = NULL; -+ prCmdInfo->pfCmdTimeoutHandler = NULL; -+ prCmdInfo->fgIsOid = TRUE; -+ prCmdInfo->ucCID = CMD_ID_NIC_POWER_CTRL; -+ prCmdInfo->fgSetQuery = TRUE; -+ prCmdInfo->fgNeedResp = FALSE; -+ prCmdInfo->fgDriverDomainMCR = FALSE; -+ prCmdInfo->ucCmdSeqNum = ucCmdSeqNum; -+ prCmdInfo->u4SetInfoLen = sizeof(CMD_NIC_POWER_CTRL); -+ -+ /* 2.3 Setup WIFI_CMD_T */ -+ prWifiCmd = (P_WIFI_CMD_T) (prCmdInfo->pucInfoBuffer); -+ prWifiCmd->u2TxByteCount_UserPriority = prCmdInfo->u2InfoBufLen; -+ prWifiCmd->ucCID = prCmdInfo->ucCID; -+ prWifiCmd->ucSetQuery = prCmdInfo->fgSetQuery; -+ prWifiCmd->ucSeqNum = prCmdInfo->ucCmdSeqNum; -+ -+ kalMemZero(prWifiCmd->aucBuffer, sizeof(CMD_NIC_POWER_CTRL)); -+ ((P_CMD_NIC_POWER_CTRL) (prWifiCmd->aucBuffer))->ucPowerMode = ucPowerMode; -+ -+ /* 3. Issue CMD for entering specific power mode */ -+ ucTC = TC4_INDEX; -+ -+ while (1) { -+ /* 3.0 Removal check */ -+ if (kalIsCardRemoved(prAdapter->prGlueInfo) == TRUE || fgIsBusAccessFailed == TRUE) { -+ status = WLAN_STATUS_FAILURE; -+ break; -+ } -+ /* 3.1 Acquire TX Resource */ -+ if (nicTxAcquireResource(prAdapter, ucTC, FALSE) == WLAN_STATUS_RESOURCES) { -+ -+ /* wait and poll tx resource */ -+ if (nicTxPollingResource(prAdapter, ucTC) != WLAN_STATUS_SUCCESS) { -+ DBGLOG(INIT, ERROR, "Fail to get TX resource return within timeout\n"); -+ status = WLAN_STATUS_FAILURE; -+ break; -+ } -+ continue; -+ } -+ /* 3.2 Send CMD Info Packet */ -+ if (nicTxCmd(prAdapter, prCmdInfo, ucTC) != WLAN_STATUS_SUCCESS) { -+ DBGLOG(INIT, ERROR, "Fail to transmit CMD_NIC_POWER_CTRL command\n"); -+ status = WLAN_STATUS_FAILURE; -+ } -+ -+ break; -+ }; -+ -+ /* 4. Free CMD Info Packet. */ -+ cmdBufFreeCmdInfo(prAdapter, prCmdInfo); -+ -+ /* 5. Add flag */ -+ if (ucPowerMode == 1) -+ prAdapter->fgIsEnterD3ReqIssued = TRUE; -+ -+ return status; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is called to check if it is RF test mode and -+* the OID is allowed to be called or not -+* -+* \param[IN] prAdapter Pointer to the Adapter structure. -+* \param[IN] fgEnableBroadcast Enable/ disable broadcast packet to be received. -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN wlanIsHandlerAllowedInRFTest(IN PFN_OID_HANDLER_FUNC pfnOidHandler, IN BOOLEAN fgSetInfo) -+{ -+ PFN_OID_HANDLER_FUNC *apfnOidHandlerAllowedInRFTest; -+ UINT_32 i; -+ UINT_32 u4NumOfElem; -+ -+ if (fgSetInfo) { -+ apfnOidHandlerAllowedInRFTest = apfnOidSetHandlerAllowedInRFTest; -+ u4NumOfElem = sizeof(apfnOidSetHandlerAllowedInRFTest) / sizeof(PFN_OID_HANDLER_FUNC); -+ } else { -+ apfnOidHandlerAllowedInRFTest = apfnOidQueryHandlerAllowedInRFTest; -+ u4NumOfElem = sizeof(apfnOidQueryHandlerAllowedInRFTest) / sizeof(PFN_OID_HANDLER_FUNC); -+ } -+ -+ for (i = 0; i < u4NumOfElem; i++) { -+ if (apfnOidHandlerAllowedInRFTest[i] == pfnOidHandler) -+ return TRUE; -+ } -+ -+ return FALSE; -+} -+ -+#if CFG_ENABLE_FW_DOWNLOAD -+#if CFG_ENABLE_FW_DOWNLOAD_AGGREGATION -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is called to download FW image in an aggregated way -+* -+* @param prAdapter Pointer to the Adapter structure. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanImageSectionDownloadAggregated(IN P_ADAPTER_T prAdapter, -+ IN UINT_32 u4DestAddr, IN UINT_32 u4ImgSecSize, IN PUINT_8 pucImgSecBuf) -+{ -+#if defined(MT6620) || defined(MT6628) -+ P_CMD_INFO_T prCmdInfo; -+ P_INIT_HIF_TX_HEADER_T prInitHifTxHeader; -+ P_INIT_CMD_DOWNLOAD_BUF prInitCmdDownloadBuf; -+ UINT_8 ucTC, ucCmdSeqNum; -+ WLAN_STATUS u4Status = WLAN_STATUS_SUCCESS; -+ PUINT_8 pucOutputBuf = (PUINT_8) NULL; /* Pointer to Transmit Data Structure Frame */ -+ UINT_32 u4PktCnt, u4Offset, u4Length; -+ UINT_32 u4TotalLength; -+ -+ ASSERT(prAdapter); -+ ASSERT(pucImgSecBuf); -+ -+ pucOutputBuf = prAdapter->rTxCtrl.pucTxCoalescingBufPtr; -+ -+ DEBUGFUNC("wlanImageSectionDownloadAggregated"); -+ -+ if (u4ImgSecSize == 0) -+ return WLAN_STATUS_SUCCESS; -+ /* 1. Allocate CMD Info Packet and Pre-fill Headers */ -+ prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, -+ sizeof(INIT_HIF_TX_HEADER_T) + sizeof(INIT_CMD_DOWNLOAD_BUF) + -+ CMD_PKT_SIZE_FOR_IMAGE); -+ -+ if (!prCmdInfo) { -+ DBGLOG(INIT, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); -+ return WLAN_STATUS_FAILURE; -+ } -+ -+ prCmdInfo->u2InfoBufLen = sizeof(INIT_HIF_TX_HEADER_T) + sizeof(INIT_CMD_DOWNLOAD_BUF) + CMD_PKT_SIZE_FOR_IMAGE; -+ -+ /* 2. Use TC0's resource to download image. (only TC0 is allowed) */ -+ ucTC = TC0_INDEX; -+ -+ /* 3. Setup common CMD Info Packet */ -+ prInitHifTxHeader = (P_INIT_HIF_TX_HEADER_T) (prCmdInfo->pucInfoBuffer); -+ prInitHifTxHeader->ucEtherTypeOffset = 0; -+ prInitHifTxHeader->ucCSflags = 0; -+ prInitHifTxHeader->rInitWifiCmd.ucCID = INIT_CMD_ID_DOWNLOAD_BUF; -+ -+ /* 4. Setup CMD_DOWNLOAD_BUF */ -+ prInitCmdDownloadBuf = (P_INIT_CMD_DOWNLOAD_BUF) (prInitHifTxHeader->rInitWifiCmd.aucBuffer); -+ prInitCmdDownloadBuf->u4DataMode = 0 -+#if CFG_ENABLE_FW_ENCRYPTION -+ | DOWNLOAD_BUF_ENCRYPTION_MODE -+#endif -+ ; -+ -+ /* 5.0 reset loop control variable */ -+ u4TotalLength = 0; -+ u4Offset = u4PktCnt = 0; -+ -+ /* 5.1 main loop for maximize transmission count per access */ -+ while (u4Offset < u4ImgSecSize) { -+ if (nicTxAcquireResource(prAdapter, ucTC, FALSE) == WLAN_STATUS_SUCCESS) { -+ /* 5.1.1 calculate u4Length */ -+ if (u4Offset + CMD_PKT_SIZE_FOR_IMAGE < u4ImgSecSize) -+ u4Length = CMD_PKT_SIZE_FOR_IMAGE; -+ else -+ u4Length = u4ImgSecSize - u4Offset; -+ -+ /* 5.1.1 increase command sequence number */ -+ ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter); -+ prInitHifTxHeader->rInitWifiCmd.ucSeqNum = ucCmdSeqNum; -+ -+ /* 5.1.2 update HIF TX hardware header */ -+ prInitHifTxHeader->u2TxByteCount = -+ ALIGN_4(sizeof(INIT_HIF_TX_HEADER_T) + sizeof(INIT_CMD_DOWNLOAD_BUF) + (UINT_16) u4Length); -+ -+ /* 5.1.3 fill command header */ -+ prInitCmdDownloadBuf->u4Address = u4DestAddr + u4Offset; -+ prInitCmdDownloadBuf->u4Length = u4Length; -+ prInitCmdDownloadBuf->u4CRC32 = wlanCRC32(pucImgSecBuf + u4Offset, u4Length); -+ -+ /* 5.1.4.1 copy header to coalescing buffer */ -+ kalMemCopy(pucOutputBuf + u4TotalLength, -+ (PVOID) prCmdInfo->pucInfoBuffer, -+ sizeof(INIT_HIF_TX_HEADER_T) + sizeof(INIT_CMD_DOWNLOAD_BUF)); -+ -+ /* 5.1.4.2 copy payload to coalescing buffer */ -+ kalMemCopy(pucOutputBuf + u4TotalLength + sizeof(INIT_HIF_TX_HEADER_T) + -+ sizeof(INIT_CMD_DOWNLOAD_BUF), pucImgSecBuf + u4Offset, u4Length); -+ -+ /* 5.1.4.3 update length and other variables */ -+ u4TotalLength += -+ ALIGN_4(sizeof(INIT_HIF_TX_HEADER_T) + sizeof(INIT_CMD_DOWNLOAD_BUF) + u4Length); -+ u4Offset += u4Length; -+ u4PktCnt++; -+ -+ if (u4Offset < u4ImgSecSize) -+ continue; -+ } else if (u4PktCnt == 0) { -+ /* no resource, so get some back */ -+ if (nicTxPollingResource(prAdapter, ucTC) != WLAN_STATUS_SUCCESS) { -+ u4Status = WLAN_STATUS_FAILURE; -+ DBGLOG(INIT, ERROR, "Fail to get TX resource return within timeout\n"); -+ break; -+ } -+ } -+ -+ if (u4PktCnt != 0) { -+ /* start transmission */ -+ HAL_WRITE_TX_PORT(prAdapter, -+ 0, -+ u4TotalLength, (PUINT_8) pucOutputBuf, prAdapter->u4CoalescingBufCachedSize); -+ -+ /* reset varaibles */ -+ u4PktCnt = 0; -+ u4TotalLength = 0; -+ } -+ } -+ -+ /* 8. Free CMD Info Packet. */ -+ cmdBufFreeCmdInfo(prAdapter, prCmdInfo); -+ -+ return u4Status; -+ -+#else -+#error "Only MT6620/MT6628/MT6582 supports firmware download in an aggregated way" -+ -+ return WLAN_STATUS_FAILURE; -+ -+#endif -+} -+ -+#endif -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is called to download FW image. -+* -+* @param prAdapter Pointer to the Adapter structure. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanImageSectionDownload(IN P_ADAPTER_T prAdapter, -+ IN UINT_32 u4DestAddr, IN UINT_32 u4ImgSecSize, IN PUINT_8 pucImgSecBuf) -+{ -+ P_CMD_INFO_T prCmdInfo; -+ P_INIT_HIF_TX_HEADER_T prInitHifTxHeader; -+ P_INIT_CMD_DOWNLOAD_BUF prInitCmdDownloadBuf; -+ UINT_8 ucTC, ucCmdSeqNum; -+ WLAN_STATUS u4Status = WLAN_STATUS_SUCCESS; -+ -+ ASSERT(prAdapter); -+ ASSERT(pucImgSecBuf); -+ ASSERT(u4ImgSecSize <= CMD_PKT_SIZE_FOR_IMAGE); -+ -+ DEBUGFUNC("wlanImageSectionDownload"); -+ -+ if (u4ImgSecSize == 0) -+ return WLAN_STATUS_SUCCESS; -+ /* 1. Allocate CMD Info Packet and its Buffer. */ -+ prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, -+ sizeof(INIT_HIF_TX_HEADER_T) + sizeof(INIT_CMD_DOWNLOAD_BUF) + u4ImgSecSize); -+ -+ if (!prCmdInfo) { -+ DBGLOG(INIT, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); -+ return WLAN_STATUS_FAILURE; -+ } -+ -+ prCmdInfo->u2InfoBufLen = sizeof(INIT_HIF_TX_HEADER_T) + sizeof(INIT_CMD_DOWNLOAD_BUF) + (UINT_16) u4ImgSecSize; -+ -+ /* 2. Use TC0's resource to download image. (only TC0 is allowed) */ -+ ucTC = TC0_INDEX; -+ -+ /* 3. increase command sequence number */ -+ ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter); -+ -+ /* 4. Setup common CMD Info Packet */ -+ prInitHifTxHeader = (P_INIT_HIF_TX_HEADER_T) (prCmdInfo->pucInfoBuffer); -+ prInitHifTxHeader->rInitWifiCmd.ucCID = INIT_CMD_ID_DOWNLOAD_BUF; -+ prInitHifTxHeader->rInitWifiCmd.ucSeqNum = ucCmdSeqNum; -+ -+ /* 5. Setup CMD_DOWNLOAD_BUF */ -+ prInitCmdDownloadBuf = (P_INIT_CMD_DOWNLOAD_BUF) (prInitHifTxHeader->rInitWifiCmd.aucBuffer); -+ prInitCmdDownloadBuf->u4Address = u4DestAddr; -+ prInitCmdDownloadBuf->u4Length = u4ImgSecSize; -+ prInitCmdDownloadBuf->u4CRC32 = wlanCRC32(pucImgSecBuf, u4ImgSecSize); -+ -+ prInitCmdDownloadBuf->u4DataMode = 0 -+#if CFG_ENABLE_FW_DOWNLOAD_ACK -+ | DOWNLOAD_BUF_ACK_OPTION /* ACK needed */ -+#endif -+#if CFG_ENABLE_FW_ENCRYPTION -+ | DOWNLOAD_BUF_ENCRYPTION_MODE -+#endif -+ ; -+ -+ kalMemCopy(prInitCmdDownloadBuf->aucBuffer, pucImgSecBuf, u4ImgSecSize); -+ -+ /* 6. Send FW_Download command */ -+ while (1) { -+ /* 6.1 Acquire TX Resource */ -+ if (nicTxAcquireResource(prAdapter, ucTC, FALSE) == WLAN_STATUS_RESOURCES) { -+ if (nicTxPollingResource(prAdapter, ucTC) != WLAN_STATUS_SUCCESS) { -+ u4Status = WLAN_STATUS_FAILURE; -+ DBGLOG(INIT, ERROR, "Fail to get TX resource return within timeout\n"); -+ break; -+ } -+ continue; -+ } -+ /* 6.2 Send CMD Info Packet */ -+ if (nicTxInitCmd(prAdapter, prCmdInfo, ucTC) != WLAN_STATUS_SUCCESS) { -+ u4Status = WLAN_STATUS_FAILURE; -+ DBGLOG(INIT, ERROR, "Fail to transmit image download command\n"); -+ } -+ -+ break; -+ }; -+ -+#if CFG_ENABLE_FW_DOWNLOAD_ACK -+ /* 7. Wait for INIT_EVENT_ID_CMD_RESULT */ -+ u4Status = wlanImageSectionDownloadStatus(prAdapter, ucCmdSeqNum); -+#endif -+ -+ /* 8. Free CMD Info Packet. */ -+ cmdBufFreeCmdInfo(prAdapter, prCmdInfo); -+ -+ return u4Status; -+} -+ -+#if !CFG_ENABLE_FW_DOWNLOAD_ACK -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is called to confirm previously firmware download is done without error -+* -+* @param prAdapter Pointer to the Adapter structure. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS wlanImageQueryStatus(IN P_ADAPTER_T prAdapter) -+{ -+ P_CMD_INFO_T prCmdInfo; -+ P_INIT_HIF_TX_HEADER_T prInitHifTxHeader; -+ UINT_8 aucBuffer[sizeof(INIT_HIF_RX_HEADER_T) + sizeof(INIT_EVENT_PENDING_ERROR)]; -+ UINT_32 u4RxPktLength; -+ P_INIT_HIF_RX_HEADER_T prInitHifRxHeader; -+ P_INIT_EVENT_PENDING_ERROR prEventPendingError; -+ WLAN_STATUS u4Status = WLAN_STATUS_SUCCESS; -+ UINT_8 ucTC, ucCmdSeqNum; -+ -+ ASSERT(prAdapter); -+ -+ DEBUGFUNC("wlanImageQueryStatus"); -+ -+ /* 1. Allocate CMD Info Packet and it Buffer. */ -+ prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, sizeof(INIT_HIF_TX_HEADER_T)); -+ -+ if (!prCmdInfo) { -+ DBGLOG(INIT, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); -+ return WLAN_STATUS_FAILURE; -+ } -+ -+ kalMemZero(prCmdInfo, sizeof(INIT_HIF_TX_HEADER_T)); -+ prCmdInfo->u2InfoBufLen = sizeof(INIT_HIF_TX_HEADER_T); -+ -+ /* 2. Use TC0's resource to download image. (only TC0 is allowed) */ -+ ucTC = TC0_INDEX; -+ -+ /* 3. increase command sequence number */ -+ ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter); -+ -+ /* 4. Setup common CMD Info Packet */ -+ prInitHifTxHeader = (P_INIT_HIF_TX_HEADER_T) (prCmdInfo->pucInfoBuffer); -+ prInitHifTxHeader->rInitWifiCmd.ucCID = INIT_CMD_ID_QUERY_PENDING_ERROR; -+ prInitHifTxHeader->rInitWifiCmd.ucSeqNum = ucCmdSeqNum; -+ -+ /* 5. Send command */ -+ while (1) { -+ /* 5.1 Acquire TX Resource */ -+ if (nicTxAcquireResource(prAdapter, ucTC, FALSE) == WLAN_STATUS_RESOURCES) { -+ if (nicTxPollingResource(prAdapter, ucTC) != WLAN_STATUS_SUCCESS) { -+ u4Status = WLAN_STATUS_FAILURE; -+ DBGLOG(INIT, ERROR, "Fail to get TX resource return within timeout\n"); -+ break; -+ } -+ continue; -+ } -+ /* 5.2 Send CMD Info Packet */ -+ if (nicTxInitCmd(prAdapter, prCmdInfo, ucTC) != WLAN_STATUS_SUCCESS) { -+ u4Status = WLAN_STATUS_FAILURE; -+ DBGLOG(INIT, ERROR, "Fail to transmit image download command\n"); -+ } -+ -+ break; -+ }; -+ -+ /* 6. Wait for INIT_EVENT_ID_PENDING_ERROR */ -+ do { -+ if (kalIsCardRemoved(prAdapter->prGlueInfo) == TRUE || fgIsBusAccessFailed == TRUE) { -+ u4Status = WLAN_STATUS_FAILURE; -+ } else if (nicRxWaitResponse(prAdapter, -+ 0, -+ aucBuffer, -+ sizeof(INIT_HIF_RX_HEADER_T) + sizeof(INIT_EVENT_PENDING_ERROR), -+ &u4RxPktLength) != WLAN_STATUS_SUCCESS) { -+ u4Status = WLAN_STATUS_FAILURE; -+ } else { -+ prInitHifRxHeader = (P_INIT_HIF_RX_HEADER_T) aucBuffer; -+ -+ /* EID / SeqNum check */ -+ if (prInitHifRxHeader->rInitWifiEvent.ucEID != INIT_EVENT_ID_PENDING_ERROR) { -+ u4Status = WLAN_STATUS_FAILURE; -+ } else if (prInitHifRxHeader->rInitWifiEvent.ucSeqNum != ucCmdSeqNum) { -+ u4Status = WLAN_STATUS_FAILURE; -+ } else { -+ prEventPendingError = -+ (P_INIT_EVENT_PENDING_ERROR) (prInitHifRxHeader->rInitWifiEvent.aucBuffer); -+ if (prEventPendingError->ucStatus != 0) { /* 0 for download success */ -+ u4Status = WLAN_STATUS_FAILURE; -+ } else { -+ u4Status = WLAN_STATUS_SUCCESS; -+ } -+ } -+ } -+ } while (FALSE); -+ -+ /* 7. Free CMD Info Packet. */ -+ cmdBufFreeCmdInfo(prAdapter, prCmdInfo); -+ -+ return u4Status; -+} -+ -+#else -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is called to confirm the status of -+* previously downloaded firmware scatter -+* -+* @param prAdapter Pointer to the Adapter structure. -+* ucCmdSeqNum Sequence number of previous firmware scatter -+* -+* @return WLAN_STATUS_SUCCESS -+* WLAN_STATUS_FAILURE -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS wlanImageSectionDownloadStatus(IN P_ADAPTER_T prAdapter, IN UINT_8 ucCmdSeqNum) -+{ -+ UINT_8 aucBuffer[sizeof(INIT_HIF_RX_HEADER_T) + sizeof(INIT_EVENT_CMD_RESULT)]; -+ P_INIT_HIF_RX_HEADER_T prInitHifRxHeader; -+ P_INIT_EVENT_CMD_RESULT prEventCmdResult; -+ UINT_32 u4RxPktLength; -+ WLAN_STATUS u4Status; -+ -+ ASSERT(prAdapter); -+ -+ do { -+ if (kalIsCardRemoved(prAdapter->prGlueInfo) == TRUE || fgIsBusAccessFailed == TRUE) { -+ DBGLOG(INIT, ERROR, "kalIsCardRemoved or fgIsBusAccessFailed\n"); -+ u4Status = WLAN_STATUS_FAILURE; -+ } else if (nicRxWaitResponse(prAdapter, -+ 0, -+ aucBuffer, -+ sizeof(INIT_HIF_RX_HEADER_T) + sizeof(INIT_EVENT_CMD_RESULT),/* 4B + 4B */ -+ &u4RxPktLength) != WLAN_STATUS_SUCCESS) { -+ DBGLOG(INIT, ERROR, "nicRxWaitResponse fail\n"); -+ u4Status = WLAN_STATUS_FAILURE; -+ } else { -+ prInitHifRxHeader = (P_INIT_HIF_RX_HEADER_T) aucBuffer; -+ -+ /* EID / SeqNum check */ -+ if (prInitHifRxHeader->rInitWifiEvent.ucEID != INIT_EVENT_ID_CMD_RESULT) { -+ DBGLOG(INIT, ERROR, "rInitWifiEvent.ucEID != INIT_EVENT_ID_CMD_RESULT\n"); -+ u4Status = WLAN_STATUS_FAILURE; -+ g_IsNeedDoChipReset = 1; -+ kalSendAeeWarning("[Check EID error!]", __func__); -+ } else if (prInitHifRxHeader->rInitWifiEvent.ucSeqNum != ucCmdSeqNum) { -+ DBGLOG(INIT, ERROR, "rInitWifiEvent.ucSeqNum != ucCmdSeqNum\n"); -+ u4Status = WLAN_STATUS_FAILURE; -+ g_IsNeedDoChipReset = 1; -+ kalSendAeeWarning("[Check SeqNum error!]", __func__); -+ } else { -+ prEventCmdResult = -+ (P_INIT_EVENT_CMD_RESULT) (prInitHifRxHeader->rInitWifiEvent.aucBuffer); -+ if (prEventCmdResult->ucStatus != 0) { /* 0 for download success */ -+ /* -+ 0: success -+ 1: rejected by invalid param -+ 2: rejected by incorrect CRC -+ 3: rejected by decryption failure -+ 4: unknown CMD -+ */ -+ DBGLOG(INIT, ERROR, "Read Response status error = %d\n", -+ prEventCmdResult->ucStatus); -+ u4Status = WLAN_STATUS_FAILURE; -+ } else { -+ u4Status = WLAN_STATUS_SUCCESS; -+ } -+ } -+ } -+ } while (FALSE); -+ -+ return u4Status; -+} -+ -+#endif -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is called to start FW normal operation. -+* -+* @param prAdapter Pointer to the Adapter structure. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS wlanConfigWifiFunc(IN P_ADAPTER_T prAdapter, IN BOOLEAN fgEnable, IN UINT_32 u4StartAddress) -+{ -+ P_CMD_INFO_T prCmdInfo; -+ P_INIT_HIF_TX_HEADER_T prInitHifTxHeader; -+ P_INIT_CMD_WIFI_START prInitCmdWifiStart; -+ UINT_8 ucTC, ucCmdSeqNum; -+ WLAN_STATUS u4Status = WLAN_STATUS_SUCCESS; -+ -+ ASSERT(prAdapter); -+ -+ DEBUGFUNC("wlanConfigWifiFunc"); -+ -+ /* 1. Allocate CMD Info Packet and its Buffer. */ -+ prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, sizeof(INIT_HIF_TX_HEADER_T) + sizeof(INIT_CMD_WIFI_START)); -+ -+ if (!prCmdInfo) { -+ DBGLOG(INIT, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); -+ return WLAN_STATUS_FAILURE; -+ } -+ -+ kalMemZero(prCmdInfo->pucInfoBuffer, sizeof(INIT_HIF_TX_HEADER_T) + sizeof(INIT_CMD_WIFI_START)); -+ prCmdInfo->u2InfoBufLen = sizeof(INIT_HIF_TX_HEADER_T) + sizeof(INIT_CMD_WIFI_START); -+ -+ /* 2. Always use TC0 */ -+ ucTC = TC0_INDEX; -+ -+ /* 3. increase command sequence number */ -+ ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter); -+ -+ /* 4. Setup common CMD Info Packet */ -+ prInitHifTxHeader = (P_INIT_HIF_TX_HEADER_T) (prCmdInfo->pucInfoBuffer); -+ prInitHifTxHeader->rInitWifiCmd.ucCID = INIT_CMD_ID_WIFI_START; -+ prInitHifTxHeader->rInitWifiCmd.ucSeqNum = ucCmdSeqNum; -+ -+ prInitCmdWifiStart = (P_INIT_CMD_WIFI_START) (prInitHifTxHeader->rInitWifiCmd.aucBuffer); -+ prInitCmdWifiStart->u4Override = (fgEnable == TRUE ? 1 : 0); -+ prInitCmdWifiStart->u4Address = u4StartAddress; -+ -+ /* 5. Seend WIFI start command */ -+ while (1) { -+ /* 5.1 Acquire TX Resource */ -+ if (nicTxAcquireResource(prAdapter, ucTC, FALSE) == WLAN_STATUS_RESOURCES) { -+ -+ /* wait and poll tx resource */ -+ if (nicTxPollingResource(prAdapter, ucTC) != WLAN_STATUS_SUCCESS) { -+ u4Status = WLAN_STATUS_FAILURE; -+ DBGLOG(INIT, ERROR, "Fail to get TX resource return within timeout\n"); -+ break; -+ } -+ -+ continue; -+ } -+ /* 5.2 Send CMD Info Packet */ -+ if (nicTxInitCmd(prAdapter, prCmdInfo, ucTC) != WLAN_STATUS_SUCCESS) { -+ u4Status = WLAN_STATUS_FAILURE; -+ DBGLOG(INIT, ERROR, "Fail to transmit WIFI start command\n"); -+ } -+ -+ break; -+ }; -+ -+ /* 6. Free CMD Info Packet. */ -+ cmdBufFreeCmdInfo(prAdapter, prCmdInfo); -+ -+ return u4Status; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is used to generate CRC32 checksum -+* -+* @param buf Pointer to the data. -+* @param len data length -+* -+* @return crc32 value -+*/ -+/*----------------------------------------------------------------------------*/ -+static const UINT_32 crc32_ccitt_table[256] = { -+ 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, -+ 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, -+ 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, -+ 0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, -+ 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856, -+ 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, -+ 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, -+ 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, -+ 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, -+ 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a, -+ 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, -+ 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, -+ 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, -+ 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, -+ 0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e, -+ 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, -+ 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, -+ 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, -+ 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, -+ 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, -+ 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, -+ 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, -+ 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010, -+ 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, -+ 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, -+ 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, -+ 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, -+ 0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, -+ 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344, -+ 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, -+ 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, -+ 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, -+ 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, -+ 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c, -+ 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, -+ 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, -+ 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, -+ 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, -+ 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c, -+ 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, -+ 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, -+ 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, -+ 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, -+ 0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, -+ 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278, -+ 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, -+ 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66, -+ 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, -+ 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, -+ 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, -+ 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, -+ 0x2d02ef8d -+ }; -+ -+UINT_32 wlanCRC32(PUINT_8 buf, UINT_32 len) -+{ -+ UINT_32 i, crc32 = 0xFFFFFFFF; -+ -+ for (i = 0; i < len; i++) -+ crc32 = crc32_ccitt_table[(crc32 ^ buf[i]) & 0xff] ^ (crc32 >> 8); -+ -+ return ~crc32; -+} -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is called to process queued RX packets -+* -+* @param prAdapter Pointer to the Adapter structure. -+* prSwRfbListHead Pointer to head of RX packets link list -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS wlanProcessQueuedSwRfb(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfbListHead) -+{ -+ P_SW_RFB_T prSwRfb, prNextSwRfb; -+ P_TX_CTRL_T prTxCtrl; -+ P_RX_CTRL_T prRxCtrl; -+ -+ ASSERT(prAdapter); -+ ASSERT(prSwRfbListHead); -+ -+ prTxCtrl = &prAdapter->rTxCtrl; -+ prRxCtrl = &prAdapter->rRxCtrl; -+ -+ prSwRfb = prSwRfbListHead; -+ -+ do { -+ /* save next first */ -+ prNextSwRfb = (P_SW_RFB_T) QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T) prSwRfb); -+ -+ switch (prSwRfb->eDst) { -+ case RX_PKT_DESTINATION_HOST: -+ /* to host */ -+ nicRxProcessPktWithoutReorder(prAdapter, prSwRfb); -+ break; -+ -+ case RX_PKT_DESTINATION_FORWARD: -+ /* need ot forward */ -+ nicRxProcessForwardPkt(prAdapter, prSwRfb); -+ break; -+ -+ case RX_PKT_DESTINATION_HOST_WITH_FORWARD: -+ /* to host and forward */ -+ nicRxProcessGOBroadcastPkt(prAdapter, prSwRfb); -+ break; -+ -+ case RX_PKT_DESTINATION_NULL: -+ /* free it */ -+ nicRxReturnRFB(prAdapter, prSwRfb); -+ break; -+ -+ default: -+ break; -+ } -+ -+#if CFG_HIF_RX_STARVATION_WARNING -+ prRxCtrl->u4DequeuedCnt++; -+#endif -+ -+ /* check next queued packet */ -+ prSwRfb = prNextSwRfb; -+ } while (prSwRfb); -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is called to purge queued TX packets -+* by indicating failure to OS and returned to free list -+* -+* @param prAdapter Pointer to the Adapter structure. -+* prMsduInfoListHead Pointer to head of TX packets link list -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS wlanProcessQueuedMsduInfo(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfoListHead) -+{ -+ ASSERT(prAdapter); -+ ASSERT(prMsduInfoListHead); -+ -+ nicTxFreeMsduInfoPacket(prAdapter, prMsduInfoListHead); -+ nicTxReturnMsduInfo(prAdapter, prMsduInfoListHead); -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is called to check if the OID handler needs timeout -+* -+* @param prAdapter Pointer to the Adapter structure. -+* pfnOidHandler Pointer to the OID handler -+* -+* @return TRUE -+* FALSE -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN wlanoidTimeoutCheck(IN P_ADAPTER_T prAdapter, IN PFN_OID_HANDLER_FUNC pfnOidHandler) -+{ -+ PFN_OID_HANDLER_FUNC *apfnOidHandlerWOTimeoutCheck; -+ UINT_32 i; -+ UINT_32 u4NumOfElem; -+ -+ apfnOidHandlerWOTimeoutCheck = apfnOidWOTimeoutCheck; -+ u4NumOfElem = sizeof(apfnOidWOTimeoutCheck) / sizeof(PFN_OID_HANDLER_FUNC); -+ -+ /* skip some OID timeout checks ? */ -+ for (i = 0; i < u4NumOfElem; i++) { -+ if (apfnOidHandlerWOTimeoutCheck[i] == pfnOidHandler) -+ return FALSE; -+ } -+ -+ /* set timer if need timeout check */ -+ /* cnmTimerStartTimer(prAdapter, */ -+ /* &(prAdapter->rOidTimeoutTimer), */ -+ /* 1000); */ -+ cnmTimerStartTimer(prAdapter, &(prAdapter->rOidTimeoutTimer), 2000); -+ -+ return TRUE; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is called to clear any pending OID timeout check -+* -+* @param prAdapter Pointer to the Adapter structure. -+* -+* @return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID wlanoidClearTimeoutCheck(IN P_ADAPTER_T prAdapter) -+{ -+ ASSERT(prAdapter); -+ -+ cnmTimerStopTimer(prAdapter, &(prAdapter->rOidTimeoutTimer)); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is called to update network address in firmware domain -+* -+* @param prAdapter Pointer to the Adapter structure. -+* -+* @return WLAN_STATUS_FAILURE The request could not be processed -+* WLAN_STATUS_PENDING The request has been queued for later processing -+* WLAN_STATUS_SUCCESS The request has been processed -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS wlanUpdateNetworkAddress(IN P_ADAPTER_T prAdapter) -+{ -+ const UINT_8 aucZeroMacAddr[] = NULL_MAC_ADDR; -+ PARAM_MAC_ADDRESS rMacAddr = {0}; -+ UINT_8 ucCmdSeqNum; -+ P_CMD_INFO_T prCmdInfo; -+ P_WIFI_CMD_T prWifiCmd; -+ P_CMD_BASIC_CONFIG prCmdBasicConfig; -+ UINT_32 u4SysTime; -+ -+ DEBUGFUNC("wlanUpdateNetworkAddress"); -+ -+ ASSERT(prAdapter); -+ -+ if (kalRetrieveNetworkAddress(prAdapter->prGlueInfo, &rMacAddr) == FALSE || IS_BMCAST_MAC_ADDR(rMacAddr) -+ || EQUAL_MAC_ADDR(aucZeroMacAddr, rMacAddr)) { -+ /* eFUSE has a valid address, don't do anything */ -+ if (prAdapter->fgIsEmbbededMacAddrValid == TRUE) { -+#if CFG_SHOW_MACADDR_SOURCE -+ DBGLOG(INIT, INFO, "Using embedded MAC address"); -+#endif -+ return WLAN_STATUS_SUCCESS; -+ } -+#if CFG_SHOW_MACADDR_SOURCE -+ DBGLOG(INIT, TRACE, "Using dynamically generated MAC address"); -+#endif -+ /* dynamic generate */ -+ u4SysTime = kalGetTimeTick(); -+ -+ rMacAddr[0] = 0x00; -+ rMacAddr[1] = 0x08; -+ rMacAddr[2] = 0x22; -+ -+ kalMemCopy(&rMacAddr[3], &u4SysTime, 3); -+ } else { -+#if CFG_SHOW_MACADDR_SOURCE -+ DBGLOG(INIT, INFO, "Using host-supplied MAC address"); -+#endif -+ } -+ -+ /* allocate command memory */ -+ prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, CMD_HDR_SIZE + sizeof(CMD_BASIC_CONFIG)); -+ -+ if (!prCmdInfo) { -+ DBGLOG(INIT, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); -+ return WLAN_STATUS_FAILURE; -+ } -+ /* increase command sequence number */ -+ ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter); -+ -+ /* compose CMD_BUILD_CONNECTION cmd pkt */ -+ prCmdInfo->eCmdType = COMMAND_TYPE_GENERAL_IOCTL; -+ prCmdInfo->u2InfoBufLen = CMD_HDR_SIZE + sizeof(CMD_BASIC_CONFIG); -+ prCmdInfo->pfCmdDoneHandler = NULL; -+ prCmdInfo->pfCmdTimeoutHandler = NULL; -+ prCmdInfo->fgIsOid = FALSE; -+ prCmdInfo->ucCID = CMD_ID_BASIC_CONFIG; -+ prCmdInfo->fgSetQuery = TRUE; -+ prCmdInfo->fgNeedResp = FALSE; -+ prCmdInfo->fgDriverDomainMCR = FALSE; -+ prCmdInfo->ucCmdSeqNum = ucCmdSeqNum; -+ prCmdInfo->u4SetInfoLen = sizeof(CMD_BASIC_CONFIG); -+ -+ /* Setup WIFI_CMD_T */ -+ prWifiCmd = (P_WIFI_CMD_T) (prCmdInfo->pucInfoBuffer); -+ prWifiCmd->u2TxByteCount_UserPriority = prCmdInfo->u2InfoBufLen; -+ prWifiCmd->ucCID = prCmdInfo->ucCID; -+ prWifiCmd->ucSetQuery = prCmdInfo->fgSetQuery; -+ prWifiCmd->ucSeqNum = prCmdInfo->ucCmdSeqNum; -+ -+ /* configure CMD_BASIC_CONFIG */ -+ prCmdBasicConfig = (P_CMD_BASIC_CONFIG) (prWifiCmd->aucBuffer); -+ kalMemCopy(&(prCmdBasicConfig->rMyMacAddr), &rMacAddr, PARAM_MAC_ADDR_LEN); -+ prCmdBasicConfig->ucNative80211 = 0; -+ prCmdBasicConfig->rCsumOffload.u2RxChecksum = 0; -+ prCmdBasicConfig->rCsumOffload.u2TxChecksum = 0; -+ -+#if CFG_TCP_IP_CHKSUM_OFFLOAD -+ if (prAdapter->u4CSUMFlags & CSUM_OFFLOAD_EN_TX_TCP) -+ prCmdBasicConfig->rCsumOffload.u2TxChecksum |= BIT(2); -+ -+ if (prAdapter->u4CSUMFlags & CSUM_OFFLOAD_EN_TX_UDP) -+ prCmdBasicConfig->rCsumOffload.u2TxChecksum |= BIT(1); -+ -+ if (prAdapter->u4CSUMFlags & CSUM_OFFLOAD_EN_TX_IP) -+ prCmdBasicConfig->rCsumOffload.u2TxChecksum |= BIT(0); -+ -+ if (prAdapter->u4CSUMFlags & CSUM_OFFLOAD_EN_RX_TCP) -+ prCmdBasicConfig->rCsumOffload.u2RxChecksum |= BIT(2); -+ -+ if (prAdapter->u4CSUMFlags & CSUM_OFFLOAD_EN_RX_UDP) -+ prCmdBasicConfig->rCsumOffload.u2RxChecksum |= BIT(1); -+ -+ if (prAdapter->u4CSUMFlags & (CSUM_OFFLOAD_EN_RX_IPv4 | CSUM_OFFLOAD_EN_RX_IPv6)) -+ prCmdBasicConfig->rCsumOffload.u2RxChecksum |= BIT(0); -+#endif -+ -+ /* send the command to FW */ -+ if (wlanSendCommand(prAdapter, prCmdInfo) == WLAN_STATUS_RESOURCES) { -+ -+ /* backup the command to wait response */ -+ prCmdInfo->pfCmdDoneHandler = nicCmdEventQueryAddress; -+ kalEnqueueCommand(prAdapter->prGlueInfo, (P_QUE_ENTRY_T) prCmdInfo); -+ -+ return WLAN_STATUS_PENDING; -+ } -+ /* send ok without response */ -+ nicCmdEventQueryAddress(prAdapter, prCmdInfo, (PUINT_8) prCmdBasicConfig); -+ cmdBufFreeCmdInfo(prAdapter, prCmdInfo); -+ -+ return WLAN_STATUS_SUCCESS; -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is called to check if the device is in RF test mode -+* -+* @param pfnOidHandler Pointer to the OID handler -+* -+* @return TRUE -+* FALSE -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN wlanQueryTestMode(IN P_ADAPTER_T prAdapter) -+{ -+ ASSERT(prAdapter); -+ -+ return prAdapter->fgTestMode; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is called to identify 802.1x and Bluetooth-over-Wi-Fi -+* security frames, and queued into command queue for strict ordering -+* due to 802.1x frames before add-key OIDs are not to be encrypted -+* -+* @param prAdapter Pointer of Adapter Data Structure -+* @param prPacket Pointer of native packet -+* -+* @return TRUE -+* FALSE -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN wlanProcessSecurityFrame(IN P_ADAPTER_T prAdapter, IN P_NATIVE_PACKET prPacket) -+{ -+ UINT_8 ucPriorityParam; -+ UINT_8 aucEthDestAddr[PARAM_MAC_ADDR_LEN]; -+ BOOLEAN fgIs1x = FALSE; -+ BOOLEAN fgIsPAL = FALSE; -+ UINT_32 u4PacketLen; -+ ULONG u4SysTime; -+ UINT_8 ucNetworkType; -+ P_CMD_INFO_T prCmdInfo; -+ UINT_8 ucCmdSeqNo = 0; -+ -+ /* 1x data packets */ -+ KAL_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(prAdapter); -+ ASSERT(prPacket); -+ -+ /* retrieve some information for packet classification */ -+ if (kalQoSFrameClassifierAndPacketInfo(prAdapter->prGlueInfo, -+ prPacket, -+ &ucPriorityParam, -+ &u4PacketLen, -+ aucEthDestAddr, -+ &fgIs1x, -+ &fgIsPAL, -+ &ucNetworkType, -+ &ucCmdSeqNo) == TRUE) { -+ /* almost TRUE except frame length < 14B */ -+ -+ if (fgIs1x == FALSE) -+ return FALSE; -+ -+ /* get a free command entry */ -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_RESOURCE); -+ QUEUE_REMOVE_HEAD(&prAdapter->rFreeCmdList, prCmdInfo, P_CMD_INFO_T); -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_RESOURCE); -+ -+ if (prCmdInfo) { -+ P_STA_RECORD_T prStaRec; -+ -+ /* fill arrival time */ -+ u4SysTime = (OS_SYSTIME) kalGetTimeTick(); -+ GLUE_SET_PKT_ARRIVAL_TIME(prPacket, u4SysTime); -+ -+ kalMemZero(prCmdInfo, sizeof(CMD_INFO_T)); -+ -+ prCmdInfo->eCmdType = COMMAND_TYPE_SECURITY_FRAME; -+ prCmdInfo->u2InfoBufLen = (UINT_16) u4PacketLen; -+ prCmdInfo->pucInfoBuffer = NULL; -+ prCmdInfo->prPacket = prPacket; -+ prCmdInfo->ucCmdSeqNum = ucCmdSeqNo; -+#if 0 -+ prCmdInfo->ucStaRecIndex = qmGetStaRecIdx(prAdapter, -+ aucEthDestAddr, -+ (ENUM_NETWORK_TYPE_INDEX_T) ucNetworkType); -+#endif -+ prStaRec = cnmGetStaRecByAddress(prAdapter, -+ (ENUM_NETWORK_TYPE_INDEX_T) ucNetworkType, -+ aucEthDestAddr); -+ if (prStaRec) -+ prCmdInfo->ucStaRecIndex = prStaRec->ucIndex; -+ else -+ prCmdInfo->ucStaRecIndex = STA_REC_INDEX_NOT_FOUND; -+ -+ prCmdInfo->eNetworkType = (ENUM_NETWORK_TYPE_INDEX_T) ucNetworkType; -+ prCmdInfo->pfCmdDoneHandler = wlanSecurityFrameTxDone; -+ prCmdInfo->pfCmdTimeoutHandler = wlanSecurityFrameTxTimeout; -+ prCmdInfo->fgIsOid = FALSE; -+ prCmdInfo->fgSetQuery = TRUE; -+ prCmdInfo->fgNeedResp = FALSE; -+ -+ /* -+ queue the 1x packet and we will send the packet to CONNSYS by -+ using command queue -+ */ -+ kalEnqueueCommand(prAdapter->prGlueInfo, (P_QUE_ENTRY_T) prCmdInfo); -+ -+ /* TRUE: means we have already handled it in the function */ -+ return TRUE; -+ } -+ -+ /* no memory, why assert ? can skip the packet ? */ -+ ASSERT(0); -+ return FALSE; -+ } -+ return FALSE; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is called when 802.1x or Bluetooth-over-Wi-Fi -+* security frames has been sent to firmware -+* -+* @param prAdapter Pointer of Adapter Data Structure -+* @param prCmdInfo Pointer of CMD_INFO_T -+* @param pucEventBuf meaningless, only for API compatibility -+* -+* @return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID wlanSecurityFrameTxDone(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) -+{ -+ ASSERT(prAdapter); -+ ASSERT(prCmdInfo); -+ -+ if (prCmdInfo->eNetworkType == NETWORK_TYPE_AIS_INDEX && -+ prAdapter->rWifiVar.rAisSpecificBssInfo.fgCounterMeasure) { -+ -+ /* AIS counter measure so change RSN FSM to SEND_DEAUTH state */ -+ P_STA_RECORD_T prSta = cnmGetStaRecByIndex(prAdapter, prCmdInfo->ucStaRecIndex); -+ -+ if (prSta) { -+ kalMsleep(10); -+ secFsmEventEapolTxDone(prAdapter, prSta, TX_RESULT_SUCCESS); -+ } -+ } -+ -+ /* free the packet */ -+ kalSecurityFrameSendComplete(prAdapter->prGlueInfo, prCmdInfo->prPacket, WLAN_STATUS_SUCCESS); -+ DBGLOG(TX, INFO, "Security frame tx done, SeqNum: %d\n", prCmdInfo->ucCmdSeqNum); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is called when 802.1x or Bluetooth-over-Wi-Fi -+* security frames has failed sending to firmware -+* -+* @param prAdapter Pointer of Adapter Data Structure -+* @param prCmdInfo Pointer of CMD_INFO_T -+* -+* @return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID wlanSecurityFrameTxTimeout(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo) -+{ -+ ASSERT(prAdapter); -+ ASSERT(prCmdInfo); -+ -+ /* free the packet */ -+ kalSecurityFrameSendComplete(prAdapter->prGlueInfo, prCmdInfo->prPacket, WLAN_STATUS_FAILURE); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is called before AIS is starting a new scan -+* -+* @param prAdapter Pointer of Adapter Data Structure -+* -+* @return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID wlanClearScanningResult(IN P_ADAPTER_T prAdapter) -+{ -+ BOOLEAN fgKeepCurrOne = FALSE; -+ UINT_32 i; -+ -+ ASSERT(prAdapter); -+ -+ /* clear scanning result except current one */ -+ /* copy current one to prAdapter->rWlanInfo.arScanResult[0] */ -+ if (kalGetMediaStateIndicated(prAdapter->prGlueInfo) == PARAM_MEDIA_STATE_CONNECTED) { -+ for (i = 0; i < prAdapter->rWlanInfo.u4ScanResultNum; i++) { -+ -+ if (EQUAL_MAC_ADDR(prAdapter->rWlanInfo.rCurrBssId.arMacAddress, -+ prAdapter->rWlanInfo.arScanResult[i].arMacAddress)) { -+ fgKeepCurrOne = TRUE; -+ -+ if (i != 0) { -+ /* copy structure */ -+ kalMemCopy(&(prAdapter->rWlanInfo.arScanResult[0]), -+ &(prAdapter->rWlanInfo.arScanResult[i]), -+ OFFSET_OF(PARAM_BSSID_EX_T, aucIEs)); -+ } -+ -+ if (prAdapter->rWlanInfo.arScanResult[i].u4IELength > 0) { -+ if (prAdapter->rWlanInfo.apucScanResultIEs[i] != -+ &(prAdapter->rWlanInfo.aucScanIEBuf[0])) { -+ /* move IEs to head */ -+ kalMemCopy(prAdapter->rWlanInfo.aucScanIEBuf, -+ prAdapter->rWlanInfo.apucScanResultIEs[i], -+ prAdapter->rWlanInfo.arScanResult[i].u4IELength); -+ } -+ /* modify IE pointer */ -+ prAdapter->rWlanInfo.apucScanResultIEs[0] = -+ &(prAdapter->rWlanInfo.aucScanIEBuf[0]); -+ } else { -+ prAdapter->rWlanInfo.apucScanResultIEs[0] = NULL; -+ } -+ -+ break; -+ } -+ } -+ } -+ -+ if (fgKeepCurrOne == TRUE) { -+ prAdapter->rWlanInfo.u4ScanResultNum = 1; -+ prAdapter->rWlanInfo.u4ScanIEBufferUsage = ALIGN_4(prAdapter->rWlanInfo.arScanResult[0].u4IELength); -+ } else { -+ prAdapter->rWlanInfo.u4ScanResultNum = 0; -+ prAdapter->rWlanInfo.u4ScanIEBufferUsage = 0; -+ } -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is called when AIS received a beacon timeout event -+* -+* @param prAdapter Pointer of Adapter Data Structure -+* @param arBSSID MAC address of the specified BSS -+* -+* @return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID wlanClearBssInScanningResult(IN P_ADAPTER_T prAdapter, IN PUINT_8 arBSSID) -+{ -+ UINT_32 i, j, u4IELength = 0, u4IEMoveLength; -+ PUINT_8 pucIEPtr; -+ -+ ASSERT(prAdapter); -+ -+ /* clear the scanning result for arBSSID */ -+ i = 0; -+ while (1) { -+ if (i >= prAdapter->rWlanInfo.u4ScanResultNum) -+ break; -+ -+ if (EQUAL_MAC_ADDR(arBSSID, prAdapter->rWlanInfo.arScanResult[i].arMacAddress)) { -+ -+ /* backup current IE length */ -+ u4IELength = ALIGN_4(prAdapter->rWlanInfo.arScanResult[i].u4IELength); -+ pucIEPtr = prAdapter->rWlanInfo.apucScanResultIEs[i]; -+ -+ /* removed from middle */ -+ for (j = i + 1; j < prAdapter->rWlanInfo.u4ScanResultNum; j++) { -+ kalMemCopy(&(prAdapter->rWlanInfo.arScanResult[j - 1]), -+ &(prAdapter->rWlanInfo.arScanResult[j]), -+ OFFSET_OF(PARAM_BSSID_EX_T, aucIEs)); -+ -+ prAdapter->rWlanInfo.apucScanResultIEs[j - 1] = -+ prAdapter->rWlanInfo.apucScanResultIEs[j]; -+ } -+ -+ prAdapter->rWlanInfo.u4ScanResultNum--; -+ -+ /* remove IE buffer if needed := move rest of IE buffer */ -+ if (u4IELength > 0) { -+ u4IEMoveLength = prAdapter->rWlanInfo.u4ScanIEBufferUsage - -+ (((ULONG) pucIEPtr) + (ULONG) u4IELength - -+ ((ULONG) (&(prAdapter->rWlanInfo.aucScanIEBuf[0])))); -+ -+ kalMemCopy(pucIEPtr, pucIEPtr + u4IELength, u4IEMoveLength); -+ -+ prAdapter->rWlanInfo.u4ScanIEBufferUsage -= u4IELength; -+ -+ /* correction of pointers to IE buffer */ -+ for (j = 0; j < prAdapter->rWlanInfo.u4ScanResultNum; j++) { -+ if (prAdapter->rWlanInfo.apucScanResultIEs[j] > pucIEPtr) { -+ prAdapter->rWlanInfo.apucScanResultIEs[j] = -+ (PUINT_8) ((ULONG) (prAdapter->rWlanInfo.apucScanResultIEs[j]) - -+ u4IELength); -+ } -+ } -+ } -+ } -+ -+ i++; -+ } -+ -+} -+ -+#if CFG_TEST_WIFI_DIRECT_GO -+VOID wlanEnableP2pFunction(IN P_ADAPTER_T prAdapter) -+{ -+#if 0 -+ P_MSG_P2P_FUNCTION_SWITCH_T prMsgFuncSwitch = (P_MSG_P2P_FUNCTION_SWITCH_T) NULL; -+ -+ prMsgFuncSwitch = -+ (P_MSG_P2P_FUNCTION_SWITCH_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_P2P_FUNCTION_SWITCH_T)); -+ if (!prMsgFuncSwitch) { -+ ASSERT(FALSE); -+ return; -+ } -+ -+ prMsgFuncSwitch->rMsgHdr.eMsgId = MID_MNY_P2P_FUN_SWITCH; -+ prMsgFuncSwitch->fgIsFuncOn = TRUE; -+ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgFuncSwitch, MSG_SEND_METHOD_BUF); -+#endif -+ -+} -+ -+VOID wlanEnableATGO(IN P_ADAPTER_T prAdapter) -+{ -+ -+ P_MSG_P2P_CONNECTION_REQUEST_T prMsgConnReq = (P_MSG_P2P_CONNECTION_REQUEST_T) NULL; -+ UINT_8 aucTargetDeviceID[MAC_ADDR_LEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; -+ -+ prMsgConnReq = -+ (P_MSG_P2P_CONNECTION_REQUEST_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_P2P_CONNECTION_REQUEST_T)); -+ if (!prMsgConnReq) { -+ ASSERT(FALSE); -+ return; -+ } -+ -+ prMsgConnReq->rMsgHdr.eMsgId = MID_MNY_P2P_CONNECTION_REQ; -+ -+ /*=====Param Modified for test=====*/ -+ COPY_MAC_ADDR(prMsgConnReq->aucDeviceID, aucTargetDeviceID); -+ prMsgConnReq->fgIsTobeGO = TRUE; -+ prMsgConnReq->fgIsPersistentGroup = FALSE; -+ -+ /*=====Param Modified for test=====*/ -+ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgConnReq, MSG_SEND_METHOD_BUF); -+ -+} -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is called to retrieve permanent address from firmware -+* -+* @param prAdapter Pointer of Adapter Data Structure -+* -+* @return WLAN_STATUS_SUCCESS -+* WLAN_STATUS_FAILURE -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS wlanQueryPermanentAddress(IN P_ADAPTER_T prAdapter) -+{ -+ UINT_8 ucCmdSeqNum; -+ P_CMD_INFO_T prCmdInfo; -+ P_WIFI_CMD_T prWifiCmd; -+ UINT_32 u4RxPktLength; -+ UINT_8 aucBuffer[sizeof(WIFI_EVENT_T) + sizeof(EVENT_BASIC_CONFIG)]; -+ P_HIF_RX_HEADER_T prHifRxHdr; -+ P_WIFI_EVENT_T prEvent; -+ P_EVENT_BASIC_CONFIG prEventBasicConfig; -+ -+ ASSERT(prAdapter); -+ -+ DEBUGFUNC("wlanQueryPermanentAddress"); -+ -+ /* 1. Allocate CMD Info Packet and its Buffer */ -+ prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, CMD_HDR_SIZE + sizeof(CMD_BASIC_CONFIG)); -+ if (!prCmdInfo) { -+ DBGLOG(INIT, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); -+ return WLAN_STATUS_FAILURE; -+ } -+ /* increase command sequence number */ -+ ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter); -+ -+ /* compose CMD_BUILD_CONNECTION cmd pkt */ -+ prCmdInfo->eCmdType = COMMAND_TYPE_GENERAL_IOCTL; -+ prCmdInfo->u2InfoBufLen = CMD_HDR_SIZE + sizeof(CMD_BASIC_CONFIG); -+ prCmdInfo->pfCmdDoneHandler = NULL; -+ prCmdInfo->fgIsOid = FALSE; -+ prCmdInfo->ucCID = CMD_ID_BASIC_CONFIG; -+ prCmdInfo->fgSetQuery = FALSE; -+ prCmdInfo->fgNeedResp = TRUE; -+ prCmdInfo->fgDriverDomainMCR = FALSE; -+ prCmdInfo->ucCmdSeqNum = ucCmdSeqNum; -+ prCmdInfo->u4SetInfoLen = sizeof(CMD_BASIC_CONFIG); -+ -+ /* Setup WIFI_CMD_T */ -+ prWifiCmd = (P_WIFI_CMD_T) (prCmdInfo->pucInfoBuffer); -+ prWifiCmd->u2TxByteCount_UserPriority = prCmdInfo->u2InfoBufLen; -+ prWifiCmd->ucCID = prCmdInfo->ucCID; -+ prWifiCmd->ucSetQuery = prCmdInfo->fgSetQuery; -+ prWifiCmd->ucSeqNum = prCmdInfo->ucCmdSeqNum; -+ -+ /* send the command */ -+ wlanSendCommand(prAdapter, prCmdInfo); -+ cmdBufFreeCmdInfo(prAdapter, prCmdInfo); -+ -+ /* wait for response */ -+ if (nicRxWaitResponse(prAdapter, -+ 1, -+ aucBuffer, -+ sizeof(WIFI_EVENT_T) + sizeof(EVENT_BASIC_CONFIG), /* 8B + 12B */ -+ &u4RxPktLength) != WLAN_STATUS_SUCCESS) -+ return WLAN_STATUS_FAILURE; -+ /* header checking .. */ -+ prHifRxHdr = (P_HIF_RX_HEADER_T) aucBuffer; -+ if ((prHifRxHdr->u2PacketType & HIF_RX_HDR_PACKET_TYPE_MASK) != HIF_RX_PKT_TYPE_EVENT) -+ return WLAN_STATUS_FAILURE; -+ -+ prEvent = (P_WIFI_EVENT_T) aucBuffer; -+ if (prEvent->ucEID != EVENT_ID_BASIC_CONFIG) -+ return WLAN_STATUS_FAILURE; -+ -+ prEventBasicConfig = (P_EVENT_BASIC_CONFIG) (prEvent->aucBuffer); -+ -+ COPY_MAC_ADDR(prAdapter->rWifiVar.aucPermanentAddress, &(prEventBasicConfig->rMyMacAddr)); -+ COPY_MAC_ADDR(prAdapter->rWifiVar.aucMacAddress, &(prEventBasicConfig->rMyMacAddr)); -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is called to retrieve NIC capability from firmware -+* -+* @param prAdapter Pointer of Adapter Data Structure -+* -+* @return WLAN_STATUS_SUCCESS -+* WLAN_STATUS_FAILURE -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS wlanQueryNicCapability(IN P_ADAPTER_T prAdapter) -+{ -+ UINT_8 ucCmdSeqNum; -+ P_CMD_INFO_T prCmdInfo; -+ P_WIFI_CMD_T prWifiCmd; -+ UINT_32 u4RxPktLength; -+ UINT_32 u4FwIDVersion = 0; -+ UINT_8 aucBuffer[sizeof(WIFI_EVENT_T) + sizeof(EVENT_NIC_CAPABILITY)]; -+ P_HIF_RX_HEADER_T prHifRxHdr; -+ P_WIFI_EVENT_T prEvent; -+ P_EVENT_NIC_CAPABILITY prEventNicCapability; -+ -+ ASSERT(prAdapter); -+ -+ DEBUGFUNC("wlanQueryNicCapability"); -+ -+ /* 1. Allocate CMD Info Packet and its Buffer */ -+ prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, CMD_HDR_SIZE + sizeof(EVENT_NIC_CAPABILITY)); -+ if (!prCmdInfo) { -+ DBGLOG(INIT, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); -+ return WLAN_STATUS_FAILURE; -+ } -+ /* increase command sequence number */ -+ ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter); -+ -+ /* compose CMD_BUILD_CONNECTION cmd pkt */ -+ prCmdInfo->eCmdType = COMMAND_TYPE_GENERAL_IOCTL; -+ prCmdInfo->u2InfoBufLen = CMD_HDR_SIZE + sizeof(EVENT_NIC_CAPABILITY); -+ prCmdInfo->pfCmdDoneHandler = NULL; -+ prCmdInfo->fgIsOid = FALSE; -+ prCmdInfo->ucCID = CMD_ID_GET_NIC_CAPABILITY; -+ prCmdInfo->fgSetQuery = FALSE; -+ prCmdInfo->fgNeedResp = TRUE; -+ prCmdInfo->fgDriverDomainMCR = FALSE; -+ prCmdInfo->ucCmdSeqNum = ucCmdSeqNum; -+ prCmdInfo->u4SetInfoLen = 0; -+ -+ /* Setup WIFI_CMD_T */ -+ prWifiCmd = (P_WIFI_CMD_T) (prCmdInfo->pucInfoBuffer); -+ prWifiCmd->u2TxByteCount_UserPriority = prCmdInfo->u2InfoBufLen; -+ prWifiCmd->ucCID = prCmdInfo->ucCID; -+ prWifiCmd->ucSetQuery = prCmdInfo->fgSetQuery; -+ prWifiCmd->ucSeqNum = prCmdInfo->ucCmdSeqNum; -+ -+ /* send the command */ -+ wlanSendCommand(prAdapter, prCmdInfo); -+ cmdBufFreeCmdInfo(prAdapter, prCmdInfo); -+ -+ /* wait for FW response */ -+ if (nicRxWaitResponse(prAdapter, -+ 1, -+ aucBuffer, -+ sizeof(WIFI_EVENT_T) + sizeof(EVENT_NIC_CAPABILITY), -+ &u4RxPktLength) != WLAN_STATUS_SUCCESS) -+ return WLAN_STATUS_FAILURE; -+ /* header checking .. */ -+ prHifRxHdr = (P_HIF_RX_HEADER_T) aucBuffer; -+ if ((prHifRxHdr->u2PacketType & HIF_RX_HDR_PACKET_TYPE_MASK) != HIF_RX_PKT_TYPE_EVENT) -+ return WLAN_STATUS_FAILURE; -+ -+ prEvent = (P_WIFI_EVENT_T) aucBuffer; -+ if (prEvent->ucEID != EVENT_ID_NIC_CAPABILITY) -+ return WLAN_STATUS_FAILURE; -+ -+ prEventNicCapability = (P_EVENT_NIC_CAPABILITY) (prEvent->aucBuffer); -+ -+ prAdapter->rVerInfo.u2FwProductID = prEventNicCapability->u2ProductID; -+ prAdapter->rVerInfo.u2FwOwnVersion = prEventNicCapability->u2FwVersion; -+ prAdapter->rVerInfo.u2FwPeerVersion = prEventNicCapability->u2DriverVersion; -+ prAdapter->fgIsHw5GBandDisabled = (BOOLEAN) prEventNicCapability->ucHw5GBandDisabled; -+ prAdapter->fgIsEepromUsed = (BOOLEAN) prEventNicCapability->ucEepromUsed; -+ prAdapter->fgIsEfuseValid = (BOOLEAN) prEventNicCapability->ucEfuseValid; -+ prAdapter->fgIsEmbbededMacAddrValid = (BOOLEAN) prEventNicCapability->ucMacAddrValid; -+ -+ u4FwIDVersion = (prAdapter->rVerInfo.u2FwProductID << 16) | (prAdapter->rVerInfo.u2FwOwnVersion); -+ mtk_wcn_wmt_set_wifi_ver(u4FwIDVersion); -+#if (CFG_SUPPORT_TDLS == 1) -+ if (prEventNicCapability->ucFeatureSet & (1 << FEATURE_SET_OFFSET_TDLS)) -+ prAdapter->fgTdlsIsSup = TRUE; -+ DBGLOG(TDLS, TRACE, " support flag: 0x%x\n", prEventNicCapability->ucFeatureSet); -+#else -+ prAdapter->fgTdlsIsSup = 0; -+#endif /* CFG_SUPPORT_TDLS */ -+ -+ if (!(prEventNicCapability->ucFeatureSet & (1 << FEATURE_SET_OFFSET_5G_SUPPORT))) -+ prAdapter->fgEnable5GBand = FALSE; /* firmware does not support */ -+ -+#if CFG_ENABLE_CAL_LOG -+ DBGLOG(INIT, LOUD, " RF CAL FAIL = (%d),BB CAL FAIL = (%d)\n", -+ prEventNicCapability->ucRfCalFail, prEventNicCapability->ucBbCalFail); -+#endif -+ return WLAN_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is called to retrieve NIC capability from firmware -+* -+* @param prAdapter Pointer of Adapter Data Structure -+* -+* @return WLAN_STATUS_SUCCESS -+* WLAN_STATUS_FAILURE -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS wlanQueryDebugCode(IN P_ADAPTER_T prAdapter) -+{ -+ UINT_8 ucCmdSeqNum; -+ P_CMD_INFO_T prCmdInfo; -+ P_WIFI_CMD_T prWifiCmd; -+ -+ ASSERT(prAdapter); -+ -+ DEBUGFUNC("wlanQueryDebugCode"); -+ -+ /* 1. Allocate CMD Info Packet and its Buffer */ -+ prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, CMD_HDR_SIZE); -+ if (!prCmdInfo) { -+ DBGLOG(INIT, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); -+ return WLAN_STATUS_FAILURE; -+ } -+ /* increase command sequence number */ -+ ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter); -+ -+ /* compose CMD_BUILD_CONNECTION cmd pkt */ -+ prCmdInfo->eCmdType = COMMAND_TYPE_GENERAL_IOCTL; -+ prCmdInfo->u2InfoBufLen = CMD_HDR_SIZE; -+ prCmdInfo->pfCmdDoneHandler = NULL; -+ prCmdInfo->fgIsOid = FALSE; -+ prCmdInfo->ucCID = CMD_ID_GET_DEBUG_CODE; -+ prCmdInfo->fgSetQuery = FALSE; -+ prCmdInfo->fgNeedResp = FALSE; -+ prCmdInfo->fgDriverDomainMCR = FALSE; -+ prCmdInfo->ucCmdSeqNum = ucCmdSeqNum; -+ prCmdInfo->u4SetInfoLen = 0; -+ -+ /* Setup WIFI_CMD_T */ -+ prWifiCmd = (P_WIFI_CMD_T) (prCmdInfo->pucInfoBuffer); -+ prWifiCmd->u2TxByteCount_UserPriority = prCmdInfo->u2InfoBufLen; -+ prWifiCmd->ucCID = prCmdInfo->ucCID; -+ prWifiCmd->ucSetQuery = prCmdInfo->fgSetQuery; -+ prWifiCmd->ucSeqNum = prCmdInfo->ucCmdSeqNum; -+ -+ /* send the command */ -+ wlanSendCommand(prAdapter, prCmdInfo); -+ cmdBufFreeCmdInfo(prAdapter, prCmdInfo); -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is called to retrieve compiler flag from firmware -+* -+* @param prAdapter Pointer of Adapter Data Structure -+* -+* @return WLAN_STATUS_SUCCESS -+* WLAN_STATUS_FAILURE -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS wlanQueryCompileFlag(IN P_ADAPTER_T prAdapter, IN UINT_32 u4QueryID, OUT PUINT_32 pu4CompilerFlag) -+{ -+ UINT_8 ucCmdSeqNum; -+ P_CMD_INFO_T prCmdInfo; -+ P_WIFI_CMD_T prWifiCmd; -+ UINT_32 u4RxPktLength; -+ UINT_8 aucBuffer[sizeof(WIFI_EVENT_T) + sizeof(CMD_SW_DBG_CTRL_T)]; -+ P_HIF_RX_HEADER_T prHifRxHdr; -+ P_WIFI_EVENT_T prEvent; -+ P_CMD_SW_DBG_CTRL_T prCmdNicCompileFlag, prEventNicCompileFlag; -+ -+ ASSERT(prAdapter); -+ -+ DEBUGFUNC(__func__); -+ -+ /* 1. Allocate CMD Info Packet and its Buffer */ -+ prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, CMD_HDR_SIZE + sizeof(CMD_SW_DBG_CTRL_T)); -+ if (!prCmdInfo) { -+ DBGLOG(INIT, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); -+ return WLAN_STATUS_FAILURE; -+ } -+ /* increase command sequence number */ -+ ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter); -+ -+ /* compose CMD_BUILD_CONNECTION cmd pkt */ -+ prCmdInfo->eCmdType = COMMAND_TYPE_GENERAL_IOCTL; -+ prCmdInfo->u2InfoBufLen = CMD_HDR_SIZE + sizeof(CMD_SW_DBG_CTRL_T); -+ prCmdInfo->pfCmdDoneHandler = NULL; -+ prCmdInfo->fgIsOid = FALSE; -+ prCmdInfo->ucCID = CMD_ID_SW_DBG_CTRL; -+ prCmdInfo->fgSetQuery = FALSE; -+ prCmdInfo->fgNeedResp = TRUE; -+ prCmdInfo->fgDriverDomainMCR = FALSE; -+ prCmdInfo->ucCmdSeqNum = ucCmdSeqNum; -+ prCmdInfo->u4SetInfoLen = 0; -+ -+ /* Setup WIFI_CMD_T */ -+ prWifiCmd = (P_WIFI_CMD_T) (prCmdInfo->pucInfoBuffer); -+ prWifiCmd->u2TxByteCount_UserPriority = prCmdInfo->u2InfoBufLen; -+ prWifiCmd->ucCID = prCmdInfo->ucCID; -+ prWifiCmd->ucSetQuery = prCmdInfo->fgSetQuery; -+ prWifiCmd->ucSeqNum = prCmdInfo->ucCmdSeqNum; -+ -+ /* Fill up SW CR */ -+ prCmdNicCompileFlag = (P_CMD_SW_DBG_CTRL_T) (prWifiCmd->aucBuffer); -+ -+ prCmdNicCompileFlag->u4Id = u4QueryID; -+ -+ wlanSendCommand(prAdapter, prCmdInfo); -+ cmdBufFreeCmdInfo(prAdapter, prCmdInfo); -+ -+ if (nicRxWaitResponse(prAdapter, -+ 1, -+ aucBuffer, -+ sizeof(WIFI_EVENT_T) + sizeof(CMD_SW_DBG_CTRL_T), -+ &u4RxPktLength) != WLAN_STATUS_SUCCESS) -+ return WLAN_STATUS_FAILURE; -+ /* header checking .. */ -+ prHifRxHdr = (P_HIF_RX_HEADER_T) aucBuffer; -+ if ((prHifRxHdr->u2PacketType & HIF_RX_HDR_PACKET_TYPE_MASK) != HIF_RX_PKT_TYPE_EVENT) -+ return WLAN_STATUS_FAILURE; -+ -+ prEvent = (P_WIFI_EVENT_T) aucBuffer; -+ if (prEvent->ucEID != EVENT_ID_SW_DBG_CTRL) -+ return WLAN_STATUS_FAILURE; -+ -+ prEventNicCompileFlag = (P_CMD_SW_DBG_CTRL_T) (prEvent->aucBuffer); -+ -+ *pu4CompilerFlag = prEventNicCompileFlag->u4Data; -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+WLAN_STATUS wlanQueryCompileFlags(IN P_ADAPTER_T prAdapter) -+{ -+ wlanQueryCompileFlag(prAdapter, 0xA0240000, &prAdapter->u4FwCompileFlag0); -+ wlanQueryCompileFlag(prAdapter, 0xA0240001, &prAdapter->u4FwCompileFlag1); -+ -+ DBGLOG(INIT, TRACE, -+ "Compile Flags: 0x%08x 0x%08x\n", prAdapter->u4FwCompileFlag0, prAdapter->u4FwCompileFlag1); -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+#if defined(MT6628) -+static INT_32 wlanChangeCodeWord(INT_32 au4Input) -+{ -+ -+ UINT_16 i; -+#if TXPWR_USE_PDSLOPE -+ CODE_MAPPING_T arCodeTable[] = { -+ {0X100, -40}, -+ {0X104, -35}, -+ {0X128, -30}, -+ {0X14C, -25}, -+ {0X170, -20}, -+ {0X194, -15}, -+ {0X1B8, -10}, -+ {0X1DC, -5}, -+ {0, 0}, -+ {0X24, 5}, -+ {0X48, 10}, -+ {0X6C, 15}, -+ {0X90, 20}, -+ {0XB4, 25}, -+ {0XD8, 30}, -+ {0XFC, 35}, -+ {0XFF, 40}, -+ -+ }; -+#else -+ CODE_MAPPING_T arCodeTable[] = { -+ {0X100, 0x80}, -+ {0X104, 0x80}, -+ {0X128, 0x80}, -+ {0X14C, 0x80}, -+ {0X170, 0x80}, -+ {0X194, 0x94}, -+ {0X1B8, 0XB8}, -+ {0X1DC, 0xDC}, -+ {0, 0}, -+ {0X24, 0x24}, -+ {0X48, 0x48}, -+ {0X6C, 0x6c}, -+ {0X90, 0x7F}, -+ {0XB4, 0x7F}, -+ {0XD8, 0x7F}, -+ {0XFC, 0x7F}, -+ {0XFF, 0x7F}, -+ -+ }; -+#endif -+ -+ for (i = 0; i < sizeof(arCodeTable) / sizeof(CODE_MAPPING_T); i++) { -+ -+ if (arCodeTable[i].u4RegisterValue == au4Input) -+ return arCodeTable[i].i4TxpowerOffset; -+ } -+ -+ return 0; -+} -+#endif -+ -+#if TXPWR_USE_PDSLOPE -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief -+* -+* @param prAdapter Pointer of Adapter Data Structure -+* -+* @return WLAN_STATUS_SUCCESS -+* WLAN_STATUS_FAILURE -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS wlanQueryPdMcr(IN P_ADAPTER_T prAdapter, P_PARAM_MCR_RW_STRUCT_T prMcrRdInfo) -+{ -+ UINT_8 ucCmdSeqNum; -+ P_CMD_INFO_T prCmdInfo; -+ P_WIFI_CMD_T prWifiCmd; -+ UINT_32 u4RxPktLength; -+ UINT_8 aucBuffer[sizeof(WIFI_EVENT_T) + sizeof(CMD_ACCESS_REG)]; -+ P_HIF_RX_HEADER_T prHifRxHdr; -+ P_WIFI_EVENT_T prEvent; -+ P_CMD_ACCESS_REG prCmdMcrQuery; -+ -+ ASSERT(prAdapter); -+ -+ /* 1. Allocate CMD Info Packet and its Buffer */ -+ prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, CMD_HDR_SIZE + sizeof(CMD_ACCESS_REG)); -+ -+ if (!prCmdInfo) { -+ DBGLOG(INIT, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); -+ return WLAN_STATUS_FAILURE; -+ } -+ /* increase command sequence number */ -+ ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter); -+ -+ /* compose CMD_BUILD_CONNECTION cmd pkt */ -+ prCmdInfo->eCmdType = COMMAND_TYPE_GENERAL_IOCTL; -+ prCmdInfo->u2InfoBufLen = (UINT_16) (CMD_HDR_SIZE + sizeof(CMD_ACCESS_REG)); -+ prCmdInfo->pfCmdDoneHandler = NULL; -+ prCmdInfo->pfCmdTimeoutHandler = nicOidCmdTimeoutCommon; -+ prCmdInfo->fgIsOid = FALSE; -+ prCmdInfo->ucCID = CMD_ID_ACCESS_REG; -+ prCmdInfo->fgSetQuery = FALSE; -+ prCmdInfo->fgNeedResp = TRUE; -+ prCmdInfo->fgDriverDomainMCR = FALSE; -+ prCmdInfo->ucCmdSeqNum = ucCmdSeqNum; -+ prCmdInfo->u4SetInfoLen = sizeof(CMD_ACCESS_REG); -+ -+ /* Setup WIFI_CMD_T */ -+ prWifiCmd = (P_WIFI_CMD_T) (prCmdInfo->pucInfoBuffer); -+ prWifiCmd->u2TxByteCount_UserPriority = prCmdInfo->u2InfoBufLen; -+ prWifiCmd->ucCID = prCmdInfo->ucCID; -+ prWifiCmd->ucSetQuery = prCmdInfo->fgSetQuery; -+ prWifiCmd->ucSeqNum = prCmdInfo->ucCmdSeqNum; -+ kalMemCopy(prWifiCmd->aucBuffer, prMcrRdInfo, sizeof(CMD_ACCESS_REG)); -+ -+ wlanSendCommand(prAdapter, prCmdInfo); -+ cmdBufFreeCmdInfo(prAdapter, prCmdInfo); -+ -+ if (nicRxWaitResponse(prAdapter, -+ 1, -+ aucBuffer, -+ sizeof(WIFI_EVENT_T) + sizeof(CMD_ACCESS_REG), &u4RxPktLength) != WLAN_STATUS_SUCCESS) -+ return WLAN_STATUS_FAILURE; -+ /* header checking .. */ -+ prHifRxHdr = (P_HIF_RX_HEADER_T) aucBuffer; -+ if ((prHifRxHdr->u2PacketType & HIF_RX_HDR_PACKET_TYPE_MASK) != HIF_RX_PKT_TYPE_EVENT) -+ return WLAN_STATUS_FAILURE; -+ -+ prEvent = (P_WIFI_EVENT_T) aucBuffer; -+ -+ if (prEvent->ucEID != EVENT_ID_ACCESS_REG) -+ return WLAN_STATUS_FAILURE; -+ -+ prCmdMcrQuery = (P_CMD_ACCESS_REG) (prEvent->aucBuffer); -+ prMcrRdInfo->u4McrOffset = prCmdMcrQuery->u4Address; -+ prMcrRdInfo->u4McrData = prCmdMcrQuery->u4Data; -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+static INT_32 wlanIntRound(INT_32 au4Input) -+{ -+ -+ if (au4Input >= 0) { -+ if ((au4Input % 10) == 5) { -+ au4Input = au4Input + 5; -+ return au4Input; -+ } -+ } -+ -+ if (au4Input < 0) { -+ if ((au4Input % 10) == -5) { -+ au4Input = au4Input - 5; -+ return au4Input; -+ } -+ } -+ -+ return au4Input; -+} -+ -+static INT_32 wlanCal6628EfuseForm(IN P_ADAPTER_T prAdapter, INT_32 au4Input) -+{ -+ -+ PARAM_MCR_RW_STRUCT_T rMcrRdInfo; -+ INT_32 au4PdSlope, au4TxPwrOffset, au4TxPwrOffset_Round; -+ INT_8 auTxPwrOffset_Round; -+ -+ rMcrRdInfo.u4McrOffset = 0x60205c68; -+ rMcrRdInfo.u4McrData = 0; -+ au4TxPwrOffset = au4Input; -+ wlanQueryPdMcr(prAdapter, &rMcrRdInfo); -+ -+ au4PdSlope = (rMcrRdInfo.u4McrData) & BITS(0, 6); -+ au4TxPwrOffset_Round = wlanIntRound((au4TxPwrOffset * au4PdSlope)) / 10; -+ -+ au4TxPwrOffset_Round = -au4TxPwrOffset_Round; -+ -+ if (au4TxPwrOffset_Round < -128) -+ au4TxPwrOffset_Round = 128; -+ else if (au4TxPwrOffset_Round < 0) -+ au4TxPwrOffset_Round += 256; -+ else if (au4TxPwrOffset_Round > 127) -+ au4TxPwrOffset_Round = 127; -+ -+ auTxPwrOffset_Round = (UINT8) au4TxPwrOffset_Round; -+ -+ return au4TxPwrOffset_Round; -+} -+ -+#endif -+ -+#if defined(MT6628) -+static VOID wlanChangeNvram6620to6628(PUINT_8 pucEFUSE) -+{ -+ -+#define EFUSE_CH_OFFSET1_L_MASK_6620 BITS(0, 8) -+#define EFUSE_CH_OFFSET1_L_SHIFT_6620 0 -+#define EFUSE_CH_OFFSET1_M_MASK_6620 BITS(9, 17) -+#define EFUSE_CH_OFFSET1_M_SHIFT_6620 9 -+#define EFUSE_CH_OFFSET1_H_MASK_6620 BITS(18, 26) -+#define EFUSE_CH_OFFSET1_H_SHIFT_6620 18 -+#define EFUSE_CH_OFFSET1_VLD_MASK_6620 BIT(27) -+#define EFUSE_CH_OFFSET1_VLD_SHIFT_6620 27 -+ -+#define EFUSE_CH_OFFSET1_L_MASK_5931 BITS(0, 7) -+#define EFUSE_CH_OFFSET1_L_SHIFT_5931 0 -+#define EFUSE_CH_OFFSET1_M_MASK_5931 BITS(8, 15) -+#define EFUSE_CH_OFFSET1_M_SHIFT_5931 8 -+#define EFUSE_CH_OFFSET1_H_MASK_5931 BITS(16, 23) -+#define EFUSE_CH_OFFSET1_H_SHIFT_5931 16 -+#define EFUSE_CH_OFFSET1_VLD_MASK_5931 BIT(24) -+#define EFUSE_CH_OFFSET1_VLD_SHIFT_5931 24 -+#define EFUSE_ALL_CH_OFFSET1_MASK_5931 BITS(25, 27) -+#define EFUSE_ALL_CH_OFFSET1_SHIFT_5931 25 -+ -+ INT_32 au4ChOffset; -+ INT_16 au2ChOffsetL, au2ChOffsetM, au2ChOffsetH; -+ -+ au4ChOffset = *(UINT_32 *) (pucEFUSE + 72); -+ -+ if ((au4ChOffset & EFUSE_CH_OFFSET1_VLD_MASK_6620) && ((*(UINT_32 *) (pucEFUSE + 28)) == 0)) { -+ -+ au2ChOffsetL = ((au4ChOffset & EFUSE_CH_OFFSET1_L_MASK_6620) >> EFUSE_CH_OFFSET1_L_SHIFT_6620); -+ -+ au2ChOffsetM = ((au4ChOffset & EFUSE_CH_OFFSET1_M_MASK_6620) >> EFUSE_CH_OFFSET1_M_SHIFT_6620); -+ -+ au2ChOffsetH = ((au4ChOffset & EFUSE_CH_OFFSET1_H_MASK_6620) >> EFUSE_CH_OFFSET1_H_SHIFT_6620); -+ -+ au2ChOffsetL = wlanChangeCodeWord(au2ChOffsetL); -+ au2ChOffsetM = wlanChangeCodeWord(au2ChOffsetM); -+ au2ChOffsetH = wlanChangeCodeWord(au2ChOffsetH); -+ -+ au4ChOffset = 0; -+ au4ChOffset |= *(UINT_32 *) (pucEFUSE + 72) -+ >> (EFUSE_CH_OFFSET1_VLD_SHIFT_6620 - -+ EFUSE_CH_OFFSET1_VLD_SHIFT_5931) & EFUSE_CH_OFFSET1_VLD_MASK_5931; -+ -+ au4ChOffset |= -+ ((((UINT_32) au2ChOffsetL) << EFUSE_CH_OFFSET1_L_SHIFT_5931) & EFUSE_CH_OFFSET1_L_MASK_5931); -+ au4ChOffset |= -+ ((((UINT_32) au2ChOffsetM) << EFUSE_CH_OFFSET1_M_SHIFT_5931) & EFUSE_CH_OFFSET1_M_MASK_5931); -+ au4ChOffset |= -+ ((((UINT_32) au2ChOffsetH) << EFUSE_CH_OFFSET1_H_SHIFT_5931) & EFUSE_CH_OFFSET1_H_MASK_5931); -+ -+ *((INT_32 *) ((pucEFUSE + 28))) = au4ChOffset; -+ -+ } -+ -+} -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is called to load manufacture data from NVRAM -+* if available and valid -+* -+* @param prAdapter Pointer of Adapter Data Structure -+* @param prRegInfo Pointer of REG_INFO_T -+* -+* @return WLAN_STATUS_SUCCESS -+* WLAN_STATUS_FAILURE -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS wlanLoadManufactureData(IN P_ADAPTER_T prAdapter, IN P_REG_INFO_T prRegInfo) -+{ -+#if CFG_SUPPORT_RDD_TEST_MODE -+ CMD_RDD_CH_T rRddParam; -+#endif -+ -+ ASSERT(prAdapter); -+ -+ /* 1. Version Check */ -+ kalGetConfigurationVersion(prAdapter->prGlueInfo, -+ &(prAdapter->rVerInfo.u2Part1CfgOwnVersion), -+ &(prAdapter->rVerInfo.u2Part1CfgPeerVersion), -+ &(prAdapter->rVerInfo.u2Part2CfgOwnVersion), -+ &(prAdapter->rVerInfo.u2Part2CfgPeerVersion)); -+ -+#if (CFG_SW_NVRAM_VERSION_CHECK == 1) -+ if (CFG_DRV_OWN_VERSION < prAdapter->rVerInfo.u2Part1CfgPeerVersion -+ || CFG_DRV_OWN_VERSION < prAdapter->rVerInfo.u2Part2CfgPeerVersion -+ || prAdapter->rVerInfo.u2Part1CfgOwnVersion <= CFG_DRV_PEER_VERSION -+ || prAdapter->rVerInfo.u2Part2CfgOwnVersion <= CFG_DRV_PEER_VERSION) { -+ return WLAN_STATUS_FAILURE; -+ } -+#endif -+ -+ /* MT6620 E1/E2 would be ignored directly */ -+ if (prAdapter->rVerInfo.u2Part1CfgOwnVersion == 0x0001) { -+ prRegInfo->ucTxPwrValid = 1; -+ } else { -+ /* 2. Load TX power gain parameters if valid */ -+ if (prRegInfo->ucTxPwrValid != 0) { -+ /* send to F/W */ -+ nicUpdateTxPower(prAdapter, (P_CMD_TX_PWR_T) (&(prRegInfo->rTxPwr))); -+ } -+ } -+ -+ /* Workaround for supporting 5G */ -+ prRegInfo->ucEnable5GBand = 1; -+ prRegInfo->ucSupport5GBand = 1; -+ -+ /* 3. Check if needs to support 5GHz */ -+ /* if(prRegInfo->ucEnable5GBand) { // Frank workaround */ -+ if (1) { -+ /* check if it is disabled by hardware */ -+ if (prAdapter->fgIsHw5GBandDisabled || prRegInfo->ucSupport5GBand == 0) -+ prAdapter->fgEnable5GBand = FALSE; -+ else -+ prAdapter->fgEnable5GBand = TRUE; -+ } else -+ prAdapter->fgEnable5GBand = FALSE; -+ /* Workaround for supporting 5G */ -+ prAdapter->fgEnable5GBand = TRUE; -+/* -+ DBGLOG(INIT, INFO, "NVRAM 5G Enable(%d) SW_En(%d) HW_Dis(%d)\n", -+ prRegInfo->ucEnable5GBand, prRegInfo->ucSupport5GBand, prAdapter->fgIsHw5GBandDisabled); -+*/ -+ /* 4. Send EFUSE data */ -+#if defined(MT6628) -+ wlanChangeNvram6620to6628(prRegInfo->aucEFUSE); -+#endif -+ -+ wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SET_PHY_PARAM, -+ TRUE, -+ FALSE, -+ FALSE, NULL, NULL, sizeof(CMD_PHY_PARAM_T), (PUINT_8) (prRegInfo->aucEFUSE), NULL, 0); -+ -+#if CFG_SUPPORT_RDD_TEST_MODE -+ rRddParam.ucRddTestMode = (UINT_8) prRegInfo->u4RddTestMode; -+ rRddParam.ucRddShutCh = (UINT_8) prRegInfo->u4RddShutFreq; -+ rRddParam.ucRddStartCh = (UINT_8) nicFreq2ChannelNum(prRegInfo->u4RddStartFreq); -+ rRddParam.ucRddStopCh = (UINT_8) nicFreq2ChannelNum(prRegInfo->u4RddStopFreq); -+ rRddParam.ucRddDfs = (UINT_8) prRegInfo->u4RddDfs; -+ prAdapter->ucRddStatus = 0; -+ nicUpdateRddTestMode(prAdapter, (P_CMD_RDD_CH_T) (&rRddParam)); -+#endif -+ -+ /* 5. Get 16-bits Country Code and Bandwidth */ -+ prAdapter->rWifiVar.rConnSettings.u2CountryCode = -+ (((UINT_16) prRegInfo->au2CountryCode[0]) << 8) | (((UINT_16) prRegInfo->au2CountryCode[1]) & BITS(0, 7)); -+ -+ DBGLOG(INIT, INFO, "NVRAM 5G Enable(%d) SW_En(%d) HW_Dis(%d) CountryCode(0x%x 0x%x)\n", -+ prRegInfo->ucEnable5GBand, prRegInfo->ucSupport5GBand, prAdapter->fgIsHw5GBandDisabled, -+ prRegInfo->au2CountryCode[0], prRegInfo->au2CountryCode[1]); -+ -+#if 0 /* Bandwidth control will be controlled by GUI. 20110930 -+ * So ignore the setting from registry/NVRAM -+ */ -+ prAdapter->rWifiVar.rConnSettings.uc2G4BandwidthMode = -+ prRegInfo->uc2G4BwFixed20M ? CONFIG_BW_20M : CONFIG_BW_20_40M; -+ prAdapter->rWifiVar.rConnSettings.uc5GBandwidthMode = -+ prRegInfo->uc5GBwFixed20M ? CONFIG_BW_20M : CONFIG_BW_20_40M; -+#endif -+ -+ /* 6. Set domain and channel information to chip */ -+ rlmDomainSendCmd(prAdapter, FALSE); -+ /* Update supported channel list in channel table */ -+ wlanUpdateChannelTable(prAdapter->prGlueInfo); -+ -+ /* 7. Set band edge tx power if available */ -+ if (prRegInfo->fg2G4BandEdgePwrUsed) { -+ CMD_EDGE_TXPWR_LIMIT_T rCmdEdgeTxPwrLimit; -+ -+ rCmdEdgeTxPwrLimit.cBandEdgeMaxPwrCCK = prRegInfo->cBandEdgeMaxPwrCCK; -+ rCmdEdgeTxPwrLimit.cBandEdgeMaxPwrOFDM20 = prRegInfo->cBandEdgeMaxPwrOFDM20; -+ rCmdEdgeTxPwrLimit.cBandEdgeMaxPwrOFDM40 = prRegInfo->cBandEdgeMaxPwrOFDM40; -+ -+ DBGLOG(INIT, TRACE, "NVRAM 2G Bandedge CCK(%d) HT20(%d)HT40(%d)\n", -+ rCmdEdgeTxPwrLimit.cBandEdgeMaxPwrCCK, -+ rCmdEdgeTxPwrLimit.cBandEdgeMaxPwrOFDM20, rCmdEdgeTxPwrLimit.cBandEdgeMaxPwrOFDM40); -+ -+ wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SET_EDGE_TXPWR_LIMIT, -+ TRUE, -+ FALSE, -+ FALSE, -+ NULL, -+ NULL, sizeof(CMD_EDGE_TXPWR_LIMIT_T), (PUINT_8)&rCmdEdgeTxPwrLimit, NULL, 0); -+ } -+ /* 8. set 5G band edge tx power if available (add for 6625) */ -+ if (prAdapter->fgEnable5GBand) { -+#define NVRAM_5G_TX_BANDEDGE_VALID_OFFSET 10 -+#define NVRAM_5G_TX_BANDEDGE_OFDM20_OFFSET 11 -+#define NVRAM_5G_TX_BANDEDGE_OFDM40_OFFSET 12 -+ -+ if (prRegInfo->aucEFUSE[NVRAM_5G_TX_BANDEDGE_VALID_OFFSET]) { -+ CMD_EDGE_TXPWR_LIMIT_T rCmdEdgeTxPwrLimit; -+ -+ rCmdEdgeTxPwrLimit.cBandEdgeMaxPwrOFDM20 -+ = prRegInfo->aucEFUSE[NVRAM_5G_TX_BANDEDGE_OFDM20_OFFSET]; -+ rCmdEdgeTxPwrLimit.cBandEdgeMaxPwrOFDM40 -+ = prRegInfo->aucEFUSE[NVRAM_5G_TX_BANDEDGE_OFDM40_OFFSET]; -+ -+ DBGLOG(INIT, TRACE, "NVRAM 5G Bandedge HT20(%d)HT40(%d)\n", -+ rCmdEdgeTxPwrLimit.cBandEdgeMaxPwrOFDM20, rCmdEdgeTxPwrLimit.cBandEdgeMaxPwrOFDM40); -+ -+ wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SET_5G_EDGE_TXPWR_LIMIT, -+ TRUE, -+ FALSE, -+ FALSE, -+ NULL, -+ NULL, -+ sizeof(CMD_EDGE_TXPWR_LIMIT_T), (PUINT_8)&rCmdEdgeTxPwrLimit, NULL, 0); -+ } -+ } -+ /* 9. set RSSI compensation */ -+ /* DBGLOG(INIT, INFO, ("[frank] RSSI valid(%d) 2G(%d) 5G(%d)", -+ prRegInfo->fgRssiCompensationValidbit, -+ prRegInfo->uc2GRssiCompensation, -+ prRegInfo->uc5GRssiCompensation)); */ -+ if (prRegInfo->fgRssiCompensationValidbit) { -+ CMD_RSSI_COMPENSATE_T rCmdRssiCompensate; -+ -+ rCmdRssiCompensate.uc2GRssiCompensation = prRegInfo->uc2GRssiCompensation; -+ rCmdRssiCompensate.uc5GRssiCompensation = prRegInfo->uc5GRssiCompensation; -+ -+ DBGLOG(INIT, LOUD, "NVRAM RSSI Comp. 2G(%d)5G(%d)\n", -+ rCmdRssiCompensate.uc2GRssiCompensation, rCmdRssiCompensate.uc5GRssiCompensation); -+ wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SET_RSSI_COMPENSATE, -+ TRUE, -+ FALSE, -+ FALSE, -+ NULL, NULL, sizeof(CMD_RSSI_COMPENSATE_T), (PUINT_8)&rCmdRssiCompensate, NULL, 0); -+ } -+ /* 10. notify FW Band Support 5G */ -+ if (prAdapter->fgEnable5GBand) { -+ CMD_BAND_SUPPORT_T rCmdBandSupport; -+ -+ rCmdBandSupport.uc5GBandSupport = TRUE; -+ DBGLOG(INIT, TRACE, "NVRAM 5G BandSupport\n"); -+ wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SET_BAND_SUPPORT, -+ TRUE, -+ FALSE, -+ FALSE, -+ NULL, NULL, sizeof(CMD_BAND_SUPPORT_T), (PUINT_8)&rCmdBandSupport, NULL, 0); -+ -+ } -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is called to check -+* Media Stream Mode is set to non-default value or not, -+* and clear to default value if above criteria is met -+* -+* @param prAdapter Pointer of Adapter Data Structure -+* -+* @return TRUE -+* The media stream mode was non-default value and has been reset -+* FALSE -+* The media stream mode is default value -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN wlanResetMediaStreamMode(IN P_ADAPTER_T prAdapter) -+{ -+ ASSERT(prAdapter); -+ -+ if (prAdapter->rWlanInfo.eLinkAttr.ucMediaStreamMode != 0) { -+ prAdapter->rWlanInfo.eLinkAttr.ucMediaStreamMode = 0; -+ -+ return TRUE; -+ } else { -+ return FALSE; -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is called to check if any pending timer has expired -+* -+* @param prAdapter Pointer of Adapter Data Structure -+* -+* @return WLAN_STATUS_SUCCESS -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS wlanTimerTimeoutCheck(IN P_ADAPTER_T prAdapter) -+{ -+ ASSERT(prAdapter); -+ -+ /* check timer status */ -+ cnmTimerDoTimeOutCheck(prAdapter); -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is called to check if any pending mailbox message -+* to be handled -+* -+* @param prAdapter Pointer of Adapter Data Structure -+* -+* @return WLAN_STATUS_SUCCESS -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS wlanProcessMboxMessage(IN P_ADAPTER_T prAdapter) -+{ -+ UINT_32 i; -+ -+ ASSERT(prAdapter); -+ -+ for (i = 0; i < MBOX_ID_TOTAL_NUM; i++) { /* MBOX_ID_TOTAL_NUM = 1 */ -+ mboxRcvAllMsg(prAdapter, (ENUM_MBOX_ID_T) i); -+ } -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is called to enqueue a single TX packet into CORE -+* -+* @param prAdapter Pointer of Adapter Data Structure -+* prNativePacket Pointer of Native Packet -+* -+* @return WLAN_STATUS_SUCCESS -+* WLAN_STATUS_RESOURCES -+* WLAN_STATUS_INVALID_PACKET -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS wlanEnqueueTxPacket(IN P_ADAPTER_T prAdapter, IN P_NATIVE_PACKET prNativePacket) -+{ -+ P_TX_CTRL_T prTxCtrl; -+ P_MSDU_INFO_T prMsduInfo; -+ -+ KAL_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(prAdapter); -+ -+ prTxCtrl = &prAdapter->rTxCtrl; -+ -+ /* get a free packet header */ -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_MSDU_INFO_LIST); -+ QUEUE_REMOVE_HEAD(&prTxCtrl->rFreeMsduInfoList, prMsduInfo, P_MSDU_INFO_T); -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_MSDU_INFO_LIST); -+ -+ if (prMsduInfo == NULL) -+ return WLAN_STATUS_RESOURCES; -+ -+ prMsduInfo->eSrc = TX_PACKET_OS; -+ -+ if (nicTxFillMsduInfo(prAdapter, prMsduInfo, prNativePacket) == FALSE) { -+ /* packet is not extractable */ -+ -+ /* fill fails */ -+ kalSendComplete(prAdapter->prGlueInfo, prNativePacket, WLAN_STATUS_INVALID_PACKET); -+ -+ nicTxReturnMsduInfo(prAdapter, prMsduInfo); -+ -+ return WLAN_STATUS_INVALID_PACKET; -+ } -+ /* enqueue to QM */ -+ nicTxEnqueueMsdu(prAdapter, prMsduInfo); -+ return WLAN_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is called to flush pending TX packets in CORE -+* -+* @param prAdapter Pointer of Adapter Data Structure -+* -+* @return WLAN_STATUS_SUCCESS -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS wlanFlushTxPendingPackets(IN P_ADAPTER_T prAdapter) -+{ -+ ASSERT(prAdapter); -+ -+ return nicTxFlush(prAdapter); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief this function sends pending MSDU_INFO_T to MT6620 -+* -+* @param prAdapter Pointer to the Adapter structure. -+* @param pfgHwAccess Pointer for tracking LP-OWN status -+* -+* @retval WLAN_STATUS_SUCCESS Reset is done successfully. -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS wlanTxPendingPackets(IN P_ADAPTER_T prAdapter, IN OUT PBOOLEAN pfgHwAccess) -+{ -+ P_TX_CTRL_T prTxCtrl; -+ P_MSDU_INFO_T prMsduInfo; -+ -+ KAL_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(prAdapter); -+ prTxCtrl = &prAdapter->rTxCtrl; -+ -+ ASSERT(pfgHwAccess); -+ -+ /* <1> dequeue packets by txDequeuTxPackets() */ -+ /* Note: prMsduInfo is a packet list queue */ -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_QM_TX_QUEUE); -+ prMsduInfo = qmDequeueTxPackets(prAdapter, &prTxCtrl->rTc); -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_QM_TX_QUEUE); -+ -+ if (prMsduInfo != NULL) { -+ if (kalIsCardRemoved(prAdapter->prGlueInfo) == FALSE) { -+ /* <2> Acquire LP-OWN if necessary */ -+ if (*pfgHwAccess == FALSE) { -+ *pfgHwAccess = TRUE; -+ -+ wlanAcquirePowerControl(prAdapter); -+ } -+#if (MT6620_E1_ASIC_HIFSYS_WORKAROUND == 1) -+ if (prAdapter->fgIsClockGatingEnabled == TRUE) -+ nicDisableClockGating(prAdapter); -+#endif -+ /* <3> send packet"s" to HIF */ -+ nicTxMsduInfoList(prAdapter, prMsduInfo); -+ -+ /* <4> update TC by txAdjustTcQuotas() */ -+ nicTxAdjustTcq(prAdapter); -+ } else -+ wlanProcessQueuedMsduInfo(prAdapter, prMsduInfo); /* free the packet */ -+ } -+#if (MT6620_E1_ASIC_HIFSYS_WORKAROUND == 1) -+ if (prAdapter->fgIsClockGatingEnabled == FALSE) -+ nicEnableClockGating(prAdapter); -+#endif -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is called to acquire power control from firmware -+* -+* @param prAdapter Pointer of Adapter Data Structure -+* -+* @return WLAN_STATUS_SUCCESS -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS wlanAcquirePowerControl(IN P_ADAPTER_T prAdapter) -+{ -+ ASSERT(prAdapter); -+ -+ /* do driver own */ -+ ACQUIRE_POWER_CONTROL_FROM_PM(prAdapter); -+ -+ /* Reset sleepy state *//* no use */ -+ if (prAdapter->fgWiFiInSleepyState == TRUE) -+ prAdapter->fgWiFiInSleepyState = FALSE; -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is called to release power control to firmware -+* -+* @param prAdapter Pointer of Adapter Data Structure -+* -+* @return WLAN_STATUS_SUCCESS -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS wlanReleasePowerControl(IN P_ADAPTER_T prAdapter) -+{ -+ ASSERT(prAdapter); -+ -+ /* do FW own */ -+ RECLAIM_POWER_CONTROL_TO_PM(prAdapter, FALSE); -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is called to report currently pending TX frames count -+* (command packets are not included) -+* -+* @param prAdapter Pointer of Adapter Data Structure -+* -+* @return number of pending TX frames -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT_32 wlanGetTxPendingFrameCount(IN P_ADAPTER_T prAdapter) -+{ -+ P_TX_CTRL_T prTxCtrl; -+ UINT_32 u4Num; -+ -+ ASSERT(prAdapter); -+ prTxCtrl = &prAdapter->rTxCtrl; -+ -+ /* number in prTxQueue + number in RX forward */ -+ u4Num = kalGetTxPendingFrameCount(prAdapter->prGlueInfo) + (UINT_32) (prTxCtrl->i4PendingFwdFrameCount); -+ -+ return u4Num; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is to report current ACPI state -+* -+* @param prAdapter Pointer of Adapter Data Structure -+* -+* @return ACPI_STATE_D0 Normal Operation Mode -+* ACPI_STATE_D3 Suspend Mode -+*/ -+/*----------------------------------------------------------------------------*/ -+ENUM_ACPI_STATE_T wlanGetAcpiState(IN P_ADAPTER_T prAdapter) -+{ -+ ASSERT(prAdapter); -+ -+ return prAdapter->rAcpiState; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is to update current ACPI state only -+* -+* @param prAdapter Pointer of Adapter Data Structure -+* @param ePowerState ACPI_STATE_D0 Normal Operation Mode -+* ACPI_STATE_D3 Suspend Mode -+* -+* @return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID wlanSetAcpiState(IN P_ADAPTER_T prAdapter, IN ENUM_ACPI_STATE_T ePowerState) -+{ -+ ASSERT(prAdapter); -+ ASSERT(ePowerState <= ACPI_STATE_D3); -+ -+ prAdapter->rAcpiState = ePowerState; -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is to query ECO version from HIFSYS CR -+* -+* @param prAdapter Pointer of Adapter Data Structure -+* -+* @return zero Unable to retrieve ECO version information -+* non-zero ECO version (1-based) -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT_8 wlanGetEcoVersion(IN P_ADAPTER_T prAdapter) -+{ -+ ASSERT(prAdapter); -+ -+ if (nicVerifyChipID(prAdapter) == TRUE) -+ return prAdapter->ucRevID + 1; -+ else -+ return 0; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is to setting the default Tx Power configuration -+* -+* @param prAdapter Pointer of Adapter Data Structure -+* -+* @return zero Unable to retrieve ECO version information -+* non-zero ECO version (1-based) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID wlanDefTxPowerCfg(IN P_ADAPTER_T prAdapter) -+{ -+ UINT_8 i; -+ P_GLUE_INFO_T prGlueInfo = prAdapter->prGlueInfo; -+ P_SET_TXPWR_CTRL_T prTxpwr; -+ -+ ASSERT(prGlueInfo); -+ -+ prTxpwr = &prGlueInfo->rTxPwr; -+ -+ prTxpwr->c2GLegacyStaPwrOffset = 0; -+ prTxpwr->c2GHotspotPwrOffset = 0; -+ prTxpwr->c2GP2pPwrOffset = 0; -+ prTxpwr->c2GBowPwrOffset = 0; -+ prTxpwr->c5GLegacyStaPwrOffset = 0; -+ prTxpwr->c5GHotspotPwrOffset = 0; -+ prTxpwr->c5GP2pPwrOffset = 0; -+ prTxpwr->c5GBowPwrOffset = 0; -+ prTxpwr->ucConcurrencePolicy = 0; -+ for (i = 0; i < 3; i++) -+ prTxpwr->acReserved1[i] = 0; -+ -+ for (i = 0; i < 14; i++) -+ prTxpwr->acTxPwrLimit2G[i] = 63; -+ -+ for (i = 0; i < 4; i++) -+ prTxpwr->acTxPwrLimit5G[i] = 63; -+ -+ for (i = 0; i < 2; i++) -+ prTxpwr->acReserved2[i] = 0; -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is to -+* set preferred band configuration corresponding to network type -+* -+* @param prAdapter Pointer of Adapter Data Structure -+* @param eBand Given band -+* @param eNetTypeIndex Given Network Type -+* -+* @return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+wlanSetPreferBandByNetwork(IN P_ADAPTER_T prAdapter, IN ENUM_BAND_T eBand, IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex) -+{ -+ ASSERT(prAdapter); -+ ASSERT(eBand <= BAND_NUM); -+ ASSERT(eNetTypeIndex <= NETWORK_TYPE_INDEX_NUM); -+ -+ /* 1. set prefer band according to network type */ -+ prAdapter->aePreferBand[eNetTypeIndex] = eBand; -+ -+ /* 2. remove buffered BSS descriptors correspondingly */ -+ if (eBand == BAND_2G4) -+ scanRemoveBssDescByBandAndNetwork(prAdapter, BAND_5G, eNetTypeIndex); -+ else if (eBand == BAND_5G) -+ scanRemoveBssDescByBandAndNetwork(prAdapter, BAND_2G4, eNetTypeIndex); -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is to -+* get channel information corresponding to specified network type -+* -+* @param prAdapter Pointer of Adapter Data Structure -+* @param eNetTypeIndex Given Network Type -+* -+* @return channel number -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT_8 wlanGetChannelNumberByNetwork(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex) -+{ -+ P_BSS_INFO_T prBssInfo; -+ -+ ASSERT(prAdapter); -+ ASSERT(eNetTypeIndex <= NETWORK_TYPE_INDEX_NUM); -+ -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[eNetTypeIndex]); -+ -+ return prBssInfo->ucPrimaryChannel; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is to -+* get BSS descriptor information corresponding to specified network type -+* -+* @param prAdapter Pointer of Adapter Data Structure -+* @param eNetTypeIndex Given Network Type -+* -+* @return pointer to BSS_DESC_T -+*/ -+/*----------------------------------------------------------------------------*/ -+P_BSS_DESC_T wlanGetTargetBssDescByNetwork(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex) -+{ -+ ASSERT(prAdapter); -+ ASSERT(eNetTypeIndex <= NETWORK_TYPE_INDEX_NUM); -+ -+ switch (eNetTypeIndex) { -+ case NETWORK_TYPE_AIS_INDEX: -+ return prAdapter->rWifiVar.rAisFsmInfo.prTargetBssDesc; -+ -+ case NETWORK_TYPE_P2P_INDEX: -+ return NULL; -+ -+ case NETWORK_TYPE_BOW_INDEX: -+ return prAdapter->rWifiVar.rBowFsmInfo.prTargetBssDesc; -+ -+ default: -+ return NULL; -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is to -+* check unconfigured system properties and generate related message on -+* scan list to notify users -+* -+* @param prAdapter Pointer of Adapter Data Structure -+* -+* @return WLAN_STATUS_SUCCESS -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS wlanCheckSystemConfiguration(IN P_ADAPTER_T prAdapter) -+{ -+#if (CFG_NVRAM_EXISTENCE_CHECK == 1) || (CFG_SW_NVRAM_VERSION_CHECK == 1) -+ const UINT_8 aucZeroMacAddr[] = NULL_MAC_ADDR; -+ const UINT_8 aucBCAddr[] = BC_MAC_ADDR; -+ BOOLEAN fgIsConfExist = TRUE; -+ BOOLEAN fgGenErrMsg = FALSE; -+ P_REG_INFO_T prRegInfo = NULL; -+ P_WLAN_BEACON_FRAME_T prBeacon = NULL; -+ P_IE_SSID_T prSsid = NULL; -+ UINT_32 u4ErrCode = 0; -+ UINT_8 aucErrMsg[32]; -+ PARAM_SSID_T rSsid; -+ PARAM_802_11_CONFIG_T rConfiguration; -+ PARAM_RATES_EX rSupportedRates; -+#endif -+ -+ DEBUGFUNC("wlanCheckSystemConfiguration"); -+ -+ ASSERT(prAdapter); -+ -+#if (CFG_NVRAM_EXISTENCE_CHECK == 1) -+ if (kalIsConfigurationExist(prAdapter->prGlueInfo) == FALSE) { -+ fgIsConfExist = FALSE; -+ fgGenErrMsg = TRUE; -+ } -+#endif -+ -+#if (CFG_SW_NVRAM_VERSION_CHECK == 1) -+ prRegInfo = kalGetConfiguration(prAdapter->prGlueInfo); -+ -+ if (fgIsConfExist == TRUE && (CFG_DRV_OWN_VERSION < prAdapter->rVerInfo.u2Part1CfgPeerVersion -+ || CFG_DRV_OWN_VERSION < prAdapter->rVerInfo.u2Part2CfgPeerVersion -+ || prAdapter->rVerInfo.u2Part1CfgOwnVersion <= CFG_DRV_PEER_VERSION -+ || prAdapter->rVerInfo.u2Part2CfgOwnVersion <= CFG_DRV_PEER_VERSION /* NVRAM */ -+ || CFG_DRV_OWN_VERSION < prAdapter->rVerInfo.u2FwPeerVersion -+ || prAdapter->rVerInfo.u2FwOwnVersion <= CFG_DRV_PEER_VERSION -+#if CFG_SUPPORT_PWR_LIMIT_COUNTRY -+ || prAdapter->fgIsPowerLimitTableValid == FALSE -+#endif -+ || (prAdapter->fgIsEmbbededMacAddrValid == FALSE && -+ (IS_BMCAST_MAC_ADDR(prRegInfo->aucMacAddr) -+ || EQUAL_MAC_ADDR(aucZeroMacAddr, prRegInfo->aucMacAddr))) -+ || prRegInfo->ucTxPwrValid == 0)) -+ fgGenErrMsg = TRUE; -+#endif -+ -+ if (fgGenErrMsg == TRUE) { -+ prBeacon = cnmMemAlloc(prAdapter, RAM_TYPE_BUF, sizeof(WLAN_BEACON_FRAME_T) + sizeof(IE_SSID_T)); -+ if (!prBeacon) { -+ ASSERT(FALSE); -+ return WLAN_STATUS_FAILURE; -+ } -+ -+ /* initialization */ -+ kalMemZero(prBeacon, sizeof(WLAN_BEACON_FRAME_T) + sizeof(IE_SSID_T)); -+ -+ /* prBeacon initialization */ -+ prBeacon->u2FrameCtrl = MAC_FRAME_BEACON; -+ COPY_MAC_ADDR(prBeacon->aucDestAddr, aucBCAddr); -+ COPY_MAC_ADDR(prBeacon->aucSrcAddr, aucZeroMacAddr); -+ COPY_MAC_ADDR(prBeacon->aucBSSID, aucZeroMacAddr); -+ prBeacon->u2BeaconInterval = 100; -+ prBeacon->u2CapInfo = CAP_INFO_ESS; -+ -+ /* prSSID initialization */ -+ prSsid = (P_IE_SSID_T) (&prBeacon->aucInfoElem[0]); -+ prSsid->ucId = ELEM_ID_SSID; -+ -+ /* rConfiguration initialization */ -+ rConfiguration.u4Length = sizeof(PARAM_802_11_CONFIG_T); -+ rConfiguration.u4BeaconPeriod = 100; -+ rConfiguration.u4ATIMWindow = 1; -+ rConfiguration.u4DSConfig = 2412; -+ rConfiguration.rFHConfig.u4Length = sizeof(PARAM_802_11_CONFIG_FH_T); -+ -+ /* rSupportedRates initialization */ -+ kalMemZero(rSupportedRates, sizeof(PARAM_RATES_EX)); -+ } -+#if (CFG_NVRAM_EXISTENCE_CHECK == 1) -+#define NVRAM_ERR_MSG "NVRAM WARNING: Err = 0x01" -+ if ((kalIsConfigurationExist(prAdapter->prGlueInfo) == FALSE) && (prBeacon) && (prSsid)) { -+ COPY_SSID(prSsid->aucSSID, prSsid->ucLength, NVRAM_ERR_MSG, strlen(NVRAM_ERR_MSG)); -+ -+ kalIndicateBssInfo(prAdapter->prGlueInfo, -+ (PUINT_8) prBeacon, -+ OFFSET_OF(WLAN_BEACON_FRAME_T, aucInfoElem) + OFFSET_OF(IE_SSID_T, -+ aucSSID) + prSsid->ucLength, -+ 1, 0); -+ COPY_SSID(rSsid.aucSsid, rSsid.u4SsidLen, NVRAM_ERR_MSG, strlen(NVRAM_ERR_MSG)); -+ nicAddScanResult(prAdapter, -+ prBeacon->aucBSSID, -+ &rSsid, -+ 0, -+ 0, -+ PARAM_NETWORK_TYPE_FH, -+ &rConfiguration, -+ NET_TYPE_INFRA, -+ rSupportedRates, -+ OFFSET_OF(WLAN_BEACON_FRAME_T, aucInfoElem) + OFFSET_OF(IE_SSID_T, -+ aucSSID) + prSsid->ucLength - -+ WLAN_MAC_MGMT_HEADER_LEN, (PUINT_8) ((ULONG) (prBeacon) + WLAN_MAC_MGMT_HEADER_LEN)); -+ } -+#endif -+ -+#if (CFG_SW_NVRAM_VERSION_CHECK == 1) -+#define VER_ERR_MSG "NVRAM WARNING: Err = 0x%02X" -+ if ((fgIsConfExist == TRUE) && (prBeacon) && (prSsid)) { -+ if ((CFG_DRV_OWN_VERSION < prAdapter->rVerInfo.u2Part1CfgPeerVersion -+ || CFG_DRV_OWN_VERSION < prAdapter->rVerInfo.u2Part2CfgPeerVersion -+ || prAdapter->rVerInfo.u2Part1CfgOwnVersion <= CFG_DRV_PEER_VERSION -+ || prAdapter->rVerInfo.u2Part2CfgOwnVersion <= CFG_DRV_PEER_VERSION /* NVRAM */ -+ || CFG_DRV_OWN_VERSION < prAdapter->rVerInfo.u2FwPeerVersion -+ || prAdapter->rVerInfo.u2FwOwnVersion <= CFG_DRV_PEER_VERSION)) -+ u4ErrCode |= NVRAM_ERROR_VERSION_MISMATCH; -+ -+ if (prRegInfo->ucTxPwrValid == 0) -+ u4ErrCode |= NVRAM_ERROR_INVALID_TXPWR; -+ -+ if (prAdapter->fgIsEmbbededMacAddrValid == FALSE && (IS_BMCAST_MAC_ADDR(prRegInfo->aucMacAddr) -+ || EQUAL_MAC_ADDR(aucZeroMacAddr, -+ prRegInfo->aucMacAddr))) -+ u4ErrCode |= NVRAM_ERROR_INVALID_MAC_ADDR; -+ -+#if CFG_SUPPORT_PWR_LIMIT_COUNTRY -+ if (prAdapter->fgIsPowerLimitTableValid == FALSE) -+ u4ErrCode |= NVRAM_POWER_LIMIT_TABLE_INVALID; -+#endif -+ if (u4ErrCode != 0) { -+ sprintf(aucErrMsg, VER_ERR_MSG, (unsigned int)u4ErrCode); -+ COPY_SSID(prSsid->aucSSID, prSsid->ucLength, aucErrMsg, strlen(aucErrMsg)); -+ -+ kalIndicateBssInfo(prAdapter->prGlueInfo, -+ (PUINT_8) prBeacon, -+ OFFSET_OF(WLAN_BEACON_FRAME_T, aucInfoElem) + OFFSET_OF(IE_SSID_T, -+ aucSSID) + -+ prSsid->ucLength, 1, 0); -+ -+ COPY_SSID(rSsid.aucSsid, rSsid.u4SsidLen, NVRAM_ERR_MSG, strlen(NVRAM_ERR_MSG)); -+ nicAddScanResult(prAdapter, -+ prBeacon->aucBSSID, -+ &rSsid, -+ 0, -+ 0, -+ PARAM_NETWORK_TYPE_FH, -+ &rConfiguration, -+ NET_TYPE_INFRA, -+ rSupportedRates, -+ OFFSET_OF(WLAN_BEACON_FRAME_T, aucInfoElem) + OFFSET_OF(IE_SSID_T, -+ aucSSID) + -+ prSsid->ucLength - WLAN_MAC_MGMT_HEADER_LEN, -+ (PUINT_8) ((ULONG) (prBeacon) + WLAN_MAC_MGMT_HEADER_LEN)); -+ } -+ } -+#endif -+ -+ if (fgGenErrMsg == TRUE) -+ cnmMemFree(prAdapter, prBeacon); -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+WLAN_STATUS -+wlanoidQueryStaStatistics(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ WLAN_STATUS rResult = WLAN_STATUS_FAILURE; -+ P_STA_RECORD_T prStaRec, prTempStaRec; -+ P_PARAM_GET_STA_STATISTICS prQueryStaStatistics; -+ UINT_8 ucStaRecIdx; -+ P_QUE_MGT_T prQM = &prAdapter->rQM; -+ CMD_GET_STA_STATISTICS_T rQueryCmdStaStatistics; -+ UINT_8 ucIdx; -+ P_GLUE_INFO_T prGlueInfo = prAdapter->prGlueInfo; -+ -+ do { -+ ASSERT(pvQueryBuffer); -+ -+ /* 4 1. Sanity test */ -+ if ((prAdapter == NULL) || (pu4QueryInfoLen == NULL)) -+ break; -+ -+ if ((u4QueryBufferLen) && (pvQueryBuffer == NULL)) -+ break; -+ -+ if (u4QueryBufferLen < sizeof(PARAM_GET_STA_STA_STATISTICS)) { -+ *pu4QueryInfoLen = sizeof(PARAM_GET_STA_STA_STATISTICS); -+ rResult = WLAN_STATUS_BUFFER_TOO_SHORT; -+ break; -+ } -+ -+ prQueryStaStatistics = (P_PARAM_GET_STA_STATISTICS) pvQueryBuffer; -+ *pu4QueryInfoLen = sizeof(PARAM_GET_STA_STA_STATISTICS); -+ -+ /* 4 5. Get driver global QM counter */ -+ for (ucIdx = TC0_INDEX; ucIdx <= TC3_INDEX; ucIdx++) { -+ prQueryStaStatistics->au4TcAverageQueLen[ucIdx] = prQM->au4AverageQueLen[ucIdx]; -+ prQueryStaStatistics->au4TcCurrentQueLen[ucIdx] = prQM->au4CurrentTcResource[ucIdx]; -+ } -+ -+ /* 4 2. Get StaRec by MAC address */ -+ prStaRec = NULL; -+ -+ for (ucStaRecIdx = 0; ucStaRecIdx < CFG_NUM_OF_STA_RECORD; ucStaRecIdx++) { -+ prTempStaRec = &(prAdapter->arStaRec[ucStaRecIdx]); -+ if (prTempStaRec->fgIsValid && prTempStaRec->fgIsInUse) { -+ if (EQUAL_MAC_ADDR(prTempStaRec->aucMacAddr, prQueryStaStatistics->aucMacAddr)) { -+ prStaRec = prTempStaRec; -+ break; -+ } -+ } -+ } -+ -+ if (!prStaRec) { -+ rResult = WLAN_STATUS_INVALID_DATA; -+ break; -+ } -+ -+ prQueryStaStatistics->u4Flag |= BIT(0); -+ -+#if CFG_ENABLE_PER_STA_STATISTICS -+ /* 4 3. Get driver statistics */ -+ DBGLOG(TX, INFO, "skbToDriver %lld, skbFreed: %lld\n", -+ prAdapter->prGlueInfo->u8SkbToDriver, -+ prAdapter->prGlueInfo->u8SkbFreed); -+ prAdapter->prGlueInfo->u8SkbFreed = 0; -+ prAdapter->prGlueInfo->u8SkbToDriver = 0; -+ -+ prQueryStaStatistics->u4TxTotalCount = prStaRec->u4TotalTxPktsNumber; -+ prQueryStaStatistics->u4TxExceedThresholdCount = prStaRec->u4ThresholdCounter; -+ prQueryStaStatistics->u4TxMaxTime = prStaRec->u4MaxTxPktsTime; -+ prQueryStaStatistics->u4TxMaxHifTime = prStaRec->u4MaxTxPktsHifTime; -+ if (prStaRec->u4TotalTxPktsNumber) { -+ prQueryStaStatistics->u4TxAverageProcessTime = -+ (prStaRec->u4TotalTxPktsTime / prStaRec->u4TotalTxPktsNumber); -+ prQueryStaStatistics->u4TxAverageHifTime = -+ (prStaRec->u4TotalTxPktsHifTime / prStaRec->u4TotalTxPktsNumber); -+ } else -+ prQueryStaStatistics->u4TxAverageProcessTime = 0; -+ -+ for (ucIdx = TC0_INDEX; ucIdx <= TC3_INDEX; ucIdx++) { -+ prQueryStaStatistics->au4TcResourceEmptyCount[ucIdx] = -+ prQM->au4QmTcResourceEmptyCounter[prStaRec->ucNetTypeIndex][ucIdx]; -+ /* Reset */ -+ prQM->au4QmTcResourceEmptyCounter[prStaRec->ucNetTypeIndex][ucIdx] = 0; -+ prQueryStaStatistics->au4TcResourceBackCount[ucIdx] = -+ prQM->au4QmTcResourceBackCounter[ucIdx]; -+ prQM->au4QmTcResourceBackCounter[ucIdx] = 0; -+ -+ prQueryStaStatistics->au4DequeueNoTcResource[ucIdx] = -+ prQM->au4DequeueNoTcResourceCounter[ucIdx]; -+ prQM->au4DequeueNoTcResourceCounter[ucIdx] = 0; -+ prQueryStaStatistics->au4TcResourceUsedCount[ucIdx] = -+ prQM->au4ResourceUsedCounter[ucIdx]; -+ prQM->au4ResourceUsedCounter[ucIdx] = 0; -+ prQueryStaStatistics->au4TcResourceWantedCount[ucIdx] = -+ prQM->au4ResourceWantedCounter[ucIdx]; -+ prQM->au4ResourceWantedCounter[ucIdx] = 0; -+ } -+ -+ prQueryStaStatistics->u4EnqueueCounter = prQM->u4EnqeueuCounter; -+ prQueryStaStatistics->u4DequeueCounter = prQM->u4DequeueCounter; -+ prQueryStaStatistics->u4EnqueueStaCounter = prStaRec->u4EnqeueuCounter; -+ prQueryStaStatistics->u4DequeueStaCounter = prStaRec->u4DeqeueuCounter; -+ -+ prQueryStaStatistics->IsrCnt = prGlueInfo->IsrCnt - prGlueInfo->IsrPreCnt; -+ prQueryStaStatistics->IsrPassCnt = prGlueInfo->IsrPassCnt - prGlueInfo->IsrPrePassCnt; -+ prQueryStaStatistics->TaskIsrCnt = prGlueInfo->TaskIsrCnt - prGlueInfo->TaskPreIsrCnt; -+ -+ prQueryStaStatistics->IsrAbnormalCnt = prGlueInfo->IsrAbnormalCnt; -+ prQueryStaStatistics->IsrSoftWareCnt = prGlueInfo->IsrSoftWareCnt; -+ prQueryStaStatistics->IsrRxCnt = prGlueInfo->IsrRxCnt; -+ prQueryStaStatistics->IsrTxCnt = prGlueInfo->IsrTxCnt; -+ -+ /* 4 4.1 Reset statistics */ -+ prStaRec->u4ThresholdCounter = 0; -+ prStaRec->u4TotalTxPktsNumber = 0; -+ prStaRec->u4TotalTxPktsTime = 0; -+ prStaRec->u4MaxTxPktsTime = 0; -+ prStaRec->u4MaxTxPktsHifTime = 0; -+ -+ prStaRec->u4EnqeueuCounter = 0; -+ prStaRec->u4DeqeueuCounter = 0; -+ -+ prQM->u4EnqeueuCounter = 0; -+ prQM->u4DequeueCounter = 0; -+ -+ prGlueInfo->IsrPreCnt = prGlueInfo->IsrCnt; -+ prGlueInfo->IsrPrePassCnt = prGlueInfo->IsrPassCnt; -+ prGlueInfo->TaskPreIsrCnt = prGlueInfo->TaskIsrCnt; -+ prGlueInfo->IsrAbnormalCnt = 0; -+ prGlueInfo->IsrSoftWareCnt = 0; -+ prGlueInfo->IsrRxCnt = 0; -+ prGlueInfo->IsrTxCnt = 0; -+#endif -+ -+ for (ucIdx = TC0_INDEX; ucIdx <= TC3_INDEX; ucIdx++) -+ prQueryStaStatistics->au4TcQueLen[ucIdx] = prStaRec->arTxQueue[ucIdx].u4NumElem; -+ -+ rResult = WLAN_STATUS_SUCCESS; -+ -+ /* 4 6. Ensure FW supports get station link status */ -+ if (prAdapter->u4FwCompileFlag0 & COMPILE_FLAG0_GET_STA_LINK_STATUS) { -+ -+ rQueryCmdStaStatistics.ucIndex = prStaRec->ucIndex; -+ COPY_MAC_ADDR(rQueryCmdStaStatistics.aucMacAddr, prQueryStaStatistics->aucMacAddr); -+ rQueryCmdStaStatistics.ucReadClear = TRUE; -+ -+ rResult = wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_GET_STA_STATISTICS, -+ FALSE, -+ TRUE, -+ TRUE, -+ nicCmdEventQueryStaStatistics, -+ nicOidCmdTimeoutCommon, -+ sizeof(CMD_GET_STA_STATISTICS_T), -+ (PUINT_8)&rQueryCmdStaStatistics, -+ pvQueryBuffer, u4QueryBufferLen); -+ -+ prQueryStaStatistics->u4Flag |= BIT(1); -+ } else { -+ rResult = WLAN_STATUS_NOT_SUPPORTED; -+ } -+ -+ } while (FALSE); -+ -+ return rResult; -+} /* wlanoidQueryP2pVersion */ -+ -+#if CFG_AUTO_CHANNEL_SEL_SUPPORT -+ -+/* 4 Auto Channel Selection */ -+WLAN_STATUS -+wlanoidQueryACSChannelList(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ WLAN_STATUS rResult = WLAN_STATUS_FAILURE; -+ /* P_PARAM_GET_CHN_LOAD prQueryChnLoad; */ -+ P_PARAM_GET_LTE_MODE prLteMode; -+ CMD_GET_LTE_SAFE_CHN_T rQuery_LTE_SAFE_CHN; -+ -+ DBGLOG(P2P, INFO, "[Auto Channel]wlanoidQueryACSChannelList\n"); -+ do { -+ ASSERT(pvQueryBuffer); -+ -+ /* 4 1. Sanity test */ -+ if ((prAdapter == NULL) || (pu4QueryInfoLen == NULL)) -+ break; -+ -+ if ((u4QueryBufferLen) && (pvQueryBuffer == NULL)) -+ break; -+ -+ prLteMode = (P_PARAM_GET_LTE_MODE) pvQueryBuffer; -+ -+ /* 4 3. Ensure FW supports get station link status */ -+#if 0 -+ if (prAdapter->u4FwCompileFlag0 & COMPILE_FLAG0_GET_STA_LINK_STATUS) { -+ CMD_ACCESS_REG rCmdAccessReg; -+ -+ rCmdAccessReg.u4Address = 0xFFFFFFFF; -+ rCmdAccessReg.u4Data = ELEM_RM_TYPE_ACS_CHN; -+ -+ rResult = wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_ACCESS_REG, -+ TRUE, -+ TRUE, -+ TRUE, -+ /* The handler to receive firmware notification */ -+ nicCmdEventQueryChannelLoad, -+ nicOidCmdTimeoutCommon, -+ sizeof(CMD_ACCESS_REG), -+ (PUINT_8)&rCmdAccessReg, pvQueryBuffer, u4QueryBufferLen); -+ -+ prQueryChnLoad->u4Flag |= BIT(1); -+ } else { -+ rResult = WLAN_STATUS_NOT_SUPPORTED; -+ } -+#endif -+ /* 4 4.Avoid LTE Channels */ -+ prLteMode->u4Flags &= BIT(0); -+ /*if(prAdapter->u4FwCompileFlag0 & COMPILE_FLAG0_GET_STA_LINK_STATUS) */ { -+ -+ rResult = wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_GET_LTE_CHN, -+ FALSE, -+ TRUE, -+ /* Query ID */ -+ TRUE, -+ /* The handler to receive firmware notification */ -+ nicCmdEventQueryLTESafeChn, -+ nicOidCmdTimeoutCommon, -+ sizeof(CMD_GET_LTE_SAFE_CHN_T), -+ (PUINT_8)&rQuery_LTE_SAFE_CHN, -+ pvQueryBuffer, u4QueryBufferLen); -+ -+ DBGLOG(P2P, INFO, "[Auto Channel] Get LTE Channels\n"); -+ prLteMode->u4Flags |= BIT(1); -+ } -+ -+ /* 4 5. Calc the value */ -+ -+ DBGLOG(P2P, INFO, "[Auto Channel] Candidated Channels\n"); -+ } while (FALSE); -+ -+ return rResult; -+} /* wlanoidQueryP2pVersion */ -+#endif -+#if CFG_SUPPORT_CFG_FILE -+ -+P_WLAN_CFG_ENTRY_T wlanCfgGetEntry(IN P_ADAPTER_T prAdapter, const PCHAR pucKey) -+{ -+ -+ P_WLAN_CFG_ENTRY_T prWlanCfgEntry; -+ P_WLAN_CFG_T prWlanCfg; -+ UINT_32 i; -+ -+ prWlanCfg = prAdapter->prWlanCfg; -+ -+ ASSERT(prWlanCfg); -+ ASSERT(pucKey); -+ -+ prWlanCfgEntry = NULL; -+ -+ for (i = 0; i < WLAN_CFG_ENTRY_NUM_MAX; i++) { -+ prWlanCfgEntry = &prWlanCfg->arWlanCfgBuf[i]; -+ if (prWlanCfgEntry->aucKey[0] != '\0') { -+ DBGLOG(INIT, LOUD, "compare key %s saved key %s\n", pucKey, prWlanCfgEntry->aucKey); -+ if (kalStrniCmp(pucKey, prWlanCfgEntry->aucKey, WLAN_CFG_KEY_LEN_MAX - 1) == 0) -+ return prWlanCfgEntry; -+ } -+ } -+ -+ DBGLOG(INIT, LOUD, "wifi config there is no entry \'%s\'\n", pucKey); -+ return NULL; -+ -+} -+ -+WLAN_STATUS wlanCfgGet(IN P_ADAPTER_T prAdapter, const PCHAR pucKey, PCHAR pucValue, PCHAR pucValueDef, UINT_32 u4Flags) -+{ -+ -+ P_WLAN_CFG_ENTRY_T prWlanCfgEntry; -+ P_WLAN_CFG_T prWlanCfg; -+ -+ prWlanCfg = prAdapter->prWlanCfg; -+ -+ ASSERT(prWlanCfg); -+ ASSERT(pucValue); -+ -+ /* Find the exist */ -+ prWlanCfgEntry = wlanCfgGetEntry(prAdapter, pucKey); -+ -+ if (prWlanCfgEntry) { -+ kalStrnCpy(pucValue, prWlanCfgEntry->aucValue, WLAN_CFG_VALUE_LEN_MAX - 1); -+ return WLAN_STATUS_SUCCESS; -+ } -+ if (pucValueDef) -+ kalStrnCpy(pucValue, pucValueDef, WLAN_CFG_VALUE_LEN_MAX - 1); -+ return WLAN_STATUS_FAILURE; -+ -+} -+ -+UINT_32 wlanCfgGetUint32(IN P_ADAPTER_T prAdapter, const PCHAR pucKey, UINT_32 u4ValueDef) -+{ -+ P_WLAN_CFG_ENTRY_T prWlanCfgEntry; -+ P_WLAN_CFG_T prWlanCfg; -+ UINT_32 u4Value; -+ INT_32 u4Ret; -+ -+ prWlanCfg = prAdapter->prWlanCfg; -+ -+ ASSERT(prWlanCfg); -+ -+ u4Value = u4ValueDef; -+ /* Find the exist */ -+ prWlanCfgEntry = wlanCfgGetEntry(prAdapter, pucKey); -+ -+ if (prWlanCfgEntry) { -+ u4Ret = kalkStrtou32(prWlanCfgEntry->aucValue, 0, &u4Value); -+ if (u4Ret) -+ DBGLOG(INIT, ERROR, "parse prWlanCfgEntry->aucValue u4Ret=%u\n", u4Ret); -+ /* u4Value = kalStrtoul(prWlanCfgEntry->aucValue, NULL, 0); */ -+ } -+ -+ return u4Value; -+} -+ -+INT_32 wlanCfgGetInt32(IN P_ADAPTER_T prAdapter, const PCHAR pucKey, INT_32 i4ValueDef) -+{ -+ P_WLAN_CFG_ENTRY_T prWlanCfgEntry; -+ P_WLAN_CFG_T prWlanCfg; -+ INT_32 i4Value; -+ INT_32 i4Ret; -+ -+ prWlanCfg = prAdapter->prWlanCfg; -+ -+ ASSERT(prWlanCfg); -+ -+ i4Value = i4ValueDef; -+ /* Find the exist */ -+ prWlanCfgEntry = wlanCfgGetEntry(prAdapter, pucKey); -+ -+ if (prWlanCfgEntry) { -+ i4Ret = kalkStrtos32(prWlanCfgEntry->aucValue, 0, &i4Value); -+ /* i4Ret = kalStrtol(prWlanCfgEntry->aucValue, NULL, 0); */ -+ if (i4Ret) -+ DBGLOG(INIT, ERROR, "parse prWlanCfgEntry->aucValue i4Ret=%u\n\r", i4Ret); -+ } -+ -+ return i4Value; -+} -+ -+WLAN_STATUS wlanCfgSet(IN P_ADAPTER_T prAdapter, const PCHAR pucKey, PCHAR pucValue, UINT_32 u4Flags) -+{ -+ -+ P_WLAN_CFG_ENTRY_T prWlanCfgEntry; -+ P_WLAN_CFG_T prWlanCfg; -+ UINT_32 u4EntryIndex; -+ UINT_32 i; -+ UINT_8 ucExist; -+ -+ prWlanCfg = prAdapter->prWlanCfg; -+ ASSERT(prWlanCfg); -+ ASSERT(pucKey); -+ -+ /* Find the exist */ -+ ucExist = 0; -+ prWlanCfgEntry = wlanCfgGetEntry(prAdapter, pucKey); -+ -+ if (!prWlanCfgEntry) { -+ /* Find the empty */ -+ for (i = 0; i < WLAN_CFG_ENTRY_NUM_MAX; i++) { -+ prWlanCfgEntry = &prWlanCfg->arWlanCfgBuf[i]; -+ if (prWlanCfgEntry->aucKey[0] == '\0') -+ break; -+ } -+ -+ u4EntryIndex = i; -+ if (u4EntryIndex < WLAN_CFG_ENTRY_NUM_MAX) { -+ prWlanCfgEntry = &prWlanCfg->arWlanCfgBuf[u4EntryIndex]; -+ kalMemZero(prWlanCfgEntry, sizeof(WLAN_CFG_ENTRY_T)); -+ } else { -+ prWlanCfgEntry = NULL; -+ DBGLOG(INIT, ERROR, "wifi config there is no empty entry\n"); -+ } -+ } /* !prWlanCfgEntry */ -+ else -+ ucExist = 1; -+ -+ if (prWlanCfgEntry) { -+ if (ucExist == 0) { -+ kalStrnCpy(prWlanCfgEntry->aucKey, pucKey, WLAN_CFG_KEY_LEN_MAX - 1); -+ prWlanCfgEntry->aucKey[WLAN_CFG_KEY_LEN_MAX - 1] = '\0'; -+ } -+ -+ if (pucValue && pucValue[0] != '\0') { -+ kalStrnCpy(prWlanCfgEntry->aucValue, pucValue, WLAN_CFG_VALUE_LEN_MAX - 1); -+ prWlanCfgEntry->aucValue[WLAN_CFG_VALUE_LEN_MAX - 1] = '\0'; -+ -+ if (ucExist) { -+ if (prWlanCfgEntry->pfSetCb) -+ prWlanCfgEntry->pfSetCb(prAdapter, -+ prWlanCfgEntry->aucKey, -+ prWlanCfgEntry->aucValue, prWlanCfgEntry->pPrivate, 0); -+ } -+ } else { -+ /* Call the pfSetCb if value is empty ? */ -+ /* remove the entry if value is empty */ -+ kalMemZero(prWlanCfgEntry, sizeof(WLAN_CFG_ENTRY_T)); -+ } -+ -+ } -+ /* prWlanCfgEntry */ -+ if (prWlanCfgEntry) { -+ DBGLOG(INIT, LOUD, "Set wifi config exist %u \'%s\' \'%s\'\n", -+ ucExist, prWlanCfgEntry->aucKey, prWlanCfgEntry->aucValue); -+ return WLAN_STATUS_SUCCESS; -+ } -+ if (pucKey) -+ DBGLOG(INIT, ERROR, "Set wifi config error key \'%s\'\n", pucKey); -+ if (pucValue) -+ DBGLOG(INIT, ERROR, "Set wifi config error value \'%s\'\n", pucValue); -+ return WLAN_STATUS_FAILURE; -+ -+} -+ -+WLAN_STATUS -+wlanCfgSetCb(IN P_ADAPTER_T prAdapter, const PCHAR pucKey, WLAN_CFG_SET_CB pfSetCb, void *pPrivate, UINT_32 u4Flags) -+{ -+ -+ P_WLAN_CFG_ENTRY_T prWlanCfgEntry; -+ P_WLAN_CFG_T prWlanCfg; -+ -+ prWlanCfg = prAdapter->prWlanCfg; -+ ASSERT(prWlanCfg); -+ -+ /* Find the exist */ -+ prWlanCfgEntry = wlanCfgGetEntry(prAdapter, pucKey); -+ -+ if (prWlanCfgEntry) { -+ prWlanCfgEntry->pfSetCb = pfSetCb; -+ prWlanCfgEntry->pPrivate = pPrivate; -+ } -+ -+ if (prWlanCfgEntry) -+ return WLAN_STATUS_SUCCESS; -+ else -+ return WLAN_STATUS_FAILURE; -+ -+} -+ -+WLAN_STATUS wlanCfgSetUint32(IN P_ADAPTER_T prAdapter, const PCHAR pucKey, UINT_32 u4Value) -+{ -+ -+ P_WLAN_CFG_T prWlanCfg; -+ UINT_8 aucBuf[WLAN_CFG_VALUE_LEN_MAX]; -+ -+ prWlanCfg = prAdapter->prWlanCfg; -+ -+ ASSERT(prWlanCfg); -+ -+ kalMemZero(aucBuf, sizeof(aucBuf)); -+ -+ kalSnprintf(aucBuf, WLAN_CFG_VALUE_LEN_MAX, "0x%x", (unsigned int)u4Value); -+ -+ return wlanCfgSet(prAdapter, pucKey, aucBuf, 0); -+} -+ -+enum { -+ STATE_EOF = 0, -+ STATE_TEXT = 1, -+ STATE_NEWLINE = 2 -+}; -+ -+struct WLAN_CFG_PARSE_STATE_S { -+ CHAR *ptr; -+ CHAR *text; -+ INT_32 nexttoken; -+ UINT_32 maxSize; -+}; -+ -+INT_32 wlanCfgFindNextToken(struct WLAN_CFG_PARSE_STATE_S *state) -+{ -+ CHAR *x = state->ptr; -+ CHAR *s; -+ -+ if (state->nexttoken) { -+ INT_32 t = state->nexttoken; -+ -+ state->nexttoken = 0; -+ return t; -+ } -+ -+ for (;;) { -+ switch (*x) { -+ case 0: -+ state->ptr = x; -+ return STATE_EOF; -+ case '\n': -+ x++; -+ state->ptr = x; -+ return STATE_NEWLINE; -+ case ' ': -+ case '\t': -+ case '\r': -+ x++; -+ continue; -+ case '#': -+ while (*x && (*x != '\n')) -+ x++; -+ if (*x == '\n') { -+ state->ptr = x + 1; -+ return STATE_NEWLINE; -+ } -+ state->ptr = x; -+ return STATE_EOF; -+ default: -+ goto text; -+ } -+ } -+ -+textdone: -+ state->ptr = x; -+ *s = 0; -+ return STATE_TEXT; -+text: -+ state->text = s = x; -+textresume: -+ for (;;) { -+ switch (*x) { -+ case 0: -+ goto textdone; -+ case ' ': -+ case '\t': -+ case '\r': -+ x++; -+ goto textdone; -+ case '\n': -+ state->nexttoken = STATE_NEWLINE; -+ x++; -+ goto textdone; -+ case '"': -+ x++; -+ for (;;) { -+ switch (*x) { -+ case 0: -+ /* unterminated quoted thing */ -+ state->ptr = x; -+ return STATE_EOF; -+ case '"': -+ x++; -+ goto textresume; -+ default: -+ *s++ = *x++; -+ } -+ } -+ break; -+ case '\\': -+ x++; -+ switch (*x) { -+ case 0: -+ goto textdone; -+ case 'n': -+ *s++ = '\n'; -+ break; -+ case 'r': -+ *s++ = '\r'; -+ break; -+ case 't': -+ *s++ = '\t'; -+ break; -+ case '\\': -+ *s++ = '\\'; -+ break; -+ case '\r': -+ /* \ -> line continuation */ -+ if (x[1] != '\n') { -+ x++; -+ continue; -+ } -+ case '\n': -+ /* \ -> line continuation */ -+ x++; -+ /* eat any extra whitespace */ -+ while ((*x == ' ') || (*x == '\t')) -+ x++; -+ continue; -+ default: -+ /* unknown escape -- just copy */ -+ *s++ = *x++; -+ } -+ continue; -+ default: -+ *s++ = *x++; -+ } -+ } -+ return STATE_EOF; -+} -+ -+WLAN_STATUS wlanCfgParseArgument(CHAR *cmdLine, INT_32 *argc, CHAR *argv[]) -+{ -+ struct WLAN_CFG_PARSE_STATE_S state; -+ CHAR **args; -+ INT_32 nargs; -+ -+ if (cmdLine == NULL || argc == NULL || argv == NULL) { -+ ASSERT(0); -+ return WLAN_STATUS_FAILURE; -+ } -+ args = argv; -+ nargs = 0; -+ state.ptr = cmdLine; -+ state.nexttoken = 0; -+ state.maxSize = 0; -+ -+ if (kalStrnLen(cmdLine, 512) >= 512) { -+ ASSERT(0); -+ return WLAN_STATUS_FAILURE; -+ } -+ -+ for (;;) { -+ switch (wlanCfgFindNextToken(&state)) { -+ case STATE_EOF: -+ goto exit; -+ case STATE_NEWLINE: -+ goto exit; -+ case STATE_TEXT: -+ if (nargs < WLAN_CFG_ARGV_MAX) -+ args[nargs++] = state.text; -+ break; -+ } -+ } -+ -+exit: -+ *argc = nargs; -+ return WLAN_STATUS_SUCCESS; -+} -+ -+WLAN_STATUS -+wlanCfgParseAddEntry(IN P_ADAPTER_T prAdapter, -+ PUINT_8 pucKeyHead, PUINT_8 pucKeyTail, PUINT_8 pucValueHead, PUINT_8 pucValueTail) -+{ -+ -+ UINT_8 aucKey[WLAN_CFG_KEY_LEN_MAX]; -+ UINT_8 aucValue[WLAN_CFG_VALUE_LEN_MAX]; -+ UINT_32 u4Len; -+ -+ kalMemZero(aucKey, sizeof(aucKey)); -+ kalMemZero(aucValue, sizeof(aucValue)); -+ -+ if ((pucKeyHead == NULL) -+ || (pucValueHead == NULL) -+ ) -+ return WLAN_STATUS_FAILURE; -+ -+ if (pucKeyTail) { -+ if (pucKeyHead > pucKeyTail) -+ return WLAN_STATUS_FAILURE; -+ u4Len = pucKeyTail - pucKeyHead + 1; -+ } else -+ u4Len = kalStrnLen(pucKeyHead, WLAN_CFG_KEY_LEN_MAX - 1); -+ -+ if (u4Len >= WLAN_CFG_KEY_LEN_MAX) -+ u4Len = WLAN_CFG_KEY_LEN_MAX - 1; -+ -+ if (u4Len < WLAN_CFG_VALUE_LEN_MAX) -+ kalStrnCpy(aucKey, pucKeyHead, u4Len); -+ else -+ DBGLOG(INIT, ERROR, "wifi entry parse error: Data len > %d\n", u4Len); -+ -+ if (pucValueTail) { -+ if (pucValueHead > pucValueTail) -+ return WLAN_STATUS_FAILURE; -+ u4Len = pucValueTail - pucValueHead + 1; -+ } else -+ u4Len = kalStrnLen(pucValueHead, WLAN_CFG_VALUE_LEN_MAX - 1); -+ -+ if (u4Len >= WLAN_CFG_VALUE_LEN_MAX) -+ u4Len = WLAN_CFG_VALUE_LEN_MAX - 1; -+ -+ if (u4Len < WLAN_CFG_VALUE_LEN_MAX) -+ kalStrnCpy(aucValue, pucValueHead, u4Len); -+ else -+ DBGLOG(INIT, ERROR, "wifi entry parse error: Data len > %d\n", u4Len); -+ -+ return wlanCfgSet(prAdapter, aucKey, aucValue, 0); -+} -+ -+enum { -+ WAIT_KEY_HEAD = 0, -+ WAIT_KEY_TAIL, -+ WAIT_VALUE_HEAD, -+ WAIT_VALUE_TAIL, -+ WAIT_COMMENT_TAIL -+}; -+ -+WLAN_STATUS wlanCfgParse(IN P_ADAPTER_T prAdapter, PUINT_8 pucConfigBuf, UINT_32 u4ConfigBufLen) -+{ -+ -+ struct WLAN_CFG_PARSE_STATE_S state; -+ PCHAR apcArgv[WLAN_CFG_ARGV_MAX]; -+ CHAR **args; -+ INT_32 nargs; -+ -+ if (pucConfigBuf == NULL) { -+ ASSERT(0); -+ return WLAN_STATUS_FAILURE; -+ } -+ if (kalStrnLen(pucConfigBuf, 4000) >= 4000) { -+ ASSERT(0); -+ return WLAN_STATUS_FAILURE; -+ } -+ if (u4ConfigBufLen == 0) -+ return WLAN_STATUS_FAILURE; -+ args = apcArgv; -+ nargs = 0; -+ state.ptr = pucConfigBuf; -+ state.nexttoken = 0; -+ state.maxSize = u4ConfigBufLen; -+ -+ for (;;) { -+ switch (wlanCfgFindNextToken(&state)) { -+ case STATE_EOF: -+ if (nargs > 1) -+ wlanCfgParseAddEntry(prAdapter, args[0], NULL, args[1], NULL); -+ goto exit; -+ case STATE_NEWLINE: -+ if (nargs > 1) -+ wlanCfgParseAddEntry(prAdapter, args[0], NULL, args[1], NULL); -+ nargs = 0; -+ break; -+ case STATE_TEXT: -+ if (nargs < WLAN_CFG_ARGV_MAX) -+ args[nargs++] = state.text; -+ break; -+ } -+ } -+ -+exit: -+ return WLAN_STATUS_SUCCESS; -+ -+#if 0 -+ /* Old version */ -+ UINT_32 i; -+ UINT_8 c; -+ PUINT_8 pbuf; -+ UINT_8 ucState; -+ PUINT_8 pucKeyTail = NULL; -+ PUINT_8 pucKeyHead = NULL; -+ PUINT_8 pucValueHead = NULL; -+ PUINT_8 pucValueTail = NULL; -+ -+ ucState = WAIT_KEY_HEAD; -+ pbuf = pucConfigBuf; -+ -+ for (i = 0; i < u4ConfigBufLen; i++) { -+ c = pbuf[i]; -+ if (c == '\r' || c == '\n') { -+ -+ if (ucState == WAIT_VALUE_TAIL) { -+ /* Entry found */ -+ if (pucValueHead) -+ wlanCfgParseAddEntry(prAdapter, pucKeyHead, pucKeyTail, -+ pucValueHead, pucValueTail); -+ } -+ ucState = WAIT_KEY_HEAD; -+ pucKeyTail = NULL; -+ pucKeyHead = NULL; -+ pucValueHead = NULL; -+ pucValueTail = NULL; -+ -+ } else if (c == '=') { -+ if (ucState == WAIT_KEY_TAIL) { -+ pucKeyTail = &pbuf[i - 1]; -+ ucState = WAIT_VALUE_HEAD; -+ } -+ } else if (c == ' ' || c == '\t') { -+ if (ucState == WAIT_KEY_HEAD) -+ ; -+ else if (ucState == WAIT_KEY_TAIL) { -+ pucKeyTail = &pbuf[i - 1]; -+ ucState = WAIT_VALUE_HEAD; -+ } -+ } else { -+ -+ if (c == '#') { -+ /* comments */ -+ if (ucState == WAIT_KEY_HEAD) -+ ucState = WAIT_COMMENT_TAIL; -+ else if (ucState == WAIT_VALUE_TAIL) -+ pucValueTail = &pbuf[i]; -+ -+ } else { -+ if (ucState == WAIT_KEY_HEAD) { -+ pucKeyHead = &pbuf[i]; -+ pucKeyTail = &pbuf[i]; -+ ucState = WAIT_KEY_TAIL; -+ } else if (ucState == WAIT_VALUE_HEAD) { -+ pucValueHead = &pbuf[i]; -+ pucValueTail = &pbuf[i]; -+ ucState = WAIT_VALUE_TAIL; -+ } else if (ucState == WAIT_VALUE_TAIL) -+ pucValueTail = &pbuf[i]; -+ } -+ } -+ -+ } /* for */ -+ -+ if (ucState == WAIT_VALUE_TAIL) { -+ /* Entry found */ -+ if (pucValueTail) -+ wlanCfgParseAddEntry(prAdapter, pucKeyHead, pucKeyTail, pucValueHead, pucValueTail); -+ } -+#endif -+ -+ return WLAN_STATUS_SUCCESS; -+} -+#endif -+ -+#if CFG_SUPPORT_CFG_FILE -+WLAN_STATUS wlanCfgInit(IN P_ADAPTER_T prAdapter, PUINT_8 pucConfigBuf, UINT_32 u4ConfigBufLen, UINT_32 u4Flags) -+{ -+ P_WLAN_CFG_T prWlanCfg; -+ /* P_WLAN_CFG_ENTRY_T prWlanCfgEntry; */ -+ prAdapter->prWlanCfg = &prAdapter->rWlanCfg; -+ prWlanCfg = prAdapter->prWlanCfg; -+ -+ kalMemZero(prWlanCfg, sizeof(WLAN_CFG_T)); -+ ASSERT(prWlanCfg); -+ prWlanCfg->u4WlanCfgEntryNumMax = WLAN_CFG_ENTRY_NUM_MAX; -+ prWlanCfg->u4WlanCfgKeyLenMax = WLAN_CFG_KEY_LEN_MAX; -+ prWlanCfg->u4WlanCfgValueLenMax = WLAN_CFG_VALUE_LEN_MAX; -+#if 0 -+ DBGLOG(INIT, INFO, "Init wifi config len %u max entry %u\n", u4ConfigBufLen, prWlanCfg->u4WlanCfgEntryNumMax); -+#endif -+ /* self test */ -+ wlanCfgSet(prAdapter, "ConfigValid", "0x123", 0); -+ if (wlanCfgGetUint32(prAdapter, "ConfigValid", 0) != 0x123) -+ DBGLOG(INIT, ERROR, "wifi config error %u\n", __LINE__); -+ wlanCfgSet(prAdapter, "ConfigValid", "1", 0); -+ if (wlanCfgGetUint32(prAdapter, "ConfigValid", 0) != 1) -+ DBGLOG(INIT, ERROR, "wifi config error %u\n", __LINE__); -+#if 0 /* soc chip didn't support these parameters now */ -+ /* Add initil config */ -+ /* use g,wlan,p2p,ap as prefix */ -+ /* Don't set cb here , overwrite by another api */ -+ wlanCfgSet(prAdapter, "TxLdpc", "1", 0); -+ wlanCfgSet(prAdapter, "RxLdpc", "1", 0); -+ wlanCfgSet(prAdapter, "RxBeamformee", "1", 0); -+ wlanCfgSet(prAdapter, "RoamTh1", "100", 0); -+ wlanCfgSet(prAdapter, "RoamTh2", "150", 0); -+ wlanCfgSet(prAdapter, "wlanRxLdpc", "1", 0); -+ wlanCfgSet(prAdapter, "apRxLdpc", "1", 0); -+ wlanCfgSet(prAdapter, "p2pRxLdpc", "1", 0); -+#endif -+ /* Parse the pucConfigBuff */ -+ -+ if (pucConfigBuf && (u4ConfigBufLen > 0)) -+ wlanCfgParse(prAdapter, pucConfigBuf, u4ConfigBufLen); -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is to initialize WLAN feature options -+* -+* @param prAdapter Pointer of ADAPTER_T -+* -+* @return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID wlanCfgApply(IN P_ADAPTER_T prAdapter) -+{ -+#define STR2BYTE(s) (((((PUINT_8)s)[0]-'0')*10)+(((PUINT_8)s)[1]-'0')) -+ CHAR aucValue[WLAN_CFG_VALUE_LEN_MAX]; -+ P_WIFI_VAR_T prWifiVar = &prAdapter->rWifiVar; -+ P_REG_INFO_T prRegInfo = &prAdapter->prGlueInfo->rRegInfo; -+ P_TX_PWR_PARAM_T prTxPwr = &prRegInfo->rTxPwr; -+ -+ kalMemZero(aucValue, sizeof(aucValue)); -+ DBGLOG(INIT, LOUD, "CFG_FILE: Apply Config File\n"); -+ /* Apply COUNTRY Config */ -+ if (wlanCfgGet(prAdapter, "country", aucValue, "", 0) == WLAN_STATUS_SUCCESS) { -+ DBGLOG(INIT, LOUD, "CFG_FILE: Found Country Key, Value=%s\n", aucValue); -+ prAdapter->rWifiVar.rConnSettings.u2CountryCode = -+ (((UINT_16) aucValue[0]) << 8) | ((UINT_16) aucValue[1]); -+ prRegInfo->au2CountryCode[0] = aucValue[0]; -+ prRegInfo->au2CountryCode[1] = aucValue[1]; -+ } -+ prWifiVar->ucApWpsMode = (UINT_8) wlanCfgGetUint32(prAdapter, "ApWpsMode", 0); -+ prWifiVar->ucCert11nMode = (UINT_8)wlanCfgGetUint32(prAdapter, "Cert11nMode", 0); -+ DBGLOG(INIT, LOUD, "CFG_FILE: ucApWpsMode = %u, ucCert11nMode = %u\n", -+ prWifiVar->ucApWpsMode, prWifiVar->ucCert11nMode); -+ if (prWifiVar->ucCert11nMode == 1) -+ nicWriteMcr(prAdapter, 0x11111115 , 1); -+ -+ if (wlanCfgGet(prAdapter, "5G_support", aucValue, "", 0) == WLAN_STATUS_SUCCESS) -+ prRegInfo->ucSupport5GBand = (*aucValue == 'y') ? 1 : 0; -+ if (wlanCfgGet(prAdapter, "TxPower2G4CCK", aucValue, "", 0) == WLAN_STATUS_SUCCESS -+ && kalStrLen(aucValue) == 2) { -+ prTxPwr->cTxPwr2G4Cck = STR2BYTE(aucValue); -+ DBGLOG(INIT, LOUD, "2.4G cck=%d\n", prTxPwr->cTxPwr2G4Cck); -+ } -+ if (wlanCfgGet(prAdapter, "TxPower2G4OFDM", aucValue, "", 0) == WLAN_STATUS_SUCCESS && -+ kalStrLen(aucValue) == 10) { -+ prTxPwr->cTxPwr2G4OFDM_BPSK = STR2BYTE(aucValue); -+ prTxPwr->cTxPwr2G4OFDM_QPSK = STR2BYTE(aucValue + 2); -+ prTxPwr->cTxPwr2G4OFDM_16QAM = STR2BYTE(aucValue + 4); -+ prTxPwr->cTxPwr2G4OFDM_48Mbps = STR2BYTE(aucValue + 6); -+ prTxPwr->cTxPwr2G4OFDM_54Mbps = STR2BYTE(aucValue + 8); -+ DBGLOG(INIT, LOUD, "2.4G OFDM=%d,%d,%d,%d,%d\n", -+ prTxPwr->cTxPwr2G4OFDM_BPSK, prTxPwr->cTxPwr2G4OFDM_QPSK, -+ prTxPwr->cTxPwr2G4OFDM_16QAM, prTxPwr->cTxPwr2G4OFDM_48Mbps, -+ prTxPwr->cTxPwr2G4OFDM_54Mbps); -+ } -+ if (wlanCfgGet(prAdapter, "TxPower2G4HT20", aucValue, "", 0) == WLAN_STATUS_SUCCESS && -+ kalStrLen(aucValue) == 12) { -+ prTxPwr->cTxPwr2G4HT20_BPSK = STR2BYTE(aucValue); -+ prTxPwr->cTxPwr2G4HT20_QPSK = STR2BYTE(aucValue + 2); -+ prTxPwr->cTxPwr2G4HT20_16QAM = STR2BYTE(aucValue + 4); -+ prTxPwr->cTxPwr2G4HT20_MCS5 = STR2BYTE(aucValue + 6); -+ prTxPwr->cTxPwr2G4HT20_MCS6 = STR2BYTE(aucValue + 8); -+ prTxPwr->cTxPwr2G4HT20_MCS7 = STR2BYTE(aucValue + 10); -+ DBGLOG(INIT, LOUD, "2.4G HT20=%d,%d,%d,%d,%d,%d\n", -+ prTxPwr->cTxPwr2G4HT20_BPSK, prTxPwr->cTxPwr2G4HT20_QPSK, -+ prTxPwr->cTxPwr2G4HT20_16QAM, prTxPwr->cTxPwr2G4HT20_MCS5, -+ prTxPwr->cTxPwr2G4HT20_MCS6, prTxPwr->cTxPwr2G4HT20_MCS7); -+ } -+ if (wlanCfgGet(prAdapter, "TxPower2G4HT40", aucValue, "", 0) == WLAN_STATUS_SUCCESS && -+ kalStrLen(aucValue) == 12) { -+ prTxPwr->cTxPwr2G4HT40_BPSK = STR2BYTE(aucValue); -+ prTxPwr->cTxPwr2G4HT40_QPSK = STR2BYTE(aucValue + 2); -+ prTxPwr->cTxPwr2G4HT40_16QAM = STR2BYTE(aucValue + 4); -+ prTxPwr->cTxPwr2G4HT40_MCS5 = STR2BYTE(aucValue + 6); -+ prTxPwr->cTxPwr2G4HT40_MCS6 = STR2BYTE(aucValue + 8); -+ prTxPwr->cTxPwr2G4HT40_MCS7 = STR2BYTE(aucValue + 10); -+ DBGLOG(INIT, LOUD, "2.4G HT40=%d,%d,%d,%d,%d,%d\n", -+ prTxPwr->cTxPwr2G4HT40_BPSK, prTxPwr->cTxPwr2G4HT40_QPSK, -+ prTxPwr->cTxPwr2G4HT40_16QAM, prTxPwr->cTxPwr2G4HT40_MCS5, -+ prTxPwr->cTxPwr2G4HT40_MCS6, prTxPwr->cTxPwr2G4HT40_MCS7); -+ } -+ if (wlanCfgGet(prAdapter, "TxPower5GOFDM", aucValue, "", 0) == WLAN_STATUS_SUCCESS -+ && kalStrLen(aucValue) == 10) { -+ prTxPwr->cTxPwr5GOFDM_BPSK = STR2BYTE(aucValue); -+ prTxPwr->cTxPwr5GOFDM_QPSK = STR2BYTE(aucValue + 2); -+ prTxPwr->cTxPwr5GOFDM_16QAM = STR2BYTE(aucValue + 4); -+ prTxPwr->cTxPwr5GOFDM_48Mbps = STR2BYTE(aucValue + 6); -+ prTxPwr->cTxPwr5GOFDM_54Mbps = STR2BYTE(aucValue + 8); -+ DBGLOG(INIT, LOUD, "5G OFDM=%d,%d,%d,%d,%d\n", -+ prTxPwr->cTxPwr5GOFDM_BPSK, prTxPwr->cTxPwr5GOFDM_QPSK, -+ prTxPwr->cTxPwr5GOFDM_16QAM, prTxPwr->cTxPwr5GOFDM_48Mbps, -+ prTxPwr->cTxPwr5GOFDM_54Mbps); -+ } -+ if (wlanCfgGet(prAdapter, "TxPower5GHT20", aucValue, "", 0) == WLAN_STATUS_SUCCESS -+ && kalStrLen(aucValue) == 12) { -+ prTxPwr->cTxPwr5GHT20_BPSK = STR2BYTE(aucValue); -+ prTxPwr->cTxPwr5GHT20_QPSK = STR2BYTE(aucValue + 2); -+ prTxPwr->cTxPwr5GHT20_16QAM = STR2BYTE(aucValue + 4); -+ prTxPwr->cTxPwr5GHT20_MCS5 = STR2BYTE(aucValue + 6); -+ prTxPwr->cTxPwr5GHT20_MCS6 = STR2BYTE(aucValue + 8); -+ prTxPwr->cTxPwr5GHT20_MCS7 = STR2BYTE(aucValue + 10); -+ DBGLOG(INIT, LOUD, "5G HT20=%d,%d,%d,%d,%d,%d\n", -+ prTxPwr->cTxPwr5GHT20_BPSK, prTxPwr->cTxPwr5GHT20_QPSK, -+ prTxPwr->cTxPwr5GHT20_16QAM, prTxPwr->cTxPwr5GHT20_MCS5, prTxPwr->cTxPwr5GHT20_MCS6, -+ prTxPwr->cTxPwr5GHT20_MCS7); -+ } -+ if (wlanCfgGet(prAdapter, "TxPower5GHT40", aucValue, "", 0) == WLAN_STATUS_SUCCESS -+ && kalStrLen(aucValue) == 12) { -+ prTxPwr->cTxPwr5GHT40_BPSK = STR2BYTE(aucValue); -+ prTxPwr->cTxPwr5GHT40_QPSK = STR2BYTE(aucValue + 2); -+ prTxPwr->cTxPwr5GHT40_16QAM = STR2BYTE(aucValue + 4); -+ prTxPwr->cTxPwr5GHT40_MCS5 = STR2BYTE(aucValue + 6); -+ prTxPwr->cTxPwr5GHT40_MCS6 = STR2BYTE(aucValue + 8); -+ prTxPwr->cTxPwr5GHT40_MCS7 = STR2BYTE(aucValue + 10); -+ DBGLOG(INIT, LOUD, "5G HT40=%d,%d,%d,%d,%d,%d\n", -+ prTxPwr->cTxPwr5GHT40_BPSK, prTxPwr->cTxPwr5GHT40_QPSK, -+ prTxPwr->cTxPwr5GHT40_16QAM, prTxPwr->cTxPwr5GHT40_MCS5, prTxPwr->cTxPwr5GHT40_MCS6, -+ prTxPwr->cTxPwr5GHT40_MCS7); -+ } -+ /* TODO: Apply other Config */ -+} -+#endif /* CFG_SUPPORT_CFG_FILE */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/common/wlan_oid.c b/drivers/misc/mediatek/connectivity/wlan/gen2/common/wlan_oid.c -new file mode 100644 -index 000000000000..993ff061ed20 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/common/wlan_oid.c -@@ -0,0 +1,11050 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/common/wlan_oid.c#5 -+*/ -+ -+/*! \file wlanoid.c -+ \brief This file contains the WLAN OID processing routines of Windows driver for -+ MediaTek Inc. 802.11 Wireless LAN Adapters. -+*/ -+ -+/* -+** Log: wlan_oid.c -+** -+** 09 05 2013 cp.wu -+** isolate logic regarding roaming & reassociation -+** -+** 09 03 2013 cp.wu -+** add path for reassociation -+** -+** 09 02 2013 cp.wu -+** add path to handle reassociation request -+** -+** 07 19 2012 yuche.tsai -+** NULL -+** Code update for JB. -+ * -+ * 07 17 2012 yuche.tsai -+ * NULL -+ * Let netdev bring up. -+ * -+ * 07 17 2012 yuche.tsai -+ * NULL -+ * Compile no error before trial run. -+ * -+ * 03 02 2012 terry.wu -+ * NULL -+ * Sync CFG80211 modification from branch 2,2. -+ * -+ * 01 06 2012 wh.su -+ * [WCXRP00001153] [MT6620 Wi-Fi][Driver] Adding the get_ch_list and set_tx_power proto type function -+ * using the wlanSendSetQueryCmd to set the tx power control cmd. -+ * -+ * 01 06 2012 wh.su -+ * [WCXRP00001153] [MT6620 Wi-Fi][Driver] Adding the get_ch_list and set_tx_power proto type function -+ * change the set tx power cmd name. -+ * -+ * 01 05 2012 wh.su -+ * [WCXRP00001153] [MT6620 Wi-Fi][Driver] Adding the get_ch_list and set_tx_power proto type function -+ * Adding the related ioctl / wlan oid function to set the Tx power cfg. -+ * -+ * 12 20 2011 cp.wu -+ * [WCXRP00001144] [MT6620 Wi-Fi][Driver][Firmware] Add RF_FUNC_ID for exposing device and related version information -+ * add driver implementations for RF_AT_FUNCID_FW_INFO & RF_AT_FUNCID_DRV_INFO -+ * to expose version information -+ * -+ * 12 05 2011 cp.wu -+ * [WCXRP00001131] [MT6620 Wi-Fi][Driver][AIS] Implement connect-by-BSSID path -+ * add CONNECT_BY_BSSID policy -+ * -+ * 11 22 2011 cp.wu -+ * [WCXRP00001120] [MT6620 Wi-Fi][Driver] Modify roaming to AIS state transition from synchronous to -+ * asynchronous approach to avoid incomplete state termination -+ * 1. change RDD related compile option brace position. -+ * 2. when roaming is triggered, ask AIS to transit immediately only when AIS is in Normal TR state -+ * without join timeout timer ticking -+ * 3. otherwise, insert AIS_REQUEST into pending request queue -+ * -+ * 11 21 2011 cp.wu -+ * [WCXRP00001118] [MT6620 Wi-Fi][Driver] Corner case protections to pass Monkey testing -+ * 1. wlanoidQueryBssIdList might be passed with a non-zero length but a NULL pointer of buffer -+ * add more checking for such cases -+ * -+ * 2. kalSendComplete() might be invoked with a packet belongs to P2P network right after P2P is unregistered. -+ * add some tweaking to protect such cases because that net device has become invalid. -+ * -+ * 11 15 2011 cm.chang -+ * NULL -+ * Fix compiling warning -+ * -+ * 11 11 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * modify the xlog related code. -+ * -+ * 11 11 2011 tsaiyuan.hsu -+ * [WCXRP00001083] [MT6620 Wi-Fi][DRV]] dump debug counter or frames when debugging is triggered -+ * add debug counters of bb and ar for xlog. -+ * -+ * 11 10 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * change the debug module level. -+ * -+ * 11 09 2011 george.huang -+ * [WCXRP00000871] [MT6620 Wi-Fi][FW] Include additional wakeup condition, which is by -+ * consequent DTIM unicast indication add XLOG for Set PS mode entry -+ * -+ * 11 08 2011 tsaiyuan.hsu -+ * [WCXRP00001083] [MT6620 Wi-Fi][DRV]] dump debug counter or frames when debugging is triggered -+ * check if CFG_SUPPORT_SWCR is defined to aoid compiler error. -+ * -+ * 11 07 2011 tsaiyuan.hsu -+ * [WCXRP00001083] [MT6620 Wi-Fi][DRV]] dump debug counter or frames when debugging is triggered -+ * add debug counters and periodically dump counters for debugging. -+ * -+ * 11 03 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * change the DBGLOG for "\n" and "\r\n". LABEL to LOUD for XLOG -+ * -+ * 11 02 2011 chinghwa.yu -+ * [WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm -+ * Add RDD certification features. -+ * -+ * 10 21 2011 eddie.chen -+ * [WCXRP00001051] [MT6620 Wi-Fi][Driver/Fw] Adjust the STA aging timeout -+ * Add switch to ignore the STA aging timeout. -+ * -+ * 10 12 2011 wh.su -+ * [WCXRP00001036] [MT6620 Wi-Fi][Driver][FW] Adding the 802.11w code for MFP -+ * adding the 802.11w related function and define . -+ * -+ * 09 15 2011 tsaiyuan.hsu -+ * [WCXRP00000938] [MT6620 Wi-Fi][FW] add system config for CTIA -+ * correct fifo full control from query to set operation for CTIA. -+ * -+ * 08 31 2011 cm.chang -+ * [WCXRP00000969] [MT6620 Wi-Fi][Driver][FW] Channel list for 5G band based on country code -+ * . -+ * -+ * 08 17 2011 tsaiyuan.hsu -+ * [WCXRP00000938] [MT6620 Wi-Fi][FW] add system config for CTIA -+ * add system config for CTIA. -+ * -+ * 08 15 2011 george.huang -+ * [MT6620 Wi-Fi][FW] handle TSF drift for connection detection -+ * . -+ * -+ * 07 28 2011 chinghwa.yu -+ * [WCXRP00000063] Update BCM CoEx design and settings -+ * Add BWCS cmd and event. -+ * -+ * 07 18 2011 chinghwa.yu -+ * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm -+ * Add CMD/Event for RDD and BWCS. -+ * -+ * 07 11 2011 wh.su -+ * [WCXRP00000849] [MT6620 Wi-Fi][Driver] Remove some of the WAPI define for make sure the value is initialize, -+ * for customer not enable WAPI -+ * For make sure wapi initial value is set. -+ * -+ * 06 23 2011 cp.wu -+ * [WCXRP00000812] [MT6620 Wi-Fi][Driver] not show NVRAM when there is no valid MAC address in NVRAM content -+ * check with firmware for valid MAC address. -+ * -+ * 05 02 2011 eddie.chen -+ * [WCXRP00000373] [MT6620 Wi-Fi][FW] SW debug control -+ * Fix compile warning. -+ * -+ * 04 29 2011 george.huang -+ * [WCXRP00000684] [MT6620 Wi-Fi][Driver] Support P2P setting ARP filter -+ * . -+ * -+ * 04 27 2011 george.huang -+ * [WCXRP00000684] [MT6620 Wi-Fi][Driver] Support P2P setting ARP filter -+ * add more debug message -+ * -+ * 04 26 2011 eddie.chen -+ * [WCXRP00000373] [MT6620 Wi-Fi][FW] SW debug control -+ * Add rx path profiling. -+ * -+ * 04 12 2011 eddie.chen -+ * [WCXRP00000617] [MT6620 Wi-Fi][DRV/FW] Fix for sigma -+ * Fix the sta index in processing security frame -+ * Simple flow control for TC4 to avoid mgt frames for PS STA to occupy the TC4 -+ * Add debug message. -+ * -+ * 04 08 2011 george.huang -+ * [WCXRP00000621] [MT6620 Wi-Fi][Driver] Support P2P supplicant to set power mode -+ * separate settings of P2P and AIS -+ * -+ * 03 31 2011 puff.wen -+ * NULL -+ * . -+ * -+ * 03 29 2011 puff.wen -+ * NULL -+ * Add chennel switch for stress test -+ * -+ * 03 29 2011 cp.wu -+ * [WCXRP00000604] [MT6620 Wi-Fi][Driver] Surpress Klockwork Warning -+ * surpress klock warning with code path rewritten -+ * -+ * 03 24 2011 wh.su -+ * [WCXRP00000595] [MT6620 Wi-Fi][Driver] at CTIA indicate disconnect to make the ps profile can apply -+ * use disconnect event instead of ais abort for CTIA testing. -+ * -+ * 03 23 2011 george.huang -+ * [WCXRP00000586] [MT6620 Wi-Fi][FW] Modify for blocking absence request right after connected -+ * revise for CTIA power mode setting -+ * -+ * 03 22 2011 george.huang -+ * [WCXRP00000504] [MT6620 Wi-Fi][FW] Support Sigma CAPI for power saving related command -+ * link with supplicant commands -+ * -+ * 03 17 2011 chinglan.wang -+ * [WCXRP00000570] [MT6620 Wi-Fi][Driver] Add Wi-Fi Protected Setup v2.0 feature -+ * . -+ * -+ * 03 17 2011 yarco.yang -+ * [WCXRP00000569] [MT6620 Wi-Fi][F/W][Driver] Set multicast address support current network usage -+ * . -+ * -+ * 03 15 2011 george.huang -+ * [WCXRP00000557] [MT6620 Wi-Fi] Support current consumption test mode commands -+ * Support current consumption measurement mode command -+ * -+ * 03 15 2011 eddie.chen -+ * [WCXRP00000554] [MT6620 Wi-Fi][DRV] Add sw control debug counter -+ * Add sw debug counter for QM. -+ * -+ * 03 10 2011 cp.wu -+ * [WCXRP00000532] [MT6620 Wi-Fi][Driver] Migrate NVRAM configuration procedures from MT6620 E2 to MT6620 E3 -+ * deprecate configuration used by MT6620 E2 -+ * -+ * 03 07 2011 terry.wu -+ * [WCXRP00000521] [MT6620 Wi-Fi][Driver] Remove non-standard debug message -+ * Toggle non-standard debug messages to comments. -+ * -+ * 03 04 2011 cp.wu -+ * [WCXRP00000515] [MT6620 Wi-Fi][Driver] Surpress compiler warning which is identified by GNU compiler collection -+ * surpress compile warning occurred when compiled by GNU compiler collection. -+ * -+ * 03 03 2011 wh.su -+ * [WCXRP00000510] [MT6620 Wi-Fi] [Driver] Fixed the CTIA enter test mode issue -+ * fixed the enter ctia test mode issue. -+ * -+ * 03 02 2011 george.huang -+ * [WCXRP00000504] [MT6620 Wi-Fi][FW] Support Sigma CAPI for power saving related command -+ * Update sigma CAPI for U-APSD setting -+ * -+ * 03 02 2011 george.huang -+ * [WCXRP00000504] [MT6620 Wi-Fi][FW] Support Sigma CAPI for power saving related command -+ * Support UAPSD/OppPS/NoA parameter setting -+ * -+ * 03 02 2011 cp.wu -+ * [WCXRP00000503] [MT6620 Wi-Fi][Driver] Take RCPI brought by association response as -+ * initial RSSI right after connection is built. -+ * use RCPI brought by ASSOC-RESP after connection is built as initial RCPI to avoid using a uninitialized MAC-RX RCPI. -+ * -+ * 01 27 2011 george.huang -+ * [WCXRP00000400] [MT6620 Wi-Fi] support CTIA power mode setting -+ * Support CTIA power mode setting. -+ * -+ * 01 26 2011 wh.su -+ * [WCXRP00000396] [MT6620 Wi-Fi][Driver] Support Sw Ctrl ioctl at linux -+ * adding the SW cmd ioctl support, use set/get structure ioctl. -+ * -+ * 01 25 2011 cp.wu -+ * [WCXRP00000394] [MT6620 Wi-Fi][Driver] Count space needed for generating error message in -+ * scanning list into buffer size checking -+ * when doing size prechecking, check illegal MAC address as well -+ * -+ * 01 20 2011 eddie.chen -+ * [WCXRP00000374] [MT6620 Wi-Fi][DRV] SW debug control -+ * Add Oid for sw control debug command -+ * -+ * 01 15 2011 puff.wen -+ * NULL -+ * Add Stress test -+ * -+ * 01 12 2011 cp.wu -+ * [WCXRP00000358] [MT6620 Wi-Fi][Driver] Provide concurrent information for each module -+ * check if allow to switch to IBSS mode via concurrent module before setting to IBSS mode -+ * -+ * 01 12 2011 cm.chang -+ * [WCXRP00000354] [MT6620 Wi-Fi][Driver][FW] Follow NVRAM bandwidth setting -+ * User-defined bandwidth is for 2.4G and 5G individually -+ * -+ * 01 04 2011 cp.wu -+ * [WCXRP00000342] [MT6620 Wi-Fi][Driver] show error code in scanning list when MAC address is not -+ * correctly configured in NVRAM -+ * show error code 0x10 when MAC address in NVRAM is not configured correctly. -+ * -+ * 01 04 2011 cp.wu -+ * [WCXRP00000338] [MT6620 Wi-Fi][Driver] Separate kalMemAlloc into kmalloc and vmalloc implementations -+ * to ease physically continuous memory demands -+ * separate kalMemAlloc() into virtually-continuous and physically-continuous type to ease slab system pressure -+ * -+ * 12 28 2010 george.huang -+ * [WCXRP00000232] [MT5931 Wi-Fi][FW] Modifications for updated HW power on sequence and related design -+ * support WMM-PS U-APSD AC assignment. -+ * -+ * 12 28 2010 cp.wu -+ * [WCXRP00000269] [MT6620 Wi-Fi][Driver][Firmware] Prepare for v1.1 branch release -+ * report EEPROM used flag via NIC_CAPABILITY -+ * -+ * 12 28 2010 cp.wu -+ * [WCXRP00000269] [MT6620 Wi-Fi][Driver][Firmware] Prepare for v1.1 branch release -+ * integrate with 'EEPROM used' flag for reporting correct capability to Engineer Mode/META and other tools -+ * -+ * 12 16 2010 cp.wu -+ * [WCXRP00000268] [MT6620 Wi-Fi][Driver] correction for WHQL failed items -+ * correction for OID_802_11_NETWORK_TYPES_SUPPORTED handlers -+ * -+ * 12 13 2010 cp.wu -+ * [WCXRP00000256] [MT6620 Wi-Fi][Driver] Eliminate potential issues which is identified by Klockwork -+ * suppress warning reported by Klockwork. -+ * -+ * 12 07 2010 cm.chang -+ * [WCXRP00000239] MT6620 Wi-Fi][Driver][FW] Merge concurrent branch back to maintrunk -+ * 1. BSSINFO include RLM parameter -+ * 2. free all sta records when network is disconnected -+ * -+ * 12 07 2010 cm.chang -+ * [WCXRP00000238] MT6620 Wi-Fi][Driver][FW] Support regulation domain setting from NVRAM and supplicant -+ * 1. Country code is from NVRAM or supplicant -+ * 2. Change band definition in CMD/EVENT. -+ * -+ * 11 30 2010 cp.wu -+ * [WCXRP00000213] [MT6620 Wi-Fi][Driver] Implement scanning with specified SSID for wpa_supplicant with ap_scan=1 -+ * . -+ * -+ * 11 26 2010 cp.wu -+ * [WCXRP00000209] [MT6620 Wi-Fi][Driver] Modify NVRAM checking mechanism to warning only -+ * with necessary data field checking -+ * 1. NVRAM error is now treated as warning only, thus normal operation is still available -+ * but extra scan result used to indicate user is attached -+ * 2. DPD and TX-PWR are needed fields from now on, if these 2 fields are not available then warning message is shown -+ * -+ * 11 25 2010 cp.wu -+ * [WCXRP00000208] [MT6620 Wi-Fi][Driver] Add scanning with specified SSID to AIS FSM -+ * add scanning with specified SSID facility to AIS-FSM -+ * -+ * 11 21 2010 wh.su -+ * [WCXRP00000192] [MT6620 Wi-Fi][Driver] Fixed fail trying to build connection with Security -+ * AP while enable WAPI message check -+ * Not set the wapi mode while the wapi assoc info set non-wapi ie. -+ * -+ * 11 05 2010 wh.su -+ * [WCXRP00000165] [MT6620 Wi-Fi] [Pre-authentication] Assoc req rsn ie use wrong pmkid value -+ * fixed the.pmkid value mismatch issue -+ * -+ * 11 01 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version -+ * Check[WCXRP00000150] [MT6620 Wi-Fi][Driver] Add implementation for querying -+ * current TX rate from firmware auto rate module -+ * 1) Query link speed (TX rate) from firmware directly with buffering mechanism to reduce overhead -+ * 2) Remove CNM CH-RECOVER event handling -+ * 3) cfg read/write API renamed with kal prefix for unified naming rules. -+ * -+ * 10 26 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version -+ * Check[WCXRP00000137] [MT6620 Wi-Fi] [FW] Support NIC capability query command -+ * 1) update NVRAM content template to ver 1.02 -+ * 2) add compile option for querying NIC capability (default: off) -+ * 3) modify AIS 5GHz support to run-time option, which could be turned on by registry or NVRAM setting -+ * 4) correct auto-rate compiler error under linux (treat warning as error) -+ * 5) simplify usage of NVRAM and REG_INFO_T -+ * 6) add version checking between driver and firmware -+ * -+ * 10 22 2010 cp.wu -+ * [WCXRP00000122] [MT6620 Wi-Fi][Driver] Preparation for YuSu source tree integration -+ * dos2unix conversion. -+ * -+ * 10 20 2010 cp.wu -+ * [WCXRP00000117] [MT6620 Wi-Fi][Driver] Add logic for suspending driver when MT6620 is not responding anymore -+ * use OID_CUSTOM_TEST_MODE as indication for driver reset -+ * by dropping pending TX packets -+ * -+ * 10 18 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version -+ * Check[WCXRP00000086] [MT6620 Wi-Fi][Driver] The mac address is all zero at android complete -+ * implementation of Android NVRAM access -+ * -+ * 10 06 2010 yuche.tsai -+ * NULL -+ * Update SLT 5G Test Channel Set. -+ * -+ * 10 06 2010 cp.wu -+ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning -+ * code reorganization to improve isolation between GLUE and CORE layers. -+ * -+ * 10 06 2010 yuche.tsai -+ * NULL -+ * Update For SLT 5G Test Channel Selection Rule. -+ * -+ * 10 05 2010 cp.wu -+ * [WCXRP00000075] [MT6620 Wi-Fi][Driver] Fill query buffer for OID_802_11_BSSID_LIST in 4-bytes aligned form -+ * Query buffer size needs to be enlarged due to result is filled in 4-bytes alignment boundary -+ * -+ * 10 05 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check -+ * 1) add NVRAM access API -+ * 2) fake scanning result when NVRAM doesn't exist and/or version mismatch. (off by compiler option) -+ * 3) add OID implementation for NVRAM read/write service -+ * -+ * 10 04 2010 cp.wu -+ * [WCXRP00000077] [MT6620 Wi-Fi][Driver][FW] Eliminate use of ENUM_NETWORK_TYPE_T and -+ * replaced by ENUM_NETWORK_TYPE_INDEX_T only remove ENUM_NETWORK_TYPE_T definitions -+ * -+ * 10 04 2010 cp.wu -+ * [WCXRP00000075] [MT6620 Wi-Fi][Driver] Fill query buffer for OID_802_11_BSSID_LIST in 4-bytes aligned form -+ * Extend result length to multiples of 4-bytes -+ * -+ * 09 24 2010 cp.wu -+ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning -+ * eliminate unused variables which lead gcc to argue -+ * -+ * 09 24 2010 cp.wu -+ * [WCXRP00000057] [MT6620 Wi-Fi][Driver] Modify online scan to a run-time switchable feature -+ * Modify online scan as a run-time adjustable option (for Windows, in registry) -+ * -+ * 09 23 2010 cp.wu -+ * [WCXRP00000051] [MT6620 Wi-Fi][Driver] WHQL test fail in MAC address changed item -+ * use firmware reported mac address right after wlanAdapterStart() as permanent address -+ * -+ * 09 23 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check -+ * add skeleton for NVRAM integration -+ * -+ * 09 08 2010 cp.wu -+ * NULL -+ * use static memory pool for storing IEs of scanning result. -+ * -+ * 09 07 2010 yuche.tsai -+ * NULL -+ * Update SLT due to API change of SCAN module. -+ * -+ * 09 06 2010 cp.wu -+ * NULL -+ * Androi/Linux: return current operating channel information -+ * -+ * 09 06 2010 cp.wu -+ * NULL -+ * 1) initialize for correct parameter even for disassociation. -+ * 2) AIS-FSM should have a limit on trials to build connection -+ * -+ * 09 03 2010 yuche.tsai -+ * NULL -+ * Refine SLT IO control handler. -+ * -+ * 09 03 2010 kevin.huang -+ * NULL -+ * Refine #include sequence and solve recursive/nested #include issue -+ * -+ * 09 01 2010 wh.su -+ * NULL -+ * adding the wapi support for integration test. -+ * -+ * 08 30 2010 chinglan.wang -+ * NULL -+ * Modify the rescan condition. -+ * -+ * 08 29 2010 yuche.tsai -+ * NULL -+ * Finish SLT TX/RX & Rate Changing Support. -+ * -+ * 08 27 2010 chinglan.wang -+ * NULL -+ * Update configuration for MT6620_E1_PRE_ALPHA_1832_0827_2010 -+ * -+ * 08 25 2010 george.huang -+ * NULL -+ * update OID/ registry control path for PM related settings -+ * -+ * 08 24 2010 cp.wu -+ * NULL -+ * 1) initialize variable for enabling short premable/short time slot. -+ * 2) add compile option for disabling online scan -+ * -+ * 08 16 2010 george.huang -+ * NULL -+ * . -+ * -+ * 08 16 2010 george.huang -+ * NULL -+ * update params defined in CMD_SET_NETWORK_ADDRESS_LIST -+ * -+ * 08 04 2010 cp.wu -+ * NULL -+ * fix for check build WHQL testing: -+ * 1) do not assert query buffer if indicated buffer length is zero -+ * 2) sdio.c has bugs which cause freeing same pointer twice -+ * -+ * 08 04 2010 cp.wu -+ * NULL -+ * revert changelist #15371, efuse read/write access will be done by RF test approach -+ * -+ * 08 04 2010 cp.wu -+ * NULL -+ * add OID definitions for EFUSE read/write access. -+ * -+ * 08 04 2010 george.huang -+ * NULL -+ * handle change PS mode OID/ CMD -+ * -+ * 08 04 2010 cp.wu -+ * NULL -+ * add an extra parameter to rftestQueryATInfo 'cause it's necessary to pass u4FuncData for query request. -+ * -+ * 08 04 2010 cp.wu -+ * NULL -+ * bypass u4FuncData for RF-Test query request as well. -+ * -+ * 08 04 2010 yarco.yang -+ * NULL -+ * Add TX_AMPDU and ADDBA_REJECT command -+ * -+ * 08 03 2010 cp.wu -+ * NULL -+ * surpress compilation warning. -+ * -+ * 08 02 2010 george.huang -+ * NULL -+ * add WMM-PS test related OID/ CMD handlers -+ * -+ * 07 29 2010 cp.wu -+ * NULL -+ * eliminate u4FreqInKHz usage, combined into rConnections.ucAdHoc* -+ * -+ * 07 28 2010 cp.wu -+ * NULL -+ * 1) eliminate redundant variable eOPMode in prAdapter->rWlanInfo -+ * 2) change nicMediaStateChange() API prototype -+ * -+ * 07 26 2010 cp.wu -+ * -+ * re-commit code logic being overwriten. -+ * -+ * 07 24 2010 wh.su -+ * -+ * .support the Wi-Fi RSN -+ * -+ * 07 21 2010 cp.wu -+ * -+ * 1) change BG_SCAN to ONLINE_SCAN for consistent term -+ * 2) only clear scanning result when scan is permitted to do -+ * -+ * 07 20 2010 cp.wu -+ * -+ * 1) [AIS] when new scan is issued, clear currently available scanning result except the connected one -+ * 2) refine disconnection behaviour when issued during BG-SCAN process -+ * -+ * 07 19 2010 wh.su -+ * -+ * modify the auth and encry status variable. -+ * -+ * 07 16 2010 cp.wu -+ * -+ * remove work-around in case SCN is not available. -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 07 05 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) change fake BSS_DESC from channel 6 to channel 1 due to channel switching is not done yet. -+ * 2) after MAC address is queried from firmware, all related variables in driver domain should be updated as well -+ * -+ * 07 01 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * AIS-FSM integration with CNM channel request messages -+ * -+ * 07 01 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * implementation of DRV-SCN and related mailbox message handling. -+ * -+ * 06 29 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) sync to. CMD/EVENT document v0.03 -+ * 2) simplify DTIM period parsing in scan.c only, bss.c no longer parses it again. -+ * 3) send command packet to indicate FW-PM after -+ * a) 1st beacon is received after AIS has connected to an AP -+ * b) IBSS-ALONE has been created -+ * c) IBSS-MERGE has occurred -+ * -+ * 06 25 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add API in que_mgt to retrieve sta-rec index for security frames. -+ * -+ * 06 24 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 802.1x and bluetooth-over-Wi-Fi security frames are now delievered to firmware via command path instead of data path. -+ * -+ * 06 23 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) add SCN compilation option. -+ * 2) when SCN is not turned on, BSSID_SCAN will generate a fake entry for 1st connection -+ * -+ * 06 23 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * implement SCAN-REQUEST oid as mailbox message dispatching. -+ * -+ * 06 23 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * integrate . -+ * -+ * 06 22 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) add command warpper for STA-REC/BSS-INFO sync. -+ * 2) enhance command packet sending procedure for non-oid part -+ * 3) add command packet definitions for STA-REC/BSS-INFO sync. -+ * -+ * 06 21 2010 wh.su -+ * [WPD00003840][MT6620 5931] Security migration -+ * remove duplicate variable for migration. -+ * -+ * 06 21 2010 wh.su -+ * [WPD00003840][MT6620 5931] Security migration -+ * adding the compiling flag for oid pmkid. -+ * -+ * 06 21 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * enable RX management frame handling. -+ * -+ * 06 18 2010 wh.su -+ * [WPD00003840][MT6620 5931] Security migration -+ * migration the security related function from firmware. -+ * -+ * 06 11 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) migrate assoc.c. -+ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness -+ * 3) add configuration options for CNM_MEM and RSN modules -+ * 4) add data path for management frames -+ * 5) eliminate rPacketInfo of MSDU_INFO_T -+ * -+ * 06 10 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) eliminate CFG_CMD_EVENT_VERSION_0_9 -+ * 2) when disconnected, indicate nic directly (no event is needed) -+ * -+ * 06 07 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * merge wlan_def.h. -+ * -+ * 06 07 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * merge wifi_var.h, precomp.h, cnm_timer.h (data type only) -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 06 03 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * move timer callback to glue layer. -+ * -+ * 05 28 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * simplify cmd packet sending for RF test and MCR access OIDs -+ * -+ * 05 27 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * disable radio even when STA is not associated. -+ * -+ * 05 27 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * correct 2 OID behaviour to meet WHQL requirement. -+ * -+ * 05 26 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * 1) Modify set mac address code -+ * 2) remove power management macro -+ * -+ * 05 25 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * correct BSSID_LIST oid when radio if turned off. -+ * -+ * 05 24 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) when acquiring LP-own, write for clr-own with lower frequency compared to read poll -+ * 2) correct address list parsing -+ * -+ * 05 24 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * disable wlanoidSetNetworkAddress() temporally. -+ * -+ * 05 22 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * some OIDs should be DRIVER_CORE instead of GLUE_EXTENSION -+ * -+ * 05 22 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) disable NETWORK_LAYER_ADDRESSES handling temporally. -+ * 2) finish statistics OIDs -+ * -+ * 05 22 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * change OID behavior to meet WHQL requirement. -+ * -+ * 05 20 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) integrate OID_GEN_NETWORK_LAYER_ADDRESSES with CMD_ID_SET_IP_ADDRESS -+ * 2) buffer statistics data for 2 seconds -+ * 3) use default value for adhoc parameters instead of 0 -+ * -+ * 05 19 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) do not take timeout mechanism for power mode oids -+ * 2) retrieve network type from connection status -+ * 3) after disassciation, set radio state to off -+ * 4) TCP option over IPv6 is supported -+ * -+ * 05 18 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * implement Wakeup-on-LAN except firmware integration part -+ * -+ * 05 17 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * correct wlanoidSet802dot11PowerSaveProfile implementation. -+ * -+ * 05 17 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) enable CMD/EVENT ver 0.9 definition. -+ * 2) abandon use of ENUM_MEDIA_STATE -+ * -+ * 05 17 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * correct OID_802_11_DISASSOCIATE handling. -+ * -+ * 05 17 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * 1) add timeout handler mechanism for pending command packets -+ * 2) add p2p add/removal key -+ * -+ * 05 14 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * Add dissassocation support for wpa supplicant -+ * -+ * 05 14 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * correct return value. -+ * -+ * 05 13 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * add NULL OID implementation for WOL-related OIDs. -+ * -+ * 05 06 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * for disassociation, still use parameter with current setting. -+ * -+ * 05 06 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * for disassociation, generate a WZC-compatible invalid SSID. -+ * -+ * 05 06 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * associate to illegal SSID when handling OID_802_11_DISASSOCIATE -+ * -+ * 04 27 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * reserve field of privacy filter and RTS threshold setting. -+ * -+ * 04 23 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * surpress compiler warning -+ * -+ * 04 23 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * . -+ * -+ * 04 22 2010 cp.wu -+ * [WPD00003830]add OID_802_11_PRIVACY_FILTER support -+ * enable RX filter OID -+ * -+ * 04 19 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * Add ioctl of power management -+ * -+ * 04 14 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * information buffer for query oid/ioctl is now buffered in prCmdInfo -+ * * instead of glue-layer variable to improve multiple oid/ioctl capability -+ * -+ * 04 13 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * add framework for BT-over-Wi-Fi support. -+ * * * * 1) prPendingCmdInfo is replaced by queue for multiple handler capability -+ * * * * 2) command sequence number is now increased atomically -+ * * * * 3) private data could be hold and taken use for other purpose -+ * -+ * 04 12 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * correct OID_802_11_CONFIGURATION query for infrastructure mode. -+ * -+ * 04 09 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * 1) remove unused spin lock declaration -+ * -+ * 04 07 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * finish non-glue layer access to glue variables -+ * -+ * 04 07 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * rWlanInfo should be placed at adapter rather than glue due to most operations -+ * * are done in adapter layer. -+ * -+ * 04 07 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * (1)improve none-glue code portability -+ * (2) disable set Multicast address during atomic context -+ * -+ * 04 07 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * eliminate direct access to prGlueInfo->eParamMediaStateIndicated from non-glue layer -+ * -+ * 04 06 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * ePowerCtrl is not necessary as a glue variable. -+ * -+ * 04 06 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * eliminate direct access to prGlueInfo->rWlanInfo.eLinkAttr.ucMediaStreamMode from non-glue layer. -+ * -+ * 04 06 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * improve none-glue code portability -+ * -+ * 04 06 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * code refine: fgTestMode should be at adapter rather than glue due to the device/fw is also involved -+ * -+ * 04 01 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * . -+ * -+ * 03 31 2010 wh.su -+ * [WPD00003816][MT6620 Wi-Fi] Adding the security support -+ * modify the wapi related code for new driver's design. -+ * -+ * 03 30 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * statistics information OIDs are now handled by querying from firmware domain -+ * -+ * 03 28 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * improve glue code portability -+ * -+ * 03 26 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * indicate media stream mode after set is done -+ * -+ * 03 26 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * add a temporary flag for integration with CMD/EVENT v0.9. -+ * -+ * 03 25 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) correct OID_802_11_CONFIGURATION with frequency setting behavior. -+ * the frequency is used for adhoc connection only -+ * 2) update with SD1 v0.9 CMD/EVENT documentation -+ * -+ * 03 24 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * [WPD00003826] Initial import for Linux port -+ * initial import for Linux port -+ * -+ * 03 24 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * initial import for Linux port -+ * -+ * 03 24 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * generate information for OID_GEN_RCV_OK & OID_GEN_XMIT_OK -+ * -+ * -+ * 03 22 2010 cp.wu -+ * [WPD00003824][MT6620 Wi-Fi][New Feature] Add support of large scan list -+ * Implement feature needed by CR: WPD00003824: refining association command by pasting scanning result -+ * -+ * 03 19 2010 wh.su -+ * [WPD00003820][MT6620 Wi-Fi] Modify the code for meet the WHQL test -+ * adding the check for pass WHQL test item. -+ * -+ * 03 19 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) add ACPI D0/D3 state switching support -+ * * 2) use more formal way to handle interrupt when the status is retrieved from enhanced RX response -+ * -+* 03 16 2010 wh.su -+ * [WPD00003820][MT6620 Wi-Fi] Modify the code for meet the WHQL test -+ * fixed some whql pre-test fail case. -+ * -+ * 03 03 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * implement custom OID: EEPROM read/write access -+ * -+ * 03 03 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * implement OID_802_3_MULTICAST_LIST oid handling -+ * -+ * 03 02 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) the use of prPendingOid revised, all accessing are now protected by spin lock -+ * * 2) ensure wlanReleasePendingOid will clear all command queues -+ * -+ * 02 25 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * send CMD_ID_INFRASTRUCTURE when handling OID_802_11_INFRASTRUCTURE_MODE set. -+ * -+ * 02 24 2010 wh.su -+ * [WPD00003820][MT6620 Wi-Fi] Modify the code for meet the WHQL test -+ * Don't needed to check the auth mode, WHQL testing not specific at auth wpa2. -+ * -+ * 02 23 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * do not check SSID validity anymore. -+ * -+ * 02 23 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * add checksum offloading support. -+ * -+ * 02 09 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1. Permanent and current MAC address are now retrieved by CMD/EVENT packets instead of hard-coded address -+ * * 2. follow MSDN defined behavior when associates to another AP -+ * * 3. for firmware download, packet size could be up to 2048 bytes -+ * -+ * 02 09 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * move ucCmdSeqNum as instance variable -+ * -+ * 02 04 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * when OID_CUSTOM_OID_INTERFACE_VERSION is queried, do modify connection states -+ * -+ * 01 27 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) implement timeout mechanism when OID is pending for longer than 1 second -+ * * 2) allow OID_802_11_CONFIGURATION to be executed when RF test mode is turned on -+ * -+ * 01 27 2010 wh.su -+ * [WPD00003816][MT6620 Wi-Fi] Adding the security support -+ * . -+ * -+ * 01 27 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1. eliminate improper variable in rHifInfo -+ * * 2. block TX/ordinary OID when RF test mode is engaged -+ * * 3. wait until firmware finish operation when entering into and leaving from RF test mode -+ * * 4. correct some HAL implementation -+ * -+ * 01 22 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * implement following 802.11 OIDs: -+ * OID_802_11_RSSI, -+ * OID_802_11_RSSI_TRIGGER, -+ * OID_802_11_STATISTICS, -+ * OID_802_11_DISASSOCIATE, -+ * OID_802_11_POWER_MODE -+ * -+ * 01 21 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * implement OID_802_11_MEDIA_STREAM_MODE -+ * -+ * 01 21 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * implement OID_802_11_SUPPORTED_RATES / OID_802_11_DESIRED_RATES -+ * -+ * 01 21 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * do not fill ucJoinOnly currently -+ * -+ * 01 14 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * enable to connect to ad-hoc network -+ * -+ * 01 07 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * .implement Set/Query BeaconInterval/AtimWindow -+ * -+ * 01 07 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * .Set/Get AT Info is not blocked even when driver is not in fg test mode -+ * -+ * 12 30 2009 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) According to CMD/EVENT documentation v0.8, -+ * OID_CUSTOM_TEST_RX_STATUS & OID_CUSTOM_TEST_TX_STATUS is no longer used, -+ * and result is retrieved by get ATInfo instead -+ * 2) add 4 counter for recording aggregation statistics -+ * -+ * 12 28 2009 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * eliminate redundant variables for connection_state -+** \main\maintrunk.MT6620WiFiDriver_Prj\32 2009-12-16 22:13:36 GMT mtk02752 -+** change hard-coded MAC address to match with FW (temporally) -+** \main\maintrunk.MT6620WiFiDriver_Prj\31 2009-12-10 16:49:50 GMT mtk02752 -+** code clean -+** \main\maintrunk.MT6620WiFiDriver_Prj\30 2009-12-08 17:38:49 GMT mtk02752 -+** + add OID for RF test -+** * MCR RD/WR are modified to match with cmd/event definition -+** \main\maintrunk.MT6620WiFiDriver_Prj\29 2009-12-08 11:32:20 GMT mtk02752 -+** add skeleton for RF test implementation -+** \main\maintrunk.MT6620WiFiDriver_Prj\28 2009-12-03 16:43:24 GMT mtk01461 -+** Modify query SCAN list oid by adding prEventScanResult -+** -+** \main\maintrunk.MT6620WiFiDriver_Prj\27 2009-12-03 16:39:27 GMT mtk01461 -+** Sync CMD data structure in set ssid oid -+** \main\maintrunk.MT6620WiFiDriver_Prj\26 2009-12-03 16:28:22 GMT mtk01461 -+** Add invalid check of set SSID oid and fix query scan list oid -+** \main\maintrunk.MT6620WiFiDriver_Prj\25 2009-11-30 17:33:08 GMT mtk02752 -+** implement wlanoidSetInfrastructureMode/wlanoidQueryInfrastructureMode -+** \main\maintrunk.MT6620WiFiDriver_Prj\24 2009-11-30 10:53:49 GMT mtk02752 -+** 1st DW of WIFI_CMD_T is shared with HIF_TX_HEADER_T -+** \main\maintrunk.MT6620WiFiDriver_Prj\23 2009-11-30 09:22:48 GMT mtk02752 -+** correct wifi cmd length mismatch -+** \main\maintrunk.MT6620WiFiDriver_Prj\22 2009-11-25 21:34:33 GMT mtk02752 -+** sync EVENT_SCAN_RESULT_T with firmware -+** \main\maintrunk.MT6620WiFiDriver_Prj\21 2009-11-25 21:03:27 GMT mtk02752 -+** implement wlanoidQueryBssidList() -+** \main\maintrunk.MT6620WiFiDriver_Prj\20 2009-11-25 18:17:17 GMT mtk02752 -+** refine GL_WLAN_INFO_T for buffering scan result -+** \main\maintrunk.MT6620WiFiDriver_Prj\19 2009-11-23 20:28:51 GMT mtk02752 -+** some OID will be set to WLAN_STATUS_PENDING until it is sent via wlanSendCommand() -+** \main\maintrunk.MT6620WiFiDriver_Prj\18 2009-11-23 17:56:36 GMT mtk02752 -+** implement wlanoidSetBssidListScan(), wlanoidSetBssid() and wlanoidSetSsid() -+** -+** \main\maintrunk.MT6620WiFiDriver_Prj\17 2009-11-13 17:20:53 GMT mtk02752 -+** add Set BSSID/SSID path but disabled temporally due to FW is not ready yet -+** \main\maintrunk.MT6620WiFiDriver_Prj\16 2009-11-13 12:28:58 GMT mtk02752 -+** add wlanoidSetBssidListScan -> cmd_info path -+** \main\maintrunk.MT6620WiFiDriver_Prj\15 2009-11-09 22:48:07 GMT mtk01084 -+** modify test cases entry -+** \main\maintrunk.MT6620WiFiDriver_Prj\14 2009-11-04 14:10:58 GMT mtk01084 -+** add new test interfaces -+** \main\maintrunk.MT6620WiFiDriver_Prj\13 2009-10-30 18:17:10 GMT mtk01084 -+** fix compiler warning -+** \main\maintrunk.MT6620WiFiDriver_Prj\12 2009-10-29 19:46:26 GMT mtk01084 -+** add test functions -+** \main\maintrunk.MT6620WiFiDriver_Prj\11 2009-10-23 16:07:56 GMT mtk01084 -+** include new file -+** \main\maintrunk.MT6620WiFiDriver_Prj\10 2009-10-13 21:58:29 GMT mtk01084 -+** modify for new HW architecture -+** \main\maintrunk.MT6620WiFiDriver_Prj\9 2009-10-02 13:48:49 GMT mtk01725 -+** \main\maintrunk.MT6620WiFiDriver_Prj\8 2009-09-09 17:26:04 GMT mtk01084 -+** \main\maintrunk.MT6620WiFiDriver_Prj\7 2009-04-21 12:09:50 GMT mtk01461 -+** Update for MCR Write OID -+** \main\maintrunk.MT6620WiFiDriver_Prj\6 2009-04-21 09:35:18 GMT mtk01461 -+** Update wlanoidQueryMcrRead() for composing CMD_INFO_T -+** \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-04-17 18:09:51 GMT mtk01426 -+** Remove kalIndicateStatusAndComplete() in wlanoidQueryOidInterfaceVersion() -+** \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-04-14 15:51:50 GMT mtk01426 -+** Add MCR read/write support -+** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-03-19 18:32:40 GMT mtk01084 -+** update for basic power management functions -+** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 20:06:31 GMT mtk01426 -+** Init for develop -+** -+*/ -+ -+/****************************************************************************** -+* C O M P I L E R F L A G S -+******************************************************************************* -+*/ -+ -+/****************************************************************************** -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************* -+*/ -+#include "precomp.h" -+#include "mgmt/rsn.h" -+ -+#include -+ -+/****************************************************************************** -+* C O N S T A N T S -+******************************************************************************* -+*/ -+ -+/****************************************************************************** -+* D A T A T Y P E S -+******************************************************************************* -+*/ -+ -+/****************************************************************************** -+* P U B L I C D A T A -+******************************************************************************* -+*/ -+ -+/****************************************************************************** -+* P R I V A T E D A T A -+******************************************************************************* -+*/ -+ -+/****************************************************************************** -+* M A C R O S -+******************************************************************************* -+*/ -+ -+/****************************************************************************** -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************* -+*/ -+ -+/****************************************************************************** -+* F U N C T I O N S -+******************************************************************************* -+*/ -+#if CFG_ENABLE_STATISTICS_BUFFERING -+static BOOLEAN IsBufferedStatisticsUsable(P_ADAPTER_T prAdapter) -+{ -+ ASSERT(prAdapter); -+ -+ if (prAdapter->fgIsStatValid == TRUE && -+ (kalGetTimeTick() - prAdapter->rStatUpdateTime) <= CFG_STATISTICS_VALID_CYCLE) -+ return TRUE; -+ else -+ return FALSE; -+} -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to query the supported physical layer network -+* type that can be used by the driver. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[out] pvQueryBuffer A pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufferLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryNetworkTypesSupported(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ UINT_32 u4NumItem = 0; -+ ENUM_PARAM_NETWORK_TYPE_T eSupportedNetworks[PARAM_NETWORK_TYPE_NUM]; -+ PPARAM_NETWORK_TYPE_LIST prSupported; -+ -+ /* The array of all physical layer network subtypes that the driver supports. */ -+ -+ DEBUGFUNC("wlanoidQueryNetworkTypesSupported"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4QueryInfoLen); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ -+ /* Init. */ -+ for (u4NumItem = 0; u4NumItem < PARAM_NETWORK_TYPE_NUM; u4NumItem++) -+ eSupportedNetworks[u4NumItem] = 0; -+ -+ u4NumItem = 0; -+ -+ eSupportedNetworks[u4NumItem] = PARAM_NETWORK_TYPE_DS; -+ u4NumItem++; -+ -+ eSupportedNetworks[u4NumItem] = PARAM_NETWORK_TYPE_OFDM24; -+ u4NumItem++; -+ -+ *pu4QueryInfoLen = -+ (UINT_32) OFFSET_OF(PARAM_NETWORK_TYPE_LIST, eNetworkType) + -+ (u4NumItem * sizeof(ENUM_PARAM_NETWORK_TYPE_T)); -+ -+ if (u4QueryBufferLen < *pu4QueryInfoLen) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ prSupported = (PPARAM_NETWORK_TYPE_LIST) pvQueryBuffer; -+ prSupported->NumberOfItems = u4NumItem; -+ kalMemCopy(prSupported->eNetworkType, eSupportedNetworks, u4NumItem * sizeof(ENUM_PARAM_NETWORK_TYPE_T)); -+ -+ DBGLOG(OID, TRACE, "NDIS supported network type list: %u\n", prSupported->NumberOfItems); -+ DBGLOG_MEM8(OID, TRACE, prSupported, *pu4QueryInfoLen); -+ -+ return WLAN_STATUS_SUCCESS; -+} /* wlanoidQueryNetworkTypesSupported */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to query the current physical layer network -+* type used by the driver. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[out] pvQueryBuffer A pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufferLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the -+* call failed due to invalid length of the query -+* buffer, returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_BUFFER_TOO_SHORT -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryNetworkTypeInUse(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ /* TODO: need to check the OID handler content again!! */ -+ -+ ENUM_PARAM_NETWORK_TYPE_T rCurrentNetworkTypeInUse = PARAM_NETWORK_TYPE_OFDM24; -+ -+ DEBUGFUNC("wlanoidQueryNetworkTypeInUse"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4QueryInfoLen); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ -+ if (u4QueryBufferLen < sizeof(ENUM_PARAM_NETWORK_TYPE_T)) { -+ *pu4QueryInfoLen = sizeof(ENUM_PARAM_NETWORK_TYPE_T); -+ return WLAN_STATUS_BUFFER_TOO_SHORT; -+ } -+ -+ if (kalGetMediaStateIndicated(prAdapter->prGlueInfo) == PARAM_MEDIA_STATE_CONNECTED) -+ rCurrentNetworkTypeInUse = (ENUM_PARAM_NETWORK_TYPE_T) (prAdapter->rWlanInfo.ucNetworkType); -+ else -+ rCurrentNetworkTypeInUse = (ENUM_PARAM_NETWORK_TYPE_T) (prAdapter->rWlanInfo.ucNetworkTypeInUse); -+ -+ *(P_ENUM_PARAM_NETWORK_TYPE_T) pvQueryBuffer = rCurrentNetworkTypeInUse; -+ *pu4QueryInfoLen = sizeof(ENUM_PARAM_NETWORK_TYPE_T); -+ -+ DBGLOG(OID, TRACE, "Network type in use: %d\n", rCurrentNetworkTypeInUse); -+ -+ return WLAN_STATUS_SUCCESS; -+} /* wlanoidQueryNetworkTypeInUse */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to set the physical layer network type used -+* by the driver. -+* -+* \param[in] pvAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns the -+* amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS The given network type is supported and accepted. -+* \retval WLAN_STATUS_INVALID_DATA The given network type is not in the -+* supported list. -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetNetworkTypeInUse(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ /* TODO: need to check the OID handler content again!! */ -+ -+ ENUM_PARAM_NETWORK_TYPE_T eNewNetworkType; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ -+ DEBUGFUNC("wlanoidSetNetworkTypeInUse"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pvSetBuffer); -+ ASSERT(pu4SetInfoLen); -+ -+ if (u4SetBufferLen < sizeof(ENUM_PARAM_NETWORK_TYPE_T)) { -+ *pu4SetInfoLen = sizeof(ENUM_PARAM_NETWORK_TYPE_T); -+ return WLAN_STATUS_INVALID_LENGTH; -+ } -+ -+ eNewNetworkType = *(P_ENUM_PARAM_NETWORK_TYPE_T) pvSetBuffer; -+ *pu4SetInfoLen = sizeof(ENUM_PARAM_NETWORK_TYPE_T); -+ -+ DBGLOG(OID, INFO, "New network type: %d mode\n", eNewNetworkType); -+ -+ switch (eNewNetworkType) { -+ -+ case PARAM_NETWORK_TYPE_DS: -+ prAdapter->rWlanInfo.ucNetworkTypeInUse = (UINT_8) PARAM_NETWORK_TYPE_DS; -+ break; -+ -+ case PARAM_NETWORK_TYPE_OFDM5: -+ prAdapter->rWlanInfo.ucNetworkTypeInUse = (UINT_8) PARAM_NETWORK_TYPE_OFDM5; -+ break; -+ -+ case PARAM_NETWORK_TYPE_OFDM24: -+ prAdapter->rWlanInfo.ucNetworkTypeInUse = (UINT_8) PARAM_NETWORK_TYPE_OFDM24; -+ break; -+ -+ case PARAM_NETWORK_TYPE_AUTOMODE: -+ prAdapter->rWlanInfo.ucNetworkTypeInUse = (UINT_8) PARAM_NETWORK_TYPE_AUTOMODE; -+ break; -+ -+ case PARAM_NETWORK_TYPE_FH: -+ DBGLOG(OID, INFO, "Not support network type: %d\n", eNewNetworkType); -+ rStatus = WLAN_STATUS_NOT_SUPPORTED; -+ break; -+ -+ default: -+ DBGLOG(OID, INFO, "Unknown network type: %d\n", eNewNetworkType); -+ rStatus = WLAN_STATUS_INVALID_DATA; -+ break; -+ } -+ -+ /* Verify if we support the new network type. */ -+ if (rStatus != WLAN_STATUS_SUCCESS) -+ DBGLOG(OID, WARN, "Unknown network type: %d\n", eNewNetworkType); -+ -+ return rStatus; -+} /* wlanoidSetNetworkTypeInUse */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to query the current BSSID. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[out] pvQueryBuffer A pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufferLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_ADAPTER_NOT_READY -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryBssid(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ -+ DEBUGFUNC("wlanoidQueryBssid"); -+ -+ ASSERT(prAdapter); -+ -+ if (u4QueryBufferLen < MAC_ADDR_LEN) { -+ ASSERT(pu4QueryInfoLen); -+ *pu4QueryInfoLen = MAC_ADDR_LEN; -+ return WLAN_STATUS_BUFFER_TOO_SHORT; -+ } -+ -+ ASSERT(u4QueryBufferLen >= MAC_ADDR_LEN); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ ASSERT(pu4QueryInfoLen); -+ -+ if (kalGetMediaStateIndicated(prAdapter->prGlueInfo) == PARAM_MEDIA_STATE_CONNECTED) -+ kalMemCopy(pvQueryBuffer, prAdapter->rWlanInfo.rCurrBssId.arMacAddress, MAC_ADDR_LEN); -+ else if (prAdapter->rWifiVar.rConnSettings.eOPMode == NET_TYPE_IBSS) { -+ PARAM_MAC_ADDRESS aucTemp; /*!< BSSID */ -+ -+ COPY_MAC_ADDR(aucTemp, prAdapter->rWlanInfo.rCurrBssId.arMacAddress); -+ aucTemp[0] &= ~BIT(0); -+ aucTemp[1] |= BIT(1); -+ COPY_MAC_ADDR(pvQueryBuffer, aucTemp); -+ } else -+ rStatus = WLAN_STATUS_ADAPTER_NOT_READY; -+ -+ *pu4QueryInfoLen = MAC_ADDR_LEN; -+ return rStatus; -+} /* wlanoidQueryBssid */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to query the list of all BSSIDs detected by -+* the driver. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[out] pvQueryBuffer A pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufferLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+* \retval WLAN_STATUS_ADAPTER_NOT_READY -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryBssidList(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ P_GLUE_INFO_T prGlueInfo; -+ UINT_32 i, u4BssidListExLen; -+ P_PARAM_BSSID_LIST_EX_T prList; -+ P_PARAM_BSSID_EX_T prBssidEx; -+ PUINT_8 cp; -+ -+ DEBUGFUNC("wlanoidQueryBssidList"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4QueryInfoLen); -+ -+ if (u4QueryBufferLen) { -+ ASSERT(pvQueryBuffer); -+ -+ if (!pvQueryBuffer) -+ return WLAN_STATUS_INVALID_DATA; -+ } -+ -+ prGlueInfo = prAdapter->prGlueInfo; -+ -+ if (prAdapter->rAcpiState == ACPI_STATE_D3) { -+ DBGLOG(OID, WARN, "Fail in qeury BSSID list! (Adapter not ready). ACPI=D%d, Radio=%d\n", -+ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); -+ return WLAN_STATUS_ADAPTER_NOT_READY; -+ } -+ -+ u4BssidListExLen = 0; -+ -+ if (prAdapter->fgIsRadioOff == FALSE) { -+ for (i = 0; i < prAdapter->rWlanInfo.u4ScanResultNum; i++) -+ u4BssidListExLen += ALIGN_4(prAdapter->rWlanInfo.arScanResult[i].u4Length); -+ } -+ -+ if (u4BssidListExLen) -+ u4BssidListExLen += 4; /* u4NumberOfItems. */ -+ else -+ u4BssidListExLen = sizeof(PARAM_BSSID_LIST_EX_T); -+ -+ *pu4QueryInfoLen = u4BssidListExLen; -+ -+ if (u4QueryBufferLen < *pu4QueryInfoLen) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ /* Clear the buffer */ -+ kalMemZero(pvQueryBuffer, u4BssidListExLen); -+ -+ prList = (P_PARAM_BSSID_LIST_EX_T) pvQueryBuffer; -+ cp = (PUINT_8) &prList->arBssid[0]; -+ -+ if (prAdapter->fgIsRadioOff == FALSE && prAdapter->rWlanInfo.u4ScanResultNum > 0) { -+ /* fill up for each entry */ -+ for (i = 0; i < prAdapter->rWlanInfo.u4ScanResultNum; i++) { -+ prBssidEx = (P_PARAM_BSSID_EX_T) cp; -+ -+ /* copy structure */ -+ kalMemCopy(prBssidEx, -+ &(prAdapter->rWlanInfo.arScanResult[i]), OFFSET_OF(PARAM_BSSID_EX_T, aucIEs)); -+ -+ /*For WHQL test, Rssi should be in range -10 ~ -200 dBm */ -+ if (prBssidEx->rRssi > PARAM_WHQL_RSSI_MAX_DBM) -+ prBssidEx->rRssi = PARAM_WHQL_RSSI_MAX_DBM; -+ -+ if (prAdapter->rWlanInfo.arScanResult[i].u4IELength > 0) { -+ /* copy IEs */ -+ kalMemCopy(prBssidEx->aucIEs, -+ prAdapter->rWlanInfo.apucScanResultIEs[i], -+ prAdapter->rWlanInfo.arScanResult[i].u4IELength); -+ } -+ /* 4-bytes alignement */ -+ prBssidEx->u4Length = ALIGN_4(prBssidEx->u4Length); -+ -+ cp += prBssidEx->u4Length; -+ prList->u4NumberOfItems++; -+ } -+ } -+ -+ return WLAN_STATUS_SUCCESS; -+} /* wlanoidQueryBssidList */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to request the driver to perform -+* scanning. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer Pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_ADAPTER_NOT_READY -+* \retval WLAN_STATUS_FAILURE -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetBssidListScan(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ P_PARAM_SSID_T prSsid; -+ PARAM_SSID_T rSsid; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ -+ DEBUGFUNC("wlanoidSetBssidListScan()"); -+ -+ if (prAdapter->rAcpiState == ACPI_STATE_D3) { -+ DBGLOG(OID, WARN, "Fail in set BSSID list scan! (Adapter not ready). ACPI=D%d, Radio=%d\n", -+ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); -+ return WLAN_STATUS_ADAPTER_NOT_READY; -+ } -+ -+ ASSERT(pu4SetInfoLen); -+ *pu4SetInfoLen = 0; -+ -+ if (prAdapter->fgIsRadioOff) { -+ DBGLOG(OID, WARN, "Return from BSSID list scan! (radio off). ACPI=D%d, Radio=%d\n", -+ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); -+ return WLAN_STATUS_SUCCESS; -+ } -+ -+ DBGLOG(OID, TRACE, "Scan\n"); -+ -+ if (pvSetBuffer != NULL && u4SetBufferLen != 0) { -+ COPY_SSID(rSsid.aucSsid, rSsid.u4SsidLen, pvSetBuffer, u4SetBufferLen); -+ prSsid = &rSsid; -+ } else { -+ prSsid = NULL; -+ } -+ -+#if CFG_SUPPORT_RDD_TEST_MODE -+ if (prAdapter->prGlueInfo->rRegInfo.u4RddTestMode) { -+ if ((prAdapter->fgEnOnlineScan == TRUE) && (prAdapter->ucRddStatus)) { -+ if (kalGetMediaStateIndicated(prAdapter->prGlueInfo) != PARAM_MEDIA_STATE_CONNECTED) { -+ aisFsmScanRequest(prAdapter, prSsid, NULL, 0); -+ } else { -+ /* reject the scan request */ -+ rStatus = WLAN_STATUS_FAILURE; -+ } -+ } else { -+ /* reject the scan request */ -+ rStatus = WLAN_STATUS_FAILURE; -+ } -+ } else -+#endif -+ { -+ if (prAdapter->fgEnOnlineScan == TRUE) { -+ aisFsmScanRequest(prAdapter, prSsid, NULL, 0); -+ } else if (kalGetMediaStateIndicated(prAdapter->prGlueInfo) != PARAM_MEDIA_STATE_CONNECTED) { -+ aisFsmScanRequest(prAdapter, prSsid, NULL, 0); -+ } else { -+ /* reject the scan request */ -+ rStatus = WLAN_STATUS_FAILURE; -+ } -+ } -+ -+ return rStatus; -+} /* wlanoidSetBssidListScan */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to request the driver to perform -+* scanning with attaching information elements(IEs) specified from user space -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer Pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_ADAPTER_NOT_READY -+* \retval WLAN_STATUS_FAILURE -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetBssidListScanExt(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ P_PARAM_SCAN_REQUEST_EXT_T prScanRequest; -+ P_AIS_FSM_INFO_T prAisFsmInfo; -+ P_PARAM_SSID_T prSsid; -+ PUINT_8 pucIe; -+ UINT_32 u4IeLength; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ UINT_8 ucScanTime = AIS_SCN_DONE_TIMEOUT_SEC; -+ -+ DEBUGFUNC("wlanoidSetBssidListScanExt()"); -+ -+ if (prAdapter->rAcpiState == ACPI_STATE_D3) { -+ DBGLOG(OID, ERROR, "Fail in set BSSID list scan! (Adapter not ready). ACPI=D%d, Radio=%d\n", -+ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); -+ return WLAN_STATUS_ADAPTER_NOT_READY; -+ } else if (prAdapter->fgTestMode) { -+ DBGLOG(OID, WARN, "didn't support Scan in test mode\n"); -+ return WLAN_STATUS_FAILURE; -+ } -+ -+ ASSERT(pu4SetInfoLen); -+ *pu4SetInfoLen = 0; -+ -+ if (u4SetBufferLen != sizeof(PARAM_SCAN_REQUEST_EXT_T)) { -+ DBGLOG(OID, ERROR, "u4SetBufferLen != sizeof(PARAM_SCAN_REQUEST_EXT_T)\n"); -+ return WLAN_STATUS_INVALID_LENGTH; -+ } -+ -+ if (prAdapter->fgIsRadioOff) { -+ DBGLOG(OID, INFO, "Return from BSSID list scan! (radio off). ACPI=D%d, Radio=%d\n", -+ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); -+ return WLAN_STATUS_SUCCESS; -+ } -+ -+ DBGLOG(OID, TRACE, "ScanEx\n"); -+ -+ /* clear old scan backup results if exists */ -+ { -+ P_SCAN_INFO_T prScanInfo; -+ P_LINK_T prBSSDescList; -+ P_BSS_DESC_T prBssDesc; -+ -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ prBSSDescList = &prScanInfo->rBSSDescList; -+ LINK_FOR_EACH_ENTRY(prBssDesc, prBSSDescList, rLinkEntry, BSS_DESC_T) { -+ if (prBssDesc->eBSSType == BSS_TYPE_INFRASTRUCTURE) { -+ kalMemZero(prBssDesc->aucRawBuf, CFG_RAW_BUFFER_SIZE); -+ prBssDesc->u2RawLength = 0; -+ } -+ } -+ } -+ -+ if (pvSetBuffer != NULL && u4SetBufferLen != 0) { -+ prScanRequest = (P_PARAM_SCAN_REQUEST_EXT_T) pvSetBuffer; -+ prSsid = &(prScanRequest->rSsid); -+ pucIe = prScanRequest->pucIE; -+ u4IeLength = prScanRequest->u4IELength; -+ } else { -+ prScanRequest = NULL; -+ prSsid = NULL; -+ pucIe = NULL; -+ u4IeLength = 0; -+ } -+ -+/* P_AIS_FSM_INFO_T prAisFsmInfo; */ -+ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); -+ -+/* #if CFG_SUPPORT_WFD */ -+#if 0 -+ if ((prAdapter->rWifiVar.prP2pFsmInfo->rWfdConfigureSettings.ucWfdEnable) && -+ ((prAdapter->rWifiVar.prP2pFsmInfo->rWfdConfigureSettings.u4WfdFlag & WFD_FLAGS_DEV_INFO_VALID))) { -+ -+ if (prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX].eConnectionState == -+ PARAM_MEDIA_STATE_CONNECTED) { -+ DBGLOG(OID, TRACE, "Twice the Scan Time for WFD\n"); -+ ucScanTime *= 2; -+ } -+ } -+#endif /* CFG_SUPPORT_WFD */ -+ cnmTimerStartTimer(prAdapter, &prAisFsmInfo->rScanDoneTimer, SEC_TO_MSEC(ucScanTime)); -+ -+#if CFG_SUPPORT_RDD_TEST_MODE -+ if (prAdapter->prGlueInfo->rRegInfo.u4RddTestMode) { -+ if ((prAdapter->fgEnOnlineScan == TRUE) && (prAdapter->ucRddStatus)) { -+ if (kalGetMediaStateIndicated(prAdapter->prGlueInfo) != PARAM_MEDIA_STATE_CONNECTED) { -+ aisFsmScanRequest(prAdapter, prSsid, pucIe, u4IeLength); -+ } else { -+ /* reject the scan request */ -+ cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rScanDoneTimer); -+ rStatus = WLAN_STATUS_FAILURE; -+ } -+ } else { -+ /* reject the scan request */ -+ cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rScanDoneTimer); -+ rStatus = WLAN_STATUS_FAILURE; -+ } -+ } else -+#endif -+ { -+ if (prAdapter->fgEnOnlineScan == TRUE) { -+ aisFsmScanRequest(prAdapter, prSsid, pucIe, u4IeLength); -+ } else if (kalGetMediaStateIndicated(prAdapter->prGlueInfo) != PARAM_MEDIA_STATE_CONNECTED) { -+ aisFsmScanRequest(prAdapter, prSsid, pucIe, u4IeLength); -+ } else { -+ /* reject the scan request */ -+ cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rScanDoneTimer); -+ rStatus = WLAN_STATUS_FAILURE; -+ DBGLOG(OID, WARN, "ScanEx fail %d!\n", prAdapter->fgEnOnlineScan); -+ } -+ } -+ -+ return rStatus; -+} /* wlanoidSetBssidListScanWithIE */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine will initiate the join procedure to attempt to associate -+* with the specified BSSID. -+* -+* \param[in] pvAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+* \retval WLAN_STATUS_INVALID_DATA -+* \retval WLAN_STATUS_ADAPTER_NOT_READY -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetBssid(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ P_GLUE_INFO_T prGlueInfo; -+ P_UINT_8 pAddr; -+ UINT_32 i; -+ INT_32 i4Idx = -1; -+ P_MSG_AIS_ABORT_T prAisAbortMsg; -+ UINT_8 ucReasonOfDisconnect; -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ *pu4SetInfoLen = MAC_ADDR_LEN; -+ if (u4SetBufferLen != MAC_ADDR_LEN) { -+ *pu4SetInfoLen = MAC_ADDR_LEN; -+ return WLAN_STATUS_INVALID_LENGTH; -+ } else if (prAdapter->rAcpiState == ACPI_STATE_D3) { -+ DBGLOG(OID, WARN, "Fail in set ssid! (Adapter not ready). ACPI=D%d, Radio=%d\n", -+ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); -+ return WLAN_STATUS_ADAPTER_NOT_READY; -+ } -+ -+ prGlueInfo = prAdapter->prGlueInfo; -+ pAddr = (P_UINT_8) pvSetBuffer; -+ -+ /* re-association check */ -+ if (kalGetMediaStateIndicated(prGlueInfo) == PARAM_MEDIA_STATE_CONNECTED) { -+ if (EQUAL_MAC_ADDR(prAdapter->rWlanInfo.rCurrBssId.arMacAddress, pAddr)) { -+ kalSetMediaStateIndicated(prGlueInfo, PARAM_MEDIA_STATE_TO_BE_INDICATED); -+ ucReasonOfDisconnect = DISCONNECT_REASON_CODE_REASSOCIATION; -+ } else { -+ DBGLOG(OID, TRACE, "DisByBssid\n"); -+ kalIndicateStatusAndComplete(prGlueInfo, WLAN_STATUS_MEDIA_DISCONNECT, NULL, 0); -+ ucReasonOfDisconnect = DISCONNECT_REASON_CODE_NEW_CONNECTION; -+ } -+ } else { -+ ucReasonOfDisconnect = DISCONNECT_REASON_CODE_NEW_CONNECTION; -+ } -+ -+ /* check if any scanned result matchs with the BSSID */ -+ for (i = 0; i < prAdapter->rWlanInfo.u4ScanResultNum; i++) { -+ if (EQUAL_MAC_ADDR(prAdapter->rWlanInfo.arScanResult[i].arMacAddress, pAddr)) { -+ i4Idx = (INT_32) i; -+ break; -+ } -+ } -+ -+ /* prepare message to AIS */ -+ if (prAdapter->rWifiVar.rConnSettings.eOPMode == NET_TYPE_IBSS -+ || prAdapter->rWifiVar.rConnSettings.eOPMode == NET_TYPE_DEDICATED_IBSS) { -+ /* IBSS *//* beacon period */ -+ prAdapter->rWifiVar.rConnSettings.u2BeaconPeriod = prAdapter->rWlanInfo.u2BeaconPeriod; -+ prAdapter->rWifiVar.rConnSettings.u2AtimWindow = prAdapter->rWlanInfo.u2AtimWindow; -+ } -+ -+ /* Set Connection Request Issued Flag */ -+ prAdapter->rWifiVar.rConnSettings.fgIsConnReqIssued = TRUE; -+ prAdapter->rWifiVar.rConnSettings.eConnectionPolicy = CONNECT_BY_BSSID; -+ -+ /* Send AIS Abort Message */ -+ prAisAbortMsg = (P_MSG_AIS_ABORT_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_AIS_ABORT_T)); -+ if (!prAisAbortMsg) { -+ ASSERT(0); -+ return WLAN_STATUS_FAILURE; -+ } -+ -+ prAisAbortMsg->rMsgHdr.eMsgId = MID_OID_AIS_FSM_JOIN_REQ; -+ prAisAbortMsg->ucReasonOfDisconnect = ucReasonOfDisconnect; -+ -+ /* Update the information to CONNECTION_SETTINGS_T */ -+ prAdapter->rWifiVar.rConnSettings.ucSSIDLen = 0; -+ prAdapter->rWifiVar.rConnSettings.aucSSID[0] = '\0'; -+ -+ COPY_MAC_ADDR(prAdapter->rWifiVar.rConnSettings.aucBSSID, pAddr); -+ -+ if (EQUAL_MAC_ADDR(prAdapter->rWlanInfo.rCurrBssId.arMacAddress, pAddr)) -+ prAisAbortMsg->fgDelayIndication = TRUE; -+ else -+ prAisAbortMsg->fgDelayIndication = FALSE; -+ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prAisAbortMsg, MSG_SEND_METHOD_BUF); -+ -+ DBGLOG(OID, INFO, "SetBssid\n"); -+ return WLAN_STATUS_SUCCESS; -+} /* end of wlanoidSetBssid() */ -+ -+WLAN_STATUS -+wlanoidSetConnect(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ P_GLUE_INFO_T prGlueInfo; -+ P_PARAM_CONNECT_T pParamConn; -+ P_CONNECTION_SETTINGS_T prConnSettings; -+ UINT_32 i; -+ /*INT_32 i4Idx = -1, i4MaxRSSI = INT_MIN;*/ -+ P_MSG_AIS_ABORT_T prAisAbortMsg; -+ BOOLEAN fgIsValidSsid = TRUE; -+ BOOLEAN fgEqualSsid = FALSE; -+ BOOLEAN fgEqualBssid = FALSE; -+ const UINT_8 aucZeroMacAddr[] = NULL_MAC_ADDR; -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ /* MSDN: -+ * Powering on the radio if the radio is powered off through a setting of OID_802_11_DISASSOCIATE -+ */ -+ if (prAdapter->fgIsRadioOff == TRUE) -+ prAdapter->fgIsRadioOff = FALSE; -+ -+ if (u4SetBufferLen != sizeof(PARAM_CONNECT_T)) -+ return WLAN_STATUS_INVALID_LENGTH; -+ else if (prAdapter->rAcpiState == ACPI_STATE_D3) { -+ DBGLOG(OID, WARN, "Fail in set ssid! (Adapter not ready). ACPI=D%d, Radio=%d\n", -+ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); -+ return WLAN_STATUS_ADAPTER_NOT_READY; -+ } -+ prAisAbortMsg = (P_MSG_AIS_ABORT_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_AIS_ABORT_T)); -+ if (!prAisAbortMsg) { -+ ASSERT(0); -+ return WLAN_STATUS_FAILURE; -+ } -+ prAisAbortMsg->rMsgHdr.eMsgId = MID_OID_AIS_FSM_JOIN_REQ; -+ -+ pParamConn = (P_PARAM_CONNECT_T) pvSetBuffer; -+ prConnSettings = &prAdapter->rWifiVar.rConnSettings; -+ -+ if (pParamConn->u4SsidLen > 32) { -+ cnmMemFree(prAdapter, prAisAbortMsg); -+ return WLAN_STATUS_INVALID_LENGTH; -+ } else if (!pParamConn->pucBssid && !pParamConn->pucSsid) { -+ cnmMemFree(prAdapter, prAisAbortMsg); -+ return WLAN_STATUS_INVALID_LENGTH; -+ } -+ -+ prGlueInfo = prAdapter->prGlueInfo; -+ kalMemZero(prConnSettings->aucSSID, sizeof(prConnSettings->aucSSID)); -+ kalMemZero(prConnSettings->aucBSSID, sizeof(prConnSettings->aucBSSID)); -+ prConnSettings->eConnectionPolicy = CONNECT_BY_SSID_ANY; -+ prConnSettings->fgIsConnByBssidIssued = FALSE; -+ -+ if (pParamConn->pucSsid) { -+ prConnSettings->eConnectionPolicy = CONNECT_BY_SSID_BEST_RSSI; -+ COPY_SSID(prConnSettings->aucSSID, -+ prConnSettings->ucSSIDLen, pParamConn->pucSsid, (UINT_8) pParamConn->u4SsidLen); -+ if (EQUAL_SSID(prAdapter->rWlanInfo.rCurrBssId.rSsid.aucSsid, -+ prAdapter->rWlanInfo.rCurrBssId.rSsid.u4SsidLen, -+ pParamConn->pucSsid, pParamConn->u4SsidLen)) -+ fgEqualSsid = TRUE; -+ } -+ if (pParamConn->pucBssid) { -+ if (!EQUAL_MAC_ADDR(aucZeroMacAddr, pParamConn->pucBssid) && IS_UCAST_MAC_ADDR(pParamConn->pucBssid)) { -+ prConnSettings->eConnectionPolicy = CONNECT_BY_BSSID; -+ prConnSettings->fgIsConnByBssidIssued = TRUE; -+ COPY_MAC_ADDR(prConnSettings->aucBSSID, pParamConn->pucBssid); -+ if (EQUAL_MAC_ADDR(prAdapter->rWlanInfo.rCurrBssId.arMacAddress, pParamConn->pucBssid)) -+ fgEqualBssid = TRUE; -+ } else -+ DBGLOG(OID, TRACE, "wrong bssid %pM to connect\n", pParamConn->pucBssid); -+ } else -+ DBGLOG(OID, TRACE, "No Bssid set\n"); -+ prConnSettings->u4FreqInKHz = pParamConn->u4CenterFreq; -+ -+ /* prepare for CMD_BUILD_CONNECTION & CMD_GET_CONNECTION_STATUS */ -+ /* re-association check */ -+ if (kalGetMediaStateIndicated(prGlueInfo) == PARAM_MEDIA_STATE_CONNECTED) { -+ if (fgEqualSsid) { -+ prAisAbortMsg->ucReasonOfDisconnect = DISCONNECT_REASON_CODE_ROAMING; -+ if (fgEqualBssid) { -+ kalSetMediaStateIndicated(prGlueInfo, PARAM_MEDIA_STATE_TO_BE_INDICATED); -+ prAisAbortMsg->ucReasonOfDisconnect = DISCONNECT_REASON_CODE_REASSOCIATION; -+ } -+ } else { -+ DBGLOG(OID, TRACE, "DisBySsid\n"); -+ kalIndicateStatusAndComplete(prGlueInfo, WLAN_STATUS_MEDIA_DISCONNECT, NULL, 0); -+ prAisAbortMsg->ucReasonOfDisconnect = DISCONNECT_REASON_CODE_NEW_CONNECTION; -+ } -+ } else -+ prAisAbortMsg->ucReasonOfDisconnect = DISCONNECT_REASON_CODE_NEW_CONNECTION; -+#if 0 -+ /* check if any scanned result matchs with the SSID */ -+ for (i = 0; i < prAdapter->rWlanInfo.u4ScanResultNum; i++) { -+ PUINT_8 aucSsid = prAdapter->rWlanInfo.arScanResult[i].rSsid.aucSsid; -+ UINT_8 ucSsidLength = (UINT_8) prAdapter->rWlanInfo.arScanResult[i].rSsid.u4SsidLen; -+ INT_32 i4RSSI = prAdapter->rWlanInfo.arScanResult[i].rRssi; -+ -+ if (EQUAL_SSID(aucSsid, ucSsidLength, pParamConn->pucSsid, pParamConn->u4SsidLen) && -+ i4RSSI >= i4MaxRSSI) { -+ i4Idx = (INT_32) i; -+ i4MaxRSSI = i4RSSI; -+ } -+ if (EQUAL_MAC_ADDR(prAdapter->rWlanInfo.arScanResult[i].arMacAddress, pAddr)) { -+ i4Idx = (INT_32) i; -+ break; -+ } -+ } -+#endif -+ /* prepare message to AIS */ -+ if (prConnSettings->eOPMode == NET_TYPE_IBSS || prConnSettings->eOPMode == NET_TYPE_DEDICATED_IBSS) { -+ /* IBSS *//* beacon period */ -+ prConnSettings->u2BeaconPeriod = prAdapter->rWlanInfo.u2BeaconPeriod; -+ prConnSettings->u2AtimWindow = prAdapter->rWlanInfo.u2AtimWindow; -+ } -+ -+ if (prAdapter->rWifiVar.fgSupportWZCDisassociation) { -+ if (pParamConn->u4SsidLen == ELEM_MAX_LEN_SSID) { -+ fgIsValidSsid = FALSE; -+ -+ for (i = 0; i < ELEM_MAX_LEN_SSID; i++) { -+ if (pParamConn->pucSsid) { -+ if (!((0 < pParamConn->pucSsid[i]) && (pParamConn->pucSsid[i] <= 0x1F))) { -+ fgIsValidSsid = TRUE; -+ break; -+ } -+ } -+ } -+ } -+ } -+ -+ /* Set Connection Request Issued Flag */ -+ if (fgIsValidSsid) -+ prConnSettings->fgIsConnReqIssued = TRUE; -+ else -+ prConnSettings->fgIsConnReqIssued = FALSE; -+ -+ if (fgEqualSsid || fgEqualBssid) -+ prAisAbortMsg->fgDelayIndication = TRUE; -+ else -+ /* Update the information to CONNECTION_SETTINGS_T */ -+ prAisAbortMsg->fgDelayIndication = FALSE; -+ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prAisAbortMsg, MSG_SEND_METHOD_BUF); -+ -+ DBGLOG(OID, INFO, "ssid %s, bssid %pM, conn policy %d, disc reason %d\n", -+ prConnSettings->aucSSID, prConnSettings->aucBSSID, -+ prConnSettings->eConnectionPolicy, prAisAbortMsg->ucReasonOfDisconnect); -+ return WLAN_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine will initiate the join procedure to attempt -+* to associate with the new SSID. If the previous scanning -+* result is aged, we will scan the channels at first. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer Pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_DATA -+* \retval WLAN_STATUS_ADAPTER_NOT_READY -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetSsid(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ P_GLUE_INFO_T prGlueInfo; -+ P_PARAM_SSID_T pParamSsid; -+ UINT_32 i; -+ INT_32 i4Idx = -1, i4MaxRSSI = INT_MIN; -+ P_MSG_AIS_ABORT_T prAisAbortMsg; -+ BOOLEAN fgIsValidSsid = TRUE; -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ /* MSDN: -+ * Powering on the radio if the radio is powered off through a setting of OID_802_11_DISASSOCIATE -+ */ -+ if (prAdapter->fgIsRadioOff == TRUE) -+ prAdapter->fgIsRadioOff = FALSE; -+ -+ if (u4SetBufferLen < sizeof(PARAM_SSID_T) || u4SetBufferLen > sizeof(PARAM_SSID_T)) { -+ return WLAN_STATUS_INVALID_LENGTH; -+ } else if (prAdapter->rAcpiState == ACPI_STATE_D3) { -+ DBGLOG(OID, WARN, "Fail in set ssid! (Adapter not ready). ACPI=D%d, Radio=%d\n", -+ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); -+ return WLAN_STATUS_ADAPTER_NOT_READY; -+ } -+ -+ pParamSsid = (P_PARAM_SSID_T) pvSetBuffer; -+ -+ if (pParamSsid->u4SsidLen > 32) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ prGlueInfo = prAdapter->prGlueInfo; -+ -+ /* prepare for CMD_BUILD_CONNECTION & CMD_GET_CONNECTION_STATUS */ -+ /* re-association check */ -+ if (kalGetMediaStateIndicated(prGlueInfo) == PARAM_MEDIA_STATE_CONNECTED) { -+ if (EQUAL_SSID(prAdapter->rWlanInfo.rCurrBssId.rSsid.aucSsid, -+ prAdapter->rWlanInfo.rCurrBssId.rSsid.u4SsidLen, -+ pParamSsid->aucSsid, pParamSsid->u4SsidLen)) { -+ kalSetMediaStateIndicated(prGlueInfo, PARAM_MEDIA_STATE_TO_BE_INDICATED); -+ } else { -+ DBGLOG(OID, TRACE, "DisBySsid\n"); -+ kalIndicateStatusAndComplete(prGlueInfo, WLAN_STATUS_MEDIA_DISCONNECT, NULL, 0); -+ } -+ } -+ /* check if any scanned result matchs with the SSID */ -+ for (i = 0; i < prAdapter->rWlanInfo.u4ScanResultNum; i++) { -+ PUINT_8 aucSsid = prAdapter->rWlanInfo.arScanResult[i].rSsid.aucSsid; -+ UINT_8 ucSsidLength = (UINT_8) prAdapter->rWlanInfo.arScanResult[i].rSsid.u4SsidLen; -+ INT_32 i4RSSI = prAdapter->rWlanInfo.arScanResult[i].rRssi; -+ -+ if (EQUAL_SSID(aucSsid, ucSsidLength, pParamSsid->aucSsid, pParamSsid->u4SsidLen) && -+ i4RSSI >= i4MaxRSSI) { -+ i4Idx = (INT_32) i; -+ i4MaxRSSI = i4RSSI; -+ } -+ } -+ -+ /* prepare message to AIS */ -+ if (prAdapter->rWifiVar.rConnSettings.eOPMode == NET_TYPE_IBSS -+ || prAdapter->rWifiVar.rConnSettings.eOPMode == NET_TYPE_DEDICATED_IBSS) { -+ /* IBSS *//* beacon period */ -+ prAdapter->rWifiVar.rConnSettings.u2BeaconPeriod = prAdapter->rWlanInfo.u2BeaconPeriod; -+ prAdapter->rWifiVar.rConnSettings.u2AtimWindow = prAdapter->rWlanInfo.u2AtimWindow; -+ } -+ -+ if (prAdapter->rWifiVar.fgSupportWZCDisassociation) { -+ if (pParamSsid->u4SsidLen == ELEM_MAX_LEN_SSID) { -+ fgIsValidSsid = FALSE; -+ -+ for (i = 0; i < ELEM_MAX_LEN_SSID; i++) { -+ if (!((0 < pParamSsid->aucSsid[i]) && (pParamSsid->aucSsid[i] <= 0x1F))) { -+ fgIsValidSsid = TRUE; -+ break; -+ } -+ } -+ } -+ } -+ -+ /* Set Connection Request Issued Flag */ -+ if (fgIsValidSsid) { -+ prAdapter->rWifiVar.rConnSettings.fgIsConnReqIssued = TRUE; -+ -+ if (pParamSsid->u4SsidLen) { -+ prAdapter->rWifiVar.rConnSettings.eConnectionPolicy = CONNECT_BY_SSID_BEST_RSSI; -+ } else { -+ /* wildcard SSID */ -+ prAdapter->rWifiVar.rConnSettings.eConnectionPolicy = CONNECT_BY_SSID_ANY; -+ } -+ } else { -+ prAdapter->rWifiVar.rConnSettings.fgIsConnReqIssued = FALSE; -+ } -+ -+ /* Send AIS Abort Message */ -+ prAisAbortMsg = (P_MSG_AIS_ABORT_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_AIS_ABORT_T)); -+ if (!prAisAbortMsg) { -+ ASSERT(0); -+ return WLAN_STATUS_FAILURE; -+ } -+ -+ prAisAbortMsg->rMsgHdr.eMsgId = MID_OID_AIS_FSM_JOIN_REQ; -+ prAisAbortMsg->ucReasonOfDisconnect = DISCONNECT_REASON_CODE_NEW_CONNECTION; -+ -+ COPY_SSID(prAdapter->rWifiVar.rConnSettings.aucSSID, -+ prAdapter->rWifiVar.rConnSettings.ucSSIDLen, pParamSsid->aucSsid, (UINT_8) pParamSsid->u4SsidLen); -+ -+ prAdapter->rWifiVar.rConnSettings.u4FreqInKHz = pParamSsid->u4CenterFreq; -+ if (EQUAL_SSID(prAdapter->rWlanInfo.rCurrBssId.rSsid.aucSsid, -+ prAdapter->rWlanInfo.rCurrBssId.rSsid.u4SsidLen, pParamSsid->aucSsid, pParamSsid->u4SsidLen)) { -+ prAisAbortMsg->fgDelayIndication = TRUE; -+ } else { -+ /* Update the information to CONNECTION_SETTINGS_T */ -+ prAisAbortMsg->fgDelayIndication = FALSE; -+ } -+ DBGLOG(SCN, INFO, "SSID %s\n", prAdapter->rWifiVar.rConnSettings.aucSSID); -+ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prAisAbortMsg, MSG_SEND_METHOD_BUF); -+ -+ return WLAN_STATUS_SUCCESS; -+ -+} /* end of wlanoidSetSsid() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to query the currently associated SSID. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvQueryBuffer Pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufferLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQuerySsid(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ P_PARAM_SSID_T prAssociatedSsid; -+ -+ DEBUGFUNC("wlanoidQuerySsid"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4QueryInfoLen); -+ -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ -+ *pu4QueryInfoLen = sizeof(PARAM_SSID_T); -+ -+ /* Check for query buffer length */ -+ if (u4QueryBufferLen < *pu4QueryInfoLen) { -+ DBGLOG(OID, WARN, "Invalid length %u\n", u4QueryBufferLen); -+ return WLAN_STATUS_INVALID_LENGTH; -+ } -+ -+ prAssociatedSsid = (P_PARAM_SSID_T) pvQueryBuffer; -+ -+ kalMemZero(prAssociatedSsid->aucSsid, sizeof(prAssociatedSsid->aucSsid)); -+ -+ if (kalGetMediaStateIndicated(prAdapter->prGlueInfo) == PARAM_MEDIA_STATE_CONNECTED) { -+ prAssociatedSsid->u4SsidLen = prAdapter->rWlanInfo.rCurrBssId.rSsid.u4SsidLen; -+ -+ if (prAssociatedSsid->u4SsidLen) { -+ kalMemCopy(prAssociatedSsid->aucSsid, -+ prAdapter->rWlanInfo.rCurrBssId.rSsid.aucSsid, prAssociatedSsid->u4SsidLen); -+ } -+ } else { -+ prAssociatedSsid->u4SsidLen = 0; -+ -+ DBGLOG(OID, TRACE, "Null SSID\n"); -+ } -+ -+ return WLAN_STATUS_SUCCESS; -+} /* wlanoidQuerySsid */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to query the current 802.11 network type. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvQueryBuffer Pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufferLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_BUFFER_TOO_SHORT -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryInfrastructureMode(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ DEBUGFUNC("wlanoidQueryInfrastructureMode"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4QueryInfoLen); -+ -+ *pu4QueryInfoLen = sizeof(ENUM_PARAM_OP_MODE_T); -+ -+ if (u4QueryBufferLen < sizeof(ENUM_PARAM_OP_MODE_T)) -+ return WLAN_STATUS_BUFFER_TOO_SHORT; -+ -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ -+ *(P_ENUM_PARAM_OP_MODE_T) pvQueryBuffer = prAdapter->rWifiVar.rConnSettings.eOPMode; -+ -+ /* -+ ** According to OID_802_11_INFRASTRUCTURE_MODE -+ ** If there is no prior OID_802_11_INFRASTRUCTURE_MODE, -+ ** NDIS_STATUS_ADAPTER_NOT_READY shall be returned. -+ */ -+#if DBG -+ switch (*(P_ENUM_PARAM_OP_MODE_T) pvQueryBuffer) { -+ case NET_TYPE_IBSS: -+ DBGLOG(OID, INFO, "IBSS mode\n"); -+ break; -+ case NET_TYPE_INFRA: -+ DBGLOG(OID, INFO, "Infrastructure mode\n"); -+ break; -+ default: -+ DBGLOG(OID, INFO, "Automatic mode\n"); -+ } -+#endif -+ -+ return WLAN_STATUS_SUCCESS; -+} /* wlanoidQueryInfrastructureMode */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to set mode to infrastructure or -+* IBSS, or automatic switch between the two. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer Pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed due to invalid -+* length of the set buffer, returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_DATA -+* \retval WLAN_STATUS_ADAPTER_NOT_READY -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetInfrastructureMode(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ P_GLUE_INFO_T prGlueInfo; -+ ENUM_PARAM_OP_MODE_T eOpMode; -+ -+ DEBUGFUNC("wlanoidSetInfrastructureMode"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pvSetBuffer); -+ ASSERT(pu4SetInfoLen); -+ -+ prGlueInfo = prAdapter->prGlueInfo; -+ -+ if (u4SetBufferLen < sizeof(ENUM_PARAM_OP_MODE_T)) -+ return WLAN_STATUS_BUFFER_TOO_SHORT; -+ -+ *pu4SetInfoLen = sizeof(ENUM_PARAM_OP_MODE_T); -+ -+ if (prAdapter->rAcpiState == ACPI_STATE_D3) { -+ DBGLOG(OID, WARN, "Fail in set infrastructure mode! (Adapter not ready). ACPI=D%d, Radio=%d\n", -+ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); -+ return WLAN_STATUS_ADAPTER_NOT_READY; -+ } -+ -+ eOpMode = *(P_ENUM_PARAM_OP_MODE_T) pvSetBuffer; -+ /* Verify the new infrastructure mode. */ -+ if (eOpMode >= NET_TYPE_NUM) { -+ DBGLOG(OID, TRACE, "Invalid mode value %d\n", eOpMode); -+ return WLAN_STATUS_INVALID_DATA; -+ } -+ -+ /* check if possible to switch to AdHoc mode */ -+ if (eOpMode == NET_TYPE_IBSS || eOpMode == NET_TYPE_DEDICATED_IBSS) { -+ if (cnmAisIbssIsPermitted(prAdapter) == FALSE) { -+ DBGLOG(OID, TRACE, "Mode value %d unallowed\n", eOpMode); -+ return WLAN_STATUS_FAILURE; -+ } -+ } -+ -+ /* Save the new infrastructure mode setting. */ -+ prAdapter->rWifiVar.rConnSettings.eOPMode = eOpMode; -+ -+ /* Clean up the Tx key flag */ -+ prAdapter->rWifiVar.rAisSpecificBssInfo.fgTransmitKeyExist = FALSE; -+ -+ prAdapter->rWifiVar.rConnSettings.fgWapiMode = FALSE; -+#if CFG_SUPPORT_WAPI -+ prAdapter->prGlueInfo->u2WapiAssocInfoIESz = 0; -+ kalMemZero(&prAdapter->prGlueInfo->aucWapiAssocInfoIEs, 42); -+#endif -+ -+#if CFG_SUPPORT_802_11W -+ prAdapter->rWifiVar.rAisSpecificBssInfo.fgMgmtProtection = FALSE; -+ prAdapter->rWifiVar.rAisSpecificBssInfo.fgBipKeyInstalled = FALSE; -+#endif -+ -+#if CFG_SUPPORT_WPS2 -+ kalMemZero(&prAdapter->prGlueInfo->aucWSCAssocInfoIE, 200); -+ prAdapter->prGlueInfo->u2WSCAssocInfoIELen = 0; -+#endif -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_INFRASTRUCTURE, -+ TRUE, -+ FALSE, -+ TRUE, -+ nicCmdEventSetCommon, nicOidCmdTimeoutCommon, 0, NULL, pvSetBuffer, u4SetBufferLen); -+ -+} /* wlanoidSetInfrastructureMode */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to query the current 802.11 authentication -+* mode. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[out] pvQueryBuffer A pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufferLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_BUFFER_TOO_SHORT -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryAuthMode(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ DEBUGFUNC("wlanoidQueryAuthMode"); -+ -+ ASSERT(prAdapter); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ ASSERT(pu4QueryInfoLen); -+ -+ *pu4QueryInfoLen = sizeof(ENUM_PARAM_AUTH_MODE_T); -+ -+ if (u4QueryBufferLen < sizeof(ENUM_PARAM_AUTH_MODE_T)) -+ return WLAN_STATUS_BUFFER_TOO_SHORT; -+ -+ *(P_ENUM_PARAM_AUTH_MODE_T) pvQueryBuffer = prAdapter->rWifiVar.rConnSettings.eAuthMode; -+ -+#if DBG -+ switch (*(P_ENUM_PARAM_AUTH_MODE_T) pvQueryBuffer) { -+ case AUTH_MODE_OPEN: -+ DBGLOG(OID, INFO, "Current auth mode: Open\n"); -+ break; -+ -+ case AUTH_MODE_SHARED: -+ DBGLOG(OID, INFO, "Current auth mode: Shared\n"); -+ break; -+ -+ case AUTH_MODE_AUTO_SWITCH: -+ DBGLOG(OID, INFO, "Current auth mode: Auto-switch\n"); -+ break; -+ -+ case AUTH_MODE_WPA: -+ DBGLOG(OID, INFO, "Current auth mode: WPA\n"); -+ break; -+ -+ case AUTH_MODE_WPA_PSK: -+ DBGLOG(OID, INFO, "Current auth mode: WPA PSK\n"); -+ break; -+ -+ case AUTH_MODE_WPA_NONE: -+ DBGLOG(OID, INFO, "Current auth mode: WPA None\n"); -+ break; -+ -+ case AUTH_MODE_WPA2: -+ DBGLOG(OID, INFO, "Current auth mode: WPA2\n"); -+ break; -+ -+ case AUTH_MODE_WPA2_PSK: -+ DBGLOG(OID, INFO, "Current auth mode: WPA2 PSK\n"); -+ break; -+ -+ default: -+ DBGLOG(OID, INFO, "Current auth mode: %d\n", *(P_ENUM_PARAM_AUTH_MODE_T) pvQueryBuffer); -+ break; -+ } -+#endif -+ return WLAN_STATUS_SUCCESS; -+} /* wlanoidQueryAuthMode */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to set the IEEE 802.11 authentication mode -+* to the driver. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_DATA -+* \retval WLAN_STATUS_INVALID_LENGTH -+* \retval WLAN_STATUS_ADAPTER_NOT_READY -+* \retval WLAN_STATUS_NOT_ACCEPTED -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetAuthMode(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ P_GLUE_INFO_T prGlueInfo; -+ UINT_32 i, u4AkmSuite; -+ P_DOT11_RSNA_CONFIG_AUTHENTICATION_SUITES_ENTRY prEntry; -+ -+ DEBUGFUNC("wlanoidSetAuthMode"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ ASSERT(pvSetBuffer); -+ -+ prGlueInfo = prAdapter->prGlueInfo; -+ -+ *pu4SetInfoLen = sizeof(ENUM_PARAM_AUTH_MODE_T); -+ -+ if (u4SetBufferLen < sizeof(ENUM_PARAM_AUTH_MODE_T)) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ /* RF Test */ -+ /* if (IS_ARB_IN_RFTEST_STATE(prAdapter)) { */ -+ /* return WLAN_STATUS_SUCCESS; */ -+ /* } */ -+ -+ if (prAdapter->rAcpiState == ACPI_STATE_D3) { -+ DBGLOG(OID, WARN, "Fail in set Authentication mode! (Adapter not ready). ACPI=D%d, Radio=%d\n", -+ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); -+ return WLAN_STATUS_ADAPTER_NOT_READY; -+ } -+ -+ /* Check if the new authentication mode is valid. */ -+ if (*(P_ENUM_PARAM_AUTH_MODE_T) pvSetBuffer >= AUTH_MODE_NUM) { -+ DBGLOG(OID, TRACE, "Invalid auth mode %d\n", *(P_ENUM_PARAM_AUTH_MODE_T) pvSetBuffer); -+ return WLAN_STATUS_INVALID_DATA; -+ } -+ -+ switch (*(P_ENUM_PARAM_AUTH_MODE_T) pvSetBuffer) { -+ case AUTH_MODE_WPA: -+ case AUTH_MODE_WPA_PSK: -+ case AUTH_MODE_WPA2: -+ case AUTH_MODE_WPA2_PSK: -+ /* infrastructure mode only */ -+ if (prAdapter->rWifiVar.rConnSettings.eOPMode != NET_TYPE_INFRA) -+ return WLAN_STATUS_NOT_ACCEPTED; -+ break; -+ -+ case AUTH_MODE_WPA_NONE: -+ /* ad hoc mode only */ -+ if (prAdapter->rWifiVar.rConnSettings.eOPMode != NET_TYPE_IBSS) -+ return WLAN_STATUS_NOT_ACCEPTED; -+ break; -+ -+ default: -+ break; -+ } -+ -+ /* Save the new authentication mode. */ -+ prAdapter->rWifiVar.rConnSettings.eAuthMode = *(P_ENUM_PARAM_AUTH_MODE_T) pvSetBuffer; -+ -+#if DBG -+ switch (prAdapter->rWifiVar.rConnSettings.eAuthMode) { -+ case AUTH_MODE_OPEN: -+ DBGLOG(RSN, TRACE, "New auth mode: open\n"); -+ break; -+ -+ case AUTH_MODE_SHARED: -+ DBGLOG(RSN, TRACE, "New auth mode: shared\n"); -+ break; -+ -+ case AUTH_MODE_AUTO_SWITCH: -+ DBGLOG(RSN, TRACE, "New auth mode: auto-switch\n"); -+ break; -+ -+ case AUTH_MODE_WPA: -+ DBGLOG(RSN, TRACE, "New auth mode: WPA\n"); -+ break; -+ -+ case AUTH_MODE_WPA_PSK: -+ DBGLOG(RSN, TRACE, "New auth mode: WPA PSK\n"); -+ break; -+ -+ case AUTH_MODE_WPA_NONE: -+ DBGLOG(RSN, TRACE, "New auth mode: WPA None\n"); -+ break; -+ -+ case AUTH_MODE_WPA2: -+ DBGLOG(RSN, TRACE, "New auth mode: WPA2\n"); -+ break; -+ -+ case AUTH_MODE_WPA2_PSK: -+ DBGLOG(RSN, TRACE, "New auth mode: WPA2 PSK\n"); -+ break; -+ -+ default: -+ DBGLOG(RSN, TRACE, "New auth mode: unknown (%d)\n", prAdapter->rWifiVar.rConnSettings.eAuthMode); -+ } -+#endif -+ -+ if (prAdapter->rWifiVar.rConnSettings.eAuthMode >= AUTH_MODE_WPA) { -+ switch (prAdapter->rWifiVar.rConnSettings.eAuthMode) { -+ case AUTH_MODE_WPA: -+ u4AkmSuite = WPA_AKM_SUITE_802_1X; -+ break; -+ -+ case AUTH_MODE_WPA_PSK: -+ u4AkmSuite = WPA_AKM_SUITE_PSK; -+ break; -+ -+ case AUTH_MODE_WPA_NONE: -+ u4AkmSuite = WPA_AKM_SUITE_NONE; -+ break; -+ -+ case AUTH_MODE_WPA2: -+ u4AkmSuite = RSN_AKM_SUITE_802_1X; -+ break; -+ -+ case AUTH_MODE_WPA2_PSK: -+ u4AkmSuite = RSN_AKM_SUITE_PSK; -+ break; -+ -+ default: -+ u4AkmSuite = 0; -+ } -+ } else { -+ u4AkmSuite = 0; -+ } -+ -+ /* Enable the specific AKM suite only. */ -+ for (i = 0; i < MAX_NUM_SUPPORTED_AKM_SUITES; i++) { -+ prEntry = &prAdapter->rMib.dot11RSNAConfigAuthenticationSuitesTable[i]; -+ -+ if (prEntry->dot11RSNAConfigAuthenticationSuite == u4AkmSuite) -+ prEntry->dot11RSNAConfigAuthenticationSuiteEnabled = TRUE; -+ else -+ prEntry->dot11RSNAConfigAuthenticationSuiteEnabled = FALSE; -+#if CFG_SUPPORT_802_11W -+ if (kalGetMfpSetting(prAdapter->prGlueInfo) != RSN_AUTH_MFP_DISABLED) { -+ if ((u4AkmSuite == RSN_AKM_SUITE_PSK) && -+ prEntry->dot11RSNAConfigAuthenticationSuite == RSN_AKM_SUITE_PSK_SHA256) { -+ DBGLOG(RSN, TRACE, "Enable RSN_AKM_SUITE_PSK_SHA256 AKM support\n"); -+ prEntry->dot11RSNAConfigAuthenticationSuiteEnabled = TRUE; -+ -+ } -+ if ((u4AkmSuite == RSN_AKM_SUITE_802_1X) && -+ prEntry->dot11RSNAConfigAuthenticationSuite == RSN_AKM_SUITE_802_1X_SHA256) { -+ DBGLOG(RSN, TRACE, "Enable RSN_AKM_SUITE_802_1X_SHA256 AKM support\n"); -+ prEntry->dot11RSNAConfigAuthenticationSuiteEnabled = TRUE; -+ } -+ } -+#endif -+ } -+ -+ return WLAN_STATUS_SUCCESS; -+ -+} /* wlanoidSetAuthMode */ -+ -+#if 0 -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to query the current 802.11 privacy filter -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[out] pvQueryBuffer A pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufferLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_BUFFER_TOO_SHORT -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryPrivacyFilter(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ DEBUGFUNC("wlanoidQueryPrivacyFilter"); -+ -+ ASSERT(prAdapter); -+ -+ ASSERT(pvQueryBuffer); -+ ASSERT(pu4QueryInfoLen); -+ -+ *pu4QueryInfoLen = sizeof(ENUM_PARAM_PRIVACY_FILTER_T); -+ -+ if (u4QueryBufferLen < sizeof(ENUM_PARAM_PRIVACY_FILTER_T)) -+ return WLAN_STATUS_BUFFER_TOO_SHORT; -+ -+ *(P_ENUM_PARAM_PRIVACY_FILTER_T) pvQueryBuffer = prAdapter->rWlanInfo.ePrivacyFilter; -+ -+#if DBG -+ switch (*(P_ENUM_PARAM_PRIVACY_FILTER_T) pvQueryBuffer) { -+ case PRIVACY_FILTER_ACCEPT_ALL: -+ DBGLOG(OID, INFO, "Current privacy mode: open mode\n"); -+ break; -+ -+ case PRIVACY_FILTER_8021xWEP: -+ DBGLOG(OID, INFO, "Current privacy mode: filtering mode\n"); -+ break; -+ -+ default: -+ DBGLOG(OID, INFO, "Current auth mode: %d\n", *(P_ENUM_PARAM_AUTH_MODE_T) pvQueryBuffer); -+ } -+#endif -+ return WLAN_STATUS_SUCCESS; -+} /* wlanoidQueryPrivacyFilter */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to set the IEEE 802.11 privacy filter -+* to the driver. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_DATA -+* \retval WLAN_STATUS_INVALID_LENGTH -+* \retval WLAN_STATUS_ADAPTER_NOT_READY -+* \retval WLAN_STATUS_NOT_ACCEPTED -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetPrivacyFilter(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ P_GLUE_INFO_T prGlueInfo; -+ -+ DEBUGFUNC("wlanoidSetPrivacyFilter"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ ASSERT(pvSetBuffer); -+ -+ prGlueInfo = prAdapter->prGlueInfo; -+ -+ *pu4SetInfoLen = sizeof(ENUM_PARAM_PRIVACY_FILTER_T); -+ -+ if (u4SetBufferLen < sizeof(ENUM_PARAM_PRIVACY_FILTER_T)) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ if (prAdapter->rAcpiState == ACPI_STATE_D3) { -+ DBGLOG(OID, WARN, "Fail in set Authentication mode! (Adapter not ready). ACPI=D%d, Radio=%d\n", -+ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); -+ return WLAN_STATUS_ADAPTER_NOT_READY; -+ } -+ -+ /* Check if the new authentication mode is valid. */ -+ if (*(P_ENUM_PARAM_PRIVACY_FILTER_T) pvSetBuffer >= PRIVACY_FILTER_NUM) { -+ DBGLOG(OID, TRACE, "Invalid privacy filter %d\n", *(P_ENUM_PARAM_PRIVACY_FILTER_T) pvSetBuffer); -+ return WLAN_STATUS_INVALID_DATA; -+ } -+ -+ switch (*(P_ENUM_PARAM_PRIVACY_FILTER_T) pvSetBuffer) { -+ default: -+ break; -+ } -+ -+ /* Save the new authentication mode. */ -+ prAdapter->rWlanInfo.ePrivacyFilter = *(ENUM_PARAM_PRIVACY_FILTER_T) pvSetBuffer; -+ -+ return WLAN_STATUS_SUCCESS; -+ -+} /* wlanoidSetPrivacyFilter */ -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to reload the available default settings for -+* the specified type field. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_ADAPTER_NOT_READY -+* \retval WLAN_STATUS_INVALID_DATA -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetReloadDefaults(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ ENUM_PARAM_NETWORK_TYPE_T eNetworkType; -+ UINT_32 u4Len; -+ UINT_8 ucCmdSeqNum; -+ -+ DEBUGFUNC("wlanoidSetReloadDefaults"); -+ -+ ASSERT(prAdapter); -+ -+ ASSERT(pu4SetInfoLen); -+ *pu4SetInfoLen = sizeof(PARAM_RELOAD_DEFAULTS); -+ -+ /* if (IS_ARB_IN_RFTEST_STATE(prAdapter)) { */ -+ /* return WLAN_STATUS_SUCCESS; */ -+ /* } */ -+ -+ if (prAdapter->rAcpiState == ACPI_STATE_D3) { -+ DBGLOG(OID, WARN, "Fail in set Reload default! (Adapter not ready). ACPI=D%d, Radio=%d\n", -+ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); -+ return WLAN_STATUS_ADAPTER_NOT_READY; -+ } -+ -+ ASSERT(pvSetBuffer); -+ /* Verify the available reload options and reload the settings. */ -+ switch (*(P_PARAM_RELOAD_DEFAULTS) pvSetBuffer) { -+ case ENUM_RELOAD_WEP_KEYS: -+ /* Reload available default WEP keys from the permanent -+ storage. */ -+ prAdapter->rWifiVar.rConnSettings.eAuthMode = AUTH_MODE_OPEN; -+ /* ENUM_ENCRYPTION_DISABLED; */ -+ prAdapter->rWifiVar.rConnSettings.eEncStatus = ENUM_ENCRYPTION1_KEY_ABSENT; -+ { -+ P_GLUE_INFO_T prGlueInfo; -+ P_CMD_INFO_T prCmdInfo; -+ P_WIFI_CMD_T prWifiCmd; -+ P_CMD_802_11_KEY prCmdKey; -+ UINT_8 aucBCAddr[] = BC_MAC_ADDR; -+ -+ prGlueInfo = prAdapter->prGlueInfo; -+ prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, (CMD_HDR_SIZE + sizeof(CMD_802_11_KEY))); -+ -+ if (!prCmdInfo) { -+ DBGLOG(OID, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); -+ return WLAN_STATUS_FAILURE; -+ } -+ /* increase command sequence number */ -+ ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter); -+ -+ /* compose CMD_802_11_KEY cmd pkt */ -+ prCmdInfo->eCmdType = COMMAND_TYPE_NETWORK_IOCTL; -+ prCmdInfo->eNetworkType = NETWORK_TYPE_AIS_INDEX; -+ prCmdInfo->u2InfoBufLen = CMD_HDR_SIZE + sizeof(CMD_802_11_KEY); -+ prCmdInfo->pfCmdDoneHandler = nicCmdEventSetCommon; -+ prCmdInfo->pfCmdTimeoutHandler = nicOidCmdTimeoutCommon; -+ prCmdInfo->fgIsOid = TRUE; -+ prCmdInfo->ucCID = CMD_ID_ADD_REMOVE_KEY; -+ prCmdInfo->fgSetQuery = TRUE; -+ prCmdInfo->fgNeedResp = FALSE; -+ prCmdInfo->fgDriverDomainMCR = FALSE; -+ prCmdInfo->ucCmdSeqNum = ucCmdSeqNum; -+ prCmdInfo->u4SetInfoLen = sizeof(PARAM_REMOVE_KEY_T); -+ prCmdInfo->pvInformationBuffer = pvSetBuffer; -+ prCmdInfo->u4InformationBufferLength = u4SetBufferLen; -+ -+ /* Setup WIFI_CMD_T */ -+ prWifiCmd = (P_WIFI_CMD_T) (prCmdInfo->pucInfoBuffer); -+ prWifiCmd->u2TxByteCount_UserPriority = prCmdInfo->u2InfoBufLen; -+ prWifiCmd->ucCID = prCmdInfo->ucCID; -+ prWifiCmd->ucSetQuery = prCmdInfo->fgSetQuery; -+ prWifiCmd->ucSeqNum = prCmdInfo->ucCmdSeqNum; -+ -+ prCmdKey = (P_CMD_802_11_KEY) (prWifiCmd->aucBuffer); -+ -+ kalMemZero((PUINT_8) prCmdKey, sizeof(CMD_802_11_KEY)); -+ -+ prCmdKey->ucAddRemove = 0; /* Remove */ -+ prCmdKey->ucKeyId = 0; /* (UINT_8)(prRemovedKey->u4KeyIndex & 0x000000ff); */ -+ kalMemCopy(prCmdKey->aucPeerAddr, aucBCAddr, MAC_ADDR_LEN); -+ -+ ASSERT(prCmdKey->ucKeyId < MAX_KEY_NUM); -+ -+ prCmdKey->ucKeyType = 0; -+ -+ /* insert into prCmdQueue */ -+ kalEnqueueCommand(prGlueInfo, (P_QUE_ENTRY_T) prCmdInfo); -+ -+ /* wakeup txServiceThread later */ -+ GLUE_SET_EVENT(prGlueInfo); -+ -+ return WLAN_STATUS_PENDING; -+ } -+ -+ break; -+ -+ default: -+ DBGLOG(OID, TRACE, "Invalid reload option %d\n", *(P_PARAM_RELOAD_DEFAULTS) pvSetBuffer); -+ rStatus = WLAN_STATUS_INVALID_DATA; -+ } -+ -+ /* OID_802_11_RELOAD_DEFAULTS requiest to reset to auto mode */ -+ eNetworkType = PARAM_NETWORK_TYPE_AUTOMODE; -+ wlanoidSetNetworkTypeInUse(prAdapter, &eNetworkType, sizeof(eNetworkType), &u4Len); -+ -+ return rStatus; -+} /* wlanoidSetReloadDefaults */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to set a WEP key to the driver. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+* \retval WLAN_STATUS_INVALID_DATA -+* \retval WLAN_STATUS_ADAPTER_NOT_READY -+* \retval WLAN_STATUS_BUFFER_TOO_SHORT -+*/ -+/*----------------------------------------------------------------------------*/ -+#ifdef LINUX -+UINT_8 keyBuffer[sizeof(PARAM_KEY_T) + 16 /* LEGACY_KEY_MAX_LEN */]; -+UINT_8 aucBCAddr[] = BC_MAC_ADDR; -+#endif -+WLAN_STATUS -+wlanoidSetAddWep(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+#ifndef LINUX -+ UINT_8 keyBuffer[sizeof(PARAM_KEY_T) + 16 /* LEGACY_KEY_MAX_LEN */]; -+ UINT_8 aucBCAddr[] = BC_MAC_ADDR; -+#endif -+ P_PARAM_WEP_T prNewWepKey; -+ P_PARAM_KEY_T prParamKey = (P_PARAM_KEY_T) keyBuffer; -+ UINT_32 u4KeyId, u4SetLen; -+ -+ DEBUGFUNC("wlanoidSetAddWep"); -+ -+ ASSERT(prAdapter); -+ -+ *pu4SetInfoLen = OFFSET_OF(PARAM_WEP_T, aucKeyMaterial); -+ -+ if (u4SetBufferLen < OFFSET_OF(PARAM_WEP_T, aucKeyMaterial)) { -+ ASSERT(pu4SetInfoLen); -+ return WLAN_STATUS_BUFFER_TOO_SHORT; -+ } -+ -+ ASSERT(pvSetBuffer); -+ ASSERT(pu4SetInfoLen); -+ -+ if (prAdapter->rAcpiState == ACPI_STATE_D3) { -+ DBGLOG(OID, WARN, "Fail in set add WEP! (Adapter not ready). ACPI=D%d, Radio=%d\n", -+ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); -+ return WLAN_STATUS_ADAPTER_NOT_READY; -+ } -+ -+ prNewWepKey = (P_PARAM_WEP_T) pvSetBuffer; -+ -+ /* Verify the total buffer for minimum length. */ -+ if (u4SetBufferLen < OFFSET_OF(PARAM_WEP_T, aucKeyMaterial) + prNewWepKey->u4KeyLength) { -+ DBGLOG(OID, WARN, "Invalid total buffer length (%d) than minimum length (%d)\n", -+ (UINT_8) u4SetBufferLen, (UINT_8) OFFSET_OF(PARAM_WEP_T, aucKeyMaterial)); -+ -+ *pu4SetInfoLen = OFFSET_OF(PARAM_WEP_T, aucKeyMaterial); -+ return WLAN_STATUS_INVALID_DATA; -+ } -+ -+ /* Verify the key structure length. */ -+ if (prNewWepKey->u4Length > u4SetBufferLen) { -+ DBGLOG(OID, WARN, "Invalid key structure length (%d) greater than total buffer length (%d)\n", -+ (UINT_8) prNewWepKey->u4Length, (UINT_8) u4SetBufferLen); -+ -+ *pu4SetInfoLen = u4SetBufferLen; -+ return WLAN_STATUS_INVALID_DATA; -+ } -+ -+ /* Verify the key material length for maximum key material length:16 */ -+ if (prNewWepKey->u4KeyLength > 16 /* LEGACY_KEY_MAX_LEN */) { -+ DBGLOG(OID, WARN, "Invalid key material length (%d) greater than maximum key material length (16)\n", -+ (UINT_8) prNewWepKey->u4KeyLength); -+ -+ *pu4SetInfoLen = u4SetBufferLen; -+ return WLAN_STATUS_INVALID_DATA; -+ } -+ -+ *pu4SetInfoLen = u4SetBufferLen; -+ -+ u4KeyId = prNewWepKey->u4KeyIndex & BITS(0, 29) /* WEP_KEY_ID_FIELD */; -+ -+ /* Verify whether key index is valid or not, current version -+ driver support only 4 global WEP keys setting by this OID */ -+ if (u4KeyId > MAX_KEY_NUM - 1) { -+ DBGLOG(OID, ERROR, "Error, invalid WEP key ID: %d\n", (UINT_8) u4KeyId); -+ return WLAN_STATUS_INVALID_DATA; -+ } -+ -+ prParamKey->u4KeyIndex = u4KeyId; -+ -+ /* Transmit key */ -+ if (prNewWepKey->u4KeyIndex & IS_TRANSMIT_KEY) -+ prParamKey->u4KeyIndex |= IS_TRANSMIT_KEY; -+ -+ /* Per client key */ -+ if (prNewWepKey->u4KeyIndex & IS_UNICAST_KEY) -+ prParamKey->u4KeyIndex |= IS_UNICAST_KEY; -+ -+ prParamKey->u4KeyLength = prNewWepKey->u4KeyLength; -+ -+ kalMemCopy(prParamKey->arBSSID, aucBCAddr, MAC_ADDR_LEN); -+ -+ kalMemCopy(prParamKey->aucKeyMaterial, prNewWepKey->aucKeyMaterial, prNewWepKey->u4KeyLength); -+ -+ prParamKey->u4Length = OFFSET_OF(PARAM_KEY_T, aucKeyMaterial) + prNewWepKey->u4KeyLength; -+ -+ wlanoidSetAddKey(prAdapter, (PVOID) prParamKey, prParamKey->u4Length, &u4SetLen); -+ -+ return WLAN_STATUS_PENDING; -+} /* wlanoidSetAddWep */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to request the driver to remove the WEP key -+* at the specified key index. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_DATA -+* \retval WLAN_STATUS_INVALID_LENGTH -+* \retval WLAN_STATUS_ADAPTER_NOT_READY -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetRemoveWep(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ UINT_32 u4KeyId, u4SetLen; -+ PARAM_REMOVE_KEY_T rRemoveKey; -+ UINT_8 aucBCAddr[] = BC_MAC_ADDR; -+ -+ DEBUGFUNC("wlanoidSetRemoveWep"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ *pu4SetInfoLen = sizeof(PARAM_KEY_INDEX); -+ -+ if (u4SetBufferLen < sizeof(PARAM_KEY_INDEX)) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ ASSERT(pvSetBuffer); -+ u4KeyId = *(PUINT_32) pvSetBuffer; -+ -+ /* Dump PARAM_WEP content. */ -+ DBGLOG(OID, INFO, "Set: Dump PARAM_KEY_INDEX content\n"); -+ DBGLOG(OID, INFO, "Index : 0x%08x\n", u4KeyId); -+ -+ if (prAdapter->rAcpiState == ACPI_STATE_D3) { -+ DBGLOG(OID, WARN, "Fail in set remove WEP! (Adapter not ready). ACPI=D%d, Radio=%d\n", -+ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); -+ return WLAN_STATUS_ADAPTER_NOT_READY; -+ } -+ -+ if (u4KeyId & IS_TRANSMIT_KEY) { -+ /* Bit 31 should not be set */ -+ DBGLOG(OID, ERROR, "Invalid WEP key index: 0x%08x\n", u4KeyId); -+ return WLAN_STATUS_INVALID_DATA; -+ } -+ -+ u4KeyId &= BITS(0, 7); -+ -+ /* Verify whether key index is valid or not. Current version -+ driver support only 4 global WEP keys. */ -+ if (u4KeyId > MAX_KEY_NUM - 1) { -+ DBGLOG(OID, ERROR, "invalid WEP key ID %u\n", u4KeyId); -+ return WLAN_STATUS_INVALID_DATA; -+ } -+ -+ rRemoveKey.u4Length = sizeof(PARAM_REMOVE_KEY_T); -+ rRemoveKey.u4KeyIndex = *(PUINT_32) pvSetBuffer; -+ -+ kalMemCopy(rRemoveKey.arBSSID, aucBCAddr, MAC_ADDR_LEN); -+ -+ wlanoidSetRemoveKey(prAdapter, (PVOID)&rRemoveKey, sizeof(PARAM_REMOVE_KEY_T), &u4SetLen); -+ -+ return WLAN_STATUS_PENDING; -+} /* wlanoidSetRemoveWep */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to set a key to the driver. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_ADAPTER_NOT_READY -+* \retval WLAN_STATUS_INVALID_LENGTH -+* \retval WLAN_STATUS_INVALID_DATA -+* -+* \note The setting buffer PARAM_KEY_T, which is set by NDIS, is unpacked. -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+_wlanoidSetAddKey(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, -+ IN UINT_32 u4SetBufferLen, IN BOOLEAN fgIsOid, IN UINT_8 ucAlgorithmId, OUT PUINT_32 pu4SetInfoLen) -+{ -+ P_GLUE_INFO_T prGlueInfo; -+ P_CMD_INFO_T prCmdInfo; -+ P_WIFI_CMD_T prWifiCmd; -+ P_PARAM_KEY_T prNewKey; -+ P_CMD_802_11_KEY prCmdKey; -+ UINT_8 ucCmdSeqNum; -+ -+#if 0 -+ DEBUGFUNC("wlanoidSetAddKey"); -+ DBGLOG(OID, LOUD, "\n"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pvSetBuffer); -+ ASSERT(pu4SetInfoLen); -+ -+ if (prAdapter->rAcpiState == ACPI_STATE_D3) { -+ DBGLOG(OID, WARN, "Fail in set add key! (Adapter not ready). ACPI=D%d, Radio=%d\n", -+ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); -+ return WLAN_STATUS_ADAPTER_NOT_READY; -+ } -+#endif -+ -+ prNewKey = (P_PARAM_KEY_T) pvSetBuffer; -+ -+#if 0 -+ /* Verify the key structure length. */ -+ if (prNewKey->u4Length > u4SetBufferLen) { -+ DBGLOG(OID, WARN, "Invalid key structure length (%d) greater than total buffer length (%d)\n", -+ (UINT_8) prNewKey->u4Length, (UINT_8) u4SetBufferLen); -+ -+ *pu4SetInfoLen = u4SetBufferLen; -+ return WLAN_STATUS_INVALID_LENGTH; -+ } -+ -+ /* Verify the key material length for key material buffer */ -+ if (prNewKey->u4KeyLength > prNewKey->u4Length - OFFSET_OF(PARAM_KEY_T, aucKeyMaterial)) { -+ DBGLOG(OID, WARN, "Invalid key material length (%d)\n", (UINT_8) prNewKey->u4KeyLength); -+ *pu4SetInfoLen = u4SetBufferLen; -+ return WLAN_STATUS_INVALID_DATA; -+ } -+ -+ /* Exception check */ -+ if (prNewKey->u4KeyIndex & 0x0fffff00) -+ return WLAN_STATUS_INVALID_DATA; -+ -+ /* Exception check, pairwise key must with transmit bit enabled */ -+ if ((prNewKey->u4KeyIndex & BITS(30, 31)) == IS_UNICAST_KEY) -+ return WLAN_STATUS_INVALID_DATA; -+ -+ if (!(prNewKey->u4KeyLength == WEP_40_LEN || prNewKey->u4KeyLength == WEP_104_LEN || -+ prNewKey->u4KeyLength == CCMP_KEY_LEN || prNewKey->u4KeyLength == TKIP_KEY_LEN)) { -+ return WLAN_STATUS_INVALID_DATA; -+ } -+ -+ /* Exception check, pairwise key must with transmit bit enabled */ -+ if ((prNewKey->u4KeyIndex & BITS(30, 31)) == BITS(30, 31)) { -+ if (((prNewKey->u4KeyIndex & 0xff) != 0) || -+ ((prNewKey->arBSSID[0] == 0xff) && (prNewKey->arBSSID[1] == 0xff) && (prNewKey->arBSSID[2] == 0xff) -+ && (prNewKey->arBSSID[3] == 0xff) && (prNewKey->arBSSID[4] == 0xff) -+ && (prNewKey->arBSSID[5] == 0xff))) { -+ return WLAN_STATUS_INVALID_DATA; -+ } -+ } -+ -+ *pu4SetInfoLen = u4SetBufferLen; -+#endif -+ -+ /* Dump PARAM_KEY content. */ -+ DBGLOG(OID, TRACE, "Set: PARAM_KEY Length: 0x%08x, Key Index: 0x%08x, Key Length: 0x%08x\n", -+ prNewKey->u4Length, prNewKey->u4KeyIndex, prNewKey->u4KeyLength); -+ DBGLOG(OID, TRACE, "BSSID:\n"); -+ DBGLOG_MEM8(OID, TRACE, prNewKey->arBSSID, sizeof(PARAM_MAC_ADDRESS)); -+ DBGLOG(OID, TRACE, "Key RSC:\n"); -+ DBGLOG_MEM8(OID, TRACE, &prNewKey->rKeyRSC, sizeof(PARAM_KEY_RSC)); -+ DBGLOG(OID, TRACE, "Key Material:\n"); -+ DBGLOG_MEM8(OID, TRACE, prNewKey->aucKeyMaterial, prNewKey->u4KeyLength); -+ -+ if (prAdapter->rWifiVar.rConnSettings.eAuthMode < AUTH_MODE_WPA) { -+ /* Todo:: Store the legacy wep key for OID_802_11_RELOAD_DEFAULTS */ -+ /* Todo:: Nothing */ -+ } -+ -+ if (prNewKey->u4KeyIndex & IS_TRANSMIT_KEY) -+ prAdapter->rWifiVar.rAisSpecificBssInfo.fgTransmitKeyExist = TRUE; -+ -+ prGlueInfo = prAdapter->prGlueInfo; -+ prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, (CMD_HDR_SIZE + sizeof(CMD_802_11_KEY))); -+ -+ if (!prCmdInfo) { -+ DBGLOG(OID, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); -+ return WLAN_STATUS_FAILURE; -+ } -+ /* increase command sequence number */ -+ ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter); -+ DBGLOG(OID, TRACE, "ucCmdSeqNum = %d\n", ucCmdSeqNum); -+ -+ /* compose CMD_802_11_KEY cmd pkt */ -+ prCmdInfo->eCmdType = COMMAND_TYPE_NETWORK_IOCTL; -+ prCmdInfo->eNetworkType = NETWORK_TYPE_AIS_INDEX; -+ prCmdInfo->u2InfoBufLen = CMD_HDR_SIZE + sizeof(CMD_802_11_KEY); -+ prCmdInfo->pfCmdDoneHandler = nicCmdEventSetCommon; -+ prCmdInfo->pfCmdTimeoutHandler = nicOidCmdTimeoutCommon; -+ prCmdInfo->fgIsOid = fgIsOid; -+ prCmdInfo->ucCID = CMD_ID_ADD_REMOVE_KEY; -+ prCmdInfo->fgSetQuery = TRUE; -+ prCmdInfo->fgNeedResp = FALSE; -+ prCmdInfo->fgDriverDomainMCR = FALSE; -+ prCmdInfo->ucCmdSeqNum = ucCmdSeqNum; -+ prCmdInfo->u4SetInfoLen = u4SetBufferLen; -+ prCmdInfo->pvInformationBuffer = pvSetBuffer; -+ prCmdInfo->u4InformationBufferLength = u4SetBufferLen; -+ -+ /* Setup WIFI_CMD_T */ -+ prWifiCmd = (P_WIFI_CMD_T) (prCmdInfo->pucInfoBuffer); -+ prWifiCmd->u2TxByteCount_UserPriority = prCmdInfo->u2InfoBufLen; -+ prWifiCmd->ucCID = prCmdInfo->ucCID; -+ prWifiCmd->ucSetQuery = prCmdInfo->fgSetQuery; -+ prWifiCmd->ucSeqNum = prCmdInfo->ucCmdSeqNum; -+ -+ prCmdKey = (P_CMD_802_11_KEY) (prWifiCmd->aucBuffer); -+ -+ kalMemZero(prCmdKey, sizeof(CMD_802_11_KEY)); -+ -+ prCmdKey->ucAddRemove = 1; /* Add */ -+ -+ prCmdKey->ucTxKey = ((prNewKey->u4KeyIndex & IS_TRANSMIT_KEY) == IS_TRANSMIT_KEY) ? 1 : 0; -+ prCmdKey->ucKeyType = ((prNewKey->u4KeyIndex & IS_UNICAST_KEY) == IS_UNICAST_KEY) ? 1 : 0; -+ prCmdKey->ucIsAuthenticator = ((prNewKey->u4KeyIndex & IS_AUTHENTICATOR) == IS_AUTHENTICATOR) ? 1 : 0; -+ -+ kalMemCopy(prCmdKey->aucPeerAddr, (PUINT_8) prNewKey->arBSSID, MAC_ADDR_LEN); -+ -+ prCmdKey->ucNetType = 0; /* AIS */ -+ -+ prCmdKey->ucKeyId = (UINT_8) (prNewKey->u4KeyIndex & 0xff); -+ -+ /* Note: adjust the key length for WPA-None */ -+ prCmdKey->ucKeyLen = (UINT_8) prNewKey->u4KeyLength; -+ -+ kalMemCopy(prCmdKey->aucKeyMaterial, (PUINT_8) prNewKey->aucKeyMaterial, prCmdKey->ucKeyLen); -+ -+ if (prNewKey->u4KeyLength == 5) { -+ prCmdKey->ucAlgorithmId = CIPHER_SUITE_WEP40; -+ } else if (prNewKey->u4KeyLength == 13) { -+ prCmdKey->ucAlgorithmId = CIPHER_SUITE_WEP104; -+ } else if (prNewKey->u4KeyLength == 16) { -+ if ((ucAlgorithmId != CIPHER_SUITE_CCMP) && -+ (prAdapter->rWifiVar.rConnSettings.eAuthMode < AUTH_MODE_WPA)) -+ prCmdKey->ucAlgorithmId = CIPHER_SUITE_WEP128; -+ else { -+#if CFG_SUPPORT_802_11W -+ if (prCmdKey->ucKeyId >= 4) { -+ prCmdKey->ucAlgorithmId = CIPHER_SUITE_BIP; -+ P_AIS_SPECIFIC_BSS_INFO_T prAisSpecBssInfo; -+ -+ prAisSpecBssInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo; -+ prAisSpecBssInfo->fgBipKeyInstalled = TRUE; -+ } else -+#endif -+ prCmdKey->ucAlgorithmId = CIPHER_SUITE_CCMP; -+ if (rsnCheckPmkidCandicate(prAdapter)) { -+ P_AIS_SPECIFIC_BSS_INFO_T prAisSpecBssInfo; -+ -+ prAisSpecBssInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo; -+ DBGLOG(RSN, TRACE, -+ "Add key: Prepare a timer to indicate candidate PMKID Candidate\n"); -+ cnmTimerStopTimer(prAdapter, &prAisSpecBssInfo->rPreauthenticationTimer); -+ cnmTimerStartTimer(prAdapter, &prAisSpecBssInfo->rPreauthenticationTimer, -+ SEC_TO_MSEC(WAIT_TIME_IND_PMKID_CANDICATE_SEC)); -+ } -+ } -+ } else if (prNewKey->u4KeyLength == 32) { -+ if (prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA_NONE) { -+ if (prAdapter->rWifiVar.rConnSettings.eEncStatus == ENUM_ENCRYPTION2_ENABLED) -+ prCmdKey->ucAlgorithmId = CIPHER_SUITE_TKIP; -+ else if (prAdapter->rWifiVar.rConnSettings.eEncStatus == ENUM_ENCRYPTION3_ENABLED) { -+ prCmdKey->ucAlgorithmId = CIPHER_SUITE_CCMP; -+ prCmdKey->ucKeyLen = CCMP_KEY_LEN; -+ } -+ } else -+ prCmdKey->ucAlgorithmId = CIPHER_SUITE_TKIP; -+ } -+ -+ DBGLOG(RSN, TRACE, "prCmdKey->ucAlgorithmId=%d, key len=%d\n", -+ prCmdKey->ucAlgorithmId, (UINT32) prNewKey->u4KeyLength); -+ -+ /* insert into prCmdQueue */ -+ kalEnqueueCommand(prGlueInfo, (P_QUE_ENTRY_T) prCmdInfo); -+ -+ /* wakeup txServiceThread later */ -+ GLUE_SET_EVENT(prGlueInfo); -+ -+ return WLAN_STATUS_PENDING; -+} -+ -+WLAN_STATUS -+wlanoidSetAddKey(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ P_PARAM_KEY_T prNewKey; -+ -+ DEBUGFUNC("wlanoidSetAddKey"); -+ DBGLOG(OID, LOUD, "\n"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pvSetBuffer); -+ ASSERT(pu4SetInfoLen); -+ -+ if (prAdapter->rAcpiState == ACPI_STATE_D3) { -+ DBGLOG(OID, WARN, "Fail in set add key! (Adapter not ready). ACPI=D%d, Radio=%d\n", -+ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); -+ return WLAN_STATUS_ADAPTER_NOT_READY; -+ } -+ -+ prNewKey = (P_PARAM_KEY_T) pvSetBuffer; -+ -+ /* Verify the key structure length. */ -+ if (prNewKey->u4Length > u4SetBufferLen) { -+ DBGLOG(OID, WARN, "Invalid key structure length (%d) greater than total buffer length (%d)\n", -+ (UINT_8) prNewKey->u4Length, (UINT_8) u4SetBufferLen); -+ -+ *pu4SetInfoLen = u4SetBufferLen; -+ return WLAN_STATUS_INVALID_LENGTH; -+ } -+ -+ /* Verify the key material length for key material buffer */ -+ if (prNewKey->u4KeyLength > prNewKey->u4Length - OFFSET_OF(PARAM_KEY_T, aucKeyMaterial)) { -+ DBGLOG(OID, WARN, "Invalid key material length (%d)\n", (UINT_8) prNewKey->u4KeyLength); -+ *pu4SetInfoLen = u4SetBufferLen; -+ return WLAN_STATUS_INVALID_DATA; -+ } -+ -+ /* Exception check */ -+ if (prNewKey->u4KeyIndex & 0x0fffff00) -+ return WLAN_STATUS_INVALID_DATA; -+ -+ /* Exception check, pairwise key must with transmit bit enabled */ -+ if ((prNewKey->u4KeyIndex & BITS(30, 31)) == BITS(30, 31)) { -+ if (((prNewKey->u4KeyLength == CCMP_KEY_LEN || prNewKey->u4KeyLength == TKIP_KEY_LEN) && -+ (prNewKey->u4KeyIndex & 0xff) != 0) || -+ EQUAL_MAC_ADDR(prNewKey->arBSSID, "\xff\xff\xff\xff\xff\xff")) { -+ return WLAN_STATUS_INVALID_DATA; -+ } -+ } else if ((prNewKey->u4KeyIndex & BITS(30, 31)) == IS_UNICAST_KEY) -+ return WLAN_STATUS_INVALID_DATA; -+ -+ if (!(prNewKey->u4KeyLength == WEP_40_LEN || prNewKey->u4KeyLength == WEP_104_LEN || -+ prNewKey->u4KeyLength == CCMP_KEY_LEN || prNewKey->u4KeyLength == TKIP_KEY_LEN)) { -+ return WLAN_STATUS_INVALID_DATA; -+ } -+ -+ *pu4SetInfoLen = u4SetBufferLen; -+ -+#if (CFG_SUPPORT_TDLS == 1) -+ /* -+ supplicant will set key before updating station & enabling the link so we need to -+ backup the key information and set key when link is enabled -+ */ -+ if (TdlsexKeyHandle(prAdapter, prNewKey) == TDLS_STATUS_SUCCESS) -+ return WLAN_STATUS_SUCCESS; -+#endif /* CFG_SUPPORT_TDLS */ -+ -+ return _wlanoidSetAddKey(prAdapter, pvSetBuffer, u4SetBufferLen, TRUE, CIPHER_SUITE_NONE, pu4SetInfoLen); -+} /* wlanoidSetAddKey */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to request the driver to remove the key at -+* the specified key index. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_DATA -+* \retval WLAN_STATUS_INVALID_LENGTH -+* \retval WLAN_STATUS_ADAPTER_NOT_READY -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetRemoveKey(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ P_GLUE_INFO_T prGlueInfo; -+ P_CMD_INFO_T prCmdInfo; -+ P_WIFI_CMD_T prWifiCmd; -+ P_PARAM_REMOVE_KEY_T prRemovedKey; -+ P_CMD_802_11_KEY prCmdKey; -+ UINT_8 ucCmdSeqNum; -+ -+ DEBUGFUNC("wlanoidSetRemoveKey"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ *pu4SetInfoLen = sizeof(PARAM_REMOVE_KEY_T); -+ -+ if (u4SetBufferLen < sizeof(PARAM_REMOVE_KEY_T)) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ if (prAdapter->rAcpiState == ACPI_STATE_D3) { -+ DBGLOG(OID, WARN, "Fail in set remove key! (Adapter not ready). ACPI=D%d, Radio=%d\n", -+ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); -+ return WLAN_STATUS_ADAPTER_NOT_READY; -+ } -+ -+ ASSERT(pvSetBuffer); -+ prRemovedKey = (P_PARAM_REMOVE_KEY_T) pvSetBuffer; -+ -+ /* Dump PARAM_REMOVE_KEY content. */ -+ DBGLOG(OID, TRACE, "Set: Dump PARAM_REMOVE_KEY content\n"); -+ DBGLOG(OID, TRACE, "Length : 0x%08x\n", prRemovedKey->u4Length); -+ DBGLOG(OID, TRACE, "Key Index : 0x%08x\n", prRemovedKey->u4KeyIndex); -+ DBGLOG(OID, TRACE, "BSSID:\n"); -+ DBGLOG_MEM8(OID, TRACE, prRemovedKey->arBSSID, MAC_ADDR_LEN); -+ -+ /* Check bit 31: this bit should always 0 */ -+ if (prRemovedKey->u4KeyIndex & IS_TRANSMIT_KEY) { -+ /* Bit 31 should not be set */ -+ DBGLOG(OID, ERROR, "invalid key index: 0x%08x\n", prRemovedKey->u4KeyIndex); -+ return WLAN_STATUS_INVALID_DATA; -+ } -+ -+ /* Check bits 8 ~ 29 should always be 0 */ -+ if (prRemovedKey->u4KeyIndex & BITS(8, 29)) { -+ /* Bit 31 should not be set */ -+ DBGLOG(OID, ERROR, "invalid key index: 0x%08x\n", prRemovedKey->u4KeyIndex); -+ return WLAN_STATUS_INVALID_DATA; -+ } -+ -+ /* Clean up the Tx key flag */ -+ if (prRemovedKey->u4KeyIndex & IS_UNICAST_KEY) -+ prAdapter->rWifiVar.rAisSpecificBssInfo.fgTransmitKeyExist = FALSE; -+ -+ prGlueInfo = prAdapter->prGlueInfo; -+ prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, (CMD_HDR_SIZE + sizeof(CMD_802_11_KEY))); -+ -+ if (!prCmdInfo) { -+ DBGLOG(OID, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); -+ return WLAN_STATUS_FAILURE; -+ } -+ /* increase command sequence number */ -+ ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter); -+ -+ /* compose CMD_802_11_KEY cmd pkt */ -+ prCmdInfo->eCmdType = COMMAND_TYPE_NETWORK_IOCTL; -+ prCmdInfo->eNetworkType = NETWORK_TYPE_AIS_INDEX; -+ prCmdInfo->u2InfoBufLen = CMD_HDR_SIZE + sizeof(CMD_802_11_KEY); -+ prCmdInfo->pfCmdDoneHandler = nicCmdEventSetCommon; -+ prCmdInfo->pfCmdTimeoutHandler = nicOidCmdTimeoutCommon; -+ prCmdInfo->fgIsOid = TRUE; -+ prCmdInfo->ucCID = CMD_ID_ADD_REMOVE_KEY; -+ prCmdInfo->fgSetQuery = TRUE; -+ prCmdInfo->fgNeedResp = FALSE; -+ prCmdInfo->fgDriverDomainMCR = FALSE; -+ prCmdInfo->ucCmdSeqNum = ucCmdSeqNum; -+ prCmdInfo->u4SetInfoLen = sizeof(PARAM_REMOVE_KEY_T); -+ prCmdInfo->pvInformationBuffer = pvSetBuffer; -+ prCmdInfo->u4InformationBufferLength = u4SetBufferLen; -+ -+ /* Setup WIFI_CMD_T */ -+ prWifiCmd = (P_WIFI_CMD_T) (prCmdInfo->pucInfoBuffer); -+ prWifiCmd->u2TxByteCount_UserPriority = prCmdInfo->u2InfoBufLen; -+ prWifiCmd->ucCID = prCmdInfo->ucCID; -+ prWifiCmd->ucSetQuery = prCmdInfo->fgSetQuery; -+ prWifiCmd->ucSeqNum = prCmdInfo->ucCmdSeqNum; -+ -+ prCmdKey = (P_CMD_802_11_KEY) (prWifiCmd->aucBuffer); -+ -+ kalMemZero((PUINT_8) prCmdKey, sizeof(CMD_802_11_KEY)); -+ -+ prCmdKey->ucAddRemove = 0; /* Remove */ -+ prCmdKey->ucKeyId = (UINT_8) (prRemovedKey->u4KeyIndex & 0x000000ff); -+ kalMemCopy(prCmdKey->aucPeerAddr, (PUINT_8) prRemovedKey->arBSSID, MAC_ADDR_LEN); -+ -+#if CFG_SUPPORT_802_11W -+ ASSERT(prCmdKey->ucKeyId < MAX_KEY_NUM + 2); -+#else -+ /* ASSERT(prCmdKey->ucKeyId < MAX_KEY_NUM); */ -+#endif -+ -+ if (prRemovedKey->u4KeyIndex & IS_UNICAST_KEY) -+ prCmdKey->ucKeyType = 1; -+ /* insert into prCmdQueue */ -+ kalEnqueueCommand(prGlueInfo, (P_QUE_ENTRY_T) prCmdInfo); -+ -+ /* wakeup txServiceThread later */ -+ GLUE_SET_EVENT(prGlueInfo); -+ -+ return WLAN_STATUS_PENDING; -+} /* wlanoidSetRemoveKey */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to query the current encryption status. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[out] pvQueryBuffer A pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufferLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryEncryptionStatus(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ BOOLEAN fgTransmitKeyAvailable = TRUE; -+ ENUM_PARAM_ENCRYPTION_STATUS_T eEncStatus = 0; -+ -+ DEBUGFUNC("wlanoidQueryEncryptionStatus"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4QueryInfoLen); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ -+ *pu4QueryInfoLen = sizeof(ENUM_PARAM_ENCRYPTION_STATUS_T); -+ -+ fgTransmitKeyAvailable = prAdapter->rWifiVar.rAisSpecificBssInfo.fgTransmitKeyExist; -+ -+ switch (prAdapter->rWifiVar.rConnSettings.eEncStatus) { -+ case ENUM_ENCRYPTION3_ENABLED: -+ if (fgTransmitKeyAvailable) -+ eEncStatus = ENUM_ENCRYPTION3_ENABLED; -+ else -+ eEncStatus = ENUM_ENCRYPTION3_KEY_ABSENT; -+ break; -+ -+ case ENUM_ENCRYPTION2_ENABLED: -+ if (fgTransmitKeyAvailable) { -+ eEncStatus = ENUM_ENCRYPTION2_ENABLED; -+ break; -+ } -+ eEncStatus = ENUM_ENCRYPTION2_KEY_ABSENT; -+ break; -+ -+ case ENUM_ENCRYPTION1_ENABLED: -+ if (fgTransmitKeyAvailable) -+ eEncStatus = ENUM_ENCRYPTION1_ENABLED; -+ else -+ eEncStatus = ENUM_ENCRYPTION1_KEY_ABSENT; -+ break; -+ -+ case ENUM_ENCRYPTION_DISABLED: -+ eEncStatus = ENUM_ENCRYPTION_DISABLED; -+ break; -+ -+ default: -+ DBGLOG(OID, ERROR, "Unknown Encryption Status Setting:%d\n", -+ prAdapter->rWifiVar.rConnSettings.eEncStatus); -+ } -+ -+#if DBG -+ DBGLOG(OID, INFO, -+ "Encryption status: %d Return:%d\n", prAdapter->rWifiVar.rConnSettings.eEncStatus, eEncStatus); -+#endif -+ -+ *(P_ENUM_PARAM_ENCRYPTION_STATUS_T) pvQueryBuffer = eEncStatus; -+ -+ return WLAN_STATUS_SUCCESS; -+} /* wlanoidQueryEncryptionStatus */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to set the encryption status to the driver. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_ADAPTER_NOT_READY -+* \retval WLAN_STATUS_NOT_SUPPORTED -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetEncryptionStatus(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ P_GLUE_INFO_T prGlueInfo; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ ENUM_PARAM_ENCRYPTION_STATUS_T eEewEncrypt; -+ -+ DEBUGFUNC("wlanoidSetEncryptionStatus"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pvSetBuffer); -+ ASSERT(pu4SetInfoLen); -+ -+ prGlueInfo = prAdapter->prGlueInfo; -+ -+ *pu4SetInfoLen = sizeof(ENUM_PARAM_ENCRYPTION_STATUS_T); -+ -+ /* if (IS_ARB_IN_RFTEST_STATE(prAdapter)) { */ -+ /* return WLAN_STATUS_SUCCESS; */ -+ /* } */ -+ -+ if (prAdapter->rAcpiState == ACPI_STATE_D3) { -+ DBGLOG(OID, WARN, "Fail in set encryption status! (Adapter not ready). ACPI=D%d, Radio=%d\n", -+ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); -+ return WLAN_STATUS_ADAPTER_NOT_READY; -+ } -+ -+ eEewEncrypt = *(P_ENUM_PARAM_ENCRYPTION_STATUS_T) pvSetBuffer; -+ DBGLOG(OID, TRACE, "ENCRYPTION_STATUS %d\n", eEewEncrypt); -+ -+ switch (eEewEncrypt) { -+ case ENUM_ENCRYPTION_DISABLED: /* Disable WEP, TKIP, AES */ -+ DBGLOG(RSN, TRACE, "Disable Encryption\n"); -+ secSetCipherSuite(prAdapter, CIPHER_FLAG_WEP40 | CIPHER_FLAG_WEP104 | CIPHER_FLAG_WEP128); -+ break; -+ -+ case ENUM_ENCRYPTION1_ENABLED: /* Enable WEP. Disable TKIP, AES */ -+ DBGLOG(RSN, TRACE, "Enable Encryption1\n"); -+ secSetCipherSuite(prAdapter, CIPHER_FLAG_WEP40 | CIPHER_FLAG_WEP104 | CIPHER_FLAG_WEP128); -+ break; -+ -+ case ENUM_ENCRYPTION2_ENABLED: /* Enable WEP, TKIP. Disable AES */ -+ secSetCipherSuite(prAdapter, -+ CIPHER_FLAG_WEP40 | CIPHER_FLAG_WEP104 | CIPHER_FLAG_WEP128 | CIPHER_FLAG_TKIP); -+ DBGLOG(RSN, TRACE, "Enable Encryption2\n"); -+ break; -+ -+ case ENUM_ENCRYPTION3_ENABLED: /* Enable WEP, TKIP, AES */ -+ secSetCipherSuite(prAdapter, -+ CIPHER_FLAG_WEP40 | -+ CIPHER_FLAG_WEP104 | CIPHER_FLAG_WEP128 | CIPHER_FLAG_TKIP | CIPHER_FLAG_CCMP); -+ DBGLOG(RSN, TRACE, "Enable Encryption3\n"); -+ break; -+ -+ default: -+ DBGLOG(RSN, WARN, "Unacceptible encryption status: %d\n", -+ *(P_ENUM_PARAM_ENCRYPTION_STATUS_T) pvSetBuffer); -+ -+ rStatus = WLAN_STATUS_NOT_SUPPORTED; -+ } -+ -+ if (rStatus == WLAN_STATUS_SUCCESS) { -+ /* Save the new encryption status. */ -+ prAdapter->rWifiVar.rConnSettings.eEncStatus = *(P_ENUM_PARAM_ENCRYPTION_STATUS_T) pvSetBuffer; -+ -+ DBGLOG(RSN, TRACE, "wlanoidSetEncryptionStatus to %d\n", -+ prAdapter->rWifiVar.rConnSettings.eEncStatus); -+ } -+ -+ return rStatus; -+} /* wlanoidSetEncryptionStatus */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to test the driver. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+* \retval WLAN_STATUS_INVALID_DATA -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetTest(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ P_PARAM_802_11_TEST_T prTest; -+ PVOID pvTestData; -+ PVOID pvStatusBuffer; -+ UINT_32 u4StatusBufferSize; -+ -+ DEBUGFUNC("wlanoidSetTest"); -+ -+ ASSERT(prAdapter); -+ -+ ASSERT(pu4SetInfoLen); -+ ASSERT(pvSetBuffer); -+ -+ *pu4SetInfoLen = u4SetBufferLen; -+ -+ prTest = (P_PARAM_802_11_TEST_T) pvSetBuffer; -+ -+ DBGLOG(OID, TRACE, "Test - Type %u\n", prTest->u4Type); -+ -+ switch (prTest->u4Type) { -+ case 1: /* Type 1: generate an authentication event */ -+ pvTestData = (PVOID) &prTest->u.AuthenticationEvent; -+ pvStatusBuffer = (PVOID) prAdapter->aucIndicationEventBuffer; -+ u4StatusBufferSize = prTest->u4Length - 8; -+ if (u4StatusBufferSize > sizeof(PARAM_AUTH_EVENT_T)) { -+ DBGLOG(OID, TRACE, "prTest->u4Length error %u\n", u4StatusBufferSize); -+ ASSERT(FALSE); -+ } -+ break; -+ -+ case 2: /* Type 2: generate an RSSI status indication */ -+ pvTestData = (PVOID) &prTest->u.RssiTrigger; -+ pvStatusBuffer = (PVOID) &prAdapter->rWlanInfo.rCurrBssId.rRssi; -+ u4StatusBufferSize = sizeof(PARAM_RSSI); -+ break; -+ -+ default: -+ return WLAN_STATUS_INVALID_DATA; -+ } -+ -+ ASSERT(u4StatusBufferSize <= 180); -+ if (u4StatusBufferSize > 180) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ /* Get the contents of the StatusBuffer from the test structure. */ -+ kalMemCopy(pvStatusBuffer, pvTestData, u4StatusBufferSize); -+ -+ kalIndicateStatusAndComplete(prAdapter->prGlueInfo, -+ WLAN_STATUS_MEDIA_SPECIFIC_INDICATION, pvStatusBuffer, u4StatusBufferSize); -+ -+ return WLAN_STATUS_SUCCESS; -+} /* wlanoidSetTest */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to query the driver's WPA2 status. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[out] pvQueryBuffer A pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufferLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryCapability(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ P_PARAM_CAPABILITY_T prCap; -+ P_PARAM_AUTH_ENCRYPTION_T prAuthenticationEncryptionSupported; -+ -+ DEBUGFUNC("wlanoidQueryCapability"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4QueryInfoLen); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ -+ *pu4QueryInfoLen = 4 * sizeof(UINT_32) + 14 * sizeof(PARAM_AUTH_ENCRYPTION_T); -+ -+ if (u4QueryBufferLen < *pu4QueryInfoLen) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ prCap = (P_PARAM_CAPABILITY_T) pvQueryBuffer; -+ -+ prCap->u4Length = *pu4QueryInfoLen; -+ prCap->u4Version = 2; /* WPA2 */ -+ prCap->u4NoOfPMKIDs = CFG_MAX_PMKID_CACHE; -+ prCap->u4NoOfAuthEncryptPairsSupported = 14; -+ -+ prAuthenticationEncryptionSupported = &prCap->arAuthenticationEncryptionSupported[0]; -+ -+ /* fill 14 entries of supported settings */ -+ prAuthenticationEncryptionSupported[0].eAuthModeSupported = AUTH_MODE_OPEN; -+ -+ prAuthenticationEncryptionSupported[0].eEncryptStatusSupported = ENUM_ENCRYPTION_DISABLED; -+ -+ prAuthenticationEncryptionSupported[1].eAuthModeSupported = AUTH_MODE_OPEN; -+ prAuthenticationEncryptionSupported[1].eEncryptStatusSupported = ENUM_ENCRYPTION1_ENABLED; -+ -+ prAuthenticationEncryptionSupported[2].eAuthModeSupported = AUTH_MODE_SHARED; -+ prAuthenticationEncryptionSupported[2].eEncryptStatusSupported = ENUM_ENCRYPTION_DISABLED; -+ -+ prAuthenticationEncryptionSupported[3].eAuthModeSupported = AUTH_MODE_SHARED; -+ prAuthenticationEncryptionSupported[3].eEncryptStatusSupported = ENUM_ENCRYPTION1_ENABLED; -+ -+ prAuthenticationEncryptionSupported[4].eAuthModeSupported = AUTH_MODE_WPA; -+ prAuthenticationEncryptionSupported[4].eEncryptStatusSupported = ENUM_ENCRYPTION2_ENABLED; -+ -+ prAuthenticationEncryptionSupported[5].eAuthModeSupported = AUTH_MODE_WPA; -+ prAuthenticationEncryptionSupported[5].eEncryptStatusSupported = ENUM_ENCRYPTION3_ENABLED; -+ -+ prAuthenticationEncryptionSupported[6].eAuthModeSupported = AUTH_MODE_WPA_PSK; -+ prAuthenticationEncryptionSupported[6].eEncryptStatusSupported = ENUM_ENCRYPTION2_ENABLED; -+ -+ prAuthenticationEncryptionSupported[7].eAuthModeSupported = AUTH_MODE_WPA_PSK; -+ prAuthenticationEncryptionSupported[7].eEncryptStatusSupported = ENUM_ENCRYPTION3_ENABLED; -+ -+ prAuthenticationEncryptionSupported[8].eAuthModeSupported = AUTH_MODE_WPA_NONE; -+ prAuthenticationEncryptionSupported[8].eEncryptStatusSupported = ENUM_ENCRYPTION2_ENABLED; -+ -+ prAuthenticationEncryptionSupported[9].eAuthModeSupported = AUTH_MODE_WPA_NONE; -+ prAuthenticationEncryptionSupported[9].eEncryptStatusSupported = ENUM_ENCRYPTION3_ENABLED; -+ -+ prAuthenticationEncryptionSupported[10].eAuthModeSupported = AUTH_MODE_WPA2; -+ prAuthenticationEncryptionSupported[10].eEncryptStatusSupported = ENUM_ENCRYPTION2_ENABLED; -+ -+ prAuthenticationEncryptionSupported[11].eAuthModeSupported = AUTH_MODE_WPA2; -+ prAuthenticationEncryptionSupported[11].eEncryptStatusSupported = ENUM_ENCRYPTION3_ENABLED; -+ -+ prAuthenticationEncryptionSupported[12].eAuthModeSupported = AUTH_MODE_WPA2_PSK; -+ prAuthenticationEncryptionSupported[12].eEncryptStatusSupported = ENUM_ENCRYPTION2_ENABLED; -+ -+ prAuthenticationEncryptionSupported[13].eAuthModeSupported = AUTH_MODE_WPA2_PSK; -+ prAuthenticationEncryptionSupported[13].eEncryptStatusSupported = ENUM_ENCRYPTION3_ENABLED; -+ -+ return WLAN_STATUS_SUCCESS; -+ -+} /* wlanoidQueryCapability */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to query the PMKID in the PMK cache. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[out] pvQueryBuffer A pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufferLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryPmkid(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ UINT_32 i; -+ P_PARAM_PMKID_T prPmkid; -+ P_AIS_SPECIFIC_BSS_INFO_T prAisSpecBssInfo; -+ -+ DEBUGFUNC("wlanoidQueryPmkid"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4QueryInfoLen); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ -+ prAisSpecBssInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo; -+ -+ *pu4QueryInfoLen = OFFSET_OF(PARAM_PMKID_T, arBSSIDInfo) + -+ prAisSpecBssInfo->u4PmkidCacheCount * sizeof(PARAM_BSSID_INFO_T); -+ -+ if (u4QueryBufferLen < *pu4QueryInfoLen) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ prPmkid = (P_PARAM_PMKID_T) pvQueryBuffer; -+ -+ prPmkid->u4Length = *pu4QueryInfoLen; -+ prPmkid->u4BSSIDInfoCount = prAisSpecBssInfo->u4PmkidCacheCount; -+ -+ for (i = 0; i < prAisSpecBssInfo->u4PmkidCacheCount; i++) { -+ kalMemCopy(prPmkid->arBSSIDInfo[i].arBSSID, -+ prAisSpecBssInfo->arPmkidCache[i].rBssidInfo.arBSSID, sizeof(PARAM_MAC_ADDRESS)); -+ kalMemCopy(prPmkid->arBSSIDInfo[i].arPMKID, -+ prAisSpecBssInfo->arPmkidCache[i].rBssidInfo.arPMKID, sizeof(PARAM_PMKID_VALUE)); -+ } -+ -+ return WLAN_STATUS_SUCCESS; -+ -+} /* wlanoidQueryPmkid */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to set the PMKID to the PMK cache in the driver. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_BUFFER_TOO_SHORT -+* \retval WLAN_STATUS_INVALID_DATA -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetPmkid(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ UINT_32 i, j; -+ P_PARAM_PMKID_T prPmkid; -+ P_AIS_SPECIFIC_BSS_INFO_T prAisSpecBssInfo; -+ -+ DEBUGFUNC("wlanoidSetPmkid"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ *pu4SetInfoLen = u4SetBufferLen; -+ -+ /* It's possibble BSSIDInfoCount is zero, because OS wishes to clean PMKID */ -+ if (u4SetBufferLen < OFFSET_OF(PARAM_PMKID_T, arBSSIDInfo)) -+ return WLAN_STATUS_BUFFER_TOO_SHORT; -+ -+ ASSERT(pvSetBuffer); -+ prPmkid = (P_PARAM_PMKID_T) pvSetBuffer; -+ -+ if (u4SetBufferLen < -+ ((prPmkid->u4BSSIDInfoCount * sizeof(PARAM_BSSID_INFO_T)) + OFFSET_OF(PARAM_PMKID_T, arBSSIDInfo))) -+ return WLAN_STATUS_INVALID_DATA; -+ -+ if (prPmkid->u4BSSIDInfoCount > CFG_MAX_PMKID_CACHE) -+ return WLAN_STATUS_INVALID_DATA; -+ -+ DBGLOG(OID, TRACE, "Count %u\n", prPmkid->u4BSSIDInfoCount); -+ -+ prAisSpecBssInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo; -+ -+ /* This OID replace everything in the PMKID cache. */ -+ if (prPmkid->u4BSSIDInfoCount == 0) { -+ prAisSpecBssInfo->u4PmkidCacheCount = 0; -+ kalMemZero(prAisSpecBssInfo->arPmkidCache, sizeof(PMKID_ENTRY_T) * CFG_MAX_PMKID_CACHE); -+ } -+ if ((prAisSpecBssInfo->u4PmkidCacheCount + prPmkid->u4BSSIDInfoCount > CFG_MAX_PMKID_CACHE)) { -+ prAisSpecBssInfo->u4PmkidCacheCount = 0; -+ kalMemZero(prAisSpecBssInfo->arPmkidCache, sizeof(PMKID_ENTRY_T) * CFG_MAX_PMKID_CACHE); -+ } -+ -+ /* -+ The driver can only clear its PMKID cache whenever it make a media disconnect -+ indication. Otherwise, it must change the PMKID cache only when set through this OID. -+ */ -+#if CFG_RSN_MIGRATION -+ for (i = 0; i < prPmkid->u4BSSIDInfoCount; i++) { -+ /* Search for desired BSSID. If desired BSSID is found, -+ then set the PMKID */ -+ if (!rsnSearchPmkidEntry(prAdapter, (PUINT_8) prPmkid->arBSSIDInfo[i].arBSSID, &j)) { -+ /* No entry found for the specified BSSID, so add one entry */ -+ if (prAisSpecBssInfo->u4PmkidCacheCount < CFG_MAX_PMKID_CACHE - 1) { -+ j = prAisSpecBssInfo->u4PmkidCacheCount; -+ kalMemCopy(prAisSpecBssInfo->arPmkidCache[j].rBssidInfo.arBSSID, -+ prPmkid->arBSSIDInfo[i].arBSSID, sizeof(PARAM_MAC_ADDRESS)); -+ prAisSpecBssInfo->u4PmkidCacheCount++; -+ } else { -+ j = CFG_MAX_PMKID_CACHE; -+ } -+ } -+ -+ if (j < CFG_MAX_PMKID_CACHE) { -+ kalMemCopy(prAisSpecBssInfo->arPmkidCache[j].rBssidInfo.arPMKID, -+ prPmkid->arBSSIDInfo[i].arPMKID, sizeof(PARAM_PMKID_VALUE)); -+ DBGLOG(RSN, TRACE, "Add BSSID %pM idx=%d PMKID value %pM\n", -+ (prAisSpecBssInfo->arPmkidCache[j].rBssidInfo.arBSSID), (UINT_32) j, -+ (prAisSpecBssInfo->arPmkidCache[j].rBssidInfo.arPMKID)); -+ prAisSpecBssInfo->arPmkidCache[j].fgPmkidExist = TRUE; -+ } -+ } -+#endif -+ return WLAN_STATUS_SUCCESS; -+ -+} /* wlanoidSetPmkid */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to query the set of supported data rates that -+* the radio is capable of running -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* \param[out] pvQueryBuffer A pointer to the buffer that holds the result of -+* the query -+* \param[in] u4QueryBufferLen The length of the query buffer -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number -+* of bytes written into the query buffer. If the -+* call failed due to invalid length of the query -+* buffer, returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQuerySupportedRates(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ PARAM_RATES eRate = { -+ /* BSSBasicRateSet for 802.11n Non-HT rates */ -+ 0x8C, /* 6M */ -+ 0x92, /* 9M */ -+ 0x98, /* 12M */ -+ 0xA4, /* 18M */ -+ 0xB0, /* 24M */ -+ 0xC8, /* 36M */ -+ 0xE0, /* 48M */ -+ 0xEC /* 54M */ -+ }; -+ -+ DEBUGFUNC("wlanoidQuerySupportedRates"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4QueryInfoLen); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ -+ *pu4QueryInfoLen = sizeof(PARAM_RATES_EX); -+ -+ if (u4QueryBufferLen < *pu4QueryInfoLen) { -+ DBGLOG(OID, WARN, "Invalid length %u\n", u4QueryBufferLen); -+ return WLAN_STATUS_INVALID_LENGTH; -+ } -+ -+ kalMemCopy(pvQueryBuffer, (PVOID) &eRate, sizeof(PARAM_RATES)); -+ -+ return WLAN_STATUS_SUCCESS; -+} /* end of wlanoidQuerySupportedRates() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to query current desired rates. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvQueryBuffer Pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufferLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryDesiredRates(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ DEBUGFUNC("wlanoidQueryDesiredRates"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4QueryInfoLen); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ -+ *pu4QueryInfoLen = sizeof(PARAM_RATES_EX); -+ -+ if (u4QueryBufferLen < *pu4QueryInfoLen) { -+ DBGLOG(OID, WARN, "Invalid length %u\n", u4QueryBufferLen); -+ return WLAN_STATUS_INVALID_LENGTH; -+ } -+ -+ kalMemCopy(pvQueryBuffer, (PVOID) &(prAdapter->rWlanInfo.eDesiredRates), sizeof(PARAM_RATES)); -+ -+ return WLAN_STATUS_SUCCESS; -+ -+} /* end of wlanoidQueryDesiredRates() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to Set the desired rates. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer Pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+* \retval WLAN_STATUS_INVALID_DATA -+* \retval WLAN_STATUS_ADAPTER_NOT_READY -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetDesiredRates(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ UINT_32 i; -+ -+ DEBUGFUNC("wlanoidSetDesiredRates"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pvSetBuffer); -+ ASSERT(pu4SetInfoLen); -+ -+ if (u4SetBufferLen < sizeof(PARAM_RATES)) { -+ DBGLOG(OID, WARN, "Invalid length %u\n", u4SetBufferLen); -+ return WLAN_STATUS_INVALID_LENGTH; -+ } -+ -+ *pu4SetInfoLen = sizeof(PARAM_RATES); -+ -+ if (u4SetBufferLen < sizeof(PARAM_RATES)) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ kalMemCopy((PVOID) &(prAdapter->rWlanInfo.eDesiredRates), pvSetBuffer, sizeof(PARAM_RATES)); -+ -+ prAdapter->rWlanInfo.eLinkAttr.ucDesiredRateLen = PARAM_MAX_LEN_RATES; -+ for (i = 0; i < PARAM_MAX_LEN_RATES; i++) -+ prAdapter->rWlanInfo.eLinkAttr.u2DesiredRate[i] = (UINT_16) (prAdapter->rWlanInfo.eDesiredRates[i]); -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_LINK_ATTRIB, -+ TRUE, -+ FALSE, -+ TRUE, -+ nicCmdEventSetCommon, -+ nicOidCmdTimeoutCommon, -+ sizeof(CMD_LINK_ATTRIB), -+ (PUINT_8) &(prAdapter->rWlanInfo.eLinkAttr), pvSetBuffer, u4SetBufferLen); -+ -+} /* end of wlanoidSetDesiredRates() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to query the maximum frame size in bytes, -+* not including the header. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[out] pvQueryBuffer A pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufferLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the -+* call failed due to invalid length of the query -+* buffer, returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryMaxFrameSize(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ DEBUGFUNC("wlanoidQueryMaxFrameSize"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4QueryInfoLen); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ -+ if (u4QueryBufferLen < sizeof(UINT_32)) { -+ *pu4QueryInfoLen = sizeof(UINT_32); -+ return WLAN_STATUS_INVALID_LENGTH; -+ } -+ -+ *(PUINT_32) pvQueryBuffer = ETHERNET_MAX_PKT_SZ - ETHERNET_HEADER_SZ; -+ *pu4QueryInfoLen = sizeof(UINT_32); -+ -+ return WLAN_STATUS_SUCCESS; -+} /* wlanoidQueryMaxFrameSize */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to query the maximum total packet length -+* in bytes. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[out] pvQueryBuffer A pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufferLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryMaxTotalSize(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ DEBUGFUNC("wlanoidQueryMaxTotalSize"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4QueryInfoLen); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ -+ if (u4QueryBufferLen < sizeof(UINT_32)) { -+ *pu4QueryInfoLen = sizeof(UINT_32); -+ return WLAN_STATUS_INVALID_LENGTH; -+ } -+ -+ *(PUINT_32) pvQueryBuffer = ETHERNET_MAX_PKT_SZ; -+ *pu4QueryInfoLen = sizeof(UINT_32); -+ -+ return WLAN_STATUS_SUCCESS; -+} /* wlanoidQueryMaxTotalSize */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to query the vendor ID of the NIC. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[out] pvQueryBuffer A pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufferLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryVendorId(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+#if DBG -+ PUINT_8 cp; -+#endif -+ DEBUGFUNC("wlanoidQueryVendorId"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4QueryInfoLen); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ -+ if (u4QueryBufferLen < sizeof(UINT_32)) { -+ *pu4QueryInfoLen = sizeof(UINT_32); -+ return WLAN_STATUS_INVALID_LENGTH; -+ } -+ -+ kalMemCopy(pvQueryBuffer, prAdapter->aucMacAddress, 3); -+ *((PUINT_8) pvQueryBuffer + 3) = 1; -+ *pu4QueryInfoLen = sizeof(UINT_32); -+ -+#if DBG -+ cp = (PUINT_8) pvQueryBuffer; -+ DBGLOG(OID, LOUD, "Vendor ID=%02x-%02x-%02x-%02x\n", cp[0], cp[1], cp[2], cp[3]); -+#endif -+ -+ return WLAN_STATUS_SUCCESS; -+} /* wlanoidQueryVendorId */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to query the current RSSI value. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvQueryBuffer Pointer to the buffer that holds the result of the query. -+* \param[in] u4QueryBufferLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call failed due to invalid length of -+* the query buffer, returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_BUFFER_TOO_SHORT -+* \retval WLAN_STATUS_ADAPTER_NOT_READY -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryRssi(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ DEBUGFUNC("wlanoidQueryRssi"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4QueryInfoLen); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ -+ *pu4QueryInfoLen = sizeof(PARAM_RSSI); -+ -+ /* Check for query buffer length */ -+ if (u4QueryBufferLen < *pu4QueryInfoLen) { -+ DBGLOG(OID, WARN, "Too short length %u\n", u4QueryBufferLen); -+ return WLAN_STATUS_BUFFER_TOO_SHORT; -+ } -+ -+ if (kalGetMediaStateIndicated(prAdapter->prGlueInfo) == PARAM_MEDIA_STATE_DISCONNECTED) { -+ return WLAN_STATUS_ADAPTER_NOT_READY; -+ } else if (prAdapter->fgIsLinkQualityValid == TRUE && -+ (kalGetTimeTick() - prAdapter->rLinkQualityUpdateTime) <= CFG_LINK_QUALITY_VALID_PERIOD) { -+ PARAM_RSSI rRssi; -+ -+ rRssi = (PARAM_RSSI) prAdapter->rLinkQuality.cRssi; /* ranged from (-128 ~ 30) in unit of dBm */ -+ -+ if (rRssi > PARAM_WHQL_RSSI_MAX_DBM) -+ rRssi = PARAM_WHQL_RSSI_MAX_DBM; -+ else if (rRssi < PARAM_WHQL_RSSI_MIN_DBM) -+ rRssi = PARAM_WHQL_RSSI_MIN_DBM; -+ -+ kalMemCopy(pvQueryBuffer, &rRssi, sizeof(PARAM_RSSI)); -+ return WLAN_STATUS_SUCCESS; -+ } -+#ifdef LINUX -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_GET_LINK_QUALITY, -+ FALSE, -+ TRUE, -+ TRUE, -+ nicCmdEventQueryLinkQuality, -+ nicOidCmdTimeoutCommon, -+ *pu4QueryInfoLen, pvQueryBuffer, pvQueryBuffer, u4QueryBufferLen); -+#else -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_GET_LINK_QUALITY, -+ FALSE, -+ TRUE, -+ TRUE, -+ nicCmdEventQueryLinkQuality, -+ nicOidCmdTimeoutCommon, 0, NULL, pvQueryBuffer, u4QueryBufferLen); -+ -+#endif -+} /* end of wlanoidQueryRssi() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to query the current RSSI trigger value. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvQueryBuffer Pointer to the buffer that holds the result of the query. -+* \param[in] u4QueryBufferLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call failed due to invalid length of -+* the query buffer, returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_BUFFER_TOO_SHORT -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryRssiTrigger(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ DEBUGFUNC("wlanoidQueryRssiTrigger"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4QueryInfoLen); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ -+ if (prAdapter->rWlanInfo.eRssiTriggerType == ENUM_RSSI_TRIGGER_NONE) -+ return WLAN_STATUS_ADAPTER_NOT_READY; -+ -+ *pu4QueryInfoLen = sizeof(PARAM_RSSI); -+ -+ /* Check for query buffer length */ -+ if (u4QueryBufferLen < *pu4QueryInfoLen) { -+ DBGLOG(OID, WARN, "Too short length %u\n", u4QueryBufferLen); -+ return WLAN_STATUS_BUFFER_TOO_SHORT; -+ } -+ -+ *(PARAM_RSSI *) pvQueryBuffer = prAdapter->rWlanInfo.rRssiTriggerValue; -+ DBGLOG(OID, INFO, "RSSI trigger: %d dBm\n", *(PARAM_RSSI *) pvQueryBuffer); -+ -+ return WLAN_STATUS_SUCCESS; -+} /* wlanoidQueryRssiTrigger */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to set a trigger value of the RSSI event. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns the -+* amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetRssiTrigger(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ PARAM_RSSI rRssiTriggerValue; -+ -+ DEBUGFUNC("wlanoidSetRssiTrigger"); -+ ASSERT(prAdapter); -+ ASSERT(pvSetBuffer); -+ ASSERT(pu4SetInfoLen); -+ -+ *pu4SetInfoLen = sizeof(PARAM_RSSI); -+ rRssiTriggerValue = *(PARAM_RSSI *) pvSetBuffer; -+ -+ if (rRssiTriggerValue > PARAM_WHQL_RSSI_MAX_DBM || rRssiTriggerValue < PARAM_WHQL_RSSI_MIN_DBM) -+ return -+ /* Save the RSSI trigger value to the Adapter structure */ -+ prAdapter->rWlanInfo.rRssiTriggerValue = rRssiTriggerValue; -+ -+ /* If the RSSI trigger value is equal to the current RSSI value, the -+ * indication triggers immediately. We need to indicate the protocol -+ * that an RSSI status indication event triggers. */ -+ if (rRssiTriggerValue == (PARAM_RSSI) (prAdapter->rLinkQuality.cRssi)) { -+ prAdapter->rWlanInfo.eRssiTriggerType = ENUM_RSSI_TRIGGER_TRIGGERED; -+ -+ kalIndicateStatusAndComplete(prAdapter->prGlueInfo, -+ WLAN_STATUS_MEDIA_SPECIFIC_INDICATION, -+ (PVOID) &prAdapter->rWlanInfo.rRssiTriggerValue, sizeof(PARAM_RSSI)); -+ } else if (rRssiTriggerValue < (PARAM_RSSI) (prAdapter->rLinkQuality.cRssi)) -+ prAdapter->rWlanInfo.eRssiTriggerType = ENUM_RSSI_TRIGGER_GREATER; -+ else if (rRssiTriggerValue > (PARAM_RSSI) (prAdapter->rLinkQuality.cRssi)) -+ prAdapter->rWlanInfo.eRssiTriggerType = ENUM_RSSI_TRIGGER_LESS; -+ -+ return WLAN_STATUS_SUCCESS; -+} /* wlanoidSetRssiTrigger */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to set a suggested value for the number of -+* bytes of received packet data that will be indicated to the protocol -+* driver. We just accept the set and ignore this value. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetCurrentLookahead(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ DEBUGFUNC("wlanoidSetCurrentLookahead"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pvSetBuffer); -+ ASSERT(pu4SetInfoLen); -+ -+ if (u4SetBufferLen < sizeof(UINT_32)) { -+ *pu4SetInfoLen = sizeof(UINT_32); -+ return WLAN_STATUS_INVALID_LENGTH; -+ } -+ -+ *pu4SetInfoLen = sizeof(UINT_32); -+ return WLAN_STATUS_SUCCESS; -+} /* wlanoidSetCurrentLookahead */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to query the number of frames that the driver -+* receives but does not indicate to the protocols due to errors. -+* -+* \param[in] pvAdapter Pointer to the Adapter structure. -+* \param[out] pvQueryBuf A pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+* \retval WLAN_STATUS_ADAPTER_NOT_READY -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryRcvError(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ DEBUGFUNC("wlanoidQueryRcvError"); -+ DBGLOG(OID, LOUD, "\n"); -+ -+ ASSERT(prAdapter); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ ASSERT(pu4QueryInfoLen); -+ -+ if (prAdapter->rAcpiState == ACPI_STATE_D3) { -+ DBGLOG(OID, WARN, "Fail in query receive error! (Adapter not ready). ACPI=D%d, Radio=%d\n", -+ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); -+ *pu4QueryInfoLen = sizeof(UINT_32); -+ return WLAN_STATUS_ADAPTER_NOT_READY; -+ } else if (u4QueryBufferLen < sizeof(UINT_32) -+ || (u4QueryBufferLen > sizeof(UINT_32) && u4QueryBufferLen < sizeof(UINT_64))) { -+ *pu4QueryInfoLen = sizeof(UINT_64); -+ return WLAN_STATUS_INVALID_LENGTH; -+ } -+#if CFG_ENABLE_STATISTICS_BUFFERING -+ if (IsBufferedStatisticsUsable(prAdapter) == TRUE) { -+ /* @FIXME, RX_ERROR_DROP_COUNT/RX_FIFO_FULL_DROP_COUNT is not calculated */ -+ if (u4QueryBufferLen == sizeof(UINT_32)) { -+ *pu4QueryInfoLen = sizeof(UINT_32); -+ *(PUINT_32) pvQueryBuffer = (UINT_32) prAdapter->rStatStruct.rFCSErrorCount.QuadPart; -+ } else { -+ *pu4QueryInfoLen = sizeof(UINT_64); -+ *(PUINT_64) pvQueryBuffer = (UINT_64) prAdapter->rStatStruct.rFCSErrorCount.QuadPart; -+ } -+ -+ return WLAN_STATUS_SUCCESS; -+ } -+#endif -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_GET_STATISTICS, -+ FALSE, -+ TRUE, -+ TRUE, -+ nicCmdEventQueryRecvError, -+ nicOidCmdTimeoutCommon, 0, NULL, pvQueryBuffer, u4QueryBufferLen); -+ -+} /* wlanoidQueryRcvError */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to query the number of frames that the NIC -+* cannot receive due to lack of NIC receive buffer space. -+* -+* \param[in] pvAdapter Pointer to the Adapter structure -+* \param[in] pvQueryBuf A pointer to the buffer that holds the result of the -+* query buffer -+* \param[in] u4QueryBufLen The length of the query buffer -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS If success; -+* \retval WLAN_STATUS_INVALID_LENGTH -+* \retval WLAN_STATUS_ADAPTER_NOT_READY -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryRcvNoBuffer(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ DEBUGFUNC("wlanoidQueryRcvNoBuffer"); -+ DBGLOG(OID, LOUD, "\n"); -+ -+ ASSERT(prAdapter); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ ASSERT(pu4QueryInfoLen); -+ -+ if (prAdapter->rAcpiState == ACPI_STATE_D3) { -+ DBGLOG(OID, WARN, "Fail in query receive error! (Adapter not ready). ACPI=D%d, Radio=%d\n", -+ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); -+ *pu4QueryInfoLen = sizeof(UINT_32); -+ return WLAN_STATUS_ADAPTER_NOT_READY; -+ } else if (u4QueryBufferLen < sizeof(UINT_32) -+ || (u4QueryBufferLen > sizeof(UINT_32) && u4QueryBufferLen < sizeof(UINT_64))) { -+ *pu4QueryInfoLen = sizeof(UINT_64); -+ return WLAN_STATUS_INVALID_LENGTH; -+ } -+#if CFG_ENABLE_STATISTICS_BUFFERING -+ if (IsBufferedStatisticsUsable(prAdapter) == TRUE) { -+ if (u4QueryBufferLen == sizeof(UINT_32)) { -+ *pu4QueryInfoLen = sizeof(UINT_32); -+ *(PUINT_32) pvQueryBuffer = (UINT_32) 0; /* @FIXME */ -+ } else { -+ *pu4QueryInfoLen = sizeof(UINT_64); -+ *(PUINT_64) pvQueryBuffer = (UINT_64) 0; /* @FIXME */ -+ } -+ -+ return WLAN_STATUS_SUCCESS; -+ } -+#endif -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_GET_STATISTICS, -+ FALSE, -+ TRUE, -+ TRUE, -+ nicCmdEventQueryRecvNoBuffer, -+ nicOidCmdTimeoutCommon, 0, NULL, pvQueryBuffer, u4QueryBufferLen); -+ -+} /* wlanoidQueryRcvNoBuffer */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to query the number of frames that the NIC -+* received and it is CRC error. -+* -+* \param[in] pvAdapter Pointer to the Adapter structure -+* \param[in] pvQueryBuf A pointer to the buffer that holds the result of the -+* query buffer -+* \param[in] u4QueryBufLen The length of the query buffer -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS If success; -+* \retval WLAN_STATUS_INVALID_LENGTH -+* \retval WLAN_STATUS_ADAPTER_NOT_READY -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryRcvCrcError(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ DEBUGFUNC("wlanoidQueryRcvCrcError"); -+ DBGLOG(OID, LOUD, "\n"); -+ -+ ASSERT(prAdapter); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ ASSERT(pu4QueryInfoLen); -+ -+ if (prAdapter->rAcpiState == ACPI_STATE_D3) { -+ DBGLOG(OID, WARN, "Fail in query receive error! (Adapter not ready). ACPI=D%d, Radio=%d\n", -+ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); -+ *pu4QueryInfoLen = sizeof(UINT_32); -+ return WLAN_STATUS_ADAPTER_NOT_READY; -+ } else if (u4QueryBufferLen < sizeof(UINT_32) -+ || (u4QueryBufferLen > sizeof(UINT_32) && u4QueryBufferLen < sizeof(UINT_64))) { -+ *pu4QueryInfoLen = sizeof(UINT_64); -+ return WLAN_STATUS_INVALID_LENGTH; -+ } -+#if CFG_ENABLE_STATISTICS_BUFFERING -+ if (IsBufferedStatisticsUsable(prAdapter) == TRUE) { -+ if (u4QueryBufferLen == sizeof(UINT_32)) { -+ *pu4QueryInfoLen = sizeof(UINT_32); -+ *(PUINT_32) pvQueryBuffer = (UINT_32) prAdapter->rStatStruct.rFCSErrorCount.QuadPart; -+ } else { -+ *pu4QueryInfoLen = sizeof(UINT_64); -+ *(PUINT_64) pvQueryBuffer = (UINT_64) prAdapter->rStatStruct.rFCSErrorCount.QuadPart; -+ } -+ -+ return WLAN_STATUS_SUCCESS; -+ } -+#endif -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_GET_STATISTICS, -+ FALSE, -+ TRUE, -+ TRUE, -+ nicCmdEventQueryRecvCrcError, -+ nicOidCmdTimeoutCommon, 0, NULL, pvQueryBuffer, u4QueryBufferLen); -+ -+} /* wlanoidQueryRcvCrcError */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to query the current 802.11 statistics. -+* -+* \param[in] pvAdapter Pointer to the Adapter structure -+* \param[in] pvQueryBuf A pointer to the buffer that holds the result of the -+* query buffer -+* \param[in] u4QueryBufLen The length of the query buffer -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryStatisticsPL(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ DBGLOG(OID, LOUD, "\n"); -+ -+ ASSERT(prAdapter); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ ASSERT(pu4QueryInfoLen); -+ -+ *pu4QueryInfoLen = sizeof(PARAM_802_11_STATISTICS_STRUCT_T); -+ -+ if (prAdapter->rAcpiState == ACPI_STATE_D3) { -+ DBGLOG(OID, WARN, "Fail in query receive error! (Adapter not ready). ACPI=D%d, Radio=%d\n", -+ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); -+ *pu4QueryInfoLen = sizeof(UINT_32); -+ return WLAN_STATUS_ADAPTER_NOT_READY; -+ } else if (u4QueryBufferLen < sizeof(PARAM_802_11_STATISTICS_STRUCT_T)) { -+ DBGLOG(OID, WARN, "Too short length %u\n", u4QueryBufferLen); -+ return WLAN_STATUS_INVALID_LENGTH; -+ } -+#if CFG_ENABLE_STATISTICS_BUFFERING -+ if (IsBufferedStatisticsUsable(prAdapter) == TRUE) { -+ P_PARAM_802_11_STATISTICS_STRUCT_T prStatistics; -+ -+ *pu4QueryInfoLen = sizeof(PARAM_802_11_STATISTICS_STRUCT_T); -+ prStatistics = (P_PARAM_802_11_STATISTICS_STRUCT_T) pvQueryBuffer; -+ -+ prStatistics->u4Length = sizeof(PARAM_802_11_STATISTICS_STRUCT_T); -+ prStatistics->rTransmittedFragmentCount = prAdapter->rStatStruct.rTransmittedFragmentCount; -+ prStatistics->rMulticastTransmittedFrameCount = prAdapter->rStatStruct.rMulticastTransmittedFrameCount; -+ prStatistics->rFailedCount = prAdapter->rStatStruct.rFailedCount; -+ prStatistics->rRetryCount = prAdapter->rStatStruct.rRetryCount; -+ prStatistics->rMultipleRetryCount = prAdapter->rStatStruct.rMultipleRetryCount; -+ prStatistics->rRTSSuccessCount = prAdapter->rStatStruct.rRTSSuccessCount; -+ prStatistics->rRTSFailureCount = prAdapter->rStatStruct.rRTSFailureCount; -+ prStatistics->rACKFailureCount = prAdapter->rStatStruct.rACKFailureCount; -+ prStatistics->rFrameDuplicateCount = prAdapter->rStatStruct.rFrameDuplicateCount; -+ prStatistics->rReceivedFragmentCount = prAdapter->rStatStruct.rReceivedFragmentCount; -+ prStatistics->rMulticastReceivedFrameCount = prAdapter->rStatStruct.rMulticastReceivedFrameCount; -+ prStatistics->rFCSErrorCount = prAdapter->rStatStruct.rFCSErrorCount; -+ prStatistics->rTKIPLocalMICFailures.QuadPart = 0; -+ prStatistics->rTKIPICVErrors.QuadPart = 0; -+ prStatistics->rTKIPCounterMeasuresInvoked.QuadPart = 0; -+ prStatistics->rTKIPReplays.QuadPart = 0; -+ prStatistics->rCCMPFormatErrors.QuadPart = 0; -+ prStatistics->rCCMPReplays.QuadPart = 0; -+ prStatistics->rCCMPDecryptErrors.QuadPart = 0; -+ prStatistics->rFourWayHandshakeFailures.QuadPart = 0; -+ prStatistics->rWEPUndecryptableCount.QuadPart = 0; -+ prStatistics->rWEPICVErrorCount.QuadPart = 0; -+ prStatistics->rDecryptSuccessCount.QuadPart = 0; -+ prStatistics->rDecryptFailureCount.QuadPart = 0; -+ return WLAN_STATUS_SUCCESS; -+ } -+#endif -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_GET_STATISTICS_PL, -+ FALSE, -+ TRUE, -+ TRUE, -+ nicCmdEventQueryStatistics, -+ nicOidCmdTimeoutCommon, 0, NULL, pvQueryBuffer, u4QueryBufferLen); -+ -+} /* wlanoidQueryStatistics */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to query the current 802.11 statistics. -+* -+* \param[in] pvAdapter Pointer to the Adapter structure -+* \param[in] pvQueryBuf A pointer to the buffer that holds the result of the -+* query buffer -+* \param[in] u4QueryBufLen The length of the query buffer -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryStatistics(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ DEBUGFUNC("wlanoidQueryStatistics"); -+ DBGLOG(OID, LOUD, "\n"); -+ -+ ASSERT(prAdapter); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ ASSERT(pu4QueryInfoLen); -+ -+ *pu4QueryInfoLen = sizeof(PARAM_802_11_STATISTICS_STRUCT_T); -+ -+ if (prAdapter->rAcpiState == ACPI_STATE_D3) { -+ DBGLOG(OID, WARN, "Fail in query receive error! (Adapter not ready). ACPI=D%d, Radio=%d\n", -+ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); -+ *pu4QueryInfoLen = sizeof(UINT_32); -+ return WLAN_STATUS_ADAPTER_NOT_READY; -+ } else if (u4QueryBufferLen < sizeof(PARAM_802_11_STATISTICS_STRUCT_T)) { -+ DBGLOG(OID, WARN, "Too short length %u\n", u4QueryBufferLen); -+ return WLAN_STATUS_INVALID_LENGTH; -+ } -+#if CFG_ENABLE_STATISTICS_BUFFERING -+ if (IsBufferedStatisticsUsable(prAdapter) == TRUE) { -+ P_PARAM_802_11_STATISTICS_STRUCT_T prStatistics; -+ -+ *pu4QueryInfoLen = sizeof(PARAM_802_11_STATISTICS_STRUCT_T); -+ prStatistics = (P_PARAM_802_11_STATISTICS_STRUCT_T) pvQueryBuffer; -+ -+ prStatistics->u4Length = sizeof(PARAM_802_11_STATISTICS_STRUCT_T); -+ prStatistics->rTransmittedFragmentCount = prAdapter->rStatStruct.rTransmittedFragmentCount; -+ prStatistics->rMulticastTransmittedFrameCount = prAdapter->rStatStruct.rMulticastTransmittedFrameCount; -+ prStatistics->rFailedCount = prAdapter->rStatStruct.rFailedCount; -+ prStatistics->rRetryCount = prAdapter->rStatStruct.rRetryCount; -+ prStatistics->rMultipleRetryCount = prAdapter->rStatStruct.rMultipleRetryCount; -+ prStatistics->rRTSSuccessCount = prAdapter->rStatStruct.rRTSSuccessCount; -+ prStatistics->rRTSFailureCount = prAdapter->rStatStruct.rRTSFailureCount; -+ prStatistics->rACKFailureCount = prAdapter->rStatStruct.rACKFailureCount; -+ prStatistics->rFrameDuplicateCount = prAdapter->rStatStruct.rFrameDuplicateCount; -+ prStatistics->rReceivedFragmentCount = prAdapter->rStatStruct.rReceivedFragmentCount; -+ prStatistics->rMulticastReceivedFrameCount = prAdapter->rStatStruct.rMulticastReceivedFrameCount; -+ prStatistics->rFCSErrorCount = prAdapter->rStatStruct.rFCSErrorCount; -+ prStatistics->rTKIPLocalMICFailures.QuadPart = 0; -+ prStatistics->rTKIPICVErrors.QuadPart = 0; -+ prStatistics->rTKIPCounterMeasuresInvoked.QuadPart = 0; -+ prStatistics->rTKIPReplays.QuadPart = 0; -+ prStatistics->rCCMPFormatErrors.QuadPart = 0; -+ prStatistics->rCCMPReplays.QuadPart = 0; -+ prStatistics->rCCMPDecryptErrors.QuadPart = 0; -+ prStatistics->rFourWayHandshakeFailures.QuadPart = 0; -+ prStatistics->rWEPUndecryptableCount.QuadPart = 0; -+ prStatistics->rWEPICVErrorCount.QuadPart = 0; -+ prStatistics->rDecryptSuccessCount.QuadPart = 0; -+ prStatistics->rDecryptFailureCount.QuadPart = 0; -+ -+ return WLAN_STATUS_SUCCESS; -+ } -+#endif -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_GET_STATISTICS, -+ FALSE, -+ TRUE, -+ TRUE, -+ nicCmdEventQueryStatistics, -+ nicOidCmdTimeoutCommon, 0, NULL, pvQueryBuffer, u4QueryBufferLen); -+ -+} /* wlanoidQueryStatistics */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to query current media streaming status. -+* -+* \param[in] pvAdapter Pointer to the Adapter structure -+* \param[in] pvQueryBuf A pointer to the buffer that holds the result of the -+* query buffer -+* \param[in] u4QueryBufLen The length of the query buffer -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryMediaStreamMode(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ DEBUGFUNC("wlanoidQueryMediaStreamMode"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4QueryInfoLen); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ -+ *pu4QueryInfoLen = sizeof(ENUM_MEDIA_STREAM_MODE); -+ -+ if (u4QueryBufferLen < *pu4QueryInfoLen) { -+ DBGLOG(OID, WARN, "Invalid length %u\n", u4QueryBufferLen); -+ return WLAN_STATUS_INVALID_LENGTH; -+ } -+ -+ *(P_ENUM_MEDIA_STREAM_MODE) pvQueryBuffer = -+ prAdapter->rWlanInfo.eLinkAttr.ucMediaStreamMode == 0 ? ENUM_MEDIA_STREAM_OFF : ENUM_MEDIA_STREAM_ON; -+ -+ return WLAN_STATUS_SUCCESS; -+ -+} /* wlanoidQueryMediaStreamMode */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to enter media streaming mode or exit media streaming mode -+* -+* \param[in] pvAdapter Pointer to the Adapter structure -+* \param[in] pvQueryBuf A pointer to the buffer that holds the result of the -+* query buffer -+* \param[in] u4QueryBufLen The length of the query buffer -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetMediaStreamMode(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ ENUM_MEDIA_STREAM_MODE eStreamMode; -+ -+ DEBUGFUNC("wlanoidSetMediaStreamMode"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pvSetBuffer); -+ ASSERT(pu4SetInfoLen); -+ -+ if (u4SetBufferLen < sizeof(ENUM_MEDIA_STREAM_MODE)) { -+ DBGLOG(OID, WARN, "Invalid length %u\n", u4SetBufferLen); -+ return WLAN_STATUS_INVALID_LENGTH; -+ } -+ -+ *pu4SetInfoLen = sizeof(ENUM_MEDIA_STREAM_MODE); -+ -+ eStreamMode = *(P_ENUM_MEDIA_STREAM_MODE) pvSetBuffer; -+ -+ if (eStreamMode == ENUM_MEDIA_STREAM_OFF) -+ prAdapter->rWlanInfo.eLinkAttr.ucMediaStreamMode = 0; -+ else -+ prAdapter->rWlanInfo.eLinkAttr.ucMediaStreamMode = 1; -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_LINK_ATTRIB, -+ TRUE, -+ FALSE, -+ TRUE, -+ nicCmdEventSetMediaStreamMode, -+ nicOidCmdTimeoutCommon, -+ sizeof(CMD_LINK_ATTRIB), -+ (PUINT_8) &(prAdapter->rWlanInfo.eLinkAttr), pvSetBuffer, u4SetBufferLen); -+} /* wlanoidSetMediaStreamMode */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to query the permanent MAC address of the NIC. -+* -+* \param[in] pvAdapter Pointer to the Adapter structure -+* \param[in] pvQueryBuf A pointer to the buffer that holds the result of the -+* query buffer -+* \param[in] u4QueryBufLen The length of the query buffer -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryPermanentAddr(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ DEBUGFUNC("wlanoidQueryPermanentAddr"); -+ DBGLOG(OID, LOUD, "\n"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4QueryInfoLen); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ -+ if (u4QueryBufferLen < MAC_ADDR_LEN) -+ return WLAN_STATUS_BUFFER_TOO_SHORT; -+ -+ COPY_MAC_ADDR(pvQueryBuffer, prAdapter->rWifiVar.aucPermanentAddress); -+ *pu4QueryInfoLen = MAC_ADDR_LEN; -+ -+ return WLAN_STATUS_SUCCESS; -+} /* wlanoidQueryPermanentAddr */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to query the MAC address the NIC is currently using. -+* -+* \param[in] pvAdapter Pointer to the Adapter structure -+* \param[in] pvQueryBuf A pointer to the buffer that holds the result of the -+* query buffer -+* \param[in] u4QueryBufLen The length of the query buffer -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_BUFFER_TOO_SHORT -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryCurrentAddr(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ CMD_BASIC_CONFIG rCmdBasicConfig; -+ -+ DEBUGFUNC("wlanoidQueryCurrentAddr"); -+ DBGLOG(OID, LOUD, "\n"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4QueryInfoLen); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ -+ if (u4QueryBufferLen < MAC_ADDR_LEN) -+ return WLAN_STATUS_BUFFER_TOO_SHORT; -+ -+ kalMemZero(&rCmdBasicConfig, sizeof(CMD_BASIC_CONFIG)); -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_BASIC_CONFIG, -+ FALSE, -+ TRUE, -+ TRUE, -+ nicCmdEventQueryAddress, -+ nicOidCmdTimeoutCommon, -+ sizeof(CMD_BASIC_CONFIG), -+ (PUINT_8) &rCmdBasicConfig, pvQueryBuffer, u4QueryBufferLen); -+ -+} /* wlanoidQueryCurrentAddr */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to query NIC link speed. -+* -+* \param[in] pvAdapter Pointer to the Adapter structure -+* \param[in] pvQueryBuf A pointer to the buffer that holds the result of the -+* query buffer -+* \param[in] u4QueryBufLen The length of the query buffer -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_BUFFER_TOO_SHORT -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryLinkSpeed(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ DEBUGFUNC("wlanoidQueryLinkSpeed"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4QueryInfoLen); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ -+ *pu4QueryInfoLen = sizeof(UINT_32); -+ -+ if (u4QueryBufferLen < sizeof(UINT_32)) -+ return WLAN_STATUS_BUFFER_TOO_SHORT; -+ -+ if (kalGetMediaStateIndicated(prAdapter->prGlueInfo) != PARAM_MEDIA_STATE_CONNECTED) { -+ return WLAN_STATUS_ADAPTER_NOT_READY; -+ } else if (prAdapter->fgIsLinkRateValid == TRUE && -+ (kalGetTimeTick() - prAdapter->rLinkRateUpdateTime) <= CFG_LINK_QUALITY_VALID_PERIOD) { -+ *(PUINT_32) pvQueryBuffer = prAdapter->rLinkQuality.u2LinkSpeed * 5000; /* change to unit of 100bps */ -+ return WLAN_STATUS_SUCCESS; -+ } else { -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_GET_LINK_QUALITY, -+ FALSE, -+ TRUE, -+ TRUE, -+ nicCmdEventQueryLinkSpeed, -+ nicOidCmdTimeoutCommon, 0, NULL, pvQueryBuffer, u4QueryBufferLen); -+ } -+} /* end of wlanoidQueryLinkSpeed() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to query MCR value. -+* -+* \param[in] pvAdapter Pointer to the Adapter structure. -+* \param[out] pvQueryBuf A pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryMcrRead(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ P_PARAM_CUSTOM_MCR_RW_STRUCT_T prMcrRdInfo; -+ CMD_ACCESS_REG rCmdAccessReg; -+ -+ DEBUGFUNC("wlanoidQueryMcrRead"); -+ DBGLOG(OID, LOUD, "\n"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4QueryInfoLen); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ -+ *pu4QueryInfoLen = sizeof(PARAM_CUSTOM_MCR_RW_STRUCT_T); -+ -+ if (u4QueryBufferLen < sizeof(PARAM_CUSTOM_MCR_RW_STRUCT_T)) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ prMcrRdInfo = (P_PARAM_CUSTOM_MCR_RW_STRUCT_T) pvQueryBuffer; -+ -+ /* 0x9000 - 0x9EFF reserved for FW */ -+#if CFG_SUPPORT_SWCR -+ if ((prMcrRdInfo->u4McrOffset >> 16) == 0x9F00) { -+ swCrReadWriteCmd(prAdapter, -+ SWCR_READ, -+ (UINT_16) (prMcrRdInfo->u4McrOffset & BITS(0, 15)), &prMcrRdInfo->u4McrData); -+ return WLAN_STATUS_SUCCESS; -+ } -+#endif /* CFG_SUPPORT_SWCR */ -+ -+ /* Check if access F/W Domain MCR (due to WiFiSYS is placed from 0x6000-0000 */ -+ if (prMcrRdInfo->u4McrOffset & 0xFFFF0000) { -+ /* fill command */ -+ rCmdAccessReg.u4Address = prMcrRdInfo->u4McrOffset; -+ rCmdAccessReg.u4Data = 0; -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_ACCESS_REG, -+ FALSE, -+ TRUE, -+ TRUE, -+ nicCmdEventQueryMcrRead, -+ nicOidCmdTimeoutCommon, -+ sizeof(CMD_ACCESS_REG), -+ (PUINT_8) &rCmdAccessReg, pvQueryBuffer, u4QueryBufferLen); -+ } else { -+ HAL_MCR_RD(prAdapter, prMcrRdInfo->u4McrOffset & BITS(2, 31), /* address is in DWORD unit */ -+ &prMcrRdInfo->u4McrData); -+ -+ DBGLOG(OID, TRACE, "MCR Read: Offset = %#08x, Data = %#08x\n", -+ prMcrRdInfo->u4McrOffset, prMcrRdInfo->u4McrData); -+ return WLAN_STATUS_SUCCESS; -+ } -+} /* end of wlanoidQueryMcrRead() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to write MCR and enable specific function. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetMcrWrite(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ P_PARAM_CUSTOM_MCR_RW_STRUCT_T prMcrWrInfo; -+ CMD_ACCESS_REG rCmdAccessReg; -+ -+#if CFG_STRESS_TEST_SUPPORT -+ P_AIS_FSM_INFO_T prAisFsmInfo; -+ P_BSS_INFO_T prBssInfo = &(prAdapter->rWifiVar.arBssInfo[(NETWORK_TYPE_AIS_INDEX)]); -+ P_STA_RECORD_T prStaRec = prBssInfo->prStaRecOfAP; -+ UINT_32 u4McrOffset, u4McrData; -+#endif -+ -+ DEBUGFUNC("wlanoidSetMcrWrite"); -+ DBGLOG(OID, LOUD, "\n"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ *pu4SetInfoLen = sizeof(PARAM_CUSTOM_MCR_RW_STRUCT_T); -+ -+ if (u4SetBufferLen < sizeof(PARAM_CUSTOM_MCR_RW_STRUCT_T)) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ ASSERT(pvSetBuffer); -+ -+ prMcrWrInfo = (P_PARAM_CUSTOM_MCR_RW_STRUCT_T) pvSetBuffer; -+ -+ /* 0x9000 - 0x9EFF reserved for FW */ -+ /* 0xFFFE reserved for FW */ -+ -+ /* -- Puff Stress Test Begin */ -+#if CFG_STRESS_TEST_SUPPORT -+ -+ /* 0xFFFFFFFE for Control Rate */ -+ if (prMcrWrInfo->u4McrOffset == 0xFFFFFFFE) { -+ if (prMcrWrInfo->u4McrData < FIXED_RATE_NUM && prMcrWrInfo->u4McrData > 0) -+ prAdapter->rWifiVar.eRateSetting = (ENUM_REGISTRY_FIXED_RATE_T) (prMcrWrInfo->u4McrData); -+ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); -+ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_3); -+ DEBUGFUNC("[Stress Test]Complete Rate is Changed...\n"); -+ DBGLOG(OID, TRACE, -+ "[Stress Test] Rate is Changed to index %d...\n", prAdapter->rWifiVar.eRateSetting); -+ } -+ /* 0xFFFFFFFD for Switch Channel */ -+ else if (prMcrWrInfo->u4McrOffset == 0xFFFFFFFD) { -+ if (prMcrWrInfo->u4McrData <= 11 && prMcrWrInfo->u4McrData >= 1) -+ prBssInfo->ucPrimaryChannel = prMcrWrInfo->u4McrData; -+ nicUpdateBss(prAdapter, prBssInfo->ucNetTypeIndex); -+ DBGLOG(OID, TRACE, "[Stress Test] Channel is switched to %d ...\n", prBssInfo->ucPrimaryChannel); -+ -+ return WLAN_STATUS_SUCCESS; -+ } -+ /* 0xFFFFFFFFC for Control RF Band and SCO */ -+ else if (prMcrWrInfo->u4McrOffset == 0xFFFFFFFC) { -+ /* Band */ -+ if (prMcrWrInfo->u4McrData & 0x80000000) { -+ /* prBssInfo->eBand = BAND_5G; */ -+ /* prBssInfo->ucPrimaryChannel = 52; // Bond to Channel 52 */ -+ } else { -+ prBssInfo->eBand = BAND_2G4; -+ prBssInfo->ucPrimaryChannel = 8; /* Bond to Channel 6 */ -+ } -+ -+ /* Bandwidth */ -+ if (prMcrWrInfo->u4McrData & 0x00010000) { -+ prStaRec->u2HtCapInfo |= HT_CAP_INFO_SUP_CHNL_WIDTH; -+ prStaRec->ucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; -+ -+ if (prMcrWrInfo->u4McrData == 0x00010002) { -+ prBssInfo->eBssSCO = CHNL_EXT_SCB; /* U20 */ -+ prBssInfo->ucPrimaryChannel += 2; -+ } else if (prMcrWrInfo->u4McrData == 0x00010001) { -+ prBssInfo->eBssSCO = CHNL_EXT_SCA; /* L20 */ -+ prBssInfo->ucPrimaryChannel -= 2; -+ } else { -+ prBssInfo->eBssSCO = CHNL_EXT_SCA; /* 40 */ -+ } -+ } -+ -+ if (prMcrWrInfo->u4McrData & 0x00000000) { -+ prStaRec->u2HtCapInfo &= ~HT_CAP_INFO_SUP_CHNL_WIDTH; -+ prBssInfo->eBssSCO = CHNL_EXT_SCN; -+ } -+ rlmBssInitForAPandIbss(prAdapter, prBssInfo); -+ } -+ /* 0xFFFFFFFB for HT Capability */ -+ else if (prMcrWrInfo->u4McrOffset == 0xFFFFFFFB) { -+ /* Enable HT Capability */ -+ if (prMcrWrInfo->u4McrData & 0x00000001) { -+ prStaRec->u2HtCapInfo |= HT_CAP_INFO_HT_GF; -+ DEBUGFUNC("[Stress Test]Enable HT capability...\n"); -+ } else { -+ prStaRec->u2HtCapInfo &= (~HT_CAP_INFO_HT_GF); -+ DEBUGFUNC("[Stress Test]Disable HT capability...\n"); -+ } -+ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); -+ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_3); -+ } -+ /* 0xFFFFFFFA for Enable Random Rx Reset */ -+ else if (prMcrWrInfo->u4McrOffset == 0xFFFFFFFA) { -+ rCmdAccessReg.u4Address = prMcrWrInfo->u4McrOffset; -+ rCmdAccessReg.u4Data = prMcrWrInfo->u4McrData; -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_RANDOM_RX_RESET_EN, -+ TRUE, -+ FALSE, -+ TRUE, -+ nicCmdEventSetCommon, -+ nicOidCmdTimeoutCommon, -+ sizeof(CMD_ACCESS_REG), -+ (PUINT_8) &rCmdAccessReg, pvSetBuffer, u4SetBufferLen); -+ } -+ /* 0xFFFFFFF9 for Disable Random Rx Reset */ -+ else if (prMcrWrInfo->u4McrOffset == 0xFFFFFFF9) { -+ rCmdAccessReg.u4Address = prMcrWrInfo->u4McrOffset; -+ rCmdAccessReg.u4Data = prMcrWrInfo->u4McrData; -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_RANDOM_RX_RESET_DE, -+ TRUE, -+ FALSE, -+ TRUE, -+ nicCmdEventSetCommon, -+ nicOidCmdTimeoutCommon, -+ sizeof(CMD_ACCESS_REG), -+ (PUINT_8) &rCmdAccessReg, pvSetBuffer, u4SetBufferLen); -+ } -+ /* 0xFFFFFFF8 for Enable SAPP */ -+ else if (prMcrWrInfo->u4McrOffset == 0xFFFFFFF8) { -+ rCmdAccessReg.u4Address = prMcrWrInfo->u4McrOffset; -+ rCmdAccessReg.u4Data = prMcrWrInfo->u4McrData; -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SAPP_EN, -+ TRUE, -+ FALSE, -+ TRUE, -+ nicCmdEventSetCommon, -+ nicOidCmdTimeoutCommon, -+ sizeof(CMD_ACCESS_REG), -+ (PUINT_8) &rCmdAccessReg, pvSetBuffer, u4SetBufferLen); -+ } -+ /* 0xFFFFFFF7 for Disable SAPP */ -+ else if (prMcrWrInfo->u4McrOffset == 0xFFFFFFF7) { -+ rCmdAccessReg.u4Address = prMcrWrInfo->u4McrOffset; -+ rCmdAccessReg.u4Data = prMcrWrInfo->u4McrData; -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SAPP_DE, -+ TRUE, -+ FALSE, -+ TRUE, -+ nicCmdEventSetCommon, -+ nicOidCmdTimeoutCommon, -+ sizeof(CMD_ACCESS_REG), -+ (PUINT_8) &rCmdAccessReg, pvSetBuffer, u4SetBufferLen); -+ } -+ -+ else -+#endif -+ /* -- Puff Stress Test End */ -+ -+ /* Check if access F/W Domain MCR */ -+ if (prMcrWrInfo->u4McrOffset & 0xFFFF0000) { -+ -+ /* 0x9000 - 0x9EFF reserved for FW */ -+#if CFG_SUPPORT_SWCR -+ if ((prMcrWrInfo->u4McrOffset >> 16) == 0x9F00) { -+ swCrReadWriteCmd(prAdapter, -+ SWCR_WRITE, -+ (UINT_16) (prMcrWrInfo->u4McrOffset & BITS(0, 15)), &prMcrWrInfo->u4McrData); -+ return WLAN_STATUS_SUCCESS; -+ } -+#endif /* CFG_SUPPORT_SWCR */ -+ -+#if 1 -+ /* low power test special command */ -+ if (prMcrWrInfo->u4McrOffset == 0x11111110) { -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ /* DbgPrint("Enter test mode\n"); */ -+ prAdapter->fgTestMode = TRUE; -+ return rStatus; -+ } -+ if (prMcrWrInfo->u4McrOffset == 0x11111111) { -+ /* DbgPrint("nicpmSetAcpiPowerD3\n"); */ -+ -+ nicpmSetAcpiPowerD3(prAdapter); -+ kalDevSetPowerState(prAdapter->prGlueInfo, (UINT_32) ParamDeviceStateD3); -+ return WLAN_STATUS_SUCCESS; -+ } -+ if (prMcrWrInfo->u4McrOffset == 0x11111112) { -+ -+ /* DbgPrint("LP enter sleep\n"); */ -+ -+ /* fill command */ -+ rCmdAccessReg.u4Address = prMcrWrInfo->u4McrOffset; -+ rCmdAccessReg.u4Data = prMcrWrInfo->u4McrData; -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_ACCESS_REG, -+ TRUE, -+ FALSE, -+ TRUE, -+ nicCmdEventSetCommon, -+ nicOidCmdTimeoutCommon, -+ sizeof(CMD_ACCESS_REG), -+ (PUINT_8) &rCmdAccessReg, pvSetBuffer, u4SetBufferLen); -+ } -+#endif -+ -+#if 1 -+ /* low power test special command */ -+ if (prMcrWrInfo->u4McrOffset == 0x11111110) { -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ /* DbgPrint("Enter test mode\n"); */ -+ prAdapter->fgTestMode = TRUE; -+ return rStatus; -+ } -+ if (prMcrWrInfo->u4McrOffset == 0x11111111) { -+ /* DbgPrint("nicpmSetAcpiPowerD3\n"); */ -+ -+ nicpmSetAcpiPowerD3(prAdapter); -+ kalDevSetPowerState(prAdapter->prGlueInfo, (UINT_32) ParamDeviceStateD3); -+ return WLAN_STATUS_SUCCESS; -+ } -+ if (prMcrWrInfo->u4McrOffset == 0x11111112) { -+ -+ /* DbgPrint("LP enter sleep\n"); */ -+ -+ /* fill command */ -+ rCmdAccessReg.u4Address = prMcrWrInfo->u4McrOffset; -+ rCmdAccessReg.u4Data = prMcrWrInfo->u4McrData; -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_ACCESS_REG, -+ TRUE, -+ FALSE, -+ TRUE, -+ nicCmdEventSetCommon, -+ nicOidCmdTimeoutCommon, -+ sizeof(CMD_ACCESS_REG), -+ (PUINT_8) &rCmdAccessReg, pvSetBuffer, u4SetBufferLen); -+ } -+#endif -+ /* fill command */ -+ rCmdAccessReg.u4Address = prMcrWrInfo->u4McrOffset; -+ rCmdAccessReg.u4Data = prMcrWrInfo->u4McrData; -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_ACCESS_REG, -+ TRUE, -+ FALSE, -+ TRUE, -+ nicCmdEventSetCommon, -+ nicOidCmdTimeoutCommon, -+ sizeof(CMD_ACCESS_REG), -+ (PUINT_8) &rCmdAccessReg, pvSetBuffer, u4SetBufferLen); -+ } else { -+ HAL_MCR_WR(prAdapter, (prMcrWrInfo->u4McrOffset & BITS(2, 31)), /* address is in DWORD unit */ -+ prMcrWrInfo->u4McrData); -+ -+ DBGLOG(OID, TRACE, "MCR Write: Offset = %#08x, Data = %#08x\n", -+ prMcrWrInfo->u4McrOffset, prMcrWrInfo->u4McrData); -+ -+ return WLAN_STATUS_SUCCESS; -+ } -+} /* wlanoidSetMcrWrite */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to query SW CTRL -+* -+* \param[in] pvAdapter Pointer to the Adapter structure. -+* \param[out] pvQueryBuf A pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQuerySwCtrlRead(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ P_PARAM_CUSTOM_SW_CTRL_STRUCT_T prSwCtrlInfo; -+ WLAN_STATUS rWlanStatus; -+ UINT_16 u2Id, u2SubId; -+ UINT_32 u4Data; -+ -+ CMD_SW_DBG_CTRL_T rCmdSwCtrl; -+ -+ DEBUGFUNC("wlanoidQuerySwCtrlRead"); -+ DBGLOG(OID, LOUD, "\n"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4QueryInfoLen); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ -+ *pu4QueryInfoLen = sizeof(PARAM_CUSTOM_SW_CTRL_STRUCT_T); -+ -+ if (u4QueryBufferLen < sizeof(PARAM_CUSTOM_SW_CTRL_STRUCT_T)) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ prSwCtrlInfo = (P_PARAM_CUSTOM_SW_CTRL_STRUCT_T) pvQueryBuffer; -+ -+ u2Id = (UINT_16) (prSwCtrlInfo->u4Id >> 16); -+ u2SubId = (UINT_16) (prSwCtrlInfo->u4Id & BITS(0, 15)); -+ u4Data = 0; -+ rWlanStatus = WLAN_STATUS_SUCCESS; -+ -+ switch (u2Id) { -+ /* 0x9000 - 0x9EFF reserved for FW */ -+ /* 0xFFFE reserved for FW */ -+ -+#if CFG_SUPPORT_SWCR -+ case 0x9F00: -+ swCrReadWriteCmd(prAdapter, SWCR_READ /* Read */ , -+ (UINT_16) u2SubId, &u4Data); -+ break; -+#endif /* CFG_SUPPORT_SWCR */ -+ -+ case 0xFFFF: -+ { -+ u4Data = 0x5AA56620; -+ } -+ break; -+ -+ case 0x9000: -+ default: -+ { -+ rCmdSwCtrl.u4Id = prSwCtrlInfo->u4Id; -+ rCmdSwCtrl.u4Data = 0; -+ rWlanStatus = wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SW_DBG_CTRL, -+ FALSE, -+ TRUE, -+ TRUE, -+ nicCmdEventQuerySwCtrlRead, -+ nicOidCmdTimeoutCommon, -+ sizeof(CMD_SW_DBG_CTRL_T), -+ (PUINT_8) &rCmdSwCtrl, pvQueryBuffer, u4QueryBufferLen); -+ } -+ } /* switch(u2Id) */ -+ -+ prSwCtrlInfo->u4Data = u4Data; -+ -+ return rWlanStatus; -+ -+} -+ -+ /* end of wlanoidQuerySwCtrlRead() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to write SW CTRL -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetSwCtrlWrite(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ P_PARAM_CUSTOM_SW_CTRL_STRUCT_T prSwCtrlInfo; -+ CMD_SW_DBG_CTRL_T rCmdSwCtrl; -+ WLAN_STATUS rWlanStatus; -+ UINT_16 u2Id, u2SubId; -+ UINT_32 u4Data; -+#if CFG_SUPPORT_HOTSPOT_OPTIMIZATION -+ P_GLUE_INFO_T prGlueInfo; -+ CMD_HOTSPOT_OPTIMIZATION_CONFIG arHotspotOptimizationCfg; -+#endif -+ -+ DEBUGFUNC("wlanoidSetSwCtrlWrite"); -+ DBGLOG(OID, LOUD, "\n"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+#if CFG_SUPPORT_HOTSPOT_OPTIMIZATION -+ prGlueInfo = prAdapter->prGlueInfo; -+#endif -+ -+ *pu4SetInfoLen = sizeof(PARAM_CUSTOM_SW_CTRL_STRUCT_T); -+ -+ if (u4SetBufferLen < sizeof(PARAM_CUSTOM_SW_CTRL_STRUCT_T)) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ ASSERT(pvSetBuffer); -+ -+ prSwCtrlInfo = (P_PARAM_CUSTOM_SW_CTRL_STRUCT_T) pvSetBuffer; -+ -+ u2Id = (UINT_16) (prSwCtrlInfo->u4Id >> 16); -+ u2SubId = (UINT_16) (prSwCtrlInfo->u4Id & BITS(0, 15)); -+ u4Data = prSwCtrlInfo->u4Data; -+ rWlanStatus = WLAN_STATUS_SUCCESS; -+ -+ switch (u2Id) { -+ -+ /* 0x9000 - 0x9EFF reserved for FW */ -+ /* 0xFFFE reserved for FW */ -+ -+#if CFG_SUPPORT_SWCR -+ case 0x9F00: -+ swCrReadWriteCmd(prAdapter, SWCR_WRITE, (UINT_16) u2SubId, &u4Data); -+ break; -+#endif /* CFG_SUPPORT_SWCR */ -+ -+ case 0x1000: -+ if (u2SubId == 0x8000) { -+ /* CTIA power save mode setting (code: 0x10008000) */ -+ prAdapter->u4CtiaPowerMode = u4Data; -+ prAdapter->fgEnCtiaPowerMode = TRUE; -+ -+ /* */ -+ { -+ PARAM_POWER_MODE ePowerMode; -+ -+ if (prAdapter->u4CtiaPowerMode == 0) -+ /* force to keep in CAM mode */ -+ ePowerMode = Param_PowerModeCAM; -+ else if (prAdapter->u4CtiaPowerMode == 1) -+ ePowerMode = Param_PowerModeMAX_PSP; -+ else -+ ePowerMode = Param_PowerModeFast_PSP; -+ -+ rWlanStatus = nicConfigPowerSaveProfile(prAdapter, -+ NETWORK_TYPE_AIS_INDEX, ePowerMode, TRUE); -+ } -+ } -+ break; -+ case 0x1001: -+ if (u2SubId == 0x0) -+ prAdapter->fgEnOnlineScan = (BOOLEAN) u4Data; -+ else if (u2SubId == 0x1) -+ prAdapter->fgDisBcnLostDetection = (BOOLEAN) u4Data; -+ else if (u2SubId == 0x2) -+ prAdapter->rWifiVar.fgSupportUAPSD = (BOOLEAN) u4Data; -+ else if (u2SubId == 0x3) { -+ prAdapter->u4UapsdAcBmp = u4Data & BITS(0, 15); -+ prAdapter->rWifiVar.arBssInfo[u4Data >> 16].rPmProfSetupInfo.ucBmpDeliveryAC = -+ (UINT_8) prAdapter->u4UapsdAcBmp; -+ prAdapter->rWifiVar.arBssInfo[u4Data >> 16].rPmProfSetupInfo.ucBmpTriggerAC = -+ (UINT_8) prAdapter->u4UapsdAcBmp; -+ } else if (u2SubId == 0x4) -+ prAdapter->fgDisStaAgingTimeoutDetection = (BOOLEAN) u4Data; -+ else if (u2SubId == 0x5) -+ prAdapter->rWifiVar.rConnSettings.uc2G4BandwidthMode = (UINT_8) u4Data; -+ else if (u2SubId == 0x0100) -+ prAdapter->rWifiVar.u8SupportRxGf = (UINT_8) u4Data; -+ else if (u2SubId == 0x0101) { -+ prAdapter->rWifiVar.u8SupportRxSgi20 = (UINT_8) u4Data; -+ prAdapter->rWifiVar.u8SupportRxSgi40 = (UINT_8) u4Data; -+ } else if (u2SubId == 0x0102) -+ prAdapter->rWifiVar.u8SupportRxSTBC = (UINT_8) u4Data; -+ break; -+ -+#if CFG_SUPPORT_SWCR -+ case 0x1002: -+ if (u2SubId == 0x0) { -+ if (u4Data) -+ u4Data = BIT(HIF_RX_PKT_TYPE_MANAGEMENT); -+ swCrFrameCheckEnable(prAdapter, u4Data); -+ } else if (u2SubId == 0x1) { -+ BOOLEAN fgIsEnable; -+ UINT_8 ucType; -+ UINT_32 u4Timeout; -+ -+ fgIsEnable = (BOOLEAN) (u4Data & 0xff); -+ ucType = 0; /* ((u4Data>>4) & 0xf); */ -+ u4Timeout = ((u4Data >> 8) & 0xff); -+ swCrDebugCheckEnable(prAdapter, fgIsEnable, ucType, u4Timeout); -+ } -+ break; -+#endif -+ -+#if CFG_SUPPORT_802_11W -+ case 0x2000: -+ DBGLOG(RSN, TRACE, "802.11w test 0x%x\n", u2SubId); -+ if (u2SubId == 0x0) -+ rsnStartSaQuery(prAdapter); -+ if (u2SubId == 0x1) -+ rsnStopSaQuery(prAdapter); -+ if (u2SubId == 0x2) -+ rsnSaQueryRequest(prAdapter, NULL); -+ if (u2SubId == 0x3) { -+ P_BSS_INFO_T prBssInfo = &(prAdapter->rWifiVar.arBssInfo[(NETWORK_TYPE_AIS_INDEX)]); -+ -+ authSendDeauthFrame(prAdapter, prBssInfo->prStaRecOfAP, NULL, 7, NULL); -+ } -+ /* wext_set_mode */ -+ /* -+ if (u2SubId == 0x3) { -+ prAdapter->prGlueInfo->rWpaInfo.u4Mfp = RSN_AUTH_MFP_DISABLED; -+ } -+ if (u2SubId == 0x4) { -+ //prAdapter->rWifiVar.rAisSpecificBssInfo.fgMgmtProtection = TRUE; -+ prAdapter->prGlueInfo->rWpaInfo.u4Mfp = RSN_AUTH_MFP_OPTIONAL; -+ } -+ if (u2SubId == 0x5) { -+ //prAdapter->rWifiVar.rAisSpecificBssInfo.fgMgmtProtection = TRUE; -+ prAdapter->prGlueInfo->rWpaInfo.u4Mfp = RSN_AUTH_MFP_REQUIRED; -+ } -+ */ -+ break; -+#endif -+ case 0xFFFF: -+ { -+/* CMD_ACCESS_REG rCmdAccessReg; */ -+#if 1 /* CFG_MT6573_SMT_TEST */ -+ if (u2SubId == 0x0123) { -+ -+ DBGLOG(HAL, TRACE, "set smt fixed rate: %u\n", u4Data); -+ -+ if ((ENUM_REGISTRY_FIXED_RATE_T) (u4Data) < FIXED_RATE_NUM) -+ prAdapter->rWifiVar.eRateSetting = (ENUM_REGISTRY_FIXED_RATE_T) (u4Data); -+ else -+ prAdapter->rWifiVar.eRateSetting = FIXED_RATE_NONE; -+ -+ if (prAdapter->rWifiVar.eRateSetting == FIXED_RATE_NONE) -+ /* Enable Auto (Long/Short) Preamble */ -+ prAdapter->rWifiVar.ePreambleType = PREAMBLE_TYPE_AUTO; -+ else if ((prAdapter->rWifiVar.eRateSetting >= FIXED_RATE_MCS0_20M_400NS && -+ prAdapter->rWifiVar.eRateSetting <= FIXED_RATE_MCS7_20M_400NS) -+ || (prAdapter->rWifiVar.eRateSetting >= FIXED_RATE_MCS0_40M_400NS && -+ prAdapter->rWifiVar.eRateSetting <= FIXED_RATE_MCS32_400NS)) -+ /* Force Short Preamble */ -+ prAdapter->rWifiVar.ePreambleType = PREAMBLE_TYPE_SHORT; -+ else -+ /* Force Long Preamble */ -+ prAdapter->rWifiVar.ePreambleType = PREAMBLE_TYPE_LONG; -+ -+ /* abort to re-connect */ -+#if 1 -+ DBGLOG(OID, TRACE, "DisBySwC\n"); -+ kalIndicateStatusAndComplete(prAdapter->prGlueInfo, -+ WLAN_STATUS_MEDIA_DISCONNECT, NULL, 0); -+#else -+ aisBssBeaconTimeout(prAdapter); -+#endif -+ -+ return WLAN_STATUS_SUCCESS; -+ -+ } else if (u2SubId == 0x1234) { -+ /* 1. Disable On-Lin Scan */ -+ /* 3. Disable FIFO FULL no ack */ -+ /* 4. Disable Roaming */ -+ /* Disalbe auto tx power */ -+ /* 2. Keep at CAM mode */ -+ /* 5. Disable Beacon Timeout Detection */ -+ rWlanStatus = nicEnterCtiaMode(prAdapter, TRUE, TRUE); -+ } else if (u2SubId == 0x1235) { -+ /* 1. Enaable On-Lin Scan */ -+ /* 3. Enable FIFO FULL no ack */ -+ /* 4. Enable Roaming */ -+ /* Enable auto tx power */ -+ /* 2. Keep at Fast PS */ -+ /* 5. Enable Beacon Timeout Detection */ -+ rWlanStatus = nicEnterCtiaMode(prAdapter, FALSE, TRUE); -+ } -+#if CFG_SUPPORT_HOTSPOT_OPTIMIZATION -+ else if (u2SubId == 0x1240) { -+ DBGLOG(P2P, TRACE, "Disable Hotspot Optimization!\n"); -+ -+ arHotspotOptimizationCfg.fgHotspotOptimizationEn = FALSE; -+ arHotspotOptimizationCfg.u4Level = 0; -+ wlanoidSendSetQueryP2PCmd(prAdapter, -+ CMD_ID_SET_HOTSPOT_OPTIMIZATION, -+ TRUE, -+ FALSE, -+ TRUE, -+ NULL, -+ NULL, -+ sizeof(CMD_HOTSPOT_OPTIMIZATION_CONFIG), -+ (PUINT_8) &arHotspotOptimizationCfg, NULL, 0); -+ } else if (u2SubId == 0x1241) { -+ DBGLOG(P2P, TRACE, "Enable Hotspot Optimization!\n"); -+ -+ arHotspotOptimizationCfg.fgHotspotOptimizationEn = TRUE; -+ arHotspotOptimizationCfg.u4Level = 5; -+ wlanoidSendSetQueryP2PCmd(prAdapter, -+ CMD_ID_SET_HOTSPOT_OPTIMIZATION, -+ TRUE, -+ FALSE, -+ TRUE, -+ NULL, -+ NULL, -+ sizeof(CMD_HOTSPOT_OPTIMIZATION_CONFIG), -+ (PUINT_8) &arHotspotOptimizationCfg, NULL, 0); -+ } -+#endif /* CFG_SUPPORT_HOTSPOT_OPTIMIZATION */ -+ else if (u2SubId == 0x1250) { -+ DBGLOG(OID, TRACE, "LTE_COEX: SW SET DUAL BAND\n"); -+ prAdapter->aePreferBand[NETWORK_TYPE_AIS_INDEX] = BAND_NULL; -+ } else if (u2SubId == 0x1251) { -+ DBGLOG(OID, TRACE, "LTE_COEX: SW SET 2.4G BAND\n"); -+ prAdapter->aePreferBand[NETWORK_TYPE_AIS_INDEX] = BAND_2G4; -+ } else if (u2SubId == 0x1252) { -+ DBGLOG(OID, TRACE, "LTE_COEX: SW SET 5G BAND\n"); -+ prAdapter->aePreferBand[NETWORK_TYPE_AIS_INDEX] = BAND_5G; -+ } -+#endif -+ } -+ break; -+ -+ case 0x9000: -+ default: -+ { -+ rCmdSwCtrl.u4Id = prSwCtrlInfo->u4Id; -+ rCmdSwCtrl.u4Data = prSwCtrlInfo->u4Data; -+ rWlanStatus = wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SW_DBG_CTRL, -+ TRUE, -+ FALSE, -+ TRUE, -+ nicCmdEventSetCommon, -+ nicOidCmdTimeoutCommon, -+ sizeof(CMD_SW_DBG_CTRL_T), -+ (PUINT_8) &rCmdSwCtrl, pvSetBuffer, u4SetBufferLen); -+ } -+ } /* switch(u2Id) */ -+ -+ return rWlanStatus; -+} -+ -+ /* wlanoidSetSwCtrlWrite */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to query EEPROM value. -+* -+* \param[in] pvAdapter Pointer to the Adapter structure. -+* \param[out] pvQueryBuf A pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_FAILURE -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryEepromRead(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ P_PARAM_CUSTOM_EEPROM_RW_STRUCT_T prEepromRwInfo; -+ CMD_ACCESS_EEPROM rCmdAccessEeprom; -+ -+ DEBUGFUNC("wlanoidQueryEepromRead"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4QueryInfoLen); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ -+ *pu4QueryInfoLen = sizeof(PARAM_CUSTOM_EEPROM_RW_STRUCT_T); -+ -+ if (u4QueryBufferLen < sizeof(PARAM_CUSTOM_EEPROM_RW_STRUCT_T)) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ prEepromRwInfo = (P_PARAM_CUSTOM_EEPROM_RW_STRUCT_T) pvQueryBuffer; -+ -+ kalMemZero(&rCmdAccessEeprom, sizeof(CMD_ACCESS_EEPROM)); -+ rCmdAccessEeprom.u2Offset = prEepromRwInfo->ucEepromIndex; -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_ACCESS_EEPROM, -+ FALSE, -+ TRUE, -+ TRUE, -+ nicCmdEventQueryEepromRead, -+ nicOidCmdTimeoutCommon, -+ sizeof(CMD_ACCESS_EEPROM), -+ (PUINT_8) &rCmdAccessEeprom, pvQueryBuffer, u4QueryBufferLen); -+ -+} /* wlanoidQueryEepromRead */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to write EEPROM value. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_FAILURE -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetEepromWrite(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ P_PARAM_CUSTOM_EEPROM_RW_STRUCT_T prEepromRwInfo; -+ CMD_ACCESS_EEPROM rCmdAccessEeprom; -+ -+ DEBUGFUNC("wlanoidSetEepromWrite"); -+ DBGLOG(OID, LOUD, "\n"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ *pu4SetInfoLen = sizeof(PARAM_CUSTOM_EEPROM_RW_STRUCT_T); -+ -+ if (u4SetBufferLen < sizeof(PARAM_CUSTOM_EEPROM_RW_STRUCT_T)) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ ASSERT(pvSetBuffer); -+ -+ prEepromRwInfo = (P_PARAM_CUSTOM_EEPROM_RW_STRUCT_T) pvSetBuffer; -+ -+ kalMemZero(&rCmdAccessEeprom, sizeof(CMD_ACCESS_EEPROM)); -+ rCmdAccessEeprom.u2Offset = prEepromRwInfo->ucEepromIndex; -+ rCmdAccessEeprom.u2Data = prEepromRwInfo->u2EepromData; -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_ACCESS_EEPROM, -+ TRUE, -+ FALSE, -+ TRUE, -+ nicCmdEventSetCommon, -+ nicOidCmdTimeoutCommon, -+ sizeof(CMD_ACCESS_EEPROM), -+ (PUINT_8) &rCmdAccessEeprom, pvSetBuffer, u4SetBufferLen); -+ -+} /* wlanoidSetEepromWrite */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to query the number of the successfully transmitted -+* packets. -+* -+* \param[in] pvAdapter Pointer to the Adapter structure. -+* \param[out] pvQueryBuf A pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryXmitOk(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ DEBUGFUNC("wlanoidQueryXmitOk"); -+ DBGLOG(OID, LOUD, "\n"); -+ -+ ASSERT(prAdapter); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ ASSERT(pu4QueryInfoLen); -+ -+ if (prAdapter->rAcpiState == ACPI_STATE_D3) { -+ DBGLOG(OID, WARN, "Fail in query receive error! (Adapter not ready). ACPI=D%d, Radio=%d\n", -+ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); -+ *pu4QueryInfoLen = sizeof(UINT_32); -+ return WLAN_STATUS_ADAPTER_NOT_READY; -+ } else if (u4QueryBufferLen < sizeof(UINT_32) -+ || (u4QueryBufferLen > sizeof(UINT_32) && u4QueryBufferLen < sizeof(UINT_64))) { -+ *pu4QueryInfoLen = sizeof(UINT_64); -+ return WLAN_STATUS_INVALID_LENGTH; -+ } -+#if CFG_ENABLE_STATISTICS_BUFFERING -+ if (IsBufferedStatisticsUsable(prAdapter) == TRUE) { -+ if (u4QueryBufferLen == sizeof(UINT_32)) { -+ *pu4QueryInfoLen = sizeof(UINT_32); -+ *(PUINT_32) pvQueryBuffer = (UINT_32) prAdapter->rStatStruct.rTransmittedFragmentCount.QuadPart; -+ } else { -+ *pu4QueryInfoLen = sizeof(UINT_64); -+ *(PUINT_64) pvQueryBuffer = (UINT_64) prAdapter->rStatStruct.rTransmittedFragmentCount.QuadPart; -+ } -+ -+ return WLAN_STATUS_SUCCESS; -+ } -+#endif -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_GET_STATISTICS, -+ FALSE, -+ TRUE, -+ TRUE, -+ nicCmdEventQueryXmitOk, -+ nicOidCmdTimeoutCommon, 0, NULL, pvQueryBuffer, u4QueryBufferLen); -+ -+} /* wlanoidQueryXmitOk */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to query the number of the successfully received -+* packets. -+* -+* \param[in] pvAdapter Pointer to the Adapter structure. -+* \param[out] pvQueryBuf A pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryRcvOk(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ DEBUGFUNC("wlanoidQueryRcvOk"); -+ DBGLOG(OID, LOUD, "\n"); -+ -+ ASSERT(prAdapter); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ ASSERT(pu4QueryInfoLen); -+ -+ if (prAdapter->rAcpiState == ACPI_STATE_D3) { -+ DBGLOG(OID, WARN, "Fail in query receive error! (Adapter not ready). ACPI=D%d, Radio=%d\n", -+ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); -+ *pu4QueryInfoLen = sizeof(UINT_32); -+ return WLAN_STATUS_ADAPTER_NOT_READY; -+ } else if (u4QueryBufferLen < sizeof(UINT_32) -+ || (u4QueryBufferLen > sizeof(UINT_32) && u4QueryBufferLen < sizeof(UINT_64))) { -+ *pu4QueryInfoLen = sizeof(UINT_64); -+ return WLAN_STATUS_INVALID_LENGTH; -+ } -+#if CFG_ENABLE_STATISTICS_BUFFERING -+ if (IsBufferedStatisticsUsable(prAdapter) == TRUE) { -+ if (u4QueryBufferLen == sizeof(UINT_32)) { -+ *pu4QueryInfoLen = sizeof(UINT_32); -+ *(PUINT_32) pvQueryBuffer = (UINT_32) prAdapter->rStatStruct.rReceivedFragmentCount.QuadPart; -+ } else { -+ *pu4QueryInfoLen = sizeof(UINT_64); -+ *(PUINT_64) pvQueryBuffer = (UINT_64) prAdapter->rStatStruct.rReceivedFragmentCount.QuadPart; -+ } -+ -+ return WLAN_STATUS_SUCCESS; -+ } -+#endif -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_GET_STATISTICS, -+ FALSE, -+ TRUE, -+ TRUE, -+ nicCmdEventQueryRecvOk, -+ nicOidCmdTimeoutCommon, 0, NULL, pvQueryBuffer, u4QueryBufferLen); -+ -+} /* wlanoidQueryRcvOk */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to query the number of frames that the driver -+* fails to transmit. -+* -+* \param[in] pvAdapter Pointer to the Adapter structure. -+* \param[out] pvQueryBuf A pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryXmitError(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ DEBUGFUNC("wlanoidQueryXmitError"); -+ DBGLOG(OID, LOUD, "\n"); -+ -+ ASSERT(prAdapter); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ ASSERT(pu4QueryInfoLen); -+ -+ if (prAdapter->rAcpiState == ACPI_STATE_D3) { -+ DBGLOG(OID, WARN, "Fail in query receive error! (Adapter not ready). ACPI=D%d, Radio=%d\n", -+ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); -+ *pu4QueryInfoLen = sizeof(UINT_32); -+ return WLAN_STATUS_ADAPTER_NOT_READY; -+ } else if (u4QueryBufferLen < sizeof(UINT_32) -+ || (u4QueryBufferLen > sizeof(UINT_32) && u4QueryBufferLen < sizeof(UINT_64))) { -+ *pu4QueryInfoLen = sizeof(UINT_64); -+ return WLAN_STATUS_INVALID_LENGTH; -+ } -+#if CFG_ENABLE_STATISTICS_BUFFERING -+ if (IsBufferedStatisticsUsable(prAdapter) == TRUE) { -+ if (u4QueryBufferLen == sizeof(UINT_32)) { -+ *pu4QueryInfoLen = sizeof(UINT_32); -+ *(PUINT_32) pvQueryBuffer = (UINT_32) prAdapter->rStatStruct.rFailedCount.QuadPart; -+ } else { -+ *pu4QueryInfoLen = sizeof(UINT_64); -+ *(PUINT_64) pvQueryBuffer = (UINT_64) prAdapter->rStatStruct.rFailedCount.QuadPart; -+ } -+ -+ return WLAN_STATUS_SUCCESS; -+ } -+#endif -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_GET_STATISTICS, -+ FALSE, -+ TRUE, -+ TRUE, -+ nicCmdEventQueryXmitError, -+ nicOidCmdTimeoutCommon, 0, NULL, pvQueryBuffer, u4QueryBufferLen); -+ -+} /* wlanoidQueryXmitError */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to query the number of frames successfully -+* transmitted after exactly one collision. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[out] pvQueryBuf A pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryXmitOneCollision(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ DEBUGFUNC("wlanoidQueryXmitOneCollision"); -+ DBGLOG(OID, LOUD, "\n"); -+ -+ ASSERT(prAdapter); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ ASSERT(pu4QueryInfoLen); -+ -+ if (prAdapter->rAcpiState == ACPI_STATE_D3) { -+ DBGLOG(OID, WARN, "Fail in query receive error! (Adapter not ready). ACPI=D%d, Radio=%d\n", -+ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); -+ *pu4QueryInfoLen = sizeof(UINT_32); -+ return WLAN_STATUS_ADAPTER_NOT_READY; -+ } else if (u4QueryBufferLen < sizeof(UINT_32) -+ || (u4QueryBufferLen > sizeof(UINT_32) && u4QueryBufferLen < sizeof(UINT_64))) { -+ *pu4QueryInfoLen = sizeof(UINT_64); -+ return WLAN_STATUS_INVALID_LENGTH; -+ } -+#if CFG_ENABLE_STATISTICS_BUFFERING -+ if (IsBufferedStatisticsUsable(prAdapter) == TRUE) { -+ if (u4QueryBufferLen == sizeof(UINT_32)) { -+ *pu4QueryInfoLen = sizeof(UINT_32); -+ *(PUINT_32) pvQueryBuffer = (UINT_32) -+ (prAdapter->rStatStruct.rMultipleRetryCount.QuadPart - -+ prAdapter->rStatStruct.rRetryCount.QuadPart); -+ } else { -+ *pu4QueryInfoLen = sizeof(UINT_64); -+ *(PUINT_64) pvQueryBuffer = (UINT_64) -+ (prAdapter->rStatStruct.rMultipleRetryCount.QuadPart - -+ prAdapter->rStatStruct.rRetryCount.QuadPart); -+ } -+ -+ return WLAN_STATUS_SUCCESS; -+ } -+#endif -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_GET_STATISTICS, -+ FALSE, -+ TRUE, -+ TRUE, -+ nicCmdEventQueryXmitOneCollision, -+ nicOidCmdTimeoutCommon, 0, NULL, pvQueryBuffer, u4QueryBufferLen); -+ -+} /* wlanoidQueryXmitOneCollision */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to query the number of frames successfully -+* transmitted after more than one collision. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[out] pvQueryBuf A pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryXmitMoreCollisions(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ DEBUGFUNC("wlanoidQueryXmitMoreCollisions"); -+ DBGLOG(OID, LOUD, "\n"); -+ -+ ASSERT(prAdapter); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ ASSERT(pu4QueryInfoLen); -+ -+ if (prAdapter->rAcpiState == ACPI_STATE_D3) { -+ DBGLOG(OID, WARN, "Fail in query receive error! (Adapter not ready). ACPI=D%d, Radio=%d\n", -+ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); -+ *pu4QueryInfoLen = sizeof(UINT_32); -+ return WLAN_STATUS_ADAPTER_NOT_READY; -+ } else if (u4QueryBufferLen < sizeof(UINT_32) -+ || (u4QueryBufferLen > sizeof(UINT_32) && u4QueryBufferLen < sizeof(UINT_64))) { -+ *pu4QueryInfoLen = sizeof(UINT_64); -+ return WLAN_STATUS_INVALID_LENGTH; -+ } -+#if CFG_ENABLE_STATISTICS_BUFFERING -+ if (IsBufferedStatisticsUsable(prAdapter) == TRUE) { -+ if (u4QueryBufferLen == sizeof(UINT_32)) { -+ *pu4QueryInfoLen = sizeof(UINT_32); -+ *(PUINT_32) pvQueryBuffer = (UINT_32) (prAdapter->rStatStruct.rMultipleRetryCount.QuadPart); -+ } else { -+ *pu4QueryInfoLen = sizeof(UINT_64); -+ *(PUINT_64) pvQueryBuffer = (UINT_64) (prAdapter->rStatStruct.rMultipleRetryCount.QuadPart); -+ } -+ -+ return WLAN_STATUS_SUCCESS; -+ } -+#endif -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_GET_STATISTICS, -+ FALSE, -+ TRUE, -+ TRUE, -+ nicCmdEventQueryXmitMoreCollisions, -+ nicOidCmdTimeoutCommon, 0, NULL, pvQueryBuffer, u4QueryBufferLen); -+} /* wlanoidQueryXmitMoreCollisions */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to query the number of frames -+* not transmitted due to excessive collisions. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvQueryBuffer Pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufferLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryXmitMaxCollisions(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ DEBUGFUNC("wlanoidQueryXmitMaxCollisions"); -+ DBGLOG(OID, LOUD, "\n"); -+ -+ ASSERT(prAdapter); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ ASSERT(pu4QueryInfoLen); -+ -+ if (prAdapter->rAcpiState == ACPI_STATE_D3) { -+ DBGLOG(OID, WARN, "Fail in query receive error! (Adapter not ready). ACPI=D%d, Radio=%d\n", -+ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); -+ *pu4QueryInfoLen = sizeof(UINT_32); -+ return WLAN_STATUS_ADAPTER_NOT_READY; -+ } else if (u4QueryBufferLen < sizeof(UINT_32) -+ || (u4QueryBufferLen > sizeof(UINT_32) && u4QueryBufferLen < sizeof(UINT_64))) { -+ *pu4QueryInfoLen = sizeof(UINT_64); -+ return WLAN_STATUS_INVALID_LENGTH; -+ } -+#if CFG_ENABLE_STATISTICS_BUFFERING -+ if (IsBufferedStatisticsUsable(prAdapter) == TRUE) { -+ if (u4QueryBufferLen == sizeof(UINT_32)) { -+ *pu4QueryInfoLen = sizeof(UINT_32); -+ *(PUINT_32) pvQueryBuffer = (UINT_32) prAdapter->rStatStruct.rFailedCount.QuadPart; -+ } else { -+ *pu4QueryInfoLen = sizeof(UINT_64); -+ *(PUINT_64) pvQueryBuffer = (UINT_64) prAdapter->rStatStruct.rFailedCount.QuadPart; -+ } -+ -+ return WLAN_STATUS_SUCCESS; -+ } -+#endif -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_GET_STATISTICS, -+ FALSE, -+ TRUE, -+ TRUE, -+ nicCmdEventQueryXmitMaxCollisions, -+ nicOidCmdTimeoutCommon, 0, NULL, pvQueryBuffer, u4QueryBufferLen); -+} /* wlanoidQueryXmitMaxCollisions */ -+ -+#define MTK_CUSTOM_OID_INTERFACE_VERSION 0x00006620 /* for WPDWifi DLL */ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to query current the OID interface version, -+* which is the interface between the application and driver. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvQueryBuffer Pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufferLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryOidInterfaceVersion(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ DEBUGFUNC("wlanoidQueryOidInterfaceVersion"); -+ -+ ASSERT(prAdapter); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ ASSERT(pu4QueryInfoLen); -+ -+ *(PUINT_32) pvQueryBuffer = MTK_CUSTOM_OID_INTERFACE_VERSION; -+ *pu4QueryInfoLen = sizeof(UINT_32); -+ -+ DBGLOG(OID, WARN, "Custom OID interface version: %#08X\n", *(PUINT_32) pvQueryBuffer); -+ -+ return WLAN_STATUS_SUCCESS; -+} /* wlanoidQueryOidInterfaceVersion */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to query current Multicast Address List. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvQueryBuffer Pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufferLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_BUFFER_TOO_SHORT -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryMulticastList(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+#ifndef LINUX -+ ASSERT(prAdapter); -+ ASSERT(pu4QueryInfoLen); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_MAC_MCAST_ADDR, -+ FALSE, -+ TRUE, -+ TRUE, -+ nicCmdEventQueryMcastAddr, -+ nicOidCmdTimeoutCommon, 0, NULL, pvQueryBuffer, u4QueryBufferLen); -+#else -+ return WLAN_STATUS_SUCCESS; -+#endif -+} /* end of wlanoidQueryMulticastList() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to set Multicast Address List. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer Pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+* \retval WLAN_STATUS_ADAPTER_NOT_READY -+* \retval WLAN_STATUS_MULTICAST_FULL -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetMulticastList(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ UINT_8 ucNetTypeIndex = NETWORK_TYPE_AIS_INDEX; /* Caller should provide this information */ -+ CMD_MAC_MCAST_ADDR rCmdMacMcastAddr; -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ /* The data must be a multiple of the Ethernet address size. */ -+ if ((u4SetBufferLen % MAC_ADDR_LEN)) { -+ DBGLOG(OID, WARN, "Invalid MC list length %u\n", u4SetBufferLen); -+ -+ *pu4SetInfoLen = (((u4SetBufferLen + MAC_ADDR_LEN) - 1) / MAC_ADDR_LEN) * MAC_ADDR_LEN; -+ -+ return WLAN_STATUS_INVALID_LENGTH; -+ } -+ -+ *pu4SetInfoLen = u4SetBufferLen; -+ -+ /* Verify if we can support so many multicast addresses. */ -+ if ((u4SetBufferLen / MAC_ADDR_LEN) > MAX_NUM_GROUP_ADDR) { -+ DBGLOG(OID, WARN, "Too many MC addresses\n"); -+ -+ return WLAN_STATUS_MULTICAST_FULL; -+ } -+ -+ /* NOTE(Kevin): Windows may set u4SetBufferLen == 0 && -+ * pvSetBuffer == NULL to clear exist Multicast List. -+ */ -+ if (u4SetBufferLen) -+ ASSERT(pvSetBuffer); -+ -+ if (prAdapter->rAcpiState == ACPI_STATE_D3) { -+ DBGLOG(OID, WARN, "Fail in set multicast list! (Adapter not ready). ACPI=D%d, Radio=%d\n", -+ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); -+ return WLAN_STATUS_ADAPTER_NOT_READY; -+ } -+ -+ rCmdMacMcastAddr.u4NumOfGroupAddr = u4SetBufferLen / MAC_ADDR_LEN; -+ rCmdMacMcastAddr.ucNetTypeIndex = ucNetTypeIndex; -+ kalMemCopy(rCmdMacMcastAddr.arAddress, pvSetBuffer, u4SetBufferLen); -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_MAC_MCAST_ADDR, -+ TRUE, -+ FALSE, -+ TRUE, -+ nicCmdEventSetCommon, -+ nicOidCmdTimeoutCommon, -+ sizeof(CMD_MAC_MCAST_ADDR), -+ (PUINT_8) &rCmdMacMcastAddr, pvSetBuffer, u4SetBufferLen); -+} /* end of wlanoidSetMulticastList() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to set Packet Filter. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer Pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+* \retval WLAN_STATUS_NOT_SUPPORTED -+* \retval WLAN_STATUS_ADAPTER_NOT_READY -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetCurrentPacketFilter(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ UINT_32 u4NewPacketFilter; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ if (u4SetBufferLen < sizeof(UINT_32)) { -+ *pu4SetInfoLen = sizeof(UINT_32); -+ DBGLOG(OID, INFO, "iput buffer is too small"); -+ return WLAN_STATUS_INVALID_LENGTH; -+ } -+ ASSERT(pvSetBuffer); -+ -+ /* Set the new packet filter. */ -+ u4NewPacketFilter = *(PUINT_32) pvSetBuffer; -+ -+ DBGLOG(OID, TRACE, "New packet filter: %#08x\n", u4NewPacketFilter); -+ -+ if (prAdapter->rAcpiState == ACPI_STATE_D3) { -+ DBGLOG(OID, WARN, "Fail in set current packet filter! (Adapter not ready). ACPI=D%d, Radio=%d\n", -+ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); -+ return WLAN_STATUS_ADAPTER_NOT_READY; -+ } -+ -+ do { -+ /* Verify the bits of the new packet filter. If any bits are set that -+ we don't support, leave. */ -+ if (u4NewPacketFilter & ~(PARAM_PACKET_FILTER_SUPPORTED)) { -+ rStatus = WLAN_STATUS_NOT_SUPPORTED; -+ break; -+ } -+#if DBG -+ /* Need to enable or disable promiscuous support depending on the new -+ filter. */ -+ if (u4NewPacketFilter & PARAM_PACKET_FILTER_PROMISCUOUS) -+ DBGLOG(OID, TRACE, "Enable promiscuous mode\n"); -+ else -+ DBGLOG(OID, TRACE, "Disable promiscuous mode\n"); -+ -+ if (u4NewPacketFilter & PARAM_PACKET_FILTER_ALL_MULTICAST) -+ DBGLOG(OID, TRACE, "Enable all-multicast mode\n"); -+ else if (u4NewPacketFilter & PARAM_PACKET_FILTER_MULTICAST) -+ DBGLOG(OID, TRACE, "Enable multicast\n"); -+ else -+ DBGLOG(OID, TRACE, "Disable multicast\n"); -+ -+ if (u4NewPacketFilter & PARAM_PACKET_FILTER_BROADCAST) -+ DBGLOG(OID, TRACE, "Enable Broadcast\n"); -+ else -+ DBGLOG(OID, TRACE, "Disable Broadcast\n"); -+#endif -+ } while (FALSE); -+ -+ if (rStatus == WLAN_STATUS_SUCCESS) { -+ /* Store the packet filter */ -+ -+ prAdapter->u4OsPacketFilter &= PARAM_PACKET_FILTER_P2P_MASK; -+ prAdapter->u4OsPacketFilter |= u4NewPacketFilter; -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SET_RX_FILTER, -+ TRUE, -+ FALSE, -+ TRUE, -+ nicCmdEventSetCommon, -+ nicOidCmdTimeoutCommon, -+ sizeof(UINT_32), -+ (PUINT_8) &prAdapter->u4OsPacketFilter, pvSetBuffer, u4SetBufferLen); -+ } else { -+ return rStatus; -+ } -+} /* wlanoidSetCurrentPacketFilter */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to query current packet filter. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvQueryBuffer Pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufferLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryCurrentPacketFilter(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ DEBUGFUNC("wlanoidQueryCurrentPacketFilter"); -+ ASSERT(prAdapter); -+ ASSERT(pu4QueryInfoLen); -+ -+ *pu4QueryInfoLen = sizeof(UINT_32); -+ -+ if (u4QueryBufferLen >= sizeof(UINT_32)) { -+ ASSERT(pvQueryBuffer); -+ *(PUINT_32) pvQueryBuffer = prAdapter->u4OsPacketFilter; -+ } -+ -+ return WLAN_STATUS_SUCCESS; -+} /* wlanoidQueryCurrentPacketFilter */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to query ACPI device power state. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvQueryBuffer Pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufferLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryAcpiDevicePowerState(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+#if DBG -+ PPARAM_DEVICE_POWER_STATE prPowerState; -+#endif -+ -+ DEBUGFUNC("wlanoidQueryAcpiDevicePowerState"); -+ ASSERT(prAdapter); -+ ASSERT(pu4QueryInfoLen); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ -+ *pu4QueryInfoLen = sizeof(PARAM_DEVICE_POWER_STATE); -+ -+#if DBG -+ prPowerState = (PPARAM_DEVICE_POWER_STATE) pvQueryBuffer; -+ switch (*prPowerState) { -+ case ParamDeviceStateD0: -+ DBGLOG(OID, INFO, "Query Power State: D0\n"); -+ break; -+ case ParamDeviceStateD1: -+ DBGLOG(OID, INFO, "Query Power State: D1\n"); -+ break; -+ case ParamDeviceStateD2: -+ DBGLOG(OID, INFO, "Query Power State: D2\n"); -+ break; -+ case ParamDeviceStateD3: -+ DBGLOG(OID, INFO, "Query Power State: D3\n"); -+ break; -+ default: -+ break; -+ } -+#endif -+ -+ /* Since we will disconnect the newwork, therefore we do not -+ need to check queue empty */ -+ *(PPARAM_DEVICE_POWER_STATE) pvQueryBuffer = ParamDeviceStateD3; -+ /* WARNLOG(("Ready to transition to D3\n")); */ -+ return WLAN_STATUS_SUCCESS; -+ -+} /* pwrmgtQueryPower */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to set ACPI device power state. -+* -+* \param[in] pvAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetAcpiDevicePowerState(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ PPARAM_DEVICE_POWER_STATE prPowerState; -+ BOOLEAN fgRetValue = TRUE; -+ -+ DEBUGFUNC("wlanoidSetAcpiDevicePowerState"); -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ *pu4SetInfoLen = sizeof(PARAM_DEVICE_POWER_STATE); -+ -+ ASSERT(pvSetBuffer); -+ prPowerState = (PPARAM_DEVICE_POWER_STATE) pvSetBuffer; -+ switch (*prPowerState) { -+ case ParamDeviceStateD0: -+ DBGLOG(OID, INFO, "Set Power State: D0\n"); -+ kalDevSetPowerState(prAdapter->prGlueInfo, (UINT_32) ParamDeviceStateD0); -+ fgRetValue = nicpmSetAcpiPowerD0(prAdapter); -+ break; -+ case ParamDeviceStateD1: -+ DBGLOG(OID, INFO, "Set Power State: D1\n"); -+ /* no break here */ -+ case ParamDeviceStateD2: -+ DBGLOG(OID, INFO, "Set Power State: D2\n"); -+ /* no break here */ -+ case ParamDeviceStateD3: -+ DBGLOG(OID, INFO, "Set Power State: D3\n"); -+ fgRetValue = nicpmSetAcpiPowerD3(prAdapter); -+ kalDevSetPowerState(prAdapter->prGlueInfo, (UINT_32) ParamDeviceStateD3); -+ break; -+ default: -+ break; -+ } -+ -+ if (fgRetValue == TRUE) -+ return WLAN_STATUS_SUCCESS; -+ else -+ return WLAN_STATUS_FAILURE; -+} /* end of wlanoidSetAcpiDevicePowerState() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to query the current fragmentation threshold. -+* -+* \param[in] pvAdapter Pointer to the Adapter structure. -+* \param[out] pvQueryBuffer A pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufferLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_BUFFER_TOO_SHORT -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryFragThreshold(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ DEBUGFUNC("wlanoidQueryFragThreshold"); -+ -+ ASSERT(prAdapter); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ ASSERT(pu4QueryInfoLen); -+ -+ DBGLOG(OID, LOUD, "\n"); -+ -+#if CFG_TX_FRAGMENT -+ -+ return WLAN_STATUS_SUCCESS; -+ -+#else -+ -+ return WLAN_STATUS_NOT_SUPPORTED; -+#endif /* CFG_TX_FRAGMENT */ -+ -+} /* end of wlanoidQueryFragThreshold() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to set a new fragmentation threshold to the -+* driver. -+* -+* \param[in] pvAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_DATA -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetFragThreshold(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+#if CFG_TX_FRAGMENT -+ -+ return WLAN_STATUS_SUCCESS; -+ -+#else -+ -+ return WLAN_STATUS_NOT_SUPPORTED; -+#endif /* CFG_TX_FRAGMENT */ -+ -+} /* end of wlanoidSetFragThreshold() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to query the current RTS threshold. -+* -+* \param[in] pvAdapter Pointer to the Adapter structure. -+* \param[out] pvQueryBuffer A pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufferLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_BUFFER_TOO_SHORT -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryRtsThreshold(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ DEBUGFUNC("wlanoidQueryRtsThreshold"); -+ -+ ASSERT(prAdapter); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ ASSERT(pu4QueryInfoLen); -+ -+ DBGLOG(OID, LOUD, "\n"); -+ -+ if (u4QueryBufferLen < sizeof(PARAM_RTS_THRESHOLD)) { -+ *pu4QueryInfoLen = sizeof(PARAM_RTS_THRESHOLD); -+ return WLAN_STATUS_BUFFER_TOO_SHORT; -+ } -+ -+ *((PARAM_RTS_THRESHOLD *) pvQueryBuffer) = prAdapter->rWlanInfo.eRtsThreshold; -+ -+ return WLAN_STATUS_SUCCESS; -+ -+} /* wlanoidQueryRtsThreshold */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to set a new RTS threshold to the driver. -+* -+* \param[in] pvAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_DATA -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetRtsThreshold(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ PARAM_RTS_THRESHOLD *prRtsThreshold; -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ *pu4SetInfoLen = sizeof(PARAM_RTS_THRESHOLD); -+ if (u4SetBufferLen < sizeof(PARAM_RTS_THRESHOLD)) { -+ DBGLOG(OID, WARN, "Invalid length %u\n", u4SetBufferLen); -+ return WLAN_STATUS_INVALID_LENGTH; -+ } -+ -+ prRtsThreshold = (PARAM_RTS_THRESHOLD *) pvSetBuffer; -+ *prRtsThreshold = prAdapter->rWlanInfo.eRtsThreshold; -+ -+ return WLAN_STATUS_SUCCESS; -+ -+} /* wlanoidSetRtsThreshold */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is used to turn radio off. -+* -+* \param[in] pvAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_ADAPTER_NOT_READY -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetDisassociate(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ P_MSG_AIS_ABORT_T prAisAbortMsg; -+ -+ DEBUGFUNC("wlanoidSetDisassociate"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ *pu4SetInfoLen = 0; -+ -+ if (prAdapter->rAcpiState == ACPI_STATE_D3) { -+ DBGLOG(OID, WARN, "Fail in set disassociate! (Adapter not ready). ACPI=D%d, Radio=%d\n", -+ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); -+ return WLAN_STATUS_ADAPTER_NOT_READY; -+ } -+ -+ /* prepare message to AIS */ -+ prAdapter->rWifiVar.rConnSettings.fgIsConnReqIssued = FALSE; -+ -+ /* Send AIS Abort Message */ -+ prAisAbortMsg = (P_MSG_AIS_ABORT_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_AIS_ABORT_T)); -+ if (!prAisAbortMsg) { -+ ASSERT(0); -+ return WLAN_STATUS_FAILURE; -+ } -+ -+ prAisAbortMsg->rMsgHdr.eMsgId = MID_OID_AIS_FSM_JOIN_REQ; -+ prAisAbortMsg->ucReasonOfDisconnect = DISCONNECT_REASON_CODE_NEW_CONNECTION; -+ prAisAbortMsg->fgDelayIndication = FALSE; -+ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prAisAbortMsg, MSG_SEND_METHOD_BUF); -+ -+ /* indicate for disconnection */ -+ if (kalGetMediaStateIndicated(prAdapter->prGlueInfo) == PARAM_MEDIA_STATE_CONNECTED) { -+ DBGLOG(OID, INFO, "DisconnectByOid\n"); -+ kalIndicateStatusAndComplete(prAdapter->prGlueInfo, WLAN_STATUS_MEDIA_DISCONNECT_LOCALLY, NULL, 0); -+ } -+#if !defined(LINUX) -+ prAdapter->fgIsRadioOff = TRUE; -+#endif -+ -+ return WLAN_STATUS_SUCCESS; -+} /* wlanoidSetDisassociate */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is used to query the power save profile. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[out] pvQueryBuf A pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \return WLAN_STATUS_SUCCESS -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQuery802dot11PowerSaveProfile(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ DEBUGFUNC("wlanoidQuery802dot11PowerSaveProfile"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4QueryInfoLen); -+ -+ if (u4QueryBufferLen != 0) { -+ ASSERT(pvQueryBuffer); -+ -+/* *(PPARAM_POWER_MODE) pvQueryBuffer = (PARAM_POWER_MODE)(prAdapter->rWlanInfo.ePowerSaveMode.ucPsProfile); */ -+ *(PPARAM_POWER_MODE) pvQueryBuffer = -+ (PARAM_POWER_MODE) (prAdapter->rWlanInfo.arPowerSaveMode[NETWORK_TYPE_AIS_INDEX].ucPsProfile); -+ *pu4QueryInfoLen = sizeof(PARAM_POWER_MODE); -+ -+ /* hack for CTIA power mode setting function */ -+ if (prAdapter->fgEnCtiaPowerMode) { -+ /* set to non-zero value (to prevent MMI query 0, before it intends to set 0, */ -+ /* which will skip its following state machine) */ -+ *(PPARAM_POWER_MODE) pvQueryBuffer = (PARAM_POWER_MODE) 2; -+ } -+ } -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is used to set the power save profile. -+* -+* \param[in] pvAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSet802dot11PowerSaveProfile(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ WLAN_STATUS status; -+ PARAM_POWER_MODE ePowerMode; -+ -+ DEBUGFUNC("wlanoidSet802dot11PowerSaveProfile"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ *pu4SetInfoLen = sizeof(PARAM_POWER_MODE); -+ if (u4SetBufferLen < sizeof(PARAM_POWER_MODE)) { -+ DBGLOG(OID, WARN, "Invalid length %u\n", u4SetBufferLen); -+ return WLAN_STATUS_INVALID_LENGTH; -+ } else if (*(PPARAM_POWER_MODE) pvSetBuffer >= Param_PowerModeMax) { -+ /* WARNLOG(("Invalid power mode %d\n", */ -+ /* *(PPARAM_POWER_MODE) pvSetBuffer)); */ -+ return WLAN_STATUS_INVALID_DATA; -+ } -+ -+ ePowerMode = *(PPARAM_POWER_MODE) pvSetBuffer; -+ -+ if (prAdapter->fgEnCtiaPowerMode) { -+ if (ePowerMode == Param_PowerModeCAM) -+ ; -+ else { -+ /* User setting to PS mode (Param_PowerModeMAX_PSP or Param_PowerModeFast_PSP) */ -+ -+ if (prAdapter->u4CtiaPowerMode == 0) -+ /* force to keep in CAM mode */ -+ ePowerMode = Param_PowerModeCAM; -+ else if (prAdapter->u4CtiaPowerMode == 1) -+ ePowerMode = Param_PowerModeMAX_PSP; -+ else if (prAdapter->u4CtiaPowerMode == 2) -+ ePowerMode = Param_PowerModeFast_PSP; -+ } -+ } -+ -+ status = nicConfigPowerSaveProfile(prAdapter, NETWORK_TYPE_AIS_INDEX, ePowerMode, TRUE); -+ -+ switch (ePowerMode) { -+ case Param_PowerModeCAM: -+ DBGLOG(OID, INFO, "Set Wi-Fi PS mode to CAM (%d)\n", ePowerMode); -+ break; -+ case Param_PowerModeMAX_PSP: -+ DBGLOG(OID, INFO, "Set Wi-Fi PS mode to MAX PS (%d)\n", ePowerMode); -+ break; -+ case Param_PowerModeFast_PSP: -+ DBGLOG(OID, INFO, "Set Wi-Fi PS mode to FAST PS (%d)\n", ePowerMode); -+ break; -+ default: -+ DBGLOG(OID, INFO, "invalid Wi-Fi PS mode setting (%d)\n", ePowerMode); -+ break; -+ } -+ -+ return status; -+ -+} /* end of wlanoidSetAcpiDevicePowerStateMode() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to query current status of AdHoc Mode. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvQueryBuffer Pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufferLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_BUFFER_TOO_SHORT -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryAdHocMode(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ return WLAN_STATUS_SUCCESS; -+} /* end of wlanoidQueryAdHocMode() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to set AdHoc Mode. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer Pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+* \retval WLAN_STATUS_INVALID_DATA -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetAdHocMode(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ return WLAN_STATUS_SUCCESS; -+} /* end of wlanoidSetAdHocMode() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to query RF frequency. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvQueryBuffer Pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufferLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_BUFFER_TOO_SHORT -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryFrequency(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ DEBUGFUNC("wlanoidQueryFrequency"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4QueryInfoLen); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ -+ if (u4QueryBufferLen < sizeof(UINT_32)) -+ return WLAN_STATUS_BUFFER_TOO_SHORT; -+ -+ if (prAdapter->rWifiVar.rConnSettings.eOPMode == NET_TYPE_INFRA) { -+ if (kalGetMediaStateIndicated(prAdapter->prGlueInfo) == PARAM_MEDIA_STATE_CONNECTED) { -+ *(PUINT_32) pvQueryBuffer = -+ nicChannelNum2Freq(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX].ucPrimaryChannel); -+ } else { -+ *(PUINT_32) pvQueryBuffer = 0; -+ } -+ } else { -+ *(PUINT_32) pvQueryBuffer = nicChannelNum2Freq(prAdapter->rWifiVar.rConnSettings.ucAdHocChannelNum); -+ } -+ -+ return WLAN_STATUS_SUCCESS; -+} /* end of wlanoidQueryFrequency() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to set RF frequency by User Settings. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvQueryBuffer Pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufferLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+* \retval WLAN_STATUS_INVALID_DATA -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetFrequency(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ PUINT_32 pu4FreqInKHz; -+ -+ DEBUGFUNC("wlanoidSetFrequency"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ *pu4SetInfoLen = sizeof(UINT_32); -+ -+ if (u4SetBufferLen < sizeof(UINT_32)) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ ASSERT(pvSetBuffer); -+ pu4FreqInKHz = (PUINT_32) pvSetBuffer; -+ -+ prAdapter->rWifiVar.rConnSettings.ucAdHocChannelNum = (UINT_8) nicFreq2ChannelNum(*pu4FreqInKHz); -+ prAdapter->rWifiVar.rConnSettings.eAdHocBand = *pu4FreqInKHz < 5000000 ? BAND_2G4 : BAND_5G; -+ -+ return WLAN_STATUS_SUCCESS; -+} /* end of wlanoidSetFrequency() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to set 802.11 channel of the radio frequency. -+* This is a proprietary function call to Lunux currently. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+* \retval WLAN_STATUS_INVALID_DATA -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetChannel(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ ASSERT(0); /* // */ -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to query the Beacon Interval from User Settings. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvQueryBuffer Pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufferLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_BUFFER_TOO_SHORT -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryBeaconInterval(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ DEBUGFUNC("wlanoidQueryBeaconInterval"); -+ ASSERT(prAdapter); -+ ASSERT(pu4QueryInfoLen); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ -+ *pu4QueryInfoLen = sizeof(UINT_32); -+ -+ if (u4QueryBufferLen < sizeof(UINT_32)) -+ return WLAN_STATUS_BUFFER_TOO_SHORT; -+ -+ if (kalGetMediaStateIndicated(prAdapter->prGlueInfo) == PARAM_MEDIA_STATE_CONNECTED) { -+ if (prAdapter->rWifiVar.rConnSettings.eOPMode == NET_TYPE_INFRA) -+ *(PUINT_32) pvQueryBuffer = prAdapter->rWlanInfo.rCurrBssId.rConfiguration.u4BeaconPeriod; -+ else -+ *(PUINT_32) pvQueryBuffer = (UINT_32) prAdapter->rWlanInfo.u2BeaconPeriod; -+ } else { -+ if (prAdapter->rWifiVar.rConnSettings.eOPMode == NET_TYPE_INFRA) -+ *(PUINT_32) pvQueryBuffer = 0; -+ else -+ *(PUINT_32) pvQueryBuffer = (UINT_32) prAdapter->rWlanInfo.u2BeaconPeriod; -+ } -+ -+ return WLAN_STATUS_SUCCESS; -+} /* end of wlanoidQueryBeaconInterval() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to set the Beacon Interval to User Settings. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer Pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+* \retval WLAN_STATUS_INVALID_DATA -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetBeaconInterval(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ PUINT_32 pu4BeaconInterval; -+ -+ DEBUGFUNC("wlanoidSetBeaconInterval"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ *pu4SetInfoLen = sizeof(UINT_32); -+ if (u4SetBufferLen < sizeof(UINT_32)) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ ASSERT(pvSetBuffer); -+ pu4BeaconInterval = (PUINT_32) pvSetBuffer; -+ -+ if ((*pu4BeaconInterval < DOT11_BEACON_PERIOD_MIN) || (*pu4BeaconInterval > DOT11_BEACON_PERIOD_MAX)) { -+ DBGLOG(OID, TRACE, "Invalid Beacon Interval = %u\n", *pu4BeaconInterval); -+ return WLAN_STATUS_INVALID_DATA; -+ } -+ -+ prAdapter->rWlanInfo.u2BeaconPeriod = (UINT_16) *pu4BeaconInterval; -+ -+ DBGLOG(OID, INFO, "Set beacon interval: %d\n", prAdapter->rWlanInfo.u2BeaconPeriod); -+ -+ return WLAN_STATUS_SUCCESS; -+} /* end of wlanoidSetBeaconInterval() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to query the ATIM window from User Settings. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvQueryBuffer Pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufferLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_BUFFER_TOO_SHORT -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryAtimWindow(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ DEBUGFUNC("wlanoidQueryAtimWindow"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4QueryInfoLen); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ -+ *pu4QueryInfoLen = sizeof(UINT_32); -+ -+ if (u4QueryBufferLen < sizeof(UINT_32)) -+ return WLAN_STATUS_BUFFER_TOO_SHORT; -+ -+ if (prAdapter->rWifiVar.rConnSettings.eOPMode == NET_TYPE_INFRA) -+ *(PUINT_32) pvQueryBuffer = 0; -+ else -+ *(PUINT_32) pvQueryBuffer = (UINT_32) prAdapter->rWlanInfo.u2AtimWindow; -+ -+ return WLAN_STATUS_SUCCESS; -+ -+} /* end of wlanoidQueryAtimWindow() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to set the ATIM window to User Settings. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer Pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+* \retval WLAN_STATUS_INVALID_DATA -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetAtimWindow(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ PUINT_32 pu4AtimWindow; -+ -+ DEBUGFUNC("wlanoidSetAtimWindow"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ *pu4SetInfoLen = sizeof(UINT_32); -+ -+ if (u4SetBufferLen < sizeof(UINT_32)) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ ASSERT(pvSetBuffer); -+ pu4AtimWindow = (PUINT_32) pvSetBuffer; -+ -+ prAdapter->rWlanInfo.u2AtimWindow = (UINT_16) *pu4AtimWindow; -+ -+ return WLAN_STATUS_SUCCESS; -+} /* end of wlanoidSetAtimWindow() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to Set the MAC address which is currently used by the NIC. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer Pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+* \retval WLAN_STATUS_INVALID_DATA -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetCurrentAddr(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ ASSERT(0); /* // */ -+ -+ return WLAN_STATUS_SUCCESS; -+} /* end of wlanoidSetCurrentAddr() */ -+ -+#if CFG_TCP_IP_CHKSUM_OFFLOAD -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Setting the checksum offload function. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer Pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+* \retval WLAN_STATUS_ADAPTER_NOT_READY -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetCSUMOffload(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ UINT_32 i, u4CSUMFlags; -+ CMD_BASIC_CONFIG rCmdBasicConfig; -+ -+ DEBUGFUNC("wlanoidSetCSUMOffload"); -+ DBGLOG(OID, LOUD, "\n"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ *pu4SetInfoLen = sizeof(UINT_32); -+ -+ if (u4SetBufferLen < sizeof(UINT_32)) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ ASSERT(pvSetBuffer); -+ u4CSUMFlags = *(PUINT_32) pvSetBuffer; -+ -+ kalMemZero(&rCmdBasicConfig, sizeof(CMD_BASIC_CONFIG)); -+ -+ for (i = 0; i < 6; i++) { /* set to broadcast address for not-specified */ -+ rCmdBasicConfig.rMyMacAddr[i] = 0xff; -+ } -+ -+ rCmdBasicConfig.ucNative80211 = 0; /* @FIXME: for Vista */ -+ -+ if (u4CSUMFlags & CSUM_OFFLOAD_EN_TX_TCP) -+ rCmdBasicConfig.rCsumOffload.u2TxChecksum |= BIT(2); -+ -+ if (u4CSUMFlags & CSUM_OFFLOAD_EN_TX_UDP) -+ rCmdBasicConfig.rCsumOffload.u2TxChecksum |= BIT(1); -+ -+ if (u4CSUMFlags & CSUM_OFFLOAD_EN_TX_IP) -+ rCmdBasicConfig.rCsumOffload.u2TxChecksum |= BIT(0); -+ -+ if (u4CSUMFlags & CSUM_OFFLOAD_EN_RX_TCP) -+ rCmdBasicConfig.rCsumOffload.u2RxChecksum |= BIT(2); -+ -+ if (u4CSUMFlags & CSUM_OFFLOAD_EN_RX_UDP) -+ rCmdBasicConfig.rCsumOffload.u2RxChecksum |= BIT(1); -+ -+ if (u4CSUMFlags & (CSUM_OFFLOAD_EN_RX_IPv4 | CSUM_OFFLOAD_EN_RX_IPv6)) -+ rCmdBasicConfig.rCsumOffload.u2RxChecksum |= BIT(0); -+ -+ prAdapter->u4CSUMFlags = u4CSUMFlags; -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_BASIC_CONFIG, -+ TRUE, -+ FALSE, -+ TRUE, -+ nicCmdEventSetCommon, -+ nicOidCmdTimeoutCommon, -+ sizeof(CMD_BASIC_CONFIG), (PUINT_8) &rCmdBasicConfig, pvSetBuffer, u4SetBufferLen); -+} -+#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Setting the IP address for pattern search function. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \return WLAN_STATUS_SUCCESS -+* \return WLAN_STATUS_ADAPTER_NOT_READY -+* \return WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetNetworkAddress(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ UINT_32 i, j; -+ P_CMD_SET_NETWORK_ADDRESS_LIST prCmdNetworkAddressList; -+ P_PARAM_NETWORK_ADDRESS_LIST prNetworkAddressList = (P_PARAM_NETWORK_ADDRESS_LIST) pvSetBuffer; -+ P_PARAM_NETWORK_ADDRESS prNetworkAddress; -+ P_PARAM_NETWORK_ADDRESS_IP prNetAddrIp; -+ UINT_32 u4IpAddressCount, u4CmdSize; -+ PUINT_8 pucBuf = (PUINT_8) pvSetBuffer; -+#if CFG_ENABLE_GTK_FRAME_FILTER -+ UINT_32 u4IpV4AddrListSize; -+ P_BSS_INFO_T prBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]; -+#endif -+ -+ DEBUGFUNC("wlanoidSetNetworkAddress"); -+ DBGLOG(OID, LOUD, "\n"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ *pu4SetInfoLen = 4; -+ -+ if (u4SetBufferLen < sizeof(PARAM_NETWORK_ADDRESS_LIST)) -+ return WLAN_STATUS_INVALID_DATA; -+ -+ *pu4SetInfoLen = 0; -+ u4IpAddressCount = 0; -+ -+ prNetworkAddress = prNetworkAddressList->arAddress; -+ for (i = 0; i < prNetworkAddressList->u4AddressCount; i++) { -+ if (prNetworkAddress->u2AddressType == PARAM_PROTOCOL_ID_TCP_IP && -+ prNetworkAddress->u2AddressLength == sizeof(PARAM_NETWORK_ADDRESS_IP)) { -+ u4IpAddressCount++; -+ } -+ -+ prNetworkAddress = (P_PARAM_NETWORK_ADDRESS) (prNetworkAddress + -+ (ULONG) (prNetworkAddress->u2AddressLength + -+ OFFSET_OF(PARAM_NETWORK_ADDRESS, aucAddress))); -+ } -+ -+ /* construct payload of command packet */ -+ u4CmdSize = OFFSET_OF(CMD_SET_NETWORK_ADDRESS_LIST, arNetAddress) + -+ sizeof(IPV4_NETWORK_ADDRESS) * u4IpAddressCount; -+ if (u4IpAddressCount == 0) -+ u4CmdSize = sizeof(CMD_SET_NETWORK_ADDRESS_LIST); -+ -+ prCmdNetworkAddressList = (P_CMD_SET_NETWORK_ADDRESS_LIST) kalMemAlloc(u4CmdSize, VIR_MEM_TYPE); -+ -+ if (prCmdNetworkAddressList == NULL) -+ return WLAN_STATUS_FAILURE; -+ -+#if CFG_ENABLE_GTK_FRAME_FILTER -+ u4IpV4AddrListSize = OFFSET_OF(IPV4_NETWORK_ADDRESS_LIST, arNetAddr) + -+ (u4IpAddressCount * sizeof(IPV4_NETWORK_ADDRESS)); -+ if (prBssInfo->prIpV4NetAddrList) -+ FREE_IPV4_NETWORK_ADDR_LIST(prBssInfo->prIpV4NetAddrList); -+ prBssInfo->prIpV4NetAddrList = (P_IPV4_NETWORK_ADDRESS_LIST) kalMemAlloc(u4IpV4AddrListSize, VIR_MEM_TYPE); -+ if (prBssInfo->prIpV4NetAddrList == NULL) { -+ kalMemFree(prCmdNetworkAddressList, VIR_MEM_TYPE, u4CmdSize); -+ return WLAN_STATUS_FAILURE; -+ } -+ prBssInfo->prIpV4NetAddrList->ucAddrCount = (UINT_8) u4IpAddressCount; -+#endif -+ -+ /* fill P_CMD_SET_NETWORK_ADDRESS_LIST */ -+ prCmdNetworkAddressList->ucNetTypeIndex = NETWORK_TYPE_AIS_INDEX; -+ -+ /* only to set IP address to FW once ARP filter is enabled */ -+ if (prAdapter->fgEnArpFilter) { -+ prCmdNetworkAddressList->ucAddressCount = (UINT_8) u4IpAddressCount; -+ prNetworkAddress = prNetworkAddressList->arAddress; -+ -+ DBGLOG(OID, INFO, "u4IpAddressCount (%u)\n", u4IpAddressCount); -+ -+ for (i = 0, j = 0; i < prNetworkAddressList->u4AddressCount; i++) { -+ if (prNetworkAddress->u2AddressType == PARAM_PROTOCOL_ID_TCP_IP && -+ prNetworkAddress->u2AddressLength == sizeof(PARAM_NETWORK_ADDRESS_IP)) { -+ prNetAddrIp = (P_PARAM_NETWORK_ADDRESS_IP) prNetworkAddress->aucAddress; -+ -+ kalMemCopy(prCmdNetworkAddressList->arNetAddress[j].aucIpAddr, -+ &(prNetAddrIp->in_addr), sizeof(UINT_32)); -+ -+#if CFG_ENABLE_GTK_FRAME_FILTER -+ kalMemCopy(prBssInfo->prIpV4NetAddrList->arNetAddr[j].aucIpAddr, -+ &(prNetAddrIp->in_addr), sizeof(UINT_32)); -+#endif -+ -+ j++; -+ -+ pucBuf = (PUINT_8) &prNetAddrIp->in_addr; -+ DBGLOG(OID, INFO, -+ "prNetAddrIp->in_addr:%d:%d:%d:%d\n", pucBuf[0], pucBuf[1], pucBuf[2], -+ pucBuf[3]); -+ } -+ -+ prNetworkAddress = (P_PARAM_NETWORK_ADDRESS) (prNetworkAddress + -+ (ULONG) (prNetworkAddress->u2AddressLength + -+ OFFSET_OF(PARAM_NETWORK_ADDRESS, -+ aucAddress))); -+ } -+ -+ } else { -+ prCmdNetworkAddressList->ucAddressCount = 0; -+ } -+ -+ rStatus = wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SET_IP_ADDRESS, -+ TRUE, -+ FALSE, -+ TRUE, -+ nicCmdEventSetIpAddress, -+ nicOidCmdTimeoutCommon, -+ u4CmdSize, (PUINT_8) prCmdNetworkAddressList, pvSetBuffer, u4SetBufferLen); -+ -+ kalMemFree(prCmdNetworkAddressList, VIR_MEM_TYPE, u4CmdSize); -+ return rStatus; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Set driver to switch into RF test mode -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set, -+* should be NULL -+* \param[in] u4SetBufferLen The length of the set buffer, should be 0 -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \return WLAN_STATUS_SUCCESS -+* \return WLAN_STATUS_ADAPTER_NOT_READY -+* \return WLAN_STATUS_INVALID_DATA -+* \return WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidRftestSetTestMode(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ WLAN_STATUS rStatus; -+ CMD_TEST_CTRL_T rCmdTestCtrl; -+ -+ DEBUGFUNC("wlanoidRftestSetTestMode"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pvSetBuffer); -+ ASSERT(pu4SetInfoLen); -+ -+ *pu4SetInfoLen = 0; -+ -+ if (u4SetBufferLen == 0) { -+ if (prAdapter->fgTestMode == FALSE) { -+ /* switch to RF Test mode */ -+ rCmdTestCtrl.ucAction = 0; /* Switch mode */ -+ rCmdTestCtrl.u.u4OpMode = 1; /* RF test mode */ -+ -+ rStatus = wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_TEST_MODE, -+ TRUE, -+ TRUE, -+ TRUE, -+ nicCmdEventEnterRfTest, -+ nicOidCmdEnterRFTestTimeout, -+ sizeof(CMD_TEST_CTRL_T), -+ (PUINT_8) &rCmdTestCtrl, pvSetBuffer, u4SetBufferLen); -+ } else { -+ /* already in test mode .. */ -+ rStatus = WLAN_STATUS_SUCCESS; -+ } -+ } else { -+ rStatus = WLAN_STATUS_INVALID_DATA; -+ } -+ DBGLOG(OID, INFO, "Enter TestMode, setBufLen %u, InTestMode %d, rStatus %u\n", -+ u4SetBufferLen, prAdapter->fgTestMode, rStatus); -+ return rStatus; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Set driver to switch into normal operation mode from RF test mode -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set -+* should be NULL -+* \param[in] u4SetBufferLen The length of the set buffer, should be 0 -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \return WLAN_STATUS_SUCCESS -+* \return WLAN_STATUS_ADAPTER_NOT_READY -+* \return WLAN_STATUS_INVALID_DATA -+* \return WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidRftestSetAbortTestMode(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ WLAN_STATUS rStatus; -+ CMD_TEST_CTRL_T rCmdTestCtrl; -+ -+ DEBUGFUNC("wlanoidRftestSetTestMode"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pvSetBuffer); -+ ASSERT(pu4SetInfoLen); -+ -+ *pu4SetInfoLen = 0; -+ -+ if (u4SetBufferLen == 0) { -+ if (prAdapter->fgTestMode == TRUE) { -+ /* switch to normal mode */ -+ rCmdTestCtrl.ucAction = 0; /* Switch mode */ -+ rCmdTestCtrl.u.u4OpMode = 0; /* normal mode */ -+ -+ rStatus = wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_TEST_MODE, -+ TRUE, -+ FALSE, -+ TRUE, -+ nicCmdEventLeaveRfTest, -+ nicOidCmdTimeoutCommon, -+ sizeof(CMD_TEST_CTRL_T), -+ (PUINT_8) &rCmdTestCtrl, pvSetBuffer, u4SetBufferLen); -+ } else { -+ /* already in normal mode .. */ -+ rStatus = WLAN_STATUS_SUCCESS; -+ } -+ } else { -+ rStatus = WLAN_STATUS_INVALID_DATA; -+ } -+ DBGLOG(OID, INFO, "Abort TestMode, setBufLen %u, InTestMode %d, rStatus %u\n", -+ u4SetBufferLen, prAdapter->fgTestMode, rStatus); -+ return rStatus; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief query for RF test parameter -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvQueryBuffer Pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufferLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_BUFFER_TOO_SHORT -+* \retval WLAN_STATUS_NOT_SUPPORTED -+* \retval WLAN_STATUS_NOT_ACCEPTED -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidRftestQueryAutoTest(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ P_PARAM_MTK_WIFI_TEST_STRUCT_T prRfATInfo; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ -+ DEBUGFUNC("wlanoidRftestQueryAutoTest"); -+ -+ ASSERT(prAdapter); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ ASSERT(pu4QueryInfoLen); -+ -+ *pu4QueryInfoLen = sizeof(PARAM_MTK_WIFI_TEST_STRUCT_T); -+ -+ if (u4QueryBufferLen != sizeof(PARAM_MTK_WIFI_TEST_STRUCT_T)) { -+ DBGLOG(OID, ERROR, "Invalid data. QueryBufferLen: %u.\n", u4QueryBufferLen); -+ return WLAN_STATUS_INVALID_LENGTH; -+ } -+ -+ prRfATInfo = (P_PARAM_MTK_WIFI_TEST_STRUCT_T) pvQueryBuffer; -+ rStatus = rftestQueryATInfo(prAdapter, -+ prRfATInfo->u4FuncIndex, prRfATInfo->u4FuncData, pvQueryBuffer, u4QueryBufferLen); -+ -+ return rStatus; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Set RF test parameter -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \return WLAN_STATUS_SUCCESS -+* \return WLAN_STATUS_ADAPTER_NOT_READY -+* \return WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidRftestSetAutoTest(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ P_PARAM_MTK_WIFI_TEST_STRUCT_T prRfATInfo; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ -+ DEBUGFUNC("wlanoidRftestSetAutoTest"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pvSetBuffer); -+ ASSERT(pu4SetInfoLen); -+ -+ *pu4SetInfoLen = sizeof(PARAM_MTK_WIFI_TEST_STRUCT_T); -+ -+ if (u4SetBufferLen != sizeof(PARAM_MTK_WIFI_TEST_STRUCT_T)) { -+ DBGLOG(OID, ERROR, "Invalid data. SetBufferLen: %u.\n", u4SetBufferLen); -+ return WLAN_STATUS_INVALID_LENGTH; -+ } -+ -+ prRfATInfo = (P_PARAM_MTK_WIFI_TEST_STRUCT_T) pvSetBuffer; -+ rStatus = rftestSetATInfo(prAdapter, prRfATInfo->u4FuncIndex, prRfATInfo->u4FuncData); -+ -+ return rStatus; -+} -+ -+/* RF test OID set handler */ -+WLAN_STATUS rftestSetATInfo(IN P_ADAPTER_T prAdapter, UINT_32 u4FuncIndex, UINT_32 u4FuncData) -+{ -+ P_GLUE_INFO_T prGlueInfo; -+ P_CMD_INFO_T prCmdInfo; -+ P_WIFI_CMD_T prWifiCmd; -+ P_CMD_TEST_CTRL_T pCmdTestCtrl; -+ UINT_8 ucCmdSeqNum; -+ -+ ASSERT(prAdapter); -+ -+ prGlueInfo = prAdapter->prGlueInfo; -+ prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, (CMD_HDR_SIZE + sizeof(CMD_TEST_CTRL_T))); -+ -+ if (!prCmdInfo) { -+ DBGLOG(OID, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); -+ return WLAN_STATUS_FAILURE; -+ } -+ /* increase command sequence number */ -+ ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter); -+ -+ /* Setup common CMD Info Packet */ -+ prCmdInfo->eCmdType = COMMAND_TYPE_GENERAL_IOCTL; -+ prCmdInfo->u2InfoBufLen = CMD_HDR_SIZE + sizeof(CMD_TEST_CTRL_T); -+ prCmdInfo->pfCmdDoneHandler = nicCmdEventSetCommon; -+ prCmdInfo->pfCmdTimeoutHandler = nicOidCmdTimeoutCommon; -+ prCmdInfo->fgIsOid = TRUE; -+ prCmdInfo->ucCID = CMD_ID_TEST_MODE; -+ prCmdInfo->fgSetQuery = TRUE; -+ prCmdInfo->fgNeedResp = FALSE; -+ prCmdInfo->fgDriverDomainMCR = FALSE; -+ prCmdInfo->ucCmdSeqNum = ucCmdSeqNum; -+ prCmdInfo->u4SetInfoLen = sizeof(CMD_TEST_CTRL_T); -+ prCmdInfo->pvInformationBuffer = NULL; -+ prCmdInfo->u4InformationBufferLength = 0; -+ -+ /* Setup WIFI_CMD_T (payload = CMD_TEST_CTRL_T) */ -+ prWifiCmd = (P_WIFI_CMD_T) (prCmdInfo->pucInfoBuffer); -+ prWifiCmd->u2TxByteCount_UserPriority = prCmdInfo->u2InfoBufLen; -+ prWifiCmd->ucCID = prCmdInfo->ucCID; -+ prWifiCmd->ucSetQuery = prCmdInfo->fgSetQuery; -+ prWifiCmd->ucSeqNum = prCmdInfo->ucCmdSeqNum; -+ -+ pCmdTestCtrl = (P_CMD_TEST_CTRL_T) (prWifiCmd->aucBuffer); -+ pCmdTestCtrl->ucAction = 1; /* Set ATInfo */ -+ pCmdTestCtrl->u.rRfATInfo.u4FuncIndex = u4FuncIndex; -+ pCmdTestCtrl->u.rRfATInfo.u4FuncData = u4FuncData; -+ -+ /* insert into prCmdQueue */ -+ kalEnqueueCommand(prGlueInfo, (P_QUE_ENTRY_T) prCmdInfo); -+ -+ /* wakeup txServiceThread later */ -+ GLUE_SET_EVENT(prAdapter->prGlueInfo); -+ -+ return WLAN_STATUS_PENDING; -+} -+ -+WLAN_STATUS -+rftestQueryATInfo(IN P_ADAPTER_T prAdapter, -+ UINT_32 u4FuncIndex, UINT_32 u4FuncData, OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen) -+{ -+ P_GLUE_INFO_T prGlueInfo; -+ P_CMD_INFO_T prCmdInfo; -+ P_WIFI_CMD_T prWifiCmd; -+ P_CMD_TEST_CTRL_T pCmdTestCtrl; -+ UINT_8 ucCmdSeqNum; -+ P_EVENT_TEST_STATUS prTestStatus; -+ -+ ASSERT(prAdapter); -+ -+ prGlueInfo = prAdapter->prGlueInfo; -+ -+ if (u4FuncIndex == RF_AT_FUNCID_FW_INFO) { -+ /* driver implementation */ -+ prTestStatus = (P_EVENT_TEST_STATUS) pvQueryBuffer; -+ -+ prTestStatus->rATInfo.u4FuncData = -+ (prAdapter->rVerInfo.u2FwProductID << 16) | (prAdapter->rVerInfo.u2FwOwnVersion); -+ u4QueryBufferLen = sizeof(EVENT_TEST_STATUS); -+ -+ return WLAN_STATUS_SUCCESS; -+ } else if (u4FuncIndex == RF_AT_FUNCID_DRV_INFO) { -+ /* driver implementation */ -+ prTestStatus = (P_EVENT_TEST_STATUS) pvQueryBuffer; -+ -+ prTestStatus->rATInfo.u4FuncData = CFG_DRV_OWN_VERSION; -+ u4QueryBufferLen = sizeof(EVENT_TEST_STATUS); -+ -+ return WLAN_STATUS_SUCCESS; -+ } -+ prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, (CMD_HDR_SIZE + sizeof(CMD_TEST_CTRL_T))); -+ -+ if (!prCmdInfo) { -+ DBGLOG(OID, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); -+ return WLAN_STATUS_FAILURE; -+ } -+ /* increase command sequence number */ -+ ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter); -+ -+ /* Setup common CMD Info Packet */ -+ prCmdInfo->eCmdType = COMMAND_TYPE_GENERAL_IOCTL; -+ prCmdInfo->u2InfoBufLen = CMD_HDR_SIZE + sizeof(CMD_TEST_CTRL_T); -+ prCmdInfo->pfCmdDoneHandler = nicCmdEventQueryRfTestATInfo; -+ prCmdInfo->pfCmdTimeoutHandler = nicOidCmdTimeoutCommon; -+ prCmdInfo->fgIsOid = TRUE; -+ prCmdInfo->ucCID = CMD_ID_TEST_MODE; -+ prCmdInfo->fgSetQuery = FALSE; -+ prCmdInfo->fgNeedResp = TRUE; -+ prCmdInfo->fgDriverDomainMCR = FALSE; -+ prCmdInfo->ucCmdSeqNum = ucCmdSeqNum; -+ prCmdInfo->u4SetInfoLen = sizeof(CMD_TEST_CTRL_T); -+ prCmdInfo->pvInformationBuffer = pvQueryBuffer; -+ prCmdInfo->u4InformationBufferLength = u4QueryBufferLen; -+ -+ /* Setup WIFI_CMD_T (payload = CMD_TEST_CTRL_T) */ -+ prWifiCmd = (P_WIFI_CMD_T) (prCmdInfo->pucInfoBuffer); -+ prWifiCmd->u2TxByteCount_UserPriority = prCmdInfo->u2InfoBufLen; -+ prWifiCmd->ucCID = prCmdInfo->ucCID; -+ prWifiCmd->ucSetQuery = prCmdInfo->fgSetQuery; -+ prWifiCmd->ucSeqNum = prCmdInfo->ucCmdSeqNum; -+ -+ pCmdTestCtrl = (P_CMD_TEST_CTRL_T) (prWifiCmd->aucBuffer); -+ pCmdTestCtrl->ucAction = 2; /* Get ATInfo */ -+ pCmdTestCtrl->u.rRfATInfo.u4FuncIndex = u4FuncIndex; -+ pCmdTestCtrl->u.rRfATInfo.u4FuncData = u4FuncData; -+ -+ /* insert into prCmdQueue */ -+ kalEnqueueCommand(prGlueInfo, (P_QUE_ENTRY_T) prCmdInfo); -+ -+ /* wakeup txServiceThread later */ -+ GLUE_SET_EVENT(prAdapter->prGlueInfo); -+ -+ return WLAN_STATUS_PENDING; -+} -+ -+WLAN_STATUS rftestSetFrequency(IN P_ADAPTER_T prAdapter, IN UINT_32 u4FreqInKHz, IN PUINT_32 pu4SetInfoLen) -+{ -+ CMD_TEST_CTRL_T rCmdTestCtrl; -+ -+ ASSERT(prAdapter); -+ -+ rCmdTestCtrl.ucAction = 5; /* Set Channel Frequency */ -+ rCmdTestCtrl.u.u4ChannelFreq = u4FreqInKHz; -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_TEST_MODE, -+ TRUE, -+ FALSE, -+ TRUE, -+ nicCmdEventSetCommon, -+ nicOidCmdTimeoutCommon, sizeof(CMD_TEST_CTRL_T), (PUINT_8) &rCmdTestCtrl, NULL, 0); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief command packet generation utility -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] ucCID Command ID -+* \param[in] fgSetQuery Set or Query -+* \param[in] fgNeedResp Need for response -+* \param[in] pfCmdDoneHandler Function pointer when command is done -+* \param[in] u4SetQueryInfoLen The length of the set/query buffer -+* \param[in] pucInfoBuffer Pointer to set/query buffer -+* -+* -+* \retval WLAN_STATUS_PENDING -+* \retval WLAN_STATUS_FAILURE -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanSendSetQueryCmd(IN P_ADAPTER_T prAdapter, -+ UINT_8 ucCID, -+ BOOLEAN fgSetQuery, -+ BOOLEAN fgNeedResp, -+ BOOLEAN fgIsOid, -+ PFN_CMD_DONE_HANDLER pfCmdDoneHandler, -+ PFN_CMD_TIMEOUT_HANDLER pfCmdTimeoutHandler, -+ UINT_32 u4SetQueryInfoLen, -+ PUINT_8 pucInfoBuffer, OUT PVOID pvSetQueryBuffer, IN UINT_32 u4SetQueryBufferLen) -+{ -+ P_GLUE_INFO_T prGlueInfo; -+ P_CMD_INFO_T prCmdInfo; -+ P_WIFI_CMD_T prWifiCmd; -+ UINT_8 ucCmdSeqNum; -+ -+ prGlueInfo = prAdapter->prGlueInfo; -+ prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, (CMD_HDR_SIZE + u4SetQueryInfoLen)); -+ -+ DEBUGFUNC("wlanSendSetQueryCmd"); -+ -+ if (!prCmdInfo) { -+ DBGLOG(OID, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); -+ return WLAN_STATUS_FAILURE; -+ } -+ /* increase command sequence number */ -+ ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter); -+ DBGLOG(OID, TRACE, "ucCmdSeqNum =%d, ucCID =%d\n", ucCmdSeqNum, ucCID); -+ -+ /* Setup common CMD Info Packet */ -+ prCmdInfo->eCmdType = COMMAND_TYPE_NETWORK_IOCTL; -+ prCmdInfo->eNetworkType = NETWORK_TYPE_AIS_INDEX; -+ prCmdInfo->u2InfoBufLen = (UINT_16) (CMD_HDR_SIZE + u4SetQueryInfoLen); -+ prCmdInfo->pfCmdDoneHandler = pfCmdDoneHandler; -+ prCmdInfo->pfCmdTimeoutHandler = pfCmdTimeoutHandler; -+ prCmdInfo->fgIsOid = fgIsOid; -+ prCmdInfo->ucCID = ucCID; -+ prCmdInfo->fgSetQuery = fgSetQuery; -+ prCmdInfo->fgNeedResp = fgNeedResp; -+ prCmdInfo->fgDriverDomainMCR = FALSE; -+ prCmdInfo->ucCmdSeqNum = ucCmdSeqNum; -+ prCmdInfo->u4SetInfoLen = u4SetQueryInfoLen; -+ prCmdInfo->pvInformationBuffer = pvSetQueryBuffer; -+ prCmdInfo->u4InformationBufferLength = u4SetQueryBufferLen; -+ -+ /* Setup WIFI_CMD_T (no payload) */ -+ prWifiCmd = (P_WIFI_CMD_T) (prCmdInfo->pucInfoBuffer); -+ prWifiCmd->u2TxByteCount_UserPriority = prCmdInfo->u2InfoBufLen; -+ prWifiCmd->ucCID = prCmdInfo->ucCID; -+ prWifiCmd->ucSetQuery = prCmdInfo->fgSetQuery; -+ prWifiCmd->ucSeqNum = prCmdInfo->ucCmdSeqNum; -+ -+ if (u4SetQueryInfoLen > 0 && pucInfoBuffer != NULL) -+ kalMemCopy(prWifiCmd->aucBuffer, pucInfoBuffer, u4SetQueryInfoLen); -+ /* insert into prCmdQueue */ -+ kalEnqueueCommand(prGlueInfo, (P_QUE_ENTRY_T) prCmdInfo); -+ -+ /* wakeup txServiceThread later */ -+ GLUE_SET_EVENT(prGlueInfo); -+ return WLAN_STATUS_PENDING; -+} -+ -+#if CFG_SUPPORT_WAPI -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called by WAPI ui to set wapi mode, which is needed to info the the driver -+* to operation at WAPI mode while driver initialize. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set -+* \param[in] u4SetBufferLen The length of the set buffer -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed due to invalid length of -+* the set buffer, returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_DATA If new setting value is wrong. -+* \retval WLAN_STATUS_INVALID_LENGTH -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetWapiMode(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ DEBUGFUNC("wlanoidSetWapiMode"); -+ DBGLOG(OID, LOUD, "\r\n"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ ASSERT(pvSetBuffer); -+ -+ /* Todo:: For support WAPI and Wi-Fi at same driver, use the set wapi assoc ie at the check point */ -+ /* The Adapter Connection setting fgUseWapi will cleat whil oid set mode (infra), */ -+ /* And set fgUseWapi True while set wapi assoc ie */ -+ /* policay selection, add key all depend on this flag, */ -+ /* The fgUseWapi may remove later */ -+ if (*(PUINT_32) pvSetBuffer) -+ prAdapter->fgUseWapi = TRUE; -+ else -+ prAdapter->fgUseWapi = FALSE; -+ -+#if 0 -+ prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, (CMD_HDR_SIZE + 4)); -+ -+ if (!prCmdInfo) { -+ DBGLOG(OID, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); -+ return WLAN_STATUS_FAILURE; -+ } -+ /* increase command sequence number */ -+ ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter); -+ -+ /* compose CMD_BUILD_CONNECTION cmd pkt */ -+ prCmdInfo->eCmdType = COMMAND_TYPE_NETWORK_IOCTL; -+ prCmdInfo->eNetworkType = NETWORK_TYPE_AIS_INDEX; -+ prCmdInfo->u2InfoBufLen = CMD_HDR_SIZE + 4; -+ prCmdInfo->pfCmdDoneHandler = nicCmdEventSetCommon; -+ prCmdInfo->pfCmdTimeoutHandler = NULL; -+ prCmdInfo->fgIsOid = TRUE; -+ prCmdInfo->ucCID = CMD_ID_WAPI_MODE; -+ prCmdInfo->fgSetQuery = TRUE; -+ prCmdInfo->fgNeedResp = FALSE; -+ prCmdInfo->fgDriverDomainMCR = FALSE; -+ prCmdInfo->ucCmdSeqNum = ucCmdSeqNum; -+ prCmdInfo->u4SetInfoLen = u4SetBufferLen; -+ prCmdInfo->pvInformationBuffer = pvSetBuffer; -+ prCmdInfo->u4InformationBufferLength = u4SetBufferLen; -+ -+ /* Setup WIFI_CMD_T */ -+ prWifiCmd = (P_WIFI_CMD_T) (prCmdInfo->pucInfoBuffer); -+ prWifiCmd->u2TxByteCount_UserPriority = prCmdInfo->u2InfoBufLen; -+ prWifiCmd->ucCID = prCmdInfo->ucCID; -+ prWifiCmd->ucSetQuery = prCmdInfo->fgSetQuery; -+ prWifiCmd->ucSeqNum = prCmdInfo->ucCmdSeqNum; -+ -+ cp = (PUINT_8) (prWifiCmd->aucBuffer); -+ -+ kalMemCopy(cp, (PUINT_8) pvSetBuffer, 4); -+ -+ /* insert into prCmdQueue */ -+ kalEnqueueCommand(prGlueInfo, (P_QUE_ENTRY_T) prCmdInfo); -+ -+ /* wakeup txServiceThread later */ -+ GLUE_SET_EVENT(prGlueInfo); -+ -+ return WLAN_STATUS_PENDING; -+#else -+ return WLAN_STATUS_SUCCESS; -+#endif -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called by WAPI to set the assoc info, which is needed to add to -+* Association request frame while join WAPI AP. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set -+* \param[in] u4SetBufferLen The length of the set buffer -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed due to invalid length of -+* the set buffer, returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_DATA If new setting value is wrong. -+* \retval WLAN_STATUS_INVALID_LENGTH -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetWapiAssocInfo(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ P_WAPI_INFO_ELEM_T prWapiInfo; -+ PUINT_8 cp; -+ UINT_16 u2AuthSuiteCount = 0; -+ UINT_16 u2PairSuiteCount = 0; -+ UINT_32 u4AuthKeyMgtSuite = 0; -+ UINT_32 u4PairSuite = 0; -+ UINT_32 u4GroupSuite = 0; -+ -+ ASSERT(prAdapter); -+ ASSERT(pvSetBuffer); -+ ASSERT(pu4SetInfoLen); -+ -+ DEBUGFUNC("wlanoidSetWapiAssocInfo"); -+ DBGLOG(OID, LOUD, "\r\n"); -+ -+ if (u4SetBufferLen < 20 /* From EID to Group cipher */) { -+ prAdapter->rWifiVar.rConnSettings.fgWapiMode = FALSE; -+ DBGLOG(SEC, INFO, "fgWapiMode = FALSE due to u4SetBufferLen %u < 20!\n", u4SetBufferLen); -+ return WLAN_STATUS_INVALID_LENGTH; -+ } -+ -+ prAdapter->rWifiVar.rConnSettings.fgWapiMode = TRUE; -+ -+ /* if (prWapiInfo->ucElemId != ELEM_ID_WAPI) */ -+ /* DBGLOG(SEC, TRACE, ("Not WAPI IE ?!\n")); */ -+ -+ /* if (prWapiInfo->ucLength < 18) */ -+ /* return WLAN_STATUS_INVALID_LENGTH; */ -+ -+ *pu4SetInfoLen = u4SetBufferLen; -+ -+ prWapiInfo = (P_WAPI_INFO_ELEM_T) pvSetBuffer; -+ -+ if (prWapiInfo->ucElemId != ELEM_ID_WAPI) { -+ DBGLOG(SEC, INFO, "Not WAPI IE ?! u4SetBufferLen = %u\n", u4SetBufferLen); -+ prAdapter->rWifiVar.rConnSettings.fgWapiMode = FALSE; -+ return WLAN_STATUS_INVALID_LENGTH; -+ } -+ -+ if (prWapiInfo->ucLength < 18) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ /* Skip Version check */ -+ cp = (PUINT_8) &prWapiInfo->u2AuthKeyMgtSuiteCount; -+ -+ WLAN_GET_FIELD_16(cp, &u2AuthSuiteCount); -+ -+ if (u2AuthSuiteCount > 1) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ cp = (PUINT_8) &prWapiInfo->aucAuthKeyMgtSuite1[0]; -+ WLAN_GET_FIELD_32(cp, &u4AuthKeyMgtSuite); -+ -+ DBGLOG(SEC, TRACE, "WAPI: Assoc Info auth mgt suite [%d]: %02x-%02x-%02x-%02x\n", -+ u2AuthSuiteCount, -+ (UCHAR) (u4AuthKeyMgtSuite & 0x000000FF), -+ (UCHAR) ((u4AuthKeyMgtSuite >> 8) & 0x000000FF), -+ (UCHAR) ((u4AuthKeyMgtSuite >> 16) & 0x000000FF), -+ (UCHAR) ((u4AuthKeyMgtSuite >> 24) & 0x000000FF)); -+ -+ if (u4AuthKeyMgtSuite != WAPI_AKM_SUITE_802_1X && u4AuthKeyMgtSuite != WAPI_AKM_SUITE_PSK) -+ ASSERT(FALSE); -+ -+ cp += 4; -+ WLAN_GET_FIELD_16(cp, &u2PairSuiteCount); -+ if (u2PairSuiteCount > 1) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ cp += 2; -+ WLAN_GET_FIELD_32(cp, &u4PairSuite); -+ DBGLOG(SEC, TRACE, "WAPI: Assoc Info pairwise cipher suite [%d]: %02x-%02x-%02x-%02x\n", -+ u2PairSuiteCount, -+ (UCHAR) (u4PairSuite & 0x000000FF), -+ (UCHAR) ((u4PairSuite >> 8) & 0x000000FF), -+ (UCHAR) ((u4PairSuite >> 16) & 0x000000FF), (UCHAR) ((u4PairSuite >> 24) & 0x000000FF)); -+ -+ if (u4PairSuite != WAPI_CIPHER_SUITE_WPI) -+ ASSERT(FALSE); -+ -+ cp += 4; -+ WLAN_GET_FIELD_32(cp, &u4GroupSuite); -+ DBGLOG(SEC, TRACE, "WAPI: Assoc Info group cipher suite : %02x-%02x-%02x-%02x\n", -+ (UCHAR) (u4GroupSuite & 0x000000FF), -+ (UCHAR) ((u4GroupSuite >> 8) & 0x000000FF), -+ (UCHAR) ((u4GroupSuite >> 16) & 0x000000FF), (UCHAR) ((u4GroupSuite >> 24) & 0x000000FF)); -+ -+ if (u4GroupSuite != WAPI_CIPHER_SUITE_WPI) -+ ASSERT(FALSE); -+ -+ prAdapter->rWifiVar.rConnSettings.u4WapiSelectedAKMSuite = u4AuthKeyMgtSuite; -+ prAdapter->rWifiVar.rConnSettings.u4WapiSelectedPairwiseCipher = u4PairSuite; -+ prAdapter->rWifiVar.rConnSettings.u4WapiSelectedGroupCipher = u4GroupSuite; -+ -+ kalMemCopy(prAdapter->prGlueInfo->aucWapiAssocInfoIEs, pvSetBuffer, u4SetBufferLen); -+ prAdapter->prGlueInfo->u2WapiAssocInfoIESz = (UINT_16) u4SetBufferLen; -+ DBGLOG(SEC, TRACE, "Assoc Info IE sz %u\n", u4SetBufferLen); -+ -+ return WLAN_STATUS_SUCCESS; -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to set the wpi key to the driver. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_ADAPTER_NOT_READY -+* \retval WLAN_STATUS_INVALID_LENGTH -+* \retval WLAN_STATUS_INVALID_DATA -+* -+* \note The setting buffer P_PARAM_WPI_KEY, which is set by NDIS, is unpacked. -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetWapiKey(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ P_GLUE_INFO_T prGlueInfo; -+ P_CMD_INFO_T prCmdInfo; -+ P_WIFI_CMD_T prWifiCmd; -+ P_PARAM_WPI_KEY_T prNewKey; -+ P_CMD_802_11_KEY prCmdKey; -+ PUINT_8 pc; -+ UINT_8 ucCmdSeqNum; -+ -+ DEBUGFUNC("wlanoidSetWapiKey"); -+ DBGLOG(OID, LOUD, "\r\n"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pvSetBuffer); -+ ASSERT(pu4SetInfoLen); -+ -+ if (prAdapter->rAcpiState == ACPI_STATE_D3) { -+ DBGLOG(OID, WARN, "Fail in set add key! (Adapter not ready). ACPI=D%d, Radio=%d\r\n", -+ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); -+ return WLAN_STATUS_ADAPTER_NOT_READY; -+ } -+ -+ prNewKey = (P_PARAM_WPI_KEY_T) pvSetBuffer; -+ -+ DBGLOG_MEM8(OID, TRACE, (PUINT_8) pvSetBuffer, 560); -+ pc = (PUINT_8) pvSetBuffer; -+ -+ *pu4SetInfoLen = u4SetBufferLen; -+ -+ /* Exception check */ -+ if (prNewKey->ucKeyID != 0x1 || prNewKey->ucKeyID != 0x0) { -+ prNewKey->ucKeyID = prNewKey->ucKeyID & BIT(0); -+ /* DBGLOG(SEC, INFO, ("Invalid WAPI key ID (%d)\r\n", prNewKey->ucKeyID)); */ -+ } -+ -+ /* Dump P_PARAM_WPI_KEY_T content. */ -+ DBGLOG(OID, TRACE, "Set: Dump P_PARAM_WPI_KEY_T content\r\n"); -+ DBGLOG(OID, TRACE, "TYPE : %d\r\n", prNewKey->eKeyType); -+ DBGLOG(OID, TRACE, "Direction : %d\r\n", prNewKey->eDirection); -+ DBGLOG(OID, TRACE, "KeyID : %d\r\n", prNewKey->ucKeyID); -+ DBGLOG(OID, TRACE, "AddressIndex:\r\n"); -+ DBGLOG_MEM8(OID, TRACE, prNewKey->aucAddrIndex, 12); -+ prNewKey->u4LenWPIEK = 16; -+ -+ DBGLOG_MEM8(OID, TRACE, (PUINT_8) prNewKey->aucWPIEK, (UINT_8) prNewKey->u4LenWPIEK); -+ prNewKey->u4LenWPICK = 16; -+ -+ DBGLOG(OID, TRACE, "CK Key(%d):\r\n", (UINT_8) prNewKey->u4LenWPICK); -+ DBGLOG_MEM8(OID, TRACE, (PUINT_8) prNewKey->aucWPICK, (UINT_8) prNewKey->u4LenWPICK); -+ DBGLOG(OID, TRACE, "PN:\r\n"); -+ if (prNewKey->eKeyType == 0) { -+ prNewKey->aucPN[0] = 0x5c; -+ prNewKey->aucPN[1] = 0x36; -+ prNewKey->aucPN[2] = 0x5c; -+ prNewKey->aucPN[3] = 0x36; -+ prNewKey->aucPN[4] = 0x5c; -+ prNewKey->aucPN[5] = 0x36; -+ prNewKey->aucPN[6] = 0x5c; -+ prNewKey->aucPN[7] = 0x36; -+ prNewKey->aucPN[8] = 0x5c; -+ prNewKey->aucPN[9] = 0x36; -+ prNewKey->aucPN[10] = 0x5c; -+ prNewKey->aucPN[11] = 0x36; -+ prNewKey->aucPN[12] = 0x5c; -+ prNewKey->aucPN[13] = 0x36; -+ prNewKey->aucPN[14] = 0x5c; -+ prNewKey->aucPN[15] = 0x36; -+ } -+ -+ DBGLOG_MEM8(OID, TRACE, (PUINT_8) prNewKey->aucPN, 16); -+ -+ prGlueInfo = prAdapter->prGlueInfo; -+ -+ prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, (CMD_HDR_SIZE + u4SetBufferLen)); -+ -+ if (!prCmdInfo) { -+ DBGLOG(OID, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); -+ return WLAN_STATUS_FAILURE; -+ } -+ /* increase command sequence number */ -+ ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter); -+ -+ /* compose CMD_ID_ADD_REMOVE_KEY cmd pkt */ -+ prCmdInfo->eCmdType = COMMAND_TYPE_NETWORK_IOCTL; -+ prCmdInfo->eNetworkType = NETWORK_TYPE_AIS_INDEX; -+ prCmdInfo->u2InfoBufLen = CMD_HDR_SIZE + sizeof(CMD_802_11_KEY); -+ prCmdInfo->pfCmdDoneHandler = nicCmdEventSetCommon; -+ prCmdInfo->pfCmdTimeoutHandler = nicOidCmdTimeoutCommon; -+ prCmdInfo->fgIsOid = TRUE; -+ prCmdInfo->ucCID = CMD_ID_ADD_REMOVE_KEY; -+ prCmdInfo->fgSetQuery = TRUE; -+ prCmdInfo->fgNeedResp = FALSE; -+ prCmdInfo->fgDriverDomainMCR = FALSE; -+ prCmdInfo->ucCmdSeqNum = ucCmdSeqNum; -+ prCmdInfo->u4SetInfoLen = u4SetBufferLen; -+ prCmdInfo->pvInformationBuffer = pvSetBuffer; -+ prCmdInfo->u4InformationBufferLength = u4SetBufferLen; -+ -+ /* Setup WIFI_CMD_T */ -+ prWifiCmd = (P_WIFI_CMD_T) (prCmdInfo->pucInfoBuffer); -+ prWifiCmd->u2TxByteCount_UserPriority = prCmdInfo->u2InfoBufLen; -+ prWifiCmd->ucCID = prCmdInfo->ucCID; -+ prWifiCmd->ucSetQuery = prCmdInfo->fgSetQuery; -+ prWifiCmd->ucSeqNum = prCmdInfo->ucCmdSeqNum; -+ -+ prCmdKey = (P_CMD_802_11_KEY) (prWifiCmd->aucBuffer); -+ -+ kalMemZero(prCmdKey, sizeof(CMD_802_11_KEY)); -+ -+ prCmdKey->ucAddRemove = 1; /* Add */ -+ -+ if (prNewKey->eKeyType == ENUM_WPI_PAIRWISE_KEY) { -+ prCmdKey->ucTxKey = 1; -+ prCmdKey->ucKeyType = 1; -+ } -+ -+ kalMemCopy(prCmdKey->aucPeerAddr, (PUINT_8) prNewKey->aucAddrIndex, MAC_ADDR_LEN); -+ -+ prCmdKey->ucNetType = 0; /* AIS */ -+ -+ prCmdKey->ucKeyId = prNewKey->ucKeyID; -+ -+ prCmdKey->ucKeyLen = 32; -+ -+ prCmdKey->ucAlgorithmId = CIPHER_SUITE_WPI; -+ -+ kalMemCopy(prCmdKey->aucKeyMaterial, (PUINT_8) prNewKey->aucWPIEK, 16); -+ -+ kalMemCopy(prCmdKey->aucKeyMaterial + 16, (PUINT_8) prNewKey->aucWPICK, 16); -+ -+ kalMemCopy(prCmdKey->aucKeyRsc, (PUINT_8) prNewKey->aucPN, 16); -+ -+ /* insert into prCmdQueue */ -+ kalEnqueueCommand(prGlueInfo, (P_QUE_ENTRY_T) prCmdInfo); -+ -+ /* wakeup txServiceThread later */ -+ GLUE_SET_EVENT(prGlueInfo); -+ -+ return WLAN_STATUS_PENDING; -+} /* wlanoidSetAddKey */ -+#endif -+ -+#if CFG_SUPPORT_WPS2 -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called by WSC to set the assoc info, which is needed to add to -+* Association request frame while join WPS AP. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set -+* \param[in] u4SetBufferLen The length of the set buffer -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed due to invalid length of -+* the set buffer, returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_DATA If new setting value is wrong. -+* \retval WLAN_STATUS_INVALID_LENGTH -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetWSCAssocInfo(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ ASSERT(prAdapter); -+ ASSERT(pvSetBuffer); -+ ASSERT(pu4SetInfoLen); -+ -+ DEBUGFUNC("wlanoidSetWSCAssocInfo"); -+ DBGLOG(OID, LOUD, "\r\n"); -+ -+ if (u4SetBufferLen == 0) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ *pu4SetInfoLen = u4SetBufferLen; -+ -+ kalMemCopy(prAdapter->prGlueInfo->aucWSCAssocInfoIE, pvSetBuffer, u4SetBufferLen); -+ prAdapter->prGlueInfo->u2WSCAssocInfoIELen = (UINT_16) u4SetBufferLen; -+ DBGLOG(SEC, TRACE, "Assoc Info IE sz %u\n", u4SetBufferLen); -+ -+ return WLAN_STATUS_SUCCESS; -+ -+} -+#endif -+ -+#if CFG_ENABLE_WAKEUP_ON_LAN -+WLAN_STATUS -+wlanoidSetAddWakeupPattern(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ P_PARAM_PM_PACKET_PATTERN prPacketPattern; -+ -+ DEBUGFUNC("wlanoidSetAddWakeupPattern"); -+ DBGLOG(OID, LOUD, "\r\n"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ *pu4SetInfoLen = sizeof(PARAM_PM_PACKET_PATTERN); -+ -+ if (u4SetBufferLen < sizeof(PARAM_PM_PACKET_PATTERN)) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ ASSERT(pvSetBuffer); -+ -+ prPacketPattern = (P_PARAM_PM_PACKET_PATTERN) pvSetBuffer; -+ -+ /* FIXME: -+ * Send the struct to firmware */ -+ -+ return WLAN_STATUS_FAILURE; -+} -+ -+WLAN_STATUS -+wlanoidSetRemoveWakeupPattern(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ P_PARAM_PM_PACKET_PATTERN prPacketPattern; -+ -+ DEBUGFUNC("wlanoidSetAddWakeupPattern"); -+ DBGLOG(OID, LOUD, "\r\n"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ *pu4SetInfoLen = sizeof(PARAM_PM_PACKET_PATTERN); -+ -+ if (u4SetBufferLen < sizeof(PARAM_PM_PACKET_PATTERN)) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ ASSERT(pvSetBuffer); -+ -+ prPacketPattern = (P_PARAM_PM_PACKET_PATTERN) pvSetBuffer; -+ -+ /* FIXME: -+ * Send the struct to firmware */ -+ -+ return WLAN_STATUS_FAILURE; -+} -+ -+WLAN_STATUS -+wlanoidQueryEnableWakeup(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ PUINT_32 pu4WakeupEventEnable; -+ -+ DEBUGFUNC("wlanoidQueryEnableWakeup"); -+ DBGLOG(OID, LOUD, "\r\n"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4QueryInfoLen); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ -+ *pu4QueryInfoLen = sizeof(UINT_32); -+ -+ if (u4QueryBufferLen < sizeof(UINT_32)) -+ return WLAN_STATUS_BUFFER_TOO_SHORT; -+ -+ pu4WakeupEventEnable = (PUINT_32) pvQueryBuffer; -+ -+ *pu4WakeupEventEnable = prAdapter->u4WakeupEventEnable; -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+WLAN_STATUS -+wlanoidSetEnableWakeup(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ PUINT_32 pu4WakeupEventEnable; -+ -+ DEBUGFUNC("wlanoidSetEnableWakup"); -+ DBGLOG(OID, LOUD, "\r\n"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ *pu4SetInfoLen = sizeof(UINT_32); -+ -+ if (u4SetBufferLen < sizeof(UINT_32)) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ ASSERT(pvSetBuffer); -+ -+ pu4WakeupEventEnable = (PUINT_32) pvSetBuffer; -+ prAdapter->u4WakeupEventEnable = *pu4WakeupEventEnable; -+ -+ /* FIXME: -+ * Send Command Event for setting wakeup-pattern / Magic Packet to firmware -+ * */ -+ -+ return WLAN_STATUS_FAILURE; -+} -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to configure PS related settings for WMM-PS test. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetWiFiWmmPsTest(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ P_PARAM_CUSTOM_WMM_PS_TEST_STRUCT_T prWmmPsTestInfo; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ CMD_SET_WMM_PS_TEST_STRUCT_T rSetWmmPsTestParam; -+ UINT_16 u2CmdBufLen; -+ P_PM_PROFILE_SETUP_INFO_T prPmProfSetupInfo; -+ P_BSS_INFO_T prBssInfo; -+ -+ DEBUGFUNC("wlanoidSetWiFiWmmPsTest"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pvSetBuffer); -+ ASSERT(pu4SetInfoLen); -+ -+ *pu4SetInfoLen = sizeof(PARAM_CUSTOM_WMM_PS_TEST_STRUCT_T); -+ -+ prWmmPsTestInfo = (P_PARAM_CUSTOM_WMM_PS_TEST_STRUCT_T) pvSetBuffer; -+ -+ rSetWmmPsTestParam.ucNetTypeIndex = NETWORK_TYPE_AIS_INDEX; -+ rSetWmmPsTestParam.bmfgApsdEnAc = prWmmPsTestInfo->bmfgApsdEnAc; -+ rSetWmmPsTestParam.ucIsEnterPsAtOnce = prWmmPsTestInfo->ucIsEnterPsAtOnce; -+ rSetWmmPsTestParam.ucIsDisableUcTrigger = prWmmPsTestInfo->ucIsDisableUcTrigger; -+ -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[rSetWmmPsTestParam.ucNetTypeIndex]); -+ prPmProfSetupInfo = &prBssInfo->rPmProfSetupInfo; -+ prPmProfSetupInfo->ucBmpDeliveryAC = (rSetWmmPsTestParam.bmfgApsdEnAc >> 4) & BITS(0, 3); -+ prPmProfSetupInfo->ucBmpTriggerAC = rSetWmmPsTestParam.bmfgApsdEnAc & BITS(0, 3); -+ -+ u2CmdBufLen = sizeof(CMD_SET_WMM_PS_TEST_STRUCT_T); -+ -+#if 0 -+ /* it will apply the disable trig or not immediately */ -+ if (prPmInfo->ucWmmPsDisableUcPoll && prPmInfo->ucWmmPsConnWithTrig) -+ ; /* NIC_PM_WMM_PS_DISABLE_UC_TRIG(prAdapter, TRUE); */ -+ else -+ ; /* NIC_PM_WMM_PS_DISABLE_UC_TRIG(prAdapter, FALSE); */ -+#endif -+ -+ rStatus = wlanSendSetQueryCmd(prAdapter, CMD_ID_SET_WMM_PS_TEST_PARMS, TRUE, FALSE, TRUE, NULL, /* TODO? */ -+ NULL, u2CmdBufLen, (PUINT_8) &rSetWmmPsTestParam, NULL, 0); -+ -+ return rStatus; -+} /* wlanoidSetWiFiWmmPsTest */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to configure enable/disable TX A-MPDU feature. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetTxAmpdu(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ CMD_TX_AMPDU_T rTxAmpdu; -+ UINT_16 u2CmdBufLen; -+ PBOOLEAN pfgEnable; -+ -+ DEBUGFUNC("wlanoidSetTxAmpdu"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pvSetBuffer); -+ ASSERT(pu4SetInfoLen); -+ -+ *pu4SetInfoLen = sizeof(BOOLEAN); -+ -+ pfgEnable = (PBOOLEAN) pvSetBuffer; -+ -+ rTxAmpdu.fgEnable = *pfgEnable; -+ -+ u2CmdBufLen = sizeof(CMD_TX_AMPDU_T); -+ -+ rStatus = wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_TX_AMPDU, -+ TRUE, FALSE, TRUE, NULL, NULL, u2CmdBufLen, (PUINT_8) &rTxAmpdu, NULL, 0); -+ -+ return rStatus; -+} /* wlanoidSetTxAmpdu */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to configure reject/accept ADDBA Request. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetAddbaReject(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ CMD_ADDBA_REJECT_T rAddbaReject; -+ UINT_16 u2CmdBufLen; -+ PBOOLEAN pfgEnable; -+ -+ DEBUGFUNC("wlanoidSetAddbaReject"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pvSetBuffer); -+ ASSERT(pu4SetInfoLen); -+ -+ *pu4SetInfoLen = sizeof(BOOLEAN); -+ -+ pfgEnable = (PBOOLEAN) pvSetBuffer; -+ -+ rAddbaReject.fgEnable = *pfgEnable; -+ -+ u2CmdBufLen = sizeof(CMD_ADDBA_REJECT_T); -+ -+ rStatus = wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_ADDBA_REJECT, -+ TRUE, FALSE, TRUE, NULL, NULL, u2CmdBufLen, (PUINT_8) &rAddbaReject, NULL, 0); -+ -+ return rStatus; -+} /* wlanoidSetAddbaReject */ -+ -+#if CFG_SLT_SUPPORT -+ -+WLAN_STATUS -+wlanoidQuerySLTStatus(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ WLAN_STATUS rWlanStatus = WLAN_STATUS_SUCCESS; -+ P_PARAM_MTK_SLT_TEST_STRUCT_T prMtkSltInfo = (P_PARAM_MTK_SLT_TEST_STRUCT_T) NULL; -+ P_SLT_INFO_T prSltInfo = (P_SLT_INFO_T) NULL; -+ -+ DEBUGFUNC("wlanoidQuerySLTStatus"); -+ DBGLOG(OID, LOUD, "\r\n"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4QueryInfoLen); -+ -+ *pu4QueryInfoLen = sizeof(PARAM_MTK_SLT_TEST_STRUCT_T); -+ -+ if (u4QueryBufferLen < sizeof(PARAM_MTK_SLT_TEST_STRUCT_T)) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ ASSERT(pvQueryBuffer); -+ -+ prMtkSltInfo = (P_PARAM_MTK_SLT_TEST_STRUCT_T) pvQueryBuffer; -+ -+ prSltInfo = &(prAdapter->rWifiVar.rSltInfo); -+ -+ switch (prMtkSltInfo->rSltFuncIdx) { -+ case ENUM_MTK_SLT_FUNC_LP_SET: -+ { -+ P_PARAM_MTK_SLT_LP_TEST_STRUCT_T prLpSetting = (P_PARAM_MTK_SLT_LP_TEST_STRUCT_T) NULL; -+ -+ ASSERT(prMtkSltInfo->u4FuncInfoLen == sizeof(PARAM_MTK_SLT_LP_TEST_STRUCT_T)); -+ -+ prLpSetting = (P_PARAM_MTK_SLT_LP_TEST_STRUCT_T) &prMtkSltInfo->unFuncInfoContent; -+ -+ prLpSetting->u4BcnRcvNum = prSltInfo->u4BeaconReceiveCnt; -+ } -+ break; -+ default: -+ /* TBD... */ -+ break; -+ } -+ -+ return rWlanStatus; -+} /* wlanoidQuerySLTStatus */ -+ -+WLAN_STATUS -+wlanoidUpdateSLTMode(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ WLAN_STATUS rWlanStatus = WLAN_STATUS_SUCCESS; -+ P_PARAM_MTK_SLT_TEST_STRUCT_T prMtkSltInfo = (P_PARAM_MTK_SLT_TEST_STRUCT_T) NULL; -+ P_SLT_INFO_T prSltInfo = (P_SLT_INFO_T) NULL; -+ P_BSS_DESC_T prBssDesc = (P_BSS_DESC_T) NULL; -+ P_STA_RECORD_T prStaRec = (P_STA_RECORD_T) NULL; -+ P_BSS_INFO_T prBssInfo = (P_BSS_INFO_T) NULL; -+ -+ /* 1. Action: Update or Initial Set -+ * 2. Role. -+ * 3. Target MAC address. -+ * 4. RF BW & Rate Settings -+ */ -+ -+ DEBUGFUNC("wlanoidUpdateSLTMode"); -+ DBGLOG(OID, LOUD, "\r\n"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ *pu4SetInfoLen = sizeof(PARAM_MTK_SLT_TEST_STRUCT_T); -+ -+ if (u4SetBufferLen < sizeof(PARAM_MTK_SLT_TEST_STRUCT_T)) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ ASSERT(pvSetBuffer); -+ -+ prMtkSltInfo = (P_PARAM_MTK_SLT_TEST_STRUCT_T) pvSetBuffer; -+ -+ prSltInfo = &(prAdapter->rWifiVar.rSltInfo); -+ prBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]; -+ -+ switch (prMtkSltInfo->rSltFuncIdx) { -+ case ENUM_MTK_SLT_FUNC_INITIAL: /* Initialize */ -+ { -+ P_PARAM_MTK_SLT_INITIAL_STRUCT_T prMtkSltInit = (P_PARAM_MTK_SLT_INITIAL_STRUCT_T) NULL; -+ -+ ASSERT(prMtkSltInfo->u4FuncInfoLen == sizeof(PARAM_MTK_SLT_INITIAL_STRUCT_T)); -+ -+ prMtkSltInit = (P_PARAM_MTK_SLT_INITIAL_STRUCT_T) &prMtkSltInfo->unFuncInfoContent; -+ -+ if (prSltInfo->prPseudoStaRec != NULL) { -+ /* The driver has been initialized. */ -+ prSltInfo->prPseudoStaRec = NULL; -+ } -+ -+ prSltInfo->prPseudoBssDesc = scanSearchExistingBssDesc(prAdapter, -+ BSS_TYPE_IBSS, -+ prMtkSltInit->aucTargetMacAddr, -+ prMtkSltInit->aucTargetMacAddr); -+ -+ prSltInfo->u2SiteID = prMtkSltInit->u2SiteID; -+ -+ /* Bandwidth 2.4G: Channel 1~14 -+ * Bandwidth 5G: *36, 40, 44, 48, 52, 56, 60, 64, -+ * *100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, -+ * 149, 153, *157, 161, -+ * 184, 188, 192, 196, 200, 204, 208, 212, *216 -+ */ -+ prSltInfo->ucChannel2G4 = 1 + (prSltInfo->u2SiteID % 4) * 5; -+ -+ switch (prSltInfo->ucChannel2G4) { -+ case 1: -+ prSltInfo->ucChannel5G = 36; -+ break; -+ case 6: -+ prSltInfo->ucChannel5G = 52; -+ break; -+ case 11: -+ prSltInfo->ucChannel5G = 104; -+ break; -+ case 16: -+ prSltInfo->ucChannel2G4 = 14; -+ prSltInfo->ucChannel5G = 161; -+ break; -+ default: -+ ASSERT(FALSE); -+ } -+ -+ if (prSltInfo->prPseudoBssDesc == NULL) { -+ do { -+ prSltInfo->prPseudoBssDesc = scanAllocateBssDesc(prAdapter); -+ -+ if (prSltInfo->prPseudoBssDesc == NULL) { -+ rWlanStatus = WLAN_STATUS_FAILURE; -+ break; -+ } -+ prBssDesc = prSltInfo->prPseudoBssDesc; -+ } while (FALSE); -+ } else { -+ prBssDesc = prSltInfo->prPseudoBssDesc; -+ } -+ -+ if (prBssDesc) { -+ prBssDesc->eBSSType = BSS_TYPE_IBSS; -+ -+ COPY_MAC_ADDR(prBssDesc->aucSrcAddr, prMtkSltInit->aucTargetMacAddr); -+ COPY_MAC_ADDR(prBssDesc->aucBSSID, prBssInfo->aucOwnMacAddr); -+ -+ prBssDesc->u2BeaconInterval = 100; -+ prBssDesc->u2ATIMWindow = 0; -+ prBssDesc->ucDTIMPeriod = 1; -+ -+ prBssDesc->u2IELength = 0; -+ -+ prBssDesc->fgIsERPPresent = TRUE; -+ prBssDesc->fgIsHTPresent = TRUE; -+ -+ prBssDesc->u2OperationalRateSet = BIT(RATE_36M_INDEX); -+ prBssDesc->u2BSSBasicRateSet = BIT(RATE_36M_INDEX); -+ prBssDesc->fgIsUnknownBssBasicRate = FALSE; -+ -+ prBssDesc->fgIsLargerTSF = TRUE; -+ -+ prBssDesc->eBand = BAND_2G4; -+ -+ prBssDesc->ucChannelNum = prSltInfo->ucChannel2G4; -+ -+ prBssDesc->ucPhyTypeSet = PHY_TYPE_SET_802_11ABGN; -+ -+ GET_CURRENT_SYSTIME(&prBssDesc->rUpdateTime); -+ } -+ } -+ break; -+ case ENUM_MTK_SLT_FUNC_RATE_SET: /* Update RF Settings. */ -+ if (prSltInfo->prPseudoStaRec == NULL) { -+ rWlanStatus = WLAN_STATUS_FAILURE; -+ break; -+ } -+ -+ P_PARAM_MTK_SLT_TR_TEST_STRUCT_T prTRSetting = (P_PARAM_MTK_SLT_TR_TEST_STRUCT_T) NULL; -+ -+ ASSERT(prMtkSltInfo->u4FuncInfoLen == sizeof(PARAM_MTK_SLT_TR_TEST_STRUCT_T)); -+ -+ prStaRec = prSltInfo->prPseudoStaRec; -+ prTRSetting = (P_PARAM_MTK_SLT_TR_TEST_STRUCT_T) &prMtkSltInfo->unFuncInfoContent; -+ -+ if (prTRSetting->rNetworkType == PARAM_NETWORK_TYPE_OFDM5) { -+ prBssInfo->eBand = BAND_5G; -+ prBssInfo->ucPrimaryChannel = prSltInfo->ucChannel5G; -+ } -+ if (prTRSetting->rNetworkType == PARAM_NETWORK_TYPE_OFDM24) { -+ prBssInfo->eBand = BAND_2G4; -+ prBssInfo->ucPrimaryChannel = prSltInfo->ucChannel2G4; -+ } -+ -+ if ((prTRSetting->u4FixedRate & FIXED_BW_DL40) != 0) { -+ /* RF 40 */ -+ /* It would controls RFBW capability in WTBL. */ -+ prStaRec->u2HtCapInfo |= HT_CAP_INFO_SUP_CHNL_WIDTH; -+ /* This controls RF BW, RF BW would be 40 only if */ -+ /* 1. PHY_TYPE_BIT_HT is TRUE. */ -+ /* 2. SCO is SCA/SCB. */ -+ prStaRec->ucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; -+ -+ /* U20/L20 Control. */ -+ switch (prTRSetting->u4FixedRate & 0xC000) { -+ case FIXED_EXT_CHNL_U20: -+ prBssInfo->eBssSCO = CHNL_EXT_SCB; /* +2 */ -+ if (prTRSetting->rNetworkType == PARAM_NETWORK_TYPE_OFDM5) -+ prBssInfo->ucPrimaryChannel += 2; -+ else { -+ /* For channel 1, testing L20 at channel 8. */ -+ if (prBssInfo->ucPrimaryChannel < 5) -+ prBssInfo->ucPrimaryChannel = 8; -+ } -+ break; -+ case FIXED_EXT_CHNL_L20: -+ default: /* 40M */ -+ prBssInfo->eBssSCO = CHNL_EXT_SCA; /* -2 */ -+ if (prTRSetting->rNetworkType == PARAM_NETWORK_TYPE_OFDM5) { -+ prBssInfo->ucPrimaryChannel -= 2; -+ } else { -+ /* For channel 11 / 14. testing U20 at channel 3. */ -+ if (prBssInfo->ucPrimaryChannel > 10) -+ prBssInfo->ucPrimaryChannel = 3; -+ } -+ break; -+ } -+ } else { -+ /* RF 20 */ -+ prStaRec->u2HtCapInfo &= ~HT_CAP_INFO_SUP_CHNL_WIDTH; -+ prBssInfo->eBssSCO = CHNL_EXT_SCN; -+ } -+ -+ prBssInfo->fgErpProtectMode = FALSE; -+ prBssInfo->eHtProtectMode = HT_PROTECT_MODE_NONE; -+ prBssInfo->eGfOperationMode = GF_MODE_NORMAL; -+ -+ nicUpdateBss(prAdapter, prBssInfo->ucNetTypeIndex); -+ -+ prStaRec->u2HtCapInfo &= ~(HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M); -+ -+ switch (prTRSetting->u4FixedRate & 0xFF) { -+ case RATE_OFDM_54M: -+ prStaRec->u2DesiredNonHTRateSet = BIT(RATE_54M_INDEX); -+ break; -+ case RATE_OFDM_48M: -+ prStaRec->u2DesiredNonHTRateSet = BIT(RATE_48M_INDEX); -+ break; -+ case RATE_OFDM_36M: -+ prStaRec->u2DesiredNonHTRateSet = BIT(RATE_36M_INDEX); -+ break; -+ case RATE_OFDM_24M: -+ prStaRec->u2DesiredNonHTRateSet = BIT(RATE_24M_INDEX); -+ break; -+ case RATE_OFDM_6M: -+ prStaRec->u2DesiredNonHTRateSet = BIT(RATE_6M_INDEX); -+ break; -+ case RATE_CCK_11M_LONG: -+ prStaRec->u2DesiredNonHTRateSet = BIT(RATE_11M_INDEX); -+ break; -+ case RATE_CCK_1M_LONG: -+ prStaRec->u2DesiredNonHTRateSet = BIT(RATE_1M_INDEX); -+ break; -+ case RATE_GF_MCS_0: -+ prStaRec->u2DesiredNonHTRateSet = BIT(RATE_HT_PHY_INDEX); -+ prStaRec->u2HtCapInfo |= HT_CAP_INFO_HT_GF; -+ break; -+ case RATE_MM_MCS_7: -+ prStaRec->u2DesiredNonHTRateSet = BIT(RATE_HT_PHY_INDEX); -+ prStaRec->u2HtCapInfo &= ~HT_CAP_INFO_HT_GF; -+#if 0 /* Only for Current Measurement Mode. */ -+ prStaRec->u2HtCapInfo |= (HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M); -+#endif -+ break; -+ case RATE_GF_MCS_7: -+ prStaRec->u2DesiredNonHTRateSet = BIT(RATE_HT_PHY_INDEX); -+ prStaRec->u2HtCapInfo |= HT_CAP_INFO_HT_GF; -+ break; -+ default: -+ prStaRec->u2DesiredNonHTRateSet = BIT(RATE_36M_INDEX); -+ break; -+ } -+ -+ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); -+ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_3); -+ -+ break; -+ case ENUM_MTK_SLT_FUNC_LP_SET: /* Reset LP Test Result. */ -+ { -+ P_PARAM_MTK_SLT_LP_TEST_STRUCT_T prLpSetting = (P_PARAM_MTK_SLT_LP_TEST_STRUCT_T) NULL; -+ -+ ASSERT(prMtkSltInfo->u4FuncInfoLen == sizeof(PARAM_MTK_SLT_LP_TEST_STRUCT_T)); -+ -+ prLpSetting = (P_PARAM_MTK_SLT_LP_TEST_STRUCT_T) &prMtkSltInfo->unFuncInfoContent; -+ -+ if (prSltInfo->prPseudoBssDesc == NULL) { -+ /* Please initial SLT Mode first. */ -+ break; -+ } -+ prBssDesc = prSltInfo->prPseudoBssDesc; -+ -+ switch (prLpSetting->rLpTestMode) { -+ case ENUM_MTK_LP_TEST_NORMAL: -+ /* In normal mode, we would use target MAC address to be the BSSID. */ -+ COPY_MAC_ADDR(prBssDesc->aucBSSID, prBssInfo->aucOwnMacAddr); -+ prSltInfo->fgIsDUT = FALSE; -+ break; -+ case ENUM_MTK_LP_TEST_GOLDEN_SAMPLE: -+ /* 1. Lower AIFS of BCN queue. -+ * 2. Fixed Random Number tobe 0. -+ */ -+ prSltInfo->fgIsDUT = FALSE; -+ /* In LP test mode, we would use MAC address of Golden Sample to be the BSSID. */ -+ COPY_MAC_ADDR(prBssDesc->aucBSSID, prBssInfo->aucOwnMacAddr); -+ break; -+ case ENUM_MTK_LP_TEST_DUT: -+ /* 1. Enter Sleep Mode. -+ * 2. Fix random number a large value & enlarge AIFN of BCN queue. -+ */ -+ COPY_MAC_ADDR(prBssDesc->aucBSSID, prBssDesc->aucSrcAddr); -+ prSltInfo->u4BeaconReceiveCnt = 0; -+ prSltInfo->fgIsDUT = TRUE; -+ break; -+ } -+ -+ } -+ -+ break; -+ default: -+ break; -+ } -+ -+ return WLAN_STATUS_FAILURE; -+ -+ return rWlanStatus; -+} /* wlanoidUpdateSLTMode */ -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to query NVRAM value. -+* -+* \param[in] pvAdapter Pointer to the Adapter structure. -+* \param[out] pvQueryBuf A pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_FAILURE -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryNvramRead(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ P_PARAM_CUSTOM_NVRAM_RW_STRUCT_T prNvramRwInfo; -+ UINT_16 u2Data; -+ BOOLEAN fgStatus; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ -+ DEBUGFUNC("wlanoidQueryNvramRead"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4QueryInfoLen); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ -+ *pu4QueryInfoLen = sizeof(PARAM_CUSTOM_NVRAM_RW_STRUCT_T); -+ -+ if (u4QueryBufferLen < sizeof(PARAM_CUSTOM_NVRAM_RW_STRUCT_T)) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ prNvramRwInfo = (P_PARAM_CUSTOM_NVRAM_RW_STRUCT_T) pvQueryBuffer; -+ -+ if (prNvramRwInfo->ucEepromMethod == PARAM_EEPROM_READ_METHOD_READ) { -+ /* change to byte offset */ -+ fgStatus = kalCfgDataRead16(prAdapter->prGlueInfo, -+ prNvramRwInfo->ucEepromIndex << 1, -+ &u2Data); -+ -+ if (fgStatus) { -+ prNvramRwInfo->u2EepromData = u2Data; -+ DBGLOG(OID, INFO, "NVRAM Read: index=%#X, data=%#02X\r\n", -+ prNvramRwInfo->ucEepromIndex, u2Data); -+ } else { -+ DBGLOG(OID, ERROR, "NVRAM Read Failed: index=%#x.\r\n", prNvramRwInfo->ucEepromIndex); -+ rStatus = WLAN_STATUS_FAILURE; -+ } -+ } else if (prNvramRwInfo->ucEepromMethod == PARAM_EEPROM_READ_METHOD_GETSIZE) { -+ prNvramRwInfo->u2EepromData = CFG_FILE_WIFI_REC_SIZE; -+ DBGLOG(OID, INFO, "EEPROM size =%d\r\n", prNvramRwInfo->u2EepromData); -+ } -+ -+ *pu4QueryInfoLen = sizeof(PARAM_CUSTOM_EEPROM_RW_STRUCT_T); -+ -+ return rStatus; -+} /* wlanoidQueryNvramRead */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to write NVRAM value. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_FAILURE -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetNvramWrite(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ P_PARAM_CUSTOM_NVRAM_RW_STRUCT_T prNvramRwInfo; -+ BOOLEAN fgStatus; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ -+ DEBUGFUNC("wlanoidSetNvramWrite"); -+ DBGLOG(OID, LOUD, "\n"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ *pu4SetInfoLen = sizeof(PARAM_CUSTOM_NVRAM_RW_STRUCT_T); -+ -+ if (u4SetBufferLen < sizeof(PARAM_CUSTOM_NVRAM_RW_STRUCT_T)) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ ASSERT(pvSetBuffer); -+ -+ prNvramRwInfo = (P_PARAM_CUSTOM_NVRAM_RW_STRUCT_T) pvSetBuffer; -+ -+ /* change to byte offset */ -+ fgStatus = kalCfgDataWrite16(prAdapter->prGlueInfo, -+ prNvramRwInfo->ucEepromIndex << 1, -+ prNvramRwInfo->u2EepromData); -+ -+ if (fgStatus == FALSE) { -+ DBGLOG(OID, ERROR, "NVRAM Write Failed.\r\n"); -+ rStatus = WLAN_STATUS_FAILURE; -+ } -+ -+ return rStatus; -+} /* wlanoidSetNvramWrite */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to get the config data source type. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_FAILURE -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryCfgSrcType(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ ASSERT(prAdapter); -+ -+ *pu4QueryInfoLen = sizeof(ENUM_CFG_SRC_TYPE_T); -+ -+ if (kalIsConfigurationExist(prAdapter->prGlueInfo) == TRUE) -+ *(P_ENUM_CFG_SRC_TYPE_T) pvQueryBuffer = CFG_SRC_TYPE_NVRAM; -+ else -+ *(P_ENUM_CFG_SRC_TYPE_T) pvQueryBuffer = CFG_SRC_TYPE_EEPROM; -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to get the config data source type. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_FAILURE -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryEepromType(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ ASSERT(prAdapter); -+ -+ *pu4QueryInfoLen = sizeof(P_ENUM_EEPROM_TYPE_T); -+ -+#if CFG_SUPPORT_NIC_CAPABILITY -+ if (prAdapter->fgIsEepromUsed == TRUE) -+ *(P_ENUM_EEPROM_TYPE_T) pvQueryBuffer = EEPROM_TYPE_PRESENT; -+ else -+ *(P_ENUM_EEPROM_TYPE_T) pvQueryBuffer = EEPROM_TYPE_NO; -+#else -+ *(P_ENUM_EEPROM_TYPE_T) pvQueryBuffer = EEPROM_TYPE_NO; -+#endif -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to get the config data source type. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_FAILURE -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetCountryCode(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ PUINT_8 pucCountry; -+ UINT_16 u2CountryCode; -+ -+ ASSERT(prAdapter); -+ ASSERT(pvSetBuffer); -+ ASSERT(u4SetBufferLen == 2); -+ -+ *pu4SetInfoLen = 2; -+ -+ pucCountry = pvSetBuffer; -+ u2CountryCode = (((UINT_16) pucCountry[0]) << 8) | ((UINT_16) pucCountry[1]); -+ -+ /* previous country code == FF : ignore country code, current country code == FE : resume */ -+ if (prAdapter->rWifiVar.rConnSettings.u2CountryCodeBakup == COUNTRY_CODE_FF) { -+ if (u2CountryCode != COUNTRY_CODE_FE) { -+ DBGLOG(OID, INFO, "Skip country code cmd (0x%04x)\n", u2CountryCode); -+ return WLAN_STATUS_SUCCESS; -+ } -+ DBGLOG(OID, INFO, "Resume handle country code cmd (0x%04x)\n", u2CountryCode); -+ } -+ -+ prAdapter->rWifiVar.rConnSettings.u2CountryCode = u2CountryCode; -+ prAdapter->rWifiVar.rConnSettings.u2CountryCodeBakup = prAdapter->rWifiVar.rConnSettings.u2CountryCode; -+ DBGLOG(OID, LOUD, "u2CountryCodeBakup=0x%04x\n", prAdapter->rWifiVar.rConnSettings.u2CountryCodeBakup); -+ -+ /* Force to re-search country code in country domains */ -+ prAdapter->prDomainInfo = NULL; -+ rlmDomainSendCmd(prAdapter, TRUE); -+ -+ /* Update supported channel list in channel table based on current country domain */ -+ wlanUpdateChannelTable(prAdapter->prGlueInfo); -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+#if 0 -+WLAN_STATUS -+wlanoidSetNoaParam(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ P_PARAM_CUSTOM_NOA_PARAM_STRUCT_T prNoaParam; -+ CMD_CUSTOM_NOA_PARAM_STRUCT_T rCmdNoaParam; -+ -+ DEBUGFUNC("wlanoidSetNoaParam"); -+ DBGLOG(OID, LOUD, "\n"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ *pu4SetInfoLen = sizeof(PARAM_CUSTOM_NOA_PARAM_STRUCT_T); -+ -+ if (u4SetBufferLen < sizeof(PARAM_CUSTOM_NOA_PARAM_STRUCT_T)) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ ASSERT(pvSetBuffer); -+ -+ prNoaParam = (P_PARAM_CUSTOM_NOA_PARAM_STRUCT_T) pvSetBuffer; -+ -+ kalMemZero(&rCmdNoaParam, sizeof(CMD_CUSTOM_NOA_PARAM_STRUCT_T)); -+ rCmdNoaParam.u4NoaDurationMs = prNoaParam->u4NoaDurationMs; -+ rCmdNoaParam.u4NoaIntervalMs = prNoaParam->u4NoaIntervalMs; -+ rCmdNoaParam.u4NoaCount = prNoaParam->u4NoaCount; -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SET_NOA_PARAM, -+ TRUE, -+ FALSE, -+ TRUE, -+ nicCmdEventSetCommon, -+ nicOidCmdTimeoutCommon, -+ sizeof(CMD_CUSTOM_NOA_PARAM_STRUCT_T), -+ (PUINT_8) &rCmdNoaParam, pvSetBuffer, u4SetBufferLen); -+} -+ -+WLAN_STATUS -+wlanoidSetOppPsParam(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ P_PARAM_CUSTOM_OPPPS_PARAM_STRUCT_T prOppPsParam; -+ CMD_CUSTOM_OPPPS_PARAM_STRUCT_T rCmdOppPsParam; -+ -+ DEBUGFUNC("wlanoidSetOppPsParam"); -+ DBGLOG(OID, LOUD, "\n"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ *pu4SetInfoLen = sizeof(PARAM_CUSTOM_OPPPS_PARAM_STRUCT_T); -+ -+ if (u4SetBufferLen < sizeof(PARAM_CUSTOM_OPPPS_PARAM_STRUCT_T)) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ ASSERT(pvSetBuffer); -+ -+ prOppPsParam = (P_PARAM_CUSTOM_OPPPS_PARAM_STRUCT_T) pvSetBuffer; -+ -+ kalMemZero(&rCmdOppPsParam, sizeof(CMD_CUSTOM_OPPPS_PARAM_STRUCT_T)); -+ rCmdOppPsParam.u4CTwindowMs = prOppPsParam->u4CTwindowMs; -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SET_OPPPS_PARAM, -+ TRUE, -+ FALSE, -+ TRUE, -+ nicCmdEventSetCommon, -+ nicOidCmdTimeoutCommon, -+ sizeof(CMD_CUSTOM_OPPPS_PARAM_STRUCT_T), -+ (PUINT_8) &rCmdOppPsParam, pvSetBuffer, u4SetBufferLen); -+} -+ -+WLAN_STATUS -+wlanoidSetUApsdParam(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ P_PARAM_CUSTOM_UAPSD_PARAM_STRUCT_T prUapsdParam; -+ CMD_CUSTOM_UAPSD_PARAM_STRUCT_T rCmdUapsdParam; -+ P_PM_PROFILE_SETUP_INFO_T prPmProfSetupInfo; -+ P_BSS_INFO_T prBssInfo; -+ -+ DEBUGFUNC("wlanoidSetUApsdParam"); -+ DBGLOG(OID, LOUD, "\n"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ *pu4SetInfoLen = sizeof(PARAM_CUSTOM_UAPSD_PARAM_STRUCT_T); -+ -+ if (u4SetBufferLen < sizeof(PARAM_CUSTOM_UAPSD_PARAM_STRUCT_T)) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ ASSERT(pvSetBuffer); -+ -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); -+ prPmProfSetupInfo = &prBssInfo->rPmProfSetupInfo; -+ -+ prUapsdParam = (P_PARAM_CUSTOM_UAPSD_PARAM_STRUCT_T) pvSetBuffer; -+ -+ kalMemZero(&rCmdUapsdParam, sizeof(CMD_CUSTOM_OPPPS_PARAM_STRUCT_T)); -+ rCmdUapsdParam.fgEnAPSD = prUapsdParam->fgEnAPSD; -+ prAdapter->rWifiVar.fgSupportUAPSD = prUapsdParam->fgEnAPSD; -+ -+ rCmdUapsdParam.fgEnAPSD_AcBe = prUapsdParam->fgEnAPSD_AcBe; -+ rCmdUapsdParam.fgEnAPSD_AcBk = prUapsdParam->fgEnAPSD_AcBk; -+ rCmdUapsdParam.fgEnAPSD_AcVo = prUapsdParam->fgEnAPSD_AcVo; -+ rCmdUapsdParam.fgEnAPSD_AcVi = prUapsdParam->fgEnAPSD_AcVi; -+ prPmProfSetupInfo->ucBmpDeliveryAC = -+ ((prUapsdParam->fgEnAPSD_AcBe << 0) | -+ (prUapsdParam->fgEnAPSD_AcBk << 1) | -+ (prUapsdParam->fgEnAPSD_AcVi << 2) | (prUapsdParam->fgEnAPSD_AcVo << 3)); -+ prPmProfSetupInfo->ucBmpTriggerAC = -+ ((prUapsdParam->fgEnAPSD_AcBe << 0) | -+ (prUapsdParam->fgEnAPSD_AcBk << 1) | -+ (prUapsdParam->fgEnAPSD_AcVi << 2) | (prUapsdParam->fgEnAPSD_AcVo << 3)); -+ -+ rCmdUapsdParam.ucMaxSpLen = prUapsdParam->ucMaxSpLen; -+ prPmProfSetupInfo->ucUapsdSp = prUapsdParam->ucMaxSpLen; -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SET_UAPSD_PARAM, -+ TRUE, -+ FALSE, -+ TRUE, -+ nicCmdEventSetCommon, -+ nicOidCmdTimeoutCommon, -+ sizeof(CMD_CUSTOM_OPPPS_PARAM_STRUCT_T), -+ (PUINT_8) &rCmdUapsdParam, pvSetBuffer, u4SetBufferLen); -+} -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to set BT profile or BT information and the -+* driver will set the built-in PTA configuration into chip. -+* -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetBT(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ -+ P_PTA_IPC_T prPtaIpc; -+ -+ DEBUGFUNC("wlanoidSetBT.\n"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ *pu4SetInfoLen = sizeof(PTA_IPC_T); -+ if (u4SetBufferLen != sizeof(PTA_IPC_T)) { -+ WARNLOG(("Invalid length %u\n", u4SetBufferLen)); -+ return WLAN_STATUS_INVALID_LENGTH; -+ } -+ -+ if (prAdapter->rAcpiState == ACPI_STATE_D3) { -+ DBGLOG(OID, WARN, "Fail to set BT profile because of ACPI_D3\n"); -+ return WLAN_STATUS_ADAPTER_NOT_READY; -+ } -+ -+ ASSERT(pvSetBuffer); -+ prPtaIpc = (P_PTA_IPC_T) pvSetBuffer; -+ -+#if CFG_SUPPORT_BCM && CFG_SUPPORT_BCM_BWCS && CFG_SUPPORT_BCM_BWCS_DEBUG -+ DBGLOG(OID, INFO, -+ "BCM BWCS CMD: BTPParams[0]=%02x, BTPParams[1]=%02x, BTPParams[2]=%02x, BTPParams[3]=%02x.\n", -+ prPtaIpc->u.aucBTPParams[0], prPtaIpc->u.aucBTPParams[1], prPtaIpc->u.aucBTPParams[2], -+ prPtaIpc->u.aucBTPParams[3]; -+ -+#endif -+ -+ wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SET_BWCS, -+ TRUE, FALSE, FALSE, NULL, NULL, sizeof(PTA_IPC_T), (PUINT_8) prPtaIpc, NULL, 0); -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to query current BT profile and BTCR values -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvQueryBuffer Pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufferLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryBT(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+/* P_PARAM_PTA_IPC_T prPtaIpc; */ -+/* UINT_32 u4QueryBuffLen; */ -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4QueryInfoLen); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ -+ *pu4QueryInfoLen = sizeof(PTA_IPC_T); -+ -+ /* Check for query buffer length */ -+ if (u4QueryBufferLen != sizeof(PTA_IPC_T)) { -+ DBGLOG(OID, WARN, "Invalid length %u\n", u4QueryBufferLen); -+ return WLAN_STATUS_INVALID_LENGTH; -+ } -+ -+ ASSERT(pvQueryBuffer); -+/* prPtaIpc = (P_PTA_IPC_T)pvQueryBuffer; */ -+/* prPtaIpc->ucCmd = BT_CMD_PROFILE; */ -+/* prPtaIpc->ucLen = sizeof(prPtaIpc->u); */ -+/* nicPtaGetProfile(prAdapter, (PUINT_8)&prPtaIpc->u, &u4QueryBuffLen); */ -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+#if 0 -+WLAN_STATUS -+wlanoidQueryBtSingleAntenna(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ P_PTA_INFO_T prPtaInfo; -+ PUINT_32 pu4SingleAntenna; -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4QueryInfoLen); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ -+ *pu4QueryInfoLen = sizeof(UINT_32); -+ -+ /* Check for query buffer length */ -+ if (u4QueryBufferLen != sizeof(UINT_32)) { -+ DBGLOG(OID, WARN, "Invalid length %u\n", u4QueryBufferLen); -+ return WLAN_STATUS_INVALID_LENGTH; -+ } -+ -+ ASSERT(pvQueryBuffer); -+ -+ prPtaInfo = &prAdapter->rPtaInfo; -+ pu4SingleAntenna = (PUINT_32) pvQueryBuffer; -+ -+ if (prPtaInfo->fgSingleAntenna) { -+ /* DBGLOG(OID, INFO, (KERN_WARNING DRV_NAME"Q Single Ant = 1\r\n")); */ -+ *pu4SingleAntenna = 1; -+ } else { -+ /* DBGLOG(OID, INFO, (KERN_WARNING DRV_NAME"Q Single Ant = 0\r\n")); */ -+ *pu4SingleAntenna = 0; -+ } -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+WLAN_STATUS -+wlanoidSetBtSingleAntenna(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ -+ PUINT_32 pu4SingleAntenna; -+ UINT_32 u4SingleAntenna; -+ P_PTA_INFO_T prPtaInfo; -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ prPtaInfo = &prAdapter->rPtaInfo; -+ -+ *pu4SetInfoLen = sizeof(UINT_32); -+ if (u4SetBufferLen != sizeof(UINT_32)) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ if (IS_ARB_IN_RFTEST_STATE(prAdapter)) -+ return WLAN_STATUS_SUCCESS; -+ -+ if (prAdapter->rAcpiState == ACPI_STATE_D3) { -+ DBGLOG(OID, WARN, "Fail to set antenna because of ACPI_D3\n"); -+ return WLAN_STATUS_ADAPTER_NOT_READY; -+ } -+ -+ ASSERT(pvSetBuffer); -+ pu4SingleAntenna = (PUINT_32) pvSetBuffer; -+ u4SingleAntenna = *pu4SingleAntenna; -+ -+ if (u4SingleAntenna == 0) { -+ /* DBGLOG(OID, INFO, (KERN_WARNING DRV_NAME"Set Single Ant = 0\r\n")); */ -+ prPtaInfo->fgSingleAntenna = FALSE; -+ } else { -+ /* DBGLOG(OID, INFO, (KERN_WARNING DRV_NAME"Set Single Ant = 1\r\n")); */ -+ prPtaInfo->fgSingleAntenna = TRUE; -+ } -+ ptaFsmRunEventSetConfig(prAdapter, &prPtaInfo->rPtaParam); -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+#if CFG_SUPPORT_BCM && CFG_SUPPORT_BCM_BWCS -+WLAN_STATUS -+wlanoidQueryPta(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ P_PTA_INFO_T prPtaInfo; -+ PUINT_32 pu4Pta; -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4QueryInfoLen); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ -+ *pu4QueryInfoLen = sizeof(UINT_32); -+ -+ /* Check for query buffer length */ -+ if (u4QueryBufferLen != sizeof(UINT_32)) { -+ DBGLOG(OID, WARN, "Invalid length %u\n", u4QueryBufferLen); -+ return WLAN_STATUS_INVALID_LENGTH; -+ } -+ -+ ASSERT(pvQueryBuffer); -+ -+ prPtaInfo = &prAdapter->rPtaInfo; -+ pu4Pta = (PUINT_32) pvQueryBuffer; -+ -+ if (prPtaInfo->fgEnabled) { -+ /* DBGLOG(OID, INFO, (KERN_WARNING DRV_NAME"PTA = 1\r\n")); */ -+ *pu4Pta = 1; -+ } else { -+ /* DBGLOG(OID, INFO, (KERN_WARNING DRV_NAME"PTA = 0\r\n")); */ -+ *pu4Pta = 0; -+ } -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+WLAN_STATUS -+wlanoidSetPta(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ PUINT_32 pu4PtaCtrl; -+ UINT_32 u4PtaCtrl; -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ *pu4SetInfoLen = sizeof(UINT_32); -+ if (u4SetBufferLen != sizeof(UINT_32)) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ if (IS_ARB_IN_RFTEST_STATE(prAdapter)) -+ return WLAN_STATUS_SUCCESS; -+ -+ if (prAdapter->rAcpiState == ACPI_STATE_D3) { -+ DBGLOG(OID, WARN, "Fail to set BT setting because of ACPI_D3\n"); -+ return WLAN_STATUS_ADAPTER_NOT_READY; -+ } -+ -+ ASSERT(pvSetBuffer); -+ pu4PtaCtrl = (PUINT_32) pvSetBuffer; -+ u4PtaCtrl = *pu4PtaCtrl; -+ -+ if (u4PtaCtrl == 0) { -+ /* DBGLOG(OID, INFO, (KERN_WARNING DRV_NAME"Set Pta= 0\r\n")); */ -+ nicPtaSetFunc(prAdapter, FALSE); -+ } else { -+ /* DBGLOG(OID, INFO, (KERN_WARNING DRV_NAME"Set Pta= 1\r\n")); */ -+ nicPtaSetFunc(prAdapter, TRUE); -+ } -+ -+ return WLAN_STATUS_SUCCESS; -+} -+#endif -+ -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to set Tx power profile. -+* -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetTxPower(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ /* P_SET_TXPWR_CTRL_T pTxPwr = (P_SET_TXPWR_CTRL_T)pvSetBuffer; */ -+ /* UINT_32 i; */ -+ WLAN_STATUS rStatus; -+ -+ DEBUGFUNC("wlanoidSetTxPower"); -+ DBGLOG(OID, LOUD, "\r\n"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pvSetBuffer); -+ -+#if 0 -+ DBGLOG(OID, INFO, "c2GLegacyStaPwrOffset=%d\n", pTxPwr->c2GLegacyStaPwrOffset); -+ DBGLOG(OID, INFO, "c2GHotspotPwrOffset=%d\n", pTxPwr->c2GHotspotPwrOffset); -+ DBGLOG(OID, INFO, "c2GP2pPwrOffset=%d\n", pTxPwr->c2GP2pPwrOffset); -+ DBGLOG(OID, INFO, "c2GBowPwrOffset=%d\n", pTxPwr->c2GBowPwrOffset); -+ DBGLOG(OID, INFO, "c5GLegacyStaPwrOffset=%d\n", pTxPwr->c5GLegacyStaPwrOffset); -+ DBGLOG(OID, INFO, "c5GHotspotPwrOffset=%d\n", pTxPwr->c5GHotspotPwrOffset); -+ DBGLOG(OID, INFO, "c5GP2pPwrOffset=%d\n", pTxPwr->c5GP2pPwrOffset); -+ DBGLOG(OID, INFO, "c5GBowPwrOffset=%d\n", pTxPwr->c5GBowPwrOffset); -+ DBGLOG(OID, INFO, "ucConcurrencePolicy=%d\n", pTxPwr->ucConcurrencePolicy); -+ -+ for (i = 0; i < 14; i++) -+ DBGLOG(OID, INFO, "acTxPwrLimit2G[%d]=%d\n", i, pTxPwr->acTxPwrLimit2G[i]); -+ -+ for (i = 0; i < 4; i++) -+ DBGLOG(OID, INFO, "acTxPwrLimit5G[%d]=%d\n", i, pTxPwr->acTxPwrLimit5G[i]); -+#endif -+ -+ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ -+ CMD_ID_SET_TXPWR_CTRL, /* ucCID */ -+ TRUE, /* fgSetQuery */ -+ FALSE, /* fgNeedResp */ -+ TRUE, /* fgIsOid */ -+ NULL, /* pfCmdDoneHandler */ -+ NULL, /* pfCmdTimeoutHandler */ -+ u4SetBufferLen, /* u4SetQueryInfoLen */ -+ (PUINT_8) pvSetBuffer, /* pucInfoBuffer */ -+ NULL, /* pvSetQueryBuffer */ -+ 0 /* u4SetQueryBufferLen */ -+ ); -+ -+ ASSERT(rStatus == WLAN_STATUS_PENDING); -+ -+ return rStatus; -+ -+} -+ -+WLAN_STATUS wlanSendMemDumpCmd(IN P_ADAPTER_T prAdapter, IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen) -+{ -+ P_PARAM_CUSTOM_MEM_DUMP_STRUCT_T prMemDumpInfo; -+ P_CMD_DUMP_MEM prCmdDumpMem; -+ CMD_DUMP_MEM rCmdDumpMem; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ UINT_32 u4MemSize = PARAM_MEM_DUMP_MAX_SIZE; -+ -+ UINT_32 u4RemainLeng = 0; -+ UINT_32 u4CurAddr = 0; -+ UINT_8 ucFragNum = 0; -+ -+ prCmdDumpMem = &rCmdDumpMem; -+ prMemDumpInfo = (P_PARAM_CUSTOM_MEM_DUMP_STRUCT_T) pvQueryBuffer; -+ -+ u4RemainLeng = prMemDumpInfo->u4RemainLength; -+ u4CurAddr = prMemDumpInfo->u4Address + prMemDumpInfo->u4Length; -+ ucFragNum = prMemDumpInfo->ucFragNum + 1; -+ -+ /* Query. If request length is larger than max length, do it as ping pong. -+ * Send a command and wait for a event. Send next command while the event is received. -+ * -+ */ -+ do { -+ UINT_32 u4CurLeng = 0; -+ -+ if (u4RemainLeng > u4MemSize) { -+ u4CurLeng = u4MemSize; -+ u4RemainLeng -= u4MemSize; -+ } else { -+ u4CurLeng = u4RemainLeng; -+ u4RemainLeng = 0; -+ } -+ -+ prCmdDumpMem->u4Address = u4CurAddr; -+ prCmdDumpMem->u4Length = u4CurLeng; -+ prCmdDumpMem->u4RemainLength = u4RemainLeng; -+ prCmdDumpMem->ucFragNum = ucFragNum; -+ -+ DBGLOG(OID, TRACE, "[%d] 0x%X, len %u, remain len %u\n", -+ ucFragNum, -+ prCmdDumpMem->u4Address, prCmdDumpMem->u4Length, prCmdDumpMem->u4RemainLength); -+ -+ rStatus = wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_DUMP_MEM, -+ FALSE, -+ TRUE, -+ TRUE, -+ nicCmdEventQueryMemDump, -+ nicOidCmdTimeoutCommon, -+ sizeof(CMD_DUMP_MEM), -+ (PUINT_8) prCmdDumpMem, pvQueryBuffer, u4QueryBufferLen); -+ -+ } while (FALSE); -+ -+ return rStatus; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to dump memory. -+* -+* \param[in] pvAdapter Pointer to the Adapter structure. -+* \param[out] pvQueryBuf A pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryMemDump(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ P_PARAM_CUSTOM_MEM_DUMP_STRUCT_T prMemDumpInfo; -+ -+ DEBUGFUNC("wlanoidQueryMemDump"); -+ DBGLOG(OID, LOUD, "\n"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4QueryInfoLen); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ -+ *pu4QueryInfoLen = sizeof(UINT_32); -+ -+ prMemDumpInfo = (P_PARAM_CUSTOM_MEM_DUMP_STRUCT_T) pvQueryBuffer; -+ DBGLOG(OID, TRACE, "Dump 0x%X, len %u\n", prMemDumpInfo->u4Address, prMemDumpInfo->u4Length); -+ -+ prMemDumpInfo->u4RemainLength = prMemDumpInfo->u4Length; -+ prMemDumpInfo->u4Length = 0; -+ prMemDumpInfo->ucFragNum = 0; -+ -+ return wlanSendMemDumpCmd(prAdapter, pvQueryBuffer, u4QueryBufferLen); -+ -+} /* end of wlanoidQueryMcrRead() */ -+ -+#if CFG_ENABLE_WIFI_DIRECT -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is used to set the p2p mode. -+* -+* \param[in] pvAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetP2pMode(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ WLAN_STATUS status = WLAN_STATUS_SUCCESS; -+ P_PARAM_CUSTOM_P2P_SET_STRUCT_T prSetP2P = (P_PARAM_CUSTOM_P2P_SET_STRUCT_T) NULL; -+ /* P_MSG_P2P_NETDEV_REGISTER_T prP2pNetdevRegMsg = (P_MSG_P2P_NETDEV_REGISTER_T)NULL; */ -+ DEBUGFUNC("wlanoidSetP2pMode"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ *pu4SetInfoLen = sizeof(PARAM_CUSTOM_P2P_SET_STRUCT_T); -+ if (u4SetBufferLen < sizeof(PARAM_CUSTOM_P2P_SET_STRUCT_T)) { -+ DBGLOG(OID, WARN, "Invalid length %u\n", u4SetBufferLen); -+ return WLAN_STATUS_INVALID_LENGTH; -+ } -+ -+ prSetP2P = (P_PARAM_CUSTOM_P2P_SET_STRUCT_T) pvSetBuffer; -+ -+ DBGLOG(P2P, INFO, "Set P2P enable %p [%u] mode[%u]\n", prSetP2P, prSetP2P->u4Enable, prSetP2P->u4Mode); -+ -+ /* -+ * enable = 1, mode = 0 => init P2P network -+ * enable = 1, mode = 1 => init Soft AP network -+ * enable = 0 => uninit P2P/AP network -+ */ -+ -+ if (prSetP2P->u4Enable) { -+ p2pSetMode((prSetP2P->u4Mode == 1) ? TRUE : FALSE); -+ -+ if (p2pLaunch(prAdapter->prGlueInfo)) -+ ASSERT(prAdapter->fgIsP2PRegistered); -+ -+ } else { -+ DBGLOG(P2P, TRACE, "prAdapter->fgIsP2PRegistered = %d\n", prAdapter->fgIsP2PRegistered); -+ -+ if (prAdapter->fgIsP2PRegistered) { -+ DBGLOG(P2P, INFO, "p2pRemove\n"); -+ p2pRemove(prAdapter->prGlueInfo); -+ } -+ -+ } -+ -+#if 0 -+ prP2pNetdevRegMsg = (P_MSG_P2P_NETDEV_REGISTER_T) cnmMemAlloc(prAdapter, -+ RAM_TYPE_MSG, -+ (sizeof(MSG_P2P_NETDEV_REGISTER_T))); -+ -+ if (prP2pNetdevRegMsg == NULL) { -+ ASSERT(FALSE); -+ status = WLAN_STATUS_RESOURCES; -+ return status; -+ } -+ -+ prP2pNetdevRegMsg->rMsgHdr.eMsgId = MID_MNY_P2P_NET_DEV_REGISTER; -+ prP2pNetdevRegMsg->fgIsEnable = (prSetP2P->u4Enable == 1) ? TRUE : FALSE; -+ prP2pNetdevRegMsg->ucMode = (UINT_8) prSetP2P->u4Mode; -+ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prP2pNetdevRegMsg, MSG_SEND_METHOD_BUF); -+#endif -+ -+ return status; -+} -+#endif -+ -+#if CFG_SUPPORT_BUILD_DATE_CODE -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is used to query build date code information from firmware -+* -+* \param[in] pvAdapter Pointer to the Adapter structure. -+* \param[out] pvQueryBuffer A pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufferLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryBuildDateCode(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ CMD_GET_BUILD_DATE_CODE rCmdGetBuildDateCode; -+ -+ DEBUGFUNC("wlanoidQueryBuildDateCode"); -+ DBGLOG(OID, LOUD, "\n"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4QueryInfoLen); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ -+ *pu4QueryInfoLen = sizeof(UINT_8) * 16; -+ -+ if (u4QueryBufferLen < sizeof(UINT_8) * 16) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_GET_BUILD_DATE_CODE, -+ FALSE, -+ TRUE, -+ TRUE, -+ nicCmdEventBuildDateCode, -+ nicOidCmdTimeoutCommon, -+ sizeof(CMD_GET_BUILD_DATE_CODE), -+ (PUINT_8) &rCmdGetBuildDateCode, pvQueryBuffer, u4QueryBufferLen); -+ -+} /* end of wlanoidQueryBuildDateCode() */ -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is used to query BSS info from firmware -+* -+* \param[in] pvAdapter Pointer to the Adapter structure. -+* \param[out] pvQueryBuffer A pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufferLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryBSSInfo(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ EVENT_AIS_BSS_INFO_T rCmdBSSInfo; -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4QueryInfoLen); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ -+ *pu4QueryInfoLen = sizeof(EVENT_AIS_BSS_INFO_T); -+ -+ if (u4QueryBufferLen < sizeof(EVENT_AIS_BSS_INFO_T)) -+ return WLAN_STATUS_INVALID_LENGTH; -+ kalMemZero(&rCmdBSSInfo, sizeof(EVENT_AIS_BSS_INFO_T)); -+ /* -+ rStatus = wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_GET_BSS_INFO, -+ FALSE, -+ TRUE, -+ TRUE, -+ nicCmdEventGetBSSInfo, -+ nicOidCmdTimeoutCommon, -+ sizeof(P_EVENT_AIS_BSS_INFO_T), -+ (PUINT_8) &rCmdBSSInfo, pvQueryBuffer, u4QueryBufferLen); -+ */ -+ rStatus = wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_GET_BSS_INFO, -+ FALSE, -+ TRUE, -+ TRUE, -+ nicCmdEventGetBSSInfo, -+ nicOidCmdTimeoutCommon, -+ sizeof(EVENT_AIS_BSS_INFO_T), -+ (PUINT_8) & rCmdBSSInfo, pvQueryBuffer, u4QueryBufferLen); -+ -+ return rStatus; -+} /* wlanoidSetWiFiWmmPsTest */ -+ -+#if CFG_SUPPORT_BATCH_SCAN -+ -+#define CMD_WLS_BATCHING "WLS_BATCHING" -+ -+#define BATCHING_SET "SET" -+#define BATCHING_GET "GET" -+#define BATCHING_STOP "STOP" -+ -+#define PARAM_SCANFREQ "SCANFREQ" -+#define PARAM_MSCAN "MSCAN" -+#define PARAM_BESTN "BESTN" -+#define PARAM_CHANNEL "CHANNEL" -+#define PARAM_RTT "RTT" -+ -+WLAN_STATUS -+batchSetCmd(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4WritenLen) -+{ -+ P_CHANNEL_INFO_T prRfChannelInfo; -+ CMD_BATCH_REQ_T rCmdBatchReq; -+ -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ PCHAR head, p, p2; -+ UINT_32 tokens; -+ INT_32 scanfreq, mscan, bestn, rtt; -+ -+ DBGLOG(SCN, TRACE, "[BATCH] command=%s, len=%u\n", (PCHAR) pvSetBuffer, (UINT_32) u4SetBufferLen); -+ -+ if (!pu4WritenLen) -+ return -EINVAL; -+ *pu4WritenLen = 0; -+ -+ if (u4SetBufferLen < kalStrLen(CMD_WLS_BATCHING)) { -+ DBGLOG(SCN, TRACE, "[BATCH] invalid len %u\n", (UINT_32) u4SetBufferLen); -+ return -EINVAL; -+ } -+ -+ head = pvSetBuffer + kalStrLen(CMD_WLS_BATCHING) + 1; -+ kalMemSet(&rCmdBatchReq, 0, sizeof(CMD_BATCH_REQ_T)); -+ -+ if (!kalStrnCmp(head, BATCHING_SET, kalStrLen(BATCHING_SET))) { -+ -+ DBGLOG(SCN, TRACE, "XXX Start Batch Scan XXX\n"); -+ -+ head += kalStrLen(BATCHING_SET) + 1; -+ -+ /* SCANFREQ, MSCAN, BESTN */ -+ tokens = kalSScanf(head, "SCANFREQ=%d MSCAN=%d BESTN=%d", &scanfreq, &mscan, &bestn); -+ if (tokens != 3) { -+ DBGLOG(SCN, TRACE, "[BATCH] Parse fail: tokens=%u, SCANFREQ=%d MSCAN=%d BESTN=%d\n", -+ (UINT_32) tokens, scanfreq, mscan, bestn); -+ return -EINVAL; -+ } -+ /* RTT */ -+ p = kalStrStr(head, PARAM_RTT); -+ if (!p) { -+ DBGLOG(SCN, TRACE, "[BATCH] Parse RTT fail. head=%s\n", head); -+ return -EINVAL; -+ } -+ tokens = kalSScanf(p, "RTT=%d", &rtt); -+ if (tokens != 1) { -+ DBGLOG(SCN, TRACE, "[BATCH] Parse fail: tokens=%u, rtt=%d\n", (UINT_32) tokens, rtt); -+ return -EINVAL; -+ } -+ /* CHANNEL */ -+ p = kalStrStr(head, PARAM_CHANNEL); -+ if (!p) { -+ DBGLOG(SCN, TRACE, "[BATCH] Parse CHANNEL fail(1)\n"); -+ return -EINVAL; -+ } -+ head = p; -+ p = kalStrChr(head, '>'); -+ if (!p) { -+ DBGLOG(SCN, TRACE, "[BATCH] Parse CHANNEL fail(2)\n"); -+ return -EINVAL; -+ } -+ /* else { -+ *p = '.'; // remove '>' because sscanf can not parse <%s> -+ }*/ -+ /*tokens = kalSScanf(head, "CHANNEL=<%s", c_channel); -+ if (tokens != 1) { -+ DBGLOG(SCN, TRACE, ("[BATCH] Parse fail: tokens=%d, CHANNEL=<%s>\n", -+ tokens, c_channel)); -+ return -EINVAL; -+ } */ -+ rCmdBatchReq.ucChannelType = SCAN_CHANNEL_SPECIFIED; -+ rCmdBatchReq.ucChannelListNum = 0; -+ prRfChannelInfo = &rCmdBatchReq.arChannelList[0]; -+ p = head + kalStrLen(PARAM_CHANNEL) + 2; /* c_channel; */ -+ while ((p2 = kalStrSep((char **)&p, ",")) != NULL) { -+ if (p2 == NULL || *p2 == 0) -+ break; -+ if (*p2 == '\0') -+ continue; -+ if (*p2 == 'A') { -+ rCmdBatchReq.ucChannelType = -+ rCmdBatchReq.ucChannelType == -+ SCAN_CHANNEL_2G4 ? SCAN_CHANNEL_FULL : SCAN_CHANNEL_5G; -+ } else if (*p2 == 'B') { -+ rCmdBatchReq.ucChannelType = -+ rCmdBatchReq.ucChannelType == -+ SCAN_CHANNEL_5G ? SCAN_CHANNEL_FULL : SCAN_CHANNEL_2G4; -+ } else { -+ -+ /* Translate Freq from MHz to channel number. */ -+ prRfChannelInfo->ucChannelNum = kalStrtol(p2, NULL, 0); -+ DBGLOG(SCN, TRACE, "Scanning Channel:%u, freq: %d\n", -+ (UINT_32) prRfChannelInfo->ucChannelNum, -+ (UINT_32) nicChannelNum2Freq(prRfChannelInfo->ucChannelNum)); -+ prRfChannelInfo->ucBand = prRfChannelInfo->ucChannelNum < 15 ? BAND_2G4 : BAND_5G; -+ -+ rCmdBatchReq.ucChannelListNum++; -+ if (rCmdBatchReq.ucChannelListNum >= 32) -+ break; -+ prRfChannelInfo++; -+ } -+ } -+ -+ /* set channel for test */ -+#if 0 -+ rCmdBatchReq.ucChannelType = 4; /* SCAN_CHANNEL_SPECIFIED; */ -+ rCmdBatchReq.ucChannelListNum = 0; -+ prRfChannelInfo = &rCmdBatchReq.arChannelList[0]; -+ for (i = 1; i <= 14; i++) { -+ -+ /* filter out some */ -+ if (i == 1 || i == 5 || i == 11) -+ continue; -+ -+ /* Translate Freq from MHz to channel number. */ -+ prRfChannelInfo->ucChannelNum = i; -+ DBGLOG(SCN, TRACE, "Scanning Channel:%d, freq: %d\n", -+ prRfChannelInfo->ucChannelNum, -+ nicChannelNum2Freq(prRfChannelInfo->ucChannelNum)); -+ prRfChannelInfo->ucBand = BAND_2G4; -+ -+ rCmdBatchReq.ucChannelListNum++; -+ prRfChannelInfo++; -+ } -+#endif -+#if 0 -+ rCmdBatchReq.ucChannelType = 0; /* SCAN_CHANNEL_FULL; */ -+#endif -+ -+ rCmdBatchReq.u4Scanfreq = scanfreq; -+ rCmdBatchReq.ucMScan = mscan > CFG_BATCH_MAX_MSCAN ? CFG_BATCH_MAX_MSCAN : mscan; -+ rCmdBatchReq.ucBestn = bestn; -+ rCmdBatchReq.ucRtt = rtt; -+ DBGLOG(SCN, TRACE, "[BATCH] SCANFREQ=%u MSCAN=%u BESTN=%u RTT=%u\n", -+ (UINT_32) rCmdBatchReq.u4Scanfreq, -+ (UINT_32) rCmdBatchReq.ucMScan, -+ (UINT_32) rCmdBatchReq.ucBestn, (UINT_32) rCmdBatchReq.ucRtt; -+ -+ if (rCmdBatchReq.ucChannelType != SCAN_CHANNEL_SPECIFIED) { -+ DBGLOG(SCN, TRACE, "[BATCH] CHANNELS = %s\n", -+ rCmdBatchReq.ucChannelType == SCAN_CHANNEL_FULL ? "FULL" : -+ rCmdBatchReq.ucChannelType == SCAN_CHANNEL_2G4 ? "2.4G all" : "5G all"); -+ } else { -+ DBGLOG(SCN, TRACE, "[BATCH] CHANNEL list\n"); -+ prRfChannelInfo = &rCmdBatchReq.arChannelList[0]; -+ for (tokens = 0; tokens < rCmdBatchReq.ucChannelListNum; tokens++) { -+ DBGLOG(SCN, TRACE, "[BATCH] %s, %d\n", -+ prRfChannelInfo->ucBand == BAND_2G4 ? "2.4G" : "5G", -+ prRfChannelInfo->ucChannelNum); -+ prRfChannelInfo++; -+ } -+ } -+ -+ rCmdBatchReq.ucSeqNum = 1; -+ rCmdBatchReq.ucNetTypeIndex = NETWORK_TYPE_AIS_INDEX; -+ rCmdBatchReq.ucCmd = SCAN_BATCH_REQ_START; -+ -+ *pu4WritenLen = kalSnprintf(pvSetBuffer, 3, "%d", rCmdBatchReq.ucMScan); -+ -+ } else if (!kalStrnCmp(head, BATCHING_STOP, kalStrLen(BATCHING_STOP))) { -+ -+ DBGLOG(SCN, TRACE, "XXX Stop Batch Scan XXX\n"); -+ -+ rCmdBatchReq.ucSeqNum = 1; -+ rCmdBatchReq.ucNetTypeIndex = NETWORK_TYPE_AIS_INDEX; -+ rCmdBatchReq.ucCmd = SCAN_BATCH_REQ_STOP; -+ } else { -+ return -EINVAL; -+ } -+ -+ wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SET_BATCH_REQ, -+ TRUE, FALSE, TRUE, NULL, NULL, sizeof(CMD_BATCH_REQ_T), (PUINT_8) &rCmdBatchReq, NULL, 0); -+ -+ /* kalMemSet(pvSetBuffer, 0, u4SetBufferLen); */ -+ /* rStatus = kalSnprintf(pvSetBuffer, 2, "%s", "OK"); */ -+ -+ return rStatus; -+} -+ -+WLAN_STATUS -+batchGetCmd(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ CMD_BATCH_REQ_T rCmdBatchReq; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ P_EVENT_BATCH_RESULT_T prEventBatchResult; -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4QueryInfoLen); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ prEventBatchResult = (P_EVENT_BATCH_RESULT_T) pvQueryBuffer; -+ -+ DBGLOG(SCN, TRACE, "XXX Get Batch Scan Result (%u) XXX\n", (UINT_32) prEventBatchResult->ucScanCount); -+ -+ *pu4QueryInfoLen = sizeof(EVENT_BATCH_RESULT_T); -+ -+ rCmdBatchReq.ucSeqNum = 2; -+ rCmdBatchReq.ucCmd = SCAN_BATCH_REQ_RESULT; -+ rCmdBatchReq.ucMScan = prEventBatchResult->ucScanCount; /* Get which round result */ -+ -+ rStatus = wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SET_BATCH_REQ, -+ FALSE, -+ TRUE, -+ TRUE, -+ nicCmdEventBatchScanResult, -+ nicOidCmdTimeoutCommon, -+ sizeof(CMD_BATCH_REQ_T), -+ (PUINT_8) &rCmdBatchReq, (PVOID) pvQueryBuffer, u4QueryBufferLen); -+ -+ return rStatus; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set -+* \param[in] u4SetBufferLen The length of the set buffer -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed due to invalid length of -+* the set buffer, returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_DATA If new setting value is wrong. -+* \retval WLAN_STATUS_INVALID_LENGTH -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetBatchScanReq(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ return batchSetCmd(prAdapter, pvSetBuffer, u4SetBufferLen, pu4SetInfoLen); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] pvAdapter Pointer to the Adapter structure. -+* \param[out] pvQueryBuffer A pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufferLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryBatchScanResult(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ return batchGetCmd(prAdapter, pvQueryBuffer, u4QueryBufferLen, pu4QueryInfoLen); -+ -+} /* end of wlanoidQueryBatchScanResult() */ -+ -+#endif /* CFG_SUPPORT_BATCH_SCAN */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to request starting of schedule scan -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_ADAPTER_NOT_READY -+* \retval WLAN_STATUS_INVALID_LENGTH -+* \retval WLAN_STATUS_INVALID_DATA -+* -+* \note The setting buffer PARAM_SCHED_SCAN_REQUEST_EXT_T -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetStartSchedScan(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ P_PARAM_SCHED_SCAN_REQUEST prSchedScanRequest; -+ -+ DEBUGFUNC("wlanoidSetStartSchedScan()"); -+ -+ if (prAdapter->rAcpiState == ACPI_STATE_D3) { -+ DBGLOG(SCN, WARN, "Fail in set scheduled scan! (Adapter not ready). ACPI=D%d, Radio=%d\n", -+ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); -+ return WLAN_STATUS_ADAPTER_NOT_READY; -+ } -+ -+ ASSERT(pu4SetInfoLen); -+ *pu4SetInfoLen = 0; -+ -+ if (u4SetBufferLen != sizeof(PARAM_SCHED_SCAN_REQUEST)) { -+ return WLAN_STATUS_INVALID_LENGTH; -+ } else if (pvSetBuffer == NULL) { -+ return WLAN_STATUS_INVALID_DATA; -+ } else if (kalGetMediaStateIndicated(prAdapter->prGlueInfo) == PARAM_MEDIA_STATE_CONNECTED && -+ prAdapter->fgEnOnlineScan == FALSE) { -+ return WLAN_STATUS_FAILURE; -+ } -+ -+ if (prAdapter->fgIsRadioOff) { -+ DBGLOG(SCN, WARN, "Return from BSSID list scan! (radio off). ACPI=D%d, Radio=%d\n", -+ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); -+ return WLAN_STATUS_SUCCESS; -+ } -+ -+ prSchedScanRequest = (P_PARAM_SCHED_SCAN_REQUEST) pvSetBuffer; -+ -+ if (scnFsmSchedScanRequest(prAdapter, -+ (UINT_8) (prSchedScanRequest->u4SsidNum), -+ prSchedScanRequest->arSsid, -+ prSchedScanRequest->u4IELength, -+ prSchedScanRequest->pucIE, prSchedScanRequest->u2ScanInterval) == TRUE) { -+ return WLAN_STATUS_SUCCESS; -+ } else { -+ return WLAN_STATUS_FAILURE; -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to request termination of schedule scan -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_ADAPTER_NOT_READY -+* \retval WLAN_STATUS_INVALID_LENGTH -+* \retval WLAN_STATUS_INVALID_DATA -+* -+* \note The setting buffer PARAM_SCHED_SCAN_REQUEST_EXT_T -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetStopSchedScan(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ ASSERT(prAdapter); -+ -+ /* ask SCN module to stop scan request */ -+ if (scnFsmSchedScanStopRequest(prAdapter) == TRUE) -+ return WLAN_STATUS_SUCCESS; -+ else -+ return WLAN_STATUS_FAILURE; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to set a periodically scan action -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_ADAPTER_NOT_READY -+* \retval WLAN_STATUS_INVALID_LENGTH -+* \retval WLAN_STATUS_INVALID_DATA -+* -+* \note The setting buffer PARAM_SCHED_SCAN_REQUEST_EXT_T -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetGSCNAction(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ P_CMD_SET_PSCAN_ENABLE prCmdPscnAction; -+ P_SCAN_INFO_T prScanInfo; -+ -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ DBGLOG(SCN, TRACE, "wlanoidSetGSCNAction\n"); -+ -+ if (prAdapter->rAcpiState == ACPI_STATE_D3) { -+ DBGLOG(SCN, WARN, "Fail in set Periodically Scan! (Adapter not ready). ACPI=D%d, Radio=%d\n", -+ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); -+ return WLAN_STATUS_ADAPTER_NOT_READY; -+ } -+ -+ if (u4SetBufferLen != sizeof(CMD_SET_PSCAN_ENABLE)) -+ return WLAN_STATUS_INVALID_LENGTH; -+ else if (pvSetBuffer == NULL) -+ return WLAN_STATUS_INVALID_DATA; -+ -+ if (prAdapter->fgIsRadioOff) { -+ DBGLOG(SCN, WARN, "Return from BSSID list scan! (radio off). ACPI=D%d, Radio=%d\n", -+ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); -+ return WLAN_STATUS_SUCCESS; -+ } -+ -+ prCmdPscnAction = (P_CMD_SET_PSCAN_ENABLE) pvSetBuffer; -+ -+ if (prCmdPscnAction->ucPscanAct == ENABLE) { -+#if 0 -+ DBGLOG(OID, INFO, "set PCSN ENABLE\n"); -+ if (scnFsmPSCNAction(prAdapter, (UINT_8) (prCmdPscnAction->ucPscanAct)) == TRUE) { -+ -+ DBGLOG(OID, INFO, "wlanoidSetGSCNAction < ---\n"); -+ return WLAN_STATUS_PENDING; -+ } -+ DBGLOG(OID, INFO, "wlanoidSetGSCNAction < ---\n"); -+ return WLAN_STATUS_FAILURE; -+ -+#endif -+ scnPSCNFsm(prAdapter, PSCN_SCANNING, NULL, NULL, NULL, NULL, FALSE, FALSE, FALSE, TRUE); -+ } else if (prCmdPscnAction->ucPscanAct == DISABLE) { -+#if 0 -+ DBGLOG(OID, INFO, "disable PCSN\n"); -+ scnFsmPSCNAction(prAdapter, (UINT_8) DISABLE); -+ -+ DBGLOG(OID, TRACE, "set new PCSN\n"); -+ scnCombineParamsIntoPSCN(prAdapter, NULL, NULL, NULL, NULL, FALSE, FALSE, TRUE); -+ -+ DBGLOG(OID, INFO, "ENABLE or disable PCSN\n"); -+ if (!prScanInfo->fgPscnOnnning) { -+ DBGLOG(OID, INFO, "ENABLE PCSN\n"); -+ scnFsmPSCNAction(prAdapter, ENABLE); -+ } else { -+ DBGLOG(OID, INFO, "All PCSN is disabled...\n"); -+ } -+#endif -+ scnPSCNFsm(prAdapter, PSCN_RESET, NULL, NULL, NULL, NULL, FALSE, FALSE, TRUE, FALSE); -+ } -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to set a periodically scan action -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_ADAPTER_NOT_READY -+* \retval WLAN_STATUS_INVALID_LENGTH -+* \retval WLAN_STATUS_INVALID_DATA -+* -+* \note The setting buffer PARAM_SCHED_SCAN_REQUEST_EXT_T -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetGSCNAParam(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ P_PARAM_WIFI_GSCAN_CMD_PARAMS prCmdGscnParam; -+ /*UINT_8 i, j = 0;*/ -+ DBGLOG(SCN, INFO, "wlanoidSetGSCNAParam v1\n"); -+ -+ if (prAdapter->rAcpiState == ACPI_STATE_D3) { -+ DBGLOG(SCN, WARN, "Fail in set Periodically Scan! (Adapter not ready). ACPI=D%d, Radio=%d\n", -+ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); -+ return WLAN_STATUS_ADAPTER_NOT_READY; -+ } -+ if (u4SetBufferLen != sizeof(PARAM_WIFI_GSCAN_CMD_PARAMS)) { -+ DBGLOG(SCN, WARN, "(u4SetBufferLen != sizeof(P_PARAM_WIFI_GSCAN_CMD_PARAMS))\n"); -+ return WLAN_STATUS_INVALID_LENGTH; -+ } else if (pvSetBuffer == NULL) { -+ DBGLOG(SCN, WARN, "(pvSetBuffer == NULL)\n"); -+ return WLAN_STATUS_INVALID_DATA; -+ } -+ if (prAdapter->fgIsRadioOff) { -+ DBGLOG(SCN, INFO, "Return from BSSID list scan! (radio off). ACPI=D%d, Radio=%d\n", -+ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); -+ return WLAN_STATUS_SUCCESS; -+ } -+ -+ prCmdGscnParam = (P_PARAM_WIFI_GSCAN_CMD_PARAMS) pvSetBuffer; -+ /* KC-XXX memcpy(prCmdGscnParam, */ -+ /* (P_PARAM_WIFI_GSCAN_CMD_PARAMS)pvSetBuffer, */ -+ /* sizeof(PARAM_WIFI_GSCAN_CMD_PARAMS) ); */ -+ DBGLOG(SCN, INFO, -+ "prCmdGscnParam : base_period[%u], max_ap_per_scan[%u] num_buckets[%u], report_threshold[%u]\n", -+ prCmdGscnParam->base_period, prCmdGscnParam->max_ap_per_scan, prCmdGscnParam->num_buckets, -+ prCmdGscnParam->report_threshold); -+#if 0 -+ for (i = 0; i < prCmdGscnParam->num_buckets; i++) { -+ -+ DBGLOG(OID, INFO, -+ "prCmdGscnParam->buckets : band[%u], bucket[%u] num_buckets[%u], period[%u] report_events[%u]\n", -+ prCmdGscnParam->buckets[i].band, prCmdGscnParam->buckets[i].bucket, -+ prCmdGscnParam->buckets[i].num_channels, prCmdGscnParam->buckets[i].period, -+ prCmdGscnParam->buckets[i].report_events)); -+ DBGLOG(OID, INFO, "prCmdGscnParam->buckets[%d] has channel: ", i); -+ for (j = 0; j < prCmdGscnParam->buckets[i].num_channels; j++) -+ DBGLOG(OID, INFO, " %d, ", prCmdGscnParam->buckets[i].channels[j].channel); -+ DBGLOG(OID, INFO, "\n"); -+ } -+#endif -+ if (scnSetGSCNParam(prAdapter, prCmdGscnParam) == TRUE) { -+ DBGLOG(SCN, INFO, "wlanoidSetGSCNAParam --->scnSetGSCNParam\n"); -+ return WLAN_STATUS_PENDING; -+ } else { -+ return WLAN_STATUS_FAILURE; -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to set configure gscan PARAMs -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_ADAPTER_NOT_READY -+* \retval WLAN_STATUS_INVALID_LENGTH -+* \retval WLAN_STATUS_INVALID_DATA -+* -+* \note The setting buffer PARAM_SCHED_SCAN_REQUEST_EXT_T -+*/ -+/*----------------------------------------------------------------------------*/ -+ -+WLAN_STATUS -+wlanoidSetGSCNAConfig(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ P_PARAM_WIFI_GSCAN_CMD_PARAMS prCmdGscnScnConfigParam; -+ CMD_GSCN_SCN_COFIG_T rCmdGscnScnConfig; -+ -+ DBGLOG(SCN, INFO, "wlanoidSetGSCNAConfig v1\n"); -+ -+ if (prAdapter->rAcpiState == ACPI_STATE_D3) { -+ DBGLOG(SCN, WARN, "Fail in set Periodically Scan! (Adapter not ready). ACPI=D%d, Radio=%d\n", -+ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); -+ return WLAN_STATUS_ADAPTER_NOT_READY; -+ } -+ if (u4SetBufferLen != sizeof(PARAM_WIFI_GSCAN_CMD_PARAMS)) { -+ DBGLOG(SCN, WARN, "(u4SetBufferLen != sizeof(CMD_GSCN_SCN_COFIG_T))\n"); -+ return WLAN_STATUS_INVALID_LENGTH; -+ } else if (pvSetBuffer == NULL) { -+ DBGLOG(SCN, WARN, "(pvSetBuffer == NULL)\n"); -+ return WLAN_STATUS_INVALID_DATA; -+ } -+ if (prAdapter->fgIsRadioOff) { -+ DBGLOG(SCN, INFO, "Return from BSSID list scan! (radio off). ACPI=D%d, Radio=%d\n", -+ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); -+ return WLAN_STATUS_SUCCESS; -+ } -+ -+ DBGLOG(SCN, INFO, "prCmdGscnScnConfigParam = (P_PARAM_WIFI_GSCAN_CMD_PARAMS)pvSetBuffer\n"); -+ prCmdGscnScnConfigParam = (P_PARAM_WIFI_GSCAN_CMD_PARAMS) pvSetBuffer; -+ memcpy(prCmdGscnScnConfigParam, (P_PARAM_WIFI_GSCAN_CMD_PARAMS) pvSetBuffer, -+ sizeof(PARAM_WIFI_GSCAN_CMD_PARAMS)); -+ DBGLOG(SCN, INFO, "prCmdGscnScnConfigParam assign prCmdGscnScnConfig\n"); -+ rCmdGscnScnConfig.u4BufferThreshold = prCmdGscnScnConfigParam->report_threshold; -+ rCmdGscnScnConfig.ucNumApPerScn = prCmdGscnScnConfigParam->max_ap_per_scan; -+ rCmdGscnScnConfig.u4NumScnToCache = prCmdGscnScnConfigParam->num_scans; -+ DBGLOG(SCN, INFO, " report_threshold %d report_threshold %d num_scans %d\n", -+ rCmdGscnScnConfig.u4BufferThreshold, -+ rCmdGscnScnConfig.ucNumApPerScn, rCmdGscnScnConfig.u4NumScnToCache); -+ if (scnFsmSetGSCNConfig(prAdapter, &rCmdGscnScnConfig) == TRUE) { -+ DBGLOG(SCN, INFO, "wlanoidSetGSCNAParam --->scnSetGSCNParam\n"); -+ return WLAN_STATUS_PENDING; -+ } else { -+ return WLAN_STATUS_FAILURE; -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to get a gscan result -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_ADAPTER_NOT_READY -+* \retval WLAN_STATUS_INVALID_LENGTH -+* \retval WLAN_STATUS_INVALID_DATA -+* -+* \note The setting buffer PARAM_SCHED_SCAN_REQUEST_EXT_T -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidGetGSCNResult(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ P_PARAM_WIFI_GSCAN_GET_RESULT_PARAMS prGetGscnScnResultParm; -+ CMD_GET_GSCAN_RESULT_T rGetGscnScnResultCmd; -+ -+ DEBUGFUNC("wlanoidGetGSCNResult()"); -+ DBGLOG(SCN, INFO, "wlanoidGetGSCNResult v1\n"); -+ if (prAdapter->rAcpiState == ACPI_STATE_D3) { -+ DBGLOG(SCN, WARN, "Fail in set Periodically Scan! (Adapter not ready). ACPI=D%d, Radio=%d\n", -+ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); -+ return WLAN_STATUS_ADAPTER_NOT_READY; -+ } -+ -+ if (u4SetBufferLen != sizeof(PARAM_WIFI_GSCAN_GET_RESULT_PARAMS)) { -+ DBGLOG(SCN, WARN, "(u4SetBufferLen != sizeof(CMD_GSCN_SCN_COFIG_T))\n"); -+ return WLAN_STATUS_INVALID_LENGTH; -+ } else if (pvSetBuffer == NULL) { -+ DBGLOG(SCN, WARN, "(pvSetBuffer == NULL)\n"); -+ return WLAN_STATUS_INVALID_DATA; -+ } -+ -+ if (prAdapter->fgIsRadioOff) { -+ DBGLOG(SCN, INFO, "Return from BSSID list scan! (radio off). ACPI=D%d, Radio=%d\n", -+ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); -+ return WLAN_STATUS_SUCCESS; -+ } -+ -+ prGetGscnScnResultParm = (P_PARAM_WIFI_GSCAN_GET_RESULT_PARAMS) pvSetBuffer; -+ /* memcpy(&rGetGscnScnResultCmd, prGetGscnScnResultParm, sizeof(PARAM_WIFI_GSCAN_GET_RESULT_PARAMS) ); */ -+ -+ rGetGscnScnResultCmd.u4Num = prGetGscnScnResultParm->get_num; -+ rGetGscnScnResultCmd.ucFlush = prGetGscnScnResultParm->flush; -+ rGetGscnScnResultCmd.ucVersion = PSCAN_VERSION; -+ kalMemZero(rGetGscnScnResultCmd.aucReserved, sizeof(rGetGscnScnResultCmd.aucReserved)); -+ -+ if (scnFsmGetGSCNResult(prAdapter, &rGetGscnScnResultCmd) == TRUE) { -+ DBGLOG(SCN, INFO, "wlanoidGetGSCNResult --->scnFsmGetGSCNResult\n"); -+ return WLAN_STATUS_PENDING; -+ } else { -+ return WLAN_STATUS_FAILURE; -+ } -+ -+} -+ -+#if CFG_SUPPORT_HOTSPOT_2_0 -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called by HS2.0 to set the assoc info, which is needed to add to -+* Association request frame while join HS2.0 AP. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set -+* \param[in] u4SetBufferLen The length of the set buffer -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed due to invalid length of -+* the set buffer, returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_DATA If new setting value is wrong. -+* \retval WLAN_STATUS_INVALID_LENGTH -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetHS20Info(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ P_IE_HS20_INDICATION_T prHS20IndicationIe; -+ -+ ASSERT(prAdapter); -+ ASSERT(pvSetBuffer); -+ ASSERT(pu4SetInfoLen); -+ -+ DEBUGFUNC("wlanoidSetHS20AssocInfo"); -+ DBGLOG(OID, LOUD, "\r\n"); -+ -+ if (u4SetBufferLen == 0) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ *pu4SetInfoLen = u4SetBufferLen; -+ -+ prHS20IndicationIe = (P_IE_HS20_INDICATION_T) pvSetBuffer; -+ -+ prAdapter->prGlueInfo->ucHotspotConfig = prHS20IndicationIe->ucHotspotConfig; -+ prAdapter->prGlueInfo->fgConnectHS20AP = TRUE; -+ -+ DBGLOG(SEC, TRACE, "HS20 IE sz %u\n", u4SetBufferLen); -+ -+ kalMemCopy(prAdapter->prGlueInfo->aucHS20AssocInfoIE, pvSetBuffer, u4SetBufferLen); -+ prAdapter->prGlueInfo->u2HS20AssocInfoIELen = (UINT_16) u4SetBufferLen; -+ DBGLOG(SEC, TRACE, "HS20 Assoc Info IE sz %u\n", u4SetBufferLen); -+ -+ return WLAN_STATUS_SUCCESS; -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called by WSC to set the assoc info, which is needed to add to -+* Association request frame while join WPS AP. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set -+* \param[in] u4SetBufferLen The length of the set buffer -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed due to invalid length of -+* the set buffer, returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_DATA If new setting value is wrong. -+* \retval WLAN_STATUS_INVALID_LENGTH -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetInterworkingInfo(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+#if 0 -+ P_HS20_INFO_T prHS20Info = NULL; -+ P_IE_INTERWORKING_T prInterWorkingIe; -+ -+ ASSERT(prAdapter); -+ ASSERT(pvSetBuffer); -+ ASSERT(pu4SetInfoLen); -+ -+ prHS20Info = &(prAdapter->rWifiVar.rHS20Info); -+ -+ DEBUGFUNC("wlanoidSetInterworkingInfo"); -+ DBGLOG(OID, TRACE, "\r\n"); -+ -+ if (u4SetBufferLen == 0) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ *pu4SetInfoLen = u4SetBufferLen; -+ prInterWorkingIe = (P_IE_INTERWORKING_T) pvSetBuffer; -+ -+ prHS20Info->ucAccessNetworkOptions = prInterWorkingIe->ucAccNetOpt; -+ prHS20Info->ucVenueGroup = prInterWorkingIe->ucVenueGroup; -+ prHS20Info->ucVenueType = prInterWorkingIe->ucVenueType; -+ COPY_MAC_ADDR(prHS20Info->aucHESSID, prInterWorkingIe->aucHESSID); -+ -+ DBGLOG(SEC, TRACE, "IW IE sz %ld\n", u4SetBufferLen); -+#endif -+ return WLAN_STATUS_SUCCESS; -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called by WSC to set the Roaming Consortium IE info, which is needed to -+* add to Association request frame while join WPS AP. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set -+* \param[in] u4SetBufferLen The length of the set buffer -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed due to invalid length of -+* the set buffer, returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_DATA If new setting value is wrong. -+* \retval WLAN_STATUS_INVALID_LENGTH -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetRoamingConsortiumIEInfo(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+#if 0 -+ P_HS20_INFO_T prHS20Info = NULL; -+ P_PARAM_HS20_ROAMING_CONSORTIUM_INFO prRCInfo; -+ -+ ASSERT(prAdapter); -+ ASSERT(pvSetBuffer); -+ ASSERT(pu4SetInfoLen); -+ -+ prHS20Info = &(prAdapter->rWifiVar.rHS20Info); -+ -+ /* DEBUGFUNC("wlanoidSetRoamingConsortiumInfo"); */ -+ /* DBGLOG(HS2, TRACE, ("\r\n")); */ -+ -+ if (u4SetBufferLen == 0) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ *pu4SetInfoLen = u4SetBufferLen; -+ prRCInfo = (P_PARAM_HS20_ROAMING_CONSORTIUM_INFO) pvSetBuffer; -+ -+ kalMemCopy(&(prHS20Info->rRCInfo), prRCInfo, sizeof(PARAM_HS20_ROAMING_CONSORTIUM_INFO)); -+ -+ /* DBGLOG(HS2, TRACE, ("RoamingConsortium IE sz %ld\n", u4SetBufferLen)); */ -+#endif -+ return WLAN_STATUS_SUCCESS; -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to set_bssid_pool -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer Pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+* \retval WLAN_STATUS_ADAPTER_NOT_READY -+* \retval WLAN_STATUS_MULTICAST_FULL -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetHS20BssidPool(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ WLAN_STATUS rWlanStatus = WLAN_STATUS_SUCCESS; -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ if (u4SetBufferLen) -+ ASSERT(pvSetBuffer); -+ -+ if (u4SetBufferLen < sizeof(PARAM_HS20_SET_BSSID_POOL)) { -+ *pu4SetInfoLen = sizeof(PARAM_HS20_SET_BSSID_POOL); -+ return WLAN_STATUS_BUFFER_TOO_SHORT; -+ } -+ -+ rWlanStatus = hs20SetBssidPool(prAdapter, pvSetBuffer, NETWORK_TYPE_AIS_INDEX); -+ -+ return rWlanStatus; -+} /* end of wlanoidSendHS20GASRequest() */ -+ -+#endif -+ -+#if CFG_SUPPORT_ROAMING_ENC -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to query the MAC address the NIC is currently using. -+* -+* \param[in] pvAdapter Pointer to the Adapter structure -+* \param[in] pvQueryBuf A pointer to the buffer that holds the result of the -+* query buffer -+* \param[in] u4QueryBufLen The length of the query buffer -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_BUFFER_TOO_SHORT -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetRoamingInfo(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ CMD_ROAMING_INFO_T *prCmdRoamingInfo; -+ -+ DEBUGFUNC("wlanoidSetRoamingInfo"); -+ DBGLOG(OID, LOUD, "\n"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ *pu4SetInfoLen = sizeof(CMD_ROAMING_INFO_T); -+ -+ if (u4SetBufferLen < sizeof(CMD_ROAMING_INFO_T)) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ ASSERT(pvSetBuffer); -+ prCmdRoamingInfo = (CMD_ROAMING_INFO_T *) pvSetBuffer; -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SET_ROAMING_INFO, -+ TRUE, -+ FALSE, -+ TRUE, -+ nicCmdEventSetCommon, -+ nicOidCmdTimeoutCommon, -+ sizeof(CMD_ROAMING_INFO_T), (PUINT_8) prCmdRoamingInfo, NULL, 0); -+} -+#endif /* CFG_SUPPORT_ROAMING_ENC */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to set chip -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetChipConfig(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ P_PARAM_CUSTOM_CHIP_CONFIG_STRUCT_T prChipConfigInfo; -+ CMD_CHIP_CONFIG_T rCmdChipConfig; -+ WLAN_STATUS rWlanStatus = WLAN_STATUS_SUCCESS; -+ -+ DATA_STRUCT_INSPECTING_ASSERT(sizeof(prChipConfigInfo->aucCmd) == CHIP_CONFIG_RESP_SIZE); -+ DEBUGFUNC("wlanoidSetChipConfig"); -+ DBGLOG(OID, LOUD, "\n"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ *pu4SetInfoLen = sizeof(PARAM_CUSTOM_CHIP_CONFIG_STRUCT_T); -+ -+ if (u4SetBufferLen < sizeof(PARAM_CUSTOM_CHIP_CONFIG_STRUCT_T)) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ ASSERT(pvSetBuffer); -+ -+ prChipConfigInfo = (P_PARAM_CUSTOM_CHIP_CONFIG_STRUCT_T) pvSetBuffer; -+ kalMemZero(&rCmdChipConfig, sizeof(rCmdChipConfig)); -+ -+ rCmdChipConfig.u2Id = prChipConfigInfo->u2Id; -+ rCmdChipConfig.ucType = prChipConfigInfo->ucType; -+ rCmdChipConfig.ucRespType = prChipConfigInfo->ucRespType; -+ rCmdChipConfig.u2MsgSize = prChipConfigInfo->u2MsgSize; -+ if (rCmdChipConfig.u2MsgSize > CHIP_CONFIG_RESP_SIZE) { -+ DBGLOG(OID, INFO, "Chip config Msg Size %u is not valid (set)\n", rCmdChipConfig.u2MsgSize); -+ rCmdChipConfig.u2MsgSize = CHIP_CONFIG_RESP_SIZE; -+ } -+ kalMemCopy(rCmdChipConfig.aucCmd, prChipConfigInfo->aucCmd, rCmdChipConfig.u2MsgSize); -+ -+ DBGLOG(OID, TRACE, "rCmdChipConfig.aucCmd=%s\n", rCmdChipConfig.aucCmd); -+#if 1 -+ rWlanStatus = wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_CHIP_CONFIG, -+ TRUE, -+ FALSE, -+ TRUE, -+ nicCmdEventSetCommon, -+ nicOidCmdTimeoutCommon, -+ sizeof(CMD_CHIP_CONFIG_T), -+ (PUINT_8) &rCmdChipConfig, pvSetBuffer, u4SetBufferLen); -+#endif -+ return rWlanStatus; -+} /* wlanoidSetChipConfig */ -+ -+WLAN_STATUS -+wlanoidSetWfdDebugMode(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ P_CMD_WFD_DEBUG_MODE_INFO_T prCmdWfdDebugModeInfo; -+ -+ DEBUGFUNC("wlanoidSetWFDDebugMode"); -+ DBGLOG(OID, LOUD, "\n"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ *pu4SetInfoLen = sizeof(CMD_WFD_DEBUG_MODE_INFO_T); -+ -+ if (u4SetBufferLen < sizeof(CMD_WFD_DEBUG_MODE_INFO_T)) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ ASSERT(pvSetBuffer); -+ prCmdWfdDebugModeInfo = (CMD_WFD_DEBUG_MODE_INFO_T *) pvSetBuffer; -+ -+ DBGLOG(OID, INFO, "New WFD Debug: %d mode and period=0x%x\n", prCmdWfdDebugModeInfo->ucDebugMode, -+ prCmdWfdDebugModeInfo->u2PeriodInteval); -+ -+ prAdapter->rWifiVar.prP2pFsmInfo->rWfdDebugSetting.ucWfdDebugMode = (UINT_8) prCmdWfdDebugModeInfo->ucDebugMode; -+ prAdapter->rWifiVar.prP2pFsmInfo->rWfdDebugSetting.u2WfdSNShowPeiroid = -+ (UINT_16) prCmdWfdDebugModeInfo->u2PeriodInteval; -+ -+ return WLAN_STATUS_SUCCESS; -+} /*wlanoidSetWfdDebugMode */ -+ -+ -+#if (CFG_SUPPORT_TXR_ENC == 1) -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to query the MAC address the NIC is currently using. -+* -+* \param[in] pvAdapter Pointer to the Adapter structure -+* \param[in] pvQueryBuf A pointer to the buffer that holds the result of the -+* query buffer -+* \param[in] u4QueryBufLen The length of the query buffer -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_BUFFER_TOO_SHORT -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetTxRateInfo( -+ IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, -+ IN UINT_32 u4SetBufferLen, -+ OUT PUINT_32 pu4SetInfoLen) -+{ -+ CMD_RLM_INFO_T *prCmdTxRInfo; -+ -+ DEBUGFUNC("wlanoidSetTxRateInfo"); -+ DBGLOG(OID, LOUD, "\n"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ *pu4SetInfoLen = sizeof(CMD_RLM_INFO_T); -+ -+ if (u4SetBufferLen < sizeof(CMD_RLM_INFO_T)) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ ASSERT(pvSetBuffer); -+ prCmdTxRInfo = (CMD_RLM_INFO_T *)pvSetBuffer; -+ -+ DBGLOG(OID, INFO, " command = %u %u %u %u %d %u %u\n", -+ prCmdTxRInfo->u4Version, -+ prCmdTxRInfo->fgIsErrRatioEnhanceApplied, -+ prCmdTxRInfo->ucErrRatio2LimitMinRate, -+ prCmdTxRInfo->ucMinLegacyRateIdx, -+ prCmdTxRInfo->cMinRssiThreshold, -+ prCmdTxRInfo->fgIsRtsApplied, -+ prCmdTxRInfo->ucRecoverTime)); -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_TX_AR_ERR_CONFIG, -+ TRUE, -+ FALSE, -+ TRUE, -+ nicCmdEventSetCommon, -+ nicOidCmdTimeoutCommon, -+ sizeof(CMD_RLM_INFO_T), -+ (PUINT_8)prCmdTxRInfo, -+ NULL, -+ 0 -+ ); -+} -+#endif /* CFG_SUPPORT_TXR_ENC */ -+ -+WLAN_STATUS -+wlanoidNotifyFwSuspend(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ WIFI_SYSTEM_SUSPEND_CMD_T rSuspendCmd; -+ -+ if (!prAdapter || !pvSetBuffer) -+ return WLAN_STATUS_INVALID_DATA; -+ -+ rSuspendCmd.fgIsSystemSuspend = *(PBOOLEAN)pvSetBuffer; -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SET_SYSTEM_SUSPEND, -+ TRUE, -+ FALSE, -+ TRUE, -+ nicCmdEventSetCommon, -+ nicOidCmdTimeoutCommon, -+ sizeof(BOOLEAN), -+ (PUINT_8)&rSuspendCmd, -+ NULL, -+ 0); -+} -+ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/common/wlan_p2p.c b/drivers/misc/mediatek/connectivity/wlan/gen2/common/wlan_p2p.c -new file mode 100644 -index 000000000000..7ca7ee48922e ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/common/wlan_p2p.c -@@ -0,0 +1,1654 @@ -+/* -+** Id: //Department/DaVinci/TRUNK/WiFi_P2P_Driver/common/wlan_p2p.c#8 -+*/ -+ -+/*! \file wlan_bow.c -+ \brief This file contains the Wi-Fi Direct commands processing routines for -+ MediaTek Inc. 802.11 Wireless LAN Adapters. -+*/ -+ -+/* -+** Log: wlan_p2p.c -+ * -+ * 07 17 2012 yuche.tsai -+ * NULL -+ * Compile no error before trial run. -+ * -+ * 11 24 2011 yuche.tsai -+ * NULL -+ * Fix P2P IOCTL of multicast address bug, add low power driver stop control. -+ * -+ * 11 22 2011 yuche.tsai -+ * NULL -+ * Update RSSI link quality of P2P Network query method. (Bug fix) -+ * -+ * 11 19 2011 yuche.tsai -+ * NULL -+ * Add RSSI support for P2P network. -+ * -+ * 11 08 2011 yuche.tsai -+ * [WCXRP00001094] [Volunteer Patch][Driver] Driver version & supplicant version query & set support -+ * for service discovery version check. -+ * Add support for driver version query & p2p supplicant verseion set. -+ * For new service discovery mechanism sync. -+ * -+ * 10 18 2011 yuche.tsai -+ * [WCXRP00001045] [WiFi Direct][Driver] Check 2.1 branch. -+ * Support Channel Query. -+ * -+ * 10 18 2011 yuche.tsai -+ * [WCXRP00001045] [WiFi Direct][Driver] Check 2.1 branch. -+ * New 2.1 branch -+ -+ * -+ * 08 23 2011 yuche.tsai -+ * NULL -+ * Fix Multicast Issue of P2P. -+ * -+ * 04 27 2011 george.huang -+ * [WCXRP00000684] [MT6620 Wi-Fi][Driver] Support P2P setting ARP filter -+ * Support P2P ARP filter setting on early suspend/ late resume -+ * -+ * 04 08 2011 george.huang -+ * [WCXRP00000621] [MT6620 Wi-Fi][Driver] Support P2P supplicant to set power mode -+ * separate settings of P2P and AIS -+ * -+ * 03 22 2011 george.huang -+ * [WCXRP00000504] [MT6620 Wi-Fi][FW] Support Sigma CAPI for power saving related command -+ * link with supplicant commands -+ * -+ * 03 17 2011 wh.su -+ * [WCXRP00000571] [MT6620 Wi-Fi] [Driver] Not check the p2p role during set key -+ * Skip the p2p role for adding broadcast key issue. -+ * -+ * 03 16 2011 wh.su -+ * [WCXRP00000530] [MT6620 Wi-Fi] [Driver] skip doing p2pRunEventAAAComplete after send assoc response Tx Done -+ * fixed compiling error while enable dbg. -+ * -+ * 03 08 2011 yuche.tsai -+ * [WCXRP00000480] [Volunteer Patch][MT6620][Driver] WCS IE format -+ * issue[WCXRP00000509] [Volunteer Patch][MT6620][Driver] Kernal panic when remove p2p module. -+ * . -+ * -+ * 03 07 2011 terry.wu -+ * [WCXRP00000521] [MT6620 Wi-Fi][Driver] Remove non-standard debug message -+ * Toggle non-standard debug messages to comments. -+ * -+ * 03 07 2011 wh.su -+ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code -+ * rename the define to anti_pviracy. -+ * -+ * 03 05 2011 wh.su -+ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code -+ * add the code to get the check rsponse and indicate to app. -+ * -+ * 03 02 2011 wh.su -+ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code -+ * Add Security check related code. -+ * -+ * 03 02 2011 yuche.tsai -+ * [WCXRP00000245] 1. Invitation Request/Response. -+2. Provision Discovery Request/Response -+ -+ * Fix SD Request Query Length issue. -+ * -+ * 03 02 2011 yuche.tsai -+ * [WCXRP00000245] 1. Invitation Request/Response. -+2. Provision Discovery Request/Response -+ -+ * Service Discovery Request. -+ * -+ * 03 01 2011 yuche.tsai -+ * [WCXRP00000245] 1. Invitation Request/Response. -+2. Provision Discovery Request/Response -+ -+ * Update Service Discovery Wlan OID related function. -+ * -+ * 03 01 2011 yuche.tsai -+ * [WCXRP00000245] 1. Invitation Request/Response. -+2. Provision Discovery Request/Response -+ -+ * Update Service Discovery Related wlanoid function. -+ * -+ * 02 09 2011 yuche.tsai -+ * [WCXRP00000245] 1. Invitation Request/Response. -+2. Provision Discovery Request/Response -+ -+ * Add Service Discovery Indication Related code. -+ * -+ * 01 26 2011 yuche.tsai -+ * [WCXRP00000245] 1. Invitation Request/Response. -+2. Provision Discovery Request/Response -+ -+ * Add Service Discovery Function. -+ * -+ * 01 05 2011 cp.wu -+ * [WCXRP00000283] [MT6620 Wi-Fi][Driver][Wi-Fi Direct] Implementation of interface -+ * for supporting Wi-Fi Direct Service Discovery ioctl implementations for P2P Service Discovery -+ * -+ * 01 04 2011 cp.wu -+ * [WCXRP00000338] [MT6620 Wi-Fi][Driver] Separate kalMemAlloc into kmalloc and vmalloc implementations to -+ * ease physically continuous memory demands separate kalMemAlloc() into virtually-continuous -+ * and physically-continuous type to ease slab system pressure -+ * -+ * 12 22 2010 cp.wu -+ * [WCXRP00000283] [MT6620 Wi-Fi][Driver][Wi-Fi Direct] Implementation of interface -+ * for supporting Wi-Fi Direct Service Discovery -+ * 1. header file restructure for more clear module isolation -+ * 2. add function interface definition for implementing Service Discovery callbacks -+ * -+ * 10 04 2010 cp.wu -+ * [WCXRP00000077] [MT6620 Wi-Fi][Driver][FW] Eliminate use of ENUM_NETWORK_TYPE_T -+ * and replaced by ENUM_NETWORK_TYPE_INDEX_T only remove ENUM_NETWORK_TYPE_T definitions -+ * -+ * 09 28 2010 wh.su -+ * NULL -+ * [WCXRP00000069][MT6620 Wi-Fi][Driver] Fix some code for phase 1 P2P Demo. -+ * -+ * 09 21 2010 kevin.huang -+ * [WCXRP00000054] [MT6620 Wi-Fi][Driver] Restructure driver for second Interface -+ * Isolate P2P related function for Hardware Software Bundle -+ * -+ * 09 03 2010 kevin.huang -+ * NULL -+ * Refine #include sequence and solve recursive/nested #include issue -+ * -+ * 08 23 2010 cp.wu -+ * NULL -+ * revise constant definitions to be matched with implementation (original cmd-event definition is deprecated) -+ * -+ * 08 16 2010 cp.wu -+ * NULL -+ * add subroutines for P2P to set multicast list. -+ * -+ * 08 16 2010 george.huang -+ * NULL -+ * . -+ * -+ * 08 16 2010 george.huang -+ * NULL -+ * support wlanoidSetP2pPowerSaveProfile() in P2P -+ * -+ * 08 16 2010 george.huang -+ * NULL -+ * Support wlanoidSetNetworkAddress() for P2P -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 25 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add API in que_mgt to retrieve sta-rec index for security frames. -+ * -+ * 06 24 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 802.1x and bluetooth-over-Wi-Fi security frames are now delievered to firmware via command path instead of data path. -+ * -+ * 06 11 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) migrate assoc.c. -+ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness -+ * 3) add configuration options for CNM_MEM and RSN modules -+ * 4) add data path for management frames -+ * 5) eliminate rPacketInfo of MSDU_INFO_T -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 05 17 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * 1) add timeout handler mechanism for pending command packets -+ * 2) add p2p add/removal key -+ * -+** -+*/ -+ -+/****************************************************************************** -+* C O M P I L E R F L A G S -+******************************************************************************* -+*/ -+ -+/****************************************************************************** -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************* -+*/ -+#include "precomp.h" -+#include "gl_p2p_ioctl.h" -+ -+/****************************************************************************** -+* C O N S T A N T S -+******************************************************************************* -+*/ -+ -+/****************************************************************************** -+* D A T A T Y P E S -+******************************************************************************* -+*/ -+ -+/****************************************************************************** -+* P U B L I C D A T A -+******************************************************************************* -+*/ -+ -+/****************************************************************************** -+* P R I V A T E D A T A -+******************************************************************************* -+*/ -+ -+/****************************************************************************** -+* M A C R O S -+******************************************************************************* -+*/ -+ -+/****************************************************************************** -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************* -+*/ -+ -+/****************************************************************************** -+* F U N C T I O N S -+******************************************************************************* -+*/ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief command packet generation utility -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] ucCID Command ID -+* \param[in] fgSetQuery Set or Query -+* \param[in] fgNeedResp Need for response -+* \param[in] pfCmdDoneHandler Function pointer when command is done -+* \param[in] u4SetQueryInfoLen The length of the set/query buffer -+* \param[in] pucInfoBuffer Pointer to set/query buffer -+* -+* -+* \retval WLAN_STATUS_PENDING -+* \retval WLAN_STATUS_FAILURE -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSendSetQueryP2PCmd(IN P_ADAPTER_T prAdapter, -+ UINT_8 ucCID, -+ BOOLEAN fgSetQuery, -+ BOOLEAN fgNeedResp, -+ BOOLEAN fgIsOid, -+ PFN_CMD_DONE_HANDLER pfCmdDoneHandler, -+ PFN_CMD_TIMEOUT_HANDLER pfCmdTimeoutHandler, -+ UINT_32 u4SetQueryInfoLen, -+ PUINT_8 pucInfoBuffer, OUT PVOID pvSetQueryBuffer, IN UINT_32 u4SetQueryBufferLen) -+{ -+ P_GLUE_INFO_T prGlueInfo; -+ P_CMD_INFO_T prCmdInfo; -+ P_WIFI_CMD_T prWifiCmd; -+ UINT_8 ucCmdSeqNum; -+ -+ ASSERT(prAdapter); -+ -+ prGlueInfo = prAdapter->prGlueInfo; -+ ASSERT(prGlueInfo); -+ -+ DEBUGFUNC("wlanoidSendSetQueryP2PCmd"); -+ DBGLOG(REQ, TRACE, "Command ID = 0x%08X\n", ucCID); -+ -+ prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, (CMD_HDR_SIZE + u4SetQueryInfoLen)); -+ -+ if (!prCmdInfo) { -+ DBGLOG(P2P, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); -+ return WLAN_STATUS_FAILURE; -+ } -+ /* increase command sequence number */ -+ ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter); -+ DBGLOG(REQ, TRACE, "ucCmdSeqNum =%d\n", ucCmdSeqNum); -+ -+ /* Setup common CMD Info Packet */ -+ prCmdInfo->eCmdType = COMMAND_TYPE_NETWORK_IOCTL; -+ prCmdInfo->eNetworkType = NETWORK_TYPE_P2P_INDEX; -+ prCmdInfo->u2InfoBufLen = (UINT_16) (CMD_HDR_SIZE + u4SetQueryInfoLen); -+ prCmdInfo->pfCmdDoneHandler = pfCmdDoneHandler; -+ prCmdInfo->pfCmdTimeoutHandler = pfCmdTimeoutHandler; -+ prCmdInfo->fgIsOid = fgIsOid; -+ prCmdInfo->ucCID = ucCID; -+ prCmdInfo->fgSetQuery = fgSetQuery; -+ prCmdInfo->fgNeedResp = fgNeedResp; -+ prCmdInfo->fgDriverDomainMCR = FALSE; -+ prCmdInfo->ucCmdSeqNum = ucCmdSeqNum; -+ prCmdInfo->u4SetInfoLen = u4SetQueryInfoLen; -+ prCmdInfo->pvInformationBuffer = pvSetQueryBuffer; -+ prCmdInfo->u4InformationBufferLength = u4SetQueryBufferLen; -+ -+ /* Setup WIFI_CMD_T (no payload) */ -+ prWifiCmd = (P_WIFI_CMD_T) (prCmdInfo->pucInfoBuffer); -+ prWifiCmd->u2TxByteCount_UserPriority = prCmdInfo->u2InfoBufLen; -+ prWifiCmd->ucCID = prCmdInfo->ucCID; -+ prWifiCmd->ucSetQuery = prCmdInfo->fgSetQuery; -+ prWifiCmd->ucSeqNum = prCmdInfo->ucCmdSeqNum; -+ -+ if (u4SetQueryInfoLen > 0 && pucInfoBuffer != NULL) -+ kalMemCopy(prWifiCmd->aucBuffer, pucInfoBuffer, u4SetQueryInfoLen); -+ /* insert into prCmdQueue */ -+ kalEnqueueCommand(prGlueInfo, (P_QUE_ENTRY_T) prCmdInfo); -+ -+ /* wakeup txServiceThread later */ -+ GLUE_SET_EVENT(prGlueInfo); -+ return WLAN_STATUS_PENDING; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to set a key to Wi-Fi Direct driver -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_ADAPTER_NOT_READY -+* \retval WLAN_STATUS_INVALID_LENGTH -+* \retval WLAN_STATUS_INVALID_DATA -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetAddP2PKey(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ CMD_802_11_KEY rCmdKey; -+ P_PARAM_KEY_T prNewKey; -+ -+ DEBUGFUNC("wlanoidSetAddP2PKey"); -+ DBGLOG(REQ, INFO, "\n"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pvSetBuffer); -+ ASSERT(pu4SetInfoLen); -+ -+ prNewKey = (P_PARAM_KEY_T) pvSetBuffer; -+ -+ /* Verify the key structure length. */ -+ if (prNewKey->u4Length > u4SetBufferLen) { -+ DBGLOG(REQ, WARN, "Invalid key structure length (%d) greater than total buffer length (%d)\n", -+ (UINT_8) prNewKey->u4Length, (UINT_8) u4SetBufferLen); -+ -+ *pu4SetInfoLen = u4SetBufferLen; -+ return WLAN_STATUS_INVALID_LENGTH; -+ } -+ /* Verify the key material length for key material buffer */ -+ else if (prNewKey->u4KeyLength > prNewKey->u4Length - OFFSET_OF(PARAM_KEY_T, aucKeyMaterial)) { -+ DBGLOG(REQ, WARN, "Invalid key material length (%d)\n", (UINT_8) prNewKey->u4KeyLength); -+ *pu4SetInfoLen = u4SetBufferLen; -+ return WLAN_STATUS_INVALID_DATA; -+ } -+ /* Exception check */ -+ else if (prNewKey->u4KeyIndex & 0x0fffff00) -+ return WLAN_STATUS_INVALID_DATA; -+ /* Exception check, pairwise key must with transmit bit enabled */ -+ else if ((prNewKey->u4KeyIndex & BITS(30, 31)) == IS_UNICAST_KEY) { -+ return WLAN_STATUS_INVALID_DATA; -+ } else if (!(prNewKey->u4KeyLength == CCMP_KEY_LEN) && !(prNewKey->u4KeyLength == TKIP_KEY_LEN)) { -+ return WLAN_STATUS_INVALID_DATA; -+ } -+ /* Exception check, pairwise key must with transmit bit enabled */ -+ else if ((prNewKey->u4KeyIndex & BITS(30, 31)) == BITS(30, 31)) { -+ if (((prNewKey->u4KeyIndex & 0xff) != 0) || -+ ((prNewKey->arBSSID[0] == 0xff) && (prNewKey->arBSSID[1] == 0xff) && (prNewKey->arBSSID[2] == 0xff) -+ && (prNewKey->arBSSID[3] == 0xff) && (prNewKey->arBSSID[4] == 0xff) -+ && (prNewKey->arBSSID[5] == 0xff))) { -+ return WLAN_STATUS_INVALID_DATA; -+ } -+ } -+ -+ *pu4SetInfoLen = u4SetBufferLen; -+ -+ /* fill CMD_802_11_KEY */ -+ kalMemZero(&rCmdKey, sizeof(CMD_802_11_KEY)); -+ rCmdKey.ucAddRemove = 1; /* add */ -+ rCmdKey.ucTxKey = ((prNewKey->u4KeyIndex & IS_TRANSMIT_KEY) == IS_TRANSMIT_KEY) ? 1 : 0; -+ rCmdKey.ucKeyType = ((prNewKey->u4KeyIndex & IS_UNICAST_KEY) == IS_UNICAST_KEY) ? 1 : 0; -+ if (kalP2PGetRole(prAdapter->prGlueInfo) == 1) { /* group client */ -+ rCmdKey.ucIsAuthenticator = 0; -+ } else { /* group owner */ -+ rCmdKey.ucIsAuthenticator = 1; -+ } -+ COPY_MAC_ADDR(rCmdKey.aucPeerAddr, prNewKey->arBSSID); -+ rCmdKey.ucNetType = NETWORK_TYPE_P2P_INDEX; -+ if (prNewKey->u4KeyLength == CCMP_KEY_LEN) -+ rCmdKey.ucAlgorithmId = CIPHER_SUITE_CCMP; /* AES */ -+ else if (prNewKey->u4KeyLength == TKIP_KEY_LEN) -+ rCmdKey.ucAlgorithmId = CIPHER_SUITE_TKIP; /* TKIP */ -+ rCmdKey.ucKeyId = (UINT_8) (prNewKey->u4KeyIndex & 0xff); -+ rCmdKey.ucKeyLen = (UINT_8) prNewKey->u4KeyLength; -+ kalMemCopy(rCmdKey.aucKeyMaterial, (PUINT_8) prNewKey->aucKeyMaterial, rCmdKey.ucKeyLen); -+ -+ return wlanoidSendSetQueryP2PCmd(prAdapter, -+ CMD_ID_ADD_REMOVE_KEY, -+ TRUE, -+ FALSE, -+ TRUE, -+ nicCmdEventSetCommon, -+ NULL, -+ sizeof(CMD_802_11_KEY), (PUINT_8) &rCmdKey, pvSetBuffer, u4SetBufferLen); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to request Wi-Fi Direct driver to remove keys -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_DATA -+* \retval WLAN_STATUS_INVALID_LENGTH -+* \retval WLAN_STATUS_INVALID_DATA -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetRemoveP2PKey(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ CMD_802_11_KEY rCmdKey; -+ P_PARAM_REMOVE_KEY_T prRemovedKey; -+ -+ DEBUGFUNC("wlanoidSetRemoveP2PKey"); -+ ASSERT(prAdapter); -+ -+ if (u4SetBufferLen < sizeof(PARAM_REMOVE_KEY_T)) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ ASSERT(pvSetBuffer); -+ prRemovedKey = (P_PARAM_REMOVE_KEY_T) pvSetBuffer; -+ -+ /* Check bit 31: this bit should always 0 */ -+ if (prRemovedKey->u4KeyIndex & IS_TRANSMIT_KEY) { -+ /* Bit 31 should not be set */ -+ DBGLOG(REQ, ERROR, "invalid key index: 0x%08x\n", prRemovedKey->u4KeyIndex); -+ return WLAN_STATUS_INVALID_DATA; -+ } -+ -+ /* Check bits 8 ~ 29 should always be 0 */ -+ if (prRemovedKey->u4KeyIndex & BITS(8, 29)) { -+ /* Bit 31 should not be set */ -+ DBGLOG(REQ, ERROR, "invalid key index: 0x%08x\n", prRemovedKey->u4KeyIndex); -+ return WLAN_STATUS_INVALID_DATA; -+ } -+ -+ /* There should not be any key operation for P2P Device */ -+ if (kalP2PGetRole(prAdapter->prGlueInfo) == 0) -+ ; /* return WLAN_STATUS_NOT_ACCEPTED; */ -+ -+ kalMemZero((PUINT_8) &rCmdKey, sizeof(CMD_802_11_KEY)); -+ -+ rCmdKey.ucAddRemove = 0; /* remove */ -+ if (kalP2PGetRole(prAdapter->prGlueInfo) == 1) { /* group client */ -+ rCmdKey.ucIsAuthenticator = 0; -+ } else { /* group owner */ -+ rCmdKey.ucIsAuthenticator = 1; -+ } -+ kalMemCopy(rCmdKey.aucPeerAddr, (PUINT_8) prRemovedKey->arBSSID, MAC_ADDR_LEN); -+ rCmdKey.ucNetType = NETWORK_TYPE_P2P_INDEX; -+ rCmdKey.ucKeyId = (UINT_8) (prRemovedKey->u4KeyIndex & 0x000000ff); -+ -+ return wlanoidSendSetQueryP2PCmd(prAdapter, -+ CMD_ID_ADD_REMOVE_KEY, -+ TRUE, -+ FALSE, -+ TRUE, -+ nicCmdEventSetCommon, -+ NULL, -+ sizeof(CMD_802_11_KEY), (PUINT_8) &rCmdKey, pvSetBuffer, u4SetBufferLen); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Setting the IP address for pattern search function. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \return WLAN_STATUS_SUCCESS -+* \return WLAN_STATUS_ADAPTER_NOT_READY -+* \return WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetP2pNetworkAddress(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ UINT_32 i, j; -+ P_CMD_SET_NETWORK_ADDRESS_LIST prCmdNetworkAddressList; -+ P_PARAM_NETWORK_ADDRESS_LIST prNetworkAddressList = (P_PARAM_NETWORK_ADDRESS_LIST) pvSetBuffer; -+ P_PARAM_NETWORK_ADDRESS prNetworkAddress; -+ P_PARAM_NETWORK_ADDRESS_IP prNetAddrIp; -+ UINT_32 u4IpAddressCount, u4CmdSize; -+ -+ DEBUGFUNC("wlanoidSetP2pNetworkAddress"); -+ DBGLOG(P2P, TRACE, "\n"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ *pu4SetInfoLen = 4; -+ -+ if (u4SetBufferLen < sizeof(PARAM_NETWORK_ADDRESS_LIST)) -+ return WLAN_STATUS_INVALID_DATA; -+ -+ *pu4SetInfoLen = 0; -+ u4IpAddressCount = 0; -+ -+ prNetworkAddress = prNetworkAddressList->arAddress; -+ for (i = 0; i < prNetworkAddressList->u4AddressCount; i++) { -+ if (prNetworkAddress->u2AddressType == PARAM_PROTOCOL_ID_TCP_IP && -+ prNetworkAddress->u2AddressLength == sizeof(PARAM_NETWORK_ADDRESS_IP)) { -+ u4IpAddressCount++; -+ } -+ -+ prNetworkAddress = (P_PARAM_NETWORK_ADDRESS) ((ULONG) prNetworkAddress + -+ (ULONG) (prNetworkAddress->u2AddressLength + -+ OFFSET_OF(PARAM_NETWORK_ADDRESS, aucAddress))); -+ } -+ -+ /* construct payload of command packet */ -+ u4CmdSize = OFFSET_OF(CMD_SET_NETWORK_ADDRESS_LIST, arNetAddress) + -+ sizeof(IPV4_NETWORK_ADDRESS) * u4IpAddressCount; -+ -+ prCmdNetworkAddressList = (P_CMD_SET_NETWORK_ADDRESS_LIST) kalMemAlloc(u4CmdSize, VIR_MEM_TYPE); -+ -+ if (prCmdNetworkAddressList == NULL) -+ return WLAN_STATUS_FAILURE; -+ -+ /* fill P_CMD_SET_NETWORK_ADDRESS_LIST */ -+ prCmdNetworkAddressList->ucNetTypeIndex = NETWORK_TYPE_P2P_INDEX; -+ prCmdNetworkAddressList->ucAddressCount = (UINT_8) u4IpAddressCount; -+ prNetworkAddress = prNetworkAddressList->arAddress; -+ for (i = 0, j = 0; i < prNetworkAddressList->u4AddressCount; i++) { -+ if (prNetworkAddress->u2AddressType == PARAM_PROTOCOL_ID_TCP_IP && -+ prNetworkAddress->u2AddressLength == sizeof(PARAM_NETWORK_ADDRESS_IP)) { -+ prNetAddrIp = (P_PARAM_NETWORK_ADDRESS_IP) prNetworkAddress->aucAddress; -+ -+ kalMemCopy(prCmdNetworkAddressList->arNetAddress[j].aucIpAddr, -+ &(prNetAddrIp->in_addr), sizeof(UINT_32)); -+ -+ j++; -+ } -+ -+ prNetworkAddress = (P_PARAM_NETWORK_ADDRESS) ((ULONG) prNetworkAddress + -+ (ULONG) (prNetworkAddress->u2AddressLength + -+ OFFSET_OF(PARAM_NETWORK_ADDRESS, aucAddress))); -+ } -+ -+ rStatus = wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SET_IP_ADDRESS, -+ TRUE, -+ FALSE, -+ TRUE, -+ nicCmdEventSetIpAddress, -+ nicOidCmdTimeoutCommon, -+ u4CmdSize, (PUINT_8) prCmdNetworkAddressList, pvSetBuffer, u4SetBufferLen); -+ -+ kalMemFree(prCmdNetworkAddressList, VIR_MEM_TYPE, u4CmdSize); -+ return rStatus; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is used to query the power save profile. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[out] pvQueryBuf A pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \return WLAN_STATUS_SUCCESS -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryP2pPowerSaveProfile(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ DEBUGFUNC("wlanoidQueryP2pPowerSaveProfile"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4QueryInfoLen); -+ -+ if (u4QueryBufferLen != 0) { -+ ASSERT(pvQueryBuffer); -+ -+ *(PPARAM_POWER_MODE) pvQueryBuffer = -+ (PARAM_POWER_MODE) (prAdapter->rWlanInfo.arPowerSaveMode[NETWORK_TYPE_P2P_INDEX].ucPsProfile); -+ *pu4QueryInfoLen = sizeof(PARAM_POWER_MODE); -+ } -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is used to set the power save profile. -+* -+* \param[in] pvAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetP2pPowerSaveProfile(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ WLAN_STATUS status; -+ PARAM_POWER_MODE ePowerMode; -+ -+ DEBUGFUNC("wlanoidSetP2pPowerSaveProfile"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ *pu4SetInfoLen = sizeof(PARAM_POWER_MODE); -+ if (u4SetBufferLen < sizeof(PARAM_POWER_MODE)) { -+ DBGLOG(REQ, WARN, "Invalid length %u\n", u4SetBufferLen); -+ return WLAN_STATUS_INVALID_LENGTH; -+ } else if (*(PPARAM_POWER_MODE) pvSetBuffer >= Param_PowerModeMax) { -+ WARNLOG(("Invalid power mode %d\n", *(PPARAM_POWER_MODE) pvSetBuffer)); -+ return WLAN_STATUS_INVALID_DATA; -+ } -+ -+ ePowerMode = *(PPARAM_POWER_MODE) pvSetBuffer; -+ -+ if (prAdapter->fgEnCtiaPowerMode) { -+ if (ePowerMode == Param_PowerModeCAM) { -+ /*Todo:: Nothing*/ -+ /*Todo:: Nothing*/ -+ } else { -+ /* User setting to PS mode (Param_PowerModeMAX_PSP or Param_PowerModeFast_PSP) */ -+ -+ if (prAdapter->u4CtiaPowerMode == 0) { -+ /* force to keep in CAM mode */ -+ ePowerMode = Param_PowerModeCAM; -+ } else if (prAdapter->u4CtiaPowerMode == 1) { -+ ePowerMode = Param_PowerModeMAX_PSP; -+ } else if (prAdapter->u4CtiaPowerMode == 2) { -+ ePowerMode = Param_PowerModeFast_PSP; -+ } -+ } -+ } -+ -+ status = nicConfigPowerSaveProfile(prAdapter, NETWORK_TYPE_P2P_INDEX, ePowerMode, TRUE); -+ return status; -+} /* end of wlanoidSetP2pPowerSaveProfile() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is used to set the power save profile. -+* -+* \param[in] pvAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetP2pSetNetworkAddress(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ UINT_32 i, j; -+ P_CMD_SET_NETWORK_ADDRESS_LIST prCmdNetworkAddressList; -+ P_PARAM_NETWORK_ADDRESS_LIST prNetworkAddressList = (P_PARAM_NETWORK_ADDRESS_LIST) pvSetBuffer; -+ P_PARAM_NETWORK_ADDRESS prNetworkAddress; -+ P_PARAM_NETWORK_ADDRESS_IP prNetAddrIp; -+ UINT_32 u4IpAddressCount, u4CmdSize; -+ PUINT_8 pucBuf = (PUINT_8) pvSetBuffer; -+ -+ DEBUGFUNC("wlanoidSetP2pSetNetworkAddress"); -+ DBGLOG(P2P, TRACE, "\n"); -+ DBGLOG(P2P, INFO, "wlanoidSetP2pSetNetworkAddress (%d)\n", (INT_16) u4SetBufferLen); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ *pu4SetInfoLen = 4; -+ -+ if (u4SetBufferLen < sizeof(PARAM_NETWORK_ADDRESS_LIST)) -+ return WLAN_STATUS_INVALID_DATA; -+ -+ *pu4SetInfoLen = 0; -+ u4IpAddressCount = 0; -+ -+ prNetworkAddress = prNetworkAddressList->arAddress; -+ for (i = 0; i < prNetworkAddressList->u4AddressCount; i++) { -+ if (prNetworkAddress->u2AddressType == PARAM_PROTOCOL_ID_TCP_IP && -+ prNetworkAddress->u2AddressLength == sizeof(PARAM_NETWORK_ADDRESS_IP)) { -+ u4IpAddressCount++; -+ } -+ -+ prNetworkAddress = (P_PARAM_NETWORK_ADDRESS) ((ULONG) prNetworkAddress + -+ (ULONG) (prNetworkAddress->u2AddressLength + -+ OFFSET_OF(PARAM_NETWORK_ADDRESS, aucAddress))); -+ } -+ -+ /* construct payload of command packet */ -+ u4CmdSize = OFFSET_OF(CMD_SET_NETWORK_ADDRESS_LIST, arNetAddress) + -+ sizeof(IPV4_NETWORK_ADDRESS) * u4IpAddressCount; -+ -+ if (u4IpAddressCount == 0) -+ u4CmdSize = sizeof(CMD_SET_NETWORK_ADDRESS_LIST); -+ -+ prCmdNetworkAddressList = (P_CMD_SET_NETWORK_ADDRESS_LIST) kalMemAlloc(u4CmdSize, VIR_MEM_TYPE); -+ -+ if (prCmdNetworkAddressList == NULL) -+ return WLAN_STATUS_FAILURE; -+ -+ /* fill P_CMD_SET_NETWORK_ADDRESS_LIST */ -+ prCmdNetworkAddressList->ucNetTypeIndex = NETWORK_TYPE_P2P_INDEX; -+ -+ /* only to set IP address to FW once ARP filter is enabled */ -+ if (prAdapter->fgEnArpFilter) { -+ prCmdNetworkAddressList->ucAddressCount = (UINT_8) u4IpAddressCount; -+ prNetworkAddress = prNetworkAddressList->arAddress; -+ -+ DBGLOG(P2P, INFO, "u4IpAddressCount (%u)\n", u4IpAddressCount); -+ for (i = 0, j = 0; i < prNetworkAddressList->u4AddressCount; i++) { -+ if (prNetworkAddress->u2AddressType == PARAM_PROTOCOL_ID_TCP_IP && -+ prNetworkAddress->u2AddressLength == sizeof(PARAM_NETWORK_ADDRESS_IP)) { -+ prNetAddrIp = (P_PARAM_NETWORK_ADDRESS_IP) prNetworkAddress->aucAddress; -+ -+ kalMemCopy(prCmdNetworkAddressList->arNetAddress[j].aucIpAddr, -+ &(prNetAddrIp->in_addr), sizeof(UINT_32)); -+ -+ j++; -+ -+ pucBuf = (PUINT_8) &prNetAddrIp->in_addr; -+ DBGLOG(P2P, INFO, "prNetAddrIp->in_addr:%d:%d:%d:%d\n", -+ (UINT_8) pucBuf[0], (UINT_8) pucBuf[1], -+ (UINT_8) pucBuf[2], (UINT_8) pucBuf[3]); -+ } -+ -+ prNetworkAddress = (P_PARAM_NETWORK_ADDRESS) ((ULONG) prNetworkAddress + -+ (ULONG) (prNetworkAddress->u2AddressLength + -+ OFFSET_OF(PARAM_NETWORK_ADDRESS, -+ aucAddress))); -+ } -+ -+ } else { -+ prCmdNetworkAddressList->ucAddressCount = 0; -+ } -+ -+ rStatus = wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SET_IP_ADDRESS, -+ TRUE, -+ FALSE, -+ TRUE, -+ nicCmdEventSetIpAddress, -+ nicOidCmdTimeoutCommon, -+ u4CmdSize, (PUINT_8) prCmdNetworkAddressList, pvSetBuffer, u4SetBufferLen); -+ -+ kalMemFree(prCmdNetworkAddressList, VIR_MEM_TYPE, u4CmdSize); -+ return rStatus; -+} /* end of wlanoidSetP2pSetNetworkAddress() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to set Multicast Address List. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer Pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+* \retval WLAN_STATUS_ADAPTER_NOT_READY -+* \retval WLAN_STATUS_MULTICAST_FULL -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetP2PMulticastList(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ CMD_MAC_MCAST_ADDR rCmdMacMcastAddr; -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ /* The data must be a multiple of the Ethernet address size. */ -+ if ((u4SetBufferLen % MAC_ADDR_LEN)) { -+ DBGLOG(REQ, WARN, "Invalid MC list length %u\n", u4SetBufferLen); -+ -+ *pu4SetInfoLen = (((u4SetBufferLen + MAC_ADDR_LEN) - 1) / MAC_ADDR_LEN) * MAC_ADDR_LEN; -+ -+ return WLAN_STATUS_INVALID_LENGTH; -+ } -+ -+ *pu4SetInfoLen = u4SetBufferLen; -+ -+ /* Verify if we can support so many multicast addresses. */ -+ if ((u4SetBufferLen / MAC_ADDR_LEN) > MAX_NUM_GROUP_ADDR) { -+ DBGLOG(REQ, WARN, "Too many MC addresses\n"); -+ -+ return WLAN_STATUS_MULTICAST_FULL; -+ } -+ -+ /* NOTE(Kevin): Windows may set u4SetBufferLen == 0 && -+ * pvSetBuffer == NULL to clear exist Multicast List. -+ */ -+ if (u4SetBufferLen) -+ ASSERT(pvSetBuffer); -+ -+ if (prAdapter->rAcpiState == ACPI_STATE_D3) { -+ DBGLOG(REQ, WARN, "Fail in set multicast list! (Adapter not ready). ACPI=D%d, Radio=%d\n", -+ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); -+ return WLAN_STATUS_ADAPTER_NOT_READY; -+ } -+ -+ rCmdMacMcastAddr.u4NumOfGroupAddr = u4SetBufferLen / MAC_ADDR_LEN; -+ rCmdMacMcastAddr.ucNetTypeIndex = NETWORK_TYPE_P2P_INDEX; -+ kalMemCopy(rCmdMacMcastAddr.arAddress, pvSetBuffer, u4SetBufferLen); -+ -+ /* This CMD response is no need to complete the OID. Or the event would unsync. */ -+ return wlanoidSendSetQueryP2PCmd(prAdapter, CMD_ID_MAC_MCAST_ADDR, TRUE, FALSE, FALSE, -+ nicCmdEventSetCommon, -+ nicOidCmdTimeoutCommon, -+ sizeof(CMD_MAC_MCAST_ADDR), -+ (PUINT_8) &rCmdMacMcastAddr, pvSetBuffer, u4SetBufferLen); -+ -+} /* end of wlanoidSetP2PMulticastList() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to send GAS frame for P2P Service Discovery Request -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer Pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+* \retval WLAN_STATUS_ADAPTER_NOT_READY -+* \retval WLAN_STATUS_MULTICAST_FULL -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSendP2PSDRequest(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ WLAN_STATUS rWlanStatus = WLAN_STATUS_SUCCESS; -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ if (u4SetBufferLen) -+ ASSERT(pvSetBuffer); -+ -+ if (u4SetBufferLen < sizeof(PARAM_P2P_SEND_SD_REQUEST)) { -+ *pu4SetInfoLen = sizeof(PARAM_P2P_SEND_SD_REQUEST); -+ return WLAN_STATUS_BUFFER_TOO_SHORT; -+ } -+/* rWlanStatus = p2pFsmRunEventSDRequest(prAdapter, (P_PARAM_P2P_SEND_SD_REQUEST)pvSetBuffer); */ -+ -+ return rWlanStatus; -+} /* end of wlanoidSendP2PSDRequest() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to send GAS frame for P2P Service Discovery Response -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer Pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+* \retval WLAN_STATUS_ADAPTER_NOT_READY -+* \retval WLAN_STATUS_MULTICAST_FULL -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSendP2PSDResponse(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ WLAN_STATUS rWlanStatus = WLAN_STATUS_SUCCESS; -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ if (u4SetBufferLen) -+ ASSERT(pvSetBuffer); -+ -+ if (u4SetBufferLen < sizeof(PARAM_P2P_SEND_SD_RESPONSE)) { -+ *pu4SetInfoLen = sizeof(PARAM_P2P_SEND_SD_RESPONSE); -+ return WLAN_STATUS_BUFFER_TOO_SHORT; -+ } -+/* rWlanStatus = p2pFsmRunEventSDResponse(prAdapter, (P_PARAM_P2P_SEND_SD_RESPONSE)pvSetBuffer); */ -+ -+ return rWlanStatus; -+} /* end of wlanoidGetP2PSDRequest() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to get GAS frame for P2P Service Discovery Request -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[out] pvQueryBuffer A pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufferLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+* \retval WLAN_STATUS_ADAPTER_NOT_READY -+* \retval WLAN_STATUS_MULTICAST_FULL -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidGetP2PSDRequest(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ WLAN_STATUS rWlanStatus = WLAN_STATUS_SUCCESS; -+ /*PUINT_8 pucPacketBuffer = NULL, pucTA = NULL;*/ -+/* PUINT_8 pucChannelNum = NULL; */ -+ /*PUINT_16 pu2PacketLength = NULL;*/ -+ /*P_WLAN_MAC_HEADER_T prWlanHdr = (P_WLAN_MAC_HEADER_T) NULL;*/ -+ /*UINT_8 ucVersionNum = 0;*/ -+/* UINT_8 ucChannelNum = 0, ucSeqNum = 0; */ -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4QueryInfoLen); -+ -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ -+ if (u4QueryBufferLen < sizeof(PARAM_P2P_GET_SD_REQUEST)) { -+ *pu4QueryInfoLen = sizeof(PARAM_P2P_GET_SD_REQUEST); -+ return WLAN_STATUS_BUFFER_TOO_SHORT; -+ } -+ -+ DBGLOG(P2P, TRACE, "Get Service Discovery Request\n"); -+#if 0 -+ ucVersionNum = p2pFuncGetVersionNumOfSD(prAdapter); -+ if (ucVersionNum == 0) { -+ P_PARAM_P2P_GET_SD_REQUEST prP2pGetSdReq = (P_PARAM_P2P_GET_SD_REQUEST) pvQueryBuffer; -+ -+ pucPacketBuffer = prP2pGetSdReq->aucPacketContent; -+ pu2PacketLength = &prP2pGetSdReq->u2PacketLength; -+ pucTA = &prP2pGetSdReq->rTransmitterAddr; -+ } else { -+ P_PARAM_P2P_GET_SD_REQUEST_EX prP2pGetSdReqEx = (P_PARAM_P2P_GET_SD_REQUEST_EX) NULL; -+ -+ prP2pGetSdReqEx = (P_PARAM_P2P_GET_SD_REQUEST) pvQueryBuffer; -+ pucPacketBuffer = prP2pGetSdReqEx->aucPacketContent; -+ pu2PacketLength = &prP2pGetSdReqEx->u2PacketLength; -+ pucTA = &prP2pGetSdReqEx->rTransmitterAddr; -+ pucChannelNum = &prP2pGetSdReqEx->ucChannelNum; -+ ucSeqNum = prP2pGetSdReqEx->ucSeqNum; -+ } -+ -+ rWlanStatus = p2pFuncGetServiceDiscoveryFrame(prAdapter, -+ pucPacketBuffer, -+ (u4QueryBufferLen - sizeof(PARAM_P2P_GET_SD_REQUEST)), -+ (PUINT_32) pu2PacketLength, pucChannelNum, ucSeqNum); -+#else -+ *pu4QueryInfoLen = 0; -+ return rWlanStatus; -+#endif -+ /* -+ prWlanHdr = (P_WLAN_MAC_HEADER_T) pucPacketBuffer; -+ -+ kalMemCopy(pucTA, prWlanHdr->aucAddr2, MAC_ADDR_LEN); -+ -+ if (pu4QueryInfoLen) { -+ if (ucVersionNum == 0) -+ *pu4QueryInfoLen = (UINT_32) (sizeof(PARAM_P2P_GET_SD_REQUEST) + (*pu2PacketLength)); -+ else -+ *pu4QueryInfoLen = (UINT_32) (sizeof(PARAM_P2P_GET_SD_REQUEST_EX) + (*pu2PacketLength)); -+ -+ } -+ -+ return rWlanStatus; -+ */ -+} /* end of wlanoidGetP2PSDRequest() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to get GAS frame for P2P Service Discovery Response -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[out] pvQueryBuffer A pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufferLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+* \retval WLAN_STATUS_ADAPTER_NOT_READY -+* \retval WLAN_STATUS_MULTICAST_FULL -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidGetP2PSDResponse(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ WLAN_STATUS rWlanStatus = WLAN_STATUS_SUCCESS; -+ /*P_WLAN_MAC_HEADER_T prWlanHdr = (P_WLAN_MAC_HEADER_T) NULL;*/ -+ /* UINT_8 ucSeqNum = 0, */ -+ /*UINT_8 ucVersionNum = 0;*/ -+ /*PUINT_8 pucPacketContent = (PUINT_8) NULL, pucTA = (PUINT_8) NULL;*/ -+ /*PUINT_16 pu2PacketLength = (PUINT_16) NULL;*/ -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4QueryInfoLen); -+ -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ -+ if (u4QueryBufferLen < sizeof(PARAM_P2P_GET_SD_RESPONSE)) { -+ *pu4QueryInfoLen = sizeof(PARAM_P2P_GET_SD_RESPONSE); -+ return WLAN_STATUS_BUFFER_TOO_SHORT; -+ } -+ -+ DBGLOG(P2P, TRACE, "Get Service Discovery Response\n"); -+ -+#if 0 -+ ucVersionNum = p2pFuncGetVersionNumOfSD(prAdapter); -+ if (ucVersionNum == 0) { -+ P_PARAM_P2P_GET_SD_RESPONSE prP2pGetSdRsp = (P_PARAM_P2P_GET_SD_RESPONSE) NULL; -+ -+ prP2pGetSdRsp = (P_PARAM_P2P_GET_SD_REQUEST) pvQueryBuffer; -+ pucPacketContent = prP2pGetSdRsp->aucPacketContent; -+ pucTA = &prP2pGetSdRsp->rTransmitterAddr; -+ pu2PacketLength = &prP2pGetSdRsp->u2PacketLength; -+ } else { -+ P_PARAM_P2P_GET_SD_RESPONSE_EX prP2pGetSdRspEx = (P_PARAM_P2P_GET_SD_RESPONSE_EX) NULL; -+ -+ prP2pGetSdRspEx = (P_PARAM_P2P_GET_SD_RESPONSE_EX) pvQueryBuffer; -+ pucPacketContent = prP2pGetSdRspEx->aucPacketContent; -+ pucTA = &prP2pGetSdRspEx->rTransmitterAddr; -+ pu2PacketLength = &prP2pGetSdRspEx->u2PacketLength; -+ ucSeqNum = prP2pGetSdRspEx->ucSeqNum; -+ } -+ -+/* rWlanStatus = p2pFuncGetServiceDiscoveryFrame(prAdapter, */ -+/* pucPacketContent, */ -+/* (u4QueryBufferLen - sizeof(PARAM_P2P_GET_SD_RESPONSE)), */ -+/* (PUINT_32)pu2PacketLength, */ -+/* NULL, */ -+/* ucSeqNum); */ -+#else -+ *pu4QueryInfoLen = 0; -+ return rWlanStatus; -+#endif -+ /* -+ prWlanHdr = (P_WLAN_MAC_HEADER_T) pucPacketContent; -+ -+ kalMemCopy(pucTA, prWlanHdr->aucAddr2, MAC_ADDR_LEN); -+ -+ if (pu4QueryInfoLen) { -+ if (ucVersionNum == 0) -+ *pu4QueryInfoLen = (UINT_32) (sizeof(PARAM_P2P_GET_SD_RESPONSE) + *pu2PacketLength); -+ else -+ *pu4QueryInfoLen = (UINT_32) (sizeof(PARAM_P2P_GET_SD_RESPONSE_EX) + *pu2PacketLength); -+ } -+ -+ return rWlanStatus; -+ */ -+} /* end of wlanoidGetP2PSDResponse() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to terminate P2P Service Discovery Phase -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer Pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+* \retval WLAN_STATUS_ADAPTER_NOT_READY -+* \retval WLAN_STATUS_MULTICAST_FULL -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetP2PTerminateSDPhase(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ WLAN_STATUS rWlanStatus = WLAN_STATUS_SUCCESS; -+ P_PARAM_P2P_TERMINATE_SD_PHASE prP2pTerminateSD = (P_PARAM_P2P_TERMINATE_SD_PHASE) NULL; -+ UINT_8 aucNullAddr[] = NULL_MAC_ADDR; -+ -+ do { -+ if ((prAdapter == NULL) || (pu4SetInfoLen == NULL)) -+ break; -+ -+ if ((u4SetBufferLen) && (pvSetBuffer == NULL)) -+ break; -+ -+ if (u4SetBufferLen < sizeof(PARAM_P2P_TERMINATE_SD_PHASE)) { -+ *pu4SetInfoLen = sizeof(PARAM_P2P_TERMINATE_SD_PHASE); -+ rWlanStatus = WLAN_STATUS_BUFFER_TOO_SHORT; -+ break; -+ } -+ -+ prP2pTerminateSD = (P_PARAM_P2P_TERMINATE_SD_PHASE) pvSetBuffer; -+ -+ if (EQUAL_MAC_ADDR(prP2pTerminateSD->rPeerAddr, aucNullAddr)) { -+ DBGLOG(P2P, TRACE, "Service Discovery Version 2.0\n"); -+/* p2pFuncSetVersionNumOfSD(prAdapter, 2); */ -+ } -+ /* rWlanStatus = p2pFsmRunEventSDAbort(prAdapter); */ -+ -+ } while (FALSE); -+ -+ return rWlanStatus; -+} /* end of wlanoidSetP2PTerminateSDPhase() */ -+ -+#if CFG_SUPPORT_ANTI_PIRACY -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer Pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+* \retval WLAN_STATUS_ADAPTER_NOT_READY -+* \retval WLAN_STATUS_MULTICAST_FULL -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetSecCheckRequest(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ if (u4SetBufferLen) -+ ASSERT(pvSetBuffer); -+ -+ return wlanoidSendSetQueryP2PCmd(prAdapter, -+ CMD_ID_SEC_CHECK, -+ FALSE, -+ TRUE, -+ TRUE, -+ NULL, -+ nicOidCmdTimeoutCommon, -+ u4SetBufferLen, (PUINT_8) pvSetBuffer, pvSetBuffer, u4SetBufferLen); -+ -+} /* end of wlanoidSetSecCheckRequest() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[out] pvQueryBuffer A pointer to the buffer that holds the result of -+* the query. -+* \param[in] u4QueryBufferLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+* \retval WLAN_STATUS_ADAPTER_NOT_READY -+* \retval WLAN_STATUS_MULTICAST_FULL -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidGetSecCheckResponse(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ WLAN_STATUS rWlanStatus = WLAN_STATUS_SUCCESS; -+ /* P_WLAN_MAC_HEADER_T prWlanHdr = (P_WLAN_MAC_HEADER_T)NULL; */ -+ P_GLUE_INFO_T prGlueInfo; -+ -+ prGlueInfo = prAdapter->prGlueInfo; -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4QueryInfoLen); -+ -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ -+ if (u4QueryBufferLen > 256) -+ u4QueryBufferLen = 256; -+ -+ *pu4QueryInfoLen = u4QueryBufferLen; -+ -+#if DBG -+ DBGLOG_MEM8(SEC, LOUD, prGlueInfo->prP2PInfo->aucSecCheckRsp, u4QueryBufferLen); -+#endif -+ kalMemCopy((PUINT_8) (pvQueryBuffer + OFFSET_OF(IW_P2P_TRANSPORT_STRUCT, aucBuffer)), -+ prGlueInfo->prP2PInfo->aucSecCheckRsp, u4QueryBufferLen); -+ -+ return rWlanStatus; -+} /* end of wlanoidGetSecCheckResponse() */ -+#endif -+ -+WLAN_STATUS -+wlanoidSetNoaParam(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ P_PARAM_CUSTOM_NOA_PARAM_STRUCT_T prNoaParam; -+ CMD_CUSTOM_NOA_PARAM_STRUCT_T rCmdNoaParam; -+ -+ DEBUGFUNC("wlanoidSetNoaParam"); -+ DBGLOG(P2P, TRACE, "\n"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ *pu4SetInfoLen = sizeof(PARAM_CUSTOM_NOA_PARAM_STRUCT_T); -+ -+ if (u4SetBufferLen < sizeof(PARAM_CUSTOM_NOA_PARAM_STRUCT_T)) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ ASSERT(pvSetBuffer); -+ -+ prNoaParam = (P_PARAM_CUSTOM_NOA_PARAM_STRUCT_T) pvSetBuffer; -+ -+ kalMemZero(&rCmdNoaParam, sizeof(CMD_CUSTOM_NOA_PARAM_STRUCT_T)); -+ rCmdNoaParam.u4NoaDurationMs = prNoaParam->u4NoaDurationMs; -+ rCmdNoaParam.u4NoaIntervalMs = prNoaParam->u4NoaIntervalMs; -+ rCmdNoaParam.u4NoaCount = prNoaParam->u4NoaCount; -+ -+#if 0 -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SET_NOA_PARAM, -+ TRUE, -+ FALSE, -+ TRUE, -+ nicCmdEventSetCommon, -+ nicOidCmdTimeoutCommon, -+ sizeof(CMD_CUSTOM_NOA_PARAM_STRUCT_T), -+ (PUINT_8) &rCmdNoaParam, pvSetBuffer, u4SetBufferLen); -+#else -+ return wlanoidSendSetQueryP2PCmd(prAdapter, -+ CMD_ID_SET_NOA_PARAM, -+ TRUE, -+ FALSE, -+ TRUE, -+ NULL, -+ nicOidCmdTimeoutCommon, -+ sizeof(CMD_CUSTOM_NOA_PARAM_STRUCT_T), -+ (PUINT_8) &rCmdNoaParam, pvSetBuffer, u4SetBufferLen); -+ -+#endif -+ -+} -+ -+WLAN_STATUS -+wlanoidSetOppPsParam(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ P_PARAM_CUSTOM_OPPPS_PARAM_STRUCT_T prOppPsParam; -+ CMD_CUSTOM_OPPPS_PARAM_STRUCT_T rCmdOppPsParam; -+ -+ DEBUGFUNC("wlanoidSetOppPsParam"); -+ DBGLOG(P2P, TRACE, "\n"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ *pu4SetInfoLen = sizeof(PARAM_CUSTOM_OPPPS_PARAM_STRUCT_T); -+ -+ if (u4SetBufferLen < sizeof(PARAM_CUSTOM_OPPPS_PARAM_STRUCT_T)) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ ASSERT(pvSetBuffer); -+ -+ prOppPsParam = (P_PARAM_CUSTOM_OPPPS_PARAM_STRUCT_T) pvSetBuffer; -+ -+ kalMemZero(&rCmdOppPsParam, sizeof(CMD_CUSTOM_OPPPS_PARAM_STRUCT_T)); -+ rCmdOppPsParam.u4CTwindowMs = prOppPsParam->u4CTwindowMs; -+ -+#if 0 -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SET_OPPPS_PARAM, -+ TRUE, -+ FALSE, -+ TRUE, -+ nicCmdEventSetCommon, -+ nicOidCmdTimeoutCommon, -+ sizeof(CMD_CUSTOM_OPPPS_PARAM_STRUCT_T), -+ (PUINT_8) &rCmdOppPsParam, pvSetBuffer, u4SetBufferLen); -+#else -+ return wlanoidSendSetQueryP2PCmd(prAdapter, -+ CMD_ID_SET_NOA_PARAM, -+ TRUE, -+ FALSE, -+ TRUE, -+ NULL, -+ nicOidCmdTimeoutCommon, -+ sizeof(CMD_CUSTOM_OPPPS_PARAM_STRUCT_T), -+ (PUINT_8) &rCmdOppPsParam, pvSetBuffer, u4SetBufferLen); -+ -+#endif -+ -+} -+ -+WLAN_STATUS -+wlanoidSetUApsdParam(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ P_PARAM_CUSTOM_UAPSD_PARAM_STRUCT_T prUapsdParam; -+ CMD_CUSTOM_UAPSD_PARAM_STRUCT_T rCmdUapsdParam; -+ P_PM_PROFILE_SETUP_INFO_T prPmProfSetupInfo; -+ P_BSS_INFO_T prBssInfo; -+ -+ DEBUGFUNC("wlanoidSetUApsdParam"); -+ DBGLOG(P2P, TRACE, "\n"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ *pu4SetInfoLen = sizeof(PARAM_CUSTOM_UAPSD_PARAM_STRUCT_T); -+ -+ if (u4SetBufferLen < sizeof(PARAM_CUSTOM_UAPSD_PARAM_STRUCT_T)) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ ASSERT(pvSetBuffer); -+ -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); -+ prPmProfSetupInfo = &prBssInfo->rPmProfSetupInfo; -+ -+ prUapsdParam = (P_PARAM_CUSTOM_UAPSD_PARAM_STRUCT_T) pvSetBuffer; -+ -+ kalMemZero(&rCmdUapsdParam, sizeof(CMD_CUSTOM_OPPPS_PARAM_STRUCT_T)); -+ rCmdUapsdParam.fgEnAPSD = prUapsdParam->fgEnAPSD; -+ prAdapter->rWifiVar.fgSupportUAPSD = prUapsdParam->fgEnAPSD; -+ -+ rCmdUapsdParam.fgEnAPSD_AcBe = prUapsdParam->fgEnAPSD_AcBe; -+ rCmdUapsdParam.fgEnAPSD_AcBk = prUapsdParam->fgEnAPSD_AcBk; -+ rCmdUapsdParam.fgEnAPSD_AcVo = prUapsdParam->fgEnAPSD_AcVo; -+ rCmdUapsdParam.fgEnAPSD_AcVi = prUapsdParam->fgEnAPSD_AcVi; -+ prPmProfSetupInfo->ucBmpDeliveryAC = -+ ((prUapsdParam->fgEnAPSD_AcBe << 0) | -+ (prUapsdParam->fgEnAPSD_AcBk << 1) | -+ (prUapsdParam->fgEnAPSD_AcVi << 2) | (prUapsdParam->fgEnAPSD_AcVo << 3)); -+ prPmProfSetupInfo->ucBmpTriggerAC = -+ ((prUapsdParam->fgEnAPSD_AcBe << 0) | -+ (prUapsdParam->fgEnAPSD_AcBk << 1) | -+ (prUapsdParam->fgEnAPSD_AcVi << 2) | (prUapsdParam->fgEnAPSD_AcVo << 3)); -+ -+ rCmdUapsdParam.ucMaxSpLen = prUapsdParam->ucMaxSpLen; -+ prPmProfSetupInfo->ucUapsdSp = prUapsdParam->ucMaxSpLen; -+ -+#if 0 -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SET_UAPSD_PARAM, -+ TRUE, -+ FALSE, -+ TRUE, -+ nicCmdEventSetCommon, -+ nicOidCmdTimeoutCommon, -+ sizeof(CMD_CUSTOM_OPPPS_PARAM_STRUCT_T), -+ (PUINT_8) &rCmdUapsdParam, pvSetBuffer, u4SetBufferLen); -+#else -+ return wlanoidSendSetQueryP2PCmd(prAdapter, -+ CMD_ID_SET_UAPSD_PARAM, -+ TRUE, -+ FALSE, -+ TRUE, -+ NULL, -+ nicOidCmdTimeoutCommon, -+ sizeof(CMD_CUSTOM_OPPPS_PARAM_STRUCT_T), -+ (PUINT_8) &rCmdUapsdParam, pvSetBuffer, u4SetBufferLen); -+ -+#endif -+} -+ -+WLAN_STATUS -+wlanoidQueryP2pOpChannel(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ -+ WLAN_STATUS rResult = WLAN_STATUS_FAILURE; -+/* PUINT_8 pucOpChnl = (PUINT_8)pvQueryBuffer; */ -+ -+ do { -+ if ((prAdapter == NULL) || (pu4QueryInfoLen == NULL)) -+ break; -+ -+ if ((u4QueryBufferLen) && (pvQueryBuffer == NULL)) -+ break; -+ -+ if (u4QueryBufferLen < sizeof(UINT_8)) { -+ *pu4QueryInfoLen = sizeof(UINT_8); -+ rResult = WLAN_STATUS_BUFFER_TOO_SHORT; -+ break; -+ } -+#if 0 -+ if (!p2pFuncGetCurrentOpChnl(prAdapter, pucOpChnl)) { -+ rResult = WLAN_STATUS_INVALID_DATA; -+ break; -+ } -+#else -+ rResult = WLAN_STATUS_INVALID_DATA; -+ break; -+#endif -+ /* -+ *pu4QueryInfoLen = sizeof(UINT_8); -+ rResult = WLAN_STATUS_SUCCESS; -+ */ -+ -+ } while (FALSE); -+ -+ return rResult; -+} /* wlanoidQueryP2pOpChannel */ -+ -+WLAN_STATUS -+wlanoidQueryP2pVersion(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ WLAN_STATUS rResult = WLAN_STATUS_FAILURE; -+/* PUINT_8 pucVersionNum = (PUINT_8)pvQueryBuffer; */ -+ -+ do { -+ if ((prAdapter == NULL) || (pu4QueryInfoLen == NULL)) -+ break; -+ -+ if ((u4QueryBufferLen) && (pvQueryBuffer == NULL)) -+ break; -+ -+ if (u4QueryBufferLen < sizeof(UINT_8)) { -+ *pu4QueryInfoLen = sizeof(UINT_8); -+ rResult = WLAN_STATUS_BUFFER_TOO_SHORT; -+ break; -+ } -+ -+ } while (FALSE); -+ -+ return rResult; -+} /* wlanoidQueryP2pVersion */ -+ -+WLAN_STATUS -+wlanoidSetP2pSupplicantVersion(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ WLAN_STATUS rResult = WLAN_STATUS_FAILURE; -+ UINT_8 ucVersionNum; -+ -+ do { -+ if ((prAdapter == NULL) || (pu4SetInfoLen == NULL)) { -+ -+ rResult = WLAN_STATUS_INVALID_DATA; -+ break; -+ } -+ -+ if ((u4SetBufferLen) && (pvSetBuffer == NULL)) { -+ rResult = WLAN_STATUS_INVALID_DATA; -+ break; -+ } -+ -+ *pu4SetInfoLen = sizeof(UINT_8); -+ -+ if (u4SetBufferLen < sizeof(UINT_8)) { -+ rResult = WLAN_STATUS_INVALID_LENGTH; -+ break; -+ } -+ -+ ucVersionNum = *((PUINT_8) pvSetBuffer); -+ -+ rResult = WLAN_STATUS_SUCCESS; -+ } while (FALSE); -+ -+ return rResult; -+} /* wlanoidSetP2pSupplicantVersion */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is used to set the WPS mode. -+* -+* \param[in] pvAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetP2pWPSmode(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ WLAN_STATUS status; -+ UINT_32 u4IsWPSmode = 0; -+ -+ DEBUGFUNC("wlanoidSetP2pWPSmode"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4SetInfoLen); -+ -+ if (pvSetBuffer) -+ u4IsWPSmode = *(PUINT_32) pvSetBuffer; -+ else -+ u4IsWPSmode = 0; -+ -+ if (u4IsWPSmode) -+ prAdapter->rWifiVar.prP2pFsmInfo->fgIsWPSMode = 1; -+ else -+ prAdapter->rWifiVar.prP2pFsmInfo->fgIsWPSMode = 0; -+ -+ status = nicUpdateBss(prAdapter, NETWORK_TYPE_P2P_INDEX); -+ -+ return status; -+} /* end of wlanoidSetP2pWPSmode() */ -+ -+#if CFG_SUPPORT_P2P_RSSI_QUERY -+WLAN_STATUS -+wlanoidQueryP2pRssi(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ DEBUGFUNC("wlanoidQueryP2pRssi"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4QueryInfoLen); -+ if (u4QueryBufferLen) -+ ASSERT(pvQueryBuffer); -+ -+ *pu4QueryInfoLen = sizeof(PARAM_RSSI); -+ -+ /* Check for query buffer length */ -+ if (u4QueryBufferLen < *pu4QueryInfoLen) { -+ DBGLOG(REQ, WARN, "Too short length %u\n", u4QueryBufferLen); -+ return WLAN_STATUS_BUFFER_TOO_SHORT; -+ } -+ -+ if (prAdapter->fgIsP2pLinkQualityValid == TRUE && -+ (kalGetTimeTick() - prAdapter->rP2pLinkQualityUpdateTime) <= CFG_LINK_QUALITY_VALID_PERIOD) { -+ PARAM_RSSI rRssi; -+ -+ rRssi = (PARAM_RSSI) prAdapter->rP2pLinkQuality.cRssi; /* ranged from (-128 ~ 30) in unit of dBm */ -+ -+ if (rRssi > PARAM_WHQL_RSSI_MAX_DBM) -+ rRssi = PARAM_WHQL_RSSI_MAX_DBM; -+ else if (rRssi < PARAM_WHQL_RSSI_MIN_DBM) -+ rRssi = PARAM_WHQL_RSSI_MIN_DBM; -+ -+ kalMemCopy(pvQueryBuffer, &rRssi, sizeof(PARAM_RSSI)); -+ return WLAN_STATUS_SUCCESS; -+ } -+#ifdef LINUX -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_GET_LINK_QUALITY, -+ FALSE, -+ TRUE, -+ TRUE, -+ nicCmdEventQueryLinkQuality, -+ nicOidCmdTimeoutCommon, -+ *pu4QueryInfoLen, pvQueryBuffer, pvQueryBuffer, u4QueryBufferLen); -+#else -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_GET_LINK_QUALITY, -+ FALSE, -+ TRUE, -+ TRUE, -+ nicCmdEventQueryLinkQuality, -+ nicOidCmdTimeoutCommon, 0, NULL, pvQueryBuffer, u4QueryBufferLen); -+ -+#endif -+} /* wlanoidQueryP2pRssi */ -+#endif -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/CFG_Wifi_File.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/CFG_Wifi_File.h -new file mode 100644 -index 000000000000..89de18c89c1c ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/CFG_Wifi_File.h -@@ -0,0 +1,238 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/CFG_Wifi_File.h#1 -+*/ -+ -+/*! \file CFG_Wifi_File.h -+ \brief Collection of NVRAM structure used for YuSu project -+ -+ In this file we collect all compiler flags and detail the driver behavior if -+ enable/disable such switch or adjust numeric parameters. -+*/ -+ -+/* -+** Log: CFG_Wifi_File.h -+ * -+ * 09 08 2011 cm.chang -+ * [WCXRP00000969] [MT6620 Wi-Fi][Driver][FW] Channel list for 5G band based on country code -+ * Use new fields ucChannelListMap and ucChannelListIndex in NVRAM -+ * -+ * 08 31 2011 cm.chang -+ * [WCXRP00000969] [MT6620 Wi-Fi][Driver][FW] Channel list for 5G band based on country code -+ * . -+ * -+ * 08 15 2011 cp.wu -+ * [WCXRP00000851] [MT6628 Wi-Fi][Driver] Add HIFSYS related definition to driver source tree -+ * add MT6628-specific definitions. -+ * -+ * 08 09 2011 cp.wu -+ * [WCXRP00000702] [MT5931][Driver] Modify initialization sequence for E1 ASIC -+ * [WCXRP00000913] [MT6620 Wi-Fi] create repository of source code dedicated for MT6620 E6 ASIC -+ * add CCK-DSSS TX-PWR control field in NVRAM and CMD definition for MT5931-MP -+ * -+ * 05 27 2011 cp.wu -+ * [WCXRP00000749] [MT6620 Wi-Fi][Driver] Add band edge tx power control to Wi-Fi NVRAM -+ * update NVRAM data structure definition. -+ * -+ * 03 10 2011 cp.wu -+ * [WCXRP00000532] [MT6620 Wi-Fi][Driver] Migrate NVRAM configuration procedures from MT6620 E2 to MT6620 E3 -+ * deprecate configuration used by MT6620 E2 -+ * -+ * 10 26 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check -+ * [WCXRP00000137] [MT6620 Wi-Fi] [FW] Support NIC capability query command -+ * 1) update NVRAM content template to ver 1.02 -+ * 2) add compile option for querying NIC capability (default: off) -+ * 3) modify AIS 5GHz support to run-time option, which could be turned on by registry or NVRAM setting -+ * 4) correct auto-rate compiler error under linux (treat warning as error) -+ * 5) simplify usage of NVRAM and REG_INFO_T -+ * 6) add version checking between driver and firmware -+ * -+ * 10 25 2010 cp.wu -+ * [WCXRP00000133] [MT6620 Wi-Fi] [FW][Driver] Change TX power offset band definition -+ * follow-up for CMD_5G_PWR_OFFSET_T definition change -+ * -+ * 10 05 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check -+ * 1) add NVRAM access API -+ * 2) fake scanning result when NVRAM doesn't exist and/or version mismatch. (off by compiler option) -+ * 3) add OID implementation for NVRAM read/write service -+ * -+ * 09 23 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check -+ * add skeleton for NVRAM integration -+ * -+*/ -+ -+#ifndef _CFG_WIFI_FILE_H -+#define _CFG_WIFI_FILE_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "gl_typedef.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+/* duplicated from nic_cmd_event.h to avoid header dependency */ -+typedef struct _TX_PWR_PARAM_T { -+ INT_8 cTxPwr2G4Cck; /* signed, in unit of 0.5dBm */ -+ INT_8 acReserved[3]; /* form MT6628 acReserved[0]=cTxPwr2G4Dsss */ -+ INT_8 cTxPwr2G4OFDM_BPSK; -+ INT_8 cTxPwr2G4OFDM_QPSK; -+ INT_8 cTxPwr2G4OFDM_16QAM; -+ INT_8 cTxPwr2G4OFDM_Reserved; -+ INT_8 cTxPwr2G4OFDM_48Mbps; -+ INT_8 cTxPwr2G4OFDM_54Mbps; -+ -+ INT_8 cTxPwr2G4HT20_BPSK; -+ INT_8 cTxPwr2G4HT20_QPSK; -+ INT_8 cTxPwr2G4HT20_16QAM; -+ INT_8 cTxPwr2G4HT20_MCS5; -+ INT_8 cTxPwr2G4HT20_MCS6; -+ INT_8 cTxPwr2G4HT20_MCS7; -+ -+ INT_8 cTxPwr2G4HT40_BPSK; -+ INT_8 cTxPwr2G4HT40_QPSK; -+ INT_8 cTxPwr2G4HT40_16QAM; -+ INT_8 cTxPwr2G4HT40_MCS5; -+ INT_8 cTxPwr2G4HT40_MCS6; -+ INT_8 cTxPwr2G4HT40_MCS7; -+ -+ INT_8 cTxPwr5GOFDM_BPSK; -+ INT_8 cTxPwr5GOFDM_QPSK; -+ INT_8 cTxPwr5GOFDM_16QAM; -+ INT_8 cTxPwr5GOFDM_Reserved; -+ INT_8 cTxPwr5GOFDM_48Mbps; -+ INT_8 cTxPwr5GOFDM_54Mbps; -+ -+ INT_8 cTxPwr5GHT20_BPSK; -+ INT_8 cTxPwr5GHT20_QPSK; -+ INT_8 cTxPwr5GHT20_16QAM; -+ INT_8 cTxPwr5GHT20_MCS5; -+ INT_8 cTxPwr5GHT20_MCS6; -+ INT_8 cTxPwr5GHT20_MCS7; -+ -+ INT_8 cTxPwr5GHT40_BPSK; -+ INT_8 cTxPwr5GHT40_QPSK; -+ INT_8 cTxPwr5GHT40_16QAM; -+ INT_8 cTxPwr5GHT40_MCS5; -+ INT_8 cTxPwr5GHT40_MCS6; -+ INT_8 cTxPwr5GHT40_MCS7; -+} TX_PWR_PARAM_T, *P_TX_PWR_PARAM_T; -+ -+typedef struct _PWR_5G_OFFSET_T { -+ INT_8 cOffsetBand0; /* 4.915-4.980G */ -+ INT_8 cOffsetBand1; /* 5.000-5.080G */ -+ INT_8 cOffsetBand2; /* 5.160-5.180G */ -+ INT_8 cOffsetBand3; /* 5.200-5.280G */ -+ INT_8 cOffsetBand4; /* 5.300-5.340G */ -+ INT_8 cOffsetBand5; /* 5.500-5.580G */ -+ INT_8 cOffsetBand6; /* 5.600-5.680G */ -+ INT_8 cOffsetBand7; /* 5.700-5.825G */ -+} PWR_5G_OFFSET_T, *P_PWR_5G_OFFSET_T; -+ -+typedef struct _PWR_PARAM_T { -+ UINT_32 au4Data[28]; -+ UINT_32 u4RefValue1; -+ UINT_32 u4RefValue2; -+} PWR_PARAM_T, *P_PWR_PARAM_T; -+ -+typedef struct _MT6620_CFG_PARAM_STRUCT { -+ /* 256 bytes of MP data */ -+ UINT_16 u2Part1OwnVersion; -+ UINT_16 u2Part1PeerVersion; -+ UINT_8 aucMacAddress[6]; -+ UINT_8 aucCountryCode[2]; -+ TX_PWR_PARAM_T rTxPwr; -+ UINT_8 aucEFUSE[144]; -+ UINT_8 ucTxPwrValid; -+ UINT_8 ucSupport5GBand; -+ UINT_8 fg2G4BandEdgePwrUsed; -+ INT_8 cBandEdgeMaxPwrCCK; -+ INT_8 cBandEdgeMaxPwrOFDM20; -+ INT_8 cBandEdgeMaxPwrOFDM40; -+ -+ UINT_8 ucRegChannelListMap; -+ UINT_8 ucRegChannelListIndex; -+ UINT_8 aucRegSubbandInfo[36]; -+ -+ UINT_8 aucReserved2[256 - 240]; -+ -+ /* 256 bytes of function data */ -+ UINT_16 u2Part2OwnVersion; -+ UINT_16 u2Part2PeerVersion; -+ UINT_8 uc2G4BwFixed20M; -+ UINT_8 uc5GBwFixed20M; -+ UINT_8 ucEnable5GBand; -+ UINT_8 aucPreTailReserved; -+ UINT_8 uc2GRssiCompensation; -+ UINT_8 uc5GRssiCompensation; -+ UINT_8 fgRssiCompensationValidbit; -+ UINT_8 ucRxAntennanumber; -+ UINT_8 aucTailReserved[256 - 12]; -+} MT6620_CFG_PARAM_STRUCT, *P_MT6620_CFG_PARAM_STRUCT, WIFI_CFG_PARAM_STRUCT, *P_WIFI_CFG_PARAM_STRUCT; -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+#ifndef DATA_STRUCT_INSPECTING_ASSERT -+#define DATA_STRUCT_INSPECTING_ASSERT(expr) \ -+{ \ -+ switch (0) {case 0: case (expr): default:; } \ -+} -+#endif -+ -+#define CFG_FILE_WIFI_REC_SIZE sizeof(WIFI_CFG_PARAM_STRUCT) -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+#ifndef _lint -+/* We don't have to call following function to inspect the data structure. -+ * It will check automatically while at compile time. -+ * We'll need this to guarantee the same member order in different structures -+ * to simply handling effort in some functions. -+ */ -+static inline VOID nvramOffsetCheck(VOID) -+{ -+ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(WIFI_CFG_PARAM_STRUCT, u2Part2OwnVersion) == 256); -+ -+ DATA_STRUCT_INSPECTING_ASSERT(sizeof(WIFI_CFG_PARAM_STRUCT) == 512); -+ -+ DATA_STRUCT_INSPECTING_ASSERT((OFFSET_OF(WIFI_CFG_PARAM_STRUCT, aucEFUSE) & 0x0001) == 0); -+ -+ DATA_STRUCT_INSPECTING_ASSERT((OFFSET_OF(WIFI_CFG_PARAM_STRUCT, aucRegSubbandInfo) & 0x0001) == 0); -+} -+#endif -+ -+#endif /* _CFG_WIFI_FILE_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/config.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/config.h -new file mode 100644 -index 000000000000..a52053d5752d ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/config.h -@@ -0,0 +1,1628 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/config.h#2 -+*/ -+ -+/*! \file "config.h" -+ \brief This file includes the various configurable parameters for customers -+ -+ This file ncludes the configurable parameters except the parameters indicate the turning-on/off of some features -+*/ -+ -+/* -+** Log: config.h -+ * -+ * 07 13 2012 cp.wu -+ * [WCXRP00001259] [MT6620 Wi-Fi][Driver][Firmware] Send a signal to firmware for -+ * termination after SDIO error has happened -+ * [driver domain] add force reset by host-to-device interrupt mechanism -+ * -+ * 06 13 2012 yuche.tsai -+ * NULL -+ * Update maintrunk driver. -+ * Add support for driver compose assoc request frame. -+ * -+ * 06 05 2012 tsaiyuan.hsu -+ * [WCXRP00001249] [ALPS.ICS] Daily build warning on "wlan/mgmt/swcr.c#1" -+ * resolve build waring for "WNM_UNIT_TEST not defined".. -+ * -+ * 06 04 2012 cp.wu -+ * [WCXRP00001245] [MT6620 Wi-Fi][Driver][Firmware] NPS Software Development -+ * discussed with WH, privacy bit in associate response is not necessary to be checked, -+ * and identified as association failure when mismatching with beacon/probe response -+ * -+ * 05 11 2012 cp.wu -+ * [WCXRP00001237] [MT6620 Wi-Fi][Driver] Show MAC address and MAC address source for ACS's convenience -+ * show MAC address & source while initiliazation -+ * -+ * 04 20 2012 cp.wu -+ * [WCXRP00000913] [MT6620 Wi-Fi] create repository of source code dedicated for MT6620 E6 ASIC -+ * correct macro -+ * -+ * 04 12 2012 terry.wu -+ * NULL -+ * Add AEE message support -+ * 1) Show AEE warning(red screen) if SDIO access error occurs -+ * -+ * 03 29 2012 eason.tsai -+ * [WCXRP00001216] [MT6628 Wi-Fi][Driver]add conditional define -+ * add conditional define. -+ * -+ * 03 02 2012 terry.wu -+ * NULL -+ * Enable CFG80211 Support. -+ * -+ * 01 05 2012 tsaiyuan.hsu -+ * [WCXRP00001157] [MT6620 Wi-Fi][FW][DRV] add timing measurement support for 802.11v -+ * add timing measurement support for 802.11v. -+ * -+ * 11 23 2011 cp.wu -+ * [WCXRP00001123] [MT6620 Wi-Fi][Driver] Add option to disable beacon content change detection -+ * add compile option to disable beacon content change detection. -+ * -+ * 11 18 2011 yuche.tsai -+ * NULL -+ * CONFIG P2P support RSSI query, default turned off. -+ * -+ * 10 28 2011 cp.wu -+ * [MT6620 Wi-Fi][Win32 Driver] Enable 5GHz support as default -+ * enable 5GHz as default for DaVinci trunk and V2.1 driver release . -+ * -+ * 10 18 2011 cp.wu -+ * [WCXRP00001022] [MT6628 Driver][Firmware Download] Add multi section independent download functionality -+ * surpress compiler warning for MT6628 build -+ * -+ * 10 12 2011 wh.su -+ * [WCXRP00001036] [MT6620 Wi-Fi][Driver][FW] Adding the 802.11w code for MFP -+ * adding the 802.11w related function and define . -+ * -+ * 10 03 2011 cp.wu -+ * [WCXRP00001022] [MT6628 Driver][Firmware Download] Add multi section independent download functionality -+ * enable divided firmware downloading. -+ * -+ * 10 03 2011 cp.wu -+ * [WCXRP00001022] [MT6628 Driver][Firmware Download] Add multi section independent download functionality -+ * add firmware download path in divided scatters. -+ * -+ * 10 03 2011 cp.wu -+ * [MT6628 Driver][Firmware Download] Add multi section independent download functionality -+ * add firmware downloading aggregated path. -+ * -+ * 09 28 2011 tsaiyuan.hsu -+ * [WCXRP00000900] [MT5931 Wi-Fi] Improve balance of TX and RX -+ * enlarge window size only by 4. -+ * -+ * 08 15 2011 cp.wu -+ * [WCXRP00000851] [MT6628 Wi-Fi][Driver] Add HIFSYS related definition to driver source tree -+ * reuse firmware download logic of MT6620 for MT6628. -+ * -+ * 08 15 2011 cp.wu -+ * [WCXRP00000851] [MT6628 Wi-Fi][Driver] Add HIFSYS related definition to driver source tree -+ * add MT6628-specific definitions. -+ * -+ * 08 15 2011 cp.wu -+ * [WCXRP00000913] [MT6620 Wi-Fi] create repository of source code dedicated for MT6620 E6 ASIC -+ * support to load different firmware image for E3/E4/E5 and E6 ASIC on win32 platforms. -+ * -+ * 08 12 2011 cp.wu -+ * [WCXRP00000913] [MT6620 Wi-Fi] create repository of source code dedicated for MT6620 E6 ASIC -+ * load WIFI_RAM_CODE_E6 for MT6620 E6 ASIC. -+ * -+ * 08 09 2011 chinghwa.yu -+ * [WCXRP00000063] Update BCM CoEx design and settings -+ * Add BWCS definition for MT6620. -+ * -+ * 07 28 2011 chinghwa.yu -+ * [WCXRP00000063] Update BCM CoEx design and settings -+ * Add BWCS cmd and event. -+ * -+ * 07 22 2011 jeffrey.chang -+ * [WCXRP00000864] [MT5931] Add command to adjust OSC stable time -+ * modify driver to set OSC stable time after f/w download -+ * -+ * 07 18 2011 chinghwa.yu -+ * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm -+ * Add CMD/Event for RDD and BWCS. -+ * -+ * 07 05 2011 yuche.tsai -+ * [WCXRP00000821] [Volunteer Patch][WiFi Direct][Driver] WiFi Direct Connection Speed Issue -+ * Refine compile flag. -+ * -+ * 07 05 2011 yuche.tsai -+ * [WCXRP00000821] [Volunteer Patch][WiFi Direct][Driver] WiFi Direct Connection Speed Issue -+ * Add wifi direct connection enhancement method I, II & VI. -+ * -+ * 06 24 2011 cp.wu -+ * [WCXRP00000702] [MT5931][Driver] Modify initialization sequence for E1 ASIC -+ * [WCXRP00000812] [MT6620 Wi-Fi][Driver] not show NVRAM when there is no valid MAC address in NVRAM content -+ * increase RX buffer number to have a 2:1 ping-pong ratio -+ * -+ * 06 23 2011 eddie.chen -+ * [WCXRP00000810] [MT5931][DRV/FW] Adjust TxRx Buffer number and Rx buffer size -+ * 1. Different TX RX buffer -+ * 2. Enlarge RX buffer and increase the number 8->11 -+ * 3. Separate the WINSZIE and RX buffer number -+ * 4. Fix RX maximum size in MAC -+ * -+ * 06 20 2011 terry.wu -+ * NULL -+ * Add BoW Rate Limitation. -+ * -+ * 06 17 2011 terry.wu -+ * NULL -+ * . -+ * -+ * 06 17 2011 terry.wu -+ * NULL -+ * Add BoW 11N support. -+ * -+ * 06 07 2011 yuche.tsai -+ * [WCXRP00000763] [Volunteer Patch][MT6620][Driver] RX Service Discovery Frame under AP mode Issue -+ * Add compile flag for persistent group support. -+ * -+ * 06 01 2011 cm.chang -+ * [WCXRP00000756] [MT6620 Wi-Fi][Driver] 1. AIS follow channel of BOW 2. Provide legal channel function -+ * Limit AIS to fixed channel same with BOW -+ * -+ * 04 18 2011 terry.wu -+ * [WCXRP00000660] [MT6620 Wi-Fi][Driver] Remove flag CFG_WIFI_DIRECT_MOVED -+ * Remove flag CFG_WIFI_DIRECT_MOVED. -+ * -+ * 04 14 2011 cm.chang -+ * [WCXRP00000634] [MT6620 Wi-Fi][Driver][FW] 2nd BSS will not support 40MHz bandwidth for concurrency -+ * Enable RX STBC capability -+ * -+ * 04 11 2011 george.huang -+ * [WCXRP00000628] [MT6620 Wi-Fi][FW][Driver] Modify U-APSD setting to default OFF -+ * . -+ * -+ * 04 08 2011 pat.lu -+ * [WCXRP00000623] [MT6620 Wi-Fi][Driver] use ARCH define to distinguish PC Linux driver -+ * Use CONFIG_X86 instead of PC_LINUX_DRIVER_USE option to have proper compile setting for PC Linux driver -+ * -+ * 04 08 2011 cp.wu -+ * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer -+ * 1. correction: RX aggregation is not limited to SDIO but for all host interface options -+ * 2. add forward declarations for DBG-only symbols -+ * -+ * 04 06 2011 cp.wu -+ * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer -+ * 1. do not check for pvData inside wlanNetCreate() due to it is NULL for eHPI port -+ * 2. update perm_addr as well for MAC address -+ * 3. not calling check_mem_region() anymore for eHPI -+ * 4. correct MSC_CS macro for 0-based notation -+ * -+ * 04 01 2011 cp.wu -+ * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer -+ * 1. simplify config.h due to aggregation options could be also applied for eHPI/SPI interface -+ * 2. use spin-lock instead of semaphore for protecting eHPI access because of possible access from ISR -+ * 3. request_irq() API has some changes between linux kernel 2.6.12 and 2.6.26 -+ * -+ * 03 29 2011 cp.wu -+ * [WCXRP00000598] [MT6620 Wi-Fi][Driver] Implementation of interface for communicating with -+ * user space process for RESET_START and RESET_END events -+ * implement kernel-to-userspace communication via generic netlink socket for whole-chip resetting mechanism -+ * -+ * 03 22 2011 pat.lu -+ * [WCXRP00000592] [MT6620 Wi-Fi][Driver] Support PC Linux Environment Driver Build -+ * Add a compiler option "PC_LINUX_DRIVER_USE" for building driver in PC Linux environment. -+ * -+ * 03 18 2011 wh.su -+ * [WCXRP00000530] [MT6620 Wi-Fi] [Driver] skip doing p2pRunEventAAAComplete after send assoc response Tx Done -+ * enable the Anti_piracy check at driver . -+ * -+ * 03 17 2011 tsaiyuan.hsu -+ * [WCXRP00000517] [MT6620 Wi-Fi][Driver][FW] Fine Tune Performance of Roaming -+ * enable roaming feature. -+ * -+ * 03 17 2011 chinglan.wang -+ * [WCXRP00000570] [MT6620 Wi-Fi][Driver] Add Wi-Fi Protected Setup v2.0 feature -+ * . -+ * -+ * 03 15 2011 cp.wu -+ * [WCXRP00000559] [MT6620 Wi-Fi][Driver] Combine TX/RX DMA buffers into a single one -+ * to reduce physically continuous memory consumption -+ * 1. deprecate CFG_HANDLE_IST_IN_SDIO_CALLBACK -+ * 2. Use common coalescing buffer for both TX/RX directions -+ * -+ * -+ * 03 15 2011 eddie.chen -+ * [WCXRP00000554] [MT6620 Wi-Fi][DRV] Add sw control debug counter -+ * Add sw debug counter for QM. -+ * -+ * 03 07 2011 wh.su -+ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code -+ * rename the define to anti_pviracy. -+ * -+ * 03 06 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Sync BOW Driver to latest person development branch version.. -+ * -+ * 03 02 2011 wh.su -+ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code -+ * Add security check code. -+ * -+ * 03 01 2011 george.huang -+ * [WCXRP00000495] [MT6620 Wi-Fi][FW] Support pattern filter for unwanted ARP frames -+ * Fix compile issue -+ * -+ * 02 25 2011 george.huang -+ * [WCXRP00000497] [MT6620 Wi-Fi][FW] Change default UAPSD AC assignment -+ * Assign all AC default to be U-APSD enabled. -+ * -+ * 02 14 2011 wh.su -+ * [WCXRP00000432] [MT6620 Wi-Fi][Driver] Add STA privacy check at hotspot mode -+ * Let the privacy check at hotspot mode default enable. -+ * -+ * 02 09 2011 wh.su -+ * [WCXRP00000432] [MT6620 Wi-Fi][Driver] Add STA privacy check at hotspot mode -+ * adding the code for check STA privacy bit at AP mode, . -+ * -+ * 02 08 2011 cp.wu -+ * [WCXRP00000427] [MT6620 Wi-Fi][Driver] Modify veresion information to match with release revision number -+ * change version number to v1.2.0.0 for preparing v1.2 software package release. -+ * -+ * 02 01 2011 yarco.yang -+ * [WCXRP00000417] [MT6620 Driver] Change CFG_HANDLE_IST_IN_SDIO_CALLBACK from 1 to 0 for Interoperability -+ * . -+ * -+ * 01 27 2011 tsaiyuan.hsu -+ * [WCXRP00000392] [MT6620 Wi-Fi][Driver] Add Roaming Support -+ * add roaming fsm -+ * 1. not support 11r, only use strength of signal to determine roaming. -+ * 2. not enable CFG_SUPPORT_ROAMING until completion of full test. -+ * 3. in 6620, adopt work-around to avoid sign extension problem of cck of hw -+ * 4. assume that change of link quality in smooth way. -+ * -+ * 01 19 2011 wh.su -+ * [WCXRP00000370] [MT6620 Wi-Fi][Driver] Disable Rx RDG for workaround pre-N ccmp issue -+ * Not announce support Rx RDG for wokaround pre-N ccmp construct AAD issue.. -+ * -+ * 01 15 2011 puff.wen -+ * NULL -+ * Add Stress test -+ * -+ * 01 12 2011 cp.wu -+ * [WCXRP00000356] [MT6620 Wi-Fi][Driver] fill mac header length for security frames 'cause -+ * hardware header translation needs such information -+ * fill mac header length information for 802.1x frames. -+ * -+ * 01 11 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Support BOW only for Linux. -+ * -+ * 01 10 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Enable BOW and 4 physical links. -+ * -+ * 01 08 2011 yuche.tsai -+ * [WCXRP00000345] [MT6620][Volunteer Patch] P2P may issue a SSID specified scan request, -+ * but the SSID length is still invalid. -+ * Modify CFG_SLT_SUPPORT default value. -+ * -+ * 01 08 2011 yuche.tsai -+ * [WCXRP00000341] [MT6620][SLT] Create Branch for SLT SW. -+ * Update configure flag. -+ * -+ * 12 28 2010 cp.wu -+ * [WCXRP00000269] [MT6620 Wi-Fi][Driver][Firmware] Prepare for v1.1 branch release -+ * report EEPROM used flag via NIC_CAPABILITY -+ * -+ * 12 28 2010 cp.wu -+ * [WCXRP00000269] [MT6620 Wi-Fi][Driver][Firmware] Prepare for v1.1 branch release -+ * integrate with 'EEPROM used' flag for reporting correct capability to Engineer Mode/META and other tools -+ * -+ * 12 15 2010 yuche.tsai -+ * NULL -+ * Update SLT Descriptor number configure in driver. -+ * -+ * 12 13 2010 chinglan.wang -+ * NULL -+ * Add WPS 1.0 feature flag to enable the WPS 1.0 function. -+ * -+ * 11 23 2010 george.huang -+ * [WCXRP00000127] [MT6620 Wi-Fi][Driver] Add a registry to disable Beacon Timeout function for SQA test by using E1 EVB -+ * Enable PM function by default -+ * -+ * 11 15 2010 wh.su -+ * [WCXRP00000171] [MT6620 Wi-Fi][Driver] Add message check code same behavior as mt5921 -+ * use config.mk WAPI config define. -+ * -+ * 11 08 2010 wh.su -+ * [WCXRP00000171] [MT6620 Wi-Fi][Driver] Add message check code same behavior as mt5921 -+ * use the config.mk define. -+ * -+ * 11 01 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check -+ * [WCXRP00000150] [MT6620 Wi-Fi][Driver] Add implementation for querying current TX rate from firmware auto rate module -+ * 1) Query link speed (TX rate) from firmware directly with buffering mechanism to reduce overhead -+ * 2) Remove CNM CH-RECOVER event handling -+ * 3) cfg read/write API renamed with kal prefix for unified naming rules. -+ * -+ * 11 01 2010 yarco.yang -+ * [WCXRP00000149] [MT6620 WI-Fi][Driver]Fine tune performance on MT6516 platform -+ * Add code to run WlanIST in SDIO callback. -+ * -+ * 10 26 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check -+ * [WCXRP00000137] [MT6620 Wi-Fi] [FW] Support NIC capability query command -+ * 1) update NVRAM content template to ver 1.02 -+ * 2) add compile option for querying NIC capability (default: off) -+ * 3) modify AIS 5GHz support to run-time option, which could be turned on by registry or NVRAM setting -+ * 4) correct auto-rate compiler error under linux (treat warning as error) -+ * 5) simplify usage of NVRAM and REG_INFO_T -+ * 6) add version checking between driver and firmware -+ * -+ * 10 25 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check -+ * add option for enable/disable TX PWR gain adjustment (default: off) -+ * -+ * 10 20 2010 wh.su -+ * [WCXRP00000067] [MT6620 Wi-Fi][Driver] Support the android+ WAPI function -+ * enable the WAPI compiling flag as default -+ * -+ * 10 19 2010 cp.wu -+ * [WCXRP00000122] [MT6620 Wi-Fi][Driver] Preparation for YuSu source tree integration -+ * remove HIF_SDIO_ONE flags because the settings could be merged for runtime detection instead of compile-time. -+ * -+ * 10 18 2010 cp.wu -+ * [WCXRP00000117] [MT6620 Wi-Fi][Driver] Add logic for suspending driver when MT6620 is not responding anymore -+ * 1. when wlanAdapterStop() failed to send POWER CTRL command to firmware, do not poll for ready bit dis-assertion -+ * 2. shorten polling count for shorter response time -+ * 3. if bad I/O operation is detected during TX resource polling, then further operation is aborted as well -+ * -+ * 10 18 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check -+ * [WCXRP00000086] [MT6620 Wi-Fi][Driver] The mac address is all zero at android -+ * complete implementation of Android NVRAM access -+ * -+ * 10 14 2010 wh.su -+ * [WCXRP00000102] [MT6620 Wi-Fi] [FW] Add a compiling flag and code for support Direct GO at Android -+ * Add a define CFG_TEST_ANDROID_DIRECT_GO compiling flag -+ * -+ * 10 08 2010 cm.chang -+ * NULL -+ * Remove unused compiling flags (TX_RDG and TX_SGI) -+ * -+ * 10 07 2010 cp.wu -+ * [WCXRP00000083] [MT5931][Driver][FW] Add necessary logic for MT5931 first connection -+ * add firmware download for MT5931. -+ * -+ * 10 05 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check -+ * load manufacture data when CFG_SUPPORT_NVRAM is set to 1 -+ * -+ * 10 05 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check -+ * 1) add NVRAM access API -+ * 2) fake scanning result when NVRAM doesn't exist and/or version mismatch. (off by compiler option) -+ * 3) add OID implementation for NVRAM read/write service -+ * -+ * 10 05 2010 yarco.yang -+ * [WCXRP00000082] [MT6620 Wi-Fi][Driver]High throughput performance tuning -+ * Change CFG_IST_LOOP_COUNT from 2 to 1 to reduce unnecessary SDIO bus access -+ * -+ * 09 24 2010 cp.wu -+ * [WCXRP00000057] [MT6620 Wi-Fi][Driver] Modify online scan to a run-time switchable feature -+ * Modify online scan as a run-time adjustable option (for Windows, in registry) -+ * -+ * 09 23 2010 cp.wu -+ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning -+ * eliminate reference of CFG_RESPONSE_MAX_PKT_SIZE -+ * -+ * 09 20 2010 cm.chang -+ * NULL -+ * Disable RX STBC by BB HEC based on MT6620E1_PHY_BUG v05.docx -+ * -+ * 09 17 2010 chinglan.wang -+ * NULL -+ * Add performance test option -+ * -+ * 09 10 2010 chinglan.wang -+ * NULL -+ * Modify for Software Migration Phase 2.10 for E2 FPGA -+ * -+ * 09 07 2010 yuche.tsai -+ * NULL -+ * Add a CFG for max common IE buffer size. -+ * -+ * 09 01 2010 cp.wu -+ * NULL -+ * restore configuration as before. -+ * -+ * 09 01 2010 cp.wu -+ * NULL -+ * HIFSYS Clock Source Workaround -+ * -+ * 08 31 2010 kevin.huang -+ * NULL -+ * Use LINK LIST operation to process SCAN result -+ * -+ * 08 30 2010 chinglan.wang -+ * NULL -+ * Enable the MT6620_FPGA_BWCS value. -+ * -+ * 08 30 2010 chinglan.wang -+ * NULL -+ * Disable the FW encryption. -+ * -+ * 08 27 2010 chinglan.wang -+ * NULL -+ * Update configuration for MT6620_E1_PRE_ALPHA_1832_0827_2010 -+ * -+ * 08 26 2010 yuche.tsai -+ * NULL -+ * Add AT GO test configure mode under WinXP. -+ * Please enable 1. CFG_ENABLE_WIFI_DIRECT, 2. CFG_TEST_WIFI_DIRECT_GO, 3. CFG_SUPPORT_AAA -+ * -+ * 08 25 2010 cp.wu -+ * NULL -+ * add option for enabling AIS 5GHz scan -+ * -+ * 08 25 2010 george.huang -+ * NULL -+ * update OID/ registry control path for PM related settings -+ * -+ * 08 24 2010 cp.wu -+ * NULL -+ * 1) initialize variable for enabling short premable/short time slot. -+ * 2) add compile option for disabling online scan -+ * -+ * 08 24 2010 cm.chang -+ * NULL -+ * Support RLM initail channel of Ad-hoc, P2P and BOW -+ * -+ * 08 23 2010 cp.wu -+ * NULL -+ * revise constant definitions to be matched with implementation (original cmd-event definition is deprecated) -+ * -+ * 08 23 2010 chinghwa.yu -+ * NULL -+ * Disable BOW Test. -+ * -+ * 08 23 2010 jeffrey.chang -+ * NULL -+ * fix config.h typo -+ * -+ * 08 23 2010 chinghwa.yu -+ * NULL -+ * Update for BOW. -+ * -+ * 08 21 2010 jeffrey.chang -+ * NULL -+ * 1) add sdio two setting -+ * 2) bug fix of sdio glue -+ * -+ * 08 09 2010 wh.su -+ * NULL -+ * let the firmware download default enabled. -+ * -+ * 08 07 2010 wh.su -+ * NULL -+ * adding the privacy related code for P2P network -+ * -+ * 08 05 2010 yuche.tsai -+ * NULL -+ * Add a configure flag for P2P unitest. -+ * -+ * 07 23 2010 cp.wu -+ * -+ * 1) re-enable AIS-FSM beacon timeout handling. -+ * 2) scan done API revised -+ * -+ * 07 23 2010 cp.wu -+ * -+ * 1) enable Ad-Hoc -+ * 2) disable beacon timeout handling temporally due to unexpected beacon timeout event. -+ * -+ * 07 19 2010 wh.su -+ * -+ * update for security supporting. -+ * -+ * 07 19 2010 yuche.tsai -+ * -+ * Add for SLT support. -+ * -+ * 07 16 2010 cp.wu -+ * -+ * remove work-around in case SCN is not available. -+ * -+ * 07 14 2010 yarco.yang -+ * -+ * 1. Remove CFG_MQM_MIGRATION -+ * 2. Add CMD_UPDATE_WMM_PARMS command -+ * -+ * 07 13 2010 cp.wu -+ * -+ * 1) MMPDUs are now sent to MT6620 by CMD queue for keeping strict order of 1X/MMPDU/CMD packets -+ * 2) integrate with qmGetFrameAction() for deciding which MMPDU/1X could pass checking for sending -+ * 2) enhance CMD_INFO_T descriptor number from 10 to 32 to avoid descriptor -+ * underflow under concurrent network operation -+ * -+ * 07 09 2010 yarco.yang -+ * -+ * [MT6620 and MT5931] SW Migration: Add ADDBA support -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 07 08 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * take use of RLM module for parsing/generating HT IEs for 11n capability -+ * -+ * 07 07 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * for first connection, if connecting failed do not enter into scan state. -+ * -+ * 06 25 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * modify Beacon/ProbeResp to complete parsing, -+ * because host software has looser memory usage restriction -+ * -+ * 06 23 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) add SCN compilation option. -+ * 2) when SCN is not turned on, BSSID_SCAN will generate a fake entry for 1st connection -+ * -+ * 06 22 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) add command warpper for STA-REC/BSS-INFO sync. -+ * 2) enhance command packet sending procedure for non-oid part -+ * 3) add command packet definitions for STA-REC/BSS-INFO sync. -+ * -+ * 06 21 2010 wh.su -+ * [WPD00003840][MT6620 5931] Security migration -+ * set default compiling flag for security disable. -+ * -+ * 06 21 2010 yarco.yang -+ * [WPD00003837][MT6620]Data Path Refine -+ * Support CFG_MQM_MIGRATION flag -+ * -+ * 06 21 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * enable RX management frame handling. -+ * -+ * 06 21 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add scan_fsm into building. -+ * -+ * 06 18 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Provide cnmMgtPktAlloc() and alloc/free function of msg/buf -+ * -+ * 06 15 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add scan.c. -+ * -+ * 06 14 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add management dispatching function table. -+ * -+ * 06 11 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * auth.c is migrated. -+ * -+ * 06 11 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add bss.c. -+ * -+ * 06 11 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) migrate assoc.c. -+ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness -+ * 3) add configuration options for CNM_MEM and RSN modules -+ * 4) add data path for management frames -+ * 5) eliminate rPacketInfo of MSDU_INFO_T -+ * -+ * 06 10 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) eliminate CFG_CMD_EVENT_VERSION_0_9 -+ * 2) when disconnected, indicate nic directly (no event is needed) -+ * -+ * 06 07 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add aa_fsm.h, ais_fsm.h, bss.h, mib.h and scan.h. -+ * -+ * 06 07 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * merge wlan_def.h. -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 05 31 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * add config option for cfg80211. -+ * -+ * 05 26 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * set ATIMwindow default value to zero. -+ * -+ * 05 21 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * add option for FPGA_BWCS & FPGA_V5 -+ * -+ * 05 20 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) integrate OID_GEN_NETWORK_LAYER_ADDRESSES with CMD_ID_SET_IP_ADDRESS -+ * 2) buffer statistics data for 2 seconds -+ * 3) use default value for adhoc parameters instead of 0 -+ * -+ * 05 17 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) enable CMD/EVENT ver 0.9 definition. -+ * 2) abandon use of ENUM_MEDIA_STATE -+ * -+ * 05 17 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * add CFG_STARTUP_DEBUG for debugging starting up issue. -+ * -+ * 05 17 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * add basic handling framework for wireless extension ioctls. -+ * -+ * 05 11 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * change firmware name to WIFI_RAM_CODE. -+ * -+ * 05 07 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * disable bt-over-wifi configuration, turn it on after firmware finished implementation -+ * -+ * 04 27 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * add multiple physical link support -+ * -+ * 04 23 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * surpress compiler warning -+ * -+ * 04 22 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * re-enable power management -+ * -+ * 04 22 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * -+ * 1) modify rx path code for supporting Wi-Fi direct -+ * 2) modify config.h since Linux dont need to consider retaining packet -+ * -+ * 04 22 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * enable TCP/IP checksum offloading by default. -+ * -+ * 04 19 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * set CFG_ENABLE_FULL_PM to 1 as default to -+ * 1) acquire own before hardware access -+ * 2) set own back after hardware access -+ * -+ * 04 15 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * change firmware name -+ * -+ * 04 07 2010 cp.wu -+ * [WPD00003827][MT6620 Wi-Fi] Chariot fail and following ping fail, no pkt send from driver -+ * disable RX-enhanced response temporally, it seems the CQ is not resolved yet. -+ * -+ * 04 06 2010 cp.wu -+ * [WPD00003827][MT6620 Wi-Fi] Chariot fail and following ping fail, no pkt send from driver -+ * re-enable RX enhanced mode as WPD00003827 is resolved. -+ * -+ * 04 06 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * turn off RX_ENHANCE mode by default. -+ * -+ * 04 06 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) eliminate unused definitions -+ * * 2) ready bit will be polled for limited iteration -+ * -+ * 04 02 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * firmware download: Linux uses different firmware path -+ * -+ * 04 01 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * change to use WIFI_TCM_ALWAYS_ON as firmware image -+ * -+ * 03 31 2010 wh.su -+ * [WPD00003816][MT6620 Wi-Fi] Adding the security support -+ * modify the wapi related code for new driver's design. -+ * -+ * 03 26 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * add a temporary flag for integration with CMD/EVENT v0.9. -+ * -+ * 03 25 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * firmware download load address & start address are now configured from config.h -+ * * due to the different configurations on FPGA and ASIC -+ * -+ * 03 24 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * add options for full PM support. -+ * -+ * 03 24 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * [WPD00003826] Initial import for Linux port -+ * initial import for Linux port -+ * -+ * 03 24 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * [WPD00003826] Initial import for Linux port -+ * initial import for Linux port -+ * -+ * 03 24 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * initial import for Linux port -+ * -+ * 03 16 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * turn on FW-DOWNLOAD as default for release. -+ * -+ * 03 16 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * build up basic data structure and definitions to support BT-over-WiFi -+ * -+ * 03 12 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * add two option for ACK and ENCRYPTION for firmware download -+ * -+ * 03 11 2010 cp.wu -+ * [WPD00003821][BUG] Host driver stops processing RX packets from HIF RX0 -+ * add RX starvation warning debug message controlled by CFG_HIF_RX_STARVATION_WARNING -+ * -+ * 03 10 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * code clean: removing unused variables and structure definitions -+ * -+ * 03 05 2010 cp.wu -+ * [WPD00003821][BUG] Host driver stops processing RX packets from HIF RX0 -+ * change CFG_NUM_OF_QM_RX_PKT_NUM to 120 -+ * -+ * 03 04 2010 cp.wu -+ * [WPD00003821][BUG] Host driver stops processing RX packets from HIF RX0 -+ * . -+ * -+ * 03 04 2010 cp.wu -+ * [WPD00003821][BUG] Host driver stops processing RX packets from HIF RX0 -+ * increase RX buffer number to avoid RX buffer starvation. -+ * -+ * 02 24 2010 tehuang.liu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * Changed the number of STA_RECs to 20 -+ * -+ * 02 23 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * add checksum offloading support. -+ * -+ * 02 11 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1. add logic for firmware download -+ * * 2. firmware image filename and start/load address are now retrieved from registry -+ * -+ * 02 08 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * prepare for implementing fw download logic -+ * -+ * 12 30 2009 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) According to CMD/EVENT documentation v0.8, -+ * * OID_CUSTOM_TEST_RX_STATUS & OID_CUSTOM_TEST_TX_STATUS is no longer used, -+ * * and result is retrieved by get ATInfo instead -+ * * 2) add 4 counter for recording aggregation statistics -+** \main\maintrunk.MT6620WiFiDriver_Prj\25 2009-12-16 22:12:28 GMT mtk02752 -+** enable interrupt enhanced response, TX/RX Aggregation as default -+** \main\maintrunk.MT6620WiFiDriver_Prj\24 2009-12-10 16:38:43 GMT mtk02752 -+** eliminate compile options which are obsolete or for emulation purpose -+** \main\maintrunk.MT6620WiFiDriver_Prj\23 2009-12-09 13:56:26 GMT MTK02468 -+** Added RX buffer reordering configurations -+** \main\maintrunk.MT6620WiFiDriver_Prj\22 2009-12-04 12:09:09 GMT mtk02752 -+** once enhanced intr/rx response is taken, RX must be access in aggregated basis -+** \main\maintrunk.MT6620WiFiDriver_Prj\21 2009-11-23 17:54:50 GMT mtk02752 -+** correct a typo -+** \main\maintrunk.MT6620WiFiDriver_Prj\20 2009-11-17 22:40:47 GMT mtk01084 -+** add defines -+** \main\maintrunk.MT6620WiFiDriver_Prj\19 2009-11-17 17:33:37 GMT mtk02752 -+** add coalescing buffer definition for SD1_SD3_DATAPATH_INTEGRATION -+** \main\maintrunk.MT6620WiFiDriver_Prj\18 2009-11-16 20:32:40 GMT mtk02752 -+** add CFG_TX_MAX_PKT_NUM for limiting queued TX packet -+** \main\maintrunk.MT6620WiFiDriver_Prj\17 2009-11-16 13:34:44 GMT mtk02752 -+** add SD1_SD3_DATAPATH_INTEGRATION define for source control -+** \main\maintrunk.MT6620WiFiDriver_Prj\16 2009-11-13 13:54:11 GMT mtk01084 -+** enable INT enhance mode by default -+** \main\maintrunk.MT6620WiFiDriver_Prj\15 2009-10-30 18:17:14 GMT mtk01084 -+** add new define -+** \main\maintrunk.MT6620WiFiDriver_Prj\14 2009-10-29 19:47:36 GMT mtk01084 -+** not use HIF loopback mode -+** \main\maintrunk.MT6620WiFiDriver_Prj\13 2009-10-13 21:58:33 GMT mtk01084 -+** update for new macro define -+** \main\maintrunk.MT6620WiFiDriver_Prj\12 2009-09-09 17:26:08 GMT mtk01084 -+** add CFG_TEST_WITH_MT5921 -+** \main\maintrunk.MT6620WiFiDriver_Prj\11 2009-05-18 21:02:30 GMT mtk01426 -+** Update CFG_RX_COALESCING_BUFFER_SIZE -+** \main\maintrunk.MT6620WiFiDriver_Prj\10 2009-04-21 09:35:51 GMT mtk01461 -+** Add CFG_TX_DBG_MGT_BUF to debug MGMT Buffer depth -+** \main\maintrunk.MT6620WiFiDriver_Prj\9 2009-04-14 15:52:21 GMT mtk01426 -+** Add OOB_DATA_PRE_FIXED_LEN define -+** \main\maintrunk.MT6620WiFiDriver_Prj\8 2009-04-08 16:51:08 GMT mtk01084 -+** update for FW download part -+** \main\maintrunk.MT6620WiFiDriver_Prj\7 2009-04-01 10:33:37 GMT mtk01461 -+** Add SW pre test flag CFG_HIF_LOOPBACK_PRETEST -+** \main\maintrunk.MT6620WiFiDriver_Prj\6 2009-03-23 00:29:18 GMT mtk01461 -+** Fix CFG_COALESCING_BUFFER_SIZE if enable the CFG_TX_FRAGMENT -+** \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-03-18 20:58:34 GMT mtk01426 -+** Add CFG_HIF_LOOPBACK and CFG_SDIO_RX_ENHANCE -+** \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-03-17 20:17:36 GMT mtk01426 -+** Add CMD/Response related configure -+** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-03-16 09:08:21 GMT mtk01461 -+** Update TX PATH API -+** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 20:11:21 GMT mtk01426 -+** Init for develop -+** -+*/ -+ -+#ifndef _CONFIG_H -+#define _CONFIG_H -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+#ifdef MT6620 -+#undef MT6620 -+#endif -+ -+#ifndef MT6628 -+#define MT6628 -+#endif -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+/* 2 Flags for OS capability */ -+ -+#define MTK_WCN_SINGLE_MODULE 0 /* 1: without WMT */ -+ -+#ifdef LINUX -+#ifdef CONFIG_X86 -+#define MTK_WCN_HIF_SDIO 0 -+#else -+#define MTK_WCN_HIF_SDIO 0 /* samp */ -+#endif -+#else -+#define MTK_WCN_HIF_SDIO 0 -+#endif -+ -+#if (CFG_SUPPORT_AEE == 1) -+#define CFG_ENABLE_AEE_MSG 1 -+#else -+#define CFG_ENABLE_AEE_MSG 0 -+#endif -+ -+#if CFG_ENABLE_AEE_MSG -+#include -+#endif -+ -+/* 2 Flags for Driver Features */ -+#define CFG_TX_FRAGMENT 1 /*!< 1: Enable TX fragmentation -+ 0: Disable */ -+#define CFG_SUPPORT_PERFORMANCE_TEST 0 /*Only for performance Test */ -+ -+#define CFG_COUNTRY_CODE NULL /* "US" */ -+ -+#ifndef LINUX -+#define CFG_FW_FILENAME L"WIFI_RAM_CODE" -+#define CFG_FW_FILENAME_E6 L"WIFI_RAM_CODE_E6" -+#else -+#define CFG_FW_FILENAME "WIFI_RAM_CODE" -+#endif -+#ifndef LINUX -+#define CFG_SUPPORT_CFG_FILE 0 -+#else -+#define CFG_SUPPORT_CFG_FILE 1 -+#endif -+ -+#define CFG_SUPPORT_CE_FCC_TXPWR_LIMIT 0 /* Support CE FCC Tx Power limit */ -+ -+#define CFG_SUPPORT_802_11D 1 /*!< 1(default): Enable 802.11d -+ 0: Disable */ -+ -+#define CFG_SUPPORT_RRM 0 /* Radio Reasource Measurement (802.11k) */ -+#define CFG_SUPPORT_DFS 1 /* DFS (802.11h) */ -+ -+#if (CFG_SUPPORT_DFS == 1) /* Add by Enlai */ -+#define CFG_SUPPORT_QUIET 1 /* Quiet (802.11h) */ -+#define CFG_SUPPORT_SPEC_MGMT 1 /* Spectrum Management (802.11h): TPC and DFS */ -+#else -+#define CFG_SUPPORT_QUIET 0 /* Quiet (802.11h) */ -+#define CFG_SUPPORT_SPEC_MGMT 0 /* Spectrum Management (802.11h): TPC and DFS */ -+#endif -+ -+#define CFG_SUPPORT_RX_RDG 0 /* 11n feature. RX RDG capability */ -+#define CFG_SUPPORT_MFB 0 /* 802.11n MCS Feedback responder */ -+#define CFG_SUPPORT_RX_STBC 1 /* 802.11n RX STBC (1SS) */ -+#define CFG_SUPPORT_RX_SGI 1 /* 802.11n RX short GI for both 20M and 40M BW */ -+#define CFG_SUPPORT_RX_HT_GF 1 /* 802.11n RX HT green-field capability */ -+ -+#define CFG_SUPPORT_ROAMING_ENC 0 /* enahnced roaming */ -+ -+#define CFG_SUPPORT_TDLS 1 /* IEEE802.11z TDLS */ -+#define CFG_SUPPORT_TDLS_DBG 0 /* TDLS debug */ -+#define CFG_SUPPORT_STATISTICS 1 -+#define CFG_SUPPORT_DBG_POWERMODE 1 /* for debugging power always active mode */ -+ -+#define CFG_SUPPORT_GSCN 1 -+ -+#define CFG_SUPPORT_TXR_ENC 0 /* enhanced tx rate switch */ -+ -+#define CFG_SUPPORT_PERSIST_NETDEV 0 /* create NETDEV when system bootup */ -+ -+#define CFG_FORCE_USE_20BW 1 -+/*------------------------------------------------------------------------------ -+ * SLT Option -+ *------------------------------------------------------------------------------ -+ */ -+#define CFG_SLT_SUPPORT 0 -+ -+#define MTK_AUTO_CHANNEL_SEL_SUPPORT_ENABLE 0 -+ -+#if defined(MTK_AUTO_CHANNEL_SEL_SUPPORT_ENABLE) -+#define CFG_AUTO_CHANNEL_SEL_SUPPORT 1 -+#else -+#define CFG_AUTO_CHANNEL_SEL_SUPPORT 0 -+#endif -+ -+#ifdef NDIS60_MINIPORT -+#define CFG_NATIVE_802_11 1 -+ -+#define CFG_TX_MAX_PKT_SIZE 2304 -+#define CFG_TCP_IP_CHKSUM_OFFLOAD_NDIS_60 0 /* !< 1: Enable TCP/IP header checksum offload -+ 0: Disable */ -+#define CFG_TCP_IP_CHKSUM_OFFLOAD 0 -+#define CFG_WHQL_DOT11_STATISTICS 1 -+#define CFG_WHQL_ADD_REMOVE_KEY 1 -+#define CFG_WHQL_CUSTOM_IE 1 -+#define CFG_WHQL_SAFE_MODE_ENABLED 1 -+ -+#else -+#define CFG_TCP_IP_CHKSUM_OFFLOAD 1 /* !< 1: Enable TCP/IP header checksum offload -+ 0: Disable */ -+#define CFG_TCP_IP_CHKSUM_OFFLOAD_NDIS_60 0 -+#define CFG_TX_MAX_PKT_SIZE 1600 -+#define CFG_NATIVE_802_11 0 -+#endif -+ -+/* 2 Flags for Driver Parameters */ -+/*------------------------------------------------------------------------------ -+ * Flags for EHPI Interface in Colibri Platform -+ *------------------------------------------------------------------------------ -+ */ -+#define CFG_EHPI_FASTER_BUS_TIMING 0 /*!< 1: Do workaround for faster bus timing -+ 0(default): Disable */ -+ -+/*------------------------------------------------------------------------------ -+ * Flags for HIFSYS Interface -+ *------------------------------------------------------------------------------ -+ */ -+#ifdef _lint -+#define _HIF_SDIO 0 /* samp */ -+#endif -+ -+#define CFG_SDIO_INTR_ENHANCE 1 /*!< 1(default): Enable SDIO ISR & TX/RX status enhance mode -+ 0: Disable */ -+#define CFG_SDIO_RX_ENHANCE 0 /*!< 1(default): Enable SDIO ISR & TX/RX status enhance mode -+ 0: Disable */ -+#define CFG_SDIO_TX_AGG 1 /*!< 1: Enable SDIO TX enhance -+ mode(Multiple frames in single BLOCK CMD) -+ 0(default): Disable */ -+ -+#define CFG_SDIO_RX_AGG 1 /*!< 1: Enable SDIO RX enhance -+ mode(Multiple frames in single BLOCK CMD) -+ 0(default): Disable */ -+ -+#if (CFG_SDIO_RX_AGG == 1) && (CFG_SDIO_INTR_ENHANCE == 0) -+#error "CFG_SDIO_INTR_ENHANCE should be 1 once CFG_SDIO_RX_AGG equals to 1" -+#elif (CFG_SDIO_INTR_ENHANCE == 1 || CFG_SDIO_RX_ENHANCE == 1) && (CFG_SDIO_RX_AGG == 0) -+#error "CFG_SDIO_RX_AGG should be 1 once CFG_SDIO_INTR_ENHANCE and/or CFG_SDIO_RX_ENHANCE equals to 1" -+#endif -+ -+#define CFG_SDIO_MAX_RX_AGG_NUM 0 /*!< 1: Setting the maximum RX aggregation number -+ 0(default): no limited */ -+ -+#ifdef WINDOWS_CE -+#define CFG_SDIO_PATHRU_MODE 1 /*!< 1: Support pass through (PATHRU) mode -+ 0: Disable */ -+#else -+#define CFG_SDIO_PATHRU_MODE 0 /*!< 0: Always disable if WINDOWS_CE is not defined */ -+#endif -+ -+#define CFG_MAX_RX_ENHANCE_LOOP_COUNT 3 -+ -+/*------------------------------------------------------------------------------ -+ * Flags and Parameters for Integration -+ *------------------------------------------------------------------------------ -+ */ -+#if defined(MT6620) -+#define MT6620_FPGA_BWCS 0 -+#define MT6620_FPGA_V5 0 -+ -+#if (MT6620_FPGA_BWCS == 1) && (MT6620_FPGA_V5 == 1) -+#error -+#endif -+ -+#if (MTK_WCN_HIF_SDIO == 1) -+#define CFG_MULTI_ECOVER_SUPPORT 1 -+#elif !defined(LINUX) -+#define CFG_MULTI_ECOVER_SUPPORT 1 -+#else -+#define CFG_MULTI_ECOVER_SUPPORT 0 -+#endif -+ -+#define CFG_ENABLE_CAL_LOG 0 -+#define CFG_REPORT_RFBB_VERSION 0 -+ -+#elif defined(MT6628) -+ -+#define CFG_MULTI_ECOVER_SUPPORT 0 -+ -+#define CFG_ENABLE_CAL_LOG 1 -+#define CFG_REPORT_RFBB_VERSION 1 -+ -+#endif -+ -+#define CFG_CHIP_RESET_SUPPORT 1 -+ -+#if defined(MT6628) -+#define CFG_EMBED_FIRMWARE_BUILD_DATE_CODE 1 -+#endif -+ -+/*------------------------------------------------------------------------------ -+ * Flags for workaround -+ *------------------------------------------------------------------------------ -+ */ -+#if defined(MT6620) && (MT6620_FPGA_BWCS == 0) && (MT6620_FPGA_V5 == 0) -+#define MT6620_E1_ASIC_HIFSYS_WORKAROUND 0 -+#else -+#define MT6620_E1_ASIC_HIFSYS_WORKAROUND 0 -+#endif -+ -+/* SPM issue: suspend current is higher than deep idle */ -+#define CFG_SPM_WORKAROUND_FOR_HOTSPOT 1 -+ -+/*------------------------------------------------------------------------------ -+ * Flags for driver version -+ *------------------------------------------------------------------------------ -+ */ -+#define CFG_DRV_OWN_VERSION \ -+ ((UINT_16)((NIC_DRIVER_MAJOR_VERSION << 8) | (NIC_DRIVER_MINOR_VERSION))) -+#define CFG_DRV_PEER_VERSION ((UINT_16)0x0000) -+ -+/*------------------------------------------------------------------------------ -+ * Flags for TX path which are OS dependent -+ *------------------------------------------------------------------------------ -+ */ -+/*! NOTE(Kevin): If the Network buffer is non-scatter-gather like structure(without -+ * NETIF_F_FRAGLIST in LINUX), then we can set CFG_TX_BUFFER_IS_SCATTER_LIST to "0" -+ * for zero copy TX packets. -+ * For scatter-gather like structure, we set "1", driver will do copy frame to -+ * internal coalescing buffer before write it to FIFO. -+ */ -+#if defined(LINUX) -+#define CFG_TX_BUFFER_IS_SCATTER_LIST 1 /*!< 1: Do frame copy before write to TX FIFO. -+ Used when Network buffer is scatter-gather. -+ 0(default): Do not copy frame */ -+#else /* WINDOWS/WINCE */ -+#define CFG_TX_BUFFER_IS_SCATTER_LIST 1 -+#endif /* LINUX */ -+ -+#if CFG_SDIO_TX_AGG || CFG_TX_BUFFER_IS_SCATTER_LIST -+#define CFG_COALESCING_BUFFER_SIZE (CFG_TX_MAX_PKT_SIZE * NIC_TX_BUFF_SUM) -+#else -+#define CFG_COALESCING_BUFFER_SIZE (CFG_TX_MAX_PKT_SIZE) -+#endif /* CFG_SDIO_TX_AGG || CFG_TX_BUFFER_IS_SCATTER_LIST */ -+ -+/*------------------------------------------------------------------------------ -+ * Flags and Parameters for TX path -+ *------------------------------------------------------------------------------ -+ */ -+ -+/*! Maximum number of SW TX packet queue */ -+#define CFG_TX_MAX_PKT_NUM 512 /* 256 must >= CFG_TX_STOP_NETIF_PER_QUEUE_THRESHOLD * 2; -+ or wmm will fail when queue is full */ -+ -+/*! Maximum number of SW TX CMD packet buffer */ -+#define CFG_TX_MAX_CMD_PKT_NUM 32 -+ -+/*! Maximum number of associated STAs */ -+#define CFG_NUM_OF_STA_RECORD 20 -+ -+/*------------------------------------------------------------------------------ -+ * Flags and Parameters for RX path -+ *------------------------------------------------------------------------------ -+ */ -+ -+/*! Max. descriptor number - sync. with firmware */ -+#if CFG_SLT_SUPPORT -+#define CFG_NUM_OF_RX0_HIF_DESC 42 -+#else -+#define CFG_NUM_OF_RX0_HIF_DESC 16 -+#endif -+#define CFG_NUM_OF_RX1_HIF_DESC 2 -+ -+/*! Max. buffer hold by QM */ -+#define CFG_NUM_OF_QM_RX_PKT_NUM 120 -+ -+/*! Maximum number of SW RX packet buffer */ -+#define CFG_RX_MAX_PKT_NUM ((CFG_NUM_OF_RX0_HIF_DESC + CFG_NUM_OF_RX1_HIF_DESC) * 3 \ -+ + CFG_NUM_OF_QM_RX_PKT_NUM) -+ -+#define CFG_RX_REORDER_Q_THRESHOLD 8 -+ -+#ifndef LINUX -+#define CFG_RX_RETAINED_PKT_THRESHOLD \ -+ (CFG_NUM_OF_RX0_HIF_DESC + CFG_NUM_OF_RX1_HIF_DESC + CFG_NUM_OF_QM_RX_PKT_NUM) -+#else -+#define CFG_RX_RETAINED_PKT_THRESHOLD 0 -+#endif -+ -+/*! Maximum RX packet size, if exceed this value, drop incoming packet */ -+/* 7.2.3 Maganement frames */ -+#define CFG_RX_MAX_PKT_SIZE (28 + 2312 + 12 /*HIF_RX_HEADER_T*/) /* TODO: it should be -+ 4096 under emulation mode */ -+ -+/*! Minimum RX packet size, if lower than this value, drop incoming packet */ -+#define CFG_RX_MIN_PKT_SIZE 10 /*!< 802.11 Control Frame is 10 bytes */ -+ -+#if CFG_SDIO_RX_AGG -+ /* extra size for CS_STATUS and enhanced response */ -+#define CFG_RX_COALESCING_BUFFER_SIZE ((CFG_NUM_OF_RX0_HIF_DESC + 1) \ -+ * CFG_RX_MAX_PKT_SIZE) -+#else -+#define CFG_RX_COALESCING_BUFFER_SIZE (CFG_RX_MAX_PKT_SIZE) -+#endif -+ -+/*! RX BA capability */ -+#define CFG_NUM_OF_RX_BA_AGREEMENTS 8 -+#define CFG_RX_BA_MAX_WINSIZE 16 -+#define CFG_RX_BA_INC_SIZE 4 -+#define CFG_RX_MAX_BA_TID_NUM 8 -+#define CFG_RX_REORDERING_ENABLED 1 -+ -+/*------------------------------------------------------------------------------ -+ * Flags and Parameters for CMD/RESPONSE -+ *------------------------------------------------------------------------------ -+ */ -+#define CFG_RESPONSE_POLLING_TIMEOUT 512 -+ -+/*------------------------------------------------------------------------------ -+ * Flags and Parameters for Protocol Stack -+ *------------------------------------------------------------------------------ -+ */ -+/*! Maximum number of BSS in the SCAN list */ -+#define CFG_MAX_NUM_BSS_LIST 64 -+ -+#define CFG_MAX_COMMON_IE_BUF_LEN ((1500 * CFG_MAX_NUM_BSS_LIST) / 3) -+ -+/*! Maximum size of Header buffer of each SCAN record */ -+#define CFG_RAW_BUFFER_SIZE 1024 -+ -+/*! Maximum size of IE buffer of each SCAN record */ -+#define CFG_IE_BUFFER_SIZE 512 -+ -+/*! Maximum number of STA records */ -+#define CFG_MAX_NUM_STA_RECORD 32 -+ -+/*------------------------------------------------------------------------------ -+ * Flags and Parameters for Power management -+ *------------------------------------------------------------------------------ -+ */ -+#define CFG_ENABLE_FULL_PM 1 -+#define CFG_ENABLE_WAKEUP_ON_LAN 0 -+#if defined(CONFIG_ARCH_MT6755) || defined(CONFIG_ARCH_MT6735) || defined(CONFIG_ARCH_MT6735M) || \ -+ defined(CONFIG_ARCH_MT6753) || defined(CONFIG_ARCH_MT6580) -+#define CFG_SUPPORT_WAKEUP_REASON_DEBUG 1 /* debug which packet wake up host */ -+#else -+#define CFG_SUPPORT_WAKEUP_REASON_DEBUG 0 /* debug which packet wake up host */ -+#endif -+#define CFG_INIT_POWER_SAVE_PROF ENUM_PSP_FAST_SWITCH -+ -+#define CFG_INIT_ENABLE_PATTERN_FILTER_ARP 0 -+ -+#define CFG_INIT_UAPSD_AC_BMP 0 /* (BIT(3) | BIT(2) | BIT(1) | BIT(0)) */ -+ -+/* #define CFG_SUPPORT_WAPI 0 */ -+#define CFG_SUPPORT_WPS 1 -+#define CFG_SUPPORT_WPS2 1 -+ -+/*------------------------------------------------------------------------------ -+ * 802.11i RSN Pre-authentication PMKID cahce maximun number -+ *------------------------------------------------------------------------------ -+ */ -+#define CFG_MAX_PMKID_CACHE 16 /*!< max number of PMKID cache -+ 16(default) : The Max PMKID cache */ -+/*------------------------------------------------------------------------------ -+ * Auto Channel Selection Maximun Channel Number -+ *------------------------------------------------------------------------------ -+ */ -+ -+#define MAX_AUTO_CHAL_NUM 23 /* Ch1~Ch14,Ch36,Ch40,Ch44, -+ Ch48,Ch149,Ch153,Ch157,Ch161 */ -+/*------------------------------------------------------------------------------ -+ * FAST SCAN -+ *------------------------------------------------------------------------------ -+ */ -+#define CFG_ENABLE_FAST_SCAN 0 -+#define CFG_CN_SUPPORT_CLASS121 0 /* Add Class 121, 5470-5725MHz, support for China domain */ -+#if CFG_ENABLE_FAST_SCAN -+ #define CFG_FAST_SCAN_DWELL_TIME 40 -+ #define CFG_FAST_SCAN_REG_DOMAIN_DEF_IDX 10 -+#endif -+/*------------------------------------------------------------------------------ -+ * Flags and Parameters for Ad-Hoc -+ *------------------------------------------------------------------------------ -+ */ -+#define CFG_INIT_ADHOC_FREQ (2462000) -+#define CFG_INIT_ADHOC_MODE AD_HOC_MODE_MIXED_11BG -+#define CFG_INIT_ADHOC_BEACON_INTERVAL (100) -+#define CFG_INIT_ADHOC_ATIM_WINDOW (0) -+ -+/*------------------------------------------------------------------------------ -+ * Flags and Parameters for Maximum Scan SSID number -+ *------------------------------------------------------------------------------ -+ */ -+#define CFG_SCAN_SSID_MAX_NUM (4) -+#define CFG_SCAN_SSID_MATCH_MAX_NUM (16) -+ -+/*------------------------------------------------------------------------------ -+ * Flags and Parameters for Load Setup Default -+ *------------------------------------------------------------------------------ -+ */ -+ -+/*------------------------------------------------------------------------------ -+ * Flags for enable 802.11A Band setting -+ *------------------------------------------------------------------------------ -+ */ -+ -+/*------------------------------------------------------------------------------ -+ * Flags and Parameters for Interrupt Process -+ *------------------------------------------------------------------------------ -+ */ -+#if defined(_HIF_SDIO) && defined(WINDOWS_CE) -+#define CFG_IST_LOOP_COUNT 8 -+#else -+#define CFG_IST_LOOP_COUNT 8 -+#endif /* _HIF_SDIO */ -+ -+#define CFG_INT_WRITE_CLEAR 0 -+ -+#if defined(LINUX) -+#define CFG_DBG_GPIO_PINS 0 /* if 1, use MT6516 GPIO pin to log TX behavior */ -+#endif -+ -+/* 2 Flags for Driver Debug Options */ -+/*------------------------------------------------------------------------------ -+ * Flags of TX Debug Option. NOTE(Kevin): Confirm with SA before modifying following flags. -+ *------------------------------------------------------------------------------ -+ */ -+#define CFG_DBG_MGT_BUF 1 /*!< 1: Debug statistics usage of MGMT Buffer -+ 0: Disable */ -+ -+#define CFG_HIF_STATISTICS 0 -+ -+#define CFG_HIF_RX_STARVATION_WARNING 0 -+ -+#define CFG_STARTUP_DEBUG 0 -+ -+#define CFG_RX_PKTS_DUMP 1 -+ -+/*------------------------------------------------------------------------------ -+ * Flags of Firmware Download Option. -+ *------------------------------------------------------------------------------ -+ */ -+#define CFG_ENABLE_FW_DOWNLOAD 1 -+ -+#define CFG_ENABLE_FW_DOWNLOAD_ACK 1 -+#define CFG_ENABLE_FW_ENCRYPTION 1 -+ -+#if defined(MT6628) -+#define CFG_ENABLE_FW_DOWNLOAD_AGGREGATION 0 -+#define CFG_ENABLE_FW_DIVIDED_DOWNLOAD 1 -+#endif -+ -+#if defined(MT6620) -+#if MT6620_FPGA_BWCS -+#define CFG_FW_LOAD_ADDRESS 0x10014000 -+#define CFG_OVERRIDE_FW_START_ADDRESS 0 -+#define CFG_FW_START_ADDRESS 0x10014001 -+#elif MT6620_FPGA_V5 -+#define CFG_FW_LOAD_ADDRESS 0x10008000 -+#define CFG_OVERRIDE_FW_START_ADDRESS 0 -+#define CFG_FW_START_ADDRESS 0x10008001 -+#else -+#define CFG_FW_LOAD_ADDRESS 0x10008000 -+#define CFG_OVERRIDE_FW_START_ADDRESS 0 -+#define CFG_FW_START_ADDRESS 0x10008001 -+#endif -+#elif defined(MT6628) -+#define CFG_FW_LOAD_ADDRESS 0x00060000 -+#define CFG_OVERRIDE_FW_START_ADDRESS 1 -+#define CFG_FW_START_ADDRESS 0x00060000 -+#define CFG_START_ADDRESS_IS_1ST_SECTION_ADDR 1 -+#endif -+ -+/*------------------------------------------------------------------------------ -+ * Flags of Bluetooth-over-WiFi (BT 3.0 + HS) support -+ *------------------------------------------------------------------------------ -+ */ -+ -+#ifdef LINUX -+#ifdef CONFIG_X86 -+#define CFG_ENABLE_BT_OVER_WIFI 0 -+#else -+#define CFG_ENABLE_BT_OVER_WIFI 1 -+#endif -+#else -+#define CFG_ENABLE_BT_OVER_WIFI 0 -+#endif -+ -+#define CFG_BOW_SEPARATE_DATA_PATH 1 -+ -+#define CFG_BOW_PHYSICAL_LINK_NUM 4 -+ -+#define CFG_BOW_TEST 0 -+ -+#define CFG_BOW_LIMIT_AIS_CHNL 1 -+ -+#define CFG_BOW_SUPPORT_11N 0 -+ -+#define CFG_BOW_RATE_LIMITATION 1 -+ -+/*------------------------------------------------------------------------------ -+ * Flags of Wi-Fi Direct support -+ *------------------------------------------------------------------------------ -+ */ -+#ifdef LINUX -+#ifdef CONFIG_X86 -+#define CFG_ENABLE_WIFI_DIRECT 0 -+#define CFG_SUPPORT_802_11W 0 -+#else -+#define CFG_ENABLE_WIFI_DIRECT 1 -+#define CFG_SUPPORT_802_11W 0 /*!< 0(default): Disable 802.11W */ -+#endif -+#else -+#define CFG_ENABLE_WIFI_DIRECT 0 -+#define CFG_SUPPORT_802_11W 0 /* Not support at WinXP */ -+#endif -+ -+#define CFG_SUPPORT_PERSISTENT_GROUP 0 -+ -+#define CFG_TEST_WIFI_DIRECT_GO 0 -+ -+#define CFG_TEST_ANDROID_DIRECT_GO 0 -+ -+#define CFG_UNITEST_P2P 0 -+ -+/* -+ * Enable cfg80211 option after Android 2.2(Froyo) is suggested, -+ * cfg80211 on linux 2.6.29 is not mature yet -+ */ -+#define CFG_ENABLE_WIFI_DIRECT_CFG_80211 1 -+ -+#define CFG_SUPPORT_HOTSPOT_OPTIMIZATION 1 -+#define CFG_HOTSPOT_OPTIMIZATION_BEACON_INTERVAL 300 -+#define CFG_HOTSPOT_OPTIMIZATION_DTIM 1 -+ -+/*------------------------------------------------------------------------------ -+ * Configuration Flags (Linux Only) -+ *------------------------------------------------------------------------------ -+ */ -+#define CFG_SUPPORT_EXT_CONFIG 0 -+ -+/*------------------------------------------------------------------------------ -+ * Statistics Buffering Mechanism -+ *------------------------------------------------------------------------------ -+ */ -+#if CFG_SUPPORT_PERFORMANCE_TEST -+#define CFG_ENABLE_STATISTICS_BUFFERING 1 -+#else -+#define CFG_ENABLE_STATISTICS_BUFFERING 0 -+#endif -+#define CFG_STATISTICS_VALID_CYCLE 2000 -+#define CFG_LINK_QUALITY_VALID_PERIOD 5000 -+ -+/*------------------------------------------------------------------------------ -+ * Migration Option -+ *------------------------------------------------------------------------------ -+ */ -+#define CFG_SUPPORT_ADHOC 0 -+#define CFG_SUPPORT_AAA 1 -+ -+#define CFG_SUPPORT_BCM 0 -+#define CFG_SUPPORT_BCM_BWCS 0 -+#define CFG_SUPPORT_BCM_BWCS_DEBUG 0 -+ -+#define CFG_SUPPORT_RDD_TEST_MODE 0 -+ -+#define CFG_SUPPORT_PWR_MGT 1 -+ -+#define CFG_RSN_MIGRATION 1 -+ -+#define CFG_PRIVACY_MIGRATION 1 -+ -+#define CFG_ENABLE_HOTSPOT_PRIVACY_CHECK 1 -+ -+#define CFG_MGMT_FRAME_HANDLING 1 -+ -+#define CFG_MGMT_HW_ACCESS_REPLACEMENT 0 -+ -+#if CFG_SUPPORT_PERFORMANCE_TEST -+ -+#else -+ -+#endif -+ -+#define CFG_SUPPORT_AIS_5GHZ 1 -+#define CFG_SUPPORT_BEACON_CHANGE_DETECTION 0 -+ -+/*------------------------------------------------------------------------------ -+ * Option for NVRAM and Version Checking -+ *------------------------------------------------------------------------------ -+ */ -+#define CFG_SUPPORT_NVRAM 1 -+#define CFG_NVRAM_EXISTENCE_CHECK 1 -+#define CFG_SW_NVRAM_VERSION_CHECK 1 -+#define CFG_SUPPORT_NIC_CAPABILITY 1 -+ -+/*------------------------------------------------------------------------------ -+ * CONFIG_TITLE : Stress Test Option -+ * OWNER : Puff Wen -+ * Description : For stress test only. DO NOT enable it while normal operation -+ *------------------------------------------------------------------------------ -+ */ -+#define CFG_STRESS_TEST_SUPPORT 0 -+ -+/*------------------------------------------------------------------------------ -+ * Flags for LINT -+ *------------------------------------------------------------------------------ -+ */ -+#define LINT_SAVE_AND_DISABLE /*lint -save -e* */ -+ -+#define LINT_RESTORE /*lint -restore */ -+ -+#define LINT_EXT_HEADER_BEGIN LINT_SAVE_AND_DISABLE -+ -+#define LINT_EXT_HEADER_END LINT_RESTORE -+ -+/*------------------------------------------------------------------------------ -+ * Flags of Features -+ *------------------------------------------------------------------------------ -+ */ -+ -+#define CFG_SUPPORT_QOS 1 /* Enable/disable QoS TX, AMPDU */ -+#define CFG_SUPPORT_AMPDU_TX 1 -+#define CFG_SUPPORT_AMPDU_RX 1 -+#define CFG_SUPPORT_TSPEC 0 /* Enable/disable TS-related Action frames handling */ -+#define CFG_SUPPORT_UAPSD 1 -+#define CFG_SUPPORT_UL_PSMP 0 -+ -+#define CFG_SUPPORT_ROAMING 1 /* Roaming System */ -+#define CFG_SUPPORT_SWCR 1 -+ -+#define CFG_SUPPORT_ANTI_PIRACY 1 -+ -+#define CFG_SUPPORT_OSC_SETTING 1 -+ -+#define CFG_SUPPORT_P2P_RSSI_QUERY 0 -+ -+#define CFG_SHOW_MACADDR_SOURCE 1 -+ -+#define CFG_SUPPORT_802_11V 0 /* Support 802.11v Wireless Network Management */ -+#define CFG_SUPPORT_802_11V_TIMING_MEASUREMENT 0 -+#if (CFG_SUPPORT_802_11V_TIMING_MEASUREMENT == 1) && (CFG_SUPPORT_802_11V == 0) -+#error "CFG_SUPPORT_802_11V should be 1 once CFG_SUPPORT_802_11V_TIMING_MEASUREMENT equals to 1" -+#endif -+#if (CFG_SUPPORT_802_11V == 0) -+#define WNM_UNIT_TEST 0 -+#endif -+ -+#define CFG_DRIVER_COMPOSE_ASSOC_REQ 1 -+ -+#define CFG_STRICT_CHECK_CAPINFO_PRIVACY 0 -+ -+#define CFG_SUPPORT_WFD 1 -+ -+#define CFG_SUPPORT_WFD_COMPOSE_IE 1 -+ -+/*------------------------------------------------------------------------------ -+ * Flags of Packet Lifetime Profiling Mechanism -+ *------------------------------------------------------------------------------ -+ */ -+#define CFG_ENABLE_PKT_LIFETIME_PROFILE 1 -+ -+#define CFG_ENABLE_PER_STA_STATISTICS 1 -+ -+#define CFG_PRINT_RTP_PROFILE 0 /* If want to enable WFD Debug, please change it to 1. */ -+#define CFG_PRINT_RTP_SN_SKIP 0 -+ -+#define CFG_SUPPORT_PWR_LIMIT_COUNTRY 1 -+/*------------------------------------------------------------------------------ -+ * Flags of bus error tolerance -+ *------------------------------------------------------------------------------ -+ */ -+#define CFG_FORCE_RESET_UNDER_BUS_ERROR 0 -+ -+/*------------------------------------------------------------------------------ -+ * Build Date Code Integration -+ *------------------------------------------------------------------------------ -+ */ -+#define CFG_SUPPORT_BUILD_DATE_CODE 1 -+ -+/*------------------------------------------------------------------------------ -+ * Flags for prepare the FW compile flag -+ *------------------------------------------------------------------------------ -+ */ -+#define COMPILE_FLAG0_GET_STA_LINK_STATUS (1<<0) -+#define COMPILE_FLAG0_WFD_ENHANCEMENT_PROTECT (1<<1) -+ -+/*------------------------------------------------------------------------------ -+ * Flags of Batch Scan SUPPORT -+ *------------------------------------------------------------------------------ -+ */ -+#define CFG_SUPPORT_BATCH_SCAN 0 -+#define CFG_BATCH_MAX_MSCAN 2 -+ -+/*------------------------------------------------------------------------------ -+ * Flags of Channel Environment SUPPORT -+ *------------------------------------------------------------------------------ -+ */ -+#define CFG_SUPPORT_GET_CH_ENV 1 -+ -+/*------------------------------------------------------------------------------ -+ * Flags of THERMO_THROTTLING SUPPORT -+ *------------------------------------------------------------------------------ -+ */ -+ -+#define CFG_SUPPORT_THERMO_THROTTLING 1 -+#define WLAN_INCLUDE_PROC 1 -+ -+#define CFG_SUPPORT_DETECT_SECURITY_MODE_CHANGE 1 -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif /* _CONFIG_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/debug.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/debug.h -new file mode 100644 -index 000000000000..af586063c21a ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/debug.h -@@ -0,0 +1,466 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/debug.h#1 -+*/ -+ -+/*! \file debug.h -+ \brief Definition of SW debugging level. -+ -+ In this file, it describes the definition of various SW debugging levels and -+ assert functions. -+*/ -+ -+/* -+** Log: debug.h -+ * -+ * 12 16 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * fixed the Windows DDK free build compiling error. -+ * -+ * 11 24 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * Adjust code for DBG and CONFIG_XLOG. -+ * -+ * 11 11 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * modify the xlog related code. -+ * -+ * 11 10 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * Using the new XLOG define for dum Memory. -+ * -+ * 11 03 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * Add dumpMemory8 at XLOG support. -+ * -+ * 11 02 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * adding the code for XLOG. -+ * -+ * 08 31 2011 cm.chang -+ * [WCXRP00000969] [MT6620 Wi-Fi][Driver][FW] Channel list for 5G band based on country code -+ * . -+ * -+ * 01 27 2011 tsaiyuan.hsu -+ * [WCXRP00000392] [MT6620 Wi-Fi][Driver] Add Roaming Support -+ * add roaming fsm -+ * 1. not support 11r, only use strength of signal to determine roaming. -+ * 2. not enable CFG_SUPPORT_ROAMING until completion of full test. -+ * 3. in 6620, adopt work-around to avoid sign extension problem of cck of hw -+ * 4. assume that change of link quality in smooth way. -+ * -+ * 01 07 2011 wh.su -+ * [WCXRP00000326] [MT6620][Wi-Fi][Driver] check in the binary format gl_sec.o.new instead of use change type!!! -+ * . -+ * -+ * 09 23 2010 cp.wu -+ * NULL -+ * add BOW index for debugging message and passing compilation -+ * -+ * 07 20 2010 wh.su -+ * -+ * adding the wapi code. -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 21 2010 yarco.yang -+ * [WPD00003837][MT6620]Data Path Refine -+ * Support CFG_MQM_MIGRATION flag -+ * -+ * 06 17 2010 yuche.tsai -+ * [WPD00003839][MT6620 5931][P2P] Feature migration -+ * Add one more debug moduel for P2P. -+ * -+ * 06 14 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add management dispatching function table. -+ * -+ * 06 11 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add bss.c. -+ * -+ * 06 11 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) migrate assoc.c. -+ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness -+ * 3) add configuration options for CNM_MEM and RSN modules -+ * 4) add data path for management frames -+ * 5) eliminate rPacketInfo of MSDU_INFO_T -+ * -+ * 06 10 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add debug module index for cnm and ais. -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 05 17 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * add CFG_STARTUP_DEBUG for debugging starting up issue. -+ * -+ * 04 26 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) surpress compiler warning -+ * 2) when acqruing LP-own, keep writing WHLPCR whenever OWN is not acquired yet -+** \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-10-29 19:47:50 GMT mtk01084 -+** add emu category -+** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-04-17 18:12:04 GMT mtk01426 -+** Don't use dynamic memory allocate for debug message -+** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 20:11:29 GMT mtk01426 -+** Init for develop -+** -+*/ -+ -+#ifndef _DEBUG_H -+#define _DEBUG_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+#ifndef BUILD_QA_DBG -+#define BUILD_QA_DBG 0 -+#endif -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "gl_typedef.h" -+ -+extern UINT_8 aucDebugModule[]; -+extern UINT_32 u4DebugModule; -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+/* Define debug category (class): -+ * (1) ERROR (2) WARN (3) STATE (4) EVENT (5) TRACE (6) INFO (7) LOUD (8) TEMP -+ */ -+#define DBG_CLASS_ERROR BIT(0) -+#define DBG_CLASS_WARN BIT(1) -+#define DBG_CLASS_STATE BIT(2) -+#define DBG_CLASS_EVENT BIT(3) -+#define DBG_CLASS_TRACE BIT(4) -+#define DBG_CLASS_INFO BIT(5) -+#define DBG_CLASS_LOUD BIT(6) -+#define DBG_CLASS_TEMP BIT(7) -+#define DBG_CLASS_MASK BITS(0, 7) -+ -+#if defined(LINUX) -+#define DBG_PRINTF_64BIT_DEC "lld" -+ -+#else /* Windows */ -+#define DBG_PRINTF_64BIT_DEC "I64d" -+ -+#endif -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+/* Define debug module index */ -+typedef enum _ENUM_DBG_MODULE_T { -+ DBG_INIT_IDX = 0, /* For driver initial */ -+ DBG_HAL_IDX, /* For HAL(HW) Layer */ -+ DBG_INTR_IDX, /* For Interrupt */ -+ DBG_REQ_IDX, -+ DBG_TX_IDX, -+ DBG_RX_IDX, -+ DBG_RFTEST_IDX, /* For RF test mode */ -+ DBG_EMU_IDX, /* Developer specific */ -+ -+ DBG_SW1_IDX, /* Developer specific */ -+ DBG_SW2_IDX, /* Developer specific */ -+ DBG_SW3_IDX, /* Developer specific */ -+ DBG_SW4_IDX, /* Developer specific */ -+ -+ DBG_HEM_IDX, /* HEM */ -+ DBG_AIS_IDX, /* AIS */ -+ DBG_RLM_IDX, /* RLM */ -+ DBG_MEM_IDX, /* RLM */ -+ DBG_CNM_IDX, /* CNM */ -+ DBG_RSN_IDX, /* RSN */ -+ DBG_BSS_IDX, /* BSS */ -+ DBG_SCN_IDX, /* SCN */ -+ DBG_SAA_IDX, /* SAA */ -+ DBG_AAA_IDX, /* AAA */ -+ DBG_P2P_IDX, /* P2P */ -+ DBG_QM_IDX, /* QUE_MGT */ -+ DBG_SEC_IDX, /* SEC */ -+ DBG_BOW_IDX, /* BOW */ -+ DBG_WAPI_IDX, /* WAPI */ -+ DBG_ROAMING_IDX, /* ROAMING */ -+ DBG_TDLS_IDX, /* TDLS *//* CFG_SUPPORT_TDLS */ -+ DBG_OID_IDX, -+ DBG_NIC_IDX, -+ -+ DBG_MODULE_NUM /* Notice the XLOG check */ -+} ENUM_DBG_MODULE_T; -+ -+/* XLOG */ -+/* #define XLOG_DBG_MODULE_IDX 28 */ /* DBG_MODULE_NUM */ -+/* #if (XLOG_DBG_MODULE_IDX != XLOG_DBG_MODULE_IDX) */ -+/* #error "Please modify the DBG_MODULE_NUM and make sure this include at XLOG" */ -+/* #endif */ -+ -+/* Define who owns developer specific index */ -+#define DBG_YARCO_IDX DBG_SW1_IDX -+#define DBG_KEVIN_IDX DBG_SW2_IDX -+#define DBG_CMC_IDX DBG_SW3_IDX -+#define DBG_GEORGE_IDX DBG_SW4_IDX -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+/* Debug print format string for the OS system time */ -+#define OS_SYSTIME_DBG_FORMAT "0x%08x" -+ -+/* Debug print argument for the OS system time */ -+#define OS_SYSTIME_DBG_ARGUMENT(systime) (systime) -+ -+/* Debug print format string for the MAC Address */ -+#define MACSTR "%pM" -+/* "%02x:%02x:%02x:%02x:%02x:%02x" */ -+ -+/* Debug print argument for the MAC Address */ -+#define MAC2STR(a) a -+/* ((PUINT_8)a)[0], ((PUINT_8)a)[1], ((PUINT_8)a)[2], ((PUINT_8)a)[3], ((PUINT_8)a)[4], ((PUINT_8)a)[5] */ -+ -+/* The pre-defined format to dump the value of a varaible with its name shown. */ -+#define DUMPVAR(variable, format) (#variable " = " format "\n", variable) -+ -+/* The pre-defined format to dump the MAC type value with its name shown. */ -+#define DUMPMACADDR(addr) (#addr " = %pM\n", (addr)) -+ -+/* Basiclly, we just do renaming of KAL functions although they should -+ * be defined as "Nothing to do" if DBG=0. But in some compiler, the macro -+ * syntax does not support #define LOG_FUNC(x,...) -+ * -+ * A caller shall not invoke these three macros when DBG=0. -+ */ -+ -+/*LOG_FUNC("[wlan]%s:(" #_Module " " #_Class ") "_Fmt, __func__, ##__VA_ARGS__);*/ -+ -+#define LOG_FUNC kalPrint -+ -+#if defined(LINUX) -+#define DBGLOG(_Module, _Class, _Fmt, ...) \ -+ do { \ -+ if ((aucDebugModule[DBG_##_Module##_IDX] & DBG_CLASS_##_Class) == 0) \ -+ break; \ -+ LOG_FUNC("%s:(" #_Module " " #_Class ")"_Fmt, __func__, ##__VA_ARGS__); \ -+ } while (0) -+#else -+#define DBGLOG(_Module, _Class, _Fmt) -+#endif -+ -+#if DBG -+ -+#define TMP_BUF_LEN 256 -+#define TMP_WBUF_LEN (TMP_BUF_LEN * 2) -+ -+extern PINT_16 g_wbuf_p; -+extern PINT_8 g_buf_p; -+ -+ /* If __FUNCTION__ is already defined by compiler, we just use it. */ -+#if defined(__func__) -+#define DEBUGFUNC(_Func) -+#else -+#define DEBUGFUNC(_Func) \ -+ static const char __func__[] = _Func -+#endif -+ -+#define DBGLOG_MEM8(_Module, _Class, _StartAddr, _Length) \ -+ { \ -+ if (aucDebugModule[DBG_##_Module##_IDX] & DBG_CLASS_##_Class) { \ -+ LOG_FUNC("%s: (" #_Module " " #_Class ")\n", __func__); \ -+ dumpMemory8((PUINT_8) (_StartAddr), (UINT_32) (_Length)); \ -+ } \ -+ } -+ -+#define DBGLOG_MEM32(_Module, _Class, _StartAddr, _Length) \ -+ { \ -+ if (aucDebugModule[DBG_##_Module##_IDX] & DBG_CLASS_##_Class) { \ -+ LOG_FUNC("%s: (" #_Module " " #_Class ")\n", __func__); \ -+ dumpMemory32((PUINT_32) (_StartAddr), (UINT_32) (_Length)); \ -+ } \ -+ } -+ /*lint -restore */ -+ -+ /*lint -save -e961 use of '#undef' is discouraged */ -+#undef ASSERT -+ /*lint -restore */ -+ -+#ifdef _lint -+#define ASSERT(_exp) \ -+ { \ -+ if (!(_exp)) { \ -+ do {} while (1); \ -+ } \ -+ } -+#else -+#define ASSERT(_exp) \ -+ { \ -+ if (!(_exp) && !fgIsBusAccessFailed) { \ -+ LOG_FUNC("Assertion failed: %s:%d %s\n", __FILE__, __LINE__, #_exp); \ -+ kalBreakPoint(); \ -+ } \ -+ } -+#endif /* _lint */ -+ -+#define ASSERT_REPORT(_exp, _fmt) \ -+ { \ -+ if (!(_exp) && !fgIsBusAccessFailed) { \ -+ LOG_FUNC("Assertion failed: %s:%d %s\n", __FILE__, __LINE__, #_exp); \ -+ LOG_FUNC _fmt; \ -+ kalBreakPoint(); \ -+ } \ -+ } -+ -+#define DISP_STRING(_str) _str -+ -+#else /* !DBG */ -+ -+#define DEBUGFUNC(_Func) -+#define INITLOG(_Fmt) -+#define ERRORLOG(_Fmt) -+#define WARNLOG(_Fmt) -+ -+#define DBGLOG_MEM8(_Module, _Class, _StartAddr, _Length) -+#define DBGLOG_MEM32(_Module, _Class, _StartAddr, _Length) -+ -+#undef ASSERT -+ -+#if BUILD_QA_DBG -+#if defined(LINUX) /* For debugging in Linux w/o GDB */ -+#define ASSERT(_exp) \ -+ { \ -+ if (!(_exp) && !fgIsBusAccessFailed) { \ -+ LOG_FUNC("Assertion failed: %s:%d (%s)\n", __FILE__, __LINE__, #_exp); \ -+ kalBreakPoint(); \ -+ } \ -+ } -+ -+#define ASSERT_REPORT(_exp, _fmt) \ -+ { \ -+ if (!(_exp) && !fgIsBusAccessFailed) { \ -+ LOG_FUNC("Assertion failed: %s:%d (%s)\n", __FILE__, __LINE__, #_exp); \ -+ LOG_FUNC _fmt; \ -+ kalBreakPoint(); \ -+ } \ -+ } -+#else -+#ifdef WINDOWS_CE -+#define UNICODE_TEXT(_msg) TEXT(_msg) -+#define ASSERT(_exp) \ -+ { \ -+ if (!(_exp) && !fgIsBusAccessFailed) { \ -+ TCHAR rUbuf[256]; \ -+ kalBreakPoint(); \ -+ _stprintf(rUbuf, TEXT("Assertion failed: %s:%d %s\n"), \ -+ UNICODE_TEXT(__FILE__), \ -+ __LINE__, \ -+ UNICODE_TEXT(#_exp)); \ -+ MessageBox(NULL, rUbuf, TEXT("ASSERT!"), MB_OK); \ -+ } \ -+ } -+ -+#define ASSERT_REPORT(_exp, _fmt) \ -+ { \ -+ if (!(_exp) && !fgIsBusAccessFailed) { \ -+ TCHAR rUbuf[256]; \ -+ kalBreakPoint(); \ -+ _stprintf(rUbuf, TEXT("Assertion failed: %s:%d %s\n"), \ -+ UNICODE_TEXT(__FILE__), \ -+ __LINE__, \ -+ UNICODE_TEXT(#_exp)); \ -+ MessageBox(NULL, rUbuf, TEXT("ASSERT!"), MB_OK); \ -+ } \ -+ } -+#else -+#define ASSERT(_exp) \ -+ { \ -+ if (!(_exp) && !fgIsBusAccessFailed) { \ -+ kalBreakPoint(); \ -+ } \ -+ } -+ -+#define ASSERT_REPORT(_exp, _fmt) \ -+ { \ -+ if (!(_exp) && !fgIsBusAccessFailed) { \ -+ kalBreakPoint(); \ -+ } \ -+ } -+#endif /* WINDOWS_CE */ -+#endif /* LINUX */ -+#else -+#define ASSERT(_exp) \ -+ { \ -+ if (!(_exp) && !fgIsBusAccessFailed) { \ -+ LOG_FUNC("Warning at %s:%d (%s)\n", __func__, __LINE__, #_exp); \ -+ } \ -+ } -+ -+#define ASSERT_REPORT(_exp, _fmt) \ -+ { \ -+ if (!(_exp) && !fgIsBusAccessFailed) { \ -+ LOG_FUNC("Warning at %s:%d (%s)\n", __func__, __LINE__, #_exp); \ -+ LOG_FUNC _fmt; \ -+ } \ -+ } -+#endif /* BUILD_QA_DBG */ -+ -+#define DISP_STRING(_str) "" -+ -+#endif /* DBG */ -+ -+#if CFG_STARTUP_DEBUG -+#if defined(LINUX) -+#define DBGPRINTF kalPrint -+#else -+#define DBGPRINTF DbgPrint -+#endif -+#else -+#define DBGPRINTF(...) -+#endif -+ -+/* The following macro is used for debugging packed structures. */ -+#ifndef DATA_STRUCT_INSPECTING_ASSERT -+#define DATA_STRUCT_INSPECTING_ASSERT(expr) \ -+{ \ -+ switch (0) {case 0: case (expr): default:; } \ -+} -+#endif -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+VOID dumpMemory8(IN PUINT_8 pucStartAddr, IN UINT_32 u4Length); -+ -+VOID dumpMemory32(IN PUINT_32 pu4StartAddr, IN UINT_32 u4Length); -+ -+VOID wlanDebugInit(VOID); -+VOID wlanDebugUninit(VOID); -+VOID wlanTraceReleaseTcRes(P_ADAPTER_T prAdapter, PUINT_8 aucTxRlsCnt, UINT_8 ucAvailable); -+VOID wlanTraceTxCmd(P_CMD_INFO_T prCmd); -+VOID wlanDumpTcResAndTxedCmd(PUINT_8 pucBuf, UINT_32 maxLen); -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+#endif /* _DEBUG_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/link.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/link.h -new file mode 100644 -index 000000000000..108860c80e2d ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/link.h -@@ -0,0 +1,368 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/link.h#1 -+*/ -+ -+/*! \file link.h -+ \brief Definition for simple doubly linked list operations. -+ -+ In this file we define the simple doubly linked list data structure and its -+ operation MACROs and INLINE functions. -+*/ -+ -+/* -+** Log: link.h -+ * -+ * 08 05 2010 yuche.tsai -+ * NULL -+ * Modify a MACRO of LINK_FOR_EACH_SAFE for compile error. -+ * -+ * 07 19 2010 cm.chang -+ * -+ * Set RLM parameters and enable CNM channel manager -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 07 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * [WPD00003833] [MT6620 and MT5931] Driver migration -+ * . -+ * -+ * -+ * -+ * -+ * May 4 2009 mtk01084 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * add WIFI to BORA source control -+** \main\maintrunk.MT5921\8 2008-10-16 15:57:11 GMT mtk01461 -+** Update driver to fix lint warning -+** \main\maintrunk.MT5921\7 2008-08-10 18:47:53 GMT mtk01461 -+** Update for Driver Review -+** \main\maintrunk.MT5921\6 2007-12-11 00:09:00 GMT mtk01461 -+** Add macro for checking valid list -+** \main\maintrunk.MT5921\5 2007-11-13 14:27:01 GMT mtk01461 -+** Add LINK_IS_INVALID macro -+** Revision 1.1.1.1 2007/06/22 08:09:05 MTK01461 -+** no message -+** -+*/ -+ -+#ifndef _LINK_H -+#define _LINK_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "gl_typedef.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+/* May cause page fault & unalignment issue (data abort) */ -+#define INVALID_LINK_POISON1 ((VOID *) 0x00100101) -+/* Used to verify that nonbody uses non-initialized link entries. */ -+#define INVALID_LINK_POISON2 ((VOID *) 0x00100201) -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+/* Simple Doubly Linked List Structures - Entry Part */ -+typedef struct _LINK_ENTRY_T { -+ struct _LINK_ENTRY_T *prNext, *prPrev; -+} LINK_ENTRY_T, *P_LINK_ENTRY_T; -+ -+/* Simple Doubly Linked List Structures - List Part */ -+typedef struct _LINK_T { -+ P_LINK_ENTRY_T prNext; -+ P_LINK_ENTRY_T prPrev; -+ UINT_32 u4NumElem; -+} LINK_T, *P_LINK_T; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+#if 0 /* No one use it, temporarily mark it for [Lint - Info 773] */ -+#define LINK_ADDR(rLink) { (P_LINK_ENTRY_T)(&(rLink)), (P_LINK_ENTRY_T)(&(rLink)), 0 } -+ -+#define LINK_DECLARATION(rLink) \ -+ struct _LINK_T rLink = LINK_ADDR(rLink) -+#endif -+ -+#define LINK_INITIALIZE(prLink) \ -+ do { \ -+ ((P_LINK_T)(prLink))->prNext = (P_LINK_ENTRY_T)(prLink); \ -+ ((P_LINK_T)(prLink))->prPrev = (P_LINK_ENTRY_T)(prLink); \ -+ ((P_LINK_T)(prLink))->u4NumElem = 0; \ -+ } while (0) -+ -+#define LINK_ENTRY_INITIALIZE(prEntry) \ -+ do { \ -+ ((P_LINK_ENTRY_T)(prEntry))->prNext = (P_LINK_ENTRY_T)NULL; \ -+ ((P_LINK_ENTRY_T)(prEntry))->prPrev = (P_LINK_ENTRY_T)NULL; \ -+ } while (0) -+ -+#define LINK_ENTRY_INVALID(prEntry) \ -+ do { \ -+ ((P_LINK_ENTRY_T)(prEntry))->prNext = (P_LINK_ENTRY_T)INVALID_LINK_POISON1; \ -+ ((P_LINK_ENTRY_T)(prEntry))->prPrev = (P_LINK_ENTRY_T)INVALID_LINK_POISON2; \ -+ } while (0) -+ -+#define LINK_IS_EMPTY(prLink) (((P_LINK_T)(prLink))->prNext == (P_LINK_ENTRY_T)(prLink)) -+ -+/* NOTE: We should do memory zero before any LINK been initiated, so we can check -+ * if it is valid before parsing the LINK. -+ */ -+#define LINK_IS_INVALID(prLink) (((P_LINK_T)(prLink))->prNext == (P_LINK_ENTRY_T)NULL) -+ -+#define LINK_IS_VALID(prLink) (((P_LINK_T)(prLink))->prNext != (P_LINK_ENTRY_T)NULL) -+ -+#define LINK_ENTRY(ptr, type, member) ENTRY_OF(ptr, type, member) -+ -+/* Insert an entry into a link list's head */ -+#define LINK_INSERT_HEAD(prLink, prEntry) \ -+ { \ -+ linkAdd(prEntry, prLink); \ -+ ((prLink)->u4NumElem)++; \ -+ } -+ -+/* Append an entry into a link list's tail */ -+#define LINK_INSERT_TAIL(prLink, prEntry) \ -+ { \ -+ linkAddTail(prEntry, prLink); \ -+ ((prLink)->u4NumElem)++; \ -+ } -+ -+/* Peek head entry, but keep still in link list */ -+#define LINK_PEEK_HEAD(prLink, _type, _member) \ -+ ( \ -+ LINK_IS_EMPTY(prLink) ? \ -+ NULL : LINK_ENTRY((prLink)->prNext, _type, _member) \ -+ ) -+ -+/* Peek tail entry, but keep still in link list */ -+#define LINK_PEEK_TAIL(prLink, _type, _member) \ -+ ( \ -+ LINK_IS_EMPTY(prLink) ? \ -+ NULL : LINK_ENTRY((prLink)->prPrev, _type, _member) \ -+ ) -+ -+/* Get first entry from a link list */ -+/* NOTE: We assume the link entry located at the beginning of "prEntry Type", -+ * so that we can cast the link entry to other data type without doubts. -+ * And this macro also decrease the total entry count at the same time. -+ */ -+#define LINK_REMOVE_HEAD(prLink, prEntry, _P_TYPE) \ -+ { \ -+ ASSERT(prLink); \ -+ if (LINK_IS_EMPTY(prLink)) { \ -+ prEntry = (_P_TYPE)NULL; \ -+ } \ -+ else { \ -+ prEntry = (_P_TYPE)(((P_LINK_T)(prLink))->prNext); \ -+ linkDel((P_LINK_ENTRY_T)prEntry); \ -+ ((prLink)->u4NumElem)--; \ -+ } \ -+ } -+ -+/* Assume the link entry located at the beginning of prEntry Type. -+ * And also decrease the total entry count. -+ */ -+#define LINK_REMOVE_KNOWN_ENTRY(prLink, prEntry) \ -+ { \ -+ ASSERT(prLink); \ -+ ASSERT(prEntry); \ -+ linkDel((P_LINK_ENTRY_T)prEntry); \ -+ ((prLink)->u4NumElem)--; \ -+ } -+ -+/* Iterate over a link list */ -+#define LINK_FOR_EACH(prEntry, prLink) \ -+ for (prEntry = (prLink)->prNext; \ -+ prEntry != (P_LINK_ENTRY_T)(prLink); \ -+ prEntry = (P_LINK_ENTRY_T)prEntry->prNext) -+ -+/* Iterate over a link list backwards */ -+#define LINK_FOR_EACH_PREV(prEntry, prLink) \ -+ for (prEntry = (prLink)->prPrev; \ -+ prEntry != (P_LINK_ENTRY_T)(prLink); \ -+ prEntry = (P_LINK_ENTRY_T)prEntry->prPrev) -+ -+/* Iterate over a link list safe against removal of link entry */ -+#define LINK_FOR_EACH_SAFE(prEntry, prNextEntry, prLink) \ -+ for (prEntry = (prLink)->prNext, prNextEntry = prEntry->prNext; \ -+ prEntry != (P_LINK_ENTRY_T)(prLink); \ -+ prEntry = prNextEntry, prNextEntry = prEntry->prNext) -+ -+/* Iterate over a link list of given type */ -+#define LINK_FOR_EACH_ENTRY(prObj, prLink, rMember, _TYPE) \ -+ for (prObj = LINK_ENTRY((prLink)->prNext, _TYPE, rMember); \ -+ &prObj->rMember != (P_LINK_ENTRY_T)(prLink); \ -+ prObj = LINK_ENTRY(prObj->rMember.prNext, _TYPE, rMember)) -+ -+/* Iterate backwards over a link list of given type */ -+#define LINK_FOR_EACH_ENTRY_PREV(prObj, prLink, rMember, _TYPE) \ -+ for (prObj = LINK_ENTRY((prLink)->prPrev, _TYPE, rMember); \ -+ &prObj->rMember != (P_LINK_ENTRY_T)(prLink); \ -+ prObj = LINK_ENTRY(prObj->rMember.prPrev, _TYPE, rMember)) -+ -+/* Iterate over a link list of given type safe against removal of link entry */ -+#define LINK_FOR_EACH_ENTRY_SAFE(prObj, prNextObj, prLink, rMember, _TYPE) \ -+ for (prObj = LINK_ENTRY((prLink)->prNext, _TYPE, rMember), \ -+ prNextObj = LINK_ENTRY(prObj->rMember.prNext, _TYPE, rMember); \ -+ &prObj->rMember != (P_LINK_ENTRY_T)(prLink); \ -+ prObj = prNextObj, \ -+ prNextObj = LINK_ENTRY(prNextObj->rMember.prNext, _TYPE, rMember)) -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is only for internal link list manipulation. -+* -+* \param[in] prNew Pointer of new link head -+* \param[in] prPrev Pointer of previous link head -+* \param[in] prNext Pointer of next link head -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+static inline VOID __linkAdd(IN P_LINK_ENTRY_T prNew, IN P_LINK_ENTRY_T prPrev, IN P_LINK_ENTRY_T prNext) -+{ -+ prNext->prPrev = prNew; -+ prNew->prNext = prNext; -+ prNew->prPrev = prPrev; -+ prPrev->prNext = prNew; -+ -+} /* end of __linkAdd() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will add a new entry after the specified link head. -+* -+* \param[in] prNew New entry to be added -+* \param[in] prHead Specified link head to add it after -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+static inline VOID linkAdd(IN P_LINK_ENTRY_T prNew, IN P_LINK_T prLink) -+{ -+ __linkAdd(prNew, (P_LINK_ENTRY_T) prLink, prLink->prNext); -+ -+} /* end of linkAdd() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will add a new entry before the specified link head. -+* -+* \param[in] prNew New entry to be added -+* \param[in] prHead Specified link head to add it before -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+static inline VOID linkAddTail(IN P_LINK_ENTRY_T prNew, IN P_LINK_T prLink) -+{ -+ __linkAdd(prNew, prLink->prPrev, (P_LINK_ENTRY_T) prLink); -+ -+} /* end of linkAddTail() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is only for internal link list manipulation. -+* -+* \param[in] prPrev Pointer of previous link head -+* \param[in] prNext Pointer of next link head -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+static inline VOID __linkDel(IN P_LINK_ENTRY_T prPrev, IN P_LINK_ENTRY_T prNext) -+{ -+ prNext->prPrev = prPrev; -+ prPrev->prNext = prNext; -+ -+} /* end of __linkDel() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will delete a specified entry from link list. -+* NOTE: the entry is in an initial state. -+* -+* \param prEntry Specified link head(entry) -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+static inline VOID linkDel(IN P_LINK_ENTRY_T prEntry) -+{ -+ __linkDel(prEntry->prPrev, prEntry->prNext); -+ -+ LINK_ENTRY_INITIALIZE(prEntry); -+ -+} /* end of linkDel() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will delete a specified entry from link list and then add it -+* after the specified link head. -+* -+* \param[in] prEntry Specified link head(entry) -+* \param[in] prOtherHead Another link head to add it after -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+static inline VOID linkMove(IN P_LINK_ENTRY_T prEntry, IN P_LINK_T prLink) -+{ -+ __linkDel(prEntry->prPrev, prEntry->prNext); -+ linkAdd(prEntry, prLink); -+ -+} /* end of linkMove() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will delete a specified entry from link list and then add it -+* before the specified link head. -+* -+* \param[in] prEntry Specified link head(entry) -+* \param[in] prOtherHead Another link head to add it before -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+static inline VOID linkMoveTail(IN P_LINK_ENTRY_T prEntry, IN P_LINK_T prLink) -+{ -+ __linkDel(prEntry->prPrev, prEntry->prNext); -+ linkAddTail(prEntry, prLink); -+ -+} /* end of linkMoveTail() */ -+ -+#endif /* _LINK_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/aa_fsm.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/aa_fsm.h -new file mode 100644 -index 000000000000..fd83c79ffe10 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/aa_fsm.h -@@ -0,0 +1,188 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/mgmt/aa_fsm.h#1 -+*/ -+ -+/*! \file aa_fsm.h -+ \brief Declaration of functions and finite state machine for SAA/AAA Module. -+ -+ Declaration of functions and finite state machine for SAA/AAA Module. -+*/ -+ -+/* -+** Log: aa_fsm.h -+ * -+ * 10 13 2011 cp.wu -+ * [MT6620 Wi-Fi][Driver] Reduce join failure count limit to 2 for faster re-join for other BSS -+ * 1. short join failure count limit to 2 -+ * 2. treat join timeout as kind of join failure as well -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 21 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * refine TX-DONE callback. -+ * -+ * 06 11 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) migrate assoc.c. -+ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness -+ * 3) add configuration options for CNM_MEM and RSN modules -+ * 4) add data path for management frames -+ * 5) eliminate rPacketInfo of MSDU_INFO_T -+ * -+ * 06 10 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add buildable & linkable ais_fsm.c -+ * -+ * related reference are still waiting to be resolved -+ * -+ * 06 07 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add aa_fsm.h, ais_fsm.h, bss.h, mib.h and scan.h. -+ * -+ * 03 10 2010 kevin.huang -+ * [BORA00000654][WIFISYS][New Feature] CNM Module - Ch Manager Support -+ * -+ * Add Channel Manager for arbitration of JOIN and SCAN Req -+ * -+ * 02 04 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Add AAA Module Support, Revise Net Type to Net Type Index for array lookup -+ * -+ * 01 11 2010 kevin.huang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Add Deauth and Disassoc Handler -+ * -+ * Nov 24 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Revise MGMT Handler with Retain Status -+ * -+ * Nov 23 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * -+*/ -+ -+#ifndef _AA_FSM_H -+#define _AA_FSM_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+/* Retry interval for retransmiting authentication-request MMPDU. */ -+#define TX_AUTHENTICATION_RETRY_TIMEOUT_TU 100 /* TU. */ -+ -+/* Retry interval for retransmiting association-request MMPDU. */ -+#define TX_ASSOCIATION_RETRY_TIMEOUT_TU 100 /* TU. */ -+ -+/* Wait for a response to a transmitted authentication-request MMPDU. */ -+#define DOT11_AUTHENTICATION_RESPONSE_TIMEOUT_TU 512 /* TU. */ -+ -+/* Wait for a response to a transmitted association-request MMPDU. */ -+#define DOT11_ASSOCIATION_RESPONSE_TIMEOUT_TU 512 /* TU. */ -+ -+/* The maximum time to wait for JOIN process complete. */ -+#define JOIN_FAILURE_TIMEOUT_BEACON_INTERVAL 20 /* Beacon Interval, 20 * 100TU = 2 sec. */ -+ -+/* Retry interval for next JOIN request. */ -+#define JOIN_RETRY_INTERVAL_SEC 10 /* Seconds */ -+ -+/* Maximum Retry Count for accept a JOIN request. */ -+#define JOIN_MAX_RETRY_FAILURE_COUNT 2 /* Times */ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+typedef enum _ENUM_AA_STATE_T { -+ AA_STATE_IDLE = 0, -+ SAA_STATE_SEND_AUTH1, -+ SAA_STATE_WAIT_AUTH2, -+ SAA_STATE_SEND_AUTH3, -+ SAA_STATE_WAIT_AUTH4, -+ SAA_STATE_SEND_ASSOC1, -+ SAA_STATE_WAIT_ASSOC2, -+ AAA_STATE_SEND_AUTH2, -+ AAA_STATE_SEND_AUTH4, /* We may not use, because P2P GO didn't support WEP and 11r */ -+ AAA_STATE_SEND_ASSOC2, -+ AA_STATE_RESOURCE, /* A state for debugging the case of out of msg buffer. */ -+ AA_STATE_NUM -+} ENUM_AA_STATE_T; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+/*----------------------------------------------------------------------------*/ -+/* Routines in saa_fsm.c */ -+/*----------------------------------------------------------------------------*/ -+VOID -+saaFsmSteps(IN P_ADAPTER_T prAdapter, -+ IN P_STA_RECORD_T prStaRec, IN ENUM_AA_STATE_T eNextState, IN P_SW_RFB_T prRetainedSwRfb); -+ -+WLAN_STATUS -+saaFsmSendEventJoinComplete(IN P_ADAPTER_T prAdapter, -+ WLAN_STATUS rJoinStatus, P_STA_RECORD_T prStaRec, P_SW_RFB_T prSwRfb); -+ -+VOID saaFsmRunEventStart(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); -+ -+WLAN_STATUS -+saaFsmRunEventTxDone(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus); -+ -+VOID saaFsmRunEventTxReqTimeOut(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec); -+ -+VOID saaFsmRunEventRxRespTimeOut(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec); -+ -+VOID saaFsmRunEventRxAuth(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); -+ -+WLAN_STATUS saaFsmRunEventRxAssoc(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); -+ -+WLAN_STATUS saaFsmRunEventRxDeauth(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); -+ -+WLAN_STATUS saaFsmRunEventRxDisassoc(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); -+ -+VOID saaFsmRunEventAbort(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); -+ -+/*----------------------------------------------------------------------------*/ -+/* Routines in aaa_fsm.c */ -+/*----------------------------------------------------------------------------*/ -+VOID aaaFsmRunEventRxAuth(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); -+ -+WLAN_STATUS aaaFsmRunEventRxAssoc(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); -+ -+WLAN_STATUS -+aaaFsmRunEventTxDone(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus); -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif /* _AA_FSM_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/ais_fsm.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/ais_fsm.h -new file mode 100644 -index 000000000000..b771bdacf2c6 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/ais_fsm.h -@@ -0,0 +1,573 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/mgmt/ais_fsm.h#1 -+*/ -+ -+/*! \file ais_fsm.h -+ \brief Declaration of functions and finite state machine for AIS Module. -+ -+ Declaration of functions and finite state machine for AIS Module. -+*/ -+ -+/* -+** Log: ais_fsm.h -+ * -+ * 11 22 2011 cp.wu -+ * [WCXRP00001120] [MT6620 Wi-Fi][Driver] Modify roaming to AIS state transition -+ * from synchronous to asynchronous approach to avoid incomplete state termination -+ * 1. change RDD related compile option brace position. -+ * 2. when roaming is triggered, ask AIS to transit immediately only when AIS -+ * is in Normal TR state without join timeout timer ticking -+ * 3. otherwise, insert AIS_REQUEST into pending request queue -+ * -+ * 04 25 2011 cp.wu -+ * [WCXRP00000676] [MT6620 Wi-Fi][Driver] AIS to reduce request channel period from 5 seconds to 2 seconds -+ * channel interval for joining is shortened to 2 seconds to avoid interruption of concurrent operating network. -+ * -+ * 02 26 2011 tsaiyuan.hsu -+ * [WCXRP00000391] [MT6620 Wi-Fi][FW] Add Roaming Support -+ * not send disassoc or deauth to leaving AP so as to improve performace of roaming. -+ * -+ * 02 22 2011 cp.wu -+ * [WCXRP00000487] [MT6620 Wi-Fi][Driver][AIS] Serve scan and connect request with -+ * a queue-based approach to improve response time for scanning request -+ * handle SCAN and RECONNECT with a FIFO approach. -+ * -+ * 01 27 2011 tsaiyuan.hsu -+ * [WCXRP00000392] [MT6620 Wi-Fi][Driver] Add Roaming Support -+ * add roaming fsm -+ * 1. not support 11r, only use strength of signal to determine roaming. -+ * 2. not enable CFG_SUPPORT_ROAMING until completion of full test. -+ * 3. in 6620, adopt work-around to avoid sign extension problem of cck of hw -+ * 4. assume that change of link quality in smooth way. -+ * -+ * 01 14 2011 cp.wu -+ * [WCXRP00000359] [MT6620 Wi-Fi][Driver] add an extra state to ensure DEAUTH frame is always sent -+ * Add an extra state to guarantee DEAUTH frame is sent then connect to new BSS. -+ * This change is due to WAPI AP needs DEAUTH frame as a necessary step in handshaking protocol. -+ * -+ * 11 25 2010 cp.wu -+ * [WCXRP00000208] [MT6620 Wi-Fi][Driver] Add scanning with specified SSID to AIS FSM -+ * add scanning with specified SSID facility to AIS-FSM -+ * -+ * 11 01 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check -+ * [WCXRP00000150] [MT6620 Wi-Fi][Driver] Add implementation for querying current TX rate from firmware auto rate module -+ * 1) Query link speed (TX rate) from firmware directly with buffering mechanism to reduce overhead -+ * 2) Remove CNM CH-RECOVER event handling -+ * 3) cfg read/write API renamed with kal prefix for unified naming rules. -+ * -+ * 09 06 2010 cp.wu -+ * NULL -+ * 1) initialize for correct parameter even for disassociation. -+ * 2) AIS-FSM should have a limit on trials to build connection -+ * -+ * 09 03 2010 kevin.huang -+ * NULL -+ * Refine #include sequence and solve recursive/nested #include issue -+ * -+ * 08 25 2010 cp.wu -+ * NULL -+ * [AIS-FSM] IBSS no longer needs to acquire channel for beaconing, RLM/CNM will handle -+ * the channel switching when BSS information is updated -+ * -+ * 08 12 2010 kevin.huang -+ * NULL -+ * Refine bssProcessProbeRequest() and bssSendBeaconProbeResponse() -+ * -+ * 08 12 2010 cp.wu -+ * NULL -+ * [AIS-FSM] honor registry setting for adhoc running mode. (A/B/G) -+ * -+ * 08 03 2010 cp.wu -+ * NULL -+ * surpress compilation warning. -+ * -+ * 07 30 2010 cp.wu -+ * NULL -+ * 1) BoW wrapper: use definitions instead of hard-coded constant for error code -+ * 2) AIS-FSM: eliminate use of desired RF parameters, use prTargetBssDesc instead -+ * 3) add handling for RX_PKT_DESTINATION_HOST_WITH_FORWARD for GO-broadcast frames -+ * -+ * 07 26 2010 cp.wu -+ * -+ * AIS-FSM: when scan request is coming in the 1st 5 seconds of channel privilege period, -+ * just pend it til 5-sec. period finishes -+ * -+ * 07 26 2010 cp.wu -+ * -+ * AIS-FSM FIX: return channel privilege even when the privilege is not granted yet -+ * QM: qmGetFrameAction() won't assert when corresponding STA-REC index is not found -+ * -+ * 07 23 2010 cp.wu -+ * -+ * add AIS-FSM handling for beacon timeout event. -+ * -+ * 07 21 2010 cp.wu -+ * -+ * separate AIS-FSM states into different cases of channel request. -+ * -+ * 07 21 2010 cp.wu -+ * -+ * 1) change BG_SCAN to ONLINE_SCAN for consistent term -+ * 2) only clear scanning result when scan is permitted to do -+ * -+ * 07 19 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration. -+ * Add Ad-Hoc support to AIS-FSM -+ * -+ * 07 14 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration. -+ * Refine AIS-FSM by divided into more states -+ * -+ * 07 09 2010 cp.wu -+ * -+ * 1) separate AIS_FSM state for two kinds of scanning. (OID triggered scan, and scan-for-connection) -+ * 2) eliminate PRE_BSS_DESC_T, Beacon/PrebResp is now parsed in single pass -+ * 3) implment DRV-SCN module, currently only accepts single scan request, -+ * other request will be directly dropped by returning BUSY -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 07 01 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * AIS-FSM integration with CNM channel request messages -+ * -+ * 07 01 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * implementation of DRV-SCN and related mailbox message handling. -+ * -+ * 06 10 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add buildable & linkable ais_fsm.c -+ * -+ * related reference are still waiting to be resolved -+ * -+ * 06 09 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add definitions for module migration. -+ * -+ * 06 07 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add aa_fsm.h, ais_fsm.h, bss.h, mib.h and scan.h. -+ * -+ * 05 12 2010 kevin.huang -+ * [BORA00000794][WIFISYS][New Feature]Power Management Support -+ * Add Power Management - Legacy PS-POLL support. -+ * -+ * 04 23 2010 wh.su -+ * [BORA00000605][WIFISYS] Phase3 Integration -+ * reduce the background ssid idle time min and max value -+ * -+ * 04 19 2010 kevin.huang -+ * [BORA00000714][WIFISYS][New Feature]Beacon Timeout Support -+ * Add Beacon Timeout Support -+ * * and will send Null frame to diagnose connection -+ * -+ * 03 16 2010 kevin.huang -+ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support -+ * Add AdHoc Mode -+ * -+ * 03 10 2010 kevin.huang -+ * [BORA00000654][WIFISYS][New Feature] CNM Module - Ch Manager Support -+ * -+ * * Add Channel Manager for arbitration of JOIN and SCAN Req -+ * -+ * 02 26 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Remove CFG_TEST_VIRTUAL_CMD and add support of Driver STA_RECORD_T activation -+ * -+ * 02 23 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Support dynamic channel selection -+ * -+ * 02 04 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Add AAA Module Support, Revise Net Type to Net Type Index for array lookup -+ * -+ * 01 11 2010 kevin.huang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Add Deauth and Disassoc Handler -+ * -+ * 01 07 2010 kevin.huang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Add Media disconnect indication and related postpone functions -+ * -+ * Dec 3 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Add aisFsmRunEventJoinComplete() -+ * -+ * Nov 25 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Add Virtual CMD & RESP for testing CMD PATH -+ * -+ * Nov 23 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * add aisFsmInitializeConnectionSettings() -+ * -+ * Nov 20 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Add CFG_TEST_MGMT_FSM for aisFsmTest() -+ * -+ * Nov 18 2009 mtk01104 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Add function prototype of aisFsmInit() -+ * -+ * Nov 16 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * -+*/ -+ -+#ifndef _AIS_FSM_H -+#define _AIS_FSM_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+#define AIS_BG_SCAN_INTERVAL_MIN_SEC 2 /* 30 // exponential to 960 */ -+#define AIS_BG_SCAN_INTERVAL_MAX_SEC 2 /* 960 // 16min */ -+ -+#define AIS_DELAY_TIME_OF_DISC_SEC_ONLY_2G4 2 /* 2.4G scan need about 0.5s, so delay 2s to reconnect is enough */ -+#define AIS_DELAY_TIME_OF_DISC_SEC_DUALBAND 5 /* 2.4G scan need about 3.3s, so delay 5s to reconnect is enough */ -+ -+#define AIS_IBSS_ALONE_TIMEOUT_SEC 20 /* seconds */ -+ -+#define AIS_BEACON_TIMEOUT_COUNT_ADHOC 30 -+#define AIS_BEACON_TIMEOUT_COUNT_INFRA 10 -+#define AIS_BEACON_TIMEOUT_GUARD_TIME_SEC 1 /* Second */ -+ -+#define AIS_BEACON_MAX_TIMEOUT_TU 100 -+#define AIS_BEACON_MIN_TIMEOUT_TU 5 -+#define AIS_BEACON_MAX_TIMEOUT_VALID TRUE -+#define AIS_BEACON_MIN_TIMEOUT_VALID TRUE -+ -+#define AIS_BMC_MAX_TIMEOUT_TU 100 -+#define AIS_BMC_MIN_TIMEOUT_TU 5 -+#define AIS_BMC_MAX_TIMEOUT_VALID TRUE -+#define AIS_BMC_MIN_TIMEOUT_VALID TRUE -+ -+#define AIS_JOIN_CH_GRANT_THRESHOLD 10 -+#define AIS_JOIN_CH_REQUEST_INTERVAL 3000 -+ -+#define AIS_SCN_DONE_TIMEOUT_SEC 30 /* 15 for 2.4G + 5G */ /* 5 */ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+typedef enum _ENUM_AIS_STATE_T { -+ AIS_STATE_IDLE = 0, -+ AIS_STATE_SEARCH, -+ AIS_STATE_SCAN, -+ AIS_STATE_ONLINE_SCAN, -+ AIS_STATE_LOOKING_FOR, -+ AIS_STATE_WAIT_FOR_NEXT_SCAN, -+ AIS_STATE_REQ_CHANNEL_JOIN, -+ AIS_STATE_JOIN, -+ AIS_STATE_IBSS_ALONE, -+ AIS_STATE_IBSS_MERGE, -+ AIS_STATE_NORMAL_TR, -+ AIS_STATE_DISCONNECTING, -+ AIS_STATE_REQ_REMAIN_ON_CHANNEL, -+ AIS_STATE_REMAIN_ON_CHANNEL, -+ AIS_STATE_NUM -+} ENUM_AIS_STATE_T; -+ -+typedef struct _MSG_AIS_ABORT_T { -+ MSG_HDR_T rMsgHdr; /* Must be the first member */ -+ UINT_8 ucReasonOfDisconnect; -+ BOOLEAN fgDelayIndication; -+} MSG_AIS_ABORT_T, *P_MSG_AIS_ABORT_T; -+ -+typedef struct _MSG_AIS_IBSS_PEER_FOUND_T { -+ MSG_HDR_T rMsgHdr; /* Must be the first member */ -+ UINT_8 ucNetTypeIndex; -+ BOOLEAN fgIsMergeIn; /* TRUE: Merge In, FALSE: Merge Out */ -+ P_STA_RECORD_T prStaRec; -+} MSG_AIS_IBSS_PEER_FOUND_T, *P_MSG_AIS_IBSS_PEER_FOUND_T; -+ -+typedef enum _ENUM_AIS_REQUEST_TYPE_T { -+ AIS_REQUEST_SCAN, -+ AIS_REQUEST_RECONNECT, -+ AIS_REQUEST_ROAMING_SEARCH, -+ AIS_REQUEST_ROAMING_CONNECT, -+ AIS_REQUEST_REMAIN_ON_CHANNEL, -+ AIS_REQUEST_NUM -+} ENUM_AIS_REQUEST_TYPE_T; -+ -+typedef struct _AIS_REQ_HDR_T { -+ LINK_ENTRY_T rLinkEntry; -+ ENUM_AIS_REQUEST_TYPE_T eReqType; -+} AIS_REQ_HDR_T, *P_AIS_REQ_HDR_T; -+ -+typedef struct _AIS_REQ_CHNL_INFO { -+ ENUM_BAND_T eBand; -+ ENUM_CHNL_EXT_T eSco; -+ UINT_8 ucChannelNum; -+ UINT_32 u4DurationMs; -+ UINT_64 u8Cookie; -+} AIS_REQ_CHNL_INFO, *P_AIS_REQ_CHNL_INFO; -+ -+typedef struct _AIS_MGMT_TX_REQ_INFO_T { -+ BOOLEAN fgIsMgmtTxRequested; -+ P_MSDU_INFO_T prMgmtTxMsdu; -+ UINT_64 u8Cookie; -+} AIS_MGMT_TX_REQ_INFO_T, *P_AIS_MGMT_TX_REQ_INFO_T; -+ -+typedef struct _AIS_FSM_INFO_T { -+ ENUM_AIS_STATE_T ePreviousState; -+ ENUM_AIS_STATE_T eCurrentState; -+ -+ BOOLEAN fgTryScan; -+ -+ BOOLEAN fgIsInfraChannelFinished; -+ BOOLEAN fgIsChannelRequested; -+ BOOLEAN fgIsChannelGranted; -+ -+#if CFG_SUPPORT_ROAMING -+ BOOLEAN fgIsRoamingScanPending; -+#endif /* CFG_SUPPORT_ROAMING */ -+ -+ UINT_8 ucAvailableAuthTypes; /* Used for AUTH_MODE_AUTO_SWITCH */ -+ -+ P_BSS_DESC_T prTargetBssDesc; /* For destination */ -+ -+ P_STA_RECORD_T prTargetStaRec; /* For JOIN Abort */ -+ -+ UINT_32 u4SleepInterval; -+ -+ TIMER_T rBGScanTimer; -+ -+ TIMER_T rIbssAloneTimer; -+ -+ TIMER_T rIndicationOfDisconnectTimer; -+ -+ TIMER_T rJoinTimeoutTimer; -+ -+ TIMER_T rChannelTimeoutTimer; -+ -+ TIMER_T rScanDoneTimer; -+ -+ TIMER_T rDeauthDoneTimer; -+ -+ UINT_8 ucSeqNumOfReqMsg; -+ UINT_8 ucSeqNumOfChReq; -+ UINT_8 ucSeqNumOfScanReq; -+ -+ UINT_32 u4ChGrantedInterval; -+ -+ UINT_8 ucConnTrialCount; -+ -+ UINT_8 ucScanSSIDLen; -+ UINT_8 aucScanSSID[ELEM_MAX_LEN_SSID]; -+ -+ UINT_32 u4ScanIELength; -+ UINT_8 aucScanIEBuf[MAX_IE_LENGTH]; -+ -+ /* Pending Request List */ -+ LINK_T rPendingReqList; -+ -+ /* Join Request Timestamp */ -+ OS_SYSTIME rJoinReqTime; -+ -+ /* for cfg80211 REMAIN_ON_CHANNEL support */ -+ AIS_REQ_CHNL_INFO rChReqInfo; -+ -+ /* Mgmt tx related. */ -+ AIS_MGMT_TX_REQ_INFO_T rMgmtTxInfo; -+ -+ /* Packet filter for AIS module. */ -+ UINT_32 u4AisPacketFilter; -+ -+} AIS_FSM_INFO_T, *P_AIS_FSM_INFO_T; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+#define aisChangeMediaState(_prAdapter, _eNewMediaState) \ -+ (_prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX].eConnectionState = (_eNewMediaState)) -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+VOID aisInitializeConnectionSettings(IN P_ADAPTER_T prAdapter, IN P_REG_INFO_T prRegInfo); -+ -+VOID aisFsmInit(IN P_ADAPTER_T prAdapter); -+ -+VOID aisFsmUninit(IN P_ADAPTER_T prAdapter); -+ -+VOID aisFsmStateInit_JOIN(IN P_ADAPTER_T prAdapter, P_BSS_DESC_T prBssDesc); -+ -+BOOLEAN aisFsmStateInit_RetryJOIN(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec); -+ -+VOID aisFsmStateInit_IBSS_ALONE(IN P_ADAPTER_T prAdapter); -+ -+VOID aisFsmStateInit_IBSS_MERGE(IN P_ADAPTER_T prAdapter, P_BSS_DESC_T prBssDesc); -+ -+VOID aisFsmStateAbort(IN P_ADAPTER_T prAdapter, UINT_8 ucReasonOfDisconnect, BOOLEAN fgDelayIndication); -+ -+VOID aisFsmStateAbort_JOIN(IN P_ADAPTER_T prAdapter); -+ -+VOID aisFsmStateAbort_SCAN(IN P_ADAPTER_T prAdapter); -+ -+VOID aisFsmStateAbort_NORMAL_TR(IN P_ADAPTER_T prAdapter); -+ -+VOID aisFsmStateAbort_IBSS(IN P_ADAPTER_T prAdapter); -+#if 0 -+VOID aisFsmSetChannelInfo(IN P_ADAPTER_T prAdapter, IN P_MSG_SCN_SCAN_REQ ScanReqMsg, IN ENUM_AIS_STATE_T CurrentState); -+#endif -+VOID aisFsmSteps(IN P_ADAPTER_T prAdapter, ENUM_AIS_STATE_T eNextState); -+ -+/*----------------------------------------------------------------------------*/ -+/* Mailbox Message Handling */ -+/*----------------------------------------------------------------------------*/ -+VOID aisFsmRunEventScanDone(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); -+ -+VOID aisFsmRunEventAbort(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); -+ -+VOID aisFsmRunEventJoinComplete(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); -+ -+VOID aisFsmRunEventFoundIBSSPeer(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); -+ -+VOID aisFsmRunEventRemainOnChannel(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); -+ -+VOID aisFsmRunEventCancelRemainOnChannel(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); -+ -+/*----------------------------------------------------------------------------*/ -+/* Handling for Ad-Hoc Network */ -+/*----------------------------------------------------------------------------*/ -+VOID aisFsmCreateIBSS(IN P_ADAPTER_T prAdapter); -+ -+VOID aisFsmMergeIBSS(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec); -+ -+/*----------------------------------------------------------------------------*/ -+/* Handling of Incoming Mailbox Message from CNM */ -+/*----------------------------------------------------------------------------*/ -+VOID aisFsmRunEventChGrant(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); -+ -+/*----------------------------------------------------------------------------*/ -+/* Generating Outgoing Mailbox Message to CNM */ -+/*----------------------------------------------------------------------------*/ -+VOID aisFsmReleaseCh(IN P_ADAPTER_T prAdapter); -+ -+/*----------------------------------------------------------------------------*/ -+/* Event Indication */ -+/*----------------------------------------------------------------------------*/ -+VOID -+aisIndicationOfMediaStateToHost(IN P_ADAPTER_T prAdapter, -+ ENUM_PARAM_MEDIA_STATE_T eConnectionState, BOOLEAN fgDelayIndication); -+ -+VOID aisPostponedEventOfDisconnTimeout(IN P_ADAPTER_T prAdapter, ULONG ulParam); -+ -+VOID aisUpdateBssInfoForJOIN(IN P_ADAPTER_T prAdapter, P_STA_RECORD_T prStaRec, P_SW_RFB_T prAssocRspSwRfb); -+ -+VOID aisUpdateBssInfoForCreateIBSS(IN P_ADAPTER_T prAdapter); -+ -+VOID aisUpdateBssInfoForMergeIBSS(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec); -+ -+BOOLEAN aisValidateProbeReq(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, OUT PUINT_32 pu4ControlFlags); -+ -+WLAN_STATUS -+aisFsmRunEventMgmtFrameTxDone(IN P_ADAPTER_T prAdapter, -+ IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus); -+ -+/*----------------------------------------------------------------------------*/ -+/* Disconnection Handling */ -+/*----------------------------------------------------------------------------*/ -+VOID aisFsmDisconnect(IN P_ADAPTER_T prAdapter, IN BOOLEAN fgDelayIndication); -+ -+/*----------------------------------------------------------------------------*/ -+/* Event Handling */ -+/*----------------------------------------------------------------------------*/ -+VOID aisBssBeaconTimeout(IN P_ADAPTER_T prAdapter); -+ -+VOID aisBssSecurityChanged(IN P_ADAPTER_T prAdapter); -+ -+WLAN_STATUS -+aisDeauthXmitComplete(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus); -+ -+#if CFG_SUPPORT_ROAMING -+VOID aisFsmRunEventRoamingDiscovery(IN P_ADAPTER_T prAdapter, UINT_32 u4ReqScan); -+ -+ENUM_AIS_STATE_T aisFsmRoamingScanResultsUpdate(IN P_ADAPTER_T prAdapter); -+ -+VOID aisFsmRoamingDisconnectPrevAP(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prTargetStaRec); -+ -+VOID aisUpdateBssInfoForRoamingAP(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN P_SW_RFB_T prAssocRspSwRfb); -+#endif /*CFG_SUPPORT_ROAMING */ -+ -+/*----------------------------------------------------------------------------*/ -+/* Timeout Handling */ -+/*----------------------------------------------------------------------------*/ -+VOID aisFsmRunEventBGSleepTimeOut(IN P_ADAPTER_T prAdapter, ULONG ulParam); -+ -+VOID aisFsmRunEventIbssAloneTimeOut(IN P_ADAPTER_T prAdapter, ULONG ulParam); -+ -+VOID aisFsmRunEventJoinTimeout(IN P_ADAPTER_T prAdapter, ULONG ulParam); -+ -+VOID aisFsmRunEventChannelTimeout(IN P_ADAPTER_T prAdapter, ULONG ulParam); -+ -+VOID aisFsmRunEventScanDoneTimeOut(IN P_ADAPTER_T prAdapter, ULONG ulParam); -+ -+VOID aisFsmRunEventDeauthTimeout(IN P_ADAPTER_T prAdapter, ULONG ulParam); -+ -+/*----------------------------------------------------------------------------*/ -+/* OID/IOCTL Handling */ -+/*----------------------------------------------------------------------------*/ -+VOID aisFsmScanRequest(IN P_ADAPTER_T prAdapter, IN P_PARAM_SSID_T prSsid, IN PUINT_8 pucIe, IN UINT_32 u4IeLength); -+ -+/*----------------------------------------------------------------------------*/ -+/* Internal State Checking */ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN aisFsmIsRequestPending(IN P_ADAPTER_T prAdapter, IN ENUM_AIS_REQUEST_TYPE_T eReqType, IN BOOLEAN bRemove); -+ -+P_AIS_REQ_HDR_T aisFsmGetNextRequest(IN P_ADAPTER_T prAdapter); -+ -+BOOLEAN aisFsmInsertRequest(IN P_ADAPTER_T prAdapter, IN ENUM_AIS_REQUEST_TYPE_T eReqType); -+ -+VOID aisFsmFlushRequest(IN P_ADAPTER_T prAdapter); -+ -+WLAN_STATUS -+aisFuncTxMgmtFrame(IN P_ADAPTER_T prAdapter, -+ IN P_AIS_MGMT_TX_REQ_INFO_T prMgmtTxReqInfo, IN P_MSDU_INFO_T prMgmtTxMsdu, IN UINT_64 u8Cookie); -+ -+VOID aisFsmRunEventMgmtFrameTx(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); -+ -+VOID aisFuncValidateRxActionFrame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); -+ -+#if defined(CFG_TEST_MGMT_FSM) && (CFG_TEST_MGMT_FSM != 0) -+VOID aisTest(VOID); -+#endif /* CFG_TEST_MGMT_FSM */ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif /* _AIS_FSM_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/assoc.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/assoc.h -new file mode 100644 -index 000000000000..70b32bca102b ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/assoc.h -@@ -0,0 +1,112 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/mgmt/assoc.h#1 -+*/ -+ -+/*! \file assoc.h -+ \brief This file contains the ASSOC REQ/RESP of -+ IEEE 802.11 family for MediaTek 802.11 Wireless LAN Adapters. -+*/ -+ -+/* -+** Log: assoc.h -+ * -+ * 09 03 2010 kevin.huang -+ * NULL -+ * Refine #include sequence and solve recursive/nested #include issue -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 17 2010 yuche.tsai -+ * [WPD00003839][MT6620 5931][P2P] Feature migration -+ * Add assocCheckTxReAssocRespFrame() proto type for P2P usage. -+ * -+ * 06 11 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) migrate assoc.c. -+ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness -+ * 3) add configuration options for CNM_MEM and RSN modules -+ * 4) add data path for management frames -+ * 5) eliminate rPacketInfo of MSDU_INFO_T -+ * -+ * 06 10 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add buildable & linkable ais_fsm.c -+ * -+ * related reference are still waiting to be resolved -+ * -+*/ -+ -+#ifndef _ASSOC_H -+#define _ASSOC_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+/*----------------------------------------------------------------------------*/ -+/* Routines in assoc.c */ -+/*----------------------------------------------------------------------------*/ -+UINT_16 assocBuildCapabilityInfo(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec); -+ -+WLAN_STATUS assocSendReAssocReqFrame(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec); -+ -+WLAN_STATUS assocCheckTxReAssocReqFrame(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); -+ -+WLAN_STATUS assocCheckTxReAssocRespFrame(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); -+ -+WLAN_STATUS -+assocCheckRxReAssocRspFrameStatus(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, OUT PUINT_16 pu2StatusCode); -+ -+WLAN_STATUS assocSendDisAssocFrame(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN UINT_16 u2ReasonCode); -+ -+WLAN_STATUS -+assocProcessRxDisassocFrame(IN P_ADAPTER_T prAdapter, -+ IN P_SW_RFB_T prSwRfb, IN UINT_8 aucBSSID[], OUT PUINT_16 pu2ReasonCode); -+ -+WLAN_STATUS assocProcessRxAssocReqFrame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, OUT PUINT_16 pu2StatusCode); -+ -+WLAN_STATUS assocSendReAssocRespFrame(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec); -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif /* _ASSOC_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/auth.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/auth.h -new file mode 100644 -index 000000000000..4f76f03324dd ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/auth.h -@@ -0,0 +1,125 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/mgmt/auth.h#1 -+*/ -+ -+/*! \file auth.h -+ \brief This file contains the authentication REQ/RESP of -+ IEEE 802.11 family for MediaTek 802.11 Wireless LAN Adapters. -+*/ -+ -+/* -+** Log: auth.h -+ * -+ * 04 21 2011 terry.wu -+ * [WCXRP00000674] [MT6620 Wi-Fi][Driver] Refine AAA authSendAuthFrame -+ * Add network type parameter to authSendAuthFrame. -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 14 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add management dispatching function table. -+ * -+ * 06 11 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * auth.c is migrated. -+ * -+ * 06 10 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add buildable & linkable ais_fsm.c -+ * -+ * related reference are still waiting to be resolved -+ * -+*/ -+ -+#ifndef _AUTH_H -+#define _AUTH_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+/*----------------------------------------------------------------------------*/ -+/* Routines in auth.c */ -+/*----------------------------------------------------------------------------*/ -+VOID authAddIEChallengeText(IN P_ADAPTER_T prAdapter, IN OUT P_MSDU_INFO_T prMsduInfo); -+ -+#if !CFG_SUPPORT_AAA -+WLAN_STATUS authSendAuthFrame(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN UINT_16 u2TransactionSeqNum); -+#else -+WLAN_STATUS -+authSendAuthFrame(IN P_ADAPTER_T prAdapter, -+ IN P_STA_RECORD_T prStaRec, -+ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, -+ IN P_SW_RFB_T prFalseAuthSwRfb, IN UINT_16 u2TransactionSeqNum, IN UINT_16 u2StatusCode); -+#endif /* CFG_SUPPORT_AAA */ -+ -+WLAN_STATUS authCheckTxAuthFrame(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo, IN UINT_16 u2TransactionSeqNum); -+ -+WLAN_STATUS authCheckRxAuthFrameTransSeq(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); -+ -+WLAN_STATUS -+authCheckRxAuthFrameStatus(IN P_ADAPTER_T prAdapter, -+ IN P_SW_RFB_T prSwRfb, IN UINT_16 u2TransactionSeqNum, OUT PUINT_16 pu2StatusCode); -+ -+VOID authHandleIEChallengeText(P_ADAPTER_T prAdapter, P_SW_RFB_T prSwRfb, P_IE_HDR_T prIEHdr); -+ -+WLAN_STATUS authProcessRxAuth2_Auth4Frame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); -+ -+WLAN_STATUS -+authSendDeauthFrame(IN P_ADAPTER_T prAdapter, -+ IN P_STA_RECORD_T prStaRec, -+ IN P_SW_RFB_T prClassErrSwRfb, IN UINT_16 u2ReasonCode, IN PFN_TX_DONE_HANDLER pfTxDoneHandler); -+ -+WLAN_STATUS authProcessRxDeauthFrame(IN P_SW_RFB_T prSwRfb, IN UINT_8 aucBSSID[], OUT PUINT_16 pu2ReasonCode); -+ -+WLAN_STATUS -+authProcessRxAuth1Frame(IN P_ADAPTER_T prAdapter, -+ IN P_SW_RFB_T prSwRfb, -+ IN UINT_8 aucExpectedBSSID[], -+ IN UINT_16 u2ExpectedAuthAlgNum, -+ IN UINT_16 u2ExpectedTransSeqNum, OUT PUINT_16 pu2ReturnStatusCode); -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif /* _AUTH_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/bow_fsm.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/bow_fsm.h -new file mode 100644 -index 000000000000..5995d133a6cd ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/bow_fsm.h -@@ -0,0 +1,184 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/mgmt/bow_fsm.h#1 -+*/ -+ -+/*! \file bow_fsm.h -+ \brief Declaration of functions and finite state machine for BOW Module. -+ -+ Declaration of functions and finite state machine for BOW Module. -+*/ -+ -+/* -+** Log: bow_fsm.h -+ * -+ * 05 22 2011 terry.wu -+ * [WCXRP00000735] [MT6620 Wi-Fi][BoW][FW/Driver] Protect BoW connection establishment -+ * Submit missing BoW header files. -+ * -+ * 03 27 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Support multiple physical link. -+ * -+ * 02 16 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Add bowNotifyAllLinkDisconnected interface and change channel grant procedure for bow starting.. -+ * -+ * 02 15 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Add channel previledge into _BOW_FSM_INFO_T. -+ * -+ * 09 16 2010 chinghwa.yu -+ * NULL -+ * update bowChangeMediaState. -+ * -+ * 08 24 2010 chinghwa.yu -+ * NULL -+ * Update BOW for the 1st time. -+ */ -+ -+#ifndef _BOW_FSM_H -+#define _BOW_FSM_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+#define BOW_BG_SCAN_INTERVAL_MIN_SEC 2 /* 30 // exponential to 960 */ -+#define BOW_BG_SCAN_INTERVAL_MAX_SEC 2 /* 960 // 16min */ -+ -+#define BOW_DELAY_TIME_OF_DISCONNECT_SEC 10 -+ -+#define BOW_BEACON_TIMEOUT_COUNT_STARTING 10 -+#define BOW_BEACON_TIMEOUT_GUARD_TIME_SEC 1 /* Second */ -+ -+#define BOW_BEACON_MAX_TIMEOUT_TU 100 -+#define BOW_BEACON_MIN_TIMEOUT_TU 5 -+#define BOW_BEACON_MAX_TIMEOUT_VALID TRUE -+#define BOW_BEACON_MIN_TIMEOUT_VALID TRUE -+ -+#define BOW_BMC_MAX_TIMEOUT_TU 100 -+#define BOW_BMC_MIN_TIMEOUT_TU 5 -+#define BOW_BMC_MAX_TIMEOUT_VALID TRUE -+#define BOW_BMC_MIN_TIMEOUT_VALID TRUE -+ -+#define BOW_JOIN_CH_GRANT_THRESHOLD 10 -+#define BOW_JOIN_CH_REQUEST_INTERVAL 2000 -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+typedef enum _ENUM_BOW_STATE_T { -+ BOW_STATE_IDLE = 0, -+ BOW_STATE_SEARCH, -+ BOW_STATE_SCAN, -+ BOW_STATE_ONLINE_SCAN, -+ BOW_STATE_LOOKING_FOR, -+ BOW_STATE_WAIT_FOR_NEXT_SCAN, -+ BOW_STATE_REQ_CHANNEL_JOIN, -+ BOW_STATE_REQ_CHANNEL_ALONE, -+ BOW_STATE_REQ_CHANNEL_MERGE, -+ BOW_STATE_JOIN, -+ BOW_STATE_IBSS_ALONE, -+ BOW_STATE_IBSS_MERGE, -+ BOW_STATE_NORMAL_TR, -+ BOW_STATE_NUM -+} ENUM_BOW_STATE_T; -+ -+typedef struct _BOW_FSM_INFO_T { -+ ENUM_BOW_STATE_T ePreviousState; -+ ENUM_BOW_STATE_T eCurrentState; -+ -+ BOOLEAN fgTryScan; -+ -+ /* Channel Privilege */ -+ -+ BOOLEAN fgIsInfraChannelFinished; -+ BOOLEAN fgIsChannelRequested; -+ BOOLEAN fgIsChannelGranted; -+ BOOLEAN fgIsScanPending; -+ UINT_32 u4ChGrantedInterval; -+ -+ UINT_8 ucPrimaryChannel; -+ ENUM_BAND_T eBand; -+ UINT_16 u2BeaconInterval; -+ -+ ENUM_BOW_STATE_T eReturnState; /* Return state after current activity finished or abort. */ -+ ENUM_BOW_STATE_T eForwardState; /* Step to next state if ACTION frame is TX successfully. */ -+ -+ P_BSS_DESC_T prTargetBss; /* BSS of target P2P Device. For Connection/Service Discovery */ -+ -+ P_STA_RECORD_T prTargetStaRec; -+ P_BSS_DESC_T prTargetBssDesc; /* For destination */ -+ -+ UINT_8 aucPeerAddress[6]; -+ -+ UINT_8 ucRole; -+ -+ BOOLEAN fgSupportQoS; -+ -+ BOOLEAN fgIsRsponseProbe; /* Indicate if BOW can response probe request frame. */ -+ -+ /* Sequence number of requested message. */ -+ UINT_8 ucSeqNumOfChReq; -+ UINT_8 ucSeqNumOfReqMsg; -+ UINT_8 ucSeqNumOfScnMsg; -+ UINT_8 ucSeqNumOfScanReq; -+ -+ UINT_8 ucSeqNumOfCancelMsg; -+ -+ UINT_8 ucDialogToken; -+ -+ /* Timer */ -+ TIMER_T rStartingBeaconTimer; /* For device discovery time of each discovery request from user. */ -+ TIMER_T rStartingDiscoveryTimer; -+ TIMER_T rOperationListenTimer; /* For Find phase under operational state. */ -+ TIMER_T rFSMTimer; /* A timer used for Action frame timeout usage. */ -+ TIMER_T rIndicationOfDisconnectTimer; -+ TIMER_T rChGrantedTimer; -+ -+ UINT_8 ucAvailableAuthTypes; /* Used for AUTH_MODE_AUTO_SWITCH */ -+ -+} BOW_FSM_INFO_T, *P_BOW_FSM_INFO_T; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+#define bowChangeMediaState(_prAdapter, _eNewMediaState) \ -+ (_prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_BOW_INDEX].eConnectionState = (_eNewMediaState)) -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/bss.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/bss.h -new file mode 100644 -index 000000000000..0597132b970e ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/bss.h -@@ -0,0 +1,265 @@ -+/* -+** Id: @(#) bss.h -+*/ -+ -+/*! \file "bss.h" -+ \brief In this file we define the function prototype used in BSS/IBSS. -+ -+ The file contains the function declarations and defines for used in BSS/IBSS. -+*/ -+ -+/* -+** Log: bss.h -+ * -+ * 07 17 2012 yuche.tsai -+ * NULL -+ * Let netdev bring up. -+ * -+ * 07 17 2012 yuche.tsai -+ * NULL -+ * Compile no error before trial run. -+ * -+ * 03 02 2012 terry.wu -+ * NULL -+ * Sync CFG80211 modification from branch 2,2. -+ * -+ * 09 14 2011 yuche.tsai -+ * NULL -+ * Add P2P IE in assoc response. -+ * -+ * 03 19 2011 yuche.tsai -+ * [WCXRP00000581] [Volunteer Patch][MT6620][Driver] P2P IE in Assoc Req Issue -+ * Make assoc req to append P2P IE if wifi direct is enabled. -+ * -+ * 03 02 2011 wh.su -+ * [WCXRP00000448] [MT6620 Wi-Fi][Driver] Fixed WSC IE not send out at probe request -+ * Add code to send beacon and probe response WSC IE at Auto GO. -+ * -+ * 02 23 2011 eddie.chen -+ * [WCXRP00000463] [MT6620 Wi-Fi][FW/Driver][Hotspot] Cannot update WMM PS STA's partital bitmap -+ * Fix parsing WMM INFO and bmp delivery bitmap definition. -+ * -+ * 01 31 2011 george.huang -+ * [WCXRP00000333] [MT5931][FW] support SRAM power control drivers -+ * Extend TIM PVB, from 2 to 3 octets. -+ * -+ * 11 29 2010 cp.wu -+ * [WCXRP00000210] [MT6620 Wi-Fi][Driver][FW] Set RCPI value in STA_REC for -+ * initial TX rate selection of auto-rate algorithm -+ * update ucRcpi of STA_RECORD_T for AIS when -+ * 1) Beacons for IBSS merge is received -+ * 2) Associate Response for a connecting peer is received -+ * -+ * 09 03 2010 kevin.huang -+ * NULL -+ * Refine #include sequence and solve recursive/nested #include issue -+ * -+ * 08 12 2010 kevin.huang -+ * NULL -+ * Update bssProcessProbeRequest() and bssSendBeaconProbeResponse() declarations -+ * -+ * 07 19 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration. -+ * when IBSS is being merged-in, send command packet to PM for connected indication -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 25 2010 george.huang -+ * [WPD00001556]Basic power managemenet function -+ * Create beacon update path, with expose bssUpdateBeaconContent() -+ * -+ * 06 17 2010 yuche.tsai -+ * [WPD00003839][MT6620 5931][P2P] Feature migration -+ * Add CTRL FLAGS for Probe Response. -+ * -+ * 06 09 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add necessary changes to driver data paths. -+ * -+ * 06 07 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add aa_fsm.h, ais_fsm.h, bss.h, mib.h and scan.h. -+ * -+ * 06 04 2010 george.huang -+ * [BORA00000678][MT6620]WiFi LP integration -+ * [PM] Support U-APSD for STA mode -+ * -+ * 05 28 2010 kevin.huang -+ * [BORA00000794][WIFISYS][New Feature]Power Management Support -+ * Add ClientList handling API - bssClearClientList, bssAddStaRecToClientList -+ * -+ * 05 14 2010 kevin.huang -+ * [BORA00000794][WIFISYS][New Feature]Power Management Support -+ * Remove unused typedef. -+ * -+ * 05 12 2010 kevin.huang -+ * [BORA00000794][WIFISYS][New Feature]Power Management Support -+ * Fix file merge error -+ * -+ * 05 12 2010 kevin.huang -+ * [BORA00000794][WIFISYS][New Feature]Power Management Support -+ * Add Power Management - Legacy PS-POLL support. -+ * -+ * 04 19 2010 kevin.huang -+ * [BORA00000714][WIFISYS][New Feature]Beacon Timeout Support -+ * Add Beacon Timeout Support -+ * * * and will send Null frame to diagnose connection -+ * -+ * 03 16 2010 kevin.huang -+ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support -+ * Add AdHoc Mode -+ * -+ * 02 23 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Add DTIM count update while TX Beacon -+ * -+ * 02 04 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Add AAA Module Support, Revise Net Type to Net Type Index for array lookup -+*/ -+ -+#ifndef _BSS_H -+#define _BSS_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+/* NOTE(Kevin): change define for george */ -+/* #define MAX_LEN_TIM_PARTIAL_BMP (((MAX_ASSOC_ID + 1) + 7) / 8) */ /* Required bits = (MAX_ASSOC_ID + 1) */ -+#define MAX_LEN_TIM_PARTIAL_BMP ((CFG_STA_REC_NUM + 7) / 8) -+/* reserve length greater than maximum size of STA_REC */ /* obsoleted: Assume we only use AID:1~15 */ -+ -+/* CTRL FLAGS for Probe Response */ -+#define BSS_PROBE_RESP_USE_P2P_DEV_ADDR BIT(0) -+#define BSS_PROBE_RESP_INCLUDE_P2P_IE BIT(1) -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+#define bssAssignAssocID(_prStaRec) ((_prStaRec)->ucIndex + 1) -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+/*----------------------------------------------------------------------------*/ -+/* Routines for all Operation Modes */ -+/*----------------------------------------------------------------------------*/ -+P_STA_RECORD_T -+bssCreateStaRecFromBssDesc(IN P_ADAPTER_T prAdapter, -+ IN ENUM_STA_TYPE_T eStaType, -+ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_BSS_DESC_T prBssDesc); -+ -+VOID bssComposeNullFrame(IN P_ADAPTER_T prAdapter, IN PUINT_8 pucBuffer, IN P_STA_RECORD_T prStaRec); -+ -+VOID -+bssComposeQoSNullFrame(IN P_ADAPTER_T prAdapter, -+ IN PUINT_8 pucBuffer, IN P_STA_RECORD_T prStaRec, IN UINT_8 ucUP, IN BOOLEAN fgSetEOSP); -+ -+WLAN_STATUS -+bssSendNullFrame(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN PFN_TX_DONE_HANDLER pfTxDoneHandler); -+ -+WLAN_STATUS -+bssSendQoSNullFrame(IN P_ADAPTER_T prAdapter, -+ IN P_STA_RECORD_T prStaRec, IN UINT_8 ucUP, IN PFN_TX_DONE_HANDLER pfTxDoneHandler); -+ -+/*----------------------------------------------------------------------------*/ -+/* Routines for both IBSS(AdHoc) and BSS(AP) */ -+/*----------------------------------------------------------------------------*/ -+VOID bssGenerateExtSuppRate_IE(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); -+ -+VOID -+bssBuildBeaconProbeRespFrameCommonIEs(IN P_MSDU_INFO_T prMsduInfo, IN P_BSS_INFO_T prBssInfo, IN PUINT_8 pucDestAddr); -+ -+VOID -+bssComposeBeaconProbeRespFrameHeaderAndFF(IN PUINT_8 pucBuffer, -+ IN PUINT_8 pucDestAddr, -+ IN PUINT_8 pucOwnMACAddress, -+ IN PUINT_8 pucBSSID, IN UINT_16 u2BeaconInterval, IN UINT_16 u2CapInfo); -+ -+WLAN_STATUS -+bssSendBeaconProbeResponse(IN P_ADAPTER_T prAdapter, -+ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, -+ IN PUINT_8 pucDestAddr, IN UINT_32 u4ControlFlags); -+ -+WLAN_STATUS bssProcessProbeRequest(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); -+ -+VOID bssClearClientList(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prBssInfo); -+ -+VOID bssAddStaRecToClientList(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prBssInfo, IN P_STA_RECORD_T prStaRec); -+ -+VOID bssRemoveStaRecFromClientList(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prBssInfo, IN P_STA_RECORD_T prStaRec); -+ -+/*----------------------------------------------------------------------------*/ -+/* Routines for IBSS(AdHoc) only */ -+/*----------------------------------------------------------------------------*/ -+VOID -+ibssProcessMatchedBeacon(IN P_ADAPTER_T prAdapter, -+ IN P_BSS_INFO_T prBssInfo, IN P_BSS_DESC_T prBssDesc, IN UINT_8 ucRCPI); -+ -+WLAN_STATUS ibssCheckCapabilityForAdHocMode(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBssDesc); -+ -+VOID ibssInitForAdHoc(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prBssInfo); -+ -+WLAN_STATUS bssUpdateBeaconContent(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex); -+ -+/*----------------------------------------------------------------------------*/ -+/* Routines for BSS(AP) only */ -+/*----------------------------------------------------------------------------*/ -+VOID bssInitForAP(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prBssInfo, IN BOOLEAN fgIsRateUpdate); -+ -+VOID bssUpdateDTIMCount(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex); -+ -+VOID bssSetTIMBitmap(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prBssInfo, IN UINT_16 u2AssocId); -+ -+P_STA_RECORD_T bssGetClientByAddress(IN P_BSS_INFO_T prBssInfo, PUINT_8 pucMacAddr); -+ -+/*link function to p2p module for txBcnIETable*/ -+ -+/* WMM-2.2.2 WMM ACI to AC coding */ -+typedef enum _ENUM_ACI_T { -+ ACI_BE = 0, -+ ACI_BK = 1, -+ ACI_VI = 2, -+ ACI_VO = 3, -+ ACI_NUM -+} ENUM_ACI_T, *P_ENUM_ACI_T; -+ -+typedef enum _ENUM_AC_PRIORITY_T { -+ AC_BK_PRIORITY = 0, -+ AC_BE_PRIORITY, -+ AC_VI_PRIORITY, -+ AC_VO_PRIORITY -+} ENUM_AC_PRIORITY_T, *P_ENUM_AC_PRIORITY_T; -+ -+#endif /* _BSS_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/cnm.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/cnm.h -new file mode 100644 -index 000000000000..81b16b588867 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/cnm.h -@@ -0,0 +1,258 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/mgmt/cnm.h#1 -+*/ -+ -+/*! \file "cnm.h" -+ \brief -+*/ -+ -+/* -+** Log: cnm.h -+ * -+ * 06 23 2011 cp.wu -+ * [WCXRP00000798] [MT6620 Wi-Fi][Firmware] Follow-ups for WAPI frequency offset workaround in firmware SCN module -+ * change parameter name from PeerAddr to BSSID -+ * -+ * 06 20 2011 cp.wu -+ * [WCXRP00000798] [MT6620 Wi-Fi][Firmware] Follow-ups for WAPI frequency offset workaround in firmware SCN module -+ * 1. specify target's BSSID when requesting channel privilege. -+ * 2. pass BSSID information to firmware domain -+ * -+ * 04 12 2011 cm.chang -+ * [WCXRP00000634] [MT6620 Wi-Fi][Driver][FW] 2nd BSS will not support 40MHz bandwidth for concurrency -+ * . -+ * -+ * 03 10 2011 cm.chang -+ * [WCXRP00000358] [MT6620 Wi-Fi][Driver] Provide concurrent information for each module -+ * Add some functions to let AIS/Tethering or AIS/BOW be the same channel -+ * -+ * 01 12 2011 cm.chang -+ * [WCXRP00000358] [MT6620 Wi-Fi][Driver] Provide concurrent information for each module -+ * Provide function to decide if BSS can be activated or not -+ * -+ * 12 07 2010 cm.chang -+ * [WCXRP00000239] MT6620 Wi-Fi][Driver][FW] Merge concurrent branch back to maintrunk -+ * 1. BSSINFO include RLM parameter -+ * 2. free all sta records when network is disconnected -+ * -+ * 08 24 2010 cm.chang -+ * NULL -+ * Support RLM initail channel of Ad-hoc, P2P and BOW -+ * -+ * 07 19 2010 cm.chang -+ * -+ * Set RLM parameters and enable CNM channel manager -+ * -+ * 07 13 2010 cm.chang -+ * -+ * Rename MSG_CH_RELEASE_T to MSG_CH_ABORT_T -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 07 08 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Rename MID_MNY_CNM_CH_RELEASE to MID_MNY_CNM_CH_ABORT -+ * -+ * 07 01 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Need bandwidth info when requesting channel privilege -+ * -+ * 07 01 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Modify CNM message handler for new flow -+ * -+ * 05 12 2010 kevin.huang -+ * [BORA00000794][WIFISYS][New Feature]Power Management Support -+ * Add Power Management - Legacy PS-POLL support. -+ * -+ * 05 05 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Add a new function to send abort message -+ * -+ * 03 16 2010 kevin.huang -+ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support -+ * Add AdHoc Mode -+ * -+ * 03 10 2010 kevin.huang -+ * [BORA00000654][WIFISYS][New Feature] CNM Module - Ch Manager Support -+ * Add Channel Manager for arbitration of JOIN and SCAN Req -+ * -+ * 02 08 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Support partial part about cmd basic configuration -+ * -+ * Nov 18 2009 mtk01104 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Add prototype of cnmFsmEventInit() -+ * -+ * Nov 2 2009 mtk01104 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * -+** -+*/ -+ -+#ifndef _CNM_H -+#define _CNM_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+typedef enum _ENUM_CH_REQ_TYPE_T { -+ CH_REQ_TYPE_JOIN, -+ CH_REQ_TYPE_P2P_LISTEN, -+ -+ CH_REQ_TYPE_NUM -+} ENUM_CH_REQ_TYPE_T, *P_ENUM_CH_REQ_TYPE_T; -+ -+typedef struct _MSG_CH_REQ_T { -+ MSG_HDR_T rMsgHdr; /* Must be the first member */ -+ UINT_8 ucNetTypeIndex; -+ UINT_8 ucTokenID; -+ UINT_8 ucPrimaryChannel; -+ ENUM_CHNL_EXT_T eRfSco; -+ ENUM_BAND_T eRfBand; -+ ENUM_CH_REQ_TYPE_T eReqType; -+ UINT_32 u4MaxInterval; /* In unit of ms */ -+ UINT_8 aucBSSID[6]; -+ UINT_8 aucReserved[2]; -+} MSG_CH_REQ_T, *P_MSG_CH_REQ_T; -+ -+typedef struct _MSG_CH_ABORT_T { -+ MSG_HDR_T rMsgHdr; /* Must be the first member */ -+ UINT_8 ucNetTypeIndex; -+ UINT_8 ucTokenID; -+} MSG_CH_ABORT_T, *P_MSG_CH_ABORT_T; -+ -+typedef struct _MSG_CH_GRANT_T { -+ MSG_HDR_T rMsgHdr; /* Must be the first member */ -+ UINT_8 ucNetTypeIndex; -+ UINT_8 ucTokenID; -+ UINT_8 ucPrimaryChannel; -+ ENUM_CHNL_EXT_T eRfSco; -+ ENUM_BAND_T eRfBand; -+ ENUM_CH_REQ_TYPE_T eReqType; -+ UINT_32 u4GrantInterval; /* In unit of ms */ -+} MSG_CH_GRANT_T, *P_MSG_CH_GRANT_T; -+ -+typedef struct _MSG_CH_REOCVER_T { -+ MSG_HDR_T rMsgHdr; /* Must be the first member */ -+ UINT_8 ucNetTypeIndex; -+ UINT_8 ucTokenID; -+ UINT_8 ucPrimaryChannel; -+ ENUM_CHNL_EXT_T eRfSco; -+ ENUM_BAND_T eRfBand; -+ ENUM_CH_REQ_TYPE_T eReqType; -+} MSG_CH_RECOVER_T, *P_MSG_CH_RECOVER_T; -+ -+typedef struct _CNM_INFO_T { -+ UINT_32 u4Reserved; -+} CNM_INFO_T, *P_CNM_INFO_T; -+ -+#if CFG_ENABLE_WIFI_DIRECT -+/* Moved from p2p_fsm.h */ -+typedef struct _DEVICE_TYPE_T { -+ UINT_16 u2CategoryId; /* Category ID */ -+ UINT_8 aucOui[4]; /* OUI */ -+ UINT_16 u2SubCategoryId; /* Sub Category ID */ -+} __KAL_ATTRIB_PACKED__ DEVICE_TYPE_T, *P_DEVICE_TYPE_T; -+#endif -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+VOID cnmInit(P_ADAPTER_T prAdapter); -+ -+VOID cnmUninit(P_ADAPTER_T prAdapter); -+ -+VOID cnmChMngrRequestPrivilege(P_ADAPTER_T prAdapter, P_MSG_HDR_T prMsgHdr); -+ -+VOID cnmChMngrAbortPrivilege(P_ADAPTER_T prAdapter, P_MSG_HDR_T prMsgHdr); -+ -+VOID cnmChMngrHandleChEvent(P_ADAPTER_T prAdapter, P_WIFI_EVENT_T prEvent); -+ -+BOOLEAN -+cnmPreferredChannel(P_ADAPTER_T prAdapter, P_ENUM_BAND_T prBand, PUINT_8 pucPrimaryChannel, P_ENUM_CHNL_EXT_T prBssSCO); -+ -+BOOLEAN cnmAisInfraChannelFixed(P_ADAPTER_T prAdapter, P_ENUM_BAND_T prBand, PUINT_8 pucPrimaryChannel); -+ -+VOID cnmAisInfraConnectNotify(P_ADAPTER_T prAdapter); -+ -+BOOLEAN cnmAisIbssIsPermitted(P_ADAPTER_T prAdapter); -+ -+BOOLEAN cnmP2PIsPermitted(P_ADAPTER_T prAdapter); -+ -+BOOLEAN cnmBowIsPermitted(P_ADAPTER_T prAdapter); -+ -+BOOLEAN cnmBss40mBwPermitted(P_ADAPTER_T prAdapter, ENUM_NETWORK_TYPE_INDEX_T eNetTypeIdx); -+#if CFG_P2P_LEGACY_COEX_REVISE -+BOOLEAN cnmAisDetectP2PChannel(P_ADAPTER_T prAdapter, P_ENUM_BAND_T prBand, PUINT_8 pucPrimaryChannel); -+#endif -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+#ifndef _lint -+/* We don't have to call following function to inspect the data structure. -+ * It will check automatically while at compile time. -+ * We'll need this to guarantee the same member order in different structures -+ * to simply handling effort in some functions. -+ */ -+static inline VOID cnmMsgDataTypeCheck(VOID) -+{ -+ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSG_CH_GRANT_T, rMsgHdr) == 0); -+ -+ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSG_CH_GRANT_T, rMsgHdr) == OFFSET_OF(MSG_CH_RECOVER_T, rMsgHdr)); -+ -+ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSG_CH_GRANT_T, ucNetTypeIndex) == -+ OFFSET_OF(MSG_CH_RECOVER_T, ucNetTypeIndex)); -+ -+ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSG_CH_GRANT_T, ucTokenID) == OFFSET_OF(MSG_CH_RECOVER_T, ucTokenID)); -+ -+ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSG_CH_GRANT_T, ucPrimaryChannel) == -+ OFFSET_OF(MSG_CH_RECOVER_T, ucPrimaryChannel)); -+ -+ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSG_CH_GRANT_T, eRfSco) == OFFSET_OF(MSG_CH_RECOVER_T, eRfSco)); -+ -+ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSG_CH_GRANT_T, eRfBand) == OFFSET_OF(MSG_CH_RECOVER_T, eRfBand)); -+ -+ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSG_CH_GRANT_T, eReqType) == OFFSET_OF(MSG_CH_RECOVER_T, eReqType)); -+ -+} -+#endif /* _lint */ -+ -+#endif /* _CNM_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/cnm_mem.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/cnm_mem.h -new file mode 100644 -index 000000000000..c8f25b1b29a9 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/cnm_mem.h -@@ -0,0 +1,1164 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/mgmt/cnm_mem.h#1 -+*/ -+ -+/*! \file "cnm_mem.h" -+ \brief In this file we define the structure of the control unit of -+ packet buffer and MGT/MSG Memory Buffer. -+*/ -+ -+/* -+** Log: cnm_mem.h -+ * -+ * 03 02 2012 terry.wu -+ * NULL -+ * Snc CFG80211 modification for ICS migration from branch 2.2. -+ * -+ * 01 05 2012 tsaiyuan.hsu -+ * [WCXRP00001157] [MT6620 Wi-Fi][FW][DRV] add timing measurement support for 802.11v -+ * add timing measurement support for 802.11v. -+ * -+ * 03 17 2011 yuche.tsai -+ * NULL -+ * Resize the Secondary Device Type array when WiFi Direct is enabled. -+ * -+ * 03 16 2011 wh.su -+ * [WCXRP00000530] [MT6620 Wi-Fi] [Driver] skip doing p2pRunEventAAAComplete after send assoc response Tx Done -+ * enable the protected while at P2P start GO, and skip some security check . -+ * -+ * 01 26 2011 cm.chang -+ * [WCXRP00000395] [MT6620 Wi-Fi][Driver][FW] Search STA_REC with additional net type index argument -+ * . -+ * -+ * 01 11 2011 eddie.chen -+ * [WCXRP00000322] Add WMM IE in beacon, -+ -+Add per station flow control when STA is in PS -+ -+ * Add per STA flow control when STA is in PS mode -+ * -+ * 12 29 2010 eddie.chen -+ * [WCXRP00000322] Add WMM IE in beacon, -+Add per station flow control when STA is in PS -+ -+ * 1) PS flow control event -+ * -+ * 2) WMM IE in beacon, assoc resp, probe resp -+ * -+ * 12 23 2010 george.huang -+ * [WCXRP00000152] [MT6620 Wi-Fi] AP mode power saving function -+ * 1. update WMM IE parsing, with ASSOC REQ handling -+ * 2. extend U-APSD parameter passing from driver to FW -+ * -+ * 12 07 2010 cm.chang -+ * [WCXRP00000239] MT6620 Wi-Fi][Driver][FW] Merge concurrent branch back to maintrunk -+ * 1. BSSINFO include RLM parameter -+ * 2. free all sta records when network is disconnected -+ * -+ * 11 29 2010 cm.chang -+ * [WCXRP00000210] [MT6620 Wi-Fi][Driver][FW] Set RCPI value in STA_REC for -+ * initial TX rate selection of auto-rate algorithm -+ * Sync RCPI of STA_REC to FW as reference of initial TX rate -+ * -+ * 10 18 2010 cp.wu -+ * [WCXRP00000053] [MT6620 Wi-Fi][Driver] Reset incomplete and might leads to BSOD -+ * when entering RF test with AIS associated -+ * 1. remove redundant variables in STA_REC structure -+ * 2. add STA-REC uninitialization routine for clearing pending events -+ * -+ * 09 21 2010 kevin.huang -+ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning -+ * Eliminate Linux Compile Warning -+ * -+ * 09 03 2010 kevin.huang -+ * NULL -+ * Refine #include sequence and solve recursive/nested #include issue -+ * -+ * 07 12 2010 cp.wu -+ * -+ * SAA will take a record for tracking request sequence number. -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 07 07 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Support state of STA record change from 1 to 1 -+ * -+ * 07 01 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Support sync command of STA_REC -+ * -+ * 06 21 2010 wh.su -+ * [WPD00003840][MT6620 5931] Security migration -+ * modify some code for concurrent network. -+ * -+ * 06 21 2010 yuche.tsai -+ * [WPD00003839][MT6620 5931][P2P] Feature migration -+ * Fix compile error for P2P related defination. -+ * -+ * 06 18 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Provide cnmMgtPktAlloc() and alloc/free function of msg/buf -+ * -+ * 06 17 2010 yuche.tsai -+ * [WPD00003839][MT6620 5931][P2P] Feature migration -+ * Add P2P related fields. -+ * -+ * 06 14 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * saa_fsm.c is migrated. -+ * -+ * 06 14 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * restore utility function invoking via hem_mbox to direct calls -+ * -+ * 06 10 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add buildable & linkable ais_fsm.c -+ * -+ * related reference are still waiting to be resolved -+ * -+ * 06 08 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * hem_mbox is migrated. -+ * -+ * 06 08 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add hem_mbox.c and cnm_mem.h (but disabled some feature) for further migration -+ * -+ * 06 04 2010 george.huang -+ * [BORA00000678][MT6620]WiFi LP integration -+ * [BORA00000678] [MT6620]WiFi LP integration -+ * 1. add u8TimeStamp in MSDU_INFO -+ * 2. move fgIsRxTSFUpdated/fgIsTxTSFUpdated from static to BSS_INFO -+ * 3. add new member for supporting PM in STA_RECORD, which is for AP PS mode -+ * -+ * 05 31 2010 yarco.yang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Add RX TSF Log Feature and ADDBA Rsp with DECLINE handling -+ * -+ * 05 28 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Support checking of duplicated buffer free -+ * -+ * 05 28 2010 kevin.huang -+ * [BORA00000794][WIFISYS][New Feature]Power Management Support -+ * Move define of STA_REC_NUM to config.h and rename to CFG_STA_REC_NUM -+ * -+ * 05 21 2010 kevin.huang -+ * [BORA00000794][WIFISYS][New Feature]Power Management Support -+ * Refine txmInitWtblTxRateTable() - set TX initial rate according to AP's operation rate set -+ * -+ * 05 19 2010 yarco.yang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Fixed MAC RX Desc be overwritten issue -+ * -+ * 05 12 2010 kevin.huang -+ * [BORA00000794][WIFISYS][New Feature]Power Management Support -+ * Add Power Management - Legacy PS-POLL support. -+ * -+ * 05 10 2010 yarco.yang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Support Rx header translation for A-MSDU subframe -+ * -+ * 05 07 2010 george.huang -+ * [BORA00000678][MT6620]WiFi LP integration -+ * add more sanity check about setting timer -+ * -+ * 04 29 2010 george.huang -+ * [BORA00000678][MT6620]WiFi LP integration -+ * modify the compiling flag for RAM usage -+ * -+ * 04 28 2010 tehuang.liu -+ * [BORA00000605][WIFISYS] Phase3 Integration -+ * Modified some MQM-related data structures (SN counter, TX/RX BA table) -+ * -+ * 04 27 2010 tehuang.liu -+ * [BORA00000605][WIFISYS] Phase3 Integration -+ * Added new TX/RX BA tables in STA_REC -+ * -+ * 04 19 2010 kevin.huang -+ * [BORA00000714][WIFISYS][New Feature]Beacon Timeout Support -+ * Add Beacon Timeout Support and will send Null frame to diagnose connection -+ * -+ * 04 09 2010 tehuang.liu -+ * [BORA00000605][WIFISYS] Phase3 Integration -+ * [BORA00000644] WiFi phase 4 integration -+ * Added per-TID SN cache in STA_REC -+ * -+ * 03 24 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Support power control -+ * -+ * 03 16 2010 kevin.huang -+ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support -+ * Add AdHoc Mode -+ * -+ * 03 11 2010 yuche.tsai -+ * [BORA00000343][MT6620] Emulation For TX -+ * . -+ * -+ * 03 05 2010 yarco.yang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Remove Emulation definition -+ * -+ * 03 04 2010 cp.wu -+ * [BORA00000368]Integrate HIF part into BORA -+ * eliminate HIF_EMULATION in cnm_mem.h -+ * -+ * 03 04 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Add cnmStaRecChangeState() declaration. -+ * -+ * 03 03 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Remove compiling warning for some emulation flags -+ * -+ * 03 03 2010 wh.su -+ * [BORA00000637][MT6620 Wi-Fi] [Bug] WPA2 pre-authentication timer not correctly initialize -+ * move the AIS specific variable for security to AIS specific structure. -+ * -+ * 03 03 2010 wh.su -+ * [BORA00000637][MT6620 Wi-Fi] [Bug] WPA2 pre-authentication timer not correctly initialize -+ * Fixed the pre-authentication timer not correctly init issue, -+ * and modify the security related callback function prototype. -+ * -+ * 03 01 2010 tehuang.liu -+ * [BORA00000569][WIFISYS] Phase 2 Integration Test -+ * To store field AMPDU Parameters in STA_REC -+ * -+ * 02 26 2010 tehuang.liu -+ * [BORA00000569][WIFISYS] Phase 2 Integration Test -+ * Added fgIsWmmSupported in STA_RECORD_T. -+ * -+ * 02 26 2010 tehuang.liu -+ * [BORA00000569][WIFISYS] Phase 2 Integration Test -+ * Added fgIsUapsdSupported in STA_RECORD_T -+ * -+ * 02 13 2010 tehuang.liu -+ * [BORA00000569][WIFISYS] Phase 2 Integration Test -+ * Added arTspecTable in STA_REC for TSPEC management -+ * -+ * 02 12 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Enable mgmt buffer debug by default -+ * -+ * 02 12 2010 tehuang.liu -+ * [BORA00000569][WIFISYS] Phase 2 Integration Test -+ * Added BUFFER_SOURCE_BCN -+ * -+ * 02 10 2010 tehuang.liu -+ * [BORA00000569][WIFISYS] Phase 2 Integration Test -+ * Renamed MSDU_INFO.ucFixedRateIndex as MSDU_INFO.ucFixedRateCode -+ * -+ * 02 04 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Add AAA Module Support, Revise Net Type to Net Type Index for array lookup -+ * -+ * 02 02 2010 tehuang.liu -+ * [BORA00000569][WIFISYS] Phase 2 Integration Test -+ * Added SN info in MSDU_INFO_T -+ * -+ * 01 27 2010 wh.su -+ * [BORA00000476][Wi-Fi][firmware] Add the security module initialize code -+ * add and fixed some security function. -+ * -+ * 01 11 2010 kevin.huang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Add Deauth and Disassoc Handler -+ * -+ * 01 08 2010 cp.wu -+ * [BORA00000368]Integrate HIF part into BORA -+ * 1) separate wifi_var_emu.c/.h from wifi_var.c/.h -+ * 2) eliminate HIF_EMULATION code sections appeared in wifi_var/cnm_mem -+ * 3) use cnmMemAlloc() instead to allocate SRAM buffer -+ * -+ * 12 31 2009 cp.wu -+ * [BORA00000368]Integrate HIF part into BORA -+ * 1) surpress debug message emitted from hal_hif.c -+ * 2) add two set of field for recording buffer process time -+ * -+ * 12 31 2009 cp.wu -+ * [BORA00000368]Integrate HIF part into BORA -+ * 1. move wifi task initialization from wifi_task.c(rom) to wifi_init.c (TCM) for integrating F/W download later -+ * * * * * 2. WIFI_Event_Dispatcher() prototype changed to return to suspend mode from normal operation mode -+ * * * * * 2. HIF emulation logic revised -+ * -+ * 12 29 2009 yuche.tsai -+ * [BORA00000343][MT6620] Emulation For TX -+ * .Using global buffer declaring by SD1 instead of using another one. -+ * -+ * 12 25 2009 tehuang.liu -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Integrated modifications for 1st connection (mainly on FW modules MQM, TXM, and RXM) -+ * * MQM: BA handling -+ * * TXM: Macros updates -+ * * RXM: Macros/Duplicate Removal updates -+ * -+ * 12 24 2009 yarco.yang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * . -+ * -+ * 12 23 2009 cp.wu -+ * [BORA00000368]Integrate HIF part into BORA -+ * allocating SRAM for emulation purpose by ruducing MEM_BANK3_BUF_SZ -+ * -+ * 12 21 2009 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Remove individual DATA_BUF_BLOCK_NUM definition for emulation compiling flagsu1rwduu`wvpghlqg|fh+fmdkb -+ * -+ * 12 21 2009 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Support several data buffer banks. -+ * -+ * 12 18 2009 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * .For new FPGA memory size -+ * -+ * 12 18 2009 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * . -+ * -+ * 12 17 2009 george.huang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * . -+ * -+ * Dec 17 2009 MTK02468 -+ * [BORA00000337] To check in codes for FPGA emulation -+ * Modified the DATA_BLOCK_SIZE from 1620 to 2048 -+ * -+ * Dec 16 2009 mtk01426 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Add CFG_TEST_SEC_EMULATION flag -+ * -+ * Dec 9 2009 mtk01104 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Add HT cap to sta record -+ * -+ * Dec 9 2009 mtk02752 -+ * [BORA00000368] Integrate HIF part into BORA -+ * add cnmDataPktFree() for emulation loopback purpose -+ * -+ * Dec 8 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * add the buffer for key handshake 1x and cmd key order issue -+ * -+ * Dec 7 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * move the tx call back function proto type to typedef.h -+ * -+ * Dec 3 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Add cnmGetStaRecByAddress() and modify variable in STA_RECORD_T -+ * -+ * Dec 1 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * rename the port block flag -+ * -+ * Nov 23 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Add variables to STA_RECORD_T for assoc/auth -+ * -+ * Nov 23 2009 mtk02468 -+ * [BORA00000337] To check in codes for FPGA emulation -+ * Fixed the value of STA_WAIT_QUEUE_NUM (from 7 to 5) -+ * -+ * Nov 20 2009 mtk02468 -+ * [BORA00000337] To check in codes for FPGA emulation -+ * Removed u2FrameLength from SW_RFB -+ * -+ * Nov 20 2009 mtk02468 -+ * [BORA00000337] To check in codes for FPGA emulation -+ * Fixed indenting -+ * -+ * Nov 20 2009 mtk02468 -+ * [BORA00000337] To check in codes for FPGA emulation -+ * Updated MSDU_INFO and SW_RFB -+ * -+ * Nov 19 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * update the variable for security -+ * -+ * Nov 18 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * remove the variable to make the compiler ok -+ * -+ * Nov 18 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * add the variable for security module -+ * -+ * Nov 16 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Fix typo in define of MSG_BUF_BLOCK_SIZE -+ * -+ * Nov 13 2009 mtk02468 -+ * [BORA00000337] To check in codes for FPGA emulation -+ * Let typedef STA_REC_T precede typedef MSDU_INFO_T and SW_RFB_T -+ * -+ * Nov 13 2009 mtk02468 -+ * [BORA00000337] To check in codes for FPGA emulation -+ * Modified MSDU_INFO and STA_REC for TXM and MQM -+ * -+ * Nov 12 2009 mtk01104 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Rename STA_REC_T to STA_RECORD_T and add ucIndex member -+ * -+ * Nov 9 2009 mtk01104 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Make sure ucBufferSource the same offset in MSDU_INFO and SW_RFB -+ * -+ * Nov 6 2009 mtk01426 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * -+ * -+ * Nov 5 2009 mtk01426 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * -+ * -+ * Nov 5 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Update comment -+ * -+ * Oct 30 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Add draft content of MSDU_INFO_T and SW_RFB_T -+ * -+ * Oct 30 2009 mtk01084 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * -+ * -+ * Oct 28 2009 mtk01104 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * -+ * -+ * Oct 23 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Fix lint warning -+ * -+ * Oct 21 2009 mtk01426 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Add CFG_TEST_RX_EMULATION flag -+ * -+ * Oct 20 2009 mtk01426 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * -+ * -+ * Oct 9 2009 mtk02468 -+ * [BORA00000337] To check in codes for FPGA emulation -+ * Added field ucTC to MSDU_INFO_T and field pucHifRxPacket to SW_RFB_T -+ * -+ * Oct 8 2009 mtk01104 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * -+** -+*/ -+ -+#ifndef _CNM_MEM_H -+#define _CNM_MEM_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+#ifndef POWER_OF_2 -+#define POWER_OF_2(n) BIT(n) -+#endif -+ -+/* Size of a basic management buffer block in power of 2 */ -+#define MGT_BUF_BLOCK_SIZE_IN_POWER_OF_2 7 /* 7 to the power of 2 = 128 */ -+#define MSG_BUF_BLOCK_SIZE_IN_POWER_OF_2 5 /* 5 to the power of 2 = 32 */ -+ -+/* Size of a basic management buffer block */ -+#define MGT_BUF_BLOCK_SIZE POWER_OF_2(MGT_BUF_BLOCK_SIZE_IN_POWER_OF_2) -+#define MSG_BUF_BLOCK_SIZE POWER_OF_2(MSG_BUF_BLOCK_SIZE_IN_POWER_OF_2) -+ -+/* Total size of (n) basic management buffer blocks */ -+#define MGT_BUF_BLOCKS_SIZE(n) ((UINT_32)(n) << MGT_BUF_BLOCK_SIZE_IN_POWER_OF_2) -+#define MSG_BUF_BLOCKS_SIZE(n) ((UINT_32)(n) << MSG_BUF_BLOCK_SIZE_IN_POWER_OF_2) -+ -+/* Number of management buffer block */ -+#define MAX_NUM_OF_BUF_BLOCKS 32 /* Range: 1~32 */ -+ -+/* Size of overall management frame buffer */ -+#define MGT_BUFFER_SIZE (MAX_NUM_OF_BUF_BLOCKS * MGT_BUF_BLOCK_SIZE) -+#define MSG_BUFFER_SIZE (MAX_NUM_OF_BUF_BLOCKS * MSG_BUF_BLOCK_SIZE) -+ -+/* STA_REC related definitions */ -+#define STA_REC_INDEX_BMCAST 0xFF -+#define STA_REC_INDEX_NOT_FOUND 0xFE -+#define STA_WAIT_QUEUE_NUM 5 /* Number of SW queues in each STA_REC: AC0~AC4 */ -+#define SC_CACHE_INDEX_NUM 5 /* Number of SC caches in each STA_REC: AC0~AC4 */ -+ -+/* P2P related definitions */ -+#ifdef CFG_ENABLE_WIFI_DIRECT -+/* Moved from p2p_fsm.h */ -+#define WPS_ATTRI_MAX_LEN_DEVICE_NAME 32 /* 0x1011 */ -+#define P2P_GC_MAX_CACHED_SEC_DEV_TYPE_COUNT 8 /* NOTE(Kevin): Shall <= 16 */ -+#endif -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+#if ((MAX_NUM_OF_BUF_BLOCKS > 32) || (MAX_NUM_OF_BUF_BLOCKS <= 0)) -+#error > #define MAX_NUM_OF_MGT_BUF_BLOCKS : Out of boundary ! -+#elif MAX_NUM_OF_BUF_BLOCKS > 16 -+typedef UINT_32 BUF_BITMAP; -+#elif MAX_NUM_OF_BUF_BLOCKS > 8 -+typedef UINT_16 BUF_BITMAP; -+#else -+typedef UINT_8 BUF_BITMAP; -+#endif /* MAX_NUM_OF_MGT_BUF_BLOCKS */ -+ -+/* Control variable of TX management memory pool */ -+typedef struct _BUF_INFO_T { -+ PUINT_8 pucBuf; -+ -+#if CFG_DBG_MGT_BUF -+ UINT_32 u4AllocCount; -+ UINT_32 u4FreeCount; -+ UINT_32 u4AllocNullCount; -+#endif /* CFG_DBG_MGT_BUF */ -+ -+ BUF_BITMAP rFreeBlocksBitmap; -+ UINT_8 aucAllocatedBlockNum[MAX_NUM_OF_BUF_BLOCKS]; -+} BUF_INFO_T, *P_BUF_INFO_T; -+ -+/* Wi-Fi divides RAM into three types -+ * MSG: Mailbox message (Small size) -+ * BUF: HW DMA buffers (HIF/MAC) -+ */ -+typedef enum _ENUM_RAM_TYPE_T { -+ RAM_TYPE_MSG = 0, -+ RAM_TYPE_BUF -+} ENUM_RAM_TYPE_T, P_ENUM_RAM_TYPE_T; -+ -+typedef enum _ENUM_BUFFER_SOURCE_T { -+ BUFFER_SOURCE_HIF_TX0 = 0, -+ BUFFER_SOURCE_HIF_TX1, -+ BUFFER_SOURCE_MAC_RX, -+ BUFFER_SOURCE_MNG, -+ BUFFER_SOURCE_BCN, -+ BUFFER_SOURCE_NUM -+} ENUM_BUFFER_SOURCE_T, *P_ENUM_BUFFER_SOURCE_T; -+ -+typedef enum _ENUM_SEC_STATE_T { -+ SEC_STATE_INIT, -+ SEC_STATE_INITIATOR_PORT_BLOCKED, -+ SEC_STATE_RESPONDER_PORT_BLOCKED, -+ SEC_STATE_CHECK_OK, -+ SEC_STATE_SEND_EAPOL, -+ SEC_STATE_SEND_DEAUTH, -+ SEC_STATE_COUNTERMEASURE, -+ SEC_STATE_NUM -+} ENUM_SEC_STATE_T; -+ -+typedef struct _TSPEC_ENTRY_T { -+ UINT_8 ucStatus; -+ UINT_8 ucToken; /* Dialog Token in ADDTS_REQ or ADDTS_RSP */ -+ UINT_16 u2MediumTime; -+ UINT_32 u4TsInfo; -+ /* PARAM_QOS_TS_INFO rParamTsInfo; */ -+ /* Add other retained QoS parameters below */ -+} TSPEC_ENTRY_T, *P_TSPEC_ENTRY_T, TSPEC_TABLE_ENTRY_T, *P_TSPEC_TABLE_ENTRY_T; -+ -+typedef struct _SEC_INFO_T { -+ -+ ENUM_SEC_STATE_T ePreviousState; -+ ENUM_SEC_STATE_T eCurrentState; -+ -+ BOOLEAN fg2nd1xSend; -+ BOOLEAN fgKeyStored; -+ -+ UINT_8 aucStoredKey[64]; -+ -+ BOOLEAN fgAllowOnly1x; -+} SEC_INFO_T, *P_SEC_INFO_T; -+ -+#define MAX_NUM_CONCURRENT_FRAGMENTED_MSDUS 3 -+ -+#define UPDATE_BSS_RSSI_INTERVAL_SEC 3 /* Seconds */ -+ -+/* Fragment information structure */ -+typedef struct _FRAG_INFO_T { -+ UINT_16 u2NextFragSeqCtrl; -+ PUINT_8 pucNextFragStart; -+ P_SW_RFB_T pr1stFrag; -+ OS_SYSTIME rReceiveLifetimeLimit; /* The receive time of 1st fragment */ -+} FRAG_INFO_T, *P_FRAG_INFO_T; -+ -+typedef struct _STAT_CNT_INFO_FW_T { -+ UINT32 u4NumOfTx; /* number of packets sent from host */ -+ UINT32 u4NumOfTxOK; /* number of packets sent to air OK */ -+ UINT32 u4NumOfTxRetry; /* number of packets sent to air RETRY */ -+ UINT32 u4TxDoneAirTimeMax; /* maximum tx done air time */ -+ -+ UINT32 u4NumOfPtiRspTxOk; /* number of PTI RSP sent to air OK */ -+ UINT32 u4NumOfPtiRspTxErr; /* number of PTI RSP sent to air ERROR */ -+ -+ UINT32 u4NumOfTxErr; /* number of packets sent to air ERROR */ -+ -+ UINT32 u4NumOfRx; /* number of received packets */ -+ UINT32 u4NumOfPtiRspRx; /* number of PTI RSP rcv */ -+ -+#define STAT_CNT_INFO_TX_ERR_FLUSHED 0x00000001 -+#define STAT_CNT_INFO_TX_ERR_AGE_TIMEOUT 0x00000002 -+#define STAT_CNT_INFO_TX_ERR_MPDU 0x00000004 -+#define STAT_CNT_INFO_TX_ERR_RTS 0x00000010 -+#define STAT_CNT_INFO_TX_ERR_LIFETIME 0x00000020 -+#define STAT_CNT_INFO_TX_ERR_UNKNOWN 0x80000000 -+ UINT32 u4TxErrBitmap; /* TX error type */ -+ -+#define STAT_CNT_INFO_MAX_TX_RATE_OK_HIS_NUM 10 /* TX OK history */ -+ UINT8 aucTxRateOkHis[STAT_CNT_INFO_MAX_TX_RATE_OK_HIS_NUM][2]; -+ UINT32 u4TxRateOkHisId; -+ -+#define STAT_CNT_INFO_MAX_RATE_ID (32) /* MCS0 ~ MCS31 */ -+ UINT32 aucTxRateMap[STAT_CNT_INFO_MAX_RATE_ID]; -+ UINT32 aucRxRateMap[STAT_CNT_INFO_MAX_RATE_ID]; -+ -+ UINT8 aucStateHis[100][3]; /* State history */ -+ UINT32 u4StateHisId; /* history ID */ -+} STAT_CNT_INFO_FW_T; -+ -+typedef struct _STAT_CNT_INFO_DRV_T { -+ -+ UINT32 u4NumOfTxFromOs; /* number of packets sent from OS */ -+ UINT32 u4NumOfTxQueFull; /* number of packets dropped due to queue full */ -+ UINT32 u4NumOfTxToFw; /* number of packets sent to firmware */ -+ -+ STAT_CNT_INFO_FW_T rFw; -+} STAT_CNT_INFO_DRV_T; -+ -+/* Define STA record structure */ -+struct _STA_RECORD_T { -+ LINK_ENTRY_T rLinkEntry; -+ UINT_8 ucIndex; /* Not modify it except initializing */ -+ -+ BOOLEAN fgIsInUse; /* Indicate if this entry is in use or not */ -+ UINT_8 aucMacAddr[MAC_ADDR_LEN]; /* MAC address */ -+ -+ /* SAA/AAA */ -+ ENUM_AA_STATE_T eAuthAssocState; /* Store STATE Value used in SAA/AAA */ -+ UINT_8 ucAuthAssocReqSeqNum; -+ -+ ENUM_STA_TYPE_T eStaType; /* Indicate the role of this STA in -+ * the network (for example, P2P GO) -+ */ -+ -+ UINT_8 ucNetTypeIndex; /* ENUM_NETWORK_TYPE_INDEX_T */ -+ -+ UINT_8 ucStaState; /* STATE_1,2,3 */ -+ -+ UINT_8 ucPhyTypeSet; /* Available PHY Type Set of this peer -+ * (may deduced from received BSS_DESC_T) -+ */ -+ UINT_8 ucDesiredPhyTypeSet; /* The match result by AND operation of peer's -+ * PhyTypeSet and ours. -+ */ -+ BOOLEAN fgHasBasicPhyType; /* A flag to indicate a Basic Phy Type which -+ * is used to generate some Phy Attribute IE -+ * (e.g. capability, MIB) during association. -+ */ -+ UINT_8 ucNonHTBasicPhyType; /* The Basic Phy Type chosen among the -+ * ucDesiredPhyTypeSet. -+ */ -+ -+ UINT_16 u2CapInfo; /* For Infra Mode, to store Capability Info. from Association Resp(SAA). -+ * For AP Mode, to store Capability Info. from Association Req(AAA). -+ */ -+ UINT_16 u2AssocId; /* For Infra Mode, to store AID from Association Resp(SAA). -+ * For AP Mode, to store the Assigned AID(AAA). -+ */ -+ -+ UINT_16 u2ListenInterval; /* Listen Interval from STA(AAA) */ -+ -+ UINT_16 u2DesiredNonHTRateSet; /* Our Current Desired Rate Set after -+ * match with STA's Operational Rate Set -+ */ -+ -+ UINT_16 u2OperationalRateSet; /* Operational Rate Set of peer BSS */ -+ UINT_16 u2BSSBasicRateSet; /* Basic Rate Set of peer BSS */ -+ -+ BOOLEAN fgIsMerging; /* For IBSS Mode, to indicate that Merge is ongoing */ -+ -+ BOOLEAN fgDiagnoseConnection; /* For Infra/AP Mode, to diagnose the Connection with -+ * this peer by sending ProbeReq/Null frame */ -+ -+ /*------------------------------------------------------------------------------------------*/ -+ /* 802.11n HT capabilities when (prStaRec->ucPhyTypeSet & PHY_TYPE_BIT_HT) is true */ -+ /* They have the same definition with fields of information element */ -+ /*------------------------------------------------------------------------------------------*/ -+ UINT_8 ucMcsSet; /* MCS0~7 rate set of peer BSS */ -+ BOOLEAN fgSupMcs32; /* MCS32 is supported by peer BSS */ -+ UINT_16 u2HtCapInfo; /* HT cap info field by HT cap IE */ -+ UINT_8 ucAmpduParam; /* Field A-MPDU Parameters in HT cap IE */ -+ UINT_16 u2HtExtendedCap; /* HT extended cap field by HT cap IE */ -+ UINT_32 u4TxBeamformingCap; /* TX beamforming cap field by HT cap IE */ -+ UINT_8 ucAselCap; /* ASEL cap field by HT cap IE */ -+ -+ UINT_8 ucRCPI; /* RCPI of peer */ -+ -+ UINT_8 ucDTIMPeriod; /* Target BSS's DTIM Period, we use this -+ * value for setup Listen Interval -+ * TODO(Kevin): TBD -+ */ -+ UINT_8 ucAuthAlgNum; /* For Infra/AP Mode, the Auth Algorithm Num used in Authentication(SAA/AAA) */ -+ BOOLEAN fgIsReAssoc; /* For Infra/AP Mode, to indicate ReAssoc Frame was in used(SAA/AAA) */ -+ -+ UINT_8 ucTxAuthAssocRetryCount; /* For Infra Mode, the Retry Count of TX Auth/Assod Frame(SAA) */ -+ UINT_8 ucTxAuthAssocRetryLimit; /* For Infra Mode, the Retry Limit of TX Auth/Assod Frame(SAA) */ -+ -+ UINT_16 u2StatusCode; /* Status of Auth/Assoc Req */ -+ UINT_16 u2ReasonCode; /* Reason that been Deauth/Disassoc */ -+ -+ P_IE_CHALLENGE_TEXT_T prChallengeText; /* Point to an allocated buffer for storing Challenge Text -+ * for Shared Key Authentication -+ */ -+ -+ TIMER_T rTxReqDoneOrRxRespTimer; /* For Infra Mode, a timer used to send a timeout event -+ * while waiting for TX request done or RX response. -+ */ -+ -+ /*------------------------------------------------------------------------------------------*/ -+ /* Power Management related fields (for STA/ AP/ P2P/ BOW power saving mode) */ -+ /*------------------------------------------------------------------------------------------*/ -+ BOOLEAN fgSetPwrMgtBit; /* For Infra Mode, to indicate that outgoing frame need toggle -+ * the Pwr Mgt Bit in its Frame Control Field. -+ */ -+ -+ BOOLEAN fgIsInPS; /* For AP Mode, to indicate the client PS state(PM). -+ * TRUE: In PS Mode; FALSE: In Active Mode. */ -+ -+ BOOLEAN fgIsInPsPollSP; /* For Infra Mode, to indicate we've sent a PS POLL to AP and start -+ * the PS_POLL Service Period(LP) -+ */ -+ -+ BOOLEAN fgIsInTriggerSP; /* For Infra Mode, to indicate we've sent a Trigger Frame to AP and start -+ * the Delivery Service Period(LP) -+ */ -+ -+ UINT_8 ucBmpDeliveryAC; /* 0: AC0, 1: AC1, 2: AC2, 3: AC3 */ -+ -+ UINT_8 ucBmpTriggerAC; /* 0: AC0, 1: AC1, 2: AC2, 3: AC3 */ -+ -+ UINT_8 ucUapsdSp; /* Max SP length */ -+ -+ /*------------------------------------------------------------------------------------------*/ -+ -+ BOOLEAN fgIsRtsEnabled; -+ -+ OS_SYSTIME rUpdateTime; /* (4) System Timestamp of Successful TX and RX */ -+ -+ OS_SYSTIME rLastJoinTime; /* (4) System Timestamp of latest JOIN process */ -+ -+ UINT_8 ucJoinFailureCount; /* Retry Count of JOIN process */ -+ -+ LINK_T arStaWaitQueue[STA_WAIT_QUEUE_NUM]; /* For TXM to defer pkt forwarding to MAC TX DMA */ -+ -+ UINT_16 au2CachedSeqCtrl[TID_NUM + 1]; /* Duplicate removal for HT STA on a per-TID basis -+ * ("+1" is for MMPDU and non-QoS) -+ */ -+ -+#if 0 -+ /* RXM */ -+ P_RX_BA_ENTRY_T aprRxBaTable[TID_NUM]; -+ -+ /* TXM */ -+ P_TX_BA_ENTRY_T aprTxBaTable[TID_NUM]; -+#endif -+ -+ FRAG_INFO_T rFragInfo[MAX_NUM_CONCURRENT_FRAGMENTED_MSDUS]; -+ -+ SEC_INFO_T rSecInfo; /* The security state machine */ -+ -+ BOOLEAN fgPortBlock; /* The 802.1x Port Control flag */ -+ -+ BOOLEAN fgTransmitKeyExist; /* Unicast key exist for this STA */ -+ -+ UINT_8 ucWTEntry; -+ -+ BOOLEAN fgTxAmpduEn; /* Enable TX AMPDU for this Peer */ -+ BOOLEAN fgRxAmpduEn; /* Enable RX AMPDU for this Peer */ -+ -+ PUINT_8 pucAssocReqIe; -+ UINT_16 u2AssocReqIeLen; -+ /*------------------------------------------------------------------------------------------*/ -+ /* WMM/QoS related fields */ -+ /*------------------------------------------------------------------------------------------*/ -+ BOOLEAN fgIsQoS; /* If the STA is associated as a QSTA or QAP (for TX/RX) */ -+ BOOLEAN fgIsWmmSupported; /* If the peer supports WMM, set to TRUE (for association) */ -+ BOOLEAN fgIsUapsdSupported; /* Set according to the scan result (for association) */ -+ -+ /*------------------------------------------------------------------------------------------*/ -+ /* P2P related fields */ -+ /*------------------------------------------------------------------------------------------*/ -+#if CFG_ENABLE_WIFI_DIRECT -+ UINT_8 u2DevNameLen; -+ UINT_8 aucDevName[WPS_ATTRI_MAX_LEN_DEVICE_NAME]; -+ -+ UINT_8 aucDevAddr[MAC_ADDR_LEN]; /* P2P Device Address */ -+ -+ UINT_16 u2ConfigMethods; -+ -+ UINT_8 ucDeviceCap; -+ -+ UINT_8 ucSecondaryDevTypeCount; -+ -+ DEVICE_TYPE_T rPrimaryDevTypeBE; -+ -+ DEVICE_TYPE_T arSecondaryDevTypeBE[P2P_GC_MAX_CACHED_SEC_DEV_TYPE_COUNT]; -+#endif /* CFG_SUPPORT_P2P */ -+ -+ /*------------------------------------------------------------------------------------------*/ -+ /* QM related fields */ -+ /*------------------------------------------------------------------------------------------*/ -+ -+ UINT_8 ucFreeQuota; /* Per Sta flow controal. Valid when fgIsInPS is TRUE. -+ Change it for per Queue flow control */ -+ /* UINT_8 aucFreeQuotaPerQueue[NUM_OF_PER_STA_TX_QUEUES]; */ /* used in future */ -+ UINT_8 ucFreeQuotaForDelivery; -+ UINT_8 ucFreeQuotaForNonDelivery; -+#if CFG_ENABLE_PKT_LIFETIME_PROFILE && CFG_ENABLE_PER_STA_STATISTICS -+ UINT_32 u4TotalTxPktsNumber; -+ UINT_32 u4TotalTxPktsTime; -+ UINT_32 u4TotalTxPktsHifTime; -+ -+ UINT_32 u4MaxTxPktsTime; -+ UINT_32 u4MaxTxPktsHifTime; -+ -+ UINT_32 u4ThresholdCounter; -+ UINT_32 u4EnqeueuCounter; -+ UINT_32 u4DeqeueuCounter; -+ UINT_32 u4PrevIntCount; -+ UINT_32 u4ThisIntCount; -+ UINT_32 u4NoTcResource; -+#endif -+ -+#if 1 -+ /*------------------------------------------------------------------------------------------*/ -+ /* To be removed, this is to make que_mgt compilation success only */ -+ /*------------------------------------------------------------------------------------------*/ -+ /* When this STA_REC is in use, set to TRUE. */ -+ BOOLEAN fgIsValid; -+ -+ /* Per-STA Queues: [0] AC0, [1] AC1, [2] AC2, [3] AC3, [4] 802.1x */ -+ QUE_T arTxQueue[NUM_OF_PER_STA_TX_QUEUES]; -+ -+ /* When this STA is in PS Mode, set to TRUE. */ -+ /* BOOLEAN fgIsPS; */ -+ -+ /* When this STA enters Power-Saving, FW will notify the driver with a Session ID */ -+ UINT_8 ucPsSessionID; -+ -+ BOOLEAN fgIsAp; -+ -+ /* Reorder Parameter reference table */ -+ P_RX_BA_ENTRY_T aprRxReorderParamRefTbl[CFG_RX_MAX_BA_TID_NUM]; -+#endif -+ -+#if CFG_SUPPORT_802_11V_TIMING_MEASUREMENT -+ TIMINGMSMT_PARAM_T rWNMTimingMsmt; -+#endif -+ -+#if (CFG_SUPPORT_TDLS == 1) -+ BOOLEAN fgTdlsIsProhibited; /* TRUE: AP prohibits TDLS links */ -+ BOOLEAN fgTdlsIsChSwProhibited; /* TRUE: AP prohibits TDLS chan switch */ -+ -+ BOOLEAN flgTdlsIsInitiator; /* TRUE: the peer is the initiator */ -+ IE_HT_CAP_T rTdlsHtCap; /* temp to queue HT capability element */ -+ BOOLEAN fgTdlsInSecurityMode; /* TRUE: security mode */ -+ PARAM_KEY_T rTdlsKeyTemp; /* temp to queue the key information */ -+ -+#define TDLS_SETUP_TIMEOUT_SEC 5 /* unit: second */ -+ OS_SYSTIME rTdlsSetupStartTime; /* time when link setup is started */ -+ -+ OS_SYSTIME rTdlsTxQuotaEmptyTime; /* time when TX quota is 0 */ -+ -+ STAT_CNT_INFO_DRV_T rTdlsStatistics; -+#endif /* CFG_SUPPORT_TDLS */ -+ -+#if (CFG_SUPPORT_STATISTICS == 1) -+#define STATS_ENV_TIMEOUT_SEC 10 /* unit: second */ -+ OS_SYSTIME rStatsEnvTxPeriodLastTime; -+ -+#define STATS_ENV_TX_CNT_REPORT_TRIGGER 2500 /* 6Mbps */ -+#define STATS_ENV_TX_CNT_REPORT_TRIGGER_SEC 5 /* unit: second */ -+ OS_SYSTIME rStatsEnvTxLastTime; -+ UINT32 u4StatsEnvTxCnt; -+ -+ UINT32 u4NumOfNoTxQuota; -+ -+ UINT32 u4RxReorderFallAheadCnt; -+ UINT32 u4RxReorderFallBehindCnt; -+ UINT32 u4RxReorderHoleCnt; -+ UINT32 u4RxReorderHoleTimeoutCnt; -+ -+ UINT32 u4StatsRxPassToOsCnt; -+ -+ /* delay from HIF to pass to OS: us */ -+#define STATS_STAY_INT_BYTE_THRESHOLD 500 -+ UINT32 u4StayIntMaxRx[3], u4StayIntMinRx[3], u4StayIntAvgRx[3]; -+ -+ UINT8 ucStatsGenDisplayCnt; -+#endif /* CFG_SUPPORT_STATISTICS */ -+}; -+ -+#if 0 -+/* use nic_tx.h instead */ -+/* MSDU_INFO and SW_RFB structure */ -+typedef struct _MSDU_INFO_T { -+ -+ /* 4 ----------------MSDU_INFO and SW_RFB Common Fields------------------ */ -+ -+ LINK_ENTRY_T rLinkEntry; -+ PUINT_8 pucBuffer; /* Pointer to the associated buffer */ -+ -+ UINT_8 ucBufferSource; /* HIF TX0, HIF TX1, MAC RX, or MNG Pool */ -+ UINT_8 ucNetworkTypeIndex; /* Network type index that this TX packet is assocaited with */ -+ UINT_8 ucTC; /* 0 to 5 (used by HIF TX to increment the corresponding TC counter) */ -+ UINT_8 ucTID; /* Traffic Identification */ -+ -+ BOOLEAN fgIs802_11Frame; /* Set to TRUE for 802.11 frame */ -+ UINT_8 ucMacHeaderLength; -+ UINT_16 u2PayloadLength; -+ PUINT_8 pucMacHeader; /* 802.11 header */ -+ PUINT_8 pucPayload; /* 802.11 payload */ -+ -+ OS_SYSTIME rArrivalTime; /* System Timestamp (4) */ -+ P_STA_RECORD_T prStaRec; -+ -+#if CFG_PROFILE_BUFFER_TRACING -+ ENUM_BUFFER_ACTIVITY_TYPE_T eActivity[2]; -+ UINT_32 rActivityTime[2]; -+#endif -+#if DBG && CFG_BUFFER_FREE_CHK -+ BOOLEAN fgBufferInSource; -+#endif -+ -+ UINT_8 ucControlFlag; /* For specify some Control Flags, e.g. Basic Rate */ -+ -+ /* 4 -----------------------Non-Common ------------------------- */ -+ /* TODO: move flags to ucControlFlag */ -+ -+ BOOLEAN fgIs1xFrame; /* Set to TRUE for 802.1x frame */ -+ -+ /* TXM: For TX Done handling, callback function & parameter (5) */ -+ BOOLEAN fgIsTxFailed; /* Set to TRUE if transmission failure */ -+ -+ PFN_TX_DONE_HANDLER pfTxDoneHandler; -+ -+ UINT_64 u8TimeStamp; /* record the TX timestamp */ -+ -+ /* TXM: For PS forwarding control (per-STA flow control) */ -+ UINT_8 ucPsForwardingType; /* Delivery-enabled, non-delivery-enabled, non-PS */ -+ UINT_8 ucPsSessionID; /* The Power Save session id for PS forwarding control */ -+ -+ /* TXM: For MAC TX DMA operations */ -+ UINT_8 ucMacTxQueIdx; /* MAC TX queue: AC0-AC6, BCM, or BCN */ -+ BOOLEAN fgNoAck; /* Set to true if Ack is not required for this packet */ -+ BOOLEAN fgBIP; /* Set to true if BIP is used for this packet */ -+ UINT_8 ucFragTotalCount; -+ UINT_8 ucFragFinishedCount; -+ UINT_16 u2FragThreshold; /* Fragmentation threshold without WLAN Header & FCS */ -+ BOOLEAN fgFixedRate; /* If a fixed rate is used, set to TRUE. */ -+ UINT_8 ucFixedRateCode; /* The rate code copied to MAC TX Desc */ -+ UINT_8 ucFixedRateRetryLimit; /* The retry limit when a fixed rate is used */ -+ BOOLEAN fgIsBmcQueueEnd; /* Set to true if this packet is the end of BMC */ -+ -+ /* TXM: For flushing ACL frames */ -+ UINT_16 u2PalLLH; /* 802.11 PAL LLH */ -+ /* UINT_16 u2LLH; */ -+ UINT_16 u2ACLSeq; /* u2LLH+u2ACLSeq for AM HCI flush ACL frame */ -+ -+ /* TXM for retransmitting a flushed packet */ -+ BOOLEAN fgIsSnAssigned; -+ UINT_16 u2SequenceNumber; /* To remember the Sequence Control field of this MPDU */ -+ -+} MSDU_INFO_T, *P_MSDU_INFO_T; -+#endif -+ -+#if 0 -+/* nic_rx.h */ -+typedef struct _SW_RFB_T { -+ -+ /* 4 ----------------MSDU_INFO and SW_RFB Common Fields------------------ */ -+ -+ LINK_ENTRY_T rLinkEntry; -+ PUINT_8 pucBuffer; /* Pointer to the associated buffer */ -+ -+ UINT_8 ucBufferSource; /* HIF TX0, HIF TX1, MAC RX, or MNG Pool */ -+ UINT_8 ucNetworkTypeIndex; /* Network type index that this TX packet is assocaited with */ -+ UINT_8 ucTC; /* 0 to 5 (used by HIF TX to increment the corresponding TC counter) */ -+ UINT_8 ucTID; /* Traffic Identification */ -+ -+ BOOLEAN fgIs802_11Frame; /* Set to TRUE for 802.11 frame */ -+ UINT_8 ucMacHeaderLength; -+ UINT_16 u2PayloadLength; -+ PUINT_8 pucMacHeader; /* 802.11 header */ -+ PUINT_8 pucPayload; /* 802.11 payload */ -+ -+ OS_SYSTIME rArrivalTime; /* System Timestamp (4) */ -+ P_STA_RECORD_T prStaRec; -+ -+#if CFG_PROFILE_BUFFER_TRACING -+ ENUM_BUFFER_ACTIVITY_TYPE_T eActivity[2]; -+ UINT_32 rActivityTime[2]; -+#endif -+#if DBG && CFG_BUFFER_FREE_CHK -+ BOOLEAN fgBufferInSource; -+#endif -+ -+ UINT_8 ucControlFlag; /* For specify some Control Flags, e.g. Basic Rate */ -+ -+ /* 4 -----------------------Non-Common ------------------------- */ -+ -+ /* For composing the HIF RX Header (TODO: move flags to ucControlFlag) */ -+ PUINT_8 pucHifRxPacket; /* Pointer to the Response packet to HIF RX0 or RX1 */ -+ UINT_16 u2HifRxPacketLength; -+ UINT_8 ucHeaderOffset; -+ UINT_8 ucHifRxPortIndex; -+ -+ UINT_16 u2SequenceControl; -+ BOOLEAN fgIsA4Frame; /* (For MAC RX packet parsing) set to TRUE if 4 addresses are present */ -+ BOOLEAN fgIsBAR; -+ BOOLEAN fgIsQoSData; -+ BOOLEAN fgIsAmsduSubframe; /* Set to TRUE for A-MSDU Subframe */ -+ -+ /* For HIF RX DMA Desc */ -+ BOOLEAN fgTUChecksumCheckRequired; -+ BOOLEAN fgIPChecksumCheckRequired; -+ UINT_8 ucEtherTypeOffset; -+ -+} SW_RFB_T, *P_SW_RFB_T; -+#endif -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+P_MSDU_INFO_T cnmMgtPktAlloc(IN P_ADAPTER_T prAdapter, IN UINT_32 u4Length); -+ -+VOID cnmMgtPktFree(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); -+ -+VOID cnmMemInit(IN P_ADAPTER_T prAdapter); -+ -+PVOID cnmMemAlloc(IN P_ADAPTER_T prAdapter, IN ENUM_RAM_TYPE_T eRamType, IN UINT_32 u4Length); -+ -+VOID cnmMemFree(IN P_ADAPTER_T prAdapter, IN PVOID pvMemory); -+ -+VOID cnmStaRecInit(IN P_ADAPTER_T prAdapter); -+ -+VOID cnmStaRecUninit(IN P_ADAPTER_T prAdapter); -+ -+P_STA_RECORD_T cnmStaRecAlloc(IN P_ADAPTER_T prAdapter, IN UINT_8 ucNetTypeIndex); -+ -+VOID cnmStaRecFree(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN BOOLEAN fgSyncToChip); -+ -+VOID cnmStaFreeAllStaByNetType(P_ADAPTER_T prAdapter, ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, BOOLEAN fgSyncToChip); -+ -+P_STA_RECORD_T cnmGetStaRecByIndex(IN P_ADAPTER_T prAdapter, IN UINT_8 ucIndex); -+ -+P_STA_RECORD_T cnmGetStaRecByAddress(IN P_ADAPTER_T prAdapter, IN UINT_8 ucNetTypeIndex, IN UINT_8 aucPeerMACAddress[]); -+ -+VOID cnmStaRecResetStatus(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex); -+ -+VOID cnmStaRecChangeState(IN P_ADAPTER_T prAdapter, IN OUT P_STA_RECORD_T prStaRec, IN UINT_8 ucNewState); -+ -+P_STA_RECORD_T -+cnmStaTheTypeGet(P_ADAPTER_T prAdapter, -+ ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, ENUM_STA_TYPE_T eStaType, UINT32 *pu4StartIdx); -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+#ifndef _lint -+/* Kevin: we don't have to call following function to inspect the data structure. -+ * It will check automatically while at compile time. -+ * We'll need this for porting driver to different RTOS. -+ */ -+static inline VOID cnmMemDataTypeCheck(VOID) -+{ -+#if 0 -+ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSDU_INFO_T, rLinkEntry) == 0); -+ -+ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSDU_INFO_T, rLinkEntry) == OFFSET_OF(SW_RFB_T, rLinkEntry)); -+ -+ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSDU_INFO_T, pucBuffer) == OFFSET_OF(SW_RFB_T, pucBuffer)); -+ -+ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSDU_INFO_T, ucBufferSource) == OFFSET_OF(SW_RFB_T, ucBufferSource)); -+ -+ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSDU_INFO_T, pucMacHeader) == OFFSET_OF(SW_RFB_T, pucMacHeader)); -+ -+ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSDU_INFO_T, ucMacHeaderLength) == -+ OFFSET_OF(SW_RFB_T, ucMacHeaderLength)); -+ -+ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSDU_INFO_T, pucPayload) == OFFSET_OF(SW_RFB_T, pucPayload)); -+ -+ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSDU_INFO_T, u2PayloadLength) == OFFSET_OF(SW_RFB_T, u2PayloadLength)); -+ -+ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSDU_INFO_T, prStaRec) == OFFSET_OF(SW_RFB_T, prStaRec)); -+ -+ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSDU_INFO_T, ucNetworkTypeIndex) == -+ OFFSET_OF(SW_RFB_T, ucNetworkTypeIndex)); -+ -+ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSDU_INFO_T, ucTID) == OFFSET_OF(SW_RFB_T, ucTID)); -+ -+ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSDU_INFO_T, fgIs802_11Frame) == OFFSET_OF(SW_RFB_T, fgIs802_11Frame)); -+ -+ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSDU_INFO_T, ucControlFlag) == OFFSET_OF(SW_RFB_T, ucControlFlag)); -+ -+ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSDU_INFO_T, rArrivalTime) == OFFSET_OF(SW_RFB_T, rArrivalTime)); -+ -+ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSDU_INFO_T, ucTC) == OFFSET_OF(SW_RFB_T, ucTC)); -+ -+#if CFG_PROFILE_BUFFER_TRACING -+ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSDU_INFO_T, eActivity[0]) == OFFSET_OF(SW_RFB_T, eActivity[0])); -+ -+ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSDU_INFO_T, rActivityTime[0]) == -+ OFFSET_OF(SW_RFB_T, rActivityTime[0])); -+#endif -+ -+#if DBG && CFG_BUFFER_FREE_CHK -+ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(MSDU_INFO_T, fgBufferInSource) == -+ OFFSET_OF(SW_RFB_T, fgBufferInSource)); -+#endif -+ -+ DATA_STRUCT_INSPECTING_ASSERT(OFFSET_OF(STA_RECORD_T, rLinkEntry) == 0); -+ -+ return; -+#endif -+} -+#endif /* _lint */ -+ -+#endif /* _CNM_MEM_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/cnm_scan.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/cnm_scan.h -new file mode 100644 -index 000000000000..cc5d0fa1adfc ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/cnm_scan.h -@@ -0,0 +1,169 @@ -+/* -+** Id: @(#) -+*/ -+ -+/*! \file "cnm_scan.h" -+ \brief -+ -+*/ -+ -+/* -+** Log: cnm_scan.h -+ * -+ * 09 03 2010 kevin.huang -+ * NULL -+ * Refine #include sequence and solve recursive/nested #include issue -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 07 05 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * remove unused definitions. -+ * -+ * 07 01 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * implementation of DRV-SCN and related mailbox message handling. -+ * -+ * 06 07 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * merge cnm_scan.h and hem_mbox.h -+ * -+ * 05 12 2010 kevin.huang -+ * [BORA00000794][WIFISYS][New Feature]Power Management Support -+ * Add Power Management - Legacy PS-POLL support. -+ * -+ * 03 30 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Support 2.4G OBSS scan -+ * -+ * 03 16 2010 kevin.huang -+ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support -+ * Add AdHoc Mode -+ * -+ * 03 10 2010 kevin.huang -+ * [BORA00000654][WIFISYS][New Feature] CNM Module - Ch Manager Support -+ * -+ * * * * Add Channel Manager for arbitration of JOIN and SCAN Req -+ * -+ * 02 23 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Add support scan channel 1~14 and update scan result's frequency infou1rwduu`wvpghlqg|n`slk+mpdkb -+ * -+ * 02 04 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Add AAA Module Support, Revise Net Type to Net Type Index for array lookup -+ * -+ * Nov 18 2009 mtk01104 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Add function prototype of cnmScanInit() -+ * -+ * Nov 5 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * -+** -+*/ -+ -+#ifndef _CNM_SCAN_H -+#define _CNM_SCAN_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+#define SCN_CHANNEL_DWELL_TIME_MIN_MSEC 12 -+#define SCN_CHANNEL_DWELL_TIME_EXT_MSEC 98 -+ -+#define SCN_TOTAL_PROBEREQ_NUM_FOR_FULL 3 -+#define SCN_SPECIFIC_PROBEREQ_NUM_FOR_FULL 1 -+ -+#define SCN_TOTAL_PROBEREQ_NUM_FOR_PARTIAL 2 -+#define SCN_SPECIFIC_PROBEREQ_NUM_FOR_PARTIAL 1 -+ -+#define SCN_INTERLACED_CHANNEL_GROUPS_NUM 3 /* Used by partial scan */ -+ -+#define SCN_PARTIAL_SCAN_NUM 3 -+ -+#define SCN_PARTIAL_SCAN_IDLE_MSEC 100 -+ -+#define MAXIMUM_OPERATION_CHANNEL_LIST 46 -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+/* The type of Scan Source */ -+typedef enum _ENUM_SCN_REQ_SOURCE_T { -+ SCN_REQ_SOURCE_HEM = 0, -+ SCN_REQ_SOURCE_NET_FSM, -+ SCN_REQ_SOURCE_ROAMING, /* ROAMING Module is independent of AIS FSM */ -+ SCN_REQ_SOURCE_OBSS, /* 2.4G OBSS scan */ -+ SCN_REQ_SOURCE_NUM -+} ENUM_SCN_REQ_SOURCE_T, *P_ENUM_SCN_REQ_SOURCE_T; -+ -+typedef enum _ENUM_SCAN_PROFILE_T { -+ SCAN_PROFILE_FULL = 0, -+ SCAN_PROFILE_PARTIAL, -+ SCAN_PROFILE_VOIP, -+ SCAN_PROFILE_FULL_2G4, -+ SCAN_PROFILE_NUM -+} ENUM_SCAN_PROFILE_T, *P_ENUM_SCAN_PROFILE_T; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+#if 0 -+VOID cnmScanInit(VOID); -+ -+VOID cnmScanRunEventScanRequest(IN P_MSG_HDR_T prMsgHdr); -+ -+BOOLEAN cnmScanRunEventScanAbort(IN P_MSG_HDR_T prMsgHdr); -+ -+VOID cnmScanProfileSelection(VOID); -+ -+VOID cnmScanProcessStart(VOID); -+ -+VOID cnmScanProcessStop(VOID); -+ -+VOID cnmScanRunEventReqAISAbsDone(IN P_MSG_HDR_T prMsgHdr); -+ -+VOID cnmScanRunEventCancelAISAbsDone(IN P_MSG_HDR_T prMsgHdr); -+ -+VOID cnmScanPartialScanTimeout(UINT_32 u4Param); -+ -+VOID cnmScanRunEventScnFsmComplete(IN P_MSG_HDR_T prMsgHdr); -+#endif -+ -+#endif /* _CNM_SCAN_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/cnm_timer.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/cnm_timer.h -new file mode 100644 -index 000000000000..a2ed9cd02fed ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/cnm_timer.h -@@ -0,0 +1,235 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/mgmt/cnm_timer.h#1 -+*/ -+ -+/*! \file cnm_timer.h -+ \brief Declaration of timer obj and related timer macro for setup time out -+ event. -+ -+ In this file we declare the timer object and provide several macro for -+ Protocol functional blocks to setup their own time out event. -+*/ -+ -+/* -+** Log: cnm_timer.h -+ * -+ * 12 13 2011 cm.chang -+ * [WCXRP00001136] [All Wi-Fi][Driver] Add wake lock for pending timer -+ * Add wake lock if timer timeout value is smaller than 5 seconds -+ * -+ * 09 03 2010 kevin.huang -+ * NULL -+ * Refine #include sequence and solve recursive/nested #include issue -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 08 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * cnm_timer has been migrated. -+ * -+ * 06 08 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add hem_mbox.c and cnm_mem.h (but disabled some feature) for further migration -+ * -+ * 06 07 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * merge cnm_scan.h and hem_mbox.h -+ * -+ * 06 07 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * merge wifi_var.h, precomp.h, cnm_timer.h (data type only) -+ * -+ * 06 04 2010 george.huang -+ * [BORA00000678][MT6620]WiFi LP integration -+ * [PM] Support U-APSD for STA mode -+ * -+ * 04 24 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Return timer token back to COS when entering wait off state -+ * -+ * 01 08 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Support longer timeout interval to 45 days from 65secu1rwduu`wvpghlqg|fh+fmdkb -+ * -+ * 01 06 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Fix system time is 32KHz instead of 1ms -+ * -+ * Nov 23 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * add the copy time function -+ * -+ * Nov 5 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Fix LINT warnning -+ * -+ * Oct 28 2009 mtk01104 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * -+** -+*/ -+ -+#ifndef _CNM_TIMER_H -+#define _CNM_TIMER_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+#undef MSEC_PER_SEC -+#define MSEC_PER_SEC 1000 -+#undef USEC_PER_MSEC -+#define USEC_PER_MSEC 1000 -+#define USEC_PER_TU 1024 /* microsecond */ -+ -+#define MSEC_PER_MIN (60 * MSEC_PER_SEC) -+ -+#define MGMT_MAX_TIMEOUT_INTERVAL ((UINT_32)0x7fffffff) -+ -+#define WAKE_LOCK_MAX_TIME 5 /* Unit: sec */ -+ -+/* If WAKE_LOCK_MAX_TIME is too large, the whole system may always keep awake -+ * because of periodic timer of OBSS scanning -+ */ -+#if (WAKE_LOCK_MAX_TIME >= OBSS_SCAN_MIN_INTERVAL) -+#error WAKE_LOCK_MAX_TIME is too large -+#endif -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+typedef VOID(*PFN_MGMT_TIMEOUT_FUNC) (P_ADAPTER_T, ULONG); -+ -+typedef struct _TIMER_T { -+ LINK_ENTRY_T rLinkEntry; -+ OS_SYSTIME rExpiredSysTime; -+ UINT_16 u2Minutes; -+ UINT_16 u2Reserved; -+ ULONG ulData; -+ PFN_MGMT_TIMEOUT_FUNC pfMgmtTimeOutFunc; -+} TIMER_T, *P_TIMER_T; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+/* Check if time "a" is before time "b" */ -+/* In 32-bit variable, 0x00000001~0x7fffffff -> positive number, -+ * 0x80000000~0xffffffff -> negative number -+ */ -+#define TIME_BEFORE_64bit(a, b) (a < b) -+ -+#define TIME_BEFORE(a, b) ((UINT_32)((UINT_32)(a) - (UINT_32)(b)) > 0x7fffffff) -+ -+/* #define TIME_BEFORE(a,b) ((INT_32)((INT_32)(b) - (INT_32)(a)) > 0) -+ * may cause UNexpect result between Free build and Check build for WinCE -+ */ -+ -+#define TIME_AFTER(a, b) TIME_BEFORE(b, a) -+ -+#define SYSTIME_TO_SEC(_systime) ((_systime) / KAL_HZ) -+#define SEC_TO_SYSTIME(_sec) ((_sec) * KAL_HZ) -+ -+/* The macros to convert second & millisecond */ -+#define MSEC_TO_SEC(_msec) ((_msec) / MSEC_PER_SEC) -+#define SEC_TO_MSEC(_sec) ((UINT_32)(_sec) * MSEC_PER_SEC) -+ -+/* The macros to convert millisecond & microsecond */ -+#define USEC_TO_MSEC(_usec) ((_usec) / USEC_PER_MSEC) -+#define MSEC_TO_USEC(_msec) ((UINT_32)(_msec) * USEC_PER_MSEC) -+ -+/* The macros to convert TU & microsecond, TU & millisecond */ -+#define TU_TO_USEC(_tu) ((_tu) * USEC_PER_TU) -+#define TU_TO_MSEC(_tu) USEC_TO_MSEC(TU_TO_USEC(_tu)) -+ -+/* The macros to convert TU & & OS system time, round up by 0.5 */ -+#define TU_TO_SYSTIME(_tu) MSEC_TO_SYSTIME(TU_TO_MSEC(_tu)) -+#define SYSTIME_TO_TU(_systime) \ -+ ((SYSTIME_TO_USEC(_systime) + ((USEC_PER_TU / 2) - 1)) / USEC_PER_TU) -+ -+/* The macros to convert OS system time & microsecond */ -+#define SYSTIME_TO_USEC(_systime) (SYSTIME_TO_MSEC(_systime) * USEC_PER_MSEC) -+ -+/* The macro to get the current OS system time */ -+#define GET_CURRENT_SYSTIME(_systime_p) {*(_systime_p) = kalGetTimeTick(); } -+ -+/* The macro to copy the system time */ -+#define COPY_SYSTIME(_destTime, _srcTime) {(_destTime) = (_srcTime); } -+ -+/* The macro to get the system time difference between t1 and t2 (t1 - t2) */ -+/* #define GET_SYSTIME_DIFFERENCE(_time1, _time2, _diffTime) \ -+ (_diffTime) = (_time1) - (_time2) */ -+ -+/* The macro to check for the expiration, if TRUE means _currentTime >= _expirationTime */ -+#define CHECK_FOR_EXPIRATION(_currentTime, _expirationTime) \ -+ (((UINT_32)(_currentTime) - (UINT_32)(_expirationTime)) <= 0x7fffffffUL) -+ -+/* The macro to check for the timeout */ -+#define CHECK_FOR_TIMEOUT(_currentTime, _timeoutStartingTime, _timeout) \ -+ CHECK_FOR_EXPIRATION((_currentTime), ((_timeoutStartingTime) + (_timeout))) -+ -+/* The macro to set the expiration time with a specified timeout *//* Watch out for round up. */ -+#define SET_EXPIRATION_TIME(_expirationTime, _timeout) \ -+ { \ -+ GET_CURRENT_SYSTIME(&(_expirationTime)); \ -+ (_expirationTime) += (OS_SYSTIME)(_timeout); \ -+ } -+ -+#define timerRenewTimer(adapter, tmr, interval) \ -+ timerStartTimer(adapter, tmr, interval, (tmr)->function, (tmr)->data) -+ -+#define MGMT_INIT_TIMER(_adapter_p, _timer, _callbackFunc) \ -+ timerInitTimer(_adapter_p, &(_timer), (ULONG)(_callbackFunc)) -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+VOID cnmTimerInitialize(IN P_ADAPTER_T prAdapter); -+ -+VOID cnmTimerDestroy(IN P_ADAPTER_T prAdapter); -+ -+VOID -+cnmTimerInitTimer(IN P_ADAPTER_T prAdapter, IN P_TIMER_T prTimer, IN PFN_MGMT_TIMEOUT_FUNC pfFunc, IN ULONG ulData); -+ -+VOID cnmTimerStopTimer(IN P_ADAPTER_T prAdapter, IN P_TIMER_T prTimer); -+ -+VOID cnmTimerStartTimer(IN P_ADAPTER_T prAdapter, IN P_TIMER_T prTimer, IN UINT_32 u4TimeoutMs); -+ -+VOID cnmTimerDoTimeOutCheck(IN P_ADAPTER_T prAdapter); -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+static inline INT_32 timerPendingTimer(IN P_TIMER_T prTimer) -+{ -+ ASSERT(prTimer); -+ -+ return prTimer->rLinkEntry.prNext != NULL; -+} -+ -+#endif /* _CNM_TIMER_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/hem_mbox.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/hem_mbox.h -new file mode 100644 -index 000000000000..868de4a6c40a ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/hem_mbox.h -@@ -0,0 +1,446 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/mgmt/hem_mbox.h#2 -+*/ -+ -+/*! \file hem_mbox.h -+ \brief -+ -+*/ -+ -+/* -+** Log: hem_mbox.h -+** -+** 07 26 2012 yuche.tsai -+** [ALPS00324337] [ALPS.JB][Hot-Spot] Driver update for Hot-Spot -+** Update driver code of ALPS.JB for hot-spot. -+** -+** 07 19 2012 yuche.tsai -+** NULL -+** Code update for JB. -+ * -+ * 03 02 2012 terry.wu -+ * NULL -+ * Sync CFG80211 modification from branch 2,2. -+ * -+ * 07 18 2011 cp.wu -+ * [WCXRP00000858] [MT5931][Driver][Firmware] Add support for scan to search for -+ * more than one SSID in a single scanning request -+ * add framework in driver domain for supporting new SCAN_REQ_V2 for more than 1 SSID -+ * support as well as uProbeDelay in NDIS 6.x driver model -+ * -+ * 06 07 2011 yuche.tsai -+ * [WCXRP00000696] [Volunteer Patch][MT6620][Driver] Infinite loop issue when RX invitation response. -+ * cnm_timer[WCXRP00000763] [Volunteer Patch][MT6620][Driver] RX Service Discovery Frame under AP mode Issue -+ * Add invitation support. -+ * -+ * 06 02 2011 cp.wu -+ * [WCXRP00000681] [MT5931][Firmware] HIF code size reduction -+ * eliminate unused parameters for SAA-FSM -+ * -+ * 01 26 2011 cm.chang -+ * [WCXRP00000395] [MT6620 Wi-Fi][Driver][FW] Search STA_REC with additional net type index argument -+ * Allocate system RAM if fixed message or mgmt buffer is not available -+ * -+ * 11 08 2010 cm.chang -+ * [WCXRP00000169] [MT6620 Wi-Fi][Driver][FW] Remove unused CNM recover message ID -+ * Remove CNM channel reover message ID -+ * -+ * 09 16 2010 cm.chang -+ * NULL -+ * Remove unused message ID -+ * -+ * 09 03 2010 kevin.huang -+ * NULL -+ * Refine #include sequence and solve recursive/nested #include issue -+ * -+ * 08 30 2010 cp.wu -+ * NULL -+ * eliminate klockwork errors -+ * -+ * 08 25 2010 george.huang -+ * NULL -+ * update OID/ registry control path for PM related settings -+ * -+ * 08 23 2010 chinghwa.yu -+ * NULL -+ * Update for BOW. -+ * -+ * 08 16 2010 cp.wu -+ * NULL -+ * add interface for RLM to trigger OBSS-SCAN. -+ * -+ * 08 11 2010 yuche.tsai -+ * NULL -+ * Add some message ID for P2P FSM under provisioning phase. -+ * -+ * 08 11 2010 yuche.tsai -+ * NULL -+ * Add Message Event ID for P2P Module. -+ * -+ * 08 05 2010 yuche.tsai -+ * NULL -+ * Check-in P2P Device Discovery Feature. -+ * -+ * 08 04 2010 cp.wu -+ * NULL -+ * remove unused mailbox message definitions. -+ * -+ * 08 02 2010 yuche.tsai -+ * NULL -+ * P2P Group Negotiation Code Check in. -+ * -+ * 07 19 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration. -+ * message table should not be commented out by compilation option without modifying header file -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 07 08 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Rename MID_MNY_CNM_CH_RELEASE to MID_MNY_CNM_CH_ABORT -+ * -+ * 07 01 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * AIS-FSM integration with CNM channel request messages -+ * -+ * 07 01 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * implementation of DRV-SCN and related mailbox message handling. -+ * -+ * 07 01 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Modify CNM message handler for new flow -+ * -+ * 06 18 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Provide cnmMgtPktAlloc() and alloc/free function of msg/buf -+ * -+ * 06 14 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * restore utility function invoking via hem_mbox to direct calls -+ * -+ * 06 11 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * auth.c is migrated. -+ * -+ * 06 10 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add buildable & linkable ais_fsm.c -+ * -+ * related reference are still waiting to be resolved -+ * -+ * 06 09 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add definitions for module migration. -+ * -+ * 06 08 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * hem_mbox is migrated. -+ * -+ * 06 07 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * merge cnm_scan.h and hem_mbox.h -+ * -+ * 05 12 2010 kevin.huang -+ * [BORA00000794][WIFISYS][New Feature]Power Management Support -+ * Add Power Management - Legacy PS-POLL support. -+ * -+ * 04 29 2010 tehuang.liu -+ * [BORA00000605][WIFISYS] Phase3 Integration -+ * Removed MID_RXM_MQM_QOS_ACTION_FRAME -+ * -+ * 04 29 2010 tehuang.liu -+ * [BORA00000605][WIFISYS] Phase3 Integration -+ * Removed MID_RXM_MQM_BA_ACTION_FRAME -+ * -+ * 03 30 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Support 2.4G OBSS scan -+ * -+ * 03 16 2010 kevin.huang -+ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support -+ * Add AdHoc Mode -+ * -+ * 03 10 2010 kevin.huang -+ * [BORA00000654][WIFISYS][New Feature] CNM Module - Ch Manager Support -+ * -+ * * * * * Add Channel Manager for arbitration of JOIN and SCAN Req -+ * -+ * 03 05 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Develop partial DPD code -+ * -+ * 02 11 2010 tehuang.liu -+ * [BORA00000569][WIFISYS] Phase 2 Integration Test -+ * Added MID_RXM_MQM_QOS_ACTION_FRAME for RXM to indicate QoS Action frames to MQM -+ * -+ * 01 11 2010 kevin.huang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Add Deauth and Disassoc Handler -+ * -+ * Dec 7 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Rename the parameter of mboxDummy() -+ * -+ * Dec 2 2009 MTK02468 -+ * [BORA00000337] To check in codes for FPGA emulation -+ * Added MID_RXM_MQM_BA_ACTION_FRAME -+ * -+ * Nov 24 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Remove Dummy MSG ID -+ * -+ * Nov 23 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Add JOIN REQ related MSG ID -+ * -+ * Nov 16 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Add AIS ABORT MSG ID -+ * -+ * Nov 5 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Add SCN MSG IDs -+ * -+ * Oct 28 2009 mtk01104 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * -+*/ -+ -+#ifndef _HEM_MBOX_H -+#define _HEM_MBOX_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+/* Message IDs */ -+typedef enum _ENUM_MSG_ID_T { -+ MID_MNY_CNM_CH_REQ, /* MANY notify CNM to obtain channel privilege */ -+ MID_MNY_CNM_CH_ABORT, /* MANY notify CNM to abort/release channel privilege */ -+ -+ MID_CNM_AIS_CH_GRANT, /* CNM notify AIS for indicating channel granted */ -+ MID_CNM_P2P_CH_GRANT, /* CNM notify P2P for indicating channel granted */ -+ MID_CNM_BOW_CH_GRANT, /* CNM notify BOW for indicating channel granted */ -+ -+ /*--------------------------------------------------*/ -+ /* SCN Module Mailbox Messages */ -+ /*--------------------------------------------------*/ -+ MID_AIS_SCN_SCAN_REQ, /* AIS notify SCN for starting scan */ -+ MID_AIS_SCN_SCAN_REQ_V2, /* AIS notify SCN for starting scan with multiple SSID support */ -+ MID_AIS_SCN_SCAN_CANCEL, /* AIS notify SCN for cancelling scan */ -+ MID_P2P_SCN_SCAN_REQ, /* P2P notify SCN for starting scan */ -+ MID_P2P_SCN_SCAN_REQ_V2, /* P2P notify SCN for starting scan with multiple SSID support */ -+ MID_P2P_SCN_SCAN_CANCEL, /* P2P notify SCN for cancelling scan */ -+ MID_BOW_SCN_SCAN_REQ, /* BOW notify SCN for starting scan */ -+ MID_BOW_SCN_SCAN_REQ_V2, /* BOW notify SCN for starting scan with multiple SSID support */ -+ MID_BOW_SCN_SCAN_CANCEL, /* BOW notify SCN for cancelling scan */ -+ MID_RLM_SCN_SCAN_REQ, /* RLM notify SCN for starting scan (OBSS-SCAN) */ -+ MID_RLM_SCN_SCAN_REQ_V2, /* RLM notify SCN for starting scan (OBSS-SCAN) with multiple SSID support */ -+ MID_RLM_SCN_SCAN_CANCEL, /* RLM notify SCN for cancelling scan (OBSS-SCAN) */ -+ MID_SCN_AIS_SCAN_DONE, /* SCN notify AIS for scan completion */ -+ MID_SCN_P2P_SCAN_DONE, /* SCN notify P2P for scan completion */ -+ MID_SCN_BOW_SCAN_DONE, /* SCN notify BOW for scan completion */ -+ MID_SCN_RLM_SCAN_DONE, /* SCN notify RLM for scan completion (OBSS-SCAN) */ -+ -+ /*--------------------------------------------------*/ -+ /* AIS Module Mailbox Messages */ -+ /*--------------------------------------------------*/ -+ MID_OID_AIS_FSM_JOIN_REQ, /* OID/IOCTL notify AIS for join */ -+ MID_OID_AIS_FSM_ABORT, /* OID/IOCTL notify AIS for abort */ -+ MID_AIS_SAA_FSM_START, /* AIS notify SAA for Starting authentication/association fsm */ -+ MID_AIS_SAA_FSM_ABORT, /* AIS notify SAA for Aborting authentication/association fsm */ -+ MID_SAA_AIS_JOIN_COMPLETE, /* SAA notify AIS for indicating join complete */ -+ -+#if CFG_ENABLE_BT_OVER_WIFI -+ /*--------------------------------------------------*/ -+ /* BOW Module Mailbox Messages */ -+ /*--------------------------------------------------*/ -+ MID_BOW_SAA_FSM_START, /* BOW notify SAA for Starting authentication/association fsm */ -+ MID_BOW_SAA_FSM_ABORT, /* BOW notify SAA for Aborting authentication/association fsm */ -+ MID_SAA_BOW_JOIN_COMPLETE, /* SAA notify BOW for indicating join complete */ -+#endif -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ /*--------------------------------------------------*/ -+ /* P2P Module Mailbox Messages */ -+ /*--------------------------------------------------*/ -+ MID_P2P_SAA_FSM_START, /* P2P notify SAA for Starting authentication/association fsm */ -+ MID_P2P_SAA_FSM_ABORT, /* P2P notify SAA for Aborting authentication/association fsm */ -+ MID_SAA_P2P_JOIN_COMPLETE, /* SAA notify P2P for indicating join complete */ -+ -+ MID_MNY_P2P_FUN_SWITCH, /* Enable P2P FSM. */ -+ MID_MNY_P2P_DEVICE_DISCOVERY, /* Start device discovery. */ -+ MID_MNY_P2P_CONNECTION_REQ, /* Connection request. */ -+ MID_MNY_P2P_CONNECTION_ABORT, /* Abort connection request, P2P FSM return to IDLE. */ -+ MID_MNY_P2P_BEACON_UPDATE, -+ MID_MNY_P2P_STOP_AP, -+ MID_MNY_P2P_CHNL_REQ, -+ MID_MNY_P2P_CHNL_ABORT, -+ MID_MNY_P2P_MGMT_TX, -+ MID_MNY_P2P_GROUP_DISSOLVE, -+ MID_MNY_P2P_MGMT_FRAME_REGISTER, -+ MID_MNY_P2P_NET_DEV_REGISTER, -+ MID_MNY_P2P_START_AP, -+ MID_MNY_P2P_MGMT_FRAME_UPDATE, -+ MID_MNY_P2P_EXTEND_LISTEN_INTERVAL, -+#if CFG_SUPPORT_WFD -+ MID_MNY_P2P_WFD_CFG_UPDATE, -+#endif -+#endif -+ -+#if CFG_SUPPORT_ADHOC -+ MID_SCN_AIS_FOUND_IBSS, /* SCN notify AIS that an IBSS Peer has been found and can merge into */ -+#endif /* CFG_SUPPORT_ADHOC */ -+ -+ MID_SAA_AIS_FSM_ABORT, /* SAA notify AIS for indicating deauthentication/disassociation */ -+ -+ /*--------------------------------------------------*/ -+ /* AIS MGMT-TX Support */ -+ /*--------------------------------------------------*/ -+ MID_MNY_AIS_REMAIN_ON_CHANNEL, -+ MID_MNY_AIS_CANCEL_REMAIN_ON_CHANNEL, -+ MID_MNY_AIS_MGMT_TX, -+ -+ MID_TOTAL_NUM -+} ENUM_MSG_ID_T, *P_ENUM_MSG_ID_T; -+ -+/* Message header of inter-components */ -+struct _MSG_HDR_T { -+ LINK_ENTRY_T rLinkEntry; -+ ENUM_MSG_ID_T eMsgId; -+}; -+ -+typedef VOID(*PFN_MSG_HNDL_FUNC) (P_ADAPTER_T, P_MSG_HDR_T); -+ -+typedef struct _MSG_HNDL_ENTRY { -+ ENUM_MSG_ID_T eMsgId; -+ PFN_MSG_HNDL_FUNC pfMsgHndl; -+} MSG_HNDL_ENTRY_T, *P_MSG_HNDL_ENTRY_T; -+ -+typedef enum _EUNM_MSG_SEND_METHOD_T { -+ MSG_SEND_METHOD_BUF = 0, /* Message is put in the queue and will be -+ executed when mailbox is checked. */ -+ MSG_SEND_METHOD_UNBUF /* The handler function is called immediately -+ in the same context of the sender */ -+} EUNM_MSG_SEND_METHOD_T, *P_EUNM_MSG_SEND_METHOD_T; -+ -+typedef enum _ENUM_MBOX_ID_T { -+ MBOX_ID_0 = 0, -+ MBOX_ID_TOTAL_NUM -+} ENUM_MBOX_ID_T, *P_ENUM_MBOX_ID_T; -+ -+/* Define Mailbox structure */ -+typedef struct _MBOX_T { -+ LINK_T rLinkHead; -+} MBOX_T, *P_MBOX_T; -+ -+typedef struct _MSG_SAA_FSM_START_T { -+ MSG_HDR_T rMsgHdr; /* Must be the first member */ -+ UINT_8 ucSeqNum; -+ P_STA_RECORD_T prStaRec; -+} MSG_SAA_FSM_START_T, *P_MSG_SAA_FSM_START_T; -+ -+typedef struct _MSG_SAA_FSM_COMP_T { -+ MSG_HDR_T rMsgHdr; /* Must be the first member */ -+ UINT_8 ucSeqNum; -+ WLAN_STATUS rJoinStatus; -+ P_STA_RECORD_T prStaRec; -+ P_SW_RFB_T prSwRfb; -+} MSG_SAA_FSM_COMP_T, *P_MSG_SAA_FSM_COMP_T; -+ -+typedef struct _MSG_SAA_FSM_ABORT_T { -+ MSG_HDR_T rMsgHdr; /* Must be the first member */ -+ UINT_8 ucSeqNum; -+ P_STA_RECORD_T prStaRec; -+} MSG_SAA_FSM_ABORT_T, *P_MSG_SAA_FSM_ABORT_T; -+ -+typedef struct _MSG_CONNECTION_ABORT_T { -+ MSG_HDR_T rMsgHdr; /* Must be the first member */ -+ UINT_8 ucNetTypeIndex; -+} MSG_CONNECTION_ABORT_T, *P_MSG_CONNECTION_ABORT_T; -+ -+typedef struct _MSG_REMAIN_ON_CHANNEL_T { -+ MSG_HDR_T rMsgHdr; /* Must be the first member */ -+ ENUM_BAND_T eBand; -+ ENUM_CHNL_EXT_T eSco; -+ UINT_8 ucChannelNum; -+ UINT_32 u4DurationMs; -+ UINT_64 u8Cookie; -+} MSG_REMAIN_ON_CHANNEL_T, *P_MSG_REMAIN_ON_CHANNEL_T; -+ -+typedef struct _MSG_CANCEL_REMAIN_ON_CHANNEL_T { -+ MSG_HDR_T rMsgHdr; /* Must be the first member */ -+ UINT_64 u8Cookie; -+} MSG_CANCEL_REMAIN_ON_CHANNEL_T, *P_MSG_CANCEL_REMAIN_ON_CHANNEL_T; -+ -+typedef struct _MSG_MGMT_TX_REQUEST_T { -+ MSG_HDR_T rMsgHdr; -+ P_MSDU_INFO_T prMgmtMsduInfo; -+ UINT_64 u8Cookie; /* For indication. */ -+ BOOLEAN fgNoneCckRate; -+ BOOLEAN fgIsWaitRsp; -+} MSG_MGMT_TX_REQUEST_T, *P_MSG_MGMT_TX_REQUEST_T; -+ -+/* specific message data types */ -+typedef MSG_SAA_FSM_START_T MSG_JOIN_REQ_T, *P_MSG_JOIN_REQ_T; -+typedef MSG_SAA_FSM_COMP_T MSG_JOIN_COMP_T, *P_MSG_JOIN_COMP_T; -+typedef MSG_SAA_FSM_ABORT_T MSG_JOIN_ABORT_T, *P_MSG_JOIN_ABORT_T; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+VOID mboxSetup(IN P_ADAPTER_T prAdapter, IN ENUM_MBOX_ID_T eMboxId); -+ -+VOID -+mboxSendMsg(IN P_ADAPTER_T prAdapter, -+ IN ENUM_MBOX_ID_T eMboxId, IN P_MSG_HDR_T prMsg, IN EUNM_MSG_SEND_METHOD_T eMethod); -+ -+VOID mboxRcvAllMsg(IN P_ADAPTER_T prAdapter, IN ENUM_MBOX_ID_T eMboxId); -+ -+VOID mboxInitialize(IN P_ADAPTER_T prAdapter); -+ -+VOID mboxDestroy(IN P_ADAPTER_T prAdapter); -+ -+VOID mboxDummy(IN P_ADAPTER_T prAdapter, P_MSG_HDR_T prMsgHdr); -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif /* _HEM_MBOX_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/hs20.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/hs20.h -new file mode 100644 -index 000000000000..88b99222133f ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/hs20.h -@@ -0,0 +1,148 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/HS2_DEV_SW/MT6620_WIFI_DRIVER_V2_1_HS_2_0/include/mgmt/hs20.h#2 -+*/ -+ -+/*! \file hs20.h -+ \brief This file contains the function declaration for hs20.c. -+*/ -+ -+/* -+** Log: -+ * -+ */ -+ -+#ifndef _HS20_H -+#define _HS20_H -+ -+#if CFG_SUPPORT_HOTSPOT_2_0 -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+#define BSSID_POOL_MAX_SIZE 8 -+#define HS20_SIGMA_SCAN_RESULT_TIMEOUT 30 /* sec */ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+#if CFG_ENABLE_GTK_FRAME_FILTER -+/*For GTK Frame Filter*/ -+typedef struct _IPV4_NETWORK_ADDRESS_LIST { -+ UINT_8 ucAddrCount; -+ IPV4_NETWORK_ADDRESS arNetAddr[1]; -+} IPV4_NETWORK_ADDRESS_LIST, *P_IPV4_NETWORK_ADDRESS_LIST; -+#endif -+ -+/* Entry of BSSID Pool - For SIGMA Test */ -+typedef struct _BSSID_ENTRY_T { -+ UINT_8 aucBSSID[MAC_ADDR_LEN]; -+} BSSID_ENTRY_T, P_HS20_BSSID_POOL_ENTRY_T; -+ -+struct _HS20_INFO_T { -+ -+ /*Hotspot 2.0 Information */ -+ UINT_8 aucHESSID[MAC_ADDR_LEN]; -+ UINT_8 ucAccessNetworkOptions; -+ UINT_8 ucVenueGroup; /* VenueInfo - Group */ -+ UINT_8 ucVenueType; -+ UINT_8 ucHotspotConfig; -+ -+ /*Roaming Consortium Information */ -+ /* PARAM_HS20_ROAMING_CONSORTIUM_INFO rRCInfo; */ -+ -+ /*Hotspot 2.0 dummy AP Info */ -+ -+ /*Time Advertisement Information */ -+ /* UINT_32 u4UTCOffsetTime; */ -+ /* UINT_8 aucTimeZone[ELEM_MAX_LEN_TIME_ZONE]; */ -+ /* UINT_8 ucLenTimeZone; */ -+ -+ /* For SIGMA Test */ -+ /* BSSID Pool */ -+ BSSID_ENTRY_T arBssidPool[BSSID_POOL_MAX_SIZE]; -+ UINT_8 ucNumBssidPoolEntry; -+ BOOLEAN fgIsHS2SigmaMode; -+ -+}; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/*For GTK Frame Filter*/ -+#if DBG -+#define FREE_IPV4_NETWORK_ADDR_LIST(_prAddrList) \ -+ { \ -+ UINT_32 u4Size = OFFSET_OF(IPV4_NETWORK_ADDRESS_LIST, arNetAddr) + \ -+ (((_prAddrList)->ucAddrCount) * sizeof(IPV4_NETWORK_ADDRESS)); \ -+ kalMemFree((_prAddrList), VIR_MEM_TYPE, u4Size); \ -+ (_prAddrList) = NULL; \ -+ } -+#else -+#define FREE_IPV4_NETWORK_ADDR_LIST(_prAddrList) \ -+ { \ -+ kalMemFree((_prAddrList), VIR_MEM_TYPE, 0); \ -+ (_prAddrList) = NULL; \ -+ } -+#endif -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+VOID hs20GenerateInterworkingIE(IN P_ADAPTER_T prAdapter, OUT P_MSDU_INFO_T prMsduInfo); -+ -+VOID hs20GenerateRoamingConsortiumIE(IN P_ADAPTER_T prAdapter, OUT P_MSDU_INFO_T prMsduInfo); -+ -+VOID hs20GenerateHS20IE(IN P_ADAPTER_T prAdapter, OUT P_MSDU_INFO_T prMsduInfo); -+ -+VOID hs20FillExtCapIE(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo, P_MSDU_INFO_T prMsduInfo); -+ -+VOID hs20FillProreqExtCapIE(IN P_ADAPTER_T prAdapter, OUT PUINT_8 pucIE); -+ -+VOID hs20FillHS20IE(IN P_ADAPTER_T prAdapter, OUT PUINT_8 pucIE); -+ -+UINT_32 hs20CalculateHS20RelatedIEForProbeReq(IN P_ADAPTER_T prAdapter, IN PUINT_8 pucTargetBSSID); -+ -+WLAN_STATUS hs20GenerateHS20RelatedIEForProbeReq(IN P_ADAPTER_T prAdapter, IN PUINT_8 pucTargetBSSID, OUT PUINT_8 prIE); -+ -+BOOLEAN hs20IsGratuitousArp(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prCurrSwRfb); -+ -+BOOLEAN hs20IsUnsolicitedNeighborAdv(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prCurrSwRfb); -+ -+#if CFG_ENABLE_GTK_FRAME_FILTER -+BOOLEAN hs20IsForgedGTKFrame(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prBssInfo, IN P_SW_RFB_T prCurrSwRfb); -+#endif -+ -+BOOLEAN hs20IsUnsecuredFrame(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prBssInfo, IN P_SW_RFB_T prCurrSwRfb); -+ -+BOOLEAN hs20IsFrameFilterEnabled(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prBssInfo); -+ -+WLAN_STATUS hs20SetBssidPool(IN P_ADAPTER_T prAdapter, IN PVOID pvBuffer, IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIdx); -+ -+#endif -+#endif -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/mib.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/mib.h -new file mode 100644 -index 000000000000..cb89fd8793ee ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/mib.h -@@ -0,0 +1,153 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/mgmt/mib.h#1 -+*/ -+ -+/*! \file mib.h -+ \brief This file contains the IEEE 802.11 family related MIB definition -+ for MediaTek 802.11 Wireless LAN Adapters. -+*/ -+ -+/* -+** Log: mib.h -+ * -+ * 11 08 2010 wh.su -+ * [WCXRP00000171] [MT6620 Wi-Fi][Driver] Add message check code same behavior as mt5921 -+ * add the message check code from mt5921. -+ * -+ * 07 24 2010 wh.su -+ * -+ * .support the Wi-Fi RSN -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 07 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add aa_fsm.h, ais_fsm.h, bss.h, mib.h and scan.h. -+ * -+ * 02 04 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Add AAA Module Support, Revise Net Type to Net Type Index for array lookup -+ * -+ * Nov 23 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * -+*/ -+ -+#ifndef _MIB_H -+#define _MIB_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+/* Entry in SMT AuthenticationAlgorithms Table: dot11AuthenticationAlgorithmsEntry */ -+typedef struct _DOT11_AUTHENTICATION_ALGORITHMS_ENTRY { -+ BOOLEAN dot11AuthenticationAlgorithmsEnable; /* dot11AuthenticationAlgorithmsEntry 3 */ -+} DOT11_AUTHENTICATION_ALGORITHMS_ENTRY, *P_DOT11_AUTHENTICATION_ALGORITHMS_ENTRY; -+ -+/* Entry in SMT dot11RSNAConfigPairwiseCiphersTalbe Table: dot11RSNAConfigPairwiseCiphersEntry */ -+typedef struct _DOT11_RSNA_CONFIG_PAIRWISE_CIPHERS_ENTRY { -+ UINT_32 dot11RSNAConfigPairwiseCipher; /* dot11RSNAConfigPairwiseCiphersEntry 2 */ -+ BOOLEAN dot11RSNAConfigPairwiseCipherEnabled; /* dot11RSNAConfigPairwiseCiphersEntry 3 */ -+} DOT11_RSNA_CONFIG_PAIRWISE_CIPHERS_ENTRY, *P_DOT11_RSNA_CONFIG_PAIRWISE_CIPHERS_ENTRY; -+ -+/* Entry in SMT dot11RSNAConfigAuthenticationSuitesTalbe Table: dot11RSNAConfigAuthenticationSuitesEntry */ -+typedef struct _DOT11_RSNA_CONFIG_AUTHENTICATION_SUITES_ENTRY { -+ UINT_32 dot11RSNAConfigAuthenticationSuite; /* dot11RSNAConfigAuthenticationSuitesEntry 2 */ -+ BOOLEAN dot11RSNAConfigAuthenticationSuiteEnabled; /* dot11RSNAConfigAuthenticationSuitesEntry 3 */ -+} DOT11_RSNA_CONFIG_AUTHENTICATION_SUITES_ENTRY, *P_DOT11_RSNA_CONFIG_AUTHENTICATION_SUITES_ENTRY; -+ -+/* ----- IEEE 802.11 MIB Major sections ----- */ -+typedef struct _IEEE_802_11_MIB_T { -+ /* dot11PrivacyTable (dot11smt 5) */ -+ UINT_8 dot11WEPDefaultKeyID; /* dot11PrivacyEntry 2 */ -+ BOOLEAN dot11TranmitKeyAvailable; -+ UINT_32 dot11WEPICVErrorCount; /* dot11PrivacyEntry 5 */ -+ UINT_32 dot11WEPExcludedCount; /* dot11PrivacyEntry 6 */ -+ -+ /* dot11RSNAConfigTable (dot11smt 8) */ -+ UINT_32 dot11RSNAConfigGroupCipher; /* dot11RSNAConfigEntry 4 */ -+ -+ /* dot11RSNAConfigPairwiseCiphersTable (dot11smt 9) */ -+ DOT11_RSNA_CONFIG_PAIRWISE_CIPHERS_ENTRY dot11RSNAConfigPairwiseCiphersTable[MAX_NUM_SUPPORTED_CIPHER_SUITES]; -+ -+ /* dot11RSNAConfigAuthenticationSuitesTable (dot11smt 10) */ -+ DOT11_RSNA_CONFIG_AUTHENTICATION_SUITES_ENTRY -+ dot11RSNAConfigAuthenticationSuitesTable[MAX_NUM_SUPPORTED_AKM_SUITES]; -+ -+#if 0 /* SUPPORT_WAPI */ -+ BOOLEAN fgWapiKeyInstalled; -+ PARAM_WPI_KEY_T rWapiPairwiseKey[2]; -+ BOOLEAN fgPairwiseKeyUsed[2]; -+ UINT_8 ucWpiActivedPWKey; /* Must be 0 or 1, by wapi spec */ -+ PARAM_WPI_KEY_T rWapiGroupKey[2]; -+ BOOLEAN fgGroupKeyUsed[2]; -+#endif -+} IEEE_802_11_MIB_T, *P_IEEE_802_11_MIB_T; -+ -+/* ------------------ IEEE 802.11 non HT PHY characteristics ---------------- */ -+typedef const struct _NON_HT_PHY_ATTRIBUTE_T { -+ UINT_16 u2SupportedRateSet; -+ -+ BOOLEAN fgIsShortPreambleOptionImplemented; -+ -+ BOOLEAN fgIsShortSlotTimeOptionImplemented; -+ -+} NON_HT_PHY_ATTRIBUTE_T, *P_NON_HT_PHY_ATTRIBUTE_T; -+ -+typedef const struct _NON_HT_ADHOC_MODE_ATTRIBUTE_T { -+ -+ ENUM_PHY_TYPE_INDEX_T ePhyTypeIndex; -+ -+ UINT_16 u2BSSBasicRateSet; -+ -+} NON_HT_ADHOC_MODE_ATTRIBUTE_T, *P_NON_HT_ADHOC_MODE_ATTRIBUTE_T; -+ -+typedef NON_HT_ADHOC_MODE_ATTRIBUTE_T NON_HT_AP_MODE_ATTRIBUTE_T; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+extern NON_HT_PHY_ATTRIBUTE_T rNonHTPhyAttributes[]; -+extern NON_HT_ADHOC_MODE_ATTRIBUTE_T rNonHTAdHocModeAttributes[]; -+extern NON_HT_AP_MODE_ATTRIBUTE_T rNonHTApModeAttributes[]; -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif /* _MIB_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_assoc.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_assoc.h -new file mode 100644 -index 000000000000..11145c31dbfa ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_assoc.h -@@ -0,0 +1,55 @@ -+/* -+** Id: //Department/DaVinci/TRUNK/WiFi_P2P_Driver/include/mgmt/p2p_assoc.h#1 -+*/ -+ -+/*! \file p2p_assoc.h -+ \brief This file contains the Wi-Fi Direct ASSOC REQ/RESP of -+ IEEE 802.11 family for MediaTek 802.11 Wireless LAN Adapters. -+*/ -+ -+#ifndef _P2P_ASSOC_H -+#define _P2P_ASSOC_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+PUINT_8 p2pBuildReAssocReqFrameCommonIEs(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo, IN PUINT_8 pucBuffer); -+ -+#endif -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_bss.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_bss.h -new file mode 100644 -index 000000000000..869d7bf0ee61 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_bss.h -@@ -0,0 +1,56 @@ -+/* -+** Id: //Department/DaVinci/TRUNK/WiFi_P2P_Driver/include/mgmt/p2p_bss.h#2 -+*/ -+ -+/*! \file "p2p_bss.h" -+ \brief In this file we define the function prototype used in p2p BSS/IBSS. -+ -+ The file contains the function declarations and defines for used in BSS/IBSS. -+*/ -+ -+#ifndef _P2P_BSS_H -+#define _P2P_BSS_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+UINT_32 p2pGetTxProbRspIeTableSize(VOID); -+ -+#endif -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_fsm.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_fsm.h -new file mode 100644 -index 000000000000..2541e1d2883e ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_fsm.h -@@ -0,0 +1,2190 @@ -+/* -+** Id: //Department/DaVinci/TRUNK/WiFi_P2P_Driver/include/mgmt/p2p_fsm.h#23 -+*/ -+ -+/*! \file p2p_fsm.h -+ \brief Declaration of functions and finite state machine for P2P Module. -+ -+ Declaration of functions and finite state machine for P2P Module. -+*/ -+ -+/* -+** Log: p2p_fsm.h -+** -+** 09 12 2012 wcpadmin -+** [ALPS00276400] Remove MTK copyright and legal header on GPL/LGPL related packages -+** . -+** -+** 08 14 2012 yuche.tsai -+** NULL -+** Fix compile error. -+** -+** 07 26 2012 yuche.tsai -+** [ALPS00324337] [ALPS.JB][Hot-Spot] Driver update for Hot-Spot -+** Update driver code of ALPS.JB for hot-spot. -+** -+** 07 19 2012 yuche.tsai -+** NULL -+** Code update for JB. -+ * -+ * 07 18 2012 yuche.tsai -+ * NULL -+ * add one file. -+ * -+ * 12 02 2011 yuche.tsai -+ * NULL -+ * Resolve class 3 error issue under AP mode. -+ * -+ * data frame may TX before Assoc Response TX. -+ * -+ * 11 11 2011 yuche.tsai -+ * NULL -+ * Fix work thread cancel issue. -+ * -+ * 11 11 2011 yuche.tsai -+ * NULL -+ * Fix default device name issue. -+ * -+ * 11 09 2011 yuche.tsai -+ * [WCXRP00001093] [Need Patch][Volunteer Patch] Service Discovery 2.0 state transition issue. -+ * Fix SD2.0 issue which may cause KE. (Monkey test) -+ * -+ * 11 08 2011 yuche.tsai -+ * [WCXRP00001094] [Volunteer Patch][Driver] Driver version & supplicant version -+ * query & set support for service discovery version check. -+ * Add support for driver version query & p2p supplicant verseion set. -+ * For new service discovery mechanism sync. -+ * -+ * 10 18 2011 yuche.tsai -+ * [WCXRP00001045] [WiFi Direct][Driver] Check 2.1 branch. -+ * Support Channel Query. -+ * -+ * 10 18 2011 yuche.tsai -+ * [WCXRP00001045] [WiFi Direct][Driver] Check 2.1 branch. -+ * New 2.1 branch -+ -+ * -+ * 09 01 2011 yuche.tsai -+ * NULL -+ * Fix channel stay interval. -+ * Sync channel stay interval & channel request interval under AP mode.. -+ * -+ * 08 30 2011 yuche.tsai -+ * [WCXRP00000953] [Volunteer Patch][Driver] Hot Spot Channel ASSERT issue. -+ * Fix hot spot FW assert issue when under concurrent case. (DBG enable only) -+ * -+ * 08 16 2011 cp.wu -+ * [WCXRP00000934] [MT6620 Wi-Fi][Driver][P2P] Wi-Fi hot spot with auto sparse channel residence -+ * auto channel decision for 2.4GHz hot spot mode -+ * -+ * 08 16 2011 yuche.tsai -+ * NULL -+ * Fix scan policy for Active LISTEN scan. -+ * -+ * 08 09 2011 yuche.tsai -+ * [WCXRP00000919] [Volunteer Patch][WiFi Direct][Driver] Invitation New Feature. -+ * Invitation Feature add on. -+ * -+ * 08 02 2011 yuche.tsai -+ * [WCXRP00000896] [Volunteer Patch][WiFi Direct][Driver] GO with multiple client, -+ * TX deauth to a disconnecting device issue. -+ * Support TX Deauth Issue. -+ * -+ * 07 26 2011 yuche.tsai -+ * [WCXRP00000875] [Volunteer Patch][WiFi Direct][Driver] MT6620 IOT issue with realtek test bed solution. -+ * Turn off persistent group support for V2.0 release. -+ * -+ * 07 18 2011 yuche.tsai -+ * [WCXRP00000856] [Volunteer Patch][WiFi Direct][Driver] MT6620 WiFi Direct IOT Issue with BCM solution. -+ * Fix compile error. -+ * -+ * 07 18 2011 yuche.tsai -+ * [WCXRP00000856] [Volunteer Patch][WiFi Direct][Driver] MT6620 WiFi Direct IOT Issue with BCM solution. -+ * Fix MT6620 WiFi Direct IOT Issue with BCM solution. -+ * -+ * 07 11 2011 yuche.tsai -+ * [WCXRP00000845] [Volunteer Patch][WiFi Direct] WiFi Direct Device Connection Robustness -+ * Enhance Connection Robustness. -+ * -+ * 07 08 2011 yuche.tsai -+ * [WCXRP00000841] [Volunteer Patch][WiFi Direct] Group Owner Setting. -+ * Update GO configure parameter. -+ * -+ * 07 05 2011 yuche.tsai -+ * [WCXRP00000821] [Volunteer Patch][WiFi Direct][Driver] WiFi Direct Connection Speed Issue -+ * Disable enhancement II for debugging. -+ * -+ * 07 05 2011 yuche.tsai -+ * [WCXRP00000821] [Volunteer Patch][WiFi Direct][Driver] WiFi Direct Connection Speed Issue -+ * Refine compile flag. -+ * -+ * 07 05 2011 yuche.tsai -+ * [WCXRP00000821] [Volunteer Patch][WiFi Direct][Driver] WiFi Direct Connection Speed Issue -+ * Add wifi direct connection enhancement method I, II & VI. -+ * -+ * 06 20 2011 yuche.tsai -+ * [WCXRP00000799] [Volunteer Patch][MT6620][Driver] Connection Indication Twice Issue. -+ * Fix connection indication twice issue. -+ * -+ * 06 07 2011 yuche.tsai -+ * [WCXRP00000763] [Volunteer Patch][MT6620][Driver] RX Service Discovery Frame under AP mode Issue -+ * Fix RX SD request under AP mode issue. -+ * -+ * 05 04 2011 yuche.tsai -+ * NULL -+ * Support partial persistent group function. -+ * -+ * 04 20 2011 terry.wu -+ * [WCXRP00000660] [MT6620 Wi-Fi][Driver] Remove flag CFG_WIFI_DIRECT_MOVED -+ * Remove CFG_WIFI_DIRECT_MOVED. -+ * -+ * 04 08 2011 yuche.tsai -+ * [WCXRP00000624] [Volunteer Patch][MT6620][Driver] Add device discoverability support for GO. -+ * Add device discoverability support. -+ * -+ * 03 25 2011 yuche.tsai -+ * NULL -+ * Improve some error handleing. -+ * -+ * 03 22 2011 george.huang -+ * [WCXRP00000504] [MT6620 Wi-Fi][FW] Support Sigma CAPI for power saving related command -+ * link with supplicant commands -+ * -+ * 03 22 2011 yuche.tsai -+ * NULL -+ * 1.Shorten the LISTEN interval. -+ * 2. Fix IF address issue when we are GO -+ * 3. Fix LISTEN channel issue. -+ * -+ * 03 21 2011 yuche.tsai -+ * NULL -+ * Change P2P Connection Request Flow. -+ * -+ * 03 19 2011 yuche.tsai -+ * [WCXRP00000584] [Volunteer Patch][MT6620][Driver] Add beacon timeout support for WiFi Direct. -+ * Add beacon timeout support. -+ * -+ * 03 19 2011 yuche.tsai -+ * [WCXRP00000581] [Volunteer Patch][MT6620][Driver] P2P IE in Assoc Req Issue -+ * Append P2P IE in Assoc Req, so that GC can be discovered in probe response of GO. -+ * -+ * 03 18 2011 yuche.tsai -+ * [WCXRP00000574] [Volunteer Patch][MT6620][Driver] Modify P2P FSM Connection Flow -+ * Modify connection flow after Group Formation Complete, or device connect to a GO. -+ * Instead of request channel & connect directly, we use scan to allocate channel bandwidth & connect after RX BCN. -+ * -+ * 03 15 2011 yuche.tsai -+ * [WCXRP00000560] [Volunteer Patch][MT6620][Driver] P2P Connection from UI using KEY/DISPLAY issue -+ * Fix some configure method issue. -+ * -+ * 03 10 2011 yuche.tsai -+ * NULL -+ * Add P2P API. -+ * -+ * 03 07 2011 yuche.tsai -+ * [WCXRP00000502] [Volunteer Patch][MT6620][Driver] Fix group ID issue when doing Group Formation. -+ * . -+ * -+ * 03 07 2011 wh.su -+ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code -+ * rename the define to anti_pviracy. -+ * -+ * 03 05 2011 wh.su -+ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code -+ * add the code to get the check rsponse and indicate to app. -+ * -+ * 03 01 2011 yuche.tsai -+ * [WCXRP00000501] [Volunteer Patch][MT6620][Driver] No common channel issue when doing GO formation -+ * Update channel issue when doing GO formation.. -+ * -+ * 03 01 2011 yuche.tsai -+ * [WCXRP00000245] 1. Invitation Request/Response. -+2. Provision Discovery Request/Response -+ -+ * Update Service Discovery Related wlanoid function. -+ * -+ * 02 18 2011 wh.su -+ * [WCXRP00000471] [MT6620 Wi-Fi][Driver] Add P2P Provison discovery append Config Method attribute at WSC IE -+ * fixed the ioctl setting that index not map to spec defined config method. -+ * -+ * 02 18 2011 yuche.tsai -+ * [WCXRP00000480] [Volunteer Patch][MT6620][Driver] WCS IE format issue -+ * Fix WSC IE BE format issue. -+ * -+ * 02 17 2011 wh.su -+ * [WCXRP00000471] [MT6620 Wi-Fi][Driver] Add P2P Provison discovery append Config Method attribute at WSC IE -+ * append the WSC IE config method attribute at provision discovery request. -+ * -+ * 02 11 2011 yuche.tsai -+ * [WCXRP00000431] [Volunteer Patch][MT6620][Driver] Add MLME support for deauthentication under AP(Hot-Spot) mode. -+ * Add two function prototype. -+ * -+ * 02 10 2011 yuche.tsai -+ * [WCXRP00000431] [Volunteer Patch][MT6620][Driver] Add MLME support for deauthentication under AP(Hot-Spot) mode. -+ * Support Disassoc & Deauthentication for Hot-Spot. -+ * -+ * 02 09 2011 yuche.tsai -+ * [WCXRP00000245] 1. Invitation Request/Response. -+ -+2. Provision Discovery Request/Response -+ -+ * Add Service Discovery Indication Related code. -+ * -+ * 02 09 2011 yuche.tsai -+ * [WCXRP00000431] [Volunteer Patch][MT6620][Driver] Add MLME support for deauthentication under AP(Hot-Spot) mode. -+ * Add Support for MLME deauthentication for Hot-Spot. -+ * -+ * 02 09 2011 yuche.tsai -+ * [WCXRP00000429] [Volunteer Patch][MT6620][Driver] Hot Spot Client Limit Issue -+ * Fix Client Limit Issue. -+ * -+ * 01 26 2011 yuche.tsai -+ * [WCXRP00000245] 1. Invitation Request/Response. -+ -+2. Provision Discovery Request/Response -+ -+ * Add Service Discovery Function. -+ * -+ * 01 25 2011 terry.wu -+ * [WCXRP00000393] [MT6620 Wi-Fi][Driver] Add new module insert parameter -+ * Add a new module parameter to indicate current runnig mode, P2P or AP. -+ * -+ * 01 19 2011 george.huang -+ * [WCXRP00000355] [MT6620 Wi-Fi] Set WMM-PS related setting with qualifying AP capability -+ * Null NOA attribute setting when no related parameters. -+ * -+ * 01 12 2011 yuche.tsai -+ * [WCXRP00000352] [Volunteer Patch][MT6620][Driver] P2P Statsion Record Client List Issue -+ * Modify some behavior of AP mode. -+ * -+ * 12 22 2010 yuche.tsai -+ * [WCXRP00000245] 1. Invitation Request/Response. -+2. Provision Discovery Request/Response -+ -+ * Fix Compile Error. -+ * -+ * 12 15 2010 yuche.tsai -+ * [WCXRP00000245] 1. Invitation Request/Response. -+2. Provision Discovery Request/Response -+ -+ * Refine Connection Flow. -+ * -+ * 12 08 2010 yuche.tsai -+ * [WCXRP00000244] [MT6620][Driver] Add station record type for each client when in AP mode. -+ * Change STA Type under AP mode. We would tell if client is a P2P device or a legacy client -+ * by checking the P2P IE in assoc req frame. -+ * -+ * 12 02 2010 yuche.tsai -+ * NULL -+ * Update P2P Connection Policy for Invitation. -+ * -+ * 12 02 2010 yuche.tsai -+ * NULL -+ * Update P2P Connection Policy for Invitation & Provision Discovery. -+ * -+ * 11 30 2010 yuche.tsai -+ * NULL -+ * Invitation & Provision Discovery Indication. -+ * -+ * 11 30 2010 yuche.tsai -+ * NULL -+ * Update Configure Method indication & selection for Provision Discovery & GO_NEGO_REQ -+ * -+ * 11 29 2010 yuche.tsai -+ * NULL -+ * Update P2P related function for INVITATION & PROVISION DISCOVERY. -+ * -+ * 11 26 2010 george.huang -+ * [WCXRP00000152] [MT6620 Wi-Fi] AP mode power saving function -+ * Update P2P PS for NOA function. -+ * -+ * 11 25 2010 yuche.tsai -+ * NULL -+ * Update Code for Invitation Related Function. -+ * -+ * 11 17 2010 wh.su -+ * [WCXRP00000164] [MT6620 Wi-Fi][Driver] Support the p2p random SSID[WCXRP00000179] [MT6620 Wi-Fi][FW] -+ * Set the Tx lowest rate at wlan table for normal operation -+ * fixed some ASSERT check. -+ * -+ * 11 04 2010 wh.su -+ * [WCXRP00000164] [MT6620 Wi-Fi][Driver] Support the p2p random SSID -+ * adding the p2p random ssid support. -+ * -+ * 10 20 2010 wh.su -+ * [WCXRP00000124] [MT6620 Wi-Fi] [Driver] Support the dissolve P2P Group -+ * Add the code to support disconnect p2p group -+ * -+ * 10 08 2010 wh.su -+ * [WCXRP00000085] [MT6620 Wif-Fi] [Driver] update the modified p2p state machine -+ * update the frog's new p2p state machine. -+ * -+ * 10 04 2010 wh.su -+ * [WCXRP00000081] [MT6620][Driver] Fix the compiling error at WinXP while enable P2P -+ * fixed compiling error while enable p2p. -+ * -+ * 09 21 2010 kevin.huang -+ * [WCXRP00000054] [MT6620 Wi-Fi][Driver] Restructure driver for second Interface -+ * Isolate P2P related function for Hardware Software Bundle -+ * -+ * 09 10 2010 wh.su -+ * NULL -+ * fixed the compiling error at WinXP. -+ * -+ * 09 07 2010 wh.su -+ * NULL -+ * adding the code for beacon/probe req/ probe rsp wsc ie at p2p. -+ * -+ * 09 03 2010 kevin.huang -+ * NULL -+ * Refine #include sequence and solve recursive/nested #include issue -+ * -+ * 08 26 2010 yuche.tsai -+ * NULL -+ * Add connection abort message event prototype. -+ * -+ * 08 20 2010 kevin.huang -+ * NULL -+ * Modify AAA Module for changing STA STATE 3 at p2p/bowRunEventAAAComplete() -+ * -+ * 08 16 2010 yuche.tsai -+ * NULL -+ * Fix P2P Intended Interface Address Bug. -+ * Extend GO Nego Timeout Time. -+ * -+ * 08 16 2010 yuche.tsai -+ * NULL -+ * Extend Listen Interval default value & remove deprecated variable. -+ * -+ * 08 16 2010 kevin.huang -+ * NULL -+ * Refine AAA functions -+ * -+ * 08 12 2010 kevin.huang -+ * NULL -+ * Refine bssProcessProbeRequest() and bssSendBeaconProbeResponse() -+ * -+ * 08 12 2010 yuche.tsai -+ * NULL -+ * Add function prototype for join complete. -+ * -+ * 08 11 2010 yuche.tsai -+ * NULL -+ * Add some function proto type for P2P FSM under provisioning phase.. -+ * -+ * 08 11 2010 yuche.tsai -+ * NULL -+ * Change P2P data structure for supporting -+ * 1. P2P Device discovery. -+ * 2. P2P Group Negotiation. -+ * 3. P2P JOIN -+ * -+ * 08 05 2010 yuche.tsai -+ * NULL -+ * Check-in P2P Device Discovery Feature. -+ * -+ * 08 03 2010 george.huang -+ * NULL -+ * handle event for updating NOA parameters indicated from FW -+ * -+ * 08 02 2010 yuche.tsai -+ * NULL -+ * P2P Group Negotiation Code Check in. -+ * -+ * 07 26 2010 yuche.tsai -+ * -+ * Update P2P FSM header file. -+ * -+ * 07 23 2010 cp.wu -+ * -+ * P2P/RSN/WAPI IEs need to be declared with compact structure. -+ * -+ * 07 21 2010 yuche.tsai -+ * -+ * Add for P2P Scan Result Parsing & Saving. -+ * -+ * 07 19 2010 yuche.tsai -+ * -+ * Update P2P FSM header file. -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 21 2010 yuche.tsai -+ * [WPD00003839][MT6620 5931][P2P] Feature migration -+ * Fix some P2P function prototype. -+ * -+ * 06 17 2010 yuche.tsai -+ * [WPD00003839][MT6620 5931][P2P] Feature migration -+ * First draft for migration P2P FSM from FW to Driver. -+ * -+ * 03 18 2010 kevin.huang -+ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support -+ * Rename CFG flag for P2P -+ * -+ * 02 26 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Modify parameter of p2pStartGO -+ * -+ * 02 23 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Add Wi-Fi Direct SSID and P2P GO Test Mode -+ * -+ * 02 04 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Add AAA Module Support, Revise Net Type to Net Type Index for array lookup -+*/ -+ -+#ifndef _P2P_FSM_H -+#define _P2P_FSM_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+#define CID52_53_54 0 -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+typedef enum _ENUM_P2P_STATE_T { -+ P2P_STATE_IDLE = 0, -+ P2P_STATE_SCAN, -+ P2P_STATE_AP_CHANNEL_DETECT, -+ P2P_STATE_REQING_CHANNEL, -+ P2P_STATE_CHNL_ON_HAND, /* Requesting Channel to Send Specific Frame. */ -+ P2P_STATE_GC_JOIN, /* Sending Specific Frame. May extending channel by other event. */ -+ P2P_STATE_NUM -+} ENUM_P2P_STATE_T, *P_ENUM_P2P_STATE_T; -+ -+enum _ENUM_P2P_DEV_EXT_LISTEN_T { -+ P2P_DEV_NOT_EXT_LISTEN, -+ P2P_DEV_EXT_LISTEN_ING, -+ P2P_DEV_EXT_LISTEN_WAITFOR_TIMEOUT, -+ P2P_DEV_EXT_LISTEN_NUM -+}; -+ -+typedef enum _ENUM_CHANNEL_REQ_TYPE_T { -+ CHANNEL_REQ_TYPE_REMAIN_ON_CHANNEL, -+ CHANNEL_REQ_TYPE_GC_JOIN_REQ, -+ CHANNEL_REQ_TYPE_GO_START_BSS -+} ENUM_CHANNEL_REQ_TYPE_T, *P_ENUM_CHANNEL_REQ_TYPE_T; -+ -+typedef enum _ENUM_BUFFER_TYPE_T { -+ ENUM_FRAME_TYPE_EXTRA_IE_BEACON, -+ ENUM_FRAME_TYPE_EXTRA_IE_ASSOC_RSP, -+ ENUM_FRAME_TYPE_EXTRA_IE_PROBE_RSP, -+ ENUM_FRAME_TYPE_PROBE_RSP_TEMPLATE, -+ ENUM_FRAME_TYPE_BEACON_TEMPLATE, -+ ENUM_FRAME_IE_NUM -+} ENUM_BUFFER_TYPE_T, *P_ENUM_BUFFER_TYPE_T; -+ -+typedef enum _ENUM_HIDDEN_SSID_TYPE_T { -+ ENUM_HIDDEN_SSID_NONE, -+ ENUM_HIDDEN_SSID_LEN, -+ ENUM_HIDDEN_SSID_ZERO_CONTENT, -+ ENUM_HIDDEN_SSID_NUM -+} ENUM_HIDDEN_SSID_TYPE_T, *P_ENUM_HIDDEN_SSID_TYPE_T; -+ -+typedef struct _P2P_SSID_STRUCT_T { -+ UINT_8 aucSsid[32]; -+ UINT_8 ucSsidLen; -+} P2P_SSID_STRUCT_T, *P_P2P_SSID_STRUCT_T; -+ -+typedef struct _P2P_STATION_INFO_T { -+ UINT_32 u4InactiveTime; -+ UINT_32 u4RxBytes; /* TODO: */ -+ UINT_32 u4TxBytes; /* TODO: */ -+ UINT_32 u4RxPackets; /* TODO: */ -+ UINT_32 u4TxPackets; /* TODO: */ -+ /* TODO: Add more for requirement. */ -+} P2P_STATION_INFO_T, *P_P2P_STATION_INFO_T; -+ -+typedef struct _AP_CRYPTO_SETTINGS_T { -+ UINT_32 u4WpaVersion; -+ UINT_32 u4CipherGroup; -+ INT_32 i4NumOfCiphers; -+ UINT_32 aucCiphersPairwise[5]; -+ INT_32 i4NumOfAkmSuites; -+ UINT_32 aucAkmSuites[2]; -+ BOOLEAN fgIsControlPort; -+ UINT_16 u2ControlPortBE; -+ BOOLEAN fgIsControlPortEncrypt; -+} AP_CRYPTO_SETTINGS_T, *P_AP_CRYPTO_SETTINGS_T; -+ -+/*-------------------- P2P FSM ACTION STRUCT ---------------------*/ -+typedef struct _P2P_CHNL_REQ_INFO_T { -+ BOOLEAN fgIsChannelRequested; -+ UINT_8 ucSeqNumOfChReq; -+ UINT_64 u8Cookie; -+ UINT_8 ucReqChnlNum; -+ ENUM_BAND_T eBand; -+ ENUM_CHNL_EXT_T eChnlSco; -+ UINT_32 u4MaxInterval; -+ ENUM_CHANNEL_REQ_TYPE_T eChannelReqType; -+ -+ UINT_8 ucOriChnlNum; -+ ENUM_BAND_T eOriBand; -+ ENUM_CHNL_EXT_T eOriChnlSco; -+ UINT_32 NFC_BEAM; /*NFC Beam + Indication */ -+} P2P_CHNL_REQ_INFO_T, *P_P2P_CHNL_REQ_INFO_T; -+ -+typedef struct _P2P_SCAN_REQ_INFO_T { -+ ENUM_SCAN_TYPE_T eScanType; -+ ENUM_SCAN_CHANNEL eChannelSet; -+ UINT_16 u2PassiveDewellTime; -+ UINT_8 ucSeqNumOfScnMsg; -+ BOOLEAN fgIsAbort; -+ BOOLEAN fgIsScanRequest; -+ UINT_8 ucNumChannelList; -+ RF_CHANNEL_INFO_T arScanChannelList[MAXIMUM_OPERATION_CHANNEL_LIST]; -+ UINT_32 u4BufLength; -+ UINT_8 aucIEBuf[MAX_IE_LENGTH]; -+ P2P_SSID_STRUCT_T rSsidStruct; /* Currently we can only take one SSID scan request */ -+ BOOLEAN fgIsGOInitialDone; -+} P2P_SCAN_REQ_INFO_T, *P_P2P_SCAN_REQ_INFO_T; -+ -+typedef struct _P2P_CONNECTION_REQ_INFO_T { -+ -+ BOOLEAN fgIsConnRequest; -+ P2P_SSID_STRUCT_T rSsidStruct; -+ UINT_8 aucBssid[MAC_ADDR_LEN]; -+ /* For ASSOC Req. */ -+ UINT_32 u4BufLength; -+ UINT_8 aucIEBuf[MAX_IE_LENGTH]; -+} P2P_CONNECTION_REQ_INFO_T, *P_P2P_CONNECTION_REQ_INFO_T; -+ -+typedef struct _P2P_MGMT_TX_REQ_INFO_T { -+ BOOLEAN fgIsMgmtTxRequested; -+ P_MSDU_INFO_T prMgmtTxMsdu; -+ UINT_64 u8Cookie; -+} P2P_MGMT_TX_REQ_INFO_T, *P_P2P_MGMT_TX_REQ_INFO_T; -+ -+struct _MSG_P2P_EXTEND_LISTEN_INTERVAL_T { -+ MSG_HDR_T rMsgHdr; -+ UINT_32 wait; /* interval supplicant expected to stay in listen interval */ -+}; -+ -+typedef struct _P2P_BEACON_UPDATE_INFO_T { -+ PUINT_8 pucBcnHdr; -+ UINT_32 u4BcnHdrLen; -+ PUINT_8 pucBcnBody; -+ UINT_32 u4BcnBodyLen; -+} P2P_BEACON_UPDATE_INFO_T, *P_P2P_BEACON_UPDATE_INFO_T; -+ -+typedef struct _P2P_PROBE_RSP_UPDATE_INFO_T { -+ P_MSDU_INFO_T prProbeRspMsduTemplate; -+} P2P_PROBE_RSP_UPDATE_INFO_T, *P_P2P_PROBE_RSP_UPDATE_INFO_T; -+ -+typedef struct _P2P_ASSOC_RSP_UPDATE_INFO_T { -+ PUINT_8 pucAssocRspExtIE; -+ UINT_16 u2AssocIELen; -+} P2P_ASSOC_RSP_UPDATE_INFO_T, *P_P2P_ASSOC_RSP_UPDATE_INFO_T; -+ -+typedef struct _P2P_JOIN_INFO_T { -+ UINT_32 ucSeqNumOfReqMsg; -+ UINT_8 ucAvailableAuthTypes; -+ P_STA_RECORD_T prTargetStaRec; -+ P2P_SSID_STRUCT_T rSsidStruct; -+ BOOLEAN fgIsJoinComplete; -+ /* For ASSOC Rsp. */ -+ UINT_32 u4BufLength; -+ UINT_8 aucIEBuf[MAX_IE_LENGTH]; -+} P2P_JOIN_INFO_T, *P_P2P_JOIN_INFO_T; -+ -+#if CFG_SUPPORT_WFD -+ -+#define WFD_FLAGS_DEV_INFO_VALID BIT(0) /* 1. WFD_DEV_INFO, 2. WFD_CTRL_PORT, 3. WFD_MAT_TP. */ -+#define WFD_FLAGS_SINK_INFO_VALID BIT(1) /* 1. WFD_SINK_STATUS, 2. WFD_SINK_MAC. */ -+#define WFD_FLAGS_ASSOC_MAC_VALID BIT(2) /* 1. WFD_ASSOC_MAC. */ -+#define WFD_FLAGS_EXT_CAPABILITY_VALID BIT(3) /* 1. WFD_EXTEND_CAPABILITY. */ -+ -+struct _WFD_CFG_SETTINGS_T { -+ UINT_32 u4WfdCmdType; -+ UINT_8 ucWfdEnable; -+ UINT_8 ucWfdCoupleSinkStatus; -+ UINT_8 ucWfdSessionAvailable; /* 0: NA 1:Set 2:Clear */ -+ UINT_8 ucWfdSigmaMode; -+ UINT_16 u2WfdDevInfo; -+ UINT_16 u2WfdControlPort; -+ UINT_16 u2WfdMaximumTp; -+ UINT_16 u2WfdExtendCap; -+ UINT_8 aucWfdCoupleSinkAddress[MAC_ADDR_LEN]; -+ UINT_8 aucWfdAssociatedBssid[MAC_ADDR_LEN]; -+ UINT_8 aucWfdVideoIp[4]; -+ UINT_8 aucWfdAudioIp[4]; -+ UINT_16 u2WfdVideoPort; -+ UINT_16 u2WfdAudioPort; -+ UINT_32 u4WfdFlag; -+ UINT_32 u4WfdPolicy; -+ UINT_32 u4WfdState; -+ UINT_8 aucWfdSessionInformationIE[24 * 8]; -+ UINT_16 u2WfdSessionInformationIELen; -+ UINT_8 aucReserved1[2]; -+ UINT_8 aucWfdPrimarySinkMac[MAC_ADDR_LEN]; -+ UINT_8 aucWfdSecondarySinkMac[MAC_ADDR_LEN]; -+ UINT_32 u4WfdAdvancedFlag; -+ /* Group 1 64 bytes */ -+ UINT_8 aucWfdLocalIp[4]; -+ UINT_16 u2WfdLifetimeAc2; /* Unit is 2 TU */ -+ UINT_16 u2WfdLifetimeAc3; /* Unit is 2 TU */ -+ UINT_16 u2WfdCounterThreshold; /* Unit is ms */ -+ UINT_8 aucReverved2[54]; -+ /* Group 2 64 bytes */ -+ UINT_8 aucReverved3[64]; -+ /* Group 3 64 bytes */ -+ UINT_8 aucReverved4[64]; -+ -+}; -+ -+struct _WFD_DBG_CFG_SETTINGS_T { -+ UINT_8 ucWfdDebugMode; -+ UINT_16 u2WfdSNShowPeiroid; -+ UINT_8 Reserved; -+ -+}; -+ -+#endif -+ -+struct _P2P_FSM_INFO_T { -+ /* State related. */ -+ ENUM_P2P_STATE_T ePreviousState; -+ ENUM_P2P_STATE_T eCurrentState; -+ -+ /* Channel related. */ -+ P2P_CHNL_REQ_INFO_T rChnlReqInfo; -+ -+ /* Scan related. */ -+ P2P_SCAN_REQ_INFO_T rScanReqInfo; -+ -+ /* Connection related. */ -+ P2P_CONNECTION_REQ_INFO_T rConnReqInfo; -+ -+ /* Mgmt tx related. */ -+ P2P_MGMT_TX_REQ_INFO_T rMgmtTxInfo; -+ -+ /* Beacon related. */ -+ P2P_BEACON_UPDATE_INFO_T rBcnContentInfo; -+ -+ /* Probe Response related. */ -+ P2P_PROBE_RSP_UPDATE_INFO_T rProbeRspContentInfo; -+ -+ /* Assoc Rsp related. */ -+ P2P_ASSOC_RSP_UPDATE_INFO_T rAssocRspContentInfo; -+ -+ /* GC Join related. */ -+ P2P_JOIN_INFO_T rJoinInfo; -+ -+ /* FSM Timer */ -+/* TIMER_T rP2pFsmTimeoutTimer; */ -+ -+ /* GC Target BSS. */ -+ P_BSS_DESC_T prTargetBss; -+ -+ /* GC Connection Request. */ -+ BOOLEAN fgIsConnectionRequested; -+ -+ BOOLEAN fgIsApMode; -+ -+ /* Channel grant interval. */ -+ UINT_32 u4GrantInterval; -+ -+ /* Packet filter for P2P module. */ -+ UINT_32 u4P2pPacketFilter; -+ -+ /* vvvvvvvvvvvvvvvvvvvvvvvvvvvvvv Prepare for use vvvvvvvvvvvvvvvvvvvvvvvvvvvvvv */ -+ /* Msg event queue. */ -+ LINK_T rMsgEventQueue; -+ -+#if CFG_SUPPORT_WFD -+ WFD_CFG_SETTINGS_T rWfdConfigureSettings; -+ WFD_DBG_CFG_SETTINGS_T rWfdDebugSetting; -+#endif -+ -+ BOOLEAN fgIsWPSMode; -+ -+ enum _ENUM_P2P_DEV_EXT_LISTEN_T eListenExted; -+}; -+ -+/*---------------- Messages -------------------*/ -+typedef struct _MSG_P2P_SCAN_REQUEST_T { -+ MSG_HDR_T rMsgHdr; /* Must be the first member */ -+ P_P2P_SSID_STRUCT_T prSSID; -+ INT_32 i4SsidNum; -+ UINT_32 u4NumChannel; -+ PUINT_8 pucIEBuf; -+ UINT_32 u4IELen; -+ BOOLEAN fgIsAbort; -+ RF_CHANNEL_INFO_T arChannelListInfo[1]; -+} MSG_P2P_SCAN_REQUEST_T, *P_MSG_P2P_SCAN_REQUEST_T; -+ -+typedef struct _MSG_P2P_CHNL_REQUEST_T { -+ MSG_HDR_T rMsgHdr; /* Must be the first member */ -+ UINT_64 u8Cookie; -+ UINT_32 u4Duration; -+ ENUM_CHNL_EXT_T eChnlSco; -+ RF_CHANNEL_INFO_T rChannelInfo; -+} MSG_P2P_CHNL_REQUEST_T, *P_MSG_P2P_CHNL_REQUEST_T; -+ -+typedef struct _MSG_P2P_CHNL_ABORT_T { -+ MSG_HDR_T rMsgHdr; /* Must be the first member */ -+ UINT_64 u8Cookie; -+} MSG_P2P_CHNL_ABORT_T, *P_MSG_P2P_CHNL_ABORT_T; -+ -+typedef struct _MSG_P2P_CONNECTION_REQUEST_T { -+ MSG_HDR_T rMsgHdr; /* Must be the first member */ -+ P2P_SSID_STRUCT_T rSsid; -+ UINT_8 aucBssid[MAC_ADDR_LEN]; -+ ENUM_CHNL_EXT_T eChnlSco; -+ RF_CHANNEL_INFO_T rChannelInfo; -+ UINT_32 u4IELen; -+ UINT_8 aucIEBuf[1]; -+ /* TODO: Auth Type, OPEN, SHARED, FT, EAP... */ -+} MSG_P2P_CONNECTION_REQUEST_T, *P_MSG_P2P_CONNECTION_REQUEST_T; -+ -+typedef struct _MSG_P2P_CONNECTION_ABORT_T { -+ MSG_HDR_T rMsgHdr; /* Must be the first member. */ -+ UINT_8 aucTargetID[MAC_ADDR_LEN]; -+ UINT_16 u2ReasonCode; -+ BOOLEAN fgSendDeauth; -+} MSG_P2P_CONNECTION_ABORT_T, *P_MSG_P2P_CONNECTION_ABORT_T; -+ -+typedef struct _MSG_P2P_MGMT_TX_REQUEST_T { -+ MSG_HDR_T rMsgHdr; -+ P_MSDU_INFO_T prMgmtMsduInfo; -+ UINT_64 u8Cookie; /* For indication. */ -+ BOOLEAN fgNoneCckRate; -+ BOOLEAN fgIsWaitRsp; -+} MSG_P2P_MGMT_TX_REQUEST_T, *P_MSG_P2P_MGMT_TX_REQUEST_T; -+ -+typedef struct _MSG_P2P_START_AP_T { -+ MSG_HDR_T rMsgHdr; -+ UINT_32 u4DtimPeriod; -+ UINT_32 u4BcnInterval; -+ UINT_8 aucSsid[32]; -+ UINT_16 u2SsidLen; -+ UINT_8 ucHiddenSsidType; -+ BOOLEAN fgIsPrivacy; -+ AP_CRYPTO_SETTINGS_T rEncryptionSettings; -+ INT_32 i4InactiveTimeout; -+} MSG_P2P_START_AP_T, *P_MSG_P2P_START_AP_T; -+ -+typedef struct _MSG_P2P_BEACON_UPDATE_T { -+ MSG_HDR_T rMsgHdr; -+ UINT_32 u4BcnHdrLen; -+ UINT_32 u4BcnBodyLen; -+ PUINT_8 pucBcnHdr; -+ PUINT_8 pucBcnBody; -+ UINT_8 aucBuffer[1]; /* Header & Body are put here. */ -+} MSG_P2P_BEACON_UPDATE_T, *P_MSG_P2P_BEACON_UPDATE_T; -+ -+typedef struct _MSG_P2P_MGMT_FRAME_UPDATE_T { -+ MSG_HDR_T rMsgHdr; -+ ENUM_BUFFER_TYPE_T eBufferType; -+ UINT_32 u4BufferLen; -+ UINT_8 aucBuffer[1]; -+} MSG_P2P_MGMT_FRAME_UPDATE_T, *P_MSG_P2P_MGMT_FRAME_UPDATE_T; -+ -+typedef struct _MSG_P2P_SWITCH_OP_MODE_T { -+ MSG_HDR_T rMsgHdr; /* Must be the first member */ -+ ENUM_OP_MODE_T eOpMode; -+} MSG_P2P_SWITCH_OP_MODE_T, *P_MSG_P2P_SWITCH_OP_MODE_T; -+ -+typedef struct _MSG_P2P_MGMT_FRAME_REGISTER_T { -+ MSG_HDR_T rMsgHdr; /* Must be the first member */ -+ UINT_16 u2FrameType; -+ BOOLEAN fgIsRegister; -+} MSG_P2P_MGMT_FRAME_REGISTER_T, *P_MSG_P2P_MGMT_FRAME_REGISTER_T; -+ -+typedef struct _MSG_P2P_NETDEV_REGISTER_T { -+ MSG_HDR_T rMsgHdr; /* Must be the first member */ -+ BOOLEAN fgIsEnable; -+ UINT_8 ucMode; -+} MSG_P2P_NETDEV_REGISTER_T, *P_MSG_P2P_NETDEV_REGISTER_T; -+ -+#if CFG_SUPPORT_WFD -+typedef struct _MSG_WFD_CONFIG_SETTINGS_CHANGED_T { -+ MSG_HDR_T rMsgHdr; /* Must be the first member */ -+ P_WFD_CFG_SETTINGS_T prWfdCfgSettings; -+} MSG_WFD_CONFIG_SETTINGS_CHANGED_T, *P_MSG_WFD_CONFIG_SETTINGS_CHANGED_T; -+#endif -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+VOID p2pFsmStateTransition(IN P_ADAPTER_T prAdapter, IN P_P2P_FSM_INFO_T prP2pFsmInfo, IN ENUM_P2P_STATE_T eNextState); -+ -+VOID p2pFsmRunEventAbort(IN P_ADAPTER_T prAdapter, IN P_P2P_FSM_INFO_T prP2pFsmInfo); -+ -+VOID p2pFsmRunEventScanRequest(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); -+ -+VOID p2pFsmRunEventMgmtFrameTx(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); -+ -+VOID p2pFsmRunEventStartAP(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); -+ -+VOID p2pFsmRunEventNetDeviceRegister(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); -+ -+VOID p2pFsmRunEventUpdateMgmtFrame(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); -+ -+VOID p2pFsmRunEventExtendListen(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); -+ -+VOID p2pFsmRunEventBeaconUpdate(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); -+ -+VOID p2pFsmRunEventStopAP(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); -+ -+VOID p2pFsmRunEventChannelRequest(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); -+ -+VOID p2pFsmRunEventChannelAbort(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); -+ -+VOID p2pFsmRunEventDissolve(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); -+ -+VOID p2pFsmRunEventSwitchOPMode(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); -+ -+WLAN_STATUS -+p2pFsmRunEventMgmtFrameTxDone(IN P_ADAPTER_T prAdapter, -+ IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus); -+ -+VOID p2pFsmRunEventMgmtFrameRegister(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); -+ -+#if CFG_SUPPORT_WFD -+VOID p2pFsmRunEventWfdSettingUpdate(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); -+#endif -+ -+#if 0 -+/* ////////////////////////////////////////////////////////////////////////////////////////////////////// */ -+/* ///////////////////////////////////////////////////////////////////////////////////// */ -+/* ///////////////////////////////////////////////////////////////////////////////////// */ -+/* ///////////////////////////////////////////////////////////////////////////////////// */ -+/* ///////////////////////////////////////////////////////////////////////////////////// */ -+/* ////////////////////////////////////////////////////////////////////////////////////////////////////// */ -+#endif -+ -+/* 3 --------------- WFA P2P DEFAULT PARAMETERS --------------- */ -+#define P2P_WILDCARD_SSID "DIRECT-" -+#define P2P_WILDCARD_SSID_LEN 7 -+#define P2P_GROUP_ID_LEN 9 -+ -+#define P2P_DRIVER_VERSION 2 /* Update when needed. */ -+ -+#define P2P_DEFAULT_DEV_NAME "Wireless Client" -+#define P2P_DEFAULT_DEV_NAME_LEN 15 -+#define P2P_DEFAULT_PRIMARY_CATEGORY_ID 10 -+#define P2P_DEFAULT_PRIMARY_SUB_CATEGORY_ID 5 -+#define P2P_DEFAULT_CONFIG_METHOD \ -+ (WPS_ATTRI_CFG_METHOD_PUSH_BUTTON | WPS_ATTRI_CFG_METHOD_KEYPAD | WPS_ATTRI_CFG_METHOD_DISPLAY) -+#define P2P_DEFAULT_LISTEN_CHANNEL 1 -+ -+#define P2P_MAX_SUPPORTED_SEC_DEV_TYPE_COUNT 0 /* NOTE(Kevin): Shall <= 16 */ -+#define P2P_MAX_SUPPORTED_CHANNEL_LIST_COUNT 13 -+ -+#define P2P_MAX_SUPPORTED_CHANNEL_LIST_SIZE 51 /* Contains 6 sub-band. */ -+ -+#define P2P_GC_MAX_CACHED_SEC_DEV_TYPE_COUNT 8 /* NOTE(Kevin): Shall <= 16 */ -+ -+#define P2P_MAXIMUM_CLIENT_COUNT 8 -+#define P2P_MAXIMUM_NOA_COUNT 8 -+ -+#define P2P_MAXIMUM_ATTRIBUTE_LEN 251 -+ -+#define P2P_CTWINDOW_DEFAULT 25 /* in TU=(1024usec) */ -+ -+#define P2P_MAXIMUM_ATTRIBUTES_CACHE_SIZE 768 -+ -+/* P2P 3.1.2.1.3 - Find Phase */ -+#define P2P_MAX_DISCOVERABLE_INTERVAL 8 /* 3 */ -+#define P2P_MIN_DISCOVERABLE_INTERVAL 5 /* 1 */ -+ -+#define P2P_LISTEN_SCAN_UNIT 100 /* MS */ -+ -+/* FSM Time Related constrain. */ -+#define P2P_SERACH_STATE_PERIOD_MS 1000 /* Deprecated. */ -+ -+#define P2P_GO_CHANNEL_STAY_INTERVAL 1000 -+ -+#define P2P_GO_NEGO_TIMEOUT_MS 500 -+#define P2P_CONNECTION_TIMEOUT_SEC 120 -+ -+#define P2P_INVITAION_TIMEOUT_MS 500 /* Timeout Wait Invitation Resonse. */ -+#define P2P_PROVISION_DISCOVERY_TIMEOUT_MS 500 /* Timeout Wait Provision Discovery Resonse. */ -+ -+/* 3 --------------- WFA P2P IE --------------- */ -+/* P2P 4.1.1 - P2P IE format */ -+#define P2P_OUI_TYPE_LEN 4 -+#define P2P_IE_OUI_HDR (ELEM_HDR_LEN + P2P_OUI_TYPE_LEN) /* == OFFSET_OF(IE_P2P_T, -+ aucP2PAttributes[0]) */ -+ -+/* P2P 4.1.1 - General P2P Attribute */ -+#define P2P_ATTRI_HDR_LEN 3 /* ID(1 octet) + Length(2 octets) */ -+#define P2P_ATTRI_LEN_NOTICE_OF_ABSENCE (P2P_ATTRI_HDR_LEN + 2) /* 5 */ -+ -+/* P2P 4.1.1 - P2P Attribute ID definitions */ -+#define P2P_ATTRI_ID_STATUS 0 -+#define P2P_ATTRI_ID_REASON_CODE 1 -+#define P2P_ATTRI_ID_P2P_CAPABILITY 2 -+#define P2P_ATTRI_ID_P2P_DEV_ID 3 -+#define P2P_ATTRI_ID_GO_INTENT 4 -+#define P2P_ATTRI_ID_CFG_TIMEOUT 5 -+#define P2P_ATTRI_ID_LISTEN_CHANNEL 6 -+#define P2P_ATTRI_ID_P2P_GROUP_BSSID 7 -+#define P2P_ATTRI_ID_EXT_LISTEN_TIMING 8 -+#define P2P_ATTRI_ID_INTENDED_P2P_IF_ADDR 9 -+#define P2P_ATTRI_ID_P2P_MANAGEABILITY 10 -+#define P2P_ATTRI_ID_CHANNEL_LIST 11 -+#define P2P_ATTRI_ID_NOTICE_OF_ABSENCE 12 -+#define P2P_ATTRI_ID_P2P_DEV_INFO 13 -+#define P2P_ATTRI_ID_P2P_GROUP_INFO 14 -+#define P2P_ATTRI_ID_P2P_GROUP_ID 15 -+#define P2P_ATTRI_ID_P2P_INTERFACE 16 -+#define P2P_ATTRI_ID_OPERATING_CHANNEL 17 -+#define P2P_ATTRI_ID_INVITATION_FLAG 18 -+#define P2P_ATTRI_ID_VENDOR_SPECIFIC 221 -+ -+/* Maximum Length of P2P Attributes */ -+#define P2P_ATTRI_MAX_LEN_STATUS 1 /* 0 */ -+#define P2P_ATTRI_MAX_LEN_REASON_CODE 1 /* 1 */ -+#define P2P_ATTRI_MAX_LEN_P2P_CAPABILITY 2 /* 2 */ -+#define P2P_ATTRI_MAX_LEN_P2P_DEV_ID 6 /* 3 */ -+#define P2P_ATTRI_MAX_LEN_GO_INTENT 1 /* 4 */ -+#define P2P_ATTRI_MAX_LEN_CFG_TIMEOUT 2 /* 5 */ -+#if CID52_53_54 -+#define P2P_ATTRI_MAX_LEN_LISTEN_CHANNEL 5 /* 6 */ -+#else -+#define P2P_ATTRI_MAX_LEN_LISTEN_CHANNEL 5 /* 6 */ -+#endif -+#define P2P_ATTRI_MAX_LEN_P2P_GROUP_BSSID 6 /* 7 */ -+#define P2P_ATTRI_MAX_LEN_EXT_LISTEN_TIMING 4 /* 8 */ -+#define P2P_ATTRI_MAX_LEN_INTENDED_P2P_IF_ADDR 6 /* 9 */ -+#define P2P_ATTRI_MAX_LEN_P2P_MANAGEABILITY 1 /* 10 */ -+/* #define P2P_ATTRI_MAX_LEN_CHANNEL_LIST 3 + (n* (2 + num_of_ch)) */ /* 11 */ -+#define P2P_ATTRI_LEN_CHANNEL_LIST 3 /* 11 */ -+#define P2P_ATTRI_LEN_CHANNEL_ENTRY 2 /* 11 */ -+ -+/* #define P2P_ATTRI_MAX_LEN_NOTICE_OF_ABSENCE 2 + (n* (13)) */ /* 12 */ -+#define P2P_ATTRI_MAX_LEN_NOTICE_OF_ABSENCE (2 + (P2P_MAXIMUM_NOA_COUNT*(13))) /* 12 */ -+ -+#define P2P_ATTRI_MAX_LEN_P2P_DEV_INFO (17 + (8 * (8)) + 36) /* 13 */ -+/* #define P2P_ATTRI_MAX_LEN_P2P_GROUP_INFO n* (25 + (m* (8)) + 32) */ /* 14 */ -+#define P2P_ATTRI_MAX_LEN_P2P_GROUP_ID 38 /* 15 */ -+#define P2P_ATTRI_MAX_LEN_P2P_INTERFACE 253 /* 7 + 6* [0~41] */ /* 16 */ -+#if CID52_53_54 -+#define P2P_ATTRI_MAX_LEN_OPERATING_CHANNEL 5 /* 17 */ -+#else -+#define P2P_ATTRI_MAX_LEN_OPERATING_CHANNEL 5 /* 17 */ -+#endif -+#define P2P_ATTRI_MAX_LEN_INVITATION_FLAGS 1 /* 18 */ -+ -+/* P2P 4.1.2 - P2P Status definitions */ -+#define P2P_STATUS_SUCCESS 0 -+#define P2P_STATUS_FAIL_INFO_IS_CURRENTLY_UNAVAILABLE 1 -+#define P2P_STATUS_FAIL_INCOMPATIBLE_PARAM 2 -+#define P2P_STATUS_FAIL_LIMIT_REACHED 3 -+#define P2P_STATUS_FAIL_INVALID_PARAM 4 -+#define P2P_STATUS_FAIL_UNABLE_ACCOMMODATE_REQ 5 -+#define P2P_STATUS_FAIL_PREVIOUS_PROTOCOL_ERR 6 -+#define P2P_STATUS_FAIL_NO_COMMON_CHANNELS 7 -+#define P2P_STATUS_FAIL_UNKNOWN_P2P_GROUP 8 -+#define P2P_STATUS_FAIL_SAME_INTENT_VALUE_15 9 -+#define P2P_STATUS_FAIL_INCOMPATIBLE_PROVISION_METHOD 10 -+#define P2P_STATUS_FAIL_REJECTED_BY_USER 11 -+ -+/* P2P 4.1.3 - P2P Minor Reason Code definitions */ -+#define P2P_REASON_SUCCESS 0 -+#define P2P_REASON_DISASSOCIATED_DUE_CROSS_CONNECTION 1 -+#define P2P_REASON_DISASSOCIATED_DUE_UNMANAGEABLE 2 -+#define P2P_REASON_DISASSOCIATED_DUE_NO_P2P_COEXIST_PARAM 3 -+#define P2P_REASON_DISASSOCIATED_DUE_MANAGEABLE 4 -+ -+/* P2P 4.1.4 - Device Capability Bitmap definitions */ -+#define P2P_DEV_CAPABILITY_SERVICE_DISCOVERY BIT(0) -+#define P2P_DEV_CAPABILITY_CLIENT_DISCOVERABILITY BIT(1) -+#define P2P_DEV_CAPABILITY_CONCURRENT_OPERATION BIT(2) -+#define P2P_DEV_CAPABILITY_P2P_INFRA_MANAGED BIT(3) -+#define P2P_DEV_CAPABILITY_P2P_DEVICE_LIMIT BIT(4) -+#define P2P_DEV_CAPABILITY_P2P_INVITATION_PROCEDURE BIT(5) -+ -+/* P2P 4.1.4 - Group Capability Bitmap definitions */ -+#define P2P_GROUP_CAPABILITY_P2P_GROUP_OWNER BIT(0) -+#define P2P_GROUP_CAPABILITY_PERSISTENT_P2P_GROUP BIT(1) -+#define P2P_GROUP_CAPABILITY_P2P_GROUP_LIMIT BIT(2) -+#define P2P_GROUP_CAPABILITY_INTRA_BSS_DISTRIBUTION BIT(3) -+#define P2P_GROUP_CAPABILITY_CROSS_CONNECTION BIT(4) -+#define P2P_GROUP_CAPABILITY_PERSISTENT_RECONNECT BIT(5) -+#define P2P_GROUP_CAPABILITY_GROUP_FORMATION BIT(6) -+ -+/* P2P 4.1.6 - GO Intent field definitions */ -+#define P2P_GO_INTENT_TIE_BREAKER_FIELD BIT(0) -+#define P2P_GO_INTENT_VALUE_MASK BITS(1, 7) -+#define P2P_GO_INTENT_VALUE_OFFSET 1 -+ -+/* P2P 4.1.12 - Manageability Bitmap definitions */ -+#define P2P_DEVICE_MANAGEMENT BIT(0) -+ -+/* P2P 4.1.14 - CTWindow and OppPS Parameters definitions */ -+#define P2P_CTW_OPPPS_PARAM_OPPPS_FIELD BIT(7) -+#define P2P_CTW_OPPPS_PARAM_CTWINDOW_MASK BITS(0, 6) -+ -+#define ELEM_MAX_LEN_P2P_FOR_PROBE_REQ \ -+ (P2P_OUI_TYPE_LEN + \ -+ (P2P_ATTRI_HDR_LEN + P2P_ATTRI_MAX_LEN_P2P_CAPABILITY) + \ -+ (P2P_ATTRI_HDR_LEN + P2P_ATTRI_MAX_LEN_P2P_DEV_ID) + \ -+ (P2P_ATTRI_HDR_LEN + P2P_ATTRI_MAX_LEN_LISTEN_CHANNEL) + \ -+ (P2P_ATTRI_HDR_LEN + P2P_ATTRI_MAX_LEN_OPERATING_CHANNEL)) -+ -+#define ELEM_MAX_LEN_P2P_FOR_ASSOC_REQ \ -+ (P2P_OUI_TYPE_LEN + \ -+ (P2P_ATTRI_HDR_LEN + P2P_ATTRI_MAX_LEN_P2P_CAPABILITY) + \ -+ (P2P_ATTRI_HDR_LEN + P2P_ATTRI_MAX_LEN_EXT_LISTEN_TIMING) + \ -+ (P2P_ATTRI_HDR_LEN + P2P_ATTRI_MAX_LEN_P2P_DEV_INFO)) -+ -+/* P2P 4.1.16 - P2P Client Infor Descriptor */ -+#define P2P_CLIENT_INFO_DESC_HDR_LEN 1 /* Length(1 octets) */ -+ -+/* P2P 4.1.20 - P2P Invitation Flags Attribute*/ -+#define P2P_INVITATION_FLAGS_INVITATION_TYPE BIT(0) -+#define P2P_INVITATION_TYPE_INVITATION 0 -+#define P2P_INVITATION_TYPE_REINVOKE 1 -+/* 3 --------------- WPS Data Element Definitions --------------- */ -+/* P2P 4.2.2 - General WSC Attribute */ -+#define WSC_ATTRI_HDR_LEN 4 /* ID(2 octet) + Length(2 octets) */ -+#define WSC_ATTRI_MAX_LEN_VERSION 1 -+#define WSC_ATTRI_MAX_LEN_DEVICE_PASSWORD_ID 2 -+#define WSC_ATTRI_LEN_CONFIG_METHOD 2 -+ -+/* WPS 11 - Data Element Definitions */ -+#define WPS_ATTRI_ID_VERSION 0x104A -+#define WPS_ATTRI_ID_CONFIGURATION_METHODS 0x1008 -+#define WPS_ATTRI_ID_DEVICE_PASSWORD 0x1012 -+#define WPS_ATTRI_ID_DEVICE_NAME 0x1011 -+#define WPS_ATTRI_ID_PRI_DEVICE_TYPE 0x1054 -+#define WPS_ATTRI_ID_SEC_DEVICE_TYPE 0x1055 -+ -+#define WPS_MAXIMUM_ATTRIBUTES_CACHE_SIZE 300 -+ -+#define WPS_ATTRI_MAX_LEN_DEVICE_NAME 32 /* 0x1011 */ -+ -+#define WPS_ATTRI_CFG_METHOD_USBA BIT(0) -+#define WPS_ATTRI_CFG_METHOD_ETHERNET BIT(1) -+#define WPS_ATTRI_CFG_METHOD_LABEL BIT(2) -+#define WPS_ATTRI_CFG_METHOD_DISPLAY BIT(3) -+#define WPS_ATTRI_CFG_METHOD_EXT_NFC BIT(4) -+#define WPS_ATTRI_CFG_METHOD_INT_NFC BIT(5) -+#define WPS_ATTRI_CFG_METHOD_NFC_IF BIT(6) -+#define WPS_ATTRI_CFG_METHOD_PUSH_BUTTON BIT(7) -+#define WPS_ATTRI_CFG_METHOD_KEYPAD BIT(8) -+ -+#define P2P_FLAGS_PROVISION_COMPLETE 0x00000001 -+#define P2P_FLAGS_PROVISION_DISCOVERY_COMPLETE 0x00000002 -+#define P2P_FLAGS_PROVISION_DISCOVERY_WAIT_RESPONSE 0x00000004 -+#define P2P_FLAGS_PROVISION_DISCOVERY_RESPONSE_WAIT 0x00000008 -+#define P2P_FLAGS_MASK_PROVISION 0x00000017 -+#define P2P_FLAGS_MASK_PROVISION_COMPLETE 0x00000015 -+#define P2P_FLAGS_PROVISION_DISCOVERY_INDICATED 0x00000010 -+#define P2P_FLAGS_INVITATION_TOBE_GO 0x00000100 -+#define P2P_FLAGS_INVITATION_TOBE_GC 0x00000200 -+#define P2P_FLAGS_INVITATION_SUCCESS 0x00000400 -+#define P2P_FLAGS_INVITATION_WAITING_TARGET 0x00000800 -+#define P2P_FLAGS_MASK_INVITATION 0x00000F00 -+#define P2P_FLAGS_FORMATION_ON_GOING 0x00010000 -+#define P2P_FLAGS_FORMATION_LOCAL_PWID_RDY 0x00020000 -+#define P2P_FLAGS_FORMATION_TARGET_PWID_RDY 0x00040000 -+#define P2P_FLAGS_FORMATION_COMPLETE 0x00080000 -+#define P2P_FLAGS_MASK_FORMATION 0x000F0000 -+#define P2P_FLAGS_DEVICE_DISCOVER_REQ 0x00100000 -+#define P2P_FLAGS_DEVICE_DISCOVER_DONE 0x00200000 -+#define P2P_FLAGS_DEVICE_INVITATION_WAIT 0x00400000 -+#define P2P_FLAGS_DEVICE_SERVICE_DISCOVER_WAIT 0x00800000 -+#define P2P_FLAGS_MASK_DEVICE_DISCOVER 0x00F00000 -+ -+#define P2P_FLAGS_DEVICE_FORMATION_REQUEST 0x01000000 -+ -+/* MACRO for flag operation */ -+#define SET_FLAGS(_FlagsVar, _BitsToSet) \ -+ {(_FlagsVar) = ((_FlagsVar) | (_BitsToSet))} -+ -+#define TEST_FLAGS(_FlagsVar, _BitsToCheck) \ -+ (((_FlagsVar) & (_BitsToCheck)) == (_BitsToCheck)) -+ -+#define CLEAR_FLAGS(_FlagsVar, _BitsToClear) \ -+ {(_FlagsVar) &= ~(_BitsToClear)} -+ -+#define CFG_DISABLE_WIFI_DIRECT_ENHANCEMENT_I 0 -+ -+#define CFG_DISABLE_WIFI_DIRECT_ENHANCEMENT_II 0 -+ -+#define CFG_DISABLE_WIFI_DIRECT_ENHANCEMENT_III 0 -+ -+#define CFG_DISABLE_WIFI_DIRECT_ENHANCEMENT_IV 0 -+ -+#define CFG_DISABLE_DELAY_PROVISION_DISCOVERY 0 -+ -+#define CFG_CONNECTION_POLICY_2_0 0 -+ -+/* Device Password ID */ -+enum wps_dev_password_id { -+ DEV_PW_DEFAULT = 0x0000, -+ DEV_PW_USER_SPECIFIED = 0x0001, -+ DEV_PW_MACHINE_SPECIFIED = 0x0002, -+ DEV_PW_REKEY = 0x0003, -+ DEV_PW_PUSHBUTTON = 0x0004, -+ DEV_PW_REGISTRAR_SPECIFIED = 0x0005 -+}; -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+#if defined(WINDOWS_DDK) || defined(WINDOWS_CE) -+#pragma pack(1) -+#endif -+ -+/* 3 --------------- WFA P2P IE and Attributes --------------- */ -+ -+/* P2P 4.1.1 - P2P Information Element */ -+typedef struct _IE_P2P_T { -+ UINT_8 ucId; /* Element ID */ -+ UINT_8 ucLength; /* Length */ -+ UINT_8 aucOui[3]; /* OUI */ -+ UINT_8 ucOuiType; /* OUI Type */ -+ UINT_8 aucP2PAttributes[1]; /* P2P Attributes */ -+} __KAL_ATTRIB_PACKED__ IE_P2P_T, *P_IE_P2P_T; -+ -+/* P2P 4.1.1 - General P2P Attribute */ -+typedef struct _P2P_ATTRIBUTE_T { -+ UINT_8 ucId; /* Attribute ID */ -+ UINT_16 u2Length; /* Length */ -+ UINT_8 aucBody[1]; /* Body field */ -+} __KAL_ATTRIB_PACKED__ P2P_ATTRIBUTE_T, ATTRIBUTE_HDR_T, *P_P2P_ATTRIBUTE_T, *P_ATTRIBUTE_HDR_T; -+ -+/* P2P 4.1.2 - P2P Status Attribute */ -+typedef struct _P2P_ATTRI_STATUS_T { -+ UINT_8 ucId; /* Attribute ID */ -+ UINT_16 u2Length; /* Length */ -+ UINT_8 ucStatusCode; /* Status Code */ -+} __KAL_ATTRIB_PACKED__ P2P_ATTRI_STATUS_T, *P_P2P_ATTRI_STATUS_T; -+ -+/* P2P 4.1.3 - P2P Minor Reason Code Attribute */ -+typedef struct _P2P_ATTRI_REASON_T { -+ UINT_8 ucId; /* Attribute ID */ -+ UINT_16 u2Length; /* Length */ -+ UINT_8 ucMinorReasonCode; /* Minor Reason Code */ -+} __KAL_ATTRIB_PACKED__ P2P_ATTRI_REASON_T, *P_P2P_ATTRI_REASON_T; -+ -+/* P2P 4.1.4 - P2P Capability Attribute */ -+typedef struct _P2P_ATTRI_CAPABILITY_T { -+ UINT_8 ucId; /* Attribute ID */ -+ UINT_16 u2Length; /* Length */ -+ UINT_8 ucDeviceCap; /* Device Capability Bitmap */ -+ UINT_8 ucGroupCap; /* Group Capability Bitmap */ -+} __KAL_ATTRIB_PACKED__ P2P_ATTRI_CAPABILITY_T, *P_P2P_ATTRI_CAPABILITY_T; -+ -+/* P2P 4.1.5 - P2P Device ID Attribute */ -+typedef struct _P2P_ATTRI_DEV_ID_T { -+ UINT_8 ucId; /* Attribute ID */ -+ UINT_16 u2Length; /* Length */ -+ UINT_8 aucDevAddr[MAC_ADDR_LEN]; /* P2P Device Address */ -+} __KAL_ATTRIB_PACKED__ P2P_ATTRI_DEV_ID_T, *P_P2P_ATTRI_DEV_ID_T; -+ -+/* P2P 4.1.6 - Group Owner Intent Attribute */ -+typedef struct _P2P_ATTRI_GO_INTENT_T { -+ UINT_8 ucId; /* Attribute ID */ -+ UINT_16 u2Length; /* Length */ -+ UINT_8 ucGOIntent; /* Group Owner Intent */ -+} __KAL_ATTRIB_PACKED__ P2P_ATTRI_GO_INTENT_T, *P_P2P_ATTRI_GO_INTENT_T; -+ -+/* P2P 4.1.7 - Configuration Timeout Attribute */ -+typedef struct _P2P_ATTRI_CFG_TIMEOUT_T { -+ UINT_8 ucId; /* Attribute ID */ -+ UINT_16 u2Length; /* Length */ -+ UINT_8 ucGOCfgTimeout; /* GO Configuration Timeout */ -+ UINT_8 ucClientCfgTimeout; /* Client Configuration Timeout */ -+} __KAL_ATTRIB_PACKED__ P2P_ATTRI_CFG_TIMEOUT_T, *P_P2P_ATTRI_CFG_TIMEOUT_T; -+ -+/* P2P 4.1.8 - Listen Channel Attribute */ -+typedef struct _P2P_ATTRI_LISTEN_CHANNEL_T { -+ UINT_8 ucId; /* Attribute ID */ -+ UINT_16 u2Length; /* Length */ -+ UINT_8 aucCountryString[3]; /* Country String */ -+ UINT_8 ucOperatingClass; /* Operating Class from 802.11 Annex J/P802.11 REVmb 3.0 */ -+ UINT_8 ucChannelNumber; /* Channel Number */ -+} __KAL_ATTRIB_PACKED__ P2P_ATTRI_LISTEN_CHANNEL_T, *P_P2P_ATTRI_LISTEN_CHANNEL_T; -+ -+/* P2P 4.1.9 - P2P Group BSSID Attribute */ -+typedef struct _P2P_ATTRI_GROUP_BSSID_T { -+ UINT_8 ucId; /* Attribute ID */ -+ UINT_16 u2Length; /* Length */ -+ UINT_8 aucBssid[MAC_ADDR_LEN]; /* P2P Group BSSID */ -+} __KAL_ATTRIB_PACKED__ P2P_ATTRI_GROUP_BSSID_T, *P_P2P_ATTRI_GROUP_BSSID_T; -+ -+/* P2P 4.1.10 - Extended Listen Timing Attribute */ -+typedef struct _P2P_ATTRI_EXT_LISTEN_TIMING_T { -+ UINT_8 ucId; /* Attribute ID */ -+ UINT_16 u2Length; /* Length */ -+ UINT_16 u2AvailPeriod; /* Availability Period */ -+ UINT_16 u2AvailInterval; /* Availability Interval */ -+} __KAL_ATTRIB_PACKED__ P2P_ATTRI_EXT_LISTEN_TIMING_T, *P_P2P_ATTRI_EXT_LISTEN_TIMING_T; -+ -+/* P2P 4.1.11 - Intended P2P Interface Address Attribute */ -+typedef struct _P2P_ATTRI_INTENDED_IF_ADDR_T { -+ UINT_8 ucId; /* Attribute ID */ -+ UINT_16 u2Length; /* Length */ -+ UINT_8 aucIfAddr[MAC_ADDR_LEN]; /* P2P Interface Address */ -+} __KAL_ATTRIB_PACKED__ P2P_ATTRI_INTENDED_IF_ADDR_T, *P_P2P_ATTRI_INTENDED_IF_ADDR_T; -+ -+/* P2P 4.1.12 - P2P Manageability Attribute */ -+typedef struct _P2P_ATTRI_MANAGEABILITY_T { -+ UINT_8 ucId; /* Attribute ID */ -+ UINT_16 u2Length; /* Length */ -+ UINT_8 ucManageability; /* P2P Manageability Bitmap */ -+} __KAL_ATTRIB_PACKED__ P2P_ATTRI_MANAGEABILITY_T, *P_P2P_ATTRI_MANAGEABILITY_T; -+ -+/* P2P 4.1.13 - Channel List Attribute */ -+typedef struct _P2P_ATTRI_CHANNEL_LIST_T { -+ UINT_8 ucId; /* Attribute ID */ -+ UINT_16 u2Length; /* Length */ -+ UINT_8 aucCountryString[3]; /* Country String */ -+ UINT_8 aucChannelEntry[1]; /* Channel Entry List */ -+} __KAL_ATTRIB_PACKED__ P2P_ATTRI_CHANNEL_T, *P_P2P_ATTRI_CHANNEL_T; -+ -+typedef struct _CHANNEL_ENTRY_FIELD_T { -+ UINT_8 ucRegulatoryClass; /* Regulatory Class */ -+ UINT_8 ucNumberOfChannels; /* Number Of Channels */ -+ UINT_8 aucChannelList[1]; /* Channel List */ -+} __KAL_ATTRIB_PACKED__ CHANNEL_ENTRY_FIELD_T, *P_CHANNEL_ENTRY_FIELD_T; -+ -+/* P2P 4.1.14 - Notice of Absence Attribute */ -+typedef struct _P2P_ATTRI_NOA_T { -+ UINT_8 ucId; /* Attribute ID */ -+ UINT_16 u2Length; /* Length */ -+ UINT_8 ucIndex; /* Index */ -+ UINT_8 ucCTWOppPSParam; /* CTWindow and OppPS Parameters */ -+ UINT_8 aucNoADesc[1]; /* NoA Descriptor */ -+} __KAL_ATTRIB_PACKED__ P2P_ATTRI_NOA_T, *P_P2P_ATTRI_NOA_T; -+ -+typedef struct _NOA_DESCRIPTOR_T { -+ UINT_8 ucCountType; /* Count/Type */ -+ UINT_32 u4Duration; /* Duration */ -+ UINT_32 u4Interval; /* Interval */ -+ UINT_32 u4StartTime; /* Start Time */ -+} __KAL_ATTRIB_PACKED__ NOA_DESCRIPTOR_T, *P_NOA_DESCRIPTOR_T; -+ -+typedef struct _P2P_ATTRI_DEV_INFO_T { -+ UINT_8 ucId; /* Attribute ID */ -+ UINT_16 u2Length; /* Length */ -+ UINT_8 aucDevAddr[MAC_ADDR_LEN]; /* P2P Device Address */ -+ UINT_16 u2ConfigMethodsBE; /* Config Method */ -+ DEVICE_TYPE_T rPrimaryDevTypeBE; /* Primary Device Type */ -+ UINT_8 ucNumOfSecondaryDevType; /* Number of Secondary Device Types */ -+ DEVICE_TYPE_T arSecondaryDevTypeListBE[1]; /* Secondary Device Type List */ -+} __KAL_ATTRIB_PACKED__ P2P_ATTRI_DEV_INFO_T, *P_P2P_ATTRI_DEV_INFO_T; -+ -+/* WPS 7.1 & 11 WPS TLV Data Format - Device Name */ -+typedef struct _DEVICE_NAME_TLV_T { -+ UINT_16 u2Id; /* WPS Attribute Type */ -+ UINT_16 u2Length; /* Data Length */ -+ UINT_8 aucName[32]; /* Device Name */ /* TODO: Fixme */ -+} __KAL_ATTRIB_PACKED__ DEVICE_NAME_TLV_T, *P_DEVICE_NAME_TLV_T; -+ -+/* P2P 4.1.16 - P2P Group Info Attribute */ -+typedef struct _P2P_CLIENT_INFO_DESC_T { -+ UINT_8 ucLength; /* Length */ -+ UINT_8 aucDevAddr[MAC_ADDR_LEN]; /* P2P Device Address */ -+ UINT_8 aucIfAddr[MAC_ADDR_LEN]; /* P2P Interface Address */ -+ UINT_8 ucDeviceCap; /* Device Capability Bitmap */ -+ UINT_16 u2ConfigMethodsBE; /* Config Method */ -+ DEVICE_TYPE_T rPrimaryDevTypeBE; /* Primary Device Type */ -+ UINT_8 ucNumOfSecondaryDevType; /* Number of Secondary Device Types */ -+ DEVICE_TYPE_T arSecondaryDevTypeListBE[1]; /* Secondary Device Type List */ -+} __KAL_ATTRIB_PACKED__ P2P_CLIENT_INFO_DESC_T, *P_P2P_CLIENT_INFO_DESC_T; -+ -+typedef struct _P2P_ATTRI_GROUP_INFO_T { -+ UINT_8 ucId; /* Attribute ID */ -+ UINT_16 u2Length; /* Length */ -+ P2P_CLIENT_INFO_DESC_T arClientDesc[1]; /* P2P Client Info Descriptors */ -+} __KAL_ATTRIB_PACKED__ P2P_ATTRI_GROUP_INFO_T, *P_P2P_ATTRI_GROUP_INFO_T; -+ -+/* P2P 4.1.17 - P2P Group ID Attribute */ -+typedef struct _P2P_ATTRI_GROUP_ID_T { -+ UINT_8 ucId; /* Attribute ID */ -+ UINT_16 u2Length; /* Length */ -+ UINT_8 aucDevAddr[MAC_ADDR_LEN]; /* P2P Device Address */ -+ UINT_8 aucSSID[ELEM_MAX_LEN_SSID]; /* SSID */ -+} __KAL_ATTRIB_PACKED__ P2P_ATTRI_GROUP_ID_T, *P_P2P_ATTRI_GROUP_ID_T; -+ -+/* P2P 4.1.18 - P2P Interface Attribute */ -+typedef struct _P2P_ATTRI_INTERFACE_T { -+ UINT_8 ucId; /* Attribute ID */ -+ UINT_16 u2Length; /* Length */ -+ UINT_8 aucDevAddr[MAC_ADDR_LEN]; /* P2P Device Address */ -+ UINT_8 ucIfAddrCount; /* P2P Interface Address Count */ -+ UINT_8 aucIfAddrList[MAC_ADDR_LEN]; /* P2P Interface Address List */ -+} __KAL_ATTRIB_PACKED__ P2P_ATTRI_INTERFACE_T, *P_P2P_ATTRI_INTERFACE_T; -+ -+/* P2P 4.1.19 - Operating Channel Attribute */ -+typedef struct _P2P_ATTRI_OPERATING_CHANNEL_T { -+ UINT_8 ucId; /* Attribute ID */ -+ UINT_16 u2Length; /* Length */ -+ UINT_8 aucCountryString[3]; /* Country String */ -+ UINT_8 ucOperatingClass; /* Operating Class from 802.11 Annex J/P802.11 REVmb 3.0 */ -+ UINT_8 ucChannelNumber; /* Channel Number */ -+} __KAL_ATTRIB_PACKED__ P2P_ATTRI_OPERATING_CHANNEL_T, *P_P2P_ATTRI_OPERATING_CHANNEL_T; -+ -+/* P2P 4.1.20 - Invitation Flags Attribute */ -+typedef struct _P2P_ATTRI_INVITATION_FLAG_T { -+ UINT_8 ucId; /* Attribute ID */ -+ UINT_16 u2Length; /* Length */ -+ UINT_8 ucInviteFlagsBitmap; /* Invitation Flags Bitmap */ -+} __KAL_ATTRIB_PACKED__ P2P_ATTRI_INVITATION_FLAG_T, *P_P2P_ATTRI_INVITATION_FLAG_T; -+ -+/* P2P 4.1.1 - General WSC Attribute */ -+typedef struct _WSC_ATTRIBUTE_T { -+ UINT_16 u2Id; /* Attribute ID */ -+ UINT_16 u2Length; /* Length */ -+ UINT_8 aucBody[1]; /* Body field */ -+} __KAL_ATTRIB_PACKED__ WSC_ATTRIBUTE_T, *P_WSC_ATTRIBUTE_T; -+ -+/* WSC 1.0 Table 28 */ -+typedef struct _WSC_ATTRI_VERSION_T { -+ UINT_16 u2Id; /* Attribute ID */ -+ UINT_16 u2Length; /* Length */ -+ UINT_8 ucVersion; /* Version 1.0 or 1.1 */ -+} __KAL_ATTRIB_PACKED__ WSC_ATTRI_VERSION_T, *P_WSC_ATTRI_VERSION_T; -+ -+typedef struct _WSC_ATTRI_DEVICE_PASSWORD_ID_T { -+ UINT_16 u2Id; /* Attribute ID */ -+ UINT_16 u2Length; /* Length */ -+ UINT_16 u2DevPasswordId; /* Device Password ID */ -+} __KAL_ATTRIB_PACKED__ WSC_ATTRI_DEVICE_PASSWORD_ID_T, *P_WSC_ATTRI_DEVICE_PASSWORD_ID_T; -+ -+typedef struct _WSC_ATTRI_CONFIGURATION_METHOD_T { -+ UINT_16 u2Id; /* Attribute ID */ -+ UINT_16 u2Length; /* Length */ -+ UINT_16 u2ConfigMethods; /* Configure Methods */ -+} __KAL_ATTRIB_PACKED__ WSC_ATTRI_CONFIGURATION_METHOD_T, *P_WSC_ATTRI_CONFIGURATION_METHOD_T; -+ -+#if defined(WINDOWS_DDK) || defined(WINDOWS_CE) -+#pragma pack() -+#endif -+ -+/* 3 --------------- WFA P2P Attributes Handler prototype --------------- */ -+typedef UINT_32(*PFN_APPEND_ATTRI_FUNC) (P_ADAPTER_T, BOOLEAN, PUINT_16, PUINT_8, UINT_16); -+ -+typedef VOID(*PFN_HANDLE_ATTRI_FUNC) (P_SW_RFB_T, P_P2P_ATTRIBUTE_T); -+ -+typedef VOID(*PFN_VERIFY_ATTRI_FUNC) (P_SW_RFB_T, P_P2P_ATTRIBUTE_T, PUINT_16); -+ -+typedef UINT_32(*PFN_CALCULATE_VAR_ATTRI_LEN_FUNC) (P_ADAPTER_T, P_STA_RECORD_T); -+ -+typedef struct _APPEND_VAR_ATTRI_ENTRY_T { -+ UINT_16 u2EstimatedFixedAttriLen; /* For fixed length */ -+ PFN_CALCULATE_VAR_ATTRI_LEN_FUNC pfnCalculateVariableAttriLen; -+ PFN_APPEND_ATTRI_FUNC pfnAppendAttri; -+} APPEND_VAR_ATTRI_ENTRY_T, *P_APPEND_VAR_ATTRI_ENTRY_T; -+ -+typedef enum _ENUM_CONFIG_METHOD_SEL { -+ ENUM_CONFIG_METHOD_SEL_AUTO, -+ ENUM_CONFIG_METHOD_SEL_USER, -+ ENUM_CONFIG_METHOD_SEL_NUM -+} ENUM_CONFIG_METHOD_SEL, *P_ENUM_CONFIG_METHOD_SEL; -+ -+typedef enum _ENUM_P2P_FORMATION_POLICY { -+ ENUM_P2P_FORMATION_POLICY_AUTO = 0, -+ ENUM_P2P_FORMATION_POLICY_PASSIVE, /* Device would wait GO NEGO REQ instead of sending it actively. */ -+ ENUM_P2P_FORMATION_POLICY_NUM -+} ENUM_P2P_FORMATION_POLICY, P_ENUM_P2P_FORMATION_POLICY; -+ -+typedef enum _ENUM_P2P_INVITATION_POLICY { -+ ENUM_P2P_INVITATION_POLICY_USER = 0, -+ ENUM_P2P_INVITATION_POLICY_ACCEPT_FIRST, -+ ENUM_P2P_INVITATION_POLICY_DENY_ALL, -+ ENUM_P2P_INVITATION_POLICY_NUM -+} ENUM_P2P_INVITATION_POLICY, P_ENUM_P2P_INVITATION_POLICY; -+ -+/* 3 --------------- Data Structure for P2P Operation --------------- */ -+/* 3 Session for CONNECTION SETTINGS of P2P */ -+struct _P2P_CONNECTION_SETTINGS_T { -+ UINT_8 ucDevNameLen; -+ UINT_8 aucDevName[WPS_ATTRI_MAX_LEN_DEVICE_NAME]; -+ -+ DEVICE_TYPE_T rPrimaryDevTypeBE; -+ -+ ENUM_P2P_FORMATION_POLICY eFormationPolicy; /* Formation Policy. */ -+ -+ /*------------WSC Related Param---------------*/ -+ UINT_16 u2ConfigMethodsSupport; /* Preferred configure method. -+ * Some device may not have keypad. -+ */ -+ ENUM_CONFIG_METHOD_SEL eConfigMethodSelType; -+ UINT_16 u2TargetConfigMethod; /* Configure method selected by user or auto. */ -+ UINT_16 u2LocalConfigMethod; /* Configure method of target. */ -+ BOOLEAN fgIsPasswordIDRdy; -+ /*------------WSC Related Param---------------*/ -+ -+ UINT_8 ucClientConfigTimeout; -+ UINT_8 ucGoConfigTimeout; -+ -+ UINT_8 ucSecondaryDevTypeCount; -+#if P2P_MAX_SUPPORTED_SEC_DEV_TYPE_COUNT -+ DEVICE_TYPE_T arSecondaryDevTypeBE[P2P_MAX_SUPPORTED_SEC_DEV_TYPE_COUNT]; -+#endif -+ -+#if 0 -+ UINT_8 ucRfChannelListCount; -+#if P2P_MAX_SUPPORTED_CHANNEL_LIST_COUNT -+ UINT_8 aucChannelList[P2P_MAX_SUPPORTED_CHANNEL_LIST_COUNT]; /* Channel Numbering -+ depends on 802.11mb Annex J. */ -+ -+#endif -+#else -+ UINT_8 ucRfChannelListSize; -+#if P2P_MAX_SUPPORTED_CHANNEL_LIST_SIZE -+ UINT_8 aucChannelEntriesField[P2P_MAX_SUPPORTED_CHANNEL_LIST_SIZE]; -+#endif -+#endif -+ -+ /* Go Intent */ -+ UINT_8 ucTieBreaker; -+ UINT_8 ucGoIntent; -+ -+ /* For Device Capability */ -+ BOOLEAN fgSupportServiceDiscovery; -+ BOOLEAN fgSupportClientDiscoverability; -+ BOOLEAN fgSupportConcurrentOperation; -+ BOOLEAN fgSupportInfraManaged; -+ BOOLEAN fgSupportInvitationProcedure; -+ -+ /* For Group Capability */ -+ BOOLEAN fgSupportPersistentP2PGroup; -+ BOOLEAN fgSupportIntraBSSDistribution; -+ BOOLEAN fgSupportCrossConnection; -+ BOOLEAN fgSupportPersistentReconnect; -+ -+ BOOLEAN fgP2pGroupLimit; -+ -+ BOOLEAN fgSupportOppPS; -+ UINT_16 u2CTWindow; -+ -+ BOOLEAN fgIsScanReqIssued; -+ BOOLEAN fgIsServiceDiscoverIssued; -+ -+ /*============ Target Device Connection Settings ============*/ -+ -+ /* Discover Target Device Info. */ -+ BOOLEAN fgIsDevId; -+ BOOLEAN fgIsDevType; -+ -+ /* Encryption mode of Target Device */ -+ ENUM_PARAM_AUTH_MODE_T eAuthMode; -+ -+ /* SSID -+ * 1. AP Mode, this is the desired SSID user specified. -+ * 2. Client Mode, this is the target SSID to be connected to. -+ */ -+ UINT_8 aucSSID[ELEM_MAX_LEN_SSID]; -+ UINT_8 ucSSIDLen; -+ -+ /* Operating channel requested. */ -+ UINT_8 ucOperatingChnl; -+ ENUM_BAND_T eBand; -+ -+ /* Linten channel requested. */ -+ UINT_8 ucListenChnl; -+ -+ /* For device discover address/type. */ -+ UINT_8 aucTargetDevAddr[MAC_ADDR_LEN]; /* P2P Device Address, for P2P Device Discovery & P2P Connection. */ -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ P_P2P_DEVICE_DESC_T prTargetP2pDesc; -+#endif -+ -+ UINT_8 ucLastStatus; /* P2P FSM would append status attribute according to this field. */ -+ -+#if !CFG_DISABLE_DELAY_PROVISION_DISCOVERY -+ UINT_8 ucLastDialogToken; -+ UINT_8 aucIndicateDevAddr[MAC_ADDR_LEN]; -+#endif -+ -+#if 0 -+ UINT_8 ucTargetRfChannelListCount; -+#if P2P_MAX_SUPPORTED_CHANNEL_LIST_COUNT -+ UINT_8 aucTargetChannelList[P2P_MAX_SUPPORTED_CHANNEL_LIST_COUNT]; /* Channel Numbering -+ depends on 802.11mb Annex J. */ -+#endif -+#endif -+ -+}; -+ -+typedef struct _NOA_TIMING_T { -+ BOOLEAN fgIsInUse; /* Indicate if this entry is in use or not */ -+ UINT_8 ucCount; /* Count */ -+ -+ UINT_8 aucReserved[2]; -+ -+ UINT_32 u4Duration; /* Duration */ -+ UINT_32 u4Interval; /* Interval */ -+ UINT_32 u4StartTime; /* Start Time */ -+} NOA_TIMING_T, *P_NOA_TIMING_T; -+ -+typedef enum _ENUM_P2P_IOCTL_T { -+ P2P_IOCTL_IDLE = 0, -+ P2P_IOCTL_DEV_DISCOVER, -+ P2P_IOCTL_INVITATION_REQ, -+ P2P_IOCTL_SERV_DISCOVER, -+ P2P_IOCTL_WAITING, -+ P2P_IOCTL_NUM -+} ENUM_P2P_IOCTL_T; -+ -+/*---------------- Service Discovery Related -------------------*/ -+typedef enum _ENUM_SERVICE_TX_TYPE_T { -+ ENUM_SERVICE_TX_TYPE_BY_DA, -+ ENUM_SERVICE_TX_TYPE_BY_CHNL, -+ ENUM_SERVICE_TX_TYPE_NUM -+} ENUM_SERVICE_TX_TYPE_T; -+ -+typedef struct _SERVICE_DISCOVERY_FRAME_DATA_T { -+ QUE_ENTRY_T rQueueEntry; -+ P_MSDU_INFO_T prSDFrame; -+ ENUM_SERVICE_TX_TYPE_T eServiceType; -+ UINT_8 ucSeqNum; -+ union { -+ -+ UINT_8 ucChannelNum; -+ UINT_8 aucPeerAddr[MAC_ADDR_LEN]; -+ } uTypeData; -+ BOOLEAN fgIsTxDoneIndicate; -+} SERVICE_DISCOVERY_FRAME_DATA_T, *P_SERVICE_DISCOVERY_FRAME_DATA_T; -+ -+struct _P2P_FSM_INFO_T_DEPRECATED { -+ /* P2P FSM State */ -+ ENUM_P2P_STATE_T eCurrentState; -+ -+ /* Channel */ -+ BOOLEAN fgIsChannelRequested; -+ -+ ENUM_P2P_STATE_T ePreviousState; -+ -+ ENUM_P2P_STATE_T eReturnState; /* Return state after current activity finished or abort. */ -+ -+ UINT_8 aucTargetIfAddr[PARAM_MAC_ADDR_LEN]; -+ P_BSS_DESC_T prTargetBss; /* BSS of target P2P Device. For Connection/Service Discovery */ -+ -+ P_STA_RECORD_T prTargetStaRec; -+ -+ BOOLEAN fgIsRsponseProbe; /* Indicate if P2P FSM can response probe request frame. */ -+ -+ /* Sequence number of requested message. */ -+ UINT_8 ucSeqNumOfReqMsg; /* Used for SAA FSM request message. */ -+ -+ /* Channel Privilege */ -+ UINT_8 ucSeqNumOfChReq; /* Used for Channel Request message. */ -+ -+ UINT_8 ucSeqNumOfScnMsg; /* Used for SCAN FSM request message. */ -+ UINT_8 ucSeqNumOfCancelMsg; -+ -+ UINT_8 ucDialogToken; -+ UINT_8 ucRxDialogToken; -+ -+ /* Timer */ -+ TIMER_T rDeviceDiscoverTimer; /* For device discovery time of each discovery request from user. */ -+ TIMER_T rOperationListenTimer; /* For Find phase under operational state. */ -+ TIMER_T rFSMTimer; /* A timer used for Action frame timeout usage. */ -+ -+ TIMER_T rRejoinTimer; /* A timer used for Action frame timeout usage. */ -+ -+ /* Flag to indicate Provisioning */ -+ BOOLEAN fgIsConnectionRequested; -+ -+ /* Current IOCTL. */ -+ ENUM_P2P_IOCTL_T eP2pIOCTL; -+ -+ UINT_8 ucAvailableAuthTypes; /* Used for AUTH_MODE_AUTO_SWITCH */ -+ -+ /*--------SERVICE DISCOVERY--------*/ -+ QUE_T rQueueGASRx; /* Input Request/Response. */ -+ QUE_T rQueueGASTx; /* Output Response. */ -+ P_SERVICE_DISCOVERY_FRAME_DATA_T prSDRequest; -+ UINT_8 ucVersionNum; /* GAS packet sequence number for...Action Frame? */ -+ UINT_8 ucGlobalSeqNum; /* Sequence Number of RX SD packet. */ -+ /*--------Service DISCOVERY--------*/ -+ -+ /*--------DEVICE DISCOVERY---------*/ -+ UINT_8 aucTargetGroupID[PARAM_MAC_ADDR_LEN]; -+ UINT_16 u2TargetGroupSsidLen; -+ UINT_8 aucTargetSsid[32]; -+ UINT_8 aucSearchingP2pDevice[PARAM_MAC_ADDR_LEN]; -+ UINT_8 ucDLToken; -+ /*----------------------------------*/ -+ -+ /* Indicating Peer Status. */ -+ UINT_32 u4Flags; -+ -+ /*Indicating current running mode. */ -+ BOOLEAN fgIsApMode; -+ -+ /*------------INVITATION------------*/ -+ ENUM_P2P_INVITATION_POLICY eInvitationRspPolicy; -+ /*----------------------------------*/ -+ -+}; -+ -+struct _P2P_SPECIFIC_BSS_INFO_T { -+ /* For GO(AP) Mode - Compose TIM IE */ -+ UINT_16 u2SmallestAID; -+ UINT_16 u2LargestAID; -+ UINT_8 ucBitmapCtrl; -+ /* UINT_8 aucPartialVirtualBitmap[MAX_LEN_TIM_PARTIAL_BMP]; */ -+ -+ /* For GC/GO OppPS */ -+ BOOLEAN fgEnableOppPS; -+ UINT_16 u2CTWindow; -+ -+ /* For GC/GO NOA */ -+ UINT_8 ucNoAIndex; -+ UINT_8 ucNoATimingCount; /* Number of NoA Timing */ -+ NOA_TIMING_T arNoATiming[P2P_MAXIMUM_NOA_COUNT]; -+ -+ BOOLEAN fgIsNoaAttrExisted; -+ -+ /* For P2P Device */ -+ UINT_8 ucRegClass; /* Regulatory Class for channel. */ -+ UINT_8 ucListenChannel; /* Linten Channel only on channels 1, 6 and 11 in the 2.4 GHz. */ -+ -+ UINT_8 ucPreferredChannel; /* Operating Channel, should be one of channel list -+ in p2p connection settings. */ -+ ENUM_CHNL_EXT_T eRfSco; -+ ENUM_BAND_T eRfBand; -+ -+ /* Extended Listen Timing. */ -+ UINT_16 u2AvailabilityPeriod; -+ UINT_16 u2AvailabilityInterval; -+ -+#if 0 /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0) */ -+ UINT_16 u2IELenForBCN; -+ UINT_8 aucBeaconIECache[P2P_MAXIMUM_ATTRIBUTES_CACHE_SIZE + WPS_MAXIMUM_ATTRIBUTES_CACHE_SIZE]; -+ -+/* UINT_16 u2IELenForProbeRsp; */ -+/* UINT_8 aucProbeRspIECache[P2P_MAXIMUM_ATTRIBUTES_CACHE_SIZE + WPS_MAXIMUM_ATTRIBUTES_CACHE_SIZE]; */ -+ -+ UINT_16 u2IELenForAssocRsp; -+ UINT_8 aucAssocRspIECache[P2P_MAXIMUM_ATTRIBUTES_CACHE_SIZE + WPS_MAXIMUM_ATTRIBUTES_CACHE_SIZE]; -+ -+#else -+ UINT_16 u2AttributeLen; -+ UINT_8 aucAttributesCache[P2P_MAXIMUM_ATTRIBUTES_CACHE_SIZE]; -+ -+ UINT_16 u2WscAttributeLen; -+ UINT_8 aucWscAttributesCache[WPS_MAXIMUM_ATTRIBUTES_CACHE_SIZE]; -+#endif -+ UINT_8 aucGroupID[MAC_ADDR_LEN]; -+ UINT_16 u2GroupSsidLen; -+ UINT_8 aucGroupSsid[ELEM_MAX_LEN_SSID]; -+ -+ PARAM_CUSTOM_NOA_PARAM_STRUCT_T rNoaParam; -+ PARAM_CUSTOM_OPPPS_PARAM_STRUCT_T rOppPsParam; -+ -+ UINT_16 u2WpaIeLen; -+ UINT_8 aucWpaIeBuffer[ELEM_HDR_LEN + ELEM_MAX_LEN_WPA]; -+}; -+ -+typedef struct _MSG_P2P_DEVICE_DISCOVER_T { -+ MSG_HDR_T rMsgHdr; /* Must be the first member */ -+ UINT_32 u4DevDiscoverTime; /* 0: Infinite, 1~X: in unit of MS. */ -+ BOOLEAN fgIsSpecificType; -+#if CFG_ENABLE_WIFI_DIRECT -+ P2P_DEVICE_TYPE_T rTargetDeviceType; -+#endif -+ UINT_8 aucTargetDeviceID[MAC_ADDR_LEN]; -+} MSG_P2P_DEVICE_DISCOVER_T, *P_MSG_P2P_DEVICE_DISCOVER_T; -+ -+typedef struct _MSG_P2P_INVITATION_REQUEST_T { -+ MSG_HDR_T rMsgHdr; /* Must be the first member */ -+ UINT_8 aucDeviceID[MAC_ADDR_LEN]; /* Target Device ID to be invited. */ -+} MSG_P2P_INVITATION_REQUEST_T, *P_MSG_P2P_INVITATION_REQUEST_T; -+ -+typedef struct _MSG_P2P_FUNCTION_SWITCH_T { -+ MSG_HDR_T rMsgHdr; /* Must be the first member */ -+ BOOLEAN fgIsFuncOn; -+} MSG_P2P_FUNCTION_SWITCH_T, *P_MSG_P2P_FUNCTION_SWITCH_T; -+ -+typedef struct _MSG_P2P_SERVICE_DISCOVERY_REQUEST_T { -+ MSG_HDR_T rMsgHdr; /* Must be the first member */ -+ UINT_8 aucDeviceID[MAC_ADDR_LEN]; -+ BOOLEAN fgNeedTxDoneIndicate; -+ UINT_8 ucSeqNum; -+} MSG_P2P_SERVICE_DISCOVERY_REQUEST_T, *P_MSG_P2P_SERVICE_DISCOVERY_REQUEST_T; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+#define p2pChangeMediaState(_prAdapter, _eNewMediaState) \ -+do { \ -+ (_prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX].eConnectionState = (_eNewMediaState));\ -+ wfdChangeMediaState((_prAdapter), NETWORK_TYPE_P2P_INDEX, (_eNewMediaState)); \ -+} while (0) -+ -+#define ATTRI_ID(_fp) (((P_P2P_ATTRIBUTE_T) _fp)->ucId) -+#define ATTRI_LEN(_fp) \ -+ (((UINT_16) ((PUINT_8)&((P_P2P_ATTRIBUTE_T) _fp)->u2Length)[0]) | \ -+ ((UINT_16) ((PUINT_8)&((P_P2P_ATTRIBUTE_T) _fp)->u2Length)[1] << 8)) -+ -+#define ATTRI_SIZE(_fp) (P2P_ATTRI_HDR_LEN + ATTRI_LEN(_fp)) -+ -+#define P2P_ATTRI_FOR_EACH(_pucAttriBuf, _u2AttriBufLen, _u2Offset) \ -+ for ((_u2Offset) = 0; ((_u2Offset) < (_u2AttriBufLen)); \ -+ (_u2Offset) += ATTRI_SIZE(_pucAttriBuf), ((_pucAttriBuf) += ATTRI_SIZE(_pucAttriBuf))) -+ -+#define P2P_IE(_fp) ((P_IE_P2P_T) _fp) -+ -+#define WSC_ATTRI_ID(_fp) \ -+ (((UINT_16) ((PUINT_8)&((P_WSC_ATTRIBUTE_T) _fp)->u2Id)[0] << 8) | \ -+ ((UINT_16) ((PUINT_8)&((P_WSC_ATTRIBUTE_T) _fp)->u2Id)[1])) -+ -+#define WSC_ATTRI_LEN(_fp) \ -+ (((UINT_16) ((PUINT_8)&((P_WSC_ATTRIBUTE_T) _fp)->u2Length)[0] << 8) | \ -+ ((UINT_16) ((PUINT_8)&((P_WSC_ATTRIBUTE_T) _fp)->u2Length)[1])) -+ -+#define WSC_ATTRI_SIZE(_fp) (WSC_ATTRI_HDR_LEN + WSC_ATTRI_LEN(_fp)) -+ -+#define WSC_ATTRI_FOR_EACH(_pucAttriBuf, _u2AttriBufLen, _u2Offset) \ -+ for ((_u2Offset) = 0; ((_u2Offset) < (_u2AttriBufLen)); \ -+ (_u2Offset) += WSC_ATTRI_SIZE(_pucAttriBuf), ((_pucAttriBuf) += WSC_ATTRI_SIZE(_pucAttriBuf))) -+ -+#define WSC_IE(_fp) ((P_IE_P2P_T) _fp) -+ -+#define WFD_ATTRI_ID(_fp) (((P_WFD_ATTRIBUTE_T) _fp)->ucElemID) -+ -+#define WFD_ATTRI_LEN(_fp) \ -+ (((UINT_16) ((PUINT_8)&((P_WFD_ATTRIBUTE_T) _fp)->u2Length)[0] << 8) | \ -+ ((UINT_16) ((PUINT_8)&((P_WFD_ATTRIBUTE_T) _fp)->u2Length)[1])) -+ -+#define WFD_ATTRI_SIZE(_fp) (WFD_ATTRI_HDR_LEN + WFD_ATTRI_LEN(_fp)) -+ -+#define WFD_ATTRI_FOR_EACH(_pucAttriBuf, _u2AttriBufLen, _u2Offset) \ -+ for ((_u2Offset) = 0; ((_u2Offset) < (_u2AttriBufLen)); \ -+ (_u2Offset) += WFD_ATTRI_SIZE(_pucAttriBuf), ((_pucAttriBuf) += WFD_ATTRI_SIZE(_pucAttriBuf))) -+ -+#if DBG -+#define ASSERT_BREAK(_exp) \ -+ { \ -+ if (!(_exp)) { \ -+ ASSERT(FALSE); \ -+ break; \ -+ } \ -+ } -+ -+#else -+#define ASSERT_BREAK(_exp) -+#endif -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/*======P2P State======*/ -+VOID -+p2pStateInit_LISTEN(IN P_ADAPTER_T prAdapter, -+ IN P_P2P_FSM_INFO_T prP2pFsmInfo, -+ IN P_P2P_SPECIFIC_BSS_INFO_T prSP2pBssInfo, IN UINT_8 ucListenChannel); -+ -+VOID p2pStateAbort_LISTEN(IN P_ADAPTER_T prAdapter, IN BOOLEAN fgIsChannelExtenstion); -+ -+VOID p2pStateAbort_SEARCH_SCAN(IN P_ADAPTER_T prAdapter, IN BOOLEAN fgIsChannelExtenstion); -+ -+VOID p2pStateAbort_GO_OPERATION(IN P_ADAPTER_T prAdapter); -+ -+VOID p2pStateAbort_GC_OPERATION(IN P_ADAPTER_T prAdapter); -+ -+VOID -+p2pStateInit_CONFIGURATION(IN P_ADAPTER_T prAdapter, -+ IN P_P2P_FSM_INFO_T prP2pFsmInfo, -+ IN P_BSS_INFO_T prP2pBssInfo, IN P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecBssInfo); -+ -+VOID p2pStateAbort_CONFIGURATION(IN P_ADAPTER_T prAdapter); -+ -+VOID p2pStateInit_JOIN(IN P_ADAPTER_T prAdapter); -+ -+VOID p2pStateAbort_JOIN(IN P_ADAPTER_T prAdapter); -+ -+/*====== P2P Functions ======*/ -+ -+VOID p2pFuncInitGO(IN P_ADAPTER_T prAdapter); -+ -+VOID -+p2pFuncDisconnect(IN P_ADAPTER_T prAdapter, -+ IN P_STA_RECORD_T prStaRec, IN BOOLEAN fgSendDeauth, IN UINT_16 u2ReasonCode); -+ -+VOID -+p2pFuncSwitchOPMode(IN P_ADAPTER_T prAdapter, -+ IN P_BSS_INFO_T prP2pBssInfo, IN ENUM_OP_MODE_T eOpMode, IN BOOLEAN fgSyncToFW); -+ -+VOID p2pFuncRunEventProvisioningComplete(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); -+ -+WLAN_STATUS p2pFuncSetGroupID(IN P_ADAPTER_T prAdapter, IN PUINT_8 pucGroupID, IN PUINT_8 pucSsid, IN UINT_8 ucSsidLen); -+ -+WLAN_STATUS -+p2pFuncSendDeviceDiscoverabilityReqFrame(IN P_ADAPTER_T prAdapter, IN UINT_8 aucDestAddr[], IN UINT_8 ucDialogToken); -+ -+WLAN_STATUS -+p2pFuncSendDeviceDiscoverabilityRspFrame(IN P_ADAPTER_T prAdapter, IN UINT_8 aucDestAddr[], IN UINT_8 ucDialogToken); -+ -+UINT_8 p2pFuncGetVersionNumOfSD(IN P_ADAPTER_T prAdapter); -+ -+/*====== P2P FSM ======*/ -+VOID p2pFsmRunEventConnectionRequest(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); -+ -+VOID p2pFsmRunEventDeviceDiscoveryRequest(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); -+ -+VOID p2pFsmRunEventDeviceDiscoveryAbort(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); -+ -+VOID p2pFsmRunEventRxGroupNegotiationReqFrame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); -+ -+WLAN_STATUS -+p2pFsmRunEventGroupNegotiationRequestTxDone(IN P_ADAPTER_T prAdapter, -+ IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus); -+ -+WLAN_STATUS -+p2pFsmRunEventGroupNegotiationResponseTxDone(IN P_ADAPTER_T prAdapter, -+ IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus); -+ -+WLAN_STATUS -+p2pFsmRunEventGroupNegotiationConfirmTxDone(IN P_ADAPTER_T prAdapter, -+ IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus); -+ -+WLAN_STATUS -+p2pFsmRunEventProvisionDiscoveryRequestTxDone(IN P_ADAPTER_T prAdapter, -+ IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus); -+ -+WLAN_STATUS -+p2pFsmRunEventProvisionDiscoveryResponseTxDone(IN P_ADAPTER_T prAdapter, -+ IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus); -+ -+WLAN_STATUS -+p2pFsmRunEventInvitationRequestTxDone(IN P_ADAPTER_T prAdapter, -+ IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus); -+ -+VOID p2pFsmRunEventRxDeauthentication(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN P_SW_RFB_T prSwRfb); -+ -+VOID p2pFsmRunEventRxDisassociation(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN P_SW_RFB_T prSwRfb); -+ -+VOID p2pFsmRunEventBeaconTimeout(IN P_ADAPTER_T prAdapter); -+ -+WLAN_STATUS -+p2pFsmRunEventDeauthTxDone(IN P_ADAPTER_T prAdapter, -+ IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus); -+ -+#if 1 -+#endif -+ -+/* //////////////////////////////////////////////////////////////////////// */ -+/* //////////////////////////////////////////////////////////////////////// */ -+/* //////////////////////////////////////////////////////////////////////// */ -+/* //////////////////////////////////////////////////////////////////////// */ -+/* //////////////////////////////////////////////////////////////////////// */ -+/* //////////////////////////////////////////////////////////////////////// */ -+/* //////////////////////////////////////////////////////////////////////// */ -+/* //////////////////////////////////////////////////////////////////////// */ -+/* //////////////////////////////////////////////////////////////////////// */ -+/* //////////////////////////////////////////////////////////////////////// */ -+/* //////////////////////////////////////////////////////////////////////// */ -+/*======Mail Box Event Message=====*/ -+ -+VOID p2pFsmRunEventConnectionAbort(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); -+ -+VOID p2pFsmRunEventConnectionTrigger(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); -+ -+VOID p2pFsmRunEventP2PFunctionSwitch(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); -+ -+VOID p2pFsmRunEventChGrant(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); -+ -+VOID p2pFsmRunEventJoinComplete(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); -+ -+VOID p2pFsmRunEventConnectionPause(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); -+ -+VOID -+p2pIndicationOfMediaStateToHost(IN P_ADAPTER_T prAdapter, -+ IN ENUM_PARAM_MEDIA_STATE_T eConnectionState, IN UINT_8 aucTargetAddr[]); -+ -+VOID p2pUpdateBssInfoForJOIN(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN P_SW_RFB_T prAssocRspSwRfb); -+ -+/*======Mail Box Event Message=====*/ -+ -+VOID p2pFsmInit(IN P_ADAPTER_T prAdapter); -+ -+VOID p2pFsmUninit(IN P_ADAPTER_T prAdapter); -+ -+VOID p2pFsmSteps(IN P_ADAPTER_T prAdapter, IN ENUM_P2P_STATE_T eNextState); -+ -+VOID p2pStartGO(IN P_ADAPTER_T prAdapter); -+ -+VOID p2pAssignSsid(IN PUINT_8 pucSsid, IN PUINT_8 pucSsidLen); -+ -+VOID p2pFsmRunEventScanDone(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); -+ -+VOID p2pFsmRunEventIOReqTimeout(IN P_ADAPTER_T prAdapter, IN UINT_32 u4Param); -+ -+VOID p2pFsmRunEventSearchPeriodTimeout(IN P_ADAPTER_T prAdapter, IN UINT_32 u4Param); -+ -+VOID p2pFsmRunEventFsmTimeout(IN P_ADAPTER_T prAdapter, IN ULONG u4Param); -+ -+VOID p2pFsmRunEventRejoinTimeout(IN P_ADAPTER_T prAdapter, IN UINT_32 u4Parm); -+ -+/*=============== P2P Function Related ================*/ -+ -+/*=============== P2P Function Related ================*/ -+ -+#if CFG_TEST_WIFI_DIRECT_GO -+VOID p2pTest(IN P_ADAPTER_T prAdapter); -+#endif /* CFG_TEST_WIFI_DIRECT_GO */ -+ -+VOID p2pGenerateP2P_IEForBeacon(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); -+ -+VOID p2pGenerateP2P_IEForAssocReq(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); -+ -+VOID p2pGenerateP2P_IEForAssocRsp(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); -+ -+VOID -+p2pGenerateP2P_IEForProbeReq(IN P_ADAPTER_T prAdapter, IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); -+ -+UINT_32 -+p2pCalculateP2P_IELenForBeacon(IN P_ADAPTER_T prAdapter, -+ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec); -+ -+UINT_32 -+p2pCalculateP2P_IELenForAssocRsp(IN P_ADAPTER_T prAdapter, -+ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec); -+ -+UINT_32 -+p2pCalculateP2P_IELenForProbeReq(IN P_ADAPTER_T prAdapter, -+ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec); -+ -+VOID p2pGenerateWSC_IEForProbeResp(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); -+ -+VOID -+p2pGenerateWSC_IEForProbeReq(IN P_ADAPTER_T prAdapter, IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); -+ -+UINT_16 p2pCalculateWSC_IELenForProbeReq(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex); -+ -+UINT_32 -+p2pCalculateWSC_IELenForProbeResp(IN P_ADAPTER_T prAdapter, -+ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec); -+ -+UINT_32 -+p2pAppendAttriStatus(IN P_ADAPTER_T prAdapter, -+ IN BOOLEAN fgIsAssocFrame, IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); -+ -+UINT_32 -+p2pAppendAttriCapability(IN P_ADAPTER_T prAdapter, -+ IN BOOLEAN fgIsAssocFrame, IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); -+ -+UINT_32 -+p2pAppendAttriGoIntent(IN P_ADAPTER_T prAdapter, -+ IN BOOLEAN fgIsAssocFrame, IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); -+ -+UINT_32 -+p2pAppendAttriCfgTimeout(IN P_ADAPTER_T prAdapter, -+ IN BOOLEAN fgIsAssocFrame, IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); -+ -+UINT_32 -+p2pAppendAttriGroupBssid(IN P_ADAPTER_T prAdapter, -+ IN BOOLEAN fgIsAssocFrame, IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); -+ -+UINT_32 -+p2pAppendAttriDeviceIDForBeacon(IN P_ADAPTER_T prAdapter, -+ IN BOOLEAN fgIsAssocFrame, -+ IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); -+ -+UINT_32 -+p2pAppendAttriDeviceIDForProbeReq(IN P_ADAPTER_T prAdapter, -+ IN BOOLEAN fgIsAssocFrame, -+ IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); -+ -+UINT_32 -+p2pAppendAttriDeviceIDForDeviceDiscoveryReq(IN P_ADAPTER_T prAdapter, -+ IN BOOLEAN fgIsAssocFrame, -+ IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); -+ -+UINT_32 -+p2pAppendAttriListenChannel(IN P_ADAPTER_T prAdapter, -+ IN BOOLEAN fgIsAssocFrame, IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); -+ -+UINT_32 -+p2pAppendAttriIntendP2pIfAddr(IN P_ADAPTER_T prAdapter, -+ IN BOOLEAN fgIsAssocFrame, -+ IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); -+ -+UINT_32 -+p2pAppendAttriChannelList(IN P_ADAPTER_T prAdapter, -+ IN BOOLEAN fgIsAssocFrame, IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); -+ -+UINT_32 p2pCalculateAttriLenChannelList(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec); -+ -+UINT_32 -+p2pAppendAttriNoA(IN P_ADAPTER_T prAdapter, -+ IN BOOLEAN fgIsAssocFrame, IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); -+ -+UINT_32 -+p2pAppendAttriDeviceInfo(IN P_ADAPTER_T prAdapter, -+ IN BOOLEAN fgIsAssocFrame, IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); -+ -+UINT_32 p2pCalculateAttriLenDeviceInfo(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec); -+ -+UINT_32 -+p2pAppendAttriGroupInfo(IN P_ADAPTER_T prAdapter, -+ IN BOOLEAN fgIsAssocFrame, IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); -+ -+UINT_32 p2pCalculateAttriLenGroupInfo(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec); -+ -+UINT_32 -+p2pAppendAttriP2pGroupID(IN P_ADAPTER_T prAdapter, -+ IN BOOLEAN fgIsAssocFrame, IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); -+ -+UINT_32 -+p2pAppendAttriOperatingChannel(IN P_ADAPTER_T prAdapter, -+ IN BOOLEAN fgIsAssocFrame, -+ IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); -+ -+UINT_32 -+p2pAppendAttriInvitationFlag(IN P_ADAPTER_T prAdapter, -+ IN BOOLEAN fgIsAssocFrame, IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); -+ -+VOID -+p2pGenerateWscIE(IN P_ADAPTER_T prAdapter, -+ IN UINT_8 ucOuiType, -+ IN BOOLEAN fgIsAssocFrame, -+ IN PUINT_16 pu2Offset, -+ IN PUINT_8 pucBuf, -+ IN UINT_16 u2BufSize, IN APPEND_VAR_ATTRI_ENTRY_T arAppendAttriTable[], IN UINT_32 u4AttriTableSize); -+ -+UINT_32 -+p2pAppendAttriWSCConfigMethod(IN P_ADAPTER_T prAdapter, -+ IN BOOLEAN fgIsAssocFrame, -+ IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); -+ -+UINT_32 -+p2pAppendAttriWSCVersion(IN P_ADAPTER_T prAdapter, -+ IN BOOLEAN fgIsAssocFrame, IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); -+ -+UINT_32 -+p2pAppendAttriWSCGONegReqDevPasswordId(IN P_ADAPTER_T prAdapter, -+ IN BOOLEAN fgIsAssocFrame, -+ IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); -+ -+UINT_32 -+p2pAppendAttriWSCGONegRspDevPasswordId(IN P_ADAPTER_T prAdapter, -+ IN BOOLEAN fgIsAssocFrame, -+ IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); -+ -+WLAN_STATUS -+p2pGetWscAttriList(IN P_ADAPTER_T prAdapter, -+ IN UINT_8 ucOuiType, -+ IN PUINT_8 pucIE, IN UINT_16 u2IELength, OUT PPUINT_8 ppucAttriList, OUT PUINT_16 pu2AttriListLen); -+ -+WLAN_STATUS -+p2pGetAttriList(IN P_ADAPTER_T prAdapter, -+ IN UINT_8 ucOuiType, -+ IN PUINT_8 pucIE, IN UINT_16 u2IELength, OUT PPUINT_8 ppucAttriList, OUT PUINT_16 pu2AttriListLen); -+ -+VOID p2pRunEventAAATxFail(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec); -+ -+WLAN_STATUS p2pRunEventAAASuccess(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec); -+ -+WLAN_STATUS p2pRunEventAAAComplete(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec); -+ -+WLAN_STATUS p2pSendProbeResponseFrame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); -+ -+BOOLEAN p2pFsmRunEventRxProbeRequestFrame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); -+ -+VOID p2pFsmRunEventRxProbeResponseFrame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, IN P_BSS_DESC_T prBssDesc); -+ -+WLAN_STATUS p2pRxPublicActionFrame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); -+ -+WLAN_STATUS p2pRxActionFrame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); -+ -+VOID p2pFsmRunEventRxGroupNegotiationRspFrame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); -+ -+VOID p2pFsmRunEventRxGroupNegotiationCfmFrame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); -+ -+#if 0 /* frog */ -+BOOLEAN scanMatchFilterOfP2P(IN P_SW_RFB_T prSWRfb, IN PP_BSS_DESC_T pprBssDesc); -+#endif /* frog */ -+ -+VOID -+p2pProcessEvent_UpdateNOAParam(IN P_ADAPTER_T prAdapter, -+ UINT_8 ucNetTypeIndex, P_EVENT_UPDATE_NOA_PARAMS_T prEventUpdateNoaParam); -+ -+VOID p2pFuncCompleteIOCTL(IN P_ADAPTER_T prAdapter, IN WLAN_STATUS rWlanStatus); -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+#ifndef _lint -+/* Kevin: we don't have to call following function to inspect the data structure. -+ * It will check automatically while at compile time. -+ * We'll need this for porting driver to different RTOS. -+ */ -+static inline VOID p2pDataTypeCheck(VOID) -+{ -+ DATA_STRUCT_INSPECTING_ASSERT(sizeof(IE_P2P_T) == (2 + 4 + 1)); /* all UINT_8 */ -+ DATA_STRUCT_INSPECTING_ASSERT(sizeof(P2P_ATTRIBUTE_T) == (3 + 1)); -+ DATA_STRUCT_INSPECTING_ASSERT(sizeof(P2P_ATTRI_STATUS_T) == (3 + 1)); -+ DATA_STRUCT_INSPECTING_ASSERT(sizeof(P2P_ATTRI_REASON_T) == (3 + 1)); -+ DATA_STRUCT_INSPECTING_ASSERT(sizeof(P2P_ATTRI_CAPABILITY_T) == (3 + 2)); -+ DATA_STRUCT_INSPECTING_ASSERT(sizeof(P2P_ATTRI_DEV_ID_T) == (3 + 6)); -+ DATA_STRUCT_INSPECTING_ASSERT(sizeof(P2P_ATTRI_GO_INTENT_T) == (3 + 1)); -+ DATA_STRUCT_INSPECTING_ASSERT(sizeof(P2P_ATTRI_CFG_TIMEOUT_T) == (3 + 2)); -+#if CID52_53_54 -+ DATA_STRUCT_INSPECTING_ASSERT(sizeof(P2P_ATTRI_LISTEN_CHANNEL_T) == (3 + 5)); -+#else -+ DATA_STRUCT_INSPECTING_ASSERT(sizeof(P2P_ATTRI_LISTEN_CHANNEL_T) == (3 + 5)); -+#endif -+ DATA_STRUCT_INSPECTING_ASSERT(sizeof(P2P_ATTRI_GROUP_BSSID_T) == (3 + 6)); -+ DATA_STRUCT_INSPECTING_ASSERT(sizeof(P2P_ATTRI_EXT_LISTEN_TIMING_T) == (3 + 4)); -+ DATA_STRUCT_INSPECTING_ASSERT(sizeof(P2P_ATTRI_INTENDED_IF_ADDR_T) == (3 + 6)); -+ DATA_STRUCT_INSPECTING_ASSERT(sizeof(P2P_ATTRI_MANAGEABILITY_T) == (3 + 1)); -+ -+ DATA_STRUCT_INSPECTING_ASSERT(sizeof(P2P_ATTRI_CHANNEL_T) == (3 + 4)); -+ DATA_STRUCT_INSPECTING_ASSERT(sizeof(CHANNEL_ENTRY_FIELD_T) == 3); -+ DATA_STRUCT_INSPECTING_ASSERT(sizeof(P2P_ATTRI_NOA_T) == (3 + 3)); -+ DATA_STRUCT_INSPECTING_ASSERT(sizeof(NOA_DESCRIPTOR_T) == 13); -+ DATA_STRUCT_INSPECTING_ASSERT(sizeof(DEVICE_TYPE_T) == 8); -+ DATA_STRUCT_INSPECTING_ASSERT(sizeof(P2P_ATTRI_DEV_INFO_T) == (3 + 6 + 2 + 8 + 1 + 8)); -+ DATA_STRUCT_INSPECTING_ASSERT(sizeof(DEVICE_NAME_TLV_T) == (4 + 32)); -+ DATA_STRUCT_INSPECTING_ASSERT(sizeof(P2P_CLIENT_INFO_DESC_T) == (1 + 6 + 6 + 1 + 2 + 8 + 1 + 8)); -+ DATA_STRUCT_INSPECTING_ASSERT(sizeof(P2P_ATTRI_GROUP_INFO_T) == (3 + (1 + 6 + 6 + 1 + 2 + 8 + 1 + 8))); -+ DATA_STRUCT_INSPECTING_ASSERT(sizeof(P2P_ATTRI_GROUP_ID_T) == (3 + 38)); -+ DATA_STRUCT_INSPECTING_ASSERT(sizeof(P2P_ATTRI_INTERFACE_T) == (3 + 13)); -+#if CID52_53_54 -+ DATA_STRUCT_INSPECTING_ASSERT(sizeof(P2P_ATTRI_OPERATING_CHANNEL_T) == (3 + 5)); -+#else -+ DATA_STRUCT_INSPECTING_ASSERT(sizeof(P2P_ATTRI_OPERATING_CHANNEL_T) == (3 + 5)); -+#endif -+ -+} -+#endif /* _lint */ -+ -+#endif /* _P2P_FSM_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_func.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_func.h -new file mode 100644 -index 000000000000..1ac1770debca ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_func.h -@@ -0,0 +1,155 @@ -+#ifndef _P2P_FUNC_H -+#define _P2P_FUNC_H -+ -+#define P2P_EXT_LISTEN_TIME_MS 600 -+#define P2P_OFF_CHNL_TX_DEFAULT_TIME_MS 1000 -+ -+VOID p2pFuncRequestScan(IN P_ADAPTER_T prAdapter, IN P_P2P_SCAN_REQ_INFO_T prScanReqInfo); -+ -+VOID p2pFuncCancelScan(IN P_ADAPTER_T prAdapter, IN P_P2P_SCAN_REQ_INFO_T prScanReqInfo); -+ -+VOID -+p2pFuncStartGO(IN P_ADAPTER_T prAdapter, -+ IN P_BSS_INFO_T prBssInfo, -+ IN PUINT_8 pucSsidBuf, -+ IN UINT_8 ucSsidLen, -+ IN UINT_8 ucChannelNum, IN ENUM_BAND_T eBand, IN ENUM_CHNL_EXT_T eSco, IN BOOLEAN fgIsPureAP); -+ -+VOID p2pFuncAcquireCh(IN P_ADAPTER_T prAdapter, IN P_P2P_CHNL_REQ_INFO_T prChnlReqInfo); -+ -+VOID p2pFuncReleaseCh(IN P_ADAPTER_T prAdapter, IN P_P2P_CHNL_REQ_INFO_T prChnlReqInfo); -+ -+VOID p2pFuncSetChannel(IN P_ADAPTER_T prAdapter, IN P_RF_CHANNEL_INFO_T prRfChannelInfo); -+ -+BOOLEAN p2pFuncRetryJOIN(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN P_P2P_JOIN_INFO_T prJoinInfo); -+ -+VOID -+p2pFuncUpdateBssInfoForJOIN(IN P_ADAPTER_T prAdapter, -+ IN P_BSS_DESC_T prBssDesc, IN P_STA_RECORD_T prStaRec, IN P_SW_RFB_T prAssocRspSwRfb); -+ -+WLAN_STATUS -+p2pFuncTxMgmtFrame(IN P_ADAPTER_T prAdapter, -+ IN P_P2P_MGMT_TX_REQ_INFO_T prMgmtTxReqInfo, IN P_MSDU_INFO_T prMgmtTxMsdu, IN UINT_64 u8Cookie); -+ -+WLAN_STATUS -+p2pFuncBeaconUpdate(IN P_ADAPTER_T prAdapter, -+ IN P_BSS_INFO_T prP2pBssInfo, -+ IN P_P2P_BEACON_UPDATE_INFO_T prBcnUpdateInfo, -+ IN PUINT_8 pucNewBcnHdr, IN UINT_32 u4NewHdrLen, IN PUINT_8 pucNewBcnBody, IN UINT_32 u4NewBodyLen); -+ -+BOOLEAN -+p2pFuncValidateAuth(IN P_ADAPTER_T prAdapter, -+ IN P_SW_RFB_T prSwRfb, IN PP_STA_RECORD_T pprStaRec, OUT PUINT_16 pu2StatusCode); -+ -+BOOLEAN p2pFuncValidateAssocReq(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, OUT PUINT_16 pu2StatusCode); -+ -+VOID p2pFuncResetStaRecStatus(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec); -+ -+VOID p2pFuncInitConnectionSettings(IN P_ADAPTER_T prAdapter, IN P_P2P_CONNECTION_SETTINGS_T prP2PConnSettings); -+ -+BOOLEAN p2pFuncParseCheckForP2PInfoElem(IN P_ADAPTER_T prAdapter, IN PUINT_8 pucBuf, OUT PUINT_8 pucOuiType); -+ -+BOOLEAN p2pFuncValidateProbeReq(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, OUT PUINT_32 pu4ControlFlags); -+ -+VOID p2pFuncValidateRxActionFrame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); -+ -+BOOLEAN p2pFuncIsAPMode(IN P_P2P_FSM_INFO_T prP2pFsmInfo); -+ -+VOID -+p2pFuncParseBeaconContent(IN P_ADAPTER_T prAdapter, -+ IN P_BSS_INFO_T prP2pBssInfo, IN PUINT_8 pucIEInfo, IN UINT_32 u4IELen); -+ -+P_BSS_DESC_T -+p2pFuncKeepOnConnection(IN P_ADAPTER_T prAdapter, -+ IN P_P2P_CONNECTION_REQ_INFO_T prConnReqInfo, -+ IN P_P2P_CHNL_REQ_INFO_T prChnlReqInfo, IN P_P2P_SCAN_REQ_INFO_T prScanReqInfo); -+ -+VOID p2pFuncStoreAssocRspIEBuffer(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); -+ -+VOID -+p2pFuncMgmtFrameRegister(IN P_ADAPTER_T prAdapter, -+ IN UINT_16 u2FrameType, IN BOOLEAN fgIsRegistered, OUT PUINT_32 pu4P2pPacketFilter); -+ -+VOID p2pFuncUpdateMgmtFrameRegister(IN P_ADAPTER_T prAdapter, IN UINT_32 u4OsFilter); -+ -+VOID p2pFuncGetStationInfo(IN P_ADAPTER_T prAdapter, IN PUINT_8 pucMacAddr, OUT P_P2P_STATION_INFO_T prStaInfo); -+ -+BOOLEAN -+p2pFuncGetAttriList(IN P_ADAPTER_T prAdapter, -+ IN UINT_8 ucOuiType, -+ IN PUINT_8 pucIE, IN UINT_16 u2IELength, OUT PPUINT_8 ppucAttriList, OUT PUINT_16 pu2AttriListLen); -+ -+P_MSDU_INFO_T p2pFuncProcessP2pProbeRsp(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMgmtTxMsdu); -+ -+#if 0 /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0) */ -+UINT_32 -+p2pFuncCalculateExtra_IELenForBeacon(IN P_ADAPTER_T prAdapter, -+ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec); -+ -+VOID p2pFuncGenerateExtra_IEForBeacon(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); -+ -+#else -+UINT_32 -+p2pFuncCalculateP2p_IELenForBeacon(IN P_ADAPTER_T prAdapter, -+ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec); -+ -+VOID p2pFuncGenerateP2p_IEForBeacon(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); -+ -+UINT_32 -+p2pFuncCalculateWSC_IELenForBeacon(IN P_ADAPTER_T prAdapter, -+ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec); -+ -+VOID p2pFuncGenerateWSC_IEForBeacon(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); -+#endif -+UINT_32 -+p2pFuncCalculateP2p_IELenForAssocRsp(IN P_ADAPTER_T prAdapter, -+ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec); -+ -+VOID p2pFuncGenerateP2p_IEForAssocRsp(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); -+ -+UINT_32 -+p2pFuncCalculateWSC_IELenForAssocRsp(IN P_ADAPTER_T prAdapter, -+ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec); -+ -+VOID p2pFuncGenerateWSC_IEForAssocRsp(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); -+ -+UINT_32 -+p2pFuncCalculateP2P_IELen(IN P_ADAPTER_T prAdapter, -+ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, -+ IN P_STA_RECORD_T prStaRec, -+ IN APPEND_VAR_ATTRI_ENTRY_T arAppendAttriTable[], IN UINT_32 u4AttriTableSize); -+ -+VOID -+p2pFuncGenerateP2P_IE(IN P_ADAPTER_T prAdapter, -+ IN BOOLEAN fgIsAssocFrame, -+ IN PUINT_16 pu2Offset, -+ IN PUINT_8 pucBuf, -+ IN UINT_16 u2BufSize, -+ IN APPEND_VAR_ATTRI_ENTRY_T arAppendAttriTable[], IN UINT_32 u4AttriTableSize); -+ -+UINT_32 -+p2pFuncAppendAttriStatusForAssocRsp(IN P_ADAPTER_T prAdapter, -+ IN BOOLEAN fgIsAssocFrame, -+ IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); -+ -+UINT_32 -+p2pFuncAppendAttriExtListenTiming(IN P_ADAPTER_T prAdapter, -+ IN BOOLEAN fgIsAssocFrame, -+ IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); -+ -+VOID -+p2pFuncDissolve(IN P_ADAPTER_T prAdapter, -+ IN P_BSS_INFO_T prP2pBssInfo, IN BOOLEAN fgSendDeauth, IN UINT_16 u2ReasonCode); -+ -+P_IE_HDR_T -+p2pFuncGetSpecIE(IN P_ADAPTER_T prAdapter, -+ IN PUINT_8 pucIEBuf, IN UINT_16 u2BufferLen, IN UINT_8 ucElemID, IN PBOOLEAN pfgIsMore); -+ -+P_ATTRIBUTE_HDR_T -+p2pFuncGetSpecAttri(IN P_ADAPTER_T prAdapter, -+ IN UINT_8 ucOuiType, IN PUINT_8 pucIEBuf, IN UINT_16 u2BufferLen, IN UINT_16 u2AttriID); -+ -+WLAN_STATUS wfdChangeMediaState(IN P_ADAPTER_T prAdapter, -+ IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx, -+ IN ENUM_PARAM_MEDIA_STATE_T eConnectionState); -+#endif -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_ie.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_ie.h -new file mode 100644 -index 000000000000..efb75855695f ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_ie.h -@@ -0,0 +1,156 @@ -+#ifndef _P2P_IE_H -+#define _P2P_IE_H -+ -+#if CFG_SUPPORT_WFD -+ -+#define ELEM_MAX_LEN_WFD 62 /* TODO: Move to appropriate place */ -+ -+/*---------------- WFD Data Element Definitions ----------------*/ -+/* WFD 4.1.1 - WFD IE format */ -+#define WFD_OUI_TYPE_LEN 4 -+#define WFD_IE_OUI_HDR (ELEM_HDR_LEN + WFD_OUI_TYPE_LEN) /* == OFFSET_OF(IE_P2P_T, -+ aucP2PAttributes[0]) */ -+ -+/* WFD 4.1.1 - General WFD Attribute */ -+#define WFD_ATTRI_HDR_LEN 3 /* ID(1 octet) + Length(2 octets) */ -+ -+/* WFD Attribute Code */ -+#define WFD_ATTRI_ID_DEV_INFO 0 -+#define WFD_ATTRI_ID_ASSOC_BSSID 1 -+#define WFD_ATTRI_ID_COUPLED_SINK_INFO 6 -+#define WFD_ATTRI_ID_EXT_CAPABILITY 7 -+#define WFD_ATTRI_ID_SESSION_INFO 9 -+#define WFD_ATTRI_ID_ALTER_MAC_ADDRESS 10 -+ -+/* Maximum Length of WFD Attributes */ -+#define WFD_ATTRI_MAX_LEN_DEV_INFO 6 /* 0 */ -+#define WFD_ATTRI_MAX_LEN_ASSOC_BSSID 6 /* 1 */ -+#define WFD_ATTRI_MAX_LEN_COUPLED_SINK_INFO 7 /* 6 */ -+#define WFD_ATTRI_MAX_LEN_EXT_CAPABILITY 2 /* 7 */ -+#define WFD_ATTRI_MAX_LEN_SESSION_INFO 0 /* 9 */ /* 24 * #Clients */ -+#define WFD_ATTRI_MAX_LEN_ALTER_MAC_ADDRESS 6 /* 10 */ -+ -+/* WFD 1.10 5.1.1 */ -+typedef struct _IE_WFD_T { -+ UINT_8 ucId; /* Element ID */ -+ UINT_8 ucLength; /* Length */ -+ UINT_8 aucOui[3]; /* OUI */ -+ UINT_8 ucOuiType; /* OUI Type */ -+ UINT_8 aucWFDAttributes[1]; /* WFD Subelement */ -+} __KAL_ATTRIB_PACKED__ IE_WFD_T, *P_IE_WFD_T; -+ -+typedef struct _WFD_ATTRIBUTE_T { -+ UINT_8 ucElemID; /* Subelement ID */ -+ UINT_16 u2Length; /* Length */ -+ UINT_8 aucBody[1]; /* Body field */ -+} __KAL_ATTRIB_PACKED__ WFD_ATTRIBUTE_T, *P_WFD_ATTRIBUTE_T; -+ -+typedef struct _WFD_DEVICE_INFORMATION_IE_T { -+ UINT_8 ucElemID; -+ UINT_16 u2Length; -+ UINT_16 u2WfdDevInfo; -+ UINT_16 u2SessionMgmtCtrlPort; -+ UINT_16 u2WfdDevMaxSpeed; -+} __KAL_ATTRIB_PACKED__ WFD_DEVICE_INFORMATION_IE_T, *P_WFD_DEVICE_INFORMATION_IE_T; -+ -+typedef struct _WFD_ASSOCIATED_BSSID_IE_T { -+ UINT_8 ucElemID; -+ UINT_16 u2Length; -+ UINT_8 aucAssocBssid[MAC_ADDR_LEN]; -+} __KAL_ATTRIB_PACKED__ WFD_ASSOCIATED_BSSID_IE_T, *P_WFD_ASSOCIATED_BSSID_IE_T; -+ -+typedef struct _WFD_COUPLE_SINK_INFORMATION_IE_T { -+ UINT_8 ucElemID; -+ UINT_16 u2Length; -+ UINT_8 ucCoupleSinkStatusBp; -+ UINT_8 aucCoupleSinkMac[MAC_ADDR_LEN]; -+} __KAL_ATTRIB_PACKED__ WFD_COUPLE_SINK_INFORMATION_IE_T, *P_WFD_COUPLE_SINK_INFORMATION_IE_T; -+ -+typedef struct _WFD_EXTENDED_CAPABILITY_IE_T { -+ UINT_8 ucElemID; -+ UINT_16 u2Length; -+ UINT_16 u2WfdExtCapabilityBp; -+} __KAL_ATTRIB_PACKED__ WFD_EXTENDED_CAPABILITY_IE_T, *P_WFD_EXTENDED_CAPABILITY_IE_T; -+ -+typedef struct _WFD_SESSION_INFORMATION_IE_T { -+ UINT_8 ucElemID; -+ UINT_16 u2Length; -+ PUINT_8 pucWfdDevInfoDesc[1]; -+} __KAL_ATTRIB_PACKED__ WFD_SESSION_INFORMATION_IE_T, *P_WFD_SESSION_INFORMATION_IE_T; -+ -+typedef struct _WFD_DEVICE_INFORMATION_DESCRIPTOR_T { -+ UINT_8 ucLength; -+ UINT_8 aucDevAddr[MAC_ADDR_LEN]; -+ UINT_8 aucAssocBssid[MAC_ADDR_LEN]; -+ UINT_16 u2WfdDevInfo; -+ UINT_16 u2WfdDevMaxSpeed; -+ UINT_8 ucCoupleSinkStatusBp; -+ UINT_8 aucCoupleSinkMac[MAC_ADDR_LEN]; -+} __KAL_ATTRIB_PACKED__ WFD_DEVICE_INFORMATION_DESCRIPTOR_T, *P_WFD_DEVICE_INFORMATION_DESCRIPTOR_T; -+ -+#endif -+ -+UINT_32 -+p2pCalculate_IEForAssocReq(IN P_ADAPTER_T prAdapter, -+ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec); -+ -+VOID p2pGenerate_IEForAssocReq(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); -+ -+#if CFG_SUPPORT_WFD -+ -+UINT_32 -+wfdFuncAppendAttriDevInfo(IN P_ADAPTER_T prAdapter, -+ IN BOOLEAN fgIsAssocFrame, IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); -+ -+UINT_32 -+wfdFuncAppendAttriAssocBssid(IN P_ADAPTER_T prAdapter, -+ IN BOOLEAN fgIsAssocFrame, IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); -+ -+UINT_32 -+wfdFuncAppendAttriCoupledSinkInfo(IN P_ADAPTER_T prAdapter, -+ IN BOOLEAN fgIsAssocFrame, -+ IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); -+ -+UINT_32 -+wfdFuncAppendAttriExtCapability(IN P_ADAPTER_T prAdapter, -+ IN BOOLEAN fgIsAssocFrame, -+ IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); -+ -+UINT_32 wfdFuncCalculateAttriLenSessionInfo(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec); -+ -+UINT_32 -+wfdFuncAppendAttriSessionInfo(IN P_ADAPTER_T prAdapter, -+ IN BOOLEAN fgIsAssocFrame, -+ IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize); -+ -+UINT_32 -+wfdFuncCalculateWfdIELenForProbeResp(IN P_ADAPTER_T prAdapter, -+ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec); -+ -+VOID wfdFuncGenerateWfdIEForProbeResp(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); -+ -+UINT_32 -+wfdFuncCalculateWfdIELenForAssocReq(IN P_ADAPTER_T prAdapter, -+ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec); -+ -+VOID wfdFuncGenerateWfdIEForAssocReq(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); -+ -+UINT_32 -+wfdFuncCalculateWfdIELenForAssocRsp(IN P_ADAPTER_T prAdapter, -+ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec); -+ -+VOID wfdFuncGenerateWfdIEForAssocRsp(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); -+ -+UINT_32 -+wfdFuncCalculateWfdIELenForBeacon(IN P_ADAPTER_T prAdapter, -+ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec); -+ -+VOID wfdFuncGenerateWfdIEForBeacon(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); -+ -+#endif -+ -+UINT_32 p2pFuncCalculateP2P_IE_NoA(IN P_ADAPTER_T prAdapter, IN UINT_32 ucBssIdx, IN P_STA_RECORD_T prStaRec); -+ -+VOID p2pFuncGenerateP2P_IE_NoA(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); -+ -+#endif -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_rlm.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_rlm.h -new file mode 100644 -index 000000000000..32bc14c10959 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_rlm.h -@@ -0,0 +1,74 @@ -+/* -+** Id: //Department/DaVinci/TRUNK/WiFi_P2P_Driver/include/mgmt/p2p_rlm.h#1 -+*/ -+ -+/*! \file "rlm.h" -+ \brief -+*/ -+ -+#ifndef _P2P_RLM_H -+#define _P2P_RLM_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+extern VOID rlmSyncOperationParams(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo); -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+VOID rlmBssInitForAP(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo); -+ -+BOOLEAN rlmUpdateBwByChListForAP(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo); -+ -+VOID rlmUpdateParamsForAP(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo, BOOLEAN fgUpdateBeacon); -+ -+VOID rlmFuncInitialChannelList(IN P_ADAPTER_T prAdapter); -+ -+VOID -+rlmFuncCommonChannelList(IN P_ADAPTER_T prAdapter, -+ IN P_CHANNEL_ENTRY_FIELD_T prChannelEntryII, IN UINT_8 ucChannelListSize); -+ -+UINT_8 rlmFuncFindOperatingClass(IN P_ADAPTER_T prAdapter, IN UINT_8 ucChannelNum); -+ -+BOOLEAN -+rlmFuncFindAvailableChannel(IN P_ADAPTER_T prAdapter, -+ IN UINT_8 ucCheckChnl, -+ IN PUINT_8 pucSuggestChannel, IN BOOLEAN fgIsSocialChannel, IN BOOLEAN fgIsDefaultChannel); -+ -+ENUM_CHNL_EXT_T rlmDecideScoForAP(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo); -+ -+#endif -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_rlm_obss.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_rlm_obss.h -new file mode 100644 -index 000000000000..5b6e756f48dd ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_rlm_obss.h -@@ -0,0 +1,64 @@ -+/* -+** Id: //Department/DaVinci/TRUNK/WiFi_P2P_Driver/include/mgmt/p2p_rlm_obss.h#1 -+*/ -+ -+/*! \file "rlm_obss.h" -+ \brief -+*/ -+ -+#ifndef _P2P_RLM_OBSS_H -+#define _P2P_RLM_OBSS_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+VOID rlmRspGenerateObssScanIE(P_ADAPTER_T prAdapter, P_MSDU_INFO_T prMsduInfo); -+ -+VOID rlmProcessPublicAction(P_ADAPTER_T prAdapter, P_SW_RFB_T prSwRfb); -+ -+VOID rlmProcessHtAction(P_ADAPTER_T prAdapter, P_SW_RFB_T prSwRfb); -+ -+VOID rlmHandleObssStatusEventPkt(P_ADAPTER_T prAdapter, P_EVENT_AP_OBSS_STATUS_T prObssStatus); -+ -+UINT_8 rlmObssChnlLevel(P_BSS_INFO_T prBssInfo, ENUM_BAND_T eBand, UINT_8 ucPriChannel, ENUM_CHNL_EXT_T eExtend); -+ -+VOID rlmObssScanExemptionRsp(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo, P_SW_RFB_T prSwRfb); -+ -+#endif -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_scan.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_scan.h -new file mode 100644 -index 000000000000..8db6aa5c31e0 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_scan.h -@@ -0,0 +1,81 @@ -+/* -+** Id: //Department/DaVinci/TRUNK/WiFi_P2P_Driver/include/mgmt/p2p_scan.h#1 -+*/ -+ -+/*! \file "scan.h" -+ \brief -+ -+*/ -+ -+#ifndef _P2P_SCAN_H -+#define _P2P_SCAN_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+WLAN_STATUS scanSendDeviceDiscoverEvent(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBssDesc, IN P_SW_RFB_T prSwRfb); -+ -+P_P2P_DEVICE_DESC_T -+scanSearchTargetP2pDesc(IN P_ADAPTER_T prAdapter, IN UINT_8 aucDeviceID[], IN PP_BSS_DESC_T pprBssDesc); -+ -+P_P2P_DEVICE_DESC_T -+scanFindP2pDeviceDesc(IN P_ADAPTER_T prAdapter, -+ IN P_BSS_DESC_T prBssDesc, -+ IN UINT_8 aucMacAddr[], IN BOOLEAN fgIsDeviceAddr, IN BOOLEAN fgAddIfNoFound); -+ -+P_P2P_DEVICE_DESC_T scanGetP2pDeviceDesc(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBssDesc); -+ -+VOID scnEventReturnChannel(IN P_ADAPTER_T prAdapter, IN UINT_8 ucScnSeqNum); -+ -+BOOLEAN scanUpdateP2pDeviceDesc(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBssDesc); -+ -+VOID -+scanP2pProcessBeaconAndProbeResp(IN P_ADAPTER_T prAdapter, -+ IN P_SW_RFB_T prSwRfb, -+ IN P_WLAN_STATUS prStatus, -+ IN P_BSS_DESC_T prBssDesc, IN P_WLAN_BEACON_FRAME_T prWlanBeaconFrame); -+ -+VOID scanRemoveAllP2pBssDesc(P_ADAPTER_T prAdapter); -+ -+VOID scanRemoveP2pBssDesc(P_ADAPTER_T prAdapter, P_BSS_DESC_T prBssDesc); -+ -+P_BSS_DESC_T -+scanP2pSearchDesc(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prP2pBssInfo, IN P_P2P_CONNECTION_REQ_INFO_T prConnReqInfo); -+ -+#endif -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_state.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_state.h -new file mode 100644 -index 000000000000..8f0c4c1564a8 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/p2p_state.h -@@ -0,0 +1,43 @@ -+#ifndef _P2P_STATE_H -+#define _P2P_STATE_H -+ -+BOOLEAN -+p2pStateInit_IDLE(IN P_ADAPTER_T prAdapter, -+ IN P_P2P_FSM_INFO_T prP2pFsmInfo, IN P_BSS_INFO_T prP2pBssInfo, OUT P_ENUM_P2P_STATE_T peNextState); -+ -+VOID p2pStateAbort_IDLE(IN P_ADAPTER_T prAdapter, IN P_P2P_FSM_INFO_T prP2pFsmInfo, IN ENUM_P2P_STATE_T eNextState); -+ -+VOID p2pStateInit_SCAN(IN P_ADAPTER_T prAdapter, IN P_P2P_FSM_INFO_T prP2pFsmInfo); -+ -+VOID p2pStateAbort_SCAN(IN P_ADAPTER_T prAdapter, IN P_P2P_FSM_INFO_T prP2pFsmInfo, IN ENUM_P2P_STATE_T eNextState); -+ -+VOID p2pStateInit_AP_CHANNEL_DETECT(IN P_ADAPTER_T prAdapter, IN P_P2P_FSM_INFO_T prP2pFsmInfo); -+ -+VOID -+p2pStateAbort_AP_CHANNEL_DETECT(IN P_ADAPTER_T prAdapter, -+ IN P_P2P_FSM_INFO_T prP2pFsmInfo, -+ IN P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo, IN ENUM_P2P_STATE_T eNextState); -+ -+VOID -+p2pStateInit_CHNL_ON_HAND(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prP2pBssInfo, IN P_P2P_FSM_INFO_T prP2pFsmInfo); -+ -+VOID -+p2pStateAbort_CHNL_ON_HAND(IN P_ADAPTER_T prAdapter, -+ IN P_P2P_FSM_INFO_T prP2pFsmInfo, -+ IN P_BSS_INFO_T prP2pBssInfo, IN ENUM_P2P_STATE_T eNextState); -+ -+VOID -+p2pStateAbort_REQING_CHANNEL(IN P_ADAPTER_T prAdapter, -+ IN P_P2P_FSM_INFO_T prP2pFsmInfo, IN ENUM_P2P_STATE_T eNextState); -+ -+VOID -+p2pStateInit_GC_JOIN(IN P_ADAPTER_T prAdapter, -+ IN P_P2P_FSM_INFO_T prP2pFsmInfo, -+ IN P_BSS_INFO_T prP2pBssInfo, IN P_P2P_JOIN_INFO_T prJoinInfo, IN P_BSS_DESC_T prBssDesc); -+ -+VOID -+p2pStateAbort_GC_JOIN(IN P_ADAPTER_T prAdapter, -+ IN P_P2P_FSM_INFO_T prP2pFsmInfo, -+ IN P_P2P_JOIN_INFO_T prJoinInfo, IN ENUM_P2P_STATE_T eNextState); -+ -+#endif -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/privacy.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/privacy.h -new file mode 100644 -index 000000000000..c80430ae4eb5 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/privacy.h -@@ -0,0 +1,230 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/mgmt/privacy.h#1 -+*/ -+ -+/*! \file privacy.h -+ \brief This file contains the function declaration for privacy.c. -+*/ -+ -+/* -+** Log: privacy.h -+ * -+ * 07 24 2010 wh.su -+ * -+ * .support the Wi-Fi RSN -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 21 2010 wh.su -+ * [WPD00003840][MT6620 5931] Security migration -+ * modify some code for concurrent network. -+ * -+ * 06 19 2010 wh.su -+ * [WPD00003840][MT6620 5931] Security migration -+ * consdier the concurrent network setting. -+ * -+ * 06 18 2010 wh.su -+ * [WPD00003840][MT6620 5931] Security migration -+ * migration the security related function from firmware. -+ * -+ * 03 01 2010 wh.su -+ * [BORA00000605][WIFISYS] Phase3 Integration -+ * Refine the variable and parameter for security. -+ * -+ * 02 25 2010 wh.su -+ * [BORA00000626][MT6620] Refine the remove key flow for WHQL testing -+ * For support the WHQL test, do the remove key code refine. -+ * -+ * Dec 10 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * change the cmd return type -+ * -+ * Dec 8 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * adding the function declaration for auth mode and encryption status setting from build connection command -+ * -+ * Dec 7 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * adding the function declaration for wapi -+ * -+ * Dec 7 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * adding the tx done callback handle function -+ * -+ * Dec 7 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * adding the function declaration for mac header privacy bit setting -+ * -+ * Dec 4 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * adding the structure for parsing the EAPoL frame -+ * -+ * Dec 3 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * adjust the class error function parameter -+ * -+ * Dec 1 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * adding some security function declaration -+ * -+ * Nov 19 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * adding the ap selection structure -+ * -+ * Nov 18 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * -+** -+*/ -+ -+#ifndef _PRIVACY_H -+#define _PRIVACY_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+#define MAX_KEY_NUM 4 -+#define WEP_40_LEN 5 -+#define WEP_104_LEN 13 -+#define LEGACY_KEY_MAX_LEN 16 -+#define CCMP_KEY_LEN 16 -+#define TKIP_KEY_LEN 32 -+#define MAX_KEY_LEN 32 -+#define MIC_RX_KEY_OFFSET 16 -+#define MIC_TX_KEY_OFFSET 24 -+#define MIC_KEY_LEN 8 -+ -+#define WEP_KEY_ID_FIELD BITS(0, 29) -+#define KEY_ID_FIELD BITS(0, 7) -+ -+#define IS_TRANSMIT_KEY BIT(31) -+#define IS_UNICAST_KEY BIT(30) -+#define IS_AUTHENTICATOR BIT(28) -+ -+#define CIPHER_SUITE_NONE 0 -+#define CIPHER_SUITE_WEP40 1 -+#define CIPHER_SUITE_TKIP 2 -+#define CIPHER_SUITE_TKIP_WO_MIC 3 -+#define CIPHER_SUITE_CCMP 4 -+#define CIPHER_SUITE_WEP104 5 -+#define CIPHER_SUITE_BIP 6 -+#define CIPHER_SUITE_WEP128 7 -+#define CIPHER_SUITE_WPI 8 -+ -+#define WPA_KEY_INFO_KEY_TYPE BIT(3) /* 1 = Pairwise, 0 = Group key */ -+#define WPA_KEY_INFO_MIC BIT(8) -+#define WPA_KEY_INFO_SECURE BIT(9) -+ -+#define MASK_2ND_EAPOL (WPA_KEY_INFO_KEY_TYPE | WPA_KEY_INFO_MIC) -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+typedef struct _IEEE_802_1X_HDR { -+ UINT_8 ucVersion; -+ UINT_8 ucType; -+ UINT_16 u2Length; -+ /* followed by length octets of data */ -+} IEEE_802_1X_HDR, *P_IEEE_802_1X_HDR; -+ -+typedef struct _EAPOL_KEY { -+ UINT_8 ucType; -+ /* Note: key_info, key_length, and key_data_length are unaligned */ -+ UINT_8 aucKeyInfo[2]; /* big endian */ -+ UINT_8 aucKeyLength[2]; /* big endian */ -+ UINT_8 aucReplayCounter[8]; -+ UINT_8 aucKeyNonce[16]; -+ UINT_8 aucKeyIv[16]; -+ UINT_8 aucKeyRsc[8]; -+ UINT_8 aucKeyId[8]; /* Reserved in IEEE 802.11i/RSN */ -+ UINT_8 aucKeyMic[16]; -+ UINT_8 aucKeyDataLength[2]; /* big endian */ -+ /* followed by key_data_length bytes of key_data */ -+} EAPOL_KEY, *P_EAPOL_KEY; -+ -+/* WPA2 PMKID candicate structure */ -+typedef struct _PMKID_CANDICATE_T { -+ UINT_8 aucBssid[MAC_ADDR_LEN]; -+ UINT_32 u4PreAuthFlags; -+} PMKID_CANDICATE_T, *P_PMKID_CANDICATE_T; -+ -+#if 0 -+/* WPA2 PMKID cache structure */ -+typedef struct _PMKID_ENTRY_T { -+ PARAM_BSSID_INFO_T rBssidInfo; -+ BOOLEAN fgPmkidExist; -+} PMKID_ENTRY_T, *P_PMKID_ENTRY_T; -+#endif -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+VOID secInit(IN P_ADAPTER_T prAdapter, IN UINT_8 ucNetTypeIdx); -+ -+VOID secSetPortBlocked(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta, IN BOOLEAN fgPort); -+ -+BOOLEAN secCheckClassError(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, IN P_STA_RECORD_T prStaRec); -+ -+BOOLEAN secTxPortControlCheck(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo, IN P_STA_RECORD_T prStaRec); -+ -+BOOLEAN secRxPortControlCheck(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSWRfb); -+ -+VOID secSetCipherSuite(IN P_ADAPTER_T prAdapter, IN UINT_32 u4CipherSuitesFlags); -+ -+BOOLEAN -+secProcessEAPOL(IN P_ADAPTER_T prAdapter, -+ IN P_MSDU_INFO_T prMsduInfo, -+ IN P_STA_RECORD_T prStaRec, IN PUINT_8 pucPayload, IN UINT_16 u2PayloadLen); -+ -+VOID -+secHandleTxDoneCallback(IN P_ADAPTER_T prAdapter, -+ IN P_MSDU_INFO_T pMsduInfo, IN P_STA_RECORD_T prStaRec, IN WLAN_STATUS rStatus); -+ -+BOOLEAN secIsProtectedFrame(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsdu, IN P_STA_RECORD_T prStaRec); -+ -+VOID secClearPmkid(IN P_ADAPTER_T prAdapter); -+ -+BOOLEAN secRsnKeyHandshakeEnabled(IN P_ADAPTER_T prAdapter); -+ -+BOOLEAN secTransmitKeyExist(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta); -+ -+BOOLEAN secEnabledInAis(IN P_ADAPTER_T prAdapter); -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif /* _PRIVACY_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rate.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rate.h -new file mode 100644 -index 000000000000..123dbebdacaf ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rate.h -@@ -0,0 +1,93 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/mgmt/rate.h#1 -+*/ -+ -+/*! \file rate.h -+ \brief This file contains the rate utility function of -+ IEEE 802.11 family for MediaTek 802.11 Wireless LAN Adapters. -+*/ -+ -+/* -+** Log: rate.h -+ * -+ * 09 03 2010 kevin.huang -+ * NULL -+ * Refine #include sequence and solve recursive/nested #include issue -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 10 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add buildable & linkable ais_fsm.c -+ * -+ * related reference are still waiting to be resolved -+ * -+*/ -+ -+#ifndef _RATE_H -+#define _RATE_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+/*----------------------------------------------------------------------------*/ -+/* Routines in rate.c */ -+/*----------------------------------------------------------------------------*/ -+VOID -+rateGetRateSetFromIEs(IN P_IE_SUPPORTED_RATE_T prIeSupportedRate, -+ IN P_IE_EXT_SUPPORTED_RATE_T prIeExtSupportedRate, -+ OUT PUINT_16 pu2OperationalRateSet, -+ OUT PUINT_16 pu2BSSBasicRateSet, OUT PBOOLEAN pfgIsUnknownBSSBasicRate); -+ -+VOID -+rateGetDataRatesFromRateSet(IN UINT_16 u2OperationalRateSet, -+ IN UINT_16 u2BSSBasicRateSet, OUT PUINT_8 pucDataRates, OUT PUINT_8 pucDataRatesLen); -+ -+BOOLEAN rateGetHighestRateIndexFromRateSet(IN UINT_16 u2RateSet, OUT PUINT_8 pucHighestRateIndex); -+ -+BOOLEAN rateGetLowestRateIndexFromRateSet(IN UINT_16 u2RateSet, OUT PUINT_8 pucLowestRateIndex); -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif /* _RATE_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rlm.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rlm.h -new file mode 100644 -index 000000000000..1af3841ecec2 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rlm.h -@@ -0,0 +1,396 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/mgmt/rlm.h#2 -+*/ -+ -+/*! \file "rlm.h" -+ \brief -+*/ -+ -+/* -+** Log: rlm.h -+ * -+ * 07 17 2012 yuche.tsai -+ * NULL -+ * Compile no error before trial run. -+ * -+ * 09 30 2011 cm.chang -+ * [WCXRP00001020] [MT6620 Wi-Fi][Driver] Handle secondary channel offset of AP in 5GHz band -+ * . -+ * -+ * 04 12 2011 cm.chang -+ * [WCXRP00000634] [MT6620 Wi-Fi][Driver][FW] 2nd BSS will not support 40MHz bandwidth for concurrency -+ * . -+ * -+ * 01 13 2011 cm.chang -+ * [WCXRP00000358] [MT6620 Wi-Fi][Driver] Provide concurrent information for each module -+ * Refine function when rcv a 20/40M public action frame -+ * -+ * 01 13 2011 cm.chang -+ * [WCXRP00000354] [MT6620 Wi-Fi][Driver][FW] Follow NVRAM bandwidth setting -+ * Use SCO of BSS_INFO to replace user-defined setting variables -+ * -+ * 01 12 2011 cm.chang -+ * [WCXRP00000354] [MT6620 Wi-Fi][Driver][FW] Follow NVRAM bandwidth setting -+ * User-defined bandwidth is for 2.4G and 5G individually -+ * -+ * 12 07 2010 cm.chang -+ * [WCXRP00000239] MT6620 Wi-Fi][Driver][FW] Merge concurrent branch back to maintrunk -+ * 1. BSSINFO include RLM parameter -+ * 2. free all sta records when network is disconnected -+ * -+ * 12 07 2010 cm.chang -+ * [WCXRP00000238] MT6620 Wi-Fi][Driver][FW] Support regulation domain setting from NVRAM and supplicant -+ * 1. Country code is from NVRAM or supplicant -+ * 2. Change band definition in CMD/EVENT. -+ * -+ * 10 18 2010 cm.chang -+ * [WCXRP00000114] [MT6620 Wi-Fi] [Driver] Fix compiling warning in Linux about RLM network index checking -+ * Enum member cannot be used as compiling option decision in Linux -+ * -+ * 09 10 2010 cm.chang -+ * NULL -+ * Always update Beacon content if FW sync OBSS info -+ * -+ * 08 31 2010 kevin.huang -+ * NULL -+ * Use LINK LIST operation to process SCAN result -+ * -+ * 08 24 2010 cm.chang -+ * NULL -+ * Support RLM initail channel of Ad-hoc, P2P and BOW -+ * -+ * 08 23 2010 chinghwa.yu -+ * NULL -+ * Update for BOW. -+ * -+ * 08 20 2010 cm.chang -+ * NULL -+ * Migrate RLM code to host from FW -+ * -+ * 08 16 2010 cp.wu -+ * NULL -+ * Replace CFG_SUPPORT_BOW by CFG_ENABLE_BT_OVER_WIFI. -+ * There is no CFG_SUPPORT_BOW in driver domain source. -+ * -+ * 08 02 2010 yuche.tsai -+ * NULL -+ * P2P Group Negotiation Code Check in. -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 07 08 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Check draft RLM code for HT cap -+ * -+ * 06 28 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * 1st draft code for RLM module -+ * -+ * 06 02 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Add RX HT GF compiling option -+ * -+ * 06 02 2010 chinghwa.yu -+ * [BORA00000563]Add WiFi CoEx BCM module -+ * Roll back to remove CFG_SUPPORT_BCM_TEST. -+ * -+ * 06 01 2010 chinghwa.yu -+ * [BORA00000563]Add WiFi CoEx BCM module -+ * Update BCM Test and RW configuration. -+ * -+ * 05 31 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Add some compiling options to control 11n functions -+ * -+ * 05 18 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Ad-hoc Beacon should not carry HT OP and OBSS IEs -+ * -+ * 05 17 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * MT6620 does not support L-SIG TXOP -+ * -+ * 05 05 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * First draft support for 20/40M bandwidth for AP mode -+ * -+ * 04 24 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * g_aprBssInfo[] depends on CFG_SUPPORT_P2P and CFG_SUPPORT_BOW -+ * -+ * 04 22 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * First draft code to support protection in AP mode -+ * -+ * 04 07 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Different invoking order for WTBL entry of associated AP -+ * -+ * 03 24 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Not carry HT cap when being associated with b/g only AP -+ * -+ * 03 03 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Move default value of HT capability to rlm.h -+ * -+ * 02 12 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Use bss info array for concurrent handle -+ * -+ * 01 22 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Support protection and bandwidth switch -+ * -+ * 01 08 2010 kevin.huang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * -+ * Modify the prototype of rlmRecAssocRspHtInfo() -+ * -+ * Dec 9 2009 mtk01104 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Add several function prototypes for HT operation -+ * -+ * Nov 18 2009 mtk01104 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * -+ * -+** -+*/ -+ -+#ifndef _RLM_H -+#define _RLM_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+#define ELEM_EXT_CAP_DEFAULT_VAL \ -+ (ELEM_EXT_CAP_20_40_COEXIST_SUPPORT /*| ELEM_EXT_CAP_PSMP_CAP*/) -+ -+#if CFG_SUPPORT_RX_STBC -+#define FIELD_HT_CAP_INFO_RX_STBC HT_CAP_INFO_RX_STBC_1_SS -+#else -+#define FIELD_HT_CAP_INFO_RX_STBC HT_CAP_INFO_RX_STBC_NO_SUPPORTED -+#endif -+ -+#if CFG_SUPPORT_RX_SGI -+#define FIELD_HT_CAP_INFO_SGI_20M HT_CAP_INFO_SHORT_GI_20M -+#define FIELD_HT_CAP_INFO_SGI_40M HT_CAP_INFO_SHORT_GI_40M -+#else -+#define FIELD_HT_CAP_INFO_SGI_20M 0 -+#define FIELD_HT_CAP_INFO_SGI_40M 0 -+#endif -+ -+#if CFG_SUPPORT_RX_HT_GF -+#define FIELD_HT_CAP_INFO_HT_GF HT_CAP_INFO_HT_GF -+#else -+#define FIELD_HT_CAP_INFO_HT_GF 0 -+#endif -+ -+#define HT_CAP_INFO_DEFAULT_VAL \ -+ (HT_CAP_INFO_SUP_CHNL_WIDTH | FIELD_HT_CAP_INFO_HT_GF | \ -+ FIELD_HT_CAP_INFO_SGI_20M | FIELD_HT_CAP_INFO_SGI_40M | \ -+ FIELD_HT_CAP_INFO_RX_STBC | HT_CAP_INFO_DSSS_CCK_IN_40M) -+ -+#define AMPDU_PARAM_DEFAULT_VAL \ -+ (AMPDU_PARAM_MAX_AMPDU_LEN_64K | AMPDU_PARAM_MSS_NO_RESTRICIT) -+ -+#define SUP_MCS_TX_DEFAULT_VAL \ -+ SUP_MCS_TX_SET_DEFINED /* TX defined and TX/RX equal (TBD) */ -+ -+#if CFG_SUPPORT_MFB -+#define FIELD_HT_EXT_CAP_MFB HT_EXT_CAP_MCS_FEEDBACK_BOTH -+#else -+#define FIELD_HT_EXT_CAP_MFB HT_EXT_CAP_MCS_FEEDBACK_NO_FB -+#endif -+ -+#if CFG_SUPPORT_RX_RDG -+#define FIELD_HT_EXT_CAP_RDR HT_EXT_CAP_RD_RESPONDER -+#else -+#define FIELD_HT_EXT_CAP_RDR 0 -+#endif -+ -+#if CFG_SUPPORT_MFB || CFG_SUPPORT_RX_RDG -+#define FIELD_HT_EXT_CAP_HTC HT_EXT_CAP_HTC_SUPPORT -+#else -+#define FIELD_HT_EXT_CAP_HTC 0 -+#endif -+ -+#define HT_EXT_CAP_DEFAULT_VAL \ -+ (HT_EXT_CAP_PCO | HT_EXT_CAP_PCO_TRANS_TIME_NONE | \ -+ FIELD_HT_EXT_CAP_MFB | FIELD_HT_EXT_CAP_HTC | \ -+ FIELD_HT_EXT_CAP_RDR) -+ -+#define TX_BEAMFORMING_CAP_DEFAULT_VAL 0 -+#define ASEL_CAP_DEFAULT_VAL 0 -+ -+/* Define bandwidth from user setting */ -+#define CONFIG_BW_20_40M 0 -+#define CONFIG_BW_20M 1 /* 20MHz only */ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/* It is used for RLM module to judge if specific network is valid -+ * Note: Ad-hoc mode of AIS is not included now. (TBD) -+ */ -+#define RLM_NET_PARAM_VALID(_prBssInfo) \ -+ (IS_BSS_ACTIVE(_prBssInfo) && \ -+ ((_prBssInfo)->eConnectionState == PARAM_MEDIA_STATE_CONNECTED || \ -+ (_prBssInfo)->eCurrentOPMode == OP_MODE_ACCESS_POINT || \ -+ (_prBssInfo)->eCurrentOPMode == OP_MODE_IBSS || \ -+ RLM_NET_IS_BOW(_prBssInfo)) \ -+ ) -+ -+#define RLM_NET_IS_11N(_prBssInfo) \ -+ ((_prBssInfo)->ucPhyTypeSet & PHY_TYPE_SET_802_11N) -+#define RLM_NET_IS_11GN(_prBssInfo) \ -+ ((_prBssInfo)->ucPhyTypeSet & PHY_TYPE_SET_802_11GN) -+ -+/* This macro is used to sweep all 3 networks */ -+#define RLM_NET_FOR_EACH(_ucNetIdx) \ -+ for ((_ucNetIdx) = 0; \ -+ (_ucNetIdx) < NETWORK_TYPE_INDEX_NUM; \ -+ (_ucNetIdx)++) -+ -+/* This macro is used to sweep all networks excluding BOW */ -+#if CFG_ENABLE_BT_OVER_WIFI -+ /* Note: value of enum NETWORK_TYPE_BOW_INDEX is validated in -+ * rlmStuctureCheck(). -+ */ -+#define RLM_NET_FOR_EACH_NO_BOW(_ucNetIdx) \ -+ for ((_ucNetIdx) = 0; \ -+ (_ucNetIdx) < NETWORK_TYPE_BOW_INDEX; \ -+ (_ucNetIdx)++) -+ -+#define RLM_NET_IS_BOW(_prBssInfo) \ -+ ((_prBssInfo)->ucNetTypeIndex == NETWORK_TYPE_BOW_INDEX) -+ -+#else -+#define RLM_NET_FOR_EACH_NO_BOW(_ucNetIdx) RLM_NET_FOR_EACH(_ucNetIdx) -+#define RLM_NET_IS_BOW(_prBssInfo) (FALSE) -+ -+#endif /* end of CFG_ENABLE_BT_OVER_WIFI */ -+ -+/* The bandwidth modes are not used anymore. They represent if AP -+ * can use 20/40 bandwidth, not all modes. (20110411) -+ */ -+#define RLM_AP_IS_BW_40_ALLOWED(_prAdapter, _prBssInfo) \ -+ (((_prBssInfo)->eBand == BAND_2G4 && \ -+ (_prAdapter)->rWifiVar.rConnSettings.uc2G4BandwidthMode \ -+ == CONFIG_BW_20_40M) || \ -+ ((_prBssInfo)->eBand == BAND_5G && \ -+ (_prAdapter)->rWifiVar.rConnSettings.uc5GBandwidthMode \ -+ == CONFIG_BW_20_40M)) -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+VOID rlmFsmEventInit(P_ADAPTER_T prAdapter); -+ -+VOID rlmFsmEventUninit(P_ADAPTER_T prAdapter); -+ -+VOID rlmReqGenerateHtCapIE(P_ADAPTER_T prAdapter, P_MSDU_INFO_T prMsduInfo); -+ -+VOID rlmReqGenerateExtCapIE(P_ADAPTER_T prAdapter, P_MSDU_INFO_T prMsduInfo); -+ -+VOID rlmRspGenerateHtCapIE(P_ADAPTER_T prAdapter, P_MSDU_INFO_T prMsduInfo); -+ -+VOID rlmRspGenerateExtCapIE(P_ADAPTER_T prAdapter, P_MSDU_INFO_T prMsduInfo); -+ -+VOID rlmRspGenerateHtOpIE(P_ADAPTER_T prAdapter, P_MSDU_INFO_T prMsduInfo); -+ -+VOID rlmRspGenerateErpIE(P_ADAPTER_T prAdapter, P_MSDU_INFO_T prMsduInfo); -+ -+VOID rlmProcessBcn(P_ADAPTER_T prAdapter, P_SW_RFB_T prSwRfb, PUINT_8 pucIE, UINT_16 u2IELength); -+ -+VOID rlmProcessAssocRsp(P_ADAPTER_T prAdapter, P_SW_RFB_T prSwRfb, PUINT_8 pucIE, UINT_16 u2IELength); -+ -+VOID rlmFillSyncCmdParam(P_CMD_SET_BSS_RLM_PARAM_T prCmdBody, P_BSS_INFO_T prBssInfo); -+ -+VOID rlmSyncOperationParams(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo); -+ -+VOID rlmBssInitForAPandIbss(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo); -+ -+VOID rlmProcessAssocReq(P_ADAPTER_T prAdapter, P_SW_RFB_T prSwRfb, PUINT_8 pucIE, UINT_16 u2IELength); -+ -+VOID rlmBssAborted(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo); -+ -+UINT32 -+rlmFillHtCapIEByParams(BOOLEAN fg40mAllowed, -+ BOOLEAN fgShortGIDisabled, -+ UINT_8 u8SupportRxSgi20, -+ UINT_8 u8SupportRxSgi40, -+ UINT_8 u8SupportRxGf, UINT_8 u8SupportRxSTBC, ENUM_OP_MODE_T eCurrentOPMode, UINT_8 *pOutBuf); -+ -+UINT32 rlmFillHtOpIeBody(P_BSS_INFO_T prBssInfo, UINT_8 *pFme); -+ -+#if CFG_SUPPORT_DFS /* Add by Enlai */ -+VOID rlmProcessSpecMgtAction(P_ADAPTER_T prAdapter, P_SW_RFB_T prSwRfb); -+ -+VOID rlmProcessChannelSwitchIE(P_ADAPTER_T prAdapter, P_IE_CHANNEL_SWITCH_T prChannelSwitchIE); -+#endif -+ -+VOID -+rlmTxRateEnhanceConfig( -+ P_ADAPTER_T prAdapter -+ ); -+ -+VOID -+rlmCmd( -+ P_GLUE_INFO_T prGlueInfo, -+ UINT_8 *prInBuf, -+ UINT_32 u4InBufLen -+ ); -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#ifndef _lint -+static inline VOID rlmDataTypeCheck(VOID) -+{ -+#if CFG_ENABLE_BT_OVER_WIFI -+ DATA_STRUCT_INSPECTING_ASSERT(NETWORK_TYPE_AIS_INDEX < NETWORK_TYPE_BOW_INDEX); -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ DATA_STRUCT_INSPECTING_ASSERT(NETWORK_TYPE_P2P_INDEX < NETWORK_TYPE_BOW_INDEX); -+#endif -+#endif -+ -+} -+#endif /* _lint */ -+ -+#endif /* _RLM_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rlm_domain.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rlm_domain.h -new file mode 100644 -index 000000000000..65e907041a28 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rlm_domain.h -@@ -0,0 +1,557 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/mgmt/rlm_domain.h#1 -+*/ -+ -+/*! \file "rlm_domain.h" -+ \brief -+*/ -+ -+/* -+** Log: rlm_domain.h -+ * -+ * 09 29 2011 cm.chang -+ * NULL -+ * Change the function prototype of rlmDomainGetChnlList() -+ * -+ * 09 08 2011 cm.chang -+ * [WCXRP00000969] [MT6620 Wi-Fi][Driver][FW] Channel list for 5G band based on country code -+ * Use new fields ucChannelListMap and ucChannelListIndex in NVRAM -+ * -+ * 08 31 2011 cm.chang -+ * [WCXRP00000969] [MT6620 Wi-Fi][Driver][FW] Channel list for 5G band based on country code -+ * . -+ * -+ * 06 01 2011 cm.chang -+ * [WCXRP00000756] [MT6620 Wi-Fi][Driver] 1. AIS follow channel of BOW 2. Provide legal channel function -+ * Provide legal channel function based on domain -+ * -+ * 12 07 2010 cm.chang -+ * [WCXRP00000238] MT6620 Wi-Fi][Driver][FW] Support regulation domain setting from NVRAM and supplicant -+ * 1. Country code is from NVRAM or supplicant -+ * 2. Change band definition in CMD/EVENT. -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 28 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * 1st draft code for RLM module -+ * -+ * 02 23 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Add support scan channel 1~14 and update scan result's frequency infou1rwduu`wvpghlqg|n`slk+mpdkb -+ * -+ * 01 13 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Provide query function about full channel list. -+ * -+ * Dec 1 2009 mtk01104 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Declare public rDomainInfo -+ * -+** -+*/ -+ -+#ifndef _RLM_DOMAIN_H -+#define _RLM_DOMAIN_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+#define MAX_SUBBAND_NUM 6 -+#define MAX_SUBBAND_NUM_5G 8 -+ -+#define COUNTRY_CODE_NULL ((UINT_16)0x0) -+ -+/* ISO/IEC 3166-1 two-character country codes */ -+ -+#define COUNTRY_CODE_AD (((UINT_16) 'A' << 8) | (UINT_16) 'D') /* Andorra */ -+#define COUNTRY_CODE_AE (((UINT_16) 'A' << 8) | (UINT_16) 'E') /* UAE */ -+#define COUNTRY_CODE_AF (((UINT_16) 'A' << 8) | (UINT_16) 'F') /* Afghanistan */ -+#define COUNTRY_CODE_AG (((UINT_16) 'A' << 8) | (UINT_16) 'G') /* Antigua & Barbuda */ -+#define COUNTRY_CODE_AI (((UINT_16) 'A' << 8) | (UINT_16) 'I') /* Anguilla */ -+#define COUNTRY_CODE_AL (((UINT_16) 'A' << 8) | (UINT_16) 'L') /* Albania */ -+#define COUNTRY_CODE_AM (((UINT_16) 'A' << 8) | (UINT_16) 'M') /* Armenia */ -+#define COUNTRY_CODE_AN (((UINT_16) 'A' << 8) | (UINT_16) 'N') /* Netherlands Antilles */ -+#define COUNTRY_CODE_AO (((UINT_16) 'A' << 8) | (UINT_16) 'O') /* Angola */ -+#define COUNTRY_CODE_AR (((UINT_16) 'A' << 8) | (UINT_16) 'R') /* Argentina */ -+#define COUNTRY_CODE_AS (((UINT_16) 'A' << 8) | (UINT_16) 'S') /* American Samoa (USA) */ -+#define COUNTRY_CODE_AT (((UINT_16) 'A' << 8) | (UINT_16) 'T') /* Austria */ -+#define COUNTRY_CODE_AU (((UINT_16) 'A' << 8) | (UINT_16) 'U') /* Australia */ -+#define COUNTRY_CODE_AW (((UINT_16) 'A' << 8) | (UINT_16) 'W') /* Aruba */ -+#define COUNTRY_CODE_AZ (((UINT_16) 'A' << 8) | (UINT_16) 'Z') /* Azerbaijan */ -+#define COUNTRY_CODE_BA (((UINT_16) 'B' << 8) | (UINT_16) 'A') /* Bosnia and Herzegovina */ -+#define COUNTRY_CODE_BB (((UINT_16) 'B' << 8) | (UINT_16) 'B') /* Barbados */ -+#define COUNTRY_CODE_BD (((UINT_16) 'B' << 8) | (UINT_16) 'D') /* Bangladesh */ -+#define COUNTRY_CODE_BE (((UINT_16) 'B' << 8) | (UINT_16) 'E') /* Belgium */ -+#define COUNTRY_CODE_BF (((UINT_16) 'B' << 8) | (UINT_16) 'F') /* Burkina Faso */ -+#define COUNTRY_CODE_BG (((UINT_16) 'B' << 8) | (UINT_16) 'G') /* Bulgaria */ -+#define COUNTRY_CODE_BH (((UINT_16) 'B' << 8) | (UINT_16) 'H') /* Bahrain */ -+#define COUNTRY_CODE_BI (((UINT_16) 'B' << 8) | (UINT_16) 'I') /* Burundi */ -+#define COUNTRY_CODE_BJ (((UINT_16) 'B' << 8) | (UINT_16) 'J') /* Benin */ -+#define COUNTRY_CODE_BM (((UINT_16) 'B' << 8) | (UINT_16) 'M') /* Bermuda */ -+#define COUNTRY_CODE_BN (((UINT_16) 'B' << 8) | (UINT_16) 'N') /* Brunei */ -+#define COUNTRY_CODE_BO (((UINT_16) 'B' << 8) | (UINT_16) 'O') /* Bolivia */ -+#define COUNTRY_CODE_BR (((UINT_16) 'B' << 8) | (UINT_16) 'R') /* Brazil */ -+#define COUNTRY_CODE_BS (((UINT_16) 'B' << 8) | (UINT_16) 'S') /* Bahamas */ -+#define COUNTRY_CODE_BT (((UINT_16) 'B' << 8) | (UINT_16) 'T') /* Bhutan */ -+#define COUNTRY_CODE_BW (((UINT_16) 'B' << 8) | (UINT_16) 'W') /* Botswana */ -+#define COUNTRY_CODE_BY (((UINT_16) 'B' << 8) | (UINT_16) 'Y') /* Belarus */ -+#define COUNTRY_CODE_BZ (((UINT_16) 'B' << 8) | (UINT_16) 'Z') /* Belize */ -+#define COUNTRY_CODE_CA (((UINT_16) 'C' << 8) | (UINT_16) 'A') /* Canada */ -+#define COUNTRY_CODE_CD (((UINT_16) 'C' << 8) | (UINT_16) 'D') /* Congo. Democratic Republic of the */ -+#define COUNTRY_CODE_CF (((UINT_16) 'C' << 8) | (UINT_16) 'F') /* Central African Republic */ -+#define COUNTRY_CODE_CG (((UINT_16) 'C' << 8) | (UINT_16) 'G') /* Congo. Republic of the */ -+#define COUNTRY_CODE_CH (((UINT_16) 'C' << 8) | (UINT_16) 'H') /* Switzerland */ -+#define COUNTRY_CODE_CI (((UINT_16) 'C' << 8) | (UINT_16) 'I') /* Cote d'lvoire */ -+#define COUNTRY_CODE_CK (((UINT_16) 'C' << 8) | (UINT_16) 'K') /* Cook Island */ -+#define COUNTRY_CODE_CL (((UINT_16) 'C' << 8) | (UINT_16) 'L') /* Chile */ -+#define COUNTRY_CODE_CM (((UINT_16) 'C' << 8) | (UINT_16) 'M') /* Cameroon */ -+#define COUNTRY_CODE_CN (((UINT_16) 'C' << 8) | (UINT_16) 'N') /* China */ -+#define COUNTRY_CODE_CO (((UINT_16) 'C' << 8) | (UINT_16) 'O') /* Columbia */ -+#define COUNTRY_CODE_CR (((UINT_16) 'C' << 8) | (UINT_16) 'R') /* Costa Rica */ -+#define COUNTRY_CODE_CU (((UINT_16) 'C' << 8) | (UINT_16) 'U') /* Cuba */ -+#define COUNTRY_CODE_CV (((UINT_16) 'C' << 8) | (UINT_16) 'V') /* Cape Verde */ -+#define COUNTRY_CODE_CX (((UINT_16) 'C' << 8) | (UINT_16) 'X') /* "Christmas Island(Australia) */ -+#define COUNTRY_CODE_CY (((UINT_16) 'C' << 8) | (UINT_16) 'Y') /* Cyprus */ -+#define COUNTRY_CODE_CZ (((UINT_16) 'C' << 8) | (UINT_16) 'Z') /* Czech */ -+#define COUNTRY_CODE_DE (((UINT_16) 'D' << 8) | (UINT_16) 'E') /* Germany */ -+#define COUNTRY_CODE_DJ (((UINT_16) 'D' << 8) | (UINT_16) 'J') /* Djibouti */ -+#define COUNTRY_CODE_DK (((UINT_16) 'D' << 8) | (UINT_16) 'K') /* Denmark */ -+#define COUNTRY_CODE_DM (((UINT_16) 'D' << 8) | (UINT_16) 'M') /* Dominica */ -+#define COUNTRY_CODE_DO (((UINT_16) 'D' << 8) | (UINT_16) 'O') /* Dominican Republic */ -+#define COUNTRY_CODE_DZ (((UINT_16) 'D' << 8) | (UINT_16) 'Z') /* Algeria */ -+#define COUNTRY_CODE_EC (((UINT_16) 'E' << 8) | (UINT_16) 'C') /* Ecuador */ -+#define COUNTRY_CODE_EE (((UINT_16) 'E' << 8) | (UINT_16) 'E') /* Estonia */ -+#define COUNTRY_CODE_EG (((UINT_16) 'E' << 8) | (UINT_16) 'G') /* Egypt */ -+#define COUNTRY_CODE_EH (((UINT_16) 'E' << 8) | (UINT_16) 'H') /* Western Sahara (Morocco) */ -+#define COUNTRY_CODE_ER (((UINT_16) 'E' << 8) | (UINT_16) 'R') /* Eritrea */ -+#define COUNTRY_CODE_ES (((UINT_16) 'E' << 8) | (UINT_16) 'S') /* Spain */ -+#define COUNTRY_CODE_ET (((UINT_16) 'E' << 8) | (UINT_16) 'T') /* Ethiopia */ -+#define COUNTRY_CODE_EU (((UINT_16) 'E' << 8) | (UINT_16) 'U') /* Europe */ -+#define COUNTRY_CODE_FI (((UINT_16) 'F' << 8) | (UINT_16) 'I') /* Finland */ -+#define COUNTRY_CODE_FJ (((UINT_16) 'F' << 8) | (UINT_16) 'J') /* Fiji */ -+#define COUNTRY_CODE_FK (((UINT_16) 'F' << 8) | (UINT_16) 'K') /* Falkland Island */ -+#define COUNTRY_CODE_FM (((UINT_16) 'F' << 8) | (UINT_16) 'M') /* Micronesia */ -+#define COUNTRY_CODE_FO (((UINT_16) 'F' << 8) | (UINT_16) 'O') /* Faroe Island */ -+#define COUNTRY_CODE_FR (((UINT_16) 'F' << 8) | (UINT_16) 'R') /* France */ -+#define COUNTRY_CODE_FR (((UINT_16) 'F' << 8) | (UINT_16) 'R') /* Wallis and Futuna (France) */ -+#define COUNTRY_CODE_GA (((UINT_16) 'G' << 8) | (UINT_16) 'A') /* Gabon */ -+#define COUNTRY_CODE_GB (((UINT_16) 'G' << 8) | (UINT_16) 'B') /* United Kingdom */ -+#define COUNTRY_CODE_GD (((UINT_16) 'G' << 8) | (UINT_16) 'D') /* Grenada */ -+#define COUNTRY_CODE_GE (((UINT_16) 'G' << 8) | (UINT_16) 'E') /* Georgia */ -+#define COUNTRY_CODE_GF (((UINT_16) 'G' << 8) | (UINT_16) 'F') /* French Guiana */ -+#define COUNTRY_CODE_GG (((UINT_16) 'G' << 8) | (UINT_16) 'G') /* Guernsey */ -+#define COUNTRY_CODE_GH (((UINT_16) 'G' << 8) | (UINT_16) 'H') /* Ghana */ -+#define COUNTRY_CODE_GI (((UINT_16) 'G' << 8) | (UINT_16) 'I') /* Gibraltar */ -+#define COUNTRY_CODE_GM (((UINT_16) 'G' << 8) | (UINT_16) 'M') /* Gambia */ -+#define COUNTRY_CODE_GN (((UINT_16) 'G' << 8) | (UINT_16) 'N') /* Guinea */ -+#define COUNTRY_CODE_GP (((UINT_16) 'G' << 8) | (UINT_16) 'P') /* Guadeloupe */ -+#define COUNTRY_CODE_GQ (((UINT_16) 'G' << 8) | (UINT_16) 'Q') /* Equatorial Guinea */ -+#define COUNTRY_CODE_GR (((UINT_16) 'G' << 8) | (UINT_16) 'R') /* Greece */ -+#define COUNTRY_CODE_GT (((UINT_16) 'G' << 8) | (UINT_16) 'T') /* Guatemala */ -+#define COUNTRY_CODE_GU (((UINT_16) 'G' << 8) | (UINT_16) 'U') /* Guam */ -+#define COUNTRY_CODE_GW (((UINT_16) 'G' << 8) | (UINT_16) 'W') /* Guinea-Bissau */ -+#define COUNTRY_CODE_GY (((UINT_16) 'G' << 8) | (UINT_16) 'Y') /* Guyana */ -+#define COUNTRY_CODE_HK (((UINT_16) 'H' << 8) | (UINT_16) 'K') /* Hong Kong */ -+#define COUNTRY_CODE_HN (((UINT_16) 'H' << 8) | (UINT_16) 'N') /* Honduras */ -+#define COUNTRY_CODE_HR (((UINT_16) 'H' << 8) | (UINT_16) 'R') /* Croatia */ -+#define COUNTRY_CODE_HT (((UINT_16) 'H' << 8) | (UINT_16) 'T') /* Haiti */ -+#define COUNTRY_CODE_HU (((UINT_16) 'H' << 8) | (UINT_16) 'U') /* Hungary */ -+#define COUNTRY_CODE_ID (((UINT_16) 'I' << 8) | (UINT_16) 'D') /* Indonesia */ -+#define COUNTRY_CODE_IE (((UINT_16) 'I' << 8) | (UINT_16) 'E') /* Ireland */ -+#define COUNTRY_CODE_IL (((UINT_16) 'I' << 8) | (UINT_16) 'L') /* Israel */ -+#define COUNTRY_CODE_IM (((UINT_16) 'I' << 8) | (UINT_16) 'M') /* Isle of Man */ -+#define COUNTRY_CODE_IN (((UINT_16) 'I' << 8) | (UINT_16) 'N') /* India */ -+#define COUNTRY_CODE_IQ (((UINT_16) 'I' << 8) | (UINT_16) 'Q') /* Iraq */ -+#define COUNTRY_CODE_IR (((UINT_16) 'I' << 8) | (UINT_16) 'R') /* Iran */ -+#define COUNTRY_CODE_IS (((UINT_16) 'I' << 8) | (UINT_16) 'S') /* Iceland */ -+#define COUNTRY_CODE_IT (((UINT_16) 'I' << 8) | (UINT_16) 'T') /* Italy */ -+#define COUNTRY_CODE_JE (((UINT_16) 'J' << 8) | (UINT_16) 'E') /* Jersey */ -+#define COUNTRY_CODE_JM (((UINT_16) 'J' << 8) | (UINT_16) 'M') /* Jameica */ -+#define COUNTRY_CODE_JO (((UINT_16) 'J' << 8) | (UINT_16) 'O') /* Jordan */ -+#define COUNTRY_CODE_JP (((UINT_16) 'J' << 8) | (UINT_16) 'P') /* Japan */ -+#define COUNTRY_CODE_KE (((UINT_16) 'K' << 8) | (UINT_16) 'E') /* Kenya */ -+#define COUNTRY_CODE_KG (((UINT_16) 'K' << 8) | (UINT_16) 'G') /* Kyrgyzstan */ -+#define COUNTRY_CODE_KH (((UINT_16) 'K' << 8) | (UINT_16) 'H') /* Cambodia */ -+#define COUNTRY_CODE_KI (((UINT_16) 'K' << 8) | (UINT_16) 'I') /* Kiribati */ -+#define COUNTRY_CODE_KM (((UINT_16) 'K' << 8) | (UINT_16) 'M') /* Comoros */ -+#define COUNTRY_CODE_KN (((UINT_16) 'K' << 8) | (UINT_16) 'N') /* Saint Kitts and Nevis */ -+#define COUNTRY_CODE_KP (((UINT_16) 'K' << 8) | (UINT_16) 'P') /* North Korea */ -+#define COUNTRY_CODE_KR (((UINT_16) 'K' << 8) | (UINT_16) 'R') /* South Korea */ -+#define COUNTRY_CODE_KW (((UINT_16) 'K' << 8) | (UINT_16) 'W') /* Kuwait */ -+#define COUNTRY_CODE_KY (((UINT_16) 'K' << 8) | (UINT_16) 'Y') /* Cayman Islands */ -+#define COUNTRY_CODE_KZ (((UINT_16) 'K' << 8) | (UINT_16) 'Z') /* Kazakhstan */ -+#define COUNTRY_CODE_LA (((UINT_16) 'L' << 8) | (UINT_16) 'A') /* Laos */ -+#define COUNTRY_CODE_LB (((UINT_16) 'L' << 8) | (UINT_16) 'B') /* Lebanon */ -+#define COUNTRY_CODE_LC (((UINT_16) 'L' << 8) | (UINT_16) 'C') /* Saint Lucia */ -+#define COUNTRY_CODE_LI (((UINT_16) 'L' << 8) | (UINT_16) 'I') /* Liechtenstein */ -+#define COUNTRY_CODE_LK (((UINT_16) 'L' << 8) | (UINT_16) 'K') /* Sri Lanka */ -+#define COUNTRY_CODE_LR (((UINT_16) 'L' << 8) | (UINT_16) 'R') /* Liberia */ -+#define COUNTRY_CODE_LS (((UINT_16) 'L' << 8) | (UINT_16) 'S') /* Lesotho */ -+#define COUNTRY_CODE_LT (((UINT_16) 'L' << 8) | (UINT_16) 'T') /* Lithuania */ -+#define COUNTRY_CODE_LU (((UINT_16) 'L' << 8) | (UINT_16) 'U') /* Luxemburg */ -+#define COUNTRY_CODE_LV (((UINT_16) 'L' << 8) | (UINT_16) 'V') /* Latvia */ -+#define COUNTRY_CODE_LY (((UINT_16) 'L' << 8) | (UINT_16) 'Y') /* Libya */ -+#define COUNTRY_CODE_MA (((UINT_16) 'M' << 8) | (UINT_16) 'A') /* Morocco */ -+#define COUNTRY_CODE_MC (((UINT_16) 'M' << 8) | (UINT_16) 'C') /* Monaco */ -+#define COUNTRY_CODE_MD (((UINT_16) 'M' << 8) | (UINT_16) 'D') /* Moldova */ -+#define COUNTRY_CODE_ME (((UINT_16) 'M' << 8) | (UINT_16) 'E') /* Montenegro */ -+#define COUNTRY_CODE_MF (((UINT_16) 'M' << 8) | (UINT_16) 'F') /* Saint Martin / Sint Marteen -+ (Added on window's list) */ -+#define COUNTRY_CODE_MG (((UINT_16) 'M' << 8) | (UINT_16) 'G') /* Madagascar */ -+#define COUNTRY_CODE_MH (((UINT_16) 'M' << 8) | (UINT_16) 'H') /* Marshall Islands */ -+#define COUNTRY_CODE_MK (((UINT_16) 'M' << 8) | (UINT_16) 'K') /* Macedonia */ -+#define COUNTRY_CODE_ML (((UINT_16) 'M' << 8) | (UINT_16) 'L') /* Mali */ -+#define COUNTRY_CODE_MM (((UINT_16) 'M' << 8) | (UINT_16) 'M') /* Myanmar */ -+#define COUNTRY_CODE_MN (((UINT_16) 'M' << 8) | (UINT_16) 'N') /* Mongolia */ -+#define COUNTRY_CODE_MO (((UINT_16) 'M' << 8) | (UINT_16) 'O') /* Macao */ -+#define COUNTRY_CODE_MP (((UINT_16) 'M' << 8) | (UINT_16) 'P') /* Northern Mariana Islands (Rota Island. -+ Saipan and Tinian Island) */ -+#define COUNTRY_CODE_MQ (((UINT_16) 'M' << 8) | (UINT_16) 'Q') /* Martinique (France) */ -+#define COUNTRY_CODE_MR (((UINT_16) 'M' << 8) | (UINT_16) 'R') /* Mauritania */ -+#define COUNTRY_CODE_MS (((UINT_16) 'M' << 8) | (UINT_16) 'S') /* Montserrat (UK) */ -+#define COUNTRY_CODE_MT (((UINT_16) 'M' << 8) | (UINT_16) 'T') /* Malta */ -+#define COUNTRY_CODE_MU (((UINT_16) 'M' << 8) | (UINT_16) 'U') /* Mauritius */ -+#define COUNTRY_CODE_MV (((UINT_16) 'M' << 8) | (UINT_16) 'V') /* Maldives */ -+#define COUNTRY_CODE_MW (((UINT_16) 'M' << 8) | (UINT_16) 'W') /* Malawi */ -+#define COUNTRY_CODE_MX (((UINT_16) 'M' << 8) | (UINT_16) 'X') /* Mexico */ -+#define COUNTRY_CODE_MY (((UINT_16) 'M' << 8) | (UINT_16) 'Y') /* Malaysia */ -+#define COUNTRY_CODE_MZ (((UINT_16) 'M' << 8) | (UINT_16) 'Z') /* Mozambique */ -+#define COUNTRY_CODE_NA (((UINT_16) 'N' << 8) | (UINT_16) 'A') /* Namibia */ -+#define COUNTRY_CODE_NC (((UINT_16) 'N' << 8) | (UINT_16) 'C') /* New Caledonia */ -+#define COUNTRY_CODE_NE (((UINT_16) 'N' << 8) | (UINT_16) 'E') /* Niger */ -+#define COUNTRY_CODE_NF (((UINT_16) 'N' << 8) | (UINT_16) 'F') /* Norfolk Island */ -+#define COUNTRY_CODE_NG (((UINT_16) 'N' << 8) | (UINT_16) 'G') /* Nigeria */ -+#define COUNTRY_CODE_NI (((UINT_16) 'N' << 8) | (UINT_16) 'I') /* Nicaragua */ -+#define COUNTRY_CODE_NL (((UINT_16) 'N' << 8) | (UINT_16) 'L') /* Netherlands */ -+#define COUNTRY_CODE_NO (((UINT_16) 'N' << 8) | (UINT_16) 'O') /* Norway */ -+#define COUNTRY_CODE_NP (((UINT_16) 'N' << 8) | (UINT_16) 'P') /* Nepal */ -+#define COUNTRY_CODE_NR (((UINT_16) 'N' << 8) | (UINT_16) 'R') /* Nauru */ -+#define COUNTRY_CODE_NU (((UINT_16) 'N' << 8) | (UINT_16) 'U') /* Niue */ -+#define COUNTRY_CODE_NZ (((UINT_16) 'N' << 8) | (UINT_16) 'Z') /* New Zealand */ -+#define COUNTRY_CODE_OM (((UINT_16) 'O' << 8) | (UINT_16) 'M') /* Oman */ -+#define COUNTRY_CODE_PA (((UINT_16) 'P' << 8) | (UINT_16) 'A') /* Panama */ -+#define COUNTRY_CODE_PE (((UINT_16) 'P' << 8) | (UINT_16) 'E') /* Peru */ -+#define COUNTRY_CODE_PF (((UINT_16) 'P' << 8) | (UINT_16) 'F') /* "French Polynesia */ -+#define COUNTRY_CODE_PG (((UINT_16) 'P' << 8) | (UINT_16) 'G') /* Papua New Guinea */ -+#define COUNTRY_CODE_PH (((UINT_16) 'P' << 8) | (UINT_16) 'H') /* Philippines */ -+#define COUNTRY_CODE_PK (((UINT_16) 'P' << 8) | (UINT_16) 'K') /* Pakistan */ -+#define COUNTRY_CODE_PL (((UINT_16) 'P' << 8) | (UINT_16) 'L') /* Poland */ -+#define COUNTRY_CODE_PM (((UINT_16) 'P' << 8) | (UINT_16) 'M') /* Saint Pierre and Miquelon */ -+#define COUNTRY_CODE_PN (((UINT_16) 'P' << 8) | (UINT_16) 'N') /* Pitcairn Islands */ -+#define COUNTRY_CODE_PR (((UINT_16) 'P' << 8) | (UINT_16) 'R') /* Puerto Rico (USA) */ -+#define COUNTRY_CODE_PS (((UINT_16) 'P' << 8) | (UINT_16) 'S') /* Palestinian Authority */ -+#define COUNTRY_CODE_PT (((UINT_16) 'P' << 8) | (UINT_16) 'T') /* Portugal */ -+#define COUNTRY_CODE_PW (((UINT_16) 'P' << 8) | (UINT_16) 'W') /* Palau */ -+#define COUNTRY_CODE_PY (((UINT_16) 'P' << 8) | (UINT_16) 'Y') /* Paraguay */ -+#define COUNTRY_CODE_QA (((UINT_16) 'Q' << 8) | (UINT_16) 'A') /* Qatar */ -+#define COUNTRY_CODE_RE (((UINT_16) 'R' << 8) | (UINT_16) 'E') /* Reunion (France) */ -+#define COUNTRY_CODE_RKS (((UINT_16) 'R' << 8) | (UINT_16) 'K') /* Kosvo (Added on window's list) */ -+#define COUNTRY_CODE_RO (((UINT_16) 'R' << 8) | (UINT_16) 'O') /* Romania */ -+#define COUNTRY_CODE_RS (((UINT_16) 'R' << 8) | (UINT_16) 'S') /* Serbia */ -+#define COUNTRY_CODE_RU (((UINT_16) 'R' << 8) | (UINT_16) 'U') /* Russia */ -+#define COUNTRY_CODE_RW (((UINT_16) 'R' << 8) | (UINT_16) 'W') /* Rwanda */ -+#define COUNTRY_CODE_SA (((UINT_16) 'S' << 8) | (UINT_16) 'A') /* Saudi Arabia */ -+#define COUNTRY_CODE_SB (((UINT_16) 'S' << 8) | (UINT_16) 'B') /* Solomon Islands */ -+#define COUNTRY_CODE_SC (((UINT_16) 'S' << 8) | (UINT_16) 'C') /* Seychelles */ -+#define COUNTRY_CODE_SD (((UINT_16) 'S' << 8) | (UINT_16) 'D') /* Sudan */ -+#define COUNTRY_CODE_SE (((UINT_16) 'S' << 8) | (UINT_16) 'E') /* Sweden */ -+#define COUNTRY_CODE_SG (((UINT_16) 'S' << 8) | (UINT_16) 'G') /* Singapole */ -+#define COUNTRY_CODE_SI (((UINT_16) 'S' << 8) | (UINT_16) 'I') /* Slovenia */ -+#define COUNTRY_CODE_SK (((UINT_16) 'S' << 8) | (UINT_16) 'K') /* Slovakia */ -+#define COUNTRY_CODE_SL (((UINT_16) 'S' << 8) | (UINT_16) 'L') /* Sierra Leone */ -+#define COUNTRY_CODE_SM (((UINT_16) 'S' << 8) | (UINT_16) 'M') /* San Marino */ -+#define COUNTRY_CODE_SN (((UINT_16) 'S' << 8) | (UINT_16) 'N') /* Senegal */ -+#define COUNTRY_CODE_SO (((UINT_16) 'S' << 8) | (UINT_16) 'O') /* Somalia */ -+#define COUNTRY_CODE_SR (((UINT_16) 'S' << 8) | (UINT_16) 'R') /* Suriname */ -+#define COUNTRY_CODE_SS (((UINT_16) 'S' << 8) | (UINT_16) 'S') /* South_Sudan */ -+#define COUNTRY_CODE_ST (((UINT_16) 'S' << 8) | (UINT_16) 'T') /* Sao Tome and Principe */ -+#define COUNTRY_CODE_SV (((UINT_16) 'S' << 8) | (UINT_16) 'V') /* El Salvador */ -+#define COUNTRY_CODE_SY (((UINT_16) 'S' << 8) | (UINT_16) 'Y') /* Syria */ -+#define COUNTRY_CODE_SZ (((UINT_16) 'S' << 8) | (UINT_16) 'Z') /* Swaziland */ -+#define COUNTRY_CODE_TC (((UINT_16) 'T' << 8) | (UINT_16) 'C') /* Turks and Caicos Islands (UK) */ -+#define COUNTRY_CODE_TD (((UINT_16) 'T' << 8) | (UINT_16) 'D') /* Chad */ -+#define COUNTRY_CODE_TF (((UINT_16) 'T' << 8) | (UINT_16) 'F') /* French Southern and Antarctic Lands */ -+#define COUNTRY_CODE_TG (((UINT_16) 'T' << 8) | (UINT_16) 'G') /* Togo */ -+#define COUNTRY_CODE_TH (((UINT_16) 'T' << 8) | (UINT_16) 'H') /* Thailand */ -+#define COUNTRY_CODE_TJ (((UINT_16) 'T' << 8) | (UINT_16) 'J') /* Tajikistan */ -+#define COUNTRY_CODE_TL (((UINT_16) 'T' << 8) | (UINT_16) 'L') /* East Timor */ -+#define COUNTRY_CODE_TM (((UINT_16) 'T' << 8) | (UINT_16) 'M') /* Turkmenistan */ -+#define COUNTRY_CODE_TN (((UINT_16) 'T' << 8) | (UINT_16) 'N') /* Tunisia */ -+#define COUNTRY_CODE_TO (((UINT_16) 'T' << 8) | (UINT_16) 'O') /* Tonga */ -+#define COUNTRY_CODE_TR (((UINT_16) 'T' << 8) | (UINT_16) 'R') /* Turkey */ -+#define COUNTRY_CODE_TT (((UINT_16) 'T' << 8) | (UINT_16) 'T') /* Trinidad and Tobago */ -+#define COUNTRY_CODE_TV (((UINT_16) 'T' << 8) | (UINT_16) 'V') /* Tuvalu */ -+#define COUNTRY_CODE_TW (((UINT_16) 'T' << 8) | (UINT_16) 'W') /* Taiwan */ -+#define COUNTRY_CODE_TZ (((UINT_16) 'T' << 8) | (UINT_16) 'Z') /* Tanzania */ -+#define COUNTRY_CODE_UA (((UINT_16) 'U' << 8) | (UINT_16) 'A') /* Ukraine */ -+#define COUNTRY_CODE_UG (((UINT_16) 'U' << 8) | (UINT_16) 'G') /* Ugnada */ -+#define COUNTRY_CODE_US (((UINT_16) 'U' << 8) | (UINT_16) 'S') /* US */ -+#define COUNTRY_CODE_UY (((UINT_16) 'U' << 8) | (UINT_16) 'Y') /* Uruguay */ -+#define COUNTRY_CODE_UZ (((UINT_16) 'U' << 8) | (UINT_16) 'Z') /* Uzbekistan */ -+#define COUNTRY_CODE_VA (((UINT_16) 'V' << 8) | (UINT_16) 'A') /* Vatican (Holy See) */ -+#define COUNTRY_CODE_VC (((UINT_16) 'V' << 8) | (UINT_16) 'C') /* Saint Vincent and the Grenadines */ -+#define COUNTRY_CODE_VE (((UINT_16) 'V' << 8) | (UINT_16) 'E') /* Venezuela */ -+#define COUNTRY_CODE_VG (((UINT_16) 'V' << 8) | (UINT_16) 'G') /* British Virgin Islands */ -+#define COUNTRY_CODE_VI (((UINT_16) 'V' << 8) | (UINT_16) 'I') /* US Virgin Islands */ -+#define COUNTRY_CODE_VN (((UINT_16) 'V' << 8) | (UINT_16) 'N') /* Vietnam */ -+#define COUNTRY_CODE_VU (((UINT_16) 'V' << 8) | (UINT_16) 'U') /* Vanuatu */ -+#define COUNTRY_CODE_WS (((UINT_16) 'W' << 8) | (UINT_16) 'S') /* Samoa */ -+#define COUNTRY_CODE_YE (((UINT_16) 'Y' << 8) | (UINT_16) 'E') /* Yemen */ -+#define COUNTRY_CODE_YT (((UINT_16) 'Y' << 8) | (UINT_16) 'T') /* Mayotte (France) */ -+#define COUNTRY_CODE_ZA (((UINT_16) 'Z' << 8) | (UINT_16) 'A') /* South Africa */ -+#define COUNTRY_CODE_ZM (((UINT_16) 'Z' << 8) | (UINT_16) 'M') /* Zambia */ -+#define COUNTRY_CODE_ZW (((UINT_16) 'Z' << 8) | (UINT_16) 'W') /* Zimbabwe */ -+ -+#define COUNTRY_CODE_DF (((UINT_16) 'D' << 8) | (UINT_16) 'F') /* Default country domain */ -+#define COUNTRY_CODE_UDF (((UINT_16) 'U' << 8) | (UINT_16) 'D') /* User defined supported channel list -+ and passive scan channel list */ -+ -+#define COUNTRY_CODE_FF (((UINT_16) 'F' << 8) | (UINT_16) 'F') /* enable open for all channel for Certification */ -+#define COUNTRY_CODE_FE (((UINT_16) 'F' << 8) | (UINT_16) 'E') /* disable open for all channel for Certification */ -+ -+/* dot11RegDomainsSupportValue */ -+#define MIB_REG_DOMAIN_FCC 0x10 /* FCC (US) */ -+#define MIB_REG_DOMAIN_IC 0x20 /* IC or DOC (Canada) */ -+#define MIB_REG_DOMAIN_ETSI 0x30 /* ETSI (Europe) */ -+#define MIB_REG_DOMAIN_SPAIN 0x31 /* Spain */ -+#define MIB_REG_DOMAIN_FRANCE 0x32 /* France */ -+#define MIB_REG_DOMAIN_JAPAN 0x40 /* MPHPT (Japan) */ -+#define MIB_REG_DOMAIN_OTHER 0x00 /* other */ -+ -+/*2.4G*/ -+#define BAND_2G4_LOWER_BOUND 1 -+#define BAND_2G4_UPPER_BOUND 14 -+/*5G SubBand FCC spec*/ -+#define UNII1_LOWER_BOUND 36 -+#define UNII1_UPPER_BOUND 48 -+#define UNII2A_LOWER_BOUND 52 -+#define UNII2A_UPPER_BOUND 64 -+#define UNII2C_LOWER_BOUND 100 -+#define UNII2C_UPPER_BOUND 144 -+#define UNII3_LOWER_BOUND 149 -+#define UNII3_UPPER_BOUND 173 -+ -+#if CFG_SUPPORT_PWR_LIMIT_COUNTRY -+ -+#define POWER_LIMIT_TABLE_NULL 0xFFFF -+#define MAX_TX_POWER 63 -+#define MIN_TX_POWER -64 -+#define MAX_CMD_SUPPORT_CHANNEL_NUM 64 -+ -+#endif -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+#if CFG_SUPPORT_PWR_LIMIT_COUNTRY -+ -+typedef enum _ENUM_POWER_LIMIT_T { -+ PWR_LIMIT_CCK, -+ PWR_LIMIT_20M, -+ PWR_LIMIT_40M, -+ PWR_LIMIT_80M, -+ PWR_LIMIT_160M, -+ PWR_LIMIT_NUM -+} ENUM_POWER_LIMIT_T, *P_ENUM_POWER_LIMIT_T; -+ -+#endif -+ -+typedef enum _ENUM_POWER_LIMIT_SUBBAND_T { -+ POWER_LIMIT_2G4, -+ POWER_LIMIT_UNII1, -+ POWER_LIMIT_UNII2A, -+ POWER_LIMIT_UNII2C, -+ POWER_LIMIT_UNII3, -+ POWER_LIMIT_SUBAND_NUM -+} ENUM_POWER_LIMIT_SUBBAND_T, *P_ENUM_POWER_LIMIT_SUBBAND_T; -+ -+/* Define channel offset in unit of 5MHz bandwidth */ -+typedef enum _ENUM_CHNL_SPAN_T { -+ CHNL_SPAN_5 = 1, -+ CHNL_SPAN_10 = 2, -+ CHNL_SPAN_20 = 4, -+ CHNL_SPAN_40 = 8 -+} ENUM_CHNL_SPAN_T, *P_ENUM_CHNL_SPAN_T; -+ -+/* Define BSS operating bandwidth */ -+typedef enum _ENUM_CHNL_BW_T { -+ CHNL_BW_20, -+ CHNL_BW_20_40, -+ CHNL_BW_10, -+ CHNL_BW_5 -+} ENUM_CHNL_BW_T, *P_ENUM_CHNL_BW_T; -+ -+/* In all bands, the first channel will be SCA and the second channel is SCB, -+ * then iteratively. -+ * Note the final channel will not be SCA. -+ */ -+typedef struct _DOMAIN_SUBBAND_INFO { -+ /* Note1: regulation class depends on operation bandwidth and RF band. -+ * For example: 2.4GHz, 1~13, 20MHz ==> regulation class = 81 -+ * 2.4GHz, 1~13, SCA ==> regulation class = 83 -+ * 2.4GHz, 1~13, SCB ==> regulation class = 84 -+ * Note2: TX power limit is not specified here because path loss is unknown -+ */ -+ UINT_8 ucRegClass; /* Regulation class for 20MHz */ -+ UINT_8 ucBand; /* Type: ENUM_BAND_T */ -+ UINT_8 ucChannelSpan; /* Type: ENUM_CHNL_SPAN_T */ -+ UINT_8 ucFirstChannelNum; -+ UINT_8 ucNumChannels; -+ UINT_8 fgDfs; /* Type: BOOLEAN */ -+} DOMAIN_SUBBAND_INFO, *P_DOMAIN_SUBBAND_INFO; -+ -+/* Use it as all available channel list for STA */ -+typedef struct _DOMAIN_INFO_ENTRY { -+ PUINT_16 pu2CountryGroup; -+ UINT_32 u4CountryNum; -+ -+ /* If different attributes, put them into different rSubBands. -+ * For example, DFS shall be used or not. -+ */ -+ DOMAIN_SUBBAND_INFO rSubBand[MAX_SUBBAND_NUM]; -+} DOMAIN_INFO_ENTRY, *P_DOMAIN_INFO_ENTRY; -+ -+ -+#if CFG_SUPPORT_PWR_LIMIT_COUNTRY -+ -+typedef struct _CHANNEL_POWER_LIMIT { -+ UINT_8 ucCentralCh; -+ INT_8 cPwrLimitCCK; -+ INT_8 cPwrLimit20; -+ INT_8 cPwrLimit40; -+ INT_8 cPwrLimit80; -+ INT_8 cPwrLimit160; -+ UINT_8 ucFlag; -+ UINT_8 aucReserved[1]; -+} CHANNEL_POWER_LIMIT, *P_CHANNEL_POWER_LIMIT; -+ -+typedef struct _COUNTRY_CHANNEL_POWER_LIMIT { -+ UINT_8 aucCountryCode[2]; -+ UINT_8 ucCountryFlag; -+ UINT_8 ucChannelNum; -+ UINT_8 aucReserved[4]; -+ CHANNEL_POWER_LIMIT rChannelPowerLimit[80]; -+} COUNTRY_CHANNEL_POWER_LIMIT, *P_COUNTRY_CHANNEL_POWER_LIMIT; -+ -+#define CHANNEL_PWR_LIMIT(_channel, _pwrLimit_cck, _pwrLimit_bw20, \ -+ _pwrLimit_bw40, _pwrLimit_bw80, _pwrLimit_bw160, _ucFlag) \ -+ { \ -+ .ucCentralCh = (_channel), \ -+ .cPwrLimitCCK = (_pwrLimit_cck), \ -+ .cPwrLimit20 = (_pwrLimit_bw20), \ -+ .cPwrLimit40 = (_pwrLimit_bw40), \ -+ .cPwrLimit80 = (_pwrLimit_bw80), \ -+ .cPwrLimit160 = (_pwrLimit_bw160), \ -+ .ucFlag = (_ucFlag), \ -+ .aucReserved = {0} \ -+} -+ -+typedef struct _COUNTRY_POWER_LIMIT_TABLE_DEFAULT { -+ UINT_8 aucCountryCode[2]; -+ /* 0: ch 1 ~14 , 1: ch 36 ~48, 2: ch 52 ~64, 3: ch 100 ~144, 4: ch 149 ~165 */ -+ INT_8 aucPwrLimitSubBand[POWER_LIMIT_SUBAND_NUM]; -+ /* bit0: cPwrLimit2G4, bit1: cPwrLimitUnii1; bit2: cPwrLimitUnii2A; -+ * bit3: cPwrLimitUnii2C; bit4: cPwrLimitUnii3; mW: 0, mW\MHz : 1 */ -+ UINT_8 ucPwrUnit; -+} COUNTRY_POWER_LIMIT_TABLE_DEFAULT, *P_COUNTRY_POWER_LIMIT_TABLE_DEFAULT; -+ -+typedef struct _COUNTRY_POWER_LIMIT_TABLE_CONFIGURATION { -+ UINT_8 aucCountryCode[2]; -+ UINT_8 ucCentralCh; -+ INT_8 aucPwrLimit[PWR_LIMIT_NUM]; -+} COUNTRY_POWER_LIMIT_TABLE_CONFIGURATION, *P_COUNTRY_POWER_LIMIT_TABLE_CONFIGURATION; -+ -+typedef struct _SUBBAND_CHANNEL_T { -+ UINT_8 ucStartCh; -+ UINT_8 ucEndCh; -+ UINT_8 ucInterval; -+ UINT_8 ucReserved; -+} SUBBAND_CHANNEL_T, *P_SUBBAND_CHANNEL_T; -+ -+#endif -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+#define CAL_CH_OFFSET_80M(_PRIMARY_CH, _CENTRAL_CH) \ -+ (((_PRIMARY_CH - _CENTRAL_CH) + 6) >> 2) -+ -+#define CAL_CH_OFFSET_160M(_PRIMARY_CH, _CENTRAL_CH) \ -+ (((_PRIMARY_CH - _CENTRAL_CH) + 14) >> 2) -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+P_DOMAIN_INFO_ENTRY rlmDomainGetDomainInfo(P_ADAPTER_T prAdapter); -+ -+VOID -+rlmDomainGetChnlList(P_ADAPTER_T prAdapter, -+ ENUM_BAND_T eSpecificBand, BOOLEAN fgNoDfs, -+ UINT_8 ucMaxChannelNum, PUINT_8 pucNumOfChannel, P_RF_CHANNEL_INFO_T paucChannelList); -+ -+VOID rlmDomainSendCmd(P_ADAPTER_T prAdapter, BOOLEAN fgIsOid); -+ -+VOID rlmDomainSendDomainInfoCmd(P_ADAPTER_T prAdapter, BOOLEAN fgIsOid); -+ -+VOID rlmDomainSendPassiveScanInfoCmd(P_ADAPTER_T prAdapter, BOOLEAN fgIsOid); -+ -+BOOLEAN rlmDomainIsLegalChannel(P_ADAPTER_T prAdapter, ENUM_BAND_T eBand, UINT_8 ucChannel); -+ -+UINT_32 rlmDomainSupOperatingClassIeFill(PUINT_8 pBuf); -+ -+BOOLEAN rlmDomainCheckChannelEntryValid(P_ADAPTER_T prAdapter, UINT_8 ucCentralCh); -+ -+UINT_8 rlmDomainGetCenterChannel(ENUM_BAND_T eBand, UINT_8 ucPriChannel, ENUM_CHNL_EXT_T eExtend); -+ -+BOOLEAN rlmDomainIsValidRfSetting(P_ADAPTER_T prAdapter, ENUM_BAND_T eBand, -+ UINT_8 ucPriChannel, ENUM_CHNL_EXT_T eExtend, -+ ENUM_CHANNEL_WIDTH_T eChannelWidth, UINT_8 ucChannelS1, UINT_8 ucChannelS2); -+ -+#if CFG_SUPPORT_PWR_LIMIT_COUNTRY -+ -+BOOLEAN -+rlmDomainCheckPowerLimitValid(P_ADAPTER_T prAdapter, -+ COUNTRY_POWER_LIMIT_TABLE_CONFIGURATION rPowerLimitTableConfiguration, -+ UINT_8 ucPwrLimitNum); -+ -+VOID rlmDomainCheckCountryPowerLimitTable(P_ADAPTER_T prAdapter); -+ -+UINT_16 rlmDomainPwrLimitDefaultTableDecision(P_ADAPTER_T prAdapter, UINT_16 u2CountryCode); -+ -+VOID rlmDomainSendPwrLimitCmd(P_ADAPTER_T prAdapter); -+#endif -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif /* _RLM_DOMAIN_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rlm_obss.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rlm_obss.h -new file mode 100644 -index 000000000000..7f29dba4ce06 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rlm_obss.h -@@ -0,0 +1,150 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/mgmt/rlm_obss.h#1 -+*/ -+ -+/*! \file "rlm_obss.h" -+ \brief -+*/ -+ -+/* -+** Log: rlm_obss.h -+ * -+ * 01 24 2011 cm.chang -+ * [WCXRP00000384] [MT6620 Wi-Fi][Driver][FW] Handle 20/40 action frame in AP mode and stop -+ * ampdu timer when sta_rec is freed -+ * Process received 20/40 coexistence action frame for AP mode -+ * -+ * 01 13 2011 cm.chang -+ * [WCXRP00000358] [MT6620 Wi-Fi][Driver] Provide concurrent information for each module -+ * Refine function when rcv a 20/40M public action frame -+ * -+ * 01 12 2011 cm.chang -+ * [WCXRP00000354] [MT6620 Wi-Fi][Driver][FW] Follow NVRAM bandwidth setting -+ * User-defined bandwidth is for 2.4G and 5G individually -+ * -+ * 08 24 2010 cm.chang -+ * NULL -+ * Support RLM initail channel of Ad-hoc, P2P and BOW -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 28 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * 1st draft code for RLM module -+ * -+ * 05 07 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Process 20/40 coexistence public action frame in AP mode -+ * -+ * 05 05 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * First draft support for 20/40M bandwidth for AP mode -+ * -+ * 04 07 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Add virtual test for OBSS scan -+ * -+ * 03 30 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Support 2.4G OBSS scan -+ * -+ * 02 13 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Support PCO in STA mode -+ * -+ * 02 12 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Use bss info array for concurrent handle -+ * -+ * 01 25 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Support protection and bandwidth switch -+*/ -+ -+#ifndef _RLM_OBSS_H -+#define _RLM_OBSS_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+#define CHNL_LIST_SZ_2G 14 -+#define CHNL_LIST_SZ_5G 14 -+ -+#define CHNL_LEVEL0 0 -+#define CHNL_LEVEL1 1 -+#define CHNL_LEVEL2 2 -+ -+#define AFFECTED_CHNL_OFFSET 5 -+ -+#define OBSS_SCAN_MIN_INTERVAL 10 /* In unit of sec */ -+ -+#define PUBLIC_ACTION_MAX_LEN 200 /* In unit of byte */ -+ -+/* P2P GO only */ -+/* Define default OBSS Scan parameters (from MIB in spec.) */ -+#define dot11OBSSScanPassiveDwell 20 -+#define dot11OBSSScanActiveDwell 10 -+#define dot11OBSSScanPassiveTotalPerChannel 200 -+#define dot11OBSSScanActiveTotalPerChannel 20 -+#define dot11BSSWidthTriggerScanInterval 300 /* Unit: sec */ -+#define dot11BSSWidthChannelTransitionDelayFactor 5 -+#define dot11OBSSScanActivityThreshold 25 -+ -+#define OBSS_20_40M_TIMEOUT (dot11BSSWidthTriggerScanInterval + 10) -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/* Control MAC PCO function */ -+typedef enum _ENUM_SYS_PCO_PHASE_T { -+ SYS_PCO_PHASE_DISABLED = 0, -+ SYS_PCO_PHASE_20M, -+ SYS_PCO_PHASE_40M -+} ENUM_SYS_PCO_PHASE_T, *P_ENUM_SYS_PCO_PHASE_T; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+VOID rlmObssInit(P_ADAPTER_T prAdapter); -+ -+VOID rlmObssScanDone(P_ADAPTER_T prAdapter, P_MSG_HDR_T prMsgHdr); -+ -+VOID rlmObssTriggerScan(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo); -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif /* _RLM_OBSS_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rlm_protection.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rlm_protection.h -new file mode 100644 -index 000000000000..8665e48569ba ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rlm_protection.h -@@ -0,0 +1,122 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/mgmt/rlm_protection.h#1 -+*/ -+ -+/*! \file "rlm_protection.h" -+ \brief -+*/ -+ -+/* -+** Log: rlm_protection.h -+ * -+ * 08 20 2010 cm.chang -+ * NULL -+ * Migrate RLM code to host from FW -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 28 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * 1st draft code for RLM module -+ * -+ * 04 22 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * First draft code to support protection in AP mode -+ * -+ * 02 13 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Support PCO in STA mode -+ * -+ * 02 12 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Use bss info array for concurrent handle -+ * -+ * 01 25 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Support protection and bandwidth switch -+*/ -+ -+#ifndef _RLM_PROTECTION_H -+#define _RLM_PROTECTION_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+typedef enum _ENUM_SYS_PROTECT_MODE_T { -+ SYS_PROTECT_MODE_NONE = 0, /* Mode 0 */ -+ SYS_PROTECT_MODE_ERP, /* Mode 1 */ -+ SYS_PROTECT_MODE_NON_HT, /* Mode 2 */ -+ SYS_PROTECT_MODE_20M, /* Mode 3 */ -+ -+ SYS_PROTECT_MODE_NUM -+} ENUM_SYS_PROTECT_MODE_T, *P_ENUM_SYS_PROTECT_MODE_T; -+ -+/* This definition follows HT Protection field of HT Operation IE */ -+typedef enum _ENUM_HT_PROTECT_MODE_T { -+ HT_PROTECT_MODE_NONE = 0, -+ HT_PROTECT_MODE_NON_MEMBER, -+ HT_PROTECT_MODE_20M, -+ HT_PROTECT_MODE_NON_HT, -+ -+ HT_PROTECT_MODE_NUM -+} ENUM_HT_PROTECT_MODE_T, *P_ENUM_HT_PROTECT_MODE_T; -+ -+typedef enum _ENUM_GF_MODE_T { -+ GF_MODE_NORMAL = 0, -+ GF_MODE_PROTECT, -+ GF_MODE_DISALLOWED, -+ -+ GF_MODE_NUM -+} ENUM_GF_MODE_T, *P_ENUM_GF_MODE_T; -+ -+typedef enum _ENUM_RIFS_MODE_T { -+ RIFS_MODE_NORMAL = 0, -+ RIFS_MODE_DISALLOWED, -+ -+ RIFS_MODE_NUM -+} ENUM_RIFS_MODE_T, *P_ENUM_RIFS_MODE_T; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif /* _RLM_PROTECTION_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rlm_txpwr_init.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rlm_txpwr_init.h -new file mode 100644 -index 000000000000..d01c6e01e83f ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rlm_txpwr_init.h -@@ -0,0 +1,1213 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/mgmt/rlm_txpwr_init.h#1 -+*/ -+ -+/*! \file "rlm_txpwr_init.h" -+ \brief -+*/ -+ -+/* -+** Log: rlm_txpwr_init.h -+*/ -+ -+ -+#ifndef _RLM_TXPWR_INIT_H -+#define _RLM_TXPWR_INIT_H -+ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+/*Support Tx Power Range : 63~ -64 (unit : 0.5dBm)*/ -+ -+#define PWR_LIMIT_2G4_IN_MW_MHZ BIT(0) -+#define PWR_LIMIT_UNII1_IN_MW_MHZ BIT(1) -+#define PWR_LIMIT_UNII2A_IN_MW_MHZ BIT(2) -+#define PWR_LIMIT_UNII2C_IN_MW_MHZ BIT(3) -+#define PWR_LIMIT_UNII3_IN_MW_MHZ BIT(4) -+ -+#if CFG_SUPPORT_CE_FCC_TXPWR_LIMIT -+#define CE_FCC_TXPWR_LIMIT_CCK 30 /* 15 dBm */ -+#define CE_FCC_TXPWR_LIMIT_OFDM 20 /* 10 dBm */ -+#define CE_FCC_TXPWR_LIMIT_HT40 18 /* 9 dBm */ -+#endif -+ -+ -+#if CFG_SUPPORT_PWR_LIMIT_COUNTRY -+ -+COUNTRY_POWER_LIMIT_TABLE_DEFAULT g_rRlmPowerLimitDefault[] = { -+ -+ {{'A', 'O'} -+ , {40, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'B', 'Z'} -+ , {40, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'B', 'J'} -+ , {40, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'B', 'T'} -+ , {40, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'B', 'O'} -+ , {40, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'B', 'I'} -+ , {40, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'C', 'M'} -+ , {40, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'C', 'F'} -+ , {40, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'T', 'D'} -+ , {40, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'K', 'M'} -+ , {40, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'C', 'D'} -+ , {40, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'C', 'G'} -+ , {40, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'C', 'I'} -+ , {40, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'D', 'J'} -+ , {40, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'G', 'Q'} -+ , {40, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'E', 'R'} -+ , {40, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'F', 'J'} -+ , {40, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'G', 'A'} -+ , {40, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'G', 'M'} -+ , {40, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'G', 'N'} -+ , {40, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'G', 'W'} -+ , {40, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'R', 'K'} -+ , {40, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'K', 'G'} -+ , {40, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'L', 'Y'} -+ , {40, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'M', 'G'} -+ , {40, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'M', 'L'} -+ , {40, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'N', 'R'} -+ , {40, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'N', 'C'} -+ , {40, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'S', 'T'} -+ , {40, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'S', 'C'} -+ , {40, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'S', 'L'} -+ , {40, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'S', 'B'} -+ , {40, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'S', 'O'} -+ , {40, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'S', 'R'} -+ , {40, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'S', 'Z'} -+ , {40, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'T', 'J'} -+ , {40, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'T', 'G'} -+ , {40, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'T', 'O'} -+ , {40, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'T', 'M'} -+ , {40, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'T', 'V'} -+ , {40, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'V', 'U'} -+ , {40, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'Y', 'E'} -+ , {40, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'A', 'S'} -+ , {60, 34, 46, 48, 60} -+ , 0} -+ , -+ {{'A', 'I'} -+ , {60, 34, 48, 60, 60} -+ , 0} -+ , -+ {{'B', 'M'} -+ , {60, 34, 48, 48, 60} -+ , 0} -+ , -+ {{'C', 'A'} -+ , {60, 46, 48, 48, 60} -+ , 0} -+ , -+ {{'K', 'Y'} -+ , {60, 34, 48, 60, 60} -+ , 0} -+ , -+ {{'G', 'U'} -+ , {60, 34, 48, 48, 60} -+ , 0} -+ , -+ {{'F', 'M'} -+ , {60, 34, 48, 48, 60} -+ , 0} -+ , -+ {{'P', 'R'} -+ , {60, 34, 46, 48, 60} -+ , 0} -+ , -+ {{'U', 'S'} -+ , {60, 34, 48, 48, 60} -+ , 0} -+ , -+ {{'V', 'I'} -+ , {60, 34, 48, 48, 60} -+ , 0} -+ , -+ {{'A', 'R'} -+ , {60, 34, 48, 48, 60} -+ , 0} -+ , -+ {{'A', 'U'} -+ , {63, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'A', 'Z'} -+ , {40, 34, 48, 60, 60} -+ , 0} -+ , -+ {{'B', 'W'} -+ , {40, 46, 46, 60, 60} -+ , 0} -+ , -+ {{'K', 'H'} -+ , {40, 46, 46, 48, 60} -+ , 0} -+ , -+ {{'C', 'X'} -+ , {63, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'C', 'O'} -+ , {60, 34, 48, 48, 60} -+ , 0} -+ , -+ {{'C', 'R'} -+ , {60, 34, 48, 48, 60} -+ , 0} -+ , -+ {{'E', 'C'} -+ , {60, 34, 48, 48, 60} -+ , 0} -+ , -+ {{'G', 'D'} -+ , {40, 46, 46, 60, 60} -+ , 0} -+ , -+ {{'G', 'T'} -+ , {40, 34, 48, 48, 60} -+ , 0} -+ , -+ {{'H', 'K'} -+ , {63, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'K', 'I'} -+ , {63, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'L', 'B'} -+ , {40, 46, 46, 46, 46} -+ , 0} -+ , -+ {{'L', 'R'} -+ , {60, 46, 60, 63, 63} -+ , 0} -+ , -+ {{'M', 'N'} -+ , {46, 32, 46, 46, 58} -+ , 0} -+ , -+ {{'A', 'N'} -+ , {60, 34, 48, 48, 60} -+ , 0} -+ , -+ {{'N', 'Z'} -+ , {63, 46, 60, 48, 63} -+ , 0} -+ , -+ {{'N', 'I'} -+ , {60, 34, 48, 48, 60} -+ , 0} -+ , -+ {{'P', 'W'} -+ , {60, 60, 60, 60, 60} -+ , 0} -+ , -+ {{'P', 'Y'} -+ , {60, 46, 46, 48, 60} -+ , 0} -+ , -+ {{'P', 'E'} -+ , {54, 46, 48, 42, 48} -+ , 0} -+ , -+ {{'P', 'H'} -+ , {40, 46, 46, 48, 48} -+ , 0} -+ , -+ {{'W', 'S'} -+ , {40, 40, 40, 40, 60} -+ , 0} -+ , -+ {{'S', 'G'} -+ , {46, 46, 46, 60, 60} -+ , 0} -+ , -+ {{'L', 'K'} -+ , {46, 46, 46, 46, 46} -+ , 0} -+ , -+ {{'T', 'H'} -+ , {40, 46, 46, 60, 60} -+ , 0} -+ , -+ {{'T', 'T'} -+ , {60, 46, 46, 60, 60} -+ , 0} -+ , -+ {{'U', 'Y'} -+ , {63, 46, 46, 46, 46} -+ , 0} -+ , -+ {{'V', 'N'} -+ , {46, 46, 46, 60, 60} -+ , 0} -+ , -+ {{'A', 'W'} -+ , {60, 46, 60, 60, 63} -+ , 0} -+ , -+ {{'L', 'A'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'S', 'A'} -+ , {40, 46, 46, 60, 60} -+ , 0} -+ , -+ {{'A', 'E'} -+ , {40, 46, 46, 60, 46} -+ , 0} -+ , -+ {{'U', 'G'} -+ , {40, 46, 46, 48, 60} -+ , 0} -+ , -+ {{'M', 'M'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'A', 'L'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'D', 'Z'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'A', 'D'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'A', 'T'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'B', 'Y'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'B', 'E'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'B', 'A'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'V', 'G'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'B', 'G'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'C', 'V'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'H', 'R'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'C', 'Y'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'C', 'Z'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'D', 'K'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'E', 'E'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'E', 'T'} -+ , {40, 40, 40, 40, 63} -+ , 0} -+ , -+ {{'F', 'I'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'F', 'R'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'G', 'F'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'P', 'F'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'T', 'F'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'G', 'E'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'D', 'E'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'G', 'H'} -+ , {40, 34, 48, 60, 63} -+ , 0} -+ , -+ {{'G', 'R'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'G', 'P'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'H', 'U'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'I', 'S'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'I', 'Q'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'I', 'E'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'I', 'T'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'K', 'E'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'L', 'V'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'L', 'S'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'L', 'I'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'L', 'T'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'L', 'U'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'M', 'K'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'M', 'T'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'M', 'Q'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'M', 'R'} -+ , {40, 46, 46, 46, 63} -+ , 0} -+ , -+ {{'M', 'U'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'Y', 'T'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'M', 'D'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'M', 'C'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'M', 'E'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'M', 'S'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'N', 'L'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'N', 'O'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'O', 'M'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'P', 'L'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'P', 'T'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'R', 'E'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'R', 'O'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'M', 'F'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'S', 'M'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'S', 'N'} -+ , {40, 40, 40, 60, 63} -+ , 0} -+ , -+ {{'R', 'S'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'S', 'K'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'S', 'I'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'Z', 'A'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'E', 'S'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'S', 'E'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'C', 'H'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'T', 'R'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'T', 'C'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'G', 'B'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'V', 'A'} -+ , {40, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'A', 'M'} -+ , {40, 40, 40, 63, 63} -+ , 0} -+ , -+ {{'I', 'L'} -+ , {40, 46, 46, 63, 63} -+ , 0} -+ , -+ {{'K', 'W'} -+ , {40, 46, 46, 63, 63} -+ , 0} -+ , -+ {{'M', 'A'} -+ , {40, 46, 46, 63, 63} -+ , 0} -+ , -+ {{'N', 'E'} -+ , {40, 46, 46, 63, 63} -+ , 0} -+ , -+ {{'T', 'N'} -+ , {40, 46, 46, 63, 63} -+ , 0} -+ , -+ {{'E', 'H'} -+ , {40, 46, 46, 63, 63} -+ , 0} -+ , -+ {{'N', 'P'} -+ , {60, 46, 46, 63, 60} -+ , 0} -+ , -+ {{'A', 'F'} -+ , {40, 46, 63, 63, 63} -+ , 0} -+ , -+ {{'A', 'G'} -+ , {40, 46, 48, 63, 54} -+ , 0} -+ , -+ {{'B', 'S'} -+ , {63, 46, 60, 63, 63} -+ , 0} -+ , -+ {{'B', 'H'} -+ , {40, 46, 46, 63, 63} -+ , 0} -+ , -+ {{'B', 'B'} -+ , {40, 46, 48, 63, 54} -+ , 0} -+ , -+ {{'B', 'N'} -+ , {46, 46, 46, 63, 60} -+ , 0} -+ , -+ {{'C', 'L'} -+ , {40, 44, 44, 63, 44} -+ , 0} -+ , -+ {{'C', 'N'} -+ , {40, 46, 46, 63, 54} -+ , 0} -+ , -+ {{'E', 'G'} -+ , {40, 46, 46, 63, 46} -+ , 0} -+ , -+ {{'S', 'V'} -+ , {60, 34, 48, 63, 60} -+ , 0} -+ , -+ {{'I', 'N'} -+ , {60, 46, 46, 63, 60} -+ , 0} -+ , -+ {{'M', 'Y'} -+ , {54, 60, 60, 63, 60} -+ , 0} -+ , -+ {{'M', 'V'} -+ , {40, 46, 46, 63, 40} -+ , 0} -+ , -+ {{'P', 'A'} -+ , {60, 34, 48, 63, 60} -+ , 0} -+ , -+ {{'V', 'E'} -+ , {60, 46, 46, 63, 60} -+ , 0} -+ , -+ {{'Z', 'M'} -+ , {60, 46, 46, 63, 60} -+ , 0} -+ , -+ {{'J', 'O'} -+ , {40, 46, 63, 63, 46} -+ , 0} -+ , -+ {{'P', 'G'} -+ , {40, 46, 63, 63, 60} -+ , 0} -+ , -+ {{'B', 'F'} -+ , {40, 63, 63, 63, 60} -+ , 0} -+ , -+ {{'G', 'Y'} -+ , {60, 63, 63, 63, 60} -+ , 0} -+ , -+ {{'H', 'T'} -+ , {40, 63, 63, 63, 60} -+ , 0} -+ , -+ {{'H', 'N'} -+ , {60, 63, 63, 63, 60} -+ , 0} -+ , -+ {{'J', 'M'} -+ , {54, 63, 63, 63, 57} -+ , 0} -+ , -+ {{'M', 'O'} -+ , {40, 63, 63, 63, 40} -+ , 0} -+ , -+ {{'M', 'W'} -+ , {60, 63, 63, 63, 60} -+ , 0} -+ , -+ {{'P', 'K'} -+ , {40, 63, 63, 63, 40} -+ , 0} -+ , -+ {{'Q', 'A'} -+ , {40, 63, 63, 63, 40} -+ , 0} -+ , -+ {{'R', 'W'} -+ , {40, 63, 63, 63, 60} -+ , 0} -+ , -+ {{'K', 'N'} -+ , {40, 63, 63, 63, 60} -+ , 0} -+ , -+ {{'T', 'Z'} -+ , {40, 63, 63, 63, 40} -+ , 0} -+ , -+ {{'I', 'D'} -+ , {46, 63, 63, 63, 60} -+ , 0} -+ , -+ {{'N', 'G'} -+ , {40, 63, 46, 63, 60} -+ , 0} -+ , -+ {{'B', 'D'} -+ , {40, 46, 46, 60, 28} -+ , 0} -+ , -+ {{'B', 'R'} -+ , {52, 46, 46, 60, 60} -+ , 0} -+ , -+ {{'D', 'M'} -+ , {60, 34, 46, 48, 60} -+ , 0} -+ , -+ {{'D', 'O'} -+ , {63, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'F', 'K'} -+ , {40, 46, 46, 60, 28} -+ , 0} -+ , -+ {{'K', 'Z'} -+ , {40, 34, 48, 60, 60} -+ , 0} -+ , -+ {{'M', 'X'} -+ , {60, 34, 48, 60, 63} -+ , 0} -+ , -+ {{'M', 'Z'} -+ , {40, 34, 46, 48, 60} -+ , 0} -+ , -+ {{'N', 'A'} -+ , {40, 34, 46, 48, 60} -+ , 0} -+ , -+ {{'R', 'U'} -+ , {40, 34, 48, 60, 60} -+ , 0} -+ , -+ {{'L', 'C'} -+ , {40, 34, 48, 48, 60} -+ , 0} -+ , -+ {{'V', 'C'} -+ , {40, 34, 46, 48, 60} -+ , 0} -+ , -+ {{'U', 'A'} -+ , {40, 46, 46, 46, 48} -+ , 0} -+ , -+ {{'U', 'Z'} -+ , {40, 48, 48, 48, 60} -+ , 0} -+ , -+ {{'Z', 'W'} -+ , {40, 34, 46, 48, 60} -+ , 0} -+ , -+ {{'M', 'P'} -+ , {60, 34, 46, 48, 60} -+ , 0} -+ , -+ {{'T', 'W'} -+ , {60, 63, 34, 48, 60} -+ , 0} -+ , -+ {{'C', 'K'} -+ , {63, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'C', 'U'} -+ , {63, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'T', 'L'} -+ , {63, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'F', 'O'} -+ , {63, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'G', 'I'} -+ , {63, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'G', 'G'} -+ , {63, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'I', 'R'} -+ , {63, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'I', 'M'} -+ , {63, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'J', 'E'} -+ , {63, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'K', 'P'} -+ , {63, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'M', 'H'} -+ , {63, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'N', 'U'} -+ , {63, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'N', 'F'} -+ , {63, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'P', 'S'} -+ , {63, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'P', 'N'} -+ , {63, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'P', 'M'} -+ , {63, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'S', 'S'} -+ , {63, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'S', 'D'} -+ , {63, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'S', 'Y'} -+ , {63, 63, 63, 63, 63} -+ , 0} -+ , -+ {{'J', 'P'} -+ , {46, 46, 46, 60, 63} -+ , 0} -+ , -+ {{'K', 'R'} -+ , {46, 34, 46, 46, 46} -+ , PWR_LIMIT_UNII1_IN_MW_MHZ} -+ , -+ -+/*Default*/ -+ {{0, 0} -+ , {63, 63, 63, 63, 63} -+ , 0} -+}; -+ -+COUNTRY_POWER_LIMIT_TABLE_CONFIGURATION g_rRlmPowerLimitConfiguration[] = { -+ -+ {{'A', 'I'} -+ , 144, {48, 48, 48, 48, 48} -+ } -+ , -+ {{'A', 'Z'} -+ , 144, {48, 48, 48, 48, 48} -+ } -+ , -+ {{'B', 'W'} -+ , 144, {48, 48, 48, 48, 48} -+ } -+ , -+ {{'G', 'D'} -+ , 144, {48, 48, 48, 48, 48} -+ } -+ , -+ {{'L', 'B'} -+ , 144, {48, 48, 48, 48, 48} -+ } -+ , -+ {{'L', 'R'} -+ , 144, {48, 48, 48, 48, 48} -+ } -+ , -+ {{'W', 'S'} -+ , 165, {40, 40, 40, 40, 40} -+ } -+ , -+ {{'V', 'N'} -+ , 144, {48, 48, 48, 48, 48} -+ } -+ , -+ {{'U', 'S'} -+ , 1, {38, 30, 60, 60, 60} -+ } -+ , -+ {{'U', 'S'} -+ , 3, {60, 60, 26, 60, 60} -+ } -+ , -+ {{'U', 'S'} -+ , 9, {60, 60, 26, 60, 60} -+ } -+ , -+ {{'U', 'S'} -+ , 11, {38, 30, 60, 60, 60} -+ } -+ , -+ {{'U', 'S'} -+ , 36, {34, 34, 34, 34, 34} -+ } -+ , -+ {{'U', 'S'} -+ , 38, {34, 34, 34, 34, 34} -+ } -+ , -+ {{'U', 'S'} -+ , 42, {34, 34, 34, 31, 34} -+ } -+ , -+ {{'U', 'S'} -+ , 58, {48, 48, 48, 31, 48} -+ } -+ , -+ {{'U', 'S'} -+ , 62, {48, 48, 34, 48, 48} -+ } -+ , -+ {{'U', 'S'} -+ , 64, {37, 37, 48, 48, 48} -+ } -+ , -+ {{'U', 'S'} -+ , 100, {37, 37, 48, 48, 48} -+ } -+ , -+ {{'U', 'S'} -+ , 102, {48, 48, 34, 48, 48} -+ } -+ , -+ {{'U', 'S'} -+ , 106, {48, 48, 48, 31, 48} -+ } -+ , -+ {{'U', 'S'} -+ , 155, {60, 60, 60, 31, 60} -+ } -+ , -+ {{'U', 'S'} -+ , 159, {60, 60, 34, 60, 60} -+ } -+ , -+ {{'U', 'S'} -+ , 165, {37, 37, 60, 60, 60} -+ } -+ , -+ -+/*Default*/ -+ {{0, 0} -+ , 165, {63, 63, 63, 63, 63} -+ } -+}; -+ -+#if 0 -+COUNTRY_CHANNEL_POWER_LIMIT g_rRlmCountryPowerLimitTable[] = { -+ { -+ {'A', 'O'} -+ , 0, 0, {0, 0, 0, 0} -+ , -+ { -+ CHANNEL_PWR_LIMIT(1, 40, 40, 40, 40, 40, 0), -+ CHANNEL_PWR_LIMIT(2, 40, 40, 40, 40, 40, 0), -+ CHANNEL_PWR_LIMIT(3, 40, 40, 40, 40, 40, 0), -+ CHANNEL_PWR_LIMIT(4, 40, 40, 40, 40, 40, 0), -+ CHANNEL_PWR_LIMIT(5, 40, 40, 40, 40, 40, 0), -+ CHANNEL_PWR_LIMIT(6, 40, 40, 40, 40, 40, 0), -+ CHANNEL_PWR_LIMIT(7, 40, 40, 40, 40, 40, 0), -+ CHANNEL_PWR_LIMIT(8, 40, 40, 40, 40, 40, 0), -+ CHANNEL_PWR_LIMIT(9, 40, 40, 40, 40, 40, 0), -+ CHANNEL_PWR_LIMIT(10, 40, 40, 40, 40, 40, 0), -+ CHANNEL_PWR_LIMIT(11, 40, 40, 40, 40, 40, 0), -+ CHANNEL_PWR_LIMIT(12, 40, 40, 40, 40, 40, 0), -+ CHANNEL_PWR_LIMIT(13, 40, 40, 40, 40, 40, 0), -+ CHANNEL_PWR_LIMIT(14, 40, 40, 40, 40, 40, 0), -+ -+ CHANNEL_PWR_LIMIT(36, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(38, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(40, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(42, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(44, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(46, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(48, 63, 63, 63, 63, 63, 0), -+ -+ CHANNEL_PWR_LIMIT(52, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(54, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(56, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(58, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(60, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(62, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(64, 63, 63, 63, 63, 63, 0), -+ -+ CHANNEL_PWR_LIMIT(100, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(102, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(104, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(106, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(108, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(110, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(112, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(114, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(116, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(118, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(120, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(122, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(124, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(126, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(128, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(130, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(132, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(134, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(136, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(138, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(140, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(142, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(144, 63, 63, 63, 63, 63, 0), -+ -+ CHANNEL_PWR_LIMIT(149, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(151, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(153, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(155, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(157, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(159, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(161, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(163, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(165, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(167, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(169, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(171, 63, 63, 63, 63, 63, 0), -+ CHANNEL_PWR_LIMIT(173, 63, 63, 63, 63, 63, 0) -+ } -+ } -+ , -+ { -+ /*Used to check the end of country entry */ -+ {0, 0} -+ , 0, 0, {0, 0, 0, 0} -+ , -+ { -+ /*Used to check the end of channel power limit */ -+ CHANNEL_PWR_LIMIT(ENDCH, 0, 0, 0, 0, 0, 0) -+ } -+ } /*end of CountryTable */ -+}; -+#endif -+#endif -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+#endif /* _RLM_TXPWR_INIT_H */ -+ -+ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/roaming_fsm.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/roaming_fsm.h -new file mode 100644 -index 000000000000..0df4ec3e0828 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/roaming_fsm.h -@@ -0,0 +1,171 @@ -+/* -+** Id: -+*/ -+ -+/*! \file "roaming_fsm.h" -+ \brief This file defines the FSM for Roaming MODULE. -+ -+ This file defines the FSM for Roaming MODULE. -+*/ -+ -+/* -+** Log: roaming_fsm.h -+ * -+ * 08 31 2011 tsaiyuan.hsu -+ * [WCXRP00000931] [MT5931 Wi-Fi][DRV/FW] add swcr to disable roaming from driver -+ * remove obsolete code. -+ * -+ * 08 15 2011 tsaiyuan.hsu -+ * [WCXRP00000931] [MT5931 Wi-Fi][DRV/FW] add swcr to disable roaming from driver -+ * add swcr in driver reg, 0x9fxx0000, to disable roaming . -+ * -+ * 03 16 2011 tsaiyuan.hsu -+ * [WCXRP00000517] [MT6620 Wi-Fi][Driver][FW] Fine Tune Performance of Roaming -+ * remove obsolete definition and unused variables. -+ * -+ * 02 26 2011 tsaiyuan.hsu -+ * [WCXRP00000391] [MT6620 Wi-Fi][FW] Add Roaming Support -+ * not send disassoc or deauth to leaving AP so as to improve performace of roaming. -+ * -+ * 01 27 2011 tsaiyuan.hsu -+ * [WCXRP00000392] [MT6620 Wi-Fi][Driver] Add Roaming Support -+ * add roaming fsm -+ * 1. not support 11r, only use strength of signal to determine roaming. -+ * 2. not enable CFG_SUPPORT_ROAMING until completion of full test. -+ * 3. in 6620, adopt work-around to avoid sign extension problem of cck of hw -+ * 4. assume that change of link quality in smooth way. -+ * -+ * 01 27 2011 tsaiyuan.hsu -+ * [WCXRP00000392] [MT6620 Wi-Fi][Driver] Add Roaming Support -+ * add roaming fsm -+ * 1. not support 11r, only use strength of signal to determine roaming. -+ * 2. not enable CFG_SUPPORT_ROAMING until completion of full test. -+ * 3. in 6620, adopt work-around to avoid sign extension problem of cck of hw -+ * 4. assume that change of link quality in smooth way. -+ * -+*/ -+ -+#ifndef _ROAMING_FSM_H -+#define _ROAMING_FSM_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+/* Roaming Discovery interval, SCAN result need to be updated */ -+#define ROAMING_DISCOVERY_TIMEOUT_SEC 5 /* Seconds. */ -+ -+/* #define ROAMING_NO_SWING_RCPI_STEP 5 //rcpi */ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+typedef enum _ENUM_ROAMING_FAIL_REASON_T { -+ ROAMING_FAIL_REASON_CONNLIMIT = 0, -+ ROAMING_FAIL_REASON_NOCANDIDATE, -+ ROAMING_FAIL_REASON_NUM -+} ENUM_ROAMING_FAIL_REASON_T; -+ -+/* events of roaming between driver and firmware */ -+typedef enum _ENUM_ROAMING_EVENT_T { -+ ROAMING_EVENT_START = 0, -+ ROAMING_EVENT_DISCOVERY, -+ ROAMING_EVENT_ROAM, -+ ROAMING_EVENT_FAIL, -+ ROAMING_EVENT_ABORT, -+ ROAMING_EVENT_NUM -+} ENUM_ROAMING_EVENT_T; -+ -+#define ROAMING_EVENT_REASON_TX_ERR BIT(0) -+#define ROAMING_EVENT_REASON_RCPI BIT(1) -+ -+typedef struct _ROAMING_PARAM_T { -+ UINT_16 u2Event; -+ UINT_16 u2Data; -+ UINT_16 u2Reason; -+} ROAMING_PARAM_T, *P_ROAMING_PARAM_T; -+ -+ /**/ typedef enum _ENUM_ROAMING_STATE_T { -+ ROAMING_STATE_IDLE = 0, -+ ROAMING_STATE_DECISION, -+ ROAMING_STATE_DISCOVERY, -+ ROAMING_STATE_ROAM, -+ ROAMING_STATE_NUM -+} ENUM_ROAMING_STATE_T; -+ -+typedef struct _ROAMING_INFO_T { -+ BOOLEAN fgIsEnableRoaming; -+ -+ ENUM_ROAMING_STATE_T eCurrentState; -+ -+ OS_SYSTIME rRoamingDiscoveryUpdateTime; -+ -+#define ROAMING_ENTRY_TIMEOUT_SKIP_COUNT_MAX 2 -+ UINT_32 RoamingEntryTimeoutSkipCount; -+ -+} ROAMING_INFO_T, *P_ROAMING_INFO_T; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+#if CFG_SUPPORT_ROAMING -+#define IS_ROAMING_ACTIVE(prAdapter) \ -+ (prAdapter->rWifiVar.rRoamingInfo.eCurrentState == ROAMING_STATE_ROAM) -+#else -+#define IS_ROAMING_ACTIVE(prAdapter) FALSE -+#endif /* CFG_SUPPORT_ROAMING */ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+VOID roamingFsmInit(IN P_ADAPTER_T prAdapter); -+ -+VOID roamingFsmUninit(IN P_ADAPTER_T prAdapter); -+ -+VOID roamingFsmSendCmd(IN P_ADAPTER_T prAdapter, IN P_ROAMING_PARAM_T prParam); -+ -+VOID roamingFsmScanResultsUpdate(IN P_ADAPTER_T prAdapter); -+ -+VOID roamingFsmSteps(IN P_ADAPTER_T prAdapter, IN ENUM_ROAMING_STATE_T eNextState); -+ -+VOID roamingFsmRunEventStart(IN P_ADAPTER_T prAdapter); -+ -+VOID roamingFsmRunEventDiscovery(IN P_ADAPTER_T prAdapter, IN P_ROAMING_PARAM_T prParam); -+ -+VOID roamingFsmRunEventRoam(IN P_ADAPTER_T prAdapter); -+ -+VOID roamingFsmRunEventFail(IN P_ADAPTER_T prAdapter, IN UINT_32 u4Reason); -+ -+VOID roamingFsmRunEventAbort(IN P_ADAPTER_T prAdapter); -+ -+WLAN_STATUS roamingFsmProcessEvent(IN P_ADAPTER_T prAdapter, IN P_ROAMING_PARAM_T prParam); -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif /* _ROAMING_FSM_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rsn.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rsn.h -new file mode 100644 -index 000000000000..20ab14251f65 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/rsn.h -@@ -0,0 +1,271 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/mgmt/rsn.h#1 -+*/ -+ -+/*! \file rsn.h -+ \brief The wpa/rsn related define, macro and structure are described here. -+*/ -+ -+/* -+** Log: rsn.h -+ * -+ * 10 12 2011 wh.su -+ * [WCXRP00001036] [MT6620 Wi-Fi][Driver][FW] Adding the 802.11w code for MFP -+ * adding the 802.11w related function and define . -+ * -+ * 06 22 2011 wh.su -+ * [WCXRP00000806] [MT6620 Wi-Fi][Driver] Move the WPA/RSN IE and WAPI IE structure to mac.h -+ * and let the sw structure not align at byte -+ * Move the WAPI/RSN IE to mac.h and SW structure not align to byte, -+ * Notice needed update P2P.ko. -+ * -+ * 03 17 2011 chinglan.wang -+ * [WCXRP00000570] [MT6620 Wi-Fi][Driver] Add Wi-Fi Protected Setup v2.0 feature -+ * . -+ * -+ * 02 09 2011 wh.su -+ * [WCXRP00000432] [MT6620 Wi-Fi][Driver] Add STA privacy check at hotspot mode -+ * adding the code for check STA privacy bit at AP mode, . -+ * -+ * 11 05 2010 wh.su -+ * [WCXRP00000165] [MT6620 Wi-Fi] [Pre-authentication] Assoc req rsn ie use wrong pmkid value -+ * fixed the.pmkid value mismatch issue -+ * -+ * 10 04 2010 wh.su -+ * [WCXRP00000081] [MT6620][Driver] Fix the compiling error at WinXP while enable P2P -+ * add a kal function for set cipher. -+ * -+ * 09 01 2010 wh.su -+ * NULL -+ * adding the wapi support for integration test. -+ * -+ * 08 30 2010 wh.su -+ * NULL -+ * remove non-used code. -+ * -+ * 08 19 2010 wh.su -+ * NULL -+ * adding the tx pkt call back handle for countermeasure. -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 18 2010 wh.su -+ * [WPD00003840][MT6620 5931] Security migration -+ * migration from MT6620 firmware. -+ * -+ * 03 03 2010 wh.su -+ * [BORA00000637][MT6620 Wi-Fi] [Bug] WPA2 pre-authentication timer not correctly initialize -+ * Fixed the pre-authentication timer not correctly init issue, and modify -+ * the security related callback function prototype. -+ * -+ * 01 27 2010 wh.su -+ * [BORA00000476][Wi-Fi][firmware] Add the security module initialize code -+ * add and fixed some security function. -+ * -+ * Dec 4 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * adjust the function prototype for generate wap/rsn ie -+ * -+ * Dec 3 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * adjust the function input parameter -+ * -+ * Dec 1 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * adding some event function declaration -+ * -+ * Nov 26 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * move the internal data structure for pmkid to rsn.h -+ * -+ * Nov 23 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * adding the port control and class error function -+ * -+ * Nov 19 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * adding the pmkid candidate -+ * -+ * Nov 18 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * -+** -+*/ -+ -+#ifndef _RSN_H -+#define _RSN_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+/* ----- Definitions for Cipher Suite Selectors ----- */ -+#define RSN_CIPHER_SUITE_USE_GROUP_KEY 0x00AC0F00 -+#define RSN_CIPHER_SUITE_WEP40 0x01AC0F00 -+#define RSN_CIPHER_SUITE_TKIP 0x02AC0F00 -+#define RSN_CIPHER_SUITE_CCMP 0x04AC0F00 -+#define RSN_CIPHER_SUITE_WEP104 0x05AC0F00 -+#if CFG_SUPPORT_802_11W -+#define RSN_CIPHER_SUITE_AES_128_CMAC 0x06AC0F00 -+#endif -+ -+#define WPA_CIPHER_SUITE_NONE 0x00F25000 -+#define WPA_CIPHER_SUITE_WEP40 0x01F25000 -+#define WPA_CIPHER_SUITE_TKIP 0x02F25000 -+#define WPA_CIPHER_SUITE_CCMP 0x04F25000 -+#define WPA_CIPHER_SUITE_WEP104 0x05F25000 -+ -+/* ----- Definitions for Authentication and Key Management Suite Selectors ----- */ -+#define RSN_AKM_SUITE_NONE 0x00AC0F00 -+#define RSN_AKM_SUITE_802_1X 0x01AC0F00 -+#define RSN_AKM_SUITE_PSK 0x02AC0F00 -+#if CFG_SUPPORT_802_11W -+#define RSN_AKM_SUITE_802_1X_SHA256 0x05AC0F00 -+#define RSN_AKM_SUITE_PSK_SHA256 0x06AC0F00 -+#endif -+ -+#define WPA_AKM_SUITE_NONE 0x00F25000 -+#define WPA_AKM_SUITE_802_1X 0x01F25000 -+#define WPA_AKM_SUITE_PSK 0x02F25000 -+ -+#define ELEM_ID_RSN_LEN_FIXED 20 /* The RSN IE len for associate request */ -+ -+#define ELEM_ID_WPA_LEN_FIXED 22 /* The RSN IE len for associate request */ -+ -+#define MASK_RSNIE_CAP_PREAUTH BIT(0) -+ -+#define GET_SELECTOR_TYPE(x) ((UINT_8)(((x) >> 24) & 0x000000FF)) -+#define SET_SELECTOR_TYPE(x, y) {x = (((x) & 0x00FFFFFF) | (((UINT_32)(y) << 24) & 0xFF000000))} -+ -+#define AUTH_CIPHER_CCMP 0x00000008 -+ -+/* Cihpher suite flags */ -+#define CIPHER_FLAG_NONE 0x00000000 -+#define CIPHER_FLAG_WEP40 0x00000001 /* BIT 1 */ -+#define CIPHER_FLAG_TKIP 0x00000002 /* BIT 2 */ -+#define CIPHER_FLAG_CCMP 0x00000008 /* BIT 4 */ -+#define CIPHER_FLAG_WEP104 0x00000010 /* BIT 5 */ -+#define CIPHER_FLAG_WEP128 0x00000020 /* BIT 6 */ -+ -+#define WAIT_TIME_IND_PMKID_CANDICATE_SEC 6 /* seconds */ -+#define TKIP_COUNTERMEASURE_SEC 60 /* seconds */ -+ -+#if CFG_SUPPORT_802_11W -+#define RSN_AUTH_MFP_DISABLED 0 /* MFP disabled */ -+#define RSN_AUTH_MFP_OPTIONAL 1 /* MFP optional */ -+#define RSN_AUTH_MFP_REQUIRED 2 /* MFP required */ -+#endif -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/* Flags for PMKID Candidate list structure */ -+#define EVENT_PMKID_CANDIDATE_PREAUTH_ENABLED 0x01 -+ -+#define CONTROL_FLAG_UC_MGMT_NO_ENC BIT(5) -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+#define RSN_IE(fp) ((P_RSN_INFO_ELEM_T) fp) -+#define WPA_IE(fp) ((P_WPA_INFO_ELEM_T) fp) -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+BOOLEAN rsnParseRsnIE(IN P_ADAPTER_T prAdapter, IN P_RSN_INFO_ELEM_T prInfoElem, OUT P_RSN_INFO_T prRsnInfo); -+ -+BOOLEAN rsnParseWpaIE(IN P_ADAPTER_T prAdapter, IN P_WPA_INFO_ELEM_T prInfoElem, OUT P_RSN_INFO_T prWpaInfo); -+ -+BOOLEAN rsnSearchSupportedCipher(IN P_ADAPTER_T prAdapter, IN UINT_32 u4Cipher, OUT PUINT_32 pu4Index); -+ -+BOOLEAN rsnSearchAKMSuite(IN P_ADAPTER_T prAdapter, IN UINT_32 u4AkmSuite, OUT PUINT_32 pu4Index); -+ -+BOOLEAN rsnPerformPolicySelection(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBss); -+ -+VOID rsnGenerateWpaNoneIE(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); -+ -+VOID rsnGenerateWPAIE(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); -+ -+VOID rsnGenerateRSNIE(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); -+ -+BOOLEAN -+rsnParseCheckForWFAInfoElem(IN P_ADAPTER_T prAdapter, -+ IN PUINT_8 pucBuf, OUT PUINT_8 pucOuiType, OUT PUINT_16 pu2SubTypeVersion); -+ -+BOOLEAN rsnIsSuitableBSS(IN P_ADAPTER_T prAdapter, IN P_RSN_INFO_T prBssRsnInfo); -+ -+#if CFG_SUPPORT_AAA -+void rsnParserCheckForRSNCCMPPSK(P_ADAPTER_T prAdapter, P_RSN_INFO_ELEM_T prIe, PUINT_16 pu2StatusCode); -+#endif -+ -+VOID rsnTkipHandleMICFailure(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta, IN BOOLEAN fgErrorKeyType); -+ -+VOID rsnSelectPmkidCandidateList(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBssDesc); -+ -+VOID rsnUpdatePmkidCandidateList(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBssDesc); -+ -+BOOLEAN rsnSearchPmkidEntry(IN P_ADAPTER_T prAdapter, IN PUINT_8 pucBssid, OUT PUINT_32 pu4EntryIndex); -+ -+BOOLEAN rsnCheckPmkidCandicate(IN P_ADAPTER_T prAdapter); -+ -+VOID rsnCheckPmkidCache(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBss); -+ -+VOID rsnGeneratePmkidIndication(IN P_ADAPTER_T prAdapter); -+ -+VOID rsnIndicatePmkidCand(IN P_ADAPTER_T prAdapter, IN ULONG ulParm); -+#if CFG_SUPPORT_WPS2 -+VOID rsnGenerateWSCIE(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); -+#endif -+ -+#if CFG_SUPPORT_802_11W -+UINT_32 rsnCheckBipKeyInstalled(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec); -+ -+UINT_8 rsnCheckSaQueryTimeout(IN P_ADAPTER_T prAdapter); -+ -+void rsnStartSaQueryTimer(IN P_ADAPTER_T prAdapter); -+ -+void rsnStartSaQuery(IN P_ADAPTER_T prAdapter); -+ -+void rsnStopSaQuery(IN P_ADAPTER_T prAdapter); -+ -+void rsnSaQueryRequest(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); -+ -+void rsnSaQueryAction(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); -+ -+BOOLEAN rsnCheckRxMgmt(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, IN UINT_8 ucSubtype); -+#endif -+BOOLEAN rsnCheckSecurityModeChanged(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo, P_BSS_DESC_T prBssDesc); -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif /* _RSN_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/scan.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/scan.h -new file mode 100644 -index 000000000000..c08b2244be6c ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/scan.h -@@ -0,0 +1,988 @@ -+/* -+** Id: @(#) -+*/ -+ -+/*! \file "scan.h" -+ \brief -+ -+*/ -+ -+/* -+** Log: scan.h -+ * -+ * 01 16 2012 cp.wu -+ * [MT6620 Wi-Fi][Driver] API and behavior modification for preferred band configuration -+ * with corresponding network configuration -+ * add wlanSetPreferBandByNetwork() for glue layer to invoke for setting -+ * preferred band configuration corresponding to network type. -+ * -+ * 08 11 2011 cp.wu -+ * [WCXRP00000830] [MT6620 Wi-Fi][Firmware] Use MDRDY counter to detect empty channel for shortening scan time -+ * sparse channel detection: -+ * driver: collect sparse channel information with scan-done event -+ * -+ * 07 18 2011 cp.wu -+ * [WCXRP00000858] [MT5931][Driver][Firmware] Add support for scan to search for more than one SSID -+ * in a single scanning request -+ * add framework in driver domain for supporting new SCAN_REQ_V2 for more than 1 SSID -+ * support as well as uProbeDelay in NDIS 6.x driver model -+ * -+ * 06 27 2011 cp.wu -+ * [WCXRP00000815] [MT6620 Wi-Fi][Driver] allow single BSSID with multiple SSID settings -+ * to work around some tricky AP which use space character as hidden SSID -+ * allow to have a single BSSID with multiple SSID to be presented in scanning result -+ * -+ * 04 18 2011 terry.wu -+ * [WCXRP00000660] [MT6620 Wi-Fi][Driver] Remove flag CFG_WIFI_DIRECT_MOVED -+ * Remove flag CFG_WIFI_DIRECT_MOVED. -+ * -+ * 02 09 2011 wh.su -+ * [WCXRP00000433] [MT6620 Wi-Fi][Driver] Remove WAPI structure define for avoid P2P module -+ * with structure miss-align pointer issue -+ * always pre-allio WAPI related structure for align p2p module. -+ * -+ * 01 14 2011 yuche.tsai -+ * [WCXRP00000352] [Volunteer Patch][MT6620][Driver] P2P Statsion Record Client List Issue -+ * Fix compile error. -+ * -+ * 09 08 2010 cp.wu -+ * NULL -+ * use static memory pool for storing IEs of scanning result. -+ * -+ * 09 03 2010 kevin.huang -+ * NULL -+ * Refine #include sequence and solve recursive/nested #include issue -+ * -+ * 08 31 2010 kevin.huang -+ * NULL -+ * Use LINK LIST operation to process SCAN result -+ * -+ * 08 30 2010 cp.wu -+ * NULL -+ * eliminate klockwork errors -+ * -+ * 08 16 2010 cp.wu -+ * NULL -+ * add interface for RLM to trigger OBSS-SCAN. -+ * -+ * 08 12 2010 yuche.tsai -+ * NULL -+ * Add a functio prototype to find p2p descriptor of a bss descriptor directly. -+ * -+ * 08 11 2010 yuche.tsai -+ * NULL -+ * Add function prototype for return channel. -+ * modify data structure for scan specific device ID or TYPE. (Move from P2P Connection Settings to Scan Param) -+ * -+ * 08 05 2010 yuche.tsai -+ * NULL -+ * Check-in P2P Device Discovery Feature. -+ * -+ * 08 02 2010 yuche.tsai -+ * NULL -+ * P2P Group Negotiation Code Check in. -+ * -+ * 07 26 2010 yuche.tsai -+ * -+ * Add a option for channel time extension in scan abort command. -+ * -+ * 07 21 2010 yuche.tsai -+ * -+ * Add for P2P Scan Result Parsing & Saving. -+ * -+ * 07 19 2010 yuche.tsai -+ * -+ * Scan status "FIND" is used for P2P FSM find state. -+ * -+ * 07 19 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration. -+ * SCN module is now able to handle multiple concurrent scanning requests -+ * -+ * 07 14 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration. -+ * pass band with channel number information as scan parameter -+ * -+ * 07 14 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration. -+ * remove timer in DRV-SCN. -+ * -+ * 07 09 2010 cp.wu -+ * -+ * 1) separate AIS_FSM state for two kinds of scanning. (OID triggered scan, and scan-for-connection) -+ * 2) eliminate PRE_BSS_DESC_T, Beacon/PrebResp is now parsed in single pass -+ * 3) implment DRV-SCN module, currently only accepts single scan request, other request -+ * will be directly dropped by returning BUSY -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 07 01 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add scan uninitialization procedure -+ * -+ * 07 01 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * implementation of DRV-SCN and related mailbox message handling. -+ * -+ * 06 25 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * modify Beacon/ProbeResp to complete parsing, -+ * because host software has looser memory usage restriction -+ * -+ * 06 17 2010 yuche.tsai -+ * [WPD00003839][MT6620 5931][P2P] Feature migration -+ * Add P2P related field in SCAN_PARAM_T. -+ * -+ * 06 14 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * saa_fsm.c is migrated. -+ * -+ * 06 14 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add management dispatching function table. -+ * -+ * 06 14 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * restore utility function invoking via hem_mbox to direct calls -+ * -+ * 06 11 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * auth.c is migrated. -+ * -+ * 06 10 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add buildable & linkable ais_fsm.c -+ * -+ * related reference are still waiting to be resolved -+ * -+ * 06 07 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add aa_fsm.h, ais_fsm.h, bss.h, mib.h and scan.h. -+ * -+ * 05 12 2010 kevin.huang -+ * [BORA00000794][WIFISYS][New Feature]Power Management Support -+ * Add Power Management - Legacy PS-POLL support. -+ * -+ * 04 13 2010 kevin.huang -+ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support -+ * -+ * Add new HW CH macro support -+ * -+ * 03 16 2010 kevin.huang -+ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support -+ * Add AdHoc Mode -+ * -+ * 03 10 2010 kevin.huang -+ * [BORA00000654][WIFISYS][New Feature] CNM Module - Ch Manager Support -+ * -+ * * * * * * Add Channel Manager for arbitration of JOIN and SCAN Req -+ * -+ * 02 26 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Modify scanBuildProbeReqFrameCommonIEs() to support P2P SCAN -+ * -+ * 02 23 2010 wh.su -+ * [BORA00000592][MT6620 Wi-Fi] Adding the security related code for driver -+ * refine the scan procedure, reduce the WPA and WAPI IE parsing, and move the parsing to the time for join. -+ * -+ * 02 23 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Add support scan channel 1~14 and update scan result's frequency infou1rwduu`wvpghlqg|n`slk+mpdkb -+ * -+ * 02 04 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Add AAA Module Support, Revise Net Type to Net Type Index for array lookup -+ * -+ * 01 27 2010 wh.su -+ * [BORA00000476][Wi-Fi][firmware] Add the security module initialize code -+ * add and fixed some security function. -+ * -+ * 01 07 2010 kevin.huang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * -+ * Simplify the process of Beacon during SCAN and remove redundant variable in PRE_BSS_DESC_T -+ * -+ * Dec 7 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * adding variable for wapi ap -+ * -+ * Dec 4 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * remove non-used secuirty variavle -+ * -+ * Dec 3 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Refine data structure of BSS_DESC_T and PRE_BSS_DESC_T -+ * -+ * Nov 24 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Add eNetType to rScanParam and revise MGMT Handler with Retain Status -+ * -+ * Nov 23 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Add ucAvailablePhyTypeSet to BSS_DESC_T -+ * -+ * Nov 20 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Add aucSrcAddress to SCAN_PARAM_T for P2P's Device Address -+ * -+ * Nov 19 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * adding the security related variable -+ * -+ * Nov 18 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * adding the security ie filed for scan parsing -+ * -+ * Nov 16 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Add scanSearchBssDescByPolicy() -+ * -+ * Nov 5 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Add function declarations of scan_fsm.c -+ * -+ * Oct 30 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Add scan.h to source control -+** -+*/ -+ -+#ifndef _SCAN_H -+#define _SCAN_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+#include "gl_vendor.h" -+ -+/* TDLS test purpose */ -+extern BOOLEAN flgTdlsTestExtCapElm; -+extern UINT8 aucTdlsTestExtCapElm[]; -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+/*! Maximum buffer size of SCAN list */ -+#define SCN_MAX_BUFFER_SIZE (CFG_MAX_NUM_BSS_LIST * ALIGN_4(sizeof(BSS_DESC_T))) -+ -+#define SCN_RM_POLICY_EXCLUDE_CONNECTED BIT(0) /* Remove SCAN result except the connected one. */ -+#define SCN_RM_POLICY_TIMEOUT BIT(1) /* Remove the timeout one */ -+#define SCN_RM_POLICY_OLDEST_HIDDEN BIT(2) /* Remove the oldest one with hidden ssid */ -+#define SCN_RM_POLICY_SMART_WEAKEST BIT(3) /* If there are more than half BSS which has the -+ * same ssid as connection setting, remove the -+ * weakest one from them -+ * Else remove the weakest one. -+ */ -+#define SCN_RM_POLICY_ENTIRE BIT(4) /* Remove entire SCAN result */ -+ -+#define SCN_BSS_DESC_SAME_SSID_THRESHOLD 3 /* This is used by POLICY SMART WEAKEST, -+ * If exceed this value, remove weakest BSS_DESC_T -+ * with same SSID first in large network. -+ */ -+ -+/* the scan time in WFD mode + 2.4G/5G is about 9s so we need to enlarge the value */ -+#define SCN_BSS_DESC_REMOVE_TIMEOUT_SEC 15 /* Second. */ -+ /* This is used by POLICY TIMEOUT, -+ * If exceed this value, remove timeout BSS_DESC_T. -+ */ -+ -+#define SCN_PROBE_DELAY_MSEC 0 -+ -+#define SCN_ADHOC_BSS_DESC_TIMEOUT_SEC 5 /* Second. */ -+ -+#define SCN_NLO_NETWORK_CHANNEL_NUM (4) -+ -+/*----------------------------------------------------------------------------*/ -+/* MSG_SCN_SCAN_REQ */ -+/*----------------------------------------------------------------------------*/ -+#define SCAN_REQ_SSID_WILDCARD BIT(0) -+#define SCAN_REQ_SSID_P2P_WILDCARD BIT(1) -+#define SCAN_REQ_SSID_SPECIFIED BIT(2) -+ -+/*----------------------------------------------------------------------------*/ -+/* Support Multiple SSID SCAN */ -+/*----------------------------------------------------------------------------*/ -+#define SCN_SSID_MAX_NUM CFG_SCAN_SSID_MAX_NUM -+#define SCN_SSID_MATCH_MAX_NUM CFG_SCAN_SSID_MATCH_MAX_NUM -+ -+#define SWC_NUM_BSSID_THRESHOLD_DEFAULT 8 -+#define SWC_RSSI_WINDSIZE_DEFAULT 8 -+#define LOST_AP_WINDOW 16 -+#define MAX_CHANNEL_NUM_PER_BUCKETS 8 -+ -+#define SCN_BSS_JOIN_FAIL_THRESOLD 4 -+#define SCN_BSS_JOIN_FAIL_CNT_RESET_SEC 15 -+#define SCN_BSS_JOIN_FAIL_RESET_STEP 2 -+ -+#if CFG_SUPPORT_BATCH_SCAN -+/*----------------------------------------------------------------------------*/ -+/* SCAN_BATCH_REQ */ -+/*----------------------------------------------------------------------------*/ -+#define SCAN_BATCH_REQ_START BIT(0) -+#define SCAN_BATCH_REQ_STOP BIT(1) -+#define SCAN_BATCH_REQ_RESULT BIT(2) -+#endif -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+typedef enum _ENUM_SCAN_TYPE_T { -+ SCAN_TYPE_PASSIVE_SCAN = 0, -+ SCAN_TYPE_ACTIVE_SCAN, -+ SCAN_TYPE_NUM -+} ENUM_SCAN_TYPE_T, *P_ENUM_SCAN_TYPE_T; -+ -+typedef enum _ENUM_SCAN_STATE_T { -+ SCAN_STATE_IDLE = 0, -+ SCAN_STATE_SCANNING, -+ SCAN_STATE_NUM -+} ENUM_SCAN_STATE_T; -+ -+typedef enum _ENUM_SCAN_CHANNEL_T { -+ SCAN_CHANNEL_FULL = 0, -+ SCAN_CHANNEL_2G4, -+ SCAN_CHANNEL_5G, -+ SCAN_CHANNEL_P2P_SOCIAL, -+ SCAN_CHANNEL_SPECIFIED, -+ SCAN_CHANNEL_NUM -+} ENUM_SCAN_CHANNEL, *P_ENUM_SCAN_CHANNEL; -+ -+typedef struct _MSG_SCN_FSM_T { -+ MSG_HDR_T rMsgHdr; /* Must be the first member */ -+ UINT_32 u4Dummy; -+} MSG_SCN_FSM_T, *P_MSG_SCN_FSM_T; -+ -+typedef enum _ENUM_PSCAN_STATE_T { -+ PSCN_IDLE = 1, -+ PSCN_SCANNING, -+ PSCN_RESET, -+ PSCAN_STATE_T_NUM -+} ENUM_PSCAN_STATE_T; -+ -+/*----------------------------------------------------------------------------*/ -+/* BSS Descriptors */ -+/*----------------------------------------------------------------------------*/ -+struct _BSS_DESC_T { -+ LINK_ENTRY_T rLinkEntry; -+ -+ UINT_8 aucBSSID[MAC_ADDR_LEN]; -+ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* For IBSS, the SrcAddr is different from BSSID */ -+ -+ BOOLEAN fgIsConnecting; /* If we are going to connect to this BSS -+ * (JOIN or ROAMING to another BSS), don't -+ * remove this record from BSS List. -+ */ -+ BOOLEAN fgIsConnected; /* If we have connected to this BSS (NORMAL_TR), -+ * don't removed this record from BSS list. -+ */ -+ -+ BOOLEAN fgIsHiddenSSID; /* When this flag is TRUE, means the SSID -+ * of this BSS is not known yet. -+ */ -+ UINT_8 ucSSIDLen; -+ UINT_8 aucSSID[ELEM_MAX_LEN_SSID]; -+ -+ OS_SYSTIME rUpdateTime; -+ -+ ENUM_BSS_TYPE_T eBSSType; -+ -+ UINT_16 u2CapInfo; -+ -+ UINT_16 u2BeaconInterval; -+ UINT_16 u2ATIMWindow; -+ -+ UINT_16 u2OperationalRateSet; -+ UINT_16 u2BSSBasicRateSet; -+ BOOLEAN fgIsUnknownBssBasicRate; -+ -+ BOOLEAN fgIsERPPresent; -+ BOOLEAN fgIsHTPresent; -+ -+ UINT_8 ucPhyTypeSet; /* Available PHY Type Set of this BSS */ -+ -+ UINT_8 ucChannelNum; -+ -+ ENUM_CHNL_EXT_T eSco; /* Record bandwidth for association process -+ Some AP will send association resp by 40MHz BW */ -+ ENUM_BAND_T eBand; -+ -+ UINT_8 ucDTIMPeriod; -+ -+ BOOLEAN fgIsLargerTSF; /* This BSS's TimeStamp is larger than us(TCL == 1 in RX_STATUS_T) */ -+ -+ UINT_8 ucRCPI; -+ -+ UINT_8 ucWmmFlag; /* A flag to indicate this BSS's WMM capability */ -+ -+ /*! \brief The srbiter Search State will matched the scan result, -+ and saved the selected cipher and akm, and report the score, -+ for arbiter join state, join module will carry this target BSS -+ to rsn generate ie function, for gen wpa/rsn ie */ -+ UINT_32 u4RsnSelectedGroupCipher; -+ UINT_32 u4RsnSelectedPairwiseCipher; -+ UINT_32 u4RsnSelectedAKMSuite; -+ -+ UINT_16 u2RsnCap; -+ -+ RSN_INFO_T rRSNInfo; -+ RSN_INFO_T rWPAInfo; -+#if 1 /* CFG_SUPPORT_WAPI */ -+ WAPI_INFO_T rIEWAPI; -+ BOOLEAN fgIEWAPI; -+#endif -+ BOOLEAN fgIERSN; -+ BOOLEAN fgIEWPA; -+ -+ /*! \brief RSN parameters selected for connection */ -+ /*! \brief The Select score for final AP selection, -+ 0, no sec, 1,2,3 group cipher is WEP, TKIP, CCMP */ -+ UINT_8 ucEncLevel; -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ BOOLEAN fgIsP2PPresent; -+ BOOLEAN fgIsP2PReport; /* TRUE: report to upper layer */ -+ P_P2P_DEVICE_DESC_T prP2pDesc; -+ -+ UINT_8 aucIntendIfAddr[MAC_ADDR_LEN]; /* For IBSS, the SrcAddr is different from BSSID */ -+/* UINT_8 ucDevCapabilityBitmap; */ /* Device Capability Attribute. (P2P_DEV_CAPABILITY_XXXX) */ -+/* UINT_8 ucGroupCapabilityBitmap; */ /* Group Capability Attribute. (P2P_GROUP_CAPABILITY_XXXX) */ -+ -+ LINK_T rP2pDeviceList; -+ -+/* P_LINK_T prP2pDeviceList; */ -+ -+ /* For -+ * 1. P2P Capability. -+ * 2. P2P Device ID. ( in aucSrcAddr[] ) -+ * 3. NOA (TODO:) -+ * 4. Extend Listen Timing. (Probe Rsp) (TODO:) -+ * 5. P2P Device Info. (Probe Rsp) -+ * 6. P2P Group Info. (Probe Rsp) -+ */ -+#endif -+ -+ BOOLEAN fgIsIEOverflow; /* The received IE length exceed the maximum IE buffer size */ -+ UINT_16 u2RawLength; /* The byte count of aucRawBuf[] */ -+ UINT_16 u2IELength; /* The byte count of aucIEBuf[] */ -+ -+ ULARGE_INTEGER u8TimeStamp; /* Place u8TimeStamp before aucIEBuf[1] to force DW align */ -+ UINT_8 aucRawBuf[CFG_RAW_BUFFER_SIZE]; -+ UINT_8 aucIEBuf[CFG_IE_BUFFER_SIZE]; -+ UINT_8 ucJoinFailureCount; -+ OS_SYSTIME rJoinFailTime; -+}; -+ -+typedef struct _SCAN_PARAM_T { /* Used by SCAN FSM */ -+ /* Active or Passive */ -+ ENUM_SCAN_TYPE_T eScanType; -+ -+ /* Network Type */ -+ ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex; -+ -+ /* Specified SSID Type */ -+ UINT_8 ucSSIDType; -+ UINT_8 ucSSIDNum; -+ -+ /* Length of Specified SSID */ -+ UINT_8 ucSpecifiedSSIDLen[SCN_SSID_MAX_NUM]; -+ -+ /* Specified SSID */ -+ UINT_8 aucSpecifiedSSID[SCN_SSID_MAX_NUM][ELEM_MAX_LEN_SSID]; -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ BOOLEAN fgFindSpecificDev; /* P2P: Discovery Protocol */ -+ UINT_8 aucDiscoverDevAddr[MAC_ADDR_LEN]; -+ BOOLEAN fgIsDevType; -+ P2P_DEVICE_TYPE_T rDiscoverDevType; -+ -+ UINT_16 u2PassiveListenInterval; -+ /* TODO: Find Specific Device Type. */ -+#endif /* CFG_SUPPORT_P2P */ -+ -+ BOOLEAN fgIsObssScan; -+ BOOLEAN fgIsScanV2; -+ -+ /* Run time flags */ -+ UINT_16 u2ProbeDelayTime; -+ -+ /* channel information */ -+ ENUM_SCAN_CHANNEL eScanChannel; -+ UINT_8 ucChannelListNum; -+ RF_CHANNEL_INFO_T arChnlInfoList[MAXIMUM_OPERATION_CHANNEL_LIST]; -+ -+ /* Feedback information */ -+ UINT_8 ucSeqNum; -+ -+ /* Information Element */ -+ UINT_16 u2IELen; -+ UINT_8 aucIE[MAX_IE_LENGTH]; -+ -+} SCAN_PARAM_T, *P_SCAN_PARAM_T; -+ -+typedef struct _NLO_PARAM_T { /* Used by SCAN FSM */ -+ SCAN_PARAM_T rScanParam; -+ -+ /* NLO */ -+ BOOLEAN fgStopAfterIndication; -+ UINT_8 ucFastScanIteration; -+ UINT_16 u2FastScanPeriod; -+ UINT_16 u2SlowScanPeriod; -+ -+ /* Match SSID */ -+ UINT_8 ucMatchSSIDNum; -+ UINT_8 ucMatchSSIDLen[SCN_SSID_MATCH_MAX_NUM]; -+ UINT_8 aucMatchSSID[SCN_SSID_MATCH_MAX_NUM][ELEM_MAX_LEN_SSID]; -+ -+ UINT_8 aucCipherAlgo[SCN_SSID_MATCH_MAX_NUM]; -+ UINT_16 au2AuthAlgo[SCN_SSID_MATCH_MAX_NUM]; -+ UINT_8 aucChannelHint[SCN_SSID_MATCH_MAX_NUM][SCN_NLO_NETWORK_CHANNEL_NUM]; -+ P_BSS_DESC_T aprPendingBssDescToInd[SCN_SSID_MATCH_MAX_NUM]; -+} NLO_PARAM_T, *P_NLO_PARAM_T; -+ -+#if 1 -+ -+typedef struct _GSCN_CHANNEL_INFO_T { -+ UINT_8 ucBand; -+ UINT_8 ucChannel; /* frequency */ -+ UINT_8 ucPassive; /* 0 => active, 1 => passive scan; ignored for DFS */ -+ UINT_8 aucReserved[1]; -+ -+ UINT_32 u4DwellTimeMs; /* dwell time hint */ -+ /* Add channel class */ -+} GSCN_CHANNEL_INFO_T, *P_GSCN_CHANNEL_INFO_T; -+ -+typedef struct _GSCAN_CHANNEL_BUCKET_T { -+ -+ UINT_16 u2BucketIndex; /* bucket index, 0 based */ -+ UINT_8 ucBucketFreqMultiple; /* desired period, in millisecond; -+ * if this is too low, the firmware should choose to generate -+ * results as fast as it can instead of failing the command */ -+ /* report_events semantics - -+ * 0 => report only when scan history is % full -+ * 1 => same as 0 + report a scan completion event after scanning this bucket -+ * 2 => same as 1 + forward scan results (beacons/probe responses + IEs) in real time to HAL -+ * 3 => same as 2 + forward scan results (beacons/probe responses + IEs) in real time to -+ supplicant as well (optional) . */ -+ UINT_8 ucReportFlag; -+ UINT_8 ucNumChannels; -+ UINT_8 aucReserved[3]; -+ WIFI_BAND eBand; /* when UNSPECIFIED, use channel list */ -+ GSCN_CHANNEL_INFO_T arChannelList[GSCAN_MAX_CHANNELS]; /* channels to scan; these may include DFS channels */ -+} GSCAN_CHANNEL_BUCKET_T, *P_GSCAN_CHANNEL_BUCKET_T; -+ -+typedef struct _CMD_GSCN_REQ_T { -+ UINT_8 ucFlags; -+ UINT_8 ucNumScnToCache; -+ UINT_8 aucReserved[2]; -+ UINT_32 u4BufferThreshold; -+ UINT_32 u4BasePeriod; /* base timer period in ms */ -+ UINT_32 u4NumBuckets; -+ UINT_32 u4MaxApPerScan; /* number of APs to store in each scan in the */ -+ /* BSSID/RSSI history buffer (keep the highest RSSI APs) */ -+ -+ GSCAN_CHANNEL_BUCKET_T arChannelBucket[GSCAN_MAX_BUCKETS]; -+} CMD_GSCN_REQ_T, *P_CMD_GSCN_REQ_T; -+ -+#endif -+ -+typedef struct _CMD_GSCN_SCN_COFIG_T { -+ UINT_8 ucNumApPerScn; /* GSCAN_ATTRIBUTE_NUM_AP_PER_SCAN */ -+ UINT_32 u4NumScnToCache; /* GSCAN_ATTRIBUTE_NUM_SCANS_TO_CACHE */ -+ UINT_32 u4BufferThreshold; /* GSCAN_ATTRIBUTE_REPORT_THRESHOLD */ -+} CMD_GSCN_SCN_COFIG_T, *P_CMD_GSCN_SCN_COFIG_T; -+ -+typedef struct _CMD_GET_GSCAN_RESULT { -+ UINT_8 ucVersion; -+ UINT_8 aucReserved[2]; -+ UINT_8 ucFlush; -+ UINT_32 u4Num; -+} CMD_GET_GSCAN_RESULT_T, *P_CMD_GET_GSCAN_RESULT_T; -+ -+typedef struct _CMD_BATCH_REQ_T { -+ UINT_8 ucSeqNum; -+ UINT_8 ucNetTypeIndex; -+ UINT_8 ucCmd; /* Start/ Stop */ -+ UINT_8 ucMScan; /* an integer number of scans per batch */ -+ UINT_8 ucBestn; /* an integer number of the max AP to remember per scan */ -+ UINT_8 ucRtt; /* an integer number of highest-strength AP for which we'd like -+ approximate distance reported */ -+ UINT_8 ucChannel; /* channels */ -+ UINT_8 ucChannelType; -+ UINT_8 ucChannelListNum; -+ UINT_8 aucReserved[3]; -+ UINT_32 u4Scanfreq; /* an integer number of seconds between scans */ -+ CHANNEL_INFO_T arChannelList[32]; /* channels */ -+} CMD_BATCH_REQ_T, *P_CMD_BATCH_REQ_T; -+ -+typedef struct _PSCN_PARAM_T { -+ UINT_8 ucVersion; -+ CMD_NLO_REQ rCurrentCmdNloReq; -+ CMD_BATCH_REQ_T rCurrentCmdBatchReq; -+ CMD_GSCN_REQ_T rCurrentCmdGscnReq; -+ BOOLEAN fgNLOScnEnable; -+ BOOLEAN fgBatchScnEnable; -+ BOOLEAN fgGScnEnable; -+ UINT_32 u4BasePeriod; /* GSCAN_ATTRIBUTE_BASE_PERIOD */ -+} PSCN_PARAM_T, *P_PSCN_PARAM_T; -+ -+typedef struct _SCAN_INFO_T { -+ ENUM_SCAN_STATE_T eCurrentState; /* Store the STATE variable of SCAN FSM */ -+ -+ OS_SYSTIME rLastScanCompletedTime; -+ -+ SCAN_PARAM_T rScanParam; -+ NLO_PARAM_T rNloParam; -+ -+ UINT_32 u4NumOfBssDesc; -+ -+ UINT_8 aucScanBuffer[SCN_MAX_BUFFER_SIZE]; -+ -+ LINK_T rBSSDescList; -+ -+ LINK_T rFreeBSSDescList; -+ -+ LINK_T rPendingMsgList; -+ -+ /* Sparse Channel Detection */ -+ BOOLEAN fgIsSparseChannelValid; -+ RF_CHANNEL_INFO_T rSparseChannel; -+ -+ /* NLO scanning state tracking */ -+ BOOLEAN fgNloScanning; -+ BOOLEAN fgPscnOnnning; -+ BOOLEAN fgGScnConfigSet; -+ BOOLEAN fgGScnParamSet; -+ P_PSCN_PARAM_T prPscnParam; -+ ENUM_PSCAN_STATE_T eCurrentPSCNState; -+ -+} SCAN_INFO_T, *P_SCAN_INFO_T; -+ -+/* Incoming Mailbox Messages */ -+typedef struct _MSG_SCN_SCAN_REQ_T { -+ MSG_HDR_T rMsgHdr; /* Must be the first member */ -+ UINT_8 ucSeqNum; -+ UINT_8 ucNetTypeIndex; -+ ENUM_SCAN_TYPE_T eScanType; -+ UINT_8 ucSSIDType; /* BIT(0) wildcard / BIT(1) P2P-wildcard / BIT(2) specific */ -+ UINT_8 ucSSIDLength; -+ UINT_8 aucSSID[PARAM_MAX_LEN_SSID]; -+#if CFG_ENABLE_WIFI_DIRECT -+ UINT_16 u2ChannelDwellTime; /* In TU. 1024us. */ -+#endif -+ ENUM_SCAN_CHANNEL eScanChannel; -+ UINT_8 ucChannelListNum; -+ RF_CHANNEL_INFO_T arChnlInfoList[MAXIMUM_OPERATION_CHANNEL_LIST]; -+ UINT_16 u2IELen; -+ UINT_8 aucIE[MAX_IE_LENGTH]; -+} MSG_SCN_SCAN_REQ, *P_MSG_SCN_SCAN_REQ; -+ -+typedef struct _MSG_SCN_SCAN_REQ_V2_T { -+ MSG_HDR_T rMsgHdr; /* Must be the first member */ -+ UINT_8 ucSeqNum; -+ UINT_8 ucNetTypeIndex; -+ ENUM_SCAN_TYPE_T eScanType; -+ UINT_8 ucSSIDType; /* BIT(0) wildcard / BIT(1) P2P-wildcard / BIT(2) specific */ -+ UINT_8 ucSSIDNum; -+ P_PARAM_SSID_T prSsid; -+ UINT_16 u2ProbeDelay; -+ UINT_16 u2ChannelDwellTime; /* In TU. 1024us. */ -+ ENUM_SCAN_CHANNEL eScanChannel; -+ UINT_8 ucChannelListNum; -+ RF_CHANNEL_INFO_T arChnlInfoList[MAXIMUM_OPERATION_CHANNEL_LIST]; -+ UINT_16 u2IELen; -+ UINT_8 aucIE[MAX_IE_LENGTH]; -+} MSG_SCN_SCAN_REQ_V2, *P_MSG_SCN_SCAN_REQ_V2; -+ -+typedef struct _MSG_SCN_SCAN_CANCEL_T { -+ MSG_HDR_T rMsgHdr; /* Must be the first member */ -+ UINT_8 ucSeqNum; -+ UINT_8 ucNetTypeIndex; -+#if CFG_ENABLE_WIFI_DIRECT -+ BOOLEAN fgIsChannelExt; -+#endif -+} MSG_SCN_SCAN_CANCEL, *P_MSG_SCN_SCAN_CANCEL; -+ -+/* Outgoing Mailbox Messages */ -+typedef enum _ENUM_SCAN_STATUS_T { -+ SCAN_STATUS_DONE = 0, -+ SCAN_STATUS_CANCELLED, -+ SCAN_STATUS_FAIL, -+ SCAN_STATUS_BUSY, -+ SCAN_STATUS_NUM -+} ENUM_SCAN_STATUS, *P_ENUM_SCAN_STATUS; -+ -+typedef struct _MSG_SCN_SCAN_DONE_T { -+ MSG_HDR_T rMsgHdr; /* Must be the first member */ -+ UINT_8 ucSeqNum; -+ UINT_8 ucNetTypeIndex; -+ ENUM_SCAN_STATUS eScanStatus; -+} MSG_SCN_SCAN_DONE, *P_MSG_SCN_SCAN_DONE; -+ -+#if CFG_SUPPORT_AGPS_ASSIST -+typedef enum { -+ AGPS_PHY_A, -+ AGPS_PHY_B, -+ AGPS_PHY_G, -+} AP_PHY_TYPE; -+ -+typedef struct _AGPS_AP_INFO_T { -+ UINT_8 aucBSSID[6]; -+ INT_16 i2ApRssi; /* -127..128 */ -+ UINT_16 u2Channel; /* 0..256 */ -+ AP_PHY_TYPE ePhyType; -+} AGPS_AP_INFO_T, *P_AGPS_AP_INFO_T; -+ -+typedef struct _AGPS_AP_LIST_T { -+ UINT_8 ucNum; -+ AGPS_AP_INFO_T arApInfo[32]; -+} AGPS_AP_LIST_T, *P_AGPS_AP_LIST_T; -+#endif -+ -+typedef struct _CMD_SET_PSCAN_PARAM { -+ UINT_8 ucVersion; -+ CMD_NLO_REQ rCmdNloReq; -+ CMD_BATCH_REQ_T rCmdBatchReq; -+ CMD_GSCN_REQ_T rCmdGscnReq; -+ BOOLEAN fgNLOScnEnable; -+ BOOLEAN fgBatchScnEnable; -+ BOOLEAN fgGScnEnable; -+ UINT_32 u4BasePeriod; -+} CMD_SET_PSCAN_PARAM, *P_CMD_SET_PSCAN_PARAM; -+ -+typedef struct _CMD_SET_PSCAN_ADD_HOTLIST_BSSID { -+ UINT_8 aucMacAddr[6]; -+ UINT_8 ucFlags; -+ UINT_8 aucReserved[5]; -+} CMD_SET_PSCAN_ADD_HOTLIST_BSSID, *P_CMD_SET_PSCAN_ADD_HOTLIST_BSSID; -+ -+typedef struct _CMD_SET_PSCAN_ADD_SWC_BSSID { -+ INT_32 i4RssiLowThreshold; -+ INT_32 i4RssiHighThreshold; -+ UINT_8 aucMacAddr[6]; -+ UINT_8 aucReserved[6]; -+} CMD_SET_PSCAN_ADD_SWC_BSSID, *P_CMD_SET_PSCAN_ADD_SWC_BSSID; -+ -+typedef struct _CMD_SET_PSCAN_MAC_ADDR { -+ UINT_8 ucVersion; -+ UINT_8 ucFlags; -+ UINT_8 aucMacAddr[6]; -+ UINT_8 aucReserved[8]; -+} CMD_SET_PSCAN_MAC_ADDR, *P_CMD_SET_PSCAN_MAC_ADDR; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+/*----------------------------------------------------------------------------*/ -+/* Routines in scan.c */ -+/*----------------------------------------------------------------------------*/ -+VOID scnInit(IN P_ADAPTER_T prAdapter); -+ -+VOID scnUninit(IN P_ADAPTER_T prAdapter); -+ -+/* BSS-DESC Search */ -+P_BSS_DESC_T scanSearchBssDescByBssid(IN P_ADAPTER_T prAdapter, IN UINT_8 aucBSSID[]); -+ -+P_BSS_DESC_T -+scanSearchBssDescByBssidAndSsid(IN P_ADAPTER_T prAdapter, -+ IN UINT_8 aucBSSID[], IN BOOLEAN fgCheckSsid, IN P_PARAM_SSID_T prSsid); -+ -+P_BSS_DESC_T scanSearchBssDescByTA(IN P_ADAPTER_T prAdapter, IN UINT_8 aucSrcAddr[]); -+ -+P_BSS_DESC_T -+scanSearchBssDescByTAAndSsid(IN P_ADAPTER_T prAdapter, -+ IN UINT_8 aucSrcAddr[], IN BOOLEAN fgCheckSsid, IN P_PARAM_SSID_T prSsid); -+ -+#if CFG_SUPPORT_HOTSPOT_2_0 -+P_BSS_DESC_T scanSearchBssDescByBssidAndLatestUpdateTime(IN P_ADAPTER_T prAdapter, IN UINT_8 aucBSSID[]); -+#endif -+ -+/* BSS-DESC Search - Alternative */ -+P_BSS_DESC_T -+scanSearchExistingBssDesc(IN P_ADAPTER_T prAdapter, -+ IN ENUM_BSS_TYPE_T eBSSType, IN UINT_8 aucBSSID[], IN UINT_8 aucSrcAddr[]); -+ -+P_BSS_DESC_T -+scanSearchExistingBssDescWithSsid(IN P_ADAPTER_T prAdapter, -+ IN ENUM_BSS_TYPE_T eBSSType, -+ IN UINT_8 aucBSSID[], -+ IN UINT_8 aucSrcAddr[], IN BOOLEAN fgCheckSsid, IN P_PARAM_SSID_T prSsid); -+ -+/* BSS-DESC Allocation */ -+P_BSS_DESC_T scanAllocateBssDesc(IN P_ADAPTER_T prAdapter); -+ -+/* BSS-DESC Removal */ -+VOID scanRemoveBssDescsByPolicy(IN P_ADAPTER_T prAdapter, IN UINT_32 u4RemovePolicy); -+ -+VOID scanRemoveBssDescByBssid(IN P_ADAPTER_T prAdapter, IN UINT_8 aucBSSID[]); -+ -+VOID -+scanRemoveBssDescByBandAndNetwork(IN P_ADAPTER_T prAdapter, -+ IN ENUM_BAND_T eBand, IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex); -+ -+/* BSS-DESC State Change */ -+VOID scanRemoveConnFlagOfBssDescByBssid(IN P_ADAPTER_T prAdapter, IN UINT_8 aucBSSID[]); -+ -+#if 0 -+/* BSS-DESC Insertion */ -+P_BSS_DESC_T scanAddToInternalScanResult(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSWRfb, IN P_BSS_DESC_T prBssDesc); -+#endif -+ -+/* BSS-DESC Insertion - ALTERNATIVE */ -+P_BSS_DESC_T scanAddToBssDesc(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); -+ -+WLAN_STATUS scanProcessBeaconAndProbeResp(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSWRfb); -+ -+VOID -+scanBuildProbeReqFrameCommonIEs(IN P_MSDU_INFO_T prMsduInfo, -+ IN PUINT_8 pucDesiredSsid, IN UINT_32 u4DesiredSsidLen, IN UINT_16 u2SupportedRateSet); -+ -+WLAN_STATUS scanSendProbeReqFrames(IN P_ADAPTER_T prAdapter, IN P_SCAN_PARAM_T prScanParam); -+ -+VOID scanUpdateBssDescForSearch(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBssDesc); -+ -+P_BSS_DESC_T scanSearchBssDescByPolicy(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex); -+ -+WLAN_STATUS scanAddScanResult(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBssDesc, IN P_SW_RFB_T prSwRfb); -+ -+VOID scanReportBss2Cfg80211(IN P_ADAPTER_T prAdapter, IN ENUM_BSS_TYPE_T eBSSType, IN P_BSS_DESC_T SpecificprBssDesc); -+ -+/*----------------------------------------------------------------------------*/ -+/* Routines in scan_fsm.c */ -+/*----------------------------------------------------------------------------*/ -+VOID scnFsmSteps(IN P_ADAPTER_T prAdapter, IN ENUM_SCAN_STATE_T eNextState); -+ -+/*----------------------------------------------------------------------------*/ -+/* Command Routines */ -+/*----------------------------------------------------------------------------*/ -+VOID scnSendScanReqExtCh(IN P_ADAPTER_T prAdapter); -+ -+VOID scnSendScanReq(IN P_ADAPTER_T prAdapter); -+ -+VOID scnSendScanReqV2ExtCh(IN P_ADAPTER_T prAdapter); -+ -+VOID scnSendScanReqV2(IN P_ADAPTER_T prAdapter); -+ -+/*----------------------------------------------------------------------------*/ -+/* RX Event Handling */ -+/*----------------------------------------------------------------------------*/ -+VOID scnEventScanDone(IN P_ADAPTER_T prAdapter, IN P_EVENT_SCAN_DONE prScanDone); -+ -+VOID scnEventNloDone(IN P_ADAPTER_T prAdapter, IN P_EVENT_NLO_DONE_T prNloDone); -+ -+/*----------------------------------------------------------------------------*/ -+/* Mailbox Message Handling */ -+/*----------------------------------------------------------------------------*/ -+VOID scnFsmMsgStart(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); -+ -+VOID scnFsmMsgAbort(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); -+ -+VOID scnFsmHandleScanMsg(IN P_ADAPTER_T prAdapter, IN P_MSG_SCN_SCAN_REQ prScanReqMsg); -+ -+VOID scnFsmHandleScanMsgV2(IN P_ADAPTER_T prAdapter, IN P_MSG_SCN_SCAN_REQ_V2 prScanReqMsg); -+ -+VOID scnFsmRemovePendingMsg(IN P_ADAPTER_T prAdapter, IN UINT_8 ucSeqNum, IN UINT_8 ucNetTypeIndex); -+ -+/*----------------------------------------------------------------------------*/ -+/* Mailbox Message Generation */ -+/*----------------------------------------------------------------------------*/ -+VOID -+scnFsmGenerateScanDoneMsg(IN P_ADAPTER_T prAdapter, -+ IN UINT_8 ucSeqNum, IN UINT_8 ucNetTypeIndex, IN ENUM_SCAN_STATUS eScanStatus); -+ -+/*----------------------------------------------------------------------------*/ -+/* Query for sparse channel */ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN scnQuerySparseChannel(IN P_ADAPTER_T prAdapter, P_ENUM_BAND_T prSparseBand, PUINT_8 pucSparseChannel); -+ -+/*----------------------------------------------------------------------------*/ -+/* OID/IOCTL Handling */ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN -+scnFsmSchedScanRequest(IN P_ADAPTER_T prAdapter, -+ IN UINT_8 ucSsidNum, -+ IN P_PARAM_SSID_T prSsid, IN UINT_32 u4IeLength, IN PUINT_8 pucIe, IN UINT_16 u2Interval); -+ -+BOOLEAN scnFsmSchedScanStopRequest(IN P_ADAPTER_T prAdapter); -+ -+BOOLEAN scnFsmPSCNAction(IN P_ADAPTER_T prAdapter, IN UINT_8 ucPscanAct); -+ -+BOOLEAN scnFsmPSCNSetParam(IN P_ADAPTER_T prAdapter, IN P_CMD_SET_PSCAN_PARAM prCmdPscnParam); -+ -+BOOLEAN scnFsmGSCNSetHotlist(IN P_ADAPTER_T prAdapter, IN P_CMD_SET_PSCAN_PARAM prCmdPscnParam); -+ -+#if 0 -+ -+BOOLEAN scnFsmGSCNSetRssiSignificatn(IN P_ADAPTER_T prAdapter, IN P_CMD_SET_PSCAN_PARAM prCmdPscnParam); -+#endif -+ -+BOOLEAN scnFsmPSCNAddSWCBssId(IN P_ADAPTER_T prAdapter, IN P_CMD_SET_PSCAN_ADD_SWC_BSSID prCmdPscnAddSWCBssId); -+ -+BOOLEAN scnFsmPSCNSetMacAddr(IN P_ADAPTER_T prAdapter, IN P_CMD_SET_PSCAN_MAC_ADDR prCmdPscnSetMacAddr); -+ -+#if 1 /* CFG_SUPPORT_GSCN_NONSYNC_BROADCOM */ -+BOOLEAN scnSetGSCNParam(IN P_ADAPTER_T prAdapter, IN P_PARAM_WIFI_GSCAN_CMD_PARAMS prCmdGscnParam); -+ -+#else -+BOOLEAN scnSetGSCNParam(IN P_ADAPTER_T prAdapter, IN P_CMD_GSCN_REQ_T prCmdGscnParam); -+ -+#endif -+ -+BOOLEAN -+scnCombineParamsIntoPSCN(IN P_ADAPTER_T prAdapter, -+ IN P_CMD_NLO_REQ prCmdNloReq, -+ IN P_CMD_BATCH_REQ_T prCmdBatchReq, -+ IN P_CMD_GSCN_REQ_T prCmdGscnReq, -+ IN P_CMD_GSCN_SCN_COFIG_T prNewCmdGscnConfig, -+ IN BOOLEAN fgRemoveNLOfromPSCN, -+ IN BOOLEAN fgRemoveBatchSCNfromPSCN, IN BOOLEAN fgRemoveGSCNfromPSCN); -+ -+BOOLEAN scnFsmSetGSCNConfig(IN P_ADAPTER_T prAdapter, IN P_CMD_GSCN_SCN_COFIG_T prCmdGscnScnConfig); -+ -+BOOLEAN scnFsmGetGSCNResult(IN P_ADAPTER_T prAdapter, IN P_CMD_GET_GSCAN_RESULT_T prGetGscnScnResultCmd); -+ -+VOID -+scnPSCNFsm(IN P_ADAPTER_T prAdapter, -+ ENUM_PSCAN_STATE_T eNextPSCNState, -+ IN P_CMD_NLO_REQ prCmdNloReq, -+ IN P_CMD_BATCH_REQ_T prCmdBatchReq, -+ IN P_CMD_GSCN_REQ_T prCmdGscnReq, -+ IN P_CMD_GSCN_SCN_COFIG_T prNewCmdGscnConfig, -+ IN BOOLEAN fgRemoveNLOfromPSCN, -+ IN BOOLEAN fgRemoveBatchSCNfromPSCN, IN BOOLEAN fgRemoveGSCNfromPSCN, IN BOOLEAN fgEnableGSCN); -+ -+#endif /* _SCAN_H */ -+ -+#if CFG_SUPPORT_AGPS_ASSIST -+VOID scanReportScanResultToAgps(P_ADAPTER_T prAdapter); -+#endif -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/sec_fsm.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/sec_fsm.h -new file mode 100644 -index 000000000000..c6c468e06c4a ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/sec_fsm.h -@@ -0,0 +1,233 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/mgmt/sec_fsm.h#1 -+*/ -+ -+/*! \file sec_fsm.h -+ \brief Declaration of functions and finite state machine for SECURITY Module. -+ -+ Function declaration for privacy.c and SEC_STATE for SECURITY FSM. -+*/ -+ -+/* -+** Log: sec_fsm.h -+ * -+ * 09 29 2010 wh.su -+ * [WCXRP00000072] [MT6620 Wi-Fi][Driver] Fix TKIP Counter Measure EAPoL callback register issue -+ * [MT6620 Wi-Fi][Driver] Fix TKIP Counter Measure EAPoL callback register issue. -+ * -+ * 09 21 2010 kevin.huang -+ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning -+ * Eliminate Linux Compile Warning -+ * -+ * 09 03 2010 kevin.huang -+ * NULL -+ * Refine #include sequence and solve recursive/nested #include issue -+ * -+ * 08 20 2010 wh.su -+ * NULL -+ * adding the eapol callback setting. -+ * -+ * 08 19 2010 wh.su -+ * NULL -+ * adding the tx pkt call back handle for countermeasure. -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 21 2010 wh.su -+ * [WPD00003840][MT6620 5931] Security migration -+ * modify some code for concurrent network. -+ * -+ * 06 19 2010 wh.su -+ * [WPD00003840][MT6620 5931] Security migration -+ * consdier the concurrent network setting. -+ * -+ * 03 04 2010 wh.su -+ * [BORA00000605][WIFISYS] Phase3 Integration -+ * Code refine, and remove non-used code. -+ * -+ * 03 03 2010 wh.su -+ * [BORA00000637][MT6620 Wi-Fi] [Bug] WPA2 pre-authentication timer not correctly initialize -+ * Fixed the pre-authentication timer not correctly init issue, and modify the security -+ * related callback function prototype. -+ * -+ * 03 01 2010 wh.su -+ * [BORA00000605][WIFISYS] Phase3 Integration -+ * Refine the variable and parameter for security. -+ * -+ * 12 18 2009 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * . -+ * -+ * Dec 7 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * fixed the deauth Tx done callback parameter -+ * -+ * Dec 4 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * adding the reference function declaration -+ * -+ * Dec 3 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * delete non-used code -+ * -+ * Dec 1 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * adjust the function prototype -+ * -+ * Nov 23 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * adjust the function declaration -+ * -+ * Nov 19 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * adding the security variable -+ * -+ * Nov 18 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * -+** \main\maintrunk.MT5921\14 2009-04-06 15:35:47 GMT mtk01088 -+** add the variable to set the disable AP selection for privacy check, for wps open networking. -+** \main\maintrunk.MT5921\13 2008-11-19 11:46:01 GMT mtk01088 -+** rename some variable with pre-fix to avoid the misunderstanding -+** \main\maintrunk.MT5921\12 2008-08-28 20:37:11 GMT mtk01088 -+** remove non-used code -+** -+** \main\maintrunk.MT5921\11 2008-03-18 09:51:52 GMT mtk01088 -+** Add function declaration for timer to indicate pmkid candidate -+** \main\maintrunk.MT5921\10 2008-02-29 15:12:08 GMT mtk01088 -+** add variable for sw port control -+** \main\maintrunk.MT5921\9 2008-02-29 12:37:30 GMT mtk01088 -+** rename the security related function declaration -+** \main\maintrunk.MT5921\8 2007-12-27 13:59:08 GMT mtk01088 -+** adjust the wlan table and sec fsm init timing -+** \main\maintrunk.MT5921\7 2007-11-20 10:39:49 GMT mtk01088 -+** add function timer for wait EAPoL Error timeout -+** \main\maintrunk.MT5921\6 2007-11-06 20:39:08 GMT mtk01088 -+** rename the counter measure timer -+** \main\maintrunk.MT5921\5 2007-11-06 20:14:31 GMT mtk01088 -+** add a abort function -+** Revision 1.5 2007/07/16 02:33:42 MTK01088 -+** change the ENUM declaration structure prefix from r to e -+** -+** Revision 1.4 2007/07/09 06:23:10 MTK01088 -+** update -+** -+** Revision 1.3 2007/07/04 10:09:04 MTK01088 -+** adjust the state for security fsm -+** change function name -+** -+** Revision 1.2 2007/07/03 08:13:22 MTK01088 -+** change the sec fsm state -+** add the event for sec fsm -+** -+** Revision 1.1 2007/06/27 06:20:35 MTK01088 -+** add the sec fsm header file -+** -+** -+*/ -+#ifndef _SEC_FSM_H -+#define _SEC_FSM_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/* TKIP CounterMeasure interval for Rejoin to Network. */ -+#define COUNTER_MEASURE_TIMEOUT_INTERVAL_SEC 60 -+ -+/* Timeout to wait the EAPoL Error Report frame Send out. */ -+#define EAPOL_REPORT_SEND_TIMEOUT_INTERVAL_SEC 1 -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+typedef UINT_32 SEC_STATUS, *P_SEC_STATUS; -+ -+#if 0 -+/* WPA2 PMKID candicate structure */ -+typedef struct _PMKID_CANDICATE_T { -+ UINT_8 aucBssid[MAC_ADDR_LEN]; /* MAC address */ -+ UINT_32 u4PreAuthFlags; -+} PMKID_CANDICATE_T, *P_PMKID_CANDICATE_T; -+#endif -+ -+typedef SEC_STATUS(*PFN_SEC_FSM_STATE_HANDLER) (VOID); -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+#define SEC_STATE_TRANSITION_FLAG fgIsTransition -+#define SEC_NEXT_STATE_VAR eNextState -+ -+#define SEC_STATE_TRANSITION(prAdapter, prSta, eFromState, eToState) \ -+ { secFsmTrans_ ## eFromState ## _to_ ## eToState(prAdapter, prSta); \ -+ SEC_NEXT_STATE_VAR = SEC_STATE_ ## eToState; \ -+ SEC_STATE_TRANSITION_FLAG = (BOOLEAN)TRUE; \ -+ } -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/*--------------------------------------------------------------*/ -+/* Routines to handle the sec check */ -+/*--------------------------------------------------------------*/ -+/***** Routines in sec_fsm.c *****/ -+VOID secFsmInit(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta); -+ -+VOID secFsmEventInit(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta); -+ -+VOID secFsmEventStart(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta); -+ -+VOID secFsmEventAbort(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta); -+ -+BOOLEAN secFsmEventPTKInstalled(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta); -+ -+VOID secFsmEvent2ndEapolTx(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta); -+ -+VOID secFsmEvent4ndEapolTxDone(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta); -+ -+VOID -+secFsmEventEapolTxDone(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus); -+ -+VOID secFsmEventEapolTxTimeout(IN P_ADAPTER_T prAdapter, IN ULONG ulParm); -+ -+VOID -+secFsmEventDeauthTxDone(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus); -+ -+VOID secFsmEventStartCounterMeasure(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta); -+ -+VOID secFsmEventEndOfCounterMeasure(IN P_ADAPTER_T prAdapter, IN ULONG ulParm); -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+#endif /* _SEC_FSM_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/stats.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/stats.h -new file mode 100644 -index 000000000000..1c0f9a76e119 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/stats.h -@@ -0,0 +1,368 @@ -+/* -+** Id: stats.h#1 -+*/ -+ -+/*! \file stats.h -+ \brief This file includes statistics support. -+*/ -+ -+/* -+** Log: stats.h -+ * -+ * 07 17 2014 samp.lin -+ * NULL -+ * Initial version. -+ */ -+ -+/******************************************************************************* -+ * C O M P I L E R F L A G S -+ ******************************************************************************** -+ */ -+ -+/******************************************************************************* -+ * E X T E R N A L R E F E R E N C E S -+ ******************************************************************************** -+ */ -+extern UINT_64 u8DrvOwnStart, u8DrvOwnEnd; -+extern UINT32 u4DrvOwnMax; -+extern BOOLEAN fgIsUnderSuspend; -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/* Command to TDLS core module */ -+typedef enum _STATS_CMD_CORE_ID { -+ STATS_CORE_CMD_ENV_REQUEST = 0x00 -+} STATS_CMD_CORE_ID; -+ -+typedef enum _STATS_EVENT_HOST_ID { -+ STATS_HOST_EVENT_ENV_REPORT = 0x00, -+ STATS_HOST_EVENT_RX_DROP -+} STATS_EVENT_HOST_ID; -+ -+#define CFG_ARP BIT(0) -+#define CFG_DNS BIT(1) -+#define CFG_TCP BIT(2) -+#define CFG_UDP BIT(3) -+#define CFG_EAPOL BIT(4) -+#define CFG_DHCP BIT(5) -+#define CFG_ICMP BIT(6) -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+typedef struct _STATS_CMD_CORE_T { -+ -+ UINT32 u4Command; /* STATS_CMD_CORE_ID */ -+ -+ UINT8 ucStaRecIdx; -+ UINT8 ucReserved[3]; -+ -+ UINT32 u4Reserved[4]; -+ -+#define STATS_CMD_CORE_RESERVED_SIZE 50 -+ union { -+ UINT8 Reserved[STATS_CMD_CORE_RESERVED_SIZE]; -+ } Content; -+ -+} STATS_CMD_CORE_T; -+ -+typedef struct _STATS_INFO_ENV_T { -+ -+ BOOLEAN fgIsUsed; /* TRUE: used */ -+ -+ /* ------------------- TX ------------------- */ -+ BOOLEAN fgTxIsRtsUsed; /* TRUE: we use RTS/CTS currently */ -+ BOOLEAN fgTxIsRtsEverUsed; /* TRUE: we ever use RTS/CTS */ -+ BOOLEAN fgTxIsCtsSelfUsed; /* TRUE: we use CTS-self */ -+ -+#define STATS_INFO_TX_PARAM_HW_BW40_OFFSET 0 -+#define STATS_INFO_TX_PARAM_HW_SHORT_GI20_OFFSET 1 -+#define STATS_INFO_TX_PARAM_HW_SHORT_GI40_OFFSET 2 -+#define STATS_INFO_TX_PARAM_USE_BW40_OFFSET 3 -+#define STATS_INFO_TX_PARAM_USE_SHORT_GI_OFFSET 4 -+#define STATS_INFO_TX_PARAM_NO_ACK_OFFSET 5 -+ UINT_8 ucTxParam; -+ -+ UINT_8 ucStaRecIdx; -+ UINT_8 ucReserved1[2]; -+ -+ UINT32 u4TxDataCntAll; /* total tx count from host */ -+ UINT32 u4TxDataCntOK; /* total tx ok count to air */ -+ UINT32 u4TxDataCntErr; /* total tx err count to air */ -+ -+ /* WLAN_STATUS_BUFFER_RETAINED ~ WLAN_STATUS_PACKET_LIFETIME_ERROR */ -+ UINT32 u4TxDataCntErrType[6]; /* total tx err count for different type to air */ -+ -+ UINT_8 ucTxRate1NonHTMax; -+ UINT_8 ucTxRate1HTMax; -+ UINT32 u4TxRateCntNonHT[16]; /* tx done rate */ -+ UINT32 u4TxRateCntHT[16]; /* tx done rate */ -+ -+ UINT_8 ucTxAggBitmap; /* TX BA sessions TID0 ~ TID7 */ -+ UINT_8 ucTxPeerAggMaxSize; -+ -+ /* ------------------- RX ------------------- */ -+ BOOLEAN fgRxIsRtsUsed; /* TRUE: peer uses RTS/CTS currently */ -+ BOOLEAN fgRxIsRtsEverUsed; /* TRUE: peer ever uses RTS/CTS */ -+ -+ UINT_8 ucRcvRcpi; -+ UINT_8 ucHwChanNum; -+ BOOLEAN fgRxIsShortGI; -+ UINT_8 ucReserved2[1]; -+ -+ UINT32 u4RxDataCntAll; /* total rx count from peer */ -+ UINT32 u4RxDataCntErr; /* total rx err count */ -+ UINT32 u4RxRateCnt[3][16]; /* [0]:CCK, [1]:OFDM, [2]:MIXED (skip green mode) */ -+ -+ UINT_8 ucRxAggBitmap; /* RX BA sessions TID0 ~ TID7 */ -+ UINT_8 ucRxAggMaxSize; -+ -+#define STATS_INFO_PHY_MODE_CCK 0 -+#define STATS_INFO_PHY_MODE_OFDM 1 -+#define STATS_INFO_PHY_MODE_HT 2 -+#define STATS_INFO_PHY_MODE_VHT 3 -+ UINT_8 ucBssSupPhyMode; /* CCK, OFDM, HT, or VHT BSS */ -+ -+ UINT_8 ucVersion; /* the version of statistics info environment */ -+ -+ /* ------------------- Delay ------------------- */ -+#define STATS_AIR_DELAY_INT 500 /* 500 byte */ -+ -+ /* delay in firmware from host to MAC */ -+ /* unit: us, for 500B, 1000B, max */ -+ UINT32 u4StayIntMaxH2M[3], u4StayIntMinH2M[3], u4StayIntAvgH2M[3]; -+ -+ /* delay in firmware from MAC to TX done */ -+ /* unit: 32us, for 500B, 1000B, max */ -+ UINT32 u4AirDelayMax[3], u4AirDelayMin[3], u4AirDelayAvg[3]; -+ -+ /* delay in firmware from host to TX done */ -+ /* unit: us, for 500B, 1000B, max */ -+ UINT32 u4StayIntMax[3], u4StayIntMin[3], u4StayIntAvg[3]; -+ UINT32 u4StayIntMaxSysTime[3]; -+ -+ /* delay in firmware from driver to TX done */ -+ /* unit: us, for 500B, 1000B, max */ -+ UINT32 u4StayIntMaxD2T[3], u4StayIntMinD2T[3], u4StayIntAvgD2T[3]; -+ -+ /* delay count in firmware from host to TX done */ -+ /* u4StayIntByConst: divide 4 fix partitions to count each delay in firmware */ -+#define STATS_STAY_INT_CONST 1 /* 1ms */ -+#define STATS_STAY_INT_CONST_2 5 -+#define STATS_STAY_INT_CONST_3 10 -+#define STATS_STAY_INT_CONST_4 15 -+#define STATS_STAY_INT_CONST_NUM 4 -+ UINT32 u4StayIntByConst[STATS_STAY_INT_CONST_NUM]; -+ -+ /* -+ u4StayIntMaxPast: past maximum delay in firmware -+ u4StayIntCnt[]: divide 4 partitions to count each delay in firmware -+ */ -+#define STATS_STAY_INT_NUM 4 -+ UINT32 u4StayIntMaxPast; -+ UINT32 u4StayIntCnt[STATS_STAY_INT_NUM + 1]; -+ -+ /* delay count in firmware from driver to HIF */ -+ /* u4StayIntD2HByConst: divide 4 fix partitions to count each delay in firmware */ -+#define STATS_STAY_INT_D2H_CONST 10 /* 10ms */ -+#define STATS_STAY_INT_D2H_CONST_2 20 -+#define STATS_STAY_INT_D2H_CONST_3 30 -+#define STATS_STAY_INT_D2H_CONST_4 40 -+#define STATS_STAY_INT_D2H_CONST_NUM 4 -+ UINT32 u4StayIntD2HByConst[STATS_STAY_INT_D2H_CONST_NUM]; -+ -+ /* unit: us, for 500B, 1000B, max */ -+ UINT32 u4StayIntMaxRx[3], u4StayIntMinRx[3], u4StayIntAvgRx[3]; -+ -+ /* ------------------- Others ------------------- */ -+ UINT32 u4NumOfChanChange; /* total channel change count */ -+ UINT32 u4NumOfRetryCnt; /* total TX retry count */ -+ UINT32 u4RxFifoFullCnt; /* counter of the number of the packets which -+ pass RFCR but are dropped due to FIFO full. */ -+ UINT32 u4PsIntMax; /* maximum time from ps to active */ -+ UINT_8 ucNumOfPsChange; /* peer power save change count */ -+ UINT_8 ucReserved3[3]; -+ -+ UINT32 u4ReportSysTime; /* firmware system time */ -+ UINT32 u4RxDataCntOk; /* total rx count to hif */ -+ -+ /* V4 */ -+ UINT32 u4RxRateRetryCnt[3][16]; /* [0]:CCK, [1]:OFDM, [2]:MIXED (skip green mode) */ -+ UINT32 au4ChanIdleCnt[10]; /* past Channel idle count in unit of slot */ -+ -+ /* V5 */ -+ UINT32 u4BtContUseTime; /* the air time that BT continuous occypy */ -+ -+ /* V6 */ -+ UINT32 u4LastTxOkTime; /* last time we tx ok to the station */ -+ -+ /* V7 */ -+ UINT_8 ucBtWfCoexGrantCnt[8]; /* [0]:WF Rx Grant Cnt[1]: WF Tx Grant Cnt[2]: WF Grant with Priority1 */ -+ /* [4]:BT Rx Grant Cnt[5]: BT Tx Grant Cnt[6]: BT Grant with Priority1 */ -+ -+ /* V8 */ -+ UINT_32 u4RxMacFreeDescCnt[6]; -+ UINT_32 u4RxHifFreeDescCnt[6]; -+ -+ /* V9 */ -+#define STATS_MAX_RX_DROP_TYPE 20 -+ UINT32 u4NumOfRxDrop[STATS_MAX_RX_DROP_TYPE]; -+ -+ /* V10 */ -+ UINT_32 u4NumOfTxDone; /* number of all packets (data/man/ctrl) tx done */ -+ UINT_32 u4NumOfTxDoneFixRate; /* number of done rate = 0 */ -+ UINT_32 u4NumOfTxDoneErrRate; /* number of error done rate */ -+ UINT_32 u4NumOfNullTxDone; /* number of null tx done */ -+ UINT_32 u4NumOfQoSNullTxDone; /* number of QoS-null tx done */ -+ -+ /* V11 */ -+ /* delay in firmware from HIF RX to HIF RX Done */ -+ /* unit: us, for 500B, 1000B, max */ -+ UINT32 u4StayIntMaxHR2HRD[3], u4StayIntMinHR2HRD[3], u4StayIntAvgHR2HRD[3]; -+ -+ /* V12 */ -+ UINT32 u4AirDelayTotal; /* agg all the air delay */ -+ -+ /* V13 */ -+ UINT32 u4CurrChnlInfo; /* add current channel information */ -+ -+ UINT_8 ucReserved_rate[4]; /* the field must be the last one */ -+} STATS_INFO_ENV_T; -+ -+/******************************************************************************* -+* M A C R O D E C L A R A T I O N S -+******************************************************************************** -+*/ -+#if (CFG_SUPPORT_STATISTICS == 1) -+ -+#define STATS_ENV_REPORT_DETECT statsEnvReportDetect -+ -+#define STATS_RX_REORDER_FALL_AHEAD_INC(__StaRec__) \ -+{ \ -+ (__StaRec__)->u4RxReorderFallAheadCnt++; \ -+} -+ -+#define STATS_RX_REORDER_FALL_BEHIND_INC(__StaRec__) \ -+{ \ -+ (__StaRec__)->u4RxReorderFallBehindCnt++; \ -+} -+ -+#define STATS_RX_REORDER_HOLE_INC(__StaRec__) \ -+{ \ -+ (__StaRec__)->u4RxReorderHoleCnt++; \ -+} -+ -+#define STATS_RX_REORDER_HOLE_TIMEOUT_INC(__StaRec__, __IsTimeout__) \ -+{ \ -+ if ((__IsTimeout__) == TRUE) \ -+ (__StaRec__)->u4RxReorderHoleTimeoutCnt++; \ -+} -+ -+#define STATS_RX_ARRIVE_TIME_RECORD(__SwRfb__) \ -+{ \ -+ (__SwRfb__)->rRxTime = StatsEnvTimeGet(); \ -+} -+ -+#define STATS_RX_PASS2OS_INC StatsEnvRxDone -+ -+#define STATS_RX_PKT_INFO_DISPLAY StatsRxPktInfoDisplay -+ -+#define STATS_TX_TIME_ARRIVE(__Skb__) \ -+do { \ -+ UINT_64 __SysTime; \ -+ __SysTime = StatsEnvTimeGet(); /* us */ \ -+ GLUE_SET_PKT_XTIME(__Skb__, __SysTime); \ -+} while (FALSE) -+ -+#define STATS_TX_TIME_TO_HIF StatsEnvTxTime2Hif -+ -+#define STATS_TX_PKT_CALLBACK StatsTxPktCallBack -+#define STATS_TX_PKT_DONE_INFO_DISPLAY StatsTxPktDoneInfoDisplay -+ -+#define STATS_DRIVER_OWN_RESET() \ -+{ \ -+ u4DrvOwnMax = 0; \ -+} -+#define STATS_DRIVER_OWN_START_RECORD() \ -+{ \ -+ u8DrvOwnStart = StatsEnvTimeGet(); \ -+} -+#define STATS_DRIVER_OWN_END_RECORD() \ -+{ \ -+ u8DrvOwnEnd = StatsEnvTimeGet(); \ -+} -+#define STATS_DRIVER_OWN_STOP() \ -+do { \ -+ UINT32 __Diff; \ -+ __Diff = (UINT32)(u8DrvOwnEnd - u8DrvOwnStart); \ -+ if (__Diff > u4DrvOwnMax) \ -+ u4DrvOwnMax = __Diff; \ -+} while (FALSE) -+ -+#else -+ -+#define STATS_ENV_REPORT_DETECT(__Adapter__, __StaRecIndex__) -+ -+#define STATS_RX_REORDER_FALL_AHEAD_INC(__StaRec__) -+#define STATS_RX_REORDER_FALL_BEHIND_INC(__StaRec__) -+#define STATS_RX_REORDER_HOLE_INC(__StaRec__) -+#define STATS_RX_REORDER_HOLE_TIMEOUT_INC(__StaRec__, __IsTimeout__) -+#define STATS_RX_PASS2OS_INC(__StaRec__, __SwRfb__) -+#define STATS_RX_PKT_INFO_DISPLAY(__Pkt__) -+ -+#define STATS_TX_TIME_ARRIVE(__Skb__) -+#define STATS_TX_TIME_TO_HIF(__MsduInfo__, __HwTxHeader__) -+#define STATS_TX_PKT_CALLBACK(__Pkt__, __fgIsNeedAck__) -+#define STATS_TX_PKT_DONE_INFO_DISPLAY(__Adapter__, __Event__) -+ -+#define STATS_DRIVER_OWN_RESET() -+#define STATS_DRIVER_OWN_START_RECORD() -+#define STATS_DRIVER_OWN_END_RECORD() -+#define STATS_DRIVER_OWN_STOP() -+#endif /* CFG_SUPPORT_STATISTICS */ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E F U N C T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C F U N C T I O N S -+******************************************************************************** -+*/ -+ -+VOID statsEnvReportDetect(ADAPTER_T *prAdapter, UINT8 ucStaRecIndex); -+ -+VOID StatsEnvRxDone(STA_RECORD_T *prStaRec, SW_RFB_T *prSwRfb); -+ -+UINT_64 StatsEnvTimeGet(VOID); -+ -+VOID StatsEnvTxTime2Hif(MSDU_INFO_T *prMsduInfo, HIF_TX_HEADER_T *prHwTxHeader); -+ -+VOID statsEventHandle(GLUE_INFO_T *prGlueInfo, UINT8 *prInBuf, UINT32 u4InBufLen); -+ -+VOID StatsRxPktInfoDisplay(UINT_8 *pPkt); -+ -+VOID StatsTxPktCallBack(UINT_8 *pPkt, P_MSDU_INFO_T prMsduInfo); -+ -+VOID StatsTxPktDoneInfoDisplay(ADAPTER_T *prAdapter, UINT_8 *pucEvtBuf); -+ -+VOID StatsSetCfgTxDone(UINT_16 u2Cfg, BOOLEAN fgSet); -+ -+UINT_16 StatsGetCfgTxDone(VOID); -+ -+/* End of stats.h */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/swcr.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/swcr.h -new file mode 100644 -index 000000000000..50c4b558c2cd ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/swcr.h -@@ -0,0 +1,187 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/mgmt/swcr.h#1 -+*/ -+ -+/*! \file "swcr.h" -+ \brief -+*/ -+ -+/* -+ * -+ */ -+ -+#ifndef _SWCR_H -+#define _SWCR_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "nic_cmd_event.h" -+ -+#if 0 -+extern SWCR_MAP_ENTRY_T g_arRlmArSwCrMap[]; -+#endif -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+#define SWCR_VAR(x) ((VOID *)&x) -+#define SWCR_FUNC(x) ((VOID *)x) -+ -+#define SWCR_T_FUNC BIT(7) -+ -+#define SWCR_L_32 3 -+#define SWCR_L_16 2 -+#define SWCR_L_8 1 -+ -+#define SWCR_READ 0 -+#define SWCR_WRITE 1 -+ -+#define SWCR_MAP_NUM(x) (sizeof(x)/sizeof(x[0])) -+ -+#define SWCR_CR_NUM 7 -+ -+#define SWCR_GET_RW_INDEX(action, rw, index) \ -+do { \ -+ index = action & 0x7F; \ -+ rw = action >> 7; \ -+} while (0) -+ -+extern UINT_32 g_au4SwCr[]; /*: 0: command other: data */ -+ -+typedef VOID(*PFN_SWCR_RW_T) (P_ADAPTER_T prAdapter, UINT_8 ucRead, UINT_16 u2Addr, UINT_32 *pu4Data); -+typedef VOID(*PFN_CMD_RW_T) (P_ADAPTER_T prAdapter, UINT_8 ucCate, UINT_8 ucAction, UINT_8 ucOpt0, UINT_8 ucOpt1); -+ -+typedef struct _SWCR_MAP_ENTRY_T { -+ UINT_16 u2Type; -+ PVOID u4Addr; -+} SWCR_MAP_ENTRY_T, *P_SWCR_MAP_ENTRY_T; -+ -+typedef struct _SWCR_MOD_MAP_ENTRY_T { -+ UINT_8 ucMapNum; -+ P_SWCR_MAP_ENTRY_T prSwCrMap; -+} SWCR_MOD_MAP_ENTRY_T, *P_SWCR_MOD_MAP_ENTRY_T; -+ -+typedef enum _ENUM_SWCR_DBG_TYPE_T { -+ SWCR_DBG_TYPE_ALL = 0, -+ SWCR_DBG_TYPE_TXRX, -+ SWCR_DBG_TYPE_RX_RATES, -+ SWCR_DBG_TYPE_PS, -+ SWCR_DBG_TYPE_NUM -+} ENUM_SWCR_DBG_TYPE_T; -+ -+typedef enum _ENUM_SWCR_DBG_ALL_T { -+ SWCR_DBG_ALL_TX_CNT = 0, -+ SWCR_DBG_ALL_TX_BCN_CNT, -+ SWCR_DBG_ALL_TX_FAILED_CNT, -+ SWCR_DBG_ALL_TX_RETRY_CNT, -+ SWCR_DBG_ALL_TX_AGING_TIMEOUT_CNT, -+ SWCR_DBG_ALL_TX_PS_OVERFLOW_CNT, -+ SWCR_DBG_ALL_TX_MGNT_DROP_CNT, -+ SWCR_DBG_ALL_TX_ERROR_CNT, -+ -+ SWCR_DBG_ALL_RX_CNT, -+ SWCR_DBG_ALL_RX_DROP_CNT, -+ SWCR_DBG_ALL_RX_DUP_DROP_CNT, -+ SWCR_DBG_ALL_RX_TYPE_ERROR_DROP_CNT, -+ SWCR_DBG_ALL_RX_CLASS_ERROR_DROP_CNT, -+ SWCR_DBG_ALL_RX_AMPDU_ERROR_DROP_CNT, -+ -+ SWCR_DBG_ALL_RX_STATUS_ERROR_DROP_CNT, -+ SWCR_DBG_ALL_RX_FORMAT_ERROR_DROP_CNT, -+ SWCR_DBG_ALL_RX_ICV_ERROR_DROP_CNT, -+ SWCR_DBG_ALL_RX_KEY_ERROR_DROP_CNT, -+ SWCR_DBG_ALL_RX_TKIP_ERROR_DROP_CNT, -+ SWCR_DBG_ALL_RX_MIC_ERROR_DROP_CNT, -+ SWCR_DBG_ALL_RX_BIP_ERROR_DROP_CNT, -+ -+ SWCR_DBG_ALL_RX_FCSERR_CNT, -+ SWCR_DBG_ALL_RX_FIFOFULL_CNT, -+ SWCR_DBG_ALL_RX_PFDROP_CNT, -+ -+ SWCR_DBG_ALL_PWR_PS_POLL_CNT, -+ SWCR_DBG_ALL_PWR_TRIGGER_NULL_CNT, -+ SWCR_DBG_ALL_PWR_BCN_IND_CNT, -+ SWCR_DBG_ALL_PWR_BCN_TIMEOUT_CNT, -+ SWCR_DBG_ALL_PWR_PM_STATE0, -+ SWCR_DBG_ALL_PWR_PM_STATE1, -+ SWCR_DBG_ALL_PWR_CUR_PS_PROF0, -+ SWCR_DBG_ALL_PWR_CUR_PS_PROF1, -+ -+ SWCR_DBG_ALL_AR_STA0_RATE, -+ SWCR_DBG_ALL_AR_STA0_BWGI, -+ SWCR_DBG_ALL_AR_STA0_RX_RATE_RCPI, -+ -+ SWCR_DBG_ALL_ROAMING_ENABLE, -+ SWCR_DBG_ALL_ROAMING_ROAM_CNT, -+ SWCR_DBG_ALL_ROAMING_INT_CNT, -+ -+ SWCR_DBG_ALL_BB_RX_MDRDY_CNT, -+ SWCR_DBG_ALL_BB_RX_FCSERR_CNT, -+ SWCR_DBG_ALL_BB_CCK_PD_CNT, -+ SWCR_DBG_ALL_BB_OFDM_PD_CNT, -+ SWCR_DBG_ALL_BB_CCK_SFDERR_CNT, -+ SWCR_DBG_ALL_BB_CCK_SIGERR_CNT, -+ SWCR_DBG_ALL_BB_OFDM_TAGERR_CNT, -+ SWCR_DBG_ALL_BB_OFDM_SIGERR_CNT, -+ -+ SWCR_DBG_ALL_NUM -+} ENUM_SWCR_DBG_ALL_T; -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+VOID swCtrlCmdCategory0(P_ADAPTER_T prAdapter, UINT_8 ucCate, UINT_8 ucAction, UINT_8 ucOpt0, UINT_8 ucOpt1); -+VOID swCtrlCmdCategory1(P_ADAPTER_T prAdapter, UINT_8 ucCate, UINT_8 ucAction, UINT_8 ucOpt0, UINT_8 ucOpt1); -+VOID testPsCmdCategory0(P_ADAPTER_T prAdapter, UINT_8 ucCate, UINT_8 ucAction, UINT_8 ucOpt0, UINT_8 ucOpt1); -+VOID testPsCmdCategory1(P_ADAPTER_T prAdapter, UINT_8 ucCate, UINT_8 ucAction, UINT_8 ucOpt0, UINT_8 ucOpt1); -+void testWNMCmdCategory0(P_ADAPTER_T prAdapter, UINT_8 ucCate, UINT_8 ucAction, UINT_8 ucOpt0, UINT_8 ucOpt1); -+VOID swCtrlSwCr(P_ADAPTER_T prAdapter, UINT_8 ucRead, UINT_16 u2Addr, UINT_32 *pu4Data); -+ -+/* Support Debug */ -+VOID swCrDebugCheck(P_ADAPTER_T prAdapter, P_CMD_SW_DBG_CTRL_T prCmdSwCtrl); -+VOID swCrDebugCheckTimeout(IN P_ADAPTER_T prAdapter, ULONG ulParam); -+VOID swCrDebugQuery(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); -+VOID swCrDebugQueryTimeout(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo); -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+VOID swCrReadWriteCmd(P_ADAPTER_T prAdapter, UINT_8 ucRead, UINT_16 u2Addr, UINT_32 *pu4Data); -+ -+/* Debug Support */ -+VOID swCrFrameCheckEnable(P_ADAPTER_T prAdapter, UINT_32 u4DumpType); -+VOID swCrDebugInit(P_ADAPTER_T prAdapter); -+VOID swCrDebugCheckEnable(P_ADAPTER_T prAdapter, BOOLEAN fgIsEnable, UINT_8 ucType, UINT_32 u4Timeout); -+VOID swCrDebugUninit(P_ADAPTER_T prAdapter); -+ -+#endif -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/tdls.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/tdls.h -new file mode 100644 -index 000000000000..3b6991131d05 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/tdls.h -@@ -0,0 +1,262 @@ -+/* -+** Id: include/tdls.h#1 -+*/ -+ -+/*! \file "tdls.h" -+ \brief This file contains the internal used in TDLS modules -+ for MediaTek Inc. 802.11 Wireless LAN Adapters. -+*/ -+ -+/* -+** Log: tdls.h -+ * -+ * 11 18 2013 vend_samp.lin -+ * NULL -+ * Initial version. -+ * -+ ** -+ */ -+ -+#ifndef _TDLS_H -+#define _TDLS_H -+ -+#if (CFG_SUPPORT_TDLS == 1) -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+#define TDLS_CFG_CMD_TEST 1 -+#define TDLS_CFG_HT_SUP 1 -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+extern int wlanHardStartXmit(struct sk_buff *prSkb, struct net_device *prDev); -+extern BOOLEAN flgTdlsTestExtCapElm; -+extern UINT8 aucTdlsTestExtCapElm[]; -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+typedef struct _TDLS_LINK_HIS_OTHERS_T { -+ BOOLEAN fgIsHt; /* TRUE: HT device */ -+ -+} TDLS_LINK_HIS_OTHERS_T; -+ -+/* command */ -+typedef enum _TDLS_CMD_ID { -+ TDLS_CMD_TEST_TX_FRAME = 0x00, -+ TDLS_CMD_TEST_RCV_FRAME = 0x01, -+ TDLS_CMD_TEST_PEER_ADD = 0x02, -+ TDLS_CMD_TEST_PEER_UPDATE = 0x03, -+ TDLS_CMD_TEST_DATA_FRAME = 0x04, -+ TDLS_CMD_TEST_RCV_NULL = 0x05, -+ TDLS_CMD_MIB_UPDATE = 0x06, -+ TDLS_CMD_TEST_SKIP_TX_FAIL = 0x07, -+ TDLS_CMD_UAPSD_CONF = 0x08, -+ TDLS_CMD_CH_SW_CONF = 0x09, -+ TDLS_CMD_TEST_SKIP_KEEP_ALIVE = 0x0a, -+ TDLS_CMD_TEST_SKIP_CHSW_TIMEOUT = 0x0b, -+ TDLS_CMD_TEST_TX_TDLS_FRAME = 0x0c, -+ TDLS_CMD_TEST_PROHIBIT_SET_IN_AP = 0x0d, -+ TDLS_CMD_TEST_SCAN_DISABLE = 0x0e, -+ TDLS_CMD_TEST_DATA_FRAME_CONT = 0x0f, -+ TDLS_CMD_TEST_CH_SW_PROHIBIT_SET_IN_AP = 0x10, -+ TDLS_CMD_SETUP_CONF = 0x11, -+ TDLS_CMD_INFO = 0x12, -+ TDLS_CMD_TEST_DELAY = 0x13, -+ TDLS_CMD_KEY_INFO = 0x14, -+ TDLS_CMD_TEST_PTI_TX_FAIL = 0x15 -+} TDLS_CMD_ID; -+ -+typedef enum _TDLS_EVENT_HOST_ID { -+ TDLS_HOST_EVENT_TEAR_DOWN = 0x00, /* TDLS_EVENT_HOST_SUBID_TEAR_DOWN */ -+ TDLS_HOST_EVENT_TX_DONE, -+ TDLS_HOST_EVENT_FME_STATUS, /* TDLS_EVENT_HOST_SUBID_SPECIFIC_FRAME */ -+ TDLS_HOST_EVENT_STATISTICS -+} TDLS_EVENT_HOST_ID; -+ -+typedef enum _TDLS_EVENT_HOST_SUBID_TEAR_DOWN { -+ TDLS_HOST_EVENT_TD_PTI_TIMEOUT = 0x00, -+ TDLS_HOST_EVENT_TD_AGE_TIMEOUT, -+ TDLS_HOST_EVENT_TD_PTI_SEND_FAIL, -+ TDLS_HOST_EVENT_TD_PTI_SEND_MAX_FAIL, -+ TDLS_HOST_EVENT_TD_WRONG_NETWORK_IDX, -+ TDLS_HOST_EVENT_TD_NON_STATE3, -+ TDLS_HOST_EVENT_TD_LOST_TEAR_DOWN -+} TDLS_EVENT_HOST_SUBID_TEAR_DOWN; -+ -+typedef enum _TDLS_EVENT_HOST_SUBID_SPECIFIC_FRAME { -+ TDLS_HOST_EVENT_SF_BA, -+ TDLS_HOST_EVENT_SF_BA_OK, -+ TDLS_HOST_EVENT_SF_BA_DECLINE, -+ TDLS_HOST_EVENT_SF_BA_PEER, -+ TDLS_HOST_EVENT_SF_BA_RSP_OK, -+ TDLS_HOST_EVENT_SF_BA_RSP_DECLINE -+} TDLS_EVENT_HOST_SUBID_SPECIFIC_FRAME; -+ -+/* payload specific type in the LLC/SNAP header */ -+#define TDLS_FRM_PAYLOAD_TYPE 2 -+ -+#define TDLS_FRM_CATEGORY 12 -+ -+typedef enum _TDLS_FRM_ACTION_ID { -+ TDLS_FRM_ACTION_SETUP_REQ = 0x00, -+ TDLS_FRM_ACTION_SETUP_RSP, -+ TDLS_FRM_ACTION_CONFIRM, -+ TDLS_FRM_ACTION_TEARDOWN, -+ TDLS_FRM_ACTION_PTI, -+ TDLS_FRM_ACTION_CHAN_SWITCH_REQ, -+ TDLS_FRM_ACTION_CHAN_SWITCH_RSP, -+ TDLS_FRM_ACTION_PEER_PSM_REQ, -+ TDLS_FRM_ACTION_PEER_PSM_RSP, -+ TDLS_FRM_ACTION_PTI_RSP, /* 0x09 */ -+ TDLS_FRM_ACTION_DISCOVERY_REQ, -+ -+ TDLS_FRM_ACTION_EVENT_TEAR_DOWN_TO_SUPPLICANT = 0x30, -+ -+ TDLS_FRM_DATA_TEST_DATA = 0x80 -+} TDLS_FRM_ACTION_ID; -+ -+#define TDLS_FRM_ACTION_DISCOVERY_RESPONSE 14 -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+/* 7.3.2.62 Link Identifier element */ -+#define ELEM_ID_LINK_IDENTIFIER 101 -+#define ELEM_LEN_LINK_IDENTIFIER 18 -+ -+typedef struct _IE_LINK_IDENTIFIER_T { -+ UINT_8 ucId; -+ UINT_8 ucLength; -+ UINT_8 aBSSID[6]; -+ UINT_8 aInitiator[6]; -+ UINT_8 aResponder[6]; -+} __KAL_ATTRIB_PACKED__ IE_LINK_IDENTIFIER_T; -+ -+#define TDLS_LINK_IDENTIFIER_IE(__ie__) ((IE_LINK_IDENTIFIER_T *)(__ie__)) -+ -+/* test command use */ -+typedef struct _PARAM_CUSTOM_TDLS_CMD_STRUCT_T { -+ -+ UINT_8 ucFmeType; /* TDLS_FRM_ACTION_ID */ -+ -+ UINT_8 ucToken; -+ UINT_16 u2Cap; -+ -+ /* bit0: TDLS, bit1: Peer U-APSD Buffer, bit2: Channel Switching */ -+#define TDLS_EX_CAP_PEER_UAPSD BIT(0) -+#define TDLS_EX_CAP_CHAN_SWITCH BIT(1) -+#define TDLS_EX_CAP_TDLS BIT(2) -+ UINT_8 ucExCap; -+ -+ UINT_8 arSupRate[4]; -+ UINT_8 arSupChan[4]; -+ -+ UINT_32 u4Timeout; -+ -+#define TDLS_FME_MAC_ADDR_LEN 6 -+ UINT_8 arRspAddr[TDLS_FME_MAC_ADDR_LEN]; -+ UINT_8 arBssid[TDLS_FME_MAC_ADDR_LEN]; -+ -+/* -+ Linux Kernel-3.10 -+ struct station_parameters { -+ const u8 *supported_rates; -+ struct net_device *vlan; -+ u32 sta_flags_mask, sta_flags_set; -+ u32 sta_modify_mask; -+ int listen_interval; -+ u16 aid; -+ u8 supported_rates_len; -+ u8 plink_action; -+ u8 plink_state; -+ const struct ieee80211_ht_cap *ht_capa; -+ const struct ieee80211_vht_cap *vht_capa; -+ u8 uapsd_queues; -+ u8 max_sp; -+ enum nl80211_mesh_power_mode local_pm; -+ u16 capability; -+ const u8 *ext_capab; -+ u8 ext_capab_len; -+ }; -+*/ -+ struct ieee80211_ht_cap rHtCapa; -+ struct ieee80211_vht_cap rVhtCapa; /* LINUX_KERNEL_VERSION >= 3.10.0 */ -+ struct station_parameters rPeerInfo; -+ -+} PARAM_CUSTOM_TDLS_CMD_STRUCT_T; -+ -+typedef struct _TDLS_MGMT_TX_INFO { -+ UINT8 aucPeer[6]; -+ UINT8 ucActionCode; -+ UINT8 ucDialogToken; -+ UINT16 u2StatusCode; -+ UINT32 u4SecBufLen; -+ UINT8 aucSecBuf[1000]; -+} TDLS_MGMT_TX_INFO; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/* check any TDLS link */ -+#define TDLS_IS_NO_LINK_GOING(__GlueInfo__) \ -+ ((__GlueInfo__)->rTdlsLink.cLinkCnt == 0) -+ -+/* increase TDLS link count */ -+#define TDLS_LINK_INCREASE(__GlueInfo__) \ -+ ((__GlueInfo__)->rTdlsLink.cLinkCnt++) -+ -+/* decrease TDLS link count */ -+#define TDLS_LINK_DECREASE(__GlueInfo__) \ -+do { \ -+ if ((__GlueInfo__)->rTdlsLink.cLinkCnt > 0) \ -+ (__GlueInfo__)->rTdlsLink.cLinkCnt--; \ -+} while (0) -+ -+/* get TDLS link count */ -+#define TDLS_LINK_COUNT(__GlueInfo__) \ -+ ((__GlueInfo__)->rTdlsLink.cLinkCnt) -+ -+/* reset TDLS link count */ -+#define TDLS_LINK_COUNT_RESET(__GlueInfo__) \ -+ ((__GlueInfo__)->rTdlsLink.cLinkCnt = 0) -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+/* Note: these functions are used only in tdls module, not other modules */ -+UINT_32 TdlsFrameGeneralIeAppend(ADAPTER_T *prAdapter, STA_RECORD_T *prStaRec, UINT_16 u2StatusCode, UINT_8 *pPkt); -+ -+TDLS_STATUS -+TdlsDataFrameSend(ADAPTER_T *prAdapter, -+ STA_RECORD_T *prStaRec, -+ UINT_8 *pPeerMac, -+ UINT_8 ucActionCode, -+ UINT_8 ucDialogToken, UINT_16 u2StatusCode, UINT_8 *pAppendIe, UINT_32 AppendIeLen); -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif /* CFG_SUPPORT_TDLS */ -+ -+#endif /* _TDLS_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/wapi.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/wapi.h -new file mode 100644 -index 000000000000..12c9359f2e8f ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/wapi.h -@@ -0,0 +1,104 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/mgmt/wapi.h#1 -+*/ -+ -+/*! \file wapi.h -+ \brief The wapi related define, macro and structure are described here. -+*/ -+ -+/* -+** Log: wapi.h -+ * -+ * 07 20 2010 wh.su -+ * -+ * . -+ * -+ * 01 27 2010 wh.su -+ * [BORA00000476][Wi-Fi][firmware] Add the security module initialize code -+ * add and fixed some security function. -+ * -+ * Dec 8 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * change the wapi function name and adding the generate wapi ie function -+ * -+ * Dec 7 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * adding some wapi structure define -+ * -+ * Nov 23 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * -+** \main\maintrunk.MT5921\1 2009-10-09 17:06:29 GMT mtk01088 -+** -+*/ -+ -+#ifndef _WAPI_H -+#define _WAPI_H -+ -+#if CFG_SUPPORT_WAPI -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+#define WAPI_CIPHER_SUITE_WPI 0x01721400 /* WPI_SMS4 */ -+#define WAPI_AKM_SUITE_802_1X 0x01721400 /* WAI */ -+#define WAPI_AKM_SUITE_PSK 0x02721400 /* WAI_PSK */ -+ -+#define ELEM_ID_WAPI 68 /* WAPI IE */ -+ -+#define WAPI_IE(fp) ((P_WAPI_INFO_ELEM_T) fp) -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+VOID wapiGenerateWAPIIE(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); -+ -+BOOLEAN wapiParseWapiIE(IN P_WAPI_INFO_ELEM_T prInfoElem, OUT P_WAPI_INFO_T prWapiInfo); -+ -+BOOLEAN wapiPerformPolicySelection(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBss); -+ -+/* BOOLEAN */ -+/* wapiUpdateTxKeyIdx ( */ -+/* IN P_STA_RECORD_T prStaRec, */ -+/* IN UINT_8 ucWlanIdx */ -+/* ); */ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+#endif -+#endif /* _WAPI_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/wlan_typedef.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/wlan_typedef.h -new file mode 100644 -index 000000000000..5dc969f1cc05 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/wlan_typedef.h -@@ -0,0 +1,87 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/mgmt/wlan_typedef.h#1 -+*/ -+ -+/*! \file wlan_typedef.h -+ \brief Declaration of data type and return values of internal protocol stack. -+ -+ In this file we declare the data type and return values which will be exported -+ to all MGMT Protocol Stack. -+*/ -+ -+/* -+** Log: wlan_typedef.h -+*/ -+ -+#ifndef _WLAN_TYPEDEF_H -+#define _WLAN_TYPEDEF_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+/* Type definition for BSS_INFO_T structure, to describe the attributes used in a -+ * common BSS. -+ */ -+typedef struct _BSS_INFO_T BSS_INFO_T, *P_BSS_INFO_T; -+ -+typedef BSS_INFO_T AIS_BSS_INFO_T, *P_AIS_BSS_INFO_T; -+typedef BSS_INFO_T P2P_BSS_INFO_T, *P_P2P_BSS_INFO_T; -+typedef BSS_INFO_T BOW_BSS_INFO_T, *P_BOW_BSS_INFO_T; -+ -+typedef struct _AIS_SPECIFIC_BSS_INFO_T AIS_SPECIFIC_BSS_INFO_T, *P_AIS_SPECIFIC_BSS_INFO_T; -+typedef struct _P2P_SPECIFIC_BSS_INFO_T P2P_SPECIFIC_BSS_INFO_T, *P_P2P_SPECIFIC_BSS_INFO_T; -+typedef struct _BOW_SPECIFIC_BSS_INFO_T BOW_SPECIFIC_BSS_INFO_T, *P_BOW_SPECIFIC_BSS_INFO_T; -+/* CFG_SUPPORT_WFD */ -+typedef struct _WFD_CFG_SETTINGS_T WFD_CFG_SETTINGS_T, *P_WFD_CFG_SETTINGS_T; -+ -+typedef struct _WFD_DBG_CFG_SETTINGS_T WFD_DBG_CFG_SETTINGS_T, *P_WFD_DBG_CFG_SETTINGS_T; -+ -+/* BSS related structures */ -+/* Type definition for BSS_DESC_T structure, to describe parameter sets of a particular BSS */ -+typedef struct _BSS_DESC_T BSS_DESC_T, *P_BSS_DESC_T, **PP_BSS_DESC_T; -+ -+#if CFG_SUPPORT_HOTSPOT_2_0 -+typedef struct _HS20_INFO_T HS20_INFO_T, *P_HS20_INFO_T; -+#endif /* CFG_SUPPORT_HOTSPOT_2_0 */ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+#endif /* _WLAN_TYPEDEF_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/wnm.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/wnm.h -new file mode 100644 -index 000000000000..09bc0b5d5151 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/mgmt/wnm.h -@@ -0,0 +1,95 @@ -+/* -+** Id: //Department/DaVinci/TRUNK/MT6620_5931_WiFi_Driver/include/mgmt/wnm.h#1 -+*/ -+ -+/*! \file wnm.h -+ \brief This file contains the IEEE 802.11 family related 802.11v network management -+ for MediaTek 802.11 Wireless LAN Adapters. -+*/ -+ -+/* -+** Log: wnm.h -+ * -+ * 01 05 2012 tsaiyuan.hsu -+ * [WCXRP00001157] [MT6620 Wi-Fi][FW][DRV] add timing measurement support for 802.11v -+ * add timing measurement support for 802.11v. -+ * -+ * -+*/ -+ -+#ifndef _WNM_H -+#define _WNM_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+typedef struct _TIMINGMSMT_PARAM_T { -+ BOOLEAN fgInitiator; -+ UINT_8 ucTrigger; -+ UINT_8 ucDialogToken; /* Dialog Token */ -+ UINT_8 ucFollowUpDialogToken; /* Follow Up Dialog Token */ -+ UINT_32 u4ToD; /* Timestamp of Departure [10ns] */ -+ UINT_32 u4ToA; /* Timestamp of Arrival [10ns] */ -+} TIMINGMSMT_PARAM_T, *P_TIMINGMSMT_PARAM_T; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+WLAN_STATUS -+wnmRunEventTimgingMeasTxDone(IN P_ADAPTER_T prAdapter, -+ IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus); -+ -+VOID -+wnmComposeTimingMeasFrame(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN PFN_TX_DONE_HANDLER pfTxDoneHandler); -+ -+VOID wnmTimingMeasRequest(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); -+ -+VOID wnmWNMAction(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); -+ -+VOID wnmReportTimingMeas(IN P_ADAPTER_T prAdapter, IN UINT_8 ucStaRecIndex, IN UINT_32 u4ToD, IN UINT_32 u4ToA); -+ -+#define WNM_UNIT_TEST 1 -+ -+#if WNM_UNIT_TEST -+VOID wnmTimingMeasUnitTest1(P_ADAPTER_T prAdapter, UINT_8 ucStaRecIndex); -+#endif -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif /* _WNM_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/adapter.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/adapter.h -new file mode 100644 -index 000000000000..d34f2c9c36a8 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/adapter.h -@@ -0,0 +1,1506 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/nic/adapter.h#3 -+*/ -+ -+/*! \file adapter.h -+ \brief Definition of internal data structure for driver manipulation. -+ -+ In this file we define the internal data structure - ADAPTER_T which stands -+ for MiniPort ADAPTER(From Windows point of view) or stands for Network ADAPTER. -+*/ -+ -+/* -+** Log: adapter.h -+** -+** 08 31 2012 yuche.tsai -+** [ALPS00349585] [6577JB][WiFi direct][KE]Establish p2p connection while both device have -+** connected to AP previously,one device reboots automatically with KE -+** Fix possible KE when concurrent & disconnect. -+** -+** 07 26 2012 yuche.tsai -+** [ALPS00324337] [ALPS.JB][Hot-Spot] Driver update for Hot-Spot -+** Update driver code of ALPS.JB for hot-spot. -+ * -+ * 07 17 2012 yuche.tsai -+ * NULL -+ * Let netdev bring up. -+ * -+ * 07 17 2012 yuche.tsai -+ * NULL -+ * Compile no error before trial run. -+ * -+ * 06 13 2012 yuche.tsai -+ * NULL -+ * Update maintrunk driver. -+ * Add support for driver compose assoc request frame. -+ * -+ * 03 02 2012 terry.wu -+ * NULL -+ * Snc CFG80211 modification for ICS migration from branch 2.2. -+ * -+ * 03 02 2012 terry.wu -+ * NULL -+ * Sync CFG80211 modification from branch 2,2. -+ * -+ * 01 16 2012 cp.wu -+ * [MT6620 Wi-Fi][Driver] API and behavior modification for preferred band configuration -+ * with corresponding network configuration -+ * add wlanSetPreferBandByNetwork() for glue layer to invoke for setting preferred band configuration -+ * corresponding to network type. -+ * -+ * 12 13 2011 cm.chang -+ * [WCXRP00001136] [All Wi-Fi][Driver] Add wake lock for pending timer -+ * Add wake lock if timer timeout value is smaller than 5 seconds -+ * -+ * 12 02 2011 yuche.tsai -+ * NULL -+ * Resolve inorder issue under AP mode. -+ * -+ * data frame may TX before assoc response frame. -+ * -+ * 11 19 2011 yuche.tsai -+ * NULL -+ * Update RSSI for P2P. -+ * -+ * 11 18 2011 yuche.tsai -+ * NULL -+ * CONFIG P2P support RSSI query, default turned off. -+ * -+ * 11 11 2011 yuche.tsai -+ * NULL -+ * Fix work thread cancel issue. -+ * -+ * 10 21 2011 eddie.chen -+ * [WCXRP00001051] [MT6620 Wi-Fi][Driver/Fw] Adjust the STA aging timeout -+ * Add switch to ignore the STA aging timeout. -+ * -+ * 10 12 2011 wh.su -+ * [WCXRP00001036] [MT6620 Wi-Fi][Driver][FW] Adding the 802.11w code for MFP -+ * adding the 802.11w related function and define . -+ * -+ * 09 20 2011 cm.chang -+ * [WCXRP00000997] [MT6620 Wi-Fi][Driver][FW] Handle change of BSS preamble type and slot time -+ * Remove ERP member in adapter structure -+ * -+ * 09 14 2011 yuche.tsai -+ * NULL -+ * Add P2P IE in assoc response. -+ * -+ * 08 31 2011 cm.chang -+ * [WCXRP00000969] [MT6620 Wi-Fi][Driver][FW] Channel list for 5G band based on country code -+ * . -+ * -+ * 07 18 2011 chinghwa.yu -+ * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm -+ * Add CMD/Event for RDD and BWCS. -+ * -+ * 06 23 2011 cp.wu -+ * [WCXRP00000812] [MT6620 Wi-Fi][Driver] not show NVRAM when there is no valid MAC address in NVRAM content -+ * check with firmware for valid MAC address. -+ * -+ * 04 18 2011 terry.wu -+ * [WCXRP00000660] [MT6620 Wi-Fi][Driver] Remove flag CFG_WIFI_DIRECT_MOVED -+ * Remove flag CFG_WIFI_DIRECT_MOVED. -+ * -+ * 04 12 2011 cm.chang -+ * [WCXRP00000634] [MT6620 Wi-Fi][Driver][FW] 2nd BSS will not support 40MHz bandwidth for concurrency -+ * . -+ * -+ * 04 08 2011 yuche.tsai -+ * [WCXRP00000624] [Volunteer Patch][MT6620][Driver] Add device discoverability support for GO. -+ * Add device discoverability support. -+ * Action frame callback for GO Device Discoverability Req. -+ * -+ * 04 08 2011 george.huang -+ * [WCXRP00000621] [MT6620 Wi-Fi][Driver] Support P2P supplicant to set power mode -+ * separate settings of P2P and AIS -+ * -+ * 04 08 2011 eddie.chen -+ * [WCXRP00000617] [MT6620 Wi-Fi][DRV/FW] Fix for sigma -+ * Fix for sigma -+ * -+ * 03 19 2011 yuche.tsai -+ * [WCXRP00000584] [Volunteer Patch][MT6620][Driver] Add beacon timeout support for WiFi Direct. -+ * Add beacon timeout support for WiFi Direct Network. -+ * -+ * 03 19 2011 yuche.tsai -+ * [WCXRP00000581] [Volunteer Patch][MT6620][Driver] P2P IE in Assoc Req Issue -+ * Make assoc req to append P2P IE if wifi direct is enabled. -+ * -+ * 03 17 2011 cp.wu -+ * [WCXRP00000562] [MT6620 Wi-Fi][Driver] I/O buffer pre-allocation to avoid physically -+ * continuous memory shortage after system running for a long period -+ * use pre-allocated buffer for storing enhanced interrupt response as well -+ * -+ * 03 15 2011 cp.wu -+ * [WCXRP00000559] [MT6620 Wi-Fi][Driver] Combine TX/RX DMA buffers into a single one to reduce -+ * physically continuous memory consumption -+ * 1. deprecate CFG_HANDLE_IST_IN_SDIO_CALLBACK -+ * 2. Use common coalescing buffer for both TX/RX directions -+ * -+ * -+ * 03 10 2011 yuche.tsai -+ * [WCXRP00000533] [Volunteer Patch][MT6620][Driver] Provide a P2P function API for Legacy WiFi to query AP mode. -+ * Provide an API for Legacy WiFi to query the operation mode.. -+ * -+ * 03 05 2011 wh.su -+ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code -+ * add the code to get the check rsponse and indicate to app. -+ * -+ * 03 02 2011 wh.su -+ * [WCXRP00000448] [MT6620 Wi-Fi][Driver] Fixed WSC IE not send out at probe request -+ * Add code to send beacon and probe response WSC IE at Auto GO. -+ * -+ * 03 02 2011 cp.wu -+ * [WCXRP00000503] [MT6620 Wi-Fi][Driver] Take RCPI brought by association response as -+ * initial RSSI right after connection is built. -+ * use RCPI brought by ASSOC-RESP after connection is built as initial RCPI to avoid -+ * using a uninitialized MAC-RX RCPI. -+ * -+ * 02 21 2011 terry.wu -+ * [WCXRP00000476] [MT6620 Wi-Fi][Driver] Clean P2P scan list while removing P2P -+ * Clean P2P scan list while removing P2P. -+ * -+ * 02 17 2011 eddie.chen -+ * [WCXRP00000458] [MT6620 Wi-Fi][Driver] BOW Concurrent - ProbeResp was exist in other channel -+ * 1) Change GetFrameAction decision when BSS is absent. -+ * 2) Check channel and resource in processing ProbeRequest -+ * -+ * 02 16 2011 cm.chang -+ * [WCXRP00000447] [MT6620 Wi-Fi][FW] Support new NVRAM update mechanism -+ * . -+ * -+ * 02 10 2011 yuche.tsai -+ * [WCXRP00000431] [Volunteer Patch][MT6620][Driver] Add MLME support for deauthentication under AP(Hot-Spot) mode. -+ * Add RX deauthentication & disassociation process under Hot-Spot mode. -+ * -+ * 02 09 2011 wh.su -+ * [WCXRP00000433] [MT6620 Wi-Fi][Driver] Remove WAPI structure define for avoid P2P module -+ * with structure miss-align pointer issue -+ * always pre-allio WAPI related structure for align p2p module. -+ * -+ * 02 08 2011 yuche.tsai -+ * [WCXRP00000419] [Volunteer Patch][MT6620/MT5931][Driver] Provide function of disconnect to -+ * target station for AAA module. -+ * Provide disconnect function for AAA module. -+ * -+ * 02 01 2011 cm.chang -+ * [WCXRP00000415] [MT6620 Wi-Fi][Driver] Check if any memory leakage happens when uninitializing in DGB mode -+ * . -+ * -+ * 01 27 2011 tsaiyuan.hsu -+ * [WCXRP00000392] [MT6620 Wi-Fi][Driver] Add Roaming Support -+ * add roaming fsm -+ * 1. not support 11r, only use strength of signal to determine roaming. -+ * 2. not enable CFG_SUPPORT_ROAMING until completion of full test. -+ * 3. in 6620, adopt work-around to avoid sign extension problem of cck of hw -+ * 4. assume that change of link quality in smooth way. -+ * -+ * 01 27 2011 george.huang -+ * [WCXRP00000400] [MT6620 Wi-Fi] support CTIA power mode setting -+ * Support CTIA power mode setting. -+ * -+ * 01 27 2011 george.huang -+ * [WCXRP00000355] [MT6620 Wi-Fi] Set WMM-PS related setting with qualifying AP capability -+ * Support current measure mode, assigned by registry (XP only). -+ * -+ * 01 24 2011 cp.wu -+ * [WCXRP00000382] [MT6620 Wi-Fi][Driver] Track forwarding packet number with notifying tx thread for serving -+ * 1. add an extra counter for tracking pending forward frames. -+ * 2. notify TX service thread as well when there is pending forward frame -+ * 3. correct build errors leaded by introduction of Wi-Fi direct separation module -+ * -+ * 01 12 2011 cm.chang -+ * [WCXRP00000354] [MT6620 Wi-Fi][Driver][FW] Follow NVRAM bandwidth setting -+ * User-defined bandwidth is for 2.4G and 5G individually -+ * -+ * 12 29 2010 eddie.chen -+ * [WCXRP00000322] Add WMM IE in beacon, -+ -+Add per station flow control when STA is in PS -+ -+ * Add WMM parameter for broadcast. -+ * -+ * 12 29 2010 eddie.chen -+ * [WCXRP00000322] Add WMM IE in beacon, -+ -+Add per station flow control when STA is in PS -+ -+ * Add CWMin CWMax for AP to generate IE. -+ * -+ * 12 29 2010 eddie.chen -+ * [WCXRP00000322] Add WMM IE in beacon, -+Add per station flow control when STA is in PS -+ -+ * 1) PS flow control event -+ * -+ * 2) WMM IE in beacon, assoc resp, probe resp -+ * -+ * 12 28 2010 cp.wu -+ * [WCXRP00000269] [MT6620 Wi-Fi][Driver][Firmware] Prepare for v1.1 branch release -+ * report EEPROM used flag via NIC_CAPABILITY -+ * -+ * 12 28 2010 cp.wu -+ * [WCXRP00000269] [MT6620 Wi-Fi][Driver][Firmware] Prepare for v1.1 branch release -+ * integrate with 'EEPROM used' flag for reporting correct capability to Engineer Mode/META and other tools -+ * -+ * 12 07 2010 cm.chang -+ * [WCXRP00000238] MT6620 Wi-Fi][Driver][FW] Support regulation domain setting from NVRAM and supplicant -+ * 1. Country code is from NVRAM or supplicant -+ * 2. Change band definition in CMD/EVENT. -+ * -+ * 11 01 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000150] [MT6620 Wi-Fi][Driver] -+ * Add implementation for querying current TX rate from firmware auto rate module -+ * 1) Query link speed (TX rate) from firmware directly with buffering mechanism to reduce overhead -+ * 2) Remove CNM CH-RECOVER event handling -+ * 3) cfg read/write API renamed with kal prefix for unified naming rules. -+ * -+ * 10 27 2010 george.huang -+ * [WCXRP00000127] [MT6620 Wi-Fi][Driver] Add a registry to disable Beacon Timeout function for SQA test by using E1 EVB -+ * Support registry option for disable beacon lost detection. -+ * -+ * 10 26 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000137] [MT6620 Wi-Fi] [FW] -+ * Support NIC capability query command -+ * 1) update NVRAM content template to ver 1.02 -+ * 2) add compile option for querying NIC capability (default: off) -+ * 3) modify AIS 5GHz support to run-time option, which could be turned on by registry or NVRAM setting -+ * 4) correct auto-rate compiler error under linux (treat warning as error) -+ * 5) simplify usage of NVRAM and REG_INFO_T -+ * 6) add version checking between driver and firmware -+ * -+ * 10 08 2010 cp.wu -+ * [WCXRP00000084] [MT6620 Wi-Fi][Driver][FW] Add fixed rate support for distance test -+ * adding fixed rate support for distance test. (from registry setting) -+ * -+ * 10 06 2010 cp.wu -+ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning -+ * code reorganization to improve isolation between GLUE and CORE layers. -+ * -+ * 10 05 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check -+ * 1) add NVRAM access API -+ * 2) fake scanning result when NVRAM doesn't exist and/or version mismatch. (off by compiler option) -+ * 3) add OID implementation for NVRAM read/write service -+ * -+ * 09 27 2010 chinghwa.yu -+ * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000065] Update BoW design and settings -+ * Update BCM/BoW design and settings. -+ * -+ * 09 24 2010 cp.wu -+ * [WCXRP00000057] [MT6620 Wi-Fi][Driver] Modify online scan to a run-time switchable feature -+ * Modify online scan as a run-time adjustable option (for Windows, in registry) -+ * -+ * 09 23 2010 cp.wu -+ * [WCXRP00000051] [MT6620 Wi-Fi][Driver] WHQL test fail in MAC address changed item -+ * use firmware reported mac address right after wlanAdapterStart() as permanent address -+ * -+ * 09 08 2010 cp.wu -+ * NULL -+ * use static memory pool for storing IEs of scanning result. -+ * -+ * 09 07 2010 yuche.tsai -+ * NULL -+ * Add a common IE buffer in P2P INFO structure. -+ * -+ * 09 03 2010 kevin.huang -+ * NULL -+ * Refine #include sequence and solve recursive/nested #include issue -+ * -+ * 09 01 2010 cp.wu -+ * NULL -+ * restore configuration as before. -+ * -+ * 09 01 2010 wh.su -+ * NULL -+ * adding the wapi support for integration test. -+ * -+ * 08 31 2010 kevin.huang -+ * NULL -+ * Use LINK LIST operation to process SCAN result -+ * -+ * 08 29 2010 yuche.tsai -+ * NULL -+ * Finish SLT TX/RX & Rate Changing Support. -+ * -+ * 08 25 2010 george.huang -+ * NULL -+ * update OID/ registry control path for PM related settings -+ * -+ * 08 24 2010 cm.chang -+ * NULL -+ * Support RLM initail channel of Ad-hoc, P2P and BOW -+ * -+ * 08 23 2010 chinghwa.yu -+ * NULL -+ * Update for BOW. -+ * -+ * 08 20 2010 cm.chang -+ * NULL -+ * Migrate RLM code to host from FW -+ * -+ * 08 16 2010 yuche.tsai -+ * NULL -+ * Add an intend mode for BSS info. -+ * It is used to let P2P BSS Info to know which OP Mode it is going to become. -+ * -+ * 08 04 2010 george.huang -+ * NULL -+ * handle change PS mode OID/ CMD -+ * -+ * 08 02 2010 cp.wu -+ * NULL -+ * comment out deprecated members in BSS_INFO, which are only used by firmware rather than driver. -+ * -+ * 07 29 2010 cp.wu -+ * NULL -+ * eliminate u4FreqInKHz usage, combined into rConnections.ucAdHoc* -+ * -+ * 07 28 2010 cp.wu -+ * NULL -+ * 1) eliminate redundant variable eOPMode in prAdapter->rWlanInfo -+ * 2) change nicMediaStateChange() API prototype -+ * -+ * 07 24 2010 wh.su -+ * -+ * .support the Wi-Fi RSN -+ * -+ * 07 21 2010 yuche.tsai -+ * -+ * Add for P2P Scan Result Parsing & Saving. -+ * -+ * 07 19 2010 wh.su -+ * -+ * update for security supporting. -+ * -+ * 07 19 2010 cm.chang -+ * -+ * Set RLM parameters and enable CNM channel manager -+ * -+ * 07 19 2010 yuche.tsai -+ * -+ * Remove BSS info which is redonedent in Wifi Var.. -+ * -+ * 07 16 2010 yarco.yang -+ * -+ * 1. Support BSS Absence/Presence Event -+ * 2. Support STA change PS mode Event -+ * 3. Support BMC forwarding for AP mode. -+ * -+ * 07 14 2010 yarco.yang -+ * -+ * 1. Remove CFG_MQM_MIGRATION -+ * 2. Add CMD_UPDATE_WMM_PARMS command -+ * -+ * 07 09 2010 george.huang -+ * -+ * [WPD00001556] Migrate PM variables from FW to driver: for composing QoS Info -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 07 08 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Check draft RLM code for HT cap -+ * -+ * 06 29 2010 yarco.yang -+ * [WPD00003837][MT6620]Data Path Refine -+ * replace g_rQM with Adpater->rQM -+ * -+ * 06 28 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * 1st draft code for RLM module -+ * -+ * 06 21 2010 wh.su -+ * [WPD00003840][MT6620 5931] Security migration -+ * remove duplicate variable for migration. -+ * -+ * 06 21 2010 wh.su -+ * [WPD00003840][MT6620 5931] Security migration -+ * modify some code for concurrent network. -+ * -+ * 06 21 2010 yuche.tsai -+ * [WPD00003839][MT6620 5931][P2P] Feature migration -+ * Add P2P FSM Info in adapter. -+ * -+ * 06 21 2010 yarco.yang -+ * [WPD00003837][MT6620]Data Path Refine -+ * Support CFG_MQM_MIGRATION flag -+ * -+ * 06 18 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Provide cnmMgtPktAlloc() and alloc/free function of msg/buf -+ * -+ * 06 18 2010 wh.su -+ * [WPD00003840][MT6620 5931] Security migration -+ * migration the security related function from firmware. -+ * -+ * 06 17 2010 yuche.tsai -+ * [WPD00003839][MT6620 5931][P2P] Feature migration -+ * Add P2P related field, additional include p2p_fsm.h if p2p is enabled. -+ * -+ * 06 15 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add scan.c. -+ * -+ * 06 14 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add management dispatching function table. -+ * -+ * 06 11 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * auth.c is migrated. -+ * -+ * 06 11 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) migrate assoc.c. -+ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness -+ * 3) add configuration options for CNM_MEM and RSN modules -+ * 4) add data path for management frames -+ * 5) eliminate rPacketInfo of MSDU_INFO_T -+ * -+ * 06 10 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add buildable & linkable ais_fsm.c -+ * -+ * related reference are still waiting to be resolved -+ * -+ * 06 09 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add definitions for module migration. -+ * -+ * 06 08 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * cnm_timer has been migrated. -+ * -+ * 06 08 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * hem_mbox is migrated. -+ * -+ * 06 07 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * merge wifi_var.h, precomp.h, cnm_timer.h (data type only) -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 05 22 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * change OID behavior to meet WHQL requirement. -+ * -+ * 05 20 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) integrate OID_GEN_NETWORK_LAYER_ADDRESSES with CMD_ID_SET_IP_ADDRESS -+ * 2) buffer statistics data for 2 seconds -+ * 3) use default value for adhoc parameters instead of 0 -+ * -+ * 05 19 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) do not take timeout mechanism for power mode oids -+ * 2) retrieve network type from connection status -+ * 3) after disassciation, set radio state to off -+ * 4) TCP option over IPv6 is supported -+ * -+ * 05 18 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * implement Wakeup-on-LAN except firmware integration part -+ * -+ * 04 27 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * reserve field of privacy filter and RTS threshold setting. -+ * -+ * 04 13 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * add framework for BT-over-Wi-Fi support. -+ * * * * * * 1) prPendingCmdInfo is replaced by queue for multiple handler capability -+ * * * * * * 2) command sequence number is now increased atomically -+ * * * * * * 3) private data could be hold and taken use for other purpose -+ * -+ * 04 07 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * rWlanInfo should be placed at adapter rather than glue due to most operations -+ * * * are done in adapter layer. -+ * -+ * 04 06 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * code refine: fgTestMode should be at adapter rather than glue due to the device/fw is also involved -+ * -+ * 03 31 2010 wh.su -+ * [WPD00003816][MT6620 Wi-Fi] Adding the security support -+ * modify the wapi related code for new driver's design. -+ * -+ * 03 19 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) add ACPI D0/D3 state switching support -+ * * * 2) use more formal way to handle interrupt when the status is retrieved from enhanced RX response -+ * -+ * 03 03 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * implement OID_802_3_MULTICAST_LIST oid handling -+ * -+ * 03 02 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) the use of prPendingOid revised, all accessing are now protected by spin lock -+ * * * 2) ensure wlanReleasePendingOid will clear all command queues -+ * -+ * 02 09 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * move ucCmdSeqNum as instance variable -+ * -+ * 01 27 2010 wh.su -+ * [WPD00003816][MT6620 Wi-Fi] Adding the security support -+ * . -+ * -+ * 01 27 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1. eliminate improper variable in rHifInfo -+ * * * 2. block TX/ordinary OID when RF test mode is engaged -+ * * * 3. wait until firmware finish operation when entering into and leaving from RF test mode -+ * * * 4. correct some HAL implementation -+ * -+ * 12 30 2009 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) According to CMD/EVENT documentation v0.8, -+ * * * OID_CUSTOM_TEST_RX_STATUS & OID_CUSTOM_TEST_TX_STATUS is no longer used, -+ * * * and result is retrieved by get ATInfo instead -+ * * * 2) add 4 counter for recording aggregation statistics -+ * -+ * 12 28 2009 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * eliminate redundant variables for connection_state -+** \main\maintrunk.MT6620WiFiDriver_Prj\13 2009-12-16 18:02:03 GMT mtk02752 -+** add external reference to avoid compilation error -+** \main\maintrunk.MT6620WiFiDriver_Prj\12 2009-12-10 16:40:26 GMT mtk02752 -+** eliminate unused member -+** \main\maintrunk.MT6620WiFiDriver_Prj\11 2009-12-08 17:36:08 GMT mtk02752 -+** add RF test data members into P_ADAPTER_T -+** \main\maintrunk.MT6620WiFiDriver_Prj\10 2009-10-13 21:58:45 GMT mtk01084 -+** update for new HW architecture design -+** \main\maintrunk.MT6620WiFiDriver_Prj\9 2009-04-28 10:29:57 GMT mtk01461 -+** Add read WTSR for SDIO_STATUS_ENHANCE mode -+** \main\maintrunk.MT6620WiFiDriver_Prj\8 2009-04-21 09:37:35 GMT mtk01461 -+** Add prPendingCmdInfoOfOID for temporarily saving the CMD_INFO_T before en-queue to rCmdQueue -+** \main\maintrunk.MT6620WiFiDriver_Prj\7 2009-04-17 19:57:51 GMT mtk01461 -+** Add MGMT Buffer Info -+** \main\maintrunk.MT6620WiFiDriver_Prj\6 2009-04-01 10:34:12 GMT mtk01461 -+** Add SW pre test CFG_HIF_LOOPBACK_PRETEST -+** \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-03-23 21:41:48 GMT mtk01461 -+** Add fgIsWmmAssoc flag for TC assignment -+** \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-03-19 18:32:51 GMT mtk01084 -+** update for basic power management functions -+** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-03-18 20:51:52 GMT mtk01426 -+** Add #if CFG_SDIO_RX_ENHANCE related data structure -+** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 20:16:17 GMT mtk01426 -+** Init for develop -+** -+*/ -+ -+#ifndef _ADAPTER_H -+#define _ADAPTER_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#if CFG_SUPPORT_HOTSPOT_2_0 -+#include "hs20.h" -+#endif -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+typedef struct _ENHANCE_MODE_DATA_STRUCT_T SDIO_CTRL_T, *P_SDIO_CTRL_T; -+ -+typedef struct _WLAN_INFO_T { -+ PARAM_BSSID_EX_T rCurrBssId; -+ -+ /* Scan Result */ -+ PARAM_BSSID_EX_T arScanResult[CFG_MAX_NUM_BSS_LIST]; -+ PUINT_8 apucScanResultIEs[CFG_MAX_NUM_BSS_LIST]; -+ UINT_32 u4ScanResultNum; -+ -+ /* IE pool for Scanning Result */ -+ UINT_8 aucScanIEBuf[CFG_MAX_COMMON_IE_BUF_LEN]; -+ UINT_32 u4ScanIEBufferUsage; -+ -+ OS_SYSTIME u4SysTime; -+ -+ /* connection parameter (for Ad-Hoc) */ -+ UINT_16 u2BeaconPeriod; -+ UINT_16 u2AtimWindow; -+ -+ PARAM_RATES eDesiredRates; -+ CMD_LINK_ATTRIB eLinkAttr; -+/* CMD_PS_PROFILE_T ePowerSaveMode; */ -+ CMD_PS_PROFILE_T arPowerSaveMode[NETWORK_TYPE_INDEX_NUM]; -+ -+ /* trigger parameter */ -+ ENUM_RSSI_TRIGGER_TYPE eRssiTriggerType; -+ PARAM_RSSI rRssiTriggerValue; -+ -+ /* Privacy Filter */ -+ ENUM_PARAM_PRIVACY_FILTER_T ePrivacyFilter; -+ -+ /* RTS Threshold */ -+ PARAM_RTS_THRESHOLD eRtsThreshold; -+ -+ /* Network Type */ -+ UINT_8 ucNetworkType; -+ -+ /* Network Type In Use */ -+ UINT_8 ucNetworkTypeInUse; -+ -+} WLAN_INFO_T, *P_WLAN_INFO_T; -+ -+/* Session for CONNECTION SETTINGS */ -+typedef struct _CONNECTION_SETTINGS_T { -+ -+ UINT_8 aucMacAddress[MAC_ADDR_LEN]; -+ -+ UINT_8 ucDelayTimeOfDisconnectEvent; -+ -+ BOOLEAN fgIsConnByBssidIssued; -+ UINT_8 aucBSSID[MAC_ADDR_LEN]; -+ -+ BOOLEAN fgIsConnReqIssued; -+ BOOLEAN fgIsDisconnectedByNonRequest; -+ -+ UINT_8 ucSSIDLen; -+ UINT_8 aucSSID[ELEM_MAX_LEN_SSID]; -+ -+ ENUM_PARAM_OP_MODE_T eOPMode; -+ -+ ENUM_PARAM_CONNECTION_POLICY_T eConnectionPolicy; -+ -+ ENUM_PARAM_AD_HOC_MODE_T eAdHocMode; -+ -+ ENUM_PARAM_AUTH_MODE_T eAuthMode; -+ -+ ENUM_PARAM_ENCRYPTION_STATUS_T eEncStatus; -+ -+ BOOLEAN fgIsScanReqIssued; -+ -+ /* MIB attributes */ -+ UINT_16 u2BeaconPeriod; -+ -+ UINT_16 u2RTSThreshold; /* User desired setting */ -+ -+ UINT_16 u2DesiredNonHTRateSet; /* User desired setting */ -+ -+ UINT_8 ucAdHocChannelNum; /* For AdHoc */ -+ -+ ENUM_BAND_T eAdHocBand; /* For AdHoc */ -+ -+ UINT_32 u4FreqInKHz; /* Center frequency */ -+ -+ /* ATIM windows using for IBSS power saving function */ -+ UINT_16 u2AtimWindow; -+ -+ /* Features */ -+ BOOLEAN fgIsEnableRoaming; -+ -+ BOOLEAN fgIsAdHocQoSEnable; -+ -+ ENUM_PARAM_PHY_CONFIG_T eDesiredPhyConfig; -+ -+ /* Used for AP mode for desired channel and bandwidth */ -+ UINT_16 u2CountryCode; -+ UINT_16 u2CountryCodeBakup; -+ UINT_8 uc2G4BandwidthMode; /* 20/40M or 20M only */ -+ UINT_8 uc5GBandwidthMode; /* 20/40M or 20M only */ -+ -+ BOOLEAN fgTxShortGIDisabled; -+ BOOLEAN fgRxShortGIDisabled; -+ -+#if CFG_SUPPORT_802_11D -+ BOOLEAN fgMultiDomainCapabilityEnabled; -+#endif /* CFG_SUPPORT_802_11D */ -+ -+#if 1 /* CFG_SUPPORT_WAPI */ -+ BOOLEAN fgWapiMode; -+ UINT_32 u4WapiSelectedGroupCipher; -+ UINT_32 u4WapiSelectedPairwiseCipher; -+ UINT_32 u4WapiSelectedAKMSuite; -+#endif -+ -+ /* CR1486, CR1640 */ -+ /* for WPS, disable the privacy check for AP selection policy */ -+ BOOLEAN fgPrivacyCheckDisable; -+ -+ /* b0~3: trigger-en AC0~3. b4~7: delivery-en AC0~3 */ -+ UINT_8 bmfgApsdEnAc; -+ -+ /* for RSN info store, when upper layer set rsn info */ -+ RSN_INFO_T rRsnInfo; -+ -+} CONNECTION_SETTINGS_T, *P_CONNECTION_SETTINGS_T; -+ -+struct _BSS_INFO_T { -+ -+ ENUM_PARAM_MEDIA_STATE_T eConnectionState; /* Connected Flag used in AIS_NORMAL_TR */ -+ ENUM_PARAM_MEDIA_STATE_T eConnectionStateIndicated; /* The Media State that report to HOST */ -+ -+ ENUM_OP_MODE_T eCurrentOPMode; /* Current Operation Mode - Infra/IBSS */ -+#if CFG_ENABLE_WIFI_DIRECT -+ ENUM_OP_MODE_T eIntendOPMode; -+#endif -+ -+ BOOLEAN fgIsNetActive; /* TRUE if this network has been activated */ -+ -+ UINT_8 ucNetTypeIndex; /* ENUM_NETWORK_TYPE_INDEX_T */ -+ -+ UINT_8 ucReasonOfDisconnect; /* Used by media state indication */ -+ -+ UINT_8 ucSSIDLen; /* Length of SSID */ -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ ENUM_HIDDEN_SSID_TYPE_T eHiddenSsidType; /* For Hidden SSID usage. */ -+#endif -+ -+ UINT_8 aucSSID[ELEM_MAX_LEN_SSID]; /* SSID used in this BSS */ -+ -+ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* The BSSID of the associated BSS */ -+ -+ UINT_8 aucOwnMacAddr[MAC_ADDR_LEN]; /* Owned MAC Address used in this BSS */ -+ -+ P_STA_RECORD_T prStaRecOfAP; /* For Infra Mode, and valid only if -+ * eConnectionState == MEDIA_STATE_CONNECTED -+ */ -+ LINK_T rStaRecOfClientList; /* For IBSS/AP Mode, all known STAs in current BSS */ -+ -+ UINT_16 u2CapInfo; /* Change Detection */ -+ -+ UINT_16 u2BeaconInterval; /* The Beacon Interval of this BSS */ -+ -+ UINT_16 u2ATIMWindow; /* For IBSS Mode */ -+ -+ UINT_16 u2AssocId; /* For Infra Mode, it is the Assoc ID assigned by AP. -+ */ -+ -+ UINT_8 ucDTIMPeriod; /* For Infra/AP Mode */ -+ -+ UINT_8 ucDTIMCount; /* For AP Mode, it is the DTIM value we should carried in -+ * the Beacon of next TBTT. -+ */ -+ -+ UINT_8 ucPhyTypeSet; /* Available PHY Type Set of this peer -+ * (This is deduced from received BSS_DESC_T) -+ */ -+ -+ UINT_8 ucNonHTBasicPhyType; /* The Basic PHY Type Index, used to setup Phy Capability */ -+ -+ UINT_8 ucConfigAdHocAPMode; /* The configuration of AdHoc/AP Mode. e.g. 11g or 11b */ -+ -+ UINT_8 ucBeaconTimeoutCount; /* For Infra/AP Mode, it is a threshold of Beacon Lost Count to -+ confirm connection was lost */ -+ -+ BOOLEAN fgHoldSameBssidForIBSS; /* For IBSS Mode, to keep use same BSSID to extend the life cycle of an IBSS */ -+ -+ BOOLEAN fgIsBeaconActivated; /* For AP/IBSS Mode, it is used to indicate that Beacon is sending */ -+ -+ P_MSDU_INFO_T prBeacon; /* For AP/IBSS Mode - Beacon Frame */ -+ -+ BOOLEAN fgIsIBSSMaster; /* For IBSS Mode - To indicate that we can reply ProbeResp Frame. -+ In current TBTT interval */ -+ -+ BOOLEAN fgIsShortPreambleAllowed; /* From Capability Info. of AssocResp Frame -+ AND of Beacon/ProbeResp Frame */ -+ BOOLEAN fgUseShortPreamble; /* Short Preamble is enabled in current BSS. */ -+ BOOLEAN fgUseShortSlotTime; /* Short Slot Time is enabled in current BSS. */ -+ -+ UINT_16 u2OperationalRateSet; /* Operational Rate Set of current BSS */ -+ UINT_16 u2BSSBasicRateSet; /* Basic Rate Set of current BSS */ -+ -+ UINT_8 ucAllSupportedRatesLen; /* Used for composing Beacon Frame in AdHoc or AP Mode */ -+ UINT_8 aucAllSupportedRates[RATE_NUM]; -+ -+ UINT_8 ucAssocClientCnt; /* TODO(Kevin): Number of associated clients */ -+ -+ BOOLEAN fgIsProtection; -+ BOOLEAN fgIsQBSS; /* fgIsWmmBSS; *//* For Infra/AP/IBSS Mode, it is used to indicate if we support WMM in -+ * current BSS. */ -+ BOOLEAN fgIsNetAbsent; /* TRUE: BSS is absent, FALSE: BSS is present */ -+ -+ UINT_32 u4RsnSelectedGroupCipher; -+ UINT_32 u4RsnSelectedPairwiseCipher; -+ UINT_32 u4RsnSelectedAKMSuite; -+ UINT_16 u2RsnSelectedCapInfo; -+ -+ /*------------------------------------------------------------------------*/ -+ /* Power Management related information */ -+ /*------------------------------------------------------------------------*/ -+ PM_PROFILE_SETUP_INFO_T rPmProfSetupInfo; -+ -+ /*------------------------------------------------------------------------*/ -+ /* WMM/QoS related information */ -+ /*------------------------------------------------------------------------*/ -+ UINT_8 ucWmmParamSetCount; /* Used to detect the change of EDCA parameters. For AP mode, -+ the value is used in WMM IE */ -+ -+ AC_QUE_PARMS_T arACQueParms[WMM_AC_INDEX_NUM]; -+ -+ UINT_8 aucCWminLog2ForBcast[WMM_AC_INDEX_NUM]; /* For AP mode, broadcast the CWminLog2 */ -+ UINT_8 aucCWmaxLog2ForBcast[WMM_AC_INDEX_NUM]; /* For AP mode, broadcast the CWmaxLog2 */ -+ AC_QUE_PARMS_T arACQueParmsForBcast[WMM_AC_INDEX_NUM]; /* For AP mode, broadcast the value */ -+ -+ /*------------------------------------------------------------------------*/ -+ /* 802.11n HT operation IE when (prStaRec->ucPhyTypeSet & PHY_TYPE_BIT_HT) */ -+ /* is true. They have the same definition with fields of */ -+ /* information element (CM) */ -+ /*------------------------------------------------------------------------*/ -+ ENUM_BAND_T eBand; -+ UINT_8 ucPrimaryChannel; -+ UINT_8 ucHtOpInfo1; -+ UINT_16 u2HtOpInfo2; -+ UINT_16 u2HtOpInfo3; -+ -+ /*------------------------------------------------------------------------*/ -+ /* Required protection modes (CM) */ -+ /*------------------------------------------------------------------------*/ -+ BOOLEAN fgErpProtectMode; -+ ENUM_HT_PROTECT_MODE_T eHtProtectMode; -+ ENUM_GF_MODE_T eGfOperationMode; -+ ENUM_RIFS_MODE_T eRifsOperationMode; -+ -+ BOOLEAN fgObssErpProtectMode; /* GO only */ -+ ENUM_HT_PROTECT_MODE_T eObssHtProtectMode; /* GO only */ -+ ENUM_GF_MODE_T eObssGfOperationMode; /* GO only */ -+ BOOLEAN fgObssRifsOperationMode; /* GO only */ -+ -+ /*------------------------------------------------------------------------*/ -+ /* OBSS to decide if 20/40M bandwidth is permitted. */ -+ /* The first member indicates the following channel list length. */ -+ /*------------------------------------------------------------------------*/ -+ BOOLEAN fgAssoc40mBwAllowed; -+ BOOLEAN fg40mBwAllowed; -+ ENUM_CHNL_EXT_T eBssSCO; /* Real setting for HW -+ * 20/40M AP mode will always set 40M, -+ * but its OP IE can be changed. -+ */ -+ UINT_8 auc2G_20mReqChnlList[CHNL_LIST_SZ_2G + 1]; -+ UINT_8 auc2G_NonHtChnlList[CHNL_LIST_SZ_2G + 1]; -+ UINT_8 auc2G_PriChnlList[CHNL_LIST_SZ_2G + 1]; -+ UINT_8 auc2G_SecChnlList[CHNL_LIST_SZ_2G + 1]; -+ -+ UINT_8 auc5G_20mReqChnlList[CHNL_LIST_SZ_5G + 1]; -+ UINT_8 auc5G_NonHtChnlList[CHNL_LIST_SZ_5G + 1]; -+ UINT_8 auc5G_PriChnlList[CHNL_LIST_SZ_5G + 1]; -+ UINT_8 auc5G_SecChnlList[CHNL_LIST_SZ_5G + 1]; -+ -+ TIMER_T rObssScanTimer; -+ UINT_16 u2ObssScanInterval; /* in unit of sec */ -+ -+ BOOLEAN fgObssActionForcedTo20M; /* GO only */ -+ BOOLEAN fgObssBeaconForcedTo20M; /* GO only */ -+ -+ /*------------------------------------------------------------------------*/ -+ /* HW Related Fields (Kevin) */ -+ /*------------------------------------------------------------------------*/ -+ UINT_8 ucHwDefaultFixedRateCode; /* The default rate code copied to MAC TX Desc */ -+ UINT_16 u2HwLPWakeupGuardTimeUsec; -+ -+ UINT_8 ucBssFreeQuota; /* The value is updated from FW */ -+#if CFG_ENABLE_GTK_FRAME_FILTER -+ P_IPV4_NETWORK_ADDRESS_LIST prIpV4NetAddrList; -+#endif -+ UINT_16 u2DeauthReason; -+ -+#if (CFG_SUPPORT_TDLS == 1) -+ BOOLEAN fgTdlsIsProhibited; /* TRUE: AP prohibits TDLS links */ -+ BOOLEAN fgTdlsIsChSwProhibited; /* TRUE: AP prohibits TDLS chan switch */ -+#endif /* CFG_SUPPORT_TDLS */ -+}; -+ -+struct _AIS_SPECIFIC_BSS_INFO_T { -+ UINT_8 ucRoamingAuthTypes; /* This value indicate the roaming type used in AIS_JOIN */ -+ -+ BOOLEAN fgIsIBSSActive; -+ -+ /*! \brief Global flag to let arbiter stay at standby and not connect to any network */ -+ BOOLEAN fgCounterMeasure; -+ UINT_8 ucWEPDefaultKeyID; -+ BOOLEAN fgTransmitKeyExist; /* Legacy wep Transmit key exist or not */ -+ -+ /* While Do CounterMeasure procedure, check the EAPoL Error report have send out */ -+ BOOLEAN fgCheckEAPoLTxDone; -+ -+ UINT_32 u4RsnaLastMICFailTime; -+ -+ /* Stored the current bss wpa rsn cap filed, used for roaming policy */ -+ /* UINT_16 u2RsnCap; */ -+ TIMER_T rPreauthenticationTimer; -+ -+ /* By the flow chart of 802.11i, -+ wait 60 sec before associating to same AP -+ or roaming to a new AP -+ or sending data in IBSS, -+ keep a timer for handle the 60 sec counterMeasure */ -+ TIMER_T rRsnaBlockTrafficTimer; -+ TIMER_T rRsnaEAPoLReportTimeoutTimer; -+ -+ /* For Keep the Tx/Rx Mic key for TKIP SW Calculate Mic */ -+ /* This is only one for AIS/AP */ -+ UINT_8 aucTxMicKey[8]; -+ UINT_8 aucRxMicKey[8]; -+ -+ /* Buffer for WPA2 PMKID */ -+ /* The PMKID cache lifetime is expire by media_disconnect_indication */ -+ UINT_32 u4PmkidCandicateCount; -+ PMKID_CANDICATE_T arPmkidCandicate[CFG_MAX_PMKID_CACHE]; -+ UINT_32 u4PmkidCacheCount; -+ PMKID_ENTRY_T arPmkidCache[CFG_MAX_PMKID_CACHE]; -+ BOOLEAN fgIndicatePMKID; -+#if CFG_SUPPORT_802_11W -+ BOOLEAN fgMgmtProtection; -+ UINT_32 u4SaQueryStart; -+ UINT_32 u4SaQueryCount; -+ UINT_8 ucSaQueryTimedOut; -+ PUINT_8 pucSaQueryTransId; -+ TIMER_T rSaQueryTimer; -+ BOOLEAN fgBipKeyInstalled; -+#endif -+}; -+ -+struct _BOW_SPECIFIC_BSS_INFO_T { -+ UINT_16 u2Reserved; /* Reserved for Data Type Check */ -+}; -+ -+#if CFG_SLT_SUPPORT -+typedef struct _SLT_INFO_T { -+ -+ P_BSS_DESC_T prPseudoBssDesc; -+ UINT_16 u2SiteID; -+ UINT_8 ucChannel2G4; -+ UINT_8 ucChannel5G; -+ BOOLEAN fgIsDUT; -+ UINT_32 u4BeaconReceiveCnt; -+ /* ///////Deprecated///////// */ -+ P_STA_RECORD_T prPseudoStaRec; -+} SLT_INFO_T, *P_SLT_INFO_T; -+#endif -+ -+/* Major member variables for WiFi FW operation. -+ Variables within this region will be ready for access after WIFI function is enabled. -+*/ -+typedef struct _WIFI_VAR_T { -+ BOOLEAN fgIsRadioOff; -+ -+ BOOLEAN fgIsEnterD3ReqIssued; -+ -+ BOOLEAN fgDebugCmdResp; -+ -+ CONNECTION_SETTINGS_T rConnSettings; -+ -+ SCAN_INFO_T rScanInfo; -+ -+#if CFG_SUPPORT_ROAMING -+ ROAMING_INFO_T rRoamingInfo; -+#endif /* CFG_SUPPORT_ROAMING */ -+ -+ AIS_FSM_INFO_T rAisFsmInfo; -+ -+ ENUM_PWR_STATE_T aePwrState[NETWORK_TYPE_INDEX_NUM]; -+ -+ BSS_INFO_T arBssInfo[NETWORK_TYPE_INDEX_NUM]; -+ -+ AIS_SPECIFIC_BSS_INFO_T rAisSpecificBssInfo; -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ P_P2P_CONNECTION_SETTINGS_T prP2PConnSettings; -+ -+ P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo; -+ -+ P_P2P_FSM_INFO_T prP2pFsmInfo; -+#endif /* CFG_ENABLE_WIFI_DIRECT */ -+ -+#if CFG_ENABLE_BT_OVER_WIFI -+ BOW_SPECIFIC_BSS_INFO_T rBowSpecificBssInfo; -+ BOW_FSM_INFO_T rBowFsmInfo; -+#endif /* CFG_ENABLE_BT_OVER_WIFI */ -+ -+ DEAUTH_INFO_T arDeauthInfo[MAX_DEAUTH_INFO_COUNT]; -+ -+ /* Current Wi-Fi Settings and Flags */ -+ UINT_8 aucPermanentAddress[MAC_ADDR_LEN]; -+ UINT_8 aucMacAddress[MAC_ADDR_LEN]; -+ UINT_8 aucDeviceAddress[MAC_ADDR_LEN]; -+ UINT_8 aucInterfaceAddress[MAC_ADDR_LEN]; -+ -+ UINT_8 ucAvailablePhyTypeSet; -+ -+ ENUM_PHY_TYPE_INDEX_T eNonHTBasicPhyType2G4; /* Basic Phy Type used by SCN according -+ * to the set of Available PHY Types -+ */ -+ -+ ENUM_PARAM_PREAMBLE_TYPE_T ePreambleType; -+ ENUM_REGISTRY_FIXED_RATE_T eRateSetting; -+ -+ BOOLEAN fgIsShortSlotTimeOptionEnable; -+ /* User desired setting, but will honor the capability of AP */ -+ -+ BOOLEAN fgEnableJoinToHiddenSSID; -+ BOOLEAN fgSupportWZCDisassociation; -+ -+ BOOLEAN fgSupportQoS; -+ BOOLEAN fgSupportAmpduTx; -+ BOOLEAN fgSupportAmpduRx; -+ BOOLEAN fgSupportTspec; -+ BOOLEAN fgSupportUAPSD; -+ BOOLEAN fgSupportULPSMP; -+ UINT_8 u8SupportRxSgi20; /* 0: default 1: enable 2:disble */ -+ UINT_8 u8SupportRxSgi40; -+ UINT_8 u8SupportRxGf; -+ UINT_8 u8SupportRxSTBC; -+#if CFG_SUPPORT_CFG_FILE -+ UINT_8 ucApWpsMode; -+ UINT_8 ucCert11nMode; -+#endif -+#if CFG_SUPPORT_CE_FCC_TXPWR_LIMIT -+ UINT_8 ucCeFccTxPwrLimit; -+ UINT_8 ucCeFccTxPwrLimitCck; -+ UINT_8 ucCeFccTxPwrLimitOfdmHt20; -+ UINT_8 ucCeFccTxPwrLimitHt40; -+#endif -+ -+#if CFG_SLT_SUPPORT -+ SLT_INFO_T rSltInfo; -+#endif -+ -+#if CFG_SUPPORT_HOTSPOT_2_0 -+ HS20_INFO_T rHS20Info; -+#endif -+#if CFG_AUTO_CHANNEL_SEL_SUPPORT -+ PARAM_GET_CHN_LOAD rChnLoadInfo; -+#endif -+ -+} WIFI_VAR_T, *P_WIFI_VAR_T; /* end of _WIFI_VAR_T */ -+ -+/* cnm_timer module */ -+typedef struct { -+ LINK_T rLinkHead; -+ OS_SYSTIME rNextExpiredSysTime; -+ KAL_WAKE_LOCK_T rWakeLock; -+ BOOLEAN fgWakeLocked; -+} ROOT_TIMER, *P_ROOT_TIMER; -+ -+/* FW/DRV/NVRAM version information */ -+typedef struct { -+ -+ /* NVRAM or Registry */ -+ UINT_16 u2Part1CfgOwnVersion; -+ UINT_16 u2Part1CfgPeerVersion; -+ UINT_16 u2Part2CfgOwnVersion; -+ UINT_16 u2Part2CfgPeerVersion; -+ -+ /* Firmware */ -+ UINT_16 u2FwProductID; -+ UINT_16 u2FwOwnVersion; -+ UINT_16 u2FwPeerVersion; -+ -+} WIFI_VER_INFO_T, *P_WIFI_VER_INFO_T; -+ -+#if CFG_ENABLE_WIFI_DIRECT -+/* -+* p2p function pointer structure -+*/ -+ -+typedef struct _P2P_FUNCTION_LINKER { -+ P2P_REMOVE prP2pRemove; -+/* NIC_P2P_MEDIA_STATE_CHANGE prNicP2pMediaStateChange; */ -+/* SCAN_UPDATE_P2P_DEVICE_DESC prScanUpdateP2pDeviceDesc; */ -+/* P2P_FSM_RUN_EVENT_RX_PROBE_RESPONSE_FRAME prP2pFsmRunEventRxProbeResponseFrame; */ -+ P2P_GENERATE_P2P_IE prP2pGenerateWSC_IEForBeacon; -+/* P2P_CALCULATE_WSC_IE_LEN_FOR_PROBE_RSP prP2pCalculateWSC_IELenForProbeRsp; */ -+/* P2P_GENERATE_WSC_IE_FOR_PROBE_RSP prP2pGenerateWSC_IEForProbeRsp; */ -+/* SCAN_REMOVE_P2P_BSS_DESC prScanRemoveP2pBssDesc; */ -+/* P2P_HANDLE_SEC_CHECK_RSP prP2pHandleSecCheckRsp; */ -+ P2P_NET_REGISTER prP2pNetRegister; -+ P2P_NET_UNREGISTER prP2pNetUnregister; -+ P2P_CALCULATE_P2P_IE_LEN prP2pCalculateP2p_IELenForAssocReq; /* All IEs generated from supplicant. */ -+ P2P_GENERATE_P2P_IE prP2pGenerateP2p_IEForAssocReq; /* All IEs generated from supplicant. */ -+} P2P_FUNCTION_LINKER, *P_P2P_FUNCTION_LINKER; -+ -+#endif -+ -+/* -+ *State Machine: -+ *-->STOP: Turn on/off WiFi -+ *-->DISABLE: Screen was off (wlanHandleSystemSuspend) -+ *-->ENABLE: Screen was on (wlanHandleSystemResume) -+ *----->clear DISABLE -+ *-->RUNNING: Screen was on && Tx/Rx was ongoing (wlanHardStartXmit/kalRxIndicatePkts) -+*/ -+struct GL_PER_MON_T { -+ TIMER_T rPerfMonTimer; -+ ULONG ulPerfMonFlag; -+ ULONG ulLastTxBytes; -+ ULONG ulLastRxBytes; -+ ULONG ulP2PLastTxBytes; -+ ULONG ulP2PLastRxBytes; -+ /*in bps*/ -+ ULONG ulThroughput; -+ /*in ms*/ -+ UINT32 u4UpdatePeriod; -+ UINT32 u4TarPerfLevel; -+ UINT32 u4CurrPerfLevel; -+}; -+ -+/* -+ * Major ADAPTER structure -+ * Major data structure for driver operation -+ */ -+struct _ADAPTER_T { -+ UINT_8 ucRevID; -+ -+ UINT_16 u2NicOpChnlNum; -+ -+ BOOLEAN fgIsEnableWMM; -+ BOOLEAN fgIsWmmAssoc; /* This flag is used to indicate that WMM is enable in current BSS */ -+ -+ UINT_32 u4OsPacketFilter; /* packet filter used by OS */ -+ -+#if CFG_TCP_IP_CHKSUM_OFFLOAD -+ UINT_32 u4CSUMFlags; -+#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */ -+ -+ ENUM_BAND_T aePreferBand[NETWORK_TYPE_INDEX_NUM]; -+ -+ /* ADAPTER flags */ -+ UINT_32 u4Flags; -+ UINT_32 u4HwFlags; -+ -+ BOOLEAN fgIsRadioOff; -+ -+ BOOLEAN fgIsEnterD3ReqIssued; -+ -+ UINT_8 aucMacAddress[MAC_ADDR_LEN]; -+ -+ ENUM_PHY_TYPE_INDEX_T eCurrentPhyType; /* Current selection basing on the set of Available PHY Types */ -+ -+#if CFG_COALESCING_BUFFER_SIZE || CFG_SDIO_RX_AGG -+ UINT_32 u4CoalescingBufCachedSize; -+ PUINT_8 pucCoalescingBufCached; -+#endif /* CFG_COALESCING_BUFFER_SIZE */ -+ -+ /* Buffer for CMD_INFO_T, Mgt packet and mailbox message */ -+ BUF_INFO_T rMgtBufInfo; -+ BUF_INFO_T rMsgBufInfo; -+ PUINT_8 pucMgtBufCached; -+ UINT_32 u4MgtBufCachedSize; -+ UINT_8 aucMsgBuf[MSG_BUFFER_SIZE]; -+#if CFG_DBG_MGT_BUF -+ UINT_32 u4MemAllocDynamicCount; /* Debug only */ -+ UINT_32 u4MemFreeDynamicCount; /* Debug only */ -+#endif -+ -+ STA_RECORD_T arStaRec[CFG_STA_REC_NUM]; -+ -+ /* Element for TX PATH */ -+ TX_CTRL_T rTxCtrl; -+ QUE_T rFreeCmdList; -+ CMD_INFO_T arHifCmdDesc[CFG_TX_MAX_CMD_PKT_NUM]; -+ -+ /* Element for RX PATH */ -+ RX_CTRL_T rRxCtrl; -+ -+ P_SDIO_CTRL_T prSDIOCtrl; -+ -+#if (MT6620_E1_ASIC_HIFSYS_WORKAROUND == 1) -+ /* Element for MT6620 E1 HIFSYS workaround */ -+ BOOLEAN fgIsClockGatingEnabled; -+#endif -+ -+ /* Buffer for Authentication Event */ -+ /* Move to glue layer and refine the kal function */ -+ /* Reference to rsnGeneratePmkidIndication function at rsn.c */ -+ UINT_8 aucIndicationEventBuffer[(CFG_MAX_PMKID_CACHE * 20) + 8]; -+ -+ UINT_32 u4IntStatus; -+ -+ ENUM_ACPI_STATE_T rAcpiState; -+ -+ BOOLEAN fgIsIntEnable; -+ BOOLEAN fgIsIntEnableWithLPOwnSet; -+ -+ BOOLEAN fgIsFwOwn; -+ BOOLEAN fgWiFiInSleepyState; -+ -+ UINT_32 u4PwrCtrlBlockCnt; -+ -+ QUE_T rPendingCmdQueue; -+ -+ P_GLUE_INFO_T prGlueInfo; -+ -+ UINT_8 ucCmdSeqNum; -+ UINT_8 ucTxSeqNum; -+ -+#if 1 /* CFG_SUPPORT_WAPI */ -+ BOOLEAN fgUseWapi; -+#endif -+ -+ /* RF Test flags */ -+ BOOLEAN fgTestMode; -+ -+ /* WLAN Info for DRIVER_CORE OID query */ -+ WLAN_INFO_T rWlanInfo; -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ BOOLEAN fgIsP2PRegistered; -+ ENUM_NET_REG_STATE_T rP2PNetRegState; -+ BOOLEAN fgIsWlanLaunched; -+ P_P2P_INFO_T prP2pInfo; -+#if CFG_SUPPORT_P2P_RSSI_QUERY -+ OS_SYSTIME rP2pLinkQualityUpdateTime; -+ BOOLEAN fgIsP2pLinkQualityValid; -+ EVENT_LINK_QUALITY rP2pLinkQuality; -+#endif -+ -+ /* FSM Timer */ -+ TIMER_T rP2pFsmTimeoutTimer; -+#endif -+ -+ /* Online Scan Option */ -+ BOOLEAN fgEnOnlineScan; -+ -+ /* Online Scan Option */ -+ BOOLEAN fgDisBcnLostDetection; -+ -+ /* MAC address */ -+ PARAM_MAC_ADDRESS rMyMacAddr; -+ -+ /* Wake-up Event for WOL */ -+ UINT_32 u4WakeupEventEnable; -+ -+ /* Event Buffering */ -+ EVENT_STATISTICS rStatStruct; -+ OS_SYSTIME rStatUpdateTime; -+ BOOLEAN fgIsStatValid; -+ -+ EVENT_LINK_QUALITY rLinkQuality; -+ OS_SYSTIME rLinkQualityUpdateTime; -+ BOOLEAN fgIsLinkQualityValid; -+ OS_SYSTIME rLinkRateUpdateTime; -+ BOOLEAN fgIsLinkRateValid; -+ -+ /* WIFI_VAR_T */ -+ WIFI_VAR_T rWifiVar; -+ -+ /* MTK WLAN NIC driver IEEE 802.11 MIB */ -+ IEEE_802_11_MIB_T rMib; -+ -+ /* Mailboxs for inter-module communication */ -+ MBOX_T arMbox[MBOX_ID_TOTAL_NUM]; -+ -+ /* Timers for OID Pending Handling */ -+ TIMER_T rOidTimeoutTimer; -+ -+ TIMER_T rReturnIndicatedRfbListTimer; -+ -+ /* Root Timer for cnm_timer module */ -+ ROOT_TIMER rRootTimer; -+ -+ /* RLM maintenance */ -+ ENUM_CHNL_EXT_T eRfSco; -+ ENUM_SYS_PROTECT_MODE_T eSysProtectMode; -+ ENUM_GF_MODE_T eSysHtGfMode; -+ ENUM_RIFS_MODE_T eSysTxRifsMode; -+ ENUM_SYS_PCO_PHASE_T eSysPcoPhase; -+ -+ P_DOMAIN_INFO_ENTRY prDomainInfo; -+ -+ /* QM */ -+ QUE_MGT_T rQM; -+ -+ CNM_INFO_T rCnmInfo; -+ -+ UINT_32 u4PowerMode; -+ -+ UINT_32 u4CtiaPowerMode; -+ BOOLEAN fgEnCtiaPowerMode; -+ -+ UINT_32 fgEnArpFilter; -+ -+ UINT_32 u4UapsdAcBmp; -+ -+ UINT_32 u4MaxSpLen; -+ -+ UINT_32 u4PsCurrentMeasureEn; -+ -+ /* Version Information */ -+ WIFI_VER_INFO_T rVerInfo; -+ -+ /* 5GHz support (from F/W) */ -+ BOOLEAN fgIsHw5GBandDisabled; -+ BOOLEAN fgEnable5GBand; -+ BOOLEAN fgIsEepromUsed; -+ BOOLEAN fgIsEfuseValid; -+ BOOLEAN fgIsEmbbededMacAddrValid; -+ -+#if CFG_SUPPORT_PWR_LIMIT_COUNTRY -+ BOOLEAN fgIsPowerLimitTableValid; -+#endif -+ -+ /* Packet Forwarding Tracking */ -+ INT_32 i4PendingFwdFrameCount; -+ -+#if CFG_SUPPORT_RDD_TEST_MODE -+ UINT_8 ucRddStatus; -+#endif -+ -+ BOOLEAN fgDisStaAgingTimeoutDetection; -+#if CFG_SUPPORT_CFG_FILE -+ P_WLAN_CFG_T prWlanCfg; -+ WLAN_CFG_T rWlanCfg; -+#endif -+#if CFG_SPM_WORKAROUND_FOR_HOTSPOT -+ KAL_WAKE_LOCK_T rApWakeLock; -+#endif -+ UINT_32 u4FwCompileFlag0; -+ UINT_32 u4FwCompileFlag1; -+ KAL_WAKE_LOCK_T rTxThreadWakeLock; -+ KAL_WAKE_LOCK_T rAhbIsrWakeLock; -+ -+#if CFG_SUPPORT_ROAMING_ENC -+ BOOLEAN fgIsRoamingEncEnabled; -+#endif /* CFG_SUPPORT_ROAMING_ENC */ -+ -+#if (CFG_SUPPORT_TDLS == 1) -+ BOOLEAN fgTdlsIsSup; -+#endif /* CFG_SUPPORT_TDLS */ -+ -+ UINT_8 ucScanTime; -+ -+#if CFG_SUPPORT_DBG_POWERMODE -+ BOOLEAN fgEnDbgPowerMode; /* dbg privilege power mode, always keep in active */ -+#endif -+ -+ UINT_32 u4AirDelayTotal; /* dbg privilege power mode, always keep in active */ -+ ULONG ulSuspendFlag; -+ struct GL_PER_MON_T rPerMonitor; -+}; /* end of _ADAPTER_T */ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+#define SUSPEND_FLAG_FOR_WAKEUP_REASON (0) -+#define SUSPEND_FLAG_CLEAR_WHEN_RESUME (1) -+ -+/*----------------------------------------------------------------------------*/ -+/* Macros for BSS_INFO_T - Flag of Net Active */ -+/*----------------------------------------------------------------------------*/ -+#define IS_NET_ACTIVE(_prAdapter, _NetTypeIndex) \ -+ (_prAdapter->rWifiVar.arBssInfo[(_NetTypeIndex)].fgIsNetActive) -+#define IS_BSS_ACTIVE(_prBssInfo) ((_prBssInfo)->fgIsNetActive) -+ -+#define IS_AIS_ACTIVE(_prAdapter) IS_NET_ACTIVE(_prAdapter, NETWORK_TYPE_AIS_INDEX) -+#define IS_P2P_ACTIVE(_prAdapter) IS_NET_ACTIVE(_prAdapter, NETWORK_TYPE_P2P_INDEX) -+#define IS_BOW_ACTIVE(_prAdapter) IS_NET_ACTIVE(_prAdapter, NETWORK_TYPE_BOW_INDEX) -+ -+#define SET_NET_ACTIVE(_prAdapter, _NetTypeIndex) \ -+ {_prAdapter->rWifiVar.arBssInfo[(_NetTypeIndex)].fgIsNetActive = TRUE; } -+ -+#define UNSET_NET_ACTIVE(_prAdapter, _NetTypeIndex) \ -+ {_prAdapter->rWifiVar.arBssInfo[(_NetTypeIndex)].fgIsNetActive = FALSE; } -+ -+#define BSS_INFO_INIT(_prAdapter, _NetTypeIndex) \ -+ { UINT_8 _aucZeroMacAddr[] = NULL_MAC_ADDR; \ -+ P_BSS_INFO_T _prBssInfo = &(_prAdapter->rWifiVar.arBssInfo[(_NetTypeIndex)]); \ -+ \ -+ _prBssInfo->eConnectionState = PARAM_MEDIA_STATE_DISCONNECTED; \ -+ _prBssInfo->eConnectionStateIndicated = PARAM_MEDIA_STATE_DISCONNECTED; \ -+ _prBssInfo->eCurrentOPMode = OP_MODE_INFRASTRUCTURE; \ -+ _prBssInfo->fgIsNetActive = FALSE; \ -+ _prBssInfo->ucNetTypeIndex = (_NetTypeIndex); \ -+ _prBssInfo->ucReasonOfDisconnect = DISCONNECT_REASON_CODE_RESERVED; \ -+ COPY_MAC_ADDR(_prBssInfo->aucBSSID, _aucZeroMacAddr); \ -+ LINK_INITIALIZE(&_prBssInfo->rStaRecOfClientList); \ -+ _prBssInfo->fgIsBeaconActivated = FALSE; \ -+ _prBssInfo->ucHwDefaultFixedRateCode = RATE_CCK_1M_LONG; \ -+ _prBssInfo->fgIsNetAbsent = FALSE; \ -+ } -+ -+#if CFG_ENABLE_BT_OVER_WIFI -+#define BOW_BSS_INFO_INIT(_prAdapter, _NetTypeIndex) \ -+ { \ -+ P_BSS_INFO_T _prBssInfo = &(_prAdapter->rWifiVar.arBssInfo[(_NetTypeIndex)]); \ -+ \ -+ _prBssInfo->eConnectionState = PARAM_MEDIA_STATE_DISCONNECTED; \ -+ _prBssInfo->eConnectionStateIndicated = PARAM_MEDIA_STATE_DISCONNECTED; \ -+ _prBssInfo->eCurrentOPMode = OP_MODE_BOW; \ -+ _prBssInfo->ucNetTypeIndex = (_NetTypeIndex); \ -+ _prBssInfo->ucReasonOfDisconnect = DISCONNECT_REASON_CODE_RESERVED; \ -+ LINK_INITIALIZE(&_prBssInfo->rStaRecOfClientList); \ -+ _prBssInfo->fgIsBeaconActivated = TRUE; \ -+ _prBssInfo->ucHwDefaultFixedRateCode = RATE_CCK_1M_LONG; \ -+ _prBssInfo->fgIsNetAbsent = FALSE; \ -+ } -+#endif -+ -+#define PERF_MON_DISABLE_BIT_OFF (0) -+#define PERF_MON_STOP_BIT_OFF (1) -+#define PERF_MON_RUNNING_BIT_OFF (2) -+ -+#define THROUGHPUT_L1_THRESHOLD (20*1024*1024) -+#define THROUGHPUT_L2_THRESHOLD (60*1024*1024) -+#define THROUGHPUT_L3_THRESHOLD (135*1024*1024) -+ -+/*----------------------------------------------------------------------------*/ -+/* Macros for Power State */ -+/*----------------------------------------------------------------------------*/ -+#define SET_NET_PWR_STATE_IDLE(_prAdapter, _NetTypeIndex) \ -+ {_prAdapter->rWifiVar.aePwrState[(_NetTypeIndex)] = PWR_STATE_IDLE; } -+ -+#define SET_NET_PWR_STATE_ACTIVE(_prAdapter, _NetTypeIndex) \ -+ {_prAdapter->rWifiVar.aePwrState[(_NetTypeIndex)] = PWR_STATE_ACTIVE; } -+ -+#define SET_NET_PWR_STATE_PS(_prAdapter, _NetTypeIndex) \ -+ {_prAdapter->rWifiVar.aePwrState[(_NetTypeIndex)] = PWR_STATE_PS; } -+ -+#define IS_NET_PWR_STATE_ACTIVE(_prAdapter, _NetTypeIndex) \ -+ (_prAdapter->rWifiVar.aePwrState[(_NetTypeIndex)] == PWR_STATE_ACTIVE) -+ -+#define IS_NET_PWR_STATE_IDLE(_prAdapter, _NetTypeIndex) \ -+ (_prAdapter->rWifiVar.aePwrState[(_NetTypeIndex)] == PWR_STATE_IDLE) -+ -+#define IS_SCN_PWR_STATE_ACTIVE(_prAdapter) \ -+ (_prAdapter->rWifiVar.rScanInfo.eScanPwrState == SCAN_PWR_STATE_ACTIVE) -+ -+#define IS_SCN_PWR_STATE_IDLE(_prAdapter) \ -+ (_prAdapter->rWifiVar.rScanInfo.eScanPwrState == SCAN_PWR_STATE_IDLE) -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif /* _ADAPTER_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/bow.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/bow.h -new file mode 100644 -index 000000000000..6c4c1b76622b ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/bow.h -@@ -0,0 +1,322 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/nic/bow.h#1 -+*/ -+ -+/* -+** Log: bow.h -+ * -+ * 01 16 2012 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Support BOW for 5GHz band. -+ * -+ * 05 25 2011 terry.wu -+ * [WCXRP00000735] [MT6620 Wi-Fi][BoW][FW/Driver] Protect BoW connection establishment -+ * Add BoW Cancel Scan Request and Turn On deactive network function. -+ * -+ * 05 22 2011 terry.wu -+ * [WCXRP00000735] [MT6620 Wi-Fi][BoW][FW/Driver] Protect BoW connection establishment -+ * Submit missing BoW header files. -+ * -+ * 03 27 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Support multiple physical link. -+ * -+ * 03 06 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Sync BOW Driver to latest person development branch version.. -+ * -+ * 02 10 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Fix kernel API change issue. -+ * Before ALPS 2.2 (2.2 included), kfifo_alloc() is -+ * struct kfifo *kfifo_alloc(unsigned int size, gfp_t gfp_mask, spinlock_t *lock); -+ * After ALPS 2.3, kfifo_alloc() is changed to -+ * int kfifo_alloc(struct kfifo *fifo, unsigned int size, gfp_t gfp_mask); -+ * -+ * 02 10 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Update BOW structure. -+ * -+ * 02 09 2011 cp.wu -+ * [WCXRP00000430] [MT6620 Wi-Fi][Firmware][Driver] Create V1.2 branch for MT6620E1 and MT6620E3 -+ * create V1.2 driver branch based on label MT6620_WIFI_DRIVER_V1_2_110209_1031 -+ * with BOW and P2P enabled as default -+ * -+ * 02 08 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Replace kfifo_get and kfifo_put with kfifo_out and kfifo_in. -+ * Update BOW get MAC status, remove returning event for AIS network type. -+ * -+ * 01 11 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Add Activity Report definition. -+ * -+ * 10 18 2010 chinghwa.yu -+ * [WCXRP00000110] [MT6620 Wi-Fi] [Driver] Fix BoW Connected event size -+ * Fix wrong BoW event size. -+ * -+ * 07 15 2010 cp.wu -+ * -+ * sync. bluetooth-over-Wi-Fi interface to driver interface document v0.2.6. -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 05 13 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * 1) all BT physical handles shares the same RSSI/Link Quality. -+ * 2) simplify BT command composing -+ * -+ * 04 28 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * change prefix for data structure used to communicate with 802.11 PAL -+ * to avoid ambiguous naming with firmware interface -+ * -+ * 04 27 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * basic implementation for EVENT_BT_OVER_WIFI -+ * -+ * 04 13 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * add framework for BT-over-Wi-Fi support. -+ * * * * * * * 1) prPendingCmdInfo is replaced by queue for multiple handler capability -+ * * * * * * * 2) command sequence number is now increased atomically -+ * * * * * * * 3) private data could be hold and taken use for other purpose -+ * -+ * 04 09 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * sync. with design document for interface change. -+ * -+ * 04 02 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * Wi-Fi driver no longer needs to implement 802.11 PAL, thus replaced by wrapping command/event definitions -+ * -+ * 03 16 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * correct typo. -+ * -+ * 03 16 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * update for all command/event needed to be supported by 802.11 PAL. -+ * -+ * 03 16 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * build up basic data structure and definitions to support BT-over-WiFi -+ * -+*/ -+ -+#ifndef _BOW_H_ -+#define _BOW_H_ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+#define BOWDEVNAME "bow0" -+ -+#define MAX_BOW_NUMBER_OF_CHANNEL_2G4 14 -+#define MAX_BOW_NUMBER_OF_CHANNEL_5G 4 -+/* (MAX_BOW_NUMBER_OF_CHANNEL_2G4 + MAX_BOW_NUMBER_OF_CHANNEL_5G) */ -+#define MAX_BOW_NUMBER_OF_CHANNEL 18 -+ -+#define MAX_ACTIVITY_REPORT 2 -+#define MAX_ACTIVITY_REPROT_TIME 660 -+ -+#define ACTIVITY_REPORT_STATUS_SUCCESS 0 -+#define ACTIVITY_REPORT_STATUS_FAILURE 1 -+#define ACTIVITY_REPORT_STATUS_TIME_INVALID 2 -+#define ACTIVITY_REPORT_STATUS_OTHERS 3 -+ -+#define ACTIVITY_REPORT_SCHEDULE_UNKNOWN 0 /* Does not know the schedule of the interference */ -+#define ACTIVITY_REPORT_SCHEDULE_KNOWN 1 -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+typedef struct _BT_OVER_WIFI_COMMAND_HEADER_T { -+ UINT_8 ucCommandId; -+ UINT_8 ucSeqNumber; -+ UINT_16 u2PayloadLength; -+} AMPC_COMMAND_HEADER_T, *P_AMPC_COMMAND_HEADER_T; -+ -+typedef struct _BT_OVER_WIFI_COMMAND { -+ AMPC_COMMAND_HEADER_T rHeader; -+ UINT_8 aucPayload[0]; -+} AMPC_COMMAND, *P_AMPC_COMMAND; -+ -+typedef struct _BT_OVER_WIFI_EVENT_HEADER_T { -+ UINT_8 ucEventId; -+ UINT_8 ucSeqNumber; -+ UINT_16 u2PayloadLength; -+} AMPC_EVENT_HEADER_T, *P_AMPC_EVENT_HEADER_T; -+ -+typedef struct _BT_OVER_WIFI_EVENT { -+ AMPC_EVENT_HEADER_T rHeader; -+ UINT_8 aucPayload[0]; -+} AMPC_EVENT, *P_AMPC_EVENT; -+ -+typedef struct _CHANNEL_DESC_T { -+ UINT_8 ucChannelBand; -+ UINT_8 ucChannelNum; -+} CHANNEL_DESC, P_CHANNEL_DESC; -+ -+/* Command Structures */ -+typedef struct _BOW_SETUP_CONNECTION { -+/* Fixed to 2.4G */ -+ UINT_8 ucChannelNum; -+ UINT_8 ucReserved1; -+ UINT_8 aucPeerAddress[6]; -+ UINT_16 u2BeaconInterval; -+ UINT_8 ucTimeoutDiscovery; -+ UINT_8 ucTimeoutInactivity; -+ UINT_8 ucRole; -+ UINT_8 ucPAL_Capabilities; -+ INT_8 cMaxTxPower; -+ UINT_8 ucReserved2; -+ -+/* Pending, for future BOW 5G supporting. */ -+/* UINT_8 aucPeerAddress[6]; -+ UINT_16 u2BeaconInterval; -+ UINT_8 ucTimeoutDiscovery; -+ UINT_8 ucTimeoutInactivity; -+ UINT_8 ucRole; -+ UINT_8 ucPAL_Capabilities; -+ INT_8 cMaxTxPower; -+ UINT_8 ucChannelListNum; -+ CHANNEL_DESC arChannelList[1]; -+*/ -+} BOW_SETUP_CONNECTION, *P_BOW_SETUP_CONNECTION; -+ -+typedef struct _BOW_DESTROY_CONNECTION { -+ UINT_8 aucPeerAddress[6]; -+ UINT_8 aucReserved[2]; -+} BOW_DESTROY_CONNECTION, *P_BOW_DESTROY_CONNECTION; -+ -+typedef struct _BOW_SET_PTK { -+ UINT_8 aucPeerAddress[6]; -+ UINT_8 aucReserved[2]; -+ UINT_8 aucTemporalKey[16]; -+} BOW_SET_PTK, *P_BOW_SET_PTK; -+ -+typedef struct _BOW_READ_RSSI { -+ UINT_8 aucPeerAddress[6]; -+ UINT_8 aucReserved[2]; -+} BOW_READ_RSSI, *P_BOW_READ_RSSI; -+ -+typedef struct _BOW_READ_LINK_QUALITY { -+ UINT_8 aucPeerAddress[6]; -+ UINT_8 aucReserved[2]; -+} BOW_READ_LINK_QUALITY, *P_BOW_READ_LINK_QUALITY; -+ -+typedef struct _BOW_SHORT_RANGE_MODE { -+ UINT_8 aucPeerAddress[6]; -+ INT_8 cTxPower; -+ UINT_8 ucReserved; -+} BOW_SHORT_RANGE_MODE, *P_BOW_SHORT_RANGE_MODE; -+ -+/* Event Structures */ -+typedef struct _BOW_COMMAND_STATUS { -+ UINT_8 ucStatus; -+ UINT_8 ucReserved[3]; -+} BOW_COMMAND_STATUS, *P_BOW_COMMAND_STATUS; -+ -+typedef struct _BOW_MAC_STATUS { -+ UINT_8 aucMacAddr[6]; -+ UINT_8 ucAvailability; -+ UINT_8 ucNumOfChannel; -+ CHANNEL_DESC arChannelList[MAX_BOW_NUMBER_OF_CHANNEL]; -+} BOW_MAC_STATUS, *P_BOW_MAC_STATUS; -+ -+typedef struct _BOW_LINK_CONNECTED { -+ CHANNEL_DESC rChannel; -+ UINT_8 aucReserved; -+ UINT_8 aucPeerAddress[6]; -+} BOW_LINK_CONNECTED, *P_BOW_LINK_CONNECTED; -+ -+typedef struct _BOW_LINK_DISCONNECTED { -+ UINT_8 ucReason; -+ UINT_8 aucReserved; -+ UINT_8 aucPeerAddress[6]; -+} BOW_LINK_DISCONNECTED, *P_BOW_LINK_DISCONNECTED; -+ -+typedef struct _BOW_RSSI { -+ INT_8 cRssi; -+ UINT_8 aucReserved[3]; -+} BOW_RSSI, *P_BOW_RSSI; -+ -+typedef struct _BOW_LINK_QUALITY { -+ UINT_8 ucLinkQuality; -+ UINT_8 aucReserved[3]; -+} BOW_LINK_QUALITY, *P_BOW_LINK_QUALITY; -+ -+typedef enum _ENUM_BOW_CMD_ID_T { -+ BOW_CMD_ID_GET_MAC_STATUS = 1, -+ BOW_CMD_ID_SETUP_CONNECTION, -+ BOW_CMD_ID_DESTROY_CONNECTION, -+ BOW_CMD_ID_SET_PTK, -+ BOW_CMD_ID_READ_RSSI, -+ BOW_CMD_ID_READ_LINK_QUALITY, -+ BOW_CMD_ID_SHORT_RANGE_MODE, -+ BOW_CMD_ID_GET_CHANNEL_LIST, -+} ENUM_BOW_CMD_ID_T, *P_ENUM_BOW_CMD_ID_T; -+ -+typedef enum _ENUM_BOW_EVENT_ID_T { -+ BOW_EVENT_ID_COMMAND_STATUS = 1, -+ BOW_EVENT_ID_MAC_STATUS, -+ BOW_EVENT_ID_LINK_CONNECTED, -+ BOW_EVENT_ID_LINK_DISCONNECTED, -+ BOW_EVENT_ID_RSSI, -+ BOW_EVENT_ID_LINK_QUALITY, -+ BOW_EVENT_ID_CHANNEL_LIST, -+ BOW_EVENT_ID_CHANNEL_SELECTED, -+} ENUM_BOW_EVENT_ID_T, *P_ENUM_BOW_EVENT_ID_T; -+ -+typedef enum _ENUM_BOW_DEVICE_STATE { -+ BOW_DEVICE_STATE_DISCONNECTED = 0, -+ BOW_DEVICE_STATE_DISCONNECTING, -+ BOW_DEVICE_STATE_ACQUIRING_CHANNEL, -+ BOW_DEVICE_STATE_STARTING, -+ BOW_DEVICE_STATE_SCANNING, -+ BOW_DEVICE_STATE_CONNECTING, -+ BOW_DEVICE_STATE_CONNECTED, -+ BOW_DEVICE_STATE_NUM -+} ENUM_BOW_DEVICE_STATE, *P_ENUM_BOW_DEVICE_STATE; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+#endif /*_BOW_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/cmd_buf.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/cmd_buf.h -new file mode 100644 -index 000000000000..c1ecb303b877 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/cmd_buf.h -@@ -0,0 +1,150 @@ -+/* -+** Id: -+*/ -+ -+/*! \file "cmd_buf.h" -+ \brief In this file we define the structure for Command Packet. -+ -+ In this file we define the structure for Command Packet and the control unit -+ of MGMT Memory Pool. -+*/ -+ -+/* -+** Log: cmd_buf.h -+ * -+ * 10 04 2010 cp.wu -+ * [WCXRP00000077] [MT6620 Wi-Fi][Driver][FW] Eliminate use of ENUM_NETWORK_TYPE_T and replaced by -+ * ENUM_NETWORK_TYPE_INDEX_T only -+ * remove ENUM_NETWORK_TYPE_T definitions -+ * -+ * 09 03 2010 kevin.huang -+ * NULL -+ * Refine #include sequence and solve recursive/nested #include issue -+ * -+ * 07 13 2010 cp.wu -+ * -+ * 1) MMPDUs are now sent to MT6620 by CMD queue for keeping strict order of 1X/MMPDU/CMD packets -+ * 2) integrate with qmGetFrameAction() for deciding which MMPDU/1X could pass checking for sending -+ * 2) enhance CMD_INFO_T descriptor number from 10 to 32 to avoid descriptor underflow -+ * under concurrent network operation -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 07 01 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Enable change log -+*/ -+ -+#ifndef _CMD_BUF_H -+#define _CMD_BUF_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+typedef enum _COMMAND_TYPE { -+ COMMAND_TYPE_GENERAL_IOCTL, -+ COMMAND_TYPE_NETWORK_IOCTL, -+ COMMAND_TYPE_SECURITY_FRAME, -+ COMMAND_TYPE_MANAGEMENT_FRAME, -+ COMMAND_TYPE_NUM -+} COMMAND_TYPE, *P_COMMAND_TYPE; -+ -+typedef VOID(*PFN_CMD_DONE_HANDLER) (IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); -+ -+typedef VOID(*PFN_CMD_TIMEOUT_HANDLER) (IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo); -+ -+struct _CMD_INFO_T { -+ QUE_ENTRY_T rQueEntry; -+ -+ COMMAND_TYPE eCmdType; -+ -+ UINT_16 u2InfoBufLen; /* This is actual CMD buffer length */ -+ PUINT_8 pucInfoBuffer; /* May pointer to structure in prAdapter */ -+ P_NATIVE_PACKET prPacket; /* only valid when it's a security frame */ -+ -+ ENUM_NETWORK_TYPE_INDEX_T eNetworkType; -+ UINT_8 ucStaRecIndex; /* only valid when it's a security frame */ -+ -+ PFN_CMD_DONE_HANDLER pfCmdDoneHandler; -+ PFN_CMD_TIMEOUT_HANDLER pfCmdTimeoutHandler; -+ -+ BOOLEAN fgIsOid; /* Used to check if we need indicate */ -+ -+ UINT_8 ucCID; -+ BOOLEAN fgSetQuery; -+ BOOLEAN fgNeedResp; -+ BOOLEAN fgDriverDomainMCR; /* Access Driver Domain MCR, for CMD_ID_ACCESS_REG only */ -+ UINT_8 ucCmdSeqNum; -+ UINT_32 u4SetInfoLen; /* Indicate how many byte we read for Set OID */ -+ -+ /* information indicating by OID/ioctl */ -+ PVOID pvInformationBuffer; -+ UINT_32 u4InformationBufferLength; -+ -+ /* private data */ -+ UINT_32 u4PrivateData; -+}; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+VOID cmdBufInitialize(IN P_ADAPTER_T prAdapter); -+ -+P_CMD_INFO_T cmdBufAllocateCmdInfo(IN P_ADAPTER_T prAdapter, IN UINT_32 u4Length); -+ -+VOID cmdBufFreeCmdInfo(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo); -+ -+/*----------------------------------------------------------------------------*/ -+/* Routines for CMDs */ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanSendSetQueryCmd(IN P_ADAPTER_T prAdapter, -+ UINT_8 ucCID, -+ BOOLEAN fgSetQuery, -+ BOOLEAN fgNeedResp, -+ BOOLEAN fgIsOid, -+ PFN_CMD_DONE_HANDLER pfCmdDoneHandler, -+ PFN_CMD_TIMEOUT_HANDLER pfCmdTimeoutHandler, -+ UINT_32 u4SetQueryInfoLen, -+ PUINT_8 pucInfoBuffer, OUT PVOID pvSetQueryBuffer, IN UINT_32 u4SetQueryBufferLen); -+VOID cmdBufDumpCmdQueue(P_QUE_T prQueue, CHAR *queName); -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+#endif /* _CMD_BUF_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/hal.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/hal.h -new file mode 100644 -index 000000000000..0fdb9dcadeef ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/hal.h -@@ -0,0 +1,618 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/nic/hal.h#1 -+*/ -+ -+/*! \file "hal.h" -+ \brief The declaration of hal functions -+ -+ N/A -+*/ -+ -+/* -+** Log: hal.h -+ * -+ * 04 01 2011 tsaiyuan.hsu -+ * [WCXRP00000615] [MT 6620 Wi-Fi][Driver] Fix klocwork issues -+ * fix the klocwork issues, 57500, 57501, 57502 and 57503. -+ * -+ * 03 21 2011 cp.wu -+ * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer -+ * portability improvement -+ * -+ * 03 07 2011 terry.wu -+ * [WCXRP00000521] [MT6620 Wi-Fi][Driver] Remove non-standard debug message -+ * Toggle non-standard debug messages to comments. -+ * -+ * 11 08 2010 cp.wu -+ * [WCXRP00000166] [MT6620 Wi-Fi][Driver] use SDIO CMD52 for enabling/disabling interrupt to reduce transaction period -+ * change to use CMD52 for enabling/disabling interrupt to reduce SDIO transaction time -+ * -+ * 09 01 2010 cp.wu -+ * NULL -+ * move HIF CR initialization from where after sdioSetupCardFeature() to wlanAdapterStart() -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 15 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * change zero-padding for TX port access to HAL. -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 04 06 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * eliminate direct access for prGlueInfo->fgIsCardRemoved in non-glue layer -+ * -+ * 01 27 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1. eliminate improper variable in rHifInfo -+ * * * * 2. block TX/ordinary OID when RF test mode is engaged -+ * * * * 3. wait until firmware finish operation when entering into and leaving from RF test mode -+ * * * * 4. correct some HAL implementation -+** \main\maintrunk.MT6620WiFiDriver_Prj\17 2009-12-16 18:02:26 GMT mtk02752 -+** include precomp.h -+** \main\maintrunk.MT6620WiFiDriver_Prj\16 2009-12-10 16:43:16 GMT mtk02752 -+** code clean -+** \main\maintrunk.MT6620WiFiDriver_Prj\15 2009-11-13 13:54:15 GMT mtk01084 -+** \main\maintrunk.MT6620WiFiDriver_Prj\14 2009-11-11 10:36:01 GMT mtk01084 -+** modify HAL functions -+** \main\maintrunk.MT6620WiFiDriver_Prj\13 2009-11-09 22:56:28 GMT mtk01084 -+** modify HW access routines -+** \main\maintrunk.MT6620WiFiDriver_Prj\12 2009-10-29 19:50:09 GMT mtk01084 -+** add new macro HAL_TX_PORT_WR -+** \main\maintrunk.MT6620WiFiDriver_Prj\11 2009-10-23 16:08:10 GMT mtk01084 -+** \main\maintrunk.MT6620WiFiDriver_Prj\10 2009-10-13 21:58:50 GMT mtk01084 -+** update for new HW architecture design -+** \main\maintrunk.MT6620WiFiDriver_Prj\9 2009-05-18 14:28:10 GMT mtk01084 -+** fix issue in HAL_DRIVER_OWN_BY_SDIO_CMD52() -+** \main\maintrunk.MT6620WiFiDriver_Prj\8 2009-05-11 17:26:33 GMT mtk01084 -+** modify the bit definition to check driver own status -+** \main\maintrunk.MT6620WiFiDriver_Prj\7 2009-04-28 10:30:22 GMT mtk01461 -+** Fix typo -+** \main\maintrunk.MT6620WiFiDriver_Prj\6 2009-04-01 10:50:34 GMT mtk01461 -+** Redefine HAL_PORT_RD/WR macro for SW pre test -+** \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-03-24 09:46:49 GMT mtk01084 -+** fix LINT error -+** \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-03-23 16:53:38 GMT mtk01084 -+** add HAL_DRIVER_OWN_BY_SDIO_CMD52() -+** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-03-18 20:53:13 GMT mtk01426 -+** Fixed lint warn -+** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 20:16:20 GMT mtk01426 -+** Init for develop -+** -+*/ -+ -+#ifndef _HAL_H -+#define _HAL_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/* Macros for flag operations for the Adapter structure */ -+#define HAL_SET_FLAG(_M, _F) ((_M)->u4HwFlags |= (_F)) -+#define HAL_CLEAR_FLAG(_M, _F) ((_M)->u4HwFlags &= ~(_F)) -+#define HAL_TEST_FLAG(_M, _F) ((_M)->u4HwFlags & (_F)) -+#define HAL_TEST_FLAGS(_M, _F) (((_M)->u4HwFlags & (_F)) == (_F)) -+ -+#if defined(_HIF_SDIO) -+#define HAL_MCR_RD(_prAdapter, _u4Offset, _pu4Value) \ -+do { \ -+ if (HAL_TEST_FLAG(_prAdapter, ADAPTER_FLAG_HW_ERR) == FALSE) { \ -+ if (_prAdapter->rAcpiState == ACPI_STATE_D3) { \ -+ ASSERT(0); \ -+ } \ -+ if (kalDevRegRead(_prAdapter->prGlueInfo, _u4Offset, _pu4Value) == FALSE) {\ -+ HAL_SET_FLAG(_prAdapter, ADAPTER_FLAG_HW_ERR); \ -+ fgIsBusAccessFailed = TRUE; \ -+ /* DBGLOG(HAL, ERROR, ("HAL_MCR_RD access fail! 0x%x: 0x%x\n", */ \ -+ /* (UINT32)_u4Offset, (UINT32)*_pu4Value)); */ \ -+ } \ -+ } else { \ -+ /* DBGLOG(HAL, WARN, ("ignore HAL_MCR_RD access! 0x%x\n", (UINT32)_u4Offset)); */ \ -+ } \ -+} while (0) -+ -+#define HAL_MCR_WR(_prAdapter, _u4Offset, _u4Value) \ -+do { \ -+ if (HAL_TEST_FLAG(_prAdapter, ADAPTER_FLAG_HW_ERR) == FALSE) { \ -+ if (_prAdapter->rAcpiState == ACPI_STATE_D3) { \ -+ ASSERT(0); \ -+ } \ -+ if (kalDevRegWrite(_prAdapter->prGlueInfo, _u4Offset, _u4Value) == FALSE) {\ -+ HAL_SET_FLAG(_prAdapter, ADAPTER_FLAG_HW_ERR); \ -+ fgIsBusAccessFailed = TRUE; \ -+ /* DBGLOG(HAL, ERROR, ("HAL_MCR_WR access fail! 0x%x: 0x%x\n", */ \ -+ /* (UINT32)_u4Offset, (UINT32)_u4Value)); */ \ -+ } \ -+ } else { \ -+ /* DBGLOG(HAL, WARN, ("ignore HAL_MCR_WR access! 0x%x: 0x%x\n", */ \ -+ /* (UINT32)_u4Offset, (UINT32)_u4Value)); */ \ -+ } \ -+} while (0) -+ -+#define HAL_PORT_RD(_prAdapter, _u4Port, _u4Len, _pucBuf, _u4ValidBufSize) \ -+{ \ -+ /*fgResult = FALSE; */\ -+ if (_prAdapter->rAcpiState == ACPI_STATE_D3) { \ -+ ASSERT(0); \ -+ } \ -+ if (HAL_TEST_FLAG(_prAdapter, ADAPTER_FLAG_HW_ERR) == FALSE) { \ -+ if (kalDevPortRead(_prAdapter->prGlueInfo, _u4Port, _u4Len, _pucBuf, _u4ValidBufSize) \ -+ == FALSE) {\ -+ HAL_SET_FLAG(_prAdapter, ADAPTER_FLAG_HW_ERR); \ -+ fgIsBusAccessFailed = TRUE; \ -+ DBGLOG(HAL, ERROR, "HAL_PORT_RD access fail! 0x%x\n", _u4Port); \ -+ } \ -+ else { \ -+ /*fgResult = TRUE;*/ } \ -+ } else { \ -+ DBGLOG(HAL, WARN, "ignore HAL_PORT_RD access! 0x%x\n", _u4Port); \ -+ } \ -+} -+ -+#define HAL_PORT_WR(_prAdapter, _u4Port, _u4Len, _pucBuf, _u4ValidBufSize) \ -+{ \ -+ /*fgResult = FALSE; */\ -+ if (_prAdapter->rAcpiState == ACPI_STATE_D3) { \ -+ ASSERT(0); \ -+ } \ -+ if (HAL_TEST_FLAG(_prAdapter, ADAPTER_FLAG_HW_ERR) == FALSE) { \ -+ if (kalDevPortWrite(_prAdapter->prGlueInfo, _u4Port, _u4Len, _pucBuf, _u4ValidBufSize) \ -+ == FALSE) {\ -+ HAL_SET_FLAG(_prAdapter, ADAPTER_FLAG_HW_ERR); \ -+ fgIsBusAccessFailed = TRUE; \ -+ DBGLOG(HAL, ERROR, "HAL_PORT_WR access fail! 0x%x\n", _u4Port); \ -+ } \ -+ else { \ -+ /*fgResult = TRUE;*/ } \ -+ } else { \ -+ DBGLOG(HAL, WARN, "ignore HAL_PORT_WR access! 0x%x\n", _u4Port); \ -+ } \ -+} -+ -+#if 0 /* only for SDIO */ -+#define HAL_BYTE_WR(_prAdapter, _u4Port, _ucBuf) \ -+{ \ -+ if (_prAdapter->rAcpiState == ACPI_STATE_D3) { \ -+ ASSERT(0); \ -+ } \ -+ if (HAL_TEST_FLAG(_prAdapter, ADAPTER_FLAG_HW_ERR) == FALSE) { \ -+ if (kalDevWriteWithSdioCmd52(_prAdapter->prGlueInfo, _u4Port, _ucBuf) == FALSE) {\ -+ HAL_SET_FLAG(_prAdapter, ADAPTER_FLAG_HW_ERR); \ -+ fgIsBusAccessFailed = TRUE; \ -+ DBGLOG(HAL, ERROR, "HAL_BYTE_WR access fail! 0x%x\n", _u4Port); \ -+ } \ -+ else { \ -+ /* Todo:: Nothing*/ \ -+ } \ -+ } \ -+ else { \ -+ DBGLOG(HAL, WARN, "ignore HAL_BYTE_WR access! 0x%x\n", _u4Port); \ -+ } \ -+} -+#endif -+ -+#define HAL_DRIVER_OWN_BY_SDIO_CMD52(_prAdapter, _pfgDriverIsOwnReady) \ -+{ \ -+ UINT_8 ucBuf = BIT(1); \ -+ if (_prAdapter->rAcpiState == ACPI_STATE_D3) { \ -+ ASSERT(0); \ -+ } \ -+ if (HAL_TEST_FLAG(_prAdapter, ADAPTER_FLAG_HW_ERR) == FALSE) { \ -+ if (kalDevReadAfterWriteWithSdioCmd52(_prAdapter->prGlueInfo, MCR_WHLPCR_BYTE1, &ucBuf, 1) \ -+ == FALSE) {\ -+ HAL_SET_FLAG(_prAdapter, ADAPTER_FLAG_HW_ERR); \ -+ fgIsBusAccessFailed = TRUE; \ -+ DBGLOG(HAL, ERROR, "kalDevReadAfterWriteWithSdioCmd52 access fail!\n"); \ -+ } \ -+ else { \ -+ *_pfgDriverIsOwnReady = (ucBuf & BIT(0)) ? TRUE : FALSE; \ -+ } \ -+ } else { \ -+ DBGLOG(HAL, WARN, "ignore HAL_DRIVER_OWN_BY_SDIO_CMD52 access!\n"); \ -+ } \ -+} -+ -+#else /* #if defined(_HIF_SDIO) */ -+#define HAL_MCR_RD(_prAdapter, _u4Offset, _pu4Value) \ -+{ \ -+ if (_prAdapter->rAcpiState == ACPI_STATE_D3) { \ -+ ASSERT(0); \ -+ } \ -+ if (kalDevRegRead(_prAdapter->prGlueInfo, _u4Offset, _pu4Value) \ -+ == FALSE) \ -+ fgIsBusAccessFailed = TRUE; \ -+} -+ -+#define HAL_MCR_WR(_prAdapter, _u4Offset, _u4Value) \ -+{ \ -+ if (_prAdapter->rAcpiState == ACPI_STATE_D3) { \ -+ ASSERT(0); \ -+ } \ -+ if (kalDevRegWrite(_prAdapter->prGlueInfo, _u4Offset, _u4Value) \ -+ == FALSE) \ -+ fgIsBusAccessFailed = TRUE; \ -+} -+ -+#define HAL_PORT_RD(_prAdapter, _u4Port, _u4Len, _pucBuf, _u4ValidBufSize) \ -+{ \ -+ if (_prAdapter->rAcpiState == ACPI_STATE_D3) { \ -+ ASSERT(0); \ -+ } \ -+ if (kalDevPortRead(_prAdapter->prGlueInfo, _u4Port, _u4Len, _pucBuf, _u4ValidBufSize) \ -+ == FALSE) \ -+ fgIsBusAccessFailed = TRUE; \ -+} -+ -+#define HAL_PORT_WR(_prAdapter, _u4Port, _u4Len, _pucBuf, _u4ValidBufSize) \ -+{ \ -+ if (_prAdapter->rAcpiState == ACPI_STATE_D3) { \ -+ ASSERT(0); \ -+ } \ -+ if (kalDevPortWrite(_prAdapter->prGlueInfo, _u4Port, _u4Len, _pucBuf, _u4ValidBufSize) \ -+ == FALSE) \ -+ fgIsBusAccessFailed = TRUE; \ -+} -+ -+#if 0 /* only for SDIO */ -+#define HAL_BYTE_WR(_prAdapter, _u4Port, _ucBuf) \ -+{ \ -+ if (_prAdapter->rAcpiState == ACPI_STATE_D3) { \ -+ ASSERT(0); \ -+ } \ -+kalDevWriteWithSdioCmd52(_prAdapter->prGlueInfo, _u4Port, _ucBuf); \ -+} -+#endif -+ -+#endif /* #if defined(_HIF_SDIO) */ -+ -+#define HAL_READ_RX_PORT(prAdapter, u4PortId, u4Len, pvBuf, _u4ValidBufSize) \ -+{ \ -+ ASSERT(u4PortId < 2); \ -+ HAL_PORT_RD(prAdapter, \ -+ ((u4PortId == 0) ? MCR_WRDR0 : MCR_WRDR1), \ -+ u4Len, \ -+ pvBuf, \ -+ _u4ValidBufSize/*temp!!*//*4Kbyte*/); \ -+} -+ -+#define HAL_WRITE_TX_PORT(_prAdapter, _ucTxPortIdx, _u4Len, _pucBuf, _u4ValidBufSize) \ -+{ \ -+ ASSERT(_ucTxPortIdx < 2); \ -+ if ((_u4ValidBufSize - _u4Len) >= sizeof(UINT_32)) { \ -+ /* fill with single dword of zero as TX-aggregation termination */ \ -+ *(PUINT_32) (&((_pucBuf)[ALIGN_4(_u4Len)])) = 0; \ -+ } \ -+ HAL_PORT_WR(_prAdapter, \ -+ (_ucTxPortIdx == 0) ? MCR_WTDR0 : MCR_WTDR1, \ -+ _u4Len, \ -+ _pucBuf, \ -+ _u4ValidBufSize/*temp!!*//*4KByte*/); \ -+} -+ -+/* The macro to read the given MCR several times to check if the wait -+ condition come true. */ -+#define HAL_MCR_RD_AND_WAIT(_pAdapter, _offset, _pReadValue, _waitCondition, _waitDelay, _waitCount, _status) \ -+{ \ -+ UINT_32 count; \ -+ (_status) = FALSE; \ -+ for (count = 0; count < (_waitCount); count++) { \ -+ HAL_MCR_RD((_pAdapter), (_offset), (_pReadValue)); \ -+ if ((_waitCondition)) { \ -+ (_status) = TRUE; \ -+ break; \ -+ } \ -+ kalUdelay((_waitDelay)); \ -+ } \ -+} -+ -+/* The macro to write 1 to a R/S bit and read it several times to check if the -+ command is done */ -+#define HAL_MCR_WR_AND_WAIT(_pAdapter, _offset, _writeValue, _busyMask, _waitDelay, _waitCount, _status) \ -+{ \ -+ UINT_32 u4Temp; \ -+ UINT_32 u4Count = _waitCount; \ -+ (_status) = FALSE; \ -+ HAL_MCR_WR((_pAdapter), (_offset), (_writeValue)); \ -+ do { \ -+ kalUdelay((_waitDelay)); \ -+ HAL_MCR_RD((_pAdapter), (_offset), &u4Temp); \ -+ if (!(u4Temp & (_busyMask))) { \ -+ (_status) = TRUE; \ -+ break; \ -+ } \ -+ u4Count--; \ -+ } while (u4Count); \ -+} -+ -+#define HAL_GET_CHIP_ID_VER(_prAdapter, pu2ChipId, pu2Version) \ -+{ \ -+ UINT_32 u4Value; \ -+ HAL_MCR_RD(_prAdapter, \ -+ MCR_WCIR, \ -+ &u4Value); \ -+ *pu2ChipId = (UINT_16)(u4Value & WCIR_CHIP_ID); \ -+ *pu2Version = (UINT_16)(u4Value & WCIR_REVISION_ID) >> 16; \ -+} -+ -+#define HAL_WAIT_WIFI_FUNC_READY(_prAdapter) \ -+{ \ -+ UINT_32 u4Value; \ -+ UINT_32 i; \ -+ for (i = 0; i < 100; i++) { \ -+ HAL_MCR_RD(_prAdapter, \ -+ MCR_WCIR, \ -+ &u4Value); \ -+ if (u4Value & WCIR_WLAN_READY) { \ -+ break; \ -+ } \ -+ NdisMSleep(10); \ -+ } \ -+} -+ -+#define HAL_INTR_DISABLE(_prAdapter) \ -+ HAL_MCR_WR(_prAdapter, \ -+ MCR_WHLPCR, \ -+ WHLPCR_INT_EN_CLR) -+ -+#define HAL_INTR_ENABLE(_prAdapter) \ -+ HAL_MCR_WR(_prAdapter, \ -+ MCR_WHLPCR, \ -+ WHLPCR_INT_EN_SET) -+ -+#define HAL_INTR_ENABLE_AND_LP_OWN_SET(_prAdapter) \ -+ HAL_MCR_WR(_prAdapter, \ -+ MCR_WHLPCR, \ -+ (WHLPCR_INT_EN_SET | WHLPCR_FW_OWN_REQ_SET)) -+ -+#define HAL_LP_OWN_SET(_prAdapter) \ -+ HAL_MCR_WR(_prAdapter, \ -+ MCR_WHLPCR, \ -+ WHLPCR_FW_OWN_REQ_SET) -+ -+#define HAL_LP_OWN_CLR_OK(_prAdapter, _pfgResult) \ -+{ \ -+ UINT_32 i; \ -+ UINT_32 u4RegValue; \ -+ UINT_32 u4LoopCnt = 2048 / 8; \ -+ *_pfgResult = TRUE; \ -+ /* Software get LP ownership */ \ -+ HAL_MCR_WR(_prAdapter, \ -+ MCR_WHLPCR, \ -+ WHLPCR_FW_OWN_REQ_CLR) \ -+ for (i = 0; i < u4LoopCnt; i++) { \ -+ HAL_MCR_RD(_prAdapter, MCR_WHLPCR, &u4RegValue); \ -+ if (u4RegValue & WHLPCR_IS_DRIVER_OWN) { \ -+ break; \ -+ } \ -+ else { \ -+ kalUdelay(8); \ -+ } \ -+ } \ -+ if (i == u4LoopCnt) { \ -+ *_pfgResult = FALSE; \ -+ /*ERRORLOG(("LP cannot be own back (%ld)", u4LoopCnt));*/ \ -+ /* check the time of LP instructions need to perform from Sleep to On */ \ -+ /*ASSERT(0); */ \ -+ } \ -+} -+ -+#define HAL_GET_ABNORMAL_INTERRUPT_REASON_CODE(_prAdapter, pu4AbnormalReason) \ -+{ \ -+ HAL_MCR_RD(_prAdapter, \ -+ MCR_WASR, \ -+ pu4AbnormalReason); \ -+} -+ -+#define HAL_DISABLE_RX_ENHANCE_MODE(_prAdapter) \ -+{ \ -+ UINT_32 u4Value; \ -+ HAL_MCR_RD(_prAdapter, \ -+ MCR_WHCR, \ -+ &u4Value); \ -+ HAL_MCR_WR(_prAdapter, \ -+ MCR_WHCR, \ -+ u4Value & ~WHCR_RX_ENHANCE_MODE_EN); \ -+} -+ -+#define HAL_ENABLE_RX_ENHANCE_MODE(_prAdapter) \ -+{ \ -+ UINT_32 u4Value; \ -+ HAL_MCR_RD(_prAdapter, \ -+ MCR_WHCR, \ -+ &u4Value); \ -+ HAL_MCR_WR(_prAdapter, \ -+ MCR_WHCR, \ -+ u4Value | WHCR_RX_ENHANCE_MODE_EN); \ -+} -+ -+#define HAL_CFG_MAX_HIF_RX_LEN_NUM(_prAdapter, _ucNumOfRxLen) \ -+{ \ -+ UINT_32 u4Value, ucNum; \ -+ ucNum = ((_ucNumOfRxLen >= 16) ? 0 : _ucNumOfRxLen); \ -+ u4Value = 0; \ -+ HAL_MCR_RD(_prAdapter, \ -+ MCR_WHCR, \ -+ &u4Value); \ -+ u4Value &= ~WHCR_MAX_HIF_RX_LEN_NUM; \ -+ u4Value |= ((((UINT_32)ucNum) << 4) & WHCR_MAX_HIF_RX_LEN_NUM); \ -+ HAL_MCR_WR(_prAdapter, \ -+ MCR_WHCR, \ -+ u4Value); \ -+} -+ -+#define HAL_SET_INTR_STATUS_READ_CLEAR(prAdapter) \ -+{ \ -+ UINT_32 u4Value; \ -+ HAL_MCR_RD(prAdapter, \ -+ MCR_WHCR, \ -+ &u4Value); \ -+ HAL_MCR_WR(prAdapter, \ -+ MCR_WHCR, \ -+ u4Value & ~WHCR_W_INT_CLR_CTRL); \ -+ prAdapter->prGlueInfo->rHifInfo.fgIntReadClear = TRUE;\ -+} -+ -+#define HAL_SET_INTR_STATUS_WRITE_1_CLEAR(prAdapter) \ -+{ \ -+ UINT_32 u4Value; \ -+ HAL_MCR_RD(prAdapter, \ -+ MCR_WHCR, \ -+ &u4Value); \ -+ HAL_MCR_WR(prAdapter, \ -+ MCR_WHCR, \ -+ u4Value | WHCR_W_INT_CLR_CTRL); \ -+ prAdapter->prGlueInfo->rHifInfo.fgIntReadClear = FALSE;\ -+} -+ -+/* Note: enhance mode structure may also carried inside the buffer, -+ if the length of the buffer is long enough */ -+#define HAL_READ_INTR_STATUS(prAdapter, length, pvBuf) \ -+ HAL_PORT_RD(prAdapter, \ -+ MCR_WHISR, \ -+ length, \ -+ pvBuf, \ -+ length) -+ -+#define HAL_READ_TX_RELEASED_COUNT(_prAdapter, aucTxReleaseCount) \ -+{ \ -+ PUINT_32 pu4Value = (PUINT_32)aucTxReleaseCount; \ -+ HAL_MCR_RD(_prAdapter, \ -+ MCR_WTSR0, \ -+ &pu4Value[0]); \ -+ HAL_MCR_RD(_prAdapter, \ -+ MCR_WTSR1, \ -+ &pu4Value[1]); \ -+} -+ -+#define HAL_READ_RX_LENGTH(prAdapter, pu2Rx0Len, pu2Rx1Len) \ -+{ \ -+ UINT_32 u4Value; \ -+ u4Value = 0; \ -+ HAL_MCR_RD(prAdapter, \ -+ MCR_WRPLR, \ -+ &u4Value); \ -+ *pu2Rx0Len = (UINT_16)u4Value; \ -+ *pu2Rx1Len = (UINT_16)(u4Value >> 16); \ -+} -+ -+#define HAL_GET_INTR_STATUS_FROM_ENHANCE_MODE_STRUCT(pvBuf, u2Len, pu4Status) \ -+{ \ -+ PUINT_32 pu4Buf = (PUINT_32)pvBuf; \ -+ *pu4Status = pu4Buf[0]; \ -+} -+ -+#define HAL_GET_TX_STATUS_FROM_ENHANCE_MODE_STRUCT(pvInBuf, pu4BufOut, u4LenBufOut) \ -+{ \ -+ PUINT_32 pu4Buf = (PUINT_32)pvInBuf; \ -+ ASSERT(u4LenBufOut >= 8); \ -+ pu4BufOut[0] = pu4Buf[1]; \ -+ pu4BufOut[1] = pu4Buf[2]; \ -+} -+ -+#define HAL_GET_RX_LENGTH_FROM_ENHANCE_MODE_STRUCT(pvInBuf, pu2Rx0Num, au2Rx0Len, pu2Rx1Num, au2Rx1Len) \ -+{ \ -+ PUINT_32 pu4Buf = (PUINT_32)pvInBuf; \ -+ ASSERT((sizeof(au2Rx0Len) / sizeof(UINT_16)) >= 16); \ -+ ASSERT((sizeof(au2Rx1Len) / sizeof(UINT_16)) >= 16); \ -+ *pu2Rx0Num = (UINT_16)pu4Buf[3]; \ -+ *pu2Rx1Num = (UINT_16)(pu4Buf[3] >> 16); \ -+ kalMemCopy(au2Rx0Len, &pu4Buf[4], 8); \ -+ kalMemCopy(au2Rx1Len, &pu4Buf[12], 8); \ -+} -+ -+#define HAL_GET_MAILBOX_FROM_ENHANCE_MODE_STRUCT(pvInBuf, pu4Mailbox0, pu4Mailbox1) \ -+{ \ -+ PUINT_32 pu4Buf = (PUINT_32)pvInBuf; \ -+ *pu4Mailbox0 = (UINT_16)pu4Buf[21]; \ -+ *pu4Mailbox1 = (UINT_16)pu4Buf[22]; \ -+} -+ -+#define HAL_IS_TX_DONE_INTR(u4IntrStatus) \ -+ ((u4IntrStatus & WHISR_TX_DONE_INT) ? TRUE : FALSE) -+ -+#define HAL_IS_RX_DONE_INTR(u4IntrStatus) \ -+ ((u4IntrStatus & (WHISR_RX0_DONE_INT | WHISR_RX1_DONE_INT)) ? TRUE : FALSE) -+ -+#define HAL_IS_ABNORMAL_INTR(u4IntrStatus) \ -+ ((u4IntrStatus & WHISR_ABNORMAL_INT) ? TRUE : FALSE) -+ -+#define HAL_IS_FW_OWNBACK_INTR(u4IntrStatus) \ -+ ((u4IntrStatus & WHISR_FW_OWN_BACK_INT) ? TRUE : FALSE) -+ -+#define HAL_PUT_MAILBOX(prAdapter, u4MboxId, u4Data) \ -+{ \ -+ ASSERT(u4MboxId < 2); \ -+ HAL_MCR_WR(prAdapter, \ -+ ((u4MboxId == 0) ? MCR_H2DSM0R : MCR_H2DSM1R), \ -+ u4Data); \ -+} -+ -+#define HAL_GET_MAILBOX(prAdapter, u4MboxId, pu4Data) \ -+{ \ -+ ASSERT(u4MboxId < 2); \ -+ HAL_MCR_RD(prAdapter, \ -+ ((u4MboxId == 0) ? MCR_D2HRM0R : MCR_D2HRM1R), \ -+ pu4Data); \ -+} -+ -+#define HAL_SET_MAILBOX_READ_CLEAR(prAdapter, fgEnableReadClear) \ -+{ \ -+ UINT_32 u4Value; \ -+ HAL_MCR_RD(prAdapter, MCR_WHCR, &u4Value);\ -+ HAL_MCR_WR(prAdapter, MCR_WHCR, \ -+ (fgEnableReadClear) ? \ -+ (u4Value | WHCR_W_MAILBOX_RD_CLR_EN) : \ -+ (u4Value & ~WHCR_W_MAILBOX_RD_CLR_EN)); \ -+ prAdapter->prGlueInfo->rHifInfo.fgMbxReadClear = fgEnableReadClear;\ -+} -+ -+#define HAL_GET_MAILBOX_READ_CLEAR(prAdapter) (prAdapter->prGlueInfo->rHifInfo.fgMbxReadClear) -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif /* _HAL_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/hif_rx.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/hif_rx.h -new file mode 100644 -index 000000000000..b9aa154b097e ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/hif_rx.h -@@ -0,0 +1,220 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/nic/hif_rx.h#1 -+*/ -+ -+/*! \file "hif_rx.h" -+ \brief Provide HIF RX Header Information between F/W and Driver -+ -+ N/A -+*/ -+ -+/* -+** Log: hif_rx.h -+ * -+ * 09 01 2010 kevin.huang -+ * NULL -+ * Use LINK LIST operation to process SCAN result -+ * -+ * 07 16 2010 yarco.yang -+ * -+ * 1. Support BSS Absence/Presence Event -+ * 2. Support STA change PS mode Event -+ * 3. Support BMC forwarding for AP mode. -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 14 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * follow-ups for HIF_RX_HEADER_T update: -+ * 1) add TCL -+ * 2) add RCPI -+ * 3) add ChannelNumber -+ * -+ * 06 11 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) migrate assoc.c. -+ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness -+ * 3) add configuration options for CNM_MEM and RSN modules -+ * 4) add data path for management frames -+ * 5) eliminate rPacketInfo of MSDU_INFO_T -+ * -+ * 06 09 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add necessary changes to driver data paths. -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+** \main\maintrunk.MT6620WiFiDriver_Prj\10 2009-12-10 16:44:00 GMT mtk02752 -+** code clean -+** \main\maintrunk.MT6620WiFiDriver_Prj\9 2009-12-09 13:59:20 GMT MTK02468 -+** Added HIF_RX_HDR parsing macros -+** \main\maintrunk.MT6620WiFiDriver_Prj\8 2009-11-24 19:54:54 GMT mtk02752 -+** adopt HIF_RX_HEADER_T in new data path -+** \main\maintrunk.MT6620WiFiDriver_Prj\7 2009-10-29 19:51:19 GMT mtk01084 -+** modify FW/ driver interface -+** \main\maintrunk.MT6620WiFiDriver_Prj\6 2009-04-28 10:33:58 GMT mtk01461 -+** Add define of HW_APPENED_LEN -+** \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-04-01 10:51:02 GMT mtk01461 -+** Rename ENUM_HIF_RX_PKT_TYPE_T -+** \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-03-19 12:05:03 GMT mtk01426 -+** Remove __KAL_ATTRIB_PACKED__ and add hifDataTypeCheck() -+** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-03-17 20:18:52 GMT mtk01426 -+** Add comment to HIF_RX_HEADER_T -+** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 20:16:23 GMT mtk01426 -+** Init for develop -+** -+*/ -+ -+#ifndef _HIF_RX_H -+#define _HIF_RX_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+/*! HIF_RX_HEADER_T */ -+/* DW 0, Byte 1 */ -+#define HIF_RX_HDR_PACKET_TYPE_MASK BITS(0, 1) -+#define HIF_RX_HDR_SEC_MODE_MASK BITS(2, 5) -+#define HIF_RX_HDR_SEC_MODE_OFFSET 2 -+ -+/* DW 1, Byte 0 */ -+#define HIF_RX_HDR_HEADER_LEN BITS(2, 7) -+#define HIF_RX_HDR_HEADER_LEN_OFFSET 2 -+#define HIF_RX_HDR_HEADER_OFFSET_MASK BITS(0, 1) -+ -+/* DW 1, Byte 1 */ -+#define HIF_RX_HDR_80211_HEADER_FORMAT BIT(0) -+#define HIF_RX_HDR_DO_REORDER BIT(1) -+#define HIF_RX_HDR_PAL BIT(2) -+#define HIF_RX_HDR_TCL BIT(3) -+#define HIF_RX_HDR_NETWORK_IDX_MASK BITS(4, 7) -+#define HIF_RX_HDR_NETWORK_IDX_OFFSET 4 -+ -+/* DW 1, Byte 2, 3 */ -+#define HIF_RX_HDR_SEQ_NO_MASK BITS(0, 11) -+#define HIF_RX_HDR_TID_MASK BITS(12, 14) -+#define HIF_RX_HDR_TID_OFFSET 12 -+#define HIF_RX_HDR_BAR_FRAME BIT(15) -+ -+#define HIF_RX_HDR_FLAG_AMP_WDS BIT(0) -+#define HIF_RX_HDR_FLAG_802_11_FORMAT BIT(1) -+#define HIF_RX_HDR_FLAG_BAR_FRAME BIT(2) -+#define HIF_RX_HDR_FLAG_DO_REORDERING BIT(3) -+#define HIF_RX_HDR_FLAG_CTRL_WARPPER_FRAME BIT(4) -+ -+#define HIF_RX_HW_APPENDED_LEN 4 -+ -+/* For DW 2, Byte 3 - ucHwChannelNum */ -+#define HW_CHNL_NUM_MAX_2G4 14 -+#define HW_CHNL_NUM_MAX_4G_5G (255 - HW_CHNL_NUM_MAX_2G4) -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+typedef struct _HIF_RX_HEADER_T { -+ UINT_16 u2PacketLen; -+ UINT_16 u2PacketType; -+ UINT_8 ucHerderLenOffset; -+ UINT_8 uc80211_Reorder_PAL_TCL; -+ UINT_16 u2SeqNoTid; -+ UINT_8 ucStaRecIdx; -+ UINT_8 ucRcpi; -+ UINT_8 ucHwChannelNum; -+ UINT_8 ucReserved; -+} HIF_RX_HEADER_T, *P_HIF_RX_HEADER_T; -+ -+typedef enum _ENUM_HIF_RX_PKT_TYPE_T { -+ HIF_RX_PKT_TYPE_DATA = 0, -+ HIF_RX_PKT_TYPE_EVENT, -+ HIF_RX_PKT_TYPE_TX_LOOPBACK, -+ HIF_RX_PKT_TYPE_MANAGEMENT, -+ HIF_RX_PKT_TYPE_NUM -+} ENUM_HIF_RX_PKT_TYPE_T, *P_ENUM_HIF_RX_PKT_TYPE_T; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+#define HIF_RX_HDR_SIZE sizeof(HIF_RX_HEADER_T) -+ -+#define HIF_RX_HDR_GET_80211_FLAG(_prHifRxHdr) \ -+ (((((_prHifRxHdr)->uc80211_Reorder_PAL_TCL) & HIF_RX_HDR_80211_HEADER_FORMAT) ? TRUE : FALSE)) -+#define HIF_RX_HDR_GET_REORDER_FLAG(_prHifRxHdr) \ -+ (((((_prHifRxHdr)->uc80211_Reorder_PAL_TCL) & HIF_RX_HDR_DO_REORDER) ? TRUE : FALSE)) -+#define HIF_RX_HDR_GET_PAL_FLAG(_prHifRxHdr) \ -+ (((((_prHifRxHdr)->uc80211_Reorder_PAL_TCL) & HIF_RX_HDR_PAL) ? TRUE : FALSE)) -+#define HIF_RX_HDR_GET_TCL_FLAG(_prHifRxHdr) \ -+ (((((_prHifRxHdr)->uc80211_Reorder_PAL_TCL) & HIF_RX_HDR_TCL) ? TRUE : FALSE)) -+#define HIF_RX_HDR_GET_NETWORK_IDX(_prHifRxHdr) \ -+ ((((_prHifRxHdr)->uc80211_Reorder_PAL_TCL) & HIF_RX_HDR_NETWORK_IDX_MASK)\ -+ >> HIF_RX_HDR_NETWORK_IDX_OFFSET) -+ -+#define HIF_RX_HDR_GET_SEC_MODE(_prHifRxHdr) \ -+ ((((_prHifRxHdr)->u2PacketType) & HIF_RX_HDR_SEC_MODE_MASK) >> HIF_RX_HDR_SEC_MODE_OFFSET) -+ -+#define HIF_RX_HDR_GET_TID(_prHifRxHdr) \ -+ ((((_prHifRxHdr)->u2SeqNoTid) & HIF_RX_HDR_TID_MASK)\ -+ >> HIF_RX_HDR_TID_OFFSET) -+#define HIF_RX_HDR_GET_SN(_prHifRxHdr) \ -+ (((_prHifRxHdr)->u2SeqNoTid) & HIF_RX_HDR_SEQ_NO_MASK) -+#define HIF_RX_HDR_GET_BAR_FLAG(_prHifRxHdr) \ -+ (((((_prHifRxHdr)->u2SeqNoTid) & HIF_RX_HDR_BAR_FRAME) ? TRUE : FALSE)) -+ -+#define HIF_RX_HDR_GET_CHNL_NUM(_prHifRxHdr) \ -+ ((((_prHifRxHdr)->ucHwChannelNum) > HW_CHNL_NUM_MAX_4G_5G) ? \ -+ (((_prHifRxHdr)->ucHwChannelNum) - HW_CHNL_NUM_MAX_4G_5G) : \ -+ ((_prHifRxHdr)->ucHwChannelNum)) -+ -+/* To do: support more bands other than 2.4G and 5G */ -+#define HIF_RX_HDR_GET_RF_BAND(_prHifRxHdr) \ -+ ((((_prHifRxHdr)->ucHwChannelNum) <= HW_CHNL_NUM_MAX_2G4) ? \ -+ BAND_2G4 : BAND_5G) -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+static inline VOID hifDataTypeCheck(VOID); -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+/* Kevin: we don't have to call following function to inspect the data structure. -+ * It will check automatically while at compile time. -+ * We'll need this for porting driver to different RTOS. -+ */ -+static inline VOID hifDataTypeCheck(VOID) -+{ -+ DATA_STRUCT_INSPECTING_ASSERT(sizeof(HIF_RX_HEADER_T) == 12); -+ -+} -+ -+#endif -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/hif_tx.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/hif_tx.h -new file mode 100644 -index 000000000000..17252f2c7760 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/hif_tx.h -@@ -0,0 +1,214 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/nic/hif_tx.h#1 -+*/ -+ -+/* -+** Log: hif_tx.h -+ * -+ * 10 07 2010 cp.wu -+ * [WCXRP00000083] [MT5931][Driver][FW] Add necessary logic for MT5931 first connection -+ * add firmware download for MT5931. -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 14 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * fill extra information for revised HIF_TX_HEADER. -+ * -+ * 06 10 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) add flag on MSDU_INFO_T for indicating BIP frame and forceBasicRate -+ * 2) add packet type for indicating management frames -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 03 10 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * code clean: removing unused variables and structure definitions -+ * -+ * 02 09 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1. Permanent and current MAC address are now retrieved by CMD/EVENT packets instead of hard-coded address -+ * * * 2. follow MSDN defined behavior when associates to another AP -+ * * * 3. for firmware download, packet size could be up to 2048 bytes -+ * -+ * 01 13 2010 tehuang.liu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * Enabled the Burst_End Indication mechanism -+ * -+ * 01 13 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * TX: fill ucWlanHeaderLength/ucPktFormtId_Flags according to info provided by prMsduInfo -+** \main\maintrunk.MT6620WiFiDriver_Prj\16 2009-12-10 16:43:40 GMT mtk02752 -+** code clean -+** \main\maintrunk.MT6620WiFiDriver_Prj\15 2009-11-24 19:55:11 GMT mtk02752 -+** adopt HIF_TX_HEADER_T in new data path -+** \main\maintrunk.MT6620WiFiDriver_Prj\14 2009-11-23 17:54:13 GMT mtk02752 -+** CMD_HDR_SIZE = (sizeof(WIFI_CMD_T)) to follow up CM's CMD/EVENT documentation -+** -+** \main\maintrunk.MT6620WiFiDriver_Prj\13 2009-11-17 22:41:10 GMT mtk01084 -+** \main\maintrunk.MT6620WiFiDriver_Prj\12 2009-11-17 17:34:07 GMT mtk02752 -+** remove HIF_TX_BUFF_COUNT_TC0 (move to nic_tx.h) -+** \main\maintrunk.MT6620WiFiDriver_Prj\11 2009-11-17 12:14:12 GMT mtk02752 -+** add initial value for HIF_TX_BUFF_COUNT_TC5 -+** \main\maintrunk.MT6620WiFiDriver_Prj\10 2009-11-13 13:54:18 GMT mtk01084 -+** \main\maintrunk.MT6620WiFiDriver_Prj\9 2009-11-04 14:11:14 GMT mtk01084 -+** modify SW TX data format -+** \main\maintrunk.MT6620WiFiDriver_Prj\8 2009-10-29 19:51:53 GMT mtk01084 -+** modify FW/ driver interface -+** \main\maintrunk.MT6620WiFiDriver_Prj\7 2009-05-20 12:22:46 GMT mtk01461 -+** Add SeqNum field to CMD Header -+** \main\maintrunk.MT6620WiFiDriver_Prj\6 2009-04-17 19:40:52 GMT mtk01461 -+** Update the Log Sign -+*/ -+ -+#ifndef _HIF_TX_H -+#define _HIF_TX_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+/* Maximum buffer size for individual HIF TCQ Buffer */ -+#define HIF_TX_BUFF_MAX_SIZE 1552 /* Reserved field was not included */ -+ -+/* Maximum buffer count for individual HIF TCQ */ -+#define HIF_TX_BUFF_COUNT_TC0 3 -+#define HIF_TX_BUFF_COUNT_TC1 3 -+#define HIF_TX_BUFF_COUNT_TC2 3 -+#define HIF_TX_BUFF_COUNT_TC3 3 -+#define HIF_TX_BUFF_COUNT_TC4 2 -+ -+#define TX_HDR_SIZE sizeof(HIF_TX_HEADER_T) -+ -+#define CMD_HDR_SIZE sizeof(WIFI_CMD_T) -+ -+#define CMD_PKT_SIZE_FOR_IMAGE 2048 /* !< 2048 Bytes CMD payload buffer */ -+ -+/*! NIC_HIF_TX_HEADER_T */ -+/* DW 0, Byte 0,1 */ -+#define HIF_TX_HDR_TX_BYTE_COUNT_MASK BITS(0, 11) -+#define HIF_TX_HDR_USER_PRIORITY_OFFSET 12 -+ -+/* DW 0, Byte 2 */ -+#define HIF_TX_HDR_ETHER_TYPE_OFFSET_MASK BITS(0, 7) -+ -+/* DW 0, Byte 3 */ -+#define HIF_TX_HDR_IP_CSUM BIT(0) -+#define HIF_TX_HDR_TCP_CSUM BIT(1) -+#define HIF_TX_HDR_RESOURCE_MASK BITS(2, 5) -+#define HIF_TX_HDR_RESOURCE_OFFSET 2 -+#define HIF_TX_HDR_PACKET_TYPE_MASK BITS(6, 7) -+#define HIF_TX_HDR_PACKET_TYPE_OFFSET 6 -+ -+/* DW 1, Byte 0 */ -+#define HIF_TX_HDR_WLAN_HEADER_LEN_MASK BITS(0, 5) -+ -+/* DW 1, Byte 1 */ -+#define HIF_TX_HDR_FORMAT_ID_MASK BITS(0, 2) -+#define HIF_TX_HDR_NETWORK_TYPE_MASK BITS(4, 5) -+#define HIF_TX_HDR_NETWORK_TYPE_OFFSET 4 -+#define HIF_TX_HDR_FLAG_1X_FRAME_MASK BIT(6) -+#define HIF_TX_HDR_FLAG_1X_FRAME_OFFSET 6 -+#define HIF_TX_HDR_FLAG_802_11_FORMAT_MASK BIT(7) -+#define HIF_TX_HDR_FLAG_802_11_FORMAT_OFFSET 7 -+ -+/* DW2, Byte 3 */ -+#define HIF_TX_HDR_PS_FORWARDING_TYPE_MASK BITS(0, 1) -+#define HIF_TX_HDR_PS_SESSION_ID_MASK BITS(2, 4) -+#define HIF_TX_HDR_PS_SESSION_ID_OFFSET 2 -+#define HIF_TX_HDR_BURST_END_MASK BIT(5) -+#define HIF_TX_HDR_BURST_END_OFFSET 5 -+ -+/* DW3, Byte 1 */ -+#define HIF_TX_HDR_NEED_ACK BIT(0) -+#define HIF_TX_HDR_BIP BIT(1) -+#define HIF_TX_HDR_BASIC_RATE BIT(2) -+#define HIF_TX_HDR_NEED_TX_DONE_STATUS BIT(3) -+#define HIF_TX_HDR_RTS BIT(4) -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+typedef struct _HIF_HW_TX_HEADER_T { -+ UINT_16 u2TxByteCount; -+ UINT_8 ucEtherTypeOffset; -+ UINT_8 ucCSflags; -+ UINT_8 aucBuffer[0]; -+} HIF_HW_TX_HEADER_T, *P_HIF_HW_TX_HEADER_T; -+ -+typedef struct _HIF_TX_HEADER_T { -+ UINT_16 u2TxByteCount_UserPriority; -+ UINT_8 ucEtherTypeOffset; -+ UINT_8 ucResource_PktType_CSflags; -+ UINT_8 ucWlanHeaderLength; -+ UINT_8 ucPktFormtId_Flags; -+ UINT_16 u2LLH; /* for BOW */ -+ UINT_16 u2SeqNo; /* for BOW */ -+ UINT_8 ucStaRecIdx; -+ UINT_8 ucForwardingType_SessionID_Reserved; -+ UINT_8 ucPacketSeqNo; -+ UINT_8 ucAck_BIP_BasicRate; -+ UINT_8 aucReserved[2]; -+} HIF_TX_HEADER_T, *P_HIF_TX_HEADER_T; -+ -+typedef enum _ENUM_HIF_TX_PKT_TYPE_T { -+ HIF_TX_PKT_TYPE_DATA = 0, -+ HIF_TX_PKT_TYPE_CMD, -+ HIF_TX_PKT_TYPE_HIF_LOOPBACK, -+ HIF_TX_PKT_TYPE_MANAGEMENT, -+ HIF_TX_PKT_TYPE_NUM -+} ENUM_HIF_TX_PKT_TYPE_T, *P_ENUM_HIF_TX_PKT_TYPE_T; -+ -+typedef enum _ENUM_HIF_OOB_CTRL_PKT_TYPE_T { -+ HIF_OOB_CTRL_PKT_TYPE_LOOPBACK = 1, -+ HIF_OOB_CTRL_PKT_TYP_NUM -+} ENUM_HIF_OOB_CTRL_PKT_TYPE_T, *P_ENUM_HIF_OOB_CTRL_PKT_TYPE_T; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+#define TFCB_FRAME_PAD_TO_DW(u2Length) ALIGN_4(u2Length) -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+/* Kevin: we don't have to call following function to inspect the data structure. -+ * It will check automatically while at compile time. -+ */ -+static inline VOID hif_txDataTypeCheck(VOID); -+ -+static inline VOID hif_txDataTypeCheck(VOID) -+{ -+ DATA_STRUCT_INSPECTING_ASSERT(sizeof(HIF_TX_HEADER_T) == 16); -+ -+} -+ -+#endif /*_HIF_TX_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/mac.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/mac.h -new file mode 100644 -index 000000000000..ff38d30c3cf2 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/mac.h -@@ -0,0 +1,2323 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/nic/mac.h#1 -+*/ -+ -+/*! \file "mac.h" -+ \brief Brief description. -+ -+ Detail description. -+*/ -+ -+/* -+** Log: mac.h -+ * -+ * 03 02 2012 terry.wu -+ * NULL -+ * Sync CFG80211 modification from branch 2,2. -+ * -+ * 01 05 2012 tsaiyuan.hsu -+ * [WCXRP00001157] [MT6620 Wi-Fi][FW][DRV] add timing measurement support for 802.11v -+ * add timing measurement support for 802.11v. -+ * -+ * 10 12 2011 wh.su -+ * [WCXRP00001036] [MT6620 Wi-Fi][Driver][FW] Adding the 802.11w code for MFP -+ * adding the 802.11w related function and define . -+ * -+ * 06 22 2011 wh.su -+ * [WCXRP00000806] [MT6620 Wi-Fi][Driver] Move the WPA/RSN IE and WAPI IE structure to mac.h -+ * and let the sw structure not align at byte -+ * Move the WAPI/RSN IE to mac.h and SW structure not align to byte, -+ * Notice needed update P2P.ko. -+ * -+ * 05 06 2011 wh.su -+ * [WCXRP00000699] [MT6620 Wi-Fi][Driver] Add the ie pointer check for avoid TP-LINK AP send -+ * the wrong beacon make driver got incorrect support rate set -+ * Add the length check before access the ie length filed. -+ * -+ * 05 06 2011 wh.su -+ * [WCXRP00000699] [MT6620 Wi-Fi][Driver] Add the ie pointer check for avoid TP-LINK AP send -+ * the wrong beacon make driver got incorrect support rate set -+ * adding the length check before processing next ie.. -+ * -+ * 04 18 2011 terry.wu -+ * [WCXRP00000660] [MT6620 Wi-Fi][Driver] Remove flag CFG_WIFI_DIRECT_MOVED -+ * Remove flag CFG_WIFI_DIRECT_MOVED. -+ * -+ * 04 12 2011 cm.chang -+ * [WCXRP00000634] [MT6620 Wi-Fi][Driver][FW] 2nd BSS will not support 40MHz bandwidth for concurrency -+ * . -+ * -+ * 04 08 2011 yuche.tsai -+ * [WCXRP00000624] [Volunteer Patch][MT6620][Driver] Add device discoverability support for GO. -+ * Add device discover ability support. -+ * -+ * 03 17 2011 chinglan.wang -+ * [WCXRP00000570] [MT6620 Wi-Fi][Driver] Add Wi-Fi Protected Setup v2.0 feature -+ * . -+ * -+ * 01 25 2011 yuche.tsai -+ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record. -+ * Some action frame define is not belong to P2P. -+ * -+ * 01 25 2011 yuche.tsai -+ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record. -+ * Add some service discovery MAC define, phase I. -+ * -+ * 12 13 2010 cp.wu -+ * [WCXRP00000260] [MT6620 Wi-Fi][Driver][Firmware] Create V1.1 branch for both firmware and driver -+ * create branch for Wi-Fi driver v1.1 -+ * -+ * 12 13 2010 cp.wu -+ * [WCXRP00000256] [MT6620 Wi-Fi][Driver] Eliminate potential issues which is identified by Klockwork -+ * suppress warning reported by Klockwork. -+ * -+ * 11 01 2010 cp.wu -+ * [WCXRP00000122] [MT6620 Wi-Fi][Driver] Preparation for YuSu source tree integration -+ * revert to previous revision. (this file is not necessary to be changed) -+ * -+ * 08 20 2010 cm.chang -+ * NULL -+ * Migrate RLM code to host from FW -+ * -+ * 08 02 2010 yuche.tsai -+ * NULL -+ * 1. Add P2P MAC define. -+ * 2. Add scan device found event -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 21 2010 yuche.tsai -+ * [WPD00003839][MT6620 5931][P2P] Feature migration -+ * Add WFA specific OUI. -+ * -+ * 06 17 2010 yuche.tsai -+ * [WPD00003839][MT6620 5931][P2P] Feature migration -+ * Add P2P IE ID & Vendor OUI TYPE for P2P. -+ * -+ * 06 07 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * merge MAC.h. -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 01 13 2010 tehuang.liu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * Added OFFSET_BAR_SSC_SN -+** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-12-09 14:00:24 GMT MTK02468 -+** Added offsets and masks for the BA Parameter Set filed -+** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 20:16:26 GMT mtk01426 -+** Init for develop -+** -+*/ -+ -+#ifndef _MAC_H -+#define _MAC_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+/* 3 --------------- Constants for Ethernet/802.11 MAC --------------- */ -+/* MAC Address */ -+#define MAC_ADDR_LEN 6 -+ -+#define MAC_ADDR_LOCAL_ADMIN BIT(1) -+ -+#define ETH_P_IPV4 0x0800 -+#define ETH_P_IPX 0x8137 /* Novell IPX */ -+#define ETH_P_AARP 0x80F3 /* AppleTalk Address Resolution Protocol (AARP) */ -+#define ETH_P_IPV6 0x86DD -+ -+#define IP_VERSION_4 4 -+#define IP_VERSION_6 6 -+ -+#define IP_PROTOCOL_TCP 6 -+#define IP_PROTOCOL_UDP 17 -+ -+#define IPV4_HDR_IP_IDENTIFICATION_OFFSET 4 -+#define IPV4_HDR_IP_PROTOCOL_OFFSET 9 -+#define IPV4_HDR_IP_CSUM_OFFSET 10 -+#define IPV4_HDR_IP_SRC_ADDR_OFFSET 12 -+#define IPV4_HDR_IP_DST_ADDR_OFFSET 16 -+ -+#define IPV6_HDR_IP_PROTOCOL_OFFSET 6 -+#define IPV6_HDR_IP_SRC_ADDR_OFFSET 8 -+#define IPV6_HDR_IP_DST_ADDR_OFFSET 24 -+#define IPV6_HDR_IP_DST_ADDR_MAC_HIGH_OFFSET 32 -+#define IPV6_HDR_IP_DST_ADDR_MAC_LOW_OFFSET 37 -+#define IPV6_PROTOCOL_ICMPV6 0x3A -+#define IPV6_ADDR_LEN 16 -+#define IPV6_HDR_LEN 40 -+ -+#define ARP_OPERATION_OFFSET 6 -+#define ARP_SNEDER_MAC_OFFSET 8 -+#define ARP_SENDER_IP_OFFSET 14 -+#define ARP_TARGET_MAC_OFFSET 18 -+#define ARP_TARGET_IP_OFFSET 24 -+#define ARP_OPERATION_REQUEST 0x0001 -+#define ARP_OPERATION_RESPONSE 0x0002 -+ -+#define ICMPV6_TYPE_OFFSET 0 -+#define ICMPV6_FLAG_OFFSET 4 -+#define ICMPV6_TARGET_ADDR_OFFSET 8 -+#define ICMPV6_TARGET_LL_ADDR_TYPE_OFFSET 24 -+#define ICMPV6_TARGET_LL_ADDR_LEN_OFFSET 25 -+#define ICMPV6_TARGET_LL_ADDR_TA_OFFSET 26 -+ -+#define ICMPV6_FLAG_ROUTER_BIT BIT(7) -+#define ICMPV6_FLAG_SOLICITED_BIT BIT(6) -+#define ICMPV6_FLAG_OVERWRITE_BIT BIT(5) -+#define ICMPV6_TYPE_NEIGHBOR_SOLICITATION 0x87 -+#define ICMPV6_TYPE_NEIGHBOR_ADVERTISEMENT 0x88 -+ -+#define TCP_HDR_TCP_CSUM_OFFSET 16 -+#define UDP_HDR_UDP_CSUM_OFFSET 6 -+ -+#define LLC_LEN 8 /* LLC(3) + SNAP(3) + EtherType(2) */ -+ -+#define NULL_MAC_ADDR {0x00, 0x00, 0x00, 0x00, 0x00, 0x00} -+#define BC_MAC_ADDR {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF} -+ -+/* Ethernet Frame Field Size, in byte */ -+#define ETHER_HEADER_LEN 14 -+#define ETHER_TYPE_LEN 2 -+#define ETHER_MIN_PKT_SZ 60 -+#define ETHER_MAX_PKT_SZ 1514 -+ -+/* IEEE 802.11 WLAN Frame Field Size, in byte */ -+#define WLAN_MAC_HEADER_LEN 24 /* Address 4 excluded */ -+#define WLAN_MAC_HEADER_A4_LEN 30 /* Address 4 included */ -+#define WLAN_MAC_HEADER_QOS_LEN 26 /* QoS Control included */ -+#define WLAN_MAC_HEADER_QOS_HTC_LEN 30 /* QoS Control and HTC included */ -+#define WLAN_MAC_HEADER_A4_QOS_LEN 32 /* Address 4 and QoS Control included */ -+#define WLAN_MAC_HEADER_A4_QOS_HTC_LEN 36 /* Address 4, QoS Control and HTC included */ -+#define WLAN_MAC_MGMT_HEADER_LEN 24 /* Address 4 excluded */ -+#define WLAN_MAC_MGMT_HEADER_HTC_LEN 28 /* HTC included */ -+ -+#define QOS_CTRL_LEN 2 -+#define HT_CTRL_LEN 4 -+ -+#define WLAN_MAC_CTS_ACK_LEN (WLAN_MAC_CTS_ACK_FRAME_HEADER_LEN + FCS_LEN) -+ -+/* 6.2.1.1.2 Semantics of the service primitive */ -+#define MSDU_MAX_LENGTH 2304 -+ -+/* 7.1.3.3.3 Broadcast BSSID */ -+#define BC_BSSID BC_MAC_ADDR -+ -+/* 7.1.3.7 FCS field */ -+#define FCS_LEN 4 -+ -+/* 7.3.1.6 Listen Interval field */ -+#define DEFAULT_LISTEN_INTERVAL_BY_DTIM_PERIOD 2 /* In unit of AP's DTIM interval, */ -+#define DEFAULT_LISTEN_INTERVAL 10 -+ -+/* 7.3.2.1 Broadcast(Wildcard) SSID */ -+#define BC_SSID "" -+#define BC_SSID_LEN 0 -+ -+/* 7.3.2.2 Data Rate Value */ -+#define RATE_1M 2 /* 1M in unit of 500kb/s */ -+#define RATE_2M 4 /* 2M */ -+#define RATE_5_5M 11 /* 5.5M */ -+#define RATE_11M 22 /* 11M */ -+#define RATE_22M 44 /* 22M */ -+#define RATE_33M 66 /* 33M */ -+#define RATE_6M 12 /* 6M */ -+#define RATE_9M 18 /* 9M */ -+#define RATE_12M 24 /* 12M */ -+#define RATE_18M 36 /* 18M */ -+#define RATE_24M 48 /* 24M */ -+#define RATE_36M 72 /* 36M */ -+#define RATE_48M 96 /* 48M */ -+#define RATE_54M 108 /* 54M */ -+/* 7.3.2.14 BSS membership selector */ -+#define RATE_HT_PHY 127 /* BSS Selector - Clause 20. HT PHY */ -+#define RATE_MASK BITS(0, 6) /* mask bits for the rate */ -+#define RATE_BASIC_BIT BIT(7) /* mask bit for the rate belonging to the BSSBasicRateSet */ -+ -+/* 8.3.2.2 TKIP MPDU formats */ -+#define TKIP_MIC_LEN 8 -+ -+/* 9.2.10 DIFS */ -+#define DIFS 2 /* 2 x aSlotTime */ -+ -+/* 11.3 STA Authentication and Association */ -+#define STA_STATE_1 0 /* Accept Class 1 frames */ -+#define STA_STATE_2 1 /* Accept Class 1 & 2 frames */ -+#define STA_STATE_3 2 /* Accept Class 1,2 & 3 frames */ -+ -+/* 15.4.8.5 802.11k RCPI-dBm mapping*/ -+#define NDBM_LOW_BOUND_FOR_RCPI 110 -+#define RCPI_LOW_BOUND 0 -+#define RCPI_HIGH_BOUND 220 -+#define RCPI_MEASUREMENT_NOT_AVAILABLE 255 -+ -+/* PHY characteristics */ -+/* 17.4.4/18.3.3/19.8.4 Slot Time (aSlotTime) */ -+#define SLOT_TIME_LONG 20 /* Long Slot Time */ -+#define SLOT_TIME_SHORT 9 /* Short Slot Time */ -+ -+#define SLOT_TIME_HR_DSSS SLOT_TIME_LONG /* 802.11b aSlotTime */ -+#define SLOT_TIME_OFDM SLOT_TIME_SHORT /* 802.11a aSlotTime(20M Spacing) */ -+#define SLOT_TIME_OFDM_10M_SPACING 13 /* 802.11a aSlotTime(10M Spacing) */ -+#define SLOT_TIME_ERP_LONG SLOT_TIME_LONG /* 802.11g aSlotTime(Long) */ -+#define SLOT_TIME_ERP_SHORT SLOT_TIME_SHORT /* 802.11g aSlotTime(Short) */ -+ -+/* 17.4.4/18.3.3/19.8.4 Contention Window (aCWmin & aCWmax) */ -+#define CWMIN_OFDM 15 /* 802.11a aCWmin */ -+#define CWMAX_OFDM 1023 /* 802.11a aCWmax */ -+ -+#define CWMIN_HR_DSSS 31 /* 802.11b aCWmin */ -+#define CWMAX_HR_DSSS 1023 /* 802.11b aCWmax */ -+ -+#define CWMIN_ERP_0 31 /* 802.11g aCWmin(0) - for only have 1/2/5/11Mbps Rates */ -+#define CWMIN_ERP_1 15 /* 802.11g aCWmin(1) */ -+#define CWMAX_ERP 1023 /* 802.11g aCWmax */ -+ -+/* Short Inter-Frame Space (aSIFSTime) */ -+/* 15.3.3 802.11b aSIFSTime */ -+#define SIFS_TIME_HR_DSSS 10 -+/* 17.4.4 802.11a aSIFSTime */ -+#define SIFS_TIME_OFDM 16 -+/* 19.8.4 802.11g aSIFSTime */ -+#define SIFS_TIME_ERP 10 -+ -+/* 15.4.6.2 Number of operating channels */ -+#define CH_1 0x1 -+#define CH_2 0x2 -+#define CH_3 0x3 -+#define CH_4 0x4 -+#define CH_5 0x5 -+#define CH_6 0x6 -+#define CH_7 0x7 -+#define CH_8 0x8 -+#define CH_9 0x9 -+#define CH_10 0xa -+#define CH_11 0xb -+#define CH_12 0xc -+#define CH_13 0xd -+#define CH_14 0xe -+ -+#define MAXIMUM_OPERATION_CHANNEL_LIST 46 -+ -+/* 3 --------------- IEEE 802.11 PICS --------------- */ -+/* Annex D - dot11OperationEntry 2 */ -+#define DOT11_RTS_THRESHOLD_MIN 0 -+#define DOT11_RTS_THRESHOLD_MAX 2347 /* from Windows DDK */ -+/* #define DOT11_RTS_THRESHOLD_MAX 3000 // from Annex D */ -+ -+#define DOT11_RTS_THRESHOLD_DEFAULT \ -+ DOT11_RTS_THRESHOLD_MAX -+ -+/* Annex D - dot11OperationEntry 5 */ -+#define DOT11_FRAGMENTATION_THRESHOLD_MIN 256 -+#define DOT11_FRAGMENTATION_THRESHOLD_MAX 2346 /* from Windows DDK */ -+/* #define DOT11_FRAGMENTATION_THRESHOLD_MAX 3000 // from Annex D */ -+ -+#define DOT11_FRAGMENTATION_THRESHOLD_DEFAULT \ -+ DOT11_FRAGMENTATION_THRESHOLD_MAX -+ -+/* Annex D - dot11OperationEntry 6 */ -+#define DOT11_TRANSMIT_MSDU_LIFETIME_TU_MIN 1 -+#define DOT11_TRANSMIT_MSDU_LIFETIME_TU_MAX 0xFFFFffff -+#define DOT11_TRANSMIT_MSDU_LIFETIME_TU_DEFAULT 4095 /* 802.11 define 512 */ -+ /* MT5921 only aceept N <= 4095 */ -+ -+/* Annex D - dot11OperationEntry 7 */ -+#define DOT11_RECEIVE_LIFETIME_TU_MIN 1 -+#define DOT11_RECEIVE_LIFETIME_TU_MAX 0xFFFFffff -+#define DOT11_RECEIVE_LIFETIME_TU_DEFAULT 4096 /* 802.11 define 512 */ -+ -+/* Annex D - dot11StationConfigEntry 12 */ -+#define DOT11_BEACON_PERIOD_MIN 1 /* TU. */ -+#define DOT11_BEACON_PERIOD_MAX 0xffff /* TU. */ -+#define DOT11_BEACON_PERIOD_DEFAULT 100 /* TU. */ -+ -+/* Annex D - dot11StationConfigEntry 13 */ -+#define DOT11_DTIM_PERIOD_MIN 1 /* TU. */ -+#define DOT11_DTIM_PERIOD_MAX 255 /* TU. */ -+#define DOT11_DTIM_PERIOD_DEFAULT 1 /* TU. */ -+ -+/* Annex D - dot11RegDomainsSupportValue */ -+#define REGULATION_DOMAIN_FCC 0x10 /* FCC (US) */ -+#define REGULATION_DOMAIN_IC 0x20 /* IC or DOC (Canada) */ -+#define REGULATION_DOMAIN_ETSI 0x30 /* ETSI (Europe) */ -+#define REGULATION_DOMAIN_SPAIN 0x31 /* Spain */ -+#define REGULATION_DOMAIN_FRANCE 0x32 /* France */ -+#define REGULATION_DOMAIN_JAPAN 0x40 /* MKK (Japan) */ -+#define REGULATION_DOMAIN_CHINA 0x50 /* China */ -+#define REGULATION_DOMAIN_OTHER 0x00 /* Other */ -+ -+/* 3 --------------- IEEE 802.11 MAC header fields --------------- */ -+/* 7.1.3.1 Masks for the subfields in the Frame Control field */ -+#define MASK_FC_PROTOCOL_VER BITS(0, 1) -+#define MASK_FC_TYPE BITS(2, 3) -+#define MASK_FC_SUBTYPE BITS(4, 7) -+#define MASK_FC_SUBTYPE_QOS_DATA BIT(7) -+#define MASK_FC_TO_DS BIT(8) -+#define MASK_FC_FROM_DS BIT(9) -+#define MASK_FC_MORE_FRAG BIT(10) -+#define MASK_FC_RETRY BIT(11) -+#define MASK_FC_PWR_MGT BIT(12) -+#define MASK_FC_MORE_DATA BIT(13) -+#define MASK_FC_PROTECTED_FRAME BIT(14) -+#define MASK_FC_ORDER BIT(15) -+ -+#define MASK_FRAME_TYPE (MASK_FC_TYPE | MASK_FC_SUBTYPE) -+#define MASK_TO_DS_FROM_DS (MASK_FC_TO_DS | MASK_FC_FROM_DS) -+ -+#define MAX_NUM_OF_FC_SUBTYPES 16 -+#define OFFSET_OF_FC_SUBTYPE 4 -+ -+/* 7.1.3.1.2 MAC frame types and subtypes */ -+#define MAC_FRAME_TYPE_MGT 0 -+#define MAC_FRAME_TYPE_CTRL BIT(2) -+#define MAC_FRAME_TYPE_DATA BIT(3) -+#define MAC_FRAME_TYPE_QOS_DATA (MAC_FRAME_TYPE_DATA | MASK_FC_SUBTYPE_QOS_DATA) -+ -+#define MAC_FRAME_ASSOC_REQ (MAC_FRAME_TYPE_MGT | 0x0000) -+#define MAC_FRAME_ASSOC_RSP (MAC_FRAME_TYPE_MGT | 0x0010) -+#define MAC_FRAME_REASSOC_REQ (MAC_FRAME_TYPE_MGT | 0x0020) -+#define MAC_FRAME_REASSOC_RSP (MAC_FRAME_TYPE_MGT | 0x0030) -+#define MAC_FRAME_PROBE_REQ (MAC_FRAME_TYPE_MGT | 0x0040) -+#define MAC_FRAME_PROBE_RSP (MAC_FRAME_TYPE_MGT | 0x0050) -+#define MAC_FRAME_BEACON (MAC_FRAME_TYPE_MGT | 0x0080) -+#define MAC_FRAME_ATIM (MAC_FRAME_TYPE_MGT | 0x0090) -+#define MAC_FRAME_DISASSOC (MAC_FRAME_TYPE_MGT | 0x00A0) -+#define MAC_FRAME_AUTH (MAC_FRAME_TYPE_MGT | 0x00B0) -+#define MAC_FRAME_DEAUTH (MAC_FRAME_TYPE_MGT | 0x00C0) -+#define MAC_FRAME_ACTION (MAC_FRAME_TYPE_MGT | 0x00D0) -+#define MAC_FRAME_ACTION_NO_ACK (MAC_FRAME_TYPE_MGT | 0x00E0) -+ -+#define MAC_FRAME_CONTRL_WRAPPER (MAC_FRAME_TYPE_CTRL | 0x0070) -+#define MAC_FRAME_BLOCK_ACK_REQ (MAC_FRAME_TYPE_CTRL | 0x0080) -+#define MAC_FRAME_BLOCK_ACK (MAC_FRAME_TYPE_CTRL | 0x0090) -+#define MAC_FRAME_PS_POLL (MAC_FRAME_TYPE_CTRL | 0x00A0) -+#define MAC_FRAME_RTS (MAC_FRAME_TYPE_CTRL | 0x00B0) -+#define MAC_FRAME_CTS (MAC_FRAME_TYPE_CTRL | 0x00C0) -+#define MAC_FRAME_ACK (MAC_FRAME_TYPE_CTRL | 0x00D0) -+#define MAC_FRAME_CF_END (MAC_FRAME_TYPE_CTRL | 0x00E0) -+#define MAC_FRAME_CF_END_CF_ACK (MAC_FRAME_TYPE_CTRL | 0x00F0) -+ -+#define MAC_FRAME_DATA (MAC_FRAME_TYPE_DATA | 0x0000) -+#define MAC_FRAME_DATA_CF_ACK (MAC_FRAME_TYPE_DATA | 0x0010) -+#define MAC_FRAME_DATA_CF_POLL (MAC_FRAME_TYPE_DATA | 0x0020) -+#define MAC_FRAME_DATA_CF_ACK_CF_POLL (MAC_FRAME_TYPE_DATA | 0x0030) -+#define MAC_FRAME_NULL (MAC_FRAME_TYPE_DATA | 0x0040) -+#define MAC_FRAME_CF_ACK (MAC_FRAME_TYPE_DATA | 0x0050) -+#define MAC_FRAME_CF_POLL (MAC_FRAME_TYPE_DATA | 0x0060) -+#define MAC_FRAME_CF_ACK_CF_POLL (MAC_FRAME_TYPE_DATA | 0x0070) -+#define MAC_FRAME_QOS_DATA (MAC_FRAME_TYPE_DATA | 0x0080) -+#define MAC_FRAME_QOS_DATA_CF_ACK (MAC_FRAME_TYPE_DATA | 0x0090) -+#define MAC_FRAME_QOS_DATA_CF_POLL (MAC_FRAME_TYPE_DATA | 0x00A0) -+#define MAC_FRAME_QOS_DATA_CF_ACK_CF_POLL (MAC_FRAME_TYPE_DATA | 0x00B0) -+#define MAC_FRAME_QOS_NULL (MAC_FRAME_TYPE_DATA | 0x00C0) -+#define MAC_FRAME_QOS_CF_POLL (MAC_FRAME_TYPE_DATA | 0x00E0) -+#define MAC_FRAME_QOS_CF_ACK_CF_POLL (MAC_FRAME_TYPE_DATA | 0x00F0) -+ -+/* 7.1.3.2 Mask for the AID value in the Duration/ID field */ -+#define MASK_DI_DURATION BITS(0, 14) -+#define MASK_DI_AID BITS(0, 13) -+#define MASK_DI_AID_MSB BITS(14, 15) -+#define MASK_DI_CFP_FIXED_VALUE BIT(15) -+ -+/* 7.1.3.4 Masks for the subfields in the Sequence Control field */ -+#define MASK_SC_SEQ_NUM BITS(4, 15) -+#define MASK_SC_SEQ_NUM_OFFSET 4 -+#define MASK_SC_FRAG_NUM BITS(0, 3) -+#define INVALID_SEQ_CTRL_NUM 0x000F /* According to 6.2.1.1.2 -+ * FRAG_NUM won't equal to 15 -+ */ -+ -+/* 7.1.3.5 QoS Control field */ -+#define TID_NUM 16 -+#define TID_MASK BITS(0, 3) -+#define EOSP BIT(4) -+#define ACK_POLICY BITS(5, 6) -+#define A_MSDU_PRESENT BIT(7) -+ -+#define MASK_QC_TID BITS(0, 3) -+#define MASK_QC_EOSP BIT(4) -+#define MASK_QC_EOSP_OFFSET 4 -+#define MASK_QC_ACK_POLICY BITS(5, 6) -+#define MASK_QC_ACK_POLICY_OFFSET 5 -+#define MASK_QC_A_MSDU_PRESENT BIT(7) -+ -+/* 7.1.3.5a HT Control field */ -+#define HT_CTRL_LINK_ADAPTATION_CTRL BITS(0, 15) -+#define HT_CTRL_CALIBRATION_POSITION BITS(16, 17) -+#define HT_CTRL_CALIBRATION_SEQUENCE BITS(18, 19) -+#define HT_CTRL_CSI_STEERING BITS(22, 23) -+#define HT_CTRL_NDP_ANNOUNCEMENT BIT(24) -+#define HT_CTRL_AC_CONSTRAINT BIT(30) -+#define HT_CTRL_RDG_MORE_PPDU BIT(31) -+ -+#define LINK_ADAPTATION_CTRL_TRQ BIT(1) -+#define LINK_ADAPTATION_CTRL_MAI_MRQ BIT(2) -+#define LINK_ADAPTATION_CTRL_MAI_MSI BITS(3, 5) -+#define LINK_ADAPTATION_CTRL_MFSI BITS(6, 8) -+#define LINK_ADAPTATION_CTRL_MFB_ASELC_CMD BITS(9, 11) -+#define LINK_ADAPTATION_CTRL_MFB_ASELC_DATA BITS(12, 15) -+ -+/* 7.1.3.5.3 Ack Policy subfield*/ -+#define ACK_POLICY_NORMAL_ACK_IMPLICIT_BA_REQ 0 -+#define ACK_POLICY_NO_ACK 1 -+#define ACK_POLICY_NO_EXPLICIT_ACK_PSMP_ACK 2 -+#define ACK_POLICY_BA 3 -+ -+/* 7.1.3.7 FCS field */ -+#define FCS_LEN 4 -+ -+/* 7.2.1.4 WLAN Control Frame - PS-POLL Frame */ -+#define PSPOLL_FRAME_LEN 16 /* w/o FCS */ -+ -+/* 7.2.7.1 BAR */ -+#define OFFSET_BAR_SSC_SN 4 -+ -+/* 8.3.2.2 TKIP MPDU formats */ -+#define TKIP_MIC_LEN 8 -+ -+/* 2009.11.30 mtk02468: Moved these definitions to the right place */ -+#if 0 -+/* Block Ack Parameter Set field */ -+#define BA_PARM_BA_POLICY BIT(1) -+#define BA_PARM_TID BITS(2, 5) -+#define BA_PARM_BUFFER_SIZE BITS(6, 15) -+#endif -+ -+#define BA_POLICY_IMMEDIATE BIT(1) -+ -+/* Block Ack Starting Sequence Control field */ -+#define BA_START_SEQ_CTL_FRAG_NUM BITS(0, 3) -+#define BA_START_SEQ_CTL_SSN BITS(4, 15) -+ -+/* BAR Control field */ -+#define BAR_CONTROL_NO_ACK_POLICY BIT(0) -+#define BAR_CONTROL_MULTI_TID BIT(1) -+#define BAR_CONTROL_COMPRESSED_BA BIT(2) -+#define BAR_CONTROL_TID_INFO BITS(12, 15) -+#define BAR_CONTROL_TID_INFO_OFFSET 12 -+ -+/* TID Value */ -+#define BAR_INFO_TID_VALUE BITS(12, 15) -+ -+#define BAR_COMPRESSED_VARIANT_FRAME_LEN (16 + 4) -+ -+/* 3 --------------- IEEE 802.11 frame body fields --------------- */ -+/* 3 Management frame body components (I): Fixed Fields. */ -+/* 7.3.1.1 Authentication Algorithm Number field */ -+#define AUTH_ALGORITHM_NUM_FIELD_LEN 2 -+ -+#define AUTH_ALGORITHM_NUM_OPEN_SYSTEM 0 /* Open System */ -+#define AUTH_ALGORITHM_NUM_SHARED_KEY 1 /* Shared Key */ -+#define AUTH_ALGORITHM_NUM_FAST_BSS_TRANSITION 2 /* Fast BSS Transition */ -+ -+/* 7.3.1.2 Authentication Transaction Sequence Number field */ -+#define AUTH_TRANSACTION_SEQENCE_NUM_FIELD_LEN 2 -+#define AUTH_TRANSACTION_SEQ_1 1 -+#define AUTH_TRANSACTION_SEQ_2 2 -+#define AUTH_TRANSACTION_SEQ_3 3 -+#define AUTH_TRANSACTION_SEQ_4 4 -+ -+/* 7.3.1.3 Beacon Interval field */ -+#define BEACON_INTERVAL_FIELD_LEN 2 -+ -+/* 7.3.1.4 Capability Information field */ -+#define CAP_INFO_FIELD_LEN 2 -+#define CAP_INFO_ESS BIT(0) -+#define CAP_INFO_IBSS BIT(1) -+#define CAP_INFO_BSS_TYPE (CAP_INFO_ESS | CAP_INFO_IBSS) -+#define CAP_INFO_CF_POLLABLE BIT(2) -+#define CAP_INFO_CF_POLL_REQ BIT(3) -+#define CAP_INFO_CF (CAP_INFO_CF_POLLABLE | CAP_INFO_CF_POLL_REQ) -+#define CAP_INFO_PRIVACY BIT(4) -+#define CAP_INFO_SHORT_PREAMBLE BIT(5) -+#define CAP_INFO_PBCC BIT(6) -+#define CAP_INFO_CH_AGILITY BIT(7) -+#define CAP_INFO_SPEC_MGT BIT(8) -+#define CAP_INFO_QOS BIT(9) -+#define CAP_INFO_SHORT_SLOT_TIME BIT(10) -+#define CAP_INFO_APSD BIT(11) -+#define CAP_INFO_RESERVED BIT(12) -+#define CAP_INFO_DSSS_OFDM BIT(13) -+#define CAP_INFO_DELAYED_BLOCK_ACK BIT(14) -+#define CAP_INFO_IMM_BLOCK_ACK BIT(15) -+/* STA usage of CF-Pollable and CF-Poll Request subfields */ -+/* STA: not CF-Pollable */ -+#define CAP_CF_STA_NOT_POLLABLE 0x0000 -+/* STA: CF-Pollable, not requesting on the CF-Polling list */ -+#define CAP_CF_STA_NOT_ON_LIST CAP_INFO_CF_POLL_REQ -+/* STA: CF-Pollable, requesting on the CF-Polling list */ -+#define CAP_CF_STA_ON_LIST CAP_INFO_CF_POLLABLE -+/* STA: CF-Pollable, requesting never to be polled */ -+#define CAP_CF_STA_NEVER_POLLED (CAP_INFO_CF_POLLABLE | CAP_INFO_CF_POLL_REQ) -+ -+/* AP usage of CF-Pollable and CF-Poll Request subfields */ -+/* AP: No point coordinator (PC) */ -+#define CAP_CF_AP_NO_PC 0x0000 -+/* AP: PC at AP for delivery only (no polling) */ -+#define CAP_CF_AP_DELIVERY_ONLY CAP_INFO_CF_POLL_REQ -+/* AP: PC at AP for delivery and polling */ -+#define CAP_CF_AP_DELIVERY_POLLING CAP_INFO_CF_POLLABLE -+ -+/* 7.3.1.5 Current AP Address field */ -+#define CURR_AP_ADDR_FIELD_LEN MAC_ADDR_LEN -+ -+/* 7.3.1.6 Listen Interval field */ -+#define LISTEN_INTERVAL_FIELD_LEN 2 -+ -+/* 7.3.1.7 Reason Code field */ -+#define REASON_CODE_FIELD_LEN 2 -+ -+#define REASON_CODE_RESERVED 0 /* Reseved */ -+#define REASON_CODE_UNSPECIFIED 1 /* Unspecified reason */ -+#define REASON_CODE_PREV_AUTH_INVALID 2 /* Previous auth no longer valid */ -+#define REASON_CODE_DEAUTH_LEAVING_BSS 3 /* Deauth because sending STA is leaving BSS */ -+#define REASON_CODE_DISASSOC_INACTIVITY 4 /* Disassoc due to inactivity */ -+#define REASON_CODE_DISASSOC_AP_OVERLOAD 5 /* Disassoc because AP is unable to handle all assoc STAs */ -+#define REASON_CODE_CLASS_2_ERR 6 /* Class 2 frame rx from nonauth STA */ -+#define REASON_CODE_CLASS_3_ERR 7 /* Class 3 frame rx from nonassoc STA */ -+#define REASON_CODE_DISASSOC_LEAVING_BSS 8 /* Disassoc because sending STA is leaving BSS */ -+#define REASON_CODE_ASSOC_BEFORE_AUTH 9 /* STA requesting (re)assoc is not auth with responding STA */ -+#define REASON_CODE_DISASSOC_PWR_CAP_UNACCEPTABLE 10 /* Disassoc because the info in Power Capability is -+ unacceptable */ -+#define REASON_CODE_DISASSOC_SUP_CHS_UNACCEPTABLE 11 /* Disassoc because the info in Supported Channels is -+ unacceptable */ -+#define REASON_CODE_INVALID_INFO_ELEM 13 /* Invalid information element */ -+#define REASON_CODE_MIC_FAILURE 14 /* MIC failure */ -+#define REASON_CODE_4_WAY_HANDSHAKE_TIMEOUT 15 /* 4-way handshake timeout */ -+#define REASON_CODE_GROUP_KEY_UPDATE_TIMEOUT 16 /* Group key update timeout */ -+#define REASON_CODE_DIFFERENT_INFO_ELEM 17 /* Info element in 4-way handshake different from -+ (Re-)associate request/Probe response/Beacon */ -+#define REASON_CODE_MULTICAST_CIPHER_NOT_VALID 18 /* Multicast Cipher is not valid */ -+#define REASON_CODE_UNICAST_CIPHER_NOT_VALID 19 /* Unicast Cipher is not valid */ -+#define REASON_CODE_AKMP_NOT_VALID 20 /* AKMP is not valid */ -+#define REASON_CODE_UNSUPPORTED_RSNE_VERSION 21 /* Unsupported RSNE version */ -+#define REASON_CODE_INVALID_RSNE_CAPABILITIES 22 /* Invalid RSNE Capabilities */ -+#define REASON_CODE_IEEE_802_1X_AUTH_FAILED 23 /* IEEE 802.1X Authentication failed */ -+#define REASON_CODE_CIPHER_REJECT_SEC_POLICY 24 /* Cipher suite rejected because of the security policy */ -+#define REASON_CODE_DISASSOC_UNSPECIFIED_QOS 32 /* Disassoc for unspecified, QoS-related reason */ -+#define REASON_CODE_DISASSOC_LACK_OF_BANDWIDTH 33 /* Disassoc because QAP lacks sufficient bandwidth -+ for this QSTA */ -+#define REASON_CODE_DISASSOC_ACK_LOST_POOR_CHANNEL 34 /* Disassoc because of too many ACKs lost for AP transmissions -+ and/or poor channel conditions */ -+#define REASON_CODE_DISASSOC_TX_OUTSIDE_TXOP_LIMIT 35 /* Disassoc because QSTA is transmitting outside the limits of -+ its TXOPs */ -+#define REASON_CODE_PEER_WHILE_LEAVING 36 /* QSTA is leaving the QBSS or resetting */ -+#define REASON_CODE_PEER_REFUSE_DLP 37 /* Peer does not want to use this mechanism */ -+#define REASON_CODE_PEER_SETUP_REQUIRED 38 /* Frames received but a setup is reqired */ -+#define REASON_CODE_PEER_TIME_OUT 39 /* Time out */ -+#define REASON_CODE_PEER_CIPHER_UNSUPPORTED 45 /* Peer does not support the requested cipher suite */ -+#define REASON_CODE_BEACON_TIMEOUT 100 /* for beacon timeout, defined by mediatek */ -+#define REASON_CODE_BSS_SECURITY_CHANGE 101 /* for BSS security change, defined by mediatek */ -+/* 7.3.1.8 AID field */ -+#define AID_FIELD_LEN 2 -+#define AID_MASK BITS(0, 13) -+#define AID_MSB BITS(14, 15) -+#define AID_MIN_VALUE 1 -+#define AID_MAX_VALUE 2007 -+ -+/* 7.3.1.9 Status Code field */ -+#define STATUS_CODE_FIELD_LEN 2 -+ -+#define STATUS_CODE_RESERVED 0 /* Reserved - Used by TX Auth */ -+#define STATUS_CODE_SUCCESSFUL 0 /* Successful */ -+#define STATUS_CODE_UNSPECIFIED_FAILURE 1 /* Unspecified failure */ -+#define STATUS_CODE_CAP_NOT_SUPPORTED 10 /* Cannot support all requested cap in the Cap Info field */ -+#define STATUS_CODE_REASSOC_DENIED_WITHOUT_ASSOC 11 /* Reassoc denied due to inability to confirm that -+ assoc exists */ -+#define STATUS_CODE_ASSOC_DENIED_OUTSIDE_STANDARD 12 /* Assoc denied due to reason outside the scope of this std. */ -+#define STATUS_CODE_AUTH_ALGORITHM_NOT_SUPPORTED 13 /* Responding STA does not support the specified -+ auth algorithm */ -+#define STATUS_CODE_AUTH_OUT_OF_SEQ 14 /* Rx an auth frame with auth transaction seq num -+ out of expected seq */ -+#define STATUS_CODE_AUTH_REJECTED_CHAL_FAIL 15 /* Auth rejected because of challenge failure */ -+#define STATUS_CODE_AUTH_REJECTED_TIMEOUT 16 /* Auth rejected due to timeout waiting for next frame -+ in sequence */ -+#define STATUS_CODE_ASSOC_DENIED_AP_OVERLOAD 17 /* Assoc denied because AP is unable to handle additional -+ assoc STAs */ -+#define STATUS_CODE_ASSOC_DENIED_RATE_NOT_SUPPORTED 18 /* Assoc denied due to requesting STA not supporting -+ all of basic rates */ -+#define STATUS_CODE_ASSOC_DENIED_NO_SHORT_PREAMBLE 19 /* Assoc denied due to requesting STA not supporting short -+ preamble */ -+#define STATUS_CODE_ASSOC_DENIED_NO_PBCC 20 /* Assoc denied due to requesting STA not supporting PBCC */ -+#define STATUS_CODE_ASSOC_DENIED_NO_CH_AGILITY 21 /* Assoc denied due to requesting STA not supporting channel -+ agility */ -+#define STATUS_CODE_ASSOC_REJECTED_NO_SPEC_MGT 22 /* Assoc rejected because Spectrum Mgt capability is required */ -+#define STATUS_CODE_ASSOC_REJECTED_PWR_CAP 23 /* Assoc rejected because the info in Power Capability -+ is unacceptable */ -+#define STATUS_CODE_ASSOC_REJECTED_SUP_CHS 24 /* Assoc rejected because the info in Supported Channels -+ is unacceptable */ -+#define STATUS_CODE_ASSOC_DENIED_NO_SHORT_SLOT_TIME 25 /* Assoc denied due to requesting STA not supporting -+ short slot time */ -+#define STATUS_CODE_ASSOC_DENIED_NO_DSSS_OFDM 26 /* Assoc denied due to requesting STA not supporting -+ DSSS-OFDM */ -+#if CFG_SUPPORT_802_11W -+#define STATUS_CODE_ASSOC_REJECTED_TEMPORARILY 30 /* IEEE 802.11w, Assoc denied due to the SA query */ -+#define STATUS_CODE_ROBUST_MGMT_FRAME_POLICY_VIOLATION 31 /* IEEE 802.11w, Assoc denied due to the MFP select -+ policy */ -+#endif -+#define STATUS_CODE_UNSPECIFIED_QOS_FAILURE 32 /* Unspecified, QoS-related failure */ -+#define STATUS_CODE_ASSOC_DENIED_BANDWIDTH 33 /* Assoc denied due to insufficient bandwidth to handle another -+ QSTA */ -+#define STATUS_CODE_ASSOC_DENIED_POOR_CHANNEL 34 /* Assoc denied due to excessive frame loss rates and/or poor -+ channel conditions */ -+#define STATUS_CODE_ASSOC_DENIED_NO_QOS_FACILITY 35 /* Assoc denied due to requesting STA not supporting QoS -+ facility */ -+#define STATUS_CODE_REQ_DECLINED 37 /* Request has been declined */ -+#define STATUS_CODE_REQ_INVALID_PARAMETER_VALUE 38 /* Request has not been successful as one or more parameters -+ have invalid values */ -+#define STATUS_CODE_REQ_NOT_HONORED_TSPEC 39 /* TS not created because request cannot be honored. -+ Suggested TSPEC provided. */ -+#define STATUS_CODE_INVALID_INFO_ELEMENT 40 /* Invalid information element */ -+#define STATUS_CODE_INVALID_GROUP_CIPHER 41 /* Invalid group cipher */ -+#define STATUS_CODE_INVALID_PAIRWISE_CIPHER 42 /* Invalid pairwise cipher */ -+#define STATUS_CODE_INVALID_AKMP 43 /* Invalid AKMP */ -+#define STATUS_CODE_UNSUPPORTED_RSN_IE_VERSION 44 /* Unsupported RSN information element version */ -+#define STATUS_CODE_INVALID_RSN_IE_CAP 45 /* Invalid RSN information element capabilities */ -+#define STATUS_CODE_CIPHER_SUITE_REJECTED 46 /* Cipher suite rejected because of security policy */ -+#define STATUS_CODE_REQ_NOT_HONORED_TS_DELAY 47 /* TS not created because request cannot be honored. -+ Attempt to create a TS later. */ -+#define STATUS_CODE_DIRECT_LINK_NOT_ALLOWED 48 /* Direct Link is not allowed in the BSS by policy */ -+#define STATUS_CODE_DESTINATION_STA_NOT_PRESENT 49 /* Destination STA is not present within this QBSS */ -+#define STATUS_CODE_DESTINATION_STA_NOT_QSTA 50 /* Destination STA is not a QSTA */ -+#define STATUS_CODE_ASSOC_DENIED_LARGE_LIS_INTERVAL 51 /* Association denied because the ListenInterval is too large */ -+ -+/* proprietary definition of reserved field of Status Code */ -+#define STATUS_CODE_JOIN_FAILURE 0xFFF0 /* Join failure */ -+#define STATUS_CODE_JOIN_TIMEOUT 0xFFF1 /* Join timeout */ -+#define STATUS_CODE_AUTH_TIMEOUT 0xFFF2 /* Authentication timeout */ -+#define STATUS_CODE_ASSOC_TIMEOUT 0xFFF3 /* (Re)Association timeout */ -+#define STATUS_CODE_CCX_CCKM_REASSOC_FAILURE 0xFFF4 /* CCX CCKM reassociation failure */ -+ -+/* 7.3.1.10 Timestamp field */ -+#define TIMESTAMP_FIELD_LEN 8 -+ -+/* 7.3.1.11 Category of Action field */ -+#define CATEGORY_SPEC_MGT 0 -+#define CATEGORY_QOS_ACTION 1 /* QoS action */ -+#define CATEGORY_DLS_ACTION 2 /* Direct Link Protocol (DLP) action */ -+#define CATEGORY_BLOCK_ACK_ACTION 3 /* Block ack action */ -+#define CATEGORY_PUBLIC_ACTION 4 /* Public action */ -+#define CATEGORY_RM_ACTION 5 /* Radio measurement action */ -+#define CATEGORY_HT_ACTION 7 -+#if CFG_SUPPORT_802_11W -+#define CATEGORY_SA_QUERT_ACTION 8 -+#endif -+#define CATEGORY_WNM_ACTION 10 /* 802.11v Wireless Network Management */ -+#define CATEGORY_UNPROTECTED_WNM_ACTION 11 /* 802.11v Wireless Network Management */ -+#define CATEGORY_WME_MGT_NOTIFICATION 17 /* WME management notification */ -+#define CATEGORY_VENDOR_SPECIFIC_ACTION 127 -+ -+/* 7.3.1.14 Block Ack Parameter Set field */ -+#define BA_PARAM_SET_ACK_POLICY_MASK BIT(1) -+#define BA_PARAM_SET_ACK_POLICY_MASK_OFFSET 1 -+#define BA_PARAM_SET_TID_MASK BITS(2, 5) -+#define BA_PARAM_SET_TID_MASK_OFFSET 2 -+#define BA_PARAM_SET_BUFFER_SIZE_MASK BITS(6, 15) -+#define BA_PARAM_SET_BUFFER_SIZE_MASK_OFFSET 6 -+ -+#define BA_PARAM_SET_ACK_POLICY_IMMEDIATE_BA 1 -+#define BA_PARAM_SET_ACK_POLICY_DELAYED_BA 0 -+ -+/* 3 Management frame body components (II): Information Elements. */ -+/* 7.3.2 Element IDs of information elements */ -+#define ELEM_HDR_LEN 2 -+ -+#define ELEM_ID_SSID 0 /* SSID */ -+#define ELEM_ID_SUP_RATES 1 /* Supported rates */ -+#define ELEM_ID_FH_PARAM_SET 2 /* FH parameter set */ -+#define ELEM_ID_DS_PARAM_SET 3 /* DS parameter set */ -+#define ELEM_ID_CF_PARAM_SET 4 /* CF parameter set */ -+#define ELEM_ID_TIM 5 /* TIM */ -+#define ELEM_ID_IBSS_PARAM_SET 6 /* IBSS parameter set */ -+#define ELEM_ID_COUNTRY_INFO 7 /* Country information */ -+#define ELEM_ID_HOPPING_PATTERN_PARAM 8 /* Hopping pattern parameters */ -+#define ELEM_ID_HOPPING_PATTERN_TABLE 9 /* Hopping pattern table */ -+#define ELEM_ID_REQUEST 10 /* Request */ -+#define ELEM_ID_BSS_LOAD 11 /* BSS load */ -+#define ELEM_ID_EDCA_PARAM_SET 12 /* EDCA parameter set */ -+#define ELEM_ID_TSPEC 13 /* Traffic specification (TSPEC) */ -+#define ELEM_ID_TCLAS 14 /* Traffic classification (TCLAS) */ -+#define ELEM_ID_SCHEDULE 15 /* Schedule */ -+#define ELEM_ID_CHALLENGE_TEXT 16 /* Challenge text */ -+ -+#define ELEM_ID_PWR_CONSTRAINT 32 /* Power constraint */ -+#define ELEM_ID_PWR_CAP 33 /* Power capability */ -+#define ELEM_ID_TPC_REQ 34 /* TPC request */ -+#define ELEM_ID_TPC_REPORT 35 /* TPC report */ -+#define ELEM_ID_SUP_CHS 36 /* Supported channels */ -+#define ELEM_ID_CH_SW_ANNOUNCEMENT 37 /* Channel switch announcement */ -+#define ELEM_ID_MEASUREMENT_REQ 38 /* Measurement request */ -+#define ELEM_ID_MEASUREMENT_REPORT 39 /* Measurement report */ -+#define ELEM_ID_QUIET 40 /* Quiet */ -+#define ELEM_ID_IBSS_DFS 41 /* IBSS DFS */ -+#define ELEM_ID_ERP_INFO 42 /* ERP information */ -+#define ELEM_ID_TS_DELAY 43 /* TS delay */ -+#define ELEM_ID_TCLAS_PROCESSING 44 /* TCLAS processing */ -+#define ELEM_ID_HT_CAP 45 /* HT Capabilities subelement */ -+#define ELEM_ID_QOS_CAP 46 /* QoS capability */ -+#define ELEM_ID_RSN 48 /* RSN IE */ -+#define ELEM_ID_EXTENDED_SUP_RATES 50 /* Extended supported rates */ -+#define ELEM_ID_TIMEOUT_INTERVAL 56 /* 802.11w SA Timeout interval */ -+#define ELEM_ID_SUP_OPERATING_CLASS 59 /* Supported Operating Classes */ -+#define ELEM_ID_HT_OP 61 /* HT Operation */ -+#define ELEM_ID_SCO 62 /* Secondary Channel Offset */ -+#define ELEM_ID_RRM_ENABLED_CAP 70 /* Radio Resource Management Enabled Capabilities */ -+#define ELEM_ID_20_40_BSS_COEXISTENCE 72 /* 20/40 BSS Coexistence */ -+#define ELEM_ID_20_40_INTOLERANT_CHNL_REPORT 73 /* 20/40 BSS Intolerant Channel Report */ -+#define ELEM_ID_OBSS_SCAN_PARAMS 74 /* Overlapping BSS Scan Parameters */ -+#define ELEM_ID_INTERWORKING 107 /* Interworking with External Network */ -+#define ELEM_ID_ADVERTISEMENT_PROTOCOL 108 /* Advertisement Protocol */ -+#define ELEM_ID_ROAMING_CONSORTIUM 111 /* Roaming Consortium */ -+#define ELEM_ID_EXTENDED_CAP 127 /* Extended capabilities */ -+ -+#define ELEM_ID_VENDOR 221 /* Vendor specific IE */ -+#define ELEM_ID_WPA ELEM_ID_VENDOR /* WPA IE */ -+#define ELEM_ID_WMM ELEM_ID_VENDOR /* WMM IE */ -+#define ELEM_ID_P2P ELEM_ID_VENDOR /* WiFi Direct */ -+#define ELEM_ID_WFD ELEM_ID_VENDOR /* WiFi Direct */ -+#define ELEM_ID_WSC ELEM_ID_VENDOR /* WSC IE */ -+ -+#define ELEM_ID_RESERVED 255 /* Reserved */ -+ -+/* 7.3.2.1 SSID element */ -+#define ELEM_MAX_LEN_SSID 32 -+ -+/* 7.3.2.2 Supported Rates */ -+#define ELEM_MAX_LEN_SUP_RATES 8 -+ -+/* 7.3.2.4 DS Parameter Set */ -+#define ELEM_MAX_LEN_DS_PARAMETER_SET 1 -+ -+/* 7.3.2.5 CF Parameter Set */ -+#define ELEM_CF_PARM_LEN 8 -+ -+/* 7.3.2.6 TIM */ -+#define ELEM_MIX_LEN_TIM 4 -+#define ELEM_MAX_LEN_TIM 254 -+ -+/* 7.3.2.7 IBSS Parameter Set element */ -+#define ELEM_MAX_LEN_IBSS_PARAMETER_SET 2 -+ -+/* 7.3.2.8 Challenge Text element */ -+#define ELEM_MIN_LEN_CHALLENGE_TEXT 1 -+#define ELEM_MAX_LEN_CHALLENGE_TEXT 253 -+ -+/* 7.3.2.9 Country Information element */ -+/* Country IE should contain at least 3-bytes country code string and one subband triplet. */ -+#define ELEM_MIN_LEN_COUNTRY_INFO 6 -+ -+#define ELEM_ID_COUNTRY_INFO_TRIPLET_LEN_FIXED 3 -+#define ELEM_ID_COUNTRY_INFO_SUBBAND_TRIPLET_LEN_FIXED 3 -+#define ELEM_ID_COUNTRY_INFO_REGULATORY_TRIPLET_LEN_FIXED 3 -+ -+/* 7.3.2.13 ERP Information element */ -+#define ELEM_MAX_LEN_ERP 1 -+/* -- bits in the ERP Information element */ -+#define ERP_INFO_NON_ERP_PRESENT BIT(0) /* NonERP_Present bit */ -+#define ERP_INFO_USE_PROTECTION BIT(1) /* Use_Protection bit */ -+#define ERP_INFO_BARKER_PREAMBLE_MODE BIT(2) /* Barker_Preamble_Mode bit */ -+ -+/* 7.3.2.14 Extended Supported Rates */ -+#define ELEM_MAX_LEN_EXTENDED_SUP_RATES 255 -+ -+#if CFG_SUPPORT_DFS -+/* 7.3.2.19 Supported Channels element */ -+#define ELEM_MAX_LEN_SUPPORTED_CHANNELS 7 -+#endif -+ -+/* 7.3.2.21 Measurement Request element */ -+#define ELEM_RM_TYPE_BASIC_REQ 0 -+#define ELEM_RM_TYPE_CCA_REQ 1 -+#define ELEM_RM_TYPE_RPI_HISTOGRAM_REQ 2 -+#define ELEM_RM_TYPE_CHNL_LOAD_REQ 3 -+#define ELEM_RM_TYPE_NOISE_HISTOGRAM_REQ 4 -+#define ELEM_RM_TYPE_BEACON_REQ 5 -+#define ELEM_RM_TYPE_FRAME_REQ 6 -+#define ELEM_RM_TYPE_STA_STATISTICS_REQ 7 -+#define ELEM_RM_TYPE_LCI_REQ 8 -+#define ELEM_RM_TYPE_TS_REQ 9 -+#define ELEM_RM_TYPE_MEASURE_PAUSE_REQ 255 -+ -+/* 7.3.2.22 Measurement Report element */ -+#define ELEM_RM_TYPE_BASIC_REPORT 0 -+#define ELEM_RM_TYPE_CCA_REPORT 1 -+#define ELEM_RM_TYPE_RPI_HISTOGRAM_REPORT 2 -+#define ELEM_RM_TYPE_CHNL_LOAD_REPORT 3 -+#define ELEM_RM_TYPE_NOISE_HISTOGRAM_REPORT 4 -+#define ELEM_RM_TYPE_BEACON_REPORT 5 -+#define ELEM_RM_TYPE_FRAME_REPORT 6 -+#define ELEM_RM_TYPE_STA_STATISTICS_REPORT 7 -+#define ELEM_RM_TYPE_LCI_REPORT 8 -+#define ELEM_RM_TYPE_TS_REPORT 9 -+/*Auto Channel Selection*/ -+#if CFG_AUTO_CHANNEL_SEL_SUPPORT -+#define ELEM_RM_TYPE_ACS_CHN 1 -+#define ELEM_RM_TYPE_LTE_CHN 2 -+#endif -+ -+/* 7.3.2.25 RSN information element */ -+#define ELEM_MAX_LEN_WPA 34 /* one pairwise, one AKM suite, one PMKID */ -+#define ELEM_MAX_LEN_RSN 38 /* one pairwise, one AKM suite, one PMKID */ -+#define ELEM_MAX_LEN_WAPI 38 /* one pairwise, one AKM suite, one BKID */ -+#define ELEM_MAX_LEN_WSC 200 /* one pairwise, one AKM suite, one BKID */ -+ -+#if CFG_SUPPORT_802_11W -+#define ELEM_WPA_CAP_MFPR BIT(6) -+#define ELEM_WPA_CAP_MFPC BIT(7) -+#endif -+ -+/* 7.3.2.27 Extended Capabilities information element */ -+#define ELEM_EXT_CAP_20_40_COEXIST_SUPPORT BIT(0) -+#define ELEM_EXT_CAP_PSMP_CAP BIT(4) -+#define ELEM_EXT_CAP_SERVICE_INTERVAL_GRANULARITY BIT(5) -+#define ELEM_EXT_CAP_SCHEDULE_PSMP BIT(6) -+ -+#define ELEM_EXT_CAP_BSS_TRANSITION_BIT 19 -+#define ELEM_EXT_CAP_UTC_TSF_OFFSET_BIT 27 -+#define ELEM_EXT_CAP_INTERWORKING_BIT 31 -+#define ELEM_EXT_CAP_WNM_NOTIFICATION_BIT 46 -+ -+#if CFG_SUPPORT_HOTSPOT_2_0 -+#define ELEM_MAX_LEN_EXT_CAP (6) -+#else -+#define ELEM_MAX_LEN_EXT_CAP (3 - ELEM_HDR_LEN) -+#endif -+ -+/* 7.3.2.30 TSPEC element */ -+#define TS_INFO_TRAFFIC_TYPE_MASK BIT(0) /* WMM: 0 (Asynchronous TS of low-duty cycles) */ -+#define TS_INFO_TID_OFFSET 1 -+#define TS_INFO_TID_MASK BITS(1, 4) -+#define TS_INFO_DIRECTION_OFFSET 5 -+#define TS_INFO_DIRECTION_MASK BITS(5, 6) -+#define TS_INFO_ACCESS_POLICY_OFFSET 7 -+#define TS_INFO_ACCESS_POLICY_MASK BITS(7, 8) -+#define TS_INFO_AGGREGATION_MASK BIT(9) /* WMM: 0 */ -+#define TS_INFO_APSD_MASK BIT(10) -+#define TS_INFO_UP_OFFSET 11 -+#define TS_INFO_UP_MASK BITS(11, 13) -+#define TS_INFO_ACK_POLICY_OFFSET 14 -+#define TS_INFO_ACK_POLICY_MASK BITS(14, 15) -+#define TS_INFO_SCHEDULE_MASK 16 -+ -+/* 7.3.2.56 HT capabilities element */ -+#define ELEM_MAX_LEN_HT_CAP (28 - ELEM_HDR_LEN) /* sizeof(IE_HT_CAP_T)-2 */ -+ -+/* 7.3.2.56.2 HT capabilities Info field */ -+#define HT_CAP_INFO_LDPC_CAP BIT(0) -+#define HT_CAP_INFO_SUP_CHNL_WIDTH BIT(1) -+#define HT_CAP_INFO_SM_POWER_SAVE BITS(2, 3) -+#define HT_CAP_INFO_HT_GF BIT(4) -+#define HT_CAP_INFO_SHORT_GI_20M BIT(5) -+#define HT_CAP_INFO_SHORT_GI_40M BIT(6) -+#define HT_CAP_INFO_TX_STBC BIT(7) -+#define HT_CAP_INFO_RX_STBC BITS(8, 9) -+#define HT_CAP_INFO_HT_DELAYED_BA BIT(10) -+#define HT_CAP_INFO_MAX_AMSDU_LEN BIT(11) -+#define HT_CAP_INFO_DSSS_CCK_IN_40M BIT(12) -+#define HT_CAP_INFO_40M_INTOLERANT BIT(14) -+#define HT_CAP_INFO_LSIG_TXOP_SUPPORT BIT(15) -+ -+#define HT_CAP_INFO_RX_STBC_NO_SUPPORTED 0 -+#define HT_CAP_INFO_RX_STBC_1_SS BIT(8) -+#define HT_CAP_INFO_RX_STBC_2_SS BIT(9) -+#define HT_CAP_INFO_RX_STBC_3_SS HT_CAP_INFO_RX_STBC -+ -+/* 7.3.2.56.3 A-MPDU Parameters field */ -+#define AMPDU_PARAM_MAX_AMPDU_LEN_EXP BITS(0, 1) -+#define AMPDU_PARAM_MIN_START_SPACING BITS(2, 4) -+ -+#define AMPDU_PARAM_MAX_AMPDU_LEN_8K 0 -+#define AMPDU_PARAM_MAX_AMPDU_LEN_16K BIT(0) -+#define AMPDU_PARAM_MAX_AMPDU_LEN_32K BIT(1) -+#define AMPDU_PARAM_MAX_AMPDU_LEN_64K BITS(0, 1) -+ -+#define AMPDU_PARAM_MSS_NO_RESTRICIT 0 -+#define AMPDU_PARAM_MSS_1_4_US BIT(2) -+#define AMPDU_PARAM_MSS_1_2_US BIT(3) -+#define AMPDU_PARAM_MSS_1_US BITS(2, 3) -+#define AMPDU_PARAM_MSS_2_US BIT(4) -+#define AMPDU_PARAM_MSS_4_US (BIT(4) | BIT(2)) -+#define AMPDU_PARAM_MSS_8_US (BIT(4) | BIT(3)) -+#define AMPDU_PARAM_MSS_16_US BITS(2, 4) -+ -+/* 7.3.2.56.4 Supported MCS Set field (TX rate: octects 12~15) */ -+#define SUP_MCS_TX_SET_DEFINED BIT(0) -+#define SUP_MCS_TX_RX_SET_NOT_EQUAL BIT(1) -+#define SUP_MCS_TX_MAX_NUM_SS BITS(2, 3) -+#define SUP_MCS_TX_UNEQUAL_MODULATION BIT(4) -+ -+#define SUP_MCS_TX_MAX_NUM_1_SS 0 -+#define SUP_MCS_TX_MAX_NUM_2_SS BIT(2) -+#define SUP_MCS_TX_MAX_NUM_3_SS BIT(3) -+#define SUP_MCS_TX_MAX_NUM_4_SS BITS(2, 3) -+ -+#define SUP_MCS_RX_BITMASK_OCTET_NUM 10 -+#define SUP_MCS_RX_DEFAULT_HIGHEST_RATE 0 /* Not specify */ -+ -+/* 7.3.2.56.5 HT Extended Capabilities field */ -+#define HT_EXT_CAP_PCO BIT(0) -+#define HT_EXT_CAP_PCO_TRANSITION_TIME BITS(1, 2) -+#define HT_EXT_CAP_MCS_FEEDBACK BITS(8, 9) -+#define HT_EXT_CAP_HTC_SUPPORT BIT(10) -+#define HT_EXT_CAP_RD_RESPONDER BIT(11) -+ -+#define HT_EXT_CAP_PCO_TRANS_TIME_NONE 0 -+#define HT_EXT_CAP_PCO_TRANS_TIME_400US BIT(1) -+#define HT_EXT_CAP_PCO_TRANS_TIME_1_5MS BIT(2) -+#define HT_EXT_CAP_PCO_TRANS_TIME_5MS BITS(1, 2) -+ -+#define HT_EXT_CAP_MCS_FEEDBACK_NO_FB 0 -+#define HT_EXT_CAP_MCS_FEEDBACK_UNSOLICITED BIT(9) -+#define HT_EXT_CAP_MCS_FEEDBACK_BOTH BITS(8, 9) -+ -+/* 7.3.2.56.6 Transmit Beamforming Capabilities field */ -+ -+/* 7.3.2.56.7 Antenna Selection Capability field */ -+#define ASEL_CAP_CAPABLE BIT(0) -+#define ASEL_CAP_CSI_FB_BY_TX_ASEL_CAPABLE BIT(1) -+#define ASEL_CAP_ANT_INDICES_FB_BY_TX_ASEL_CAPABLE BIT(2) -+#define ASEL_CAP_EXPLICIT_CSI_FB_CAPABLE BIT(3) -+#define ASEL_CAP_ANT_INDICES_CAPABLE BIT(4) -+#define ASEL_CAP_RX_ASEL_CAPABLE BIT(5) -+#define ASEL_CAP_TX_SOUNDING_CAPABLE BIT(6) -+ -+/* 7.3.2.57 HT Operation element */ -+#define ELEM_MAX_LEN_HT_OP (24 - ELEM_HDR_LEN) /* sizeof(IE_HT_OP_T)-2 */ -+ -+#define HT_OP_INFO1_SCO BITS(0, 1) -+#define HT_OP_INFO1_STA_CHNL_WIDTH BIT(2) -+#define HT_OP_INFO1_RIFS_MODE BIT(3) -+ -+#define HT_OP_INFO2_HT_PROTECTION BITS(0, 1) -+#define HT_OP_INFO2_NON_GF_HT_STA_PRESENT BIT(2) -+#define HT_OP_INFO2_OBSS_NON_HT_STA_PRESENT BIT(4) -+ -+#define HT_OP_INFO3_DUAL_BEACON BIT(6) -+#define HT_OP_INFO3_DUAL_CTS_PROTECTION BIT(7) -+#define HT_OP_INFO3_STBC_BEACON BIT(8) -+#define HT_OP_INFO3_LSIG_TXOP_FULL_SUPPORT BIT(9) -+#define HT_OP_INFO3_PCO_ACTIVE BIT(10) -+#define HT_OP_INFO3_PCO_PHASE BIT(11) -+ -+/* 7.3.2.59 OBSS Scan Parameter element */ -+#define ELEM_MAX_LEN_OBSS_SCAN (16 - ELEM_HDR_LEN) -+ -+/* 7.3.2.60 20/40 BSS Coexistence element */ -+#define ELEM_MAX_LEN_20_40_BSS_COEXIST (3 - ELEM_HDR_LEN) -+ -+#define BSS_COEXIST_INFO_REQ BIT(0) -+#define BSS_COEXIST_40M_INTOLERANT BIT(1) -+#define BSS_COEXIST_20M_REQ BIT(2) -+#define BSS_COEXIST_OBSS_SCAN_EXEMPTION_REQ BIT(3) -+#define BSS_COEXIST_OBSS_SCAN_EXEMPTION_GRANT BIT(4) -+ -+/* 802.11u 7.3.2.92 Interworking IE */ -+#define ELEM_MAX_LEN_INTERWORKING (11 - ELEM_HDR_LEN) -+ -+/* 802.11u 7.3.2.93 Advertisement Protocol IE */ -+#define ELEM_MAX_LEN_ADV_PROTOCOL (4 - ELEM_HDR_LEN) -+ -+/* 802.11u 7.3.2.96 Roaming Consortium IE */ -+#define ELEM_MAX_LEN_ROAMING_CONSORTIUM (19 - ELEM_HDR_LEN) -+ -+#define IW_IE_LENGTH_ANO 1 -+#define IW_IE_LENGTH_ANO_VENUE 3 -+#define IW_IE_LENGTH_ANO_HESSID 7 -+#define IW_IE_LENGTH_ANO_VENUE_HESSID 9 -+ -+/* 3 Management frame body components (III): 7.4 Action frame format details. */ -+/* 7.4.1 Spectrum Measurement Action frame details */ -+#define ACTION_MEASUREMENT_REQ 0 /* Spectrum measurement request */ -+#define ACTION_MEASUREMENT_REPORT 1 /* Spectrum measurement report */ -+#define ACTION_TPC_REQ 2 /* TPC request */ -+#define ACTION_TPC_REPORT 3 /* TPC report */ -+#define ACTION_CHNL_SWITCH 4 /* Channel Switch Announcement */ -+ -+/* 7.4.2 QoS Action frame details */ -+#define ACTION_ADDTS_REQ 0 /* ADDTS request */ -+#define ACTION_ADDTS_RSP 1 /* ADDTS response */ -+#define ACTION_DELTS 2 /* DELTS */ -+#define ACTION_SCHEDULE 3 /* Schedule */ -+ -+#define ACTION_ADDTS_REQ_FRAME_LEN (24+3+63) /* WMM TSPEC IE: 63 */ -+#define ACTION_ADDTS_RSP_FRAME_LEN (24+4+63) /* WMM Status Code: 1; WMM TSPEC IE: 63 */ -+ -+/* 7.4.3 DLS Action frame details */ -+#define ACTION_DLS_REQ 0 /* DLS request */ -+#define ACTION_DLS_RSP 1 /* DLS response */ -+#define ACTION_DLS_TEARDOWN 2 /* DLS teardown */ -+ -+/* 7.4.4 Block ack Action frame details */ -+#define ACTION_ADDBA_REQ 0 /* ADDBA request */ -+#define ACTION_ADDBA_RSP 1 /* ADDBA response */ -+#define ACTION_DELBA 2 /* DELBA */ -+ -+#define ACTION_ADDBA_REQ_FRAME_LEN (24+9) -+#define ACTION_ADDBA_RSP_FRAME_LEN (24+9) -+ -+#define ACTION_DELBA_INITIATOR_MASK BIT(11) -+#define ACTION_DELBA_TID_MASK BITS(12, 15) -+#define ACTION_DELBA_TID_OFFSET 12 -+#define ACTION_DELBA_FRAME_LEN (24+6) -+ -+/* 7.4.6 Radio Measurement Action frame details */ -+#define ACTION_RM_REQ 0 /* Radio measurement request */ -+#define ACTION_RM_REPORT 1 /* Radio measurement report */ -+#define ACTION_LM_REQ 2 /* Link measurement request */ -+#define ACTION_LM_REPORT 3 /* Link measurement report */ -+#define ACTION_NEIGHBOR_REPORT_REQ 4 /* Neighbor report request */ -+#define ACTION_NEIGHBOR_REPORT_RSP 5 /* Neighbor report response */ -+ -+/* 7.4.7 Public Action frame details */ -+#define ACTION_PUBLIC_20_40_COEXIST 0 /* 20/40 BSS coexistence */ -+ -+#if CFG_SUPPORT_802_11W -+/* SA Query Action frame (IEEE 802.11w/D8.0, 7.4.9) */ -+#define ACTION_SA_QUERY_REQUEST 0 -+#define ACTION_SA_QUERY_RESPONSE 1 -+ -+#define ACTION_SA_QUERY_TR_ID_LEN 2 -+ -+/* Timeout Interval Type */ -+#define ACTION_SA_TIMEOUT_REASSOC_DEADLINE 1 -+#define ACTION_SA_TIMEOUT_KEY_LIFETIME 2 -+#define ACTION_SA_TIMEOUT_ASSOC_COMEBACK 3 -+#endif -+ -+/* 7.4.10.1 HT action frame details */ -+#define ACTION_HT_NOTIFY_CHANNEL_WIDTH 0 /* Notify Channel Width */ -+#define ACTION_HT_SM_POWER_SAVE 1 /* SM Power Save */ -+#define ACTION_HT_PSMP 2 /* PSMP */ -+#define ACTION_HT_SET_PCO_PHASE 3 /* Set PCO Phase */ -+#define ACTION_HT_CSI 4 /* CSI */ -+#define ACTION_HT_NON_COMPRESSED_BEAMFORM 5 /* Non-compressed Beamforming */ -+#define ACTION_HT_COMPRESSED_BEAMFORM 6 /* Compressed Beamforming */ -+#define ACTION_HT_ANT_SEL_INDICES_FB 7 /* Antenna Selection Indices Feedback */ -+ -+/* 802.11v Wireless Network Management */ -+#define ACTION_WNM_TIMING_MEASUREMENT_REQUEST 27 -+ -+#define ACTION_UNPROTECTED_WNM_TIM 0 -+#define ACTION_UNPROTECTED_WNM_TIMING_MEASUREMENT 1 -+ -+#define ACTION_UNPROTECTED_WNM_TIMING_MEAS_LEN 12 -+ -+/* 3 --------------- WFA frame body fields --------------- */ -+#define VENDOR_OUI_WFA { 0x00, 0x50, 0xF2 } -+#define VENDOR_OUI_WFA_SPECIFIC { 0x50, 0x6F, 0x9A } -+#define VENDOR_OUI_TYPE_WPA 1 -+#define VENDOR_OUI_TYPE_WMM 2 -+#define VENDOR_OUI_TYPE_WPS 4 -+#define VENDOR_OUI_TYPE_P2P 9 -+#define VENDOR_OUI_TYPE_WFD 10 -+#define VENDOR_OUI_TYPE_HS20 16 -+ -+#define VENDOR_OUI_TYPE_LEN 4 /* Length of OUI and Type */ -+ -+/* VERSION(2 octets for WPA) / SUBTYPE(1 octet)-VERSION(1 octet) fields for WMM in WFA IE */ -+#define VERSION_WPA 0x0001 /* Little Endian Format */ -+#define VENDOR_OUI_SUBTYPE_VERSION_WMM_INFO 0x0100 -+#define VENDOR_OUI_SUBTYPE_VERSION_WMM_PARAM 0x0101 -+ -+/* SUBTYPE(1 octet) for WMM */ -+#define VENDOR_OUI_SUBTYPE_WMM_INFO 0x00 /* WMM Spec version 1.1 */ -+#define VENDOR_OUI_SUBTYPE_WMM_PARAM 0x01 -+#define VENDOR_OUI_SUBTYPE_WMM_TSPEC 0x02 -+ -+/* VERSION(1 octet) for WMM */ -+#define VERSION_WMM 0x01 /* WMM Spec version 1.1 */ -+ -+/* WMM-2.1.6 QoS Control Field */ -+#define WMM_QC_UP_MASK BITS(0, 2) -+#define WMM_QC_EOSP BIT(4) -+#define WMM_QC_ACK_POLICY_MASK BITS(5, 6) -+#define WMM_QC_ACK_POLICY_OFFSET 5 -+#define WMM_QC_ACK_POLICY_ACKNOWLEDGE 0 -+#define WMM_QC_ACK_POLICY_NOT_ACKNOWLEDGE (1 << WMM_QC_ACK_POLICY_OFFSET) -+ -+/* WMM-2.2.1 WMM Information Element */ -+#define ELEM_MIN_LEN_WFA_OUI_TYPE_SUBTYPE 6 -+ -+/* HOTSPOT 2.0 Indication IE*/ -+#define ELEM_MAX_LEN_HS20_INDICATION 5 -+#define ELEM_MIN_LEN_HS20_INDICATION 4 -+ -+/* Hotspot Configuration*/ -+#define ELEM_HS_CONFIG_DGAF_DISABLED_MASK BIT(0) /* Downstream Group-Addressed Forwarding */ -+ -+/* 3 Control frame body */ -+/* 7.2.1.7 BlockAckReq */ -+#define CTRL_BAR_BAR_CONTROL_OFFSET 16 -+#define CTRL_BAR_BAR_INFORMATION_OFFSET 18 -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+#if defined(WINDOWS_DDK) || defined(WINDOWS_CE) -+#pragma pack(1) -+#endif -+ -+typedef struct _LLC_SNAP_HEADER_T { -+ UINT_8 ucDSAP; -+ UINT_8 ucSSAP; -+ UINT_8 ucControl; -+ UINT_8 aucCode[3]; -+ UINT_16 u2Type; -+} __KAL_ATTRIB_PACKED__ LLC_SNAP_HEADER_T, *P_LLC_SNAP_HEADER_T; -+ -+/* 3 MAC Header. */ -+/* Ethernet Frame Header */ -+typedef struct _ETH_FRAME_HEADER_T { -+ UINT_8 aucDestAddr[MAC_ADDR_LEN]; -+ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; -+ UINT_16 u2TypeLen; -+} __KAL_ATTRIB_PACKED__ ETH_FRAME_HEADER_T, *P_ETH_FRAME_HEADER_T; -+ -+/* Ethernet Frame Structure */ -+typedef struct _ETH_FRAME_T { -+ UINT_8 aucDestAddr[MAC_ADDR_LEN]; -+ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; -+ UINT_16 u2TypeLen; -+ UINT_8 aucData[1]; -+} __KAL_ATTRIB_PACKED__ ETH_FRAME_T, *P_ETH_FRAME_T; -+ -+/* IEEE 802.11 WLAN Frame Structure */ -+/* WLAN MAC Header (without Address 4 and QoS Control fields) */ -+typedef struct _WLAN_MAC_HEADER_T { -+ UINT_16 u2FrameCtrl; -+ UINT_16 u2DurationID; -+ UINT_8 aucAddr1[MAC_ADDR_LEN]; -+ UINT_8 aucAddr2[MAC_ADDR_LEN]; -+ UINT_8 aucAddr3[MAC_ADDR_LEN]; -+ UINT_16 u2SeqCtrl; -+} __KAL_ATTRIB_PACKED__ WLAN_MAC_HEADER_T, *P_WLAN_MAC_HEADER_T; -+ -+/* WLAN MAC Header (QoS Control fields included) */ -+typedef struct _WLAN_MAC_HEADER_QOS_T { -+ UINT_16 u2FrameCtrl; -+ UINT_16 u2DurationID; -+ UINT_8 aucAddr1[MAC_ADDR_LEN]; -+ UINT_8 aucAddr2[MAC_ADDR_LEN]; -+ UINT_8 aucAddr3[MAC_ADDR_LEN]; -+ UINT_16 u2SeqCtrl; -+ UINT_16 u2QosCtrl; -+} __KAL_ATTRIB_PACKED__ WLAN_MAC_HEADER_QOS_T, *P_WLAN_MAC_HEADER_QOS_T; -+ -+/* WLAN MAC Header (HT Control fields included) */ -+typedef struct _WLAN_MAC_HEADER_HT_T { -+ UINT_16 u2FrameCtrl; -+ UINT_16 u2DurationID; -+ UINT_8 aucAddr1[MAC_ADDR_LEN]; -+ UINT_8 aucAddr2[MAC_ADDR_LEN]; -+ UINT_8 aucAddr3[MAC_ADDR_LEN]; -+ UINT_16 u2SeqCtrl; -+ UINT_16 u2QosCtrl; -+ UINT_32 u4HtCtrl; -+} __KAL_ATTRIB_PACKED__ WLAN_MAC_HEADER_HT_T, *P_WLAN_MAC_HEADER_HT_T; -+ -+/* WLAN MAC Header (Address 4 included) */ -+typedef struct _WLAN_MAC_HEADER_A4_T { -+ UINT_16 u2FrameCtrl; -+ UINT_16 u2DurationID; -+ UINT_8 aucAddr1[MAC_ADDR_LEN]; -+ UINT_8 aucAddr2[MAC_ADDR_LEN]; -+ UINT_8 aucAddr3[MAC_ADDR_LEN]; -+ UINT_16 u2SeqCtrl; -+ UINT_8 aucAddr4[MAC_ADDR_LEN]; -+} __KAL_ATTRIB_PACKED__ WLAN_MAC_HEADER_A4_T, *P_WLAN_MAC_HEADER_A4_T; -+ -+/* WLAN MAC Header (Address 4 and QoS Control fields included) */ -+typedef struct _WLAN_MAC_HEADER_A4_QOS_T { -+ UINT_16 u2FrameCtrl; -+ UINT_16 u2DurationID; -+ UINT_8 aucAddr1[MAC_ADDR_LEN]; -+ UINT_8 aucAddr2[MAC_ADDR_LEN]; -+ UINT_8 aucAddr3[MAC_ADDR_LEN]; -+ UINT_16 u2SeqCtrl; -+ UINT_8 aucAddr4[MAC_ADDR_LEN]; -+ UINT_16 u2QosCtrl; -+} __KAL_ATTRIB_PACKED__ WLAN_MAC_HEADER_A4_QOS_T, *P_WLAN_MAC_HEADER_A4_QOS_T; -+ -+typedef struct _WLAN_MAC_HEADER_A4_HT_T { -+ UINT_16 u2FrameCtrl; -+ UINT_16 u2DurationID; -+ UINT_8 aucAddr1[MAC_ADDR_LEN]; -+ UINT_8 aucAddr2[MAC_ADDR_LEN]; -+ UINT_8 aucAddr3[MAC_ADDR_LEN]; -+ UINT_16 u2SeqCtrl; -+ UINT_8 aucAddr4[MAC_ADDR_LEN]; -+ UINT_16 u2QosCtrl; -+ UINT_32 u4HtCtrl; -+} __KAL_ATTRIB_PACKED__ WLAN_MAC_HEADER_A4_HT_T, *P_WLAN_MAC_HEADER_A4_HT_T; -+ -+/* 7.2.3 WLAN MAC Header for Management Frame - MMPDU */ -+typedef struct _WLAN_MAC_MGMT_HEADER_T { -+ UINT_16 u2FrameCtrl; -+ UINT_16 u2Duration; -+ UINT_8 aucDestAddr[MAC_ADDR_LEN]; -+ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; -+ UINT_8 aucBSSID[MAC_ADDR_LEN]; -+ UINT_16 u2SeqCtrl; -+} __KAL_ATTRIB_PACKED__ WLAN_MAC_MGMT_HEADER_T, *P_WLAN_MAC_MGMT_HEADER_T; -+ -+/* WLAN MAC Header for Management Frame (HT Control fields included) */ -+typedef struct _WLAN_MAC_MGMT_HEADER_HT_T { -+ UINT_16 u2FrameCtrl; -+ UINT_16 u2DurationID; -+ UINT_8 aucAddr1[MAC_ADDR_LEN]; -+ UINT_8 aucAddr2[MAC_ADDR_LEN]; -+ UINT_8 aucAddr3[MAC_ADDR_LEN]; -+ UINT_16 u2SeqCtrl; -+ UINT_32 u4HtCtrl; -+} __KAL_ATTRIB_PACKED__ WLAN_MAC_MGMT_HEADER_HT_T, *P_WLAN_MAC_MGMT_HEADER_HT_T; -+ -+/* 3 WLAN CONTROL Frame */ -+/* 7.2.1.4 WLAN Control Frame - PS-POLL Frame */ -+typedef struct _CTRL_PSPOLL_FRAME_T { -+ UINT_16 u2FrameCtrl; /* Frame Control */ -+ UINT_16 u2AID; /* AID */ -+ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ -+ UINT_8 aucTA[MAC_ADDR_LEN]; /* TA */ -+} __KAL_ATTRIB_PACKED__ CTRL_PSPOLL_FRAME_T, *P_CTRL_PSPOLL_FRAME_T; -+ -+/* BAR */ -+typedef struct _CTRL_BAR_FRAME_T { -+ UINT_16 u2FrameCtrl; /* Frame Control */ -+ UINT_16 u2DurationID; /* Duration */ -+ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* RA */ -+ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* TA */ -+ UINT_16 u2BarControl; -+ UINT_8 aucBarInfo[2]; /* Variable size */ -+} __KAL_ATTRIB_PACKED__ CTRL_BAR_FRAME_T, *P_CTRL_BAR_FRAME_T; -+ -+/* 3 WLAN Management Frame. */ -+/* 7.2.3.1 WLAN Management Frame - Beacon Frame */ -+typedef struct _WLAN_BEACON_FRAME_T { -+ /* Beacon header */ -+ UINT_16 u2FrameCtrl; /* Frame Control */ -+ UINT_16 u2DurationID; /* Duration */ -+ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ -+ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ -+ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ -+ UINT_16 u2SeqCtrl; /* Sequence Control */ -+ /* Beacon frame body */ -+ UINT_32 au4Timestamp[2]; /* Timestamp */ -+ UINT_16 u2BeaconInterval; /* Beacon Interval */ -+ UINT_16 u2CapInfo; /* Capability */ -+ UINT_8 aucInfoElem[1]; /* Various IEs, start from SSID */ -+} __KAL_ATTRIB_PACKED__ WLAN_BEACON_FRAME_T, *P_WLAN_BEACON_FRAME_T; -+ -+typedef struct _WLAN_BEACON_FRAME_BODY_T { -+ /* Beacon frame body */ -+ UINT_32 au4Timestamp[2]; /* Timestamp */ -+ UINT_16 u2BeaconInterval; /* Beacon Interval */ -+ UINT_16 u2CapInfo; /* Capability */ -+ UINT_8 aucInfoElem[1]; /* Various IEs, start from SSID */ -+} __KAL_ATTRIB_PACKED__ WLAN_BEACON_FRAME_BODY_T, *P_WLAN_BEACON_FRAME_BODY_T; -+ -+/* 7.2.3.3 WLAN Management Frame - Disassociation Frame */ -+typedef struct _WLAN_DISASSOC_FRAME_T { -+ /* Authentication MAC header */ -+ UINT_16 u2FrameCtrl; /* Frame Control */ -+ UINT_16 u2DurationID; /* Duration */ -+ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ -+ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ -+ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ -+ UINT_16 u2SeqCtrl; /* Sequence Control */ -+ /* Disassociation frame body */ -+ UINT_16 u2ReasonCode; /* Reason code */ -+ UINT_8 aucInfoElem[1]; /* Various IEs, possible no. */ -+} __KAL_ATTRIB_PACKED__ WLAN_DISASSOC_FRAME_T, *P_WLAN_DISASSOC_FRAME_T; -+ -+/* 7.2.3.4 WLAN Management Frame - Association Request frame */ -+typedef struct _WLAN_ASSOC_REQ_FRAME_T { -+ /* Association Request MAC header */ -+ UINT_16 u2FrameCtrl; /* Frame Control */ -+ UINT_16 u2DurationID; /* Duration */ -+ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ -+ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ -+ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ -+ UINT_16 u2SeqCtrl; /* Sequence Control */ -+ /* Association Request frame body */ -+ UINT_16 u2CapInfo; /* Capability information */ -+ UINT_16 u2ListenInterval; /* Listen interval */ -+ UINT_8 aucInfoElem[1]; /* Information elements, include WPA IE */ -+} __KAL_ATTRIB_PACKED__ WLAN_ASSOC_REQ_FRAME_T, *P_WLAN_ASSOC_REQ_FRAME_T; -+ -+/* 7.2.3.5 WLAN Management Frame - Association Response frame */ -+typedef struct _WLAN_ASSOC_RSP_FRAME_T { -+ /* Association Response MAC header */ -+ UINT_16 u2FrameCtrl; /* Frame Control */ -+ UINT_16 u2DurationID; /* Duration */ -+ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ -+ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ -+ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ -+ UINT_16 u2SeqCtrl; /* Sequence Control */ -+ /* Association Response frame body */ -+ UINT_16 u2CapInfo; /* Capability information */ -+ UINT_16 u2StatusCode; /* Status code */ -+ UINT_16 u2AssocId; /* Association ID */ -+ UINT_8 aucInfoElem[1]; /* Information elements, such as -+ supported rates, and etc. */ -+} __KAL_ATTRIB_PACKED__ WLAN_ASSOC_RSP_FRAME_T, *P_WLAN_ASSOC_RSP_FRAME_T; -+ -+/* 7.2.3.6 WLAN Management Frame - Reassociation Request frame */ -+typedef struct _WLAN_REASSOC_REQ_FRAME_T { -+ /* Reassociation Request MAC header */ -+ UINT_16 u2FrameCtrl; /* Frame Control */ -+ UINT_16 u2DurationID; /* Duration */ -+ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ -+ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ -+ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ -+ UINT_16 u2SeqCtrl; /* Sequence Control */ -+ /* Reassociation Request frame body */ -+ UINT_16 u2CapInfo; /* Capability information */ -+ UINT_16 u2ListenInterval; /* Listen interval */ -+ UINT_8 aucCurrentAPAddr[MAC_ADDR_LEN]; /* Current AP address */ -+ UINT_8 aucInfoElem[1]; /* Information elements, include WPA IE */ -+} __KAL_ATTRIB_PACKED__ WLAN_REASSOC_REQ_FRAME_T, *P_WLAN_REASSOC_REQ_FRAME_T; -+ -+/* 7.2.3.7 WLAN Management Frame - Reassociation Response frame -+ (the same as Association Response frame) */ -+typedef WLAN_ASSOC_RSP_FRAME_T WLAN_REASSOC_RSP_FRAME_T, *P_WLAN_REASSOC_RSP_FRAME_T; -+ -+/* 7.2.3.9 WLAN Management Frame - Probe Response Frame */ -+typedef WLAN_BEACON_FRAME_T WLAN_PROBE_RSP_FRAME_T, *P_WLAN_PROBE_RSP_FRAME_T; -+ -+/* 7.2.3.10 WLAN Management Frame - Authentication Frame */ -+typedef struct _WLAN_AUTH_FRAME_T { -+ /* Authentication MAC header */ -+ UINT_16 u2FrameCtrl; /* Frame Control */ -+ UINT_16 u2DurationID; /* Duration */ -+ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ -+ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ -+ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ -+ UINT_16 u2SeqCtrl; /* Sequence Control */ -+ /* Authentication frame body */ -+ UINT_16 u2AuthAlgNum; /* Authentication algorithm number */ -+ UINT_16 u2AuthTransSeqNo; /* Authentication transaction sequence number */ -+ UINT_16 u2StatusCode; /* Status code */ -+ UINT_8 aucInfoElem[1]; /* Various IEs for Fast BSS Transition */ -+} __KAL_ATTRIB_PACKED__ WLAN_AUTH_FRAME_T, *P_WLAN_AUTH_FRAME_T; -+ -+/* 7.2.3.11 WLAN Management Frame - Deauthentication Frame */ -+typedef struct _WLAN_DEAUTH_FRAME_T { -+ /* Authentication MAC header */ -+ UINT_16 u2FrameCtrl; /* Frame Control */ -+ UINT_16 u2DurationID; /* Duration */ -+ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ -+ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ -+ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ -+ UINT_16 u2SeqCtrl; /* Sequence Control */ -+ /* Deauthentication frame body */ -+ UINT_16 u2ReasonCode; /* Reason code */ -+ UINT_8 aucInfoElem[1]; /* Various IEs, possible no. */ -+} __KAL_ATTRIB_PACKED__ WLAN_DEAUTH_FRAME_T, *P_WLAN_DEAUTH_FRAME_T; -+ -+/* 3 Information Elements. */ -+/* 7.3.2 Generic element format */ -+typedef struct _IE_HDR_T { -+ UINT_8 ucId; -+ UINT_8 ucLength; -+ UINT_8 aucInfo[1]; -+} __KAL_ATTRIB_PACKED__ IE_HDR_T, *P_IE_HDR_T; -+ -+/* 7.3.2.1 SSID element */ -+typedef struct _IE_SSID_T { -+ UINT_8 ucId; -+ UINT_8 ucLength; -+ UINT_8 aucSSID[ELEM_MAX_LEN_SSID]; -+} __KAL_ATTRIB_PACKED__ IE_SSID_T, *P_IE_SSID_T; -+ -+/* 7.3.2.2 Supported Rates element */ -+typedef struct _IE_SUPPORTED_RATE_T { -+ UINT_8 ucId; -+ UINT_8 ucLength; -+ UINT_8 aucSupportedRates[ELEM_MAX_LEN_SUP_RATES]; -+} __KAL_ATTRIB_PACKED__ IE_SUPPORTED_RATE_T, *P_IE_SUPPORTED_RATE_T; -+ -+/* 7.3.2.4 DS Parameter Set element */ -+typedef struct _IE_DS_PARAM_SET_T { -+ UINT_8 ucId; -+ UINT_8 ucLength; -+ UINT_8 ucCurrChnl; -+} __KAL_ATTRIB_PACKED__ IE_DS_PARAM_SET_T, *P_IE_DS_PARAM_SET_T; -+ -+/* 7.3.2.5 CF Parameter Set element */ -+typedef struct _IE_CF_PARAM_SET_T { -+ UINT_8 ucId; -+ UINT_8 ucLength; -+ UINT_8 ucCFPCount; -+ UINT_8 ucCFPPeriod; -+ UINT_16 u2CFPMaxDur; -+ UINT_16 u2DurRemaining; -+} __KAL_ATTRIB_PACKED__ IE_CF_PARAM_SET_T, *P_IE_CF_PARAM_SET_T; -+ -+/* 7.3.2.6 TIM */ -+typedef struct _IE_TIM_T { -+ UINT_8 ucId; -+ UINT_8 ucLength; -+ UINT_8 ucDTIMCount; -+ UINT_8 ucDTIMPeriod; -+ UINT_8 ucBitmapControl; -+ UINT_8 aucPartialVirtualMap[1]; -+} __KAL_ATTRIB_PACKED__ IE_TIM_T, *P_IE_TIM_T; -+ -+/* 7.3.2.7 IBSS Parameter Set element */ -+typedef struct _IE_IBSS_PARAM_SET_T { -+ UINT_8 ucId; -+ UINT_8 ucLength; -+ UINT_16 u2ATIMWindow; -+} __KAL_ATTRIB_PACKED__ IE_IBSS_PARAM_SET_T, *P_IE_IBSS_PARAM_SET_T; -+ -+/* 7.3.2.8 Challenge Text element */ -+typedef struct _IE_CHALLENGE_TEXT_T { -+ UINT_8 ucId; -+ UINT_8 ucLength; -+ UINT_8 aucChallengeText[ELEM_MAX_LEN_CHALLENGE_TEXT]; -+} __KAL_ATTRIB_PACKED__ IE_CHALLENGE_TEXT_T, *P_IE_CHALLENGE_TEXT_T; -+ -+/* 7.3.2.9 Country information element */ -+#if CFG_SUPPORT_802_11D -+/*! \brief COUNTRY_INFO_TRIPLET is defined for the COUNTRY_INFO_ELEM structure. */ -+typedef struct _COUNTRY_INFO_TRIPLET_T { -+ UINT_8 ucParam1; /*!< If param1 >= 201, this triplet is referred to as -+ Regulatory Triplet in 802_11J. */ -+ UINT_8 ucParam2; -+ UINT_8 ucParam3; -+} __KAL_ATTRIB_PACKED__ COUNTRY_INFO_TRIPLET_T, *P_COUNTRY_INFO_TRIPLET_T; -+ -+typedef struct _COUNTRY_INFO_SUBBAND_TRIPLET_T { -+ UINT_8 ucFirstChnlNum; /*!< First Channel Number */ -+ UINT_8 ucNumOfChnl; /*!< Number of Channels */ -+ INT_8 cMaxTxPwrLv; /*!< Maximum Transmit Power Level */ -+} __KAL_ATTRIB_PACKED__ COUNTRY_INFO_SUBBAND_TRIPLET_T, *P_COUNTRY_INFO_SUBBAND_TRIPLET_T; -+ -+typedef struct _COUNTRY_INFO_REGULATORY_TRIPLET_T { -+ UINT_8 ucRegExtId; /*!< Regulatory Extension Identifier, should -+ be greater than or equal to 201 */ -+ UINT_8 ucRegClass; /*!< Regulatory Class */ -+ UINT_8 ucCoverageClass; /*!< Coverage Class, unsigned 1-octet value 0~31 -+ , 32~255 reserved */ -+} __KAL_ATTRIB_PACKED__ COUNTRY_INFO_REGULATORY_TRIPLET_T, *P_COUNTRY_INFO_REGULATORY_TRIPLET_T; -+ -+typedef struct _IE_COUNTRY_T { -+ UINT_8 ucId; -+ UINT_8 ucLength; -+ UINT_8 aucCountryStr[3]; -+ COUNTRY_INFO_SUBBAND_TRIPLET_T arCountryStr[1]; -+} __KAL_ATTRIB_PACKED__ IE_COUNTRY_T, *P_IE_COUNTRY_T; -+#endif /* CFG_SUPPORT_802_11D */ -+ -+/* 7.3.2.13 ERP element */ -+typedef struct _IE_ERP_T { -+ UINT_8 ucId; -+ UINT_8 ucLength; -+ UINT_8 ucERP; -+} __KAL_ATTRIB_PACKED__ IE_ERP_T, *P_IE_ERP_T; -+ -+/* 7.3.2.14 Extended Supported Rates element */ -+typedef struct _IE_EXT_SUPPORTED_RATE_T { -+ UINT_8 ucId; -+ UINT_8 ucLength; -+ UINT_8 aucExtSupportedRates[ELEM_MAX_LEN_EXTENDED_SUP_RATES]; -+} __KAL_ATTRIB_PACKED__ IE_EXT_SUPPORTED_RATE_T, *P_IE_EXT_SUPPORTED_RATE_T; -+ -+/* 7.3.2.15 Power Constraint element */ -+typedef struct _IE_POWER_CONSTRAINT_T { -+ UINT_8 ucId; -+ UINT_8 ucLength; -+ UINT_8 ucLocalPowerConstraint; /* Unit: dBm */ -+} __KAL_ATTRIB_PACKED__ IE_POWER_CONSTRAINT_T, *P_IE_POWER_CONSTRAINT_T; -+ -+/* 7.3.2.16 Power Capability element */ -+typedef struct _IE_POWER_CAP_T { -+ UINT_8 ucId; -+ UINT_8 ucLength; -+ INT_8 cMinTxPowerCap; /* Unit: dBm */ -+ INT_8 cMaxTxPowerCap; /* Unit: dBm */ -+} __KAL_ATTRIB_PACKED__ IE_POWER_CAP_T, *P_IE_POWER_CAP_T; -+ -+/* 7.3.2.17 TPC request element */ -+typedef struct _IE_TPC_REQ_T { -+ UINT_8 ucId; -+ UINT_8 ucLength; -+} __KAL_ATTRIB_PACKED__ IE_TPC_REQ_T, *P_IE_TPC_REQ_T; -+ -+/* 7.3.2.18 TPC report element */ -+typedef struct _IE_TPC_REPORT_T { -+ UINT_8 ucId; -+ UINT_8 ucLength; -+ INT_8 cTxPower; /* Unit: dBm */ -+ INT_8 cLinkMargin; /* Unit: dB */ -+} __KAL_ATTRIB_PACKED__ IE_TPC_REPORT_T, *P_IE_TPC_REPORT_T; -+ -+#if CFG_SUPPORT_DFS /* Add by Enlai */ -+/* 7.3.2.19 Supported Channels element*/ -+typedef struct _IE_SUPPORTED_CHANNELS_T { -+ UINT_8 ucId; -+ UINT_8 ucLength; -+ UINT_8 ucChannelNum[ELEM_MAX_LEN_SUPPORTED_CHANNELS * 2]; -+} __KAL_ATTRIB_PACKED__ IE_SUPPORTED_CHANNELS_T, *P_IE_SUPPORTED_CHANNELS_T; -+ -+/* 7.3.2.20 Channel Switch Announcement element*/ -+typedef struct _IE_CHANNEL_SWITCH_T { -+ UINT_8 ucId; -+ UINT_8 ucLength; -+ UINT_8 ucChannelSwitchMode; -+ UINT_8 ucNewChannelNum; -+ UINT_8 ucChannelSwitchCount; -+} __KAL_ATTRIB_PACKED__ IE_CHANNEL_SWITCH_T, *P_IE_CHANNEL_SWITCH_T; -+#endif -+ -+/* 7.3.2.21 Measurement Request element */ -+typedef struct _IE_MEASUREMENT_REQ_T { -+ UINT_8 ucId; -+ UINT_8 ucLength; -+ UINT_8 ucToken; -+ UINT_8 ucRequestMode; -+ UINT_8 ucMeasurementType; -+ UINT_8 aucRequestFields[1]; -+} __KAL_ATTRIB_PACKED__ IE_MEASUREMENT_REQ_T, *P_IE_MEASUREMENT_REQ_T; -+ -+typedef struct _SM_BASIC_REQ_T { -+ UINT_8 ucChannel; -+ UINT_32 au4StartTime[2]; -+ UINT_16 u2Duration; -+} __KAL_ATTRIB_PACKED__ SM_BASIC_REQ_T, *P_SM_BASIC_REQ_T; -+ -+/* SM_COMMON_REQ_T is not specified in Spec. Use it as common structure of SM */ -+typedef SM_BASIC_REQ_T SM_REQ_COMMON_T, *P_SM_REQ_COMMON_T; -+typedef SM_BASIC_REQ_T SM_CCA_REQ_T, *P_SM_CCA_REQ_T; -+typedef SM_BASIC_REQ_T SM_RPI_HISTOGRAM_REQ_T, *P_SM_RPI_HISTOGRAM_REQ_T; -+ -+typedef struct _RM_CHNL_LOAD_REQ_T { -+ UINT_8 ucRegulatoryClass; -+ UINT_8 ucChannel; -+ UINT_16 u2RandomInterval; -+ UINT_16 u2Duration; -+ UINT_8 aucSubElements[1]; -+} __KAL_ATTRIB_PACKED__ RM_CHNL_LOAD_REQ_T, *P_RM_CHNL_LOAD_REQ_T; -+ -+typedef RM_CHNL_LOAD_REQ_T RM_NOISE_HISTOGRAM_REQ_T, *P_RM_NOISE_HISTOGRAM_REQ_T; -+ -+typedef struct _RM_BCN_REQ_T { -+ UINT_8 ucRegulatoryClass; -+ UINT_8 ucChannel; -+ UINT_16 u2RandomInterval; -+ UINT_16 u2Duration; -+ UINT_8 ucMeasurementMode; -+ UINT_8 aucBssid[6]; -+ UINT_8 aucSubElements[1]; -+} __KAL_ATTRIB_PACKED__ RM_BCN_REQ_T, *P_RM_BCN_REQ_T; -+ -+typedef struct _RM_FRAME_REQ_T { -+ UINT_8 ucRegulatoryClass; -+ UINT_8 ucChannel; -+ UINT_16 u2RandomInterval; -+ UINT_16 u2Duration; -+ UINT_8 ucFrameReqType; -+ UINT_8 aucMacAddr[6]; -+ UINT_8 aucSubElements[1]; -+} __KAL_ATTRIB_PACKED__ RM_FRAME_REQ_T, *P_RM_FRAME_REQ_T; -+ -+typedef struct _RM_STA_STATS_REQ_T { -+ UINT_8 aucPeerMacAddr[6]; -+ UINT_16 u2RandomInterval; -+ UINT_16 u2Duration; -+ UINT_8 ucGroupID; -+ UINT_8 aucSubElements[1]; -+} __KAL_ATTRIB_PACKED__ RM_STA_STATS_REQ_T, *P_RM_STA_STATS_REQ_T; -+ -+typedef struct _RM_LCI_REQ_T { -+ UINT_8 ucLocationSubject; -+ UINT_8 ucLatitudeResolution; -+ UINT_8 ucLongitudeResolution; -+ UINT_8 ucAltitudeResolution; -+ UINT_8 aucSubElements[1]; -+} __KAL_ATTRIB_PACKED__ RM_LCI_REQ_T, *P_RM_LCI_REQ_T; -+ -+typedef struct _RM_TS_MEASURE_REQ_T { -+ UINT_16 u2RandomInterval; -+ UINT_16 u2Duration; -+ UINT_8 aucPeerStaAddr[6]; -+ UINT_8 ucTrafficID; -+ UINT_8 ucBin0Range; -+ UINT_8 aucSubElements[1]; -+} __KAL_ATTRIB_PACKED__ RM_TS_MEASURE_REQ_T, *P_RM_TS_MEASURE_REQ_T; -+ -+typedef struct _RM_MEASURE_PAUSE_REQ_T { -+ UINT_16 u2PauseTime; -+ UINT_8 aucSubElements[1]; -+} __KAL_ATTRIB_PACKED__ RM_MEASURE_PAUSE_REQ_T, *P_RM_MEASURE_PAUSE_REQ_T; -+ -+/* 7.3.2.22 Measurement Report element */ -+typedef struct _IE_MEASUREMENT_REPORT_T { -+ UINT_8 ucId; -+ UINT_8 ucLength; -+ UINT_8 ucToken; -+ UINT_8 ucReportMode; -+ UINT_8 ucMeasurementType; -+ UINT_8 aucReportFields[1]; -+} __KAL_ATTRIB_PACKED__ IE_MEASUREMENT_REPORT_T, *P_IE_MEASUREMENT_REPORT_T; -+ -+typedef struct _SM_BASIC_REPORT_T { -+ UINT_8 ucChannel; -+ UINT_32 u4StartTime[2]; -+ UINT_16 u2Duration; -+ UINT_8 ucMap; -+} __KAL_ATTRIB_PACKED__ SM_BASIC_REPORT_T, *P_SM_BASIC_REPORT_T; -+ -+typedef struct _SM_CCA_REPORT_T { -+ UINT_8 ucChannel; -+ UINT_32 u4StartTime[2]; -+ UINT_16 u2Duration; -+ UINT_8 ucCcaBusyFraction; -+} __KAL_ATTRIB_PACKED__ SM_CCA_REPORT_T, *P_SM_CCA_REPORT_T; -+ -+typedef struct _SM_RPI_REPORT_T { -+ UINT_8 ucChannel; -+ UINT_32 u4StartTime[2]; -+ UINT_16 u2Duration; -+ UINT_8 aucRPI[8]; -+} __KAL_ATTRIB_PACKED__ SM_RPI_REPORT_T, *P_SM_RPI_REPORT_T; -+ -+typedef struct _RM_CHNL_LOAD_REPORT_T { -+ UINT_8 ucRegulatoryClass; -+ UINT_8 ucChannel; -+ UINT_32 u4StartTime[2]; -+ UINT_16 u2Duration; -+ UINT_8 ucChnlLoad; -+} __KAL_ATTRIB_PACKED__ RM_CHNL_LOAD_REPORT_T, *P_RM_CHNL_LOAD_REPORT_T; -+ -+typedef struct _RM_IPI_REPORT_T { -+ UINT_8 ucRegulatoryClass; -+ UINT_8 ucChannel; -+ UINT_32 u4StartTime[2]; -+ UINT_16 u2Duration; -+ UINT_8 ucAntennaId; -+ INT_8 cANPI; -+ UINT_8 aucIPI[11]; -+} __KAL_ATTRIB_PACKED__ RM_IPI_REPORT_T, *P_RM_IPI_REPORT_T; -+ -+/* 7.3.2.23 Quiet element */ -+typedef struct _IE_QUIET_T { -+ UINT_8 ucId; -+ UINT_8 ucLength; -+ UINT_8 ucCount; -+ UINT_8 ucPeriod; -+ UINT_16 u2Duration; -+ UINT_16 u2Offset; -+} __KAL_ATTRIB_PACKED__ IE_QUIET_T, *P_IE_QUIET_T; -+ -+/* 7.3.2.27 Extended Capabilities element */ -+typedef struct _IE_EXT_CAP_T { -+ UINT_8 ucId; -+ UINT_8 ucLength; -+ UINT_8 aucCapabilities[5]; -+} __KAL_ATTRIB_PACKED__ IE_EXT_CAP_T, *P_EXT_CAP_T; -+ -+/* 7.3.2.27 hs20 Extended Capabilities element */ -+typedef struct _IE_HS20_EXT_CAP_T { -+ UINT_8 ucId; -+ UINT_8 ucLength; -+ UINT_8 aucCapabilities[6]; -+} __KAL_ATTRIB_PACKED__ IE_HS20_EXT_CAP_T, *P_HS20_EXT_CAP_T; -+ -+ -+/* 7.3.2.27 Extended Capabilities element */ -+typedef struct _IE_RRM_ENABLED_CAP_T { -+ UINT_8 ucId; -+ UINT_8 ucLength; -+ UINT_8 aucCap[5]; -+} __KAL_ATTRIB_PACKED__ IE_RRM_ENABLED_CAP_T, *P_IE_RRM_ENABLED_CAP_T; -+ -+/* 7.3.2.51 Timeout Interval element (TIE) */ -+typedef struct _IE_TIMEOUT_INTERVAL_T { -+ UINT_8 ucId; -+ UINT_8 ucLength; -+#define IE_TIMEOUT_INTERVAL_TYPE_RESERVED 0 -+#define IE_TIMEOUT_INTERVAL_TYPE_REASSOC 1 -+#define IE_TIMEOUT_INTERVAL_TYPE_KEY_LIFETIME 2 -+#define IE_TIMEOUT_INTERVAL_TYPE_ASSOC_COMEBACK 3 -+ UINT_8 ucType; -+ UINT_32 u4Value; -+} __KAL_ATTRIB_PACKED__ IE_TIMEOUT_INTERVAL_T; -+ -+/* 7.3.2.56 HT Capabilities element */ -+typedef struct _SUP_MCS_SET_FIELD { -+ UINT_8 aucRxMcsBitmask[SUP_MCS_RX_BITMASK_OCTET_NUM]; -+ UINT_16 u2RxHighestSupportedRate; -+ UINT_32 u4TxRateInfo; -+} __KAL_ATTRIB_PACKED__ SUP_MCS_SET_FIELD, *P_SUP_MCS_SET_FIELD; -+ -+typedef struct _IE_HT_CAP_T { -+ UINT_8 ucId; -+ UINT_8 ucLength; -+ UINT_16 u2HtCapInfo; -+ UINT_8 ucAmpduParam; -+ SUP_MCS_SET_FIELD rSupMcsSet; -+ UINT_16 u2HtExtendedCap; -+ UINT_32 u4TxBeamformingCap; -+ UINT_8 ucAselCap; -+} __KAL_ATTRIB_PACKED__ IE_HT_CAP_T, *P_IE_HT_CAP_T; -+ -+/* 7.3.2.57 HT Operation element */ -+typedef struct _IE_HT_OP_T { -+ UINT_8 ucId; -+ UINT_8 ucLength; -+ UINT_8 ucPrimaryChannel; -+ UINT_8 ucInfo1; -+ UINT_16 u2Info2; -+ UINT_16 u2Info3; -+ UINT_8 aucBasicMcsSet[16]; -+} __KAL_ATTRIB_PACKED__ IE_HT_OP_T, *P_IE_HT_OP_T; -+ -+/* 7.3.2.25 RSN Information element format */ -+typedef struct _RSN_INFO_ELEM_T { -+ UCHAR ucElemId; -+ UCHAR ucLength; -+ UINT_16 u2Version; -+ UINT_32 u4GroupKeyCipherSuite; -+ UINT_16 u2PairwiseKeyCipherSuiteCount; -+ UCHAR aucPairwiseKeyCipherSuite1[4]; -+} __KAL_ATTRIB_PACKED__ RSN_INFO_ELEM_T, *P_RSN_INFO_ELEM_T; -+ -+/* 7.3.2.26 WPA Information element format */ -+typedef struct _WPA_INFO_ELEM_T { -+ UCHAR ucElemId; -+ UCHAR ucLength; -+ UCHAR aucOui[3]; -+ UCHAR ucOuiType; -+ UINT_16 u2Version; -+ UINT_32 u4GroupKeyCipherSuite; -+ UINT_16 u2PairwiseKeyCipherSuiteCount; -+ UCHAR aucPairwiseKeyCipherSuite1[4]; -+} __KAL_ATTRIB_PACKED__ WPA_INFO_ELEM_T, *P_WPA_INFO_ELEM_T; -+ -+/* 7.3.2.58 20/40 BSS Intolerant Channel Report element */ -+typedef struct _IE_INTOLERANT_CHNL_REPORT_T { -+ UINT_8 ucId; -+ UINT_8 ucLength; -+ UINT_8 ucRegulatoryClass; -+ UINT_8 aucChannelList[1]; -+} __KAL_ATTRIB_PACKED__ IE_INTOLERANT_CHNL_REPORT_T, *P_IE_INTOLERANT_CHNL_REPORT_T; -+ -+/* 7.3.2.59 OBSS Scan Parameters element */ -+typedef struct _IE_OBSS_SCAN_PARAM_T { -+ UINT_8 ucId; -+ UINT_8 ucLength; -+ UINT_16 u2ScanPassiveDwell; -+ UINT_16 u2ScanActiveDwell; -+ UINT_16 u2TriggerScanInterval; -+ UINT_16 u2ScanPassiveTotalPerChnl; -+ UINT_16 u2ScanActiveTotalPerChnl; -+ UINT_16 u2WidthTransDelayFactor; -+ UINT_16 u2ScanActivityThres; -+} __KAL_ATTRIB_PACKED__ IE_OBSS_SCAN_PARAM_T, *P_IE_OBSS_SCAN_PARAM_T; -+ -+/* 7.3.2.60 20/40 BSS Coexistence element */ -+typedef struct _IE_20_40_COEXIST_T { -+ UINT_8 ucId; -+ UINT_8 ucLength; -+ UINT_8 ucData; -+} __KAL_ATTRIB_PACKED__ IE_20_40_COEXIST_T, *P_IE_20_40_COEXIST_T; -+ -+/* 7.3.2.60 20/40 BSS Coexistence element */ -+typedef struct _IE_SUP_OPERATING_CLASS_T { -+ UINT_8 ucId; -+ UINT_8 ucLength; -+ UINT_8 ucCur; -+ UINT_8 ucSup[255]; -+} __KAL_ATTRIB_PACKED__ IE_SUP_OPERATING_CLASS_T, *P_IE_SUP_OPERATING_CLASS_T; -+ -+/* 3 7.4 Action Frame. */ -+/* 7.4 Action frame format */ -+typedef struct _WLAN_ACTION_FRAME { -+ /* Action MAC header */ -+ UINT_16 u2FrameCtrl; /* Frame Control */ -+ UINT_16 u2DurationID; /* Duration */ -+ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ -+ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ -+ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ -+ UINT_16 u2SeqCtrl; /* Sequence Control */ -+ /* Action frame body */ -+ UINT_8 ucCategory; /* Category */ -+ UINT_8 ucAction; /* Action Value */ -+ UINT_8 ucActionDetails[1]; /* Action details */ -+} __KAL_ATTRIB_PACKED__ WLAN_ACTION_FRAME, *P_WLAN_ACTION_FRAME; -+ -+/* 7.4.1.1 Spectrum Measurement Request frame format */ -+typedef struct _ACTION_SM_REQ_FRAME { -+ /* ADDTS Request MAC header */ -+ UINT_16 u2FrameCtrl; /* Frame Control */ -+ UINT_16 u2Duration; /* Duration */ -+ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ -+ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ -+ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ -+ UINT_16 u2SeqCtrl; /* Sequence Control */ -+ /* ADDTS Request frame body */ -+ UINT_8 ucCategory; /* Category */ -+ UINT_8 ucAction; /* Action Value */ -+ UINT_8 ucDialogToken; /* Dialog Token */ -+ UINT_8 aucInfoElem[1]; /* Information elements */ -+} __KAL_ATTRIB_PACKED__ ACTION_SM_REQ_FRAME, *P_ACTION_SM_REQ_FRAME; -+ -+/* 7.4.1.2 Spectrum Measurement Report frame format */ -+typedef ACTION_SM_REQ_FRAME ACTION_SM_REPORT_FRAME, *P_ACTION_SM_REPORT_FRAME; -+ -+/* 7.4.1.5 Channel Switch Announcement frame format */ -+typedef struct _ACTION_CHANNEL_SWITCH_FRAME { -+ /* ADDTS Request MAC header */ -+ UINT_16 u2FrameCtrl; /* Frame Control */ -+ UINT_16 u2Duration; /* Duration */ -+ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ -+ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ -+ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ -+ UINT_16 u2SeqCtrl; /* Sequence Control */ -+ /* ADDTS Request frame body */ -+ UINT_8 ucCategory; /* Category */ -+ UINT_8 ucAction; /* Action Value */ -+ UINT_8 aucInfoElem[5]; /* Information elements */ -+} __KAL_ATTRIB_PACKED__ _ACTION_CHANNEL_SWITCH_FRAME, *P_ACTION_CHANNEL_SWITCH_FRAME; -+ -+/* 7.4.2.1 ADDTS Request frame format */ -+typedef struct _ACTION_ADDTS_REQ_FRAME { -+ /* ADDTS Request MAC header */ -+ UINT_16 u2FrameCtrl; /* Frame Control */ -+ UINT_16 u2Duration; /* Duration */ -+ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ -+ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ -+ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ -+ UINT_16 u2SeqCtrl; /* Sequence Control */ -+ /* ADDTS Request frame body */ -+ UINT_8 ucCategory; /* Category */ -+ UINT_8 ucAction; /* Action Value */ -+ UINT_8 ucDialogToken; /* Dialog Token */ -+ UINT_8 aucInfoElem[1]; /* Information elements, such as -+ TS Delay, and etc. */ -+} __KAL_ATTRIB_PACKED__ ACTION_ADDTS_REQ_FRAME, *P_ACTION_ADDTS_REQ_FRAME; -+ -+/* 7.4.2.2 ADDTS Response frame format */ -+typedef struct _ACTION_ADDTS_RSP_FRAME { -+ /* ADDTS Response MAC header */ -+ UINT_16 u2FrameCtrl; /* Frame Control */ -+ UINT_16 u2Duration; /* Duration */ -+ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ -+ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ -+ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ -+ UINT_16 u2SeqCtrl; /* Sequence Control */ -+ /* ADDTS Response frame body */ -+ UINT_8 ucCategory; /* Category */ -+ UINT_8 ucAction; /* Action Value */ -+ UINT_8 ucDialogToken; /* Dialog Token */ -+ UINT_8 ucStatusCode; /* WMM Status Code is of one byte */ -+ UINT_8 aucInfoElem[1]; /* Information elements, such as -+ TS Delay, and etc. */ -+} __KAL_ATTRIB_PACKED__ ACTION_ADDTS_RSP_FRAME, *P_ACTION_ADDTS_RSP_FRAME; -+ -+/* 7.4.2.3 DELTS frame format */ -+typedef struct _ACTION_DELTS_FRAME { -+ /* DELTS MAC header */ -+ UINT_16 u2FrameCtrl; /* Frame Control */ -+ UINT_16 u2DurationID; /* Duration */ -+ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ -+ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ -+ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ -+ UINT_16 u2SeqCtrl; /* Sequence Control */ -+ /* DELTS frame body */ -+ UINT_8 ucCategory; /* Category */ -+ UINT_8 ucAction; /* Action Value */ -+ UINT_8 aucTsInfo[3]; /* TS Info */ -+} __KAL_ATTRIB_PACKED__ ACTION_DELTS_FRAME, *P_ACTION_DELTS_FRAME; -+ -+/* 7.4.4.1 ADDBA Request frame format */ -+typedef struct _ACTION_ADDBA_REQ_FRAME_T { -+ /* Action MAC header */ -+ UINT_16 u2FrameCtrl; /* Frame Control */ -+ UINT_16 u2DurationID; /* Duration */ -+ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ -+ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ -+ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ -+ UINT_16 u2SeqCtrl; /* Sequence Control */ -+ /* Action frame body */ -+ UINT_8 ucCategory; /* Category */ -+ UINT_8 ucAction; /* Action Value */ -+ UINT_8 ucDialogToken; /* Dialog Token chosen by the sender */ -+ UINT_8 aucBAParameterSet[2]; /* BA policy, TID, buffer size */ -+ UINT_8 aucBATimeoutValue[2]; -+ UINT_8 aucBAStartSeqCtrl[2]; /* SSN */ -+} __KAL_ATTRIB_PACKED__ ACTION_ADDBA_REQ_FRAME_T, *P_ACTION_ADDBA_REQ_FRAME_T; -+ -+typedef struct _ACTION_ADDBA_REQ_BODY_T { -+ UINT_16 u2BAParameterSet; /* BA policy, TID, buffer size */ -+ UINT_16 u2BATimeoutValue; -+ UINT_16 u2BAStartSeqCtrl; /* SSN */ -+} __KAL_ATTRIB_PACKED__ ACTION_ADDBA_REQ_BODY_T, *P_ACTION_ADDBA_REQ_BODY_T; -+ -+/* 7.4.4.2 ADDBA Response frame format */ -+typedef struct _ACTION_ADDBA_RSP_FRAME_T { -+ /* Action MAC header */ -+ UINT_16 u2FrameCtrl; /* Frame Control */ -+ UINT_16 u2DurationID; /* Duration */ -+ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ -+ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ -+ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ -+ UINT_16 u2SeqCtrl; /* Sequence Control */ -+ /* Action frame body */ -+ UINT_8 ucCategory; /* Category */ -+ UINT_8 ucAction; /* Action Value */ -+ UINT_8 ucDialogToken; /* Dialog Token chosen by the sender */ -+ UINT_8 aucStatusCode[2]; -+ UINT_8 aucBAParameterSet[2]; /* BA policy, TID, buffer size */ -+ UINT_8 aucBATimeoutValue[2]; -+} __KAL_ATTRIB_PACKED__ ACTION_ADDBA_RSP_FRAME_T, *P_ACTION_ADDBA_RSP_FRAME_T; -+ -+typedef struct _ACTION_ADDBA_RSP_BODY_T { -+ UINT_16 u2StatusCode; -+ UINT_16 u2BAParameterSet; /* BA policy, TID, buffer size */ -+ UINT_16 u2BATimeoutValue; -+} __KAL_ATTRIB_PACKED__ ACTION_ADDBA_RSP_BODY_T, *P_ACTION_ADDBA_RSP_BODY_T; -+ -+/* 7.4.4.3 DELBA frame format */ -+typedef struct _ACTION_DELBA_FRAME_T { -+ /* Action MAC header */ -+ UINT_16 u2FrameCtrl; /* Frame Control */ -+ UINT_16 u2DurationID; /* Duration */ -+ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ -+ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ -+ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ -+ UINT_16 u2SeqCtrl; /* Sequence Control */ -+ /* Action frame body */ -+ UINT_8 ucCategory; /* Category */ -+ UINT_8 ucAction; /* Action Value */ -+ UINT_16 u2DelBaParameterSet; /* Bit 11 Initiator, Bits 12-15 TID */ -+ UINT_16 u2ReasonCode; /* 7.3.1.7 */ -+} __KAL_ATTRIB_PACKED__ ACTION_DELBA_FRAME_T, *P_ACTION_DELBA_FRAME_T; -+ -+/* 7.4.6.1 Radio Measurement Request frame format */ -+typedef struct _ACTION_RM_REQ_FRAME { -+ /* MAC header */ -+ UINT_16 u2FrameCtrl; /* Frame Control */ -+ UINT_16 u2Duration; /* Duration */ -+ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ -+ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ -+ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ -+ UINT_16 u2SeqCtrl; /* Sequence Control */ -+ /* Radio Measurement Request frame body */ -+ UINT_8 ucCategory; /* Category */ -+ UINT_8 ucAction; /* Action Value */ -+ UINT_8 ucDialogToken; /* Dialog Token */ -+ UINT_16 u2Repetitions; /* Number of repetitions */ -+ UINT_8 aucInfoElem[1]; /* Measurement Request elements, such as -+ channel load request, and etc. */ -+} __KAL_ATTRIB_PACKED__ ACTION_RM_REQ_FRAME, *P_ACTION_RM_REQ_FRAME; -+ -+/* 7.4.6.2 Radio Measurement Report frame format */ -+typedef struct _ACTION_RM_REPORT_FRAME { -+ /* MAC header */ -+ UINT_16 u2FrameCtrl; /* Frame Control */ -+ UINT_16 u2Duration; /* Duration */ -+ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ -+ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ -+ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ -+ UINT_16 u2SeqCtrl; /* Sequence Control */ -+ /* Radio Measurement Report frame body */ -+ UINT_8 ucCategory; /* Category */ -+ UINT_8 ucAction; /* Action Value */ -+ UINT_8 ucDialogToken; /* Dialog Token */ -+ UINT_8 aucInfoElem[1]; /* Measurement Report elements, such as -+ channel load report, and etc. */ -+} __KAL_ATTRIB_PACKED__ ACTION_RM_REPORT_FRAME, *P_ACTION_RM_REPORT_FRAME; -+ -+/* 7.4.7.1a 20/40 BSS Coexistence Management frame format */ -+typedef struct _ACTION_20_40_COEXIST_FRAME { -+ /* MAC header */ -+ UINT_16 u2FrameCtrl; /* Frame Control */ -+ UINT_16 u2Duration; /* Duration */ -+ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ -+ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ -+ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ -+ UINT_16 u2SeqCtrl; /* Sequence Control */ -+ /* BSS Coexistence Management frame body */ -+ UINT_8 ucCategory; /* Category */ -+ UINT_8 ucAction; /* Action Value */ -+ -+ IE_20_40_COEXIST_T rBssCoexist; /* 20/40 BSS coexistence element */ -+ IE_INTOLERANT_CHNL_REPORT_T rChnlReport; /* Intolerant channel report */ -+ -+} __KAL_ATTRIB_PACKED__ ACTION_20_40_COEXIST_FRAME, *P_ACTION_20_40_COEXIST_FRAME; -+ -+#if CFG_SUPPORT_802_11W -+/* 7.4.9 SA Query Management frame format */ -+typedef struct _ACTION_SA_QUERY_FRAME { -+ /* MAC header */ -+ UINT_16 u2FrameCtrl; /* Frame Control */ -+ UINT_16 u2Duration; /* Duration */ -+ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ -+ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ -+ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ -+ UINT_16 u2SeqCtrl; /* Sequence Control */ -+ /* BSS Coexistence Management frame body */ -+ UINT_8 ucCategory; /* Category */ -+ UINT_8 ucAction; /* Action Value */ -+ -+ UINT_8 ucTransId[ACTION_SA_QUERY_TR_ID_LEN]; /* Transaction id */ -+ -+} __KAL_ATTRIB_PACKED__ ACTION_SA_QUERY_FRAME, *P_ACTION_SA_QUERY_FRAME; -+#endif -+ -+/* 7.4.10 Notify Channel Width Management frame format */ -+typedef struct _ACTION_NOTIFY_CHNL_WIDTH_FRAME { -+ /* MAC header */ -+ UINT_16 u2FrameCtrl; /* Frame Control */ -+ UINT_16 u2Duration; /* Duration */ -+ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ -+ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ -+ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ -+ UINT_16 u2SeqCtrl; /* Sequence Control */ -+ /* BSS Coexistence Management frame body */ -+ UINT_8 ucCategory; /* Category */ -+ UINT_8 ucAction; /* Action Value */ -+ UINT_8 ucChannelWidth; /* Channel Width */ -+} __KAL_ATTRIB_PACKED__ ACTION_NOTIFY_CHNL_WIDTH_FRAME, *P_ACTION_NOTIFY_CHNL_WIDTH_FRAME; -+ -+/* 802.11v Wireless Network Management: Timing Measurement Request */ -+typedef struct _ACTION_WNM_TIMING_MEAS_REQ_FRAME { -+ /* MAC header */ -+ UINT_16 u2FrameCtrl; /* Frame Control */ -+ UINT_16 u2Duration; /* Duration */ -+ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ -+ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ -+ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ -+ UINT_16 u2SeqCtrl; /* Sequence Control */ -+ /* Timing Measurement Request Management frame body */ -+ UINT_8 ucCategory; /* Category */ -+ UINT_8 ucAction; /* Action Value */ -+ UINT_8 ucTrigger; /* Trigger */ -+} __KAL_ATTRIB_PACKED__ ACTION_WNM_TIMING_MEAS_REQ_FRAME, *P_ACTION_WNM_TIMING_MEAS_REQ_FRAME; -+ -+/* 802.11v Wireless Network Management: Timing Measurement */ -+typedef struct _ACTION_UNPROTECTED_WNM_TIMING_MEAS_FRAME { -+ /* MAC header */ -+ UINT_16 u2FrameCtrl; /* Frame Control */ -+ UINT_16 u2Duration; /* Duration */ -+ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ -+ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ -+ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ -+ UINT_16 u2SeqCtrl; /* Sequence Control */ -+ /* Timing Measurement Management frame body */ -+ UINT_8 ucCategory; /* Category */ -+ UINT_8 ucAction; /* Action Value */ -+ UINT_8 ucDialogToken; /* Dialog Token */ -+ UINT_8 ucFollowUpDialogToken; /* Follow Up Dialog Token */ -+ UINT_32 u4ToD; /* Timestamp of Departure [10ns] */ -+ UINT_32 u4ToA; /* Timestamp of Arrival [10ns] */ -+ UINT_8 ucMaxToDErr; /* Maximum of ToD Error [10ns] */ -+ UINT_8 ucMaxToAErr; /* Maximum of ToA Error [10ns] */ -+} __KAL_ATTRIB_PACKED__ ACTION_UNPROTECTED_WNM_TIMING_MEAS_FRAME, *P_ACTION_UNPROTECTED_WNM_TIMING_MEAS_FRAME; -+ -+/* 3 Information Elements from WFA. */ -+typedef struct _IE_WFA_T { -+ UINT_8 ucId; -+ UINT_8 ucLength; -+ UINT_8 aucOui[3]; -+ UINT_8 ucOuiType; -+ UINT_8 aucOuiSubTypeVersion[2]; -+ /*!< Please be noted. WPA defines a 16 bit field version -+ instead of one subtype field and one version field */ -+} __KAL_ATTRIB_PACKED__ IE_WFA_T, *P_IE_WFA_T; -+ -+/* HS20 3.1 - HS 2.0 Indication Information Element */ -+typedef struct _IE_HS20_INDICATION_T { -+ UINT_8 ucId; /* Element ID */ -+ UINT_8 ucLength; /* Length */ -+ UINT_8 aucOui[3]; /* OUI */ -+ UINT_8 ucType; /* Type */ -+ UINT_8 ucHotspotConfig; /* Hotspot Configuration */ -+} __KAL_ATTRIB_PACKED__ IE_HS20_INDICATION_T, *P_IE_HS20_INDICATION_T; -+ -+/* WAPI Information element format */ -+typedef struct _WAPI_INFO_ELEM_T { -+ UCHAR ucElemId; -+ UCHAR ucLength; -+ UINT_16 u2Version; -+ UINT_16 u2AuthKeyMgtSuiteCount; -+ UCHAR aucAuthKeyMgtSuite1[4]; -+} __KAL_ATTRIB_PACKED__ WAPI_INFO_ELEM_T, *P_WAPI_INFO_ELEM_T; -+ -+#if defined(WINDOWS_DDK) || defined(WINDOWS_CE) -+#pragma pack() -+#endif -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+/* Convert the ECWmin(max) to CWmin(max) */ -+#define ECW_TO_CW(_ECW) ((1 << (_ECW)) - 1) -+ -+/* Convert the RCPI to dBm */ -+#define RCPI_TO_dBm(_rcpi) \ -+ ((PARAM_RSSI)(((_rcpi) > RCPI_HIGH_BOUND ? RCPI_HIGH_BOUND : (_rcpi)) >> 1) - NDBM_LOW_BOUND_FOR_RCPI) -+ -+/* Convert the dBm to RCPI */ -+#define dBm_TO_RCPI(_dbm) \ -+ (RCPI)(((((PARAM_RSSI)(_dbm) + NDBM_LOW_BOUND_FOR_RCPI) << 1) > RCPI_HIGH_BOUND) ? RCPI_HIGH_BOUND : \ -+ ((((PARAM_RSSI)(_dbm) + NDBM_LOW_BOUND_FOR_RCPI) << 1) < RCPI_LOW_BOUND ? RCPI_LOW_BOUND : \ -+ (((PARAM_RSSI)(_dbm) + NDBM_LOW_BOUND_FOR_RCPI) << 1))) -+ -+/* Convert an unsigned char pointer to an information element pointer */ -+#define IE_ID(fp) (((P_IE_HDR_T) fp)->ucId) -+#define IE_LEN(fp) (((P_IE_HDR_T) fp)->ucLength) -+#define IE_SIZE(fp) (ELEM_HDR_LEN + IE_LEN(fp)) -+ -+#define SSID_IE(fp) ((P_IE_SSID_T) fp) -+ -+#define SUP_RATES_IE(fp) ((P_IE_SUPPORTED_RATE_T) fp) -+ -+#define DS_PARAM_IE(fp) ((P_IE_DS_PARAM_SET_T) fp) -+ -+#define TIM_IE(fp) ((P_IE_TIM_T) fp) -+ -+#define IBSS_PARAM_IE(fp) ((P_IE_IBSS_PARAM_SET_T) fp) -+ -+#define ERP_INFO_IE(fp) ((P_IE_ERP_T) fp) -+ -+#define EXT_SUP_RATES_IE(fp) ((P_IE_EXT_SUPPORTED_RATE_T) fp) -+ -+#define WFA_IE(fp) ((P_IE_WFA_T) fp) -+ -+#if CFG_SUPPORT_802_11D -+#define COUNTRY_IE(fp) ((P_IE_COUNTRY_T) fp) -+#endif -+ -+#define EXT_CAP_IE(fp) ((P_EXT_CAP_T) fp) -+ -+#define HT_CAP_IE(fp) ((P_IE_HT_CAP_T) fp) -+ -+#define HT_OP_IE(fp) ((P_IE_HT_OP_T) fp) -+ -+#define OBSS_SCAN_PARAM_IE(fp) ((P_IE_OBSS_SCAN_PARAM_T) fp) -+ -+#define BSS_20_40_COEXIST_IE(fp) ((P_IE_20_40_COEXIST_T) fp) -+ -+#define SUP_OPERATING_CLASS_IE(fp) ((P_IE_SUP_OPERATING_CLASS_T) fp) -+ -+#define QUIET_IE(fp) ((P_IE_QUIET_T) fp) -+ -+#if CFG_SUPPORT_DFS /* Add by Enlai */ -+#define SUPPORTED_CHANNELS_IE(fp) ((P_IE_SUPPORTED_CHANNELS_T)fp) -+#endif -+ -+#define TIMEOUT_INTERVAL_IE(fp) ((IE_TIMEOUT_INTERVAL_T *)fp) -+ -+/* The macro to check if the MAC address is B/MCAST Address */ -+#define IS_BMCAST_MAC_ADDR(_pucDestAddr) \ -+ ((BOOLEAN) (((PUINT_8)(_pucDestAddr))[0] & BIT(0))) -+ -+/* The macro to check if the MAC address is UCAST Address */ -+#define IS_UCAST_MAC_ADDR(_pucDestAddr) \ -+ ((BOOLEAN) !(((PUINT_8)(_pucDestAddr))[0] & BIT(0))) -+ -+/* The macro to copy the MAC address */ -+#define COPY_MAC_ADDR(_pucDestAddr, _pucSrcAddr) \ -+ kalMemCopy(_pucDestAddr, _pucSrcAddr, MAC_ADDR_LEN) -+ -+/* The macro to check if two MAC addresses are equal */ -+#define EQUAL_MAC_ADDR(_pucDestAddr, _pucSrcAddr) \ -+ (!kalMemCmp(_pucDestAddr, _pucSrcAddr, MAC_ADDR_LEN)) -+ -+/* The macro to check if two MAC addresses are not equal */ -+#define UNEQUAL_MAC_ADDR(_pucDestAddr, _pucSrcAddr) \ -+ (kalMemCmp(_pucDestAddr, _pucSrcAddr, MAC_ADDR_LEN)) -+ -+/* The macro to check whether two SSIDs are equal */ -+#define EQUAL_SSID(pucSsid1, ucSsidLen1, pucSsid2, ucSsidLen2) \ -+ ((ucSsidLen1 <= ELEM_MAX_LEN_SSID) && \ -+ (ucSsidLen2 <= ELEM_MAX_LEN_SSID) && \ -+ ((ucSsidLen1) == (ucSsidLen2)) && \ -+ !kalMemCmp(pucSsid1, pucSsid2, ucSsidLen1)) -+ -+/* The macro to check whether two SSIDs are equal */ -+#define UNEQUAL_SSID(pucSsid1, ucSsidLen1, pucSsid2, ucSsidLen2) \ -+ ((ucSsidLen1 > ELEM_MAX_LEN_SSID) || \ -+ (ucSsidLen2 > ELEM_MAX_LEN_SSID) || \ -+ ((ucSsidLen1) != (ucSsidLen2)) || \ -+ kalMemCmp(pucSsid1, pucSsid2, ucSsidLen1)) -+ -+/* The macro to copy the SSID, the length of pucDestSsid should have at least 32 bytes */ -+#define COPY_SSID(pucDestSsid, ucDestSsidLen, pucSrcSsid, ucSrcSsidLen) \ -+ do { \ -+ ucDestSsidLen = ucSrcSsidLen; \ -+ if (ucSrcSsidLen) { \ -+ ASSERT(ucSrcSsidLen <= ELEM_MAX_LEN_SSID); \ -+ kalMemCopy(pucDestSsid, \ -+ pucSrcSsid, \ -+ ((ucSrcSsidLen > ELEM_MAX_LEN_SSID) ? ELEM_MAX_LEN_SSID : ucSrcSsidLen)); \ -+ } \ -+ } while (FALSE) -+ -+/* The macro to copy the IE */ -+#define COPY_IE(pucDestIE, pucSrcIE) \ -+ do { \ -+ kalMemCopy((PUINT_8)pucDestIE, \ -+ (PUINT_8)pucSrcIE,\ -+ IE_SIZE(pucSrcIE)); \ -+ } while (FALSE) -+ -+#define IE_FOR_EACH(_pucIEsBuf, _u2IEsBufLen, _u2Offset) \ -+ for ((_u2Offset) = 0;\ -+ ((((_u2Offset) + 2) <= (_u2IEsBufLen)) && (((_u2Offset) + IE_SIZE(_pucIEsBuf)) <= (_u2IEsBufLen))); \ -+ (_u2Offset) += IE_SIZE(_pucIEsBuf), (_pucIEsBuf) += IE_SIZE(_pucIEsBuf)) -+ -+#define SET_EXT_CAP(_aucField, _ucFieldLength, _ucBit) \ -+ do { \ -+ if ((_ucBit) < ((_ucFieldLength) * 8)) { \ -+ PUINT_8 aucExtCap = (PUINT_8)(_aucField); \ -+ ((aucExtCap)[(_ucBit) / 8]) |= BIT((_ucBit) % 8); \ -+ } \ -+ } while (FALSE) -+ -+#define TEST_EXT_CAP(_aucField, _ucFieldLength, _ucBit) \ -+ ((((_ucFieldLength) * 8) > (_ucBit)) && (((_aucField)[(_ucBit) / 8]) & BIT((_ucBit) % 8))) -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif /* _MAC_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/mtreg.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/mtreg.h -new file mode 100644 -index 000000000000..583923aed010 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/mtreg.h -@@ -0,0 +1,272 @@ -+/* -+** Id: //Department/DaVinci/TRUNK/MT6620_5931_WiFi_Driver/include/nic/mtreg.h#2 -+*/ -+ -+/*! \file "mtreg.h" -+ \brief The common register definition of mt5931 -+ -+ N/A -+*/ -+ -+/* -+** Log: mtreg.h -+ * -+ * 01 28 2013 samp.lin -+ * [WCXRP00000851] [MT6582 Wi-Fi][Driver] Add HIFSYS related definition to driver source tree -+ * add MT6582-specific definitions. -+ * -+ * 08 15 2011 cp.wu -+ * [WCXRP00000851] [MT6628 Wi-Fi][Driver] Add HIFSYS related definition to driver source tree -+ * add MT6628-specific definitions. -+ * -+ * 07 13 2011 cp.wu -+ * [WCXRP00000851] [MT6628 Wi-Fi][Driver] Add HIFSYS related definition to driver source tree -+ * add initial version for MT6628 driver support. -+ * -+*/ -+ -+#ifndef _MTREG_H -+#define _MTREG_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+/* 1 MT6628 MCR Definition */ -+ -+/* 2 Host Interface */ -+ -+/* 4 CHIP ID Register */ -+#define MCR_WCIR 0x0000 -+ -+/* 4 HIF Low Power Control Register */ -+#define MCR_WHLPCR 0x0004 -+ -+/* 4 Control Status Register */ -+#define MCR_WSDIOCSR 0x0008 -+#define MCR_WSPICSR 0x0008 -+ -+/* 4 HIF Control Register */ -+#define MCR_WHCR 0x000C -+ -+/* 4 HIF Interrupt Status Register */ -+#define MCR_WHISR 0x0010 -+ -+/* 4 HIF Interrupt Enable Register */ -+#define MCR_WHIER 0x0014 -+ -+/* 4 Abnormal Status Register */ -+#define MCR_WASR 0x0018 -+ -+/* 4 WLAN Software Interrupt Control Register */ -+#define MCR_WSICR 0x001C -+ -+/* 4 WLAN TX Status Register */ -+#define MCR_WTSR0 0x0020 -+ -+/* 4 WLAN TX Status Register */ -+#define MCR_WTSR1 0x0024 -+ -+/* 4 WLAN TX Data Register 0 */ -+#define MCR_WTDR0 0x0028 -+ -+/* 4 WLAN TX Data Register 1 */ -+#define MCR_WTDR1 0x002C -+ -+/* 4 WLAN RX Data Register 0 */ -+#define MCR_WRDR0 0x0030 -+ -+/* 4 WLAN RX Data Register 1 */ -+#define MCR_WRDR1 0x0034 -+ -+/* 4 Host to Device Send Mailbox 0 Register */ -+#define MCR_H2DSM0R 0x0038 -+ -+/* 4 Host to Device Send Mailbox 1 Register */ -+#define MCR_H2DSM1R 0x003c -+ -+/* 4 Device to Host Receive Mailbox 0 Register */ -+#define MCR_D2HRM0R 0x0040 -+ -+/* 4 Device to Host Receive Mailbox 1 Register */ -+#define MCR_D2HRM1R 0x0044 -+ -+/* 4 Device to Host Receive Mailbox 2 Register */ -+#define MCR_D2HRM2R 0x0048 -+ -+/* 4 WLAN RX Packet Length Register */ -+#define MCR_WRPLR 0x0050 -+ -+/* 4 HSIF Transaction Count Register */ -+#define MCR_HSTCR 0x0058 -+ -+/* #if CFG_SDIO_INTR_ENHANCE */ -+typedef struct _ENHANCE_MODE_DATA_STRUCT_T { -+ UINT_32 u4WHISR; -+ union { -+ struct { -+ UINT_8 ucTQ0Cnt; -+ UINT_8 ucTQ1Cnt; -+ UINT_8 ucTQ2Cnt; -+ UINT_8 ucTQ3Cnt; -+ UINT_8 ucTQ4Cnt; -+ UINT_8 ucTQ5Cnt; -+ UINT_16 u2Rsrv; -+ } u; -+ UINT_32 au4WTSR[2]; -+ } rTxInfo; -+ union { -+ struct { -+ UINT_16 u2NumValidRx0Len; -+ UINT_16 u2NumValidRx1Len; -+ UINT_16 au2Rx0Len[16]; -+ UINT_16 au2Rx1Len[16]; -+ } u; -+ UINT_32 au4RxStatusRaw[17]; -+ } rRxInfo; -+ UINT_32 u4RcvMailbox0; -+ UINT_32 u4RcvMailbox1; -+} ENHANCE_MODE_DATA_STRUCT_T, *P_ENHANCE_MODE_DATA_STRUCT_T; -+/* #endif */ /* ENHANCE_MODE_DATA_STRUCT_T */ -+ -+/* 2 Definition in each register */ -+/* 3 WCIR 0x0000 */ -+#define WCIR_WLAN_READY BIT(21) -+#define WCIR_POR_INDICATOR BIT(20) -+#define WCIR_REVISION_ID BITS(16, 19) -+#define WCIR_CHIP_ID BITS(0, 15) -+ -+#define MTK_CHIP_REV_72 0x00006572 -+#define MTK_CHIP_REV_82 0x00006582 -+#define MTK_CHIP_REV_92 0x00006592 -+#define MTK_CHIP_MP_REVERSION_ID 0x0 -+ -+/* 3 WHLPCR 0x0004 */ -+#define WHLPCR_FW_OWN_REQ_CLR BIT(9) -+#define WHLPCR_FW_OWN_REQ_SET BIT(8) -+#define WHLPCR_IS_DRIVER_OWN BIT(8) -+#define WHLPCR_INT_EN_CLR BIT(1) -+#define WHLPCR_INT_EN_SET BIT(0) -+ -+/* 3 WSDIOCSR 0x0008 */ -+#define WSDIOCSR_SDIO_RE_INIT_EN BIT(0) -+ -+/* 3 WSPICSR 0x0008 */ -+#define WCSR_SPI_MODE_SEL BITS(3, 4) -+#define WCSR_SPI_ENDIAN_BIG BIT(2) -+#define WCSR_SPI_INT_OUT_MODE BIT(1) -+#define WCSR_SPI_DATA_OUT_MODE BIT(0) -+ -+/* 3 WHCR 0x000C */ -+#define WHCR_RX_ENHANCE_MODE_EN BIT(16) -+#define WHCR_MAX_HIF_RX_LEN_NUM BITS(4, 7) -+#define WHCR_W_MAILBOX_RD_CLR_EN BIT(2) -+#define WHCR_W_INT_CLR_CTRL BIT(1) -+#define WHCR_MCU_DBG_EN BIT(0) -+#define WHCR_OFFSET_MAX_HIF_RX_LEN_NUM 4 -+ -+/* 3 WHISR 0x0010 */ -+#define WHISR_D2H_SW_INT BITS(8, 31) -+#define WHISR_D2H_SW_ASSERT_INFO_INT BIT(31) -+#define WHISR_FW_OWN_BACK_INT BIT(4) -+#define WHISR_ABNORMAL_INT BIT(3) -+#define WHISR_RX1_DONE_INT BIT(2) -+#define WHISR_RX0_DONE_INT BIT(1) -+#define WHISR_TX_DONE_INT BIT(0) -+ -+/* 3 WHIER 0x0014 */ -+#define WHIER_D2H_SW_INT BITS(8, 31) -+#define WHIER_FW_OWN_BACK_INT_EN BIT(4) -+#define WHIER_ABNORMAL_INT_EN BIT(3) -+#define WHIER_RX1_DONE_INT_EN BIT(2) -+#define WHIER_RX0_DONE_INT_EN BIT(1) -+#define WHIER_TX_DONE_INT_EN BIT(0) -+#define WHIER_DEFAULT (WHIER_RX0_DONE_INT_EN | \ -+ WHIER_RX1_DONE_INT_EN | \ -+ WHIER_TX_DONE_INT_EN | \ -+ WHIER_ABNORMAL_INT_EN | \ -+ WHIER_D2H_SW_INT \ -+ ) -+ -+/* 3 WASR 0x0018 */ -+#define WASR_FW_OWN_INVALID_ACCESS BIT(4) -+#define WASR_RX1_UNDER_FLOW BIT(3) -+#define WASR_RX0_UNDER_FLOW BIT(2) -+#define WASR_TX1_OVER_FLOW BIT(1) -+#define WASR_TX0_OVER_FLOW BIT(0) -+ -+/* 3 WSICR 0x001C */ -+#define WSICR_H2D_SW_INT_SET BITS(16, 31) -+ -+/* 3 WRPLR 0x0050 */ -+#define WRPLR_RX1_PACKET_LENGTH BITS(16, 31) -+#define WRPLR_RX0_PACKET_LENGTH BITS(0, 15) -+ -+/* 3 HSTCR 0x0058 */ -+#define HSTCR_AFF_BURST_LEN BITS(24, 25) -+#define HSTCR_AFF_BURST_LEN_OFFSET 24 -+#define HSTCR_TRANS_TARGET BITS(20, 22) -+#define HSTCR_TRANS_TARGET_OFFSET 20 -+#define HSTCR_HSIF_TRANS_CNT BITS(2, 19) -+#define HSTCR_HSIF_TRANS_CNT_OFFSET 2 -+ -+/* HSTCR_TRANS_TARGET */ -+typedef enum _eTransTarget { -+ TRANS_TARGET_TXD0 = 0, -+ TRANS_TARGET_TXD1, -+ TRANS_TARGET_RXD0, -+ TRANS_TARGET_RXD1, -+ TRANS_TARGET_WHISR, -+ NUM_TRANS_TARGET -+} E_TRANS_TARGET_T; -+ -+typedef enum _E_AFF_BURST_LEN { -+ BURST_1_DW = 0, -+ BURST_4_DW, -+ BURST_8_DW, -+ BURST_RSV, -+ NUM_AFF_BURST_LEN -+} E_AFF_BURST_LEN; -+ -+#endif /* _MTREG_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/nic.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/nic.h -new file mode 100644 -index 000000000000..c059b707aee8 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/nic.h -@@ -0,0 +1,498 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/nic/nic.h#1 -+*/ -+ -+/*! \file "nic.h" -+ \brief The declaration of nic functions -+ -+ Detail description. -+*/ -+ -+/* -+** Log: nic.h -+ * -+ * 11 01 2011 chinglan.wang -+ * NULL -+ * Modify the Wi-Fi method of the flush TX queue when disconnect the AP. -+ * If disconnect the AP and flush all the data frame in the TX queue, WPS -+ * cannot do the 4-way handshake to connect to the AP.. -+ * -+ * 07 18 2011 chinghwa.yu -+ * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm -+ * Add CMD/Event for RDD and BWCS. -+ * -+ * 05 11 2011 cp.wu -+ * [WCXRP00000718] [MT6620 Wi-Fi] modify the behavior of setting tx power -+ * ACPI APIs migrate to wlan_lib.c for glue layer to invoke. -+ * -+ * 04 11 2011 yuche.tsai -+ * [WCXRP00000627] [Volunteer Patch][MT6620][Driver] Pending MMPUD of P2P Network may crash system issue. -+ * Fix kernel panic issue when MMPDU of P2P is pending in driver. -+ * -+ * 03 02 2011 cp.wu -+ * [WCXRP00000503] [MT6620 Wi-Fi][Driver] Take RCPI brought by association response as initial RSSI right -+ * after connection is built. -+ * use RCPI brought by ASSOC-RESP after connection is built as initial RCPI to avoid using a uninitialized MAC-RX RCPI. -+ * -+ * 02 01 2011 cm.chang -+ * [WCXRP00000415] [MT6620 Wi-Fi][Driver] Check if any memory leakage happens when uninitializing in DGB mode -+ * . -+ * -+ * 01 27 2011 tsaiyuan.hsu -+ * [WCXRP00000392] [MT6620 Wi-Fi][Driver] Add Roaming Support -+ * add roaming fsm -+ * 1. not support 11r, only use strength of signal to determine roaming. -+ * 2. not enable CFG_SUPPORT_ROAMING until completion of full test. -+ * 3. in 6620, adopt work-around to avoid sign extension problem of cck of hw -+ * 4. assume that change of link quality in smooth way. -+ * -+ * 10 26 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000137] [MT6620 Wi-Fi] [FW] -+ * Support NIC capability query command -+ * 1) update NVRAM content template to ver 1.02 -+ * 2) add compile option for querying NIC capability (default: off) -+ * 3) modify AIS 5GHz support to run-time option, which could be turned on by registry or NVRAM setting -+ * 4) correct auto-rate compiler error under linux (treat warning as error) -+ * 5) simplify usage of NVRAM and REG_INFO_T -+ * 6) add version checking between driver and firmware -+ * -+ * 10 26 2010 eddie.chen -+ * [WCXRP00000134] [MT6620 Wi-Fi][Driver] Add a registry to enable auto rate for SQA test by using E1 EVB -+ * Add auto rate parameter in registry. -+ * -+ * 10 12 2010 cp.wu -+ * [WCXRP00000084] [MT6620 Wi-Fi][Driver][FW] Add fixed rate support for distance test -+ * add HT (802.11n) fixed rate support. -+ * -+ * 10 08 2010 cp.wu -+ * [WCXRP00000084] [MT6620 Wi-Fi][Driver][FW] Add fixed rate support for distance test -+ * adding fixed rate support for distance test. (from registry setting) -+ * -+ * 10 05 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check -+ * 1) add NVRAM access API -+ * 2) fake scanning result when NVRAM doesn't exist and/or version mismatch. (off by compiler option) -+ * 3) add OID implementation for NVRAM read/write service -+ * -+ * 10 04 2010 cp.wu -+ * [WCXRP00000077] [MT6620 Wi-Fi][Driver][FW] Eliminate use of ENUM_NETWORK_TYPE_T and replaced -+ * by ENUM_NETWORK_TYPE_INDEX_T only -+ * remove ENUM_NETWORK_TYPE_T definitions -+ * -+ * 09 21 2010 cp.wu -+ * [WCXRP00000053] [MT6620 Wi-Fi][Driver] Reset incomplete and might leads to BSOD when entering RF test -+ * with AIS associated -+ * Do a complete reset with STA-REC null checking for RF test re-entry -+ * -+ * 09 08 2010 cp.wu -+ * NULL -+ * use static memory pool for storing IEs of scanning result. -+ * -+ * 09 01 2010 cp.wu -+ * NULL -+ * HIFSYS Clock Source Workaround -+ * -+ * 08 25 2010 george.huang -+ * NULL -+ * update OID/ registry control path for PM related settings -+ * -+ * 08 12 2010 cp.wu -+ * NULL -+ * [AIS-FSM] honor registry setting for adhoc running mode. (A/B/G) -+ * -+ * 08 03 2010 cp.wu -+ * NULL -+ * Centralize mgmt/system service procedures into independent calls. -+ * -+ * 07 28 2010 cp.wu -+ * NULL -+ * 1) eliminate redundant variable eOPMode in prAdapter->rWlanInfo -+ * 2) change nicMediaStateChange() API prototype -+ * -+ * 07 14 2010 yarco.yang -+ * -+ * 1. Remove CFG_MQM_MIGRATION -+ * 2. Add CMD_UPDATE_WMM_PARMS command -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 07 06 2010 george.huang -+ * [WPD00001556]Basic power managemenet function -+ * Update arguments for nicUpdateBeaconIETemplate() -+ * -+ * 07 06 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * STA-REC is maintained by CNM only. -+ * -+ * 07 05 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) ignore RSN checking when RSN is not turned on. -+ * 2) set STA-REC deactivation callback as NULL -+ * 3) add variable initialization API based on PHY configuration -+ * -+ * 06 30 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * sync. with CMD/EVENT document ver0.07. -+ * -+ * 06 29 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) sync to. CMD/EVENT document v0.03 -+ * 2) simplify DTIM period parsing in scan.c only, bss.c no longer parses it again. -+ * 3) send command packet to indicate FW-PM after -+ * a) 1st beacon is received after AIS has connected to an AP -+ * b) IBSS-ALONE has been created -+ * c) IBSS-MERGE has occurred -+ * -+ * 06 25 2010 george.huang -+ * [WPD00001556]Basic power managemenet function -+ * Create beacon update path, with expose bssUpdateBeaconContent() -+ * -+ * 06 22 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) add command warpper for STA-REC/BSS-INFO sync. -+ * 2) enhance command packet sending procedure for non-oid part -+ * 3) add command packet definitions for STA-REC/BSS-INFO sync. -+ * -+ * 06 21 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * implement TX_DONE callback path. -+ * -+ * 06 11 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) migrate assoc.c. -+ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness -+ * 3) add configuration options for CNM_MEM and RSN modules -+ * 4) add data path for management frames -+ * 5) eliminate rPacketInfo of MSDU_INFO_T -+ * -+ * 06 10 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) eliminate CFG_CMD_EVENT_VERSION_0_9 -+ * 2) when disconnected, indicate nic directly (no event is needed) -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 04 26 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) surpress compiler warning -+ * 2) when acqruing LP-own, keep writing WHLPCR whenever OWN is not acquired yet -+ * -+ * 04 13 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * add framework for BT-over-Wi-Fi support. -+ * * * * * * * * * 1) prPendingCmdInfo is replaced by queue for multiple handler capability -+ * * * * * * * * * 2) command sequence number is now increased atomically -+ * * * * * * * * * 3) private data could be hold and taken use for other purpose -+ * -+ * 04 12 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * add channel frequency <-> number conversion -+ * -+ * 03 19 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) add ACPI D0/D3 state switching support -+ * * * * * 2) use more formal way to handle interrupt when the status is retrieved from enhanced RX response -+ * -+ * 03 17 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * always process TX interrupt first then RX interrupt. -+ * -+ * 02 25 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * correct behavior to prevent duplicated RX handling for RX0_DONE and RX1_DONE -+ * -+ * 02 23 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * add checksum offloading support. -+** \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-10-13 21:58:58 GMT mtk01084 -+** update for new HW architecture design -+** \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-04-24 21:12:55 GMT mtk01104 -+** Add function prototype nicRestoreSpiDefMode() -+** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-03-19 18:32:54 GMT mtk01084 -+** update for basic power management functions -+** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 20:16:32 GMT mtk01426 -+** Init for develop -+** -+*/ -+ -+#ifndef _NIC_H -+#define _NIC_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+struct _REG_ENTRY_T { -+ UINT_32 u4Offset; -+ UINT_32 u4Value; -+}; -+ -+struct _TABLE_ENTRY_T { -+ P_REG_ENTRY_T pu4TablePtr; -+ UINT_16 u2Size; -+}; -+ -+/*! INT status to event map */ -+typedef struct _INT_EVENT_MAP_T { -+ UINT_32 u4Int; -+ UINT_32 u4Event; -+} INT_EVENT_MAP_T, *P_INT_EVENT_MAP_T; -+ -+enum ENUM_INT_EVENT_T { -+ INT_EVENT_ABNORMAL, -+ INT_EVENT_SW_INT, -+ INT_EVENT_TX, -+ INT_EVENT_RX, -+ INT_EVENT_NUM -+}; -+ -+typedef enum _ENUM_IE_UPD_METHOD_T { -+ IE_UPD_METHOD_UPDATE_RANDOM, -+ IE_UPD_METHOD_UPDATE_ALL, -+ IE_UPD_METHOD_DELETE_ALL, -+} ENUM_IE_UPD_METHOD_T, *P_ENUM_IE_UPD_METHOD_T; -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+extern BOOLEAN fgIsResetting; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+/*----------------------------------------------------------------------------*/ -+/* Routines in nic.c */ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS nicAllocateAdapterMemory(IN P_ADAPTER_T prAdapter); -+ -+VOID nicReleaseAdapterMemory(IN P_ADAPTER_T prAdapter); -+ -+VOID nicDisableInterrupt(IN P_ADAPTER_T prAdapter); -+ -+VOID nicEnableInterrupt(IN P_ADAPTER_T prAdapter); -+ -+WLAN_STATUS nicProcessIST(IN P_ADAPTER_T prAdapter); -+ -+WLAN_STATUS nicProcessIST_impl(IN P_ADAPTER_T prAdapter, IN UINT_32 u4IntStatus); -+ -+WLAN_STATUS nicInitializeAdapter(IN P_ADAPTER_T prAdapter); -+ -+VOID nicMCRInit(IN P_ADAPTER_T prAdapter); -+ -+BOOLEAN nicVerifyChipID(IN P_ADAPTER_T prAdapter); -+ -+#if CFG_SDIO_INTR_ENHANCE -+VOID nicSDIOInit(IN P_ADAPTER_T prAdapter); -+ -+VOID nicSDIOReadIntStatus(IN P_ADAPTER_T prAdapter, OUT PUINT_32 pu4IntStatus); -+#endif -+ -+BOOLEAN nicpmSetDriverOwn(IN P_ADAPTER_T prAdapter); -+ -+VOID nicpmSetFWOwn(IN P_ADAPTER_T prAdapter, IN BOOLEAN fgEnableGlobalInt); -+ -+BOOLEAN nicpmSetAcpiPowerD0(IN P_ADAPTER_T prAdapter); -+ -+BOOLEAN nicpmSetAcpiPowerD3(IN P_ADAPTER_T prAdapter); -+ -+#if defined(_HIF_SPI) -+void nicRestoreSpiDefMode(IN P_ADAPTER_T prAdapter); -+#endif -+ -+VOID nicProcessSoftwareInterrupt(IN P_ADAPTER_T prAdapter); -+ -+VOID nicProcessAbnormalInterrupt(IN P_ADAPTER_T prAdapter); -+ -+VOID nicPutMailbox(IN P_ADAPTER_T prAdapter, IN UINT_32 u4MailboxNum, IN UINT_32 u4Data); -+ -+VOID nicGetMailbox(IN P_ADAPTER_T prAdapter, IN UINT_32 u4MailboxNum, OUT PUINT_32 pu4Data); -+ -+VOID nicSetSwIntr(IN P_ADAPTER_T prAdapter, IN UINT_32 u4SwIntrBitmap); -+ -+P_CMD_INFO_T nicGetPendingCmdInfo(IN P_ADAPTER_T prAdapter, IN UINT_8 ucSeqNum); -+ -+P_MSDU_INFO_T nicGetPendingTxMsduInfo(IN P_ADAPTER_T prAdapter, IN UINT_8 ucSeqNum); -+ -+P_MSDU_INFO_T nicGetPendingStaMMPDU(IN P_ADAPTER_T prAdapter, IN UINT_8 ucStaRecIdx); -+ -+VOID nicFreePendingTxMsduInfoByNetwork(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkType); -+ -+UINT_8 nicIncreaseCmdSeqNum(IN P_ADAPTER_T prAdapter); -+ -+UINT_8 nicIncreaseTxSeqNum(IN P_ADAPTER_T prAdapter); -+ -+/* Media State Change */ -+WLAN_STATUS -+nicMediaStateChange(IN P_ADAPTER_T prAdapter, -+ IN ENUM_NETWORK_TYPE_INDEX_T eNetworkType, IN P_EVENT_CONNECTION_STATUS prConnectionStatus); -+ -+/* Utility function for channel number conversion */ -+UINT_32 nicChannelNum2Freq(IN UINT_32 u4ChannelNum); -+ -+UINT_32 nicFreq2ChannelNum(IN UINT_32 u4FreqInKHz); -+ -+/* firmware command wrapper */ -+ /* NETWORK (WIFISYS) */ -+WLAN_STATUS nicActivateNetwork(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx); -+ -+WLAN_STATUS nicDeactivateNetwork(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx); -+ -+ /* BSS-INFO */ -+WLAN_STATUS nicUpdateBss(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx); -+ -+ /* BSS-INFO Indication (PM) */ -+WLAN_STATUS nicPmIndicateBssCreated(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx); -+ -+WLAN_STATUS nicPmIndicateBssConnected(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx); -+ -+WLAN_STATUS nicPmIndicateBssAbort(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx); -+ -+ /* Beacon Template Update */ -+WLAN_STATUS -+nicUpdateBeaconIETemplate(IN P_ADAPTER_T prAdapter, -+ IN ENUM_IE_UPD_METHOD_T eIeUpdMethod, -+ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, -+ IN UINT_16 u2Capability, IN PUINT_8 aucIe, IN UINT_16 u2IELen); -+ -+WLAN_STATUS nicQmUpdateWmmParms(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx); -+ -+WLAN_STATUS nicSetAutoTxPower(IN P_ADAPTER_T prAdapter, IN P_CMD_AUTO_POWER_PARAM_T prAutoPwrParam); -+ -+/*----------------------------------------------------------------------------*/ -+/* Calibration Control */ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS nicUpdateTxPower(IN P_ADAPTER_T prAdapter, IN P_CMD_TX_PWR_T prTxPwrParam); -+ -+WLAN_STATUS nicUpdate5GOffset(IN P_ADAPTER_T prAdapter, IN P_CMD_5G_PWR_OFFSET_T pr5GPwrOffset); -+ -+WLAN_STATUS nicUpdateDPD(IN P_ADAPTER_T prAdapter, IN P_CMD_PWR_PARAM_T prDpdCalResult); -+ -+/*----------------------------------------------------------------------------*/ -+/* PHY configuration */ -+/*----------------------------------------------------------------------------*/ -+VOID nicSetAvailablePhyTypeSet(IN P_ADAPTER_T prAdapter); -+ -+/*----------------------------------------------------------------------------*/ -+/* MGMT and System Service Control */ -+/*----------------------------------------------------------------------------*/ -+VOID nicInitSystemService(IN P_ADAPTER_T prAdapter); -+ -+VOID nicResetSystemService(IN P_ADAPTER_T prAdapter); -+ -+VOID nicUninitSystemService(IN P_ADAPTER_T prAdapter); -+ -+VOID nicInitMGMT(IN P_ADAPTER_T prAdapter, IN P_REG_INFO_T prRegInfo); -+ -+VOID nicUninitMGMT(IN P_ADAPTER_T prAdapter); -+ -+WLAN_STATUS -+nicConfigPowerSaveProfile(IN P_ADAPTER_T prAdapter, -+ ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, PARAM_POWER_MODE ePwrMode, BOOLEAN fgEnCmdEvent); -+ -+WLAN_STATUS nicEnterCtiaMode(IN P_ADAPTER_T prAdapter, BOOLEAN fgEnterCtia, BOOLEAN fgEnCmdEvent); -+/*----------------------------------------------------------------------------*/ -+/* Scan Result Processing */ -+/*----------------------------------------------------------------------------*/ -+VOID -+nicAddScanResult(IN P_ADAPTER_T prAdapter, -+ IN PARAM_MAC_ADDRESS rMacAddr, -+ IN P_PARAM_SSID_T prSsid, -+ IN UINT_32 u4Privacy, -+ IN PARAM_RSSI rRssi, -+ IN ENUM_PARAM_NETWORK_TYPE_T eNetworkType, -+ IN P_PARAM_802_11_CONFIG_T prConfiguration, -+ IN ENUM_PARAM_OP_MODE_T eOpMode, -+ IN PARAM_RATES_EX rSupportedRates, IN UINT_16 u2IELength, IN PUINT_8 pucIEBuf); -+ -+VOID nicFreeScanResultIE(IN P_ADAPTER_T prAdapter, IN UINT_32 u4Idx); -+ -+#if (MT6620_E1_ASIC_HIFSYS_WORKAROUND == 1) -+/*----------------------------------------------------------------------------*/ -+/* Workaround Control */ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS nicEnableClockGating(IN P_ADAPTER_T prAdapter); -+ -+WLAN_STATUS nicDisableClockGating(IN P_ADAPTER_T prAdapter); -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/* Fixed Rate Hacking */ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+nicUpdateRateParams(IN P_ADAPTER_T prAdapter, -+ IN ENUM_REGISTRY_FIXED_RATE_T eRateSetting, -+ IN PUINT_8 pucDesiredPhyTypeSet, -+ IN PUINT_16 pu2DesiredNonHTRateSet, -+ IN PUINT_16 pu2BSSBasicRateSet, -+ IN PUINT_8 pucMcsSet, IN PUINT_8 pucSupMcs32, IN PUINT_16 u2HtCapInfo); -+ -+/*----------------------------------------------------------------------------*/ -+/* Write registers */ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS nicWriteMcr(IN P_ADAPTER_T prAdapter, IN UINT_32 u4Address, IN UINT_32 u4Value); -+ -+/*----------------------------------------------------------------------------*/ -+/* Update auto rate */ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+nicRlmArUpdateParms(IN P_ADAPTER_T prAdapter, -+ IN UINT_32 u4ArSysParam0, -+ IN UINT_32 u4ArSysParam1, IN UINT_32 u4ArSysParam2, IN UINT_32 u4ArSysParam3); -+ -+/*----------------------------------------------------------------------------*/ -+/* Enable/Disable Roaming */ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS nicRoamingUpdateParams(IN P_ADAPTER_T prAdapter, IN UINT_32 u4EnableRoaming); -+ -+VOID nicPrintFirmwareAssertInfo(IN P_ADAPTER_T prAdapter); -+ -+/*----------------------------------------------------------------------------*/ -+/* Link Quality Updating */ -+/*----------------------------------------------------------------------------*/ -+VOID -+nicUpdateLinkQuality(IN P_ADAPTER_T prAdapter, -+ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIdx, IN P_EVENT_LINK_QUALITY prEventLinkQuality); -+ -+VOID -+nicUpdateRSSI(IN P_ADAPTER_T prAdapter, -+ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIdx, IN INT_8 cRssi, IN INT_8 cLinkQuality); -+ -+VOID nicUpdateLinkSpeed(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIdx, IN UINT_16 u2LinkSpeed); -+ -+#if CFG_SUPPORT_RDD_TEST_MODE -+WLAN_STATUS nicUpdateRddTestMode(IN P_ADAPTER_T prAdapter, IN P_CMD_RDD_CH_T prRddChParam); -+#endif -+ -+#endif /* _NIC_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/nic_rx.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/nic_rx.h -new file mode 100644 -index 000000000000..86e2c84b07ff ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/nic_rx.h -@@ -0,0 +1,420 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/nic/nic_rx.h#1 -+*/ -+ -+/*! \file "nic_rx.h" -+ \brief The declaration of the nic rx functions -+ -+*/ -+ -+/* -+** Log: nic_rx.h -+ * -+ * 11 07 2011 tsaiyuan.hsu -+ * [WCXRP00001083] [MT6620 Wi-Fi][DRV]] dump debug counter or frames when debugging is triggered -+ * add debug counters and periodically dump counters for debugging. -+ * -+ * 05 05 2011 cp.wu -+ * [WCXRP00000702] [MT5931][Driver] Modify initialization sequence for E1 ASIC -+ * add delay after whole-chip resetting for MT5931 E1 ASIC. -+ * -+ * 04 18 2011 terry.wu -+ * [WCXRP00000660] [MT6620 Wi-Fi][Driver] Remove flag CFG_WIFI_DIRECT_MOVED -+ * Remove flag CFG_WIFI_DIRECT_MOVED. -+ * -+ * 01 24 2011 cm.chang -+ * [WCXRP00000384] [MT6620 Wi-Fi][Driver][FW] Handle 20/40 action frame in AP mode -+ * and stop ampdu timer when sta_rec is freed -+ * Process received 20/40 coexistence action frame for AP mode -+ * -+ * 09 08 2010 cp.wu -+ * NULL -+ * use static memory pool for storing IEs of scanning result. -+ * -+ * 09 07 2010 yuche.tsai -+ * NULL -+ * Change prototype of API of adding P2P device to scan result. -+ * Additional IE buffer is saved. -+ * -+ * 09 03 2010 kevin.huang -+ * NULL -+ * Refine #include sequence and solve recursive/nested #include issue -+ * -+ * 08 05 2010 yuche.tsai -+ * NULL -+ * Modify data structure for P2P Scan result. -+ * -+ * 08 03 2010 cp.wu -+ * NULL -+ * newly added P2P API should be declared in header file. -+ * -+ * 07 30 2010 cp.wu -+ * NULL -+ * 1) BoW wrapper: use definitions instead of hard-coded constant for error code -+ * 2) AIS-FSM: eliminate use of desired RF parameters, use prTargetBssDesc instead -+ * 3) add handling for RX_PKT_DESTINATION_HOST_WITH_FORWARD for GO-broadcast frames -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 14 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * saa_fsm.c is migrated. -+ * -+ * 06 14 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add management dispatching function table. -+ * -+ * 06 11 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) migrate assoc.c. -+ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness -+ * 3) add configuration options for CNM_MEM and RSN modules -+ * 4) add data path for management frames -+ * 5) eliminate rPacketInfo of MSDU_INFO_T -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 03 30 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * remove driver-land statistics. -+ * -+ * 03 24 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * generate information for OID_GEN_RCV_OK & OID_GEN_XMIT_OK -+ * * -+ * -+ * 03 11 2010 cp.wu -+ * [WPD00003821][BUG] Host driver stops processing RX packets from HIF RX0 -+ * add RX starvation warning debug message controlled by CFG_HIF_RX_STARVATION_WARNING -+ * -+ * 03 10 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * code clean: removing unused variables and structure definitions -+ * -+ * 02 25 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * correct behavior to prevent duplicated RX handling for RX0_DONE and RX1_DONE -+ * -+ * 02 10 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * implement host-side firmware download logic -+ * -+ * 02 10 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) remove unused function in nic_rx.c [which has been handled in que_mgt.c] -+ * * 2) firmware image length is now retrieved via NdisFileOpen -+ * * 3) firmware image is not structured by (P_IMG_SEC_HDR_T) anymore -+ * * 4) nicRxWaitResponse() revised -+ * * 5) another set of TQ counter default value is added for fw-download state -+ * * 6) Wi-Fi load address is now retrieved from registry too -+ * -+ * 12 30 2009 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) According to CMD/EVENT documentation v0.8, -+ * * * * OID_CUSTOM_TEST_RX_STATUS & OID_CUSTOM_TEST_TX_STATUS is no longer used, -+ * * * * and result is retrieved by get ATInfo instead -+ * * * * 2) add 4 counter for recording aggregation statistics -+** \main\maintrunk.MT6620WiFiDriver_Prj\24 2009-12-10 16:49:09 GMT mtk02752 -+** code clean -+** \main\maintrunk.MT6620WiFiDriver_Prj\23 2009-12-09 14:02:37 GMT MTK02468 -+** Added ucStaRecIdx in SW_RFB_T and HALF_SEQ_NO_COUNT definition (to replace HALF_SEQ_NO_CNOUT) -+** \main\maintrunk.MT6620WiFiDriver_Prj\22 2009-11-27 11:07:54 GMT mtk02752 -+** add flush for reset -+** \main\maintrunk.MT6620WiFiDriver_Prj\21 2009-11-25 18:18:09 GMT mtk02752 -+** modify nicRxAddScanResult() -+** \main\maintrunk.MT6620WiFiDriver_Prj\20 2009-11-24 22:42:22 GMT mtk02752 -+** add nicRxAddScanResult() to prepare to handle SCAN_RESULT event -+** \main\maintrunk.MT6620WiFiDriver_Prj\19 2009-11-24 19:57:06 GMT mtk02752 -+** adopt P_HIF_RX_HEADER_T -+** \main\maintrunk.MT6620WiFiDriver_Prj\18 2009-11-16 21:43:04 GMT mtk02752 -+** correct ENUM_RX_PKT_DESTINATION_T definitions -+** \main\maintrunk.MT6620WiFiDriver_Prj\17 2009-11-16 15:28:25 GMT mtk02752 -+** add ucQueuedPacketNum for indicating how many packet are queued by RX reordering buffer/forwarding path -+** \main\maintrunk.MT6620WiFiDriver_Prj\16 2009-11-16 15:05:01 GMT mtk02752 -+** add eTC for SW_RFB_T and structure RX_MAILBOX -+** \main\maintrunk.MT6620WiFiDriver_Prj\15 2009-11-13 21:16:57 GMT mtk02752 -+** \main\maintrunk.MT6620WiFiDriver_Prj\14 2009-11-13 16:59:30 GMT mtk02752 -+** add handler for event packet -+** \main\maintrunk.MT6620WiFiDriver_Prj\13 2009-11-13 13:45:50 GMT mtk02752 -+** add port param for nicRxEnhanceReadBuffer() -+** \main\maintrunk.MT6620WiFiDriver_Prj\12 2009-11-11 10:12:31 GMT mtk02752 -+** nicSDIOReadIntStatus() always read sizeof(ENHANCE_MODE_DATA_STRUCT_T) for int response, -+** thus the number should be set to 0(:=16) instead of 10 -+** \main\maintrunk.MT6620WiFiDriver_Prj\11 2009-10-29 19:53:32 GMT mtk01084 -+** modify structure naming -+** \main\maintrunk.MT6620WiFiDriver_Prj\10 2009-10-23 16:08:23 GMT mtk01084 -+** \main\maintrunk.MT6620WiFiDriver_Prj\9 2009-10-13 21:59:01 GMT mtk01084 -+** update for new HW architecture design -+** \main\maintrunk.MT6620WiFiDriver_Prj\8 2009-05-20 12:23:33 GMT mtk01461 -+** Add u4MaxEventBufferLen parameter to nicRxWaitResponse() -+** \main\maintrunk.MT6620WiFiDriver_Prj\7 2009-05-18 21:00:48 GMT mtk01426 -+** Update SDIO_MAXIMUM_RX_STATUS value -+** \main\maintrunk.MT6620WiFiDriver_Prj\6 2009-04-28 10:36:15 GMT mtk01461 -+** Remove unused define - SDIO_MAXIMUM_TX_STATUS -+** \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-04-01 10:53:17 GMT mtk01461 -+** Add function for HIF_LOOPBACK_PRE_TEST -+** \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-03-18 20:56:19 GMT mtk01426 -+** Add to support CFG_HIF_LOOPBACK and CFG_SDIO_RX_ENHANCE -+** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-03-17 20:19:56 GMT mtk01426 -+** Add nicRxWaitResponse function proto type -+** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 20:16:35 GMT mtk01426 -+** Init for develop -+** -+*/ -+ -+#ifndef _NIC_RX_H -+#define _NIC_RX_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+extern P_SW_RFB_T g_arGscnResultsTempBuffer[]; -+extern UINT_8 g_GscanResultsTempBufferIndex; -+extern UINT_8 g_arGscanResultsIndicateNumber[]; -+extern UINT_8 g_GetResultsBufferedCnt; -+extern UINT_8 g_GetResultsCmdCnt; -+extern void kalDevLoopbkRxHandle(IN P_ADAPTER_T prAdapter, IN OUT P_SW_RFB_T prSwRfb); -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+#define MAX_SEQ_NO 4095 -+#define MAX_SEQ_NO_COUNT 4096 -+#define HALF_SEQ_NO_CNOUT 2048 -+ -+#define HALF_SEQ_NO_COUNT 2048 -+ -+#define MT6620_FIXED_WIN_SIZE 64 -+#define CFG_RX_MAX_BA_ENTRY 4 -+#define CFG_RX_MAX_BA_TID_NUM 8 -+ -+#define RX_STATUS_FLAG_MORE_PACKET BIT(30) -+#define RX_STATUS_CHKSUM_MASK BITS(0, 10) -+ -+#define RX_RFB_LEN_FIELD_LEN 4 -+#define RX_HEADER_OFFSET 2 -+ -+#define RX_RETURN_INDICATED_RFB_TIMEOUT_SEC 3 -+ -+#if defined(_HIF_SDIO) && defined(WINDOWS_DDK) -+/*! On XP, maximum Tx+Rx Statue <= 64-4(HISR)*/ -+#define SDIO_MAXIMUM_RX_LEN_NUM 0 /*!< 0~15 (0: un-limited) */ -+#else -+#define SDIO_MAXIMUM_RX_LEN_NUM 0 /*!< 0~15 (0: un-limited) */ -+#endif -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+typedef enum _ENUM_RX_STATISTIC_COUNTER_T { -+ RX_MPDU_TOTAL_COUNT = 0, -+ RX_SIZE_ERR_DROP_COUNT, -+ -+ RX_DATA_INDICATION_COUNT, -+ RX_DATA_RETURNED_COUNT, -+ RX_DATA_RETAINED_COUNT, -+ -+ RX_DROP_TOTAL_COUNT, -+ RX_TYPE_ERR_DROP_COUNT, -+ RX_CLASS_ERR_DROP_COUNT, -+ RX_DST_NULL_DROP_COUNT, -+ -+#if CFG_TCP_IP_CHKSUM_OFFLOAD || CFG_TCP_IP_CHKSUM_OFFLOAD_NDIS_60 -+ RX_CSUM_TCP_FAILED_COUNT, -+ RX_CSUM_UDP_FAILED_COUNT, -+ RX_CSUM_IP_FAILED_COUNT, -+ RX_CSUM_TCP_SUCCESS_COUNT, -+ RX_CSUM_UDP_SUCCESS_COUNT, -+ RX_CSUM_IP_SUCCESS_COUNT, -+ RX_CSUM_UNKNOWN_L4_PKT_COUNT, -+ RX_CSUM_UNKNOWN_L3_PKT_COUNT, -+ RX_IP_V6_PKT_CCOUNT, -+#endif -+ RX_STATISTIC_COUNTER_NUM -+} ENUM_RX_STATISTIC_COUNTER_T; -+ -+typedef enum _ENUM_RX_PKT_DESTINATION_T { -+ RX_PKT_DESTINATION_HOST, /* to OS */ -+ RX_PKT_DESTINATION_FORWARD, /* to TX queue for forward, AP mode */ -+ RX_PKT_DESTINATION_HOST_WITH_FORWARD, /* to both TX and OS, AP mode broadcast packet */ -+ RX_PKT_DESTINATION_NULL, /* packet to be freed */ -+ RX_PKT_DESTINATION_NUM -+} ENUM_RX_PKT_DESTINATION_T; -+ -+struct _SW_RFB_T { -+ QUE_ENTRY_T rQueEntry; -+ PVOID pvPacket; /*!< ptr to rx Packet Descriptor */ -+ PUINT_8 pucRecvBuff; /*!< ptr to receive data buffer */ -+ P_HIF_RX_HEADER_T prHifRxHdr; -+ UINT_32 u4HifRxHdrFlag; -+ PVOID pvHeader; -+ UINT_16 u2PacketLen; -+ UINT_16 u2HeaderLen; -+ UINT_16 u2SSN; -+ UINT_8 ucTid; -+ UINT_8 ucWlanIdx; -+ UINT_8 ucPacketType; -+ UINT_8 ucStaRecIdx; -+ -+ ENUM_CSUM_RESULT_T aeCSUM[CSUM_TYPE_NUM]; -+ ENUM_RX_PKT_DESTINATION_T eDst; -+ ENUM_TRAFFIC_CLASS_INDEX_T eTC; /* only valid when eDst == FORWARD */ -+ -+ UINT_64 rRxTime; -+}; -+ -+/*! RX configuration type structure */ -+typedef struct _RX_CTRL_T { -+ UINT_32 u4RxCachedSize; -+ PUINT_8 pucRxCached; -+ QUE_T rFreeSwRfbList; -+ QUE_T rReceivedRfbList; -+ QUE_T rIndicatedRfbList; -+ -+#if CFG_SDIO_RX_AGG -+ PUINT_8 pucRxCoalescingBufPtr; -+#endif -+ -+ PVOID apvIndPacket[CFG_RX_MAX_PKT_NUM]; -+ PVOID apvRetainedPacket[CFG_RX_MAX_PKT_NUM]; -+ -+ UINT_8 ucNumIndPacket; -+ UINT_8 ucNumRetainedPacket; -+ UINT_64 au8Statistics[RX_STATISTIC_COUNTER_NUM]; /*!< RX Counters */ -+ -+#if CFG_HIF_STATISTICS -+ UINT_32 u4TotalRxAccessNum; -+ UINT_32 u4TotalRxPacketNum; -+#endif -+ -+#if CFG_HIF_RX_STARVATION_WARNING -+ UINT_32 u4QueuedCnt; -+ UINT_32 u4DequeuedCnt; -+#endif -+ -+#if CFG_RX_PKTS_DUMP -+ UINT_32 u4RxPktsDumpTypeMask; -+#endif -+ -+} RX_CTRL_T, *P_RX_CTRL_T; -+ -+typedef struct _RX_MAILBOX_T { -+ UINT_32 u4RxMailbox[2]; /* for Device-to-Host Mailbox */ -+} RX_MAILBOX_T, *P_RX_MAILBOX_T; -+ -+typedef WLAN_STATUS(*PROCESS_RX_MGT_FUNCTION) (P_ADAPTER_T, P_SW_RFB_T); -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+#define RX_INC_CNT(prRxCtrl, eCounter) \ -+ {((P_RX_CTRL_T)prRxCtrl)->au8Statistics[eCounter]++; } -+ -+#define RX_ADD_CNT(prRxCtrl, eCounter, u8Amount) \ -+ {((P_RX_CTRL_T)prRxCtrl)->au8Statistics[eCounter] += (UINT_64)u8Amount; } -+ -+#define RX_GET_CNT(prRxCtrl, eCounter) \ -+ (((P_RX_CTRL_T)prRxCtrl)->au8Statistics[eCounter]) -+ -+#define RX_RESET_ALL_CNTS(prRxCtrl) \ -+ {kalMemZero(&prRxCtrl->au8Statistics[0], sizeof(prRxCtrl->au8Statistics)); } -+ -+#define RX_STATUS_TEST_MORE_FLAG(flag) \ -+ ((BOOLEAN)((flag & RX_STATUS_FLAG_MORE_PACKET) ? TRUE : FALSE)) -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+VOID nicRxInitialize(IN P_ADAPTER_T prAdapter); -+ -+VOID nicRxUninitialize(IN P_ADAPTER_T prAdapter); -+ -+VOID nicRxProcessRFBs(IN P_ADAPTER_T prAdapter); -+ -+#if !CFG_SDIO_INTR_ENHANCE -+VOID nicRxReceiveRFBs(IN P_ADAPTER_T prAdapter); -+ -+WLAN_STATUS nicRxReadBuffer(IN P_ADAPTER_T prAdapter, IN OUT P_SW_RFB_T prSwRfb); -+ -+#else -+VOID nicRxSDIOReceiveRFBs(IN P_ADAPTER_T prAdapter); -+ -+WLAN_STATUS -+nicRxEnhanceReadBuffer(IN P_ADAPTER_T prAdapter, -+ IN UINT_32 u4DataPort, IN UINT_16 u2RxLength, IN OUT P_SW_RFB_T prSwRfb); -+#endif /* CFG_SDIO_INTR_ENHANCE */ -+ -+#if CFG_SDIO_RX_AGG -+VOID nicRxSDIOAggReceiveRFBs(IN P_ADAPTER_T prAdapter); -+#endif -+ -+WLAN_STATUS nicRxSetupRFB(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prRfb); -+ -+VOID nicRxReturnRFB(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prRfb); -+ -+VOID nicProcessRxInterrupt(IN P_ADAPTER_T prAdapter); -+ -+VOID nicRxProcessPktWithoutReorder(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); -+ -+VOID nicRxProcessForwardPkt(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); -+ -+VOID nicRxProcessGOBroadcastPkt(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); -+ -+VOID nicRxFillRFB(IN P_ADAPTER_T prAdapter, IN OUT P_SW_RFB_T prSwRfb); -+ -+VOID nicRxProcessDataPacket(IN P_ADAPTER_T prAdapter, IN OUT P_SW_RFB_T prSwRfb); -+ -+VOID nicRxProcessEventPacket(IN P_ADAPTER_T prAdapter, IN OUT P_SW_RFB_T prSwRfb); -+ -+VOID nicRxProcessMgmtPacket(IN P_ADAPTER_T prAdapter, IN OUT P_SW_RFB_T prSwRfb); -+ -+#if CFG_TCP_IP_CHKSUM_OFFLOAD -+VOID nicRxFillChksumStatus(IN P_ADAPTER_T prAdapter, IN OUT P_SW_RFB_T prSwRfb, IN UINT_32 u4TcpUdpIpCksStatus); -+ -+VOID nicRxUpdateCSUMStatistics(IN P_ADAPTER_T prAdapter, IN const ENUM_CSUM_RESULT_T aeCSUM[]); -+#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */ -+ -+VOID nicRxQueryStatus(IN P_ADAPTER_T prAdapter, IN PUINT_8 pucBuffer, OUT PUINT_32 pu4Count); -+ -+VOID nicRxClearStatistics(IN P_ADAPTER_T prAdapter); -+ -+VOID nicRxQueryStatistics(IN P_ADAPTER_T prAdapter, IN PUINT_8 pucBuffer, OUT PUINT_32 pu4Count); -+ -+WLAN_STATUS -+nicRxWaitResponse(IN P_ADAPTER_T prAdapter, -+ IN UINT_8 ucPortIdx, OUT PUINT_8 pucRspBuffer, IN UINT_32 u4MaxRespBufferLen, OUT PUINT_32 pu4Length); -+ -+VOID nicRxEnablePromiscuousMode(IN P_ADAPTER_T prAdapter); -+ -+VOID nicRxDisablePromiscuousMode(IN P_ADAPTER_T prAdapter); -+ -+WLAN_STATUS nicRxFlush(IN P_ADAPTER_T prAdapter); -+ -+WLAN_STATUS nicRxProcessActionFrame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); -+ -+#endif /* _NIC_RX_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/nic_tx.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/nic_tx.h -new file mode 100644 -index 000000000000..e516468fcb16 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/nic_tx.h -@@ -0,0 +1,642 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/nic/nic_tx.h#1 -+*/ -+ -+/*! \file nic_tx.h -+ \brief Functions that provide TX operation in NIC's point of view. -+ -+ This file provides TX functions which are responsible for both Hardware and -+ Software Resource Management and keep their Synchronization. -+ -+*/ -+ -+/* -+** Log: nic_tx.h -+ * -+ * 11 18 2011 eddie.chen -+ * [WCXRP00001096] [MT6620 Wi-Fi][Driver/FW] Enhance the log function (xlog) -+ * Add log counter for tx -+ * -+ * 11 10 2011 eddie.chen -+ * [WCXRP00001096] [MT6620 Wi-Fi][Driver/FW] Enhance the log function (xlog) -+ * Add TX_DONE status detail information. -+ * -+ * 08 15 2011 cp.wu -+ * [WCXRP00000851] [MT6628 Wi-Fi][Driver] Add HIFSYS related definition to driver source tree -+ * add MT6628-specific definitions. -+ * -+ * 04 12 2011 cp.wu -+ * [WCXRP00000631] [MT6620 Wi-Fi][Driver] Add an API for QM to retrieve current TC counter value and processing -+ * frame dropping cases for TC4 path -+ * 1. add nicTxGetResource() API for QM to make decisions. -+ * 2. if management frames is decided by QM for dropping, the call back is invoked to indicate such a case. -+ * -+ * 03 21 2011 cp.wu -+ * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer -+ * portability improvement -+ * -+ * 02 16 2011 cp.wu -+ * [WCXRP00000449] [MT6620 Wi-Fi][Driver] Refine CMD queue handling by adding an extra API for checking -+ * available count and modify behavior -+ * 1. add new API: nicTxGetFreeCmdCount() -+ * 2. when there is insufficient command descriptor, nicTxEnqueueMsdu() will drop command packets directly -+ * -+ * 01 24 2011 cp.wu -+ * [WCXRP00000382] [MT6620 Wi-Fi][Driver] Track forwarding packet number with notifying tx thread for serving -+ * 1. add an extra counter for tracking pending forward frames. -+ * 2. notify TX service thread as well when there is pending forward frame -+ * 3. correct build errors leaded by introduction of Wi-Fi direct separation module -+ * -+ * 12 15 2010 yuche.tsai -+ * NULL -+ * Update SLT Descriptor number configure in driver. -+ * -+ * 11 16 2010 yarco.yang -+ * [WCXRP00000177] [MT5931 F/W] Performance tuning for 1st connection -+ * Update TX buffer count -+ * -+ * 11 03 2010 cp.wu -+ * [WCXRP00000083] [MT5931][Driver][FW] Add necessary logic for MT5931 first connection -+ * 1) use 8 buffers for MT5931 which is equipped with less memory -+ * 2) modify MT5931 debug level to TRACE when download is successful -+ * -+ * 10 18 2010 cp.wu -+ * [WCXRP00000117] [MT6620 Wi-Fi][Driver] Add logic for suspending driver when MT6620 is not responding anymore -+ * 1. when wlanAdapterStop() failed to send POWER CTRL command to firmware, do not poll for ready bit dis-assertion -+ * 2. shorten polling count for shorter response time -+ * 3. if bad I/O operation is detected during TX resource polling, then further operation is aborted as well -+ * -+ * 10 06 2010 cp.wu -+ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning -+ * code reorganization to improve isolation between GLUE and CORE layers. -+ * -+ * 09 03 2010 kevin.huang -+ * NULL -+ * Refine #include sequence and solve recursive/nested #include issue -+ * -+ * 08 30 2010 cp.wu -+ * NULL -+ * API added: nicTxPendingPackets(), for simplifying porting layer -+ * -+ * 07 26 2010 cp.wu -+ * -+ * change TC4 initial value from 2 to 4. -+ * -+ * 07 13 2010 cp.wu -+ * -+ * 1) MMPDUs are now sent to MT6620 by CMD queue for keeping strict order of 1X/MMPDU/CMD packets -+ * 2) integrate with qmGetFrameAction() for deciding which MMPDU/1X could pass checking for sending -+ * 2) enhance CMD_INFO_T descriptor number from 10 to 32 to avoid descriptor underflow under -+ * concurrent network operation -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 07 06 2010 yarco.yang -+ * [WPD00003837][MT6620]Data Path Refine -+ * Add MGMT Packet type for HIF_TX_HEADER -+ * -+ * 06 23 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * integrate . -+ * -+ * 06 21 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * refine TX-DONE callback. -+ * -+ * 06 21 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * TX descriptors are now allocated once for reducing allocation overhead -+ * -+ * 06 21 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * specify correct value for management frames. -+ * -+ * 06 11 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) migrate assoc.c. -+ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness -+ * 3) add configuration options for CNM_MEM and RSN modules -+ * 4) add data path for management frames -+ * 5) eliminate rPacketInfo of MSDU_INFO_T -+ * -+ * 06 10 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) add flag on MSDU_INFO_T for indicating BIP frame and forceBasicRate -+ * 2) add packet type for indicating management frames -+ * -+ * 06 09 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add necessary changes to driver data paths. -+ * -+ * 06 09 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add TX_PACKET_MGMT to indicate the frame is coming from management modules -+ * -+ * 06 07 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * merge wlan_def.h. -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 03 30 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * remove driver-land statistics. -+ * -+ * 03 24 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * generate information for OID_GEN_RCV_OK & OID_GEN_XMIT_OK -+ * * * -+ * -+ * 03 10 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * code clean: removing unused variables and structure definitions -+ * -+ * 03 02 2010 tehuang.liu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * Redistributed the initial TC resources for normal operation -+ * -+ * 03 02 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * add mutex to avoid multiple access to qmTxQueue simultaneously. -+ * -+ * 02 23 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * add new API: wlanProcessQueuedPackets() -+ * -+ * 02 10 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) remove unused function in nic_rx.c [which has been handled in que_mgt.c] -+ * * * 2) firmware image length is now retrieved via NdisFileOpen -+ * * * 3) firmware image is not structured by (P_IMG_SEC_HDR_T) anymore -+ * * * 4) nicRxWaitResponse() revised -+ * * * 5) another set of TQ counter default value is added for fw-download state -+ * * * 6) Wi-Fi load address is now retrieved from registry too -+ * -+ * 02 09 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1. Permanent and current MAC address are now retrieved by CMD/EVENT packets instead of hard-coded address -+ * * * * 2. follow MSDN defined behavior when associates to another AP -+ * * * * 3. for firmware download, packet size could be up to 2048 bytes -+ * -+ * 01 27 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1. eliminate improper variable in rHifInfo -+ * * * * * 2. block TX/ordinary OID when RF test mode is engaged -+ * * * * * 3. wait until firmware finish operation when entering into and leaving from RF test mode -+ * * * * * 4. correct some HAL implementation -+ * -+ * 01 13 2010 tehuang.liu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * Enabled the Burst_End Indication mechanism -+ * -+ * 12 30 2009 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) According to CMD/EVENT documentation v0.8, -+ * * * * * OID_CUSTOM_TEST_RX_STATUS & OID_CUSTOM_TEST_TX_STATUS is no longer used, -+ * * * * * and result is retrieved by get ATInfo instead -+ * * * * * 2) add 4 counter for recording aggregation statistics -+** \main\maintrunk.MT6620WiFiDriver_Prj\24 2009-12-10 16:53:28 GMT mtk02752 -+** remove unused API -+** \main\maintrunk.MT6620WiFiDriver_Prj\23 2009-11-27 11:08:00 GMT mtk02752 -+** add flush for reset -+** \main\maintrunk.MT6620WiFiDriver_Prj\22 2009-11-24 19:56:49 GMT mtk02752 -+** remove redundant eTC -+** \main\maintrunk.MT6620WiFiDriver_Prj\21 2009-11-23 22:01:08 GMT mtk02468 -+** Added MSDU_INFO fields for composing HIF TX header -+** \main\maintrunk.MT6620WiFiDriver_Prj\20 2009-11-17 22:40:51 GMT mtk01084 -+** \main\maintrunk.MT6620WiFiDriver_Prj\19 2009-11-17 17:35:05 GMT mtk02752 -+** + nicTxMsduInfoList() for sending MsduInfoList -+** + NIC_TX_BUFF_COUNT_TC[0~5] -+** \main\maintrunk.MT6620WiFiDriver_Prj\18 2009-11-17 11:07:00 GMT mtk02752 -+** add nicTxAdjustTcq() API -+** \main\maintrunk.MT6620WiFiDriver_Prj\17 2009-11-16 22:28:30 GMT mtk02752 -+** move aucFreeBufferCount/aucMaxNumOfBuffer into another structure -+** \main\maintrunk.MT6620WiFiDriver_Prj\16 2009-11-16 21:44:50 GMT mtk02752 -+** + nicTxReturnMsduInfo() -+** + nicTxFillMsduInfo() -+** + rFreeMsduInfoList field in TX_CTRL -+** \main\maintrunk.MT6620WiFiDriver_Prj\15 2009-11-16 18:00:43 GMT mtk02752 -+** use P_PACKET_INFO_T for prPacket to avoid inventing another new structure for packet -+** \main\maintrunk.MT6620WiFiDriver_Prj\14 2009-11-16 15:28:49 GMT mtk02752 -+** add ucQueuedPacketNum for indicating how many packets are queued by per STA/AC queue -+** \main\maintrunk.MT6620WiFiDriver_Prj\13 2009-11-16 10:52:01 GMT mtk02752 -+** \main\maintrunk.MT6620WiFiDriver_Prj\12 2009-11-14 23:39:24 GMT mtk02752 -+** interface structure redefine -+** \main\maintrunk.MT6620WiFiDriver_Prj\11 2009-11-13 21:17:03 GMT mtk02752 -+** \main\maintrunk.MT6620WiFiDriver_Prj\10 2009-10-29 19:53:10 GMT mtk01084 -+** remove strange code by Frog -+** \main\maintrunk.MT6620WiFiDriver_Prj\9 2009-10-13 21:59:04 GMT mtk01084 -+** update for new HW architecture design -+** \main\maintrunk.MT6620WiFiDriver_Prj\8 2009-10-02 13:53:03 GMT mtk01725 -+** \main\maintrunk.MT6620WiFiDriver_Prj\7 2009-04-28 10:36:50 GMT mtk01461 -+** Add declaration of nicTxReleaseResource() -+** \main\maintrunk.MT6620WiFiDriver_Prj\6 2009-04-17 19:58:39 GMT mtk01461 -+** Move CMD_INFO_T related define and function to cmd_buf.h -+** \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-04-01 10:53:53 GMT mtk01461 -+** Add function for SDIO_TX_ENHANCE -+** \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-03-23 00:33:27 GMT mtk01461 -+** Define constants for TX PATH and add nicTxPollingResource -+** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-03-16 09:09:32 GMT mtk01461 -+** Update TX PATH API -+** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 20:16:38 GMT mtk01426 -+** Init for develop -+** -+*/ -+ -+#ifndef _NIC_TX_H -+#define _NIC_TX_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+#define NIC_TX_RESOURCE_POLLING_TIMEOUT 256 -+#define NIC_TX_RESOURCE_POLLING_DELAY_MSEC 50 -+ -+/* Maximum buffer count for individual HIF TCQ */ -+ -+#if defined(MT6620) -+#if CFG_SLT_SUPPORT -+ /* 20101215 mtk01725 Redistributed the initial TC resources for SLT operation */ -+#define NIC_TX_BUFF_COUNT_TC0 0 /* First connection: 0 */ -+#define NIC_TX_BUFF_COUNT_TC1 16 /* First connection: 32 */ -+#define NIC_TX_BUFF_COUNT_TC2 0 /* First connection: 0 */ -+#define NIC_TX_BUFF_COUNT_TC3 0 /* First connection: 0 */ -+#define NIC_TX_BUFF_COUNT_TC4 4 /* First connection: 2 */ -+#define NIC_TX_BUFF_COUNT_TC5 0 /* First connection: 0 */ -+#else -+ /* 20100302 mtk02468 Redistributed the initial TC resources for normal operation */ -+#define NIC_TX_BUFF_COUNT_TC0 6 /* First connection: 0 */ -+#define NIC_TX_BUFF_COUNT_TC1 8 /* First connection: 32 */ -+#define NIC_TX_BUFF_COUNT_TC2 8 /* First connection: 0 */ -+#define NIC_TX_BUFF_COUNT_TC3 8 /* First connection: 0 */ -+#define NIC_TX_BUFF_COUNT_TC4 4 /* First connection: 2 */ -+#define NIC_TX_BUFF_COUNT_TC5 2 /* First connection: 0 */ -+#endif -+#elif defined(MT6628) -+#if (CFG_SRAM_SIZE_OPTION == 0) -+#define NIC_TX_BUFF_COUNT_TC0 1 /* First connection: 0 */ -+#define NIC_TX_BUFF_COUNT_TC1 20 /* First connection: 32 */ -+#define NIC_TX_BUFF_COUNT_TC2 1 /* First connection: 0 */ -+#define NIC_TX_BUFF_COUNT_TC3 1 /* First connection: 0 */ -+#define NIC_TX_BUFF_COUNT_TC4 4 /* First connection: 2 */ -+#define NIC_TX_BUFF_COUNT_TC5 1 /* First connection: 0 */ -+#elif (CFG_SRAM_SIZE_OPTION == 1) -+#define NIC_TX_BUFF_COUNT_TC0 1 /* First connection: 0 */ -+#define NIC_TX_BUFF_COUNT_TC1 36 /* First connection: 32 */ -+#define NIC_TX_BUFF_COUNT_TC2 1 /* First connection: 0 */ -+#define NIC_TX_BUFF_COUNT_TC3 1 /* First connection: 0 */ -+#define NIC_TX_BUFF_COUNT_TC4 4 /* First connection: 2 */ -+#define NIC_TX_BUFF_COUNT_TC5 1 /* First connection: 0 */ -+#elif (CFG_SRAM_SIZE_OPTION == 2) -+#define NIC_TX_BUFF_COUNT_TC0 1 /* First connection: 0 */ -+#define NIC_TX_BUFF_COUNT_TC1 48 /* First connection: 32 */ -+#define NIC_TX_BUFF_COUNT_TC2 1 /* First connection: 0 */ -+#define NIC_TX_BUFF_COUNT_TC3 1 /* First connection: 0 */ -+#define NIC_TX_BUFF_COUNT_TC4 4 /* First connection: 2 */ -+#define NIC_TX_BUFF_COUNT_TC5 1 /* First connection: 0 */ -+#else -+#error "> Set TX_BUFF_COUNT_TC error!" -+#endif -+#endif -+ -+#define NIC_TX_BUFF_SUM (NIC_TX_BUFF_COUNT_TC0 + \ -+ NIC_TX_BUFF_COUNT_TC1 + \ -+ NIC_TX_BUFF_COUNT_TC2 + \ -+ NIC_TX_BUFF_COUNT_TC3 + \ -+ NIC_TX_BUFF_COUNT_TC4 + \ -+ NIC_TX_BUFF_COUNT_TC5) -+#if CFG_ENABLE_FW_DOWNLOAD -+ -+#define NIC_TX_INIT_BUFF_COUNT_TC0 8 -+#define NIC_TX_INIT_BUFF_COUNT_TC1 0 -+#define NIC_TX_INIT_BUFF_COUNT_TC2 0 -+#define NIC_TX_INIT_BUFF_COUNT_TC3 0 -+#define NIC_TX_INIT_BUFF_COUNT_TC4 0 -+#define NIC_TX_INIT_BUFF_COUNT_TC5 0 -+ -+#define NIC_TX_INIT_BUFF_SUM (NIC_TX_INIT_BUFF_COUNT_TC0 + \ -+ NIC_TX_INIT_BUFF_COUNT_TC1 + \ -+ NIC_TX_INIT_BUFF_COUNT_TC2 + \ -+ NIC_TX_INIT_BUFF_COUNT_TC3 + \ -+ NIC_TX_INIT_BUFF_COUNT_TC4 + \ -+ NIC_TX_INIT_BUFF_COUNT_TC5) -+ -+#endif -+ -+#if CFG_ENABLE_PKT_LIFETIME_PROFILE -+#define NIC_TX_TIME_THRESHOLD 100 /* in unit of ms */ -+#endif -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+/* 3 Session for TX QUEUES */ -+/* The definition in this ENUM is used to categorize packet's Traffic Class according -+ * to the their TID(User Priority). -+ * In order to achieve QoS goal, a particular TC should not block the process of -+ * another packet with different TC. -+ * In current design we will have 5 categories(TCs) of SW resource. -+ */ -+typedef enum _ENUM_TRAFFIC_CLASS_INDEX_T { -+ TC0_INDEX = 0, /* HIF TX0: AC0 packets */ -+ TC1_INDEX, /* HIF TX0: AC1 packets & non-QoS packets */ -+ TC2_INDEX, /* HIF TX0: AC2 packets */ -+ TC3_INDEX, /* HIF TX0: AC3 packets */ -+ TC4_INDEX, /* HIF TX1: Command packets or 802.1x packets */ -+ TC5_INDEX, /* HIF TX0: BMCAST packets */ -+ TC_NUM /* Maximum number of Traffic Classes. */ -+} ENUM_TRAFFIC_CLASS_INDEX_T; -+ -+typedef enum _ENUM_TX_STATISTIC_COUNTER_T { -+ TX_MPDU_TOTAL_COUNT = 0, -+ TX_INACTIVE_BSS_DROP, -+ TX_INACTIVE_STA_DROP, -+ TX_FORWARD_OVERFLOW_DROP, -+ TX_AP_BORADCAST_DROP, -+ TX_STATISTIC_COUNTER_NUM -+} ENUM_TX_STATISTIC_COUNTER_T; -+ -+typedef struct _TX_TCQ_STATUS_T { -+ UINT_8 aucFreeBufferCount[TC_NUM]; -+ UINT_8 aucMaxNumOfBuffer[TC_NUM]; -+} TX_TCQ_STATUS_T, *P_TX_TCQ_STATUS_T; -+ -+typedef struct _TX_TCQ_ADJUST_T { -+ INT_8 acVariation[TC_NUM]; -+} TX_TCQ_ADJUST_T, *P_TX_TCQ_ADJUST_T; -+ -+typedef struct _TX_CTRL_T { -+ UINT_32 u4TxCachedSize; -+ PUINT_8 pucTxCached; -+ -+/* Elements below is classified according to TC (Traffic Class) value. */ -+ -+ TX_TCQ_STATUS_T rTc; -+ -+ PUINT_8 pucTxCoalescingBufPtr; -+ -+ QUE_T rFreeMsduInfoList; -+ -+ /* Management Frame Tracking */ -+ /* number of management frames to be sent */ -+ INT_32 i4TxMgmtPendingNum; -+ -+ /* to tracking management frames need TX done callback */ -+ QUE_T rTxMgmtTxingQueue; -+ -+#if CFG_HIF_STATISTICS -+ UINT_32 u4TotalTxAccessNum; -+ UINT_32 u4TotalTxPacketNum; -+#endif -+ UINT_32 au4Statistics[TX_STATISTIC_COUNTER_NUM]; -+ -+ /* Number to track forwarding frames */ -+ INT_32 i4PendingFwdFrameCount; -+ -+} TX_CTRL_T, *P_TX_CTRL_T; -+ -+typedef enum _ENUM_TX_PACKET_SRC_T { -+ TX_PACKET_OS, -+ TX_PACKET_OS_OID, -+ TX_PACKET_FORWARDING, -+ TX_PACKET_MGMT, -+ TX_PACKET_NUM -+} ENUM_TX_PACKET_SRC_T; -+ -+typedef enum _ENUM_HIF_TX_PACKET_TYPE_T { -+ HIF_TX_PACKET_TYPE_DATA = 0, -+ HIF_TX_PACKET_TYPE_COMMAND, -+ HIF_TX_PACKET_TYPE_HIF_LB, -+ HIF_TX_PACKET_TYPE_MGMT -+} ENUM_HIF_TX_PACKET_TYPE_T, *P_ENUM_HIF_TX_PACKET_TYPE_T; -+ -+typedef enum _ENUM_TX_RESULT_CODE_T { -+ TX_RESULT_SUCCESS = 0, -+ TX_RESULT_LIFE_TIMEOUT, -+ TX_RESULT_RTS_ERROR, -+ TX_RESULT_MPDU_ERROR, -+ TX_RESULT_AGING_TIMEOUT, -+ TX_RESULT_FLUSHED, -+ TX_RESULT_DROPPED_IN_DRIVER = 32, -+ TX_RESULT_NUM -+} ENUM_TX_RESULT_CODE_T, *P_ENUM_TX_RESULT_CODE_T; -+ -+struct _WLAN_CFG_ENTRY_T { -+ UINT_8 aucKey[WLAN_CFG_KEY_LEN_MAX]; -+ UINT_8 aucValue[WLAN_CFG_VALUE_LEN_MAX]; -+ WLAN_CFG_SET_CB pfSetCb; -+ PVOID pPrivate; -+ UINT_32 u4Flags; -+}; -+ -+struct _WLAN_CFG_T { -+ UINT_32 u4WlanCfgEntryNumMax; -+ UINT_32 u4WlanCfgKeyLenMax; -+ UINT_32 u4WlanCfgValueLenMax; -+ WLAN_CFG_ENTRY_T arWlanCfgBuf[WLAN_CFG_ENTRY_NUM_MAX]; -+}; -+ -+/* TX Call Back Function */ -+typedef WLAN_STATUS(*PFN_TX_DONE_HANDLER) (IN P_ADAPTER_T prAdapter, -+ IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus); -+ -+#if CFG_ENABLE_PKT_LIFETIME_PROFILE -+typedef struct _PKT_PROFILE_T { -+ BOOLEAN fgIsValid; -+#if CFG_PRINT_RTP_PROFILE -+ BOOLEAN fgIsPrinted; -+ UINT_16 u2IpSn; -+ UINT_16 u2RtpSn; -+ UINT_8 ucTcxFreeCount; -+#endif -+ OS_SYSTIME rHardXmitArrivalTimestamp; -+ OS_SYSTIME rEnqueueTimestamp; -+ OS_SYSTIME rDequeueTimestamp; -+ OS_SYSTIME rHifTxDoneTimestamp; -+} PKT_PROFILE_T, *P_PKT_PROFILE_T; -+#endif -+ -+/* TX transactions could be divided into 4 kinds: -+ * -+ * 1) 802.1X / Bluetooth-over-Wi-Fi Security Frames -+ * [CMD_INFO_T] - [prPacket] - in skb or NDIS_PACKET form -+ * -+ * 2) MMPDU -+ * [CMD_INFO_T] - [prPacket] - [MSDU_INFO_T] - [prPacket] - direct buffer for frame body -+ * -+ * 3) Command Packets -+ * [CMD_INFO_T] - [pucInfoBuffer] - direct buffer for content of command packet -+ * -+ * 4) Normal data frame -+ * [MSDU_INFO_T] - [prPacket] - in skb or NDIS_PACKET form -+ */ -+ -+/* PS_FORWARDING_TYPE_NON_PS means that the receiving STA is in Active Mode -+* from the perspective of host driver (maybe not synchronized with FW --> SN is needed) -+*/ -+ -+struct _MSDU_INFO_T { -+ QUE_ENTRY_T rQueEntry; -+ P_NATIVE_PACKET prPacket; -+ -+ ENUM_TX_PACKET_SRC_T eSrc; /* specify OS/FORWARD packet */ -+ UINT_8 ucUserPriority; -+ -+ /* For composing HIF TX header */ -+ UINT_8 ucTC; /* Traffic Class: 0~4 (HIF TX0), 5 (HIF TX1) */ -+ UINT_8 ucPacketType; /* 0: Data, 1: Command, 2: HIF Loopback 3: Management Frame */ -+ UINT_8 ucStaRecIndex; -+ UINT_8 ucNetworkType; /* See ENUM_NETWORK_TYPE_T */ -+ UINT_8 ucFormatID; /* 0: MAUI, Linux, Windows NDIS 5.1 */ -+ BOOLEAN fgIs802_1x; /* TRUE: 802.1x frame */ -+ BOOLEAN fgIs802_11; /* TRUE: 802.11 header is present */ -+ UINT_16 u2PalLLH; /* PAL Logical Link Header (for BOW network) */ -+ UINT_16 u2AclSN; /* ACL Sequence Number (for BOW network) */ -+ UINT_8 ucPsForwardingType; /* See ENUM_PS_FORWARDING_TYPE_T */ -+ UINT_8 ucPsSessionID; /* PS Session ID specified by the FW for the STA */ -+ BOOLEAN fgIsBurstEnd; /* TRUE means this is the last packet of the burst for (STA, TID) */ -+ BOOLEAN fgIsBIP; /* Management Frame Protection */ -+ BOOLEAN fgIsBasicRate; /* Force Basic Rate Transmission */ -+ -+ /* flattened from PACKET_INFO_T */ -+ UINT_8 ucMacHeaderLength; -+ UINT_8 ucLlcLength; /* w/o EtherType */ -+ UINT_16 u2FrameLength; -+ UINT_8 aucEthDestAddr[MAC_ADDR_LEN]; /* Ethernet Destination Address */ -+ -+ /* for TX done tracking */ -+ UINT_8 ucTxSeqNum; -+ PFN_TX_DONE_HANDLER pfTxDoneHandler; -+ BOOLEAN fgNeedTxDoneStatus; -+ -+#if CFG_ENABLE_PKT_LIFETIME_PROFILE -+ PKT_PROFILE_T rPktProfile; -+#endif -+ COMMAND_TYPE eCmdType; -+ UINT_8 ucCID; -+ UINT_32 u4InqueTime; -+}; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+#define TX_INC_CNT(prTxCtrl, eCounter) \ -+ {((P_TX_CTRL_T)prTxCtrl)->au4Statistics[eCounter]++; } -+ -+#define TX_ADD_CNT(prTxCtrl, eCounter, u8Amount) \ -+ {((P_TX_CTRL_T)prTxCtrl)->au4Statistics[eCounter] += (UINT_32)u8Amount; } -+ -+#define TX_GET_CNT(prTxCtrl, eCounter) \ -+ (((P_TX_CTRL_T)prTxCtrl)->au4Statistics[eCounter]) -+ -+#define TX_RESET_ALL_CNTS(prTxCtrl) \ -+ {kalMemZero(&prTxCtrl->au4Statistics[0], sizeof(prTxCtrl->au4Statistics)); } -+ -+#if CFG_ENABLE_PKT_LIFETIME_PROFILE -+#define PRINT_PKT_PROFILE(_pkt_profile, _note) \ -+{ \ -+ if (!(_pkt_profile)->fgIsPrinted) { \ -+ DBGLOG(TX, TRACE, "X[%u] E[%u] D[%u] HD[%u] B[%d] RTP[%d] %s\n", \ -+ (UINT_32)((_pkt_profile)->rHardXmitArrivalTimestamp), \ -+ (UINT_32)((_pkt_profile)->rEnqueueTimestamp), \ -+ (UINT_32)((_pkt_profile)->rDequeueTimestamp), \ -+ (UINT_32)((_pkt_profile)->rHifTxDoneTimestamp), \ -+ (UINT_8)((_pkt_profile)->ucTcxFreeCount), \ -+ (UINT_16)((_pkt_profile)->u2RtpSn), \ -+ (_note)); \ -+ (_pkt_profile)->fgIsPrinted = TRUE; \ -+ } \ -+} -+ -+#define CHK_PROFILES_DELTA(_pkt1, _pkt2, _delta) \ -+ (CHECK_FOR_TIMEOUT((_pkt1)->rHardXmitArrivalTimestamp, (_pkt2)->rHardXmitArrivalTimestamp, (_delta)) || \ -+ CHECK_FOR_TIMEOUT((_pkt1)->rEnqueueTimestamp, (_pkt2)->rEnqueueTimestamp, (_delta)) || \ -+ CHECK_FOR_TIMEOUT((_pkt1)->rDequeueTimestamp, (_pkt2)->rDequeueTimestamp, (_delta)) || \ -+ CHECK_FOR_TIMEOUT((_pkt1)->rHifTxDoneTimestamp, (_pkt2)->rHifTxDoneTimestamp, (_delta))) -+ -+#define CHK_PROFILE_DELTA(_pkt, _delta) \ -+ (CHECK_FOR_TIMEOUT((_pkt)->rEnqueueTimestamp, (_pkt)->rHardXmitArrivalTimestamp, (_delta)) || \ -+ CHECK_FOR_TIMEOUT((_pkt)->rDequeueTimestamp, (_pkt)->rEnqueueTimestamp, (_delta)) || \ -+ CHECK_FOR_TIMEOUT((_pkt)->rHifTxDoneTimestamp, (_pkt)->rDequeueTimestamp, (_delta))) -+#endif -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+VOID nicTxInitialize(IN P_ADAPTER_T prAdapter); -+ -+WLAN_STATUS nicTxAcquireResource(IN P_ADAPTER_T prAdapter, IN UINT_8 ucTC, IN BOOLEAN pfgIsSecOrMgmt); -+ -+WLAN_STATUS nicTxPollingResource(IN P_ADAPTER_T prAdapter, IN UINT_8 ucTC); -+ -+BOOLEAN nicTxReleaseResource(IN P_ADAPTER_T prAdapter, IN UINT_8 *aucTxRlsCnt); -+ -+WLAN_STATUS nicTxResetResource(IN P_ADAPTER_T prAdapter); -+ -+UINT_8 nicTxGetResource(IN P_ADAPTER_T prAdapter, IN UINT_8 ucTC); -+ -+WLAN_STATUS nicTxMsduInfoList(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfoListHead); -+ -+WLAN_STATUS nicTxMsduQueue(IN P_ADAPTER_T prAdapter, UINT_8 ucPortIdx, P_QUE_T prQue); -+ -+WLAN_STATUS nicTxCmd(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN UINT_8 ucTC); -+ -+VOID nicTxRelease(IN P_ADAPTER_T prAdapter); -+ -+VOID nicProcessTxInterrupt(IN P_ADAPTER_T prAdapter); -+ -+VOID nicTxFreeMsduInfoPacket(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfoListHead); -+ -+VOID nicTxReturnMsduInfo(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfoListHead); -+ -+BOOLEAN nicTxFillMsduInfo(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo, IN P_NATIVE_PACKET prNdisPacket); -+ -+WLAN_STATUS nicTxAdjustTcq(IN P_ADAPTER_T prAdapter); -+ -+WLAN_STATUS nicTxFlush(IN P_ADAPTER_T prAdapter); -+ -+#if CFG_ENABLE_FW_DOWNLOAD -+WLAN_STATUS nicTxInitCmd(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN UINT_8 ucTC); -+ -+WLAN_STATUS nicTxInitResetResource(IN P_ADAPTER_T prAdapter); -+#endif -+ -+WLAN_STATUS nicTxEnqueueMsdu(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); -+ -+UINT_32 nicTxGetFreeCmdCount(IN P_ADAPTER_T prAdapter); -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif /* _NIC_TX_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/p2p.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/p2p.h -new file mode 100644 -index 000000000000..d518aaf10eb5 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/p2p.h -@@ -0,0 +1,192 @@ -+/* -+** Id: //Department/DaVinci/TRUNK/WiFi_P2P_Driver/include/nic/p2p.h#3 -+*/ -+ -+/* -+** Log: p2p.h -+ * -+ * 07 17 2012 yuche.tsai -+ * NULL -+ * Compile no error before trial run. -+ * -+ * 10 20 2010 wh.su -+ * [WCXRP00000124] [MT6620 Wi-Fi] [Driver] Support the dissolve P2P Group -+ * Add the code to support disconnect p2p group -+ * -+ * 09 21 2010 kevin.huang -+ * [WCXRP00000054] [MT6620 Wi-Fi][Driver] Restructure driver for second Interface -+ * Isolate P2P related function for Hardware Software Bundle -+ * -+ * 08 03 2010 cp.wu -+ * NULL -+ * [Wi-Fi Direct] add framework for driver hooks -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 23 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * p2p interface revised to be sync. with HAL -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 05 18 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * add parameter to control: -+ * 1) auto group owner -+ * 2) P2P-PS parameter (CTWindow, NoA descriptors) -+ * -+ * 05 18 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * correct WPS Device Password ID definition. -+ * -+ * 05 17 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * implement get scan result. -+ * -+ * 05 17 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * add basic handling framework for wireless extension ioctls. -+ * -+ * 05 14 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * add ioctl framework for Wi-Fi Direct by reusing wireless extension ioctls as well -+ * -+ * 05 11 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * p2p ioctls revised. -+ * -+ * 05 10 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * implement basic wi-fi direct framework -+ * -+ * 05 07 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * add basic framework for implementating P2P driver hook. -+ * -+ * -+*/ -+ -+#ifndef _P2P_H -+#define _P2P_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/* refer to 'Config Methods' in WPS */ -+#define WPS_CONFIG_USBA 0x0001 -+#define WPS_CONFIG_ETHERNET 0x0002 -+#define WPS_CONFIG_LABEL 0x0004 -+#define WPS_CONFIG_DISPLAY 0x0008 -+#define WPS_CONFIG_EXT_NFC 0x0010 -+#define WPS_CONFIG_INT_NFC 0x0020 -+#define WPS_CONFIG_NFC 0x0040 -+#define WPS_CONFIG_PBC 0x0080 -+#define WPS_CONFIG_KEYPAD 0x0100 -+ -+/* refer to 'Device Password ID' in WPS */ -+#define WPS_DEV_PASSWORD_ID_PIN 0x0000 -+#define WPS_DEV_PASSWORD_ID_USER 0x0001 -+#define WPS_DEV_PASSWORD_ID_MACHINE 0x0002 -+#define WPS_DEV_PASSWORD_ID_REKEY 0x0003 -+#define WPS_DEV_PASSWORD_ID_PUSHBUTTON 0x0004 -+#define WPS_DEV_PASSWORD_ID_REGISTRAR 0x0005 -+ -+#define P2P_DEVICE_TYPE_NUM 2 -+#define P2P_DEVICE_NAME_LENGTH 32 -+#define P2P_NETWORK_NUM 8 -+#define P2P_MEMBER_NUM 8 -+ -+#define P2P_WILDCARD_SSID "DIRECT-" -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+struct _P2P_INFO_T { -+ UINT_32 u4DeviceNum; -+ EVENT_P2P_DEV_DISCOVER_RESULT_T arP2pDiscoverResult[CFG_MAX_NUM_BSS_LIST]; -+ PUINT_8 pucCurrIePtr; -+ UINT_8 aucCommIePool[CFG_MAX_COMMON_IE_BUF_LEN]; /* A common pool for IE of all scan results. */ -+}; -+ -+typedef enum { -+ ENUM_P2P_PEER_GROUP, -+ ENUM_P2P_PEER_DEVICE, -+ ENUM_P2P_PEER_NUM -+} ENUM_P2P_PEER_TYPE, *P_ENUM_P2P_PEER_TYPE; -+ -+typedef struct _P2P_DEVICE_INFO { -+ UINT_8 aucDevAddr[PARAM_MAC_ADDR_LEN]; -+ UINT_8 aucIfAddr[PARAM_MAC_ADDR_LEN]; -+ UINT_8 ucDevCapabilityBitmap; -+ INT_32 i4ConfigMethod; -+ UINT_8 aucPrimaryDeviceType[8]; -+ UINT_8 aucSecondaryDeviceType[8]; -+ UINT_8 aucDeviceName[P2P_DEVICE_NAME_LENGTH]; -+} P2P_DEVICE_INFO, *P_P2P_DEVICE_INFO; -+ -+typedef struct _P2P_GROUP_INFO { -+ PARAM_SSID_T rGroupID; -+ P2P_DEVICE_INFO rGroupOwnerInfo; -+ UINT_8 ucMemberNum; -+ P2P_DEVICE_INFO arMemberInfo[P2P_MEMBER_NUM]; -+} P2P_GROUP_INFO, *P_P2P_GROUP_INFO; -+ -+typedef struct _P2P_NETWORK_INFO { -+ ENUM_P2P_PEER_TYPE eNodeType; -+ -+ union { -+ P2P_GROUP_INFO rGroupInfo; -+ P2P_DEVICE_INFO rDeviceInfo; -+ } node; -+ -+} P2P_NETWORK_INFO, *P_P2P_NETWORK_INFO; -+ -+typedef struct _P2P_NETWORK_LIST { -+ UINT_8 ucNetworkNum; -+ P2P_NETWORK_INFO rP2PNetworkInfo[P2P_NETWORK_NUM]; -+} P2P_NETWORK_LIST, *P_P2P_NETWORK_LIST; -+ -+typedef struct _P2P_DISCONNECT_INFO { -+ UINT_8 ucRole; -+ UINT_8 ucRsv[3]; -+} P2P_DISCONNECT_INFO, *P_P2P_DISCONNECT_INFO; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+#endif /*_P2P_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/p2p_cmd_buf.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/p2p_cmd_buf.h -new file mode 100644 -index 000000000000..7f7a92584c7c ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/p2p_cmd_buf.h -@@ -0,0 +1,83 @@ -+/* -+** Id: -+*/ -+ -+/*! \file "p2p_cmd_buf.h" -+ \brief In this file we define the structure for Command Packet. -+ -+ In this file we define the structure for Command Packet and the control unit -+ of MGMT Memory Pool. -+*/ -+ -+/* -+** Log: p2p_cmd_buf.h -+ * -+ * 07 17 2012 yuche.tsai -+ * NULL -+ * Compile no error before trial run. -+ * -+ * 12 22 2010 cp.wu -+ * [WCXRP00000283] [MT6620 Wi-Fi][Driver][Wi-Fi Direct] Implementation of interface -+ * for supporting Wi-Fi Direct Service Discovery -+ * 1. header file restructure for more clear module isolation -+ * 2. add function interface definition for implementing Service Discovery callbacks -+*/ -+ -+#ifndef _P2P_CMD_BUF_H -+#define _P2P_CMD_BUF_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/*--------------------------------------------------------------*/ -+/* Firmware Command Packer */ -+/*--------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSendSetQueryP2PCmd(IN P_ADAPTER_T prAdapter, -+ UINT_8 ucCID, -+ BOOLEAN fgSetQuery, -+ BOOLEAN fgNeedResp, -+ BOOLEAN fgIsOid, -+ PFN_CMD_DONE_HANDLER pfCmdDoneHandler, -+ PFN_CMD_TIMEOUT_HANDLER pfCmdTimeoutHandler, -+ UINT_32 u4SetQueryInfoLen, -+ PUINT_8 pucInfoBuffer, OUT PVOID pvSetQueryBuffer, IN UINT_32 u4SetQueryBufferLen); -+ -+#endif /* _P2P_CMD_BUF_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/p2p_mac.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/p2p_mac.h -new file mode 100644 -index 000000000000..76115dabe1a1 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/p2p_mac.h -@@ -0,0 +1,207 @@ -+/* -+** Id: //Department/DaVinci/TRUNK/WiFi_P2P_Driver/include/nic/p2p_mac.h#2 -+*/ -+ -+/*! \file "p2p_mac.h" -+ \brief Brief description. -+ -+ Detail description. -+*/ -+ -+#ifndef _P2P_MAC_H -+#define _P2P_MAC_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+#define ACTION_PUBLIC_WIFI_DIRECT 9 -+#define ACTION_GAS_INITIAL_REQUEST 10 -+#define ACTION_GAS_INITIAL_RESPONSE 11 -+#define ACTION_GAS_COMEBACK_REQUEST 12 -+#define ACTION_GAS_COMEBACK_RESPONSE 13 -+ -+/* P2P 4.2.8.1 - P2P Public Action Frame Type. */ -+#define P2P_PUBLIC_ACTION_GO_NEGO_REQ 0 -+#define P2P_PUBLIC_ACTION_GO_NEGO_RSP 1 -+#define P2P_PUBLIC_ACTION_GO_NEGO_CFM 2 -+#define P2P_PUBLIC_ACTION_INVITATION_REQ 3 -+#define P2P_PUBLIC_ACTION_INVITATION_RSP 4 -+#define P2P_PUBLIC_ACTION_DEV_DISCOVER_REQ 5 -+#define P2P_PUBLIC_ACTION_DEV_DISCOVER_RSP 6 -+#define P2P_PUBLIC_ACTION_PROV_DISCOVERY_REQ 7 -+#define P2P_PUBLIC_ACTION_PROV_DISCOVERY_RSP 8 -+ -+/* P2P 4.2.9.1 - P2P Action Frame Type */ -+#define P2P_ACTION_NOTICE_OF_ABSENCE 0 -+#define P2P_ACTION_P2P_PRESENCE_REQ 1 -+#define P2P_ACTION_P2P_PRESENCE_RSP 2 -+#define P2P_ACTION_GO_DISCOVER_REQ 3 -+ -+#define P2P_PUBLIC_ACTION_FRAME_LEN (WLAN_MAC_MGMT_HEADER_LEN+8) -+#define P2P_ACTION_FRAME_LEN (WLAN_MAC_MGMT_HEADER_LEN+7) -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/* P2P 4.2.8.2 P2P Public Action Frame Format */ -+typedef struct _P2P_PUBLIC_ACTION_FRAME_T { -+ /* MAC header */ -+ UINT_16 u2FrameCtrl; /* Frame Control */ -+ UINT_16 u2Duration; /* Duration */ -+ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ -+ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ -+ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ -+ UINT_16 u2SeqCtrl; /* Sequence Control */ -+ /* P2P Public Action Frame Body */ -+ UINT_8 ucCategory; /* Category, 0x04 */ -+ UINT_8 ucAction; /* Action Value, 0x09 */ -+ UINT_8 aucOui[3]; /* 0x50, 0x6F, 0x9A */ -+ UINT_8 ucOuiType; /* 0x09 */ -+ UINT_8 ucOuiSubtype; /* GO Nego Req/Rsp/Cfm, P2P Invittion Req/Rsp, Device Discoverability Req/Rsp */ -+ UINT_8 ucDialogToken; /* Dialog Token. */ -+ UINT_8 aucInfoElem[1]; /* P2P IE, WSC IE. */ -+} __KAL_ATTRIB_PACKED__ P2P_PUBLIC_ACTION_FRAME_T, *P_P2P_PUBLIC_ACTION_FRAME_T; -+ -+/* P2P 4.2.9.1 - General Action Frame Format. */ -+typedef struct _P2P_ACTION_FRAME_T { -+ /* MAC header */ -+ UINT_16 u2FrameCtrl; /* Frame Control */ -+ UINT_16 u2Duration; /* Duration */ -+ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ -+ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ -+ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ -+ UINT_16 u2SeqCtrl; /* Sequence Control */ -+ /* P2P Action Frame Body */ -+ UINT_8 ucCategory; /* 0x7F */ -+ UINT_8 aucOui[3]; /* 0x50, 0x6F, 0x9A */ -+ UINT_8 ucOuiType; /* 0x09 */ -+ UINT_8 ucOuiSubtype; /* */ -+ UINT_8 ucDialogToken; -+ UINT_8 aucInfoElem[1]; -+} __KAL_ATTRIB_PACKED__ P2P_ACTION_FRAME_T, *P_P2P_ACTION_FRAME_T; -+ -+/* P2P C.1 GAS Public Action Initial Request Frame Format */ -+typedef struct _GAS_PUBLIC_ACTION_INITIAL_REQUEST_FRAME_T { -+ /* MAC header */ -+ UINT_16 u2FrameCtrl; /* Frame Control */ -+ UINT_16 u2Duration; /* Duration */ -+ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ -+ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ -+ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ -+ UINT_16 u2SeqCtrl; /* Sequence Control */ -+ /* P2P Public Action Frame Body */ -+ UINT_8 ucCategory; /* Category, 0x04 */ -+ UINT_8 ucAction; /* Action Value, 0x09 */ -+ UINT_8 ucDialogToken; /* Dialog Token. */ -+ UINT_8 aucInfoElem[1]; /* Advertisement IE. */ -+} __KAL_ATTRIB_PACKED__ GAS_PUBLIC_ACTION_INITIAL_REQUEST_FRAME_T, *P_GAS_PUBLIC_ACTION_INITIAL_REQUEST_FRAME_T; -+ -+/* P2P C.2 GAS Public Action Initial Response Frame Format */ -+typedef struct _GAS_PUBLIC_ACTION_INITIAL_RESPONSE_FRAME_T { -+ /* MAC header */ -+ UINT_16 u2FrameCtrl; /* Frame Control */ -+ UINT_16 u2Duration; /* Duration */ -+ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ -+ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ -+ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ -+ UINT_16 u2SeqCtrl; /* Sequence Control */ -+ /* P2P Public Action Frame Body */ -+ UINT_8 ucCategory; /* Category, 0x04 */ -+ UINT_8 ucAction; /* Action Value, 0x09 */ -+ UINT_8 ucDialogToken; /* Dialog Token. */ -+ UINT_16 u2StatusCode; /* Initial Response. */ -+ UINT_16 u2ComebackDelay; /* Initial Response. *//* In unit of TU. */ -+ UINT_8 aucInfoElem[1]; /* Advertisement IE. */ -+} __KAL_ATTRIB_PACKED__ GAS_PUBLIC_ACTION_INITIAL_RESPONSE_FRAME_T, *P_GAS_PUBLIC_ACTION_INITIAL_RESPONSE_FRAME_T; -+ -+/* P2P C.3-1 GAS Public Action Comeback Request Frame Format */ -+typedef struct _GAS_PUBLIC_ACTION_COMEBACK_REQUEST_FRAME_T { -+ /* MAC header */ -+ UINT_16 u2FrameCtrl; /* Frame Control */ -+ UINT_16 u2Duration; /* Duration */ -+ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ -+ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ -+ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ -+ UINT_16 u2SeqCtrl; /* Sequence Control */ -+ /* P2P Public Action Frame Body */ -+ UINT_8 ucCategory; /* Category, 0x04 */ -+ UINT_8 ucAction; /* Action Value, 0x09 */ -+ UINT_8 ucDialogToken; /* Dialog Token. */ -+} __KAL_ATTRIB_PACKED__ GAS_PUBLIC_ACTION_COMEBACK_REQUEST_FRAME_T, *P_GAS_PUBLIC_ACTION_COMEBACK_REQUEST_FRAME_T; -+ -+/* P2P C.3-2 GAS Public Action Comeback Response Frame Format */ -+typedef struct _GAS_PUBLIC_ACTION_COMEBACK_RESPONSE_FRAME_T { -+ /* MAC header */ -+ UINT_16 u2FrameCtrl; /* Frame Control */ -+ UINT_16 u2Duration; /* Duration */ -+ UINT_8 aucDestAddr[MAC_ADDR_LEN]; /* DA */ -+ UINT_8 aucSrcAddr[MAC_ADDR_LEN]; /* SA */ -+ UINT_8 aucBSSID[MAC_ADDR_LEN]; /* BSSID */ -+ UINT_16 u2SeqCtrl; /* Sequence Control */ -+ /* P2P Public Action Frame Body */ -+ UINT_8 ucCategory; /* Category, 0x04 */ -+ UINT_8 ucAction; /* Action Value, 0x09 */ -+ UINT_8 ucDialogToken; /* Dialog Token. */ -+ UINT_16 u2StatusCode; /* Comeback Response. */ -+ UINT_8 ucFragmentID; /*Comeback Response. */ -+ UINT_16 u2ComebackDelay; /* Comeback Response. */ -+ UINT_8 aucInfoElem[1]; /* Advertisement IE. */ -+} __KAL_ATTRIB_PACKED__ GAS_PUBLIC_ACTION_COMEBACK_RESPONSE_FRAME_T, *P_GAS_PUBLIC_ACTION_COMEBACK_RESPONSE_FRAME_T; -+ -+typedef struct _P2P_SD_VENDER_SPECIFIC_CONTENT_T { -+ /* Service Discovery Vendor-specific Content. */ -+ UINT_8 ucOuiSubtype; /* 0x09 */ -+ UINT_16 u2ServiceUpdateIndicator; -+ UINT_8 aucServiceTLV[1]; -+} __KAL_ATTRIB_PACKED__ P2P_SD_VENDER_SPECIFIC_CONTENT_T, *P_P2P_SD_VENDER_SPECIFIC_CONTENT_T; -+ -+typedef struct _P2P_SERVICE_REQUEST_TLV_T { -+ UINT_16 u2Length; -+ UINT_8 ucServiceProtocolType; -+ UINT_8 ucServiceTransID; -+ UINT_8 aucQueryData[1]; -+} __KAL_ATTRIB_PACKED__ P2P_SERVICE_REQUEST_TLV_T, *P_P2P_SERVICE_REQUEST_TLV_T; -+ -+typedef struct _P2P_SERVICE_RESPONSE_TLV_T { -+ UINT_16 u2Length; -+ UINT_8 ucServiceProtocolType; -+ UINT_8 ucServiceTransID; -+ UINT_8 ucStatusCode; -+ UINT_8 aucResponseData[1]; -+} __KAL_ATTRIB_PACKED__ P2P_SERVICE_RESPONSE_TLV_T, *P_P2P_SERVICE_RESPONSE_TLV_T; -+ -+#endif -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/p2p_nic.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/p2p_nic.h -new file mode 100644 -index 000000000000..0a87bd457a92 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/p2p_nic.h -@@ -0,0 +1,62 @@ -+/* -+** Id: //Department/DaVinci/TRUNK/WiFi_P2P_Driver/include/nic/p2p_nic.h#1 -+*/ -+ -+/*! \file "p2p_nic.h" -+ \brief The declaration of nic functions -+ -+ Detail description. -+*/ -+ -+#ifndef _P2P_NIC_H -+#define _P2P_NIC_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+VOID -+nicP2pMediaStateChange(IN P_ADAPTER_T prAdapter, -+ IN ENUM_NETWORK_TYPE_INDEX_T eNetworkType, IN P_EVENT_CONNECTION_STATUS prConnectionStatus); -+ -+VOID -+nicRxAddP2pDevice(IN P_ADAPTER_T prAdapter, -+ IN P_EVENT_P2P_DEV_DISCOVER_RESULT_T prP2pResult, IN PUINT_8 pucRxIEBuf, IN UINT_16 u2RxIELength); -+ -+#endif -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/p2p_nic_cmd_event.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/p2p_nic_cmd_event.h -new file mode 100644 -index 000000000000..cea77414ce35 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/p2p_nic_cmd_event.h -@@ -0,0 +1,70 @@ -+/* -+** Id: //Department/DaVinci/TRUNK/WiFi_P2P_Driver/include/nic/p2p_nic_cmd_event.h#1 -+*/ -+ -+/*! \file p2p_nic_cmd_event.h -+ \brief -+*/ -+ -+#ifndef _P2P_NIC_CMD_EVENT_H -+#define _P2P_NIC_CMD_EVENT_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+typedef struct _EVENT_P2P_DEV_DISCOVER_RESULT_T { -+/* UINT_8 aucCommunicateAddr[MAC_ADDR_LEN]; // Deprecated. */ -+ UINT_8 aucDeviceAddr[MAC_ADDR_LEN]; /* Device Address. */ -+ UINT_8 aucInterfaceAddr[MAC_ADDR_LEN]; /* Device Address. */ -+ UINT_8 ucDeviceCapabilityBitmap; -+ UINT_8 ucGroupCapabilityBitmap; -+ UINT_16 u2ConfigMethod; /* Configure Method. */ -+ P2P_DEVICE_TYPE_T rPriDevType; -+ UINT_8 ucSecDevTypeNum; -+ P2P_DEVICE_TYPE_T arSecDevType[2]; -+ UINT_16 u2NameLength; -+ UINT_8 aucName[32]; -+ PUINT_8 pucIeBuf; -+ UINT_16 u2IELength; -+ UINT_8 aucBSSID[MAC_ADDR_LEN]; -+ /* TODO: Service Information or PasswordID valid? */ -+} EVENT_P2P_DEV_DISCOVER_RESULT_T, *P_EVENT_P2P_DEV_DISCOVER_RESULT_T; -+ -+#endif -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/que_mgt.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/que_mgt.h -new file mode 100644 -index 000000000000..dbfb90d94ee4 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/que_mgt.h -@@ -0,0 +1,971 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/nic/que_mgt.h#1 -+*/ -+ -+/*! \file "que_mgt.h" -+ \brief TX/RX queues management header file -+ -+ The main tasks of queue management include TC-based HIF TX flow control, -+ adaptive TC quota adjustment, HIF TX grant scheduling, Power-Save -+ forwarding control, RX packet reordering, and RX BA agreement management. -+*/ -+ -+/* -+** Log: que_mgt.h -+ * -+ * 08 15 2011 cp.wu -+ * [WCXRP00000851] [MT6628 Wi-Fi][Driver] Add HIFSYS related definition to driver source tree -+ * add MT6628-specific definitions. -+ * -+ * 07 26 2011 eddie.chen -+ * [WCXRP00000874] [MT5931][DRV] API for query the RX reorder queued packets counter -+ * API for query the RX reorder queued packets counter. -+ * -+ * 06 14 2011 eddie.chen -+ * [WCXRP00000753] [MT5931 Wi-Fi][DRV] Adjust QM for MT5931 -+ * Change the parameter for WMM pass. -+ * -+ * 05 31 2011 eddie.chen -+ * [WCXRP00000753] [MT5931 Wi-Fi][DRV] Adjust QM for MT5931 -+ * Fix the QM quota in MT5931. -+ * -+ * 05 09 2011 eddie.chen -+ * [WCXRP00000709] [MT6620 Wi-Fi][Driver] Check free number before copying broadcast packet -+ * Check free number before copying broadcast packet. -+ * -+ * 04 14 2011 eddie.chen -+ * [WCXRP00000603] [MT6620 Wi-Fi][DRV] Fix Klocwork warning -+ * Check the SW RFB free. Fix the compile warning.. -+ * -+ * 04 08 2011 eddie.chen -+ * [WCXRP00000617] [MT6620 Wi-Fi][DRV/FW] Fix for sigma -+ * Fix for sigma -+ * -+ * 03 28 2011 eddie.chen -+ * [WCXRP00000602] [MT6620 Wi-Fi][DRV] Fix wmm parameters in beacon for BOW -+ * Fix wmm parameters in beacon for BOW. -+ * -+ * 03 15 2011 eddie.chen -+ * [WCXRP00000554] [MT6620 Wi-Fi][DRV] Add sw control debug counter -+ * Add sw debug counter for QM. -+ * -+ * 02 17 2011 eddie.chen -+ * [WCXRP00000458] [MT6620 Wi-Fi][Driver] BOW Concurrent - ProbeResp was exist in other channel -+ * 1) Change GetFrameAction decision when BSS is absent. -+ * 2) Check channel and resource in processing ProbeRequest -+ * -+ * 01 12 2011 eddie.chen -+ * [WCXRP00000322] Add WMM IE in beacon, -+ -+Add per station flow control when STA is in PS -+ -+ * 1) Check Bss if support QoS before adding WMMIE -+ * 2) Check if support prAdapter->rWifiVar QoS and uapsd in flow control -+ * -+ * 12 29 2010 eddie.chen -+ * [WCXRP00000322] Add WMM IE in beacon, -+ -+Add per station flow control when STA is in PS -+ -+ * 1) PS flow control event -+ * -+ * 2) WMM IE in beacon, assoc resp, probe resp -+ * -+ * 12 23 2010 george.huang -+ * [WCXRP00000152] [MT6620 Wi-Fi] AP mode power saving function -+ * 1. update WMM IE parsing, with ASSOC REQ handling -+ * 2. extend U-APSD parameter passing from driver to FW -+ * -+ * 10 04 2010 cp.wu -+ * [WCXRP00000077] [MT6620 Wi-Fi][Driver][FW] Eliminate use of ENUM_NETWORK_TYPE_T -+ * and replaced by ENUM_NETWORK_TYPE_INDEX_T only remove ENUM_NETWORK_TYPE_T definitions -+ * -+ * 09 21 2010 kevin.huang -+ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning -+ * Eliminate Linux Compile Warning -+ * -+ * 08 04 2010 yarco.yang -+ * NULL -+ * Add TX_AMPDU and ADDBA_REJECT command -+ * -+ * 07 22 2010 george.huang -+ * -+ * Update fgIsQoS information in BSS INFO by CMD -+ * -+ * 07 16 2010 yarco.yang -+ * -+ * 1. Support BSS Absence/Presence Event -+ * 2. Support STA change PS mode Event -+ * 3. Support BMC forwarding for AP mode. -+ * -+ * 07 14 2010 yarco.yang -+ * -+ * 1. Remove CFG_MQM_MIGRATION -+ * 2. Add CMD_UPDATE_WMM_PARMS command -+ * -+ * 07 13 2010 yarco.yang -+ * -+ * [WPD00003849] -+ * [MT6620 and MT5931] SW Migration, add qmGetFrameAction() API for CMD Queue Processing -+ * -+ * 07 09 2010 yarco.yang -+ * -+ * [MT6620 and MT5931] SW Migration: Add ADDBA support -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 29 2010 yarco.yang -+ * [WPD00003837][MT6620]Data Path Refine -+ * replace g_rQM with Adpater->rQM -+ * -+ * 06 25 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add API in que_mgt to retrieve sta-rec index for security frames. -+ * -+ * 06 23 2010 yarco.yang -+ * [WPD00003837][MT6620]Data Path Refine -+ * Merge g_arStaRec[] into adapter->arStaRec[] -+ * -+ * 06 21 2010 yarco.yang -+ * [WPD00003837][MT6620]Data Path Refine -+ * Support CFG_MQM_MIGRATION flag -+ * -+ * 06 18 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Provide cnmMgtPktAlloc() and alloc/free function of msg/buf -+ * -+ * 06 08 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add hem_mbox.c and cnm_mem.h (but disabled some feature) for further migration -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 03 30 2010 tehuang.liu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * Enabled adaptive TC resource control -+ * -+ * 03 24 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * initial import for Linux port -+ * -+ * 03 19 2010 tehuang.liu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * By default enabling dynamic STA_REC activation and decactivation -+ * -+ * 03 17 2010 tehuang.liu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * Changed STA_REC index determination rules (DA=BMCAST always --> STA_REC_INDEX_BMCAST) -+ * -+ * 03 11 2010 tehuang.liu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * Fixed buffer leak when processing BAR frames -+ * -+ * 02 25 2010 tehuang.liu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * Enabled multi-STA TX path with fairness -+ * -+ * 02 24 2010 tehuang.liu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * Enabled dynamically activating and deactivating STA_RECs -+ * -+ * 02 24 2010 tehuang.liu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * Added code for dynamic activating and deactivating STA_RECs. -+ * -+ * 01 13 2010 tehuang.liu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * Enabled the Burst_End Indication mechanism -+** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-12-09 14:04:53 GMT MTK02468 -+** Added RX buffer reordering function prototypes -+** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-12-02 22:08:44 GMT MTK02468 -+** Added macro QM_INIT_STA_REC for initialize a STA_REC -+** \main\maintrunk.MT6620WiFiDriver_Prj\1 2009-11-23 21:58:43 GMT mtk02468 -+** Initial version -+** -+*/ -+ -+#ifndef _QUE_MGT_H -+#define _QUE_MGT_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/* Queue Manager Features */ -+/* 1: Indicate the last TX packet to the FW for each burst */ -+#define QM_BURST_END_INFO_ENABLED 1 -+/* 1: To fairly share TX resource among active STAs */ -+#define QM_FORWARDING_FAIRNESS 1 -+/* 1: To adaptively adjust resource for each TC */ -+#define QM_ADAPTIVE_TC_RESOURCE_CTRL 1 -+/* 1: To print TC resource adjustment results */ -+#define QM_PRINT_TC_RESOURCE_CTRL 0 -+/* 1: If pkt with SSN is missing, auto advance the RX reordering window */ -+#define QM_RX_WIN_SSN_AUTO_ADVANCING 1 -+/* 1: Indicate the packets falling behind to OS before the frame with SSN is received */ -+#define QM_RX_INIT_FALL_BEHIND_PASS 1 -+/* 1: Count times of TC resource empty happened */ -+#define QM_TC_RESOURCE_EMPTY_COUNTER 1 -+/* Parameters */ -+ -+/* -+ In TDLS or AP mode, peer maybe enter "sleep mode". -+ -+ If QM_INIT_TIME_TO_UPDATE_QUE_LEN = 60 when peer is in sleep mode, -+ we need to wait 60 * u4TimeToAdjustTcResource = 180 packets -+ u4TimeToAdjustTcResource = 3, -+ then we will adjust TC resouce for VI or VO. -+ -+ But in TDLS test case, the throughput is very low, only 0.8Mbps in 5.7, -+ we will to wait about 12 seconds to collect 180 packets. -+ but the test time is only 20 seconds. -+*/ -+#define QM_INIT_TIME_TO_UPDATE_QUE_LEN 60 /* p: Update queue lengths when p TX packets are enqueued */ -+#define QM_INIT_TIME_TO_UPDATE_QUE_LEN_MIN 5 -+ -+#define QM_INIT_TIME_TO_ADJUST_TC_RSC 3 /* s: Adjust the TC resource every s updates of queue lengths */ -+#define QM_QUE_LEN_MOVING_AVE_FACTOR 3 /* Factor for Que Len averaging */ -+ -+#define QM_MIN_RESERVED_TC0_RESOURCE 1 -+#define QM_MIN_RESERVED_TC1_RESOURCE 1 -+#define QM_MIN_RESERVED_TC2_RESOURCE 1 -+#define QM_MIN_RESERVED_TC3_RESOURCE 1 -+#define QM_MIN_RESERVED_TC4_RESOURCE 2 /* Resource for TC4 is not adjustable */ -+#define QM_MIN_RESERVED_TC5_RESOURCE 1 -+ -+#if defined(MT6620) -+ -+#define QM_GUARANTEED_TC0_RESOURCE 4 -+#define QM_GUARANTEED_TC1_RESOURCE 4 -+#define QM_GUARANTEED_TC2_RESOURCE 9 -+#define QM_GUARANTEED_TC3_RESOURCE 11 -+#define QM_GUARANTEED_TC4_RESOURCE 2 /* Resource for TC4 is not adjustable */ -+#define QM_GUARANTEED_TC5_RESOURCE 4 -+ -+#elif defined(MT6628) -+ -+#define QM_GUARANTEED_TC0_RESOURCE 4 -+#define QM_GUARANTEED_TC1_RESOURCE 4 -+#define QM_GUARANTEED_TC2_RESOURCE 6 -+#define QM_GUARANTEED_TC3_RESOURCE 6 -+#define QM_GUARANTEED_TC4_RESOURCE 2 /* Resource for TC4 is not adjustable */ -+#define QM_GUARANTEED_TC5_RESOURCE 4 -+ -+#else -+#error -+#endif -+ -+#define QM_EXTRA_RESERVED_RESOURCE_WHEN_BUSY 0 -+ -+#define QM_TOTAL_TC_RESOURCE (\ -+ NIC_TX_BUFF_COUNT_TC0 + NIC_TX_BUFF_COUNT_TC1 +\ -+ NIC_TX_BUFF_COUNT_TC2 + NIC_TX_BUFF_COUNT_TC3 +\ -+ NIC_TX_BUFF_COUNT_TC5) -+#define QM_AVERAGE_TC_RESOURCE 6 -+ -+/* Note: QM_INITIAL_RESIDUAL_TC_RESOURCE shall not be less than 0 */ -+/* for 6628: QM_TOTAL_TC_RESOURCE = 28, RESIDUAL = 4 4 6 6 2 4 = 26 */ -+#define QM_INITIAL_RESIDUAL_TC_RESOURCE (QM_TOTAL_TC_RESOURCE - \ -+ (QM_GUARANTEED_TC0_RESOURCE +\ -+ QM_GUARANTEED_TC1_RESOURCE +\ -+ QM_GUARANTEED_TC2_RESOURCE +\ -+ QM_GUARANTEED_TC3_RESOURCE +\ -+ QM_GUARANTEED_TC5_RESOURCE \ -+ )) -+ -+/* Hard-coded network type for Phase 3: NETWORK_TYPE_AIS/P2P/BOW */ -+#define QM_OPERATING_NETWORK_TYPE NETWORK_TYPE_AIS -+ -+#define QM_TEST_MODE 0 -+#define QM_TEST_TRIGGER_TX_COUNT 50 -+#define QM_TEST_STA_REC_DETERMINATION 0 -+#define QM_TEST_STA_REC_DEACTIVATION 0 -+#define QM_TEST_FAIR_FORWARDING 0 -+ -+#define QM_DEBUG_COUNTER 0 -+ -+/* Per-STA Queues: [0] AC0, [1] AC1, [2] AC2, [3] AC3, [4] 802.1x */ -+/* Per-Type Queues: [0] BMCAST */ -+#define NUM_OF_PER_STA_TX_QUEUES 5 -+#define NUM_OF_PER_TYPE_TX_QUEUES 1 -+ -+/* These two constants are also used for FW to verify the STA_REC index */ -+#define STA_REC_INDEX_BMCAST 0xFF -+#define STA_REC_INDEX_NOT_FOUND 0xFE -+ -+/* TX Queue Index */ -+#define TX_QUEUE_INDEX_BMCAST 0 -+#define TX_QUEUE_INDEX_NO_STA_REC 0 -+#define TX_QUEUE_INDEX_AC0 0 -+#define TX_QUEUE_INDEX_AC1 1 -+#define TX_QUEUE_INDEX_AC2 2 -+#define TX_QUEUE_INDEX_AC3 3 -+#define TX_QUEUE_INDEX_802_1X 4 -+#define TX_QUEUE_INDEX_NON_QOS 1 -+ -+/* 1 WMM-related */ -+/* WMM FLAGS */ -+#define WMM_FLAG_SUPPORT_WMM BIT(0) -+#define WMM_FLAG_SUPPORT_WMMSA BIT(1) -+#define WMM_FLAG_AC_PARAM_PRESENT BIT(2) -+#define WMM_FLAG_SUPPORT_UAPSD BIT(3) -+ -+/* WMM Admission Control Mandatory FLAGS */ -+#define ACM_FLAG_ADM_NOT_REQUIRED 0 -+#define ACM_FLAG_ADM_GRANTED BIT(0) -+#define ACM_FLAG_ADM_REQUIRED BIT(1) -+ -+/* WMM Power Saving FLAGS */ -+#define AC_FLAG_TRIGGER_ENABLED BIT(1) -+#define AC_FLAG_DELIVERY_ENABLED BIT(2) -+ -+/* WMM-2.2.1 WMM Information Element */ -+#define ELEM_MAX_LEN_WMM_INFO 7 -+ -+/* WMM-2.2.2 WMM Parameter Element */ -+#define ELEM_MAX_LEN_WMM_PARAM 24 -+ -+/* WMM-2.2.1 WMM QoS Info field */ -+#define WMM_QOS_INFO_PARAM_SET_CNT BITS(0, 3) /* Sent by AP */ -+#define WMM_QOS_INFO_UAPSD BIT(7) -+ -+#define WMM_QOS_INFO_VO_UAPSD BIT(0) /* Sent by non-AP STA */ -+#define WMM_QOS_INFO_VI_UAPSD BIT(1) -+#define WMM_QOS_INFO_BK_UAPSD BIT(2) -+#define WMM_QOS_INFO_BE_UAPSD BIT(3) -+#define WMM_QOS_INFO_MAX_SP_LEN_MASK BITS(5, 6) -+#define WMM_QOS_INFO_MAX_SP_ALL 0 -+#define WMM_QOS_INFO_MAX_SP_2 BIT(5) -+#define WMM_QOS_INFO_MAX_SP_4 BIT(6) -+#define WMM_QOS_INFO_MAX_SP_6 BITS(5, 6) -+ -+/* -- definitions for Max SP length field */ -+#define WMM_MAX_SP_LENGTH_ALL 0 -+#define WMM_MAX_SP_LENGTH_2 2 -+#define WMM_MAX_SP_LENGTH_4 4 -+#define WMM_MAX_SP_LENGTH_6 6 -+ -+/* WMM-2.2.2 WMM ACI/AIFSN field */ -+/* -- subfields in the ACI/AIFSN field */ -+#define WMM_ACIAIFSN_AIFSN BITS(0, 3) -+#define WMM_ACIAIFSN_ACM BIT(4) -+#define WMM_ACIAIFSN_ACI BITS(5, 6) -+#define WMM_ACIAIFSN_ACI_OFFSET 5 -+ -+/* -- definitions for ACI field */ -+#define WMM_ACI_AC_BE 0 -+#define WMM_ACI_AC_BK BIT(5) -+#define WMM_ACI_AC_VI BIT(6) -+#define WMM_ACI_AC_VO BITS(5, 6) -+ -+#define WMM_ACI(_AC) (_AC << WMM_ACIAIFSN_ACI_OFFSET) -+ -+/* -- definitions for ECWmin/ECWmax field */ -+#define WMM_ECW_WMIN_MASK BITS(0, 3) -+#define WMM_ECW_WMAX_MASK BITS(4, 7) -+#define WMM_ECW_WMAX_OFFSET 4 -+ -+#define TXM_DEFAULT_FLUSH_QUEUE_GUARD_TIME 0 /* Unit: 64 us */ -+ -+#define QM_RX_BA_ENTRY_MISS_TIMEOUT_MS (1000) -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+enum { -+ QM_DBG_CNT_00 = 0, -+ QM_DBG_CNT_01, -+ QM_DBG_CNT_02, -+ QM_DBG_CNT_03, -+ QM_DBG_CNT_04, -+ QM_DBG_CNT_05, -+ QM_DBG_CNT_06, -+ QM_DBG_CNT_07, -+ QM_DBG_CNT_08, -+ QM_DBG_CNT_09, -+ QM_DBG_CNT_10, -+ QM_DBG_CNT_11, -+ QM_DBG_CNT_12, -+ QM_DBG_CNT_13, -+ QM_DBG_CNT_14, -+ QM_DBG_CNT_15, -+ QM_DBG_CNT_16, -+ QM_DBG_CNT_17, -+ QM_DBG_CNT_18, -+ QM_DBG_CNT_19, -+ QM_DBG_CNT_20, -+ QM_DBG_CNT_21, -+ QM_DBG_CNT_22, -+ QM_DBG_CNT_23, -+ QM_DBG_CNT_24, -+ QM_DBG_CNT_25, -+ QM_DBG_CNT_26, -+ QM_DBG_CNT_27, -+ QM_DBG_CNT_28, -+ QM_DBG_CNT_29, -+ QM_DBG_CNT_30, -+ QM_DBG_CNT_31, -+ QM_DBG_CNT_NUM -+}; -+ -+/* Used for MAC TX */ -+typedef enum _ENUM_MAC_TX_QUEUE_INDEX_T { -+ MAC_TX_QUEUE_AC0_INDEX = 0, -+ MAC_TX_QUEUE_AC1_INDEX, -+ MAC_TX_QUEUE_AC2_INDEX, -+ MAC_TX_QUEUE_AC3_INDEX, -+ MAC_TX_QUEUE_AC4_INDEX, -+ MAC_TX_QUEUE_AC5_INDEX, -+ MAC_TX_QUEUE_AC6_INDEX, -+ MAC_TX_QUEUE_BCN_INDEX, -+ MAC_TX_QUEUE_BMC_INDEX, -+ MAC_TX_QUEUE_NUM -+} ENUM_MAC_TX_QUEUE_INDEX_T; -+ -+typedef struct _RX_BA_ENTRY_T { -+ BOOLEAN fgIsValid; -+ QUE_T rReOrderQue; -+ UINT_16 u2WinStart; -+ UINT_16 u2WinEnd; -+ UINT_16 u2WinSize; -+ -+ /* For identifying the RX BA agreement */ -+ UINT_8 ucStaRecIdx; -+ UINT_8 ucTid; -+ -+ BOOLEAN fgIsWaitingForPktWithSsn; -+ -+ /* UINT_8 ucTxBufferSize; */ -+ /* BOOL fgIsAcConstrain; */ -+ /* BOOL fgIsBaEnabled; */ -+} RX_BA_ENTRY_T, *P_RX_BA_ENTRY_T; -+ -+/* The mailbox message (could be used for Host-To-Device or Device-To-Host Mailbox) */ -+typedef struct _MAILBOX_MSG_T { -+ UINT_32 u4Msg[2]; /* [0]: D2HRM0R or H2DRM0R, [1]: D2HRM1R or H2DRM1R */ -+} MAILBOX_MSG_T, *P_MAILBOX_MSG_T; -+ -+/* Used for adaptively adjusting TC resources */ -+typedef struct _TC_RESOURCE_CTRL_T { -+ /* TC0, TC1, TC2, TC3, TC5 */ -+ UINT_32 au4AverageQueLen[TC_NUM - 1]; -+} TC_RESOURCE_CTRL_T, *P_TC_RESOURCE_CTRL_T; -+ -+typedef struct _QUE_MGT_T { /* Queue Management Control Info */ -+ -+ /* Per-Type Queues: [0] BMCAST or UNKNOWN-STA packets */ -+ QUE_T arTxQueue[NUM_OF_PER_TYPE_TX_QUEUES]; -+ -+#if 0 -+ /* For TX Scheduling */ -+ UINT_8 arRemainingTxOppt[NUM_OF_PER_STA_TX_QUEUES]; -+ UINT_8 arCurrentTxStaIndex[NUM_OF_PER_STA_TX_QUEUES]; -+ -+#endif -+ -+ /* Reordering Queue Parameters */ -+ RX_BA_ENTRY_T arRxBaTable[CFG_NUM_OF_RX_BA_AGREEMENTS]; -+ -+ /* Current number of activated RX BA agreements <= CFG_NUM_OF_RX_BA_AGREEMENTS */ -+ UINT_8 ucRxBaCount; -+ -+#if QM_TEST_MODE -+ UINT_32 u4PktCount; -+ P_ADAPTER_T prAdapter; -+ -+#if QM_TEST_FAIR_FORWARDING -+ UINT_32 u4CurrentStaRecIndexToEnqueue; -+#endif -+ -+#endif -+ -+#if QM_FORWARDING_FAIRNESS -+ /* The current TX count for a STA with respect to a TC index */ -+ UINT_32 au4ForwardCount[NUM_OF_PER_STA_TX_QUEUES]; -+ -+ /* The current serving STA with respect to a TC index */ -+ UINT_32 au4HeadStaRecIndex[NUM_OF_PER_STA_TX_QUEUES]; -+#endif -+ -+#if QM_ADAPTIVE_TC_RESOURCE_CTRL -+ UINT_32 au4AverageQueLen[TC_NUM]; -+ UINT_32 au4CurrentTcResource[TC_NUM]; -+ UINT_32 au4MinReservedTcResource[TC_NUM]; /* The minimum amount of resource no matter busy or idle */ -+ UINT_32 au4GuaranteedTcResource[TC_NUM]; /* The minimum amount of resource when extremely busy */ -+ -+ UINT_32 u4TimeToAdjustTcResource; -+ UINT_32 u4TimeToUpdateQueLen; -+ UINT_32 u4TxNumOfVi, u4TxNumOfVo; /* number of VI/VO packets */ -+ -+ /* Set to TRUE if the last TC adjustment has not been completely applied (i.e., waiting more TX-Done events -+ to align the TC quotas to the TC resource assignment) */ -+ BOOLEAN fgTcResourcePostAnnealing; -+ -+#endif -+ -+#if QM_DEBUG_COUNTER -+ UINT_32 au4QmDebugCounters[QM_DBG_CNT_NUM]; -+#endif -+#if QM_TC_RESOURCE_EMPTY_COUNTER -+ UINT_32 au4QmTcResourceEmptyCounter[NET_TYPE_NUM][TC_NUM]; -+ UINT_32 au4QmTcResourceBackCounter[TC_NUM]; -+ UINT_32 au4DequeueNoTcResourceCounter[TC_NUM]; -+ -+ UINT_32 au4ResourceUsedCounter[TC_NUM]; -+ -+ UINT_32 au4ResourceWantedCounter[TC_NUM]; -+ -+ UINT_32 u4EnqeueuCounter; -+ UINT_32 u4DequeueCounter; -+#endif -+} QUE_MGT_T, *P_QUE_MGT_T; -+ -+typedef struct _EVENT_RX_ADDBA_T { -+ /* Event header */ -+ UINT_16 u2Length; -+ UINT_16 u2Reserved1; /* Must be filled with 0x0001 (EVENT Packet) */ -+ UINT_8 ucEID; -+ UINT_8 ucSeqNum; -+ UINT_8 aucReserved2[2]; -+ -+ /* Fields not present in the received ADDBA_REQ */ -+ UINT_8 ucStaRecIdx; -+ -+ /* Fields that are present in the received ADDBA_REQ */ -+ UINT_8 ucDialogToken; /* Dialog Token chosen by the sender */ -+ UINT_16 u2BAParameterSet; /* BA policy, TID, buffer size */ -+ UINT_16 u2BATimeoutValue; -+ UINT_16 u2BAStartSeqCtrl; /* SSN */ -+ -+} EVENT_RX_ADDBA_T, *P_EVENT_RX_ADDBA_T; -+ -+typedef struct _EVENT_RX_DELBA_T { -+ /* Event header */ -+ UINT_16 u2Length; -+ UINT_16 u2Reserved1; /* Must be filled with 0x0001 (EVENT Packet) */ -+ UINT_8 ucEID; -+ UINT_8 ucSeqNum; -+ UINT_8 aucReserved2[2]; -+ -+ /* Fields not present in the received ADDBA_REQ */ -+ UINT_8 ucStaRecIdx; -+ UINT_8 ucTid; -+} EVENT_RX_DELBA_T, *P_EVENT_RX_DELBA_T; -+ -+typedef struct _EVENT_BSS_ABSENCE_PRESENCE_T { -+ /* Event header */ -+ UINT_16 u2Length; -+ UINT_16 u2Reserved1; /* Must be filled with 0x0001 (EVENT Packet) */ -+ UINT_8 ucEID; -+ UINT_8 ucSeqNum; -+ UINT_8 aucReserved2[2]; -+ -+ /* Event Body */ -+ UINT_8 ucNetTypeIdx; -+ BOOLEAN fgIsAbsent; -+ UINT_8 ucBssFreeQuota; -+ UINT_8 aucReserved[1]; -+} EVENT_BSS_ABSENCE_PRESENCE_T, *P_EVENT_BSS_ABSENCE_PRESENCE_T; -+ -+typedef struct _EVENT_STA_CHANGE_PS_MODE_T { -+ /* Event header */ -+ UINT_16 u2Length; -+ UINT_16 u2Reserved1; /* Must be filled with 0x0001 (EVENT Packet) */ -+ UINT_8 ucEID; -+ UINT_8 ucSeqNum; -+ UINT_8 aucReserved2[2]; -+ -+ /* Event Body */ -+ UINT_8 ucStaRecIdx; -+ BOOLEAN fgIsInPs; -+ UINT_8 ucUpdateMode; -+ UINT_8 ucFreeQuota; -+} EVENT_STA_CHANGE_PS_MODE_T, *P_EVENT_STA_CHANGE_PS_MODE_T; -+ -+/* The free quota is used by PS only now */ -+/* The event may be used by per STA flow conttrol in general */ -+typedef struct _EVENT_STA_UPDATE_FREE_QUOTA_T { -+ /* Event header */ -+ UINT_16 u2Length; -+ UINT_16 u2Reserved1; /* Must be filled with 0x0001 (EVENT Packet) */ -+ UINT_8 ucEID; -+ UINT_8 ucSeqNum; -+ UINT_8 aucReserved2[2]; -+ -+ /* Event Body */ -+ UINT_8 ucStaRecIdx; -+ UINT_8 ucUpdateMode; -+ UINT_8 ucFreeQuota; -+ UINT_8 aucReserved[1]; -+} EVENT_STA_UPDATE_FREE_QUOTA_T, *P_EVENT_STA_UPDATE_FREE_QUOTA_T; -+ -+/* WMM-2.2.1 WMM Information Element */ -+typedef struct _IE_WMM_INFO_T { -+ UINT_8 ucId; /* Element ID */ -+ UINT_8 ucLength; /* Length */ -+ UINT_8 aucOui[3]; /* OUI */ -+ UINT_8 ucOuiType; /* OUI Type */ -+ UINT_8 ucOuiSubtype; /* OUI Subtype */ -+ UINT_8 ucVersion; /* Version */ -+ UINT_8 ucQosInfo; /* QoS Info field */ -+ UINT_8 ucDummy[3]; /* Dummy for pack */ -+} IE_WMM_INFO_T, *P_IE_WMM_INFO_T; -+ -+/* WMM-2.2.2 WMM Parameter Element */ -+typedef struct _IE_WMM_PARAM_T { -+ UINT_8 ucId; /* Element ID */ -+ UINT_8 ucLength; /* Length */ -+ -+ /* IE Body */ -+ UINT_8 aucOui[3]; /* OUI */ -+ UINT_8 ucOuiType; /* OUI Type */ -+ UINT_8 ucOuiSubtype; /* OUI Subtype */ -+ UINT_8 ucVersion; /* Version */ -+ -+ /* WMM IE Body */ -+ UINT_8 ucQosInfo; /* QoS Info field */ -+ UINT_8 ucReserved; -+ -+ /* AC Parameters */ -+ UINT_8 ucAciAifsn_BE; -+ UINT_8 ucEcw_BE; -+ UINT_8 aucTxopLimit_BE[2]; -+ -+ UINT_8 ucAciAifsn_BG; -+ UINT_8 ucEcw_BG; -+ UINT_8 aucTxopLimit_BG[2]; -+ -+ UINT_8 ucAciAifsn_VI; -+ UINT_8 ucEcw_VI; -+ UINT_8 aucTxopLimit_VI[2]; -+ -+ UINT_8 ucAciAifsn_VO; -+ UINT_8 ucEcw_VO; -+ UINT_8 aucTxopLimit_VO[2]; -+ -+} IE_WMM_PARAM_T, *P_IE_WMM_PARAM_T; -+ -+typedef struct _IE_WMM_TSPEC_T { -+ UINT_8 ucId; /* Element ID */ -+ UINT_8 ucLength; /* Length */ -+ UINT_8 aucOui[3]; /* OUI */ -+ UINT_8 ucOuiType; /* OUI Type */ -+ UINT_8 ucOuiSubtype; /* OUI Subtype */ -+ UINT_8 ucVersion; /* Version */ -+ /* WMM TSPEC body */ -+ UINT_8 aucTsInfo[3]; /* TS Info */ -+ UINT_8 aucTspecBodyPart[1]; /* Note: Utilize PARAM_QOS_TSPEC to fill (memory copy) */ -+} IE_WMM_TSPEC_T, *P_IE_WMM_TSPEC_T; -+ -+typedef struct _IE_WMM_HDR_T { -+ UINT_8 ucId; /* Element ID */ -+ UINT_8 ucLength; /* Length */ -+ UINT_8 aucOui[3]; /* OUI */ -+ UINT_8 ucOuiType; /* OUI Type */ -+ UINT_8 ucOuiSubtype; /* OUI Subtype */ -+ UINT_8 ucVersion; /* Version */ -+ UINT_8 aucBody[1]; /* IE body */ -+} IE_WMM_HDR_T, *P_IE_WMM_HDR_T; -+ -+typedef struct _AC_QUE_PARMS_T { -+ UINT_16 u2CWmin; /*!< CWmin */ -+ UINT_16 u2CWmax; /*!< CWmax */ -+ UINT_16 u2TxopLimit; /*!< TXOP limit */ -+ UINT_16 u2Aifsn; /*!< AIFSN */ -+ UINT_8 ucGuradTime; /*!< GuardTime for STOP/FLUSH. */ -+ BOOLEAN fgIsACMSet; -+} AC_QUE_PARMS_T, *P_AC_QUE_PARMS_T; -+ -+/* WMM ACI (AC index) */ -+typedef enum _ENUM_WMM_ACI_T { -+ WMM_AC_BE_INDEX = 0, -+ WMM_AC_BK_INDEX, -+ WMM_AC_VI_INDEX, -+ WMM_AC_VO_INDEX, -+ WMM_AC_INDEX_NUM -+} ENUM_WMM_ACI_T, *P_ENUM_WMM_ACI_T; -+ -+/* Used for CMD Queue Operation */ -+typedef enum _ENUM_FRAME_ACTION_T { -+ FRAME_ACTION_DROP_PKT = 0, -+ FRAME_ACTION_QUEUE_PKT, -+ FRAME_ACTION_TX_PKT, -+ FRAME_ACTION_NUM -+} ENUM_FRAME_ACTION_T; -+ -+typedef enum _ENUM_FRAME_TYPE_IN_CMD_Q_T { -+ FRAME_TYPE_802_1X = 0, -+ FRAME_TYPE_MMPDU, -+ FRAME_TYPE_NUM -+} ENUM_FRAME_TYPE_IN_CMD_Q_T; -+ -+typedef enum _ENUM_FREE_QUOTA_MODET_T { -+ FREE_QUOTA_UPDATE_MODE_INIT = 0, -+ FREE_QUOTA_UPDATE_MODE_OVERWRITE, -+ FREE_QUOTA_UPDATE_MODE_INCREASE, -+ FREE_QUOTA_UPDATE_MODE_DECREASE -+} ENUM_FREE_QUOTA_MODET_T, *P_ENUM_FREE_QUOTA_MODET_T; -+ -+typedef struct _CMD_UPDATE_WMM_PARMS_T { -+ AC_QUE_PARMS_T arACQueParms[AC_NUM]; -+ UINT_8 ucNetTypeIndex; -+ UINT_8 fgIsQBSS; -+ UINT_8 aucReserved[2]; -+} CMD_UPDATE_WMM_PARMS_T, *P_CMD_UPDATE_WMM_PARMS_T; -+ -+typedef struct _CMD_TX_AMPDU_T { -+ BOOLEAN fgEnable; -+ UINT_8 aucReserved[3]; -+} CMD_TX_AMPDU_T, *P_CMD_TX_AMPDU_T; -+ -+typedef struct _CMD_ADDBA_REJECT { -+ BOOLEAN fgEnable; -+ UINT_8 aucReserved[3]; -+} CMD_ADDBA_REJECT_T, *P_CMD_ADDBA_REJECT_T; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+#define QM_TX_SET_NEXT_MSDU_INFO(_prMsduInfoPreceding, _prMsduInfoNext) \ -+ ((((_prMsduInfoPreceding)->rQueEntry).prNext) = (P_QUE_ENTRY_T)(_prMsduInfoNext)) -+ -+#define QM_TX_SET_NEXT_SW_RFB(_prSwRfbPreceding, _prSwRfbNext) \ -+ ((((_prSwRfbPreceding)->rQueEntry).prNext) = (P_QUE_ENTRY_T)(_prSwRfbNext)) -+ -+#define QM_TX_GET_NEXT_MSDU_INFO(_prMsduInfo) \ -+ ((P_MSDU_INFO_T)(((_prMsduInfo)->rQueEntry).prNext)) -+ -+#define QM_RX_SET_NEXT_SW_RFB(_prSwRfbPreceding, _prSwRfbNext) \ -+ ((((_prSwRfbPreceding)->rQueEntry).prNext) = (P_QUE_ENTRY_T)(_prSwRfbNext)) -+ -+#define QM_RX_GET_NEXT_SW_RFB(_prSwRfb) \ -+ ((P_SW_RFB_T)(((_prSwRfb)->rQueEntry).prNext)) -+ -+#if 0 -+#define QM_GET_STA_REC_PTR_FROM_INDEX(_prAdapter, _ucIndex) \ -+ ((((_ucIndex) != STA_REC_INDEX_BMCAST) && ((_ucIndex) != STA_REC_INDEX_NOT_FOUND)) ?\ -+ &(_prAdapter->arStaRec[_ucIndex]) : NULL) -+#endif -+ -+#define QM_GET_STA_REC_PTR_FROM_INDEX(_prAdapter, _ucIndex) \ -+ cnmGetStaRecByIndex(_prAdapter, _ucIndex) -+ -+#define QM_TX_SET_MSDU_INFO_FOR_DATA_PACKET(\ -+ _prMsduInfo,\ -+ _ucTC,\ -+ _ucPacketType,\ -+ _ucFormatID,\ -+ _fgIs802_1x,\ -+ _fgIs802_11,\ -+ _u2PalLLH,\ -+ _u2AclSN,\ -+ _ucPsForwardingType,\ -+ _ucPsSessionID\ -+ ) \ -+{\ -+ ASSERT(_prMsduInfo);\ -+ (_prMsduInfo)->ucTC = (_ucTC);\ -+ (_prMsduInfo)->ucPacketType = (_ucPacketType);\ -+ (_prMsduInfo)->ucFormatID = (_ucFormatID);\ -+ (_prMsduInfo)->fgIs802_1x = (_fgIs802_1x);\ -+ (_prMsduInfo)->fgIs802_11 = (_fgIs802_11);\ -+ (_prMsduInfo)->u2PalLLH = (_u2PalLLH);\ -+ (_prMsduInfo)->u2AclSN = (_u2AclSN);\ -+ (_prMsduInfo)->ucPsForwardingType = (_ucPsForwardingType);\ -+ (_prMsduInfo)->ucPsSessionID = (_ucPsSessionID);\ -+ (_prMsduInfo)->fgIsBurstEnd = (FALSE);\ -+} -+ -+#define QM_INIT_STA_REC(\ -+ _prStaRec,\ -+ _fgIsValid,\ -+ _fgIsQoS,\ -+ _pucMacAddr\ -+ )\ -+{\ -+ ASSERT(_prStaRec);\ -+ (_prStaRec)->fgIsValid = (_fgIsValid);\ -+ (_prStaRec)->fgIsQoS = (_fgIsQoS);\ -+ (_prStaRec)->fgIsInPS = FALSE; \ -+ (_prStaRec)->ucPsSessionID = 0xFF;\ -+ COPY_MAC_ADDR((_prStaRec)->aucMacAddr, (_pucMacAddr));\ -+} -+ -+#if QM_ADAPTIVE_TC_RESOURCE_CTRL -+#define QM_GET_TX_QUEUE_LEN(_prAdapter, _u4QueIdx) \ -+ ((_prAdapter->rQM.au4AverageQueLen[(_u4QueIdx)] >> QM_QUE_LEN_MOVING_AVE_FACTOR)) -+#endif -+ -+#define WMM_IE_OUI_TYPE(fp) (((P_IE_WMM_HDR_T)(fp))->ucOuiType) -+#define WMM_IE_OUI_SUBTYPE(fp) (((P_IE_WMM_HDR_T)(fp))->ucOuiSubtype) -+#define WMM_IE_OUI(fp) (((P_IE_WMM_HDR_T)(fp))->aucOui) -+ -+#if QM_DEBUG_COUNTER -+#define QM_DBG_CNT_INC(_prQM, _index) { (_prQM)->au4QmDebugCounters[(_index)]++; } -+#else -+#define QM_DBG_CNT_INC(_prQM, _index) {} -+#endif -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+/*----------------------------------------------------------------------------*/ -+/* Queue Management and STA_REC Initialization */ -+/*----------------------------------------------------------------------------*/ -+ -+VOID qmInit(IN P_ADAPTER_T prAdapter); -+ -+#if QM_TEST_MODE -+VOID qmTestCases(IN P_ADAPTER_T prAdapter); -+#endif -+ -+VOID qmActivateStaRec(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec); -+ -+VOID qmDeactivateStaRec(IN P_ADAPTER_T prAdapter, IN UINT_32 u4StaRecIdx); -+ -+/*----------------------------------------------------------------------------*/ -+/* TX-Related Queue Management */ -+/*----------------------------------------------------------------------------*/ -+ -+P_MSDU_INFO_T qmFlushTxQueues(IN P_ADAPTER_T prAdapter); -+ -+P_MSDU_INFO_T qmFlushStaTxQueues(IN P_ADAPTER_T prAdapter, IN UINT_32 u4StaRecIdx); -+ -+P_MSDU_INFO_T qmEnqueueTxPackets(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfoListHead); -+ -+P_MSDU_INFO_T qmDequeueTxPackets(IN P_ADAPTER_T prAdapter, IN P_TX_TCQ_STATUS_T prTcqStatus); -+ -+VOID qmAdjustTcQuotas(IN P_ADAPTER_T prAdapter, OUT P_TX_TCQ_ADJUST_T prTcqAdjust, IN P_TX_TCQ_STATUS_T prTcqStatus); -+ -+#if QM_ADAPTIVE_TC_RESOURCE_CTRL -+VOID qmReassignTcResource(IN P_ADAPTER_T prAdapter); -+ -+VOID qmUpdateAverageTxQueLen(IN P_ADAPTER_T prAdapter); -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/* RX-Related Queue Management */ -+/*----------------------------------------------------------------------------*/ -+ -+VOID qmInitRxQueues(IN P_ADAPTER_T prAdapter); -+ -+P_SW_RFB_T qmFlushRxQueues(IN P_ADAPTER_T prAdapter); -+ -+P_SW_RFB_T qmHandleRxPackets(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfbListHead); -+ -+VOID qmProcessPktWithReordering(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, OUT P_QUE_T prReturnedQue); -+ -+VOID qmProcessBarFrame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, OUT P_QUE_T prReturnedQue); -+ -+VOID -+qmInsertFallWithinReorderPkt(IN P_SW_RFB_T prSwRfb, IN P_RX_BA_ENTRY_T prReorderQueParm, OUT P_QUE_T prReturnedQue); -+ -+VOID qmInsertFallAheadReorderPkt(IN P_SW_RFB_T prSwRfb, IN P_RX_BA_ENTRY_T prReorderQueParm, OUT P_QUE_T prReturnedQue); -+ -+BOOLEAN -+qmPopOutDueToFallWithin(IN P_RX_BA_ENTRY_T prReorderQueParm, OUT P_QUE_T prReturnedQue, OUT BOOLEAN *fgIsTimeout); -+ -+VOID qmPopOutDueToFallAhead(IN P_RX_BA_ENTRY_T prReorderQueParm, OUT P_QUE_T prReturnedQue); -+ -+VOID qmHandleMailboxRxMessage(IN MAILBOX_MSG_T prMailboxRxMsg); -+ -+BOOLEAN qmCompareSnIsLessThan(IN UINT_32 u4SnLess, IN UINT_32 u4SnGreater); -+ -+VOID qmHandleEventRxAddBa(IN P_ADAPTER_T prAdapter, IN P_WIFI_EVENT_T prEvent); -+ -+VOID qmHandleEventRxDelBa(IN P_ADAPTER_T prAdapter, IN P_WIFI_EVENT_T prEvent); -+ -+P_RX_BA_ENTRY_T qmLookupRxBaEntry(IN P_ADAPTER_T prAdapter, IN UINT_8 ucStaRecIdx, IN UINT_8 ucTid); -+ -+BOOLEAN -+qmAddRxBaEntry(IN P_ADAPTER_T prAdapter, -+ IN UINT_8 ucStaRecIdx, IN UINT_8 ucTid, IN UINT_16 u2WinStart, IN UINT_16 u2WinSize); -+ -+VOID qmDelRxBaEntry(IN P_ADAPTER_T prAdapter, IN UINT_8 ucStaRecIdx, IN UINT_8 ucTid, IN BOOLEAN fgFlushToHost); -+ -+VOID mqmProcessAssocRsp(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, IN PUINT_8 pucIE, IN UINT_16 u2IELength); -+ -+VOID -+mqmParseEdcaParameters(IN P_ADAPTER_T prAdapter, -+ IN P_SW_RFB_T prSwRfb, IN PUINT_8 pucIE, IN UINT_16 u2IELength, IN BOOLEAN fgForceOverride); -+ -+VOID mqmFillAcQueParam(IN P_IE_WMM_PARAM_T prIeWmmParam, IN UINT_32 u4AcOffset, OUT P_AC_QUE_PARMS_T prAcQueParams); -+ -+VOID mqmProcessScanResult(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prScanResult, OUT P_STA_RECORD_T prStaRec); -+ -+/* Utility function: for deciding STA-REC index */ -+UINT_8 qmGetStaRecIdx(IN P_ADAPTER_T prAdapter, IN PUINT_8 pucEthDestAddr, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkType); -+ -+UINT_32 -+mqmGenerateWmmInfoIEByParam(BOOLEAN fgSupportUAPSD, -+ UINT_8 ucBmpDeliveryAC, UINT_8 ucBmpTriggerAC, UINT_8 ucUapsdSp, UINT_8 *pOutBuf); -+ -+VOID mqmGenerateWmmInfoIE(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); -+ -+UINT_32 mqmGenerateWmmParamIEByParam(P_ADAPTER_T prAdapter, -+ P_BSS_INFO_T prBssInfo, UINT_8 *pOutBuf, ENUM_OP_MODE_T ucOpMode); -+ -+VOID mqmGenerateWmmParamIE(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); -+ -+ENUM_FRAME_ACTION_T -+qmGetFrameAction(IN P_ADAPTER_T prAdapter, -+ IN ENUM_NETWORK_TYPE_INDEX_T eNetworkType, -+ IN UINT_8 ucStaRecIdx, IN P_MSDU_INFO_T prMsduInfo, IN ENUM_FRAME_TYPE_IN_CMD_Q_T eFrameType); -+ -+VOID qmHandleEventBssAbsencePresence(IN P_ADAPTER_T prAdapter, IN P_WIFI_EVENT_T prEvent); -+ -+VOID qmHandleEventStaChangePsMode(IN P_ADAPTER_T prAdapter, IN P_WIFI_EVENT_T prEvent); -+ -+VOID mqmProcessAssocReq(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, IN PUINT_8 pucIE, IN UINT_16 u2IELength); -+ -+VOID qmHandleEventStaUpdateFreeQuota(IN P_ADAPTER_T prAdapter, IN P_WIFI_EVENT_T prEvent); -+ -+VOID -+qmUpdateFreeQuota(IN P_ADAPTER_T prAdapter, -+ IN P_STA_RECORD_T prStaRec, IN UINT_8 ucUpdateMode, IN UINT_8 ucFreeQuota, IN UINT_8 ucNumOfTxDone); -+ -+VOID qmFreeAllByNetType(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx); -+ -+UINT_32 qmGetRxReorderQueuedBufferCount(IN P_ADAPTER_T prAdapter); -+ -+#if ARP_MONITER_ENABLE -+VOID qmDetectArpNoResponse(P_ADAPTER_T prAdapter, P_MSDU_INFO_T prMsduInfo); -+VOID qmResetArpDetect(VOID); -+VOID qmHandleRxArpPackets(P_ADAPTER_T prAdapter, P_SW_RFB_T prSwRfb); -+#endif -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif /* _QUE_MGT_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/wlan_def.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/wlan_def.h -new file mode 100644 -index 000000000000..2804b0387f5f ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/wlan_def.h -@@ -0,0 +1,1010 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/nic/wlan_def.h#1 -+*/ -+ -+/*! \file "wlan_def.h" -+ \brief This file includes the basic definition of WLAN -+ -+*/ -+ -+/* -+** Log: wlan_def.h -+** -+** 09 02 2013 cp.wu -+** add path to handle reassociation request -+ * -+ * 12 05 2011 cp.wu -+ * [WCXRP00001131] [MT6620 Wi-Fi][Driver][AIS] Implement connect-by-BSSID path -+ * add CONNECT_BY_BSSID policy -+ * -+ * 10 12 2011 wh.su -+ * [WCXRP00001036] [MT6620 Wi-Fi][Driver][FW] Adding the 802.11w code for MFP -+ * adding the 802.11w related function and define . -+ * -+ * 06 22 2011 wh.su -+ * [WCXRP00000806] [MT6620 Wi-Fi][Driver] Move the WPA/RSN IE and WAPI IE structure to mac.h and let the sw -+ * structure not align at byte -+ * Move the WAPI/RSN IE to mac.h and SW structure not align to byte, -+ * Notice needed update P2P.ko. -+ * -+ * 04 08 2011 eddie.chen -+ * [WCXRP00000617] [MT6620 Wi-Fi][DRV/FW] Fix for sigma -+ * Fix for sigma -+ * -+ * 03 17 2011 yuche.tsai -+ * NULL -+ * Resize the Secondary Device Type array when WiFi Direct is enabled. -+ * -+ * 01 25 2011 yuche.tsai -+ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record. -+ * Change Station Type in Station Record, Modify MACRO definition for getting station type & network type index & Role. -+ * -+ * 01 25 2011 yuche.tsai -+ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record. -+ * Add new station type MACRO. -+ * -+ * 12 07 2010 cm.chang -+ * [WCXRP00000238] MT6620 Wi-Fi][Driver][FW] Support regulation domain setting from NVRAM and supplicant -+ * 1. Country code is from NVRAM or supplicant -+ * 2. Change band definition in CMD/EVENT. -+ * -+ * 10 11 2010 kevin.huang -+ * [WCXRP00000068] [MT6620 Wi-Fi][Driver][FW] Fix STA RECORD sync issue and remove unused code -+ * Update ENUM_STA_ROLE_INDEX_T by using a fixed base value -+ * -+ * 10 04 2010 cp.wu -+ * [WCXRP00000077] [MT6620 Wi-Fi][Driver][FW] Eliminate use of ENUM_NETWORK_TYPE_T and replaced by -+ * ENUM_NETWORK_TYPE_INDEX_T only -+ * remove ENUM_NETWORK_TYPE_T definitions -+ * -+ * 09 14 2010 chinghwa.yu -+ * NULL -+ * Update OP_MODE_BOW and include bow_fsm.h. -+ * -+ * 09 03 2010 kevin.huang -+ * NULL -+ * Refine #include sequence and solve recursive/nested #include issue -+ * -+ * 08 31 2010 kevin.huang -+ * NULL -+ * Use LINK LIST operation to process SCAN result -+ * -+ * 08 29 2010 yuche.tsai -+ * NULL -+ * Change P2P Descriptor List to a pointer and allocate it dynamically to avoid structure corrupt by BssDescriptor free. -+ * -+ * 08 16 2010 kevin.huang -+ * NULL -+ * Refine AAA functions -+ * -+ * 08 12 2010 kevin.huang -+ * NULL -+ * Refine bssProcessProbeRequest() and bssSendBeaconProbeResponse() -+ * -+ * 08 12 2010 yuche.tsai -+ * NULL -+ * Add a pointer in BSS Descriptor for P2P Descriptor. -+ * -+ * 08 11 2010 yuche.tsai -+ * NULL -+ * Add an Interface in BSS Descriptor. -+ * -+ * 08 05 2010 yuche.tsai -+ * NULL -+ * Modify data structure for P2P Scan result. -+ * -+ * 07 26 2010 yuche.tsai -+ * -+ * Add an operation mode for P2P device. -+ * -+ * 07 23 2010 cp.wu -+ * -+ * P2P/RSN/WAPI IEs need to be declared with compact structure. -+ * -+ * 07 21 2010 yuche.tsai -+ * -+ * Add for P2P Scan Result Parsing & Saving. -+ * -+ * 07 20 2010 wh.su -+ * -+ * adding the wapi code. -+ * -+ * 07 09 2010 cp.wu -+ * -+ * 1) separate AIS_FSM state for two kinds of scanning. (OID triggered scan, and scan-for-connection) -+ * 2) eliminate PRE_BSS_DESC_T, Beacon/PrebResp is now parsed in single pass -+ * 3) implment DRV-SCN module, currently only accepts single scan request, other request will be directly -+ * dropped by returning BUSY -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 28 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * 1st draft code for RLM module -+ * -+ * 06 25 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * modify Beacon/ProbeResp to complete parsing, -+ * because host software has looser memory usage restriction -+ * -+ * 06 21 2010 yuche.tsai -+ * [WPD00003839][MT6620 5931][P2P] Feature migration -+ * Add P2P present boolean flag in BSS & Pre-BSS descriptor. -+ * -+ * 06 18 2010 wh.su -+ * [WPD00003840][MT6620 5931] Security migration -+ * migration the security related function from firmware. -+ * -+ * 06 11 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * auth.c is migrated. -+ * -+ * 06 11 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) migrate assoc.c. -+ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness -+ * 3) add configuration options for CNM_MEM and RSN modules -+ * 4) add data path for management frames -+ * 5) eliminate rPacketInfo of MSDU_INFO_T -+ * -+ * 06 10 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add buildable & linkable ais_fsm.c -+ * -+ * related reference are still waiting to be resolved -+ * -+ * 06 09 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add definitions for module migration. -+ * -+ * 06 07 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * move bss related data types to wlan_def.h to avoid recursive dependency. -+ * -+ * 06 07 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * merge wlan_def.h. -+ * -+ * 06 07 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * merge cnm_scan.h and hem_mbox.h -+ * -+ * 06 07 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * merge wifi_var.h, precomp.h, cnm_timer.h (data type only) -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 20:16:40 GMT mtk01426 -+** Init for develop -+** -+*/ -+ -+#ifndef _WLAN_DEF_H -+#define _WLAN_DEF_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+/* disconnect reason */ -+#define DISCONNECT_REASON_CODE_RESERVED 0 -+#define DISCONNECT_REASON_CODE_RADIO_LOST 1 -+#define DISCONNECT_REASON_CODE_DEAUTHENTICATED 2 -+#define DISCONNECT_REASON_CODE_DISASSOCIATED 3 -+#define DISCONNECT_REASON_CODE_NEW_CONNECTION 4 -+#define DISCONNECT_REASON_CODE_REASSOCIATION 5 -+#define DISCONNECT_REASON_CODE_ROAMING 6 -+ -+/* The rate definitions */ -+#define TX_MODE_CCK 0x00 -+#define TX_MODE_OFDM 0x40 -+#define TX_MODE_HT_MM 0x80 -+#define TX_MODE_HT_GF 0xC0 -+ -+#define RATE_CCK_SHORT_PREAMBLE 0x10 -+#define RATE_OFDM 0x20 -+ -+#define PHY_RATE_1M 0x0 -+#define PHY_RATE_2M 0x1 -+#define PHY_RATE_5_5M 0x2 -+#define PHY_RATE_11M 0x3 -+#define PHY_RATE_6M 0xB -+#define PHY_RATE_9M 0xF -+#define PHY_RATE_12M 0xA -+#define PHY_RATE_18M 0xE -+#define PHY_RATE_24M 0x9 -+#define PHY_RATE_36M 0xD -+#define PHY_RATE_48M 0x8 -+#define PHY_RATE_54M 0xC -+#define PHY_RATE_MCS0 0x0 -+#define PHY_RATE_MCS1 0x1 -+#define PHY_RATE_MCS2 0x2 -+#define PHY_RATE_MCS3 0x3 -+#define PHY_RATE_MCS4 0x4 -+#define PHY_RATE_MCS5 0x5 -+#define PHY_RATE_MCS6 0x6 -+#define PHY_RATE_MCS7 0x7 -+#define PHY_RATE_MCS32 0x20 -+ -+#define RATE_CCK_1M_LONG (TX_MODE_CCK | PHY_RATE_1M) -+#define RATE_CCK_2M_LONG (TX_MODE_CCK | PHY_RATE_2M) -+#define RATE_CCK_5_5M_LONG (TX_MODE_CCK | PHY_RATE_5_5M) -+#define RATE_CCK_11M_LONG (TX_MODE_CCK | PHY_RATE_11M) -+#define RATE_CCK_2M_SHORT (TX_MODE_CCK | PHY_RATE_2M | RATE_CCK_SHORT_PREAMBLE) -+#define RATE_CCK_5_5M_SHORT (TX_MODE_CCK | PHY_RATE_5_5M | RATE_CCK_SHORT_PREAMBLE) -+#define RATE_CCK_11M_SHORT (TX_MODE_CCK | PHY_RATE_11M | RATE_CCK_SHORT_PREAMBLE) -+#define RATE_OFDM_6M (TX_MODE_OFDM | RATE_OFDM | PHY_RATE_6M) -+#define RATE_OFDM_9M (TX_MODE_OFDM | RATE_OFDM | PHY_RATE_9M) -+#define RATE_OFDM_12M (TX_MODE_OFDM | RATE_OFDM | PHY_RATE_12M) -+#define RATE_OFDM_18M (TX_MODE_OFDM | RATE_OFDM | PHY_RATE_18M) -+#define RATE_OFDM_24M (TX_MODE_OFDM | RATE_OFDM | PHY_RATE_24M) -+#define RATE_OFDM_36M (TX_MODE_OFDM | RATE_OFDM | PHY_RATE_36M) -+#define RATE_OFDM_48M (TX_MODE_OFDM | RATE_OFDM | PHY_RATE_48M) -+#define RATE_OFDM_54M (TX_MODE_OFDM | RATE_OFDM | PHY_RATE_54M) -+ -+#define RATE_MM_MCS_0 (TX_MODE_HT_MM | PHY_RATE_MCS0) -+#define RATE_MM_MCS_1 (TX_MODE_HT_MM | PHY_RATE_MCS1) -+#define RATE_MM_MCS_2 (TX_MODE_HT_MM | PHY_RATE_MCS2) -+#define RATE_MM_MCS_3 (TX_MODE_HT_MM | PHY_RATE_MCS3) -+#define RATE_MM_MCS_4 (TX_MODE_HT_MM | PHY_RATE_MCS4) -+#define RATE_MM_MCS_5 (TX_MODE_HT_MM | PHY_RATE_MCS5) -+#define RATE_MM_MCS_6 (TX_MODE_HT_MM | PHY_RATE_MCS6) -+#define RATE_MM_MCS_7 (TX_MODE_HT_MM | PHY_RATE_MCS7) -+#define RATE_MM_MCS_32 (TX_MODE_HT_MM | PHY_RATE_MCS32) -+ -+#define RATE_GF_MCS_0 (TX_MODE_HT_GF | PHY_RATE_MCS0) -+#define RATE_GF_MCS_1 (TX_MODE_HT_GF | PHY_RATE_MCS1) -+#define RATE_GF_MCS_2 (TX_MODE_HT_GF | PHY_RATE_MCS2) -+#define RATE_GF_MCS_3 (TX_MODE_HT_GF | PHY_RATE_MCS3) -+#define RATE_GF_MCS_4 (TX_MODE_HT_GF | PHY_RATE_MCS4) -+#define RATE_GF_MCS_5 (TX_MODE_HT_GF | PHY_RATE_MCS5) -+#define RATE_GF_MCS_6 (TX_MODE_HT_GF | PHY_RATE_MCS6) -+#define RATE_GF_MCS_7 (TX_MODE_HT_GF | PHY_RATE_MCS7) -+#define RATE_GF_MCS_32 (TX_MODE_HT_GF | PHY_RATE_MCS32) -+ -+#define RATE_TX_MODE_MASK BITS(6, 7) -+#define RATE_TX_MODE_OFFSET 6 -+#define RATE_CODE_GET_TX_MODE(_ucRateCode) ((_ucRateCode & RATE_TX_MODE_MASK) >> RATE_TX_MODE_OFFSET) -+#define RATE_PHY_RATE_MASK BITS(0, 5) -+#define RATE_PHY_RATE_OFFSET 0 -+#define RATE_CODE_GET_PHY_RATE(_ucRateCode) ((_ucRateCode & RATE_PHY_RATE_MASK) >> RATE_PHY_RATE_OFFSET) -+#define RATE_PHY_RATE_SHORT_PREAMBLE BIT(4) -+#define RATE_CODE_IS_SHORT_PREAMBLE(_ucRateCode) ((_ucRateCode & RATE_PHY_RATE_SHORT_PREAMBLE)?TRUE:FALSE) -+ -+#define CHNL_LIST_SZ_2G 14 -+#define CHNL_LIST_SZ_5G 14 -+ -+/*! CNM(STA_RECORD_T) related definition */ -+#define CFG_STA_REC_NUM 20 -+ -+/* PHY TYPE bit definitions */ -+#define PHY_TYPE_BIT_HR_DSSS BIT(PHY_TYPE_HR_DSSS_INDEX) /* HR/DSSS PHY (clause 18) */ -+#define PHY_TYPE_BIT_ERP BIT(PHY_TYPE_ERP_INDEX) /* ERP PHY (clause 19) */ -+#define PHY_TYPE_BIT_OFDM BIT(PHY_TYPE_OFDM_INDEX) /* OFDM 5 GHz PHY (clause 17) */ -+#define PHY_TYPE_BIT_HT BIT(PHY_TYPE_HT_INDEX) /* HT PHY (clause 20) */ -+ -+/* PHY TYPE set definitions */ -+#define PHY_TYPE_SET_802_11ABGN (PHY_TYPE_BIT_OFDM | \ -+ PHY_TYPE_BIT_HR_DSSS | \ -+ PHY_TYPE_BIT_ERP | \ -+ PHY_TYPE_BIT_HT) -+ -+#define PHY_TYPE_SET_802_11BGN (PHY_TYPE_BIT_HR_DSSS | \ -+ PHY_TYPE_BIT_ERP | \ -+ PHY_TYPE_BIT_HT) -+ -+#define PHY_TYPE_SET_802_11GN (PHY_TYPE_BIT_ERP | \ -+ PHY_TYPE_BIT_HT) -+ -+#define PHY_TYPE_SET_802_11AN (PHY_TYPE_BIT_OFDM | \ -+ PHY_TYPE_BIT_HT) -+ -+#define PHY_TYPE_SET_802_11ABG (PHY_TYPE_BIT_OFDM | \ -+ PHY_TYPE_BIT_HR_DSSS | \ -+ PHY_TYPE_BIT_ERP) -+ -+#define PHY_TYPE_SET_802_11BG (PHY_TYPE_BIT_HR_DSSS | \ -+ PHY_TYPE_BIT_ERP) -+ -+#define PHY_TYPE_SET_802_11A (PHY_TYPE_BIT_OFDM) -+ -+#define PHY_TYPE_SET_802_11G (PHY_TYPE_BIT_ERP) -+ -+#define PHY_TYPE_SET_802_11B (PHY_TYPE_BIT_HR_DSSS) -+ -+#define PHY_TYPE_SET_802_11N (PHY_TYPE_BIT_HT) -+ -+/* Rate set bit definitions */ -+#define RATE_SET_BIT_1M BIT(RATE_1M_INDEX) /* Bit 0: 1M */ -+#define RATE_SET_BIT_2M BIT(RATE_2M_INDEX) /* Bit 1: 2M */ -+#define RATE_SET_BIT_5_5M BIT(RATE_5_5M_INDEX) /* Bit 2: 5.5M */ -+#define RATE_SET_BIT_11M BIT(RATE_11M_INDEX) /* Bit 3: 11M */ -+#define RATE_SET_BIT_22M BIT(RATE_22M_INDEX) /* Bit 4: 22M */ -+#define RATE_SET_BIT_33M BIT(RATE_33M_INDEX) /* Bit 5: 33M */ -+#define RATE_SET_BIT_6M BIT(RATE_6M_INDEX) /* Bit 6: 6M */ -+#define RATE_SET_BIT_9M BIT(RATE_9M_INDEX) /* Bit 7: 9M */ -+#define RATE_SET_BIT_12M BIT(RATE_12M_INDEX) /* Bit 8: 12M */ -+#define RATE_SET_BIT_18M BIT(RATE_18M_INDEX) /* Bit 9: 18M */ -+#define RATE_SET_BIT_24M BIT(RATE_24M_INDEX) /* Bit 10: 24M */ -+#define RATE_SET_BIT_36M BIT(RATE_36M_INDEX) /* Bit 11: 36M */ -+#define RATE_SET_BIT_48M BIT(RATE_48M_INDEX) /* Bit 12: 48M */ -+#define RATE_SET_BIT_54M BIT(RATE_54M_INDEX) /* Bit 13: 54M */ -+#define RATE_SET_BIT_HT_PHY BIT(RATE_HT_PHY_INDEX) /* Bit 14: BSS Selector */ -+ -+/* Rate set definitions */ -+#define RATE_SET_HR_DSSS (RATE_SET_BIT_1M | \ -+ RATE_SET_BIT_2M | \ -+ RATE_SET_BIT_5_5M | \ -+ RATE_SET_BIT_11M) -+ -+#define RATE_SET_ERP (RATE_SET_BIT_1M | \ -+ RATE_SET_BIT_2M | \ -+ RATE_SET_BIT_5_5M | \ -+ RATE_SET_BIT_11M | \ -+ RATE_SET_BIT_6M | \ -+ RATE_SET_BIT_9M | \ -+ RATE_SET_BIT_12M | \ -+ RATE_SET_BIT_18M | \ -+ RATE_SET_BIT_24M | \ -+ RATE_SET_BIT_36M | \ -+ RATE_SET_BIT_48M | \ -+ RATE_SET_BIT_54M) -+ -+#define RATE_SET_ERP_P2P (RATE_SET_BIT_6M | \ -+ RATE_SET_BIT_9M | \ -+ RATE_SET_BIT_12M | \ -+ RATE_SET_BIT_18M | \ -+ RATE_SET_BIT_24M | \ -+ RATE_SET_BIT_36M | \ -+ RATE_SET_BIT_48M | \ -+ RATE_SET_BIT_54M) -+ -+#define RATE_SET_OFDM (RATE_SET_BIT_6M | \ -+ RATE_SET_BIT_9M | \ -+ RATE_SET_BIT_12M | \ -+ RATE_SET_BIT_18M | \ -+ RATE_SET_BIT_24M | \ -+ RATE_SET_BIT_36M | \ -+ RATE_SET_BIT_48M | \ -+ RATE_SET_BIT_54M) -+ -+#define RATE_SET_HT (RATE_SET_ERP) -+/* #define RATE_SET_HT (RATE_SET_ERP | RATE_SET_BIT_HT_PHY) *//* NOTE(Kevin): TBD */ -+ -+#define RATE_SET_ALL_ABG RATE_SET_ERP -+ -+#define BASIC_RATE_SET_HR_DSSS (RATE_SET_BIT_1M | \ -+ RATE_SET_BIT_2M) -+ -+#define BASIC_RATE_SET_HR_DSSS_ERP (RATE_SET_BIT_1M | \ -+ RATE_SET_BIT_2M | \ -+ RATE_SET_BIT_5_5M | \ -+ RATE_SET_BIT_11M) -+ -+#define BASIC_RATE_SET_ERP (RATE_SET_BIT_1M | \ -+ RATE_SET_BIT_2M | \ -+ RATE_SET_BIT_5_5M | \ -+ RATE_SET_BIT_11M | \ -+ RATE_SET_BIT_6M | \ -+ RATE_SET_BIT_12M | \ -+ RATE_SET_BIT_24M) -+ -+#define BASIC_RATE_SET_OFDM (RATE_SET_BIT_6M | \ -+ RATE_SET_BIT_12M | \ -+ RATE_SET_BIT_24M) -+ -+#define BASIC_RATE_SET_ERP_P2P (RATE_SET_BIT_6M | \ -+ RATE_SET_BIT_12M | \ -+ RATE_SET_BIT_24M) -+ -+#define INITIAL_RATE_SET_RCPI_100 RATE_SET_ALL_ABG -+ -+#define INITIAL_RATE_SET_RCPI_80 (RATE_SET_BIT_1M | \ -+ RATE_SET_BIT_2M | \ -+ RATE_SET_BIT_5_5M | \ -+ RATE_SET_BIT_11M | \ -+ RATE_SET_BIT_6M | \ -+ RATE_SET_BIT_9M | \ -+ RATE_SET_BIT_12M | \ -+ RATE_SET_BIT_24M) -+ -+#define INITIAL_RATE_SET_RCPI_60 (RATE_SET_BIT_1M | \ -+ RATE_SET_BIT_2M | \ -+ RATE_SET_BIT_5_5M | \ -+ RATE_SET_BIT_11M | \ -+ RATE_SET_BIT_6M) -+ -+#define INITIAL_RATE_SET(_rcpi) (INITIAL_RATE_SET_ ## _rcpi) -+ -+#define RCPI_100 100 /* -60 dBm */ -+#define RCPI_80 80 /* -70 dBm */ -+#define RCPI_60 60 /* -80 dBm */ -+ -+/* The number of RCPI records used to calculate their average value */ -+#define MAX_NUM_RCPI_RECORDS 10 -+ -+/* The number of RCPI records used to calculate their average value */ -+#define NO_RCPI_RECORDS -128 -+#define MAX_RCPI_DBM 0 -+#define MIN_RCPI_DBM -100 -+ -+#define MAC_TX_RESERVED_FIELD 0 /* NOTE(Kevin): Should defined in tx.h */ -+ -+#define MAX_ASSOC_ID (CFG_STA_REC_NUM) /* Available AID: 1 ~ 20(STA_REC_NUM) */ -+ -+#define MAX_DEAUTH_INFO_COUNT 4 /* NOTE(Kevin): Used in auth.c */ -+#define MIN_DEAUTH_INTERVAL_MSEC 500 /* The minimum interval if continuously send Deauth Frame */ -+ -+/* Authentication Type */ -+#define AUTH_TYPE_OPEN_SYSTEM BIT(AUTH_ALGORITHM_NUM_OPEN_SYSTEM) -+#define AUTH_TYPE_SHARED_KEY BIT(AUTH_ALGORITHM_NUM_SHARED_KEY) -+#define AUTH_TYPE_FAST_BSS_TRANSITION BIT(AUTH_ALGORITHM_NUM_FAST_BSS_TRANSITION) -+ -+/* Authentication Retry Limit */ -+#define TX_AUTH_ASSOCI_RETRY_LIMIT 2 -+#define TX_AUTH_ASSOCI_RETRY_LIMIT_FOR_ROAMING 1 -+ -+/* WMM-2.2.1 WMM Information Element */ -+#define ELEM_MAX_LEN_WMM_INFO 7 -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+typedef UINT_16 PHY_TYPE, *P_PHY_TYPE; -+typedef UINT_8 RCPI, *P_RCPI; -+typedef UINT_8 ALC_VAL, *P_ALC_VAL; -+ -+typedef enum _ENUM_HW_BSSID_T { -+ BSSID_0 = 0, -+ BSSID_1, -+ BSSID_NUM -+} ENUM_HW_BSSID_T; -+ -+typedef enum _ENUM_HW_MAC_ADDR_T { -+ MAC_ADDR_0 = 0, -+ MAC_ADDR_1, -+ MAC_ADDR_NUM -+} ENUM_HW_MAC_ADDR_T; -+ -+typedef enum _ENUM_HW_OP_MODE_T { -+ HW_OP_MODE_STA = 0, -+ HW_OP_MODE_AP, -+ HW_OP_MODE_ADHOC, -+ HW_OP_MODE_NUM -+} ENUM_HW_OP_MODE_T; -+ -+typedef enum _ENUM_TSF_T { -+ ENUM_LOCAL_TSF_0, -+ ENUM_LOCAL_TSF_1, -+ ENUM_LOCAL_TSF_NUM -+} ENUM_LOCAL_TSF_T, *P_ENUM_LOCAL_TSF_T; -+ -+typedef enum _HAL_TS_HW_UPDATE_MODE { -+ HAL_TSF_HW_UPDATE_BY_TICK_AND_RECEIVED_FRAME, -+ HAL_TSF_HW_UPDATE_BY_TICK_ONLY, -+ HAL_TSF_HW_UPDATE_BY_RECEIVED_FRAME_ONLY, -+ HAL_TSF_HW_UPDATE_BY_TICK_AND_RECEIVED_FRAME_AD_HOC -+} HAL_TSF_HW_UPDATE_MODE; -+ -+typedef enum _ENUM_AC_T { -+ AC0 = 0, -+ AC1, -+ AC2, -+ AC3, -+ AC_NUM -+} ENUM_AC_T, *P_ENUM_AC_T; -+ -+/* The Type of Network been activated */ -+typedef enum _ENUM_NETWORK_TYPE_INDEX_T { -+ NETWORK_TYPE_AIS_INDEX = 0, -+ NETWORK_TYPE_P2P_INDEX, -+ NETWORK_TYPE_BOW_INDEX, -+ NETWORK_TYPE_INDEX_NUM -+} ENUM_NETWORK_TYPE_INDEX_T; -+ -+/* The Type of STA Type. */ -+typedef enum _ENUM_STA_TYPE_INDEX_T { -+ STA_TYPE_LEGACY_INDEX = 0, -+ STA_TYPE_P2P_INDEX, -+ STA_TYPE_BOW_INDEX, -+ STA_TYPE_INDEX_NUM -+} ENUM_STA_TYPE_INDEX_T; -+ -+#define STA_ROLE_BASE_INDEX 4 -+ -+typedef enum _ENUM_STA_ROLE_INDEX_T { -+ STA_ROLE_ADHOC_INDEX = STA_ROLE_BASE_INDEX, /* 4 */ -+ STA_ROLE_CLIENT_INDEX, -+ STA_ROLE_AP_INDEX, -+ STA_ROLE_TDLS_INDEX, -+ STA_ROLE_DLS_INDEX /* Note: need to extend P_CMD_UPDATE_STA_RECORD_T */ -+} ENUM_STA_ROLE_INDEX_T; -+ -+/* The Power State of a specific Network */ -+typedef enum _ENUM_PWR_STATE_T { -+ PWR_STATE_IDLE = 0, -+ PWR_STATE_ACTIVE, -+ PWR_STATE_PS, -+ PWR_STATE_NUM -+} ENUM_PWR_STATE_T; -+ -+typedef enum _ENUM_PHY_TYPE_INDEX_T { -+ /* PHY_TYPE_DSSS_INDEX, *//* DSSS PHY (clause 15) -- Not used anymore */ -+ PHY_TYPE_HR_DSSS_INDEX = 0, /* HR/DSSS PHY (clause 18) */ -+ PHY_TYPE_ERP_INDEX, /* ERP PHY (clause 19) */ -+ PHY_TYPE_ERP_P2P_INDEX, /* ERP PHY (clause 19) w/o HR/DSSS */ -+ PHY_TYPE_OFDM_INDEX, /* OFDM 5 GHz PHY (clause 17) */ -+ PHY_TYPE_HT_INDEX, /* HT PHY (clause 20) */ -+ PHY_TYPE_INDEX_NUM /* 5 */ -+} ENUM_PHY_TYPE_INDEX_T, *P_ENUM_PHY_TYPE_INDEX_T; -+ -+typedef enum _ENUM_ACPI_STATE_T { -+ ACPI_STATE_D0 = 0, -+ ACPI_STATE_D1, -+ ACPI_STATE_D2, -+ ACPI_STATE_D3 -+} ENUM_ACPI_STATE_T; -+ -+/* The operation mode of a specific Network */ -+typedef enum _ENUM_OP_MODE_T { -+ OP_MODE_INFRASTRUCTURE = 0, /* Infrastructure/GC */ -+ OP_MODE_IBSS, /* AdHoc */ -+ OP_MODE_ACCESS_POINT, /* For GO */ -+ OP_MODE_P2P_DEVICE, /* P2P Device */ -+ OP_MODE_BOW, -+ OP_MODE_NUM -+} ENUM_OP_MODE_T, *P_ENUM_OP_MODE_T; -+ -+typedef enum _ENUM_CHNL_EXT_T { -+ CHNL_EXT_SCN = 0, -+ CHNL_EXT_SCA = 1, -+ CHNL_EXT_RES = 2, -+ CHNL_EXT_SCB = 3 -+} ENUM_CHNL_EXT_T, *P_ENUM_CHNL_EXT_T; -+ -+/* This starting freq of the band is unit of kHz */ -+typedef enum _ENUM_BAND_T { -+ BAND_NULL, -+ BAND_2G4, -+ BAND_5G, -+ BAND_NUM -+} ENUM_BAND_T, *P_ENUM_BAND_T; -+ -+/* Provide supported channel list to other components in array format */ -+typedef struct _RF_CHANNEL_INFO_T { -+ ENUM_BAND_T eBand; -+ UINT_8 ucChannelNum; -+} RF_CHANNEL_INFO_T, *P_RF_CHANNEL_INFO_T; -+ -+typedef enum _ENUM_RATE_INDEX_T { -+ RATE_1M_INDEX = 0, /* 1M */ -+ RATE_2M_INDEX, /* 2M */ -+ RATE_5_5M_INDEX, /* 5.5M */ -+ RATE_11M_INDEX, /* 11M */ -+ RATE_22M_INDEX, /* 22M */ -+ RATE_33M_INDEX, /* 33M */ -+ RATE_6M_INDEX, /* 6M */ -+ RATE_9M_INDEX, /* 9M */ -+ RATE_12M_INDEX, /* 12M */ -+ RATE_18M_INDEX, /* 18M */ -+ RATE_24M_INDEX, /* 24M */ -+ RATE_36M_INDEX, /* 36M */ -+ RATE_48M_INDEX, /* 48M */ -+ RATE_54M_INDEX, /* 54M */ -+ RATE_HT_PHY_INDEX, /* BSS Selector - HT PHY */ -+ RATE_NUM /* 15 */ -+} ENUM_RATE_INDEX_T, *P_ENUM_RATE_INDEX_T; -+ -+typedef enum _ENUM_HT_RATE_INDEX_T { -+ HT_RATE_MCS0_INDEX = 0, -+ HT_RATE_MCS1_INDEX, -+ HT_RATE_MCS2_INDEX, -+ HT_RATE_MCS3_INDEX, -+ HT_RATE_MCS4_INDEX, -+ HT_RATE_MCS5_INDEX, -+ HT_RATE_MCS6_INDEX, -+ HT_RATE_MCS7_INDEX, -+ HT_RATE_MCS32_INDEX, -+ HT_RATE_NUM /* 9 */ -+} ENUM_HT_RATE_INDEX_T, *P_ENUM_HT_RATE_INDEX_T; -+ -+typedef enum _ENUM_PREMABLE_OPTION_T { -+ PREAMBLE_DEFAULT_LONG_NONE = 0, /* LONG for PHY_TYPE_HR_DSSS, NONE for PHY_TYPE_OFDM */ -+ PREAMBLE_OPTION_SHORT, /* SHORT mandatory for PHY_TYPE_ERP, SHORT option for PHY_TYPE_HR_DSSS */ -+ PREAMBLE_HT_MIXED_MODE, -+ PREAMBLE_HT_GREEN_FIELD, -+ PREAMBLE_OPTION_NUM -+} ENUM_PREMABLE_OPTION_T, *P_ENUM_PREMABLE_OPTION_T; -+ -+typedef enum _ENUM_CHANNEL_WIDTH_T { -+ CW_20_40MHZ = 0, -+ CW_80MHZ = 1, -+ CW_160MHZ = 2, -+ CW_80P80MHZ = 3 -+} ENUM_CHANNEL_WIDTH_T, *P_ENUM_CHANNEL_WIDTH_P; -+ -+typedef enum _ENUM_MODULATION_SYSTEM_T { -+ MODULATION_SYSTEM_CCK = 0, -+ MODULATION_SYSTEM_OFDM, -+ MODULATION_SYSTEM_HT20, -+ MODULATION_SYSTEM_HT40, -+ MODULATION_SYSTEM_NUM -+} ENUM_MODULATION_SYSTEM_T, *P_ENUM_MODULATION_SYSTEM_T; -+ -+typedef enum _ENUM_MODULATION_TYPE_T { -+ MODULATION_TYPE_CCK_BPSK = 0, -+ MODULATION_TYPE_QPSK, -+ MODULATION_TYPE_16QAM, -+ MODULATION_TYPE_64QAM, -+ MODULATION_TYPE_NUM -+} ENUM_MODULATION_TYPE_T, *P_ENUM_MODULATION_TYPE_T; -+ -+typedef enum _ENUM_PS_FORWARDING_TYPE_T { -+ PS_FORWARDING_TYPE_NON_PS = 0, -+ PS_FORWARDING_TYPE_DELIVERY_ENABLED, -+ PS_FORWARDING_TYPE_NON_DELIVERY_ENABLED, -+ PS_FORWARDING_MORE_DATA_ENABLED, -+ PS_FORWARDING_TYPE_NUM -+} ENUM_PS_FORWARDING_TYPE_T, *P_ENUM_PS_FORWARDING_TYPE_T; -+ -+typedef struct _DEAUTH_INFO_T { -+ UINT_8 aucRxAddr[MAC_ADDR_LEN]; -+ OS_SYSTIME rLastSendTime; -+} DEAUTH_INFO_T, *P_DEAUTH_INFO_T; -+ -+/*----------------------------------------------------------------------------*/ -+/* Information Element (IE) handlers */ -+/*----------------------------------------------------------------------------*/ -+typedef VOID(*PFN_APPEND_IE_FUNC) (P_ADAPTER_T, P_MSDU_INFO_T); -+typedef VOID(*PFN_HANDLE_IE_FUNC) (P_ADAPTER_T, P_SW_RFB_T, P_IE_HDR_T); -+typedef VOID(*PFN_VERIFY_IE_FUNC) (P_ADAPTER_T, P_SW_RFB_T, P_IE_HDR_T, PUINT_16); -+typedef UINT_32(*PFN_CALCULATE_VAR_IE_LEN_FUNC) (P_ADAPTER_T, ENUM_NETWORK_TYPE_INDEX_T, P_STA_RECORD_T); -+ -+typedef struct _APPEND_IE_ENTRY_T { -+ UINT_16 u2EstimatedIELen; -+ PFN_APPEND_IE_FUNC pfnAppendIE; -+} APPEND_IE_ENTRY_T, *P_APPEND_IE_ENTRY_T; -+ -+typedef struct _APPEND_VAR_IE_ENTRY_T { -+ UINT_16 u2EstimatedFixedIELen; /* For Fixed Length */ -+ PFN_CALCULATE_VAR_IE_LEN_FUNC pfnCalculateVariableIELen; -+ PFN_APPEND_IE_FUNC pfnAppendIE; -+} APPEND_VAR_IE_ENTRY_T, *P_APPEND_VAR_IE_ENTRY_T; -+ -+typedef struct _HANDLE_IE_ENTRY_T { -+ UINT_8 ucElemID; -+ PFN_HANDLE_IE_FUNC pfnHandleIE; -+} HANDLE_IE_ENTRY_T, *P_HANDLE_IE_ENTRY_T; -+ -+typedef struct _VERIFY_IE_ENTRY_T { -+ UINT_8 ucElemID; -+ PFN_VERIFY_IE_FUNC pfnVarifyIE; -+} VERIFY_IE_ENTRY_T, *P_VERIFY_IE_ENTRY_T; -+ -+/*----------------------------------------------------------------------------*/ -+/* Parameters of User Configuration */ -+/*----------------------------------------------------------------------------*/ -+typedef enum _ENUM_PARAM_CONNECTION_POLICY_T { -+ CONNECT_BY_SSID_BEST_RSSI = 0, -+ CONNECT_BY_SSID_GOOD_RSSI_MIN_CH_LOAD, -+ CONNECT_BY_SSID_ANY, /* NOTE(Kevin): Needed by WHQL */ -+ CONNECT_BY_BSSID, -+ CONNECT_BY_CUSTOMIZED_RULE /* NOTE(Kevin): TBD */ -+} ENUM_PARAM_CONNECTION_POLICY_T, *P_ENUM_PARAM_CONNECTION_POLICY_T; -+ -+typedef enum _ENUM_PARAM_PREAMBLE_TYPE_T { -+ PREAMBLE_TYPE_LONG = 0, -+ PREAMBLE_TYPE_SHORT, -+ PREAMBLE_TYPE_AUTO /*!< Try preamble short first, if fail tray preamble long. */ -+} ENUM_PARAM_PREAMBLE_TYPE_T, *P_ENUM_PARAM_PREAMBLE_TYPE_T; -+ -+/* This is enum defined for user to select a phy config listed in combo box */ -+typedef enum _ENUM_PARAM_PHY_CONFIG_T { -+ /*!< Can associated with 802.11abg AP but without n capability, Scan dual band. */ -+ PHY_CONFIG_802_11ABG = 0, -+ PHY_CONFIG_802_11BG, /*!< Can associated with 802_11bg AP, Scan single band and not report 5G BSSs. */ -+ PHY_CONFIG_802_11G, /*!< Can associated with 802_11g only AP, Scan single band and not report 5G BSSs. */ -+ PHY_CONFIG_802_11A, /*!< Can associated with 802_11a only AP, Scan single band and not report 2.4G BSSs. */ -+ PHY_CONFIG_802_11B, /*!< Can associated with 802_11b only AP, Scan single band and not report 5G BSSs. */ -+ PHY_CONFIG_802_11ABGN, /*!< Can associated with 802.11abgn AP, Scan dual band. */ -+ PHY_CONFIG_802_11BGN, /*!< Can associated with 802_11bgn AP, Scan single band and not report 5G BSSs. */ -+ PHY_CONFIG_802_11AN, /*!< Can associated with 802_11an AP, Scan single band and not report 2.4G BSSs. */ -+ PHY_CONFIG_802_11GN, /*!< Can associated with 802_11gn AP, Scan single band and not report 5G BSSs. */ -+ PHY_CONFIG_NUM /* 9 */ -+} ENUM_PARAM_PHY_CONFIG_T, *P_ENUM_PARAM_PHY_CONFIG_T; -+ -+/* This is enum defined for user to select an AP Mode */ -+typedef enum _ENUM_PARAM_AP_MODE_T { -+ AP_MODE_11B = 0, /*!< Create 11b BSS if we support 802.11abg/802.11bg. */ -+ AP_MODE_MIXED_11BG, /*!< Create 11bg mixed BSS if we support 802.11abg/802.11bg/802.11g. */ -+ AP_MODE_11G, /*!< Create 11g only BSS if we support 802.11abg/802.11bg/802.11g. */ -+ AP_MODE_11G_P2P, /*!< Create 11g only BSS for P2P if we support 802.11abg/802.11bg/802.11g. */ -+ AP_MODE_11A, /*!< Create 11a only BSS if we support 802.11abg. */ -+ AP_MODE_NUM /* 4 */ -+} ENUM_PARAM_AP_MODE_T, *P_ENUM_PARAM_AP_MODE_T; -+ -+/* Masks for determining the Network Type or the Station Role, given the ENUM_STA_TYPE_T */ -+#define NETWORK_TYPE_AIS_MASK BIT(NETWORK_TYPE_AIS_INDEX) -+#define NETWORK_TYPE_P2P_MASK BIT(NETWORK_TYPE_P2P_INDEX) -+#define NETWORK_TYPE_BOW_MASK BIT(NETWORK_TYPE_BOW_INDEX) -+#define STA_TYPE_LEGACY_MASK BIT(STA_TYPE_LEGACY_INDEX) -+#define STA_TYPE_P2P_MASK BIT(STA_TYPE_P2P_INDEX) -+#define STA_TYPE_BOW_MASK BIT(STA_TYPE_BOW_INDEX) -+#define STA_TYPE_ADHOC_MASK BIT(STA_ROLE_ADHOC_INDEX) -+#define STA_TYPE_CLIENT_MASK BIT(STA_ROLE_CLIENT_INDEX) -+#define STA_TYPE_AP_MASK BIT(STA_ROLE_AP_INDEX) -+#define STA_TYPE_DLS_MASK BIT(STA_ROLE_DLS_INDEX) -+#define STA_TYPE_TDLS_MASK BIT(STA_ROLE_TDLS_INDEX) -+ -+/* Macros for obtaining the Network Type or the Station Role, given the ENUM_STA_TYPE_T */ -+#define IS_STA_IN_AIS(_prStaRec) ((_prStaRec)->ucNetTypeIndex == NETWORK_TYPE_AIS_INDEX) -+#define IS_STA_IN_P2P(_prStaRec) ((_prStaRec)->ucNetTypeIndex == NETWORK_TYPE_P2P_INDEX) -+#define IS_STA_IN_BOW(_prStaRec) ((_prStaRec)->ucNetTypeIndex == NETWORK_TYPE_BOW_INDEX) -+#define IS_STA_LEGACY_TYPE(_prStaRec) ((_prStaRec->eStaType) & STA_TYPE_LEGACY_MASK) -+#define IS_STA_P2P_TYPE(_prStaRec) ((_prStaRec->eStaType) & STA_TYPE_P2P_MASK) -+#define IS_STA_BOW_TYPE(_prStaRec) ((_prStaRec->eStaType) & STA_TYPE_BOW_MASK) -+#define IS_ADHOC_STA(_prStaRec) ((_prStaRec->eStaType) & STA_TYPE_ADHOC_MASK) -+#define IS_CLIENT_STA(_prStaRec) ((_prStaRec->eStaType) & STA_TYPE_CLIENT_MASK) -+#define IS_AP_STA(_prStaRec) ((_prStaRec->eStaType) & STA_TYPE_AP_MASK) -+#define IS_DLS_STA(_prStaRec) ((_prStaRec->eStaType) & STA_TYPE_DLS_MASK) -+#define IS_TDLS_STA(_prStaRec) ((_prStaRec->eStaType) & STA_TYPE_TDLS_MASK) -+ -+/* The ENUM_STA_TYPE_T accounts for ENUM_NETWORK_TYPE_T and ENUM_STA_ROLE_INDEX_T. -+ * * It is a merged version of Network Type and STA Role. -+ * */ -+typedef enum _ENUM_STA_TYPE_T { -+ STA_TYPE_LEGACY_AP = (STA_TYPE_LEGACY_MASK | STA_TYPE_AP_MASK), -+ STA_TYPE_LEGACY_CLIENT = (STA_TYPE_LEGACY_MASK | STA_TYPE_CLIENT_MASK), -+ STA_TYPE_ADHOC_PEER = (STA_TYPE_LEGACY_MASK | STA_TYPE_ADHOC_MASK), -+#if CFG_ENABLE_WIFI_DIRECT -+ STA_TYPE_P2P_GO = (STA_TYPE_P2P_MASK | STA_TYPE_AP_MASK), -+ STA_TYPE_P2P_GC = (STA_TYPE_P2P_MASK | STA_TYPE_CLIENT_MASK), -+#endif -+#if CFG_ENABLE_BT_OVER_WIFI -+ STA_TYPE_BOW_AP = (STA_TYPE_BOW_MASK | STA_TYPE_AP_MASK), -+ STA_TYPE_BOW_CLIENT = (STA_TYPE_BOW_MASK | STA_TYPE_CLIENT_MASK), -+#endif -+ STA_TYPE_DLS_PEER = (STA_TYPE_LEGACY_MASK | STA_TYPE_DLS_MASK), -+ STA_TYPE_TDLS_PEER = (STA_TYPE_LEGACY_MASK | STA_TYPE_TDLS_MASK) -+} ENUM_STA_TYPE_T, *P_ENUM_STA_TYPE_T; -+ -+/* The type of BSS we discovered */ -+typedef enum _ENUM_BSS_TYPE_T { -+ BSS_TYPE_INFRASTRUCTURE = 1, -+ BSS_TYPE_IBSS, -+ BSS_TYPE_P2P_DEVICE, -+ BSS_TYPE_BOW_DEVICE, -+ BSS_TYPE_NUM -+} ENUM_BSS_TYPE_T, *P_ENUM_BSS_TYPE_T; -+ -+/*----------------------------------------------------------------------------*/ -+/* RSN structures */ -+/*----------------------------------------------------------------------------*/ -+/* #if defined(WINDOWS_DDK) || defined(WINDOWS_CE) */ -+/* #pragma pack(1) */ -+/* #endif */ -+ -+#define MAX_NUM_SUPPORTED_CIPHER_SUITES 8 /* max number of supported cipher suites */ -+#if CFG_SUPPORT_802_11W -+#define MAX_NUM_SUPPORTED_AKM_SUITES 8 /* max number of supported AKM suites */ -+#else -+#define MAX_NUM_SUPPORTED_AKM_SUITES 6 /* max number of supported AKM suites */ -+#endif -+ -+/* Structure of RSN Information */ -+typedef struct _RSN_INFO_T { -+ UINT_8 ucElemId; -+ UINT_16 u2Version; -+ UINT_32 u4GroupKeyCipherSuite; -+ UINT_32 u4PairwiseKeyCipherSuiteCount; -+ UINT_32 au4PairwiseKeyCipherSuite[MAX_NUM_SUPPORTED_CIPHER_SUITES]; -+ UINT_32 u4AuthKeyMgtSuiteCount; -+ UINT_32 au4AuthKeyMgtSuite[MAX_NUM_SUPPORTED_AKM_SUITES]; -+ UINT_16 u2RsnCap; -+ BOOLEAN fgRsnCapPresent; -+} /*__KAL_ATTRIB_PACKED__*/ RSN_INFO_T, *P_RSN_INFO_T; -+ -+#define MAX_NUM_SUPPORTED_WAPI_AKM_SUITES 1 /* max number of supported AKM suites */ -+#define MAX_NUM_SUPPORTED_WAPI_CIPHER_SUITES 1 /* max number of supported cipher suites */ -+ -+/* Structure of WAPI Information */ -+typedef struct _WAPI_INFO_T { -+ UINT_8 ucElemId; -+ UCHAR ucLength; -+ UINT_16 u2Version; -+ UINT_32 u4AuthKeyMgtSuiteCount; -+ UINT_32 au4AuthKeyMgtSuite[MAX_NUM_SUPPORTED_WAPI_AKM_SUITES]; -+ UINT_32 u4PairwiseKeyCipherSuiteCount; -+ UINT_32 au4PairwiseKeyCipherSuite[MAX_NUM_SUPPORTED_WAPI_CIPHER_SUITES]; -+ UINT_32 u4GroupKeyCipherSuite; -+ UINT_16 u2WapiCap; -+ UINT_16 u2Bkid; -+ UINT_8 aucBkid[1][16]; -+} /* __KAL_ATTRIB_PACKED__ */ WAPI_INFO_T, *P_WAPI_INFO_T; -+ -+/* #if defined(WINDOWS_DDK) || defined(WINDOWS_CE) */ -+/* #pragma pack() */ -+/* #endif */ -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ -+typedef struct _P2P_DEVICE_TYPE_T { -+ UINT_16 u2CategoryID; -+ UINT_16 u2SubCategoryID; -+} P2P_DEVICE_TYPE_T, *P_P2P_DEVICE_TYPE_T; -+ -+typedef struct _P2P_DEVICE_DESC_T { -+ LINK_ENTRY_T rLinkEntry; -+ BOOLEAN fgDevInfoValid; -+ UINT_8 aucDeviceAddr[MAC_ADDR_LEN]; /* Device Address. */ -+ UINT_8 aucInterfaceAddr[MAC_ADDR_LEN]; /* Interface Address. */ -+ UINT_8 ucDeviceCapabilityBitmap; -+ UINT_8 ucGroupCapabilityBitmap; -+ UINT_16 u2ConfigMethod; /* Configure Method support. */ -+ P2P_DEVICE_TYPE_T rPriDevType; -+ UINT_8 ucSecDevTypeNum; -+ P2P_DEVICE_TYPE_T arSecDevType[8]; /* Reference to P2P_GC_MAX_CACHED_SEC_DEV_TYPE_COUNT */ -+ UINT_16 u2NameLength; -+ UINT_8 aucName[32]; /* Reference to WPS_ATTRI_MAX_LEN_DEVICE_NAME */ -+ /* TODO: Service Information or PasswordID valid? */ -+} P2P_DEVICE_DESC_T, *P_P2P_DEVICE_DESC_T; -+ -+#endif -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+static const UINT_8 aucRateIndex2RateCode[PREAMBLE_OPTION_NUM][RATE_NUM] = { -+ { /* Long Preamble */ -+ RATE_CCK_1M_LONG, /* RATE_1M_INDEX = 0 */ -+ RATE_CCK_2M_LONG, /* RATE_2M_INDEX */ -+ RATE_CCK_5_5M_LONG, /* RATE_5_5M_INDEX */ -+ RATE_CCK_11M_LONG, /* RATE_11M_INDEX */ -+ RATE_CCK_1M_LONG, /* RATE_22M_INDEX - Not supported */ -+ RATE_CCK_1M_LONG, /* RATE_33M_INDEX - Not supported */ -+ RATE_OFDM_6M, /* RATE_6M_INDEX */ -+ RATE_OFDM_9M, /* RATE_9M_INDEX */ -+ RATE_OFDM_12M, /* RATE_12M_INDEX */ -+ RATE_OFDM_18M, /* RATE_18M_INDEX */ -+ RATE_OFDM_24M, /* RATE_24M_INDEX */ -+ RATE_OFDM_36M, /* RATE_36M_INDEX */ -+ RATE_OFDM_48M, /* RATE_48M_INDEX */ -+ RATE_OFDM_54M, /* RATE_54M_INDEX */ -+ }, -+ { /* Short Preamble */ -+ RATE_CCK_1M_LONG, /* RATE_1M_INDEX = 0 */ -+ RATE_CCK_2M_SHORT, /* RATE_2M_INDEX */ -+ RATE_CCK_5_5M_SHORT, /* RATE_5_5M_INDEX */ -+ RATE_CCK_11M_SHORT, /* RATE_11M_INDEX */ -+ RATE_CCK_1M_LONG, /* RATE_22M_INDEX - Not supported */ -+ RATE_CCK_1M_LONG, /* RATE_33M_INDEX - Not supported */ -+ RATE_OFDM_6M, /* RATE_6M_INDEX */ -+ RATE_OFDM_9M, /* RATE_9M_INDEX */ -+ RATE_OFDM_12M, /* RATE_12M_INDEX */ -+ RATE_OFDM_18M, /* RATE_18M_INDEX */ -+ RATE_OFDM_24M, /* RATE_24M_INDEX */ -+ RATE_OFDM_36M, /* RATE_36M_INDEX */ -+ RATE_OFDM_48M, /* RATE_48M_INDEX */ -+ RATE_OFDM_54M, /* RATE_54M_INDEX */ -+ }, -+ { /* Mixed Mode(Option) */ -+ RATE_MM_MCS_0, /* RATE_MCS0_INDEX, */ -+ RATE_MM_MCS_1, /* RATE_MCS1_INDEX, */ -+ RATE_MM_MCS_2, /* RATE_MCS2_INDEX, */ -+ RATE_MM_MCS_3, /* RATE_MCS3_INDEX, */ -+ RATE_MM_MCS_4, /* RATE_MCS4_INDEX, */ -+ RATE_MM_MCS_5, /* RATE_MCS5_INDEX, */ -+ RATE_MM_MCS_6, /* RATE_MCS6_INDEX, */ -+ RATE_MM_MCS_7, /* RATE_MCS7_INDEX, */ -+ RATE_MM_MCS_32 /* RATE_MCS32_INDEX, */ -+ }, -+ { /* Green Field(Option) */ -+ RATE_GF_MCS_0, /* RATE_MCS0_INDEX, */ -+ RATE_GF_MCS_1, /* RATE_MCS1_INDEX, */ -+ RATE_GF_MCS_2, /* RATE_MCS2_INDEX, */ -+ RATE_GF_MCS_3, /* RATE_MCS3_INDEX, */ -+ RATE_GF_MCS_4, /* RATE_MCS4_INDEX, */ -+ RATE_GF_MCS_5, /* RATE_MCS5_INDEX, */ -+ RATE_GF_MCS_6, /* RATE_MCS6_INDEX, */ -+ RATE_GF_MCS_7, /* RATE_MCS7_INDEX, */ -+ RATE_GF_MCS_32 /* RATE_MCS32_INDEX, */ -+ } -+}; -+ -+static const UINT_8 aucRateTableSize[PREAMBLE_OPTION_NUM] = { -+ RATE_HT_PHY_INDEX, -+ RATE_HT_PHY_INDEX, -+ HT_RATE_NUM, -+ HT_RATE_NUM -+}; -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+/* Macros to get and set the wireless LAN frame fields those are 16/32 bits in -+ length. */ -+#define WLAN_GET_FIELD_16(_memAddr_p, _value_p) \ -+ { \ -+ PUINT_8 __cp = (PUINT_8) (_memAddr_p); \ -+ *(PUINT_16)(_value_p) = ((UINT_16) __cp[0]) | ((UINT_16) __cp[1] << 8); \ -+ } -+ -+#define WLAN_GET_FIELD_BE16(_memAddr_p, _value_p) \ -+ { \ -+ PUINT_8 __cp = (PUINT_8) (_memAddr_p); \ -+ *(PUINT_16)(_value_p) = ((UINT_16) __cp[0] << 8) | ((UINT_16) __cp[1]); \ -+ } -+ -+#define WLAN_GET_FIELD_32(_memAddr_p, _value_p) \ -+ { \ -+ PUINT_8 __cp = (PUINT_8) (_memAddr_p); \ -+ *(PUINT_32)(_value_p) = ((UINT_32) __cp[0]) | ((UINT_32) __cp[1] << 8) | \ -+ ((UINT_32) __cp[2] << 16) | ((UINT_32) __cp[3] << 24); \ -+ } -+ -+#define WLAN_GET_FIELD_64(_memAddr_p, _value_p) \ -+ { \ -+ PUINT_8 __cp = (PUINT_8) (_memAddr_p); \ -+ *(PUINT_64)(_value_p) = \ -+ ((UINT_64) __cp[0]) | ((UINT_64) __cp[1] << 8) | \ -+ ((UINT_64) __cp[2] << 16) | ((UINT_64) __cp[3] << 24) | \ -+ ((UINT_64) __cp[4] << 32) | ((UINT_64) __cp[5] << 40) | \ -+ ((UINT_64) __cp[6] << 48) | ((UINT_64) __cp[7] << 56); \ -+ } -+ -+#define WLAN_SET_FIELD_16(_memAddr_p, _value) \ -+ { \ -+ PUINT_8 __cp = (PUINT_8) (_memAddr_p); \ -+ __cp[0] = (UINT_8) (_value); \ -+ __cp[1] = (UINT_8) ((_value) >> 8); \ -+ } -+ -+#define WLAN_SET_FIELD_BE16(_memAddr_p, _value) \ -+ { \ -+ PUINT_8 __cp = (PUINT_8) (_memAddr_p); \ -+ __cp[0] = (UINT_8) ((_value) >> 8); \ -+ __cp[1] = (UINT_8) (_value); \ -+ } -+ -+#define WLAN_SET_FIELD_32(_memAddr_p, _value) \ -+ { \ -+ PUINT_8 __cp = (PUINT_8) (_memAddr_p); \ -+ __cp[0] = (UINT_8) (_value); \ -+ __cp[1] = (UINT_8) ((_value) >> 8); \ -+ __cp[2] = (UINT_8) ((_value) >> 16); \ -+ __cp[3] = (UINT_8) ((_value) >> 24); \ -+ } -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif /* _WLAN_DEF_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic_cmd_event.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic_cmd_event.h -new file mode 100644 -index 000000000000..aba2e040c194 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic_cmd_event.h -@@ -0,0 +1,2290 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/nic_cmd_event.h#1 -+*/ -+ -+/*! \file "nic_cmd_event.h" -+ \brief This file contains the declairation file of the WLAN OID processing routines -+ of Windows driver for MediaTek Inc. 802.11 Wireless LAN Adapters. -+*/ -+ -+/* -+** Log: nic_cmd_event.h -+ * -+ * 03 29 2012 eason.tsai -+ * [WCXRP00001216] [MT6628 Wi-Fi][Driver]add conditional define -+ * add conditional define. -+ * -+ * 03 04 2012 eason.tsai -+ * NULL -+ * modify the cal fail report code. -+ * -+ * 01 06 2012 wh.su -+ * [WCXRP00001153] [MT6620 Wi-Fi][Driver] Adding the get_ch_list and set_tx_power proto type function -+ * redefine the CMD_ID_SET_TXPWR_CTRL value. -+ * -+ * 01 05 2012 wh.su -+ * [WCXRP00001153] [MT6620 Wi-Fi][Driver] Adding the get_ch_list and set_tx_power proto type function -+ * Adding the related ioctl / wlan oid function to set the Tx power cfg. -+ * -+ * 11 30 2011 cm.chang -+ * [WCXRP00001128] [MT5931 Wi-Fi][FW] Update BB/RF setting based on RF doc v0.7 for LGE spec -+ * 1. Add a new CMD for driver to set device mode -+ * 2. Update calibration parameters -+ * -+ * 11 19 2011 yuche.tsai -+ * NULL -+ * Update RSSI for P2P. -+ * -+ * 11 18 2011 yuche.tsai -+ * NULL -+ * CONFIG P2P support RSSI query, default turned off. -+ * -+ * 11 10 2011 eddie.chen -+ * [WCXRP00001096] [MT6620 Wi-Fi][Driver/FW] Enhance the log function (xlog) -+ * Add TX_DONE status detail information. -+ * -+ * 11 08 2011 tsaiyuan.hsu -+ * [WCXRP00001083] [MT6620 Wi-Fi][DRV]] dump debug counter or frames when debugging is triggered -+ * check if CFG_SUPPORT_SWCR is defined to aoid compiler error. -+ * -+ * 11 07 2011 tsaiyuan.hsu -+ * [WCXRP00001083] [MT6620 Wi-Fi][DRV]] dump debug counter or frames when debugging is triggered -+ * add debug counters and periodically dump counters for debugging. -+ * -+ * 10 26 2011 cp.wu -+ * [WCXRP00001065] [MT6620 Wi-Fi][MT5931][FW][DRV] Adding parameter for controlling -+ * minimum channel dwell time for scanning -+ * add interface for control minimum channel dwell time for scanning. -+ * -+ * 09 20 2011 cm.chang -+ * [WCXRP00000997] [MT6620 Wi-Fi][Driver][FW] Handle change of BSS preamble type and slot time -+ * New CMD definition about RLM parameters -+ * -+ * 08 31 2011 cm.chang -+ * [WCXRP00000969] [MT6620 Wi-Fi][Driver][FW] Channel list for 5G band based on country code -+ * . -+ * -+ * 08 25 2011 chinghwa.yu -+ * [WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm -+ * Add DFS switch. -+ * -+ * 08 24 2011 chinghwa.yu -+ * [WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm -+ * Update RDD test mode cases. -+ * -+ * 08 15 2011 cp.wu -+ * [WCXRP00000851] [MT6628 Wi-Fi][Driver] Add HIFSYS related definition to driver source tree -+ * add MT6628-specific definitions. -+ * -+ * 08 11 2011 cp.wu -+ * [WCXRP00000830] [MT6620 Wi-Fi][Firmware] Use MDRDY counter to detect empty channel for shortening scan time -+ * sparse channel detection: -+ * driver: collect sparse channel information with scan-done event -+ * -+ * 08 09 2011 cp.wu -+ * [WCXRP00000702] [MT5931][Driver] Modify initialization sequence for E1 ASIC -+ * [WCXRP00000913] [MT6620 Wi-Fi] create repository of source code dedicated for MT6620 E6 ASIC -+ * add CCK-DSSS TX-PWR control field in NVRAM and CMD definition for MT5931-MP -+ * -+ * 08 03 2011 terry.wu -+ * [WCXRP00000899] [MT6620] [FW] Reply probe rsp in FW for hotspot mode -+ * Reply Probe Rsp in FW for Hotspot Mode. -+ * -+ * -+ * -+ * 08 03 2011 terry.wu -+ * [WCXRP00000899] [MT6620] [FW] Reply probe rsp in FW for hotspot mode -+ * Reply Probe Rsp in FW for Hotspot Mode. -+ * -+ * -+ * 08 03 2011 terry.wu -+ * [WCXRP00000899] [MT6620] [FW] Reply probe rsp in FW for hotspot mode -+ * Reply Probe Rsp in FW for Hotspot Mode. -+ * -+ * 08 03 2011 terry.wu -+ * [WCXRP00000899] [MT6620] [FW] Reply probe rsp in FW for hotspot mode -+ * Reply Probe Rsp in FW for Hotspot Mode. -+ * -+ * 07 28 2011 chinghwa.yu -+ * [WCXRP00000063] Update BCM CoEx design and settings -+ * Add BWCS cmd and event. -+ * -+ * 07 22 2011 jeffrey.chang -+ * [WCXRP00000864] [MT5931] Add command to adjust OSC stable time -+ * add osc stable time command structure -+ * -+ * 07 22 2011 jeffrey.chang -+ * [WCXRP00000864] [MT5931] Add command to adjust OSC stable time -+ * modify driver to set OSC stable time after f/w download -+ * -+ * 07 18 2011 chinghwa.yu -+ * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm -+ * Add CMD/Event for RDD and BWCS. -+ * -+ * 07 18 2011 cp.wu -+ * [WCXRP00000858] [MT5931][Driver][Firmware] Add support for scan to search for more than -+ * one SSID in a single scanning request -+ * add framework in driver domain for supporting new SCAN_REQ_V2 for more than 1 SSID -+ * support as well as uProbeDelay in NDIS 6.x driver model -+ * -+ * 06 23 2011 cp.wu -+ * [WCXRP00000812] [MT6620 Wi-Fi][Driver] not show NVRAM when there is no valid MAC address in NVRAM content -+ * check with firmware for valid MAC address. -+ * -+ * 06 23 2011 cp.wu -+ * [WCXRP00000798] [MT6620 Wi-Fi][Firmware] Follow-ups for WAPI frequency offset workaround in firmware SCN module -+ * change parameter name from PeerAddr to BSSID -+ * -+ * 06 20 2011 cp.wu -+ * [WCXRP00000798] [MT6620 Wi-Fi][Firmware] Follow-ups for WAPI frequency offset workaround in firmware SCN module -+ * 1. specify target's BSSID when requesting channel privilege. -+ * 2. pass BSSID information to firmware domain -+ * -+ * 06 09 2011 tsaiyuan.hsu -+ * [WCXRP00000760] [MT5931 Wi-Fi][FW] Refine rxmHandleMacRxDone to reduce code size -+ * move send_auth at rxmHandleMacRxDone in firmware to driver to reduce code size. -+ * -+ * 05 27 2011 cp.wu -+ * [WCXRP00000749] [MT6620 Wi-Fi][Driver] Add band edge tx power control to Wi-Fi NVRAM -+ * invoke CMD_ID_SET_EDGE_TXPWR_LIMIT when there is valid data exist in NVRAM content. -+ * -+ * 04 18 2011 terry.wu -+ * [WCXRP00000660] [MT6620 Wi-Fi][Driver] Remove flag CFG_WIFI_DIRECT_MOVED -+ * Remove flag CFG_WIFI_DIRECT_MOVED. -+ * -+ * 03 31 2011 chinglan.wang -+ * [WCXRP00000613] [MT6620 Wi-Fi] [FW] [Driver] BssInfo can get the security mode which is WPA/WPA2/WAPI or not. -+ * . -+ * -+ * 03 18 2011 cm.chang -+ * [WCXRP00000576] [MT6620 Wi-Fi][Driver][FW] Remove P2P compile option in scan req/cancel command -+ * As CR title -+ * -+ * 03 17 2011 yarco.yang -+ * [WCXRP00000569] [MT6620 Wi-Fi][F/W][Driver] Set multicast address support current network usage -+ * . -+ * -+ * 03 07 2011 wh.su -+ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code -+ * rename the define to anti_pviracy. -+ * -+ * 03 05 2011 wh.su -+ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code -+ * add the code to get the check rsponse and indicate to app. -+ * -+ * 03 02 2011 wh.su -+ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code -+ * Add Security check related code. -+ * -+ * 03 02 2011 george.huang -+ * [WCXRP00000504] [MT6620 Wi-Fi][FW] Support Sigma CAPI for power saving related command -+ * Support UAPSD/OppPS/NoA parameter setting -+ * -+ * 02 16 2011 cm.chang -+ * [WCXRP00000447] [MT6620 Wi-Fi][FW] Support new NVRAM update mechanism -+ * . -+ * -+ * 02 10 2011 cp.wu -+ * [WCXRP00000434] [MT6620 Wi-Fi][Driver] Obsolete unused event packet handlers -+ * EVENT_ID_CONNECTION_STATUS has been obsoleted and no need to handle. -+ * -+ * 02 08 2011 eddie.chen -+ * [WCXRP00000426] [MT6620 Wi-Fi][FW/Driver] Add STA aging timeout and defualtHwRatein AP mode -+ * Add event STA agint timeout -+ * -+ * 01 27 2011 tsaiyuan.hsu -+ * [WCXRP00000392] [MT6620 Wi-Fi][Driver] Add Roaming Support -+ * add roaming fsm -+ * 1. not support 11r, only use strength of signal to determine roaming. -+ * 2. not enable CFG_SUPPORT_ROAMING until completion of full test. -+ * 3. in 6620, adopt work-around to avoid sign extension problem of cck of hw -+ * 4. assume that change of link quality in smooth way. -+ * -+ * 01 25 2011 yuche.tsai -+ * [WCXRP00000352] [Volunteer Patch][MT6620][Driver] P2P Statsion Record Client List Issue -+ * Update cmd format of BSS INFO, always sync OwnMac to FW no matter P2P is enabled or not.. -+ * -+ * 01 20 2011 eddie.chen -+ * [WCXRP00000374] [MT6620 Wi-Fi][DRV] SW debug control -+ * Add Oid for sw control debug command -+ * -+ * 01 15 2011 puff.wen -+ * NULL -+ * Add Stress test -+ * -+ * 01 12 2011 cm.chang -+ * [WCXRP00000354] [MT6620 Wi-Fi][Driver][FW] Follow NVRAM bandwidth setting -+ * Sync HT operation element information from host to FW -+ * -+ * 01 12 2011 cm.chang -+ * [WCXRP00000354] [MT6620 Wi-Fi][Driver][FW] Follow NVRAM bandwidth setting -+ * User-defined bandwidth is for 2.4G and 5G individually -+ * -+ * 12 29 2010 eddie.chen -+ * [WCXRP00000322] Add WMM IE in beacon, -+ -+Add per station flow control when STA is in PS -+ -+ * 1) PS flow control event -+ * -+ * 2) WMM IE in beacon, assoc resp, probe resp -+ * -+ * 12 28 2010 cp.wu -+ * [WCXRP00000269] [MT6620 Wi-Fi][Driver][Firmware] Prepare for v1.1 branch release -+ * report EEPROM used flag via NIC_CAPABILITY -+ * -+ * 12 28 2010 cp.wu -+ * [WCXRP00000269] [MT6620 Wi-Fi][Driver][Firmware] Prepare for v1.1 branch release -+ * integrate with 'EEPROM used' flag for reporting correct capability to Engineer Mode/META and other tools -+ * -+ * 12 23 2010 george.huang -+ * [WCXRP00000152] [MT6620 Wi-Fi] AP mode power saving function -+ * 1. update WMM IE parsing, with ASSOC REQ handling -+ * 2. extend U-APSD parameter passing from driver to FW -+ * -+ * 12 07 2010 cm.chang -+ * [WCXRP00000239] MT6620 Wi-Fi][Driver][FW] Merge concurrent branch back to maintrunk -+ * 1. BSSINFO include RLM parameter -+ * 2. free all sta records when network is disconnected -+ * -+ * 12 07 2010 cm.chang -+ * [WCXRP00000238] MT6620 Wi-Fi][Driver][FW] Support regulation domain setting from NVRAM and supplicant -+ * 1. Country code is from NVRAM or supplicant -+ * 2. Change band definition in CMD/EVENT. -+ * -+ * 11 29 2010 cm.chang -+ * [WCXRP00000210] [MT6620 Wi-Fi][Driver][FW] Set RCPI value in STA_REC for -+ * initial TX rate selection of auto-rate algorithm -+ * Sync RCPI of STA_REC to FW as reference of initial TX rate -+ * -+ * 11 08 2010 cm.chang -+ * [WCXRP00000169] [MT6620 Wi-Fi][Driver][FW] Remove unused CNM recover message ID -+ * Remove CNM channel reover message ID -+ * -+ * 11 01 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check -+ * [WCXRP00000150] [MT6620 Wi-Fi][Driver] Add implementation for querying current TX rate from firmware auto rate module -+ * 1) Query link speed (TX rate) from firmware directly with buffering mechanism to reduce overhead -+ * 2) Remove CNM CH-RECOVER event handling -+ * 3) cfg read/write API renamed with kal prefix for unified naming rules. -+ * -+ * 10 26 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check -+ * [WCXRP00000137] [MT6620 Wi-Fi] [FW] Support NIC capability query command -+ * 1) update NVRAM content template to ver 1.02 -+ * 2) add compile option for querying NIC capability (default: off) -+ * 3) modify AIS 5GHz support to run-time option, which could be turned on by registry or NVRAM setting -+ * 4) correct auto-rate compiler error under linux (treat warning as error) -+ * 5) simplify usage of NVRAM and REG_INFO_T -+ * 6) add version checking between driver and firmware -+ * -+ * 10 25 2010 cp.wu -+ * [WCXRP00000133] [MT6620 Wi-Fi] [FW][Driver] Change TX power offset band definition -+ * follow-up for CMD_5G_PWR_OFFSET_T definition change -+ * -+ * 10 20 2010 cp.wu -+ * [WCXRP00000117] [MT6620 Wi-Fi][Driver] Add logic for suspending driver when MT6620 is not responding anymore -+ * use OID_CUSTOM_TEST_MODE as indication for driver reset -+ * by dropping pending TX packets -+ * -+ * 10 20 2010 wh.su -+ * [WCXRP00000124] [MT6620 Wi-Fi] [Driver] Support the dissolve P2P Group -+ * Add the code to support disconnect p2p group -+ * -+ * 09 15 2010 cm.chang -+ * NULL -+ * Add new CMD for TX power, 5G power offset and power parameters -+ * -+ * 09 07 2010 yuche.tsai -+ * NULL -+ * Add a pointer in P2P SCAN RESULT structure. This pointer -+ * is pointed to a IE buffer for this P2p device. -+ * -+ * 09 07 2010 wh.su -+ * NULL -+ * adding the code for beacon/probe req/ probe rsp wsc ie at p2p. -+ * -+ * 09 03 2010 kevin.huang -+ * NULL -+ * Refine #include sequence and solve recursive/nested #include issue -+ * -+ * 08 23 2010 chinghwa.yu -+ * NULL -+ * Update for BOW. -+ * -+ * 08 20 2010 cm.chang -+ * NULL -+ * Migrate RLM code to host from FW -+ * -+ * 08 16 2010 george.huang -+ * NULL -+ * add new CMD ID definition -+ * -+ * 08 16 2010 yuche.tsai -+ * NULL -+ * Add a field in BSS INFO cmd to change interface address for P2P. (switching between Device Addr & Interface Addr) -+ * -+ * 08 12 2010 yuche.tsai -+ * NULL -+ * Add interface address indication when indicate connection status. -+ * It is requested by supplicant to do 4 way handshake. -+ * -+ * 08 07 2010 wh.su -+ * NULL -+ * adding the privacy related code for P2P network -+ * -+ * 08 05 2010 yuche.tsai -+ * NULL -+ * Change data structure for P2P Device scan result, all channel time for scan command. -+ * -+ * 08 04 2010 george.huang -+ * NULL -+ * handle change PS mode OID/ CMD -+ * -+ * 08 04 2010 yarco.yang -+ * NULL -+ * Add TX_AMPDU and ADDBA_REJECT command -+ * -+ * 08 03 2010 george.huang -+ * NULL -+ * handle event for updating NOA parameters indicated from FW -+ * -+ * 08 02 2010 george.huang -+ * NULL -+ * add WMM-PS test related OID/ CMD handlers -+ * -+ * 07 28 2010 cp.wu -+ * NULL -+ * sync. CMD_BSS_INFO structure change to CMD-EVENT v0.15. -+ * -+ * 07 26 2010 yuche.tsai -+ * -+ * Add P2P Device Found Event. -+ * Channel extension option in scan abort command. -+ * -+ * 07 23 2010 cp.wu -+ * -+ * add AIS-FSM handling for beacon timeout event. -+ * -+ * 07 21 2010 yuche.tsai -+ * -+ * Add for P2P Scan Result Parsing & Saving. -+ * -+ * 07 20 2010 george.huang -+ * -+ * DWORD align for the CMD data structure -+ * -+ * 07 20 2010 cp.wu -+ * -+ * pass band information for scan in an efficient way by mapping ENUM_BAND_T into UINT_8.. -+ * -+ * 07 19 2010 wh.su -+ * -+ * update for security supporting. -+ * -+ * 07 19 2010 cm.chang -+ * -+ * Set RLM parameters and enable CNM channel manager -+ * -+ * 07 16 2010 yarco.yang -+ * -+ * 1. Support BSS Absence/Presence Event -+ * 2. Support STA change PS mode Event -+ * 3. Support BMC forwarding for AP mode. -+ * -+ * 07 14 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration. -+ * pass band with channel number information as scan parameter -+ * -+ * 07 14 2010 yarco.yang -+ * -+ * 1. Remove CFG_MQM_MIGRATION -+ * 2. Add CMD_UPDATE_WMM_PARMS command -+ * -+ * 07 09 2010 cp.wu -+ * -+ * reorder members of CMD_SET_BSS_INFO. -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 07 07 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * update prStaRecOfAP with BSS-INFO. -+ * -+ * 07 07 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Support state of STA record change from 1 to 1 -+ * -+ * 07 01 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Support sync command of STA_REC -+ * -+ * 07 01 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * implementation of DRV-SCN and related mailbox message handling. -+ * -+ * 06 30 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * sync. with CMD/EVENT document ver0.07. -+ * -+ * 06 29 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * correct variable naming for 8-bit variable used in CMD_BEACON_TEMPLATE_UPDATE. -+ * -+ * 06 29 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) sync to. CMD/EVENT document v0.03 -+ * 2) simplify DTIM period parsing in scan.c only, bss.c no longer parses it again. -+ * 3) send command packet to indicate FW-PM after -+ * a) 1st beacon is received after AIS has connected to an AP -+ * b) IBSS-ALONE has been created -+ * c) IBSS-MERGE has occurred -+ * -+ * 06 28 2010 george.huang -+ * [WPD00001556]Basic power managemenet function -+ * Create beacon update path, with expose bssUpdateBeaconContent() -+ * -+ * 06 22 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) add command warpper for STA-REC/BSS-INFO sync. -+ * 2) enhance command packet sending procedure for non-oid part -+ * 3) add command packet definitions for STA-REC/BSS-INFO sync. -+ * -+ * 06 21 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add BSS/STA_REC commands for integration. -+ * -+ * 06 21 2010 yarco.yang -+ * [WPD00003837][MT6620]Data Path Refine -+ * Add TX Done Event handle entry -+ * -+ * 06 10 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) eliminate CFG_CMD_EVENT_VERSION_0_9 -+ * 2) when disconnected, indicate nic directly (no event is needed) -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 05 20 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) integrate OID_GEN_NETWORK_LAYER_ADDRESSES with CMD_ID_SET_IP_ADDRESS -+ * 2) buffer statistics data for 2 seconds -+ * 3) use default value for adhoc parameters instead of 0 -+ * -+ * 05 19 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) do not take timeout mechanism for power mode oids -+ * 2) retrieve network type from connection status -+ * 3) after disassciation, set radio state to off -+ * 4) TCP option over IPv6 is supported -+ * -+ * 05 17 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * correct OID_802_11_DISASSOCIATE handling. -+ * -+ * 05 17 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * 1) add timeout handler mechanism for pending command packets -+ * 2) add p2p add/removal key -+ * -+ * 04 13 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * add framework for BT-over-Wi-Fi support. -+ * * * * * * * * * * 1) prPendingCmdInfo is replaced by queue for multiple handler capability -+ * * * * * * * * * * 2) command sequence number is now increased atomically -+ * * * * * * * * * * 3) private data could be hold and taken use for other purpose -+ * -+ * 04 06 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * sync statistics data structure definition with firmware implementation -+ * -+ * 03 30 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * statistics information OIDs are now handled by querying from firmware domain -+ * -+ * 03 26 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * indicate media stream mode after set is done -+ * -+ * 03 26 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * add a temporary flag for integration with CMD/EVENT v0.9. -+ * -+ * 03 25 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) correct OID_802_11_CONFIGURATION with frequency setting behavior. -+ * * the frequency is used for adhoc connection only -+ * * 2) update with SD1 v0.9 CMD/EVENT documentation -+ * -+ * 03 24 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * initial import for Linux port -+ * -+ * 03 22 2010 cp.wu -+ * [WPD00003824][MT6620 Wi-Fi][New Feature] Add support of large scan list -+ * Implement feature needed by CR: WPD00003824: refining association command by pasting scanning result -+ * -+ * 03 19 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) add ACPI D0/D3 state switching support -+ * * * * * * 2) use more formal way to handle interrupt when the status is retrieved from enhanced RX response -+ * -+ * 03 15 2010 kevin.huang -+ * [WPD00003820][MT6620 Wi-Fi] Modify the code for meet the WHQL test -+ * Add event for activate STA_RECORD_T -+ * -+ * 03 03 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * implement custom OID: EEPROM read/write access -+ * -+ * 03 03 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * implement OID_802_3_MULTICAST_LIST oid handling -+ * -+ * 02 26 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * move EVENT_ID_ASSOC_INFO from nic_rx.c to gl_kal_ndis_51.c -+ * 'cause it involves OS dependent data structure handling -+ * -+ * 02 25 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * send CMD_ID_INFRASTRUCTURE when handling OID_802_11_INFRASTRUCTURE_MODE set. -+ * -+ * 02 09 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1. Permanent and current MAC address are now retrieved by CMD/EVENT packets instead of hard-coded address -+ * * * * * 2. follow MSDN defined behavior when associates to another AP -+ * * * * * 3. for firmware download, packet size could be up to 2048 bytes -+ * -+ * 01 27 2010 wh.su -+ * [WPD00003816][MT6620 Wi-Fi] Adding the security support -+ * . -+ * -+ * 01 27 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1. eliminate improper variable in rHifInfo -+ * * * * * * 2. block TX/ordinary OID when RF test mode is engaged -+ * * * * * * 3. wait until firmware finish operation when entering into and leaving from RF test mode -+ * * * * * * 4. correct some HAL implementation -+ * -+ * 01 22 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * implement following 802.11 OIDs: -+ * * * OID_802_11_RSSI, -+ * * * OID_802_11_RSSI_TRIGGER, -+ * * * OID_802_11_STATISTICS, -+ * * * OID_802_11_DISASSOCIATE, -+ * * * OID_802_11_POWER_MODE -+ * -+ * 01 21 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * implement OID_802_11_MEDIA_STREAM_MODE -+ * -+ * 01 21 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * implement OID_802_11_SUPPORTED_RATES / OID_802_11_DESIRED_RATES -+ * -+ * 12 30 2009 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) According to CMD/EVENT documentation v0.8, -+ * * * * * * OID_CUSTOM_TEST_RX_STATUS & OID_CUSTOM_TEST_TX_STATUS is no longer used, -+ * * * * * * and result is retrieved by get ATInfo instead -+ * * * * * * 2) add 4 counter for recording aggregation statistics -+** \main\maintrunk.MT6620WiFiDriver_Prj\20 2009-12-11 18:35:07 GMT mtk02752 -+** add CMD added in CMD/EVEN document v0.8 -+** \main\maintrunk.MT6620WiFiDriver_Prj\19 2009-12-10 16:39:37 GMT mtk02752 -+** eliminate unused definitions -+** \main\maintrunk.MT6620WiFiDriver_Prj\18 2009-12-10 09:55:11 GMT mtk02752 -+** command ID/event ID revised -+** \main\maintrunk.MT6620WiFiDriver_Prj\17 2009-12-09 13:57:37 GMT MTK02468 -+** Added event ids (EVENT_ID_RX_ADDBA and EVENT_ID_RX_DELBA) -+** \main\maintrunk.MT6620WiFiDriver_Prj\16 2009-12-08 17:35:39 GMT mtk02752 -+** + add event ID for EVENT_ID_TEST_STATUS (rf test) -+** \main\maintrunk.MT6620WiFiDriver_Prj\15 2009-12-07 23:01:09 GMT mtk02752 -+** add data structure for RF_TEST -+** \main\maintrunk.MT6620WiFiDriver_Prj\14 2009-12-03 16:22:56 GMT mtk01461 -+** Modify the element - i4RSSI in EVENT of SCAN RESULT -+** \main\maintrunk.MT6620WiFiDriver_Prj\13 2009-11-30 10:54:44 GMT mtk02752 -+** 1st DW of WIFI_CMD_T is shared with HIF_TX_HEADER_T, while 1st DW of WIFI_EVENT_T is shared with HIF_RX_HEADER_T -+** \main\maintrunk.MT6620WiFiDriver_Prj\12 2009-11-26 10:16:58 GMT mtk02752 -+** resync EVENT_CONNECTION_STATUS -+** \main\maintrunk.MT6620WiFiDriver_Prj\11 2009-11-25 21:34:01 GMT mtk02752 -+** sync. EVENT_SCAN_RESULT_T with firmware -+** \main\maintrunk.MT6620WiFiDriver_Prj\10 2009-11-25 21:03:48 GMT mtk02752 -+** refine MGMT_FRAME -+** \main\maintrunk.MT6620WiFiDriver_Prj\9 2009-11-25 18:17:47 GMT mtk02752 -+** refine GL_WLAN_INFO_T for buffering scan result and presume max. ie length = 600 bytes -+** \main\maintrunk.MT6620WiFiDriver_Prj\8 2009-11-24 22:41:20 GMT mtk02752 -+** add EVENT_SCAN_RESULT_T definition -+** \main\maintrunk.MT6620WiFiDriver_Prj\7 2009-11-23 20:29:16 GMT mtk02752 -+** fix typo -+** \main\maintrunk.MT6620WiFiDriver_Prj\6 2009-11-23 14:46:01 GMT mtk02752 -+** add new command/event structure upon CM@SD1's documentation -+** \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-11-13 15:13:40 GMT mtk02752 -+** add command definition for CMD_BUILD_CONNECTION and EVENT_CONNECTION_STATUS -+** \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-05-20 12:22:22 GMT mtk01461 -+** Add SeqNum field to Event Header -+** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-04-29 15:42:11 GMT mtk01461 -+** Update structure of HIF_EVENT_HEADER_T and EVENT_HDR_SIZE -+** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-04-21 12:10:36 GMT mtk01461 -+** Add Common Set CMD Callback for MCR Write and other Set OID -+** \main\maintrunk.MT6620WiFiDriver_Prj\1 2009-04-21 01:40:17 GMT mtk01461 -+** Command Done Handler -+*/ -+#ifndef _NIC_CMD_EVENT_H -+#define _NIC_CMD_EVENT_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+#define CMD_STATUS_SUCCESS 0 -+#define CMD_STATUS_REJECTED 1 -+#define CMD_STATUS_UNKNOWN 2 -+ -+#define EVENT_HDR_SIZE OFFSET_OF(WIFI_EVENT_T, aucBuffer[0]) -+ -+#define MAX_IE_LENGTH (600) -+#define MAX_WSC_IE_LENGTH (400) -+ -+/* Action field in structure CMD_CH_PRIVILEGE_T */ -+#define CMD_CH_ACTION_REQ 0 -+#define CMD_CH_ACTION_ABORT 1 -+ -+/* Status field in structure EVENT_CH_PRIVILEGE_T */ -+#define EVENT_CH_STATUS_GRANT 0 -+ -+#define SCN_PSCAN_SWC_RSSI_WIN_MAX 75 -+#define SCN_PSCAN_SWC_MAX_NUM 8 -+#define SCN_PSCAN_HOTLIST_REPORT_MAX_NUM 8 -+ -+typedef enum _ENUM_CMD_ID_T { -+ CMD_ID_TEST_MODE = 1, /* 0x01 (Set) */ -+ CMD_ID_RESET_REQUEST, /* 0x02 (Set) */ -+ CMD_ID_BUILD_CONNECTION, /* 0x03 (Set) */ -+ CMD_ID_SCAN_REQ_V2, /* 0x04 (Set) */ -+ CMD_ID_NIC_POWER_CTRL, /* 0x05 (Set) */ -+ CMD_ID_POWER_SAVE_MODE, /* 0x06 (Set) */ -+ CMD_ID_LINK_ATTRIB, /* 0x07 (Set) */ -+ CMD_ID_ADD_REMOVE_KEY, /* 0x08 (Set) */ -+ CMD_ID_DEFAULT_KEY_ID, /* 0x09 (Set) */ -+ CMD_ID_INFRASTRUCTURE, /* 0x0a (Set) */ -+ CMD_ID_SET_RX_FILTER, /* 0x0b (Set) */ -+ CMD_ID_DOWNLOAD_BUF, /* 0x0c (Set) */ -+ CMD_ID_WIFI_START, /* 0x0d (Set) */ -+ CMD_ID_CMD_BT_OVER_WIFI, /* 0x0e (Set) */ -+ CMD_ID_SET_MEDIA_CHANGE_DELAY_TIME, /* 0x0f (Set) */ -+ CMD_ID_SEND_ADDBA_RSP, /* 0x10 (Set) */ -+ CMD_ID_WAPI_MODE, /* 0x11 (Set) (obsolete) */ -+ CMD_ID_WAPI_ASSOC_INFO, /* 0x12 (Set) (obsolete) */ -+ CMD_ID_SET_DOMAIN_INFO, /* 0x13 (Set) */ -+ CMD_ID_SET_IP_ADDRESS, /* 0x14 (Set) */ -+ CMD_ID_BSS_ACTIVATE_CTRL, /* 0x15 (Set) */ -+ CMD_ID_SET_BSS_INFO, /* 0x16 (Set) */ -+ CMD_ID_UPDATE_STA_RECORD, /* 0x17 (Set) */ -+ CMD_ID_REMOVE_STA_RECORD, /* 0x18 (Set) */ -+ CMD_ID_INDICATE_PM_BSS_CREATED, /* 0x19 (Set) */ -+ CMD_ID_INDICATE_PM_BSS_CONNECTED, /* 0x1a (Set) */ -+ CMD_ID_INDICATE_PM_BSS_ABORT, /* 0x1b (Set) */ -+ CMD_ID_UPDATE_BEACON_CONTENT, /* 0x1c (Set) */ -+ CMD_ID_SET_BSS_RLM_PARAM, /* 0x1d (Set) */ -+ CMD_ID_SCAN_REQ, /* 0x1e (Set) */ -+ CMD_ID_SCAN_CANCEL, /* 0x1f (Set) */ -+ CMD_ID_CH_PRIVILEGE, /* 0x20 (Set) */ -+ CMD_ID_UPDATE_WMM_PARMS, /* 0x21 (Set) */ -+ CMD_ID_SET_WMM_PS_TEST_PARMS, /* 0x22 (Set) */ -+ CMD_ID_TX_AMPDU, /* 0x23 (Set) */ -+ CMD_ID_ADDBA_REJECT, /* 0x24 (Set) */ -+ CMD_ID_SET_PS_PROFILE_ADV, /* 0x25 (Set) */ -+ CMD_ID_SET_RAW_PATTERN, /* 0x26 (Set) */ -+ CMD_ID_CONFIG_PATTERN_FUNC, /* 0x27 (Set) */ -+ CMD_ID_SET_TX_PWR, /* 0x28 (Set) */ -+ CMD_ID_SET_5G_PWR_OFFSET, /* 0x29 (Set) */ -+ CMD_ID_SET_PWR_PARAM, /* 0x2A (Set) */ -+ CMD_ID_P2P_ABORT, /* 0x2B (Set) */ -+#if CFG_STRESS_TEST_SUPPORT -+ CMD_ID_RANDOM_RX_RESET_EN = 0x2C, /* 0x2C (Set ) */ -+ CMD_ID_RANDOM_RX_RESET_DE = 0x2D, /* 0x2D (Set ) */ -+ CMD_ID_SAPP_EN = 0x2E, /* 0x2E (Set ) */ -+ CMD_ID_SAPP_DE = 0x2F, /* 0x2F (Set ) */ -+#endif -+ CMD_ID_ROAMING_TRANSIT = 0x30, /* 0x30 (Set) */ -+ CMD_ID_SET_PHY_PARAM, /* 0x31 (Set) */ -+ CMD_ID_SET_NOA_PARAM, /* 0x32 (Set) */ -+ CMD_ID_SET_OPPPS_PARAM, /* 0x33 (Set) */ -+ CMD_ID_SET_UAPSD_PARAM, /* 0x34 (Set) */ -+ CMD_ID_SET_SIGMA_STA_SLEEP, /* 0x35 (Set) */ -+ CMD_ID_SET_EDGE_TXPWR_LIMIT, /* 0x36 (Set) */ -+ CMD_ID_SET_DEVICE_MODE, /* 0x37 (Set) */ -+ CMD_ID_SET_TXPWR_CTRL, /* 0x38 (Set) */ -+ CMD_ID_SET_AUTOPWR_CTRL, /* 0x39 (Set) */ -+ CMD_ID_SET_WFD_CTRL, /* 0x3A (Set) */ -+ CMD_ID_SET_5G_EDGE_TXPWR_LIMIT, /* 0x3B (Set) */ -+ CMD_ID_SET_RSSI_COMPENSATE, /* 0x3C (Set) */ -+ CMD_ID_SET_BAND_SUPPORT = 0x3D, /* 0x3D (Set) */ -+ CMD_ID_SET_NLO_REQ, /* 0x3E (Set) */ -+ CMD_ID_SET_NLO_CANCEL, /* 0x3F (Set) */ -+ CMD_ID_SET_BATCH_REQ, /* 0x40 (Set) */ -+ CMD_ID_SET_WOWLAN, /* 0x41 (Set) */ /*CFG_SUPPORT_WOWLAN */ -+ CMD_ID_GET_PSCAN_CAPABILITY = 0x42, /* 0x42 (Set) */ -+ CMD_ID_SET_PSCN_ENABLE = 0x43, /* 0x43 (Set) */ -+ CMD_ID_SET_PSCAN_PARAM = 0x44, /* 0x44 (Set) */ -+ CMD_ID_SET_PSCN_ADD_HOTLIST_BSSID = 0x45, /* 0x45 (Set) */ -+ CMD_ID_SET_PSCN_ADD_SW_BSSID = 0x46, /* 0x46 (Set) */ -+ CMD_ID_SET_PSCN_MAC_ADDR = 0x47, /* 0x47 (Set) */ -+ CMD_ID_GET_GSCN_SCN_RESULT = 0x48, /* 0x48 (Get) */ -+ CMD_ID_SET_COUNTRY_POWER_LIMIT = 0x4A, /* 0x4A (Set) */ -+ CMD_ID_SET_SYSTEM_SUSPEND = 0x60, /* 0x60 (Set) */ -+ CMD_ID_GET_NIC_CAPABILITY = 0x80, /* 0x80 (Query) */ -+ CMD_ID_GET_LINK_QUALITY, /* 0x81 (Query) */ -+ CMD_ID_GET_STATISTICS, /* 0x82 (Query) */ -+ CMD_ID_GET_CONNECTION_STATUS, /* 0x83 (Query) */ -+ CMD_ID_GET_ASSOC_INFO, /* 0x84 (Query) (obsolete) */ -+ CMD_ID_GET_STA_STATISTICS = 0x85, /* 0x85 (Query) */ -+ CMD_ID_GET_DEBUG_CODE = 0x86, /* 0x86 (Query) */ -+ CMD_ID_GET_LTE_CHN = 0x87, /* 0x87 (Query) */ -+ CMD_ID_GET_CHN_LOADING = 0x88, /* 0x88 (Query) */ -+ CMD_ID_GET_STATISTICS_PL = 0x89, /* 0x87 (Query) */ -+ CMD_ID_BASIC_CONFIG = 0xc1, /* 0xc1 (Set / Query) */ -+ CMD_ID_ACCESS_REG, /* 0xc2 (Set / Query) */ -+ CMD_ID_MAC_MCAST_ADDR, /* 0xc3 (Set / Query) */ -+ CMD_ID_802_11_PMKID, /* 0xc4 (Set / Query) */ -+ CMD_ID_ACCESS_EEPROM, /* 0xc5 (Set / Query) */ -+ CMD_ID_SW_DBG_CTRL, /* 0xc6 (Set / Query) */ -+#if 1 /* CFG_SUPPORT_ANTI_PIRACY */ -+ CMD_ID_SEC_CHECK, /* 0xc7 (Set / Query) */ -+#endif -+ CMD_ID_DUMP_MEM, /* 0xc8 (Query) */ -+ -+ CMD_ID_CHIP_CONFIG = 0xCA, /* 0xca (Set / Query) */ -+ -+#if CFG_SUPPORT_RDD_TEST_MODE -+ CMD_ID_SET_RDD_CH = 0xE1, -+#endif -+ -+ CMD_ID_SET_BWCS = 0xF1, -+ CMD_ID_SET_ROAMING_INFO = 0xF3, -+ -+#if CFG_SUPPORT_BUILD_DATE_CODE -+ CMD_ID_GET_BUILD_DATE_CODE = 0xF8, -+#endif -+ CMD_ID_GET_BSS_INFO = 0xF9, -+#if 1 /* CFG_SUPPORT_HOTSPOT_OPTIMIZATION */ -+ CMD_ID_SET_HOTSPOT_OPTIMIZATION = 0xFA, /* 0xFA (Set) */ -+#endif -+ -+ CMD_ID_TDLS_CORE = 0xFC, -+ CMD_ID_STATS = 0xFD, -+ CMD_ID_TX_AR_ERR_CONFIG = 0xFF -+} ENUM_CMD_ID_T, *P_ENUM_CMD_ID_T; -+ -+typedef enum _ENUM_EVENT_ID_T { -+ EVENT_ID_CMD_RESULT = 1, /* 0x01 (Query) */ -+ EVENT_ID_NIC_CAPABILITY, /* 0x02 (Query) */ -+ EVENT_ID_CONNECTION_STATUS, /* 0x03 (Query / Unsolicited) (obsolete) */ -+ EVENT_ID_SCAN_RESULT, /* 0x04 (Query / Unsolicited) (obselete) */ -+ EVENT_ID_LINK_QUALITY, /* 0x05 (Query / Unsolicited) */ -+ EVENT_ID_STATISTICS, /* 0x06 (Query) */ -+ EVENT_ID_MIC_ERR_INFO, /* 0x07 (Unsolicited) */ -+ EVENT_ID_ASSOC_INFO, /* 0x08 (Query - CMD_ID_GET_ASSOC_INFO) */ -+ EVENT_ID_BASIC_CONFIG, /* 0x09 (Query - CMD_ID_BASIC_CONFIG) */ -+ EVENT_ID_ACCESS_REG, /* 0x0a (Query - CMD_ID_ACCESS_REG) */ -+ EVENT_ID_MAC_MCAST_ADDR, /* 0x0b (Query - CMD_ID_MAC_MCAST_ADDR) */ -+ EVENT_ID_802_11_PMKID, /* 0x0c (Query - CMD_ID_802_11_PMKID) */ -+ EVENT_ID_ACCESS_EEPROM, /* 0x0d (Query - CMD_ID_ACCESS_EEPROM) */ -+ EVENT_ID_SLEEPY_NOTIFY, /* 0x0e (Query) */ -+ EVENT_ID_BT_OVER_WIFI, /* 0x0f (Unsolicited) */ -+ EVENT_ID_TEST_STATUS, /* 0x10 (Query - CMD_ID_TEST_MODE) */ -+ EVENT_ID_RX_ADDBA, /* 0x11 (Unsolicited) (obsolete) */ -+ EVENT_ID_RX_DELBA, /* 0x12 (Unsolicited) (obsolete) */ -+ EVENT_ID_ACTIVATE_STA_REC_T, /* 0x13 (Unsolicited) */ -+ EVENT_ID_DEACTIVATE_STA_REC_T, /* 0x14 (Unsolicited) */ -+ EVENT_ID_SCAN_DONE, /* 0x15 (Unsoiicited) */ -+ EVENT_ID_RX_FLUSH, /* 0x16 (Unsolicited) */ -+ EVENT_ID_TX_DONE, /* 0x17 (Unsolicited) */ -+ EVENT_ID_CH_PRIVILEGE, /* 0x18 (Unsolicited) */ -+ EVENT_ID_BSS_ABSENCE_PRESENCE = 0x19, /* 0x19 (Unsolicited) */ -+ EVENT_ID_STA_CHANGE_PS_MODE, /* 0x1A (Unsolicited) */ -+ EVENT_ID_BSS_BEACON_TIMEOUT, /* 0x1B (Unsolicited) */ -+ EVENT_ID_UPDATE_NOA_PARAMS, /* 0x1C (Unsolicited) */ -+ EVENT_ID_AP_OBSS_STATUS, /* 0x1D (Unsolicited) */ -+ EVENT_ID_STA_UPDATE_FREE_QUOTA, /* 0x1E (Unsolicited) */ -+ EVENT_ID_SW_DBG_CTRL, /* 0x1F (Query - CMD_ID_SW_DBG_CTRL) */ -+ EVENT_ID_ROAMING_STATUS, /* 0x20 (Unsolicited) */ -+ EVENT_ID_STA_AGING_TIMEOUT, /* 0x21 (Unsolicited) */ -+#if 1 /* CFG_SUPPORT_ANTI_PIRACY */ -+ EVENT_ID_SEC_CHECK_RSP, /* 0x22 (Unsolicited) */ -+#endif -+ EVENT_ID_SEND_DEAUTH, /* 0x23 (Unsolicited) */ -+ -+#if CFG_SUPPORT_RDD_TEST_MODE -+ EVENT_ID_UPDATE_RDD_STATUS, /* 0x24 (Unsolicited) */ -+#endif -+ -+#if CFG_SUPPORT_BCM && CFG_SUPPORT_BCM_BWCS -+ EVENT_ID_UPDATE_BWCS_STATUS = 0x25, /* 0x25 (Unsolicited) */ -+ EVENT_ID_UPDATE_BCM_DEBUG, /* 0x26 (Unsolicited) */ -+#endif -+ EVENT_ID_RX_ERR, -+ EVENT_ID_DUMP_MEM, -+ EVENT_ID_STA_STATISTICS = 0x29, /* 0x29 (Query ) */ -+ EVENT_ID_STA_STATISTICS_UPDATE, /* 0x2A (Unsolicited) */ -+ EVENT_ID_NLO_DONE = 0x2b, -+ -+ EVENT_ID_GSCAN_CAPABILITY = 0x30, -+ EVENT_ID_GSCAN_SCAN_COMPLETE = 0x31, -+ EVENT_ID_GSCAN_FULL_RESULT = 0x32, -+ EVENT_ID_GSCAN_SIGNIFICANT_CHANGE = 0x33, -+ EVENT_ID_GSCAN_GEOFENCE_FOUND = 0x34, -+ EVENT_ID_GSCAN_SCAN_AVAILABLE = 0x35, -+ EVENT_ID_GSCAN_RESULT = 0x36, -+ EVENT_ID_BATCH_RESULT = 0x37, -+ -+ EVENT_ID_TDLS = 0x80, -+ EVENT_ID_STATS_ENV = 0x81, -+ -+#if CFG_SUPPORT_BUILD_DATE_CODE -+ EVENT_ID_BUILD_DATE_CODE = 0xF8, -+#endif -+ EVENT_ID_GET_AIS_BSS_INFO = 0xF9, -+ EVENT_ID_DEBUG_CODE = 0xFB, -+ EVENT_ID_RFTEST_READY = 0xFC, /* 0xFC */ -+ EVENT_ID_TX_DONE_STATUS = 0xFD, -+ EVENT_ID_FW_LOG_ENV = 0xFE, /* 0xFE, FW real time debug log */ -+} ENUM_EVENT_ID_T, *P_ENUM_EVENT_ID_T; -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+#ifndef LINUX -+typedef UINT_8 CMD_STATUS; -+#endif -+ -+typedef struct _EVENT_TX_DONE_STATUS_T { -+ UINT_8 ucPacketSeq; -+ UINT_8 ucStatus; -+ UINT_16 u2SequenceNumber; -+ UINT_32 au4Reserved1; -+ UINT_32 au4Reserved2; -+ UINT_32 au4Reserved3; -+ UINT_32 u4PktBufInfo; -+ UINT_8 aucPktBuf[200]; -+} EVENT_TX_DONE_STATUS_T, *P_EVENT_TX_DONE_STATUS_T; -+ -+/* for Event Packet (via HIF-RX) */ -+ /* following CM's documentation v0.7 */ -+typedef struct _WIFI_CMD_T { -+ UINT_16 u2TxByteCount_UserPriority; -+ UINT_8 ucEtherTypeOffset; -+ UINT_8 ucResource_PktType_CSflags; -+ UINT_8 ucCID; -+ UINT_8 ucSetQuery; -+ UINT_8 ucSeqNum; -+ UINT_8 aucReserved2; -+ -+ UINT_8 aucBuffer[0]; -+} WIFI_CMD_T, *P_WIFI_CMD_T; -+ -+/* for Command Packet (via HIF-TX) */ -+ /* following CM's documentation v0.7 */ -+typedef struct _WIFI_EVENT_T { -+ UINT_16 u2PacketLen; -+ UINT_16 u2PacketType; -+ UINT_8 ucEID; -+ UINT_8 ucSeqNum; -+ UINT_8 aucReserved2[2]; -+ -+ UINT_8 aucBuffer[0]; -+} WIFI_EVENT_T, *P_WIFI_EVENT_T; -+ -+/* CMD_ID_TEST_MODE */ -+typedef struct _CMD_TEST_CTRL_T { -+ UINT_8 ucAction; -+ UINT_8 aucReserved[3]; -+ union { -+ UINT_32 u4OpMode; -+ UINT_32 u4ChannelFreq; -+ PARAM_MTK_WIFI_TEST_STRUCT_T rRfATInfo; -+ } u; -+} CMD_TEST_CTRL_T, *P_CMD_TEST_CTRL_T; -+ -+/* EVENT_TEST_STATUS */ -+typedef struct _PARAM_CUSTOM_RFTEST_TX_STATUS_STRUCT_T { -+ UINT_32 u4PktSentStatus; -+ UINT_32 u4PktSentCount; -+ UINT_16 u2AvgAlc; -+ UINT_8 ucCckGainControl; -+ UINT_8 ucOfdmGainControl; -+} PARAM_CUSTOM_RFTEST_TX_STATUS_STRUCT_T, *P_PARAM_CUSTOM_RFTEST_TX_STATUS_STRUCT_T; -+ -+typedef struct _PARAM_CUSTOM_RFTEST_RX_STATUS_STRUCT_T { -+ UINT_32 u4IntRxOk; /*!< number of packets that Rx ok from interrupt */ -+ UINT_32 u4IntCrcErr; /*!< number of packets that CRC error from interrupt */ -+ UINT_32 u4IntShort; /*!< number of packets that is short preamble from interrupt */ -+ UINT_32 u4IntLong; /*!< number of packets that is long preamble from interrupt */ -+ UINT_32 u4PauRxPktCount; /*!< number of packets that Rx ok from PAU */ -+ UINT_32 u4PauCrcErrCount; /*!< number of packets that CRC error from PAU */ -+ UINT_32 u4PauRxFifoFullCount; /*!< number of packets that is short preamble from PAU */ -+ UINT_32 u4PauCCACount; /*!< CCA rising edge count */ -+} PARAM_CUSTOM_RFTEST_RX_STATUS_STRUCT_T, *P_PARAM_CUSTOM_RFTEST_RX_STATUS_STRUCT_T; -+ -+typedef union _EVENT_TEST_STATUS { -+ PARAM_MTK_WIFI_TEST_STRUCT_T rATInfo; -+/* PARAM_CUSTOM_RFTEST_TX_STATUS_STRUCT_T rTxStatus; */ -+/* PARAM_CUSTOM_RFTEST_RX_STATUS_STRUCT_T rRxStatus; */ -+} EVENT_TEST_STATUS, *P_EVENT_TEST_STATUS; -+ -+/* CMD_BUILD_CONNECTION */ -+typedef struct _CMD_BUILD_CONNECTION { -+ UINT_8 ucInfraMode; -+ UINT_8 ucAuthMode; -+ UINT_8 ucEncryptStatus; -+ UINT_8 ucSsidLen; -+ UINT_8 aucSsid[PARAM_MAX_LEN_SSID]; -+ UINT_8 aucBssid[PARAM_MAC_ADDR_LEN]; -+ -+ /* Ad-hoc mode */ -+ UINT_16 u2BeaconPeriod; -+ UINT_16 u2ATIMWindow; -+ UINT_8 ucJoinOnly; -+ UINT_8 ucReserved; -+ UINT_32 u4FreqInKHz; -+ -+ /* for faster connection */ -+ UINT_8 aucScanResult[0]; -+} CMD_BUILD_CONNECTION, *P_CMD_BUILD_CONNECTION; -+ -+/* CMD_ADD_REMOVE_KEY */ -+typedef struct _CMD_802_11_KEY { -+ UINT_8 ucAddRemove; -+ UINT_8 ucTxKey; -+ UINT_8 ucKeyType; -+ UINT_8 ucIsAuthenticator; -+ UINT_8 aucPeerAddr[6]; -+ UINT_8 ucNetType; -+ UINT_8 ucAlgorithmId; -+ UINT_8 ucKeyId; -+ UINT_8 ucKeyLen; -+ UINT_8 aucReverved[2]; -+ UINT_8 aucKeyMaterial[32]; -+ UINT_8 aucKeyRsc[16]; -+} CMD_802_11_KEY, *P_CMD_802_11_KEY; -+ -+/* WPA2 PMKID cache structure */ -+typedef struct _PMKID_ENTRY_T { -+ PARAM_BSSID_INFO_T rBssidInfo; -+ BOOLEAN fgPmkidExist; -+} PMKID_ENTRY_T, *P_PMKID_ENTRY_T; -+ -+typedef struct _CMD_802_11_PMKID { -+ ULONG u4BSSIDInfoCount; -+ P_PMKID_ENTRY_T arPMKIDInfo[1]; -+} CMD_802_11_PMKID, *P_CMD_802_11_PMKID; -+ -+/* CMD_BASIC_CONFIG */ -+typedef struct _CMD_CSUM_OFFLOAD { -+ UINT_16 u2RxChecksum; /* bit0: IP, bit1: UDP, bit2: TCP */ -+ UINT_16 u2TxChecksum; /* bit0: IP, bit1: UDP, bit2: TCP */ -+} CMD_CSUM_OFFLOAD, *P_CMD_CSUM_OFFLOAD; -+ -+typedef struct _CMD_BASIC_CONFIG { -+ PARAM_MAC_ADDRESS rMyMacAddr; -+ UINT_8 ucNative80211; -+ UINT_8 aucReserved[1]; -+ -+ CMD_CSUM_OFFLOAD rCsumOffload; -+} CMD_BASIC_CONFIG, *P_CMD_BASIC_CONFIG, EVENT_BASIC_CONFIG, *P_EVENT_BASIC_CONFIG; -+ -+/* CMD_MAC_MCAST_ADDR */ -+typedef struct _CMD_MAC_MCAST_ADDR { -+ UINT_32 u4NumOfGroupAddr; -+ UINT_8 ucNetTypeIndex; -+ UINT_8 aucReserved[3]; -+ PARAM_MAC_ADDRESS arAddress[MAX_NUM_GROUP_ADDR]; -+} CMD_MAC_MCAST_ADDR, *P_CMD_MAC_MCAST_ADDR, EVENT_MAC_MCAST_ADDR, *P_EVENT_MAC_MCAST_ADDR; -+ -+/* CMD_ACCESS_EEPROM */ -+typedef struct _CMD_ACCESS_EEPROM { -+ UINT_16 u2Offset; -+ UINT_16 u2Data; -+} CMD_ACCESS_EEPROM, *P_CMD_ACCESS_EEPROM, EVENT_ACCESS_EEPROM, *P_EVENT_ACCESS_EEPROM; -+ -+typedef struct _CMD_CUSTOM_NOA_PARAM_STRUCT_T { -+ UINT_32 u4NoaDurationMs; -+ UINT_32 u4NoaIntervalMs; -+ UINT_32 u4NoaCount; -+} CMD_CUSTOM_NOA_PARAM_STRUCT_T, *P_CMD_CUSTOM_NOA_PARAM_STRUCT_T; -+ -+typedef struct _CMD_CUSTOM_OPPPS_PARAM_STRUCT_T { -+ UINT_32 u4CTwindowMs; -+} CMD_CUSTOM_OPPPS_PARAM_STRUCT_T, *P_CMD_CUSTOM_OPPPS_PARAM_STRUCT_T; -+ -+typedef struct _CMD_CUSTOM_UAPSD_PARAM_STRUCT_T { -+ UINT_8 fgEnAPSD; -+ UINT_8 fgEnAPSD_AcBe; -+ UINT_8 fgEnAPSD_AcBk; -+ UINT_8 fgEnAPSD_AcVo; -+ UINT_8 fgEnAPSD_AcVi; -+ UINT_8 ucMaxSpLen; -+ UINT_8 aucResv[2]; -+} CMD_CUSTOM_UAPSD_PARAM_STRUCT_T, *P_CMD_CUSTOM_UAPSD_PARAM_STRUCT_T; -+ -+/* EVENT_CONNECTION_STATUS */ -+typedef struct _EVENT_CONNECTION_STATUS { -+ UINT_8 ucMediaStatus; -+ UINT_8 ucReasonOfDisconnect; -+ -+ UINT_8 ucInfraMode; -+ UINT_8 ucSsidLen; -+ UINT_8 aucSsid[PARAM_MAX_LEN_SSID]; -+ UINT_8 aucBssid[PARAM_MAC_ADDR_LEN]; -+ UINT_8 ucAuthenMode; -+ UINT_8 ucEncryptStatus; -+ UINT_16 u2BeaconPeriod; -+ UINT_16 u2AID; -+ UINT_16 u2ATIMWindow; -+ UINT_8 ucNetworkType; -+ UINT_8 aucReserved[1]; -+ UINT_32 u4FreqInKHz; -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ UINT_8 aucInterfaceAddr[PARAM_MAC_ADDR_LEN]; -+#endif -+ -+} EVENT_CONNECTION_STATUS, *P_EVENT_CONNECTION_STATUS; -+ -+/* EVENT_NIC_CAPABILITY */ -+typedef struct _EVENT_NIC_CAPABILITY { -+ UINT_16 u2ProductID; -+ UINT_16 u2FwVersion; -+ UINT_16 u2DriverVersion; -+ UINT_8 ucHw5GBandDisabled; -+ UINT_8 ucEepromUsed; -+ UINT_8 ucEfuseValid; -+ UINT_8 ucMacAddrValid; -+#if CFG_REPORT_RFBB_VERSION -+ UINT_8 ucRfVersion; -+ UINT_8 ucPhyVersion; -+#endif -+#if CFG_ENABLE_CAL_LOG -+ UINT_8 ucRfCalFail; -+ UINT_8 ucBbCalFail; -+#endif -+ -+#define FEATURE_SET_OFFSET_TDLS 0 -+#define FEATURE_SET_OFFSET_5G_SUPPORT 1 -+ UINT_8 ucFeatureSet; /* bit0: TDLS */ -+ -+ UINT_8 aucReserved[1]; -+#if CFG_EMBED_FIRMWARE_BUILD_DATE_CODE -+ UINT_8 aucDateCode[16]; -+#endif -+} EVENT_NIC_CAPABILITY, *P_EVENT_NIC_CAPABILITY; -+ -+/* modified version of WLAN_BEACON_FRAME_BODY_T for simplier buffering */ -+typedef struct _WLAN_BEACON_FRAME_BODY_T_LOCAL { -+ /* Beacon frame body */ -+ UINT_32 au4Timestamp[2]; /* Timestamp */ -+ UINT_16 u2BeaconInterval; /* Beacon Interval */ -+ UINT_16 u2CapInfo; /* Capability */ -+ UINT_8 aucInfoElem[MAX_IE_LENGTH]; /* Various IEs, start from SSID */ -+ UINT_16 u2IELength; /* This field is *NOT* carried by F/W but caculated by nic_rx */ -+} WLAN_BEACON_FRAME_BODY_T_LOCAL, *P_WLAN_BEACON_FRAME_BODY_T_LOCAL; -+ -+/* EVENT_SCAN_RESULT */ -+typedef struct _EVENT_SCAN_RESULT_T { -+ INT_32 i4RSSI; -+ UINT_32 u4LinkQuality; -+ UINT_32 u4DSConfig; /* Center frequency */ -+ UINT_32 u4DomainInfo; /* Require CM opinion */ -+ UINT_32 u4Reserved; -+ UINT_8 ucNetworkType; -+ UINT_8 ucOpMode; -+ UINT_8 aucBssid[MAC_ADDR_LEN]; -+ UINT_8 aucRatesEx[PARAM_MAX_LEN_RATES_EX]; -+ WLAN_BEACON_FRAME_BODY_T_LOCAL rBeaconFrameBody; -+} EVENT_SCAN_RESULT_T, *P_EVENT_SCAN_RESULT_T; -+ -+/* event of tkip mic error */ -+typedef struct _EVENT_MIC_ERR_INFO { -+ UINT_32 u4Flags; -+} EVENT_MIC_ERR_INFO, *P_EVENT_MIC_ERR_INFO; -+ -+typedef struct _EVENT_PMKID_CANDIDATE_LIST_T { -+ UINT_32 u4Version; /*!< Version */ -+ UINT_32 u4NumCandidates; /*!< How many candidates follow */ -+ PARAM_PMKID_CANDIDATE_T arCandidateList[1]; -+} EVENT_PMKID_CANDIDATE_LIST_T, *P_EVENT_PMKID_CANDIDATE_LIST_T; -+ -+typedef struct _EVENT_CMD_RESULT { -+ UINT_8 ucCmdID; -+ UINT_8 ucStatus; -+ UINT_8 aucReserved[2]; -+} EVENT_CMD_RESULT, *P_EVENT_CMD_RESULT; -+ -+/* CMD_ID_ACCESS_REG & EVENT_ID_ACCESS_REG */ -+typedef struct _CMD_ACCESS_REG { -+ UINT_32 u4Address; -+ UINT_32 u4Data; -+} CMD_ACCESS_REG, *P_CMD_ACCESS_REG; -+ -+/* CMD_ID_ACCESS_REG & EVENT_ID_ACCESS_REG */ -+#if CFG_AUTO_CHANNEL_SEL_SUPPORT -+ -+typedef struct _CMD_ACCESS_CHN_LOAD { -+ UINT_32 u4Address; -+ UINT_32 u4Data; -+ UINT_16 u2Channel; -+ UINT_8 aucReserved[2]; -+} CMD_ACCESS_CHN_LOAD, *P_ACCESS_CHN_LOAD; -+ -+#endif -+/* CMD_DUMP_MEMORY */ -+typedef struct _CMD_DUMP_MEM { -+ UINT_32 u4Address; -+ UINT_32 u4Length; -+ UINT_32 u4RemainLength; -+ UINT_8 ucFragNum; -+} CMD_DUMP_MEM, *P_CMD_DUMP_MEM; -+ -+typedef struct _EVENT_DUMP_MEM_T { -+ UINT_32 u4Address; -+ UINT_32 u4Length; -+ UINT_32 u4RemainLength; -+ UINT_8 ucFragNum; -+ UINT_8 aucBuffer[1]; -+} EVENT_DUMP_MEM_T, *P_EVENT_DUMP_MEM_T; -+ -+typedef struct _CMD_SW_DBG_CTRL_T { -+ UINT_32 u4Id; -+ UINT_32 u4Data; -+ /* Debug Support */ -+ UINT_32 u4DebugCnt[64]; -+} CMD_SW_DBG_CTRL_T, *P_CMD_SW_DBG_CTRL_T; -+ -+/* CMD_ID_LINK_ATTRIB */ -+typedef struct _CMD_LINK_ATTRIB { -+ INT_8 cRssiTrigger; -+ UINT_8 ucDesiredRateLen; -+ UINT_16 u2DesiredRate[32]; -+ UINT_8 ucMediaStreamMode; -+ UINT_8 aucReserved[1]; -+} CMD_LINK_ATTRIB, *P_CMD_LINK_ATTRIB; -+ -+/* CMD_ID_NIC_POWER_CTRL */ -+typedef struct _CMD_NIC_POWER_CTRL { -+ UINT_8 ucPowerMode; -+ UINT_8 aucReserved[3]; -+} CMD_NIC_POWER_CTRL, *P_CMD_NIC_POWER_CTRL; -+ -+/* CMD_ID_POWER_SAVE_MODE */ -+typedef struct _CMD_PS_PROFILE_T { -+ UINT_8 ucNetTypeIndex; -+ UINT_8 ucPsProfile; -+ UINT_8 aucReserved[2]; -+} CMD_PS_PROFILE_T, *P_CMD_PS_PROFILE_T; -+ -+/* EVENT_LINK_QUALITY */ -+typedef struct _EVENT_LINK_QUALITY { -+ INT_8 cRssi; -+ INT_8 cLinkQuality; -+ UINT_16 u2LinkSpeed; -+ UINT_8 ucMediumBusyPercentage; -+} EVENT_LINK_QUALITY, *P_EVENT_LINK_QUALITY; -+ -+#if CFG_SUPPORT_P2P_RSSI_QUERY -+/* EVENT_LINK_QUALITY */ -+typedef struct _EVENT_LINK_QUALITY_EX { -+ INT_8 cRssi; -+ INT_8 cLinkQuality; -+ UINT_16 u2LinkSpeed; -+ UINT_8 ucMediumBusyPercentage; -+ UINT_8 ucIsLQ0Rdy; -+ INT_8 cRssiP2P; /* For P2P Network. */ -+ INT_8 cLinkQualityP2P; -+ UINT_16 u2LinkSpeedP2P; -+ UINT_8 ucMediumBusyPercentageP2P; -+ UINT_8 ucIsLQ1Rdy; -+} EVENT_LINK_QUALITY_EX, *P_EVENT_LINK_QUALITY_EX; -+#endif -+ -+/* EVENT_ID_STATISTICS */ -+typedef struct _EVENT_STATISTICS { -+ LARGE_INTEGER rTransmittedFragmentCount; -+ LARGE_INTEGER rMulticastTransmittedFrameCount; -+ LARGE_INTEGER rFailedCount; -+ LARGE_INTEGER rRetryCount; -+ LARGE_INTEGER rMultipleRetryCount; -+ LARGE_INTEGER rRTSSuccessCount; -+ LARGE_INTEGER rRTSFailureCount; -+ LARGE_INTEGER rACKFailureCount; -+ LARGE_INTEGER rFrameDuplicateCount; -+ LARGE_INTEGER rReceivedFragmentCount; -+ LARGE_INTEGER rMulticastReceivedFrameCount; -+ LARGE_INTEGER rFCSErrorCount; -+} EVENT_STATISTICS, *P_EVENT_STATISTICS; -+ -+/* EVENT_ID_FW_SLEEPY_NOTIFY */ -+typedef struct _EVENT_SLEEPY_NOTIFY { -+ UINT_8 ucSleepyState; -+ UINT_8 aucReserved[3]; -+} EVENT_SLEEPY_NOTIFY, *P_EVENT_SLEEPY_NOTIFY; -+ -+typedef struct _EVENT_ACTIVATE_STA_REC_T { -+ UINT_8 aucMacAddr[6]; -+ UINT_8 ucStaRecIdx; -+ UINT_8 ucNetworkTypeIndex; -+ BOOLEAN fgIsQoS; -+ BOOLEAN fgIsAP; -+ UINT_8 aucReserved[2]; -+} EVENT_ACTIVATE_STA_REC_T, *P_EVENT_ACTIVATE_STA_REC_T; -+ -+typedef struct _EVENT_DEACTIVATE_STA_REC_T { -+ UINT_8 ucStaRecIdx; -+ UINT_8 aucReserved[3]; -+} EVENT_DEACTIVATE_STA_REC_T, *P_EVENT_DEACTIVATE_STA_REC_T; -+ -+/* CMD_BT_OVER_WIFI */ -+typedef struct _CMD_BT_OVER_WIFI { -+ UINT_8 ucAction; /* 0: query, 1: setup, 2: destroy */ -+ UINT_8 ucChannelNum; -+ PARAM_MAC_ADDRESS rPeerAddr; -+ UINT_16 u2BeaconInterval; -+ UINT_8 ucTimeoutDiscovery; -+ UINT_8 ucTimeoutInactivity; -+ UINT_8 ucRole; -+ UINT_8 PAL_Capabilities; -+ UINT_8 cMaxTxPower; -+ UINT_8 ucChannelBand; -+ UINT_8 ucReserved[1]; -+} CMD_BT_OVER_WIFI, *P_CMD_BT_OVER_WIFI; -+ -+/* EVENT_BT_OVER_WIFI */ -+typedef struct _EVENT_BT_OVER_WIFI { -+ UINT_8 ucLinkStatus; -+ UINT_8 ucSelectedChannel; -+ INT_8 cRSSI; -+ UINT_8 ucReserved[1]; -+} EVENT_BT_OVER_WIFI, *P_EVENT_BT_OVER_WIFI; -+ -+/* Same with DOMAIN_SUBBAND_INFO */ -+typedef struct _CMD_SUBBAND_INFO { -+ UINT_8 ucRegClass; -+ UINT_8 ucBand; -+ UINT_8 ucChannelSpan; -+ UINT_8 ucFirstChannelNum; -+ UINT_8 ucNumChannels; -+ UINT_8 aucReserved[3]; -+} CMD_SUBBAND_INFO, *P_CMD_SUBBAND_INFO; -+ -+/* CMD_SET_DOMAIN_INFO */ -+typedef struct _CMD_SET_DOMAIN_INFO_T { -+ UINT_16 u2CountryCode; -+ UINT_16 u2IsSetPassiveScan; /* 0: set channel domain; 1: set passive scan channel domain */ -+ CMD_SUBBAND_INFO rSubBand[6]; -+ -+ UINT_8 uc2G4Bandwidth; /* CONFIG_BW_20_40M or CONFIG_BW_20M */ -+ UINT_8 uc5GBandwidth; /* CONFIG_BW_20_40M or CONFIG_BW_20M */ -+ UINT_8 aucReserved[2]; -+} CMD_SET_DOMAIN_INFO_T, *P_CMD_SET_DOMAIN_INFO_T; -+ -+#if CFG_SUPPORT_PWR_LIMIT_COUNTRY -+ -+/* CMD_SET_PWR_LIMIT_TABLE */ -+typedef struct _CMD_CHANNEL_POWER_LIMIT { -+ UINT_8 ucCentralCh; -+ INT_8 cPwrLimitCCK; -+ INT_8 cPwrLimit20; -+ INT_8 cPwrLimit40; -+ INT_8 cPwrLimit80; -+ INT_8 cPwrLimit160; -+ UINT_8 ucFlag; -+ UINT_8 aucReserved[1]; -+} CMD_CHANNEL_POWER_LIMIT, *P_CMD_CHANNEL_POWER_LIMIT; -+ -+typedef struct _CMD_SET_COUNTRY_CHANNEL_POWER_LIMIT_T { -+ UINT_16 u2CountryCode; -+ UINT_8 ucCountryFlag; -+ UINT_8 ucNum; -+ UINT_8 aucReserved[4]; -+ CMD_CHANNEL_POWER_LIMIT rChannelPowerLimit[1]; -+} CMD_SET_COUNTRY_CHANNEL_POWER_LIMIT_T, *P_CMD_SET_COUNTRY_CHANNEL_POWER_LIMIT_T; -+ -+#endif -+ -+/* CMD_SET_IP_ADDRESS */ -+typedef struct _IPV4_NETWORK_ADDRESS { -+ UINT_8 aucIpAddr[4]; -+} IPV4_NETWORK_ADDRESS, *P_IPV4_NETWORK_ADDRESS; -+ -+typedef struct _CMD_SET_NETWORK_ADDRESS_LIST { -+ UINT_8 ucNetTypeIndex; -+ UINT_8 ucAddressCount; -+ UINT_8 ucReserved[2]; -+ IPV4_NETWORK_ADDRESS arNetAddress[1]; -+} CMD_SET_NETWORK_ADDRESS_LIST, *P_CMD_SET_NETWORK_ADDRESS_LIST; -+ -+typedef struct _PATTERN_DESCRIPTION { -+ UINT_8 fgCheckBcA1; -+ UINT_8 fgCheckMcA1; -+ UINT_8 ePatternHeader; -+ UINT_8 fgAndOp; -+ UINT_8 fgNotOp; -+ UINT_8 ucPatternMask; -+ UINT_16 ucPatternOffset; -+ UINT_8 aucPattern[8]; -+} PATTERN_DESCRIPTION, *P_PATTERN_DESCRIPTION; -+ -+typedef struct _CMD_RAW_PATTERN_CONFIGURATION_T { -+ PATTERN_DESCRIPTION arPatternDesc[4]; -+} CMD_RAW_PATTERN_CONFIGURATION_T, *P_CMD_RAW_PATTERN_CONFIGURATION_T; -+ -+typedef struct _CMD_PATTERN_FUNC_CONFIG { -+ BOOLEAN fgBcA1En; -+ BOOLEAN fgMcA1En; -+ BOOLEAN fgBcA1MatchDrop; -+ BOOLEAN fgMcA1MatchDrop; -+} CMD_PATTERN_FUNC_CONFIG, *P_CMD_PATTERN_FUNC_CONFIG; -+ -+typedef struct _EVENT_TX_DONE_T { -+ UINT_8 ucPacketSeq; -+ UINT_8 ucStatus; -+ UINT_16 u2SequenceNumber; -+ UINT_32 au4Reserved1; -+ UINT_32 au4Reserved2; -+ UINT_32 au4Reserved3; -+} EVENT_TX_DONE_T, *P_EVENT_TX_DONE_T; -+ -+typedef struct _CMD_BSS_ACTIVATE_CTRL { -+ UINT_8 ucNetTypeIndex; -+ UINT_8 ucActive; -+ UINT_8 aucReserved[2]; -+} CMD_BSS_ACTIVATE_CTRL, *P_CMD_BSS_ACTIVATE_CTRL; -+ -+typedef struct _CMD_SET_BSS_RLM_PARAM_T { -+ UINT_8 ucNetTypeIndex; -+ UINT_8 ucRfBand; -+ UINT_8 ucPrimaryChannel; -+ UINT_8 ucRfSco; -+ UINT_8 ucErpProtectMode; -+ UINT_8 ucHtProtectMode; -+ UINT_8 ucGfOperationMode; -+ UINT_8 ucTxRifsMode; -+ UINT_16 u2HtOpInfo3; -+ UINT_16 u2HtOpInfo2; -+ UINT_8 ucHtOpInfo1; -+ UINT_8 ucUseShortPreamble; -+ UINT_8 ucUseShortSlotTime; -+ UINT_8 ucCheckId; /* Fixed value: 0x72 */ -+} CMD_SET_BSS_RLM_PARAM_T, *P_CMD_SET_BSS_RLM_PARAM_T; -+ -+typedef struct _CMD_SET_BSS_INFO { -+ UINT_8 ucNetTypeIndex; -+ UINT_8 ucConnectionState; -+ UINT_8 ucCurrentOPMode; -+ UINT_8 ucSSIDLen; -+ UINT_8 aucSSID[32]; -+ UINT_8 aucBSSID[6]; -+ UINT_8 ucIsQBSS; -+ UINT_8 ucReserved1; -+ UINT_16 u2OperationalRateSet; -+ UINT_16 u2BSSBasicRateSet; -+ UINT_8 ucStaRecIdxOfAP; -+ UINT_8 ucReserved2; -+ UINT_8 ucReserved3; -+ UINT_8 ucNonHTBasicPhyType; /* For Slot Time and CWmin */ -+ UINT_8 ucAuthMode; -+ UINT_8 ucEncStatus; -+ UINT_8 ucPhyTypeSet; -+ UINT_8 aucOwnMac[6]; -+ UINT_8 fgWapiMode; -+ UINT_8 fgIsApMode; -+ UINT_8 fgHiddenSsidMode; -+ CMD_SET_BSS_RLM_PARAM_T rBssRlmParam; -+} CMD_SET_BSS_INFO, *P_CMD_SET_BSS_INFO; -+ -+typedef struct _CMD_UPDATE_STA_RECORD_T { -+ UINT_8 ucIndex; -+ UINT_8 ucStaType; -+ UINT_8 aucMacAddr[MAC_ADDR_LEN]; -+ UINT_16 u2AssocId; -+ UINT_16 u2ListenInterval; -+ UINT_8 ucNetTypeIndex; -+ UINT_8 ucDesiredPhyTypeSet; -+ UINT_16 u2DesiredNonHTRateSet; -+ UINT_16 u2BSSBasicRateSet; -+ UINT_8 ucIsQoS; -+ UINT_8 ucIsUapsdSupported; -+ UINT_8 ucStaState; -+ UINT_8 ucMcsSet; -+ UINT_8 ucSupMcs32; -+ UINT_8 ucAmpduParam; -+ UINT_16 u2HtCapInfo; -+ UINT_16 u2HtExtendedCap; -+ UINT_32 u4TxBeamformingCap; -+ UINT_8 ucAselCap; -+ UINT_8 ucRCPI; -+ UINT_8 ucNeedResp; -+ UINT_8 ucUapsdAc; /* b0~3: Trigger enabled, b4~7: Delivery enabled */ -+ UINT_8 ucUapsdSp; /* 0: all, 1: max 2, 2: max 4, 3: max 6 */ -+ UINT_8 aucReserved[3]; -+ /* TBD */ -+} CMD_UPDATE_STA_RECORD_T, *P_CMD_UPDATE_STA_RECORD_T; -+ -+typedef struct _CMD_REMOVE_STA_RECORD_T { -+ UINT_8 ucIndex; -+ UINT_8 ucReserved; -+ UINT_8 aucMacAddr[MAC_ADDR_LEN]; -+} CMD_REMOVE_STA_RECORD_T, *P_CMD_REMOVE_STA_RECORD_T; -+ -+typedef struct _CMD_INDICATE_PM_BSS_CREATED_T { -+ UINT_8 ucNetTypeIndex; -+ UINT_8 ucDtimPeriod; -+ UINT_16 u2BeaconInterval; -+ UINT_16 u2AtimWindow; -+ UINT_8 aucReserved[2]; -+} CMD_INDICATE_PM_BSS_CREATED, *P_CMD_INDICATE_PM_BSS_CREATED; -+ -+typedef struct _CMD_INDICATE_PM_BSS_CONNECTED_T { -+ UINT_8 ucNetTypeIndex; -+ UINT_8 ucDtimPeriod; -+ UINT_16 u2AssocId; -+ UINT_16 u2BeaconInterval; -+ UINT_16 u2AtimWindow; -+ UINT_8 fgIsUapsdConnection; -+ UINT_8 ucBmpDeliveryAC; -+ UINT_8 ucBmpTriggerAC; -+ UINT_8 aucReserved[1]; -+} CMD_INDICATE_PM_BSS_CONNECTED, *P_CMD_INDICATE_PM_BSS_CONNECTED; -+ -+typedef struct _CMD_INDICATE_PM_BSS_ABORT { -+ UINT_8 ucNetTypeIndex; -+ UINT_8 aucReserved[3]; -+} CMD_INDICATE_PM_BSS_ABORT, *P_CMD_INDICATE_PM_BSS_ABORT; -+ -+typedef struct _CMD_BEACON_TEMPLATE_UPDATE { -+ UINT_8 ucUpdateMethod; /* 0: update randomly, -+ * 1: update all, -+ * 2: delete all (1 and 2 will update directly without search) -+ */ -+ UINT_8 ucNetTypeIndex; -+ UINT_8 aucReserved[2]; -+ UINT_16 u2Capability; -+ UINT_16 u2IELen; -+ UINT_8 aucIE[MAX_IE_LENGTH]; -+} CMD_BEACON_TEMPLATE_UPDATE, *P_CMD_BEACON_TEMPLATE_UPDATE; -+ -+typedef struct _CMD_SET_WMM_PS_TEST_STRUCT_T { -+ UINT_8 ucNetTypeIndex; -+ UINT_8 bmfgApsdEnAc; /* b0~3: trigger-en AC0~3. b4~7: delivery-en AC0~3 */ -+ UINT_8 ucIsEnterPsAtOnce; /* enter PS immediately without 5 second guard after connected */ -+ UINT_8 ucIsDisableUcTrigger; /* not to trigger UC on beacon TIM is matched (under U-APSD) */ -+} CMD_SET_WMM_PS_TEST_STRUCT_T, *P_CMD_SET_WMM_PS_TEST_STRUCT_T; -+ -+/* Definition for CHANNEL_INFO.ucBand: -+ * 0: Reserved -+ * 1: BAND_2G4 -+ * 2: BAND_5G -+ * Others: Reserved -+ */ -+typedef struct _CHANNEL_INFO_T { -+ UINT_8 ucBand; -+ UINT_8 ucChannelNum; -+} CHANNEL_INFO_T, *P_CHANNEL_INFO_T; -+ -+typedef struct _CMD_SCAN_REQ_EXT_CH_T { -+ UINT_8 ucSeqNum; -+ UINT_8 ucNetworkType; -+ UINT_8 ucScanType; -+ UINT_8 ucSSIDType; /* BIT(0) wildcard / BIT(1) P2P-wildcard / BIT(2) specific */ -+ UINT_8 ucSSIDLength; -+ UINT_8 aucReserved[1]; -+ UINT_16 u2ChannelMinDwellTime; -+ UINT_8 aucSSID[32]; -+ UINT_16 u2ChannelDwellTime; /* For P2P */ -+ UINT_8 ucChannelType; -+ UINT_8 ucChannelListNum; -+ CHANNEL_INFO_T arChannelList[MAXIMUM_OPERATION_CHANNEL_LIST]; -+ UINT_16 u2IELen; -+ UINT_8 aucIE[MAX_IE_LENGTH]; -+} CMD_SCAN_REQ_EXT_CH, *P_CMD_SCAN_REQ_EXT_CH; -+ -+typedef struct _CMD_SCAN_REQ_T { -+ UINT_8 ucSeqNum; -+ UINT_8 ucNetworkType; -+ UINT_8 ucScanType; -+ UINT_8 ucSSIDType; /* BIT(0) wildcard / BIT(1) P2P-wildcard / BIT(2) specific */ -+ UINT_8 ucSSIDLength; -+ UINT_8 aucReserved[1]; -+ UINT_16 u2ChannelMinDwellTime; -+ UINT_8 aucSSID[32]; -+ UINT_16 u2ChannelDwellTime; /* For P2P */ -+ UINT_8 ucChannelType; -+ UINT_8 ucChannelListNum; -+ CHANNEL_INFO_T arChannelList[32]; -+ UINT_16 u2IELen; -+ UINT_8 aucIE[MAX_IE_LENGTH]; -+} CMD_SCAN_REQ, *P_CMD_SCAN_REQ; -+ -+typedef struct _CMD_SCAN_REQ_V2_EXT_CH_T { -+ UINT_8 ucSeqNum; -+ UINT_8 ucNetworkType; -+ UINT_8 ucScanType; -+ UINT_8 ucSSIDType; -+ PARAM_SSID_T arSSID[4]; -+ UINT_16 u2ProbeDelayTime; -+ UINT_16 u2ChannelDwellTime; /* For P2P */ -+ UINT_8 ucChannelType; -+ UINT_8 ucChannelListNum; -+ CHANNEL_INFO_T arChannelList[MAXIMUM_OPERATION_CHANNEL_LIST]; -+ UINT_16 u2IELen; -+ UINT_8 aucIE[MAX_IE_LENGTH]; -+} CMD_SCAN_REQ_V2_EXT_CH, *P_CMD_SCAN_REQ_V2_EXT_CH; -+ -+typedef struct _CMD_SCAN_REQ_V2_T { -+ UINT_8 ucSeqNum; -+ UINT_8 ucNetworkType; -+ UINT_8 ucScanType; -+ UINT_8 ucSSIDType; -+ PARAM_SSID_T arSSID[4]; -+ UINT_16 u2ProbeDelayTime; -+ UINT_16 u2ChannelDwellTime; /* For P2P */ -+ UINT_8 ucChannelType; -+ UINT_8 ucChannelListNum; -+ CHANNEL_INFO_T arChannelList[32]; -+ UINT_16 u2IELen; -+ UINT_8 aucIE[MAX_IE_LENGTH]; -+} CMD_SCAN_REQ_V2, *P_CMD_SCAN_REQ_V2; -+ -+typedef struct _CMD_SCAN_CANCEL_T { -+ UINT_8 ucSeqNum; -+ UINT_8 ucIsExtChannel; /* For P2P channel extension. */ -+ UINT_8 aucReserved[2]; -+} CMD_SCAN_CANCEL, *P_CMD_SCAN_CANCEL; -+ -+typedef struct _EVENT_SCAN_DONE_T { -+ UINT_8 ucSeqNum; -+ UINT_8 ucSparseChannelValid; -+ CHANNEL_INFO_T rSparseChannel; -+} EVENT_SCAN_DONE, *P_EVENT_SCAN_DONE; -+ -+#if CFG_SUPPORT_GET_CH_ENV -+typedef struct _CH_ENV_T { -+ UINT_8 ucChNum; -+ UINT_8 ucApNum; -+} CH_ENV_T, *P_CH_ENV_T; -+#endif -+ -+#if 0 /* CFG_SUPPORT_BATCH_SCAN */ -+typedef struct _CMD_BATCH_REQ_T { -+ UINT_8 ucSeqNum; -+ UINT_8 ucNetTypeIndex; -+ UINT_8 ucCmd; /* Start/ Stop */ -+ UINT_8 ucMScan; /* an integer number of scans per batch */ -+ UINT_8 ucBestn; /* an integer number of the max AP to remember per scan */ -+ UINT_8 ucRtt; /* an integer number of highest-strength AP for which we'd -+ like approximate distance reported */ -+ UINT_8 ucChannel; /* channels */ -+ UINT_8 ucChannelType; -+ UINT_8 ucChannelListNum; -+ UINT_8 aucReserved[3]; -+ UINT_32 u4Scanfreq; /* an integer number of seconds between scans */ -+ CHANNEL_INFO_T arChannelList[32]; /* channels */ -+} CMD_BATCH_REQ_T, *P_CMD_BATCH_REQ_T; -+ -+typedef struct _EVENT_BATCH_RESULT_ENTRY_T { -+ UINT_8 aucBssid[MAC_ADDR_LEN]; -+ UINT_8 aucSSID[ELEM_MAX_LEN_SSID]; -+ UINT_8 ucSSIDLen; -+ INT_8 cRssi; -+ UINT_32 ucFreq; -+ UINT_32 u4Age; -+ UINT_32 u4Dist; -+ UINT_32 u4Distsd; -+} EVENT_BATCH_RESULT_ENTRY_T, *P_EVENT_BATCH_RESULT_ENTRY_T; -+ -+typedef struct _EVENT_BATCH_RESULT_T { -+ UINT_8 ucScanCount; -+ UINT_8 aucReserved[3]; -+ EVENT_BATCH_RESULT_ENTRY_T arBatchResult[12]; /* Must be the same with SCN_BATCH_STORE_MAX_NUM */ -+} EVENT_BATCH_RESULT_T, *P_EVENT_BATCH_RESULT_T; -+#endif -+ -+typedef struct _CMD_CH_PRIVILEGE_T { -+ UINT_8 ucNetTypeIndex; -+ UINT_8 ucTokenID; -+ UINT_8 ucAction; -+ UINT_8 ucPrimaryChannel; -+ UINT_8 ucRfSco; -+ UINT_8 ucRfBand; -+ UINT_8 ucReqType; -+ UINT_8 ucReserved; -+ UINT_32 u4MaxInterval; /* In unit of ms */ -+ UINT_8 aucBSSID[6]; -+ UINT_8 aucReserved[2]; -+} CMD_CH_PRIVILEGE_T, *P_CMD_CH_PRIVILEGE_T; -+ -+typedef struct _CMD_TX_PWR_T { -+ INT_8 cTxPwr2G4Cck; /* signed, in unit of 0.5dBm */ -+#if defined(MT6620) -+ INT_8 acReserved[3]; -+#elif defined(MT6628) -+ INT_8 cTxPwr2G4Dsss; /* signed, in unit of 0.5dBm */ -+ INT_8 acReserved[2]; -+#else -+#error "No valid definition!" -+#endif -+ -+ INT_8 cTxPwr2G4OFDM_BPSK; -+ INT_8 cTxPwr2G4OFDM_QPSK; -+ INT_8 cTxPwr2G4OFDM_16QAM; -+ INT_8 cTxPwr2G4OFDM_Reserved; -+ INT_8 cTxPwr2G4OFDM_48Mbps; -+ INT_8 cTxPwr2G4OFDM_54Mbps; -+ -+ INT_8 cTxPwr2G4HT20_BPSK; -+ INT_8 cTxPwr2G4HT20_QPSK; -+ INT_8 cTxPwr2G4HT20_16QAM; -+ INT_8 cTxPwr2G4HT20_MCS5; -+ INT_8 cTxPwr2G4HT20_MCS6; -+ INT_8 cTxPwr2G4HT20_MCS7; -+ -+ INT_8 cTxPwr2G4HT40_BPSK; -+ INT_8 cTxPwr2G4HT40_QPSK; -+ INT_8 cTxPwr2G4HT40_16QAM; -+ INT_8 cTxPwr2G4HT40_MCS5; -+ INT_8 cTxPwr2G4HT40_MCS6; -+ INT_8 cTxPwr2G4HT40_MCS7; -+ -+ INT_8 cTxPwr5GOFDM_BPSK; -+ INT_8 cTxPwr5GOFDM_QPSK; -+ INT_8 cTxPwr5GOFDM_16QAM; -+ INT_8 cTxPwr5GOFDM_Reserved; -+ INT_8 cTxPwr5GOFDM_48Mbps; -+ INT_8 cTxPwr5GOFDM_54Mbps; -+ -+ INT_8 cTxPwr5GHT20_BPSK; -+ INT_8 cTxPwr5GHT20_QPSK; -+ INT_8 cTxPwr5GHT20_16QAM; -+ INT_8 cTxPwr5GHT20_MCS5; -+ INT_8 cTxPwr5GHT20_MCS6; -+ INT_8 cTxPwr5GHT20_MCS7; -+ -+ INT_8 cTxPwr5GHT40_BPSK; -+ INT_8 cTxPwr5GHT40_QPSK; -+ INT_8 cTxPwr5GHT40_16QAM; -+ INT_8 cTxPwr5GHT40_MCS5; -+ INT_8 cTxPwr5GHT40_MCS6; -+ INT_8 cTxPwr5GHT40_MCS7; -+} CMD_TX_PWR_T, *P_CMD_TX_PWR_T; -+ -+typedef struct _CMD_5G_PWR_OFFSET_T { -+ INT_8 cOffsetBand0; /* 4.915-4.980G */ -+ INT_8 cOffsetBand1; /* 5.000-5.080G */ -+ INT_8 cOffsetBand2; /* 5.160-5.180G */ -+ INT_8 cOffsetBand3; /* 5.200-5.280G */ -+ INT_8 cOffsetBand4; /* 5.300-5.340G */ -+ INT_8 cOffsetBand5; /* 5.500-5.580G */ -+ INT_8 cOffsetBand6; /* 5.600-5.680G */ -+ INT_8 cOffsetBand7; /* 5.700-5.825G */ -+} CMD_5G_PWR_OFFSET_T, *P_CMD_5G_PWR_OFFSET_T; -+ -+typedef struct _CMD_PWR_PARAM_T { -+ UINT_32 au4Data[28]; -+ UINT_32 u4RefValue1; -+ UINT_32 u4RefValue2; -+} CMD_PWR_PARAM_T, *P_CMD_PWR_PARAM_T; -+ -+typedef struct _CMD_PHY_PARAM_T { -+ UINT_8 aucData[144]; /* eFuse content */ -+} CMD_PHY_PARAM_T, *P_CMD_PHY_PARAM_T; -+ -+typedef struct _CMD_AUTO_POWER_PARAM_T { -+ UINT_8 ucType; /* 0: Disable 1: Enalbe 0x10: Change parameters */ -+ UINT_8 ucNetTypeIndex; -+ UINT_8 aucReserved[2]; -+ UINT_8 aucLevelRcpiTh[3]; -+ UINT_8 aucReserved2[1]; -+ INT_8 aicLevelPowerOffset[3]; /* signed, in unit of 0.5dBm */ -+ UINT_8 aucReserved3[1]; -+ UINT_8 aucReserved4[8]; -+} CMD_AUTO_POWER_PARAM_T, *P_CMD_AUTO_POWER_PARAM_T; -+ -+typedef struct _EVENT_CH_PRIVILEGE_T { -+ UINT_8 ucNetTypeIndex; -+ UINT_8 ucTokenID; -+ UINT_8 ucStatus; -+ UINT_8 ucPrimaryChannel; -+ UINT_8 ucRfSco; -+ UINT_8 ucRfBand; -+ UINT_8 ucReqType; -+ UINT_8 ucReserved; -+ UINT_32 u4GrantInterval; /* In unit of ms */ -+} EVENT_CH_PRIVILEGE_T, *P_EVENT_CH_PRIVILEGE_T; -+ -+typedef enum _ENUM_BEACON_TIMEOUT_TYPE_T { -+ BEACON_TIMEOUT_LOST_BEACON = 0, -+ BEACON_TIMEOUT_AGE, -+ BEACON_TIMEOUT_CONNECT, -+ BEACON_TIMEOUT_BEACON_INTERVAL, -+ BEACON_TIMEOUT_ABORT, -+ BEACON_TIMEOUT_TX_ERROR, -+ BEACON_TIMEOUT_TYPE_NUM -+} ENUM_BEACON_TIMEOUT_TYPE_T, *P_ENUM_BEACON_TIMEOUT_TYPE_T; -+ -+typedef struct _EVENT_BSS_BEACON_TIMEOUT_T { -+ UINT_8 ucNetTypeIndex; -+ UINT_8 ucReason; /* ENUM_BEACON_TIMEOUT_TYPE_T */ -+ UINT_8 aucReserved[2]; -+} EVENT_BSS_BEACON_TIMEOUT_T, *P_EVENT_BSS_BEACON_TIMEOUT_T; -+ -+typedef struct _EVENT_STA_AGING_TIMEOUT_T { -+ UINT_8 ucStaRecIdx; -+ UINT_8 aucReserved[3]; -+} EVENT_STA_AGING_TIMEOUT_T, *P_EVENT_STA_AGING_TIMEOUT_T; -+ -+typedef struct _EVENT_NOA_TIMING_T { -+ UINT_8 fgIsInUse; /* Indicate if this entry is in use or not */ -+ UINT_8 ucCount; /* Count */ -+ UINT_8 aucReserved[2]; -+ -+ UINT_32 u4Duration; /* Duration */ -+ UINT_32 u4Interval; /* Interval */ -+ UINT_32 u4StartTime; /* Start Time */ -+} EVENT_NOA_TIMING_T, *P_EVENT_NOA_TIMING_T; -+ -+typedef struct _EVENT_UPDATE_NOA_PARAMS_T { -+ UINT_8 ucNetTypeIndex; -+ UINT_8 aucReserved[2]; -+ UINT_8 fgEnableOppPS; -+ UINT_16 u2CTWindow; -+ -+ UINT_8 ucNoAIndex; -+ UINT_8 ucNoATimingCount; /* Number of NoA Timing */ -+ EVENT_NOA_TIMING_T arEventNoaTiming[8 /*P2P_MAXIMUM_NOA_COUNT */]; -+} EVENT_UPDATE_NOA_PARAMS_T, *P_EVENT_UPDATE_NOA_PARAMS_T; -+ -+typedef struct _EVENT_AP_OBSS_STATUS_T { -+ UINT_8 ucNetTypeIndex; -+ UINT_8 ucObssErpProtectMode; -+ UINT_8 ucObssHtProtectMode; -+ UINT_8 ucObssGfOperationMode; -+ UINT_8 ucObssRifsOperationMode; -+ UINT_8 ucObssBeaconForcedTo20M; -+ UINT_8 aucReserved[2]; -+} EVENT_AP_OBSS_STATUS_T, *P_EVENT_AP_OBSS_STATUS_T; -+ -+typedef struct _CMD_EDGE_TXPWR_LIMIT_T { -+ INT_8 cBandEdgeMaxPwrCCK; -+ INT_8 cBandEdgeMaxPwrOFDM20; -+ INT_8 cBandEdgeMaxPwrOFDM40; -+ INT_8 cReserved; -+} CMD_EDGE_TXPWR_LIMIT_T, *P_CMD_EDGE_TXPWR_LIMIT_T; -+ -+typedef struct _CMD_RSSI_COMPENSATE_T { -+ UINT_8 uc2GRssiCompensation; -+ UINT_8 uc5GRssiCompensation; -+ UINT_8 ucRssiCompensationValidbit; -+ UINT_8 cReserved; -+} CMD_RSSI_COMPENSATE_T, *P_CMD_RSSI_COMPENSATE_T; -+ -+typedef struct _CMD_BAND_SUPPORT_T { -+ UINT_8 uc5GBandSupport; -+ UINT_8 cReserved[3]; -+} CMD_BAND_SUPPORT_T, *P_CMD_BAND_SUPPORT_T; -+ -+typedef struct _CMD_TX_PWR_CE_T { -+ INT_8 cTxPwrCckLmt; /* signed, in unit of 0.5dBm */ -+ INT_8 cTxPwrOfdmLmt; /* signed, in unit of 0.5dBm */ -+ INT_8 cTxPwrHt20Lmt; -+ INT_8 cTxPwrHt40Lmt; -+} CMD_TX_PWR_CE_T, *P_CMD_TX_PWR_CE_T; -+ -+typedef struct _CMD_SET_DEVICE_MODE_T { -+ UINT_16 u2ChipID; -+ UINT_16 u2Mode; -+} CMD_SET_DEVICE_MODE_T, *P_CMD_SET_DEVICE_MODE_T; -+ -+#if CFG_SUPPORT_RDD_TEST_MODE -+typedef struct _CMD_RDD_CH_T { -+ UINT_8 ucRddTestMode; -+ UINT_8 ucRddShutCh; -+ UINT_8 ucRddStartCh; -+ UINT_8 ucRddStopCh; -+ UINT_8 ucRddDfs; -+ UINT_8 ucReserved; -+ UINT_8 ucReserved1; -+ UINT_8 ucReserved2; -+} CMD_RDD_CH_T, *P_CMD_RDD_CH_T; -+ -+typedef struct _EVENT_RDD_STATUS_T { -+ UINT_8 ucRddStatus; -+ UINT_8 aucReserved[3]; -+} EVENT_RDD_STATUS_T, *P_EVENT_RDD_STATUS_T; -+#endif -+ -+typedef struct _EVENT_AIS_BSS_INFO_T { -+ ENUM_PARAM_MEDIA_STATE_T eConnectionState; /* Connected Flag used in AIS_NORMAL_TR */ -+ ENUM_OP_MODE_T eCurrentOPMode; /* Current Operation Mode - Infra/IBSS */ -+ BOOLEAN fgIsNetActive; /* TRUE if this network has been actived */ -+ UINT_8 ucReserved[3]; -+} EVENT_AIS_BSS_INFO_T, *P_EVENT_AIS_BSS_INFO_T; -+ -+typedef struct _CMD_SET_TXPWR_CTRL_T { -+ INT_8 c2GLegacyStaPwrOffset; /* Unit: 0.5dBm, default: 0 */ -+ INT_8 c2GHotspotPwrOffset; -+ INT_8 c2GP2pPwrOffset; -+ INT_8 c2GBowPwrOffset; -+ INT_8 c5GLegacyStaPwrOffset; /* Unit: 0.5dBm, default: 0 */ -+ INT_8 c5GHotspotPwrOffset; -+ INT_8 c5GP2pPwrOffset; -+ INT_8 c5GBowPwrOffset; -+ UINT_8 ucConcurrencePolicy; /* TX power policy when concurrence -+ in the same channel -+ 0: Highest power has priority -+ 1: Lowest power has priority */ -+ INT_8 acReserved1[3]; /* Must be zero */ -+ -+ /* Power limit by channel for all data rates */ -+ INT_8 acTxPwrLimit2G[14]; /* Channel 1~14, Unit: 0.5dBm */ -+ INT_8 acTxPwrLimit5G[4]; /* UNII 1~4 */ -+ INT_8 acReserved2[2]; /* Must be zero */ -+} CMD_SET_TXPWR_CTRL_T, *P_CMD_SET_TXPWR_CTRL_T; -+ -+#if CFG_SUPPORT_BUILD_DATE_CODE -+typedef struct _CMD_GET_BUILD_DATE_CODE { -+ UINT_8 aucReserved[4]; -+} CMD_GET_BUILD_DATE_CODE, *P_CMD_GET_BUILD_DATE_CODE; -+ -+typedef struct _EVENT_BUILD_DATE_CODE { -+ UINT_8 aucDateCode[16]; -+} EVENT_BUILD_DATE_CODE, *P_EVENT_BUILD_DATE_CODE; -+#endif -+ -+typedef struct _CMD_GET_STA_STATISTICS_T { -+ UINT_8 ucIndex; -+ UINT_8 ucFlags; -+ UINT_8 ucReadClear; -+ UINT_8 aucReserved0[1]; -+ UINT_8 aucMacAddr[MAC_ADDR_LEN]; -+ UINT_8 aucReserved1[2]; -+ UINT_8 aucReserved2[16]; -+} CMD_GET_STA_STATISTICS_T, *P_CMD_GET_STA_STATISTICS_T; -+ -+/* CFG_SUPPORT_WFD */ -+typedef struct _EVENT_STA_STATISTICS_T { -+ /* Event header */ -+ /* UINT_16 u2Length; */ -+ /* UINT_16 u2Reserved1; *//* Must be filled with 0x0001 (EVENT Packet) */ -+ /* UINT_8 ucEID; */ -+ /* UINT_8 ucSeqNum; */ -+ /* UINT_8 aucReserved2[2]; */ -+ -+ /* Event Body */ -+ UINT_8 ucVersion; -+ UINT_8 aucReserved1[3]; -+ UINT_32 u4Flags; /* Bit0: valid */ -+ -+ UINT_8 ucStaRecIdx; -+ UINT_8 ucNetworkTypeIndex; -+ UINT_8 ucWTEntry; -+ UINT_8 aucReserved4[1]; -+ -+ UINT_8 ucMacAddr[MAC_ADDR_LEN]; -+ UINT_8 ucPer; /* base: 128 */ -+ UINT_8 ucRcpi; -+ -+ UINT_32 u4PhyMode; /* SGI BW */ -+ UINT_16 u2LinkSpeed; /* unit is 0.5 Mbits */ -+ UINT_8 ucLinkQuality; -+ UINT_8 ucLinkReserved; -+ -+ UINT_32 u4TxCount; -+ UINT_32 u4TxFailCount; -+ UINT_32 u4TxLifeTimeoutCount; -+ UINT_32 u4TxDoneAirTime; -+ -+ UINT_8 aucReserved[64]; -+} EVENT_STA_STATISTICS_T, *P_EVENT_STA_STATISTICS_T; -+ -+#if CFG_SUPPORT_HOTSPOT_OPTIMIZATION -+typedef struct _CMD_HOTSPOT_OPTIMIZATION_CONFIG { -+ UINT_32 fgHotspotOptimizationEn; -+ UINT_32 u4Level; -+} CMD_HOTSPOT_OPTIMIZATION_CONFIG, *P_HOTSPOT_OPTIMIZATION_CONFIG; -+#endif -+#if CFG_AUTO_CHANNEL_SEL_SUPPORT -+ -+/* 4 Auto Channel Selection */ -+ -+typedef struct _CMD_GET_CHN_LOAD_T { -+ UINT_8 ucIndex; -+ UINT_8 ucFlags; -+ UINT_8 ucReadClear; -+ UINT_8 aucReserved0[1]; -+ -+ UINT_8 ucChannel; -+ UINT_16 u2ChannelLoad; -+ UINT_8 aucReserved1[1]; -+ UINT_8 aucReserved2[16]; -+} CMD_GET_CHN_LOAD_T, *P_CMD_GET_CHN_LOAD_T; -+/* 4 Auto Channel Selection */ -+ -+typedef struct _EVENT_CHN_LOAD_T { -+ /* Event Body */ -+ UINT_8 ucVersion; -+ UINT_8 aucReserved1[3]; -+ UINT_32 u4Flags; /* Bit0: valid */ -+ -+ UINT_8 ucChannel; -+ UINT_16 u2ChannelLoad; -+ UINT_8 aucReserved4[1]; -+ -+ UINT_8 aucReserved[64]; -+ -+} EVENT_CHN_LOAD_T, *P_EVENT_CHN_LOAD_T; -+typedef struct _CMD_GET_LTE_SAFE_CHN_T { -+ UINT_8 ucIndex; -+ UINT_8 ucFlags; -+ UINT_8 aucReserved0[2]; -+ -+ UINT_8 aucReserved2[16]; -+} CMD_GET_LTE_SAFE_CHN_T, *P_CMD_GET_LTE_SAFE_CHN_T; -+ -+typedef struct _EVENT_LTE_MODE_T { -+ /* Event Body */ -+ UINT_8 ucVersion; -+ UINT_8 aucReserved1[3]; -+ UINT_32 u4Flags; /* Bit0: valid */ -+ -+ LTE_SAFE_CH_INFO_T rLteSafeChn; -+ UINT_8 aucReserved4[3]; -+ -+ UINT_8 aucReserved[4]; -+ -+} EVENT_LTE_MODE_T, *P_EVENT_LTE_MODE_T; -+#endif -+typedef struct _CMD_ROAMING_INFO_T { -+ UINT_32 fgIsFastRoamingApplied; -+ UINT_32 Reserved[9]; -+} CMD_ROAMING_INFO_T; -+ -+typedef struct _CMD_WFD_DEBUG_MODE_INFO_T { -+ UINT_8 ucDebugMode; -+ UINT_16 u2PeriodInteval; -+ UINT_8 Reserved; -+} CMD_WFD_DEBUG_MODE_INFO_T, *P_CMD_WFD_DEBUG_MODE_INFO_T; -+ -+typedef struct _EVENT_FW_LOG_T { -+ UINT_8 fileName[64]; -+ UINT_32 lineNo; -+ UINT_32 WifiUpTime; -+ UINT_8 log[896]; /* total size is aucBuffer in WIFI_EVENT_T */ -+} EVENT_FW_LOG_T, *P_EVENT_FW_LOG_T; -+ -+typedef enum _ENUM_NLO_CIPHER_ALGORITHM { -+ NLO_CIPHER_ALGO_NONE = 0x00, -+ NLO_CIPHER_ALGO_WEP40 = 0x01, -+ NLO_CIPHER_ALGO_TKIP = 0x02, -+ NLO_CIPHER_ALGO_CCMP = 0x04, -+ NLO_CIPHER_ALGO_WEP104 = 0x05, -+ NLO_CIPHER_ALGO_WPA_USE_GROUP = 0x100, -+ NLO_CIPHER_ALGO_RSN_USE_GROUP = 0x100, -+ NLO_CIPHER_ALGO_WEP = 0x101, -+} ENUM_NLO_CIPHER_ALGORITHM, *P_ENUM_NLO_CIPHER_ALGORITHM; -+ -+typedef enum _ENUM_NLO_AUTH_ALGORITHM { -+ NLO_AUTH_ALGO_80211_OPEN = 1, -+ NLO_AUTH_ALGO_80211_SHARED_KEY = 2, -+ NLO_AUTH_ALGO_WPA = 3, -+ NLO_AUTH_ALGO_WPA_PSK = 4, -+ NLO_AUTH_ALGO_WPA_NONE = 5, -+ NLO_AUTH_ALGO_RSNA = 6, -+ NLO_AUTH_ALGO_RSNA_PSK = 7, -+} ENUM_NLO_AUTH_ALGORITHM, *P_ENUM_NLO_AUTH_ALGORITHM; -+ -+typedef struct _NLO_NETWORK { -+ UINT_8 ucNumChannelHint[4]; -+ UINT_8 ucSSIDLength; -+ UINT_8 ucCipherAlgo; -+ UINT_16 u2AuthAlgo; -+ UINT_8 aucSSID[32]; -+} NLO_NETWORK, *P_NLO_NETWORK; -+ -+typedef struct _CMD_NLO_REQ { -+ UINT_8 ucSeqNum; -+ UINT_8 ucBssIndex; -+ UINT_8 ucNetworkType; -+ UINT_8 fgStopAfterIndication; -+ UINT_8 ucFastScanIteration; -+ UINT_16 u2FastScanPeriod; -+ UINT_16 u2SlowScanPeriod; -+ UINT_8 ucEntryNum; -+ UINT_8 ucReserved; -+ UINT_16 u2IELen; -+ NLO_NETWORK arNetworkList[16]; -+ UINT_8 aucIE[0]; -+ UINT_8 ucScanType; -+} CMD_NLO_REQ, *P_CMD_NLO_REQ; -+ -+typedef struct _CMD_NLO_CANCEL_T { -+ UINT_8 ucSeqNum; -+ UINT_8 aucReserved[3]; -+} CMD_NLO_CANCEL, *P_CMD_NLO_CANCEL; -+ -+typedef struct _EVENT_NLO_DONE_T { -+ UINT_8 ucSeqNum; -+ UINT_8 ucStatus; -+ UINT_8 aucReserved[2]; -+} EVENT_NLO_DONE_T, *P_EVENT_NLO_DONE_T; -+ -+typedef struct _EVENT_GSCAN_CAPABILITY_T { -+ UINT_8 ucVersion; -+ UINT_8 aucReserved1[3]; -+ UINT_32 u4MaxScanCacheSize; -+ UINT_32 u4MaxScanBuckets; -+ UINT_32 u4MaxApCachePerScan; -+ UINT_32 u4MaxRssiSampleSize; -+ UINT_32 u4MaxScanReportingThreshold; -+ UINT_32 u4MaxHotlistAps; -+ UINT_32 u4MaxSignificantWifiChangeAps; -+ UINT_32 au4Reserved[4]; -+} EVENT_GSCAN_CAPABILITY_T, *P_EVENT_GSCAN_CAPABILITY_T; -+ -+typedef struct _EVENT_GSCAN_SCAN_AVAILABLE_T { -+ UINT_16 u2Num; -+ UINT_8 aucReserved[2]; -+} EVENT_GSCAN_SCAN_AVAILABLE_T, *P_EVENT_GSCAN_SCAN_AVAILABLE_T; -+ -+typedef struct _EVENT_GSCAN_SCAN_COMPLETE_T { -+ UINT_8 ucScanState; -+ UINT_8 aucReserved[3]; -+} EVENT_GSCAN_SCAN_COMPLETE_T, *P_EVENT_GSCAN_SCAN_COMPLETE_T; -+ -+typedef struct WIFI_GSCAN_RESULT { -+ UINT_64 u8Ts; /* Time of discovery */ -+ UINT_8 arSsid[ELEM_MAX_LEN_SSID + 1]; /* null terminated */ -+ UINT_8 arMacAddr[6]; /* BSSID */ -+ UINT_32 u4Channel; /* channel frequency in MHz */ -+ INT_32 i4Rssi; /* in db */ -+ UINT_64 u8Rtt; /* in nanoseconds */ -+ UINT_64 u8RttSd; /* standard deviation in rtt */ -+ UINT_16 u2BeaconPeriod; /* units are Kusec */ -+ UINT_16 u2Capability; /* Capability information */ -+ UINT_32 u4IeLength; /* byte length of Information Elements */ -+ UINT_8 ucIeData[1]; /* IE data to follow */ -+} WIFI_GSCAN_RESULT_T, *P_WIFI_GSCAN_RESULT_T; -+ -+typedef struct _EVENT_GSCAN_RESULT_T { -+ UINT_8 ucVersion; -+ UINT_8 aucReserved[3]; -+ UINT_16 u2ScanId; -+ UINT_16 u2ScanFlags; -+ UINT_16 u2NumOfResults; -+ WIFI_GSCAN_RESULT_T rResult[1]; -+} EVENT_GSCAN_RESULT_T, *P_EVENT_GSCAN_RESULT_T; -+ -+typedef struct _EVENT_GSCAN_FULL_RESULT_T { -+ UINT_8 ucVersion; -+ UINT_8 aucReserved[3]; -+ WIFI_GSCAN_RESULT_T rResult; -+} EVENT_GSCAN_FULL_RESULT_T, *P_EVENT_GSCAN_FULL_RESULT_T; -+ -+typedef struct GSCAN_SWC_NET { -+ UINT_16 u2Flags; -+ UINT_16 u2Channel; -+ UINT_8 arBssid[6]; -+ INT_8 aicRssi[SCN_PSCAN_SWC_RSSI_WIN_MAX]; -+} GSCAN_SWC_NET_T, P_GSCAN_SWC_NET_T; -+ -+typedef struct _EVENT_GSCAN_SIGNIFICANT_CHANGE_T { -+ UINT_8 ucVersion; -+ UINT_8 aucReserved[3]; -+ GSCAN_SWC_NET_T arNet[SCN_PSCAN_SWC_MAX_NUM]; -+} EVENT_GSCAN_SIGNIFICANT_CHANGE_T, *P_EVENT_GSCAN_SIGNIFICANT_CHANGE_T; -+ -+typedef struct _EVENT_GSCAN_GEOFENCE_FOUND_T { -+ UINT_8 ucVersion; -+ UINT_8 aucReserved[3]; -+ WIFI_GSCAN_RESULT_T rResult[SCN_PSCAN_HOTLIST_REPORT_MAX_NUM]; -+} EVENT_GSCAN_GEOFENCE_FOUND_T, *P_EVENT_GSCAN_GEOFENCE_FOUND_T; -+ -+#if CFG_SUPPORT_BATCH_SCAN -+ -+#if 0 /* !CFG_SUPPORT_GSCN */ -+typedef struct _CMD_BATCH_REQ_T { -+ UINT_8 ucSeqNum; -+ UINT_8 ucNetTypeIndex; -+ UINT_8 ucCmd; /* Start/ Stop */ -+ UINT_8 ucMScan; /* an integer number of scans per batch */ -+ UINT_8 ucBestn; /* an integer number of the max AP to remember per scan */ -+ UINT_8 ucRtt; /* an integer number of highest-strength AP for which -+ we'd like approximate distance reported */ -+ UINT_8 ucChannel; /* channels */ -+ UINT_8 ucChannelType; -+ UINT_8 ucChannelListNum; -+ UINT_8 aucReserved[3]; -+ UINT_32 u4Scanfreq; /* an integer number of seconds between scans */ -+ CHANNEL_INFO_T arChannelList[32]; /* channels */ -+} CMD_BATCH_REQ_T, *P_CMD_BATCH_REQ_T; -+ -+#endif -+ -+typedef struct _EVENT_BATCH_RESULT_ENTRY_T { -+ UINT_8 aucBssid[MAC_ADDR_LEN]; -+ UINT_8 aucSSID[ELEM_MAX_LEN_SSID]; -+ UINT_8 ucSSIDLen; -+ INT_8 cRssi; -+ UINT_32 ucFreq; -+ UINT_32 u4Age; -+ UINT_32 u4Dist; -+ UINT_32 u4Distsd; -+} EVENT_BATCH_RESULT_ENTRY_T, *P_EVENT_BATCH_RESULT_ENTRY_T; -+ -+typedef struct _EVENT_BATCH_RESULT_T { -+ UINT_8 ucScanCount; -+ UINT_8 aucReserved[3]; -+ EVENT_BATCH_RESULT_ENTRY_T arBatchResult[12]; /* Must be the same with SCN_BATCH_STORE_MAX_NUM */ -+} EVENT_BATCH_RESULT_T, *P_EVENT_BATCH_RESULT_T; -+#endif -+ -+typedef struct _CMD_RLM_INFO_T { -+ UINT_32 u4Version; -+ UINT_32 fgIsErrRatioEnhanceApplied; -+ UINT_8 ucErrRatio2LimitMinRate; -+ /* -+ 0:1M, 1:2M, 2:5.5M, 3:11M, 6:6M, 7:9M, 8:12M, 9:18M, 10:24M, 11:36M, 12:48M, 13:54M -+ */ -+ UINT_8 ucMinLegacyRateIdx; -+ INT_8 cMinRssiThreshold; -+ BOOLEAN fgIsRtsApplied; -+ UINT_8 ucRecoverTime; -+ -+ UINT_32 u4Reserved[0]; -+} CMD_RLM_INFO_T; -+ -+typedef struct _WIFI_SYSTEM_SUSPEND_CMD_T { -+ BOOLEAN fgIsSystemSuspend; -+ UINT_8 reserved[3]; -+} WIFI_SYSTEM_SUSPEND_CMD_T, *P_WIFI_SYSTEM_SUSPEND_CMD_T; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+VOID nicCmdEventQueryMcrRead(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); -+ -+VOID nicCmdEventQueryMemDump(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); -+ -+VOID nicCmdEventQuerySwCtrlRead(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); -+ -+VOID nicCmdEventQueryRfTestATInfo(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); -+ -+VOID nicCmdEventSetCommon(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); -+ -+VOID nicCmdEventSetDisassociate(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); -+ -+VOID nicCmdEventSetIpAddress(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); -+ -+VOID nicCmdEventQueryLinkQuality(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); -+ -+VOID nicCmdEventQueryLinkSpeed(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); -+ -+VOID nicCmdEventQueryStatistics(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); -+ -+VOID nicCmdEventEnterRfTest(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); -+ -+VOID nicCmdEventLeaveRfTest(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); -+ -+VOID nicCmdEventQueryAddress(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); -+ -+VOID nicCmdEventQueryMcastAddr(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); -+ -+VOID nicCmdEventQueryEepromRead(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); -+ -+VOID nicCmdEventSetMediaStreamMode(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); -+ -+/* Statistics responder */ -+VOID nicCmdEventQueryXmitOk(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); -+ -+VOID nicCmdEventQueryRecvOk(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); -+ -+VOID nicCmdEventQueryXmitError(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); -+ -+VOID nicCmdEventQueryRecvError(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); -+ -+VOID nicCmdEventQueryRecvNoBuffer(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); -+ -+VOID nicCmdEventQueryRecvCrcError(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); -+ -+VOID nicCmdEventQueryRecvErrorAlignment(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); -+ -+VOID nicCmdEventQueryXmitOneCollision(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); -+ -+VOID nicCmdEventQueryXmitMoreCollisions(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); -+ -+VOID nicCmdEventQueryXmitMaxCollisions(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); -+ -+/* for timeout check */ -+VOID nicOidCmdTimeoutCommon(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo); -+ -+VOID nicCmdTimeoutCommon(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo); -+ -+VOID nicOidCmdEnterRFTestTimeout(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo); -+ -+#if CFG_SUPPORT_BUILD_DATE_CODE -+VOID nicCmdEventBuildDateCode(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); -+#endif -+ -+VOID nicCmdEventQueryStaStatistics(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); -+ -+#if CFG_AUTO_CHANNEL_SEL_SUPPORT -+/* 4 Auto Channel Selection */ -+VOID nicCmdEventQueryChannelLoad(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); -+ -+VOID nicCmdEventQueryLTESafeChn(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); -+#endif -+ -+#if CFG_SUPPORT_BATCH_SCAN -+VOID nicCmdEventBatchScanResult(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); -+#endif -+ -+VOID nicCmdEventGetBSSInfo(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif /* _NIC_CMD_EVENT_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic_init_cmd_event.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic_init_cmd_event.h -new file mode 100644 -index 000000000000..994c589190de ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/nic_init_cmd_event.h -@@ -0,0 +1,177 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/nic_init_cmd_event.h#1 -+*/ -+ -+/*! \file "nic_init_cmd_event.h" -+ \brief This file contains the declairation file of the WLAN initialization routines -+ for MediaTek Inc. 802.11 Wireless LAN Adapters. -+*/ -+ -+/* -+** Log: nic_init_cmd_event.h -+ * -+ * 09 26 2011 cp.wu -+ * [WCXRP00001011] [MT6628 Wi-Fi] Firmware Download Agent: make CRC validation as an optional feature -+ * add definition for disabling CRC32 validation (for MT6628 only) -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 03 12 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * add two option for ACK and ENCRYPTION for firmware download -+ * -+ * 03 01 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * add command/event definitions for initial states -+ * -+ * 02 10 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * implement host-side firmware download logic -+ * -+ * 02 08 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * prepare for implementing fw download logic -+ * -+*/ -+#ifndef _NIC_INIT_CMD_EVENT_H -+#define _NIC_INIT_CMD_EVENT_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+#include "gl_typedef.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+#define INIT_CMD_STATUS_SUCCESS 0 -+#define INIT_CMD_STATUS_REJECTED_INVALID_PARAMS 1 -+#define INIT_CMD_STATUS_REJECTED_CRC_ERROR 2 -+#define INIT_CMD_STATUS_REJECTED_DECRYPT_FAIL 3 -+#define INIT_CMD_STATUS_UNKNOWN 4 -+ -+#define EVENT_HDR_SIZE OFFSET_OF(WIFI_EVENT_T, aucBuffer[0]) -+ -+typedef enum _ENUM_INIT_CMD_ID { -+ INIT_CMD_ID_DOWNLOAD_BUF = 1, -+ INIT_CMD_ID_WIFI_START, -+ INIT_CMD_ID_ACCESS_REG, -+ INIT_CMD_ID_QUERY_PENDING_ERROR -+} ENUM_INIT_CMD_ID, *P_ENUM_INIT_CMD_ID; -+ -+typedef enum _ENUM_INIT_EVENT_ID { -+ INIT_EVENT_ID_CMD_RESULT = 1, -+ INIT_EVENT_ID_ACCESS_REG, -+ INIT_EVENT_ID_PENDING_ERROR -+} ENUM_INIT_EVENT_ID, *P_ENUM_INIT_EVENT_ID; -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+typedef UINT_8 CMD_STATUS; -+ -+/* commands */ -+typedef struct _INIT_WIFI_CMD_T { -+ UINT_8 ucCID; -+ UINT_8 ucSeqNum; -+ UINT_16 u2Reserved; -+ UINT_8 aucBuffer[0]; -+} INIT_WIFI_CMD_T, *P_INIT_WIFI_CMD_T; -+ -+typedef struct _INIT_HIF_TX_HEADER_T { -+ UINT_16 u2TxByteCount; -+ UINT_8 ucEtherTypeOffset; -+ UINT_8 ucCSflags; -+ INIT_WIFI_CMD_T rInitWifiCmd; -+} INIT_HIF_TX_HEADER_T, *P_INIT_HIF_TX_HEADER_T; -+ -+#define DOWNLOAD_BUF_ENCRYPTION_MODE BIT(0) -+#define DOWNLOAD_BUF_NO_CRC_CHECKING BIT(30) -+#define DOWNLOAD_BUF_ACK_OPTION BIT(31) -+typedef struct _INIT_CMD_DOWNLOAD_BUF { -+ UINT_32 u4Address; -+ UINT_32 u4Length; -+ UINT_32 u4CRC32; -+ UINT_32 u4DataMode; -+ UINT_8 aucBuffer[0]; -+} INIT_CMD_DOWNLOAD_BUF, *P_INIT_CMD_DOWNLOAD_BUF; -+ -+typedef struct _INIT_CMD_WIFI_START { -+ UINT_32 u4Override; -+ UINT_32 u4Address; -+} INIT_CMD_WIFI_START, *P_INIT_CMD_WIFI_START; -+ -+typedef struct _INIT_CMD_ACCESS_REG { -+ UINT_8 ucSetQuery; -+ UINT_8 aucReserved[3]; -+ UINT_32 u4Address; -+ UINT_32 u4Data; -+} INIT_CMD_ACCESS_REG, *P_INIT_CMD_ACCESS_REG; -+ -+/* Events */ -+typedef struct _INIT_WIFI_EVENT_T { -+ UINT_16 u2RxByteCount; -+ UINT_8 ucEID; -+ UINT_8 ucSeqNum; -+ UINT_8 aucBuffer[0]; -+} INIT_WIFI_EVENT_T, *P_INIT_WIFI_EVENT_T; -+ -+typedef struct _INIT_HIF_RX_HEADER_T { -+ INIT_WIFI_EVENT_T rInitWifiEvent; -+} INIT_HIF_RX_HEADER_T, *P_INIT_HIF_RX_HEADER_T; -+ -+typedef struct _INIT_EVENT_CMD_RESULT { -+ UINT_8 ucStatus; /* 0: success */ -+ /* 1: rejected by invalid param */ -+ /* 2: rejected by incorrect CRC */ -+ /* 3: rejected by decryption failure */ -+ /* 4: unknown CMD */ -+ UINT_8 aucReserved[3]; -+} INIT_EVENT_CMD_RESULT, *P_INIT_EVENT_CMD_RESULT, INIT_EVENT_PENDING_ERROR, *P_INIT_EVENT_PENDING_ERROR; -+ -+typedef struct _INIT_EVENT_ACCESS_REG { -+ UINT_32 u4Address; -+ UINT_32 u4Data; -+} INIT_EVENT_ACCESS_REG, *P_INIT_EVENT_ACCESS_REG; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif /* _NIC_INIT_CMD_EVENT_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/p2p_precomp.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/p2p_precomp.h -new file mode 100644 -index 000000000000..85af819f4e62 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/p2p_precomp.h -@@ -0,0 +1,201 @@ -+/* -+** Id: //Department/DaVinci/TRUNK/WiFi_P2P_Driver/include/p2p_precomp.h#1 -+*/ -+ -+/*! \file p2p_precomp.h -+ \brief Collection of most compiler flags for p2p driver are described here. -+ -+ In this file we collect all compiler flags and detail the p2p driver behavior if -+ enable/disable such switch or adjust numeric parameters. -+*/ -+ -+#ifndef _P2P_PRECOMP_H -+#define _P2P_PRECOMP_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "gl_os.h" /* Include "config.h" */ -+ -+#include "gl_p2p_os.h" -+ -+#include "debug.h" -+ -+#include "link.h" -+#include "queue.h" -+ -+/*------------------------------------------------------------------------------ -+ * .\include\mgmt -+ *------------------------------------------------------------------------------ -+ */ -+#include "wlan_typedef.h" -+ -+#include "mac.h" -+ -+/* Dependency: mac.h (MAC_ADDR_LEN) */ -+#include "wlan_def.h" -+ -+#include "roaming_fsm.h" -+ -+/*------------------------------------------------------------------------------ -+ * .\include\nic -+ *------------------------------------------------------------------------------ -+ */ -+/* Dependency: wlan_def.h (ENUM_NETWORK_TYPE_T) */ -+#include "cmd_buf.h" -+ -+/* Dependency: mac.h (MAC_ADDR_LEN) */ -+#include "nic_cmd_event.h" -+ -+/* Dependency: nic_cmd_event.h (P_EVENT_CONNECTION_STATUS) */ -+#include "nic.h" -+ -+#include "nic_init_cmd_event.h" -+ -+#include "hif_rx.h" -+#include "hif_tx.h" -+ -+#include "nic_tx.h" -+ -+/* Dependency: hif_rx.h (P_HIF_RX_HEADER_T) */ -+#include "nic_rx.h" -+ -+#include "que_mgt.h" -+ -+#if CFG_ENABLE_WIFI_DIRECT -+#include "p2p_typedef.h" -+#include "p2p_cmd_buf.h" -+#include "p2p_nic_cmd_event.h" -+#include "p2p_mac.h" -+#include "p2p_nic.h" -+#endif -+ -+/*------------------------------------------------------------------------------ -+ * .\include\mgmt -+ *------------------------------------------------------------------------------ -+ */ -+ -+#include "hem_mbox.h" -+ -+#include "scan.h" -+#include "bss.h" -+ -+#include "wlan_lib.h" -+#include "wlan_oid.h" -+#include "wlan_bow.h" -+ -+#include "wlan_p2p.h" -+ -+#include "hal.h" -+ -+#if defined(MT6620) -+#include "mt6620_reg.h" -+#endif -+ -+#include "rlm.h" -+#include "rlm_domain.h" -+#include "rlm_protection.h" -+#include "rlm_obss.h" -+#include "rate.h" -+ -+#include "aa_fsm.h" -+ -+#include "cnm_timer.h" -+ -+#if CFG_ENABLE_BT_OVER_WIFI -+#include "bow.h" -+#include "bow_fsm.h" -+#endif -+ -+#include "pwr_mgt.h" -+ -+#include "cnm.h" -+/* Dependency: aa_fsm.h (ENUM_AA_STATE_T), p2p_fsm.h (WPS_ATTRI_MAX_LEN_DEVICE_NAME) */ -+#include "cnm_mem.h" -+#include "cnm_scan.h" -+ -+#include "p2p_rlm_obss.h" -+#include "p2p_bss.h" -+#include "p2p.h" -+/* Dependency: cnm_timer.h (TIMER_T) */ -+#include "p2p_fsm.h" -+#include "p2p_scan.h" -+#include "p2p_state.h" -+#include "p2p_func.h" -+#include "p2p_rlm.h" -+#include "p2p_assoc.h" -+#include "p2p_ie.h" -+ -+#include "privacy.h" -+ -+#include "mib.h" -+ -+#include "auth.h" -+#include "assoc.h" -+ -+#include "ais_fsm.h" -+ -+#include "adapter.h" -+ -+#include "que_mgt.h" -+#include "rftest.h" -+ -+#if CFG_RSN_MIGRATION -+#include "rsn.h" -+#include "sec_fsm.h" -+#endif -+ -+#if CFG_SUPPORT_WAPI -+#include "wapi.h" -+#endif -+ -+/*------------------------------------------------------------------------------ -+ * NVRAM structure -+ *------------------------------------------------------------------------------ -+ */ -+#include "CFG_Wifi_File.h" -+ -+#include "gl_p2p_kal.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif /*_P2P_PRECOMP_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/p2p_typedef.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/p2p_typedef.h -new file mode 100644 -index 000000000000..a02d391d3643 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/p2p_typedef.h -@@ -0,0 +1,165 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/p2p_typedef.h#1 -+*/ -+ -+/*! \file p2p_typedef.h -+ \brief Declaration of data type and return values of internal protocol stack. -+ -+ In this file we declare the data type and return values which will be exported -+ to all MGMT Protocol Stack. -+*/ -+ -+#ifndef _P2P_TYPEDEF_H -+#define _P2P_TYPEDEF_H -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/* -+* type definition of pointer to p2p structure -+*/ -+/* typedef struct _GL_P2P_INFO_T GL_P2P_INFO_T, *P_GL_P2P_INFO_T; */ -+typedef struct _P2P_INFO_T P2P_INFO_T, *P_P2P_INFO_T; -+ -+typedef struct _P2P_FSM_INFO_T P2P_FSM_INFO_T, *P_P2P_FSM_INFO_T; -+ -+typedef struct _P2P_CONNECTION_SETTINGS_T P2P_CONNECTION_SETTINGS_T, *P_P2P_CONNECTION_SETTINGS_T; -+ -+/* Type definition for function pointer to p2p function*/ -+typedef BOOLEAN(*P2P_LAUNCH) (P_GLUE_INFO_T prGlueInfo); -+ -+typedef BOOLEAN(*P2P_REMOVE) (P_GLUE_INFO_T prGlueInfo, BOOLEAN fgIsWlanLaunched); -+ -+typedef BOOLEAN(*KAL_P2P_GET_CIPHER) (IN P_GLUE_INFO_T prGlueInfo); -+ -+typedef BOOLEAN(*KAL_P2P_GET_TKIP_CIPHER) (IN P_GLUE_INFO_T prGlueInfo); -+ -+typedef BOOLEAN(*KAL_P2P_GET_CCMP_CIPHER) (IN P_GLUE_INFO_T prGlueInfo); -+ -+typedef BOOLEAN(*KAL_P2P_GET_WSC_MODE) (IN P_GLUE_INFO_T prGlueInfo); -+ -+typedef struct net_device *(*KAL_P2P_GET_DEV_HDLR) (P_GLUE_INFO_T prGlueInfo); -+ -+typedef VOID(*KAL_P2P_SET_MULTICAST_WORK_ITEM) (P_GLUE_INFO_T prGlueInfo); -+ -+typedef VOID(*P2P_NET_REGISTER) (P_GLUE_INFO_T prGlueInfo); -+ -+typedef VOID(*P2P_NET_UNREGISTER) (P_GLUE_INFO_T prGlueInfo); -+ -+typedef VOID(*KAL_P2P_UPDATE_ASSOC_INFO) (IN P_GLUE_INFO_T prGlueInfo, -+ IN PUINT_8 pucFrameBody, -+ IN UINT_32 u4FrameBodyLen, IN BOOLEAN fgReassocRequest); -+ -+typedef BOOLEAN(*P2P_VALIDATE_AUTH) (IN P_ADAPTER_T prAdapter, -+ IN P_SW_RFB_T prSwRfb, IN PP_STA_RECORD_T pprStaRec, OUT PUINT_16 pu2StatusCode); -+ -+typedef BOOLEAN(*P2P_VALIDATE_ASSOC_REQ) (IN P_ADAPTER_T prAdapter, -+ IN P_SW_RFB_T prSwRfb, OUT PUINT_16 pu4ControlFlags); -+ -+typedef VOID(*P2P_RUN_EVENT_AAA_TX_FAIL) (IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec); -+ -+typedef BOOLEAN(*P2P_PARSE_CHECK_FOR_P2P_INFO_ELEM) (IN P_ADAPTER_T prAdapter, -+ IN PUINT_8 pucBuf, OUT PUINT_8 pucOuiType); -+ -+typedef WLAN_STATUS(*P2P_RUN_EVENT_AAA_COMPLETE) (IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec); -+ -+typedef VOID(*P2P_PROCESS_EVENT_UPDATE_NOA_PARAM) (IN P_ADAPTER_T prAdapter, -+ UINT_8 ucNetTypeIndex, -+ P_EVENT_UPDATE_NOA_PARAMS_T prEventUpdateNoaParam); -+ -+typedef VOID(*SCAN_P2P_PROCESS_BEACON_AND_PROBE_RESP) (IN P_ADAPTER_T prAdapter, -+ IN P_SW_RFB_T prSwRfb, -+ IN P_WLAN_STATUS prStatus, -+ IN P_BSS_DESC_T prBssDesc, -+ IN P_WLAN_BEACON_FRAME_T prWlanBeaconFrame); -+ -+typedef VOID(*P2P_RX_PUBLIC_ACTION_FRAME) (P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); -+ -+typedef VOID(*RLM_RSP_GENERATE_OBSS_SCAN_IE) (P_ADAPTER_T prAdapter, P_MSDU_INFO_T prMsduInfo); -+ -+typedef VOID(*RLM_UPDATE_BW_BY_CH_LIST_FOR_AP) (P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo); -+ -+typedef VOID(*RLM_PROCESS_PUBLIC_ACTION) (P_ADAPTER_T prAdapter, P_SW_RFB_T prSwRfb); -+ -+typedef VOID(*RLM_PROCESS_HT_ACTION) (P_ADAPTER_T prAdapter, P_SW_RFB_T prSwRfb); -+ -+typedef VOID(*RLM_UPDATE_PARAMS_FOR_AP) (P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo, BOOLEAN fgUpdateBeacon); -+ -+typedef VOID(*RLM_HANDLE_OBSS_STATUS_EVENT_PKT) (P_ADAPTER_T prAdapter, P_EVENT_AP_OBSS_STATUS_T prObssStatus); -+ -+typedef BOOLEAN(*P2P_FUNC_VALIDATE_PROBE_REQ) (IN P_ADAPTER_T prAdapter, -+ IN P_SW_RFB_T prSwRfb, OUT PUINT_32 pu4ControlFlags); -+ -+typedef VOID(*RLM_BSS_INIT_FOR_AP) (P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo); -+ -+typedef UINT_32(*P2P_GET_PROB_RSP_IE_TABLE_SIZE) (VOID); -+ -+typedef PUINT_8(*P2P_BUILD_REASSOC_REQ_FRAME_COMMON_IES) (IN P_ADAPTER_T prAdapter, -+ IN P_MSDU_INFO_T prMsduInfo, IN PUINT_8 pucBuffer); -+ -+typedef VOID(*P2P_FUNC_DISCONNECT) (IN P_ADAPTER_T prAdapter, -+ IN P_STA_RECORD_T prStaRec, IN BOOLEAN fgSendDeauth, IN UINT_16 u2ReasonCode); -+ -+typedef VOID(*P2P_FSM_RUN_EVENT_RX_DEAUTH) (IN P_ADAPTER_T prAdapter, -+ IN P_STA_RECORD_T prStaRec, IN P_SW_RFB_T prSwRfb); -+ -+typedef VOID(*P2P_FSM_RUN_EVENT_RX_DISASSOC) (IN P_ADAPTER_T prAdapter, -+ IN P_STA_RECORD_T prStaRec, IN P_SW_RFB_T prSwRfb); -+ -+typedef BOOLEAN(*P2P_FUN_IS_AP_MODE) (IN P_P2P_FSM_INFO_T prP2pFsmInfo); -+ -+typedef VOID(*P2P_FSM_RUN_EVENT_BEACON_TIMEOUT) (IN P_ADAPTER_T prAdapter); -+ -+typedef VOID(*P2P_FUNC_STORE_ASSOC_RSP_IE_BUFFER) (IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb); -+ -+typedef VOID(*P2P_GENERATE_P2P_IE) (IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); -+ -+typedef UINT_32(*P2P_CALCULATE_P2P_IE_LEN) (IN P_ADAPTER_T prAdapter, -+ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec); -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+#endif /*CFG_ENABLE_WIFI_DIRECT */ -+ -+#endif /* _P2P_TYPEDEF_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/precomp.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/precomp.h -new file mode 100644 -index 000000000000..1b7e7ede66e1 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/precomp.h -@@ -0,0 +1,388 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/precomp.h#2 -+*/ -+ -+/*! \file precomp.h -+ \brief Collection of most compiler flags are described here. -+ -+ In this file we collect all compiler flags and detail the driver behavior if -+ enable/disable such switch or adjust numeric parameters. -+*/ -+ -+/* -+** Log: precomp.h -+ * -+ * 07 17 2012 yuche.tsai -+ * NULL -+ * Compile no error before trial run. -+ * -+ * 01 05 2012 tsaiyuan.hsu -+ * [WCXRP00001157] [MT6620 Wi-Fi][FW][DRV] add timing measurement support for 802.11v -+ * add timing measurement support for 802.11v. -+ * -+ * 08 15 2011 cp.wu -+ * [WCXRP00000851] [MT6628 Wi-Fi][Driver] Add HIFSYS related definition to driver source tree -+ * add MT6628-specific definitions. -+ * -+ * 04 18 2011 terry.wu -+ * [WCXRP00000660] [MT6620 Wi-Fi][Driver] Remove flag CFG_WIFI_DIRECT_MOVED -+ * Remove flag CFG_WIFI_DIRECT_MOVED. -+ * -+ * 03 15 2011 eddie.chen -+ * [WCXRP00000554] [MT6620 Wi-Fi][DRV] Add sw control debug counter -+ * Add sw debug counter for QM. -+ * -+ * 01 27 2011 tsaiyuan.hsu -+ * [WCXRP00000392] [MT6620 Wi-Fi][Driver] Add Roaming Support -+ * add roaming fsm -+ * 1. not support 11r, only use strength of signal to determine roaming. -+ * 2. not enable CFG_SUPPORT_ROAMING until completion of full test. -+ * 3. in 6620, adopt work-around to avoid sign extension problem of cck of hw -+ * 4. assume that change of link quality in smooth way. -+ * -+ * 12 13 2010 cp.wu -+ * [WCXRP00000260] [MT6620 Wi-Fi][Driver][Firmware] Create V1.1 branch for both firmware and driver -+ * create branch for Wi-Fi driver v1.1 -+ * -+ * 10 07 2010 cp.wu -+ * [WCXRP00000083] [MT5931][Driver][FW] Add necessary logic for MT5931 first connection -+ * add firmware download for MT5931. -+ * -+ * 10 05 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check -+ * 1) add NVRAM access API -+ * 2) fake scanning result when NVRAM doesn't exist and/or version mismatch. (off by compiler option) -+ * 3) add OID implementation for NVRAM read/write service -+ * -+ * 09 21 2010 kevin.huang -+ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning -+ * Isolate P2P related function for Hardware Software Bundle -+ * -+ * 09 14 2010 chinghwa.yu -+ * NULL -+ * Fix BOW_FSM_INFO_T dependence. -+ * -+ * 09 03 2010 kevin.huang -+ * NULL -+ * Refine #include sequence and solve recursive/nested #include issue -+ * -+ * 07 20 2010 wh.su -+ * -+ * adding the wapi code. -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 07 08 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Check draft RLM code for HT cap -+ * -+ * 07 01 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Modify CNM message handler for new flow -+ * -+ * 06 28 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * 1st draft code for RLM module -+ * -+ * 06 19 2010 wh.su -+ * [WPD00003840][MT6620 5931] Security migration -+ * consdier the concurrent network setting. -+ * -+ * 06 18 2010 wh.su -+ * [WPD00003840][MT6620 5931] Security migration -+ * migration the security related function from firmware. -+ * -+ * 06 18 2010 wh.su -+ * [WPD00003840][MT6620 5931] Security migration -+ * migration from MT6620 firmware. -+ * -+ * 06 08 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add hem_mbox.c and cnm_mem.h (but disabled some feature) for further migration -+ * -+ * 06 07 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * merge cnm_scan.h and hem_mbox.h -+ * -+ * 06 07 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * merge wifi_var.h, precomp.h, cnm_timer.h (data type only) -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 05 17 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * 1) add timeout handler mechanism for pending command packets -+ * 2) add p2p add/removal key -+ * -+ * 04 13 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * add framework for BT-over-Wi-Fi support. -+ * * * * * * * * * * * 1) prPendingCmdInfo is replaced by queue for multiple handler capability -+ * * * * * * * * * * * 2) command sequence number is now increased atomically -+ * * * * * * * * * * * 3) private data could be hold and taken use for other purpose -+ * -+ * 03 16 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * build up basic data structure and definitions to support BT-over-WiFi -+ * -+ * 02 08 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * prepare for implementing fw download logic -+ * -+ * 01 27 2010 wh.su -+ * [WPD00003816][MT6620 Wi-Fi] Adding the security support -+ * . -+** \main\maintrunk.MT6620WiFiDriver_Prj\9 2009-12-08 11:30:58 GMT mtk02752 -+** add rftest.h for implementing RF test mode in driver land -+** \main\maintrunk.MT6620WiFiDriver_Prj\8 2009-11-23 22:02:00 GMT mtk02468 -+** Added que_mgt.h -+** \main\maintrunk.MT6620WiFiDriver_Prj\7 2009-10-13 21:58:36 GMT mtk01084 -+** update for new macro define -+** \main\maintrunk.MT6620WiFiDriver_Prj\6 2009-04-21 09:40:11 GMT mtk01461 -+** Add nic_cmd_event.h -+** \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-04-17 20:00:26 GMT mtk01461 -+** Add cmd_buf.h -+** \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-03-19 18:32:44 GMT mtk01084 -+** update for basic power management functions -+** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-03-16 09:08:25 GMT mtk01461 -+** Update TX PATH API -+** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 20:11:38 GMT mtk01426 -+** Init for develop -+** -+*/ -+ -+#ifndef _PRECOMP_H -+#define _PRECOMP_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "gl_os.h" /* Include "config.h" */ -+ -+#if CFG_ENABLE_WIFI_DIRECT -+#include "gl_p2p_os.h" -+#endif -+ -+#include "debug.h" -+ -+#include "link.h" -+#include "queue.h" -+ -+/*------------------------------------------------------------------------------ -+ * .\include\mgmt -+ *------------------------------------------------------------------------------ -+ */ -+#include "wlan_typedef.h" -+ -+#include "mac.h" -+ -+/* Dependency: mac.h (MAC_ADDR_LEN) */ -+#include "wlan_def.h" -+ -+#if CFG_SUPPORT_SWCR -+#include "swcr.h" -+#endif -+ -+/*------------------------------------------------------------------------------ -+ * .\include\nic -+ *------------------------------------------------------------------------------ -+ */ -+/* Dependency: wlan_def.h (ENUM_NETWORK_TYPE_T) */ -+#include "cmd_buf.h" -+ -+/* Dependency: mac.h (MAC_ADDR_LEN) */ -+#include "nic_cmd_event.h" -+ -+/* Dependency: nic_cmd_event.h (P_EVENT_CONNECTION_STATUS) */ -+#include "nic.h" -+ -+#include "nic_init_cmd_event.h" -+ -+#include "hif_rx.h" -+#include "hif_tx.h" -+ -+#include "nic_tx.h" -+ -+/* Dependency: hif_rx.h (P_HIF_RX_HEADER_T) */ -+#include "nic_rx.h" -+ -+#include "que_mgt.h" -+ -+#if CFG_ENABLE_WIFI_DIRECT -+#include "p2p_typedef.h" -+#include "p2p_cmd_buf.h" -+#include "p2p_nic_cmd_event.h" -+#include "p2p_mac.h" -+#include "p2p_nic.h" -+#endif -+ -+/*------------------------------------------------------------------------------ -+ * .\include\mgmt -+ *------------------------------------------------------------------------------ -+ */ -+ -+#include "hem_mbox.h" -+ -+#include "scan.h" -+#include "bss.h" -+ -+#include "wlan_lib.h" -+#include "wlan_oid.h" -+#include "wlan_bow.h" -+ -+#if CFG_ENABLE_WIFI_DIRECT -+#include "wlan_p2p.h" -+#endif -+ -+#include "hal.h" -+ -+#if defined(MT6620) -+#include "mt6620_reg.h" -+#elif defined(MT6628) -+/* #include "mt6628_reg.h" */ -+#include "mtreg.h" -+#endif -+ -+#include "rlm.h" -+#include "rlm_domain.h" -+#include "rlm_protection.h" -+#include "rlm_obss.h" -+#include "rate.h" -+#if CFG_SUPPORT_802_11V -+#include "wnm.h" -+#endif -+ -+#include "aa_fsm.h" -+ -+#include "cnm_timer.h" -+ -+#if CFG_ENABLE_BT_OVER_WIFI -+#include "bow.h" -+#include "bow_fsm.h" -+#endif -+ -+#include "pwr_mgt.h" -+ -+#if (CFG_SUPPORT_STATISTICS == 1) -+#include "stats.h" -+#endif /* CFG_SUPPORT_STATISTICS */ -+ -+#include "cnm.h" -+/* Dependency: aa_fsm.h (ENUM_AA_STATE_T), p2p_fsm.h (WPS_ATTRI_MAX_LEN_DEVICE_NAME) */ -+#include "cnm_mem.h" -+#include "cnm_scan.h" -+ -+#if CFG_ENABLE_WIFI_DIRECT -+#include "p2p_rlm_obss.h" -+#include "p2p_bss.h" -+#include "p2p.h" -+#include "p2p_fsm.h" -+#include "p2p_scan.h" -+#include "p2p_state.h" -+#include "p2p_func.h" -+#include "p2p_rlm.h" -+#include "p2p_assoc.h" -+#include "p2p_ie.h" -+#endif -+ -+#include "privacy.h" -+ -+#include "mib.h" -+ -+#include "auth.h" -+#include "assoc.h" -+ -+#if CFG_SUPPORT_ROAMING -+#include "roaming_fsm.h" -+#endif /* CFG_SUPPORT_ROAMING */ -+ -+#include "ais_fsm.h" -+ -+#include "adapter.h" -+ -+#include "que_mgt.h" -+#include "rftest.h" -+ -+#if CFG_RSN_MIGRATION -+#include "rsn.h" -+#include "sec_fsm.h" -+#endif -+ -+#if CFG_SUPPORT_WAPI -+#include "wapi.h" -+#endif -+ -+/*------------------------------------------------------------------------------ -+ * NVRAM structure -+ *------------------------------------------------------------------------------ -+ */ -+#include "CFG_Wifi_File.h" -+ -+#if CFG_ENABLE_WIFI_DIRECT -+#include "gl_p2p_kal.h" -+#endif -+ -+typedef int (*set_p2p_mode) (struct net_device *netdev, PARAM_CUSTOM_P2P_SET_STRUCT_T p2pmode); -+typedef void (*set_dbg_level) (unsigned char modules[DBG_MODULE_NUM]); -+ -+extern void wlanRegisterNotifier(void); -+extern void wlanUnregisterNotifier(void); -+extern void register_set_p2p_mode_handler(set_p2p_mode handler); -+extern void register_set_dbg_level_handler(set_dbg_level handler); -+ -+#if CFG_TC1_FEATURE -+#define NIC_INF_NAME_IN_AP_MODE "legacy%d" -+extern volatile int wlan_if_changed; -+#endif -+extern BOOLEAN fgIsResetting; -+ -+extern UINT_8 g_aucBufIpAddr[32]; -+extern UINT_8 aucDebugModule[]; -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif /* _PRECOMP_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/pwr_mgt.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/pwr_mgt.h -new file mode 100644 -index 000000000000..40f52dcc9d68 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/pwr_mgt.h -@@ -0,0 +1,141 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/pwr_mgt.h#1 -+*/ -+ -+/*! \file "pwr_mgt.h" -+ \brief In this file we define the STATE and EVENT for Power Management FSM. -+ -+ The SCAN FSM is responsible for performing SCAN behavior when the Arbiter enter -+ ARB_STATE_SCAN. The STATE and EVENT for SCAN FSM are defined here with detail -+ description. -+*/ -+ -+/* -+** Log: pwr_mgt.h -+ * -+ * 07 09 2010 george.huang -+ * -+ * [WPD00001556] Migrate PM variables from FW to driver: for composing QoS Info -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 04 20 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * don't need SPIN_LOCK_PWR_CTRL anymore, it will raise IRQL -+ * and cause SdBusSubmitRequest running at DISPATCH_LEVEL as well. -+ -+ * -+ * 03 25 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * firmware download load address & start address are now configured from config.h -+ * * * due to the different configurations on FPGA and ASIC -+** \main\maintrunk.MT6620WiFiDriver_Prj\7 2009-12-10 16:39:10 GMT mtk02752 -+** disable PM macros temporally -+** \main\maintrunk.MT6620WiFiDriver_Prj\6 2009-10-29 19:48:37 GMT mtk01084 -+** temp remove power management macro -+** \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-04-08 16:51:11 GMT mtk01084 -+** update for power management control macro -+** \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-04-03 14:59:58 GMT mtk01426 -+** Add #if CFG_HIF_LOOPBACK_PRETEST -+** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-03-23 16:53:10 GMT mtk01084 -+** modify ACQUIRE_POWER_CONTROL_FROM_PM() and RECLAIM_POWER_CONTROL_TO_PM() macro -+** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-19 18:32:47 GMT mtk01084 -+** update for basic power management functions -+** \main\maintrunk.MT6620WiFiDriver_Prj\1 2009-03-19 15:05:20 GMT mtk01084 -+** Initial version -+** -+*/ -+ -+#ifndef _PWR_MGT_H -+#define _PWR_MGT_H -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+#define PM_UAPSD_AC0 (BIT(0)) -+#define PM_UAPSD_AC1 (BIT(1)) -+#define PM_UAPSD_AC2 (BIT(2)) -+#define PM_UAPSD_AC3 (BIT(3)) -+ -+#define PM_UAPSD_ALL (PM_UAPSD_AC0 | PM_UAPSD_AC1 | PM_UAPSD_AC2 | PM_UAPSD_AC3) -+#define PM_UAPSD_NONE 0 -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+typedef struct _PM_PROFILE_SETUP_INFO_T { -+ /* Profile setup */ -+ UINT_8 ucBmpDeliveryAC; /* 0: AC_BE, 1: AC_BK, 2: AC_VI, 3: AC_VO */ -+ UINT_8 ucBmpTriggerAC; /* 0: AC_BE, 1: AC_BK, 2: AC_VI, 3: AC_VO */ -+ -+ UINT_8 ucUapsdSp; /* Number of triggered packets in UAPSD */ -+ -+} PM_PROFILE_SETUP_INFO_T, *P_PM_PROFILE_SETUP_INFO_T; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+#if !CFG_ENABLE_FULL_PM -+#define ACQUIRE_POWER_CONTROL_FROM_PM(_prAdapter) -+#define RECLAIM_POWER_CONTROL_TO_PM(_prAdapter, _fgEnableGINT_in_IST) -+#else -+#define ACQUIRE_POWER_CONTROL_FROM_PM(_prAdapter) \ -+ { \ -+ if (_prAdapter->fgIsFwOwn) { \ -+ nicpmSetDriverOwn(_prAdapter); \ -+ } \ -+ /* Increase Block to Enter Low Power Semaphore count */ \ -+ GLUE_INC_REF_CNT(_prAdapter->u4PwrCtrlBlockCnt); \ -+ } -+ -+#define RECLAIM_POWER_CONTROL_TO_PM(_prAdapter, _fgEnableGINT_in_IST) \ -+ { \ -+ ASSERT(_prAdapter->u4PwrCtrlBlockCnt != 0); \ -+ /* Decrease Block to Enter Low Power Semaphore count */ \ -+ GLUE_DEC_REF_CNT(_prAdapter->u4PwrCtrlBlockCnt); \ -+ if (_prAdapter->fgWiFiInSleepyState && (_prAdapter->u4PwrCtrlBlockCnt == 0)) { \ -+ nicpmSetFWOwn(_prAdapter, _fgEnableGINT_in_IST); \ -+ } \ -+ } -+#endif -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif /* _PWR_MGT_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/queue.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/queue.h -new file mode 100644 -index 000000000000..a9e74b58a8c9 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/queue.h -@@ -0,0 +1,195 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/queue.h#1 -+*/ -+ -+/*! \file queue.h -+ \brief Definition for singly queue operations. -+ -+ In this file we define the singly queue data structure and its -+ queue operation MACROs. -+*/ -+ -+/* -+** Log: queue.h -+ * -+ * 07 16 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration. -+ * bugfix for SCN migration -+ * 1) modify QUEUE_CONCATENATE_QUEUES() so it could be used to concatence with an empty queue -+ * 2) before AIS issues scan request, network(BSS) needs to be activated first -+ * 3) only invoke COPY_SSID when using specified SSID for scan -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 04 20 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * . -+** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 20:11:46 GMT mtk01426 -+** Init for develop -+** -+*/ -+ -+#ifndef _QUEUE_H -+#define _QUEUE_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "gl_typedef.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+/* Singly Queue Structures - Entry Part */ -+typedef struct _QUE_ENTRY_T { -+ struct _QUE_ENTRY_T *prNext; -+ struct _QUE_ENTRY_T *prPrev; /* For Rx buffer reordering used only */ -+} QUE_ENTRY_T, *P_QUE_ENTRY_T; -+ -+/* Singly Queue Structures - Queue Part */ -+typedef struct _QUE_T { -+ P_QUE_ENTRY_T prHead; -+ P_QUE_ENTRY_T prTail; -+ UINT_32 u4NumElem; -+} QUE_T, *P_QUE_T; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/* -+ * To resolve compiler warning of address check -Waddress -+ * Redefine a ASSERT dedicate for queue operation -+ */ -+#if DBG -+#define QUE_ASSERT ASSERT -+#else -+#define QUE_ASSERT(_exp) -+#endif -+ -+#define QUEUE_INITIALIZE(prQueue) \ -+ { \ -+ (prQueue)->prHead = (P_QUE_ENTRY_T)NULL; \ -+ (prQueue)->prTail = (P_QUE_ENTRY_T)NULL; \ -+ (prQueue)->u4NumElem = 0; \ -+ } -+ -+#define QUEUE_IS_EMPTY(prQueue) (((P_QUE_T)(prQueue))->prHead == (P_QUE_ENTRY_T)NULL) -+ -+#define QUEUE_IS_NOT_EMPTY(prQueue) ((prQueue)->u4NumElem > 0) -+ -+#define QUEUE_GET_HEAD(prQueue) ((prQueue)->prHead) -+ -+#define QUEUE_GET_TAIL(prQueue) ((prQueue)->prTail) -+ -+#define QUEUE_GET_NEXT_ENTRY(prQueueEntry) ((prQueueEntry)->prNext) -+ -+#define QUEUE_INSERT_HEAD(prQueue, prQueueEntry) \ -+ { \ -+ QUE_ASSERT(prQueue); \ -+ QUE_ASSERT(prQueueEntry); \ -+ (prQueueEntry)->prNext = (prQueue)->prHead; \ -+ (prQueue)->prHead = (prQueueEntry); \ -+ if ((prQueue)->prTail == (P_QUE_ENTRY_T)NULL) { \ -+ (prQueue)->prTail = (prQueueEntry); \ -+ } \ -+ ((prQueue)->u4NumElem)++; \ -+ } -+ -+#define QUEUE_INSERT_TAIL(prQueue, prQueueEntry) \ -+ { \ -+ QUE_ASSERT(prQueue); \ -+ QUE_ASSERT(prQueueEntry); \ -+ (prQueueEntry)->prNext = (P_QUE_ENTRY_T)NULL; \ -+ if ((prQueue)->prTail) { \ -+ ((prQueue)->prTail)->prNext = (prQueueEntry); \ -+ } else { \ -+ (prQueue)->prHead = (prQueueEntry); \ -+ } \ -+ (prQueue)->prTail = (prQueueEntry); \ -+ ((prQueue)->u4NumElem)++; \ -+ } -+ -+/* NOTE: We assume the queue entry located at the beginning of "prQueueEntry Type", -+ * so that we can cast the queue entry to other data type without doubts. -+ * And this macro also decrease the total entry count at the same time. -+ */ -+#define QUEUE_REMOVE_HEAD(prQueue, prQueueEntry, _P_TYPE) \ -+ { \ -+ QUE_ASSERT(prQueue); \ -+ prQueueEntry = (_P_TYPE)((prQueue)->prHead); \ -+ if (prQueueEntry) { \ -+ (prQueue)->prHead = ((P_QUE_ENTRY_T)(prQueueEntry))->prNext; \ -+ if ((prQueue)->prHead == (P_QUE_ENTRY_T)NULL) { \ -+ (prQueue)->prTail = (P_QUE_ENTRY_T)NULL; \ -+ } \ -+ ((P_QUE_ENTRY_T)(prQueueEntry))->prNext = (P_QUE_ENTRY_T)NULL; \ -+ ((prQueue)->u4NumElem)--; \ -+ } \ -+ } -+ -+#define QUEUE_MOVE_ALL(prDestQueue, prSrcQueue) \ -+ { \ -+ QUE_ASSERT(prDestQueue); \ -+ QUE_ASSERT(prSrcQueue); \ -+ *(P_QUE_T)prDestQueue = *(P_QUE_T)prSrcQueue; \ -+ QUEUE_INITIALIZE(prSrcQueue); \ -+ } -+ -+#define QUEUE_CONCATENATE_QUEUES(prDestQueue, prSrcQueue) \ -+ { \ -+ QUE_ASSERT(prDestQueue); \ -+ QUE_ASSERT(prSrcQueue); \ -+ if (prSrcQueue->u4NumElem > 0) { \ -+ if ((prDestQueue)->prTail) { \ -+ ((prDestQueue)->prTail)->prNext = (prSrcQueue)->prHead; \ -+ } else { \ -+ (prDestQueue)->prHead = (prSrcQueue)->prHead; \ -+ } \ -+ (prDestQueue)->prTail = (prSrcQueue)->prTail; \ -+ ((prDestQueue)->u4NumElem) += ((prSrcQueue)->u4NumElem); \ -+ QUEUE_INITIALIZE(prSrcQueue); \ -+ } \ -+ } -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif /* _QUEUE_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/rftest.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/rftest.h -new file mode 100644 -index 000000000000..4489e5601302 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/rftest.h -@@ -0,0 +1,294 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/rftest.h#1 -+*/ -+ -+/*! \file "rftest.h" -+ \brief definitions for RF Productino test -+ -+*/ -+ -+/* -+** Log: rftest.h -+ * -+ * 12 20 2011 cp.wu -+ * [WCXRP00001144] [MT6620 Wi-Fi][Driver][Firmware] Add RF_FUNC_ID for exposing device and related version information -+ * add driver implementations for RF_AT_FUNCID_FW_INFO & RF_AT_FUNCID_DRV_INFO -+ * to expose version information -+ * -+ * 08 04 2010 cp.wu -+ * NULL -+ * add an extra parameter to rftestQueryATInfo 'cause it's necessary to pass u4FuncData for query request. -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 04 14 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * information buffer for query oid/ioctl is now buffered in prCmdInfo -+ * * * * instead of glue-layer variable to improve multiple oid/ioctl capability -+ * -+ * 12 30 2009 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) According to CMD/EVENT documentation v0.8, -+ * * * * * * * OID_CUSTOM_TEST_RX_STATUS & OID_CUSTOM_TEST_TX_STATUS is no longer used, -+ * * * * * * * and result is retrieved by get ATInfo instead -+ * * * * * * * 2) add 4 counter for recording aggregation statistics -+** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-12-08 17:35:11 GMT mtk02752 -+** * comment out RF test which is not supported on MT6620 -+** + API decalre for rftest -+** \main\maintrunk.MT6620WiFiDriver_Prj\1 2009-12-08 11:29:07 GMT mtk02752 -+** definitions for RF test mode -+** -+*/ -+#ifndef _RFTEST_H -+#define _RFTEST_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+/* Table Version */ -+#define RF_AUTO_TEST_FUNCTION_TABLE_VERSION 0x01000001 -+ -+/* Power */ -+#define RF_AT_PARAM_POWER_MASK BITS(0, 7) -+#define RF_AT_PARAM_POWER_MAX RF_AT_PARAM_POWER_MASK -+ -+/* Rate */ -+#define RF_AT_PARAM_RATE_MCS_MASK BIT(31) -+#define RF_AT_PARAM_RATE_MASK BITS(0, 7) -+#define RF_AT_PARAM_RATE_CCK_MAX 3 -+#define RF_AT_PARAM_RATE_1M 0 -+#define RF_AT_PARAM_RATE_2M 1 -+#define RF_AT_PARAM_RATE_5_5M 2 -+#define RF_AT_PARAM_RATE_11M 3 -+#define RF_AT_PARAM_RATE_6M 4 -+#define RF_AT_PARAM_RATE_9M 5 -+#define RF_AT_PARAM_RATE_12M 6 -+#define RF_AT_PARAM_RATE_18M 7 -+#define RF_AT_PARAM_RATE_24M 8 -+#define RF_AT_PARAM_RATE_36M 9 -+#define RF_AT_PARAM_RATE_48M 10 -+#define RF_AT_PARAM_RATE_54M 11 -+ -+/* Antenna */ -+#define RF_AT_PARAM_ANTENNA_ID_MASK BITS(0, 7) -+#define RF_AT_PARAM_ANTENNA_ID_MAX 1 -+ -+/* Packet Length */ -+#define RF_AT_PARAM_TX_80211HDR_BYTE_MAX (32) -+#define RF_AT_PARAM_TX_80211PAYLOAD_BYTE_MAX (2048) -+ -+#define RF_AT_PARAM_TX_PKTLEN_BYTE_DEFAULT 1024 -+#define RF_AT_PARAM_TX_PKTLEN_BYTE_MAX \ -+ ((UINT_16)(RF_AT_PARAM_TX_80211HDR_BYTE_MAX + RF_AT_PARAM_TX_80211PAYLOAD_BYTE_MAX)) -+ -+/* Packet Count */ -+#define RF_AT_PARAM_TX_PKTCNT_DEFAULT 1000 -+#define RF_AT_PARAM_TX_PKTCNT_UNLIMITED 0 -+ -+/* Packet Interval */ -+#define RF_AT_PARAM_TX_PKT_INTERVAL_US_DEFAULT 50 -+ -+/* ALC */ -+#define RF_AT_PARAM_ALC_DISABLE 0 -+#define RF_AT_PARAM_ALC_ENABLE 1 -+ -+/* TXOP */ -+#define RF_AT_PARAM_TXOP_DEFAULT 0 -+#define RF_AT_PARAM_TXOPQUE_QMASK BITS(16, 31) -+#define RF_AT_PARAM_TXOPQUE_TMASK BITS(0, 15) -+#define RF_AT_PARAM_TXOPQUE_AC0 (0<<16) -+#define RF_AT_PARAM_TXOPQUE_AC1 (1<<16) -+#define RF_AT_PARAM_TXOPQUE_AC2 (2<<16) -+#define RF_AT_PARAM_TXOPQUE_AC3 (3<<16) -+#define RF_AT_PARAM_TXOPQUE_AC4 (4<<16) -+#define RF_AT_PARAM_TXOPQUE_QOFFSET 16 -+ -+/* Retry Limit */ -+#define RF_AT_PARAM_TX_RETRY_DEFAULT 0 -+#define RF_AT_PARAM_TX_RETRY_MAX 6 -+ -+/* QoS Queue */ -+#define RF_AT_PARAM_QOSQUE_AC0 0 -+#define RF_AT_PARAM_QOSQUE_AC1 1 -+#define RF_AT_PARAM_QOSQUE_AC2 2 -+#define RF_AT_PARAM_QOSQUE_AC3 3 -+#define RF_AT_PARAM_QOSQUE_AC4 4 -+#define RF_AT_PARAM_QOSQUE_DEFAULT RF_AT_PARAM_QOSQUE_AC0 -+ -+/* Bandwidth */ -+#define RF_AT_PARAM_BANDWIDTH_20MHZ 0 -+#define RF_AT_PARAM_BANDWIDTH_40MHZ 1 -+#define RF_AT_PARAM_BANDWIDTH_U20_IN_40MHZ 2 -+#define RF_AT_PARAM_BANDWIDTH_D20_IN_40MHZ 3 -+#define RF_AT_PARAM_BANDWIDTH_DEFAULT RF_AT_PARAM_BANDWIDTH_20MHZ -+ -+/* GI (Guard Interval) */ -+#define RF_AT_PARAM_GI_800NS 0 -+#define RF_AT_PARAM_GI_400NS 1 -+#define RF_AT_PARAM_GI_DEFAULT RF_AT_PARAM_GI_800NS -+ -+/* STBC */ -+#define RF_AT_PARAM_STBC_DISABLE 0 -+#define RF_AT_PARAM_STBC_ENABLE 1 -+ -+/* RIFS */ -+#define RF_AT_PARAM_RIFS_DISABLE 0 -+#define RF_AT_PARAM_RIFS_ENABLE 1 -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+/* Function ID List */ -+typedef enum _ENUM_RF_AT_FUNCID_T { -+ RF_AT_FUNCID_VERSION = 0, -+ RF_AT_FUNCID_COMMAND, -+ RF_AT_FUNCID_POWER, -+ RF_AT_FUNCID_RATE, -+ RF_AT_FUNCID_PREAMBLE, -+ RF_AT_FUNCID_ANTENNA, -+ RF_AT_FUNCID_PKTLEN, -+ RF_AT_FUNCID_PKTCNT, -+ RF_AT_FUNCID_PKTINTERVAL, -+ RF_AT_FUNCID_TEMP_COMPEN, -+ RF_AT_FUNCID_TXOPLIMIT, -+ RF_AT_FUNCID_ACKPOLICY, -+ RF_AT_FUNCID_PKTCONTENT, -+ RF_AT_FUNCID_RETRYLIMIT, -+ RF_AT_FUNCID_QUEUE, -+ RF_AT_FUNCID_BANDWIDTH, -+ RF_AT_FUNCID_GI, -+ RF_AT_FUNCID_STBC, -+ RF_AT_FUNCID_CHNL_FREQ, -+ RF_AT_FUNCID_RIFS, -+ RF_AT_FUNCID_TRSW_TYPE, -+ RF_AT_FUNCID_RF_SX_SHUTDOWN, -+ RF_AT_FUNCID_PLL_SHUTDOWN, -+ RF_AT_FUNCID_SLOW_CLK_MODE, -+ RF_AT_FUNCID_ADC_CLK_MODE, -+ RF_AT_FUNCID_MEASURE_MODE, -+ RF_AT_FUNCID_VOLT_COMPEN, -+ RF_AT_FUNCID_DPD_TX_GAIN, -+ RF_AT_FUNCID_DPD_MODE, -+ RF_AT_FUNCID_TSSI_MODE, -+ RF_AT_FUNCID_TX_GAIN_CODE, -+ RF_AT_FUNCID_TX_PWR_MODE, -+ -+ /* Query command */ -+ RF_AT_FUNCID_TXED_COUNT = 32, -+ RF_AT_FUNCID_TXOK_COUNT, -+ RF_AT_FUNCID_RXOK_COUNT, -+ RF_AT_FUNCID_RXERROR_COUNT, -+ RF_AT_FUNCID_RESULT_INFO, -+ RF_AT_FUNCID_TRX_IQ_RESULT, -+ RF_AT_FUNCID_TSSI_RESULT, -+ RF_AT_FUNCID_DPD_RESULT, -+ RF_AT_FUNCID_RXV_DUMP, -+ RF_AT_FUNCID_RX_PHY_STATIS, -+ RF_AT_FUNCID_MEASURE_RESULT, -+ RF_AT_FUNCID_TEMP_SENSOR, -+ RF_AT_FUNCID_VOLT_SENSOR, -+ RF_AT_FUNCID_READ_EFUSE, -+ RF_AT_FUNCID_RX_RSSI, -+ RF_AT_FUNCID_FW_INFO, -+ RF_AT_FUNCID_DRV_INFO, -+ -+ /* Set command */ -+ RF_AT_FUNCID_SET_DPD_RESULT = 64, -+ RF_AT_FUNCID_SET_CW_MODE, -+ RF_AT_FUNCID_SET_JAPAN_CH14_FILTER, -+ RF_AT_FUNCID_WRITE_EFUSE, -+ RF_AT_FUNCID_SET_MAC_ADDRESS -+} ENUM_RF_AT_FUNCID_T; -+ -+/* Command */ -+typedef enum _ENUM_RF_AT_COMMAND_T { -+ RF_AT_COMMAND_STOPTEST = 0, -+ RF_AT_COMMAND_STARTTX, -+ RF_AT_COMMAND_STARTRX, -+ RF_AT_COMMAND_RESET, -+ RF_AT_COMMAND_OUTPUT_POWER, /* Payload */ -+ RF_AT_COMMAND_LO_LEAKAGE, /* Local freq is renamed to Local leakage */ -+ RF_AT_COMMAND_CARRIER_SUPPR, /* OFDM (LTF/STF), CCK (PI,PI/2) */ -+ RF_AT_COMMAND_TRX_IQ_CAL, -+ RF_AT_COMMAND_TSSI_CAL, -+ RF_AT_COMMAND_DPD_CAL, -+ RF_AT_COMMAND_CW, -+ RF_AT_COMMAND_NUM -+} ENUM_RF_AT_COMMAND_T; -+ -+/* Preamble */ -+typedef enum _ENUM_RF_AT_PREAMBLE_T { -+ RF_AT_PREAMBLE_NORMAL = 0, -+ RF_AT_PREAMBLE_CCK_SHORT, -+ RF_AT_PREAMBLE_11N_MM, -+ RF_AT_PREAMBLE_11N_GF, -+ RF_AT_PREAMBLE_NUM -+} ENUM_RF_AT_PREAMBLE_T; -+ -+/* Ack Policy */ -+typedef enum _ENUM_RF_AT_ACK_POLICY_T { -+ RF_AT_ACK_POLICY_NORMAL = 0, -+ RF_AT_ACK_POLICY_NOACK, -+ RF_AT_ACK_POLICY_NOEXPLICTACK, -+ RF_AT_ACK_POLICY_BLOCKACK, -+ RF_AT_ACK_POLICY_NUM -+} ENUM_RF_AT_ACK_POLICY_T; -+ -+typedef enum _ENUM_RF_AUTOTEST_STATE_T { -+ RF_AUTOTEST_STATE_STANDBY = 0, -+ RF_AUTOTEST_STATE_TX, -+ RF_AUTOTEST_STATE_RX, -+ RF_AUTOTEST_STATE_RESET, -+ RF_AUTOTEST_STATE_OUTPUT_POWER, -+ RF_AUTOTEST_STATE_LOCA_FREQUENCY, -+ RF_AUTOTEST_STATE_CARRIER_SUPRRESION, -+ RF_AUTOTEST_STATE_NUM -+} ENUM_RF_AUTOTEST_STATE_T; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+WLAN_STATUS rftestSetATInfo(IN P_ADAPTER_T prAdapter, UINT_32 u4FuncIndex, UINT_32 u4FuncData); -+ -+WLAN_STATUS -+rftestQueryATInfo(IN P_ADAPTER_T prAdapter, -+ UINT_32 u4FuncIndex, UINT_32 u4FuncData, OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen); -+ -+WLAN_STATUS rftestSetFrequency(IN P_ADAPTER_T prAdapter, IN UINT_32 u4FreqInKHz, IN PUINT_32 pu4SetInfoLen); -+ -+#endif /* _RFTEST_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/tdls_extr.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/tdls_extr.h -new file mode 100644 -index 000000000000..8ee184591fc2 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/tdls_extr.h -@@ -0,0 +1,427 @@ -+/* -+** Id: include/tdls_extr.h#1 -+*/ -+ -+/*! \file "tdls_extr.h" -+ \brief This file contains the external used in other modules -+ for MediaTek Inc. 802.11 Wireless LAN Adapters. -+*/ -+ -+/* -+** Log: tdls_extr.h -+ * -+ * 11 18 2013 vend_samp.lin -+ * NULL -+ * Initial version. -+ * -+ ** -+ */ -+ -+#ifndef _TDLS_EXTR_H -+#define _TDLS_EXTR_H -+ -+#if (CFG_SUPPORT_TDLS == 1) -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#define TDLS_TX_QUOTA_EMPTY_TIMEOUT 10 -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+/* protocol */ -+#define TDLS_FRM_PROT_TYPE 0x890d -+ -+/* TDLS uses Ethertype 89-0d frames. The UP shall be AC_VI, unless otherwise specified. */ -+#define USER_PRIORITY_TDLS 5 -+ -+/* Status code */ -+#define TDLS_STATUS WLAN_STATUS -+ -+#define TDLS_STATUS_SUCCESS WLAN_STATUS_SUCCESS -+#define TDLS_STATUS_FAILURE WLAN_STATUS_FAILURE -+#define TDLS_STATUS_INVALID_LENGTH WLAN_STATUS_INVALID_LENGTH -+#define TDLS_STATUS_RESOURCES WLAN_STATUS_RESOURCES -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+#define TDLS_U32 UINT32 -+#define TDLS_U16 UINT16 -+#define TDLS_U8 UINT8 -+ -+typedef enum _TDLS_REASON_CODE { -+ TDLS_REASON_CODE_UNREACHABLE = 25, -+ TDLS_REASON_CODE_UNSPECIFIED = 26, -+ -+ TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_UNKNOWN = 0x80, /* 128 */ -+ TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_WIFI_OFF = 0x81, /* 129 */ -+ TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_ROAMING = 0x82, /* 130 */ -+ TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_PTI_TIMEOUT = 0x83, /* 131 */ -+ TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_AGE_TIMEOUT = 0x84, /* 132 */ -+ TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_REKEY = 0x85, /* 133 */ -+ TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_PTI_SEND_FAIL = 0x86, /* 134 */ -+ TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_PTI_SEND_MAX_FAIL = 0x87, /* 135 */ -+ TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_WRONG_NETWORK_IDX = 0x88, /* 136 */ -+ TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_NON_STATE3 = 0x89, /* 137 */ -+ TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_TX_QUOTA_EMPTY = 0x8a, /* 138 */ -+ TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_LOST_TEAR_DOWN = 0x8b /* 139 */ -+} TDLS_REASON_CODE; -+ -+/* TDLS FSM */ -+typedef struct _TDLS_CMD_PEER_ADD_T { -+ -+ TDLS_U8 aucPeerMac[6]; -+ -+#if 0 -+ ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex; -+ UINT_16 u2CapInfo; -+ -+ UINT_16 u2OperationalRateSet; -+ UINT_16 u2BSSBasicRateSet; -+ BOOLEAN fgIsUnknownBssBasicRate; -+ -+ UINT_8 ucPhyTypeSet; -+#endif -+} TDLS_CMD_PEER_ADD_T; -+ -+typedef struct _TDLS_CMD_LINK_T { -+ -+ TDLS_U8 aucPeerMac[6]; -+ BOOLEAN fgIsEnabled; -+} TDLS_CMD_LINK_T; -+ -+typedef struct _TDLS_CMD_PEER_UPDATE_HT_CAP_MCS_INFO_T { -+ TDLS_U8 arRxMask[10]; -+ TDLS_U16 u2RxHighest; -+ TDLS_U8 ucTxParams; -+ TDLS_U8 Reserved[3]; -+} TDLS_CMD_PEER_UPDATE_HT_CAP_MCS_INFO_T; -+ -+typedef struct _TDLS_CMD_PEER_UPDATE_HT_CAP_T { -+ TDLS_U16 u2CapInfo; -+ TDLS_U8 ucAmpduParamsInfo; -+ -+ /* 16 bytes MCS information */ -+ TDLS_CMD_PEER_UPDATE_HT_CAP_MCS_INFO_T rMCS; -+ -+ TDLS_U16 u2ExtHtCapInfo; -+ TDLS_U32 u4TxBfCapInfo; -+ TDLS_U8 ucAntennaSelInfo; -+} TDLS_CMD_PEER_UPDATE_HT_CAP_T; -+ -+typedef struct _TDLS_CMD_PEER_UPDATE_T { -+ -+ TDLS_U8 aucPeerMac[6]; -+ -+#define TDLS_CMD_PEER_UPDATE_SUP_CHAN_MAX 50 -+ TDLS_U8 aucSupChan[TDLS_CMD_PEER_UPDATE_SUP_CHAN_MAX]; -+ -+ TDLS_U16 u2StatusCode; -+ -+#define TDLS_CMD_PEER_UPDATE_SUP_RATE_MAX 50 -+ TDLS_U8 aucSupRate[TDLS_CMD_PEER_UPDATE_SUP_RATE_MAX]; -+ TDLS_U16 u2SupRateLen; -+ -+ TDLS_U8 UapsdBitmap; -+ TDLS_U8 UapsdMaxSp; /* MAX_SP */ -+ -+ TDLS_U16 u2Capability; -+#define TDLS_CMD_PEER_UPDATE_EXT_CAP_MAXLEN 5 -+ TDLS_U8 aucExtCap[TDLS_CMD_PEER_UPDATE_EXT_CAP_MAXLEN]; -+ TDLS_U16 u2ExtCapLen; -+ -+ TDLS_CMD_PEER_UPDATE_HT_CAP_T rHtCap; -+ BOOLEAN fgIsSupHt; -+ -+} TDLS_CMD_PEER_UPDATE_T; -+ -+/* Command to TDLS core module */ -+typedef enum _TDLS_CMD_CORE_ID { -+ TDLS_CORE_CMD_TEST_NULL_RCV = 0x00, -+ TDLS_CORE_CMD_TEST_PTI_RSP = 0x01, -+ TDLS_CORE_CMD_MIB_UPDATE = 0x02, -+ TDLS_CORE_CMD_TEST_TX_FAIL_SKIP = 0x03, -+ TDLS_CORE_CMD_UAPSD_CONF = 0x04, -+ TDLS_CORE_CMD_TEST_DATA_RCV = 0x05, -+ TDLS_CORE_CMD_TEST_PTI_REQ = 0x06, -+ TDLS_CORE_CMD_TEST_CHSW_REQ = 0x07, -+ TDLS_CORE_CMD_CHSW_CONF = 0x08, -+ TDLS_CORE_CMD_TEST_KEEP_ALIVE_SKIP = 0x09, -+ TDLS_CORE_CMD_TEST_CHSW_TIMEOUT_SKIP = 0x0a, -+ TDLS_CORE_CMD_TEST_CHSW_RSP = 0x0b, -+ TDLS_CORE_CMD_TEST_SCAN_SKIP = 0x0c, -+ TDLS_CORE_CMD_SETUP_CONF = 0x0d, -+ TDLS_CORE_CMD_TEST_TEAR_DOWN = 0x0e, -+ TDLS_CORE_CMD_KEY_INFO = 0x0f, -+ TDLS_CORE_CMD_TEST_PTI_TX_FAIL = 0x10 -+} TDLS_CMD_CORE_ID; -+ -+typedef struct _TDLS_CMD_CORE_TEST_NULL_RCV_T { -+ -+ TDLS_U32 u4PM; -+} TDLS_CMD_CORE_TEST_NULL_RCV_T; -+ -+typedef struct _TDLS_CMD_CORE_TEST_PTI_REQ_RCV_T { -+ -+ TDLS_U32 u4DialogToken; -+} TDLS_CMD_CORE_TEST_PTI_REQ_RCV_T; -+ -+typedef struct _TDLS_CMD_CORE_TEST_PTI_RSP_RCV_T { -+ -+ TDLS_U32 u4DialogToken; -+ TDLS_U32 u4PM; -+} TDLS_CMD_CORE_TEST_PTI_RSP_RCV_T; -+ -+typedef struct _TDLS_CMD_CORE_TEST_TEAR_DOWN_RCV_T { -+ -+ TDLS_U32 u4ReasonCode; -+} TDLS_CMD_CORE_TEST_TEAR_DOWN_RCV_T; -+ -+typedef struct _TDLS_CMD_CORE_TEST_CHST_REQ_RCV_T { -+ -+ TDLS_U32 u4Chan; -+ TDLS_U32 u4RegClass; -+ TDLS_U32 u4SecChanOff; -+ TDLS_U32 u4SwitchTime; -+ TDLS_U32 u4SwitchTimeout; -+} TDLS_CMD_CORE_TEST_CHST_REQ_RCV_T; -+ -+typedef struct _TDLS_CMD_CORE_TEST_CHST_RSP_RCV_T { -+ -+ TDLS_U32 u4Chan; -+ TDLS_U32 u4SwitchTime; -+ TDLS_U32 u4SwitchTimeout; -+ TDLS_U32 u4StatusCode; -+} TDLS_CMD_CORE_TEST_CHST_RSP_RCV_T; -+ -+typedef struct _TDLS_CMD_CORE_TEST_DATA_RCV_T { -+ -+ TDLS_U32 u4PM; -+ TDLS_U32 u4UP; -+ TDLS_U32 u4EOSP; -+ TDLS_U32 u4IsNull; -+} TDLS_CMD_CORE_TEST_DATA_RCV_T; -+ -+typedef struct _TDLS_CMD_CORE_MIB_PARAM_UPDATE_T { -+ -+ BOOLEAN Tdlsdot11TunneledDirectLinkSetupImplemented; -+ BOOLEAN Tdlsdot11TDLSPeerUAPSDBufferSTAActivated; -+ BOOLEAN Tdlsdot11TDLSPeerPSMActivated; -+ TDLS_U16 Tdlsdot11TDLSPeerUAPSDIndicationWindow; -+ BOOLEAN Tdlsdot11TDLSChannelSwitchingActivated; -+ TDLS_U8 Tdlsdot11TDLSPeerSTAMissingAckRetryLimit; -+ TDLS_U8 Tdlsdot11TDLSResponseTimeout; -+ TDLS_U16 Tdlsdot11TDLSProbeDelay; -+ TDLS_U8 Tdlsdot11TDLSDiscoveryRequestWindow; -+ TDLS_U8 Tdlsdot11TDLSACDeterminationInterval; -+} TDLS_CMD_CORE_MIB_PARAM_UPDATE_T; -+ -+typedef struct _TDLS_CMD_CORE_TEST_TX_FAIL_SKIP_T { -+ -+ BOOLEAN fgIsEnable; -+} TDLS_CMD_CORE_TEST_TX_FAIL_SKIP_T; -+ -+typedef struct _TDLS_CMD_CORE_UAPSD_CONFIG_T { -+ -+ BOOLEAN fgIsSpTimeoutSkip; -+ BOOLEAN fgIsPtiTimeoutSkip; -+} TDLS_CMD_CORE_UAPSD_CONFIG_T; -+ -+typedef struct _TDLS_CMD_CORE_SETUP_CONFIG_T { -+ -+ BOOLEAN fgIs2040Supported; -+} TDLS_CMD_CORE_SETUP_CONFIG_T; -+ -+typedef struct _TDLS_CMD_CORE_CHSW_CONFIG_T { -+ -+ TDLS_U8 ucNetTypeIndex; -+ BOOLEAN fgIsChSwEnabled; -+ BOOLEAN fgIsChSwStarted; -+ TDLS_U8 ucRegClass; -+ TDLS_U8 ucTargetChan; -+ TDLS_U8 ucSecChanOff; -+ BOOLEAN fgIsChSwRegular; -+} TDLS_CMD_CORE_CHSW_CONFIG_T; -+ -+typedef struct _TDLS_CMD_CORE_TEST_KEEP_ALIVE_SKIP_T { -+ -+ BOOLEAN fgIsEnable; -+} TDLS_CMD_CORE_TEST_KEEP_ALIVE_SKIP_T; -+ -+typedef struct _TDLS_CMD_CORE_TEST_CHSW_TIMEOUT_SKIP_T { -+ -+ BOOLEAN fgIsEnable; -+} TDLS_CMD_CORE_TEST_CHSW_TIMEOUT_SKIP_T; -+ -+typedef struct _TDLS_CMD_CORE_TEST_PROHIBIT_T { -+ -+ BOOLEAN fgIsEnable; -+ BOOLEAN fgIsSet; -+} TDLS_CMD_CORE_TEST_PROHIBIT_T; -+ -+typedef struct _TDLS_CMD_CORE_TEST_SCAN_SKIP_T { -+ -+ BOOLEAN fgIsEnable; -+} TDLS_CMD_CORE_TEST_SCAN_SKIP_T; -+ -+typedef struct _TDLS_CMD_CORE_INFO_DISPLAY_T { -+ -+ BOOLEAN fgIsToClearAllHistory; -+} TDLS_CMD_CORE_INFO_DISPLAY_T; -+ -+typedef struct _TDLS_CMD_CORE_TEST_PTI_TX_FAIL_T { -+ -+ BOOLEAN fgIsEnable; -+} TDLS_CMD_CORE_TEST_PTI_TX_FAIL_T; -+ -+typedef struct _TDLS_CMD_CORE_T { -+ -+ TDLS_U32 u4Command; /* TDLS_CMD_CORE_ID */ -+ -+ TDLS_U8 aucPeerMac[6]; -+ TDLS_U8 ucNetTypeIndex; -+ -+#define TDLS_CMD_CORE_RESERVED_SIZE 50 -+ union { -+ TDLS_CMD_CORE_TEST_NULL_RCV_T rCmdNullRcv; -+ TDLS_CMD_CORE_TEST_PTI_REQ_RCV_T rCmdPtiReqRcv; -+ TDLS_CMD_CORE_TEST_PTI_RSP_RCV_T rCmdPtiRspRcv; -+ TDLS_CMD_CORE_TEST_TEAR_DOWN_RCV_T rCmdTearDownRcv; -+ TDLS_CMD_CORE_TEST_CHST_REQ_RCV_T rCmdChStReqRcv; -+ TDLS_CMD_CORE_TEST_CHST_RSP_RCV_T rCmdChStRspRcv; -+ TDLS_CMD_CORE_TEST_DATA_RCV_T rCmdDatRcv; -+ TDLS_CMD_CORE_TEST_TX_FAIL_SKIP_T rCmdTxFailSkip; -+ TDLS_CMD_CORE_TEST_KEEP_ALIVE_SKIP_T rCmdKeepAliveSkip; -+ TDLS_CMD_CORE_TEST_CHSW_TIMEOUT_SKIP_T rCmdChSwTimeoutSkip; -+ TDLS_CMD_CORE_TEST_PROHIBIT_T rCmdProhibit; -+ TDLS_CMD_CORE_TEST_SCAN_SKIP_T rCmdScanSkip; -+ TDLS_CMD_CORE_TEST_PTI_TX_FAIL_T rCmdPtiTxFail; -+ -+ TDLS_CMD_CORE_MIB_PARAM_UPDATE_T rCmdMibUpdate; -+ TDLS_CMD_CORE_UAPSD_CONFIG_T rCmdUapsdConf; -+ TDLS_CMD_CORE_CHSW_CONFIG_T rCmdChSwConf; -+ TDLS_CMD_CORE_SETUP_CONFIG_T rCmdSetupConf; -+ TDLS_CMD_CORE_INFO_DISPLAY_T rCmdInfoDisplay; -+ TDLS_U8 Reserved[TDLS_CMD_CORE_RESERVED_SIZE]; -+ } Content; -+} TDLS_CMD_CORE_T; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+/* -+ assign station record idx for the packet only when STA_STATE_3 -+ Or we will try to send data frame when the TDLS peer's state is STA_STATE_1 -+ EX: -+ 1. mtk_cfg80211_add_station: First create the STA_RECORD_T; -+ 2. TdlsexCfg80211TdlsMgmt: Send a TDLS request frame. -+ 3. mtk_cfg80211_add_station: Change state to STA_STATE_1. -+ 4. TdlsexCfg80211TdlsMgmt: Send a TDLS request frame. -+*/ -+#define TDLSEX_STA_REC_IDX_GET(__prAdapter__, __MsduInfo__) \ -+{ \ -+ STA_RECORD_T *__StaRec__; \ -+ __MsduInfo__->ucStaRecIndex = STA_REC_INDEX_NOT_FOUND; \ -+ __StaRec__ = cnmGetStaRecByAddress(__prAdapter__, \ -+ (UINT_8) NETWORK_TYPE_AIS_INDEX, \ -+ __MsduInfo__->aucEthDestAddr); \ -+ if ((__StaRec__ != NULL) && \ -+ ((__StaRec__)->ucStaState == STA_STATE_3) && \ -+ (IS_TDLS_STA(__StaRec__))) { \ -+ __MsduInfo__->ucStaRecIndex = __StaRec__->ucIndex; \ -+ } \ -+} -+ -+/* fill wiphy flag */ -+#define TDLSEX_WIPHY_FLAGS_INIT(__fgFlag__)\ -+{ \ -+ __fgFlag__ |= (WIPHY_FLAG_SUPPORTS_TDLS | WIPHY_FLAG_TDLS_EXTERNAL_SETUP);\ -+} -+ -+/* assign user priority of a TDLS action frame */ -+/* -+ According to 802.11z: Setup req/resp are sent in AC_BK, otherwise we should default -+ to AC_VI. -+*/ -+#define TDLSEX_UP_ASSIGN(__UserPriority__) \ -+{ \ -+ __UserPriority__ = USER_PRIORITY_TDLS; \ -+} -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+int -+TdlsexCfg80211TdlsMgmt(struct wiphy *wiphy, struct net_device *dev, -+ const u8 *peer, u8 action_code, u8 dialog_token, -+ u16 status_code, u32 peer_capability, -+ bool initiator, const u8 *buf, size_t len); -+ -+int TdlsexCfg80211TdlsOper(struct wiphy *wiphy, struct net_device *dev, -+ const u8 *peer, enum nl80211_tdls_operation oper); -+ -+VOID TdlsexCmd(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); -+ -+VOID TdlsexBssExtCapParse(STA_RECORD_T *prStaRec, UINT_8 *pucIE); -+ -+VOID TdlsexEventHandle(P_GLUE_INFO_T prGlueInfo, UINT8 *prInBuf, UINT32 u4InBufLen); -+ -+TDLS_STATUS TdlsexKeyHandle(ADAPTER_T *prAdapter, PARAM_KEY_T *prNewKey); -+ -+VOID TdlsexInit(ADAPTER_T *prAdapter); -+ -+BOOLEAN TdlsexIsAnyPeerInPowerSave(ADAPTER_T *prAdapter); -+ -+TDLS_STATUS TdlsexLinkCtrl(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen); -+ -+VOID -+TdlsexLinkHistoryRecord(GLUE_INFO_T *prGlueInfo, -+ BOOLEAN fgIsTearDown, UINT8 *pucPeerMac, BOOLEAN fgIsFromUs, UINT16 u2ReasonCode); -+ -+TDLS_STATUS TdlsexMgmtCtrl(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen); -+ -+TDLS_STATUS TdlsexPeerAdd(P_ADAPTER_T prAdapter, PVOID pvSetBuffer, UINT_32 u4SetBufferLen, PUINT_32 pu4SetInfoLen); -+ -+TDLS_STATUS TdlsexPeerUpdate(P_ADAPTER_T prAdapter, PVOID pvSetBuffer, UINT_32 u4SetBufferLen, PUINT_32 pu4SetInfoLen); -+ -+BOOLEAN TdlsexRxFrameDrop(GLUE_INFO_T *prGlueInfo, UINT_8 *pPkt); -+ -+VOID TdlsexRxFrameHandle(GLUE_INFO_T *prGlueInfo, UINT8 *pPkt, UINT16 u2PktLen); -+ -+TDLS_STATUS TdlsexStaRecIdxGet(ADAPTER_T *prAdapter, MSDU_INFO_T *prMsduInfo); -+ -+VOID TdlsexTxQuotaCheck(GLUE_INFO_T *prGlueInfo, STA_RECORD_T *prStaRec, UINT8 FreeQuota); -+ -+VOID TdlsexUninit(ADAPTER_T *prAdapter); -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif /* CFG_SUPPORT_TDLS */ -+ -+#endif /* _TDLS_EXTR_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/typedef.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/typedef.h -new file mode 100644 -index 000000000000..7ab62dae8813 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/typedef.h -@@ -0,0 +1,244 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/typedef.h#1 -+*/ -+ -+/*! \file typedef.h -+ \brief Declaration of data type and return values of internal protocol stack. -+ -+ In this file we declare the data type and return values which will be exported -+ to the GLUE Layer. -+*/ -+ -+/* -+** Log: typedef.h -+ * -+ * 07 18 2011 chinghwa.yu -+ * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm -+ * Add CMD/Event for RDD and BWCS. -+ * -+ * 12 30 2010 cp.wu -+ * [WCXRP00000327] [MT6620 Wi-Fi][Driver] Improve HEC WHQA 6972 workaround coverage in driver side -+ * host driver not to set FW-own when there is still pending interrupts -+ * -+ * 09 03 2010 kevin.huang -+ * NULL -+ * Refine #include sequence and solve recursive/nested #include issue -+ * -+ * 08 16 2010 kevin.huang -+ * NULL -+ * Refine AAA functions -+ * -+ * 07 19 2010 jeffrey.chang -+ * -+ * Linux port modification -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 23 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * integrate . -+ * -+ * 06 18 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Provide cnmMgtPktAlloc() and alloc/free function of msg/buf -+ * -+ * 06 11 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) migrate assoc.c. -+ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness -+ * 3) add configuration options for CNM_MEM and RSN modules -+ * 4) add data path for management frames -+ * 5) eliminate rPacketInfo of MSDU_INFO_T -+ * -+ * 06 09 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add necessary changes to driver data paths. -+ * -+ * 06 09 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add definitions for module migration. -+ * -+ * 06 07 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add aa_fsm.h, ais_fsm.h, bss.h, mib.h and scan.h. -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 06 03 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * move timer callback to glue layer. -+ * -+ * 05 31 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * add cfg80211 interface, which is to replace WE, for further extension -+ * -+ * 03 24 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * initial import for Linux port -+ * -+ * 02 24 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * add Ethernet destination address information in packet info for TX -+ * -+ * 02 23 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * add new API: wlanProcessQueuedPackets() -+** \main\maintrunk.MT6620WiFiDriver_Prj\6 2009-03-23 21:41:37 GMT mtk01461 -+** Update PACKET_INFO_INIT for TX Path -+** \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-03-23 00:30:17 GMT mtk01461 -+** Add parameter in PACKET_INFO_T for HIF Loopback -+** \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-03-18 20:25:22 GMT mtk01461 -+** Fix LINT warning -+** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-03-16 09:08:28 GMT mtk01461 -+** Update TX PATH API -+** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 20:11:54 GMT mtk01426 -+** Init for develop -+** -+*/ -+ -+#ifndef _TYPEDEF_H -+#define _TYPEDEF_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/* ieee80211.h of linux has duplicated definitions */ -+#if defined(WLAN_STATUS_SUCCESS) -+#undef WLAN_STATUS_SUCCESS -+#endif -+ -+#define WLAN_STATUS_SUCCESS ((WLAN_STATUS) 0x00000000L) -+#define WLAN_STATUS_PENDING ((WLAN_STATUS) 0x00000103L) -+#define WLAN_STATUS_NOT_ACCEPTED ((WLAN_STATUS) 0x00010003L) -+ -+#define WLAN_STATUS_MEDIA_CONNECT ((WLAN_STATUS) 0x4001000BL) -+#define WLAN_STATUS_MEDIA_DISCONNECT ((WLAN_STATUS) 0x4001000CL) -+#define WLAN_STATUS_MEDIA_DISCONNECT_LOCALLY ((WLAN_STATUS) 0x4001000DL) -+ -+#define WLAN_STATUS_MEDIA_SPECIFIC_INDICATION ((WLAN_STATUS) 0x40010012L) -+ -+#define WLAN_STATUS_SCAN_COMPLETE ((WLAN_STATUS) 0x60010001L) -+#define WLAN_STATUS_MSDU_OK ((WLAN_STATUS) 0x60010002L) -+ -+/* TODO(Kevin): double check if 0x60010001 & 0x60010002 is proprietary */ -+#define WLAN_STATUS_ROAM_OUT_FIND_BEST ((WLAN_STATUS) 0x60010101L) -+#define WLAN_STATUS_ROAM_DISCOVERY ((WLAN_STATUS) 0x60010102L) -+ -+#define WLAN_STATUS_FAILURE ((WLAN_STATUS) 0xC0000001L) -+#define WLAN_STATUS_RESOURCES ((WLAN_STATUS) 0xC000009AL) -+#define WLAN_STATUS_NOT_SUPPORTED ((WLAN_STATUS) 0xC00000BBL) -+ -+#define WLAN_STATUS_MULTICAST_FULL ((WLAN_STATUS) 0xC0010009L) -+#define WLAN_STATUS_INVALID_PACKET ((WLAN_STATUS) 0xC001000FL) -+#define WLAN_STATUS_ADAPTER_NOT_READY ((WLAN_STATUS) 0xC0010011L) -+#define WLAN_STATUS_NOT_INDICATING ((WLAN_STATUS) 0xC0010013L) -+#define WLAN_STATUS_INVALID_LENGTH ((WLAN_STATUS) 0xC0010014L) -+#define WLAN_STATUS_INVALID_DATA ((WLAN_STATUS) 0xC0010015L) -+#define WLAN_STATUS_BUFFER_TOO_SHORT ((WLAN_STATUS) 0xC0010016L) -+ -+#define WLAN_STATUS_BWCS_UPDATE ((WLAN_STATUS) 0xC0010017L) -+ -+#define WLAN_STATUS_CONNECT_INDICATION ((WLAN_STATUS) 0xC0010018L) -+ -+/* NIC status flags */ -+#define ADAPTER_FLAG_HW_ERR 0x00400000 -+ -+/* Type Length */ -+#define TL_IPV4 0x0008 -+#define TL_IPV6 0xDD86 -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+/* Type definition for GLUE_INFO structure */ -+typedef struct _GLUE_INFO_T GLUE_INFO_T, *P_GLUE_INFO_T; -+ -+/* Type definition for WLAN STATUS */ -+typedef UINT_32 WLAN_STATUS, *P_WLAN_STATUS; -+ -+/* Type definition for ADAPTER structure */ -+typedef struct _ADAPTER_T ADAPTER_T, *P_ADAPTER_T; -+ -+/* Type definition for MESSAGE HEADER structure */ -+typedef struct _MSG_HDR_T MSG_HDR_T, *P_MSG_HDR_T; -+ -+/* Type definition for WLAN configuration */ -+typedef struct _WLAN_CFG_T WLAN_CFG_T, *P_WLAN_CFG_T; -+ -+/* Type definition for WLAN configuration entry */ -+typedef struct _WLAN_CFG_ENTRY_T WLAN_CFG_ENTRY_T, *P_WLAN_CFG_ENTRY_T; -+ -+/* Type definition for WLAN configuration callback */ -+typedef WLAN_STATUS(*WLAN_CFG_SET_CB) (P_ADAPTER_T prAdapter, -+ PUINT_8 pucKey, PUINT_8 pucValue, PVOID pPrivate, UINT_32 u4Flags); -+ -+/* Type definition for Pointer to OS Native Packet */ -+typedef void *P_NATIVE_PACKET; -+ -+/* Type definition for STA_RECORD_T structure to handle the connectivity and packet reception -+ * for a particular STA. -+ */ -+typedef struct _STA_RECORD_T STA_RECORD_T, *P_STA_RECORD_T, **PP_STA_RECORD_T; -+ -+/* CMD_INFO_T is used by Glue Layer to send a cluster of Command(OID) information to -+ * the TX Path to reduce the parameters of a function call. -+ */ -+typedef struct _CMD_INFO_T CMD_INFO_T, *P_CMD_INFO_T; -+ -+/* Following typedef should be removed later, because Glue Layer should not -+ * be aware of following data type. -+ */ -+typedef struct _SW_RFB_T SW_RFB_T, *P_SW_RFB_T, **PP_SW_RFB_T; -+ -+typedef struct _MSDU_INFO_T MSDU_INFO_T, *P_MSDU_INFO_T; -+ -+typedef struct _REG_ENTRY_T REG_ENTRY_T, *P_REG_ENTRY_T; -+ -+/* IST handler definition */ -+typedef VOID(*IST_EVENT_FUNCTION) (P_ADAPTER_T); -+ -+/* Type definition for function pointer of timer handler */ -+typedef VOID(*PFN_TIMER_CALLBACK) (IN P_GLUE_INFO_T); -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+#endif /* _TYPEDEF_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/wlan_bow.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/wlan_bow.h -new file mode 100644 -index 000000000000..e8937166dc4f ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/wlan_bow.h -@@ -0,0 +1,352 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/wlan_bow.h#1 -+*/ -+ -+/*! \file "wlan_bow.h" -+ \brief This file contains the declairations of 802.11 PAL -+ command processing routines for -+ MediaTek Inc. 802.11 Wireless LAN Adapters. -+*/ -+ -+/* -+** Log: wlan_bow.h -+ * -+ * 05 25 2011 terry.wu -+ * [WCXRP00000735] [MT6620 Wi-Fi][BoW][FW/Driver] Protect BoW connection establishment -+ * Add BoW Cancel Scan Request and Turn On deactive network function. -+ * -+ * 05 23 2011 terry.wu -+ * [WCXRP00000735] [MT6620 Wi-Fi][BoW][FW/Driver] Protect BoW connection establishment -+ * Add some BoW error handling. -+ * -+ * 05 21 2011 terry.wu -+ * [WCXRP00000735] [MT6620 Wi-Fi][BoW][FW/Driver] Protect BoW connection establishment -+ * Protect BoW connection establishment. -+ * -+ * 05 17 2011 terry.wu -+ * [WCXRP00000730] [MT6620 Wi-Fi][BoW] Send deauth while disconnecting -+ * Send deauth while disconnecting BoW link. -+ * -+ * 05 06 2011 terry.wu -+ * [WCXRP00000707] [MT6620 Wi-Fi][Driver] Fix BoW Multiple Physical Link connect/disconnect issue -+ * Fix BoW Multiple Physical Link connect/disconnect issue. -+ * -+ * 04 15 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Add BOW short range mode. -+ * -+ * 03 27 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Support multiple physical link. -+ * -+ * 03 10 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Add BOW table. -+ * -+ * 02 16 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Add bowNotifyAllLinkDisconnected interface and change channel grant procedure for bow starting.. -+ * -+ * 02 15 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Update bowString and channel grant. -+ * -+ * 01 11 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Update BOW Activity Report structure and bug fix. -+ * -+ * 09 27 2010 chinghwa.yu -+ * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000065] Update BoW design and settings -+ * Update BCM/BoW design and settings. -+ * -+ * 09 14 2010 chinghwa.yu -+ * NULL -+ * Add bowRunEventAAAComplete. -+ * -+ * 08 24 2010 chinghwa.yu -+ * NULL -+ * Update BOW for the 1st time. -+ * -+ * 07 30 2010 cp.wu -+ * NULL -+ * 1) BoW wrapper: use definitions instead of hard-coded constant for error code -+ * 2) AIS-FSM: eliminate use of desired RF parameters, use prTargetBssDesc instead -+ * 3) add handling for RX_PKT_DESTINATION_HOST_WITH_FORWARD for GO-broadcast frames -+ * -+ * 07 15 2010 cp.wu -+ * -+ * sync. bluetooth-over-Wi-Fi interface to driver interface document v0.2.6. -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 05 17 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * 1) add timeout handler mechanism for pending command packets -+ * 2) add p2p add/removal key -+ * -+ * 05 13 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * 1) all BT physical handles shares the same RSSI/Link Quality. -+ * 2) simplify BT command composing -+ * -+ * 04 28 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * change prefix for data structure used to communicate with 802.11 PAL -+ * to avoid ambiguous naming with firmware interface -+ * -+ * 04 27 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * add multiple physical link support -+ * -+ * 04 13 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * add framework for BT-over-Wi-Fi support. -+ * * * * * * * * * * * * 1) prPendingCmdInfo is replaced by queue for multiple handler capability -+ * * * * * * * * * * * * 2) command sequence number is now increased atomically -+ * * * * * * * * * * * * 3) private data could be hold and taken use for other purpose -+** -+*/ -+ -+#ifndef _WLAN_BOW_H -+#define _WLAN_BOW_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "nic/bow.h" -+#include "nic/cmd_buf.h" -+ -+#if CFG_ENABLE_BT_OVER_WIFI -+ -+#if CFG_BOW_TEST -+extern UINT_32 g_arBowRevPalPacketTime[32]; -+#endif -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+#define BOWCMD_STATUS_SUCCESS 0 -+#define BOWCMD_STATUS_FAILURE 1 -+#define BOWCMD_STATUS_UNACCEPTED 2 -+#define BOWCMD_STATUS_INVALID 3 -+#define BOWCMD_STATUS_TIMEOUT 4 -+ -+#define BOW_WILDCARD_SSID "AMP" -+#define BOW_WILDCARD_SSID_LEN 3 -+#define BOW_SSID_LEN 21 -+ -+ /* 0: query, 1: setup, 2: destroy */ -+#define BOW_QUERY_CMD 0 -+#define BOW_SETUP_CMD 1 -+#define BOW_DESTROY_CMD 2 -+ -+#define BOW_INITIATOR 0 -+#define BOW_RESPONDER 1 -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+typedef struct _BOW_TABLE_T { -+ UINT_8 ucAcquireID; -+ BOOLEAN fgIsValid; -+ ENUM_BOW_DEVICE_STATE eState; -+ UINT_8 aucPeerAddress[6]; -+ /* UINT_8 ucRole; */ -+ /* UINT_8 ucChannelNum; */ -+ UINT_16 u2Reserved; -+} BOW_TABLE_T, *P_BOW_TABLE_T; -+ -+typedef WLAN_STATUS(*PFN_BOW_CMD_HANDLE) (P_ADAPTER_T, P_AMPC_COMMAND); -+ -+typedef struct _BOW_CMD_T { -+ UINT_8 uCmdID; -+ PFN_BOW_CMD_HANDLE pfCmdHandle; -+} BOW_CMD_T, *P_BOW_CMD_T; -+ -+typedef struct _BOW_EVENT_ACTIVITY_REPORT_T { -+ UINT_8 ucReason; -+ UINT_8 aucReserved; -+ UINT_8 aucPeerAddress[6]; -+} BOW_EVENT_ACTIVITY_REPORT_T, *P_BOW_EVENT_ACTIVITY_REPORT_T; -+ -+/* -+ucReason: 0: success -+ 1: general failure -+ 2: too much time (> 2/3 second totally) requested for scheduling. -+ Others: reserved. -+*/ -+ -+typedef struct _BOW_EVENT_SYNC_TSF_T { -+ UINT_64 u4TsfTime; -+ UINT_32 u4TsfSysTime; -+ UINT_32 u4ScoTime; -+ UINT_32 u4ScoSysTime; -+} BOW_EVENT_SYNC_TSF_T, *P_BOW_EVENT_SYNC_TSF_T; -+ -+typedef struct _BOW_ACTIVITY_REPORT_BODY_T { -+ UINT_32 u4StartTime; -+ UINT_32 u4Duration; -+ UINT_32 u4Periodicity; -+} BOW_ACTIVITY_REPORT_BODY_T, *P_BOW_ACTIVITY_REPORT_BODY_T; -+ -+typedef struct _BOW_ACTIVITY_REPORT_T { -+ UINT_8 aucPeerAddress[6]; -+ UINT_8 ucScheduleKnown; -+ UINT_8 ucNumReports; -+ BOW_ACTIVITY_REPORT_BODY_T arBowActivityReportBody[MAX_ACTIVITY_REPORT]; -+} BOW_ACTIVITY_REPORT_T, *P_BOW_ACTIVITY_REPORT_T; -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+/*--------------------------------------------------------------*/ -+/* Firmware Command Packer */ -+/*--------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSendSetQueryBowCmd(IN P_ADAPTER_T prAdapter, -+ UINT_8 ucCID, -+ BOOLEAN fgSetQuery, -+ BOOLEAN fgNeedResp, -+ PFN_CMD_DONE_HANDLER pfCmdDoneHandler, -+ PFN_CMD_TIMEOUT_HANDLER pfCmdTimeoutHandler, -+ UINT_32 u4SetQueryInfoLen, PUINT_8 pucInfoBuffer, IN UINT_8 ucSeqNumber); -+ -+/*--------------------------------------------------------------*/ -+/* Command Dispatcher */ -+/*--------------------------------------------------------------*/ -+WLAN_STATUS wlanbowHandleCommand(IN P_ADAPTER_T prAdapter, IN P_AMPC_COMMAND prCmd); -+ -+/*--------------------------------------------------------------*/ -+/* Routines to handle command */ -+/*--------------------------------------------------------------*/ -+WLAN_STATUS bowCmdGetMacStatus(IN P_ADAPTER_T prAdapter, IN P_AMPC_COMMAND prCmd); -+ -+WLAN_STATUS bowCmdSetupConnection(IN P_ADAPTER_T prAdapter, IN P_AMPC_COMMAND prCmd); -+ -+WLAN_STATUS bowCmdDestroyConnection(IN P_ADAPTER_T prAdapter, IN P_AMPC_COMMAND prCmd); -+ -+WLAN_STATUS bowCmdSetPTK(IN P_ADAPTER_T prAdapter, IN P_AMPC_COMMAND prCmd); -+ -+WLAN_STATUS bowCmdReadRSSI(IN P_ADAPTER_T prAdapter, IN P_AMPC_COMMAND prCmd); -+ -+WLAN_STATUS bowCmdReadLinkQuality(IN P_ADAPTER_T prAdapter, IN P_AMPC_COMMAND prCmd); -+ -+WLAN_STATUS bowCmdShortRangeMode(IN P_ADAPTER_T prAdapter, IN P_AMPC_COMMAND prCmd); -+ -+WLAN_STATUS bowCmdGetChannelList(IN P_ADAPTER_T prAdapter, IN P_AMPC_COMMAND prCmd); -+ -+VOID wlanbowCmdEventSetStatus(IN P_ADAPTER_T prAdapter, IN P_AMPC_COMMAND prCmd, IN UINT_8 ucEventBuf); -+ -+/*--------------------------------------------------------------*/ -+/* Callbacks for event indication */ -+/*--------------------------------------------------------------*/ -+VOID wlanbowCmdEventSetCommon(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); -+ -+VOID wlanbowCmdEventLinkConnected(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); -+ -+VOID wlanbowCmdEventLinkDisconnected(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); -+ -+VOID wlanbowCmdEventSetSetupConnection(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); -+ -+VOID wlanbowCmdEventReadLinkQuality(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); -+ -+VOID wlanbowCmdEventReadRssi(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); -+ -+VOID wlanbowCmdTimeoutHandler(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo); -+ -+VOID bowStopping(IN P_ADAPTER_T prAdapter); -+ -+VOID bowStarting(IN P_ADAPTER_T prAdapter); -+ -+VOID bowAssignSsid(IN PUINT_8 pucSsid, IN PUINT_8 pucSsidLen); -+ -+BOOLEAN bowValidateProbeReq(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, OUT PUINT_32 pu4ControlFlags); -+ -+VOID bowSendBeacon(IN P_ADAPTER_T prAdapter, ULONG ulParam); -+ -+VOID bowResponderScan(IN P_ADAPTER_T prAdapter); -+ -+VOID bowResponderScanDone(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); -+ -+VOID bowResponderCancelScan(IN P_ADAPTER_T prAdapter, IN BOOLEAN fgIsChannelExtention); -+ -+VOID bowResponderJoin(IN P_ADAPTER_T prAdapter, P_BSS_DESC_T prBssDesc); -+ -+VOID bowFsmRunEventJoinComplete(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); -+ -+VOID -+bowIndicationOfMediaStateToHost(IN P_ADAPTER_T prAdapter, -+ ENUM_PARAM_MEDIA_STATE_T eConnectionState, BOOLEAN fgDelayIndication); -+ -+VOID bowRunEventAAATxFail(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec); -+ -+WLAN_STATUS bowRunEventAAAComplete(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec); -+ -+WLAN_STATUS bowRunEventRxDeAuth(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN P_SW_RFB_T prSwRfb); -+ -+VOID bowDisconnectLink(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus); -+ -+BOOLEAN bowValidateAssocReq(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, OUT PUINT_16 pu2StatusCode); -+ -+BOOLEAN -+bowValidateAuth(IN P_ADAPTER_T prAdapter, -+ IN P_SW_RFB_T prSwRfb, IN PP_STA_RECORD_T pprStaRec, OUT PUINT_16 pu2StatusCode); -+ -+VOID bowRunEventChGrant(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr); -+ -+VOID bowRequestCh(IN P_ADAPTER_T prAdapter); -+ -+VOID bowReleaseCh(IN P_ADAPTER_T prAdapter); -+ -+VOID bowChGrantedTimeout(IN P_ADAPTER_T prAdapter, IN ULONG ulParam); -+ -+BOOLEAN bowNotifyAllLinkDisconnected(IN P_ADAPTER_T prAdapter); -+ -+BOOLEAN bowCheckBowTableIfVaild(IN P_ADAPTER_T prAdapter, IN UINT_8 aucPeerAddress[6]); -+ -+BOOLEAN bowGetBowTableContent(IN P_ADAPTER_T prAdapter, IN UINT_8 ucBowTableIdx, OUT P_BOW_TABLE_T prBowTable); -+ -+BOOLEAN -+bowGetBowTableEntryByPeerAddress(IN P_ADAPTER_T prAdapter, IN UINT_8 aucPeerAddress[6], OUT PUINT_8 pucBowTableIdx); -+ -+BOOLEAN bowGetBowTableFreeEntry(IN P_ADAPTER_T prAdapter, OUT PUINT_8 pucBowTableIdx); -+ -+ENUM_BOW_DEVICE_STATE bowGetBowTableState(IN P_ADAPTER_T prAdapter, IN UINT_8 aucPeerAddress[6]); -+ -+BOOLEAN bowSetBowTableState(IN P_ADAPTER_T prAdapter, IN UINT_8 aucPeerAddress[6], IN ENUM_BOW_DEVICE_STATE eState); -+ -+BOOLEAN bowSetBowTableContent(IN P_ADAPTER_T prAdapter, IN UINT_8 ucBowTableIdx, IN P_BOW_TABLE_T prBowTable); -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif -+#endif /* _WLAN_BOW_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/wlan_lib.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/wlan_lib.h -new file mode 100644 -index 000000000000..87259397a93d ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/wlan_lib.h -@@ -0,0 +1,1001 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/wlan_lib.h#1 -+*/ -+ -+/*! \file "wlan_lib.h" -+ \brief The declaration of the functions of the wlanAdpater objects -+ -+ Detail description. -+*/ -+ -+/* -+** Log: wlan_lib.h -+ * -+ * 06 08 2012 eason.tsai -+ * NULL -+ * Nvram context covert from 6620 to 6628 for old 6620 meta tool -+ * -+ * 01 16 2012 cp.wu -+ * [MT6620 Wi-Fi][Driver] API and behavior modification for -+ * preferred band configuration with corresponding network configuration -+ * add wlanSetPreferBandByNetwork() for glue layer to invoke for -+ * setting preferred band configuration corresponding to network type. -+ * -+ * 01 05 2012 wh.su -+ * [WCXRP00001153] [MT6620 Wi-Fi][Driver] Adding the get_ch_list and set_tx_power proto type function -+ * Adding the related ioctl / wlan oid function to set the Tx power cfg. -+ * -+ * 10 03 2011 cp.wu -+ * [WCXRP00001022] [MT6628 Driver][Firmware Download] Add multi section independent download functionality -+ * eliminate win32 native data types. -+ * -+ * 10 03 2011 cp.wu -+ * [WCXRP00001022] [MT6628 Driver][Firmware Download] Add multi section independent download functionality -+ * add firmware download path in divided scatters. -+ * -+ * 10 03 2011 cp.wu -+ * [MT6628 Driver][Firmware Download] Add multi section independent download functionality -+ * add firmware downloading aggregated path. -+ * -+ * 09 20 2011 tsaiyuan.hsu -+ * [WCXRP00000931] [MT5931 Wi-Fi][DRV/FW] add swcr to disable roaming from driver -+ * change window registry of driver for roaming. -+ * -+ * 09 08 2011 cm.chang -+ * [WCXRP00000969] [MT6620 Wi-Fi][Driver][FW] Channel list for 5G band based on country code -+ * Use new fields ucChannelListMap and ucChannelListIndex in NVRAM -+ * -+ * 08 31 2011 cm.chang -+ * [WCXRP00000969] [MT6620 Wi-Fi][Driver][FW] Channel list for 5G band based on country code -+ * . -+ * -+ * 08 25 2011 chinghwa.yu -+ * [WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm -+ * Add DFS switch. -+ * -+ * 08 24 2011 chinghwa.yu -+ * [WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm -+ * Update RDD test mode cases. -+ * -+ * 08 15 2011 cp.wu -+ * [WCXRP00000913] [MT6620 Wi-Fi] create repository of source code dedicated for MT6620 E6 ASIC -+ * support to load different firmware image for E3/E4/E5 and E6 ASIC on win32 platforms. -+ * -+ * 08 02 2011 yuche.tsai -+ * [WCXRP00000896] [Volunteer Patch][WiFi Direct][Driver] GO with multiple client, -+ * TX deauth to a disconnecting device issue. -+ * Fix GO send deauth frame issue. -+ * -+ * 07 22 2011 jeffrey.chang -+ * [WCXRP00000864] [MT5931] Add command to adjust OSC stable time -+ * modify driver to set OSC stable time after f/w download -+ * -+ * 07 18 2011 chinghwa.yu -+ * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm -+ * Add CMD/Event for RDD and BWCS. -+ * -+ * 05 27 2011 cp.wu -+ * [WCXRP00000749] [MT6620 Wi-Fi][Driver] Add band edge tx power control to Wi-Fi NVRAM -+ * invoke CMD_ID_SET_EDGE_TXPWR_LIMIT when there is valid data exist in NVRAM content. -+ * -+ * 05 11 2011 cp.wu -+ * [WCXRP00000718] [MT6620 Wi-Fi] modify the behavior of setting tx power -+ * ACPI APIs migrate to wlan_lib.c for glue layer to invoke. -+ * -+ * 04 18 2011 cp.wu -+ * [WCXRP00000636] [WHQL][MT5931 Driver] 2c_PMHibernate (hang on 2h) -+ * 1) add API for glue layer to query ACPI state -+ * 2) Windows glue should not access to hardware after switched into D3 state -+ * -+ * 03 10 2011 cp.wu -+ * [WCXRP00000532] [MT6620 Wi-Fi][Driver] Migrate NVRAM configuration procedures from MT6620 E2 to MT6620 E3 -+ * deprecate configuration used by MT6620 E2 -+ * -+ * 01 27 2011 tsaiyuan.hsu -+ * [WCXRP00000392] [MT6620 Wi-Fi][Driver] Add Roaming Support -+ * add roaming fsm -+ * 1. not support 11r, only use strength of signal to determine roaming. -+ * 2. not enable CFG_SUPPORT_ROAMING until completion of full test. -+ * 3. in 6620, adopt work-around to avoid sign extension problem of cck of hw -+ * 4. assume that change of link quality in smooth way. -+ * -+ * 01 27 2011 george.huang -+ * [WCXRP00000355] [MT6620 Wi-Fi] Set WMM-PS related setting with qualifying AP capability -+ * Support current measure mode, assigned by registry (XP only). -+ * -+ * 01 24 2011 cp.wu -+ * [WCXRP00000382] [MT6620 Wi-Fi][Driver] Track forwarding packet number with notifying tx thread for serving -+ * 1. add an extra counter for tracking pending forward frames. -+ * 2. notify TX service thread as well when there is pending forward frame -+ * 3. correct build errors leaded by introduction of Wi-Fi direct separation module -+ * -+ * 01 10 2011 cp.wu -+ * [WCXRP00000351] [MT6620 Wi-Fi][Driver] remove from scanning result -+ * in OID handling layer when the corresponding BSS is disconnected due to beacon timeout -+ * remove from scanning result when the BSS is disconnected due to beacon timeout. -+ * -+ * 10 27 2010 george.huang -+ * [WCXRP00000127] [MT6620 Wi-Fi][Driver] Add a registry to -+ * disable Beacon Timeout function for SQA test by using E1 EVB -+ * Support registry option for disable beacon lost detection. -+ * -+ * 10 26 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check -+ * [WCXRP00000137] [MT6620 Wi-Fi] [FW] Support NIC capability query command -+ * 1) update NVRAM content template to ver 1.02 -+ * 2) add compile option for querying NIC capability (default: off) -+ * 3) modify AIS 5GHz support to run-time option, which could be turned on by registry or NVRAM setting -+ * 4) correct auto-rate compiler error under linux (treat warning as error) -+ * 5) simplify usage of NVRAM and REG_INFO_T -+ * 6) add version checking between driver and firmware -+ * -+ * 10 26 2010 eddie.chen -+ * [WCXRP00000134] [MT6620 Wi-Fi][Driver] Add a registry to enable auto rate for SQA test by using E1 EVB -+ * Add auto rate parameter in registry. -+ * -+ * 10 18 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check -+ * [WCXRP00000086] [MT6620 Wi-Fi][Driver] The mac address is all zero at android -+ * complete implementation of Android NVRAM access -+ * -+ * 10 08 2010 cp.wu -+ * [WCXRP00000084] [MT6620 Wi-Fi][Driver][FW] Add fixed rate support for distance test -+ * adding fixed rate support for distance test. (from registry setting) -+ * -+ * 10 06 2010 cp.wu -+ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning -+ * divide a single function into 2 part to surpress a weird compiler warning from gcc-4.4.0 -+ * -+ * 10 06 2010 cp.wu -+ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning -+ * code reorganization to improve isolation between GLUE and CORE layers. -+ * -+ * 10 05 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check -+ * load manufacture data when CFG_SUPPORT_NVRAM is set to 1 -+ * -+ * 09 24 2010 cp.wu -+ * [WCXRP00000057] [MT6620 Wi-Fi][Driver] Modify online scan to a run-time switchable feature -+ * Modify online scan as a run-time adjustable option (for Windows, in registry) -+ * -+ * 09 23 2010 cp.wu -+ * [WCXRP00000051] [MT6620 Wi-Fi][Driver] WHQL test fail in MAC address changed item -+ * use firmware reported mac address right after wlanAdapterStart() as permanent address -+ * -+ * 09 23 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check -+ * add skeleton for NVRAM integration -+ * -+ * 08 26 2010 yuche.tsai -+ * NULL -+ * Add AT GO test configure mode under WinXP. -+ * Please enable 1. CFG_ENABLE_WIFI_DIRECT, 2. CFG_TEST_WIFI_DIRECT_GO, 3. CFG_SUPPORT_AAA -+ * -+ * 08 25 2010 george.huang -+ * NULL -+ * . -+ * -+ * 07 21 2010 cp.wu -+ * -+ * 1) change BG_SCAN to ONLINE_SCAN for consistent term -+ * 2) only clear scanning result when scan is permitted to do -+ * -+ * 07 13 2010 cp.wu -+ * -+ * 1) MMPDUs are now sent to MT6620 by CMD queue for keeping strict order of 1X/MMPDU/CMD packets -+ * 2) integrate with qmGetFrameAction() for deciding which MMPDU/1X could pass checking for sending -+ * 2) enhance CMD_INFO_T descriptor number from 10 to 32 to avoid -+ * descriptor underflow under concurrent network operation -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 24 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 802.1x and bluetooth-over-Wi-Fi security frames are now delievered to firmware via command path instead of data path. -+ * -+ * 06 21 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * change MAC address updating logic. -+ * -+ * 06 21 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * simplify timer usage. -+ * -+ * 06 11 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) migrate assoc.c. -+ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness -+ * 3) add configuration options for CNM_MEM and RSN modules -+ * 4) add data path for management frames -+ * 5) eliminate rPacketInfo of MSDU_INFO_T -+ * -+ * 06 08 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * cnm_timer has been migrated. -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 05 20 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) integrate OID_GEN_NETWORK_LAYER_ADDRESSES with CMD_ID_SET_IP_ADDRESS -+ * 2) buffer statistics data for 2 seconds -+ * 3) use default value for adhoc parameters instead of 0 -+ * -+ * 05 12 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * add extra 64 adjustable parameters for CoEX scenario. -+ * -+ * 04 06 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * code refine: fgTestMode should be at adapter rather than glue due to the device/fw is also involved -+ * -+ * 04 06 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) for some OID, never do timeout expiration -+ * * 2) add 2 kal API for later integration -+ * -+ * 04 01 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * change to use WIFI_TCM_ALWAYS_ON as firmware image -+ * -+ * 03 31 2010 wh.su -+ * [WPD00003816][MT6620 Wi-Fi] Adding the security support -+ * modify the wapi related code for new driver's design. -+ * -+ * 03 22 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * always send CMD_NIC_POWER_CTRL packet when nic is being halted -+ * -+ * 03 12 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * add two option for ACK and ENCRYPTION for firmware download -+ * -+ * 02 24 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * separate wlanProcesQueuePacket() into 2 APIs upon request -+ * -+ * 02 23 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * add new API: wlanProcessQueuedPackets() -+ * -+ * 02 11 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1. add logic for firmware download -+ * * * 2. firmware image filename and start/load address are now retrieved from registry -+ * -+ * 02 10 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) remove unused function in nic_rx.c [which has been handled in que_mgt.c] -+ * * * * 2) firmware image length is now retrieved via NdisFileOpen -+ * * * * 3) firmware image is not structured by (P_IMG_SEC_HDR_T) anymore -+ * * * * 4) nicRxWaitResponse() revised -+ * * * * 5) another set of TQ counter default value is added for fw-download state -+ * * * * 6) Wi-Fi load address is now retrieved from registry too -+ * -+ * 02 08 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * prepare for implementing fw download logic -+ * -+ * 01 27 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1. eliminate improper variable in rHifInfo -+ * * * * * * * 2. block TX/ordinary OID when RF test mode is engaged -+ * * * * * * * 3. wait until firmware finish operation when entering into and leaving from RF test mode -+ * * * * * * * 4. correct some HAL implementation -+** \main\maintrunk.MT6620WiFiDriver_Prj\10 2009-12-10 16:39:55 GMT mtk02752 -+** eliminate unused API -+** \main\maintrunk.MT6620WiFiDriver_Prj\9 2009-10-13 21:58:41 GMT mtk01084 -+** update for new macro define -+** \main\maintrunk.MT6620WiFiDriver_Prj\8 2009-05-19 10:43:06 GMT mtk01461 -+** Add wlanReleasePendingOid() -+** \main\maintrunk.MT6620WiFiDriver_Prj\7 2009-04-13 16:38:44 GMT mtk01084 -+** add WIFI start function -+** \main\maintrunk.MT6620WiFiDriver_Prj\6 2009-04-08 16:51:14 GMT mtk01084 -+** Update for the image download part -+** \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-04-01 10:57:38 GMT mtk01461 -+** Add wlanSendLeftClusteredFrames() for SDIO_TX_ENHANCE -+** \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-03-23 00:31:02 GMT mtk01461 -+** Add declaration of FW Image download reference code -+** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-03-16 09:08:31 GMT mtk01461 -+** Update TX PATH API -+** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 20:12:04 GMT mtk01426 -+** Init for develop -+** -+*/ -+ -+#ifndef _WLAN_LIB_H -+#define _WLAN_LIB_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "CFG_Wifi_File.h" -+#include "rlm_domain.h" -+#include "wlan_typedef.h" -+ -+ -+extern BOOLEAN fgIsResetting; -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+#define MAX_NUM_GROUP_ADDR 32 /* max number of group addresses */ -+ -+#define TX_CS_TCP_UDP_GEN BIT(1) -+#define TX_CS_IP_GEN BIT(0) -+ -+#define CSUM_OFFLOAD_EN_TX_TCP BIT(0) -+#define CSUM_OFFLOAD_EN_TX_UDP BIT(1) -+#define CSUM_OFFLOAD_EN_TX_IP BIT(2) -+#define CSUM_OFFLOAD_EN_RX_TCP BIT(3) -+#define CSUM_OFFLOAD_EN_RX_UDP BIT(4) -+#define CSUM_OFFLOAD_EN_RX_IPv4 BIT(5) -+#define CSUM_OFFLOAD_EN_RX_IPv6 BIT(6) -+#define CSUM_OFFLOAD_EN_TX_MASK BITS(0, 2) -+#define CSUM_OFFLOAD_EN_ALL BITS(0, 6) -+ -+/* TCP, UDP, IP Checksum */ -+#define RX_CS_TYPE_UDP BIT(7) -+#define RX_CS_TYPE_TCP BIT(6) -+#define RX_CS_TYPE_IPv6 BIT(5) -+#define RX_CS_TYPE_IPv4 BIT(4) -+ -+#define RX_CS_STATUS_UDP BIT(3) -+#define RX_CS_STATUS_TCP BIT(2) -+#define RX_CS_STATUS_IP BIT(0) -+ -+#define CSUM_NOT_SUPPORTED 0x0 -+ -+#define TXPWR_USE_PDSLOPE 0 -+ -+/* NVRAM error code definitions */ -+#define NVRAM_ERROR_VERSION_MISMATCH BIT(1) -+#define NVRAM_ERROR_INVALID_TXPWR BIT(2) -+#define NVRAM_ERROR_INVALID_DPD BIT(3) -+#define NVRAM_ERROR_INVALID_MAC_ADDR BIT(4) -+#if CFG_SUPPORT_PWR_LIMIT_COUNTRY -+#define NVRAM_POWER_LIMIT_TABLE_INVALID BIT(5) -+#endif -+ -+#define NUM_TC_RESOURCE_TO_STATISTICS 4 -+ -+#define WLAN_CFG_ARGV_MAX 8 -+#define WLAN_CFG_ENTRY_NUM_MAX 128 -+#define WLAN_CFG_KEY_LEN_MAX 32 /* include \x00 EOL */ -+#define WLAN_CFG_VALUE_LEN_MAX 32 /* include \x00 EOL */ -+#define WLAN_CFG_FLAG_SKIP_CB BIT(0) -+#define WLAN_CFG_FILE_BUF_SIZE 2048 -+ -+#define WLAN_CFG_SET_CHIP_LEN_MAX 10 -+#define WLAN_CFG_SET_DEBUG_LEVEL_LEN_MAX 10 -+#define WLAN_CFG_SET_SW_CTRL_LEN_MAX 10 -+ -+#define WLAN_OID_TIMEOUT_THRESHOLD 2000 /* OID timeout (in ms) */ -+#define WLAN_OID_TIMEOUT_THRESHOLD_IN_RESETTING 300 /* OID timeout during chip-resetting (in ms) */ -+ -+#define WLAN_OID_NO_ACK_THRESHOLD 3 -+ -+#define WLAN_TX_THREAD_TASK_PRIORITY 0 /* If not setting the priority, 0 is the default */ -+#define WLAN_TX_THREAD_TASK_NICE (-10) /* If not setting the nice, -10 is the default */ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+typedef WLAN_STATUS(*PFN_OID_HANDLER_FUNC) (IN P_ADAPTER_T prAdapter, -+ IN PVOID pvBuf, IN UINT_32 u4BufLen, OUT PUINT_32 pu4OutInfoLen); -+ -+typedef enum _ENUM_CSUM_TYPE_T { -+ CSUM_TYPE_IPV4, -+ CSUM_TYPE_IPV6, -+ CSUM_TYPE_TCP, -+ CSUM_TYPE_UDP, -+ CSUM_TYPE_NUM -+} ENUM_CSUM_TYPE_T, *P_ENUM_CSUM_TYPE_T; -+ -+typedef enum _ENUM_CSUM_RESULT_T { -+ CSUM_RES_NONE, -+ CSUM_RES_SUCCESS, -+ CSUM_RES_FAILED, -+ CSUM_RES_NUM -+} ENUM_CSUM_RESULT_T, *P_ENUM_CSUM_RESULT_T; -+ -+typedef enum _ENUM_PHY_MODE_T { -+ ENUM_PHY_2G4_CCK, -+ ENUM_PHY_2G4_OFDM_BPSK, -+ ENUM_PHY_2G4_OFDM_QPSK, -+ ENUM_PHY_2G4_OFDM_16QAM, -+ ENUM_PHY_2G4_OFDM_48M, -+ ENUM_PHY_2G4_OFDM_54M, -+ ENUM_PHY_2G4_HT20_BPSK, -+ ENUM_PHY_2G4_HT20_QPSK, -+ ENUM_PHY_2G4_HT20_16QAM, -+ ENUM_PHY_2G4_HT20_MCS5, -+ ENUM_PHY_2G4_HT20_MCS6, -+ ENUM_PHY_2G4_HT20_MCS7, -+ ENUM_PHY_2G4_HT40_BPSK, -+ ENUM_PHY_2G4_HT40_QPSK, -+ ENUM_PHY_2G4_HT40_16QAM, -+ ENUM_PHY_2G4_HT40_MCS5, -+ ENUM_PHY_2G4_HT40_MCS6, -+ ENUM_PHY_2G4_HT40_MCS7, -+ ENUM_PHY_5G_OFDM_BPSK, -+ ENUM_PHY_5G_OFDM_QPSK, -+ ENUM_PHY_5G_OFDM_16QAM, -+ ENUM_PHY_5G_OFDM_48M, -+ ENUM_PHY_5G_OFDM_54M, -+ ENUM_PHY_5G_HT20_BPSK, -+ ENUM_PHY_5G_HT20_QPSK, -+ ENUM_PHY_5G_HT20_16QAM, -+ ENUM_PHY_5G_HT20_MCS5, -+ ENUM_PHY_5G_HT20_MCS6, -+ ENUM_PHY_5G_HT20_MCS7, -+ ENUM_PHY_5G_HT40_BPSK, -+ ENUM_PHY_5G_HT40_QPSK, -+ ENUM_PHY_5G_HT40_16QAM, -+ ENUM_PHY_5G_HT40_MCS5, -+ ENUM_PHY_5G_HT40_MCS6, -+ ENUM_PHY_5G_HT40_MCS7, -+ ENUM_PHY_MODE_NUM -+} ENUM_PHY_MODE_T, *P_ENUM_PHY_MODE_T; -+ -+typedef enum _ENUM_POWER_SAVE_POLL_MODE_T { -+ ENUM_POWER_SAVE_POLL_DISABLE, -+ ENUM_POWER_SAVE_POLL_LEGACY_NULL, -+ ENUM_POWER_SAVE_POLL_QOS_NULL, -+ ENUM_POWER_SAVE_POLL_NUM -+} ENUM_POWER_SAVE_POLL_MODE_T, *P_ENUM_POWER_SAVE_POLL_MODE_T; -+ -+typedef enum _ENUM_AC_TYPE_T { -+ ENUM_AC_TYPE_AC0, -+ ENUM_AC_TYPE_AC1, -+ ENUM_AC_TYPE_AC2, -+ ENUM_AC_TYPE_AC3, -+ ENUM_AC_TYPE_AC4, -+ ENUM_AC_TYPE_AC5, -+ ENUM_AC_TYPE_AC6, -+ ENUM_AC_TYPE_BMC, -+ ENUM_AC_TYPE_NUM -+} ENUM_AC_TYPE_T, *P_ENUM_AC_TYPE_T; -+ -+typedef enum _ENUM_ADV_AC_TYPE_T { -+ ENUM_ADV_AC_TYPE_RX_NSW, -+ ENUM_ADV_AC_TYPE_RX_PTA, -+ ENUM_ADV_AC_TYPE_RX_SP, -+ ENUM_ADV_AC_TYPE_TX_PTA, -+ ENUM_ADV_AC_TYPE_TX_RSP, -+ ENUM_ADV_AC_TYPE_NUM -+} ENUM_ADV_AC_TYPE_T, *P_ENUM_ADV_AC_TYPE_T; -+ -+typedef enum _ENUM_REG_CH_MAP_T { -+ REG_CH_MAP_COUNTRY_CODE, -+ REG_CH_MAP_TBL_IDX, -+ REG_CH_MAP_CUSTOMIZED, -+ REG_CH_MAP_NUM -+} ENUM_REG_CH_MAP_T, *P_ENUM_REG_CH_MAP_T; -+ -+#define CHIP_CONFIG_RESP_SIZE 320 -+enum { -+ CHIP_CONFIG_TYPE_WO_RESPONSE = 0x00, -+ CHIP_CONFIG_TYPE_MEM8 = 0x01, -+ CHIP_CONFIG_TYPE_MEM32 = 0x02, -+ CHIP_CONFIG_TYPE_ASCII = 0x03, -+ CHIP_CONFIG_TYPE_BINARY = 0x04, -+ CHIP_CONFIG_TYPE_DRV_PASSTHROUGH = 0x05, -+ CHIP_CONFIG_TYPE_END -+}; -+ -+typedef struct _SET_TXPWR_CTRL_T { -+ INT_8 c2GLegacyStaPwrOffset; /* Unit: 0.5dBm, default: 0 */ -+ INT_8 c2GHotspotPwrOffset; -+ INT_8 c2GP2pPwrOffset; -+ INT_8 c2GBowPwrOffset; -+ INT_8 c5GLegacyStaPwrOffset; /* Unit: 0.5dBm, default: 0 */ -+ INT_8 c5GHotspotPwrOffset; -+ INT_8 c5GP2pPwrOffset; -+ INT_8 c5GBowPwrOffset; -+ UINT_8 ucConcurrencePolicy; /* TX power policy when concurrence -+ in the same channel -+ 0: Highest power has priority -+ 1: Lowest power has priority */ -+ INT_8 acReserved1[3]; /* Must be zero */ -+ -+ /* Power limit by channel for all data rates */ -+ INT_8 acTxPwrLimit2G[14]; /* Channel 1~14, Unit: 0.5dBm */ -+ INT_8 acTxPwrLimit5G[4]; /* UNII 1~4 */ -+ INT_8 acReserved2[2]; /* Must be zero */ -+} SET_TXPWR_CTRL_T, *P_SET_TXPWR_CTRL_T; -+ -+/* For storing driver initialization value from glue layer */ -+typedef struct _REG_INFO_T { -+ UINT_32 u4SdBlockSize; /* SDIO block size */ -+ UINT_32 u4SdBusWidth; /* SDIO bus width. 1 or 4 */ -+ UINT_32 u4SdClockRate; /* SDIO clock rate. (in unit of HZ) */ -+ UINT_32 u4StartAddress; /* Starting address of Wi-Fi Firmware */ -+ UINT_32 u4LoadAddress; /* Load address of Wi-Fi Firmware */ -+ UINT_16 aucFwImgFilename[65]; /* Firmware filename */ -+ UINT_16 aucFwImgFilenameE6[65]; /* Firmware filename for E6 */ -+ UINT_32 u4StartFreq; /* Start Frequency for Ad-Hoc network : in unit of KHz */ -+ UINT_32 u4AdhocMode; /* Default mode for Ad-Hoc network : ENUM_PARAM_AD_HOC_MODE_T */ -+ UINT_32 u4RddStartFreq; -+ UINT_32 u4RddStopFreq; -+ UINT_32 u4RddTestMode; -+ UINT_32 u4RddShutFreq; -+ UINT_32 u4RddDfs; -+ INT_32 i4HighRssiThreshold; -+ INT_32 i4MediumRssiThreshold; -+ INT_32 i4LowRssiThreshold; -+ INT_32 au4TxPriorityTag[ENUM_AC_TYPE_NUM]; -+ INT_32 au4RxPriorityTag[ENUM_AC_TYPE_NUM]; -+ INT_32 au4AdvPriorityTag[ENUM_ADV_AC_TYPE_NUM]; -+ UINT_32 u4FastPSPoll; -+ UINT_32 u4PTA; /* 0: disable, 1: enable */ -+ UINT_32 u4TXLimit; /* 0: disable, 1: enable */ -+ UINT_32 u4SilenceWindow; /* range: 100 - 625, unit: us */ -+ UINT_32 u4TXLimitThreshold; /* range: 250 - 1250, unit: us */ -+ UINT_32 u4PowerMode; -+ UINT_32 fgEnArpFilter; -+ UINT_32 u4PsCurrentMeasureEn; -+ UINT_32 u4UapsdAcBmp; -+ UINT_32 u4MaxSpLen; -+ UINT_32 fgDisOnlineScan; /* 0: enable online scan, non-zero: disable online scan */ -+ UINT_32 fgDisBcnLostDetection; /* 0: enable online scan, non-zero: disable online scan */ -+ UINT_32 u4FixedRate; /* 0: automatic, non-zero: fixed rate */ -+ UINT_32 u4ArSysParam0; -+ UINT_32 u4ArSysParam1; -+ UINT_32 u4ArSysParam2; -+ UINT_32 u4ArSysParam3; -+ UINT_32 fgDisRoaming; /* 0:enable roaming 1:disable */ -+ -+ /* NVRAM - MP Data -START- */ -+ UINT_8 aucMacAddr[6]; -+ UINT_16 au2CountryCode[4]; /* Country code (in ISO 3166-1 expression, ex: "US", "TW") */ -+ TX_PWR_PARAM_T rTxPwr; -+ UINT_8 aucEFUSE[144]; -+ UINT_8 ucTxPwrValid; -+ UINT_8 ucSupport5GBand; -+ UINT_8 fg2G4BandEdgePwrUsed; -+ INT_8 cBandEdgeMaxPwrCCK; -+ INT_8 cBandEdgeMaxPwrOFDM20; -+ INT_8 cBandEdgeMaxPwrOFDM40; -+ ENUM_REG_CH_MAP_T eRegChannelListMap; -+ UINT_8 ucRegChannelListIndex; -+ DOMAIN_INFO_ENTRY rDomainInfo; -+ /* NVRAM - MP Data -END- */ -+ -+ /* NVRAM - Functional Data -START- */ -+ UINT_8 uc2G4BwFixed20M; -+ UINT_8 uc5GBwFixed20M; -+ UINT_8 ucEnable5GBand; -+ UINT_8 uc2GRssiCompensation; -+ UINT_8 uc5GRssiCompensation; -+ UINT_8 fgRssiCompensationValidbit; -+ UINT_8 ucRxAntennanumber; -+ /* NVRAM - Functional Data -END- */ -+ -+} REG_INFO_T, *P_REG_INFO_T; -+ -+/* for divided firmware loading */ -+typedef struct _FWDL_SECTION_INFO_T { -+ UINT_32 u4Offset; -+ UINT_32 u4Reserved; -+ UINT_32 u4Length; -+ UINT_32 u4DestAddr; -+} FWDL_SECTION_INFO_T, *P_FWDL_SECTION_INFO_T; -+ -+typedef struct _FIRMWARE_DIVIDED_DOWNLOAD_T { -+ UINT_32 u4Signature; -+ UINT_32 u4CRC; /* CRC calculated without first 8 bytes included */ -+ UINT_32 u4NumOfEntries; -+ UINT_32 u4Reserved; -+ FWDL_SECTION_INFO_T arSection[]; -+} FIRMWARE_DIVIDED_DOWNLOAD_T, *P_FIRMWARE_DIVIDED_DOWNLOAD_T; -+ -+typedef struct _PARAM_MCR_RW_STRUCT_T { -+ UINT_32 u4McrOffset; -+ UINT_32 u4McrData; -+} PARAM_MCR_RW_STRUCT_T, *P_PARAM_MCR_RW_STRUCT_T; -+ -+typedef struct _PARAM_GET_STA_STATISTICS { -+ UINT_8 ucInvalid; -+ UINT_8 ucVersion; -+ /* Per-STA statistic */ -+ UINT_8 aucMacAddr[MAC_ADDR_LEN]; -+ UINT_32 u4LinkScore; -+ UINT_32 u4Flag; -+ -+ /* From FW */ -+ UINT_8 ucPer; /* base: 128 */ -+ UINT_8 ucRcpi; -+ UINT_32 u4PhyMode; -+ UINT_16 u2LinkSpeed; /* unit is 0.5 Mbits */ -+ -+ UINT_32 u4TxFailCount; -+ UINT_32 u4TxLifeTimeoutCount; -+ UINT_32 u4TxAverageAirTime; -+ -+ /* From driver */ -+ UINT_32 u4TxTotalCount; -+ UINT_32 u4TxExceedThresholdCount; -+ UINT_32 u4TxAverageProcessTime; -+ -+ UINT_32 u4TxMaxTime; -+ UINT_32 u4TxMaxHifTime; -+ UINT_32 u4TxAverageHifTime; -+ -+ /* -+ * How many packages Enqueue/Deqeue during statistics interval -+ */ -+ UINT_32 u4EnqueueCounter; -+ UINT_32 u4DequeueCounter; -+ -+ UINT_32 u4EnqueueStaCounter; -+ UINT_32 u4DequeueStaCounter; -+ -+ UINT_32 IsrCnt; -+ UINT_32 IsrPassCnt; -+ UINT_32 TaskIsrCnt; -+ -+ UINT_32 IsrAbnormalCnt; -+ UINT_32 IsrSoftWareCnt; -+ UINT_32 IsrRxCnt; -+ UINT_32 IsrTxCnt; -+ -+ UINT_32 au4TcResourceEmptyCount[NUM_TC_RESOURCE_TO_STATISTICS]; -+ UINT_32 au4DequeueNoTcResource[NUM_TC_RESOURCE_TO_STATISTICS]; -+ UINT_32 au4TcResourceBackCount[NUM_TC_RESOURCE_TO_STATISTICS]; -+ -+ UINT_32 au4TcResourceUsedCount[NUM_TC_RESOURCE_TO_STATISTICS]; -+ UINT_32 au4TcResourceWantedCount[NUM_TC_RESOURCE_TO_STATISTICS]; -+ -+ UINT_32 au4TcQueLen[NUM_TC_RESOURCE_TO_STATISTICS]; -+ /* Global queue management statistic */ -+ UINT_32 au4TcAverageQueLen[NUM_TC_RESOURCE_TO_STATISTICS]; -+ UINT_32 au4TcCurrentQueLen[NUM_TC_RESOURCE_TO_STATISTICS]; -+ -+ /* Reserved fields */ -+ UINT_8 au4Reserved[32]; -+} PARAM_GET_STA_STA_STATISTICS, *P_PARAM_GET_STA_STATISTICS; -+ -+#if CFG_AUTO_CHANNEL_SEL_SUPPORT -+typedef enum _ENUM_TESTMODE_AVAILABLE_CHAN_ATTR { -+ NL80211_TESTMODE_AVAILABLE_CHAN_INVALID = 0, -+ NL80211_TESTMODE_AVAILABLE_CHAN_2G_BASE_1, -+ NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_34, -+ NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_149, -+ NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_184, -+ -+ NL80211_TESTMODE_AVAILABLE_CHAN_NUM, -+} ENUM_TESTMODE_AVAILABLE_CHAN_ATTR; -+ -+typedef struct _LTE_SAFE_CH_INFO_T { -+ UINT_32 au4SafeChannelBitmask[NL80211_TESTMODE_AVAILABLE_CHAN_NUM - 1]; -+} LTE_SAFE_CH_INFO_T, *P_CMD_LTE_SAFE_CH_INFO_T; -+ -+ /* Record Each CH Load */ -+typedef struct _PARAM_CHN_LOAD_INFO { -+ /* Per-CHN Load */ -+ UINT_32 u4Flag; -+ -+ UINT_8 ucChannel; -+ UINT_16 u2ChannelLoad; -+ UINT_8 au4Reserved[1]; -+ -+ UINT_16 u2APNum; -+ UINT_16 u2APNumTmpCountingBuf; -+ -+ /* Reserved fields */ -+ UINT_8 au4Reserved1[8]; -+} PARAM_CHN_LOAD_INFO, *P_PARAM_CHN_LOAD_INFO; -+ -+typedef struct _PARAM_GET_CHN_LOAD { -+ LTE_SAFE_CH_INFO_T rLteSafeChnList; -+ PARAM_CHN_LOAD_INFO rEachChnLoad[MAX_AUTO_CHAL_NUM]; -+ BOOLEAN fgDataReadyBit; -+ UINT_8 au4Reserved1[3]; -+} PARAM_GET_CHN_LOAD, *P_PARAM_GET_CHN_LOAD; -+ -+typedef struct _PARAM_PREFER_CHN_INFO { -+ -+ UINT_8 ucChannel; -+ UINT_16 u2APNum; -+ UINT_8 au4Reserved1[1]; -+} PARAM_PREFER_CHN_INFO, *P_PARAM_PREFER_CHN_INFO; -+ -+typedef struct _PARAM_GET_LTE_MODE { -+ /* Event Body */ -+ UINT_8 ucVersion; -+ UINT_8 aucReserved1[3]; -+ UINT_32 u4Flags; /* Bit0: valid */ -+ -+ LTE_SAFE_CH_INFO_T LTE_MODE; -+ UINT_8 aucReserved4[3]; -+ -+ UINT_8 aucReserved[4]; -+ -+} PARAM_GET_LTE_MODE, *P_PARAM_GET_LTE_MODE; -+ -+#endif -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+#define BUILD_SIGN(ch0, ch1, ch2, ch3) \ -+ ((UINT_32)(UINT_8)(ch0) | ((UINT_32)(UINT_8)(ch1) << 8) | \ -+ ((UINT_32)(UINT_8)(ch2) << 16) | ((UINT_32)(UINT_8)(ch3) << 24)) -+ -+#define MTK_WIFI_SIGNATURE BUILD_SIGN('M', 'T', 'K', 'W') -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+P_ADAPTER_T wlanAdapterCreate(IN P_GLUE_INFO_T prGlueInfo); -+ -+VOID wlanAdapterDestroy(IN P_ADAPTER_T prAdapter); -+ -+VOID wlanCardEjected(IN P_ADAPTER_T prAdapter); -+ -+VOID wlanIST(IN P_ADAPTER_T prAdapter); -+ -+BOOLEAN wlanISR(IN P_ADAPTER_T prAdapter, IN BOOLEAN fgGlobalIntrCtrl); -+ -+WLAN_STATUS wlanProcessCommandQueue(IN P_ADAPTER_T prAdapter, IN P_QUE_T prCmdQue); -+ -+WLAN_STATUS wlanSendCommand(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo); -+ -+VOID wlanReleaseCommand(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo); -+ -+VOID wlanReleasePendingOid(IN P_ADAPTER_T prAdapter, IN ULONG ulData); -+ -+VOID wlanReleasePendingCMDbyNetwork(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkType); -+ -+VOID wlanReturnPacket(IN P_ADAPTER_T prAdapter, IN PVOID pvPacket); -+ -+VOID wlanReturnIndicatedPacketsTimeOut(IN P_ADAPTER_T prAdapter, IN ULONG ulData); -+ -+WLAN_STATUS -+wlanQueryInformation(IN P_ADAPTER_T prAdapter, -+ IN PFN_OID_HANDLER_FUNC pfOidQryHandler, -+ IN PVOID pvInfoBuf, IN UINT_32 u4InfoBufLen, OUT PUINT_32 pu4QryInfoLen); -+ -+WLAN_STATUS -+wlanSetInformation(IN P_ADAPTER_T prAdapter, -+ IN PFN_OID_HANDLER_FUNC pfOidSetHandler, -+ IN PVOID pvInfoBuf, IN UINT_32 u4InfoBufLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanAdapterStart(IN P_ADAPTER_T prAdapter, -+ IN P_REG_INFO_T prRegInfo, IN PVOID pvFwImageMapFile, IN UINT_32 u4FwImageFileLength); -+ -+WLAN_STATUS wlanAdapterStop(IN P_ADAPTER_T prAdapter); -+ -+#if CFG_SUPPORT_WAPI -+BOOLEAN wlanQueryWapiMode(IN P_ADAPTER_T prAdapter); -+#endif -+ -+VOID wlanReturnRxPacket(IN PVOID pvAdapter, IN PVOID pvPacket); -+ -+VOID wlanRxSetBroadcast(IN P_ADAPTER_T prAdapter, IN BOOLEAN fgEnableBroadcast); -+ -+BOOLEAN wlanIsHandlerNeedHwAccess(IN PFN_OID_HANDLER_FUNC pfnOidHandler, IN BOOLEAN fgSetInfo); -+ -+VOID wlanSetPromiscuousMode(IN P_ADAPTER_T prAdapter, IN BOOLEAN fgEnablePromiscuousMode); -+ -+#if CFG_ENABLE_FW_DOWNLOAD -+#if CFG_ENABLE_FW_DOWNLOAD_AGGREGATION -+WLAN_STATUS -+wlanImageSectionDownloadAggregated(IN P_ADAPTER_T prAdapter, -+ IN UINT_32 u4DestAddr, IN UINT_32 u4ImgSecSize, IN PUINT_8 pucImgSecBuf); -+#endif -+ -+WLAN_STATUS -+wlanImageSectionDownload(IN P_ADAPTER_T prAdapter, -+ IN UINT_32 u4DestAddr, IN UINT_32 u4ImgSecSize, IN PUINT_8 pucImgSecBuf); -+ -+#if !CFG_ENABLE_FW_DOWNLOAD_ACK -+WLAN_STATUS wlanImageQueryStatus(IN P_ADAPTER_T prAdapter); -+#else -+WLAN_STATUS wlanImageSectionDownloadStatus(IN P_ADAPTER_T prAdapter, IN UINT_8 ucCmdSeqNum); -+#endif -+ -+WLAN_STATUS wlanConfigWifiFunc(IN P_ADAPTER_T prAdapter, IN BOOLEAN fgEnable, IN UINT_32 u4StartAddress); -+ -+UINT_32 wlanCRC32(PUINT_8 buf, UINT_32 len); -+ -+#endif -+ -+WLAN_STATUS wlanSendNicPowerCtrlCmd(IN P_ADAPTER_T prAdapter, IN UINT_8 ucPowerMode); -+ -+BOOLEAN wlanIsHandlerAllowedInRFTest(IN PFN_OID_HANDLER_FUNC pfnOidHandler, IN BOOLEAN fgSetInfo); -+ -+WLAN_STATUS wlanProcessQueuedSwRfb(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfbListHead); -+ -+WLAN_STATUS wlanProcessQueuedMsduInfo(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfoListHead); -+ -+BOOLEAN wlanoidTimeoutCheck(IN P_ADAPTER_T prAdapter, IN PFN_OID_HANDLER_FUNC pfnOidHandler); -+ -+VOID wlanoidClearTimeoutCheck(IN P_ADAPTER_T prAdapter); -+ -+WLAN_STATUS wlanUpdateNetworkAddress(IN P_ADAPTER_T prAdapter); -+ -+BOOLEAN wlanQueryTestMode(IN P_ADAPTER_T prAdapter); -+ -+/* Security Frame Handling */ -+BOOLEAN wlanProcessSecurityFrame(IN P_ADAPTER_T prAdapter, IN P_NATIVE_PACKET prPacket); -+ -+VOID wlanSecurityFrameTxDone(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf); -+ -+VOID wlanSecurityFrameTxTimeout(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo); -+ -+/*----------------------------------------------------------------------------*/ -+/* OID/IOCTL Handling */ -+/*----------------------------------------------------------------------------*/ -+VOID wlanClearScanningResult(IN P_ADAPTER_T prAdapter); -+ -+VOID wlanClearBssInScanningResult(IN P_ADAPTER_T prAdapter, IN PUINT_8 arBSSID); -+ -+#if CFG_TEST_WIFI_DIRECT_GO -+VOID wlanEnableP2pFunction(IN P_ADAPTER_T prAdapter); -+ -+VOID wlanEnableATGO(IN P_ADAPTER_T prAdapter); -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/* Address Retrieve by Polling */ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS wlanQueryPermanentAddress(IN P_ADAPTER_T prAdapter); -+ -+/*----------------------------------------------------------------------------*/ -+/* NIC Capability Retrieve by Polling */ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS wlanQueryNicCapability(IN P_ADAPTER_T prAdapter); -+ -+/*----------------------------------------------------------------------------*/ -+/* NIC Capability Retrieve by Polling */ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS wlanQueryDebugCode(IN P_ADAPTER_T prAdapter); -+ -+/*----------------------------------------------------------------------------*/ -+/* Compiler Flags Retrieve by Polling */ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS wlanQueryCompileFlags(IN P_ADAPTER_T prAdapter); -+ -+/*----------------------------------------------------------------------------*/ -+/* PD MCR Retrieve by Polling */ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS wlanQueryPdMcr(IN P_ADAPTER_T prAdapter, IN P_PARAM_MCR_RW_STRUCT_T prMcrRdInfo); -+/*----------------------------------------------------------------------------*/ -+/* Loading Manufacture Data */ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS wlanLoadManufactureData(IN P_ADAPTER_T prAdapter, IN P_REG_INFO_T prRegInfo); -+ -+/*----------------------------------------------------------------------------*/ -+/* Media Stream Mode */ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN wlanResetMediaStreamMode(IN P_ADAPTER_T prAdapter); -+ -+/*----------------------------------------------------------------------------*/ -+/* Timer Timeout Check (for Glue Layer) */ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS wlanTimerTimeoutCheck(IN P_ADAPTER_T prAdapter); -+ -+/*----------------------------------------------------------------------------*/ -+/* Mailbox Message Check (for Glue Layer) */ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS wlanProcessMboxMessage(IN P_ADAPTER_T prAdapter); -+ -+/*----------------------------------------------------------------------------*/ -+/* TX Pending Packets Handling (for Glue Layer) */ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS wlanEnqueueTxPacket(IN P_ADAPTER_T prAdapter, IN P_NATIVE_PACKET prNativePacket); -+ -+WLAN_STATUS wlanFlushTxPendingPackets(IN P_ADAPTER_T prAdapter); -+ -+WLAN_STATUS wlanTxPendingPackets(IN P_ADAPTER_T prAdapter, IN OUT PBOOLEAN pfgHwAccess); -+ -+/*----------------------------------------------------------------------------*/ -+/* Low Power Acquire/Release (for Glue Layer) */ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS wlanAcquirePowerControl(IN P_ADAPTER_T prAdapter); -+ -+WLAN_STATUS wlanReleasePowerControl(IN P_ADAPTER_T prAdapter); -+ -+/*----------------------------------------------------------------------------*/ -+/* Pending Packets Number Reporting (for Glue Layer) */ -+/*----------------------------------------------------------------------------*/ -+UINT_32 wlanGetTxPendingFrameCount(IN P_ADAPTER_T prAdapter); -+ -+/*----------------------------------------------------------------------------*/ -+/* ACPI state inquiry (for Glue Layer) */ -+/*----------------------------------------------------------------------------*/ -+ENUM_ACPI_STATE_T wlanGetAcpiState(IN P_ADAPTER_T prAdapter); -+ -+VOID wlanSetAcpiState(IN P_ADAPTER_T prAdapter, IN ENUM_ACPI_STATE_T ePowerState); -+ -+VOID wlanDefTxPowerCfg(IN P_ADAPTER_T prAdapter); -+ -+/*----------------------------------------------------------------------------*/ -+/* get ECO version from Revision ID register (for Win32) */ -+/*----------------------------------------------------------------------------*/ -+UINT_8 wlanGetEcoVersion(IN P_ADAPTER_T prAdapter); -+ -+/*----------------------------------------------------------------------------*/ -+/* set preferred band configuration corresponding to network type */ -+/*----------------------------------------------------------------------------*/ -+VOID -+wlanSetPreferBandByNetwork(IN P_ADAPTER_T prAdapter, IN ENUM_BAND_T eBand, IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex); -+ -+/*----------------------------------------------------------------------------*/ -+/* get currently operating channel information */ -+/*----------------------------------------------------------------------------*/ -+UINT_8 wlanGetChannelNumberByNetwork(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex); -+ -+/*----------------------------------------------------------------------------*/ -+/* get BSS Descriptor information */ -+/*----------------------------------------------------------------------------*/ -+P_BSS_DESC_T wlanGetTargetBssDescByNetwork(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex); -+ -+/*----------------------------------------------------------------------------*/ -+/* check for system configuration to generate message on scan list */ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS wlanCheckSystemConfiguration(IN P_ADAPTER_T prAdapter); -+ -+/*----------------------------------------------------------------------------*/ -+/* query sta statistics information from driver and firmware */ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidQueryStaStatistics(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS wlanCfgParseArgument(CHAR *cmdLine, INT_32 *argc, CHAR *argv[]); -+ -+P_WLAN_CFG_ENTRY_T wlanCfgGetEntry(IN P_ADAPTER_T prAdapter, const PCHAR pucKey); -+ -+WLAN_STATUS -+wlanCfgGet(IN P_ADAPTER_T prAdapter, const PCHAR pucKey, PCHAR pucValue, PCHAR pucValueDef, UINT_32 u4Flags); -+ -+UINT_32 wlanCfgGetUint32(IN P_ADAPTER_T prAdapter, const PCHAR pucKey, UINT_32 u4ValueDef); -+ -+INT_32 wlanCfgGetInt32(IN P_ADAPTER_T prAdapter, const PCHAR pucKey, INT_32 i4ValueDef); -+ -+WLAN_STATUS wlanCfgSetUint32(IN P_ADAPTER_T prAdapter, const PCHAR pucKey, UINT_32 u4Value); -+ -+WLAN_STATUS wlanCfgSet(IN P_ADAPTER_T prAdapter, const PCHAR pucKey, PCHAR pucValue, UINT_32 u4Flags); -+ -+WLAN_STATUS -+wlanCfgSetCb(IN P_ADAPTER_T prAdapter, const PCHAR pucKey, WLAN_CFG_SET_CB pfSetCb, void *pPrivate, UINT_32 u4Flags); -+ -+#if CFG_SUPPORT_CFG_FILE -+WLAN_STATUS wlanCfgInit(IN P_ADAPTER_T prAdapter, PUINT_8 pucConfigBuf, UINT_32 u4ConfigBufLen, UINT_32 u4Flags); -+ -+VOID wlanCfgApply(IN P_ADAPTER_T prAdapter); -+#endif /* CFG_SUPPORT_CFG_FILE */ -+ -+extern VOID mtk_wcn_wmt_set_wifi_ver(UINT_32 Value); -+ -+#endif /* _WLAN_LIB_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/wlan_oid.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/wlan_oid.h -new file mode 100644 -index 000000000000..45919df996e9 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/wlan_oid.h -@@ -0,0 +1,1715 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/include/wlan_oid.h#2 -+*/ -+ -+/*! \file "wlan_oid.h" -+ \brief This file contains the declairation file of the WLAN OID processing routines -+ of Windows driver for MediaTek Inc. 802.11 Wireless LAN Adapters. -+*/ -+ -+/* -+** Log: wlan_oid.h -+ * -+ * 03 02 2012 terry.wu -+ * NULL -+ * Sync CFG80211 modification from branch 2,2. -+ * -+ * 01 05 2012 wh.su -+ * [WCXRP00001153] [MT6620 Wi-Fi][Driver] Adding the get_ch_list and set_tx_power proto type function -+ * Adding the related ioctl / wlan oid function to set the Tx power cfg. -+ * -+ * 07 18 2011 chinghwa.yu -+ * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm -+ * Add CMD/Event for RDD and BWCS. -+ * -+ * 03 22 2011 george.huang -+ * [WCXRP00000504] [MT6620 Wi-Fi][FW] Support Sigma CAPI for power saving related command -+ * link with supplicant commands -+ * -+ * 03 17 2011 chinglan.wang -+ * [WCXRP00000570] [MT6620 Wi-Fi][Driver] Add Wi-Fi Protected Setup v2.0 feature -+ * . -+ * -+ * 03 02 2011 george.huang -+ * [WCXRP00000504] [MT6620 Wi-Fi][FW] Support Sigma CAPI for power saving related command -+ * Support UAPSD/OppPS/NoA parameter setting -+ * -+ * 01 20 2011 eddie.chen -+ * [WCXRP00000374] [MT6620 Wi-Fi][DRV] SW debug control -+ * Add Oid for sw control debug command -+ * -+ * 12 07 2010 cm.chang -+ * [WCXRP00000238] MT6620 Wi-Fi][Driver][FW] Support regulation domain setting from NVRAM and supplicant -+ * 1. Country code is from NVRAM or supplicant -+ * 2. Change band definition in CMD/EVENT. -+ * -+ * 10 18 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check -+ * [WCXRP00000086] [MT6620 Wi-Fi][Driver] The mac address is all zero at android -+ * complete implementation of Android NVRAM access -+ * -+ * 10 08 2010 cp.wu -+ * [WCXRP00000084] [MT6620 Wi-Fi][Driver][FW] Add fixed rate support for distance test -+ * adding fixed rate support for distance test. (from registry setting) -+ * -+ * 09 23 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check -+ * add skeleton for NVRAM integration -+ * -+ * 09 08 2010 cp.wu -+ * NULL -+ * use static memory pool for storing IEs of scanning result. -+ * -+ * 09 03 2010 kevin.huang -+ * NULL -+ * Refine #include sequence and solve recursive/nested #include issue -+ * -+ * 08 29 2010 yuche.tsai -+ * NULL -+ * Finish SLT TX/RX & Rate Changing Support. -+ * -+ * 08 04 2010 cp.wu -+ * NULL -+ * revert changelist #15371, efuse read/write access will be done by RF test approach -+ * -+ * 08 04 2010 cp.wu -+ * NULL -+ * add OID definitions for EFUSE read/write access. -+ * -+ * 08 04 2010 yarco.yang -+ * NULL -+ * Add TX_AMPDU and ADDBA_REJECT command -+ * -+ * 08 02 2010 george.huang -+ * NULL -+ * add WMM-PS test related OID/ CMD handlers -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 22 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) add command warpper for STA-REC/BSS-INFO sync. -+ * 2) enhance command packet sending procedure for non-oid part -+ * 3) add command packet definitions for STA-REC/BSS-INFO sync. -+ * -+ * 06 18 2010 wh.su -+ * [WPD00003840][MT6620 5931] Security migration -+ * migration from MT6620 firmware. -+ * -+ * 06 07 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * merge wlan_def.h. -+ * -+ * 06 07 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * merge wifi_var.h, precomp.h, cnm_timer.h (data type only) -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 06 03 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * move timer callback to glue layer. -+ * -+ * 05 20 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) integrate OID_GEN_NETWORK_LAYER_ADDRESSES with CMD_ID_SET_IP_ADDRESS -+ * 2) buffer statistics data for 2 seconds -+ * 3) use default value for adhoc parameters instead of 0 -+ * -+ * 05 18 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * implement Wakeup-on-LAN except firmware integration part -+ * -+ * 05 17 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * MT6620 is not supporting NDIS_PACKET_TYPE_PROMISCUOUS. -+ * -+ -+ * -+ * 05 17 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * 1) add timeout handler mechanism for pending command packets -+ * 2) add p2p add/removal key -+ * -+ * 05 13 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * add NULL OID implementation for WOL-related OIDs. -+ * -+ * 04 22 2010 cp.wu -+ * [WPD00003830]add OID_802_11_PRIVACY_FILTER support -+ * enable RX filter OID -+ * -+ * 04 14 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * information buffer for query oid/ioctl is now buffered in prCmdInfo -+ * * * * * instead of glue-layer variable to improve multiple oid/ioctl capability -+ * -+ * 03 31 2010 wh.su -+ * [WPD00003816][MT6620 Wi-Fi] Adding the security support -+ * modify the wapi related code for new driver's design. -+ * -+ * 03 26 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * indicate media stream mode after set is done -+ * -+ * 03 24 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * initial import for Linux port -+ * -+ * 03 03 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * implement custom OID: EEPROM read/write access -+ * -+ * 02 09 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1. Permanent and current MAC address are now retrieved by CMD/EVENT packets instead of hard-coded address -+ * * * * * * 2. follow MSDN defined behavior when associates to another AP -+ * * * * * * 3. for firmware download, packet size could be up to 2048 bytes -+ * -+ * 01 27 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) implement timeout mechanism when OID is pending for longer than 1 second -+ * * * 2) allow OID_802_11_CONFIGURATION to be executed when RF test mode is turned on -+ * -+ * 01 27 2010 wh.su -+ * [WPD00003816][MT6620 Wi-Fi] Adding the security support -+ * . -+ * -+ * 01 22 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * implement following 802.11 OIDs: -+ * * * * OID_802_11_RSSI, -+ * * * * OID_802_11_RSSI_TRIGGER, -+ * * * * OID_802_11_STATISTICS, -+ * * * * OID_802_11_DISASSOCIATE, -+ * * * * OID_802_11_POWER_MODE -+ * -+ * 01 21 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * implement OID_802_11_MEDIA_STREAM_MODE -+ * -+ * 01 21 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * implement OID_802_11_SUPPORTED_RATES / OID_802_11_DESIRED_RATES -+** \main\maintrunk.MT6620WiFiDriver_Prj\6 2009-12-08 11:38:11 GMT mtk02752 -+** add declares for RF test related APIs -+** \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-11-24 22:41:53 GMT mtk02752 -+** remove u4SysTime, MSDN 10-second will be implemented in FW side -+** \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-11-23 20:30:13 GMT mtk02752 -+** add u4SysTime field in PARAM_BSSID_EX_T -+** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-11-12 19:48:35 GMT mtk02752 -+** allow upper layer to set a packet filter with PROMISCUOUS mode -+** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 20:12:12 GMT mtk01426 -+** Init for develop -+** -+*/ -+ -+#ifndef _WLAN_OID_H -+#define _WLAN_OID_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#if DBG -+extern UINT_8 aucDebugModule[DBG_MODULE_NUM]; -+extern UINT_32 u4DebugModule; -+UINT_32 u4DebugModuleTemp; -+#endif /* DBG */ -+extern int sprintf(char *buf, const char *fmt, ...); -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+#define PARAM_MAX_LEN_SSID 32 -+ -+#define PARAM_MAC_ADDR_LEN 6 -+ -+#define ETHERNET_HEADER_SZ 14 -+#define ETHERNET_MIN_PKT_SZ 60 -+#define ETHERNET_MAX_PKT_SZ 1514 -+ -+#define PARAM_MAX_LEN_RATES 8 -+#define PARAM_MAX_LEN_RATES_EX 16 -+ -+#define PARAM_AUTH_REQUEST_REAUTH 0x01 -+#define PARAM_AUTH_REQUEST_KEYUPDATE 0x02 -+#define PARAM_AUTH_REQUEST_PAIRWISE_ERROR 0x06 -+#define PARAM_AUTH_REQUEST_GROUP_ERROR 0x0E -+ -+#define PARAM_EEPROM_READ_METHOD_READ 1 -+#define PARAM_EEPROM_READ_METHOD_GETSIZE 0 -+ -+#define PARAM_WHQL_RSSI_MAX_DBM (-10) -+#define PARAM_WHQL_RSSI_MIN_DBM (-200) -+ -+#define PARAM_DEVICE_WAKE_UP_ENABLE 0x00000001 -+#define PARAM_DEVICE_WAKE_ON_PATTERN_MATCH_ENABLE 0x00000002 -+#define PARAM_DEVICE_WAKE_ON_MAGIC_PACKET_ENABLE 0x00000004 -+ -+#define PARAM_WAKE_UP_MAGIC_PACKET 0x00000001 -+#define PARAM_WAKE_UP_PATTERN_MATCH 0x00000002 -+#define PARAM_WAKE_UP_LINK_CHANGE 0x00000004 -+ -+/* Packet filter bit definitioin (UINT_32 bit-wise definition) */ -+#define PARAM_PACKET_FILTER_DIRECTED 0x00000001 -+#define PARAM_PACKET_FILTER_MULTICAST 0x00000002 -+#define PARAM_PACKET_FILTER_ALL_MULTICAST 0x00000004 -+#define PARAM_PACKET_FILTER_BROADCAST 0x00000008 -+#define PARAM_PACKET_FILTER_PROMISCUOUS 0x00000020 -+#define PARAM_PACKET_FILTER_ALL_LOCAL 0x00000080 -+#if CFG_ENABLE_WIFI_DIRECT_CFG_80211 -+#define PARAM_PACKET_FILTER_P2P_MASK 0xC0000000 -+#define PARAM_PACKET_FILTER_PROBE_REQ 0x80000000 -+#define PARAM_PACKET_FILTER_ACTION_FRAME 0x40000000 -+#endif -+ -+#if CFG_SLT_SUPPORT -+#define PARAM_PACKET_FILTER_SUPPORTED (PARAM_PACKET_FILTER_DIRECTED | \ -+ PARAM_PACKET_FILTER_MULTICAST | \ -+ PARAM_PACKET_FILTER_BROADCAST | \ -+ PARAM_PACKET_FILTER_ALL_MULTICAST) -+#else -+#define PARAM_PACKET_FILTER_SUPPORTED (PARAM_PACKET_FILTER_DIRECTED | \ -+ PARAM_PACKET_FILTER_MULTICAST | \ -+ PARAM_PACKET_FILTER_BROADCAST) -+#endif -+ -+#define PARAM_MEM_DUMP_MAX_SIZE 2048 -+ -+#define BT_PROFILE_PARAM_LEN 8 -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+/*----------------------------------------------------------------------------*/ -+/* Parameters of User Configuration which match to NDIS5.1 */ -+/*----------------------------------------------------------------------------*/ -+/* NDIS_802_11_AUTHENTICATION_MODE */ -+typedef enum _ENUM_PARAM_AUTH_MODE_T { -+ AUTH_MODE_OPEN, /*!< Open system */ -+ AUTH_MODE_SHARED, /*!< Shared key */ -+ AUTH_MODE_AUTO_SWITCH, /*!< Either open system or shared key */ -+ AUTH_MODE_WPA, -+ AUTH_MODE_WPA_PSK, -+ AUTH_MODE_WPA_NONE, /*!< For Ad hoc */ -+ AUTH_MODE_WPA2, -+ AUTH_MODE_WPA2_PSK, -+ AUTH_MODE_NUM /*!< Upper bound, not real case */ -+} ENUM_PARAM_AUTH_MODE_T, *P_ENUM_PARAM_AUTH_MODE_T; -+ -+/* NDIS_802_11_ENCRYPTION_STATUS *//* Encryption types */ -+typedef enum _ENUM_WEP_STATUS_T { -+ ENUM_WEP_ENABLED, -+ ENUM_ENCRYPTION1_ENABLED = ENUM_WEP_ENABLED, -+ ENUM_WEP_DISABLED, -+ ENUM_ENCRYPTION_DISABLED = ENUM_WEP_DISABLED, -+ ENUM_WEP_KEY_ABSENT, -+ ENUM_ENCRYPTION1_KEY_ABSENT = ENUM_WEP_KEY_ABSENT, -+ ENUM_WEP_NOT_SUPPORTED, -+ ENUM_ENCRYPTION_NOT_SUPPORTED = ENUM_WEP_NOT_SUPPORTED, -+ ENUM_ENCRYPTION2_ENABLED, -+ ENUM_ENCRYPTION2_KEY_ABSENT, -+ ENUM_ENCRYPTION3_ENABLED, -+ ENUM_ENCRYPTION3_KEY_ABSENT -+} ENUM_PARAM_ENCRYPTION_STATUS_T, *P_ENUM_PARAM_ENCRYPTION_STATUS_T; -+ -+typedef UINT_8 PARAM_MAC_ADDRESS[PARAM_MAC_ADDR_LEN]; -+ -+typedef UINT_32 PARAM_KEY_INDEX; -+typedef UINT_64 PARAM_KEY_RSC; -+typedef INT_32 PARAM_RSSI; -+ -+typedef UINT_32 PARAM_FRAGMENTATION_THRESHOLD; -+typedef UINT_32 PARAM_RTS_THRESHOLD; -+ -+typedef UINT_8 PARAM_RATES[PARAM_MAX_LEN_RATES]; -+typedef UINT_8 PARAM_RATES_EX[PARAM_MAX_LEN_RATES_EX]; -+ -+typedef enum _ENUM_PARAM_PHY_TYPE_T { -+ PHY_TYPE_802_11ABG = 0, /*!< Can associated with 802.11abg AP, -+ Scan dual band. */ -+ PHY_TYPE_802_11BG, /*!< Can associated with 802_11bg AP, -+ Scan single band and not report 802_11a BSSs. */ -+ PHY_TYPE_802_11G, /*!< Can associated with 802_11g only AP, -+ Scan single band and not report 802_11ab BSSs. */ -+ PHY_TYPE_802_11A, /*!< Can associated with 802_11a only AP, -+ Scan single band and not report 802_11bg BSSs. */ -+ PHY_TYPE_802_11B, /*!< Can associated with 802_11b only AP, -+ Scan single band and not report 802_11ag BSSs. */ -+ PHY_TYPE_NUM /* 5 */ -+} ENUM_PARAM_PHY_TYPE_T, *P_ENUM_PARAM_PHY_TYPE_T; -+ -+typedef enum _ENUM_PARAM_OP_MODE_T { -+ NET_TYPE_IBSS = 0, /*!< Try to merge/establish an AdHoc, do periodic SCAN for merging. */ -+ NET_TYPE_INFRA, /*!< Try to join an Infrastructure, do periodic SCAN for joining. */ -+ NET_TYPE_AUTO_SWITCH, /*!< Try to join an Infrastructure, if fail then try to merge or -+ establish an AdHoc, do periodic SCAN for joining or merging. */ -+ NET_TYPE_DEDICATED_IBSS, /*!< Try to merge an AdHoc first, -+ if fail then establish AdHoc permanently, no more SCAN. */ -+ NET_TYPE_NUM /* 4 */ -+} ENUM_PARAM_OP_MODE_T, *P_ENUM_PARAM_OP_MODE_T; -+ -+typedef struct _PARAM_SSID_T { -+ UINT_32 u4SsidLen; /*!< SSID length in bytes. Zero length is broadcast(any) SSID */ -+ UINT_8 aucSsid[PARAM_MAX_LEN_SSID]; -+ UINT_32 u4CenterFreq; -+} PARAM_SSID_T, *P_PARAM_SSID_T; -+ -+typedef struct _PARAM_CONNECT_T { -+ UINT_32 u4SsidLen; /*!< SSID length in bytes. Zero length is broadcast(any) SSID */ -+ UINT_8 *pucSsid; -+ UINT_8 *pucBssid; -+ UINT_32 u4CenterFreq; -+} PARAM_CONNECT_T, *P_PARAM_CONNECT_T; -+ -+/* This is enum defined for user to select an AdHoc Mode */ -+typedef enum _ENUM_PARAM_AD_HOC_MODE_T { -+ AD_HOC_MODE_11B = 0, /*!< Create 11b IBSS if we support 802.11abg/802.11bg. */ -+ AD_HOC_MODE_MIXED_11BG, /*!< Create 11bg mixed IBSS if we support 802.11abg/802.11bg/802.11g. */ -+ AD_HOC_MODE_11G, /*!< Create 11g only IBSS if we support 802.11abg/802.11bg/802.11g. */ -+ AD_HOC_MODE_11A, /*!< Create 11a only IBSS if we support 802.11abg. */ -+ AD_HOC_MODE_NUM /* 4 */ -+} ENUM_PARAM_AD_HOC_MODE_T, *P_ENUM_PARAM_AD_HOC_MODE_T; -+ -+typedef enum _ENUM_PARAM_MEDIA_STATE_T { -+ PARAM_MEDIA_STATE_CONNECTED, -+ PARAM_MEDIA_STATE_DISCONNECTED, -+ PARAM_MEDIA_STATE_TO_BE_INDICATED /* for following MSDN re-association behavior */ -+} ENUM_PARAM_MEDIA_STATE_T, *P_ENUM_PARAM_MEDIA_STATE_T; -+ -+typedef enum _ENUM_PARAM_NETWORK_TYPE_T { -+ PARAM_NETWORK_TYPE_FH, -+ PARAM_NETWORK_TYPE_DS, -+ PARAM_NETWORK_TYPE_OFDM5, -+ PARAM_NETWORK_TYPE_OFDM24, -+ PARAM_NETWORK_TYPE_AUTOMODE, -+ PARAM_NETWORK_TYPE_NUM /*!< Upper bound, not real case */ -+} ENUM_PARAM_NETWORK_TYPE_T, *P_ENUM_PARAM_NETWORK_TYPE_T; -+ -+typedef struct _PARAM_NETWORK_TYPE_LIST { -+ UINT_32 NumberOfItems; /*!< At least 1 */ -+ ENUM_PARAM_NETWORK_TYPE_T eNetworkType[1]; -+} PARAM_NETWORK_TYPE_LIST, *PPARAM_NETWORK_TYPE_LIST; -+ -+typedef enum _ENUM_PARAM_PRIVACY_FILTER_T { -+ PRIVACY_FILTER_ACCEPT_ALL, -+ PRIVACY_FILTER_8021xWEP, -+ PRIVACY_FILTER_NUM -+} ENUM_PARAM_PRIVACY_FILTER_T, *P_ENUM_PARAM_PRIVACY_FILTER_T; -+ -+typedef enum _ENUM_RELOAD_DEFAULTS { -+ ENUM_RELOAD_WEP_KEYS -+} PARAM_RELOAD_DEFAULTS, *P_PARAM_RELOAD_DEFAULTS; -+ -+typedef struct _PARAM_PM_PACKET_PATTERN { -+ UINT_32 Priority; /* Importance of the given pattern. */ -+ UINT_32 Reserved; /* Context information for transports. */ -+ UINT_32 MaskSize; /* Size in bytes of the pattern mask. */ -+ UINT_32 PatternOffset; /* Offset from beginning of this */ -+ /* structure to the pattern bytes. */ -+ UINT_32 PatternSize; /* Size in bytes of the pattern. */ -+ UINT_32 PatternFlags; /* Flags (TBD). */ -+} PARAM_PM_PACKET_PATTERN, *P_PARAM_PM_PACKET_PATTERN; -+ -+/*--------------------------------------------------------------*/ -+/*! \brief Struct definition to indicate specific event. */ -+/*--------------------------------------------------------------*/ -+typedef enum _ENUM_STATUS_TYPE_T { -+ ENUM_STATUS_TYPE_AUTHENTICATION, -+ ENUM_STATUS_TYPE_MEDIA_STREAM_MODE, -+ ENUM_STATUS_TYPE_CANDIDATE_LIST, -+ ENUM_STATUS_TYPE_NUM /*!< Upper bound, not real case */ -+} ENUM_STATUS_TYPE_T, *P_ENUM_STATUS_TYPE_T; -+ -+typedef struct _PARAM_802_11_CONFIG_FH_T { -+ UINT_32 u4Length; /*!< Length of structure */ -+ UINT_32 u4HopPattern; /*!< Defined as 802.11 */ -+ UINT_32 u4HopSet; /*!< to one if non-802.11 */ -+ UINT_32 u4DwellTime; /*!< In unit of Kusec */ -+} PARAM_802_11_CONFIG_FH_T, *P_PARAM_802_11_CONFIG_FH_T; -+ -+typedef struct _PARAM_802_11_CONFIG_T { -+ UINT_32 u4Length; /*!< Length of structure */ -+ UINT_32 u4BeaconPeriod; /*!< In unit of Kusec */ -+ UINT_32 u4ATIMWindow; /*!< In unit of Kusec */ -+ UINT_32 u4DSConfig; /*!< Channel frequency in unit of kHz */ -+ PARAM_802_11_CONFIG_FH_T rFHConfig; -+} PARAM_802_11_CONFIG_T, *P_PARAM_802_11_CONFIG_T; -+ -+typedef struct _PARAM_STATUS_INDICATION_T { -+ ENUM_STATUS_TYPE_T eStatusType; -+} PARAM_STATUS_INDICATION_T, *P_PARAM_STATUS_INDICATION_T; -+ -+typedef struct _PARAM_AUTH_REQUEST_T { -+ UINT_32 u4Length; /*!< Length of this struct */ -+ PARAM_MAC_ADDRESS arBssid; -+ UINT_32 u4Flags; /*!< Definitions are as follows */ -+} PARAM_AUTH_REQUEST_T, *P_PARAM_AUTH_REQUEST_T; -+ -+typedef struct _PARAM_AUTH_EVENT_T { -+ PARAM_STATUS_INDICATION_T rStatus; -+ PARAM_AUTH_REQUEST_T arRequest[1]; -+} PARAM_AUTH_EVENT_T, *P_PARAM_AUTH_EVENT_T; -+ -+/*! \brief Capabilities, privacy, rssi and IEs of each BSSID */ -+typedef struct _PARAM_BSSID_EX_T { -+ UINT_32 u4Length; /*!< Length of structure */ -+ PARAM_MAC_ADDRESS arMacAddress; /*!< BSSID */ -+ UINT_8 Reserved[2]; -+ PARAM_SSID_T rSsid; /*!< SSID */ -+ UINT_32 u4Privacy; /*!< Need WEP encryption */ -+ PARAM_RSSI rRssi; /*!< in dBm */ -+ ENUM_PARAM_NETWORK_TYPE_T eNetworkTypeInUse; -+ PARAM_802_11_CONFIG_T rConfiguration; -+ ENUM_PARAM_OP_MODE_T eOpMode; -+ PARAM_RATES_EX rSupportedRates; -+ UINT_32 u4IELength; -+ UINT_8 aucIEs[1]; -+} PARAM_BSSID_EX_T, *P_PARAM_BSSID_EX_T; -+ -+typedef struct _PARAM_BSSID_LIST_EX { -+ UINT_32 u4NumberOfItems; /*!< at least 1 */ -+ PARAM_BSSID_EX_T arBssid[1]; -+} PARAM_BSSID_LIST_EX_T, *P_PARAM_BSSID_LIST_EX_T; -+ -+typedef struct _PARAM_WEP_T { -+ UINT_32 u4Length; /*!< Length of structure */ -+ UINT_32 u4KeyIndex; /*!< 0: pairwise key, others group keys */ -+ UINT_32 u4KeyLength; /*!< Key length in bytes */ -+ UINT_8 aucKeyMaterial[32]; /*!< Key content by above setting */ -+} PARAM_WEP_T, *P_PARAM_WEP_T; -+ -+/*! \brief Key mapping of BSSID */ -+typedef struct _PARAM_KEY_T { -+ UINT_32 u4Length; /*!< Length of structure */ -+ UINT_32 u4KeyIndex; /*!< KeyID */ -+ UINT_32 u4KeyLength; /*!< Key length in bytes */ -+ PARAM_MAC_ADDRESS arBSSID; /*!< MAC address */ -+ PARAM_KEY_RSC rKeyRSC; -+ UINT_8 aucKeyMaterial[32]; /*!< Key content by above setting */ -+} PARAM_KEY_T, *P_PARAM_KEY_T; -+ -+typedef struct _PARAM_REMOVE_KEY_T { -+ UINT_32 u4Length; /*!< Length of structure */ -+ UINT_32 u4KeyIndex; /*!< KeyID */ -+ PARAM_MAC_ADDRESS arBSSID; /*!< MAC address */ -+} PARAM_REMOVE_KEY_T, *P_PARAM_REMOVE_KEY_T; -+ -+#if CFG_SUPPORT_WAPI -+typedef enum _ENUM_KEY_TYPE { -+ ENUM_WPI_PAIRWISE_KEY = 0, -+ ENUM_WPI_GROUP_KEY -+} ENUM_KEY_TYPE; -+ -+typedef enum _ENUM_WPI_PROTECT_TYPE { -+ ENUM_WPI_NONE, -+ ENUM_WPI_RX, -+ ENUM_WPI_TX, -+ ENUM_WPI_RX_TX -+} ENUM_WPI_PROTECT_TYPE; -+ -+typedef struct _PARAM_WPI_KEY_T { -+ ENUM_KEY_TYPE eKeyType; -+ ENUM_WPI_PROTECT_TYPE eDirection; -+ UINT_8 ucKeyID; -+ UINT_8 aucRsv[3]; -+ UINT_8 aucAddrIndex[12]; -+ UINT_32 u4LenWPIEK; -+ UINT_8 aucWPIEK[256]; -+ UINT_32 u4LenWPICK; -+ UINT_8 aucWPICK[256]; -+ UINT_8 aucPN[16]; -+} PARAM_WPI_KEY_T, *P_PARAM_WPI_KEY_T; -+#endif -+ -+typedef enum _PARAM_POWER_MODE { -+ Param_PowerModeCAM, -+ Param_PowerModeMAX_PSP, -+ Param_PowerModeFast_PSP, -+#if CFG_SUPPORT_DBG_POWERMODE -+ Param_PowerModeKeepActiveOn, /* privilege mode, always active */ -+ Param_PowerModeKeepActiveOff, /* to leave privilege mode */ -+#endif -+ Param_PowerModeMax /* Upper bound, not real case */ -+} PARAM_POWER_MODE, *PPARAM_POWER_MODE; -+ -+typedef enum _PARAM_DEVICE_POWER_STATE { -+ ParamDeviceStateUnspecified = 0, -+ ParamDeviceStateD0, -+ ParamDeviceStateD1, -+ ParamDeviceStateD2, -+ ParamDeviceStateD3, -+ ParamDeviceStateMaximum -+} PARAM_DEVICE_POWER_STATE, *PPARAM_DEVICE_POWER_STATE; -+ -+#if CFG_SUPPORT_802_11D -+ -+/*! \brief The enumeration definitions for OID_IPN_MULTI_DOMAIN_CAPABILITY */ -+typedef enum _PARAM_MULTI_DOMAIN_CAPABILITY { -+ ParamMultiDomainCapDisabled, -+ ParamMultiDomainCapEnabled -+} PARAM_MULTI_DOMAIN_CAPABILITY, *P_PARAM_MULTI_DOMAIN_CAPABILITY; -+#endif -+ -+typedef struct _COUNTRY_STRING_ENTRY { -+ UINT_8 aucCountryCode[2]; -+ UINT_8 aucEnvironmentCode[2]; -+} COUNTRY_STRING_ENTRY, *P_COUNTRY_STRING_ENTRY; -+ -+/* Power management related definition and enumerations */ -+#define UAPSD_NONE 0 -+#define UAPSD_AC0 (BIT(0) | BIT(4)) -+#define UAPSD_AC1 (BIT(1) | BIT(5)) -+#define UAPSD_AC2 (BIT(2) | BIT(6)) -+#define UAPSD_AC3 (BIT(3) | BIT(7)) -+#define UAPSD_ALL (UAPSD_AC0 | UAPSD_AC1 | UAPSD_AC2 | UAPSD_AC3) -+ -+typedef enum _ENUM_POWER_SAVE_PROFILE_T { -+ ENUM_PSP_CONTINUOUS_ACTIVE = 0, -+ ENUM_PSP_CONTINUOUS_POWER_SAVE, -+ ENUM_PSP_FAST_SWITCH, -+ ENUM_PSP_NUM -+} ENUM_POWER_SAVE_PROFILE_T, *PENUM_POWER_SAVE_PROFILE_T; -+ -+/*--------------------------------------------------------------*/ -+/*! \brief Set/Query testing type. */ -+/*--------------------------------------------------------------*/ -+typedef struct _PARAM_802_11_TEST_T { -+ UINT_32 u4Length; -+ UINT_32 u4Type; -+ union { -+ PARAM_AUTH_EVENT_T AuthenticationEvent; -+ PARAM_RSSI RssiTrigger; -+ } u; -+} PARAM_802_11_TEST_T, *P_PARAM_802_11_TEST_T; -+ -+/*--------------------------------------------------------------*/ -+/*! \brief Set/Query authentication and encryption capability. */ -+/*--------------------------------------------------------------*/ -+typedef struct _PARAM_AUTH_ENCRYPTION_T { -+ ENUM_PARAM_AUTH_MODE_T eAuthModeSupported; -+ ENUM_PARAM_ENCRYPTION_STATUS_T eEncryptStatusSupported; -+} PARAM_AUTH_ENCRYPTION_T, *P_PARAM_AUTH_ENCRYPTION_T; -+ -+typedef struct _PARAM_CAPABILITY_T { -+ UINT_32 u4Length; -+ UINT_32 u4Version; -+ UINT_32 u4NoOfPMKIDs; -+ UINT_32 u4NoOfAuthEncryptPairsSupported; -+ PARAM_AUTH_ENCRYPTION_T arAuthenticationEncryptionSupported[1]; -+} PARAM_CAPABILITY_T, *P_PARAM_CAPABILITY_T; -+ -+typedef UINT_8 PARAM_PMKID_VALUE[16]; -+ -+typedef struct _PARAM_BSSID_INFO_T { -+ PARAM_MAC_ADDRESS arBSSID; -+ PARAM_PMKID_VALUE arPMKID; -+} PARAM_BSSID_INFO_T, *P_PARAM_BSSID_INFO_T; -+ -+typedef struct _PARAM_PMKID_T { -+ UINT_32 u4Length; -+ UINT_32 u4BSSIDInfoCount; -+ PARAM_BSSID_INFO_T arBSSIDInfo[1]; -+} PARAM_PMKID_T, *P_PARAM_PMKID_T; -+ -+/*! \brief PMKID candidate lists. */ -+typedef struct _PARAM_PMKID_CANDIDATE_T { -+ PARAM_MAC_ADDRESS arBSSID; -+ UINT_32 u4Flags; -+} PARAM_PMKID_CANDIDATE_T, *P_PARAM_PMKID_CANDIDATE_T; -+ -+/* #ifdef LINUX */ -+typedef struct _PARAM_PMKID_CANDIDATE_LIST_T { -+ UINT_32 u4Version; /*!< Version */ -+ UINT_32 u4NumCandidates; /*!< How many candidates follow */ -+ PARAM_PMKID_CANDIDATE_T arCandidateList[1]; -+} PARAM_PMKID_CANDIDATE_LIST_T, *P_PARAM_PMKID_CANDIDATE_LIST_T; -+/* #endif */ -+ -+typedef struct _PARAM_CUSTOM_MCR_RW_STRUCT_T { -+ UINT_32 u4McrOffset; -+ UINT_32 u4McrData; -+} PARAM_CUSTOM_MCR_RW_STRUCT_T, *P_PARAM_CUSTOM_MCR_RW_STRUCT_T; -+ -+typedef struct _PARAM_CUSTOM_MEM_DUMP_STRUCT_T { -+ UINT_32 u4Address; -+ UINT_32 u4Length; -+ UINT_32 u4RemainLength; -+ UINT_8 ucFragNum; -+} PARAM_CUSTOM_MEM_DUMP_STRUCT_T, *P_PARAM_CUSTOM_MEM_DUMP_STRUCT_T; -+ -+typedef struct _PARAM_CUSTOM_SW_CTRL_STRUCT_T { -+ UINT_32 u4Id; -+ UINT_32 u4Data; -+} PARAM_CUSTOM_SW_CTRL_STRUCT_T, *P_PARAM_CUSTOM_SW_CTRL_STRUCT_T; -+ -+typedef struct _CMD_CHIP_CONFIG_T { -+ UINT_16 u2Id; -+ UINT_8 ucType; -+ UINT_8 ucRespType; -+ UINT_16 u2MsgSize; -+ UINT_8 aucReserved0[2]; -+ UINT_8 aucCmd[CHIP_CONFIG_RESP_SIZE]; -+} CMD_CHIP_CONFIG_T, *P_CMD_CHIP_CONFIG_T; -+ -+typedef struct _PARAM_CUSTOM_CHIP_CONFIG_STRUCT_T { -+ UINT_16 u2Id; -+ UINT_8 ucType; -+ UINT_8 ucRespType; -+ UINT_16 u2MsgSize; -+ UINT_8 aucReserved0[2]; -+ UINT_8 aucCmd[CHIP_CONFIG_RESP_SIZE]; -+} PARAM_CUSTOM_CHIP_CONFIG_STRUCT_T, *P_PARAM_CUSTOM_CHIP_CONFIG_STRUCT_T; -+ -+typedef struct _PARAM_CUSTOM_KEY_CFG_STRUCT_T { -+ UINT_8 aucKey[WLAN_CFG_KEY_LEN_MAX]; -+ UINT_8 aucValue[WLAN_CFG_VALUE_LEN_MAX]; -+} PARAM_CUSTOM_KEY_CFG_STRUCT_T, *P_PARAM_CUSTOM_KEY_CFG_STRUCT_T; -+ -+typedef struct _PARAM_CUSTOM_EEPROM_RW_STRUCT_T { -+ UINT_8 ucEepromMethod; /* For read only read: 1, query size: 0 */ -+ UINT_8 ucEepromIndex; -+ UINT_8 reserved; -+ UINT_16 u2EepromData; -+} PARAM_CUSTOM_EEPROM_RW_STRUCT_T, *P_PARAM_CUSTOM_EEPROM_RW_STRUCT_T, -+PARAM_CUSTOM_NVRAM_RW_STRUCT_T, *P_PARAM_CUSTOM_NVRAM_RW_STRUCT_T; -+ -+typedef struct _PARAM_CUSTOM_WMM_PS_TEST_STRUCT_T { -+ UINT_8 bmfgApsdEnAc; /* b0~3: trigger-en AC0~3. b4~7: delivery-en AC0~3 */ -+ UINT_8 ucIsEnterPsAtOnce; /* enter PS immediately without 5 second guard after connected */ -+ UINT_8 ucIsDisableUcTrigger; /* not to trigger UC on beacon TIM is matched (under U-APSD) */ -+ UINT_8 reserved; -+} PARAM_CUSTOM_WMM_PS_TEST_STRUCT_T, *P_PARAM_CUSTOM_WMM_PS_TEST_STRUCT_T; -+ -+typedef struct _PARAM_CUSTOM_NOA_PARAM_STRUCT_T { -+ UINT_32 u4NoaDurationMs; -+ UINT_32 u4NoaIntervalMs; -+ UINT_32 u4NoaCount; -+} PARAM_CUSTOM_NOA_PARAM_STRUCT_T, *P_PARAM_CUSTOM_NOA_PARAM_STRUCT_T; -+ -+typedef struct _PARAM_CUSTOM_OPPPS_PARAM_STRUCT_T { -+ UINT_32 u4CTwindowMs; -+} PARAM_CUSTOM_OPPPS_PARAM_STRUCT_T, *P_PARAM_CUSTOM_OPPPS_PARAM_STRUCT_T; -+ -+typedef struct _PARAM_CUSTOM_UAPSD_PARAM_STRUCT_T { -+ UINT_8 fgEnAPSD; -+ UINT_8 fgEnAPSD_AcBe; -+ UINT_8 fgEnAPSD_AcBk; -+ UINT_8 fgEnAPSD_AcVo; -+ UINT_8 fgEnAPSD_AcVi; -+ UINT_8 ucMaxSpLen; -+ UINT_8 aucResv[2]; -+} PARAM_CUSTOM_UAPSD_PARAM_STRUCT_T, *P_PARAM_CUSTOM_UAPSD_PARAM_STRUCT_T; -+ -+typedef struct _PARAM_CUSTOM_P2P_SET_STRUCT_T { -+ UINT_32 u4Enable; -+ UINT_32 u4Mode; -+} PARAM_CUSTOM_P2P_SET_STRUCT_T, *P_PARAM_CUSTOM_P2P_SET_STRUCT_T; -+ -+typedef enum _ENUM_CFG_SRC_TYPE_T { -+ CFG_SRC_TYPE_EEPROM, -+ CFG_SRC_TYPE_NVRAM, -+ CFG_SRC_TYPE_UNKNOWN, -+ CFG_SRC_TYPE_NUM -+} ENUM_CFG_SRC_TYPE_T, *P_ENUM_CFG_SRC_TYPE_T; -+ -+typedef enum _ENUM_EEPROM_TYPE_T { -+ EEPROM_TYPE_NO, -+ EEPROM_TYPE_PRESENT, -+ EEPROM_TYPE_NUM -+} ENUM_EEPROM_TYPE_T, *P_ENUM_EEPROM_TYPE_T; -+ -+typedef struct _PARAM_QOS_TSINFO { -+ UINT_8 ucTrafficType; /* Traffic Type: 1 for isochronous 0 for asynchronous */ -+ UINT_8 ucTid; /* TSID: must be between 8 ~ 15 */ -+ UINT_8 ucDirection; /* direction */ -+ UINT_8 ucAccessPolicy; /* access policy */ -+ UINT_8 ucAggregation; /* aggregation */ -+ UINT_8 ucApsd; /* APSD */ -+ UINT_8 ucuserPriority; /* user priority */ -+ UINT_8 ucTsInfoAckPolicy; /* TSINFO ACK policy */ -+ UINT_8 ucSchedule; /* Schedule */ -+} PARAM_QOS_TSINFO, *P_PARAM_QOS_TSINFO; -+ -+typedef struct _PARAM_QOS_TSPEC { -+ PARAM_QOS_TSINFO rTsInfo; /* TS info field */ -+ UINT_16 u2NominalMSDUSize; /* nominal MSDU size */ -+ UINT_16 u2MaxMSDUsize; /* maximum MSDU size */ -+ UINT_32 u4MinSvcIntv; /* minimum service interval */ -+ UINT_32 u4MaxSvcIntv; /* maximum service interval */ -+ UINT_32 u4InactIntv; /* inactivity interval */ -+ UINT_32 u4SpsIntv; /* suspension interval */ -+ UINT_32 u4SvcStartTime; /* service start time */ -+ UINT_32 u4MinDataRate; /* minimum Data rate */ -+ UINT_32 u4MeanDataRate; /* mean data rate */ -+ UINT_32 u4PeakDataRate; /* peak data rate */ -+ UINT_32 u4MaxBurstSize; /* maximum burst size */ -+ UINT_32 u4DelayBound; /* delay bound */ -+ UINT_32 u4MinPHYRate; /* minimum PHY rate */ -+ UINT_16 u2Sba; /* surplus bandwidth allowance */ -+ UINT_16 u2MediumTime; /* medium time */ -+} PARAM_QOS_TSPEC, *P_PARAM_QOS_TSPEC; -+ -+typedef struct _PARAM_QOS_ADDTS_REQ_INFO { -+ PARAM_QOS_TSPEC rTspec; -+} PARAM_QOS_ADDTS_REQ_INFO, *P_PARAM_QOS_ADDTS_REQ_INFO; -+ -+typedef struct _PARAM_VOIP_CONFIG { -+ UINT_32 u4VoipTrafficInterval; /* 0: disable VOIP configuration */ -+} PARAM_VOIP_CONFIG, *P_PARAM_VOIP_CONFIG; -+ -+/*802.11 Statistics Struct*/ -+typedef struct _PARAM_802_11_STATISTICS_STRUCT_T { -+ UINT_32 u4Length; /* Length of structure */ -+ LARGE_INTEGER rTransmittedFragmentCount; -+ LARGE_INTEGER rMulticastTransmittedFrameCount; -+ LARGE_INTEGER rFailedCount; -+ LARGE_INTEGER rRetryCount; -+ LARGE_INTEGER rMultipleRetryCount; -+ LARGE_INTEGER rRTSSuccessCount; -+ LARGE_INTEGER rRTSFailureCount; -+ LARGE_INTEGER rACKFailureCount; -+ LARGE_INTEGER rFrameDuplicateCount; -+ LARGE_INTEGER rReceivedFragmentCount; -+ LARGE_INTEGER rMulticastReceivedFrameCount; -+ LARGE_INTEGER rFCSErrorCount; -+ LARGE_INTEGER rTKIPLocalMICFailures; -+ LARGE_INTEGER rTKIPICVErrors; -+ LARGE_INTEGER rTKIPCounterMeasuresInvoked; -+ LARGE_INTEGER rTKIPReplays; -+ LARGE_INTEGER rCCMPFormatErrors; -+ LARGE_INTEGER rCCMPReplays; -+ LARGE_INTEGER rCCMPDecryptErrors; -+ LARGE_INTEGER rFourWayHandshakeFailures; -+ LARGE_INTEGER rWEPUndecryptableCount; -+ LARGE_INTEGER rWEPICVErrorCount; -+ LARGE_INTEGER rDecryptSuccessCount; -+ LARGE_INTEGER rDecryptFailureCount; -+} PARAM_802_11_STATISTICS_STRUCT_T, *P_PARAM_802_11_STATISTICS_STRUCT_T; -+ -+/* Linux Network Device Statistics Struct */ -+typedef struct _PARAM_LINUX_NETDEV_STATISTICS_T { -+ UINT_32 u4RxPackets; -+ UINT_32 u4TxPackets; -+ UINT_32 u4RxBytes; -+ UINT_32 u4TxBytes; -+ UINT_32 u4RxErrors; -+ UINT_32 u4TxErrors; -+ UINT_32 u4Multicast; -+} PARAM_LINUX_NETDEV_STATISTICS_T, *P_PARAM_LINUX_NETDEV_STATISTICS_T; -+ -+typedef struct _PARAM_MTK_WIFI_TEST_STRUCT_T { -+ UINT_32 u4FuncIndex; -+ UINT_32 u4FuncData; -+} PARAM_MTK_WIFI_TEST_STRUCT_T, *P_PARAM_MTK_WIFI_TEST_STRUCT_T; -+ -+/* 802.11 Media stream constraints */ -+typedef enum _ENUM_MEDIA_STREAM_MODE { -+ ENUM_MEDIA_STREAM_OFF, -+ ENUM_MEDIA_STREAM_ON -+} ENUM_MEDIA_STREAM_MODE, *P_ENUM_MEDIA_STREAM_MODE; -+ -+/* for NDIS 5.1 Media Streaming Change */ -+typedef struct _PARAM_MEDIA_STREAMING_INDICATION { -+ PARAM_STATUS_INDICATION_T rStatus; -+ ENUM_MEDIA_STREAM_MODE eMediaStreamMode; -+} PARAM_MEDIA_STREAMING_INDICATION, *P_PARAM_MEDIA_STREAMING_INDICATION; -+ -+#define PARAM_PROTOCOL_ID_DEFAULT 0x00 -+#define PARAM_PROTOCOL_ID_TCP_IP 0x02 -+#define PARAM_PROTOCOL_ID_IPX 0x06 -+#define PARAM_PROTOCOL_ID_NBF 0x07 -+#define PARAM_PROTOCOL_ID_MAX 0x0F -+#define PARAM_PROTOCOL_ID_MASK 0x0F -+ -+/* for NDIS OID_GEN_NETWORK_LAYER_ADDRESSES */ -+typedef struct _PARAM_NETWORK_ADDRESS_IP { -+ UINT_16 sin_port; -+ UINT_32 in_addr; -+ UINT_8 sin_zero[8]; -+} PARAM_NETWORK_ADDRESS_IP, *P_PARAM_NETWORK_ADDRESS_IP; -+ -+typedef struct _PARAM_NETWORK_ADDRESS { -+ UINT_16 u2AddressLength; /* length in bytes of Address[] in this */ -+ UINT_16 u2AddressType; /* type of this address (PARAM_PROTOCOL_ID_XXX above) */ -+ UINT_8 aucAddress[1]; /* actually AddressLength bytes long */ -+} PARAM_NETWORK_ADDRESS, *P_PARAM_NETWORK_ADDRESS; -+ -+/* The following is used with OID_GEN_NETWORK_LAYER_ADDRESSES to set network layer addresses on an interface */ -+ -+typedef struct _PARAM_NETWORK_ADDRESS_LIST { -+ UINT_32 u4AddressCount; /* number of addresses following */ -+ UINT_16 u2AddressType; /* type of this address (NDIS_PROTOCOL_ID_XXX above) */ -+ PARAM_NETWORK_ADDRESS arAddress[1]; /* actually AddressCount elements long */ -+} PARAM_NETWORK_ADDRESS_LIST, *P_PARAM_NETWORK_ADDRESS_LIST; -+ -+#if CFG_SLT_SUPPORT -+ -+#define FIXED_BW_LG20 0x0000 -+#define FIXED_BW_UL20 0x2000 -+#define FIXED_BW_DL40 0x3000 -+ -+#define FIXED_EXT_CHNL_U20 0x4000 /* For AGG register. */ -+#define FIXED_EXT_CHNL_L20 0xC000 /* For AGG regsiter. */ -+ -+typedef enum _ENUM_MTK_LP_TEST_MODE_T { -+ ENUM_MTK_LP_TEST_NORMAL, -+ ENUM_MTK_LP_TEST_GOLDEN_SAMPLE, -+ ENUM_MTK_LP_TEST_DUT, -+ ENUM_MTK_LP_TEST_MODE_NUM -+} ENUM_MTK_LP_TEST_MODE_T, *P_ENUM_MTK_LP_TEST_MODE_T; -+ -+typedef enum _ENUM_MTK_SLT_FUNC_IDX_T { -+ ENUM_MTK_SLT_FUNC_DO_NOTHING, -+ ENUM_MTK_SLT_FUNC_INITIAL, -+ ENUM_MTK_SLT_FUNC_RATE_SET, -+ ENUM_MTK_SLT_FUNC_LP_SET, -+ ENUM_MTK_SLT_FUNC_NUM -+} ENUM_MTK_SLT_FUNC_IDX_T, *P_ENUM_MTK_SLT_FUNC_IDX_T; -+ -+typedef struct _PARAM_MTK_SLT_LP_TEST_STRUCT_T { -+ ENUM_MTK_LP_TEST_MODE_T rLpTestMode; -+ UINT_32 u4BcnRcvNum; -+} PARAM_MTK_SLT_LP_TEST_STRUCT_T, *P_PARAM_MTK_SLT_LP_TEST_STRUCT_T; -+ -+typedef struct _PARAM_MTK_SLT_TR_TEST_STRUCT_T { -+ ENUM_PARAM_NETWORK_TYPE_T rNetworkType; /* Network Type OFDM5G or OFDM2.4G */ -+ UINT_32 u4FixedRate; /* Fixed Rate including BW */ -+} PARAM_MTK_SLT_TR_TEST_STRUCT_T, *P_PARAM_MTK_SLT_TR_TEST_STRUCT_T; -+ -+typedef struct _PARAM_MTK_SLT_INITIAL_STRUCT_T { -+ UINT_8 aucTargetMacAddr[PARAM_MAC_ADDR_LEN]; -+ UINT_16 u2SiteID; -+} PARAM_MTK_SLT_INITIAL_STRUCT_T, *P_PARAM_MTK_SLT_INITIAL_STRUCT_T; -+ -+typedef struct _PARAM_MTK_SLT_TEST_STRUCT_T { -+ ENUM_MTK_SLT_FUNC_IDX_T rSltFuncIdx; -+ UINT_32 u4Length; /* Length of structure, -+ including myself */ -+ UINT_32 u4FuncInfoLen; /* Include following content -+ field and myself */ -+ union { -+ PARAM_MTK_SLT_INITIAL_STRUCT_T rMtkInitTest; -+ PARAM_MTK_SLT_LP_TEST_STRUCT_T rMtkLpTest; -+ PARAM_MTK_SLT_TR_TEST_STRUCT_T rMtkTRTest; -+ } unFuncInfoContent; -+ -+} PARAM_MTK_SLT_TEST_STRUCT_T, *P_PARAM_MTK_SLT_TEST_STRUCT_T; -+ -+#endif -+ -+/*--------------------------------------------------------------*/ -+/*! \brief For Fixed Rate Configuration (Registry) */ -+/*--------------------------------------------------------------*/ -+typedef enum _ENUM_REGISTRY_FIXED_RATE_T { -+ FIXED_RATE_NONE, -+ FIXED_RATE_1M, -+ FIXED_RATE_2M, -+ FIXED_RATE_5_5M, -+ FIXED_RATE_11M, -+ FIXED_RATE_6M, -+ FIXED_RATE_9M, -+ FIXED_RATE_12M, -+ FIXED_RATE_18M, -+ FIXED_RATE_24M, -+ FIXED_RATE_36M, -+ FIXED_RATE_48M, -+ FIXED_RATE_54M, -+ FIXED_RATE_MCS0_20M_800NS, -+ FIXED_RATE_MCS1_20M_800NS, -+ FIXED_RATE_MCS2_20M_800NS, -+ FIXED_RATE_MCS3_20M_800NS, -+ FIXED_RATE_MCS4_20M_800NS, -+ FIXED_RATE_MCS5_20M_800NS, -+ FIXED_RATE_MCS6_20M_800NS, -+ FIXED_RATE_MCS7_20M_800NS, -+ FIXED_RATE_MCS0_20M_400NS, -+ FIXED_RATE_MCS1_20M_400NS, -+ FIXED_RATE_MCS2_20M_400NS, -+ FIXED_RATE_MCS3_20M_400NS, -+ FIXED_RATE_MCS4_20M_400NS, -+ FIXED_RATE_MCS5_20M_400NS, -+ FIXED_RATE_MCS6_20M_400NS, -+ FIXED_RATE_MCS7_20M_400NS, -+ FIXED_RATE_MCS0_40M_800NS, -+ FIXED_RATE_MCS1_40M_800NS, -+ FIXED_RATE_MCS2_40M_800NS, -+ FIXED_RATE_MCS3_40M_800NS, -+ FIXED_RATE_MCS4_40M_800NS, -+ FIXED_RATE_MCS5_40M_800NS, -+ FIXED_RATE_MCS6_40M_800NS, -+ FIXED_RATE_MCS7_40M_800NS, -+ FIXED_RATE_MCS32_800NS, -+ FIXED_RATE_MCS0_40M_400NS, -+ FIXED_RATE_MCS1_40M_400NS, -+ FIXED_RATE_MCS2_40M_400NS, -+ FIXED_RATE_MCS3_40M_400NS, -+ FIXED_RATE_MCS4_40M_400NS, -+ FIXED_RATE_MCS5_40M_400NS, -+ FIXED_RATE_MCS6_40M_400NS, -+ FIXED_RATE_MCS7_40M_400NS, -+ FIXED_RATE_MCS32_400NS, -+ FIXED_RATE_NUM -+} ENUM_REGISTRY_FIXED_RATE_T, *P_ENUM_REGISTRY_FIXED_RATE_T; -+ -+typedef enum _ENUM_BT_CMD_T { -+ BT_CMD_PROFILE = 0, -+ BT_CMD_UPDATE, -+ BT_CMD_NUM -+} ENUM_BT_CMD_T; -+ -+typedef enum _ENUM_BT_PROFILE_T { -+ BT_PROFILE_CUSTOM = 0, -+ BT_PROFILE_SCO, -+ BT_PROFILE_ACL, -+ BT_PROFILE_MIXED, -+ BT_PROFILE_NO_CONNECTION, -+ BT_PROFILE_NUM -+} ENUM_BT_PROFILE_T; -+ -+typedef struct _PTA_PROFILE_T { -+ ENUM_BT_PROFILE_T eBtProfile; -+ union { -+ UINT_8 aucBTPParams[BT_PROFILE_PARAM_LEN]; -+ /* 0: sco reserved slot time, -+ 1: sco idle slot time, -+ 2: acl throughput, -+ 3: bt tx power, -+ 4: bt rssi -+ 5: VoIP interval -+ 6: BIT(0) Use this field, BIT(1) 0 apply single/ 1 dual PTA setting. -+ */ -+ UINT_32 au4Btcr[4]; -+ } u; -+} PTA_PROFILE_T, *P_PTA_PROFILE_T; -+ -+typedef struct _PTA_IPC_T { -+ UINT_8 ucCmd; -+ UINT_8 ucLen; -+ union { -+ PTA_PROFILE_T rProfile; -+ UINT_8 aucBTPParams[BT_PROFILE_PARAM_LEN]; -+ } u; -+} PARAM_PTA_IPC_T, *P_PARAM_PTA_IPC_T, PTA_IPC_T, *P_PTA_IPC_T; -+ -+/*--------------------------------------------------------------*/ -+/*! \brief CFG80211 Scan Request Container */ -+/*--------------------------------------------------------------*/ -+ -+typedef struct _PARAM_SCAN_REQUEST_EXT_T { -+ PARAM_SSID_T rSsid; -+ UINT_32 u4IELength; -+ PUINT_8 pucIE; -+} PARAM_SCAN_REQUEST_EXT_T, *P_PARAM_SCAN_REQUEST_EXT_T; -+ -+/*--------------------------------------------------------------*/ -+/*! \brief CFG80211 Scheduled Scan Request Container */ -+/*--------------------------------------------------------------*/ -+typedef struct _PARAM_SCHED_SCAN_REQUEST_T { -+ UINT_32 u4SsidNum; -+ PARAM_SSID_T arSsid[CFG_SCAN_SSID_MATCH_MAX_NUM]; -+ UINT_32 u4IELength; -+ PUINT_8 pucIE; -+ UINT_16 u2ScanInterval; /* in milliseconds */ -+} PARAM_SCHED_SCAN_REQUEST, *P_PARAM_SCHED_SCAN_REQUEST; -+ -+#if CFG_SUPPORT_HOTSPOT_2_0 -+typedef struct _PARAM_HS20_SET_BSSID_POOL { -+ BOOLEAN fgIsEnable; -+ UINT_8 ucNumBssidPool; -+ PARAM_MAC_ADDRESS arBSSID[8]; -+} PARAM_HS20_SET_BSSID_POOL, *P_PARAM_HS20_SET_BSSID_POOL; -+ -+#endif -+ -+typedef struct _PARAM_CUSTOM_WFD_DEBUG_STRUCT_T { -+ UINT_8 ucWFDDebugMode; /* 0: Disable -+ 1:Enable but only show inqueue skb ether SN -+ 2.show skb ether SN and the statistics of skb inqueue time */ -+ UINT_16 u2SNPeriod; /* The Ether SN Period */ -+ -+ UINT_8 reserved; -+} PARAM_CUSTOM_WFD_DEBUG_STRUCT_T, *P_PARAM_CUSTOM_WFD_DEBUG_STRUCT_T; -+ -+typedef struct _CMD_GET_PSCAN_CAPABILITY { -+/* TBD */ -+} CMD_GET_GSCAN_CAPABILITY, *P_CMD_GET_GSCAN_CAPABILITY; -+ -+typedef struct _CMD_SET_PSCAN_ENABLE { -+ UINT_8 ucPscanAct; -+ UINT_8 aucReserved[3]; -+} CMD_SET_PSCAN_ENABLE, *P_CMD_SET_PSCAN_ENABLE; -+ -+typedef enum _ENUM_PSCAN_ACT_T { -+ ENABLE, -+ DISABLE, -+ SUSPEND, -+ CLEAR -+} ENUM_PSCAN_ACT_T, *P_ENUM_PSCAN_ACT_T; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+/*--------------------------------------------------------------*/ -+/* Routines to set parameters or query information. */ -+/*--------------------------------------------------------------*/ -+/***** Routines in wlan_oid.c *****/ -+WLAN_STATUS -+wlanoidQueryNetworkTypesSupported(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryNetworkTypeInUse(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidSetNetworkTypeInUse(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryBssid(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidSetBssidListScan(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidSetBssidListScanExt(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryBssidList(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidSetBssid(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidSetSsid(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidSetConnect(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidQuerySsid(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryInfrastructureMode(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidSetInfrastructureMode(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryAuthMode(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidSetAuthMode(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+#if 0 -+WLAN_STATUS -+wlanoidQueryPrivacyFilter(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidSetPrivacyFilter(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+#endif -+ -+WLAN_STATUS -+wlanoidSetEncryptionStatus(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryEncryptionStatus(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidSetAddWep(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidSetRemoveWep(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+_wlanoidSetAddKey(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, -+ IN UINT_32 u4SetBufferLen, IN BOOLEAN fgIsOid, IN UINT_8 ucAlgorithmId, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidSetAddKey(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidSetRemoveKey(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidSetReloadDefaults(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidSetTest(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryCapability(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryFrequency(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidSetFrequency(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryAtimWindow(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidSetAtimWindow(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidSetChannel(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryRssi(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryRssiTrigger(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidSetRssiTrigger(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryRtsThreshold(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidSetRtsThreshold(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidQuery802dot11PowerSaveProfile(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidSet802dot11PowerSaveProfile(IN P_ADAPTER_T prAdapter, -+ IN PVOID prSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryPmkid(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidSetPmkid(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidQuerySupportedRates(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryDesiredRates(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidSetDesiredRates(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryPermanentAddr(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuf, IN UINT_32 u4QueryBufLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryCurrentAddr(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuf, IN UINT_32 u4QueryBufLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryPermanentAddr(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuf, IN UINT_32 u4QueryBufLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryLinkSpeed(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryMcrRead(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryMemDump(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidSetMcrWrite(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidQuerySwCtrlRead(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidSetSwCtrlWrite(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryEepromRead(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidSetEepromWrite(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryRfTestRxStatus(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryRfTestTxStatus(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryOidInterfaceVersion(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryVendorId(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryMulticastList(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidSetMulticastList(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryRcvError(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryRcvNoBuffer(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryRcvCrcError(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryStatistics(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+WLAN_STATUS -+wlanoidQueryStatisticsPL(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+#ifdef LINUX -+ -+WLAN_STATUS -+wlanoidQueryStatisticsForLinux(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+#endif -+ -+WLAN_STATUS -+wlanoidQueryMediaStreamMode(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidSetMediaStreamMode(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryRcvOk(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryXmitOk(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryXmitError(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryXmitOneCollision(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryXmitMoreCollisions(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryXmitMaxCollisions(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidSetCurrentPacketFilter(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryCurrentPacketFilter(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidSetAcpiDevicePowerState(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryAcpiDevicePowerState(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidSetDisassociate(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryFragThreshold(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidSetFragThreshold(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryAdHocMode(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidSetAdHocMode(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryBeaconInterval(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidSetBeaconInterval(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidSetCurrentAddr(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+#if CFG_TCP_IP_CHKSUM_OFFLOAD -+WLAN_STATUS -+wlanoidSetCSUMOffload(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */ -+ -+WLAN_STATUS -+wlanoidSetNetworkAddress(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryMaxFrameSize(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryMaxTotalSize(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidSetCurrentLookahead(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+/* RF Test related APIs */ -+WLAN_STATUS -+wlanoidRftestSetTestMode(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidRftestSetAbortTestMode(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidRftestQueryAutoTest(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidRftestSetAutoTest(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+#if CFG_SUPPORT_WAPI -+WLAN_STATUS -+wlanoidSetWapiMode(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidSetWapiAssocInfo(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidSetWapiKey(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+#endif -+ -+#if CFG_SUPPORT_WPS2 -+WLAN_STATUS -+wlanoidSetWSCAssocInfo(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+#endif -+ -+#if CFG_ENABLE_WAKEUP_ON_LAN -+WLAN_STATUS -+wlanoidSetAddWakeupPattern(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidSetRemoveWakeupPattern(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryEnableWakeup(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 u4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidSetEnableWakeup(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+#endif -+ -+WLAN_STATUS -+wlanoidSetWiFiWmmPsTest(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidSetTxAmpdu(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryBSSInfo(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidSetAddbaReject(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryNvramRead(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidSetNvramWrite(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryCfgSrcType(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryEepromType(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidSetCountryCode(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS wlanSendMemDumpCmd(IN P_ADAPTER_T prAdapter, IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen); -+ -+#if CFG_SLT_SUPPORT -+ -+WLAN_STATUS -+wlanoidQuerySLTStatus(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidUpdateSLTMode(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+#endif -+ -+#if 0 -+WLAN_STATUS -+wlanoidSetNoaParam(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidSetOppPsParam(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidSetUApsdParam(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetBT(IN P_ADAPTER_T prAdapter, IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryBT(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidSetTxPower(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+#if CFG_SUPPORT_BUILD_DATE_CODE -+WLAN_STATUS -+wlanoidQueryBuildDateCode(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+#endif -+ -+/* -+WLAN_STATUS -+wlanoidQueryBtSingleAntenna ( -+ IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, -+ IN UINT_32 u4QueryBufferLen, -+ OUT PUINT_32 pu4QueryInfoLen -+ ); -+ -+WLAN_STATUS -+wlanoidSetBtSingleAntenna ( -+ IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, -+ IN UINT_32 u4SetBufferLen, -+ OUT PUINT_32 pu4SetInfoLen -+ ); -+ -+WLAN_STATUS -+wlanoidSetPta ( -+ IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, -+ IN UINT_32 u4SetBufferLen, -+ OUT PUINT_32 pu4SetInfoLen -+ ); -+ -+WLAN_STATUS -+wlanoidQueryPta ( -+ IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, -+ IN UINT_32 u4QueryBufferLen, -+ OUT PUINT_32 pu4QueryInfoLen -+ ); -+*/ -+ -+#if CFG_ENABLE_WIFI_DIRECT -+WLAN_STATUS -+wlanoidSetP2pMode(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+#endif -+ -+#if CFG_SUPPORT_BATCH_SCAN -+WLAN_STATUS -+wlanoidSetBatchScanReq(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryBatchScanResult(IN P_ADAPTER_T prAdapter, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+#endif -+ -+#if CFG_SUPPORT_HOTSPOT_2_0 -+WLAN_STATUS -+wlanoidSetHS20Info(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidSetInterworkingInfo(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidSetRoamingConsortiumIEInfo(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidSetHS20BssidPool(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+#endif -+ -+WLAN_STATUS -+wlanoidSetRoamingInfo(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidSetWfdDebugMode(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidSetStartSchedScan(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidSetStopSchedScan(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidSetGSCNAction(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidSetGSCNAParam(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidSetGSCNAConfig(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidGetGSCNResult(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidSetTxRateInfo( -+ IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, -+ IN UINT_32 u4SetBufferLen, -+ OUT PUINT_32 pu4SetInfoLen -+ ); -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+WLAN_STATUS -+wlanoidSetChipConfig(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+WLAN_STATUS -+wlanoidNotifyFwSuspend(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, -+ IN UINT_32 u4SetBufferLen, -+ OUT PUINT_32 pu4SetInfoLen); -+ -+#endif /* _WLAN_OID_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/include/wlan_p2p.h b/drivers/misc/mediatek/connectivity/wlan/gen2/include/wlan_p2p.h -new file mode 100644 -index 000000000000..0b558d64034d ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/include/wlan_p2p.h -@@ -0,0 +1,307 @@ -+/* -+** Id: //Department/DaVinci/TRUNK/WiFi_P2P_Driver/include/wlan_p2p.h#3 -+*/ -+ -+/*! \file "wlan_p2p.h" -+ \brief This file contains the declairations of Wi-Fi Direct command -+ processing routines for MediaTek Inc. 802.11 Wireless LAN Adapters. -+*/ -+ -+/* -+** Log: wlan_p2p.h -+ * -+ * 07 17 2012 yuche.tsai -+ * NULL -+ * Compile no error before trial run. -+ * -+ * 11 19 2011 yuche.tsai -+ * NULL -+ * Add RSSI support for P2P network. -+ * -+ * 11 08 2011 yuche.tsai -+ * [WCXRP00001094] [Volunteer Patch][Driver] Driver version & supplicant version -+ * query & set support for service discovery version check. -+ * Add support for driver version query & p2p supplicant verseion set. -+ * For new service discovery mechanism sync. -+ * -+ * 10 18 2011 yuche.tsai -+ * [WCXRP00001045] [WiFi Direct][Driver] Check 2.1 branch. -+ * Support Channel Query. -+ * -+ * 10 18 2011 yuche.tsai -+ * [WCXRP00001045] [WiFi Direct][Driver] Check 2.1 branch. -+ * New 2.1 branch -+ -+ * -+ * 04 27 2011 george.huang -+ * [WCXRP00000684] [MT6620 Wi-Fi][Driver] Support P2P setting ARP filter -+ * Support P2P ARP filter setting on early suspend/ late resume -+ * -+ * 04 08 2011 george.huang -+ * [WCXRP00000621] [MT6620 Wi-Fi][Driver] Support P2P supplicant to set power mode -+ * separate settings of P2P and AIS -+ * -+ * 03 22 2011 george.huang -+ * [WCXRP00000504] [MT6620 Wi-Fi][FW] Support Sigma CAPI for power saving related command -+ * link with supplicant commands -+ * -+ * 03 07 2011 wh.su -+ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code -+ * rename the define to anti_pviracy. -+ * -+ * 03 02 2011 wh.su -+ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code -+ * Add Security check related code. -+ * -+ * 01 05 2011 cp.wu -+ * [WCXRP00000283] [MT6620 Wi-Fi][Driver][Wi-Fi Direct] Implementation of interface -+ * for supporting Wi-Fi Direct Service Discovery -+ * ioctl implementations for P2P Service Discovery -+ * -+ * 12 22 2010 cp.wu -+ * [WCXRP00000283] [MT6620 Wi-Fi][Driver][Wi-Fi Direct] Implementation of interface -+ * for supporting Wi-Fi Direct Service Discovery -+ * 1. header file restructure for more clear module isolation -+ * 2. add function interface definition for implementing Service Discovery callbacks -+ * -+ * 09 21 2010 kevin.huang -+ * [WCXRP00000054] [MT6620 Wi-Fi][Driver] Restructure driver for second Interface -+ * Isolate P2P related function for Hardware Software Bundle -+ * -+ * 08 16 2010 cp.wu -+ * NULL -+ * add subroutines for P2P to set multicast list. -+ * -+ * 08 16 2010 george.huang -+ * NULL -+ * support wlanoidSetP2pPowerSaveProfile() in P2P -+ * -+ * 08 16 2010 george.huang -+ * NULL -+ * Support wlanoidSetNetworkAddress() for P2P -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 05 17 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * MT6620 is not supporting NDIS_PACKET_TYPE_PROMISCUOUS. -+ * -+ -+ * -+** -+*/ -+ -+#ifndef _WLAN_P2P_H -+#define _WLAN_P2P_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+#if CFG_ENABLE_WIFI_DIRECT -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/* Service Discovery */ -+typedef struct _PARAM_P2P_SEND_SD_RESPONSE { -+ PARAM_MAC_ADDRESS rReceiverAddr; -+ UINT_8 fgNeedTxDoneIndication; -+ UINT_8 ucChannelNum; -+ UINT_16 u2PacketLength; -+ UINT_8 aucPacketContent[0]; /*native 802.11 */ -+} PARAM_P2P_SEND_SD_RESPONSE, *P_PARAM_P2P_SEND_SD_RESPONSE; -+ -+typedef struct _PARAM_P2P_GET_SD_REQUEST { -+ PARAM_MAC_ADDRESS rTransmitterAddr; -+ UINT_16 u2PacketLength; -+ UINT_8 aucPacketContent[0]; /*native 802.11 */ -+} PARAM_P2P_GET_SD_REQUEST, *P_PARAM_P2P_GET_SD_REQUEST; -+ -+typedef struct _PARAM_P2P_GET_SD_REQUEST_EX { -+ PARAM_MAC_ADDRESS rTransmitterAddr; -+ UINT_16 u2PacketLength; -+ UINT_8 ucChannelNum; /* Channel Number Where SD Request is received. */ -+ UINT_8 ucSeqNum; /* Get SD Request by sequence number. */ -+ UINT_8 aucPacketContent[0]; /*native 802.11 */ -+} PARAM_P2P_GET_SD_REQUEST_EX, *P_PARAM_P2P_GET_SD_REQUEST_EX; -+ -+typedef struct _PARAM_P2P_SEND_SD_REQUEST { -+ PARAM_MAC_ADDRESS rReceiverAddr; -+ UINT_8 fgNeedTxDoneIndication; -+ UINT_8 ucVersionNum; /* Indicate the Service Discovery Supplicant Version. */ -+ UINT_16 u2PacketLength; -+ UINT_8 aucPacketContent[0]; /*native 802.11 */ -+} PARAM_P2P_SEND_SD_REQUEST, *P_PARAM_P2P_SEND_SD_REQUEST; -+ -+/* Service Discovery 1.0. */ -+typedef struct _PARAM_P2P_GET_SD_RESPONSE { -+ PARAM_MAC_ADDRESS rTransmitterAddr; -+ UINT_16 u2PacketLength; -+ UINT_8 aucPacketContent[0]; /*native 802.11 */ -+} PARAM_P2P_GET_SD_RESPONSE, *P_PARAM_P2P_GET_SD_RESPONSE; -+ -+/* Service Discovery 2.0. */ -+typedef struct _PARAM_P2P_GET_SD_RESPONSE_EX { -+ PARAM_MAC_ADDRESS rTransmitterAddr; -+ UINT_16 u2PacketLength; -+ UINT_8 ucSeqNum; /* Get SD Response by sequence number. */ -+ UINT_8 aucPacketContent[0]; /*native 802.11 */ -+} PARAM_P2P_GET_SD_RESPONSE_EX, *P_PARAM_P2P_GET_SD_RESPONSE_EX; -+ -+typedef struct _PARAM_P2P_TERMINATE_SD_PHASE { -+ PARAM_MAC_ADDRESS rPeerAddr; -+} PARAM_P2P_TERMINATE_SD_PHASE, *P_PARAM_P2P_TERMINATE_SD_PHASE; -+ -+/*! \brief Key mapping of BSSID */ -+typedef struct _P2P_PARAM_KEY_T { -+ UINT_32 u4Length; /*!< Length of structure */ -+ UINT_32 u4KeyIndex; /*!< KeyID */ -+ UINT_32 u4KeyLength; /*!< Key length in bytes */ -+ PARAM_MAC_ADDRESS arBSSID; /*!< MAC address */ -+ PARAM_KEY_RSC rKeyRSC; -+ UINT_8 aucKeyMaterial[32]; /*!< Key content by above setting */ -+} P2P_PARAM_KEY_T, *P_P2P_PARAM_KEY_T; -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/*--------------------------------------------------------------*/ -+/* Routines to handle command */ -+/*--------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSetAddP2PKey(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidSetRemoveP2PKey(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidSetNetworkAddress(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidSetP2PMulticastList(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+/*--------------------------------------------------------------*/ -+/* Service Discovery Subroutines */ -+/*--------------------------------------------------------------*/ -+WLAN_STATUS -+wlanoidSendP2PSDRequest(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidSendP2PSDResponse(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidGetP2PSDRequest(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidGetP2PSDResponse(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 puQueryInfoLen); -+ -+WLAN_STATUS -+wlanoidSetP2PTerminateSDPhase(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+#if CFG_SUPPORT_ANTI_PIRACY -+WLAN_STATUS -+wlanoidSetSecCheckRequest(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidGetSecCheckResponse(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+#endif -+ -+WLAN_STATUS -+wlanoidSetNoaParam(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidSetOppPsParam(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidSetUApsdParam(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryP2pPowerSaveProfile(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidSetP2pPowerSaveProfile(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidSetP2pSetNetworkAddress(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryP2pOpChannel(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidQueryP2pVersion(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+WLAN_STATUS -+wlanoidSetP2pSupplicantVersion(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+WLAN_STATUS -+wlanoidSetP2pWPSmode(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+#if CFG_SUPPORT_P2P_RSSI_QUERY -+WLAN_STATUS -+wlanoidQueryP2pRssi(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+#endif -+ -+/*--------------------------------------------------------------*/ -+/* Callbacks for event indication */ -+/*--------------------------------------------------------------*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif -+#endif /* _WLAN_P2P_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/aaa_fsm.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/aaa_fsm.c -new file mode 100644 -index 000000000000..f2324f13280e ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/aaa_fsm.c -@@ -0,0 +1,1303 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/aaa_fsm.c#2 -+*/ -+ -+/*! \file "aaa_fsm.c" -+ \brief This file defines the FSM for AAA MODULE. -+ -+ This file defines the FSM for AAA MODULE. -+*/ -+ -+/* -+** Log: aaa_fsm.c -+ * -+ * 07 17 2012 yuche.tsai -+ * NULL -+ * Compile no error before trial run. -+ * -+ * 06 13 2012 yuche.tsai -+ * NULL -+ * Update maintrunk driver. -+ * Add support for driver compose assoc request frame. -+ * -+ * 03 02 2012 terry.wu -+ * NULL -+ * Sync CFG80211 modification from branch 2,2. -+ * -+ * 02 22 2012 yuche.tsai -+ * NULL -+ * Solve sigma test 5.1.3 issue, assoc response should have P2P IE. -+ * -+ * 12 02 2011 yuche.tsai -+ * NULL -+ * Resolve inorder issue under AP mode. -+ * -+ * data frame may TX before assoc response frame. -+ * -+ * 11 18 2011 yuche.tsai -+ * NULL -+ * CONFIG P2P support RSSI query, default turned off. -+ * -+ * 06 17 2011 terry.wu -+ * NULL -+ * Add BoW 11N support. -+ * -+ * 06 02 2011 eddie.chen -+ * [WCXRP00000759] [MT6620 Wi-Fi][DRV] Update RCPI in AAA -+ * Update RCPI when receiving Assoc request. -+ * -+ * 04 21 2011 terry.wu -+ * [WCXRP00000674] [MT6620 Wi-Fi][Driver] Refine AAA authSendAuthFrame -+ * Add network type parameter to authSendAuthFrame. -+ * -+ * 04 15 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Add BOW short range mode. -+ * -+ * 04 09 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Change Link connection event procedure and change skb length check to 1512 bytes. -+ * -+ * 03 09 2011 wh.su -+ * [WCXRP00000530] [MT6620 Wi-Fi] [Driver] skip doing p2pRunEventAAAComplete after send assoc response Tx Done -+ * Skip to call p2pRunEventAAAComplete to avoid indicate STA connect twice. -+ * -+ * 03 04 2011 terry.wu -+ * [WCXRP00000515] [MT6620 Wi-Fi][Driver] Surpress compiler warning which is identified by GNU compiler collection -+ * Remove unused variable. -+ * -+ * 02 16 2011 yuche.tsai -+ * [WCXRP00000429] [Volunteer Patch][MT6620][Driver] Hot Spot Client Limit Issue -+ * Add more check after RX assoc frame under Hot-Spot mode. -+ * -+ * 02 09 2011 yuche.tsai -+ * [WCXRP00000429] [Volunteer Patch][MT6620][Driver] Hot Spot Client Limit Issue -+ * Fix Client Limit Issue. -+ * -+ * 01 25 2011 yuche.tsai -+ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record. -+ * Change Station Type in Station Record, Modify MACRO definition for getting station type & network type index & Role. -+ * -+ * 01 15 2011 puff.wen -+ * NULL -+ * [On behalf of Frog] Add CFG_ENABLE_WIFI_DIRECT to p2pRunEventAAAComplete -+ * -+ * 01 14 2011 yuche.tsai -+ * [WCXRP00000352] [Volunteer Patch][MT6620][Driver] P2P Statsion Record Client List Issue -+ * Modify AAA flow according to CM's comment. -+ * -+ * 09 03 2010 kevin.huang -+ * NULL -+ * Refine #include sequence and solve recursive/nested #include issue -+ * -+ * 08 29 2010 yuche.tsai -+ * NULL -+ * Fix Compile warning, type cast from UINT_32 to UINT_16. -+ * -+ * 08 26 2010 yuche.tsai -+ * NULL -+ * In P2P AT GO test mode under WinXP, we would not indicate connected event to host. -+ * -+ * 08 24 2010 cm.chang -+ * NULL -+ * Support RLM initail channel of Ad-hoc, P2P and BOW -+ * -+ * 08 23 2010 chinghwa.yu -+ * NULL -+ * Update for BOW. -+ * -+ * 08 20 2010 kevin.huang -+ * NULL -+ * Modify AAA Module for changing STA STATE 3 at p2p/bowRunEventAAAComplete() -+ * -+ * 08 17 2010 yuche.tsai -+ * NULL -+ * Fix bug while enabling P2P GO. -+ * -+ * 08 16 2010 kevin.huang -+ * NULL -+ * Refine AAA functions -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 21 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * refine TX-DONE callback. -+ * -+ * 06 21 2010 yuche.tsai -+ * [WPD00003839][MT6620 5931][P2P] Feature migration -+ * modify due to P2P functino call prototype change. -+ * -+ * 06 17 2010 yuche.tsai -+ * [WPD00003839][MT6620 5931][P2P] Feature migration -+ * First draft for migration P2P FSM from FW to Driver. -+ * -+ * 04 02 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Modify CFG flags -+ * -+ * 02 26 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * add support of Driver STA_RECORD_T activation -+ * -+ * 02 04 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Add AAA Module Support, Revise Net Type to Net Type Index for array lookup -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "precomp.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+#if 0 -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will send Event to AIS/BOW/P2P -+* -+* @param[in] rJoinStatus To indicate JOIN success or failure. -+* @param[in] prStaRec Pointer to the STA_RECORD_T -+* @param[in] prSwRfb Pointer to the SW_RFB_T -+ -+* @return none -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS aaaFsmSendEventJoinComplete(WLAN_STATUS rJoinStatus, P_STA_RECORD_T prStaRec, P_SW_RFB_T prSwRfb) -+{ -+ P_MSG_SAA_JOIN_COMP_T prJoinCompMsg; -+ -+ ASSERT(prStaRec); -+ -+ prJoinCompMsg = cnmMemAlloc(RAM_TYPE_TCM, sizeof(MSG_SAA_JOIN_COMP_T)); -+ if (!prJoinCompMsg) -+ return WLAN_STATUS_RESOURCES; -+ -+ if (IS_STA_IN_AIS(prStaRec)) -+ prJoinCompMsg->rMsgHdr.eMsgId = MID_SAA_AIS_JOIN_COMPLETE; -+ else if (IS_STA_IN_P2P(prStaRec)) -+ prJoinCompMsg->rMsgHdr.eMsgId = MID_SAA_P2P_JOIN_COMPLETE; -+ else if (IS_STA_IN_BOW(prStaRec)) -+ prJoinCompMsg->rMsgHdr.eMsgId = MID_SAA_BOW_JOIN_COMPLETE; -+ else -+ ASSERT(0); -+ -+ prJoinCompMsg->rJoinStatus = rJoinStatus; -+ prJoinCompMsg->prStaRec = prStaRec; -+ prJoinCompMsg->prSwRfb = prSwRfb; -+ -+ mboxSendMsg(MBOX_ID_0, (P_MSG_HDR_T) prJoinCompMsg, MSG_SEND_METHOD_BUF); -+ -+ return WLAN_STATUS_SUCCESS; -+ -+} /* end of saaFsmSendEventJoinComplete() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will handle the Start Event to AAA FSM. -+* -+* @param[in] prMsgHdr Message of Join Request for a particular STA. -+* -+* @return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID aaaFsmRunEventStart(IN P_MSG_HDR_T prMsgHdr) -+{ -+ P_MSG_SAA_JOIN_REQ_T prJoinReqMsg; -+ P_STA_RECORD_T prStaRec; -+ P_AIS_BSS_INFO_T prAisBssInfo; -+ -+ ASSERT(prMsgHdr); -+ -+ prJoinReqMsg = (P_MSG_SAA_JOIN_REQ_T) prMsgHdr; -+ prStaRec = prJoinReqMsg->prStaRec; -+ -+ ASSERT(prStaRec); -+ -+ DBGLOG(SAA, LOUD, "EVENT-START: Trigger SAA FSM\n"); -+ -+ cnmMemFree(prMsgHdr); -+ -+ /* 4 <1> Validation of SAA Start Event */ -+ if (!IS_AP_STA(prStaRec->eStaType)) { -+ -+ DBGLOG(SAA, ERROR, "EVENT-START: STA Type - %d was not supported.\n", prStaRec->eStaType); -+ -+ /* Ignore the return value because don't care the prSwRfb */ -+ saaFsmSendEventJoinComplete(WLAN_STATUS_FAILURE, prStaRec, NULL); -+ -+ return; -+ } -+ /* 4 <2> The previous JOIN process is not completed ? */ -+ if (prStaRec->eAuthAssocState != AA_STATE_IDLE) { -+ DBGLOG(SAA, ERROR, "EVENT-START: Reentry of SAA Module.\n"); -+ prStaRec->eAuthAssocState = AA_STATE_IDLE; -+ } -+ /* 4 <3> Reset Status Code and Time */ -+ /* Update Station Record - Status/Reason Code */ -+ prStaRec->u2StatusCode = STATUS_CODE_SUCCESSFUL; -+ -+ /* Update the record join time. */ -+ GET_CURRENT_SYSTIME(&prStaRec->rLastJoinTime); -+ -+ prStaRec->ucTxAuthAssocRetryCount = 0; -+ -+ if (prStaRec->prChallengeText) { -+ cnmMemFree(prStaRec->prChallengeText); -+ prStaRec->prChallengeText = (P_IE_CHALLENGE_TEXT_T) NULL; -+ } -+ -+ cnmTimerStopTimer(&prStaRec->rTxReqDoneOrRxRespTimer); -+ -+ prStaRec->ucStaState = STA_STATE_1; -+ -+ /* Trigger SAA MODULE */ -+ saaFsmSteps(prStaRec, SAA_STATE_SEND_AUTH1, (P_SW_RFB_T) NULL); -+ -+} /* end of saaFsmRunEventStart() */ -+#endif -+ -+#if CFG_SUPPORT_AAA -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will process the Rx Auth Request Frame and then -+* trigger AAA FSM. -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* @param[in] prSwRfb Pointer to the SW_RFB_T structure. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID aaaFsmRunEventRxAuth(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb) -+{ -+ P_BSS_INFO_T prBssInfo; -+ P_STA_RECORD_T prStaRec = (P_STA_RECORD_T) NULL; -+ UINT_16 u2StatusCode; -+ BOOLEAN fgReplyAuth = FALSE; -+ ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex; -+ -+ ASSERT(prAdapter); -+ -+ do { -+ -+ /* 4 <1> Check P2P network conditions */ -+#if CFG_ENABLE_WIFI_DIRECT -+ if (prAdapter->fgIsP2PRegistered) { -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); -+ -+ if (prBssInfo->fgIsNetActive) { -+ -+ /* 4 <1.1> Validate Auth Frame by Auth Algorithm/Transation Seq */ -+ if (WLAN_STATUS_SUCCESS == -+ authProcessRxAuth1Frame(prAdapter, -+ prSwRfb, -+ prBssInfo->aucBSSID, -+ AUTH_ALGORITHM_NUM_OPEN_SYSTEM, -+ AUTH_TRANSACTION_SEQ_1, &u2StatusCode)) { -+ -+ if (STATUS_CODE_SUCCESSFUL == u2StatusCode) { -+ /* 4 <1.2> Validate Auth Frame for Network Specific Conditions */ -+ fgReplyAuth = p2pFuncValidateAuth(prAdapter, -+ prSwRfb, &prStaRec, &u2StatusCode); -+ } else { -+ fgReplyAuth = TRUE; -+ } -+ eNetTypeIndex = NETWORK_TYPE_P2P_INDEX; -+ break; -+ } -+ } -+ } -+#endif /* CFG_ENABLE_WIFI_DIRECT */ -+ -+ /* 4 <2> Check BOW network conditions */ -+#if CFG_ENABLE_BT_OVER_WIFI -+ { -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_BOW_INDEX]); -+ -+ if ((prBssInfo->fgIsNetActive) && (OP_MODE_BOW == prBssInfo->eCurrentOPMode)) { -+ -+ /* 4 <2.1> Validate Auth Frame by Auth Algorithm/Transation Seq */ -+ /* Check if for this BSSID */ -+ if (WLAN_STATUS_SUCCESS == -+ authProcessRxAuth1Frame(prAdapter, -+ prSwRfb, -+ prBssInfo->aucBSSID, -+ AUTH_ALGORITHM_NUM_OPEN_SYSTEM, -+ AUTH_TRANSACTION_SEQ_1, &u2StatusCode)) { -+ -+ if (STATUS_CODE_SUCCESSFUL == u2StatusCode) { -+ -+ /* 4 <2.2> Validate Auth Frame for Network Specific Conditions */ -+ fgReplyAuth = -+ bowValidateAuth(prAdapter, prSwRfb, &prStaRec, &u2StatusCode); -+ -+ } else { -+ -+ fgReplyAuth = TRUE; -+ } -+ eNetTypeIndex = NETWORK_TYPE_BOW_INDEX; -+ /* TODO(Kevin): Allocate a STA_RECORD_T for new client */ -+ break; -+ } -+ } -+ } -+#endif /* CFG_ENABLE_BT_OVER_WIFI */ -+ -+ return; -+ } while (FALSE); -+ -+ if (prStaRec) { -+ /* update RCPI */ -+ prStaRec->ucRCPI = prSwRfb->prHifRxHdr->ucRcpi; -+ } -+ /* 4 <3> Update STA_RECORD_T and reply Auth_2(Response to Auth_1) Frame */ -+ if (fgReplyAuth) { -+ -+ if (prStaRec) { -+ -+ if (u2StatusCode == STATUS_CODE_SUCCESSFUL) { -+ if (prStaRec->eAuthAssocState != AA_STATE_IDLE) { -+ DBGLOG(AAA, WARN, "Previous AuthAssocState (%d) != IDLE.\n", -+ prStaRec->eAuthAssocState); -+ } -+ -+ prStaRec->eAuthAssocState = AAA_STATE_SEND_AUTH2; -+ } else { -+ prStaRec->eAuthAssocState = AA_STATE_IDLE; -+ -+ /* NOTE(Kevin): Change to STATE_1 */ -+ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); -+ } -+ -+ /* Update the record join time. */ -+ GET_CURRENT_SYSTIME(&prStaRec->rUpdateTime); -+ -+ /* Update Station Record - Status/Reason Code */ -+ prStaRec->u2StatusCode = u2StatusCode; -+ -+ prStaRec->ucAuthAlgNum = AUTH_ALGORITHM_NUM_OPEN_SYSTEM; -+ } else { -+ /* NOTE(Kevin): We should have STA_RECORD_T if the status code was successful */ -+ ASSERT(!(u2StatusCode == STATUS_CODE_SUCCESSFUL)); -+ } -+ -+ /* NOTE: Ignore the return status for AAA */ -+ /* 4 <4> Reply Auth */ -+ authSendAuthFrame(prAdapter, prStaRec, eNetTypeIndex, prSwRfb, AUTH_TRANSACTION_SEQ_2, u2StatusCode); -+ -+ } -+ -+} /* end of aaaFsmRunEventRxAuth() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will process the Rx (Re)Association Request Frame and then -+* trigger AAA FSM. -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* @param[in] prSwRfb Pointer to the SW_RFB_T structure. -+* -+* @retval WLAN_STATUS_SUCCESS Always return success -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS aaaFsmRunEventRxAssoc(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb) -+{ -+ P_BSS_INFO_T prBssInfo; -+ P_STA_RECORD_T prStaRec = (P_STA_RECORD_T) NULL; -+ UINT_16 u2StatusCode = STATUS_CODE_RESERVED; -+ BOOLEAN fgReplyAssocResp = FALSE; -+ -+ ASSERT(prAdapter); -+ -+ do { -+ -+ /* 4 <1> Check if we have the STA_RECORD_T for incoming Assoc Req */ -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); -+ -+ /* We should have the corresponding Sta Record. */ -+ if ((!prStaRec) || (!prStaRec->fgIsInUse)) { -+ ASSERT(0); /* Only for debug phase */ -+ break; -+ } -+ -+ if (!IS_CLIENT_STA(prStaRec)) -+ break; -+ -+ if (prStaRec->ucStaState == STA_STATE_3) { -+ /* Do Reassocation */ -+ } else if ((prStaRec->ucStaState == STA_STATE_2) && -+ (prStaRec->eAuthAssocState == AAA_STATE_SEND_AUTH2)) { -+ /* Normal case */ -+ } else { -+ DBGLOG(AAA, INFO, "Previous AuthAssocState (%d) != SEND_AUTH2, ucStaState:%d.\n", -+ prStaRec->eAuthAssocState, -+ prStaRec->ucStaState); -+ /* TODO: Why assoc req event is faster than tx done of auth */ -+ if (prStaRec->eAuthAssocState != AAA_STATE_SEND_AUTH2) -+ break; -+ } -+ -+ /* update RCPI */ -+ prStaRec->ucRCPI = prSwRfb->prHifRxHdr->ucRcpi; -+ -+ /* 4 <2> Check P2P network conditions */ -+#if CFG_ENABLE_WIFI_DIRECT -+ if ((prAdapter->fgIsP2PRegistered) && (IS_STA_IN_P2P(prStaRec))) { -+ -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); -+ -+ if (prBssInfo->fgIsNetActive) { -+ -+ /* 4 <2.1> Validate Assoc Req Frame and get Status Code */ -+ /* Check if for this BSSID */ -+ if (WLAN_STATUS_SUCCESS == -+ assocProcessRxAssocReqFrame(prAdapter, prSwRfb, &u2StatusCode)) { -+ -+ if (STATUS_CODE_SUCCESSFUL == u2StatusCode) { -+ /* 4 <2.2> Validate Assoc Req Frame for Network Specific Conditions */ -+ fgReplyAssocResp = p2pFuncValidateAssocReq(prAdapter, -+ prSwRfb, -+ (PUINT_16)&u2StatusCode); -+ } else { -+ fgReplyAssocResp = TRUE; -+ } -+ -+ break; -+ } -+ } -+ } -+#endif /* CFG_ENABLE_WIFI_DIRECT */ -+ -+ /* 4 <3> Check BOW network conditions */ -+#if CFG_ENABLE_BT_OVER_WIFI -+ if (IS_STA_IN_BOW(prStaRec)) { -+ -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_BOW_INDEX]); -+ -+ if ((prBssInfo->fgIsNetActive) && (OP_MODE_BOW == prBssInfo->eCurrentOPMode)) { -+ -+ /* 4 <3.1> Validate Auth Frame by Auth Algorithm/Transation Seq */ -+ /* Check if for this BSSID */ -+ if (WLAN_STATUS_SUCCESS == -+ assocProcessRxAssocReqFrame(prAdapter, prSwRfb, &u2StatusCode)) { -+ -+ if (STATUS_CODE_SUCCESSFUL == u2StatusCode) { -+ -+ /* 4 <3.2> Validate Auth Frame for Network Specific Conditions */ -+ fgReplyAssocResp = -+ bowValidateAssocReq(prAdapter, prSwRfb, &u2StatusCode); -+ -+ } else { -+ -+ fgReplyAssocResp = TRUE; -+ } -+ -+ /* TODO(Kevin): Allocate a STA_RECORD_T for new client */ -+ break; -+ } -+ } -+ } -+#endif /* CFG_ENABLE_BT_OVER_WIFI */ -+ -+ return WLAN_STATUS_SUCCESS; /* To release the SW_RFB_T */ -+ } while (FALSE); -+ -+ /* 4 <4> Update STA_RECORD_T and reply Assoc Resp Frame */ -+ if (fgReplyAssocResp) { -+ UINT_16 u2IELength; -+ PUINT_8 pucIE; -+ -+ if ((((P_WLAN_ASSOC_REQ_FRAME_T) (prSwRfb->pvHeader))->u2FrameCtrl & MASK_FRAME_TYPE) == -+ MAC_FRAME_REASSOC_REQ) { -+ -+ u2IELength = prSwRfb->u2PacketLen - -+ (UINT_16) OFFSET_OF(WLAN_REASSOC_REQ_FRAME_T, aucInfoElem[0]); -+ -+ pucIE = ((P_WLAN_REASSOC_REQ_FRAME_T) (prSwRfb->pvHeader))->aucInfoElem; -+ } else { -+ u2IELength = prSwRfb->u2PacketLen - (UINT_16) OFFSET_OF(WLAN_ASSOC_REQ_FRAME_T, aucInfoElem[0]); -+ -+ pucIE = ((P_WLAN_ASSOC_REQ_FRAME_T) (prSwRfb->pvHeader))->aucInfoElem; -+ } -+ -+ rlmProcessAssocReq(prAdapter, prSwRfb, pucIE, u2IELength); -+ -+ /* 4 <4.1> Assign Association ID */ -+ if (u2StatusCode == STATUS_CODE_SUCCESSFUL) { -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ if ((prAdapter->fgIsP2PRegistered) && (IS_STA_IN_P2P(prStaRec))) { -+ if (p2pRunEventAAAComplete(prAdapter, prStaRec) == WLAN_STATUS_SUCCESS) { -+ prStaRec->u2AssocId = bssAssignAssocID(prStaRec); -+ /* prStaRec->eAuthAssocState = AA_STATE_IDLE; */ -+ prStaRec->eAuthAssocState = AAA_STATE_SEND_ASSOC2;/* NOTE(Kevin): for TX done */ -+ -+ /* NOTE(Kevin): Method A: Change to STATE_3 before handle TX Done */ -+ /* cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_3); */ -+ } else { -+ /* Client List FULL. */ -+ u2StatusCode = STATUS_CODE_REQ_DECLINED; -+ -+ prStaRec->u2AssocId = 0; /* Invalid Association ID */ -+ -+ /* If (Re)association fail, the peer can try Association w/o Auth immediately */ -+ prStaRec->eAuthAssocState = AAA_STATE_SEND_AUTH2; -+ -+ /* NOTE(Kevin): Better to change state here, not at TX Done */ -+ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_2); -+ } -+ } -+#endif -+ -+#if CFG_ENABLE_BT_OVER_WIFI -+ if ((IS_STA_IN_BOW(prStaRec))) { -+ /* if (bowRunEventAAAComplete(prAdapter, prStaRec) == WLAN_STATUS_SUCCESS) { */ -+ prStaRec->u2AssocId = bssAssignAssocID(prStaRec); -+ prStaRec->eAuthAssocState = AAA_STATE_SEND_ASSOC2; /* NOTE(Kevin): for TX done */ -+ -+ /* NOTE(Kevin): Method A: Change to STATE_3 before handle TX Done */ -+ /* cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_3); */ -+ } -+#if 0 -+ else { -+ /* Client List FULL. */ -+ u2StatusCode = STATUS_CODE_REQ_DECLINED; -+ -+ prStaRec->u2AssocId = 0; /* Invalid Association ID */ -+ -+ /* If (Re)association fail, the peer can try Association w/o Auth immediately */ -+ prStaRec->eAuthAssocState = AAA_STATE_SEND_AUTH2; -+ -+ /* NOTE(Kevin): Better to change state here, not at TX Done */ -+ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_2); -+ } -+ } -+#endif -+#endif -+ } else { -+ prStaRec->u2AssocId = 0; /* Invalid Association ID */ -+ -+ /* If (Re)association fail, the peer can try Association w/o Auth immediately */ -+ prStaRec->eAuthAssocState = AAA_STATE_SEND_AUTH2; -+ -+ /* NOTE(Kevin): Better to change state here, not at TX Done */ -+ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_2); -+ } -+ -+ /* Update the record join time. */ -+ GET_CURRENT_SYSTIME(&prStaRec->rUpdateTime); -+ -+ /* Update Station Record - Status/Reason Code */ -+ prStaRec->u2StatusCode = u2StatusCode; -+ -+ /* NOTE: Ignore the return status for AAA */ -+ /* 4 <4.2> Reply Assoc Resp */ -+ assocSendReAssocRespFrame(prAdapter, prStaRec); -+ -+} -+ -+return WLAN_STATUS_SUCCESS; -+ -+} /* end of aaaFsmRunEventRxAssoc() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will handle TxDone(Auth2/AssocReq) Event of AAA FSM. -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* @param[in] prMsduInfo Pointer to the MSDU_INFO_T. -+* @param[in] rTxDoneStatus Return TX status of the Auth1/Auth3/AssocReq frame. -+* -+* @retval WLAN_STATUS_SUCCESS -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+aaaFsmRunEventTxDone(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus) -+{ -+ P_STA_RECORD_T prStaRec; -+ P_BSS_INFO_T prBssInfo; -+ -+ ASSERT(prAdapter); -+ ASSERT(prMsduInfo); -+ -+ DBGLOG(AAA, LOUD, "EVENT-TX DONE: Current Time = %lu\n", (unsigned long)kalGetTimeTick()); -+ -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); -+ -+ if ((!prStaRec) || (!prStaRec->fgIsInUse)) { -+ DBGLOG(AAA, INFO, "EVENT-TX DONE: Invalid StaRec"); -+ return WLAN_STATUS_SUCCESS; /* For the case of replying ERROR STATUS CODE */ -+ } -+ -+ ASSERT(prStaRec->ucNetTypeIndex < NETWORK_TYPE_INDEX_NUM); -+ -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]); -+ DBGLOG(AAA, INFO, "TX DONE status: %d, AuthAssocState: %d, SeqNo: %d\n", -+ rTxDoneStatus, prStaRec->eAuthAssocState, -+ prMsduInfo->ucTxSeqNum); -+ -+ switch (prStaRec->eAuthAssocState) { -+ case AAA_STATE_SEND_AUTH2: -+ { -+ /* Strictly check the outgoing frame is matched with current AA STATE */ -+ if (authCheckTxAuthFrame(prAdapter, prMsduInfo, AUTH_TRANSACTION_SEQ_2) != WLAN_STATUS_SUCCESS) -+ break; -+ -+ if (STATUS_CODE_SUCCESSFUL == prStaRec->u2StatusCode) { -+ if (TX_RESULT_SUCCESS == rTxDoneStatus) { -+ -+ /* NOTE(Kevin): Change to STATE_2 at TX Done */ -+ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_2); -+ } else { -+ -+ prStaRec->eAuthAssocState = AA_STATE_IDLE; -+ -+ /* NOTE(Kevin): Change to STATE_1 */ -+ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ if ((prAdapter->fgIsP2PRegistered) && (IS_STA_IN_P2P(prStaRec))) -+ p2pRunEventAAATxFail(prAdapter, prStaRec); -+#endif /* CFG_ENABLE_WIFI_DIRECT */ -+ -+#if CFG_ENABLE_BT_OVER_WIFI -+ if (IS_STA_IN_BOW(prStaRec)) -+ bowRunEventAAATxFail(prAdapter, prStaRec); -+#endif /* CFG_ENABLE_BT_OVER_WIFI */ -+ } -+ -+ } -+ /* NOTE(Kevin): Ignore the TX Done Event of Auth Frame with Error Status Code */ -+ -+ } -+ break; -+ -+ case AAA_STATE_SEND_ASSOC2: -+ { -+ /* Strictly check the outgoing frame is matched with current SAA STATE */ -+ if (assocCheckTxReAssocRespFrame(prAdapter, prMsduInfo) != WLAN_STATUS_SUCCESS) -+ break; -+ -+ if (STATUS_CODE_SUCCESSFUL == prStaRec->u2StatusCode) { -+ if (TX_RESULT_SUCCESS == rTxDoneStatus) { -+ -+ prStaRec->eAuthAssocState = AA_STATE_IDLE; -+ -+ /* NOTE(Kevin): Change to STATE_3 at TX Done */ -+#if CFG_ENABLE_WIFI_DIRECT -+ if ((prAdapter->fgIsP2PRegistered) && (IS_STA_IN_P2P(prStaRec))) -+ p2pRunEventAAASuccess(prAdapter, prStaRec); -+#endif /* CFG_ENABLE_WIFI_DIRECT */ -+ -+#if CFG_ENABLE_BT_OVER_WIFI -+ -+ if (IS_STA_IN_BOW(prStaRec)) -+ bowRunEventAAAComplete(prAdapter, prStaRec); -+#endif /* CFG_ENABLE_BT_OVER_WIFI */ -+ -+ } else { -+ -+ prStaRec->eAuthAssocState = AAA_STATE_SEND_AUTH2; -+ -+ /* NOTE(Kevin): Change to STATE_2 */ -+ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_2); -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ if ((prAdapter->fgIsP2PRegistered) && (IS_STA_IN_P2P(prStaRec))) -+ p2pRunEventAAATxFail(prAdapter, prStaRec); -+#endif /* CFG_ENABLE_WIFI_DIRECT */ -+ -+#if CFG_ENABLE_BT_OVER_WIFI -+ if (IS_STA_IN_BOW(prStaRec)) -+ bowRunEventAAATxFail(prAdapter, prStaRec); -+#endif /* CFG_ENABLE_BT_OVER_WIFI */ -+ -+ } -+ } -+ /* NOTE(Kevin): Ignore the TX Done Event of Auth Frame with Error Status Code */ -+ } -+ break; -+ -+ default: -+ break; /* Ignore other cases */ -+ } -+ -+ return WLAN_STATUS_SUCCESS; -+ -+} /* end of aaaFsmRunEventTxDone() */ -+#endif /* CFG_SUPPORT_AAA */ -+ -+#if 0 /* TODO(Kevin): for abort event, just reset the STA_RECORD_T. */ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will send ABORT Event to JOIN FSM. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID saaFsmRunEventAbort(IN P_MSG_HDR_T prMsgHdr) -+{ -+ P_JOIN_INFO_T prJoinInfo; -+ P_STA_RECORD_T prStaRec; -+ -+ DEBUGFUNC("joinFsmRunEventAbort"); -+ -+ ASSERT(prAdapter); -+ prJoinInfo = &prAdapter->rJoinInfo; -+ -+ DBGLOG(JOIN, EVENT, "JOIN EVENT: ABORT\n"); -+ -+ /* NOTE(Kevin): when reach here, the ARB_STATE should be in ARB_STATE_JOIN. */ -+ ASSERT(prJoinInfo->prBssDesc); -+ -+ /* 4 <1> Update Flags and Elements of JOIN Module. */ -+ /* Reset Send Auth/(Re)Assoc Frame Count */ -+ prJoinInfo->ucTxAuthAssocRetryCount = 0; -+ -+ /* Cancel all JOIN relative Timer */ -+ ARB_CANCEL_TIMER(prAdapter, prJoinInfo->rTxRequestTimer); -+ -+ ARB_CANCEL_TIMER(prAdapter, prJoinInfo->rRxResponseTimer); -+ -+ ARB_CANCEL_TIMER(prAdapter, prJoinInfo->rJoinTimer); -+ -+ /* 4 <2> Update the associated STA_RECORD_T during JOIN. */ -+ /* Get a Station Record if possible, TA == BSSID for AP */ -+ prStaRec = staRecGetStaRecordByAddr(prAdapter, prJoinInfo->prBssDesc->aucBSSID); -+ if (prStaRec) -+ prStaRec->ucStaState = STA_STATE_1; /* Update Station Record - Class 1 Flag */ -+#if DBG -+ else -+ ASSERT(0); /* Shouldn't happened, because we already add this STA_RECORD_T at JOIN_STATE_INIT */ -+#endif /* DBG */ -+ -+ /* 4 <3> Pull back to IDLE. */ -+ joinFsmSteps(prAdapter, JOIN_STATE_IDLE); -+ -+ /* 4 <4> If we are in Roaming, recover the settings of previous BSS. */ -+ /* NOTE: JOIN FAIL - -+ * Restore original setting from current BSS_INFO_T. -+ */ -+ if (prAdapter->eConnectionState == MEDIA_STATE_CONNECTED) -+ joinAdoptParametersFromCurrentBss(prAdapter); -+ -+} /* end of joinFsmRunEventAbort() */ -+#endif -+ -+/* TODO(Kevin): following code will be modified and move to AIS FSM */ -+#if 0 -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will send Join Timeout Event to JOIN FSM. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* -+* \retval WLAN_STATUS_FAILURE Fail because of Join Timeout -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS joinFsmRunEventJoinTimeOut(IN P_ADAPTER_T prAdapter) -+{ -+ P_JOIN_INFO_T prJoinInfo; -+ P_STA_RECORD_T prStaRec; -+ -+ DEBUGFUNC("joinFsmRunEventJoinTimeOut"); -+ -+ ASSERT(prAdapter); -+ prJoinInfo = &prAdapter->rJoinInfo; -+ -+ DBGLOG(JOIN, EVENT, "JOIN EVENT: JOIN TIMEOUT\n"); -+ -+ /* Get a Station Record if possible, TA == BSSID for AP */ -+ prStaRec = staRecGetStaRecordByAddr(prAdapter, prJoinInfo->prBssDesc->aucBSSID); -+ -+ /* We have renew this Sta Record when in JOIN_STATE_INIT */ -+ ASSERT(prStaRec); -+ -+ /* Record the Status Code of Authentication Request */ -+ prStaRec->u2StatusCode = STATUS_CODE_JOIN_TIMEOUT; -+ -+ /* Increase Failure Count */ -+ prStaRec->ucJoinFailureCount++; -+ -+ /* Reset Send Auth/(Re)Assoc Frame Count */ -+ prJoinInfo->ucTxAuthAssocRetryCount = 0; -+ -+ /* Cancel other JOIN relative Timer */ -+ ARB_CANCEL_TIMER(prAdapter, prJoinInfo->rTxRequestTimer); -+ -+ ARB_CANCEL_TIMER(prAdapter, prJoinInfo->rRxResponseTimer); -+ -+ /* Restore original setting from current BSS_INFO_T */ -+ if (prAdapter->eConnectionState == MEDIA_STATE_CONNECTED) -+ joinAdoptParametersFromCurrentBss(prAdapter); -+ -+ /* Pull back to IDLE */ -+ joinFsmSteps(prAdapter, JOIN_STATE_IDLE); -+ -+ return WLAN_STATUS_FAILURE; -+ -+} /* end of joinFsmRunEventJoinTimeOut() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will adopt the parameters from Peer BSS. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID joinAdoptParametersFromPeerBss(IN P_ADAPTER_T prAdapter) -+{ -+ P_JOIN_INFO_T prJoinInfo; -+ P_BSS_DESC_T prBssDesc; -+ -+ DEBUGFUNC("joinAdoptParametersFromPeerBss"); -+ -+ ASSERT(prAdapter); -+ prJoinInfo = &prAdapter->rJoinInfo; -+ prBssDesc = prJoinInfo->prBssDesc; -+ -+ /* 4 <1> Adopt Peer BSS' PHY TYPE */ -+ prAdapter->eCurrentPhyType = prBssDesc->ePhyType; -+ -+ DBGLOG(JOIN, INFO, "Target BSS[%s]'s PhyType = %s\n", -+ prBssDesc->aucSSID, (prBssDesc->ePhyType == PHY_TYPE_ERP_INDEX) ? "ERP" : "HR_DSSS"); -+ -+ /* 4 <2> Adopt Peer BSS' Frequency(Band/Channel) */ -+ DBGLOG(JOIN, INFO, "Target BSS's Channel = %d, Band = %d\n", prBssDesc->ucChannelNum, prBssDesc->eBand); -+ -+ nicSwitchChannel(prAdapter, prBssDesc->eBand, prBssDesc->ucChannelNum, 10); -+ -+ prJoinInfo->fgIsParameterAdopted = TRUE; -+ -+} /* end of joinAdoptParametersFromPeerBss() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will adopt the parameters from current associated BSS. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID joinAdoptParametersFromCurrentBss(IN P_ADAPTER_T prAdapter) -+{ -+ /* P_JOIN_INFO_T prJoinInfo = &prAdapter->rJoinInfo; */ -+ P_BSS_INFO_T prBssInfo; -+ -+ ASSERT(prAdapter); -+ prBssInfo = &prAdapter->rBssInfo; -+ -+ /* 4 <1> Adopt current BSS' PHY TYPE */ -+ prAdapter->eCurrentPhyType = prBssInfo->ePhyType; -+ -+ /* 4 <2> Adopt current BSS' Frequency(Band/Channel) */ -+ DBGLOG(JOIN, INFO, "Current BSS's Channel = %d, Band = %d\n", prBssInfo->ucChnl, prBssInfo->eBand); -+ -+ nicSwitchChannel(prAdapter, prBssInfo->eBand, prBssInfo->ucChnl, 10); -+ -+} /* end of joinAdoptParametersFromCurrentBss() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will update all the SW variables and HW MCR registers after -+* the association with target BSS. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID joinComplete(IN P_ADAPTER_T prAdapter) -+{ -+ P_JOIN_INFO_T prJoinInfo; -+ P_BSS_DESC_T prBssDesc; -+ P_PEER_BSS_INFO_T prPeerBssInfo; -+ P_BSS_INFO_T prBssInfo; -+ P_CONNECTION_SETTINGS_T prConnSettings; -+ P_STA_RECORD_T prStaRec; -+ P_TX_CTRL_T prTxCtrl; -+#if CFG_SUPPORT_802_11D -+ P_IE_COUNTRY_T prIECountry; -+#endif -+ -+ DEBUGFUNC("joinComplete"); -+ -+ ASSERT(prAdapter); -+ prJoinInfo = &prAdapter->rJoinInfo; -+ prBssDesc = prJoinInfo->prBssDesc; -+ prPeerBssInfo = &prAdapter->rPeerBssInfo; -+ prBssInfo = &prAdapter->rBssInfo; -+ prConnSettings = &prAdapter->rConnSettings; -+ prTxCtrl = &prAdapter->rTxCtrl; -+ -+/* 4 <1> Update Connecting & Connected Flag of BSS_DESC_T. */ -+ /* Remove previous AP's Connection Flags if have */ -+ scanRemoveConnectionFlagOfBssDescByBssid(prAdapter, prBssInfo->aucBSSID); -+ -+ prBssDesc->fgIsConnected = TRUE; /* Mask as Connected */ -+ -+ if (prBssDesc->fgIsHiddenSSID) { -+ /* NOTE(Kevin): This is for the case of Passive Scan and the target BSS didn't -+ * broadcast SSID on its Beacon Frame. -+ */ -+ COPY_SSID(prBssDesc->aucSSID, -+ prBssDesc->ucSSIDLen, prAdapter->rConnSettings.aucSSID, prAdapter->rConnSettings.ucSSIDLen); -+ -+ if (prBssDesc->ucSSIDLen) -+ prBssDesc->fgIsHiddenSSID = FALSE; -+#if DBG -+ else -+ ASSERT(0); -+#endif /* DBG */ -+ -+ DBGLOG(JOIN, INFO, "Hidden SSID! - Update SSID : %s\n", prBssDesc->aucSSID); -+ } -+/* 4 <2> Update BSS_INFO_T from BSS_DESC_T */ -+ /* 4 <2.A> PHY Type */ -+ prBssInfo->ePhyType = prBssDesc->ePhyType; -+ -+ /* 4 <2.B> BSS Type */ -+ prBssInfo->eBSSType = BSS_TYPE_INFRASTRUCTURE; -+ -+ /* 4 <2.C> BSSID */ -+ COPY_MAC_ADDR(prBssInfo->aucBSSID, prBssDesc->aucBSSID); -+ -+ DBGLOG(JOIN, INFO, "JOIN to BSSID: [%pM]\n", prBssDesc->aucBSSID); -+ -+ /* 4 <2.D> SSID */ -+ COPY_SSID(prBssInfo->aucSSID, prBssInfo->ucSSIDLen, prBssDesc->aucSSID, prBssDesc->ucSSIDLen); -+ -+ /* 4 <2.E> Channel / Band information. */ -+ prBssInfo->eBand = prBssDesc->eBand; -+ prBssInfo->ucChnl = prBssDesc->ucChannelNum; -+ -+ /* 4 <2.F> RSN/WPA information. */ -+ secFsmRunEventStart(prAdapter); -+ prBssInfo->u4RsnSelectedPairwiseCipher = prBssDesc->u4RsnSelectedPairwiseCipher; -+ prBssInfo->u4RsnSelectedGroupCipher = prBssDesc->u4RsnSelectedGroupCipher; -+ prBssInfo->u4RsnSelectedAKMSuite = prBssDesc->u4RsnSelectedAKMSuite; -+ -+ if (secRsnKeyHandshakeEnabled()) -+ prBssInfo->fgIsWPAorWPA2Enabled = TRUE; -+ else -+ prBssInfo->fgIsWPAorWPA2Enabled = FALSE; -+ -+ /* 4 <2.G> Beacon interval. */ -+ prBssInfo->u2BeaconInterval = prBssDesc->u2BeaconInterval; -+ -+ /* 4 <2.H> DTIM period. */ -+ prBssInfo->ucDtimPeriod = prBssDesc->ucDTIMPeriod; -+ -+ /* 4 <2.I> ERP Information */ -+ if ((prBssInfo->ePhyType == PHY_TYPE_ERP_INDEX) && /* Our BSS's PHY_TYPE is ERP now. */ -+ (prBssDesc->fgIsERPPresent)) { -+ -+ prBssInfo->fgIsERPPresent = TRUE; -+ prBssInfo->ucERP = prBssDesc->ucERP; /* Save the ERP for later check */ -+ } else { /* Some AP, may send ProbeResp without ERP IE. Thus prBssDesc->fgIsERPPresent is FALSE. */ -+ prBssInfo->fgIsERPPresent = FALSE; -+ prBssInfo->ucERP = 0; -+ } -+ -+#if CFG_SUPPORT_802_11D -+ /* 4 <2.J> Country inforamtion of the associated AP */ -+ if (prConnSettings->fgMultiDomainCapabilityEnabled) { -+ DOMAIN_INFO_ENTRY rDomainInfo; -+ -+ if (domainGetDomainInfoByScanResult(prAdapter, &rDomainInfo)) { -+ if (prBssDesc->prIECountry) { -+ prIECountry = prBssDesc->prIECountry; -+ -+ domainParseCountryInfoElem(prIECountry, &prBssInfo->rDomainInfo); -+ -+ /* use the domain get from the BSS info */ -+ prBssInfo->fgIsCountryInfoPresent = TRUE; -+ nicSetupOpChnlList(prAdapter, prBssInfo->rDomainInfo.u2CountryCode, FALSE); -+ } else { -+ /* use the domain get from the scan result */ -+ prBssInfo->fgIsCountryInfoPresent = TRUE; -+ nicSetupOpChnlList(prAdapter, rDomainInfo.u2CountryCode, FALSE); -+ } -+ } -+ } -+#endif -+ -+ /* 4 <2.K> Signal Power of the associated AP */ -+ prBssInfo->rRcpi = prBssDesc->rRcpi; -+ prBssInfo->rRssi = RCPI_TO_dBm(prBssInfo->rRcpi); -+ GET_CURRENT_SYSTIME(&prBssInfo->rRssiLastUpdateTime); -+ -+ /* 4 <2.L> Capability Field of the associated AP */ -+ prBssInfo->u2CapInfo = prBssDesc->u2CapInfo; -+ -+ DBGLOG(JOIN, INFO, "prBssInfo-> fgIsERPPresent = %d, ucERP = %02x, rRcpi = %d, rRssi = %ld\n", -+ prBssInfo->fgIsERPPresent, prBssInfo->ucERP, prBssInfo->rRcpi, prBssInfo->rRssi); -+ -+/* 4 <3> Update BSS_INFO_T from PEER_BSS_INFO_T & NIC RATE FUNC */ -+ /* 4 <3.A> Association ID */ -+ prBssInfo->u2AssocId = prPeerBssInfo->u2AssocId; -+ -+ /* 4 <3.B> WMM Information */ -+ if (prAdapter->fgIsEnableWMM && (prPeerBssInfo->rWmmInfo.ucWmmFlag & WMM_FLAG_SUPPORT_WMM)) { -+ -+ prBssInfo->fgIsWmmAssoc = TRUE; -+ prTxCtrl->rTxQForVoipAccess = TXQ_AC3; -+ -+ qosWmmInfoInit(&prBssInfo->rWmmInfo, (prBssInfo->ePhyType == PHY_TYPE_HR_DSSS_INDEX) ? TRUE : FALSE); -+ -+ if (prPeerBssInfo->rWmmInfo.ucWmmFlag & WMM_FLAG_AC_PARAM_PRESENT) { -+ kalMemCopy(&prBssInfo->rWmmInfo, &prPeerBssInfo->rWmmInfo, sizeof(WMM_INFO_T)); -+ } else { -+ kalMemCopy(&prBssInfo->rWmmInfo, -+ &prPeerBssInfo->rWmmInfo, -+ sizeof(WMM_INFO_T) - sizeof(prPeerBssInfo->rWmmInfo.arWmmAcParams)); -+ } -+ } else { -+ prBssInfo->fgIsWmmAssoc = FALSE; -+ prTxCtrl->rTxQForVoipAccess = TXQ_AC1; -+ -+ kalMemZero(&prBssInfo->rWmmInfo, sizeof(WMM_INFO_T)); -+ } -+ -+ /* 4 <3.C> Operational Rate Set & BSS Basic Rate Set */ -+ prBssInfo->u2OperationalRateSet = prPeerBssInfo->u2OperationalRateSet; -+ prBssInfo->u2BSSBasicRateSet = prPeerBssInfo->u2BSSBasicRateSet; -+ -+ /* 4 <3.D> Short Preamble */ -+ if (prBssInfo->fgIsERPPresent) { -+ -+ /* NOTE(Kevin 2007/12/24): Truth Table. -+ * Short Preamble Bit in -+ * Final Driver Setting(Short) -+ * TRUE FALSE FALSE FALSE(shouldn't have such case, -+ * use the AssocResp) -+ * TRUE FALSE TRUE FALSE -+ * FALSE FALSE FALSE FALSE(shouldn't have such case, -+ * use the AssocResp) -+ * FALSE FALSE TRUE FALSE -+ * TRUE TRUE FALSE TRUE(follow ERP) -+ * TRUE TRUE TRUE FALSE(follow ERP) -+ * FALSE TRUE FALSE FALSE(shouldn't have such case, -+ * and we should set to FALSE) -+ * FALSE TRUE TRUE FALSE(we should set to FALSE) -+ */ -+ if ((prPeerBssInfo->fgIsShortPreambleAllowed) && -+ ((prConnSettings->ePreambleType == PREAMBLE_TYPE_SHORT) || /* Short Preamble Option Enable is TRUE */ -+ ((prConnSettings->ePreambleType == PREAMBLE_TYPE_AUTO) && -+ (prBssDesc->u2CapInfo & CAP_INFO_SHORT_PREAMBLE)))) { -+ -+ prBssInfo->fgIsShortPreambleAllowed = TRUE; -+ -+ if (prBssInfo->ucERP & ERP_INFO_BARKER_PREAMBLE_MODE) -+ prBssInfo->fgUseShortPreamble = FALSE; -+ else -+ prBssInfo->fgUseShortPreamble = TRUE; -+ } else { -+ prBssInfo->fgIsShortPreambleAllowed = FALSE; -+ prBssInfo->fgUseShortPreamble = FALSE; -+ } -+ } else { -+ /* NOTE(Kevin 2007/12/24): Truth Table. -+ * Short Preamble Bit in -+ * Final Driver Setting(Short) -+ * TRUE FALSE FALSE -+ * FALSE FALSE FALSE -+ * TRUE TRUE TRUE -+ * FALSE TRUE(status success) TRUE -+ * --> Honor the result of prPeerBssInfo. -+ */ -+ -+ prBssInfo->fgIsShortPreambleAllowed = prBssInfo->fgUseShortPreamble = -+ prPeerBssInfo->fgIsShortPreambleAllowed; -+ } -+ -+ DBGLOG(JOIN, INFO, "prBssInfo->fgIsShortPreambleAllowed = %d, prBssInfo->fgUseShortPreamble = %d\n", -+ prBssInfo->fgIsShortPreambleAllowed, prBssInfo->fgUseShortPreamble); -+ -+ /* 4 <3.E> Short Slot Time */ -+ prBssInfo->fgUseShortSlotTime = prPeerBssInfo->fgUseShortSlotTime; /* AP support Short Slot Time */ -+ -+ DBGLOG(JOIN, INFO, "prBssInfo->fgUseShortSlotTime = %d\n", prBssInfo->fgUseShortSlotTime); -+ -+ nicSetSlotTime(prAdapter, -+ prBssInfo->ePhyType, -+ ((prConnSettings->fgIsShortSlotTimeOptionEnable && -+ prBssInfo->fgUseShortSlotTime) ? TRUE : FALSE)); -+ -+ /* 4 <3.F> Update Tx Rate for Control Frame */ -+ bssUpdateTxRateForControlFrame(prAdapter); -+ -+ /* 4 <3.G> Save the available Auth Types during Roaming (Design for Fast BSS Transition). */ -+ /* if (prAdapter->fgIsEnableRoaming) */ /* NOTE(Kevin): Always prepare info for roaming */ -+ { -+ -+ if (prJoinInfo->ucCurrAuthAlgNum == AUTH_ALGORITHM_NUM_OPEN_SYSTEM) -+ prJoinInfo->ucRoamingAuthTypes |= AUTH_TYPE_OPEN_SYSTEM; -+ else if (prJoinInfo->ucCurrAuthAlgNum == AUTH_ALGORITHM_NUM_SHARED_KEY) -+ prJoinInfo->ucRoamingAuthTypes |= AUTH_TYPE_SHARED_KEY; -+ -+ prBssInfo->ucRoamingAuthTypes = prJoinInfo->ucRoamingAuthTypes; -+ -+ /* Set the stable time of the associated BSS. We won't do roaming decision -+ * during the stable time. -+ */ -+ SET_EXPIRATION_TIME(prBssInfo->rRoamingStableExpirationTime, -+ SEC_TO_SYSTIME(ROAMING_STABLE_TIMEOUT_SEC)); -+ } -+ -+ /* 4 <3.H> Update Parameter for TX Fragmentation Threshold */ -+#if CFG_TX_FRAGMENT -+ txFragInfoUpdate(prAdapter); -+#endif /* CFG_TX_FRAGMENT */ -+ -+/* 4 <4> Update STA_RECORD_T */ -+ /* Get a Station Record if possible */ -+ prStaRec = staRecGetStaRecordByAddr(prAdapter, prBssDesc->aucBSSID); -+ -+ if (prStaRec) { -+ UINT_16 u2OperationalRateSet, u2DesiredRateSet; -+ -+ /* 4 <4.A> Desired Rate Set */ -+ u2OperationalRateSet = (rPhyAttributes[prBssInfo->ePhyType].u2SupportedRateSet & -+ prBssInfo->u2OperationalRateSet); -+ -+ u2DesiredRateSet = (u2OperationalRateSet & prConnSettings->u2DesiredRateSet); -+ if (u2DesiredRateSet) { -+ prStaRec->u2DesiredRateSet = u2DesiredRateSet; -+ } else { -+ /* For Error Handling - The Desired Rate Set is not covered in Operational Rate Set. */ -+ prStaRec->u2DesiredRateSet = u2OperationalRateSet; -+ } -+ -+ /* Try to set the best initial rate for this entry */ -+ if (!rateGetBestInitialRateIndex(prStaRec->u2DesiredRateSet, -+ prStaRec->rRcpi, &prStaRec->ucCurrRate1Index)) { -+ -+ if (!rateGetLowestRateIndexFromRateSet(prStaRec->u2DesiredRateSet, &prStaRec->ucCurrRate1Index)) -+ ASSERT(0); -+ } -+ -+ DBGLOG(JOIN, INFO, "prStaRec->ucCurrRate1Index = %d\n", prStaRec->ucCurrRate1Index); -+ -+ /* 4 <4.B> Preamble Mode */ -+ prStaRec->fgIsShortPreambleOptionEnable = prBssInfo->fgUseShortPreamble; -+ -+ /* 4 <4.C> QoS Flag */ -+ prStaRec->fgIsQoS = prBssInfo->fgIsWmmAssoc; -+ } -+#if DBG -+ else -+ ASSERT(0); -+#endif /* DBG */ -+ -+/* 4 <5> Update NIC */ -+ /* 4 <5.A> Update BSSID & Operation Mode */ -+ nicSetupBSS(prAdapter, prBssInfo); -+ -+ /* 4 <5.B> Update WLAN Table. */ -+ if (nicSetHwBySta(prAdapter, prStaRec) == FALSE) -+ ASSERT(FALSE); -+ /* 4 <5.C> Update Desired Rate Set for BT. */ -+#if CFG_TX_FRAGMENT -+ if (prConnSettings->fgIsEnableTxAutoFragmentForBT) -+ txRateSetInitForBT(prAdapter, prStaRec); -+#endif /* CFG_TX_FRAGMENT */ -+ -+ /* 4 <5.D> TX AC Parameter and TX/RX Queue Control */ -+ if (prBssInfo->fgIsWmmAssoc) { -+ -+#if CFG_TX_AGGREGATE_HW_FIFO -+ nicTxAggregateTXQ(prAdapter, FALSE); -+#endif /* CFG_TX_AGGREGATE_HW_FIFO */ -+ -+ qosUpdateWMMParametersAndAssignAllowedACI(prAdapter, &prBssInfo->rWmmInfo); -+ } else { -+ -+#if CFG_TX_AGGREGATE_HW_FIFO -+ nicTxAggregateTXQ(prAdapter, TRUE); -+#endif /* CFG_TX_AGGREGATE_HW_FIFO */ -+ -+ nicTxNonQoSAssignDefaultAdmittedTXQ(prAdapter); -+ -+ nicTxNonQoSUpdateTXQParameters(prAdapter, prBssInfo->ePhyType); -+ } -+ -+#if CFG_TX_STOP_WRITE_TX_FIFO_UNTIL_JOIN -+ { -+ prTxCtrl->fgBlockTxDuringJoin = FALSE; -+ -+#if !CFG_TX_AGGREGATE_HW_FIFO /* TX FIFO AGGREGATE already do flush once */ -+ nicTxFlushStopQueues(prAdapter, (UINT_8) TXQ_DATA_MASK, (UINT_8) NULL); -+#endif /* CFG_TX_AGGREGATE_HW_FIFO */ -+ -+ nicTxRetransmitOfSendWaitQue(prAdapter); -+ -+ if (prTxCtrl->fgIsPacketInOsSendQueue) -+ nicTxRetransmitOfOsSendQue(prAdapter); -+#if CFG_SDIO_TX_ENHANCE -+ halTxLeftClusteredMpdu(prAdapter); -+#endif /* CFG_SDIO_TX_ENHANCE */ -+ -+ } -+#endif /* CFG_TX_STOP_WRITE_TX_FIFO_UNTIL_JOIN */ -+ -+/* 4 <6> Setup CONNECTION flag. */ -+ prAdapter->eConnectionState = MEDIA_STATE_CONNECTED; -+ prAdapter->eConnectionStateIndicated = MEDIA_STATE_CONNECTED; -+ -+ if (prJoinInfo->fgIsReAssoc) -+ prAdapter->fgBypassPortCtrlForRoaming = TRUE; -+ else -+ prAdapter->fgBypassPortCtrlForRoaming = FALSE; -+ -+ kalIndicateStatusAndComplete(prAdapter->prGlueInfo, WLAN_STATUS_MEDIA_CONNECT, (PVOID) NULL, 0); -+ -+} /* end of joinComplete() */ -+#endif -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/ais_fsm.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/ais_fsm.c -new file mode 100644 -index 000000000000..7b5a49a5ba63 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/ais_fsm.c -@@ -0,0 +1,5039 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/ais_fsm.c#1 -+*/ -+ -+/*! \file "aa_fsm.c" -+ \brief This file defines the FSM for SAA and AAA MODULE. -+ -+ This file defines the FSM for SAA and AAA MODULE. -+*/ -+ -+/* -+** Log: ais_fsm.c -+** -+** 09 06 2013 cp.wu -+** always paste SSID information to SAA-FSM -+** -+** 09 06 2013 cp.wu -+** add error handling when reassociation request failed to locate bss descriptor -+** -+** 09 05 2013 cp.wu -+** isolate logic regarding roaming & reassociation -+** -+** 09 04 2013 cp.wu -+** fix typo -+** -+** 09 03 2013 cp.wu -+** add path for reassociation -+ * -+ * 04 20 2012 cp.wu -+ * [WCXRP00000913] [MT6620 Wi-Fi] create repository of source code dedicated for MT6620 E6 ASIC -+ * correct macro -+ * -+ * 01 16 2012 cp.wu -+ * [MT6620 Wi-Fi][Driver] API and behavior modification for preferred band configuration with -+ * corresponding network configuration -+ * add wlanSetPreferBandByNetwork() for glue layer to invoke for setting preferred band configuration -+ * corresponding to network type. -+ * -+ * 11 24 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * Adjust code for DBG and CONFIG_XLOG. -+ * -+ * 11 22 2011 cp.wu -+ * [WCXRP00001120] [MT6620 Wi-Fi][Driver] Modify roaming to AIS state transition from synchronous -+ * to asynchronous approach to avoid incomplete state termination -+ * 1. change RDD related compile option brace position. -+ * 2. when roaming is triggered, ask AIS to transit immediately only when AIS is in Normal TR state -+ * without join timeout timer ticking -+ * 3. otherwise, insert AIS_REQUEST into pending request queue -+ * -+ * 11 11 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * modify the xlog related code. -+ * -+ * 11 04 2011 cp.wu -+ * [WCXRP00001086] [MT6620 Wi-Fi][Driver] On Android, indicate an extra DISCONNECT for REASSOCIATED -+ * cases as an explicit trigger for Android framework -+ * correct reference to BSSID field in Association-Response frame. -+ * -+ * 11 04 2011 cp.wu -+ * [WCXRP00001086] [MT6620 Wi-Fi][Driver] On Android, indicate an extra DISCONNECT for REASSOCIATED -+ * cases as an explicit trigger for Android framework -+ * 1. for DEAUTH/DISASSOC cases, indicate for DISCONNECTION immediately. -+ * 2. (Android only) when reassociation-and-non-roaming cases happened, indicate an extra DISCONNECT -+ * indication to Android Wi-Fi framework -+ * -+ * 11 02 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * adding the code for XLOG. -+ * -+ * 10 26 2011 tsaiyuan.hsu -+ * [WCXRP00001064] [MT6620 Wi-Fi][DRV]] add code with roaming awareness when disconnecting AIS network -+ * be aware roaming when disconnecting AIS network. -+ * -+ * 10 25 2011 cm.chang -+ * [WCXRP00001058] [All Wi-Fi][Driver] Fix sta_rec's phyTypeSet and OBSS scan in AP mode -+ * STA_REC shall be NULL for Beacon's MSDU -+ * -+ * 10 13 2011 cp.wu -+ * [MT6620 Wi-Fi][Driver] Reduce join failure count limit to 2 for faster re-join for other BSS -+ * 1. short join failure count limit to 2 -+ * 2. treat join timeout as kind of join failure as well -+ * -+ * 10 12 2011 wh.su -+ * [WCXRP00001036] [MT6620 Wi-Fi][Driver][FW] Adding the 802.11w code for MFP -+ * adding the 802.11w related function and define . -+ * -+ * 09 30 2011 cm.chang -+ * [WCXRP00001020] [MT6620 Wi-Fi][Driver] Handle secondary channel offset of AP in 5GHz band -+ * . -+ * -+ * 09 20 2011 tsaiyuan.hsu -+ * [WCXRP00000931] [MT5931 Wi-Fi][DRV/FW] add swcr to disable roaming from driver -+ * change window registry of driver for roaming. -+ * -+ * 09 20 2011 cm.chang -+ * [WCXRP00000997] [MT6620 Wi-Fi][Driver][FW] Handle change of BSS preamble type and slot time -+ * Handle client mode about preamble type and slot time -+ * -+ * 09 08 2011 tsaiyuan.hsu -+ * [WCXRP00000972] [MT6620 Wi-Fi][DRV]] check if roaming occurs after join failure to avoid state incosistence. -+ * check if roaming occurs after join failure to avoid deactivation of network. -+ * -+ * 08 24 2011 chinghwa.yu -+ * [WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm -+ * Update RDD test mode cases. -+ * -+ * 08 16 2011 tsaiyuan.hsu -+ * [WCXRP00000931] [MT5931 Wi-Fi][DRV/FW] add swcr to disable roaming from driver -+ * EnableRoaming in registry is deprecated. -+ * -+ * 08 16 2011 tsaiyuan.hsu -+ * [WCXRP00000931] [MT5931 Wi-Fi][DRV/FW] add swcr to disable roaming from driver -+ * use registry to enable or disable roaming. -+ * -+ * 07 07 2011 cp.wu -+ * [WCXRP00000840] [MT6620 Wi-Fi][Driver][AIS] Stop timer for joining when channel is released -+ * due to join failure count exceeding limit -+ * stop timer when joining operation is failed due to try count exceeds limitation -+ * -+ * 06 28 2011 cp.wu -+ * [WCXRP00000815] [MT6620 Wi-Fi][Driver] allow single BSSID with multiple SSID settings to work -+ * around some tricky AP which use space character as hidden SSID -+ * do not handle SCAN request immediately after connected to increase the probability of receiving 1st beacon frame. -+ * -+ * 06 23 2011 cp.wu -+ * [WCXRP00000798] [MT6620 Wi-Fi][Firmware] Follow-ups for WAPI frequency offset workaround in firmware SCN module -+ * change parameter name from PeerAddr to BSSID -+ * -+ * 06 20 2011 cp.wu -+ * [WCXRP00000798] [MT6620 Wi-Fi][Firmware] Follow-ups for WAPI frequency offset workaround in firmware SCN module -+ * 1. specify target's BSSID when requesting channel privilege. -+ * 2. pass BSSID information to firmware domain -+ * -+ * 06 16 2011 cp.wu -+ * [WCXRP00000782] [MT6620 Wi-Fi][AIS] Treat connection at higher priority over scanning to avoid WZC connection timeout -+ * ensure DEAUTH is always sent before establish a new connection -+ * -+ * 06 16 2011 cp.wu -+ * [WCXRP00000782] [MT6620 Wi-Fi][AIS] Treat connection at higher priority over scanning to avoid WZC connection timeout -+ * typo fix: a right brace is missed. -+ * -+ * 06 16 2011 cp.wu -+ * [WCXRP00000782] [MT6620 Wi-Fi][AIS] Treat connection at higher priority over scanning to avoid WZC connection timeout -+ * When RECONNECT request is identified as disconnected, it is necessary to check for pending scan request. -+ * -+ * 06 16 2011 cp.wu -+ * [WCXRP00000757] [MT6620 Wi-Fi][Driver][SCN] take use of RLM API to filter out BSS in disallowed channels -+ * mark fgIsTransition as TRUE for state rolling. -+ * -+ * 06 16 2011 cp.wu -+ * [WCXRP00000782] [MT6620 Wi-Fi][AIS] Treat connection at higher priority over scanning to avoid WZC connection timeout -+ * always check for pending scan after switched into NORMAL_TR state. -+ * -+ * 06 14 2011 cp.wu -+ * [WCXRP00000782] [MT6620 Wi-Fi][AIS] Treat connection at higher priority over scanning to avoid WZC connection timeout -+ * always treat connection request at higher priority over scanning request -+ * -+ * 06 09 2011 tsaiyuan.hsu -+ * [WCXRP00000760] [MT5931 Wi-Fi][FW] Refine rxmHandleMacRxDone to reduce code size -+ * move send_auth at rxmHandleMacRxDone in firmware to driver to reduce code size. -+ * -+ * 06 02 2011 cp.wu -+ * [WCXRP00000681] [MT5931][Firmware] HIF code size reduction -+ * eliminate unused parameters for SAA-FSM -+ * -+ * 05 18 2011 cp.wu -+ * [WCXRP00000732] [MT6620 Wi-Fi][AIS] No need to switch back to IDLE state -+ * when DEAUTH frame is dropped due to bss disconnection -+ * change SCAN handling behavior when followed by a CONNECT/DISCONNECT requests by pending instead of dropping. -+ * -+ * 05 17 2011 cp.wu -+ * [WCXRP00000732] [MT6620 Wi-Fi][AIS] No need to switch back to IDLE state -+ * when DEAUTH frame is dropped due to bss disconnection -+ * when TX DONE status is TX_RESULT_DROPPED_IN_DRIVER, no need to switch back to IDLE state. -+ * -+ * 04 14 2011 cm.chang -+ * [WCXRP00000634] [MT6620 Wi-Fi][Driver][FW] 2nd BSS will not support 40MHz bandwidth for concurrency -+ * . -+ * -+ * 04 13 2011 george.huang -+ * [WCXRP00000628] [MT6620 Wi-Fi][FW][Driver] Modify U-APSD setting to default OFF -+ * remove assert -+ * -+ * 03 18 2011 cp.wu -+ * [WCXRP00000575] [MT6620 Wi-Fi][Driver][AIS] reduce memory usage when generating mailbox message for scan request -+ * when there is no IE needed for probe request, then request a smaller memory for mailbox message -+ * -+ * 03 17 2011 chinglan.wang -+ * [WCXRP00000570] [MT6620 Wi-Fi][Driver] Add Wi-Fi Protected Setup v2.0 feature -+ * . -+ * -+ * 03 17 2011 chinglan.wang -+ * [WCXRP00000570] [MT6620 Wi-Fi][Driver] Add Wi-Fi Protected Setup v2.0 feature -+ * . -+ * -+ * 03 16 2011 tsaiyuan.hsu -+ * [WCXRP00000517] [MT6620 Wi-Fi][Driver][FW] Fine Tune Performance of Roaming -+ * remove obsolete definition and unused variables. -+ * -+ * 03 11 2011 cp.wu -+ * [WCXRP00000535] [MT6620 Wi-Fi][Driver] Fixed channel operation when AIS and Tethering are operating concurrently -+ * When fixed channel operation is necessary, AIS-FSM would scan and only connect for BSS on the specific channel -+ * -+ * 03 09 2011 tsaiyuan.hsu -+ * [WCXRP00000517] [MT6620 Wi-Fi][Driver][FW] Fine Tune Performance of Roaming -+ * avoid clearing fgIsScanReqIssued so as to add scan results. -+ * -+ * 03 07 2011 terry.wu -+ * [WCXRP00000521] [MT6620 Wi-Fi][Driver] Remove non-standard debug message -+ * Toggle non-standard debug messages to comments. -+ * -+ * 03 04 2011 tsaiyuan.hsu -+ * [WCXRP00000517] [MT6620 Wi-Fi][Driver][FW] Fine Tune Performance of Roaming -+ * reset retry conter of attemp to connect to ap after completion of join. -+ * -+ * 03 04 2011 cp.wu -+ * [WCXRP00000515] [MT6620 Wi-Fi][Driver] Surpress compiler warning which is identified by GNU compiler collection -+ * surpress compile warning occurred when compiled by GNU compiler collection. -+ * -+ * 03 02 2011 cp.wu -+ * [WCXRP00000503] [MT6620 Wi-Fi][Driver] Take RCPI brought by association response as initial RSSI right -+ * after connection is built. -+ * use RCPI brought by ASSOC-RESP after connection is built as initial RCPI to avoid using a uninitialized MAC-RX RCPI. -+ * -+ * 02 26 2011 tsaiyuan.hsu -+ * [WCXRP00000391] [MT6620 Wi-Fi][FW] Add Roaming Support -+ * not send disassoc or deauth to leaving AP so as to improve performace of roaming. -+ * -+ * 02 23 2011 cp.wu -+ * [WCXRP00000487] [MT6620 Wi-Fi][Driver][AIS] Serve scan and connect request with a queue-based approach to -+ * improve response time for scanning request -+ * when handling reconnect request, set fgTryScan as TRUE -+ * -+ * 02 22 2011 cp.wu -+ * [WCXRP00000487] [MT6620 Wi-Fi][Driver][AIS] Serve scan and connect request with a queue-based approach -+ * to improve response time for scanning request -+ * handle SCAN and RECONNECT with a FIFO approach. -+ * -+ * 02 09 2011 tsaiyuan.hsu -+ * [WCXRP00000392] [MT6620 Wi-Fi][Driver] Add Roaming Support -+ * Check if prRegInfo is null or not before initializing roaming parameters. -+ * -+ * 02 01 2011 cp.wu -+ * [WCXRP00000416] [MT6620 Wi-Fi][Driver] treat "unable to find BSS" as connection trial -+ * to prevent infinite reconnection trials -+ * treat "unable to find BSS" as connection trial to prevent infinite reconnection trials. -+ * -+ * 01 27 2011 tsaiyuan.hsu -+ * [WCXRP00000392] [MT6620 Wi-Fi][Driver] Add Roaming Support -+ * add roaming fsm -+ * 1. not support 11r, only use strength of signal to determine roaming. -+ * 2. not enable CFG_SUPPORT_ROAMING until completion of full test. -+ * 3. in 6620, adopt work-around to avoid sign extension problem of cck of hw -+ * 4. assume that change of link quality in smooth way. -+ * -+ * 01 26 2011 yuche.tsai -+ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record. -+ * . -+ * -+ * 01 25 2011 yuche.tsai -+ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record. -+ * Fix Compile Error when DBG is disabled. -+ * -+ * 01 25 2011 yuche.tsai -+ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record. -+ * Change Station Type in Station Record, Modify MACRO definition for getting station type & network type index & Role. -+ * -+ * 01 14 2011 cp.wu -+ * [WCXRP00000359] [MT6620 Wi-Fi][Driver] add an extra state to ensure DEAUTH frame is always sent -+ * Add an extra state to guarantee DEAUTH frame is sent then connect to new BSS. -+ * This change is due to WAPI AP needs DEAUTH frame as a necessary step in handshaking protocol. -+ * -+ * 01 11 2011 cp.wu -+ * [WCXRP00000307] [MT6620 Wi-Fi][SQA]WHQL test .2c_wlan_adhoc case fail. -+ * [IBSS] when merged in, the bss state should be updated to firmware to pass WHQL adhoc failed item -+ * -+ * 01 10 2011 cp.wu -+ * [WCXRP00000351] [MT6620 Wi-Fi][Driver] remove from scanning result in OID handling layer -+ * when the corresponding BSS is disconnected due to beacon timeout -+ * remove from scanning result when the BSS is disconnected due to beacon timeout. -+ * -+ * 01 03 2011 cp.wu -+ * [WCXRP00000337] [MT6620 Wi-FI][Driver] AIS-FSM not to invoke cnmStaRecResetStatus -+ * directly 'cause it frees all belonging STA-RECs -+ * do not invoke cnmStaRecResetStatus() directly, nicUpdateBss will do the things after bss is disconnected -+ * -+ * 12 30 2010 cp.wu -+ * [WCXRP00000270] [MT6620 Wi-Fi][Driver] Clear issues after concurrent networking support has been merged -+ * do not need to manipulate prStaRec after indicating BSS disconnection to firmware, -+ * 'cause all STA-RECs belongs to BSS has been freed already -+ * -+ * 12 27 2010 cp.wu -+ * [WCXRP00000269] [MT6620 Wi-Fi][Driver][Firmware] Prepare for v1.1 branch release -+ * add DEBUGFUNC() macro invoking for more detailed debugging information -+ * -+ * 12 23 2010 george.huang -+ * [WCXRP00000152] [MT6620 Wi-Fi] AP mode power saving function -+ * 1. update WMM IE parsing, with ASSOC REQ handling -+ * 2. extend U-APSD parameter passing from driver to FW -+ * -+ * 12 17 2010 cp.wu -+ * [WCXRP00000270] [MT6620 Wi-Fi][Driver] Clear issues after concurrent networking support has been merged -+ * before BSS disconnection is indicated to firmware, all correlated peer should be cleared and freed -+ * -+ * 12 07 2010 cm.chang -+ * [WCXRP00000239] MT6620 Wi-Fi][Driver][FW] Merge concurrent branch back to maintrunk -+ * 1. BSSINFO include RLM parameter -+ * 2. free all sta records when network is disconnected -+ * -+ * 11 25 2010 yuche.tsai -+ * NULL -+ * Update SLT Function for QoS Support and not be affected by fixed rate function. -+ * -+ * 11 25 2010 cp.wu -+ * [WCXRP00000208] [MT6620 Wi-Fi][Driver] Add scanning with specified SSID to AIS FSM -+ * add scanning with specified SSID facility to AIS-FSM -+ * -+ * 11 01 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with -+ * Version Check[WCXRP00000150] [MT6620 Wi-Fi][Driver] Add implementation for querying current TX rate -+ * from firmware auto rate module -+ * 1) Query link speed (TX rate) from firmware directly with buffering mechanism to reduce overhead -+ * 2) Remove CNM CH-RECOVER event handling -+ * 3) cfg read/write API renamed with kal prefix for unified naming rules. -+ * -+ * 10 26 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000137] [MT6620 Wi-Fi] [FW] -+ * Support NIC capability query command -+ * 1) update NVRAM content template to ver 1.02 -+ * 2) add compile option for querying NIC capability (default: off) -+ * 3) modify AIS 5GHz support to run-time option, which could be turned on by registry or NVRAM setting -+ * 4) correct auto-rate compiler error under linux (treat warning as error) -+ * 5) simplify usage of NVRAM and REG_INFO_T -+ * 6) add version checking between driver and firmware -+ * -+ * 10 14 2010 wh.su -+ * [WCXRP00000097] [MT6620 Wi-Fi] [Driver] Fixed the P2P not setting the fgIsChannelExt value make scan not abort -+ * initial the fgIsChannelExt value. -+ * -+ * 10 08 2010 cp.wu -+ * [WCXRP00000087] [MT6620 Wi-Fi][Driver] Cannot connect to 5GHz AP, driver will cause FW assert. -+ * correct erroneous logic: specifying eBand with incompatible eSco -+ * -+ * 10 04 2010 cp.wu -+ * [WCXRP00000077] [MT6620 Wi-Fi][Driver][FW] Eliminate use of ENUM_NETWORK_TYPE_T -+ * and replaced by ENUM_NETWORK_TYPE_INDEX_T only -+ * remove ENUM_NETWORK_TYPE_T definitions -+ * -+ * 09 27 2010 chinghwa.yu -+ * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000065] Update BoW design and settings -+ * Update BCM/BoW design and settings. -+ * -+ * 09 23 2010 cp.wu -+ * [WCXRP00000049] [MT6620 Wi-Fi][Driver] Adhoc cannot be created successfully. -+ * keep IBSS-ALONE state retrying until further instruction is received -+ * -+ * 09 21 2010 cp.wu -+ * [WCXRP00000053] [MT6620 Wi-Fi][Driver] Reset incomplete and might leads to BSOD -+ * when entering RF test with AIS associated -+ * Do a complete reset with STA-REC null checking for RF test re-entry -+ * -+ * 09 09 2010 yuche.tsai -+ * NULL -+ * Fix NULL IE Beacon issue. Sync Beacon Content to FW before enable beacon. -+ * Both in IBSS Create & IBSS Merge -+ * -+ * 09 09 2010 cp.wu -+ * NULL -+ * frequency is in unit of KHz thus no need to divide 1000 once more. -+ * -+ * 09 06 2010 cp.wu -+ * NULL -+ * 1) initialize for correct parameter even for disassociation. -+ * 2) AIS-FSM should have a limit on trials to build connection -+ * -+ * 09 03 2010 kevin.huang -+ * NULL -+ * Refine #include sequence and solve recursive/nested #include issue -+ * -+ * 08 30 2010 cp.wu -+ * NULL -+ * eliminate klockwork errors -+ * -+ * 08 29 2010 yuche.tsai -+ * NULL -+ * Finish SLT TX/RX & Rate Changing Support. -+ * -+ * 08 25 2010 cp.wu -+ * NULL -+ * add option for enabling AIS 5GHz scan -+ * -+ * 08 25 2010 cp.wu -+ * NULL -+ * [AIS-FSM] IBSS no longer needs to acquire channel for beaconing, -+ * RLM/CNM will handle the channel switching when BSS information is updated -+ * -+ * 08 25 2010 george.huang -+ * NULL -+ * update OID/ registry control path for PM related settings -+ * -+ * 08 24 2010 cm.chang -+ * NULL -+ * Support RLM initail channel of Ad-hoc, P2P and BOW -+ * -+ * 08 20 2010 cm.chang -+ * NULL -+ * Migrate RLM code to host from FW -+ * -+ * 08 12 2010 cp.wu -+ * NULL -+ * check-in missed files. -+ * -+ * 08 12 2010 kevin.huang -+ * NULL -+ * Refine bssProcessProbeRequest() and bssSendBeaconProbeResponse() -+ * -+ * 08 09 2010 cp.wu -+ * NULL -+ * reset fgIsScanReqIssued when abort request is received right after join completion. -+ * -+ * 08 03 2010 cp.wu -+ * NULL -+ * surpress compilation warning. -+ * -+ * 08 02 2010 cp.wu -+ * NULL -+ * comment out deprecated members in BSS_INFO, which are only used by firmware rather than driver. -+ * -+ * 07 30 2010 cp.wu -+ * NULL -+ * 1) BoW wrapper: use definitions instead of hard-coded constant for error code -+ * 2) AIS-FSM: eliminate use of desired RF parameters, use prTargetBssDesc instead -+ * 3) add handling for RX_PKT_DESTINATION_HOST_WITH_FORWARD for GO-broadcast frames -+ * -+ * 07 29 2010 cp.wu -+ * NULL -+ * eliminate u4FreqInKHz usage, combined into rConnections.ucAdHoc* -+ * -+ * 07 29 2010 cp.wu -+ * NULL -+ * allocate on MGMT packet for IBSS beaconing. -+ * -+ * 07 29 2010 cp.wu -+ * NULL -+ * [AIS-FSM] fix: when join failed, release channel privilege as well -+ * -+ * 07 28 2010 cp.wu -+ * NULL -+ * reuse join-abort sub-procedure to reduce code size. -+ * -+ * 07 28 2010 cp.wu -+ * NULL -+ * 1) eliminate redundant variable eOPMode in prAdapter->rWlanInfo -+ * 2) change nicMediaStateChange() API prototype -+ * -+ * 07 26 2010 cp.wu -+ * -+ * AIS-FSM: when scan request is coming in the 1st 5 seconds of channel privilege period, -+ * just pend it til 5-sec. period finishes -+ * -+ * 07 26 2010 cp.wu -+ * -+ * AIS-FSM FIX: return channel privilege even when the privilege is not granted yet -+ * QM: qmGetFrameAction() won't assert when corresponding STA-REC index is not found -+ * -+ * 07 26 2010 cp.wu -+ * -+ * re-commit code logic being overwriten. -+ * -+ * 07 24 2010 wh.su -+ * -+ * .support the Wi-Fi RSN -+ * -+ * 07 23 2010 cp.wu -+ * -+ * 1) re-enable AIS-FSM beacon timeout handling. -+ * 2) scan done API revised -+ * -+ * 07 23 2010 cp.wu -+ * -+ * 1) enable Ad-Hoc -+ * 2) disable beacon timeout handling temporally due to unexpected beacon timeout event. -+ * -+ * 07 23 2010 cp.wu -+ * -+ * indicate scan done for linux wireless extension -+ * -+ * 07 23 2010 cp.wu -+ * -+ * add AIS-FSM handling for beacon timeout event. -+ * -+ * 07 22 2010 cp.wu -+ * -+ * 1) refine AIS-FSM indent. -+ * 2) when entering RF Test mode, flush 802.1X frames as well -+ * 3) when entering D3 state, flush 802.1X frames as well -+ * -+ * 07 21 2010 cp.wu -+ * -+ * separate AIS-FSM states into different cases of channel request. -+ * -+ * 07 21 2010 cp.wu -+ * -+ * 1) change BG_SCAN to ONLINE_SCAN for consistent term -+ * 2) only clear scanning result when scan is permitted to do -+ * -+ * 07 20 2010 cp.wu -+ * -+ * 1) [AIS] when new scan is issued, clear currently available scanning result except the connected one -+ * 2) refine disconnection behaviour when issued during BG-SCAN process -+ * -+ * 07 20 2010 cp.wu -+ * -+ * 1) bugfix: do not stop timer for join after switched into normal_tr state, -+ * for providing chance for DHCP handshasking -+ * 2) modify rsnPerformPolicySelection() invoking -+ * -+ * 07 19 2010 cp.wu -+ * -+ * 1) init AIS_BSS_INFO as channel number = 1 with band = 2.4GHz -+ * 2) correct typo -+ * -+ * 07 19 2010 wh.su -+ * -+ * update for security supporting. -+ * -+ * 07 19 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration. -+ * when IBSS is being merged-in, send command packet to PM for connected indication -+ * -+ * 07 19 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration. -+ * Add Ad-Hoc support to AIS-FSM -+ * -+ * 07 19 2010 jeffrey.chang -+ * -+ * Linux port modification -+ * -+ * 07 16 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration. -+ * bugfix for SCN migration -+ * 1) modify QUEUE_CONCATENATE_QUEUES() so it could be used to concatence with an empty queue -+ * 2) before AIS issues scan request, network(BSS) needs to be activated first -+ * 3) only invoke COPY_SSID when using specified SSID for scan -+ * -+ * 07 15 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration. -+ * for AIS scanning, driver specifies no extra IE for probe request -+ * -+ * 07 15 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration. -+ * driver no longer generates probe request frames -+ * -+ * 07 14 2010 yarco.yang -+ * -+ * Remove CFG_MQM_MIGRATION -+ * -+ * 07 14 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration. -+ * Refine AIS-FSM by divided into more states -+ * -+ * 07 13 2010 cm.chang -+ * -+ * Rename MSG_CH_RELEASE_T to MSG_CH_ABORT_T -+ * -+ * 07 09 2010 cp.wu -+ * -+ * 1) separate AIS_FSM state for two kinds of scanning. (OID triggered scan, and scan-for-connection) -+ * 2) eliminate PRE_BSS_DESC_T, Beacon/PrebResp is now parsed in single pass -+ * 3) implment DRV-SCN module, currently only accepts single scan request, -+ * other request will be directly dropped by returning BUSY -+ * -+ * 07 09 2010 george.huang -+ * -+ * [WPD00001556] Migrate PM variables from FW to driver: for composing QoS Info -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 07 08 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * take use of RLM module for parsing/generating HT IEs for 11n capability -+ * -+ * 07 08 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Rename MID_MNY_CNM_CH_RELEASE to MID_MNY_CNM_CH_ABORT -+ * -+ * 07 07 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * for first connection, if connecting failed do not enter into scan state. -+ * -+ * 07 06 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * once STA-REC is allocated and updated, invoke cnmStaRecChangeState() to sync. with firmware. -+ * -+ * 07 06 2010 george.huang -+ * [WPD00001556]Basic power managemenet function -+ * Update arguments for nicUpdateBeaconIETemplate() -+ * -+ * 07 06 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * STA-REC is maintained by CNM only. -+ * -+ * 07 05 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * remove unused definitions. -+ * -+ * 07 01 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * AIS-FSM integration with CNM channel request messages -+ * -+ * 07 01 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * implementation of DRV-SCN and related mailbox message handling. -+ * -+ * 06 30 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * sync. with CMD/EVENT document ver0.07. -+ * -+ * 06 29 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) sync to. CMD/EVENT document v0.03 -+ * 2) simplify DTIM period parsing in scan.c only, bss.c no longer parses it again. -+ * 3) send command packet to indicate FW-PM after -+ * a) 1st beacon is received after AIS has connected to an AP -+ * b) IBSS-ALONE has been created -+ * c) IBSS-MERGE has occurred -+ * -+ * 06 25 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * modify Beacon/ProbeResp to complete parsing, -+ * because host software has looser memory usage restriction -+ * -+ * 06 23 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * integrate . -+ * -+ * 06 22 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * comment out RLM APIs by CFG_RLM_MIGRATION. -+ * -+ * 06 22 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) add command warpper for STA-REC/BSS-INFO sync. -+ * 2) enhance command packet sending procedure for non-oid part -+ * 3) add command packet definitions for STA-REC/BSS-INFO sync. -+ * -+ * 06 21 2010 yarco.yang -+ * [WPD00003837][MT6620]Data Path Refine -+ * Support CFG_MQM_MIGRATION flag -+ * -+ * 06 21 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add scan_fsm into building. -+ * -+ * 06 21 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * RSN/PRIVACY compilation flag awareness correction -+ * -+ * 06 18 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Provide cnmMgtPktAlloc() and alloc/free function of msg/buf -+ * -+ * 06 18 2010 wh.su -+ * [WPD00003840][MT6620 5931] Security migration -+ * migration from MT6620 firmware. -+ * -+ * 06 15 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add scan.c. -+ * -+ * 06 14 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * restore utility function invoking via hem_mbox to direct calls -+ * -+ * 06 11 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * auth.c is migrated. -+ * -+ * 06 11 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add bss.c. -+ * -+ * 06 11 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) migrate assoc.c. -+ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness -+ * 3) add configuration options for CNM_MEM and RSN modules -+ * 4) add data path for management frames -+ * 5) eliminate rPacketInfo of MSDU_INFO_T -+ * -+ * 06 10 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * change to enqueue TX frame infinitely. -+ * -+ * 06 10 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) eliminate CFG_CMD_EVENT_VERSION_0_9 -+ * 2) when disconnected, indicate nic directly (no event is needed) -+ * -+ * 06 10 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add buildable & linkable ais_fsm.c -+ * -+ * related reference are still waiting to be resolved -+ * -+ * 06 01 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Add conditionial compiling flag to choose default available bandwidth -+ * -+ * 05 28 2010 kevin.huang -+ * [BORA00000794][WIFISYS][New Feature]Power Management Support -+ * Add ClientList handling API - bssClearClientList, bssAddStaRecToClientList -+ * -+ * 05 24 2010 kevin.huang -+ * [BORA00000794][WIFISYS][New Feature]Power Management Support -+ * Refine authSendAuthFrame() for NULL STA_RECORD_T case and minimum deauth interval. -+ * -+ * 05 21 2010 kevin.huang -+ * [BORA00000794][WIFISYS][New Feature]Power Management Support -+ * Fix compile error if CFG_CMD_EVENT_VER_009 == 0 for prEventConnStatus->ucNetworkType. -+ * -+ * 05 21 2010 kevin.huang -+ * [BORA00000794][WIFISYS][New Feature]Power Management Support -+ * Refine txmInitWtblTxRateTable() - set TX initial rate according to AP's operation rate set -+ * -+ * 05 17 2010 kevin.huang -+ * [BORA00000794][WIFISYS][New Feature]Power Management Support -+ * Call pmAbort() and add ucNetworkType field in EVENT_CONNECTION_STATUS -+ * -+ * 05 14 2010 kevin.huang -+ * [BORA00000794][WIFISYS][New Feature]Power Management Support -+ * Fix compile warning - define of MQM_WMM_PARSING was removed -+ * -+ * 05 12 2010 kevin.huang -+ * [BORA00000794][WIFISYS][New Feature]Power Management Support -+ * Add Power Management - Legacy PS-POLL support. -+ * -+ * 04 28 2010 tehuang.liu -+ * [BORA00000605][WIFISYS] Phase3 Integration -+ * Removed the use of compiling flag MQM_WMM_PARSING -+ * -+ * 04 27 2010 kevin.huang -+ * [BORA00000714][WIFISYS][New Feature]Beacon Timeout Support -+ * -+ * Fix typo -+ * -+ * 04 27 2010 kevin.huang -+ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support -+ * Add Set Slot Time and Beacon Timeout Support for AdHoc Mode -+ * -+ * 04 19 2010 kevin.huang -+ * [BORA00000714][WIFISYS][New Feature]Beacon Timeout Support -+ * Add Send Deauth for Class 3 Error and Leave Network Support -+ * -+ * 04 15 2010 wh.su -+ * [BORA00000680][MT6620] Support the statistic for Micxxsoft os query -+ * fixed the protected bit at cap info for ad-hoc. -+ * -+ * 04 13 2010 kevin.huang -+ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support -+ * Add new HW CH macro support -+ * -+ * 04 07 2010 chinghwa.yu -+ * [BORA00000563]Add WiFi CoEx BCM module -+ * Add TX Power Control RCPI function. -+ * -+ * 03 29 2010 wh.su -+ * [BORA00000605][WIFISYS] Phase3 Integration -+ * move the wlan table alloc / free to change state function. -+ * -+ * 03 25 2010 wh.su -+ * [BORA00000676][MT6620] Support the frequency setting and query at build connection / connection event -+ * modify the build connection and status event structure bu CMD_EVENT doc 0.09 draft, default is disable. -+ * -+ * 03 24 2010 wh.su -+ * [BORA00000605][WIFISYS] Phase3 Integration -+ * fixed some WHQL testing error. -+ * -+ * 03 24 2010 kevin.huang -+ * [BORA00000654][WIFISYS][New Feature] CNM Module - Ch Manager Support -+ * Add Set / Unset POWER STATE in AIS Network -+ * -+ * 03 16 2010 kevin.huang -+ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support -+ * Add AdHoc Mode -+ * -+ * 03 10 2010 kevin.huang -+ * [BORA00000654][WIFISYS][New Feature] CNM Module - Ch Manager Support -+ * Add Channel Manager for arbitration of JOIN and SCAN Req -+ * -+ * 03 03 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Add PHY_CONFIG to change Phy Type -+ * -+ * 03 03 2010 chinghwa.yu -+ * [BORA00000563]Add WiFi CoEx BCM module -+ * Use bcmWiFiNotify to replace wifi_send_msg to pass information to BCM module. -+ * -+ * 03 03 2010 chinghwa.yu -+ * [BORA00000563]Add WiFi CoEx BCM module -+ * Remove wmt_task definition and add PTA function. -+ * -+ * 03 02 2010 tehuang.liu -+ * [BORA00000569][WIFISYS] Phase 2 Integration Test -+ * Init TXM and MQM testing procedures in aisFsmRunEventJoinComplete() -+ * -+ * 03 01 2010 tehuang.liu -+ * [BORA00000569][WIFISYS] Phase 2 Integration Test -+ * Modified aisUpdateBssInfo() to call TXM's functions for setting WTBL TX parameters -+ * -+ * 03 01 2010 wh.su -+ * [BORA00000605][WIFISYS] Phase3 Integration -+ * clear the pmkid cache while indicate media disconnect. -+ * -+ * 02 26 2010 tehuang.liu -+ * [BORA00000569][WIFISYS] Phase 2 Integration Test -+ * . -+ * -+ * 02 26 2010 tehuang.liu -+ * [BORA00000569][WIFISYS] Phase 2 Integration Test -+ * Enabled MQM parsing WMM IEs for non-AP mode -+ * -+ * 02 26 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Remove CFG_TEST_VIRTUAL_CMD and add support of Driver STA_RECORD_T activation -+ * -+ * 02 25 2010 wh.su -+ * [BORA00000605][WIFISYS] Phase3 Integration -+ * use the Rx0 dor event indicate. -+ * -+ * 02 23 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Support dynamic channel selection -+ * -+ * 02 23 2010 wh.su -+ * [BORA00000621][MT6620 Wi-Fi] Add the RSSI indicate to avoid XP stalled for query rssi value -+ * Adding the RSSI event support, -+ * using the HAL function to get the rcpi value and tranlsate to RSSI and indicate to driver -+ * -+ * 02 12 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Use bss info array for concurrent handle -+ * -+ * 02 05 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Revise data structure to share the same BSS_INFO_T for avoiding coding error -+ * -+ * 02 04 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Add AAA Module Support, Revise Net Type to Net Type Index for array lookup -+ * -+ * 01 27 2010 tehuang.liu -+ * [BORA00000569][WIFISYS] Phase 2 Integration Test -+ * Set max AMDPU size supported by the peer to 64 KB, -+ * removed mqmInit() and mqmTxSendAddBaReq() function calls in aisUpdateBssInfo() -+ * -+ * 01 27 2010 wh.su -+ * [BORA00000476][Wi-Fi][firmware] Add the security module initialize code -+ * add and fixed some security function. -+ * -+ * 01 22 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Support protection and bandwidth switch -+ * -+ * 01 20 2010 kevin.huang -+ * [BORA00000569][WIFISYS] Phase 2 Integration Test -+ * Add PHASE_2_INTEGRATION_WORK_AROUND and CFG_SUPPORT_BCM flags -+ * -+ * 01 15 2010 tehuang.liu -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Configured the AMPDU factor to 3 for the APu1rwduu`wvpghlqg|q`mpdkb+ilp -+ * -+ * 01 14 2010 chinghwa.yu -+ * [BORA00000563]Add WiFi CoEx BCM module -+ * Add WiFi BCM module for the 1st time. -+ * -+ * 01 11 2010 kevin.huang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Add Deauth and Disassoc Handler -+ * -+ * 01 07 2010 kevin.huang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * -+ * Refine JOIN Complete and separate the function of Media State indication -+ * -+ * 01 04 2010 tehuang.liu -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * For working out the first connection Chariot-verified version -+ * -+ * 12 18 2009 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * . -+ * -+ * Dec 10 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * adding the sample code to update the wlan table rate, -+ * -+ * Dec 10 2009 mtk01104 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Different function prototype of wifi_send_msg() -+ * -+ * Dec 9 2009 mtk01104 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Call rlm related function to process HT info when join complete -+ * -+ * Dec 9 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * default the acquired wlan table entry code off -+ * -+ * Dec 9 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * adding the code to acquired the wlan table entry, and a sample code to update the BA bit at table -+ * -+ * Dec 7 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Fix the problem of prSwRfb overwrited by event packet in aisFsmRunEventJoinComplete() -+ * -+ * Dec 4 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * adding the code to integrate the security related code -+ * -+ * Dec 3 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Remove redundant declaration -+ * -+ * Dec 3 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Add code for JOIN init and JOIN complete -+ * -+ * Nov 30 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Rename u4RSSI to i4RSSI -+ * -+ * Nov 30 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Revise ENUM_MEDIA_STATE to ENUM_PARAM_MEDIA_STATE -+ * -+ * Nov 30 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Add fgIsScanReqIssued to CONNECTION_SETTINGS_T -+ * -+ * Nov 26 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Revise Virtual CMD handler due to structure changed -+ * -+ * Nov 25 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Add Virtual CMD & RESP for testing CMD PATH -+ * -+ * Nov 23 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Add aisFsmInitializeConnectionSettings() -+ * -+ * Nov 20 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Add CFG_TEST_MGMT_FSM flag for aisFsmTest() -+ * -+ * Nov 16 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "precomp.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+#define AIS_ROAMING_CONNECTION_TRIAL_LIMIT 2 -+#define AIS_ROAMING_SCAN_CHANNEL_DWELL_TIME 80 -+ -+#define CTIA_MAGIC_SSID "ctia_test_only_*#*#3646633#*#*" -+#define CTIA_MAGIC_SSID_LEN 30 -+ -+#define AIS_JOIN_TIMEOUT 7 -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+#if DBG -+/*lint -save -e64 Type mismatch */ -+static PUINT_8 apucDebugAisState[AIS_STATE_NUM] = { -+ (PUINT_8) DISP_STRING("AIS_STATE_IDLE"), -+ (PUINT_8) DISP_STRING("AIS_STATE_SEARCH"), -+ (PUINT_8) DISP_STRING("AIS_STATE_SCAN"), -+ (PUINT_8) DISP_STRING("AIS_STATE_ONLINE_SCAN"), -+ (PUINT_8) DISP_STRING("AIS_STATE_LOOKING_FOR"), -+ (PUINT_8) DISP_STRING("AIS_STATE_WAIT_FOR_NEXT_SCAN"), -+ (PUINT_8) DISP_STRING("AIS_STATE_REQ_CHANNEL_JOIN"), -+ (PUINT_8) DISP_STRING("AIS_STATE_JOIN"), -+ (PUINT_8) DISP_STRING("AIS_STATE_IBSS_ALONE"), -+ (PUINT_8) DISP_STRING("AIS_STATE_IBSS_MERGE"), -+ (PUINT_8) DISP_STRING("AIS_STATE_NORMAL_TR"), -+ (PUINT_8) DISP_STRING("AIS_STATE_DISCONNECTING"), -+ (PUINT_8) DISP_STRING("AIS_STATE_REQ_REMAIN_ON_CHANNEL"), -+ (PUINT_8) DISP_STRING("AIS_STATE_REMAIN_ON_CHANNEL") -+}; -+ -+/*lint -restore */ -+#endif /* DBG */ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief the function is used to initialize the value of the connection settings for -+* AIS network -+* -+* @param (none) -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID aisInitializeConnectionSettings(IN P_ADAPTER_T prAdapter, IN P_REG_INFO_T prRegInfo) -+{ -+ P_CONNECTION_SETTINGS_T prConnSettings; -+ UINT_8 aucAnyBSSID[] = BC_BSSID; -+ UINT_8 aucZeroMacAddr[] = NULL_MAC_ADDR; -+ int i = 0; -+ -+ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); -+ -+ /* Setup default values for operation */ -+ COPY_MAC_ADDR(prConnSettings->aucMacAddress, aucZeroMacAddr); -+ -+ if (prRegInfo) -+ prConnSettings->ucDelayTimeOfDisconnectEvent = -+ (!prAdapter->fgIsHw5GBandDisabled && prRegInfo->ucSupport5GBand) ? -+ AIS_DELAY_TIME_OF_DISC_SEC_DUALBAND : AIS_DELAY_TIME_OF_DISC_SEC_ONLY_2G4; -+ else -+ prConnSettings->ucDelayTimeOfDisconnectEvent = AIS_DELAY_TIME_OF_DISC_SEC_ONLY_2G4; -+ -+ COPY_MAC_ADDR(prConnSettings->aucBSSID, aucAnyBSSID); -+ prConnSettings->fgIsConnByBssidIssued = FALSE; -+ -+ prConnSettings->fgIsConnReqIssued = FALSE; -+ prConnSettings->fgIsDisconnectedByNonRequest = FALSE; -+ -+ prConnSettings->ucSSIDLen = 0; -+ -+ prConnSettings->eOPMode = NET_TYPE_INFRA; -+ -+ prConnSettings->eConnectionPolicy = CONNECT_BY_SSID_BEST_RSSI; -+ -+ if (prRegInfo) { -+ prConnSettings->ucAdHocChannelNum = (UINT_8) nicFreq2ChannelNum(prRegInfo->u4StartFreq); -+ prConnSettings->eAdHocBand = prRegInfo->u4StartFreq < 5000000 ? BAND_2G4 : BAND_5G; -+ prConnSettings->eAdHocMode = (ENUM_PARAM_AD_HOC_MODE_T) (prRegInfo->u4AdhocMode); -+ } -+ -+ prConnSettings->eAuthMode = AUTH_MODE_OPEN; -+ -+ prConnSettings->eEncStatus = ENUM_ENCRYPTION_DISABLED; -+ -+ prConnSettings->fgIsScanReqIssued = FALSE; -+ -+ /* MIB attributes */ -+ prConnSettings->u2BeaconPeriod = DOT11_BEACON_PERIOD_DEFAULT; -+ -+ prConnSettings->u2RTSThreshold = DOT11_RTS_THRESHOLD_DEFAULT; -+ -+ prConnSettings->u2DesiredNonHTRateSet = RATE_SET_ALL_ABG; -+ -+ /* prConnSettings->u4FreqInKHz; */ /* Center frequency */ -+ -+ /* Set U-APSD AC */ -+ prConnSettings->bmfgApsdEnAc = PM_UAPSD_NONE; -+ -+ secInit(prAdapter, NETWORK_TYPE_AIS_INDEX); -+ -+ /* Features */ -+ prConnSettings->fgIsEnableRoaming = FALSE; -+#if CFG_SUPPORT_ROAMING -+ if (prRegInfo) -+ prConnSettings->fgIsEnableRoaming = ((prRegInfo->fgDisRoaming > 0) ? (FALSE) : (TRUE)); -+#endif /* CFG_SUPPORT_ROAMING */ -+ -+ prConnSettings->fgIsAdHocQoSEnable = FALSE; -+ -+ prConnSettings->eDesiredPhyConfig = PHY_CONFIG_802_11ABGN; -+ -+ /* Set default bandwidth modes */ -+ prConnSettings->uc2G4BandwidthMode = CONFIG_BW_20M; -+ prConnSettings->uc5GBandwidthMode = CONFIG_BW_20_40M; -+ -+ prConnSettings->rRsnInfo.ucElemId = 0x30; -+ prConnSettings->rRsnInfo.u2Version = 0x0001; -+ prConnSettings->rRsnInfo.u4GroupKeyCipherSuite = 0; -+ prConnSettings->rRsnInfo.u4PairwiseKeyCipherSuiteCount = 0; -+ for (i = 0; i < MAX_NUM_SUPPORTED_CIPHER_SUITES; i++) -+ prConnSettings->rRsnInfo.au4PairwiseKeyCipherSuite[i] = 0; -+ prConnSettings->rRsnInfo.u4AuthKeyMgtSuiteCount = 0; -+ for (i = 0; i < MAX_NUM_SUPPORTED_AKM_SUITES; i++) -+ prConnSettings->rRsnInfo.au4AuthKeyMgtSuite[i] = 0; -+ prConnSettings->rRsnInfo.u2RsnCap = 0; -+ prConnSettings->rRsnInfo.fgRsnCapPresent = FALSE; -+ -+} /* end of aisFsmInitializeConnectionSettings() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief the function is used to initialize the value in AIS_FSM_INFO_T for -+* AIS FSM operation -+* -+* @param (none) -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT_32 ucScanTimeoutTimes = 0; -+VOID aisFsmInit(IN P_ADAPTER_T prAdapter) -+{ -+ P_AIS_FSM_INFO_T prAisFsmInfo; -+ P_BSS_INFO_T prAisBssInfo; -+ P_AIS_SPECIFIC_BSS_INFO_T prAisSpecificBssInfo; -+ -+ DEBUGFUNC("aisFsmInit()"); -+ DBGLOG(SW1, TRACE, "->aisFsmInit()\n"); -+ -+ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); -+ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ prAisSpecificBssInfo = &(prAdapter->rWifiVar.rAisSpecificBssInfo); -+ -+ /* 4 <1> Initiate FSM */ -+ prAisFsmInfo->ePreviousState = AIS_STATE_IDLE; -+ prAisFsmInfo->eCurrentState = AIS_STATE_IDLE; -+ -+ prAisFsmInfo->ucAvailableAuthTypes = 0; -+ -+ prAisFsmInfo->prTargetBssDesc = (P_BSS_DESC_T) NULL; -+ -+ prAisFsmInfo->ucSeqNumOfReqMsg = 0; -+ prAisFsmInfo->ucSeqNumOfChReq = 0; -+ prAisFsmInfo->ucSeqNumOfScanReq = 0; -+ -+ prAisFsmInfo->fgIsInfraChannelFinished = TRUE; -+#if CFG_SUPPORT_ROAMING -+ prAisFsmInfo->fgIsRoamingScanPending = FALSE; -+#endif /* CFG_SUPPORT_ROAMING */ -+ prAisFsmInfo->fgIsChannelRequested = FALSE; -+ prAisFsmInfo->fgIsChannelGranted = FALSE; -+ -+ /* 4 <1.1> Initiate FSM - Timer INIT */ -+ cnmTimerInitTimer(prAdapter, -+ &prAisFsmInfo->rBGScanTimer, -+ (PFN_MGMT_TIMEOUT_FUNC) aisFsmRunEventBGSleepTimeOut, (ULONG) NULL); -+ -+ cnmTimerInitTimer(prAdapter, -+ &prAisFsmInfo->rIbssAloneTimer, -+ (PFN_MGMT_TIMEOUT_FUNC) aisFsmRunEventIbssAloneTimeOut, (ULONG) NULL); -+ -+ cnmTimerInitTimer(prAdapter, -+ &prAisFsmInfo->rIndicationOfDisconnectTimer, -+ (PFN_MGMT_TIMEOUT_FUNC) aisPostponedEventOfDisconnTimeout, (ULONG) NULL); -+ -+ cnmTimerInitTimer(prAdapter, -+ &prAisFsmInfo->rJoinTimeoutTimer, -+ (PFN_MGMT_TIMEOUT_FUNC) aisFsmRunEventJoinTimeout, (ULONG) NULL); -+ -+ cnmTimerInitTimer(prAdapter, -+ &prAisFsmInfo->rScanDoneTimer, -+ (PFN_MGMT_TIMEOUT_FUNC) aisFsmRunEventScanDoneTimeOut, (ULONG) NULL); -+ -+ cnmTimerInitTimer(prAdapter, -+ &prAisFsmInfo->rChannelTimeoutTimer, -+ (PFN_MGMT_TIMEOUT_FUNC) aisFsmRunEventChannelTimeout, (ULONG) NULL); -+ -+ cnmTimerInitTimer(prAdapter, -+ &prAisFsmInfo->rDeauthDoneTimer, -+ (PFN_MGMT_TIMEOUT_FUNC) aisFsmRunEventDeauthTimeout, (ULONG) NULL); -+ -+ /* 4 <1.2> Initiate PWR STATE */ -+ SET_NET_PWR_STATE_IDLE(prAdapter, NETWORK_TYPE_AIS_INDEX); -+ -+ /* 4 <2> Initiate BSS_INFO_T - common part */ -+ BSS_INFO_INIT(prAdapter, NETWORK_TYPE_AIS_INDEX); -+ COPY_MAC_ADDR(prAisBssInfo->aucOwnMacAddr, prAdapter->rWifiVar.aucMacAddress); -+ -+ /* 4 <3> Initiate BSS_INFO_T - private part */ -+ /* TODO */ -+ prAisBssInfo->eBand = BAND_2G4; -+ prAisBssInfo->ucPrimaryChannel = 1; -+ prAisBssInfo->prStaRecOfAP = (P_STA_RECORD_T) NULL; -+ -+ /* 4 <4> Allocate MSDU_INFO_T for Beacon */ -+ prAisBssInfo->prBeacon = cnmMgtPktAlloc(prAdapter, -+ OFFSET_OF(WLAN_BEACON_FRAME_T, aucInfoElem[0]) + MAX_IE_LENGTH); -+ -+ if (prAisBssInfo->prBeacon) { -+ prAisBssInfo->prBeacon->eSrc = TX_PACKET_MGMT; -+ prAisBssInfo->prBeacon->ucStaRecIndex = 0xFF; /* NULL STA_REC */ -+ } else { -+ ASSERT(0); -+ } -+ -+#if 0 -+ prAisBssInfo->rPmProfSetupInfo.ucBmpDeliveryAC = PM_UAPSD_ALL; -+ prAisBssInfo->rPmProfSetupInfo.ucBmpTriggerAC = PM_UAPSD_ALL; -+ prAisBssInfo->rPmProfSetupInfo.ucUapsdSp = WMM_MAX_SP_LENGTH_2; -+#else -+ if (prAdapter->u4UapsdAcBmp == 0) { -+ prAdapter->u4UapsdAcBmp = CFG_INIT_UAPSD_AC_BMP; -+ /* ASSERT(prAdapter->u4UapsdAcBmp); */ -+ } -+ prAisBssInfo->rPmProfSetupInfo.ucBmpDeliveryAC = (UINT_8) prAdapter->u4UapsdAcBmp; -+ prAisBssInfo->rPmProfSetupInfo.ucBmpTriggerAC = (UINT_8) prAdapter->u4UapsdAcBmp; -+ prAisBssInfo->rPmProfSetupInfo.ucUapsdSp = (UINT_8) prAdapter->u4MaxSpLen; -+#endif -+ -+ /* request list initialization */ -+ LINK_INITIALIZE(&prAisFsmInfo->rPendingReqList); -+ -+ /* DBGPRINTF("[2] ucBmpDeliveryAC:0x%x, ucBmpTriggerAC:0x%x, ucUapsdSp:0x%x", */ -+ /* prAisBssInfo->rPmProfSetupInfo.ucBmpDeliveryAC, */ -+ /* prAisBssInfo->rPmProfSetupInfo.ucBmpTriggerAC, */ -+ /* prAisBssInfo->rPmProfSetupInfo.ucUapsdSp); */ -+ -+ /*reset ucScanTimeoutTimes value*/ -+ ucScanTimeoutTimes = 0; -+ -+} /* end of aisFsmInit() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief the function is used to uninitialize the value in AIS_FSM_INFO_T for -+* AIS FSM operation -+* -+* @param (none) -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID aisFsmUninit(IN P_ADAPTER_T prAdapter) -+{ -+ P_AIS_FSM_INFO_T prAisFsmInfo; -+ P_BSS_INFO_T prAisBssInfo; -+ P_AIS_SPECIFIC_BSS_INFO_T prAisSpecificBssInfo; -+ -+ DEBUGFUNC("aisFsmUninit()"); -+ DBGLOG(SW1, INFO, "->aisFsmUninit()\n"); -+ -+ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); -+ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ prAisSpecificBssInfo = &(prAdapter->rWifiVar.rAisSpecificBssInfo); -+ -+ /* 4 <1> Stop all timers */ -+ cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rBGScanTimer); -+ cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rIbssAloneTimer); -+ cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rIndicationOfDisconnectTimer); -+ cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rJoinTimeoutTimer); -+ cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rScanDoneTimer); /* Add by Enlai */ -+ cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rChannelTimeoutTimer); -+ -+ /* 4 <2> flush pending request */ -+ aisFsmFlushRequest(prAdapter); -+ -+ /* 4 <3> Reset driver-domain BSS-INFO */ -+ if (prAisBssInfo->prBeacon) { -+ cnmMgtPktFree(prAdapter, prAisBssInfo->prBeacon); -+ prAisBssInfo->prBeacon = NULL; -+ } -+#if CFG_SUPPORT_802_11W -+ rsnStopSaQuery(prAdapter); -+#endif -+ -+} /* end of aisFsmUninit() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Initialization of JOIN STATE -+* -+* @param[in] prBssDesc The pointer of BSS_DESC_T which is the BSS we will try to join with. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID aisFsmStateInit_JOIN(IN P_ADAPTER_T prAdapter, P_BSS_DESC_T prBssDesc) -+{ -+ P_AIS_FSM_INFO_T prAisFsmInfo; -+ P_BSS_INFO_T prAisBssInfo; -+ P_AIS_SPECIFIC_BSS_INFO_T prAisSpecificBssInfo; -+ P_CONNECTION_SETTINGS_T prConnSettings; -+ P_STA_RECORD_T prStaRec; -+ P_MSG_JOIN_REQ_T prJoinReqMsg; -+ -+ DEBUGFUNC("aisFsmStateInit_JOIN()"); -+ -+ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); -+ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ prAisSpecificBssInfo = &(prAdapter->rWifiVar.rAisSpecificBssInfo); -+ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); -+ -+ ASSERT(prBssDesc); -+ -+ /* 4 <1> We are going to connect to this BSS. */ -+ prBssDesc->fgIsConnecting = TRUE; -+ -+ /* 4 <2> Setup corresponding STA_RECORD_T */ -+ prStaRec = bssCreateStaRecFromBssDesc(prAdapter, STA_TYPE_LEGACY_AP, NETWORK_TYPE_AIS_INDEX, prBssDesc); -+ if (prStaRec == NULL) { -+ DBGLOG(AIS, WARN, "Create station record fail\n"); -+ return; -+ } -+ -+ prAisFsmInfo->prTargetStaRec = prStaRec; -+ -+ /* 4 <2.1> sync. to firmware domain */ -+ if (prStaRec->ucStaState == STA_STATE_1) -+ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); -+ /* 4 <3> Update ucAvailableAuthTypes which we can choice during SAA */ -+ if (prAisBssInfo->eConnectionState == PARAM_MEDIA_STATE_DISCONNECTED) { -+ -+ prStaRec->fgIsReAssoc = FALSE; -+ -+ switch (prConnSettings->eAuthMode) { -+ case AUTH_MODE_OPEN: /* Note: Omit break here. */ -+ case AUTH_MODE_WPA: -+ case AUTH_MODE_WPA_PSK: -+ case AUTH_MODE_WPA2: -+ case AUTH_MODE_WPA2_PSK: -+ prAisFsmInfo->ucAvailableAuthTypes = (UINT_8) AUTH_TYPE_OPEN_SYSTEM; -+ break; -+ -+ case AUTH_MODE_SHARED: -+ prAisFsmInfo->ucAvailableAuthTypes = (UINT_8) AUTH_TYPE_SHARED_KEY; -+ break; -+ -+ case AUTH_MODE_AUTO_SWITCH: -+ DBGLOG(AIS, LOUD, "JOIN INIT: eAuthMode == AUTH_MODE_AUTO_SWITCH\n"); -+ prAisFsmInfo->ucAvailableAuthTypes = (UINT_8) (AUTH_TYPE_OPEN_SYSTEM | AUTH_TYPE_SHARED_KEY); -+ break; -+ -+ default: -+ ASSERT(!(prConnSettings->eAuthMode == AUTH_MODE_WPA_NONE)); -+ DBGLOG(AIS, ERROR, "JOIN INIT: Auth Algorithm : %d was not supported by JOIN\n", -+ prConnSettings->eAuthMode); -+ /* TODO(Kevin): error handling ? */ -+ return; -+ } -+ -+ /* TODO(tyhsu): Assume that Roaming Auth Type is equal to ConnSettings eAuthMode */ -+ prAisSpecificBssInfo->ucRoamingAuthTypes = prAisFsmInfo->ucAvailableAuthTypes; -+ -+ prStaRec->ucTxAuthAssocRetryLimit = TX_AUTH_ASSOCI_RETRY_LIMIT; -+ -+ } else { -+ ASSERT(prBssDesc->eBSSType == BSS_TYPE_INFRASTRUCTURE); -+ ASSERT(!prBssDesc->fgIsConnected); -+ -+ DBGLOG(AIS, LOUD, "JOIN INIT: AUTH TYPE = %d for Roaming\n", -+ prAisSpecificBssInfo->ucRoamingAuthTypes); -+ -+ prStaRec->fgIsReAssoc = TRUE; /* We do roaming while the medium is connected */ -+ -+ /* TODO(Kevin): We may call a sub function to acquire the Roaming Auth Type */ -+ prAisFsmInfo->ucAvailableAuthTypes = prAisSpecificBssInfo->ucRoamingAuthTypes; -+ -+ prStaRec->ucTxAuthAssocRetryLimit = TX_AUTH_ASSOCI_RETRY_LIMIT_FOR_ROAMING; -+ } -+ -+ /* 4 <4> Use an appropriate Authentication Algorithm Number among the ucAvailableAuthTypes */ -+ if (prAisFsmInfo->ucAvailableAuthTypes & (UINT_8) AUTH_TYPE_OPEN_SYSTEM) { -+ -+ DBGLOG(AIS, LOUD, "JOIN INIT: Try to do Authentication with AuthType == OPEN_SYSTEM.\n"); -+ prAisFsmInfo->ucAvailableAuthTypes &= ~(UINT_8) AUTH_TYPE_OPEN_SYSTEM; -+ -+ prStaRec->ucAuthAlgNum = (UINT_8) AUTH_ALGORITHM_NUM_OPEN_SYSTEM; -+ } else if (prAisFsmInfo->ucAvailableAuthTypes & (UINT_8) AUTH_TYPE_SHARED_KEY) { -+ -+ DBGLOG(AIS, LOUD, "JOIN INIT: Try to do Authentication with AuthType == SHARED_KEY.\n"); -+ -+ prAisFsmInfo->ucAvailableAuthTypes &= ~(UINT_8) AUTH_TYPE_SHARED_KEY; -+ -+ prStaRec->ucAuthAlgNum = (UINT_8) AUTH_ALGORITHM_NUM_SHARED_KEY; -+ } else if (prAisFsmInfo->ucAvailableAuthTypes & (UINT_8) AUTH_TYPE_FAST_BSS_TRANSITION) { -+ -+ DBGLOG(AIS, LOUD, "JOIN INIT: Try to do Authentication with AuthType == FAST_BSS_TRANSITION.\n"); -+ -+ prAisFsmInfo->ucAvailableAuthTypes &= ~(UINT_8) AUTH_TYPE_FAST_BSS_TRANSITION; -+ -+ prStaRec->ucAuthAlgNum = (UINT_8) AUTH_ALGORITHM_NUM_FAST_BSS_TRANSITION; -+ } else { -+ ASSERT(0); -+ } -+ -+ /* 4 <5> Overwrite Connection Setting for eConnectionPolicy == ANY (Used by Assoc Req) */ -+ if (prBssDesc->ucSSIDLen) -+ COPY_SSID(prConnSettings->aucSSID, prConnSettings->ucSSIDLen, prBssDesc->aucSSID, prBssDesc->ucSSIDLen); -+ /* 4 <6> Send a Msg to trigger SAA to start JOIN process. */ -+ prJoinReqMsg = (P_MSG_JOIN_REQ_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_JOIN_REQ_T)); -+ if (!prJoinReqMsg) { -+ -+ ASSERT(0); /* Can't trigger SAA FSM */ -+ return; -+ } -+ -+ prJoinReqMsg->rMsgHdr.eMsgId = MID_AIS_SAA_FSM_START; -+ prJoinReqMsg->ucSeqNum = ++prAisFsmInfo->ucSeqNumOfReqMsg; -+ prJoinReqMsg->prStaRec = prStaRec; -+ -+ if (1) { -+ int j; -+ P_FRAG_INFO_T prFragInfo; -+ -+ for (j = 0; j < MAX_NUM_CONCURRENT_FRAGMENTED_MSDUS; j++) { -+ prFragInfo = &prStaRec->rFragInfo[j]; -+ -+ if (prFragInfo->pr1stFrag) { -+ /* nicRxReturnRFB(prAdapter, prFragInfo->pr1stFrag); */ -+ prFragInfo->pr1stFrag = (P_SW_RFB_T) NULL; -+ } -+ } -+ } -+ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prJoinReqMsg, MSG_SEND_METHOD_BUF); -+ -+} /* end of aisFsmInit_JOIN() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Retry JOIN for AUTH_MODE_AUTO_SWITCH -+* -+* @param[in] prStaRec Pointer to the STA_RECORD_T -+* -+* @retval TRUE We will retry JOIN -+* @retval FALSE We will not retry JOIN -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN aisFsmStateInit_RetryJOIN(IN P_ADAPTER_T prAdapter, P_STA_RECORD_T prStaRec) -+{ -+ P_AIS_FSM_INFO_T prAisFsmInfo; -+ P_MSG_JOIN_REQ_T prJoinReqMsg; -+ -+ DEBUGFUNC("aisFsmStateInit_RetryJOIN()"); -+ -+ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); -+ -+ /* Retry other AuthType if possible */ -+ if (!prAisFsmInfo->ucAvailableAuthTypes) -+ return FALSE; -+ -+ if (prAisFsmInfo->ucAvailableAuthTypes & (UINT_8) AUTH_TYPE_SHARED_KEY) { -+ -+ DBGLOG(AIS, INFO, "RETRY JOIN INIT: Retry Authentication with AuthType == SHARED_KEY.\n"); -+ -+ prAisFsmInfo->ucAvailableAuthTypes &= ~(UINT_8) AUTH_TYPE_SHARED_KEY; -+ -+ prStaRec->ucAuthAlgNum = (UINT_8) AUTH_ALGORITHM_NUM_SHARED_KEY; -+ } else { -+ DBGLOG(AIS, ERROR, "RETRY JOIN INIT: Retry Authentication with Unexpected AuthType.\n"); -+ ASSERT(0); -+ } -+ -+ prAisFsmInfo->ucAvailableAuthTypes = 0; /* No more available Auth Types */ -+ -+ /* Trigger SAA to start JOIN process. */ -+ prJoinReqMsg = (P_MSG_JOIN_REQ_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_JOIN_REQ_T)); -+ if (!prJoinReqMsg) { -+ -+ ASSERT(0); /* Can't trigger SAA FSM */ -+ return FALSE; -+ } -+ -+ prJoinReqMsg->rMsgHdr.eMsgId = MID_AIS_SAA_FSM_START; -+ prJoinReqMsg->ucSeqNum = ++prAisFsmInfo->ucSeqNumOfReqMsg; -+ prJoinReqMsg->prStaRec = prStaRec; -+ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prJoinReqMsg, MSG_SEND_METHOD_BUF); -+ -+ return TRUE; -+ -+} /* end of aisFsmRetryJOIN() */ -+ -+#if CFG_SUPPORT_ADHOC -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief State Initialization of AIS_STATE_IBSS_ALONE -+* -+* @param (none) -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID aisFsmStateInit_IBSS_ALONE(IN P_ADAPTER_T prAdapter) -+{ -+ P_AIS_FSM_INFO_T prAisFsmInfo; -+ P_CONNECTION_SETTINGS_T prConnSettings; -+ P_BSS_INFO_T prAisBssInfo; -+ -+ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); -+ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); -+ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ -+ /* 4 <1> Check if IBSS was created before ? */ -+ if (prAisBssInfo->fgIsBeaconActivated) { -+ -+ /* 4 <2> Start IBSS Alone Timer for periodic SCAN and then SEARCH */ -+#if !CFG_SLT_SUPPORT -+ cnmTimerStartTimer(prAdapter, &prAisFsmInfo->rIbssAloneTimer, SEC_TO_MSEC(AIS_IBSS_ALONE_TIMEOUT_SEC)); -+#endif -+ } -+ -+ aisFsmCreateIBSS(prAdapter); -+ -+} /* end of aisFsmStateInit_IBSS_ALONE() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief State Initialization of AIS_STATE_IBSS_MERGE -+* -+* @param[in] prBssDesc The pointer of BSS_DESC_T which is the IBSS we will try to merge with. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID aisFsmStateInit_IBSS_MERGE(IN P_ADAPTER_T prAdapter, P_BSS_DESC_T prBssDesc) -+{ -+ P_AIS_FSM_INFO_T prAisFsmInfo; -+ P_CONNECTION_SETTINGS_T prConnSettings; -+ P_BSS_INFO_T prAisBssInfo; -+ P_STA_RECORD_T prStaRec = (P_STA_RECORD_T) NULL; -+ -+ ASSERT(prBssDesc); -+ -+ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); -+ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); -+ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ -+ /* 4 <1> We will merge with to this BSS immediately. */ -+ prBssDesc->fgIsConnecting = FALSE; -+ prBssDesc->fgIsConnected = TRUE; -+ -+ /* 4 <2> Setup corresponding STA_RECORD_T */ -+ prStaRec = bssCreateStaRecFromBssDesc(prAdapter, STA_TYPE_ADHOC_PEER, NETWORK_TYPE_AIS_INDEX, prBssDesc); -+ if (prStaRec == NULL) { -+ DBGLOG(AIS, WARN, "Create station record fail\n"); -+ return; -+ } -+ -+ prStaRec->fgIsMerging = TRUE; -+ -+ prAisFsmInfo->prTargetStaRec = prStaRec; -+ -+ /* 4 <2.1> sync. to firmware domain */ -+ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); -+ -+ /* 4 <3> IBSS-Merge */ -+ aisFsmMergeIBSS(prAdapter, prStaRec); -+ -+} /* end of aisFsmStateInit_IBSS_MERGE() */ -+ -+#endif /* CFG_SUPPORT_ADHOC */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Process of JOIN Abort -+* -+* @param (none) -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID aisFsmStateAbort_JOIN(IN P_ADAPTER_T prAdapter) -+{ -+ P_AIS_FSM_INFO_T prAisFsmInfo; -+ P_MSG_JOIN_ABORT_T prJoinAbortMsg; -+ -+ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); -+ -+ /* 1. Abort JOIN process */ -+ prJoinAbortMsg = (P_MSG_JOIN_ABORT_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_JOIN_ABORT_T)); -+ if (!prJoinAbortMsg) { -+ -+ ASSERT(0); /* Can't abort SAA FSM */ -+ return; -+ } -+ -+ prJoinAbortMsg->rMsgHdr.eMsgId = MID_AIS_SAA_FSM_ABORT; -+ prJoinAbortMsg->ucSeqNum = prAisFsmInfo->ucSeqNumOfReqMsg; -+ prJoinAbortMsg->prStaRec = prAisFsmInfo->prTargetStaRec; -+ -+ scanRemoveConnFlagOfBssDescByBssid(prAdapter, prAisFsmInfo->prTargetStaRec->aucMacAddr); -+ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prJoinAbortMsg, MSG_SEND_METHOD_BUF); -+ -+ /* 2. Return channel privilege */ -+ aisFsmReleaseCh(prAdapter); -+ -+ /* 3.1 stop join timeout timer */ -+ cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rJoinTimeoutTimer); -+ -+ /* 3.2 reset local variable */ -+ prAisFsmInfo->fgIsInfraChannelFinished = TRUE; -+ prAdapter->rWifiVar.rConnSettings.fgIsConnReqIssued = FALSE; -+ -+} /* end of aisFsmAbortJOIN() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Process of SCAN Abort -+* -+* @param (none) -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID aisFsmStateAbort_SCAN(IN P_ADAPTER_T prAdapter) -+{ -+ P_AIS_FSM_INFO_T prAisFsmInfo; -+ P_MSG_SCN_SCAN_CANCEL prScanCancelMsg; -+ -+ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); -+ -+ /* Abort JOIN process. */ -+ prScanCancelMsg = (P_MSG_SCN_SCAN_CANCEL) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_SCN_SCAN_CANCEL)); -+ if (!prScanCancelMsg) { -+ -+ ASSERT(0); /* Can't abort SCN FSM */ -+ return; -+ } -+ -+ prScanCancelMsg->rMsgHdr.eMsgId = MID_AIS_SCN_SCAN_CANCEL; -+ prScanCancelMsg->ucSeqNum = prAisFsmInfo->ucSeqNumOfScanReq; -+ prScanCancelMsg->ucNetTypeIndex = (UINT_8) NETWORK_TYPE_AIS_INDEX; -+#if CFG_ENABLE_WIFI_DIRECT -+ if (prAdapter->fgIsP2PRegistered) -+ prScanCancelMsg->fgIsChannelExt = FALSE; -+#endif -+ -+ /* unbuffered message to guarantee scan is cancelled in sequence */ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prScanCancelMsg, MSG_SEND_METHOD_UNBUF); -+ -+} /* end of aisFsmAbortSCAN() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Process of NORMAL_TR Abort -+* -+* @param (none) -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID aisFsmStateAbort_NORMAL_TR(IN P_ADAPTER_T prAdapter) -+{ -+ P_AIS_FSM_INFO_T prAisFsmInfo; -+ -+ ASSERT(prAdapter); -+ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); -+ -+ DBGLOG(AIS, TRACE, "aisFsmStateAbort_NORMAL_TR\n"); -+ -+ /* TODO(Kevin): Do abort other MGMT func */ -+ -+ /* 1. Release channel to CNM */ -+ aisFsmReleaseCh(prAdapter); -+ -+ /* 2.1 stop join timeout timer */ -+ cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rJoinTimeoutTimer); -+ -+ /* 2.2 reset local variable */ -+ prAisFsmInfo->fgIsInfraChannelFinished = TRUE; -+ -+} /* end of aisFsmAbortNORMAL_TR() */ -+ -+#if CFG_SUPPORT_ADHOC -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Process of NORMAL_TR Abort -+* -+* @param (none) -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID aisFsmStateAbort_IBSS(IN P_ADAPTER_T prAdapter) -+{ -+ P_AIS_FSM_INFO_T prAisFsmInfo; -+ P_BSS_DESC_T prBssDesc; -+ -+ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); -+ -+ /* reset BSS-DESC */ -+ if (prAisFsmInfo->prTargetStaRec) { -+ prBssDesc = scanSearchBssDescByTA(prAdapter, prAisFsmInfo->prTargetStaRec->aucMacAddr); -+ -+ if (prBssDesc) { -+ prBssDesc->fgIsConnected = FALSE; -+ prBssDesc->fgIsConnecting = FALSE; -+ } -+ } -+ /* release channel privilege */ -+ aisFsmReleaseCh(prAdapter); -+ -+} -+#endif /* CFG_SUPPORT_ADHOC */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief The Core FSM engine of AIS(Ad-hoc, Infra STA) -+* -+* @param[in] eNextState Enum value of next AIS STATE -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID aisFsmSteps(IN P_ADAPTER_T prAdapter, ENUM_AIS_STATE_T eNextState) -+{ -+ P_AIS_FSM_INFO_T prAisFsmInfo; -+ P_BSS_INFO_T prAisBssInfo; -+ P_CONNECTION_SETTINGS_T prConnSettings; -+ P_BSS_DESC_T prBssDesc; -+ P_MSG_CH_REQ_T prMsgChReq; -+ P_MSG_SCN_SCAN_REQ prScanReqMsg; -+ P_AIS_REQ_HDR_T prAisReq; -+ ENUM_BAND_T eBand; -+ UINT_8 ucChannel; -+ UINT_16 u2ScanIELen; -+ ENUM_AIS_STATE_T eOriPreState; -+ -+ BOOLEAN fgIsTransition = (BOOLEAN) FALSE; -+ -+ DEBUGFUNC("aisFsmSteps()"); -+ -+ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); -+ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); -+ eOriPreState = prAisFsmInfo->ePreviousState; -+ -+ do { -+ -+ /* Do entering Next State */ -+ prAisFsmInfo->ePreviousState = prAisFsmInfo->eCurrentState; -+ -+#if DBG -+ DBGLOG(AIS, STATE, "TRANSITION: [%s] -> [%s]\n", -+ apucDebugAisState[prAisFsmInfo->eCurrentState], apucDebugAisState[eNextState]); -+#else -+ DBGLOG(AIS, STATE, "[%d] TRANSITION: [%d] -> [%d]\n", -+ DBG_AIS_IDX, prAisFsmInfo->eCurrentState, eNextState); -+#endif -+ /* NOTE(Kevin): This is the only place to change the eCurrentState(except initial) */ -+ prAisFsmInfo->eCurrentState = eNextState; -+ -+ fgIsTransition = (BOOLEAN) FALSE; -+ -+ /* Do tasks of the State that we just entered */ -+ switch (prAisFsmInfo->eCurrentState) { -+ /* NOTE(Kevin): we don't have to rearrange the sequence of following -+ * switch case. Instead I would like to use a common lookup table of array -+ * of function pointer to speed up state search. -+ */ -+ case AIS_STATE_IDLE: -+ -+ prAisReq = aisFsmGetNextRequest(prAdapter); -+ -+ cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rScanDoneTimer); -+ -+ if (prAisReq == NULL || prAisReq->eReqType == AIS_REQUEST_RECONNECT) { -+ if (prConnSettings->fgIsConnReqIssued == TRUE && -+ prConnSettings->fgIsDisconnectedByNonRequest == FALSE) { -+ -+ prAisFsmInfo->fgTryScan = TRUE; -+ -+ SET_NET_ACTIVE(prAdapter, NETWORK_TYPE_AIS_INDEX); -+ SET_NET_PWR_STATE_ACTIVE(prAdapter, NETWORK_TYPE_AIS_INDEX); -+ -+ /* sync with firmware */ -+ nicActivateNetwork(prAdapter, NETWORK_TYPE_AIS_INDEX); -+ -+ /* reset trial count */ -+ prAisFsmInfo->ucConnTrialCount = 0; -+ -+ eNextState = AIS_STATE_SEARCH; -+ fgIsTransition = TRUE; -+ } else { -+ UNSET_NET_ACTIVE(prAdapter, NETWORK_TYPE_AIS_INDEX); -+ SET_NET_PWR_STATE_IDLE(prAdapter, NETWORK_TYPE_AIS_INDEX); -+ -+ /* sync with firmware */ -+ nicDeactivateNetwork(prAdapter, NETWORK_TYPE_AIS_INDEX); -+ -+ /* check for other pending request */ -+ if (prAisReq && -+ (aisFsmIsRequestPending(prAdapter, AIS_REQUEST_SCAN, TRUE) == TRUE)) { -+ -+ wlanClearScanningResult(prAdapter); -+ eNextState = AIS_STATE_SCAN; -+ -+ fgIsTransition = TRUE; -+ } -+ } -+ -+ if (prAisReq) { -+ /* free the message */ -+ cnmMemFree(prAdapter, prAisReq); -+ } -+ } else if (prAisReq->eReqType == AIS_REQUEST_SCAN) { -+#if CFG_SUPPORT_ROAMING -+ prAisFsmInfo->fgIsRoamingScanPending = FALSE; -+#endif /* CFG_SUPPORT_ROAMING */ -+ wlanClearScanningResult(prAdapter); -+ -+ eNextState = AIS_STATE_SCAN; -+ fgIsTransition = TRUE; -+ -+ /* free the message */ -+ cnmMemFree(prAdapter, prAisReq); -+ } else if (prAisReq->eReqType == AIS_REQUEST_ROAMING_CONNECT -+ || prAisReq->eReqType == AIS_REQUEST_ROAMING_SEARCH) { -+ /* ignore */ -+ /* free the message */ -+ cnmMemFree(prAdapter, prAisReq); -+ } else if (prAisReq->eReqType == AIS_REQUEST_REMAIN_ON_CHANNEL) { -+ eNextState = AIS_STATE_REQ_REMAIN_ON_CHANNEL; -+ fgIsTransition = TRUE; -+ -+ /* free the message */ -+ cnmMemFree(prAdapter, prAisReq); -+ } -+ -+ prAisFsmInfo->u4SleepInterval = AIS_BG_SCAN_INTERVAL_MIN_SEC; -+ -+ break; -+ -+ case AIS_STATE_SEARCH: -+ /* 4 <1> Search for a matched candidate and save it to prTargetBssDesc. */ -+#if CFG_SLT_SUPPORT -+ prBssDesc = prAdapter->rWifiVar.rSltInfo.prPseudoBssDesc; -+#else -+ prBssDesc = scanSearchBssDescByPolicy(prAdapter, NETWORK_TYPE_AIS_INDEX); -+#endif -+ /* every time BSS join failure count is integral multiples of SCN_BSS_JOIN_FAIL_THRESOLD, -+ we need to scan again to find if a new BSS is here in the ESS, -+ this can also avoid too frequency to retry the rejected AP */ -+ if (prAisFsmInfo->ePreviousState == AIS_STATE_LOOKING_FOR || -+ ((eOriPreState == AIS_STATE_ONLINE_SCAN || -+ eOriPreState == AIS_STATE_SCAN) && prAisFsmInfo->ePreviousState != eOriPreState)) { -+ /* if previous state is scan/online scan/looking for, don't try to scan again */ -+ } else if (prBssDesc && prBssDesc->ucJoinFailureCount >= SCN_BSS_JOIN_FAIL_THRESOLD && -+ ((prBssDesc->ucJoinFailureCount - SCN_BSS_JOIN_FAIL_THRESOLD) % -+ SCN_BSS_JOIN_FAIL_THRESOLD) == 0) -+ prBssDesc = NULL; -+ -+ /* we are under Roaming Condition. */ -+ if (prAisBssInfo->eConnectionState == PARAM_MEDIA_STATE_CONNECTED) { -+ if (prAisFsmInfo->ucConnTrialCount > AIS_ROAMING_CONNECTION_TRIAL_LIMIT) { -+#if CFG_SUPPORT_ROAMING -+ roamingFsmRunEventFail(prAdapter, ROAMING_FAIL_REASON_CONNLIMIT); -+#endif /* CFG_SUPPORT_ROAMING */ -+ /* reset retry count */ -+ prAisFsmInfo->ucConnTrialCount = 0; -+ -+ /* abort connection trial */ -+ prConnSettings->fgIsConnReqIssued = FALSE; -+ -+ eNextState = AIS_STATE_NORMAL_TR; -+ fgIsTransition = TRUE; -+ -+ break; -+ } -+ } -+ /* 4 <2> We are not under Roaming Condition. */ -+ if (prAisBssInfo->eConnectionState == PARAM_MEDIA_STATE_DISCONNECTED) { -+ -+ /* 4 <2.a> If we have the matched one */ -+ if (prBssDesc) { -+ -+ /* 4
Stored the Selected BSS security cipher. -+ For later asoc req compose IE */ -+ prAisBssInfo->u4RsnSelectedGroupCipher = prBssDesc->u4RsnSelectedGroupCipher; -+ prAisBssInfo->u4RsnSelectedPairwiseCipher = -+ prBssDesc->u4RsnSelectedPairwiseCipher; -+ prAisBssInfo->u4RsnSelectedAKMSuite = prBssDesc->u4RsnSelectedAKMSuite; -+ -+ /* 4 Do STATE transition and update current Operation Mode. */ -+ if (prBssDesc->eBSSType == BSS_TYPE_INFRASTRUCTURE) { -+ -+ prAisBssInfo->eCurrentOPMode = OP_MODE_INFRASTRUCTURE; -+ -+ /* Record the target BSS_DESC_T for next STATE. */ -+ prAisFsmInfo->prTargetBssDesc = prBssDesc; -+ -+ /* Transit to channel acquire */ -+ eNextState = AIS_STATE_REQ_CHANNEL_JOIN; -+ fgIsTransition = TRUE; -+ -+ /* increase connection trial count */ -+ prAisFsmInfo->ucConnTrialCount++; -+ } -+#if CFG_SUPPORT_ADHOC -+ else if (prBssDesc->eBSSType == BSS_TYPE_IBSS) { -+ -+ prAisBssInfo->eCurrentOPMode = OP_MODE_IBSS; -+ -+ /* Record the target BSS_DESC_T for next STATE. */ -+ prAisFsmInfo->prTargetBssDesc = prBssDesc; -+ -+ eNextState = AIS_STATE_IBSS_MERGE; -+ fgIsTransition = TRUE; -+ } -+#endif /* CFG_SUPPORT_ADHOC */ -+ else { -+ ASSERT(0); -+ eNextState = AIS_STATE_WAIT_FOR_NEXT_SCAN; -+ fgIsTransition = TRUE; -+ } -+ } -+ /* 4 <2.b> If we don't have the matched one */ -+ else { -+ -+ /* increase connection trial count for infrastructure connection */ -+ if (prConnSettings->eOPMode == NET_TYPE_INFRA) -+ prAisFsmInfo->ucConnTrialCount++; -+ /* 4 Try to SCAN */ -+ if (prAisFsmInfo->fgTryScan) { -+ eNextState = AIS_STATE_LOOKING_FOR; -+ -+ fgIsTransition = TRUE; -+ break; -+ } -+ /* 4 We've do SCAN already, now wait in some STATE. */ -+ if (prConnSettings->eOPMode == NET_TYPE_INFRA) { -+ -+ /* issue reconnect request, -+ * and retreat to idle state for scheduling */ -+ aisFsmInsertRequest(prAdapter, AIS_REQUEST_RECONNECT); -+ -+ eNextState = AIS_STATE_IDLE; -+ fgIsTransition = TRUE; -+ } -+#if CFG_SUPPORT_ADHOC -+ else if ((prConnSettings->eOPMode == NET_TYPE_IBSS) -+ || (prConnSettings->eOPMode == NET_TYPE_AUTO_SWITCH) -+ || (prConnSettings->eOPMode == NET_TYPE_DEDICATED_IBSS)) { -+ -+ prAisBssInfo->eCurrentOPMode = OP_MODE_IBSS; -+ prAisFsmInfo->prTargetBssDesc = NULL; -+ -+ eNextState = AIS_STATE_IBSS_ALONE; -+ fgIsTransition = TRUE; -+ } -+#endif /* CFG_SUPPORT_ADHOC */ -+ else { -+ ASSERT(0); -+ eNextState = AIS_STATE_WAIT_FOR_NEXT_SCAN; -+ fgIsTransition = TRUE; -+ } -+ } -+ } -+ /* 4 <3> We are under Roaming Condition. */ -+ else { /* prAdapter->eConnectionState == MEDIA_STATE_CONNECTED. */ -+ -+ /* 4 <3.a> This BSS_DESC_T is our AP. */ -+ /* NOTE(Kevin 2008/05/16): Following cases will go back to NORMAL_TR. -+ * CASE I: During Roaming, APP(WZC/NDISTEST) change the connection -+ * settings. That make we can NOT match the original AP, so the -+ * prBssDesc is NULL. -+ * CASE II: The same reason as CASE I. Because APP change the -+ * eOPMode to other network type in connection setting -+ * (e.g. NET_TYPE_IBSS), so the BssDesc become the IBSS node. -+ * (For CASE I/II, before WZC/NDISTEST set the OID_SSID, it will change -+ * other parameters in connection setting first. So if we do roaming -+ * at the same time, it will hit these cases.) -+ * -+ * CASE III: Normal case, we can't find other candidate to roam -+ * out, so only the current AP will be matched. -+ * -+ * CASE IV: Timestamp of the current AP might be reset -+ */ -+ if (prAisBssInfo->ucReasonOfDisconnect != DISCONNECT_REASON_CODE_REASSOCIATION && -+ ((!prBssDesc) || /* CASE I */ -+ (prBssDesc->eBSSType != BSS_TYPE_INFRASTRUCTURE) || /* CASE II */ -+ (prBssDesc->fgIsConnected) || /* CASE III */ -+ (EQUAL_MAC_ADDR(prBssDesc->aucBSSID, prAisBssInfo->aucBSSID))) /* CASE IV */) { -+#if DBG -+ if ((prBssDesc) && (prBssDesc->fgIsConnected)) -+ ASSERT(EQUAL_MAC_ADDR(prBssDesc->aucBSSID, prAisBssInfo->aucBSSID)); -+#endif /* DBG */ -+ /* We already associated with it, go back to NORMAL_TR */ -+ /* TODO(Kevin): Roaming Fail */ -+#if CFG_SUPPORT_ROAMING -+ roamingFsmRunEventFail(prAdapter, ROAMING_FAIL_REASON_NOCANDIDATE); -+#endif /* CFG_SUPPORT_ROAMING */ -+ -+ /* Retreat to NORMAL_TR state */ -+ eNextState = AIS_STATE_NORMAL_TR; -+ fgIsTransition = TRUE; -+ break; -+ } -+ -+ /* 4 <3.b> Try to roam out for JOIN this BSS_DESC_T. */ -+ if (prBssDesc == NULL) { -+ /* increase connection trial count for infrastructure connection */ -+ if (prConnSettings->eOPMode == NET_TYPE_INFRA) -+ prAisFsmInfo->ucConnTrialCount++; -+ /* 4 Try to SCAN */ -+ if (prAisFsmInfo->fgTryScan) { -+ eNextState = AIS_STATE_LOOKING_FOR; -+ -+ fgIsTransition = TRUE; -+ break; -+ } -+ -+ /* 4 We've do SCAN already, now wait in some STATE. */ -+ if (prConnSettings->eOPMode == NET_TYPE_INFRA) { -+ -+ /* issue reconnect request, and retreat to idle state -+ * for scheduling */ -+ aisFsmInsertRequest(prAdapter, AIS_REQUEST_RECONNECT); -+ -+ eNextState = AIS_STATE_IDLE; -+ fgIsTransition = TRUE; -+ } -+#if CFG_SUPPORT_ADHOC -+ else if ((prConnSettings->eOPMode == NET_TYPE_IBSS) -+ || (prConnSettings->eOPMode == NET_TYPE_AUTO_SWITCH) -+ || (prConnSettings->eOPMode == -+ NET_TYPE_DEDICATED_IBSS)) { -+ -+ prAisBssInfo->eCurrentOPMode = OP_MODE_IBSS; -+ prAisFsmInfo->prTargetBssDesc = NULL; -+ -+ eNextState = AIS_STATE_IBSS_ALONE; -+ fgIsTransition = TRUE; -+ } -+#endif /* CFG_SUPPORT_ADHOC */ -+ else { -+ ASSERT(0); -+ eNextState = AIS_STATE_WAIT_FOR_NEXT_SCAN; -+ fgIsTransition = TRUE; -+ } -+ } else { -+#if DBG -+ if (prAisBssInfo->ucReasonOfDisconnect != -+ DISCONNECT_REASON_CODE_REASSOCIATION) { -+ ASSERT(UNEQUAL_MAC_ADDR -+ (prBssDesc->aucBSSID, prAisBssInfo->aucBSSID)); -+ } -+#endif /* DBG */ -+ -+ /* 4 Record the target BSS_DESC_T for next STATE. */ -+ prAisFsmInfo->prTargetBssDesc = prBssDesc; -+ -+ /* tyhsu: increase connection trial count */ -+ prAisFsmInfo->ucConnTrialCount++; -+ -+ /* Transit to channel acquire */ -+ eNextState = AIS_STATE_REQ_CHANNEL_JOIN; -+ fgIsTransition = TRUE; -+ } -+ } -+ -+ break; -+ -+ case AIS_STATE_WAIT_FOR_NEXT_SCAN: -+ -+ DBGLOG(AIS, LOUD, "SCAN: Idle Begin - Current Time = %u\n", kalGetTimeTick()); -+ -+ cnmTimerStartTimer(prAdapter, -+ &prAisFsmInfo->rBGScanTimer, SEC_TO_MSEC(prAisFsmInfo->u4SleepInterval)); -+ -+ SET_NET_PWR_STATE_IDLE(prAdapter, NETWORK_TYPE_AIS_INDEX); -+ -+ if (prAisFsmInfo->u4SleepInterval < AIS_BG_SCAN_INTERVAL_MAX_SEC) -+ prAisFsmInfo->u4SleepInterval <<= 1; -+ break; -+ -+ case AIS_STATE_SCAN: -+ case AIS_STATE_ONLINE_SCAN: -+ case AIS_STATE_LOOKING_FOR: -+ -+ if (!IS_NET_ACTIVE(prAdapter, NETWORK_TYPE_AIS_INDEX)) { -+ SET_NET_ACTIVE(prAdapter, NETWORK_TYPE_AIS_INDEX); -+ -+ /* sync with firmware */ -+ nicActivateNetwork(prAdapter, NETWORK_TYPE_AIS_INDEX); -+ } -+ -+ /* IE length decision */ -+ if (prAisFsmInfo->u4ScanIELength > 0) { -+ u2ScanIELen = (UINT_16) prAisFsmInfo->u4ScanIELength; -+ } else { -+#if CFG_SUPPORT_WPS2 -+ u2ScanIELen = prAdapter->prGlueInfo->u2WSCIELen; -+#else -+ u2ScanIELen = 0; -+#endif -+ } -+ -+ prScanReqMsg = (P_MSG_SCN_SCAN_REQ) cnmMemAlloc(prAdapter, -+ RAM_TYPE_MSG, -+ OFFSET_OF(MSG_SCN_SCAN_REQ, -+ aucIE) + u2ScanIELen); -+ if (!prScanReqMsg) { -+ ASSERT(0); /* Can't trigger SCAN FSM */ -+ return; -+ } -+ -+ prScanReqMsg->rMsgHdr.eMsgId = MID_AIS_SCN_SCAN_REQ; -+ prScanReqMsg->ucSeqNum = ++prAisFsmInfo->ucSeqNumOfScanReq; -+ prScanReqMsg->ucNetTypeIndex = (UINT_8) NETWORK_TYPE_AIS_INDEX; -+ -+#if CFG_SUPPORT_RDD_TEST_MODE -+ prScanReqMsg->eScanType = SCAN_TYPE_PASSIVE_SCAN; -+#else -+ prScanReqMsg->eScanType = SCAN_TYPE_ACTIVE_SCAN; -+#endif -+ -+#if CFG_SUPPORT_ROAMING_ENC -+ if (prAdapter->fgIsRoamingEncEnabled == TRUE) { -+ if (prAisFsmInfo->eCurrentState == AIS_STATE_LOOKING_FOR && -+ prAisBssInfo->eConnectionState == PARAM_MEDIA_STATE_CONNECTED) { -+ prScanReqMsg->u2ChannelDwellTime = AIS_ROAMING_SCAN_CHANNEL_DWELL_TIME; -+ } -+ } -+#endif /* CFG_SUPPORT_ROAMING_ENC */ -+ -+ if (prAisFsmInfo->eCurrentState == AIS_STATE_SCAN -+ || prAisFsmInfo->eCurrentState == AIS_STATE_ONLINE_SCAN) { -+ if (prAisFsmInfo->ucScanSSIDLen == 0) { -+ /* Scan for all available SSID */ -+ prScanReqMsg->ucSSIDType = SCAN_REQ_SSID_WILDCARD; -+ } else { -+ prScanReqMsg->ucSSIDType = SCAN_REQ_SSID_SPECIFIED; -+ COPY_SSID(prScanReqMsg->aucSSID, -+ prScanReqMsg->ucSSIDLength, -+ prAisFsmInfo->aucScanSSID, prAisFsmInfo->ucScanSSIDLen); -+ } -+ } else { -+ /* Scan for determined SSID */ -+ prScanReqMsg->ucSSIDType = SCAN_REQ_SSID_SPECIFIED; -+ COPY_SSID(prScanReqMsg->aucSSID, -+ prScanReqMsg->ucSSIDLength, -+ prConnSettings->aucSSID, prConnSettings->ucSSIDLen); -+ } -+ -+ /* check if tethering is running and need to fix on specific channel */ -+ if (cnmAisInfraChannelFixed(prAdapter, &eBand, &ucChannel) == TRUE) { -+ prScanReqMsg->eScanChannel = SCAN_CHANNEL_SPECIFIED; -+ prScanReqMsg->ucChannelListNum = 1; -+ prScanReqMsg->arChnlInfoList[0].eBand = eBand; -+ prScanReqMsg->arChnlInfoList[0].ucChannelNum = ucChannel; -+ } else { -+#if 0 -+ aisFsmSetChannelInfo(prAdapter, prScanReqMsg, prAisFsmInfo->eCurrentState); -+#endif -+ if (prAdapter->aePreferBand[NETWORK_TYPE_AIS_INDEX] -+ == BAND_NULL) { -+ if (prAdapter->fgEnable5GBand == TRUE) -+ prScanReqMsg->eScanChannel = SCAN_CHANNEL_FULL; -+ else -+ prScanReqMsg->eScanChannel = SCAN_CHANNEL_2G4; -+ } else if (prAdapter->aePreferBand[NETWORK_TYPE_AIS_INDEX] -+ == BAND_2G4) { -+ prScanReqMsg->eScanChannel = SCAN_CHANNEL_2G4; -+ } else if (prAdapter->aePreferBand[NETWORK_TYPE_AIS_INDEX] -+ == BAND_5G) { -+ prScanReqMsg->eScanChannel = SCAN_CHANNEL_5G; -+ } else { -+ prScanReqMsg->eScanChannel = SCAN_CHANNEL_FULL; -+ ASSERT(0); -+ } -+ -+ } -+ -+ if (prAisFsmInfo->u4ScanIELength > 0) { -+ kalMemCopy(prScanReqMsg->aucIE, prAisFsmInfo->aucScanIEBuf, -+ prAisFsmInfo->u4ScanIELength); -+ } else { -+#if CFG_SUPPORT_WPS2 -+ if (prAdapter->prGlueInfo->u2WSCIELen > 0) { -+ kalMemCopy(prScanReqMsg->aucIE, &prAdapter->prGlueInfo->aucWSCIE, -+ prAdapter->prGlueInfo->u2WSCIELen); -+ } -+ } -+#endif -+ -+ prScanReqMsg->u2IELen = u2ScanIELen; -+ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prScanReqMsg, MSG_SEND_METHOD_BUF); -+ DBGLOG(AIS, TRACE, "SendSR%d\n", prScanReqMsg->ucSeqNum); -+ prAisFsmInfo->fgTryScan = FALSE; /* Will enable background sleep for infrastructure */ -+ -+ prAdapter->ucScanTime++; -+ break; -+ -+ case AIS_STATE_REQ_CHANNEL_JOIN: -+ /* send message to CNM for acquiring channel */ -+ prMsgChReq = (P_MSG_CH_REQ_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_CH_REQ_T)); -+ if (!prMsgChReq) { -+ ASSERT(0); /* Can't indicate CNM for channel acquiring */ -+ return; -+ } -+ -+ prMsgChReq->rMsgHdr.eMsgId = MID_MNY_CNM_CH_REQ; -+ prMsgChReq->ucNetTypeIndex = NETWORK_TYPE_AIS_INDEX; -+ prMsgChReq->ucTokenID = ++prAisFsmInfo->ucSeqNumOfChReq; -+ prMsgChReq->eReqType = CH_REQ_TYPE_JOIN; -+ prMsgChReq->u4MaxInterval = AIS_JOIN_CH_REQUEST_INTERVAL; -+ -+ if (prAisFsmInfo->prTargetBssDesc != NULL) { -+ prMsgChReq->ucPrimaryChannel = prAisFsmInfo->prTargetBssDesc->ucChannelNum; -+ prMsgChReq->eRfSco = prAisFsmInfo->prTargetBssDesc->eSco; -+ prMsgChReq->eRfBand = prAisFsmInfo->prTargetBssDesc->eBand; -+ COPY_MAC_ADDR(prMsgChReq->aucBSSID, prAisFsmInfo->prTargetBssDesc->aucBSSID); -+ } -+ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgChReq, MSG_SEND_METHOD_BUF); -+ -+ prAisFsmInfo->fgIsChannelRequested = TRUE; -+ break; -+ -+ case AIS_STATE_JOIN: -+ aisFsmStateInit_JOIN(prAdapter, prAisFsmInfo->prTargetBssDesc); -+ break; -+ -+#if CFG_SUPPORT_ADHOC -+ case AIS_STATE_IBSS_ALONE: -+ aisFsmStateInit_IBSS_ALONE(prAdapter); -+ break; -+ -+ case AIS_STATE_IBSS_MERGE: -+ aisFsmStateInit_IBSS_MERGE(prAdapter, prAisFsmInfo->prTargetBssDesc); -+ break; -+#endif /* CFG_SUPPORT_ADHOC */ -+ -+ case AIS_STATE_NORMAL_TR: -+ if (prAisFsmInfo->fgIsInfraChannelFinished == FALSE) { -+ /* Don't do anything when rJoinTimeoutTimer is still ticking */ -+ } else { -+ /* 1. Process for pending scan */ -+ if (aisFsmIsRequestPending(prAdapter, AIS_REQUEST_SCAN, TRUE) == TRUE) { -+ wlanClearScanningResult(prAdapter); -+ eNextState = AIS_STATE_ONLINE_SCAN; -+ fgIsTransition = TRUE; -+ } -+ /* 2. Process for pending roaming scan */ -+ else if (aisFsmIsRequestPending(prAdapter, AIS_REQUEST_ROAMING_SEARCH, TRUE) == TRUE) { -+ eNextState = AIS_STATE_LOOKING_FOR; -+ fgIsTransition = TRUE; -+ } -+ /* 3. Process for pending roaming scan */ -+ else if (aisFsmIsRequestPending(prAdapter, AIS_REQUEST_ROAMING_CONNECT, TRUE) == TRUE) { -+ eNextState = AIS_STATE_SEARCH; -+ fgIsTransition = TRUE; -+ } else if (aisFsmIsRequestPending(prAdapter, AIS_REQUEST_REMAIN_ON_CHANNEL, TRUE) == -+ TRUE) { -+ eNextState = AIS_STATE_REQ_REMAIN_ON_CHANNEL; -+ fgIsTransition = TRUE; -+ } -+ } -+ -+ break; -+ -+ case AIS_STATE_DISCONNECTING: -+ /* send for deauth frame for disconnection */ -+ authSendDeauthFrame(prAdapter, -+ prAisBssInfo->prStaRecOfAP, -+ (P_SW_RFB_T) NULL, REASON_CODE_DEAUTH_LEAVING_BSS, aisDeauthXmitComplete); -+ cnmTimerStartTimer(prAdapter, &prAisFsmInfo->rDeauthDoneTimer, 100); -+ break; -+ -+ case AIS_STATE_REQ_REMAIN_ON_CHANNEL: -+ /* send message to CNM for acquiring channel */ -+ prMsgChReq = (P_MSG_CH_REQ_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_CH_REQ_T)); -+ if (!prMsgChReq) { -+ ASSERT(0); /* Can't indicate CNM for channel acquiring */ -+ return; -+ } -+ -+ /* zero-ize */ -+ kalMemZero(prMsgChReq, sizeof(MSG_CH_REQ_T)); -+ -+ /* filling */ -+ prMsgChReq->rMsgHdr.eMsgId = MID_MNY_CNM_CH_REQ; -+ prMsgChReq->ucNetTypeIndex = NETWORK_TYPE_AIS_INDEX; -+ prMsgChReq->ucTokenID = ++prAisFsmInfo->ucSeqNumOfChReq; -+ prMsgChReq->eReqType = CH_REQ_TYPE_JOIN; -+ prMsgChReq->u4MaxInterval = prAisFsmInfo->rChReqInfo.u4DurationMs; -+ prMsgChReq->ucPrimaryChannel = prAisFsmInfo->rChReqInfo.ucChannelNum; -+ prMsgChReq->eRfSco = prAisFsmInfo->rChReqInfo.eSco; -+ prMsgChReq->eRfBand = prAisFsmInfo->rChReqInfo.eBand; -+ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgChReq, MSG_SEND_METHOD_BUF); -+ -+ prAisFsmInfo->fgIsChannelRequested = TRUE; -+ -+ break; -+ -+ case AIS_STATE_REMAIN_ON_CHANNEL: -+ SET_NET_ACTIVE(prAdapter, NETWORK_TYPE_AIS_INDEX); -+ /* sync with firmware */ -+ nicActivateNetwork(prAdapter, NETWORK_TYPE_AIS_INDEX); -+ break; -+ -+ default: -+ ASSERT(0); /* Make sure we have handle all STATEs */ -+ break; -+ -+ } -+ } while (fgIsTransition); -+ -+ return; -+ -+} /* end of aisFsmSteps() */ -+#if 0 -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID aisFsmSetChannelInfo(IN P_ADAPTER_T prAdapter, IN P_MSG_SCN_SCAN_REQ ScanReqMsg, IN ENUM_AIS_STATE_T CurrentState) -+{ -+ /*get scan channel infro from prAdapter->prGlueInfo->prScanRequest*/ -+ struct cfg80211_scan_request *scan_req_t = NULL; -+ struct ieee80211_channel *channel_tmp = NULL; -+ int i = 0; -+ int j = 0; -+ UINT_8 channel_num = 0; -+ UINT_8 channel_counts = 0; -+ -+ if ((prAdapter == NULL) || (ScanReqMsg == NULL)) -+ return; -+ if ((CurrentState == AIS_STATE_SCAN) || (CurrentState == AIS_STATE_ONLINE_SCAN)) { -+ if (prAdapter->prGlueInfo->prScanRequest != NULL) { -+ scan_req_t = prAdapter->prGlueInfo->prScanRequest; -+ if ((scan_req_t != NULL) && (scan_req_t->n_channels != 0) && -+ (scan_req_t->channels != NULL)) { -+ channel_counts = scan_req_t->n_channels; -+ DBGLOG(AIS, TRACE, "channel_counts=%d\n", channel_counts); -+ -+ while (j < channel_counts) { -+ channel_tmp = scan_req_t->channels[j]; -+ if (channel_tmp == NULL) -+ break; -+ -+ DBGLOG(AIS, TRACE, "set channel band=%d\n", channel_tmp->band); -+ if (channel_tmp->band >= IEEE80211_BAND_60GHZ) { -+ j++; -+ continue; -+ } -+ if (i >= MAXIMUM_OPERATION_CHANNEL_LIST) -+ break; -+ if (channel_tmp->band == IEEE80211_BAND_2GHZ) -+ ScanReqMsg->arChnlInfoList[i].eBand = BAND_2G4; -+ else if (channel_tmp->band == IEEE80211_BAND_5GHZ) -+ ScanReqMsg->arChnlInfoList[i].eBand = BAND_5G; -+ -+ DBGLOG(AIS, TRACE, "set channel channel_rer =%d\n", -+ channel_tmp->center_freq); -+ -+ channel_num = (UINT_8)nicFreq2ChannelNum( -+ channel_tmp->center_freq * 1000); -+ -+ DBGLOG(AIS, TRACE, "set channel channel_num=%d\n", -+ channel_num); -+ ScanReqMsg->arChnlInfoList[i].ucChannelNum = channel_num; -+ -+ j++; -+ i++; -+ } -+ } -+ } -+ } -+ -+ DBGLOG(AIS, INFO, "set channel i=%d\n", i); -+ if (i > 0) { -+ ScanReqMsg->ucChannelListNum = i; -+ ScanReqMsg->eScanChannel = SCAN_CHANNEL_SPECIFIED; -+ -+ return; -+ } -+ -+ if (prAdapter->aePreferBand[NETWORK_TYPE_AIS_INDEX] -+ == BAND_NULL) { -+ if (prAdapter->fgEnable5GBand == TRUE) -+ ScanReqMsg->eScanChannel = SCAN_CHANNEL_FULL; -+ else -+ ScanReqMsg->eScanChannel = SCAN_CHANNEL_2G4; -+ } else if (prAdapter->aePreferBand[NETWORK_TYPE_AIS_INDEX] -+ == BAND_2G4) { -+ ScanReqMsg->eScanChannel = SCAN_CHANNEL_2G4; -+ } else if (prAdapter->aePreferBand[NETWORK_TYPE_AIS_INDEX] -+ == BAND_5G) { -+ ScanReqMsg->eScanChannel = SCAN_CHANNEL_5G; -+ } else { -+ ScanReqMsg->eScanChannel = SCAN_CHANNEL_FULL; -+ ASSERT(0); -+ } -+ -+ -+} -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+ -+VOID aisFsmRunEventScanDone(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) -+{ -+ P_MSG_SCN_SCAN_DONE prScanDoneMsg; -+ P_AIS_FSM_INFO_T prAisFsmInfo; -+ ENUM_AIS_STATE_T eNextState; -+ UINT_8 ucSeqNumOfCompMsg; -+ P_CONNECTION_SETTINGS_T prConnSettings; -+ -+ DEBUGFUNC("aisFsmRunEventScanDone()"); -+ -+ ASSERT(prAdapter); -+ ASSERT(prMsgHdr); -+ -+ ucScanTimeoutTimes = 0; -+ -+ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); -+ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); -+ -+ prScanDoneMsg = (P_MSG_SCN_SCAN_DONE) prMsgHdr; -+ ASSERT(prScanDoneMsg->ucNetTypeIndex == (UINT_8) NETWORK_TYPE_AIS_INDEX); -+ -+ ucSeqNumOfCompMsg = prScanDoneMsg->ucSeqNum; -+ cnmMemFree(prAdapter, prMsgHdr); -+ -+ eNextState = prAisFsmInfo->eCurrentState; -+ -+ if (ucSeqNumOfCompMsg != prAisFsmInfo->ucSeqNumOfScanReq) { -+ DBGLOG(AIS, WARN, "SEQ NO of AIS SCN DONE MSG is not matched %d %d.\n", -+ ucSeqNumOfCompMsg, prAisFsmInfo->ucSeqNumOfScanReq); -+ } else { -+ switch (prAisFsmInfo->eCurrentState) { -+ case AIS_STATE_SCAN: -+ prConnSettings->fgIsScanReqIssued = FALSE; -+ -+ /* reset scan IE buffer */ -+ prAisFsmInfo->u4ScanIELength = 0; -+ -+ kalScanDone(prAdapter->prGlueInfo, KAL_NETWORK_TYPE_AIS_INDEX, WLAN_STATUS_SUCCESS); -+ eNextState = AIS_STATE_IDLE; -+#if CFG_SUPPORT_AGPS_ASSIST -+ scanReportScanResultToAgps(prAdapter); -+#endif -+ break; -+ -+ case AIS_STATE_ONLINE_SCAN: -+ prConnSettings->fgIsScanReqIssued = FALSE; -+ -+ /* reset scan IE buffer */ -+ prAisFsmInfo->u4ScanIELength = 0; -+ -+ kalScanDone(prAdapter->prGlueInfo, KAL_NETWORK_TYPE_AIS_INDEX, WLAN_STATUS_SUCCESS); -+#if CFG_SUPPORT_ROAMING -+ eNextState = aisFsmRoamingScanResultsUpdate(prAdapter); -+#else -+ eNextState = AIS_STATE_NORMAL_TR; -+#endif /* CFG_SUPPORT_ROAMING */ -+#if CFG_SUPPORT_AGPS_ASSIST -+ scanReportScanResultToAgps(prAdapter); -+#endif -+ break; -+ -+ case AIS_STATE_LOOKING_FOR: -+ cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rScanDoneTimer); -+ scanReportBss2Cfg80211(prAdapter, BSS_TYPE_INFRASTRUCTURE, NULL); -+#if CFG_SUPPORT_ROAMING -+ eNextState = aisFsmRoamingScanResultsUpdate(prAdapter); -+#else -+ eNextState = AIS_STATE_SEARCH; -+#endif /* CFG_SUPPORT_ROAMING */ -+ break; -+ -+ default: -+ cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rScanDoneTimer); -+ break; -+ -+ } -+ } -+ -+ if (eNextState != prAisFsmInfo->eCurrentState) -+ aisFsmSteps(prAdapter, eNextState); -+ -+} /* end of aisFsmRunEventScanDone() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID aisFsmRunEventAbort(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) -+{ -+ P_MSG_AIS_ABORT_T prAisAbortMsg; -+ P_AIS_FSM_INFO_T prAisFsmInfo; -+ UINT_8 ucReasonOfDisconnect; -+ BOOLEAN fgDelayIndication; -+ P_CONNECTION_SETTINGS_T prConnSettings; -+ -+ DEBUGFUNC("aisFsmRunEventAbort()"); -+ -+ ASSERT(prAdapter); -+ ASSERT(prMsgHdr); -+ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); -+ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); -+ -+ /* 4 <1> Extract information of Abort Message and then free memory. */ -+ prAisAbortMsg = (P_MSG_AIS_ABORT_T) prMsgHdr; -+ ucReasonOfDisconnect = prAisAbortMsg->ucReasonOfDisconnect; -+ fgDelayIndication = prAisAbortMsg->fgDelayIndication; -+ -+ cnmMemFree(prAdapter, prMsgHdr); -+ -+#if DBG -+ DBGLOG(AIS, STATE, "EVENT-ABORT: Current State %s %d\n", -+ apucDebugAisState[prAisFsmInfo->eCurrentState], ucReasonOfDisconnect); -+#else -+ DBGLOG(AIS, STATE, "[%d] EVENT-ABORT: Current State [%d %d]\n", -+ DBG_AIS_IDX, prAisFsmInfo->eCurrentState, ucReasonOfDisconnect); -+#endif -+ -+ GET_CURRENT_SYSTIME(&(prAisFsmInfo->rJoinReqTime)); -+ -+ /* 4 <2> clear previous pending connection request and insert new one */ -+ if (ucReasonOfDisconnect == DISCONNECT_REASON_CODE_DEAUTHENTICATED -+ || ucReasonOfDisconnect == DISCONNECT_REASON_CODE_DISASSOCIATED) { -+ prConnSettings->fgIsDisconnectedByNonRequest = TRUE; -+ } else { -+ prConnSettings->fgIsDisconnectedByNonRequest = FALSE; -+ } -+ /* to support user space triggered roaming */ -+ if (ucReasonOfDisconnect == DISCONNECT_REASON_CODE_ROAMING && -+ prAisFsmInfo->eCurrentState != AIS_STATE_DISCONNECTING) { -+ -+ if (prAisFsmInfo->eCurrentState == AIS_STATE_NORMAL_TR && -+ prAisFsmInfo->fgIsInfraChannelFinished == TRUE) { -+ aisFsmSteps(prAdapter, AIS_STATE_SEARCH); -+ } else { -+ aisFsmIsRequestPending(prAdapter, AIS_REQUEST_ROAMING_SEARCH, TRUE); -+ aisFsmIsRequestPending(prAdapter, AIS_REQUEST_ROAMING_CONNECT, TRUE); -+ aisFsmInsertRequest(prAdapter, AIS_REQUEST_ROAMING_CONNECT); -+ } -+ return; -+ } -+ -+ aisFsmIsRequestPending(prAdapter, AIS_REQUEST_RECONNECT, TRUE); -+ aisFsmInsertRequest(prAdapter, AIS_REQUEST_RECONNECT); -+ -+ if (prAisFsmInfo->eCurrentState != AIS_STATE_DISCONNECTING) { -+ /* 4 <3> invoke abort handler */ -+ aisFsmStateAbort(prAdapter, ucReasonOfDisconnect, fgDelayIndication); -+ } -+ -+} /* end of aisFsmRunEventAbort() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function handles AIS-FSM abort event/command -+* -+* \param[in] prAdapter Pointer of ADAPTER_T -+* ucReasonOfDisconnect Reason for disonnection -+* fgDelayIndication Option to delay disconnection indication -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID aisFsmStateAbort(IN P_ADAPTER_T prAdapter, UINT_8 ucReasonOfDisconnect, BOOLEAN fgDelayIndication) -+{ -+ P_AIS_FSM_INFO_T prAisFsmInfo; -+ P_BSS_INFO_T prAisBssInfo; -+ P_CONNECTION_SETTINGS_T prConnSettings; -+ BOOLEAN fgIsCheckConnected; -+ -+ ASSERT(prAdapter); -+ -+ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); -+ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); -+ fgIsCheckConnected = FALSE; -+ -+ /* 4 <1> Save information of Abort Message and then free memory. */ -+ prAisBssInfo->ucReasonOfDisconnect = ucReasonOfDisconnect; -+ -+ /* 4 <2> Abort current job. */ -+ switch (prAisFsmInfo->eCurrentState) { -+ case AIS_STATE_IDLE: -+ case AIS_STATE_SEARCH: -+ break; -+ -+ case AIS_STATE_WAIT_FOR_NEXT_SCAN: -+ /* Do cancel timer */ -+ cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rBGScanTimer); -+ -+ /* in case roaming is triggered */ -+ fgIsCheckConnected = TRUE; -+ break; -+ -+ case AIS_STATE_SCAN: -+ /* Do abort SCAN */ -+ aisFsmStateAbort_SCAN(prAdapter); -+ -+ /* queue for later handling */ -+ if (aisFsmIsRequestPending(prAdapter, AIS_REQUEST_SCAN, FALSE) == FALSE) -+ aisFsmInsertRequest(prAdapter, AIS_REQUEST_SCAN); -+ -+ break; -+ -+ case AIS_STATE_LOOKING_FOR: -+ /* Do abort SCAN */ -+ aisFsmStateAbort_SCAN(prAdapter); -+ -+ /* in case roaming is triggered */ -+ fgIsCheckConnected = TRUE; -+ break; -+ -+ case AIS_STATE_REQ_CHANNEL_JOIN: -+ /* Release channel to CNM */ -+ aisFsmReleaseCh(prAdapter); -+ -+ /* in case roaming is triggered */ -+ fgIsCheckConnected = TRUE; -+ break; -+ -+ case AIS_STATE_JOIN: -+ /* Do abort JOIN */ -+ aisFsmStateAbort_JOIN(prAdapter); -+ -+ /* in case roaming is triggered */ -+ fgIsCheckConnected = TRUE; -+ break; -+ -+#if CFG_SUPPORT_ADHOC -+ case AIS_STATE_IBSS_ALONE: -+ case AIS_STATE_IBSS_MERGE: -+ aisFsmStateAbort_IBSS(prAdapter); -+ break; -+#endif /* CFG_SUPPORT_ADHOC */ -+ -+ case AIS_STATE_ONLINE_SCAN: -+ /* Do abort SCAN */ -+ aisFsmStateAbort_SCAN(prAdapter); -+ -+ /* queue for later handling */ -+ if (aisFsmIsRequestPending(prAdapter, AIS_REQUEST_SCAN, FALSE) == FALSE) -+ aisFsmInsertRequest(prAdapter, AIS_REQUEST_SCAN); -+ -+ fgIsCheckConnected = TRUE; -+ break; -+ -+ case AIS_STATE_NORMAL_TR: -+ fgIsCheckConnected = TRUE; -+ break; -+ -+ case AIS_STATE_DISCONNECTING: -+ /* Do abort NORMAL_TR */ -+ aisFsmStateAbort_NORMAL_TR(prAdapter); -+ -+ break; -+ -+ case AIS_STATE_REQ_REMAIN_ON_CHANNEL: -+ /* release channel */ -+ aisFsmReleaseCh(prAdapter); -+ break; -+ -+ case AIS_STATE_REMAIN_ON_CHANNEL: -+ /* 1. release channel */ -+ aisFsmReleaseCh(prAdapter); -+ -+ /* 2. stop channel timeout timer */ -+ cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rChannelTimeoutTimer); -+ -+ break; -+ -+ default: -+ break; -+ } -+ -+ if (fgIsCheckConnected && (PARAM_MEDIA_STATE_CONNECTED == prAisBssInfo->eConnectionState)) { -+ -+ /* switch into DISCONNECTING state for sending DEAUTH if necessary */ -+ if (prAisBssInfo->eCurrentOPMode == OP_MODE_INFRASTRUCTURE && -+ prAisBssInfo->ucReasonOfDisconnect == DISCONNECT_REASON_CODE_NEW_CONNECTION && -+ prAisBssInfo->prStaRecOfAP && prAisBssInfo->prStaRecOfAP->fgIsInUse) { -+ aisFsmSteps(prAdapter, AIS_STATE_DISCONNECTING); -+ -+ return; -+ } -+ /* Do abort NORMAL_TR */ -+ aisFsmStateAbort_NORMAL_TR(prAdapter); -+ -+ } -+ -+ aisFsmDisconnect(prAdapter, fgDelayIndication); -+ -+ -+} /* end of aisFsmStateAbort() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will handle the Join Complete Event from SAA FSM for AIS FSM -+* -+* @param[in] prMsgHdr Message of Join Complete of SAA FSM. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID aisFsmRunEventJoinComplete(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) -+{ -+ P_MSG_JOIN_COMP_T prJoinCompMsg; -+ P_AIS_FSM_INFO_T prAisFsmInfo; -+ ENUM_AIS_STATE_T eNextState; -+ P_STA_RECORD_T prStaRec; -+ P_SW_RFB_T prAssocRspSwRfb; -+ P_BSS_INFO_T prAisBssInfo; -+ UINT_8 aucP2pSsid[] = CTIA_MAGIC_SSID; -+ OS_SYSTIME rCurrentTime; -+ -+ DEBUGFUNC("aisFsmRunEventJoinComplete()"); -+ -+ ASSERT(prMsgHdr); -+ -+ GET_CURRENT_SYSTIME(&rCurrentTime); -+ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); -+ prJoinCompMsg = (P_MSG_JOIN_COMP_T) prMsgHdr; -+ prStaRec = prJoinCompMsg->prStaRec; -+ prAssocRspSwRfb = prJoinCompMsg->prSwRfb; -+ -+ eNextState = prAisFsmInfo->eCurrentState; -+ -+ DBGLOG(AIS, TRACE, "AISOK\n"); -+ -+ /* Check State and SEQ NUM */ -+ do { -+ if (prAisFsmInfo->eCurrentState != AIS_STATE_JOIN) -+ break; -+ -+ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ -+ /* Check SEQ NUM */ -+ if (prJoinCompMsg->ucSeqNum == prAisFsmInfo->ucSeqNumOfReqMsg) { -+ -+ /* 4 <1> JOIN was successful */ -+ if (prJoinCompMsg->rJoinStatus == WLAN_STATUS_SUCCESS) { -+ -+ /* 1. Reset retry count */ -+ prAisFsmInfo->ucConnTrialCount = 0; -+ -+ /* Completion of roaming */ -+ if (prAisBssInfo->eConnectionState == PARAM_MEDIA_STATE_CONNECTED) { -+ -+#if CFG_SUPPORT_ROAMING -+ /* 2. Deactivate previous BSS */ -+ aisFsmRoamingDisconnectPrevAP(prAdapter, prStaRec); -+ -+ /* 3. Update bss based on roaming staRec */ -+ aisUpdateBssInfoForRoamingAP(prAdapter, prStaRec, prAssocRspSwRfb); -+#endif /* CFG_SUPPORT_ROAMING */ -+ } else { -+ /* 4 <1.1> Change FW's Media State immediately. */ -+ aisChangeMediaState(prAdapter, PARAM_MEDIA_STATE_CONNECTED); -+ -+ /* 4 <1.2> Deactivate previous AP's STA_RECORD_T in Driver if have. */ -+ if ((prAisBssInfo->prStaRecOfAP) && -+ (prAisBssInfo->prStaRecOfAP != prStaRec) && -+ (prAisBssInfo->prStaRecOfAP->fgIsInUse)) { -+ -+ cnmStaRecChangeState(prAdapter, prAisBssInfo->prStaRecOfAP, -+ STA_STATE_1); -+ } -+ /* 4 <1.3> Update BSS_INFO_T */ -+ aisUpdateBssInfoForJOIN(prAdapter, prStaRec, prAssocRspSwRfb); -+ -+ /* 4 <1.4> Activate current AP's STA_RECORD_T in Driver. */ -+ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_3); -+ -+ /* 4 <1.5> Update RSSI if necessary */ -+ nicUpdateRSSI(prAdapter, NETWORK_TYPE_AIS_INDEX, -+ (INT_8) (RCPI_TO_dBm(prStaRec->ucRCPI)), 0); -+ -+ /* 4 <1.6> Indicate Connected Event to Host immediately. */ -+ /* Require BSSID, Association ID, Beacon Interval.. */ -+ /* from AIS_BSS_INFO_T */ -+ aisIndicationOfMediaStateToHost(prAdapter, PARAM_MEDIA_STATE_CONNECTED, -+ FALSE); -+ -+ /* add for ctia mode */ -+ if (EQUAL_SSID -+ (aucP2pSsid, CTIA_MAGIC_SSID_LEN, prAisBssInfo->aucSSID, -+ prAisBssInfo->ucSSIDLen)) { -+ nicEnterCtiaMode(prAdapter, TRUE, FALSE); -+ } -+ } -+ -+#if CFG_SUPPORT_ROAMING -+ /* if bssid is given, it means we no need fw roaming */ -+ if (prAdapter->rWifiVar.rConnSettings.eConnectionPolicy != CONNECT_BY_BSSID) -+ roamingFsmRunEventStart(prAdapter); -+#endif /* CFG_SUPPORT_ROAMING */ -+ -+ /* 4 <1.7> Set the Next State of AIS FSM */ -+ eNextState = AIS_STATE_NORMAL_TR; -+ } -+ /* 4 <2> JOIN was not successful */ -+ else { -+ /* 4 <2.1> Redo JOIN process with other Auth Type if possible */ -+ if (aisFsmStateInit_RetryJOIN(prAdapter, prStaRec) == FALSE) { -+ P_BSS_DESC_T prBssDesc; -+ -+ /* 1. Increase Failure Count */ -+ prStaRec->ucJoinFailureCount++; -+ -+ /* 2. release channel */ -+ aisFsmReleaseCh(prAdapter); -+ -+ /* 3.1 stop join timeout timer */ -+ cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rJoinTimeoutTimer); -+ -+ /* 3.2 reset local variable */ -+ prAisFsmInfo->fgIsInfraChannelFinished = TRUE; -+ -+ prBssDesc = scanSearchBssDescByBssid(prAdapter, prStaRec->aucMacAddr); -+ -+ if (prBssDesc == NULL) { -+ /* it maybe NULL when wlanRemove */ -+ /* -+ (1) UI does wifi off during SAA does auth/assoc procedure. -+ (2) We will do LINK_INITIALIZE(&prScanInfo->rBSSDescList); -+ in nicUninitMGMT(). -+ (3) We will handle prMsduInfo->pfTxDoneHandler -+ in nicTxRelease(). -+ (4) prMsduInfo->pfTxDoneHandler will point to -+ saaFsmRunEventTxDone(). -+ (5) Then jump to saaFsmSteps() -> saaFsmSendEventJoinComplete() -+ (6) Finally mboxSendMsg() -> aisFsmRunEventJoinComplete(). -+ (7) In aisFsmRunEventJoinComplete(), we will check -+ "prBssDesc = scanSearchBssDescByBssid(prAdapter, -+ prStaRec->aucMacAddr);" -+ (8) And prBssDesc will be NULL and hangs in -+ "ASSERT(prBssDesc->fgIsConnecting);" when DBG=0. -+ ASSERT(prBssDesc); -+ ASSERT(prBssDesc->fgIsConnecting); -+ */ -+ break; -+ } -+ /* ASSERT(prBssDesc); */ -+ /* ASSERT(prBssDesc->fgIsConnecting); */ -+ prBssDesc->ucJoinFailureCount++; -+ if (prBssDesc->ucJoinFailureCount >= SCN_BSS_JOIN_FAIL_THRESOLD) { -+ GET_CURRENT_SYSTIME(&prBssDesc->rJoinFailTime); -+ DBGLOG(AIS, INFO, -+ "Bss %pM join fail %d times,temp disable it at time:%u\n", -+ prBssDesc->aucBSSID, -+ SCN_BSS_JOIN_FAIL_THRESOLD, prBssDesc->rJoinFailTime); -+ } -+ -+ if (prBssDesc) -+ prBssDesc->fgIsConnecting = FALSE; -+ -+ /* 3.3 Free STA-REC */ -+ if (prStaRec != prAisBssInfo->prStaRecOfAP) -+ cnmStaRecFree(prAdapter, prStaRec, FALSE); -+ -+ if (prAisBssInfo->eConnectionState == PARAM_MEDIA_STATE_CONNECTED) { -+#if CFG_SUPPORT_ROAMING -+ eNextState = AIS_STATE_WAIT_FOR_NEXT_SCAN; -+#endif /* CFG_SUPPORT_ROAMING */ -+ } else if (CHECK_FOR_TIMEOUT(rCurrentTime, prAisFsmInfo->rJoinReqTime, -+ SEC_TO_SYSTIME(AIS_JOIN_TIMEOUT))) { -+ /* abort connection trial */ -+ prAdapter->rWifiVar.rConnSettings.fgIsConnReqIssued = FALSE; -+ -+ kalIndicateStatusAndComplete(prAdapter->prGlueInfo, -+ WLAN_STATUS_CONNECT_INDICATION, NULL, 0); -+ -+ eNextState = AIS_STATE_IDLE; -+ } else { -+ /* 4.b send reconnect request */ -+ aisFsmInsertRequest(prAdapter, AIS_REQUEST_RECONNECT); -+ -+ eNextState = AIS_STATE_IDLE; -+ } -+ } -+ } -+ } -+#if DBG -+ else -+ DBGLOG(AIS, WARN, "SEQ NO of AIS JOIN COMP MSG is not matched.\n"); -+#endif /* DBG */ -+ -+ if (eNextState != prAisFsmInfo->eCurrentState) -+ aisFsmSteps(prAdapter, eNextState); -+ } while (FALSE); -+ -+ if (prAssocRspSwRfb) -+ nicRxReturnRFB(prAdapter, prAssocRspSwRfb); -+ -+ cnmMemFree(prAdapter, prMsgHdr); -+ -+} /* end of aisFsmRunEventJoinComplete() */ -+ -+#if CFG_SUPPORT_ADHOC -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will handle the Grant Msg of IBSS Create which was sent by -+* CNM to indicate that channel was changed for creating IBSS. -+* -+* @param[in] prAdapter Pointer of ADAPTER_T -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID aisFsmCreateIBSS(IN P_ADAPTER_T prAdapter) -+{ -+ P_AIS_FSM_INFO_T prAisFsmInfo; -+ -+ ASSERT(prAdapter); -+ -+ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); -+ -+ do { -+ /* Check State */ -+ if (prAisFsmInfo->eCurrentState == AIS_STATE_IBSS_ALONE) -+ aisUpdateBssInfoForCreateIBSS(prAdapter); -+ } while (FALSE); -+ -+} /* end of aisFsmCreateIBSS() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will handle the Grant Msg of IBSS Merge which was sent by -+* CNM to indicate that channel was changed for merging IBSS. -+* -+* @param[in] prAdapter Pointer of ADAPTER_T -+* @param[in] prStaRec Pointer of STA_RECORD_T for merge -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID aisFsmMergeIBSS(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec) -+{ -+ P_AIS_FSM_INFO_T prAisFsmInfo; -+ ENUM_AIS_STATE_T eNextState; -+ P_BSS_INFO_T prAisBssInfo; -+ -+ ASSERT(prAdapter); -+ ASSERT(prStaRec); -+ -+ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); -+ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ -+ do { -+ -+ eNextState = prAisFsmInfo->eCurrentState; -+ -+ switch (prAisFsmInfo->eCurrentState) { -+ case AIS_STATE_IBSS_MERGE: -+ { -+ P_BSS_DESC_T prBssDesc; -+ -+ /* 4 <1.1> Change FW's Media State immediately. */ -+ aisChangeMediaState(prAdapter, PARAM_MEDIA_STATE_CONNECTED); -+ -+ /* 4 <1.2> Deactivate previous Peers' STA_RECORD_T in Driver if have. */ -+ bssClearClientList(prAdapter, prAisBssInfo); -+ -+ /* 4 <1.3> Unmark connection flag of previous BSS_DESC_T. */ -+ prBssDesc = scanSearchBssDescByBssid(prAdapter, prAisBssInfo->aucBSSID); -+ if (prBssDesc != NULL) { -+ prBssDesc->fgIsConnecting = FALSE; -+ prBssDesc->fgIsConnected = FALSE; -+ } -+ /* 4 <1.4> Update BSS_INFO_T */ -+ aisUpdateBssInfoForMergeIBSS(prAdapter, prStaRec); -+ -+ /* 4 <1.5> Add Peers' STA_RECORD_T to Client List */ -+ bssAddStaRecToClientList(prAdapter, prAisBssInfo, prStaRec); -+ -+ /* 4 <1.6> Activate current Peer's STA_RECORD_T in Driver. */ -+ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_3); -+ prStaRec->fgIsMerging = FALSE; -+ -+ /* 4 <1.7> Enable other features */ -+ -+ /* 4 <1.8> Indicate Connected Event to Host immediately. */ -+ aisIndicationOfMediaStateToHost(prAdapter, PARAM_MEDIA_STATE_CONNECTED, FALSE); -+ -+ /* 4 <1.9> Set the Next State of AIS FSM */ -+ eNextState = AIS_STATE_NORMAL_TR; -+ -+ /* 4 <1.10> Release channel privilege */ -+ aisFsmReleaseCh(prAdapter); -+ -+#if CFG_SLT_SUPPORT -+ prAdapter->rWifiVar.rSltInfo.prPseudoStaRec = prStaRec; -+#endif -+ } -+ break; -+ -+ default: -+ break; -+ } -+ -+ if (eNextState != prAisFsmInfo->eCurrentState) -+ aisFsmSteps(prAdapter, eNextState); -+ -+ } while (FALSE); -+ -+} /* end of aisFsmMergeIBSS() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will handle the Notification of existing IBSS was found -+* from SCN. -+* -+* @param[in] prMsgHdr Message of Notification of an IBSS was present. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID aisFsmRunEventFoundIBSSPeer(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) -+{ -+ P_MSG_AIS_IBSS_PEER_FOUND_T prAisIbssPeerFoundMsg; -+ P_AIS_FSM_INFO_T prAisFsmInfo; -+ ENUM_AIS_STATE_T eNextState; -+ P_STA_RECORD_T prStaRec; -+ P_BSS_INFO_T prAisBssInfo; -+ P_BSS_DESC_T prBssDesc; -+ BOOLEAN fgIsMergeIn; -+ -+ ASSERT(prMsgHdr); -+ -+ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); -+ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ -+ prAisIbssPeerFoundMsg = (P_MSG_AIS_IBSS_PEER_FOUND_T) prMsgHdr; -+ -+ ASSERT(prAisIbssPeerFoundMsg->ucNetTypeIndex == NETWORK_TYPE_AIS_INDEX); -+ -+ prStaRec = prAisIbssPeerFoundMsg->prStaRec; -+ ASSERT(prStaRec); -+ -+ fgIsMergeIn = prAisIbssPeerFoundMsg->fgIsMergeIn; -+ -+ cnmMemFree(prAdapter, prMsgHdr); -+ -+ eNextState = prAisFsmInfo->eCurrentState; -+ switch (prAisFsmInfo->eCurrentState) { -+ case AIS_STATE_IBSS_ALONE: -+ { -+ /* 4 <1> An IBSS Peer 'merged in'. */ -+ if (fgIsMergeIn) { -+ -+ /* 4 <1.1> Change FW's Media State immediately. */ -+ aisChangeMediaState(prAdapter, PARAM_MEDIA_STATE_CONNECTED); -+ -+ /* 4 <1.2> Add Peers' STA_RECORD_T to Client List */ -+ bssAddStaRecToClientList(prAdapter, prAisBssInfo, prStaRec); -+ -+#if CFG_SLT_SUPPORT -+ /* 4 <1.3> Mark connection flag of BSS_DESC_T. */ -+ prBssDesc = scanSearchBssDescByTA(prAdapter, prStaRec->aucMacAddr); -+ if (prBssDesc != NULL) { -+ prBssDesc->fgIsConnecting = FALSE; -+ prBssDesc->fgIsConnected = TRUE; -+ } else { -+ ASSERT(0); /* Should be able to find a BSS_DESC_T here. */ -+ } -+ -+ /* 4 <1.4> Activate current Peer's STA_RECORD_T in Driver. */ -+ prStaRec->fgIsQoS = TRUE; /* TODO(Kevin): TBD */ -+#else -+ /* 4 <1.3> Mark connection flag of BSS_DESC_T. */ -+ prBssDesc = scanSearchBssDescByBssid(prAdapter, prAisBssInfo->aucBSSID); -+ if (prBssDesc != NULL) { -+ prBssDesc->fgIsConnecting = FALSE; -+ prBssDesc->fgIsConnected = TRUE; -+ } else { -+ ASSERT(0); /* Should be able to find a BSS_DESC_T here. */ -+ } -+ -+ /* 4 <1.4> Activate current Peer's STA_RECORD_T in Driver. */ -+ prStaRec->fgIsQoS = FALSE; /* TODO(Kevin): TBD */ -+ -+#endif -+ -+ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_3); -+ prStaRec->fgIsMerging = FALSE; -+ -+ /* 4 <1.6> sync. to firmware */ -+ nicUpdateBss(prAdapter, NETWORK_TYPE_AIS_INDEX); -+ -+ /* 4 <1.7> Indicate Connected Event to Host immediately. */ -+ aisIndicationOfMediaStateToHost(prAdapter, PARAM_MEDIA_STATE_CONNECTED, FALSE); -+ -+ /* 4 <1.8> indicate PM for connected */ -+ nicPmIndicateBssConnected(prAdapter, NETWORK_TYPE_AIS_INDEX); -+ -+ /* 4 <1.9> Set the Next State of AIS FSM */ -+ eNextState = AIS_STATE_NORMAL_TR; -+ -+ /* 4 <1.10> Release channel privilege */ -+ aisFsmReleaseCh(prAdapter); -+ } -+ /* 4 <2> We need 'merge out' to this IBSS */ -+ else { -+ -+ /* 4 <2.1> Get corresponding BSS_DESC_T */ -+ prBssDesc = scanSearchBssDescByTA(prAdapter, prStaRec->aucMacAddr); -+ -+ prAisFsmInfo->prTargetBssDesc = prBssDesc; -+ -+ /* 4 <2.2> Set the Next State of AIS FSM */ -+ eNextState = AIS_STATE_IBSS_MERGE; -+ } -+ } -+ break; -+ -+ case AIS_STATE_NORMAL_TR: -+ { -+ -+ /* 4 <3> An IBSS Peer 'merged in'. */ -+ if (fgIsMergeIn) { -+ -+ /* 4 <3.1> Add Peers' STA_RECORD_T to Client List */ -+ bssAddStaRecToClientList(prAdapter, prAisBssInfo, prStaRec); -+ -+#if CFG_SLT_SUPPORT -+ /* 4 <3.2> Activate current Peer's STA_RECORD_T in Driver. */ -+ prStaRec->fgIsQoS = TRUE; /* TODO(Kevin): TBD */ -+#else -+ /* 4 <3.2> Activate current Peer's STA_RECORD_T in Driver. */ -+ prStaRec->fgIsQoS = FALSE; /* TODO(Kevin): TBD */ -+#endif -+ -+ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_3); -+ prStaRec->fgIsMerging = FALSE; -+ -+ } -+ /* 4 <4> We need 'merge out' to this IBSS */ -+ else { -+ -+ /* 4 <4.1> Get corresponding BSS_DESC_T */ -+ prBssDesc = scanSearchBssDescByTA(prAdapter, prStaRec->aucMacAddr); -+ -+ prAisFsmInfo->prTargetBssDesc = prBssDesc; -+ -+ /* 4 <4.2> Set the Next State of AIS FSM */ -+ eNextState = AIS_STATE_IBSS_MERGE; -+ -+ } -+ } -+ break; -+ -+ default: -+ break; -+ } -+ -+ if (eNextState != prAisFsmInfo->eCurrentState) -+ aisFsmSteps(prAdapter, eNextState); -+ -+} /* end of aisFsmRunEventFoundIBSSPeer() */ -+#endif /* CFG_SUPPORT_ADHOC */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will indicate the Media State to HOST -+* -+* @param[in] eConnectionState Current Media State -+* @param[in] fgDelayIndication Set TRUE for postponing the Disconnect Indication. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+aisIndicationOfMediaStateToHost(IN P_ADAPTER_T prAdapter, -+ ENUM_PARAM_MEDIA_STATE_T eConnectionState, BOOLEAN fgDelayIndication) -+{ -+ EVENT_CONNECTION_STATUS rEventConnStatus; -+ P_CONNECTION_SETTINGS_T prConnSettings; -+ P_BSS_INFO_T prAisBssInfo; -+ P_AIS_FSM_INFO_T prAisFsmInfo; -+ -+ DEBUGFUNC("aisIndicationOfMediaStateToHost()"); -+ -+ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); -+ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); -+ -+ /* NOTE(Kevin): Move following line to aisChangeMediaState() macro per CM's request. */ -+ /* prAisBssInfo->eConnectionState = eConnectionState; */ -+ -+ /* For indicating the Disconnect Event only if current media state is -+ * disconnected and we didn't do indication yet. -+ */ -+ if (prAisBssInfo->eConnectionState == PARAM_MEDIA_STATE_DISCONNECTED) { -+ if (prAisBssInfo->eConnectionStateIndicated == eConnectionState) -+ return; -+ } -+ -+ if (!fgDelayIndication) { -+ /* 4 <0> Cancel Delay Timer */ -+ cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rIndicationOfDisconnectTimer); -+ -+ /* 4 <1> Fill EVENT_CONNECTION_STATUS */ -+ rEventConnStatus.ucMediaStatus = (UINT_8) eConnectionState; -+ -+ if (eConnectionState == PARAM_MEDIA_STATE_CONNECTED) { -+ rEventConnStatus.ucReasonOfDisconnect = DISCONNECT_REASON_CODE_RESERVED; -+ -+ if (prAisBssInfo->eCurrentOPMode == OP_MODE_INFRASTRUCTURE) { -+ rEventConnStatus.ucInfraMode = (UINT_8) NET_TYPE_INFRA; -+ rEventConnStatus.u2AID = prAisBssInfo->u2AssocId; -+ rEventConnStatus.u2ATIMWindow = 0; -+ } else if (prAisBssInfo->eCurrentOPMode == OP_MODE_IBSS) { -+ rEventConnStatus.ucInfraMode = (UINT_8) NET_TYPE_IBSS; -+ rEventConnStatus.u2AID = 0; -+ rEventConnStatus.u2ATIMWindow = prAisBssInfo->u2ATIMWindow; -+ } else { -+ ASSERT(0); -+ } -+ -+ COPY_SSID(rEventConnStatus.aucSsid, -+ rEventConnStatus.ucSsidLen, prConnSettings->aucSSID, prConnSettings->ucSSIDLen); -+ -+ COPY_MAC_ADDR(rEventConnStatus.aucBssid, prAisBssInfo->aucBSSID); -+ -+ rEventConnStatus.u2BeaconPeriod = prAisBssInfo->u2BeaconInterval; -+ rEventConnStatus.u4FreqInKHz = nicChannelNum2Freq(prAisBssInfo->ucPrimaryChannel); -+ -+ switch (prAisBssInfo->ucNonHTBasicPhyType) { -+ case PHY_TYPE_HR_DSSS_INDEX: -+ rEventConnStatus.ucNetworkType = (UINT_8) PARAM_NETWORK_TYPE_DS; -+ break; -+ -+ case PHY_TYPE_ERP_INDEX: -+ rEventConnStatus.ucNetworkType = (UINT_8) PARAM_NETWORK_TYPE_OFDM24; -+ break; -+ -+ case PHY_TYPE_OFDM_INDEX: -+ rEventConnStatus.ucNetworkType = (UINT_8) PARAM_NETWORK_TYPE_OFDM5; -+ break; -+ -+ default: -+ ASSERT(0); -+ rEventConnStatus.ucNetworkType = (UINT_8) PARAM_NETWORK_TYPE_DS; -+ break; -+ } -+ } else { -+ /* Deactivate previous Peers' STA_RECORD_T in Driver if have. */ -+ bssClearClientList(prAdapter, prAisBssInfo); -+ -+#if CFG_PRIVACY_MIGRATION -+ /* Clear the pmkid cache while media disconnect */ -+ secClearPmkid(prAdapter); -+#endif -+ -+ rEventConnStatus.ucReasonOfDisconnect = prAisBssInfo->ucReasonOfDisconnect; -+ } -+ -+ /* 4 <2> Indication */ -+ nicMediaStateChange(prAdapter, NETWORK_TYPE_AIS_INDEX, &rEventConnStatus); -+ prAisBssInfo->eConnectionStateIndicated = eConnectionState; -+ } else { -+ /* NOTE: Only delay the Indication of Disconnect Event */ -+ ASSERT(eConnectionState == PARAM_MEDIA_STATE_DISCONNECTED); -+ -+ DBGLOG(AIS, INFO, "Postpone the indication of Disconnect for %d seconds\n", -+ prConnSettings->ucDelayTimeOfDisconnectEvent); -+ -+ cnmTimerStartTimer(prAdapter, -+ &prAisFsmInfo->rIndicationOfDisconnectTimer, -+ SEC_TO_MSEC(prConnSettings->ucDelayTimeOfDisconnectEvent)); -+ } -+ -+} /* end of aisIndicationOfMediaStateToHost() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will indicate an Event of "Media Disconnect" to HOST -+* -+* @param[in] u4Param Unused timer parameter -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID aisPostponedEventOfDisconnTimeout(IN P_ADAPTER_T prAdapter, ULONG ulParam) -+{ -+ P_BSS_INFO_T prAisBssInfo; -+ P_CONNECTION_SETTINGS_T prConnSettings; -+ -+ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); -+ -+ /* 4 <1> Deactivate previous AP's STA_RECORD_T in Driver if have. */ -+ if (prAisBssInfo->prStaRecOfAP) { -+ /* cnmStaRecChangeState(prAdapter, prAisBssInfo->prStaRecOfAP, STA_STATE_1); */ -+ -+ prAisBssInfo->prStaRecOfAP = (P_STA_RECORD_T) NULL; -+ } -+ /* 4 <2> Remove pending connection request */ -+ aisFsmIsRequestPending(prAdapter, AIS_REQUEST_RECONNECT, TRUE); -+ prConnSettings->fgIsDisconnectedByNonRequest = TRUE; -+ prAisBssInfo->u2DeauthReason = REASON_CODE_BEACON_TIMEOUT; -+ /* 4 <3> Indicate Disconnected Event to Host immediately. */ -+ aisIndicationOfMediaStateToHost(prAdapter, PARAM_MEDIA_STATE_DISCONNECTED, FALSE); -+ -+} /* end of aisPostponedEventOfDisconnTimeout() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will update the contain of BSS_INFO_T for AIS network once -+* the association was completed. -+* -+* @param[in] prStaRec Pointer to the STA_RECORD_T -+* @param[in] prAssocRspSwRfb Pointer to SW RFB of ASSOC RESP FRAME. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID aisUpdateBssInfoForJOIN(IN P_ADAPTER_T prAdapter, P_STA_RECORD_T prStaRec, P_SW_RFB_T prAssocRspSwRfb) -+{ -+ P_AIS_FSM_INFO_T prAisFsmInfo; -+ P_BSS_INFO_T prAisBssInfo; -+ P_CONNECTION_SETTINGS_T prConnSettings; -+ P_WLAN_ASSOC_RSP_FRAME_T prAssocRspFrame; -+ P_BSS_DESC_T prBssDesc; -+ UINT_16 u2IELength; -+ PUINT_8 pucIE; -+ -+ DEBUGFUNC("aisUpdateBssInfoForJOIN()"); -+ -+ ASSERT(prStaRec); -+ ASSERT(prAssocRspSwRfb); -+ -+ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); -+ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); -+ prAssocRspFrame = (P_WLAN_ASSOC_RSP_FRAME_T) prAssocRspSwRfb->pvHeader; -+ -+ DBGLOG(AIS, TRACE, "Update AIS_BSS_INFO_T and apply settings to MAC\n"); -+ -+ /* 3 <1> Update BSS_INFO_T from AIS_FSM_INFO_T or User Settings */ -+ /* 4 <1.1> Setup Operation Mode */ -+ prAisBssInfo->eCurrentOPMode = OP_MODE_INFRASTRUCTURE; -+ -+ /* 4 <1.2> Setup SSID */ -+ COPY_SSID(prAisBssInfo->aucSSID, prAisBssInfo->ucSSIDLen, prConnSettings->aucSSID, prConnSettings->ucSSIDLen); -+ -+ /* 4 <1.3> Setup Channel, Band */ -+ prAisBssInfo->ucPrimaryChannel = prAisFsmInfo->prTargetBssDesc->ucChannelNum; -+ prAisBssInfo->eBand = prAisFsmInfo->prTargetBssDesc->eBand; -+ -+ /* 3 <2> Update BSS_INFO_T from STA_RECORD_T */ -+ /* 4 <2.1> Save current AP's STA_RECORD_T and current AID */ -+ prAisBssInfo->prStaRecOfAP = prStaRec; -+ prAisBssInfo->u2AssocId = prStaRec->u2AssocId; -+ -+ /* 4 <2.2> Setup Capability */ -+ prAisBssInfo->u2CapInfo = prStaRec->u2CapInfo; /* Use AP's Cap Info as BSS Cap Info */ -+ -+ if (prAisBssInfo->u2CapInfo & CAP_INFO_SHORT_PREAMBLE) -+ prAisBssInfo->fgIsShortPreambleAllowed = TRUE; -+ else -+ prAisBssInfo->fgIsShortPreambleAllowed = FALSE; -+ -+#if (CFG_SUPPORT_TDLS == 1) -+ /* init the TDLS flags */ -+ prAisBssInfo->fgTdlsIsProhibited = prStaRec->fgTdlsIsProhibited; -+ prAisBssInfo->fgTdlsIsChSwProhibited = prStaRec->fgTdlsIsChSwProhibited; -+#endif /* CFG_SUPPORT_TDLS */ -+ -+ /* 4 <2.3> Setup PHY Attributes and Basic Rate Set/Operational Rate Set */ -+ prAisBssInfo->ucPhyTypeSet = prStaRec->ucDesiredPhyTypeSet; -+ -+ prAisBssInfo->ucNonHTBasicPhyType = prStaRec->ucNonHTBasicPhyType; -+ -+ prAisBssInfo->u2OperationalRateSet = prStaRec->u2OperationalRateSet; -+ prAisBssInfo->u2BSSBasicRateSet = prStaRec->u2BSSBasicRateSet; -+ -+ /* 3 <3> Update BSS_INFO_T from SW_RFB_T (Association Resp Frame) */ -+ /* 4 <3.1> Setup BSSID */ -+ COPY_MAC_ADDR(prAisBssInfo->aucBSSID, prAssocRspFrame->aucBSSID); -+ -+ u2IELength = (UINT_16) ((prAssocRspSwRfb->u2PacketLen - prAssocRspSwRfb->u2HeaderLen) - -+ (OFFSET_OF(WLAN_ASSOC_RSP_FRAME_T, aucInfoElem[0]) - WLAN_MAC_MGMT_HEADER_LEN)); -+ pucIE = prAssocRspFrame->aucInfoElem; -+ -+ /* 4 <3.2> Parse WMM and setup QBSS flag */ -+ /* Parse WMM related IEs and configure HW CRs accordingly */ -+ mqmProcessAssocRsp(prAdapter, prAssocRspSwRfb, pucIE, u2IELength); -+ -+ prAisBssInfo->fgIsQBSS = prStaRec->fgIsQoS; -+ -+ /* 3 <4> Update BSS_INFO_T from BSS_DESC_T */ -+ prBssDesc = scanSearchBssDescByBssid(prAdapter, prAssocRspFrame->aucBSSID); -+ if (prBssDesc) { -+ prBssDesc->fgIsConnecting = FALSE; -+ prBssDesc->fgIsConnected = TRUE; -+ prBssDesc->ucJoinFailureCount = 0; -+ -+ /* 4 <4.1> Setup MIB for current BSS */ -+ prAisBssInfo->u2BeaconInterval = prBssDesc->u2BeaconInterval; -+ } else { -+ /* should never happen */ -+ ASSERT(0); -+ } -+ -+ /* NOTE: Defer ucDTIMPeriod updating to when beacon is received after connection */ -+ prAisBssInfo->ucDTIMPeriod = 0; -+ prAisBssInfo->u2ATIMWindow = 0; -+ -+ prAisBssInfo->ucBeaconTimeoutCount = AIS_BEACON_TIMEOUT_COUNT_INFRA; -+ -+ /* 4 <4.2> Update HT information and set channel */ -+ /* Record HT related parameters in rStaRec and rBssInfo -+ * Note: it shall be called before nicUpdateBss() -+ */ -+ rlmProcessAssocRsp(prAdapter, prAssocRspSwRfb, pucIE, u2IELength); -+ -+ /* 4 <4.3> Sync with firmware for BSS-INFO */ -+ nicUpdateBss(prAdapter, NETWORK_TYPE_AIS_INDEX); -+ -+ /* 4 <4.4> *DEFER OPERATION* nicPmIndicateBssConnected() will be invoked */ -+ /* inside scanProcessBeaconAndProbeResp() after 1st beacon is received */ -+ -+} /* end of aisUpdateBssInfoForJOIN() */ -+ -+#if CFG_SUPPORT_ADHOC -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will create an Ad-Hoc network and start sending Beacon Frames. -+* -+* @param (none) -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID aisUpdateBssInfoForCreateIBSS(IN P_ADAPTER_T prAdapter) -+{ -+ P_AIS_FSM_INFO_T prAisFsmInfo; -+ P_BSS_INFO_T prAisBssInfo; -+ P_CONNECTION_SETTINGS_T prConnSettings; -+ -+ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); -+ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); -+ -+ if (prAisBssInfo->fgIsBeaconActivated) -+ return; -+ /* 3 <1> Update BSS_INFO_T per Network Basis */ -+ /* 4 <1.1> Setup Operation Mode */ -+ prAisBssInfo->eCurrentOPMode = OP_MODE_IBSS; -+ -+ /* 4 <1.2> Setup SSID */ -+ COPY_SSID(prAisBssInfo->aucSSID, prAisBssInfo->ucSSIDLen, prConnSettings->aucSSID, prConnSettings->ucSSIDLen); -+ -+ /* 4 <1.3> Clear current AP's STA_RECORD_T and current AID */ -+ prAisBssInfo->prStaRecOfAP = (P_STA_RECORD_T) NULL; -+ prAisBssInfo->u2AssocId = 0; -+ -+ /* 4 <1.4> Setup Channel, Band and Phy Attributes */ -+ prAisBssInfo->ucPrimaryChannel = prConnSettings->ucAdHocChannelNum; -+ prAisBssInfo->eBand = prConnSettings->eAdHocBand; -+ -+ if (prAisBssInfo->eBand == BAND_2G4) { -+ /* Depend on eBand */ -+ prAisBssInfo->ucPhyTypeSet = prAdapter->rWifiVar.ucAvailablePhyTypeSet & PHY_TYPE_SET_802_11BGN; -+ /* Depend on eCurrentOPMode and ucPhyTypeSet */ -+ prAisBssInfo->ucConfigAdHocAPMode = AD_HOC_MODE_MIXED_11BG; -+ } else { -+ /* Depend on eBand */ -+ prAisBssInfo->ucPhyTypeSet = prAdapter->rWifiVar.ucAvailablePhyTypeSet & PHY_TYPE_SET_802_11AN; -+ /* Depend on eCurrentOPMode and ucPhyTypeSet */ -+ prAisBssInfo->ucConfigAdHocAPMode = AD_HOC_MODE_11A; -+ } -+ -+ /* 4 <1.5> Setup MIB for current BSS */ -+ prAisBssInfo->u2BeaconInterval = prConnSettings->u2BeaconPeriod; -+ prAisBssInfo->ucDTIMPeriod = 0; -+ prAisBssInfo->u2ATIMWindow = prConnSettings->u2AtimWindow; -+ -+ prAisBssInfo->ucBeaconTimeoutCount = AIS_BEACON_TIMEOUT_COUNT_ADHOC; -+ -+#if CFG_PRIVACY_MIGRATION -+ if (prConnSettings->eEncStatus == ENUM_ENCRYPTION1_ENABLED || -+ prConnSettings->eEncStatus == ENUM_ENCRYPTION2_ENABLED || -+ prConnSettings->eEncStatus == ENUM_ENCRYPTION3_ENABLED) { -+ prAisBssInfo->fgIsProtection = TRUE; -+ } else { -+ prAisBssInfo->fgIsProtection = FALSE; -+ } -+#else -+ prAisBssInfo->fgIsProtection = FALSE; -+#endif -+ -+ /* 3 <2> Update BSS_INFO_T common part */ -+ ibssInitForAdHoc(prAdapter, prAisBssInfo); -+ -+ /* 3 <3> Set MAC HW */ -+ /* 4 <3.1> Setup channel and bandwidth */ -+ rlmBssInitForAPandIbss(prAdapter, prAisBssInfo); -+ -+ /* 4 <3.2> use command packets to inform firmware */ -+ nicUpdateBss(prAdapter, NETWORK_TYPE_AIS_INDEX); -+ -+ /* 4 <3.3> enable beaconing */ -+ bssUpdateBeaconContent(prAdapter, NETWORK_TYPE_AIS_INDEX); -+ -+ /* 4 <3.4> Update AdHoc PM parameter */ -+ nicPmIndicateBssCreated(prAdapter, NETWORK_TYPE_AIS_INDEX); -+ -+ /* 3 <4> Set ACTIVE flag. */ -+ prAisBssInfo->fgIsBeaconActivated = TRUE; -+ prAisBssInfo->fgHoldSameBssidForIBSS = TRUE; -+ -+ /* 3 <5> Start IBSS Alone Timer */ -+ cnmTimerStartTimer(prAdapter, &prAisFsmInfo->rIbssAloneTimer, SEC_TO_MSEC(AIS_IBSS_ALONE_TIMEOUT_SEC)); -+ -+ return; -+ -+} /* end of aisCreateIBSS() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will update the contain of BSS_INFO_T for AIS network once -+* the existing IBSS was found. -+* -+* @param[in] prStaRec Pointer to the STA_RECORD_T -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID aisUpdateBssInfoForMergeIBSS(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec) -+{ -+ P_AIS_FSM_INFO_T prAisFsmInfo; -+ P_BSS_INFO_T prAisBssInfo; -+ P_CONNECTION_SETTINGS_T prConnSettings; -+ P_BSS_DESC_T prBssDesc; -+ /* UINT_16 u2IELength; */ -+ /* PUINT_8 pucIE; */ -+ -+ ASSERT(prStaRec); -+ -+ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); -+ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); -+ -+ cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rIbssAloneTimer); -+ -+ if (!prAisBssInfo->fgIsBeaconActivated) { -+ -+ /* 3 <1> Update BSS_INFO_T per Network Basis */ -+ /* 4 <1.1> Setup Operation Mode */ -+ prAisBssInfo->eCurrentOPMode = OP_MODE_IBSS; -+ -+ /* 4 <1.2> Setup SSID */ -+ COPY_SSID(prAisBssInfo->aucSSID, -+ prAisBssInfo->ucSSIDLen, prConnSettings->aucSSID, prConnSettings->ucSSIDLen); -+ -+ /* 4 <1.3> Clear current AP's STA_RECORD_T and current AID */ -+ prAisBssInfo->prStaRecOfAP = (P_STA_RECORD_T) NULL; -+ prAisBssInfo->u2AssocId = 0; -+ } -+ /* 3 <2> Update BSS_INFO_T from STA_RECORD_T */ -+ /* 4 <2.1> Setup Capability */ -+ prAisBssInfo->u2CapInfo = prStaRec->u2CapInfo; /* Use Peer's Cap Info as IBSS Cap Info */ -+ -+ if (prAisBssInfo->u2CapInfo & CAP_INFO_SHORT_PREAMBLE) { -+ prAisBssInfo->fgIsShortPreambleAllowed = TRUE; -+ prAisBssInfo->fgUseShortPreamble = TRUE; -+ } else { -+ prAisBssInfo->fgIsShortPreambleAllowed = FALSE; -+ prAisBssInfo->fgUseShortPreamble = FALSE; -+ } -+ -+ /* 7.3.1.4 For IBSS, the Short Slot Time subfield shall be set to 0. */ -+ prAisBssInfo->fgUseShortSlotTime = FALSE; /* Set to FALSE for AdHoc */ -+ prAisBssInfo->u2CapInfo &= ~CAP_INFO_SHORT_SLOT_TIME; -+ -+ if (prAisBssInfo->u2CapInfo & CAP_INFO_PRIVACY) -+ prAisBssInfo->fgIsProtection = TRUE; -+ else -+ prAisBssInfo->fgIsProtection = FALSE; -+ -+ /* 4 <2.2> Setup PHY Attributes and Basic Rate Set/Operational Rate Set */ -+ prAisBssInfo->ucPhyTypeSet = prStaRec->ucDesiredPhyTypeSet; -+ -+ prAisBssInfo->ucNonHTBasicPhyType = prStaRec->ucNonHTBasicPhyType; -+ -+ prAisBssInfo->u2OperationalRateSet = prStaRec->u2OperationalRateSet; -+ prAisBssInfo->u2BSSBasicRateSet = prStaRec->u2BSSBasicRateSet; -+ -+ rateGetDataRatesFromRateSet(prAisBssInfo->u2OperationalRateSet, -+ prAisBssInfo->u2BSSBasicRateSet, -+ prAisBssInfo->aucAllSupportedRates, &prAisBssInfo->ucAllSupportedRatesLen); -+ -+ /* 3 <3> X Update BSS_INFO_T from SW_RFB_T (Association Resp Frame) */ -+ -+ /* 3 <4> Update BSS_INFO_T from BSS_DESC_T */ -+ prBssDesc = scanSearchBssDescByTA(prAdapter, prStaRec->aucMacAddr); -+ if (prBssDesc) { -+ prBssDesc->fgIsConnecting = FALSE; -+ prBssDesc->fgIsConnected = TRUE; -+ -+ /* 4 <4.1> Setup BSSID */ -+ COPY_MAC_ADDR(prAisBssInfo->aucBSSID, prBssDesc->aucBSSID); -+ -+ /* 4 <4.2> Setup Channel, Band */ -+ prAisBssInfo->ucPrimaryChannel = prBssDesc->ucChannelNum; -+ prAisBssInfo->eBand = prBssDesc->eBand; -+ -+ /* 4 <4.3> Setup MIB for current BSS */ -+ prAisBssInfo->u2BeaconInterval = prBssDesc->u2BeaconInterval; -+ prAisBssInfo->ucDTIMPeriod = 0; -+ prAisBssInfo->u2ATIMWindow = 0; /* TBD(Kevin) */ -+ -+ prAisBssInfo->ucBeaconTimeoutCount = AIS_BEACON_TIMEOUT_COUNT_ADHOC; -+ } else { -+ /* should never happen */ -+ ASSERT(0); -+ } -+ -+ /* 3 <5> Set MAC HW */ -+ /* 4 <5.1> Find Lowest Basic Rate Index for default TX Rate of MMPDU */ -+ { -+ UINT_8 ucLowestBasicRateIndex; -+ -+ if (!rateGetLowestRateIndexFromRateSet(prAisBssInfo->u2BSSBasicRateSet, &ucLowestBasicRateIndex)) { -+ -+ if (prAisBssInfo->ucPhyTypeSet & PHY_TYPE_BIT_OFDM) -+ ucLowestBasicRateIndex = RATE_6M_INDEX; -+ else -+ ucLowestBasicRateIndex = RATE_1M_INDEX; -+ } -+ -+ prAisBssInfo->ucHwDefaultFixedRateCode = -+ aucRateIndex2RateCode[prAisBssInfo->fgUseShortPreamble][ucLowestBasicRateIndex]; -+ } -+ -+ /* 4 <5.2> Setup channel and bandwidth */ -+ rlmBssInitForAPandIbss(prAdapter, prAisBssInfo); -+ -+ /* 4 <5.3> use command packets to inform firmware */ -+ nicUpdateBss(prAdapter, NETWORK_TYPE_AIS_INDEX); -+ -+ /* 4 <5.4> enable beaconing */ -+ bssUpdateBeaconContent(prAdapter, NETWORK_TYPE_AIS_INDEX); -+ -+ /* 4 <5.5> Update AdHoc PM parameter */ -+ nicPmIndicateBssConnected(prAdapter, NETWORK_TYPE_AIS_INDEX); -+ -+ /* 3 <6> Set ACTIVE flag. */ -+ prAisBssInfo->fgIsBeaconActivated = TRUE; -+ prAisBssInfo->fgHoldSameBssidForIBSS = TRUE; -+ -+} /* end of aisUpdateBssInfoForMergeIBSS() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will validate the Rx Probe Request Frame and then return -+* result to BSS to indicate if need to send the corresponding Probe Response -+* Frame if the specified conditions were matched. -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* @param[in] prSwRfb Pointer to SW RFB data structure. -+* @param[out] pu4ControlFlags Control flags for replying the Probe Response -+* -+* @retval TRUE Reply the Probe Response -+* @retval FALSE Don't reply the Probe Response -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN aisValidateProbeReq(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, OUT PUINT_32 pu4ControlFlags) -+{ -+ P_WLAN_MAC_MGMT_HEADER_T prMgtHdr; -+ P_BSS_INFO_T prBssInfo; -+ P_IE_SSID_T prIeSsid = (P_IE_SSID_T) NULL; -+ PUINT_8 pucIE; -+ UINT_16 u2IELength; -+ UINT_16 u2Offset = 0; -+ BOOLEAN fgReplyProbeResp = FALSE; -+ -+ ASSERT(prSwRfb); -+ ASSERT(pu4ControlFlags); -+ -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ -+ /* 4 <1> Parse Probe Req IE and Get IE ptr (SSID, Supported Rate IE, ...) */ -+ prMgtHdr = (P_WLAN_MAC_MGMT_HEADER_T) prSwRfb->pvHeader; -+ -+ u2IELength = prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen; -+ pucIE = (PUINT_8) prSwRfb->pvHeader + prSwRfb->u2HeaderLen; -+ -+ IE_FOR_EACH(pucIE, u2IELength, u2Offset) { -+ if (ELEM_ID_SSID == IE_ID(pucIE)) { -+ if ((!prIeSsid) && (IE_LEN(pucIE) <= ELEM_MAX_LEN_SSID)) -+ prIeSsid = (P_IE_SSID_T) pucIE; -+ break; -+ } -+ } /* end of IE_FOR_EACH */ -+ -+ /* 4 <2> Check network conditions */ -+ -+ if (prBssInfo->eCurrentOPMode == OP_MODE_IBSS) { -+ -+ if ((prIeSsid) && ((prIeSsid->ucLength == BC_SSID_LEN) || /* WILDCARD SSID */ -+ EQUAL_SSID(prBssInfo->aucSSID, prBssInfo->ucSSIDLen, /* CURRENT SSID */ -+ prIeSsid->aucSSID, prIeSsid->ucLength))) { -+ fgReplyProbeResp = TRUE; -+ } -+ } -+ -+ return fgReplyProbeResp; -+ -+} /* end of aisValidateProbeReq() */ -+ -+#endif /* CFG_SUPPORT_ADHOC */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will modify and update necessary information to firmware -+* for disconnection handling -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* -+* @retval None -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID aisFsmDisconnect(IN P_ADAPTER_T prAdapter, IN BOOLEAN fgDelayIndication) -+{ -+ P_BSS_INFO_T prAisBssInfo; -+ -+ ASSERT(prAdapter); -+ -+ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ -+ nicPmIndicateBssAbort(prAdapter, NETWORK_TYPE_AIS_INDEX); -+ -+#if CFG_SUPPORT_ADHOC -+ if (prAisBssInfo->fgIsBeaconActivated) { -+ nicUpdateBeaconIETemplate(prAdapter, IE_UPD_METHOD_DELETE_ALL, NETWORK_TYPE_AIS_INDEX, 0, NULL, 0); -+ -+ prAisBssInfo->fgIsBeaconActivated = FALSE; -+ } -+#endif -+ -+ rlmBssAborted(prAdapter, prAisBssInfo); -+ -+ /* 4 <3> Unset the fgIsConnected flag of BSS_DESC_T and send Deauth if needed. */ -+ if (PARAM_MEDIA_STATE_CONNECTED == prAisBssInfo->eConnectionState) { -+ /* add for ctia mode */ -+ { -+ UINT_8 aucP2pSsid[] = CTIA_MAGIC_SSID; -+ -+ if (EQUAL_SSID(aucP2pSsid, CTIA_MAGIC_SSID_LEN, prAisBssInfo->aucSSID, prAisBssInfo->ucSSIDLen)) -+ nicEnterCtiaMode(prAdapter, FALSE, FALSE); -+ } -+ -+ if (prAisBssInfo->ucReasonOfDisconnect == DISCONNECT_REASON_CODE_RADIO_LOST) { -+ scanRemoveBssDescByBssid(prAdapter, prAisBssInfo->aucBSSID); -+ -+ /* remove from scanning results as well */ -+ wlanClearBssInScanningResult(prAdapter, prAisBssInfo->aucBSSID); -+ -+ /* trials for re-association */ -+ if (fgDelayIndication) { -+ DBGLOG(AIS, INFO, "try to do re-association due to radio lost!\n"); -+ aisFsmIsRequestPending(prAdapter, AIS_REQUEST_RECONNECT, TRUE); -+ aisFsmInsertRequest(prAdapter, AIS_REQUEST_RECONNECT); -+ } -+ } else { -+ scanRemoveConnFlagOfBssDescByBssid(prAdapter, prAisBssInfo->aucBSSID); -+ } -+ -+ if (fgDelayIndication) { -+ if (OP_MODE_IBSS != prAisBssInfo->eCurrentOPMode) -+ prAisBssInfo->fgHoldSameBssidForIBSS = FALSE; -+ } else { -+ prAisBssInfo->fgHoldSameBssidForIBSS = FALSE; -+ } -+ } else { -+ prAisBssInfo->fgHoldSameBssidForIBSS = FALSE; -+ } -+ -+ /* 4 <4> Change Media State immediately. */ -+ if (prAisBssInfo->ucReasonOfDisconnect != DISCONNECT_REASON_CODE_REASSOCIATION) { -+ aisChangeMediaState(prAdapter, PARAM_MEDIA_STATE_DISCONNECTED); -+ -+ /* 4 <4.1> sync. with firmware */ -+ nicUpdateBss(prAdapter, NETWORK_TYPE_AIS_INDEX); -+ } -+ -+ if (!fgDelayIndication) { -+ /* 4 <5> Deactivate previous AP's STA_RECORD_T or all Clients in Driver if have. */ -+ if (prAisBssInfo->prStaRecOfAP) { -+ /* cnmStaRecChangeState(prAdapter, prAisBssInfo->prStaRecOfAP, STA_STATE_1); */ -+ -+ prAisBssInfo->prStaRecOfAP = (P_STA_RECORD_T) NULL; -+ } -+ } -+#if CFG_SUPPORT_ROAMING -+ roamingFsmRunEventAbort(prAdapter); -+ -+ /* clear pending roaming connection request */ -+ aisFsmIsRequestPending(prAdapter, AIS_REQUEST_ROAMING_SEARCH, TRUE); -+ aisFsmIsRequestPending(prAdapter, AIS_REQUEST_ROAMING_CONNECT, TRUE); -+#endif /* CFG_SUPPORT_ROAMING */ -+ -+ /* 4 <6> Indicate Disconnected Event to Host */ -+ aisIndicationOfMediaStateToHost(prAdapter, PARAM_MEDIA_STATE_DISCONNECTED, fgDelayIndication); -+ -+ /* 4 <7> Trigger AIS FSM */ -+ aisFsmSteps(prAdapter, AIS_STATE_IDLE); -+ -+} /* end of aisFsmDisconnect() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will indicate an Event of Scan done Time-Out to AIS FSM. -+* -+* @param[in] u4Param Unused timer parameter -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT_32 IsrCnt = 0, IsrPassCnt = 0, TaskIsrCnt = 0; -+VOID aisFsmRunEventScanDoneTimeOut(IN P_ADAPTER_T prAdapter, ULONG ulParam) -+{ -+#define SCAN_DONE_TIMEOUT_TIMES_LIMIT 20 -+ -+ P_AIS_FSM_INFO_T prAisFsmInfo; -+ ENUM_AIS_STATE_T eNextState; -+ P_CONNECTION_SETTINGS_T prConnSettings; -+ GL_HIF_INFO_T *HifInfo; -+ UINT_32 u4FwCnt; -+ P_GLUE_INFO_T prGlueInfo; -+ -+ DEBUGFUNC("aisFsmRunEventScanDoneTimeOut()"); -+ -+ prGlueInfo = prAdapter->prGlueInfo; -+ -+ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); -+ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); -+ HifInfo = &prAdapter->prGlueInfo->rHifInfo; -+ -+ DBGLOG(AIS, WARN, "aisFsmRunEventScanDoneTimeOut Current[%d], ucScanTimeoutTimes=%d\n", -+ prAisFsmInfo->eCurrentState, ucScanTimeoutTimes); -+ DBGLOG(AIS, WARN, "Isr/task %u %u %u (0x%x)\n", prGlueInfo->IsrCnt, prGlueInfo->IsrPassCnt, -+ prGlueInfo->TaskIsrCnt, prAdapter->fgIsIntEnable); -+ -+ /* dump firmware program counter */ -+ DBGLOG(AIS, WARN, "CONNSYS FW CPUINFO:\n"); -+ for (u4FwCnt = 0; u4FwCnt < 16; u4FwCnt++) -+ DBGLOG(AIS, WARN, "0x%08x ", MCU_REG_READL(HifInfo, CONN_MCU_CPUPCR)); -+ -+ ucScanTimeoutTimes++; -+ if (ucScanTimeoutTimes > SCAN_DONE_TIMEOUT_TIMES_LIMIT) { -+ kalSendAeeWarning("[Scan done timeout more than 20 times!]", __func__); -+ glDoChipReset(); -+ } -+#if 0 /* ALPS02018734: remove trigger assert */ -+ if (prAdapter->fgTestMode == FALSE) { -+ /* Titus - xxx */ -+ /* assert if and only if in normal mode */ -+ mtk_wcn_wmt_assert(WMTDRV_TYPE_WIFI, 40); -+ } -+#endif -+ /* report all scanned frames to upper layer to avoid scanned frame is timeout */ -+ /* must be put before kalScanDone */ -+/* scanReportBss2Cfg80211(prAdapter,BSS_TYPE_INFRASTRUCTURE,NULL); */ -+ -+ prConnSettings->fgIsScanReqIssued = FALSE; -+ kalScanDone(prAdapter->prGlueInfo, KAL_NETWORK_TYPE_AIS_INDEX, WLAN_STATUS_SUCCESS); -+ eNextState = prAisFsmInfo->eCurrentState; -+ -+ switch (prAisFsmInfo->eCurrentState) { -+ case AIS_STATE_SCAN: -+ prAisFsmInfo->u4ScanIELength = 0; -+ eNextState = AIS_STATE_IDLE; -+ break; -+ case AIS_STATE_ONLINE_SCAN: -+ /* reset scan IE buffer */ -+ prAisFsmInfo->u4ScanIELength = 0; -+#if CFG_SUPPORT_ROAMING -+ eNextState = aisFsmRoamingScanResultsUpdate(prAdapter); -+#else -+ eNextState = AIS_STATE_NORMAL_TR; -+#endif /* CFG_SUPPORT_ROAMING */ -+ break; -+ default: -+ break; -+ } -+ -+ /* try to stop scan in CONNSYS */ -+ aisFsmStateAbort_SCAN(prAdapter); -+ -+ /* wlanQueryDebugCode(prAdapter); */ /* display current SCAN FSM in FW, debug use */ -+ -+ if (eNextState != prAisFsmInfo->eCurrentState) -+ aisFsmSteps(prAdapter, eNextState); -+ -+} /* end of aisFsmBGSleepTimeout() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will indicate an Event of "Background Scan Time-Out" to AIS FSM. -+* -+* @param[in] u4Param Unused timer parameter -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID aisFsmRunEventBGSleepTimeOut(IN P_ADAPTER_T prAdapter, ULONG ulParam) -+{ -+ P_AIS_FSM_INFO_T prAisFsmInfo; -+ ENUM_AIS_STATE_T eNextState; -+ -+ DEBUGFUNC("aisFsmRunEventBGSleepTimeOut()"); -+ -+ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); -+ -+ eNextState = prAisFsmInfo->eCurrentState; -+ -+ switch (prAisFsmInfo->eCurrentState) { -+ case AIS_STATE_WAIT_FOR_NEXT_SCAN: -+ DBGLOG(AIS, LOUD, "EVENT - SCAN TIMER: Idle End - Current Time = %u\n", kalGetTimeTick()); -+ -+ eNextState = AIS_STATE_LOOKING_FOR; -+ -+ SET_NET_PWR_STATE_ACTIVE(prAdapter, NETWORK_TYPE_AIS_INDEX); -+ -+ break; -+ -+ default: -+ break; -+ } -+ -+ /* Call aisFsmSteps() when we are going to change AIS STATE */ -+ if (eNextState != prAisFsmInfo->eCurrentState) -+ aisFsmSteps(prAdapter, eNextState); -+ -+} /* end of aisFsmBGSleepTimeout() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will indicate an Event of "IBSS ALONE Time-Out" to AIS FSM. -+* -+* @param[in] u4Param Unused timer parameter -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID aisFsmRunEventIbssAloneTimeOut(IN P_ADAPTER_T prAdapter, ULONG ulParam) -+{ -+ P_AIS_FSM_INFO_T prAisFsmInfo; -+ ENUM_AIS_STATE_T eNextState; -+ -+ DEBUGFUNC("aisFsmRunEventIbssAloneTimeOut()"); -+ -+ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); -+ eNextState = prAisFsmInfo->eCurrentState; -+ -+ switch (prAisFsmInfo->eCurrentState) { -+ case AIS_STATE_IBSS_ALONE: -+ -+ /* There is no one participate in our AdHoc during this TIMEOUT Interval -+ * so go back to search for a valid IBSS again. -+ */ -+ -+ DBGLOG(AIS, LOUD, "EVENT-IBSS ALONE TIMER: Start pairing\n"); -+ -+ prAisFsmInfo->fgTryScan = TRUE; -+ -+ /* abort timer */ -+ aisFsmReleaseCh(prAdapter); -+ -+ /* Pull back to SEARCH to find candidate again */ -+ eNextState = AIS_STATE_SEARCH; -+ -+ break; -+ -+ default: -+ break; -+ } -+ -+ /* Call aisFsmSteps() when we are going to change AIS STATE */ -+ if (eNextState != prAisFsmInfo->eCurrentState) -+ aisFsmSteps(prAdapter, eNextState); -+ -+} /* end of aisIbssAloneTimeOut() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will indicate an Event of "Join Time-Out" to AIS FSM. -+* -+* @param[in] u4Param Unused timer parameter -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID aisFsmRunEventJoinTimeout(IN P_ADAPTER_T prAdapter, ULONG ulParam) -+{ -+ P_BSS_INFO_T prAisBssInfo; -+ P_AIS_FSM_INFO_T prAisFsmInfo; -+ ENUM_AIS_STATE_T eNextState; -+ OS_SYSTIME rCurrentTime; -+ -+ DEBUGFUNC("aisFsmRunEventJoinTimeout()"); -+ prAisBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]; -+ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); -+ eNextState = prAisFsmInfo->eCurrentState; -+ -+ GET_CURRENT_SYSTIME(&rCurrentTime); -+ switch (prAisFsmInfo->eCurrentState) { -+ case AIS_STATE_JOIN: -+ DBGLOG(AIS, LOUD, "EVENT- JOIN TIMEOUT\n"); -+ -+ /* 1. Do abort JOIN */ -+ aisFsmStateAbort_JOIN(prAdapter); -+ -+ /* 2. Increase Join Failure Count */ -+ prAisFsmInfo->prTargetBssDesc->ucJoinFailureCount++; -+/* For JB nl802.11 */ -+ if (prAisFsmInfo->prTargetBssDesc->ucJoinFailureCount < JOIN_MAX_RETRY_FAILURE_COUNT) { -+ /* 3.1 Retreat to AIS_STATE_SEARCH state for next try */ -+ eNextState = AIS_STATE_SEARCH; -+ } else if (prAisBssInfo->eConnectionState == PARAM_MEDIA_STATE_CONNECTED) { -+ /* 3.2 Retreat to AIS_STATE_WAIT_FOR_NEXT_SCAN state for next try */ -+ eNextState = AIS_STATE_WAIT_FOR_NEXT_SCAN; -+ } else if (!CHECK_FOR_TIMEOUT(rCurrentTime, prAisFsmInfo->rJoinReqTime, -+ SEC_TO_SYSTIME(AIS_JOIN_TIMEOUT))) { -+ /* 3.3 Retreat to AIS_STATE_WAIT_FOR_NEXT_SCAN state for next try */ -+ eNextState = AIS_STATE_WAIT_FOR_NEXT_SCAN; -+ } else { -+ /* 3.4 Retreat to AIS_STATE_JOIN_FAILURE to terminate join operation */ -+ kalIndicateStatusAndComplete(prAdapter->prGlueInfo, WLAN_STATUS_CONNECT_INDICATION, NULL, 0); -+ eNextState = AIS_STATE_IDLE; -+ } -+ break; -+ -+ case AIS_STATE_NORMAL_TR: -+ /* 1. release channel */ -+ aisFsmReleaseCh(prAdapter); -+ prAisFsmInfo->fgIsInfraChannelFinished = TRUE; -+ -+ /* 2. process if there is pending scan */ -+ if (aisFsmIsRequestPending(prAdapter, AIS_REQUEST_SCAN, TRUE) == TRUE) { -+ wlanClearScanningResult(prAdapter); -+ eNextState = AIS_STATE_ONLINE_SCAN; -+ } -+ -+ break; -+ -+ default: -+ /* release channel */ -+ aisFsmReleaseCh(prAdapter); -+ break; -+ -+ } -+ -+ /* Call aisFsmSteps() when we are going to change AIS STATE */ -+ if (eNextState != prAisFsmInfo->eCurrentState) -+ aisFsmSteps(prAdapter, eNextState); -+ -+} /* end of aisFsmRunEventJoinTimeout() */ -+ -+VOID aisFsmRunEventDeauthTimeout(IN P_ADAPTER_T prAdapter, ULONG ulParam) -+{ -+ aisDeauthXmitComplete(prAdapter, NULL, TX_RESULT_LIFE_TIMEOUT); -+} -+ -+#if defined(CFG_TEST_MGMT_FSM) && (CFG_TEST_MGMT_FSM != 0) -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID aisTest(VOID) -+{ -+ P_MSG_AIS_ABORT_T prAisAbortMsg; -+ P_CONNECTION_SETTINGS_T prConnSettings; -+ UINT_8 aucSSID[] = "pci-11n"; -+ UINT_8 ucSSIDLen = 7; -+ -+ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); -+ -+ /* Set Connection Request Issued Flag */ -+ prConnSettings->fgIsConnReqIssued = TRUE; -+ prConnSettings->ucSSIDLen = ucSSIDLen; -+ kalMemCopy(prConnSettings->aucSSID, aucSSID, ucSSIDLen); -+ -+ prAisAbortMsg = (P_MSG_AIS_ABORT_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_AIS_ABORT_T)); -+ if (!prAisAbortMsg) { -+ -+ ASSERT(0); /* Can't trigger SCAN FSM */ -+ return; -+ } -+ -+ prAisAbortMsg->rMsgHdr.eMsgId = MID_HEM_AIS_FSM_ABORT; -+ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prAisAbortMsg, MSG_SEND_METHOD_BUF); -+ -+ wifi_send_msg(INDX_WIFI, MSG_ID_WIFI_IST, 0); -+ -+} -+#endif /* CFG_TEST_MGMT_FSM */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is used to handle OID_802_11_BSSID_LIST_SCAN -+* -+* \param[in] prAdapter Pointer of ADAPTER_T -+* \param[in] prSsid Pointer of SSID_T if specified -+* \param[in] pucIe Pointer to buffer of extra information elements to be attached -+* \param[in] u4IeLength Length of information elements -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID aisFsmScanRequest(IN P_ADAPTER_T prAdapter, IN P_PARAM_SSID_T prSsid, IN PUINT_8 pucIe, IN UINT_32 u4IeLength) -+{ -+ P_CONNECTION_SETTINGS_T prConnSettings; -+ P_BSS_INFO_T prAisBssInfo; -+ P_AIS_FSM_INFO_T prAisFsmInfo; -+ -+ DEBUGFUNC("aisFsmScanRequest()"); -+ -+ ASSERT(prAdapter); -+ ASSERT(u4IeLength <= MAX_IE_LENGTH); -+ -+ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); -+ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); -+ -+ if (!prConnSettings->fgIsScanReqIssued) { -+ prConnSettings->fgIsScanReqIssued = TRUE; -+ -+ if (prSsid == NULL) { -+ prAisFsmInfo->ucScanSSIDLen = 0; -+ } else { -+ COPY_SSID(prAisFsmInfo->aucScanSSID, -+ prAisFsmInfo->ucScanSSIDLen, prSsid->aucSsid, (UINT_8) prSsid->u4SsidLen); -+ } -+ -+ if (u4IeLength > 0 && u4IeLength <= MAX_IE_LENGTH) { -+ prAisFsmInfo->u4ScanIELength = u4IeLength; -+ kalMemCopy(prAisFsmInfo->aucScanIEBuf, pucIe, u4IeLength); -+ } else { -+ prAisFsmInfo->u4ScanIELength = 0; -+ } -+ -+ if (prAisFsmInfo->eCurrentState == AIS_STATE_NORMAL_TR) { -+ if (prAisBssInfo->eCurrentOPMode == OP_MODE_INFRASTRUCTURE -+ && prAisFsmInfo->fgIsInfraChannelFinished == FALSE) { -+ /* 802.1x might not finished yet, pend it for later handling .. */ -+ aisFsmInsertRequest(prAdapter, AIS_REQUEST_SCAN); -+ } else { -+ if (prAisFsmInfo->fgIsChannelGranted == TRUE) { -+ DBGLOG(AIS, WARN, -+ "Scan Request with channel granted for join operation: %d, %d", -+ prAisFsmInfo->fgIsChannelGranted, prAisFsmInfo->fgIsChannelRequested); -+ } -+ -+ /* start online scan */ -+ wlanClearScanningResult(prAdapter); -+ aisFsmSteps(prAdapter, AIS_STATE_ONLINE_SCAN); -+ } -+ } else if (prAisFsmInfo->eCurrentState == AIS_STATE_IDLE) { -+ wlanClearScanningResult(prAdapter); -+ aisFsmSteps(prAdapter, AIS_STATE_SCAN); -+ } else { -+ aisFsmInsertRequest(prAdapter, AIS_REQUEST_SCAN); -+ } -+ } else { -+ DBGLOG(AIS, WARN, "Scan Request dropped. (state: %d)\n", prAisFsmInfo->eCurrentState); -+ } -+ -+} /* end of aisFsmScanRequest() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is invoked when CNM granted channel privilege -+* -+* \param[in] prAdapter Pointer of ADAPTER_T -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID aisFsmRunEventChGrant(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) -+{ -+ P_BSS_INFO_T prAisBssInfo; -+ P_AIS_FSM_INFO_T prAisFsmInfo; -+ P_MSG_CH_GRANT_T prMsgChGrant; -+ UINT_8 ucTokenID; -+ UINT_32 u4GrantInterval; -+ -+ ASSERT(prAdapter); -+ ASSERT(prMsgHdr); -+ -+ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); -+ prMsgChGrant = (P_MSG_CH_GRANT_T) prMsgHdr; -+ -+ ucTokenID = prMsgChGrant->ucTokenID; -+ u4GrantInterval = prMsgChGrant->u4GrantInterval; -+ -+ /* 1. free message */ -+ cnmMemFree(prAdapter, prMsgHdr); -+ -+ if (prAisFsmInfo->eCurrentState == AIS_STATE_REQ_CHANNEL_JOIN && prAisFsmInfo->ucSeqNumOfChReq == ucTokenID) { -+ /* 2. channel privilege has been approved */ -+ prAisFsmInfo->u4ChGrantedInterval = u4GrantInterval; -+ -+ /* 3. state transition to join/ibss-alone/ibss-merge */ -+ /* 3.1 set timeout timer in cases join could not be completed */ -+ cnmTimerStartTimer(prAdapter, -+ &prAisFsmInfo->rJoinTimeoutTimer, -+ prAisFsmInfo->u4ChGrantedInterval - AIS_JOIN_CH_GRANT_THRESHOLD); -+ /* 3.2 set local variable to indicate join timer is ticking */ -+ prAisFsmInfo->fgIsInfraChannelFinished = FALSE; -+ -+ /* 3.3 switch to join state */ -+ aisFsmSteps(prAdapter, AIS_STATE_JOIN); -+ -+ prAisFsmInfo->fgIsChannelGranted = TRUE; -+ } else if (prAisFsmInfo->eCurrentState == AIS_STATE_REQ_REMAIN_ON_CHANNEL && -+ prAisFsmInfo->ucSeqNumOfChReq == ucTokenID) { -+ /* 2. channel privilege has been approved */ -+ prAisFsmInfo->u4ChGrantedInterval = u4GrantInterval; -+ -+ /* 3.1 set timeout timer in cases upper layer cancel_remain_on_channel never comes */ -+ cnmTimerStartTimer(prAdapter, &prAisFsmInfo->rChannelTimeoutTimer, prAisFsmInfo->u4ChGrantedInterval); -+ -+ /* 3.2 switch to remain_on_channel state */ -+ aisFsmSteps(prAdapter, AIS_STATE_REMAIN_ON_CHANNEL); -+ -+ /* 3.3. indicate upper layer for channel ready */ -+ kalReadyOnChannel(prAdapter->prGlueInfo, -+ prAisFsmInfo->rChReqInfo.u8Cookie, -+ prAisFsmInfo->rChReqInfo.eBand, -+ prAisFsmInfo->rChReqInfo.eSco, -+ prAisFsmInfo->rChReqInfo.ucChannelNum, prAisFsmInfo->rChReqInfo.u4DurationMs); -+ -+ prAisFsmInfo->fgIsChannelGranted = TRUE; -+ } else { /* mismatched grant */ -+ /* 2. return channel privilege to CNM immediately */ -+ aisFsmReleaseCh(prAdapter); -+ } -+ -+} /* end of aisFsmRunEventChGrant() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is to inform CNM that channel privilege -+* has been released -+* -+* \param[in] prAdapter Pointer of ADAPTER_T -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID aisFsmReleaseCh(IN P_ADAPTER_T prAdapter) -+{ -+ P_AIS_FSM_INFO_T prAisFsmInfo; -+ P_MSG_CH_ABORT_T prMsgChAbort; -+ -+ ASSERT(prAdapter); -+ -+ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); -+ -+ if (prAisFsmInfo->fgIsChannelGranted == TRUE || prAisFsmInfo->fgIsChannelRequested == TRUE) { -+ -+ prAisFsmInfo->fgIsChannelRequested = FALSE; -+ prAisFsmInfo->fgIsChannelGranted = FALSE; -+ -+ /* 1. return channel privilege to CNM immediately */ -+ prMsgChAbort = (P_MSG_CH_ABORT_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_CH_ABORT_T)); -+ if (!prMsgChAbort) { -+ ASSERT(0); /* Can't release Channel to CNM */ -+ return; -+ } -+ -+ prMsgChAbort->rMsgHdr.eMsgId = MID_MNY_CNM_CH_ABORT; -+ prMsgChAbort->ucNetTypeIndex = NETWORK_TYPE_AIS_INDEX; -+ prMsgChAbort->ucTokenID = prAisFsmInfo->ucSeqNumOfChReq; -+ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgChAbort, MSG_SEND_METHOD_BUF); -+ } -+ -+} /* end of aisFsmReleaseCh() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is to inform AIS that corresponding beacon has not -+* been received for a while and probing is not successful -+* -+* \param[in] prAdapter Pointer of ADAPTER_T -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID aisBssBeaconTimeout(IN P_ADAPTER_T prAdapter) -+{ -+ P_BSS_INFO_T prAisBssInfo; -+ BOOLEAN fgDoAbortIndication = FALSE; -+ -+ ASSERT(prAdapter); -+ -+ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ -+ /* 4 <1> Diagnose Connection for Beacon Timeout Event */ -+ if (PARAM_MEDIA_STATE_CONNECTED == prAisBssInfo->eConnectionState) { -+ if (OP_MODE_INFRASTRUCTURE == prAisBssInfo->eCurrentOPMode) { -+ P_STA_RECORD_T prStaRec = prAisBssInfo->prStaRecOfAP; -+ -+ if (prStaRec) -+ fgDoAbortIndication = TRUE; -+ } else if (OP_MODE_IBSS == prAisBssInfo->eCurrentOPMode) { -+ fgDoAbortIndication = TRUE; -+ } -+ } -+ /* 4 <2> invoke abort handler */ -+ if (fgDoAbortIndication) { -+#if 0 -+ P_CONNECTION_SETTINGS_T prConnSettings; -+ -+ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); -+ prConnSettings->fgIsDisconnectedByNonRequest = TRUE; -+#endif -+ -+ DBGLOG(AIS, INFO, "Beacon Timeout, Remove BSS [%pM]\n", prAisBssInfo->aucBSSID); -+ scanRemoveBssDescByBssid(prAdapter, prAisBssInfo->aucBSSID); -+ -+ /* -+ Note: Cannot change TRUE to FALSE; or you will suffer the problem in -+ ALPS01270257/ ALPS01804173 -+ */ -+ aisFsmStateAbort(prAdapter, DISCONNECT_REASON_CODE_RADIO_LOST, TRUE); -+ } -+ -+} /* end of aisBssBeaconTimeout() */ -+ -+VOID aisBssSecurityChanged(P_ADAPTER_T prAdapter) -+{ -+ P_BSS_INFO_T prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ -+ prAdapter->rWifiVar.rConnSettings.fgIsDisconnectedByNonRequest = TRUE; -+ prAisBssInfo->u2DeauthReason = REASON_CODE_BSS_SECURITY_CHANGE; -+ aisFsmStateAbort(prAdapter, DISCONNECT_REASON_CODE_DEAUTHENTICATED, FALSE); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is to inform AIS that DEAUTH frame has been -+* sent and thus state machine could go ahead -+* -+* \param[in] prAdapter Pointer of ADAPTER_T -+* \param[in] prMsduInfo Pointer of MSDU_INFO_T for DEAUTH frame -+* \param[in] prAdapter Pointer of ADAPTER_T -+* -+* \return WLAN_STATUS_SUCCESS -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+aisDeauthXmitComplete(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus) -+{ -+ P_AIS_FSM_INFO_T prAisFsmInfo; -+ -+ ASSERT(prAdapter); -+ -+ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); -+ -+ if (rTxDoneStatus == TX_RESULT_SUCCESS) -+ cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rDeauthDoneTimer); -+ -+ if (prAisFsmInfo->eCurrentState == AIS_STATE_DISCONNECTING) { -+ if (rTxDoneStatus != TX_RESULT_DROPPED_IN_DRIVER) -+ aisFsmStateAbort(prAdapter, DISCONNECT_REASON_CODE_NEW_CONNECTION, FALSE); -+ } else { -+ DBGLOG(AIS, WARN, "DEAUTH frame transmitted without further handling"); -+ } -+ -+ return WLAN_STATUS_SUCCESS; -+ -+} /* end of aisDeauthXmitComplete() */ -+ -+#if CFG_SUPPORT_ROAMING -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will indicate an Event of "Looking for a candidate due to weak signal" to AIS FSM. -+* -+* @param[in] u4ReqScan Requesting Scan or not -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID aisFsmRunEventRoamingDiscovery(IN P_ADAPTER_T prAdapter, UINT_32 u4ReqScan) -+{ -+ P_AIS_FSM_INFO_T prAisFsmInfo; -+ P_CONNECTION_SETTINGS_T prConnSettings; -+ ENUM_AIS_REQUEST_TYPE_T eAisRequest; -+ -+ DBGLOG(AIS, LOUD, "aisFsmRunEventRoamingDiscovery()\n"); -+ -+ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); -+ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); -+ -+ /* search candidates by best rssi */ -+ prConnSettings->eConnectionPolicy = CONNECT_BY_SSID_BEST_RSSI; -+ -+#if CFG_SUPPORT_WFD -+#if CFG_ENABLE_WIFI_DIRECT -+ { -+ /* Check WFD is running */ -+ P_BSS_INFO_T prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); -+ P_WFD_CFG_SETTINGS_T prWfdCfgSettings = (P_WFD_CFG_SETTINGS_T) NULL; -+ -+ if (prAdapter->fgIsP2PRegistered && -+ IS_BSS_ACTIVE(prP2pBssInfo) && -+ (prP2pBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT || -+ prP2pBssInfo->eCurrentOPMode == OP_MODE_INFRASTRUCTURE)) { -+ DBGLOG(ROAMING, INFO, "Handle roaming when P2P is GC or GO.\n"); -+ if (prAdapter->rWifiVar.prP2pFsmInfo) { -+ prWfdCfgSettings = &(prAdapter->rWifiVar.prP2pFsmInfo->rWfdConfigureSettings); -+ if ((prWfdCfgSettings->ucWfdEnable == 1) && -+ ((prWfdCfgSettings->u4WfdFlag & WFD_FLAGS_DEV_INFO_VALID))) { -+ DBGLOG(ROAMING, INFO, "WFD is running. Stop roaming.\n"); -+ roamingFsmRunEventRoam(prAdapter); -+ roamingFsmRunEventFail(prAdapter, ROAMING_FAIL_REASON_NOCANDIDATE); -+ return; -+ } -+ } else { -+ ASSERT(0); -+ } -+ } /* fgIsP2PRegistered */ -+ } -+#endif -+#endif -+ -+ /* results are still new */ -+ if (!u4ReqScan) { -+ roamingFsmRunEventRoam(prAdapter); -+ eAisRequest = AIS_REQUEST_ROAMING_CONNECT; -+ } else { -+ if (prAisFsmInfo->eCurrentState == AIS_STATE_ONLINE_SCAN -+ || prAisFsmInfo->eCurrentState == AIS_STATE_LOOKING_FOR) { -+ eAisRequest = AIS_REQUEST_ROAMING_CONNECT; -+ } else { -+ eAisRequest = AIS_REQUEST_ROAMING_SEARCH; -+ } -+ } -+ -+ if (prAisFsmInfo->eCurrentState == AIS_STATE_NORMAL_TR && prAisFsmInfo->fgIsInfraChannelFinished == TRUE) { -+ if (eAisRequest == AIS_REQUEST_ROAMING_SEARCH) -+ aisFsmSteps(prAdapter, AIS_STATE_LOOKING_FOR); -+ else -+ aisFsmSteps(prAdapter, AIS_STATE_SEARCH); -+ } else { -+ aisFsmIsRequestPending(prAdapter, AIS_REQUEST_ROAMING_SEARCH, TRUE); -+ aisFsmIsRequestPending(prAdapter, AIS_REQUEST_ROAMING_CONNECT, TRUE); -+ -+ aisFsmInsertRequest(prAdapter, eAisRequest); -+ } -+ -+} /* end of aisFsmRunEventRoamingDiscovery() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Update the time of ScanDone for roaming and transit to Roam state. -+* -+* @param (none) -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+ENUM_AIS_STATE_T aisFsmRoamingScanResultsUpdate(IN P_ADAPTER_T prAdapter) -+{ -+ P_AIS_FSM_INFO_T prAisFsmInfo; -+ P_ROAMING_INFO_T prRoamingFsmInfo; -+ ENUM_AIS_STATE_T eNextState; -+ -+ DBGLOG(AIS, LOUD, "->aisFsmRoamingScanResultsUpdate()\n"); -+ -+ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); -+ prRoamingFsmInfo = (P_ROAMING_INFO_T) &(prAdapter->rWifiVar.rRoamingInfo); -+ -+ roamingFsmScanResultsUpdate(prAdapter); -+ -+ eNextState = prAisFsmInfo->eCurrentState; -+ if (prRoamingFsmInfo->eCurrentState == ROAMING_STATE_DISCOVERY) { -+ roamingFsmRunEventRoam(prAdapter); -+ eNextState = AIS_STATE_SEARCH; -+ } else if (prAisFsmInfo->eCurrentState == AIS_STATE_LOOKING_FOR) { -+ eNextState = AIS_STATE_SEARCH; -+ } else if (prAisFsmInfo->eCurrentState == AIS_STATE_ONLINE_SCAN) { -+ eNextState = AIS_STATE_NORMAL_TR; -+ } -+ -+ return eNextState; -+} /* end of aisFsmRoamingScanResultsUpdate() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will modify and update necessary information to firmware -+* for disconnection of last AP before switching to roaming bss. -+* -+* @param IN prAdapter Pointer to the Adapter structure. -+* prTargetStaRec Target of StaRec of roaming -+* -+* @retval None -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID aisFsmRoamingDisconnectPrevAP(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prTargetStaRec) -+{ -+ P_BSS_INFO_T prAisBssInfo; -+ -+ DBGLOG(AIS, LOUD, "aisFsmRoamingDisconnectPrevAP()"); -+ -+ ASSERT(prAdapter); -+ -+ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ -+ nicPmIndicateBssAbort(prAdapter, NETWORK_TYPE_AIS_INDEX); -+ -+ /* Not invoke rlmBssAborted() here to avoid prAisBssInfo->fg40mBwAllowed -+ * to be reset. RLM related parameters will be reset again when handling -+ * association response in rlmProcessAssocRsp(). 20110413 -+ */ -+ /* rlmBssAborted(prAdapter, prAisBssInfo); */ -+ -+ /* 4 <3> Unset the fgIsConnected flag of BSS_DESC_T and send Deauth if needed. */ -+ if (PARAM_MEDIA_STATE_CONNECTED == prAisBssInfo->eConnectionState) -+ scanRemoveConnFlagOfBssDescByBssid(prAdapter, prAisBssInfo->aucBSSID); -+ /* 4 <4> Change Media State immediately. */ -+ aisChangeMediaState(prAdapter, PARAM_MEDIA_STATE_DISCONNECTED); -+ -+ /* 4 <4.1> sync. with firmware */ -+ prTargetStaRec->ucNetTypeIndex = 0xff; /* Virtial NetType */ -+ nicUpdateBss(prAdapter, NETWORK_TYPE_AIS_INDEX); -+ prTargetStaRec->ucNetTypeIndex = NETWORK_TYPE_AIS_INDEX; /* Virtial NetType */ -+ -+#if (CFG_SUPPORT_TDLS == 1) -+ TdlsexLinkHistoryRecord(prAdapter->prGlueInfo, TRUE, prAisBssInfo->aucBSSID, -+ TRUE, TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_ROAMING); -+#endif /* CFG_SUPPORT_TDLS */ -+ -+} /* end of aisFsmRoamingDisconnectPrevAP() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will update the contain of BSS_INFO_T for AIS network once -+* the roaming was completed. -+* -+* @param IN prAdapter Pointer to the Adapter structure. -+* prStaRec StaRec of roaming AP -+* prAssocRspSwRfb -+* -+* @retval None -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID aisUpdateBssInfoForRoamingAP(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN P_SW_RFB_T prAssocRspSwRfb) -+{ -+ P_BSS_INFO_T prAisBssInfo; -+ -+ DBGLOG(AIS, LOUD, "aisUpdateBssInfoForRoamingAP()"); -+ -+ ASSERT(prAdapter); -+ -+ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ -+ /* 4 <1.1> Change FW's Media State immediately. */ -+ aisChangeMediaState(prAdapter, PARAM_MEDIA_STATE_CONNECTED); -+ -+ /* 4 <1.2> Deactivate previous AP's STA_RECORD_T in Driver if have. */ -+ if ((prAisBssInfo->prStaRecOfAP) && -+ (prAisBssInfo->prStaRecOfAP != prStaRec) && (prAisBssInfo->prStaRecOfAP->fgIsInUse)) { -+ cnmStaRecChangeState(prAdapter, prAisBssInfo->prStaRecOfAP, STA_STATE_1); -+ } -+ /* 4 <1.3> Update BSS_INFO_T */ -+ aisUpdateBssInfoForJOIN(prAdapter, prStaRec, prAssocRspSwRfb); -+ -+ /* 4 <1.4> Activate current AP's STA_RECORD_T in Driver. */ -+ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_3); -+ -+ /* 4 <1.6> Indicate Connected Event to Host immediately. */ -+ /* Require BSSID, Association ID, Beacon Interval.. from AIS_BSS_INFO_T */ -+ aisIndicationOfMediaStateToHost(prAdapter, PARAM_MEDIA_STATE_CONNECTED, FALSE); -+ -+} /* end of aisFsmRoamingUpdateBss() */ -+ -+#endif /* CFG_SUPPORT_ROAMING */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Check if there is any pending request and remove it (optional) -+* -+* @param prAdapter -+* eReqType -+* bRemove -+* -+* @return TRUE -+* FALSE -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN aisFsmIsRequestPending(IN P_ADAPTER_T prAdapter, IN ENUM_AIS_REQUEST_TYPE_T eReqType, IN BOOLEAN bRemove) -+{ -+ P_AIS_FSM_INFO_T prAisFsmInfo; -+ P_AIS_REQ_HDR_T prPendingReqHdr, prPendingReqHdrNext; -+ -+ ASSERT(prAdapter); -+ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); -+ -+ /* traverse through pending request list */ -+ LINK_FOR_EACH_ENTRY_SAFE(prPendingReqHdr, -+ prPendingReqHdrNext, &(prAisFsmInfo->rPendingReqList), rLinkEntry, AIS_REQ_HDR_T) { -+ /* check for specified type */ -+ if (prPendingReqHdr->eReqType == eReqType) { -+ /* check if need to remove */ -+ if (bRemove == TRUE) { -+ LINK_REMOVE_KNOWN_ENTRY(&(prAisFsmInfo->rPendingReqList), -+ &(prPendingReqHdr->rLinkEntry)); -+ -+ cnmMemFree(prAdapter, prPendingReqHdr); -+ } -+ -+ return TRUE; -+ } -+ } -+ -+ return FALSE; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Get next pending request -+* -+* @param prAdapter -+* -+* @return P_AIS_REQ_HDR_T -+*/ -+/*----------------------------------------------------------------------------*/ -+P_AIS_REQ_HDR_T aisFsmGetNextRequest(IN P_ADAPTER_T prAdapter) -+{ -+ P_AIS_FSM_INFO_T prAisFsmInfo; -+ P_AIS_REQ_HDR_T prPendingReqHdr; -+ -+ ASSERT(prAdapter); -+ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); -+ -+ LINK_REMOVE_HEAD(&(prAisFsmInfo->rPendingReqList), prPendingReqHdr, P_AIS_REQ_HDR_T); -+ -+ return prPendingReqHdr; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Insert a new request -+* -+* @param prAdapter -+* eReqType -+* -+* @return TRUE -+* FALSE -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN aisFsmInsertRequest(IN P_ADAPTER_T prAdapter, IN ENUM_AIS_REQUEST_TYPE_T eReqType) -+{ -+ P_AIS_REQ_HDR_T prAisReq; -+ P_AIS_FSM_INFO_T prAisFsmInfo; -+ -+ ASSERT(prAdapter); -+ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); -+ -+ prAisReq = (P_AIS_REQ_HDR_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(AIS_REQ_HDR_T)); -+ -+ if (!prAisReq) { -+ ASSERT(0); /* Can't generate new message */ -+ return FALSE; -+ } -+ -+ prAisReq->eReqType = eReqType; -+ -+ /* attach request into pending request list */ -+ LINK_INSERT_TAIL(&prAisFsmInfo->rPendingReqList, &prAisReq->rLinkEntry); -+ -+ return TRUE; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Flush all pending requests -+* -+* @param prAdapter -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID aisFsmFlushRequest(IN P_ADAPTER_T prAdapter) -+{ -+ P_AIS_REQ_HDR_T prAisReq; -+ -+ ASSERT(prAdapter); -+ -+ while ((prAisReq = aisFsmGetNextRequest(prAdapter)) != NULL) -+ cnmMemFree(prAdapter, prAisReq); -+ -+} -+ -+VOID aisFsmRunEventRemainOnChannel(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) -+{ -+ P_MSG_REMAIN_ON_CHANNEL_T prRemainOnChannel; -+ P_AIS_FSM_INFO_T prAisFsmInfo; -+ P_CONNECTION_SETTINGS_T prConnSettings; -+ -+ DEBUGFUNC("aisFsmRunEventRemainOnChannel()"); -+ -+ ASSERT(prAdapter); -+ ASSERT(prMsgHdr); -+ -+ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); -+ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); -+ -+ prRemainOnChannel = (P_MSG_REMAIN_ON_CHANNEL_T) prMsgHdr; -+ -+ /* record parameters */ -+ prAisFsmInfo->rChReqInfo.eBand = prRemainOnChannel->eBand; -+ prAisFsmInfo->rChReqInfo.eSco = prRemainOnChannel->eSco; -+ prAisFsmInfo->rChReqInfo.ucChannelNum = prRemainOnChannel->ucChannelNum; -+ prAisFsmInfo->rChReqInfo.u4DurationMs = prRemainOnChannel->u4DurationMs; -+ prAisFsmInfo->rChReqInfo.u8Cookie = prRemainOnChannel->u8Cookie; -+ -+ if (prAisFsmInfo->eCurrentState == AIS_STATE_IDLE || prAisFsmInfo->eCurrentState == AIS_STATE_NORMAL_TR) { -+ /* transit to next state */ -+ aisFsmSteps(prAdapter, AIS_STATE_REQ_REMAIN_ON_CHANNEL); -+ } else { -+ aisFsmInsertRequest(prAdapter, AIS_REQUEST_REMAIN_ON_CHANNEL); -+ } -+ -+ /* free messages */ -+ cnmMemFree(prAdapter, prMsgHdr); -+ -+} -+ -+VOID aisFsmRunEventCancelRemainOnChannel(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) -+{ -+ P_AIS_FSM_INFO_T prAisFsmInfo; -+ P_BSS_INFO_T prAisBssInfo; -+ P_MSG_CANCEL_REMAIN_ON_CHANNEL_T prCancelRemainOnChannel; -+ -+ ASSERT(prAdapter); -+ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); -+ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ -+ prCancelRemainOnChannel = (P_MSG_CANCEL_REMAIN_ON_CHANNEL_T) prMsgHdr; -+ -+ /* 1. Check the cookie first */ -+ if (prCancelRemainOnChannel->u8Cookie == prAisFsmInfo->rChReqInfo.u8Cookie) { -+ -+ /* 2. release channel privilege/request */ -+ if (prAisFsmInfo->eCurrentState == AIS_STATE_REQ_REMAIN_ON_CHANNEL) { -+ /* 2.1 elease channel */ -+ aisFsmReleaseCh(prAdapter); -+ } else if (prAisFsmInfo->eCurrentState == AIS_STATE_REMAIN_ON_CHANNEL) { -+ /* 2.1 release channel */ -+ aisFsmReleaseCh(prAdapter); -+ -+ /* 2.2 stop channel timeout timer */ -+ cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rChannelTimeoutTimer); -+ } -+ -+ /* 3. clear pending request of remain_on_channel */ -+ aisFsmIsRequestPending(prAdapter, AIS_REQUEST_REMAIN_ON_CHANNEL, TRUE); -+ -+ /* 4. decide which state to retreat */ -+ if (prAisBssInfo->eConnectionState == PARAM_MEDIA_STATE_CONNECTED) -+ aisFsmSteps(prAdapter, AIS_STATE_NORMAL_TR); -+ else -+ aisFsmSteps(prAdapter, AIS_STATE_IDLE); -+ } -+ -+ /* 5. free message */ -+ cnmMemFree(prAdapter, prMsgHdr); -+ -+} -+ -+VOID aisFsmRunEventMgmtFrameTx(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) -+{ -+ P_AIS_FSM_INFO_T prAisFsmInfo; -+ P_MSG_MGMT_TX_REQUEST_T prMgmtTxMsg = (P_MSG_MGMT_TX_REQUEST_T) NULL; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prMsgHdr != NULL)); -+ -+ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); -+ /* prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); */ -+ -+ if (prAisFsmInfo == NULL) -+ break; -+ prMgmtTxMsg = (P_MSG_MGMT_TX_REQUEST_T) prMsgHdr; -+ -+ aisFuncTxMgmtFrame(prAdapter, -+ &prAisFsmInfo->rMgmtTxInfo, prMgmtTxMsg->prMgmtMsduInfo, prMgmtTxMsg->u8Cookie); -+ -+ } while (FALSE); -+ -+ if (prMsgHdr) -+ cnmMemFree(prAdapter, prMsgHdr); -+ -+} /* aisFsmRunEventMgmtFrameTx */ -+ -+VOID aisFsmRunEventChannelTimeout(IN P_ADAPTER_T prAdapter, ULONG ulParam) -+{ -+ P_AIS_FSM_INFO_T prAisFsmInfo; -+ P_BSS_INFO_T prAisBssInfo; -+ -+ DEBUGFUNC("aisFsmRunEventRemainOnChannel()"); -+ -+ ASSERT(prAdapter); -+ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); -+ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ -+ if (prAisFsmInfo->eCurrentState == AIS_STATE_REMAIN_ON_CHANNEL) { -+ /* 1. release channel */ -+ aisFsmReleaseCh(prAdapter); -+ -+ /* 2. stop channel timeout timer */ -+ cnmTimerStopTimer(prAdapter, &prAisFsmInfo->rChannelTimeoutTimer); -+ -+ /* 3. expiration indication to upper layer */ -+ kalRemainOnChannelExpired(prAdapter->prGlueInfo, -+ prAisFsmInfo->rChReqInfo.u8Cookie, -+ prAisFsmInfo->rChReqInfo.eBand, -+ prAisFsmInfo->rChReqInfo.eSco, prAisFsmInfo->rChReqInfo.ucChannelNum); -+ -+ /* 4. decide which state to retreat */ -+ if (prAisBssInfo->eConnectionState == PARAM_MEDIA_STATE_CONNECTED) -+ aisFsmSteps(prAdapter, AIS_STATE_NORMAL_TR); -+ else -+ aisFsmSteps(prAdapter, AIS_STATE_IDLE); -+ } else { -+ DBGLOG(AIS, WARN, "Unexpected remain_on_channel timeout event\n"); -+#if DBG -+ DBGLOG(AIS, STATE, "CURRENT State: [%s]\n", apucDebugAisState[prAisFsmInfo->eCurrentState]); -+#else -+ DBGLOG(AIS, STATE, "[%d] CURRENT State: [%d]\n", DBG_AIS_IDX, prAisFsmInfo->eCurrentState); -+#endif -+ } -+ -+} -+ -+WLAN_STATUS -+aisFsmRunEventMgmtFrameTxDone(IN P_ADAPTER_T prAdapter, -+ IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus) -+{ -+ P_AIS_FSM_INFO_T prAisFsmInfo; -+ P_AIS_MGMT_TX_REQ_INFO_T prMgmtTxReqInfo = (P_AIS_MGMT_TX_REQ_INFO_T) NULL; -+ BOOLEAN fgIsSuccess = FALSE; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prMsduInfo != NULL)); -+ -+ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); -+ prMgmtTxReqInfo = &(prAisFsmInfo->rMgmtTxInfo); -+ -+ if (rTxDoneStatus != TX_RESULT_SUCCESS) { -+ DBGLOG(AIS, ERROR, "Mgmt Frame TX Fail, Status:%d.\n", rTxDoneStatus); -+ } else { -+ fgIsSuccess = TRUE; -+ /* printk("Mgmt Frame TX Done.\n"); */ -+ } -+ -+ if (prMgmtTxReqInfo->prMgmtTxMsdu == prMsduInfo) { -+ kalIndicateMgmtTxStatus(prAdapter->prGlueInfo, -+ prMgmtTxReqInfo->u8Cookie, -+ fgIsSuccess, prMsduInfo->prPacket, (UINT_32) prMsduInfo->u2FrameLength); -+ -+ prMgmtTxReqInfo->prMgmtTxMsdu = NULL; -+ } -+ -+ } while (FALSE); -+ -+ return WLAN_STATUS_SUCCESS; -+ -+} /* aisFsmRunEventMgmtFrameTxDone */ -+ -+WLAN_STATUS -+aisFuncTxMgmtFrame(IN P_ADAPTER_T prAdapter, -+ IN P_AIS_MGMT_TX_REQ_INFO_T prMgmtTxReqInfo, IN P_MSDU_INFO_T prMgmtTxMsdu, IN UINT_64 u8Cookie) -+{ -+ WLAN_STATUS rWlanStatus = WLAN_STATUS_SUCCESS; -+ P_MSDU_INFO_T prTxMsduInfo = (P_MSDU_INFO_T) NULL; -+ P_WLAN_MAC_HEADER_T prWlanHdr = (P_WLAN_MAC_HEADER_T) NULL; -+ P_STA_RECORD_T prStaRec = (P_STA_RECORD_T) NULL; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prMgmtTxReqInfo != NULL)); -+ -+ if (prMgmtTxReqInfo->fgIsMgmtTxRequested) { -+ -+ /* 1. prMgmtTxReqInfo->prMgmtTxMsdu != NULL */ -+ /* Packet on driver, not done yet, drop it. */ -+ prTxMsduInfo = prMgmtTxReqInfo->prMgmtTxMsdu; -+ if (prTxMsduInfo != NULL) { -+ -+ kalIndicateMgmtTxStatus(prAdapter->prGlueInfo, -+ prMgmtTxReqInfo->u8Cookie, -+ FALSE, -+ prTxMsduInfo->prPacket, (UINT_32) prTxMsduInfo->u2FrameLength); -+ -+ /* Leave it to TX Done handler. */ -+ /* cnmMgtPktFree(prAdapter, prTxMsduInfo); */ -+ prMgmtTxReqInfo->prMgmtTxMsdu = NULL; -+ } -+ /* 2. prMgmtTxReqInfo->prMgmtTxMsdu == NULL */ -+ /* Packet transmitted, wait tx done. (cookie issue) */ -+ } -+ -+ ASSERT(prMgmtTxReqInfo->prMgmtTxMsdu == NULL); -+ -+ prWlanHdr = (P_WLAN_MAC_HEADER_T) ((ULONG) prMgmtTxMsdu->prPacket + MAC_TX_RESERVED_FIELD); -+ prStaRec = cnmGetStaRecByAddress(prAdapter, NETWORK_TYPE_AIS_INDEX, prWlanHdr->aucAddr1); -+ prMgmtTxMsdu->ucNetworkType = (UINT_8) NETWORK_TYPE_AIS_INDEX; -+ -+ prMgmtTxReqInfo->u8Cookie = u8Cookie; -+ prMgmtTxReqInfo->prMgmtTxMsdu = prMgmtTxMsdu; -+ prMgmtTxReqInfo->fgIsMgmtTxRequested = TRUE; -+ -+ prMgmtTxMsdu->eSrc = TX_PACKET_MGMT; -+ prMgmtTxMsdu->ucPacketType = HIF_TX_PACKET_TYPE_MGMT; -+ prMgmtTxMsdu->ucStaRecIndex = (prStaRec != NULL) ? (prStaRec->ucIndex) : (0xFF); -+ if (prStaRec != NULL) { -+ /* Do nothing */ -+ /* printk("Mgmt with station record: %pM .\n", prStaRec->aucMacAddr); */ -+ } -+ -+ prMgmtTxMsdu->ucMacHeaderLength = WLAN_MAC_MGMT_HEADER_LEN; /* TODO: undcertain. */ -+ prMgmtTxMsdu->fgIs802_1x = FALSE; -+ prMgmtTxMsdu->fgIs802_11 = TRUE; -+ prMgmtTxMsdu->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter); -+ prMgmtTxMsdu->pfTxDoneHandler = aisFsmRunEventMgmtFrameTxDone; -+ prMgmtTxMsdu->fgIsBasicRate = TRUE; -+ DBGLOG(AIS, TRACE, "Mgmt seq NO. %d .\n", prMgmtTxMsdu->ucTxSeqNum); -+ -+ nicTxEnqueueMsdu(prAdapter, prMgmtTxMsdu); -+ -+ } while (FALSE); -+ -+ return rWlanStatus; -+} /* aisFuncTxMgmtFrame */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will validate the Rx Action Frame and indicate to uppoer layer -+* if the specified conditions were matched. -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* @param[in] prSwRfb Pointer to SW RFB data structure. -+* @param[out] pu4ControlFlags Control flags for replying the Probe Response -+* -+* @retval none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID aisFuncValidateRxActionFrame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb) -+{ -+ P_AIS_FSM_INFO_T prAisFsmInfo = (P_AIS_FSM_INFO_T) NULL; -+ -+ DEBUGFUNC("aisFuncValidateRxActionFrame"); -+ -+ do { -+ -+ ASSERT_BREAK((prAdapter != NULL) && (prSwRfb != NULL)); -+ -+ prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); -+ -+ if (1 /* prAisFsmInfo->u4AisPacketFilter & PARAM_PACKET_FILTER_ACTION_FRAME */) { -+ /* Leave the action frame to wpa_supplicant. */ -+ kalIndicateRxMgmtFrame(prAdapter->prGlueInfo, prSwRfb); -+ } -+ -+ } while (FALSE); -+ -+ return; -+ -+} /* aisFuncValidateRxActionFrame */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/assoc.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/assoc.c -new file mode 100644 -index 000000000000..f02d7c3bb5b2 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/assoc.c -@@ -0,0 +1,1932 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/assoc.c#3 -+*/ -+ -+/*! \file "assoc.c" -+ \brief This file includes the association-related functions. -+ -+ This file includes the association-related functions. -+*/ -+ -+/*\ -+** Log: assoc.c -+** -+** 07 27 2012 yuche.tsai -+** [ALPS00324337] [ALPS.JB][Hot-Spot] Driver update for Hot-Spot -+** Fix wifi direct connection issue. -+ * -+ * 07 17 2012 yuche.tsai -+ * NULL -+ * Let netdev bring up. -+ * -+ * 07 17 2012 yuche.tsai -+ * NULL -+ * Compile no error before trial run. -+ * -+ * 06 13 2012 yuche.tsai -+ * NULL -+ * Update maintrunk driver. -+ * Add support for driver compose assoc request frame. -+ * -+ * 06 08 2012 cp.wu -+ * [WCXRP00001245] [MT6620 Wi-Fi][Driver][Firmware] NPS Software Development -+ * add a pair of brace for compilation success. -+ * -+ * 06 04 2012 cp.wu -+ * [WCXRP00001245] [MT6620 Wi-Fi][Driver][Firmware] NPS Software Development -+ * discussed with WH, privacy bit in associate response is not necessary to be checked, -+ * and identified as association failure when mismatching with beacon/probe response -+ * -+ * 03 14 2012 wh.su -+ * [WCXRP00001173] [MT6620 Wi-Fi][Driver] Adding the ICS Tethering WPA2-PSK supporting -+ * Add code from 2.2 -+ * -+ * 03 09 2012 terry.wu -+ * NULL -+ * Fix build error. -+ * -+ * 03 02 2012 terry.wu -+ * NULL -+ * Sync CFG80211 modification from branch 2,2. -+ * -+ * 01 16 2012 yuche.tsai -+ * NULL -+ * Update Driver for wifi driect gc join IE update issue. -+ * -+ * 11 10 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * change the debug module level. -+ * -+ * 10 25 2011 cm.chang -+ * [WCXRP00001058] [All Wi-Fi][Driver] Fix sta_rec's phyTypeSet and OBSS scan in AP mode -+ * Fix PhyTypeSet in STA_REC in AP mode -+ * -+ * 10 12 2011 wh.su -+ * [WCXRP00001036] [MT6620 Wi-Fi][Driver][FW] Adding the 802.11w code for MFP -+ * adding the 802.11w related function and define . -+ * -+ * 09 19 2011 yuche.tsai -+ * NULL -+ * Fix KE when enable hot-spot & any one client connect to this hot-spot. -+ * -+ * 09 14 2011 yuche.tsai -+ * NULL -+ * Add P2P IE in assoc response. -+ * -+ * 07 15 2011 terry.wu -+ * [WCXRP00000855] [MT6620 Wi-Fi] [Driver] Workaround for Kingnet 710 AP wrong AID assignment -+ * Update workaround for Kingnet AP. -+ * -+ * 07 15 2011 terry.wu -+ * [WCXRP00000855] [MT6620 Wi-Fi] [Driver] Workaround for Kingnet 710 AP wrong AID assignment -+ * Workaround for Kingnet 710 AP wrong AID assignment. -+ * -+ * 05 02 2011 eddie.chen -+ * [WCXRP00000603] [MT6620 Wi-Fi][DRV] Fix Klocwork warning[WCXRP00000672] [MT6620 Wi-Fi][FW] -+ * Fix the PS event allocation -+ * Check STA when rx assoc. -+ * -+ * 04 18 2011 terry.wu -+ * [WCXRP00000660] [MT6620 Wi-Fi][Driver] Remove flag CFG_WIFI_DIRECT_MOVED -+ * Remove flag CFG_WIFI_DIRECT_MOVED. -+ * -+ * 03 19 2011 yuche.tsai -+ * [WCXRP00000581] [Volunteer Patch][MT6620][Driver] P2P IE in Assoc Req Issue -+ * Make assoc req to append P2P IE if wifi direct is enabled. -+ * -+ * 03 17 2011 chinglan.wang -+ * [WCXRP00000570] [MT6620 Wi-Fi][Driver] Add Wi-Fi Protected Setup v2.0 feature -+ * . -+ * -+ * 03 16 2011 wh.su -+ * [WCXRP00000530] [MT6620 Wi-Fi] [Driver] skip doing p2pRunEventAAAComplete after send assoc response Tx Done -+ * enable the protected while at P2P start GO, and skip some security check . -+ * -+ * 03 14 2011 wh.su -+ * [WCXRP00000545] [MT6620 Wi-Fi] [Driver] Fixed the p2p not enable, received a assoc rsp -+ * cause the rx assoc execute a null function -+ * Modify file for avoid assert at BOW receive a assoc response frame but no p2p function. -+ * -+ * 03 08 2011 terry.wu -+ * [WCXRP00000524] [MT6620 Wi-Fi][Driver] Fix p2p assoc request containing wrong IE format -+ * Fix p2p assoc request containing wrong IE format. -+ * -+ * 03 02 2011 wh.su -+ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code -+ * add code to let the beacon and probe response for Auto GO WSC . -+ * -+ * 02 15 2011 yuche.tsai -+ * [WCXRP00000431] [Volunteer Patch][MT6620][Driver] Add MLME support for deauthentication under AP(Hot-Spot) mode. -+ * Fix RX disassoc issue under Hot-spot mode. -+ * -+ * 02 09 2011 wh.su -+ * [WCXRP00000432] [MT6620 Wi-Fi][Driver] Add STA privacy check at hotspot mode -+ * adding the code for check STA privacy bit at AP mode, . -+ * -+ * 02 08 2011 eddie.chen -+ * [WCXRP00000426] [MT6620 Wi-Fi][FW/Driver] Add STA aging timeout and defualtHwRatein AP mode -+ * Add event STA agint timeout -+ * -+ * 01 25 2011 yuche.tsai -+ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record. -+ * Change Station Type in Station Record, Modify MACRO definition for getting station type & network type index & Role. -+ * -+ * 01 12 2011 yuche.tsai -+ * [WCXRP00000353] [Volunteer Patch][MT6620][Driver] Desired Non-HT Rate Set update -+ * when STA record is created under AP Mode. -+ * Update Phy Type Set. When legacy client is connected, it can use 11b rate, -+ * but if the P2P device is connected, 11b rate is not allowed. -+ * -+ * 01 11 2011 yuche.tsai -+ * [WCXRP00000353] [Volunteer Patch][MT6620][Driver] Desired Non-HT Rate Set update -+ * when STA record is created under AP Mode. -+ * Update Desired Non-HT Rate Set. -+ * -+ * 12 30 2010 eddie.chen -+ * [WCXRP00000322] Add WMM IE in beacon, -+ -+Add per station flow control when STA is in PS -+ -+ * Recover the code that was coverwritted.. -+ * -+ * 12 29 2010 eddie.chen -+ * [WCXRP00000322] Add WMM IE in beacon, -+Add per station flow control when STA is in PS -+ -+ * 1) PS flow control event -+ * -+ * 2) WMM IE in beacon, assoc resp, probe resp -+ * -+ * 11 04 2010 wh.su -+ * [WCXRP00000164] [MT6620 Wi-Fi][Driver] Support the p2p random SSID -+ * adding the p2p random ssid support. -+ * -+ * 10 18 2010 cp.wu -+ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning -+ * use definition macro to replace hard-coded constant -+ * -+ * 09 28 2010 wh.su -+ * NULL -+ * [WCXRP00000069][MT6620 Wi-Fi][Driver] Fix some code for phase 1 P2P Demo. -+ * -+ * 09 27 2010 chinghwa.yu -+ * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000065] Update BoW design and settings -+ * Update BCM/BoW design and settings. -+ * -+ * 09 16 2010 cm.chang -+ * NULL -+ * Change conditional compiling options for BOW -+ * -+ * 09 03 2010 kevin.huang -+ * NULL -+ * Refine #include sequence and solve recursive/nested #include issue -+ * -+ * 09 01 2010 wh.su -+ * NULL -+ * adding the wapi support for integration test. -+ * -+ * 08 30 2010 cp.wu -+ * NULL -+ * eliminate klockwork errors -+ * -+ * 08 16 2010 yuche.tsai -+ * NULL -+ * Add SSID IE in assoc req frame which is sent by P2P GC. -+ * -+ * 08 16 2010 kevin.huang -+ * NULL -+ * Refine AAA functions -+ * -+ * 08 03 2010 cp.wu -+ * NULL -+ * surpress compilation warning. -+ * -+ * 07 20 2010 wh.su -+ * -+ * adding the wapi code. -+ * -+ * 07 09 2010 yarco.yang -+ * -+ * [MT6620 and MT5931] SW Migration: Add ADDBA support -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 07 08 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * take use of RLM module for parsing/generating HT IEs for 11n capability -+ * -+ * 07 01 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * comment out RSN IE generation by CFG_RSN_MIGRATION compilation flag. -+ * -+ * 06 28 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * send MMPDU in basic rate. -+ * -+ * 06 21 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add scan_fsm into building. -+ * -+ * 06 21 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * specify correct value for management frames. -+ * -+ * 06 18 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Provide cnmMgtPktAlloc() and alloc/free function of msg/buf -+ * -+ * 06 18 2010 wh.su -+ * [WPD00003840][MT6620 5931] Security migration -+ * migration from MT6620 firmware. -+ * -+ * 06 15 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * revised. -+ * -+ * 06 14 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add management dispatching function table. -+ * -+ * 06 11 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * auth.c is migrated. -+ * -+ * 06 11 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) migrate assoc.c. -+ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness -+ * 3) add configuration options for CNM_MEM and RSN modules -+ * 4) add data path for management frames -+ * 5) eliminate rPacketInfo of MSDU_INFO_T -+ * -+ * 05 24 2010 kevin.huang -+ * [BORA00000794][WIFISYS][New Feature]Power Management Support -+ * Update assocProcessRxAssocReqFrame() to avoid redundant SSID IE {0,0} for IOT. -+ * -+ * 05 14 2010 kevin.huang -+ * [BORA00000794][WIFISYS][New Feature]Power Management Support -+ * Fix compile warning - macro > 10 line, initial value of an array -+ * -+ * 04 24 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * g_aprBssInfo[] depends on CFG_SUPPORT_P2P and CFG_SUPPORT_BOW -+ * -+ * 04 22 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * First draft code to support protection in AP mode -+ * -+ * 04 19 2010 kevin.huang -+ * [BORA00000714][WIFISYS][New Feature]Beacon Timeout Support -+ * Add Beacon Timeout Support -+ * * * * * * * * and will send Null frame to diagnose connection -+ * -+ * 04 16 2010 wh.su -+ * [BORA00000680][MT6620] Support the statistic for Micxxsoft os query -+ * adding the wpa-none for ibss beacon. -+ * -+ * 03 25 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Remove compiling warning -+ * -+ * 03 24 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Not carry HT cap when being associated with b/g only AP -+ * -+ * 02 04 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Add AAA Module Support, Revise Net Type to Net Type Index for array lookup -+ * -+ * 01 28 2010 wh.su -+ * [BORA00000476][Wi-Fi][firmware] Add the security module initialize code -+ * fixed the compiling warning.u1rwduu`wvpghlqg|rm+vp -+ * -+ * 01 27 2010 wh.su -+ * [BORA00000476][Wi-Fi][firmware] Add the security module initialize code -+ * add and fixed some security function. -+ * -+ * 01 11 2010 kevin.huang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Add Deauth and Disassoc Handler -+ * -+ * 01 07 2010 kevin.huang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Update Assoc ID for PS -+ * -+ * 01 04 2010 tehuang.liu -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * For working out the first connection Chariot-verified version -+ * -+ * 12 18 2009 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * . -+ * -+ * Dec 12 2009 mtk01104 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Use new constant definition ELEM_MAX_LEN_EXT_CAP -+ * -+ * Dec 9 2009 mtk01104 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Modify assoc req IE talbe for HT cap IE -+ * -+ * Dec 7 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * update the assocComposeReAssocReqFrameHeader() and fix the u2EstimatedFrameLen in assocSendReAssocReqFrame() -+ * -+ * Dec 7 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * remove some space line -+ * -+ * Dec 7 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * adding the sending disassoc frame function -+ * -+ * Dec 4 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * adding the txassocReq IE table, adding for WPA/RSN -+ * -+ * Dec 3 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Fix eNetType not init in send AssocReq function -+ * -+ * Dec 3 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Integrate the send Assoc with TXM -+ * -+ * Dec 1 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * adding the code to indicate the assoc request and assoc response (now disable) -+ * -+ * Nov 24 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Remove unused variables -+ * -+ * Nov 23 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "precomp.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+APPEND_VAR_IE_ENTRY_T txAssocReqIETable[] = { -+ {(ELEM_HDR_LEN + ELEM_MAX_LEN_HT_CAP), NULL, rlmReqGenerateHtCapIE} -+ , /* 45 */ -+#if CFG_SUPPORT_WPS2 -+ {(ELEM_HDR_LEN + ELEM_MAX_LEN_WSC), NULL, rsnGenerateWSCIE} -+ , /* 221 */ -+#endif -+#if CFG_RSN_MIGRATION -+ {(ELEM_HDR_LEN + ELEM_MAX_LEN_RSN), NULL, rsnGenerateRSNIE} -+ , /* 48 */ -+#endif -+#if CFG_SUPPORT_WAPI -+ {(ELEM_HDR_LEN + ELEM_MAX_LEN_WAPI), NULL, wapiGenerateWAPIIE} -+ , /* 68 */ -+#endif -+#if CFG_SUPPORT_HOTSPOT_2_0 -+ {(ELEM_HDR_LEN + ELEM_MAX_LEN_INTERWORKING), NULL, hs20GenerateInterworkingIE} -+ , /* 107 */ -+ {(ELEM_HDR_LEN + ELEM_MAX_LEN_ROAMING_CONSORTIUM), NULL, hs20GenerateRoamingConsortiumIE} -+ , /* 111 */ -+#endif -+ {(ELEM_HDR_LEN + ELEM_MAX_LEN_EXT_CAP), NULL, rlmReqGenerateExtCapIE} -+ , /* 127 */ -+#if CFG_SUPPORT_HOTSPOT_2_0 -+ {(ELEM_HDR_LEN + ELEM_MAX_LEN_HS20_INDICATION), NULL, hs20GenerateHS20IE} -+ , /* 221 */ -+#endif -+ {(ELEM_HDR_LEN + ELEM_MAX_LEN_WMM_INFO), NULL, mqmGenerateWmmInfoIE} -+ , /* 221 */ -+#if CFG_RSN_MIGRATION -+ {(ELEM_HDR_LEN + ELEM_MAX_LEN_WPA), NULL, rsnGenerateWPAIE} -+ , /* 221 */ -+#endif -+}; -+ -+#if CFG_SUPPORT_AAA -+VERIFY_IE_ENTRY_T rxAssocReqIETable[] = { -+ {ELEM_ID_RESERVED, NULL} /* 255 */ -+}; -+ -+APPEND_VAR_IE_ENTRY_T txAssocRespIETable[] = { -+ {(ELEM_HDR_LEN + ELEM_MAX_LEN_ERP), NULL, rlmRspGenerateErpIE} -+ , /* 42 */ -+ {(ELEM_HDR_LEN + ELEM_MAX_LEN_HT_CAP), NULL, rlmRspGenerateHtCapIE} -+ , /* 45 */ -+ {(ELEM_HDR_LEN + ELEM_MAX_LEN_HT_OP), NULL, rlmRspGenerateHtOpIE} -+ , /* 61 */ -+#if CFG_ENABLE_WIFI_DIRECT -+ {(ELEM_HDR_LEN + ELEM_MAX_LEN_OBSS_SCAN), NULL, rlmRspGenerateObssScanIE} -+ , /* 74 */ -+ {(0), p2pFuncCalculateP2p_IELenForAssocRsp, p2pFuncGenerateP2p_IEForAssocRsp} -+ , /* 221 */ -+#if CFG_SUPPORT_WFD -+ {(0), wfdFuncCalculateWfdIELenForAssocRsp, wfdFuncGenerateWfdIEForAssocRsp} -+ , /* 221 */ -+#endif -+#endif -+ {(ELEM_HDR_LEN + ELEM_MAX_LEN_EXT_CAP), NULL, rlmRspGenerateExtCapIE} -+ , /* 127 */ -+ {(ELEM_HDR_LEN + ELEM_MAX_LEN_WMM_PARAM), NULL, mqmGenerateWmmParamIE} -+ , /* 221 */ -+ -+ {(0), p2pFuncCalculateWSC_IELenForAssocRsp, p2pFuncGenerateWSC_IEForAssocRsp} /* 221 */ -+ -+}; -+#endif -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is used to compose the Capability Info Field. -+* -+* @param[in] prStaRec Pointer to the STA_RECORD_T -+* -+* @retval Capability Info Field -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT_16 -+assocBuildCapabilityInfo(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec) -+{ -+ UINT_32 u4NonHTPhyType; -+ UINT_16 u2CapInfo; -+ -+ /* Set up our requested capabilities. */ -+ u2CapInfo = CAP_INFO_ESS; -+ u2CapInfo |= CAP_CF_STA_NOT_POLLABLE; -+ -+ if (prStaRec == NULL) -+ u2CapInfo |= CAP_INFO_PRIVACY; -+ else { -+ if (prStaRec->u2CapInfo & CAP_INFO_PRIVACY) -+ u2CapInfo |= CAP_INFO_PRIVACY; -+ } -+ -+ /* 7.3.1.4 */ -+ if (prStaRec == NULL) { -+ if ((prAdapter->rWifiVar.ePreambleType == PREAMBLE_TYPE_SHORT) ||/* ShortPreambleOptionEnable is TRUE */ -+ (prAdapter->rWifiVar.ePreambleType == PREAMBLE_TYPE_AUTO)) -+ u2CapInfo |= CAP_INFO_SHORT_PREAMBLE; -+ if (prAdapter->rWifiVar.fgIsShortSlotTimeOptionEnable) -+ u2CapInfo |= CAP_INFO_SHORT_SLOT_TIME; -+ } else if (prStaRec->fgHasBasicPhyType) { -+ u4NonHTPhyType = prStaRec->ucNonHTBasicPhyType; -+ -+ if ((rNonHTPhyAttributes[u4NonHTPhyType].fgIsShortPreambleOptionImplemented) && -+ /* Short Preamble Option Enable is TRUE */ -+ ((prAdapter->rWifiVar.ePreambleType == PREAMBLE_TYPE_SHORT) || -+ ((prAdapter->rWifiVar.ePreambleType == PREAMBLE_TYPE_AUTO) && -+ (prStaRec->u2CapInfo & CAP_INFO_SHORT_PREAMBLE)))) { -+ -+ /* Case I: Implemented == TRUE and Short Preamble Option Enable == TRUE. -+ * Case II: Implemented == TRUE and Short Preamble == AUTO (depends on -+ * BSS_DESC_T's capability) -+ */ -+ u2CapInfo |= CAP_INFO_SHORT_PREAMBLE; -+ } -+#if CFG_SUPPORT_SPEC_MGMT /*Add by Enlai */ -+ /* Support 802.11h */ -+ if (prStaRec->u2CapInfo & CAP_INFO_SPEC_MGT) { -+ /* -+ 1. The Power Capability element shall be present if -+ dot11SpectrumManagementRequired is true. -+ -+ 2. A STA shall set dot11SpectrumManagementRequired to TRUE before -+ associating with a BSS or IBSS in which the Spectrum Management -+ bit is set to 1 in the Capability Information field in Beacon frames -+ and Probe Response frames received from the BSS or IBSS. -+ */ -+ if (prAdapter->fgEnable5GBand == TRUE) -+ u2CapInfo |= CAP_INFO_SPEC_MGT; -+ } -+#endif -+ -+ if (rNonHTPhyAttributes[u4NonHTPhyType].fgIsShortSlotTimeOptionImplemented && -+ prAdapter->rWifiVar.fgIsShortSlotTimeOptionEnable) { -+ u2CapInfo |= CAP_INFO_SHORT_SLOT_TIME; -+ } -+ } -+ -+ if (prStaRec) { -+ DBGLOG(SAA, LOUD, "ASSOC REQ: Compose Capability = 0x%04x for Target BSS [%pM].\n", -+ u2CapInfo, prStaRec->aucMacAddr); -+ } -+ -+ return u2CapInfo; -+ -+} /* end of assocBuildCapabilityInfo() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is used to compose Common Information Elements for Association -+* Request Frame. -+* -+* @param[in] prMsduInfo Pointer to the composed MSDU_INFO_T. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+static inline VOID assocBuildReAssocReqFrameCommonIEs(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo) -+{ -+ P_CONNECTION_SETTINGS_T prConnSettings; -+ P_STA_RECORD_T prStaRec; -+ PUINT_8 pucBuffer; -+ UINT_16 u2SupportedRateSet; -+ UINT_8 aucAllSupportedRates[RATE_NUM] = { 0 }; -+ UINT_8 ucAllSupportedRatesLen; -+ UINT_8 ucSupRatesLen; -+ UINT_8 ucExtSupRatesLen; -+ -+ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); -+ ASSERT(prMsduInfo); -+ ASSERT(prMsduInfo->eSrc == TX_PACKET_MGMT); -+ -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); -+ ASSERT(prStaRec); -+ -+ if (!prStaRec) -+ return; -+ -+ pucBuffer = (PUINT_8) ((ULONG) prMsduInfo->prPacket + (ULONG) prMsduInfo->u2FrameLength); -+ ASSERT(pucBuffer); -+ -+ if (IS_STA_IN_AIS(prStaRec)) { -+ -+ /* Fill the SSID element. */ -+ SSID_IE(pucBuffer)->ucId = ELEM_ID_SSID; -+ -+ /* NOTE(Kevin): We copy the SSID from CONNECTION_SETTINGS for the case of -+ * Passive Scan and the target BSS didn't broadcast SSID on its Beacon Frame. -+ */ -+ -+ COPY_SSID(SSID_IE(pucBuffer)->aucSSID, -+ SSID_IE(pucBuffer)->ucLength, prConnSettings->aucSSID, prConnSettings->ucSSIDLen); -+ -+ prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer); -+ pucBuffer += IE_SIZE(pucBuffer); -+ -+ } -+#if CFG_ENABLE_WIFI_DIRECT -+ else if ((prAdapter->fgIsP2PRegistered) && (IS_STA_IN_P2P(prStaRec))) -+ pucBuffer = p2pBuildReAssocReqFrameCommonIEs(prAdapter, prMsduInfo, pucBuffer); -+#endif -+#if CFG_ENABLE_BT_OVER_WIFI -+ else if (IS_STA_IN_BOW(prStaRec)) { -+ -+ SSID_IE(pucBuffer)->ucId = ELEM_ID_SSID; -+ -+ /* NOTE(Kevin): We copy the SSID from CONNECTION_SETTINGS for the case of -+ * Passive Scan and the target BSS didn't broadcast SSID on its Beacon Frame. -+ */ -+ -+ COPY_SSID(SSID_IE(pucBuffer)->aucSSID, -+ SSID_IE(pucBuffer)->ucLength, prConnSettings->aucSSID, prConnSettings->ucSSIDLen); -+ -+ prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer); -+ pucBuffer += IE_SIZE(pucBuffer); -+ } -+#endif -+ else { -+ /* Do nothing */ -+ /* TODO(Kevin): For other network */ -+ } -+ -+ /* NOTE(Kevin 2008/12/19): 16.3.6.3 MLME-ASSOCIATE.indication - -+ * SupportedRates - The set of data rates that are supported by the STA -+ * that is requesting association. -+ * Original(Portable Driver): Only send the Rates that we'll support. -+ * New: Send the Phy Rates if the result of following & operation == NULL. -+ */ -+ /* rateGetDataRatesFromRateSet((prBssDesc->u2OperationalRateSet & */ -+ /* rPhyAttributes[prBssDesc->ePhyType].u2SupportedRateSet), */ -+ -+ if (prStaRec->fgHasBasicPhyType) { -+ UINT_32 u4NonHTPhyType; -+ -+ u4NonHTPhyType = prStaRec->ucNonHTBasicPhyType; -+ -+ u2SupportedRateSet = (prStaRec->u2OperationalRateSet & -+ rNonHTPhyAttributes[u4NonHTPhyType].u2SupportedRateSet); -+ -+ ASSERT(u2SupportedRateSet); -+ -+ if (!u2SupportedRateSet) -+ u2SupportedRateSet = rNonHTPhyAttributes[u4NonHTPhyType].u2SupportedRateSet; -+ -+ /* TODO(Kevin): For P2P, we shouldn't send support rate set which contains 11b rate */ -+ -+ rateGetDataRatesFromRateSet(u2SupportedRateSet, 0, aucAllSupportedRates, &ucAllSupportedRatesLen); -+ -+ ucSupRatesLen = ((ucAllSupportedRatesLen > ELEM_MAX_LEN_SUP_RATES) ? -+ ELEM_MAX_LEN_SUP_RATES : ucAllSupportedRatesLen); -+ -+ ucExtSupRatesLen = ucAllSupportedRatesLen - ucSupRatesLen; -+ -+ /* Fill the Supported Rates element. */ -+ if (ucSupRatesLen) { -+ SUP_RATES_IE(pucBuffer)->ucId = ELEM_ID_SUP_RATES; -+ SUP_RATES_IE(pucBuffer)->ucLength = ucSupRatesLen; -+ kalMemCopy(SUP_RATES_IE(pucBuffer)->aucSupportedRates, aucAllSupportedRates, ucSupRatesLen); -+ -+ prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer); -+ pucBuffer += IE_SIZE(pucBuffer); -+ } -+ -+ /* Fill the Extended Supported Rates element. */ -+ if (ucExtSupRatesLen) { -+ -+ EXT_SUP_RATES_IE(pucBuffer)->ucId = ELEM_ID_EXTENDED_SUP_RATES; -+ EXT_SUP_RATES_IE(pucBuffer)->ucLength = ucExtSupRatesLen; -+ -+ kalMemCopy(EXT_SUP_RATES_IE(pucBuffer)->aucExtSupportedRates, -+ &aucAllSupportedRates[ucSupRatesLen], ucExtSupRatesLen); -+ -+ prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer); -+ pucBuffer += IE_SIZE(pucBuffer); -+ } -+ -+ /* 7.3.2.19 Supported Channels element */ -+#if CFG_SUPPORT_DFS /* Add by Enlai */ -+ if (prAdapter->fgEnable5GBand == TRUE) { -+ SUPPORTED_CHANNELS_IE(pucBuffer)->ucId = ELEM_ID_SUP_CHS; -+ SUPPORTED_CHANNELS_IE(pucBuffer)->ucLength = 8; -+ -+ SUPPORTED_CHANNELS_IE(pucBuffer)->ucChannelNum[0] = 36; -+ SUPPORTED_CHANNELS_IE(pucBuffer)->ucChannelNum[1] = 4; -+ SUPPORTED_CHANNELS_IE(pucBuffer)->ucChannelNum[2] = 52; -+ SUPPORTED_CHANNELS_IE(pucBuffer)->ucChannelNum[3] = 4; -+/* Not China --- Start */ -+ /* SUPPORTED_CHANNELS_IE(pucBuffer)->ucChannelNum[4] = 100; */ -+ /* SUPPORTED_CHANNELS_IE(pucBuffer)->ucChannelNum[5] = 11; */ -+/* Not China --- End */ -+ SUPPORTED_CHANNELS_IE(pucBuffer)->ucChannelNum[4] = 149; -+ SUPPORTED_CHANNELS_IE(pucBuffer)->ucChannelNum[5] = 4; -+ SUPPORTED_CHANNELS_IE(pucBuffer)->ucChannelNum[6] = 165; -+ SUPPORTED_CHANNELS_IE(pucBuffer)->ucChannelNum[7] = 1; -+ -+ prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer); -+ pucBuffer += IE_SIZE(pucBuffer); -+ } -+#endif -+ } -+ -+} /* end of assocBuildReAssocReqFrameCommonIEs() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will compose the (Re)Association Request frame header and -+* its fixed fields -+* -+* @param[in] prStaRec Pointer to the STA_RECORD_T -+* @param[in] pucBuffer Pointer to the frame buffer. -+* @param[in] aucMACAddress Given Our MAC Address. -+* @param[in out] pu2PayloadLen Return the length of the composed fixed fields -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+static inline VOID -+assocComposeReAssocReqFrameHeaderAndFF(IN P_ADAPTER_T prAdapter, -+ IN P_STA_RECORD_T prStaRec, -+ IN PUINT_8 pucBuffer, IN UINT_8 aucMACAddress[], IN OUT PUINT_16 pu2PayloadLen) -+{ -+ P_WLAN_ASSOC_REQ_FRAME_T prAssocFrame; -+ BOOLEAN fgIsReAssoc; -+ -+ UINT_16 u2FrameCtrl; -+ UINT_16 u2CapInfo; -+ UINT_16 u2ListenInterval; -+ -+ ASSERT(prStaRec); -+ ASSERT(pucBuffer); -+ ASSERT(aucMACAddress); -+ ASSERT(pu2PayloadLen); -+ -+ prAssocFrame = (P_WLAN_ASSOC_REQ_FRAME_T) pucBuffer; -+ fgIsReAssoc = prStaRec->fgIsReAssoc; -+ -+ /* 4 <1> Compose the frame header of the (Re)Association Request frame. */ -+ /* Fill the Frame Control field. */ -+ if (fgIsReAssoc) -+ u2FrameCtrl = MAC_FRAME_REASSOC_REQ; -+ else -+ u2FrameCtrl = MAC_FRAME_ASSOC_REQ; -+ WLAN_SET_FIELD_16(&prAssocFrame->u2FrameCtrl, u2FrameCtrl); -+ -+ /* Fill the DA field with Target BSSID. */ -+ COPY_MAC_ADDR(prAssocFrame->aucDestAddr, prStaRec->aucMacAddr); -+ -+ /* Fill the SA field with our MAC Address. */ -+ COPY_MAC_ADDR(prAssocFrame->aucSrcAddr, aucMACAddress); -+ -+ /* Fill the BSSID field with Target BSSID. */ -+ COPY_MAC_ADDR(prAssocFrame->aucBSSID, prStaRec->aucMacAddr); -+ -+ /* Clear the SEQ/FRAG_NO field(HW won't overide the FRAG_NO, so we need to clear it). */ -+ prAssocFrame->u2SeqCtrl = 0; -+ -+ /* 4 <2> Compose the frame body's common fixed field part of the (Re)Association Request frame. */ -+ u2CapInfo = assocBuildCapabilityInfo(prAdapter, prStaRec); -+ -+ /* Fill the Capability Information field. */ -+ WLAN_SET_FIELD_16(&prAssocFrame->u2CapInfo, u2CapInfo); -+ -+ /* Calculate the listen interval for the maximum power mode. Currently, we -+ set it to the value 2 times DTIM period. */ -+ if (prStaRec->ucDTIMPeriod) { -+ u2ListenInterval = prStaRec->ucDTIMPeriod * DEFAULT_LISTEN_INTERVAL_BY_DTIM_PERIOD; -+ } else { -+ DBGLOG(SAA, TRACE, "Use default listen interval\n"); -+ u2ListenInterval = DEFAULT_LISTEN_INTERVAL; -+ } -+ prStaRec->u2ListenInterval = u2ListenInterval; -+ -+ /* Fill the Listen Interval field. */ -+ WLAN_SET_FIELD_16(&prAssocFrame->u2ListenInterval, u2ListenInterval); -+ -+ /* 4 <3> Compose the Current AP Address field for ReAssociation Request frame. */ -+ /* Fill the Current AP Address field. */ -+ if (prStaRec->fgIsReAssoc) { -+ if (IS_STA_IN_AIS(prStaRec)) { -+ -+ P_AIS_BSS_INFO_T prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ P_WLAN_REASSOC_REQ_FRAME_T prReAssocFrame = (P_WLAN_REASSOC_REQ_FRAME_T) prAssocFrame; -+ -+ COPY_MAC_ADDR(prReAssocFrame->aucCurrentAPAddr, prAisBssInfo->aucBSSID); -+ } else { -+ ASSERT(0); /* We don't support ReAssociation for other network */ -+ } -+ -+ *pu2PayloadLen = (CAP_INFO_FIELD_LEN + LISTEN_INTERVAL_FIELD_LEN + CURR_AP_ADDR_FIELD_LEN); -+ } else { -+ *pu2PayloadLen = (CAP_INFO_FIELD_LEN + LISTEN_INTERVAL_FIELD_LEN); -+ } -+ -+} /* end of assocComposeReAssocReqFrame() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will send the (Re)Association Request frame -+* -+* @param[in] prStaRec Pointer to the STA_RECORD_T -+* -+* @retval WLAN_STATUS_RESOURCES No available resource for frame composing. -+* @retval WLAN_STATUS_SUCCESS Successfully send frame to TX Module -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS assocSendReAssocReqFrame(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec) -+{ -+ P_MSDU_INFO_T prMsduInfo; -+ P_BSS_INFO_T prBssInfo; -+ -+ UINT_16 u2PayloadLen; -+ UINT_16 u2EstimatedFrameLen; -+ UINT_16 u2EstimatedExtraIELen; -+ BOOLEAN fgIsReAssoc; -+ UINT_32 i; -+ -+ ASSERT(prStaRec); -+ -+ /* 4 <1> Allocate a PKT_INFO_T for Authentication Frame */ -+ fgIsReAssoc = prStaRec->fgIsReAssoc; -+ -+ /* Init with MGMT Header Length + Length of Fixed Fields + Common IE Length */ -+ if (fgIsReAssoc) { -+ u2EstimatedFrameLen = MAC_TX_RESERVED_FIELD + -+ WLAN_MAC_MGMT_HEADER_LEN + -+ CAP_INFO_FIELD_LEN + -+ LISTEN_INTERVAL_FIELD_LEN + -+ CURR_AP_ADDR_FIELD_LEN + -+ (ELEM_HDR_LEN + ELEM_MAX_LEN_SSID) + -+ (ELEM_HDR_LEN + ELEM_MAX_LEN_SUP_RATES) + (ELEM_HDR_LEN + (RATE_NUM - ELEM_MAX_LEN_SUP_RATES)); -+ } else { -+ u2EstimatedFrameLen = MAC_TX_RESERVED_FIELD + -+ WLAN_MAC_MGMT_HEADER_LEN + -+ CAP_INFO_FIELD_LEN + -+ LISTEN_INTERVAL_FIELD_LEN + -+ (ELEM_HDR_LEN + ELEM_MAX_LEN_SSID) + -+ (ELEM_HDR_LEN + ELEM_MAX_LEN_SUP_RATES) + (ELEM_HDR_LEN + (RATE_NUM - ELEM_MAX_LEN_SUP_RATES)); -+ } -+ -+ /* + Extra IE Length */ -+ u2EstimatedExtraIELen = 0; -+ -+#if CFG_ENABLE_WIFI_DIRECT_CFG_80211 && CFG_ENABLE_WIFI_DIRECT -+ if (prStaRec->ucNetTypeIndex == NETWORK_TYPE_P2P_INDEX) { -+ if ((prAdapter->fgIsP2PRegistered)) { -+ u2EstimatedExtraIELen = p2pCalculate_IEForAssocReq(prAdapter, -+ prStaRec->ucNetTypeIndex, prStaRec); -+ } else { -+ DBGLOG(P2P, TRACE, "Function Linker Lost.\n"); -+ ASSERT(FALSE); -+ } -+ } else { -+ for (i = 0; i < sizeof(txAssocReqIETable) / sizeof(APPEND_VAR_IE_ENTRY_T); i++) { -+ if (txAssocReqIETable[i].u2EstimatedFixedIELen != 0) { -+ u2EstimatedExtraIELen += txAssocReqIETable[i].u2EstimatedFixedIELen; -+ } else { -+ u2EstimatedExtraIELen += -+ (UINT_16) txAssocReqIETable[i].pfnCalculateVariableIELen(prAdapter, -+ prStaRec->ucNetTypeIndex, -+ prStaRec); -+ } -+ } -+ } -+#else -+ for (i = 0; i < sizeof(txAssocReqIETable) / sizeof(APPEND_VAR_IE_ENTRY_T); i++) { -+ if (txAssocReqIETable[i].u2EstimatedFixedIELen != 0) { -+ u2EstimatedExtraIELen += txAssocReqIETable[i].u2EstimatedFixedIELen; -+ } else { -+ u2EstimatedExtraIELen += (UINT_16) txAssocReqIETable[i].pfnCalculateVariableIELen(prAdapter, -+ prStaRec->ucNetTypeIndex, -+ prStaRec); -+ } -+ } -+#endif -+ -+ u2EstimatedFrameLen += u2EstimatedExtraIELen; -+ -+ /* Allocate a MSDU_INFO_T */ -+ prMsduInfo = cnmMgtPktAlloc(prAdapter, u2EstimatedFrameLen); -+ if (prMsduInfo == NULL) { -+ DBGLOG(SAA, WARN, "No PKT_INFO_T for sending (Re)Assoc Request.\n"); -+ return WLAN_STATUS_RESOURCES; -+ } -+ /* 4 <2> Compose (Re)Association Request frame header and fixed fields in MSDU_INfO_T. */ -+ ASSERT(prStaRec->ucNetTypeIndex < NETWORK_TYPE_INDEX_NUM); -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]); -+ -+ /* Compose Header and Fixed Field */ -+ assocComposeReAssocReqFrameHeaderAndFF(prAdapter, -+ prStaRec, -+ (PUINT_8) ((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD), -+ prBssInfo->aucOwnMacAddr, &u2PayloadLen); -+ -+ /* 4 <3> Update information of MSDU_INFO_T */ -+ prMsduInfo->eSrc = TX_PACKET_MGMT; -+ prMsduInfo->ucPacketType = HIF_TX_PACKET_TYPE_MGMT; -+ prMsduInfo->ucStaRecIndex = prStaRec->ucIndex; -+ prMsduInfo->ucNetworkType = prStaRec->ucNetTypeIndex; -+ prMsduInfo->ucMacHeaderLength = WLAN_MAC_MGMT_HEADER_LEN; -+ prMsduInfo->fgIs802_1x = FALSE; -+ prMsduInfo->fgIs802_11 = TRUE; -+ prMsduInfo->u2FrameLength = WLAN_MAC_MGMT_HEADER_LEN + u2PayloadLen; -+ prMsduInfo->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter); -+ prMsduInfo->pfTxDoneHandler = saaFsmRunEventTxDone; -+ prMsduInfo->fgIsBasicRate = TRUE; -+ -+ /* 4 <4> Compose the frame body's IEs of the (Re)Association Request frame. */ -+ assocBuildReAssocReqFrameCommonIEs(prAdapter, prMsduInfo); -+ -+ /* 4 <5> Compose IEs in MSDU_INFO_T */ -+#if CFG_ENABLE_WIFI_DIRECT_CFG_80211 && CFG_ENABLE_WIFI_DIRECT -+ if (prStaRec->ucNetTypeIndex == NETWORK_TYPE_P2P_INDEX) { -+ if ((prAdapter->fgIsP2PRegistered)) { -+ p2pGenerate_IEForAssocReq(prAdapter, prMsduInfo); -+ } else { -+ DBGLOG(P2P, TRACE, "Function Linker Lost.\n"); -+ ASSERT(FALSE); -+ } -+ } else { -+ /* Append IE */ -+ for (i = 0; i < sizeof(txAssocReqIETable) / sizeof(APPEND_VAR_IE_ENTRY_T); i++) { -+ if (txAssocReqIETable[i].pfnAppendIE) -+ txAssocReqIETable[i].pfnAppendIE(prAdapter, prMsduInfo); -+ } -+ } -+#else -+ /* Append IE */ -+ for (i = 0; i < sizeof(txAssocReqIETable) / sizeof(APPEND_VAR_IE_ENTRY_T); i++) { -+ if (txAssocReqIETable[i].pfnAppendIE) -+ txAssocReqIETable[i].pfnAppendIE(prAdapter, prMsduInfo); -+ } -+#endif -+ -+ /* 4 <6> Update the (Re)association request information */ -+ if (IS_STA_IN_AIS(prStaRec)) { -+ P_WLAN_ASSOC_REQ_FRAME_T prAssocFrame; -+ -+ prAssocFrame = (P_WLAN_ASSOC_REQ_FRAME_T) ((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD); -+ -+#if CFG_RSN_MIGRATION -+ kalUpdateReAssocReqInfo(prAdapter->prGlueInfo, -+ (PUINT_8) &prAssocFrame->u2CapInfo, -+ prMsduInfo->u2FrameLength - offsetof(WLAN_ASSOC_REQ_FRAME_T, u2CapInfo), -+ fgIsReAssoc); -+#endif -+ } -+#if CFG_ENABLE_WIFI_DIRECT -+ if ((prAdapter->fgIsP2PRegistered) && (IS_STA_IN_P2P(prStaRec))) { -+ P_WLAN_ASSOC_REQ_FRAME_T prAssocFrame; -+ -+ prAssocFrame = (P_WLAN_ASSOC_REQ_FRAME_T) ((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD); -+ -+ kalP2PUpdateAssocInfo(prAdapter->prGlueInfo, -+ (PUINT_8) &prAssocFrame->u2CapInfo, -+ prMsduInfo->u2FrameLength - offsetof(WLAN_ASSOC_REQ_FRAME_T, u2CapInfo), -+ fgIsReAssoc); -+ } -+#endif -+ -+ /* TODO(Kevin): Also release the unused tail room of the composed MMPDU */ -+ -+ /* 4 <6> Enqueue the frame to send this (Re)Association request frame. */ -+ DBGLOG(SAA, INFO, "Sending (Re)Assoc Request, network: %d seqNo: %d\n", -+ prMsduInfo->ucNetworkType, prMsduInfo->ucTxSeqNum); -+ nicTxEnqueueMsdu(prAdapter, prMsduInfo); -+ -+ return WLAN_STATUS_SUCCESS; -+} /* end of assocSendReAssocReqFrame() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will strictly check the TX (Re)Association Request frame for -+* SAA event handling. -+* -+* @param[in] prMsduInfo Pointer of MSDU_INFO_T -+* -+* @retval WLAN_STATUS_FAILURE This is not the frame we should handle at current state. -+* @retval WLAN_STATUS_SUCCESS This is the frame we should handle. -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS assocCheckTxReAssocReqFrame(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo) -+{ -+ P_WLAN_ASSOC_REQ_FRAME_T prAssocReqFrame; -+ P_STA_RECORD_T prStaRec; -+ UINT_16 u2TxFrameCtrl; -+ -+ ASSERT(prMsduInfo); -+ ASSERT(prMsduInfo->eSrc == TX_PACKET_MGMT); -+ -+ prAssocReqFrame = (P_WLAN_ASSOC_REQ_FRAME_T) (prMsduInfo->prPacket); -+ ASSERT(prAssocReqFrame); -+ -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); -+ ASSERT(prStaRec); -+ -+ if (!prStaRec) -+ return WLAN_STATUS_INVALID_PACKET; -+ /* WLAN_GET_FIELD_16(&prAssocReqFrame->u2FrameCtrl, &u2TxFrameCtrl) */ -+ u2TxFrameCtrl = prAssocReqFrame->u2FrameCtrl; /* NOTE(Kevin): Optimized for ARM */ -+ u2TxFrameCtrl &= MASK_FRAME_TYPE; -+ if (prStaRec->fgIsReAssoc) { -+ if (u2TxFrameCtrl != MAC_FRAME_REASSOC_REQ) -+ return WLAN_STATUS_FAILURE; -+ } else { -+ if (u2TxFrameCtrl != MAC_FRAME_ASSOC_REQ) -+ return WLAN_STATUS_FAILURE; -+ } -+ -+ return WLAN_STATUS_SUCCESS; -+ -+} /* end of assocCheckTxReAssocReqFrame() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will strictly check the TX (Re)Association Response frame for -+* AAA event handling. -+* -+* @param[in] prMsduInfo Pointer of MSDU_INFO_T -+* -+* @retval WLAN_STATUS_FAILURE This is not the frame we should handle at current state. -+* @retval WLAN_STATUS_SUCCESS This is the frame we should handle. -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS assocCheckTxReAssocRespFrame(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo) -+{ -+ P_WLAN_ASSOC_RSP_FRAME_T prAssocRspFrame; -+ P_STA_RECORD_T prStaRec; -+ UINT_16 u2TxFrameCtrl; -+ -+ ASSERT(prMsduInfo); -+ ASSERT(prMsduInfo->eSrc == TX_PACKET_MGMT); -+ -+ prAssocRspFrame = (P_WLAN_ASSOC_RSP_FRAME_T) (prMsduInfo->prPacket); -+ ASSERT(prAssocRspFrame); -+ -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); -+ ASSERT(prStaRec); -+ -+ if (!prStaRec) -+ return WLAN_STATUS_INVALID_PACKET; -+ /* WLAN_GET_FIELD_16(&prAssocFrame->u2FrameCtrl, &u2TxFrameCtrl) */ -+ u2TxFrameCtrl = prAssocRspFrame->u2FrameCtrl; /* NOTE(Kevin): Optimized for ARM */ -+ u2TxFrameCtrl &= MASK_FRAME_TYPE; -+ if (prStaRec->fgIsReAssoc) { -+ if (u2TxFrameCtrl != MAC_FRAME_REASSOC_RSP) -+ return WLAN_STATUS_FAILURE; -+ } else { -+ if (u2TxFrameCtrl != MAC_FRAME_ASSOC_RSP) -+ return WLAN_STATUS_FAILURE; -+ } -+ -+ return WLAN_STATUS_SUCCESS; -+ -+} /* end of assocCheckTxReAssocRespFrame() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will validate the incoming (Re)Association Frame and take out -+* the status code. -+* -+* @param[in] prSwRfb Pointer to SW RFB data structure. -+* @param[out] pu2StatusCode Pointer to store the Status Code from Authentication. -+* -+* @retval WLAN_STATUS_FAILURE This is not the frame we should handle at current state. -+* @retval WLAN_STATUS_SUCCESS This is the frame we should handle. -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+assocCheckRxReAssocRspFrameStatus(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, OUT PUINT_16 pu2StatusCode) -+{ -+ P_STA_RECORD_T prStaRec; -+ P_WLAN_ASSOC_RSP_FRAME_T prAssocRspFrame; -+ UINT_16 u2RxFrameCtrl; -+ UINT_16 u2RxCapInfo; -+ UINT_16 u2RxStatusCode; -+ UINT_16 u2RxAssocId; -+ -+ ASSERT(prSwRfb); -+ ASSERT(pu2StatusCode); -+ -+ if ((prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen) < (CAP_INFO_FIELD_LEN + -+ STATUS_CODE_FIELD_LEN + AID_FIELD_LEN)) { -+ ASSERT(0); -+ return WLAN_STATUS_FAILURE; -+ } -+ -+ DBGLOG(SAA, LOUD, "prSwRfb->u2PayloadLength = %d\n", prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen); -+ -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); -+ ASSERT(prStaRec); -+ -+ if (!prStaRec) -+ return WLAN_STATUS_INVALID_PACKET; -+ /* 4 <1> locate the (Re)Association Resp Frame. */ -+ prAssocRspFrame = (P_WLAN_ASSOC_RSP_FRAME_T) prSwRfb->pvHeader; -+ -+ /* 4 <2> Parse the Header of (Re)Association Resp Frame. */ -+ /* WLAN_GET_FIELD_16(&prAssocRspFrame->u2FrameCtrl, &u2RxFrameCtrl); */ -+ u2RxFrameCtrl = prAssocRspFrame->u2FrameCtrl; /* NOTE(Kevin): Optimized for ARM */ -+ u2RxFrameCtrl &= MASK_FRAME_TYPE; -+ if (prStaRec->fgIsReAssoc) { -+ if (u2RxFrameCtrl != MAC_FRAME_REASSOC_RSP) -+ return WLAN_STATUS_FAILURE; -+ } else { -+ if (u2RxFrameCtrl != MAC_FRAME_ASSOC_RSP) -+ return WLAN_STATUS_FAILURE; -+ } -+ -+ /* 4 <3> Parse the Fixed Fields of (Re)Association Resp Frame Body. */ -+ /* WLAN_GET_FIELD_16(&prAssocRspFrame->u2CapInfo, &u2RxCapInfo); */ -+ u2RxCapInfo = prAssocRspFrame->u2CapInfo; /* NOTE(Kevin): Optimized for ARM */ -+ -+ /* WLAN_GET_FIELD_16(&prAssocRspFrame->u2StatusCode, &u2RxStatusCode); */ -+ u2RxStatusCode = prAssocRspFrame->u2StatusCode; /* NOTE(Kevin): Optimized for ARM */ -+ -+ /* 4 <4> Check CAP_INFO */ -+ /* NOTE(Kevin): CM suggest to add MGMT workaround for those APs didn't check -+ * the CAP Privacy Bit to overcome a corner case that the Privacy Bit -+ * of our SCAN result didn't consist with AP's Association Resp. -+ */ -+ if (u2RxStatusCode == STATUS_CODE_SUCCESSFUL) { -+#if CFG_SUPPORT_WAPI -+ if (prAdapter->rWifiVar.rConnSettings.fgWapiMode) { -+ /* WAPI AP allow the customer use WZC to join mode, the privacy bit is 0 */ -+ /* even at WAI & WAPI_PSK mode, but the assoc respose set the privacy bit set 1 */ -+ DBGLOG(SEC, TRACE, "Workaround the WAPI AP allow the customer to use WZC to join\n"); -+ } else -+#endif -+#if CFG_ENABLE_WIFI_DIRECT -+ if (prAdapter->fgIsP2PRegistered && 1) { -+ /* Todo:: Fixed this */ -+ } else -+#endif -+ { -+ } -+ -+#if CFG_STRICT_CHECK_CAPINFO_PRIVACY -+ if ((prStaRec->u2CapInfo & CAP_INFO_PRIVACY) ^ (u2RxCapInfo & CAP_INFO_PRIVACY)) -+ u2RxStatusCode = STATUS_CODE_CAP_NOT_SUPPORTED; -+#endif -+ } -+ -+ if (u2RxStatusCode == STATUS_CODE_SUCCESSFUL) { -+#if CFG_RSN_MIGRATION -+ /* Update the information in the structure used to query and set -+ OID_802_11_ASSOCIATION_INFORMATION. */ -+ kalUpdateReAssocRspInfo(prAdapter->prGlueInfo, -+ (PUINT_8) &prAssocRspFrame->u2CapInfo, (UINT_32) (prSwRfb->u2PacketLen)); -+#endif -+ } -+ /* 4 <5> Update CAP_INFO and ASSOC_ID */ -+ if (u2RxStatusCode == STATUS_CODE_SUCCESSFUL) { -+ prStaRec->u2CapInfo = u2RxCapInfo; -+ -+ /* WLAN_GET_FIELD_16(&prAssocRspFrame->u2AssocId, &u2RxAssocId); */ -+ u2RxAssocId = prAssocRspFrame->u2AssocId; /* NOTE(Kevin): Optimized for ARM */ -+ -+ /* 20110715 Workaround for Kingnet 710 AP (Realtek 8186) -+ * This AP raises the bit 6&7 not bit 14&15 in AID field. -+ * It cause wrong AID assignment. -+ * For AID = 2 -+ * Normal case: 0xC002(1100 0000 0000 0010) => 2 -+ * Kingnet 710: 0x00C2(0000 0000 1100 0010) => 194 -+ * workaround: mask bit 6&7 for this AP -+ */ -+ if ((u2RxAssocId & BIT(6)) && (u2RxAssocId & BIT(7)) && !(u2RxAssocId & BITS(8, 15))) { -+ prStaRec->u2AssocId = u2RxAssocId & ~BITS(6, 7); -+ } else { -+ prStaRec->u2AssocId = u2RxAssocId & ~AID_MSB; -+#if CFG_SUPPORT_802_11W -+ if (prStaRec->ucNetTypeIndex == NETWORK_TYPE_AIS_INDEX) { -+ P_AIS_SPECIFIC_BSS_INFO_T prBssSpecInfo; -+ -+ prBssSpecInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo; -+ ASSERT(prBssSpecInfo); -+ -+ prBssSpecInfo->ucSaQueryTimedOut = 0; -+ } -+#endif -+ } -+ } -+#if CFG_SUPPORT_802_11W -+ if (u2RxStatusCode == STATUS_CODE_AUTH_ALGORITHM_NOT_SUPPORTED) { -+ DBGLOG(SAA, INFO, "AP rejected due the authentication algorithm not support\n"); -+ } else if (u2RxStatusCode == STATUS_CODE_ASSOC_REJECTED_TEMPORARILY) { -+ PUINT_8 pucIE, pucTime; -+ UINT_16 u2IELength; -+ UINT_16 u2Offset = 0; -+ -+ u2IELength = prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen; -+ pucIE = (PUINT_8) ((ULONG) prSwRfb->pvHeader + prSwRfb->u2HeaderLen); -+ -+ IE_FOR_EACH(pucIE, u2IELength, u2Offset) { -+ if (ELEM_ID_TIMEOUT_INTERVAL == IE_ID(pucIE) && IE_LEN(pucIE) == 5) { -+ pucTime = ((P_IE_HDR_T) pucIE)->aucInfo; -+ if (pucTime[0] == ACTION_SA_TIMEOUT_ASSOC_COMEBACK) { -+ UINT_32 tu; -+ -+ WLAN_GET_FIELD_32(pucTime + 1, &tu); -+ DBGLOG(SAA, INFO, -+ "AP rejected association temporarily;comeback duration %u TU (%u ms)\n", -+ tu, TU_TO_MSEC(tu)); -+ if (tu > TX_ASSOCIATION_RETRY_TIMEOUT_TU) { -+ DBGLOG(SAA, INFO, "Update timer based on comeback duration\n"); -+ /* ieee80211_reschedule_timer(wpa_s, ms); */ -+ } -+ } -+ break; -+ } -+ } /* end of IE_FOR_EACH */ -+ } -+#endif -+ *pu2StatusCode = u2RxStatusCode; -+ -+ return WLAN_STATUS_SUCCESS; -+ -+} /* end of assocCheckRxReAssocRspFrameStatus() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will compose the Disassociation frame -+* -+* @param[in] prStaRec Pointer to the STA_RECORD_T -+* @param[in] pucBuffer Pointer to the frame buffer. -+* @param[in] aucMACAddress Given Our MAC Address. -+* @param[in] u2ReasonCode The reason code of disassociation -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+static inline VOID -+assocComposeDisassocFrame(IN P_STA_RECORD_T prStaRec, -+ IN PUINT_8 pucBuffer, IN UINT_8 aucMACAddress[], IN UINT_16 u2ReasonCode) -+{ -+ P_WLAN_DISASSOC_FRAME_T prDisAssocFrame; -+ UINT_16 u2FrameCtrl; -+ -+ ASSERT(pucBuffer); -+ ASSERT(pucBuffer); -+ ASSERT(aucMACAddress); -+ -+ prDisAssocFrame = (P_WLAN_DISASSOC_FRAME_T) pucBuffer; -+ -+ /* 4 <1> Compose the frame header of the DisAssociation frame. */ -+ /* Fill the Frame Control field. */ -+ u2FrameCtrl = MAC_FRAME_DISASSOC; -+ -+ WLAN_SET_FIELD_16(&prDisAssocFrame->u2FrameCtrl, u2FrameCtrl); -+ -+ /* Fill the DA field with Target BSSID. */ -+ COPY_MAC_ADDR(prDisAssocFrame->aucDestAddr, prStaRec->aucMacAddr); -+ -+ /* Fill the SA field with our MAC Address. */ -+ COPY_MAC_ADDR(prDisAssocFrame->aucSrcAddr, aucMACAddress); -+ -+ /* Fill the BSSID field with Target BSSID. */ -+ COPY_MAC_ADDR(prDisAssocFrame->aucBSSID, prStaRec->aucMacAddr); -+ -+ /* Clear the SEQ/FRAG_NO field(HW won't overide the FRAG_NO, so we need to clear it). */ -+ prDisAssocFrame->u2SeqCtrl = 0; -+ -+ /* 4 <2> Compose the frame body's fixed field part of the Disassociation frame. */ -+ /* Fill the Reason Code field. */ -+ WLAN_SET_FIELD_16(&prDisAssocFrame->u2ReasonCode, u2ReasonCode); -+ -+} /* end of assocComposeDisassocFrame() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will send the Disassociation frame -+* -+* @param[in] prStaRec Pointer to the STA_RECORD_T -+* @param[in] u2ReasonCode The reason code of disassociation -+* -+* @retval WLAN_STATUS_RESOURCES No available resource for frame composing. -+* @retval WLAN_STATUS_SUCCESS Successfully send frame to TX Module -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS assocSendDisAssocFrame(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN UINT_16 u2ReasonCode) -+{ -+ PUINT_8 pucMacAddress; -+ P_MSDU_INFO_T prMsduInfo; -+ UINT_16 u2PayloadLen; -+ UINT_16 u2EstimatedFrameLen; -+ /* UINT_32 u4Status = WLAN_STATUS_SUCCESS; */ -+ -+ ASSERT(prStaRec); -+ -+ /* 4 <1> Allocate a PKT_INFO_T for Disassociation Frame */ -+ /* Init with MGMT Header Length + Length of Fixed Fields + IE Length */ -+ u2EstimatedFrameLen = MAC_TX_RESERVED_FIELD + WLAN_MAC_MGMT_HEADER_LEN + REASON_CODE_FIELD_LEN; -+ -+ /* Allocate a MSDU_INFO_T */ -+ prMsduInfo = cnmMgtPktAlloc(prAdapter, u2EstimatedFrameLen); -+ if (prMsduInfo == NULL) { -+ DBGLOG(SAA, WARN, "No PKT_INFO_T for sending DisAssoc.\n"); -+ return WLAN_STATUS_RESOURCES; -+ } -+ /* 4 <2> Compose Disassociation frame header and fixed fields in MSDU_INfO_T. */ -+ ASSERT(prStaRec->ucNetTypeIndex < NETWORK_TYPE_INDEX_NUM); -+ -+ pucMacAddress = prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex].aucOwnMacAddr; -+ -+ /* Compose Header and Fixed Field */ -+ assocComposeDisassocFrame(prStaRec, -+ (PUINT_8) ((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD), -+ pucMacAddress, u2ReasonCode); -+ -+#if CFG_SUPPORT_802_11W -+ if (rsnCheckBipKeyInstalled(prAdapter, prStaRec)) { -+ P_WLAN_DISASSOC_FRAME_T prDisassocFrame; -+ -+ prDisassocFrame = -+ (P_WLAN_DEAUTH_FRAME_T) (PUINT_8) ((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD); -+ -+ prDisassocFrame->u2FrameCtrl |= MASK_FC_PROTECTED_FRAME; -+ DBGLOG(TX, WARN, "assocSendDisAssocFrame with protection\n"); -+ } -+#endif -+ -+ u2PayloadLen = REASON_CODE_FIELD_LEN; -+ -+ /* 4 <3> Update information of MSDU_INFO_T */ -+ ASSERT(prStaRec->ucNetTypeIndex < NETWORK_TYPE_INDEX_NUM); -+ -+ prMsduInfo->eSrc = TX_PACKET_MGMT; -+ prMsduInfo->ucPacketType = HIF_TX_PACKET_TYPE_MGMT; -+ prMsduInfo->ucStaRecIndex = prStaRec->ucIndex; -+ prMsduInfo->ucNetworkType = prStaRec->ucNetTypeIndex; -+ prMsduInfo->ucMacHeaderLength = WLAN_MAC_MGMT_HEADER_LEN; -+ prMsduInfo->fgIs802_1x = FALSE; -+ prMsduInfo->fgIs802_11 = TRUE; -+ prMsduInfo->u2FrameLength = WLAN_MAC_MGMT_HEADER_LEN + u2PayloadLen; -+ prMsduInfo->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter); -+ prMsduInfo->pfTxDoneHandler = NULL; -+ prMsduInfo->fgIsBasicRate = TRUE; -+ -+ /* 4 <4> Enqueue the frame to send this (Re)Association request frame. */ -+ nicTxEnqueueMsdu(prAdapter, prMsduInfo); -+ -+ return WLAN_STATUS_SUCCESS; -+} /* end of assocSendDisAssocFrame() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will parse and process the incoming Disassociation frame -+* if the given BSSID is matched. -+* -+* @param[in] prSwRfb Pointer to SW RFB data structure. -+* @param[in] aucBSSID Given BSSID -+* @param[out] pu2ReasonCode Pointer to store the Reason Code from Deauthentication. -+* -+* @retval WLAN_STATUS_FAILURE This is not the frame we should handle at current state. -+* @retval WLAN_STATUS_SUCCESS This is the frame we should handle. -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+assocProcessRxDisassocFrame(IN P_ADAPTER_T prAdapter, -+ IN P_SW_RFB_T prSwRfb, IN UINT_8 aucBSSID[], OUT PUINT_16 pu2ReasonCode) -+{ -+ P_WLAN_DISASSOC_FRAME_T prDisassocFrame; -+ UINT_16 u2RxReasonCode; -+ -+ ASSERT(prSwRfb); -+ ASSERT(aucBSSID); -+ ASSERT(pu2ReasonCode); -+ -+ /* 4 <1> locate the Disassociation Frame. */ -+ prDisassocFrame = (P_WLAN_DISASSOC_FRAME_T) prSwRfb->pvHeader; -+ -+ /* 4 <2> Parse the Header of Disassociation Frame. */ -+ if ((prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen) < REASON_CODE_FIELD_LEN) { -+ ASSERT(0); -+ return WLAN_STATUS_FAILURE; -+ } -+ -+ /* Check if this Disassoc Frame is coming from Target BSSID */ -+ if (UNEQUAL_MAC_ADDR(prDisassocFrame->aucBSSID, aucBSSID)) { -+ DBGLOG(SAA, LOUD, "Ignore Disassoc Frame from other BSS [ %pM ]\n", -+ prDisassocFrame->aucSrcAddr); -+ return WLAN_STATUS_FAILURE; -+ } -+ /* 4 <3> Parse the Fixed Fields of Deauthentication Frame Body. */ -+ WLAN_GET_FIELD_16(&prDisassocFrame->u2ReasonCode, &u2RxReasonCode); -+ *pu2ReasonCode = u2RxReasonCode; -+ -+ return WLAN_STATUS_SUCCESS; -+ -+} /* end of assocProcessRxDisassocFrame() */ -+ -+#if CFG_SUPPORT_AAA -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will parse and process the incoming Association Req frame -+* and return a Status Code. -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* @param[in] prSwRfb Pointer to SW RFB data structure. -+* @param[out] pu2StatusCode Pointer to store the Status Code for carried in Association Response. -+* -+* @retval WLAN_STATUS_FAILURE This is not the frame we should handle at current state. -+* @retval WLAN_STATUS_SUCCESS This is the frame we should handle. -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS assocProcessRxAssocReqFrame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, OUT PUINT_16 pu2StatusCode) -+{ -+ P_WLAN_ASSOC_REQ_FRAME_T prAssocReqFrame; -+ P_STA_RECORD_T prStaRec; -+ P_BSS_INFO_T prBssInfo; -+ P_IE_SSID_T prIeSsid = (P_IE_SSID_T) NULL; -+ P_RSN_INFO_ELEM_T prIeRsn = (P_RSN_INFO_ELEM_T) NULL; -+ P_IE_SUPPORTED_RATE_T prIeSupportedRate = (P_IE_SUPPORTED_RATE_T) NULL; -+ P_IE_EXT_SUPPORTED_RATE_T prIeExtSupportedRate = (P_IE_EXT_SUPPORTED_RATE_T) NULL; -+ PUINT_8 pucIE, pucIEStart; -+ UINT_16 u2IELength; -+ UINT_16 u2Offset = 0; -+ UINT_16 u2StatusCode = STATUS_CODE_SUCCESSFUL; -+ UINT_16 u2RxFrameCtrl; -+ UINT_16 u2BSSBasicRateSet; -+ BOOLEAN fgIsUnknownBssBasicRate; -+ UINT_32 i; -+ -+ ASSERT(prAdapter); -+ ASSERT(prSwRfb); -+ ASSERT(pu2StatusCode); -+ -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); -+ -+ if (prStaRec == NULL) -+ return WLAN_STATUS_FAILURE; -+ /* 4 <1> locate the Association Req Frame. */ -+ prAssocReqFrame = (P_WLAN_ASSOC_REQ_FRAME_T) prSwRfb->pvHeader; -+ -+ /* 4 <2> Parse the Header of Association Req Frame. */ -+ if ((prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen) < (CAP_INFO_FIELD_LEN + LISTEN_INTERVAL_FIELD_LEN)) { -+ ASSERT(0); -+ return WLAN_STATUS_FAILURE; -+ } -+ -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]); -+ -+ /* Check if this Disassoc Frame is coming from Target BSSID */ -+ if (UNEQUAL_MAC_ADDR(prAssocReqFrame->aucBSSID, prBssInfo->aucBSSID)) -+ return WLAN_STATUS_FAILURE; /* Just Ignore this MMPDU */ -+ /* WLAN_GET_FIELD_16(&prAssocReqFrame->u2FrameCtrl, &u2RxFrameCtrl); */ -+ u2RxFrameCtrl = prAssocReqFrame->u2FrameCtrl; /* NOTE(Kevin): Optimized for ARM */ -+ u2RxFrameCtrl &= MASK_FRAME_TYPE; -+ if (MAC_FRAME_REASSOC_REQ == u2RxFrameCtrl) { -+ prStaRec->fgIsReAssoc = TRUE; -+ -+ u2IELength = (prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen) - -+ (UINT_16) (OFFSET_OF(WLAN_REASSOC_REQ_FRAME_T, aucInfoElem[0]) - WLAN_MAC_MGMT_HEADER_LEN); -+ -+ pucIEStart = pucIE = ((P_WLAN_REASSOC_REQ_FRAME_T) (prSwRfb->pvHeader))->aucInfoElem; -+ } else { -+ prStaRec->fgIsReAssoc = FALSE; -+ -+ u2IELength = (prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen) - -+ (UINT_16) (OFFSET_OF(WLAN_ASSOC_REQ_FRAME_T, aucInfoElem[0]) - WLAN_MAC_MGMT_HEADER_LEN); -+ -+ pucIEStart = pucIE = prAssocReqFrame->aucInfoElem; -+ } -+ -+ /* 4 <3> Parse the Fixed Fields of Assoc Req Frame Body. */ -+ prStaRec->u2CapInfo = prAssocReqFrame->u2CapInfo; -+ -+#if CFG_ENABLE_WIFI_DIRECT && CFG_ENABLE_HOTSPOT_PRIVACY_CHECK -+ if (prAdapter->fgIsP2PRegistered && IS_STA_IN_P2P(prStaRec)) { -+ if (((prStaRec->u2CapInfo & CAP_INFO_PRIVACY) && !kalP2PGetCipher(prAdapter->prGlueInfo))) { -+ u2StatusCode = STATUS_CODE_CAP_NOT_SUPPORTED; -+ DBGLOG(RSN, TRACE, "STA Assoc req privacy bit check fail\n"); -+ return WLAN_STATUS_SUCCESS; -+ } -+ } -+#endif -+ -+ prStaRec->u2ListenInterval = prAssocReqFrame->u2ListenInterval; -+ prStaRec->ucPhyTypeSet = 0; -+ -+ /* Might be legacy client or p2p gc. */ -+ prStaRec->eStaType = STA_TYPE_LEGACY_CLIENT; -+ -+ /* 4 <4> Parse the IE of Assoc Req Frame Body. */ -+ IE_FOR_EACH(pucIE, u2IELength, u2Offset) { -+ switch (IE_ID(pucIE)) { -+ case ELEM_ID_SSID: -+ if ((!prIeSsid) && /* NOTE(Kevin): Get SSID once */ -+ (IE_LEN(pucIE) <= ELEM_MAX_LEN_SSID)) { -+ prIeSsid = (P_IE_SSID_T) pucIE; -+ } -+ break; -+ -+ case ELEM_ID_SUP_RATES: -+ if ((!prIeSupportedRate) && (IE_LEN(pucIE) <= RATE_NUM)) -+ prIeSupportedRate = SUP_RATES_IE(pucIE); -+ break; -+ -+ case ELEM_ID_EXTENDED_SUP_RATES: -+ if (!prIeExtSupportedRate) -+ prIeExtSupportedRate = EXT_SUP_RATES_IE(pucIE); -+ break; -+ case ELEM_ID_HT_CAP: -+ prStaRec->ucPhyTypeSet |= PHY_TYPE_BIT_HT; -+ kalMemCopy(&prStaRec->u2HtCapInfo, &(HT_CAP_IE(pucIE)->u2HtCapInfo), 2); -+ break; -+ case ELEM_ID_RSN: -+#if CFG_ENABLE_WIFI_DIRECT && CFG_ENABLE_HOTSPOT_PRIVACY_CHECK -+ if (prAdapter->fgIsP2PRegistered && IS_STA_IN_P2P(prStaRec)) { -+ prIeRsn = RSN_IE(pucIE); -+ rsnParserCheckForRSNCCMPPSK(prAdapter, prIeRsn, &u2StatusCode); -+ if (u2StatusCode != STATUS_CODE_SUCCESSFUL) { -+ *pu2StatusCode = u2StatusCode; -+ return WLAN_STATUS_SUCCESS; -+ } -+ } -+#endif -+ break; -+ case ELEM_ID_VENDOR: -+#if CFG_ENABLE_WIFI_DIRECT -+ { -+ if ((prAdapter->fgIsP2PRegistered)) { -+ UINT_8 ucOuiType = 0; -+ -+ p2pFuncParseCheckForP2PInfoElem(prAdapter, pucIE, &ucOuiType); -+ -+ if (ucOuiType == VENDOR_OUI_TYPE_P2P) { -+ DBGLOG(P2P, TRACE, "Target Client is a P2P group client\n"); -+ prStaRec->eStaType = STA_TYPE_P2P_GC; -+ } -+ } -+ } -+#endif -+ break; -+ default: -+ for (i = 0; i < (sizeof(rxAssocReqIETable) / sizeof(VERIFY_IE_ENTRY_T)); i++) { -+ -+ if ((IE_ID(pucIE)) == rxAssocReqIETable[i].ucElemID) { -+ rxAssocReqIETable[i].pfnVarifyIE(prAdapter, prSwRfb, (P_IE_HDR_T) pucIE, -+ &u2StatusCode); -+ -+ if (u2StatusCode != STATUS_CODE_SUCCESSFUL) { -+ *pu2StatusCode = u2StatusCode; -+ return WLAN_STATUS_SUCCESS; -+ } -+ } -+ } -+ -+ break; -+ } -+ } /* end of IE_FOR_EACH */ -+ -+ /* parsing for WMM related information (2010/12/21) */ -+ mqmProcessAssocReq(prAdapter, prSwRfb, pucIEStart, u2IELength); -+ -+ do { -+ if (prIeSsid) { -+ if (UNEQUAL_SSID(prBssInfo->aucSSID, prBssInfo->ucSSIDLen, -+ prIeSsid->aucSSID, prIeSsid->ucLength)) { -+ -+ u2StatusCode = STATUS_CODE_UNSPECIFIED_FAILURE; -+ break; -+ } -+ } else { -+ u2StatusCode = STATUS_CODE_UNSPECIFIED_FAILURE; -+ break; -+ } -+ -+ prStaRec->u2OperationalRateSet = 0; -+ prStaRec->u2BSSBasicRateSet = 0; -+ -+ if (prIeSupportedRate || prIeExtSupportedRate) { -+ rateGetRateSetFromIEs(prIeSupportedRate, prIeExtSupportedRate, &prStaRec->u2OperationalRateSet, -+ &u2BSSBasicRateSet, /* Ignore any Basic Bit */ -+ &fgIsUnknownBssBasicRate); -+ -+ if ((prBssInfo->u2BSSBasicRateSet & prStaRec->u2OperationalRateSet) != -+ prBssInfo->u2BSSBasicRateSet) { -+ -+ u2StatusCode = STATUS_CODE_ASSOC_DENIED_RATE_NOT_SUPPORTED; -+ break; -+ } -+ -+ /* Accpet the Sta, update BSSBasicRateSet from Bss */ -+ -+ prStaRec->u2BSSBasicRateSet = prBssInfo->u2BSSBasicRateSet; -+ -+ prStaRec->u2DesiredNonHTRateSet = (prStaRec->u2OperationalRateSet & RATE_SET_ALL_ABG); -+ -+ if (BAND_2G4 == HIF_RX_HDR_GET_RF_BAND(prSwRfb->prHifRxHdr)) { -+#if 0 /* Marked by CMC 20111024 */ -+ /* check if support 11n */ -+ if (!(u2BSSBasicRateSet & RATE_SET_BIT_HT_PHY)) { -+ -+ if (prStaRec->u2OperationalRateSet & RATE_SET_OFDM) -+ prStaRec->ucPhyTypeSet |= PHY_TYPE_BIT_ERP; -+ -+ if ((!(u2BSSBasicRateSet & RATE_SET_OFDM)) && -+ (prStaRec->u2OperationalRateSet & RATE_SET_HR_DSSS)) { -+ prStaRec->ucPhyTypeSet |= PHY_TYPE_BIT_HR_DSSS; -+ -+ } -+ -+ } -+#else -+ if (prStaRec->u2OperationalRateSet & RATE_SET_OFDM) -+ prStaRec->ucPhyTypeSet |= PHY_TYPE_BIT_ERP; -+ if (prStaRec->u2OperationalRateSet & RATE_SET_HR_DSSS) -+ prStaRec->ucPhyTypeSet |= PHY_TYPE_BIT_HR_DSSS; -+#endif -+ } else { /* (BAND_5G == prBssDesc->eBande) */ -+#if 0 /* Marked by CMC 20111024 */ -+ if (!(u2BSSBasicRateSet & RATE_SET_BIT_HT_PHY)) -+ prStaRec->ucPhyTypeSet |= PHY_TYPE_BIT_OFDM; -+ ASSERT((prStaRec->u2OperationalRateSet & RATE_SET_HR_DSSS) == 0); -+#else -+ if (prStaRec->u2OperationalRateSet & RATE_SET_OFDM) -+ prStaRec->ucPhyTypeSet |= PHY_TYPE_BIT_OFDM; -+#endif -+ } -+ -+ } else { -+ ASSERT(0); -+ u2StatusCode = STATUS_CODE_ASSOC_DENIED_RATE_NOT_SUPPORTED; -+ break; -+ } -+ -+#if CFG_ENABLE_WIFI_DIRECT && CFG_ENABLE_HOTSPOT_PRIVACY_CHECK -+ if (prAdapter->fgIsP2PRegistered && IS_STA_IN_P2P(prStaRec)) { -+ if (prIeRsn) { -+ if (!kalP2PGetCipher(prAdapter->prGlueInfo)) { -+ u2StatusCode = STATUS_CODE_CIPHER_SUITE_REJECTED; -+ break; -+ } -+ } else { -+ prStaRec->rSecInfo.fgAllowOnly1x = FALSE; -+ if (kalP2PGetCipher(prAdapter->prGlueInfo)) { -+ /* Only Allow 1x */ -+ prStaRec->rSecInfo.fgAllowOnly1x = TRUE; -+ break; -+ } -+ } -+ } -+#endif -+ -+ } while (FALSE); -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ if (prAdapter->fgIsP2PRegistered && IS_STA_IN_P2P(prStaRec)) { -+#if 1 /* ICS */ -+ { -+ PUINT_8 cp = (PUINT_8) &prAssocReqFrame->u2CapInfo; -+ P_UINT_8 prNewAssocReqIe = NULL; -+ -+ if (u2IELength) { -+ prNewAssocReqIe = kalMemAlloc(u2IELength, VIR_MEM_TYPE); -+ if (NULL == prNewAssocReqIe) { -+ DBGLOG(AIS, WARN, "allocate memory for (Re)assocReqIe fail!\n"); -+ u2StatusCode = STATUS_CODE_INVALID_INFO_ELEMENT; -+ return WLAN_STATUS_FAILURE; -+ } -+ } -+ -+ if (prStaRec->fgIsReAssoc) -+ cp += 10; -+ else -+ cp += 4; -+ if (prStaRec->pucAssocReqIe) { -+ kalMemFree(prStaRec->pucAssocReqIe, VIR_MEM_TYPE, prStaRec->u2AssocReqIeLen); -+ prStaRec->pucAssocReqIe = NULL; -+ } -+ prStaRec->u2AssocReqIeLen = u2IELength; -+ if (u2IELength) { -+ prStaRec->pucAssocReqIe = prNewAssocReqIe; /* kalMemAlloc(u2IELength, VIR_MEM_TYPE); */ -+ kalMemCopy(prStaRec->pucAssocReqIe, cp, u2IELength); -+ } -+ } -+#endif -+ kalP2PUpdateAssocInfo(prAdapter->prGlueInfo, (PUINT_8) &prAssocReqFrame->u2CapInfo, -+ u2IELength + (prStaRec->fgIsReAssoc ? 10 : 4), prStaRec->fgIsReAssoc); -+ } -+#endif -+ -+ *pu2StatusCode = u2StatusCode; -+ -+ return WLAN_STATUS_SUCCESS; -+ -+} /* end of assocProcessRxAssocReqFrame() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is used to compose Common Information Elements for Association -+* Response Frame. -+* -+* @param[in] prMsduInfo Pointer to the composed MSDU_INFO_T. -+* @param[in] prBssInfo Pointer to the BSS_INFO_T. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+static inline VOID -+assocBuildReAssocRespFrameCommonIEs(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo, IN P_BSS_INFO_T prBssInfo) -+{ -+ PUINT_8 pucBuffer; -+ P_STA_RECORD_T prStaRec; -+ UINT_8 ucSupRatesLen; -+ UINT_8 ucExtSupRatesLen; -+ -+ ASSERT(prMsduInfo); -+ ASSERT(prMsduInfo->eSrc == TX_PACKET_MGMT); -+ -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); -+ ASSERT(prStaRec); -+ -+ pucBuffer = (PUINT_8) ((ULONG) prMsduInfo->prPacket + (UINT_32) prMsduInfo->u2FrameLength); -+ ASSERT(pucBuffer); -+ -+ if (prBssInfo->ucAllSupportedRatesLen > ELEM_MAX_LEN_SUP_RATES) { -+ -+ ucSupRatesLen = ELEM_MAX_LEN_SUP_RATES; -+ ucExtSupRatesLen = prBssInfo->ucAllSupportedRatesLen - ELEM_MAX_LEN_SUP_RATES; -+ } else { -+ ucSupRatesLen = prBssInfo->ucAllSupportedRatesLen; -+ ucExtSupRatesLen = 0; -+ } -+ -+ /* Fill the Supported Rates element. */ -+ if (ucSupRatesLen) { -+ SUP_RATES_IE(pucBuffer)->ucId = ELEM_ID_SUP_RATES; -+ SUP_RATES_IE(pucBuffer)->ucLength = ucSupRatesLen; -+ kalMemCopy(SUP_RATES_IE(pucBuffer)->aucSupportedRates, prBssInfo->aucAllSupportedRates, ucSupRatesLen); -+ -+ prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer); -+ pucBuffer += IE_SIZE(pucBuffer); -+ } -+ -+ /* Fill the Extended Supported Rates element. */ -+ if (ucExtSupRatesLen) { -+ -+ EXT_SUP_RATES_IE(pucBuffer)->ucId = ELEM_ID_EXTENDED_SUP_RATES; -+ EXT_SUP_RATES_IE(pucBuffer)->ucLength = ucExtSupRatesLen; -+ -+ kalMemCopy(EXT_SUP_RATES_IE(pucBuffer)->aucExtSupportedRates, -+ &prBssInfo->aucAllSupportedRates[ucSupRatesLen], ucExtSupRatesLen); -+ -+ prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer); -+ } -+ -+} /* end of assocBuildReAssocRespFrameCommonIEs() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will compose the (Re)Association Response frame -+* -+* @param[in] prStaRec Pointer to the STA_RECORD_T -+* @param[in] pucBuffer Pointer to the frame buffer. -+* @param[in] aucBssid Given BSSID. -+* @param[in] u2CapInfo Capability Field of current BSS. -+* @param[in out] pu2PayloadLen Return the length of the composed fixed fields -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+static inline VOID -+assocComposeReAssocRespFrameHeaderAndFF(IN P_STA_RECORD_T prStaRec, -+ IN PUINT_8 pucBuffer, -+ IN UINT_8 aucBSSID[], IN UINT_16 u2CapInfo, IN OUT PUINT_16 pu2PayloadLen) -+{ -+ P_WLAN_ASSOC_RSP_FRAME_T prAssocRspFrame; -+ BOOLEAN fgIsReAssoc; -+ -+ UINT_16 u2FrameCtrl; -+ -+ ASSERT(prStaRec); -+ ASSERT(pucBuffer); -+ ASSERT(aucBSSID); -+ ASSERT(pu2PayloadLen); -+ -+ prAssocRspFrame = (P_WLAN_ASSOC_RSP_FRAME_T) pucBuffer; -+ fgIsReAssoc = prStaRec->fgIsReAssoc; -+ -+ /* 4 <1> Compose the frame header of the (Re)Association Request frame. */ -+ /* Fill the Frame Control field. */ -+ if (fgIsReAssoc) -+ u2FrameCtrl = MAC_FRAME_REASSOC_RSP; -+ else -+ u2FrameCtrl = MAC_FRAME_ASSOC_RSP; -+ /* WLAN_SET_FIELD_16(&prAssocFrame->u2FrameCtrl, u2FrameCtrl); */ -+ prAssocRspFrame->u2FrameCtrl = u2FrameCtrl; /* NOTE(Kevin): Optimized for ARM */ -+ -+ /* Fill the DA field with Target MAC Address. */ -+ COPY_MAC_ADDR(prAssocRspFrame->aucDestAddr, prStaRec->aucMacAddr); -+ -+ /* Fill the SA field with current BSSID. */ -+ COPY_MAC_ADDR(prAssocRspFrame->aucSrcAddr, aucBSSID); -+ -+ /* Fill the BSSID field with current BSSID. */ -+ COPY_MAC_ADDR(prAssocRspFrame->aucBSSID, aucBSSID); -+ -+ /* Clear the SEQ/FRAG_NO field(HW won't overide the FRAG_NO, so we need to clear it). */ -+ prAssocRspFrame->u2SeqCtrl = 0; -+ -+ /* 4 <2> Compose the frame body's common fixed field part of the (Re)Association Request frame. */ -+ /* Fill the Capability Information field. */ -+ /* WLAN_SET_FIELD_16(&prAssocFrame->u2CapInfo, u2CapInfo); */ -+ prAssocRspFrame->u2CapInfo = u2CapInfo; /* NOTE(Kevin): Optimized for ARM */ -+ -+ /* WLAN_SET_FIELD_16(&prAssocFrame->u2StatusCode, prStaRec->u2StatusCode); */ -+ prAssocRspFrame->u2StatusCode = prStaRec->u2StatusCode; /* NOTE(Kevin): Optimized for ARM */ -+ -+ /* WLAN_SET_FIELD_16(&prAssocFrame->u2AssocId, ((prStaRec->u2AssocId & AID_MASK) | AID_MSB)); */ -+ prAssocRspFrame->u2AssocId = ((prStaRec->u2AssocId & AID_MASK) | AID_MSB); /* NOTE(Kevin): Optimized for ARM */ -+ -+ *pu2PayloadLen = (CAP_INFO_FIELD_LEN + STATUS_CODE_FIELD_LEN + AID_FIELD_LEN); -+ -+} /* end of assocComposeReAssocRespFrameHeaderAndFF() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will send the (Re)Association Resp frame -+* -+* @param[in] prStaRec Pointer to the STA_RECORD_T -+* -+* @retval WLAN_STATUS_RESOURCES No available resource for frame composing. -+* @retval WLAN_STATUS_SUCCESS Successfully send frame to TX Module -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS assocSendReAssocRespFrame(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec) -+{ -+ P_BSS_INFO_T prBssInfo; -+ P_MSDU_INFO_T prMsduInfo; -+ -+ UINT_16 u2PayloadLen; -+ UINT_16 u2EstimatedFrameLen; -+ UINT_16 u2EstimatedExtraIELen; -+ BOOLEAN fgIsReAssoc; -+ UINT_32 i; -+ -+ ASSERT(prStaRec); -+ -+ /* 4 <1> Allocate a PKT_INFO_T for Authentication Frame */ -+ fgIsReAssoc = prStaRec->fgIsReAssoc; -+ -+ /* Init with MGMT Header Length + Length of Fixed Fields + Common IE Length */ -+ u2EstimatedFrameLen = MAC_TX_RESERVED_FIELD + -+ WLAN_MAC_MGMT_HEADER_LEN + -+ CAP_INFO_FIELD_LEN + -+ STATUS_CODE_FIELD_LEN + -+ AID_FIELD_LEN + -+ (ELEM_HDR_LEN + ELEM_MAX_LEN_SUP_RATES) + (ELEM_HDR_LEN + (RATE_NUM - ELEM_MAX_LEN_SUP_RATES)); -+ -+ /* + Extra IE Length */ -+ u2EstimatedExtraIELen = 0; -+ -+ for (i = 0; i < sizeof(txAssocRespIETable) / sizeof(APPEND_VAR_IE_ENTRY_T); i++) { -+ if (txAssocRespIETable[i].u2EstimatedFixedIELen != 0) { -+ u2EstimatedExtraIELen += txAssocRespIETable[i].u2EstimatedFixedIELen; -+ } else if (txAssocRespIETable[i].pfnCalculateVariableIELen != NULL) { -+ u2EstimatedExtraIELen += (UINT_16) txAssocRespIETable[i].pfnCalculateVariableIELen(prAdapter, -+ prStaRec->ucNetTypeIndex, -+ prStaRec); -+ } -+ -+ } -+ -+ u2EstimatedFrameLen += u2EstimatedExtraIELen; -+ -+ /* Allocate a MSDU_INFO_T */ -+ prMsduInfo = cnmMgtPktAlloc(prAdapter, u2EstimatedFrameLen); -+ if (prMsduInfo == NULL) { -+ DBGLOG(AAA, WARN, "No PKT_INFO_T for sending (Re)Assoc Response.\n"); -+ return WLAN_STATUS_RESOURCES; -+ } -+ /* 4 <2> Compose (Re)Association Request frame header and fixed fields in MSDU_INfO_T. */ -+ ASSERT(prStaRec->ucNetTypeIndex != NETWORK_TYPE_AIS_INDEX); -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]); -+ -+ /* Compose Header and Fixed Field */ -+ assocComposeReAssocRespFrameHeaderAndFF(prStaRec, -+ (PUINT_8) ((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD), -+ prBssInfo->aucBSSID, prBssInfo->u2CapInfo, &u2PayloadLen); -+ -+ /* 4 <3> Update information of MSDU_INFO_T */ -+ ASSERT(prStaRec->ucNetTypeIndex < NETWORK_TYPE_INDEX_NUM); -+ -+ prMsduInfo->eSrc = TX_PACKET_MGMT; -+ prMsduInfo->ucPacketType = HIF_TX_PACKET_TYPE_MGMT; -+ prMsduInfo->ucStaRecIndex = prStaRec->ucIndex; -+ prMsduInfo->ucNetworkType = prStaRec->ucNetTypeIndex; -+ prMsduInfo->ucMacHeaderLength = WLAN_MAC_MGMT_HEADER_LEN; -+ prMsduInfo->fgIs802_1x = FALSE; -+ prMsduInfo->fgIs802_11 = TRUE; -+ prMsduInfo->u2FrameLength = WLAN_MAC_MGMT_HEADER_LEN + u2PayloadLen; -+ prMsduInfo->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter); -+ prMsduInfo->pfTxDoneHandler = aaaFsmRunEventTxDone; -+ prMsduInfo->fgIsBasicRate = TRUE; -+ -+ /* 4 <4> Compose the frame body's IEs of the (Re)Association Request frame. */ -+ assocBuildReAssocRespFrameCommonIEs(prAdapter, prMsduInfo, prBssInfo); -+ -+ /* 4 <5> Compose IEs in MSDU_INFO_T */ -+ -+ /* Append IE */ -+ for (i = 0; i < sizeof(txAssocRespIETable) / sizeof(APPEND_VAR_IE_ENTRY_T); i++) { -+ if (txAssocRespIETable[i].pfnAppendIE) -+ txAssocRespIETable[i].pfnAppendIE(prAdapter, prMsduInfo); -+ } -+ -+ /* TODO(Kevin): Also release the unused tail room of the composed MMPDU */ -+ -+ /* 4 <6> Enqueue the frame to send this (Re)Association request frame. */ -+ DBGLOG(SAA, INFO, "Sending (Re)Assoc Response, network: %d seqNo: %d\n", -+ prMsduInfo->ucNetworkType, prMsduInfo->ucTxSeqNum); -+ nicTxEnqueueMsdu(prAdapter, prMsduInfo); -+ -+ return WLAN_STATUS_SUCCESS; -+ -+} /* end of assocSendReAssocRespFrame() */ -+#endif /* CFG_SUPPORT_AAA */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/auth.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/auth.c -new file mode 100644 -index 000000000000..43b91d72bd43 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/auth.c -@@ -0,0 +1,1211 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/auth.c#1 -+*/ -+ -+/*! \file "auth.c" -+ \brief This file includes the authentication-related functions. -+ -+ This file includes the authentication-related functions. -+*/ -+ -+/* -+** Log: auth.c -+ * -+ * 02 13 2012 cp.wu -+ * NULL -+ * show error message only instead of raise assertion when -+ * received authentication frame is carrying illegal parameters. -+ * -+ * 11 09 2011 yuche.tsai -+ * NULL -+ * Fix a network index & station record index issue when TX deauth frame. -+ * -+ * 10 12 2011 wh.su -+ * [WCXRP00001036] [MT6620 Wi-Fi][Driver][FW] Adding the 802.11w code for MFP -+ * adding the 802.11w related function and define . -+ * -+ * 06 22 2011 yuche.tsai -+ * NULL -+ * Fix coding error. -+ * -+ * 06 20 2011 yuche.tsai -+ * [WCXRP00000796] [Volunteer Patch][MT6620][Driver] Add BC deauth frame TX feature. -+ * BC deauth support. -+ * -+ * 04 21 2011 terry.wu -+ * [WCXRP00000674] [MT6620 Wi-Fi][Driver] Refine AAA authSendAuthFrame -+ * Add network type parameter to authSendAuthFrame. -+ * -+ * 04 15 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Add BOW short range mode. -+ * -+ * 02 08 2011 yuche.tsai -+ * [WCXRP00000245] 1. Invitation Request/Response. -+2. Provision Discovery Request/Response -+ -+ * 1. Fix Service Disocvery Logical issue. -+ * 2. Fix a NULL pointer access violation issue when sending deauthentication packet to a class error station. -+ * -+ * 01 24 2011 cp.wu -+ * [WCXRP00000382] [MT6620 Wi-Fi][Driver] Track forwarding packet number with notifying tx thread for serving -+ * 1. add an extra counter for tracking pending forward frames. -+ * 2. notify TX service thread as well when there is pending forward frame -+ * 3. correct build errors leaded by introduction of Wi-Fi direct separation module -+ * -+ * 01 21 2011 terry.wu -+ * [WCXRP00000381] [MT6620 Wi-Fi][Driver] Kernel panic when replying unaccept Auth in AP mode -+ * In AP mode, use STA_REC_INDEX_NOT_FOUND(0xFE) instead of StaRec index when replying an unaccept Auth frame. -+ * -+ * 10 18 2010 cp.wu -+ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning -+ * use definition macro to replace hard-coded constant -+ * -+ * 09 03 2010 kevin.huang -+ * NULL -+ * Refine #include sequence and solve recursive/nested #include issue -+ * -+ * 08 30 2010 cp.wu -+ * NULL -+ * eliminate klockwork errors -+ * -+ * 08 16 2010 cp.wu -+ * NULL -+ * Replace CFG_SUPPORT_BOW by CFG_ENABLE_BT_OVER_WIFI. -+ * There is no CFG_SUPPORT_BOW in driver domain source. -+ * -+ * 08 16 2010 kevin.huang -+ * NULL -+ * Refine AAA functions -+ * -+ * 08 03 2010 cp.wu -+ * NULL -+ * surpress compilation warning. -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 28 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * send MMPDU in basic rate. -+ * -+ * 06 21 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * specify correct value for management frames. -+ * -+ * 06 18 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Provide cnmMgtPktAlloc() and alloc/free function of msg/buf -+ * -+ * 06 14 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add management dispatching function table. -+ * -+ * 06 11 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * auth.c is migrated. -+ * -+ * 05 28 2010 kevin.huang -+ * [BORA00000794][WIFISYS][New Feature]Power Management Support -+ * Update authSendDeauthFrame() for correct the value of eNetTypeIndex in MSDU_INFO_T -+ * -+ * 05 24 2010 kevin.huang -+ * [BORA00000794][WIFISYS][New Feature]Power Management Support -+ * Check Net is active before sending Deauth frame. -+ * -+ * 05 24 2010 kevin.huang -+ * [BORA00000794][WIFISYS][New Feature]Power Management Support -+ * Refine authSendAuthFrame() for NULL STA_RECORD_T case and minimum deauth interval. -+ * -+ * 04 24 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * g_aprBssInfo[] depends on CFG_SUPPORT_P2P and CFG_SUPPORT_BOW -+ * -+ * 04 19 2010 kevin.huang -+ * [BORA00000714][WIFISYS][New Feature]Beacon Timeout Support -+ * Add Send Deauth for Class 3 Error and Leave Network Support -+ * -+ * 02 23 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Fix compile warning -+ * -+ * 02 05 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Add debug message for abnormal authentication frame from AP -+ * -+ * 02 04 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Add AAA Module Support, Revise Net Type to Net Type Index for array lookup -+ * -+ * 01 11 2010 kevin.huang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Add Deauth and Disassoc Handler -+ * -+ * 01 07 2010 kevin.huang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * -+ * Fix the Debug Label -+ * -+ * 12 18 2009 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * . -+ * -+ * Dec 7 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Update the authComposeAuthFrameHeader() -+ * -+ * Dec 7 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * adding the send deauth frame function -+ * -+ * Dec 3 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Integrate send Auth with TXM -+ * -+ * Nov 24 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Revise MGMT Handler with Retain Status -+ * -+ * Nov 23 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "precomp.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+APPEND_IE_ENTRY_T txAuthIETable[] = { -+ {(ELEM_HDR_LEN + ELEM_MAX_LEN_CHALLENGE_TEXT), authAddIEChallengeText} -+}; -+ -+HANDLE_IE_ENTRY_T rxAuthIETable[] = { -+ {ELEM_ID_CHALLENGE_TEXT, authHandleIEChallengeText} -+}; -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will compose the Authentication frame header and fixed fields. -+* -+* @param[in] pucBuffer Pointer to the frame buffer. -+* @param[in] aucPeerMACAddress Given Peer MAC Address. -+* @param[in] aucMACAddress Given Our MAC Address. -+* @param[in] u2AuthAlgNum Authentication Algorithm Number -+* @param[in] u2TransactionSeqNum Transaction Sequence Number -+* @param[in] u2StatusCode Status Code -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+static inline VOID -+authComposeAuthFrameHeaderAndFF(IN PUINT_8 pucBuffer, -+ IN UINT_8 aucPeerMACAddress[], -+ IN UINT_8 aucMACAddress[], -+ IN UINT_16 u2AuthAlgNum, IN UINT_16 u2TransactionSeqNum, IN UINT_16 u2StatusCode) -+{ -+ P_WLAN_AUTH_FRAME_T prAuthFrame; -+ UINT_16 u2FrameCtrl; -+ -+ ASSERT(pucBuffer); -+ ASSERT(aucPeerMACAddress); -+ ASSERT(aucMACAddress); -+ -+ prAuthFrame = (P_WLAN_AUTH_FRAME_T) pucBuffer; -+ -+ /* 4 <1> Compose the frame header of the Authentication frame. */ -+ /* Fill the Frame Control field. */ -+ u2FrameCtrl = MAC_FRAME_AUTH; -+ -+ /* If this frame is the third frame in the shared key authentication -+ * sequence, it shall be encrypted. -+ */ -+ if ((u2AuthAlgNum == AUTH_ALGORITHM_NUM_SHARED_KEY) && (u2TransactionSeqNum == AUTH_TRANSACTION_SEQ_3)) -+ u2FrameCtrl |= MASK_FC_PROTECTED_FRAME; /* HW will also detect this bit for applying encryption */ -+ /* WLAN_SET_FIELD_16(&prAuthFrame->u2FrameCtrl, u2FrameCtrl); */ -+ prAuthFrame->u2FrameCtrl = u2FrameCtrl; /* NOTE(Kevin): Optimized for ARM */ -+ -+ /* Fill the DA field with Target BSSID. */ -+ COPY_MAC_ADDR(prAuthFrame->aucDestAddr, aucPeerMACAddress); -+ -+ /* Fill the SA field with our MAC Address. */ -+ COPY_MAC_ADDR(prAuthFrame->aucSrcAddr, aucMACAddress); -+ -+ switch (u2TransactionSeqNum) { -+ case AUTH_TRANSACTION_SEQ_1: -+ case AUTH_TRANSACTION_SEQ_3: -+ -+ /* Fill the BSSID field with Target BSSID. */ -+ COPY_MAC_ADDR(prAuthFrame->aucBSSID, aucPeerMACAddress); -+ break; -+ -+ case AUTH_TRANSACTION_SEQ_2: -+ case AUTH_TRANSACTION_SEQ_4: -+ -+ /* Fill the BSSID field with Current BSSID. */ -+ COPY_MAC_ADDR(prAuthFrame->aucBSSID, aucMACAddress); -+ break; -+ -+ default: -+ ASSERT(0); -+ } -+ -+ /* Clear the SEQ/FRAG_NO field. */ -+ prAuthFrame->u2SeqCtrl = 0; -+ -+ /* 4 <2> Compose the frame body's fixed field part of the Authentication frame. */ -+ /* Fill the Authentication Algorithm Number field. */ -+ /* WLAN_SET_FIELD_16(&prAuthFrame->u2AuthAlgNum, u2AuthAlgNum); */ -+ prAuthFrame->u2AuthAlgNum = u2AuthAlgNum; /* NOTE(Kevin): Optimized for ARM */ -+ -+ /* Fill the Authentication Transaction Sequence Number field. */ -+ /* WLAN_SET_FIELD_16(&prAuthFrame->u2AuthTransSeqNo, u2TransactionSeqNum); */ -+ prAuthFrame->u2AuthTransSeqNo = u2TransactionSeqNum; /* NOTE(Kevin): Optimized for ARM */ -+ -+ /* Fill the Status Code field. */ -+ /* WLAN_SET_FIELD_16(&prAuthFrame->u2StatusCode, u2StatusCode); */ -+ prAuthFrame->u2StatusCode = u2StatusCode; /* NOTE(Kevin): Optimized for ARM */ -+ -+} /* end of authComposeAuthFrameHeaderAndFF() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will append Challenge Text IE to the Authentication frame -+* -+* @param[in] prMsduInfo Pointer to the composed MSDU_INFO_T. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID authAddIEChallengeText(IN P_ADAPTER_T prAdapter, IN OUT P_MSDU_INFO_T prMsduInfo) -+{ -+ P_WLAN_AUTH_FRAME_T prAuthFrame; -+ P_STA_RECORD_T prStaRec; -+ UINT_16 u2TransactionSeqNum; -+ -+ ASSERT(prMsduInfo); -+ -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); -+ -+ if (!prStaRec) -+ return; -+ -+ ASSERT(prStaRec); -+ -+ /* For Management, frame header and payload are in a continuous buffer */ -+ prAuthFrame = (P_WLAN_AUTH_FRAME_T) prMsduInfo->prPacket; -+ -+ WLAN_GET_FIELD_16(&prAuthFrame->u2AuthTransSeqNo, &u2TransactionSeqNum) -+ -+ /* Only consider SEQ_3 for Challenge Text */ -+ if ((u2TransactionSeqNum == AUTH_TRANSACTION_SEQ_3) && -+ (prStaRec->ucAuthAlgNum == AUTH_ALGORITHM_NUM_SHARED_KEY) && (prStaRec->prChallengeText != NULL)) { -+ -+ COPY_IE(((ULONG) (prMsduInfo->prPacket) + prMsduInfo->u2FrameLength), (prStaRec->prChallengeText)); -+ -+ prMsduInfo->u2FrameLength += IE_SIZE(prStaRec->prChallengeText); -+ } -+ -+ return; -+ -+} /* end of authAddIEChallengeText() */ -+ -+#if !CFG_SUPPORT_AAA -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will send the Authenticiation frame -+* -+* @param[in] prStaRec Pointer to the STA_RECORD_T -+* @param[in] u2TransactionSeqNum Transaction Sequence Number -+* -+* @retval WLAN_STATUS_RESOURCES No available resource for frame composing. -+* @retval WLAN_STATUS_SUCCESS Successfully send frame to TX Module -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS authSendAuthFrame(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN UINT_16 u2TransactionSeqNum) -+{ -+ P_MSDU_INFO_T prMsduInfo; -+ P_BSS_INFO_T prBssInfo; -+ UINT_16 u2EstimatedFrameLen; -+ UINT_16 u2EstimatedExtraIELen; -+ UINT_16 u2PayloadLen; -+ UINT_32 i; -+ -+ DBGLOG(SAA, LOUD, "Send Auth Frame\n"); -+ -+ ASSERT(prStaRec); -+ -+ /* 4 <1> Allocate a PKT_INFO_T for Authentication Frame */ -+ /* Init with MGMT Header Length + Length of Fixed Fields */ -+ u2EstimatedFrameLen = (MAC_TX_RESERVED_FIELD + -+ WLAN_MAC_MGMT_HEADER_LEN + -+ AUTH_ALGORITHM_NUM_FIELD_LEN + -+ AUTH_TRANSACTION_SEQENCE_NUM_FIELD_LEN + STATUS_CODE_FIELD_LEN); -+ -+ /* + Extra IE Length */ -+ u2EstimatedExtraIELen = 0; -+ -+ for (i = 0; i < sizeof(txAuthIETable) / sizeof(APPEND_IE_ENTRY_T); i++) -+ u2EstimatedExtraIELen += txAuthIETable[i].u2EstimatedIELen; -+ -+ u2EstimatedFrameLen += u2EstimatedExtraIELen; -+ -+ /* Allocate a MSDU_INFO_T */ -+ prMsduInfo = cnmMgtPktAlloc(prAdapter, u2EstimatedFrameLen); -+ if (prMsduInfo == NULL) { -+ DBGLOG(SAA, WARN, "No PKT_INFO_T for sending Auth Frame.\n"); -+ return WLAN_STATUS_RESOURCES; -+ } -+ /* 4 <2> Compose Authentication Request frame header and fixed fields in MSDU_INfO_T. */ -+ ASSERT(prStaRec->ucNetTypeIndex < NETWORK_TYPE_INDEX_NUM); -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]); -+ -+ /* Compose Header and some Fixed Fields */ -+ authComposeAuthFrameHeaderAndFF((PUINT_8) ((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD), -+ prStaRec->aucMacAddr, -+ prBssInfo->aucOwnMacAddr, -+ prStaRec->ucAuthAlgNum, u2TransactionSeqNum, STATUS_CODE_RESERVED); -+ -+ u2PayloadLen = (AUTH_ALGORITHM_NUM_FIELD_LEN + AUTH_TRANSACTION_SEQENCE_NUM_FIELD_LEN + STATUS_CODE_FIELD_LEN); -+ -+ /* 4 <3> Update information of MSDU_INFO_T */ -+ prMsduInfo->eSrc = TX_PACKET_MGMT; -+ prMsduInfo->ucPacketType = HIF_TX_PACKET_TYPE_MGMT; -+ prMsduInfo->ucStaRecIndex = prStaRec->ucIndex; -+ prMsduInfo->ucNetworkType = prStaRec->ucNetTypeIndex; -+ prMsduInfo->ucMacHeaderLength = WLAN_MAC_MGMT_HEADER_LEN; -+ prMsduInfo->fgIs802_1x = FALSE; -+ prMsduInfo->fgIs802_11 = TRUE; -+ prMsduInfo->u2FrameLength = WLAN_MAC_MGMT_HEADER_LEN + u2PayloadLen; -+ prMsduInfo->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter); -+ prMsduInfo->pfTxDoneHandler = saaFsmRunEventTxDone; -+ prMsduInfo->fgIsBasicRate = TRUE; -+ -+ /* 4 <4> Compose IEs in MSDU_INFO_T */ -+ for (i = 0; i < sizeof(txAuthIETable) / sizeof(APPEND_IE_ENTRY_T); i++) { -+ if (txAuthIETable[i].pfnAppendIE) -+ txAuthIETable[i].pfnAppendIE(prAdapter, prMsduInfo); -+ } -+ -+ /* TODO(Kevin): Also release the unused tail room of the composed MMPDU */ -+ -+ /* 4 <6> Inform TXM to send this Authentication frame. */ -+ nicTxEnqueueMsdu(prAdapter, prMsduInfo); -+ -+ return WLAN_STATUS_SUCCESS; -+} /* end of authSendAuthFrame() */ -+ -+#else -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will send the Authenticiation frame -+* -+* @param[in] prStaRec Pointer to the STA_RECORD_T -+* @param[in] u2TransactionSeqNum Transaction Sequence Number -+* -+* @retval WLAN_STATUS_RESOURCES No available resource for frame composing. -+* @retval WLAN_STATUS_SUCCESS Successfully send frame to TX Module -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+authSendAuthFrame(IN P_ADAPTER_T prAdapter, -+ IN P_STA_RECORD_T prStaRec, -+ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, -+ IN P_SW_RFB_T prFalseAuthSwRfb, IN UINT_16 u2TransactionSeqNum, IN UINT_16 u2StatusCode) -+{ -+ PUINT_8 pucReceiveAddr; -+ PUINT_8 pucTransmitAddr; -+ P_MSDU_INFO_T prMsduInfo; -+ P_BSS_INFO_T prBssInfo; -+ /*get from input parameter */ -+ /* ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex = NETWORK_TYPE_AIS_INDEX; */ -+ PFN_TX_DONE_HANDLER pfTxDoneHandler = (PFN_TX_DONE_HANDLER) NULL; -+ UINT_16 u2EstimatedFrameLen; -+ UINT_16 u2EstimatedExtraIELen; -+ UINT_16 u2PayloadLen; -+ UINT_16 ucAuthAlgNum; -+ UINT_32 i; -+ -+ DBGLOG(SAA, LOUD, "Send Auth Frame %d, Status Code = %d\n", u2TransactionSeqNum, u2StatusCode); -+ -+ /* 4 <1> Allocate a PKT_INFO_T for Authentication Frame */ -+ /* Init with MGMT Header Length + Length of Fixed Fields */ -+ u2EstimatedFrameLen = (MAC_TX_RESERVED_FIELD + -+ WLAN_MAC_MGMT_HEADER_LEN + -+ AUTH_ALGORITHM_NUM_FIELD_LEN + -+ AUTH_TRANSACTION_SEQENCE_NUM_FIELD_LEN + STATUS_CODE_FIELD_LEN); -+ -+ /* + Extra IE Length */ -+ u2EstimatedExtraIELen = 0; -+ -+ for (i = 0; i < sizeof(txAuthIETable) / sizeof(APPEND_IE_ENTRY_T); i++) -+ u2EstimatedExtraIELen += txAuthIETable[i].u2EstimatedIELen; -+ -+ u2EstimatedFrameLen += u2EstimatedExtraIELen; -+ -+ /* Allocate a MSDU_INFO_T */ -+ prMsduInfo = cnmMgtPktAlloc(prAdapter, u2EstimatedFrameLen); -+ if (prMsduInfo == NULL) { -+ DBGLOG(SAA, WARN, "No PKT_INFO_T for sending Auth Frame.\n"); -+ return WLAN_STATUS_RESOURCES; -+ } -+ /* 4 <2> Compose Authentication Request frame header and fixed fields in MSDU_INfO_T. */ -+ if (prStaRec) { -+ ASSERT(prStaRec->ucNetTypeIndex < NETWORK_TYPE_INDEX_NUM); -+ -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]); -+ -+ pucTransmitAddr = prBssInfo->aucOwnMacAddr; -+ -+ pucReceiveAddr = prStaRec->aucMacAddr; -+ -+ ucAuthAlgNum = prStaRec->ucAuthAlgNum; -+ -+ switch (u2TransactionSeqNum) { -+ case AUTH_TRANSACTION_SEQ_1: -+ case AUTH_TRANSACTION_SEQ_3: -+ pfTxDoneHandler = saaFsmRunEventTxDone; -+ break; -+ -+ case AUTH_TRANSACTION_SEQ_2: -+ case AUTH_TRANSACTION_SEQ_4: -+ pfTxDoneHandler = aaaFsmRunEventTxDone; -+ break; -+ } -+ -+ } else { /* For Error Status Code */ -+ P_WLAN_AUTH_FRAME_T prFalseAuthFrame; -+ -+ ASSERT(prFalseAuthSwRfb); -+ prFalseAuthFrame = (P_WLAN_AUTH_FRAME_T) prFalseAuthSwRfb->pvHeader; -+ -+ ASSERT(u2StatusCode != STATUS_CODE_SUCCESSFUL); -+ -+ pucTransmitAddr = prFalseAuthFrame->aucDestAddr; -+ -+ pucReceiveAddr = prFalseAuthFrame->aucSrcAddr; -+ -+ ucAuthAlgNum = prFalseAuthFrame->u2AuthAlgNum; -+ -+ u2TransactionSeqNum = (prFalseAuthFrame->u2AuthTransSeqNo + 1); -+ } -+ -+ /* Compose Header and some Fixed Fields */ -+ authComposeAuthFrameHeaderAndFF((PUINT_8) ((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD), -+ pucReceiveAddr, -+ pucTransmitAddr, ucAuthAlgNum, u2TransactionSeqNum, u2StatusCode); -+ -+ u2PayloadLen = (AUTH_ALGORITHM_NUM_FIELD_LEN + AUTH_TRANSACTION_SEQENCE_NUM_FIELD_LEN + STATUS_CODE_FIELD_LEN); -+ -+ /* 4 <3> Update information of MSDU_INFO_T */ -+ prMsduInfo->eSrc = TX_PACKET_MGMT; -+ prMsduInfo->ucPacketType = HIF_TX_PACKET_TYPE_MGMT; -+ if (prStaRec) -+ prMsduInfo->ucStaRecIndex = prStaRec->ucIndex; -+ else -+ prMsduInfo->ucStaRecIndex = STA_REC_INDEX_NOT_FOUND; /* false Auth frame */ -+ prMsduInfo->ucNetworkType = (UINT_8) eNetTypeIndex; -+ prMsduInfo->ucMacHeaderLength = WLAN_MAC_MGMT_HEADER_LEN; -+ prMsduInfo->fgIs802_1x = FALSE; -+ prMsduInfo->fgIs802_11 = TRUE; -+ prMsduInfo->u2FrameLength = WLAN_MAC_MGMT_HEADER_LEN + u2PayloadLen; -+ prMsduInfo->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter); -+ prMsduInfo->pfTxDoneHandler = pfTxDoneHandler; -+ prMsduInfo->fgIsBasicRate = TRUE; -+ -+ /* 4 <4> Compose IEs in MSDU_INFO_T */ -+ for (i = 0; i < sizeof(txAuthIETable) / sizeof(APPEND_IE_ENTRY_T); i++) { -+ if (txAuthIETable[i].pfnAppendIE) -+ txAuthIETable[i].pfnAppendIE(prAdapter, prMsduInfo); -+ } -+ -+ /* TODO(Kevin): Also release the unused tail room of the composed MMPDU */ -+ -+ /* 4 <6> Inform TXM to send this Authentication frame. */ -+ DBGLOG(SAA, INFO, "network: %d Send Auth Frame %d, Status Code = %d seq num %d\n", -+ eNetTypeIndex, u2TransactionSeqNum, u2StatusCode, prMsduInfo->ucTxSeqNum); -+ nicTxEnqueueMsdu(prAdapter, prMsduInfo); -+ -+ return WLAN_STATUS_SUCCESS; -+} /* end of authSendAuthFrame() */ -+ -+#endif /* CFG_SUPPORT_AAA */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will strictly check the TX Authentication frame for SAA/AAA event -+* handling. -+* -+* @param[in] prMsduInfo Pointer of MSDU_INFO_T -+* @param[in] u2TransactionSeqNum Transaction Sequence Number -+* -+* @retval WLAN_STATUS_FAILURE This is not the frame we should handle at current state. -+* @retval WLAN_STATUS_SUCCESS This is the frame we should handle. -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS authCheckTxAuthFrame(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo, IN UINT_16 u2TransactionSeqNum) -+{ -+ P_WLAN_AUTH_FRAME_T prAuthFrame; -+ P_STA_RECORD_T prStaRec; -+ UINT_16 u2TxFrameCtrl; -+ UINT_16 u2TxAuthAlgNum; -+ UINT_16 u2TxTransactionSeqNum; -+ -+ ASSERT(prMsduInfo); -+ -+ prAuthFrame = (P_WLAN_AUTH_FRAME_T) (prMsduInfo->prPacket); -+ ASSERT(prAuthFrame); -+ -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); -+ ASSERT(prStaRec); -+ -+ if (!prStaRec) -+ return WLAN_STATUS_INVALID_PACKET; -+ /* WLAN_GET_FIELD_16(&prAuthFrame->u2FrameCtrl, &u2TxFrameCtrl) */ -+ u2TxFrameCtrl = prAuthFrame->u2FrameCtrl; /* NOTE(Kevin): Optimized for ARM */ -+ u2TxFrameCtrl &= MASK_FRAME_TYPE; -+ if (u2TxFrameCtrl != MAC_FRAME_AUTH) -+ return WLAN_STATUS_FAILURE; -+ /* WLAN_GET_FIELD_16(&prAuthFrame->u2AuthAlgNum, &u2TxAuthAlgNum) */ -+ u2TxAuthAlgNum = prAuthFrame->u2AuthAlgNum; /* NOTE(Kevin): Optimized for ARM */ -+ if (u2TxAuthAlgNum != (UINT_16) (prStaRec->ucAuthAlgNum)) -+ return WLAN_STATUS_FAILURE; -+ /* WLAN_GET_FIELD_16(&prAuthFrame->u2AuthTransSeqNo, &u2TxTransactionSeqNum) */ -+ u2TxTransactionSeqNum = prAuthFrame->u2AuthTransSeqNo; /* NOTE(Kevin): Optimized for ARM */ -+ if (u2TxTransactionSeqNum != u2TransactionSeqNum) -+ return WLAN_STATUS_FAILURE; -+ -+ return WLAN_STATUS_SUCCESS; -+ -+} /* end of authCheckTxAuthFrame() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will check the incoming Auth Frame's Transaction Sequence -+* Number before delivering it to the corresponding SAA or AAA Module. -+* -+* @param[in] prSwRfb Pointer to the SW_RFB_T structure. -+* -+* @retval WLAN_STATUS_SUCCESS Always not retain authentication frames -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS authCheckRxAuthFrameTransSeq(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb) -+{ -+ P_WLAN_AUTH_FRAME_T prAuthFrame; -+ UINT_16 u2RxTransactionSeqNum; -+ -+ ASSERT(prSwRfb); -+ -+ /* 4 <1> locate the Authentication Frame. */ -+ prAuthFrame = (P_WLAN_AUTH_FRAME_T) prSwRfb->pvHeader; -+ -+ /* 4 <2> Parse the Header of Authentication Frame. */ -+ if ((prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen) < (AUTH_ALGORITHM_NUM_FIELD_LEN + -+ AUTH_TRANSACTION_SEQENCE_NUM_FIELD_LEN + -+ STATUS_CODE_FIELD_LEN)) { -+ ASSERT(0); -+ return WLAN_STATUS_SUCCESS; -+ } -+ /* 4 <3> Parse the Fixed Fields of Authentication Frame Body. */ -+ /* WLAN_GET_FIELD_16(&prAuthFrame->u2AuthTransSeqNo, &u2RxTransactionSeqNum); */ -+ u2RxTransactionSeqNum = prAuthFrame->u2AuthTransSeqNo; /* NOTE(Kevin): Optimized for ARM */ -+ -+ switch (u2RxTransactionSeqNum) { -+ case AUTH_TRANSACTION_SEQ_2: -+ case AUTH_TRANSACTION_SEQ_4: -+ saaFsmRunEventRxAuth(prAdapter, prSwRfb); -+ break; -+ -+ case AUTH_TRANSACTION_SEQ_1: -+ case AUTH_TRANSACTION_SEQ_3: -+#if CFG_SUPPORT_AAA -+ aaaFsmRunEventRxAuth(prAdapter, prSwRfb); -+#endif /* CFG_SUPPORT_AAA */ -+ break; -+ -+ default: -+ DBGLOG(SAA, WARN, "Strange Authentication Packet: Auth Trans Seq No = %d, Error Status Code = %d\n", -+ u2RxTransactionSeqNum, prAuthFrame->u2StatusCode); -+ break; -+ } -+ -+ return WLAN_STATUS_SUCCESS; -+ -+} /* end of authCheckRxAuthFrameTransSeq() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will validate the incoming Authentication Frame and take -+* the status code out. -+* -+* @param[in] prSwRfb Pointer to SW RFB data structure. -+* @param[in] u2TransactionSeqNum Transaction Sequence Number -+* @param[out] pu2StatusCode Pointer to store the Status Code from Authentication. -+* -+* @retval WLAN_STATUS_FAILURE This is not the frame we should handle at current state. -+* @retval WLAN_STATUS_SUCCESS This is the frame we should handle. -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+authCheckRxAuthFrameStatus(IN P_ADAPTER_T prAdapter, -+ IN P_SW_RFB_T prSwRfb, IN UINT_16 u2TransactionSeqNum, OUT PUINT_16 pu2StatusCode) -+{ -+ P_STA_RECORD_T prStaRec; -+ P_WLAN_AUTH_FRAME_T prAuthFrame; -+ UINT_16 u2RxAuthAlgNum; -+ UINT_16 u2RxTransactionSeqNum; -+ /* UINT_16 u2RxStatusCode; // NOTE(Kevin): Optimized for ARM */ -+ -+ ASSERT(prSwRfb); -+ ASSERT(pu2StatusCode); -+ -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); -+ ASSERT(prStaRec); -+ -+ if (!prStaRec) -+ return WLAN_STATUS_INVALID_PACKET; -+ /* 4 <1> locate the Authentication Frame. */ -+ prAuthFrame = (P_WLAN_AUTH_FRAME_T) prSwRfb->pvHeader; -+ -+ /* 4 <2> Parse the Fixed Fields of Authentication Frame Body. */ -+ /* WLAN_GET_FIELD_16(&prAuthFrame->u2AuthAlgNum, &u2RxAuthAlgNum); */ -+ u2RxAuthAlgNum = prAuthFrame->u2AuthAlgNum; /* NOTE(Kevin): Optimized for ARM */ -+ if (u2RxAuthAlgNum != (UINT_16) prStaRec->ucAuthAlgNum) { -+ DBGLOG(SAA, WARN, "Discard Auth frame with auth type = %d, current = %d\n", -+ u2RxAuthAlgNum, prStaRec->ucAuthAlgNum); -+ *pu2StatusCode = STATUS_CODE_AUTH_ALGORITHM_NOT_SUPPORTED; -+ return WLAN_STATUS_SUCCESS; -+ } -+ /* WLAN_GET_FIELD_16(&prAuthFrame->u2AuthTransSeqNo, &u2RxTransactionSeqNum); */ -+ u2RxTransactionSeqNum = prAuthFrame->u2AuthTransSeqNo; /* NOTE(Kevin): Optimized for ARM */ -+ if (u2RxTransactionSeqNum != u2TransactionSeqNum) { -+ DBGLOG(SAA, WARN, "Discard Auth frame with Transaction Seq No = %d\n", u2RxTransactionSeqNum); -+ *pu2StatusCode = STATUS_CODE_AUTH_OUT_OF_SEQ; -+ return WLAN_STATUS_SUCCESS; -+ } -+ /* 4 <3> Get the Status code */ -+ /* WLAN_GET_FIELD_16(&prAuthFrame->u2StatusCode, &u2RxStatusCode); */ -+ /* *pu2StatusCode = u2RxStatusCode; */ -+ *pu2StatusCode = prAuthFrame->u2StatusCode; /* NOTE(Kevin): Optimized for ARM */ -+ -+ return WLAN_STATUS_SUCCESS; -+ -+} /* end of authCheckRxAuthFrameStatus() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will handle the Challenge Text IE from the Authentication frame -+* -+* @param[in] prSwRfb Pointer to SW RFB data structure. -+* @param[in] prIEHdr Pointer to start address of IE -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID authHandleIEChallengeText(P_ADAPTER_T prAdapter, P_SW_RFB_T prSwRfb, P_IE_HDR_T prIEHdr) -+{ -+ P_WLAN_AUTH_FRAME_T prAuthFrame; -+ P_STA_RECORD_T prStaRec; -+ UINT_16 u2TransactionSeqNum; -+ -+ ASSERT(prSwRfb); -+ ASSERT(prIEHdr); -+ -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); -+ ASSERT(prStaRec); -+ -+ if (!prStaRec) -+ return; -+ -+ /* For Management, frame header and payload are in a continuous buffer */ -+ prAuthFrame = (P_WLAN_AUTH_FRAME_T) prSwRfb->pvHeader; -+ -+ /* WLAN_GET_FIELD_16(&prAuthFrame->u2AuthTransSeqNo, &u2TransactionSeqNum) */ -+ u2TransactionSeqNum = prAuthFrame->u2AuthTransSeqNo; /* NOTE(Kevin): Optimized for ARM */ -+ -+ /* Only consider SEQ_2 for Challenge Text */ -+ if ((u2TransactionSeqNum == AUTH_TRANSACTION_SEQ_2) && -+ (prStaRec->ucAuthAlgNum == AUTH_ALGORITHM_NUM_SHARED_KEY)) { -+ -+ /* Free previous allocated TCM memory */ -+ if (prStaRec->prChallengeText) { -+ ASSERT(0); -+ cnmMemFree(prAdapter, prStaRec->prChallengeText); -+ prStaRec->prChallengeText = (P_IE_CHALLENGE_TEXT_T) NULL; -+ } -+ -+ prStaRec->prChallengeText = cnmMemAlloc(prAdapter, RAM_TYPE_MSG, IE_SIZE(prIEHdr)); -+ if (prStaRec->prChallengeText == NULL) -+ return; -+ -+ /* Save the Challenge Text from Auth Seq 2 Frame, before sending Auth Seq 3 Frame */ -+ COPY_IE(prStaRec->prChallengeText, prIEHdr); -+ } -+ -+ return; -+ -+} /* end of authAddIEChallengeText() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will parse and process the incoming Authentication frame. -+* -+* @param[in] prSwRfb Pointer to SW RFB data structure. -+* -+* @retval WLAN_STATUS_SUCCESS This is the frame we should handle. -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS authProcessRxAuth2_Auth4Frame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb) -+{ -+ P_WLAN_AUTH_FRAME_T prAuthFrame; -+ PUINT_8 pucIEsBuffer; -+ UINT_16 u2IEsLen; -+ UINT_16 u2Offset; -+ UINT_8 ucIEID; -+ UINT_32 i; -+ -+ ASSERT(prSwRfb); -+ -+ prAuthFrame = (P_WLAN_AUTH_FRAME_T) prSwRfb->pvHeader; -+ -+ pucIEsBuffer = &prAuthFrame->aucInfoElem[0]; -+ u2IEsLen = (prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen) - -+ (AUTH_ALGORITHM_NUM_FIELD_LEN + AUTH_TRANSACTION_SEQENCE_NUM_FIELD_LEN + STATUS_CODE_FIELD_LEN); -+ -+ IE_FOR_EACH(pucIEsBuffer, u2IEsLen, u2Offset) { -+ ucIEID = IE_ID(pucIEsBuffer); -+ -+ for (i = 0; i < (sizeof(rxAuthIETable) / sizeof(HANDLE_IE_ENTRY_T)); i++) { -+ -+ if (ucIEID == rxAuthIETable[i].ucElemID) -+ rxAuthIETable[i].pfnHandleIE(prAdapter, prSwRfb, (P_IE_HDR_T) pucIEsBuffer); -+ } -+ } -+ -+ return WLAN_STATUS_SUCCESS; -+ -+} /* end of authProcessRxAuth2_Auth4Frame() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will compose the Deauthentication frame -+* -+* @param[in] pucBuffer Pointer to the frame buffer. -+* @param[in] aucPeerMACAddress Given Peer MAC Address. -+* @param[in] aucMACAddress Given Our MAC Address. -+* @param[in] u2StatusCode Status Code -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+static inline VOID -+authComposeDeauthFrameHeaderAndFF(IN PUINT_8 pucBuffer, -+ IN UINT_8 aucPeerMACAddress[], -+ IN UINT_8 aucMACAddress[], IN UINT_8 aucBssid[], IN UINT_16 u2ReasonCode) -+{ -+ P_WLAN_DEAUTH_FRAME_T prDeauthFrame; -+ UINT_16 u2FrameCtrl; -+ -+ ASSERT(pucBuffer); -+ ASSERT(aucPeerMACAddress); -+ ASSERT(aucMACAddress); -+ ASSERT(aucBssid); -+ -+ prDeauthFrame = (P_WLAN_DEAUTH_FRAME_T) pucBuffer; -+ -+ /* 4 <1> Compose the frame header of the Deauthentication frame. */ -+ /* Fill the Frame Control field. */ -+ u2FrameCtrl = MAC_FRAME_DEAUTH; -+ -+ /* WLAN_SET_FIELD_16(&prDeauthFrame->u2FrameCtrl, u2FrameCtrl); */ -+ prDeauthFrame->u2FrameCtrl = u2FrameCtrl; /* NOTE(Kevin): Optimized for ARM */ -+ -+ /* Fill the DA field with Target BSSID. */ -+ COPY_MAC_ADDR(prDeauthFrame->aucDestAddr, aucPeerMACAddress); -+ -+ /* Fill the SA field with our MAC Address. */ -+ COPY_MAC_ADDR(prDeauthFrame->aucSrcAddr, aucMACAddress); -+ -+ /* Fill the BSSID field with Target BSSID. */ -+ COPY_MAC_ADDR(prDeauthFrame->aucBSSID, aucBssid); -+ -+ /* Clear the SEQ/FRAG_NO field(HW won't overide the FRAG_NO, so we need to clear it). */ -+ prDeauthFrame->u2SeqCtrl = 0; -+ -+ /* 4 <2> Compose the frame body's fixed field part of the Authentication frame. */ -+ /* Fill the Status Code field. */ -+ /* WLAN_SET_FIELD_16(&prDeauthFrame->u2ReasonCode, u2ReasonCode); */ -+ prDeauthFrame->u2ReasonCode = u2ReasonCode; /* NOTE(Kevin): Optimized for ARM */ -+ -+} /* end of authComposeDeauthFrameHeaderAndFF() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will send the Deauthenticiation frame -+* -+* @param[in] prStaRec Pointer to the STA_RECORD_T -+* @param[in] prClassErrSwRfb Pointer to the SW_RFB_T which is Class Error. -+* @param[in] u2ReasonCode A reason code to indicate why to leave BSS. -+* @param[in] pfTxDoneHandler TX Done call back function -+* -+* @retval WLAN_STATUS_RESOURCES No available resource for frame composing. -+* @retval WLAN_STATUS_SUCCESS Successfully send frame to TX Module -+* @retval WLAN_STATUS_FAILURE Didn't send Deauth frame for various reasons. -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+authSendDeauthFrame(IN P_ADAPTER_T prAdapter, -+ IN P_STA_RECORD_T prStaRec, -+ IN P_SW_RFB_T prClassErrSwRfb, IN UINT_16 u2ReasonCode, IN PFN_TX_DONE_HANDLER pfTxDoneHandler) -+{ -+ P_WLAN_MAC_HEADER_A4_T prWlanMacHeader = NULL; -+ PUINT_8 pucReceiveAddr; -+ PUINT_8 pucTransmitAddr; -+ PUINT_8 pucBssid = NULL; -+ -+ ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex = NETWORK_TYPE_AIS_INDEX; -+ P_MSDU_INFO_T prMsduInfo; -+ UINT_16 u2EstimatedFrameLen; -+ UINT_16 u2RxFrameCtrl; -+ P_BSS_INFO_T prBssInfo; -+ -+ P_DEAUTH_INFO_T prDeauthInfo; -+ OS_SYSTIME rCurrentTime; -+ INT_32 i4NewEntryIndex, i; -+ UINT_8 ucStaRecIdx = STA_REC_INDEX_NOT_FOUND; -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ UINT_8 aucBMC[] = BC_MAC_ADDR; -+#endif -+ -+ /* NOTE(Kevin): The best way to reply the Deauth is according to the incoming data -+ * frame -+ */ -+ /* 4 <1> Find the Receiver Address first. */ -+ if (prClassErrSwRfb) { -+ BOOLEAN fgIsAbleToSendDeauth = FALSE; -+ -+ prWlanMacHeader = (P_WLAN_MAC_HEADER_A4_T) prClassErrSwRfb->pvHeader; -+ -+ /* WLAN_GET_FIELD_16(&prWlanMacHeader->u2FrameCtrl, &u2RxFrameCtrl); */ -+ u2RxFrameCtrl = prWlanMacHeader->u2FrameCtrl; /* NOTE(Kevin): Optimized for ARM */ -+ -+ /* TODO(Kevin): Currently we won't send Deauth for IBSS node. How about DLS ? */ -+ if ((prWlanMacHeader->u2FrameCtrl & MASK_TO_DS_FROM_DS) == 0) -+ return WLAN_STATUS_FAILURE; -+ -+ /* Check if corresponding BSS is able to send Deauth */ -+ for (i = NETWORK_TYPE_AIS_INDEX; i < NETWORK_TYPE_INDEX_NUM; i++) { -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[i]); -+ -+ if (IS_NET_ACTIVE(prAdapter, i) && -+ (EQUAL_MAC_ADDR(prWlanMacHeader->aucAddr1, prBssInfo->aucOwnMacAddr))) { -+ { -+ fgIsAbleToSendDeauth = TRUE; -+ eNetTypeIndex = (ENUM_NETWORK_TYPE_INDEX_T) i; -+ break; -+ } -+ } -+ } -+ -+ if (!fgIsAbleToSendDeauth) -+ return WLAN_STATUS_FAILURE; -+ -+ pucReceiveAddr = prWlanMacHeader->aucAddr2; -+ -+ } else if (prStaRec) { -+ -+ pucReceiveAddr = prStaRec->aucMacAddr; -+ } else { -+#if CFG_ENABLE_WIFI_DIRECT -+ pucReceiveAddr = aucBMC; -+#else -+ return WLAN_STATUS_FAILURE; -+#endif -+ } -+ -+ /* 4 <2> Check if already send a Deauth frame in MIN_DEAUTH_INTERVAL_MSEC */ -+ GET_CURRENT_SYSTIME(&rCurrentTime); -+ -+ i4NewEntryIndex = -1; -+ for (i = 0; i < MAX_DEAUTH_INFO_COUNT; i++) { -+ prDeauthInfo = &(prAdapter->rWifiVar.arDeauthInfo[i]); -+ -+ /* For continuously sending Deauth frame, the minimum interval is -+ * MIN_DEAUTH_INTERVAL_MSEC. -+ */ -+ if (CHECK_FOR_TIMEOUT(rCurrentTime, -+ prDeauthInfo->rLastSendTime, MSEC_TO_SYSTIME(MIN_DEAUTH_INTERVAL_MSEC))) { -+ -+ i4NewEntryIndex = i; -+ } else if (EQUAL_MAC_ADDR(pucReceiveAddr, prDeauthInfo->aucRxAddr) && (!pfTxDoneHandler)) { -+ -+ return WLAN_STATUS_FAILURE; -+ } -+ } -+ -+ /* 4 <3> Update information. */ -+ if (i4NewEntryIndex > 0) { -+ -+ prDeauthInfo = &(prAdapter->rWifiVar.arDeauthInfo[i4NewEntryIndex]); -+ -+ COPY_MAC_ADDR(prDeauthInfo->aucRxAddr, pucReceiveAddr); -+ prDeauthInfo->rLastSendTime = rCurrentTime; -+ } else { -+ /* NOTE(Kevin): for the case of AP mode, we may encounter this case -+ * if deauth all the associated clients. -+ */ -+ DBGLOG(SAA, WARN, "No unused DEAUTH_INFO_T !\n"); -+ } -+ -+ /* 4 <4> Allocate a PKT_INFO_T for Deauthentication Frame */ -+ /* Init with MGMT Header Length + Length of Fixed Fields + IE Length */ -+ u2EstimatedFrameLen = (MAC_TX_RESERVED_FIELD + WLAN_MAC_MGMT_HEADER_LEN + REASON_CODE_FIELD_LEN); -+ -+ /* Allocate a MSDU_INFO_T */ -+ prMsduInfo = cnmMgtPktAlloc(prAdapter, u2EstimatedFrameLen); -+ if (prMsduInfo == NULL) { -+ DBGLOG(SAA, WARN, "No PKT_INFO_T for sending Deauth Request.\n"); -+ return WLAN_STATUS_RESOURCES; -+ } -+ /* 4 <5> Find the Transmitter Address and BSSID. */ -+ if (prClassErrSwRfb) { -+ -+ /* The TA of Deauth is the A1 of RX frame */ -+ pucTransmitAddr = prWlanMacHeader->aucAddr1; -+ -+ switch (prWlanMacHeader->u2FrameCtrl & MASK_TO_DS_FROM_DS) { -+ -+ case MASK_FC_FROM_DS: -+ /* The BSSID of Deauth is the A2 of RX frame */ -+ pucBssid = prWlanMacHeader->aucAddr2; -+ break; -+ -+ case MASK_FC_TO_DS: -+ /* The BSSID of Deauth is the A1 of RX frame */ -+ pucBssid = prWlanMacHeader->aucAddr1; -+ break; -+ -+ case MASK_TO_DS_FROM_DS: -+ /* TODO(Kevin): Consider BOW, now we set the BSSID of Deauth -+ * to the A2 of RX frame for temporary solution. -+ */ -+ pucBssid = prWlanMacHeader->aucAddr2; -+ break; -+ -+ /* No Default */ -+ } -+ -+ } else if (prStaRec) { -+ eNetTypeIndex = prStaRec->ucNetTypeIndex; -+ -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[eNetTypeIndex]); -+ -+ pucTransmitAddr = prBssInfo->aucOwnMacAddr; -+ -+ pucBssid = prBssInfo->aucBSSID; -+ } -+#if CFG_ENABLE_WIFI_DIRECT -+ else { -+ if (prAdapter->fgIsP2PRegistered) { -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); -+ -+ ucStaRecIdx = STA_REC_INDEX_BMCAST; -+ -+ pucTransmitAddr = prBssInfo->aucOwnMacAddr; -+ -+ pucBssid = prBssInfo->aucBSSID; -+ -+ eNetTypeIndex = NETWORK_TYPE_P2P_INDEX; -+ } else { -+ /* 20130122: free packet by samplin */ -+ cnmMgtPktFree(prAdapter, prMsduInfo); -+ return WLAN_STATUS_FAILURE; -+ } -+ } -+ -+#endif -+ -+ /* 4 <6> compose Deauthentication frame header and some fixed fields */ -+ authComposeDeauthFrameHeaderAndFF((PUINT_8) ((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD), -+ pucReceiveAddr, pucTransmitAddr, pucBssid, u2ReasonCode); -+ -+#if CFG_SUPPORT_802_11W -+ if (rsnCheckBipKeyInstalled(prAdapter, prStaRec)) { -+ P_WLAN_DEAUTH_FRAME_T prDeauthFrame; -+ -+ prDeauthFrame = -+ (P_WLAN_DEAUTH_FRAME_T) (PUINT_8) ((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD); -+ -+ prDeauthFrame->u2FrameCtrl |= MASK_FC_PROTECTED_FRAME; -+ DBGLOG(TX, WARN, "authSendDeauthFrame with protection\n"); -+ } -+#endif -+ -+ /* 4 <7> Update information of MSDU_INFO_T */ -+ prMsduInfo->eSrc = TX_PACKET_MGMT; -+ prMsduInfo->ucPacketType = HIF_TX_PACKET_TYPE_MGMT; -+ prMsduInfo->ucStaRecIndex = ((prStaRec == NULL) ? ucStaRecIdx : prStaRec->ucIndex); -+ prMsduInfo->ucNetworkType = (UINT_8) eNetTypeIndex; -+ prMsduInfo->ucMacHeaderLength = WLAN_MAC_MGMT_HEADER_LEN; -+ prMsduInfo->fgIs802_1x = FALSE; -+ prMsduInfo->fgIs802_11 = TRUE; -+ prMsduInfo->u2FrameLength = WLAN_MAC_MGMT_HEADER_LEN + REASON_CODE_FIELD_LEN; -+ prMsduInfo->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter); -+ prMsduInfo->pfTxDoneHandler = pfTxDoneHandler; -+ prMsduInfo->fgIsBasicRate = TRUE; -+ DBGLOG(SAA, INFO, "Sending Deauth, network: %d, seqNo %d\n", -+ eNetTypeIndex, prMsduInfo->ucTxSeqNum); -+ -+ /* 4 <8> Inform TXM to send this Deauthentication frame. */ -+ nicTxEnqueueMsdu(prAdapter, prMsduInfo); -+ -+ return WLAN_STATUS_SUCCESS; -+} /* end of authSendDeauthFrame() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will parse and process the incoming Deauthentication frame -+* if the given BSSID is matched. -+* -+* @param[in] prSwRfb Pointer to SW RFB data structure. -+* @param[in] aucBSSID Given BSSID -+* @param[out] pu2ReasonCode Pointer to store the Reason Code from Deauthentication. -+* -+* @retval WLAN_STATUS_FAILURE This is not the frame we should handle at current state. -+* @retval WLAN_STATUS_SUCCESS This is the frame we should handle. -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS authProcessRxDeauthFrame(IN P_SW_RFB_T prSwRfb, IN UINT_8 aucBSSID[], OUT PUINT_16 pu2ReasonCode) -+{ -+ P_WLAN_DEAUTH_FRAME_T prDeauthFrame; -+ UINT_16 u2RxReasonCode; -+ -+ ASSERT(prSwRfb); -+ ASSERT(aucBSSID); -+ ASSERT(pu2ReasonCode); -+ -+ /* 4 <1> locate the Deauthentication Frame. */ -+ prDeauthFrame = (P_WLAN_DEAUTH_FRAME_T) prSwRfb->pvHeader; -+ -+ /* 4 <2> Parse the Header of Deauthentication Frame. */ -+#if 0 /* Kevin: Seems redundant */ -+ WLAN_GET_FIELD_16(&prDeauthFrame->u2FrameCtrl, &u2RxFrameCtrl) -+ u2RxFrameCtrl &= MASK_FRAME_TYPE; -+ if (u2RxFrameCtrl != MAC_FRAME_DEAUTH) -+ return WLAN_STATUS_FAILURE; -+#endif -+ -+ if ((prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen) < REASON_CODE_FIELD_LEN) { -+ ASSERT(0); -+ return WLAN_STATUS_FAILURE; -+ } -+ -+ /* Check if this Deauth Frame is coming from Target BSSID */ -+ if (UNEQUAL_MAC_ADDR(prDeauthFrame->aucBSSID, aucBSSID)) { -+ DBGLOG(SAA, LOUD, "Ignore Deauth Frame from other BSS [ %pM ]\n", -+ prDeauthFrame->aucSrcAddr); -+ return WLAN_STATUS_FAILURE; -+ } -+ /* 4 <3> Parse the Fixed Fields of Deauthentication Frame Body. */ -+ WLAN_GET_FIELD_16(&prDeauthFrame->u2ReasonCode, &u2RxReasonCode); -+ *pu2ReasonCode = u2RxReasonCode; -+ -+ return WLAN_STATUS_SUCCESS; -+ -+} /* end of authProcessRxDeauthFrame() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will parse and process the incoming Authentication frame. -+* -+* @param[in] prSwRfb Pointer to SW RFB data structure. -+* @param[in] aucExpectedBSSID Given Expected BSSID. -+* @param[in] u2ExpectedAuthAlgNum Given Expected Authentication Algorithm Number -+* @param[in] u2ExpectedTransSeqNum Given Expected Transaction Sequence Number. -+* @param[out] pu2ReturnStatusCode Return Status Code. -+* -+* @retval WLAN_STATUS_SUCCESS This is the frame we should handle. -+* @retval WLAN_STATUS_FAILURE The frame we will ignore. -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+authProcessRxAuth1Frame(IN P_ADAPTER_T prAdapter, -+ IN P_SW_RFB_T prSwRfb, -+ IN UINT_8 aucExpectedBSSID[], -+ IN UINT_16 u2ExpectedAuthAlgNum, -+ IN UINT_16 u2ExpectedTransSeqNum, OUT PUINT_16 pu2ReturnStatusCode) -+{ -+ P_WLAN_AUTH_FRAME_T prAuthFrame; -+ UINT_16 u2ReturnStatusCode = STATUS_CODE_SUCCESSFUL; -+ -+ ASSERT(prSwRfb); -+ ASSERT(aucExpectedBSSID); -+ ASSERT(pu2ReturnStatusCode); -+ -+ /* 4 <1> locate the Authentication Frame. */ -+ prAuthFrame = (P_WLAN_AUTH_FRAME_T) prSwRfb->pvHeader; -+ -+ /* 4 <2> Check the BSSID */ -+ if (UNEQUAL_MAC_ADDR(prAuthFrame->aucBSSID, aucExpectedBSSID)) -+ return WLAN_STATUS_FAILURE; /* Just Ignore this MMPDU */ -+ /* 4 <3> Check the SA, which should not be MC/BC */ -+ if (prAuthFrame->aucSrcAddr[0] & BIT(0)) { -+ DBGLOG(P2P, WARN, "Invalid STA MAC with MC/BC bit set: %pM\n", -+ prAuthFrame->aucSrcAddr); -+ return WLAN_STATUS_FAILURE; -+ } -+ /* 4 <4> Parse the Fixed Fields of Authentication Frame Body. */ -+ if (prAuthFrame->u2AuthAlgNum != u2ExpectedAuthAlgNum) -+ u2ReturnStatusCode = STATUS_CODE_AUTH_ALGORITHM_NOT_SUPPORTED; -+ -+ if (prAuthFrame->u2AuthTransSeqNo != u2ExpectedTransSeqNum) -+ u2ReturnStatusCode = STATUS_CODE_AUTH_OUT_OF_SEQ; -+ -+ *pu2ReturnStatusCode = u2ReturnStatusCode; -+ -+ return WLAN_STATUS_SUCCESS; -+ -+} /* end of authProcessRxAuth1Frame() */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/bss.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/bss.c -new file mode 100644 -index 000000000000..160779583655 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/bss.c -@@ -0,0 +1,2521 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/bss.c#3 -+*/ -+ -+/*! \file "bss.c" -+ \brief This file contains the functions for creating BSS(AP)/IBSS(AdHoc). -+ -+ This file contains the functions for BSS(AP)/IBSS(AdHoc). We may create a BSS/IBSS -+ network, or merge with exist IBSS network and sending Beacon Frame or reply -+ the Probe Response Frame for received Probe Request Frame. -+*/ -+ -+/* -+** Log: bss.c -+** -+** 09 03 2013 cp.wu -+** add path for reassociation -+** -+** 08 30 2012 chinglan.wang -+** [ALPS00349664] [6577JB][WIFI] Phone can not connect to AP secured with AES via WPS in 802.11n Only -+** . -+** -+** 07 26 2012 yuche.tsai -+** [ALPS00324337] [ALPS.JB][Hot-Spot] Driver update for Hot-Spot -+** Update driver code of ALPS.JB for hot-spot. -+ * -+ * 07 17 2012 yuche.tsai -+ * NULL -+ * Let netdev bring up. -+ * -+ * 07 17 2012 yuche.tsai -+ * NULL -+ * Compile no error before trial run. -+ * -+ * 06 14 2012 chinglan.wang -+ * NULL -+ * Fix the losing of the HT IE in assoc request.. -+ * -+ * 06 13 2012 yuche.tsai -+ * NULL -+ * Update maintrunk driver. -+ * Add support for driver compose assoc request frame. -+ * -+ * 03 08 2012 yuche.tsai -+ * NULL -+ * Fix FW assert when start Hot-Spot. -+ * -+ * 03 02 2012 terry.wu -+ * NULL -+ * Snc CFG80211 modification for ICS migration from branch 2.2. -+ * -+ * 01 20 2012 chinglan.wang -+ * 03 02 2012 terry.wu -+ * NULL -+ * Fix the WPA-PSK TKIP and WPA2-PSK AES security mode bug. -+ * -+ * NULL -+ * Sync CFG80211 modification from branch 2,2. -+ * -+ * 01 15 2012 yuche.tsai -+ * NULL -+ * Fix wrong basic rate issue. -+ * -+ * 01 13 2012 yuche.tsai -+ * NULL -+ * WiFi Hot Spot Tethering for ICS ALPHA testing version. -+ * -+ * 11 03 2011 cm.chang -+ * [WCXRP00000997] [MT6620 Wi-Fi][Driver][FW] Handle change of BSS preamble type and slot time -+ * Always set short slot time to TRUE initially in AP mode -+ * -+ * 11 03 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * change the DBGLOG for "\n" and "\r\n". LABEL to LOUD for XLOG -+ * -+ * 09 14 2011 yuche.tsai -+ * NULL -+ * Add P2P IE in assoc response. -+ * -+ * 04 18 2011 terry.wu -+ * [WCXRP00000660] [MT6620 Wi-Fi][Driver] Remove flag CFG_WIFI_DIRECT_MOVED -+ * Remove flag CFG_WIFI_DIRECT_MOVED. -+ * -+ * 04 12 2011 eddie.chen -+ * [WCXRP00000617] [MT6620 Wi-Fi][DRV/FW] Fix for sigma -+ * Fix the sta index in processing security frame -+ * Simple flow control for TC4 to avoid mgt frames for PS STA to occupy the TC4 -+ * Add debug message. -+ * -+ * 04 08 2011 eddie.chen -+ * [WCXRP00000617] [MT6620 Wi-Fi][DRV/FW] Fix for sigma -+ * Fix for sigma -+ * -+ * 03 29 2011 eddie.chen -+ * [WCXRP00000608] [MT6620 Wi-Fi][DRV] Change wmm parameters in beacon -+ * Change wmm parameters in beacon. -+ * -+ * 03 29 2011 yuche.tsai -+ * [WCXRP00000607] [Volunteer Patch][MT6620][Driver] Coding Style Fix for klocwork scan. -+ * Fix klocwork issue. -+ * -+ * 03 19 2011 yuche.tsai -+ * [WCXRP00000581] [Volunteer Patch][MT6620][Driver] P2P IE in Assoc Req Issue -+ * Make assoc req to append P2P IE if wifi direct is enabled. -+ * -+ * 03 11 2011 chinglan.wang -+ * [WCXRP00000537] [MT6620 Wi-Fi][Driver] Can not connect to 802.11b/g/n mixed AP with WEP security. -+ * . -+ * -+ * 03 03 2011 george.huang -+ * [WCXRP00000508] [MT6620 Wi-Fi][Driver] aware of beacon MSDU will be free, after BSS deactivated -+ * . -+ * -+ * 03 03 2011 george.huang -+ * [WCXRP00000508] [MT6620 Wi-Fi][Driver] aware of beacon MSDU will be free, after BSS deactivated -+ * modify to handle if beacon MSDU been released when BSS deactivated -+ * -+ * 03 02 2011 wh.su -+ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code -+ * add code to let the beacon and probe response for Auto GO WSC . -+ * -+ * 03 02 2011 wh.su -+ * [WCXRP00000448] [MT6620 Wi-Fi][Driver] Fixed WSC IE not send out at probe request -+ * Add code to send beacon and probe response WSC IE at Auto GO. -+ * -+ * 02 17 2011 eddie.chen -+ * [WCXRP00000458] [MT6620 Wi-Fi][Driver] BOW Concurrent - ProbeResp was exist in other channel -+ * 1) Change GetFrameAction decision when BSS is absent. -+ * 2) Check channel and resource in processing ProbeRequest -+ * -+ * 02 12 2011 yuche.tsai -+ * [WCXRP00000441] [Volunteer Patch][MT6620][Driver] BoW can not create desired station type when Hot Spot is enabled. -+ * bss should create station record type according to callers input. -+ * -+ * 02 11 2011 terry.wu -+ * [WCXRP00000383] [MT6620 Wi-Fi][Driver] Separate WiFi and P2P driver into two modules -+ * In p2p link function, check networktype before calling p2p function. -+ * -+ * 02 11 2011 terry.wu -+ * [WCXRP00000383] [MT6620 Wi-Fi][Driver] Separate WiFi and P2P driver into two modules -+ * Modify p2p link function to avoid assert. -+ * -+ * 01 26 2011 cm.chang -+ * [WCXRP00000395] [MT6620 Wi-Fi][Driver][FW] Search STA_REC with additional net type index argument -+ * . -+ * -+ * 01 25 2011 yuche.tsai -+ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record. -+ * Change Station Type in Station Record, Modify MACRO definition for getting station type & network type index & Role. -+ * -+ * 01 25 2011 eddie.chen -+ * [WCXRP00000385] [MT6620 Wi-Fi][DRV] Add destination decision for forwarding packets -+ * Fix the compile error in windows. -+ * -+ * 01 24 2011 eddie.chen -+ * [WCXRP00000385] [MT6620 Wi-Fi][DRV] Add destination decision for forwarding packets -+ * Add destination decision in AP mode. -+ * -+ * 01 24 2011 terry.wu -+ * [WCXRP00000383] [MT6620 Wi-Fi][Driver] Separate WiFi and P2P driver into two modules -+ * .Fix typo and missing entry -+ * -+ * 12 30 2010 eddie.chen -+ * [WCXRP00000322] Add WMM IE in beacon, -+ -+Add per station flow control when STA is in PS -+ -+ * Fix prBssInfo->aucCWminLog to prBssInfo->aucCWminLogForBcast -+ * -+ * 12 29 2010 eddie.chen -+ * [WCXRP00000322] Add WMM IE in beacon, -+ -+Add per station flow control when STA is in PS -+ -+ * Add WMM parameter for broadcast. -+ * -+ * 12 29 2010 eddie.chen -+ * [WCXRP00000322] Add WMM IE in beacon, -+Add per station flow control when STA is in PS -+ -+ * 1) PS flow control event -+ * -+ * 2) WMM IE in beacon, assoc resp, probe resp -+ * -+ * 11 29 2010 cp.wu -+ * [WCXRP00000210] [MT6620 Wi-Fi][Driver][FW] Set RCPI value in STA_REC -+ * for initial TX rate selection of auto-rate algorithm -+ * update ucRcpi of STA_RECORD_T for AIS when -+ * 1) Beacons for IBSS merge is received -+ * 2) Associate Response for a connecting peer is received -+ * -+ * 10 18 2010 cp.wu -+ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning -+ * use definition macro to replace hard-coded constant -+ * -+ * 10 08 2010 wh.su -+ * [WCXRP00000085] [MT6620 Wif-Fi] [Driver] update the modified p2p state machine -+ * update the frog's new p2p state machine. -+ * -+ * 09 28 2010 wh.su -+ * NULL -+ * [WCXRP00000069][MT6620 Wi-Fi][Driver] Fix some code for phase 1 P2P Demo. -+ * -+ * 09 27 2010 chinghwa.yu -+ * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000065] Update BoW design and settings -+ * Update BCM/BoW design and settings. -+ * -+ * 09 16 2010 cm.chang -+ * NULL -+ * Change conditional compiling options for BOW -+ * -+ * 09 10 2010 cm.chang -+ * NULL -+ * Always update Beacon content if FW sync OBSS info -+ * -+ * 09 07 2010 wh.su -+ * NULL -+ * adding the code for beacon/probe req/ probe rsp wsc ie at p2p. -+ * -+ * 09 03 2010 kevin.huang -+ * NULL -+ * Refine #include sequence and solve recursive/nested #include issue -+ * -+ * 08 31 2010 kevin.huang -+ * NULL -+ * Use LINK LIST operation to process SCAN result -+ * -+ * 08 30 2010 cp.wu -+ * NULL -+ * eliminate klockwork errors -+ * -+ * 08 29 2010 yuche.tsai -+ * NULL -+ * Finish SLT TX/RX & Rate Changing Support. -+ * -+ * 08 24 2010 cm.chang -+ * NULL -+ * Support RLM initail channel of Ad-hoc, P2P and BOW -+ * -+ * 08 16 2010 yuche.tsai -+ * NULL -+ * Before composing Beacon IE, assign network type index for msdu info, -+ * this information is needed by RLM module while composing some RLM related IE field. -+ * -+ * 08 16 2010 cp.wu -+ * NULL -+ * Replace CFG_SUPPORT_BOW by CFG_ENABLE_BT_OVER_WIFI. -+ * There is no CFG_SUPPORT_BOW in driver domain source. -+ * -+ * 08 16 2010 kevin.huang -+ * NULL -+ * Refine AAA functions -+ * -+ * 08 12 2010 kevin.huang -+ * NULL -+ * Fix undefined pucDestAddr in bssUpdateBeaconContent() -+ * -+ * 08 12 2010 kevin.huang -+ * NULL -+ * Refine bssProcessProbeRequest() and bssSendBeaconProbeResponse() -+ * -+ * 08 11 2010 cp.wu -+ * NULL -+ * 1) do not use in-stack variable for beacon updating. (for MAUI porting) -+ * 2) extending scanning result to 64 instead of 48 -+ * -+ * 08 02 2010 yuche.tsai -+ * NULL -+ * P2P Group Negotiation Code Check in. -+ * -+ * 08 02 2010 george.huang -+ * NULL -+ * add WMM-PS test related OID/ CMD handlers -+ * -+ * 07 26 2010 yuche.tsai -+ * -+ * Add support to RX probe response for P2P. -+ * -+ * 07 20 2010 cp.wu -+ * -+ * 1) bugfix: do not stop timer for join after switched into normal_tr state, for providing chance for DHCP handshasking -+ * 2) modify rsnPerformPolicySelection() invoking -+ * -+ * 07 19 2010 wh.su -+ * -+ * update for security supporting. -+ * -+ * 07 19 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration. -+ * when IBSS is being merged-in, send command packet to PM for connected indication -+ * -+ * 07 19 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration. -+ * Add Ad-Hoc support to AIS-FSM -+ * -+ * 07 14 2010 yarco.yang -+ * -+ * 1. Remove CFG_MQM_MIGRATION -+ * 2. Add CMD_UPDATE_WMM_PARMS command -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 07 06 2010 george.huang -+ * [WPD00001556]Basic power managemenet function -+ * Update arguments for nicUpdateBeaconIETemplate() -+ * -+ * 06 29 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) sync to. CMD/EVENT document v0.03 -+ * 2) simplify DTIM period parsing in scan.c only, bss.c no longer parses it again. -+ * 3) send command packet to indicate FW-PM after -+ * a) 1st beacon is received after AIS has connected to an AP -+ * b) IBSS-ALONE has been created -+ * c) IBSS-MERGE has occurred -+ * -+ * 06 28 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * send MMPDU in basic rate. -+ * -+ * 06 25 2010 george.huang -+ * [WPD00001556]Basic power managemenet function -+ * Create beacon update path, with expose bssUpdateBeaconContent() -+ * -+ * 06 21 2010 yuche.tsai -+ * [WPD00003839][MT6620 5931][P2P] Feature migration -+ * Fix compile error while enable WIFI_DIRECT support. -+ * -+ * 06 21 2010 yarco.yang -+ * [WPD00003837][MT6620]Data Path Refine -+ * Support CFG_MQM_MIGRATION flag -+ * -+ * 06 21 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * enable RX management frame handling. -+ * -+ * 06 21 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * specify correct value for management frames. -+ * -+ * 06 18 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Provide cnmMgtPktAlloc() and alloc/free function of msg/buf -+ * -+ * 06 15 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * correct when ADHOC support is turned on. -+ * -+ * 06 15 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add scan.c. -+ * -+ * 06 14 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add management dispatching function table. -+ * -+ * 06 11 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * auth.c is migrated. -+ * -+ * 06 11 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * fix compilation error when WIFI_DIRECT is turned on -+ * -+ * 06 11 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add bss.c. -+ * -+ * 06 04 2010 george.huang -+ * [BORA00000678][MT6620]WiFi LP integration -+ * [PM] Support U-APSD for STA mode -+ * -+ * 05 28 2010 kevin.huang -+ * [BORA00000794][WIFISYS][New Feature]Power Management Support -+ * Add ClientList handling API - bssClearClientList, bssAddStaRecToClientList -+ * -+ * 05 24 2010 kevin.huang -+ * [BORA00000794][WIFISYS][New Feature]Power Management Support -+ * Update bssProcessProbeRequest() to avoid redundant SSID IE {0,0} for IOT. -+ * -+ * 05 21 2010 kevin.huang -+ * [BORA00000794][WIFISYS][New Feature]Power Management Support -+ * Refine txmInitWtblTxRateTable() - set TX initial rate according to AP's operation rate set -+ * -+ * 05 18 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Ad-hoc Beacon should not carry HT OP and OBSS IEs -+ * -+ * 05 14 2010 kevin.huang -+ * [BORA00000794][WIFISYS][New Feature]Power Management Support -+ * Use TX MGMT Frame API for sending PS NULL frame to avoid the TX Burst Mechanism in TX FW Frame API -+ * -+ * 05 14 2010 kevin.huang -+ * [BORA00000794][WIFISYS][New Feature]Power Management Support -+ * Separate Beacon and ProbeResp IE array -+ * -+ * 05 12 2010 kevin.huang -+ * [BORA00000794][WIFISYS][New Feature]Power Management Support -+ * Add Power Management - Legacy PS-POLL support. -+ * -+ * 04 28 2010 tehuang.liu -+ * [BORA00000605][WIFISYS] Phase3 Integration -+ * Removed the use of compiling flag MQM_WMM_PARSING -+ * -+ * 04 27 2010 kevin.huang -+ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support -+ * Add Set Slot Time and Beacon Timeout Support for AdHoc Mode -+ * -+ * 04 24 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * g_aprBssInfo[] depends on CFG_SUPPORT_P2P and CFG_SUPPORT_BOW -+ * -+ * 04 22 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * First draft code to support protection in AP mode -+ * -+ * 04 20 2010 kevin.huang -+ * [BORA00000714][WIFISYS][New Feature]Beacon Timeout Support -+ * Fix restart Beacon Timeout Func after connection diagnosis -+ * -+ * 04 19 2010 kevin.huang -+ * [BORA00000714][WIFISYS][New Feature]Beacon Timeout Support -+ * Add Beacon Timeout Support and will send Null frame to diagnose connection -+ * -+ * 04 16 2010 wh.su -+ * [BORA00000680][MT6620] Support the statistic for Micxxsoft os query -+ * adding the wpa-none for ibss beacon. -+ * -+ * 04 15 2010 wh.su -+ * [BORA00000680][MT6620] Support the statistic for Micxxsoft os query -+ * fixed the protected bit at cap info for ad-hoc. -+ * -+ * 03 18 2010 kevin.huang -+ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support -+ * Rename the CFG flags -+ * -+ * 03 16 2010 kevin.huang -+ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support -+ * Add AdHoc Mode -+ * -+ * 02 26 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Update outgoing beacon's TX data rate -+ * -+ * 02 23 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Add DTIM count update while TX Beacon -+ * -+ * 02 05 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Modify code due to define - BAND_24G and specific BSS_INFO_T was changed -+ * -+ * 02 05 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Revise data structure to share the same BSS_INFO_T for avoiding coding error -+ * -+ * 02 04 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Add AAA Module Support, Revise Net Type to Net Type Index for array lookup -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "precomp.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+#if (CFG_SUPPORT_ADHOC) || (CFG_SUPPORT_AAA) -+APPEND_VAR_IE_ENTRY_T txBcnIETable[] = { -+ {(ELEM_HDR_LEN + (RATE_NUM - ELEM_MAX_LEN_SUP_RATES)), NULL, bssGenerateExtSuppRate_IE}, /* 50 */ -+ {(ELEM_HDR_LEN + ELEM_MAX_LEN_ERP), NULL, rlmRspGenerateErpIE}, /* 42 */ -+ {(ELEM_HDR_LEN + ELEM_MAX_LEN_HT_CAP), NULL, rlmRspGenerateHtCapIE}, /* 45 */ -+ {(ELEM_HDR_LEN + ELEM_MAX_LEN_HT_OP), NULL, rlmRspGenerateHtOpIE}, /* 61 */ -+#if CFG_ENABLE_WIFI_DIRECT -+ {(ELEM_HDR_LEN + ELEM_MAX_LEN_OBSS_SCAN), NULL, rlmRspGenerateObssScanIE}, /* 74 */ -+#endif -+ {(ELEM_HDR_LEN + ELEM_MAX_LEN_EXT_CAP), NULL, rlmRspGenerateExtCapIE}, /* 127 */ -+ {(ELEM_HDR_LEN + ELEM_MAX_LEN_WPA), NULL, rsnGenerateWpaNoneIE}, /* 221 */ -+ {(ELEM_HDR_LEN + ELEM_MAX_LEN_WMM_PARAM), NULL, mqmGenerateWmmParamIE}, /* 221 */ -+#if CFG_ENABLE_WIFI_DIRECT -+ {(ELEM_HDR_LEN + ELEM_MAX_LEN_WPA), NULL, rsnGenerateWPAIE}, /* 221 */ -+ {(ELEM_HDR_LEN + ELEM_MAX_LEN_RSN), NULL, rsnGenerateRSNIE}, /* 48 */ -+#if 0 /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0) */ -+ {0, p2pFuncCalculateExtra_IELenForBeacon, p2pFuncGenerateExtra_IEForBeacon}, /* 221 */ -+#else -+ {0, p2pFuncCalculateP2p_IELenForBeacon, p2pFuncGenerateP2p_IEForBeacon}, /* 221 */ -+ {0, p2pFuncCalculateWSC_IELenForBeacon, p2pFuncGenerateWSC_IEForBeacon}, /* 221 */ -+ {0, p2pFuncCalculateP2P_IE_NoA, p2pFuncGenerateP2P_IE_NoA}, /* 221 */ -+#endif -+#endif /* CFG_ENABLE_WIFI_DIRECT */ -+}; -+ -+APPEND_VAR_IE_ENTRY_T txProbRspIETable[] = { -+ {(ELEM_HDR_LEN + (RATE_NUM - ELEM_MAX_LEN_SUP_RATES)), NULL, bssGenerateExtSuppRate_IE}, /* 50 */ -+ {(ELEM_HDR_LEN + ELEM_MAX_LEN_ERP), NULL, rlmRspGenerateErpIE}, /* 42 */ -+ {(ELEM_HDR_LEN + ELEM_MAX_LEN_HT_CAP), NULL, rlmRspGenerateHtCapIE}, /* 45 */ -+ {(ELEM_HDR_LEN + ELEM_MAX_LEN_HT_OP), NULL, rlmRspGenerateHtOpIE}, /* 61 */ -+#if CFG_ENABLE_WIFI_DIRECT -+ {(ELEM_HDR_LEN + ELEM_MAX_LEN_RSN), NULL, rsnGenerateRSNIE}, /* 48 */ -+ {(ELEM_HDR_LEN + ELEM_MAX_LEN_OBSS_SCAN), NULL, rlmRspGenerateObssScanIE}, /* 74 */ -+#endif -+ {(ELEM_HDR_LEN + ELEM_MAX_LEN_EXT_CAP), NULL, rlmRspGenerateExtCapIE}, /* 127 */ -+ {(ELEM_HDR_LEN + ELEM_MAX_LEN_WPA), NULL, rsnGenerateWpaNoneIE}, /* 221 */ -+ {(ELEM_HDR_LEN + ELEM_MAX_LEN_WMM_PARAM), NULL, mqmGenerateWmmParamIE} /* 221 */ -+}; -+ -+#endif /* CFG_SUPPORT_ADHOC || CFG_SUPPORT_AAA */ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+/*----------------------------------------------------------------------------*/ -+/* Routines for all Operation Modes */ -+/*----------------------------------------------------------------------------*/ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will create or reset a STA_RECORD_T by given BSS_DESC_T for -+* Infrastructure or AdHoc Mode. -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* @param[in] eStaType Assign STA Type for this STA_RECORD_T -+* @param[in] eNetTypeIndex Assign Net Type Index for this STA_RECORD_T -+* @param[in] prBssDesc Received Beacon/ProbeResp from this STA -+* -+* @retval Pointer to STA_RECORD_T -+*/ -+/*----------------------------------------------------------------------------*/ -+P_STA_RECORD_T -+bssCreateStaRecFromBssDesc(IN P_ADAPTER_T prAdapter, -+ IN ENUM_STA_TYPE_T eStaType, -+ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_BSS_DESC_T prBssDesc) -+{ -+ P_STA_RECORD_T prStaRec; -+ UINT_8 ucNonHTPhyTypeSet; -+ -+ ASSERT(prBssDesc); -+ -+ /* 4 <1> Get a valid STA_RECORD_T */ -+ prStaRec = cnmGetStaRecByAddress(prAdapter, (UINT_8) eNetTypeIndex, prBssDesc->aucSrcAddr); -+ if (!prStaRec) { -+ -+ prStaRec = cnmStaRecAlloc(prAdapter, (UINT_8) eNetTypeIndex); -+ -+ /* TODO(Kevin): Error handling of allocation of STA_RECORD_T for -+ * exhausted case and do removal of unused STA_RECORD_T. -+ */ -+ -+ if (!prStaRec) { -+ ASSERT(FALSE); -+ return NULL; -+ } -+ -+ ASSERT(prStaRec); -+ -+ prStaRec->ucStaState = STA_STATE_1; -+ prStaRec->ucJoinFailureCount = 0; -+ /* TODO(Kevin): If this is an old entry, we may also reset the ucJoinFailureCount to 0. -+ */ -+ -+ COPY_MAC_ADDR(prStaRec->aucMacAddr, prBssDesc->aucSrcAddr); -+ } -+ /* 4 <2> Setup STA TYPE and NETWORK */ -+ prStaRec->eStaType = eStaType; -+ -+ prStaRec->ucNetTypeIndex = eNetTypeIndex; -+ -+ /* 4 <3> Update information from BSS_DESC_T to current P_STA_RECORD_T */ -+ prStaRec->u2CapInfo = prBssDesc->u2CapInfo; -+ -+ prStaRec->u2OperationalRateSet = prBssDesc->u2OperationalRateSet; -+ prStaRec->u2BSSBasicRateSet = prBssDesc->u2BSSBasicRateSet; -+ -+ prStaRec->ucPhyTypeSet = prBssDesc->ucPhyTypeSet; -+ if (IS_STA_IN_AIS(prStaRec)) { -+ if (!((prAdapter->rWifiVar.rConnSettings.eEncStatus == ENUM_ENCRYPTION3_ENABLED) || -+ (prAdapter->rWifiVar.rConnSettings.eEncStatus == ENUM_ENCRYPTION3_KEY_ABSENT) || -+ (prAdapter->rWifiVar.rConnSettings.eEncStatus == ENUM_ENCRYPTION_DISABLED) || -+ (prAdapter->prGlueInfo->u2WSCAssocInfoIELen) || (prAdapter->prGlueInfo->u2WapiAssocInfoIESz))) { -+ DBGLOG(BSS, TRACE, "Ignore the HT Bit for TKIP as pairwise cipher configured!\n"); -+ prStaRec->ucPhyTypeSet &= ~PHY_TYPE_BIT_HT; -+ } -+ } else { -+ DBGLOG(BSS, TRACE, "P2P skip TKIP limitation for HT Hit!\n"); -+ } -+ prStaRec->ucDesiredPhyTypeSet = prStaRec->ucPhyTypeSet & prAdapter->rWifiVar.ucAvailablePhyTypeSet; -+ -+ ucNonHTPhyTypeSet = prStaRec->ucDesiredPhyTypeSet & PHY_TYPE_SET_802_11ABG; -+ -+ /* Check for Target BSS's non HT Phy Types */ -+ if (ucNonHTPhyTypeSet) { -+ -+ if (ucNonHTPhyTypeSet & PHY_TYPE_BIT_ERP) { -+ prStaRec->ucNonHTBasicPhyType = PHY_TYPE_ERP_INDEX; -+ } else if (ucNonHTPhyTypeSet & PHY_TYPE_BIT_OFDM) { -+ prStaRec->ucNonHTBasicPhyType = PHY_TYPE_OFDM_INDEX; -+ } else { /* if (ucNonHTPhyTypeSet & PHY_TYPE_HR_DSSS_INDEX) */ -+ -+ prStaRec->ucNonHTBasicPhyType = PHY_TYPE_HR_DSSS_INDEX; -+ } -+ -+ prStaRec->fgHasBasicPhyType = TRUE; -+ } else { -+ /* Use mandatory for 11N only BSS */ -+ ASSERT(prStaRec->ucPhyTypeSet & PHY_TYPE_SET_802_11N); -+ -+ { -+ /* TODO(Kevin): which value should we set for 11n ? ERP ? */ -+ prStaRec->ucNonHTBasicPhyType = PHY_TYPE_HR_DSSS_INDEX; -+ } -+ -+ prStaRec->fgHasBasicPhyType = FALSE; -+ } -+ -+ /* Update non HT Desired Rate Set */ -+ { -+ P_CONNECTION_SETTINGS_T prConnSettings; -+ -+ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); -+ -+ prStaRec->u2DesiredNonHTRateSet = -+ (prStaRec->u2OperationalRateSet & prConnSettings->u2DesiredNonHTRateSet); -+ } -+ -+ /* 4 <4> Update information from BSS_DESC_T to current P_STA_RECORD_T */ -+ if (IS_AP_STA(prStaRec)) { -+ /* do not need to parse IE for DTIM, -+ * which have been parsed before inserting into BSS_DESC_T -+ */ -+ if (prBssDesc->ucDTIMPeriod) -+ prStaRec->ucDTIMPeriod = prBssDesc->ucDTIMPeriod; -+ else -+ prStaRec->ucDTIMPeriod = 0; /* Means that TIM was not parsed. */ -+ } -+ /* 4 <5> Update default value */ -+ prStaRec->fgDiagnoseConnection = FALSE; -+ -+ /* 4 <6> Update default value for other Modules */ -+ /* Determine fgIsWmmSupported and fgIsUapsdSupported in STA_REC */ -+ mqmProcessScanResult(prAdapter, prBssDesc, prStaRec); -+ -+ return prStaRec; -+ -+} /* end of bssCreateStaRecFromBssDesc() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will compose the Null Data frame. -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* @param[in] pucBuffer Pointer to the frame buffer. -+* @param[in] prStaRec Pointer to the STA_RECORD_T. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID bssComposeNullFrame(IN P_ADAPTER_T prAdapter, IN PUINT_8 pucBuffer, IN P_STA_RECORD_T prStaRec) -+{ -+ P_WLAN_MAC_HEADER_T prNullFrame; -+ P_BSS_INFO_T prBssInfo; -+ UINT_16 u2FrameCtrl; -+ -+ ASSERT(pucBuffer); -+ ASSERT(prStaRec); -+ ASSERT(prStaRec->ucNetTypeIndex < NETWORK_TYPE_INDEX_NUM); -+ -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]); -+ -+ ASSERT(prBssInfo); -+ -+ prNullFrame = (P_WLAN_MAC_HEADER_T) pucBuffer; -+ -+ /* 4 <1> Decide the Frame Control Field */ -+ u2FrameCtrl = MAC_FRAME_NULL; -+ -+ if (IS_AP_STA(prStaRec)) { -+ u2FrameCtrl |= MASK_FC_TO_DS; -+ -+ if (prStaRec->fgSetPwrMgtBit) -+ u2FrameCtrl |= MASK_FC_PWR_MGT; -+ } else if (IS_CLIENT_STA(prStaRec)) { -+ u2FrameCtrl |= MASK_FC_FROM_DS; -+ } else if (IS_DLS_STA(prStaRec)) { -+ /* TODO(Kevin) */ -+ } else { -+ /* NOTE(Kevin): We won't send Null frame for IBSS */ -+ ASSERT(0); -+ return; -+ } -+ -+ /* 4 <2> Compose the Null frame */ -+ /* Fill the Frame Control field. */ -+ /* WLAN_SET_FIELD_16(&prNullFrame->u2FrameCtrl, u2FrameCtrl); */ -+ prNullFrame->u2FrameCtrl = u2FrameCtrl; /* NOTE(Kevin): Optimized for ARM */ -+ -+ /* Fill the Address 1 field with Target Peer Address. */ -+ COPY_MAC_ADDR(prNullFrame->aucAddr1, prStaRec->aucMacAddr); -+ -+ /* Fill the Address 2 field with our MAC Address. */ -+ COPY_MAC_ADDR(prNullFrame->aucAddr2, prBssInfo->aucOwnMacAddr); -+ -+ /* Fill the Address 3 field with Target BSSID. */ -+ COPY_MAC_ADDR(prNullFrame->aucAddr3, prBssInfo->aucBSSID); -+ -+ /* Clear the SEQ/FRAG_NO field(HW won't overide the FRAG_NO, so we need to clear it). */ -+ prNullFrame->u2SeqCtrl = 0; -+ -+ return; -+ -+} /* end of bssComposeNullFrameHeader() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will compose the QoS Null Data frame. -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* @param[in] pucBuffer Pointer to the frame buffer. -+* @param[in] prStaRec Pointer to the STA_RECORD_T. -+* @param[in] ucUP User Priority. -+* @param[in] fgSetEOSP Set the EOSP bit. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+bssComposeQoSNullFrame(IN P_ADAPTER_T prAdapter, -+ IN PUINT_8 pucBuffer, IN P_STA_RECORD_T prStaRec, IN UINT_8 ucUP, IN BOOLEAN fgSetEOSP) -+{ -+ P_WLAN_MAC_HEADER_QOS_T prQoSNullFrame; -+ P_BSS_INFO_T prBssInfo; -+ UINT_16 u2FrameCtrl; -+ UINT_16 u2QosControl; -+ -+ ASSERT(pucBuffer); -+ ASSERT(prStaRec); -+ ASSERT(prStaRec->ucNetTypeIndex < NETWORK_TYPE_INDEX_NUM); -+ -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]); -+ -+ ASSERT(prBssInfo); -+ -+ prQoSNullFrame = (P_WLAN_MAC_HEADER_QOS_T) pucBuffer; -+ -+ /* 4 <1> Decide the Frame Control Field */ -+ u2FrameCtrl = MAC_FRAME_QOS_NULL; -+ -+ if (IS_AP_STA(prStaRec)) { -+ u2FrameCtrl |= MASK_FC_TO_DS; -+ -+ if (prStaRec->fgSetPwrMgtBit) -+ u2FrameCtrl |= MASK_FC_PWR_MGT; -+ } else if (IS_CLIENT_STA(prStaRec)) { -+ u2FrameCtrl |= MASK_FC_FROM_DS; -+ } else if (IS_DLS_STA(prStaRec)) { -+ /* TODO(Kevin) */ -+ } else { -+ /* NOTE(Kevin): We won't send QoS Null frame for IBSS */ -+ ASSERT(0); -+ return; -+ } -+ -+ /* 4 <2> Compose the QoS Null frame */ -+ /* Fill the Frame Control field. */ -+ /* WLAN_SET_FIELD_16(&prQoSNullFrame->u2FrameCtrl, u2FrameCtrl); */ -+ prQoSNullFrame->u2FrameCtrl = u2FrameCtrl; /* NOTE(Kevin): Optimized for ARM */ -+ -+ /* Fill the Address 1 field with Target Peer Address. */ -+ COPY_MAC_ADDR(prQoSNullFrame->aucAddr1, prStaRec->aucMacAddr); -+ -+ /* Fill the Address 2 field with our MAC Address. */ -+ COPY_MAC_ADDR(prQoSNullFrame->aucAddr2, prBssInfo->aucOwnMacAddr); -+ -+ /* Fill the Address 3 field with Target BSSID. */ -+ COPY_MAC_ADDR(prQoSNullFrame->aucAddr3, prBssInfo->aucBSSID); -+ -+ /* Clear the SEQ/FRAG_NO field(HW won't overide the FRAG_NO, so we need to clear it). */ -+ prQoSNullFrame->u2SeqCtrl = 0; -+ -+ u2QosControl = (UINT_16) (ucUP & WMM_QC_UP_MASK); -+ -+ if (fgSetEOSP) -+ u2QosControl |= WMM_QC_EOSP; -+ /* WLAN_SET_FIELD_16(&prQoSNullFrame->u2QosCtrl, u2QosControl); */ -+ prQoSNullFrame->u2QosCtrl = u2QosControl; /* NOTE(Kevin): Optimized for ARM */ -+ -+ return; -+ -+} /* end of bssComposeQoSNullFrameHeader() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Send the Null Frame -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* @param[in] prStaRec Pointer to the STA_RECORD_T -+* @param[in] pfTxDoneHandler TX Done call back function -+* -+* @retval WLAN_STATUS_RESOURCE No available resources to send frame. -+* @retval WLAN_STATUS_SUCCESS Succe]ss. -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+bssSendNullFrame(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN PFN_TX_DONE_HANDLER pfTxDoneHandler) -+{ -+ P_MSDU_INFO_T prMsduInfo; -+ UINT_16 u2EstimatedFrameLen; -+ -+ /* 4 <1> Allocate a PKT_INFO_T for Null Frame */ -+ /* Init with MGMT Header Length */ -+ u2EstimatedFrameLen = MAC_TX_RESERVED_FIELD + WLAN_MAC_HEADER_LEN; -+ -+ /* Allocate a MSDU_INFO_T */ -+ prMsduInfo = cnmMgtPktAlloc(prAdapter, u2EstimatedFrameLen); -+ if (prMsduInfo == NULL) { -+ DBGLOG(BSS, WARN, "No PKT_INFO_T for sending Null Frame.\n"); -+ return WLAN_STATUS_RESOURCES; -+ } -+ /* 4 <2> Compose Null frame in MSDU_INfO_T. */ -+ bssComposeNullFrame(prAdapter, (PUINT_8) ((ULONG) prMsduInfo->prPacket + MAC_TX_RESERVED_FIELD), prStaRec); -+#if 0 -+ /* 4 <3> Update information of MSDU_INFO_T */ -+ TXM_SET_DATA_PACKET( -+ /* STA_REC ptr */ prStaRec, -+ /* MSDU_INFO ptr */ prMsduInfo, -+ /* MAC HDR ptr */ (prMsduInfo->pucBuffer + MAC_TX_RESERVED_FIELD), -+ /* MAC HDR length */ WLAN_MAC_HEADER_LEN, -+ /* PAYLOAD ptr */ -+ (prMsduInfo->pucBuffer + MAC_TX_RESERVED_FIELD + WLAN_MAC_HEADER_LEN), -+ /* PAYLOAD length */ 0, -+ /* Network Type Index */ (UINT_8) prStaRec->ucNetTypeIndex, -+ /* TID */ 0 /* BE: AC1 */ , -+ /* Flag 802.11 */ TRUE, -+ /* Pkt arrival time */ 0 /* TODO: Obtain the system time */ , -+ /* Resource TC */ 0 /* Irrelevant */ , -+ /* Flag 802.1x */ FALSE, -+ /* TX-done callback */ pfTxDoneHandler, -+ /* PS forwarding type */ PS_FORWARDING_TYPE_NON_PS, -+ /* PS Session ID */ 0 /* Irrelevant */ , -+ /* Flag fixed rate */ TRUE, -+ /* Fixed tx rate */ g_aprBssInfo[prStaRec->ucNetTypeIndex]->ucHwDefaultFixedRateCode, -+ /* Fixed-rate retry */ BSS_DEFAULT_CONN_TEST_NULL_FRAME_RETRY_LIMIT, -+ /* PAL LLH */ 0 /* Irrelevant */ , -+ /* ACL SN */ 0 /* Irrelevant */ , -+ /* Flag No Ack */ FALSE -+ ); -+ -+ /* Terminate with a NULL pointer */ -+ NIC_HIF_TX_SET_NEXT_MSDU_INFO(prMsduInfo, NULL); -+ -+ /* TODO(Kevin): Also release the unused tail room of the composed MMPDU */ -+ -+ /* Indicate the packet to TXM */ -+ /* 4 <4> Inform TXM to send this Null frame. */ -+ txmSendFwDataPackets(prMsduInfo); -+#endif -+ -+ prMsduInfo->eSrc = TX_PACKET_MGMT; -+ prMsduInfo->ucPacketType = HIF_TX_PACKET_TYPE_DATA; -+ prMsduInfo->ucStaRecIndex = prStaRec->ucIndex; -+ prMsduInfo->ucNetworkType = prStaRec->ucNetTypeIndex; -+ prMsduInfo->ucMacHeaderLength = WLAN_MAC_HEADER_LEN; -+ prMsduInfo->fgIs802_1x = FALSE; -+ prMsduInfo->fgIs802_11 = TRUE; -+ prMsduInfo->u2FrameLength = WLAN_MAC_HEADER_LEN; -+ prMsduInfo->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter); -+ prMsduInfo->pfTxDoneHandler = pfTxDoneHandler; -+ prMsduInfo->fgIsBasicRate = FALSE; -+ -+ /* 4 <4> Inform TXM to send this Null frame. */ -+ nicTxEnqueueMsdu(prAdapter, prMsduInfo); -+ -+ return WLAN_STATUS_SUCCESS; -+ -+} /* end of bssSendNullFrame() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Send the QoS Null Frame -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* @param[in] prStaRec Pointer to the STA_RECORD_T -+* @param[in] pfTxDoneHandler TX Done call back function -+* -+* @retval WLAN_STATUS_RESOURCE No available resources to send frame. -+* @retval WLAN_STATUS_SUCCESS Success. -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+bssSendQoSNullFrame(IN P_ADAPTER_T prAdapter, -+ IN P_STA_RECORD_T prStaRec, IN UINT_8 ucUP, IN PFN_TX_DONE_HANDLER pfTxDoneHandler) -+{ -+ P_MSDU_INFO_T prMsduInfo; -+ UINT_16 u2EstimatedFrameLen; -+ -+ /* 4 <1> Allocate a PKT_INFO_T for Null Frame */ -+ /* Init with MGMT Header Length */ -+ u2EstimatedFrameLen = MAC_TX_RESERVED_FIELD + WLAN_MAC_HEADER_QOS_LEN; -+ -+ /* Allocate a MSDU_INFO_T */ -+ prMsduInfo = cnmMgtPktAlloc(prAdapter, u2EstimatedFrameLen); -+ if (prMsduInfo == NULL) { -+ DBGLOG(BSS, WARN, "No PKT_INFO_T for sending Null Frame.\n"); -+ return WLAN_STATUS_RESOURCES; -+ } -+ /* 4 <2> Compose Null frame in MSDU_INfO_T. */ -+ bssComposeQoSNullFrame(prAdapter, -+ (PUINT_8) ((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD), -+ prStaRec, ucUP, FALSE); -+#if 0 -+ /* 4 <3> Update information of MSDU_INFO_T */ -+ TXM_SET_DATA_PACKET( -+ /* STA_REC ptr */ prStaRec, -+ /* MSDU_INFO ptr */ prMsduInfo, -+ /* MAC HDR ptr */ (prMsduInfo->pucBuffer + MAC_TX_RESERVED_FIELD), -+ /* MAC HDR length */ WLAN_MAC_HEADER_QOS_LEN, -+ /* PAYLOAD ptr */ -+ (prMsduInfo->pucBuffer + MAC_TX_RESERVED_FIELD + WLAN_MAC_HEADER_QOS_LEN), -+ /* PAYLOAD length */ 0, -+ /* Network Type Index */ (UINT_8) prStaRec->ucNetTypeIndex, -+ /* TID */ 0 /* BE: AC1 */ , -+ /* Flag 802.11 */ TRUE, -+ /* Pkt arrival time */ 0 /* TODO: Obtain the system time */ , -+ /* Resource TC */ 0 /* Irrelevant */ , -+ /* Flag 802.1x */ FALSE, -+ /* TX-done callback */ pfTxDoneHandler, -+ /* PS forwarding type */ PS_FORWARDING_TYPE_NON_PS, -+ /* PS Session ID */ 0 /* Irrelevant */ , -+ /* Flag fixed rate */ TRUE, -+ /* Fixed tx rate */ g_aprBssInfo[prStaRec->ucNetTypeIndex]->ucHwDefaultFixedRateCode, -+ /* Fixed-rate retry */ TXM_DEFAULT_DATA_FRAME_RETRY_LIMIT, -+ /* PAL LLH */ 0 /* Irrelevant */ , -+ /* ACL SN */ 0 /* Irrelevant */ , -+ /* Flag No Ack */ FALSE -+ ); -+ -+ /* Terminate with a NULL pointer */ -+ NIC_HIF_TX_SET_NEXT_MSDU_INFO(prMsduInfo, NULL); -+ -+ /* TODO(Kevin): Also release the unused tail room of the composed MMPDU */ -+ -+ /* Indicate the packet to TXM */ -+ /* 4 <4> Inform TXM to send this Null frame. */ -+ txmSendFwDataPackets(prMsduInfo); -+#endif -+ -+ prMsduInfo->eSrc = TX_PACKET_MGMT; -+ prMsduInfo->ucPacketType = HIF_TX_PACKET_TYPE_MGMT; -+ prMsduInfo->ucStaRecIndex = prStaRec->ucIndex; -+ prMsduInfo->ucNetworkType = prStaRec->ucNetTypeIndex; -+ prMsduInfo->ucMacHeaderLength = WLAN_MAC_HEADER_QOS_LEN; -+ prMsduInfo->fgIs802_1x = FALSE; -+ prMsduInfo->fgIs802_11 = TRUE; -+ prMsduInfo->u2FrameLength = WLAN_MAC_HEADER_QOS_LEN; -+ prMsduInfo->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter); -+ prMsduInfo->pfTxDoneHandler = pfTxDoneHandler; -+ prMsduInfo->fgIsBasicRate = TRUE; -+ -+ /* 4 <4> Inform TXM to send this Null frame. */ -+ nicTxEnqueueMsdu(prAdapter, prMsduInfo); -+ -+ return WLAN_STATUS_SUCCESS; -+ -+} /* end of bssSendQoSNullFrame() */ -+ -+#if (CFG_SUPPORT_ADHOC) || (CFG_SUPPORT_AAA) -+/*----------------------------------------------------------------------------*/ -+/* Routines for both IBSS(AdHoc) and BSS(AP) */ -+/*----------------------------------------------------------------------------*/ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is used to generate Information Elements of Extended -+* Support Rate -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* @param[in] prMsduInfo Pointer to the composed MSDU_INFO_T. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID bssGenerateExtSuppRate_IE(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo) -+{ -+ P_BSS_INFO_T prBssInfo; -+ PUINT_8 pucBuffer; -+ UINT_8 ucExtSupRatesLen; -+ -+ ASSERT(prMsduInfo); -+ -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prMsduInfo->ucNetworkType]); -+ ASSERT(prBssInfo); -+ -+ pucBuffer = (PUINT_8) ((ULONG) prMsduInfo->prPacket + (UINT_32) prMsduInfo->u2FrameLength); -+ ASSERT(pucBuffer); -+ -+ if (prBssInfo->ucAllSupportedRatesLen > ELEM_MAX_LEN_SUP_RATES) -+ ucExtSupRatesLen = prBssInfo->ucAllSupportedRatesLen - ELEM_MAX_LEN_SUP_RATES; -+ else -+ ucExtSupRatesLen = 0; -+ -+ /* Fill the Extended Supported Rates element. */ -+ if (ucExtSupRatesLen) { -+ -+ EXT_SUP_RATES_IE(pucBuffer)->ucId = ELEM_ID_EXTENDED_SUP_RATES; -+ EXT_SUP_RATES_IE(pucBuffer)->ucLength = ucExtSupRatesLen; -+ -+ kalMemCopy(EXT_SUP_RATES_IE(pucBuffer)->aucExtSupportedRates, -+ &prBssInfo->aucAllSupportedRates[ELEM_MAX_LEN_SUP_RATES], ucExtSupRatesLen); -+ -+ prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer); -+ } -+ -+} /* end of bssGenerateExtSuppRate_IE() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is used to compose Common Information Elements for Beacon -+* or Probe Response Frame. -+* -+* @param[in] prMsduInfo Pointer to the composed MSDU_INFO_T. -+* @param[in] prBssInfo Pointer to the BSS_INFO_T. -+* @param[in] pucDestAddr Pointer to the Destination Address, if NULL, means Beacon. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+bssBuildBeaconProbeRespFrameCommonIEs(IN P_MSDU_INFO_T prMsduInfo, IN P_BSS_INFO_T prBssInfo, IN PUINT_8 pucDestAddr) -+{ -+ PUINT_8 pucBuffer; -+ UINT_8 ucSupRatesLen; -+ -+ ASSERT(prMsduInfo); -+ ASSERT(prBssInfo); -+ -+ pucBuffer = (PUINT_8) ((ULONG) prMsduInfo->prPacket + (UINT_32) prMsduInfo->u2FrameLength); -+ ASSERT(pucBuffer); -+ -+ /* Compose the frame body of the Probe Response frame. */ -+ /* 4 <1> Fill the SSID element. */ -+ SSID_IE(pucBuffer)->ucId = ELEM_ID_SSID; -+ if (prBssInfo->eHiddenSsidType == ENUM_HIDDEN_SSID_LEN) { -+ if ((!pucDestAddr) && /* For Beacon only */ -+ (prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT)) { -+ SSID_IE(pucBuffer)->ucLength = 0; -+ } else { /* Probe response */ -+ SSID_IE(pucBuffer)->ucLength = prBssInfo->ucSSIDLen; -+ if (prBssInfo->ucSSIDLen) -+ kalMemCopy(SSID_IE(pucBuffer)->aucSSID, prBssInfo->aucSSID, prBssInfo->ucSSIDLen); -+ } -+ } else { -+ SSID_IE(pucBuffer)->ucLength = prBssInfo->ucSSIDLen; -+ if (prBssInfo->ucSSIDLen) -+ kalMemCopy(SSID_IE(pucBuffer)->aucSSID, prBssInfo->aucSSID, prBssInfo->ucSSIDLen); -+ } -+ -+ prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer); -+ pucBuffer += IE_SIZE(pucBuffer); -+ -+ /* 4 <2> Fill the Supported Rates element. */ -+ if (prBssInfo->ucAllSupportedRatesLen > ELEM_MAX_LEN_SUP_RATES) -+ ucSupRatesLen = ELEM_MAX_LEN_SUP_RATES; -+ else -+ ucSupRatesLen = prBssInfo->ucAllSupportedRatesLen; -+ -+ if (ucSupRatesLen) { -+ SUP_RATES_IE(pucBuffer)->ucId = ELEM_ID_SUP_RATES; -+ SUP_RATES_IE(pucBuffer)->ucLength = ucSupRatesLen; -+ kalMemCopy(SUP_RATES_IE(pucBuffer)->aucSupportedRates, prBssInfo->aucAllSupportedRates, ucSupRatesLen); -+ -+ prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer); -+ pucBuffer += IE_SIZE(pucBuffer); -+ } -+ /* 4 <3> Fill the DS Parameter Set element. */ -+ if (prBssInfo->eBand == BAND_2G4) { -+ DS_PARAM_IE(pucBuffer)->ucId = ELEM_ID_DS_PARAM_SET; -+ DS_PARAM_IE(pucBuffer)->ucLength = ELEM_MAX_LEN_DS_PARAMETER_SET; -+ DS_PARAM_IE(pucBuffer)->ucCurrChnl = prBssInfo->ucPrimaryChannel; -+ -+ prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer); -+ pucBuffer += IE_SIZE(pucBuffer); -+ } -+ /* 4 <4> IBSS Parameter Set element, ID: 6 */ -+ if (prBssInfo->eCurrentOPMode == OP_MODE_IBSS) { -+ IBSS_PARAM_IE(pucBuffer)->ucId = ELEM_ID_IBSS_PARAM_SET; -+ IBSS_PARAM_IE(pucBuffer)->ucLength = ELEM_MAX_LEN_IBSS_PARAMETER_SET; -+ WLAN_SET_FIELD_16(&(IBSS_PARAM_IE(pucBuffer)->u2ATIMWindow), prBssInfo->u2ATIMWindow); -+ -+ prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer); -+ pucBuffer += IE_SIZE(pucBuffer); -+ } -+ /* 4 <5> TIM element, ID: 5 */ -+ if ((!pucDestAddr) && /* For Beacon only. */ -+ (prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT)) { -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ /*no fgIsP2PRegistered protect */ -+ if (prBssInfo->ucNetTypeIndex == NETWORK_TYPE_P2P_INDEX) { -+#if 0 -+ P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo; -+ UINT_8 ucBitmapControl = 0; -+ UINT_32 u4N1, u4N2; -+ -+ prP2pSpecificBssInfo = &(prAdapter->rWifiVar.rP2pSpecificBssInfo); -+ -+ /* Clear existing value. */ -+ prP2pSpecificBssInfo->ucBitmapCtrl = 0; -+ kalMemZero(prP2pSpecificBssInfo->aucPartialVirtualBitmap, -+ sizeof(prP2pSpecificBssInfo->aucPartialVirtualBitmap)); -+ -+ /* IEEE 802.11 2007 - 7.3.2.6 */ -+ TIM_IE(pucBuffer)->ucId = ELEM_ID_TIM; -+ TIM_IE(pucBuffer)->ucDTIMCount = prBssInfo->ucDTIMCount; -+ TIM_IE(pucBuffer)->ucDTIMPeriod = prBssInfo->ucDTIMPeriod; -+ -+ /* Setup DTIM Count for next TBTT. */ -+ if (prBssInfo->ucDTIMCount == 0) { -+ /*Do nothing*/ -+ /* 3 *** pmQueryBufferedBCAST(); */ -+ } -+ /* 3 *** pmQueryBufferedPSNode(); */ -+ /* TODO(Kevin): Call PM Module here to loop all STA_RECORD_Ts and it -+ * will call bssSetTIMBitmap to toggle the Bitmap. -+ */ -+ -+ /* Set Virtual Bitmap for UCAST */ -+ u4N1 = (prP2pSpecificBssInfo->u2SmallestAID >> 4) << 1; /* Find the largest even number. */ -+ u4N2 = prP2pSpecificBssInfo->u2LargestAID >> 3; /* Find the smallest number. */ -+ -+ ASSERT(u4N2 >= u4N1); -+ -+ kalMemCopy(TIM_IE(pucBuffer)->aucPartialVirtualMap, -+ &prP2pSpecificBssInfo->aucPartialVirtualBitmap[u4N1], ((u4N2 - u4N1) + 1)); -+ -+ /* Set Virtual Bitmap for BMCAST */ -+ /* BMC bit only indicated when DTIM count == 0. */ -+ if (prBssInfo->ucDTIMCount == 0) -+ ucBitmapControl = prP2pSpecificBssInfo->ucBitmapCtrl; -+ TIM_IE(pucBuffer)->ucBitmapControl = ucBitmapControl | (UINT_8) u4N1; -+ -+ TIM_IE(pucBuffer)->ucLength = ((u4N2 - u4N1) + 4); -+ -+ prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer); -+#else -+ -+ /* IEEE 802.11 2007 - 7.3.2.6 */ -+ TIM_IE(pucBuffer)->ucId = ELEM_ID_TIM; -+ /* NOTE: fixed PVB length (AID is allocated from 8 ~ 15 only) */ -+ TIM_IE(pucBuffer)->ucLength = (3 + MAX_LEN_TIM_PARTIAL_BMP); /*((u4N2 - u4N1) + 4) */ -+ /* will be overwrite by FW */ -+ TIM_IE(pucBuffer)->ucDTIMCount = 0; /*prBssInfo->ucDTIMCount */ -+ TIM_IE(pucBuffer)->ucDTIMPeriod = prBssInfo->ucDTIMPeriod; -+ /* will be overwrite by FW */ -+ TIM_IE(pucBuffer)->ucBitmapControl = 0; /*ucBitmapControl | (UINT_8)u4N1 */ -+ -+ prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer); -+ -+#endif -+ -+ } else -+#endif /* CFG_ENABLE_WIFI_DIRECT */ -+ { -+ /* NOTE(Kevin): 1. AIS - Didn't Support AP Mode. -+ * 2. BOW - Didn't Support BCAST and PS. -+ */ -+ } -+ -+ } -+ -+} /* end of bssBuildBeaconProbeRespFrameCommonIEs() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will compose the Beacon/Probe Response frame header and -+* its fixed fields. -+* -+* @param[in] pucBuffer Pointer to the frame buffer. -+* @param[in] pucDestAddr Pointer to the Destination Address, if NULL, means Beacon. -+* @param[in] pucOwnMACAddress Given Our MAC Address. -+* @param[in] pucBSSID Given BSSID of the BSS. -+* @param[in] u2BeaconInterval Given Beacon Interval. -+* @param[in] u2CapInfo Given Capability Info. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+bssComposeBeaconProbeRespFrameHeaderAndFF(IN PUINT_8 pucBuffer, -+ IN PUINT_8 pucDestAddr, -+ IN PUINT_8 pucOwnMACAddress, -+ IN PUINT_8 pucBSSID, IN UINT_16 u2BeaconInterval, IN UINT_16 u2CapInfo) -+{ -+ P_WLAN_BEACON_FRAME_T prBcnProbRspFrame; -+ UINT_8 aucBCAddr[] = BC_MAC_ADDR; -+ UINT_16 u2FrameCtrl; -+ -+ DEBUGFUNC("bssComposeBeaconProbeRespFrameHeaderAndFF"); -+ /* DBGLOG(INIT, LOUD, ("\n")); */ -+ -+ ASSERT(pucBuffer); -+ ASSERT(pucOwnMACAddress); -+ ASSERT(pucBSSID); -+ -+ prBcnProbRspFrame = (P_WLAN_BEACON_FRAME_T) pucBuffer; -+ -+ /* 4 <1> Compose the frame header of the Beacon /ProbeResp frame. */ -+ /* Fill the Frame Control field. */ -+ if (pucDestAddr) { -+ u2FrameCtrl = MAC_FRAME_PROBE_RSP; -+ } else { -+ u2FrameCtrl = MAC_FRAME_BEACON; -+ pucDestAddr = aucBCAddr; -+ } -+ /* WLAN_SET_FIELD_16(&prBcnProbRspFrame->u2FrameCtrl, u2FrameCtrl); */ -+ prBcnProbRspFrame->u2FrameCtrl = u2FrameCtrl; /* NOTE(Kevin): Optimized for ARM */ -+ -+ /* Fill the DA field with BCAST MAC ADDR or TA of ProbeReq. */ -+ COPY_MAC_ADDR(prBcnProbRspFrame->aucDestAddr, pucDestAddr); -+ -+ /* Fill the SA field with our MAC Address. */ -+ COPY_MAC_ADDR(prBcnProbRspFrame->aucSrcAddr, pucOwnMACAddress); -+ -+ /* Fill the BSSID field with current BSSID. */ -+ COPY_MAC_ADDR(prBcnProbRspFrame->aucBSSID, pucBSSID); -+ -+ /* Clear the SEQ/FRAG_NO field(HW won't overide the FRAG_NO, so we need to clear it). */ -+ prBcnProbRspFrame->u2SeqCtrl = 0; -+ -+ /* 4 <2> Compose the frame body's common fixed field part of the Beacon /ProbeResp frame. */ -+ /* MAC will update TimeStamp field */ -+ -+ /* Fill the Beacon Interval field. */ -+ /* WLAN_SET_FIELD_16(&prBcnProbRspFrame->u2BeaconInterval, u2BeaconInterval); */ -+ prBcnProbRspFrame->u2BeaconInterval = u2BeaconInterval; /* NOTE(Kevin): Optimized for ARM */ -+ -+ /* Fill the Capability Information field. */ -+ /* WLAN_SET_FIELD_16(&prBcnProbRspFrame->u2CapInfo, u2CapInfo); */ -+ prBcnProbRspFrame->u2CapInfo = u2CapInfo; /* NOTE(Kevin): Optimized for ARM */ -+ -+} /* end of bssComposeBeaconProbeRespFrameHeaderAndFF() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Update the Beacon Frame Template to FW for AIS AdHoc and P2P GO. -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* @param[in] eNetTypeIndex Specify which network reply the Probe Response. -+* -+* @retval WLAN_STATUS_SUCCESS Success. -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS bssUpdateBeaconContent(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex) -+{ -+ P_BSS_INFO_T prBssInfo; -+ P_MSDU_INFO_T prMsduInfo; -+ P_WLAN_BEACON_FRAME_T prBcnFrame; -+ UINT_32 i; -+ -+ DEBUGFUNC("bssUpdateBeaconContent"); -+ DBGLOG(BSS, LOUD, "\n"); -+ -+ ASSERT(eNetTypeIndex < NETWORK_TYPE_INDEX_NUM); -+ -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[eNetTypeIndex]); -+ -+ /* 4 <1> Allocate a PKT_INFO_T for Beacon Frame */ -+ /* Allocate a MSDU_INFO_T */ -+ /* For Beacon */ -+ prMsduInfo = prBssInfo->prBeacon; -+ -+ /* beacon prMsduInfo will be NULLify once BSS deactivated, so skip if it is */ -+ if (prMsduInfo == NULL) -+ return WLAN_STATUS_SUCCESS; -+ /* 4 <2> Compose header */ -+ bssComposeBeaconProbeRespFrameHeaderAndFF((PUINT_8) ((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD), -+ NULL, -+ prBssInfo->aucOwnMacAddr, -+ prBssInfo->aucBSSID, -+ prBssInfo->u2BeaconInterval, prBssInfo->u2CapInfo); -+ -+ prMsduInfo->u2FrameLength = (WLAN_MAC_MGMT_HEADER_LEN + -+ (TIMESTAMP_FIELD_LEN + BEACON_INTERVAL_FIELD_LEN + CAP_INFO_FIELD_LEN)); -+ -+ prMsduInfo->ucNetworkType = eNetTypeIndex; -+ -+ /* 4 <3> Compose the frame body's Common IEs of the Beacon frame. */ -+ bssBuildBeaconProbeRespFrameCommonIEs(prMsduInfo, prBssInfo, NULL); -+ -+ /* 4 <4> Compose IEs in MSDU_INFO_T */ -+ -+ /* Append IE for Beacon */ -+ for (i = 0; i < sizeof(txBcnIETable) / sizeof(APPEND_VAR_IE_ENTRY_T); i++) { -+ if (txBcnIETable[i].pfnAppendIE) -+ txBcnIETable[i].pfnAppendIE(prAdapter, prMsduInfo); -+ } -+ -+ prBcnFrame = (P_WLAN_BEACON_FRAME_T) prMsduInfo->prPacket; -+ -+ return nicUpdateBeaconIETemplate(prAdapter, -+ IE_UPD_METHOD_UPDATE_ALL, -+ eNetTypeIndex, -+ prBssInfo->u2CapInfo, -+ (PUINT_8) prBcnFrame->aucInfoElem, -+ prMsduInfo->u2FrameLength - OFFSET_OF(WLAN_BEACON_FRAME_T, aucInfoElem)); -+ -+} /* end of bssUpdateBeaconContent() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Send the Beacon Frame(for BOW) or Probe Response Frame according to the given -+* Destination Address. -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* @param[in] eNetTypeIndex Specify which network reply the Probe Response. -+* @param[in] pucDestAddr Pointer to the Destination Address to reply -+* @param[in] u4ControlFlags Control flags for information on Probe Response. -+* -+* @retval WLAN_STATUS_RESOURCE No available resources to send frame. -+* @retval WLAN_STATUS_SUCCESS Success. -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+bssSendBeaconProbeResponse(IN P_ADAPTER_T prAdapter, -+ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, -+ IN PUINT_8 pucDestAddr, IN UINT_32 u4ControlFlags) -+{ -+ P_BSS_INFO_T prBssInfo; -+ P_MSDU_INFO_T prMsduInfo; -+ UINT_16 u2EstimatedFrameLen; -+ UINT_16 u2EstimatedFixedIELen; -+ UINT_16 u2EstimatedExtraIELen; -+ P_APPEND_VAR_IE_ENTRY_T prIeArray = NULL; -+ UINT_32 u4IeArraySize = 0; -+ UINT_32 i; -+ -+ ASSERT(eNetTypeIndex < NETWORK_TYPE_INDEX_NUM); -+ -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[eNetTypeIndex]); -+ -+ if (!pucDestAddr) { /* For Beacon */ -+ prIeArray = &txBcnIETable[0]; -+ u4IeArraySize = sizeof(txBcnIETable) / sizeof(APPEND_VAR_IE_ENTRY_T); -+ } else { -+ prIeArray = &txProbRspIETable[0]; -+ u4IeArraySize = sizeof(txProbRspIETable) / sizeof(APPEND_VAR_IE_ENTRY_T); -+ } -+ -+ /* 4 <1> Allocate a PKT_INFO_T for Beacon /Probe Response Frame */ -+ /* Allocate a MSDU_INFO_T */ -+ -+ /* Init with MGMT Header Length + Length of Fixed Fields + Common IE Fields */ -+ u2EstimatedFrameLen = MAC_TX_RESERVED_FIELD + -+ WLAN_MAC_MGMT_HEADER_LEN + -+ TIMESTAMP_FIELD_LEN + -+ BEACON_INTERVAL_FIELD_LEN + -+ CAP_INFO_FIELD_LEN + -+ (ELEM_HDR_LEN + ELEM_MAX_LEN_SSID) + -+ (ELEM_HDR_LEN + ELEM_MAX_LEN_SUP_RATES) + -+ (ELEM_HDR_LEN + ELEM_MAX_LEN_DS_PARAMETER_SET) + -+ (ELEM_HDR_LEN + ELEM_MAX_LEN_IBSS_PARAMETER_SET) + (ELEM_HDR_LEN + (3 + MAX_LEN_TIM_PARTIAL_BMP)); -+ -+ /* + Extra IE Length */ -+ u2EstimatedExtraIELen = 0; -+ -+ for (i = 0; i < u4IeArraySize; i++) { -+ u2EstimatedFixedIELen = prIeArray[i].u2EstimatedFixedIELen; -+ -+ if (u2EstimatedFixedIELen) { -+ u2EstimatedExtraIELen += u2EstimatedFixedIELen; -+ } else { -+ ASSERT(prIeArray[i].pfnCalculateVariableIELen); -+ -+ u2EstimatedExtraIELen += (UINT_16) -+ prIeArray[i].pfnCalculateVariableIELen(prAdapter, eNetTypeIndex, NULL); -+ } -+ } -+ -+ u2EstimatedFrameLen += u2EstimatedExtraIELen; -+ prMsduInfo = cnmMgtPktAlloc(prAdapter, u2EstimatedFrameLen); -+ if (prMsduInfo == NULL) { -+ DBGLOG(BSS, WARN, "No PKT_INFO_T for sending %s.\n", ((!pucDestAddr) ? "Beacon" : "Probe Response")); -+ return WLAN_STATUS_RESOURCES; -+ } -+ /* 4 <2> Compose Beacon/Probe Response frame header and fixed fields in MSDU_INfO_T. */ -+ /* Compose Header and Fixed Field */ -+#if CFG_ENABLE_WIFI_DIRECT -+ if (u4ControlFlags & BSS_PROBE_RESP_USE_P2P_DEV_ADDR) { -+ if (prAdapter->fgIsP2PRegistered) { -+ bssComposeBeaconProbeRespFrameHeaderAndFF((PUINT_8) -+ ((ULONG) (prMsduInfo->prPacket) + -+ MAC_TX_RESERVED_FIELD), pucDestAddr, -+ prAdapter->rWifiVar.aucDeviceAddress, -+ prAdapter->rWifiVar.aucDeviceAddress, -+ DOT11_BEACON_PERIOD_DEFAULT, -+ (prBssInfo->u2CapInfo & -+ ~(CAP_INFO_ESS | CAP_INFO_IBSS))); -+ } -+ } else -+#endif /* CFG_ENABLE_WIFI_DIRECT */ -+ { -+ bssComposeBeaconProbeRespFrameHeaderAndFF((PUINT_8) -+ ((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD), -+ pucDestAddr, prBssInfo->aucOwnMacAddr, prBssInfo->aucBSSID, -+ prBssInfo->u2BeaconInterval, prBssInfo->u2CapInfo); -+ } -+ -+ /* 4 <3> Update information of MSDU_INFO_T */ -+ prMsduInfo->eSrc = TX_PACKET_MGMT; -+ prMsduInfo->ucPacketType = HIF_TX_PACKET_TYPE_MGMT; -+ prMsduInfo->ucStaRecIndex = 0xFF; -+ prMsduInfo->ucNetworkType = (UINT_8) eNetTypeIndex; -+ prMsduInfo->ucMacHeaderLength = WLAN_MAC_MGMT_HEADER_LEN; -+ prMsduInfo->fgIs802_1x = FALSE; -+ prMsduInfo->fgIs802_11 = TRUE; -+ prMsduInfo->u2FrameLength = (WLAN_MAC_MGMT_HEADER_LEN + -+ TIMESTAMP_FIELD_LEN + BEACON_INTERVAL_FIELD_LEN + CAP_INFO_FIELD_LEN); -+ prMsduInfo->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter); -+ prMsduInfo->pfTxDoneHandler = NULL; -+ prMsduInfo->fgIsBasicRate = TRUE; -+ -+ /* 4 <4> Compose the frame body's Common IEs of the Beacon/ProbeResp frame. */ -+ bssBuildBeaconProbeRespFrameCommonIEs(prMsduInfo, prBssInfo, pucDestAddr); -+ -+ /* 4 <5> Compose IEs in MSDU_INFO_T */ -+ -+ /* Append IE */ -+ for (i = 0; i < u4IeArraySize; i++) { -+ if (prIeArray[i].pfnAppendIE) -+ prIeArray[i].pfnAppendIE(prAdapter, prMsduInfo); -+ } -+ -+ /* TODO(Kevin): Also release the unused tail room of the composed MMPDU */ -+ -+ /* 4 <6> Inform TXM to send this Beacon /Probe Response frame. */ -+ nicTxEnqueueMsdu(prAdapter, prMsduInfo); -+ -+ return WLAN_STATUS_SUCCESS; -+ -+} /* end of bssSendBeaconProbeResponse() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will process the Rx Probe Request Frame and then send -+* back the corresponding Probe Response Frame if the specified conditions -+* were matched. -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* @param[in] prSwRfb Pointer to SW RFB data structure. -+* -+* @retval WLAN_STATUS_SUCCESS Always return success -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS bssProcessProbeRequest(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb) -+{ -+ P_WLAN_MAC_MGMT_HEADER_T prMgtHdr; -+ P_BSS_INFO_T prBssInfo; -+ ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex; -+ UINT_8 aucBCBSSID[] = BC_BSSID; -+ BOOLEAN fgIsBcBssid; -+ BOOLEAN fgReplyProbeResp; -+ UINT_32 u4CtrlFlagsForProbeResp = 0; -+ ENUM_BAND_T eBand; -+ UINT_8 ucHwChannelNum; -+ -+ ASSERT(prSwRfb); -+ -+ /* 4 <1> Parse Probe Req and Get BSSID */ -+ prMgtHdr = (P_WLAN_MAC_MGMT_HEADER_T) prSwRfb->pvHeader; -+ -+ if (EQUAL_MAC_ADDR(aucBCBSSID, prMgtHdr->aucBSSID)) -+ fgIsBcBssid = TRUE; -+ else -+ fgIsBcBssid = FALSE; -+ -+ /* 4 <2> Check network conditions before reply Probe Response Frame (Consider Concurrent) */ -+ for (eNetTypeIndex = NETWORK_TYPE_AIS_INDEX; eNetTypeIndex < NETWORK_TYPE_INDEX_NUM; eNetTypeIndex++) { -+ -+ if (!IS_NET_ACTIVE(prAdapter, eNetTypeIndex)) -+ continue; -+ -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[eNetTypeIndex]); -+ -+ if ((!fgIsBcBssid) && UNEQUAL_MAC_ADDR(prBssInfo->aucBSSID, prMgtHdr->aucBSSID)) -+ continue; -+ -+ eBand = HIF_RX_HDR_GET_RF_BAND(prSwRfb->prHifRxHdr); -+ ucHwChannelNum = HIF_RX_HDR_GET_CHNL_NUM(prSwRfb->prHifRxHdr); -+ -+ if (prBssInfo->eBand != eBand) -+ continue; -+ -+ if (prBssInfo->ucPrimaryChannel != ucHwChannelNum) -+ continue; -+ -+ fgReplyProbeResp = FALSE; -+ -+ if (NETWORK_TYPE_AIS_INDEX == eNetTypeIndex) { -+ -+#if CFG_SUPPORT_ADHOC -+ fgReplyProbeResp = aisValidateProbeReq(prAdapter, prSwRfb, &u4CtrlFlagsForProbeResp); -+#endif -+ } -+#if CFG_ENABLE_WIFI_DIRECT -+ else if ((prAdapter->fgIsP2PRegistered) && (NETWORK_TYPE_P2P_INDEX == eNetTypeIndex)) { -+ if (nicTxGetFreeCmdCount(prAdapter) > (CFG_TX_MAX_CMD_PKT_NUM / 2)) { -+ /* Resource margin is enough */ -+ fgReplyProbeResp = -+ p2pFuncValidateProbeReq(prAdapter, prSwRfb, &u4CtrlFlagsForProbeResp); -+ } -+ } -+#endif -+#if CFG_ENABLE_BT_OVER_WIFI -+ else if (NETWORK_TYPE_BOW_INDEX == eNetTypeIndex) -+ fgReplyProbeResp = bowValidateProbeReq(prAdapter, prSwRfb, &u4CtrlFlagsForProbeResp); -+#endif -+ -+ if (fgReplyProbeResp) { -+ if (nicTxGetFreeCmdCount(prAdapter) > (CFG_TX_MAX_CMD_PKT_NUM / 2)) { -+ /* Resource margin is enough */ -+ bssSendBeaconProbeResponse(prAdapter, eNetTypeIndex, prMgtHdr->aucSrcAddr, -+ u4CtrlFlagsForProbeResp); -+ } -+ } -+ } -+ -+ return WLAN_STATUS_SUCCESS; -+ -+} /* end of bssProcessProbeRequest() */ -+ -+#if 0 /* NOTE(Kevin): condition check should move to P2P_FSM.c */ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will process the Rx Probe Request Frame and then send -+* back the corresponding Probe Response Frame if the specified conditions -+* were matched. -+* -+* @param[in] prSwRfb Pointer to SW RFB data structure. -+* -+* @retval WLAN_STATUS_SUCCESS Always return success -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS bssProcessProbeRequest(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb) -+{ -+ P_WLAN_MAC_MGMT_HEADER_T prMgtHdr; -+ P_BSS_INFO_T prBssInfo; -+ P_IE_SSID_T prIeSsid = (P_IE_SSID_T) NULL; -+ P_IE_SUPPORTED_RATE_T prIeSupportedRate = (P_IE_SUPPORTED_RATE_T) NULL; -+ P_IE_EXT_SUPPORTED_RATE_T prIeExtSupportedRate = (P_IE_EXT_SUPPORTED_RATE_T) NULL; -+ PUINT_8 pucIE; -+ UINT_16 u2IELength; -+ UINT_16 u2Offset = 0; -+ UINT_8 aucBCBSSID[] = BC_BSSID; -+ ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex; -+ BOOLEAN fgReplyProbeResp; -+#if CFG_ENABLE_WIFI_DIRECT -+ BOOLEAN fgP2PTargetDeviceFound; -+ UINT_8 aucP2PWildcardSSID[] = P2P_WILDCARD_SSID; -+#endif -+ -+ ASSERT(prSwRfb); -+ -+ /* 4 <1> Parse Probe Req and Get SSID IE ptr */ -+ prMgtHdr = (P_WLAN_MAC_MGMT_HEADER_T) prSwRfb->pvHeader; -+ -+ u2IELength = prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen; -+ pucIE = (PUINT_8) ((UINT_32) prSwRfb->pvHeader + prSwRfb->u2HeaderLen); -+ -+ prIeSsid = (P_IE_SSID_T) NULL; -+ -+ IE_FOR_EACH(pucIE, u2IELength, u2Offset) { -+ switch (IE_ID(pucIE)) { -+ case ELEM_ID_SSID: -+ if ((!prIeSsid) && (IE_LEN(pucIE) <= ELEM_MAX_LEN_SSID)) -+ prIeSsid = (P_IE_SSID_T) pucIE; -+ break; -+ -+ case ELEM_ID_SUP_RATES: -+ /* NOTE(Kevin): Buffalo WHR-G54S's supported rate set IE exceed 8. -+ * IE_LEN(pucIE) == 12, "1(B), 2(B), 5.5(B), 6(B), 9(B), 11(B), -+ * 12(B), 18(B), 24(B), 36(B), 48(B), 54(B)" -+ */ -+ /* if (IE_LEN(pucIE) <= ELEM_MAX_LEN_SUP_RATES) { */ -+ if (IE_LEN(pucIE) <= RATE_NUM) -+ prIeSupportedRate = SUP_RATES_IE(pucIE); -+ break; -+ -+ case ELEM_ID_EXTENDED_SUP_RATES: -+ prIeExtSupportedRate = EXT_SUP_RATES_IE(pucIE); -+ break; -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ /* TODO: P2P IE & WCS IE parsing for P2P. */ -+ case ELEM_ID_P2P: -+ -+ break; -+#endif -+ -+ /* no default */ -+ } -+ } /* end of IE_FOR_EACH */ -+ -+ /* 4 <2> Check network conditions before reply Probe Response Frame (Consider Concurrent) */ -+ for (eNetTypeIndex = NETWORK_TYPE_AIS_INDEX; eNetTypeIndex < NETWORK_TYPE_INDEX_NUM; eNetTypeIndex++) { -+ -+ if (!IS_NET_ACTIVE(prAdapter, eNetTypeIndex)) -+ continue; -+ -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[eNetTypeIndex]); -+ -+ if (UNEQUAL_MAC_ADDR(aucBCBSSID, prMgtHdr->aucBSSID) && -+ UNEQUAL_MAC_ADDR(prBssInfo->aucBSSID, prMgtHdr->aucBSSID)) { -+ /* BSSID not Wildcard BSSID. */ -+ continue; -+ } -+ -+ fgReplyProbeResp = FALSE; -+ -+ if (NETWORK_TYPE_AIS_INDEX == eNetTypeIndex) { -+ -+ if (prBssInfo->eCurrentOPMode == OP_MODE_IBSS) { -+ -+ /* TODO(Kevin): Check if we are IBSS Master. */ -+ if (TRUE && prIeSsid) { -+ if ((prIeSsid->ucLength == BC_SSID_LEN) || /* WILDCARD SSID */ -+ EQUAL_SSID(prBssInfo->aucSSID, prBssInfo->ucSSIDLen, -+ prIeSsid->aucSSID, prIeSsid->ucLength)) { -+ fgReplyProbeResp = TRUE; -+ } -+ } -+ } -+ } -+#if CFG_ENABLE_WIFI_DIRECT -+ else if (NETWORK_TYPE_P2P_INDEX == eNetTypeIndex) { -+ -+ /* TODO(Kevin): Move following lines to p2p_fsm.c */ -+ -+ if ((prIeSsid) && -+ ((prIeSsid->ucLength == BC_SSID_LEN) || -+ (EQUAL_SSID(aucP2PWildcardSSID, -+ P2P_WILDCARD_SSID_LEN, prIeSsid->aucSSID, prIeSsid->ucLength)))) { -+ /* if (p2pFsmRunEventRxProbeRequestFrame(prAdapter, prMgtHdr->aucSrcAddr, -+ pucIE, u2IELength)) { */ -+ if (p2pFsmRunEventRxProbeRequestFrame(prAdapter, prSwRfb)) { -+ /* Extand channel request time & cancel scan request. */ -+ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; -+ -+ /* TODO: RX probe request may not caused by LISTEN state. */ -+ /* TODO: It can be GO. */ -+ /* Generally speaking, cancel a non-exist scan request is fine. -+ * We can check P2P FSM here for only LISTEN state. -+ */ -+ -+ P_MSG_SCN_SCAN_CANCEL prScanCancelMsg; -+ -+ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; -+ -+ /* Abort JOIN process. */ -+ prScanCancelMsg = -+ (P_MSG_SCN_SCAN_CANCEL) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, -+ sizeof(MSG_SCN_SCAN_CANCEL)); -+ if (!prScanCancelMsg) { -+ ASSERT(0); /* Can't abort SCN FSM */ -+ continue; -+ } -+ -+ prScanCancelMsg->rMsgHdr.eMsgId = MID_P2P_SCN_SCAN_CANCEL; -+ prScanCancelMsg->ucSeqNum = prP2pFsmInfo->ucSeqNumOfScnMsg; -+ prScanCancelMsg->ucNetTypeIndex = (UINT_8) NETWORK_TYPE_P2P_INDEX; -+ prScanCancelMsg->fgIsChannelExt = TRUE; -+ -+ mboxSendMsg(prAdapter, -+ MBOX_ID_0, (P_MSG_HDR_T) prScanCancelMsg, MSG_SEND_METHOD_BUF); -+ } -+ } else { -+ /* 1. Probe Request without SSID. -+ * 2. Probe Request with SSID not Wildcard SSID & not P2P Wildcard SSID. -+ */ -+ continue; -+ } -+ -+#if 0 /* Frog */ -+ if (prAdapter->rWifiVar.prP2pFsmInfo->eCurrentState == P2P_STATE_LISTEN) { -+ /* P2P 2.4.1 - P2P Devices shall not respond to Probe Request frames -+ which only contain 11b rates only. */ -+ if (prIeSupportedRate || prIeExtSupportedRate) { -+ UINT_16 u2OperationalRateSet, u2BSSBasicRateSet; -+ BOOLEAN fgIsUnknownBssBasicRate; -+ -+ rateGetRateSetFromIEs(prIeSupportedRate, prIeExtSupportedRate, -+ &u2OperationalRateSet, -+ &u2BSSBasicRateSet, /* Ignore any Basic Bit */ -+ &fgIsUnknownBssBasicRate); -+ -+ if (u2OperationalRateSet & ~RATE_SET_HR_DSSS) -+ continue; -+ } -+ } -+ /* TODO: Check channel time before first check point to: */ -+ /* If Target device is selected: -+ * 1. Send XXXX request frame. -+ * else -+ * 1. Send Probe Response frame. -+ */ -+ -+ if (prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT) { -+ /* TODO(Kevin): During PROVISION state, can we reply Probe Response ? */ -+ -+ /* TODO(Kevin): -+ * If we are GO, accept legacy client --> accept Wildcard SSID -+ * If we are in Listen State, accept only P2P Device --> check P2P IE and WPS IE -+ */ -+ if (TRUE /* We are GO */ && prIeSsid) { -+ UINT_8 aucSSID[] = P2P_WILDCARD_SSID; -+ -+ if ((prIeSsid->ucLength == BC_SSID_LEN) || /* WILDCARD SSID */ -+ EQUAL_SSID(prBssInfo->aucSSID, prBssInfo->ucSSIDLen, -+ prIeSsid->aucSSID, prIeSsid->ucLength) || -+ EQUAL_SSID(aucSSID, P2P_WILDCARD_SSID_LEN, -+ prIeSsid->aucSSID, prIeSsid->ucLength)) { -+ fgReplyProbeResp = TRUE; -+ } -+ } -+/* else if (FALSE) { */ /* We are in Listen State */ -+/* } */ -+ -+ /* TODO(Kevin): Check P2P IE and WPS IE */ -+ } -+#endif -+ } -+#endif -+#if CFG_ENABLE_BT_OVER_WIFI -+ else if (NETWORK_TYPE_BOW_INDEX == eNetTypeIndex) { -+ -+ if (prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT) { -+ /* Do nothing */ -+ /* TODO(Kevin): TBD */ -+ } -+ } -+#endif -+ else -+ ASSERT(eNetTypeIndex < NETWORK_TYPE_INDEX_NUM); -+ -+ if (fgReplyProbeResp) -+ bssSendBeaconProbeResponse(prAdapter, eNetTypeIndex, prMgtHdr->aucSrcAddr); -+ -+ } -+ -+ return WLAN_STATUS_SUCCESS; -+ -+} /* end of bssProcessProbeRequest() */ -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is used to clear the client list for AdHoc or AP Mode -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* @param[in] prBssInfo Given related BSS_INFO_T. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID bssClearClientList(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prBssInfo) -+{ -+ P_LINK_T prStaRecOfClientList; -+ -+ ASSERT(prBssInfo); -+ -+ prStaRecOfClientList = &prBssInfo->rStaRecOfClientList; -+ -+ if (!LINK_IS_EMPTY(prStaRecOfClientList)) { -+ P_STA_RECORD_T prPeerStaRec; -+ -+ LINK_FOR_EACH_ENTRY(prPeerStaRec, prStaRecOfClientList, rLinkEntry, STA_RECORD_T) { -+ cnmStaRecChangeState(prAdapter, prPeerStaRec, STA_STATE_1); -+ } -+ -+ LINK_INITIALIZE(prStaRecOfClientList); -+ } -+ -+} /* end of bssClearClientList() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is used to Add a STA_RECORD_T to the client list for AdHoc or AP Mode -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* @param[in] prBssInfo Given related BSS_INFO_T. -+* @param[in] prStaRec Pointer to the STA_RECORD_T -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID bssAddStaRecToClientList(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prBssInfo, IN P_STA_RECORD_T prStaRec) -+{ -+ P_LINK_T prStaRecOfClientList; -+ -+ ASSERT(prBssInfo); -+ -+ prStaRecOfClientList = &prBssInfo->rStaRecOfClientList; -+ -+ if (!LINK_IS_EMPTY(prStaRecOfClientList)) { -+ P_STA_RECORD_T prCurrStaRec; -+ -+ LINK_FOR_EACH_ENTRY(prCurrStaRec, prStaRecOfClientList, rLinkEntry, STA_RECORD_T) { -+ -+ if (prCurrStaRec == prStaRec) { -+ DBGLOG(BSS, WARN, -+ "Current Client List already contains that STA_RECORD_T[%pM]\n", -+ prStaRec->aucMacAddr); -+ return; -+ } -+ } -+ } -+ -+ LINK_INSERT_TAIL(prStaRecOfClientList, &prStaRec->rLinkEntry); -+ -+} /* end of bssAddStaRecToClientList() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is used to Remove a STA_RECORD_T from the client list for AdHoc or AP Mode -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* @param[in] prStaRec Pointer to the STA_RECORD_T -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID bssRemoveStaRecFromClientList(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prBssInfo, IN P_STA_RECORD_T prStaRec) -+{ -+ P_LINK_T prStaRecOfClientList; -+ -+ ASSERT(prBssInfo); -+ -+ prStaRecOfClientList = &prBssInfo->rStaRecOfClientList; -+ -+#if 0 -+ if (!LINK_IS_EMPTY(prStaRecOfClientList)) { -+ P_STA_RECORD_T prCurrStaRec; -+ -+ LINK_FOR_EACH_ENTRY(prCurrStaRec, prStaRecOfClientList, rLinkEntry, STA_RECORD_T) { -+ -+ if (prCurrStaRec == prStaRec) { -+ -+ LINK_REMOVE_KNOWN_ENTRY(prStaRecOfClientList, &prStaRec->rLinkEntry); -+ -+ return; -+ } -+ } -+ } -+#endif -+ if (!LINK_IS_EMPTY(prStaRecOfClientList)) { -+ -+ P_LINK_ENTRY_T prLinkEntry = (P_LINK_ENTRY_T) NULL; -+ -+ LINK_FOR_EACH(prLinkEntry, prStaRecOfClientList) { -+ if ((ULONG) prStaRec == (ULONG) prLinkEntry) { -+ LINK_REMOVE_KNOWN_ENTRY(prStaRecOfClientList, &prStaRec->rLinkEntry); -+ return; -+ } -+ } -+ } -+ -+ DBGLOG(BSS, INFO, "Current Client List didn't contain that STA_RECORD_T[%pM] before removing.\n", -+ prStaRec->aucMacAddr); -+ -+} /* end of bssRemoveStaRecFromClientList() */ -+#endif /* CFG_SUPPORT_ADHOC || CFG_SUPPORT_AAA */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Get station record by Address for AP mode -+* -+* @param[in] prBssInfo Pointer to BSS_INFO_T. -+* @param[in] pucMacAddr Pointer to target mac address -+* -+* @return pointer of STA_RECORD_T if found, otherwise, return NULL -+*/ -+/*----------------------------------------------------------------------------*/ -+ -+P_STA_RECORD_T bssGetClientByAddress(IN P_BSS_INFO_T prBssInfo, PUINT_8 pucMacAddr) -+{ -+ P_LINK_T prStaRecOfClientList; -+ -+ ASSERT(prBssInfo); -+ ASSERT(pucMacAddr); -+ -+ prStaRecOfClientList = &prBssInfo->rStaRecOfClientList; -+ if (!LINK_IS_EMPTY(prStaRecOfClientList)) { -+ P_STA_RECORD_T prCurrStaRec; -+ -+ LINK_FOR_EACH_ENTRY(prCurrStaRec, prStaRecOfClientList, rLinkEntry, STA_RECORD_T) { -+ if (EQUAL_MAC_ADDR(prCurrStaRec->aucMacAddr, pucMacAddr)) -+ return prCurrStaRec; -+ } -+ } -+ return NULL; -+} -+ -+#if CFG_SUPPORT_ADHOC -+/*----------------------------------------------------------------------------*/ -+/* Routines for IBSS(AdHoc) only */ -+/*----------------------------------------------------------------------------*/ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is used to process Beacons from current Ad-Hoc network peers. -+* We also process Beacons from other Ad-Hoc network during SCAN. If it has -+* the same SSID and we'll decide to merge into it if it has a larger TSF. -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* @param[in] prBssInfo Pointer to the BSS_INFO_T. -+* @param[in] prBSSDesc Pointer to the BSS Descriptor. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+ibssProcessMatchedBeacon(IN P_ADAPTER_T prAdapter, -+ IN P_BSS_INFO_T prBssInfo, IN P_BSS_DESC_T prBssDesc, IN UINT_8 ucRCPI) -+{ -+ P_STA_RECORD_T prStaRec = NULL; -+ -+ BOOLEAN fgIsCheckCapability = FALSE; -+ BOOLEAN fgIsCheckTSF = FALSE; -+ BOOLEAN fgIsGoingMerging = FALSE; -+ BOOLEAN fgIsSameBSSID; -+ -+ ASSERT(prBssInfo); -+ ASSERT(prBssDesc); -+ -+ /* 4 <1> Process IBSS Beacon only after we create or merge with other IBSS. */ -+ if (!prBssInfo->fgIsBeaconActivated) -+ return; -+ /* 4 <2> Get the STA_RECORD_T of TA. */ -+ prStaRec = cnmGetStaRecByAddress(prAdapter, (UINT_8) NETWORK_TYPE_AIS_INDEX, prBssDesc->aucSrcAddr); -+ -+ fgIsSameBSSID = UNEQUAL_MAC_ADDR(prBssInfo->aucBSSID, prBssDesc->aucBSSID) ? FALSE : TRUE; -+ -+ /* 4 <3> IBSS Merge Decision Flow for Processing Beacon. */ -+ if (fgIsSameBSSID) { -+ -+ /* Same BSSID: -+ * Case I. This is a new TA and it has decide to merged with us. -+ * a) If fgIsMerging == FALSE - we will send msg to notify AIS. -+ * b) If fgIsMerging == TRUE - already notify AIS. -+ * Case II. This is an old TA and we've already merged together. -+ */ -+ if (!prStaRec) { -+ -+ /* For Case I - Check this IBSS's capability first before adding this Sta Record. */ -+ fgIsCheckCapability = TRUE; -+ -+ /* If check is passed, then we perform merging with this new IBSS */ -+ fgIsGoingMerging = TRUE; -+ -+ } else { -+ -+ ASSERT((prStaRec->ucNetTypeIndex == NETWORK_TYPE_AIS_INDEX) && IS_ADHOC_STA(prStaRec)); -+ -+ if (prStaRec->ucStaState != STA_STATE_3) { -+ -+ if (!prStaRec->fgIsMerging) { -+ -+ /* For Case I - Check this IBSS's capability first -+ * before adding this Sta Record. */ -+ fgIsCheckCapability = TRUE; -+ -+ /* If check is passed, then we perform merging with this new IBSS */ -+ fgIsGoingMerging = TRUE; -+ } else { -+ /* For Case II - Update rExpirationTime of Sta Record */ -+ GET_CURRENT_SYSTIME(&prStaRec->rUpdateTime); -+ } -+ } else { -+ /* For Case II - Update rExpirationTime of Sta Record */ -+ GET_CURRENT_SYSTIME(&prStaRec->rUpdateTime); -+ } -+ -+ } -+ } else { -+ -+ /* Unequal BSSID: -+ * Case III. This is a new TA and we need to compare the TSF and get the winner. -+ * Case IV. This is an old TA and it merge into a new IBSS before we do the same thing. -+ * We need to compare the TSF to get the winner. -+ * Case V. This is an old TA and it restart a new IBSS. We also need to -+ * compare the TSF to get the winner. -+ */ -+ -+ /* For Case III, IV & V - We'll always check this new IBSS's capability first -+ * before merging into new IBSS. -+ */ -+ fgIsCheckCapability = TRUE; -+ -+ /* If check is passed, we need to perform TSF check to decide the major BSSID */ -+ fgIsCheckTSF = TRUE; -+ -+ /* For Case IV & V - We won't update rExpirationTime of Sta Record */ -+ } -+ -+ /* 4 <7> Check this BSS_DESC_T's capability. */ -+ if (fgIsCheckCapability) { -+ BOOLEAN fgIsCapabilityMatched = FALSE; -+ -+ do { -+ if (!(prBssDesc->ucPhyTypeSet & (prAdapter->rWifiVar.ucAvailablePhyTypeSet))) { -+ DBGLOG(BSS, LOUD, -+ "IBSS MERGE: Ignore Peer MAC: %pM - Unsupported Phy.\n", -+ prBssDesc->aucSrcAddr); -+ -+ break; -+ } -+ -+ if (prBssDesc->fgIsUnknownBssBasicRate) { -+ DBGLOG(BSS, LOUD, -+ "IBSS MERGE: Ignore Peer MAC: %pM - Unknown Basic Rate.\n", -+ prBssDesc->aucSrcAddr); -+ -+ break; -+ } -+ -+ if (ibssCheckCapabilityForAdHocMode(prAdapter, prBssDesc) == WLAN_STATUS_FAILURE) { -+ DBGLOG(BSS, LOUD, -+ "IBSS MERGE: Ignore Peer MAC: %pM - Capability is not matched.\n", -+ prBssDesc->aucSrcAddr); -+ -+ break; -+ } -+ -+ fgIsCapabilityMatched = TRUE; -+ } while (FALSE); -+ -+ if (!fgIsCapabilityMatched) { -+ -+ if (prStaRec) { -+ /* For Case II - We merge this STA_RECORD in RX Path. -+ * Case IV & V - They change their BSSID after we merge with them. -+ */ -+ -+ DBGLOG(BSS, LOUD, -+ "IBSS MERGE: Ignore Peer MAC: %pM - Capability is not matched.\n", -+ prBssDesc->aucSrcAddr); -+ } -+ -+ return; -+ } -+ -+ DBGLOG(BSS, LOUD, -+ "IBSS MERGE: Peer MAC: %pM - Check capability was passed.\n", -+ prBssDesc->aucSrcAddr); -+ } -+ -+ if (fgIsCheckTSF) { -+#if CFG_SLT_SUPPORT -+ fgIsGoingMerging = TRUE; -+#else -+ if (prBssDesc->fgIsLargerTSF) -+ fgIsGoingMerging = TRUE; -+ else -+ return; -+#endif -+ } -+ -+ if (fgIsGoingMerging) { -+ P_MSG_AIS_IBSS_PEER_FOUND_T prAisIbssPeerFoundMsg; -+ -+ /* 4 <1> We will merge with to this BSS immediately. */ -+ prBssDesc->fgIsConnecting = TRUE; -+ prBssDesc->fgIsConnected = FALSE; -+ -+ /* 4 <2> Setup corresponding STA_RECORD_T */ -+ prStaRec = bssCreateStaRecFromBssDesc(prAdapter, -+ STA_TYPE_ADHOC_PEER, NETWORK_TYPE_AIS_INDEX, prBssDesc); -+ -+ if (!prStaRec) { -+ /* no memory ? */ -+ return; -+ } -+ -+ prStaRec->fgIsMerging = TRUE; -+ -+ /* update RCPI */ -+ prStaRec->ucRCPI = ucRCPI; -+ -+ /* 4 <3> Send Merge Msg to CNM to obtain the channel privilege. */ -+ prAisIbssPeerFoundMsg = (P_MSG_AIS_IBSS_PEER_FOUND_T) -+ cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_AIS_IBSS_PEER_FOUND_T)); -+ -+ if (!prAisIbssPeerFoundMsg) { -+ -+ ASSERT(0); /* Can't send Merge Msg */ -+ return; -+ } -+ -+ prAisIbssPeerFoundMsg->rMsgHdr.eMsgId = MID_SCN_AIS_FOUND_IBSS; -+ prAisIbssPeerFoundMsg->ucNetTypeIndex = (UINT_8) NETWORK_TYPE_AIS_INDEX; -+ prAisIbssPeerFoundMsg->prStaRec = prStaRec; -+ -+ /* Inform AIS to do STATE TRANSITION -+ * For Case I - If AIS in IBSS_ALONE, let it jump to NORMAL_TR after we know the new member. -+ * For Case III, IV - Now this new BSSID wins the TSF, follow it. -+ */ -+ if (fgIsSameBSSID) { -+ prAisIbssPeerFoundMsg->fgIsMergeIn = TRUE; -+ } else { -+#if CFG_SLT_SUPPORT -+ prAisIbssPeerFoundMsg->fgIsMergeIn = TRUE; -+#else -+ prAisIbssPeerFoundMsg->fgIsMergeIn = (prBssDesc->fgIsLargerTSF) ? FALSE : TRUE; -+#endif -+ } -+ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prAisIbssPeerFoundMsg, MSG_SEND_METHOD_BUF); -+ -+ } -+ -+} /* end of ibssProcessMatchedBeacon() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will check the Capability for Ad-Hoc to decide if we are -+* able to merge with(same capability). -+* -+* @param[in] prBSSDesc Pointer to the BSS Descriptor. -+* -+* @retval WLAN_STATUS_FAILURE Can't pass the check of Capability. -+* @retval WLAN_STATUS_SUCCESS Pass the check of Capability. -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS ibssCheckCapabilityForAdHocMode(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBssDesc) -+{ -+ P_CONNECTION_SETTINGS_T prConnSettings; -+ WLAN_STATUS rStatus = WLAN_STATUS_FAILURE; -+ -+ ASSERT(prBssDesc); -+ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); -+ -+ do { -+ /* 4 <1> Check the BSS Basic Rate Set for current AdHoc Mode */ -+ if ((prConnSettings->eAdHocMode == AD_HOC_MODE_11B) && -+ (prBssDesc->u2BSSBasicRateSet & ~RATE_SET_HR_DSSS)) { -+ break; -+ } else if ((prConnSettings->eAdHocMode == AD_HOC_MODE_11A) && -+ (prBssDesc->u2BSSBasicRateSet & ~RATE_SET_OFDM)) { -+ break; -+ } -+ /* 4 <2> Check the Short Slot Time. */ -+#if 0 /* Do not check ShortSlotTime until Wi-Fi define such policy */ -+ if (prConnSettings->eAdHocMode == AD_HOC_MODE_11G) { -+ if (((prConnSettings->fgIsShortSlotTimeOptionEnable) && -+ !(prBssDesc->u2CapInfo & CAP_INFO_SHORT_SLOT_TIME)) || -+ (!(prConnSettings->fgIsShortSlotTimeOptionEnable) && -+ (prBssDesc->u2CapInfo & CAP_INFO_SHORT_SLOT_TIME))) { -+ break; -+ } -+ } -+#endif -+ -+ /* 4 <3> Check the ATIM window setting. */ -+ if (prBssDesc->u2ATIMWindow) { -+ DBGLOG(BSS, INFO, "AdHoc PS was not supported(ATIM Window: %d)\n", prBssDesc->u2ATIMWindow); -+ break; -+ } -+#if CFG_RSN_MIGRATION -+ /* 4 <4> Check the Security setting. */ -+ if (!rsnPerformPolicySelection(prAdapter, prBssDesc)) -+ break; -+#endif -+ -+ rStatus = WLAN_STATUS_SUCCESS; -+ } while (FALSE); -+ -+ return rStatus; -+ -+} /* end of ibssCheckCapabilityForAdHocMode() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will initial the BSS_INFO_T for IBSS Mode. -+* -+* @param[in] prBssInfo Pointer to the BSS_INFO_T. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID ibssInitForAdHoc(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prBssInfo) -+{ -+ UINT_8 ucLowestBasicRateIndex; -+ UINT_8 aucBSSID[MAC_ADDR_LEN]; -+ PUINT_16 pu2BSSID = (PUINT_16) &aucBSSID[0]; -+ UINT_32 i; -+ -+ ASSERT(prBssInfo); -+ ASSERT(prBssInfo->eCurrentOPMode == OP_MODE_IBSS); -+ -+ /* 4 <1> Setup PHY Attributes and Basic Rate Set/Operational Rate Set */ -+ prBssInfo->ucNonHTBasicPhyType = (UINT_8) -+ rNonHTAdHocModeAttributes[prBssInfo->ucConfigAdHocAPMode].ePhyTypeIndex; -+ prBssInfo->u2BSSBasicRateSet = rNonHTAdHocModeAttributes[prBssInfo->ucConfigAdHocAPMode].u2BSSBasicRateSet; -+ -+ prBssInfo->u2OperationalRateSet = rNonHTPhyAttributes[prBssInfo->ucNonHTBasicPhyType].u2SupportedRateSet; -+ -+ rateGetDataRatesFromRateSet(prBssInfo->u2OperationalRateSet, -+ prBssInfo->u2BSSBasicRateSet, -+ prBssInfo->aucAllSupportedRates, &prBssInfo->ucAllSupportedRatesLen); -+ -+ /* 4 <2> Setup BSSID */ -+ if (!prBssInfo->fgHoldSameBssidForIBSS) { -+ -+ for (i = 0; i < sizeof(aucBSSID) / sizeof(UINT_16); i++) -+ pu2BSSID[i] = (UINT_16) (kalRandomNumber() & 0xFFFF); -+ -+ aucBSSID[0] &= ~0x01; /* 7.1.3.3.3 - The individual/group bit of the address is set to 0. */ -+ aucBSSID[0] |= 0x02; /* 7.1.3.3.3 - The universal/local bit of the address is set to 1. */ -+ -+ COPY_MAC_ADDR(prBssInfo->aucBSSID, aucBSSID); -+ } -+ /* 4 <3> Setup Capability - Short Preamble */ -+ if (rNonHTPhyAttributes[prBssInfo->ucNonHTBasicPhyType].fgIsShortPreambleOptionImplemented && -+ ((prAdapter->rWifiVar.ePreambleType == PREAMBLE_TYPE_SHORT) || /* Short Preamble Option Enable is TRUE */ -+ (prAdapter->rWifiVar.ePreambleType == PREAMBLE_TYPE_AUTO))) { -+ prBssInfo->fgIsShortPreambleAllowed = TRUE; -+ prBssInfo->fgUseShortPreamble = TRUE; -+ } else { -+ prBssInfo->fgIsShortPreambleAllowed = FALSE; -+ prBssInfo->fgUseShortPreamble = FALSE; -+ } -+ -+ /* 4 <4> Setup Capability - Short Slot Time */ -+ /* 7.3.1.4 For IBSS, the Short Slot Time subfield shall be set to 0. */ -+ prBssInfo->fgUseShortSlotTime = FALSE; /* Set to FALSE for AdHoc */ -+ -+ /* 4 <5> Compoase Capability */ -+ prBssInfo->u2CapInfo = CAP_INFO_IBSS; -+ -+ if (prBssInfo->fgIsProtection) -+ prBssInfo->u2CapInfo |= CAP_INFO_PRIVACY; -+ -+ if (prBssInfo->fgIsShortPreambleAllowed) -+ prBssInfo->u2CapInfo |= CAP_INFO_SHORT_PREAMBLE; -+ -+ if (prBssInfo->fgUseShortSlotTime) -+ prBssInfo->u2CapInfo |= CAP_INFO_SHORT_SLOT_TIME; -+ /* 4 <6> Find Lowest Basic Rate Index for default TX Rate of MMPDU */ -+ rateGetLowestRateIndexFromRateSet(prBssInfo->u2BSSBasicRateSet, &ucLowestBasicRateIndex); -+ -+ prBssInfo->ucHwDefaultFixedRateCode = aucRateIndex2RateCode[PREAMBLE_DEFAULT_LONG_NONE][ucLowestBasicRateIndex]; -+ -+} /* end of ibssInitForAdHoc() */ -+ -+#endif /* CFG_SUPPORT_ADHOC */ -+ -+#if CFG_SUPPORT_AAA -+ -+/*----------------------------------------------------------------------------*/ -+/* Routines for BSS(AP) only */ -+/*----------------------------------------------------------------------------*/ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will initial the BSS_INFO_T for AP Mode. -+* -+* @param[in] prBssInfo Given related BSS_INFO_T. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID bssInitForAP(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prBssInfo, IN BOOLEAN fgIsRateUpdate) -+{ -+ UINT_8 ucLowestBasicRateIndex; -+ -+ P_AC_QUE_PARMS_T prACQueParms; -+ -+ ENUM_WMM_ACI_T eAci; -+ -+ UINT_8 auCWminLog2ForBcast[WMM_AC_INDEX_NUM] = { 4 /*BE*/, 4 /*BK*/, 3 /*VO*/, 2 /*VI*/ }; -+ UINT_8 auCWmaxLog2ForBcast[WMM_AC_INDEX_NUM] = { 10, 10, 4, 3 }; -+ UINT_8 auAifsForBcast[WMM_AC_INDEX_NUM] = { 3, 7, 2, 2 }; -+ UINT_8 auTxopForBcast[WMM_AC_INDEX_NUM] = { 0, 0, 94, 47 }; /* If the AP is OFDM */ -+ -+ UINT_8 auCWminLog2[WMM_AC_INDEX_NUM] = { 4 /*BE*/, 4 /*BK*/, 3 /*VO*/, 2 /*VI*/ }; -+ UINT_8 auCWmaxLog2[WMM_AC_INDEX_NUM] = { 7, 10, 4, 3 }; -+ UINT_8 auAifs[WMM_AC_INDEX_NUM] = { 3, 7, 1, 1 }; -+ UINT_8 auTxop[WMM_AC_INDEX_NUM] = { 0, 0, 94, 47 }; /* If the AP is OFDM */ -+ -+ DEBUGFUNC("bssInitForAP"); -+ DBGLOG(BSS, LOUD, "\n"); -+ -+ ASSERT(prBssInfo); -+ ASSERT((prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT) || (prBssInfo->eCurrentOPMode == OP_MODE_BOW)); -+ -+#if 0 -+ prAdapter->rWifiVar.rConnSettings.fgRxShortGIDisabled = TRUE; -+ prAdapter->rWifiVar.rConnSettings.uc2G4BandwidthMode = CONFIG_BW_20M; -+ prAdapter->rWifiVar.rConnSettings.uc5GBandwidthMode = CONFIG_BW_20M; -+#endif -+ -+ /* 4 <1> Setup PHY Attributes and Basic Rate Set/Operational Rate Set */ -+ prBssInfo->ucNonHTBasicPhyType = (UINT_8) -+ rNonHTApModeAttributes[prBssInfo->ucConfigAdHocAPMode].ePhyTypeIndex; -+ prBssInfo->u2BSSBasicRateSet = rNonHTApModeAttributes[prBssInfo->ucConfigAdHocAPMode].u2BSSBasicRateSet; -+ -+ prBssInfo->u2OperationalRateSet = rNonHTPhyAttributes[prBssInfo->ucNonHTBasicPhyType].u2SupportedRateSet; -+ -+ if (fgIsRateUpdate) { -+ rateGetDataRatesFromRateSet(prBssInfo->u2OperationalRateSet, -+ prBssInfo->u2BSSBasicRateSet, -+ prBssInfo->aucAllSupportedRates, &prBssInfo->ucAllSupportedRatesLen); -+ } -+ /* 4 <2> Setup BSSID */ -+ COPY_MAC_ADDR(prBssInfo->aucBSSID, prBssInfo->aucOwnMacAddr); -+ -+ /* 4 <3> Setup Capability - Short Preamble */ -+ if (rNonHTPhyAttributes[prBssInfo->ucNonHTBasicPhyType].fgIsShortPreambleOptionImplemented && -+ ((prAdapter->rWifiVar.ePreambleType == PREAMBLE_TYPE_SHORT) || /* Short Preamble Option Enable is TRUE */ -+ (prAdapter->rWifiVar.ePreambleType == PREAMBLE_TYPE_AUTO))) { -+ prBssInfo->fgIsShortPreambleAllowed = TRUE; -+ prBssInfo->fgUseShortPreamble = TRUE; -+ } else { -+ prBssInfo->fgIsShortPreambleAllowed = FALSE; -+ prBssInfo->fgUseShortPreamble = FALSE; -+ } -+ -+ /* 4 <4> Setup Capability - Short Slot Time */ -+ prBssInfo->fgUseShortSlotTime = TRUE; -+ -+ /* 4 <5> Compoase Capability */ -+ prBssInfo->u2CapInfo = CAP_INFO_ESS; -+ -+ if (prBssInfo->fgIsProtection) -+ prBssInfo->u2CapInfo |= CAP_INFO_PRIVACY; -+ -+ if (prBssInfo->fgIsShortPreambleAllowed) -+ prBssInfo->u2CapInfo |= CAP_INFO_SHORT_PREAMBLE; -+ -+ if (prBssInfo->fgUseShortSlotTime) -+ prBssInfo->u2CapInfo |= CAP_INFO_SHORT_SLOT_TIME; -+ /* 4 <6> Find Lowest Basic Rate Index for default TX Rate of MMPDU */ -+ rateGetLowestRateIndexFromRateSet(prBssInfo->u2BSSBasicRateSet, &ucLowestBasicRateIndex); -+ -+ prBssInfo->ucHwDefaultFixedRateCode = aucRateIndex2RateCode[PREAMBLE_DEFAULT_LONG_NONE][ucLowestBasicRateIndex]; -+ -+ /* 4 <7> Fill the EDCA */ -+ -+ prACQueParms = prBssInfo->arACQueParmsForBcast; -+ -+ for (eAci = 0; eAci < WMM_AC_INDEX_NUM; eAci++) { -+ -+ prACQueParms[eAci].fgIsACMSet = FALSE; -+ prACQueParms[eAci].u2Aifsn = auAifsForBcast[eAci]; -+ prACQueParms[eAci].u2CWmin = BIT(auCWminLog2ForBcast[eAci]) - 1; -+ prACQueParms[eAci].u2CWmax = BIT(auCWmaxLog2ForBcast[eAci]) - 1; -+ prACQueParms[eAci].u2TxopLimit = auTxopForBcast[eAci]; -+ -+ prBssInfo->aucCWminLog2ForBcast[eAci] = auCWminLog2ForBcast[eAci]; /* used to send WMM IE */ -+ prBssInfo->aucCWmaxLog2ForBcast[eAci] = auCWmaxLog2ForBcast[eAci]; -+ -+ DBGLOG(BSS, INFO, "Bcast: eAci = %d, ACM = %d, Aifsn = %d, CWmin = %d, CWmax = %d, TxopLimit = %d\n", -+ eAci, prACQueParms[eAci].fgIsACMSet, -+ prACQueParms[eAci].u2Aifsn, -+ prACQueParms[eAci].u2CWmin, -+ prACQueParms[eAci].u2CWmax, prACQueParms[eAci].u2TxopLimit); -+ -+ } -+ -+ prACQueParms = prBssInfo->arACQueParms; -+ -+ for (eAci = 0; eAci < WMM_AC_INDEX_NUM; eAci++) { -+ -+ prACQueParms[eAci].fgIsACMSet = FALSE; -+ prACQueParms[eAci].u2Aifsn = auAifs[eAci]; -+ prACQueParms[eAci].u2CWmin = BIT(auCWminLog2[eAci]) - 1; -+ prACQueParms[eAci].u2CWmax = BIT(auCWmaxLog2[eAci]) - 1; -+ prACQueParms[eAci].u2TxopLimit = auTxop[eAci]; -+ -+ DBGLOG(BSS, INFO, "eAci = %d, ACM = %d, Aifsn = %d, CWmin = %d, CWmax = %d, TxopLimit = %d\n", -+ eAci, prACQueParms[eAci].fgIsACMSet, -+ prACQueParms[eAci].u2Aifsn, -+ prACQueParms[eAci].u2CWmin, -+ prACQueParms[eAci].u2CWmax, prACQueParms[eAci].u2TxopLimit); -+ } -+ -+ /* Note: Caller should update the EDCA setting to HW by nicQmUpdateWmmParms() it there is no AIS network */ -+ /* Note: In E2, only 4 HW queues. The the Edca parameters should be folow by AIS network */ -+ /* Note: In E3, 8 HW queues. the Wmm parameters should be updated to right queues according to BSS */ -+ -+} /* end of bssInitForAP() */ -+ -+#if 0 -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Update DTIM Count -+* -+* @param[in] eNetTypeIndex Specify which network to update -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID bssUpdateDTIMCount(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex) -+{ -+ P_BSS_INFO_T prBssInfo; -+ -+ ASSERT(eNetTypeIndex < NETWORK_TYPE_INDEX_NUM); -+ -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[eNetTypeIndex]); -+ -+ if (prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT) { -+ -+ /* Setup DTIM Count for next TBTT. */ -+ if (prBssInfo->ucDTIMCount > 0) { -+ prBssInfo->ucDTIMCount--; -+ } else { -+ -+ ASSERT(prBssInfo->ucDTIMPeriod > 0); -+ -+ prBssInfo->ucDTIMCount = prBssInfo->ucDTIMPeriod - 1; -+ } -+ } -+ -+} /* end of bssUpdateDTIMIE() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is used to set the Virtual Bitmap in TIM Information Elements -+* -+* @param[in] prBssInfo Pointer to the BSS_INFO_T. -+* @param[in] u2AssocId The association id to set in Virtual Bitmap. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID bssSetTIMBitmap(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prBssInfo, IN UINT_16 u2AssocId) -+{ -+ -+ ASSERT(prBssInfo); -+ -+ if (prBssInfo->ucNetTypeIndex == NETWORK_TYPE_P2P_INDEX) { -+ P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo; -+ -+ prP2pSpecificBssInfo = &(prAdapter->rWifiVar.rP2pSpecificBssInfo); -+ -+ /* Use Association ID == 0 for BMCAST indication */ -+ if (u2AssocId == 0) { -+ -+ prP2pSpecificBssInfo->ucBitmapCtrl |= (UINT_8) BIT(0); -+ } else { -+ PUINT_8 pucPartialVirtualBitmap; -+ UINT_8 ucBitmapToSet; -+ -+ /* (u2AssocId / 8) */ -+ pucPartialVirtualBitmap = &prP2pSpecificBssInfo->aucPartialVirtualBitmap[(u2AssocId >> 3)]; -+ ucBitmapToSet = (UINT_8) BIT((u2AssocId % 8)); -+ -+ if (*pucPartialVirtualBitmap & ucBitmapToSet) { -+ /* The virtual bitmap has been set */ -+ return; -+ } -+ -+ *pucPartialVirtualBitmap |= ucBitmapToSet; -+ -+ /* Update u2SmallestAID and u2LargestAID */ -+ if ((u2AssocId < prP2pSpecificBssInfo->u2SmallestAID) || -+ (prP2pSpecificBssInfo->u2SmallestAID == 0)) { -+ prP2pSpecificBssInfo->u2SmallestAID = u2AssocId; -+ } -+ -+ if ((u2AssocId > prP2pSpecificBssInfo->u2LargestAID) || -+ (prP2pSpecificBssInfo->u2LargestAID == 0)) { -+ prP2pSpecificBssInfo->u2LargestAID = u2AssocId; -+ } -+ } -+ } -+ -+} /* end of bssSetTIMBitmap() */ -+#endif -+ -+#endif /* CFG_SUPPORT_AAA */ -+ -+VOID bssCreateStaRecFromAuth(IN P_ADAPTER_T prAdapter) -+{ -+ -+} -+ -+VOID bssUpdateStaRecFromAssocReq(IN P_ADAPTER_T prAdapter) -+{ -+ -+} -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/cnm.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/cnm.c -new file mode 100644 -index 000000000000..39af02df2af2 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/cnm.c -@@ -0,0 +1,738 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/cnm.c#2 -+*/ -+ -+/*! \file "cnm.c" -+ \brief Module of Concurrent Network Management -+ -+ Module of Concurrent Network Management -+*/ -+ -+/* -+** Log: cnm.c -+ * -+ * 07 17 2012 yuche.tsai -+ * NULL -+ * Compile no error before trial run. -+ * -+ * 11 15 2011 cm.chang -+ * NULL -+ * Fix possible wrong message when P2P is unregistered -+ * -+ * 11 14 2011 yuche.tsai -+ * [WCXRP00001107] [Volunteer Patch][Driver] Large Network Type index assert in FW issue. -+ * Fix large network type index assert in FW issue. -+ * -+ * 11 10 2011 cm.chang -+ * NULL -+ * Modify debug message for XLOG -+ * -+ * 11 08 2011 cm.chang -+ * NULL -+ * Add RLM and CNM debug message for XLOG -+ * -+ * 11 01 2011 cm.chang -+ * [WCXRP00001077] [All Wi-Fi][Driver] Fix wrong preferred channel for AP and BOW -+ * Only check AIS channel for P2P and BOW -+ * -+ * 10 25 2011 cm.chang -+ * [WCXRP00001058] [All Wi-Fi][Driver] Fix sta_rec's phyTypeSet and OBSS scan in AP mode -+ * Extension channel of some 5G AP will not follow regulation requirement -+ * -+ * 09 30 2011 cm.chang -+ * [WCXRP00001020] [MT6620 Wi-Fi][Driver] Handle secondary channel offset of AP in 5GHz band -+ * . -+ * -+ * 09 01 2011 cm.chang -+ * [WCXRP00000937] [MT6620 Wi-Fi][Driver][FW] cnm.c line #848 assert when doing monkey test -+ * Print message only in Linux platform for monkey testing -+ * -+ * 06 23 2011 cp.wu -+ * [WCXRP00000798] [MT6620 Wi-Fi][Firmware] Follow-ups for WAPI frequency offset workaround in firmware SCN module -+ * change parameter name from PeerAddr to BSSID -+ * -+ * 06 20 2011 cp.wu -+ * [WCXRP00000798] [MT6620 Wi-Fi][Firmware] Follow-ups for WAPI frequency offset workaround in firmware SCN module -+ * 1. specify target's BSSID when requesting channel privilege. -+ * 2. pass BSSID information to firmware domain -+ * -+ * 06 01 2011 cm.chang -+ * [WCXRP00000756] [MT6620 Wi-Fi][Driver] 1. AIS follow channel of BOW 2. Provide legal channel function -+ * Limit AIS to fixed channel same with BOW -+ * -+ * 04 12 2011 cm.chang -+ * [WCXRP00000634] [MT6620 Wi-Fi][Driver][FW] 2nd BSS will not support 40MHz bandwidth for concurrency -+ * . -+ * -+ * 03 10 2011 cm.chang -+ * [WCXRP00000358] [MT6620 Wi-Fi][Driver] Provide concurrent information for each module -+ * Check if P2P network index is Tethering AP -+ * -+ * 03 10 2011 cm.chang -+ * [WCXRP00000358] [MT6620 Wi-Fi][Driver] Provide concurrent information for each module -+ * Add some functions to let AIS/Tethering or AIS/BOW be the same channel -+ * -+ * 02 17 2011 cm.chang -+ * [WCXRP00000358] [MT6620 Wi-Fi][Driver] Provide concurrent information for each module -+ * When P2P registried, invoke BOW deactivate function -+ * -+ * 01 12 2011 cm.chang -+ * [WCXRP00000358] [MT6620 Wi-Fi][Driver] Provide concurrent information for each module -+ * Provide function to decide if BSS can be activated or not -+ * -+ * 12 07 2010 cm.chang -+ * [WCXRP00000239] MT6620 Wi-Fi][Driver][FW] Merge concurrent branch back to maintrunk -+ * 1. BSSINFO include RLM parameter -+ * 2. free all sta records when network is disconnected -+ * -+ * 12 07 2010 cm.chang -+ * [WCXRP00000238] MT6620 Wi-Fi][Driver][FW] Support regulation domain setting from NVRAM and supplicant -+ * 1. Country code is from NVRAM or supplicant -+ * 2. Change band definition in CMD/EVENT. -+ * -+ * 11 08 2010 cm.chang -+ * [WCXRP00000169] [MT6620 Wi-Fi][Driver][FW] Remove unused CNM recover message ID -+ * Remove CNM channel reover message ID -+ * -+ * 10 13 2010 cm.chang -+ * [WCXRP00000094] [MT6620 Wi-Fi][Driver] Connect to 2.4GHz AP, Driver crash. -+ * Add exception handle when cmd buffer is not available -+ * -+ * 08 24 2010 cm.chang -+ * NULL -+ * Support RLM initail channel of Ad-hoc, P2P and BOW -+ * -+ * 07 19 2010 wh.su -+ * -+ * update for security supporting. -+ * -+ * 07 19 2010 cm.chang -+ * -+ * Set RLM parameters and enable CNM channel manager -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 07 08 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Rename MID_MNY_CNM_CH_RELEASE to MID_MNY_CNM_CH_ABORT -+ * -+ * 07 01 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Fix wrong message ID for channel grant to requester -+ * -+ * 07 01 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Modify CNM message handler for new flow -+ * -+ * 06 07 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Set 20/40M bandwidth of AP HT OP before association process -+ * -+ * 05 31 2010 yarco.yang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Add RX TSF Log Feature and ADDBA Rsp with DECLINE handling -+ * -+ * 05 21 2010 yarco.yang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Support TCP/UDP/IP Checksum offload feature -+ * -+ * 05 12 2010 kevin.huang -+ * [BORA00000794][WIFISYS][New Feature]Power Management Support -+ * Add Power Management - Legacy PS-POLL support. -+ * -+ * 05 05 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Add a new function to send abort message -+ * -+ * 04 27 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * BMC mac address shall be ignored in basic config command -+ * -+ * 04 24 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * g_aprBssInfo[] depends on CFG_SUPPORT_P2P and CFG_SUPPORT_BOW -+ * -+ * 04 22 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Support change of MAC address by host command -+ * -+ * 04 16 2010 wh.su -+ * [BORA00000680][MT6620] Support the statistic for Micxxsoft os query -+ * adding the wpa-none for ibss beacon. -+ * -+ * 04 07 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Fix bug for OBSS scan -+ * -+ * 03 30 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Support 2.4G OBSS scan -+ * -+ * 03 16 2010 kevin.huang -+ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support -+ * Add AdHoc Mode -+ * -+ * 03 10 2010 kevin.huang -+ * [BORA00000654][WIFISYS][New Feature] CNM Module - Ch Manager Support -+ * -+ * * * * * * * * * * Add Channel Manager for arbitration of JOIN and SCAN Req -+ * -+ * 02 25 2010 wh.su -+ * [BORA00000605][WIFISYS] Phase3 Integration -+ * use the Rx0 dor event indicate. -+ * -+ * 02 08 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Support partial part about cmd basic configuration -+ * -+ * Dec 10 2009 mtk01104 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Remove conditional compiling FPGA_V5 -+ * -+ * Nov 18 2009 mtk01104 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Add function cnmFsmEventInit() -+ * -+ * Nov 2 2009 mtk01104 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * -+** -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "precomp.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is used to initialize variables in CNM_INFO_T. -+* -+* @param (none) -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID cnmInit(P_ADAPTER_T prAdapter) -+{ -+ -+} /* end of cnmInit() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is used to initialize variables in CNM_INFO_T. -+* -+* @param (none) -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID cnmUninit(P_ADAPTER_T prAdapter) -+{ -+ -+} /* end of cnmUninit() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Before handle the message from other module, it need to obtain -+* the Channel privilege from Channel Manager -+* -+* @param[in] prMsgHdr The message need to be handled. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID cnmChMngrRequestPrivilege(P_ADAPTER_T prAdapter, P_MSG_HDR_T prMsgHdr) -+{ -+ P_MSG_CH_REQ_T prMsgChReq; -+ P_CMD_CH_PRIVILEGE_T prCmdBody; -+ WLAN_STATUS rStatus; -+ -+ ASSERT(prAdapter); -+ ASSERT(prMsgHdr); -+ -+ prMsgChReq = (P_MSG_CH_REQ_T) prMsgHdr; -+ -+ prCmdBody = (P_CMD_CH_PRIVILEGE_T) -+ cnmMemAlloc(prAdapter, RAM_TYPE_BUF, sizeof(CMD_CH_PRIVILEGE_T)); -+ ASSERT(prCmdBody); -+ -+ /* To do: exception handle */ -+ if (!prCmdBody) { -+ DBGLOG(CNM, ERROR, "ChReq: fail to get buf (net=%d, token=%d)\n", -+ prMsgChReq->ucNetTypeIndex, prMsgChReq->ucTokenID); -+ -+ cnmMemFree(prAdapter, prMsgHdr); -+ return; -+ } -+ -+ DBGLOG(CNM, INFO, "ChReq net=%d token=%d b=%d c=%d s=%d\n", -+ prMsgChReq->ucNetTypeIndex, prMsgChReq->ucTokenID, -+ prMsgChReq->eRfBand, prMsgChReq->ucPrimaryChannel, prMsgChReq->eRfSco); -+ -+ prCmdBody->ucNetTypeIndex = prMsgChReq->ucNetTypeIndex; -+ prCmdBody->ucTokenID = prMsgChReq->ucTokenID; -+ prCmdBody->ucAction = CMD_CH_ACTION_REQ; /* Request */ -+ prCmdBody->ucPrimaryChannel = prMsgChReq->ucPrimaryChannel; -+ prCmdBody->ucRfSco = (UINT_8) prMsgChReq->eRfSco; -+ prCmdBody->ucRfBand = (UINT_8) prMsgChReq->eRfBand; -+ prCmdBody->ucReqType = (UINT_8) prMsgChReq->eReqType; -+ prCmdBody->ucReserved = 0; -+ prCmdBody->u4MaxInterval = prMsgChReq->u4MaxInterval; -+ COPY_MAC_ADDR(prCmdBody->aucBSSID, prMsgChReq->aucBSSID); -+ -+ ASSERT(prCmdBody->ucNetTypeIndex < NETWORK_TYPE_INDEX_NUM); -+ -+ /* For monkey testing 20110901 */ -+ if (prCmdBody->ucNetTypeIndex >= NETWORK_TYPE_INDEX_NUM) -+ DBGLOG(CNM, ERROR, "CNM: ChReq with wrong netIdx=%d\n\n", prCmdBody->ucNetTypeIndex); -+ -+ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ -+ CMD_ID_CH_PRIVILEGE, /* ucCID */ -+ TRUE, /* fgSetQuery */ -+ FALSE, /* fgNeedResp */ -+ FALSE, /* fgIsOid */ -+ NULL, /* pfCmdDoneHandler */ -+ NULL, /* pfCmdTimeoutHandler */ -+ sizeof(CMD_CH_PRIVILEGE_T), /* u4SetQueryInfoLen */ -+ (PUINT_8) prCmdBody, /* pucInfoBuffer */ -+ NULL, /* pvSetQueryBuffer */ -+ 0 /* u4SetQueryBufferLen */ -+ ); -+ -+ ASSERT(rStatus == WLAN_STATUS_PENDING); -+ -+ cnmMemFree(prAdapter, prCmdBody); -+ cnmMemFree(prAdapter, prMsgHdr); -+ -+} /* end of cnmChMngrRequestPrivilege() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Before deliver the message to other module, it need to release -+* the Channel privilege to Channel Manager. -+* -+* @param[in] prMsgHdr The message need to be delivered -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID cnmChMngrAbortPrivilege(P_ADAPTER_T prAdapter, P_MSG_HDR_T prMsgHdr) -+{ -+ P_MSG_CH_ABORT_T prMsgChAbort; -+ P_CMD_CH_PRIVILEGE_T prCmdBody; -+ WLAN_STATUS rStatus; -+ -+ ASSERT(prAdapter); -+ ASSERT(prMsgHdr); -+ -+ prMsgChAbort = (P_MSG_CH_ABORT_T) prMsgHdr; -+ -+ prCmdBody = (P_CMD_CH_PRIVILEGE_T) -+ cnmMemAlloc(prAdapter, RAM_TYPE_BUF, sizeof(CMD_CH_PRIVILEGE_T)); -+ ASSERT(prCmdBody); -+ -+ /* To do: exception handle */ -+ if (!prCmdBody) { -+ DBGLOG(CNM, ERROR, "ChAbort: fail to get buf (net=%d, token=%d)\n", -+ prMsgChAbort->ucNetTypeIndex, prMsgChAbort->ucTokenID); -+ -+ cnmMemFree(prAdapter, prMsgHdr); -+ return; -+ } -+ -+ DBGLOG(CNM, INFO, "ChAbort net=%d token=%d\n", prMsgChAbort->ucNetTypeIndex, prMsgChAbort->ucTokenID); -+ -+ prCmdBody->ucNetTypeIndex = prMsgChAbort->ucNetTypeIndex; -+ prCmdBody->ucTokenID = prMsgChAbort->ucTokenID; -+ prCmdBody->ucAction = CMD_CH_ACTION_ABORT; /* Abort */ -+ -+ ASSERT(prCmdBody->ucNetTypeIndex < NETWORK_TYPE_INDEX_NUM); -+ -+ /* For monkey testing 20110901 */ -+ if (prCmdBody->ucNetTypeIndex >= NETWORK_TYPE_INDEX_NUM) -+ DBGLOG(CNM, ERROR, "CNM: ChAbort with wrong netIdx=%d\n\n", prCmdBody->ucNetTypeIndex); -+ -+ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ -+ CMD_ID_CH_PRIVILEGE, /* ucCID */ -+ TRUE, /* fgSetQuery */ -+ FALSE, /* fgNeedResp */ -+ FALSE, /* fgIsOid */ -+ NULL, /* pfCmdDoneHandler */ -+ NULL, /* pfCmdTimeoutHandler */ -+ sizeof(CMD_CH_PRIVILEGE_T), /* u4SetQueryInfoLen */ -+ (PUINT_8) prCmdBody, /* pucInfoBuffer */ -+ NULL, /* pvSetQueryBuffer */ -+ 0 /* u4SetQueryBufferLen */ -+ ); -+ -+ ASSERT(rStatus == WLAN_STATUS_PENDING); -+ -+ cnmMemFree(prAdapter, prCmdBody); -+ cnmMemFree(prAdapter, prMsgHdr); -+ -+} /* end of cnmChMngrAbortPrivilege() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief -+* -+* @param (none) -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID cnmChMngrHandleChEvent(P_ADAPTER_T prAdapter, P_WIFI_EVENT_T prEvent) -+{ -+ P_EVENT_CH_PRIVILEGE_T prEventBody; -+ P_MSG_CH_GRANT_T prChResp; -+ -+ ASSERT(prAdapter); -+ ASSERT(prEvent); -+ -+ prEventBody = (P_EVENT_CH_PRIVILEGE_T) (prEvent->aucBuffer); -+ prChResp = (P_MSG_CH_GRANT_T) -+ cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_CH_GRANT_T)); -+ ASSERT(prChResp); -+ -+ /* To do: exception handle */ -+ if (!prChResp) { -+ DBGLOG(CNM, ERROR, "ChGrant: fail to get buf (net=%d, token=%d)\n", -+ prEventBody->ucNetTypeIndex, prEventBody->ucTokenID); -+ -+ return; -+ } -+ -+ DBGLOG(CNM, INFO, "ChGrant net=%d token=%d ch=%d sco=%d\n", -+ prEventBody->ucNetTypeIndex, prEventBody->ucTokenID, -+ prEventBody->ucPrimaryChannel, prEventBody->ucRfSco); -+ -+ ASSERT(prEventBody->ucNetTypeIndex < NETWORK_TYPE_INDEX_NUM); -+ ASSERT(prEventBody->ucStatus == EVENT_CH_STATUS_GRANT); -+ -+ /* Decide message ID based on network and response status */ -+ if (prEventBody->ucNetTypeIndex == NETWORK_TYPE_AIS_INDEX) -+ prChResp->rMsgHdr.eMsgId = MID_CNM_AIS_CH_GRANT; -+#if CFG_ENABLE_WIFI_DIRECT -+ else if ((prAdapter->fgIsP2PRegistered) && (prEventBody->ucNetTypeIndex == NETWORK_TYPE_P2P_INDEX)) -+ prChResp->rMsgHdr.eMsgId = MID_CNM_P2P_CH_GRANT; -+#endif -+#if CFG_ENABLE_BT_OVER_WIFI -+ else if (prEventBody->ucNetTypeIndex == NETWORK_TYPE_BOW_INDEX) -+ prChResp->rMsgHdr.eMsgId = MID_CNM_BOW_CH_GRANT; -+#endif -+ else { -+ cnmMemFree(prAdapter, prChResp); -+ return; -+ } -+ -+ prChResp->ucNetTypeIndex = prEventBody->ucNetTypeIndex; -+ prChResp->ucTokenID = prEventBody->ucTokenID; -+ prChResp->ucPrimaryChannel = prEventBody->ucPrimaryChannel; -+ prChResp->eRfSco = (ENUM_CHNL_EXT_T) prEventBody->ucRfSco; -+ prChResp->eRfBand = (ENUM_BAND_T) prEventBody->ucRfBand; -+ prChResp->eReqType = (ENUM_CH_REQ_TYPE_T) prEventBody->ucReqType; -+ prChResp->u4GrantInterval = prEventBody->u4GrantInterval; -+ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prChResp, MSG_SEND_METHOD_BUF); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is invoked for P2P or BOW networks -+* -+* @param (none) -+* -+* @return TRUE: suggest to adopt the returned preferred channel -+* FALSE: No suggestion. Caller should adopt its preference -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN -+cnmPreferredChannel(P_ADAPTER_T prAdapter, P_ENUM_BAND_T prBand, PUINT_8 pucPrimaryChannel, P_ENUM_CHNL_EXT_T prBssSCO) -+{ -+ P_BSS_INFO_T prBssInfo; -+ -+ ASSERT(prAdapter); -+ ASSERT(prBand); -+ ASSERT(pucPrimaryChannel); -+ ASSERT(prBssSCO); -+ -+ prBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]; -+ -+ if (RLM_NET_PARAM_VALID(prBssInfo)) { -+ *prBand = prBssInfo->eBand; -+ *pucPrimaryChannel = prBssInfo->ucPrimaryChannel; -+ *prBssSCO = prBssInfo->eBssSCO; -+ -+ return TRUE; -+ } -+ -+ return FALSE; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief -+* -+* @param (none) -+* -+* @return TRUE: available channel is limited to return value -+* FALSE: no limited -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN cnmAisInfraChannelFixed(P_ADAPTER_T prAdapter, P_ENUM_BAND_T prBand, PUINT_8 pucPrimaryChannel) -+{ -+#if CFG_ENABLE_WIFI_DIRECT || (CFG_ENABLE_BT_OVER_WIFI && CFG_BOW_LIMIT_AIS_CHNL) -+ P_BSS_INFO_T prBssInfo; -+#endif -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ if (IS_NET_ACTIVE(prAdapter, NETWORK_TYPE_P2P_INDEX) && p2pFuncIsAPMode(prAdapter->rWifiVar.prP2pFsmInfo)) { -+ -+ ASSERT(prAdapter->fgIsP2PRegistered); -+ -+ prBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]; -+ -+ *prBand = prBssInfo->eBand; -+ *pucPrimaryChannel = prBssInfo->ucPrimaryChannel; -+ -+ return TRUE; -+ } -+#endif -+ -+#if CFG_ENABLE_BT_OVER_WIFI && CFG_BOW_LIMIT_AIS_CHNL -+ if (IS_NET_ACTIVE(prAdapter, NETWORK_TYPE_BOW_INDEX)) { -+ -+ prBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_BOW_INDEX]; -+ -+ *prBand = prBssInfo->eBand; -+ *pucPrimaryChannel = prBssInfo->ucPrimaryChannel; -+ -+ return TRUE; -+ } -+#endif -+ -+ return FALSE; -+} -+ -+#if CFG_P2P_LEGACY_COEX_REVISE -+BOOLEAN cnmAisDetectP2PChannel(P_ADAPTER_T prAdapter, P_ENUM_BAND_T prBand, PUINT_8 pucPrimaryChannel) -+{ -+ P_WIFI_VAR_T prWifiVar = &prAdapter->rWifiVar; -+ P_BSS_INFO_T prP2PBssInfo = &prWifiVar->arBssInfo[NETWORK_TYPE_P2P_INDEX]; -+#if CFG_ENABLE_WIFI_DIRECT -+ if (IS_NET_ACTIVE(prAdapter, NETWORK_TYPE_P2P_INDEX) && -+ (prP2PBssInfo->eConnectionState == PARAM_MEDIA_STATE_CONNECTED || -+ (prP2PBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT && prP2PBssInfo->eIntendOPMode == OP_MODE_NUM))) { -+ *prBand = prP2PBssInfo->eBand; -+ *pucPrimaryChannel = prP2PBssInfo->ucPrimaryChannel; -+#if CFG_SUPPORT_MCC -+ if (nicFreq2ChannelNum(prWifiVar->rConnSettings.u4FreqInKHz * 1000) != *pucPrimaryChannel) { -+ DBGLOG(CNM, INFO, "p2p is running on Channel %d, but supplicant try to run as MCC\n", -+ *pucPrimaryChannel); -+ return FALSE; -+ } -+#endif -+ DBGLOG(CNM, INFO, "p2p is running on Channel %d, supplicant try to run as SCC\n", -+ *pucPrimaryChannel); -+ return TRUE; -+ } -+#endif -+ return FALSE; -+} -+#endif -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief -+* -+* @param (none) -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID cnmAisInfraConnectNotify(P_ADAPTER_T prAdapter) -+{ -+#if CFG_ENABLE_BT_OVER_WIFI -+ P_BSS_INFO_T prAisBssInfo, prBowBssInfo; -+ -+ prAisBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]; -+ prBowBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_BOW_INDEX]; -+ -+ if (RLM_NET_PARAM_VALID(prAisBssInfo) && RLM_NET_PARAM_VALID(prBowBssInfo)) { -+ if (prAisBssInfo->eBand != prBowBssInfo->eBand || -+ prAisBssInfo->ucPrimaryChannel != prBowBssInfo->ucPrimaryChannel) { -+ -+ /* Notify BOW to do deactivation */ -+ bowNotifyAllLinkDisconnected(prAdapter); -+ } -+ } -+#endif -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief -+* -+* @param (none) -+* -+* @return TRUE: permitted -+* FALSE: Not permitted -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN cnmAisIbssIsPermitted(P_ADAPTER_T prAdapter) -+{ -+#if CFG_ENABLE_WIFI_DIRECT -+ if (IS_NET_ACTIVE(prAdapter, NETWORK_TYPE_P2P_INDEX)) -+ return FALSE; -+#endif -+ -+#if CFG_ENABLE_BT_OVER_WIFI -+ if (IS_NET_ACTIVE(prAdapter, NETWORK_TYPE_BOW_INDEX)) -+ return FALSE; -+#endif -+ -+ return TRUE; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief -+* -+* @param (none) -+* -+* @return TRUE: permitted -+* FALSE: Not permitted -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN cnmP2PIsPermitted(P_ADAPTER_T prAdapter) -+{ -+ P_BSS_INFO_T prBssInfo; -+ -+ prBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]; -+ -+ if (IS_BSS_ACTIVE(prBssInfo) && prBssInfo->eCurrentOPMode == OP_MODE_IBSS) -+ return FALSE; -+#if CFG_ENABLE_BT_OVER_WIFI -+ if (IS_NET_ACTIVE(prAdapter, NETWORK_TYPE_BOW_INDEX)) { -+ /* Notify BOW to do deactivation */ -+ bowNotifyAllLinkDisconnected(prAdapter); -+ } -+#endif -+ -+ return TRUE; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief -+* -+* @param (none) -+* -+* @return TRUE: permitted -+* FALSE: Not permitted -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN cnmBowIsPermitted(P_ADAPTER_T prAdapter) -+{ -+ P_BSS_INFO_T prBssInfo; -+ -+ prBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]; -+ -+ if (IS_BSS_ACTIVE(prBssInfo) && prBssInfo->eCurrentOPMode == OP_MODE_IBSS) -+ return FALSE; -+#if CFG_ENABLE_WIFI_DIRECT -+ if (IS_NET_ACTIVE(prAdapter, NETWORK_TYPE_P2P_INDEX)) -+ return FALSE; -+#endif -+ -+ return TRUE; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief -+* -+* @param (none) -+* -+* @return TRUE: permitted -+* FALSE: Not permitted -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN cnmBss40mBwPermitted(P_ADAPTER_T prAdapter, ENUM_NETWORK_TYPE_INDEX_T eNetTypeIdx) -+{ -+ P_BSS_INFO_T prBssInfo; -+ UINT_8 i; -+ P_BSS_DESC_T prBssDesc = NULL; -+ -+ /* Note: To support real-time decision instead of current activated-time, -+ * the STA roaming case shall be considered about synchronization -+ * problem. Another variable fgAssoc40mBwAllowed is added to -+ * represent HT capability when association -+ */ -+ for (i = 0; i < NETWORK_TYPE_INDEX_NUM; i++) { -+ if (i != (UINT_8) eNetTypeIdx) { -+ prBssInfo = &prAdapter->rWifiVar.arBssInfo[i]; -+ -+ if (IS_BSS_ACTIVE(prBssInfo) && (prBssInfo->fg40mBwAllowed || prBssInfo->fgAssoc40mBwAllowed)) -+ return FALSE; -+ } -+ } -+ -+ if (eNetTypeIdx == NETWORK_TYPE_AIS_INDEX) -+ prBssDesc = prAdapter->rWifiVar.rAisFsmInfo.prTargetBssDesc; -+ else if ((eNetTypeIdx == NETWORK_TYPE_P2P_INDEX) && (prAdapter->rWifiVar.prP2pFsmInfo)) -+ prBssDesc = prAdapter->rWifiVar.prP2pFsmInfo->prTargetBss; -+ if (prBssDesc) { -+#if (CFG_FORCE_USE_20BW == 1) -+ if (prBssDesc->eBand == BAND_2G4) -+ return FALSE; -+#endif -+ if (prBssDesc->eSco == CHNL_EXT_SCN) -+ return FALSE; -+ } -+ -+ return TRUE; -+} -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/cnm_mem.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/cnm_mem.c -new file mode 100644 -index 000000000000..05bd0ff35f7a ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/cnm_mem.c -@@ -0,0 +1,1236 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/cnm_mem.c#2 -+*/ -+ -+/*! \file "cnm_mem.c" -+ \brief This file contain the management function of packet buffers and -+ generic memory alloc/free functioin for mailbox message. -+ -+ A data packet has a fixed size of buffer, but a management -+ packet can be equipped with a variable size of buffer. -+*/ -+ -+/* -+** Log: cnm_mem.c -+ * -+ * 07 17 2012 yuche.tsai -+ * NULL -+ * Compile no error before trial run. -+ * -+ * 03 14 2012 wh.su -+ * [WCXRP00001173] [MT6620 Wi-Fi][Driver] Adding the ICS Tethering WPA2-PSK supporting -+ * Add code from 2.2 -+ * -+ * 11 17 2011 tsaiyuan.hsu -+ * [WCXRP00001115] [MT6620 Wi-Fi][DRV] avoid deactivating staRec when changing state 3 to 3. -+ * initialize fgNeedResp. -+ * -+ * 11 17 2011 tsaiyuan.hsu -+ * [WCXRP00001115] [MT6620 Wi-Fi][DRV] avoid deactivating staRec when changing state 3 to 3. -+ * avoid deactivating staRec when changing state from 3 to 3. -+ * -+ * 02 01 2011 cm.chang -+ * [WCXRP00000415] [MT6620 Wi-Fi][Driver] Check if any memory leakage happens when uninitializing in DGB mode -+ * . -+ * -+ * 01 26 2011 cm.chang -+ * [WCXRP00000395] [MT6620 Wi-Fi][Driver][FW] Search STA_REC with additional net type index argument -+ * Allocate system RAM if fixed message or mgmt buffer is not available -+ * -+ * 01 26 2011 cm.chang -+ * [WCXRP00000395] [MT6620 Wi-Fi][Driver][FW] Search STA_REC with additional net type index argument -+ * . -+ * -+ * 01 25 2011 yuche.tsai -+ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record. -+ * Change Station Type in Station Record, Modify MACRO definition for getting station type & network type index & Role. -+ * -+ * 12 13 2010 cp.wu -+ * [WCXRP00000260] [MT6620 Wi-Fi][Driver][Firmware] Create V1.1 branch for both firmware and driver -+ * create branch for Wi-Fi driver v1.1 -+ * -+ * 12 07 2010 cm.chang -+ * [WCXRP00000239] MT6620 Wi-Fi][Driver][FW] Merge concurrent branch back to maintrunk -+ * 1. BSSINFO include RLM parameter -+ * 2. free all sta records when network is disconnected -+ * -+ * 11 29 2010 cm.chang -+ * [WCXRP00000210] [MT6620 Wi-Fi][Driver][FW] Set RCPI value in STA_REC -+ * for initial TX rate selection of auto-rate algorithm -+ * Sync RCPI of STA_REC to FW as reference of initial TX rate -+ * -+ * 11 25 2010 yuche.tsai -+ * NULL -+ * Update SLT Function for QoS Support and not be affected by fixed rate function. -+ * -+ * 10 18 2010 cp.wu -+ * [WCXRP00000053] [MT6620 Wi-Fi][Driver] Reset incomplete -+ * and might leads to BSOD when entering RF test with AIS associated -+ * 1. remove redundant variables in STA_REC structure -+ * 2. add STA-REC uninitialization routine for clearing pending events -+ * -+ * 10 13 2010 cm.chang -+ * [WCXRP00000094] [MT6620 Wi-Fi][Driver] Connect to 2.4GHz AP, Driver crash. -+ * Add exception handle when cmd buffer is not available -+ * -+ * 10 12 2010 cp.wu -+ * [WCXRP00000084] [MT6620 Wi-Fi][Driver][FW] Add fixed rate support for distance test -+ * add HT (802.11n) fixed rate support. -+ * -+ * 10 08 2010 cp.wu -+ * [WCXRP00000084] [MT6620 Wi-Fi][Driver][FW] Add fixed rate support for distance test -+ * adding fixed rate support for distance test. (from registry setting) -+ * -+ * 09 24 2010 wh.su -+ * NULL -+ * [WCXRP00005002][MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning. -+ * -+ * 09 21 2010 cp.wu -+ * [WCXRP00000053] [MT6620 Wi-Fi][Driver] Reset incomplete and might leads to BSOD -+ * when entering RF test with AIS associated -+ * Do a complete reset with STA-REC null checking for RF test re-entry -+ * -+ * 09 16 2010 cm.chang -+ * NULL -+ * Change conditional compiling options for BOW -+ * -+ * 09 10 2010 cm.chang -+ * NULL -+ * Always update Beacon content if FW sync OBSS info -+ * -+ * 08 24 2010 cm.chang -+ * NULL -+ * Support RLM initail channel of Ad-hoc, P2P and BOW -+ * -+ * 08 23 2010 chinghwa.yu -+ * NULL -+ * Update for BOW. -+ * -+ * 08 20 2010 cm.chang -+ * NULL -+ * Migrate RLM code to host from FW -+ * -+ * 08 19 2010 wh.su -+ * NULL -+ * adding the tx pkt call back handle for countermeasure. -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 07 08 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Check draft RLM code for HT cap -+ * -+ * 07 07 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Support state of STA record change from 1 to 1 -+ * -+ * 07 05 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Fix correct structure size in cnmStaSendDeactivateCmd() -+ * -+ * 07 05 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) ignore RSN checking when RSN is not turned on. -+ * 2) set STA-REC deactivation callback as NULL -+ * 3) add variable initialization API based on PHY configuration -+ * -+ * 07 02 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * spin lock target revised -+ * -+ * 07 02 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * change inner loop index from i to k. -+ * -+ * 07 01 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Support sync command of STA_REC -+ * -+ * 06 23 2010 yarco.yang -+ * [WPD00003837][MT6620]Data Path Refine -+ * Merge g_arStaRec[] into adapter->arStaRec[] -+ * -+ * 06 18 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Provide cnmMgtPktAlloc() and alloc/free function of msg/buf -+ * -+ * 05 31 2010 yarco.yang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Add RX TSF Log Feature and ADDBA Rsp with DECLINE handling -+ * -+ * 05 28 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Support checking of duplicated buffer free -+ * -+ * 05 28 2010 wh.su -+ * [BORA00000626][MT6620] Refine the remove key flow for WHQL testing -+ * fixed the ad-hoc wpa-none send non-encrypted frame issue. -+ * -+ * 05 28 2010 kevin.huang -+ * [BORA00000794][WIFISYS][New Feature]Power Management Support -+ * Move define of STA_REC_NUM to config.h and rename to CFG_STA_REC_NUM -+ * -+ * 05 12 2010 kevin.huang -+ * [BORA00000794][WIFISYS][New Feature]Power Management Support -+ * Add Power Management - Legacy PS-POLL support. -+ * -+ * 04 28 2010 tehuang.liu -+ * [BORA00000605][WIFISYS] Phase3 Integration -+ * Modified some MQM-related data structures (SN counter, TX/RX BA table) -+ * -+ * 04 27 2010 tehuang.liu -+ * [BORA00000605][WIFISYS] Phase3 Integration -+ * Added new TX/RX BA tables in STA_REC -+ * -+ * 04 27 2010 tehuang.liu -+ * [BORA00000605][WIFISYS] Phase3 Integration -+ * Notify MQM, TXM, and RXM upon disconnection . -+ * -+ * 04 26 2010 tehuang.liu -+ * [BORA00000605][WIFISYS] Phase3 Integration -+ * Call mqm, txm, rxm functions upon disconnection -+ * -+ * 04 24 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * g_aprBssInfo[] depends on CFG_SUPPORT_P2P and CFG_SUPPORT_BOW -+ * -+ * 04 22 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * First draft code to support protection in AP mode -+ * -+ * 04 19 2010 kevin.huang -+ * [BORA00000714][WIFISYS][New Feature]Beacon Timeout Support -+ * Add Beacon Timeout Support -+ * * * * * * * * * * and will send Null frame to diagnose connection -+ * -+ * 04 09 2010 tehuang.liu -+ * [BORA00000605][WIFISYS] Phase3 Integration -+ * [BORA00000644] WiFi phase 4 integration -+ * * Added per-TID SN cache in STA_REC -+ * -+ * 04 07 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Different invoking order for WTBL entry of associated AP -+ * -+ * 03 29 2010 wh.su -+ * [BORA00000605][WIFISYS] Phase3 Integration -+ * move the wlan table alloc / free to change state function. -+ * -+ * 03 24 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Support power control -+ * -+ * 03 03 2010 tehuang.liu -+ * [BORA00000569][WIFISYS] Phase 2 Integration Test -+ * Initialize StaRec->arStaWaitQueue -+ * -+ * 03 03 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Add debug message when no available pkt buffer -+ * -+ * 03 01 2010 tehuang.liu -+ * [BORA00000569][WIFISYS] Phase 2 Integration Test -+ * Fixed STA_REC initialization bug: prStaRec->au2CachedSeqCtrl[k] -+ * -+ * 02 26 2010 tehuang.liu -+ * [BORA00000569][WIFISYS] Phase 2 Integration Test -+ * Added fgIsWmmSupported in STA_RECORD_T. -+ * -+ * 02 26 2010 tehuang.liu -+ * [BORA00000569][WIFISYS] Phase 2 Integration Test -+ * Added fgIsUapsdSupported in STA_RECORD_T -+ * -+ * 02 26 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * add support of Driver STA_RECORD_T activation -+ * -+ * 02 13 2010 tehuang.liu -+ * [BORA00000569][WIFISYS] Phase 2 Integration Test -+ * Added arTspecTable in STA_REC for TSPEC management -+ * -+ * 02 12 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Enable mgmt buffer debug by default -+ * -+ * 02 12 2010 tehuang.liu -+ * [BORA00000569][WIFISYS] Phase 2 Integration Test -+ * Added BUFFER_SOURCE_BCN -+ * -+ * 02 04 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Add AAA Module Support, Revise Net Type to Net Type Index for array lookup -+ * -+ * 01 11 2010 kevin.huang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Add Deauth and Disassoc Handler -+ * -+ * 01 08 2010 cp.wu -+ * [BORA00000368]Integrate HIF part into BORA -+ * 1) separate wifi_var_emu.c/.h from wifi_var.c/.h -+ * * * * * * * * * 2) eliminate HIF_EMULATION code sections appeared in wifi_var/cnm_mem -+ * * * * * * * * * 3) use cnmMemAlloc() instead to allocate SRAM buffer -+ * -+ * 12 25 2009 tehuang.liu -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Integrated modifications for 1st connection (mainly on FW modules MQM, TXM, and RXM) -+ * * * * * * * MQM: BA handling -+ * * * * * * * TXM: Macros updates -+ * * * * * * * RXM: Macros/Duplicate Removal updates -+ * -+ * 12 24 2009 yarco.yang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * . -+ * -+ * 12 21 2009 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Support several data buffer banks. -+ * -+ * 12 18 2009 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * .For new FPGA memory size -+ * -+ * Dec 9 2009 MTK02468 -+ * [BORA00000337] To check in codes for FPGA emulation -+ * Removed DBGPRINT -+ * -+ * Dec 9 2009 mtk02752 -+ * [BORA00000368] Integrate HIF part into BORA -+ * add cnmDataPktFree() for emulation loopback purpose -+ * -+ * Dec 3 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Fix warning of null pointer -+ * -+ * Dec 3 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Add cnmGetStaRecByAddress() and add fgIsInUse flag in STA_RECORD_T -+ * -+ * Nov 23 2009 mtk01104 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Assign ucBufferSource in function cnmMgtPktAlloc() -+ * -+ * Nov 23 2009 mtk02468 -+ * [BORA00000337] To check in codes for FPGA emulation -+ * Added packet redispatch function calls -+ * -+ * Nov 13 2009 mtk01084 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * enable packet re-usable in current emulation driver -+ * -+ * Nov 12 2009 mtk01104 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * 1. Add new function cnmGetStaRecByIndex() -+ * 2. Rename STA_REC_T to STA_RECORD_T -+ * -+ * Nov 9 2009 mtk01104 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Call cnmDataPktDispatch() in cnmPktFree() -+ * -+ * Nov 2 2009 mtk01104 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Remove definition of pragma section code -+ * -+ * Oct 28 2009 mtk01104 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * -+ * -+ * Oct 23 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Fix lint warning -+ * -+ * Oct 23 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Fix typo -+ * -+ * Oct 12 2009 mtk01104 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * -+ * -+ * Oct 8 2009 mtk01104 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * -+** -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "precomp.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+static VOID cnmStaRecHandleEventPkt(P_ADAPTER_T prAdapter, P_CMD_INFO_T prCmdInfo, PUINT_8 pucEventBuf); -+ -+static VOID cnmStaSendUpdateCmd(P_ADAPTER_T prAdapter, P_STA_RECORD_T prStaRec, BOOLEAN fgNeedResp); -+ -+static VOID cnmStaSendRemoveCmd(P_ADAPTER_T prAdapter, P_STA_RECORD_T prStaRec); -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+P_MSDU_INFO_T cnmMgtPktAlloc(P_ADAPTER_T prAdapter, UINT_32 u4Length) -+{ -+ P_MSDU_INFO_T prMsduInfo; -+ P_QUE_T prQueList; -+ -+ KAL_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(prAdapter); -+ prQueList = &prAdapter->rTxCtrl.rFreeMsduInfoList; -+ -+ /* Get a free MSDU_INFO_T */ -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_MSDU_INFO_LIST); -+ QUEUE_REMOVE_HEAD(prQueList, prMsduInfo, P_MSDU_INFO_T); -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_MSDU_INFO_LIST); -+ -+ if (prMsduInfo) { -+ prMsduInfo->prPacket = cnmMemAlloc(prAdapter, RAM_TYPE_BUF, u4Length); -+ prMsduInfo->eSrc = TX_PACKET_MGMT; -+ -+ if (prMsduInfo->prPacket == NULL) { -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_MSDU_INFO_LIST); -+ QUEUE_INSERT_TAIL(prQueList, &prMsduInfo->rQueEntry); -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_MSDU_INFO_LIST); -+ prMsduInfo = NULL; -+ } -+ if (prMsduInfo) { -+ prMsduInfo->eCmdType = COMMAND_TYPE_NUM; -+ prMsduInfo->ucCID = 0xff; -+ prMsduInfo->u4InqueTime = 0; -+ prMsduInfo->ucPacketType = TX_PACKET_NUM; -+ } -+ } else { -+ P_QUE_T prTxingQue; -+ P_QUE_ENTRY_T prQueueEntry = (P_QUE_ENTRY_T) NULL; -+ P_MSDU_INFO_T prMsduInfo = (P_MSDU_INFO_T) NULL; -+ P_TX_TCQ_STATUS_T pTc = (P_TX_TCQ_STATUS_T) NULL; -+ -+ prTxingQue = &(prAdapter->rTxCtrl.rTxMgmtTxingQueue); -+ pTc = &(prAdapter->rTxCtrl.rTc); -+ -+ DBGLOG(MEM, LOUD, "++dump TxPendingMsdu=%u, Tc0=%d Tc1=%d Tc2=%d Tc3=%d, Tc4=%d Tc5=%d\n", -+ prTxingQue->u4NumElem, pTc->aucFreeBufferCount[TC0_INDEX], -+ pTc->aucFreeBufferCount[TC1_INDEX], pTc->aucFreeBufferCount[TC2_INDEX], -+ pTc->aucFreeBufferCount[TC3_INDEX], pTc->aucFreeBufferCount[TC4_INDEX], -+ pTc->aucFreeBufferCount[TC5_INDEX]); -+ -+ prQueueEntry = QUEUE_GET_HEAD(prTxingQue); -+ -+ while (prQueueEntry) { -+ prMsduInfo = (P_MSDU_INFO_T) prQueueEntry; -+ -+ DBGLOG(MEM, LOUD, -+ "msdu type=%u, ucid=%u, type=%d, time=%u, seq=%u, sta=%u\n", -+ prMsduInfo->ucPacketType, -+ prMsduInfo->ucCID, -+ prMsduInfo->eCmdType, -+ prMsduInfo->u4InqueTime, prMsduInfo->ucTxSeqNum, prMsduInfo->ucStaRecIndex); -+ prQueueEntry = QUEUE_GET_NEXT_ENTRY(prQueueEntry); -+ } -+ DBGLOG(MEM, LOUD, "--end dump\n"); -+ } -+ -+#if DBG -+ if (prMsduInfo == NULL) { -+ DBGLOG(MEM, WARN, "MgtDesc#=%u\n", prQueList->u4NumElem); -+ -+#if CFG_DBG_MGT_BUF -+ DBGLOG(MEM, WARN, "rMgtBufInfo: alloc#=%u, free#=%u, null#=%u\n", -+ prAdapter->rMgtBufInfo.u4AllocCount, -+ prAdapter->rMgtBufInfo.u4FreeCount, prAdapter->rMgtBufInfo.u4AllocNullCount); -+#endif -+ -+ DBGLOG(MEM, WARN, "\n"); -+ } -+#endif -+ -+ return prMsduInfo; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID cnmMgtPktFree(P_ADAPTER_T prAdapter, P_MSDU_INFO_T prMsduInfo) -+{ -+ P_QUE_T prQueList; -+ -+ KAL_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(prAdapter); -+ ASSERT(prMsduInfo); -+ -+ prQueList = &prAdapter->rTxCtrl.rFreeMsduInfoList; -+ -+ ASSERT(prMsduInfo->prPacket); -+ if (prMsduInfo->prPacket) { -+ cnmMemFree(prAdapter, prMsduInfo->prPacket); -+ prMsduInfo->prPacket = NULL; -+ } -+ -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_MSDU_INFO_LIST); -+ prMsduInfo->fgIsBasicRate = FALSE; -+ QUEUE_INSERT_TAIL(prQueList, &prMsduInfo->rQueEntry) -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_MSDU_INFO_LIST); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is used to initial the MGMT/MSG memory pool. -+* -+* \param (none) -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID cnmMemInit(P_ADAPTER_T prAdapter) -+{ -+ P_BUF_INFO_T prBufInfo; -+ -+ /* Initialize Management buffer pool */ -+ prBufInfo = &prAdapter->rMgtBufInfo; -+ kalMemZero(prBufInfo, sizeof(prAdapter->rMgtBufInfo)); -+ prBufInfo->pucBuf = prAdapter->pucMgtBufCached; -+ -+ /* Setup available memory blocks. 1 indicates FREE */ -+ prBufInfo->rFreeBlocksBitmap = (BUF_BITMAP) BITS(0, MAX_NUM_OF_BUF_BLOCKS - 1); -+ -+ /* Initialize Message buffer pool */ -+ prBufInfo = &prAdapter->rMsgBufInfo; -+ kalMemZero(prBufInfo, sizeof(prAdapter->rMsgBufInfo)); -+ prBufInfo->pucBuf = &prAdapter->aucMsgBuf[0]; -+ -+ /* Setup available memory blocks. 1 indicates FREE */ -+ prBufInfo->rFreeBlocksBitmap = (BUF_BITMAP) BITS(0, MAX_NUM_OF_BUF_BLOCKS - 1); -+ -+ return; -+ -+} /* end of cnmMemInit() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Allocate MGMT/MSG memory pool. -+* -+* \param[in] eRamType Target RAM type. -+* TCM blk_sz= 16bytes, BUF blk_sz= 256bytes -+* \param[in] u4Length Length of the buffer to allocate. -+* -+* \retval !NULL Pointer to the start address of allocated memory. -+* \retval NULL Fail to allocat memory -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT_32 u4MemAllocCnt = 0, u4MemFreeCnt = 0; -+PVOID cnmMemAlloc(IN P_ADAPTER_T prAdapter, IN ENUM_RAM_TYPE_T eRamType, IN UINT_32 u4Length) -+{ -+ P_BUF_INFO_T prBufInfo; -+ BUF_BITMAP rRequiredBitmap; -+ UINT_32 u4BlockNum; -+ UINT_32 i, u4BlkSzInPower; -+ PVOID pvMemory; -+ -+ KAL_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(prAdapter); -+ ASSERT(u4Length); -+ -+ u4MemAllocCnt++; -+ -+ if (eRamType == RAM_TYPE_MSG && u4Length <= 256) { -+ prBufInfo = &prAdapter->rMsgBufInfo; -+ u4BlkSzInPower = MSG_BUF_BLOCK_SIZE_IN_POWER_OF_2; -+ -+ u4Length += (MSG_BUF_BLOCK_SIZE - 1); -+ u4BlockNum = u4Length >> MSG_BUF_BLOCK_SIZE_IN_POWER_OF_2; -+ -+ ASSERT(u4BlockNum <= MAX_NUM_OF_BUF_BLOCKS); -+ } else { -+ eRamType = RAM_TYPE_BUF; -+ -+ prBufInfo = &prAdapter->rMgtBufInfo; -+ u4BlkSzInPower = MGT_BUF_BLOCK_SIZE_IN_POWER_OF_2; -+ -+ u4Length += (MGT_BUF_BLOCK_SIZE - 1); -+ u4BlockNum = u4Length >> MGT_BUF_BLOCK_SIZE_IN_POWER_OF_2; -+ -+ ASSERT(u4BlockNum <= MAX_NUM_OF_BUF_BLOCKS); -+ } -+ -+#if CFG_DBG_MGT_BUF -+ prBufInfo->u4AllocCount++; -+#endif -+ -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, eRamType == RAM_TYPE_MSG ? SPIN_LOCK_MSG_BUF : SPIN_LOCK_MGT_BUF); -+ -+ if ((u4BlockNum > 0) && (u4BlockNum <= MAX_NUM_OF_BUF_BLOCKS)) { -+ -+ /* Convert number of block into bit cluster */ -+ rRequiredBitmap = BITS(0, u4BlockNum - 1); -+ -+ for (i = 0; i <= (MAX_NUM_OF_BUF_BLOCKS - u4BlockNum); i++) { -+ -+ /* Have available memory blocks */ -+ if ((prBufInfo->rFreeBlocksBitmap & rRequiredBitmap) -+ == rRequiredBitmap) { -+ -+ /* Clear corresponding bits of allocated memory blocks */ -+ prBufInfo->rFreeBlocksBitmap &= ~rRequiredBitmap; -+ -+ /* Store how many blocks be allocated */ -+ prBufInfo->aucAllocatedBlockNum[i] = (UINT_8) u4BlockNum; -+ -+ KAL_RELEASE_SPIN_LOCK(prAdapter, -+ eRamType == RAM_TYPE_MSG ? SPIN_LOCK_MSG_BUF : SPIN_LOCK_MGT_BUF); -+ -+ /* Return the start address of allocated memory */ -+ return (PVOID) (prBufInfo->pucBuf + (i << u4BlkSzInPower)); -+ -+ } -+ -+ rRequiredBitmap <<= 1; -+ } -+ } -+ -+ KAL_RELEASE_SPIN_LOCK(prAdapter, eRamType == RAM_TYPE_MSG ? SPIN_LOCK_MSG_BUF : SPIN_LOCK_MGT_BUF); -+ -+ /* cannot move the allocation between spin_lock_irqsave and spin_unlock_irqrestore */ -+#ifdef LINUX -+ pvMemory = (PVOID) kalMemAlloc(u4Length, VIR_MEM_TYPE); -+ if (pvMemory) -+ kalMemZero(pvMemory, u4Length); -+#else -+ pvMemory = (PVOID) NULL; -+#endif -+ -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, eRamType == RAM_TYPE_MSG ? SPIN_LOCK_MSG_BUF : SPIN_LOCK_MGT_BUF); -+ -+#if CFG_DBG_MGT_BUF -+ prBufInfo->u4AllocNullCount++; -+ -+ if (pvMemory) -+ prAdapter->u4MemAllocDynamicCount++; -+#endif -+ -+ KAL_RELEASE_SPIN_LOCK(prAdapter, eRamType == RAM_TYPE_MSG ? SPIN_LOCK_MSG_BUF : SPIN_LOCK_MGT_BUF); -+ -+ return pvMemory; -+ -+} /* end of cnmMemAlloc() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Release memory to MGT/MSG memory pool. -+* -+* \param pucMemory Start address of previous allocated memory -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID cnmMemFree(IN P_ADAPTER_T prAdapter, IN PVOID pvMemory) -+{ -+ P_BUF_INFO_T prBufInfo; -+ UINT_32 u4BlockIndex; -+ BUF_BITMAP rAllocatedBlocksBitmap; -+ ENUM_RAM_TYPE_T eRamType; -+ -+ KAL_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(prAdapter); -+ ASSERT(pvMemory); -+ if (!pvMemory) -+ return; -+ -+ u4MemFreeCnt++; -+ -+ /* Judge it belongs to which RAM type */ -+ if (((ULONG) pvMemory >= (ULONG)&prAdapter->aucMsgBuf[0]) && -+ ((ULONG) pvMemory <= (ULONG)&prAdapter->aucMsgBuf[MSG_BUFFER_SIZE - 1])) { -+ -+ prBufInfo = &prAdapter->rMsgBufInfo; -+ u4BlockIndex = ((ULONG) pvMemory - (ULONG) prBufInfo->pucBuf) -+ >> MSG_BUF_BLOCK_SIZE_IN_POWER_OF_2; -+ ASSERT(u4BlockIndex < MAX_NUM_OF_BUF_BLOCKS); -+ eRamType = RAM_TYPE_MSG; -+ } else if (((ULONG) pvMemory >= (ULONG) prAdapter->pucMgtBufCached) && -+ ((ULONG) pvMemory <= ((ULONG) prAdapter->pucMgtBufCached + MGT_BUFFER_SIZE - 1))) { -+ prBufInfo = &prAdapter->rMgtBufInfo; -+ u4BlockIndex = ((ULONG) pvMemory - (ULONG) prBufInfo->pucBuf) -+ >> MGT_BUF_BLOCK_SIZE_IN_POWER_OF_2; -+ ASSERT(u4BlockIndex < MAX_NUM_OF_BUF_BLOCKS); -+ eRamType = RAM_TYPE_BUF; -+ } else { -+#ifdef LINUX -+ /* For Linux, it is supported because size is not needed */ -+ kalMemFree(pvMemory, VIR_MEM_TYPE, 0); -+#else -+ /* For Windows, it is not supported because of no size argument */ -+ ASSERT(0); -+#endif -+ -+#if CFG_DBG_MGT_BUF -+ prAdapter->u4MemFreeDynamicCount++; -+#endif -+ return; -+ } -+ -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, eRamType == RAM_TYPE_MSG ? SPIN_LOCK_MSG_BUF : SPIN_LOCK_MGT_BUF); -+ -+#if CFG_DBG_MGT_BUF -+ prBufInfo->u4FreeCount++; -+#endif -+ -+ /* Convert number of block into bit cluster */ -+ ASSERT(prBufInfo->aucAllocatedBlockNum[u4BlockIndex] > 0); -+ -+ rAllocatedBlocksBitmap = BITS(0, prBufInfo->aucAllocatedBlockNum[u4BlockIndex] - 1); -+ rAllocatedBlocksBitmap <<= u4BlockIndex; -+ -+ /* Clear saved block count for this memory segment */ -+ prBufInfo->aucAllocatedBlockNum[u4BlockIndex] = 0; -+ -+ /* Set corresponding bit of released memory block */ -+ prBufInfo->rFreeBlocksBitmap |= rAllocatedBlocksBitmap; -+ -+ KAL_RELEASE_SPIN_LOCK(prAdapter, eRamType == RAM_TYPE_MSG ? SPIN_LOCK_MSG_BUF : SPIN_LOCK_MGT_BUF); -+ -+ return; -+ -+} /* end of cnmMemFree() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID cnmStaRecInit(P_ADAPTER_T prAdapter) -+{ -+ P_STA_RECORD_T prStaRec; -+ UINT_16 i; -+ -+ for (i = 0; i < CFG_STA_REC_NUM; i++) { -+ prStaRec = &prAdapter->arStaRec[i]; -+ -+ prStaRec->ucIndex = (UINT_8) i; -+ prStaRec->fgIsInUse = FALSE; -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID cnmStaRecUninit(IN P_ADAPTER_T prAdapter) -+{ -+ P_STA_RECORD_T prStaRec; -+ UINT_16 i; -+ -+ for (i = 0; i < CFG_STA_REC_NUM; i++) { -+ prStaRec = &prAdapter->arStaRec[i]; -+ -+ if (prStaRec->fgIsInUse) -+ cnmStaRecFree(prAdapter, prStaRec, FALSE); -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+P_STA_RECORD_T cnmStaRecAlloc(P_ADAPTER_T prAdapter, UINT_8 ucNetTypeIndex) -+{ -+ P_STA_RECORD_T prStaRec; -+ UINT_16 i, k; -+ -+ ASSERT(prAdapter); -+ -+ for (i = 0; i < CFG_STA_REC_NUM; i++) { -+ prStaRec = &prAdapter->arStaRec[i]; -+ -+ if (!prStaRec->fgIsInUse) { -+ /*---- Initialize STA_REC_T here ----*/ -+ kalMemZero(prStaRec, sizeof(STA_RECORD_T)); -+ prStaRec->ucIndex = (UINT_8) i; -+ prStaRec->ucNetTypeIndex = ucNetTypeIndex; -+ prStaRec->fgIsInUse = TRUE; -+ -+ if (prStaRec->pucAssocReqIe) { -+ kalMemFree(prStaRec->pucAssocReqIe, VIR_MEM_TYPE, prStaRec->u2AssocReqIeLen); -+ prStaRec->pucAssocReqIe = NULL; -+ prStaRec->u2AssocReqIeLen = 0; -+ } -+ -+ /* Initialize the SN caches for duplicate detection */ -+ for (k = 0; k < TID_NUM + 1; k++) -+ prStaRec->au2CachedSeqCtrl[k] = 0xFFFF; -+ -+ /* Initialize SW TX queues in STA_REC */ -+ for (k = 0; k < STA_WAIT_QUEUE_NUM; k++) -+ LINK_INITIALIZE(&prStaRec->arStaWaitQueue[k]); -+ -+ /* Default enable TX/RX AMPDU */ -+ prStaRec->fgTxAmpduEn = TRUE; -+ prStaRec->fgRxAmpduEn = TRUE; -+ -+#if CFG_ENABLE_PER_STA_STATISTICS && CFG_ENABLE_PKT_LIFETIME_PROFILE -+ prStaRec->u4TotalTxPktsNumber = 0; -+ prStaRec->u4TotalTxPktsTime = 0; -+ prStaRec->u4MaxTxPktsTime = 0; -+#endif -+ -+ for (k = 0; k < NUM_OF_PER_STA_TX_QUEUES; k++) -+ QUEUE_INITIALIZE(&prStaRec->arTxQueue[k]); -+ -+ break; -+ } -+ } -+ -+ return (i < CFG_STA_REC_NUM) ? prStaRec : NULL; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID cnmStaRecFree(P_ADAPTER_T prAdapter, P_STA_RECORD_T prStaRec, BOOLEAN fgSyncToChip) -+{ -+ ASSERT(prAdapter); -+ ASSERT(prStaRec); -+ -+ /* To do: free related resources, e.g. timers, buffers, etc */ -+ cnmTimerStopTimer(prAdapter, &prStaRec->rTxReqDoneOrRxRespTimer); -+ prStaRec->fgTransmitKeyExist = FALSE; -+ prStaRec->fgSetPwrMgtBit = FALSE; -+ -+ if (prStaRec->pucAssocReqIe) { -+ kalMemFree(prStaRec->pucAssocReqIe, VIR_MEM_TYPE, prStaRec->u2AssocReqIeLen); -+ prStaRec->pucAssocReqIe = NULL; -+ prStaRec->u2AssocReqIeLen = 0; -+ } -+ -+ qmDeactivateStaRec(prAdapter, prStaRec->ucIndex); -+ -+ if (fgSyncToChip) -+ cnmStaSendRemoveCmd(prAdapter, prStaRec); -+ -+ prStaRec->fgIsInUse = FALSE; -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID cnmStaFreeAllStaByNetType(P_ADAPTER_T prAdapter, ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, BOOLEAN fgSyncToChip) -+{ -+ P_STA_RECORD_T prStaRec; -+ UINT_16 i; -+ -+ for (i = 0; i < CFG_STA_REC_NUM; i++) { -+ prStaRec = (P_STA_RECORD_T) &prAdapter->arStaRec[i]; -+ -+ if (prStaRec->fgIsInUse && prStaRec->ucNetTypeIndex == (UINT_8) eNetTypeIndex) -+ cnmStaRecFree(prAdapter, prStaRec, fgSyncToChip); -+ } /* end of for loop */ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+P_STA_RECORD_T cnmGetStaRecByIndex(P_ADAPTER_T prAdapter, UINT_8 ucIndex) -+{ -+ P_STA_RECORD_T prStaRec; -+ -+ ASSERT(prAdapter); -+ -+ prStaRec = (ucIndex < CFG_STA_REC_NUM) ? &prAdapter->arStaRec[ucIndex] : NULL; -+ -+ if (prStaRec && prStaRec->fgIsInUse == FALSE) -+ prStaRec = NULL; -+ -+ return prStaRec; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Get STA_RECORD_T by Peer MAC Address(Usually TA). -+* -+* @param[in] pucPeerMacAddr Given Peer MAC Address. -+* -+* @retval Pointer to STA_RECORD_T, if found. NULL, if not found -+*/ -+/*----------------------------------------------------------------------------*/ -+P_STA_RECORD_T cnmGetStaRecByAddress(P_ADAPTER_T prAdapter, UINT_8 ucNetTypeIndex, PUINT_8 pucPeerMacAddr) -+{ -+ P_STA_RECORD_T prStaRec; -+ UINT_16 i; -+ -+ ASSERT(prAdapter); -+ ASSERT(pucPeerMacAddr); -+ -+ for (i = 0; i < CFG_STA_REC_NUM; i++) { -+ prStaRec = &prAdapter->arStaRec[i]; -+ -+ if (prStaRec->fgIsInUse && -+ prStaRec->ucNetTypeIndex == ucNetTypeIndex && -+ EQUAL_MAC_ADDR(prStaRec->aucMacAddr, pucPeerMacAddr)) { -+ break; -+ } -+ } -+ -+ return (i < CFG_STA_REC_NUM) ? prStaRec : NULL; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Reset the Status and Reason Code Field to 0 of all Station Records for -+* the specified Network Type -+* -+* @param[in] eNetType Specify Network Type -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID cnmStaRecResetStatus(P_ADAPTER_T prAdapter, ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex) -+{ -+ cnmStaFreeAllStaByNetType(prAdapter, eNetTypeIndex, FALSE); -+ -+#if 0 -+ P_STA_RECORD_T prStaRec; -+ UINT_16 i; -+ -+ ASSERT(prAdapter); -+ -+ for (i = 0; i < CFG_STA_REC_NUM; i++) { -+ prStaRec = &prAdapter->arStaRec[i]; -+ -+ if (prStaRec->fgIsInUse) { -+ if ((NETWORK_TYPE_AIS_INDEX == eNetTypeIndex) && IS_STA_IN_AIS(prStaRec->eStaType)) { -+ -+ prStaRec->u2StatusCode = STATUS_CODE_SUCCESSFUL; -+ prStaRec->u2ReasonCode = REASON_CODE_RESERVED; -+ prStaRec->ucJoinFailureCount = 0; -+ prStaRec->fgTransmitKeyExist = FALSE; -+ -+ prStaRec->fgSetPwrMgtBit = FALSE; -+ } -+ -+ /* TODO(Kevin): For P2P and BOW */ -+ } -+ } -+ -+ return; -+#endif -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will change the ucStaState of STA_RECORD_T and also do -+* event indication to HOST to sync the STA_RECORD_T in driver. -+* -+* @param[in] prStaRec Pointer to the STA_RECORD_T -+* @param[in] u4NewState New STATE to change. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID cnmStaRecChangeState(P_ADAPTER_T prAdapter, P_STA_RECORD_T prStaRec, UINT_8 ucNewState) -+{ -+ BOOLEAN fgNeedResp; -+ -+ ASSERT(prAdapter); -+ ASSERT(prStaRec); -+ ASSERT(prStaRec->fgIsInUse); -+ -+ /* Do nothing when following state transitions happen, -+ * other 6 conditions should be sync to FW, including 1-->1, 3-->3 -+ */ -+ if ((ucNewState == STA_STATE_2 && prStaRec->ucStaState != STA_STATE_3) || -+ (ucNewState == STA_STATE_1 && prStaRec->ucStaState == STA_STATE_2)) { -+ prStaRec->ucStaState = ucNewState; -+ return; -+ } -+ -+ fgNeedResp = FALSE; -+ if (ucNewState == STA_STATE_3) { -+ secFsmEventStart(prAdapter, prStaRec); -+ if (ucNewState != prStaRec->ucStaState) -+ fgNeedResp = TRUE; -+ } else { -+ if (ucNewState != prStaRec->ucStaState && prStaRec->ucStaState == STA_STATE_3) -+ qmDeactivateStaRec(prAdapter, prStaRec->ucIndex); -+ fgNeedResp = FALSE; -+ } -+ prStaRec->ucStaState = ucNewState; -+ -+ cnmStaSendUpdateCmd(prAdapter, prStaRec, fgNeedResp); -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ /* To do: Confirm if it is invoked here or other location, but it should -+ * be invoked after state sync of STA_REC -+ * Update system operation parameters for AP mode -+ */ -+ if (prAdapter->fgIsP2PRegistered && (IS_STA_IN_P2P(prStaRec))) { -+ P_BSS_INFO_T prBssInfo; -+ -+ prBssInfo = &prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]; -+ -+ if (prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT) -+ rlmUpdateParamsForAP(prAdapter, prBssInfo, FALSE); -+ } -+#endif -+} -+ -+P_STA_RECORD_T -+cnmStaTheTypeGet(P_ADAPTER_T prAdapter, -+ ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, ENUM_STA_TYPE_T eStaType, UINT32 *pu4StartIdx) -+{ -+ P_STA_RECORD_T prStaRec = NULL; -+ UINT_16 i; -+ -+ for (i = *pu4StartIdx; i < CFG_STA_REC_NUM; i++) { -+ prStaRec = (P_STA_RECORD_T) &prAdapter->arStaRec[i]; -+ -+ if (prStaRec->fgIsInUse && -+ prStaRec->ucNetTypeIndex == (UINT_8) eNetTypeIndex && prStaRec->eStaType == eStaType) { -+ i++; -+ break; -+ } -+ -+ prStaRec = NULL; /* reset */ -+ } /* end of for loop */ -+ -+ *pu4StartIdx = i; -+ return prStaRec; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief -+* -+* @param[in] -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+static VOID cnmStaRecHandleEventPkt(P_ADAPTER_T prAdapter, P_CMD_INFO_T prCmdInfo, PUINT_8 pucEventBuf) -+{ -+ P_EVENT_ACTIVATE_STA_REC_T prEventContent; -+ P_STA_RECORD_T prStaRec; -+ -+ prEventContent = (P_EVENT_ACTIVATE_STA_REC_T) pucEventBuf; -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prEventContent->ucStaRecIdx); -+ -+ if (prStaRec && prStaRec->ucStaState == STA_STATE_3 && -+ !kalMemCmp(&prStaRec->aucMacAddr[0], &prEventContent->aucMacAddr[0], MAC_ADDR_LEN)) { -+ -+ qmActivateStaRec(prAdapter, prStaRec); -+ } -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief -+* -+* @param[in] -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+static VOID cnmStaSendUpdateCmd(P_ADAPTER_T prAdapter, P_STA_RECORD_T prStaRec, BOOLEAN fgNeedResp) -+{ -+ P_CMD_UPDATE_STA_RECORD_T prCmdContent; -+ WLAN_STATUS rStatus; -+ -+ ASSERT(prAdapter); -+ ASSERT(prStaRec); -+ ASSERT(prStaRec->fgIsInUse); -+ -+ /* To do: come out a mechanism to limit one STA_REC sync once for AP mode -+ * to avoid buffer empty case when many STAs are associated -+ * simultaneously. -+ */ -+ -+ /* To do: how to avoid 2 times of allocated memory. Use Stack? -+ * One is here, the other is in wlanSendQueryCmd() -+ */ -+ prCmdContent = cnmMemAlloc(prAdapter, RAM_TYPE_BUF, sizeof(CMD_UPDATE_STA_RECORD_T)); -+ ASSERT(prCmdContent); -+ -+ /* To do: exception handle */ -+ if (!prCmdContent) -+ return; -+ -+ prCmdContent->ucIndex = prStaRec->ucIndex; -+ prCmdContent->ucStaType = (UINT_8) prStaRec->eStaType; -+ kalMemCopy(&prCmdContent->aucMacAddr[0], &prStaRec->aucMacAddr[0], MAC_ADDR_LEN); -+ prCmdContent->u2AssocId = prStaRec->u2AssocId; -+ prCmdContent->u2ListenInterval = prStaRec->u2ListenInterval; -+ prCmdContent->ucNetTypeIndex = prStaRec->ucNetTypeIndex; -+ -+ prCmdContent->ucDesiredPhyTypeSet = prStaRec->ucDesiredPhyTypeSet; -+ prCmdContent->u2DesiredNonHTRateSet = prStaRec->u2DesiredNonHTRateSet; -+ prCmdContent->u2BSSBasicRateSet = prStaRec->u2BSSBasicRateSet; -+ prCmdContent->ucMcsSet = prStaRec->ucMcsSet; -+ prCmdContent->ucSupMcs32 = (UINT_8) prStaRec->fgSupMcs32; -+ prCmdContent->u2HtCapInfo = prStaRec->u2HtCapInfo; -+ prCmdContent->ucNeedResp = (UINT_8) fgNeedResp; -+ -+#if !CFG_SLT_SUPPORT -+ if (prAdapter->rWifiVar.eRateSetting != FIXED_RATE_NONE) { -+ /* override rate configuration */ -+ nicUpdateRateParams(prAdapter, -+ prAdapter->rWifiVar.eRateSetting, -+ &(prCmdContent->ucDesiredPhyTypeSet), -+ &(prCmdContent->u2DesiredNonHTRateSet), -+ &(prCmdContent->u2BSSBasicRateSet), -+ &(prCmdContent->ucMcsSet), -+ &(prCmdContent->ucSupMcs32), &(prCmdContent->u2HtCapInfo)); -+ } -+#endif -+ -+ prCmdContent->ucIsQoS = prStaRec->fgIsQoS; -+ prCmdContent->ucIsUapsdSupported = prStaRec->fgIsUapsdSupported; -+ prCmdContent->ucStaState = prStaRec->ucStaState; -+ -+ prCmdContent->ucAmpduParam = prStaRec->ucAmpduParam; -+ prCmdContent->u2HtExtendedCap = prStaRec->u2HtExtendedCap; -+ prCmdContent->u4TxBeamformingCap = prStaRec->u4TxBeamformingCap; -+ prCmdContent->ucAselCap = prStaRec->ucAselCap; -+ prCmdContent->ucRCPI = prStaRec->ucRCPI; -+ -+ prCmdContent->ucUapsdAc = prStaRec->ucBmpTriggerAC | (prStaRec->ucBmpDeliveryAC << 4); -+ prCmdContent->ucUapsdSp = prStaRec->ucUapsdSp; -+ -+ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ -+ CMD_ID_UPDATE_STA_RECORD, /* ucCID */ -+ TRUE, /* fgSetQuery */ -+ fgNeedResp, /* fgNeedResp */ -+ FALSE, /* fgIsOid */ -+ fgNeedResp ? cnmStaRecHandleEventPkt : NULL, NULL, /* pfCmdTimeoutHandler */ -+ sizeof(CMD_UPDATE_STA_RECORD_T), /* u4SetQueryInfoLen */ -+ (PUINT_8) prCmdContent, /* pucInfoBuffer */ -+ NULL, /* pvSetQueryBuffer */ -+ 0 /* u4SetQueryBufferLen */ -+ ); -+ -+ ASSERT(rStatus == WLAN_STATUS_PENDING); -+ -+ cnmMemFree(prAdapter, prCmdContent); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief -+* -+* @param[in] -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+static VOID cnmStaSendRemoveCmd(P_ADAPTER_T prAdapter, P_STA_RECORD_T prStaRec) -+{ -+ CMD_REMOVE_STA_RECORD_T rCmdContent; -+ WLAN_STATUS rStatus; -+ -+ ASSERT(prAdapter); -+ ASSERT(prStaRec); -+ -+ rCmdContent.ucIndex = prStaRec->ucIndex; -+ kalMemCopy(&rCmdContent.aucMacAddr[0], &prStaRec->aucMacAddr[0], MAC_ADDR_LEN); -+ -+ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ -+ CMD_ID_REMOVE_STA_RECORD, /* ucCID */ -+ TRUE, /* fgSetQuery */ -+ FALSE, /* fgNeedResp */ -+ FALSE, /* fgIsOid */ -+ NULL, /* pfCmdDoneHandler */ -+ NULL, /* pfCmdTimeoutHandler */ -+ sizeof(CMD_REMOVE_STA_RECORD_T), /* u4SetQueryInfoLen */ -+ (PUINT_8) &rCmdContent, /* pucInfoBuffer */ -+ NULL, /* pvSetQueryBuffer */ -+ 0 /* u4SetQueryBufferLen */ -+ ); -+ -+ ASSERT(rStatus == WLAN_STATUS_PENDING); -+} -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/cnm_timer.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/cnm_timer.c -new file mode 100644 -index 000000000000..8cc9ef9078fe ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/cnm_timer.c -@@ -0,0 +1,482 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/cnm_timer.c#1 -+*/ -+ -+/*! \file "cnm_timer.c" -+ \brief -+ -+*/ -+ -+/* -+** Log: cnm_timer.c -+ * -+ * 12 13 2011 cm.chang -+ * [WCXRP00001136] [All Wi-Fi][Driver] Add wake lock for pending timer -+ * Add wake lock if timer timeout value is smaller than 5 seconds -+ * -+ * 02 24 2011 cp.wu -+ * [WCXRP00000490] [MT6620 Wi-Fi][Driver][Win32] modify kalMsleep() implementation -+ * because NdisMSleep() won't sleep long enough for specified interval such as 500ms -+ * modify cnm_timer and hem_mbox APIs to be thread safe to ease invoking restrictions -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 08 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * cnm_timer has been migrated. -+ * -+ * 05 28 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Support sleep notification to host -+ * -+ * 05 19 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Add some checking assertions -+ * -+ * 04 24 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Return timer token back to COS when entering wait off state -+ * -+ * 01 11 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Remove compiling warning -+ * -+ * 01 08 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Support longer timeout interval to 45 days from 65secu1rwduu`wvpghlqg|fh+fmdkb -+ * -+ * 01 06 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Fix system time is 32KHz instead of 1ms -+ * -+ * 01 04 2010 tehuang.liu -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * For working out the first connection Chariot-verified version -+ * -+ * Dec 3 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Place rRootTimer.rNextExpiredSysTime = rExpiredSysTime; before set timer -+ * -+ * Oct 30 2009 mtk01104 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * In cnmTimerInitialize(), just stop timer if it was already created. -+ * -+ * Oct 30 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Move the external reference for Lint to precomp.h -+ * -+ * Oct 30 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Fix lint warning -+ * -+ * Oct 28 2009 mtk01104 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * -+** -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "precomp.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to set the time to do the time out check. -+* -+* \param[in] rTimeout Time out interval from current time. -+* -+* \retval TRUE Success. -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static BOOLEAN cnmTimerSetTimer(IN P_ADAPTER_T prAdapter, IN OS_SYSTIME rTimeout) -+{ -+ P_ROOT_TIMER prRootTimer; -+ BOOLEAN fgNeedWakeLock; -+ -+ ASSERT(prAdapter); -+ -+ prRootTimer = &prAdapter->rRootTimer; -+ -+ kalSetTimer(prAdapter->prGlueInfo, rTimeout); -+ -+ if (rTimeout <= SEC_TO_SYSTIME(WAKE_LOCK_MAX_TIME)) { -+ fgNeedWakeLock = TRUE; -+ -+ if (!prRootTimer->fgWakeLocked) { -+ KAL_WAKE_LOCK(prAdapter, &prRootTimer->rWakeLock); -+ prRootTimer->fgWakeLocked = TRUE; -+ } -+ } else { -+ fgNeedWakeLock = FALSE; -+ } -+ -+ return fgNeedWakeLock; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routines is called to initialize a root timer. -+* -+* \param[in] prAdapter -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID cnmTimerInitialize(IN P_ADAPTER_T prAdapter) -+{ -+ P_ROOT_TIMER prRootTimer; -+ -+ KAL_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(prAdapter); -+ -+ prRootTimer = &prAdapter->rRootTimer; -+ -+ /* Note: glue layer have configured timer */ -+ -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TIMER); -+ LINK_INITIALIZE(&prRootTimer->rLinkHead); -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TIMER); -+ -+ KAL_WAKE_LOCK_INIT(prAdapter, &prRootTimer->rWakeLock, "WLAN Timer"); -+ prRootTimer->fgWakeLocked = FALSE; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routines is called to destroy a root timer. -+* When WIFI is off, the token shall be returned back to system. -+* -+* \param[in] -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID cnmTimerDestroy(IN P_ADAPTER_T prAdapter) -+{ -+ P_ROOT_TIMER prRootTimer; -+ -+ KAL_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(prAdapter); -+ -+ prRootTimer = &prAdapter->rRootTimer; -+ -+ if (prRootTimer->fgWakeLocked) { -+ KAL_WAKE_UNLOCK(prAdapter, &prRootTimer->rWakeLock); -+ prRootTimer->fgWakeLocked = FALSE; -+ } -+ KAL_WAKE_LOCK_DESTROY(prAdapter, &prRootTimer->rWakeLock); -+ -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TIMER); -+ LINK_INITIALIZE(&prRootTimer->rLinkHead); -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TIMER); -+ -+ /* Note: glue layer will be responsible for timer destruction */ -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routines is called to initialize a timer. -+* -+* \param[in] prTimer Pointer to a timer structure. -+* \param[in] pfnFunc Pointer to the call back function. -+* \param[in] u4Data Parameter for call back function. -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID cnmTimerInitTimer(IN P_ADAPTER_T prAdapter, IN P_TIMER_T prTimer, IN PFN_MGMT_TIMEOUT_FUNC pfFunc, IN ULONG ulData) -+{ -+ ASSERT(prAdapter); -+ -+ ASSERT(prTimer); -+ -+#if DBG -+ /* Note: NULL function pointer is permitted for HEM POWER */ -+ if (pfFunc == NULL) -+ DBGLOG(CNM, WARN, "Init timer with NULL callback function!\n"); -+#endif -+ -+#if DBG -+ ASSERT(prAdapter->rRootTimer.rLinkHead.prNext); -+ { -+ P_LINK_T prTimerList; -+ P_LINK_ENTRY_T prLinkEntry; -+ P_TIMER_T prPendingTimer; -+ -+ prTimerList = &(prAdapter->rRootTimer.rLinkHead); -+ -+ LINK_FOR_EACH(prLinkEntry, prTimerList) { -+ prPendingTimer = LINK_ENTRY(prLinkEntry, TIMER_T, rLinkEntry); -+ ASSERT(prPendingTimer); -+ ASSERT(prPendingTimer != prTimer); -+ } -+ } -+#endif -+ -+ LINK_ENTRY_INITIALIZE(&prTimer->rLinkEntry); -+ -+ prTimer->pfMgmtTimeOutFunc = pfFunc; -+ prTimer->ulData = ulData; -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routines is called to stop a timer. -+* -+* \param[in] prTimer Pointer to a timer structure. -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+static VOID cnmTimerStopTimer_impl(IN P_ADAPTER_T prAdapter, IN P_TIMER_T prTimer, IN BOOLEAN fgAcquireSpinlock) -+{ -+ P_ROOT_TIMER prRootTimer; -+ -+ KAL_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(prAdapter); -+ ASSERT(prTimer); -+ -+ prRootTimer = &prAdapter->rRootTimer; -+ -+ if (fgAcquireSpinlock) -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TIMER); -+ -+ if (timerPendingTimer(prTimer)) { -+ LINK_REMOVE_KNOWN_ENTRY(&prRootTimer->rLinkHead, &prTimer->rLinkEntry); -+ -+ /* Reduce dummy timeout for power saving, especially HIF activity. -+ * If two or more timers exist and being removed timer is smallest, -+ * this dummy timeout will still happen, but it is OK. -+ */ -+ if (LINK_IS_EMPTY(&prRootTimer->rLinkHead)) { -+ kalCancelTimer(prAdapter->prGlueInfo); -+ -+ if (fgAcquireSpinlock && prRootTimer->fgWakeLocked) { -+ KAL_WAKE_UNLOCK(prAdapter, &prRootTimer->rWakeLock); -+ prRootTimer->fgWakeLocked = FALSE; -+ } -+ } -+ } -+ -+ if (fgAcquireSpinlock) -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TIMER); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routines is called to stop a timer. -+* -+* \param[in] prTimer Pointer to a timer structure. -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID cnmTimerStopTimer(IN P_ADAPTER_T prAdapter, IN P_TIMER_T prTimer) -+{ -+ ASSERT(prAdapter); -+ ASSERT(prTimer); -+ -+ cnmTimerStopTimer_impl(prAdapter, prTimer, TRUE); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routines is called to start a timer with wake_lock. -+* -+* \param[in] prTimer Pointer to a timer structure. -+* \param[in] u4TimeoutMs Timeout to issue the timer and call back function -+* (unit: ms). -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID cnmTimerStartTimer(IN P_ADAPTER_T prAdapter, IN P_TIMER_T prTimer, IN UINT_32 u4TimeoutMs) -+{ -+ P_ROOT_TIMER prRootTimer; -+ P_LINK_T prTimerList; -+ OS_SYSTIME rExpiredSysTime, rTimeoutSystime; -+ -+ KAL_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(prAdapter); -+ ASSERT(prTimer); -+ -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TIMER); -+ -+ prRootTimer = &prAdapter->rRootTimer; -+ prTimerList = &prRootTimer->rLinkHead; -+ -+ /* If timeout interval is larger than 1 minute, the mod value is set -+ * to the timeout value first, then per minutue. -+ */ -+ if (u4TimeoutMs > MSEC_PER_MIN) { -+ ASSERT(u4TimeoutMs <= ((UINT_32) 0xFFFF * MSEC_PER_MIN)); -+ -+ prTimer->u2Minutes = (UINT_16) (u4TimeoutMs / MSEC_PER_MIN); -+ u4TimeoutMs -= (prTimer->u2Minutes * MSEC_PER_MIN); -+ if (u4TimeoutMs == 0) { -+ u4TimeoutMs = MSEC_PER_MIN; -+ prTimer->u2Minutes--; -+ } -+ } else { -+ prTimer->u2Minutes = 0; -+ } -+ -+ /* The assertion check if MSEC_TO_SYSTIME() may be overflow. */ -+ ASSERT(u4TimeoutMs < (((UINT_32) 0x80000000 - MSEC_PER_SEC) / KAL_HZ)); -+ rTimeoutSystime = MSEC_TO_SYSTIME(u4TimeoutMs); -+ rExpiredSysTime = kalGetTimeTick() + rTimeoutSystime; -+ -+ /* If no timer pending or the fast time interval is used. */ -+ if (LINK_IS_EMPTY(prTimerList) || TIME_BEFORE(rExpiredSysTime, prRootTimer->rNextExpiredSysTime)) { -+ -+ prRootTimer->rNextExpiredSysTime = rExpiredSysTime; -+ cnmTimerSetTimer(prAdapter, rTimeoutSystime); -+ } -+ -+ /* Add this timer to checking list */ -+ prTimer->rExpiredSysTime = rExpiredSysTime; -+ -+ if (!timerPendingTimer(prTimer)) -+ LINK_INSERT_TAIL(prTimerList, &prTimer->rLinkEntry); -+ -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TIMER); -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routines is called to check the timer list. -+* -+* \param[in] -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID cnmTimerDoTimeOutCheck(IN P_ADAPTER_T prAdapter) -+{ -+ P_ROOT_TIMER prRootTimer; -+ P_LINK_T prTimerList; -+ P_LINK_ENTRY_T prLinkEntry; -+ P_TIMER_T prTimer; -+ OS_SYSTIME rCurSysTime; -+ PFN_MGMT_TIMEOUT_FUNC pfMgmtTimeOutFunc; -+ ULONG ulTimeoutData; -+ BOOLEAN fgNeedWakeLock; -+ -+ KAL_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(prAdapter); -+ -+ /* acquire spin lock */ -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TIMER); -+ -+ prRootTimer = &prAdapter->rRootTimer; -+ prTimerList = &prRootTimer->rLinkHead; -+ -+ rCurSysTime = kalGetTimeTick(); -+ -+ /* Set the permitted max timeout value for new one */ -+ prRootTimer->rNextExpiredSysTime = rCurSysTime + MGMT_MAX_TIMEOUT_INTERVAL; -+ -+ LINK_FOR_EACH(prLinkEntry, prTimerList) { -+ prTimer = LINK_ENTRY(prLinkEntry, TIMER_T, rLinkEntry); -+ ASSERT(prTimer); -+ -+ /* Check if this entry is timeout. */ -+ if (!TIME_BEFORE(rCurSysTime, prTimer->rExpiredSysTime)) { -+ cnmTimerStopTimer_impl(prAdapter, prTimer, FALSE); -+ -+ pfMgmtTimeOutFunc = prTimer->pfMgmtTimeOutFunc; -+ ulTimeoutData = prTimer->ulData; -+ -+ if (prTimer->u2Minutes > 0) { -+ prTimer->u2Minutes--; -+ prTimer->rExpiredSysTime = rCurSysTime + MSEC_TO_SYSTIME(MSEC_PER_MIN); -+ LINK_INSERT_TAIL(prTimerList, &prTimer->rLinkEntry); -+ } else if (pfMgmtTimeOutFunc) { -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TIMER); -+ (pfMgmtTimeOutFunc) (prAdapter, ulTimeoutData); -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TIMER); -+ } -+ -+ /* Search entire list again because of nest del and add timers -+ * and current MGMT_TIMER could be volatile after stopped -+ */ -+ prLinkEntry = (P_LINK_ENTRY_T) prTimerList; -+ -+ prRootTimer->rNextExpiredSysTime = rCurSysTime + MGMT_MAX_TIMEOUT_INTERVAL; -+ } else if (TIME_BEFORE(prTimer->rExpiredSysTime, prRootTimer->rNextExpiredSysTime)) { -+ prRootTimer->rNextExpiredSysTime = prTimer->rExpiredSysTime; -+ } -+ } /* end of for loop */ -+ -+ /* Setup the prNext timeout event. It is possible the timer was already -+ * set in the above timeout callback function. -+ */ -+ fgNeedWakeLock = FALSE; -+ if (!LINK_IS_EMPTY(prTimerList)) { -+ ASSERT(TIME_AFTER(prRootTimer->rNextExpiredSysTime, rCurSysTime)); -+ -+ fgNeedWakeLock = cnmTimerSetTimer(prAdapter, (OS_SYSTIME) -+ ((INT_32) prRootTimer->rNextExpiredSysTime - (INT_32) rCurSysTime)); -+ } -+ -+ if (prRootTimer->fgWakeLocked && !fgNeedWakeLock) { -+ KAL_WAKE_UNLOCK(prAdapter, &prRootTimer->rWakeLock); -+ prRootTimer->fgWakeLocked = FALSE; -+ } -+ -+ /* release spin lock */ -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TIMER); -+} -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/hem_mbox.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/hem_mbox.c -new file mode 100644 -index 000000000000..c7a23eb018b6 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/hem_mbox.c -@@ -0,0 +1,816 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/hem_mbox.c#3 -+*/ -+ -+/*! \file "hem_mbox.c" -+ \brief -+ -+*/ -+ -+/* -+** Log: hem_mbox.c -+** -+** 08 31 2012 yuche.tsai -+** [ALPS00349585] [6577JB][WiFi direct][KE]Establish p2p connection while both device -+** have connected to AP previously,one device reboots automatically with KE -+** Fix possible KE when concurrent & disconnect. -+** -+** 07 26 2012 yuche.tsai -+** [ALPS00324337] [ALPS.JB][Hot-Spot] Driver update for Hot-Spot -+** Update driver code of ALPS.JB for hot-spot. -+** -+** 07 19 2012 yuche.tsai -+** NULL -+** Code update for JB. -+ * -+ * 07 17 2012 yuche.tsai -+ * NULL -+ * Compile no error before trial run. -+ * -+ * 05 03 2012 cp.wu -+ * [WCXRP00001231] [MT6620 Wi-Fi][MT5931][Driver] Correct SCAN_V2 related debugging facilities within hem_mbox.c -+ * correct for debug message string table by adding missed scan_v2 related definitions. -+ * -+ * 03 02 2012 terry.wu -+ * NULL -+ * Sync CFG80211 modification from branch 2,2. -+ * -+ * 01 17 2012 yuche.tsai -+ * NULL -+ * Update mgmt frame filter setting. -+ * Please also update FW 2.1 -+ * -+ * 01 13 2012 yuche.tsai -+ * NULL -+ * WiFi Hot Spot Tethering for ICS ALPHA testing version. -+ * -+ * 11 24 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * Adjust code for DBG and CONFIG_XLOG. -+ * -+ * 11 15 2011 cm.chang -+ * NULL -+ * Add exception handle for NULL function pointer of mailbox message -+ * -+ * 11 11 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * modify the xlog related code. -+ * -+ * 11 02 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * adding the code for XLOG. -+ * -+ * 07 18 2011 cp.wu -+ * [WCXRP00000858] [MT5931][Driver][Firmware] Add support for scan to search -+ * for more than one SSID in a single scanning request -+ * add framework in driver domain for supporting new SCAN_REQ_V2 for more than 1 SSID support -+ * as well as uProbeDelay in NDIS 6.x driver model -+ * -+ * 06 07 2011 yuche.tsai -+ * [WCXRP00000696] [Volunteer Patch][MT6620][Driver] Infinite loop issue when RX invitation response. -+ * [WCXRP00000763] [Volunteer Patch][MT6620][Driver] RX Service Discovery Frame under AP mode Issue -+ * Add invitation support. -+ * -+ * 04 18 2011 terry.wu -+ * [WCXRP00000660] [MT6620 Wi-Fi][Driver] Remove flag CFG_WIFI_DIRECT_MOVED -+ * Remove flag CFG_WIFI_DIRECT_MOVED. -+ * -+ * 03 29 2011 cm.chang -+ * [WCXRP00000606] [MT6620 Wi-Fi][Driver][FW] Fix klocwork warning -+ * As CR title -+ * -+ * 02 24 2011 cp.wu -+ * [WCXRP00000490] [MT6620 Wi-Fi][Driver][Win32] modify kalMsleep() implementation -+ * because NdisMSleep() won't sleep long enough for specified interval such as 500ms -+ * modify cnm_timer and hem_mbox APIs to be thread safe to ease invoking restrictions -+ * -+ * 02 15 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Update bowString and channel grant. -+ * -+ * 01 26 2011 cm.chang -+ * [WCXRP00000395] [MT6620 Wi-Fi][Driver][FW] Search STA_REC with additional net type index argument -+ * Allocate system RAM if fixed message or mgmt buffer is not available -+ * -+ * 01 26 2011 yuche.tsai -+ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record. -+ * . -+ * -+ * 01 25 2011 yuche.tsai -+ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record. -+ * Fix Compile Error when DBG is disabled. -+ * -+ * 01 24 2011 cp.wu -+ * [WCXRP00000382] [MT6620 Wi-Fi][Driver] Track forwarding packet number with notifying tx thread for serving -+ * 1. add an extra counter for tracking pending forward frames. -+ * 2. notify TX service thread as well when there is pending forward frame -+ * 3. correct build errors leaded by introduction of Wi-Fi direct separation module -+ * -+ * 12 08 2010 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Support concurrent networks. -+ * -+ * 11 08 2010 cm.chang -+ * [WCXRP00000169] [MT6620 Wi-Fi][Driver][FW] Remove unused CNM recover message ID -+ * Remove CNM channel reover message ID -+ * -+ * 11 01 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000150] [MT6620 Wi-Fi][Driver] -+ * Add implementation for querying current TX rate from firmware auto rate module -+ * 1) Query link speed (TX rate) from firmware directly with buffering mechanism to reduce overhead -+ * 2) Remove CNM CH-RECOVER event handling -+ * 3) cfg read/write API renamed with kal prefix for unified naming rules. -+ * -+ * 10 08 2010 wh.su -+ * [WCXRP00000085] [MT6620 Wif-Fi] [Driver] update the modified p2p state machine -+ * update the frog's new p2p state machine. -+ * -+ * 09 28 2010 wh.su -+ * NULL -+ * [WCXRP00000069][MT6620 Wi-Fi][Driver] Fix some code for phase 1 P2P Demo. -+ * -+ * 09 16 2010 cm.chang -+ * NULL -+ * Remove unused message ID -+ * -+ * 08 30 2010 cp.wu -+ * NULL -+ * eliminate klockwork errors -+ * -+ * 08 26 2010 yuche.tsai -+ * NULL -+ * Add P2P Connection Abort Event Message handler. -+ * -+ * 08 25 2010 george.huang -+ * NULL -+ * update OID/ registry control path for PM related settings -+ * -+ * 08 24 2010 yarco.yang -+ * NULL -+ * Fixed Driver ASSERT at mboxInitMsgMap() -+ * -+ * 08 24 2010 chinghwa.yu -+ * NULL -+ * Update for MID_SCN_BOW_SCAN_DONE mboxDummy. -+ * Update saa_fsm for BOW. -+ * -+ * 08 23 2010 chinghwa.yu -+ * NULL -+ * Add CFG_ENABLE_BT_OVER_WIFI. -+ * -+ * 08 23 2010 chinghwa.yu -+ * NULL -+ * Update for BOW. -+ * -+ * 08 16 2010 cp.wu -+ * NULL -+ * add interface for RLM to trigger OBSS-SCAN. -+ * -+ * 08 16 2010 yuche.tsai -+ * NULL -+ * Add debug message for newly add P2P message. -+ * -+ * 08 11 2010 yuche.tsai -+ * NULL -+ * Add some function entry for P2P FSM under provisioning phase.. -+ * -+ * 08 11 2010 yuche.tsai -+ * NULL -+ * Add some events to P2P Module. -+ * -+ * 08 05 2010 yuche.tsai -+ * NULL -+ * Add message box event for P2P device switch on & device discovery. -+ * -+ * 08 04 2010 cp.wu -+ * NULL -+ * remove unused mailbox message definitions. -+ * -+ * 08 02 2010 yuche.tsai -+ * NULL -+ * P2P Group Negotiation Code Check in. -+ * -+ * 07 19 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration. -+ * message table should not be commented out by compilation option without modifying header file -+ * -+ * 07 19 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration. -+ * Add Ad-Hoc support to AIS-FSM -+ * -+ * 07 19 2010 yuche.tsai -+ * -+ * Add wifi direct scan done callback. -+ * -+ * 07 09 2010 cp.wu -+ * -+ * change handler of MID_MNY_CNM_CONNECTION_ABORT from NULL to mboxDummy. -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 07 08 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Rename MID_MNY_CNM_CH_RELEASE to MID_MNY_CNM_CH_ABORT -+ * -+ * 07 01 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * AIS-FSM integration with CNM channel request messages -+ * -+ * 07 01 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * implementation of DRV-SCN and related mailbox message handling. -+ * -+ * 07 01 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Modify CNM message handler for new flow -+ * -+ * 06 15 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * enable currently migrated message call-backs. -+ * -+ * 06 14 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * restore utility function invoking via hem_mbox to direct calls -+ * -+ * 06 10 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add buildable & linkable ais_fsm.c -+ * -+ * related reference are still waiting to be resolved -+ * -+ * 06 08 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * hem_mbox is migrated. -+ * -+ * 06 08 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add hem_mbox.c and cnm_mem.h (but disabled some feature) for further migration -+ * -+ * 05 12 2010 kevin.huang -+ * [BORA00000794][WIFISYS][New Feature]Power Management Support -+ * Fix file merge error -+ * -+ * 05 12 2010 kevin.huang -+ * [BORA00000794][WIFISYS][New Feature]Power Management Support -+ * Add Power Management - Legacy PS-POLL support. -+ * -+ * 04 29 2010 tehuang.liu -+ * [BORA00000605][WIFISYS] Phase3 Integration -+ * Removed MID_RXM_MQM_QOS_ACTION_FRAME -+ * -+ * 04 29 2010 tehuang.liu -+ * [BORA00000605][WIFISYS] Phase3 Integration -+ * Removed MID_RXM_MQM_BA_ACTION_FRAME -+ * -+ * 04 27 2010 tehuang.liu -+ * [BORA00000605][WIFISYS] Phase3 Integration -+ * MID_RXM_MQM_BA_ACTION_FRAME -+ * -+ * 03 30 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Support 2.4G OBSS scan -+ * -+ * 03 16 2010 kevin.huang -+ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support -+ * Add AdHoc Mode -+ * -+ * 03 10 2010 kevin.huang -+ * [BORA00000654][WIFISYS][New Feature] CNM Module - Ch Manager Support -+ * -+ * * * * * * * * * * * * * * Add Channel Manager for arbitration of JOIN and SCAN Req -+ * -+ * 03 05 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Develop partial DPD code -+ * -+ * 02 11 2010 tehuang.liu -+ * [BORA00000569][WIFISYS] Phase 2 Integration Test -+ * Updated arMsgMapTable for MID_RXM_MQM_QOS_ACTION_FRAME -+ * -+ * 01 11 2010 kevin.huang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Add Deauth and Disassoc Handler -+ * -+ * Dec 9 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Add hemRunEventScanDone() to arMsgMapTable[] -+ * -+ * Dec 4 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Fix mboxDummy() didn't free prMsgHdr -+ * -+ * Dec 3 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Add saaAisJoinComplete event handler -+ * -+ * Dec 2 2009 MTK02468 -+ * [BORA00000337] To check in codes for FPGA emulation -+ * Fixed the handler function name in arMsgMapTable for MID_RXM_MQM_BA_ACTION_FRAME -+ * -+ * Dec 2 2009 MTK02468 -+ * [BORA00000337] To check in codes for FPGA emulation -+ * Added MID_RXM_MQM_BA_ACTION_FRAME to MsgMapTable -+ * -+ * Nov 23 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Revise MSG Handler (remove dummy and add for SAA) -+ * -+ * Nov 16 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Add aisFsmRunEventAbort() event handler -+ * -+ * Nov 11 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Fix typo -+ * -+ * Nov 10 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Add more MSG_HNDL_ENTRY_T to avoid ASSERT() in mboxInitMsgMap() -+ * -+ * Nov 5 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Add SCN message and function entry to arMsgMapTable[] -+ * -+ * Nov 2 2009 mtk01104 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Fix sorting algorithm in mboxInitMsgMap() -+ * -+ * Oct 28 2009 mtk01104 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * -+** -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "precomp.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+#if DBG -+/*lint -save -e64 Type mismatch */ -+static PUINT_8 apucDebugMsg[] = { -+ (PUINT_8) DISP_STRING("MID_MNY_CNM_CH_REQ"), -+ (PUINT_8) DISP_STRING("MID_MNY_CNM_CH_ABORT"), -+ (PUINT_8) DISP_STRING("MID_CNM_AIS_CH_GRANT"), -+ (PUINT_8) DISP_STRING("MID_CNM_P2P_CH_GRANT"), -+ (PUINT_8) DISP_STRING("MID_CNM_BOW_CH_GRANT"), -+ -+ (PUINT_8) DISP_STRING("MID_AIS_SCN_SCAN_REQ"), -+ (PUINT_8) DISP_STRING("MID_AIS_SCN_SCAN_REQ_V2"), -+ (PUINT_8) DISP_STRING("MID_AIS_SCN_SCAN_CANCEL"), -+ (PUINT_8) DISP_STRING("MID_P2P_SCN_SCAN_REQ"), -+ (PUINT_8) DISP_STRING("MID_P2P_SCN_SCAN_REQ_V2"), -+ (PUINT_8) DISP_STRING("MID_P2P_SCN_SCAN_CANCEL"), -+ (PUINT_8) DISP_STRING("MID_BOW_SCN_SCAN_REQ"), -+ (PUINT_8) DISP_STRING("MID_BOW_SCN_SCAN_REQ_V2"), -+ (PUINT_8) DISP_STRING("MID_BOW_SCN_SCAN_CANCEL"), -+ (PUINT_8) DISP_STRING("MID_RLM_SCN_SCAN_REQ"), -+ (PUINT_8) DISP_STRING("MID_RLM_SCN_SCAN_REQ_V2"), -+ (PUINT_8) DISP_STRING("MID_RLM_SCN_SCAN_CANCEL"), -+ (PUINT_8) DISP_STRING("MID_SCN_AIS_SCAN_DONE"), -+ (PUINT_8) DISP_STRING("MID_SCN_P2P_SCAN_DONE"), -+ (PUINT_8) DISP_STRING("MID_SCN_BOW_SCAN_DONE"), -+ (PUINT_8) DISP_STRING("MID_SCN_RLM_SCAN_DONE"), -+ -+ (PUINT_8) DISP_STRING("MID_OID_AIS_FSM_JOIN_REQ"), -+ (PUINT_8) DISP_STRING("MID_OID_AIS_FSM_ABORT"), -+ (PUINT_8) DISP_STRING("MID_AIS_SAA_FSM_START"), -+ (PUINT_8) DISP_STRING("MID_AIS_SAA_FSM_ABORT"), -+ (PUINT_8) DISP_STRING("MID_SAA_AIS_JOIN_COMPLETE"), -+ -+#if CFG_ENABLE_BT_OVER_WIFI -+ (PUINT_8) DISP_STRING("MID_BOW_SAA_FSM_START"), -+ (PUINT_8) DISP_STRING("MID_BOW_SAA_FSM_ABORT"), -+ (PUINT_8) DISP_STRING("MID_SAA_BOW_JOIN_COMPLETE"), -+#endif -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ (PUINT_8) DISP_STRING("MID_P2P_SAA_FSM_START"), -+ (PUINT_8) DISP_STRING("MID_P2P_SAA_FSM_ABORT"), -+ (PUINT_8) DISP_STRING("MID_SAA_P2P_JOIN_COMPLETE"), -+ -+ (PUINT_8) DISP_STRING("MID_MNY_P2P_FUN_SWITCH"), -+ (PUINT_8) DISP_STRING("MID_MNY_P2P_DEVICE_DISCOVERY"), -+ (PUINT_8) DISP_STRING("MID_MNY_P2P_CONNECTION_REQ"), -+ (PUINT_8) DISP_STRING("MID_MNY_P2P_CONNECTION_ABORT"), -+ (PUINT_8) DISP_STRING("MID_MNY_P2P_BEACON_UPDATE"), -+ (PUINT_8) DISP_STRING("MID_MNY_P2P_STOP_AP"), -+ (PUINT_8) DISP_STRING("MID_MNY_P2P_CHNL_REQ"), -+ (PUINT_8) DISP_STRING("MID_MNY_P2P_CHNL_ABORT"), -+ (PUINT_8) DISP_STRING("MID_MNY_P2P_MGMT_TX"), -+ (PUINT_8) DISP_STRING("MID_MNY_P2P_GROUP_DISSOLVE"), -+ (PUINT_8) DISP_STRING("MID_MNY_P2P_MGMT_FRAME_REGISTER"), -+ (PUINT_8) DISP_STRING("MID_MNY_P2P_NET_DEV_REGISTER"), -+ (PUINT_8) DISP_STRING("MID_MNY_P2P_START_AP"), -+ (PUINT_8) DISP_STRING("MID_MNY_P2P_UPDATE_IE_BUF"), -+#endif -+ -+#if CFG_SUPPORT_ADHOC -+ /* (PUINT_8)DISP_STRING("MID_AIS_CNM_CREATE_IBSS_REQ"), */ -+ /* (PUINT_8)DISP_STRING("MID_CNM_AIS_CREATE_IBSS_GRANT"), */ -+ /* (PUINT_8)DISP_STRING("MID_AIS_CNM_MERGE_IBSS_REQ"), */ -+ /* (PUINT_8)DISP_STRING("MID_CNM_AIS_MERGE_IBSS_GRANT"), */ -+ (PUINT_8) DISP_STRING("MID_SCN_AIS_FOUND_IBSS"), -+#endif /* CFG_SUPPORT_ADHOC */ -+ -+ (PUINT_8) DISP_STRING("MID_SAA_AIS_FSM_ABORT"), -+ (PUINT_8) DISP_STRING("MID_MNY_AIS_REMAIN_ON_CHANNEL"), -+ (PUINT_8) DISP_STRING("MID_MNY_AIS_CANCEL_REMAIN_ON_CHANNEL"), -+ (PUINT_8) DISP_STRING("MID_MNY_AIS_MGMT_TX") -+}; -+ -+/*lint -restore */ -+#endif /* DBG */ -+ -+/* This message entry will be re-ordered based on the message ID order -+ * by invoking mboxInitMsgMap() -+ */ -+static MSG_HNDL_ENTRY_T arMsgMapTable[] = { -+ {MID_MNY_CNM_CH_REQ, cnmChMngrRequestPrivilege}, -+ {MID_MNY_CNM_CH_ABORT, cnmChMngrAbortPrivilege}, -+ {MID_CNM_AIS_CH_GRANT, aisFsmRunEventChGrant}, -+#if CFG_ENABLE_WIFI_DIRECT -+ {MID_CNM_P2P_CH_GRANT, p2pFsmRunEventChGrant}, /*set in gl_p2p_init.c */ -+#else -+ {MID_CNM_P2P_CH_GRANT, mboxDummy}, -+#endif -+ -+#if CFG_ENABLE_BT_OVER_WIFI -+ {MID_CNM_BOW_CH_GRANT, bowRunEventChGrant}, -+#else -+ {MID_CNM_BOW_CH_GRANT, mboxDummy}, -+#endif -+ -+ /*--------------------------------------------------*/ -+ /* SCN Module Mailbox Messages */ -+ /*--------------------------------------------------*/ -+ {MID_AIS_SCN_SCAN_REQ, scnFsmMsgStart}, -+ {MID_AIS_SCN_SCAN_REQ_V2, scnFsmMsgStart}, -+ {MID_AIS_SCN_SCAN_CANCEL, scnFsmMsgAbort}, -+ {MID_P2P_SCN_SCAN_REQ, scnFsmMsgStart}, -+ {MID_P2P_SCN_SCAN_REQ_V2, scnFsmMsgStart}, -+ {MID_P2P_SCN_SCAN_CANCEL, scnFsmMsgAbort}, -+ {MID_BOW_SCN_SCAN_REQ, scnFsmMsgStart}, -+ {MID_BOW_SCN_SCAN_REQ_V2, scnFsmMsgStart}, -+ {MID_BOW_SCN_SCAN_CANCEL, scnFsmMsgAbort}, -+ {MID_RLM_SCN_SCAN_REQ, scnFsmMsgStart}, -+ {MID_RLM_SCN_SCAN_REQ_V2, scnFsmMsgStart}, -+ {MID_RLM_SCN_SCAN_CANCEL, scnFsmMsgAbort}, -+ {MID_SCN_AIS_SCAN_DONE, aisFsmRunEventScanDone}, -+#if CFG_ENABLE_WIFI_DIRECT -+ {MID_SCN_P2P_SCAN_DONE, p2pFsmRunEventScanDone}, /*set in gl_p2p_init.c */ -+#else -+ {MID_SCN_P2P_SCAN_DONE, mboxDummy}, -+#endif -+ -+#if CFG_ENABLE_BT_OVER_WIFI -+ {MID_SCN_BOW_SCAN_DONE, bowResponderScanDone}, -+#else -+ {MID_SCN_BOW_SCAN_DONE, mboxDummy}, -+#endif -+ {MID_SCN_RLM_SCAN_DONE, rlmObssScanDone}, -+ -+ /*--------------------------------------------------*/ -+ /* AIS Module Mailbox Messages */ -+ /*--------------------------------------------------*/ -+ {MID_OID_AIS_FSM_JOIN_REQ, aisFsmRunEventAbort}, -+ {MID_OID_AIS_FSM_ABORT, aisFsmRunEventAbort}, -+ {MID_AIS_SAA_FSM_START, saaFsmRunEventStart}, -+ {MID_AIS_SAA_FSM_ABORT, saaFsmRunEventAbort}, -+ {MID_SAA_AIS_JOIN_COMPLETE, aisFsmRunEventJoinComplete}, -+ -+#if CFG_ENABLE_BT_OVER_WIFI -+ /*--------------------------------------------------*/ -+ /* BOW Module Mailbox Messages */ -+ /*--------------------------------------------------*/ -+ {MID_BOW_SAA_FSM_START, saaFsmRunEventStart}, -+ {MID_BOW_SAA_FSM_ABORT, saaFsmRunEventAbort}, -+ {MID_SAA_BOW_JOIN_COMPLETE, bowFsmRunEventJoinComplete}, -+#endif -+ -+#if CFG_ENABLE_WIFI_DIRECT /*set in gl_p2p_init.c */ -+ {MID_P2P_SAA_FSM_START, saaFsmRunEventStart}, -+ {MID_P2P_SAA_FSM_ABORT, saaFsmRunEventAbort}, -+ {MID_SAA_P2P_JOIN_COMPLETE, p2pFsmRunEventJoinComplete}, /* TODO: p2pFsmRunEventJoinComplete */ -+ -+ {MID_MNY_P2P_FUN_SWITCH, p2pFsmRunEventSwitchOPMode}, -+ {MID_MNY_P2P_DEVICE_DISCOVERY, p2pFsmRunEventScanRequest}, -+ {MID_MNY_P2P_CONNECTION_REQ, p2pFsmRunEventConnectionRequest}, -+ {MID_MNY_P2P_CONNECTION_ABORT, p2pFsmRunEventConnectionAbort}, -+ {MID_MNY_P2P_BEACON_UPDATE, p2pFsmRunEventBeaconUpdate}, -+ {MID_MNY_P2P_STOP_AP, p2pFsmRunEventStopAP}, -+ {MID_MNY_P2P_CHNL_REQ, p2pFsmRunEventChannelRequest}, -+ {MID_MNY_P2P_CHNL_ABORT, p2pFsmRunEventChannelAbort}, -+ {MID_MNY_P2P_MGMT_TX, p2pFsmRunEventMgmtFrameTx}, -+ {MID_MNY_P2P_GROUP_DISSOLVE, p2pFsmRunEventDissolve}, -+ {MID_MNY_P2P_MGMT_FRAME_REGISTER, p2pFsmRunEventMgmtFrameRegister}, -+ {MID_MNY_P2P_NET_DEV_REGISTER, p2pFsmRunEventNetDeviceRegister}, -+ {MID_MNY_P2P_START_AP, p2pFsmRunEventStartAP}, -+ {MID_MNY_P2P_MGMT_FRAME_UPDATE, p2pFsmRunEventUpdateMgmtFrame}, -+ {MID_MNY_P2P_EXTEND_LISTEN_INTERVAL, p2pFsmRunEventExtendListen}, -+#if CFG_SUPPORT_WFD -+ {MID_MNY_P2P_WFD_CFG_UPDATE, p2pFsmRunEventWfdSettingUpdate}, -+#endif -+ -+#endif -+ -+#if CFG_SUPPORT_ADHOC -+ {MID_SCN_AIS_FOUND_IBSS, aisFsmRunEventFoundIBSSPeer}, -+#endif /* CFG_SUPPORT_ADHOC */ -+ -+ {MID_SAA_AIS_FSM_ABORT, aisFsmRunEventAbort}, -+ {MID_MNY_AIS_REMAIN_ON_CHANNEL, aisFsmRunEventRemainOnChannel}, -+ {MID_MNY_AIS_CANCEL_REMAIN_ON_CHANNEL, aisFsmRunEventCancelRemainOnChannel}, -+ {MID_MNY_AIS_MGMT_TX, aisFsmRunEventMgmtFrameTx} -+}; -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+#if DBG -+#define MBOX_HNDL_MSG(prAdapter, prMsg) do { \ -+ ASSERT(arMsgMapTable[prMsg->eMsgId].pfMsgHndl); \ -+ if (arMsgMapTable[prMsg->eMsgId].pfMsgHndl) { \ -+ DBGLOG(CNM, LOUD, "DO MSG [%d: %s]\n", prMsg->eMsgId, apucDebugMsg[prMsg->eMsgId]); \ -+ arMsgMapTable[prMsg->eMsgId].pfMsgHndl(prAdapter, prMsg); \ -+ } \ -+ else { \ -+ DBGLOG(CNM, ERROR, "NULL fptr for MSG [%d]\n", prMsg->eMsgId); \ -+ cnmMemFree(prAdapter, prMsg); \ -+ } \ -+} while (0) -+#else -+#define MBOX_HNDL_MSG(prAdapter, prMsg) do { \ -+ ASSERT(arMsgMapTable[prMsg->eMsgId].pfMsgHndl); \ -+ if (arMsgMapTable[prMsg->eMsgId].pfMsgHndl) { \ -+ DBGLOG(CNM, LOUD, "DO MSG [%d]\n", prMsg->eMsgId); \ -+ arMsgMapTable[prMsg->eMsgId].pfMsgHndl(prAdapter, prMsg); \ -+ } \ -+ else { \ -+ DBGLOG(CNM, ERROR, "NULL fptr for MSG [%d]\n", prMsg->eMsgId); \ -+ cnmMemFree(prAdapter, prMsg); \ -+ } \ -+} while (0) -+#endif -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID mboxInitMsgMap(VOID) -+{ -+ UINT_32 i, idx; -+ MSG_HNDL_ENTRY_T rTempEntry; -+ -+ ASSERT((sizeof(arMsgMapTable) / sizeof(MSG_HNDL_ENTRY_T)) == MID_TOTAL_NUM); -+ -+ for (i = 0; i < MID_TOTAL_NUM; i++) { -+ if (arMsgMapTable[i].eMsgId == (ENUM_MSG_ID_T) i) -+ continue; -+ for (idx = i + 1; idx < MID_TOTAL_NUM; idx++) { -+ if (arMsgMapTable[idx].eMsgId == (ENUM_MSG_ID_T) i) -+ break; -+ } -+ ASSERT(idx < MID_TOTAL_NUM); -+ if (idx >= MID_TOTAL_NUM) -+ continue; -+ -+ /* Swap target entry and current entry */ -+ rTempEntry.eMsgId = arMsgMapTable[idx].eMsgId; -+ rTempEntry.pfMsgHndl = arMsgMapTable[idx].pfMsgHndl; -+ -+ arMsgMapTable[idx].eMsgId = arMsgMapTable[i].eMsgId; -+ arMsgMapTable[idx].pfMsgHndl = arMsgMapTable[i].pfMsgHndl; -+ -+ arMsgMapTable[i].eMsgId = rTempEntry.eMsgId; -+ arMsgMapTable[i].pfMsgHndl = rTempEntry.pfMsgHndl; -+ } -+ -+ /* Verify the correctness of final message map */ -+ for (i = 0; i < MID_TOTAL_NUM; i++) { -+ ASSERT(arMsgMapTable[i].eMsgId == (ENUM_MSG_ID_T) i); -+ while (arMsgMapTable[i].eMsgId != (ENUM_MSG_ID_T) i) -+ ; -+ } -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID mboxSetup(IN P_ADAPTER_T prAdapter, IN ENUM_MBOX_ID_T eMboxId) -+{ -+ P_MBOX_T prMbox; -+ -+ KAL_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(eMboxId < MBOX_ID_TOTAL_NUM); -+ ASSERT(prAdapter); -+ -+ prMbox = &(prAdapter->arMbox[eMboxId]); -+ -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_MAILBOX); -+ LINK_INITIALIZE(&prMbox->rLinkHead); -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_MAILBOX); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+mboxSendMsg(IN P_ADAPTER_T prAdapter, -+ IN ENUM_MBOX_ID_T eMboxId, IN P_MSG_HDR_T prMsg, IN EUNM_MSG_SEND_METHOD_T eMethod) -+{ -+ P_MBOX_T prMbox; -+ -+ KAL_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(eMboxId < MBOX_ID_TOTAL_NUM); -+ ASSERT(prMsg); -+ ASSERT(prAdapter); -+ -+ prMbox = &(prAdapter->arMbox[eMboxId]); -+ -+ switch (eMethod) { -+ case MSG_SEND_METHOD_BUF: -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_MAILBOX); -+ LINK_INSERT_TAIL(&prMbox->rLinkHead, &prMsg->rLinkEntry); -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_MAILBOX); -+ -+ /* to wake up main service thread */ -+ GLUE_SET_EVENT(prAdapter->prGlueInfo); -+ -+ break; -+ -+ case MSG_SEND_METHOD_UNBUF: -+ MBOX_HNDL_MSG(prAdapter, prMsg); -+ break; -+ -+ default: -+ ASSERT(0); -+ break; -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID mboxRcvAllMsg(IN P_ADAPTER_T prAdapter, ENUM_MBOX_ID_T eMboxId) -+{ -+ P_MBOX_T prMbox; -+ P_MSG_HDR_T prMsg; -+ -+ KAL_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(eMboxId < MBOX_ID_TOTAL_NUM); -+ ASSERT(prAdapter); -+ -+ prMbox = &(prAdapter->arMbox[eMboxId]); -+ -+ while (!LINK_IS_EMPTY(&prMbox->rLinkHead)) { -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_MAILBOX); -+ LINK_REMOVE_HEAD(&prMbox->rLinkHead, prMsg, P_MSG_HDR_T); -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_MAILBOX); -+ -+ ASSERT(prMsg); -+ MBOX_HNDL_MSG(prAdapter, prMsg); -+ } -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID mboxInitialize(IN P_ADAPTER_T prAdapter) -+{ -+ UINT_32 i; -+ -+ ASSERT(prAdapter); -+ -+ /* Initialize Mailbox */ -+ mboxInitMsgMap(); -+ -+ /* Setup/initialize each mailbox */ -+ for (i = 0; i < MBOX_ID_TOTAL_NUM; i++) -+ mboxSetup(prAdapter, i); -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID mboxDestroy(IN P_ADAPTER_T prAdapter) -+{ -+ P_MBOX_T prMbox; -+ P_MSG_HDR_T prMsg; -+ UINT_8 i; -+ -+ KAL_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(prAdapter); -+ -+ for (i = 0; i < MBOX_ID_TOTAL_NUM; i++) { -+ prMbox = &(prAdapter->arMbox[i]); -+ -+ while (!LINK_IS_EMPTY(&prMbox->rLinkHead)) { -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_MAILBOX); -+ LINK_REMOVE_HEAD(&prMbox->rLinkHead, prMsg, P_MSG_HDR_T); -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_MAILBOX); -+ -+ ASSERT(prMsg); -+ cnmMemFree(prAdapter, prMsg); -+ } -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This is dummy function to prevent empty arMsgMapTable[] for compiling. -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID mboxDummy(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) -+{ -+ ASSERT(prAdapter); -+ -+ cnmMemFree(prAdapter, prMsgHdr); -+ -+} -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/hs20.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/hs20.c -new file mode 100644 -index 000000000000..7fb71a199ccf ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/hs20.c -@@ -0,0 +1,498 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/HS2_DEV_SW/MT6620_WIFI_DRIVER_V2_1_HS_2_0/mgmt/hs20.c#2 -+*/ -+ -+/*! \file "hs20.c" -+ \brief This file including the hotspot 2.0 related function. -+ -+ This file provided the macros and functions library support for the -+ protocol layer hotspot 2.0 related function. -+ -+*/ -+ -+/* -+** Log: hs20.c -+ * -+ */ -+ -+ /******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "precomp.h" -+ -+#if CFG_SUPPORT_HOTSPOT_2_0 -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is called to generate Interworking IE for Probe Rsp, Bcn, Assoc Req/Rsp. -+* -+* \param[in] prAdapter Pointer of ADAPTER_T -+* \param[out] prMsduInfo Pointer of the Msdu Info -+* -+* \return VOID -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID hs20GenerateInterworkingIE(IN P_ADAPTER_T prAdapter, OUT P_MSDU_INFO_T prMsduInfo) -+{ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is called to generate Roaming Consortium IE for Probe Rsp, Bcn, Assoc Req/Rsp. -+* -+* \param[in] prAdapter Pointer of ADAPTER_T -+* \param[out] prMsduInfo Pointer of the Msdu Info -+* -+* \return VOID -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID hs20GenerateRoamingConsortiumIE(IN P_ADAPTER_T prAdapter, OUT P_MSDU_INFO_T prMsduInfo) -+{ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is called to generate HS2.0 IE for Probe Rsp, Bcn, Assoc Req/Rsp. -+* -+* \param[in] prAdapter Pointer of ADAPTER_T -+* \param[out] prMsduInfo Pointer of the Msdu Info -+* -+* \return VOID -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID hs20GenerateHS20IE(IN P_ADAPTER_T prAdapter, OUT P_MSDU_INFO_T prMsduInfo) -+{ -+ PUINT_8 pucBuffer; -+ -+ ASSERT(prAdapter); -+ ASSERT(prMsduInfo); -+ -+ if (prMsduInfo->ucNetworkType != NETWORK_TYPE_AIS_INDEX) -+ return; -+ -+ pucBuffer = (PUINT_8) ((ULONG) prMsduInfo->prPacket + (UINT_32) prMsduInfo->u2FrameLength); -+ -+ /* ASSOC INFO IE ID: 221 :0xDD */ -+ if (prAdapter->prGlueInfo->u2HS20AssocInfoIELen) { -+ kalMemCopy(pucBuffer, &prAdapter->prGlueInfo->aucHS20AssocInfoIE, -+ prAdapter->prGlueInfo->u2HS20AssocInfoIELen); -+ prMsduInfo->u2FrameLength += prAdapter->prGlueInfo->u2HS20AssocInfoIELen; -+ } -+ -+} -+ -+VOID hs20FillExtCapIE(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo, P_MSDU_INFO_T prMsduInfo) -+{ -+ P_HS20_EXT_CAP_T prExtCap; -+ -+ ASSERT(prAdapter); -+ ASSERT(prMsduInfo); -+ -+ /* Add Extended Capabilities IE */ -+ prExtCap = (P_HS20_EXT_CAP_T) -+ (((PUINT_8) prMsduInfo->prPacket) + prMsduInfo->u2FrameLength); -+ -+ prExtCap->ucId = ELEM_ID_EXTENDED_CAP; -+ if (prAdapter->prGlueInfo->fgConnectHS20AP == TRUE) -+ prExtCap->ucLength = ELEM_MAX_LEN_EXT_CAP; -+ else -+ prExtCap->ucLength = 3 - ELEM_HDR_LEN; -+ -+ kalMemZero(prExtCap->aucCapabilities, prExtCap->ucLength); -+ -+ prExtCap->aucCapabilities[0] = ELEM_EXT_CAP_DEFAULT_VAL; -+ -+ if (prBssInfo->eCurrentOPMode != OP_MODE_INFRASTRUCTURE) -+ prExtCap->aucCapabilities[0] &= ~ELEM_EXT_CAP_PSMP_CAP; -+ -+ if (prAdapter->prGlueInfo->fgConnectHS20AP == TRUE) { -+ SET_EXT_CAP(prExtCap->aucCapabilities, ELEM_MAX_LEN_EXT_CAP, ELEM_EXT_CAP_BSS_TRANSITION_BIT); -+ SET_EXT_CAP(prExtCap->aucCapabilities, ELEM_MAX_LEN_EXT_CAP, ELEM_EXT_CAP_UTC_TSF_OFFSET_BIT); -+ SET_EXT_CAP(prExtCap->aucCapabilities, ELEM_MAX_LEN_EXT_CAP, ELEM_EXT_CAP_INTERWORKING_BIT); -+ -+ /* For R2 WNM-Notification */ -+ SET_EXT_CAP(prExtCap->aucCapabilities, ELEM_MAX_LEN_EXT_CAP, ELEM_EXT_CAP_WNM_NOTIFICATION_BIT); -+ } -+ kalPrint("IE_SIZE(prExtCap) = %d, %d %d\n", IE_SIZE(prExtCap), ELEM_HDR_LEN, ELEM_MAX_LEN_EXT_CAP); -+ ASSERT(IE_SIZE(prExtCap) <= (ELEM_HDR_LEN + ELEM_MAX_LEN_EXT_CAP)); -+ -+ prMsduInfo->u2FrameLength += IE_SIZE(prExtCap); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is called to fill up the content of Ext Cap IE bit 31. -+* -+* \param[in] prAdapter Pointer of ADAPTER_T -+* \param[out] pucIE Pointer of the IE buffer -+* -+* \return VOID -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID hs20FillProreqExtCapIE(IN P_ADAPTER_T prAdapter, OUT PUINT_8 pucIE) -+{ -+ P_HS20_EXT_CAP_T prExtCap; -+ -+ ASSERT(prAdapter); -+ -+ /* Add Extended Capabilities IE */ -+ prExtCap = (P_HS20_EXT_CAP_T) pucIE; -+ -+ prExtCap->ucId = ELEM_ID_EXTENDED_CAP; -+ if (prAdapter->prGlueInfo->fgConnectHS20AP == TRUE) -+ prExtCap->ucLength = ELEM_MAX_LEN_EXT_CAP; -+ else -+ prExtCap->ucLength = 3 - ELEM_HDR_LEN; -+ -+ kalMemZero(prExtCap->aucCapabilities, prExtCap->ucLength); -+ -+ prExtCap->aucCapabilities[0] = ELEM_EXT_CAP_DEFAULT_VAL; -+ -+ if (prAdapter->prGlueInfo->fgConnectHS20AP == TRUE) { -+ SET_EXT_CAP(prExtCap->aucCapabilities, ELEM_MAX_LEN_EXT_CAP, ELEM_EXT_CAP_BSS_TRANSITION_BIT); -+ SET_EXT_CAP(prExtCap->aucCapabilities, ELEM_MAX_LEN_EXT_CAP, ELEM_EXT_CAP_UTC_TSF_OFFSET_BIT); -+ SET_EXT_CAP(prExtCap->aucCapabilities, ELEM_MAX_LEN_EXT_CAP, ELEM_EXT_CAP_INTERWORKING_BIT); -+ -+ /* For R2 WNM-Notification */ -+ SET_EXT_CAP(prExtCap->aucCapabilities, ELEM_MAX_LEN_EXT_CAP, ELEM_EXT_CAP_WNM_NOTIFICATION_BIT); -+ } -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is called to fill up the content of HS2.0 IE. -+* -+* \param[in] prAdapter Pointer of ADAPTER_T -+* \param[out] pucIE Pointer of the IE buffer -+* -+* \return VOID -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID hs20FillHS20IE(IN P_ADAPTER_T prAdapter, OUT PUINT_8 pucIE) -+{ -+ P_IE_HS20_INDICATION_T prHS20IndicationIe; -+ /* P_HS20_INFO_T prHS20Info; */ -+ UINT_8 aucWfaOui[] = VENDOR_OUI_WFA_SPECIFIC; -+ -+ /* prHS20Info = &(prAdapter->rWifiVar.rHS20Info); */ -+ -+ prHS20IndicationIe = (P_IE_HS20_INDICATION_T) pucIE; -+ -+ prHS20IndicationIe->ucId = ELEM_ID_VENDOR; -+ prHS20IndicationIe->ucLength = sizeof(IE_HS20_INDICATION_T) - ELEM_HDR_LEN; -+ prHS20IndicationIe->aucOui[0] = aucWfaOui[0]; -+ prHS20IndicationIe->aucOui[1] = aucWfaOui[1]; -+ prHS20IndicationIe->aucOui[2] = aucWfaOui[2]; -+ prHS20IndicationIe->ucType = VENDOR_OUI_TYPE_HS20; -+ prHS20IndicationIe->ucHotspotConfig = 0x00; /* prHS20Info->ucHotspotConfig; */ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is called while calculating length of hotspot 2.0 indication IE for Probe Request. -+* -+* \param[in] prAdapter Pointer of ADAPTER_T -+* \param[in] pucTargetBSSID Pointer of target HESSID -+* -+* \return the length of composed HS20 IE -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT_32 hs20CalculateHS20RelatedIEForProbeReq(IN P_ADAPTER_T prAdapter, IN PUINT_8 pucTargetBSSID) -+{ -+ UINT_32 u4IeLength; -+ -+ if (0) /* Todo:: Not HS20 STA */ -+ return 0; -+ -+ u4IeLength = -+ sizeof(IE_HS20_INDICATION_T) + /* sizeof(IE_INTERWORKING_T) */ + (ELEM_HDR_LEN + ELEM_MAX_LEN_EXT_CAP); -+ -+ if (!pucTargetBSSID) { -+ /* Do nothing */ -+ /* u4IeLength -= MAC_ADDR_LEN; */ -+ } -+ -+ return u4IeLength; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is called while composing hotspot 2.0 indication IE for Probe Request. -+* -+* \param[in] prAdapter Pointer of ADAPTER_T -+* \param[in] pucTargetBSSID Pointer of target HESSID -+* \param[out] prIE Pointer of the IE buffer -+* -+* \return the wlan status -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS hs20GenerateHS20RelatedIEForProbeReq(IN P_ADAPTER_T prAdapter, IN PUINT_8 pucTargetBSSID, OUT PUINT_8 prIE) -+{ -+ if (0) /* Todo:: Not HS20 STA */ -+ return 0; -+#if 0 -+ P_HS20_INFO_T prHS20Info; -+ -+ prHS20Info = &(prAdapter->rWifiVar.rHS20Info); -+ -+ /* -+ * Generate 802.11u Interworking IE (107) -+ */ -+ hs20FillInterworkingIE(prAdapter, -+ prHS20Info->ucAccessNetworkOptions, -+ prHS20Info->ucVenueGroup, prHS20Info->ucVenueType, pucTargetBSSID, prIE); -+ prIE += IE_SIZE(prIE); -+#endif -+ /* -+ * Generate Ext Cap IE (127) -+ */ -+ hs20FillProreqExtCapIE(prAdapter, prIE); -+ prIE += IE_SIZE(prIE); -+ -+ /* -+ * Generate HS2.0 Indication IE (221) -+ */ -+ hs20FillHS20IE(prAdapter, prIE); -+ prIE += IE_SIZE(prIE); -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+BOOLEAN hs20IsGratuitousArp(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prCurrSwRfb) -+{ -+ PUINT_8 pucSenderIP = prCurrSwRfb->pvHeader + ETHER_HEADER_LEN + ARP_SENDER_IP_OFFSET; -+ PUINT_8 pucTargetIP = prCurrSwRfb->pvHeader + ETHER_HEADER_LEN + ARP_TARGET_IP_OFFSET; -+ PUINT_8 pucSenderMac = ((PUINT_8) prCurrSwRfb->pvHeader + ETHER_HEADER_LEN + ARP_SNEDER_MAC_OFFSET); -+#if CFG_HS20_DEBUG && 0 -+/* UINT_8 aucIpAllZero[4] = {0,0,0,0}; */ -+/* UINT_8 aucMACAllZero[MAC_ADDR_LEN] = {0,0,0,0,0,0}; */ -+ PUINT_8 pucTargetMac = ((PUINT_8) prCurrSwRfb->pvHeader + ETHER_HEADER_LEN + ARP_TARGET_MAC_OFFSET); -+#endif -+ -+#if CFG_HS20_DEBUG && 0 -+ PUINT_16 pu2ArpOper = (PUINT_16) ((PUINT_8) prCurrSwRfb->pvHeader + ETHER_HEADER_LEN + ARP_OPERATION_OFFSET); -+ -+ kalPrint("Recv ARP 0x%04X\n", htons(*pu2ArpOper)); -+ kalPrint("SENDER[ %pM ] [%pI4]\n", pucSenderMac, pucSenderIP); -+ kalPrint("TARGET[ %pM ] [%pI4]\n", pucTargetMac, pucTargetIP); -+#endif -+ -+ /* IsGratuitousArp */ -+ if (!kalMemCmp(pucSenderIP, pucTargetIP, 4)) { -+ kalPrint("Drop Gratuitous ARP from [ %pM ] [%pI4]\n", pucSenderMac, pucTargetIP); -+ return TRUE; -+ } -+ return FALSE; -+} -+ -+BOOLEAN hs20IsUnsolicitedNeighborAdv(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prCurrSwRfb) -+{ -+ PUINT_8 pucIpv6Protocol = ((PUINT_8) prCurrSwRfb->pvHeader + ETHER_HEADER_LEN + IPV6_HDR_IP_PROTOCOL_OFFSET); -+ -+ /* kalPrint("pucIpv6Protocol [%02X:%02X]\n", *pucIpv6Protocol, IPV6_PROTOCOL_ICMPV6); */ -+ if (*pucIpv6Protocol == IPV6_PROTOCOL_ICMPV6) { -+ PUINT_8 pucICMPv6Type = -+ ((PUINT_8) prCurrSwRfb->pvHeader + ETHER_HEADER_LEN + IPV6_HDR_LEN + ICMPV6_TYPE_OFFSET); -+ /* kalPrint("pucICMPv6Type [%02X:%02X]\n", *pucICMPv6Type, ICMPV6_TYPE_NEIGHBOR_ADVERTISEMENT); */ -+ if (*pucICMPv6Type == ICMPV6_TYPE_NEIGHBOR_ADVERTISEMENT) { -+ PUINT_8 pucICMPv6Flag = -+ ((PUINT_8) prCurrSwRfb->pvHeader + ETHER_HEADER_LEN + IPV6_HDR_LEN + ICMPV6_FLAG_OFFSET); -+ PUINT_8 pucSrcMAC = ((PUINT_8) prCurrSwRfb->pvHeader + MAC_ADDR_LEN); -+ -+#if CFG_HS20_DEBUG -+ kalPrint("NAdv Flag [%02X] [R(%d)\\S(%d)\\O(%d)]\n", -+ *pucICMPv6Flag, -+ (UINT_8) (*pucICMPv6Flag & ICMPV6_FLAG_ROUTER_BIT) >> 7, -+ (UINT_8) (*pucICMPv6Flag & ICMPV6_FLAG_SOLICITED_BIT) >> 6, -+ (UINT_8) (*pucICMPv6Flag & ICMPV6_FLAG_OVERWRITE_BIT) >> 5); -+#endif -+ if (!(*pucICMPv6Flag & ICMPV6_FLAG_SOLICITED_BIT)) { -+ kalPrint("Drop Unsolicited Neighbor Advertisement from [%pM]\n", pucSrcMAC); -+ return TRUE; -+ } -+ } -+ } -+ -+ return FALSE; -+} -+ -+#if CFG_ENABLE_GTK_FRAME_FILTER -+BOOLEAN hs20IsForgedGTKFrame(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prBssInfo, IN P_SW_RFB_T prCurrSwRfb) -+{ -+ /* -+ P_CONNECTION_SETTINGS_T prConnSettings = &prAdapter->rWifiVar.rConnSettings; -+ PUINT_8 pucEthDestAddr = prCurrSwRfb->pvHeader; -+ */ -+ /* 3 TODO: Need to verify this function before enable it */ -+ return FALSE; -+ /* -+ if ((prConnSettings->eEncStatus != ENUM_ENCRYPTION_DISABLED) && IS_BMCAST_MAC_ADDR(pucEthDestAddr)) { -+ UINT_8 ucIdx = 0; -+ PUINT_32 prIpAddr, prPacketDA; -+ PUINT_16 pu2PktIpVer = -+ (PUINT_16) ((PUINT_8) prCurrSwRfb->pvHeader + (ETHER_HEADER_LEN - ETHER_TYPE_LEN)); -+ -+ if (*pu2PktIpVer == htons(ETH_P_IPV4)) { -+ if (!prBssInfo->prIpV4NetAddrList) -+ return FALSE; -+ for (ucIdx = 0; ucIdx < prBssInfo->prIpV4NetAddrList->ucAddrCount; ucIdx++) { -+ prIpAddr = (PUINT_32) &prBssInfo->prIpV4NetAddrList->arNetAddr[ucIdx].aucIpAddr[0]; -+ prPacketDA = -+ (PUINT_32) ((PUINT_8) prCurrSwRfb->pvHeader + ETHER_HEADER_LEN + -+ IPV4_HDR_IP_DST_ADDR_OFFSET); -+ -+ if (kalMemCmp(prIpAddr, prPacketDA, 4) == 0) { -+ kalPrint("Drop FORGED IPv4 packet\n"); -+ return TRUE; -+ } -+ } -+ } -+#ifdef CONFIG_IPV6 -+ else if (*pu2PktIpVer == htons(ETH_P_IPV6)) { -+ UINT_8 aucIPv6Mac[MAC_ADDR_LEN]; -+ PUINT_8 pucIdx = -+ prCurrSwRfb->pvHeader + ETHER_HEADER_LEN + IPV6_HDR_IP_DST_ADDR_MAC_HIGH_OFFSET; -+ -+ kalMemCopy(&aucIPv6Mac[0], pucIdx, 3); -+ pucIdx += 5; -+ kalMemCopy(&aucIPv6Mac[3], pucIdx, 3); -+ kalPrint("Get IPv6 frame Dst IP MAC part %pM\n", aucIPv6Mac); -+ if (EQUAL_MAC_ADDR(aucIPv6Mac, prBssInfo->aucOwnMacAddr)) { -+ kalPrint("Drop FORGED IPv6 packet\n"); -+ return TRUE; -+ } -+ } -+#endif -+ } -+ -+ return FALSE; -+ */ -+} -+#endif -+ -+BOOLEAN hs20IsUnsecuredFrame(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prBssInfo, IN P_SW_RFB_T prCurrSwRfb) -+{ -+ PUINT_16 pu2PktIpVer = (PUINT_16) ((PUINT_8) prCurrSwRfb->pvHeader + (ETHER_HEADER_LEN - ETHER_TYPE_LEN)); -+ -+ /* kalPrint("IPVER 0x%4X\n", htons(*pu2PktIpVer)); */ -+#if CFG_HS20_DEBUG & 0 -+ UINT_8 i = 0; -+ -+ kalPrint("==============================================="); -+ for (i = 0; i < 96; i++) { -+ if (!(i % 16)) -+ kalPrint("\n"); -+ kalPrint("%02X ", *((PUINT_8) prCurrSwRfb->pvHeader + i)); -+ } -+ kalPrint("\n"); -+#endif -+ -+#if CFG_ENABLE_GTK_FRAME_FILTER -+ if (hs20IsForgedGTKFrame(prAdapter, prBssInfo, prCurrSwRfb)) -+ return TRUE; -+ -+#endif -+ if (*pu2PktIpVer == htons(ETH_P_ARP)) -+ return hs20IsGratuitousArp(prAdapter, prCurrSwRfb); -+ else if (*pu2PktIpVer == htons(ETH_P_IPV6)) -+ return hs20IsUnsolicitedNeighborAdv(prAdapter, prCurrSwRfb); -+ -+ return FALSE; -+} -+ -+BOOLEAN hs20IsFrameFilterEnabled(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prBssInfo) -+{ -+#if 1 -+ if (prAdapter->prGlueInfo->fgConnectHS20AP) -+ return TRUE; -+#else -+ PARAM_SSID_T rParamSsid; -+ P_BSS_DESC_T prBssDesc; -+ -+ rParamSsid.u4SsidLen = prBssInfo->ucSSIDLen; -+ COPY_SSID(rParamSsid.aucSsid, rParamSsid.u4SsidLen, prBssInfo->aucSSID, prBssInfo->ucSSIDLen); -+ -+ prBssDesc = scanSearchBssDescByBssidAndSsid(prAdapter, prBssInfo->aucBSSID, TRUE, &rParamSsid); -+ if (!prBssDesc) -+ return FALSE; -+ -+ if (prBssDesc->fgIsSupportHS20) { -+ if (!(prBssDesc->ucHotspotConfig & ELEM_HS_CONFIG_DGAF_DISABLED_MASK)) -+ return TRUE; -+ -+ /* Disable frame filter only if DGAF == 1 */ -+ return FALSE; -+ -+ } -+#endif -+ -+ /* For Now, always return true to run hs20 check even for legacy AP */ -+ return TRUE; -+} -+ -+WLAN_STATUS hs20SetBssidPool(IN P_ADAPTER_T prAdapter, IN PVOID pvBuffer, IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIdx) -+{ -+ P_PARAM_HS20_SET_BSSID_POOL prParamBssidPool = (P_PARAM_HS20_SET_BSSID_POOL) pvBuffer; -+ P_HS20_INFO_T prHS20Info; -+ UINT_8 ucIdx; -+ -+ prHS20Info = &(prAdapter->rWifiVar.rHS20Info); -+ kalPrint("[%s]Set Bssid Pool! enable[%d] num[%d]\n", __func__, prParamBssidPool->fgIsEnable, -+ prParamBssidPool->ucNumBssidPool); -+ for (ucIdx = 0; ucIdx < prParamBssidPool->ucNumBssidPool; ucIdx++) { -+ COPY_MAC_ADDR(prHS20Info->arBssidPool[ucIdx].aucBSSID, &prParamBssidPool->arBSSID[ucIdx]); -+ kalPrint("[%s][%d][ %pM ]\n", __func__, ucIdx, (prHS20Info->arBssidPool[ucIdx].aucBSSID)); -+ } -+ prHS20Info->fgIsHS2SigmaMode = prParamBssidPool->fgIsEnable; -+ prHS20Info->ucNumBssidPoolEntry = prParamBssidPool->ucNumBssidPool; -+ -+#if 0 -+ wlanClearScanningResult(prAdapter); -+#endif -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+#endif -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/mib.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/mib.c -new file mode 100644 -index 000000000000..469a48ebe9c1 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/mib.c -@@ -0,0 +1,111 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/mib.c#1 -+*/ -+ -+/*! \file "mib.c" -+ \brief This file includes the mib default vale and functions. -+*/ -+ -+/* -+** Log: mib.c -+ * -+ * 09 03 2010 kevin.huang -+ * NULL -+ * Refine #include sequence and solve recursive/nested #include issue -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 07 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add mib.c. -+ * -+ * 02 04 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Add AAA Module Support, Revise Net Type to Net Type Index for array lookup -+ * -+ * Nov 23 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "precomp.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+NON_HT_PHY_ATTRIBUTE_T rNonHTPhyAttributes[] = { -+ {RATE_SET_HR_DSSS, TRUE, FALSE} -+ , /* For PHY_TYPE_HR_DSSS_INDEX(0) */ -+ {RATE_SET_ERP, TRUE, TRUE} -+ , /* For PHY_TYPE_ERP_INDEX(1) */ -+ {RATE_SET_ERP_P2P, TRUE, TRUE} -+ , /* For PHY_TYPE_ERP_P2P_INDEX(2) */ -+ {RATE_SET_OFDM, FALSE, FALSE} -+ , /* For PHY_TYPE_OFDM_INDEX(3) */ -+}; -+ -+NON_HT_ADHOC_MODE_ATTRIBUTE_T rNonHTAdHocModeAttributes[AD_HOC_MODE_NUM] = { -+ {PHY_TYPE_HR_DSSS_INDEX, BASIC_RATE_SET_HR_DSSS} -+ , /* For AD_HOC_MODE_11B(0) */ -+ {PHY_TYPE_ERP_INDEX, BASIC_RATE_SET_HR_DSSS_ERP} -+ , /* For AD_HOC_MODE_MIXED_11BG(1) */ -+ {PHY_TYPE_ERP_INDEX, BASIC_RATE_SET_ERP} -+ , /* For AD_HOC_MODE_11G(2) */ -+ {PHY_TYPE_OFDM_INDEX, BASIC_RATE_SET_OFDM} -+ , /* For AD_HOC_MODE_11A(3) */ -+}; -+ -+NON_HT_AP_MODE_ATTRIBUTE_T rNonHTApModeAttributes[AP_MODE_NUM] = { -+ {PHY_TYPE_HR_DSSS_INDEX, BASIC_RATE_SET_HR_DSSS} -+ , /* For AP_MODE_11B(0) */ -+ {PHY_TYPE_ERP_INDEX, BASIC_RATE_SET_HR_DSSS_ERP} -+ , /* For AP_MODE_MIXED_11BG(1) */ -+ {PHY_TYPE_ERP_INDEX, BASIC_RATE_SET_ERP} -+ , /* For AP_MODE_11G(2) */ -+ {PHY_TYPE_ERP_P2P_INDEX, BASIC_RATE_SET_ERP_P2P} -+ , /* For AP_MODE_11G_P2P(3) */ -+ {PHY_TYPE_OFDM_INDEX, BASIC_RATE_SET_OFDM} -+ , /* For AP_MODE_11A(4) */ -+}; -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_assoc.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_assoc.c -new file mode 100644 -index 000000000000..cb5fbebedd49 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_assoc.c -@@ -0,0 +1,87 @@ -+/* -+** Id: @(#) p2p_assoc.c@@ -+*/ -+ -+/*! \file "p2p_assoc.c" -+ \brief This file includes the Wi-Fi Direct association-related functions. -+ -+ This file includes the association-related functions. -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+#include "precomp.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is used to compose Common Information Elements for P2P Association -+* Request Frame. -+* -+* @param[in] prMsduInfo Pointer to the composed MSDU_INFO_T. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+PUINT_8 p2pBuildReAssocReqFrameCommonIEs(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo, IN PUINT_8 pucBuffer) -+{ -+ P_P2P_CONNECTION_SETTINGS_T prP2pConnSettings = (P_P2P_CONNECTION_SETTINGS_T) NULL; -+ -+ prP2pConnSettings = prAdapter->rWifiVar.prP2PConnSettings; -+ -+ /* Fill the SSID element. */ -+ SSID_IE(pucBuffer)->ucId = ELEM_ID_SSID; -+ -+ /* NOTE(Kevin): We copy the SSID from CONNECTION_SETTINGS for the case of -+ * Passive Scan and the target BSS didn't broadcast SSID on its Beacon Frame. -+ */ -+ -+ COPY_SSID(SSID_IE(pucBuffer)->aucSSID, -+ SSID_IE(pucBuffer)->ucLength, prP2pConnSettings->aucSSID, prP2pConnSettings->ucSSIDLen); -+ -+ prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer); -+ pucBuffer += IE_SIZE(pucBuffer); -+ return pucBuffer; -+} -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_bss.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_bss.c -new file mode 100644 -index 000000000000..72a20a322cee ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_bss.c -@@ -0,0 +1,58 @@ -+/* -+** Id: @(#) p2p_bss.c@@ -+*/ -+ -+/*! \file "p2p_bss.c" -+ \brief This file contains the functions for creating p2p BSS(AP). -+ -+ This file contains the functions for BSS(AP). We may create a BSS -+ network, or merge with exist IBSS network and sending Beacon Frame or reply -+ the Probe Response Frame for received Probe Request Frame. -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+#include "precomp.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_fsm.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_fsm.c -new file mode 100644 -index 000000000000..f8c09e2aa9de ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_fsm.c -@@ -0,0 +1,3139 @@ -+/* -+** Id: //Department/DaVinci/TRUNK/WiFi_P2P_Driver/mgmt/p2p_fsm.c#61 -+*/ -+ -+/*! \file "p2p_fsm.c" -+ \brief This file defines the FSM for P2P Module. -+ -+ This file defines the FSM for P2P Module. -+*/ -+ -+/* -+** Log: p2p_fsm.c -+** -+** 12 20 2012 yuche.tsai -+** [ALPS00410124] [Rose][Free Test][KE][rlmUpdateParamsForAP]The device reboot automatically -+** and then "Fatal/Kernel" pops up during use data service.(Once) -+** Fix possible NULL station record cause KE under AP mode. -+** May due to variable uninitial. -+** Review: http://mtksap20:8080/go?page=NewReview&reviewid=49970 -+** -+** 09 12 2012 wcpadmin -+** [ALPS00276400] Remove MTK copyright and legal header on GPL/LGPL related packages -+** . -+** -+** 08 31 2012 yuche.tsai -+** [ALPS00349585] [6577JB][WiFi direct][KE]Establish p2p connection while both device have connected -+**to AP previously,one device reboots automatically with KE -+** Fix possible KE when concurrent & disconnect. -+** -+** 08 21 2012 yuche.tsai -+** NULL -+** fix disconnect indication. -+** -+** 08 16 2012 yuche.tsai -+** NULL -+** Fix compile warning. -+** -+** 08 14 2012 yuche.tsai -+** NULL -+** Fix p2p bug find on ALPS.JB trunk. -+** -+** 07 27 2012 yuche.tsai -+** [ALPS00324337] [ALPS.JB][Hot-Spot] Driver update for Hot-Spot -+** Update for driver unload KE issue. -+** -+** 07 26 2012 yuche.tsai -+** [ALPS00324337] [ALPS.JB][Hot-Spot] Driver update for Hot-Spot -+** Update driver code of ALPS.JB for hot-spot. -+** -+** 07 19 2012 yuche.tsai -+** NULL -+** Code update for JB. -+ * -+ * 07 17 2012 yuche.tsai -+ * NULL -+ * Compile no error before trial run. -+ * -+ * 07 05 2011 yuche.tsai -+ * [WCXRP00000821] [Volunteer Patch][WiFi Direct][Driver] WiFi Direct Connection Speed Issue -+ * Fix the compile flag of enhancement. -+ * -+ * 07 05 2011 yuche.tsai -+ * [WCXRP00000808] [Volunteer Patch][MT6620][Driver/FW] Device discoverability issue fix -+ * Change device discoverability methodology. From driver SCAN to FW lock channel. -+ * -+ * 07 05 2011 yuche.tsai -+ * [WCXRP00000821] [Volunteer Patch][WiFi Direct][Driver] WiFi Direct Connection Speed Issue -+ * Add wifi direct connection enhancement method I, II & VI. -+ * -+ * 07 05 2011 yuche.tsai -+ * [WCXRP00000833] [Volunteer Patch][WiFi Direct][Driver] Service Discovery Frame RX Indicate Issue -+ * Fix Service Discovery Race Condition Issue. -+ * -+ * 06 23 2011 cp.wu -+ * [WCXRP00000798] [MT6620 Wi-Fi][Firmware] Follow-ups for WAPI frequency offset workaround in firmware SCN module -+ * change parameter name from PeerAddr to BSSID -+ * -+ * 06 21 2011 yuche.tsai -+ * [WCXRP00000799] [Volunteer Patch][MT6620][Driver] Connection Indication Twice Issue. -+ * Fix an issue of accepting connection of GO. -+ * -+ * 06 21 2011 yuche.tsai -+ * [WCXRP00000775] [Volunteer Patch][MT6620][Driver] Dynamic enable SD capability -+ * Drop GAS frame when SD is not enabled. -+ * -+ * 06 20 2011 yuche.tsai -+ * NULL -+ * Fix compile error. -+ * -+ * 06 20 2011 yuche.tsai -+ * [WCXRP00000799] [Volunteer Patch][MT6620][Driver] Connection Indication Twice Issue. -+ * Fix connection indication twice issue. -+ * -+ * 06 20 2011 cp.wu -+ * [WCXRP00000798] [MT6620 Wi-Fi][Firmware] Follow-ups for WAPI frequency offset workaround in firmware SCN module -+ * 1. specify target's BSSID when requesting channel privilege. -+ * 2. pass BSSID information to firmware domain -+ * -+ * 06 20 2011 yuche.tsai -+ * [WCXRP00000795] [Volunteer Patch][MT6620][Driver] GO can not connect second device issue -+ * Solve P2P GO can not formation with second device issue. -+ * -+ * 06 14 2011 yuche.tsai -+ * NULL -+ * Change disconnect feature. -+ * -+ * 06 10 2011 yuche.tsai -+ * [WCXRP00000775] [Volunteer Patch][MT6620][Driver] Dynamic enable SD capability[WCXRP00000776] -+ * [Need Patch][MT6620][Driver] MT6620 response probe request of P2P device with P2P IE under Hot Spot mode. -+ * 1. Dynamic enable SD capability after P2P supplicant ready. -+ * 2. Avoid response probe respone with p2p IE when under hot spot mode. -+ * -+ * 06 07 2011 yuche.tsai -+ * [WCXRP00000763] [Volunteer Patch][MT6620][Driver] RX Service Discovery Frame under AP mode Issue -+ * Fix RX SD request under AP mode issue. -+ * -+ * 06 02 2011 cp.wu -+ * [WCXRP00000681] [MT5931][Firmware] HIF code size reduction -+ * eliminate unused parameters for SAA-FSM -+ * -+ * 05 26 2011 yuche.tsai -+ * [WCXRP00000745] Support accepting connection after one Group Connection Lost. -+ -+After Group Formation & lost connection, if MT6620 behave as: -+ -+1. GO: It would keep under GO state until been dissolved by supplicant. -+ -+ At this time, other P2P device can use join method to join this group. -+ -+2. GC: It would keep on searching target GO or target device until been dissolved by supplicant. -+ -+At this time, it would ignore other P2P device formation request. -+ -+-- -+ -+Modification: Make driver to accept GO NEGO REQ at this time, to let user decide to accept new connection or not. -+ -+ * [Volunteer Patch][MT6620][Driver] -+ * Driver would indicate connection request, if password ID is not ready but connection request is issued. -+ * -+ * 05 18 2011 yuche.tsai -+ * [WCXRP00000728] [Volunteer Patch][MT6620][Driver] Service Discovery Request TX issue. -+ * A solution for both connection request & IO control. -+ * -+ * 05 16 2011 yuche.tsai -+ * [WCXRP00000728] [Volunteer Patch][MT6620][Driver] Service Discovery Request TX issue. -+ * Fix SD request can not send out issue. -+ * -+ * 05 09 2011 terry.wu -+ * [WCXRP00000711] [MT6620 Wi-Fi][Driver] Set Initial value of StaType in StaRec for Hotspot Client -+ * Set initial value of StaType in StaRec for hotspot client. -+ * -+ * 05 04 2011 yuche.tsai -+ * [WCXRP00000697] [Volunteer Patch][MT6620][Driver] -+ * Bug fix for p2p descriptor is NULL if BSS descriptor is found first. -+ * -+ * 05 04 2011 yuche.tsai -+ * NULL -+ * Support partial persistent group function. -+ * -+ * 05 02 2011 yuche.tsai -+ * [WCXRP00000693] [Volunteer Patch][MT6620][Driver] Clear Formation Flag after TX lifetime timeout. -+ * Clear formation flag after formation timeout. -+ * -+ * 04 20 2011 yuche.tsai -+ * [WCXRP00000668] [Volunteer Patch][MT6620][Driver] Possible race condition -+ * when add scan & query scan result at the same time. -+ * Fix side effect while starting ATGO. -+ * -+ * 04 20 2011 yuche.tsai -+ * NULL -+ * Fix ASSERT issue in FW, side effect of last change. -+ * -+ * 04 19 2011 yuche.tsai -+ * [WCXRP00000668] [Volunteer Patch][MT6620][Driver] Possible race condition -+ * when add scan & query scan result at the same time. -+ * Workaround for multiple device connection, before invitation ready. -+ * -+ * 04 19 2011 yuche.tsai -+ * [WCXRP00000665] [Wifi Direct][MT6620 E4] When use Ralink's dongle to establish wifi direct connection with PBC. -+ * But 6573 always not pop accept option to establish connection. -+ * Support connection indication when GO NEGO REQ doesn't have configure method, instead it has PasswordID. -+ * -+ * 04 18 2011 yuche.tsai -+ * NULL -+ * Fix error. -+ * -+ * 04 14 2011 yuche.tsai -+ * [WCXRP00000646] [Volunteer Patch][MT6620][FW/Driver] Sigma Test Modification for some test case. -+ * Fix a connection issue. -+ * -+ * 04 14 2011 yuche.tsai -+ * [WCXRP00000646] [Volunteer Patch][MT6620][FW/Driver] Sigma Test Modification for some test case. -+ * Fix the channel issue of AP mode. -+ * -+ * 04 14 2011 yuche.tsai -+ * [WCXRP00000646] [Volunteer Patch][MT6620][FW/Driver] Sigma Test Modification for some test case. -+ * Connection flow refine for Sigma test. -+ * -+ * 04 09 2011 yuche.tsai -+ * [WCXRP00000624] [Volunteer Patch][MT6620][Driver] Add device discoverability support for GO. -+ * Fix Device discoverability related issue. -+ * -+ * 04 09 2011 yuche.tsai -+ * [WCXRP00000624] [Volunteer Patch][MT6620][Driver] Add device discoverability support for GO. -+ * Fix bug for Device Discoverability. -+ * -+ * 04 08 2011 yuche.tsai -+ * [WCXRP00000624] [Volunteer Patch][MT6620][Driver] Add device discoverability support for GO. -+ * Fix compile error. -+ * -+ * 04 08 2011 yuche.tsai -+ * [WCXRP00000624] [Volunteer Patch][MT6620][Driver] Add device discoverability support for GO. -+ * Add device discoverability support. -+ * -+ * 03 28 2011 yuche.tsai -+ * NULL -+ * Fix a possible issue for retry join when media status connected. -+ * -+ * 03 25 2011 yuche.tsai -+ * NULL -+ * Improve some error handleing. -+ * -+ * 03 24 2011 yuche.tsai -+ * NULL -+ * Assign AID before change STA_REC state to state 3. -+ * -+ * 03 23 2011 yuche.tsai -+ * NULL -+ * Fix Response Rate Issue when TX Auth Rsp Frame under P2P Mode. -+ * -+ * 03 23 2011 yuche.tsai -+ * NULL -+ * Fix issue of connection to one GC. -+ * -+ * 03 23 2011 yuche.tsai -+ * NULL -+ * Fix ASSERT issue when starting Hot-spot. -+ * -+ * 03 22 2011 yuche.tsai -+ * NULL -+ * When Target Information is not available, change to passive mode. -+ * -+ * 03 22 2011 yuche.tsai -+ * NULL -+ * Fix one connection issue while using Keypad to connect a GO. -+ * -+ * 03 22 2011 yuche.tsai -+ * NULL -+ * 1. Fix two issues that may cause kernel panic. -+ * -+ * 03 22 2011 yuche.tsai -+ * NULL -+ * Fix GC connect to other device issue. -+ * -+ * 03 22 2011 yuche.tsai -+ * NULL -+ * 1.Shorten the LISTEN interval. -+ * 2. Fix IF address issue when we are GO -+ * 3. Fix LISTEN channel issue. -+ * -+ * 03 22 2011 yuche.tsai -+ * NULL -+ * Modify formation policy setting. -+ * -+ * 03 21 2011 yuche.tsai -+ * NULL -+ * Solve Listen State doesn't response probe response issue. -+ * -+ * 03 21 2011 yuche.tsai -+ * NULL -+ * Change P2P Connection Request Flow. -+ * -+ * 03 19 2011 yuche.tsai -+ * [WCXRP00000584] [Volunteer Patch][MT6620][Driver] Add beacon timeout support for WiFi Direct. -+ * Add beacon timeout support. -+ * -+ * 03 19 2011 yuche.tsai -+ * [WCXRP00000583] [Volunteer Patch][MT6620][Driver] P2P connection of the third peer issue -+ * Indicate the correct Group SSID when join on Group. -+ * -+ * 03 19 2011 yuche.tsai -+ * [WCXRP00000583] [Volunteer Patch][MT6620][Driver] P2P connection of the third peer issue -+ * Support the third P2P device to join GO/GC group. -+ * -+ * 03 19 2011 yuche.tsai -+ * [WCXRP00000581] [Volunteer Patch][MT6620][Driver] P2P IE in Assoc Req Issue -+ * Append P2P IE in Assoc Req, so that GC can be discovered in probe response of GO. -+ * -+ * 03 18 2011 yuche.tsai -+ * [WCXRP00000578] [Volunteer Patch][MT6620][Driver] Separate Connection Request from general IOCTL -+ * Separate connection request from general IOCTL. -+ * -+ * 03 18 2011 yuche.tsai -+ * [WCXRP00000574] [Volunteer Patch][MT6620][Driver] Modify P2P FSM Connection Flow -+ * Modify connection flow after Group Formation Complete, or device connect to a GO. -+ * Instead of request channel & connect directly, we use scan to allocate channel bandwidth & connect after RX BCN. -+ * -+ * 03 17 2011 yuche.tsai -+ * NULL -+ * When AIS is connect to an AP, Hot Spot would be enabled under fixed same channel. -+ * -+ * 03 17 2011 yuche.tsai -+ * NULL -+ * Solve the Group Info IE in Probe Response incorrect issue. -+ * -+ * 03 17 2011 yuche.tsai -+ * NULL -+ * Release Channel after Join Complete. -+ * -+ * 03 16 2011 wh.su -+ * [WCXRP00000530] [MT6620 Wi-Fi] [Driver] skip doing p2pRunEventAAAComplete after send assoc response Tx Done -+ * enable the protected while at P2P start GO, and skip some security check . -+ * -+ * 03 15 2011 yuche.tsai -+ * [WCXRP00000560] [Volunteer Patch][MT6620][Driver] P2P Connection from UI using KEY/DISPLAY issue -+ * Fix local configure method issue. -+ * -+ * 03 15 2011 yuche.tsai -+ * [WCXRP00000560] [Volunteer Patch][MT6620][Driver] P2P Connection from UI using KEY/DISPLAY issue -+ * Fix some configure method issue. -+ * -+ * 03 14 2011 yuche.tsai -+ * NULL -+ * . -+ * -+ * 03 14 2011 yuche.tsai -+ * NULL -+ * Fix password ID issue. -+ * -+ * 03 10 2011 yuche.tsai -+ * NULL -+ * Add P2P API. -+ * -+ * 03 08 2011 yuche.tsai -+ * [WCXRP00000480] [Volunteer Patch][MT6620][Driver] WCS IE format issue[WCXRP00000509] -+ * [Volunteer Patch][MT6620][Driver] Kernal panic when remove p2p module. -+ * . -+ * -+ * 03 07 2011 yuche.tsai -+ * [WCXRP00000502] [Volunteer Patch][MT6620][Driver] Fix group ID issue when doing Group Formation. -+ * . -+ * -+ * 03 07 2011 wh.su -+ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code -+ * rename the define to anti_pviracy. -+ * -+ * 03 05 2011 wh.su -+ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code -+ * add the code to get the check rsponse and indicate to app. -+ * -+ * 03 04 2011 wh.su -+ * [WCXRP00000510] [MT6620 Wi-Fi] [Driver] Fixed the CTIA enter test mode issue -+ * fixed the p2p action frame type check for device request indication. -+ * -+ * 03 02 2011 yuche.tsai -+ * [WCXRP00000245] 1. Invitation Request/Response. -+2. Provision Discovery Request/Response -+ -+ * Fix Service Discovery RX packet buffer pointer. -+ * -+ * 03 01 2011 yuche.tsai -+ * [WCXRP00000501] [Volunteer Patch][MT6620][Driver] No common channel issue when doing GO formation -+ * Update channel issue when doing GO formation.. -+ * -+ * 03 01 2011 yuche.tsai -+ * [WCXRP00000245] 1. Invitation Request/Response. -+2. Provision Discovery Request/Response -+ -+ * Update Service Discovery Related wlanoid function. -+ * -+ * 02 21 2011 yuche.tsai -+ * [WCXRP00000481] [Volunteer Patch][MT6620][FW] Scan hang under concurrent case. -+ * Fix all BE issue of WSC or P2P IE. -+ * -+ * 02 18 2011 wh.su -+ * [WCXRP00000471] [MT6620 Wi-Fi][Driver] Add P2P Provison discovery append Config Method attribute at WSC IE -+ * fixed the wsc config method mapping to driver used config method issue. -+ * -+ * 02 18 2011 yuche.tsai -+ * [WCXRP00000479] [Volunteer Patch][MT6620][Driver] Probe Response of P2P using 11b rate. -+ * Update basic rate to FW, after P2P is initialed. -+ * -+ * 02 18 2011 yuche.tsai -+ * [WCXRP00000478] [Volunteer Patch][MT6620][Driver] Probe request frame during search -+ * phase do not contain P2P wildcard SSID. -+ * Use P2P Wildcard SSID when scan type of P2P_WILDCARD_SSID is set. -+ * -+ * 02 18 2011 yuche.tsai -+ * [WCXRP00000480] [Volunteer Patch][MT6620][Driver] WCS IE format issue -+ * Fix WSC IE BE format issue. -+ * -+ * 02 17 2011 wh.su -+ * [WCXRP00000471] [MT6620 Wi-Fi][Driver] Add P2P Provison discovery append Config Method attribute at WSC IE -+ * append the WSC IE config method attribute at provision discovery request. -+ * -+ * 02 16 2011 wh.su -+ * [WCXRP00000448] [MT6620 Wi-Fi][Driver] Fixed WSC IE not send out at probe request -+ * fixed the probe request send out without WSC IE issue (at P2P). -+ * -+ * 02 16 2011 yuche.tsai -+ * [WCXRP00000431] [Volunteer Patch][MT6620][Driver] Add MLME support for deauthentication under AP(Hot-Spot) mode. -+ * If two station connected to the Hot-Spot and one disconnect, FW would get into an infinite loop -+ * -+ * 02 15 2011 yuche.tsai -+ * [WCXRP00000431] [Volunteer Patch][MT6620][Driver] Add MLME support for deauthentication under AP(Hot-Spot) mode. -+ * Fix re-connection issue after RX deauthentication. -+ * -+ * 02 15 2011 yuche.tsai -+ * [WCXRP00000431] [Volunteer Patch][MT6620][Driver] Add MLME support for deauthentication under AP(Hot-Spot) mode. -+ * Fix conneciton issue after disconnect with AP. -+ * -+ * 02 12 2011 yuche.tsai -+ * [WCXRP00000441] [Volunteer Patch][MT6620][Driver] BoW can not create desired station type when Hot Spot is enabled. -+ * P2P Create Station Type according to Target BSS capability. -+ * -+ * 02 10 2011 yuche.tsai -+ * [WCXRP00000431] [Volunteer Patch][MT6620][Driver] Add MLME support for deauthentication under AP(Hot-Spot) mode. -+ * Support Disassoc & Deauthentication for Hot-Spot. -+ * -+ * 02 09 2011 yuche.tsai -+ * [WCXRP00000245] 1. Invitation Request/Response. -+2. Provision Discovery Request/Response -+ -+ * Add Service Discovery Indication Related code. -+ * -+ * 02 09 2011 yuche.tsai -+ * [WCXRP00000431] [Volunteer Patch][MT6620][Driver] Add MLME support for deauthentication under AP(Hot-Spot) mode. -+ * Add Support for MLME deauthentication for Hot-Spot. -+ * -+ * 02 09 2011 yuche.tsai -+ * [WCXRP00000429] [Volunteer Patch][MT6620][Driver] Hot Spot Client Limit Issue -+ * Fix Client Limit Issue. -+ * -+ * 02 08 2011 yuche.tsai -+ * [WCXRP00000419] [Volunteer Patch][MT6620/MT5931][Driver] Provide function of disconnect -+ * to target station for AAA module. -+ * Disconnect every station client when disolve on P2P group. -+ * -+ * 02 08 2011 yuche.tsai -+ * [WCXRP00000245] 1. Invitation Request/Response. -+2. Provision Discovery Request/Response -+ -+ * 1. Fix Service Disocvery Logical issue. -+ * 2. Fix a NULL pointer access violation issue when sending deauthentication packet to a class error station. -+ * -+ * 02 08 2011 yuche.tsai -+ * [WCXRP00000419] [Volunteer Patch][MT6620/MT5931][Driver] Provide function of disconnect -+ * to target station for AAA module. -+ * Workaround of disable P2P network. -+ * -+ * 02 08 2011 yuche.tsai -+ * [WCXRP00000421] [Volunteer Patch][MT6620][Driver] Fix incorrect SSID length Issue -+ * 1. Fixed SSID wrong length issue. -+ * 2. Under Hot Spot configuration, there won't be any P2P IE. -+ * 3. Under Hot Spot configuration, P2P FSM won't get into LISTEN state first. -+ * -+ * 01 27 2011 yuche.tsai -+ * [WCXRP00000399] [Volunteer Patch][MT6620/MT5931][Driver] Fix scan side effect after P2P module separate. -+ * Modify Start GO flow. -+ * -+ * 01 27 2011 yuche.tsai -+ * [WCXRP00000399] [Volunteer Patch][MT6620/MT5931][Driver] Fix scan side effect after P2P module separate. -+ * Fix desire phy type set issue. -+ * -+ * 01 27 2011 yuche.tsai -+ * [WCXRP00000399] [Volunteer Patch][MT6620/MT5931][Driver] Fix scan side effect after P2P module separate. -+ * Add desire phy type set phase I. -+ * -+ * 01 26 2011 yuche.tsai -+ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record. -+ * Fix P2P Disconnect Issue. -+ * -+ * 01 26 2011 yuche.tsai -+ * [WCXRP00000245] 1. Invitation Request/Response. -+2. Provision Discovery Request/Response -+ -+ * Add Service Discovery Function. -+ * -+ * 01 26 2011 cm.chang -+ * [WCXRP00000395] [MT6620 Wi-Fi][Driver][FW] Search STA_REC with additional net type index argument -+ * . -+ * -+ * 01 25 2011 yuche.tsai -+ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record. -+ * Fix compile error when DBG is disabled. -+ * -+ * 01 25 2011 yuche.tsai -+ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record. -+ * Change Station Type Definition. -+ * -+ * 01 19 2011 yuche.tsai -+ * [WCXRP00000353] [Volunteer Patch][MT6620][Driver] Desired Non-HT Rate Set update -+ * when STA record is created under AP Mode. -+ * Add P2P QoS Support. -+ * -+ * 01 19 2011 george.huang -+ * [WCXRP00000355] [MT6620 Wi-Fi] Set WMM-PS related setting with qualifying AP capability -+ * Null NOA attribute setting when no related parameters. -+ * -+ * 01 14 2011 yuche.tsai -+ * [WCXRP00000352] [Volunteer Patch][MT6620][Driver] P2P Statsion Record Client List Issue -+ * Modify AAA flow according to CM's comment. -+ * -+ * 01 13 2011 yuche.tsai -+ * [WCXRP00000353] [Volunteer Patch][MT6620][Driver] Desired Non-HT Rate Set update -+ * when STA record is created under AP Mode. -+ * Resolve Channel ZERO issue. (Uninitialized default channel) -+ * -+ * 01 13 2011 yuche.tsai -+ * [WCXRP00000352] [Volunteer Patch][MT6620][Driver] P2P Statsion Record Client List Issue -+ * Update P2P State Debug Message. -+ * -+ * 01 12 2011 yuche.tsai -+ * [WCXRP00000353] [Volunteer Patch][MT6620][Driver] Desired Non-HT Rate Set update -+ * when STA record is created under AP Mode. -+ * Fix bug when allocating message buffer. -+ * -+ * 01 12 2011 yuche.tsai -+ * [WCXRP00000353] [Volunteer Patch][MT6620][Driver] Desired Non-HT Rate Set update -+ * when STA record is created under AP Mode. -+ * Update Phy Type Set. When legacy client is connected, it can use 11b rate, -+ * but if the P2P device is connected, 11b rate is not allowed. -+ * -+ * 01 12 2011 yuche.tsai -+ * [WCXRP00000352] [Volunteer Patch][MT6620][Driver] P2P Statsion Record Client List Issue -+ * 1. Modify Channel Acquire Time of AP mode from 5s to 1s. -+ * 2. Call cnmP2pIsPermit() before active P2P network. -+ * 3. Add channel selection support for AP mode. -+ * -+ * 01 12 2011 yuche.tsai -+ * [WCXRP00000352] [Volunteer Patch][MT6620][Driver] P2P Statsion Record Client List Issue -+ * Fix Bug of reference to NULL pointer. -+ * -+ * 01 12 2011 yuche.tsai -+ * [WCXRP00000352] [Volunteer Patch][MT6620][Driver] P2P Statsion Record Client List Issue -+ * Modify some behavior of AP mode. -+ * -+ * 01 12 2011 yuche.tsai -+ * [WCXRP00000352] [Volunteer Patch][MT6620][Driver] P2P Statsion Record Client List Issue -+ * Fix bug of wrong pointer check. -+ * -+ * 01 12 2011 yuche.tsai -+ * [WCXRP00000352] [Volunteer Patch][MT6620][Driver] P2P Statsion Record Client List Issue -+ * Fix Compile Error. -+ * -+ * 01 11 2011 yuche.tsai -+ * [WCXRP00000352] [Volunteer Patch][MT6620][Driver] P2P Statsion Record Client List Issue -+ * Add station record into client list before change it state from STATE_2 to STATE_3. -+ * -+ * 01 05 2011 yuche.tsai -+ * [WCXRP00000345] [MT6620][Volunteer Patch] P2P may issue a SSID specified scan request, -+ * but the SSID length is still invalid. -+ * Specify SSID Type when issue a scan request. -+ * -+ * 01 05 2011 cp.wu -+ * [WCXRP00000338] [MT6620 Wi-Fi][Driver] Separate kalMemAlloc into kmalloc and vmalloc implementations -+ * to ease physically continuous memory demands -+ * correct typo -+ * -+ * 01 05 2011 george.huang -+ * [WCXRP00000343] [MT6620 Wi-Fi] Add TSF reset path for concurrent operation -+ * modify NOA update path for preventing assertion false alarm. -+ * -+ * 01 04 2011 cp.wu -+ * [WCXRP00000338] [MT6620 Wi-Fi][Driver] Separate kalMemAlloc into kmalloc and vmalloc implementations -+ * to ease physically continuous memory demands -+ * separate kalMemAlloc() into virtually-continuous and physically-continuous type to ease slab system pressure -+ * -+ * 01 03 2011 wh.su -+ * [WCXRP00000326] [MT6620][Wi-Fi][Driver] check in the binary format gl_sec.o.new instead of use change type!!! -+ * let the p2p ap mode acept a legacy device join. -+ * -+ * 12 22 2010 yuche.tsai -+ * [WCXRP00000245] 1. Invitation Request/Response. -+2. Provision Discovery Request/Response -+ -+ * Fix Compile Error. -+ * -+ * 12 15 2010 yuche.tsai -+ * [WCXRP00000245] 1. Invitation Request/Response. -+2. Provision Discovery Request/Response -+ -+ * Refine Connection Flow. -+ * -+ * 12 08 2010 yuche.tsai -+ * [WCXRP00000245] [MT6620][Driver] Invitation & Provision Discovery Feature Check-in -+ * [WCXRP000000245][MT6620][Driver] Invitation Request Feature Add -+ * -+ * 12 08 2010 yuche.tsai -+ * [WCXRP00000244] [MT6620][Driver] Add station record type for each client when in AP mode. -+ * Change STA Type under AP mode. We would tell if client is a P2P device or a legacy client -+ * by checking the P2P IE in assoc req frame. -+ * -+ * 12 07 2010 cm.chang -+ * [WCXRP00000239] MT6620 Wi-Fi][Driver][FW] Merge concurrent branch back to maintrunk -+ * The order of invoking nicUpdateBss() and rlm functions -+ * -+ * 12 02 2010 yuche.tsai -+ * NULL -+ * Update P2P Connection Policy for Invitation. -+ * -+ * 12 02 2010 yuche.tsai -+ * NULL -+ * Update P2P Connection Policy for Invitation & Provision Discovery. -+ * -+ * 11 30 2010 yuche.tsai -+ * NULL -+ * Invitation & Provision Discovery Indication. -+ * -+ * 11 30 2010 yuche.tsai -+ * NULL -+ * Update Configure Method indication & selection for Provision Discovery & GO_NEGO_REQ -+ * -+ * 11 30 2010 yuche.tsai -+ * NULL -+ * Update RCIP value when RX assoc request frame. -+ * -+ * 11 29 2010 yuche.tsai -+ * NULL -+ * Update P2P related function for INVITATION & PROVISION DISCOVERY. -+ * -+ * 11 26 2010 george.huang -+ * [WCXRP00000152] [MT6620 Wi-Fi] AP mode power saving function -+ * Update P2P PS for NOA function. -+ * -+ * 11 25 2010 yuche.tsai -+ * NULL -+ * Update Code for Invitation Related Function. -+ * -+ * 11 17 2010 wh.su -+ * [WCXRP00000164] [MT6620 Wi-Fi][Driver] Support the p2p random SSID[WCXRP00000179] [MT6620 Wi-Fi][FW] -+ * Set the Tx lowest rate at wlan table for normal operation -+ * fixed some ASSERT check. -+ * -+ * 11 05 2010 wh.su -+ * [WCXRP00000164] [MT6620 Wi-Fi][Driver] Support the p2p random SSID -+ * fixed the p2p role code error. -+ * -+ * 11 04 2010 wh.su -+ * [WCXRP00000164] [MT6620 Wi-Fi][Driver] Support the p2p random SSID -+ * adding the p2p random ssid support. -+ * -+ * 10 20 2010 wh.su -+ * [WCXRP00000124] [MT6620 Wi-Fi] [Driver] Support the dissolve P2P Group -+ * fixed the ASSERT check error -+ * -+ * 10 20 2010 wh.su -+ * [WCXRP00000124] [MT6620 Wi-Fi] [Driver] Support the dissolve P2P Group -+ * Add the code to support disconnect p2p group -+ * -+ * 10 19 2010 wh.su -+ * [WCXRP00000085] [MT6620 Wif-Fi] [Driver] update the modified p2p state -+ * machine[WCXRP00000102] [MT6620 Wi-Fi] [FW] Add a compiling flag and code for support Direct GO at Android -+ * fixed the compiling error. -+ * -+ * 10 14 2010 wh.su -+ * [WCXRP00000102] [MT6620 Wi-Fi] [FW] Add a compiling flag and code for support Direct GO at Android -+ * adding a code to support Direct GO with a compiling flag . -+ * -+ * 10 08 2010 cp.wu -+ * [WCXRP00000087] [MT6620 Wi-Fi][Driver] Cannot connect to 5GHz AP, driver will cause FW assert. -+ * correct erroneous logic: specifying eBand with incompatible eSco -+ * -+ * 10 08 2010 wh.su -+ * [WCXRP00000085] [MT6620 Wif-Fi] [Driver] update the modified p2p state machine -+ * fixed the compiling error. -+ * -+ * 10 08 2010 wh.su -+ * [WCXRP00000085] [MT6620 Wif-Fi] [Driver] update the modified p2p state machine -+ * update the frog's new p2p state machine. -+ * -+ * 09 10 2010 wh.su -+ * NULL -+ * fixed the compiling error at WinXP. -+ * -+ * 09 07 2010 yuche.tsai -+ * NULL -+ * Reset Common IE Buffer of P2P INFO when scan request is issued. -+ * If an action frame other than public action frame is received, return direcly. -+ * -+ * 09 07 2010 wh.su -+ * NULL -+ * adding the code for beacon/probe req/ probe rsp wsc ie at p2p. -+ * -+ * 09 06 2010 wh.su -+ * NULL -+ * let the p2p can set the privacy bit at beacon and rsn ie at assoc req at key handshake state. -+ * -+ * 09 03 2010 kevin.huang -+ * NULL -+ * Refine #include sequence and solve recursive/nested #include issue -+ * -+ * 08 26 2010 yuche.tsai -+ * NULL -+ * Add P2P Connection Abort Event Message handler. -+ * -+ * 08 24 2010 cm.chang -+ * NULL -+ * Support RLM initail channel of Ad-hoc, P2P and BOW -+ * -+ * 08 23 2010 yuche.tsai -+ * NULL -+ * 1. Fix Interface Address from GO Nego Req/Rsp is not correct. -+ * 2. Fix GO mode does not change media state after station connected. -+ * 3. Fix STA don't response probe request when there is a connection request. -+ * -+ * 08 20 2010 cm.chang -+ * NULL -+ * Migrate RLM code to host from FW -+ * -+ * 08 20 2010 kevin.huang -+ * NULL -+ * Modify AAA Module for changing STA STATE 3 at p2p/bowRunEventAAAComplete() -+ * -+ * 08 20 2010 yuche.tsai -+ * NULL -+ * Add Glue Layer indication. -+ * -+ * 08 17 2010 yuche.tsai -+ * NULL -+ * Fix compile warning under Linux. -+ * -+ * 08 17 2010 yuche.tsai -+ * NULL -+ * Fix some P2P FSM bug. -+ * -+ * 08 16 2010 yuche.tsai -+ * NULL -+ * Add random Interface Address Generation support. -+ * -+ * 08 16 2010 yuche.tsai -+ * NULL -+ * Fix some P2P FSM bug. -+ * -+ * 08 16 2010 yuche.tsai -+ * NULL -+ * Update P2P FSM code for GO Nego. -+ * -+ * 08 16 2010 kevin.huang -+ * NULL -+ * Refine AAA functions -+ * -+ * 08 12 2010 kevin.huang -+ * NULL -+ * Refine bssProcessProbeRequest() and bssSendBeaconProbeResponse() -+ * -+ * 08 12 2010 yuche.tsai -+ * NULL -+ * Join complete indication. -+ * -+ * 08 11 2010 yuche.tsai -+ * NULL -+ * Add two boolean in connection request. -+ * Based on these two boolean value, P2P FSM should -+ * decide to do invitation or group formation or start a GO directly. -+ * -+ * 08 11 2010 yuche.tsai -+ * NULL -+ * Update P2P FSM, currently P2P Device Discovery is verified. -+ * -+ * 08 05 2010 yuche.tsai -+ * NULL -+ * Update P2P FSM for group formation. -+ * -+ * 08 03 2010 george.huang -+ * NULL -+ * handle event for updating NOA parameters indicated from FW -+ * -+ * 08 03 2010 cp.wu -+ * NULL -+ * limit build always needs spin-lock declaration. -+ * -+ * 08 02 2010 yuche.tsai -+ * NULL -+ * P2P Group Negotiation Code Check in. -+ * -+ * 07 26 2010 yuche.tsai -+ * -+ * Add P2P FSM code check in. -+ * -+ * 07 21 2010 yuche.tsai -+ * -+ * Add P2P Scan & Scan Result Parsing & Saving. -+ * -+ * 07 19 2010 yuche.tsai -+ * -+ * Update P2P FSM. -+ * -+ * 07 09 2010 george.huang -+ * -+ * [WPD00001556] Migrate PM variables from FW to driver: for composing QoS Info -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 21 2010 yuche.tsai -+ * [WPD00003839][MT6620 5931][P2P] Feature migration -+ * Fix compile error while enable WIFI_DIRECT support. -+ * -+ * 06 21 2010 yuche.tsai -+ * [WPD00003839][MT6620 5931][P2P] Feature migration -+ * Update P2P Function call. -+ * -+ * 06 17 2010 yuche.tsai -+ * [WPD00003839][MT6620 5931][P2P] Feature migration -+ * First draft for migration P2P FSM from FW to Driver. -+ * -+ * 04 19 2010 kevin.huang -+ * [BORA00000714][WIFISYS][New Feature]Beacon Timeout Support -+ * Add Beacon Timeout Support and will send Null frame to diagnose connection -+ * -+ * 03 18 2010 kevin.huang -+ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support -+ * Rename CFG flag for P2P -+ * -+ * 02 26 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Add code to test P2P GO -+ * -+ * 02 23 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Add Wi-Fi Direct SSID and P2P GO Test Mode -+ * -+ * 02 05 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Modify code due to BAND_24G define was changed -+ * -+ * 02 05 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Revise data structure to share the same BSS_INFO_T for avoiding coding error -+ * -+ * 02 04 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Add AAA Module Support, Revise Net Type to Net Type Index for array lookup -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "precomp.h" -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+#if DBG -+/*lint -save -e64 Type mismatch */ -+static PUINT_8 apucDebugP2pState[P2P_STATE_NUM] = { -+ (PUINT_8) DISP_STRING("P2P_STATE_IDLE"), -+ (PUINT_8) DISP_STRING("P2P_STATE_SCAN"), -+ (PUINT_8) DISP_STRING("P2P_STATE_AP_CHANNEL_DETECT"), -+ (PUINT_8) DISP_STRING("P2P_STATE_REQING_CHANNEL"), -+ (PUINT_8) DISP_STRING("P2P_STATE_CHNL_ON_HAND"), -+ (PUINT_8) DISP_STRING("P2P_STATE_GC_JOIN") -+}; -+ -+/*lint -restore */ -+#else -+static UINT_8 apucDebugP2pState[P2P_STATE_NUM] = { -+ P2P_STATE_IDLE, -+ P2P_STATE_SCAN, -+ P2P_STATE_AP_CHANNEL_DETECT, -+ P2P_STATE_REQING_CHANNEL, -+ P2P_STATE_CHNL_ON_HAND, -+ P2P_STATE_GC_JOIN -+}; -+ -+#endif /* DBG */ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+/* p2pStateXXX : Processing P2P FSM related action. -+ * p2pFSMXXX : Control P2P FSM flow. -+ * p2pFuncXXX : Function for doing one thing. -+ */ -+VOID p2pFsmInit(IN P_ADAPTER_T prAdapter) -+{ -+ -+ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; -+ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; -+ -+ do { -+ ASSERT_BREAK(prAdapter != NULL); -+ -+ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; -+ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); -+ -+ ASSERT_BREAK(prP2pFsmInfo != NULL); -+ -+ LINK_INITIALIZE(&(prP2pFsmInfo->rMsgEventQueue)); -+ LINK_INITIALIZE(&(prP2pBssInfo->rStaRecOfClientList)); -+ -+ prP2pFsmInfo->eCurrentState = prP2pFsmInfo->ePreviousState = P2P_STATE_IDLE; -+ prP2pFsmInfo->prTargetBss = NULL; -+ prP2pFsmInfo->fgIsWPSMode = 0; -+ -+ cnmTimerInitTimer(prAdapter, -+ &(prAdapter->rP2pFsmTimeoutTimer), -+ (PFN_MGMT_TIMEOUT_FUNC) p2pFsmRunEventFsmTimeout, (ULONG) prP2pFsmInfo); -+ -+ /* 4 <2> Initiate BSS_INFO_T - common part */ -+ BSS_INFO_INIT(prAdapter, NETWORK_TYPE_P2P_INDEX); -+ -+ /* 4 <2.1> Initiate BSS_INFO_T - Setup HW ID */ -+ prP2pBssInfo->ucConfigAdHocAPMode = AP_MODE_11G_P2P; -+ prP2pBssInfo->ucHwDefaultFixedRateCode = RATE_OFDM_6M; -+ -+ prP2pBssInfo->ucNonHTBasicPhyType = (UINT_8) -+ rNonHTApModeAttributes[prP2pBssInfo->ucConfigAdHocAPMode].ePhyTypeIndex; -+ prP2pBssInfo->u2BSSBasicRateSet = -+ rNonHTApModeAttributes[prP2pBssInfo->ucConfigAdHocAPMode].u2BSSBasicRateSet; -+ -+ prP2pBssInfo->u2OperationalRateSet = -+ rNonHTPhyAttributes[prP2pBssInfo->ucNonHTBasicPhyType].u2SupportedRateSet; -+ -+ rateGetDataRatesFromRateSet(prP2pBssInfo->u2OperationalRateSet, -+ prP2pBssInfo->u2BSSBasicRateSet, -+ prP2pBssInfo->aucAllSupportedRates, &prP2pBssInfo->ucAllSupportedRatesLen); -+ -+ prP2pBssInfo->prBeacon = cnmMgtPktAlloc(prAdapter, -+ OFFSET_OF(WLAN_BEACON_FRAME_T, aucInfoElem[0]) + MAX_IE_LENGTH); -+ -+ if (prP2pBssInfo->prBeacon) { -+ prP2pBssInfo->prBeacon->eSrc = TX_PACKET_MGMT; -+ prP2pBssInfo->prBeacon->ucStaRecIndex = 0xFF; /* NULL STA_REC */ -+ prP2pBssInfo->prBeacon->ucNetworkType = NETWORK_TYPE_P2P_INDEX; -+ } else { -+ /* Out of memory. */ -+ ASSERT(FALSE); -+ } -+ -+ prP2pBssInfo->eCurrentOPMode = OP_MODE_NUM; -+ -+ prP2pBssInfo->rPmProfSetupInfo.ucBmpDeliveryAC = PM_UAPSD_ALL; -+ prP2pBssInfo->rPmProfSetupInfo.ucBmpTriggerAC = PM_UAPSD_ALL; -+ prP2pBssInfo->rPmProfSetupInfo.ucUapsdSp = WMM_MAX_SP_LENGTH_2; -+ prP2pBssInfo->ucPrimaryChannel = P2P_DEFAULT_LISTEN_CHANNEL; -+ prP2pBssInfo->eBand = BAND_2G4; -+ prP2pBssInfo->eBssSCO = CHNL_EXT_SCN; -+ -+ if (prAdapter->rWifiVar.fgSupportQoS) -+ prP2pBssInfo->fgIsQBSS = TRUE; -+ else -+ prP2pBssInfo->fgIsQBSS = FALSE; -+ -+ SET_NET_PWR_STATE_IDLE(prAdapter, NETWORK_TYPE_P2P_INDEX); -+ -+ p2pFsmStateTransition(prAdapter, prP2pFsmInfo, P2P_STATE_IDLE); -+ -+ } while (FALSE); -+ -+} /* p2pFsmInit */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief The function is used to uninitialize the value in P2P_FSM_INFO_T for -+* P2P FSM operation -+* -+* @param (none) -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID p2pFsmUninit(IN P_ADAPTER_T prAdapter) -+{ -+ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; -+ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; -+ -+ do { -+ ASSERT_BREAK(prAdapter != NULL); -+ -+ DEBUGFUNC("p2pFsmUninit()"); -+ DBGLOG(P2P, INFO, "->p2pFsmUninit()\n"); -+ -+ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; -+ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); -+ -+ p2pFuncSwitchOPMode(prAdapter, prP2pBssInfo, OP_MODE_P2P_DEVICE, TRUE); -+ -+ p2pFsmRunEventAbort(prAdapter, prP2pFsmInfo); -+ -+ p2pStateAbort_IDLE(prAdapter, prP2pFsmInfo, P2P_STATE_NUM); -+ -+ UNSET_NET_ACTIVE(prAdapter, NETWORK_TYPE_P2P_INDEX); -+ -+ wlanAcquirePowerControl(prAdapter); -+ -+ /* Release all pending CMD queue. */ -+ DBGLOG(P2P, TRACE, "p2pFsmUninit: wlanProcessCommandQueue, num of element:%d\n", -+ (UINT_32) prAdapter->prGlueInfo->rCmdQueue.u4NumElem); -+ wlanProcessCommandQueue(prAdapter, &prAdapter->prGlueInfo->rCmdQueue); -+ -+ wlanReleasePowerControl(prAdapter); -+ -+ /* Release pending mgmt frame, -+ * mgmt frame may be pending by CMD without resource. -+ */ -+ kalClearMgmtFramesByNetType(prAdapter->prGlueInfo, NETWORK_TYPE_P2P_INDEX); -+ -+ /* Clear PendingCmdQue */ -+ wlanReleasePendingCMDbyNetwork(prAdapter, NETWORK_TYPE_P2P_INDEX); -+ -+ if (prP2pBssInfo->prBeacon) { -+ cnmMgtPktFree(prAdapter, prP2pBssInfo->prBeacon); -+ prP2pBssInfo->prBeacon = NULL; -+ } -+ -+ } while (FALSE); -+ -+ return; -+ -+} /* end of p2pFsmUninit() */ -+ -+VOID p2pFsmStateTransition(IN P_ADAPTER_T prAdapter, IN P_P2P_FSM_INFO_T prP2pFsmInfo, IN ENUM_P2P_STATE_T eNextState) -+{ -+ BOOLEAN fgIsTransOut = (BOOLEAN) FALSE; -+ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; -+ P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo = (P_P2P_SPECIFIC_BSS_INFO_T) NULL; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prP2pFsmInfo != NULL)); -+ -+ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); -+ prP2pSpecificBssInfo = prAdapter->rWifiVar.prP2pSpecificBssInfo; -+ -+ if (!IS_BSS_ACTIVE(prP2pBssInfo)) { -+ if (!cnmP2PIsPermitted(prAdapter)) -+ return; -+ -+ SET_NET_ACTIVE(prAdapter, NETWORK_TYPE_P2P_INDEX); -+ nicActivateNetwork(prAdapter, NETWORK_TYPE_P2P_INDEX); -+ } -+ -+ fgIsTransOut = fgIsTransOut ? FALSE : TRUE; -+ -+ if (!fgIsTransOut) { -+#if DBG -+ DBGLOG(P2P, STATE, "TRANSITION: [%s] -> [%s]\n", -+ apucDebugP2pState[prP2pFsmInfo->eCurrentState], -+ apucDebugP2pState[eNextState]); -+#else -+ DBGLOG(P2P, STATE, "[%d] TRANSITION: [%d] -> [%d]\n", -+ DBG_P2P_IDX, apucDebugP2pState[prP2pFsmInfo->eCurrentState], -+ apucDebugP2pState[eNextState]); -+#endif -+ -+ /* Transition into current state. */ -+ prP2pFsmInfo->ePreviousState = prP2pFsmInfo->eCurrentState; -+ prP2pFsmInfo->eCurrentState = eNextState; -+ } -+ -+ switch (prP2pFsmInfo->eCurrentState) { -+ case P2P_STATE_IDLE: -+ if (fgIsTransOut) -+ p2pStateAbort_IDLE(prAdapter, prP2pFsmInfo, eNextState); -+ else -+ fgIsTransOut = p2pStateInit_IDLE(prAdapter, prP2pFsmInfo, prP2pBssInfo, &eNextState); -+ break; -+ case P2P_STATE_SCAN: -+ if (fgIsTransOut) { -+ /* Scan done / scan canceled. */ -+ p2pStateAbort_SCAN(prAdapter, prP2pFsmInfo, eNextState); -+ } else { -+ /* Initial scan request. */ -+ p2pStateInit_SCAN(prAdapter, prP2pFsmInfo); -+ } -+ -+ break; -+ case P2P_STATE_AP_CHANNEL_DETECT: -+ if (fgIsTransOut) { -+ /* Scan done */ -+ /* Get sparse channel result. */ -+ p2pStateAbort_AP_CHANNEL_DETECT(prAdapter, -+ prP2pFsmInfo, prP2pSpecificBssInfo, eNextState); -+ } -+ -+ else { -+ /* Initial passive scan request. */ -+ p2pStateInit_AP_CHANNEL_DETECT(prAdapter, prP2pFsmInfo); -+ } -+ -+ break; -+ case P2P_STATE_REQING_CHANNEL: -+ if (fgIsTransOut) { -+ /* Channel on hand / Channel canceled. */ -+ p2pStateAbort_REQING_CHANNEL(prAdapter, prP2pFsmInfo, eNextState); -+ } else { -+ /* Initial channel request. */ -+ p2pFuncAcquireCh(prAdapter, &(prP2pFsmInfo->rChnlReqInfo)); -+ } -+ -+ break; -+ case P2P_STATE_CHNL_ON_HAND: -+ if (fgIsTransOut) { -+ p2pStateAbort_CHNL_ON_HAND(prAdapter, prP2pFsmInfo, prP2pBssInfo, eNextState); -+ } else { -+ /* Initial channel ready. */ -+ /* Send channel ready event. */ -+ /* Start a FSM timer. */ -+ p2pStateInit_CHNL_ON_HAND(prAdapter, prP2pBssInfo, prP2pFsmInfo); -+ } -+ -+ break; -+ case P2P_STATE_GC_JOIN: -+ if (fgIsTransOut) { -+ /* Join complete / join canceled. */ -+ p2pStateAbort_GC_JOIN(prAdapter, prP2pFsmInfo, &(prP2pFsmInfo->rJoinInfo), eNextState); -+ } else { -+ if (prP2pFsmInfo->prTargetBss == NULL) { -+ ASSERT(FALSE); -+ } else { -+ /* Send request to SAA module. */ -+ p2pStateInit_GC_JOIN(prAdapter, -+ prP2pFsmInfo, -+ prP2pBssInfo, -+ &(prP2pFsmInfo->rJoinInfo), prP2pFsmInfo->prTargetBss); -+ } -+ } -+ -+ break; -+ default: -+ break; -+ } -+ -+ } while (fgIsTransOut); -+ -+} /* p2pFsmStateTransition */ -+ -+VOID p2pFsmRunEventSwitchOPMode(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) -+{ -+ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; -+ P_MSG_P2P_SWITCH_OP_MODE_T prSwitchOpMode = (P_MSG_P2P_SWITCH_OP_MODE_T) prMsgHdr; -+ P_P2P_CONNECTION_SETTINGS_T prP2pConnSettings = (P_P2P_CONNECTION_SETTINGS_T) NULL; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prSwitchOpMode != NULL)); -+ -+ DBGLOG(P2P, TRACE, "p2pFsmRunEventSwitchOPMode\n"); -+ -+ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); -+ prP2pConnSettings = prAdapter->rWifiVar.prP2PConnSettings; -+ -+ if (prSwitchOpMode->eOpMode >= OP_MODE_NUM) { -+ ASSERT(FALSE); -+ break; -+ } -+ -+ /* P2P Device / GC. */ -+ p2pFuncSwitchOPMode(prAdapter, prP2pBssInfo, prSwitchOpMode->eOpMode, TRUE); -+ -+ } while (FALSE); -+ -+ if (prMsgHdr) -+ cnmMemFree(prAdapter, prMsgHdr); -+ -+} /* p2pFsmRunEventSwitchOPMode */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is used to handle scan done event during Device Discovery. -+* -+* \param[in] prAdapter Pointer of ADAPTER_T -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID p2pFsmRunEventScanDone(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) -+{ -+ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; -+ P_P2P_SCAN_REQ_INFO_T prScanReqInfo = (P_P2P_SCAN_REQ_INFO_T) NULL; -+ P_MSG_SCN_SCAN_DONE prScanDoneMsg = (P_MSG_SCN_SCAN_DONE) NULL; -+ ENUM_P2P_STATE_T eNextState = P2P_STATE_NUM; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prMsgHdr != NULL)); -+ -+ /* This scan done event is either for "SCAN" phase or "SEARCH" state or "LISTEN" state. -+ * The scan done for SCAN phase & SEARCH state doesn't imply Device -+ * Discovery over. -+ */ -+ DBGLOG(P2P, TRACE, "P2P Scan Done Event\n"); -+ -+ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; -+ -+ if (prP2pFsmInfo == NULL) -+ break; -+ -+ prScanReqInfo = &(prP2pFsmInfo->rScanReqInfo); -+ prScanDoneMsg = (P_MSG_SCN_SCAN_DONE) prMsgHdr; -+ -+ if (prScanDoneMsg->ucSeqNum != prScanReqInfo->ucSeqNumOfScnMsg) { -+ /* Scan Done message sequence number mismatch. -+ * Ignore this event. (P2P FSM issue two scan events.) -+ */ -+ /* The scan request has been cancelled. -+ * Ignore this message. It is possible. -+ */ -+ DBGLOG(P2P, TRACE, "P2P Scan Don SeqNum:%d <-> P2P Fsm SCAN Msg:%d\n", -+ prScanDoneMsg->ucSeqNum, prScanReqInfo->ucSeqNumOfScnMsg); -+ -+ break; -+ } -+ -+ switch (prP2pFsmInfo->eCurrentState) { -+ case P2P_STATE_SCAN: -+ { -+ P_P2P_CONNECTION_REQ_INFO_T prConnReqInfo = &(prP2pFsmInfo->rConnReqInfo); -+ -+ prScanReqInfo->fgIsAbort = FALSE; -+ -+ if (prConnReqInfo->fgIsConnRequest) { -+ prP2pFsmInfo->prTargetBss = p2pFuncKeepOnConnection(prAdapter, -+ &prP2pFsmInfo->rConnReqInfo, -+ &prP2pFsmInfo->rChnlReqInfo, -+ &prP2pFsmInfo->rScanReqInfo); -+ if (prP2pFsmInfo->prTargetBss == NULL) -+ eNextState = P2P_STATE_SCAN; -+ else -+ eNextState = P2P_STATE_REQING_CHANNEL; -+ } else { -+ eNextState = P2P_STATE_IDLE; -+ } -+ -+ } -+ break; -+ case P2P_STATE_AP_CHANNEL_DETECT: -+ eNextState = P2P_STATE_REQING_CHANNEL; -+ break; -+ default: -+ /* Unexpected channel scan done event without being chanceled. */ -+ ASSERT(FALSE); -+ break; -+ } -+ -+ prScanReqInfo->fgIsScanRequest = FALSE; -+ -+ p2pFsmStateTransition(prAdapter, prP2pFsmInfo, eNextState); -+ -+ } while (FALSE); -+ -+ if (prMsgHdr) -+ cnmMemFree(prAdapter, prMsgHdr); -+ -+} /* p2pFsmRunEventScanDone */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is call when channel is granted by CNM module from FW. -+* -+* \param[in] prAdapter Pointer of ADAPTER_T -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID p2pFsmRunEventChGrant(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) -+{ -+ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; -+ P_P2P_CHNL_REQ_INFO_T prChnlReqInfo = (P_P2P_CHNL_REQ_INFO_T) NULL; -+ P_MSG_CH_GRANT_T prMsgChGrant = (P_MSG_CH_GRANT_T) NULL; -+ UINT_8 ucTokenID = 0; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prMsgHdr != NULL)); -+ -+ DBGLOG(P2P, TRACE, "P2P Run Event Channel Grant\n"); -+ -+ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; -+ -+ if (prP2pFsmInfo == NULL) -+ break; -+ -+ prMsgChGrant = (P_MSG_CH_GRANT_T) prMsgHdr; -+ ucTokenID = prMsgChGrant->ucTokenID; -+ prP2pFsmInfo->u4GrantInterval = prMsgChGrant->u4GrantInterval; -+ -+ prChnlReqInfo = &(prP2pFsmInfo->rChnlReqInfo); -+ -+ if (ucTokenID == prChnlReqInfo->ucSeqNumOfChReq) { -+ ENUM_P2P_STATE_T eNextState = P2P_STATE_NUM; -+ -+ switch (prP2pFsmInfo->eCurrentState) { -+ case P2P_STATE_REQING_CHANNEL: -+ switch (prChnlReqInfo->eChannelReqType) { -+ case CHANNEL_REQ_TYPE_REMAIN_ON_CHANNEL: -+ eNextState = P2P_STATE_CHNL_ON_HAND; -+ break; -+ case CHANNEL_REQ_TYPE_GC_JOIN_REQ: -+ eNextState = P2P_STATE_GC_JOIN; -+ break; -+ case CHANNEL_REQ_TYPE_GO_START_BSS: -+ eNextState = P2P_STATE_IDLE; -+ break; -+ default: -+ break; -+ } -+ -+ p2pFsmStateTransition(prAdapter, prP2pFsmInfo, eNextState); -+ break; -+ default: -+ /* Channel is granted under unexpected state. -+ * Driver should cancel channel privileagea before leaving the states. -+ */ -+ ASSERT(FALSE); -+ break; -+ } -+ -+ } else { -+ /* Channel requsted, but released. */ -+ /* ASSERT(!prChnlReqInfo->fgIsChannelRequested); */ -+ DBGLOG(P2P, TRACE, "Channel requsted, but released\n"); -+ } -+ } while (FALSE); -+ -+ if (prMsgHdr) -+ cnmMemFree(prAdapter, prMsgHdr); -+ -+ return; -+ -+} /* p2pFsmRunEventChGrant */ -+ -+VOID p2pFsmRunEventChannelRequest(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) -+{ -+ P_P2P_CHNL_REQ_INFO_T prChnlReqInfo = (P_P2P_CHNL_REQ_INFO_T) NULL; -+ P_MSG_P2P_CHNL_REQUEST_T prP2pChnlReqMsg = (P_MSG_P2P_CHNL_REQUEST_T) NULL; -+ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; -+ ENUM_P2P_STATE_T eNextState = P2P_STATE_NUM; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prMsgHdr != NULL)); -+ -+ prP2pChnlReqMsg = (P_MSG_P2P_CHNL_REQUEST_T) prMsgHdr; -+ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; -+ -+ if (prP2pFsmInfo == NULL) -+ break; -+ -+ prChnlReqInfo = &(prP2pFsmInfo->rChnlReqInfo); -+ -+ DBGLOG(P2P, TRACE, "p2pFsmRunEventChannelRequest\n"); -+ -+ /* Special case of time renewing for same frequency. */ -+ if ((prP2pFsmInfo->eCurrentState == P2P_STATE_CHNL_ON_HAND) && -+ (prChnlReqInfo->ucReqChnlNum == prP2pChnlReqMsg->rChannelInfo.ucChannelNum) && -+ (prChnlReqInfo->eBand == prP2pChnlReqMsg->rChannelInfo.eBand) && -+ (prChnlReqInfo->eChnlSco == prP2pChnlReqMsg->eChnlSco)) { -+ -+ ASSERT(prChnlReqInfo->fgIsChannelRequested == TRUE); -+ ASSERT(prChnlReqInfo->eChannelReqType == CHANNEL_REQ_TYPE_REMAIN_ON_CHANNEL); -+ -+ prChnlReqInfo->u8Cookie = prP2pChnlReqMsg->u8Cookie; -+ prChnlReqInfo->u4MaxInterval = prP2pChnlReqMsg->u4Duration; -+ -+ /* Re-enter the state. */ -+ eNextState = P2P_STATE_CHNL_ON_HAND; -+ } else { -+ -+ /* Make sure the state is in IDLE state. */ -+ p2pFsmRunEventAbort(prAdapter, prP2pFsmInfo); -+ -+ /* Cookie can only be assign after abort.(for indication) */ -+ prChnlReqInfo->u8Cookie = prP2pChnlReqMsg->u8Cookie; -+ prChnlReqInfo->ucReqChnlNum = prP2pChnlReqMsg->rChannelInfo.ucChannelNum; -+ prChnlReqInfo->eBand = prP2pChnlReqMsg->rChannelInfo.eBand; -+ prChnlReqInfo->eChnlSco = prP2pChnlReqMsg->eChnlSco; -+ prChnlReqInfo->u4MaxInterval = prP2pChnlReqMsg->u4Duration; -+ prChnlReqInfo->eChannelReqType = CHANNEL_REQ_TYPE_REMAIN_ON_CHANNEL; -+ -+ eNextState = P2P_STATE_REQING_CHANNEL; -+ } -+ -+ p2pFsmStateTransition(prAdapter, prP2pFsmInfo, eNextState); -+ -+ } while (FALSE); -+ -+ if (prMsgHdr) -+ cnmMemFree(prAdapter, prMsgHdr); -+ -+} /* p2pFsmRunEventChannelRequest */ -+ -+VOID p2pFsmRunEventChannelAbort(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) -+{ -+ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; -+ P_MSG_P2P_CHNL_ABORT_T prChnlAbortMsg = (P_MSG_P2P_CHNL_ABORT_T) NULL; -+ P_P2P_CHNL_REQ_INFO_T prChnlReqInfo = (P_P2P_CHNL_REQ_INFO_T) NULL; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prMsgHdr != NULL)); -+ -+ prChnlAbortMsg = (P_MSG_P2P_CHNL_ABORT_T) prMsgHdr; -+ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; -+ -+ if (prP2pFsmInfo == NULL) -+ break; -+ -+ prChnlReqInfo = &prP2pFsmInfo->rChnlReqInfo; -+ -+ DBGLOG(P2P, TRACE, "p2pFsmRunEventChannelAbort\n"); -+ -+ if ((prChnlAbortMsg->u8Cookie == prChnlReqInfo->u8Cookie) && (prChnlReqInfo->fgIsChannelRequested)) { -+ -+ ASSERT((prP2pFsmInfo->eCurrentState == P2P_STATE_REQING_CHANNEL || -+ (prP2pFsmInfo->eCurrentState == P2P_STATE_CHNL_ON_HAND))); -+ -+ p2pFsmStateTransition(prAdapter, prP2pFsmInfo, P2P_STATE_IDLE); -+ } -+ -+ } while (FALSE); -+ -+ if (prMsgHdr) -+ cnmMemFree(prAdapter, prMsgHdr); -+ -+} /* p2pFsmRunEventChannelAbort */ -+ -+VOID p2pFsmRunEventScanRequest(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) -+{ -+ -+ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; -+ P_MSG_P2P_SCAN_REQUEST_T prP2pScanReqMsg = (P_MSG_P2P_SCAN_REQUEST_T) NULL; -+ P_P2P_SCAN_REQ_INFO_T prScanReqInfo = (P_P2P_SCAN_REQ_INFO_T) NULL; -+ UINT_32 u4ChnlListSize = 0; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prMsgHdr != NULL)); -+ -+ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; -+ -+ if (prP2pFsmInfo == NULL) -+ break; -+ -+ prP2pScanReqMsg = (P_MSG_P2P_SCAN_REQUEST_T) prMsgHdr; -+ prScanReqInfo = &(prP2pFsmInfo->rScanReqInfo); -+ -+ DBGLOG(P2P, TRACE, "p2pFsmRunEventScanRequest\n"); -+ -+ /* Make sure the state is in IDLE state. */ -+ p2pFsmRunEventAbort(prAdapter, prP2pFsmInfo); -+ -+ ASSERT(prScanReqInfo->fgIsScanRequest == FALSE); -+ -+ prScanReqInfo->fgIsAbort = TRUE; -+ prScanReqInfo->eScanType = SCAN_TYPE_ACTIVE_SCAN; -+ prScanReqInfo->eChannelSet = SCAN_CHANNEL_SPECIFIED; -+ -+ /* Channel List */ -+ prScanReqInfo->ucNumChannelList = prP2pScanReqMsg->u4NumChannel; -+ DBGLOG(P2P, TRACE, "Scan Request Channel List Number: %d\n", prScanReqInfo->ucNumChannelList); -+ if (prScanReqInfo->ucNumChannelList > MAXIMUM_OPERATION_CHANNEL_LIST) { -+ DBGLOG(P2P, TRACE, "Channel List Number Overloaded: %d, change to: %d\n", -+ prScanReqInfo->ucNumChannelList, MAXIMUM_OPERATION_CHANNEL_LIST); -+ prScanReqInfo->ucNumChannelList = MAXIMUM_OPERATION_CHANNEL_LIST; -+ } -+ -+ u4ChnlListSize = sizeof(RF_CHANNEL_INFO_T) * prScanReqInfo->ucNumChannelList; -+ kalMemCopy(prScanReqInfo->arScanChannelList, prP2pScanReqMsg->arChannelListInfo, u4ChnlListSize); -+ -+ /* TODO: I only take the first SSID. Multiple SSID may be needed in the future. */ -+ /* SSID */ -+ if (prP2pScanReqMsg->i4SsidNum >= 1) -+ kalMemCopy(&(prScanReqInfo->rSsidStruct), prP2pScanReqMsg->prSSID, sizeof(P2P_SSID_STRUCT_T)); -+ else -+ prScanReqInfo->rSsidStruct.ucSsidLen = 0; -+ -+ /* IE Buffer */ -+ kalMemCopy(prScanReqInfo->aucIEBuf, prP2pScanReqMsg->pucIEBuf, prP2pScanReqMsg->u4IELen); -+ -+ prScanReqInfo->u4BufLength = prP2pScanReqMsg->u4IELen; -+ -+ p2pFsmStateTransition(prAdapter, prP2pFsmInfo, P2P_STATE_SCAN); -+ -+ } while (FALSE); -+ -+ if (prMsgHdr) -+ cnmMemFree(prAdapter, prMsgHdr); -+ -+} /* p2pFsmRunEventScanRequest */ -+ -+VOID p2pFsmRunEventScanAbort(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) -+{ -+ -+ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; -+ -+ do { -+ ASSERT_BREAK(prAdapter != NULL); -+ -+ DBGLOG(P2P, TRACE, "p2pFsmRunEventScanAbort\n"); -+ -+ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; -+ -+ if (prP2pFsmInfo->eCurrentState == P2P_STATE_SCAN) { -+ P_P2P_SCAN_REQ_INFO_T prScanReqInfo = &(prP2pFsmInfo->rScanReqInfo); -+ -+ prScanReqInfo->fgIsAbort = TRUE; -+ -+ p2pFsmStateTransition(prAdapter, prP2pFsmInfo, P2P_STATE_IDLE); -+ } -+ -+ } while (FALSE); -+ -+ if (prMsgHdr) -+ cnmMemFree(prAdapter, prMsgHdr); -+ -+} /* p2pFsmRunEventScanAbort */ -+ -+VOID p2pFsmRunEventAbort(IN P_ADAPTER_T prAdapter, IN P_P2P_FSM_INFO_T prP2pFsmInfo) -+{ -+ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prP2pFsmInfo != NULL)); -+ -+ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); -+ -+ DBGLOG(P2P, TRACE, "p2pFsmRunEventAbort\n"); -+ -+ if (prP2pFsmInfo->eCurrentState != P2P_STATE_IDLE) { -+ -+ if (prP2pFsmInfo->eCurrentState == P2P_STATE_SCAN) { -+ -+ P_P2P_SCAN_REQ_INFO_T prScanReqInfo = &(prP2pFsmInfo->rScanReqInfo); -+ -+ prScanReqInfo->fgIsAbort = TRUE; -+ } else if (prP2pFsmInfo->eCurrentState == P2P_STATE_REQING_CHANNEL) { -+ /* 2012/08/06: frog -+ * Prevent Start GO. -+ */ -+ prP2pBssInfo->eIntendOPMode = OP_MODE_NUM; -+ } -+ /* For other state, is there any special action that should be take before leaving? */ -+ -+ p2pFsmStateTransition(prAdapter, prP2pFsmInfo, P2P_STATE_IDLE); -+ } else { -+ /* P2P State IDLE. */ -+ P_P2P_CHNL_REQ_INFO_T prChnlReqInfo = &(prP2pFsmInfo->rChnlReqInfo); -+ -+ if (prChnlReqInfo->fgIsChannelRequested) -+ p2pFuncReleaseCh(prAdapter, prChnlReqInfo); -+ -+ cnmTimerStopTimer(prAdapter, &(prAdapter->rP2pFsmTimeoutTimer)); -+ } -+ -+ } while (FALSE); -+ -+} /* p2pFsmRunEventAbort */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is used to handle FSM Timeout. -+* -+* \param[in] prAdapter Pointer of ADAPTER_T -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID p2pFsmRunEventFsmTimeout(IN P_ADAPTER_T prAdapter, IN ULONG ulParam) -+{ -+ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) ulParam; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prP2pFsmInfo != NULL)); -+ -+ DBGLOG(P2P, TRACE, "P2P FSM Timeout Event\n"); -+ -+ switch (prP2pFsmInfo->eCurrentState) { -+ case P2P_STATE_IDLE: -+ { -+ P_P2P_CHNL_REQ_INFO_T prChnlReqInfo = &prP2pFsmInfo->rChnlReqInfo; -+ -+ if (prChnlReqInfo->fgIsChannelRequested) { -+ p2pFuncReleaseCh(prAdapter, prChnlReqInfo); -+ } else if (IS_NET_PWR_STATE_IDLE(prAdapter, NETWORK_TYPE_P2P_INDEX)) { -+ UNSET_NET_ACTIVE(prAdapter, NETWORK_TYPE_P2P_INDEX); -+ nicDeactivateNetwork(prAdapter, NETWORK_TYPE_P2P_INDEX); -+ } -+ -+ } -+ break; -+ -+/* case P2P_STATE_SCAN: */ -+/* break; */ -+/* case P2P_STATE_AP_CHANNEL_DETECT: */ -+/* break; */ -+/* case P2P_STATE_REQING_CHANNEL: */ -+/* break; */ -+ case P2P_STATE_CHNL_ON_HAND: -+ switch (prP2pFsmInfo->eListenExted) { -+ case P2P_DEV_NOT_EXT_LISTEN: -+ case P2P_DEV_EXT_LISTEN_WAITFOR_TIMEOUT: -+ DBGLOG(P2P, INFO, "p2p timeout, state==P2P_STATE_CHNL_ON_HAND, eListenExted: %d\n", -+ prP2pFsmInfo->eListenExted); -+ p2pFsmStateTransition(prAdapter, prP2pFsmInfo, P2P_STATE_IDLE); -+ prP2pFsmInfo->eListenExted = P2P_DEV_NOT_EXT_LISTEN; -+ break; -+ case P2P_DEV_EXT_LISTEN_ING: -+ DBGLOG(P2P, INFO, "p2p timeout, state==P2P_STATE_CHNL_ON_HAND, eListenExted: %d\n", -+ prP2pFsmInfo->eListenExted); -+ p2pFsmStateTransition(prAdapter, prP2pFsmInfo, P2P_STATE_CHNL_ON_HAND); -+ prP2pFsmInfo->eListenExted = P2P_DEV_EXT_LISTEN_WAITFOR_TIMEOUT; -+ break; -+ default: -+ ASSERT(FALSE); -+ DBGLOG(P2P, ERROR, -+ "Current P2P State %d is unexpected for FSM timeout event.\n", -+ prP2pFsmInfo->eCurrentState); -+ } -+ break; -+/* case P2P_STATE_GC_JOIN: */ -+/* break; */ -+ default: -+ break; -+ } -+ -+ } while (FALSE); -+ -+} /* p2pFsmRunEventFsmTimeout */ -+ -+VOID p2pFsmRunEventMgmtFrameTx(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) -+{ -+ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; -+ P_MSG_P2P_MGMT_TX_REQUEST_T prMgmtTxMsg = (P_MSG_P2P_MGMT_TX_REQUEST_T) NULL; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prMsgHdr != NULL)); -+ -+ DBGLOG(P2P, TRACE, "p2pFsmRunEventMgmtFrameTx\n"); -+ -+ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; -+ -+ if (prP2pFsmInfo == NULL) -+ break; -+ -+ prMgmtTxMsg = (P_MSG_P2P_MGMT_TX_REQUEST_T) prMsgHdr; -+ -+ p2pFuncTxMgmtFrame(prAdapter, -+ &prP2pFsmInfo->rMgmtTxInfo, prMgmtTxMsg->prMgmtMsduInfo, prMgmtTxMsg->u8Cookie); -+ -+ } while (FALSE); -+ -+ if (prMsgHdr) -+ cnmMemFree(prAdapter, prMsgHdr); -+ -+ return; -+ -+} /* p2pFsmRunEventMgmtTx */ -+ -+VOID p2pFsmRunEventStartAP(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) -+{ -+ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; -+ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; -+ P_MSG_P2P_START_AP_T prP2pStartAPMsg = (P_MSG_P2P_START_AP_T) NULL; -+ P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo = (P_P2P_SPECIFIC_BSS_INFO_T) NULL; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prMsgHdr != NULL)); -+ -+ DBGLOG(P2P, TRACE, "p2pFsmRunEventStartAP\n"); -+ -+ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; -+ -+ if (prP2pFsmInfo == NULL) -+ break; -+ -+ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); -+ prP2pStartAPMsg = (P_MSG_P2P_START_AP_T) prMsgHdr; -+ prP2pSpecificBssInfo = prAdapter->rWifiVar.prP2pSpecificBssInfo; -+ -+ if (prP2pStartAPMsg->u4BcnInterval) { -+ DBGLOG(P2P, TRACE, "Beacon interval updated to :%u\n", prP2pStartAPMsg->u4BcnInterval); -+ prP2pBssInfo->u2BeaconInterval = (UINT_16) prP2pStartAPMsg->u4BcnInterval; -+ } else if (prP2pBssInfo->u2BeaconInterval == 0) { -+ prP2pBssInfo->u2BeaconInterval = DOT11_BEACON_PERIOD_DEFAULT; -+ } -+ -+ if (prP2pStartAPMsg->u4DtimPeriod) { -+ DBGLOG(P2P, TRACE, "DTIM interval updated to :%u\n", prP2pStartAPMsg->u4DtimPeriod); -+ prP2pBssInfo->ucDTIMPeriod = (UINT_8) prP2pStartAPMsg->u4DtimPeriod; -+ } else if (prP2pBssInfo->ucDTIMPeriod == 0) { -+ prP2pBssInfo->ucDTIMPeriod = DOT11_DTIM_PERIOD_DEFAULT; -+ } -+ -+ if (prP2pStartAPMsg->u2SsidLen != 0) { -+ kalMemCopy(prP2pBssInfo->aucSSID, prP2pStartAPMsg->aucSsid, prP2pStartAPMsg->u2SsidLen); -+ kalMemCopy(prP2pSpecificBssInfo->aucGroupSsid, prP2pStartAPMsg->aucSsid, -+ prP2pStartAPMsg->u2SsidLen); -+ prP2pBssInfo->ucSSIDLen = prP2pSpecificBssInfo->u2GroupSsidLen = prP2pStartAPMsg->u2SsidLen; -+ } -+ -+ prP2pBssInfo->eHiddenSsidType = prP2pStartAPMsg->ucHiddenSsidType; -+ -+ /* TODO: JB */ -+ /* Privacy & inactive timeout. */ -+ -+ if ((prP2pBssInfo->eCurrentOPMode != OP_MODE_ACCESS_POINT) || -+ (prP2pBssInfo->eIntendOPMode != OP_MODE_NUM)) { -+ UINT_8 ucPreferedChnl = 0; -+ ENUM_BAND_T eBand = BAND_NULL; -+ ENUM_CHNL_EXT_T eSco = CHNL_EXT_SCN; -+ ENUM_P2P_STATE_T eNextState = P2P_STATE_SCAN; -+ P_P2P_CONNECTION_SETTINGS_T prP2pConnSettings = prAdapter->rWifiVar.prP2PConnSettings; -+ -+ if (prP2pFsmInfo->eCurrentState != P2P_STATE_SCAN && -+ prP2pFsmInfo->eCurrentState != P2P_STATE_IDLE) { -+ /* Make sure the state is in IDLE state. */ -+ p2pFsmRunEventAbort(prAdapter, prP2pFsmInfo); -+ } -+ prAdapter->rWifiVar.prP2pFsmInfo->rScanReqInfo.fgIsGOInitialDone = 0; -+ DBGLOG(P2P, INFO, -+ "NFC:p2pFsmRunEventStartAP,fgIsGOInitialDone[%d]\n", -+ prAdapter->rWifiVar.prP2pFsmInfo->rScanReqInfo.fgIsGOInitialDone); -+ -+ /* 20120118: Moved to p2pFuncSwitchOPMode(). */ -+ /* SET_NET_ACTIVE(prAdapter, NETWORK_TYPE_P2P_INDEX); */ -+ -+ /* Leave IDLE state. */ -+ SET_NET_PWR_STATE_ACTIVE(prAdapter, NETWORK_TYPE_P2P_INDEX); -+ -+ /* sync with firmware */ -+ /* DBGLOG(P2P, INFO, ("Activate P2P Network.\n")); */ -+ /* nicActivateNetwork(prAdapter, NETWORK_TYPE_P2P_INDEX); */ -+ -+ /* Key to trigger P2P FSM to allocate channel for AP mode. */ -+ prP2pBssInfo->eIntendOPMode = OP_MODE_ACCESS_POINT; -+ -+ /* Sparse Channel to decide which channel to use. */ -+ if ((cnmPreferredChannel(prAdapter, -+ &eBand, -+ &ucPreferedChnl, -+ &eSco) == FALSE) && (prP2pConnSettings->ucOperatingChnl == 0)) { -+ /* Sparse Channel Detection using passive mode. */ -+ eNextState = P2P_STATE_AP_CHANNEL_DETECT; -+ } else { -+ P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo = -+ prAdapter->rWifiVar.prP2pSpecificBssInfo; -+ P_P2P_CHNL_REQ_INFO_T prChnlReqInfo = &prP2pFsmInfo->rChnlReqInfo; -+ -+#if 1 -+ /* 2012-01-27: frog - Channel set from upper layer is the first priority. */ -+ /* Because the channel & beacon is decided by p2p_supplicant. */ -+ if (prP2pConnSettings->ucOperatingChnl != 0) { -+ prP2pSpecificBssInfo->ucPreferredChannel = prP2pConnSettings->ucOperatingChnl; -+ prP2pSpecificBssInfo->eRfBand = prP2pConnSettings->eBand; -+ } -+ -+ else { -+ ASSERT(ucPreferedChnl != 0); -+ prP2pSpecificBssInfo->ucPreferredChannel = ucPreferedChnl; -+ prP2pSpecificBssInfo->eRfBand = eBand; -+ } -+#else -+ if (ucPreferedChnl) { -+ prP2pSpecificBssInfo->ucPreferredChannel = ucPreferedChnl; -+ prP2pSpecificBssInfo->eRfBand = eBand; -+ } else { -+ ASSERT(prP2pConnSettings->ucOperatingChnl != 0); -+ prP2pSpecificBssInfo->ucPreferredChannel = prP2pConnSettings->ucOperatingChnl; -+ prP2pSpecificBssInfo->eRfBand = prP2pConnSettings->eBand; -+ } -+ -+#endif -+ prChnlReqInfo->ucReqChnlNum = prP2pSpecificBssInfo->ucPreferredChannel; -+ prChnlReqInfo->eBand = prP2pSpecificBssInfo->eRfBand; -+ prChnlReqInfo->eChannelReqType = CHANNEL_REQ_TYPE_GO_START_BSS; -+ -+ DBGLOG(P2P, INFO, "p2pFsmRunEventStartAP GO Scan\n"); -+ } -+ -+ /* If channel is specified, use active scan to shorten the scan time. */ -+ p2pFsmStateTransition(prAdapter, prAdapter->rWifiVar.prP2pFsmInfo, eNextState); -+ } -+ -+ } while (FALSE); -+ -+ if (prMsgHdr) -+ cnmMemFree(prAdapter, prMsgHdr); -+ -+} /* p2pFsmRunEventStartAP */ -+ -+VOID p2pFsmRunEventNetDeviceRegister(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) -+{ -+ P_MSG_P2P_NETDEV_REGISTER_T prNetDevRegisterMsg = (P_MSG_P2P_NETDEV_REGISTER_T) NULL; -+ -+ do { -+ -+ ASSERT_BREAK((prAdapter != NULL) && (prMsgHdr != NULL)); -+ -+ DBGLOG(P2P, TRACE, "p2pFsmRunEventNetDeviceRegister\n"); -+ -+ prNetDevRegisterMsg = (P_MSG_P2P_NETDEV_REGISTER_T) prMsgHdr; -+ -+ if (prNetDevRegisterMsg->fgIsEnable) { -+ p2pSetMode((prNetDevRegisterMsg->ucMode == 1) ? TRUE : FALSE); -+ -+ if (p2pLaunch(prAdapter->prGlueInfo)) -+ ASSERT(prAdapter->fgIsP2PRegistered); -+ -+ } else { -+ if (prAdapter->fgIsP2PRegistered) -+ p2pRemove(prAdapter->prGlueInfo); -+ -+ } -+ } while (FALSE); -+ -+ if (prMsgHdr) -+ cnmMemFree(prAdapter, prMsgHdr); -+ -+} /* p2pFsmRunEventNetDeviceRegister */ -+ -+VOID p2pFsmRunEventUpdateMgmtFrame(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) -+{ -+ P_MSG_P2P_MGMT_FRAME_UPDATE_T prP2pMgmtFrameUpdateMsg = (P_MSG_P2P_MGMT_FRAME_UPDATE_T) NULL; -+ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prMsgHdr != NULL)); -+ -+ DBGLOG(P2P, TRACE, "p2pFsmRunEventUpdateMgmtFrame\n"); -+ -+ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; -+ -+ if (prP2pFsmInfo == NULL) -+ break; -+ -+ prP2pMgmtFrameUpdateMsg = (P_MSG_P2P_MGMT_FRAME_UPDATE_T) prMsgHdr; -+ -+ switch (prP2pMgmtFrameUpdateMsg->eBufferType) { -+ case ENUM_FRAME_TYPE_EXTRA_IE_BEACON: -+ break; -+ case ENUM_FRAME_TYPE_EXTRA_IE_ASSOC_RSP: -+ break; -+ case ENUM_FRAME_TYPE_EXTRA_IE_PROBE_RSP: -+ break; -+ case ENUM_FRAME_TYPE_PROBE_RSP_TEMPLATE: -+ break; -+ case ENUM_FRAME_TYPE_BEACON_TEMPLATE: -+ break; -+ default: -+ break; -+ } -+ -+ } while (FALSE); -+ -+ if (prMsgHdr) -+ cnmMemFree(prAdapter, prMsgHdr); -+ -+} /* p2pFsmRunEventUpdateMgmtFrame */ -+ -+VOID p2pFsmRunEventBeaconUpdate(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) -+{ -+ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; -+ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; -+ P_MSG_P2P_BEACON_UPDATE_T prBcnUpdateMsg = (P_MSG_P2P_BEACON_UPDATE_T) NULL; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prMsgHdr != NULL)); -+ -+ DBGLOG(P2P, TRACE, "p2pFsmRunEventBeaconUpdate\n"); -+ -+ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; -+ -+ if (prP2pFsmInfo == NULL) -+ break; -+ -+ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); -+ prBcnUpdateMsg = (P_MSG_P2P_BEACON_UPDATE_T) prMsgHdr; -+ -+ p2pFuncBeaconUpdate(prAdapter, -+ prP2pBssInfo, -+ &prP2pFsmInfo->rBcnContentInfo, -+ prBcnUpdateMsg->pucBcnHdr, -+ prBcnUpdateMsg->u4BcnHdrLen, -+ prBcnUpdateMsg->pucBcnBody, prBcnUpdateMsg->u4BcnBodyLen); -+ -+ if ((prP2pBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT) && -+ (prP2pBssInfo->eIntendOPMode == OP_MODE_NUM)) { -+ /* AP is created, Beacon Update. */ -+ /* nicPmIndicateBssAbort(prAdapter, NETWORK_TYPE_P2P_INDEX); */ -+ -+ bssUpdateBeaconContent(prAdapter, NETWORK_TYPE_P2P_INDEX); -+ -+ /* nicPmIndicateBssCreated(prAdapter, NETWORK_TYPE_P2P_INDEX); */ -+ } -+ -+ } while (FALSE); -+ -+ if (prMsgHdr) -+ cnmMemFree(prAdapter, prMsgHdr); -+ -+} /* p2pFsmRunEventBeaconUpdate */ -+ -+VOID p2pFsmRunEventStopAP(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) -+{ -+ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL)); -+ -+ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); -+ -+ DBGLOG(P2P, TRACE, "p2pFsmRunEventStopAP\n"); -+ -+ if ((prP2pBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT) -+ && (prP2pBssInfo->eIntendOPMode == OP_MODE_NUM)) { -+ /* AP is created, Beacon Update. */ -+ -+ p2pFuncDissolve(prAdapter, prP2pBssInfo, TRUE, REASON_CODE_DEAUTH_LEAVING_BSS); -+ -+ DBGLOG(P2P, TRACE, "Stop Beaconing\n"); -+ nicPmIndicateBssAbort(prAdapter, NETWORK_TYPE_P2P_INDEX); -+ -+ /* Reset RLM related field of BSSINFO. */ -+ rlmBssAborted(prAdapter, prP2pBssInfo); -+ } -+ /* 20120118: Moved to p2pFuncSwitchOPMode(). */ -+ /* UNSET_NET_ACTIVE(prAdapter, NETWORK_TYPE_P2P_INDEX); */ -+ -+ /* Enter IDLE state. */ -+ SET_NET_PWR_STATE_IDLE(prAdapter, NETWORK_TYPE_P2P_INDEX); -+ -+ DBGLOG(P2P, INFO, "Re activate P2P Network.\n"); -+ nicDeactivateNetwork(prAdapter, NETWORK_TYPE_P2P_INDEX); -+ -+ nicActivateNetwork(prAdapter, NETWORK_TYPE_P2P_INDEX); -+ -+#if CFG_SUPPORT_WFD -+ p2pFsmRunEventWfdSettingUpdate(prAdapter, NULL); -+#endif -+ -+ /* p2pFsmRunEventAbort(prAdapter, prAdapter->rWifiVar.prP2pFsmInfo); */ -+ p2pFsmStateTransition(prAdapter, prAdapter->rWifiVar.prP2pFsmInfo, P2P_STATE_IDLE); -+ -+ } while (FALSE); -+ -+ if (prMsgHdr) -+ cnmMemFree(prAdapter, prMsgHdr); -+ -+} /* p2pFsmRunEventStopAP */ -+ -+VOID p2pFsmRunEventConnectionRequest(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) -+{ -+ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; -+ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; -+ P_P2P_CHNL_REQ_INFO_T prChnlReqInfo = (P_P2P_CHNL_REQ_INFO_T) NULL; -+ P_MSG_P2P_CONNECTION_REQUEST_T prConnReqMsg = (P_MSG_P2P_CONNECTION_REQUEST_T) NULL; -+ P_P2P_CONNECTION_REQ_INFO_T prConnReqInfo = (P_P2P_CONNECTION_REQ_INFO_T) NULL; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prMsgHdr != NULL)); -+ -+ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); -+ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; -+ -+ if (prP2pFsmInfo == NULL) -+ break; -+ -+ prConnReqMsg = (P_MSG_P2P_CONNECTION_REQUEST_T) prMsgHdr; -+ -+ prConnReqInfo = &(prP2pFsmInfo->rConnReqInfo); -+ prChnlReqInfo = &(prP2pFsmInfo->rChnlReqInfo); -+ -+ DBGLOG(P2P, TRACE, "p2pFsmRunEventConnectionRequest\n"); -+ -+ if (prP2pBssInfo->eCurrentOPMode != OP_MODE_INFRASTRUCTURE) -+ break; -+ -+ SET_NET_PWR_STATE_ACTIVE(prAdapter, NETWORK_TYPE_P2P_INDEX); -+ -+ /* Make sure the state is in IDLE state. */ -+ p2pFsmRunEventAbort(prAdapter, prP2pFsmInfo); -+ -+ /* Update connection request information. */ -+ prConnReqInfo->fgIsConnRequest = TRUE; -+ COPY_MAC_ADDR(prConnReqInfo->aucBssid, prConnReqMsg->aucBssid); -+ kalMemCopy(&(prConnReqInfo->rSsidStruct), &(prConnReqMsg->rSsid), sizeof(P2P_SSID_STRUCT_T)); -+ kalMemCopy(prConnReqInfo->aucIEBuf, prConnReqMsg->aucIEBuf, prConnReqMsg->u4IELen); -+ prConnReqInfo->u4BufLength = prConnReqMsg->u4IELen; -+ -+ /* Find BSS Descriptor first. */ -+ prP2pFsmInfo->prTargetBss = scanP2pSearchDesc(prAdapter, prP2pBssInfo, prConnReqInfo); -+ -+ if (prP2pFsmInfo->prTargetBss == NULL) { -+ /* Update scan parameter... to scan target device. */ -+ P_P2P_SCAN_REQ_INFO_T prScanReqInfo = &(prP2pFsmInfo->rScanReqInfo); -+ -+ DBGLOG(P2P, INFO, "p2pFsmRunEventConnectionRequest,Trigger New Scan\n"); -+ -+ prScanReqInfo->ucNumChannelList = 1; -+ prScanReqInfo->eScanType = SCAN_TYPE_ACTIVE_SCAN; -+ prScanReqInfo->eChannelSet = SCAN_CHANNEL_SPECIFIED; -+ prScanReqInfo->arScanChannelList[0].ucChannelNum = prConnReqMsg->rChannelInfo.ucChannelNum; -+ kalMemCopy(&(prScanReqInfo->rSsidStruct), &(prConnReqMsg->rSsid), sizeof(P2P_SSID_STRUCT_T)); -+ prScanReqInfo->u4BufLength = 0; /* Prevent other P2P ID in IE. */ -+ prScanReqInfo->fgIsAbort = TRUE; -+ -+ p2pFsmStateTransition(prAdapter, prP2pFsmInfo, P2P_STATE_SCAN); -+ } else { -+ prChnlReqInfo->u8Cookie = 0; -+ prChnlReqInfo->ucReqChnlNum = prConnReqMsg->rChannelInfo.ucChannelNum; -+ prChnlReqInfo->eBand = prConnReqMsg->rChannelInfo.eBand; -+ prChnlReqInfo->eChnlSco = prConnReqMsg->eChnlSco; -+ prChnlReqInfo->u4MaxInterval = AIS_JOIN_CH_REQUEST_INTERVAL; -+ prChnlReqInfo->eChannelReqType = CHANNEL_REQ_TYPE_GC_JOIN_REQ; -+ DBGLOG(P2P, INFO, "p2pFsmRunEventConnectionRequest, Report the Connecting BSS Again.\n"); -+ p2pFsmStateTransition(prAdapter, prP2pFsmInfo, P2P_STATE_REQING_CHANNEL); -+ } -+ -+ } while (FALSE); -+ -+ if (prMsgHdr) -+ cnmMemFree(prAdapter, prMsgHdr); -+ -+ return; -+ -+} /* p2pFsmRunEventConnectionRequest */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is used to handle Connection Request from Supplicant. -+* -+* \param[in] prAdapter Pointer of ADAPTER_T -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID p2pFsmRunEventConnectionAbort(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) -+{ -+ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; -+ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; -+ P_MSG_P2P_CONNECTION_ABORT_T prDisconnMsg = (P_MSG_P2P_CONNECTION_ABORT_T) NULL; -+ /* P_STA_RECORD_T prTargetStaRec = (P_STA_RECORD_T)NULL; */ -+ -+ do { -+ -+ ASSERT_BREAK((prAdapter != NULL) && (prMsgHdr != NULL)); -+ -+ DBGLOG(P2P, TRACE, "p2pFsmRunEventConnectionAbort: Connection Abort.\n"); -+ -+ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; -+ -+ if (prP2pFsmInfo == NULL) -+ break; -+ -+ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); -+ -+ prDisconnMsg = (P_MSG_P2P_CONNECTION_ABORT_T) prMsgHdr; -+ -+ switch (prP2pBssInfo->eCurrentOPMode) { -+ case OP_MODE_INFRASTRUCTURE: -+ { -+ UINT_8 aucBCBSSID[] = BC_BSSID; -+ -+ if (!prP2pBssInfo->prStaRecOfAP) { -+ DBGLOG(P2P, TRACE, "GO's StaRec is NULL\n"); -+ break; -+ } -+ if (UNEQUAL_MAC_ADDR(prP2pBssInfo->prStaRecOfAP->aucMacAddr, prDisconnMsg->aucTargetID) -+ && UNEQUAL_MAC_ADDR(prDisconnMsg->aucTargetID, aucBCBSSID)) { -+ DBGLOG(P2P, TRACE, -+ "Unequal MAC ADDR [ %pM : %pM ]\n", -+ prP2pBssInfo->prStaRecOfAP->aucMacAddr, -+ prDisconnMsg->aucTargetID); -+ break; -+ } -+ -+ kalP2PGCIndicateConnectionStatus(prAdapter->prGlueInfo, -+ NULL, NULL, 0, 0, -+ WLAN_STATUS_MEDIA_DISCONNECT_LOCALLY); -+ -+ /* Stop rejoin timer if it is started. */ -+ /* TODO: If it has. */ -+ -+ p2pFuncDisconnect(prAdapter, prP2pBssInfo->prStaRecOfAP, prDisconnMsg->fgSendDeauth, -+ prDisconnMsg->u2ReasonCode); -+ -+ /* prTargetStaRec = prP2pBssInfo->prStaRecOfAP; */ -+ -+ /* Fix possible KE when RX Beacon & call nicPmIndicateBssConnected(). */ -+ /* hit prStaRecOfAP == NULL. */ -+ p2pChangeMediaState(prAdapter, PARAM_MEDIA_STATE_DISCONNECTED); -+ -+ prP2pBssInfo->prStaRecOfAP = NULL; -+ -+ SET_NET_PWR_STATE_IDLE(prAdapter, NETWORK_TYPE_P2P_INDEX); -+ -+ p2pFsmStateTransition(prAdapter, prP2pFsmInfo, P2P_STATE_IDLE); -+ -+ } -+ break; -+ case OP_MODE_ACCESS_POINT: -+ { -+ P_LINK_T prStaRecOfClientList = &prP2pBssInfo->rStaRecOfClientList; -+ /* Search specific client device, and disconnect. */ -+ /* 1. Send deauthentication frame. */ -+ /* 2. Indication: Device disconnect. */ -+ P_LINK_ENTRY_T prLinkEntry = (P_LINK_ENTRY_T) NULL; -+ P_STA_RECORD_T prCurrStaRec = (P_STA_RECORD_T) NULL; -+ -+ DBGLOG(P2P, TRACE, -+ "Disconnecting with Target ID: %pM\n", -+ prDisconnMsg->aucTargetID); -+ -+ LINK_FOR_EACH(prLinkEntry, prStaRecOfClientList) { -+ prCurrStaRec = LINK_ENTRY(prLinkEntry, STA_RECORD_T, rLinkEntry); -+ -+ ASSERT(prCurrStaRec); -+ -+ if (EQUAL_MAC_ADDR(prCurrStaRec->aucMacAddr, prDisconnMsg->aucTargetID)) { -+ -+ DBGLOG(P2P, TRACE, -+ "Disconnecting: %pM\n", -+ prCurrStaRec->aucMacAddr); -+ -+ /* Remove STA from client list. */ -+ LINK_REMOVE_KNOWN_ENTRY(prStaRecOfClientList, -+ &prCurrStaRec->rLinkEntry); -+ -+ /* Glue layer indication. */ -+ /* kalP2PGOStationUpdate(prAdapter->prGlueInfo, prCurrStaRec, FALSE); */ -+ -+ /* Send deauth & do indication. */ -+ p2pFuncDisconnect(prAdapter, prCurrStaRec, prDisconnMsg->fgSendDeauth, -+ prDisconnMsg->u2ReasonCode); -+ -+ /* prTargetStaRec = prCurrStaRec; */ -+ -+ break; -+ } -+ } -+ -+ } -+ break; -+ case OP_MODE_P2P_DEVICE: -+ default: -+ ASSERT(FALSE); -+ break; -+ } -+ -+ } while (FALSE); -+ -+ /* 20120830 moved into p2pFuncDisconnect() */ -+ /* if ((!prDisconnMsg->fgSendDeauth) && (prTargetStaRec)) { */ -+ /* cnmStaRecFree(prAdapter, prTargetStaRec, TRUE); */ -+ /* } */ -+ -+ if (prMsgHdr) -+ cnmMemFree(prAdapter, prMsgHdr); -+ -+} /* p2pFsmRunEventConnectionAbort */ -+ -+VOID p2pFsmRunEventDissolve(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) -+{ -+ -+ /* TODO: */ -+ -+ DBGLOG(P2P, TRACE, "p2pFsmRunEventDissolve\n"); -+ -+ if (prMsgHdr) -+ cnmMemFree(prAdapter, prMsgHdr); -+ -+} -+ -+WLAN_STATUS -+p2pFsmRunEventDeauthTxDone(IN P_ADAPTER_T prAdapter, -+ IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus) -+{ -+ -+ P_STA_RECORD_T prStaRec = (P_STA_RECORD_T) NULL; -+ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; -+ ENUM_PARAM_MEDIA_STATE_T eOriMediaStatus; -+ -+ do { -+ -+ ASSERT_BREAK((prAdapter != NULL) && (prMsduInfo != NULL)); -+ -+ DBGLOG(P2P, INFO, "Deauth TX Done Status: %d, seqNo %d\n", -+ rTxDoneStatus, prMsduInfo->ucTxSeqNum); -+ -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); -+ -+ if (prStaRec == NULL) { -+ DBGLOG(P2P, TRACE, "Station Record NULL, Index:%d\n", prMsduInfo->ucStaRecIndex); -+ break; -+ } -+ -+ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); -+ eOriMediaStatus = prP2pBssInfo->eConnectionState; -+ /* Change station state. */ -+ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); -+ -+ /* Reset Station Record Status. */ -+ p2pFuncResetStaRecStatus(prAdapter, prStaRec); -+ -+ bssRemoveStaRecFromClientList(prAdapter, prP2pBssInfo, prStaRec); -+ -+ /**/ cnmStaRecFree(prAdapter, prStaRec, TRUE); -+ -+ if ((prP2pBssInfo->eCurrentOPMode != OP_MODE_ACCESS_POINT) || -+ (prP2pBssInfo->rStaRecOfClientList.u4NumElem == 0)) { -+ DBGLOG(P2P, TRACE, "No More Client, Media Status DISCONNECTED\n"); -+ p2pChangeMediaState(prAdapter, PARAM_MEDIA_STATE_DISCONNECTED); -+ } -+ -+ /* Because the eConnectionState is changed before Deauth TxDone. Dont Check eConnectionState */ -+ /* if (eOriMediaStatus != prP2pBssInfo->eConnectionState) { */ -+ /* Update Disconnected state to FW. */ -+ nicUpdateBss(prAdapter, NETWORK_TYPE_P2P_INDEX); -+ /* } */ -+ -+ } while (FALSE); -+ -+ return WLAN_STATUS_SUCCESS; -+} /* p2pFsmRunEventDeauthTxDone */ -+ -+WLAN_STATUS -+p2pFsmRunEventMgmtFrameTxDone(IN P_ADAPTER_T prAdapter, -+ IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus) -+{ -+ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; -+ P_P2P_MGMT_TX_REQ_INFO_T prMgmtTxReqInfo = (P_P2P_MGMT_TX_REQ_INFO_T) NULL; -+ BOOLEAN fgIsSuccess = FALSE; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prMsduInfo != NULL)); -+ -+ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; -+ prMgmtTxReqInfo = &(prP2pFsmInfo->rMgmtTxInfo); -+ -+ if (rTxDoneStatus != TX_RESULT_SUCCESS) { -+ DBGLOG(P2P, INFO, "Mgmt Frame TX Fail, Status: %d, seq NO. %d, Cookie: 0x%llx\n", -+ rTxDoneStatus, prMsduInfo->ucTxSeqNum, prMgmtTxReqInfo->u8Cookie); -+ } else { -+ fgIsSuccess = TRUE; -+ DBGLOG(P2P, TRACE, "Mgmt Frame TX Done.\n"); -+ } -+ -+ if (prMgmtTxReqInfo->prMgmtTxMsdu == prMsduInfo) { -+ kalP2PIndicateMgmtTxStatus(prAdapter->prGlueInfo, -+ prMgmtTxReqInfo->u8Cookie, -+ fgIsSuccess, -+ prMsduInfo->prPacket, (UINT_32) prMsduInfo->u2FrameLength); -+ -+ prMgmtTxReqInfo->prMgmtTxMsdu = NULL; -+ } -+ -+ } while (FALSE); -+ -+ return WLAN_STATUS_SUCCESS; -+ -+} /* p2pFsmRunEventMgmtFrameTxDone */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is called when JOIN complete message event is received from SAA. -+* -+* \param[in] prAdapter Pointer of ADAPTER_T -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID p2pFsmRunEventJoinComplete(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) -+{ -+ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; -+ P_P2P_JOIN_INFO_T prJoinInfo = (P_P2P_JOIN_INFO_T) NULL; -+ P_MSG_JOIN_COMP_T prJoinCompMsg = (P_MSG_JOIN_COMP_T) NULL; -+ P_SW_RFB_T prAssocRspSwRfb = (P_SW_RFB_T) NULL; -+ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; -+ -+ ASSERT_BREAK((prAdapter != NULL) && (prMsgHdr != NULL)); -+ DBGLOG(P2P, TRACE, "P2P Join Complete\n"); -+ -+ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; -+ if (prP2pFsmInfo == NULL) { -+ if (prMsgHdr) -+ cnmMemFree(prAdapter, prMsgHdr); -+ return; -+ } -+ -+ prJoinInfo = &(prP2pFsmInfo->rJoinInfo); -+ if (prMsgHdr == NULL) -+ return; -+ prJoinCompMsg = (P_MSG_JOIN_COMP_T) prMsgHdr; -+ prAssocRspSwRfb = prJoinCompMsg->prSwRfb; -+ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); -+ -+ if (prP2pBssInfo->eCurrentOPMode == OP_MODE_INFRASTRUCTURE) { -+ P_STA_RECORD_T prStaRec = (P_STA_RECORD_T) NULL; -+ -+ prStaRec = prJoinCompMsg->prStaRec; -+ -+ /* Check SEQ NUM */ -+ if (prJoinCompMsg->ucSeqNum == prJoinInfo->ucSeqNumOfReqMsg) { -+ ASSERT(prStaRec == prJoinInfo->prTargetStaRec); -+ prJoinInfo->fgIsJoinComplete = TRUE; -+ -+ if (prJoinCompMsg->rJoinStatus == WLAN_STATUS_SUCCESS) { -+ -+ /* 4 <1.1> Change FW's Media State immediately. */ -+ p2pChangeMediaState(prAdapter, PARAM_MEDIA_STATE_CONNECTED); -+ -+ /* 4 <1.2> Deactivate previous AP's STA_RECORD_T in Driver if have. */ -+ if ((prP2pBssInfo->prStaRecOfAP) && (prP2pBssInfo->prStaRecOfAP != prStaRec)) { -+ cnmStaRecChangeState(prAdapter, prP2pBssInfo->prStaRecOfAP, -+ STA_STATE_1); -+ -+ cnmStaRecFree(prAdapter, prP2pBssInfo->prStaRecOfAP, TRUE); -+ -+ prP2pBssInfo->prStaRecOfAP = NULL; -+ } -+ /* 4 <1.3> Update BSS_INFO_T */ -+ p2pFuncUpdateBssInfoForJOIN(prAdapter, prP2pFsmInfo->prTargetBss, prStaRec, -+ prAssocRspSwRfb); -+ -+ /* 4 <1.4> Activate current AP's STA_RECORD_T in Driver. */ -+ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_3); -+ DBGLOG(P2P, INFO, "P2P GC Join Success\n"); -+ -+#if CFG_SUPPORT_P2P_RSSI_QUERY -+ /* <1.5> Update RSSI if necessary */ -+ nicUpdateRSSI(prAdapter, NETWORK_TYPE_P2P_INDEX, -+ (INT_8) (RCPI_TO_dBm(prStaRec->ucRCPI)), 0); -+#endif -+ -+ /* 4 <1.6> Indicate Connected Event to Host immediately. */ -+ /* Require BSSID, Association ID, Beacon Interval.. from AIS_BSS_INFO_T */ -+ /* p2pIndicationOfMediaStateToHost(prAdapter, PARAM_MEDIA_STATE_CONNECTED, */ -+ /* prStaRec->aucMacAddr); */ -+ if (prP2pFsmInfo->prTargetBss) -+ scanReportBss2Cfg80211(prAdapter, OP_MODE_P2P_DEVICE, -+ prP2pFsmInfo->prTargetBss); -+ kalP2PGCIndicateConnectionStatus(prAdapter->prGlueInfo, -+ &prP2pFsmInfo->rConnReqInfo, -+ prJoinInfo->aucIEBuf, prJoinInfo->u4BufLength, -+ prStaRec->u2StatusCode, -+ WLAN_STATUS_MEDIA_CONNECT); -+ -+ } else { -+ /* Join Fail */ -+ /* 4 <2.1> Redo JOIN process with other Auth Type if possible */ -+ if (p2pFuncRetryJOIN(prAdapter, prStaRec, prJoinInfo) == FALSE) { -+ P_BSS_DESC_T prBssDesc; -+ -+ /* Increase Failure Count */ -+ prStaRec->ucJoinFailureCount++; -+ -+ prBssDesc = prP2pFsmInfo->prTargetBss; -+ -+ ASSERT(prBssDesc); -+ ASSERT(prBssDesc->fgIsConnecting); -+ -+ prBssDesc->fgIsConnecting = FALSE; -+ -+ if (prStaRec->ucJoinFailureCount >= 3) { -+ -+ kalP2PGCIndicateConnectionStatus(prAdapter->prGlueInfo, -+ &prP2pFsmInfo->rConnReqInfo, -+ prJoinInfo->aucIEBuf, -+ prJoinInfo->u4BufLength, -+ prStaRec->u2StatusCode, -+ WLAN_STATUS_MEDIA_CONNECT); -+ } else { -+ /* Sometime the GO is not ready to response auth. */ -+ /* Connect it again */ -+ prP2pFsmInfo->prTargetBss = NULL; -+ } -+ DBGLOG(P2P, INFO, "P2P GC Join Failed\n"); -+ -+ } -+ -+ } -+ } -+ } -+ -+ if (prAssocRspSwRfb) -+ nicRxReturnRFB(prAdapter, prAssocRspSwRfb); -+ -+ if (prP2pFsmInfo->eCurrentState == P2P_STATE_GC_JOIN) { -+ -+ if (prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX].eConnectionState == -+ PARAM_MEDIA_STATE_CONNECTED) { -+ /* Return to IDLE state. */ -+ p2pFsmStateTransition(prAdapter, prP2pFsmInfo, P2P_STATE_IDLE); -+ } else { -+ /* p2pFsmStateTransition(prAdapter, prP2pFsmInfo, P2P_STATE_IDLE); */ -+ /* one more scan */ -+ p2pFsmStateTransition(prAdapter, prP2pFsmInfo, P2P_STATE_SCAN); -+ } -+ } -+ -+ if (prMsgHdr) -+ cnmMemFree(prAdapter, prMsgHdr); -+ -+} /* p2pFsmRunEventJoinComplete */ -+ -+VOID p2pFsmRunEventMgmtFrameRegister(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) -+{ -+ P_MSG_P2P_MGMT_FRAME_REGISTER_T prMgmtFrameRegister = (P_MSG_P2P_MGMT_FRAME_REGISTER_T) NULL; -+ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prMsgHdr != NULL)); -+ -+ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; -+ -+ if (prP2pFsmInfo == NULL) -+ break; -+ -+ prMgmtFrameRegister = (P_MSG_P2P_MGMT_FRAME_REGISTER_T) prMsgHdr; -+ -+ p2pFuncMgmtFrameRegister(prAdapter, -+ prMgmtFrameRegister->u2FrameType, -+ prMgmtFrameRegister->fgIsRegister, &prP2pFsmInfo->u4P2pPacketFilter); -+ -+ } while (FALSE); -+ -+ if (prMsgHdr) -+ cnmMemFree(prAdapter, prMsgHdr); -+ -+ return; -+ -+} /* p2pFsmRunEventMgmtFrameRegister */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is call when RX deauthentication frame from the AIR. -+* If we are under STA mode, we would go back to P2P Device. -+* If we are under AP mode, we would stay in AP mode until disconnect event from HOST. -+* -+* \param[in] prAdapter Pointer of ADAPTER_T -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID p2pFsmRunEventRxDeauthentication(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN P_SW_RFB_T prSwRfb) -+{ -+ -+ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; -+ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; -+ UINT_16 u2ReasonCode = 0; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prSwRfb != NULL)); -+ -+ if (prStaRec == NULL) -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); -+ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; -+ -+ if (prP2pFsmInfo == NULL) -+ break; -+ -+ if (!prStaRec) -+ break; -+ -+ prP2pBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]; -+ -+ if (prStaRec->ucStaState == STA_STATE_1) -+ break; -+ -+ DBGLOG(P2P, TRACE, "RX Deauth\n"); -+ -+ switch (prP2pBssInfo->eCurrentOPMode) { -+ case OP_MODE_INFRASTRUCTURE: -+ if (authProcessRxDeauthFrame(prSwRfb, -+ prStaRec->aucMacAddr, &u2ReasonCode) == WLAN_STATUS_SUCCESS) { -+ P_WLAN_DEAUTH_FRAME_T prDeauthFrame = (P_WLAN_DEAUTH_FRAME_T) prSwRfb->pvHeader; -+ UINT_16 u2IELength = 0; -+ -+ if (prP2pBssInfo->prStaRecOfAP != prStaRec) -+ break; -+ -+ prStaRec->u2ReasonCode = u2ReasonCode; -+ u2IELength = prSwRfb->u2PacketLen - (WLAN_MAC_HEADER_LEN + REASON_CODE_FIELD_LEN); -+ -+ ASSERT(prP2pBssInfo->prStaRecOfAP == prStaRec); -+ -+ /* Indicate disconnect to Host. */ -+ kalP2PGCIndicateConnectionStatus(prAdapter->prGlueInfo, -+ NULL, -+ prDeauthFrame->aucInfoElem, u2IELength, u2ReasonCode, -+ WLAN_STATUS_MEDIA_DISCONNECT); -+ -+ prP2pBssInfo->prStaRecOfAP = NULL; -+ DBGLOG(P2P, INFO, "GC RX Deauth Reason: %d\n", u2ReasonCode); -+ -+ p2pFuncDisconnect(prAdapter, prStaRec, FALSE, u2ReasonCode); -+ p2pChangeMediaState(prAdapter, PARAM_MEDIA_STATE_DISCONNECTED); -+ -+ SET_NET_PWR_STATE_IDLE(prAdapter, NETWORK_TYPE_P2P_INDEX); -+ -+ p2pFsmStateTransition(prAdapter, prP2pFsmInfo, P2P_STATE_IDLE); -+ } -+ break; -+ case OP_MODE_ACCESS_POINT: -+ /* Delete client from client list. */ -+ if (authProcessRxDeauthFrame(prSwRfb, -+ prP2pBssInfo->aucBSSID, &u2ReasonCode) == WLAN_STATUS_SUCCESS) { -+ P_LINK_T prStaRecOfClientList = (P_LINK_T) NULL; -+ P_LINK_ENTRY_T prLinkEntry = (P_LINK_ENTRY_T) NULL; -+ P_STA_RECORD_T prCurrStaRec = (P_STA_RECORD_T) NULL; -+ -+ prStaRecOfClientList = &prP2pBssInfo->rStaRecOfClientList; -+ -+ LINK_FOR_EACH(prLinkEntry, prStaRecOfClientList) { -+ prCurrStaRec = LINK_ENTRY(prLinkEntry, STA_RECORD_T, rLinkEntry); -+ -+ ASSERT(prCurrStaRec); -+ -+ if (EQUAL_MAC_ADDR(prCurrStaRec->aucMacAddr, prStaRec->aucMacAddr)) { -+ -+ /* Remove STA from client list. */ -+ LINK_REMOVE_KNOWN_ENTRY(prStaRecOfClientList, -+ &prCurrStaRec->rLinkEntry); -+ -+ /* Indicate to Host. */ -+ /* kalP2PGOStationUpdate(prAdapter->prGlueInfo, prStaRec, FALSE); */ -+ -+ /* Indicate disconnect to Host. */ -+ DBGLOG(P2P, INFO, "GO RX Deauth Reason: %d\n", u2ReasonCode); -+ p2pFuncDisconnect(prAdapter, prStaRec, FALSE, u2ReasonCode); -+ -+ break; -+ } -+ } -+ } -+ break; -+ case OP_MODE_P2P_DEVICE: -+ default: -+ /* Findout why someone sent deauthentication frame to us. */ -+ ASSERT(FALSE); -+ break; -+ } -+ -+ DBGLOG(P2P, TRACE, "Deauth Reason:%d\n", u2ReasonCode); -+ -+ } while (FALSE); -+} /* p2pFsmRunEventRxDeauthentication */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is call when RX deauthentication frame from the AIR. -+* If we are under STA mode, we would go back to P2P Device. -+* If we are under AP mode, we would stay in AP mode until disconnect event from HOST. -+* -+* \param[in] prAdapter Pointer of ADAPTER_T -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID p2pFsmRunEventRxDisassociation(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN P_SW_RFB_T prSwRfb) -+{ -+ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; -+ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; -+ UINT_16 u2ReasonCode = 0; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prSwRfb != NULL)); -+ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; -+ -+ if (prP2pFsmInfo == NULL) -+ break; -+ -+ if (prStaRec == NULL) { -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); -+ if (prStaRec == NULL) -+ break; -+ } -+ -+ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); -+ -+ if (prStaRec->ucStaState == STA_STATE_1) -+ break; -+ -+ DBGLOG(P2P, TRACE, "RX Disassoc\n"); -+ -+ switch (prP2pBssInfo->eCurrentOPMode) { -+ case OP_MODE_INFRASTRUCTURE: -+ if (assocProcessRxDisassocFrame(prAdapter, -+ prSwRfb, -+ prStaRec->aucMacAddr, -+ &prStaRec->u2ReasonCode) == WLAN_STATUS_SUCCESS) { -+ P_WLAN_DISASSOC_FRAME_T prDisassocFrame = (P_WLAN_DISASSOC_FRAME_T) prSwRfb->pvHeader; -+ UINT_16 u2IELength = 0; -+ -+ ASSERT(prP2pBssInfo->prStaRecOfAP == prStaRec); -+ -+ if (prP2pBssInfo->prStaRecOfAP != prStaRec) -+ break; -+ -+ u2IELength = prSwRfb->u2PacketLen - (WLAN_MAC_HEADER_LEN + REASON_CODE_FIELD_LEN); -+ -+ /* Indicate disconnect to Host. */ -+ kalP2PGCIndicateConnectionStatus(prAdapter->prGlueInfo, -+ NULL, -+ prDisassocFrame->aucInfoElem, -+ u2IELength, prStaRec->u2ReasonCode, -+ WLAN_STATUS_MEDIA_DISCONNECT); -+ -+ prP2pBssInfo->prStaRecOfAP = NULL; -+ -+ DBGLOG(P2P, INFO, "GC RX Disassoc Reason %d\n", prStaRec->u2ReasonCode); -+ p2pFuncDisconnect(prAdapter, prStaRec, FALSE, prStaRec->u2ReasonCode); -+ p2pChangeMediaState(prAdapter, PARAM_MEDIA_STATE_DISCONNECTED); -+ SET_NET_PWR_STATE_IDLE(prAdapter, NETWORK_TYPE_P2P_INDEX); -+ p2pFsmStateTransition(prAdapter, prP2pFsmInfo, P2P_STATE_IDLE); -+ -+ } -+ break; -+ case OP_MODE_ACCESS_POINT: -+ /* Delete client from client list. */ -+ if (assocProcessRxDisassocFrame(prAdapter, -+ prSwRfb, -+ prP2pBssInfo->aucBSSID, &u2ReasonCode) == WLAN_STATUS_SUCCESS) { -+ P_LINK_T prStaRecOfClientList = (P_LINK_T) NULL; -+ P_LINK_ENTRY_T prLinkEntry = (P_LINK_ENTRY_T) NULL; -+ P_STA_RECORD_T prCurrStaRec = (P_STA_RECORD_T) NULL; -+ -+ prStaRecOfClientList = &prP2pBssInfo->rStaRecOfClientList; -+ -+ LINK_FOR_EACH(prLinkEntry, prStaRecOfClientList) { -+ prCurrStaRec = LINK_ENTRY(prLinkEntry, STA_RECORD_T, rLinkEntry); -+ -+ ASSERT(prCurrStaRec); -+ -+ if (EQUAL_MAC_ADDR(prCurrStaRec->aucMacAddr, prStaRec->aucMacAddr)) { -+ -+ /* Remove STA from client list. */ -+ LINK_REMOVE_KNOWN_ENTRY(prStaRecOfClientList, -+ &prCurrStaRec->rLinkEntry); -+ -+ /* Indicate to Host. */ -+ /* kalP2PGOStationUpdate(prAdapter->prGlueInfo, prStaRec, FALSE); */ -+ -+ /* Indicate disconnect to Host. */ -+ DBGLOG(P2P, INFO, "GO RX Disassoc Reason %d\n", u2ReasonCode); -+ p2pFuncDisconnect(prAdapter, prStaRec, FALSE, u2ReasonCode); -+ -+ break; -+ } -+ } -+ } -+ break; -+ case OP_MODE_P2P_DEVICE: -+ default: -+ ASSERT(FALSE); -+ break; -+ } -+ -+ } while (FALSE); -+} /* p2pFsmRunEventRxDisassociation */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is called when a probe request frame is received. -+* -+* \param[in] prAdapter Pointer of ADAPTER_T -+* -+* \return boolean value if probe response frame is accepted & need cancel scan request. -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID p2pFsmRunEventRxProbeResponseFrame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, IN P_BSS_DESC_T prBssDesc) -+{ -+ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; -+ P_P2P_CONNECTION_SETTINGS_T prP2pConnSettings = (P_P2P_CONNECTION_SETTINGS_T) NULL; -+ P_WLAN_MAC_MGMT_HEADER_T prMgtHdr = (P_WLAN_MAC_MGMT_HEADER_T) NULL; -+ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prSwRfb != NULL) && (prBssDesc != NULL)); -+ -+ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; -+ prP2pConnSettings = prAdapter->rWifiVar.prP2PConnSettings; -+ prP2pBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]; -+ -+ /* There is a connection request. */ -+ prMgtHdr = (P_WLAN_MAC_MGMT_HEADER_T) prSwRfb->pvHeader; -+ -+ } while (FALSE); -+ -+} /* p2pFsmRunEventRxProbeResponseFrame */ -+ -+VOID p2pFsmRunEventBeaconTimeout(IN P_ADAPTER_T prAdapter) -+{ -+ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; -+ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; -+ -+ do { -+ ASSERT_BREAK(prAdapter != NULL); -+ -+ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; -+ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); -+ -+ DBGLOG(P2P, TRACE, "p2pFsmRunEventBeaconTimeout: Beacon Timeout\n"); -+ -+ /* Only client mode would have beacon lost event. */ -+ ASSERT(prP2pBssInfo->eCurrentOPMode == OP_MODE_INFRASTRUCTURE); -+ -+ if (prP2pBssInfo->eConnectionState == PARAM_MEDIA_STATE_CONNECTED) { -+ /* Indicate disconnect to Host. */ -+ kalP2PGCIndicateConnectionStatus(prAdapter->prGlueInfo, -+ NULL, NULL, 0, REASON_CODE_DISASSOC_INACTIVITY, -+ WLAN_STATUS_MEDIA_DISCONNECT); -+ -+ if (prP2pBssInfo->prStaRecOfAP != NULL) { -+ P_STA_RECORD_T prStaRec = prP2pBssInfo->prStaRecOfAP; -+ -+ prP2pBssInfo->prStaRecOfAP = NULL; -+ -+ p2pFuncDisconnect(prAdapter, prStaRec, FALSE, REASON_CODE_DISASSOC_LEAVING_BSS); -+ -+ /* 20120830 moved into p2pFuncDisconnect() */ -+ /* cnmStaRecFree(prAdapter, prP2pBssInfo->prStaRecOfAP, TRUE); */ -+ p2pChangeMediaState(prAdapter, PARAM_MEDIA_STATE_DISCONNECTED); -+ SET_NET_PWR_STATE_IDLE(prAdapter, NETWORK_TYPE_P2P_INDEX); -+ p2pFsmStateTransition(prAdapter, prP2pFsmInfo, P2P_STATE_IDLE); -+ -+ } -+ } -+ } while (FALSE); -+ -+} /* p2pFsmRunEventBeaconTimeout */ -+ -+VOID p2pFsmRunEventExtendListen(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) -+{ -+ P_P2P_FSM_INFO_T prP2pFsmInfo = NULL; -+ struct _MSG_P2P_EXTEND_LISTEN_INTERVAL_T *prExtListenMsg = NULL; -+ -+ ASSERT_BREAK((prAdapter != NULL) && (prMsgHdr != NULL)); -+ -+ prExtListenMsg = (struct _MSG_P2P_EXTEND_LISTEN_INTERVAL_T *) prMsgHdr; -+ -+ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; -+ ASSERT_BREAK(prP2pFsmInfo); -+ -+ if (!prExtListenMsg->wait) { -+ DBGLOG(P2P, INFO, "reset listen interval\n"); -+ prP2pFsmInfo->eListenExted = P2P_DEV_NOT_EXT_LISTEN; -+ if (prMsgHdr) -+ cnmMemFree(prAdapter, prMsgHdr); -+ return; -+ } -+ -+ if (prP2pFsmInfo && (prP2pFsmInfo->eListenExted == P2P_DEV_NOT_EXT_LISTEN)) { -+ DBGLOG(P2P, INFO, "try to ext listen, p2p state: %d\n", prP2pFsmInfo->eCurrentState); -+ if (prP2pFsmInfo->eCurrentState == P2P_STATE_CHNL_ON_HAND) { -+ DBGLOG(P2P, INFO, "here to ext listen interval\n"); -+ prP2pFsmInfo->eListenExted = P2P_DEV_EXT_LISTEN_ING; -+ } -+ } -+ if (prMsgHdr) -+ cnmMemFree(prAdapter, prMsgHdr); -+} /* p2pFsmRunEventUpdateMgmtFrame */ -+ -+#if CFG_SUPPORT_WFD -+VOID p2pFsmRunEventWfdSettingUpdate(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) -+{ -+ P_WFD_CFG_SETTINGS_T prWfdCfgSettings = (P_WFD_CFG_SETTINGS_T) NULL; -+ P_MSG_WFD_CONFIG_SETTINGS_CHANGED_T prMsgWfdCfgSettings = (P_MSG_WFD_CONFIG_SETTINGS_CHANGED_T) NULL; -+ WLAN_STATUS rStatus; -+ -+ DBGLOG(P2P, INFO, "p2pFsmRunEventWfdSettingUpdate\n"); -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL)); -+ -+ if (prMsgHdr != NULL) { -+ prMsgWfdCfgSettings = (P_MSG_WFD_CONFIG_SETTINGS_CHANGED_T) prMsgHdr; -+ prWfdCfgSettings = prMsgWfdCfgSettings->prWfdCfgSettings; -+ } else { -+ prWfdCfgSettings = &prAdapter->rWifiVar.prP2pFsmInfo->rWfdConfigureSettings; -+ } -+ -+ DBGLOG(P2P, INFO, "WFD Enalbe %x info %x state %x flag %x adv %x\n", -+ prWfdCfgSettings->ucWfdEnable, -+ prWfdCfgSettings->u2WfdDevInfo, -+ (UINT_32) prWfdCfgSettings->u4WfdState, -+ (UINT_32) prWfdCfgSettings->u4WfdFlag, -+ (UINT_32) prWfdCfgSettings->u4WfdAdvancedFlag); -+ -+ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ -+ CMD_ID_SET_WFD_CTRL, /* ucCID */ -+ TRUE, /* fgSetQuery */ -+ FALSE, /* fgNeedResp */ -+ FALSE, /* fgIsOid */ -+ NULL, NULL, /* pfCmdTimeoutHandler */ -+ sizeof(WFD_CFG_SETTINGS_T), /* u4SetQueryInfoLen */ -+ (PUINT_8) prWfdCfgSettings, /* pucInfoBuffer */ -+ NULL, /* pvSetQueryBuffer */ -+ 0 /* u4SetQueryBufferLen */ -+ ); -+ -+ } while (FALSE); -+ -+ return; -+ -+} -+ -+/* p2pFsmRunEventWfdSettingUpdate */ -+ -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is used to generate P2P IE for Beacon frame. -+* -+* @param[in] prMsduInfo Pointer to the composed MSDU_INFO_T. -+* -+* @return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID p2pGenerateP2P_IEForAssocReq(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo) -+{ -+ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; -+ P_STA_RECORD_T prStaRec = (P_STA_RECORD_T) NULL; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prMsduInfo != NULL)); -+ -+ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; -+ -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); -+ -+ if (prStaRec != NULL) { -+ if (IS_STA_P2P_TYPE(prStaRec)) { -+ /* Do nothing */ -+ /* TODO: */ -+ } -+ } -+ -+ } while (FALSE); -+ -+ return; -+ -+} /* end of p2pGenerateP2P_IEForAssocReq() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is used to generate P2P IE for Probe Request frame. -+* -+* @param[in] prMsduInfo Pointer to the composed MSDU_INFO_T. -+* -+* @return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+p2pGenerateP2P_IEForProbeReq(IN P_ADAPTER_T prAdapter, IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize) -+{ -+ ASSERT(prAdapter); -+ ASSERT(pucBuf); -+ -+ /* TODO: */ -+ -+ return; -+ -+} /* end of p2pGenerateP2P_IEForProbReq() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is used to calculate P2P IE length for Beacon frame. -+* -+* @param[in] eNetTypeIndex Specify which network -+* @param[in] prStaRec Pointer to the STA_RECORD_T -+* -+* @return The length of P2P IE added -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT_32 -+p2pCalculateP2P_IELenForProbeReq(IN P_ADAPTER_T prAdapter, -+ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec) -+{ -+ -+ if (eNetTypeIndex != NETWORK_TYPE_P2P_INDEX) -+ return 0; -+ /* TODO: */ -+ -+ return 0; -+ -+} /* end of p2pCalculateP2P_IELenForProbeReq() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will indicate the Event of Tx Fail of AAA Module. -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* @param[in] prStaRec Pointer to the STA_RECORD_T -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID p2pRunEventAAATxFail(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec) -+{ -+ P_BSS_INFO_T prBssInfo; -+ -+ ASSERT(prAdapter); -+ ASSERT(prStaRec); -+ -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]); -+ -+ bssRemoveStaRecFromClientList(prAdapter, prBssInfo, prStaRec); -+ -+ p2pFuncDisconnect(prAdapter, prStaRec, FALSE, REASON_CODE_UNSPECIFIED); -+ -+ /* 20120830 moved into p2puUncDisconnect. */ -+ /* cnmStaRecFree(prAdapter, prStaRec, TRUE); */ -+ -+} /* p2pRunEventAAATxFail */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will indicate the Event of Successful Completion of AAA Module. -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* @param[in] prStaRec Pointer to the STA_RECORD_T -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS p2pRunEventAAAComplete(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec) -+{ -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; -+ ENUM_PARAM_MEDIA_STATE_T eOriMediaState; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prStaRec != NULL)); -+ -+ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); -+ -+ eOriMediaState = prP2pBssInfo->eConnectionState; -+ -+ if (prStaRec != NULL) -+ bssRemoveStaRecFromClientList(prAdapter, prP2pBssInfo, prStaRec); -+ else -+ break; -+ -+ if (prP2pBssInfo->rStaRecOfClientList.u4NumElem > P2P_MAXIMUM_CLIENT_COUNT || -+ kalP2PMaxClients(prAdapter->prGlueInfo, prP2pBssInfo->rStaRecOfClientList.u4NumElem)) { -+ rStatus = WLAN_STATUS_RESOURCES; -+ break; -+ } -+ -+ bssAddStaRecToClientList(prAdapter, prP2pBssInfo, prStaRec); -+ -+ prStaRec->u2AssocId = bssAssignAssocID(prStaRec); -+ -+ if (prP2pBssInfo->rStaRecOfClientList.u4NumElem > P2P_MAXIMUM_CLIENT_COUNT || -+ kalP2PMaxClients(prAdapter->prGlueInfo, prP2pBssInfo->rStaRecOfClientList.u4NumElem)) { -+ rStatus = WLAN_STATUS_RESOURCES; -+ break; -+ } -+ DBGLOG(P2P, INFO, "P2P GO Join Complete\n"); -+ -+ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_3); -+ -+ p2pChangeMediaState(prAdapter, PARAM_MEDIA_STATE_CONNECTED); -+ -+ /* Update Connected state to FW. */ -+ if (eOriMediaState != prP2pBssInfo->eConnectionState) -+ nicUpdateBss(prAdapter, NETWORK_TYPE_P2P_INDEX); -+ -+ } while (FALSE); -+ -+ return rStatus; -+} /* p2pRunEventAAAComplete */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will indicate the Event of Successful Completion of AAA Module. -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* @param[in] prStaRec Pointer to the STA_RECORD_T -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS p2pRunEventAAASuccess(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec) -+{ -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prStaRec != NULL)); -+ -+ /* Glue layer indication. */ -+ kalP2PGOStationUpdate(prAdapter->prGlueInfo, prStaRec, TRUE); -+ -+ } while (FALSE); -+ -+ return rStatus; -+} /* p2pRunEventAAASuccess */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS p2pRxPublicActionFrame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb) -+{ -+ WLAN_STATUS rWlanStatus = WLAN_STATUS_SUCCESS; -+ P_P2P_PUBLIC_ACTION_FRAME_T prPublicActionFrame = (P_P2P_PUBLIC_ACTION_FRAME_T) NULL; -+ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; -+ -+ ASSERT(prSwRfb); -+ ASSERT(prAdapter); -+ -+ prPublicActionFrame = (P_P2P_PUBLIC_ACTION_FRAME_T) prSwRfb->pvHeader; -+ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; -+ -+ DBGLOG(P2P, TRACE, "RX Public Action Frame Token:%d.\n", prPublicActionFrame->ucDialogToken); -+ -+ if (prPublicActionFrame->ucCategory != CATEGORY_PUBLIC_ACTION) -+ return rWlanStatus; -+ -+ switch (prPublicActionFrame->ucAction) { -+ case ACTION_PUBLIC_WIFI_DIRECT: -+ break; -+ case ACTION_GAS_INITIAL_REQUEST: -+ case ACTION_GAS_INITIAL_RESPONSE: -+ case ACTION_GAS_COMEBACK_REQUEST: -+ case ACTION_GAS_COMEBACK_RESPONSE: -+ break; -+ default: -+ break; -+ } -+ -+ return rWlanStatus; -+} /* p2pRxPublicActionFrame */ -+ -+WLAN_STATUS p2pRxActionFrame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb) -+{ -+ WLAN_STATUS rWlanStatus = WLAN_STATUS_SUCCESS; -+ P_P2P_ACTION_FRAME_T prP2pActionFrame = (P_P2P_ACTION_FRAME_T) NULL; -+ UINT_8 aucOui[3] = VENDOR_OUI_WFA_SPECIFIC; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prSwRfb != NULL)); -+ -+ prP2pActionFrame = (P_P2P_ACTION_FRAME_T) prSwRfb->pvHeader; -+ -+ if (prP2pActionFrame->ucCategory != CATEGORY_VENDOR_SPECIFIC_ACTION) { -+ DBGLOG(P2P, TRACE, "RX Action Frame but not vendor specific.\n"); -+ break; -+ } -+ -+ if ((prP2pActionFrame->ucOuiType != VENDOR_OUI_TYPE_P2P) || -+ (prP2pActionFrame->aucOui[0] != aucOui[0]) || -+ (prP2pActionFrame->aucOui[1] != aucOui[1]) || (prP2pActionFrame->aucOui[2] != aucOui[2])) { -+ DBGLOG(P2P, TRACE, "RX Vendor Specific Action Frame but not P2P Type or not WFA OUI.\n"); -+ break; -+ } -+ -+ } while (FALSE); -+ -+ return rWlanStatus; -+} /* p2pRxActionFrame */ -+ -+VOID -+p2pProcessEvent_UpdateNOAParam(IN P_ADAPTER_T prAdapter, -+ UINT_8 ucNetTypeIndex, P_EVENT_UPDATE_NOA_PARAMS_T prEventUpdateNoaParam) -+{ -+ P_BSS_INFO_T prBssInfo = (P_BSS_INFO_T) NULL; -+ P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo; -+ UINT_32 i; -+ BOOLEAN fgNoaAttrExisted = FALSE; -+ -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[ucNetTypeIndex]); -+ prP2pSpecificBssInfo = prAdapter->rWifiVar.prP2pSpecificBssInfo; -+ -+ prP2pSpecificBssInfo->fgEnableOppPS = prEventUpdateNoaParam->fgEnableOppPS; -+ prP2pSpecificBssInfo->u2CTWindow = prEventUpdateNoaParam->u2CTWindow; -+ prP2pSpecificBssInfo->ucNoAIndex = prEventUpdateNoaParam->ucNoAIndex; -+ prP2pSpecificBssInfo->ucNoATimingCount = prEventUpdateNoaParam->ucNoATimingCount; -+ -+ fgNoaAttrExisted |= prP2pSpecificBssInfo->fgEnableOppPS; -+ -+ DBGLOG(P2P, INFO, "Update NoA Count=%d.\n", prEventUpdateNoaParam->ucNoATimingCount); -+ -+ ASSERT(prP2pSpecificBssInfo->ucNoATimingCount <= P2P_MAXIMUM_NOA_COUNT); -+ -+ for (i = 0; i < prP2pSpecificBssInfo->ucNoATimingCount; i++) { -+ /* in used */ -+ prP2pSpecificBssInfo->arNoATiming[i].fgIsInUse = prEventUpdateNoaParam->arEventNoaTiming[i].fgIsInUse; -+ /* count */ -+ prP2pSpecificBssInfo->arNoATiming[i].ucCount = prEventUpdateNoaParam->arEventNoaTiming[i].ucCount; -+ /* duration */ -+ prP2pSpecificBssInfo->arNoATiming[i].u4Duration = prEventUpdateNoaParam->arEventNoaTiming[i].u4Duration; -+ /* interval */ -+ prP2pSpecificBssInfo->arNoATiming[i].u4Interval = prEventUpdateNoaParam->arEventNoaTiming[i].u4Interval; -+ /* start time */ -+ prP2pSpecificBssInfo->arNoATiming[i].u4StartTime = -+ prEventUpdateNoaParam->arEventNoaTiming[i].u4StartTime; -+ -+ fgNoaAttrExisted |= prP2pSpecificBssInfo->arNoATiming[i].fgIsInUse; -+ } -+ -+ prP2pSpecificBssInfo->fgIsNoaAttrExisted = fgNoaAttrExisted; -+ -+ /* update beacon content by the change */ -+ bssUpdateBeaconContent(prAdapter, ucNetTypeIndex); -+} -+ -+#endif /* CFG_ENABLE_WIFI_DIRECT */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_func.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_func.c -new file mode 100644 -index 000000000000..586a74721b3b ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_func.c -@@ -0,0 +1,3796 @@ -+#include "precomp.h" -+#include -+ -+#ifdef __GNUC__ -+#pragma GCC diagnostic ignored "-Wformat" -+#endif -+ -+APPEND_VAR_ATTRI_ENTRY_T txAssocRspAttributesTable[] = { -+ {(P2P_ATTRI_HDR_LEN + P2P_ATTRI_MAX_LEN_STATUS), NULL, p2pFuncAppendAttriStatusForAssocRsp} /* 0 */ -+ , {(P2P_ATTRI_HDR_LEN + P2P_ATTRI_MAX_LEN_EXT_LISTEN_TIMING), NULL, p2pFuncAppendAttriExtListenTiming} /* 8 */ -+}; -+ -+APPEND_VAR_IE_ENTRY_T txProbeRspIETable[] = { -+ {(ELEM_HDR_LEN + (RATE_NUM - ELEM_MAX_LEN_SUP_RATES)), NULL, bssGenerateExtSuppRate_IE} /* 50 */ -+ , {(ELEM_HDR_LEN + ELEM_MAX_LEN_ERP), NULL, rlmRspGenerateErpIE} /* 42 */ -+ , {(ELEM_HDR_LEN + ELEM_MAX_LEN_HT_CAP), NULL, rlmRspGenerateHtCapIE} /* 45 */ -+ , {(ELEM_HDR_LEN + ELEM_MAX_LEN_HT_OP), NULL, rlmRspGenerateHtOpIE} /* 61 */ -+ , {(ELEM_HDR_LEN + ELEM_MAX_LEN_RSN), NULL, rsnGenerateRSNIE} /* 48 */ -+ , {(ELEM_HDR_LEN + ELEM_MAX_LEN_OBSS_SCAN), NULL, rlmRspGenerateObssScanIE} /* 74 */ -+ , {(ELEM_HDR_LEN + ELEM_MAX_LEN_EXT_CAP), NULL, rlmRspGenerateExtCapIE} /* 127 */ -+ , {(ELEM_HDR_LEN + ELEM_MAX_LEN_WPA), NULL, rsnGenerateWpaNoneIE} /* 221 */ -+ , {(ELEM_HDR_LEN + ELEM_MAX_LEN_WMM_PARAM), NULL, mqmGenerateWmmParamIE} /* 221 */ -+}; -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Function for requesting scan. There is an option to do ACTIVE or PASSIVE scan. -+* -+* @param eScanType - Specify the scan type of the scan request. It can be an ACTIVE/PASSIVE -+* Scan. -+* eChannelSet - Specify the preferred channel set. -+* A FULL scan would request a legacy full channel normal scan.(usually ACTIVE). -+* A P2P_SOCIAL scan would scan 1+6+11 channels.(usually ACTIVE) -+* A SPECIFIC scan would only 1/6/11 channels scan. (Passive Listen/Specific Search) -+* ucChannelNum - A specific channel number. (Only when channel is specified) -+* eBand - A specific band. (Only when channel is specified) -+* -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID p2pFuncRequestScan(IN P_ADAPTER_T prAdapter, IN P_P2P_SCAN_REQ_INFO_T prScanReqInfo) -+{ -+ -+ P_MSG_SCN_SCAN_REQ prScanReq = (P_MSG_SCN_SCAN_REQ) NULL; -+ /*NFC Beam + Indication */ -+ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; -+ BOOLEAN fgIsPureAP = FALSE; -+ P_P2P_CHNL_REQ_INFO_T prChnlReqInfo = (P_P2P_CHNL_REQ_INFO_T) NULL; -+ -+ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); -+ fgIsPureAP = prAdapter->rWifiVar.prP2pFsmInfo->fgIsApMode; -+ -+ DEBUGFUNC("p2pFuncRequestScan()"); -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prScanReqInfo != NULL)); -+ -+ if (prScanReqInfo->eChannelSet == SCAN_CHANNEL_SPECIFIED) { -+ ASSERT_BREAK(prScanReqInfo->ucNumChannelList > 0); -+ DBGLOG(P2P, LOUD, -+ "P2P Scan Request Channel:%d\n", prScanReqInfo->arScanChannelList[0].ucChannelNum); -+ } -+ -+ prScanReq = (P_MSG_SCN_SCAN_REQ) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_SCN_SCAN_REQ)); -+ if (!prScanReq) { -+ ASSERT(0); /* Can't trigger SCAN FSM */ -+ break; -+ } -+ -+ prScanReq->rMsgHdr.eMsgId = MID_P2P_SCN_SCAN_REQ; -+ prScanReq->ucSeqNum = ++prScanReqInfo->ucSeqNumOfScnMsg; -+ prScanReq->ucNetTypeIndex = (UINT_8) NETWORK_TYPE_P2P_INDEX; -+ prScanReq->eScanType = prScanReqInfo->eScanType; -+ prScanReq->eScanChannel = prScanReqInfo->eChannelSet; -+ prScanReq->u2IELen = 0; -+ -+ /* Copy IE for Probe Request. */ -+ if (prScanReqInfo->u4BufLength > MAX_IE_LENGTH) -+ prScanReqInfo->u4BufLength = MAX_IE_LENGTH; -+ kalMemCopy(prScanReq->aucIE, prScanReqInfo->aucIEBuf, prScanReqInfo->u4BufLength); -+ prScanReq->u2IELen = (UINT_16) prScanReqInfo->u4BufLength; -+ -+ prScanReq->u2ChannelDwellTime = prScanReqInfo->u2PassiveDewellTime; -+ -+ switch (prScanReqInfo->eChannelSet) { -+ case SCAN_CHANNEL_SPECIFIED: -+ { -+ UINT_32 u4Idx = 0; -+ P_RF_CHANNEL_INFO_T prDomainInfo = -+ (P_RF_CHANNEL_INFO_T) prScanReqInfo->arScanChannelList; -+ UINT_8 aucP2pSsid[] = P2P_WILDCARD_SSID; -+ -+ -+ if (prScanReqInfo->ucNumChannelList > MAXIMUM_OPERATION_CHANNEL_LIST) -+ prScanReqInfo->ucNumChannelList = MAXIMUM_OPERATION_CHANNEL_LIST; -+ -+ for (u4Idx = 0; u4Idx < prScanReqInfo->ucNumChannelList; u4Idx++) { -+ prScanReq->arChnlInfoList[u4Idx].ucChannelNum = prDomainInfo->ucChannelNum; -+ prScanReq->arChnlInfoList[u4Idx].eBand = prDomainInfo->eBand; -+ prDomainInfo++; -+ } -+ -+ prScanReq->ucChannelListNum = prScanReqInfo->ucNumChannelList; -+ -+ /*NFC Beam + Indication */ -+ prChnlReqInfo = &prAdapter->rWifiVar.prP2pFsmInfo->rChnlReqInfo; -+ if (prChnlReqInfo->eChannelReqType == CHANNEL_REQ_TYPE_GO_START_BSS && -+ prP2pBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT && -+ !fgIsPureAP) { -+ prScanReq->ucChannelListNum = 1; -+ prScanReq->arChnlInfoList[0].ucChannelNum = prChnlReqInfo->ucReqChnlNum; -+ prScanReq->arChnlInfoList[0].eBand = prChnlReqInfo->eBand; -+ -+ DBGLOG(P2P, INFO, -+ "NFC:GO Skip Scan and Only Froce on %s[%d]\n", -+ prChnlReqInfo->eBand == 1 ? "2.4G" : "5G", -+ prChnlReqInfo->ucReqChnlNum); -+ } -+ -+ COPY_SSID(prScanReq->aucSSID, -+ prScanReq->ucSSIDLength, -+ prScanReqInfo->rSsidStruct.aucSsid, prScanReqInfo->rSsidStruct.ucSsidLen); -+ -+ /* For compatible. */ -+ if (EQUAL_SSID(aucP2pSsid, P2P_WILDCARD_SSID_LEN, -+ prScanReq->aucSSID, prScanReq->ucSSIDLength)) { -+ prScanReq->ucSSIDType = SCAN_REQ_SSID_P2P_WILDCARD; -+ } else if (prScanReq->ucSSIDLength != 0) { -+ prScanReq->ucSSIDType = SCAN_REQ_SSID_SPECIFIED; -+ } -+ -+ } -+ break; -+ -+ case SCAN_CHANNEL_FULL: -+ { -+ UINT_8 aucP2pSsid[] = P2P_WILDCARD_SSID; -+ -+ COPY_SSID(prScanReq->aucSSID, -+ prScanReq->ucSSIDLength, -+ prScanReqInfo->rSsidStruct.aucSsid, prScanReqInfo->rSsidStruct.ucSsidLen); -+ -+ /* For compatible. */ -+ if (EQUAL_SSID(aucP2pSsid, P2P_WILDCARD_SSID_LEN, -+ prScanReq->aucSSID, prScanReq->ucSSIDLength)) { -+ prScanReq->ucSSIDType = SCAN_REQ_SSID_P2P_WILDCARD; -+ } else if (prScanReq->ucSSIDLength != 0) { -+ prScanReq->ucSSIDType = SCAN_REQ_SSID_SPECIFIED; -+ } -+ } -+ break; -+ -+ case SCAN_CHANNEL_2G4: -+ { -+ UINT_8 aucP2pSsid[] = P2P_WILDCARD_SSID; -+ -+ COPY_SSID(prScanReq->aucSSID, -+ prScanReq->ucSSIDLength, -+ prScanReqInfo->rSsidStruct.aucSsid, prScanReqInfo->rSsidStruct.ucSsidLen); -+ -+ /* For compatible. */ -+ if (EQUAL_SSID(aucP2pSsid, P2P_WILDCARD_SSID_LEN, -+ prScanReq->aucSSID, prScanReq->ucSSIDLength)) { -+ prScanReq->ucSSIDType = SCAN_REQ_SSID_P2P_WILDCARD; -+ } else if (prScanReq->ucSSIDLength != 0) { -+ prScanReq->ucSSIDType = SCAN_REQ_SSID_SPECIFIED; -+ } -+ } -+ break; -+ -+ case SCAN_CHANNEL_P2P_SOCIAL: -+ { -+ UINT_8 aucP2pSsid[] = P2P_WILDCARD_SSID; -+ -+ COPY_SSID(prScanReq->aucSSID, -+ prScanReq->ucSSIDLength, -+ prScanReqInfo->rSsidStruct.aucSsid, prScanReqInfo->rSsidStruct.ucSsidLen); -+ -+ /* For compatible. */ -+ if (EQUAL_SSID(aucP2pSsid, P2P_WILDCARD_SSID_LEN, -+ prScanReq->aucSSID, prScanReq->ucSSIDLength)) { -+ prScanReq->ucSSIDType = SCAN_REQ_SSID_P2P_WILDCARD; -+ } else if (prScanReq->ucSSIDLength != 0) { -+ prScanReq->ucSSIDType = SCAN_REQ_SSID_SPECIFIED; -+ } -+ } -+ break; -+ default: -+ /* Currently there is no other scan channel set. */ -+ ASSERT(FALSE); -+ break; -+ } -+ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prScanReq, MSG_SEND_METHOD_BUF); -+ -+ } while (FALSE); -+ -+} /* p2pFuncRequestScan */ -+ -+VOID p2pFuncCancelScan(IN P_ADAPTER_T prAdapter, IN P_P2P_SCAN_REQ_INFO_T prScanInfo) -+{ -+ P_MSG_SCN_SCAN_CANCEL prScanCancelMsg = (P_MSG_SCN_SCAN_CANCEL) NULL; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prScanInfo != NULL)); -+ -+ if (!prScanInfo->fgIsScanRequest) -+ break; -+ -+ if (prScanInfo->ucSeqNumOfScnMsg) { -+ /* There is a channel privilege on hand. */ -+ DBGLOG(P2P, TRACE, "P2P Cancel Scan\n"); -+ -+ prScanCancelMsg = -+ (P_MSG_SCN_SCAN_CANCEL) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_SCN_SCAN_CANCEL)); -+ if (!prScanCancelMsg) { -+ /* Buffer not enough, can not cancel scan request. */ -+ DBGLOG(P2P, TRACE, "Buffer not enough, can not cancel scan.\n"); -+ ASSERT(FALSE); -+ break; -+ } -+ -+ prScanCancelMsg->rMsgHdr.eMsgId = MID_P2P_SCN_SCAN_CANCEL; -+ prScanCancelMsg->ucNetTypeIndex = NETWORK_TYPE_P2P_INDEX; -+ prScanCancelMsg->ucSeqNum = prScanInfo->ucSeqNumOfScnMsg++; -+ prScanCancelMsg->fgIsChannelExt = FALSE; -+ prScanInfo->fgIsScanRequest = FALSE; -+ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prScanCancelMsg, MSG_SEND_METHOD_BUF); -+ -+ } -+ -+ } while (FALSE); -+ -+} /* p2pFuncCancelScan */ -+ -+VOID -+p2pFuncSwitchOPMode(IN P_ADAPTER_T prAdapter, -+ IN P_BSS_INFO_T prP2pBssInfo, IN ENUM_OP_MODE_T eOpMode, IN BOOLEAN fgSyncToFW) -+{ -+ if (!prAdapter) -+ return; -+ if (!prAdapter->prGlueInfo) -+ return; -+ if (prAdapter->prGlueInfo->ulFlag & GLUE_FLAG_HALT) -+ return; -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prP2pBssInfo != NULL) && (eOpMode < OP_MODE_NUM)); -+ -+ if (prP2pBssInfo->eCurrentOPMode != eOpMode) { -+ DBGLOG(P2P, TRACE, -+ "p2pFuncSwitchOPMode: Switch to from %d, to %d.\n", prP2pBssInfo->eCurrentOPMode, -+ eOpMode); -+ -+ switch (prP2pBssInfo->eCurrentOPMode) { -+ case OP_MODE_ACCESS_POINT: -+ p2pFuncDissolve(prAdapter, prP2pBssInfo, TRUE, REASON_CODE_DEAUTH_LEAVING_BSS); -+ -+ p2pFsmRunEventStopAP(prAdapter, NULL); -+ break; -+ default: -+ break; -+ } -+ -+ prP2pBssInfo->eIntendOPMode = eOpMode; -+ prP2pBssInfo->eCurrentOPMode = eOpMode; -+ switch (eOpMode) { -+ case OP_MODE_INFRASTRUCTURE: -+ DBGLOG(P2P, TRACE, "p2pFuncSwitchOPMode: Switch to Client.\n"); -+ case OP_MODE_ACCESS_POINT: -+/* if (!IS_BSS_ACTIVE(prP2pBssInfo)) { */ -+/* SET_NET_ACTIVE(prAdapter, NETWORK_TYPE_P2P_INDEX); */ -+/* nicActivateNetwork(prAdapter, NETWORK_TYPE_P2P_INDEX); */ -+/* } */ -+ -+ /* Change interface address. */ -+ if (eOpMode == OP_MODE_ACCESS_POINT) { -+ DBGLOG(P2P, TRACE, "p2pFuncSwitchOPMode: Switch to AP.\n"); -+ prP2pBssInfo->ucSSIDLen = 0; -+ } -+ -+ COPY_MAC_ADDR(prP2pBssInfo->aucOwnMacAddr, prAdapter->rWifiVar.aucInterfaceAddress); -+ COPY_MAC_ADDR(prP2pBssInfo->aucBSSID, prAdapter->rWifiVar.aucInterfaceAddress); -+ -+ break; -+ case OP_MODE_P2P_DEVICE: -+ { -+ /* Change device address. */ -+ DBGLOG(P2P, TRACE, "p2pFuncSwitchOPMode: Switch back to P2P Device.\n"); -+ -+/* if (!IS_BSS_ACTIVE(prP2pBssInfo)) { */ -+/* SET_NET_ACTIVE(prAdapter, NETWORK_TYPE_P2P_INDEX); */ -+/* nicActivateNetwork(prAdapter, NETWORK_TYPE_P2P_INDEX); */ -+/* } */ -+ -+ p2pChangeMediaState(prAdapter, PARAM_MEDIA_STATE_DISCONNECTED); -+ -+ COPY_MAC_ADDR(prP2pBssInfo->aucOwnMacAddr, -+ prAdapter->rWifiVar.aucDeviceAddress); -+ COPY_MAC_ADDR(prP2pBssInfo->aucBSSID, prAdapter->rWifiVar.aucDeviceAddress); -+ -+ } -+ break; -+ default: -+/* if (IS_BSS_ACTIVE(prP2pBssInfo)) { */ -+/* UNSET_NET_ACTIVE(prAdapter, NETWORK_TYPE_P2P_INDEX); */ -+ -+/* nicDeactivateNetwork(prAdapter, NETWORK_TYPE_P2P_INDEX); */ -+/* } */ -+ ASSERT(FALSE); -+ break; -+ } -+ -+ if (1) { -+ P2P_DISCONNECT_INFO rP2PDisInfo; -+ -+ rP2PDisInfo.ucRole = 2; -+ wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_P2P_ABORT, -+ TRUE, -+ FALSE, -+ FALSE, -+ NULL, -+ NULL, -+ sizeof(P2P_DISCONNECT_INFO), (PUINT_8)&rP2PDisInfo, NULL, 0); -+ } -+ -+ DBGLOG(P2P, TRACE, -+ "The device address is changed to %pM\n", -+ prP2pBssInfo->aucOwnMacAddr); -+ DBGLOG(P2P, TRACE, "The BSSID is changed to %pM\n", prP2pBssInfo->aucBSSID); -+ -+ /* Update BSS INFO to FW. */ -+ if ((fgSyncToFW) && (eOpMode != OP_MODE_ACCESS_POINT)) -+ nicUpdateBss(prAdapter, NETWORK_TYPE_P2P_INDEX); -+ } -+ -+ } while (FALSE); -+ -+} /* p2pFuncSwitchOPMode */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will start a P2P Group Owner and send Beacon Frames. -+* -+* @param (none) -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+p2pFuncStartGO(IN P_ADAPTER_T prAdapter, -+ IN P_BSS_INFO_T prBssInfo, -+ IN PUINT_8 pucSsidBuf, -+ IN UINT_8 ucSsidLen, -+ IN UINT_8 ucChannelNum, IN ENUM_BAND_T eBand, IN ENUM_CHNL_EXT_T eSco, IN BOOLEAN fgIsPureAP) -+{ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prBssInfo != NULL)); -+ -+ ASSERT(prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT); -+ -+ prAdapter->rWifiVar.prP2pFsmInfo->rScanReqInfo.fgIsGOInitialDone = 1; -+ DBGLOG(P2P, INFO, -+ "p2pFuncStartGO:NFC Done[%d]\n", -+ prAdapter->rWifiVar.prP2pFsmInfo->rScanReqInfo.fgIsGOInitialDone); -+ /* AP mode started. */ -+ p2pFuncSwitchOPMode(prAdapter, prBssInfo, prBssInfo->eIntendOPMode, FALSE); -+ -+ prBssInfo->eIntendOPMode = OP_MODE_NUM; -+ -+ /* 4 <1.1> Assign SSID */ -+ COPY_SSID(prBssInfo->aucSSID, prBssInfo->ucSSIDLen, pucSsidBuf, ucSsidLen); -+ -+ DBGLOG(P2P, TRACE, "GO SSID:%s\n", prBssInfo->aucSSID); -+ -+ /* 4 <1.2> Clear current AP's STA_RECORD_T and current AID */ -+ prBssInfo->prStaRecOfAP = (P_STA_RECORD_T) NULL; -+ prBssInfo->u2AssocId = 0; -+ -+ /* 4 <1.3> Setup Channel, Band and Phy Attributes */ -+ prBssInfo->ucPrimaryChannel = ucChannelNum; -+ prBssInfo->eBand = eBand; -+ prBssInfo->eBssSCO = eSco; -+ -+ DBGLOG(P2P, TRACE, "GO Channel:%d\n", ucChannelNum); -+ -+ if (prBssInfo->eBand == BAND_5G) { -+ /* Depend on eBand */ -+ prBssInfo->ucPhyTypeSet = (prAdapter->rWifiVar.ucAvailablePhyTypeSet & PHY_TYPE_SET_802_11AN); -+ /* Depend on eCurrentOPMode and ucPhyTypeSet */ -+ prBssInfo->ucConfigAdHocAPMode = AP_MODE_11A; -+ } else if (fgIsPureAP) { -+ /* Depend on eBand */ -+ prBssInfo->ucPhyTypeSet = (prAdapter->rWifiVar.ucAvailablePhyTypeSet & PHY_TYPE_SET_802_11BGN); -+ /* Depend on eCurrentOPMode and ucPhyTypeSet */ -+ prBssInfo->ucConfigAdHocAPMode = AP_MODE_MIXED_11BG; -+ } else { -+ /* Depend on eBand */ -+ prBssInfo->ucPhyTypeSet = (prAdapter->rWifiVar.ucAvailablePhyTypeSet & PHY_TYPE_SET_802_11GN); -+ /* Depend on eCurrentOPMode and ucPhyTypeSet */ -+ prBssInfo->ucConfigAdHocAPMode = AP_MODE_11G_P2P; -+ } -+ -+ prBssInfo->ucNonHTBasicPhyType = (UINT_8) -+ rNonHTApModeAttributes[prBssInfo->ucConfigAdHocAPMode].ePhyTypeIndex; -+ prBssInfo->u2BSSBasicRateSet = rNonHTApModeAttributes[prBssInfo->ucConfigAdHocAPMode].u2BSSBasicRateSet; -+ prBssInfo->u2OperationalRateSet = -+ rNonHTPhyAttributes[prBssInfo->ucNonHTBasicPhyType].u2SupportedRateSet; -+ -+ if (prBssInfo->ucAllSupportedRatesLen == 0) { -+ rateGetDataRatesFromRateSet(prBssInfo->u2OperationalRateSet, -+ prBssInfo->u2BSSBasicRateSet, -+ prBssInfo->aucAllSupportedRates, -+ &prBssInfo->ucAllSupportedRatesLen); -+ } -+ /* 4 <1.5> Setup MIB for current BSS */ -+ prBssInfo->u2ATIMWindow = 0; -+ prBssInfo->ucBeaconTimeoutCount = 0; -+ -+ /* 3 <2> Update BSS_INFO_T common part */ -+#if CFG_SUPPORT_AAA -+ if (!fgIsPureAP) { -+ prBssInfo->fgIsProtection = TRUE; /* Always enable protection at P2P GO */ -+ kalP2PSetCipher(prAdapter->prGlueInfo, IW_AUTH_CIPHER_CCMP); -+ } else { -+ if (kalP2PGetCipher(prAdapter->prGlueInfo)) -+ prBssInfo->fgIsProtection = TRUE; -+ } -+ -+ /* 20120106 frog: I want separate OP_Mode & Beacon TX Function. */ -+ /* p2pFuncSwitchOPMode(prAdapter, prBssInfo, OP_MODE_ACCESS_POINT, FALSE); */ -+ -+ bssInitForAP(prAdapter, prBssInfo, FALSE); -+ -+ nicQmUpdateWmmParms(prAdapter, NETWORK_TYPE_P2P_INDEX); -+#endif /* CFG_SUPPORT_AAA */ -+ -+ /* 3 <3> Set MAC HW */ -+ /* 4 <3.1> Setup channel and bandwidth */ -+ rlmBssInitForAPandIbss(prAdapter, prBssInfo); -+ -+ /* 4 <3.2> Reset HW TSF Update Mode and Beacon Mode */ -+ nicUpdateBss(prAdapter, NETWORK_TYPE_P2P_INDEX); -+ -+ /* 4 <3.3> Update Beacon again for network phy type confirmed. */ -+ bssUpdateBeaconContent(prAdapter, NETWORK_TYPE_P2P_INDEX); -+ -+#if 0 /* CFG_SUPPORT_HOTSPOT_OPTIMIZATION */ -+ { -+ CMD_HOTSPOT_OPTIMIZATION_CONFIG arHotspotOptimizationCfg; -+ -+ arHotspotOptimizationCfg.fgHotspotOptimizationEn = TRUE; -+ arHotspotOptimizationCfg.u4Level = (0x3) << 8 | 0x5; -+ wlanoidSendSetQueryP2PCmd(prAdapter, -+ CMD_ID_SET_HOTSPOT_OPTIMIZATION, -+ TRUE, -+ FALSE, -+ TRUE, -+ NULL, -+ NULL, -+ sizeof(CMD_HOTSPOT_OPTIMIZATION_CONFIG), -+ (PUINT_8)&arHotspotOptimizationCfg, NULL, 0); -+ } -+#endif -+ -+ /* 4 <3.4> Setup BSSID */ -+ nicPmIndicateBssCreated(prAdapter, NETWORK_TYPE_P2P_INDEX); -+ -+ } while (FALSE); -+ -+} /* p2pFuncStartGO() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is to inform CNM that channel privilege -+* has been released -+* -+* \param[in] prAdapter Pointer of ADAPTER_T -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID p2pFuncReleaseCh(IN P_ADAPTER_T prAdapter, IN P_P2P_CHNL_REQ_INFO_T prChnlReqInfo) -+{ -+ P_MSG_CH_ABORT_T prMsgChRelease = (P_MSG_CH_ABORT_T) NULL; -+ -+ DEBUGFUNC("p2pFuncReleaseCh()"); -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prChnlReqInfo != NULL)); -+ -+ if (!prChnlReqInfo->fgIsChannelRequested) -+ break; -+ -+ DBGLOG(P2P, TRACE, "P2P Release Channel\n"); -+ prChnlReqInfo->fgIsChannelRequested = FALSE; -+ -+ /* 1. return channel privilege to CNM immediately */ -+ prMsgChRelease = (P_MSG_CH_ABORT_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_CH_ABORT_T)); -+ if (!prMsgChRelease) { -+ ASSERT(0); /* Can't release Channel to CNM */ -+ break; -+ } -+ -+ prMsgChRelease->rMsgHdr.eMsgId = MID_MNY_CNM_CH_ABORT; -+ prMsgChRelease->ucNetTypeIndex = NETWORK_TYPE_P2P_INDEX; -+ prMsgChRelease->ucTokenID = prChnlReqInfo->ucSeqNumOfChReq++; -+ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgChRelease, MSG_SEND_METHOD_BUF); -+ -+ } while (FALSE); -+ -+} /* p2pFuncReleaseCh */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Process of CHANNEL_REQ_JOIN Initial. Enter CHANNEL_REQ_JOIN State. -+* -+* @param (none) -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID p2pFuncAcquireCh(IN P_ADAPTER_T prAdapter, IN P_P2P_CHNL_REQ_INFO_T prChnlReqInfo) -+{ -+ P_MSG_CH_REQ_T prMsgChReq = (P_MSG_CH_REQ_T) NULL; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prChnlReqInfo != NULL)); -+ -+ p2pFuncReleaseCh(prAdapter, prChnlReqInfo); -+ -+ /* send message to CNM for acquiring channel */ -+ prMsgChReq = (P_MSG_CH_REQ_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_CH_REQ_T)); -+ -+ if (!prMsgChReq) { -+ ASSERT(0); /* Can't indicate CNM for channel acquiring */ -+ break; -+ } -+ -+ prMsgChReq->rMsgHdr.eMsgId = MID_MNY_CNM_CH_REQ; -+ prMsgChReq->ucNetTypeIndex = NETWORK_TYPE_P2P_INDEX; -+ prMsgChReq->ucTokenID = ++prChnlReqInfo->ucSeqNumOfChReq; -+ prMsgChReq->eReqType = CH_REQ_TYPE_JOIN; -+ if (prChnlReqInfo->u4MaxInterval < P2P_EXT_LISTEN_TIME_MS) -+ prMsgChReq->u4MaxInterval = P2P_EXT_LISTEN_TIME_MS; -+ else -+ prMsgChReq->u4MaxInterval = prChnlReqInfo->u4MaxInterval; -+ -+ prMsgChReq->ucPrimaryChannel = prChnlReqInfo->ucReqChnlNum; -+ prMsgChReq->eRfSco = prChnlReqInfo->eChnlSco; -+ prMsgChReq->eRfBand = prChnlReqInfo->eBand; -+ -+ kalMemZero(prMsgChReq->aucBSSID, MAC_ADDR_LEN); -+ -+ /* Channel request join BSSID. */ -+ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgChReq, MSG_SEND_METHOD_BUF); -+ -+ prChnlReqInfo->fgIsChannelRequested = TRUE; -+ -+ } while (FALSE); -+ -+} /* p2pFuncAcquireCh */ -+ -+#if 0 -+WLAN_STATUS -+p2pFuncBeaconUpdate(IN P_ADAPTER_T prAdapter, -+ IN PUINT_8 pucBcnHdr, -+ IN UINT_32 u4HdrLen, -+ IN PUINT_8 pucBcnBody, IN UINT_32 u4BodyLen, IN UINT_32 u4DtimPeriod, IN UINT_32 u4BcnInterval) -+{ -+ WLAN_STATUS rResultStatus = WLAN_STATUS_INVALID_DATA; -+ P_WLAN_BEACON_FRAME_T prBcnFrame = (P_WLAN_BEACON_FRAME_T) NULL; -+ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; -+ P_MSDU_INFO_T prBcnMsduInfo = (P_MSDU_INFO_T) NULL; -+ PUINT_8 pucTIMBody = (PUINT_8) NULL; -+ UINT_16 u2FrameLength = 0, UINT_16 u2OldBodyLen = 0; -+ UINT_8 aucIEBuf[MAX_IE_LENGTH]; -+ -+ do { -+ ASSERT_BREAK(prAdapter != NULL); -+ -+ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); -+ prBcnMsduInfo = prP2pBssInfo->prBeacon ASSERT_BREAK(prBcnMsduInfo != NULL); -+ -+ /* TODO: Find TIM IE pointer. */ -+ prBcnFrame = prBcnMsduInfo->prPacket; -+ -+ ASSERT_BREAK(prBcnFrame != NULL); -+ -+ do { -+ /* Ori header. */ -+ UINT_16 u2IELength = 0, u2Offset = 0; -+ PUINT_8 pucIEBuf = prBcnFrame->aucInfoElem; -+ -+ u2IELength = prBcnMsduInfo->u2FrameLength - prBcnMsduInfo->ucMacHeaderLength; -+ -+ IE_FOR_EACH(pucIEBuf, u2IELength, u2Offset) { -+ if ((IE_ID(pucIEBuf) == ELEM_ID_TIM) || ((IE_ID(pucIEBuf) > ELEM_ID_IBSS_PARAM_SET))) { -+ pucTIMBody = pucIEBuf; -+ break; -+ } -+ u2FrameLength += IE_SIZE(pucIEBuf); -+ } -+ -+ if (pucTIMBody == NULL) -+ pucTIMBody = pucIEBuf; -+ -+ /* Body not change. */ -+ u2OldBodyLen = (UINT_16) ((UINT_32) pucTIMBody - (UINT_32) prBcnFrame->aucInfoElem); -+ /* Move body. */ -+ kalMemCmp(aucIEBuf, pucTIMBody, u2OldBodyLen); -+ } while (FALSE); -+ -+ if (pucBcnHdr) { -+ kalMemCopy(prBcnMsduInfo->prPacket, pucBcnHdr, u4HdrLen); -+ pucTIMBody = (PUINT_8) ((UINT_32) prBcnMsduInfo->prPacket + u4HdrLen); -+ prBcnMsduInfo->ucMacHeaderLength = (WLAN_MAC_MGMT_HEADER_LEN + -+ (TIMESTAMP_FIELD_LEN + BEACON_INTERVAL_FIELD_LEN + CAP_INFO_FIELD_LEN)); -+ u2FrameLength = u4HdrLen; /* Header + Partial Body. */ -+ } else { -+ /* Header not change. */ -+ u2FrameLength += prBcnMsduInfo->ucMacHeaderLength; -+ } -+ -+ if (pucBcnBody) { -+ kalMemCopy(pucTIMBody, pucBcnBody, u4BodyLen); -+ u2FrameLength += (UINT_16) u4BodyLen; -+ } else { -+ kalMemCopy(pucTIMBody, aucIEBuf, u2OldBodyLen); -+ u2FrameLength += u2OldBodyLen; -+ } -+ -+ /* Frame Length */ -+ prBcnMsduInfo->u2FrameLength = u2FrameLength; -+ prBcnMsduInfo->fgIs802_11 = TRUE; -+ prBcnMsduInfo->ucNetworkType = NETWORK_TYPE_P2P_INDEX; -+ prP2pBssInfo->u2BeaconInterval = (UINT_16) u4BcnInterval; -+ prP2pBssInfo->ucDTIMPeriod = (UINT_8) u4DtimPeriod; -+ prP2pBssInfo->u2CapInfo = prBcnFrame->u2CapInfo; -+ prBcnMsduInfo->ucPacketType = 3; -+ rResultStatus = nicUpdateBeaconIETemplate(prAdapter, -+ IE_UPD_METHOD_UPDATE_ALL, -+ NETWORK_TYPE_P2P_INDEX, -+ prP2pBssInfo->u2CapInfo, -+ (PUINT_8) prBcnFrame->aucInfoElem, -+ prBcnMsduInfo->u2FrameLength - -+ OFFSET_OF(WLAN_BEACON_FRAME_T, -+ aucInfoElem)); -+ if (prP2pBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT) { -+ /* AP is created, Beacon Update. */ -+ nicPmIndicateBssAbort(prAdapter, NETWORK_TYPE_P2P_INDEX); -+ nicPmIndicateBssCreated(prAdapter, NETWORK_TYPE_P2P_INDEX); -+ } -+ -+ } while (FALSE); -+ return rResultStatus; -+} /* p2pFuncBeaconUpdate */ -+ -+#else -+WLAN_STATUS -+ p2pFuncBeaconUpdate(IN P_ADAPTER_T prAdapter, -+ IN P_BSS_INFO_T prP2pBssInfo, -+ IN P_P2P_BEACON_UPDATE_INFO_T prBcnUpdateInfo, -+ IN PUINT_8 pucNewBcnHdr, IN UINT_32 u4NewHdrLen, IN PUINT_8 pucNewBcnBody, IN UINT_32 u4NewBodyLen) -+{ -+WLAN_STATUS rWlanStatus = WLAN_STATUS_SUCCESS; -+P_WLAN_BEACON_FRAME_T prBcnFrame = (P_WLAN_BEACON_FRAME_T) NULL; -+P_MSDU_INFO_T prBcnMsduInfo = (P_MSDU_INFO_T) NULL; -+PUINT_8 pucIEBuf = (PUINT_8) NULL; -+PUINT_8 paucIEBuf = (PUINT_8) NULL;/*[MAX_IE_LENGTH]; aucIEBuf*/ -+ -+do { -+ ASSERT_BREAK((prAdapter != NULL) && (prP2pBssInfo != NULL) && (prBcnUpdateInfo != NULL)); -+ -+ prBcnMsduInfo = prP2pBssInfo->prBeacon; -+ -+#if DBG -+ if (prBcnUpdateInfo->pucBcnHdr != NULL) { -+ ASSERT((UINT_32) prBcnUpdateInfo->pucBcnHdr == -+ ((UINT_32) prBcnMsduInfo->prPacket + MAC_TX_RESERVED_FIELD)); -+ } -+ -+ if (prBcnUpdateInfo->pucBcnBody != NULL) { -+ ASSERT((UINT_32) prBcnUpdateInfo->pucBcnBody == -+ ((UINT_32) prBcnUpdateInfo->pucBcnHdr + (UINT_32) prBcnUpdateInfo->u4BcnHdrLen)); -+ } -+#endif -+ prBcnFrame = (P_WLAN_BEACON_FRAME_T) ((ULONG) prBcnMsduInfo->prPacket + MAC_TX_RESERVED_FIELD); -+ -+ if (!pucNewBcnBody) { -+ /* Old body. */ -+ pucNewBcnBody = prBcnUpdateInfo->pucBcnBody; -+ ASSERT(u4NewBodyLen == 0); -+ u4NewBodyLen = prBcnUpdateInfo->u4BcnBodyLen; -+ } else { -+ prBcnUpdateInfo->u4BcnBodyLen = u4NewBodyLen; -+ } -+ -+ paucIEBuf = kalMemAlloc(MAX_IE_LENGTH, VIR_MEM_TYPE); -+ if (paucIEBuf == NULL) { -+ DBGLOG(P2P, TRACE, "p2p alloc paucIEBuf fail\n"); -+ return WLAN_STATUS_FAILURE; -+ } -+ -+ /* Temp buffer body part. */ -+ kalMemCopy(paucIEBuf, pucNewBcnBody, u4NewBodyLen); -+ -+ if (pucNewBcnHdr) { -+ kalMemCopy(prBcnFrame, pucNewBcnHdr, u4NewHdrLen); -+ prBcnUpdateInfo->pucBcnHdr = (PUINT_8) prBcnFrame; -+ prBcnUpdateInfo->u4BcnHdrLen = u4NewHdrLen; -+ } -+ -+ pucIEBuf = (PUINT_8) ((ULONG) prBcnUpdateInfo->pucBcnHdr + (UINT_32) prBcnUpdateInfo->u4BcnHdrLen); -+ kalMemCopy(pucIEBuf, paucIEBuf, u4NewBodyLen); -+ kalMemFree(paucIEBuf, VIR_MEM_TYPE, MAX_IE_LENGTH); -+ prBcnUpdateInfo->pucBcnBody = pucIEBuf; -+ -+ /* Frame Length */ -+ prBcnMsduInfo->u2FrameLength = (UINT_16) (prBcnUpdateInfo->u4BcnHdrLen + prBcnUpdateInfo->u4BcnBodyLen); -+ -+ prBcnMsduInfo->ucPacketType = 3; -+ prBcnMsduInfo->fgIs802_11 = TRUE; -+ prBcnMsduInfo->ucNetworkType = NETWORK_TYPE_P2P_INDEX; -+ -+ /* Update BSS INFO related information. */ -+ COPY_MAC_ADDR(prP2pBssInfo->aucOwnMacAddr, prBcnFrame->aucSrcAddr); -+ COPY_MAC_ADDR(prP2pBssInfo->aucBSSID, prBcnFrame->aucBSSID); -+ prP2pBssInfo->u2CapInfo = prBcnFrame->u2CapInfo; -+ -+ p2pFuncParseBeaconContent(prAdapter, -+ prP2pBssInfo, -+ (PUINT_8) prBcnFrame->aucInfoElem, -+ (prBcnMsduInfo->u2FrameLength - OFFSET_OF(WLAN_BEACON_FRAME_T, aucInfoElem))); -+ -+#if 1 -+ /* bssUpdateBeaconContent(prAdapter, NETWORK_TYPE_P2P_INDEX); */ -+#else -+ nicUpdateBeaconIETemplate(prAdapter, -+ IE_UPD_METHOD_UPDATE_ALL, -+ NETWORK_TYPE_P2P_INDEX, -+ prBcnFrame->u2CapInfo, -+ (PUINT_8) prBcnFrame->aucInfoElem, -+ (prBcnMsduInfo->u2FrameLength - OFFSET_OF(WLAN_BEACON_FRAME_T, aucInfoElem))); -+#endif -+} while (FALSE); -+ -+return rWlanStatus; -+} /* p2pFuncBeaconUpdate */ -+ -+#endif -+ -+/* TODO: We do not apply IE in deauth frame set from upper layer now. */ -+WLAN_STATUS -+p2pFuncDeauth(IN P_ADAPTER_T prAdapter, -+ IN PUINT_8 pucPeerMacAddr, -+ IN UINT_16 u2ReasonCode, IN PUINT_8 pucIEBuf, IN UINT_16 u2IELen, IN BOOLEAN fgSendDeauth) -+{ -+ WLAN_STATUS rWlanStatus = WLAN_STATUS_FAILURE; -+ P_STA_RECORD_T prCliStaRec = (P_STA_RECORD_T) NULL; -+ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; -+ BOOLEAN fgIsStaFound = FALSE; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (pucPeerMacAddr != NULL)); -+ -+ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); -+ -+ prCliStaRec = cnmGetStaRecByAddress(prAdapter, NETWORK_TYPE_P2P_INDEX, pucPeerMacAddr); -+ -+ switch (prP2pBssInfo->eCurrentOPMode) { -+ case OP_MODE_ACCESS_POINT: -+ { -+ P_LINK_T prStaRecOfClientList = (P_LINK_T) NULL; -+ P_LINK_ENTRY_T prLinkEntry = (P_LINK_ENTRY_T) NULL; -+ -+ prStaRecOfClientList = &(prP2pBssInfo->rStaRecOfClientList); -+ -+ LINK_FOR_EACH(prLinkEntry, prStaRecOfClientList) { -+ if ((ULONG) prCliStaRec == (ULONG) prLinkEntry) { -+ LINK_REMOVE_KNOWN_ENTRY(prStaRecOfClientList, &prCliStaRec->rLinkEntry); -+ fgIsStaFound = TRUE; -+ break; -+ } -+ } -+ -+ } -+ break; -+ case OP_MODE_INFRASTRUCTURE: -+ ASSERT(prCliStaRec == prP2pBssInfo->prStaRecOfAP); -+ if (prCliStaRec != prP2pBssInfo->prStaRecOfAP) -+ break; -+ prP2pBssInfo->prStaRecOfAP = NULL; -+ fgIsStaFound = TRUE; -+ break; -+ default: -+ break; -+ } -+ -+ if (fgIsStaFound) -+ p2pFuncDisconnect(prAdapter, prCliStaRec, fgSendDeauth, u2ReasonCode); -+ -+ rWlanStatus = WLAN_STATUS_SUCCESS; -+ } while (FALSE); -+ -+ return rWlanStatus; -+} /* p2pFuncDeauth */ -+ -+/* TODO: We do not apply IE in disassoc frame set from upper layer now. */ -+WLAN_STATUS -+p2pFuncDisassoc(IN P_ADAPTER_T prAdapter, -+ IN PUINT_8 pucPeerMacAddr, -+ IN UINT_16 u2ReasonCode, IN PUINT_8 pucIEBuf, IN UINT_16 u2IELen, IN BOOLEAN fgSendDisassoc) -+{ -+ WLAN_STATUS rWlanStatus = WLAN_STATUS_FAILURE; -+ P_STA_RECORD_T prCliStaRec = (P_STA_RECORD_T) NULL; -+ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; -+ BOOLEAN fgIsStaFound = FALSE; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (pucPeerMacAddr != NULL)); -+ -+ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); -+ -+ prCliStaRec = cnmGetStaRecByAddress(prAdapter, NETWORK_TYPE_P2P_INDEX, pucPeerMacAddr); -+ -+ switch (prP2pBssInfo->eCurrentOPMode) { -+ case OP_MODE_ACCESS_POINT: -+ { -+ P_LINK_T prStaRecOfClientList = (P_LINK_T) NULL; -+ P_LINK_ENTRY_T prLinkEntry = (P_LINK_ENTRY_T) NULL; -+ -+ prStaRecOfClientList = &(prP2pBssInfo->rStaRecOfClientList); -+ -+ LINK_FOR_EACH(prLinkEntry, prStaRecOfClientList) { -+ if ((ULONG) prCliStaRec == (ULONG) prLinkEntry) { -+ LINK_REMOVE_KNOWN_ENTRY(prStaRecOfClientList, &prCliStaRec->rLinkEntry); -+ fgIsStaFound = TRUE; -+ /* p2pFuncDisconnect(prAdapter, prCliStaRec, -+ * fgSendDisassoc, u2ReasonCode); */ -+ break; -+ } -+ } -+ -+ } -+ break; -+ case OP_MODE_INFRASTRUCTURE: -+ ASSERT(prCliStaRec == prP2pBssInfo->prStaRecOfAP); -+ if (prCliStaRec != prP2pBssInfo->prStaRecOfAP) -+ break; -+ /* p2pFuncDisconnect(prAdapter, prCliStaRec, fgSendDisassoc, u2ReasonCode); */ -+ prP2pBssInfo->prStaRecOfAP = NULL; -+ fgIsStaFound = TRUE; -+ break; -+ default: -+ break; -+ } -+ -+ if (fgIsStaFound) { -+ -+ p2pFuncDisconnect(prAdapter, prCliStaRec, fgSendDisassoc, u2ReasonCode); -+ /* 20120830 moved into p2pFuncDisconnect(). */ -+ /* cnmStaRecFree(prAdapter, prCliStaRec, TRUE); */ -+ -+ } -+ -+ rWlanStatus = WLAN_STATUS_SUCCESS; -+ } while (FALSE); -+ -+ return rWlanStatus; -+} /* p2pFuncDisassoc */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is called to dissolve from group or one group. (Would not change P2P FSM.) -+* 1. GC: Disconnect from AP. (Send Deauth) -+* 2. GO: Disconnect all STA -+* -+* @param[in] prAdapter Pointer to the adapter structure. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+p2pFuncDissolve(IN P_ADAPTER_T prAdapter, -+ IN P_BSS_INFO_T prP2pBssInfo, IN BOOLEAN fgSendDeauth, IN UINT_16 u2ReasonCode) -+{ -+ DEBUGFUNC("p2pFuncDissolve()"); -+ -+ do { -+ -+ ASSERT_BREAK((prAdapter != NULL) && (prP2pBssInfo != NULL)); -+ -+ switch (prP2pBssInfo->eCurrentOPMode) { -+ case OP_MODE_INFRASTRUCTURE: -+ /* Reset station record status. */ -+ if (prP2pBssInfo->prStaRecOfAP) { -+ kalP2PGCIndicateConnectionStatus(prAdapter->prGlueInfo, -+ NULL, NULL, 0, REASON_CODE_DEAUTH_LEAVING_BSS, -+ WLAN_STATUS_MEDIA_DISCONNECT_LOCALLY); -+ -+ /* 2012/02/14 frog: After formation before join group, prStaRecOfAP is NULL. */ -+ p2pFuncDisconnect(prAdapter, prP2pBssInfo->prStaRecOfAP, fgSendDeauth, u2ReasonCode); -+ } -+ -+ /* Fix possible KE when RX Beacon & call nicPmIndicateBssConnected(). -+ * hit prStaRecOfAP == NULL. */ -+ p2pChangeMediaState(prAdapter, PARAM_MEDIA_STATE_DISCONNECTED); -+ -+ prP2pBssInfo->prStaRecOfAP = NULL; -+ -+ break; -+ case OP_MODE_ACCESS_POINT: -+ /* Under AP mode, we would net send deauthentication frame to each STA. -+ * We only stop the Beacon & let all stations timeout. -+ */ -+ { -+ P_LINK_T prStaRecOfClientList = (P_LINK_T) NULL; -+ -+ /* Send deauth. */ -+ authSendDeauthFrame(prAdapter, -+ NULL, (P_SW_RFB_T) NULL, u2ReasonCode, (PFN_TX_DONE_HANDLER) NULL); -+ -+ prStaRecOfClientList = &prP2pBssInfo->rStaRecOfClientList; -+ -+ while (!LINK_IS_EMPTY(prStaRecOfClientList)) { -+ P_STA_RECORD_T prCurrStaRec; -+ -+ LINK_REMOVE_HEAD(prStaRecOfClientList, prCurrStaRec, P_STA_RECORD_T); -+ -+ /* Indicate to Host. */ -+ /* kalP2PGOStationUpdate(prAdapter->prGlueInfo, prCurrStaRec, FALSE); */ -+ -+ p2pFuncDisconnect(prAdapter, prCurrStaRec, TRUE, u2ReasonCode); -+ -+ } -+ prAdapter->rWifiVar.prP2pFsmInfo->rScanReqInfo.fgIsGOInitialDone = 0; -+ } -+ -+ break; -+ default: -+ return; /* 20110420 -- alreay in Device Mode. */ -+ } -+ -+ /* Make the deauth frame send to FW ASAP. */ -+ wlanAcquirePowerControl(prAdapter); -+ wlanProcessCommandQueue(prAdapter, &prAdapter->prGlueInfo->rCmdQueue); -+ wlanReleasePowerControl(prAdapter); -+ -+ kalMdelay(100); -+ -+ /* Change Connection Status. */ -+ p2pChangeMediaState(prAdapter, PARAM_MEDIA_STATE_DISCONNECTED); -+ -+ } while (FALSE); -+ -+} /* p2pFuncDissolve */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is called to dissolve from group or one group. (Would not change P2P FSM.) -+* 1. GC: Disconnect from AP. (Send Deauth) -+* 2. GO: Disconnect all STA -+* -+* @param[in] prAdapter Pointer to the adapter structure. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+p2pFuncDisconnect(IN P_ADAPTER_T prAdapter, -+ IN P_STA_RECORD_T prStaRec, IN BOOLEAN fgSendDeauth, IN UINT_16 u2ReasonCode) -+{ -+ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; -+ ENUM_PARAM_MEDIA_STATE_T eOriMediaStatus; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prStaRec != NULL)); -+ -+ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); -+ eOriMediaStatus = prP2pBssInfo->eConnectionState; -+ -+ /* Indicate disconnect. */ -+ /* TODO: */ -+ /* kalP2PGOStationUpdate */ -+ /* kalP2PGCIndicateConnectionStatus */ -+ /* p2pIndicationOfMediaStateToHost(prAdapter, PARAM_MEDIA_STATE_DISCONNECTED, prStaRec->aucMacAddr); */ -+ DBGLOG(P2P, INFO, "p2pFuncDisconnect, eCurrentOPMode: %d, sendDeauth: %s\n", -+ prP2pBssInfo->eCurrentOPMode, fgSendDeauth ? "True" : "False"); -+ if (prP2pBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT) -+ kalP2PGOStationUpdate(prAdapter->prGlueInfo, prStaRec, FALSE); -+ -+ if (fgSendDeauth) { -+ /* Send deauth. */ -+ authSendDeauthFrame(prAdapter, -+ prStaRec, -+ (P_SW_RFB_T) NULL, -+ u2ReasonCode, (PFN_TX_DONE_HANDLER) p2pFsmRunEventDeauthTxDone); -+ } else { -+ /* Change station state. */ -+ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); -+ -+ /* Reset Station Record Status. */ -+ p2pFuncResetStaRecStatus(prAdapter, prStaRec); -+ -+ cnmStaRecFree(prAdapter, prStaRec, TRUE); -+ -+ if ((prP2pBssInfo->eCurrentOPMode != OP_MODE_ACCESS_POINT) || -+ (prP2pBssInfo->rStaRecOfClientList.u4NumElem == 0)) { -+ DBGLOG(P2P, TRACE, "No More Client, Media Status DISCONNECTED\n"); -+ p2pChangeMediaState(prAdapter, PARAM_MEDIA_STATE_DISCONNECTED); -+ } -+ -+ if (eOriMediaStatus != prP2pBssInfo->eConnectionState) { -+ /* Update Disconnected state to FW. */ -+ nicUpdateBss(prAdapter, NETWORK_TYPE_P2P_INDEX); -+ } -+ -+ } -+ -+ if (prP2pBssInfo->eCurrentOPMode != OP_MODE_ACCESS_POINT) { -+ /* GO: It would stop Beacon TX. GC: Stop all BSS related PS function. */ -+ nicPmIndicateBssAbort(prAdapter, NETWORK_TYPE_P2P_INDEX); -+ -+ /* Reset RLM related field of BSSINFO. */ -+ rlmBssAborted(prAdapter, prP2pBssInfo); -+ } -+ -+ } while (FALSE); -+ -+ return; -+ -+} /* p2pFuncDisconnect */ -+ -+/* Action frame categories (IEEE 802.11-2007, 7.3.1.11, Table 7-24) */ -+#define WLAN_ACTION_SPECTRUM_MGMT 0 -+#define WLAN_ACTION_QOS 1 -+#define WLAN_ACTION_DLS 2 -+#define WLAN_ACTION_BLOCK_ACK 3 -+#define WLAN_ACTION_PUBLIC 4 -+#define WLAN_ACTION_RADIO_MEASUREMENT 5 -+#define WLAN_ACTION_FT 6 -+#define WLAN_ACTION_HT 7 -+#define WLAN_ACTION_SA_QUERY 8 -+#define WLAN_ACTION_PROTECTED_DUAL 9 -+#define WLAN_ACTION_WNM 10 -+#define WLAN_ACTION_UNPROTECTED_WNM 11 -+#define WLAN_ACTION_TDLS 12 -+#define WLAN_ACTION_SELF_PROTECTED 15 -+#define WLAN_ACTION_WMM 17 /* WMM Specification 1.1 */ -+#define WLAN_ACTION_VENDOR_SPECIFIC 127 -+ -+/* Public action codes */ -+#define WLAN_PA_20_40_BSS_COEX 0 -+#define WLAN_PA_VENDOR_SPECIFIC 9 -+#define WLAN_PA_GAS_INITIAL_REQ 10 -+#define WLAN_PA_GAS_INITIAL_RESP 11 -+#define WLAN_PA_GAS_COMEBACK_REQ 12 -+#define WLAN_PA_GAS_COMEBACK_RESP 13 -+#define WLAN_TDLS_DISCOVERY_RESPONSE 14 -+ -+/* P2P public action frames */ -+enum p2p_action_frame_type { -+ P2P_GO_NEG_REQ = 0, -+ P2P_GO_NEG_RESP = 1, -+ P2P_GO_NEG_CONF = 2, -+ P2P_INVITATION_REQ = 3, -+ P2P_INVITATION_RESP = 4, -+ P2P_DEV_DISC_REQ = 5, -+ P2P_DEV_DISC_RESP = 6, -+ P2P_PROV_DISC_REQ = 7, -+ P2P_PROV_DISC_RESP = 8 -+}; -+ -+const char *p2p_to_string(enum p2p_action_frame_type p2p_action) -+{ -+ switch (p2p_action) { -+ case P2P_GO_NEG_REQ: -+ return "GO_NEG_REQ"; -+ case P2P_GO_NEG_RESP: -+ return "GO_NEG_RESP"; -+ case P2P_GO_NEG_CONF: -+ return "GO_NEG_CONF"; -+ case P2P_INVITATION_REQ: -+ return "INVITATION_REQ"; -+ case P2P_INVITATION_RESP: -+ return "INVITATION_RESP"; -+ case P2P_DEV_DISC_REQ: -+ return "DEV_DISC_REQ"; -+ case P2P_DEV_DISC_RESP: -+ return "DEV_DISC_RESP"; -+ case P2P_PROV_DISC_REQ: -+ return "PROV_DISC_REQ"; -+ case P2P_PROV_DISC_RESP: -+ return "PROV_DISC_RESP"; -+ } -+ -+ return "UNKNOWN P2P Public Action"; -+} -+const char *pa_to_string(int pa_action) -+{ -+ switch (pa_action) { -+ case WLAN_PA_20_40_BSS_COEX: -+ return "PA_20_40_BSS_COEX"; -+ case WLAN_PA_VENDOR_SPECIFIC: -+ return "PA_VENDOR_SPECIFIC"; -+ case WLAN_PA_GAS_INITIAL_REQ: -+ return "PA_GAS_INITIAL_REQ"; -+ case WLAN_PA_GAS_INITIAL_RESP: -+ return "PA_GAS_INITIAL_RESP"; -+ case WLAN_PA_GAS_COMEBACK_REQ: -+ return "PA_GAS_COMEBACK_REQ"; -+ case WLAN_PA_GAS_COMEBACK_RESP: -+ return "PA_GAS_COMEBACK_RESP"; -+ case WLAN_TDLS_DISCOVERY_RESPONSE: -+ return "TDLS_DISCOVERY_RESPONSE"; -+ } -+ -+ return "UNKNOWN Public Action"; -+} -+ -+const char *action_to_string(int wlan_action) -+{ -+ switch (wlan_action) { -+ case WLAN_ACTION_SPECTRUM_MGMT: -+ return "SPECTRUM_MGMT"; -+ case WLAN_ACTION_QOS: -+ return "QOS"; -+ case WLAN_ACTION_DLS: -+ return "DLS"; -+ case WLAN_ACTION_BLOCK_ACK: -+ return "BLOCK_ACK"; -+ case WLAN_ACTION_PUBLIC: -+ return "PUBLIC"; -+ case WLAN_ACTION_RADIO_MEASUREMENT: -+ return "RADIO_MEASUREMENT"; -+ case WLAN_ACTION_FT: -+ return "FT"; -+ case WLAN_ACTION_HT: -+ return "HT"; -+ case WLAN_ACTION_SA_QUERY: -+ return "SA_QUERY"; -+ case WLAN_ACTION_PROTECTED_DUAL: -+ return "PROTECTED_DUAL"; -+ case WLAN_ACTION_WNM: -+ return "WNM"; -+ case WLAN_ACTION_UNPROTECTED_WNM: -+ return "UNPROTECTED_WNM"; -+ case WLAN_ACTION_TDLS: -+ return "TDLS"; -+ case WLAN_ACTION_SELF_PROTECTED: -+ return "SELF_PROTECTED"; -+ case WLAN_ACTION_WMM: -+ return "WMM"; -+ case WLAN_ACTION_VENDOR_SPECIFIC: -+ return "VENDOR_SPECIFIC"; -+ } -+ -+ return "UNKNOWN Action Frame"; -+} -+ -+VOID p2pFuncTagActionActionP2PFrame(IN P_MSDU_INFO_T prMgmtTxMsdu, -+ IN P_WLAN_ACTION_FRAME prActFrame, -+ IN UINT_8 ucP2pAction, IN UINT_64 u8Cookie) -+{ -+ DBGLOG(P2P, INFO, "Found P2P_%s, SA: %pM - DA: %pM, cookie: 0x%llx, SeqNO: %d\n", -+ p2p_to_string(ucP2pAction), -+ prActFrame->aucSrcAddr, -+ prActFrame->aucDestAddr, -+ u8Cookie, -+ prMgmtTxMsdu->ucTxSeqNum); -+} -+ -+VOID p2pFuncTagActionActionFrame(IN P_MSDU_INFO_T prMgmtTxMsdu, -+ IN P_WLAN_ACTION_FRAME prActFrame, -+ IN UINT_8 ucAction, IN UINT_64 u8Cookie) -+{ -+ PUINT_8 pucVendor = NULL; -+ -+ DBGLOG(P2P, INFO, "Found WLAN_%s, SA: %pM - DA: %pM, cookie: 0x%llx, SeqNo: %d\n", -+ pa_to_string(ucAction), -+ prActFrame->aucSrcAddr, -+ prActFrame->aucDestAddr, -+ u8Cookie, -+ prMgmtTxMsdu->ucTxSeqNum); -+ -+ if (ucAction == WLAN_PA_VENDOR_SPECIFIC) { -+ pucVendor = (PUINT_8)prActFrame + 26; -+ if (*(pucVendor + 0) == 0x50 && -+ *(pucVendor + 1) == 0x6f && -+ *(pucVendor + 2) == 0x9a) { -+ if (*(pucVendor + 3) == 0x09) -+ /* found p2p IE */ -+ p2pFuncTagActionActionP2PFrame(prMgmtTxMsdu, -+ prActFrame, *(pucVendor + 4), u8Cookie); -+ else if (*(pucVendor + 3) == 0x0a) -+ /* found WFD IE */ -+ DBGLOG(P2P, INFO, "Found WFD IE, SA: %pM - DA: %pM\n", -+ prActFrame->aucSrcAddr, -+ prActFrame->aucDestAddr); -+ else -+ DBGLOG(P2P, INFO, "Found Other vendor 0x%x, SA: %pM - DA: %pM\n", -+ *(pucVendor + 3), -+ prActFrame->aucSrcAddr, -+ prActFrame->aucDestAddr); -+ } -+ } -+} -+ -+VOID p2pFuncTagActionCategoryFrame(IN P_MSDU_INFO_T prMgmtTxMsdu, -+ P_WLAN_ACTION_FRAME prActFrame, -+ IN UINT_8 ucCategory, -+ IN UINT_64 u8Cookie) -+{ -+ -+ UINT_8 ucAction = 0; -+ -+ DBGLOG(P2P, INFO, "Found WLAN_ACTION_%s, SA: %pM - DA: %pM, u8Cookie: 0x%llx, SeqNO: %d\n", -+ action_to_string(ucCategory), -+ prActFrame->aucSrcAddr, -+ prActFrame->aucDestAddr, -+ u8Cookie, -+ prMgmtTxMsdu->ucTxSeqNum); -+ -+ if (ucCategory == WLAN_ACTION_PUBLIC) { -+ ucAction = prActFrame->ucAction; -+ p2pFuncTagActionActionFrame(prMgmtTxMsdu, prActFrame, ucAction, u8Cookie); -+ -+ } -+} -+ -+/* -+ * used to debug p2p mgmt frame: -+ * GO Nego Req -+ * GO Nego Res -+ * GO Nego Confirm -+ * GO Invite Req -+ * GO Invite Res -+ * Device Discoverability Req -+ * Device Discoverability Res -+ * Provision Discovery Req -+ * Provision Discovery Res -+ */ -+ -+VOID -+p2pFuncTagMgmtFrame(IN P_MSDU_INFO_T prMgmtTxMsdu, IN UINT_64 u8Cookie) -+{ -+ /* P_MSDU_INFO_T prTxMsduInfo = (P_MSDU_INFO_T)NULL; */ -+ P_WLAN_MAC_HEADER_T prWlanHdr = (P_WLAN_MAC_HEADER_T) NULL; -+ P_WLAN_PROBE_RSP_FRAME_T prProbRspHdr = (P_WLAN_PROBE_RSP_FRAME_T)NULL; -+ UINT_16 u2TxFrameCtrl; -+ P_WLAN_ACTION_FRAME prActFrame; -+ UINT_8 ucCategory; -+ -+ prWlanHdr = (P_WLAN_MAC_HEADER_T) ((ULONG) prMgmtTxMsdu->prPacket + MAC_TX_RESERVED_FIELD); -+ /* -+ * mgmt frame MASK_FC_TYPE = 0 -+ * use MASK_FRAME_TYPE is oK for frame type/subtype judge -+ */ -+ u2TxFrameCtrl = prWlanHdr->u2FrameCtrl & MASK_FRAME_TYPE; -+ -+ switch (u2TxFrameCtrl) { -+ case MAC_FRAME_PROBE_RSP: -+ -+ prProbRspHdr = (P_WLAN_PROBE_RSP_FRAME_T) prWlanHdr; -+ DBGLOG(P2P, INFO, "TX Probe Response Frame, SA: %pM - DA: %pM, cookie: 0x%llx, seqNo: %d\n", -+ prProbRspHdr->aucSrcAddr, prProbRspHdr->aucDestAddr, -+ u8Cookie, -+ prMgmtTxMsdu->ucTxSeqNum); -+ -+ break; -+ -+ case MAC_FRAME_ACTION: -+ -+ prActFrame = (P_WLAN_ACTION_FRAME)prWlanHdr; -+ ucCategory = prActFrame->ucCategory; -+ p2pFuncTagActionCategoryFrame(prMgmtTxMsdu, prActFrame, -+ ucCategory, u8Cookie); -+ -+ break; -+ default: -+ DBGLOG(P2P, INFO, "MGMT:, un-tagged frame type: 0x%x, A1: %pM, A2: %pM, A3: %pM seqNo: %d\n", -+ u2TxFrameCtrl, -+ prWlanHdr->aucAddr1, -+ prWlanHdr->aucAddr2, -+ prWlanHdr->aucAddr3, -+ prMgmtTxMsdu->ucTxSeqNum); -+ break; -+ } -+} -+ -+WLAN_STATUS -+p2pFuncTxMgmtFrame(IN P_ADAPTER_T prAdapter, -+ IN P_P2P_MGMT_TX_REQ_INFO_T prMgmtTxReqInfo, IN P_MSDU_INFO_T prMgmtTxMsdu, IN UINT_64 u8Cookie) -+{ -+ WLAN_STATUS rWlanStatus = WLAN_STATUS_SUCCESS; -+ P_MSDU_INFO_T prTxMsduInfo = (P_MSDU_INFO_T) NULL; -+ P_WLAN_MAC_HEADER_T prWlanHdr = (P_WLAN_MAC_HEADER_T) NULL; -+ P_STA_RECORD_T prStaRec = (P_STA_RECORD_T) NULL; -+ BOOLEAN fgIsProbrsp = FALSE; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prMgmtTxReqInfo != NULL)); -+ -+ if (prMgmtTxReqInfo->fgIsMgmtTxRequested) { -+ -+ /* 1. prMgmtTxReqInfo->prMgmtTxMsdu != NULL */ -+ /* Packet on driver, not done yet, drop it. */ -+ prTxMsduInfo = prMgmtTxReqInfo->prMgmtTxMsdu; -+ if (prTxMsduInfo != NULL) { -+ -+ kalP2PIndicateMgmtTxStatus(prAdapter->prGlueInfo, -+ prMgmtTxReqInfo->u8Cookie, -+ FALSE, -+ prTxMsduInfo->prPacket, -+ (UINT_32) prTxMsduInfo->u2FrameLength); -+ -+ /* Leave it to TX Done handler. */ -+ /* cnmMgtPktFree(prAdapter, prTxMsduInfo); */ -+ prMgmtTxReqInfo->prMgmtTxMsdu = NULL; -+ DBGLOG(P2P, INFO, "p2pFuncTxMgmtFrame: Drop MGMT cookie: 0x%llx\n", -+ prMgmtTxReqInfo->u8Cookie); -+ } -+ /* 2. prMgmtTxReqInfo->prMgmtTxMsdu == NULL */ -+ /* Packet transmitted, wait tx done. (cookie issue) */ -+ /* 20120105 frog - use another u8cookie to store this value. */ -+ } -+ -+ ASSERT(prMgmtTxReqInfo->prMgmtTxMsdu == NULL); -+ -+ prWlanHdr = (P_WLAN_MAC_HEADER_T) ((ULONG) prMgmtTxMsdu->prPacket + MAC_TX_RESERVED_FIELD); -+ prStaRec = cnmGetStaRecByAddress(prAdapter, NETWORK_TYPE_P2P_INDEX, prWlanHdr->aucAddr1); -+ prMgmtTxMsdu->ucNetworkType = (UINT_8) NETWORK_TYPE_P2P_INDEX; -+ -+ switch (prWlanHdr->u2FrameCtrl & MASK_FRAME_TYPE) { -+ case MAC_FRAME_PROBE_RSP: -+ DBGLOG(P2P, TRACE, "p2pFuncTxMgmtFrame: TX MAC_FRAME_PROBE_RSP\n"); -+ fgIsProbrsp = TRUE; -+ prMgmtTxMsdu = p2pFuncProcessP2pProbeRsp(prAdapter, prMgmtTxMsdu); -+ break; -+ default: -+ break; -+ } -+ -+ prMgmtTxReqInfo->u8Cookie = u8Cookie; -+ prMgmtTxReqInfo->prMgmtTxMsdu = prMgmtTxMsdu; -+ prMgmtTxReqInfo->fgIsMgmtTxRequested = TRUE; -+ -+ prMgmtTxMsdu->eSrc = TX_PACKET_MGMT; -+ prMgmtTxMsdu->ucPacketType = HIF_TX_PACKET_TYPE_MGMT; -+ prMgmtTxMsdu->ucStaRecIndex = (prStaRec != NULL) ? (prStaRec->ucIndex) : (0xFF); -+ if (prStaRec != NULL) -+ DBGLOG(P2P, TRACE, "Mgmt with station record: %pM.\n", prStaRec->aucMacAddr); -+ -+ prMgmtTxMsdu->ucMacHeaderLength = WLAN_MAC_MGMT_HEADER_LEN; /* TODO: undcertain. */ -+ prMgmtTxMsdu->fgIs802_1x = FALSE; -+ prMgmtTxMsdu->fgIs802_11 = TRUE; -+ prMgmtTxMsdu->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter); -+ prMgmtTxMsdu->pfTxDoneHandler = p2pFsmRunEventMgmtFrameTxDone; -+ prMgmtTxMsdu->fgIsBasicRate = TRUE; -+ -+ p2pFuncTagMgmtFrame(prMgmtTxMsdu, u8Cookie); -+ -+ nicTxEnqueueMsdu(prAdapter, prMgmtTxMsdu); -+ -+ } while (FALSE); -+ -+ return rWlanStatus; -+} /* p2pFuncTxMgmtFrame */ -+ -+VOID p2pFuncSetChannel(IN P_ADAPTER_T prAdapter, IN P_RF_CHANNEL_INFO_T prRfChannelInfo) -+{ -+ P_P2P_CONNECTION_SETTINGS_T prP2pConnSettings = (P_P2P_CONNECTION_SETTINGS_T) NULL; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prRfChannelInfo != NULL)); -+ -+ prP2pConnSettings = prAdapter->rWifiVar.prP2PConnSettings; -+ -+ prP2pConnSettings->ucOperatingChnl = prRfChannelInfo->ucChannelNum; -+ prP2pConnSettings->eBand = prRfChannelInfo->eBand; -+ -+ } while (FALSE); -+ -+} -+ -+/* p2pFuncSetChannel */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Retry JOIN for AUTH_MODE_AUTO_SWITCH -+* -+* @param[in] prStaRec Pointer to the STA_RECORD_T -+* -+* @retval TRUE We will retry JOIN -+* @retval FALSE We will not retry JOIN -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN p2pFuncRetryJOIN(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN P_P2P_JOIN_INFO_T prJoinInfo) -+{ -+ P_MSG_JOIN_REQ_T prJoinReqMsg = (P_MSG_JOIN_REQ_T) NULL; -+ BOOLEAN fgRetValue = FALSE; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prStaRec != NULL) && (prJoinInfo != NULL)); -+ -+ /* Retry other AuthType if possible */ -+ if (!prJoinInfo->ucAvailableAuthTypes) -+ break; -+ -+ if (prJoinInfo->ucAvailableAuthTypes & (UINT_8) AUTH_TYPE_SHARED_KEY) { -+ -+ DBGLOG(P2P, INFO, "RETRY JOIN INIT: Retry Authentication with AuthType == SHARED_KEY.\n"); -+ -+ prJoinInfo->ucAvailableAuthTypes &= ~(UINT_8) AUTH_TYPE_SHARED_KEY; -+ -+ prStaRec->ucAuthAlgNum = (UINT_8) AUTH_ALGORITHM_NUM_SHARED_KEY; -+ } else { -+ DBGLOG(P2P, ERROR, "RETRY JOIN INIT: Retry Authentication with Unexpected AuthType.\n"); -+ ASSERT(0); -+ break; -+ } -+ -+ prJoinInfo->ucAvailableAuthTypes = 0; /* No more available Auth Types */ -+ -+ /* Trigger SAA to start JOIN process. */ -+ prJoinReqMsg = (P_MSG_JOIN_REQ_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_JOIN_REQ_T)); -+ if (!prJoinReqMsg) { -+ ASSERT(0); /* Can't trigger SAA FSM */ -+ break; -+ } -+ -+ prJoinReqMsg->rMsgHdr.eMsgId = MID_P2P_SAA_FSM_START; -+ prJoinReqMsg->ucSeqNum = ++prJoinInfo->ucSeqNumOfReqMsg; -+ prJoinReqMsg->prStaRec = prStaRec; -+ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prJoinReqMsg, MSG_SEND_METHOD_BUF); -+ -+ fgRetValue = TRUE; -+ } while (FALSE); -+ -+ return fgRetValue; -+ -+} /* end of p2pFuncRetryJOIN() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will update the contain of BSS_INFO_T for AIS network once -+* the association was completed. -+* -+* @param[in] prStaRec Pointer to the STA_RECORD_T -+* @param[in] prAssocRspSwRfb Pointer to SW RFB of ASSOC RESP FRAME. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+p2pFuncUpdateBssInfoForJOIN(IN P_ADAPTER_T prAdapter, -+ IN P_BSS_DESC_T prBssDesc, IN P_STA_RECORD_T prStaRec, IN P_SW_RFB_T prAssocRspSwRfb) -+{ -+ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; -+ P_P2P_CONNECTION_SETTINGS_T prP2pConnSettings = (P_P2P_CONNECTION_SETTINGS_T) NULL; -+ P_WLAN_ASSOC_RSP_FRAME_T prAssocRspFrame = (P_WLAN_ASSOC_RSP_FRAME_T) NULL; -+ UINT_16 u2IELength; -+ PUINT_8 pucIE; -+ -+ DEBUGFUNC("p2pUpdateBssInfoForJOIN()"); -+ -+ ASSERT(prAdapter); -+ ASSERT(prStaRec); -+ ASSERT(prAssocRspSwRfb); -+ -+ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); -+ prP2pConnSettings = prAdapter->rWifiVar.prP2PConnSettings; -+ prAssocRspFrame = (P_WLAN_ASSOC_RSP_FRAME_T) prAssocRspSwRfb->pvHeader; -+ -+ DBGLOG(P2P, INFO, "Update P2P_BSS_INFO_T and apply settings to MAC\n"); -+ -+ /* 3 <1> Update BSS_INFO_T from AIS_FSM_INFO_T or User Settings */ -+ /* 4 <1.1> Setup Operation Mode */ -+ prP2pBssInfo->eCurrentOPMode = OP_MODE_INFRASTRUCTURE; -+ -+ /* 4 <1.2> Setup SSID */ -+ COPY_SSID(prP2pBssInfo->aucSSID, -+ prP2pBssInfo->ucSSIDLen, prP2pConnSettings->aucSSID, prP2pConnSettings->ucSSIDLen); -+ -+ if (prBssDesc == NULL) { -+ /* Target BSS NULL. */ -+ DBGLOG(P2P, TRACE, "Target BSS NULL\n"); -+ return; -+ } -+ -+ if (UNEQUAL_MAC_ADDR(prBssDesc->aucBSSID, prAssocRspFrame->aucBSSID)) -+ ASSERT(FALSE); -+ /* 4 <1.3> Setup Channel, Band */ -+ prP2pBssInfo->ucPrimaryChannel = prBssDesc->ucChannelNum; -+ prP2pBssInfo->eBand = prBssDesc->eBand; -+ -+ /* 3 <2> Update BSS_INFO_T from STA_RECORD_T */ -+ /* 4 <2.1> Save current AP's STA_RECORD_T and current AID */ -+ prP2pBssInfo->prStaRecOfAP = prStaRec; -+ prP2pBssInfo->u2AssocId = prStaRec->u2AssocId; -+ -+ /* 4 <2.2> Setup Capability */ -+ prP2pBssInfo->u2CapInfo = prStaRec->u2CapInfo; /* Use AP's Cap Info as BSS Cap Info */ -+ -+ if (prP2pBssInfo->u2CapInfo & CAP_INFO_SHORT_PREAMBLE) -+ prP2pBssInfo->fgIsShortPreambleAllowed = TRUE; -+ else -+ prP2pBssInfo->fgIsShortPreambleAllowed = FALSE; -+ -+ /* 4 <2.3> Setup PHY Attributes and Basic Rate Set/Operational Rate Set */ -+ prP2pBssInfo->ucPhyTypeSet = prStaRec->ucDesiredPhyTypeSet; -+ -+ prP2pBssInfo->ucNonHTBasicPhyType = prStaRec->ucNonHTBasicPhyType; -+ -+ prP2pBssInfo->u2OperationalRateSet = prStaRec->u2OperationalRateSet; -+ prP2pBssInfo->u2BSSBasicRateSet = prStaRec->u2BSSBasicRateSet; -+ -+ /* 3 <3> Update BSS_INFO_T from SW_RFB_T (Association Resp Frame) */ -+ /* 4 <3.1> Setup BSSID */ -+ COPY_MAC_ADDR(prP2pBssInfo->aucBSSID, prAssocRspFrame->aucBSSID); -+ -+ u2IELength = (UINT_16) ((prAssocRspSwRfb->u2PacketLen - prAssocRspSwRfb->u2HeaderLen) - -+ (OFFSET_OF(WLAN_ASSOC_RSP_FRAME_T, aucInfoElem[0]) - WLAN_MAC_MGMT_HEADER_LEN)); -+ pucIE = prAssocRspFrame->aucInfoElem; -+ -+ /* 4 <3.2> Parse WMM and setup QBSS flag */ -+ /* Parse WMM related IEs and configure HW CRs accordingly */ -+ mqmProcessAssocRsp(prAdapter, prAssocRspSwRfb, pucIE, u2IELength); -+ -+ prP2pBssInfo->fgIsQBSS = prStaRec->fgIsQoS; -+ -+ /* 3 <4> Update BSS_INFO_T from BSS_DESC_T */ -+ ASSERT(prBssDesc); -+ -+ prBssDesc->fgIsConnecting = FALSE; -+ prBssDesc->fgIsConnected = TRUE; -+ -+ /* 4 <4.1> Setup MIB for current BSS */ -+ prP2pBssInfo->u2BeaconInterval = prBssDesc->u2BeaconInterval; -+ /* NOTE: Defer ucDTIMPeriod updating to when beacon is received after connection */ -+ prP2pBssInfo->ucDTIMPeriod = 0; -+ prP2pBssInfo->u2ATIMWindow = 0; -+ -+ prP2pBssInfo->ucBeaconTimeoutCount = AIS_BEACON_TIMEOUT_COUNT_INFRA; -+ -+ /* 4 <4.2> Update HT information and set channel */ -+ /* Record HT related parameters in rStaRec and rBssInfo -+ * Note: it shall be called before nicUpdateBss() -+ */ -+ rlmProcessAssocRsp(prAdapter, prAssocRspSwRfb, pucIE, u2IELength); -+ -+ /* 4 <4.3> Sync with firmware for BSS-INFO */ -+ nicUpdateBss(prAdapter, NETWORK_TYPE_P2P_INDEX); -+ -+ /* 4 <4.4> *DEFER OPERATION* nicPmIndicateBssConnected() will be invoked */ -+ /* inside scanProcessBeaconAndProbeResp() after 1st beacon is received */ -+ -+} /* end of p2pUpdateBssInfoForJOIN() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will validate the Rx Auth Frame and then return -+* the status code to AAA to indicate if need to perform following actions -+* when the specified conditions were matched. -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* @param[in] prSwRfb Pointer to SW RFB data structure. -+* @param[in] pprStaRec Pointer to pointer of STA_RECORD_T structure. -+* @param[out] pu2StatusCode The Status Code of Validation Result -+* -+* @retval TRUE Reply the Auth -+* @retval FALSE Don't reply the Auth -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN -+p2pFuncValidateAuth(IN P_ADAPTER_T prAdapter, -+ IN P_SW_RFB_T prSwRfb, IN PP_STA_RECORD_T pprStaRec, OUT PUINT_16 pu2StatusCode) -+{ -+ BOOLEAN fgReplyAuth = TRUE; -+ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; -+ P_STA_RECORD_T prStaRec = (P_STA_RECORD_T) NULL; -+ P_WLAN_AUTH_FRAME_T prAuthFrame = (P_WLAN_AUTH_FRAME_T) NULL; -+ -+ DBGLOG(P2P, INFO, "p2pValidate Authentication Frame\n"); -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && -+ (prSwRfb != NULL) && (pprStaRec != NULL) && (pu2StatusCode != NULL)); -+ -+ /* P2P 3.2.8 */ -+ *pu2StatusCode = STATUS_CODE_REQ_DECLINED; -+ -+ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); -+ prAuthFrame = (P_WLAN_AUTH_FRAME_T) prSwRfb->pvHeader; -+ -+ if ((prP2pBssInfo->eCurrentOPMode != OP_MODE_ACCESS_POINT) -+ || (prP2pBssInfo->eIntendOPMode != OP_MODE_NUM)) { -+ /* We are not under AP Mode yet. */ -+ fgReplyAuth = FALSE; -+ DBGLOG(P2P, WARN, -+ "Current OP mode is not under AP mode. (%d)\n", prP2pBssInfo->eCurrentOPMode); -+ break; -+ } -+ -+ prStaRec = cnmGetStaRecByAddress(prAdapter, (UINT_8) NETWORK_TYPE_P2P_INDEX, prAuthFrame->aucSrcAddr); -+ -+ if (!prStaRec) { -+ prStaRec = cnmStaRecAlloc(prAdapter, (UINT_8) NETWORK_TYPE_P2P_INDEX); -+ -+ /* TODO(Kevin): Error handling of allocation of STA_RECORD_T for -+ * exhausted case and do removal of unused STA_RECORD_T. -+ */ -+ /* Sent a message event to clean un-used STA_RECORD_T. */ -+ ASSERT(prStaRec); -+ if (!prStaRec) { -+ DBGLOG(AAA, INFO, "Station Limit Full. Decline a new Authentication.\n"); -+ break; -+ } -+ -+ COPY_MAC_ADDR(prStaRec->aucMacAddr, prAuthFrame->aucSrcAddr); -+ -+ prSwRfb->ucStaRecIdx = prStaRec->ucIndex; -+ -+ prStaRec->u2BSSBasicRateSet = prP2pBssInfo->u2BSSBasicRateSet; -+ -+ prStaRec->u2DesiredNonHTRateSet = RATE_SET_ERP_P2P; -+ -+ prStaRec->u2OperationalRateSet = RATE_SET_ERP_P2P; -+ prStaRec->ucPhyTypeSet = PHY_TYPE_SET_802_11GN; -+ prStaRec->eStaType = STA_TYPE_P2P_GC; -+ -+ /* NOTE(Kevin): Better to change state here, not at TX Done */ -+ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); -+ } else { -+ prSwRfb->ucStaRecIdx = prStaRec->ucIndex; -+ -+ if ((prStaRec->ucStaState > STA_STATE_1) && (IS_STA_IN_P2P(prStaRec))) { -+ -+ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); -+ -+ p2pFuncResetStaRecStatus(prAdapter, prStaRec); -+ -+ bssRemoveStaRecFromClientList(prAdapter, prP2pBssInfo, prStaRec); -+ } -+ -+ } -+ -+ if (prP2pBssInfo->rStaRecOfClientList.u4NumElem >= P2P_MAXIMUM_CLIENT_COUNT || -+ kalP2PMaxClients(prAdapter->prGlueInfo, prP2pBssInfo->rStaRecOfClientList.u4NumElem)) { -+ /* GROUP limit full. */ -+ /* P2P 3.2.8 */ -+ DBGLOG(P2P, WARN, -+ "Group Limit Full. (%d)\n", (INT_16) prP2pBssInfo->rStaRecOfClientList.u4NumElem); -+ -+ bssRemoveStaRecFromClientList(prAdapter, prP2pBssInfo, prStaRec); -+ -+ cnmStaRecFree(prAdapter, prStaRec, FALSE); -+ fgReplyAuth = TRUE; -+ *pu2StatusCode = STATUS_CODE_ASSOC_DENIED_AP_OVERLOAD; -+ break; -+ } -+ /* Hotspot Blacklist */ -+ if (prAuthFrame->aucSrcAddr) { -+ if (kalP2PCmpBlackList(prAdapter->prGlueInfo, prAuthFrame->aucSrcAddr)) { -+ fgReplyAuth = TRUE; -+ *pu2StatusCode = STATUS_CODE_ASSOC_DENIED_OUTSIDE_STANDARD; -+ return fgReplyAuth; -+ } -+ } -+ -+ /* prStaRec->eStaType = STA_TYPE_INFRA_CLIENT; */ -+ prStaRec->eStaType = STA_TYPE_P2P_GC; -+ -+ prStaRec->ucNetTypeIndex = NETWORK_TYPE_P2P_INDEX; -+ -+ /* Update Station Record - Status/Reason Code */ -+ prStaRec->u2StatusCode = STATUS_CODE_SUCCESSFUL; -+ -+ prStaRec->ucJoinFailureCount = 0; -+ -+ *pprStaRec = prStaRec; -+ -+ *pu2StatusCode = STATUS_CODE_SUCCESSFUL; -+ -+ } while (FALSE); -+ -+ return fgReplyAuth; -+ -+} /* p2pFuncValidateAuth */ -+ -+VOID p2pFuncResetStaRecStatus(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec) -+{ -+ do { -+ if ((prAdapter == NULL) || (prStaRec == NULL)) { -+ ASSERT(FALSE); -+ break; -+ } -+ -+ prStaRec->u2StatusCode = STATUS_CODE_SUCCESSFUL; -+ prStaRec->u2ReasonCode = REASON_CODE_RESERVED; -+ prStaRec->ucJoinFailureCount = 0; -+ prStaRec->fgTransmitKeyExist = FALSE; -+ -+ prStaRec->fgSetPwrMgtBit = FALSE; -+ -+ } while (FALSE); -+ -+} /* p2pFuncResetStaRecStatus */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief The function is used to initialize the value of the connection settings for -+* P2P network -+* -+* @param (none) -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID p2pFuncInitConnectionSettings(IN P_ADAPTER_T prAdapter, IN P_P2P_CONNECTION_SETTINGS_T prP2PConnSettings) -+{ -+ P_DEVICE_TYPE_T prDevType; -+ UINT_8 aucDefaultDevName[] = P2P_DEFAULT_DEV_NAME; -+ UINT_8 aucWfaOui[] = VENDOR_OUI_WFA; -+#if CFG_SUPPORT_CFG_FILE -+ P_WIFI_VAR_T prWifiVar = NULL; -+#endif -+ -+ ASSERT(prP2PConnSettings); -+#if CFG_SUPPORT_CFG_FILE -+ prWifiVar = &(prAdapter->rWifiVar); -+ ASSERT(prWifiVar); -+#endif -+ -+ /* Setup Default Device Name */ -+ prP2PConnSettings->ucDevNameLen = P2P_DEFAULT_DEV_NAME_LEN; -+ kalMemCopy(prP2PConnSettings->aucDevName, aucDefaultDevName, sizeof(aucDefaultDevName)); -+ -+ /* Setup Primary Device Type (Big-Endian) */ -+ prDevType = &prP2PConnSettings->rPrimaryDevTypeBE; -+ -+ prDevType->u2CategoryId = HTONS(P2P_DEFAULT_PRIMARY_CATEGORY_ID); -+ prDevType->u2SubCategoryId = HTONS(P2P_DEFAULT_PRIMARY_SUB_CATEGORY_ID); -+ -+ prDevType->aucOui[0] = aucWfaOui[0]; -+ prDevType->aucOui[1] = aucWfaOui[1]; -+ prDevType->aucOui[2] = aucWfaOui[2]; -+ prDevType->aucOui[3] = VENDOR_OUI_TYPE_WPS; -+ -+ /* Setup Secondary Device Type */ -+ prP2PConnSettings->ucSecondaryDevTypeCount = 0; -+ -+ /* Setup Default Config Method */ -+ prP2PConnSettings->eConfigMethodSelType = ENUM_CONFIG_METHOD_SEL_AUTO; -+ prP2PConnSettings->u2ConfigMethodsSupport = P2P_DEFAULT_CONFIG_METHOD; -+ prP2PConnSettings->u2TargetConfigMethod = 0; -+ prP2PConnSettings->u2LocalConfigMethod = 0; -+ prP2PConnSettings->fgIsPasswordIDRdy = FALSE; -+ -+ /* For Device Capability */ -+ prP2PConnSettings->fgSupportServiceDiscovery = FALSE; -+ prP2PConnSettings->fgSupportClientDiscoverability = TRUE; -+ prP2PConnSettings->fgSupportConcurrentOperation = TRUE; -+ prP2PConnSettings->fgSupportInfraManaged = FALSE; -+ prP2PConnSettings->fgSupportInvitationProcedure = FALSE; -+ -+ /* For Group Capability */ -+#if CFG_SUPPORT_PERSISTENT_GROUP -+ prP2PConnSettings->fgSupportPersistentP2PGroup = TRUE; -+#else -+ prP2PConnSettings->fgSupportPersistentP2PGroup = FALSE; -+#endif -+ prP2PConnSettings->fgSupportIntraBSSDistribution = TRUE; -+ prP2PConnSettings->fgSupportCrossConnection = TRUE; -+ prP2PConnSettings->fgSupportPersistentReconnect = FALSE; -+ -+ prP2PConnSettings->fgSupportOppPS = FALSE; -+ prP2PConnSettings->u2CTWindow = P2P_CTWINDOW_DEFAULT; -+ -+ /* For Connection Settings. */ -+ prP2PConnSettings->eAuthMode = AUTH_MODE_OPEN; -+ -+ prP2PConnSettings->prTargetP2pDesc = NULL; -+ prP2PConnSettings->ucSSIDLen = 0; -+ -+ /* Misc */ -+ prP2PConnSettings->fgIsScanReqIssued = FALSE; -+ prP2PConnSettings->fgIsServiceDiscoverIssued = FALSE; -+ prP2PConnSettings->fgP2pGroupLimit = FALSE; -+ prP2PConnSettings->ucOperatingChnl = 0; -+ prP2PConnSettings->ucListenChnl = 0; -+ prP2PConnSettings->ucTieBreaker = (UINT_8) (kalRandomNumber() & 0x1); -+ -+ prP2PConnSettings->eFormationPolicy = ENUM_P2P_FORMATION_POLICY_AUTO; -+#if CFG_SUPPORT_CFG_FILE -+ /* prP2PConnSettings->fgIsWPSMode = prWifiVar->ucApWpsMode; */ -+ prAdapter->rWifiVar.prP2pFsmInfo->fgIsWPSMode = prWifiVar->ucApWpsMode; -+#endif -+} /* p2pFuncInitConnectionSettings */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will validate the Rx Assoc Req Frame and then return -+* the status code to AAA to indicate if need to perform following actions -+* when the specified conditions were matched. -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* @param[in] prSwRfb Pointer to SW RFB data structure. -+* @param[out] pu2StatusCode The Status Code of Validation Result -+* -+* @retval TRUE Reply the Assoc Resp -+* @retval FALSE Don't reply the Assoc Resp -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN p2pFuncValidateAssocReq(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, OUT PUINT_16 pu2StatusCode) -+{ -+ BOOLEAN fgReplyAssocResp = TRUE; -+ P_WLAN_ASSOC_REQ_FRAME_T prAssocReqFrame = (P_WLAN_ASSOC_REQ_FRAME_T) NULL; -+ P_STA_RECORD_T prStaRec = (P_STA_RECORD_T) NULL; -+ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; -+#if CFG_SUPPORT_WFD -+ P_WFD_CFG_SETTINGS_T prWfdCfgSettings = (P_WFD_CFG_SETTINGS_T) NULL; -+ P_WFD_ATTRIBUTE_T prWfdAttribute = (P_WFD_ATTRIBUTE_T) NULL; -+ BOOLEAN fgNeedFree = FALSE; -+#endif -+ /* UINT_16 u2AttriListLen = 0; */ -+ UINT_16 u2WfdDevInfo = 0; -+ P_WFD_DEVICE_INFORMATION_IE_T prAttriWfdDevInfo; -+ -+ /* TODO(Kevin): Call P2P functions to check .. -+ 2. Check we can accept connection from thsi peer -+ a. If we are in PROVISION state, only accept the peer we do the GO formation previously. -+ b. If we are in OPERATION state, only accept the other peer when P2P_GROUP_LIMIT is 0. -+ 3. Check Black List here. -+ */ -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prSwRfb != NULL) && (pu2StatusCode != NULL)); -+ -+ *pu2StatusCode = STATUS_CODE_REQ_DECLINED; -+ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); -+ prAssocReqFrame = (P_WLAN_ASSOC_REQ_FRAME_T) prSwRfb->pvHeader; -+ -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); -+ -+ if (prStaRec == NULL) { -+ /* Station record should be ready while RX AUTH frame. */ -+ fgReplyAssocResp = FALSE; -+ ASSERT(FALSE); -+ break; -+ } -+ prStaRec->ucRCPI = prSwRfb->prHifRxHdr->ucRcpi; -+ -+ prStaRec->u2DesiredNonHTRateSet &= prP2pBssInfo->u2OperationalRateSet; -+ prStaRec->ucDesiredPhyTypeSet = prStaRec->ucPhyTypeSet & prP2pBssInfo->ucPhyTypeSet; -+ -+ if (prStaRec->ucDesiredPhyTypeSet == 0) { -+ /* The station only support 11B rate. */ -+ *pu2StatusCode = STATUS_CODE_ASSOC_DENIED_RATE_NOT_SUPPORTED; -+ break; -+ } -+#if CFG_SUPPORT_WFD && 1 -+ /* LOG_FUNC("Skip check WFD IE because some API is not ready\n"); */ -+ if (!prAdapter->rWifiVar.prP2pFsmInfo) { -+ fgReplyAssocResp = FALSE; -+ ASSERT(FALSE); -+ break; -+ } -+ -+ prWfdCfgSettings = &prAdapter->rWifiVar.prP2pFsmInfo->rWfdConfigureSettings; -+ DBGLOG(P2P, INFO, "AssocReq, wfd_en %u wfd_info 0x%x wfd_policy 0x%x wfd_flag 0x%x\n", -+ prWfdCfgSettings->ucWfdEnable, prWfdCfgSettings->u2WfdDevInfo, -+ prWfdCfgSettings->u4WfdPolicy, prWfdCfgSettings->u4WfdFlag); /* Eddie */ -+ if (prWfdCfgSettings->ucWfdEnable) { -+ if (prWfdCfgSettings->u4WfdPolicy & BIT(6)) { -+ /* Rejected all. */ -+ break; -+ } -+ -+ /* fgNeedFree = p2pFuncGetAttriList(prAdapter, */ -+ /* VENDOR_OUI_TYPE_WFD, */ -+ /* (PUINT_8)prAssocReqFrame->aucInfoElem, */ -+ /* (prSwRfb->u2PacketLen - OFFSET_OF(WLAN_ASSOC_REQ_FRAME_T, aucInfoElem)), */ -+ /* (PPUINT_8)&prWfdAttribute, */ -+ /* &u2AttriListLen); */ -+ -+ prAttriWfdDevInfo = (P_WFD_DEVICE_INFORMATION_IE_T) -+ p2pFuncGetSpecAttri(prAdapter, -+ VENDOR_OUI_TYPE_WFD, -+ (PUINT_8) prAssocReqFrame->aucInfoElem, -+ (prSwRfb->u2PacketLen - -+ OFFSET_OF(WLAN_ASSOC_REQ_FRAME_T, aucInfoElem)), -+ WFD_ATTRI_ID_DEV_INFO); -+ -+ if ((prWfdCfgSettings->u4WfdPolicy & BIT(5)) && (prAttriWfdDevInfo != NULL)) { -+ /* Rejected with WFD IE. */ -+ break; -+ } -+ -+ if ((prWfdCfgSettings->u4WfdPolicy & BIT(0)) && (prAttriWfdDevInfo == NULL)) { -+ /* Rejected without WFD IE. */ -+ break; -+ } -+ -+ if (prAttriWfdDevInfo == NULL) { -+ /* -+ * Without WFD IE. -+ * Do nothing. Accept the connection request. -+ */ -+ *pu2StatusCode = STATUS_CODE_SUCCESSFUL; -+ break; -+ } -+ -+ /* prAttriWfdDevInfo = */ -+ /* (P_WFD_DEVICE_INFORMATION_IE_T)p2pFuncGetSpecAttri(prAdapter, */ -+ /* VENDOR_OUI_TYPE_WFD, */ -+ /* (PUINT_8)prWfdAttribute, */ -+ /* u2AttriListLen, */ -+ /* WFD_ATTRI_ID_DEV_INFO); */ -+ /* if (prAttriWfdDevInfo == NULL) { */ -+ /* No such attribute. */ -+ /* break; */ -+ /* } */ -+ -+ WLAN_GET_FIELD_BE16(&prAttriWfdDevInfo->u2WfdDevInfo, &u2WfdDevInfo); -+ DBGLOG(P2P, INFO, "RX Assoc Req WFD Info:0x%x.\n", u2WfdDevInfo); -+ -+ if ((prWfdCfgSettings->u4WfdPolicy & BIT(1)) && ((u2WfdDevInfo & 0x3) == 0x0)) { -+ /* Rejected because of SOURCE. */ -+ break; -+ } -+ -+ if ((prWfdCfgSettings->u4WfdPolicy & BIT(2)) && ((u2WfdDevInfo & 0x3) == 0x1)) { -+ /* Rejected because of Primary Sink. */ -+ break; -+ } -+ -+ if ((prWfdCfgSettings->u4WfdPolicy & BIT(3)) && ((u2WfdDevInfo & 0x3) == 0x2)) { -+ /* Rejected because of Secondary Sink. */ -+ break; -+ } -+ -+ if ((prWfdCfgSettings->u4WfdPolicy & BIT(4)) && ((u2WfdDevInfo & 0x3) == 0x3)) { -+ /* Rejected because of Source & Primary Sink. */ -+ break; -+ } -+ -+ /* Check role */ -+ -+ if ((prWfdCfgSettings->u4WfdFlag & WFD_FLAGS_DEV_INFO_VALID) && -+ ((prWfdCfgSettings->u2WfdDevInfo & BITS(0, 1)) == 0x3)) { -+ /* P_MSG_WFD_CONFIG_SETTINGS_CHANGED_T prMsgWfdCfgUpdate = -+ * (P_MSG_WFD_CONFIG_SETTINGS_CHANGED_T)NULL; */ -+ UINT_16 u2DevInfo = prWfdCfgSettings->u2WfdDevInfo; -+ -+ /* We may change role here if we are dual role */ -+ -+ if ((u2WfdDevInfo & BITS(0, 1)) == 0x00 /* Peer is Source */) { -+ DBGLOG(P2P, INFO, "WFD: Switch role to primary sink\n"); -+ -+ prWfdCfgSettings->u2WfdDevInfo &= ~BITS(0, 1); -+ prWfdCfgSettings->u2WfdDevInfo |= 0x1; -+ -+ /* event to annonce the role is chanaged to P-Sink */ -+ -+ } else if ((u2WfdDevInfo & BITS(0, 1)) == 0x01 /* Peer is P-Sink */) { -+ DBGLOG(P2P, INFO, "WFD: Switch role to source\n"); -+ -+ prWfdCfgSettings->u2WfdDevInfo &= ~BITS(0, 1); -+ /* event to annonce the role is chanaged to Source */ -+ } else { -+ DBGLOG(P2P, INFO, "WFD: Peer role is wrong type(dev 0x%x)\n", -+ (u2DevInfo)); -+ DBGLOG(P2P, INFO, "WFD: Switch role to source\n"); -+ -+ prWfdCfgSettings->u2WfdDevInfo &= ~BITS(0, 1); -+ /* event to annonce the role is chanaged to Source */ -+ } -+ -+ p2pFsmRunEventWfdSettingUpdate(prAdapter, NULL); -+ -+ } /* Dual role p2p->wfd_params->WfdDevInfo */ -+ -+ /* WFD_FLAG_DEV_INFO_VALID */ -+ } -+ /* ucWfdEnable */ -+#endif -+ *pu2StatusCode = STATUS_CODE_SUCCESSFUL; -+ } while (FALSE); -+ -+#if CFG_SUPPORT_WFD -+ if ((prWfdAttribute) && (fgNeedFree)) -+ kalMemFree(prWfdAttribute, VIR_MEM_TYPE, WPS_MAXIMUM_ATTRIBUTES_CACHE_SIZE); -+#endif -+ -+ return fgReplyAssocResp; -+ -+} /* p2pFuncValidateAssocReq */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is used to check the P2P IE -+* -+* -+* @return none -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN p2pFuncParseCheckForP2PInfoElem(IN P_ADAPTER_T prAdapter, IN PUINT_8 pucBuf, OUT PUINT_8 pucOuiType) -+{ -+ UINT_8 aucWfaOui[] = VENDOR_OUI_WFA_SPECIFIC; -+ P_IE_WFA_T prWfaIE = (P_IE_WFA_T) NULL; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (pucBuf != NULL) && (pucOuiType != NULL)); -+ -+ prWfaIE = (P_IE_WFA_T) pucBuf; -+ -+ if (IE_LEN(pucBuf) <= ELEM_MIN_LEN_WFA_OUI_TYPE_SUBTYPE) { -+ break; -+ } else if (prWfaIE->aucOui[0] != aucWfaOui[0] || -+ prWfaIE->aucOui[1] != aucWfaOui[1] || prWfaIE->aucOui[2] != aucWfaOui[2]) { -+ break; -+ } -+ -+ *pucOuiType = prWfaIE->ucOuiType; -+ -+ return TRUE; -+ } while (FALSE); -+ -+ return FALSE; -+} /* p2pFuncParseCheckForP2PInfoElem */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will validate the Rx Probe Request Frame and then return -+* result to BSS to indicate if need to send the corresponding Probe Response -+* Frame if the specified conditions were matched. -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* @param[in] prSwRfb Pointer to SW RFB data structure. -+* @param[out] pu4ControlFlags Control flags for replying the Probe Response -+* -+* @retval TRUE Reply the Probe Response -+* @retval FALSE Don't reply the Probe Response -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN p2pFuncValidateProbeReq(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, OUT PUINT_32 pu4ControlFlags) -+{ -+ BOOLEAN fgIsReplyProbeRsp = FALSE; -+ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; -+ -+ DEBUGFUNC("p2pFuncValidateProbeReq"); -+ DBGLOG(P2P, TRACE, "p2pFuncValidateProbeReq\n"); -+ -+ do { -+ -+ ASSERT_BREAK((prAdapter != NULL) && (prSwRfb != NULL)); -+ -+ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; -+ -+ if (prP2pFsmInfo->u4P2pPacketFilter & PARAM_PACKET_FILTER_PROBE_REQ) { -+ -+ DBGLOG(P2P, TRACE, "report probe req to OS\n"); -+ /* Leave the probe response to p2p_supplicant. */ -+ kalP2PIndicateRxMgmtFrame(prAdapter->prGlueInfo, prSwRfb); -+ } -+ -+ } while (FALSE); -+ -+ return fgIsReplyProbeRsp; -+ -+} /* end of p2pFuncValidateProbeReq() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will validate the Rx Probe Request Frame and then return -+* result to BSS to indicate if need to send the corresponding Probe Response -+* Frame if the specified conditions were matched. -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* @param[in] prSwRfb Pointer to SW RFB data structure. -+* @param[out] pu4ControlFlags Control flags for replying the Probe Response -+* -+* @retval TRUE Reply the Probe Response -+* @retval FALSE Don't reply the Probe Response -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID p2pFuncValidateRxActionFrame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb) -+{ -+ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; -+ -+ DEBUGFUNC("p2pFuncValidateProbeReq"); -+ -+ do { -+ -+ ASSERT_BREAK((prAdapter != NULL) && (prSwRfb != NULL)); -+ -+ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; -+ -+ if (prP2pFsmInfo->u4P2pPacketFilter & PARAM_PACKET_FILTER_ACTION_FRAME) { -+ /* Leave the probe response to p2p_supplicant. */ -+ kalP2PIndicateRxMgmtFrame(prAdapter->prGlueInfo, prSwRfb); -+ } -+ -+ } while (FALSE); -+ -+ return; -+ -+} /* p2pFuncValidateRxMgmtFrame */ -+ -+BOOLEAN p2pFuncIsAPMode(IN P_P2P_FSM_INFO_T prP2pFsmInfo) -+{ -+ if (prP2pFsmInfo) { -+ if (prP2pFsmInfo->fgIsWPSMode == 1) -+ return FALSE; -+ return prP2pFsmInfo->fgIsApMode; -+ } else { -+ return FALSE; -+ } -+} -+ -+/* p2pFuncIsAPMode */ -+ -+VOID -+p2pFuncParseBeaconContent(IN P_ADAPTER_T prAdapter, -+ IN P_BSS_INFO_T prP2pBssInfo, IN PUINT_8 pucIEInfo, IN UINT_32 u4IELen) -+{ -+ PUINT_8 pucIE = (PUINT_8) NULL; -+ UINT_16 u2Offset = 0; -+ P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo = (P_P2P_SPECIFIC_BSS_INFO_T) NULL; -+ BOOLEAN ucNewSecMode = FALSE; -+ BOOLEAN ucOldSecMode = FALSE; -+ UINT_8 ucOuiType; -+ UINT_16 u2SubTypeVersion; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prP2pBssInfo != NULL)); -+ -+ if (u4IELen == 0) -+ break; -+ -+ prP2pSpecificBssInfo = prAdapter->rWifiVar.prP2pSpecificBssInfo; -+ prP2pSpecificBssInfo->u2AttributeLen = 0; -+ -+ ASSERT_BREAK(pucIEInfo != NULL); -+ -+ pucIE = pucIEInfo; -+ -+ ucOldSecMode = kalP2PGetCipher(prAdapter->prGlueInfo); -+ -+ IE_FOR_EACH(pucIE, u4IELen, u2Offset) { -+ switch (IE_ID(pucIE)) { -+ case ELEM_ID_SSID: -+ { -+ /* 0 */ /* V */ /* Done */ -+ /* DBGLOG(P2P, TRACE, ("SSID update\n")); */ -+ /* SSID is saved when start AP/GO */ -+ /* SSID IE set in beacon from supplicant will not always be */ -+ /* the true since hidden SSID case */ -+ /* -+ COPY_SSID(prP2pBssInfo->aucSSID, -+ prP2pBssInfo->ucSSIDLen, -+ SSID_IE(pucIE)->aucSSID, -+ SSID_IE(pucIE)->ucLength); -+ -+ COPY_SSID(prP2pSpecificBssInfo->aucGroupSsid, -+ prP2pSpecificBssInfo->u2GroupSsidLen, -+ SSID_IE(pucIE)->aucSSID, -+ SSID_IE(pucIE)->ucLength); -+ */ -+ } -+ break; -+ case ELEM_ID_SUP_RATES: -+ { -+ /* 1 */ /* V */ /* Done */ -+ DBGLOG(P2P, TRACE, "Support Rate IE\n"); -+ kalMemCopy(prP2pBssInfo->aucAllSupportedRates, -+ SUP_RATES_IE(pucIE)->aucSupportedRates, -+ SUP_RATES_IE(pucIE)->ucLength); -+ -+ prP2pBssInfo->ucAllSupportedRatesLen = SUP_RATES_IE(pucIE)->ucLength; -+ -+ DBGLOG_MEM8(P2P, TRACE, SUP_RATES_IE(pucIE)->aucSupportedRates, -+ SUP_RATES_IE(pucIE)->ucLength); -+ } -+ break; -+ case ELEM_ID_DS_PARAM_SET: -+ { -+ /* 3 */ /* V */ /* Done */ -+ P_P2P_CONNECTION_SETTINGS_T prP2pConnSettings = -+ prAdapter->rWifiVar.prP2PConnSettings; -+ -+ DBGLOG(P2P, TRACE, "DS PARAM IE\n"); -+ -+ ASSERT(prP2pConnSettings->ucOperatingChnl == DS_PARAM_IE(pucIE)->ucCurrChnl); -+ -+ if (prP2pConnSettings->eBand != BAND_2G4) { -+ ASSERT(FALSE); -+ break; -+ } -+ /* prP2pBssInfo->ucPrimaryChannel = DS_PARAM_IE(pucIE)->ucCurrChnl; */ -+ -+ /* prP2pBssInfo->eBand = BAND_2G4; */ -+ } -+ break; -+ case ELEM_ID_TIM: /* 5 */ /* V */ -+ DBGLOG(P2P, TRACE, "TIM IE\n"); -+ TIM_IE(pucIE)->ucDTIMPeriod = prP2pBssInfo->ucDTIMPeriod; -+ break; -+ case ELEM_ID_ERP_INFO: /* 42 */ /* V */ -+ { -+#if 1 -+ /* This IE would dynamic change due to FW detection change is required. */ -+ DBGLOG(P2P, TRACE, "ERP IE will be over write by driver\n"); -+ DBGLOG(P2P, TRACE, " ucERP: %x.\n", ERP_INFO_IE(pucIE)->ucERP); -+ -+#else -+ /* This IE would dynamic change due to FW detection change is required. */ -+ DBGLOG(P2P, TRACE, "ERP IE.\n"); -+ -+ prP2pBssInfo->ucPhyTypeSet |= PHY_TYPE_SET_802_11GN; -+ -+ ASSERT(prP2pBssInfo->eBand == BAND_2G4); -+ -+ prP2pBssInfo->fgObssErpProtectMode = -+ ((ERP_INFO_IE(pucIE)->ucERP & ERP_INFO_USE_PROTECTION) ? TRUE : FALSE); -+ -+ prP2pBssInfo->fgErpProtectMode = -+ ((ERP_INFO_IE(pucIE)->ucERP & -+ (ERP_INFO_USE_PROTECTION | ERP_INFO_NON_ERP_PRESENT)) ? TRUE : FALSE); -+#endif -+ -+ } -+ break; -+ case ELEM_ID_HT_CAP: /* 45 */ /* V */ -+ { -+#if 1 -+ DBGLOG(P2P, TRACE, "HT CAP IE would be overwritten by driver\n"); -+ -+ DBGLOG(P2P, TRACE, -+ "HT Cap Info:%x, AMPDU Param:%x\n", HT_CAP_IE(pucIE)->u2HtCapInfo, -+ HT_CAP_IE(pucIE)->ucAmpduParam); -+ -+ DBGLOG(P2P, TRACE, -+ "HT Extended Cap Info%x,TX Beamforming Cap Info%x,Ant Selection Cap Info%x\n", -+ HT_CAP_IE(pucIE)->u2HtExtendedCap, HT_CAP_IE(pucIE)->u4TxBeamformingCap, -+ HT_CAP_IE(pucIE)->ucAselCap); -+#else -+ prP2pBssInfo->ucPhyTypeSet |= PHY_TYPE_SET_802_11N; -+ -+ /* u2HtCapInfo */ -+ if ((HT_CAP_IE(pucIE)->u2HtCapInfo & -+ (HT_CAP_INFO_SUP_CHNL_WIDTH | HT_CAP_INFO_SHORT_GI_40M | -+ HT_CAP_INFO_DSSS_CCK_IN_40M)) == 0) { -+ prP2pBssInfo->fgAssoc40mBwAllowed = FALSE; -+ } else { -+ prP2pBssInfo->fgAssoc40mBwAllowed = TRUE; -+ } -+ -+ if ((HT_CAP_IE(pucIE)->u2HtCapInfo & -+ (HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M)) == 0) { -+ prAdapter->rWifiVar.rConnSettings.fgRxShortGIDisabled = TRUE; -+ } else { -+ prAdapter->rWifiVar.rConnSettings.fgRxShortGIDisabled = FALSE; -+ } -+ -+ /* ucAmpduParam */ -+ DBGLOG(P2P, TRACE, -+ "AMPDU setting from supplicant:0x%x, & default value:0x%x\n", -+ (UINT_8) HT_CAP_IE(pucIE)->ucAmpduParam, -+ (UINT_8) AMPDU_PARAM_DEFAULT_VAL); -+ -+ /* rSupMcsSet */ -+ /* Can do nothing. the field is default value from other configuration. */ -+ /* HT_CAP_IE(pucIE)->rSupMcsSet; */ -+ -+ /* u2HtExtendedCap */ -+ ASSERT(HT_CAP_IE(pucIE)->u2HtExtendedCap == -+ (HT_EXT_CAP_DEFAULT_VAL & -+ ~(HT_EXT_CAP_PCO | HT_EXT_CAP_PCO_TRANS_TIME_NONE))); -+ -+ /* u4TxBeamformingCap */ -+ ASSERT(HT_CAP_IE(pucIE)->u4TxBeamformingCap == TX_BEAMFORMING_CAP_DEFAULT_VAL); -+ -+ /* ucAselCap */ -+ ASSERT(HT_CAP_IE(pucIE)->ucAselCap == ASEL_CAP_DEFAULT_VAL); -+#endif -+ } -+ break; -+ case ELEM_ID_RSN: /* 48 */ /* V */ -+ { -+ RSN_INFO_T rRsnIe; -+ -+ DBGLOG(P2P, TRACE, "RSN IE\n"); -+ kalP2PSetCipher(prAdapter->prGlueInfo, IW_AUTH_CIPHER_CCMP); -+ ucNewSecMode = TRUE; -+ -+ if (rsnParseRsnIE(prAdapter, RSN_IE(pucIE), &rRsnIe)) { -+ prP2pBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]; -+ prP2pBssInfo->u4RsnSelectedGroupCipher = RSN_CIPHER_SUITE_CCMP; -+ prP2pBssInfo->u4RsnSelectedPairwiseCipher = RSN_CIPHER_SUITE_CCMP; -+ prP2pBssInfo->u4RsnSelectedAKMSuite = RSN_AKM_SUITE_PSK; -+ prP2pBssInfo->u2RsnSelectedCapInfo = rRsnIe.u2RsnCap; -+ } -+ } -+ break; -+ case ELEM_ID_EXTENDED_SUP_RATES: /* 50 */ /* V */ -+ /* Be attention, -+ * ELEM_ID_SUP_RATES should be placed before ELEM_ID_EXTENDED_SUP_RATES. */ -+ DBGLOG(P2P, TRACE, "Ex Support Rate IE\n"); -+ kalMemCopy(&(prP2pBssInfo->aucAllSupportedRates[prP2pBssInfo->ucAllSupportedRatesLen]), -+ EXT_SUP_RATES_IE(pucIE)->aucExtSupportedRates, -+ EXT_SUP_RATES_IE(pucIE)->ucLength); -+ -+ DBGLOG_MEM8(P2P, TRACE, EXT_SUP_RATES_IE(pucIE)->aucExtSupportedRates, -+ EXT_SUP_RATES_IE(pucIE)->ucLength); -+ -+ prP2pBssInfo->ucAllSupportedRatesLen += EXT_SUP_RATES_IE(pucIE)->ucLength; -+ break; -+ case ELEM_ID_HT_OP: -+ { -+ /* 61 */ /* V */ /* TODO: */ -+#if 1 -+ DBGLOG(P2P, TRACE, "HT OP IE would be overwritten by driver\n"); -+ -+ DBGLOG(P2P, TRACE, -+ " Primary Channel: %x, Info1: %x, Info2: %x, Info3: %x\n", -+ HT_OP_IE(pucIE)->ucPrimaryChannel, HT_OP_IE(pucIE)->ucInfo1, -+ HT_OP_IE(pucIE)->u2Info2, HT_OP_IE(pucIE)->u2Info3); -+#else -+ UINT_16 u2Info2 = 0; -+ -+ prP2pBssInfo->ucPhyTypeSet |= PHY_TYPE_SET_802_11N; -+ -+ DBGLOG(P2P, TRACE, "HT OP IE\n"); -+ -+ /* ucPrimaryChannel. */ -+ ASSERT(HT_OP_IE(pucIE)->ucPrimaryChannel == prP2pBssInfo->ucPrimaryChannel); -+ -+ /* ucInfo1 */ -+ prP2pBssInfo->ucHtOpInfo1 = HT_OP_IE(pucIE)->ucInfo1; -+ -+ /* u2Info2 */ -+ u2Info2 = HT_OP_IE(pucIE)->u2Info2; -+ -+ if (u2Info2 & HT_OP_INFO2_NON_GF_HT_STA_PRESENT) { -+ ASSERT(prP2pBssInfo->eGfOperationMode != GF_MODE_NORMAL); -+ u2Info2 &= ~HT_OP_INFO2_NON_GF_HT_STA_PRESENT; -+ } -+ -+ if (u2Info2 & HT_OP_INFO2_OBSS_NON_HT_STA_PRESENT) { -+ prP2pBssInfo->eObssHtProtectMode = HT_PROTECT_MODE_NON_MEMBER; -+ u2Info2 &= ~HT_OP_INFO2_OBSS_NON_HT_STA_PRESENT; -+ } -+ -+ switch (u2Info2 & HT_OP_INFO2_HT_PROTECTION) { -+ case HT_PROTECT_MODE_NON_HT: -+ prP2pBssInfo->eHtProtectMode = HT_PROTECT_MODE_NON_HT; -+ break; -+ case HT_PROTECT_MODE_NON_MEMBER: -+ prP2pBssInfo->eHtProtectMode = HT_PROTECT_MODE_NONE; -+ prP2pBssInfo->eObssHtProtectMode = HT_PROTECT_MODE_NON_MEMBER; -+ break; -+ default: -+ prP2pBssInfo->eHtProtectMode = HT_OP_IE(pucIE)->u2Info2; -+ break; -+ } -+ -+ /* u2Info3 */ -+ prP2pBssInfo->u2HtOpInfo3 = HT_OP_IE(pucIE)->u2Info3; -+ -+ /* aucBasicMcsSet */ -+ DBGLOG_MEM8(P2P, TRACE, HT_OP_IE(pucIE)->aucBasicMcsSet, 16); -+#endif -+ } -+ break; -+ case ELEM_ID_OBSS_SCAN_PARAMS: /* 74 */ /* V */ -+ { -+ DBGLOG(P2P, TRACE, -+ "ELEM_ID_OBSS_SCAN_PARAMS IE would be replaced by driver\n"); -+ } -+ break; -+ case ELEM_ID_EXTENDED_CAP: /* 127 */ /* V */ -+ { -+ DBGLOG(P2P, TRACE, "ELEM_ID_EXTENDED_CAP IE would be replaced by driver\n"); -+ } -+ break; -+ case ELEM_ID_VENDOR: /* 221 */ /* V */ -+ DBGLOG(P2P, TRACE, "Vender Specific IE\n"); -+ if (rsnParseCheckForWFAInfoElem -+ (prAdapter, pucIE, &ucOuiType, &u2SubTypeVersion)) { -+ if ((ucOuiType == VENDOR_OUI_TYPE_WPA) -+ && (u2SubTypeVersion == VERSION_WPA)) { -+ kalP2PSetCipher(prAdapter->prGlueInfo, IW_AUTH_CIPHER_TKIP); -+ ucNewSecMode = TRUE; -+ kalMemCopy(prP2pSpecificBssInfo->aucWpaIeBuffer, pucIE, -+ IE_SIZE(pucIE)); -+ prP2pSpecificBssInfo->u2WpaIeLen = IE_SIZE(pucIE); -+ } else if (ucOuiType == VENDOR_OUI_TYPE_WPS) { -+ kalP2PUpdateWSC_IE(prAdapter->prGlueInfo, 0, pucIE, -+ IE_SIZE(pucIE)); -+ } -+ /* WMM here. */ -+ } else if (p2pFuncParseCheckForP2PInfoElem(prAdapter, pucIE, &ucOuiType)) { -+ /* TODO Store the whole P2P IE & generate later. */ -+ /* Be aware that there may be one or more P2P IE. */ -+ if (ucOuiType == VENDOR_OUI_TYPE_P2P) { -+ kalMemCopy(&prP2pSpecificBssInfo->aucAttributesCache -+ [prP2pSpecificBssInfo->u2AttributeLen], pucIE, -+ IE_SIZE(pucIE)); -+ -+ prP2pSpecificBssInfo->u2AttributeLen += IE_SIZE(pucIE); -+ } else if (ucOuiType == VENDOR_OUI_TYPE_WFD) { -+ -+ kalMemCopy(&prP2pSpecificBssInfo->aucAttributesCache -+ [prP2pSpecificBssInfo->u2AttributeLen], pucIE, -+ IE_SIZE(pucIE)); -+ -+ prP2pSpecificBssInfo->u2AttributeLen += IE_SIZE(pucIE); -+ } -+ } else { -+ -+ kalMemCopy(&prP2pSpecificBssInfo->aucAttributesCache -+ [prP2pSpecificBssInfo->u2AttributeLen], pucIE, -+ IE_SIZE(pucIE)); -+ -+ prP2pSpecificBssInfo->u2AttributeLen += IE_SIZE(pucIE); -+ DBGLOG(P2P, TRACE, "Driver unprocessed Vender Specific IE\n"); -+ ASSERT(FALSE); -+ } -+ -+ /* TODO: Store other Vender IE except for WMM Param. */ -+ break; -+ default: -+ DBGLOG(P2P, TRACE, "Unprocessed element ID:%d\n", IE_ID(pucIE)); -+ break; -+ } -+ } -+ -+ if (!ucNewSecMode && ucOldSecMode) -+ kalP2PSetCipher(prAdapter->prGlueInfo, IW_AUTH_CIPHER_NONE); -+ -+ } while (FALSE); -+ -+} /* p2pFuncParseBeaconContent */ -+ -+P_BSS_DESC_T -+p2pFuncKeepOnConnection(IN P_ADAPTER_T prAdapter, -+ IN P_P2P_CONNECTION_REQ_INFO_T prConnReqInfo, -+ IN P_P2P_CHNL_REQ_INFO_T prChnlReqInfo, IN P_P2P_SCAN_REQ_INFO_T prScanReqInfo) -+{ -+ P_BSS_DESC_T prTargetBss = (P_BSS_DESC_T) NULL; -+ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && -+ (prConnReqInfo != NULL) && (prChnlReqInfo != NULL) && (prScanReqInfo != NULL)); -+ -+ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); -+ -+ if (prP2pBssInfo->eCurrentOPMode != OP_MODE_INFRASTRUCTURE) -+ break; -+ /* Update connection request information. */ -+ ASSERT(prConnReqInfo->fgIsConnRequest == TRUE); -+ -+ /* Find BSS Descriptor first. */ -+ prTargetBss = scanP2pSearchDesc(prAdapter, prP2pBssInfo, prConnReqInfo); -+ -+ if (prTargetBss == NULL) { -+ /* Update scan parameter... to scan target device. */ -+ prScanReqInfo->ucNumChannelList = 1; -+ prScanReqInfo->eScanType = SCAN_TYPE_ACTIVE_SCAN; -+ prScanReqInfo->eChannelSet = SCAN_CHANNEL_FULL; -+ prScanReqInfo->u4BufLength = 0; /* Prevent other P2P ID in IE. */ -+ prScanReqInfo->fgIsAbort = TRUE; -+ } else { -+ prChnlReqInfo->u8Cookie = 0; -+ prChnlReqInfo->ucReqChnlNum = prTargetBss->ucChannelNum; -+ prChnlReqInfo->eBand = prTargetBss->eBand; -+ prChnlReqInfo->eChnlSco = prTargetBss->eSco; -+ prChnlReqInfo->u4MaxInterval = AIS_JOIN_CH_REQUEST_INTERVAL; -+ prChnlReqInfo->eChannelReqType = CHANNEL_REQ_TYPE_GC_JOIN_REQ; -+ } -+ -+ } while (FALSE); -+ -+ return prTargetBss; -+} /* p2pFuncKeepOnConnection */ -+ -+/* Currently Only for ASSOC Response Frame. */ -+VOID p2pFuncStoreAssocRspIEBuffer(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb) -+{ -+ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; -+ P_P2P_JOIN_INFO_T prJoinInfo = (P_P2P_JOIN_INFO_T) NULL; -+ P_WLAN_ASSOC_RSP_FRAME_T prAssocRspFrame = (P_WLAN_ASSOC_RSP_FRAME_T) NULL; -+ INT_16 i2IELen = 0; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prSwRfb != NULL)); -+ -+ prAssocRspFrame = (P_WLAN_ASSOC_RSP_FRAME_T) prSwRfb->pvHeader; -+ -+ if (prAssocRspFrame->u2FrameCtrl != MAC_FRAME_ASSOC_RSP) -+ break; -+ -+ i2IELen = prSwRfb->u2PacketLen - (WLAN_MAC_HEADER_LEN + -+ CAP_INFO_FIELD_LEN + STATUS_CODE_FIELD_LEN + AID_FIELD_LEN); -+ -+ if (i2IELen <= 0) -+ break; -+ -+ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; -+ prJoinInfo = &(prP2pFsmInfo->rJoinInfo); -+ prJoinInfo->u4BufLength = (UINT_32) i2IELen; -+ -+ kalMemCopy(prJoinInfo->aucIEBuf, prAssocRspFrame->aucInfoElem, prJoinInfo->u4BufLength); -+ -+ } while (FALSE); -+ -+} /* p2pFuncStoreAssocRspIEBuffer */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to set Packet Filter. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] pvSetBuffer Pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+* \retval WLAN_STATUS_NOT_SUPPORTED -+* \retval WLAN_STATUS_ADAPTER_NOT_READY -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+p2pFuncMgmtFrameRegister(IN P_ADAPTER_T prAdapter, -+ IN UINT_16 u2FrameType, IN BOOLEAN fgIsRegistered, OUT PUINT_32 pu4P2pPacketFilter) -+{ -+ UINT_32 u4NewPacketFilter = 0; -+ -+ DEBUGFUNC("p2pFuncMgmtFrameRegister"); -+ -+ do { -+ ASSERT_BREAK(prAdapter != NULL); -+ -+ if (pu4P2pPacketFilter) -+ u4NewPacketFilter = *pu4P2pPacketFilter; -+ -+ switch (u2FrameType) { -+ case MAC_FRAME_PROBE_REQ: -+ if (fgIsRegistered) { -+ u4NewPacketFilter |= PARAM_PACKET_FILTER_PROBE_REQ; -+ DBGLOG(P2P, TRACE, "Open packet filer probe request\n"); -+ } else { -+ u4NewPacketFilter &= ~PARAM_PACKET_FILTER_PROBE_REQ; -+ DBGLOG(P2P, TRACE, "Close packet filer probe request\n"); -+ } -+ break; -+ case MAC_FRAME_ACTION: -+ if (fgIsRegistered) { -+ u4NewPacketFilter |= PARAM_PACKET_FILTER_ACTION_FRAME; -+ DBGLOG(P2P, TRACE, "Open packet filer action frame.\n"); -+ } else { -+ u4NewPacketFilter &= ~PARAM_PACKET_FILTER_ACTION_FRAME; -+ DBGLOG(P2P, TRACE, "Close packet filer action frame.\n"); -+ } -+ break; -+ default: -+ DBGLOG(P2P, TRACE, "Ask frog to add code for mgmt:%x\n", u2FrameType); -+ break; -+ } -+ -+ if (pu4P2pPacketFilter) -+ *pu4P2pPacketFilter = u4NewPacketFilter; -+ -+ /* u4NewPacketFilter |= prAdapter->u4OsPacketFilter; */ -+ -+ prAdapter->u4OsPacketFilter &= ~PARAM_PACKET_FILTER_P2P_MASK; -+ prAdapter->u4OsPacketFilter |= u4NewPacketFilter; -+ -+ DBGLOG(P2P, TRACE, "P2P Set PACKET filter:0x%x\n", prAdapter->u4OsPacketFilter); -+ -+ wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SET_RX_FILTER, -+ TRUE, -+ FALSE, -+ FALSE, -+ nicCmdEventSetCommon, -+ nicOidCmdTimeoutCommon, -+ sizeof(UINT_32), -+ (PUINT_8) &prAdapter->u4OsPacketFilter, -+ &u4NewPacketFilter, sizeof(u4NewPacketFilter) -+ ); -+ -+ } while (FALSE); -+ -+} /* p2pFuncMgmtFrameRegister */ -+ -+VOID p2pFuncUpdateMgmtFrameRegister(IN P_ADAPTER_T prAdapter, IN UINT_32 u4OsFilter) -+{ -+ -+ do { -+ -+ prAdapter->rWifiVar.prP2pFsmInfo->u4P2pPacketFilter = u4OsFilter; -+ -+ if ((prAdapter->u4OsPacketFilter & PARAM_PACKET_FILTER_P2P_MASK) ^ u4OsFilter) { -+ -+ prAdapter->u4OsPacketFilter &= ~PARAM_PACKET_FILTER_P2P_MASK; -+ -+ prAdapter->u4OsPacketFilter |= (u4OsFilter & PARAM_PACKET_FILTER_P2P_MASK); -+ -+ wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SET_RX_FILTER, -+ TRUE, -+ FALSE, -+ FALSE, -+ nicCmdEventSetCommon, -+ nicOidCmdTimeoutCommon, -+ sizeof(UINT_32), -+ (PUINT_8) &prAdapter->u4OsPacketFilter, &u4OsFilter, sizeof(u4OsFilter) -+ ); -+ DBGLOG(P2P, TRACE, "P2P Set PACKET filter:0x%x\n", prAdapter->u4OsPacketFilter); -+ } -+ -+ } while (FALSE); -+ -+} /* p2pFuncUpdateMgmtFrameRegister */ -+ -+VOID p2pFuncGetStationInfo(IN P_ADAPTER_T prAdapter, IN PUINT_8 pucMacAddr, OUT P_P2P_STATION_INFO_T prStaInfo) -+{ -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (pucMacAddr != NULL) && (prStaInfo != NULL)); -+ -+ prStaInfo->u4InactiveTime = 0; -+ prStaInfo->u4RxBytes = 0; -+ prStaInfo->u4TxBytes = 0; -+ prStaInfo->u4RxPackets = 0; -+ prStaInfo->u4TxPackets = 0; -+ /* TODO: */ -+ -+ } while (FALSE); -+ -+} /* p2pFuncGetStationInfo */ -+ -+BOOLEAN -+p2pFuncGetAttriList(IN P_ADAPTER_T prAdapter, -+ IN UINT_8 ucOuiType, -+ IN PUINT_8 pucIE, IN UINT_16 u2IELength, OUT PPUINT_8 ppucAttriList, OUT PUINT_16 pu2AttriListLen) -+{ -+ BOOLEAN fgIsAllocMem = FALSE; -+ UINT_8 aucWfaOui[] = VENDOR_OUI_WFA_SPECIFIC; -+ UINT_16 u2Offset = 0; -+ P_IE_P2P_T prIe = (P_IE_P2P_T) NULL; -+ PUINT_8 pucAttriListStart = (PUINT_8) NULL; -+ UINT_16 u2AttriListLen = 0, u2BufferSize = 0; -+ BOOLEAN fgBackupAttributes = FALSE; -+ UINT_16 u2CopyLen; -+ -+ ASSERT(prAdapter); -+ ASSERT(pucIE); -+ ASSERT(ppucAttriList); -+ ASSERT(pu2AttriListLen); -+ -+ if (ppucAttriList) -+ *ppucAttriList = NULL; -+ if (pu2AttriListLen) -+ *pu2AttriListLen = 0; -+ -+ if (ucOuiType == VENDOR_OUI_TYPE_WPS) { -+ aucWfaOui[0] = 0x00; -+ aucWfaOui[1] = 0x50; -+ aucWfaOui[2] = 0xF2; -+ } else if ((ucOuiType != VENDOR_OUI_TYPE_P2P) -+#if CFG_SUPPORT_WFD -+ && (ucOuiType != VENDOR_OUI_TYPE_WFD) -+#endif -+ ) { -+ DBGLOG(P2P, INFO, "Not supported OUI Type to parsing 0x%x\n", ucOuiType); -+ return fgIsAllocMem; -+ } -+ -+ IE_FOR_EACH(pucIE, u2IELength, u2Offset) { -+ if (ELEM_ID_VENDOR != IE_ID(pucIE)) -+ continue; -+ -+ prIe = (P_IE_P2P_T) pucIE; -+ -+ if (prIe->ucLength <= P2P_OUI_TYPE_LEN) -+ continue; -+ -+ if ((prIe->aucOui[0] == aucWfaOui[0]) && -+ (prIe->aucOui[1] == aucWfaOui[1]) && -+ (prIe->aucOui[2] == aucWfaOui[2]) && (ucOuiType == prIe->ucOuiType)) { -+ -+ if (!pucAttriListStart) { -+ pucAttriListStart = &prIe->aucP2PAttributes[0]; -+ if (prIe->ucLength > P2P_OUI_TYPE_LEN) -+ u2AttriListLen = (UINT_16) (prIe->ucLength - P2P_OUI_TYPE_LEN); -+ else -+ ASSERT(FALSE); -+ continue; -+ } -+/* More than 2 attributes. */ -+ -+ if (FALSE == fgBackupAttributes) { -+ P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo = -+ prAdapter->rWifiVar.prP2pSpecificBssInfo; -+ -+ fgBackupAttributes = TRUE; -+ if (ucOuiType == VENDOR_OUI_TYPE_P2P) { -+ kalMemCopy(&prP2pSpecificBssInfo->aucAttributesCache[0], -+ pucAttriListStart, u2AttriListLen); -+ -+ pucAttriListStart = -+ &prP2pSpecificBssInfo->aucAttributesCache[0]; -+ -+ u2BufferSize = P2P_MAXIMUM_ATTRIBUTE_LEN; -+ } else if (ucOuiType == VENDOR_OUI_TYPE_WPS) { -+ kalMemCopy(&prP2pSpecificBssInfo->aucWscAttributesCache -+ [0], pucAttriListStart, u2AttriListLen); -+ pucAttriListStart = -+ &prP2pSpecificBssInfo->aucWscAttributesCache[0]; -+ -+ u2BufferSize = WPS_MAXIMUM_ATTRIBUTES_CACHE_SIZE; -+ } -+#if CFG_SUPPORT_WFD -+ else if (ucOuiType == VENDOR_OUI_TYPE_WFD) { -+ PUINT_8 pucTmpBuf = (PUINT_8) NULL; -+ -+ pucTmpBuf = (PUINT_8) -+ kalMemAlloc(WPS_MAXIMUM_ATTRIBUTES_CACHE_SIZE, -+ VIR_MEM_TYPE); -+ -+ if (pucTmpBuf != NULL) { -+ fgIsAllocMem = TRUE; -+ } else { -+ /* Can't alloca memory for WFD IE relocate. */ -+ ASSERT(FALSE); -+ break; -+ } -+ -+ kalMemCopy(pucTmpBuf, -+ pucAttriListStart, u2AttriListLen); -+ -+ pucAttriListStart = pucTmpBuf; -+ -+ u2BufferSize = WPS_MAXIMUM_ATTRIBUTES_CACHE_SIZE; -+ } -+#endif -+ else -+ fgBackupAttributes = FALSE; -+ } -+ -+ u2CopyLen = (UINT_16) (prIe->ucLength - P2P_OUI_TYPE_LEN); -+ -+ if ((u2AttriListLen + u2CopyLen) > u2BufferSize) { -+ u2CopyLen = u2BufferSize - u2AttriListLen; -+ DBGLOG(P2P, WARN, -+ "Length of received P2P attributes > maximum cache size.\n"); -+ } -+ -+ if (u2CopyLen) { -+ kalMemCopy((PUINT_8) -+ ((ULONG) pucAttriListStart + -+ (UINT_32) u2AttriListLen), -+ &prIe->aucP2PAttributes[0], u2CopyLen); -+ -+ u2AttriListLen += u2CopyLen; -+ } -+ } /* prIe->aucOui */ -+ } /* IE_FOR_EACH */ -+ -+ if (pucAttriListStart) { -+ PUINT_8 pucAttribute = pucAttriListStart; -+ -+ DBGLOG(P2P, LOUD, "Checking Attribute Length.\n"); -+ if (ucOuiType == VENDOR_OUI_TYPE_P2P) { -+ P2P_ATTRI_FOR_EACH(pucAttribute, u2AttriListLen, u2Offset); -+ } else if (ucOuiType == VENDOR_OUI_TYPE_WFD) { -+ /* Do nothing */ -+ } else if (ucOuiType == VENDOR_OUI_TYPE_WPS) { -+ /* Big Endian: WSC, WFD. */ -+ WSC_ATTRI_FOR_EACH(pucAttribute, u2AttriListLen, u2Offset) { -+ DBGLOG(P2P, LOUD, "Attribute ID:%d, Length:%d.\n", -+ WSC_ATTRI_ID(pucAttribute), WSC_ATTRI_LEN(pucAttribute)); -+ } -+ } else { -+ } -+ -+ ASSERT(u2Offset == u2AttriListLen); -+ -+ if (ppucAttriList) -+ *ppucAttriList = pucAttriListStart; -+ if (pu2AttriListLen) -+ *pu2AttriListLen = u2AttriListLen; -+ -+ } else { -+ if (ppucAttriList) -+ *ppucAttriList = (PUINT_8) NULL; -+ if (pu2AttriListLen) -+ *pu2AttriListLen = 0; -+ } -+ -+ return fgIsAllocMem; -+} /* p2pFuncGetAttriList */ -+ -+P_MSDU_INFO_T p2pFuncProcessP2pProbeRsp(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMgmtTxMsdu) -+{ -+ P_MSDU_INFO_T prRetMsduInfo = prMgmtTxMsdu; -+ P_WLAN_PROBE_RSP_FRAME_T prProbeRspFrame = (P_WLAN_PROBE_RSP_FRAME_T) NULL; -+ PUINT_8 pucIEBuf = (PUINT_8) NULL; -+ UINT_16 u2Offset = 0, u2IELength = 0, u2ProbeRspHdrLen = 0; -+ BOOLEAN fgIsP2PIE = FALSE, fgIsWSCIE = FALSE; -+ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; -+ UINT_16 u2EstimateSize = 0, u2EstimatedExtraIELen = 0; -+ UINT_32 u4IeArraySize = 0, u4Idx = 0; -+ UINT_8 ucOuiType = 0; -+ UINT_16 u2SubTypeVersion = 0; -+ -+ BOOLEAN fgIsPureAP = prAdapter->rWifiVar.prP2pFsmInfo->fgIsApMode; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prMgmtTxMsdu != NULL)); -+ -+ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); -+ -+ /* 3 Make sure this is probe response frame. */ -+ prProbeRspFrame = (P_WLAN_PROBE_RSP_FRAME_T) ((ULONG) prMgmtTxMsdu->prPacket + MAC_TX_RESERVED_FIELD); -+ ASSERT_BREAK((prProbeRspFrame->u2FrameCtrl & MASK_FRAME_TYPE) == MAC_FRAME_PROBE_RSP); -+ -+ if (prP2pBssInfo->u2BeaconInterval) -+ prProbeRspFrame->u2BeaconInterval = prP2pBssInfo->u2BeaconInterval; -+ -+ /* 3 Get the importent P2P IE. */ -+ u2ProbeRspHdrLen = -+ (WLAN_MAC_MGMT_HEADER_LEN + TIMESTAMP_FIELD_LEN + BEACON_INTERVAL_FIELD_LEN + CAP_INFO_FIELD_LEN); -+ pucIEBuf = prProbeRspFrame->aucInfoElem; -+ u2IELength = prMgmtTxMsdu->u2FrameLength - u2ProbeRspHdrLen; -+ -+#if CFG_SUPPORT_WFD -+ prAdapter->prGlueInfo->prP2PInfo->u2VenderIELen = 0; -+#endif -+ -+ IE_FOR_EACH(pucIEBuf, u2IELength, u2Offset) { -+ switch (IE_ID(pucIEBuf)) { -+ case ELEM_ID_SSID: -+ { -+ -+ COPY_SSID(prP2pBssInfo->aucSSID, -+ prP2pBssInfo->ucSSIDLen, -+ SSID_IE(pucIEBuf)->aucSSID, SSID_IE(pucIEBuf)->ucLength); -+ } -+ break; -+ case ELEM_ID_VENDOR: -+#if !CFG_SUPPORT_WFD -+ if (rsnParseCheckForWFAInfoElem(prAdapter, pucIEBuf, &ucOuiType, &u2SubTypeVersion)) { -+ if (ucOuiType == VENDOR_OUI_TYPE_WPS) { -+ kalP2PUpdateWSC_IE(prAdapter->prGlueInfo, 2, pucIEBuf, -+ IE_SIZE(pucIEBuf)); -+ fgIsWSCIE = TRUE; -+ } -+ -+ } else if (p2pFuncParseCheckForP2PInfoElem(prAdapter, pucIEBuf, &ucOuiType)) { -+ if (ucOuiType == VENDOR_OUI_TYPE_P2P) { -+ /* 2 Note(frog): I use WSC IE buffer for Probe Request to -+ * store the P2P IE for Probe Response. */ -+ kalP2PUpdateWSC_IE(prAdapter->prGlueInfo, 1, pucIEBuf, -+ IE_SIZE(pucIEBuf)); -+ fgIsP2PIE = TRUE; -+ } -+ -+ } else { -+ if ((prAdapter->prGlueInfo->prP2PInfo->u2VenderIELen + -+ IE_SIZE(pucIEBuf)) < 512) { -+ kalMemCopy(prAdapter->prGlueInfo->prP2PInfo->aucVenderIE, -+ pucIEBuf, IE_SIZE(pucIEBuf)); -+ prAdapter->prGlueInfo->prP2PInfo->u2VenderIELen += -+ IE_SIZE(pucIEBuf); -+ } -+ } -+#else -+ /* Eddie May be WFD */ -+ if (rsnParseCheckForWFAInfoElem -+ (prAdapter, pucIEBuf, &ucOuiType, &u2SubTypeVersion)) { -+ if (ucOuiType == VENDOR_OUI_TYPE_WMM) -+ break; -+ -+ } -+ if ((prAdapter->prGlueInfo->prP2PInfo->u2VenderIELen + IE_SIZE(pucIEBuf)) < -+ 1024) { -+ kalMemCopy(prAdapter->prGlueInfo->prP2PInfo->aucVenderIE + -+ prAdapter->prGlueInfo->prP2PInfo->u2VenderIELen, pucIEBuf, -+ IE_SIZE(pucIEBuf)); -+ prAdapter->prGlueInfo->prP2PInfo->u2VenderIELen += IE_SIZE(pucIEBuf); -+ } -+#endif -+ break; -+ default: -+ break; -+ } -+ -+ } -+ -+ /* 3 Check the total size & current frame. */ -+ u2EstimateSize = WLAN_MAC_MGMT_HEADER_LEN + -+ TIMESTAMP_FIELD_LEN + -+ BEACON_INTERVAL_FIELD_LEN + -+ CAP_INFO_FIELD_LEN + -+ (ELEM_HDR_LEN + ELEM_MAX_LEN_SSID) + -+ (ELEM_HDR_LEN + ELEM_MAX_LEN_SUP_RATES) + (ELEM_HDR_LEN + ELEM_MAX_LEN_DS_PARAMETER_SET); -+ -+ u2EstimatedExtraIELen = 0; -+ -+ u4IeArraySize = sizeof(txProbeRspIETable) / sizeof(APPEND_VAR_IE_ENTRY_T); -+ for (u4Idx = 0; u4Idx < u4IeArraySize; u4Idx++) { -+ if (txProbeRspIETable[u4Idx].u2EstimatedFixedIELen) { -+ u2EstimatedExtraIELen += txProbeRspIETable[u4Idx].u2EstimatedFixedIELen; -+ } -+ -+ else { -+ ASSERT(txProbeRspIETable[u4Idx].pfnCalculateVariableIELen); -+ -+ u2EstimatedExtraIELen += -+ (UINT_16) (txProbeRspIETable[u4Idx].pfnCalculateVariableIELen -+ (prAdapter, NETWORK_TYPE_P2P_INDEX, NULL)); -+ } -+ -+ } -+ -+ if (fgIsWSCIE) -+ u2EstimatedExtraIELen += kalP2PCalWSC_IELen(prAdapter->prGlueInfo, 2); -+ -+ if (fgIsP2PIE) { -+ u2EstimatedExtraIELen += kalP2PCalWSC_IELen(prAdapter->prGlueInfo, 1); -+ u2EstimatedExtraIELen += p2pFuncCalculateP2P_IE_NoA(prAdapter, 0, NULL); -+ } -+#if CFG_SUPPORT_WFD -+ u2EstimatedExtraIELen += prAdapter->prGlueInfo->prP2PInfo->u2VenderIELen; -+#endif -+ -+ u2EstimateSize += u2EstimatedExtraIELen; -+ if (u2EstimateSize > (prRetMsduInfo->u2FrameLength)) { -+ prRetMsduInfo = cnmMgtPktAlloc(prAdapter, u2EstimateSize); -+ -+ if (prRetMsduInfo == NULL) { -+ DBGLOG(P2P, WARN, "No packet for sending new probe response, use original one\n"); -+ prRetMsduInfo = prMgmtTxMsdu; -+ break; -+ } -+ -+ prRetMsduInfo->ucNetworkType = NETWORK_TYPE_P2P_INDEX; -+ } -+ /* 3 Compose / Re-compose probe response frame. */ -+ bssComposeBeaconProbeRespFrameHeaderAndFF((PUINT_8) -+ ((ULONG) (prRetMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD), -+ prProbeRspFrame->aucDestAddr, prProbeRspFrame->aucSrcAddr, -+ prProbeRspFrame->aucBSSID, prProbeRspFrame->u2BeaconInterval, -+ fgIsPureAP ? prP2pBssInfo-> -+ u2CapInfo : prProbeRspFrame->u2CapInfo); -+ -+ prRetMsduInfo->u2FrameLength = -+ (WLAN_MAC_MGMT_HEADER_LEN + TIMESTAMP_FIELD_LEN + BEACON_INTERVAL_FIELD_LEN + CAP_INFO_FIELD_LEN); -+ -+ bssBuildBeaconProbeRespFrameCommonIEs(prRetMsduInfo, prP2pBssInfo, prProbeRspFrame->aucDestAddr); -+ -+ for (u4Idx = 0; u4Idx < u4IeArraySize; u4Idx++) { -+ if (txProbeRspIETable[u4Idx].pfnAppendIE) -+ txProbeRspIETable[u4Idx].pfnAppendIE(prAdapter, prRetMsduInfo); -+ -+ } -+ -+ if (fgIsWSCIE) { -+ kalP2PGenWSC_IE(prAdapter->prGlueInfo, -+ 2, -+ (PUINT_8) ((ULONG) prRetMsduInfo->prPacket + -+ (UINT_32) prRetMsduInfo->u2FrameLength)); -+ -+ prRetMsduInfo->u2FrameLength += (UINT_16) kalP2PCalWSC_IELen(prAdapter->prGlueInfo, 2); -+ } -+ -+ if (fgIsP2PIE) { -+ kalP2PGenWSC_IE(prAdapter->prGlueInfo, -+ 1, -+ (PUINT_8) ((ULONG) prRetMsduInfo->prPacket + -+ (UINT_32) prRetMsduInfo->u2FrameLength)); -+ -+ prRetMsduInfo->u2FrameLength += (UINT_16) kalP2PCalWSC_IELen(prAdapter->prGlueInfo, 1); -+ p2pFuncGenerateP2P_IE_NoA(prAdapter, prRetMsduInfo); -+ } -+#if CFG_SUPPORT_WFD -+ if (prAdapter->prGlueInfo->prP2PInfo->u2VenderIELen > 0) { -+ kalMemCopy((PUINT_8) ((ULONG) prRetMsduInfo->prPacket + (UINT_32) prRetMsduInfo->u2FrameLength), -+ prAdapter->prGlueInfo->prP2PInfo->aucVenderIE, -+ prAdapter->prGlueInfo->prP2PInfo->u2VenderIELen); -+ prRetMsduInfo->u2FrameLength += (UINT_16) prAdapter->prGlueInfo->prP2PInfo->u2VenderIELen; -+ } -+#endif -+ -+ } while (FALSE); -+ -+ if (prRetMsduInfo != prMgmtTxMsdu) -+ cnmMgtPktFree(prAdapter, prMgmtTxMsdu); -+ -+ return prRetMsduInfo; -+} /* p2pFuncProcessP2pProbeRsp */ -+ -+#if 0 /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0) */ -+UINT_32 -+p2pFuncCalculateExtra_IELenForBeacon(IN P_ADAPTER_T prAdapter, -+ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec) -+{ -+ -+ P_P2P_SPECIFIC_BSS_INFO_T prP2pSpeBssInfo = (P_P2P_SPECIFIC_BSS_INFO_T) NULL; -+ UINT_32 u4IELen = 0; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (eNetTypeIndex == NETWORK_TYPE_P2P_INDEX)); -+ -+ if (p2pFuncIsAPMode(prAdapter->rWifiVar.prP2pFsmInfo)) -+ break; -+ -+ prP2pSpeBssInfo = prAdapter->rWifiVar.prP2pSpecificBssInfo; -+ -+ u4IELen = prP2pSpeBssInfo->u2IELenForBCN; -+ -+ } while (FALSE); -+ -+ return u4IELen; -+} /* p2pFuncCalculateP2p_IELenForBeacon */ -+ -+VOID p2pFuncGenerateExtra_IEForBeacon(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo) -+{ -+ P_P2P_SPECIFIC_BSS_INFO_T prP2pSpeBssInfo = (P_P2P_SPECIFIC_BSS_INFO_T) NULL; -+ PUINT_8 pucIEBuf = (PUINT_8) NULL; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prMsduInfo != NULL)); -+ -+ prP2pSpeBssInfo = prAdapter->rWifiVar.prP2pSpecificBssInfo; -+ -+ if (p2pFuncIsAPMode(prAdapter->rWifiVar.prP2pFsmInfo)) -+ break; -+ -+ pucIEBuf = (PUINT_8) ((UINT_32) prMsduInfo->prPacket + (UINT_32) prMsduInfo->u2FrameLength); -+ -+ kalMemCopy(pucIEBuf, prP2pSpeBssInfo->aucBeaconIECache, prP2pSpeBssInfo->u2IELenForBCN); -+ -+ prMsduInfo->u2FrameLength += prP2pSpeBssInfo->u2IELenForBCN; -+ -+ } while (FALSE); -+ -+} /* p2pFuncGenerateExtra_IEForBeacon */ -+ -+#else -+UINT_32 -+p2pFuncCalculateP2p_IELenForBeacon(IN P_ADAPTER_T prAdapter, -+ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec) -+{ -+ P_P2P_SPECIFIC_BSS_INFO_T prP2pSpeBssInfo = (P_P2P_SPECIFIC_BSS_INFO_T) NULL; -+ UINT_32 u4IELen = 0; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (eNetTypeIndex == NETWORK_TYPE_P2P_INDEX)); -+ -+ if (!prAdapter->fgIsP2PRegistered) -+ break; -+ -+ if (p2pFuncIsAPMode(prAdapter->rWifiVar.prP2pFsmInfo)) -+ break; -+ -+ prP2pSpeBssInfo = prAdapter->rWifiVar.prP2pSpecificBssInfo; -+ -+ u4IELen = prP2pSpeBssInfo->u2AttributeLen; -+ -+ } while (FALSE); -+ -+ return u4IELen; -+} /* p2pFuncCalculateP2p_IELenForBeacon */ -+ -+VOID p2pFuncGenerateP2p_IEForBeacon(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo) -+{ -+ P_P2P_SPECIFIC_BSS_INFO_T prP2pSpeBssInfo = (P_P2P_SPECIFIC_BSS_INFO_T) NULL; -+ PUINT_8 pucIEBuf = (PUINT_8) NULL; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prMsduInfo != NULL)); -+ -+ if (!prAdapter->fgIsP2PRegistered) -+ break; -+ -+ prP2pSpeBssInfo = prAdapter->rWifiVar.prP2pSpecificBssInfo; -+ -+ if (p2pFuncIsAPMode(prAdapter->rWifiVar.prP2pFsmInfo)) -+ break; -+ -+ pucIEBuf = (PUINT_8) ((ULONG) prMsduInfo->prPacket + (UINT_32) prMsduInfo->u2FrameLength); -+ -+ kalMemCopy(pucIEBuf, prP2pSpeBssInfo->aucAttributesCache, prP2pSpeBssInfo->u2AttributeLen); -+ -+ prMsduInfo->u2FrameLength += prP2pSpeBssInfo->u2AttributeLen; -+ -+ } while (FALSE); -+ -+} /* p2pFuncGenerateP2p_IEForBeacon */ -+ -+UINT_32 -+p2pFuncCalculateWSC_IELenForBeacon(IN P_ADAPTER_T prAdapter, -+ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec) -+{ -+ if (eNetTypeIndex != NETWORK_TYPE_P2P_INDEX) -+ return 0; -+ -+ return kalP2PCalWSC_IELen(prAdapter->prGlueInfo, 0); -+} /* p2pFuncCalculateP2p_IELenForBeacon */ -+ -+VOID p2pFuncGenerateWSC_IEForBeacon(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo) -+{ -+ PUINT_8 pucBuffer; -+ UINT_16 u2IELen = 0; -+ -+ ASSERT(prAdapter); -+ ASSERT(prMsduInfo); -+ -+ if (prMsduInfo->ucNetworkType != NETWORK_TYPE_P2P_INDEX) -+ return; -+ -+ u2IELen = (UINT_16) kalP2PCalWSC_IELen(prAdapter->prGlueInfo, 0); -+ -+ pucBuffer = (PUINT_8) ((ULONG) prMsduInfo->prPacket + (UINT_32) prMsduInfo->u2FrameLength); -+ -+ ASSERT(pucBuffer); -+ -+ /* TODO: Check P2P FSM State. */ -+ kalP2PGenWSC_IE(prAdapter->prGlueInfo, 0, pucBuffer); -+ -+ prMsduInfo->u2FrameLength += u2IELen; -+ -+} /* p2pFuncGenerateP2p_IEForBeacon */ -+ -+#endif -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is used to calculate P2P IE length for Beacon frame. -+* -+* @param[in] eNetTypeIndex Specify which network -+* @param[in] prStaRec Pointer to the STA_RECORD_T -+* -+* @return The length of P2P IE added -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT_32 -+p2pFuncCalculateP2p_IELenForAssocRsp(IN P_ADAPTER_T prAdapter, -+ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec) -+{ -+ -+ if (eNetTypeIndex != NETWORK_TYPE_P2P_INDEX) -+ return 0; -+ -+ return p2pFuncCalculateP2P_IELen(prAdapter, -+ eNetTypeIndex, -+ prStaRec, -+ txAssocRspAttributesTable, -+ sizeof(txAssocRspAttributesTable) / sizeof(APPEND_VAR_ATTRI_ENTRY_T)); -+ -+} /* p2pFuncCalculateP2p_IELenForAssocRsp */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is used to generate P2P IE for Beacon frame. -+* -+* @param[in] prMsduInfo Pointer to the composed MSDU_INFO_T. -+* -+* @return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID p2pFuncGenerateP2p_IEForAssocRsp(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo) -+{ -+ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; -+ P_STA_RECORD_T prStaRec = (P_STA_RECORD_T) NULL; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prMsduInfo != NULL)); -+ -+ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; -+ -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); -+ if (!prStaRec) -+ break; -+ -+ if (IS_STA_P2P_TYPE(prStaRec)) { -+ DBGLOG(P2P, TRACE, "Generate NULL P2P IE for Assoc Rsp.\n"); -+ -+ p2pFuncGenerateP2P_IE(prAdapter, -+ TRUE, -+ &prMsduInfo->u2FrameLength, -+ prMsduInfo->prPacket, -+ 1500, -+ txAssocRspAttributesTable, -+ sizeof(txAssocRspAttributesTable) / sizeof(APPEND_VAR_ATTRI_ENTRY_T)); -+ } else { -+ -+ DBGLOG(P2P, TRACE, "Legacy device, no P2P IE.\n"); -+ } -+ -+ } while (FALSE); -+ -+ return; -+ -+} /* p2pFuncGenerateP2p_IEForAssocRsp */ -+ -+UINT_32 -+p2pFuncCalculateWSC_IELenForAssocRsp(IN P_ADAPTER_T prAdapter, -+ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec) -+{ -+ DBGLOG(P2P, TRACE, "p2pFuncCalculateWSC_IELenForAssocRsp\n"); -+ if (eNetTypeIndex != NETWORK_TYPE_P2P_INDEX) -+ return 0; -+ -+ return kalP2PCalWSC_IELen(prAdapter->prGlueInfo, 0); -+} /* p2pFuncCalculateP2p_IELenForAssocRsp */ -+ -+VOID p2pFuncGenerateWSC_IEForAssocRsp(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo) -+{ -+ PUINT_8 pucBuffer; -+ UINT_16 u2IELen = 0; -+ -+ ASSERT(prAdapter); -+ ASSERT(prMsduInfo); -+ -+ if (prMsduInfo->ucNetworkType != NETWORK_TYPE_P2P_INDEX) -+ return; -+ DBGLOG(P2P, TRACE, "p2pFuncGenerateWSC_IEForAssocRsp\n"); -+ -+ u2IELen = (UINT_16) kalP2PCalWSC_IELen(prAdapter->prGlueInfo, 0); -+ -+ pucBuffer = (PUINT_8) ((ULONG) prMsduInfo->prPacket + (UINT_32) prMsduInfo->u2FrameLength); -+ -+ ASSERT(pucBuffer); -+ -+ /* TODO: Check P2P FSM State. */ -+ kalP2PGenWSC_IE(prAdapter->prGlueInfo, 0, pucBuffer); -+ -+ prMsduInfo->u2FrameLength += u2IELen; -+ -+} -+ -+/* p2pFuncGenerateP2p_IEForAssocRsp */ -+ -+UINT_32 -+p2pFuncCalculateP2P_IELen(IN P_ADAPTER_T prAdapter, -+ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, -+ IN P_STA_RECORD_T prStaRec, -+ IN APPEND_VAR_ATTRI_ENTRY_T arAppendAttriTable[], IN UINT_32 u4AttriTableSize) -+{ -+ -+ UINT_32 u4OverallAttriLen, u4Dummy; -+ UINT_16 u2EstimatedFixedAttriLen; -+ UINT_32 i; -+ -+ /* Overall length of all Attributes */ -+ u4OverallAttriLen = 0; -+ -+ for (i = 0; i < u4AttriTableSize; i++) { -+ u2EstimatedFixedAttriLen = arAppendAttriTable[i].u2EstimatedFixedAttriLen; -+ -+ if (u2EstimatedFixedAttriLen) { -+ u4OverallAttriLen += u2EstimatedFixedAttriLen; -+ } else { -+ ASSERT(arAppendAttriTable[i].pfnCalculateVariableAttriLen); -+ -+ u4OverallAttriLen += arAppendAttriTable[i].pfnCalculateVariableAttriLen(prAdapter, prStaRec); -+ } -+ } -+ -+ u4Dummy = u4OverallAttriLen; -+ u4OverallAttriLen += P2P_IE_OUI_HDR; -+ -+ for (; (u4Dummy > P2P_MAXIMUM_ATTRIBUTE_LEN);) { -+ u4OverallAttriLen += P2P_IE_OUI_HDR; -+ u4Dummy -= P2P_MAXIMUM_ATTRIBUTE_LEN; -+ } -+ -+ return u4OverallAttriLen; -+} /* p2pFuncCalculateP2P_IELen */ -+ -+VOID -+p2pFuncGenerateP2P_IE(IN P_ADAPTER_T prAdapter, -+ IN BOOLEAN fgIsAssocFrame, -+ IN PUINT_16 pu2Offset, -+ IN PUINT_8 pucBuf, -+ IN UINT_16 u2BufSize, -+ IN APPEND_VAR_ATTRI_ENTRY_T arAppendAttriTable[], IN UINT_32 u4AttriTableSize) -+{ -+ PUINT_8 pucBuffer = (PUINT_8) NULL; -+ P_IE_P2P_T prIeP2P = (P_IE_P2P_T) NULL; -+ UINT_32 u4OverallAttriLen; -+ UINT_32 u4AttriLen; -+ UINT_8 aucWfaOui[] = VENDOR_OUI_WFA_SPECIFIC; -+ UINT_8 aucTempBuffer[P2P_MAXIMUM_ATTRIBUTE_LEN]; -+ UINT_32 i; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (pucBuf != NULL)); -+ -+ pucBuffer = (PUINT_8) ((ULONG) pucBuf + (*pu2Offset)); -+ -+ ASSERT_BREAK(pucBuffer != NULL); -+ -+ /* Check buffer length is still enough. */ -+ ASSERT_BREAK((u2BufSize - (*pu2Offset)) >= P2P_IE_OUI_HDR); -+ -+ prIeP2P = (P_IE_P2P_T) pucBuffer; -+ -+ prIeP2P->ucId = ELEM_ID_P2P; -+ -+ prIeP2P->aucOui[0] = aucWfaOui[0]; -+ prIeP2P->aucOui[1] = aucWfaOui[1]; -+ prIeP2P->aucOui[2] = aucWfaOui[2]; -+ prIeP2P->ucOuiType = VENDOR_OUI_TYPE_P2P; -+ -+ (*pu2Offset) += P2P_IE_OUI_HDR; -+ -+ /* Overall length of all Attributes */ -+ u4OverallAttriLen = 0; -+ -+ for (i = 0; i < u4AttriTableSize; i++) { -+ -+ if (arAppendAttriTable[i].pfnAppendAttri) { -+ u4AttriLen = -+ arAppendAttriTable[i].pfnAppendAttri(prAdapter, fgIsAssocFrame, pu2Offset, pucBuf, -+ u2BufSize); -+ -+ u4OverallAttriLen += u4AttriLen; -+ -+ if (u4OverallAttriLen > P2P_MAXIMUM_ATTRIBUTE_LEN) { -+ u4OverallAttriLen -= P2P_MAXIMUM_ATTRIBUTE_LEN; -+ -+ prIeP2P->ucLength = (VENDOR_OUI_TYPE_LEN + P2P_MAXIMUM_ATTRIBUTE_LEN); -+ -+ pucBuffer = -+ (PUINT_8) ((ULONG) prIeP2P + -+ (VENDOR_OUI_TYPE_LEN + P2P_MAXIMUM_ATTRIBUTE_LEN)); -+ -+ prIeP2P = (P_IE_P2P_T) ((ULONG) prIeP2P + -+ (ELEM_HDR_LEN + -+ (VENDOR_OUI_TYPE_LEN + P2P_MAXIMUM_ATTRIBUTE_LEN))); -+ -+ kalMemCopy(aucTempBuffer, pucBuffer, u4OverallAttriLen); -+ -+ prIeP2P->ucId = ELEM_ID_P2P; -+ -+ prIeP2P->aucOui[0] = aucWfaOui[0]; -+ prIeP2P->aucOui[1] = aucWfaOui[1]; -+ prIeP2P->aucOui[2] = aucWfaOui[2]; -+ prIeP2P->ucOuiType = VENDOR_OUI_TYPE_P2P; -+ -+ kalMemCopy(prIeP2P->aucP2PAttributes, aucTempBuffer, u4OverallAttriLen); -+ (*pu2Offset) += P2P_IE_OUI_HDR; -+ } -+ -+ } -+ -+ } -+ -+ prIeP2P->ucLength = (UINT_8) (VENDOR_OUI_TYPE_LEN + u4OverallAttriLen); -+ -+ } while (FALSE); -+ -+} /* p2pFuncGenerateP2P_IE */ -+ -+UINT_32 -+p2pFuncAppendAttriStatusForAssocRsp(IN P_ADAPTER_T prAdapter, -+ IN BOOLEAN fgIsAssocFrame, -+ IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize) -+{ -+ PUINT_8 pucBuffer; -+ P_P2P_ATTRI_STATUS_T prAttriStatus; -+ P_P2P_CONNECTION_SETTINGS_T prP2pConnSettings = (P_P2P_CONNECTION_SETTINGS_T) NULL; -+ UINT_32 u4AttriLen = 0; -+ -+ ASSERT(prAdapter); -+ ASSERT(pucBuf); -+ -+ prP2pConnSettings = prAdapter->rWifiVar.prP2PConnSettings; -+ -+ if (fgIsAssocFrame) -+ return u4AttriLen; -+ /* TODO: For assoc request P2P IE check in driver & return status in P2P IE. */ -+ -+ pucBuffer = (PUINT_8) ((ULONG) pucBuf + (UINT_32) (*pu2Offset)); -+ -+ ASSERT(pucBuffer); -+ prAttriStatus = (P_P2P_ATTRI_STATUS_T) pucBuffer; -+ -+ ASSERT(u2BufSize >= ((*pu2Offset) + (UINT_16) u4AttriLen)); -+ -+ prAttriStatus->ucId = P2P_ATTRI_ID_STATUS; -+ WLAN_SET_FIELD_16(&prAttriStatus->u2Length, P2P_ATTRI_MAX_LEN_STATUS); -+ -+ prAttriStatus->ucStatusCode = P2P_STATUS_FAIL_PREVIOUS_PROTOCOL_ERR; -+ -+ u4AttriLen = (P2P_ATTRI_HDR_LEN + P2P_ATTRI_MAX_LEN_STATUS); -+ -+ (*pu2Offset) += (UINT_16) u4AttriLen; -+ -+ return u4AttriLen; -+} /* p2pFuncAppendAttriStatusForAssocRsp */ -+ -+UINT_32 -+p2pFuncAppendAttriExtListenTiming(IN P_ADAPTER_T prAdapter, -+ IN BOOLEAN fgIsAssocFrame, -+ IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize) -+{ -+ UINT_32 u4AttriLen = 0; -+ P_P2P_ATTRI_EXT_LISTEN_TIMING_T prP2pExtListenTiming = (P_P2P_ATTRI_EXT_LISTEN_TIMING_T) NULL; -+ P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo = (P_P2P_SPECIFIC_BSS_INFO_T) NULL; -+ PUINT_8 pucBuffer = NULL; -+ -+ ASSERT(prAdapter); -+ ASSERT(pucBuf); -+ -+ if (fgIsAssocFrame) -+ return u4AttriLen; -+ /* TODO: For extend listen timing. */ -+ -+ prP2pSpecificBssInfo = prAdapter->rWifiVar.prP2pSpecificBssInfo; -+ -+ u4AttriLen = (P2P_ATTRI_HDR_LEN + P2P_ATTRI_MAX_LEN_EXT_LISTEN_TIMING); -+ -+ ASSERT(u2BufSize >= ((*pu2Offset) + (UINT_16) u4AttriLen)); -+ -+ pucBuffer = (PUINT_8) ((ULONG) pucBuf + (UINT_32) (*pu2Offset)); -+ -+ ASSERT(pucBuffer); -+ -+ prP2pExtListenTiming = (P_P2P_ATTRI_EXT_LISTEN_TIMING_T) pucBuffer; -+ -+ prP2pExtListenTiming->ucId = P2P_ATTRI_ID_EXT_LISTEN_TIMING; -+ WLAN_SET_FIELD_16(&prP2pExtListenTiming->u2Length, P2P_ATTRI_MAX_LEN_EXT_LISTEN_TIMING); -+ WLAN_SET_FIELD_16(&prP2pExtListenTiming->u2AvailInterval, prP2pSpecificBssInfo->u2AvailabilityInterval); -+ WLAN_SET_FIELD_16(&prP2pExtListenTiming->u2AvailPeriod, prP2pSpecificBssInfo->u2AvailabilityPeriod); -+ -+ (*pu2Offset) += (UINT_16) u4AttriLen; -+ -+ return u4AttriLen; -+} /* p2pFuncAppendAttriExtListenTiming */ -+ -+P_IE_HDR_T -+p2pFuncGetSpecIE(IN P_ADAPTER_T prAdapter, -+ IN PUINT_8 pucIEBuf, IN UINT_16 u2BufferLen, IN UINT_8 ucElemID, IN PBOOLEAN pfgIsMore) -+{ -+ P_IE_HDR_T prTargetIE = (P_IE_HDR_T) NULL; -+ PUINT_8 pucIE = (PUINT_8) NULL; -+ UINT_16 u2Offset = 0; -+ -+ if (pfgIsMore) -+ *pfgIsMore = FALSE; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) -+ && (pucIEBuf != NULL)); -+ -+ pucIE = pucIEBuf; -+ -+ IE_FOR_EACH(pucIE, u2BufferLen, u2Offset) { -+ if (IE_ID(pucIE) == ucElemID) { -+ if ((prTargetIE) && (pfgIsMore)) { -+ -+ *pfgIsMore = TRUE; -+ break; -+ } -+ prTargetIE = (P_IE_HDR_T) pucIE; -+ -+ if (pfgIsMore == NULL) -+ break; -+ -+ } -+ } -+ -+ } while (FALSE); -+ -+ return prTargetIE; -+} /* p2pFuncGetSpecIE */ -+ -+P_ATTRIBUTE_HDR_T -+p2pFuncGetSpecAttri(IN P_ADAPTER_T prAdapter, -+ IN UINT_8 ucOuiType, IN PUINT_8 pucIEBuf, IN UINT_16 u2BufferLen, IN UINT_16 u2AttriID) -+{ -+ P_IE_P2P_T prP2pIE = (P_IE_P2P_T) NULL; -+ P_ATTRIBUTE_HDR_T prTargetAttri = (P_ATTRIBUTE_HDR_T) NULL; -+ BOOLEAN fgIsMore = FALSE; -+ PUINT_8 pucIE = (PUINT_8) NULL, pucAttri = (PUINT_8) NULL; -+ UINT_16 u2OffsetAttri = 0; -+ UINT_16 u2BufferLenLeft = 0; -+ UINT_8 aucWfaOui[] = VENDOR_OUI_WFA_SPECIFIC; -+ -+ DBGLOG(P2P, INFO, "Check AssocReq Oui type %u attri %u for len %u\n", ucOuiType, u2AttriID, u2BufferLen); -+ -+ ASSERT(prAdapter); -+ ASSERT(pucIEBuf); -+ -+ u2BufferLenLeft = u2BufferLen; -+ pucIE = pucIEBuf; -+ do { -+ fgIsMore = FALSE; -+ prP2pIE = (P_IE_P2P_T) p2pFuncGetSpecIE(prAdapter, -+ pucIE, u2BufferLenLeft, ELEM_ID_VENDOR, &fgIsMore); -+ if (prP2pIE == NULL) -+ continue; -+ -+ ASSERT((ULONG) prP2pIE >= (ULONG) pucIE); -+ -+ u2BufferLenLeft = u2BufferLen - (UINT_16) (((ULONG) prP2pIE) - ((ULONG) pucIEBuf)); -+ -+ DBGLOG(P2P, INFO, "Find vendor id %u len %u oui %u more %u LeftLen %u\n", -+ IE_ID(prP2pIE), IE_LEN(prP2pIE), prP2pIE->ucOuiType, fgIsMore, -+ u2BufferLenLeft); -+ -+ if ((IE_LEN(prP2pIE) > P2P_OUI_TYPE_LEN) && (prP2pIE->ucOuiType == ucOuiType)) { -+ switch (ucOuiType) { -+ case VENDOR_OUI_TYPE_WPS: -+ aucWfaOui[0] = 0x00; -+ aucWfaOui[1] = 0x50; -+ aucWfaOui[2] = 0xF2; -+ break; -+ case VENDOR_OUI_TYPE_P2P: -+ break; -+ case VENDOR_OUI_TYPE_WPA: -+ case VENDOR_OUI_TYPE_WMM: -+ case VENDOR_OUI_TYPE_WFD: -+ default: -+ break; -+ } -+ -+ if ((prP2pIE->aucOui[0] != aucWfaOui[0]) -+ || (prP2pIE->aucOui[1] != aucWfaOui[1]) -+ || (prP2pIE->aucOui[2] != aucWfaOui[2])) -+ continue; -+ -+ u2OffsetAttri = 0; -+ pucAttri = prP2pIE->aucP2PAttributes; -+ -+ if (ucOuiType == VENDOR_OUI_TYPE_WPS) { -+ WSC_ATTRI_FOR_EACH(pucAttri, -+ (IE_LEN(prP2pIE) - P2P_OUI_TYPE_LEN), u2OffsetAttri) { -+ /* LOG_FUNC("WSC: attri id=%u len=%u\n", -+ * WSC_ATTRI_ID(pucAttri), -+ * WSC_ATTRI_LEN(pucAttri)); */ -+ if (WSC_ATTRI_ID(pucAttri) == u2AttriID) { -+ prTargetAttri = -+ (P_ATTRIBUTE_HDR_T) pucAttri; -+ break; -+ } -+ } -+ -+ } else if (ucOuiType == VENDOR_OUI_TYPE_P2P) { -+ P2P_ATTRI_FOR_EACH(pucAttri, -+ (IE_LEN(prP2pIE) - P2P_OUI_TYPE_LEN), u2OffsetAttri) { -+ /* LOG_FUNC("P2P: attri id=%u len=%u\n", -+ * ATTRI_ID(pucAttri), ATTRI_LEN(pucAttri)); */ -+ if (ATTRI_ID(pucAttri) == (UINT_8) u2AttriID) { -+ prTargetAttri = (P_ATTRIBUTE_HDR_T) pucAttri; -+ break; -+ } -+ } -+ } -+#if CFG_SUPPORT_WFD -+ else if (ucOuiType == VENDOR_OUI_TYPE_WFD) { -+ WFD_ATTRI_FOR_EACH(pucAttri, -+ (IE_LEN(prP2pIE) - P2P_OUI_TYPE_LEN), u2OffsetAttri) { -+ /* DBGLOG(P2P, INFO, ("WFD: attri id=%u -+ * len=%u\n",WFD_ATTRI_ID(pucAttri), -+ * WFD_ATTRI_LEN(pucAttri))); */ -+ if (ATTRI_ID(pucAttri) == (UINT_8) u2AttriID) { -+ prTargetAttri = -+ (P_ATTRIBUTE_HDR_T) pucAttri; -+ break; -+ } -+ } -+ } -+#endif -+ /* Do nothing */ -+ /* Possible or else. */ -+ } /* ucOuiType */ -+ /* P2P_OUI_TYPE_LEN */ -+ pucIE = (PUINT_8) (((ULONG) prP2pIE) + IE_SIZE(prP2pIE)); -+ /* prP2pIE */ -+ } while (prP2pIE && fgIsMore && u2BufferLenLeft); -+ -+ return prTargetAttri; -+} -+ -+/* p2pFuncGetSpecAttri */ -+ -+WLAN_STATUS -+p2pFuncGenerateBeaconProbeRsp(IN P_ADAPTER_T prAdapter, -+ IN P_BSS_INFO_T prBssInfo, IN P_MSDU_INFO_T prMsduInfo, IN BOOLEAN fgIsProbeRsp) -+{ -+ WLAN_STATUS rWlanStatus = WLAN_STATUS_SUCCESS; -+ P_WLAN_BEACON_FRAME_T prBcnFrame = (P_WLAN_BEACON_FRAME_T) NULL; -+/* P_APPEND_VAR_IE_ENTRY_T prAppendIeTable = (P_APPEND_VAR_IE_ENTRY_T)NULL; */ -+ -+ do { -+ -+ ASSERT_BREAK((prAdapter != NULL) && (prBssInfo != NULL) && (prMsduInfo != NULL)); -+ -+/* txBcnIETable */ -+ -+/* txProbeRspIETable */ -+ -+ prBcnFrame = (P_WLAN_BEACON_FRAME_T) prMsduInfo->prPacket; -+ -+ return nicUpdateBeaconIETemplate(prAdapter, -+ IE_UPD_METHOD_UPDATE_ALL, -+ NETWORK_TYPE_P2P_INDEX, -+ prBssInfo->u2CapInfo, -+ (PUINT_8) prBcnFrame->aucInfoElem, -+ prMsduInfo->u2FrameLength - OFFSET_OF(WLAN_BEACON_FRAME_T, -+ aucInfoElem)); -+ -+ } while (FALSE); -+ -+ return rWlanStatus; -+} /* p2pFuncGenerateBeaconProbeRsp */ -+ -+WLAN_STATUS -+p2pFuncComposeBeaconProbeRspTemplate(IN P_ADAPTER_T prAdapter, -+ IN PUINT_8 pucBcnBuffer, -+ IN UINT_32 u4BcnBufLen, -+ IN BOOLEAN fgIsProbeRsp, -+ IN P_P2P_PROBE_RSP_UPDATE_INFO_T prP2pProbeRspInfo, IN BOOLEAN fgSynToFW) -+{ -+ WLAN_STATUS rWlanStatus = WLAN_STATUS_SUCCESS; -+ P_MSDU_INFO_T prMsduInfo = (P_MSDU_INFO_T) NULL; -+ P_WLAN_MAC_HEADER_T prWlanBcnFrame = (P_WLAN_MAC_HEADER_T) NULL; -+ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; -+ -+ PUINT_8 pucBuffer = (PUINT_8) NULL; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (pucBcnBuffer != NULL)); -+ -+ prWlanBcnFrame = (P_WLAN_MAC_HEADER_T) pucBcnBuffer; -+ -+ if ((prWlanBcnFrame->u2FrameCtrl != MAC_FRAME_BEACON) && (!fgIsProbeRsp)) { -+ rWlanStatus = WLAN_STATUS_INVALID_DATA; -+ break; -+ } -+ -+ else if (prWlanBcnFrame->u2FrameCtrl != MAC_FRAME_PROBE_RSP) { -+ rWlanStatus = WLAN_STATUS_INVALID_DATA; -+ break; -+ } -+ -+ if (fgIsProbeRsp) { -+ ASSERT_BREAK(prP2pProbeRspInfo != NULL); -+ -+ if (prP2pProbeRspInfo->prProbeRspMsduTemplate) -+ cnmMgtPktFree(prAdapter, prP2pProbeRspInfo->prProbeRspMsduTemplate); -+ -+ prP2pProbeRspInfo->prProbeRspMsduTemplate = cnmMgtPktAlloc(prAdapter, u4BcnBufLen); -+ -+ prMsduInfo = prP2pProbeRspInfo->prProbeRspMsduTemplate; -+ -+ prMsduInfo->eSrc = TX_PACKET_MGMT; -+ prMsduInfo->ucStaRecIndex = 0xFF; -+ prMsduInfo->ucNetworkType = NETWORK_TYPE_P2P_INDEX; -+ -+ } else { -+ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); -+ prMsduInfo = prP2pBssInfo->prBeacon; -+ -+ if (prMsduInfo == NULL) { -+ rWlanStatus = WLAN_STATUS_FAILURE; -+ break; -+ } -+ -+ if (u4BcnBufLen > (OFFSET_OF(WLAN_BEACON_FRAME_T, aucInfoElem[0]) + MAX_IE_LENGTH)) { -+ /* Unexpected error, buffer overflow. */ -+ ASSERT(FALSE); -+ break; -+ } -+ -+ } -+ -+ pucBuffer = (PUINT_8) ((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD); -+ -+ kalMemCopy(pucBuffer, pucBcnBuffer, u4BcnBufLen); -+ -+ prMsduInfo->fgIs802_11 = TRUE; -+ prMsduInfo->u2FrameLength = (UINT_16) u4BcnBufLen; -+ -+ if (fgSynToFW && prP2pBssInfo) -+ rWlanStatus = p2pFuncGenerateBeaconProbeRsp(prAdapter, prP2pBssInfo, prMsduInfo, fgIsProbeRsp); -+ -+ } while (FALSE); -+ -+ return rWlanStatus; -+ -+} /* p2pFuncComposeBeaconTemplate */ -+ -+#if CFG_SUPPORT_WFD -+WLAN_STATUS wfdAdjustResource(IN P_ADAPTER_T prAdapter, IN BOOLEAN fgEnable) -+{ -+#if 1 -+ /* The API shall be called in tx_thread */ -+ P_QUE_MGT_T prQM = &prAdapter->rQM; -+ -+ DBGLOG(P2P, INFO, "wfdAdjustResource %d\n", fgEnable); -+ if (fgEnable) { -+ prQM->au4MinReservedTcResource[TC2_INDEX] = QM_GUARANTEED_TC2_RESOURCE; -+ if (QM_GUARANTEED_TC0_RESOURCE > 2) { -+ prQM->au4GuaranteedTcResource[TC0_INDEX] = QM_GUARANTEED_TC0_RESOURCE - 2; -+ prQM->au4GuaranteedTcResource[TC2_INDEX] += 2; -+ } -+ if (QM_GUARANTEED_TC1_RESOURCE > 2) { -+ prQM->au4GuaranteedTcResource[TC1_INDEX] = QM_GUARANTEED_TC1_RESOURCE - 2; -+ prQM->au4GuaranteedTcResource[TC2_INDEX] += 2; -+ } -+ } else { -+ prQM->au4MinReservedTcResource[TC2_INDEX] = QM_MIN_RESERVED_TC2_RESOURCE; -+ prQM->au4GuaranteedTcResource[TC0_INDEX] = QM_GUARANTEED_TC0_RESOURCE; -+ prQM->au4GuaranteedTcResource[TC1_INDEX] = QM_GUARANTEED_TC1_RESOURCE; -+ prQM->au4GuaranteedTcResource[TC2_INDEX] = QM_GUARANTEED_TC2_RESOURCE; -+ } -+#endif -+ return WLAN_STATUS_SUCCESS; -+} -+ -+WLAN_STATUS wfdAdjustThread(IN P_ADAPTER_T prAdapter, IN BOOLEAN fgEnable) -+{ -+#define WFD_TX_THREAD_PRIORITY 70 -+ DBGLOG(P2P, INFO, "wfdAdjustResource %d\n", fgEnable); -+ if (prAdapter->prGlueInfo->main_thread != NULL) { -+ if (fgEnable) { -+#ifdef LINUX -+ /* TODO the change schedule API shall be provided by OS glue layer */ -+ /* Or the API shall be put in os glue layer */ -+ struct sched_param param = {.sched_priority = WFD_TX_THREAD_PRIORITY }; -+ -+ sched_setscheduler(prAdapter->prGlueInfo->main_thread, SCHED_RR, ¶m); -+#endif -+ } else { -+#ifdef LINUX -+ /* TODO the change schedule API shall be provided by OS glue layer */ -+ struct sched_param param = {.sched_priority = 0 }; -+ -+ sched_setscheduler(prAdapter->prGlueInfo->main_thread, SCHED_NORMAL, ¶m); -+#endif -+ } -+ } else { -+ -+ DBGLOG(P2P, WARN, "main_thread is null, please check if the wlanRemove is called in advance\n"); -+ } -+ return WLAN_STATUS_SUCCESS; -+} -+ -+#endif /* CFG_SUPPORT_WFD */ -+ -+WLAN_STATUS wfdChangeMediaState(IN P_ADAPTER_T prAdapter, -+ IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx, ENUM_PARAM_MEDIA_STATE_T eConnectionState) -+{ -+#if CFG_SUPPORT_WFD -+ P_WFD_CFG_SETTINGS_T prWfdCfgSettings = (P_WFD_CFG_SETTINGS_T) NULL; -+ -+ if (prAdapter->fgIsP2PRegistered == FALSE) -+ return WLAN_STATUS_SUCCESS; -+ prWfdCfgSettings = &prAdapter->rWifiVar.prP2pFsmInfo->rWfdConfigureSettings; -+ -+ if ((prWfdCfgSettings->ucWfdEnable) && ((prWfdCfgSettings->u4WfdFlag & WFD_FLAGS_DEV_INFO_VALID))) { -+ -+ if (prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX].eConnectionState == -+ PARAM_MEDIA_STATE_CONNECTED) { -+ wfdAdjustResource(prAdapter, TRUE); -+ wfdAdjustThread(prAdapter, TRUE); -+ } else { -+ wfdAdjustResource(prAdapter, FALSE); -+ wfdAdjustThread(prAdapter, FALSE); -+ } -+ -+ } -+#endif -+ return WLAN_STATUS_SUCCESS; -+} -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_ie.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_ie.c -new file mode 100644 -index 000000000000..991861f73608 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_ie.c -@@ -0,0 +1,612 @@ -+#include "p2p_precomp.h" -+ -+#if CFG_SUPPORT_WFD -+#if CFG_SUPPORT_WFD_COMPOSE_IE -+#if 0 -+APPEND_VAR_ATTRI_ENTRY_T txProbeRspWFDAttributesTable[] = { -+ {(WFD_ATTRI_HDR_LEN + WFD_ATTRI_MAX_LEN_DEV_INFO), NULL, wfdFuncAppendAttriDevInfo} /* 0 */ -+ , {(WFD_ATTRI_HDR_LEN + WFD_ATTRI_MAX_LEN_ASSOC_BSSID), NULL, wfdFuncAppendAttriAssocBssid} /* 1 */ -+ , {(WFD_ATTRI_HDR_LEN + WFD_ATTRI_MAX_LEN_COUPLED_SINK_INFO), NULL, wfdFuncAppendAttriCoupledSinkInfo} /* 6 */ -+ , {(WFD_ATTRI_HDR_LEN + WFD_ATTRI_MAX_LEN_EXT_CAPABILITY), NULL, wfdFuncAppendAttriExtCapability} /* 7 */ -+ , {0, wfdFuncCalculateAttriLenSessionInfo, wfdFuncAppendAttriSessionInfo} /* 9 */ -+}; -+ -+APPEND_VAR_ATTRI_ENTRY_T txBeaconWFDAttributesTable[] = { -+ {(WFD_ATTRI_HDR_LEN + WFD_ATTRI_MAX_LEN_DEV_INFO), NULL, wfdFuncAppendAttriDevInfo} /* 0 */ -+ , {(WFD_ATTRI_HDR_LEN + WFD_ATTRI_MAX_LEN_ASSOC_BSSID), NULL, wfdFuncAppendAttriAssocBssid} /* 1 */ -+ , {(WFD_ATTRI_HDR_LEN + WFD_ATTRI_MAX_LEN_COUPLED_SINK_INFO), NULL, wfdFuncAppendAttriCoupledSinkInfo} /* 6 */ -+}; -+ -+APPEND_VAR_ATTRI_ENTRY_T txAssocReqWFDAttributesTable[] = { -+ {(WFD_ATTRI_HDR_LEN + WFD_ATTRI_MAX_LEN_DEV_INFO), NULL, wfdFuncAppendAttriDevInfo} /* 0 */ -+ , {(WFD_ATTRI_HDR_LEN + WFD_ATTRI_MAX_LEN_ASSOC_BSSID), NULL, wfdFuncAppendAttriAssocBssid} /* 1 */ -+ , {(WFD_ATTRI_HDR_LEN + WFD_ATTRI_MAX_LEN_COUPLED_SINK_INFO), NULL, wfdFuncAppendAttriCoupledSinkInfo} /* 6 */ -+}; -+#endif -+ -+APPEND_VAR_ATTRI_ENTRY_T txAssocRspWFDAttributesTable[] = { -+ {(WFD_ATTRI_HDR_LEN + WFD_ATTRI_MAX_LEN_DEV_INFO), NULL, wfdFuncAppendAttriDevInfo} /* 0 */ -+ , {(WFD_ATTRI_HDR_LEN + WFD_ATTRI_MAX_LEN_ASSOC_BSSID), NULL, wfdFuncAppendAttriAssocBssid} /* 1 */ -+ , {(WFD_ATTRI_HDR_LEN + WFD_ATTRI_MAX_LEN_COUPLED_SINK_INFO), NULL, wfdFuncAppendAttriCoupledSinkInfo} /* 6 */ -+ , {0, wfdFuncCalculateAttriLenSessionInfo, wfdFuncAppendAttriSessionInfo} /* 9 */ -+ -+}; -+ -+#endif -+ -+UINT_32 -+p2pCalculate_IEForAssocReq(IN P_ADAPTER_T prAdapter, -+ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec) -+{ -+ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; -+ P_P2P_CONNECTION_REQ_INFO_T prConnReqInfo = (P_P2P_CONNECTION_REQ_INFO_T) NULL; -+ UINT_32 u4RetValue = 0; -+ -+ do { -+ ASSERT_BREAK((eNetTypeIndex == NETWORK_TYPE_P2P_INDEX) && (prAdapter != NULL)); -+ -+ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; -+ -+ prConnReqInfo = &(prP2pFsmInfo->rConnReqInfo); -+ -+ u4RetValue = prConnReqInfo->u4BufLength; -+ -+ /* ADD HT Capability */ -+ u4RetValue += (ELEM_HDR_LEN + ELEM_MAX_LEN_HT_CAP); -+ -+ /* ADD WMM Information Element */ -+ u4RetValue += (ELEM_HDR_LEN + ELEM_MAX_LEN_WMM_INFO); -+ -+ } while (FALSE); -+ -+ return u4RetValue; -+} /* p2pCalculate_IEForAssocReq */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is used to generate P2P IE for Beacon frame. -+* -+* @param[in] prMsduInfo Pointer to the composed MSDU_INFO_T. -+* -+* @return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID p2pGenerate_IEForAssocReq(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo) -+{ -+ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; -+ P_P2P_CONNECTION_REQ_INFO_T prConnReqInfo = (P_P2P_CONNECTION_REQ_INFO_T) NULL; -+ PUINT_8 pucIEBuf = (PUINT_8) NULL; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prMsduInfo != NULL)); -+ -+ prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; -+ -+ prConnReqInfo = &(prP2pFsmInfo->rConnReqInfo); -+ -+ pucIEBuf = (PUINT_8) ((ULONG) prMsduInfo->prPacket + (UINT_32) prMsduInfo->u2FrameLength); -+ -+ kalMemCopy(pucIEBuf, prConnReqInfo->aucIEBuf, prConnReqInfo->u4BufLength); -+ -+ prMsduInfo->u2FrameLength += prConnReqInfo->u4BufLength; -+ -+ rlmReqGenerateHtCapIE(prAdapter, prMsduInfo); -+ mqmGenerateWmmInfoIE(prAdapter, prMsduInfo); -+ -+ } while (FALSE); -+ -+ return; -+ -+} /* p2pGenerate_IEForAssocReq */ -+ -+UINT_32 -+wfdFuncAppendAttriDevInfo(IN P_ADAPTER_T prAdapter, -+ IN BOOLEAN fgIsAssocFrame, IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize) -+{ -+ UINT_32 u4AttriLen = 0; -+ PUINT_8 pucBuffer = NULL; -+ P_WFD_DEVICE_INFORMATION_IE_T prWfdDevInfo = (P_WFD_DEVICE_INFORMATION_IE_T) NULL; -+ P_WFD_CFG_SETTINGS_T prWfdCfgSettings = (P_WFD_CFG_SETTINGS_T) NULL; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (pucBuf != NULL) && (pu2Offset != NULL)); -+ -+ prWfdCfgSettings = &(prAdapter->rWifiVar.prP2pFsmInfo->rWfdConfigureSettings); -+ -+ ASSERT_BREAK((prWfdCfgSettings != NULL)); -+ -+ if ((prWfdCfgSettings->ucWfdEnable == 0) || -+ ((prWfdCfgSettings->u4WfdFlag & WFD_FLAGS_DEV_INFO_VALID) == 0)) { -+ break; -+ } -+ -+ pucBuffer = (PUINT_8) ((ULONG) pucBuf + (UINT_32) (*pu2Offset)); -+ -+ ASSERT_BREAK(pucBuffer != NULL); -+ -+ prWfdDevInfo = (P_WFD_DEVICE_INFORMATION_IE_T) pucBuffer; -+ -+ prWfdDevInfo->ucElemID = WFD_ATTRI_ID_DEV_INFO; -+ -+ WLAN_SET_FIELD_BE16(&prWfdDevInfo->u2WfdDevInfo, prWfdCfgSettings->u2WfdDevInfo); -+ -+ WLAN_SET_FIELD_BE16(&prWfdDevInfo->u2SessionMgmtCtrlPort, prWfdCfgSettings->u2WfdControlPort); -+ -+ WLAN_SET_FIELD_BE16(&prWfdDevInfo->u2WfdDevMaxSpeed, prWfdCfgSettings->u2WfdMaximumTp); -+ -+ WLAN_SET_FIELD_BE16(&prWfdDevInfo->u2Length, WFD_ATTRI_MAX_LEN_DEV_INFO); -+ -+ u4AttriLen = WFD_ATTRI_MAX_LEN_DEV_INFO + WFD_ATTRI_HDR_LEN; -+ -+ } while (FALSE); -+ -+ (*pu2Offset) += (UINT_16) u4AttriLen; -+ -+ return u4AttriLen; -+} -+ -+/* wfdFuncAppendAttriDevInfo */ -+ -+UINT_32 -+wfdFuncAppendAttriAssocBssid(IN P_ADAPTER_T prAdapter, -+ IN BOOLEAN fgIsAssocFrame, IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize) -+{ -+ UINT_32 u4AttriLen = 0; -+ PUINT_8 pucBuffer = NULL; -+ P_WFD_ASSOCIATED_BSSID_IE_T prWfdAssocBssid = (P_WFD_ASSOCIATED_BSSID_IE_T) NULL; -+ P_WFD_CFG_SETTINGS_T prWfdCfgSettings = (P_WFD_CFG_SETTINGS_T) NULL; -+ P_BSS_INFO_T prAisBssInfo = (P_BSS_INFO_T) NULL; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (pucBuf != NULL) && (pu2Offset != NULL)); -+ -+ prWfdCfgSettings = &(prAdapter->rWifiVar.prP2pFsmInfo->rWfdConfigureSettings); -+ -+ ASSERT_BREAK((prWfdCfgSettings != NULL)); -+ -+ if (prWfdCfgSettings->ucWfdEnable == 0) -+ break; -+ -+ /* AIS network. */ -+ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ -+ if ((!IS_NET_ACTIVE(prAdapter, NETWORK_TYPE_AIS_INDEX)) || -+ (prAisBssInfo->eConnectionState != PARAM_MEDIA_STATE_CONNECTED)) { -+ break; -+ } -+ -+ pucBuffer = (PUINT_8) ((ULONG) pucBuf + (UINT_32) (*pu2Offset)); -+ -+ ASSERT_BREAK(pucBuffer != NULL); -+ -+ prWfdAssocBssid = (P_WFD_ASSOCIATED_BSSID_IE_T) pucBuffer; -+ -+ prWfdAssocBssid->ucElemID = WFD_ATTRI_ID_ASSOC_BSSID; -+ -+ WLAN_SET_FIELD_BE16(&prWfdAssocBssid->u2Length, WFD_ATTRI_MAX_LEN_ASSOC_BSSID); -+ -+ COPY_MAC_ADDR(prWfdAssocBssid->aucAssocBssid, prAisBssInfo->aucBSSID); -+ -+ u4AttriLen = WFD_ATTRI_MAX_LEN_ASSOC_BSSID + WFD_ATTRI_HDR_LEN; -+ -+ } while (FALSE); -+ -+ (*pu2Offset) += (UINT_16) u4AttriLen; -+ -+ return u4AttriLen; -+} -+ -+/* wfdFuncAppendAttriAssocBssid */ -+ -+UINT_32 -+wfdFuncAppendAttriCoupledSinkInfo(IN P_ADAPTER_T prAdapter, -+ IN BOOLEAN fgIsAssocFrame, -+ IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize) -+{ -+ UINT_32 u4AttriLen = 0; -+ PUINT_8 pucBuffer = NULL; -+ P_WFD_COUPLE_SINK_INFORMATION_IE_T prWfdCoupleSinkInfo = (P_WFD_COUPLE_SINK_INFORMATION_IE_T) NULL; -+ P_WFD_CFG_SETTINGS_T prWfdCfgSettings = (P_WFD_CFG_SETTINGS_T) NULL; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (pucBuf != NULL) && (pu2Offset != NULL)); -+ -+ prWfdCfgSettings = &(prAdapter->rWifiVar.prP2pFsmInfo->rWfdConfigureSettings); -+ -+ ASSERT_BREAK((prWfdCfgSettings != NULL)); -+ -+ if ((prWfdCfgSettings->ucWfdEnable == 0) || -+ ((prWfdCfgSettings->u4WfdFlag & WFD_FLAGS_SINK_INFO_VALID) == 0)) { -+ break; -+ } -+ -+ pucBuffer = (PUINT_8) ((ULONG) pucBuf + (UINT_32) (*pu2Offset)); -+ -+ ASSERT_BREAK(pucBuffer != NULL); -+ -+ prWfdCoupleSinkInfo = (P_WFD_COUPLE_SINK_INFORMATION_IE_T) pucBuffer; -+ -+ prWfdCoupleSinkInfo->ucElemID = WFD_ATTRI_ID_COUPLED_SINK_INFO; -+ -+ WLAN_SET_FIELD_BE16(&prWfdCoupleSinkInfo->u2Length, WFD_ATTRI_MAX_LEN_COUPLED_SINK_INFO); -+ -+ COPY_MAC_ADDR(prWfdCoupleSinkInfo->aucCoupleSinkMac, prWfdCfgSettings->aucWfdCoupleSinkAddress); -+ -+ prWfdCoupleSinkInfo->ucCoupleSinkStatusBp = prWfdCfgSettings->ucWfdCoupleSinkStatus; -+ -+ u4AttriLen = WFD_ATTRI_MAX_LEN_COUPLED_SINK_INFO + WFD_ATTRI_HDR_LEN; -+ -+ } while (FALSE); -+ -+ (*pu2Offset) += (UINT_16) u4AttriLen; -+ -+ return u4AttriLen; -+} -+ -+/* wfdFuncAppendAttriCoupledSinkInfo */ -+ -+UINT_32 -+wfdFuncAppendAttriExtCapability(IN P_ADAPTER_T prAdapter, -+ IN BOOLEAN fgIsAssocFrame, -+ IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize) -+{ -+ UINT_32 u4AttriLen = 0; -+ PUINT_8 pucBuffer = NULL; -+ P_WFD_EXTENDED_CAPABILITY_IE_T prWfdExtCapability = (P_WFD_EXTENDED_CAPABILITY_IE_T) NULL; -+ P_WFD_CFG_SETTINGS_T prWfdCfgSettings = (P_WFD_CFG_SETTINGS_T) NULL; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (pucBuf != NULL) && (pu2Offset != NULL)); -+ -+ prWfdCfgSettings = &(prAdapter->rWifiVar.prP2pFsmInfo->rWfdConfigureSettings); -+ -+ ASSERT_BREAK((prWfdCfgSettings != NULL)); -+ -+ if ((prWfdCfgSettings->ucWfdEnable == 0) || -+ ((prWfdCfgSettings->u4WfdFlag & WFD_FLAGS_EXT_CAPABILITY_VALID) == 0)) { -+ break; -+ } -+ -+ pucBuffer = (PUINT_8) ((ULONG) pucBuf + (UINT_32) (*pu2Offset)); -+ -+ ASSERT_BREAK(pucBuffer != NULL); -+ -+ prWfdExtCapability = (P_WFD_EXTENDED_CAPABILITY_IE_T) pucBuffer; -+ -+ prWfdExtCapability->ucElemID = WFD_ATTRI_ID_EXT_CAPABILITY; -+ -+ WLAN_SET_FIELD_BE16(&prWfdExtCapability->u2Length, WFD_ATTRI_MAX_LEN_EXT_CAPABILITY); -+ -+ WLAN_SET_FIELD_BE16(&prWfdExtCapability->u2WfdExtCapabilityBp, prWfdCfgSettings->u2WfdExtendCap); -+ -+ u4AttriLen = WFD_ATTRI_MAX_LEN_EXT_CAPABILITY + WFD_ATTRI_HDR_LEN; -+ -+ } while (FALSE); -+ -+ (*pu2Offset) += (UINT_16) u4AttriLen; -+ -+ return u4AttriLen; -+} -+ -+/* wfdFuncAppendAttriExtCapability */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is used to calculate length of Channel List Attribute -+* -+* @param[in] prStaRec Pointer to the STA_RECORD_T -+* -+* @return The length of Attribute added -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT_32 wfdFuncCalculateAttriLenSessionInfo(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec) -+{ -+ UINT_16 u2AttriLen = 0; -+ P_WFD_CFG_SETTINGS_T prWfdCfgSettings = (P_WFD_CFG_SETTINGS_T) NULL; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prStaRec != NULL)); -+ -+ prWfdCfgSettings = &(prAdapter->rWifiVar.prP2pFsmInfo->rWfdConfigureSettings); -+ -+ if (prWfdCfgSettings->ucWfdEnable == 0) -+ break; -+ -+ u2AttriLen = prWfdCfgSettings->u2WfdSessionInformationIELen + WFD_ATTRI_HDR_LEN; -+ -+ } while (FALSE); -+ -+ return (UINT_32) u2AttriLen; -+ -+} /* wfdFuncCalculateAttriLenSessionInfo */ -+ -+UINT_32 -+wfdFuncAppendAttriSessionInfo(IN P_ADAPTER_T prAdapter, -+ IN BOOLEAN fgIsAssocFrame, IN PUINT_16 pu2Offset, IN PUINT_8 pucBuf, IN UINT_16 u2BufSize) -+{ -+ UINT_32 u4AttriLen = 0; -+ PUINT_8 pucBuffer = NULL; -+ P_WFD_SESSION_INFORMATION_IE_T prWfdSessionInfo = (P_WFD_SESSION_INFORMATION_IE_T) NULL; -+ P_WFD_CFG_SETTINGS_T prWfdCfgSettings = (P_WFD_CFG_SETTINGS_T) NULL; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (pucBuf != NULL) && (pu2Offset != NULL)); -+ -+ prWfdCfgSettings = &(prAdapter->rWifiVar.prP2pFsmInfo->rWfdConfigureSettings); -+ -+ ASSERT_BREAK((prWfdCfgSettings != NULL)); -+ -+ if ((prWfdCfgSettings->ucWfdEnable == 0) || (prWfdCfgSettings->u2WfdSessionInformationIELen == 0)) -+ break; -+ -+ pucBuffer = (PUINT_8) ((ULONG) pucBuf + (UINT_32) (*pu2Offset)); -+ -+ ASSERT_BREAK(pucBuffer != NULL); -+ -+ prWfdSessionInfo = (P_WFD_SESSION_INFORMATION_IE_T) pucBuffer; -+ -+ prWfdSessionInfo->ucElemID = WFD_ATTRI_ID_SESSION_INFO; -+ -+ /* TODO: Check endian issue? */ -+ kalMemCopy(prWfdSessionInfo->pucWfdDevInfoDesc, prWfdCfgSettings->aucWfdSessionInformationIE, -+ prWfdCfgSettings->u2WfdSessionInformationIELen); -+ -+ WLAN_SET_FIELD_16(&prWfdSessionInfo->u2Length, prWfdCfgSettings->u2WfdSessionInformationIELen); -+ -+ u4AttriLen = prWfdCfgSettings->u2WfdSessionInformationIELen + WFD_ATTRI_HDR_LEN; -+ -+ } while (FALSE); -+ -+ (*pu2Offset) += (UINT_16) u4AttriLen; -+ -+ return u4AttriLen; -+} -+ -+/* wfdFuncAppendAttriSessionInfo */ -+ -+#if CFG_SUPPORT_WFD_COMPOSE_IE -+VOID -+wfdFuncGenerateWfd_IE(IN P_ADAPTER_T prAdapter, -+ IN BOOLEAN fgIsAssocFrame, -+ IN PUINT_16 pu2Offset, -+ IN PUINT_8 pucBuf, -+ IN UINT_16 u2BufSize, -+ IN APPEND_VAR_ATTRI_ENTRY_T arAppendAttriTable[], IN UINT_32 u4AttriTableSize) -+{ -+ -+ PUINT_8 pucBuffer = (PUINT_8) NULL; -+ P_IE_WFD_T prIeWFD = (P_IE_WFD_T) NULL; -+ UINT_32 u4OverallAttriLen; -+ UINT_32 u4AttriLen; -+ UINT_8 aucWfaOui[] = VENDOR_OUI_WFA_SPECIFIC; -+ UINT_8 aucTempBuffer[P2P_MAXIMUM_ATTRIBUTE_LEN]; -+ UINT_32 i; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (pucBuf != NULL)); -+ -+ pucBuffer = (PUINT_8) ((ULONG) pucBuf + (*pu2Offset)); -+ -+ ASSERT_BREAK(pucBuffer != NULL); -+ -+ /* Check buffer length is still enough. */ -+ ASSERT_BREAK((u2BufSize - (*pu2Offset)) >= WFD_IE_OUI_HDR); -+ -+ prIeWFD = (P_IE_WFD_T) pucBuffer; -+ -+ prIeWFD->ucId = ELEM_ID_WFD; -+ -+ prIeWFD->aucOui[0] = aucWfaOui[0]; -+ prIeWFD->aucOui[1] = aucWfaOui[1]; -+ prIeWFD->aucOui[2] = aucWfaOui[2]; -+ prIeWFD->ucOuiType = VENDOR_OUI_TYPE_WFD; -+ -+ (*pu2Offset) += WFD_IE_OUI_HDR; -+ -+ /* Overall length of all Attributes */ -+ u4OverallAttriLen = 0; -+ -+ for (i = 0; i < u4AttriTableSize; i++) { -+ -+ if (arAppendAttriTable[i].pfnAppendAttri) { -+ u4AttriLen = -+ arAppendAttriTable[i].pfnAppendAttri(prAdapter, fgIsAssocFrame, pu2Offset, pucBuf, -+ u2BufSize); -+ -+ u4OverallAttriLen += u4AttriLen; -+ -+ if (u4OverallAttriLen > P2P_MAXIMUM_ATTRIBUTE_LEN) { -+ u4OverallAttriLen -= P2P_MAXIMUM_ATTRIBUTE_LEN; -+ -+ prIeWFD->ucLength = (VENDOR_OUI_TYPE_LEN + P2P_MAXIMUM_ATTRIBUTE_LEN); -+ -+ pucBuffer = -+ (PUINT_8) ((ULONG) prIeWFD + (WFD_IE_OUI_HDR + P2P_MAXIMUM_ATTRIBUTE_LEN)); -+ -+ prIeWFD = -+ (P_IE_WFD_T) ((ULONG) prIeWFD + -+ (WFD_IE_OUI_HDR + P2P_MAXIMUM_ATTRIBUTE_LEN)); -+ -+ kalMemCopy(aucTempBuffer, pucBuffer, u4OverallAttriLen); -+ -+ prIeWFD->ucId = ELEM_ID_WFD; -+ -+ prIeWFD->aucOui[0] = aucWfaOui[0]; -+ prIeWFD->aucOui[1] = aucWfaOui[1]; -+ prIeWFD->aucOui[2] = aucWfaOui[2]; -+ prIeWFD->ucOuiType = VENDOR_OUI_TYPE_WFD; -+ -+ kalMemCopy(prIeWFD->aucWFDAttributes, aucTempBuffer, u4OverallAttriLen); -+ (*pu2Offset) += WFD_IE_OUI_HDR; -+ } -+ -+ } -+ -+ } -+ -+ prIeWFD->ucLength = (UINT_8) (VENDOR_OUI_TYPE_LEN + u4OverallAttriLen); -+ -+ } while (FALSE); -+ -+} /* wfdFuncGenerateWfd_IE */ -+ -+#endif /* CFG_SUPPORT_WFD_COMPOSE_IE */ -+ -+UINT_32 -+wfdFuncCalculateWfdIELenForAssocRsp(IN P_ADAPTER_T prAdapter, -+ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, IN P_STA_RECORD_T prStaRec) -+{ -+ -+#if CFG_SUPPORT_WFD_COMPOSE_IE -+ P_WFD_CFG_SETTINGS_T prWfdCfgSettings = (P_WFD_CFG_SETTINGS_T) NULL; -+ -+ prWfdCfgSettings = &(prAdapter->rWifiVar.prP2pFsmInfo->rWfdConfigureSettings); -+ -+ if (!IS_STA_P2P_TYPE(prStaRec) || (prWfdCfgSettings->ucWfdEnable == 0)) -+ return 0; -+ -+ return p2pFuncCalculateP2P_IELen(prAdapter, -+ eNetTypeIndex, -+ prStaRec, -+ txAssocRspWFDAttributesTable, -+ sizeof(txAssocRspWFDAttributesTable) / sizeof(APPEND_VAR_ATTRI_ENTRY_T)); -+ -+#else -+ return 0; -+#endif -+} /* wfdFuncCalculateWfdIELenForAssocRsp */ -+ -+VOID wfdFuncGenerateWfdIEForAssocRsp(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo) -+{ -+ -+#if CFG_SUPPORT_WFD_COMPOSE_IE -+ P_WFD_CFG_SETTINGS_T prWfdCfgSettings = (P_WFD_CFG_SETTINGS_T) NULL; -+ P_STA_RECORD_T prStaRec; -+ -+ do { -+ ASSERT_BREAK((prMsduInfo != NULL) && (prAdapter != NULL)); -+ -+ prWfdCfgSettings = &(prAdapter->rWifiVar.prP2pFsmInfo->rWfdConfigureSettings); -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); -+ -+ if (!prStaRec) { -+ ASSERT(FALSE); -+ } else if (IS_STA_P2P_TYPE(prStaRec)) { -+ -+ if (prWfdCfgSettings->ucWfdEnable == 0) -+ break; -+ if ((prWfdCfgSettings->u4WfdFlag & WFD_FLAGS_DEV_INFO_VALID) == 0) -+ break; -+ -+ wfdFuncGenerateWfd_IE(prAdapter, -+ FALSE, -+ &prMsduInfo->u2FrameLength, -+ prMsduInfo->prPacket, -+ 1500, -+ txAssocRspWFDAttributesTable, -+ sizeof(txAssocRspWFDAttributesTable) / sizeof(APPEND_VAR_ATTRI_ENTRY_T)); -+ } -+ } while (FALSE); -+ -+ return; -+#else -+ -+ return; -+#endif -+} /* wfdFuncGenerateWfdIEForAssocRsp */ -+ -+VOID p2pFuncComposeNoaAttribute(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo) -+{ -+ -+ P_IE_P2P_T prIeP2P; -+ P_P2P_ATTRI_NOA_T prNoaAttr = NULL; -+ P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo = NULL; -+ P_NOA_DESCRIPTOR_T prNoaDesc = NULL; -+ -+ UINT_8 aucWfaOui[] = VENDOR_OUI_WFA_SPECIFIC; -+ UINT_32 u4AttributeLen; -+ UINT_32 u4NumOfNoaDesc = 0; -+ UINT_32 i = 0; -+ /*P2P IE format */ -+ prIeP2P = (P_IE_P2P_T) ((ULONG) prMsduInfo->prPacket + (UINT_32) prMsduInfo->u2FrameLength); -+ prIeP2P->ucId = ELEM_ID_P2P; -+ prIeP2P->aucOui[0] = aucWfaOui[0]; -+ prIeP2P->aucOui[1] = aucWfaOui[1]; -+ prIeP2P->aucOui[2] = aucWfaOui[2]; -+ prIeP2P->ucOuiType = VENDOR_OUI_TYPE_P2P; -+ -+ prP2pSpecificBssInfo = prAdapter->rWifiVar.prP2pSpecificBssInfo; -+ /*P2P Attribute--NoA */ -+ prNoaAttr = (P_P2P_ATTRI_NOA_T) prIeP2P->aucP2PAttributes; -+ -+ prNoaAttr->ucId = P2P_ATTRI_ID_NOTICE_OF_ABSENCE; -+ prNoaAttr->ucIndex = prP2pSpecificBssInfo->ucNoAIndex; -+ /*OPP*/ if (prP2pSpecificBssInfo->fgEnableOppPS) { -+ prNoaAttr->ucCTWOppPSParam = P2P_CTW_OPPPS_PARAM_OPPPS_FIELD | -+ (prP2pSpecificBssInfo->u2CTWindow & P2P_CTW_OPPPS_PARAM_CTWINDOW_MASK); -+ } else { -+ prNoaAttr->ucCTWOppPSParam = 0; -+ } -+ /*NoA Description */ -+ DBGLOG(P2P, INFO, "Compose NoA count=%d.\n", prP2pSpecificBssInfo->ucNoATimingCount); -+ for (i = 0; i < prP2pSpecificBssInfo->ucNoATimingCount; i++) { -+ if (prP2pSpecificBssInfo->arNoATiming[i].fgIsInUse) { -+ -+ prNoaDesc = (P_NOA_DESCRIPTOR_T) &prNoaAttr->aucNoADesc[u4NumOfNoaDesc]; -+ -+ prNoaDesc->ucCountType = prP2pSpecificBssInfo->arNoATiming[i].ucCount; -+ prNoaDesc->u4Duration = prP2pSpecificBssInfo->arNoATiming[i].u4Duration; -+ prNoaDesc->u4Interval = prP2pSpecificBssInfo->arNoATiming[i].u4Interval; -+ prNoaDesc->u4StartTime = prP2pSpecificBssInfo->arNoATiming[i].u4StartTime; -+ -+ u4NumOfNoaDesc++; -+ } -+ } -+ -+ /* include "index" + "OppPs Params" + "NOA descriptors" */ -+ prNoaAttr->u2Length = 2 + u4NumOfNoaDesc * sizeof(NOA_DESCRIPTOR_T); -+ u4NumOfNoaDesc++; -+ -+ /* include "Attribute ID" + "Length" + "index" + "OppPs Params" + "NOA descriptors" */ -+ u4AttributeLen = P2P_ATTRI_HDR_LEN + prNoaAttr->u2Length; -+ -+ prIeP2P->ucLength = VENDOR_OUI_TYPE_LEN + u4AttributeLen; -+ prMsduInfo->u2FrameLength += (ELEM_HDR_LEN + prIeP2P->ucLength); -+ -+} -+ -+UINT_32 p2pFuncCalculateP2P_IE_NoA(IN P_ADAPTER_T prAdapter, IN UINT_32 ucBssIdx, IN P_STA_RECORD_T prStaRec) -+{ -+ P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo = NULL; -+ UINT_8 ucIdx; -+ UINT_32 u4NumOfNoaDesc = 0; -+ -+ if (p2pFuncIsAPMode(prAdapter->rWifiVar.prP2pFsmInfo)) -+ return 0; -+ -+ prP2pSpecificBssInfo = prAdapter->rWifiVar.prP2pSpecificBssInfo; -+ -+ for (ucIdx = 0; ucIdx < prP2pSpecificBssInfo->ucNoATimingCount; ucIdx++) { -+ if (prP2pSpecificBssInfo->arNoATiming[ucIdx].fgIsInUse) -+ u4NumOfNoaDesc++; -+ } -+ -+ /* include "index" + "OppPs Params" + "NOA descriptors" */ -+ /* include "Attribute ID" + "Length" + "index" + "OppPs Params" + "NOA descriptors" */ -+ -+ return P2P_ATTRI_LEN_NOTICE_OF_ABSENCE + (u4NumOfNoaDesc * sizeof(NOA_DESCRIPTOR_T)); -+} -+ -+VOID p2pFuncGenerateP2P_IE_NoA(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo) -+{ -+ if (p2pFuncIsAPMode(prAdapter->rWifiVar.prP2pFsmInfo)) { /* Hotspot */ -+ return; -+ } -+ -+ /* Compose NoA attribute */ -+ p2pFuncComposeNoaAttribute(prAdapter, -+ prMsduInfo /*prMsduInfo->ucBssIndex, prIeP2P->aucP2PAttributes, &u4AttributeLen */); -+ -+} -+ -+#endif -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_rlm.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_rlm.c -new file mode 100644 -index 000000000000..f25df82d9ca7 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_rlm.c -@@ -0,0 +1,905 @@ -+/* -+** Id: @(#) p2p_rlm.c@@ -+*/ -+ -+/*! \file "p2p_rlm.c" -+ \brief -+ -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+#include "precomp.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Init AP Bss -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rlmBssInitForAP(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo) -+{ -+ ENUM_BAND_T eBand; -+ UINT_8 ucChannel; -+ ENUM_CHNL_EXT_T eSCO; -+ -+ ASSERT(prAdapter); -+ ASSERT(prBssInfo); -+ -+ if (prBssInfo->eCurrentOPMode != OP_MODE_ACCESS_POINT) -+ return; -+ -+ /* Operation band, channel shall be ready before invoking this function. -+ * Bandwidth may be ready if other network is connected -+ */ -+ prBssInfo->fg40mBwAllowed = FALSE; -+ prBssInfo->fgAssoc40mBwAllowed = FALSE; -+ prBssInfo->eBssSCO = CHNL_EXT_SCN; -+ -+ if (RLM_AP_IS_BW_40_ALLOWED(prAdapter, prBssInfo)) { -+ /* In this case, the first BSS's SCO is 40MHz and known, so AP can -+ * apply 40MHz bandwidth, but the first BSS's SCO may be changed -+ * later if its Beacon lost timeout occurs -+ */ -+ if (cnmPreferredChannel(prAdapter, &eBand, &ucChannel, &eSCO) && -+ eSCO != CHNL_EXT_SCN && ucChannel == prBssInfo->ucPrimaryChannel && eBand == prBssInfo->eBand) { -+ prBssInfo->eBssSCO = eSCO; -+ } else if (cnmBss40mBwPermitted(prAdapter, prBssInfo->ucNetTypeIndex)) { -+ prBssInfo->eBssSCO = rlmDecideScoForAP(prAdapter, prBssInfo); -+ } -+ -+ if (prBssInfo->eBssSCO != CHNL_EXT_SCN) { -+ prBssInfo->fg40mBwAllowed = TRUE; -+ prBssInfo->fgAssoc40mBwAllowed = TRUE; -+ -+ prBssInfo->ucHtOpInfo1 = (UINT_8) -+ (((UINT_32) prBssInfo->eBssSCO) | HT_OP_INFO1_STA_CHNL_WIDTH); -+ -+ rlmUpdateBwByChListForAP(prAdapter, prBssInfo); -+ } -+ } -+ -+ DBGLOG(RLM, INFO, "WLAN AP SCO=%d\n", prBssInfo->eBssSCO); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief For probe response (GO, IBSS) and association response -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rlmRspGenerateObssScanIE(P_ADAPTER_T prAdapter, P_MSDU_INFO_T prMsduInfo) -+{ -+ P_BSS_INFO_T prBssInfo; -+ P_IE_OBSS_SCAN_PARAM_T prObssScanIe; -+ P_STA_RECORD_T prStaRec = (P_STA_RECORD_T) NULL; -+ -+ ASSERT(prAdapter); -+ ASSERT(prMsduInfo); -+ ASSERT(IS_NET_ACTIVE(prAdapter, prMsduInfo->ucNetworkType)); -+ -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); -+ -+ prBssInfo = &prAdapter->rWifiVar.arBssInfo[prMsduInfo->ucNetworkType]; -+ ASSERT(prBssInfo); -+ -+ if (RLM_NET_IS_11N(prBssInfo) && !RLM_NET_IS_BOW(prBssInfo) && -+ prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT && -+ (!prStaRec || (prStaRec->ucPhyTypeSet & PHY_TYPE_SET_802_11N)) && -+ prBssInfo->eBand == BAND_2G4 && prBssInfo->eBssSCO != CHNL_EXT_SCN) { -+ -+ prObssScanIe = (P_IE_OBSS_SCAN_PARAM_T) -+ (((PUINT_8) prMsduInfo->prPacket) + prMsduInfo->u2FrameLength); -+ -+ /* Add 20/40 BSS coexistence IE */ -+ prObssScanIe->ucId = ELEM_ID_OBSS_SCAN_PARAMS; -+ prObssScanIe->ucLength = sizeof(IE_OBSS_SCAN_PARAM_T) - ELEM_HDR_LEN; -+ -+ prObssScanIe->u2ScanPassiveDwell = dot11OBSSScanPassiveDwell; -+ prObssScanIe->u2ScanActiveDwell = dot11OBSSScanActiveDwell; -+ prObssScanIe->u2TriggerScanInterval = dot11BSSWidthTriggerScanInterval; -+ prObssScanIe->u2ScanPassiveTotalPerChnl = dot11OBSSScanPassiveTotalPerChannel; -+ prObssScanIe->u2ScanActiveTotalPerChnl = dot11OBSSScanActiveTotalPerChannel; -+ prObssScanIe->u2WidthTransDelayFactor = dot11BSSWidthChannelTransitionDelayFactor; -+ prObssScanIe->u2ScanActivityThres = dot11OBSSScanActivityThreshold; -+ -+ ASSERT(IE_SIZE(prObssScanIe) <= (ELEM_HDR_LEN + ELEM_MAX_LEN_OBSS_SCAN)); -+ -+ prMsduInfo->u2FrameLength += IE_SIZE(prObssScanIe); -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief P2P GO. -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN rlmUpdateBwByChListForAP(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo) -+{ -+ UINT_8 ucLevel; -+ BOOLEAN fgBwChange; -+ -+ ASSERT(prAdapter); -+ ASSERT(prBssInfo); -+ -+ fgBwChange = FALSE; -+ -+ if (prBssInfo->eBssSCO == CHNL_EXT_SCN) -+ return fgBwChange; -+ -+ ucLevel = rlmObssChnlLevel(prBssInfo, prBssInfo->eBand, prBssInfo->ucPrimaryChannel, prBssInfo->eBssSCO); -+ -+ if (ucLevel == CHNL_LEVEL0) { -+ /* Forced to 20MHz, so extended channel is SCN and STA width is zero */ -+ prBssInfo->fgObssActionForcedTo20M = TRUE; -+ -+ if (prBssInfo->ucHtOpInfo1 != (UINT_8) CHNL_EXT_SCN) { -+ prBssInfo->ucHtOpInfo1 = (UINT_8) CHNL_EXT_SCN; -+ fgBwChange = TRUE; -+ } -+ -+ cnmTimerStartTimer(prAdapter, &prBssInfo->rObssScanTimer, OBSS_20_40M_TIMEOUT * MSEC_PER_SEC); -+ } -+ -+ /* Clear up all channel lists */ -+ prBssInfo->auc2G_20mReqChnlList[0] = 0; -+ prBssInfo->auc2G_NonHtChnlList[0] = 0; -+ prBssInfo->auc2G_PriChnlList[0] = 0; -+ prBssInfo->auc2G_SecChnlList[0] = 0; -+ prBssInfo->auc5G_20mReqChnlList[0] = 0; -+ prBssInfo->auc5G_NonHtChnlList[0] = 0; -+ prBssInfo->auc5G_PriChnlList[0] = 0; -+ prBssInfo->auc5G_SecChnlList[0] = 0; -+ -+ return fgBwChange; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rlmProcessPublicAction(P_ADAPTER_T prAdapter, P_SW_RFB_T prSwRfb) -+{ -+ P_ACTION_20_40_COEXIST_FRAME prRxFrame; -+ P_IE_20_40_COEXIST_T prCoexist; -+ P_IE_INTOLERANT_CHNL_REPORT_T prChnlReport; -+ P_BSS_INFO_T prBssInfo; -+ P_STA_RECORD_T prStaRec; -+ PUINT_8 pucIE; -+ UINT_16 u2IELength, u2Offset; -+ UINT_8 i, j; -+ -+ ASSERT(prAdapter); -+ ASSERT(prSwRfb); -+ -+ prRxFrame = (P_ACTION_20_40_COEXIST_FRAME) prSwRfb->pvHeader; -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); -+ -+ if (prRxFrame->ucAction != ACTION_PUBLIC_20_40_COEXIST || -+ !prStaRec || prStaRec->ucStaState != STA_STATE_3 || -+ prSwRfb->u2PacketLen < (WLAN_MAC_MGMT_HEADER_LEN + 5) || -+ HIF_RX_HDR_GET_NETWORK_IDX(prSwRfb->prHifRxHdr) != NETWORK_TYPE_P2P_INDEX) { -+ return; -+ } -+ -+ prBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]; -+ ASSERT(prBssInfo); -+ -+ if (!IS_BSS_ACTIVE(prBssInfo) || -+ prBssInfo->eCurrentOPMode != OP_MODE_ACCESS_POINT || prBssInfo->eBssSCO == CHNL_EXT_SCN) { -+ return; -+ } -+ -+ prCoexist = &prRxFrame->rBssCoexist; -+ if (prCoexist->ucData & (BSS_COEXIST_40M_INTOLERANT | BSS_COEXIST_20M_REQ)) { -+ ASSERT(prBssInfo->auc2G_20mReqChnlList[0] <= CHNL_LIST_SZ_2G); -+ for (i = 1; i <= prBssInfo->auc2G_20mReqChnlList[0] && i <= CHNL_LIST_SZ_2G; i++) { -+ if (prBssInfo->auc2G_20mReqChnlList[i] == prBssInfo->ucPrimaryChannel) -+ break; -+ } -+ if ((i > prBssInfo->auc2G_20mReqChnlList[0]) && (i <= CHNL_LIST_SZ_2G)) { -+ prBssInfo->auc2G_20mReqChnlList[i] = prBssInfo->ucPrimaryChannel; -+ prBssInfo->auc2G_20mReqChnlList[0]++; -+ } -+ } -+ -+ /* Process intolerant channel report IE */ -+ pucIE = (PUINT_8) &prRxFrame->rChnlReport; -+ u2IELength = prSwRfb->u2PacketLen - (WLAN_MAC_MGMT_HEADER_LEN + 5); -+ -+ IE_FOR_EACH(pucIE, u2IELength, u2Offset) { -+ switch (IE_ID(pucIE)) { -+ case ELEM_ID_20_40_INTOLERANT_CHNL_REPORT: -+ prChnlReport = (P_IE_INTOLERANT_CHNL_REPORT_T) pucIE; -+ -+ if (prChnlReport->ucLength <= 1) -+ break; -+ -+ /* To do: process regulatory class. Now we assume 2.4G band */ -+ -+ for (j = 0; j < prChnlReport->ucLength - 1; j++) { -+ /* Update non-HT channel list */ -+ ASSERT(prBssInfo->auc2G_NonHtChnlList[0] <= CHNL_LIST_SZ_2G); -+ for (i = 1; i <= prBssInfo->auc2G_NonHtChnlList[0] && i <= CHNL_LIST_SZ_2G; i++) { -+ if (prBssInfo->auc2G_NonHtChnlList[i] == prChnlReport->aucChannelList[j]) -+ break; -+ } -+ if ((i > prBssInfo->auc2G_NonHtChnlList[0]) && (i <= CHNL_LIST_SZ_2G)) { -+ prBssInfo->auc2G_NonHtChnlList[i] = prChnlReport->aucChannelList[j]; -+ prBssInfo->auc2G_NonHtChnlList[0]++; -+ } -+ } -+ break; -+ -+ default: -+ break; -+ } -+ } /* end of IE_FOR_EACH */ -+ -+ if (rlmUpdateBwByChListForAP(prAdapter, prBssInfo)) { -+ bssUpdateBeaconContent(prAdapter, prBssInfo->ucNetTypeIndex); -+ rlmSyncOperationParams(prAdapter, prBssInfo); -+ } -+ -+ /* Check if OBSS scan exemption response should be sent */ -+ if (prCoexist->ucData & BSS_COEXIST_OBSS_SCAN_EXEMPTION_REQ) -+ rlmObssScanExemptionRsp(prAdapter, prBssInfo, prSwRfb); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rlmProcessHtAction(P_ADAPTER_T prAdapter, P_SW_RFB_T prSwRfb) -+{ -+ P_ACTION_NOTIFY_CHNL_WIDTH_FRAME prRxFrame; -+ P_STA_RECORD_T prStaRec; -+ -+ ASSERT(prAdapter); -+ ASSERT(prSwRfb); -+ -+ prRxFrame = (P_ACTION_NOTIFY_CHNL_WIDTH_FRAME) prSwRfb->pvHeader; -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); -+ -+ if (prRxFrame->ucAction != ACTION_HT_NOTIFY_CHANNEL_WIDTH || -+ !prStaRec || prStaRec->ucStaState != STA_STATE_3 || -+ prSwRfb->u2PacketLen < sizeof(ACTION_NOTIFY_CHNL_WIDTH_FRAME)) { -+ return; -+ } -+ -+ /* To do: depending regulation class 13 and 14 based on spec -+ * Note: (ucChannelWidth==1) shall restored back to original capability, -+ * not current setting to 40MHz BW here -+ */ -+ if (prRxFrame->ucChannelWidth == 0) -+ prStaRec->u2HtCapInfo &= ~HT_CAP_INFO_SUP_CHNL_WIDTH; -+ else if (prRxFrame->ucChannelWidth == 1) -+ prStaRec->u2HtCapInfo |= HT_CAP_INFO_SUP_CHNL_WIDTH; -+ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_3); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rlmHandleObssStatusEventPkt(P_ADAPTER_T prAdapter, P_EVENT_AP_OBSS_STATUS_T prObssStatus) -+{ -+ P_BSS_INFO_T prBssInfo; -+ -+ ASSERT(prAdapter); -+ ASSERT(prObssStatus); -+ ASSERT(prObssStatus->ucNetTypeIndex == NETWORK_TYPE_P2P_INDEX); -+ -+ prBssInfo = &prAdapter->rWifiVar.arBssInfo[prObssStatus->ucNetTypeIndex]; -+ ASSERT(prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT); -+ -+ prBssInfo->fgObssErpProtectMode = (BOOLEAN) prObssStatus->ucObssErpProtectMode; -+ prBssInfo->eObssHtProtectMode = (ENUM_HT_PROTECT_MODE_T) prObssStatus->ucObssHtProtectMode; -+ prBssInfo->eObssGfOperationMode = (ENUM_GF_MODE_T) prObssStatus->ucObssGfOperationMode; -+ prBssInfo->fgObssRifsOperationMode = (BOOLEAN) prObssStatus->ucObssRifsOperationMode; -+ prBssInfo->fgObssBeaconForcedTo20M = (BOOLEAN) prObssStatus->ucObssBeaconForcedTo20M; -+ -+ /* Check if Beacon content need to be updated */ -+ rlmUpdateParamsForAP(prAdapter, prBssInfo, TRUE); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief It is only for AP mode in NETWORK_TYPE_P2P_INDEX. -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rlmUpdateParamsForAP(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo, BOOLEAN fgUpdateBeacon) -+{ -+ P_LINK_T prStaList; -+ P_STA_RECORD_T prStaRec; -+ BOOLEAN fgErpProtectMode, fgSta40mIntolerant; -+ BOOLEAN fgUseShortPreamble, fgUseShortSlotTime; -+ ENUM_HT_PROTECT_MODE_T eHtProtectMode; -+ ENUM_GF_MODE_T eGfOperationMode; -+ UINT_8 ucHtOpInfo1; -+#if CFG_SUPPORT_HOTSPOT_OPTIMIZATION -+ P_GLUE_INFO_T prGlueInfo; -+#endif -+ -+ ASSERT(prAdapter); -+ ASSERT(prBssInfo); -+ -+ if (!IS_BSS_ACTIVE(prBssInfo) || prBssInfo->eCurrentOPMode != OP_MODE_ACCESS_POINT) -+ return; -+ -+ fgErpProtectMode = FALSE; -+ eHtProtectMode = HT_PROTECT_MODE_NONE; -+ eGfOperationMode = GF_MODE_NORMAL; -+ fgSta40mIntolerant = FALSE; -+ fgUseShortPreamble = prBssInfo->fgIsShortPreambleAllowed; -+ fgUseShortSlotTime = TRUE; -+ ucHtOpInfo1 = (UINT_8) CHNL_EXT_SCN; -+ -+ prStaList = &prBssInfo->rStaRecOfClientList; -+ -+ LINK_FOR_EACH_ENTRY(prStaRec, prStaList, rLinkEntry, STA_RECORD_T) { -+ /* ASSERT(prStaRec); */ -+ if (!prStaRec) { -+ DBGLOG(P2P, TRACE, "prStaRec is NULL in rlmUpdateParamsForAP()\n"); -+ break; -+ } -+ if (prStaRec->fgIsInUse && prStaRec->ucStaState == STA_STATE_3 && -+ prStaRec->ucNetTypeIndex == prBssInfo->ucNetTypeIndex) { -+ if (!(prStaRec->ucPhyTypeSet & (PHY_TYPE_SET_802_11GN | PHY_TYPE_SET_802_11A))) { -+ /* B-only mode, so mode 1 (ERP protection) */ -+ fgErpProtectMode = TRUE; -+ } -+ -+ if (!(prStaRec->ucPhyTypeSet & PHY_TYPE_SET_802_11N)) { -+ /* BG-only or A-only */ -+ eHtProtectMode = HT_PROTECT_MODE_NON_HT; -+ } else if (!(prStaRec->u2HtCapInfo & HT_CAP_INFO_SUP_CHNL_WIDTH)) { -+ /* 20MHz-only */ -+ /* -+ The HT Protection field may be set to 20 MHz protection -+ mode only if the following are true: -+ \A1X All STAs detected (by any means) in the primary channel -+ and all STAs detected (by any means) in the secondary -+ channel are HT STAs and all STAs that are members of -+ this BSS are HT STAs, and -+ \A1X This BSS is a 20/40 MHz BSS, and -+ \A1X There is at least one 20 MHz HT STA associated with this BSS. -+ */ -+ if (eHtProtectMode == HT_PROTECT_MODE_NONE && prBssInfo->fgAssoc40mBwAllowed) -+ eHtProtectMode = HT_PROTECT_MODE_20M; -+ } -+ -+ if (!(prStaRec->u2HtCapInfo & HT_CAP_INFO_HT_GF)) -+ eGfOperationMode = GF_MODE_PROTECT; -+ -+ if (!(prStaRec->u2CapInfo & CAP_INFO_SHORT_PREAMBLE)) -+ fgUseShortPreamble = FALSE; -+ -+ if (!(prStaRec->u2CapInfo & CAP_INFO_SHORT_SLOT_TIME)) -+ fgUseShortSlotTime = FALSE; -+ -+ if (prStaRec->u2HtCapInfo & HT_CAP_INFO_40M_INTOLERANT) -+ fgSta40mIntolerant = TRUE; -+ } -+ } /* end of LINK_FOR_EACH_ENTRY */ -+ -+ /* Check if HT operation IE about 20/40M bandwidth shall be updated */ -+ if (prBssInfo->eBssSCO != CHNL_EXT_SCN) { -+ if (/*!LINK_IS_EMPTY(prStaList) && */ !fgSta40mIntolerant && -+ !prBssInfo->fgObssActionForcedTo20M && !prBssInfo->fgObssBeaconForcedTo20M) { -+ -+ ucHtOpInfo1 = (UINT_8) -+ (((UINT_32) prBssInfo->eBssSCO) | HT_OP_INFO1_STA_CHNL_WIDTH); -+ } -+ } -+#if CFG_SUPPORT_HOTSPOT_OPTIMIZATION -+ prGlueInfo = prAdapter->prGlueInfo; -+ if (prGlueInfo->prP2PInfo->u4PsLevel & BITS(8, 15)) -+ fgErpProtectMode = TRUE; -+#endif -+ -+ /* Check if any new parameter may be updated */ -+ if (prBssInfo->fgErpProtectMode != fgErpProtectMode || -+ prBssInfo->eHtProtectMode != eHtProtectMode || -+ prBssInfo->eGfOperationMode != eGfOperationMode || -+ prBssInfo->ucHtOpInfo1 != ucHtOpInfo1 || -+ prBssInfo->fgUseShortPreamble != fgUseShortPreamble || -+ prBssInfo->fgUseShortSlotTime != fgUseShortSlotTime) { -+ -+ prBssInfo->fgErpProtectMode = fgErpProtectMode; -+ prBssInfo->eHtProtectMode = eHtProtectMode; -+ prBssInfo->eGfOperationMode = eGfOperationMode; -+ prBssInfo->ucHtOpInfo1 = ucHtOpInfo1; -+ prBssInfo->fgUseShortPreamble = fgUseShortPreamble; -+ prBssInfo->fgUseShortSlotTime = fgUseShortSlotTime; -+ -+ if (fgUseShortSlotTime) -+ prBssInfo->u2CapInfo |= CAP_INFO_SHORT_SLOT_TIME; -+ else -+ prBssInfo->u2CapInfo &= ~CAP_INFO_SHORT_SLOT_TIME; -+ -+ rlmSyncOperationParams(prAdapter, prBssInfo); -+ fgUpdateBeacon = TRUE; -+ } -+ -+ /* Update Beacon content if related IE content is changed */ -+ if (fgUpdateBeacon) -+ bssUpdateBeaconContent(prAdapter, prBssInfo->ucNetTypeIndex); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Initial the channel list from the domain information. -+* This function is called after P2P initial and Domain information changed. -+* Make sure the device is disconnected while changing domain information. -+* -+* \param[in] prAdapter Pointer of ADAPTER_T -+* -+* \return boolean value if probe response frame is -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rlmFuncInitialChannelList(IN P_ADAPTER_T prAdapter) -+{ -+ P_P2P_CONNECTION_SETTINGS_T prP2pConnSetting = (P_P2P_CONNECTION_SETTINGS_T) NULL; -+ P_DOMAIN_INFO_ENTRY prDomainInfoEntry = (P_DOMAIN_INFO_ENTRY) NULL; -+ P_DOMAIN_SUBBAND_INFO prDomainSubBand = (P_DOMAIN_SUBBAND_INFO) NULL; -+ P_CHANNEL_ENTRY_FIELD_T prChannelEntryField = (P_CHANNEL_ENTRY_FIELD_T) NULL; -+ UINT_32 u4Idx = 0, u4IdxII = 0; -+ UINT_8 ucBufferSize = P2P_MAX_SUPPORTED_CHANNEL_LIST_SIZE; -+#if 0 -+ UINT_8 ucSocialChnlSupport = 0, ucAutoChnl = 0; -+#endif -+ -+ do { -+ ASSERT_BREAK(prAdapter != NULL); -+ -+ prP2pConnSetting = prAdapter->rWifiVar.prP2PConnSettings; -+#if 0 -+ ucAutoChnl = prP2pConnSetting->ucOperatingChnl; -+#endif -+ -+ prDomainInfoEntry = rlmDomainGetDomainInfo(prAdapter); -+ -+ ASSERT_BREAK((prDomainInfoEntry != NULL) && (prP2pConnSetting != NULL)); -+ -+ prChannelEntryField = (P_CHANNEL_ENTRY_FIELD_T) prP2pConnSetting->aucChannelEntriesField; -+ -+ for (u4Idx = 0; u4Idx < MAX_SUBBAND_NUM; u4Idx++) { -+ prDomainSubBand = &prDomainInfoEntry->rSubBand[u4Idx]; -+ -+ if (((prDomainSubBand->ucBand == BAND_5G) && (!prAdapter->fgEnable5GBand)) || -+ (prDomainSubBand->ucBand == BAND_NULL)) { -+ continue; -+ } -+ -+ if (ucBufferSize < (P2P_ATTRI_LEN_CHANNEL_ENTRY + prDomainSubBand->ucNumChannels)) { -+ /* Buffer is not enough to include all supported channels. */ -+ break; /* for */ -+ } -+ -+ prChannelEntryField->ucRegulatoryClass = prDomainSubBand->ucRegClass; -+ prChannelEntryField->ucNumberOfChannels = prDomainSubBand->ucNumChannels; -+ -+ for (u4IdxII = 0; u4IdxII < prDomainSubBand->ucNumChannels; u4IdxII++) { -+ prChannelEntryField->aucChannelList[u4IdxII] = prDomainSubBand->ucFirstChannelNum + -+ (u4IdxII * prDomainSubBand->ucChannelSpan); -+ -+#if 0 -+ switch (prChannelEntryField->aucChannelList[u4IdxII]) { -+ case 1: -+ ucSocialChnlSupport = 1; -+ break; -+ case 6: -+ ucSocialChnlSupport = 6; -+ break; -+ case 11: -+ ucSocialChnlSupport = 11; -+ break; -+ default: -+ break; -+ } -+ -+#endif -+ } -+ -+ if (ucBufferSize >= (P2P_ATTRI_LEN_CHANNEL_ENTRY + prChannelEntryField->ucNumberOfChannels)) -+ ucBufferSize -= (P2P_ATTRI_LEN_CHANNEL_ENTRY + prChannelEntryField->ucNumberOfChannels); -+ else -+ break; -+ -+ prChannelEntryField = (P_CHANNEL_ENTRY_FIELD_T) ((ULONG) prChannelEntryField + -+ P2P_ATTRI_LEN_CHANNEL_ENTRY + -+ (ULONG) -+ prChannelEntryField->ucNumberOfChannels); -+ -+ } -+ -+#if 0 -+ if (prP2pConnSetting->ucListenChnl == 0) { -+ prP2pConnSetting->ucListenChnl = P2P_DEFAULT_LISTEN_CHANNEL; -+ -+ if (ucSocialChnlSupport != 0) { -+ /* 1. User Not Set LISTEN channel. -+ * 2. Social channel is not empty. -+ */ -+ prP2pConnSetting->ucListenChnl = ucSocialChnlSupport; -+ } -+ } -+#endif -+ -+ /* TODO: 20110921 frog - */ -+ /* If LISTEN channel is not set, -+ * a random supported channel would be set. -+ * If no social channel is supported, DEFAULT channel would be set. -+ */ -+ -+ prP2pConnSetting->ucRfChannelListSize = P2P_MAX_SUPPORTED_CHANNEL_LIST_SIZE - ucBufferSize; -+ -+#if 0 -+ if (prP2pConnSetting->ucOperatingChnl == 0) { /* User not set OPERATE channel. */ -+ -+ if (scnQuerySparseChannel(prAdapter, NULL, &ucAutoChnl)) -+ break; /* while */ -+ -+ ucBufferSize = prP2pConnSetting->ucRfChannelListSize; -+ -+ prChannelEntryField = (P_CHANNEL_ENTRY_FIELD_T) prP2pConnSetting->aucChannelEntriesField; -+ -+ while (ucBufferSize != 0) { -+ if (prChannelEntryField->ucNumberOfChannels != 0) { -+ ucAutoChnl = prChannelEntryField->aucChannelList[0]; -+ break; /* while */ -+ } -+ -+ else { -+ prChannelEntryField = (P_CHANNEL_ENTRY_FIELD_T) ((UINT_32) prChannelEntryField + -+ P2P_ATTRI_LEN_CHANNEL_ENTRY + -+ (UINT_32)prChannelEntryField->ucNumberOfChannels); -+ -+ ucBufferSize -= -+ (P2P_ATTRI_LEN_CHANNEL_ENTRY + prChannelEntryField->ucNumberOfChannels); -+ } -+ -+ } -+ -+ } -+#endif -+ /* We assume user would not set a channel not in the channel list. -+ * If so, the operating channel still depends on target device supporting capability. -+ */ -+ -+ /* TODO: 20110921 frog - */ -+ /* If the Operating channel is not set, a channel from supported channel list is set automatically. -+ * If there is no supported channel in channel list, a DEFAULT channel is set. -+ */ -+ -+ } while (FALSE); -+ -+#if 0 -+ prP2pConnSetting->ucOperatingChnl = ucAutoChnl; -+#endif -+ -+} /* rlmFuncInitialChannelList */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Find a common channel list from the local channel list info & target channel list info. -+* -+* \param[in] prAdapter Pointer of ADAPTER_T -+* -+* \return boolean value if probe response frame is -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+rlmFuncCommonChannelList(IN P_ADAPTER_T prAdapter, -+ IN P_CHANNEL_ENTRY_FIELD_T prChannelEntryII, IN UINT_8 ucChannelListSize) -+{ -+ P_P2P_CONNECTION_SETTINGS_T prP2pConnSetting = (P_P2P_CONNECTION_SETTINGS_T) NULL; -+ P_CHANNEL_ENTRY_FIELD_T prChannelEntryI = (P_CHANNEL_ENTRY_FIELD_T) NULL, prChannelEntryIII = -+ (P_CHANNEL_ENTRY_FIELD_T) NULL; -+ UINT_8 aucCommonChannelList[P2P_MAX_SUPPORTED_CHANNEL_LIST_SIZE] = {0}; -+ UINT_8 ucOriChnlSize = 0, ucNewChnlSize = 0; -+ -+ do { -+ -+ ASSERT_BREAK(prAdapter != NULL); -+ -+ prP2pConnSetting = prAdapter->rWifiVar.prP2PConnSettings; -+ -+ prChannelEntryIII = (P_CHANNEL_ENTRY_FIELD_T) aucCommonChannelList; -+ -+ while (ucChannelListSize > 0) { -+ -+ prChannelEntryI = (P_CHANNEL_ENTRY_FIELD_T) prP2pConnSetting->aucChannelEntriesField; -+ ucOriChnlSize = prP2pConnSetting->ucRfChannelListSize; -+ -+ while (ucOriChnlSize > 0) { -+ if (prChannelEntryI->ucRegulatoryClass == prChannelEntryII->ucRegulatoryClass) { -+ prChannelEntryIII->ucRegulatoryClass = prChannelEntryI->ucRegulatoryClass; -+ /* TODO: Currently we assume that the regulatory class the same, -+ * the channels are the same. */ -+ kalMemCopy(prChannelEntryIII->aucChannelList, prChannelEntryII->aucChannelList, -+ prChannelEntryII->ucNumberOfChannels); -+ prChannelEntryIII->ucNumberOfChannels = prChannelEntryII->ucNumberOfChannels; -+ -+ ucNewChnlSize += -+ P2P_ATTRI_LEN_CHANNEL_ENTRY + prChannelEntryIII->ucNumberOfChannels; -+ -+ prChannelEntryIII = (P_CHANNEL_ENTRY_FIELD_T) ((ULONG) prChannelEntryIII + -+ P2P_ATTRI_LEN_CHANNEL_ENTRY + -+ (ULONG)prChannelEntryIII->ucNumberOfChannels); -+ } -+ -+ ucOriChnlSize -= (P2P_ATTRI_LEN_CHANNEL_ENTRY + prChannelEntryI->ucNumberOfChannels); -+ -+ prChannelEntryI = (P_CHANNEL_ENTRY_FIELD_T) ((ULONG) prChannelEntryI + -+ P2P_ATTRI_LEN_CHANNEL_ENTRY + -+ (ULONG) -+ prChannelEntryI->ucNumberOfChannels); -+ -+ } -+ -+ ucChannelListSize -= (P2P_ATTRI_LEN_CHANNEL_ENTRY + prChannelEntryII->ucNumberOfChannels); -+ -+ prChannelEntryII = (P_CHANNEL_ENTRY_FIELD_T) ((ULONG) prChannelEntryII + -+ P2P_ATTRI_LEN_CHANNEL_ENTRY + -+ (ULONG) prChannelEntryII->ucNumberOfChannels); -+ -+ } -+ -+ kalMemCopy(prP2pConnSetting->aucChannelEntriesField, aucCommonChannelList, ucNewChnlSize); -+ prP2pConnSetting->ucRfChannelListSize = ucNewChnlSize; -+ -+ } while (FALSE); -+ -+} /* rlmFuncCommonChannelList */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT_8 rlmFuncFindOperatingClass(IN P_ADAPTER_T prAdapter, IN UINT_8 ucChannelNum) -+{ -+ UINT_8 ucRegulatoryClass = 0, ucBufferSize = 0; -+ P_P2P_CONNECTION_SETTINGS_T prP2pConnSetting = (P_P2P_CONNECTION_SETTINGS_T) NULL; -+ P_CHANNEL_ENTRY_FIELD_T prChannelEntryField = (P_CHANNEL_ENTRY_FIELD_T) NULL; -+ UINT_32 u4Idx = 0; -+ -+ do { -+ ASSERT_BREAK(prAdapter != NULL); -+ -+ prP2pConnSetting = prAdapter->rWifiVar.prP2PConnSettings; -+ ucBufferSize = prP2pConnSetting->ucRfChannelListSize; -+ prChannelEntryField = (P_CHANNEL_ENTRY_FIELD_T) prP2pConnSetting->aucChannelEntriesField; -+ -+ while (ucBufferSize != 0) { -+ -+ for (u4Idx = 0; u4Idx < prChannelEntryField->ucNumberOfChannels; u4Idx++) { -+ if (prChannelEntryField->aucChannelList[u4Idx] == ucChannelNum) { -+ ucRegulatoryClass = prChannelEntryField->ucRegulatoryClass; -+ break; -+ } -+ -+ } -+ -+ if (ucRegulatoryClass != 0) -+ break; /* while */ -+ -+ prChannelEntryField = (P_CHANNEL_ENTRY_FIELD_T) ((ULONG) prChannelEntryField + -+ P2P_ATTRI_LEN_CHANNEL_ENTRY + -+ (ULONG)prChannelEntryField->ucNumberOfChannels); -+ -+ ucBufferSize -= (P2P_ATTRI_LEN_CHANNEL_ENTRY + prChannelEntryField->ucNumberOfChannels); -+ -+ } -+ -+ } while (FALSE); -+ -+ return ucRegulatoryClass; -+} /* rlmFuncFindOperatingClass */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN -+rlmFuncFindAvailableChannel(IN P_ADAPTER_T prAdapter, -+ IN UINT_8 ucCheckChnl, -+ IN PUINT_8 pucSuggestChannel, IN BOOLEAN fgIsSocialChannel, IN BOOLEAN fgIsDefaultChannel) -+{ -+ BOOLEAN fgIsResultAvailable = FALSE; -+ P_CHANNEL_ENTRY_FIELD_T prChannelEntry = (P_CHANNEL_ENTRY_FIELD_T) NULL; -+ P_P2P_CONNECTION_SETTINGS_T prP2pConnSetting = (P_P2P_CONNECTION_SETTINGS_T) NULL; -+ UINT_8 ucBufferSize = 0, ucIdx = 0, ucChannelSelected = 0; -+ -+ do { -+ ASSERT_BREAK(prAdapter != NULL); -+ -+ if (fgIsDefaultChannel) -+ ucChannelSelected = P2P_DEFAULT_LISTEN_CHANNEL; -+ -+ prP2pConnSetting = prAdapter->rWifiVar.prP2PConnSettings; -+ ucBufferSize = prP2pConnSetting->ucRfChannelListSize; -+ prChannelEntry = (P_CHANNEL_ENTRY_FIELD_T) prP2pConnSetting->aucChannelEntriesField; -+ -+ while ((ucBufferSize != 0) && (!fgIsResultAvailable)) { -+ -+ for (ucIdx = 0; ucIdx < prChannelEntry->ucNumberOfChannels; ucIdx++) { -+ if ((!fgIsSocialChannel) || -+ (prChannelEntry->aucChannelList[ucIdx] == 1) || -+ (prChannelEntry->aucChannelList[ucIdx] == 6) || -+ (prChannelEntry->aucChannelList[ucIdx] == 11)) { -+ -+ if (prChannelEntry->aucChannelList[ucIdx] <= 11) { -+ /* 2.4G. */ -+ ucChannelSelected = prChannelEntry->aucChannelList[ucIdx]; -+ } else if ((prChannelEntry->aucChannelList[ucIdx] < 52) && -+ (prChannelEntry->aucChannelList[ucIdx] > 14)) { -+ /* 2.4G + 5G. */ -+ ucChannelSelected = prChannelEntry->aucChannelList[ucIdx]; -+ } -+ -+ if (ucChannelSelected == ucCheckChnl) { -+ fgIsResultAvailable = TRUE; -+ break; -+ } -+ } -+ -+ } -+ -+ ucBufferSize -= (P2P_ATTRI_LEN_CHANNEL_ENTRY + prChannelEntry->ucNumberOfChannels); -+ -+ prChannelEntry = (P_CHANNEL_ENTRY_FIELD_T) ((ULONG) prChannelEntry + -+ P2P_ATTRI_LEN_CHANNEL_ENTRY + -+ (ULONG) prChannelEntry->ucNumberOfChannels); -+ -+ } -+ -+ if ((!fgIsResultAvailable) && (pucSuggestChannel != NULL)) { -+ DBGLOG(P2P, TRACE, -+ "The request channel %d is not available, sugguested channel:%d\n", ucCheckChnl, -+ ucChannelSelected); -+ /* Given a suggested channel. */ -+ *pucSuggestChannel = ucChannelSelected; -+ } -+ -+ } while (FALSE); -+ -+ return fgIsResultAvailable; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+ENUM_CHNL_EXT_T rlmDecideScoForAP(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo) -+{ -+ P_DOMAIN_SUBBAND_INFO prSubband; -+ P_DOMAIN_INFO_ENTRY prDomainInfo; -+ UINT_8 ucSecondChannel, i, j; -+ ENUM_CHNL_EXT_T eSCO; -+ -+ eSCO = CHNL_EXT_SCN; -+ -+ if (prBssInfo->eBand == BAND_2G4) { -+ if (prBssInfo->ucPrimaryChannel != 14) -+ eSCO = (prBssInfo->ucPrimaryChannel > 7) ? CHNL_EXT_SCB : CHNL_EXT_SCA; -+ } else { -+ prDomainInfo = rlmDomainGetDomainInfo(prAdapter); -+ ASSERT(prDomainInfo); -+ -+ for (i = 0; i < MAX_SUBBAND_NUM; i++) { -+ prSubband = &prDomainInfo->rSubBand[i]; -+ if (prSubband->ucBand == prBssInfo->eBand) { -+ for (j = 0; j < prSubband->ucNumChannels; j++) { -+ if ((prSubband->ucFirstChannelNum + j * prSubband->ucChannelSpan) -+ == prBssInfo->ucPrimaryChannel) { -+ eSCO = (j & 1) ? CHNL_EXT_SCB : CHNL_EXT_SCA; -+ break; -+ } -+ } -+ -+ if (j < prSubband->ucNumChannels) -+ break; /* Found */ -+ } -+ } -+ } -+ -+ /* Check if it is boundary channel and 40MHz BW is permitted */ -+ if (eSCO != CHNL_EXT_SCN) { -+ ucSecondChannel = (eSCO == CHNL_EXT_SCA) ? -+ (prBssInfo->ucPrimaryChannel + 4) : (prBssInfo->ucPrimaryChannel - 4); -+ -+ if (!rlmDomainIsLegalChannel(prAdapter, prBssInfo->eBand, ucSecondChannel)) -+ eSCO = CHNL_EXT_SCN; -+ } -+ -+ return eSCO; -+} -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_rlm_obss.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_rlm_obss.c -new file mode 100644 -index 000000000000..154f1e5db0f7 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_rlm_obss.c -@@ -0,0 +1,313 @@ -+/* -+** Id: @(#) gl_p2p_cfg80211.c@@ -+*/ -+ -+/*! \file gl_p2p_cfg80211.c -+ \brief Main routines of Linux driver interface for Wi-Fi Direct -+ using cfg80211 interface -+ -+ This file contains the main routines of Linux driver for MediaTek Inc. 802.11 -+ Wireless LAN Adapters. -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#include "precomp.h" -+ -+static UINT_8 rlmObssChnlLevelIn2G4(P_BSS_INFO_T prBssInfo, UINT_8 ucPriChannel, ENUM_CHNL_EXT_T eExtend); -+ -+static UINT_8 rlmObssChnlLevelIn5G(P_BSS_INFO_T prBssInfo, UINT_8 ucPriChannel, ENUM_CHNL_EXT_T eExtend); -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Different concurrent network has itself channel lists, and -+* concurrent networks should have been recorded in channel lists. -+* If role of active P2P is GO, assume associated AP of AIS will -+* record our Beacon for P2P GO because of same channel. -+* -+* Note: If we have scenario of different channel in the future, -+* the internal FW communication channel shall be established. -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT_8 rlmObssChnlLevel(P_BSS_INFO_T prBssInfo, ENUM_BAND_T eBand, UINT_8 ucPriChannel, ENUM_CHNL_EXT_T eExtend) -+{ -+ UINT_8 ucChannelLevel; -+ -+ ASSERT(prBssInfo); -+ -+ if (eBand == BAND_2G4) { -+ ucChannelLevel = rlmObssChnlLevelIn2G4(prBssInfo, ucPriChannel, eExtend); -+ -+ /* (TBD) If concurrent networks permit different channel, extra -+ * channel judgement should be added. Please refer to -+ * previous version of this file. -+ */ -+ } else if (eBand == BAND_5G) { -+ ucChannelLevel = rlmObssChnlLevelIn5G(prBssInfo, ucPriChannel, eExtend); -+ -+ /* (TBD) If concurrent networks permit different channel, extra -+ * channel judgement should be added. Please refer to -+ * previous version of this file. -+ */ -+ } else { -+ ucChannelLevel = CHNL_LEVEL0; -+ } -+ -+ return ucChannelLevel; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+static UINT_8 rlmObssChnlLevelIn2G4(P_BSS_INFO_T prBssInfo, UINT_8 ucPriChannel, ENUM_CHNL_EXT_T eExtend) -+{ -+ UINT_8 i, ucChannelLevel; -+ UINT_8 ucSecChannel, ucCenterChannel; -+ UINT_8 ucAffectedChnl_L, ucAffectedChnl_H; -+ -+ ASSERT(prBssInfo); -+ -+ ucChannelLevel = CHNL_LEVEL2; -+ -+ /* Calculate center channel for 2.4G band */ -+ if (eExtend == CHNL_EXT_SCA) { -+ ucCenterChannel = ucPriChannel + 2; -+ ucSecChannel = ucPriChannel + 4; -+ } else if (eExtend == CHNL_EXT_SCB) { -+ ucCenterChannel = ucPriChannel - 2; -+ ucSecChannel = ucPriChannel - 4; -+ } else { -+ return CHNL_LEVEL0; -+ } -+ ASSERT(ucCenterChannel >= 1 && ucCenterChannel <= 14); -+ -+ /* Calculated low/upper channels in affected freq range */ -+ ucAffectedChnl_L = (ucCenterChannel <= AFFECTED_CHNL_OFFSET) ? 1 : (ucCenterChannel - AFFECTED_CHNL_OFFSET); -+ -+ ucAffectedChnl_H = (ucCenterChannel >= (14 - AFFECTED_CHNL_OFFSET)) ? -+ 14 : (ucCenterChannel + AFFECTED_CHNL_OFFSET); -+ -+ /* Check intolerant (Non-HT) channel list */ -+ ASSERT(prBssInfo->auc2G_NonHtChnlList[0] <= CHNL_LIST_SZ_2G); -+ for (i = 1; i <= prBssInfo->auc2G_NonHtChnlList[0] && i <= CHNL_LIST_SZ_2G; i++) { -+ if ((prBssInfo->auc2G_NonHtChnlList[i] >= ucAffectedChnl_L && -+ prBssInfo->auc2G_NonHtChnlList[i] <= ucAffectedChnl_H) && -+ prBssInfo->auc2G_NonHtChnlList[i] != ucPriChannel) { -+ -+ ucChannelLevel = CHNL_LEVEL0; -+ goto L_2G4_level_end; -+ } -+ } -+ -+ /* Check 20M BW request channel list */ -+ ASSERT(prBssInfo->auc2G_20mReqChnlList[0] <= CHNL_LIST_SZ_2G); -+ for (i = 1; i <= prBssInfo->auc2G_20mReqChnlList[0] && i <= CHNL_LIST_SZ_2G; i++) { -+ if ((prBssInfo->auc2G_20mReqChnlList[i] >= ucAffectedChnl_L && -+ prBssInfo->auc2G_20mReqChnlList[i] <= ucAffectedChnl_H)) { -+ -+ ucChannelLevel = CHNL_LEVEL0; -+ goto L_2G4_level_end; -+ } -+ } -+ -+ /* Check 2.4G primary channel list */ -+ ASSERT(prBssInfo->auc2G_PriChnlList[0] <= CHNL_LIST_SZ_2G); -+ for (i = 1; i <= prBssInfo->auc2G_PriChnlList[0] && i <= CHNL_LIST_SZ_2G; i++) { -+ if ((prBssInfo->auc2G_PriChnlList[i] >= ucAffectedChnl_L && -+ prBssInfo->auc2G_PriChnlList[i] <= ucAffectedChnl_H) && -+ prBssInfo->auc2G_PriChnlList[i] != ucPriChannel) { -+ -+ ucChannelLevel = CHNL_LEVEL0; -+ goto L_2G4_level_end; -+ } -+ } -+ -+ /* Check 2.4G secondary channel list */ -+ ASSERT(prBssInfo->auc2G_SecChnlList[0] <= CHNL_LIST_SZ_2G); -+ for (i = 1; i <= prBssInfo->auc2G_SecChnlList[0] && i <= CHNL_LIST_SZ_2G; i++) { -+ if ((prBssInfo->auc2G_SecChnlList[i] >= ucAffectedChnl_L && -+ prBssInfo->auc2G_SecChnlList[i] <= ucAffectedChnl_H) && -+ prBssInfo->auc2G_SecChnlList[i] != ucSecChannel) { -+ -+ ucChannelLevel = CHNL_LEVEL0; -+ goto L_2G4_level_end; -+ } -+ } -+ -+L_2G4_level_end: -+ -+ return ucChannelLevel; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+static UINT_8 rlmObssChnlLevelIn5G(P_BSS_INFO_T prBssInfo, UINT_8 ucPriChannel, ENUM_CHNL_EXT_T eExtend) -+{ -+ UINT_8 i, ucChannelLevel; -+ UINT_8 ucSecChannel; -+ -+ ASSERT(prBssInfo); -+ -+ ucChannelLevel = CHNL_LEVEL2; -+ -+ /* Calculate center channel for 2.4G band */ -+ if (eExtend == CHNL_EXT_SCA) -+ ucSecChannel = ucPriChannel + 4; -+ else if (eExtend == CHNL_EXT_SCB) -+ ucSecChannel = ucPriChannel - 4; -+ else -+ return CHNL_LEVEL0; -+ ASSERT(ucSecChannel >= 36); -+ -+ /* Check 5G primary channel list */ -+ ASSERT(prBssInfo->auc5G_PriChnlList[0] <= CHNL_LIST_SZ_5G); -+ for (i = 1; i <= prBssInfo->auc5G_PriChnlList[0] && i <= CHNL_LIST_SZ_5G; i++) { -+ if (prBssInfo->auc5G_PriChnlList[i] == ucSecChannel) { -+ -+ ucChannelLevel = CHNL_LEVEL0; -+ goto L_5G_level_end; -+ } else if (prBssInfo->auc5G_PriChnlList[i] == ucPriChannel) { -+ ucChannelLevel = CHNL_LEVEL1; -+ } -+ } -+ -+ /* Check non-HT channel list */ -+ ASSERT(prBssInfo->auc5G_NonHtChnlList[0] <= CHNL_LIST_SZ_5G); -+ for (i = 1; i <= prBssInfo->auc5G_NonHtChnlList[0] && i <= CHNL_LIST_SZ_5G; i++) { -+ if (prBssInfo->auc5G_NonHtChnlList[i] == ucSecChannel) { -+ -+ ucChannelLevel = CHNL_LEVEL0; -+ goto L_5G_level_end; -+ } else if (prBssInfo->auc5G_NonHtChnlList[i] == ucPriChannel) { -+ ucChannelLevel = CHNL_LEVEL1; -+ } -+ } -+ -+ /* Check secondary channel list */ -+ ASSERT(prBssInfo->auc5G_SecChnlList[0] <= CHNL_LIST_SZ_5G); -+ for (i = 1; i <= prBssInfo->auc5G_SecChnlList[0] && i <= CHNL_LIST_SZ_5G; i++) { -+ if (prBssInfo->auc5G_SecChnlList[i] == ucPriChannel) { -+ -+ ucChannelLevel = CHNL_LEVEL0; -+ goto L_5G_level_end; -+ } -+ } -+ -+L_5G_level_end: -+ -+ return ucChannelLevel; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rlmObssScanExemptionRsp(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo, P_SW_RFB_T prSwRfb) -+{ -+ P_MSDU_INFO_T prMsduInfo; -+ P_ACTION_20_40_COEXIST_FRAME prTxFrame; -+ -+ /* To do: need an algorithm to do judgement. Now always reject request */ -+ -+ prMsduInfo = (P_MSDU_INFO_T)cnmMgtPktAlloc(prAdapter, PUBLIC_ACTION_MAX_LEN); -+ if (prMsduInfo == NULL) -+ return; -+ -+ DBGLOG(RLM, INFO, "Send 20/40 coexistence rsp frame!\n"); -+ -+ prTxFrame = (P_ACTION_20_40_COEXIST_FRAME) prMsduInfo->prPacket; -+ -+ prTxFrame->u2FrameCtrl = MAC_FRAME_ACTION; -+ COPY_MAC_ADDR(prTxFrame->aucDestAddr, ((P_ACTION_20_40_COEXIST_FRAME) prSwRfb->pvHeader)->aucSrcAddr); -+ COPY_MAC_ADDR(prTxFrame->aucSrcAddr, prBssInfo->aucOwnMacAddr); -+ COPY_MAC_ADDR(prTxFrame->aucBSSID, prBssInfo->aucBSSID); -+ -+ prTxFrame->ucCategory = CATEGORY_PUBLIC_ACTION; -+ prTxFrame->ucAction = ACTION_PUBLIC_20_40_COEXIST; -+ -+ /* To do: find correct algorithm */ -+ prTxFrame->rBssCoexist.ucId = ELEM_ID_20_40_BSS_COEXISTENCE; -+ prTxFrame->rBssCoexist.ucLength = 1; -+ prTxFrame->rBssCoexist.ucData = 0; -+ -+ ASSERT((WLAN_MAC_HEADER_LEN + 5) <= PUBLIC_ACTION_MAX_LEN); -+ -+ prMsduInfo->ucPacketType = HIF_TX_PACKET_TYPE_MGMT; -+ prMsduInfo->ucStaRecIndex = prSwRfb->ucStaRecIdx; -+ prMsduInfo->ucNetworkType = prBssInfo->ucNetTypeIndex; -+ prMsduInfo->ucMacHeaderLength = WLAN_MAC_MGMT_HEADER_LEN; -+ prMsduInfo->fgIs802_1x = FALSE; -+ prMsduInfo->fgIs802_11 = TRUE; -+ prMsduInfo->u2FrameLength = WLAN_MAC_MGMT_HEADER_HTC_LEN + 5; -+ prMsduInfo->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter); -+ prMsduInfo->pfTxDoneHandler = NULL; -+ prMsduInfo->fgIsBasicRate = FALSE; -+ -+ /* Send them to HW queue */ -+ nicTxEnqueueMsdu(prAdapter, prMsduInfo); -+} -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_scan.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_scan.c -new file mode 100644 -index 000000000000..b5bd23965fe3 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_scan.c -@@ -0,0 +1,756 @@ -+/* -+** Id: @(#) p2p_scan.c@@ -+*/ -+ -+/*! \file "p2p_scan.c" -+ \brief This file defines the p2p scan profile and the processing function of -+ scan result for SCAN Module. -+ -+ The SCAN Profile selection is part of SCAN MODULE and responsible for defining -+ SCAN Parameters - e.g. MIN_CHANNEL_TIME, number of scan channels. -+ In this file we also define the process of SCAN Result including adding, searching -+ and removing SCAN record from the list. -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+#include "precomp.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+P_P2P_DEVICE_DESC_T -+scanSearchTargetP2pDesc(IN P_ADAPTER_T prAdapter, IN UINT_8 aucDeviceID[], IN PP_BSS_DESC_T pprBssDesc) -+{ -+ -+ P_P2P_DEVICE_DESC_T prTargetP2pDesc = (P_P2P_DEVICE_DESC_T) NULL; -+ P_SCAN_INFO_T prScanInfo = (P_SCAN_INFO_T) NULL; -+ P_LINK_T prBSSDescList; -+ P_BSS_DESC_T prBssDesc = (P_BSS_DESC_T) NULL; -+ -+ ASSERT(prAdapter); -+ ASSERT(aucDeviceID); -+ -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ prBSSDescList = &prScanInfo->rBSSDescList; -+ -+ /* 4 <1> The outer loop to search for a candidate. */ -+ LINK_FOR_EACH_ENTRY(prBssDesc, prBSSDescList, rLinkEntry, BSS_DESC_T) { -+ -+ /* Loop for each prBssDesc */ -+ prTargetP2pDesc = scanFindP2pDeviceDesc(prAdapter, prBssDesc, aucDeviceID, TRUE, FALSE); -+ -+ if (prTargetP2pDesc != NULL) -+ break; -+ } -+ -+ if ((pprBssDesc) && (prTargetP2pDesc != NULL)) { -+ /* Only valid if prTargetP2pDesc is not NULL. */ -+ *pprBssDesc = prBssDesc; -+ } -+ -+ return prTargetP2pDesc; -+} /* scanSearchTargetP2pDesc */ -+ -+VOID scanInvalidAllP2pClientDevice(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBssDesc) -+{ -+ P_LINK_ENTRY_T prLinkEntry = (P_LINK_ENTRY_T) NULL; -+ P_P2P_DEVICE_DESC_T prTargetDesc = (P_P2P_DEVICE_DESC_T) NULL; -+ -+ LINK_FOR_EACH(prLinkEntry, &prBssDesc->rP2pDeviceList) { -+ prTargetDesc = LINK_ENTRY(prLinkEntry, P2P_DEVICE_DESC_T, rLinkEntry); -+ -+ if (prTargetDesc->fgDevInfoValid) -+ prTargetDesc->fgDevInfoValid = FALSE; -+ } -+ -+} /* scanRenewP2pClientDevice */ -+ -+VOID scanRemoveInvalidP2pClientDevice(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBssDesc) -+{ -+ P_LINK_ENTRY_T prLinkEntry = (P_LINK_ENTRY_T) NULL, prNexEntry = (P_LINK_ENTRY_T) NULL; -+ P_P2P_DEVICE_DESC_T prTargetDesc = (P_P2P_DEVICE_DESC_T) NULL; -+ P_P2P_CONNECTION_SETTINGS_T prP2pConnSettings = (P_P2P_CONNECTION_SETTINGS_T) NULL; -+ -+ prP2pConnSettings = prAdapter->rWifiVar.prP2PConnSettings; -+ -+ LINK_FOR_EACH_SAFE(prLinkEntry, prNexEntry, &prBssDesc->rP2pDeviceList) { -+ prTargetDesc = LINK_ENTRY(prLinkEntry, P2P_DEVICE_DESC_T, rLinkEntry); -+ -+ if (!prTargetDesc->fgDevInfoValid) { -+ LINK_REMOVE_KNOWN_ENTRY(&prBssDesc->rP2pDeviceList, prLinkEntry); -+ if ((prP2pConnSettings) && (prP2pConnSettings->prTargetP2pDesc == prTargetDesc)) -+ prP2pConnSettings->prTargetP2pDesc = NULL; -+ kalMemFree(prTargetDesc, VIR_MEM_TYPE, sizeof(P2P_DEVICE_DESC_T)); -+ } -+ } -+ -+} /* scanRenewP2pClientDevice */ -+ -+P_P2P_DEVICE_DESC_T -+scanFindP2pDeviceDesc(IN P_ADAPTER_T prAdapter, -+ IN P_BSS_DESC_T prBssDesc, -+ IN UINT_8 aucMacAddr[], IN BOOLEAN fgIsDeviceAddr, IN BOOLEAN fgAddIfNoFound) -+{ -+ -+ P_P2P_DEVICE_DESC_T prTargetDesc = (P_P2P_DEVICE_DESC_T) NULL; -+ P_LINK_ENTRY_T prLinkEntry = (P_LINK_ENTRY_T) NULL; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prBssDesc != NULL) && (aucMacAddr != NULL)); -+ -+ LINK_FOR_EACH(prLinkEntry, &prBssDesc->rP2pDeviceList) { -+ prTargetDesc = LINK_ENTRY(prLinkEntry, P2P_DEVICE_DESC_T, rLinkEntry); -+ -+ if (fgIsDeviceAddr) { -+ if (EQUAL_MAC_ADDR(prTargetDesc->aucDeviceAddr, aucMacAddr)) -+ break; -+ } else { -+ if (EQUAL_MAC_ADDR(prTargetDesc->aucInterfaceAddr, aucMacAddr)) -+ break; -+ } -+ -+ prTargetDesc = NULL; -+ } -+ -+ if ((fgAddIfNoFound) && (prTargetDesc == NULL)) { -+ /* Target Not Found. */ -+ /* TODO: Use memory pool in the future. */ -+ prTargetDesc = kalMemAlloc(sizeof(P2P_DEVICE_DESC_T), VIR_MEM_TYPE); -+ -+ if (prTargetDesc) { -+ kalMemZero(prTargetDesc, sizeof(P2P_DEVICE_DESC_T)); -+ LINK_ENTRY_INITIALIZE(&(prTargetDesc->rLinkEntry)); -+ COPY_MAC_ADDR(prTargetDesc->aucDeviceAddr, aucMacAddr); -+ LINK_INSERT_TAIL(&prBssDesc->rP2pDeviceList, &prTargetDesc->rLinkEntry); -+ prTargetDesc->fgDevInfoValid = TRUE; -+ } else { -+ ASSERT(FALSE); -+ } -+ } -+ -+ } while (FALSE); -+ -+ return prTargetDesc; -+} /* scanFindP2pDeviceDesc */ -+ -+P_P2P_DEVICE_DESC_T scanGetP2pDeviceDesc(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBssDesc) -+{ -+ -+ P_P2P_DEVICE_DESC_T prTargetDesc = (P_P2P_DEVICE_DESC_T) NULL; -+ -+ ASSERT(prAdapter); -+ ASSERT(prBssDesc); -+ -+ if (prBssDesc->prP2pDesc == NULL) { -+ -+ prTargetDesc = kalMemAlloc(sizeof(P2P_DEVICE_DESC_T), VIR_MEM_TYPE); -+ -+ if (prTargetDesc) { -+ kalMemZero(prTargetDesc, sizeof(P2P_DEVICE_DESC_T)); -+ LINK_ENTRY_INITIALIZE(&(prTargetDesc->rLinkEntry)); -+ LINK_INSERT_TAIL(&prBssDesc->rP2pDeviceList, &prTargetDesc->rLinkEntry); -+ prTargetDesc->fgDevInfoValid = TRUE; -+ prBssDesc->prP2pDesc = prTargetDesc; -+ /* We are not sure the SrcAddr is Device Address or Interface Address. */ -+ COPY_MAC_ADDR(prTargetDesc->aucDeviceAddr, prBssDesc->aucSrcAddr); -+ COPY_MAC_ADDR(prTargetDesc->aucInterfaceAddr, prBssDesc->aucSrcAddr); -+ } else { -+ -+ ASSERT(FALSE); -+ } -+ } else { -+ prTargetDesc = prBssDesc->prP2pDesc; -+ } -+ -+ return prTargetDesc; -+ -+} /* scanFindP2pDeviceDesc */ -+ -+#if 0 -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Convert the Beacon or ProbeResp Frame in SW_RFB_T to Event Packet -+* -+* @param[in] prSwRfb Pointer to the receiving SW_RFB_T structure. -+* -+* @retval WLAN_STATUS_SUCCESS It is a valid Scan Result and been sent to the host. -+* @retval WLAN_STATUS_FAILURE It is not a valid Scan Result. -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN scanUpdateP2pDeviceDesc(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBssDesc) -+{ -+ P_P2P_DEVICE_DESC_T prP2pDesc = (P_P2P_DEVICE_DESC_T) NULL; -+ P_P2P_ATTRIBUTE_T prP2pAttribute = (P_P2P_ATTRIBUTE_T) NULL; -+ UINT_16 u2AttributeLen = 0; -+ UINT_32 u4Idx = 0; -+ BOOLEAN fgUpdateDevInfo = FALSE; -+ -+ P_DEVICE_NAME_TLV_T prP2pDevName = (P_DEVICE_NAME_TLV_T) NULL; -+ P_P2P_ATTRI_GROUP_INFO_T prP2pAttriGroupInfo = (P_P2P_ATTRI_GROUP_INFO_T) NULL; -+ -+ ASSERT(prAdapter); -+ -+ prP2pDesc = scanGetP2pDeviceDesc(prAdapter, prBssDesc); -+ -+ if (!prP2pDesc) { -+ ASSERT(FALSE); -+ return fgUpdateDevInfo; -+ } -+ -+ p2pGetP2PAttriList(prAdapter, prBssDesc->aucIEBuf, prBssDesc->u2IELength, (PPUINT_8) & prP2pAttribute, -+ &u2AttributeLen); -+ -+ while (u2AttributeLen >= P2P_ATTRI_HDR_LEN) { -+ switch (prP2pAttribute->ucId) { -+ case P2P_ATTRI_ID_P2P_CAPABILITY: /* Beacon, Probe Response */ -+ { -+ P_P2P_ATTRI_CAPABILITY_T prP2pAttriCapability = (P_P2P_ATTRI_CAPABILITY_T) NULL; -+ -+ prP2pAttriCapability = (P_P2P_ATTRI_CAPABILITY_T) prP2pAttribute; -+ ASSERT(prP2pAttriCapability->u2Length == 2); -+ -+ prP2pDesc->ucDeviceCapabilityBitmap = prP2pAttriCapability->ucDeviceCap; -+ prP2pDesc->ucGroupCapabilityBitmap = prP2pAttriCapability->ucGroupCap; -+ } -+ break; -+ case P2P_ATTRI_ID_P2P_DEV_ID: /* Beacon */ -+ { -+ P_P2P_ATTRI_DEV_ID_T prP2pAttriDevID = (P_P2P_ATTRI_DEV_ID_T) NULL; -+ -+ prP2pAttriDevID = (P_P2P_ATTRI_DEV_ID_T) prP2pAttribute; -+ ASSERT(prP2pAttriDevID->u2Length == P2P_ATTRI_MAX_LEN_P2P_DEV_ID); -+ -+ kalMemCopy(prP2pDesc->aucDeviceAddr, prP2pAttriDevID->aucDevAddr, MAC_ADDR_LEN); -+ } -+ break; -+ case P2P_ATTRI_ID_P2P_DEV_INFO: /* Probe Response */ -+ { -+ P_P2P_ATTRI_DEV_INFO_T prP2pAttriDevInfo = (P_P2P_ATTRI_DEV_INFO_T) NULL; -+ P_P2P_DEVICE_TYPE_T prP2pDevType = (P_P2P_DEVICE_TYPE_T) NULL; -+ UINT_16 u2NameLen = 0, u2Id = 0; -+ -+ fgUpdateDevInfo = TRUE; -+ -+ prP2pAttriDevInfo = (P_P2P_ATTRI_DEV_INFO_T) prP2pAttribute; -+ -+ kalMemCopy(prP2pDesc->aucDeviceAddr, prP2pAttriDevInfo->aucDevAddr, MAC_ADDR_LEN); -+ -+ WLAN_GET_FIELD_BE16(&prP2pAttriDevInfo->u2ConfigMethodsBE, &prP2pDesc->u2ConfigMethod); -+ -+ prP2pDevType = &prP2pDesc->rPriDevType; -+ WLAN_GET_FIELD_BE16(&prP2pAttriDevInfo->rPrimaryDevTypeBE.u2CategoryId, -+ &prP2pDevType->u2CategoryID); -+ WLAN_GET_FIELD_BE16(&prP2pAttriDevInfo->rPrimaryDevTypeBE.u2SubCategoryId, -+ &prP2pDevType->u2SubCategoryID); -+ -+ ASSERT(prP2pAttriDevInfo->ucNumOfSecondaryDevType <= -+ P2P_GC_MAX_CACHED_SEC_DEV_TYPE_COUNT); -+ /* TODO: Fixme if secondary device type is more than 2. */ -+ prP2pDesc->ucSecDevTypeNum = 0; -+ for (u4Idx = 0; u4Idx < prP2pAttriDevInfo->ucNumOfSecondaryDevType; u4Idx++) { -+ if (u4Idx < P2P_GC_MAX_CACHED_SEC_DEV_TYPE_COUNT) { -+ prP2pDevType = &(prP2pDesc->arSecDevType[u4Idx]); -+ WLAN_GET_FIELD_BE16(&prP2pAttriDevInfo-> -+ arSecondaryDevTypeListBE[u4Idx].u2CategoryId, -+ &prP2pDevType->u2CategoryID); -+ WLAN_GET_FIELD_BE16(&prP2pAttriDevInfo-> -+ arSecondaryDevTypeListBE[u4Idx].u2SubCategoryId, -+ &prP2pDevType->u2SubCategoryID); -+ prP2pDesc->ucSecDevTypeNum++; -+ } -+ -+ } -+ prP2pDevName = -+ (P_DEVICE_NAME_TLV_T) ((PUINT_8) prP2pAttriDevInfo->arSecondaryDevTypeListBE + -+ (u4Idx * sizeof(DEVICE_TYPE_T))); -+ WLAN_GET_FIELD_BE16(&prP2pDevName->u2Length, &u2NameLen); -+ WLAN_GET_FIELD_BE16(&prP2pDevName->u2Id, &u2Id); -+ ASSERT(u2Id == WPS_ATTRI_ID_DEVICE_NAME); -+ if (u2NameLen > WPS_ATTRI_MAX_LEN_DEVICE_NAME) -+ u2NameLen = WPS_ATTRI_MAX_LEN_DEVICE_NAME; -+ prP2pDesc->u2NameLength = u2NameLen; -+ kalMemCopy(prP2pDesc->aucName, prP2pDevName->aucName, prP2pDesc->u2NameLength); -+ } -+ break; -+ case P2P_ATTRI_ID_P2P_GROUP_INFO: /* Probe Response */ -+ prP2pAttriGroupInfo = (P_P2P_ATTRI_GROUP_INFO_T) prP2pAttribute; -+ break; -+ case P2P_ATTRI_ID_NOTICE_OF_ABSENCE: -+ break; -+ case P2P_ATTRI_ID_EXT_LISTEN_TIMING: -+ /* TODO: Not implement yet. */ -+ /* ASSERT(FALSE); */ -+ break; -+ default: -+ break; -+ } -+ -+ u2AttributeLen -= (prP2pAttribute->u2Length + P2P_ATTRI_HDR_LEN); -+ -+ prP2pAttribute = -+ (P_P2P_ATTRIBUTE_T) ((UINT_32) prP2pAttribute + (prP2pAttribute->u2Length + P2P_ATTRI_HDR_LEN)); -+ -+ } -+ -+ if (prP2pAttriGroupInfo != NULL) { -+ P_P2P_CLIENT_INFO_DESC_T prClientInfoDesc = (P_P2P_CLIENT_INFO_DESC_T) NULL; -+ P_P2P_DEVICE_TYPE_T prP2pDevType = (P_P2P_DEVICE_TYPE_T) NULL; -+ -+ scanInvalidAllP2pClientDevice(prAdapter, prBssDesc); -+ -+ /* GO/Device itself. */ -+ prP2pDesc->fgDevInfoValid = TRUE; -+ -+ prClientInfoDesc = (P_P2P_CLIENT_INFO_DESC_T) prP2pAttriGroupInfo->arClientDesc; -+ u2AttributeLen = prP2pAttriGroupInfo->u2Length; -+ -+ while (u2AttributeLen > 0) { -+ prP2pDesc = -+ scanFindP2pDeviceDesc(prAdapter, prBssDesc, prClientInfoDesc->aucDevAddr, TRUE, TRUE); -+ -+ if (!prP2pDesc) { -+ ASSERT(FALSE); -+ break; /* while */ -+ } -+ -+ prP2pDesc->fgDevInfoValid = TRUE; -+ -+ /* Basic size for P2P client info descriptor. */ -+ ASSERT(u2AttributeLen >= 25); -+ if (u2AttributeLen < 25) { -+ DBGLOG(P2P, WARN, "Length incorrect warning.\n"); -+ break; -+ } -+ COPY_MAC_ADDR(prP2pDesc->aucInterfaceAddr, prClientInfoDesc->aucIfAddr); -+ -+ prP2pDesc->ucDeviceCapabilityBitmap = prClientInfoDesc->ucDeviceCap; -+ -+ WLAN_GET_FIELD_BE16(&prClientInfoDesc->u2ConfigMethodsBE, &prP2pDesc->u2ConfigMethod); -+ -+ prP2pDevType = &(prP2pDesc->rPriDevType); -+ WLAN_GET_FIELD_BE16(&prClientInfoDesc->rPrimaryDevTypeBE.u2CategoryId, -+ &prP2pDevType->u2CategoryID); -+ WLAN_GET_FIELD_BE16(&prClientInfoDesc->rPrimaryDevTypeBE.u2SubCategoryId, -+ &prP2pDevType->u2SubCategoryID); -+ -+ ASSERT(prClientInfoDesc->ucNumOfSecondaryDevType <= P2P_GC_MAX_CACHED_SEC_DEV_TYPE_COUNT); -+ prP2pDesc->ucSecDevTypeNum = 0; -+ for (u4Idx = 0; u4Idx < prClientInfoDesc->ucNumOfSecondaryDevType; u4Idx++) { -+ if (u4Idx < P2P_GC_MAX_CACHED_SEC_DEV_TYPE_COUNT) { -+ prP2pDevType = &(prP2pDesc->arSecDevType[u4Idx]); -+ WLAN_GET_FIELD_BE16(&prClientInfoDesc-> -+ arSecondaryDevTypeListBE[u4Idx].u2CategoryId, -+ &prP2pDevType->u2CategoryID); -+ WLAN_GET_FIELD_BE16(&prClientInfoDesc-> -+ arSecondaryDevTypeListBE[u4Idx].u2SubCategoryId, -+ &prP2pDevType->u2SubCategoryID); -+ prP2pDesc->ucSecDevTypeNum++; -+ } -+ -+ } -+ prP2pDevName = -+ (P_DEVICE_NAME_TLV_T) (prClientInfoDesc->arSecondaryDevTypeListBE + -+ (u4Idx * sizeof(DEVICE_TYPE_T))); -+ WLAN_GET_FIELD_BE16(&prP2pDevName->u2Length, &prP2pDesc->u2NameLength); -+ if (prP2pDesc->u2NameLength > WPS_ATTRI_MAX_LEN_DEVICE_NAME) -+ prP2pDesc->u2NameLength = WPS_ATTRI_MAX_LEN_DEVICE_NAME; -+ -+ kalMemCopy(prP2pDesc->aucName, prP2pDevName->aucName, prP2pDesc->u2NameLength); -+ -+ u2AttributeLen -= (prClientInfoDesc->ucLength + P2P_CLIENT_INFO_DESC_HDR_LEN); -+ prClientInfoDesc = -+ (P_P2P_CLIENT_INFO_DESC_T) ((UINT_32) prClientInfoDesc + -+ (UINT_32) prClientInfoDesc->ucLength + -+ P2P_CLIENT_INFO_DESC_HDR_LEN); -+ } -+ -+ scanRemoveInvalidP2pClientDevice(prAdapter, prBssDesc); -+ } -+ -+ return fgUpdateDevInfo; -+} /* end of scanAddP2pDeviceInfo() */ -+ -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Convert the Beacon or ProbeResp Frame in SW_RFB_T to Event Packet -+* -+* @param[in] prSwRfb Pointer to the receiving SW_RFB_T structure. -+* -+* @retval WLAN_STATUS_SUCCESS It is a valid Scan Result and been sent to the host. -+* @retval WLAN_STATUS_FAILURE It is not a valid Scan Result. -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS scanSendDeviceDiscoverEvent(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBssDesc, IN P_SW_RFB_T prSwRfb) -+{ -+ EVENT_P2P_DEV_DISCOVER_RESULT_T rEventDevInfo; -+#if 1 -+ P_LINK_ENTRY_T prLinkEntry = (P_LINK_ENTRY_T) NULL; -+ P_P2P_DEVICE_DESC_T prTargetDesc = (P_P2P_DEVICE_DESC_T) NULL; -+ -+ LINK_FOR_EACH(prLinkEntry, &prBssDesc->rP2pDeviceList) { -+ prTargetDesc = LINK_ENTRY(prLinkEntry, P2P_DEVICE_DESC_T, rLinkEntry); -+ -+ COPY_MAC_ADDR(rEventDevInfo.aucDeviceAddr, prTargetDesc->aucDeviceAddr); -+ COPY_MAC_ADDR(rEventDevInfo.aucInterfaceAddr, prTargetDesc->aucInterfaceAddr); -+ -+ rEventDevInfo.ucDeviceCapabilityBitmap = prTargetDesc->ucDeviceCapabilityBitmap; -+ rEventDevInfo.ucGroupCapabilityBitmap = prTargetDesc->ucGroupCapabilityBitmap; -+ rEventDevInfo.u2ConfigMethod = prTargetDesc->u2ConfigMethod; -+ -+ kalMemCopy(&rEventDevInfo.rPriDevType, &prTargetDesc->rPriDevType, sizeof(P2P_DEVICE_TYPE_T)); -+ -+ kalMemCopy(rEventDevInfo.arSecDevType, -+ prTargetDesc->arSecDevType, (prTargetDesc->ucSecDevTypeNum * sizeof(P2P_DEVICE_TYPE_T))); -+ -+ rEventDevInfo.ucSecDevTypeNum = prTargetDesc->ucSecDevTypeNum; -+ -+ rEventDevInfo.u2NameLength = prTargetDesc->u2NameLength; -+ kalMemCopy(rEventDevInfo.aucName, prTargetDesc->aucName, prTargetDesc->u2NameLength); -+ -+ COPY_MAC_ADDR(rEventDevInfo.aucBSSID, prBssDesc->aucBSSID); -+ -+ if (prTargetDesc == prBssDesc->prP2pDesc) -+ nicRxAddP2pDevice(prAdapter, &rEventDevInfo, prBssDesc->aucIEBuf, prBssDesc->u2IELength); -+ else -+ nicRxAddP2pDevice(prAdapter, &rEventDevInfo, NULL, 0); -+ } -+ -+ kalP2PIndicateFound(prAdapter->prGlueInfo); -+ -+#else -+ -+ P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo = (P_P2P_SPECIFIC_BSS_INFO_T) NULL; -+ P_P2P_ATTRIBUTE_T prP2pAttribute = (P_P2P_ATTRIBUTE_T) NULL; -+ UINT_16 u2AttributeLen = 0; -+ UINT_32 u4Idx = 0; -+ P_P2P_ATTRI_GROUP_INFO_T prP2pAttriGroupInfo = (P_P2P_ATTRI_GROUP_INFO_T) NULL; -+ P_DEVICE_NAME_TLV_T prP2pDevName = (P_DEVICE_NAME_TLV_T) NULL; -+ -+ ASSERT(prAdapter); -+ -+ prP2pSpecificBssInfo = &prAdapter->rWifiVar.rP2pSpecificBssInfo; -+ -+#if 1 -+ p2pGetP2PAttriList(prAdapter, prBssDesc->aucIEBuf, prBssDesc->u2IELength, (PPUINT_8) & prP2pAttribute, -+ &u2AttributeLen); -+#else -+ prP2pAttribute = (P_P2P_ATTRIBUTE_T) &prP2pSpecificBssInfo->aucAttributesCache[0]; -+ u2AttributeLen = prP2pSpecificBssInfo->u2AttributeLen; -+#endif -+ rEventDevInfo.fgDevInfoValid = FALSE; -+ -+ while (u2AttributeLen >= P2P_ATTRI_HDR_LEN) { -+ switch (prP2pAttribute->ucId) { -+ case P2P_ATTRI_ID_P2P_CAPABILITY: -+ { -+ P_P2P_ATTRI_CAPABILITY_T prP2pAttriCapability = (P_P2P_ATTRI_CAPABILITY_T) NULL; -+ -+ prP2pAttriCapability = (P_P2P_ATTRI_CAPABILITY_T) prP2pAttribute; -+ ASSERT(prP2pAttriCapability->u2Length == 2); -+ rEventDevInfo.ucDeviceCapabilityBitmap = prP2pAttriCapability->ucDeviceCap; -+ rEventDevInfo.ucGroupCapabilityBitmap = prP2pAttriCapability->ucGroupCap; -+ } -+ break; -+ case P2P_ATTRI_ID_P2P_DEV_ID: -+ { -+ P_P2P_ATTRI_DEV_ID_T prP2pAttriDevID = (P_P2P_ATTRI_DEV_ID_T) NULL; -+ -+ prP2pAttriDevID = (P_P2P_ATTRI_DEV_ID_T) prP2pAttribute; -+ ASSERT(prP2pAttriDevID->u2Length == 6); -+ kalMemCopy(rEventDevInfo.aucCommunicateAddr, prP2pAttriDevID->aucDevAddr, MAC_ADDR_LEN); -+ } -+ break; -+ case P2P_ATTRI_ID_P2P_DEV_INFO: -+ { -+ P_P2P_ATTRI_DEV_INFO_T prP2pAttriDevInfo = (P_P2P_ATTRI_DEV_INFO_T) NULL; -+ P_P2P_DEVICE_TYPE_T prP2pDevType = (P_P2P_DEVICE_TYPE_T) NULL; -+ -+ prP2pAttriDevInfo = (P_P2P_ATTRI_DEV_INFO_T) prP2pAttribute; -+ rEventDevInfo.fgDevInfoValid = TRUE; -+ kalMemCopy(rEventDevInfo.aucCommunicateAddr, prP2pAttriDevInfo->aucDevAddr, -+ MAC_ADDR_LEN); -+ rEventDevInfo.u2ConfigMethod = prP2pAttriDevInfo->u2ConfigMethodsBE; -+ -+ prP2pDevType = &rEventDevInfo.rPriDevType; -+ prP2pDevType->u2CategoryID = prP2pAttriDevInfo->rPrimaryDevTypeBE.u2CategoryId; -+ prP2pDevType->u2SubCategoryID = prP2pAttriDevInfo->rPrimaryDevTypeBE.u2SubCategoryId; -+ -+ ASSERT(prP2pAttriDevInfo->ucNumOfSecondaryDevType <= 2); -+ /* TODO: Fixme if secondary device type is more than 2. */ -+ for (u4Idx = 0; u4Idx < prP2pAttriDevInfo->ucNumOfSecondaryDevType; u4Idx++) { -+ /* TODO: Current sub device type can only support 2. */ -+ prP2pDevType = &rEventDevInfo.arSecDevType[u4Idx]; -+ prP2pDevType->u2CategoryID = prP2pAttriDevInfo->rPrimaryDevTypeBE.u2CategoryId; -+ prP2pDevType->u2SubCategoryID = -+ prP2pAttriDevInfo->rPrimaryDevTypeBE.u2SubCategoryId; -+ } -+ -+ prP2pDevName = -+ (P_DEVICE_NAME_TLV_T) (prP2pAttriDevInfo->arSecondaryDevTypeListBE + -+ (u4Idx * sizeof(DEVICE_TYPE_T))); -+ ASSERT(prP2pDevName->u2Id == 0x1011); -+ ASSERT(prP2pDevName->u2Length <= 32); -+ /* TODO: Fixme if device name length is longer than 32 bytes. */ -+ kalMemCopy(rEventDevInfo.aucName, prP2pDevName->aucName, prP2pDevName->u2Length); -+ } -+ break; -+ case P2P_ATTRI_ID_P2P_GROUP_INFO: -+ prP2pAttriGroupInfo = (P_P2P_ATTRI_GROUP_INFO_T) prP2pAttribute; -+ break; -+ } -+ -+ u2AttributeLen -= (prP2pAttribute->u2Length + P2P_ATTRI_HDR_LEN); -+ -+ prP2pAttribute = -+ (P_P2P_ATTRIBUTE_T) ((UINT_32) prP2pAttribute + (prP2pAttribute->u2Length + P2P_ATTRI_HDR_LEN)); -+ -+ } -+ -+ nicRxAddP2pDevice(prAdapter, &rEventDevInfo); -+ -+ if (prP2pAttriGroupInfo != NULL) { -+ P_P2P_CLIENT_INFO_DESC_T prClientInfoDesc = (P_P2P_CLIENT_INFO_DESC_T) NULL; -+ P_P2P_DEVICE_TYPE_T prP2pDevType = (P_P2P_DEVICE_TYPE_T) NULL; -+ -+ prClientInfoDesc = prP2pAttriGroupInfo->arClientDesc; -+ u2AttributeLen = prP2pAttriGroupInfo->u2Length; -+ -+ while (u2AttributeLen > 0) { -+ /* Basic size for P2P client info descriptor. */ -+ ASSERT(u2AttributeLen >= 25); -+ rEventDevInfo.fgDevInfoValid = TRUE; -+ kalMemCopy(rEventDevInfo.aucCommunicateAddr, prClientInfoDesc->aucIfAddr, MAC_ADDR_LEN); -+ rEventDevInfo.ucDeviceCapabilityBitmap = prClientInfoDesc->ucDeviceCap; -+ rEventDevInfo.u2ConfigMethod = prClientInfoDesc->u2ConfigMethodsBE; -+ -+ prP2pDevType = &rEventDevInfo.rPriDevType; -+ prP2pDevType->u2CategoryID = prClientInfoDesc->rPrimaryDevTypeBE.u2CategoryId; -+ prP2pDevType->u2SubCategoryID = prClientInfoDesc->rPrimaryDevTypeBE.u2SubCategoryId; -+ -+ ASSERT(prClientInfoDesc->ucNumOfSecondaryDevType <= 2); -+ /* TODO: Fixme if secondary device type is more than 2. */ -+ for (u4Idx = 0; u4Idx < prClientInfoDesc->ucNumOfSecondaryDevType; u4Idx++) { -+ /* TODO: Current sub device type can only support 2. */ -+ prP2pDevType = &rEventDevInfo.arSecDevType[u4Idx]; -+ prP2pDevType->u2CategoryID = -+ prClientInfoDesc->arSecondaryDevTypeListBE[u4Idx].u2CategoryId; -+ prP2pDevType->u2SubCategoryID = -+ prClientInfoDesc->arSecondaryDevTypeListBE[u4Idx].u2SubCategoryId; -+ } -+ -+ prP2pDevName = -+ (P_DEVICE_NAME_TLV_T) (prClientInfoDesc->arSecondaryDevTypeListBE + -+ (u4Idx * sizeof(DEVICE_TYPE_T))); -+ ASSERT(prP2pDevName->u2Id == 0x1011); -+ ASSERT(prP2pDevName->u2Length <= 32); -+ /* TODO: Fixme if device name length is longer than 32 bytes. */ -+ kalMemCopy(&rEventDevInfo.aucName, prP2pDevName->aucName, prP2pDevName->u2Length); -+ -+ nicRxAddP2pDevice(prAdapter, &rEventDevInfo); -+ -+ u2AttributeLen -= prP2pAttriGroupInfo->u2Length; -+ prP2pAttriGroupInfo = prP2pAttriGroupInfo + prP2pAttriGroupInfo->u2Length + 1; -+ } -+ -+ } -+#endif -+ return WLAN_STATUS_SUCCESS; -+} /* scanSendDeviceDiscoverEvent */ -+ -+VOID -+scanP2pProcessBeaconAndProbeResp(IN P_ADAPTER_T prAdapter, -+ IN P_SW_RFB_T prSwRfb, -+ IN P_WLAN_STATUS prStatus, -+ IN P_BSS_DESC_T prBssDesc, IN P_WLAN_BEACON_FRAME_T prWlanBeaconFrame) -+{ -+ BOOLEAN fgIsSkipThisBeacon; -+ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; -+ P_P2P_CONNECTION_SETTINGS_T prP2pConnSettings = (P_P2P_CONNECTION_SETTINGS_T) NULL; -+ -+ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); -+ prP2pConnSettings = prAdapter->rWifiVar.prP2PConnSettings; -+ fgIsSkipThisBeacon = FALSE; -+ if (prBssDesc->fgIsP2PPresent) { -+ if ((prP2pBssInfo->eCurrentOPMode == OP_MODE_INFRASTRUCTURE) && /* P2P GC */ -+ (prP2pBssInfo->eConnectionState == PARAM_MEDIA_STATE_CONNECTED) && /* Connected */ -+ ((prWlanBeaconFrame->u2FrameCtrl & MASK_FRAME_TYPE) == MAC_FRAME_BEACON)) { /* TX Beacon */ -+ -+ fgIsSkipThisBeacon = TRUE; -+ } -+ -+ if ((!prP2pBssInfo->ucDTIMPeriod) && /* First time. */ -+ fgIsSkipThisBeacon && (EQUAL_SSID(prBssDesc->aucSSID, prBssDesc->ucSSIDLen, -+ prP2pConnSettings->aucSSID, prP2pConnSettings->ucSSIDLen))) { /* SSID Match */ -+ prP2pBssInfo->ucDTIMPeriod = prBssDesc->ucDTIMPeriod; -+ nicPmIndicateBssConnected(prAdapter, NETWORK_TYPE_P2P_INDEX); -+ } -+ -+ do { -+ RF_CHANNEL_INFO_T rChannelInfo; -+ -+ ASSERT_BREAK((prSwRfb != NULL) && (prBssDesc != NULL)); -+ -+ if (((prWlanBeaconFrame->u2FrameCtrl & MASK_FRAME_TYPE) != MAC_FRAME_PROBE_RSP)) { -+ /* Only report Probe Response frame to supplicant. */ -+ /* Probe response collect much more information. */ -+ -+ if (fgIsSkipThisBeacon || prBssDesc->eBand == BAND_2G4) -+ break; -+ } -+ -+ rChannelInfo.ucChannelNum = prBssDesc->ucChannelNum; -+ rChannelInfo.eBand = prBssDesc->eBand; -+ prBssDesc->fgIsP2PReport = TRUE; -+ -+ DBGLOG(P2P, INFO, "indicate %s [%d]\n", prBssDesc->aucSSID, prBssDesc->ucChannelNum); -+ -+ kalP2PIndicateBssInfo(prAdapter->prGlueInfo, -+ (PUINT_8) prSwRfb->pvHeader, -+ (UINT_32) prSwRfb->u2PacketLen, -+ &rChannelInfo, RCPI_TO_dBm(prBssDesc->ucRCPI)); -+ -+ } while (FALSE); -+ } -+} -+ -+VOID scnEventReturnChannel(IN P_ADAPTER_T prAdapter, IN UINT_8 ucScnSeqNum) -+{ -+ -+ CMD_SCAN_CANCEL rCmdScanCancel; -+ -+ /* send cancel message to firmware domain */ -+ rCmdScanCancel.ucSeqNum = ucScnSeqNum; -+ rCmdScanCancel.ucIsExtChannel = (UINT_8) FALSE; -+ -+ wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SCAN_CANCEL, -+ TRUE, -+ FALSE, FALSE, NULL, NULL, sizeof(CMD_SCAN_CANCEL), (PUINT_8)&rCmdScanCancel, NULL, 0); -+ -+} /* scnEventReturnChannel */ -+ -+VOID scanRemoveAllP2pBssDesc(IN P_ADAPTER_T prAdapter) -+{ -+ P_LINK_T prBSSDescList; -+ P_BSS_DESC_T prBssDesc; -+ P_BSS_DESC_T prBSSDescNext; -+ -+ ASSERT(prAdapter); -+ -+ prBSSDescList = &(prAdapter->rWifiVar.rScanInfo.rBSSDescList); -+ -+ /* Search BSS Desc from current SCAN result list. */ -+ LINK_FOR_EACH_ENTRY_SAFE(prBssDesc, prBSSDescNext, prBSSDescList, rLinkEntry, BSS_DESC_T) { -+ scanRemoveP2pBssDesc(prAdapter, prBssDesc); -+ } -+} /* scanRemoveAllP2pBssDesc */ -+ -+VOID scanRemoveP2pBssDesc(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBssDesc) -+{ -+ -+ -+} /* scanRemoveP2pBssDesc */ -+ -+P_BSS_DESC_T -+scanP2pSearchDesc(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prP2pBssInfo, IN P_P2P_CONNECTION_REQ_INFO_T prConnReqInfo) -+{ -+ P_BSS_DESC_T prCandidateBssDesc = (P_BSS_DESC_T) NULL, prBssDesc = (P_BSS_DESC_T) NULL; -+ P_LINK_T prBssDescList = (P_LINK_T) NULL; -+ -+ do { -+ if ((prAdapter == NULL) || (prP2pBssInfo == NULL) || (prConnReqInfo == NULL)) -+ break; -+ -+ prBssDescList = &(prAdapter->rWifiVar.rScanInfo.rBSSDescList); -+ -+ DBGLOG(P2P, LOUD, "Connecting to BSSID: %pM\n", prConnReqInfo->aucBssid); -+ DBGLOG(P2P, LOUD, "Connecting to SSID:%s, length:%d\n", -+ prConnReqInfo->rSsidStruct.aucSsid, prConnReqInfo->rSsidStruct.ucSsidLen); -+ -+ LINK_FOR_EACH_ENTRY(prBssDesc, prBssDescList, rLinkEntry, BSS_DESC_T) { -+ DBGLOG(P2P, LOUD, "Checking BSS: %pM\n", prBssDesc->aucBSSID); -+ -+ if (prBssDesc->eBSSType != BSS_TYPE_INFRASTRUCTURE) { -+ DBGLOG(P2P, LOUD, "Ignore mismatch BSS type.\n"); -+ continue; -+ } -+ -+ if (UNEQUAL_MAC_ADDR(prBssDesc->aucBSSID, prConnReqInfo->aucBssid)) { -+ DBGLOG(P2P, LOUD, "Ignore mismatch BSSID.\n"); -+ continue; -+ } -+ -+ /* SSID should be the same? SSID is vary for each connection. so... */ -+ if (UNEQUAL_SSID(prConnReqInfo->rSsidStruct.aucSsid, -+ prConnReqInfo->rSsidStruct.ucSsidLen, -+ prBssDesc->aucSSID, prBssDesc->ucSSIDLen)) { -+ -+ DBGLOG(P2P, TRACE, -+ "Connecting to BSSID: %pM\n", prConnReqInfo->aucBssid); -+ DBGLOG(P2P, TRACE, -+ "Connecting to SSID:%s, length:%d\n", prConnReqInfo->rSsidStruct.aucSsid, -+ prConnReqInfo->rSsidStruct.ucSsidLen); -+ DBGLOG(P2P, TRACE, -+ "Checking SSID:%s, length:%d\n", prBssDesc->aucSSID, prBssDesc->ucSSIDLen); -+ DBGLOG(P2P, TRACE, "Ignore mismatch SSID, (But BSSID match).\n"); -+ ASSERT(FALSE); -+ continue; -+ } -+ -+ if (!prBssDesc->fgIsP2PPresent) { -+ DBGLOG(P2P, ERROR, "SSID, BSSID, BSSTYPE match, but no P2P IE present.\n"); -+ continue; -+ } -+ -+ /* Final decision. */ -+ prCandidateBssDesc = prBssDesc; -+ break; -+ } -+ -+ } while (FALSE); -+ -+ return prCandidateBssDesc; -+} /* scanP2pSearchDesc */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_state.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_state.c -new file mode 100644 -index 000000000000..befb9978f473 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/p2p_state.c -@@ -0,0 +1,466 @@ -+#include "p2p_precomp.h" -+ -+BOOLEAN -+p2pStateInit_IDLE(IN P_ADAPTER_T prAdapter, -+ IN P_P2P_FSM_INFO_T prP2pFsmInfo, IN P_BSS_INFO_T prP2pBssInfo, OUT P_ENUM_P2P_STATE_T peNextState) -+{ -+ BOOLEAN fgIsTransOut = FALSE; -+/* P_P2P_CHNL_REQ_INFO_T prChnlReqInfo = (P_P2P_CHNL_REQ_INFO_T)NULL; */ -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && -+ (prP2pFsmInfo != NULL) && (prP2pBssInfo != NULL) && (peNextState != NULL)); -+ -+ if ((prP2pBssInfo->eIntendOPMode == OP_MODE_ACCESS_POINT) -+ && IS_NET_PWR_STATE_ACTIVE(prAdapter, NETWORK_TYPE_P2P_INDEX)) { -+ P_P2P_CHNL_REQ_INFO_T prChnlReqInfo = &(prP2pFsmInfo->rChnlReqInfo); -+ -+ fgIsTransOut = TRUE; -+ prChnlReqInfo->eChannelReqType = CHANNEL_REQ_TYPE_GO_START_BSS; -+ -+ DBGLOG(P2P, INFO, "p2pStateInit_IDLE GO Scan\n"); -+ *peNextState = P2P_STATE_REQING_CHANNEL; -+ -+ } else { -+#if 0 -+ else -+ if (IS_NET_PWR_STATE_ACTIVE(prAdapter, NETWORK_TYPE_P2P_INDEX)) { -+ -+ ASSERT((prP2pBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT) || -+ (prP2pBssInfo->eCurrentOPMode == OP_MODE_INFRASTRUCTURE)); -+ -+ prChnlReqInfo = &prP2pFsmInfo->rChnlReqInfo; -+ -+ if (prChnlReqInfo->fgIsChannelRequested) { -+ /* Start a timer for return channel. */ -+ DBGLOG(P2P, TRACE, "start a GO channel timer.\n"); -+ } -+ -+ } -+#endif -+ cnmTimerStartTimer(prAdapter, &(prAdapter->rP2pFsmTimeoutTimer), 5000); -+ } -+ -+ } while (FALSE); -+ -+ return fgIsTransOut; -+} /* p2pStateInit_IDLE */ -+ -+VOID p2pStateAbort_IDLE(IN P_ADAPTER_T prAdapter, IN P_P2P_FSM_INFO_T prP2pFsmInfo, IN ENUM_P2P_STATE_T eNextState) -+{ -+ -+ P_P2P_CHNL_REQ_INFO_T prChnlReqInfo = (P_P2P_CHNL_REQ_INFO_T) NULL; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prP2pFsmInfo != NULL)); -+ -+ prChnlReqInfo = &prP2pFsmInfo->rChnlReqInfo; -+ -+ if (prChnlReqInfo->fgIsChannelRequested) { -+ /* Release channel before timeout. */ -+ p2pFuncReleaseCh(prAdapter, prChnlReqInfo); -+ } -+ -+ /* Stop timer for leaving this state. */ -+ cnmTimerStopTimer(prAdapter, &(prAdapter->rP2pFsmTimeoutTimer)); -+ -+ } while (FALSE); -+ -+} /* p2pStateAbort_IDLE */ -+ -+VOID p2pStateInit_CHNL_ON_HAND(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prP2pBssInfo, IN P_P2P_FSM_INFO_T prP2pFsmInfo) -+{ -+ P_P2P_CHNL_REQ_INFO_T prChnlReqInfo = (P_P2P_CHNL_REQ_INFO_T) NULL; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prP2pFsmInfo != NULL)); -+ -+ prChnlReqInfo = &(prP2pFsmInfo->rChnlReqInfo); -+ -+ /* Store the original channel info. */ -+ prChnlReqInfo->ucOriChnlNum = prP2pBssInfo->ucPrimaryChannel; -+ prChnlReqInfo->eOriBand = prP2pBssInfo->eBand; -+ prChnlReqInfo->eOriChnlSco = prP2pBssInfo->eBssSCO; -+ -+ /* RX Probe Request would check primary channel. */ -+ prP2pBssInfo->ucPrimaryChannel = prChnlReqInfo->ucReqChnlNum; -+ prP2pBssInfo->eBand = prChnlReqInfo->eBand; -+ prP2pBssInfo->eBssSCO = prChnlReqInfo->eChnlSco; -+ -+ DBGLOG(P2P, TRACE, "start a channel on hand timer.\n"); -+ if (prP2pFsmInfo->eListenExted != P2P_DEV_EXT_LISTEN_ING) { -+ cnmTimerStartTimer(prAdapter, &(prAdapter->rP2pFsmTimeoutTimer), -+ prChnlReqInfo->u4MaxInterval); -+ -+ kalP2PIndicateChannelReady(prAdapter->prGlueInfo, -+ prChnlReqInfo->u8Cookie, -+ prChnlReqInfo->ucReqChnlNum, -+ prChnlReqInfo->eBand, prChnlReqInfo->eChnlSco, prChnlReqInfo->u4MaxInterval); -+ } else -+ cnmTimerStartTimer(prAdapter, &(prAdapter->rP2pFsmTimeoutTimer), -+ (P2P_EXT_LISTEN_TIME_MS - prChnlReqInfo->u4MaxInterval)); -+ } while (FALSE); -+ -+} /* p2pStateInit_CHNL_ON_HAND */ -+ -+VOID -+p2pStateAbort_CHNL_ON_HAND(IN P_ADAPTER_T prAdapter, -+ IN P_P2P_FSM_INFO_T prP2pFsmInfo, -+ IN P_BSS_INFO_T prP2pBssInfo, IN ENUM_P2P_STATE_T eNextState) -+{ -+ P_P2P_CHNL_REQ_INFO_T prChnlReqInfo = (P_P2P_CHNL_REQ_INFO_T) NULL; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prP2pFsmInfo != NULL)); -+ -+ prChnlReqInfo = &(prP2pFsmInfo->rChnlReqInfo); -+ -+ cnmTimerStopTimer(prAdapter, &(prAdapter->rP2pFsmTimeoutTimer)); -+ -+ /* Restore the original channel info. */ -+ prP2pBssInfo->ucPrimaryChannel = prChnlReqInfo->ucOriChnlNum; -+ prP2pBssInfo->eBand = prChnlReqInfo->eOriBand; -+ prP2pBssInfo->eBssSCO = prChnlReqInfo->eOriChnlSco; -+ -+ DBGLOG(P2P, INFO, "p2p state trans abort chann on hand, eListenExted: %d, eNextState: %d\n", -+ prP2pFsmInfo->eListenExted, eNextState); -+ if (prP2pFsmInfo->eListenExted != P2P_DEV_EXT_LISTEN_ING || -+ eNextState != P2P_STATE_CHNL_ON_HAND) { -+ /* Here maybe have a bug, when it's extlistening, a new remain_on_channel -+ was sent to driver? need to verify */ -+ prP2pFsmInfo->eListenExted = P2P_DEV_NOT_EXT_LISTEN; -+ /* Indicate channel return. */ -+ kalP2PIndicateChannelExpired(prAdapter->prGlueInfo, &prP2pFsmInfo->rChnlReqInfo); -+ -+ /* Return Channel. */ -+ p2pFuncReleaseCh(prAdapter, &(prP2pFsmInfo->rChnlReqInfo)); -+ } -+ -+ } while (FALSE); -+} /* p2pStateAbort_CHNL_ON_HAND */ -+ -+VOID -+p2pStateAbort_REQING_CHANNEL(IN P_ADAPTER_T prAdapter, IN P_P2P_FSM_INFO_T prP2pFsmInfo, IN ENUM_P2P_STATE_T eNextState) -+{ -+ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; -+ P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo = (P_P2P_SPECIFIC_BSS_INFO_T) NULL; -+ -+ do { -+ -+ ASSERT_BREAK((prAdapter != NULL) && (prP2pFsmInfo != NULL) && (eNextState < P2P_STATE_NUM)); -+ -+ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); -+ prP2pSpecificBssInfo = prAdapter->rWifiVar.prP2pSpecificBssInfo; -+ -+ if (eNextState == P2P_STATE_IDLE) { -+ if (prP2pBssInfo->eIntendOPMode == OP_MODE_ACCESS_POINT) { -+ /* Intend to be AP. */ -+ /* Setup for AP mode. */ -+ p2pFuncStartGO(prAdapter, -+ prP2pBssInfo, -+ prP2pSpecificBssInfo->aucGroupSsid, -+ prP2pSpecificBssInfo->u2GroupSsidLen, -+ prP2pSpecificBssInfo->ucPreferredChannel, -+ prP2pSpecificBssInfo->eRfBand, -+ prP2pSpecificBssInfo->eRfSco, prP2pFsmInfo->fgIsApMode); -+ -+ } else { -+ /* Return Channel. */ -+ p2pFuncReleaseCh(prAdapter, &(prP2pFsmInfo->rChnlReqInfo)); -+ } -+ -+ } -+ -+ } while (FALSE); -+ -+} /* p2pStateInit_AP_CHANNEL_DETECT */ -+ -+VOID p2pStateInit_AP_CHANNEL_DETECT(IN P_ADAPTER_T prAdapter, IN P_P2P_FSM_INFO_T prP2pFsmInfo) -+{ -+ P_P2P_SCAN_REQ_INFO_T prScanReqInfo = (P_P2P_SCAN_REQ_INFO_T) NULL; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prP2pFsmInfo != NULL)); -+ -+ prScanReqInfo = &(prP2pFsmInfo->rScanReqInfo); -+ -+ prScanReqInfo->eScanType = SCAN_TYPE_PASSIVE_SCAN; -+ prScanReqInfo->eChannelSet = SCAN_CHANNEL_2G4; -+ prScanReqInfo->u2PassiveDewellTime = 50; /* 50ms for passive channel load detection */ -+ prScanReqInfo->fgIsAbort = TRUE; -+ prScanReqInfo->fgIsScanRequest = TRUE; -+ prScanReqInfo->ucNumChannelList = 0; -+ prScanReqInfo->u4BufLength = 0; -+ prScanReqInfo->rSsidStruct.ucSsidLen = 0; -+ -+ p2pFuncRequestScan(prAdapter, prScanReqInfo); -+ -+ } while (FALSE); -+ -+} /* p2pStateInit_AP_CHANNEL_DETECT */ -+ -+VOID -+p2pStateAbort_AP_CHANNEL_DETECT(IN P_ADAPTER_T prAdapter, -+ IN P_P2P_FSM_INFO_T prP2pFsmInfo, -+ IN P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo, IN ENUM_P2P_STATE_T eNextState) -+{ -+ P_P2P_CHNL_REQ_INFO_T prChnlReqInfo = (P_P2P_CHNL_REQ_INFO_T) NULL; -+ P_P2P_CONNECTION_SETTINGS_T prP2pConnSettings = (P_P2P_CONNECTION_SETTINGS_T) NULL; -+ -+ do { -+ -+ if (eNextState == P2P_STATE_REQING_CHANNEL) { -+ UINT_8 ucPreferedChnl = 0; -+ ENUM_BAND_T eBand = BAND_NULL; -+ ENUM_CHNL_EXT_T eSco = CHNL_EXT_SCN; -+ -+ prChnlReqInfo = &(prP2pFsmInfo->rChnlReqInfo); -+ -+ /* Determine the channel for AP. */ -+ if (cnmPreferredChannel(prAdapter, &eBand, &ucPreferedChnl, &eSco) == FALSE) { -+ -+ prP2pConnSettings = prAdapter->rWifiVar.prP2PConnSettings; -+ ucPreferedChnl = prP2pConnSettings->ucOperatingChnl; -+ if (ucPreferedChnl == 0) { -+ -+ if (scnQuerySparseChannel(prAdapter, &eBand, &ucPreferedChnl) == FALSE) { -+ -+ /* What to do? */ -+ ASSERT(FALSE); -+ /* TODO: Pick up a valid channel from channel list. */ -+ ucPreferedChnl = 1; -+ eBand = BAND_2G4; -+ } -+ } -+ } -+ -+ prChnlReqInfo->eChannelReqType = CHANNEL_REQ_TYPE_GO_START_BSS; -+ -+ DBGLOG(P2P, INFO, "p2pStateAbort_AP_CHANNEL_DETECT GO Scan\n"); -+ prChnlReqInfo->ucReqChnlNum = prP2pSpecificBssInfo->ucPreferredChannel = ucPreferedChnl; -+ prChnlReqInfo->eBand = prP2pSpecificBssInfo->eRfBand = eBand; -+ prChnlReqInfo->eChnlSco = prP2pSpecificBssInfo->eRfSco = eSco; -+ } else { -+ p2pFuncCancelScan(prAdapter, &(prP2pFsmInfo->rScanReqInfo)); -+ } -+ -+ } while (FALSE); -+ -+} /* p2pStateAbort_AP_CHANNEL_DETECT */ -+ -+VOID p2pStateInit_SCAN(IN P_ADAPTER_T prAdapter, IN P_P2P_FSM_INFO_T prP2pFsmInfo) -+{ -+ P_P2P_SCAN_REQ_INFO_T prScanReqInfo = (P_P2P_SCAN_REQ_INFO_T) NULL; -+ -+ do { -+ -+ ASSERT_BREAK((prAdapter != NULL) && (prP2pFsmInfo != NULL)); -+ -+ prScanReqInfo = &prP2pFsmInfo->rScanReqInfo; -+ -+ prScanReqInfo->fgIsScanRequest = TRUE; -+ -+ p2pFuncRequestScan(prAdapter, prScanReqInfo); -+ -+ } while (FALSE); -+ -+} /* p2pStateInit_SCAN */ -+ -+VOID p2pStateAbort_SCAN(IN P_ADAPTER_T prAdapter, IN P_P2P_FSM_INFO_T prP2pFsmInfo, IN ENUM_P2P_STATE_T eNextState) -+{ -+ do { -+ ASSERT_BREAK(prAdapter != NULL); -+ -+ /* 1. Scan cancel. (Make sure the scan request is invalid. */ -+ p2pFuncCancelScan(prAdapter, &(prP2pFsmInfo->rScanReqInfo)); -+ -+ /* Scan done indication. */ -+ kalP2PIndicateScanDone(prAdapter->prGlueInfo, prP2pFsmInfo->rScanReqInfo.fgIsAbort); -+ } while (FALSE); -+ -+} /* p2pStateAbort_SCAN */ -+ -+VOID -+p2pStateInit_GC_JOIN(IN P_ADAPTER_T prAdapter, -+ IN P_P2P_FSM_INFO_T prP2pFsmInfo, -+ IN P_BSS_INFO_T prP2pBssInfo, IN P_P2P_JOIN_INFO_T prJoinInfo, IN P_BSS_DESC_T prBssDesc) -+{ -+ P_MSG_JOIN_REQ_T prJoinReqMsg = (P_MSG_JOIN_REQ_T) NULL; -+ P_STA_RECORD_T prStaRec = (P_STA_RECORD_T) NULL; -+ P_P2P_CONNECTION_SETTINGS_T prP2pConnSettings = (P_P2P_CONNECTION_SETTINGS_T) NULL; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && -+ (prP2pFsmInfo != NULL) && -+ (prP2pBssInfo != NULL) && (prJoinInfo != NULL) && (prBssDesc != NULL)); -+ -+ prP2pConnSettings = prAdapter->rWifiVar.prP2PConnSettings; -+ -+ if (prBssDesc->ucSSIDLen) { -+ COPY_SSID(prP2pConnSettings->aucSSID, -+ prP2pConnSettings->ucSSIDLen, prBssDesc->aucSSID, prBssDesc->ucSSIDLen); -+ } -+ /* Setup a join timer. */ -+ DBGLOG(P2P, TRACE, "Start a join init timer\n"); -+ cnmTimerStartTimer(prAdapter, -+ &(prAdapter->rP2pFsmTimeoutTimer), -+ (prP2pFsmInfo->u4GrantInterval - AIS_JOIN_CH_GRANT_THRESHOLD)); -+ -+ /* 2 <1> We are goin to connect to this BSS */ -+ prBssDesc->fgIsConnecting = TRUE; -+ -+ /* 2 <2> Setup corresponding STA_RECORD_T */ -+ prStaRec = bssCreateStaRecFromBssDesc(prAdapter, -+ (prBssDesc->fgIsP2PPresent ? (STA_TYPE_P2P_GO) -+ : (STA_TYPE_LEGACY_AP)), NETWORK_TYPE_P2P_INDEX, prBssDesc); -+ -+ if (prStaRec == NULL) { -+ DBGLOG(P2P, TRACE, "Create station record fail\n"); -+ break; -+ } -+ -+ prJoinInfo->prTargetStaRec = prStaRec; -+ prJoinInfo->fgIsJoinComplete = FALSE; -+ prJoinInfo->u4BufLength = 0; -+ -+ /* 2 <2.1> Sync. to FW domain */ -+ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); -+ -+ if (prP2pBssInfo->eConnectionState == PARAM_MEDIA_STATE_DISCONNECTED) { -+ P_P2P_CONNECTION_SETTINGS_T prP2pConnSettings = (P_P2P_CONNECTION_SETTINGS_T) NULL; -+ -+ prStaRec->fgIsReAssoc = FALSE; -+ -+ prP2pConnSettings = prAdapter->rWifiVar.prP2PConnSettings; -+ -+ switch (prP2pConnSettings->eAuthMode) { -+ case AUTH_MODE_OPEN: /* Note: Omit break here. */ -+ case AUTH_MODE_WPA: -+ case AUTH_MODE_WPA_PSK: -+ case AUTH_MODE_WPA2: -+ case AUTH_MODE_WPA2_PSK: -+ prJoinInfo->ucAvailableAuthTypes = (UINT_8) AUTH_TYPE_OPEN_SYSTEM; -+ break; -+ case AUTH_MODE_SHARED: -+ prJoinInfo->ucAvailableAuthTypes = (UINT_8) AUTH_TYPE_SHARED_KEY; -+ break; -+ case AUTH_MODE_AUTO_SWITCH: -+ DBGLOG(P2P, LOUD, "JOIN INIT: eAuthMode == AUTH_MODE_AUTO_SWITCH\n"); -+ prJoinInfo->ucAvailableAuthTypes = (UINT_8) (AUTH_TYPE_OPEN_SYSTEM | -+ AUTH_TYPE_SHARED_KEY); -+ break; -+ default: -+ ASSERT(!(prP2pConnSettings->eAuthMode == AUTH_MODE_WPA_NONE)); -+ DBGLOG(P2P, ERROR, "JOIN INIT: Auth Algorithm : %d was not supported by JOIN\n", -+ prP2pConnSettings->eAuthMode); -+ /* TODO(Kevin): error handling ? */ -+ return; -+ } -+ prStaRec->ucTxAuthAssocRetryLimit = TX_AUTH_ASSOCI_RETRY_LIMIT; -+ } else { -+ ASSERT(FALSE); -+ /* TODO: Shall we considering ROAMIN case for P2P Device?. */ -+ } -+ -+ /* 2 <4> Use an appropriate Authentication Algorithm Number among the ucAvailableAuthTypes. */ -+ if (prJoinInfo->ucAvailableAuthTypes & (UINT_8) AUTH_TYPE_OPEN_SYSTEM) { -+ -+ DBGLOG(P2P, TRACE, "JOIN INIT: Try to do Authentication with AuthType == OPEN_SYSTEM.\n"); -+ -+ prJoinInfo->ucAvailableAuthTypes &= ~(UINT_8) AUTH_TYPE_OPEN_SYSTEM; -+ -+ prStaRec->ucAuthAlgNum = (UINT_8) AUTH_ALGORITHM_NUM_OPEN_SYSTEM; -+ } else if (prJoinInfo->ucAvailableAuthTypes & (UINT_8) AUTH_TYPE_SHARED_KEY) { -+ -+ DBGLOG(P2P, TRACE, "JOIN INIT: Try to do Authentication with AuthType == SHARED_KEY.\n"); -+ -+ prJoinInfo->ucAvailableAuthTypes &= ~(UINT_8) AUTH_TYPE_SHARED_KEY; -+ -+ prStaRec->ucAuthAlgNum = (UINT_8) AUTH_ALGORITHM_NUM_SHARED_KEY; -+ } else if (prJoinInfo->ucAvailableAuthTypes & (UINT_8) AUTH_TYPE_FAST_BSS_TRANSITION) { -+ -+ DBGLOG(P2P, TRACE, -+ "JOIN INIT: Try to do Authentication with AuthType == FAST_BSS_TRANSITION.\n"); -+ -+ prJoinInfo->ucAvailableAuthTypes &= ~(UINT_8) AUTH_TYPE_FAST_BSS_TRANSITION; -+ -+ prStaRec->ucAuthAlgNum = (UINT_8) AUTH_ALGORITHM_NUM_FAST_BSS_TRANSITION; -+ } else { -+ ASSERT(0); -+ } -+ -+ /* 4 <5> Overwrite Connection Setting for eConnectionPolicy == ANY (Used by Assoc Req) */ -+ if (prBssDesc->ucSSIDLen) { -+ COPY_SSID(prJoinInfo->rSsidStruct.aucSsid, -+ prJoinInfo->rSsidStruct.ucSsidLen, prBssDesc->aucSSID, prBssDesc->ucSSIDLen); -+ } -+ /* 2 <5> Backup desired channel. */ -+ -+ /* 2 <6> Send a Msg to trigger SAA to start JOIN process. */ -+ prJoinReqMsg = (P_MSG_JOIN_REQ_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_JOIN_REQ_T)); -+ -+ if (!prJoinReqMsg) { -+ DBGLOG(P2P, TRACE, "Allocation Join Message Fail\n"); -+ ASSERT(FALSE); -+ return; -+ } -+ -+ prJoinReqMsg->rMsgHdr.eMsgId = MID_P2P_SAA_FSM_START; -+ prJoinReqMsg->ucSeqNum = ++prJoinInfo->ucSeqNumOfReqMsg; -+ prJoinReqMsg->prStaRec = prStaRec; -+ -+ /* TODO: Consider fragmentation info in station record. */ -+ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prJoinReqMsg, MSG_SEND_METHOD_BUF); -+ -+ } while (FALSE); -+ -+} /* p2pStateInit_GC_JOIN */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Process of JOIN Abort. Leave JOIN State & Abort JOIN. -+* -+* @param (none) -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+p2pStateAbort_GC_JOIN(IN P_ADAPTER_T prAdapter, -+ IN P_P2P_FSM_INFO_T prP2pFsmInfo, IN P_P2P_JOIN_INFO_T prJoinInfo, IN ENUM_P2P_STATE_T eNextState) -+{ -+ P_MSG_JOIN_ABORT_T prJoinAbortMsg = (P_MSG_JOIN_ABORT_T) NULL; -+ -+ do { -+ ASSERT_BREAK((prAdapter != NULL) && (prP2pFsmInfo != NULL) && (prJoinInfo != NULL)); -+ -+ if (prJoinInfo->fgIsJoinComplete == FALSE) { -+ -+ prJoinAbortMsg = -+ (P_MSG_JOIN_ABORT_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_JOIN_ABORT_T)); -+ if (!prJoinAbortMsg) { -+ DBGLOG(P2P, TRACE, "Fail to allocate join abort message buffer\n"); -+ ASSERT(FALSE); -+ return; -+ } -+ -+ prJoinAbortMsg->rMsgHdr.eMsgId = MID_P2P_SAA_FSM_ABORT; -+ prJoinAbortMsg->ucSeqNum = prJoinInfo->ucSeqNumOfReqMsg; -+ prJoinAbortMsg->prStaRec = prJoinInfo->prTargetStaRec; -+ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prJoinAbortMsg, MSG_SEND_METHOD_BUF); -+ -+ } -+ -+ /* Stop Join Timer. */ -+ cnmTimerStopTimer(prAdapter, &(prAdapter->rP2pFsmTimeoutTimer)); -+ -+ /* Release channel requested. */ -+ p2pFuncReleaseCh(prAdapter, &(prP2pFsmInfo->rChnlReqInfo)); -+ -+ } while (FALSE); -+ -+ return; -+ -+} /* p2pStateAbort_GC_JOIN */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/privacy.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/privacy.c -new file mode 100644 -index 000000000000..72fa52e761da ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/privacy.c -@@ -0,0 +1,915 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/privacy.c#1 -+*/ -+ -+/*! \file "privacy.c" -+ \brief This file including the protocol layer privacy function. -+ -+ This file provided the macros and functions library support for the -+ protocol layer security setting from rsn.c and nic_privacy.c -+ -+*/ -+ -+/* -+** Log: privacy.c -+ * -+ * 11 10 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * change the debug module level. -+ * -+ * 10 20 2011 terry.wu -+ * NULL -+ * Fix Hotspot deauth send failed. -+ * -+ * 10 12 2011 wh.su -+ * [WCXRP00001036] [MT6620 Wi-Fi][Driver][FW] Adding the 802.11w code for MFP -+ * adding the 802.11w related function and define . -+ * -+ * 06 28 2011 tsaiyuan.hsu -+ * [WCXRP00000819] [MT6620 Wi-Fi][Driver] check if staRec is NULL or not in secCheckClassError -+ * check if staRec is NULL or not in secCheckClassError. -+ * -+ * 06 09 2011 tsaiyuan.hsu -+ * [WCXRP00000760] [MT5931 Wi-Fi][FW] Refine rxmHandleMacRxDone to reduce code size -+ * move send_auth at rxmHandleMacRxDone in firmware to driver to reduce code size. -+ * -+ * 01 25 2011 yuche.tsai -+ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record. -+ * Change Station Type in Station Record, Modify MACRO definition for getting station type & network type index & Role. -+ * -+ * 11 04 2010 wh.su -+ * [WCXRP00000164] [MT6620 Wi-Fi][Driver] Support the p2p random SSID -+ * adding the p2p random ssid support. -+ * -+ * 10 04 2010 cp.wu -+ * [WCXRP00000077] [MT6620 Wi-Fi][Driver][FW] Eliminate use of ENUM_NETWORK_TYPE_T -+ * and replaced by ENUM_NETWORK_TYPE_INDEX_T only -+ * remove ENUM_NETWORK_TYPE_T definitions -+ * -+ * 09 03 2010 kevin.huang -+ * NULL -+ * Refine #include sequence and solve recursive/nested #include issue -+ * -+ * 09 01 2010 wh.su -+ * NULL -+ * adding the wapi support for integration test. -+ * -+ * 07 24 2010 wh.su -+ * -+ * .support the Wi-Fi RSN -+ * -+ * 07 20 2010 wh.su -+ * -+ * adding the wapi code. -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 21 2010 wh.su -+ * [WPD00003840][MT6620 5931] Security migration -+ * modify some code for concurrent network. -+ * -+ * 06 21 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * enable RX management frame handling. -+ * -+ * 06 19 2010 wh.su -+ * [WPD00003840][MT6620 5931] Security migration -+ * adding the compiling flag for migration. -+ * -+ * 06 19 2010 wh.su -+ * [WPD00003840][MT6620 5931] Security migration -+ * consdier the concurrent network setting. -+ * -+ * 06 18 2010 wh.su -+ * [WPD00003840][MT6620 5931] Security migration -+ * migration the security related function from firmware. -+ * -+ * 05 28 2010 wh.su -+ * [BORA00000626][MT6620] Refine the remove key flow for WHQL testing -+ * fixed the ad-hoc wpa-none send non-encrypted frame issue. -+ * -+ * 05 24 2010 kevin.huang -+ * [BORA00000794][WIFISYS][New Feature]Power Management Support -+ * Refine authSendAuthFrame() for NULL STA_RECORD_T case and minimum deauth interval. -+ * -+ * 04 29 2010 wh.su -+ * [BORA00000637][MT6620 Wi-Fi] [Bug] WPA2 pre-authentication timer not correctly initialize -+ * adjsut the pre-authentication code. -+ * -+ * 04 22 2010 wh.su -+ * [BORA00000626][MT6620] Refine the remove key flow for WHQL testing -+ * fixed the wpi same key id rx issue and fixed the remove wep key issue. -+ * -+ * 04 19 2010 kevin.huang -+ * [BORA00000714][WIFISYS][New Feature]Beacon Timeout Support -+ * Add Send Deauth for Class 3 Error and Leave Network Support -+ * -+ * 04 15 2010 wh.su -+ * [BORA00000680][MT6620] Support the statistic for Micxxsoft os query -+ * remove the assert code for allow ad-hoc pkt. -+ * -+ * 04 13 2010 wh.su -+ * [BORA00000680][MT6620] Support the statistic for Micxxsoft os query -+ * fixed the Klocwork error and refine the class error message. -+ * -+ * 03 04 2010 wh.su -+ * [BORA00000605][WIFISYS] Phase3 Integration -+ * Code refine, and remove non-used code. -+ * -+ * 03 03 2010 wh.su -+ * [BORA00000637][MT6620 Wi-Fi] [Bug] WPA2 pre-authentication timer not correctly initialize -+ * move the AIS specific variable for security to AIS specific structure. -+ * -+ * 03 03 2010 wh.su -+ * [BORA00000637][MT6620 Wi-Fi] [Bug] WPA2 pre-authentication timer not correctly initialize -+ * Fixed the pre-authentication timer not correctly init issue, -+ * and modify the security related callback function prototype. -+ * -+ * 03 01 2010 wh.su -+ * [BORA00000605][WIFISYS] Phase3 Integration -+ * Refine the variable and parameter for security. -+ * -+ * 02 26 2010 wh.su -+ * [BORA00000626][MT6620] Refine the remove key flow for WHQL testing -+ * change the waning message shown level, and clear the global transmit flag for CMD INFRASTRUCTURE. -+ * -+ * 02 25 2010 wh.su -+ * [BORA00000626][MT6620] Refine the remove key flow for WHQL testing -+ * For support the WHQL test, do the remove key code refine. -+ * -+ * 01 27 2010 wh.su -+ * [BORA00000476][Wi-Fi][firmware] Add the security module initialize code -+ * add and fixed some security function. -+ * -+ * 12 25 2009 tehuang.liu -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Integrated modifications for 1st connection (mainly on FW modules MQM, TXM, and RXM) -+ * * * * * * * * * MQM: BA handling -+ * * * * * * * * * TXM: Macros updates -+ * * * * * * * * * RXM: Macros/Duplicate Removal updates -+ * -+ * 12 18 2009 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * . -+ * -+ * Dec 11 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * modify the cmd with result return -+ * -+ * Dec 11 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * fixed the value not initialize issue -+ * -+ * Dec 10 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * change the cmd return type -+ * -+ * Dec 8 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * adding the function to update the auth mode and encryption status for cmd build connection -+ * -+ * Dec 7 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * adding some code for wapi mode -+ * -+ * Dec 7 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * adding the call to check the 4th and eapol error report frame -+ * -+ * Dec 7 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * rename the function name -+ * -+ * Dec 4 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * adding the code for parsing the EAPoL frame, and do some code refine -+ * -+ * Dec 3 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * adding the class error check -+ * -+ * Dec 3 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * adding the cmd_802_11_pmkid code -+ * -+ * Dec 1 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * doing some function rename, and adding the code for cmd CMD_ADD_REMOVE_KEY -+ * -+ * Nov 23 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * adding the clear pmkid function -+ * -+ * Nov 23 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Fix eStaType check for AIS -+ * -+ * Nov 19 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * adding the ap selection related code -+ * -+ * Nov 18 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "precomp.h" -+ -+#if CFG_PRIVACY_MIGRATION -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to initialize the privacy-related -+* parameters. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* \param[in] ucNetTypeIdx Pointer to netowrk type index -+* -+* \retval NONE -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID secInit(IN P_ADAPTER_T prAdapter, IN UINT_8 ucNetTypeIdx) -+{ -+ UINT_8 i; -+ P_CONNECTION_SETTINGS_T prConnSettings; -+ P_BSS_INFO_T prBssInfo; -+ P_AIS_SPECIFIC_BSS_INFO_T prAisSpecBssInfo; -+ -+ DEBUGFUNC("secInit"); -+ -+ ASSERT(prAdapter); -+ -+ prConnSettings = &prAdapter->rWifiVar.rConnSettings; -+ prBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]; -+ prAisSpecBssInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo; -+ -+ prBssInfo->u4RsnSelectedGroupCipher = 0; -+ prBssInfo->u4RsnSelectedPairwiseCipher = 0; -+ prBssInfo->u4RsnSelectedAKMSuite = 0; -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ prBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]; -+ -+ prBssInfo->u4RsnSelectedGroupCipher = RSN_CIPHER_SUITE_CCMP; -+ prBssInfo->u4RsnSelectedPairwiseCipher = RSN_CIPHER_SUITE_CCMP; -+ prBssInfo->u4RsnSelectedAKMSuite = RSN_AKM_SUITE_PSK; -+#endif -+ -+#if CFG_ENABLE_BT_OVER_WIFI -+ prBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_BOW_INDEX]; -+ -+ prBssInfo->u4RsnSelectedGroupCipher = RSN_CIPHER_SUITE_CCMP; -+ prBssInfo->u4RsnSelectedPairwiseCipher = RSN_CIPHER_SUITE_CCMP; -+ prBssInfo->u4RsnSelectedAKMSuite = RSN_AKM_SUITE_PSK; -+#endif -+ -+ prAdapter->rMib.dot11RSNAConfigPairwiseCiphersTable[0].dot11RSNAConfigPairwiseCipher = WPA_CIPHER_SUITE_WEP40; -+ prAdapter->rMib.dot11RSNAConfigPairwiseCiphersTable[1].dot11RSNAConfigPairwiseCipher = WPA_CIPHER_SUITE_TKIP; -+ prAdapter->rMib.dot11RSNAConfigPairwiseCiphersTable[2].dot11RSNAConfigPairwiseCipher = WPA_CIPHER_SUITE_CCMP; -+ prAdapter->rMib.dot11RSNAConfigPairwiseCiphersTable[3].dot11RSNAConfigPairwiseCipher = WPA_CIPHER_SUITE_WEP104; -+ -+ prAdapter->rMib.dot11RSNAConfigPairwiseCiphersTable[4].dot11RSNAConfigPairwiseCipher = RSN_CIPHER_SUITE_WEP40; -+ prAdapter->rMib.dot11RSNAConfigPairwiseCiphersTable[5].dot11RSNAConfigPairwiseCipher = RSN_CIPHER_SUITE_TKIP; -+ prAdapter->rMib.dot11RSNAConfigPairwiseCiphersTable[6].dot11RSNAConfigPairwiseCipher = RSN_CIPHER_SUITE_CCMP; -+ prAdapter->rMib.dot11RSNAConfigPairwiseCiphersTable[7].dot11RSNAConfigPairwiseCipher = RSN_CIPHER_SUITE_WEP104; -+ -+ for (i = 0; i < MAX_NUM_SUPPORTED_CIPHER_SUITES; i++) -+ prAdapter->rMib.dot11RSNAConfigPairwiseCiphersTable[i].dot11RSNAConfigPairwiseCipherEnabled = FALSE; -+ -+ prAdapter->rMib.dot11RSNAConfigAuthenticationSuitesTable[0].dot11RSNAConfigAuthenticationSuite = -+ WPA_AKM_SUITE_NONE; -+ prAdapter->rMib.dot11RSNAConfigAuthenticationSuitesTable[1].dot11RSNAConfigAuthenticationSuite = -+ WPA_AKM_SUITE_802_1X; -+ prAdapter->rMib.dot11RSNAConfigAuthenticationSuitesTable[2].dot11RSNAConfigAuthenticationSuite = -+ WPA_AKM_SUITE_PSK; -+ prAdapter->rMib.dot11RSNAConfigAuthenticationSuitesTable[3].dot11RSNAConfigAuthenticationSuite = -+ RSN_AKM_SUITE_NONE; -+ prAdapter->rMib.dot11RSNAConfigAuthenticationSuitesTable[4].dot11RSNAConfigAuthenticationSuite = -+ RSN_AKM_SUITE_802_1X; -+ prAdapter->rMib.dot11RSNAConfigAuthenticationSuitesTable[5].dot11RSNAConfigAuthenticationSuite = -+ RSN_AKM_SUITE_PSK; -+ -+#if CFG_SUPPORT_802_11W -+ prAdapter->rMib.dot11RSNAConfigAuthenticationSuitesTable[6].dot11RSNAConfigAuthenticationSuite = -+ RSN_AKM_SUITE_802_1X_SHA256; -+ prAdapter->rMib.dot11RSNAConfigAuthenticationSuitesTable[7].dot11RSNAConfigAuthenticationSuite = -+ RSN_AKM_SUITE_PSK_SHA256; -+#endif -+ -+ for (i = 0; i < MAX_NUM_SUPPORTED_AKM_SUITES; i++) { -+ prAdapter->rMib.dot11RSNAConfigAuthenticationSuitesTable[i].dot11RSNAConfigAuthenticationSuiteEnabled = -+ FALSE; -+ } -+ -+ secClearPmkid(prAdapter); -+ -+ cnmTimerInitTimer(prAdapter, -+ &prAisSpecBssInfo->rPreauthenticationTimer, -+ (PFN_MGMT_TIMEOUT_FUNC) rsnIndicatePmkidCand, (ULONG) NULL); -+ -+#if CFG_SUPPORT_802_11W -+ cnmTimerInitTimer(prAdapter, -+ &prAisSpecBssInfo->rSaQueryTimer, (PFN_MGMT_TIMEOUT_FUNC) rsnStartSaQueryTimer, (ULONG) NULL); -+#endif -+ -+ prAisSpecBssInfo->fgCounterMeasure = FALSE; -+ prAisSpecBssInfo->ucWEPDefaultKeyID = 0; -+ -+#if 0 -+ for (i = 0; i < WTBL_SIZE; i++) { -+ g_prWifiVar->arWtbl[i].fgUsed = FALSE; -+ g_prWifiVar->arWtbl[i].prSta = NULL; -+ g_prWifiVar->arWtbl[i].ucNetTypeIdx = NETWORK_TYPE_INDEX_NUM; -+ -+ } -+ nicPrivacyInitialize((UINT_8) NETWORK_TYPE_INDEX_NUM); -+#endif -+} /* secInit */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will indicate an Event of "Rx Class Error" to SEC_FSM for -+* JOIN Module. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* \param[in] prSwRfb Pointer to the SW RFB. -+* -+* \return FALSE Class Error -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN secCheckClassError(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, IN P_STA_RECORD_T prStaRec) -+{ -+ ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex; -+ P_BSS_INFO_T prBssInfo; -+ -+ ASSERT(prAdapter); -+ ASSERT(prSwRfb); -+ -+ if (!prStaRec) -+ return FALSE; -+ -+ eNetTypeIndex = prStaRec->ucNetTypeIndex; -+ if (!IS_NET_ACTIVE(prAdapter, eNetTypeIndex)) -+ return FALSE; -+ -+ prBssInfo = &prAdapter->rWifiVar.arBssInfo[eNetTypeIndex]; -+ if ((STA_STATE_3 != prStaRec->ucStaState) && prBssInfo->fgIsNetAbsent == FALSE) { -+ /*(IS_AP_STA(prStaRec) || IS_CLIENT_STA(prStaRec))) { */ -+ -+#if 0 /* by scott's suggestions, do not put work-around in JB2,we need to find the root cause */ -+ /* work-around for CR ALPS00816361 */ -+ if (eNetTypeIndex == NETWORK_TYPE_P2P_INDEX) { -+ DBGLOG(RSN, INFO, -+ "p2p> skip to send Deauth to MAC:[%pM] for Rx Class 3.\n", -+ prStaRec->aucMacAddr); -+ return TRUE; -+ } -+#endif -+ -+ if (WLAN_STATUS_SUCCESS == authSendDeauthFrame(prAdapter, -+ prStaRec, -+ NULL, -+ REASON_CODE_CLASS_3_ERR, -+ (PFN_TX_DONE_HANDLER) NULL)) -+ -+ DBGLOG(RSN, INFO, "Send Deauth to [ %pM ] for Rx Class 3 Error.\n", -+ prStaRec->aucMacAddr); -+ else -+ DBGLOG(RSN, INFO, "Host sends Deauth to [ %pM ] for Rx Class 3 fail.\n", -+ prStaRec->aucMacAddr); -+ return FALSE; -+ } -+ -+ return secRxPortControlCheck(prAdapter, prSwRfb); -+} /* end of secCheckClassError() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is used to setting the sta port status. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* \param[in] prSta Pointer to the sta -+* \param[in] fgPortBlock The port status -+* -+* \retval none -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID secSetPortBlocked(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta, IN BOOLEAN fgPortBlock) -+{ -+ if (prSta == NULL) -+ return; -+ -+ prSta->fgPortBlock = fgPortBlock; -+ -+ DBGLOG(RSN, TRACE, -+ "The STA %pM port %s\n", prSta->aucMacAddr, fgPortBlock == TRUE ? "BLOCK" : " OPEN"); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is used to report the sta port status. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* \param[in] prSta Pointer to the sta -+* \param[out] fgPortBlock The port status -+* -+* \return TRUE sta exist, FALSE sta not exist -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN secGetPortStatus(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta, OUT PBOOLEAN pfgPortStatus) -+{ -+ if (prSta == NULL) -+ return FALSE; -+ -+ *pfgPortStatus = prSta->fgPortBlock; -+ -+ return TRUE; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to handle Peer device Tx Security process MSDU. -+* -+* \param[in] prMsduInfo pointer to the packet info pointer -+* -+* \retval TRUE Accept the packet -+* \retval FALSE Refuse the MSDU packet due port blocked -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN /* ENUM_PORT_CONTROL_RESULT */ -+secTxPortControlCheck(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo, IN P_STA_RECORD_T prStaRec) -+{ -+ ASSERT(prAdapter); -+ ASSERT(prMsduInfo); -+ ASSERT(prStaRec); -+ -+ if (prStaRec) { -+ -+ /* Todo:: */ -+ if (prMsduInfo->fgIs802_1x) -+ return TRUE; -+ -+ if (prStaRec->fgPortBlock == TRUE) { -+ DBGLOG(SEC, TRACE, "Drop Tx packet due Port Control!\n"); -+ return FALSE; -+ } -+#if CFG_SUPPORT_WAPI -+ if (prAdapter->rWifiVar.rConnSettings.fgWapiMode) -+ return TRUE; -+#endif -+ if (IS_STA_IN_AIS(prStaRec)) { -+ if (!prAdapter->rWifiVar.rAisSpecificBssInfo.fgTransmitKeyExist && -+ (prAdapter->rWifiVar.rConnSettings.eEncStatus == ENUM_ENCRYPTION1_ENABLED)) { -+ DBGLOG(SEC, TRACE, "Drop Tx packet due the key is removed!!!\n"); -+ return FALSE; -+ } -+ } -+ } -+ -+ return TRUE; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to handle The Rx Security process MSDU. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* \param[in] prSWRfb SW rfb pinter -+* -+* \retval TRUE Accept the packet -+* \retval FALSE Refuse the MSDU packet due port control -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN secRxPortControlCheck(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSWRfb) -+{ -+ ASSERT(prSWRfb); -+ -+#if 0 -+ /* whsu:Todo: Process MGMT and DATA */ -+ if (prSWRfb->prStaRec) { -+ if (prSWRfb->prStaRec->fgPortBlock == TRUE) { -+ if (1 /* prSWRfb->fgIsDataFrame and not 1x */ && -+ (g_prWifiVar->rConnSettings.eAuthMode >= AUTH_MODE_WPA)) { -+ /* DBGLOG(SEC, WARN, ("Drop Rx data due port control !\r\n")); */ -+ return TRUE; /* Todo: whsu FALSE; */ -+ } -+ /* if (!RX_STATUS_IS_PROTECT(prSWRfb->prRxStatus)) { */ -+ /* DBGLOG(RSN, WARN, ("Drop rcv non-encrypted data frame!\n")); */ -+ /* return FALSE; */ -+ /* } */ -+ } -+ } else { -+ } -+#endif -+ return TRUE; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine will enable/disable the cipher suite -+* -+* \param[in] prAdapter Pointer to the adapter object data area. -+* \param[in] u4CipherSuitesFlags flag for cipher suite -+* -+* \retval none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID secSetCipherSuite(IN P_ADAPTER_T prAdapter, IN UINT_32 u4CipherSuitesFlags) -+{ -+ UINT_32 i; -+ P_DOT11_RSNA_CONFIG_PAIRWISE_CIPHERS_ENTRY prEntry; -+ P_IEEE_802_11_MIB_T prMib; -+ -+ ASSERT(prAdapter); -+ -+ prMib = &prAdapter->rMib; -+ -+ ASSERT(prMib); -+ -+ if (u4CipherSuitesFlags == CIPHER_FLAG_NONE) { -+ /* Disable all the pairwise cipher suites. */ -+ for (i = 0; i < MAX_NUM_SUPPORTED_CIPHER_SUITES; i++) -+ prMib->dot11RSNAConfigPairwiseCiphersTable[i].dot11RSNAConfigPairwiseCipherEnabled = FALSE; -+ -+ /* Update the group cipher suite. */ -+ prMib->dot11RSNAConfigGroupCipher = WPA_CIPHER_SUITE_NONE; -+ -+ return; -+ } -+ -+ for (i = 0; i < MAX_NUM_SUPPORTED_CIPHER_SUITES; i++) { -+ prEntry = &prMib->dot11RSNAConfigPairwiseCiphersTable[i]; -+ -+ switch (prEntry->dot11RSNAConfigPairwiseCipher) { -+ case WPA_CIPHER_SUITE_WEP40: -+ case RSN_CIPHER_SUITE_WEP40: -+ if (u4CipherSuitesFlags & CIPHER_FLAG_WEP40) -+ prEntry->dot11RSNAConfigPairwiseCipherEnabled = TRUE; -+ else -+ prEntry->dot11RSNAConfigPairwiseCipherEnabled = FALSE; -+ break; -+ -+ case WPA_CIPHER_SUITE_TKIP: -+ case RSN_CIPHER_SUITE_TKIP: -+ if (u4CipherSuitesFlags & CIPHER_FLAG_TKIP) -+ prEntry->dot11RSNAConfigPairwiseCipherEnabled = TRUE; -+ else -+ prEntry->dot11RSNAConfigPairwiseCipherEnabled = FALSE; -+ break; -+ -+ case WPA_CIPHER_SUITE_CCMP: -+ case RSN_CIPHER_SUITE_CCMP: -+ if (u4CipherSuitesFlags & CIPHER_FLAG_CCMP) -+ prEntry->dot11RSNAConfigPairwiseCipherEnabled = TRUE; -+ else -+ prEntry->dot11RSNAConfigPairwiseCipherEnabled = FALSE; -+ break; -+ -+ case WPA_CIPHER_SUITE_WEP104: -+ case RSN_CIPHER_SUITE_WEP104: -+ if (u4CipherSuitesFlags & CIPHER_FLAG_WEP104) -+ prEntry->dot11RSNAConfigPairwiseCipherEnabled = TRUE; -+ else -+ prEntry->dot11RSNAConfigPairwiseCipherEnabled = FALSE; -+ break; -+ default: -+ break; -+ } -+ } -+ -+ /* Update the group cipher suite. */ -+ if (rsnSearchSupportedCipher(prAdapter, WPA_CIPHER_SUITE_CCMP, &i)) -+ prMib->dot11RSNAConfigGroupCipher = WPA_CIPHER_SUITE_CCMP; -+ else if (rsnSearchSupportedCipher(prAdapter, WPA_CIPHER_SUITE_TKIP, &i)) -+ prMib->dot11RSNAConfigGroupCipher = WPA_CIPHER_SUITE_TKIP; -+ else if (rsnSearchSupportedCipher(prAdapter, WPA_CIPHER_SUITE_WEP104, &i)) -+ prMib->dot11RSNAConfigGroupCipher = WPA_CIPHER_SUITE_WEP104; -+ else if (rsnSearchSupportedCipher(prAdapter, WPA_CIPHER_SUITE_WEP40, &i)) -+ prMib->dot11RSNAConfigGroupCipher = WPA_CIPHER_SUITE_WEP40; -+ else -+ prMib->dot11RSNAConfigGroupCipher = WPA_CIPHER_SUITE_NONE; -+ -+} /* secSetCipherSuite */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to handle The 2nd Tx EAPoL Frame. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* \param[in] prMsduInfo pointer to the packet info pointer -+* \param[in] pucPayload pointer to the 1x hdr -+* \param[in] u2PayloadLen the 1x payload length -+* -+* \retval TRUE Accept the packet -+* \retval FALSE Refuse the MSDU packet due port control -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN -+secProcessEAPOL(IN P_ADAPTER_T prAdapter, -+ IN P_MSDU_INFO_T prMsduInfo, IN P_STA_RECORD_T prStaRec, IN PUINT_8 pucPayload, IN UINT_16 u2PayloadLen) -+{ -+ P_EAPOL_KEY prEapol = (P_EAPOL_KEY) NULL; -+ P_IEEE_802_1X_HDR pr1xHdr; -+ UINT_16 u2KeyInfo; -+ -+ ASSERT(prMsduInfo); -+ ASSERT(prStaRec); -+ -+ /* prStaRec = &(g_arStaRec[prMsduInfo->ucStaRecIndex]); */ -+ ASSERT(prStaRec); -+ -+ if (prStaRec && IS_AP_STA(prStaRec)) { -+ pr1xHdr = (P_IEEE_802_1X_HDR) pucPayload; -+ if ((pr1xHdr->ucType == 3) /* EAPoL key */ && ((u2PayloadLen - 4) > sizeof(EAPOL_KEY))) { -+ prEapol = (P_EAPOL_KEY) ((PUINT_32) (pucPayload + 4)); -+ WLAN_GET_FIELD_BE16(prEapol->aucKeyInfo, &u2KeyInfo); -+ if ((prEapol->ucType == 254) && (u2KeyInfo & MASK_2ND_EAPOL)) { -+ if (u2KeyInfo & WPA_KEY_INFO_SECURE) { -+ /* 4th EAPoL check at secHandleTxDoneCallback() */ -+ /* DBGLOG(RSN, TRACE, ("Tx 4th EAPoL frame\r\n")); */ -+ } else if (u2PayloadLen == 123 /* Not include LLC */) { -+ DBGLOG(RSN, INFO, "Tx 2nd EAPoL frame\r\n"); -+ secFsmEvent2ndEapolTx(prAdapter, prStaRec); -+ } -+ } -+ } -+ } -+ -+ return TRUE; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will handle the 4th EAPoL Tx done and mic Error Report frame. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* \param[in] pMsduInfo Pointer to the Msdu Info -+* \param[in] rStatus The Tx done status -+* -+* \return - -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+secHandleTxDoneCallback(IN P_ADAPTER_T prAdapter, -+ IN P_MSDU_INFO_T prMsduInfo, IN P_STA_RECORD_T prStaRec, IN WLAN_STATUS rStatus) -+{ -+ PUINT_8 pucPayload; -+ P_IEEE_802_1X_HDR pr1xHdr = (P_IEEE_802_1X_HDR) NULL; -+ P_EAPOL_KEY prEapol = (P_EAPOL_KEY) NULL; -+ UINT_16 u2KeyInfo; -+ UINT_16 u2PayloadLen; -+ -+ DEBUGFUNC("secHandleTxDoneCallback"); -+ -+ ASSERT(prMsduInfo); -+ /* Todo:: Notice if using the TX free immediate after send to firmware, the payload may not correcttly!!!! */ -+ -+ ASSERT(prStaRec); -+ -+ /* Todo:: This call back may not need because the order of set key and send 4th 1x can be make sure */ -+ /* Todo:: Notice the LLC offset */ -+#if 1 -+ pucPayload = (PUINT_8) prMsduInfo->prPacket; -+ ASSERT(pucPayload); -+ -+ u2PayloadLen = prMsduInfo->u2FrameLength; -+ -+ if (0 /* prMsduInfo->fgIs1xFrame */) { -+ -+ if (prStaRec && IS_AP_STA(prStaRec)) { -+ pr1xHdr = (P_IEEE_802_1X_HDR) (PUINT_32) (pucPayload + 8); -+ if ((pr1xHdr->ucType == 3) /* EAPoL key */ && ((u2PayloadLen - 4) > sizeof(EAPOL_KEY))) { -+ prEapol = (P_EAPOL_KEY) (PUINT_32) (pucPayload + 12); -+ WLAN_GET_FIELD_BE16(prEapol->aucKeyInfo, &u2KeyInfo); -+ if ((prEapol->ucType == 254) && (u2KeyInfo & MASK_2ND_EAPOL)) { -+ if (prStaRec->rSecInfo.fg2nd1xSend == TRUE -+ && u2PayloadLen == -+ 107 /* include LLC *//* u2KeyInfo & WPA_KEY_INFO_SECURE */) { -+ DBGLOG(RSN, INFO, "Tx 4th EAPoL frame\r\n"); -+ secFsmEvent4ndEapolTxDone(prAdapter, prStaRec); -+ } else if (prAdapter->rWifiVar.rAisSpecificBssInfo.fgCheckEAPoLTxDone) { -+ DBGLOG(RSN, INFO, "Tx EAPoL Error report frame\r\n"); -+ /* secFsmEventEapolTxDone(prAdapter, (UINT_32)prMsduInfo->prStaRec); */ -+ } -+ } -+ } -+ } -+ -+ } -+#endif -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to initialize the pmkid parameters. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* -+* \retval NONE -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID secClearPmkid(IN P_ADAPTER_T prAdapter) -+{ -+ P_AIS_SPECIFIC_BSS_INFO_T prAisSpecBssInfo; -+ -+ DEBUGFUNC("secClearPmkid"); -+ -+ prAisSpecBssInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo; -+ DBGLOG(RSN, TRACE, "secClearPmkid\n"); -+ prAisSpecBssInfo->u4PmkidCandicateCount = 0; -+ prAisSpecBssInfo->u4PmkidCacheCount = 0; -+ kalMemZero((PVOID) prAisSpecBssInfo->arPmkidCandicate, sizeof(PMKID_CANDICATE_T) * CFG_MAX_PMKID_CACHE); -+ kalMemZero((PVOID) prAisSpecBssInfo->arPmkidCache, sizeof(PMKID_ENTRY_T) * CFG_MAX_PMKID_CACHE); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Whether WPA, or WPA2 but not WPA-None is enabled. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* -+* \retval BOOLEAN -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN secRsnKeyHandshakeEnabled(IN P_ADAPTER_T prAdapter) -+{ -+ P_CONNECTION_SETTINGS_T prConnSettings; -+ -+ ASSERT(prAdapter); -+ -+ prConnSettings = &prAdapter->rWifiVar.rConnSettings; -+ -+ ASSERT(prConnSettings); -+ -+ ASSERT(prConnSettings->eEncStatus < ENUM_ENCRYPTION3_KEY_ABSENT); -+ -+ if (prConnSettings->eEncStatus == ENUM_ENCRYPTION_DISABLED) -+ return FALSE; -+ -+ ASSERT(prConnSettings->eAuthMode < AUTH_MODE_NUM); -+ if ((prConnSettings->eAuthMode >= AUTH_MODE_WPA) && (prConnSettings->eAuthMode != AUTH_MODE_WPA_NONE)) -+ return TRUE; -+ -+ return FALSE; -+} /* secRsnKeyHandshakeEnabled */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Return whether the transmit key alread installed. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* \param[in] prSta Pointer the sta record -+* -+* \retval TRUE Default key or Transmit key installed -+* FALSE Default key or Transmit key not installed -+* -+* \note: -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN secTransmitKeyExist(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta) -+{ -+ ASSERT(prSta); -+ -+ if (prSta->fgTransmitKeyExist) -+ return TRUE; -+ else -+ return FALSE; -+} /* secTransmitKeyExist */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Whether 802.11 privacy is enabled. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* -+* \retval BOOLEAN -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN secEnabledInAis(IN P_ADAPTER_T prAdapter) -+{ -+ DEBUGFUNC("secEnabled"); -+ -+ ASSERT(prAdapter->rWifiVar.rConnSettings.eEncStatus < ENUM_ENCRYPTION3_KEY_ABSENT); -+ -+ switch (prAdapter->rWifiVar.rConnSettings.eEncStatus) { -+ case ENUM_ENCRYPTION_DISABLED: -+ return FALSE; -+ case ENUM_ENCRYPTION1_ENABLED: -+ case ENUM_ENCRYPTION2_ENABLED: -+ case ENUM_ENCRYPTION3_ENABLED: -+ return TRUE; -+ default: -+ DBGLOG(RSN, TRACE, "Unknown encryption setting %d\n", prAdapter->rWifiVar.rConnSettings.eEncStatus); -+ break; -+ } -+ return FALSE; -+} /* secEnabled */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to set the privacy bit at mac header for TxM -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* \param[in] prMsdu the msdu for known the sta record -+* -+* \return TRUE the privacy need to set -+* FALSE the privacy no need to set -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN secIsProtectedFrame(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsdu, IN P_STA_RECORD_T prStaRec) -+{ -+ ASSERT(prAdapter); -+ -+ ASSERT(prMsdu); -+ -+ ASSERT(prStaRec); -+ /* prStaRec = &(g_arStaRec[prMsdu->ucStaRecIndex]); */ -+ -+ if (prStaRec == NULL) { -+ if (prAdapter->rWifiVar.rAisSpecificBssInfo.fgTransmitKeyExist) -+ return TRUE; -+ return FALSE; /* No privacy bit */ -+ } -+ -+ /* Todo:: */ -+ if (0 /* prMsdu->fgIs1xFrame */) { -+ if (IS_STA_IN_AIS(prStaRec) && prAdapter->rWifiVar.rConnSettings.eAuthMode < AUTH_MODE_WPA) { -+ DBGLOG(RSN, LOUD, "For AIS Legacy 1x, always not encryped\n"); -+ return FALSE; -+ } else if (!prStaRec->fgTransmitKeyExist) { -+ DBGLOG(RSN, LOUD, "1x Not Protected.\n"); -+ return FALSE; -+ } else if (prStaRec->rSecInfo.fgKeyStored) { -+ DBGLOG(RSN, LOUD, "1x not Protected due key stored!\n"); -+ return FALSE; -+ } -+ DBGLOG(RSN, LOUD, "1x Protected.\n"); -+ return TRUE; -+ } -+ if (!prStaRec->fgTransmitKeyExist) { -+ /* whsu , check for AIS only */ -+ if (prAdapter->rWifiVar.rConnSettings.eAuthMode < AUTH_MODE_WPA && -+ prAdapter->rWifiVar.rAisSpecificBssInfo.fgTransmitKeyExist) { -+ DBGLOG(RSN, LOUD, "Protected\n"); -+ return TRUE; -+ } -+ } else { -+ DBGLOG(RSN, LOUD, "Protected.\n"); -+ return TRUE; -+ } -+ -+ /* No sec or key is removed!!! */ -+ return FALSE; -+} -+#endif -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rate.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rate.c -new file mode 100644 -index 000000000000..fd0a8772a666 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rate.c -@@ -0,0 +1,497 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/rate.c#1 -+*/ -+ -+/*! \file "rate.c" -+ \brief This file contains the transmission rate handling routines. -+ -+ This file contains the transmission rate handling routines for setting up -+ ACK/CTS Rate, Highest Tx Rate, Lowest Tx Rate, Initial Tx Rate and do -+ conversion between Rate Set and Data Rates. -+*/ -+ -+/* -+** Log: rate.c -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 08 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add rate.c. -+ * -+ * 03 16 2010 kevin.huang -+ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support -+ * Add AdHoc Mode -+ * -+ * 12 18 2009 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * . -+ * -+ * Nov 23 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Update comments -+ * -+ * Nov 16 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Fix DBGLOG -+ * -+ * Nov 5 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * -+** \main\maintrunk.MT5921\12 2008-12-19 17:19:32 GMT mtk01461 -+** Fix the problem that do not ASSERT the length of Supported Rate IE == 8 -+** \main\maintrunk.MT5921\11 2008-12-01 18:17:42 GMT mtk01088 -+** fixed the lint "possible using null pointer" warning -+** \main\maintrunk.MT5921\10 2008-08-20 00:16:36 GMT mtk01461 -+** Update for Driver Review -+** \main\maintrunk.MT5921\9 2008-04-13 21:17:13 GMT mtk01461 -+** Revise GEN Link Speed OID -+** \main\maintrunk.MT5921\8 2008-03-28 10:40:13 GMT mtk01461 -+** Add rateGetRateSetFromDataRates() for set desired rate OID -+** \main\maintrunk.MT5921\7 2008-03-26 09:16:20 GMT mtk01461 -+** Add adopt operational rate as ACK rate if BasicRateSet was not found -+** Add comments -+** \main\maintrunk.MT5921\6 2008-02-21 15:01:39 GMT mtk01461 -+** Add initial rate according rx signal quality support -+** \main\maintrunk.MT5921\5 2008-01-07 15:06:44 GMT mtk01461 -+** Fix typo of rate adaptation of CtrlResp Frame -+** \main\maintrunk.MT5921\4 2007-10-25 18:05:12 GMT mtk01461 -+** Add VOIP SCAN Support & Refine Roaming -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "precomp.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+/* The list of valid data rates. */ -+const UINT_8 aucDataRate[] = { -+ RATE_1M, /* RATE_1M_INDEX = 0 */ -+ RATE_2M, /* RATE_2M_INDEX */ -+ RATE_5_5M, /* RATE_5_5M_INDEX */ -+ RATE_11M, /* RATE_11M_INDEX */ -+ RATE_22M, /* RATE_22M_INDEX */ -+ RATE_33M, /* RATE_33M_INDEX */ -+ RATE_6M, /* RATE_6M_INDEX */ -+ RATE_9M, /* RATE_9M_INDEX */ -+ RATE_12M, /* RATE_12M_INDEX */ -+ RATE_18M, /* RATE_18M_INDEX */ -+ RATE_24M, /* RATE_24M_INDEX */ -+ RATE_36M, /* RATE_36M_INDEX */ -+ RATE_48M, /* RATE_48M_INDEX */ -+ RATE_54M, /* RATE_54M_INDEX */ -+ RATE_HT_PHY /* RATE_HT_PHY_INDEX */ -+}; -+ -+static const UINT_8 aucDefaultAckCtsRateIndex[RATE_NUM] = { -+ RATE_1M_INDEX, /* RATE_1M_INDEX = 0 */ -+ RATE_2M_INDEX, /* RATE_2M_INDEX */ -+ RATE_5_5M_INDEX, /* RATE_5_5M_INDEX */ -+ RATE_11M_INDEX, /* RATE_11M_INDEX */ -+ RATE_1M_INDEX, /* RATE_22M_INDEX - Not supported */ -+ RATE_1M_INDEX, /* RATE_33M_INDEX - Not supported */ -+ RATE_6M_INDEX, /* RATE_6M_INDEX */ -+ RATE_6M_INDEX, /* RATE_9M_INDEX */ -+ RATE_12M_INDEX, /* RATE_12M_INDEX */ -+ RATE_12M_INDEX, /* RATE_18M_INDEX */ -+ RATE_24M_INDEX, /* RATE_24M_INDEX */ -+ RATE_24M_INDEX, /* RATE_36M_INDEX */ -+ RATE_24M_INDEX, /* RATE_48M_INDEX */ -+ RATE_24M_INDEX /* RATE_54M_INDEX */ -+}; -+ -+const BOOLEAN afgIsOFDMRate[RATE_NUM] = { -+ FALSE, /* RATE_1M_INDEX = 0 */ -+ FALSE, /* RATE_2M_INDEX */ -+ FALSE, /* RATE_5_5M_INDEX */ -+ FALSE, /* RATE_11M_INDEX */ -+ FALSE, /* RATE_22M_INDEX - Not supported */ -+ FALSE, /* RATE_33M_INDEX - Not supported */ -+ TRUE, /* RATE_6M_INDEX */ -+ TRUE, /* RATE_9M_INDEX */ -+ TRUE, /* RATE_12M_INDEX */ -+ TRUE, /* RATE_18M_INDEX */ -+ TRUE, /* RATE_24M_INDEX */ -+ TRUE, /* RATE_36M_INDEX */ -+ TRUE, /* RATE_48M_INDEX */ -+ TRUE /* RATE_54M_INDEX */ -+}; -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Convert the given Supported Rate & Extended Supported Rate IE to the -+* Operational Rate Set and Basic Rate Set, and also check if any Basic -+* Rate Code is unknown by driver. -+* -+* @param[in] prIeSupportedRate Pointer to the Supported Rate IE -+* @param[in] prIeExtSupportedRate Pointer to the Ext Supported Rate IE -+* @param[out] pu2OperationalRateSet Pointer to the Operational Rate Set -+* @param[out] pu2BSSBasicRateSet Pointer to the Basic Rate Set -+* @param[out] pfgIsUnknownBSSBasicRate Pointer to a Flag to indicate that Basic -+* Rate Set has unknown Rate Code -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+rateGetRateSetFromIEs(IN P_IE_SUPPORTED_RATE_T prIeSupportedRate, -+ IN P_IE_EXT_SUPPORTED_RATE_T prIeExtSupportedRate, -+ OUT PUINT_16 pu2OperationalRateSet, -+ OUT PUINT_16 pu2BSSBasicRateSet, OUT PBOOLEAN pfgIsUnknownBSSBasicRate) -+{ -+ UINT_16 u2OperationalRateSet = 0; -+ UINT_16 u2BSSBasicRateSet = 0; -+ BOOLEAN fgIsUnknownBSSBasicRate = FALSE; -+ UINT_8 ucRate; -+ UINT_32 i, j; -+ -+ ASSERT(pu2OperationalRateSet); -+ ASSERT(pu2BSSBasicRateSet); -+ ASSERT(pfgIsUnknownBSSBasicRate); -+ -+ if (prIeSupportedRate) { -+ /* NOTE(Kevin): Buffalo WHR-G54S's supported rate set IE exceed 8. -+ * IE_LEN(pucIE) == 12, "1(B), 2(B), 5.5(B), 6(B), 9(B), 11(B), -+ * 12(B), 18(B), 24(B), 36(B), 48(B), 54(B)" -+ */ -+ /* ASSERT(prIeSupportedRate->ucLength <= ELEM_MAX_LEN_SUP_RATES); */ -+ ASSERT(prIeSupportedRate->ucLength <= RATE_NUM); -+ -+ for (i = 0; i < prIeSupportedRate->ucLength; i++) { -+ ucRate = prIeSupportedRate->aucSupportedRates[i] & RATE_MASK; -+ -+ /* Search all valid data rates */ -+ for (j = 0; j < sizeof(aucDataRate) / sizeof(UINT_8); j++) { -+ if (ucRate == aucDataRate[j]) { -+ u2OperationalRateSet |= BIT(j); -+ -+ if (prIeSupportedRate->aucSupportedRates[i] & RATE_BASIC_BIT) -+ u2BSSBasicRateSet |= BIT(j); -+ -+ break; -+ } -+ } -+ -+ if ((j == sizeof(aucDataRate) / sizeof(UINT_8)) && -+ (prIeSupportedRate->aucSupportedRates[i] & RATE_BASIC_BIT)) { -+ fgIsUnknownBSSBasicRate = TRUE; /* A data rate not list in the aucDataRate[] */ -+ } -+ } -+ } -+ -+ if (prIeExtSupportedRate) { -+ /* ASSERT(prIeExtSupportedRate->ucLength <= ELEM_MAX_LEN_EXTENDED_SUP_RATES); */ -+ -+ for (i = 0; i < prIeExtSupportedRate->ucLength; i++) { -+ ucRate = prIeExtSupportedRate->aucExtSupportedRates[i] & RATE_MASK; -+ -+ /* Search all valid data rates */ -+ for (j = 0; j < sizeof(aucDataRate) / sizeof(UINT_8); j++) { -+ if (ucRate == aucDataRate[j]) { -+ u2OperationalRateSet |= BIT(j); -+ -+ if (prIeExtSupportedRate->aucExtSupportedRates[i] & RATE_BASIC_BIT) -+ u2BSSBasicRateSet |= BIT(j); -+ -+ break; -+ } -+ } -+ -+ if ((j == sizeof(aucDataRate) / sizeof(UINT_8)) && -+ (prIeExtSupportedRate->aucExtSupportedRates[i] & RATE_BASIC_BIT)) { -+ fgIsUnknownBSSBasicRate = TRUE; /* A data rate not list in the aucDataRate[] */ -+ } -+ } -+ } -+ -+ *pu2OperationalRateSet = u2OperationalRateSet; -+ *pu2BSSBasicRateSet = u2BSSBasicRateSet; -+ *pfgIsUnknownBSSBasicRate = fgIsUnknownBSSBasicRate; -+ -+ return; -+ -+} /* end of rateGetRateSetFromIEs() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Convert the given Operational Rate Set & Basic Rate Set to the Rate Code -+* Format for used in (Ext)Supportec Rate IE. -+* -+* @param[in] u2OperationalRateSet Operational Rate Set -+* @param[in] u2BSSBasicRateSet Basic Rate Set -+* @param[out] pucDataRates Pointer to the Data Rate Buffer -+* @param[out] pucDataRatesLen Pointer to the Data Rate Buffer Length -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+rateGetDataRatesFromRateSet(IN UINT_16 u2OperationalRateSet, -+ IN UINT_16 u2BSSBasicRateSet, OUT PUINT_8 pucDataRates, OUT PUINT_8 pucDataRatesLen) -+{ -+ UINT_32 i, j; -+ -+ ASSERT(pucDataRates); -+ ASSERT(pucDataRatesLen); -+ -+ ASSERT(u2BSSBasicRateSet == (u2OperationalRateSet & u2BSSBasicRateSet)); -+ -+ for (i = RATE_1M_INDEX, j = 0; i < RATE_NUM; i++) { -+ if (u2OperationalRateSet & BIT(i)) { -+ -+ *(pucDataRates + j) = aucDataRate[i]; -+ -+ if (u2BSSBasicRateSet & BIT(i)) -+ *(pucDataRates + j) |= RATE_BASIC_BIT; -+ -+ j++; -+ } -+ } -+ -+ *pucDataRatesLen = (UINT_8) j; -+ -+ return; -+ -+} /* end of rateGetDataRatesFromRateSet() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Get the highest rate from given Rate Set. -+* -+* \param[in] u2RateSet Rate Set -+* \param[out] pucHighestRateIndex Pointer to buffer of the Highest Rate Index -+* -+* \retval TRUE Highest Rate Index was found -+* \retval FALSE Highest Rate Index was not found -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN rateGetHighestRateIndexFromRateSet(IN UINT_16 u2RateSet, OUT PUINT_8 pucHighestRateIndex) -+{ -+ INT_32 i; -+ -+ ASSERT(pucHighestRateIndex); -+ -+ for (i = RATE_54M_INDEX; i >= RATE_1M_INDEX; i--) { -+ if (u2RateSet & BIT(i)) { -+ *pucHighestRateIndex = (UINT_8) i; -+ return TRUE; -+ } -+ } -+ -+ return FALSE; -+ -+} /* end of rateGetHighestRateIndexFromRateSet() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Get the lowest rate from given Rate Set. -+* -+* \param[in] u2RateSet Rate Set -+* \param[out] pucLowestRateIndex Pointer to buffer of the Lowest Rate Index -+* -+* \retval TRUE Lowest Rate Index was found -+* \retval FALSE Lowest Rate Index was not found -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN rateGetLowestRateIndexFromRateSet(IN UINT_16 u2RateSet, OUT PUINT_8 pucLowestRateIndex) -+{ -+ UINT_32 i; -+ -+ ASSERT(pucLowestRateIndex); -+ -+ for (i = RATE_1M_INDEX; i <= RATE_54M_INDEX; i++) { -+ if (u2RateSet & BIT(i)) { -+ *pucLowestRateIndex = (UINT_8) i; -+ return TRUE; -+ } -+ } -+ -+ return FALSE; -+ -+} /* end of rateGetLowestRateIndexFromRateSet() */ -+ -+#if 0 /* NOTE(Kevin): For reference */ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Convert the given Data Rates to the Rate Set. -+* -+* \param[in] pucDataRates Pointer to the Data Rates -+* \param[in] ucDataRatesLen Length of given Data Rates -+* \param[out] pu2RateSet Pointer to the Rate Set -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rateGetRateSetFromDataRates(IN PUINT_8 pucDataRates, IN UINT_8 ucDataRatesLen, OUT PUINT_16 pu2RateSet) -+{ -+ UINT_16 u2RateSet = 0; -+ UINT_8 ucRate; -+ UINT_32 i, j; -+ -+ ASSERT(pucDataRates); -+ ASSERT(pu2RateSet); -+ -+ if (pucDataRates) { -+ for (i = 0; i < ucDataRatesLen; i++) { -+ ucRate = pucDataRates[i] & RATE_MASK; -+ -+ /* Search all valid data rates */ -+ for (j = 0; j < sizeof(aucDataRate) / sizeof(UINT_8); j++) { -+ if (ucRate == aucDataRate[j]) { -+ u2RateSet |= BIT(j); -+ break; -+ } -+ } -+ } -+ } -+ -+ *pu2RateSet = u2RateSet; -+ -+ return; -+ -+} /* end of rateGetRateSetFromDataRates() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Parse the Operational Rate Set and Basic Rate Set to get the corresponding -+* ACK/CTS(Respnose) TX Rates. -+* -+* \param[in] u2OperationalRateSet Operational Rate Set -+* \param[in] u2BSSBasicRateSet Basic Rate Set -+* \param[out] aucAckCtsRateIndex Pointer to the Ack/Cts Data Rate Buffer -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+rateSetAckCtsDataRatesFromRateSet(IN UINT_16 u2OperationalRateSet, -+ IN UINT_16 u2BSSBasicRateSet, IN OUT UINT_8 aucAckCtsRateIndex[]) -+{ -+ INT_32 i, j; -+ -+ ASSERT(aucAckCtsRateIndex); -+ ASSERT(u2BSSBasicRateSet == (u2OperationalRateSet & u2BSSBasicRateSet)); -+ -+ /* Setup default ACK/CTS response rate */ -+ kalMemCopy(aucAckCtsRateIndex, (PVOID) aucDefaultAckCtsRateIndex, sizeof(aucDefaultAckCtsRateIndex)); -+ -+ for (i = RATE_54M_INDEX; i >= RATE_1M_INDEX; i--) { -+ if (u2OperationalRateSet & BIT(i)) { -+ for (j = i; j >= RATE_1M_INDEX; j--) { -+ if (u2BSSBasicRateSet & BIT(j)) { -+ /* Reply ACK Frame at the same Modulation Scheme. */ -+ if ((afgIsOFDMRate[i] && afgIsOFDMRate[j]) || -+ (!afgIsOFDMRate[i] && !afgIsOFDMRate[j])) -+ aucAckCtsRateIndex[i] = (UINT_8) j; -+ break; -+ } -+ } -+ -+ /* NOTE(Kevin 2008/03/25): Following code is used for those AP which has -+ * NULL BasicRateSet. -+ * e.g. If input Operational Rate Set = [18M 12M 9M], Basic Rate Set = NULL. -+ * Originally we'll get Ack Rate for [18M 12M 9M] is [12M 12M "6M"]. -+ * Now we'll get Ack Rate for [18M 12M 9M] is [12M 12M 9M], -+ * The Ack Rate for Tx Rates which are not list in Operational Rate Set is still -+ * use highest mandatory rate as default. -+ */ -+ if (j < RATE_1M_INDEX) { /* The ACK/CTS rate was not found in BasicRateSet */ -+ if (!(BIT(aucAckCtsRateIndex[i]) & u2OperationalRateSet)) -+ aucAckCtsRateIndex[i] = (UINT_8) i; -+ } -+ } -+ } -+ -+ return; -+ -+} /* end of rateSetAckCtsDataRatesFromRateSet() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Get the proper initial rate from Rate Set according to given RCPI value -+* -+* \param[in] u2RateSet Rate Set -+* \param[in] rRcpi RCPI value from AP or Peer STA -+* \param[out] pucInitialRateIndex Pointer to buffer of the initial Rate Index -+* -+* \retval TRUE Initial Rate Index was found -+* \retval FALSE Initial Rate Index was not found -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN rateGetBestInitialRateIndex(IN UINT_16 u2RateSet, IN RCPI rRcpi, OUT PUINT_8 pucInitialRateIndex) -+{ -+ UINT_16 u2InitRateSet; -+ INT_32 i; -+ -+ ASSERT(pucInitialRateIndex); -+ -+ DBGLOG(MGT, TRACE, "rRcpi = %d\n", rRcpi); -+ -+ if (rRcpi >= RCPI_100) { /* Best Signal */ -+ u2InitRateSet = INITIAL_RATE_SET(RCPI_100); -+ } else if (rRcpi >= RCPI_80) { /* Better Signal */ -+ u2InitRateSet = INITIAL_RATE_SET(RCPI_80); -+ } else if (rRcpi >= RCPI_60) { /* Good Signal */ -+ u2InitRateSet = INITIAL_RATE_SET(RCPI_60); -+ } else { /* Worse Signal */ -+ /* NOTE(Kevin): If return FALSE, we should assign the BSS Basic Rate Index -+ * (prBssInfo->ucBasicRateIndex) to the initial rate. It was determined in -+ * function - bssUpdateTxRateForControlFrame(). -+ */ -+ return FALSE; -+ } -+ -+ u2RateSet &= u2InitRateSet; -+ -+ for (i = RATE_54M_INDEX; i >= RATE_1M_INDEX; i--) { -+ if (u2RateSet & BIT(i)) { -+ *pucInitialRateIndex = (UINT_8) i; -+ return TRUE; -+ } -+ } -+ -+ return FALSE; -+ -+} /* end of rateGetBestInitialRateIndex() */ -+#endif -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rlm.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rlm.c -new file mode 100644 -index 000000000000..244346983f40 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rlm.c -@@ -0,0 +1,1858 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/rlm.c#2 -+*/ -+ -+/*! \file "rlm.c" -+ \brief -+ -+*/ -+ -+/* -+** Log: rlm.c -+ * -+ * 07 17 2012 yuche.tsai -+ * NULL -+ * Compile no error before trial run. -+ * -+ * 11 15 2011 cm.chang -+ * NULL -+ * Check length HT cap IE about RX associate request frame -+ * -+ * 11 10 2011 cm.chang -+ * NULL -+ * Modify debug message for XLOG -+ * -+ * 11 08 2011 cm.chang -+ * NULL -+ * Add RLM and CNM debug message for XLOG -+ * -+ * 11 03 2011 cm.chang -+ * [WCXRP00000997] [MT6620 Wi-Fi][Driver][FW] Handle change of BSS preamble type and slot time -+ * Fix preamble type of STA mode -+ * -+ * 10 25 2011 cm.chang -+ * [WCXRP00001058] [All Wi-Fi][Driver] Fix sta_rec's phyTypeSet and OBSS scan in AP mode -+ * Not send ERP IE if peer STA is 802.11b-only -+ * -+ * 10 11 2011 cm.chang -+ * [WCXRP00001031] [All Wi-Fi][Driver] Check HT IE length to avoid wrong SCO parameter -+ * Ignore HT OP IE if its length field is not valid -+ * -+ * 09 28 2011 cm.chang -+ * NULL -+ * Add length check to reduce possibility to adopt wrong IE -+ * -+ * 09 20 2011 cm.chang -+ * [WCXRP00000997] [MT6620 Wi-Fi][Driver][FW] Handle change of BSS preamble type and slot time -+ * Handle client mode about preamble type and slot time -+ * -+ * 09 01 2011 cm.chang -+ * [WCXRP00000971] [MT6620 Wi-Fi][Driver][FW] Not set Beacon timeout interval when CPTT -+ * Final channel number only adopts the field from assoc response -+ * -+ * 06 10 2011 cm.chang -+ * [WCXRP00000773] [MT6620 Wi-Fi][Driver] Workaround some AP fill primary channel field with its secondary channel -+ * If DS IE exists, ignore the primary channel field in HT OP IE -+ * -+ * 05 03 2011 cm.chang -+ * [WCXRP00000691] [MT6620 Wi-Fi][Driver] Workaround about AP's wrong HT capability IE to have wrong channel number -+ * Fix compiling error -+ * -+ * 05 02 2011 cm.chang -+ * [WCXRP00000691] [MT6620 Wi-Fi][Driver] Workaround about AP's wrong HT capability IE to have wrong channel number -+ * Refine range of valid channel number -+ * -+ * 05 02 2011 cm.chang -+ * [WCXRP00000691] [MT6620 Wi-Fi][Driver] Workaround about AP's wrong HT capability IE to have wrong channel number -+ * Check if channel is valided before record ing BSS channel -+ * -+ * 04 14 2011 cm.chang -+ * [WCXRP00000634] [MT6620 Wi-Fi][Driver][FW] 2nd BSS will not support 40MHz bandwidth for concurrency -+ * . -+ * -+ * 04 12 2011 cm.chang -+ * [WCXRP00000634] [MT6620 Wi-Fi][Driver][FW] 2nd BSS will not support 40MHz bandwidth for concurrency -+ * . -+ * -+ * 03 29 2011 cm.chang -+ * [WCXRP00000606] [MT6620 Wi-Fi][Driver][FW] Fix klocwork warning -+ * As CR title -+ * -+ * 01 24 2011 cm.chang -+ * [WCXRP00000384] [MT6620 Wi-Fi][Driver][FW] Handle 20/40 action frame in AP mode -+ * and stop ampdu timer when sta_rec is freed -+ * Process received 20/40 coexistence action frame for AP mode -+ * -+ * 12 13 2010 cp.wu -+ * [WCXRP00000260] [MT6620 Wi-Fi][Driver][Firmware] Create V1.1 branch for both firmware and driver -+ * create branch for Wi-Fi driver v1.1 -+ * -+ * 12 07 2010 cm.chang -+ * [WCXRP00000239] MT6620 Wi-Fi][Driver][FW] Merge concurrent branch back to maintrunk -+ * 1. BSSINFO include RLM parameter -+ * 2. free all sta records when network is disconnected -+ * -+ * 12 07 2010 cm.chang -+ * [WCXRP00000238] MT6620 Wi-Fi][Driver][FW] Support regulation domain setting from NVRAM and supplicant -+ * 1. Country code is from NVRAM or supplicant -+ * 2. Change band definition in CMD/EVENT. -+ * -+ * 10 15 2010 cm.chang -+ * [WCXRP00000094] [MT6620 Wi-Fi][Driver] Connect to 2.4GHz AP, Driver crash. -+ * Add exception handle when no mgmt buffer in free build -+ * -+ * 10 08 2010 cm.chang -+ * NULL -+ * When 20M only setting, ignore OBSS IE -+ * -+ * 09 16 2010 cm.chang -+ * NULL -+ * Change conditional compiling options for BOW -+ * -+ * 09 10 2010 cm.chang -+ * NULL -+ * Always update Beacon content if FW sync OBSS info -+ * -+ * 09 03 2010 kevin.huang -+ * NULL -+ * Refine #include sequence and solve recursive/nested #include issue -+ * -+ * 08 24 2010 cm.chang -+ * NULL -+ * Support RLM initail channel of Ad-hoc, P2P and BOW -+ * -+ * 08 23 2010 cp.wu -+ * NULL -+ * revise constant definitions to be matched with implementation (original cmd-event definition is deprecated) -+ * -+ * 08 23 2010 chinghwa.yu -+ * NULL -+ * Temporary add rlmUpdateParamByStaForBow() and rlmBssInitForBow(). -+ * -+ * 08 23 2010 chinghwa.yu -+ * NULL -+ * Add CFG_ENABLE_BT_OVER_WIFI. -+ * -+ * 08 23 2010 chinghwa.yu -+ * NULL -+ * Update for BOW. -+ * -+ * 08 20 2010 cm.chang -+ * NULL -+ * Migrate RLM code to host from FW -+ * -+ * 08 02 2010 yuche.tsai -+ * NULL -+ * P2P Group Negotiation Code Check in. -+ * -+ * 07 26 2010 yuche.tsai -+ * -+ * Fix compile error while enabling WiFi Direct function. -+ * -+ * 07 21 2010 yuche.tsai -+ * -+ * Add P2P Scan & Scan Result Parsing & Saving. -+ * -+ * 07 19 2010 cm.chang -+ * -+ * Set RLM parameters and enable CNM channel manager -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 07 08 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * take use of RLM module for parsing/generating HT IEs for 11n capability -+ * -+ * 07 08 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Check draft RLM code for HT cap -+ * -+ * 06 05 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Fix channel ID definition in RFB status to primary channel instead of center channel -+ * -+ * 06 02 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Add TX short GI compiling option -+ * -+ * 06 02 2010 chinghwa.yu -+ * [BORA00000563]Add WiFi CoEx BCM module -+ * Roll back to remove CFG_SUPPORT_BCM_TEST. -+ * -+ * 06 01 2010 chinghwa.yu -+ * [BORA00000563]Add WiFi CoEx BCM module -+ * Update BCM Test and RW configuration. -+ * -+ * 05 31 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Add some compiling options to control 11n functions -+ * -+ * 05 28 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Set RTS threshold of 2K bytes initially -+ * -+ * 05 18 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Ad-hoc Beacon should not carry HT OP and OBSS IEs -+ * -+ * 05 07 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Process 20/40 coexistence public action frame in AP mode -+ * -+ * 05 05 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * First draft support for 20/40M bandwidth for AP mode -+ * -+ * 04 24 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * g_aprBssInfo[] depends on CFG_SUPPORT_P2P and CFG_SUPPORT_BOW -+ * -+ * 04 22 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * First draft code to support protection in AP mode -+ * -+ * 04 13 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Utilize status of swRfb to know channel number and band -+ * -+ * 04 07 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Different invoking order for WTBL entry of associated AP -+ * -+ * 04 07 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Add virtual test for OBSS scan -+ * -+ * 04 02 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Process Beacon only ready for infra STA now -+ * -+ * 03 30 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Support 2.4G OBSS scan -+ * -+ * 03 24 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Not carry HT cap when being associated with b/g only AP -+ * -+ * 03 24 2010 wh.su -+ * [BORA00000605][WIFISYS] Phase3 Integration -+ * fixed some WHQL testing error. -+ * -+ * 03 15 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Provide draft measurement and quiet functions -+ * -+ * 03 09 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * If bss is not 11n network, zero WTBL HT parameters -+ * -+ * 03 03 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * To support CFG_SUPPORT_BCM_STP -+ * -+ * 03 02 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Generate HT IE only depending on own phyTypeSet -+ * -+ * 03 02 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Not fill HT related IE if BssInfo does not include 11n phySet -+ * -+ * 03 01 2010 tehuang.liu -+ * [BORA00000569][WIFISYS] Phase 2 Integration Test -+ * To store field AMPDU Parameters in STA_REC -+ * -+ * 02 26 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Enable RDG RX, but disable RDG TX for IOT and LongNAV -+ * -+ * 02 12 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Use bss info array for concurrent handle -+ * -+ * 02 05 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Add AAA Module Support, Revise Net Type to Net Type Index for array lookup -+ * -+ * 01 22 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Support protection and bandwidth switch -+ * -+ * 01 07 2010 kevin.huang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Modify the parameter of rlmRecAssocRspHtInfo function -+ * -+ * 12 18 2009 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * . -+ * -+ * Dec 12 2009 mtk01104 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Fix prBssInfo->ucPrimaryChannel handle for assoc resp -+ * -+ * Dec 9 2009 mtk01104 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Add some function to process HT operation -+ * -+ * Nov 28 2009 mtk01104 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Call rlmStatisticsInit() to handle MIB counters -+ * -+ * Nov 18 2009 mtk01104 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * -+ * -+** -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "precomp.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+static VOID rlmFillHtCapIE(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo, P_MSDU_INFO_T prMsduInfo); -+ -+static VOID rlmFillExtCapIE(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo, P_MSDU_INFO_T prMsduInfo); -+ -+static VOID rlmFillHtOpIE(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo, P_MSDU_INFO_T prMsduInfo); -+ -+static UINT_8 rlmRecIeInfoForClient(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo, PUINT_8 pucIE, UINT_16 u2IELength); -+ -+static BOOLEAN -+rlmRecBcnFromNeighborForClient(P_ADAPTER_T prAdapter, -+ P_BSS_INFO_T prBssInfo, P_SW_RFB_T prSwRfb, PUINT_8 pucIE, UINT_16 u2IELength); -+ -+static BOOLEAN -+rlmRecBcnInfoForClient(P_ADAPTER_T prAdapter, -+ P_BSS_INFO_T prBssInfo, P_SW_RFB_T prSwRfb, PUINT_8 pucIE, UINT_16 u2IELength); -+ -+static VOID rlmBssReset(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo); -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rlmFsmEventInit(P_ADAPTER_T prAdapter) -+{ -+ ASSERT(prAdapter); -+ -+ /* Note: assume TIMER_T structures are reset to zero or stopped -+ * before invoking this function. -+ */ -+ -+ /* Initialize OBSS FSM */ -+ rlmObssInit(prAdapter); -+#if CFG_SUPPORT_PWR_LIMIT_COUNTRY -+ rlmDomainCheckCountryPowerLimitTable(prAdapter); -+#endif -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rlmFsmEventUninit(P_ADAPTER_T prAdapter) -+{ -+ P_BSS_INFO_T prBssInfo; -+ UINT_8 ucNetIdx; -+ -+ ASSERT(prAdapter); -+ -+ RLM_NET_FOR_EACH(ucNetIdx) { -+ prBssInfo = &prAdapter->rWifiVar.arBssInfo[ucNetIdx]; -+ ASSERT(prBssInfo); -+ -+ /* Note: all RLM timers will also be stopped. -+ * Now only one OBSS scan timer. -+ */ -+ rlmBssReset(prAdapter, prBssInfo); -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief For probe request, association request -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rlmReqGenerateHtCapIE(P_ADAPTER_T prAdapter, P_MSDU_INFO_T prMsduInfo) -+{ -+ P_BSS_INFO_T prBssInfo; -+ P_STA_RECORD_T prStaRec; -+ -+ ASSERT(prAdapter); -+ ASSERT(prMsduInfo); -+ -+ prBssInfo = &prAdapter->rWifiVar.arBssInfo[prMsduInfo->ucNetworkType]; -+ ASSERT(prBssInfo); -+ -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); -+ -+ if ((prAdapter->rWifiVar.ucAvailablePhyTypeSet & PHY_TYPE_SET_802_11N) && -+ (!prStaRec || (prStaRec->ucPhyTypeSet & PHY_TYPE_SET_802_11N))) -+ rlmFillHtCapIE(prAdapter, prBssInfo, prMsduInfo); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief For probe request, association request -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rlmReqGenerateExtCapIE(P_ADAPTER_T prAdapter, P_MSDU_INFO_T prMsduInfo) -+{ -+ P_BSS_INFO_T prBssInfo; -+ P_STA_RECORD_T prStaRec; -+ -+ ASSERT(prAdapter); -+ ASSERT(prMsduInfo); -+ -+ prBssInfo = &prAdapter->rWifiVar.arBssInfo[prMsduInfo->ucNetworkType]; -+ ASSERT(prBssInfo); -+ -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); -+ -+ if ((prAdapter->rWifiVar.ucAvailablePhyTypeSet & PHY_TYPE_SET_802_11N) && -+ (!prStaRec || (prStaRec->ucPhyTypeSet & PHY_TYPE_SET_802_11N))) -+ rlmFillExtCapIE(prAdapter, prBssInfo, prMsduInfo); -+#if CFG_SUPPORT_HOTSPOT_2_0 -+ else if (prAdapter->prGlueInfo->fgConnectHS20AP == TRUE) -+ hs20FillExtCapIE(prAdapter, prBssInfo, prMsduInfo); -+#endif -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief For probe response (GO, IBSS) and association response -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rlmRspGenerateHtCapIE(P_ADAPTER_T prAdapter, P_MSDU_INFO_T prMsduInfo) -+{ -+ P_BSS_INFO_T prBssInfo; -+ P_STA_RECORD_T prStaRec; -+ -+ ASSERT(prAdapter); -+ ASSERT(prMsduInfo); -+ ASSERT(IS_NET_ACTIVE(prAdapter, prMsduInfo->ucNetworkType)); -+ -+ prBssInfo = &prAdapter->rWifiVar.arBssInfo[prMsduInfo->ucNetworkType]; -+ ASSERT(prBssInfo); -+ -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); -+ -+ if (RLM_NET_IS_11N(prBssInfo) && (!prStaRec || (prStaRec->ucPhyTypeSet & PHY_TYPE_SET_802_11N))) -+ rlmFillHtCapIE(prAdapter, prBssInfo, prMsduInfo); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief For probe response (GO, IBSS) and association response -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rlmRspGenerateExtCapIE(P_ADAPTER_T prAdapter, P_MSDU_INFO_T prMsduInfo) -+{ -+ P_BSS_INFO_T prBssInfo; -+ P_STA_RECORD_T prStaRec; -+ -+ ASSERT(prAdapter); -+ ASSERT(prMsduInfo); -+ ASSERT(IS_NET_ACTIVE(prAdapter, prMsduInfo->ucNetworkType)); -+ -+ prBssInfo = &prAdapter->rWifiVar.arBssInfo[prMsduInfo->ucNetworkType]; -+ ASSERT(prBssInfo); -+ -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); -+ -+ if (RLM_NET_IS_11N(prBssInfo) && (!prStaRec || (prStaRec->ucPhyTypeSet & PHY_TYPE_SET_802_11N))) -+ rlmFillExtCapIE(prAdapter, prBssInfo, prMsduInfo); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief For probe response (GO, IBSS) and association response -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rlmRspGenerateHtOpIE(P_ADAPTER_T prAdapter, P_MSDU_INFO_T prMsduInfo) -+{ -+ P_BSS_INFO_T prBssInfo; -+ P_STA_RECORD_T prStaRec; -+ -+ ASSERT(prAdapter); -+ ASSERT(prMsduInfo); -+ ASSERT(IS_NET_ACTIVE(prAdapter, prMsduInfo->ucNetworkType)); -+ -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); -+ -+ prBssInfo = &prAdapter->rWifiVar.arBssInfo[prMsduInfo->ucNetworkType]; -+ ASSERT(prBssInfo); -+ -+ if (RLM_NET_IS_11N(prBssInfo) && (!prStaRec || (prStaRec->ucPhyTypeSet & PHY_TYPE_SET_802_11N))) -+ rlmFillHtOpIE(prAdapter, prBssInfo, prMsduInfo); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief For probe response (GO, IBSS) and association response -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rlmRspGenerateErpIE(P_ADAPTER_T prAdapter, P_MSDU_INFO_T prMsduInfo) -+{ -+ P_BSS_INFO_T prBssInfo; -+ P_STA_RECORD_T prStaRec; -+ P_IE_ERP_T prErpIe; -+ -+ ASSERT(prAdapter); -+ ASSERT(prMsduInfo); -+ ASSERT(IS_NET_ACTIVE(prAdapter, prMsduInfo->ucNetworkType)); -+ -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); -+ -+ prBssInfo = &prAdapter->rWifiVar.arBssInfo[prMsduInfo->ucNetworkType]; -+ ASSERT(prBssInfo); -+ -+ if (RLM_NET_IS_11GN(prBssInfo) && prBssInfo->eBand == BAND_2G4 && -+ (!prStaRec || (prStaRec->ucPhyTypeSet & PHY_TYPE_SET_802_11GN))) { -+ prErpIe = (P_IE_ERP_T) -+ (((PUINT_8) prMsduInfo->prPacket) + prMsduInfo->u2FrameLength); -+ -+ /* Add ERP IE */ -+ prErpIe->ucId = ELEM_ID_ERP_INFO; -+ prErpIe->ucLength = 1; -+ -+ prErpIe->ucERP = prBssInfo->fgObssErpProtectMode ? ERP_INFO_USE_PROTECTION : 0; -+ -+ if (prBssInfo->fgErpProtectMode) -+ prErpIe->ucERP |= (ERP_INFO_NON_ERP_PRESENT | ERP_INFO_USE_PROTECTION); -+ -+ /* Handle barker preamble */ -+ if (!prBssInfo->fgUseShortPreamble) -+ prErpIe->ucERP |= ERP_INFO_BARKER_PREAMBLE_MODE; -+ -+ ASSERT(IE_SIZE(prErpIe) <= (ELEM_HDR_LEN + ELEM_MAX_LEN_ERP)); -+ -+ prMsduInfo->u2FrameLength += IE_SIZE(prErpIe); -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT32 -+rlmFillHtCapIEByParams(BOOLEAN fg40mAllowed, -+ BOOLEAN fgShortGIDisabled, -+ UINT_8 u8SupportRxSgi20, -+ UINT_8 u8SupportRxSgi40, -+ UINT_8 u8SupportRxGf, UINT_8 u8SupportRxSTBC, ENUM_OP_MODE_T eCurrentOPMode, UINT_8 *pOutBuf) -+{ -+ P_IE_HT_CAP_T prHtCap; -+ P_SUP_MCS_SET_FIELD prSupMcsSet; -+ -+ ASSERT(pOutBuf); -+ -+ prHtCap = (P_IE_HT_CAP_T) pOutBuf; -+ -+ /* Add HT capabilities IE */ -+ prHtCap->ucId = ELEM_ID_HT_CAP; -+ prHtCap->ucLength = sizeof(IE_HT_CAP_T) - ELEM_HDR_LEN; -+ -+ prHtCap->u2HtCapInfo = HT_CAP_INFO_DEFAULT_VAL; -+ if (!fg40mAllowed) { -+ prHtCap->u2HtCapInfo &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH | -+ HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_DSSS_CCK_IN_40M); -+ } -+ if (fgShortGIDisabled) -+ prHtCap->u2HtCapInfo &= ~(HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M); -+ -+ if (u8SupportRxSgi20 == 2) -+ prHtCap->u2HtCapInfo &= ~(HT_CAP_INFO_SHORT_GI_20M); -+ if (u8SupportRxSgi40 == 2) -+ prHtCap->u2HtCapInfo &= ~(HT_CAP_INFO_SHORT_GI_40M); -+ if (u8SupportRxGf == 2) -+ prHtCap->u2HtCapInfo &= ~(HT_CAP_INFO_HT_GF); -+ if (u8SupportRxSTBC == 2) -+ prHtCap->u2HtCapInfo &= ~(HT_CAP_INFO_RX_STBC_1_SS); -+ prHtCap->ucAmpduParam = AMPDU_PARAM_DEFAULT_VAL; -+ -+ prSupMcsSet = &prHtCap->rSupMcsSet; -+ kalMemZero((PVOID)&prSupMcsSet->aucRxMcsBitmask[0], SUP_MCS_RX_BITMASK_OCTET_NUM); -+ -+ prSupMcsSet->aucRxMcsBitmask[0] = BITS(0, 7); -+ -+ if (fg40mAllowed) -+ prSupMcsSet->aucRxMcsBitmask[32 / 8] = BIT(0); /* MCS32 */ -+ prSupMcsSet->u2RxHighestSupportedRate = SUP_MCS_RX_DEFAULT_HIGHEST_RATE; -+ prSupMcsSet->u4TxRateInfo = SUP_MCS_TX_DEFAULT_VAL; -+ -+ prHtCap->u2HtExtendedCap = HT_EXT_CAP_DEFAULT_VAL; -+ if (!fg40mAllowed || eCurrentOPMode != OP_MODE_INFRASTRUCTURE) -+ prHtCap->u2HtExtendedCap &= ~(HT_EXT_CAP_PCO | HT_EXT_CAP_PCO_TRANS_TIME_NONE); -+ -+ prHtCap->u4TxBeamformingCap = TX_BEAMFORMING_CAP_DEFAULT_VAL; -+ -+ prHtCap->ucAselCap = ASEL_CAP_DEFAULT_VAL; -+ -+ ASSERT(IE_SIZE(prHtCap) <= (ELEM_HDR_LEN + ELEM_MAX_LEN_HT_CAP)); -+ -+ return IE_SIZE(prHtCap); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+static VOID rlmFillHtCapIE(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo, P_MSDU_INFO_T prMsduInfo) -+{ -+ P_IE_HT_CAP_T prHtCap; -+/* P_SUP_MCS_SET_FIELD prSupMcsSet; */ -+ BOOLEAN fg40mAllowed; -+ -+ ASSERT(prAdapter); -+ ASSERT(prBssInfo); -+ ASSERT(prMsduInfo); -+ -+ fg40mAllowed = prBssInfo->fgAssoc40mBwAllowed; -+ -+ prHtCap = (P_IE_HT_CAP_T) -+ (((PUINT_8) prMsduInfo->prPacket) + prMsduInfo->u2FrameLength); -+ -+#if 0 -+ /* Add HT capabilities IE */ -+ prHtCap->ucId = ELEM_ID_HT_CAP; -+ prHtCap->ucLength = sizeof(IE_HT_CAP_T) - ELEM_HDR_LEN; -+ -+ prHtCap->u2HtCapInfo = HT_CAP_INFO_DEFAULT_VAL; -+ if (!fg40mAllowed) -+ prHtCap->u2HtCapInfo &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH | -+ HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_DSSS_CCK_IN_40M); -+ if (prAdapter->rWifiVar.rConnSettings.fgRxShortGIDisabled) -+ prHtCap->u2HtCapInfo &= ~(HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M); -+ -+ if (prAdapter->rWifiVar.u8SupportRxSgi20 == 2) -+ prHtCap->u2HtCapInfo &= ~(HT_CAP_INFO_SHORT_GI_20M); -+ if (prAdapter->rWifiVar.u8SupportRxSgi40 == 2) -+ prHtCap->u2HtCapInfo &= ~(HT_CAP_INFO_SHORT_GI_40M); -+ if (prAdapter->rWifiVar.u8SupportRxGf == 2) -+ prHtCap->u2HtCapInfo &= ~(HT_CAP_INFO_HT_GF); -+ -+ prHtCap->ucAmpduParam = AMPDU_PARAM_DEFAULT_VAL; -+ -+ prSupMcsSet = &prHtCap->rSupMcsSet; -+ kalMemZero((PVOID)&prSupMcsSet->aucRxMcsBitmask[0], SUP_MCS_RX_BITMASK_OCTET_NUM); -+ -+ prSupMcsSet->aucRxMcsBitmask[0] = BITS(0, 7); -+ -+ if (fg40mAllowed) -+ prSupMcsSet->aucRxMcsBitmask[32 / 8] = BIT(0); /* MCS32 */ -+ prSupMcsSet->u2RxHighestSupportedRate = SUP_MCS_RX_DEFAULT_HIGHEST_RATE; -+ prSupMcsSet->u4TxRateInfo = SUP_MCS_TX_DEFAULT_VAL; -+ -+ prHtCap->u2HtExtendedCap = HT_EXT_CAP_DEFAULT_VAL; -+ if (!fg40mAllowed || prBssInfo->eCurrentOPMode != OP_MODE_INFRASTRUCTURE) -+ prHtCap->u2HtExtendedCap &= ~(HT_EXT_CAP_PCO | HT_EXT_CAP_PCO_TRANS_TIME_NONE); -+ -+ prHtCap->u4TxBeamformingCap = TX_BEAMFORMING_CAP_DEFAULT_VAL; -+ -+ prHtCap->ucAselCap = ASEL_CAP_DEFAULT_VAL; -+ -+ ASSERT(IE_SIZE(prHtCap) <= (ELEM_HDR_LEN + ELEM_MAX_LEN_HT_CAP)); -+ -+ prMsduInfo->u2FrameLength += IE_SIZE(prHtCap); -+#else -+ -+ prMsduInfo->u2FrameLength += rlmFillHtCapIEByParams(fg40mAllowed, -+ prAdapter->rWifiVar.rConnSettings.fgRxShortGIDisabled, -+ prAdapter->rWifiVar.u8SupportRxSgi20, -+ prAdapter->rWifiVar.u8SupportRxSgi40, -+ prAdapter->rWifiVar.u8SupportRxGf, -+ prAdapter->rWifiVar.u8SupportRxSTBC, -+ prBssInfo->eCurrentOPMode, (UINT_8 *) prHtCap); -+#endif -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+static VOID rlmFillExtCapIE(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo, P_MSDU_INFO_T prMsduInfo) -+{ -+#if CFG_SUPPORT_HOTSPOT_2_0 -+ P_HS20_EXT_CAP_T prHsExtCap; -+#else -+ P_EXT_CAP_T prExtCap; -+#endif -+ BOOLEAN fg40mAllowed; -+ -+ ASSERT(prAdapter); -+ ASSERT(prMsduInfo); -+ -+ fg40mAllowed = prBssInfo->fgAssoc40mBwAllowed; -+ -+#if CFG_SUPPORT_HOTSPOT_2_0 -+ prHsExtCap = (P_HS20_EXT_CAP_T) -+ (((PUINT_8) prMsduInfo->prPacket) + prMsduInfo->u2FrameLength); -+ prHsExtCap->ucId = ELEM_ID_EXTENDED_CAP; -+ -+ if (prAdapter->prGlueInfo->fgConnectHS20AP == TRUE) -+ prHsExtCap->ucLength = ELEM_MAX_LEN_EXT_CAP; -+ else -+ prHsExtCap->ucLength = 3 - ELEM_HDR_LEN; -+ -+ kalMemZero(prHsExtCap->aucCapabilities, sizeof(prHsExtCap->aucCapabilities)); -+ -+ prHsExtCap->aucCapabilities[0] = ELEM_EXT_CAP_DEFAULT_VAL; -+ -+ if (!fg40mAllowed) -+ prHsExtCap->aucCapabilities[0] &= ~ELEM_EXT_CAP_20_40_COEXIST_SUPPORT; -+ -+ if (prBssInfo->eCurrentOPMode != OP_MODE_INFRASTRUCTURE) -+ prHsExtCap->aucCapabilities[0] &= ~ELEM_EXT_CAP_PSMP_CAP; -+ -+ if (prAdapter->prGlueInfo->fgConnectHS20AP == TRUE) { -+ SET_EXT_CAP(prHsExtCap->aucCapabilities, ELEM_MAX_LEN_EXT_CAP, ELEM_EXT_CAP_INTERWORKING_BIT); -+ -+ /* For R2 WNM-Notification */ -+ SET_EXT_CAP(prHsExtCap->aucCapabilities, ELEM_MAX_LEN_EXT_CAP, ELEM_EXT_CAP_WNM_NOTIFICATION_BIT); -+ } -+ -+ ASSERT(IE_SIZE(prHsExtCap) <= (ELEM_HDR_LEN + ELEM_MAX_LEN_EXT_CAP)); -+ -+ prMsduInfo->u2FrameLength += IE_SIZE(prHsExtCap); -+ -+#else -+ /* Add Extended Capabilities IE */ -+ prExtCap = (P_EXT_CAP_T) -+ (((PUINT_8) prMsduInfo->prPacket) + prMsduInfo->u2FrameLength); -+ -+ prExtCap->ucId = ELEM_ID_EXTENDED_CAP; -+ -+ prExtCap->ucLength = 3 - ELEM_HDR_LEN; -+ kalMemZero(prExtCap->aucCapabilities, sizeof(prExtCap->aucCapabilities)); -+ -+ prExtCap->aucCapabilities[0] = ELEM_EXT_CAP_DEFAULT_VAL; -+ -+ if (!fg40mAllowed) -+ prExtCap->aucCapabilities[0] &= ~ELEM_EXT_CAP_20_40_COEXIST_SUPPORT; -+ -+ if (prBssInfo->eCurrentOPMode != OP_MODE_INFRASTRUCTURE) -+ prExtCap->aucCapabilities[0] &= ~ELEM_EXT_CAP_PSMP_CAP; -+ -+ ASSERT(IE_SIZE(prExtCap) <= (ELEM_HDR_LEN + ELEM_MAX_LEN_EXT_CAP)); -+ -+ prMsduInfo->u2FrameLength += IE_SIZE(prExtCap); -+#endif -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT32 rlmFillHtOpIeBody(P_BSS_INFO_T prBssInfo, UINT_8 *pFme) -+{ -+ P_IE_HT_OP_T prHtOp; -+ UINT_16 i; -+ -+ prHtOp = (P_IE_HT_OP_T) pFme; -+ -+ /* Add HT operation IE */ -+ prHtOp->ucId = ELEM_ID_HT_OP; -+ prHtOp->ucLength = sizeof(IE_HT_OP_T) - ELEM_HDR_LEN; -+ -+ /* RIFS and 20/40 bandwidth operations are included */ -+ prHtOp->ucPrimaryChannel = prBssInfo->ucPrimaryChannel; -+ prHtOp->ucInfo1 = prBssInfo->ucHtOpInfo1; -+ -+ /* Decide HT protection mode field */ -+ if (prBssInfo->eHtProtectMode == HT_PROTECT_MODE_NON_HT) -+ prHtOp->u2Info2 = (UINT_8) HT_PROTECT_MODE_NON_HT; -+ else if (prBssInfo->eObssHtProtectMode == HT_PROTECT_MODE_NON_MEMBER) -+ prHtOp->u2Info2 = (UINT_8) HT_PROTECT_MODE_NON_MEMBER; -+ else { -+ /* It may be SYS_PROTECT_MODE_NONE or SYS_PROTECT_MODE_20M */ -+ prHtOp->u2Info2 = (UINT_8) prBssInfo->eHtProtectMode; -+ } -+ -+ if (prBssInfo->eGfOperationMode != GF_MODE_NORMAL) { -+ /* It may be GF_MODE_PROTECT or GF_MODE_DISALLOWED -+ * Note: it will also be set in ad-hoc network -+ */ -+ prHtOp->u2Info2 |= HT_OP_INFO2_NON_GF_HT_STA_PRESENT; -+ } -+ -+ if (0 /* Regulatory class 16 */ && -+ prBssInfo->eObssHtProtectMode == HT_PROTECT_MODE_NON_MEMBER) { -+ /* (TBD) It is HT_PROTECT_MODE_NON_MEMBER, so require protection -+ * although it is possible to have no protection by spec. -+ */ -+ prHtOp->u2Info2 |= HT_OP_INFO2_OBSS_NON_HT_STA_PRESENT; -+ } -+ -+ prHtOp->u2Info3 = prBssInfo->u2HtOpInfo3; /* To do: handle L-SIG TXOP */ -+ -+ /* No basic MCSx are needed temporarily */ -+ for (i = 0; i < 16; i++) -+ prHtOp->aucBasicMcsSet[i] = 0; -+ -+ return sizeof(IE_HT_OP_T); -+} -+ -+static VOID rlmFillHtOpIE(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo, P_MSDU_INFO_T prMsduInfo) -+{ -+/* P_IE_HT_OP_T prHtOp; */ -+/* UINT_16 i; */ -+ -+ ASSERT(prAdapter); -+ ASSERT(prBssInfo); -+ ASSERT(prMsduInfo); -+ -+ prMsduInfo->u2FrameLength += rlmFillHtOpIeBody(prBssInfo, -+ (((PUINT_8) prMsduInfo->prPacket) + prMsduInfo->u2FrameLength)); -+#if 0 -+ prHtOp = (P_IE_HT_OP_T) -+ (((PUINT_8) prMsduInfo->prPacket) + prMsduInfo->u2FrameLength); -+ -+ /* Add HT operation IE */ -+ prHtOp->ucId = ELEM_ID_HT_OP; -+ prHtOp->ucLength = sizeof(IE_HT_OP_T) - ELEM_HDR_LEN; -+ -+ /* RIFS and 20/40 bandwidth operations are included */ -+ prHtOp->ucPrimaryChannel = prBssInfo->ucPrimaryChannel; -+ prHtOp->ucInfo1 = prBssInfo->ucHtOpInfo1; -+ -+ /* Decide HT protection mode field */ -+ if (prBssInfo->eHtProtectMode == HT_PROTECT_MODE_NON_HT) -+ prHtOp->u2Info2 = (UINT_8) HT_PROTECT_MODE_NON_HT; -+ else if (prBssInfo->eObssHtProtectMode == HT_PROTECT_MODE_NON_MEMBER) -+ prHtOp->u2Info2 = (UINT_8) HT_PROTECT_MODE_NON_MEMBER; -+ else { -+ /* It may be SYS_PROTECT_MODE_NONE or SYS_PROTECT_MODE_20M */ -+ prHtOp->u2Info2 = (UINT_8) prBssInfo->eHtProtectMode; -+ } -+ -+ if (prBssInfo->eGfOperationMode != GF_MODE_NORMAL) { -+ /* It may be GF_MODE_PROTECT or GF_MODE_DISALLOWED -+ * Note: it will also be set in ad-hoc network -+ */ -+ prHtOp->u2Info2 |= HT_OP_INFO2_NON_GF_HT_STA_PRESENT; -+ } -+ -+ if (0 /* Regulatory class 16 */ && -+ prBssInfo->eObssHtProtectMode == HT_PROTECT_MODE_NON_MEMBER) { -+ /* (TBD) It is HT_PROTECT_MODE_NON_MEMBER, so require protection -+ * although it is possible to have no protection by spec. -+ */ -+ prHtOp->u2Info2 |= HT_OP_INFO2_OBSS_NON_HT_STA_PRESENT; -+ } -+ -+ prHtOp->u2Info3 = prBssInfo->u2HtOpInfo3; /* To do: handle L-SIG TXOP */ -+ -+ /* No basic MCSx are needed temporarily */ -+ for (i = 0; i < 16; i++) -+ prHtOp->aucBasicMcsSet[i] = 0; -+ -+ ASSERT(IE_SIZE(prHtOp) <= (ELEM_HDR_LEN + ELEM_MAX_LEN_HT_OP)); -+ -+ prMsduInfo->u2FrameLength += IE_SIZE(prHtOp); -+#endif -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function should be invoked to update parameters of associated AP. -+* (Association response and Beacon) -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+static UINT_8 rlmRecIeInfoForClient(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo, PUINT_8 pucIE, UINT_16 u2IELength) -+{ -+ UINT_16 u2Offset; -+ P_STA_RECORD_T prStaRec; -+ P_IE_HT_CAP_T prHtCap; -+ P_IE_HT_OP_T prHtOp; -+ P_IE_OBSS_SCAN_PARAM_T prObssScnParam; -+ UINT_8 ucERP, ucPrimaryChannel; -+#if CFG_SUPPORT_QUIET && 0 -+ BOOLEAN fgHasQuietIE = FALSE; -+#endif -+ -+ ASSERT(prAdapter); -+ ASSERT(prBssInfo); -+ ASSERT(pucIE); -+ -+ prStaRec = prBssInfo->prStaRecOfAP; -+ ASSERT(prStaRec); -+ if (!prStaRec) -+ return 0; -+ -+ prBssInfo->fgUseShortPreamble = prBssInfo->fgIsShortPreambleAllowed; -+ ucPrimaryChannel = 0; -+ prObssScnParam = NULL; -+ -+ /* Note: HT-related members in staRec may not be zero before, so -+ * if following IE does not exist, they are still not zero. -+ * These HT-related parameters are valid only when the corresponding -+ * BssInfo supports 802.11n, i.e., RLM_NET_IS_11N() -+ */ -+ IE_FOR_EACH(pucIE, u2IELength, u2Offset) { -+ switch (IE_ID(pucIE)) { -+ case ELEM_ID_HT_CAP: -+ if (!RLM_NET_IS_11N(prBssInfo) || IE_LEN(pucIE) != (sizeof(IE_HT_CAP_T) - 2)) -+ break; -+ prHtCap = (P_IE_HT_CAP_T) pucIE; -+ prStaRec->ucMcsSet = prHtCap->rSupMcsSet.aucRxMcsBitmask[0]; -+ prStaRec->fgSupMcs32 = (prHtCap->rSupMcsSet.aucRxMcsBitmask[32 / 8] & BIT(0)) ? TRUE : FALSE; -+ -+ prStaRec->u2HtCapInfo = prHtCap->u2HtCapInfo; -+ prStaRec->ucAmpduParam = prHtCap->ucAmpduParam; -+ prStaRec->u2HtExtendedCap = prHtCap->u2HtExtendedCap; -+ prStaRec->u4TxBeamformingCap = prHtCap->u4TxBeamformingCap; -+ prStaRec->ucAselCap = prHtCap->ucAselCap; -+ break; -+ -+ case ELEM_ID_HT_OP: -+ if (!RLM_NET_IS_11N(prBssInfo) || IE_LEN(pucIE) != (sizeof(IE_HT_OP_T) - 2)) -+ break; -+ prHtOp = (P_IE_HT_OP_T) pucIE; -+ /* Workaround that some APs fill primary channel field by its -+ * secondary channel, but its DS IE is correct 20110610 -+ */ -+ if (ucPrimaryChannel == 0) -+ ucPrimaryChannel = prHtOp->ucPrimaryChannel; -+ prBssInfo->ucHtOpInfo1 = prHtOp->ucInfo1; -+ prBssInfo->u2HtOpInfo2 = prHtOp->u2Info2; -+ prBssInfo->u2HtOpInfo3 = prHtOp->u2Info3; -+ -+ if (!prBssInfo->fg40mBwAllowed) -+ prBssInfo->ucHtOpInfo1 &= ~(HT_OP_INFO1_SCO | HT_OP_INFO1_STA_CHNL_WIDTH); -+ -+ if ((prBssInfo->ucHtOpInfo1 & HT_OP_INFO1_SCO) != CHNL_EXT_RES) -+ prBssInfo->eBssSCO = (ENUM_CHNL_EXT_T)(prBssInfo->ucHtOpInfo1 & HT_OP_INFO1_SCO); -+ -+ prBssInfo->eHtProtectMode = (ENUM_HT_PROTECT_MODE_T) -+ (prBssInfo->u2HtOpInfo2 & HT_OP_INFO2_HT_PROTECTION); -+ -+ /* To do: process regulatory class 16 */ -+ if ((prBssInfo->u2HtOpInfo2 & HT_OP_INFO2_OBSS_NON_HT_STA_PRESENT) -+ && 0 /* && regulatory class is 16 */) -+ prBssInfo->eGfOperationMode = GF_MODE_DISALLOWED; -+ else if (prBssInfo->u2HtOpInfo2 & HT_OP_INFO2_NON_GF_HT_STA_PRESENT) -+ prBssInfo->eGfOperationMode = GF_MODE_PROTECT; -+ else -+ prBssInfo->eGfOperationMode = GF_MODE_NORMAL; -+ -+ prBssInfo->eRifsOperationMode = -+ (prBssInfo->ucHtOpInfo1 & HT_OP_INFO1_RIFS_MODE) ? RIFS_MODE_NORMAL : RIFS_MODE_DISALLOWED; -+ -+ break; -+ -+ case ELEM_ID_20_40_BSS_COEXISTENCE: -+ if (!RLM_NET_IS_11N(prBssInfo)) -+ break; -+ /* To do: store if scanning exemption grant to BssInfo */ -+ break; -+ -+ case ELEM_ID_OBSS_SCAN_PARAMS: -+ if (!RLM_NET_IS_11N(prBssInfo) || IE_LEN(pucIE) != (sizeof(IE_OBSS_SCAN_PARAM_T) - 2)) -+ break; -+ /* Store OBSS parameters to BssInfo */ -+ prObssScnParam = (P_IE_OBSS_SCAN_PARAM_T) pucIE; -+ break; -+ -+ case ELEM_ID_EXTENDED_CAP: -+ if (!RLM_NET_IS_11N(prBssInfo)) -+ break; -+ /* To do: store extended capability (PSMP, coexist) to BssInfo */ -+ break; -+ -+ case ELEM_ID_ERP_INFO: -+ if (IE_LEN(pucIE) != (sizeof(IE_ERP_T) - 2) || prBssInfo->eBand != BAND_2G4) -+ break; -+ ucERP = ERP_INFO_IE(pucIE)->ucERP; -+ prBssInfo->fgErpProtectMode = (ucERP & ERP_INFO_USE_PROTECTION) ? TRUE : FALSE; -+ -+ if (ucERP & ERP_INFO_BARKER_PREAMBLE_MODE) -+ prBssInfo->fgUseShortPreamble = FALSE; -+ break; -+ -+ case ELEM_ID_DS_PARAM_SET: -+ if (IE_LEN(pucIE) == ELEM_MAX_LEN_DS_PARAMETER_SET) -+ ucPrimaryChannel = DS_PARAM_IE(pucIE)->ucCurrChnl; -+ break; -+ -+#if CFG_SUPPORT_DFS /* Add by Enlai */ -+ case ELEM_ID_CH_SW_ANNOUNCEMENT: -+ { -+ rlmProcessChannelSwitchIE(prAdapter, (P_IE_CHANNEL_SWITCH_T) pucIE); -+ } -+ break; -+ -+#if CFG_SUPPORT_QUIET && 0 -+ /* Note: RRM code should be moved to independent RRM function by -+ * component design rule. But we attach it to RLM temporarily -+ */ -+ case ELEM_ID_QUIET: -+ rrmQuietHandleQuietIE(prBssInfo, (P_IE_QUIET_T) pucIE); -+ fgHasQuietIE = TRUE; -+ break; -+#endif -+#endif -+ -+ default: -+ break; -+ } /* end of switch */ -+ } /* end of IE_FOR_EACH */ -+ -+ /* Some AP will have wrong channel number (255) when running time. -+ * Check if correct channel number information. 20110501 -+ */ -+ if ((prBssInfo->eBand == BAND_2G4 && ucPrimaryChannel > 14) || -+ (prBssInfo->eBand != BAND_2G4 && (ucPrimaryChannel >= 200 || ucPrimaryChannel <= 14))) -+ ucPrimaryChannel = 0; -+#if CFG_SUPPORT_QUIET && 0 -+ if (!fgHasQuietIE) -+ rrmQuietIeNotExist(prAdapter, prBssInfo); -+#endif -+ -+ /* Check if OBSS scan process will launch */ -+ if (!prAdapter->fgEnOnlineScan || !prObssScnParam || -+ !(prStaRec->u2HtCapInfo & HT_CAP_INFO_SUP_CHNL_WIDTH) || -+ prBssInfo->eBand != BAND_2G4 || !prBssInfo->fg40mBwAllowed) { -+ -+ /* Note: it is ok not to stop rObssScanTimer() here */ -+ prBssInfo->u2ObssScanInterval = 0; -+ } else { -+ if (prObssScnParam->u2TriggerScanInterval < OBSS_SCAN_MIN_INTERVAL) -+ prObssScnParam->u2TriggerScanInterval = OBSS_SCAN_MIN_INTERVAL; -+ if (prBssInfo->u2ObssScanInterval != prObssScnParam->u2TriggerScanInterval) { -+ -+ prBssInfo->u2ObssScanInterval = prObssScnParam->u2TriggerScanInterval; -+ -+ /* Start timer to trigger OBSS scanning */ -+ cnmTimerStartTimer(prAdapter, &prBssInfo->rObssScanTimer, -+ prBssInfo->u2ObssScanInterval * MSEC_PER_SEC); -+ } -+ } -+ -+ return ucPrimaryChannel; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief AIS or P2P GC. -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+static BOOLEAN -+rlmRecBcnFromNeighborForClient(P_ADAPTER_T prAdapter, -+ P_BSS_INFO_T prBssInfo, P_SW_RFB_T prSwRfb, PUINT_8 pucIE, UINT_16 u2IELength) -+{ -+ UINT_16 u2Offset, i; -+ UINT_8 ucPriChannel, ucSecChannel; -+ ENUM_CHNL_EXT_T eSCO; -+ BOOLEAN fgHtBss, fg20mReq; -+ -+ if ((prAdapter == NULL) -+ || (pucIE == NULL) -+ || (prBssInfo == NULL) -+ || (prSwRfb == NULL)) { -+ ASSERT(FALSE); -+ return FALSE; -+ } -+ -+ /* Record it to channel list to change 20/40 bandwidth */ -+ ucPriChannel = 0; -+ eSCO = CHNL_EXT_SCN; -+ -+ fgHtBss = FALSE; -+ fg20mReq = FALSE; -+ -+ IE_FOR_EACH(pucIE, u2IELength, u2Offset) { -+ switch (IE_ID(pucIE)) { -+ case ELEM_ID_HT_CAP: -+ { -+ P_IE_HT_CAP_T prHtCap; -+ -+ if (IE_LEN(pucIE) != (sizeof(IE_HT_CAP_T) - 2)) -+ break; -+ -+ prHtCap = (P_IE_HT_CAP_T) pucIE; -+ if (prHtCap->u2HtCapInfo & HT_CAP_INFO_40M_INTOLERANT) -+ fg20mReq = TRUE; -+ fgHtBss = TRUE; -+ break; -+ } -+ case ELEM_ID_HT_OP: -+ { -+ P_IE_HT_OP_T prHtOp; -+ -+ if (IE_LEN(pucIE) != (sizeof(IE_HT_OP_T) - 2)) -+ break; -+ -+ prHtOp = (P_IE_HT_OP_T) pucIE; -+ /* Workaround that some APs fill primary channel field by its -+ * secondary channel, but its DS IE is correct 20110610 -+ */ -+ if (ucPriChannel == 0) -+ ucPriChannel = prHtOp->ucPrimaryChannel; -+ -+ if ((prHtOp->ucInfo1 & HT_OP_INFO1_SCO) != CHNL_EXT_RES) -+ eSCO = (ENUM_CHNL_EXT_T) (prHtOp->ucInfo1 & HT_OP_INFO1_SCO); -+ break; -+ } -+ case ELEM_ID_20_40_BSS_COEXISTENCE: -+ { -+ P_IE_20_40_COEXIST_T prCoexist; -+ -+ if (IE_LEN(pucIE) != (sizeof(IE_20_40_COEXIST_T) - 2)) -+ break; -+ -+ prCoexist = (P_IE_20_40_COEXIST_T) pucIE; -+ if (prCoexist->ucData & BSS_COEXIST_40M_INTOLERANT) -+ fg20mReq = TRUE; -+ break; -+ } -+ case ELEM_ID_DS_PARAM_SET: -+ if (IE_LEN(pucIE) != (sizeof(IE_DS_PARAM_SET_T) - 2)) -+ break; -+ ucPriChannel = DS_PARAM_IE(pucIE)->ucCurrChnl; -+ break; -+ -+ default: -+ break; -+ } -+ } -+ -+ /* To do: Update channel list and 5G band. All channel lists have the same -+ * update procedure. We should give it the entry pointer of desired -+ * channel list. -+ */ -+ if (HIF_RX_HDR_GET_RF_BAND(prSwRfb->prHifRxHdr) != BAND_2G4) -+ return FALSE; -+ -+ if (ucPriChannel == 0 || ucPriChannel > 14) -+ ucPriChannel = HIF_RX_HDR_GET_CHNL_NUM(prSwRfb->prHifRxHdr); -+ -+ if (fgHtBss) { -+ ASSERT(prBssInfo->auc2G_PriChnlList[0] <= CHNL_LIST_SZ_2G); -+ for (i = 1; i <= prBssInfo->auc2G_PriChnlList[0] && i <= CHNL_LIST_SZ_2G; i++) { -+ if (prBssInfo->auc2G_PriChnlList[i] == ucPriChannel) -+ break; -+ } -+ if ((i > prBssInfo->auc2G_PriChnlList[0]) && (i <= CHNL_LIST_SZ_2G)) { -+ prBssInfo->auc2G_PriChnlList[i] = ucPriChannel; -+ prBssInfo->auc2G_PriChnlList[0]++; -+ } -+ -+ /* Update secondary channel */ -+ if (eSCO != CHNL_EXT_SCN) { -+ ucSecChannel = (eSCO == CHNL_EXT_SCA) ? (ucPriChannel + 4) : (ucPriChannel - 4); -+ -+ ASSERT(prBssInfo->auc2G_SecChnlList[0] <= CHNL_LIST_SZ_2G); -+ for (i = 1; i <= prBssInfo->auc2G_SecChnlList[0] && i <= CHNL_LIST_SZ_2G; i++) { -+ if (prBssInfo->auc2G_SecChnlList[i] == ucSecChannel) -+ break; -+ } -+ if ((i > prBssInfo->auc2G_SecChnlList[0]) && (i <= CHNL_LIST_SZ_2G)) { -+ prBssInfo->auc2G_SecChnlList[i] = ucSecChannel; -+ prBssInfo->auc2G_SecChnlList[0]++; -+ } -+ } -+ -+ /* Update 20M bandwidth request channels */ -+ if (fg20mReq) { -+ ASSERT(prBssInfo->auc2G_20mReqChnlList[0] <= CHNL_LIST_SZ_2G); -+ for (i = 1; i <= prBssInfo->auc2G_20mReqChnlList[0] && i <= CHNL_LIST_SZ_2G; i++) { -+ if (prBssInfo->auc2G_20mReqChnlList[i] == ucPriChannel) -+ break; -+ } -+ if ((i > prBssInfo->auc2G_20mReqChnlList[0]) && (i <= CHNL_LIST_SZ_2G)) { -+ prBssInfo->auc2G_20mReqChnlList[i] = ucPriChannel; -+ prBssInfo->auc2G_20mReqChnlList[0]++; -+ } -+ } -+ } else { -+ /* Update non-HT channel list */ -+ ASSERT(prBssInfo->auc2G_NonHtChnlList[0] <= CHNL_LIST_SZ_2G); -+ for (i = 1; i <= prBssInfo->auc2G_NonHtChnlList[0] && i <= CHNL_LIST_SZ_2G; i++) { -+ if (prBssInfo->auc2G_NonHtChnlList[i] == ucPriChannel) -+ break; -+ } -+ if ((i > prBssInfo->auc2G_NonHtChnlList[0]) && (i <= CHNL_LIST_SZ_2G)) { -+ prBssInfo->auc2G_NonHtChnlList[i] = ucPriChannel; -+ prBssInfo->auc2G_NonHtChnlList[0]++; -+ } -+ -+ } -+ -+ return FALSE; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief AIS or P2P GC. -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+static BOOLEAN -+rlmRecBcnInfoForClient(P_ADAPTER_T prAdapter, -+ P_BSS_INFO_T prBssInfo, P_SW_RFB_T prSwRfb, PUINT_8 pucIE, UINT_16 u2IELength) -+{ -+ if ((prAdapter == NULL) -+ || (pucIE == NULL) -+ || (prBssInfo == NULL) -+ || (prSwRfb == NULL)) { -+ ASSERT(FALSE); -+ return FALSE; -+ } -+ -+#if 0 /* SW migration 2010/8/20 */ -+ /* Note: we shall not update parameters when scanning, otherwise -+ * channel and bandwidth will not be correct or asserted failure -+ * during scanning. -+ * Note: remove channel checking. All received Beacons should be processed -+ * if measurement or other actions are executed in adjacent channels -+ * and Beacon content checking mechanism is not disabled. -+ */ -+ if (IS_SCAN_ACTIVE() -+ /* || prBssInfo->ucPrimaryChannel != CHNL_NUM_BY_SWRFB(prSwRfb) */ -+ ) { -+ return FALSE; -+ } -+#endif -+ -+ /* Handle change of slot time */ -+ prBssInfo->u2CapInfo = ((P_WLAN_BEACON_FRAME_T) (prSwRfb->pvHeader))->u2CapInfo; -+ prBssInfo->fgUseShortSlotTime = (prBssInfo->u2CapInfo & CAP_INFO_SHORT_SLOT_TIME) ? TRUE : FALSE; -+ -+ rlmRecIeInfoForClient(prAdapter, prBssInfo, pucIE, u2IELength); -+ -+ return TRUE; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rlmProcessBcn(P_ADAPTER_T prAdapter, P_SW_RFB_T prSwRfb, PUINT_8 pucIE, UINT_16 u2IELength) -+{ -+ P_BSS_INFO_T prBssInfo; -+ BOOLEAN fgNewParameter; -+ UINT_8 ucNetIdx; -+ -+ ASSERT(prAdapter); -+ ASSERT(prSwRfb); -+ ASSERT(pucIE); -+ -+ fgNewParameter = FALSE; -+ -+ /* When concurrent networks exist, GO shall have the same handle as -+ * the other BSS, so the Beacon shall be processed for bandwidth and -+ * protection mechanism. -+ * Note1: we do not have 2 AP (GO) cases simultaneously now. -+ * Note2: If we are GO, concurrent AIS AP should detect it and reflect -+ * action in its Beacon, so AIS STA just follows Beacon from AP. -+ */ -+ RLM_NET_FOR_EACH_NO_BOW(ucNetIdx) { -+ prBssInfo = &prAdapter->rWifiVar.arBssInfo[ucNetIdx]; -+ ASSERT(prBssInfo); -+ -+ if (IS_BSS_ACTIVE(prBssInfo)) { -+ if (prBssInfo->eCurrentOPMode == OP_MODE_INFRASTRUCTURE && -+ prBssInfo->eConnectionState == PARAM_MEDIA_STATE_CONNECTED) { -+ /* P2P client or AIS infra STA */ -+ if (EQUAL_MAC_ADDR(prBssInfo->aucBSSID, ((P_WLAN_MAC_MGMT_HEADER_T) -+ (prSwRfb->pvHeader))->aucBSSID)) { -+ -+ fgNewParameter = rlmRecBcnInfoForClient(prAdapter, -+ prBssInfo, prSwRfb, pucIE, u2IELength); -+ } else { -+ fgNewParameter = rlmRecBcnFromNeighborForClient(prAdapter, -+ prBssInfo, prSwRfb, pucIE, -+ u2IELength); -+ } -+ } -+#if CFG_ENABLE_WIFI_DIRECT -+ else if (prAdapter->fgIsP2PRegistered && -+ (prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT || -+ prBssInfo->eCurrentOPMode == OP_MODE_P2P_DEVICE)) { -+ /* AP scan to check if 20/40M bandwidth is permitted */ -+ rlmRecBcnFromNeighborForClient(prAdapter, prBssInfo, prSwRfb, pucIE, u2IELength); -+ } -+#endif -+ else if (prBssInfo->eCurrentOPMode == OP_MODE_IBSS) { -+ /* Do nothing */ -+ /* To do: Ad-hoc */ -+ } -+ -+ /* Appy new parameters if necessary */ -+ if (fgNewParameter) { -+ DBGLOG(RLM, TRACE, "rlmProcessBcn\n"); -+ rlmSyncOperationParams(prAdapter, prBssInfo); -+ fgNewParameter = FALSE; -+ } -+ } /* end of IS_BSS_ACTIVE() */ -+ } /* end of RLM_NET_FOR_EACH_NO_BOW */ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function should be invoked after judging successful association. -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rlmProcessAssocRsp(P_ADAPTER_T prAdapter, P_SW_RFB_T prSwRfb, PUINT_8 pucIE, UINT_16 u2IELength) -+{ -+ P_BSS_INFO_T prBssInfo; -+ P_STA_RECORD_T prStaRec; -+ UINT_8 ucPriChannel; -+ -+ ASSERT(prAdapter); -+ ASSERT(prSwRfb); -+ ASSERT(pucIE); -+ -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); -+ ASSERT(prStaRec); -+ if (!prStaRec) -+ return; -+ ASSERT(prStaRec->ucNetTypeIndex < NETWORK_TYPE_INDEX_NUM); -+ -+ prBssInfo = &prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]; -+ ASSERT(prStaRec == prBssInfo->prStaRecOfAP); -+ -+ /* To do: the invoked function is used to clear all members. It may be -+ * done by center mechanism in invoker. -+ */ -+ rlmBssReset(prAdapter, prBssInfo); -+ -+ prBssInfo->fgUseShortSlotTime = (prBssInfo->u2CapInfo & CAP_INFO_SHORT_SLOT_TIME) ? TRUE : FALSE; -+ -+ ucPriChannel = rlmRecIeInfoForClient(prAdapter, prBssInfo, pucIE, u2IELength); -+ if (ucPriChannel > 0) -+ prBssInfo->ucPrimaryChannel = ucPriChannel; -+ -+ if (!RLM_NET_IS_11N(prBssInfo) || !(prStaRec->u2HtCapInfo & HT_CAP_INFO_SUP_CHNL_WIDTH)) -+ prBssInfo->fg40mBwAllowed = FALSE; -+ -+ /* Note: Update its capabilities to WTBL by cnmStaRecChangeState(), which -+ * shall be invoked afterwards. -+ * Update channel, bandwidth and protection mode by nicUpdateBss() -+ */ -+#if 1 -+ if (prStaRec->ucNetTypeIndex == NETWORK_TYPE_P2P_INDEX) { -+ -+ DBGLOG(P2P, WARN, "Force P2P BW to 20\n"); -+ prBssInfo->fgAssoc40mBwAllowed = FALSE; -+ } -+#endif -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function should be invoked after judging successful association. -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rlmFillSyncCmdParam(P_CMD_SET_BSS_RLM_PARAM_T prCmdBody, P_BSS_INFO_T prBssInfo) -+{ -+ ASSERT(prCmdBody && prBssInfo); -+ if (!prCmdBody || !prBssInfo) -+ return; -+ -+ prCmdBody->ucNetTypeIndex = prBssInfo->ucNetTypeIndex; -+ prCmdBody->ucRfBand = (UINT_8) prBssInfo->eBand; -+ prCmdBody->ucPrimaryChannel = prBssInfo->ucPrimaryChannel; -+ prCmdBody->ucRfSco = (UINT_8) prBssInfo->eBssSCO; -+ prCmdBody->ucErpProtectMode = (UINT_8) prBssInfo->fgErpProtectMode; -+ prCmdBody->ucHtProtectMode = (UINT_8) prBssInfo->eHtProtectMode; -+ prCmdBody->ucGfOperationMode = (UINT_8) prBssInfo->eGfOperationMode; -+ prCmdBody->ucTxRifsMode = (UINT_8) prBssInfo->eRifsOperationMode; -+ prCmdBody->u2HtOpInfo3 = prBssInfo->u2HtOpInfo3; -+ prCmdBody->u2HtOpInfo2 = prBssInfo->u2HtOpInfo2; -+ prCmdBody->ucHtOpInfo1 = prBssInfo->ucHtOpInfo1; -+ prCmdBody->ucUseShortPreamble = prBssInfo->fgUseShortPreamble; -+ prCmdBody->ucUseShortSlotTime = prBssInfo->fgUseShortSlotTime; -+ prCmdBody->ucCheckId = 0x72; -+ -+ if (RLM_NET_PARAM_VALID(prBssInfo)) { -+ DBGLOG(RLM, INFO, "N=%d b=%d c=%d s=%d e=%d h=%d I=0x%02x l=%d p=%d\n", -+ prCmdBody->ucNetTypeIndex, prCmdBody->ucRfBand, -+ prCmdBody->ucPrimaryChannel, prCmdBody->ucRfSco, -+ prCmdBody->ucErpProtectMode, prCmdBody->ucHtProtectMode, -+ prCmdBody->ucHtOpInfo1, prCmdBody->ucUseShortSlotTime, -+ prCmdBody->ucUseShortPreamble); -+ } else { -+ DBGLOG(RLM, TRACE, "N=%d closed\n", prCmdBody->ucNetTypeIndex); -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will operation parameters based on situations of -+* concurrent networks. Channel, bandwidth, protection mode, supported -+* rate will be modified. -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rlmSyncOperationParams(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo) -+{ -+ P_CMD_SET_BSS_RLM_PARAM_T prCmdBody; -+ WLAN_STATUS rStatus; -+ -+ ASSERT(prAdapter); -+ ASSERT(prBssInfo); -+ -+ prCmdBody = (P_CMD_SET_BSS_RLM_PARAM_T) -+ cnmMemAlloc(prAdapter, RAM_TYPE_BUF, sizeof(CMD_SET_BSS_RLM_PARAM_T)); -+ ASSERT(prCmdBody); -+ -+ /* To do: exception handle */ -+ if (!prCmdBody) { -+ DBGLOG(RLM, WARN, "No buf for sync RLM params (Net=%d)\n", prBssInfo->ucNetTypeIndex); -+ return; -+ } -+ -+ rlmFillSyncCmdParam(prCmdBody, prBssInfo); -+ -+ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ -+ CMD_ID_SET_BSS_RLM_PARAM, /* ucCID */ -+ TRUE, /* fgSetQuery */ -+ FALSE, /* fgNeedResp */ -+ FALSE, /* fgIsOid */ -+ NULL, /* pfCmdDoneHandler */ -+ NULL, /* pfCmdTimeoutHandler */ -+ sizeof(CMD_SET_BSS_RLM_PARAM_T), /* u4SetQueryInfoLen */ -+ (PUINT_8) prCmdBody, /* pucInfoBuffer */ -+ NULL, /* pvSetQueryBuffer */ -+ 0 /* u4SetQueryBufferLen */ -+ ); -+ -+ ASSERT(rStatus == WLAN_STATUS_PENDING); -+ -+ cnmMemFree(prAdapter, prCmdBody); -+} -+ -+#if CFG_SUPPORT_AAA -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function should be invoked after judging successful association. -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rlmProcessAssocReq(P_ADAPTER_T prAdapter, P_SW_RFB_T prSwRfb, PUINT_8 pucIE, UINT_16 u2IELength) -+{ -+ P_BSS_INFO_T prBssInfo; -+ P_STA_RECORD_T prStaRec; -+ UINT_16 u2Offset; -+ P_IE_HT_CAP_T prHtCap; -+ -+ ASSERT(prAdapter); -+ ASSERT(prSwRfb); -+ ASSERT(pucIE); -+ -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); -+ ASSERT(prStaRec); -+ if (!prStaRec) -+ return; -+ ASSERT(prStaRec->ucNetTypeIndex < NETWORK_TYPE_INDEX_NUM); -+ -+ prBssInfo = &prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]; -+ -+ IE_FOR_EACH(pucIE, u2IELength, u2Offset) { -+ switch (IE_ID(pucIE)) { -+ case ELEM_ID_HT_CAP: -+ if (!RLM_NET_IS_11N(prBssInfo) || IE_LEN(pucIE) != (sizeof(IE_HT_CAP_T) - 2)) -+ break; -+ prHtCap = (P_IE_HT_CAP_T) pucIE; -+ prStaRec->ucMcsSet = prHtCap->rSupMcsSet.aucRxMcsBitmask[0]; -+ prStaRec->fgSupMcs32 = (prHtCap->rSupMcsSet.aucRxMcsBitmask[32 / 8] & BIT(0)) ? TRUE : FALSE; -+ -+ prStaRec->u2HtCapInfo = prHtCap->u2HtCapInfo; -+ prStaRec->ucAmpduParam = prHtCap->ucAmpduParam; -+ prStaRec->u2HtExtendedCap = prHtCap->u2HtExtendedCap; -+ prStaRec->u4TxBeamformingCap = prHtCap->u4TxBeamformingCap; -+ prStaRec->ucAselCap = prHtCap->ucAselCap; -+ break; -+ -+ default: -+ break; -+ } /* end of switch */ -+ } /* end of IE_FOR_EACH */ -+} -+#endif /* CFG_SUPPORT_AAA */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief It is for both STA and AP modes -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rlmBssInitForAPandIbss(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo) -+{ -+ ASSERT(prAdapter); -+ ASSERT(prBssInfo); -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ if (prAdapter->fgIsP2PRegistered && prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT) -+ rlmBssInitForAP(prAdapter, prBssInfo); -+#endif -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief It is for both STA and AP modes -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rlmBssAborted(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo) -+{ -+ ASSERT(prAdapter); -+ ASSERT(prBssInfo); -+ -+ rlmBssReset(prAdapter, prBssInfo); -+ -+ prBssInfo->fg40mBwAllowed = FALSE; -+ prBssInfo->fgAssoc40mBwAllowed = FALSE; -+ -+ /* Assume FW state is updated by CMD_ID_SET_BSS_INFO, so -+ * the sync CMD is not needed here. -+ */ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief All RLM timers will also be stopped. -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+static VOID rlmBssReset(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo) -+{ -+ ASSERT(prAdapter); -+ ASSERT(prBssInfo); -+ -+ /* HT related parameters */ -+ prBssInfo->ucHtOpInfo1 = 0; /* RIFS disabled. 20MHz */ -+ prBssInfo->u2HtOpInfo2 = 0; -+ prBssInfo->u2HtOpInfo3 = 0; -+ -+ prBssInfo->eBssSCO = 0; -+ prBssInfo->fgErpProtectMode = 0; -+ prBssInfo->eHtProtectMode = 0; -+ prBssInfo->eGfOperationMode = 0; -+ prBssInfo->eRifsOperationMode = 0; -+ -+ /* OBSS related parameters */ -+ prBssInfo->auc2G_20mReqChnlList[0] = 0; -+ prBssInfo->auc2G_NonHtChnlList[0] = 0; -+ prBssInfo->auc2G_PriChnlList[0] = 0; -+ prBssInfo->auc2G_SecChnlList[0] = 0; -+ prBssInfo->auc5G_20mReqChnlList[0] = 0; -+ prBssInfo->auc5G_NonHtChnlList[0] = 0; -+ prBssInfo->auc5G_PriChnlList[0] = 0; -+ prBssInfo->auc5G_SecChnlList[0] = 0; -+ -+ /* All RLM timers will also be stopped */ -+ cnmTimerStopTimer(prAdapter, &prBssInfo->rObssScanTimer); -+ prBssInfo->u2ObssScanInterval = 0; -+ -+ prBssInfo->fgObssErpProtectMode = 0; /* GO only */ -+ prBssInfo->eObssHtProtectMode = 0; /* GO only */ -+ prBssInfo->eObssGfOperationMode = 0; /* GO only */ -+ prBssInfo->fgObssRifsOperationMode = 0; /* GO only */ -+ prBssInfo->fgObssActionForcedTo20M = 0; /* GO only */ -+ prBssInfo->fgObssBeaconForcedTo20M = 0; /* GO only */ -+} -+ -+#if CFG_SUPPORT_DFS /* Add by Enlai */ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function handle spectrum management action frame -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rlmProcessSpecMgtAction(P_ADAPTER_T prAdapter, P_SW_RFB_T prSwRfb) -+{ -+ P_ACTION_CHANNEL_SWITCH_FRAME prRxFrame; -+ -+ ASSERT(prAdapter); -+ ASSERT(prSwRfb); -+ -+ DBGLOG(RLM, INFO, "[5G DFS]rlmProcessSpecMgtAction \r\n"); -+ -+ prRxFrame = (P_ACTION_CHANNEL_SWITCH_FRAME) prSwRfb->pvHeader; -+ DBGLOG(RLM, INFO, "[5G DFS]prRxFrame->ucAction[%d] \r\n", prRxFrame->ucAction); -+ if (prRxFrame->ucAction == ACTION_CHNL_SWITCH) -+ rlmProcessChannelSwitchIE(prAdapter, (P_IE_CHANNEL_SWITCH_T) prRxFrame->aucInfoElem); -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function process Channel Switch IE -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rlmProcessChannelSwitchIE(P_ADAPTER_T prAdapter, P_IE_CHANNEL_SWITCH_T prChannelSwitchIE) -+{ -+ P_BSS_INFO_T prAisBssInfo; -+ -+ ASSERT(prAdapter); -+ ASSERT(prChannelSwitchIE); -+ -+ DBGLOG(RLM, INFO, "[5G DFS] rlmProcessChannelSwitchIE \r\n"); -+ DBGLOG(RLM, INFO, "[5G DFS] ucChannelSwitchMode[%d], ucChannelSwitchCount[%d], ucNewChannelNum[%d] \r\n", -+ prChannelSwitchIE->ucChannelSwitchMode, -+ prChannelSwitchIE->ucChannelSwitchCount, prChannelSwitchIE->ucNewChannelNum); -+ if (prChannelSwitchIE->ucChannelSwitchMode == 1) { -+ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ DBGLOG(RLM, INFO, "[5G DFS] switch channel [%d]->[%d] \r\n", prAisBssInfo->ucPrimaryChannel, -+ prChannelSwitchIE->ucNewChannelNum); -+ prAisBssInfo->ucPrimaryChannel = prChannelSwitchIE->ucNewChannelNum; -+ nicUpdateBss(prAdapter, prAisBssInfo->ucNetTypeIndex); -+ } -+ -+} -+ -+#endif -+ -+#if (CFG_SUPPORT_TXR_ENC == 1) -+VOID -+rlmTxRateEnhanceConfig( -+ P_ADAPTER_T prAdapter -+ ) -+{ -+ P_GLUE_INFO_T prGlueInfo; -+ WLAN_STATUS rStatus = WLAN_STATUS_FAILURE; -+ CMD_RLM_INFO_T rTxRInfo; -+ UINT_32 u4SetInfoLen = 0; -+ -+ -+ /* init */ -+ prGlueInfo = prAdapter->prGlueInfo; -+ -+ /* suggestion from Tsaiyuan.Hsu */ -+ kalMemZero(&rTxRInfo, sizeof(CMD_RLM_INFO_T)); -+ rTxRInfo.fgIsErrRatioEnhanceApplied = TRUE; -+ rTxRInfo.ucErrRatio2LimitMinRate = 3; -+ rTxRInfo.ucMinLegacyRateIdx = 2; -+ rTxRInfo.cMinRssiThreshold = -60; -+ rTxRInfo.fgIsRtsApplied = TRUE; -+ rTxRInfo.ucRecoverTime = 60; -+ -+ DBGLOG(RLM, INFO, "Enable tx rate enhance function\n"); -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetTxRateInfo, -+ &rTxRInfo, -+ sizeof(rTxRInfo), -+ TRUE, -+ TRUE, -+ TRUE, -+ FALSE, -+ &u4SetInfoLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) -+ DBGLOG(RLM, WARN, "set tx rate advance info fail 0x%lx\n", rStatus); -+} -+ -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to send a command to TX Auto Rate module. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prInBuf A pointer to the command string buffer -+* \param[in] u4InBufLen The length of the buffer -+* \param[out] None -+* -+* \retval None -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+rlmCmd(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) -+{ -+ UINT_32 u4Subcmd; -+ -+ -+ /* parse TAR sub-command */ -+ u4Subcmd = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ DBGLOG(RLM, INFO, " sub command = %u\n", (UINT32)u4Subcmd); -+ -+ /* handle different sub-command */ -+ switch (u4Subcmd) { -+ case 0x00: /* configure */ -+ /* iwpriv wlan0 set_str_cmd 1_0_0_1_3_2_60_1_60 */ -+ WLAN_STATUS rStatus = WLAN_STATUS_FAILURE; -+ CMD_RLM_INFO_T rTxRInfo; -+ UINT_32 u4SetInfoLen = 0; -+ -+ kalMemZero(&rTxRInfo, sizeof(CMD_RLM_INFO_T)); -+ rTxRInfo.u4Version = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ rTxRInfo.fgIsErrRatioEnhanceApplied = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ rTxRInfo.ucErrRatio2LimitMinRate = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ rTxRInfo.ucMinLegacyRateIdx = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ rTxRInfo.cMinRssiThreshold = 0 - CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ rTxRInfo.fgIsRtsApplied = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ rTxRInfo.ucRecoverTime = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ -+ DBGLOG(RLM, INFO, " rlmCmd = %u %u %u %u %d %u %u\n", -+ rTxRInfo.u4Version, -+ rTxRInfo.fgIsErrRatioEnhanceApplied, -+ rTxRInfo.ucErrRatio2LimitMinRate, -+ rTxRInfo.ucMinLegacyRateIdx, -+ rTxRInfo.cMinRssiThreshold, -+ rTxRInfo.fgIsRtsApplied, -+ rTxRInfo.ucRecoverTime)); -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetTxRateInfo, -+ &rTxRInfo, -+ sizeof(rTxRInfo), -+ TRUE, -+ TRUE, -+ TRUE, -+ FALSE, -+ &u4SetInfoLen); -+ break; -+ -+ default: -+ break; -+ } -+} -+#endif /* CFG_SUPPORT_TXR_ENC */ -+ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rlm_domain.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rlm_domain.c -new file mode 100644 -index 000000000000..5e127488ea49 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rlm_domain.c -@@ -0,0 +1,1791 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/rlm_domain.c#1 -+*/ -+ -+/*! \file "rlm_domain.c" -+ \brief -+ -+*/ -+ -+/* -+** Log: rlm_domain.c -+ * -+ * 11 10 2011 cm.chang -+ * NULL -+ * Modify debug message for XLOG -+ * -+ * 09 29 2011 cm.chang -+ * NULL -+ * Change the function prototype of rlmDomainGetChnlList() -+ * -+ * 09 23 2011 cm.chang -+ * [WCXRP00000969] [MT6620 Wi-Fi][Driver][FW] Channel list for 5G band based on country code -+ * Let channel number to zero if band is illegal -+ * -+ * 09 22 2011 cm.chang -+ * [WCXRP00000969] [MT6620 Wi-Fi][Driver][FW] Channel list for 5G band based on country code -+ * Exclude channel list with illegal band -+ * -+ * 09 15 2011 cm.chang -+ * [WCXRP00000969] [MT6620 Wi-Fi][Driver][FW] Channel list for 5G band based on country code -+ * Use defined country group to have a change to add new group -+ * -+ * 09 08 2011 cm.chang -+ * [WCXRP00000969] [MT6620 Wi-Fi][Driver][FW] Channel list for 5G band based on country code -+ * Use new fields ucChannelListMap and ucChannelListIndex in NVRAM -+ * -+ * 08 31 2011 cm.chang -+ * [WCXRP00000969] [MT6620 Wi-Fi][Driver][FW] Channel list for 5G band based on country code -+ * . -+ * -+ * 06 01 2011 cm.chang -+ * [WCXRP00000756] [MT6620 Wi-Fi][Driver] 1. AIS follow channel of BOW 2. Provide legal channel function -+ * Provide legal channel function based on domain -+ * -+ * 03 19 2011 yuche.tsai -+ * [WCXRP00000584] [Volunteer Patch][MT6620][Driver] Add beacon timeout support for WiFi Direct. -+ * Add beacon timeout support for WiFi Direct Network. -+ * -+ * 03 02 2011 terry.wu -+ * [WCXRP00000505] [MT6620 Wi-Fi][Driver/FW] WiFi Direct Integration -+ * Export rlmDomainGetDomainInfo for p2p driver. -+ * -+ * 01 12 2011 cm.chang -+ * [WCXRP00000354] [MT6620 Wi-Fi][Driver][FW] Follow NVRAM bandwidth setting -+ * User-defined bandwidth is for 2.4G and 5G individually -+ * -+ * 12 07 2010 cm.chang -+ * [WCXRP00000238] MT6620 Wi-Fi][Driver][FW] Support regulation domain setting from NVRAM and supplicant -+ * 1. Country code is from NVRAM or supplicant -+ * 2. Change band definition in CMD/EVENT. -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 07 08 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Check draft RLM code for HT cap -+ * -+ * 03 25 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Filter out not supported RF freq when reporting available chnl list -+ * -+ * 01 22 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Support protection and bandwidth switch -+ * -+ * 01 13 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Provide query function about full channel list. -+ * -+ * Dec 1 2009 mtk01104 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * -+ * -+** -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "precomp.h" -+#include "rlm_txpwr_init.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/* The following country or domain shall be set from host driver. -+ * And host driver should pass specified DOMAIN_INFO_ENTRY to MT6620 as -+ * the channel list of being a STA to do scanning/searching AP or being an -+ * AP to choose an adequate channel if auto-channel is set. -+ */ -+ -+/* Define mapping tables between country code and its channel set -+ */ -+static const UINT_16 g_u2CountryGroup0[] = { -+ COUNTRY_CODE_AO, COUNTRY_CODE_BZ, COUNTRY_CODE_BJ, COUNTRY_CODE_BT, -+ COUNTRY_CODE_BO, COUNTRY_CODE_BI, COUNTRY_CODE_CM, COUNTRY_CODE_CF, -+ COUNTRY_CODE_TD, COUNTRY_CODE_KM, COUNTRY_CODE_CD, COUNTRY_CODE_CG, -+ COUNTRY_CODE_CI, COUNTRY_CODE_DJ, COUNTRY_CODE_GQ, COUNTRY_CODE_ER, -+ COUNTRY_CODE_FJ, COUNTRY_CODE_GA, COUNTRY_CODE_GM, COUNTRY_CODE_GN, -+ COUNTRY_CODE_GW, COUNTRY_CODE_RKS, COUNTRY_CODE_KG, COUNTRY_CODE_LY, -+ COUNTRY_CODE_MG, COUNTRY_CODE_ML, COUNTRY_CODE_NR, COUNTRY_CODE_NC, -+ COUNTRY_CODE_ST, COUNTRY_CODE_SC, COUNTRY_CODE_SL, COUNTRY_CODE_SB, -+ COUNTRY_CODE_SO, COUNTRY_CODE_SR, COUNTRY_CODE_SZ, COUNTRY_CODE_TJ, -+ COUNTRY_CODE_TG, COUNTRY_CODE_TO, COUNTRY_CODE_TM, COUNTRY_CODE_TV, -+ COUNTRY_CODE_VU, COUNTRY_CODE_YE -+}; -+ -+static const UINT_16 g_u2CountryGroup1[] = { -+ COUNTRY_CODE_AS, COUNTRY_CODE_AI, COUNTRY_CODE_BM, COUNTRY_CODE_CA, -+ COUNTRY_CODE_KY, COUNTRY_CODE_GU, COUNTRY_CODE_FM, COUNTRY_CODE_PR, -+ COUNTRY_CODE_US, COUNTRY_CODE_VI -+}; -+ -+static const UINT_16 g_u2CountryGroup2[] = { -+ COUNTRY_CODE_AR, COUNTRY_CODE_AU, COUNTRY_CODE_AZ, COUNTRY_CODE_BW, -+ COUNTRY_CODE_KH, COUNTRY_CODE_CX, COUNTRY_CODE_CO, COUNTRY_CODE_CR, -+#if (CFG_CN_SUPPORT_CLASS121 == 1) -+ COUNTRY_CODE_CN, -+#endif -+ COUNTRY_CODE_EC, COUNTRY_CODE_GD, COUNTRY_CODE_GT, COUNTRY_CODE_HK, -+ COUNTRY_CODE_KI, COUNTRY_CODE_LB, COUNTRY_CODE_LR, COUNTRY_CODE_MN, -+ COUNTRY_CODE_AN, COUNTRY_CODE_NZ, COUNTRY_CODE_NI, COUNTRY_CODE_PW, -+ COUNTRY_CODE_PY, COUNTRY_CODE_PE, COUNTRY_CODE_PH, COUNTRY_CODE_WS, -+ COUNTRY_CODE_SG, COUNTRY_CODE_LK, COUNTRY_CODE_TH, COUNTRY_CODE_TT, -+ COUNTRY_CODE_UY, COUNTRY_CODE_VN -+}; -+ -+static const UINT_16 g_u2CountryGroup3[] = { -+ COUNTRY_CODE_AW, COUNTRY_CODE_LA, COUNTRY_CODE_SA, COUNTRY_CODE_AE, -+ COUNTRY_CODE_UG -+}; -+ -+static const UINT_16 g_u2CountryGroup4[] = { COUNTRY_CODE_MM }; -+ -+static const UINT_16 g_u2CountryGroup5[] = { -+ COUNTRY_CODE_AL, COUNTRY_CODE_DZ, COUNTRY_CODE_AD, COUNTRY_CODE_AT, -+ COUNTRY_CODE_BY, COUNTRY_CODE_BE, COUNTRY_CODE_BA, COUNTRY_CODE_VG, -+ COUNTRY_CODE_BG, COUNTRY_CODE_CV, COUNTRY_CODE_HR, COUNTRY_CODE_CY, -+ COUNTRY_CODE_CZ, COUNTRY_CODE_DK, COUNTRY_CODE_EE, COUNTRY_CODE_ET, -+ COUNTRY_CODE_FI, COUNTRY_CODE_FR, COUNTRY_CODE_GF, COUNTRY_CODE_PF, -+ COUNTRY_CODE_TF, COUNTRY_CODE_GE, COUNTRY_CODE_DE, COUNTRY_CODE_GH, -+ COUNTRY_CODE_GR, COUNTRY_CODE_GP, COUNTRY_CODE_HU, COUNTRY_CODE_IS, -+ COUNTRY_CODE_IQ, COUNTRY_CODE_IE, COUNTRY_CODE_IT, COUNTRY_CODE_KE, -+ COUNTRY_CODE_LV, COUNTRY_CODE_LS, COUNTRY_CODE_LI, COUNTRY_CODE_LT, -+ COUNTRY_CODE_LU, COUNTRY_CODE_MK, COUNTRY_CODE_MT, COUNTRY_CODE_MQ, -+ COUNTRY_CODE_MR, COUNTRY_CODE_MU, COUNTRY_CODE_YT, COUNTRY_CODE_MD, -+ COUNTRY_CODE_MC, COUNTRY_CODE_ME, COUNTRY_CODE_MS, COUNTRY_CODE_NL, -+ COUNTRY_CODE_NO, COUNTRY_CODE_OM, COUNTRY_CODE_PL, COUNTRY_CODE_PT, -+ COUNTRY_CODE_RE, COUNTRY_CODE_RO, COUNTRY_CODE_MF, COUNTRY_CODE_SM, -+ COUNTRY_CODE_SN, COUNTRY_CODE_RS, COUNTRY_CODE_SK, COUNTRY_CODE_SI, -+ COUNTRY_CODE_ZA, COUNTRY_CODE_ES, COUNTRY_CODE_SE, COUNTRY_CODE_CH, -+ COUNTRY_CODE_TR, COUNTRY_CODE_TC, COUNTRY_CODE_GB, COUNTRY_CODE_VA, -+ COUNTRY_CODE_EU -+}; -+ -+static const UINT_16 g_u2CountryGroup6[] = { COUNTRY_CODE_JP }; -+ -+static const UINT_16 g_u2CountryGroup7[] = { -+ COUNTRY_CODE_AM, COUNTRY_CODE_IL, COUNTRY_CODE_KW, COUNTRY_CODE_MA, -+ COUNTRY_CODE_NE, COUNTRY_CODE_TN, COUNTRY_CODE_MA -+}; -+ -+static const UINT_16 g_u2CountryGroup8[] = { COUNTRY_CODE_NP }; -+ -+static const UINT_16 g_u2CountryGroup9[] = { COUNTRY_CODE_AF }; -+ -+static const UINT_16 g_u2CountryGroup10[] = { -+ COUNTRY_CODE_AG, COUNTRY_CODE_BS, COUNTRY_CODE_BH, COUNTRY_CODE_BB, -+ COUNTRY_CODE_BN, COUNTRY_CODE_CL, COUNTRY_CODE_EG, -+#if (CFG_CN_SUPPORT_CLASS121 == 0) -+ COUNTRY_CODE_CN, -+#endif -+ COUNTRY_CODE_SV, COUNTRY_CODE_IN, COUNTRY_CODE_MY, COUNTRY_CODE_MV, -+ COUNTRY_CODE_PA, COUNTRY_CODE_VE, COUNTRY_CODE_ZM -+}; -+ -+static const UINT_16 g_u2CountryGroup11[] = { COUNTRY_CODE_JO, COUNTRY_CODE_PG }; -+ -+static const UINT_16 g_u2CountryGroup12[] = { -+ COUNTRY_CODE_BF, COUNTRY_CODE_GY, COUNTRY_CODE_HT, COUNTRY_CODE_HN, -+ COUNTRY_CODE_JM, COUNTRY_CODE_MO, COUNTRY_CODE_MW, COUNTRY_CODE_PK, -+ COUNTRY_CODE_QA, COUNTRY_CODE_RW, COUNTRY_CODE_KN, COUNTRY_CODE_TZ -+}; -+ -+static const UINT_16 g_u2CountryGroup13[] = { COUNTRY_CODE_ID }; -+ -+static const UINT_16 g_u2CountryGroup14[] = { COUNTRY_CODE_KR }; -+ -+static const UINT_16 g_u2CountryGroup15[] = { COUNTRY_CODE_NG }; -+ -+static const UINT_16 g_u2CountryGroup16[] = { -+ COUNTRY_CODE_BD, COUNTRY_CODE_BR, COUNTRY_CODE_DM, COUNTRY_CODE_DO, -+ COUNTRY_CODE_FK, COUNTRY_CODE_KZ, COUNTRY_CODE_MX, COUNTRY_CODE_MZ, -+ COUNTRY_CODE_NA, COUNTRY_CODE_RU, COUNTRY_CODE_LC, COUNTRY_CODE_VC, -+ COUNTRY_CODE_UA, COUNTRY_CODE_UZ, COUNTRY_CODE_ZW -+}; -+ -+static const UINT_16 g_u2CountryGroup17[] = { COUNTRY_CODE_MP }; -+ -+static const UINT_16 g_u2CountryGroup18[] = { COUNTRY_CODE_TW }; -+ -+static const UINT_16 g_u2CountryGroup19[] = { -+ COUNTRY_CODE_CK, COUNTRY_CODE_CU, COUNTRY_CODE_TL, COUNTRY_CODE_FO, -+ COUNTRY_CODE_GI, COUNTRY_CODE_GG, COUNTRY_CODE_IR, COUNTRY_CODE_IM, -+ COUNTRY_CODE_JE, COUNTRY_CODE_KP, COUNTRY_CODE_MH, COUNTRY_CODE_NU, -+ COUNTRY_CODE_NF, COUNTRY_CODE_PS, COUNTRY_CODE_PN, COUNTRY_CODE_PM, -+ COUNTRY_CODE_SS, COUNTRY_CODE_SD, COUNTRY_CODE_SY -+}; -+ -+static const UINT_16 g_u2CountryGroup20[] = { -+ COUNTRY_CODE_DF, COUNTRY_CODE_FF -+ /* When country code is not found and no matched NVRAM setting, -+ * this domain info will be used. -+ */ -+}; -+ -+static const UINT_16 g_u2CountryGroup21[] = { -+ COUNTRY_CODE_UDF -+}; -+ -+DOMAIN_INFO_ENTRY arSupportedRegDomains[] = { -+ { -+ (PUINT_16) g_u2CountryGroup0, sizeof(g_u2CountryGroup0) / 2, -+ { -+ {81, BAND_2G4, CHNL_SPAN_5, 1, 13, FALSE} -+ , /* CH_SET_2G4_1_13 */ -+ -+ {115, BAND_NULL, 0, 0, 0, FALSE} -+ , /* CH_SET_UNII_LOW_NA */ -+ {118, BAND_NULL, 0, 0, 0, FALSE} -+ , /* CH_SET_UNII_MID_NA */ -+ {121, BAND_NULL, 0, 0, 0, FALSE} -+ , /* CH_SET_UNII_WW_NA */ -+ {125, BAND_NULL, 0, 0, 0, FALSE} -+ , /* CH_SET_UNII_UPPER_NA */ -+ {0, BAND_NULL, 0, 0, 0, FALSE} -+ } -+ } -+ , -+ { -+ (PUINT_16) g_u2CountryGroup1, sizeof(g_u2CountryGroup1) / 2, -+ { -+ {81, BAND_2G4, CHNL_SPAN_5, 1, 11, FALSE} -+ , /* CH_SET_2G4_1_11 */ -+ -+ {115, BAND_5G, CHNL_SPAN_20, 36, 4, FALSE} -+ , /* CH_SET_UNII_LOW_36_48 */ -+ {118, BAND_5G, CHNL_SPAN_20, 52, 4, TRUE} -+ , /* CH_SET_UNII_MID_52_64 */ -+ {121, BAND_5G, CHNL_SPAN_20, 100, 12, TRUE} -+ , /* CH_SET_UNII_WW_100_144 */ -+ {125, BAND_5G, CHNL_SPAN_20, 149, 5, FALSE} -+ , /* CH_SET_UNII_UPPER_149_165 */ -+ {0, BAND_NULL, 0, 0, 0, FALSE} -+ } -+ } -+ , -+ { -+ (PUINT_16) g_u2CountryGroup2, sizeof(g_u2CountryGroup2) / 2, -+ { -+ {81, BAND_2G4, CHNL_SPAN_5, 1, 13, FALSE} -+ , /* CH_SET_2G4_1_13 */ -+ -+ {115, BAND_5G, CHNL_SPAN_20, 36, 4, FALSE} -+ , /* CH_SET_UNII_LOW_36_48 */ -+ {118, BAND_5G, CHNL_SPAN_20, 52, 4, TRUE} -+ , /* CH_SET_UNII_MID_52_64 */ -+ {121, BAND_5G, CHNL_SPAN_20, 100, 12, TRUE} -+ , /* CH_SET_UNII_WW_100_144 */ -+ {125, BAND_5G, CHNL_SPAN_20, 149, 5, FALSE} -+ , /* CH_SET_UNII_UPPER_149_165 */ -+ {0, BAND_NULL, 0, 0, 0, FALSE} -+ } -+ } -+ , -+ { -+ (PUINT_16) g_u2CountryGroup3, sizeof(g_u2CountryGroup3) / 2, -+ { -+ {81, BAND_2G4, CHNL_SPAN_5, 1, 13, FALSE} -+ , /* CH_SET_2G4_1_13 */ -+ -+ {115, BAND_5G, CHNL_SPAN_20, 36, 4, FALSE} -+ , /* CH_SET_UNII_LOW_36_48 */ -+ {118, BAND_5G, CHNL_SPAN_20, 52, 4, TRUE} -+ , /* CH_SET_UNII_MID_52_64 */ -+ {121, BAND_5G, CHNL_SPAN_20, 100, 12, TRUE} -+ , /* CH_SET_UNII_WW_100_144 */ -+ {125, BAND_5G, CHNL_SPAN_20, 149, 4, FALSE} -+ , /* CH_SET_UNII_UPPER_149_161 */ -+ {0, BAND_NULL, 0, 0, 0, FALSE} -+ } -+ } -+ , -+ { -+ (PUINT_16) g_u2CountryGroup4, sizeof(g_u2CountryGroup4) / 2, -+ { -+ {81, BAND_2G4, CHNL_SPAN_5, 1, 13, FALSE} -+ , /* CH_SET_2G4_1_13 */ -+ -+ {115, BAND_5G, CHNL_SPAN_20, 36, 4, FALSE} -+ , /* CH_SET_UNII_LOW_36_48 */ -+ {118, BAND_5G, CHNL_SPAN_20, 52, 4, TRUE} -+ , /* CH_SET_UNII_MID_52_64 */ -+ {121, BAND_5G, CHNL_SPAN_20, 100, 12, TRUE} -+ , /* CH_SET_UNII_WW_100_144 */ -+ {125, BAND_NULL, 0, 0, 0, FALSE} -+ , /* CH_SET_UNII_UPPER_NA */ -+ {0, BAND_NULL, 0, 0, 0, FALSE} -+ } -+ } -+ , -+ { -+ (PUINT_16) g_u2CountryGroup5, sizeof(g_u2CountryGroup5) / 2, -+ { -+ {81, BAND_2G4, CHNL_SPAN_5, 1, 13, FALSE} -+ , /* CH_SET_2G4_1_13 */ -+ -+ {115, BAND_5G, CHNL_SPAN_20, 36, 4, FALSE} -+ , /* CH_SET_UNII_LOW_36_48 */ -+ {118, BAND_5G, CHNL_SPAN_20, 52, 4, TRUE} -+ , /* CH_SET_UNII_MID_52_64 */ -+ {121, BAND_5G, CHNL_SPAN_20, 100, 11, TRUE} -+ , /* CH_SET_UNII_WW_100_140 */ -+ {125, BAND_NULL, 0, 0, 0, FALSE} -+ , /* CH_SET_UNII_UPPER_NA */ -+ {0, BAND_NULL, 0, 0, 0, FALSE} -+ } -+ } -+ , -+ { -+ (PUINT_16) g_u2CountryGroup6, sizeof(g_u2CountryGroup6) / 2, -+ { -+ {81, BAND_2G4, CHNL_SPAN_5, 1, 13, FALSE} -+ , /* CH_SET_2G4_1_13 */ -+ {82, BAND_2G4, CHNL_SPAN_5, 14, 1, FALSE} -+ , /* CH_SET_2G4_14_14 */ -+ {115, BAND_5G, CHNL_SPAN_20, 36, 4, FALSE} -+ , /* CH_SET_UNII_LOW_36_48 */ -+ {118, BAND_5G, CHNL_SPAN_20, 52, 4, TRUE} -+ , /* CH_SET_UNII_MID_52_64 */ -+ {121, BAND_5G, CHNL_SPAN_20, 100, 11, TRUE} -+ , /* CH_SET_UNII_WW_100_140 */ -+ {125, BAND_NULL, 0, 0, 0, FALSE} -+ , /* CH_SET_UNII_UPPER_NA */ -+ } -+ } -+ , -+ { -+ (PUINT_16) g_u2CountryGroup7, sizeof(g_u2CountryGroup7) / 2, -+ { -+ {81, BAND_2G4, CHNL_SPAN_5, 1, 13, FALSE} -+ , /* CH_SET_2G4_1_13 */ -+ -+ {115, BAND_5G, CHNL_SPAN_20, 36, 4, FALSE} -+ , /* CH_SET_UNII_LOW_36_48 */ -+ {118, BAND_5G, CHNL_SPAN_20, 52, 4, TRUE} -+ , /* CH_SET_UNII_MID_52_64 */ -+ {121, BAND_NULL, 0, 0, 0, FALSE} -+ , /* CH_SET_UNII_WW_NA */ -+ {125, BAND_NULL, 0, 0, 0, FALSE} -+ , /* CH_SET_UNII_UPPER_NA */ -+ {0, BAND_NULL, 0, 0, 0, FALSE} -+ } -+ } -+ , -+ { -+ (PUINT_16) g_u2CountryGroup8, sizeof(g_u2CountryGroup8) / 2, -+ { -+ {81, BAND_2G4, CHNL_SPAN_5, 1, 13, FALSE} -+ , /* CH_SET_2G4_1_13 */ -+ -+ {115, BAND_5G, CHNL_SPAN_20, 36, 4, FALSE} -+ , /* CH_SET_UNII_LOW_36_48 */ -+ {118, BAND_5G, CHNL_SPAN_20, 52, 4, TRUE} -+ , /* CH_SET_UNII_MID_52_64 */ -+ {121, BAND_NULL, 0, 0, 0, FALSE} -+ , /* CH_SET_UNII_WW_NA */ -+ {125, BAND_5G, CHNL_SPAN_20, 149, 4, FALSE} -+ , /* CH_SET_UNII_UPPER_149_161 */ -+ {0, BAND_NULL, 0, 0, 0, FALSE} -+ } -+ } -+ , -+ { -+ (PUINT_16) g_u2CountryGroup9, sizeof(g_u2CountryGroup9) / 2, -+ { -+ {81, BAND_2G4, CHNL_SPAN_5, 1, 13, FALSE} -+ , /* CH_SET_2G4_1_13 */ -+ -+ {115, BAND_5G, CHNL_SPAN_20, 36, 4, FALSE} -+ , /* CH_SET_UNII_LOW_36_48 */ -+ {118, BAND_NULL, 0, 0, 0, FALSE} -+ , /* CH_SET_UNII_MID_NA */ -+ {121, BAND_NULL, 0, 0, 0, FALSE} -+ , /* CH_SET_UNII_WW_NA */ -+ {125, BAND_NULL, 0, 0, 0, FALSE} -+ , /* CH_SET_UNII_UPPER_NA */ -+ {0, BAND_NULL, 0, 0, 0, FALSE} -+ } -+ } -+ , -+ { -+ (PUINT_16) g_u2CountryGroup10, sizeof(g_u2CountryGroup10) / 2, -+ { -+ {81, BAND_2G4, CHNL_SPAN_5, 1, 13, FALSE} -+ , /* CH_SET_2G4_1_13 */ -+ -+ {115, BAND_5G, CHNL_SPAN_20, 36, 4, FALSE} -+ , /* CH_SET_UNII_LOW_36_48 */ -+ {118, BAND_5G, CHNL_SPAN_20, 52, 4, TRUE} -+ , /* CH_SET_UNII_MID_52_64 */ -+ {121, BAND_NULL, 0, 0, 0, FALSE} -+ , /* CH_SET_UNII_WW_NA */ -+ {125, BAND_5G, CHNL_SPAN_20, 149, 5, FALSE} -+ , /* CH_SET_UNII_UPPER_149_165 */ -+ {0, BAND_NULL, 0, 0, 0, FALSE} -+ } -+ } -+ , -+ { -+ (PUINT_16) g_u2CountryGroup11, sizeof(g_u2CountryGroup11) / 2, -+ { -+ {81, BAND_2G4, CHNL_SPAN_5, 1, 13, FALSE} -+ , /* CH_SET_2G4_1_13 */ -+ -+ {115, BAND_5G, CHNL_SPAN_20, 36, 4, FALSE} -+ , /* CH_SET_UNII_LOW_36_48 */ -+ {118, BAND_NULL, 0, 0, 0, FALSE} -+ , /* CH_SET_UNII_MID_NA */ -+ {121, BAND_NULL, 0, 0, 0, FALSE} -+ , /* CH_SET_UNII_WW_NA */ -+ {125, BAND_5G, CHNL_SPAN_20, 149, 5, FALSE} -+ , /* CH_SET_UNII_UPPER_149_165 */ -+ {0, BAND_NULL, 0, 0, 0, FALSE} -+ } -+ } -+ , -+ { -+ (PUINT_16) g_u2CountryGroup12, sizeof(g_u2CountryGroup12) / 2, -+ { -+ {81, BAND_2G4, CHNL_SPAN_5, 1, 13, FALSE} -+ , /* CH_SET_2G4_1_13 */ -+ -+ {115, BAND_NULL, 0, 0, 0, FALSE} -+ , /* CH_SET_UNII_LOW_NA */ -+ {118, BAND_NULL, 0, 0, 0, FALSE} -+ , /* CH_SET_UNII_MID_NA */ -+ {121, BAND_NULL, 0, 0, 0, FALSE} -+ , /* CH_SET_UNII_WW_NA */ -+ {125, BAND_5G, CHNL_SPAN_20, 149, 5, FALSE} -+ , /* CH_SET_UNII_UPPER_149_165 */ -+ {0, BAND_NULL, 0, 0, 0, FALSE} -+ } -+ } -+ , -+ { -+ (PUINT_16) g_u2CountryGroup13, sizeof(g_u2CountryGroup13) / 2, -+ { -+ {81, BAND_2G4, CHNL_SPAN_5, 1, 13, FALSE} -+ , /* CH_SET_2G4_1_13 */ -+ -+ {115, BAND_NULL, 0, 0, 0, FALSE} -+ , /* CH_SET_UNII_LOW_NA */ -+ {118, BAND_NULL, 0, 0, 0, FALSE} -+ , /* CH_SET_UNII_MID_NA */ -+ {121, BAND_NULL, 0, 0, 0, FALSE} -+ , /* CH_SET_UNII_WW_NA */ -+ {125, BAND_5G, CHNL_SPAN_20, 149, 4, FALSE} -+ , /* CH_SET_UNII_UPPER_149_161 */ -+ {0, BAND_NULL, 0, 0, 0, FALSE} -+ } -+ } -+ , -+ { -+ (PUINT_16) g_u2CountryGroup14, sizeof(g_u2CountryGroup14) / 2, -+ { -+ {81, BAND_2G4, CHNL_SPAN_5, 1, 13, FALSE} -+ , /* CH_SET_2G4_1_13 */ -+ -+ {115, BAND_5G, CHNL_SPAN_20, 36, 4, FALSE} -+ , /* CH_SET_UNII_LOW_36_48 */ -+ {118, BAND_5G, CHNL_SPAN_20, 52, 4, FALSE} -+ , /* CH_SET_UNII_MID_52_64 */ -+ {121, BAND_5G, CHNL_SPAN_20, 100, 8, FALSE} -+ , /* CH_SET_UNII_WW_100_128 */ -+ {125, BAND_5G, CHNL_SPAN_20, 149, 4, FALSE} -+ , /* CH_SET_UNII_UPPER_149_161 */ -+ {0, BAND_NULL, 0, 0, 0, FALSE} -+ } -+ } -+ , -+ { -+ (PUINT_16) g_u2CountryGroup15, sizeof(g_u2CountryGroup15) / 2, -+ { -+ {81, BAND_2G4, CHNL_SPAN_5, 1, 13, FALSE} -+ , /* CH_SET_2G4_1_13 */ -+ -+ {115, BAND_NULL, 0, 0, 0, FALSE} -+ , /* CH_SET_UNII_LOW_36_48 */ -+ {118, BAND_5G, CHNL_SPAN_20, 52, 4, TRUE} -+ , /* CH_SET_UNII_MID_52_64 */ -+ {121, BAND_5G, CHNL_SPAN_20, 100, 11, TRUE} -+ , /* CH_SET_UNII_WW_100_140 */ -+ {125, BAND_5G, CHNL_SPAN_20, 149, 5, FALSE} -+ , /* CH_SET_UNII_UPPER_149_165 */ -+ {0, BAND_NULL, 0, 0, 0, FALSE} -+ } -+ } -+ , -+ { -+ (PUINT_16) g_u2CountryGroup16, sizeof(g_u2CountryGroup16) / 2, -+ { -+ {81, BAND_2G4, CHNL_SPAN_5, 1, 13, FALSE} -+ , /* CH_SET_2G4_1_13 */ -+ -+ {115, BAND_5G, CHNL_SPAN_20, 36, 4, FALSE} -+ , /* CH_SET_UNII_LOW_36_48 */ -+ {118, BAND_5G, CHNL_SPAN_20, 52, 4, FALSE} -+ , /* CH_SET_UNII_MID_52_64 */ -+ {121, BAND_5G, CHNL_SPAN_20, 100, 11, TRUE} -+ , /* CH_SET_UNII_WW_100_140 */ -+ {125, BAND_5G, CHNL_SPAN_20, 149, 5, FALSE} -+ , /* CH_SET_UNII_UPPER_149_165 */ -+ {0, BAND_NULL, 0, 0, 0, FALSE} -+ } -+ } -+ , -+ { -+ (PUINT_16) g_u2CountryGroup17, sizeof(g_u2CountryGroup17) / 2, -+ { -+ {81, BAND_2G4, CHNL_SPAN_5, 1, 11, FALSE} -+ , /* CH_SET_2G4_1_11 */ -+ -+ {115, BAND_5G, CHNL_SPAN_20, 36, 4, FALSE} -+ , /* CH_SET_UNII_LOW_36_48 */ -+ {118, BAND_5G, CHNL_SPAN_20, 52, 4, TRUE} -+ , /* CH_SET_UNII_MID_52_64 */ -+ {121, BAND_5G, CHNL_SPAN_20, 100, 11, TRUE} -+ , /* CH_SET_UNII_WW_100_140 */ -+ {125, BAND_5G, CHNL_SPAN_20, 149, 5, FALSE} -+ , /* CH_SET_UNII_UPPER_149_165 */ -+ {0, BAND_NULL, 0, 0, 0, FALSE} -+ } -+ } -+ , -+ { -+ (PUINT_16) g_u2CountryGroup18, sizeof(g_u2CountryGroup18) / 2, -+ { -+ {81, BAND_2G4, CHNL_SPAN_5, 1, 11, FALSE} -+ , /* CH_SET_2G4_1_11 */ -+ -+ {115, BAND_5G, CHNL_SPAN_20, 36, 4, FALSE} -+ , /* CH_SET_UNII_LOW_36_48 */ -+ {118, BAND_5G, CHNL_SPAN_20, 52, 4, FALSE} -+ , /* CH_SET_UNII_MID_52_64 */ -+ {121, BAND_5G, CHNL_SPAN_20, 100, 11, FALSE} -+ , /* CH_SET_UNII_WW_100_140 */ -+ {125, BAND_5G, CHNL_SPAN_20, 149, 5, FALSE} -+ , /* CH_SET_UNII_UPPER_149_165 */ -+ {0, BAND_NULL, 0, 0, 0, FALSE} -+ } -+ } -+ , -+ { -+ (PUINT_16) g_u2CountryGroup19, sizeof(g_u2CountryGroup19) / 2, -+ { -+ {81, BAND_2G4, CHNL_SPAN_5, 1, 13, FALSE} -+ , /* CH_SET_2G4_1_13 */ -+ -+ {115, BAND_5G, CHNL_SPAN_20, 36, 4, FALSE} -+ , /* CH_SET_UNII_LOW_36_48 */ -+ {118, BAND_5G, CHNL_SPAN_20, 52, 4, TRUE} -+ , /* CH_SET_UNII_MID_52_64 */ -+ {121, BAND_5G, CHNL_SPAN_20, 100, 12, TRUE} -+ , /* CH_SET_UNII_WW_100_144 */ -+ {125, BAND_5G, CHNL_SPAN_20, 149, 5, FALSE} -+ , /* CH_SET_UNII_UPPER_149_165 */ -+ {0, BAND_NULL, 0, 0, 0, FALSE} -+ } -+ } -+ , -+ { -+ /* Note: Default group if no matched country code */ -+ (PUINT_16) g_u2CountryGroup20, sizeof(g_u2CountryGroup20) / 2, -+ { -+ {81, BAND_2G4, CHNL_SPAN_5, 1, 13, FALSE} -+ , /* CH_SET_2G4_1_13 */ -+ -+ {115, BAND_5G, CHNL_SPAN_20, 36, 4, FALSE} -+ , /* CH_SET_UNII_LOW_36_48 */ -+ {118, BAND_5G, CHNL_SPAN_20, 52, 4, TRUE} -+ , /* CH_SET_UNII_MID_52_64 */ -+ {121, BAND_5G, CHNL_SPAN_20, 100, 12, TRUE} -+ , /* CH_SET_UNII_WW_100_144 */ -+ {125, BAND_5G, CHNL_SPAN_20, 149, 5, FALSE} -+ , /* CH_SET_UNII_UPPER_149_165 */ -+ {0, BAND_NULL, 0, 0, 0, FALSE} -+ } -+ } -+ , -+ { -+ /* Note: for customer configured their own scanning list and passive scan list */ -+ (PUINT_16) g_u2CountryGroup21, sizeof(g_u2CountryGroup21) / 2, -+ { -+ {81, BAND_2G4, CHNL_SPAN_5, 1, 12, FALSE} -+ , /* CH_SET_2G4_1_13 */ -+ -+ {115, BAND_5G, CHNL_SPAN_20, 36, 0, FALSE} -+ , -+ {118, BAND_5G, CHNL_SPAN_20, 52, 0, FALSE} -+ , -+ {121, BAND_5G, CHNL_SPAN_20, 100, 0, FALSE} -+ , -+ {125, BAND_5G, CHNL_SPAN_20, 149, 0, FALSE} -+ , -+ {0, BAND_NULL, 0, 0, 0, FALSE} -+ } -+ } -+}; -+ -+static UINT_16 g_u2CountryGroup0_Passive[] = { -+ COUNTRY_CODE_UDF -+}; -+ -+DOMAIN_INFO_ENTRY arSupportedRegDomains_Passive[] = { -+ { -+ /* Default passive scan channel table is empty */ -+ COUNTRY_CODE_NULL, 0, -+ { -+ {81, BAND_2G4, CHNL_SPAN_5, 11, 0, 0}, /* CH_SET_2G4_1_14 */ -+ {82, BAND_2G4, CHNL_SPAN_5, 5, 0, 0}, -+ -+ {115, BAND_5G, CHNL_SPAN_20, 36, 0, 0}, /* CH_SET_UNII_LOW_36_48 */ -+ {118, BAND_5G, CHNL_SPAN_20, 52, 0, 0}, /* CH_SET_UNII_MID_52_64 */ -+ {121, BAND_5G, CHNL_SPAN_20, 100, 0, 0}, /* CH_SET_UNII_WW_100_140 */ -+ {125, BAND_5G, CHNL_SPAN_20, 149, 0, 0}, /* CH_SET_UNII_UPPER_149_173 */ -+ } -+ }, -+ { -+ /* User Defined passive scan channel table */ -+ g_u2CountryGroup0_Passive, 0, -+ { -+ {81, BAND_2G4, CHNL_SPAN_5, 12, 1, 0}, /* CH_SET_2G4_1_14 */ -+ {82, BAND_2G4, CHNL_SPAN_5, 5, 0, 0}, -+ -+ {115, BAND_5G, CHNL_SPAN_20, 36, 0, 0}, /* CH_SET_UNII_LOW_36_48 */ -+ {118, BAND_5G, CHNL_SPAN_20, 52, 0, 0}, /* CH_SET_UNII_MID_52_64 */ -+ {121, BAND_5G, CHNL_SPAN_20, 100, 0, 0}, /* CH_SET_UNII_WW_100_140 */ -+ {125, BAND_5G, CHNL_SPAN_20, 149, 0, 0}, /* CH_SET_UNII_UPPER_149_173 */ -+ } -+ } -+}; -+ -+#if CFG_SUPPORT_PWR_LIMIT_COUNTRY -+SUBBAND_CHANNEL_T g_rRlmSubBand[] = { -+ -+ {BAND_2G4_LOWER_BOUND, BAND_2G4_UPPER_BOUND, 1, 0} -+ , /* 2.4G */ -+ {UNII1_LOWER_BOUND, UNII1_UPPER_BOUND, 2, 0} -+ , /* ch36,38,40,..,48 */ -+ {UNII2A_LOWER_BOUND, UNII2A_UPPER_BOUND, 2, 0} -+ , /* ch52,54,56,..,64 */ -+ {UNII2C_LOWER_BOUND, UNII2C_UPPER_BOUND, 2, 0} -+ , /* ch100,102,104,...,144 */ -+ {UNII3_LOWER_BOUND, UNII3_UPPER_BOUND, 2, 0} -+ /* ch149,151,153,....,173 */ -+}; -+#endif -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in/out] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+P_DOMAIN_INFO_ENTRY rlmDomainGetDomainInfo(P_ADAPTER_T prAdapter) -+{ -+#define REG_DOMAIN_DEF_IDX 20 /* Default country domain */ -+#define REG_DOMAIN_GROUP_NUM \ -+ (sizeof(arSupportedRegDomains) / sizeof(DOMAIN_INFO_ENTRY)) -+ -+ P_DOMAIN_INFO_ENTRY prDomainInfo; -+ P_REG_INFO_T prRegInfo; -+ UINT_16 u2TargetCountryCode; -+ UINT_16 i, j; -+ -+ ASSERT(prAdapter); -+ -+ if (prAdapter->prDomainInfo) -+ return prAdapter->prDomainInfo; -+ -+ prRegInfo = &prAdapter->prGlueInfo->rRegInfo; -+ -+ DBGLOG(RLM, TRACE, "eRegChannelListMap=%d, u2CountryCode=0x%04x\n", -+ prRegInfo->eRegChannelListMap, -+ prAdapter->rWifiVar.rConnSettings.u2CountryCode); -+ -+ /* -+ * Domain info can be specified by given idx of arSupportedRegDomains table, -+ * customized, or searched by country code, -+ * only one is set among these three methods in NVRAM. -+ */ -+ if (prRegInfo->eRegChannelListMap == REG_CH_MAP_TBL_IDX && -+ prRegInfo->ucRegChannelListIndex < REG_DOMAIN_GROUP_NUM) { -+ /* by given table idx */ -+ DBGLOG(RLM, TRACE, "ucRegChannelListIndex=%d\n", prRegInfo->ucRegChannelListIndex); -+ prDomainInfo = &arSupportedRegDomains[prRegInfo->ucRegChannelListIndex]; -+ } else if (prRegInfo->eRegChannelListMap == REG_CH_MAP_CUSTOMIZED) { -+ /* by customized */ -+ prDomainInfo = &prRegInfo->rDomainInfo; -+ } else { -+ /* by country code */ -+ u2TargetCountryCode = prAdapter->rWifiVar.rConnSettings.u2CountryCode; -+ -+ for (i = 0; i < REG_DOMAIN_GROUP_NUM; i++) { -+ prDomainInfo = &arSupportedRegDomains[i]; -+ -+ if ((prDomainInfo->u4CountryNum && prDomainInfo->pu2CountryGroup) || -+ prDomainInfo->u4CountryNum == 0) { -+ for (j = 0; j < prDomainInfo->u4CountryNum; j++) { -+ if (prDomainInfo->pu2CountryGroup[j] == u2TargetCountryCode) -+ break; -+ } -+ if (j < prDomainInfo->u4CountryNum) -+ break; /* Found */ -+ } -+ } -+ -+ /* If no matched country code, use the default country domain */ -+ if (i >= REG_DOMAIN_GROUP_NUM) { -+ DBGLOG(RLM, INFO, "No matched country code, use the default country domain\n"); -+ prDomainInfo = &arSupportedRegDomains[REG_DOMAIN_DEF_IDX]; -+ } -+ } -+ -+ prAdapter->prDomainInfo = prDomainInfo; -+ return prDomainInfo; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in/out] The input variable pointed by pucNumOfChannel is the max -+* arrary size. The return value indciates meaning list size. -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+rlmDomainGetChnlList(P_ADAPTER_T prAdapter, -+ ENUM_BAND_T eSpecificBand, BOOLEAN fgNoDfs, -+ UINT_8 ucMaxChannelNum, PUINT_8 pucNumOfChannel, P_RF_CHANNEL_INFO_T paucChannelList) -+{ -+ UINT_8 i, j, ucNum; -+ P_DOMAIN_SUBBAND_INFO prSubband; -+ P_DOMAIN_INFO_ENTRY prDomainInfo; -+ -+ ASSERT(prAdapter); -+ ASSERT(paucChannelList); -+ ASSERT(pucNumOfChannel); -+ -+ prDomainInfo = rlmDomainGetDomainInfo(prAdapter); -+ ASSERT(prDomainInfo); -+ -+ ucNum = 0; -+ for (i = 0; i < MAX_SUBBAND_NUM; i++) { -+ prSubband = &prDomainInfo->rSubBand[i]; -+ -+ if (prSubband->ucBand == BAND_NULL || prSubband->ucBand >= BAND_NUM || -+ (prSubband->ucBand == BAND_5G && !prAdapter->fgEnable5GBand)) -+ continue; -+ -+ if (fgNoDfs == TRUE && prSubband->fgDfs == TRUE) -+ continue; -+ -+ if (eSpecificBand == BAND_NULL || prSubband->ucBand == eSpecificBand) { -+ for (j = 0; j < prSubband->ucNumChannels; j++) { -+ if (ucNum >= ucMaxChannelNum) -+ break; -+ paucChannelList[ucNum].eBand = prSubband->ucBand; -+ paucChannelList[ucNum].ucChannelNum = -+ prSubband->ucFirstChannelNum + j * prSubband->ucChannelSpan; -+ ucNum++; -+ } -+ } -+ } -+ -+ *pucNumOfChannel = ucNum; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief -+* -+* @param[in] -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rlmDomainSendCmd(P_ADAPTER_T prAdapter, BOOLEAN fgIsOid) -+{ -+ rlmDomainSendDomainInfoCmd(prAdapter, fgIsOid); -+#if CFG_SUPPORT_PWR_LIMIT_COUNTRY -+ rlmDomainSendPwrLimitCmd(prAdapter); -+#endif -+ rlmDomainSendPassiveScanInfoCmd(prAdapter, fgIsOid); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief -+* -+* @param[in] -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rlmDomainSendDomainInfoCmd(P_ADAPTER_T prAdapter, BOOLEAN fgIsOid) -+{ -+ P_DOMAIN_INFO_ENTRY prDomainInfo; -+ P_CMD_SET_DOMAIN_INFO_T prCmd; -+ P_DOMAIN_SUBBAND_INFO prSubBand; -+ UINT_8 i; -+ -+ prDomainInfo = rlmDomainGetDomainInfo(prAdapter); -+ ASSERT(prDomainInfo); -+ -+ prCmd = cnmMemAlloc(prAdapter, RAM_TYPE_BUF, sizeof(CMD_SET_DOMAIN_INFO_T)); -+ if (!prCmd) { -+ DBGLOG(RLM, ERROR, "Alloc cmd buffer failed\n"); -+ return; -+ } -+ kalMemZero(prCmd, sizeof(CMD_SET_DOMAIN_INFO_T)); -+ -+ prCmd->u2CountryCode = prAdapter->rWifiVar.rConnSettings.u2CountryCode; -+ prCmd->u2IsSetPassiveScan = 0; -+ prCmd->uc2G4Bandwidth = prAdapter->rWifiVar.rConnSettings.uc2G4BandwidthMode; -+ prCmd->uc5GBandwidth = prAdapter->rWifiVar.rConnSettings.uc5GBandwidthMode; -+ prCmd->aucReserved[0] = 0; -+ prCmd->aucReserved[1] = 0; -+ -+ for (i = 0; i < MAX_SUBBAND_NUM; i++) { -+ prSubBand = &prDomainInfo->rSubBand[i]; -+ -+ prCmd->rSubBand[i].ucRegClass = prSubBand->ucRegClass; -+ prCmd->rSubBand[i].ucBand = prSubBand->ucBand; -+ -+ if (prSubBand->ucBand != BAND_NULL && prSubBand->ucBand < BAND_NUM) { -+ prCmd->rSubBand[i].ucChannelSpan = prSubBand->ucChannelSpan; -+ prCmd->rSubBand[i].ucFirstChannelNum = prSubBand->ucFirstChannelNum; -+ prCmd->rSubBand[i].ucNumChannels = prSubBand->ucNumChannels; -+ } -+ } -+ -+ /* Set domain info to chip */ -+ wlanSendSetQueryCmd(prAdapter, /* prAdapter */ -+ CMD_ID_SET_DOMAIN_INFO, /* ucCID */ -+ TRUE, /* fgSetQuery */ -+ FALSE, /* fgNeedResp */ -+ fgIsOid, /* fgIsOid */ -+ NULL, /* pfCmdDoneHandler */ -+ NULL, /* pfCmdTimeoutHandler */ -+ sizeof(CMD_SET_DOMAIN_INFO_T), /* u4SetQueryInfoLen */ -+ (PUINT_8)prCmd, /* pucInfoBuffer */ -+ NULL, /* pvSetQueryBuffer */ -+ 0 /* u4SetQueryBufferLen */ -+ ); -+ -+ cnmMemFree(prAdapter, prCmd); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief -+* -+* @param[in] -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rlmDomainSendPassiveScanInfoCmd(P_ADAPTER_T prAdapter, BOOLEAN fgIsOid) -+{ -+#define REG_DOMAIN_PASSIVE_DEF_IDX 0 -+#define REG_DOMAIN_PASSIVE_UDF_IDX 1 -+ -+ P_DOMAIN_INFO_ENTRY prDomainInfo; -+ P_CMD_SET_DOMAIN_INFO_T prCmd; -+ P_DOMAIN_SUBBAND_INFO prSubBand; -+ UINT_8 i; -+ -+ prCmd = cnmMemAlloc(prAdapter, RAM_TYPE_BUF, sizeof(CMD_SET_DOMAIN_INFO_T)); -+ if (!prCmd) { -+ DBGLOG(RLM, ERROR, "Alloc cmd buffer failed\n"); -+ return; -+ } -+ kalMemZero(prCmd, sizeof(CMD_SET_DOMAIN_INFO_T)); -+ -+ prCmd->u2CountryCode = prAdapter->rWifiVar.rConnSettings.u2CountryCode; -+ prCmd->u2IsSetPassiveScan = 1; -+ prCmd->uc2G4Bandwidth = prAdapter->rWifiVar.rConnSettings.uc2G4BandwidthMode; -+ prCmd->uc5GBandwidth = prAdapter->rWifiVar.rConnSettings.uc5GBandwidthMode; -+ prCmd->aucReserved[0] = 0; -+ prCmd->aucReserved[1] = 0; -+ -+ DBGLOG(RLM, TRACE, "u2CountryCode=0x%04x\n", prAdapter->rWifiVar.rConnSettings.u2CountryCode); -+ -+ if (prAdapter->rWifiVar.rConnSettings.u2CountryCode == COUNTRY_CODE_UDF) -+ prDomainInfo = &arSupportedRegDomains_Passive[REG_DOMAIN_PASSIVE_UDF_IDX]; -+ else -+ prDomainInfo = &arSupportedRegDomains_Passive[REG_DOMAIN_PASSIVE_DEF_IDX]; -+ -+ for (i = 0; i < MAX_SUBBAND_NUM; i++) { -+ prSubBand = &prDomainInfo->rSubBand[i]; -+ -+ prCmd->rSubBand[i].ucRegClass = prSubBand->ucRegClass; -+ prCmd->rSubBand[i].ucBand = prSubBand->ucBand; -+ -+ if (prSubBand->ucBand != BAND_NULL && prSubBand->ucBand < BAND_NUM) { -+ prCmd->rSubBand[i].ucChannelSpan = prSubBand->ucChannelSpan; -+ prCmd->rSubBand[i].ucFirstChannelNum = prSubBand->ucFirstChannelNum; -+ prCmd->rSubBand[i].ucNumChannels = prSubBand->ucNumChannels; -+ } -+ } -+ -+ /* Set passive scan channel info to chip */ -+ wlanSendSetQueryCmd(prAdapter, /* prAdapter */ -+ CMD_ID_SET_DOMAIN_INFO, /* ucCID */ -+ TRUE, /* fgSetQuery */ -+ FALSE, /* fgNeedResp */ -+ fgIsOid, /* fgIsOid */ -+ NULL, /* pfCmdDoneHandler */ -+ NULL, /* pfCmdTimeoutHandler */ -+ sizeof(CMD_SET_DOMAIN_INFO_T), /* u4SetQueryInfoLen */ -+ (PUINT_8) prCmd, /* pucInfoBuffer */ -+ NULL, /* pvSetQueryBuffer */ -+ 0 /* u4SetQueryBufferLen */ -+ ); -+ -+ cnmMemFree(prAdapter, prCmd); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in/out] -+* -+* \return TRUE Legal channel -+* FALSE Illegal channel for current regulatory domain -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN rlmDomainIsLegalChannel(P_ADAPTER_T prAdapter, ENUM_BAND_T eBand, UINT_8 ucChannel) -+{ -+ UINT_8 i, j; -+ P_DOMAIN_SUBBAND_INFO prSubband; -+ P_DOMAIN_INFO_ENTRY prDomainInfo; -+ -+ prDomainInfo = rlmDomainGetDomainInfo(prAdapter); -+ ASSERT(prDomainInfo); -+ -+ for (i = 0; i < MAX_SUBBAND_NUM; i++) { -+ prSubband = &prDomainInfo->rSubBand[i]; -+ -+ if (prSubband->ucBand == BAND_5G && !prAdapter->fgEnable5GBand) -+ continue; -+ -+ if (prSubband->ucBand == eBand) { -+ for (j = 0; j < prSubband->ucNumChannels; j++) { -+ if ((prSubband->ucFirstChannelNum + j * prSubband->ucChannelSpan) -+ == ucChannel) { -+ return TRUE; -+ } -+ } -+ } -+ } -+ -+ return FALSE; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in/out] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+ -+UINT_32 rlmDomainSupOperatingClassIeFill(PUINT_8 pBuf) -+{ -+ /* -+ The Country element should only be included for Status Code 0 (Successful). -+ */ -+ UINT_32 u4IeLen; -+ UINT_8 aucClass[12] = { 0x01, 0x02, 0x03, 0x05, 0x16, 0x17, 0x19, 0x1b, -+ 0x1c, 0x1e, 0x20, 0x21 -+ }; -+ -+ /* -+ The Supported Operating Classes element is used by a STA to advertise the -+ operating classes that it is capable of operating with in this country. -+ -+ The Country element (see 8.4.2.10) allows a STA to configure its PHY and MAC -+ for operation when the operating triplet of Operating Extension Identifier, -+ Operating Class, and Coverage Class fields is present. -+ */ -+ SUP_OPERATING_CLASS_IE(pBuf)->ucId = ELEM_ID_SUP_OPERATING_CLASS; -+ SUP_OPERATING_CLASS_IE(pBuf)->ucLength = 1 + sizeof(aucClass); -+ SUP_OPERATING_CLASS_IE(pBuf)->ucCur = 0x0c; /* 0x51 */ -+ kalMemCopy(SUP_OPERATING_CLASS_IE(pBuf)->ucSup, aucClass, sizeof(aucClass)); -+ u4IeLen = (SUP_OPERATING_CLASS_IE(pBuf)->ucLength + 2); -+ pBuf += u4IeLen; -+ -+ COUNTRY_IE(pBuf)->ucId = ELEM_ID_COUNTRY_INFO; -+ COUNTRY_IE(pBuf)->ucLength = 6; -+ COUNTRY_IE(pBuf)->aucCountryStr[0] = 0x55; -+ COUNTRY_IE(pBuf)->aucCountryStr[1] = 0x53; -+ COUNTRY_IE(pBuf)->aucCountryStr[2] = 0x20; -+ COUNTRY_IE(pBuf)->arCountryStr[0].ucFirstChnlNum = 1; -+ COUNTRY_IE(pBuf)->arCountryStr[0].ucNumOfChnl = 11; -+ COUNTRY_IE(pBuf)->arCountryStr[0].cMaxTxPwrLv = 0x1e; -+ u4IeLen += (COUNTRY_IE(pBuf)->ucLength + 2); -+ -+ return u4IeLen; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief -+* -+* @param[in] -+* -+* @return (fgValid) : 0 -> inValid, 1 -> Valid -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN rlmDomainCheckChannelEntryValid(P_ADAPTER_T prAdapter, UINT_8 ucCentralCh) -+{ -+ BOOLEAN fgValid = FALSE; -+ UINT_8 ucTemp = 0; -+ UINT_8 i; -+ /*Check Power limit table channel efficient or not */ -+ -+ for (i = POWER_LIMIT_2G4; i < POWER_LIMIT_SUBAND_NUM; i++) { -+ if ((ucCentralCh >= g_rRlmSubBand[i].ucStartCh) && (ucCentralCh <= g_rRlmSubBand[i].ucEndCh)) -+ ucTemp = (ucCentralCh - g_rRlmSubBand[i].ucStartCh) % g_rRlmSubBand[i].ucInterval; -+ } -+ -+#if 0 -+ /*2.4G, ex 1, 2, 3 */ -+ if (ucCentralCh >= BAND_2G4_LOWER_BOUND && ucCentralCh <= BAND_2G4_UPPER_BOUND) -+ ucTemp = 0; -+ /*FCC- Spec : Band UNII-1, ex 36, 38, 40.... */ -+ else if (ucCentralCh >= UNII1_LOWER_BOUND && ucCentralCh <= UNII1_UPPER_BOUND) -+ ucTemp = (ucCentralCh - UNII1_LOWER_BOUND) % 2; -+ /*FCC- Spec : Band UNII-2A, ex 52, 54, 56.... */ -+ else if (ucCentralCh >= UNII2A_LOWER_BOUND && ucCentralCh <= UNII2A_UPPER_BOUND) -+ ucTemp = (ucCentralCh - UNII2A_LOWER_BOUND) % 2; -+ /*FCC- Spec : Band UNII-2C, ex 100, 102, 104.... */ -+ else if (ucCentralCh >= UNII2C_LOWER_BOUND && ucCentralCh <= UNII2C_UPPER_BOUND) -+ ucTemp = (ucCentralCh - UNII2C_LOWER_BOUND) % 2; -+ /*FCC- Spec : Band UNII-3, ex 149, 151, 153... */ -+ else if (ucCentralCh >= UNII3_LOWER_BOUND && ucCentralCh <= UNII3_UPPER_BOUND) -+ ucTemp = (ucCentralCh - UNII3_LOWER_BOUND) % 2; -+#endif -+ if (ucTemp == 0) -+ fgValid = TRUE; -+ return fgValid; -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT_8 rlmDomainGetCenterChannel(ENUM_BAND_T eBand, UINT_8 ucPriChannel, ENUM_CHNL_EXT_T eExtend) -+{ -+ UINT_8 ucCenterChannel; -+ -+ if (eExtend == CHNL_EXT_SCA) -+ ucCenterChannel = ucPriChannel + 2; -+ else if (eExtend == CHNL_EXT_SCB) -+ ucCenterChannel = ucPriChannel - 2; -+ else -+ ucCenterChannel = ucPriChannel; -+ -+ return ucCenterChannel; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN -+rlmDomainIsValidRfSetting(P_ADAPTER_T prAdapter, -+ ENUM_BAND_T eBand, -+ UINT_8 ucPriChannel, -+ ENUM_CHNL_EXT_T eExtend, -+ ENUM_CHANNEL_WIDTH_T eChannelWidth, UINT_8 ucChannelS1, UINT_8 ucChannelS2) -+{ -+ UINT_8 ucCenterChannel; -+ BOOLEAN fgValidChannel = TRUE; -+ BOOLEAN fgValidBW = TRUE; -+ BOOLEAN fgValidRfSetting = TRUE; -+ UINT_32 u4PrimaryOffset; -+ -+ /*DBG msg for Channel InValid */ -+ if (eChannelWidth == CW_20_40MHZ) { -+ ucCenterChannel = rlmDomainGetCenterChannel(eBand, ucPriChannel, eExtend); -+ -+ /* Check Central Channel Valid or Not */ -+ fgValidChannel = rlmDomainCheckChannelEntryValid(prAdapter, ucCenterChannel); -+ if (fgValidChannel == FALSE) -+ DBGLOG(RLM, WARN, "Rf: CentralCh=%d\n", ucCenterChannel); -+ } else if (eChannelWidth == CW_80MHZ) { -+ ucCenterChannel = ucChannelS1; -+ -+ /* Check Central Channel Valid or Not */ -+ fgValidChannel = rlmDomainCheckChannelEntryValid(prAdapter, ucCenterChannel); -+ if (fgValidChannel == FALSE) -+ DBGLOG(RLM, WARN, "Rf: CentralCh=%d\n", ucCenterChannel); -+ } else if (eChannelWidth == CW_160MHZ) { -+ ucCenterChannel = ucChannelS2; -+ -+ /* Check Central Channel Valid or Not */ -+ /*TODo */ -+ } -+ -+ /* Check BW Setting Correct or Not */ -+ if (eBand == BAND_2G4) { -+ if (eChannelWidth != CW_20_40MHZ) { -+ fgValidBW = FALSE; -+ DBGLOG(RLM, WARN, "Rf: B=%d, W=%d\n", eBand, eChannelWidth); -+ } -+ } else { -+ if (eChannelWidth == CW_80MHZ) { -+ u4PrimaryOffset = CAL_CH_OFFSET_80M(ucPriChannel, ucCenterChannel); -+ if (u4PrimaryOffset > 4) { -+ fgValidBW = FALSE; -+ DBGLOG(RLM, WARN, "Rf: PriOffSet=%d, W=%d\n", u4PrimaryOffset, eChannelWidth); -+ } -+ } else if (eChannelWidth == CW_160MHZ) { -+ u4PrimaryOffset = CAL_CH_OFFSET_160M(ucPriChannel, ucCenterChannel); -+ if (u4PrimaryOffset > 8) { -+ fgValidBW = FALSE; -+ DBGLOG(RLM, WARN, "Rf: PriOffSet=%d, W=%d\n", u4PrimaryOffset, eChannelWidth); -+ } -+ } -+ } -+ -+ if ((fgValidBW == FALSE) || (fgValidChannel == FALSE)) -+ fgValidRfSetting = FALSE; -+ -+ return fgValidRfSetting; -+ -+} -+ -+#if CFG_SUPPORT_PWR_LIMIT_COUNTRY -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief -+* -+* @param[in] -+* -+* @return (fgValid) : 0 -> inValid, 1 -> Valid -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN -+rlmDomainCheckPowerLimitValid(P_ADAPTER_T prAdapter, -+ COUNTRY_POWER_LIMIT_TABLE_CONFIGURATION rPowerLimitTableConfiguration, -+ UINT_8 ucPwrLimitNum) -+{ -+ UINT_8 i; -+ BOOLEAN fgValid = TRUE; -+ PINT_8 prPwrLimit; -+ -+ prPwrLimit = &rPowerLimitTableConfiguration.aucPwrLimit[0]; -+ -+ for (i = 0; i < ucPwrLimitNum; i++, prPwrLimit++) { -+ if (*prPwrLimit > MAX_TX_POWER || *prPwrLimit < MIN_TX_POWER) { -+ fgValid = FALSE; -+ break; /*Find out Wrong Power limit */ -+ } -+ } -+ return fgValid; -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief -+* -+* @param[in] -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rlmDomainCheckCountryPowerLimitTable(P_ADAPTER_T prAdapter) -+{ -+ UINT_8 i, j; -+ UINT_16 u2CountryCodeTable, u2CountryCodeCheck; -+ BOOLEAN fgChannelValid = FALSE; -+ BOOLEAN fgPowerLimitValid = FALSE; -+ BOOLEAN fgEntryRepetetion = FALSE; -+ BOOLEAN fgTableValid = TRUE; -+ -+ /*Configuration Table Check */ -+ for (i = 0; i < sizeof(g_rRlmPowerLimitConfiguration) / sizeof(COUNTRY_POWER_LIMIT_TABLE_CONFIGURATION); i++) { -+ /*Table Country Code */ -+ WLAN_GET_FIELD_BE16(&g_rRlmPowerLimitConfiguration[i].aucCountryCode[0], &u2CountryCodeTable); -+ -+ /*Repetition Entry Check */ -+ for (j = i + 1; -+ j < sizeof(g_rRlmPowerLimitConfiguration) / sizeof(COUNTRY_POWER_LIMIT_TABLE_CONFIGURATION); -+ j++) { -+ -+ WLAN_GET_FIELD_BE16(&g_rRlmPowerLimitConfiguration[j].aucCountryCode[0], &u2CountryCodeCheck); -+ if (((g_rRlmPowerLimitConfiguration[i].ucCentralCh) == -+ g_rRlmPowerLimitConfiguration[j].ucCentralCh) -+ && (u2CountryCodeTable == u2CountryCodeCheck)) { -+ fgEntryRepetetion = TRUE; -+ DBGLOG(RLM, LOUD, "Domain: Configuration Repetition CC=%c%c, Ch=%d\n", -+ g_rRlmPowerLimitConfiguration[i].aucCountryCode[0], -+ g_rRlmPowerLimitConfiguration[i].aucCountryCode[1], -+ g_rRlmPowerLimitConfiguration[i].ucCentralCh); -+ } -+ } -+ -+ /*Channel Number Check */ -+ fgChannelValid = -+ rlmDomainCheckChannelEntryValid(prAdapter, g_rRlmPowerLimitConfiguration[i].ucCentralCh); -+ -+ /*Power Limit Check */ -+ fgPowerLimitValid = -+ rlmDomainCheckPowerLimitValid(prAdapter, g_rRlmPowerLimitConfiguration[i], PWR_LIMIT_NUM); -+ -+ if (fgChannelValid == FALSE || fgPowerLimitValid == FALSE) { -+ fgTableValid = FALSE; -+ DBGLOG(RLM, LOUD, "Domain: CC=%c%c, Ch=%d, Limit: %d,%d,%d,%d,%d\n", -+ g_rRlmPowerLimitConfiguration[i].aucCountryCode[0], -+ g_rRlmPowerLimitConfiguration[i].aucCountryCode[1], -+ g_rRlmPowerLimitConfiguration[i].ucCentralCh, -+ g_rRlmPowerLimitConfiguration[i].aucPwrLimit[PWR_LIMIT_CCK], -+ g_rRlmPowerLimitConfiguration[i].aucPwrLimit[PWR_LIMIT_20M], -+ g_rRlmPowerLimitConfiguration[i].aucPwrLimit[PWR_LIMIT_40M], -+ g_rRlmPowerLimitConfiguration[i].aucPwrLimit[PWR_LIMIT_80M], -+ g_rRlmPowerLimitConfiguration[i].aucPwrLimit[PWR_LIMIT_160M]); -+ } -+ -+ if (u2CountryCodeTable == COUNTRY_CODE_NULL) { -+ DBGLOG(RLM, LOUD, "Domain: Full search down\n"); -+ break; /*End of country table entry */ -+ } -+ -+ } -+ -+ if (fgEntryRepetetion == FALSE) -+ DBGLOG(RLM, TRACE, "Domain: Configuration Table no Repetiton.\n"); -+ -+ /*Configuration Table no error */ -+ if (fgTableValid == TRUE) -+ prAdapter->fgIsPowerLimitTableValid = TRUE; -+ else -+ prAdapter->fgIsPowerLimitTableValid = FALSE; -+ -+ /*Default Table Check */ -+ fgEntryRepetetion = FALSE; -+ for (i = 0; i < sizeof(g_rRlmPowerLimitDefault) / sizeof(COUNTRY_POWER_LIMIT_TABLE_DEFAULT); i++) { -+ -+ WLAN_GET_FIELD_BE16(&g_rRlmPowerLimitDefault[i].aucCountryCode[0], &u2CountryCodeTable); -+ -+ for (j = i + 1; j < sizeof(g_rRlmPowerLimitDefault) / sizeof(COUNTRY_POWER_LIMIT_TABLE_DEFAULT); j++) { -+ WLAN_GET_FIELD_BE16(&g_rRlmPowerLimitDefault[j].aucCountryCode[0], &u2CountryCodeCheck); -+ if (u2CountryCodeTable == u2CountryCodeCheck) { -+ fgEntryRepetetion = TRUE; -+ DBGLOG(RLM, LOUD, -+ "Domain: Default Repetition CC=%c%c\n", -+ g_rRlmPowerLimitDefault[j].aucCountryCode[0], -+ g_rRlmPowerLimitDefault[j].aucCountryCode[1]); -+ } -+ } -+ } -+ if (fgEntryRepetetion == FALSE) -+ DBGLOG(RLM, TRACE, "Domain: Default Table no Repetiton.\n"); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief -+* -+* @param[in] -+* -+* @return (u2TableIndex) : if 0xFFFF -> No Table Match -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT_16 rlmDomainPwrLimitDefaultTableDecision(P_ADAPTER_T prAdapter, UINT_16 u2CountryCode) -+{ -+ -+ UINT_16 i; -+ UINT_16 u2CountryCodeTable = COUNTRY_CODE_NULL; -+ UINT_16 u2TableIndex = POWER_LIMIT_TABLE_NULL; /* No Table Match */ -+ -+ /*Default Table Index */ -+ for (i = 0; i < sizeof(g_rRlmPowerLimitDefault) / sizeof(COUNTRY_POWER_LIMIT_TABLE_DEFAULT); i++) { -+ -+ WLAN_GET_FIELD_BE16(&g_rRlmPowerLimitDefault[i].aucCountryCode[0], &u2CountryCodeTable); -+ -+ if (u2CountryCodeTable == u2CountryCode) { -+ u2TableIndex = i; -+ break; /*match country code */ -+ } else if (u2CountryCodeTable == COUNTRY_CODE_NULL) { -+ u2TableIndex = i; -+ break; /*find last one country- Default */ -+ } -+ } -+ -+ DBGLOG(RLM, TRACE, "Domain: Default Table Index = %d\n", u2TableIndex); -+ -+ return u2TableIndex; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief -+* -+* @param[in] -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rlmDomainBuildCmdByDefaultTable(P_CMD_SET_COUNTRY_CHANNEL_POWER_LIMIT_T prCmd, UINT_16 u2DefaultTableIndex) -+{ -+ UINT_8 i, k; -+ P_COUNTRY_POWER_LIMIT_TABLE_DEFAULT prPwrLimitSubBand; -+ P_CMD_CHANNEL_POWER_LIMIT prCmdPwrLimit; -+ -+ prCmdPwrLimit = &prCmd->rChannelPowerLimit[0]; -+ prPwrLimitSubBand = &g_rRlmPowerLimitDefault[u2DefaultTableIndex]; -+ -+ /*Build power limit cmd by default table information */ -+ -+ for (i = POWER_LIMIT_2G4; i < POWER_LIMIT_SUBAND_NUM; i++) { -+ if (prPwrLimitSubBand->aucPwrLimitSubBand[i] < MAX_TX_POWER) { -+ for (k = g_rRlmSubBand[i].ucStartCh; k <= g_rRlmSubBand[i].ucEndCh; -+ k += g_rRlmSubBand[i].ucInterval) { -+ if ((prPwrLimitSubBand->ucPwrUnit & BIT(i)) == 0) { -+ prCmdPwrLimit->ucCentralCh = k; -+ prCmdPwrLimit->cPwrLimitCCK = -+ prPwrLimitSubBand->aucPwrLimitSubBand[i]; -+ prCmdPwrLimit->cPwrLimit20 = -+ prPwrLimitSubBand->aucPwrLimitSubBand[i]; -+ prCmdPwrLimit->cPwrLimit40 = -+ prPwrLimitSubBand->aucPwrLimitSubBand[i]; -+ prCmdPwrLimit->cPwrLimit80 = -+ prPwrLimitSubBand->aucPwrLimitSubBand[i]; -+ prCmdPwrLimit->cPwrLimit160 = -+ prPwrLimitSubBand->aucPwrLimitSubBand[i]; -+ prCmdPwrLimit++; -+ prCmd->ucNum++; -+ -+ } else { -+ /* ex: 40MHz power limit(mW\MHz) = 20MHz power limit(mW\MHz) * 2 -+ * ---> 40MHz power limit(dBm) = 20MHz power limit(dBm) + 6; */ -+ prCmdPwrLimit->ucCentralCh = k; -+ prCmdPwrLimit->cPwrLimitCCK = prPwrLimitSubBand->aucPwrLimitSubBand[i]; -+ prCmdPwrLimit->cPwrLimit20 = prPwrLimitSubBand->aucPwrLimitSubBand[i]; -+ prCmdPwrLimit->cPwrLimit40 = prPwrLimitSubBand->aucPwrLimitSubBand[i] + 6; -+ if (prCmdPwrLimit->cPwrLimit40 > MAX_TX_POWER) -+ prCmdPwrLimit->cPwrLimit40 = MAX_TX_POWER; -+ prCmdPwrLimit->cPwrLimit80 = prPwrLimitSubBand->aucPwrLimitSubBand[i] + 12; -+ if (prCmdPwrLimit->cPwrLimit80 > MAX_TX_POWER) -+ prCmdPwrLimit->cPwrLimit80 = MAX_TX_POWER; -+ prCmdPwrLimit->cPwrLimit160 = prPwrLimitSubBand->aucPwrLimitSubBand[i] + 18; -+ if (prCmdPwrLimit->cPwrLimit160 > MAX_TX_POWER) -+ prCmdPwrLimit->cPwrLimit160 = MAX_TX_POWER; -+ prCmdPwrLimit++; -+ prCmd->ucNum++; -+ } -+ } -+ } -+ } -+ -+#if 0 -+ if (prPwrLimitSubBand->aucPwrLimitSubBand[POWER_LIMIT_2G4] < MAX_TX_POWER) { -+ for (i = BAND_2G4_LOWER_BOUND; i <= BAND_2G4_UPPER_BOUND; i++) { -+ prCmdPwrLimit->ucCentralCh = i; -+ kalMemSet(&prCmdPwrLimit->cPwrLimitCCK, prPwrLimitSubBand->aucPwrLimitSubBand[POWER_LIMIT_2G4], -+ PWR_LIMIT_NUM); -+ prCmdPwrLimit++; -+ prCmd->ucNum++; -+ } -+ } -+ -+ if (prPwrLimitSubBand->aucPwrLimitSubBand[POWER_LIMIT_UNII1] < MAX_TX_POWER) { -+ if (prCmd->u2CountryCode != COUNTRY_CODE_KR) { -+ for (i = UNII1_LOWER_BOUND; i <= UNII1_UPPER_BOUND; i += 2) { -+ prCmdPwrLimit->ucCentralCh = i; -+ kalMemSet(&prCmdPwrLimit->cPwrLimitCCK, -+ prPwrLimitSubBand->aucPwrLimitSubBand[POWER_LIMIT_UNII1], PWR_LIMIT_NUM); -+ prCmdPwrLimit++; -+ prCmd->ucNum++; -+ } -+ } else { -+ for (i = UNII1_LOWER_BOUND; i <= UNII1_UPPER_BOUND; i += 2) { -+ /* ex: 40MHz power limit(mW\MHz) = 20MHz power limit(mW\MHz) * 2 -+ * ---> 40MHz power limit(dBm) = 20MHz power limit(dBm) + 6; */ -+ prCmdPwrLimit->ucCentralCh = i; -+ prCmdPwrLimit->cPwrLimitCCK = -+ g_rRlmPowerLimitDefault[u2DefaultTableIndex].cPwrLimitUnii1; -+ prCmdPwrLimit->cPwrLimit20 = -+ g_rRlmPowerLimitDefault[u2DefaultTableIndex].cPwrLimitUnii1; -+ prCmdPwrLimit->cPwrLimit40 = -+ g_rRlmPowerLimitDefault[u2DefaultTableIndex].cPwrLimitUnii1 + 6; -+ prCmdPwrLimit->cPwrLimit80 = -+ g_rRlmPowerLimitDefault[u2DefaultTableIndex].cPwrLimitUnii1 + 12; -+ prCmdPwrLimit->cPwrLimit160 = -+ g_rRlmPowerLimitDefault[u2DefaultTableIndex].cPwrLimitUnii1 + 18; -+ prCmdPwrLimit++; -+ prCmd->ucNum++; -+ } -+ } -+ } -+ -+ if (prPwrLimitSubBand->aucPwrLimitSubBand[POWER_LIMIT_UNII2A] < MAX_TX_POWER) { -+ for (i = UNII2A_LOWER_BOUND; i <= UNII2A_UPPER_BOUND; i += 2) { -+ prCmdPwrLimit->ucCentralCh = i; -+ kalMemSet(&prCmdPwrLimit->cPwrLimitCCK, -+ prPwrLimitSubBand->aucPwrLimitSubBand[POWER_LIMIT_UNII2A], PWR_LIMIT_NUM); -+ prCmdPwrLimit++; -+ prCmd->ucNum++; -+ } -+ } -+ -+ if (prPwrLimitSubBand->aucPwrLimitSubBand[POWER_LIMIT_UNII2C] < MAX_TX_POWER) { -+ for (i = UNII2C_LOWER_BOUND; i <= UNII2C_UPPER_BOUND; i += 2) { -+ prCmdPwrLimit->ucCentralCh = i; -+ kalMemSet(&prCmdPwrLimit->cPwrLimitCCK, -+ prPwrLimitSubBand->aucPwrLimitSubBand[POWER_LIMIT_UNII2C], PWR_LIMIT_NUM); -+ prCmdPwrLimit++; -+ prCmd->ucNum++; -+ } -+ } -+ if (prPwrLimitSubBand->aucPwrLimitSubBand[POWER_LIMIT_UNII3] < MAX_TX_POWER) { -+ for (i = UNII3_LOWER_BOUND; i <= UNII3_UPPER_BOUND; i += 2) { -+ prCmdPwrLimit->ucCentralCh = i; -+ kalMemSet(&prCmdPwrLimit->cPwrLimitCCK, -+ prPwrLimitSubBand->aucPwrLimitSubBand[POWER_LIMIT_UNII3], PWR_LIMIT_NUM); -+ prCmdPwrLimit++; -+ prCmd->ucNum++; -+ } -+ } -+#endif -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief -+* -+* @param[in] -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rlmDomainBuildCmdByConfigTable(P_ADAPTER_T prAdapter, P_CMD_SET_COUNTRY_CHANNEL_POWER_LIMIT_T prCmd) -+{ -+ UINT_8 i, k; -+ UINT_16 u2CountryCodeTable = COUNTRY_CODE_NULL; -+ P_CMD_CHANNEL_POWER_LIMIT prCmdPwrLimit; -+ BOOLEAN fgChannelValid; -+ -+ /*Build power limit cmd by configuration table information */ -+ -+ for (i = 0; i < sizeof(g_rRlmPowerLimitConfiguration) / sizeof(COUNTRY_POWER_LIMIT_TABLE_CONFIGURATION); i++) { -+ -+ WLAN_GET_FIELD_BE16(&g_rRlmPowerLimitConfiguration[i].aucCountryCode[0], &u2CountryCodeTable); -+ -+ fgChannelValid = -+ rlmDomainCheckChannelEntryValid(prAdapter, g_rRlmPowerLimitConfiguration[i].ucCentralCh); -+ -+ if (u2CountryCodeTable == COUNTRY_CODE_NULL) { -+ DBGLOG(RLM, TRACE, "Domain: full search configuration table done.\n"); -+ break; /*end of configuration table */ -+ } else if ((u2CountryCodeTable == prCmd->u2CountryCode) && (fgChannelValid == TRUE)) { -+ -+ prCmdPwrLimit = &prCmd->rChannelPowerLimit[0]; -+ -+ if (prCmd->ucNum != 0) { -+ for (k = 0; k < prCmd->ucNum; k++) { -+ if (prCmdPwrLimit->ucCentralCh == -+ g_rRlmPowerLimitConfiguration[i].ucCentralCh) { -+ -+ /*Cmd setting (Default table information) and -+ Configuration table has repetition channel entry, -+ ex : Default table (ex: 2.4G, limit = 20dBm) --> ch1~14 limit =20dBm, -+ Configuration table (ex: ch1, limit = 22dBm) --> ch 1 = 22 dBm -+ Cmd final setting --> ch1 = 22dBm, ch12~14 = 20dBm -+ */ -+ prCmdPwrLimit->cPwrLimitCCK = -+ g_rRlmPowerLimitConfiguration[i].aucPwrLimit[PWR_LIMIT_CCK]; -+ prCmdPwrLimit->cPwrLimit20 = -+ g_rRlmPowerLimitConfiguration[i].aucPwrLimit[PWR_LIMIT_20M]; -+ prCmdPwrLimit->cPwrLimit40 = -+ g_rRlmPowerLimitConfiguration[i].aucPwrLimit[PWR_LIMIT_40M]; -+ prCmdPwrLimit->cPwrLimit80 = -+ g_rRlmPowerLimitConfiguration[i].aucPwrLimit[PWR_LIMIT_80M]; -+ prCmdPwrLimit->cPwrLimit160 = -+ g_rRlmPowerLimitConfiguration[i].aucPwrLimit[PWR_LIMIT_160M]; -+ -+ DBGLOG(RLM, LOUD, -+ "Domain: CC=%c%c,ConfigCh=%d,Limit=%d,%d,%d,%d,%d,Fg=%d\n", -+ ((prCmd->u2CountryCode & 0xff00) >> 8), -+ (prCmd->u2CountryCode & 0x00ff), prCmdPwrLimit->ucCentralCh, -+ prCmdPwrLimit->cPwrLimitCCK, prCmdPwrLimit->cPwrLimit20, -+ prCmdPwrLimit->cPwrLimit40, prCmdPwrLimit->cPwrLimit80, -+ prCmdPwrLimit->cPwrLimit160, prCmdPwrLimit->ucFlag); -+ -+ break; -+ } -+ prCmdPwrLimit++; -+ } -+ if (k == prCmd->ucNum) { -+ -+ /*Full search cmd (Default table setting) no match channey, -+ ex : Default table (ex: 2.4G, limit = 20dBm) --> ch1~14 limit =20dBm, -+ Configuration table (ex: ch36, limit = 22dBm) --> ch 36 = 22 dBm -+ Cmd final setting --> ch1~14 = 20dBm, ch36= 22dBm -+ */ -+ prCmdPwrLimit->cPwrLimitCCK = -+ g_rRlmPowerLimitConfiguration[i].aucPwrLimit[PWR_LIMIT_CCK]; -+ prCmdPwrLimit->cPwrLimit20 = -+ g_rRlmPowerLimitConfiguration[i].aucPwrLimit[PWR_LIMIT_20M]; -+ prCmdPwrLimit->cPwrLimit40 = -+ g_rRlmPowerLimitConfiguration[i].aucPwrLimit[PWR_LIMIT_40M]; -+ prCmdPwrLimit->cPwrLimit80 = -+ g_rRlmPowerLimitConfiguration[i].aucPwrLimit[PWR_LIMIT_80M]; -+ prCmdPwrLimit->cPwrLimit160 = -+ g_rRlmPowerLimitConfiguration[i].aucPwrLimit[PWR_LIMIT_160M]; -+ prCmd->ucNum++; -+ -+ DBGLOG(RLM, LOUD, -+ "Domain: Full CC=%c%c,ConfigCh=%d,Limit=%d,%d,%d,%d,%d,Fg=%d\n", -+ ((prCmd->u2CountryCode & 0xff00) >> 8), (prCmd->u2CountryCode & 0x00ff), -+ prCmdPwrLimit->ucCentralCh, prCmdPwrLimit->cPwrLimitCCK, -+ prCmdPwrLimit->cPwrLimit20, prCmdPwrLimit->cPwrLimit40, -+ prCmdPwrLimit->cPwrLimit80, prCmdPwrLimit->cPwrLimit160, -+ prCmdPwrLimit->ucFlag); -+ -+ } -+ } else { -+ -+ /*Default table power limit value are 63--> cmd table no channel entry -+ ex : Default table (ex: 2.4G, limit = 63Bm) --> no channel entry in cmd, -+ Configuration table (ex: ch36, limit = 22dBm) --> ch 36 = 22 dBm -+ Cmd final setting --> ch36= 22dBm -+ */ -+ prCmdPwrLimit->ucCentralCh = g_rRlmPowerLimitConfiguration[i].ucCentralCh; -+ prCmdPwrLimit->cPwrLimitCCK = -+ g_rRlmPowerLimitConfiguration[i].aucPwrLimit[PWR_LIMIT_CCK]; -+ prCmdPwrLimit->cPwrLimit20 = -+ g_rRlmPowerLimitConfiguration[i].aucPwrLimit[PWR_LIMIT_20M]; -+ prCmdPwrLimit->cPwrLimit40 = -+ g_rRlmPowerLimitConfiguration[i].aucPwrLimit[PWR_LIMIT_40M]; -+ prCmdPwrLimit->cPwrLimit80 = -+ g_rRlmPowerLimitConfiguration[i].aucPwrLimit[PWR_LIMIT_80M]; -+ prCmdPwrLimit->cPwrLimit160 = -+ g_rRlmPowerLimitConfiguration[i].aucPwrLimit[PWR_LIMIT_160M]; -+ prCmd->ucNum++; -+ -+ DBGLOG(RLM, LOUD, "Domain: Default table power limit value are 63.\n"); -+ DBGLOG(RLM, LOUD, "Domain: CC=%c%c,ConfigCh=%d,Limit=%d,%d,%d,%d,%d,Fg=%d\n", -+ ((prCmd->u2CountryCode & 0xff00) >> 8), -+ (prCmd->u2CountryCode & 0x00ff), prCmdPwrLimit->ucCentralCh, -+ prCmdPwrLimit->cPwrLimitCCK, prCmdPwrLimit->cPwrLimit20, -+ prCmdPwrLimit->cPwrLimit40, prCmdPwrLimit->cPwrLimit80, -+ prCmdPwrLimit->cPwrLimit160, prCmdPwrLimit->ucFlag); -+ -+ } -+ } -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief -+* -+* @param[in] -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rlmDomainSendPwrLimitCmd(P_ADAPTER_T prAdapter) -+{ -+ P_CMD_SET_COUNTRY_CHANNEL_POWER_LIMIT_T prCmd; -+ UINT_8 i; -+ UINT_16 u2DefaultTableIndex; -+ UINT_32 u4SetCmdTableMaxSize; -+ UINT_32 u4SetQueryInfoLen; -+ P_CMD_CHANNEL_POWER_LIMIT prCmdPwrLimit; /* for print usage */ -+ -+ u4SetCmdTableMaxSize = -+ sizeof(CMD_SET_COUNTRY_CHANNEL_POWER_LIMIT_T) + -+ MAX_CMD_SUPPORT_CHANNEL_NUM * sizeof(CMD_CHANNEL_POWER_LIMIT); -+ -+ prCmd = cnmMemAlloc(prAdapter, RAM_TYPE_BUF, u4SetCmdTableMaxSize); -+ -+ if (!prCmd) { -+ DBGLOG(RLM, ERROR, "Domain: no buf to send cmd\n"); -+ return; -+ } -+ kalMemZero(prCmd, u4SetCmdTableMaxSize); -+ -+ u2DefaultTableIndex = -+ rlmDomainPwrLimitDefaultTableDecision(prAdapter, prAdapter->rWifiVar.rConnSettings.u2CountryCode); -+ -+ if (u2DefaultTableIndex != POWER_LIMIT_TABLE_NULL) { -+ -+ WLAN_GET_FIELD_BE16(&g_rRlmPowerLimitDefault[u2DefaultTableIndex].aucCountryCode[0], -+ &prCmd->u2CountryCode); -+ -+ prCmd->ucNum = 0; -+ -+ if (prCmd->u2CountryCode != COUNTRY_CODE_NULL) { -+ /*Command - default table information */ -+ rlmDomainBuildCmdByDefaultTable(prCmd, u2DefaultTableIndex); -+ -+ /*Command - configuration table information */ -+ rlmDomainBuildCmdByConfigTable(prAdapter, prCmd); -+ } -+ } -+#if 0 -+ u4SetCmdTableMaxSize = -+ sizeof(CMD_SET_COUNTRY_CHANNEL_POWER_LIMIT_T) + -+ MAX_CMD_SUPPORT_CHANNEL_NUM * sizeof(CMD_CHANNEL_POWER_LIMIT); -+ -+ prCmd = cnmMemAlloc(prAdapter, RAM_TYPE_BUF, u4SetCmdTableMaxSize); -+ ASSERT(prCmd); -+ -+ /* To do: exception handle */ -+ if (!prCmd) { -+ DBGLOG(RLM, ERROR, "Domain: no buf to send cmd\n"); -+ return; -+ } -+ kalMemZero(prCmd, u4SetCmdTableMaxSize); /* TODO memzero */ -+ -+ if (u2TableIndex != POWER_LIMIT_TABLE_NULL && u2TableIndex < MAX_DEFAULT_TABLE_COUNTRY_NUM) { -+ -+ prCmd->u2CountryCode = (((UINT_16) g_rRlmCountryPowerLimitTable[u2TableIndex].aucCountryCode[0]) << 8) | -+ (((UINT_16) g_rRlmCountryPowerLimitTable[u2TableIndex].aucCountryCode[1]) & BITS(0, 7)); -+ prChPwrLimit = &g_rRlmCountryPowerLimitTable[u2TableIndex].rChannelPowerLimit[0]; -+ prCmdPwrLimit = &prCmd->rChannelPowerLimit[0]; -+ prCmd->ucNum = 0; -+ for (i = 0; i < MAX_CMD_SUPPORT_CHANNEL_NUM; i++) { -+ -+ if (prChPwrLimit->ucCentralCh != ENDCH) { -+ -+ /*Check Power limit table channel efficient or not */ -+ fgChannelValid = rlmDomainCheckChannelEntryValid(prAdapter, prChPwrLimit->ucCentralCh); -+ -+ /*Cmd set up */ -+ if (fgChannelValid) { -+ kalMemCopy(prCmdPwrLimit, prChPwrLimit, sizeof(CMD_CHANNEL_POWER_LIMIT)); -+ DBGLOG(RLM, INFO, -+ "Domain: ValidCh=%d,Limit=%d,%d,%d,%d,%d,Fg=%d\n", -+ prCmdPwrLimit->ucCentralCh, prCmdPwrLimit->cPwrLimitCCK, -+ prCmdPwrLimit->cPwrLimit20, prCmdPwrLimit->cPwrLimit40, -+ prCmdPwrLimit->cPwrLimit80, prCmdPwrLimit->cPwrLimit160, -+ prCmdPwrLimit->ucFlag); -+ prCmd->ucNum++; -+ prCmdPwrLimit++; -+ } else { -+ DBGLOG(RLM, INFO, -+ "Domain: Non-Ch=%d,Limit=%d,%d,%d,%d,%d,Fg=%d\n", -+ prChPwrLimit->ucCentralCh, prChPwrLimit->cPwrLimitCCK, -+ prChPwrLimit->cPwrLimit20, prChPwrLimit->cPwrLimit40, -+ prChPwrLimit->cPwrLimit80, prChPwrLimit->cPwrLimit160, -+ prChPwrLimit->ucFlag); -+ } -+ prChPwrLimit++; -+ } else { -+ /*End of the chanel entry */ -+ break; -+ } -+ }; -+ } -+#endif -+ -+ if (prCmd->u2CountryCode != 0) { -+ DBGLOG(RLM, INFO, -+ "Domain: ValidCC =%c%c, ChNum=%d\n", ((prCmd->u2CountryCode & 0xff00) >> 8), -+ (prCmd->u2CountryCode & 0x00ff), prCmd->ucNum); -+ } else { -+ DBGLOG(RLM, INFO, "Domain: ValidCC =0x%04x, ucNum=%d\n", prCmd->u2CountryCode, prCmd->ucNum); -+ } -+ prCmdPwrLimit = &prCmd->rChannelPowerLimit[0]; -+ -+ for (i = 0; i < prCmd->ucNum; i++) { -+ DBGLOG(RLM, TRACE, "Domain: Ch=%d,Limit=%d,%d,%d,%d,%d,Fg=%d\n", prCmdPwrLimit->ucCentralCh, -+ prCmdPwrLimit->cPwrLimitCCK, prCmdPwrLimit->cPwrLimit20, prCmdPwrLimit->cPwrLimit40, -+ prCmdPwrLimit->cPwrLimit80, prCmdPwrLimit->cPwrLimit160, prCmdPwrLimit->ucFlag); -+ prCmdPwrLimit++; -+ } -+ -+ u4SetQueryInfoLen = -+ (sizeof(CMD_SET_COUNTRY_CHANNEL_POWER_LIMIT_T) + (prCmd->ucNum) * sizeof(CMD_CHANNEL_POWER_LIMIT)); -+ -+ /* Update domain info to chip */ -+ if (prCmd->ucNum <= MAX_CMD_SUPPORT_CHANNEL_NUM) { -+ wlanSendSetQueryCmd(prAdapter, /* prAdapter */ -+ CMD_ID_SET_COUNTRY_POWER_LIMIT, /* ucCID */ -+ TRUE, /* fgSetQuery */ -+ FALSE, /* fgNeedResp */ -+ FALSE, /* fgIsOid */ -+ NULL, /* pfCmdDoneHandler */ -+ NULL, /* pfCmdTimeoutHandler */ -+ u4SetQueryInfoLen, /* u4SetQueryInfoLen */ -+ (PUINT_8) prCmd, /* pucInfoBuffer */ -+ NULL, /* pvSetQueryBuffer */ -+ 0 /* u4SetQueryBufferLen */ -+ ); -+ } else -+ DBGLOG(RLM, ERROR, "Domain: illegal power limit table"); -+ -+ cnmMemFree(prAdapter, prCmd); -+ -+} -+#endif -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rlm_obss.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rlm_obss.c -new file mode 100644 -index 000000000000..8450124a3f38 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rlm_obss.c -@@ -0,0 +1,436 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/rlm_obss.c#2 -+*/ -+ -+/*! \file "rlm_obss.c" -+ \brief -+ -+*/ -+ -+/* -+** Log: rlm_obss.c -+ * -+ * 07 17 2012 yuche.tsai -+ * NULL -+ * Compile no error before trial run. -+ * -+ * 11 15 2011 cm.chang -+ * NULL -+ * Avoid possible OBSS scan when BSS is switched -+ * -+ * 11 08 2011 cm.chang -+ * NULL -+ * Add RLM and CNM debug message for XLOG -+ * -+ * 10 25 2011 cm.chang -+ * [WCXRP00001058] [All Wi-Fi][Driver] Fix sta_rec's phyTypeSet and OBSS scan in AP mode -+ * Regulation class is changed to 81 in 20_40_coexistence action frame -+ * -+ * 04 12 2011 cm.chang -+ * [WCXRP00000634] [MT6620 Wi-Fi][Driver][FW] 2nd BSS will not support 40MHz bandwidth for concurrency -+ * . -+ * -+ * 03 29 2011 cm.chang -+ * [WCXRP00000606] [MT6620 Wi-Fi][Driver][FW] Fix klocwork warning -+ * As CR title -+ * -+ * 01 24 2011 cm.chang -+ * [WCXRP00000384] [MT6620 Wi-Fi][Driver][FW] Handle 20/40 action frame -+ * in AP mode and stop ampdu timer when sta_rec is freed -+ * Process received 20/40 coexistence action frame for AP mode -+ * -+ * 01 13 2011 cm.chang -+ * [WCXRP00000358] [MT6620 Wi-Fi][Driver] Provide concurrent information for each module -+ * Refine function when rcv a 20/40M public action frame -+ * -+ * 01 13 2011 cm.chang -+ * [WCXRP00000354] [MT6620 Wi-Fi][Driver][FW] Follow NVRAM bandwidth setting -+ * Use SCO of BSS_INFO to replace user-defined setting variables -+ * -+ * 01 12 2011 cm.chang -+ * [WCXRP00000354] [MT6620 Wi-Fi][Driver][FW] Follow NVRAM bandwidth setting -+ * User-defined bandwidth is for 2.4G and 5G individually -+ * -+ * 10 18 2010 cp.wu -+ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning -+ * use definition macro to replace hard-coded constant -+ * -+ * 09 16 2010 cm.chang -+ * NULL -+ * Change conditional compiling options for BOW -+ * -+ * 09 10 2010 cm.chang -+ * NULL -+ * Always update Beacon content if FW sync OBSS info -+ * -+ * 08 24 2010 cm.chang -+ * NULL -+ * Support RLM initail channel of Ad-hoc, P2P and BOW -+ * -+ * 08 20 2010 cm.chang -+ * NULL -+ * Migrate RLM code to host from FW -+ * -+ * 07 26 2010 yuche.tsai -+ * -+ * Fix compile error while enabling WiFi Direct function. -+ * -+ * 07 21 2010 yuche.tsai -+ * -+ * Add P2P Scan & Scan Result Parsing & Saving. -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 07 08 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Check draft RLM code for HT cap -+ * -+ * 05 07 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Process 20/40 coexistence public action frame in AP mode -+ * -+ * 05 05 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * First draft support for 20/40M bandwidth for AP mode -+ * -+ * 04 24 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * g_aprBssInfo[] depends on CFG_SUPPORT_P2P and CFG_SUPPORT_BOW -+ * -+ * 04 13 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Add more ASSERT to check exception -+ * -+ * 04 07 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Add virtual test for OBSS scan -+ * -+ * 03 30 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Support 2.4G OBSS scan -+ * -+ * 03 03 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * To support CFG_SUPPORT_BCM_STP -+ * -+ * 02 13 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Support PCO in STA mode -+ * -+ * 02 12 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Use bss info array for concurrent handle -+ * -+ * 02 05 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Add AAA Module Support, Revise Net Type to Net Type Index for array lookup -+ * -+ * 01 25 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Support protection and bandwidth switch -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "precomp.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+static VOID rlmObssScanTimeout(P_ADAPTER_T prAdapter, ULONG ulData); -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rlmObssInit(P_ADAPTER_T prAdapter) -+{ -+ P_BSS_INFO_T prBssInfo; -+ UINT_8 ucNetIdx; -+ -+ RLM_NET_FOR_EACH(ucNetIdx) { -+ prBssInfo = &prAdapter->rWifiVar.arBssInfo[ucNetIdx]; -+ ASSERT(prBssInfo); -+ -+ cnmTimerInitTimer(prAdapter, &prBssInfo->rObssScanTimer, rlmObssScanTimeout, (ULONG) prBssInfo); -+ } /* end of RLM_NET_FOR_EACH */ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN rlmObssUpdateChnlLists(P_ADAPTER_T prAdapter, P_SW_RFB_T prSwRfb) -+{ -+ return TRUE; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rlmObssScanDone(P_ADAPTER_T prAdapter, P_MSG_HDR_T prMsgHdr) -+{ -+ P_MSG_SCN_SCAN_DONE prScanDoneMsg; -+ P_BSS_INFO_T prBssInfo; -+ P_MSDU_INFO_T prMsduInfo; -+ P_ACTION_20_40_COEXIST_FRAME prTxFrame; -+ UINT_16 i, u2PayloadLen; -+ -+ ASSERT(prMsgHdr); -+ -+ prScanDoneMsg = (P_MSG_SCN_SCAN_DONE) prMsgHdr; -+ prBssInfo = &prAdapter->rWifiVar.arBssInfo[prScanDoneMsg->ucNetTypeIndex]; -+ ASSERT(prBssInfo); -+ -+ DBGLOG(RLM, INFO, "OBSS Scan Done (NetIdx=%d, Mode=%d)\n", -+ prScanDoneMsg->ucNetTypeIndex, prBssInfo->eCurrentOPMode); -+ -+ cnmMemFree(prAdapter, prMsgHdr); -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ /* AP mode */ -+ if ((prAdapter->fgIsP2PRegistered) && -+ (IS_NET_ACTIVE(prAdapter, prBssInfo->ucNetTypeIndex)) && -+ (prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT)) { -+ return; -+ } -+#endif -+ -+ /* STA mode */ -+ if (prBssInfo->eCurrentOPMode != OP_MODE_INFRASTRUCTURE || -+ !RLM_NET_PARAM_VALID(prBssInfo) || prBssInfo->u2ObssScanInterval == 0) { -+ DBGLOG(RLM, WARN, "OBSS Scan Done (NetIdx=%d) -- Aborted!!\n", prBssInfo->ucNetTypeIndex); -+ return; -+ } -+ -+ /* To do: check 2.4G channel list to decide if obss mgmt should be -+ * sent to associated AP. Note: how to handle concurrent network? -+ * To do: invoke rlmObssChnlLevel() to decide if 20/40 BSS coexistence -+ * management frame is needed. -+ */ -+ prMsduInfo = (P_MSDU_INFO_T) cnmMgtPktAlloc(prAdapter, MAC_TX_RESERVED_FIELD + PUBLIC_ACTION_MAX_LEN); -+ if ((prBssInfo->auc2G_20mReqChnlList[0] > 0 || prBssInfo->auc2G_NonHtChnlList[0] > 0) && prMsduInfo != NULL) { -+ DBGLOG(RLM, INFO, "Send 20/40 coexistence mgmt(20mReq=%d, NonHt=%d)\n", -+ prBssInfo->auc2G_20mReqChnlList[0], prBssInfo->auc2G_NonHtChnlList[0]); -+ -+ prTxFrame = (P_ACTION_20_40_COEXIST_FRAME) -+ ((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD); -+ -+ prTxFrame->u2FrameCtrl = MAC_FRAME_ACTION; -+ COPY_MAC_ADDR(prTxFrame->aucDestAddr, prBssInfo->aucBSSID); -+ COPY_MAC_ADDR(prTxFrame->aucSrcAddr, prBssInfo->aucOwnMacAddr); -+ COPY_MAC_ADDR(prTxFrame->aucBSSID, prBssInfo->aucBSSID); -+ -+ prTxFrame->ucCategory = CATEGORY_PUBLIC_ACTION; -+ prTxFrame->ucAction = ACTION_PUBLIC_20_40_COEXIST; -+ -+ /* To do: find correct algorithm */ -+ prTxFrame->rBssCoexist.ucId = ELEM_ID_20_40_BSS_COEXISTENCE; -+ prTxFrame->rBssCoexist.ucLength = 1; -+ prTxFrame->rBssCoexist.ucData = (prBssInfo->auc2G_20mReqChnlList[0] > 0) ? BSS_COEXIST_20M_REQ : 0; -+ -+ u2PayloadLen = 2 + 3; -+ -+ if (prBssInfo->auc2G_NonHtChnlList[0] > 0) { -+ ASSERT(prBssInfo->auc2G_NonHtChnlList[0] <= CHNL_LIST_SZ_2G); -+ -+ prTxFrame->rChnlReport.ucId = ELEM_ID_20_40_INTOLERANT_CHNL_REPORT; -+ prTxFrame->rChnlReport.ucLength = prBssInfo->auc2G_NonHtChnlList[0] + 1; -+ prTxFrame->rChnlReport.ucRegulatoryClass = 81; /* 2.4GHz, ch1~13 */ -+ for (i = 0; i < prBssInfo->auc2G_NonHtChnlList[0] && i < CHNL_LIST_SZ_2G; i++) -+ prTxFrame->rChnlReport.aucChannelList[i] = prBssInfo->auc2G_NonHtChnlList[i + 1]; -+ -+ u2PayloadLen += IE_SIZE(&prTxFrame->rChnlReport); -+ } -+ ASSERT((WLAN_MAC_HEADER_LEN + u2PayloadLen) <= PUBLIC_ACTION_MAX_LEN); -+ -+ /* Clear up channel lists in 2.4G band */ -+ prBssInfo->auc2G_20mReqChnlList[0] = 0; -+ prBssInfo->auc2G_NonHtChnlList[0] = 0; -+ -+ /* 4 Update information of MSDU_INFO_T */ -+ prMsduInfo->ucPacketType = HIF_TX_PACKET_TYPE_MGMT; /* Management frame */ -+ prMsduInfo->ucStaRecIndex = prBssInfo->prStaRecOfAP->ucIndex; -+ prMsduInfo->ucNetworkType = prBssInfo->ucNetTypeIndex; -+ prMsduInfo->ucMacHeaderLength = WLAN_MAC_MGMT_HEADER_LEN; -+ prMsduInfo->fgIs802_1x = FALSE; -+ prMsduInfo->fgIs802_11 = TRUE; -+ prMsduInfo->u2FrameLength = WLAN_MAC_MGMT_HEADER_LEN + u2PayloadLen; -+ prMsduInfo->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter); -+ prMsduInfo->pfTxDoneHandler = NULL; -+ prMsduInfo->fgIsBasicRate = FALSE; -+ -+ /* 4 Enqueue the frame to send this action frame. */ -+ nicTxEnqueueMsdu(prAdapter, prMsduInfo); -+ } -+ /* end of prMsduInfo != NULL */ -+ if (prBssInfo->u2ObssScanInterval > 0) { -+ DBGLOG(RLM, INFO, "Set OBSS timer (NetIdx=%d, %d sec)\n", -+ prBssInfo->ucNetTypeIndex, prBssInfo->u2ObssScanInterval); -+ -+ cnmTimerStartTimer(prAdapter, &prBssInfo->rObssScanTimer, prBssInfo->u2ObssScanInterval * MSEC_PER_SEC); -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+static VOID rlmObssScanTimeout(P_ADAPTER_T prAdapter, ULONG ulData) -+{ -+ P_BSS_INFO_T prBssInfo; -+ -+ prBssInfo = (P_BSS_INFO_T) ulData; -+ ASSERT(prBssInfo); -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ if (prAdapter->fgIsP2PRegistered && (IS_NET_ACTIVE(prAdapter, prBssInfo->ucNetTypeIndex))) { -+ -+ /* AP mode */ -+ if (prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT) { -+ -+ prBssInfo->fgObssActionForcedTo20M = FALSE; -+ -+ /* Check if Beacon content need to be updated */ -+ rlmUpdateParamsForAP(prAdapter, prBssInfo, FALSE); -+ -+ return; -+ } -+#if CFG_SUPPORT_WFD -+ /* WFD streaming */ -+ else { -+ P_WFD_CFG_SETTINGS_T prWfdCfgSettings = -+ &prAdapter->rWifiVar.prP2pFsmInfo->rWfdConfigureSettings; -+ P_BSS_INFO_T prP2pBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]; -+ -+ /* If WFD is enabled & connected */ -+ if (prWfdCfgSettings->ucWfdEnable && -+ (prWfdCfgSettings->u4WfdFlag & BIT(0)) && RLM_NET_PARAM_VALID(prP2pBssInfo)) { -+ -+ /* Skip OBSS scan */ -+ prBssInfo->u2ObssScanInterval = 0; -+ -+ DBGLOG(RLM, INFO, "WFD is running. Stop net[%u] OBSS scan.\n", -+ (UINT_32) prBssInfo->ucNetTypeIndex); -+ -+ return; -+ } -+ } -+#endif -+ } -+#endif /* end of CFG_ENABLE_WIFI_DIRECT */ -+ -+ /* STA mode */ -+ if (prBssInfo->eCurrentOPMode != OP_MODE_INFRASTRUCTURE || -+ !RLM_NET_PARAM_VALID(prBssInfo) || prBssInfo->u2ObssScanInterval == 0) { -+ DBGLOG(RLM, WARN, "OBSS Scan timeout (NetIdx=%d) -- Aborted!!\n", prBssInfo->ucNetTypeIndex); -+ return; -+ } -+ -+ rlmObssTriggerScan(prAdapter, prBssInfo); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rlmObssTriggerScan(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo) -+{ -+ P_MSG_SCN_SCAN_REQ prScanReqMsg; -+ -+ ASSERT(prBssInfo); -+ -+ prScanReqMsg = (P_MSG_SCN_SCAN_REQ) -+ cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_SCN_SCAN_REQ)); -+ ASSERT(prScanReqMsg); -+ -+ if (!prScanReqMsg) { -+ DBGLOG(RLM, WARN, "No buf for OBSS scan (NetIdx=%d)!!\n", prBssInfo->ucNetTypeIndex); -+ -+ cnmTimerStartTimer(prAdapter, &prBssInfo->rObssScanTimer, prBssInfo->u2ObssScanInterval * MSEC_PER_SEC); -+ return; -+ } -+ -+ /* It is ok that ucSeqNum is set to fixed value because the same network -+ * OBSS scan interval is limited to OBSS_SCAN_MIN_INTERVAL (min 10 sec) -+ * and scan module don't care seqNum of OBSS scanning -+ */ -+ prScanReqMsg->rMsgHdr.eMsgId = MID_RLM_SCN_SCAN_REQ; -+ prScanReqMsg->ucSeqNum = 0x33; -+ prScanReqMsg->ucNetTypeIndex = prBssInfo->ucNetTypeIndex; -+ prScanReqMsg->eScanType = SCAN_TYPE_ACTIVE_SCAN; -+ prScanReqMsg->ucSSIDType = SCAN_REQ_SSID_WILDCARD; -+ prScanReqMsg->ucSSIDLength = 0; -+ prScanReqMsg->eScanChannel = SCAN_CHANNEL_2G4; -+ prScanReqMsg->u2IELen = 0; -+ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prScanReqMsg, MSG_SEND_METHOD_BUF); -+ -+ DBGLOG(RLM, INFO, "Timeout to trigger OBSS scan (NetIdx=%d)!!\n", prBssInfo->ucNetTypeIndex); -+} -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rlm_protection.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rlm_protection.c -new file mode 100644 -index 000000000000..d3c513397095 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rlm_protection.c -@@ -0,0 +1,105 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/rlm_protection.c#1 -+*/ -+ -+/*! \file "rlm_protection.c" -+ \brief -+ -+*/ -+ -+/* -+** Log: rlm_protection.c -+ * -+ * 08 20 2010 cm.chang -+ * NULL -+ * Migrate RLM code to host from FW -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 07 08 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Check draft RLM code for HT cap -+ * -+ * 05 28 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Set RTS threshold of 2K bytes initially -+ * -+ * 04 24 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * g_aprBssInfo[] depends on CFG_SUPPORT_P2P and CFG_SUPPORT_BOW -+ * -+ * 04 22 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * First draft code to support protection in AP mode -+ * -+ * 03 31 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Enable RTS threshold temporarily for AMPDU -+ * -+ * 03 16 2010 kevin.huang -+ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support -+ * Add AdHoc Mode -+ * -+ * 03 03 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * To support CFG_SUPPORT_BCM_STP -+ * -+ * 02 13 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Support PCO in STA mode -+ * -+ * 02 12 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Use bss info array for concurrent handle -+ * -+ * 01 25 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Support protection and bandwidth switch -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/roaming_fsm.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/roaming_fsm.c -new file mode 100644 -index 000000000000..3f088c283993 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/roaming_fsm.c -@@ -0,0 +1,539 @@ -+/* -+** Id: -+*/ -+ -+/*! \file "roaming_fsm.c" -+ \brief This file defines the FSM for Roaming MODULE. -+ -+ This file defines the FSM for Roaming MODULE. -+*/ -+ -+/* -+** Log: roaming_fsm.c -+ * -+ * 11 24 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * Adjust code for DBG and CONFIG_XLOG. -+ * -+ * 11 11 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * modify the xlog related code. -+ * -+ * 11 02 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * adding the code for XLOG. -+ * -+ * 08 31 2011 tsaiyuan.hsu -+ * [WCXRP00000931] [MT5931 Wi-Fi][DRV/FW] add swcr to disable roaming from driver -+ * remove obsolete code. -+ * -+ * 08 15 2011 tsaiyuan.hsu -+ * [WCXRP00000931] [MT5931 Wi-Fi][DRV/FW] add swcr to disable roaming from driver -+ * add swcr in driver reg, 0x9fxx0000, to disable roaming . -+ * -+ * 03 16 2011 tsaiyuan.hsu -+ * [WCXRP00000517] [MT6620 Wi-Fi][Driver][FW] Fine Tune Performance of Roaming -+ * remove obsolete definition and unused variables. -+ * -+ * 02 26 2011 tsaiyuan.hsu -+ * [WCXRP00000391] [MT6620 Wi-Fi][FW] Add Roaming Support -+ * not send disassoc or deauth to leaving AP so as to improve performace of roaming. -+ * -+ * 01 27 2011 tsaiyuan.hsu -+ * [WCXRP00000392] [MT6620 Wi-Fi][Driver] Add Roaming Support -+ * add roaming fsm -+ * 1. not support 11r, only use strength of signal to determine roaming. -+ * 2. not enable CFG_SUPPORT_ROAMING until completion of full test. -+ * 3. in 6620, adopt work-around to avoid sign extension problem of cck of hw -+ * 4. assume that change of link quality in smooth way. -+ * -+ * 01 27 2011 tsaiyuan.hsu -+ * [WCXRP00000392] [MT6620 Wi-Fi][Driver] Add Roaming Support -+ * add roaming fsm -+ * 1. not support 11r, only use strength of signal to determine roaming. -+ * 2. not enable CFG_SUPPORT_ROAMING until completion of full test. -+ * 3. in 6620, adopt work-around to avoid sign extension problem of cck of hw -+ * 4. assume that change of link quality in smooth way. -+ * -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "precomp.h" -+ -+#if CFG_SUPPORT_ROAMING -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+#if DBG -+/*lint -save -e64 Type mismatch */ -+static PUINT_8 apucDebugRoamingState[ROAMING_STATE_NUM] = { -+ (PUINT_8) DISP_STRING("ROAMING_STATE_IDLE"), -+ (PUINT_8) DISP_STRING("ROAMING_STATE_DECISION"), -+ (PUINT_8) DISP_STRING("ROAMING_STATE_DISCOVERY"), -+ (PUINT_8) DISP_STRING("ROAMING_STATE_ROAM") -+}; -+ -+/*lint -restore */ -+#endif /* DBG */ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+/* -+#define ROAMING_ENABLE_CHECK(_roam) \ -+{ \ -+ if (!(_roam->fgIsEnableRoaming)) \ -+ return; \ -+} -+*/ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Initialize the value in ROAMING_FSM_INFO_T for ROAMING FSM operation -+* -+* @param [IN P_ADAPTER_T] prAdapter -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID roamingFsmInit(IN P_ADAPTER_T prAdapter) -+{ -+ P_ROAMING_INFO_T prRoamingFsmInfo; -+ P_CONNECTION_SETTINGS_T prConnSettings; -+ -+ DBGLOG(ROAMING, LOUD, "->roamingFsmInit(): Current Time = %u\n", kalGetTimeTick()); -+ -+ prRoamingFsmInfo = (P_ROAMING_INFO_T) &(prAdapter->rWifiVar.rRoamingInfo); -+ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); -+ -+ /* 4 <1> Initiate FSM */ -+ prRoamingFsmInfo->fgIsEnableRoaming = prConnSettings->fgIsEnableRoaming; -+ prRoamingFsmInfo->eCurrentState = ROAMING_STATE_IDLE; -+ prRoamingFsmInfo->rRoamingDiscoveryUpdateTime = 0; -+ -+} /* end of roamingFsmInit() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Uninitialize the value in AIS_FSM_INFO_T for AIS FSM operation -+* -+* @param [IN P_ADAPTER_T] prAdapter -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID roamingFsmUninit(IN P_ADAPTER_T prAdapter) -+{ -+ P_ROAMING_INFO_T prRoamingFsmInfo; -+ -+ DBGLOG(ROAMING, LOUD, "->roamingFsmUninit(): Current Time = %u\n", kalGetTimeTick()); -+ -+ prRoamingFsmInfo = (P_ROAMING_INFO_T) &(prAdapter->rWifiVar.rRoamingInfo); -+ -+ prRoamingFsmInfo->eCurrentState = ROAMING_STATE_IDLE; -+ -+} /* end of roamingFsmUninit() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Send commands to firmware -+* -+* @param [IN P_ADAPTER_T] prAdapter -+* [IN P_ROAMING_PARAM_T] prParam -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID roamingFsmSendCmd(IN P_ADAPTER_T prAdapter, IN P_ROAMING_PARAM_T prParam) -+{ -+ P_ROAMING_INFO_T prRoamingFsmInfo; -+ WLAN_STATUS rStatus; -+ -+ DBGLOG(ROAMING, LOUD, "->roamingFsmSendCmd(): Current Time = %u\n", kalGetTimeTick()); -+ -+ prRoamingFsmInfo = (P_ROAMING_INFO_T) &(prAdapter->rWifiVar.rRoamingInfo); -+ -+ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ -+ CMD_ID_ROAMING_TRANSIT, /* ucCID */ -+ TRUE, /* fgSetQuery */ -+ FALSE, /* fgNeedResp */ -+ FALSE, /* fgIsOid */ -+ NULL, /* pfCmdDoneHandler */ -+ NULL, /* pfCmdTimeoutHandler */ -+ sizeof(ROAMING_PARAM_T), /* u4SetQueryInfoLen */ -+ (PUINT_8) prParam, /* pucInfoBuffer */ -+ NULL, /* pvSetQueryBuffer */ -+ 0 /* u4SetQueryBufferLen */ -+ ); -+ -+ ASSERT(rStatus == WLAN_STATUS_PENDING); -+ -+} /* end of roamingFsmSendCmd() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Update the recent time when ScanDone occurred -+* -+* @param [IN P_ADAPTER_T] prAdapter -+* -+* @return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID roamingFsmScanResultsUpdate(IN P_ADAPTER_T prAdapter) -+{ -+ P_ROAMING_INFO_T prRoamingFsmInfo; -+ -+ prRoamingFsmInfo = (P_ROAMING_INFO_T) &(prAdapter->rWifiVar.rRoamingInfo); -+ -+ /* Check Roaming Conditions */ -+ if (!(prRoamingFsmInfo->fgIsEnableRoaming)) -+ return; -+ -+ DBGLOG(ROAMING, LOUD, "->roamingFsmScanResultsUpdate(): Current Time = %u", kalGetTimeTick()); -+ -+ GET_CURRENT_SYSTIME(&prRoamingFsmInfo->rRoamingDiscoveryUpdateTime); -+ -+} /* end of roamingFsmScanResultsUpdate() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief The Core FSM engine of ROAMING for AIS Infra. -+* -+* @param [IN P_ADAPTER_T] prAdapter -+* [IN ENUM_ROAMING_STATE_T] eNextState Enum value of next AIS STATE -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID roamingFsmSteps(IN P_ADAPTER_T prAdapter, IN ENUM_ROAMING_STATE_T eNextState) -+{ -+ P_ROAMING_INFO_T prRoamingFsmInfo; -+ ENUM_ROAMING_STATE_T ePreviousState; -+ BOOLEAN fgIsTransition = (BOOLEAN) FALSE; -+ -+ prRoamingFsmInfo = (P_ROAMING_INFO_T) &(prAdapter->rWifiVar.rRoamingInfo); -+ -+ do { -+ -+ /* Do entering Next State */ -+#if DBG -+ DBGLOG(ROAMING, STATE, "TRANSITION: [%s] -> [%s]\n", -+ apucDebugRoamingState[prRoamingFsmInfo->eCurrentState], -+ apucDebugRoamingState[eNextState]); -+#else -+ DBGLOG(ROAMING, STATE, "[%d] TRANSITION: [%d] -> [%d]\n", -+ DBG_ROAMING_IDX, prRoamingFsmInfo->eCurrentState, eNextState); -+#endif -+ /* NOTE(Kevin): This is the only place to change the eCurrentState(except initial) */ -+ ePreviousState = prRoamingFsmInfo->eCurrentState; -+ prRoamingFsmInfo->eCurrentState = eNextState; -+ -+ fgIsTransition = (BOOLEAN) FALSE; -+ -+ /* Do tasks of the State that we just entered */ -+ switch (prRoamingFsmInfo->eCurrentState) { -+ /* NOTE(Kevin): we don't have to rearrange the sequence of following -+ * switch case. Instead I would like to use a common lookup table of array -+ * of function pointer to speed up state search. -+ */ -+ case ROAMING_STATE_IDLE: -+ case ROAMING_STATE_DECISION: -+ break; -+ -+ case ROAMING_STATE_DISCOVERY: -+ { -+ OS_SYSTIME rCurrentTime; -+ -+ GET_CURRENT_SYSTIME(&rCurrentTime); -+ if (CHECK_FOR_TIMEOUT(rCurrentTime, prRoamingFsmInfo->rRoamingDiscoveryUpdateTime, -+ SEC_TO_SYSTIME(ROAMING_DISCOVERY_TIMEOUT_SEC))) { -+ DBGLOG(ROAMING, LOUD, "roamingFsmSteps: DiscoveryUpdateTime Timeout"); -+ aisFsmRunEventRoamingDiscovery(prAdapter, TRUE); -+ } else { -+ DBGLOG(ROAMING, LOUD, "roamingFsmSteps: DiscoveryUpdateTime Updated"); -+#if CFG_SUPPORT_ROAMING_ENC -+ if (prAdapter->fgIsRoamingEncEnabled == TRUE) -+ aisFsmRunEventRoamingDiscovery(prAdapter, TRUE); -+ else -+#endif /* CFG_SUPPORT_ROAMING_ENC */ -+ aisFsmRunEventRoamingDiscovery(prAdapter, FALSE); -+ } -+ } -+ break; -+ -+ case ROAMING_STATE_ROAM: -+ break; -+ -+ default: -+ ASSERT(0); /* Make sure we have handle all STATEs */ -+ } -+ } while (fgIsTransition); -+ -+ return; -+ -+} /* end of roamingFsmSteps() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Transit to Decision state after join completion -+* -+* @param [IN P_ADAPTER_T] prAdapter -+* -+* @return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID roamingFsmRunEventStart(IN P_ADAPTER_T prAdapter) -+{ -+ P_ROAMING_INFO_T prRoamingFsmInfo; -+ ENUM_ROAMING_STATE_T eNextState; -+ P_BSS_INFO_T prAisBssInfo; -+ ROAMING_PARAM_T rParam; -+ -+ prRoamingFsmInfo = (P_ROAMING_INFO_T) &(prAdapter->rWifiVar.rRoamingInfo); -+ -+ /* Check Roaming Conditions */ -+ if (!(prRoamingFsmInfo->fgIsEnableRoaming)) -+ return; -+ -+ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ if (prAisBssInfo->eCurrentOPMode != OP_MODE_INFRASTRUCTURE) -+ return; -+ -+ DBGLOG(ROAMING, EVENT, "EVENT-ROAMING START: Current Time = %u\n", kalGetTimeTick()); -+ -+ /* IDLE, ROAM -> DECISION */ -+ /* Errors as DECISION, DISCOVERY -> DECISION */ -+ if (!(prRoamingFsmInfo->eCurrentState == ROAMING_STATE_IDLE || -+ prRoamingFsmInfo->eCurrentState == ROAMING_STATE_ROAM)) -+ return; -+ -+ eNextState = ROAMING_STATE_DECISION; -+ if (eNextState != prRoamingFsmInfo->eCurrentState) { -+ rParam.u2Event = ROAMING_EVENT_START; -+ roamingFsmSendCmd(prAdapter, (P_ROAMING_PARAM_T) & rParam); -+ -+ /* Step to next state */ -+ roamingFsmSteps(prAdapter, eNextState); -+ } -+ -+} /* end of roamingFsmRunEventStart() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Transit to Discovery state when deciding to find a candidate -+* -+* @param [IN P_ADAPTER_T] prAdapter -+* -+* @return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID roamingFsmRunEventDiscovery(IN P_ADAPTER_T prAdapter, IN P_ROAMING_PARAM_T prParam) -+{ -+ P_ROAMING_INFO_T prRoamingFsmInfo; -+ ENUM_ROAMING_STATE_T eNextState; -+ -+ prRoamingFsmInfo = (P_ROAMING_INFO_T) &(prAdapter->rWifiVar.rRoamingInfo); -+ -+ /* Check Roaming Conditions */ -+ if (!(prRoamingFsmInfo->fgIsEnableRoaming)) -+ return; -+ -+ DBGLOG(ROAMING, EVENT, "EVENT-ROAMING DISCOVERY: Current Time = %u Reason = %u\n", -+ kalGetTimeTick(), prParam->u2Reason); -+ -+ /* DECISION -> DISCOVERY */ -+ /* Errors as IDLE, DISCOVERY, ROAM -> DISCOVERY */ -+ if (prRoamingFsmInfo->eCurrentState != ROAMING_STATE_DECISION) -+ return; -+#if CFG_SUPPORT_ROAMING_ENC -+ prRoamingFsmInfo->RoamingEntryTimeoutSkipCount = 0; -+#endif -+ -+ eNextState = ROAMING_STATE_DISCOVERY; -+ /* DECISION -> DISCOVERY */ -+ if (eNextState != prRoamingFsmInfo->eCurrentState) { -+ P_BSS_INFO_T prAisBssInfo; -+ P_BSS_DESC_T prBssDesc; -+ -+ /* sync. rcpi with firmware */ -+ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ prBssDesc = scanSearchBssDescByBssid(prAdapter, prAisBssInfo->aucBSSID); -+ if (prBssDesc) -+ prBssDesc->ucRCPI = (UINT_8) (prParam->u2Data & 0xff); -+ -+ roamingFsmSteps(prAdapter, eNextState); -+ } -+ -+} /* end of roamingFsmRunEventDiscovery() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Transit to Roam state after Scan Done -+* -+* @param [IN P_ADAPTER_T] prAdapter -+* -+* @return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID roamingFsmRunEventRoam(IN P_ADAPTER_T prAdapter) -+{ -+ P_ROAMING_INFO_T prRoamingFsmInfo; -+ ENUM_ROAMING_STATE_T eNextState; -+ ROAMING_PARAM_T rParam; -+ -+ prRoamingFsmInfo = (P_ROAMING_INFO_T) &(prAdapter->rWifiVar.rRoamingInfo); -+ -+ /* Check Roaming Conditions */ -+ if (!(prRoamingFsmInfo->fgIsEnableRoaming)) -+ return; -+ -+ DBGLOG(ROAMING, EVENT, "EVENT-ROAMING ROAM: Current Time = %u\n", kalGetTimeTick()); -+ -+ /* IDLE, ROAM -> DECISION */ -+ /* Errors as IDLE, DECISION, ROAM -> ROAM */ -+ if (prRoamingFsmInfo->eCurrentState != ROAMING_STATE_DISCOVERY) -+ return; -+ -+ eNextState = ROAMING_STATE_ROAM; -+ /* DISCOVERY -> ROAM */ -+ if (eNextState != prRoamingFsmInfo->eCurrentState) { -+ rParam.u2Event = ROAMING_EVENT_ROAM; -+ roamingFsmSendCmd(prAdapter, (P_ROAMING_PARAM_T) & rParam); -+ -+ /* Step to next state */ -+ roamingFsmSteps(prAdapter, eNextState); -+ } -+ -+} /* end of roamingFsmRunEventRoam() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Transit to Decision state as being failed to find out any candidate -+* -+* @param [IN P_ADAPTER_T] prAdapter -+* -+* @return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID roamingFsmRunEventFail(IN P_ADAPTER_T prAdapter, IN UINT_32 u4Param) -+{ -+ P_ROAMING_INFO_T prRoamingFsmInfo; -+ ENUM_ROAMING_STATE_T eNextState; -+ ROAMING_PARAM_T rParam; -+ -+ prRoamingFsmInfo = (P_ROAMING_INFO_T) &(prAdapter->rWifiVar.rRoamingInfo); -+ -+ /* Check Roaming Conditions */ -+ if (!(prRoamingFsmInfo->fgIsEnableRoaming)) -+ return; -+ -+ DBGLOG(ROAMING, EVENT, "EVENT-ROAMING FAIL: reason %x Current Time = %u\n", u4Param, kalGetTimeTick()); -+ -+ /* IDLE, ROAM -> DECISION */ -+ /* Errors as IDLE, DECISION, DISCOVERY -> DECISION */ -+ if (prRoamingFsmInfo->eCurrentState != ROAMING_STATE_ROAM) -+ return; -+ -+ eNextState = ROAMING_STATE_DECISION; -+ /* ROAM -> DECISION */ -+ if (eNextState != prRoamingFsmInfo->eCurrentState) { -+ rParam.u2Event = ROAMING_EVENT_FAIL; -+ rParam.u2Data = (UINT_16) (u4Param & 0xffff); -+ roamingFsmSendCmd(prAdapter, (P_ROAMING_PARAM_T) & rParam); -+ -+ /* Step to next state */ -+ roamingFsmSteps(prAdapter, eNextState); -+ } -+ -+} /* end of roamingFsmRunEventFail() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Transit to Idle state as beging aborted by other moduels, AIS -+* -+* @param [IN P_ADAPTER_T] prAdapter -+* -+* @return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID roamingFsmRunEventAbort(IN P_ADAPTER_T prAdapter) -+{ -+ P_ROAMING_INFO_T prRoamingFsmInfo; -+ ENUM_ROAMING_STATE_T eNextState; -+ ROAMING_PARAM_T rParam; -+ -+ prRoamingFsmInfo = (P_ROAMING_INFO_T) &(prAdapter->rWifiVar.rRoamingInfo); -+ -+ if (!(prRoamingFsmInfo->fgIsEnableRoaming)) -+ return; -+ -+ DBGLOG(ROAMING, EVENT, "EVENT-ROAMING ABORT: Current Time = %u\n", kalGetTimeTick()); -+ -+ eNextState = ROAMING_STATE_IDLE; -+ /* IDLE, DECISION, DISCOVERY, ROAM -> IDLE */ -+ if (eNextState != prRoamingFsmInfo->eCurrentState) { -+ rParam.u2Event = ROAMING_EVENT_ABORT; -+ roamingFsmSendCmd(prAdapter, (P_ROAMING_PARAM_T) & rParam); -+ -+ /* Step to next state */ -+ roamingFsmSteps(prAdapter, eNextState); -+ } -+ -+} /* end of roamingFsmRunEventAbort() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Process events from firmware -+* -+* @param [IN P_ADAPTER_T] prAdapter -+* [IN P_ROAMING_PARAM_T] prParam -+* -+* @return none -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS roamingFsmProcessEvent(IN P_ADAPTER_T prAdapter, IN P_ROAMING_PARAM_T prParam) -+{ -+ DBGLOG(ROAMING, LOUD, "ROAMING Process Events: Current Time = %u\n", kalGetTimeTick()); -+ -+ if (ROAMING_EVENT_DISCOVERY == prParam->u2Event) -+ roamingFsmRunEventDiscovery(prAdapter, prParam); -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+#endif -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rsn.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rsn.c -new file mode 100644 -index 000000000000..eedd8d12f2fd ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/rsn.c -@@ -0,0 +1,2533 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/rsn.c#2 -+*/ -+ -+/*! \file "rsn.c" -+ \brief This file including the 802.11i, wpa and wpa2(rsn) related function. -+ -+ This file provided the macros and functions library support the wpa/rsn ie parsing, -+ cipher and AKM check to help the AP seleced deciding, tkip mic error handler and rsn PMKID support. -+*/ -+ -+/* -+** Log: rsn.c -+ * -+ * 07 17 2012 yuche.tsai -+ * NULL -+ * Compile no error before trial run. -+ * -+ * 03 09 2012 chinglan.wang -+ * NULL -+ * Fix the condition error. -+ * -+ * 03 02 2012 terry.wu -+ * NULL -+ * Snc CFG80211 modification for ICS migration from branch 2.2. -+ * -+ * 03 02 2012 terry.wu -+ * NULL -+ * Sync CFG80211 modification from branch 2,2. -+ * -+ * 11 11 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * modify the xlog related code. -+ * -+ * 11 10 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * change the debug module level. -+ * -+ * 10 12 2011 wh.su -+ * [WCXRP00001036] [MT6620 Wi-Fi][Driver][FW] Adding the 802.11w code for MFP -+ * adding the 802.11w related function and define . -+ * -+ * 03 17 2011 chinglan.wang -+ * [WCXRP00000570] [MT6620 Wi-Fi][Driver] Add Wi-Fi Protected Setup v2.0 feature -+ * . -+ * -+ * 02 09 2011 wh.su -+ * [WCXRP00000432] [MT6620 Wi-Fi][Driver] Add STA privacy check at hotspot mode -+ * adding the code for check STA privacy bit at AP mode, . -+ * -+ * 12 24 2010 chinglan.wang -+ * NULL -+ * [MT6620][Wi-Fi] Modify the key management in the driver for WPS function. -+ * -+ * 12 13 2010 cp.wu -+ * [WCXRP00000260] [MT6620 Wi-Fi][Driver][Firmware] Create V1.1 branch for both firmware and driver -+ * create branch for Wi-Fi driver v1.1 -+ * -+ * 11 05 2010 wh.su -+ * [WCXRP00000165] [MT6620 Wi-Fi] [Pre-authentication] Assoc req rsn ie use wrong pmkid value -+ * fixed the.pmkid value mismatch issue -+ * -+ * 11 03 2010 wh.su -+ * [WCXRP00000124] [MT6620 Wi-Fi] [Driver] Support the dissolve P2P Group -+ * Refine the HT rate disallow TKIP pairwise cipher . -+ * -+ * 10 04 2010 cp.wu -+ * [WCXRP00000077] [MT6620 Wi-Fi][Driver][FW] Eliminate use of ENUM_NETWORK_TYPE_T -+ * and replaced by ENUM_NETWORK_TYPE_INDEX_T only -+ * remove ENUM_NETWORK_TYPE_T definitions -+ * -+ * 09 29 2010 yuche.tsai -+ * NULL -+ * Fix compile error, remove unused pointer in rsnGenerateRSNIE(). -+ * -+ * 09 28 2010 wh.su -+ * NULL -+ * [WCXRP00000069][MT6620 Wi-Fi][Driver] Fix some code for phase 1 P2P Demo. -+ * -+ * 09 24 2010 wh.su -+ * NULL -+ * [WCXRP00005002][MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning. -+ * -+ * 09 06 2010 wh.su -+ * NULL -+ * let the p2p can set the privacy bit at beacon and rsn ie at assoc req at key handshake state. -+ * -+ * 08 30 2010 wh.su -+ * NULL -+ * remove non-used code. -+ * -+ * 08 19 2010 wh.su -+ * NULL -+ * adding the tx pkt call back handle for countermeasure. -+ * -+ * 07 24 2010 wh.su -+ * -+ * .support the Wi-Fi RSN -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 21 2010 wh.su -+ * [WPD00003840][MT6620 5931] Security migration -+ * modify some code for concurrent network. -+ * -+ * 06 21 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * enable RX management frame handling. -+ * -+ * 06 19 2010 wh.su -+ * [WPD00003840][MT6620 5931] Security migration -+ * consdier the concurrent network setting. -+ * -+ * 06 18 2010 wh.su -+ * [WPD00003840][MT6620 5931] Security migration -+ * [WPD00003840] [MT6620 5931] Security migration -+ * migration from firmware. -+ * -+ * 05 27 2010 wh.su -+ * [BORA00000637][MT6620 Wi-Fi] [Bug] WPA2 pre-authentication timer not correctly initialize -+ * not indicate pmkid candidate while no new one scanned. -+ * -+ * 04 29 2010 wh.su -+ * [BORA00000637][MT6620 Wi-Fi] [Bug] WPA2 pre-authentication timer not correctly initialize -+ * adjsut the pre-authentication code. -+ * -+ * 03 03 2010 wh.su -+ * [BORA00000637][MT6620 Wi-Fi] [Bug] WPA2 pre-authentication timer not correctly initialize -+ * move the AIS specific variable for security to AIS specific structure. -+ * -+ * 03 03 2010 wh.su -+ * [BORA00000637][MT6620 Wi-Fi] [Bug] WPA2 pre-authentication timer not correctly initialize -+ * Fixed the pre-authentication timer not correctly init issue, -+ * and modify the security related callback function prototype. -+ * -+ * 01 27 2010 wh.su -+ * [BORA00000476][Wi-Fi][firmware] Add the security module initialize code -+ * add and fixed some security function. -+ * -+ * 12 18 2009 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * . -+ * -+ * Dec 8 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * change the name -+ * -+ * Dec 7 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * using the Rx0 port to indicate event -+ * -+ * Dec 4 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * refine the code for generate the WPA/RSN IE for assoc req -+ * -+ * Dec 3 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * adjust code for pmkid event -+ * -+ * Dec 1 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * adding the code for event (mic error and pmkid indicate) and do some function rename -+ * -+ * Nov 23 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * adding some security function -+ * -+ * Nov 19 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * adding some security feature, including pmkid -+ * -+ * Nov 18 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * -+** -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "precomp.h" -+ -+#if CFG_RSN_MIGRATION -+ -+/* extern PHY_ATTRIBUTE_T rPhyAttributes[]; */ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to parse RSN IE. -+* -+* \param[in] prInfoElem Pointer to the RSN IE -+* \param[out] prRsnInfo Pointer to the BSSDescription structure to store the -+** RSN information from the given RSN IE -+* -+* \retval TRUE - Succeeded -+* \retval FALSE - Failed -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN rsnParseRsnIE(IN P_ADAPTER_T prAdapter, IN P_RSN_INFO_ELEM_T prInfoElem, OUT P_RSN_INFO_T prRsnInfo) -+{ -+ UINT_32 i; -+ INT_32 u4RemainRsnIeLen; -+ UINT_16 u2Version; -+ UINT_16 u2Cap = 0; -+ UINT_32 u4GroupSuite = RSN_CIPHER_SUITE_CCMP; -+ UINT_16 u2PairSuiteCount = 0; -+ UINT_16 u2AuthSuiteCount = 0; -+ PUINT_8 pucPairSuite = NULL; -+ PUINT_8 pucAuthSuite = NULL; -+ PUINT_8 cp; -+ -+ DEBUGFUNC("rsnParseRsnIE"); -+ -+ ASSERT(prInfoElem); -+ ASSERT(prRsnInfo); -+ -+ /* Verify the length of the RSN IE. */ -+ if (prInfoElem->ucLength < 2) { -+ DBGLOG(RSN, TRACE, "RSN IE length too short (length=%d)\n", prInfoElem->ucLength); -+ return FALSE; -+ } -+ -+ /* Check RSN version: currently, we only support version 1. */ -+ WLAN_GET_FIELD_16(&prInfoElem->u2Version, &u2Version); -+ if (u2Version != 1) { -+ DBGLOG(RSN, TRACE, "Unsupported RSN IE version: %d\n", u2Version); -+ return FALSE; -+ } -+ -+ cp = (PUCHAR) & prInfoElem->u4GroupKeyCipherSuite; -+ u4RemainRsnIeLen = (INT_32) prInfoElem->ucLength - 2; -+ -+ do { -+ if (u4RemainRsnIeLen == 0) -+ break; -+ -+ /* Parse the Group Key Cipher Suite field. */ -+ if (u4RemainRsnIeLen < 4) { -+ DBGLOG(RSN, TRACE, "Fail to parse RSN IE in group cipher suite (IE len: %d)\n", -+ prInfoElem->ucLength); -+ return FALSE; -+ } -+ -+ WLAN_GET_FIELD_32(cp, &u4GroupSuite); -+ cp += 4; -+ u4RemainRsnIeLen -= 4; -+ -+ if (u4RemainRsnIeLen == 0) -+ break; -+ -+ /* Parse the Pairwise Key Cipher Suite Count field. */ -+ if (u4RemainRsnIeLen < 2) { -+ DBGLOG(RSN, TRACE, "Fail to parse RSN IE in pairwise cipher suite count (IE len: %d)\n", -+ prInfoElem->ucLength); -+ return FALSE; -+ } -+ -+ WLAN_GET_FIELD_16(cp, &u2PairSuiteCount); -+ cp += 2; -+ u4RemainRsnIeLen -= 2; -+ -+ /* Parse the Pairwise Key Cipher Suite List field. */ -+ i = (UINT_32) u2PairSuiteCount * 4; -+ if (u4RemainRsnIeLen < (INT_32) i) { -+ DBGLOG(RSN, TRACE, "Fail to parse RSN IE in pairwise cipher suite list (IE len: %d)\n", -+ prInfoElem->ucLength); -+ return FALSE; -+ } -+ -+ pucPairSuite = cp; -+ -+ cp += i; -+ u4RemainRsnIeLen -= (INT_32) i; -+ -+ if (u4RemainRsnIeLen == 0) -+ break; -+ -+ /* Parse the Authentication and Key Management Cipher Suite Count field. */ -+ if (u4RemainRsnIeLen < 2) { -+ DBGLOG(RSN, TRACE, "Fail to parse RSN IE in auth & key mgt suite count (IE len: %d)\n", -+ prInfoElem->ucLength); -+ return FALSE; -+ } -+ -+ WLAN_GET_FIELD_16(cp, &u2AuthSuiteCount); -+ cp += 2; -+ u4RemainRsnIeLen -= 2; -+ -+ /* Parse the Authentication and Key Management Cipher Suite List -+ field. */ -+ i = (UINT_32) u2AuthSuiteCount * 4; -+ if (u4RemainRsnIeLen < (INT_32) i) { -+ DBGLOG(RSN, TRACE, "Fail to parse RSN IE in auth & key mgt suite list (IE len: %d)\n", -+ prInfoElem->ucLength); -+ return FALSE; -+ } -+ -+ pucAuthSuite = cp; -+ -+ cp += i; -+ u4RemainRsnIeLen -= (INT_32) i; -+ -+ if (u4RemainRsnIeLen == 0) -+ break; -+ -+ /* Parse the RSN u2Capabilities field. */ -+ if (u4RemainRsnIeLen < 2) { -+ DBGLOG(RSN, TRACE, "Fail to parse RSN IE in RSN capabilities (IE len: %d)\n", -+ prInfoElem->ucLength); -+ return FALSE; -+ } -+ -+ WLAN_GET_FIELD_16(cp, &u2Cap); -+ } while (FALSE); -+ -+ /* Save the RSN information for the BSS. */ -+ prRsnInfo->ucElemId = ELEM_ID_RSN; -+ -+ prRsnInfo->u2Version = u2Version; -+ -+ prRsnInfo->u4GroupKeyCipherSuite = u4GroupSuite; -+ -+ DBGLOG(RSN, LOUD, "RSN: version %d, group key cipher suite %02x-%02x-%02x-%02x\n", -+ u2Version, (UCHAR) (u4GroupSuite & 0x000000FF), -+ (UCHAR) ((u4GroupSuite >> 8) & 0x000000FF), -+ (UCHAR) ((u4GroupSuite >> 16) & 0x000000FF), (UCHAR) ((u4GroupSuite >> 24) & 0x000000FF)); -+ -+ if (pucPairSuite) { -+ /* The information about the pairwise key cipher suites is present. */ -+ if (u2PairSuiteCount > MAX_NUM_SUPPORTED_CIPHER_SUITES) -+ u2PairSuiteCount = MAX_NUM_SUPPORTED_CIPHER_SUITES; -+ -+ prRsnInfo->u4PairwiseKeyCipherSuiteCount = (UINT_32) u2PairSuiteCount; -+ -+ for (i = 0; i < (UINT_32) u2PairSuiteCount; i++) { -+ WLAN_GET_FIELD_32(pucPairSuite, &prRsnInfo->au4PairwiseKeyCipherSuite[i]); -+ pucPairSuite += 4; -+ -+ DBGLOG(RSN, LOUD, "RSN: pairwise key cipher suite [%d]: %02x-%02x-%02x-%02x\n", -+ (UINT_8) i, (UCHAR) (prRsnInfo->au4PairwiseKeyCipherSuite[i] & 0x000000FF), -+ (UCHAR) ((prRsnInfo->au4PairwiseKeyCipherSuite[i] >> 8) & 0x000000FF), -+ (UCHAR) ((prRsnInfo->au4PairwiseKeyCipherSuite[i] >> 16) & 0x000000FF), -+ (UCHAR) ((prRsnInfo->au4PairwiseKeyCipherSuite[i] >> 24) & 0x000000FF)); -+ } -+ } else { -+ /* The information about the pairwise key cipher suites is not present. -+ Use the default chipher suite for RSN: CCMP. */ -+ prRsnInfo->u4PairwiseKeyCipherSuiteCount = 1; -+ prRsnInfo->au4PairwiseKeyCipherSuite[0] = RSN_CIPHER_SUITE_CCMP; -+ -+ DBGLOG(RSN, LOUD, "RSN: pairwise key cipher suite: %02x-%02x-%02x-%02x (default)\n", -+ (UCHAR) (prRsnInfo->au4PairwiseKeyCipherSuite[0] & 0x000000FF), -+ (UCHAR) ((prRsnInfo->au4PairwiseKeyCipherSuite[0] >> 8) & 0x000000FF), -+ (UCHAR) ((prRsnInfo->au4PairwiseKeyCipherSuite[0] >> 16) & 0x000000FF), -+ (UCHAR) ((prRsnInfo->au4PairwiseKeyCipherSuite[0] >> 24) & 0x000000FF)); -+ } -+ -+ if (pucAuthSuite) { -+ /* The information about the authentication and key management suites -+ is present. */ -+ if (u2AuthSuiteCount > MAX_NUM_SUPPORTED_AKM_SUITES) -+ u2AuthSuiteCount = MAX_NUM_SUPPORTED_AKM_SUITES; -+ -+ prRsnInfo->u4AuthKeyMgtSuiteCount = (UINT_32) u2AuthSuiteCount; -+ -+ for (i = 0; i < (UINT_32) u2AuthSuiteCount; i++) { -+ WLAN_GET_FIELD_32(pucAuthSuite, &prRsnInfo->au4AuthKeyMgtSuite[i]); -+ pucAuthSuite += 4; -+ -+ DBGLOG(RSN, LOUD, "RSN: AKM suite [%d]: %02x-%02x-%02x-%02x\n", -+ (UINT_8) i, (UCHAR) (prRsnInfo->au4AuthKeyMgtSuite[i] & 0x000000FF), -+ (UCHAR) ((prRsnInfo->au4AuthKeyMgtSuite[i] >> 8) & 0x000000FF), -+ (UCHAR) ((prRsnInfo->au4AuthKeyMgtSuite[i] >> 16) & 0x000000FF), -+ (UCHAR) ((prRsnInfo->au4AuthKeyMgtSuite[i] >> 24) & 0x000000FF)); -+ } -+ } else { -+ /* The information about the authentication and key management suites -+ is not present. Use the default AKM suite for RSN. */ -+ prRsnInfo->u4AuthKeyMgtSuiteCount = 1; -+ prRsnInfo->au4AuthKeyMgtSuite[0] = RSN_AKM_SUITE_802_1X; -+ -+ DBGLOG(RSN, LOUD, "RSN: AKM suite: %02x-%02x-%02x-%02x (default)\n", -+ (UCHAR) (prRsnInfo->au4AuthKeyMgtSuite[0] & 0x000000FF), -+ (UCHAR) ((prRsnInfo->au4AuthKeyMgtSuite[0] >> 8) & 0x000000FF), -+ (UCHAR) ((prRsnInfo->au4AuthKeyMgtSuite[0] >> 16) & 0x000000FF), -+ (UCHAR) ((prRsnInfo->au4AuthKeyMgtSuite[0] >> 24) & 0x000000FF)); -+ } -+ -+ prRsnInfo->u2RsnCap = u2Cap; -+#if CFG_SUPPORT_802_11W -+ prRsnInfo->fgRsnCapPresent = TRUE; -+#endif -+ DBGLOG(RSN, LOUD, "RSN cap: 0x%04x\n", prRsnInfo->u2RsnCap); -+ -+ return TRUE; -+} /* rsnParseRsnIE */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to parse WPA IE. -+* -+* \param[in] prInfoElem Pointer to the WPA IE. -+* \param[out] prWpaInfo Pointer to the BSSDescription structure to store the -+* WPA information from the given WPA IE. -+* -+* \retval TRUE Succeeded. -+* \retval FALSE Failed. -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN rsnParseWpaIE(IN P_ADAPTER_T prAdapter, IN P_WPA_INFO_ELEM_T prInfoElem, OUT P_RSN_INFO_T prWpaInfo) -+{ -+ UINT_32 i; -+ INT_32 u4RemainWpaIeLen; -+ UINT_16 u2Version; -+ UINT_16 u2Cap = 0; -+ UINT_32 u4GroupSuite = WPA_CIPHER_SUITE_TKIP; -+ UINT_16 u2PairSuiteCount = 0; -+ UINT_16 u2AuthSuiteCount = 0; -+ PUCHAR pucPairSuite = NULL; -+ PUCHAR pucAuthSuite = NULL; -+ PUCHAR cp; -+ BOOLEAN fgCapPresent = FALSE; -+ -+ DEBUGFUNC("rsnParseWpaIE"); -+ -+ ASSERT(prInfoElem); -+ ASSERT(prWpaInfo); -+ -+ /* Verify the length of the WPA IE. */ -+ if (prInfoElem->ucLength < 6) { -+ DBGLOG(RSN, TRACE, "WPA IE length too short (length=%d)\n", prInfoElem->ucLength); -+ return FALSE; -+ } -+ -+ /* Check WPA version: currently, we only support version 1. */ -+ WLAN_GET_FIELD_16(&prInfoElem->u2Version, &u2Version); -+ if (u2Version != 1) { -+ DBGLOG(RSN, TRACE, "Unsupported WPA IE version: %d\n", u2Version); -+ return FALSE; -+ } -+ -+ cp = (PUCHAR) &prInfoElem->u4GroupKeyCipherSuite; -+ u4RemainWpaIeLen = (INT_32) prInfoElem->ucLength - 6; -+ -+ do { -+ if (u4RemainWpaIeLen == 0) -+ break; -+ -+ /* WPA_OUI : 4 -+ Version : 2 -+ GroupSuite : 4 -+ PairwiseCount: 2 -+ PairwiseSuite: 4 * pairSuiteCount -+ AuthCount : 2 -+ AuthSuite : 4 * authSuiteCount -+ Cap : 2 */ -+ -+ /* Parse the Group Key Cipher Suite field. */ -+ if (u4RemainWpaIeLen < 4) { -+ DBGLOG(RSN, TRACE, "Fail to parse WPA IE in group cipher suite (IE len: %d)\n", -+ prInfoElem->ucLength); -+ return FALSE; -+ } -+ -+ WLAN_GET_FIELD_32(cp, &u4GroupSuite); -+ cp += 4; -+ u4RemainWpaIeLen -= 4; -+ -+ if (u4RemainWpaIeLen == 0) -+ break; -+ -+ /* Parse the Pairwise Key Cipher Suite Count field. */ -+ if (u4RemainWpaIeLen < 2) { -+ DBGLOG(RSN, TRACE, "Fail to parse WPA IE in pairwise cipher suite count (IE len: %d)\n", -+ prInfoElem->ucLength); -+ return FALSE; -+ } -+ -+ WLAN_GET_FIELD_16(cp, &u2PairSuiteCount); -+ cp += 2; -+ u4RemainWpaIeLen -= 2; -+ -+ /* Parse the Pairwise Key Cipher Suite List field. */ -+ i = (UINT_32) u2PairSuiteCount * 4; -+ if (u4RemainWpaIeLen < (INT_32) i) { -+ DBGLOG(RSN, TRACE, "Fail to parse WPA IE in pairwise cipher suite list (IE len: %d)\n", -+ prInfoElem->ucLength); -+ return FALSE; -+ } -+ -+ pucPairSuite = cp; -+ -+ cp += i; -+ u4RemainWpaIeLen -= (INT_32) i; -+ -+ if (u4RemainWpaIeLen == 0) -+ break; -+ -+ /* Parse the Authentication and Key Management Cipher Suite Count -+ field. */ -+ if (u4RemainWpaIeLen < 2) { -+ DBGLOG(RSN, TRACE, "Fail to parse WPA IE in auth & key mgt suite count (IE len: %d)\n", -+ prInfoElem->ucLength); -+ return FALSE; -+ } -+ -+ WLAN_GET_FIELD_16(cp, &u2AuthSuiteCount); -+ cp += 2; -+ u4RemainWpaIeLen -= 2; -+ -+ /* Parse the Authentication and Key Management Cipher Suite List -+ field. */ -+ i = (UINT_32) u2AuthSuiteCount * 4; -+ if (u4RemainWpaIeLen < (INT_32) i) { -+ DBGLOG(RSN, TRACE, "Fail to parse WPA IE in auth & key mgt suite list (IE len: %d)\n", -+ prInfoElem->ucLength); -+ return FALSE; -+ } -+ -+ pucAuthSuite = cp; -+ -+ cp += i; -+ u4RemainWpaIeLen -= (INT_32) i; -+ -+ if (u4RemainWpaIeLen == 0) -+ break; -+ -+ /* Parse the WPA u2Capabilities field. */ -+ if (u4RemainWpaIeLen < 2) { -+ DBGLOG(RSN, TRACE, "Fail to parse WPA IE in WPA capabilities (IE len: %d)\n", -+ prInfoElem->ucLength); -+ return FALSE; -+ } -+ -+ fgCapPresent = TRUE; -+ WLAN_GET_FIELD_16(cp, &u2Cap); -+ u4RemainWpaIeLen -= 2; -+ } while (FALSE); -+ -+ /* Save the WPA information for the BSS. */ -+ -+ prWpaInfo->ucElemId = ELEM_ID_WPA; -+ -+ prWpaInfo->u2Version = u2Version; -+ -+ prWpaInfo->u4GroupKeyCipherSuite = u4GroupSuite; -+ -+ DBGLOG(RSN, LOUD, "WPA: version %d, group key cipher suite %02x-%02x-%02x-%02x\n", -+ u2Version, (UCHAR) (u4GroupSuite & 0x000000FF), -+ (UCHAR) ((u4GroupSuite >> 8) & 0x000000FF), -+ (UCHAR) ((u4GroupSuite >> 16) & 0x000000FF), (UCHAR) ((u4GroupSuite >> 24) & 0x000000FF)); -+ -+ if (pucPairSuite) { -+ /* The information about the pairwise key cipher suites is present. */ -+ if (u2PairSuiteCount > MAX_NUM_SUPPORTED_CIPHER_SUITES) -+ u2PairSuiteCount = MAX_NUM_SUPPORTED_CIPHER_SUITES; -+ -+ prWpaInfo->u4PairwiseKeyCipherSuiteCount = (UINT_32) u2PairSuiteCount; -+ -+ for (i = 0; i < (UINT_32) u2PairSuiteCount; i++) { -+ WLAN_GET_FIELD_32(pucPairSuite, &prWpaInfo->au4PairwiseKeyCipherSuite[i]); -+ pucPairSuite += 4; -+ -+ DBGLOG(RSN, LOUD, "WPA: pairwise key cipher suite [%d]: %02x-%02x-%02x-%02x\n", -+ (UINT_8) i, (UCHAR) (prWpaInfo->au4PairwiseKeyCipherSuite[i] & 0x000000FF), -+ (UCHAR) ((prWpaInfo->au4PairwiseKeyCipherSuite[i] >> 8) & 0x000000FF), -+ (UCHAR) ((prWpaInfo->au4PairwiseKeyCipherSuite[i] >> 16) & 0x000000FF), -+ (UCHAR) ((prWpaInfo->au4PairwiseKeyCipherSuite[i] >> 24) & 0x000000FF)); -+ } -+ } else { -+ /* The information about the pairwise key cipher suites is not present. -+ Use the default chipher suite for WPA: TKIP. */ -+ prWpaInfo->u4PairwiseKeyCipherSuiteCount = 1; -+ prWpaInfo->au4PairwiseKeyCipherSuite[0] = WPA_CIPHER_SUITE_TKIP; -+ -+ DBGLOG(RSN, LOUD, "WPA: pairwise key cipher suite: %02x-%02x-%02x-%02x (default)\n", -+ (UCHAR) (prWpaInfo->au4PairwiseKeyCipherSuite[0] & 0x000000FF), -+ (UCHAR) ((prWpaInfo->au4PairwiseKeyCipherSuite[0] >> 8) & 0x000000FF), -+ (UCHAR) ((prWpaInfo->au4PairwiseKeyCipherSuite[0] >> 16) & 0x000000FF), -+ (UCHAR) ((prWpaInfo->au4PairwiseKeyCipherSuite[0] >> 24) & 0x000000FF)); -+ } -+ -+ if (pucAuthSuite) { -+ /* The information about the authentication and key management suites -+ is present. */ -+ if (u2AuthSuiteCount > MAX_NUM_SUPPORTED_AKM_SUITES) -+ u2AuthSuiteCount = MAX_NUM_SUPPORTED_AKM_SUITES; -+ -+ prWpaInfo->u4AuthKeyMgtSuiteCount = (UINT_32) u2AuthSuiteCount; -+ -+ for (i = 0; i < (UINT_32) u2AuthSuiteCount; i++) { -+ WLAN_GET_FIELD_32(pucAuthSuite, &prWpaInfo->au4AuthKeyMgtSuite[i]); -+ pucAuthSuite += 4; -+ -+ DBGLOG(RSN, LOUD, "WPA: AKM suite [%d]: %02x-%02x-%02x-%02x\n", -+ (UINT_8) i, (UCHAR) (prWpaInfo->au4AuthKeyMgtSuite[i] & 0x000000FF), -+ (UCHAR) ((prWpaInfo->au4AuthKeyMgtSuite[i] >> 8) & 0x000000FF), -+ (UCHAR) ((prWpaInfo->au4AuthKeyMgtSuite[i] >> 16) & 0x000000FF), -+ (UCHAR) ((prWpaInfo->au4AuthKeyMgtSuite[i] >> 24) & 0x000000FF)); -+ } -+ } else { -+ /* The information about the authentication and key management suites -+ is not present. Use the default AKM suite for WPA. */ -+ prWpaInfo->u4AuthKeyMgtSuiteCount = 1; -+ prWpaInfo->au4AuthKeyMgtSuite[0] = WPA_AKM_SUITE_802_1X; -+ -+ DBGLOG(RSN, LOUD, "WPA: AKM suite: %02x-%02x-%02x-%02x (default)\n", -+ (UCHAR) (prWpaInfo->au4AuthKeyMgtSuite[0] & 0x000000FF), -+ (UCHAR) ((prWpaInfo->au4AuthKeyMgtSuite[0] >> 8) & 0x000000FF), -+ (UCHAR) ((prWpaInfo->au4AuthKeyMgtSuite[0] >> 16) & 0x000000FF), -+ (UCHAR) ((prWpaInfo->au4AuthKeyMgtSuite[0] >> 24) & 0x000000FF)); -+ } -+ -+ if (fgCapPresent) { -+ prWpaInfo->fgRsnCapPresent = TRUE; -+ prWpaInfo->u2RsnCap = u2Cap; -+ DBGLOG(RSN, LOUD, "WPA: RSN cap: 0x%04x\n", prWpaInfo->u2RsnCap); -+ } else { -+ prWpaInfo->fgRsnCapPresent = FALSE; -+ prWpaInfo->u2RsnCap = 0; -+ } -+ -+ return TRUE; -+} /* rsnParseWpaIE */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to search the desired pairwise -+* cipher suite from the MIB Pairwise Cipher Suite -+* configuration table. -+* -+* \param[in] u4Cipher The desired pairwise cipher suite to be searched -+* \param[out] pu4Index Pointer to the index of the desired pairwise cipher in -+* the table -+* -+* \retval TRUE - The desired pairwise cipher suite is found in the table. -+* \retval FALSE - The desired pairwise cipher suite is not found in the -+* table. -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN rsnSearchSupportedCipher(IN P_ADAPTER_T prAdapter, IN UINT_32 u4Cipher, OUT PUINT_32 pu4Index) -+{ -+ UINT_8 i; -+ P_DOT11_RSNA_CONFIG_PAIRWISE_CIPHERS_ENTRY prEntry; -+ -+ DEBUGFUNC("rsnSearchSupportedCipher"); -+ -+ ASSERT(pu4Index); -+ -+ for (i = 0; i < MAX_NUM_SUPPORTED_CIPHER_SUITES; i++) { -+ prEntry = &prAdapter->rMib.dot11RSNAConfigPairwiseCiphersTable[i]; -+ if (prEntry->dot11RSNAConfigPairwiseCipher == u4Cipher && -+ prEntry->dot11RSNAConfigPairwiseCipherEnabled) { -+ *pu4Index = i; -+ return TRUE; -+ } -+ } -+ return FALSE; -+} /* rsnSearchSupportedCipher */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Whether BSS RSN is matched from upper layer set. -+* -+* \param[in] prAdapter Pointer to the Adapter structure, BSS RSN Information -+* -+* \retval BOOLEAN -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN rsnIsSuitableBSS(IN P_ADAPTER_T prAdapter, IN P_RSN_INFO_T prBssRsnInfo) -+{ -+ UINT_8 i = 0; -+ -+ DEBUGFUNC("rsnIsSuitableBSS"); -+ -+ do { -+ -+ if ((prAdapter->rWifiVar.rConnSettings.rRsnInfo.u4GroupKeyCipherSuite & 0x000000FF) != -+ GET_SELECTOR_TYPE(prBssRsnInfo->u4GroupKeyCipherSuite)) { -+ DBGLOG(RSN, TRACE, "Break by GroupKeyCipherSuite\n"); -+ break; -+ } -+ for (i = 0; i < prBssRsnInfo->u4PairwiseKeyCipherSuiteCount; i++) { -+ if (((prAdapter->rWifiVar.rConnSettings.rRsnInfo.au4PairwiseKeyCipherSuite[0] & 0x000000FF) != -+ GET_SELECTOR_TYPE(prBssRsnInfo->au4PairwiseKeyCipherSuite[i])) -+ && (i == prBssRsnInfo->u4PairwiseKeyCipherSuiteCount - 1)) { -+ DBGLOG(RSN, TRACE, "Break by PairwiseKeyCipherSuite\n"); -+ break; -+ } -+ } -+ for (i = 0; i < prBssRsnInfo->u4AuthKeyMgtSuiteCount; i++) { -+ if (((prAdapter->rWifiVar.rConnSettings.rRsnInfo.au4AuthKeyMgtSuite[0] & 0x000000FF) != -+ GET_SELECTOR_TYPE(prBssRsnInfo->au4AuthKeyMgtSuite[0])) -+ && (i == prBssRsnInfo->u4AuthKeyMgtSuiteCount - 1)) { -+ DBGLOG(RSN, TRACE, "Break by AuthKeyMgtSuite\n"); -+ break; -+ } -+ } -+ return TRUE; -+ } while (FALSE); -+ return FALSE; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* -+* \brief This routine is called to search the desired -+* authentication and key management (AKM) suite from the -+* MIB Authentication and Key Management Suites table. -+* -+* \param[in] u4AkmSuite The desired AKM suite to be searched -+* \param[out] pu4Index Pointer to the index of the desired AKM suite in the -+* table -+* -+* \retval TRUE The desired AKM suite is found in the table. -+* \retval FALSE The desired AKM suite is not found in the table. -+* -+* \note -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN rsnSearchAKMSuite(IN P_ADAPTER_T prAdapter, IN UINT_32 u4AkmSuite, OUT PUINT_32 pu4Index) -+{ -+ UINT_8 i; -+ P_DOT11_RSNA_CONFIG_AUTHENTICATION_SUITES_ENTRY prEntry; -+ -+ DEBUGFUNC("rsnSearchAKMSuite"); -+ -+ ASSERT(pu4Index); -+ -+ for (i = 0; i < MAX_NUM_SUPPORTED_AKM_SUITES; i++) { -+ prEntry = &prAdapter->rMib.dot11RSNAConfigAuthenticationSuitesTable[i]; -+ if (prEntry->dot11RSNAConfigAuthenticationSuite == u4AkmSuite && -+ prEntry->dot11RSNAConfigAuthenticationSuiteEnabled) { -+ *pu4Index = i; -+ return TRUE; -+ } -+ } -+ return FALSE; -+} /* rsnSearchAKMSuite */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to perform RSNA or TSN policy -+* selection for a given BSS. -+* -+* \param[in] prBss Pointer to the BSS description -+* -+* \retval TRUE - The RSNA/TSN policy selection for the given BSS is -+* successful. The selected pairwise and group cipher suites -+* are returned in the BSS description. -+* \retval FALSE - The RSNA/TSN policy selection for the given BSS is failed. -+* The driver shall not attempt to join the given BSS. -+* -+* \note The Encrypt status matched score will save to bss for final ap select. -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN rsnPerformPolicySelection(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBss) -+{ -+#if CFG_SUPPORT_802_11W -+ INT_32 i; -+ UINT_32 j; -+#else -+ UINT_32 i, j; -+#endif -+ BOOLEAN fgSuiteSupported; -+ UINT_32 u4PairwiseCipher = 0; -+ UINT_32 u4GroupCipher = 0; -+ UINT_32 u4AkmSuite = 0; -+ P_RSN_INFO_T prBssRsnInfo; -+ ENUM_NETWORK_TYPE_INDEX_T eNetwotkType; -+ BOOLEAN fgIsWpsActive = (BOOLEAN) FALSE; -+ -+ DEBUGFUNC("rsnPerformPolicySelection"); -+ -+ ASSERT(prBss); -+ -+ DBGLOG(RSN, TRACE, "rsnPerformPolicySelection\n"); -+ /* Todo:: */ -+ eNetwotkType = NETWORK_TYPE_AIS_INDEX; -+ -+ prBss->u4RsnSelectedPairwiseCipher = 0; -+ prBss->u4RsnSelectedGroupCipher = 0; -+ prBss->u4RsnSelectedAKMSuite = 0; -+ prBss->ucEncLevel = 0; -+ -+#if CFG_SUPPORT_WPS -+ fgIsWpsActive = kalWSCGetActiveState(prAdapter->prGlueInfo); -+ -+ /* CR1640, disable the AP select privacy check */ -+ if (fgIsWpsActive && -+ (prAdapter->rWifiVar.rConnSettings.eAuthMode < AUTH_MODE_WPA) && -+ (prAdapter->rWifiVar.rConnSettings.eOPMode == NET_TYPE_INFRA)) { -+ DBGLOG(RSN, TRACE, "-- Skip the Protected BSS check\n"); -+ return TRUE; -+ } -+#endif -+ -+ /* Protection is not required in this BSS. */ -+ if ((prBss->u2CapInfo & CAP_INFO_PRIVACY) == 0) { -+ -+ if (secEnabledInAis(prAdapter) == FALSE) { -+ DBGLOG(RSN, TRACE, "-- No Protected BSS\n"); -+ return TRUE; -+ } -+ DBGLOG(RSN, TRACE, "-- Protected BSS\n"); -+ return FALSE; -+ -+ } -+ -+ /* Protection is required in this BSS. */ -+ if ((prBss->u2CapInfo & CAP_INFO_PRIVACY) != 0) { -+ if (secEnabledInAis(prAdapter) == FALSE) { -+ DBGLOG(RSN, TRACE, "-- Protected BSS\n"); -+ return FALSE; -+ } -+ } -+ -+ if (prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA || -+ prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA_PSK || -+ prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA_NONE) { -+ -+ if (prBss->fgIEWPA) { -+ prBssRsnInfo = &prBss->rWPAInfo; -+ } else { -+ DBGLOG(RSN, TRACE, "WPA Information Element does not exist.\n"); -+ return FALSE; -+ } -+ } else if (prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA2 || -+ prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA2_PSK) { -+ -+ if (prBss->fgIERSN) { -+ prBssRsnInfo = &prBss->rRSNInfo; -+ } else { -+ DBGLOG(RSN, TRACE, "RSN Information Element does not exist.\n"); -+ return FALSE; -+ } -+ } else if (prAdapter->rWifiVar.rConnSettings.eEncStatus != ENUM_ENCRYPTION1_ENABLED) { -+ /* If the driver is configured to use WEP only, ignore this BSS. */ -+ DBGLOG(RSN, TRACE, "-- Not WEP-only legacy BSS %d\n", prAdapter->rWifiVar.rConnSettings.eEncStatus); -+ return FALSE; -+ } else if (prAdapter->rWifiVar.rConnSettings.eEncStatus == ENUM_ENCRYPTION1_ENABLED) { -+ /* If the driver is configured to use WEP only, use this BSS. */ -+ DBGLOG(RSN, TRACE, "-- WEP-only legacy BSS, fgIERSN %d, fgIEWPA %d\n", -+ prBss->fgIERSN, prBss->fgIEWPA); -+ /* if this BSS was configured to WPA/WPA2, don't select this AP */ -+ return (prBss->fgIERSN || prBss->fgIEWPA) ? FALSE : TRUE; -+ } -+ -+ if (!rsnIsSuitableBSS(prAdapter, prBssRsnInfo)) { -+ DBGLOG(RSN, TRACE, "RSN info check no matched\n"); -+ return FALSE; -+ } -+ -+ if (prBssRsnInfo->u4PairwiseKeyCipherSuiteCount == 1 && -+ GET_SELECTOR_TYPE(prBssRsnInfo->au4PairwiseKeyCipherSuite[0]) == CIPHER_SUITE_NONE) { -+ /* Since the pairwise cipher use the same cipher suite as the group -+ cipher in the BSS, we check the group cipher suite against the -+ current encryption status. */ -+ fgSuiteSupported = FALSE; -+ -+ switch (prBssRsnInfo->u4GroupKeyCipherSuite) { -+ case WPA_CIPHER_SUITE_CCMP: -+ case RSN_CIPHER_SUITE_CCMP: -+ if (prAdapter->rWifiVar.rConnSettings.eEncStatus == ENUM_ENCRYPTION3_ENABLED) -+ fgSuiteSupported = TRUE; -+ break; -+ -+ case WPA_CIPHER_SUITE_TKIP: -+ case RSN_CIPHER_SUITE_TKIP: -+ if (prAdapter->rWifiVar.rConnSettings.eEncStatus == ENUM_ENCRYPTION2_ENABLED) -+ fgSuiteSupported = TRUE; -+ break; -+ -+ case WPA_CIPHER_SUITE_WEP40: -+ case WPA_CIPHER_SUITE_WEP104: -+ if (prAdapter->rWifiVar.rConnSettings.eEncStatus == ENUM_ENCRYPTION1_ENABLED) -+ fgSuiteSupported = TRUE; -+ break; -+ } -+ -+ if (fgSuiteSupported) { -+ u4PairwiseCipher = WPA_CIPHER_SUITE_NONE; -+ u4GroupCipher = prBssRsnInfo->u4GroupKeyCipherSuite; -+ } -+#if DBG -+ else { -+ DBGLOG(RSN, TRACE, "Inproper encryption status %d for group-key-only BSS\n", -+ prAdapter->rWifiVar.rConnSettings.eEncStatus); -+ } -+#endif -+ } else { -+ fgSuiteSupported = FALSE; -+ -+ DBGLOG(RSN, TRACE, "eEncStatus %d %d 0x%x\n", prAdapter->rWifiVar.rConnSettings.eEncStatus, -+ (UINT_32) prBssRsnInfo->u4PairwiseKeyCipherSuiteCount, -+ (UINT_32) prBssRsnInfo->au4PairwiseKeyCipherSuite[0]); -+ /* Select pairwise/group ciphers */ -+ switch (prAdapter->rWifiVar.rConnSettings.eEncStatus) { -+ case ENUM_ENCRYPTION3_ENABLED: -+ for (i = 0; i < prBssRsnInfo->u4PairwiseKeyCipherSuiteCount; i++) { -+ if (GET_SELECTOR_TYPE(prBssRsnInfo->au4PairwiseKeyCipherSuite[i]) -+ == CIPHER_SUITE_CCMP) { -+ u4PairwiseCipher = prBssRsnInfo->au4PairwiseKeyCipherSuite[i]; -+ } -+ } -+ u4GroupCipher = prBssRsnInfo->u4GroupKeyCipherSuite; -+ break; -+ -+ case ENUM_ENCRYPTION2_ENABLED: -+ for (i = 0; i < prBssRsnInfo->u4PairwiseKeyCipherSuiteCount; i++) { -+ if (GET_SELECTOR_TYPE(prBssRsnInfo->au4PairwiseKeyCipherSuite[i]) -+ == CIPHER_SUITE_TKIP) { -+ u4PairwiseCipher = prBssRsnInfo->au4PairwiseKeyCipherSuite[i]; -+ } -+ } -+ if (GET_SELECTOR_TYPE(prBssRsnInfo->u4GroupKeyCipherSuite) == CIPHER_SUITE_CCMP) -+ DBGLOG(RSN, TRACE, "Cannot join CCMP BSS\n"); -+ else -+ u4GroupCipher = prBssRsnInfo->u4GroupKeyCipherSuite; -+ break; -+ -+ case ENUM_ENCRYPTION1_ENABLED: -+ for (i = 0; i < prBssRsnInfo->u4PairwiseKeyCipherSuiteCount; i++) { -+ if (GET_SELECTOR_TYPE(prBssRsnInfo->au4PairwiseKeyCipherSuite[i]) -+ == CIPHER_SUITE_WEP40 || -+ GET_SELECTOR_TYPE(prBssRsnInfo->au4PairwiseKeyCipherSuite[i]) -+ == CIPHER_SUITE_WEP104) { -+ u4PairwiseCipher = prBssRsnInfo->au4PairwiseKeyCipherSuite[i]; -+ } -+ } -+ if (GET_SELECTOR_TYPE(prBssRsnInfo->u4GroupKeyCipherSuite) == -+ CIPHER_SUITE_CCMP || -+ GET_SELECTOR_TYPE(prBssRsnInfo->u4GroupKeyCipherSuite) == CIPHER_SUITE_TKIP) { -+ DBGLOG(RSN, TRACE, "Cannot join CCMP/TKIP BSS\n"); -+ } else { -+ u4GroupCipher = prBssRsnInfo->u4GroupKeyCipherSuite; -+ } -+ break; -+ -+ default: -+ break; -+ } -+ } -+ -+ /* Exception handler */ -+ /* If we cannot find proper pairwise and group cipher suites to join the -+ BSS, do not check the supported AKM suites. */ -+ if (u4PairwiseCipher == 0 || u4GroupCipher == 0) { -+ DBGLOG(RSN, TRACE, "Failed to select pairwise/group cipher (0x%08x/0x%08x)\n", -+ u4PairwiseCipher, u4GroupCipher); -+ return FALSE; -+ } -+#if CFG_ENABLE_WIFI_DIRECT -+ if ((prAdapter->fgIsP2PRegistered) && (eNetwotkType == NETWORK_TYPE_P2P_INDEX)) { -+ if (u4PairwiseCipher != RSN_CIPHER_SUITE_CCMP || -+ u4GroupCipher != RSN_CIPHER_SUITE_CCMP || u4AkmSuite != RSN_AKM_SUITE_PSK) { -+ DBGLOG(RSN, TRACE, "Failed to select pairwise/group cipher for P2P network (0x%08x/0x%08x)\n", -+ u4PairwiseCipher, u4GroupCipher); -+ return FALSE; -+ } -+ } -+#endif -+ -+#if CFG_ENABLE_BT_OVER_WIFI -+ if (eNetwotkType == NETWORK_TYPE_BOW_INDEX) { -+ if (u4PairwiseCipher != RSN_CIPHER_SUITE_CCMP || -+ u4GroupCipher != RSN_CIPHER_SUITE_CCMP || u4AkmSuite != RSN_AKM_SUITE_PSK) { -+ /* Do nothing */ -+ } -+ DBGLOG(RSN, TRACE, -+ "Failed to select pairwise/group cipher for BT over Wi-Fi network (0x%08x/0x%08x)\n", -+ u4PairwiseCipher, u4GroupCipher); -+ return FALSE; -+ } -+#endif -+ -+ /* Verify if selected pairwisse cipher is supported */ -+ fgSuiteSupported = rsnSearchSupportedCipher(prAdapter, u4PairwiseCipher, &i); -+ -+ /* Verify if selected group cipher is supported */ -+ if (fgSuiteSupported) -+ fgSuiteSupported = rsnSearchSupportedCipher(prAdapter, u4GroupCipher, &i); -+ -+ if (!fgSuiteSupported) { -+ DBGLOG(RSN, TRACE, "Failed to support selected pairwise/group cipher (0x%08x/0x%08x)\n", -+ u4PairwiseCipher, u4GroupCipher); -+ return FALSE; -+ } -+ -+ /* Select AKM */ -+ /* If the driver cannot support any authentication suites advertised in -+ the given BSS, we fail to perform RSNA policy selection. */ -+ /* Attempt to find any overlapping supported AKM suite. */ -+#if CFG_SUPPORT_802_11W -+ if (i != 0) -+ for (i = (prBssRsnInfo->u4AuthKeyMgtSuiteCount - 1); i >= 0; i--) { -+#else -+ for (i = 0; i < prBssRsnInfo->u4AuthKeyMgtSuiteCount; i++) { -+#endif -+ if (rsnSearchAKMSuite(prAdapter, prBssRsnInfo->au4AuthKeyMgtSuite[i], &j)) { -+ u4AkmSuite = prBssRsnInfo->au4AuthKeyMgtSuite[i]; -+ break; -+ } -+ } -+ -+ if (u4AkmSuite == 0) { -+ DBGLOG(RSN, TRACE, "Cannot support any AKM suites\n"); -+ return FALSE; -+ } -+ -+ DBGLOG(RSN, TRACE, "Selected pairwise/group cipher: %02x-%02x-%02x-%02x/%02x-%02x-%02x-%02x\n", -+ (UINT_8) (u4PairwiseCipher & 0x000000FF), -+ (UINT_8) ((u4PairwiseCipher >> 8) & 0x000000FF), -+ (UINT_8) ((u4PairwiseCipher >> 16) & 0x000000FF), -+ (UINT_8) ((u4PairwiseCipher >> 24) & 0x000000FF), -+ (UINT_8) (u4GroupCipher & 0x000000FF), -+ (UINT_8) ((u4GroupCipher >> 8) & 0x000000FF), -+ (UINT_8) ((u4GroupCipher >> 16) & 0x000000FF), -+ (UINT_8) ((u4GroupCipher >> 24) & 0x000000FF)); -+ -+ DBGLOG(RSN, TRACE, "Selected AKM suite: %02x-%02x-%02x-%02x\n", -+ (UINT_8) (u4AkmSuite & 0x000000FF), -+ (UINT_8) ((u4AkmSuite >> 8) & 0x000000FF), -+ (UINT_8) ((u4AkmSuite >> 16) & 0x000000FF), (UINT_8) ((u4AkmSuite >> 24) & 0x000000FF)); -+ -+#if CFG_SUPPORT_802_11W -+ DBGLOG(RSN, TRACE, "MFP setting = %d\n ", kalGetMfpSetting(prAdapter->prGlueInfo)); -+ -+ if (kalGetMfpSetting(prAdapter->prGlueInfo) == RSN_AUTH_MFP_REQUIRED) { -+ if (!prBssRsnInfo->fgRsnCapPresent) { -+ DBGLOG(RSN, TRACE, "Skip RSN IE, No MFP Required Capability.\n"); -+ return FALSE; -+ } else if (!(prBssRsnInfo->u2RsnCap & ELEM_WPA_CAP_MFPC)) { -+ DBGLOG(RSN, TRACE, "Skip RSN IE, No MFP Required\n"); -+ return FALSE; -+ } -+ prAdapter->rWifiVar.rAisSpecificBssInfo.fgMgmtProtection = TRUE; -+ } else if (kalGetMfpSetting(prAdapter->prGlueInfo) == RSN_AUTH_MFP_OPTIONAL) { -+ if (prBssRsnInfo->u2RsnCap && ((prBssRsnInfo->u2RsnCap & ELEM_WPA_CAP_MFPR) || -+ (prBssRsnInfo->u2RsnCap & ELEM_WPA_CAP_MFPC))) { -+ prAdapter->rWifiVar.rAisSpecificBssInfo.fgMgmtProtection = TRUE; -+ } else { -+ prAdapter->rWifiVar.rAisSpecificBssInfo.fgMgmtProtection = FALSE; -+ } -+ } else { -+ if (prBssRsnInfo->fgRsnCapPresent && (prBssRsnInfo->u2RsnCap & ELEM_WPA_CAP_MFPR)) { -+ DBGLOG(RSN, TRACE, "Skip RSN IE, No MFP Required Capability\n"); -+ return FALSE; -+ } -+ prAdapter->rWifiVar.rAisSpecificBssInfo.fgMgmtProtection = FALSE; -+ } -+ DBGLOG(RSN, TRACE, "fgMgmtProtection = %d\n ", prAdapter->rWifiVar.rAisSpecificBssInfo.fgMgmtProtection); -+#endif -+ -+ if (GET_SELECTOR_TYPE(u4GroupCipher) == CIPHER_SUITE_CCMP) { -+ prBss->ucEncLevel = 3; -+ } else if (GET_SELECTOR_TYPE(u4GroupCipher) == CIPHER_SUITE_TKIP) { -+ prBss->ucEncLevel = 2; -+ } else if (GET_SELECTOR_TYPE(u4GroupCipher) == CIPHER_SUITE_WEP40 || -+ GET_SELECTOR_TYPE(u4GroupCipher) == CIPHER_SUITE_WEP104) { -+ prBss->ucEncLevel = 1; -+ } else { -+ ASSERT(FALSE); -+ } -+ prBss->u4RsnSelectedPairwiseCipher = u4PairwiseCipher; -+ prBss->u4RsnSelectedGroupCipher = u4GroupCipher; -+ prBss->u4RsnSelectedAKMSuite = u4AkmSuite; -+ -+ return TRUE; -+ -+} /* rsnPerformPolicySelection */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to generate WPA IE for beacon frame. -+* -+* \param[in] pucIeStartAddr Pointer to put the generated WPA IE. -+* -+* \return The append WPA-None IE length -+* \note -+* Called by: JOIN module, compose beacon IE -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rsnGenerateWpaNoneIE(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo) -+{ -+ UINT_32 i; -+ P_WPA_INFO_ELEM_T prWpaIE; -+ UINT_32 u4Suite; -+ UINT_16 u2SuiteCount; -+ PUINT_8 cp, cp2; -+ UINT_8 ucExpendedLen = 0; -+ PUINT_8 pucBuffer; -+ ENUM_NETWORK_TYPE_INDEX_T eNetworkId; -+ -+ DEBUGFUNC("rsnGenerateWpaNoneIE"); -+ -+ ASSERT(prMsduInfo); -+ -+ if (prAdapter->rWifiVar.rConnSettings.eAuthMode != AUTH_MODE_WPA_NONE) -+ return; -+ -+ eNetworkId = (ENUM_NETWORK_TYPE_INDEX_T) prMsduInfo->ucNetworkType; -+ -+ if (eNetworkId != NETWORK_TYPE_AIS_INDEX) -+ return; -+ -+ pucBuffer = (PUINT_8) ((ULONG) prMsduInfo->prPacket + (UINT_32) prMsduInfo->u2FrameLength); -+ -+ ASSERT(pucBuffer); -+ -+ prWpaIE = (P_WPA_INFO_ELEM_T) (pucBuffer); -+ -+ /* Start to construct a WPA IE. */ -+ /* Fill the Element ID field. */ -+ prWpaIE->ucElemId = ELEM_ID_WPA; -+ -+ /* Fill the OUI and OUI Type fields. */ -+ prWpaIE->aucOui[0] = 0x00; -+ prWpaIE->aucOui[1] = 0x50; -+ prWpaIE->aucOui[2] = 0xF2; -+ prWpaIE->ucOuiType = VENDOR_OUI_TYPE_WPA; -+ -+ /* Fill the Version field. */ -+ WLAN_SET_FIELD_16(&prWpaIE->u2Version, 1); /* version 1 */ -+ ucExpendedLen = 6; -+ -+ /* Fill the Pairwise Key Cipher Suite List field. */ -+ u2SuiteCount = 0; -+ cp = (PUINT_8) &prWpaIE->aucPairwiseKeyCipherSuite1[0]; -+ -+ if (rsnSearchSupportedCipher(prAdapter, WPA_CIPHER_SUITE_CCMP, &i)) -+ u4Suite = WPA_CIPHER_SUITE_CCMP; -+ else if (rsnSearchSupportedCipher(prAdapter, WPA_CIPHER_SUITE_TKIP, &i)) -+ u4Suite = WPA_CIPHER_SUITE_TKIP; -+ else if (rsnSearchSupportedCipher(prAdapter, WPA_CIPHER_SUITE_WEP104, &i)) -+ u4Suite = WPA_CIPHER_SUITE_WEP104; -+ else if (rsnSearchSupportedCipher(prAdapter, WPA_CIPHER_SUITE_WEP40, &i)) -+ u4Suite = WPA_CIPHER_SUITE_WEP40; -+ else -+ u4Suite = WPA_CIPHER_SUITE_TKIP; -+ -+ WLAN_SET_FIELD_32(cp, u4Suite); -+ u2SuiteCount++; -+ ucExpendedLen += 4; -+ cp += 4; -+ -+ /* Fill the Group Key Cipher Suite field as the same in pair-wise key. */ -+ WLAN_SET_FIELD_32(&prWpaIE->u4GroupKeyCipherSuite, u4Suite); -+ ucExpendedLen += 4; -+ -+ /* Fill the Pairwise Key Cipher Suite Count field. */ -+ WLAN_SET_FIELD_16(&prWpaIE->u2PairwiseKeyCipherSuiteCount, u2SuiteCount); -+ ucExpendedLen += 2; -+ -+ cp2 = cp; -+ -+ /* Fill the Authentication and Key Management Suite List field. */ -+ u2SuiteCount = 0; -+ cp += 2; -+ -+ if (rsnSearchAKMSuite(prAdapter, WPA_AKM_SUITE_802_1X, &i)) -+ u4Suite = WPA_AKM_SUITE_802_1X; -+ else if (rsnSearchAKMSuite(prAdapter, WPA_AKM_SUITE_PSK, &i)) -+ u4Suite = WPA_AKM_SUITE_PSK; -+ else -+ u4Suite = WPA_AKM_SUITE_NONE; -+ -+ /* This shall be the only available value for current implementation */ -+ ASSERT(u4Suite == WPA_AKM_SUITE_NONE); -+ -+ WLAN_SET_FIELD_32(cp, u4Suite); -+ u2SuiteCount++; -+ ucExpendedLen += 4; -+ cp += 4; -+ -+ /* Fill the Authentication and Key Management Suite Count field. */ -+ WLAN_SET_FIELD_16(cp2, u2SuiteCount); -+ ucExpendedLen += 2; -+ -+ /* Fill the Length field. */ -+ prWpaIE->ucLength = (UINT_8) ucExpendedLen; -+ -+ /* Increment the total IE length for the Element ID and Length fields. */ -+ prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer); -+ -+} /* rsnGenerateWpaNoneIE */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* -+* \brief This routine is called to generate WPA IE for -+* associate request frame. -+* -+* \param[in] prCurrentBss The Selected BSS description -+* -+* \retval The append WPA IE length -+* -+* \note -+* Called by: AIS module, Associate request -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rsnGenerateWPAIE(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo) -+{ -+ PUCHAR cp; -+ PUINT_8 pucBuffer; -+ ENUM_NETWORK_TYPE_INDEX_T eNetworkId; -+ P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo; -+ -+ DEBUGFUNC("rsnGenerateWPAIE"); -+ -+ ASSERT(prMsduInfo); -+ -+ pucBuffer = (PUINT_8) ((ULONG) prMsduInfo->prPacket + (UINT_32) prMsduInfo->u2FrameLength); -+ -+ ASSERT(pucBuffer); -+ -+ eNetworkId = (ENUM_NETWORK_TYPE_INDEX_T) prMsduInfo->ucNetworkType; -+ prP2pSpecificBssInfo = prAdapter->rWifiVar.prP2pSpecificBssInfo; -+ -+ /* if (eNetworkId != NETWORK_TYPE_AIS_INDEX) */ -+ /* return; */ -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ if ((1 /* prCurrentBss->fgIEWPA */ && -+ ((prAdapter->fgIsP2PRegistered) && -+ (eNetworkId == NETWORK_TYPE_P2P_INDEX) && -+ (kalP2PGetTkipCipher(prAdapter->prGlueInfo)))) || -+ ((prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA) || -+ (prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA_PSK))) { -+#else -+ if ((1 /* prCurrentBss->fgIEWPA */ && -+ ((prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA) || -+ (prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA_PSK)))) { -+#endif -+ if (prP2pSpecificBssInfo->u2WpaIeLen != 0) { -+ kalMemCopy(pucBuffer, prP2pSpecificBssInfo->aucWpaIeBuffer, prP2pSpecificBssInfo->u2WpaIeLen); -+ prMsduInfo->u2FrameLength += prP2pSpecificBssInfo->u2WpaIeLen; -+ return; -+ } -+ -+ /* Construct a WPA IE for association request frame. */ -+ WPA_IE(pucBuffer)->ucElemId = ELEM_ID_WPA; -+ WPA_IE(pucBuffer)->ucLength = ELEM_ID_WPA_LEN_FIXED; -+ WPA_IE(pucBuffer)->aucOui[0] = 0x00; -+ WPA_IE(pucBuffer)->aucOui[1] = 0x50; -+ WPA_IE(pucBuffer)->aucOui[2] = 0xF2; -+ WPA_IE(pucBuffer)->ucOuiType = VENDOR_OUI_TYPE_WPA; -+ WLAN_SET_FIELD_16(&WPA_IE(pucBuffer)->u2Version, 1); -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ if (prAdapter->fgIsP2PRegistered && eNetworkId == NETWORK_TYPE_P2P_INDEX) { -+ WLAN_SET_FIELD_32(&WPA_IE(pucBuffer)->u4GroupKeyCipherSuite, WPA_CIPHER_SUITE_TKIP); -+ } else -+#endif -+ WLAN_SET_FIELD_32(&WPA_IE(pucBuffer)->u4GroupKeyCipherSuite, -+ prAdapter->rWifiVar. -+ arBssInfo[NETWORK_TYPE_AIS_INDEX].u4RsnSelectedGroupCipher); -+ -+ cp = (PUCHAR) &WPA_IE(pucBuffer)->aucPairwiseKeyCipherSuite1[0]; -+ -+ WLAN_SET_FIELD_16(&WPA_IE(pucBuffer)->u2PairwiseKeyCipherSuiteCount, 1); -+#if CFG_ENABLE_WIFI_DIRECT -+ if (prAdapter->fgIsP2PRegistered && eNetworkId == NETWORK_TYPE_P2P_INDEX) { -+ WLAN_SET_FIELD_32(cp, WPA_CIPHER_SUITE_TKIP); -+ } else -+#endif -+ WLAN_SET_FIELD_32(cp, -+ prAdapter->rWifiVar. -+ arBssInfo[NETWORK_TYPE_AIS_INDEX].u4RsnSelectedPairwiseCipher); -+ cp += 4; -+ -+ WLAN_SET_FIELD_16(cp, 1); -+ cp += 2; -+#if CFG_ENABLE_WIFI_DIRECT -+ if (prAdapter->fgIsP2PRegistered && eNetworkId == NETWORK_TYPE_P2P_INDEX) { -+ WLAN_SET_FIELD_32(cp, WPA_AKM_SUITE_PSK); -+ } else -+#endif -+ WLAN_SET_FIELD_32(cp, -+ prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX].u4RsnSelectedAKMSuite); -+ cp += 4; -+ -+ WPA_IE(pucBuffer)->ucLength = ELEM_ID_WPA_LEN_FIXED; -+ -+ prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer); -+ } -+ -+} /* rsnGenerateWPAIE */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* -+* \brief This routine is called to generate RSN IE for -+* associate request frame. -+* -+* \param[in] prMsduInfo The Selected BSS description -+* -+* \retval The append RSN IE length -+* -+* \note -+* Called by: AIS module, P2P module, BOW module Associate request -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rsnGenerateRSNIE(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo) -+{ -+ UINT_32 u4Entry; -+ PUCHAR cp; -+ /* UINT_8 ucExpendedLen = 0; */ -+ PUINT_8 pucBuffer; -+ ENUM_NETWORK_TYPE_INDEX_T eNetworkId; -+ P_STA_RECORD_T prStaRec; -+ -+ DEBUGFUNC("rsnGenerateRSNIE"); -+ -+ ASSERT(prMsduInfo); -+ -+ pucBuffer = (PUINT_8) ((ULONG) prMsduInfo->prPacket + (UINT_32) prMsduInfo->u2FrameLength); -+ -+ ASSERT(pucBuffer); -+ -+ /* Todo:: network id */ -+ eNetworkId = (ENUM_NETWORK_TYPE_INDEX_T) prMsduInfo->ucNetworkType; -+ -+ if ( -+#if CFG_ENABLE_WIFI_DIRECT -+ ((prAdapter->fgIsP2PRegistered) && -+ (eNetworkId == NETWORK_TYPE_P2P_INDEX) && (kalP2PGetCcmpCipher(prAdapter->prGlueInfo))) || -+#endif -+#if CFG_ENABLE_BT_OVER_WIFI -+ (eNetworkId == NETWORK_TYPE_BOW_INDEX) || -+#endif -+ (eNetworkId == NETWORK_TYPE_AIS_INDEX /* prCurrentBss->fgIERSN */ && -+ ((prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA2) || -+ (prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA2_PSK)))) { -+ /* Construct a RSN IE for association request frame. */ -+ RSN_IE(pucBuffer)->ucElemId = ELEM_ID_RSN; -+ RSN_IE(pucBuffer)->ucLength = ELEM_ID_RSN_LEN_FIXED; -+ WLAN_SET_FIELD_16(&RSN_IE(pucBuffer)->u2Version, 1); /* Version */ -+ WLAN_SET_FIELD_32(&RSN_IE(pucBuffer)->u4GroupKeyCipherSuite, -+ prAdapter->rWifiVar.arBssInfo[eNetworkId].u4RsnSelectedGroupCipher); /* Group key suite */ -+ cp = (PUCHAR) &RSN_IE(pucBuffer)->aucPairwiseKeyCipherSuite1[0]; -+ WLAN_SET_FIELD_16(&RSN_IE(pucBuffer)->u2PairwiseKeyCipherSuiteCount, 1); -+ WLAN_SET_FIELD_32(cp, prAdapter->rWifiVar.arBssInfo[eNetworkId].u4RsnSelectedPairwiseCipher); -+ cp += 4; -+ WLAN_SET_FIELD_16(cp, 1); /* AKM suite count */ -+ cp += 2; -+ WLAN_SET_FIELD_32(cp, prAdapter->rWifiVar.arBssInfo[eNetworkId].u4RsnSelectedAKMSuite); /* AKM suite */ -+ cp += 4; -+ WLAN_SET_FIELD_16(cp, prAdapter->rWifiVar.arBssInfo[eNetworkId].u2RsnSelectedCapInfo);/* Capabilities */ -+#if CFG_SUPPORT_802_11W -+ if (eNetworkId == NETWORK_TYPE_AIS_INDEX && prAdapter->rWifiVar.rAisSpecificBssInfo.fgMgmtProtection) { -+ if (kalGetMfpSetting(prAdapter->prGlueInfo) == RSN_AUTH_MFP_REQUIRED) -+ WLAN_SET_FIELD_16(cp, ELEM_WPA_CAP_MFPC | ELEM_WPA_CAP_MFPR); /* Capabilities */ -+ else if (kalGetMfpSetting(prAdapter->prGlueInfo) == RSN_AUTH_MFP_OPTIONAL) -+ WLAN_SET_FIELD_16(cp, ELEM_WPA_CAP_MFPC); /* Capabilities */ -+ } -+#endif -+ cp += 2; -+ -+ if (eNetworkId == NETWORK_TYPE_AIS_INDEX) { -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); -+ if (!prStaRec) { -+ DBGLOG(RSN, TRACE, "rsnGenerateRSNIE: prStaRec is NULL\n"); -+ return; -+ } -+ } -+ -+ if (eNetworkId == NETWORK_TYPE_AIS_INDEX && -+ rsnSearchPmkidEntry(prAdapter, prStaRec->aucMacAddr, &u4Entry)) { -+ /* DBGLOG(RSN, TRACE, ("Add Pmk at assoc req\n")); */ -+ /* DBGLOG(RSN, TRACE, ("addr %pM PMKID %pM\n", */ -+ /* (prAdapter->rWifiVar.rAisSpecificBssInfo.arPmkidCache[u4Entry].rBssidInfo.arBSSID),*/ -+ /* (prAdapter->rWifiVar.rAisSpecificBssInfo.arPmkidCache[u4Entry].rBssidInfo.arPMKID))); */ -+ if (prAdapter->rWifiVar.rAisSpecificBssInfo.arPmkidCache[u4Entry].fgPmkidExist) { -+ RSN_IE(pucBuffer)->ucLength = 38; -+ WLAN_SET_FIELD_16(cp, 1); /* PMKID count */ -+ cp += 2; -+ DBGLOG(RSN, TRACE, -+ "BSSID %pM ind=%d\n", prStaRec->aucMacAddr, (UINT_32) u4Entry); -+ DBGLOG(RSN, TRACE, "use PMKID %pM\n", -+ (prAdapter->rWifiVar.rAisSpecificBssInfo. -+ arPmkidCache[u4Entry].rBssidInfo.arPMKID)); -+ kalMemCopy(cp, -+ (PVOID) prAdapter->rWifiVar.rAisSpecificBssInfo. -+ arPmkidCache[u4Entry].rBssidInfo.arPMKID, sizeof(PARAM_PMKID_VALUE)); -+ /* ucExpendedLen = 40; */ -+ } else { -+ WLAN_SET_FIELD_16(cp, 0); /* PMKID count */ -+ /* ucExpendedLen = ELEM_ID_RSN_LEN_FIXED + 2; */ -+#if CFG_SUPPORT_802_11W -+ cp += 2; -+ RSN_IE(pucBuffer)->ucLength += 2; -+#endif -+ } -+ } else { -+ WLAN_SET_FIELD_16(cp, 0); /* PMKID count */ -+ /* ucExpendedLen = ELEM_ID_RSN_LEN_FIXED + 2; */ -+#if CFG_SUPPORT_802_11W -+ cp += 2; -+ RSN_IE(pucBuffer)->ucLength += 2; -+#endif -+ } -+ -+#if CFG_SUPPORT_802_11W -+ if ((eNetworkId == NETWORK_TYPE_AIS_INDEX) -+ && (kalGetMfpSetting(prAdapter->prGlueInfo) != -+ RSN_AUTH_MFP_DISABLED) /* (mgmt_group_cipher == WPA_CIPHER_AES_128_CMAC) */) { -+ WLAN_SET_FIELD_32(cp, RSN_CIPHER_SUITE_AES_128_CMAC); -+ cp += 4; -+ RSN_IE(pucBuffer)->ucLength += 4; -+ } -+#endif -+ prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer); -+ } -+ -+} /* rsnGenerateRSNIE */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Parse the given IE buffer and check if it is WFA IE and return Type and -+* SubType for further process. -+* -+* \param[in] pucBuf Pointer to the buffer of WFA Information Element. -+* \param[out] pucOuiType Pointer to the storage of OUI Type. -+* \param[out] pu2SubTypeVersion Pointer to the storage of OUI SubType and Version. -+ -+* \retval TRUE Parse IE ok -+* \retval FALSE Parse IE fail -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN -+rsnParseCheckForWFAInfoElem(IN P_ADAPTER_T prAdapter, -+ IN PUINT_8 pucBuf, OUT PUINT_8 pucOuiType, OUT PUINT_16 pu2SubTypeVersion) -+{ -+ UINT_8 aucWfaOui[] = VENDOR_OUI_WFA; -+ P_IE_WFA_T prWfaIE; -+ -+ ASSERT(pucBuf); -+ ASSERT(pucOuiType); -+ ASSERT(pu2SubTypeVersion); -+ prWfaIE = (P_IE_WFA_T) pucBuf; -+ -+ do { -+ if (IE_LEN(pucBuf) <= ELEM_MIN_LEN_WFA_OUI_TYPE_SUBTYPE) { -+ break; -+ } else if (prWfaIE->aucOui[0] != aucWfaOui[0] || -+ prWfaIE->aucOui[1] != aucWfaOui[1] || prWfaIE->aucOui[2] != aucWfaOui[2]) { -+ break; -+ } -+ -+ *pucOuiType = prWfaIE->ucOuiType; -+ WLAN_GET_FIELD_16(&prWfaIE->aucOuiSubTypeVersion[0], pu2SubTypeVersion); -+ -+ return TRUE; -+ } while (FALSE); -+ -+ return FALSE; -+ -+} /* end of rsnParseCheckForWFAInfoElem() */ -+ -+#if CFG_SUPPORT_AAA -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Parse the given IE buffer and check if it is RSN IE with CCMP PSK -+* -+* \param[in] prAdapter Pointer to Adapter -+* \param[in] prSwRfb Pointer to the rx buffer -+* \param[in] pIE Pointer rthe buffer of Information Element. -+* \param[out] prStatusCode Pointer to the return status code. -+ -+* \retval none -+*/ -+/*----------------------------------------------------------------------------*/ -+void rsnParserCheckForRSNCCMPPSK(P_ADAPTER_T prAdapter, P_RSN_INFO_ELEM_T prIe, PUINT_16 pu2StatusCode) -+{ -+ -+ RSN_INFO_T rRsnIe; -+ -+ ASSERT(prAdapter); -+ ASSERT(prIe); -+ ASSERT(pu2StatusCode); -+ -+ *pu2StatusCode = STATUS_CODE_INVALID_INFO_ELEMENT; -+ -+ if (rsnParseRsnIE(prAdapter, prIe, &rRsnIe)) { -+ if ((rRsnIe.u4PairwiseKeyCipherSuiteCount != 1) -+ || (rRsnIe.au4PairwiseKeyCipherSuite[0] != RSN_CIPHER_SUITE_CCMP)) { -+ *pu2StatusCode = STATUS_CODE_INVALID_PAIRWISE_CIPHER; -+ return; -+ } -+ if (rRsnIe.u4GroupKeyCipherSuite != RSN_CIPHER_SUITE_CCMP) { -+ *pu2StatusCode = STATUS_CODE_INVALID_GROUP_CIPHER; -+ return; -+ } -+ if ((rRsnIe.u4AuthKeyMgtSuiteCount != 1) || (rRsnIe.au4AuthKeyMgtSuite[0] != RSN_AKM_SUITE_PSK)) { -+ *pu2StatusCode = STATUS_CODE_INVALID_AKMP; -+ return; -+ } -+ -+ DBGLOG(RSN, TRACE, "RSN with CCMP-PSK\n"); -+ *pu2StatusCode = WLAN_STATUS_SUCCESS; -+ } -+ -+} -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to generate an authentication event to NDIS. -+* -+* \param[in] u4Flags Authentication event: \n -+* PARAM_AUTH_REQUEST_REAUTH 0x01 \n -+* PARAM_AUTH_REQUEST_KEYUPDATE 0x02 \n -+* PARAM_AUTH_REQUEST_PAIRWISE_ERROR 0x06 \n -+* PARAM_AUTH_REQUEST_GROUP_ERROR 0x0E \n -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rsnGenMicErrorEvent(IN P_ADAPTER_T prAdapter, IN BOOLEAN fgFlags) -+{ -+ P_PARAM_AUTH_EVENT_T prAuthEvent; -+ -+ DEBUGFUNC("rsnGenMicErrorEvent"); -+ -+ prAuthEvent = (P_PARAM_AUTH_EVENT_T) prAdapter->aucIndicationEventBuffer; -+ -+ /* Status type: Authentication Event */ -+ prAuthEvent->rStatus.eStatusType = ENUM_STATUS_TYPE_AUTHENTICATION; -+ -+ /* Authentication request */ -+ prAuthEvent->arRequest[0].u4Length = sizeof(PARAM_AUTH_REQUEST_T); -+ kalMemCopy((PVOID) prAuthEvent->arRequest[0].arBssid, -+ (PVOID) prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX].aucBSSID, MAC_ADDR_LEN); -+ -+ if (fgFlags == TRUE) -+ prAuthEvent->arRequest[0].u4Flags = PARAM_AUTH_REQUEST_GROUP_ERROR; -+ else -+ prAuthEvent->arRequest[0].u4Flags = PARAM_AUTH_REQUEST_PAIRWISE_ERROR; -+ -+ kalIndicateStatusAndComplete(prAdapter->prGlueInfo, -+ WLAN_STATUS_MEDIA_SPECIFIC_INDICATION, -+ (PVOID) prAuthEvent, -+ sizeof(PARAM_STATUS_INDICATION_T) + sizeof(PARAM_AUTH_REQUEST_T)); -+ -+} /* rsnGenMicErrorEvent */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to handle TKIP MIC failures. -+* -+* \param[in] adapter_p Pointer to the adapter object data area. -+* \param[in] prSta Pointer to the STA which occur MIC Error -+* \param[in] fgErrorKeyType type of error key -+* -+* \retval none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rsnTkipHandleMICFailure(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta, IN BOOLEAN fgErrorKeyType) -+{ -+ /* UINT_32 u4RsnaCurrentMICFailTime; */ -+ /* P_AIS_SPECIFIC_BSS_INFO_T prAisSpecBssInfo; */ -+ -+ DEBUGFUNC("rsnTkipHandleMICFailure"); -+ -+ ASSERT(prAdapter); -+#if 1 -+ rsnGenMicErrorEvent(prAdapter, /* prSta, */ fgErrorKeyType); -+ -+ nicConfigPowerSaveProfile(prAdapter, NETWORK_TYPE_AIS_INDEX, Param_PowerModeCAM, FALSE); -+ -+ /* Generate authentication request event. */ -+ DBGLOG(RSN, INFO, "Generate TKIP MIC error event (type: 0%d)\n", fgErrorKeyType); -+#else -+ ASSERT(prSta); -+ -+ prAisSpecBssInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo; -+ -+ /* Record the MIC error occur time. */ -+ GET_CURRENT_SYSTIME(&u4RsnaCurrentMICFailTime); -+ -+ /* Generate authentication request event. */ -+ DBGLOG(RSN, INFO, "Generate TKIP MIC error event (type: 0%d)\n", fgErrorKeyType); -+ -+ /* If less than 60 seconds have passed since a previous TKIP MIC failure, -+ disassociate from the AP and wait for 60 seconds before (re)associating -+ with the same AP. */ -+ if (prAisSpecBssInfo->u4RsnaLastMICFailTime != 0 && -+ !CHECK_FOR_TIMEOUT(u4RsnaCurrentMICFailTime, -+ prAisSpecBssInfo->u4RsnaLastMICFailTime, SEC_TO_SYSTIME(TKIP_COUNTERMEASURE_SEC))) { -+ /* If less than 60 seconds expired since last MIC error, we have to -+ block traffic. */ -+ -+ DBGLOG(RSN, INFO, "Start blocking traffic!\n"); -+ rsnGenMicErrorEvent(prAdapter, /* prSta, */ fgErrorKeyType); -+ -+ secFsmEventStartCounterMeasure(prAdapter, prSta); -+ } else { -+ rsnGenMicErrorEvent(prAdapter, /* prSta, */ fgErrorKeyType); -+ DBGLOG(RSN, INFO, "First TKIP MIC error!\n"); -+ } -+ -+ COPY_SYSTIME(prAisSpecBssInfo->u4RsnaLastMICFailTime, u4RsnaCurrentMICFailTime); -+#endif -+} /* rsnTkipHandleMICFailure */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is called to select a list of BSSID from -+* the scan results for PMKID candidate list. -+* -+* \param[in] prBssDesc the BSS Desc at scan result list -+* \param[out] pu4CandidateCount Pointer to the number of selected candidates. -+* It is set to zero if no BSSID matches our requirement. -+* -+* \retval none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rsnSelectPmkidCandidateList(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBssDesc) -+{ -+ P_CONNECTION_SETTINGS_T prConnSettings; -+ P_AIS_BSS_INFO_T prAisBssInfo; -+ -+ DEBUGFUNC("rsnSelectPmkidCandidateList"); -+ -+ ASSERT(prBssDesc); -+ -+ prConnSettings = &prAdapter->rWifiVar.rConnSettings; -+ prAisBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]; -+ -+ /* Search a BSS with the same SSID from the given BSS description set. */ -+ /* DBGLOG(RSN, TRACE, ("Check scan result [%pM]\n", */ -+ /* prBssDesc->aucBSSID)); */ -+ -+ if (UNEQUAL_SSID(prBssDesc->aucSSID, prBssDesc->ucSSIDLen, -+ prConnSettings->aucSSID, prConnSettings->ucSSIDLen)) { -+ DBGLOG(RSN, TRACE, "-- SSID not matched\n"); -+ return; -+ } -+#if 0 -+ if ((prBssDesc->u2BSSBasicRateSet & -+ ~(rPhyAttributes[prAisBssInfo->ePhyType].u2SupportedRateSet)) || prBssDesc->fgIsUnknownBssBasicRate) { -+ DBGLOG(RSN, TRACE, "-- Rate set not matched\n"); -+ return; -+ } -+ -+ if (/* prBssDesc->u4RsnSelectedPairwiseCipher != prAisBssInfo->u4RsnSelectedPairwiseCipher || */ -+ prBssDesc->u4RsnSelectedGroupCipher != prAisBssInfo->u4RsnSelectedGroupCipher /*|| -+ prBssDesc->u4RsnSelectedAKMSuite != prAisBssInfo->u4RsnSelectedAKMSuite */) { -+ DBGLOG(RSN, TRACE, "-- Encrypt status not matched for PMKID\n"); -+ return; -+ } -+#endif -+ -+ rsnUpdatePmkidCandidateList(prAdapter, prBssDesc); -+ -+} /* rsnSelectPmkidCandidateList */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is called to select a list of BSSID from -+* the scan results for PMKID candidate list. -+* -+* \param[in] prBssDesc the BSS DESC at scan result list -+* -+* \retval none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rsnUpdatePmkidCandidateList(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBssDesc) -+{ -+ UINT_32 i; -+ P_CONNECTION_SETTINGS_T prConnSettings; -+ P_AIS_SPECIFIC_BSS_INFO_T prAisSpecBssInfo; -+ -+ DEBUGFUNC("rsnUpdatePmkidCandidateList"); -+ -+ ASSERT(prBssDesc); -+ -+ prConnSettings = &prAdapter->rWifiVar.rConnSettings; -+ prAisSpecBssInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo; -+ -+ if (UNEQUAL_SSID(prBssDesc->aucSSID, prBssDesc->ucSSIDLen, -+ prConnSettings->aucSSID, prConnSettings->ucSSIDLen)) { -+ DBGLOG(RSN, TRACE, "-- SSID not matched\n"); -+ return; -+ } -+ -+ for (i = 0; i < CFG_MAX_PMKID_CACHE; i++) { -+ if (EQUAL_MAC_ADDR(prBssDesc->aucBSSID, prAisSpecBssInfo->arPmkidCandicate[i].aucBssid)) -+ return; -+ } -+ -+ /* If the number of selected BSSID exceed MAX_NUM_PMKID_CACHE(16), -+ then we only store MAX_NUM_PMKID_CACHE(16) in PMKID cache */ -+ if ((prAisSpecBssInfo->u4PmkidCandicateCount + 1) > CFG_MAX_PMKID_CACHE) -+ prAisSpecBssInfo->u4PmkidCandicateCount--; -+ -+ i = prAisSpecBssInfo->u4PmkidCandicateCount; -+ -+ COPY_MAC_ADDR((PVOID) prAisSpecBssInfo->arPmkidCandicate[i].aucBssid, (PVOID) prBssDesc->aucBSSID); -+ -+ if (prBssDesc->u2RsnCap & MASK_RSNIE_CAP_PREAUTH) { -+ prAisSpecBssInfo->arPmkidCandicate[i].u4PreAuthFlags = 1; -+ DBGLOG(RSN, TRACE, "Add %pM with pre-auth to candidate list\n", -+ (prAisSpecBssInfo->arPmkidCandicate[i].aucBssid)); -+ } else { -+ prAisSpecBssInfo->arPmkidCandicate[i].u4PreAuthFlags = 0; -+ DBGLOG(RSN, TRACE, "Add %pM without pre-auth to candidate list\n", -+ (prAisSpecBssInfo->arPmkidCandicate[i].aucBssid)); -+ } -+ -+ prAisSpecBssInfo->u4PmkidCandicateCount++; -+ -+} /* rsnUpdatePmkidCandidateList */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to search the desired entry in -+* PMKID cache according to the BSSID -+* -+* \param[in] pucBssid Pointer to the BSSID -+* \param[out] pu4EntryIndex Pointer to place the found entry index -+* -+* \retval TRUE, if found one entry for specified BSSID -+* \retval FALSE, if not found -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN rsnSearchPmkidEntry(IN P_ADAPTER_T prAdapter, IN PUINT_8 pucBssid, OUT PUINT_32 pu4EntryIndex) -+{ -+ UINT_32 i; -+ P_AIS_SPECIFIC_BSS_INFO_T prAisSpecBssInfo; -+ -+ DEBUGFUNC("rsnSearchPmkidEntry"); -+ -+ ASSERT(pucBssid); -+ ASSERT(pu4EntryIndex); -+ -+ prAisSpecBssInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo; -+ -+ if (prAisSpecBssInfo->u4PmkidCacheCount > CFG_MAX_PMKID_CACHE) -+ return FALSE; -+ -+ ASSERT(prAisSpecBssInfo->u4PmkidCacheCount <= CFG_MAX_PMKID_CACHE); -+ -+ /* Search for desired BSSID */ -+ for (i = 0; i < prAisSpecBssInfo->u4PmkidCacheCount; i++) { -+ if (!kalMemCmp(prAisSpecBssInfo->arPmkidCache[i].rBssidInfo.arBSSID, pucBssid, MAC_ADDR_LEN)) -+ break; -+ } -+ -+ /* If desired BSSID is found, then set the PMKID */ -+ if (i < prAisSpecBssInfo->u4PmkidCacheCount) { -+ *pu4EntryIndex = i; -+ -+ return TRUE; -+ } -+ -+ return FALSE; -+} /* rsnSearchPmkidEntry */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to check if there is difference -+* between PMKID candicate list and PMKID cache. If there -+* is new candicate that no cache entry is available, then -+* add a new entry for the new candicate in the PMKID cache -+* and set the PMKID indication flag to TRUE. -+* -+* \retval TRUE, if new member in the PMKID candicate list -+* \retval FALSe, if no new member in the PMKID candicate list -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN rsnCheckPmkidCandicate(IN P_ADAPTER_T prAdapter) -+{ -+ P_AIS_SPECIFIC_BSS_INFO_T prAisSpecBssInfo; -+ UINT_32 i; /* Index for PMKID candicate */ -+ UINT_32 j; /* Indix for PMKID cache */ -+ BOOLEAN status = FALSE; -+ -+ DEBUGFUNC("rsnCheckPmkidCandicate"); -+ -+ prAisSpecBssInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo; -+ -+ /* Check for each candicate */ -+ for (i = 0; i < prAisSpecBssInfo->u4PmkidCandicateCount; i++) { -+ for (j = 0; j < prAisSpecBssInfo->u4PmkidCacheCount; j++) { -+ if (!kalMemCmp(prAisSpecBssInfo->arPmkidCache[j].rBssidInfo.arBSSID, -+ prAisSpecBssInfo->arPmkidCandicate[i].aucBssid, MAC_ADDR_LEN)) { -+ /* DBGLOG(RSN, TRACE, ("%pM at PMKID cache!!\n", -+ (prAisSpecBssInfo->arPmkidCandicate[i].aucBssid))); */ -+ break; -+ } -+ } -+ -+ /* No entry found in PMKID cache for the candicate, add new one */ -+ if (j == prAisSpecBssInfo->u4PmkidCacheCount -+ && prAisSpecBssInfo->u4PmkidCacheCount < CFG_MAX_PMKID_CACHE) { -+ DBGLOG(RSN, TRACE, -+ "Add %pM to PMKID cache!!\n", -+ (prAisSpecBssInfo->arPmkidCandicate[i].aucBssid)); -+ kalMemCopy((PVOID) prAisSpecBssInfo-> -+ arPmkidCache[prAisSpecBssInfo->u4PmkidCacheCount].rBssidInfo.arBSSID, -+ (PVOID) prAisSpecBssInfo->arPmkidCandicate[i].aucBssid, MAC_ADDR_LEN); -+ prAisSpecBssInfo->arPmkidCache[prAisSpecBssInfo->u4PmkidCacheCount].fgPmkidExist = FALSE; -+ prAisSpecBssInfo->u4PmkidCacheCount++; -+ -+ status = TRUE; -+ } -+ } -+ -+ return status; -+} /* rsnCheckPmkidCandicate */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is called to wait a duration to indicate the pre-auth AP candicate -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rsnIndicatePmkidCand(IN P_ADAPTER_T prAdapter, IN ULONG ulParm) -+{ -+ DBGLOG(RSN, EVENT, "Security - Time to indicate the PMKID cand.\n"); -+ -+ /* If the authentication mode is WPA2 and indication PMKID flag -+ is available, then we indicate the PMKID candidate list to NDIS and -+ clear the flag, indicatePMKID */ -+ -+ if (prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX].eConnectionState == PARAM_MEDIA_STATE_CONNECTED && -+ prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA2) { -+ rsnGeneratePmkidIndication(prAdapter); -+ } -+ -+} /* end of rsnIndicatePmkidCand() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to check the BSS Desc at scan result -+* with pre-auth cap at wpa2 mode. If there -+* is candicate that no cache entry is available, then -+* add a new entry for the new candicate in the PMKID cache -+* and set the PMKID indication flag to TRUE. -+* -+* \param[in] prBss The BSS Desc at scan result -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rsnCheckPmkidCache(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBss) -+{ -+ P_AIS_BSS_INFO_T prAisBssInfo; -+ P_AIS_SPECIFIC_BSS_INFO_T prAisSpecBssInfo; -+ P_CONNECTION_SETTINGS_T prConnSettings; -+ -+ DEBUGFUNC("rsnCheckPmkidCandicate"); -+ -+ ASSERT(prBss); -+ -+ prConnSettings = &prAdapter->rWifiVar.rConnSettings; -+ prAisBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]; -+ prAisSpecBssInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo; -+ -+ if ((prAisBssInfo->eConnectionState == PARAM_MEDIA_STATE_CONNECTED) && -+ (prConnSettings->eAuthMode == AUTH_MODE_WPA2)) { -+ rsnSelectPmkidCandidateList(prAdapter, prBss); -+ -+ /* Set indication flag of PMKID to TRUE, and then connHandleNetworkConnection() -+ will indicate this later */ -+ if (rsnCheckPmkidCandicate(prAdapter)) { -+ DBGLOG(RSN, TRACE, "Prepare a timer to indicate candidate PMKID Candidate\n"); -+ cnmTimerStopTimer(prAdapter, &prAisSpecBssInfo->rPreauthenticationTimer); -+ cnmTimerStartTimer(prAdapter, &prAisSpecBssInfo->rPreauthenticationTimer, -+ SEC_TO_MSEC(WAIT_TIME_IND_PMKID_CANDICATE_SEC)); -+ } -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to generate an PMKID candidate list -+* indication to NDIS. -+* -+* \param[in] prAdapter Pointer to the adapter object data area. -+* \param[in] u4Flags PMKID candidate list event: -+* PARAM_PMKID_CANDIDATE_PREAUTH_ENABLED 0x01 -+* -+* \retval none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rsnGeneratePmkidIndication(IN P_ADAPTER_T prAdapter) -+{ -+ P_PARAM_STATUS_INDICATION_T prStatusEvent; -+ P_PARAM_PMKID_CANDIDATE_LIST_T prPmkidEvent; -+ P_AIS_SPECIFIC_BSS_INFO_T prAisSpecificBssInfo; -+ UINT_8 i, j = 0, count = 0; -+ UINT_32 u4LenOfUsedBuffer; -+ -+ DEBUGFUNC("rsnGeneratePmkidIndication"); -+ -+ ASSERT(prAdapter); -+ -+ prStatusEvent = (P_PARAM_STATUS_INDICATION_T) prAdapter->aucIndicationEventBuffer; -+ -+ /* Status type: PMKID Candidatelist Event */ -+ prStatusEvent->eStatusType = ENUM_STATUS_TYPE_CANDIDATE_LIST; -+ ASSERT(prStatusEvent); -+ -+ prPmkidEvent = (P_PARAM_PMKID_CANDIDATE_LIST_T) (&prStatusEvent->eStatusType + 1); -+ ASSERT(prPmkidEvent); -+ -+ prAisSpecificBssInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo; -+ ASSERT(prAisSpecificBssInfo); -+ -+ for (i = 0; i < prAisSpecificBssInfo->u4PmkidCandicateCount; i++) { -+ for (j = 0; j < prAisSpecificBssInfo->u4PmkidCacheCount; j++) { -+ if (EQUAL_MAC_ADDR(prAisSpecificBssInfo->arPmkidCache[j].rBssidInfo.arBSSID, -+ prAisSpecificBssInfo->arPmkidCandicate[i].aucBssid) && -+ (prAisSpecificBssInfo->arPmkidCache[j].fgPmkidExist == TRUE)) { -+ break; -+ } -+ } -+ if (count >= CFG_MAX_PMKID_CACHE) -+ break; -+ -+ if (j == prAisSpecificBssInfo->u4PmkidCacheCount) { -+ kalMemCopy((PVOID) prPmkidEvent->arCandidateList[count].arBSSID, -+ (PVOID) prAisSpecificBssInfo->arPmkidCandicate[i].aucBssid, PARAM_MAC_ADDR_LEN); -+ prPmkidEvent->arCandidateList[count].u4Flags = -+ prAisSpecificBssInfo->arPmkidCandicate[i].u4PreAuthFlags; -+ DBGLOG(RSN, TRACE, "%pM %d\n", (prPmkidEvent->arCandidateList[count].arBSSID), -+ (UINT_32) prPmkidEvent->arCandidateList[count].u4Flags); -+ count++; -+ } -+ } -+ -+ /* PMKID Candidate List */ -+ prPmkidEvent->u4Version = 1; -+ prPmkidEvent->u4NumCandidates = count; -+ DBGLOG(RSN, TRACE, "rsnGeneratePmkidIndication #%d\n", (UINT_32) prPmkidEvent->u4NumCandidates); -+ u4LenOfUsedBuffer = sizeof(ENUM_STATUS_TYPE_T) + (2 * sizeof(UINT_32)) + -+ (count * sizeof(PARAM_PMKID_CANDIDATE_T)); -+ /* dumpMemory8((PUINT_8)prAdapter->aucIndicationEventBuffer, u4LenOfUsedBuffer); */ -+ -+ kalIndicateStatusAndComplete(prAdapter->prGlueInfo, -+ WLAN_STATUS_MEDIA_SPECIFIC_INDICATION, -+ (PVOID) prAdapter->aucIndicationEventBuffer, u4LenOfUsedBuffer); -+ -+} /* rsnGeneratePmkidIndication */ -+#endif -+ -+#if CFG_SUPPORT_WPS2 -+/*----------------------------------------------------------------------------*/ -+/*! -+* -+* \brief This routine is called to generate WSC IE for -+* associate request frame. -+* -+* \param[in] prCurrentBss The Selected BSS description -+* -+* \retval The append WSC IE length -+* -+* \note -+* Called by: AIS module, Associate request -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID rsnGenerateWSCIE(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo) -+{ -+ PUINT_8 pucBuffer; -+ -+ ASSERT(prAdapter); -+ ASSERT(prMsduInfo); -+ -+ if (prMsduInfo->ucNetworkType != NETWORK_TYPE_AIS_INDEX) -+ return; -+ -+ pucBuffer = (PUINT_8) ((ULONG) prMsduInfo->prPacket + (UINT_32) prMsduInfo->u2FrameLength); -+ -+ /* ASSOC INFO IE ID: 221 :0xDD */ -+ if (prAdapter->prGlueInfo->u2WSCAssocInfoIELen) { -+ kalMemCopy(pucBuffer, &prAdapter->prGlueInfo->aucWSCAssocInfoIE, -+ prAdapter->prGlueInfo->u2WSCAssocInfoIELen); -+ prMsduInfo->u2FrameLength += prAdapter->prGlueInfo->u2WSCAssocInfoIELen; -+ } -+ -+} -+#endif -+ -+#if CFG_SUPPORT_802_11W -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief to check if the Bip Key installed or not -+* -+* \param[in] -+* prAdapter -+* -+* \return -+* TRUE -+* FALSE -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT_32 rsnCheckBipKeyInstalled(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec) -+{ -+ if (prStaRec && prStaRec->ucNetTypeIndex == (UINT_8) NETWORK_TYPE_AIS_INDEX) -+ return prAdapter->rWifiVar.rAisSpecificBssInfo.fgBipKeyInstalled; -+ else -+ return FALSE; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* -+* \brief This routine is called to check the Sa query timeout. -+* -+* -+* \note -+* Called by: AIS module, Handle by Sa Quert timeout -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT_8 rsnCheckSaQueryTimeout(IN P_ADAPTER_T prAdapter) -+{ -+ P_AIS_SPECIFIC_BSS_INFO_T prBssSpecInfo; -+ UINT_32 now; -+ -+ prBssSpecInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo; -+ ASSERT(prBssSpecInfo); -+ -+ GET_CURRENT_SYSTIME(&now); -+ -+ if (CHECK_FOR_TIMEOUT(now, prBssSpecInfo->u4SaQueryStart, TU_TO_MSEC(1000))) { -+ LOG_FUNC("association SA Query timed out\n"); -+ -+ prBssSpecInfo->ucSaQueryTimedOut = 1; -+ kalMemFree(prBssSpecInfo->pucSaQueryTransId, VIR_MEM_TYPE, -+ prBssSpecInfo->u4SaQueryCount * ACTION_SA_QUERY_TR_ID_LEN); -+ prBssSpecInfo->pucSaQueryTransId = NULL; -+ prBssSpecInfo->u4SaQueryCount = 0; -+ cnmTimerStopTimer(prAdapter, &prBssSpecInfo->rSaQueryTimer); -+ /* Re-connect */ -+ DBGLOG(RSN, TRACE, "DisBy11w\n"); -+ kalIndicateStatusAndComplete(prAdapter->prGlueInfo, WLAN_STATUS_MEDIA_DISCONNECT, NULL, 0); -+ -+ return 1; -+ } -+ -+ return 0; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* -+* \brief This routine is called to start the 802.11w sa query timer. -+* -+* -+* \note -+* Called by: AIS module, Handle Rx mgmt request -+*/ -+/*----------------------------------------------------------------------------*/ -+void rsnStartSaQueryTimer(IN P_ADAPTER_T prAdapter) -+{ -+ P_BSS_INFO_T prBssInfo; -+ P_AIS_SPECIFIC_BSS_INFO_T prBssSpecInfo; -+ P_MSDU_INFO_T prMsduInfo; -+ P_ACTION_SA_QUERY_FRAME prTxFrame; -+ UINT_16 u2PayloadLen; -+ PUINT_8 pucTmp = NULL; -+ UINT_8 ucTransId[ACTION_SA_QUERY_TR_ID_LEN]; -+ -+ prBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]; -+ ASSERT(prBssInfo); -+ -+ prBssSpecInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo; -+ ASSERT(prBssSpecInfo); -+ -+ LOG_FUNC("MFP: Start Sa Query\n"); -+ -+ if (prBssSpecInfo->u4SaQueryCount > 0 && rsnCheckSaQueryTimeout(prAdapter)) { -+ LOG_FUNC("MFP: u4SaQueryCount count =%d\n", prBssSpecInfo->u4SaQueryCount); -+ return; -+ } -+ -+ prMsduInfo = (P_MSDU_INFO_T) cnmMgtPktAlloc(prAdapter, MAC_TX_RESERVED_FIELD + PUBLIC_ACTION_MAX_LEN); -+ -+ if (!prMsduInfo) -+ return; -+ -+ prTxFrame = (P_ACTION_SA_QUERY_FRAME) -+ ((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD); -+ -+ prTxFrame->u2FrameCtrl = MAC_FRAME_ACTION; -+ prTxFrame->u2FrameCtrl |= MASK_FC_PROTECTED_FRAME; -+ -+ COPY_MAC_ADDR(prTxFrame->aucDestAddr, prBssInfo->aucBSSID); -+ COPY_MAC_ADDR(prTxFrame->aucSrcAddr, prBssInfo->aucOwnMacAddr); -+ COPY_MAC_ADDR(prTxFrame->aucBSSID, prBssInfo->aucBSSID); -+ -+ prTxFrame->ucCategory = CATEGORY_SA_QUERT_ACTION; -+ prTxFrame->ucAction = ACTION_SA_QUERY_REQUEST; -+ -+ if (prBssSpecInfo->u4SaQueryCount == 0) -+ GET_CURRENT_SYSTIME(&prBssSpecInfo->u4SaQueryStart); -+ -+ if (prBssSpecInfo->u4SaQueryCount) { -+ pucTmp = kalMemAlloc(prBssSpecInfo->u4SaQueryCount * ACTION_SA_QUERY_TR_ID_LEN, VIR_MEM_TYPE); -+ if (!pucTmp) { -+ DBGLOG(RSN, ERROR, "MFP: Fail to alloc tmp buffer for backup sa query id\n"); -+ return; -+ } -+ kalMemCopy(pucTmp, prBssSpecInfo->pucSaQueryTransId, -+ prBssSpecInfo->u4SaQueryCount * ACTION_SA_QUERY_TR_ID_LEN); -+ } -+ -+ kalMemFree(prBssSpecInfo->pucSaQueryTransId, VIR_MEM_TYPE, -+ prBssSpecInfo->u4SaQueryCount * ACTION_SA_QUERY_TR_ID_LEN); -+ -+ ucTransId[0] = (UINT_8) (kalRandomNumber() & 0xFF); -+ ucTransId[1] = (UINT_8) (kalRandomNumber() & 0xFF); -+ -+ kalMemCopy(prTxFrame->ucTransId, ucTransId, ACTION_SA_QUERY_TR_ID_LEN); -+ -+ prBssSpecInfo->u4SaQueryCount++; -+ -+ prBssSpecInfo->pucSaQueryTransId = -+ kalMemAlloc(prBssSpecInfo->u4SaQueryCount * ACTION_SA_QUERY_TR_ID_LEN, VIR_MEM_TYPE); -+ if (!prBssSpecInfo->pucSaQueryTransId) { -+ DBGLOG(RSN, ERROR, "MFP: Fail to alloc buffer for sa query id list\n"); -+ return; -+ } -+ -+ if (pucTmp) { -+ kalMemCopy(prBssSpecInfo->pucSaQueryTransId, pucTmp, -+ (prBssSpecInfo->u4SaQueryCount - 1) * ACTION_SA_QUERY_TR_ID_LEN); -+ kalMemCopy(&prBssSpecInfo->pucSaQueryTransId -+ [(prBssSpecInfo->u4SaQueryCount - 1) * ACTION_SA_QUERY_TR_ID_LEN], ucTransId, -+ ACTION_SA_QUERY_TR_ID_LEN); -+ kalMemFree(pucTmp, VIR_MEM_TYPE, (prBssSpecInfo->u4SaQueryCount - 1) * ACTION_SA_QUERY_TR_ID_LEN); -+ } else { -+ kalMemCopy(prBssSpecInfo->pucSaQueryTransId, ucTransId, ACTION_SA_QUERY_TR_ID_LEN); -+ } -+ -+ u2PayloadLen = 2 + ACTION_SA_QUERY_TR_ID_LEN; -+ -+ /* 4 Update information of MSDU_INFO_T */ -+ prMsduInfo->ucPacketType = HIF_TX_PACKET_TYPE_MGMT; /* Management frame */ -+ prMsduInfo->ucStaRecIndex = prBssInfo->prStaRecOfAP->ucIndex; -+ prMsduInfo->ucNetworkType = prBssInfo->ucNetTypeIndex; -+ prMsduInfo->ucMacHeaderLength = WLAN_MAC_MGMT_HEADER_LEN; -+ prMsduInfo->fgIs802_1x = FALSE; -+ prMsduInfo->fgIs802_11 = TRUE; -+ prMsduInfo->u2FrameLength = WLAN_MAC_MGMT_HEADER_LEN + u2PayloadLen; -+ prMsduInfo->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter); -+ prMsduInfo->pfTxDoneHandler = NULL; -+ prMsduInfo->fgIsBasicRate = FALSE; -+ -+ /* 4 Enqueue the frame to send this action frame. */ -+ nicTxEnqueueMsdu(prAdapter, prMsduInfo); -+ -+ DBGLOG(RSN, TRACE, -+ "Set SA Query timer %d (%d sec)\n", prBssSpecInfo->u4SaQueryCount, prBssInfo->u2ObssScanInterval); -+ -+ cnmTimerStartTimer(prAdapter, &prBssSpecInfo->rSaQueryTimer, TU_TO_MSEC(201)); -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* -+* \brief This routine is called to start the 802.11w sa query. -+* -+* -+* \note -+* Called by: AIS module, Handle Rx mgmt request -+*/ -+/*----------------------------------------------------------------------------*/ -+void rsnStartSaQuery(IN P_ADAPTER_T prAdapter) -+{ -+ rsnStartSaQueryTimer(prAdapter); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* -+* \brief This routine is called to stop the 802.11w sa query. -+* -+* -+* \note -+* Called by: AIS module, Handle Rx mgmt request -+*/ -+/*----------------------------------------------------------------------------*/ -+void rsnStopSaQuery(IN P_ADAPTER_T prAdapter) -+{ -+ P_AIS_SPECIFIC_BSS_INFO_T prBssSpecInfo; -+ -+ prBssSpecInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo; -+ ASSERT(prBssSpecInfo); -+ -+ cnmTimerStopTimer(prAdapter, &prBssSpecInfo->rSaQueryTimer); -+ kalMemFree(prBssSpecInfo->pucSaQueryTransId, VIR_MEM_TYPE, -+ prBssSpecInfo->u4SaQueryCount * ACTION_SA_QUERY_TR_ID_LEN); -+ prBssSpecInfo->pucSaQueryTransId = NULL; -+ prBssSpecInfo->u4SaQueryCount = 0; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* -+* \brief This routine is called to process the 802.11w sa query action frame. -+* -+* -+* \note -+* Called by: AIS module, Handle Rx mgmt request -+*/ -+/*----------------------------------------------------------------------------*/ -+void rsnSaQueryRequest(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb) -+{ -+ P_BSS_INFO_T prBssInfo; -+ P_MSDU_INFO_T prMsduInfo; -+ P_ACTION_SA_QUERY_FRAME prRxFrame = NULL; -+ UINT_16 u2PayloadLen; -+ P_STA_RECORD_T prStaRec; -+ P_ACTION_SA_QUERY_FRAME prTxFrame; -+ -+ prBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]; -+ ASSERT(prBssInfo); -+ -+ prRxFrame = (P_ACTION_SA_QUERY_FRAME) prSwRfb->pvHeader; -+ if (!prRxFrame) -+ return; -+ -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); -+ -+ DBGLOG(RSN, TRACE, "IEEE 802.11: Received SA Query Request from %pM\n", prStaRec->aucMacAddr); -+ -+ DBGLOG_MEM8(RSN, TRACE, prRxFrame->ucTransId, ACTION_SA_QUERY_TR_ID_LEN); -+ -+ if (kalGetMediaStateIndicated(prAdapter->prGlueInfo) == PARAM_MEDIA_STATE_DISCONNECTED) { -+ DBGLOG(RSN, TRACE, "IEEE 802.11: Ignore SA Query Request from unassociated STA %pM\n", -+ prStaRec->aucMacAddr); -+ return; -+ } -+ DBGLOG(RSN, TRACE, "IEEE 802.11: Sending SA Query Response to %pM\n", prStaRec->aucMacAddr); -+ -+ prMsduInfo = (P_MSDU_INFO_T) cnmMgtPktAlloc(prAdapter, MAC_TX_RESERVED_FIELD + PUBLIC_ACTION_MAX_LEN); -+ -+ if (!prMsduInfo) -+ return; -+ -+ prTxFrame = (P_ACTION_SA_QUERY_FRAME) -+ ((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD); -+ -+ prTxFrame->u2FrameCtrl = MAC_FRAME_ACTION; -+ /* SA Query always with protected */ -+ prTxFrame->u2FrameCtrl |= MASK_FC_PROTECTED_FRAME; -+ -+ COPY_MAC_ADDR(prTxFrame->aucDestAddr, prBssInfo->aucBSSID); -+ COPY_MAC_ADDR(prTxFrame->aucSrcAddr, prBssInfo->aucOwnMacAddr); -+ COPY_MAC_ADDR(prTxFrame->aucBSSID, prBssInfo->aucBSSID); -+ -+ prTxFrame->ucCategory = CATEGORY_SA_QUERT_ACTION; -+ prTxFrame->ucAction = ACTION_SA_QUERY_RESPONSE; -+ -+ kalMemCopy(prTxFrame->ucTransId, prRxFrame->ucTransId, ACTION_SA_QUERY_TR_ID_LEN); -+ -+ u2PayloadLen = 2 + ACTION_SA_QUERY_TR_ID_LEN; -+ -+ /* 4 Update information of MSDU_INFO_T */ -+ prMsduInfo->ucPacketType = HIF_TX_PACKET_TYPE_MGMT; /* Management frame */ -+ prMsduInfo->ucStaRecIndex = prBssInfo->prStaRecOfAP->ucIndex; -+ prMsduInfo->ucNetworkType = prBssInfo->ucNetTypeIndex; -+ prMsduInfo->ucMacHeaderLength = WLAN_MAC_MGMT_HEADER_LEN; -+ prMsduInfo->fgIs802_1x = FALSE; -+ prMsduInfo->fgIs802_11 = TRUE; -+ prMsduInfo->u2FrameLength = WLAN_MAC_MGMT_HEADER_LEN + u2PayloadLen; -+ prMsduInfo->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter); -+ prMsduInfo->pfTxDoneHandler = NULL; -+ prMsduInfo->fgIsBasicRate = FALSE; -+ -+ /* 4 Enqueue the frame to send this action frame. */ -+ nicTxEnqueueMsdu(prAdapter, prMsduInfo); -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* -+* \brief This routine is called to process the 802.11w sa query action frame. -+* -+* -+* \note -+* Called by: AIS module, Handle Rx mgmt request -+*/ -+/*----------------------------------------------------------------------------*/ -+void rsnSaQueryAction(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb) -+{ -+ P_AIS_SPECIFIC_BSS_INFO_T prBssSpecInfo; -+ P_ACTION_SA_QUERY_FRAME prRxFrame; -+ P_STA_RECORD_T prStaRec; -+ UINT_32 i; -+ -+ prBssSpecInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo; -+ ASSERT(prBssSpecInfo); -+ -+ prRxFrame = (P_ACTION_SA_QUERY_FRAME) prSwRfb->pvHeader; -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); -+ -+ if (prSwRfb->u2PacketLen < ACTION_SA_QUERY_TR_ID_LEN) { -+ DBGLOG(RSN, TRACE, "IEEE 802.11: Too short SA Query Action frame (len=%u)\n", -+ prSwRfb->u2PacketLen); -+ return; -+ } -+ -+ if (prRxFrame->ucAction == ACTION_SA_QUERY_REQUEST) { -+ rsnSaQueryRequest(prAdapter, prSwRfb); -+ return; -+ } -+ -+ if (prRxFrame->ucAction != ACTION_SA_QUERY_RESPONSE) { -+ DBGLOG(RSN, TRACE, "IEEE 802.11: Unexpected SA Query " "Action %d\n", prRxFrame->ucAction); -+ return; -+ } -+ -+ DBGLOG(RSN, TRACE, "IEEE 802.11: Received SA Query Response from %pM\n", prStaRec->aucMacAddr); -+ -+ DBGLOG_MEM8(RSN, TRACE, prRxFrame->ucTransId, ACTION_SA_QUERY_TR_ID_LEN); -+ -+ /* MLME-SAQuery.confirm */ -+ -+ for (i = 0; i < prBssSpecInfo->u4SaQueryCount; i++) { -+ if (kalMemCmp(prBssSpecInfo->pucSaQueryTransId + -+ i * ACTION_SA_QUERY_TR_ID_LEN, prRxFrame->ucTransId, ACTION_SA_QUERY_TR_ID_LEN) == 0) -+ break; -+ } -+ -+ if (i >= prBssSpecInfo->u4SaQueryCount) { -+ DBGLOG(RSN, TRACE, "IEEE 802.11: No matching SA Query " "transaction identifier found\n"); -+ return; -+ } -+ -+ DBGLOG(RSN, TRACE, "Reply to pending SA Query received\n"); -+ -+ rsnStopSaQuery(prAdapter); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* -+* \brief This routine is called to process the 802.11w mgmt frame. -+* -+* -+* \note -+* Called by: AIS module, Handle Rx mgmt request -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN rsnCheckRxMgmt(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, IN UINT_8 ucSubtype) -+{ -+ P_HIF_RX_HEADER_T prHifRxHdr; -+ BOOLEAN fgUnicast = TRUE; -+ BOOLEAN fgRobustAction = FALSE; -+ -+ prHifRxHdr = prSwRfb->prHifRxHdr; -+ -+ if ((HIF_RX_HDR_GET_NETWORK_IDX(prHifRxHdr) == NETWORK_TYPE_AIS_INDEX) && -+ prAdapter->rWifiVar.rAisSpecificBssInfo.fgMgmtProtection /* Use MFP */) { -+ -+ P_WLAN_ASSOC_REQ_FRAME_T prAssocReqFrame; -+ -+ prAssocReqFrame = (P_WLAN_ASSOC_REQ_FRAME_T) prSwRfb->pvHeader; -+ -+ if (prAssocReqFrame->aucDestAddr[0] & BIT(0)) -+ fgUnicast = FALSE; -+ -+ LOG_FUNC("QM RX MGT: rsnCheckRxMgmt = %d 0x%x %d ucSubtype=%x\n", fgUnicast, prHifRxHdr->ucReserved, -+ (prHifRxHdr->ucReserved & CONTROL_FLAG_UC_MGMT_NO_ENC), ucSubtype); -+ -+ if (prHifRxHdr->ucReserved & CONTROL_FLAG_UC_MGMT_NO_ENC) { -+ /* "Dropped unprotected Robust Action frame from an MFP STA" */ -+ /* exclude Public Action */ -+ if (ucSubtype == 13 /* 0x1011: MAC_FRAME_ACTION */) { -+ UINT_8 ucAction = *prSwRfb->pucRecvBuff; -+ -+ if (ucAction != CATEGORY_PUBLIC_ACTION && ucAction != CATEGORY_HT_ACTION) { -+#if DBG && CFG_RX_PKTS_DUMP -+ LOG_FUNC("QM RX MGT: UnProtected Robust Action frame = %d\n", ucAction); -+#endif -+ fgRobustAction = TRUE; -+ return TRUE; -+ } -+ } -+ if (fgUnicast && ((ucSubtype == 10 /* 0x1010: MAC_FRAME_DISASSOC */) -+ || (ucSubtype == 12 /* 0x1100: MAC_FRAME_DEAUTH */))) { -+ LOG_FUNC("QM RX MGT: rsnStartSaQuery\n"); -+ /* MFP test plan 5.3.3.5 */ -+ rsnStartSaQuery(prAdapter); -+ return TRUE; -+ } -+ } -+#if 0 -+ else { -+ if (fgUnicast && ((ucSubtype == MAC_FRAME_DISASSOC) || (ucSubtype == MAC_FRAME_DEAUTH))) { -+ /* This done by function handler */ -+ /* kalIndicateStatusAndComplete(prAdapter->prGlueInfo, */ -+ /* WLAN_STATUS_MEDIA_DISCONNECT, */ -+ /* NULL, */ -+ /* 0); */ -+ } -+ } -+#endif -+ } -+ return FALSE; -+} -+#endif -+ -+#if CFG_SUPPORT_DETECT_SECURITY_MODE_CHANGE -+static BOOLEAN rsnCheckWpaRsnInfo(P_BSS_INFO_T prBss, P_RSN_INFO_T prWpaRsnInfo) -+{ -+ UINT_32 i = 0; -+ -+ if (prWpaRsnInfo->u4GroupKeyCipherSuite != prBss->u4RsnSelectedGroupCipher) { -+ DBGLOG(RSN, INFO, "GroupCipherSuite change, old=0x%04x, new=0x%04x\n", -+ prBss->u4RsnSelectedGroupCipher, prWpaRsnInfo->u4GroupKeyCipherSuite); -+ return TRUE; -+ } -+ for (; i < prWpaRsnInfo->u4AuthKeyMgtSuiteCount; i++) -+ if (prBss->u4RsnSelectedAKMSuite == prWpaRsnInfo->au4AuthKeyMgtSuite[i]) -+ break; -+ if (i == prWpaRsnInfo->u4AuthKeyMgtSuiteCount) { -+ DBGLOG(RSN, INFO, "KeyMgmt change, not find 0x%04x in new beacon\n", prBss->u4RsnSelectedAKMSuite); -+ return TRUE; -+ } -+ -+ for (i = 0; i < prWpaRsnInfo->u4PairwiseKeyCipherSuiteCount; i++) -+ if (prBss->u4RsnSelectedPairwiseCipher == prWpaRsnInfo->au4PairwiseKeyCipherSuite[i]) -+ break; -+ if (i == prWpaRsnInfo->u4PairwiseKeyCipherSuiteCount) { -+ DBGLOG(RSN, INFO, "Pairwise Cipher change, not find 0x%04x in new beacon\n", -+ prBss->u4RsnSelectedPairwiseCipher); -+ return TRUE; -+ } -+ -+ return FALSE; -+} -+ -+BOOLEAN rsnCheckSecurityModeChanged(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo, P_BSS_DESC_T prBssDesc) -+{ -+ ENUM_PARAM_AUTH_MODE_T eAuthMode = prAdapter->rWifiVar.rConnSettings.eAuthMode; -+ -+ switch (eAuthMode) { -+ case AUTH_MODE_OPEN: /* original is open system */ -+ if ((prBssDesc->u2CapInfo & CAP_INFO_PRIVACY) && !prAdapter->prGlueInfo->rWpaInfo.fgPrivacyInvoke) { -+ DBGLOG(RSN, INFO, "security change, open->privacy\n"); -+ return TRUE; -+ } -+ break; -+ case AUTH_MODE_SHARED: /* original is WEP */ -+ case AUTH_MODE_AUTO_SWITCH: -+ if ((prBssDesc->u2CapInfo & CAP_INFO_PRIVACY) == 0) { -+ DBGLOG(RSN, INFO, "security change, WEP->open\n"); -+ return TRUE; -+ } else if (prBssDesc->fgIERSN || prBssDesc->fgIEWPA) { -+ DBGLOG(RSN, INFO, "security change, WEP->WPA/WPA2\n"); -+ return TRUE; -+ } -+ break; -+ case AUTH_MODE_WPA: /*original is WPA */ -+ case AUTH_MODE_WPA_PSK: -+ case AUTH_MODE_WPA_NONE: -+ if (prBssDesc->fgIEWPA) -+ return rsnCheckWpaRsnInfo(prBssInfo, &prBssDesc->rWPAInfo); -+ DBGLOG(RSN, INFO, "security change, WPA->%s\n", -+ prBssDesc->fgIERSN ? "WPA2" : -+ (prBssDesc->u2CapInfo & CAP_INFO_PRIVACY ? "WEP" : "OPEN")); -+ return TRUE; -+ case AUTH_MODE_WPA2: /*original is WPA2 */ -+ case AUTH_MODE_WPA2_PSK: -+ if (prBssDesc->fgIERSN) -+ return rsnCheckWpaRsnInfo(prBssInfo, &prBssDesc->rRSNInfo); -+ DBGLOG(RSN, INFO, "security change, WPA2->%s\n", -+ prBssDesc->fgIEWPA ? "WPA" : -+ (prBssDesc->u2CapInfo & CAP_INFO_PRIVACY ? "WEP" : "OPEN")); -+ return TRUE; -+ default: -+ DBGLOG(RSN, WARN, "unknowned eAuthMode=%d\n", eAuthMode); -+ break; -+ } -+ /*DBGLOG(RSN, INFO, ("rsnCheckSecurityModeChanged, eAuthMode=%d, u2CapInfo=0x%02x, fgIEWPA=%d, fgIERSN=%d\n", -+ eAuthMode, prBssDesc->u2CapInfo, prBssDesc->fgIEWPA, prBssDesc->fgIERSN)); */ -+ return FALSE; -+} -+#endif -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/saa_fsm.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/saa_fsm.c -new file mode 100644 -index 000000000000..596ede60d788 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/saa_fsm.c -@@ -0,0 +1,1788 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/saa_fsm.c#2 -+*/ -+ -+/*! \file "saa_fsm.c" -+ \brief This file defines the FSM for SAA MODULE. -+ -+ This file defines the FSM for SAA MODULE. -+*/ -+ -+/* -+** Log: saa_fsm.c -+** -+** 09 04 2013 cp.wu -+** fix typo -+** -+** 09 03 2013 cp.wu -+** add path for reassociation -+ * -+ * 07 17 2012 yuche.tsai -+ * NULL -+ * Compile no error before trial run. -+ * -+ * 04 20 2012 cp.wu -+ * [WCXRP00000913] [MT6620 Wi-Fi] create repository of source code dedicated for MT6620 E6 ASIC -+ * correct macro -+ * -+ * 11 24 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * Adjust code for DBG and CONFIG_XLOG. -+ * -+ * 11 11 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * modify the xlog related code. -+ * -+ * 11 04 2011 cp.wu -+ * [WCXRP00001086] [MT6620 Wi-Fi][Driver] On Android, indicate an extra DISCONNECT -+ * for REASSOCIATED cases as an explicit trigger for Android framework -+ * 1. for DEAUTH/DISASSOC cases, indicate for DISCONNECTION immediately. -+ * 2. (Android only) when reassociation-and-non-roaming cases happened, -+ * indicate an extra DISCONNECT indication to Android Wi-Fi framework -+ * -+ * 11 02 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * adding the code for XLOG. -+ * -+ * 09 30 2011 cm.chang -+ * [WCXRP00001020] [MT6620 Wi-Fi][Driver] Handle secondary channel offset of AP in 5GHz band -+ * Add debug message about 40MHz bandwidth allowed -+ * -+ * 05 12 2011 cp.wu -+ * [WCXRP00000720] [MT6620 Wi-Fi][Driver] Do not do any further operation in case STA-REC -+ * has been invalidated before SAA-FSM starts to roll -+ * check for valid STA-REC before SAA-FSM starts to roll. -+ * -+ * 04 21 2011 terry.wu -+ * [WCXRP00000674] [MT6620 Wi-Fi][Driver] Refine AAA authSendAuthFrame -+ * Add network type parameter to authSendAuthFrame. -+ * -+ * 04 15 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Add BOW short range mode. -+ * -+ * 04 14 2011 cm.chang -+ * [WCXRP00000634] [MT6620 Wi-Fi][Driver][FW] 2nd BSS will not support 40MHz bandwidth for concurrency -+ * . -+ * -+ * 03 31 2011 puff.wen -+ * NULL -+ * . -+ * -+ * 02 10 2011 yuche.tsai -+ * [WCXRP00000431] [Volunteer Patch][MT6620][Driver] Add MLME support for deauthentication under AP(Hot-Spot) mode. -+ * Add RX deauthentication & disassociation process under Hot-Spot mode. -+ * -+ * 01 26 2011 yuche.tsai -+ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record. -+ * . -+ * -+ * 01 25 2011 yuche.tsai -+ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record. -+ * Fix compile error of after Station Type Macro modification. -+ * -+ * 01 25 2011 yuche.tsai -+ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record. -+ * Change Station Type in Station Record, Modify MACRO definition for getting station type & network type index & Role. -+ * -+ * 11 29 2010 cp.wu -+ * [WCXRP00000210] [MT6620 Wi-Fi][Driver][FW] Set RCPI value in STA_REC -+ * for initial TX rate selection of auto-rate algorithm -+ * update ucRcpi of STA_RECORD_T for AIS when -+ * 1) Beacons for IBSS merge is received -+ * 2) Associate Response for a connecting peer is received -+ * -+ * 10 18 2010 cp.wu -+ * [WCXRP00000053] [MT6620 Wi-Fi][Driver] Reset incomplete -+ * and might leads to BSOD when entering RF test with AIS associated -+ * 1. remove redundant variables in STA_REC structure -+ * 2. add STA-REC uninitialization routine for clearing pending events -+ * -+ * 09 03 2010 kevin.huang -+ * NULL -+ * Refine #include sequence and solve recursive/nested #include issue -+ * -+ * 08 30 2010 cp.wu -+ * NULL -+ * eliminate klockwork errors -+ * -+ * 08 24 2010 chinghwa.yu -+ * NULL -+ * Update for MID_SCN_BOW_SCAN_DONE mboxDummy. -+ * Update saa_fsm for BOW. -+ * -+ * 08 16 2010 cp.wu -+ * NULL -+ * Replace CFG_SUPPORT_BOW by CFG_ENABLE_BT_OVER_WIFI. -+ * There is no CFG_SUPPORT_BOW in driver domain source. -+ * -+ * 08 02 2010 yuche.tsai -+ * NULL -+ * Add support for P2P join event start. -+ * -+ * 07 12 2010 cp.wu -+ * -+ * SAA will take a record for tracking request sequence number. -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 07 01 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * AIS-FSM integration with CNM channel request messages -+ * -+ * 06 23 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * sync. with main branch for resetting to state 1 when associating with another AP -+ * -+ * 06 21 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * refine TX-DONE callback. -+ * -+ * 06 21 2010 wh.su -+ * [WPD00003840][MT6620 5931] Security migration -+ * remove duplicate variable for migration. -+ * -+ * 06 18 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Provide cnmMgtPktAlloc() and alloc/free function of msg/buf -+ * -+ * 06 18 2010 wh.su -+ * [WPD00003840][MT6620 5931] Security migration -+ * migration the security related function from firmware. -+ * -+ * 06 17 2010 yuche.tsai -+ * [WPD00003839][MT6620 5931][P2P] Feature migration -+ * Fix compile error when enable WiFi Direct function. -+ * -+ * 06 14 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * saa_fsm.c is migrated. -+ * -+ * 05 12 2010 kevin.huang -+ * [BORA00000794][WIFISYS][New Feature]Power Management Support -+ * Add Power Management - Legacy PS-POLL support. -+ * -+ * 04 24 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * g_aprBssInfo[] depends on CFG_SUPPORT_P2P and CFG_SUPPORT_BOW -+ * -+ * 04 19 2010 kevin.huang -+ * [BORA00000714][WIFISYS][New Feature]Beacon Timeout Support -+ * -+ * * * Add Connection Policy - Any and Rx Burst Deauth Support for WHQL -+ * -+ * 03 10 2010 kevin.huang -+ * [BORA00000654][WIFISYS][New Feature] CNM Module - Ch Manager Support -+ * Add Channel Manager for arbitration of JOIN and SCAN Req -+ * -+ * 02 26 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Add support of Driver STA_RECORD_T activation -+ * -+ * 02 04 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Add AAA Module Support, Revise Net Type to Net Type Index for array lookup -+ * -+ * 01 27 2010 wh.su -+ * [BORA00000476][Wi-Fi][firmware] Add the security module initialize code -+ * add and fixed some security function. -+ * -+ * 01 12 2010 kevin.huang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Fix compile warning due to declared but not used -+ * -+ * 01 11 2010 kevin.huang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Add Deauth and Disassoc Handler -+ * -+ * 01 08 2010 kevin.huang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Refine Debug Label -+ * -+ * 12 18 2009 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * . -+ * -+ * Dec 3 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Update comment -+ * -+ * Dec 1 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * rename the function -+ * -+ * Nov 24 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Revise MGMT Handler with Retain Status -+ * -+ * Nov 23 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "precomp.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+#if DBG -+/*lint -save -e64 Type mismatch */ -+static PUINT_8 apucDebugAAState[AA_STATE_NUM] = { -+ (PUINT_8) DISP_STRING("AA_STATE_IDLE"), -+ (PUINT_8) DISP_STRING("SAA_STATE_SEND_AUTH1"), -+ (PUINT_8) DISP_STRING("SAA_STATE_WAIT_AUTH2"), -+ (PUINT_8) DISP_STRING("SAA_STATE_SEND_AUTH3"), -+ (PUINT_8) DISP_STRING("SAA_STATE_WAIT_AUTH4"), -+ (PUINT_8) DISP_STRING("SAA_STATE_SEND_ASSOC1"), -+ (PUINT_8) DISP_STRING("SAA_STATE_WAIT_ASSOC2"), -+ (PUINT_8) DISP_STRING("AAA_STATE_SEND_AUTH2"), -+ (PUINT_8) DISP_STRING("AAA_STATE_SEND_AUTH4"), -+ (PUINT_8) DISP_STRING("AAA_STATE_SEND_ASSOC2"), -+ (PUINT_8) DISP_STRING("AA_STATE_RESOURCE") -+}; -+ -+/*lint -restore */ -+#endif /* DBG */ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief The Core FSM engine of SAA Module. -+* -+* @param[in] prStaRec Pointer to the STA_RECORD_T -+* @param[in] eNextState The value of Next State -+* @param[in] prRetainedSwRfb Pointer to the retained SW_RFB_T for JOIN Success -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+saaFsmSteps(IN P_ADAPTER_T prAdapter, -+ IN P_STA_RECORD_T prStaRec, IN ENUM_AA_STATE_T eNextState, IN P_SW_RFB_T prRetainedSwRfb) -+{ -+ ENUM_AA_STATE_T ePreviousState; -+ BOOLEAN fgIsTransition; -+ -+ ASSERT(prStaRec); -+ if (!prStaRec) { -+ return; -+ } -+ -+ do { -+ -+#if DBG -+ DBGLOG(SAA, STATE, "TRANSITION: [%s] -> [%s]\n", -+ apucDebugAAState[prStaRec->eAuthAssocState], apucDebugAAState[eNextState]); -+#else -+ DBGLOG(SAA, STATE, "[%d] TRANSITION: [%d] -> [%d]\n", -+ DBG_SAA_IDX, prStaRec->eAuthAssocState, eNextState); -+#endif -+ ePreviousState = prStaRec->eAuthAssocState; -+ -+ /* NOTE(Kevin): This is the only place to change the eAuthAssocState(except initial) */ -+ prStaRec->eAuthAssocState = eNextState; -+ -+ fgIsTransition = (BOOLEAN) FALSE; -+ switch (prStaRec->eAuthAssocState) { -+ case AA_STATE_IDLE: -+ if (ePreviousState != prStaRec->eAuthAssocState) { /* Only trigger this event once */ -+ -+ if (prRetainedSwRfb) { -+ if (saaFsmSendEventJoinComplete(prAdapter, -+ WLAN_STATUS_SUCCESS, -+ prStaRec, -+ prRetainedSwRfb) == WLAN_STATUS_SUCCESS) { -+ /* Do nothing */ -+ } else { -+ eNextState = AA_STATE_RESOURCE; -+ fgIsTransition = TRUE; -+ } -+ } else { -+ if (saaFsmSendEventJoinComplete(prAdapter, -+ WLAN_STATUS_FAILURE, -+ prStaRec, -+ NULL) == WLAN_STATUS_RESOURCES) { -+ eNextState = AA_STATE_RESOURCE; -+ fgIsTransition = TRUE; -+ } -+ } -+ -+ } -+ -+ /* Free allocated TCM memory */ -+ if (prStaRec->prChallengeText) { -+ cnmMemFree(prAdapter, prStaRec->prChallengeText); -+ prStaRec->prChallengeText = (P_IE_CHALLENGE_TEXT_T) NULL; -+ } -+ break; -+ -+ case SAA_STATE_SEND_AUTH1: -+ { -+ /* Do tasks in INIT STATE */ -+ if (prStaRec->ucTxAuthAssocRetryCount >= prStaRec->ucTxAuthAssocRetryLimit) { -+ -+ /* Record the Status Code of Authentication Request */ -+ prStaRec->u2StatusCode = STATUS_CODE_AUTH_TIMEOUT; -+ -+ eNextState = AA_STATE_IDLE; -+ fgIsTransition = TRUE; -+ } else { -+ prStaRec->ucTxAuthAssocRetryCount++; -+ -+ /* Update Station Record - Class 1 Flag */ -+ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); -+ -+#if !CFG_SUPPORT_AAA -+ if (authSendAuthFrame(prAdapter, -+ prStaRec, AUTH_TRANSACTION_SEQ_1) != WLAN_STATUS_SUCCESS) { -+#else -+ if (authSendAuthFrame(prAdapter, -+ prStaRec, -+ prStaRec->ucNetTypeIndex, -+ NULL, -+ AUTH_TRANSACTION_SEQ_1, -+ STATUS_CODE_RESERVED) != WLAN_STATUS_SUCCESS) { -+#endif /* CFG_SUPPORT_AAA */ -+ cnmTimerInitTimer(prAdapter, -+ &prStaRec->rTxReqDoneOrRxRespTimer, -+ (PFN_MGMT_TIMEOUT_FUNC) saaFsmRunEventTxReqTimeOut, -+ (ULONG) prStaRec); -+ -+ cnmTimerStartTimer(prAdapter, -+ &prStaRec->rTxReqDoneOrRxRespTimer, -+ TU_TO_MSEC(TX_AUTHENTICATION_RETRY_TIMEOUT_TU)); -+ } -+ } -+ } -+ break; -+ -+ case SAA_STATE_WAIT_AUTH2: -+ break; -+ -+ case SAA_STATE_SEND_AUTH3: -+ { -+ /* Do tasks in INIT STATE */ -+ if (prStaRec->ucTxAuthAssocRetryCount >= prStaRec->ucTxAuthAssocRetryLimit) { -+ -+ /* Record the Status Code of Authentication Request */ -+ prStaRec->u2StatusCode = STATUS_CODE_AUTH_TIMEOUT; -+ -+ eNextState = AA_STATE_IDLE; -+ fgIsTransition = TRUE; -+ } else { -+ prStaRec->ucTxAuthAssocRetryCount++; -+ -+#if !CFG_SUPPORT_AAA -+ if (authSendAuthFrame(prAdapter, -+ prStaRec, AUTH_TRANSACTION_SEQ_3) != WLAN_STATUS_SUCCESS) { -+#else -+ if (authSendAuthFrame(prAdapter, -+ prStaRec, -+ prStaRec->ucNetTypeIndex, -+ NULL, -+ AUTH_TRANSACTION_SEQ_3, -+ STATUS_CODE_RESERVED) != WLAN_STATUS_SUCCESS) { -+#endif /* CFG_SUPPORT_AAA */ -+ -+ cnmTimerInitTimer(prAdapter, -+ &prStaRec->rTxReqDoneOrRxRespTimer, -+ (PFN_MGMT_TIMEOUT_FUNC) saaFsmRunEventTxReqTimeOut, -+ (ULONG) prStaRec); -+ -+ cnmTimerStartTimer(prAdapter, -+ &prStaRec->rTxReqDoneOrRxRespTimer, -+ TU_TO_MSEC(TX_AUTHENTICATION_RETRY_TIMEOUT_TU)); -+ } -+ } -+ } -+ break; -+ -+ case SAA_STATE_WAIT_AUTH4: -+ break; -+ -+ case SAA_STATE_SEND_ASSOC1: -+ /* Do tasks in INIT STATE */ -+ if (prStaRec->ucTxAuthAssocRetryCount >= prStaRec->ucTxAuthAssocRetryLimit) { -+ -+ /* Record the Status Code of Authentication Request */ -+ prStaRec->u2StatusCode = STATUS_CODE_ASSOC_TIMEOUT; -+ -+ eNextState = AA_STATE_IDLE; -+ fgIsTransition = TRUE; -+ } else { -+ prStaRec->ucTxAuthAssocRetryCount++; -+ -+ if (assocSendReAssocReqFrame(prAdapter, prStaRec) != WLAN_STATUS_SUCCESS) { -+ -+ cnmTimerInitTimer(prAdapter, -+ &prStaRec->rTxReqDoneOrRxRespTimer, -+ (PFN_MGMT_TIMEOUT_FUNC) saaFsmRunEventTxReqTimeOut, -+ (ULONG) prStaRec); -+ -+ cnmTimerStartTimer(prAdapter, -+ &prStaRec->rTxReqDoneOrRxRespTimer, -+ TU_TO_MSEC(TX_ASSOCIATION_RETRY_TIMEOUT_TU)); -+ } -+ } -+ -+ break; -+ -+ case SAA_STATE_WAIT_ASSOC2: -+ break; -+ -+ case AA_STATE_RESOURCE: -+ /* TODO(Kevin) Can setup a timer and send message later */ -+ break; -+ -+ default: -+ DBGLOG(SAA, ERROR, "Unknown AA STATE\n"); -+ ASSERT(0); -+ break; -+ } -+ -+ } while (fgIsTransition); -+ -+ return; -+ -+} /* end of saaFsmSteps() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will send Event to AIS/BOW/P2P -+* -+* @param[in] rJoinStatus To indicate JOIN success or failure. -+* @param[in] prStaRec Pointer to the STA_RECORD_T -+* @param[in] prSwRfb Pointer to the SW_RFB_T -+ -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+saaFsmSendEventJoinComplete(IN P_ADAPTER_T prAdapter, -+ IN WLAN_STATUS rJoinStatus, IN P_STA_RECORD_T prStaRec, IN P_SW_RFB_T prSwRfb) -+{ -+ P_BSS_INFO_T prBssInfo; -+ -+ ASSERT(prStaRec); -+ if (!prStaRec) -+ return WLAN_STATUS_INVALID_PACKET; -+ -+ /* Store limitation about 40Mhz bandwidth capability during association */ -+ if (prStaRec->ucNetTypeIndex < NETWORK_TYPE_INDEX_NUM) { -+ prBssInfo = &prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]; -+ -+ if (rJoinStatus == WLAN_STATUS_SUCCESS) -+ prBssInfo->fg40mBwAllowed = prBssInfo->fgAssoc40mBwAllowed; -+ prBssInfo->fgAssoc40mBwAllowed = FALSE; -+ } -+ -+ if (prStaRec->ucNetTypeIndex == NETWORK_TYPE_AIS_INDEX) { -+ P_MSG_SAA_FSM_COMP_T prSaaFsmCompMsg; -+ -+ prSaaFsmCompMsg = cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_SAA_FSM_COMP_T)); -+ if (!prSaaFsmCompMsg) -+ return WLAN_STATUS_RESOURCES; -+ -+ prSaaFsmCompMsg->rMsgHdr.eMsgId = MID_SAA_AIS_JOIN_COMPLETE; -+ prSaaFsmCompMsg->ucSeqNum = prStaRec->ucAuthAssocReqSeqNum; -+ prSaaFsmCompMsg->rJoinStatus = rJoinStatus; -+ prSaaFsmCompMsg->prStaRec = prStaRec; -+ prSaaFsmCompMsg->prSwRfb = prSwRfb; -+ -+ /* NOTE(Kevin): Set to UNBUF for immediately JOIN complete */ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prSaaFsmCompMsg, MSG_SEND_METHOD_UNBUF); -+ -+ return WLAN_STATUS_SUCCESS; -+ } -+#if CFG_ENABLE_WIFI_DIRECT -+ else if ((prAdapter->fgIsP2PRegistered) && (IS_STA_IN_P2P(prStaRec))) { -+ P_MSG_SAA_FSM_COMP_T prSaaFsmCompMsg; -+ -+ prSaaFsmCompMsg = cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_SAA_FSM_COMP_T)); -+ if (!prSaaFsmCompMsg) -+ return WLAN_STATUS_RESOURCES; -+ -+ prSaaFsmCompMsg->rMsgHdr.eMsgId = MID_SAA_P2P_JOIN_COMPLETE; -+ prSaaFsmCompMsg->ucSeqNum = prStaRec->ucAuthAssocReqSeqNum; -+ prSaaFsmCompMsg->rJoinStatus = rJoinStatus; -+ prSaaFsmCompMsg->prStaRec = prStaRec; -+ prSaaFsmCompMsg->prSwRfb = prSwRfb; -+ -+ /* NOTE(Kevin): Set to UNBUF for immediately JOIN complete */ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prSaaFsmCompMsg, MSG_SEND_METHOD_UNBUF); -+ -+ return WLAN_STATUS_SUCCESS; -+ } -+#endif -+#if CFG_ENABLE_BT_OVER_WIFI -+ else if (prStaRec->ucNetTypeIndex == NETWORK_TYPE_BOW_INDEX) { -+ /* @TODO: BOW handler */ -+ -+ P_MSG_SAA_FSM_COMP_T prSaaFsmCompMsg; -+ -+ prSaaFsmCompMsg = cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_SAA_FSM_COMP_T)); -+ if (!prSaaFsmCompMsg) -+ return WLAN_STATUS_RESOURCES; -+ -+ prSaaFsmCompMsg->rMsgHdr.eMsgId = MID_SAA_BOW_JOIN_COMPLETE; -+ prSaaFsmCompMsg->ucSeqNum = prStaRec->ucAuthAssocReqSeqNum; -+ prSaaFsmCompMsg->rJoinStatus = rJoinStatus; -+ prSaaFsmCompMsg->prStaRec = prStaRec; -+ prSaaFsmCompMsg->prSwRfb = prSwRfb; -+ -+ /* NOTE(Kevin): Set to UNBUF for immediately JOIN complete */ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prSaaFsmCompMsg, MSG_SEND_METHOD_UNBUF); -+ -+ return WLAN_STATUS_SUCCESS; -+ } -+#endif -+ else { -+ ASSERT(0); -+ return WLAN_STATUS_FAILURE; -+ } -+ -+} /* end of saaFsmSendEventJoinComplete() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will handle the Start Event to SAA FSM. -+* -+* @param[in] prMsgHdr Message of Join Request for a particular STA. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID saaFsmRunEventStart(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) -+{ -+ P_MSG_SAA_FSM_START_T prSaaFsmStartMsg; -+ P_STA_RECORD_T prStaRec; -+ P_BSS_INFO_T prBssInfo; -+ -+ ASSERT(prAdapter); -+ ASSERT(prMsgHdr); -+ -+ prSaaFsmStartMsg = (P_MSG_SAA_FSM_START_T) prMsgHdr; -+ prStaRec = prSaaFsmStartMsg->prStaRec; -+ -+ if ((!prStaRec) || (prStaRec->fgIsInUse == FALSE)) { -+ cnmMemFree(prAdapter, prMsgHdr); -+ return; -+ } -+ -+ ASSERT(prStaRec); -+ -+ DBGLOG(SAA, LOUD, "EVENT-START: Trigger SAA FSM.\n"); -+ -+ /* record sequence number of request message */ -+ prStaRec->ucAuthAssocReqSeqNum = prSaaFsmStartMsg->ucSeqNum; -+ -+ cnmMemFree(prAdapter, prMsgHdr); -+ -+ /* 4 <1> Validation of SAA Start Event */ -+ if (!IS_AP_STA(prStaRec)) { -+ -+ DBGLOG(SAA, ERROR, "EVENT-START: STA Type - %d was not supported.\n", prStaRec->eStaType); -+ -+ /* Ignore the return value because don't care the prSwRfb */ -+ saaFsmSendEventJoinComplete(prAdapter, WLAN_STATUS_FAILURE, prStaRec, NULL); -+ -+ return; -+ } -+ /* 4 <2> The previous JOIN process is not completed ? */ -+ if (prStaRec->eAuthAssocState != AA_STATE_IDLE) { -+ DBGLOG(SAA, ERROR, "EVENT-START: Reentry of SAA Module.\n"); -+ prStaRec->eAuthAssocState = AA_STATE_IDLE; -+ } -+ /* 4 <3> Reset Status Code and Time */ -+ /* Update Station Record - Status/Reason Code */ -+ prStaRec->u2StatusCode = STATUS_CODE_SUCCESSFUL; -+ -+ /* Update the record join time. */ -+ GET_CURRENT_SYSTIME(&prStaRec->rLastJoinTime); -+ -+ prStaRec->ucTxAuthAssocRetryCount = 0; -+ -+ if (prStaRec->prChallengeText) { -+ cnmMemFree(prAdapter, prStaRec->prChallengeText); -+ prStaRec->prChallengeText = (P_IE_CHALLENGE_TEXT_T) NULL; -+ } -+ -+ cnmTimerStopTimer(prAdapter, &prStaRec->rTxReqDoneOrRxRespTimer); -+ -+#if CFG_PRIVACY_MIGRATION -+ /* 4 <4> Init the sec fsm */ -+ secFsmInit(prAdapter, prStaRec); -+#endif -+ -+ /* 4 <5> Reset the STA STATE */ -+ /* Update Station Record - Class 1 Flag */ -+ /* NOTE(Kevin): Moved to AIS FSM for Reconnect issue - -+ * We won't deactivate the same STA_RECORD_T and then activate it again for the -+ * case of reconnection. -+ */ -+ /* cnmStaRecChangeState(prStaRec, STA_STATE_1); */ -+ -+ /* 4 <6> Decide if this BSS 20/40M bandwidth is allowed */ -+ if (prStaRec->ucNetTypeIndex < NETWORK_TYPE_INDEX_NUM) { -+ prBssInfo = &prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]; -+ -+ if ((prAdapter->rWifiVar.ucAvailablePhyTypeSet & PHY_TYPE_SET_802_11N) -+ && (prStaRec->ucPhyTypeSet & PHY_TYPE_SET_802_11N)) { -+ prBssInfo->fgAssoc40mBwAllowed = cnmBss40mBwPermitted(prAdapter, prBssInfo->ucNetTypeIndex); -+ } else { -+ prBssInfo->fgAssoc40mBwAllowed = FALSE; -+ } -+ DBGLOG(RLM, INFO, "STA 40mAllowed=%d\n", prBssInfo->fgAssoc40mBwAllowed); -+ } -+ /* 4 <7> Trigger SAA FSM */ -+ if (prStaRec->ucStaState == STA_STATE_1) -+ saaFsmSteps(prAdapter, prStaRec, SAA_STATE_SEND_AUTH1, (P_SW_RFB_T) NULL); -+ else if (prStaRec->ucStaState == STA_STATE_2 || prStaRec->ucStaState == STA_STATE_3) -+ saaFsmSteps(prAdapter, prStaRec, SAA_STATE_SEND_ASSOC1, (P_SW_RFB_T) NULL); -+ -+} /* end of saaFsmRunEventStart() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will handle TxDone(Auth1/Auth3/AssocReq) Event of SAA FSM. -+* -+* @param[in] prMsduInfo Pointer to the MSDU_INFO_T. -+* @param[in] rTxDoneStatus Return TX status of the Auth1/Auth3/AssocReq frame. -+* -+* @retval WLAN_STATUS_SUCCESS -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+saaFsmRunEventTxDone(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus) -+{ -+ -+ P_STA_RECORD_T prStaRec; -+ ENUM_AA_STATE_T eNextState; -+ -+ ASSERT(prMsduInfo); -+ -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); -+ -+ if (!prStaRec) { -+ DBGLOG(SAA, INFO, "EVENT-TX DONE: Status %d, Invalid StaRec\n", rTxDoneStatus); -+ return WLAN_STATUS_INVALID_PACKET; -+ } -+ -+ ASSERT(prStaRec); -+ -+ DBGLOG(SAA, INFO, "EVENT-TX DONE: Status: %d, eAuthAssocState: %d , SeqNO: %d ", -+ rTxDoneStatus, prStaRec->eAuthAssocState, -+ prMsduInfo->ucTxSeqNum); -+ -+ eNextState = prStaRec->eAuthAssocState; -+ -+ switch (prStaRec->eAuthAssocState) { -+ case SAA_STATE_SEND_AUTH1: -+ { -+ /* Strictly check the outgoing frame is matched with current AA STATE */ -+ if (authCheckTxAuthFrame(prAdapter, prMsduInfo, AUTH_TRANSACTION_SEQ_1) != WLAN_STATUS_SUCCESS) -+ break; -+ -+ if (rTxDoneStatus == TX_RESULT_SUCCESS) { -+ eNextState = SAA_STATE_WAIT_AUTH2; -+ -+ cnmTimerStopTimer(prAdapter, &prStaRec->rTxReqDoneOrRxRespTimer); -+ -+ cnmTimerInitTimer(prAdapter, -+ &prStaRec->rTxReqDoneOrRxRespTimer, -+ (PFN_MGMT_TIMEOUT_FUNC) saaFsmRunEventRxRespTimeOut, -+ (ULONG) prStaRec); -+ -+ cnmTimerStartTimer(prAdapter, -+ &prStaRec->rTxReqDoneOrRxRespTimer, -+ TU_TO_MSEC(DOT11_AUTHENTICATION_RESPONSE_TIMEOUT_TU)); -+ } -+ -+ /* if TX was successful, change to next state. -+ * if TX was failed, do retry if possible. -+ */ -+ saaFsmSteps(prAdapter, prStaRec, eNextState, (P_SW_RFB_T) NULL); -+ } -+ break; -+ -+ case SAA_STATE_SEND_AUTH3: -+ { -+ /* Strictly check the outgoing frame is matched with current JOIN STATE */ -+ if (authCheckTxAuthFrame(prAdapter, prMsduInfo, AUTH_TRANSACTION_SEQ_3) != WLAN_STATUS_SUCCESS) -+ break; -+ -+ if (rTxDoneStatus == TX_RESULT_SUCCESS) { -+ eNextState = SAA_STATE_WAIT_AUTH4; -+ -+ cnmTimerStopTimer(prAdapter, &prStaRec->rTxReqDoneOrRxRespTimer); -+ -+ cnmTimerInitTimer(prAdapter, -+ &prStaRec->rTxReqDoneOrRxRespTimer, -+ (PFN_MGMT_TIMEOUT_FUNC) saaFsmRunEventRxRespTimeOut, -+ (ULONG) prStaRec); -+ -+ cnmTimerStartTimer(prAdapter, -+ &prStaRec->rTxReqDoneOrRxRespTimer, -+ TU_TO_MSEC(DOT11_AUTHENTICATION_RESPONSE_TIMEOUT_TU)); -+ } -+ -+ /* if TX was successful, change to next state. -+ * if TX was failed, do retry if possible. -+ */ -+ saaFsmSteps(prAdapter, prStaRec, eNextState, (P_SW_RFB_T) NULL); -+ } -+ break; -+ -+ case SAA_STATE_SEND_ASSOC1: -+ { -+ /* Strictly check the outgoing frame is matched with current SAA STATE */ -+ if (assocCheckTxReAssocReqFrame(prAdapter, prMsduInfo) != WLAN_STATUS_SUCCESS) -+ break; -+ -+ if (rTxDoneStatus == TX_RESULT_SUCCESS) { -+ eNextState = SAA_STATE_WAIT_ASSOC2; -+ -+ cnmTimerStopTimer(prAdapter, &prStaRec->rTxReqDoneOrRxRespTimer); -+ -+ cnmTimerInitTimer(prAdapter, -+ &prStaRec->rTxReqDoneOrRxRespTimer, -+ (PFN_MGMT_TIMEOUT_FUNC) saaFsmRunEventRxRespTimeOut, -+ (ULONG) prStaRec); -+ -+ cnmTimerStartTimer(prAdapter, -+ &(prStaRec->rTxReqDoneOrRxRespTimer), -+ TU_TO_MSEC(DOT11_ASSOCIATION_RESPONSE_TIMEOUT_TU)); -+ } -+ /* if TX was successful, change to next state. -+ * if TX was failed, do retry if possible. -+ */ -+ saaFsmSteps(prAdapter, prStaRec, eNextState, (P_SW_RFB_T) NULL); -+ } -+ break; -+ -+ default: -+ break; /* Ignore other cases */ -+ } -+ -+ return WLAN_STATUS_SUCCESS; -+ -+} /* end of saaFsmRunEventTxDone() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will send Tx Request Timeout Event to SAA FSM. -+* -+* @param[in] prStaRec Pointer to the STA_RECORD_T -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID saaFsmRunEventTxReqTimeOut(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec) -+{ -+ ASSERT(prStaRec); -+ if (!prStaRec) -+ return; -+ -+ DBGLOG(SAA, LOUD, "EVENT-TIMER: TX REQ TIMEOUT, Current Time = %u\n", kalGetTimeTick()); -+ -+ switch (prStaRec->eAuthAssocState) { -+ case SAA_STATE_SEND_AUTH1: -+ case SAA_STATE_SEND_AUTH3: -+ case SAA_STATE_SEND_ASSOC1: -+ saaFsmSteps(prAdapter, prStaRec, prStaRec->eAuthAssocState, (P_SW_RFB_T) NULL); -+ break; -+ -+ default: -+ return; -+ } -+ -+} /* end of saaFsmRunEventTxReqTimeOut() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will send Rx Response Timeout Event to SAA FSM. -+* -+* @param[in] prStaRec Pointer to the STA_RECORD_T -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID saaFsmRunEventRxRespTimeOut(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec) -+{ -+ ENUM_AA_STATE_T eNextState; -+ -+ DBGLOG(SAA, LOUD, "EVENT-TIMER: RX RESP TIMEOUT, Current Time = %u\n", kalGetTimeTick()); -+ -+ ASSERT(prStaRec); -+ if (!prStaRec) -+ return; -+ -+ eNextState = prStaRec->eAuthAssocState; -+ -+ switch (prStaRec->eAuthAssocState) { -+ case SAA_STATE_WAIT_AUTH2: -+ /* Record the Status Code of Authentication Request */ -+ prStaRec->u2StatusCode = STATUS_CODE_AUTH_TIMEOUT; -+ -+ /* Pull back to earlier state to do retry */ -+ eNextState = SAA_STATE_SEND_AUTH1; -+ break; -+ -+ case SAA_STATE_WAIT_AUTH4: -+ /* Record the Status Code of Authentication Request */ -+ prStaRec->u2StatusCode = STATUS_CODE_AUTH_TIMEOUT; -+ -+ /* Pull back to earlier state to do retry */ -+ eNextState = SAA_STATE_SEND_AUTH3; -+ break; -+ -+ case SAA_STATE_WAIT_ASSOC2: -+ /* Record the Status Code of Authentication Request */ -+ prStaRec->u2StatusCode = STATUS_CODE_ASSOC_TIMEOUT; -+ -+ /* Pull back to earlier state to do retry */ -+ eNextState = SAA_STATE_SEND_ASSOC1; -+ break; -+ -+ default: -+ break; /* Ignore other cases */ -+ } -+ -+ if (eNextState != prStaRec->eAuthAssocState) -+ saaFsmSteps(prAdapter, prStaRec, eNextState, (P_SW_RFB_T) NULL); -+ -+} /* end of saaFsmRunEventRxRespTimeOut() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will process the Rx Auth Response Frame and then -+* trigger SAA FSM. -+* -+* @param[in] prSwRfb Pointer to the SW_RFB_T structure. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID saaFsmRunEventRxAuth(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb) -+{ -+ P_STA_RECORD_T prStaRec; -+ UINT_16 u2StatusCode; -+ ENUM_AA_STATE_T eNextState; -+ -+ ASSERT(prSwRfb); -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); -+ -+ /* We should have the corresponding Sta Record. */ -+ if (!prStaRec) { -+ /* Peter: we can handle the packet without station record */ -+ /* ASSERT(0); */ -+ return; -+ } -+ -+ if (!IS_AP_STA(prStaRec)) -+ return; -+ -+ switch (prStaRec->eAuthAssocState) { -+ case SAA_STATE_SEND_AUTH1: -+ case SAA_STATE_WAIT_AUTH2: -+ /* Check if the incoming frame is what we are waiting for */ -+ if (authCheckRxAuthFrameStatus(prAdapter, -+ prSwRfb, AUTH_TRANSACTION_SEQ_2, &u2StatusCode) == WLAN_STATUS_SUCCESS) { -+ -+ cnmTimerStopTimer(prAdapter, &prStaRec->rTxReqDoneOrRxRespTimer); -+ -+ /* Record the Status Code of Authentication Request */ -+ prStaRec->u2StatusCode = u2StatusCode; -+ -+ if (u2StatusCode == STATUS_CODE_SUCCESSFUL) { -+ -+ authProcessRxAuth2_Auth4Frame(prAdapter, prSwRfb); -+ -+ if (prStaRec->ucAuthAlgNum == (UINT_8) AUTH_ALGORITHM_NUM_SHARED_KEY) { -+ -+ eNextState = SAA_STATE_SEND_AUTH3; -+ } else { -+ /* Update Station Record - Class 2 Flag */ -+ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_2); -+ -+ eNextState = SAA_STATE_SEND_ASSOC1; -+ } -+ } else { -+ DBGLOG(SAA, INFO, "Auth Req was rejected by [ %pM ], Status Code = %d\n", -+ (prStaRec->aucMacAddr), u2StatusCode); -+ -+ eNextState = AA_STATE_IDLE; -+ } -+ -+ /* Reset Send Auth/(Re)Assoc Frame Count */ -+ prStaRec->ucTxAuthAssocRetryCount = 0; -+ -+ saaFsmSteps(prAdapter, prStaRec, eNextState, (P_SW_RFB_T) NULL); -+ } -+ break; -+ -+ case SAA_STATE_SEND_AUTH3: -+ case SAA_STATE_WAIT_AUTH4: -+ /* Check if the incoming frame is what we are waiting for */ -+ if (authCheckRxAuthFrameStatus(prAdapter, -+ prSwRfb, AUTH_TRANSACTION_SEQ_4, &u2StatusCode) == WLAN_STATUS_SUCCESS) { -+ -+ cnmTimerStopTimer(prAdapter, &prStaRec->rTxReqDoneOrRxRespTimer); -+ -+ /* Record the Status Code of Authentication Request */ -+ prStaRec->u2StatusCode = u2StatusCode; -+ -+ if (u2StatusCode == STATUS_CODE_SUCCESSFUL) { -+ -+ authProcessRxAuth2_Auth4Frame(prAdapter, prSwRfb); /* Add for 802.11r handling */ -+ -+ /* Update Station Record - Class 2 Flag */ -+ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_2); -+ -+ eNextState = SAA_STATE_SEND_ASSOC1; -+ } else { -+ DBGLOG(SAA, INFO, "Auth Req was rejected by [ %pM ], Status Code = %d\n", -+ (prStaRec->aucMacAddr), u2StatusCode); -+ -+ eNextState = AA_STATE_IDLE; -+ } -+ -+ /* Reset Send Auth/(Re)Assoc Frame Count */ -+ prStaRec->ucTxAuthAssocRetryCount = 0; -+ -+ saaFsmSteps(prAdapter, prStaRec, eNextState, (P_SW_RFB_T) NULL); -+ } -+ break; -+ -+ default: -+ break; /* Ignore other cases */ -+ } -+ -+} /* end of saaFsmRunEventRxAuth() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will process the Rx (Re)Association Response Frame and then -+* trigger SAA FSM. -+* -+* @param[in] prSwRfb Pointer to the SW_RFB_T structure. -+* -+* @retval WLAN_STATUS_SUCCESS if the status code was not success -+* @retval WLAN_STATUS_BUFFER_RETAINED if the status code was success -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS saaFsmRunEventRxAssoc(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb) -+{ -+ P_STA_RECORD_T prStaRec; -+ UINT_16 u2StatusCode; -+ ENUM_AA_STATE_T eNextState; -+ P_SW_RFB_T prRetainedSwRfb = (P_SW_RFB_T) NULL; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ -+ ASSERT(prSwRfb); -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); -+ -+ /* We should have the corresponding Sta Record. */ -+ if (!prStaRec) { -+ ASSERT(0); -+ return rStatus; -+ } -+ -+ if (!IS_AP_STA(prStaRec)) -+ return rStatus; -+ -+ switch (prStaRec->eAuthAssocState) { -+ case SAA_STATE_SEND_ASSOC1: -+ case SAA_STATE_WAIT_ASSOC2: -+ /* TRUE if the incoming frame is what we are waiting for */ -+ if (assocCheckRxReAssocRspFrameStatus(prAdapter, prSwRfb, &u2StatusCode) == WLAN_STATUS_SUCCESS) { -+ -+ cnmTimerStopTimer(prAdapter, &prStaRec->rTxReqDoneOrRxRespTimer); -+ -+ /* Record the Status Code of Authentication Request */ -+ prStaRec->u2StatusCode = u2StatusCode; -+ -+ if (u2StatusCode == STATUS_CODE_SUCCESSFUL) { -+ -+ /* Update Station Record - Class 3 Flag */ -+ /* NOTE(Kevin): Moved to AIS FSM for roaming issue - -+ * We should deactivate the STA_RECORD_T of previous AP before -+ * activate new one in Driver. -+ */ -+ /* cnmStaRecChangeState(prStaRec, STA_STATE_3); */ -+ -+ prStaRec->ucJoinFailureCount = 0; /* Clear history. */ -+ -+ prRetainedSwRfb = prSwRfb; -+ rStatus = WLAN_STATUS_PENDING; -+ } else { -+ DBGLOG(SAA, INFO, "Assoc Req was rejected by [ %pM ], Status Code = %d\n", -+ (prStaRec->aucMacAddr), u2StatusCode); -+ } -+ -+ /* Reset Send Auth/(Re)Assoc Frame Count */ -+ prStaRec->ucTxAuthAssocRetryCount = 0; -+ -+ /* update RCPI */ -+ prStaRec->ucRCPI = prSwRfb->prHifRxHdr->ucRcpi; -+ -+ eNextState = AA_STATE_IDLE; -+ -+ saaFsmSteps(prAdapter, prStaRec, eNextState, prRetainedSwRfb); -+ } -+ break; -+ -+ default: -+ break; /* Ignore other cases */ -+ } -+ -+ return rStatus; -+ -+} /* end of saaFsmRunEventRxAssoc() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will check the incoming Deauth Frame. -+* -+* @param[in] prSwRfb Pointer to the SW_RFB_T structure. -+* -+* @retval WLAN_STATUS_SUCCESS Always not retain deauthentication frames -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS saaFsmRunEventRxDeauth(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb) -+{ -+ P_STA_RECORD_T prStaRec; -+ P_WLAN_DEAUTH_FRAME_T prDeauthFrame; -+ -+ ASSERT(prSwRfb); -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); -+ if (prStaRec == NULL) -+ return WLAN_STATUS_FAILURE; -+ -+ prDeauthFrame = (P_WLAN_DEAUTH_FRAME_T) prSwRfb->pvHeader; -+ DBGLOG(SAA, INFO, "Rx Deauth frame from BSSID=[ %pM ].\n", prDeauthFrame->aucBSSID); -+ -+ do { -+ if (IS_STA_IN_AIS(prStaRec)) { -+ P_AIS_BSS_INFO_T prAisBssInfo; -+ -+ if (!IS_AP_STA(prStaRec)) -+ break; -+ -+ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ -+ if (prStaRec->ucStaState <= STA_STATE_1) -+ break; -+ -+ /* Check if this is the AP we are associated or associating with */ -+ if (authProcessRxDeauthFrame(prSwRfb, -+ prStaRec->aucMacAddr, -+ &prStaRec->u2ReasonCode) == WLAN_STATUS_SUCCESS) { -+ -+ DBGLOG(SAA, INFO, "Deauth reason = %d\n", prStaRec->u2ReasonCode); -+ -+ if (STA_STATE_2 <= prStaRec->ucStaState) { -+ P_MSG_AIS_ABORT_T prAisAbortMsg; -+ -+ /* NOTE(Kevin): Change state immediately to avoid starvation of -+ * MSG buffer because of too many deauth frames before changing -+ * the STA state. -+ */ -+ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); -+ -+ prAisAbortMsg = -+ (P_MSG_AIS_ABORT_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, -+ sizeof(MSG_AIS_ABORT_T)); -+ if (!prAisAbortMsg) -+ break; -+ -+ prAisAbortMsg->rMsgHdr.eMsgId = MID_SAA_AIS_FSM_ABORT; -+ prAisAbortMsg->ucReasonOfDisconnect = -+ DISCONNECT_REASON_CODE_DEAUTHENTICATED; -+ prAisAbortMsg->fgDelayIndication = FALSE; -+ -+ mboxSendMsg(prAdapter, -+ MBOX_ID_0, -+ (P_MSG_HDR_T) prAisAbortMsg, MSG_SEND_METHOD_BUF); -+ } else { -+ -+ /* TODO(Kevin): Joining Abort */ -+ } -+ prAisBssInfo->u2DeauthReason = prStaRec->u2ReasonCode; -+ -+ } -+ -+ } -+#if CFG_ENABLE_WIFI_DIRECT -+ else if (prAdapter->fgIsP2PRegistered && IS_STA_IN_P2P(prStaRec)) { -+ /* TODO(Kevin) */ -+ p2pFsmRunEventRxDeauthentication(prAdapter, prStaRec, prSwRfb); -+ } -+#endif -+#if CFG_ENABLE_BT_OVER_WIFI -+ else if (IS_STA_IN_BOW(prStaRec)) -+ bowRunEventRxDeAuth(prAdapter, prStaRec, prSwRfb); -+#endif -+ else -+ ASSERT(0); -+ -+ } while (FALSE); -+ -+ return WLAN_STATUS_SUCCESS; -+} /* end of saaFsmRunEventRxDeauth() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will check the incoming Disassociation Frame. -+* -+* @param[in] prSwRfb Pointer to the SW_RFB_T structure. -+* -+* @retval WLAN_STATUS_SUCCESS Always not retain disassociation frames -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS saaFsmRunEventRxDisassoc(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb) -+{ -+ P_STA_RECORD_T prStaRec; -+ P_WLAN_DISASSOC_FRAME_T prDisassocFrame; -+ -+ ASSERT(prSwRfb); -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); -+ if (prStaRec == NULL) -+ return WLAN_STATUS_FAILURE; -+ -+ prDisassocFrame = (P_WLAN_DISASSOC_FRAME_T) prSwRfb->pvHeader; -+ DBGLOG(SAA, INFO, "Rx Disassoc frame from BSSID=[ %pM ].\n", (prDisassocFrame->aucBSSID)); -+ -+ do { -+ if (IS_STA_IN_AIS(prStaRec)) { -+ P_AIS_BSS_INFO_T prAisBssInfo; -+ -+ if (!IS_AP_STA(prStaRec)) -+ break; -+ -+ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ -+ if (prStaRec->ucStaState <= STA_STATE_1) -+ break; -+ -+ /* Check if this is the AP we are associated or associating with */ -+ if (assocProcessRxDisassocFrame(prAdapter, -+ prSwRfb, -+ prStaRec->aucMacAddr, -+ &prStaRec->u2ReasonCode) == WLAN_STATUS_SUCCESS) { -+ -+ DBGLOG(SAA, INFO, "Disassoc reason = %d\n", prStaRec->u2ReasonCode); -+ -+ if (STA_STATE_3 <= prStaRec->ucStaState) { -+ P_MSG_AIS_ABORT_T prAisAbortMsg; -+ /* NOTE(Chaozhong): Change state immediately to avoid starvation of -+ * MSG buffer because of too many disassoc frames before changing -+ * the STA state. -+ */ -+ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_2); -+ -+ prAisAbortMsg = -+ (P_MSG_AIS_ABORT_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, -+ sizeof(MSG_AIS_ABORT_T)); -+ if (!prAisAbortMsg) -+ break; -+ -+ prAisAbortMsg->rMsgHdr.eMsgId = MID_SAA_AIS_FSM_ABORT; -+ prAisAbortMsg->ucReasonOfDisconnect = -+ DISCONNECT_REASON_CODE_DISASSOCIATED; -+ prAisAbortMsg->fgDelayIndication = FALSE; -+ -+ mboxSendMsg(prAdapter, -+ MBOX_ID_0, -+ (P_MSG_HDR_T) prAisAbortMsg, MSG_SEND_METHOD_BUF); -+ } else { -+ -+ /* TODO(Kevin): Joining Abort */ -+ } -+ prAisBssInfo->u2DeauthReason = prStaRec->u2ReasonCode; -+ -+ } -+ -+ } -+#if CFG_ENABLE_WIFI_DIRECT -+ else if (prAdapter->fgIsP2PRegistered && IS_STA_IN_P2P(prStaRec)) { -+ /* TODO(Kevin) */ -+ p2pFsmRunEventRxDisassociation(prAdapter, prStaRec, prSwRfb); -+ } -+#endif -+#if CFG_ENABLE_BT_OVER_WIFI -+ else if (IS_STA_IN_BOW(prStaRec)) { -+ /* Do nothing */ -+ /* TODO(Kevin) */ -+ } -+#endif -+ else -+ ASSERT(0); -+ -+ } while (FALSE); -+ -+ return WLAN_STATUS_SUCCESS; -+} /* end of saaFsmRunEventRxDisassoc() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will handle the Abort Event to SAA FSM. -+* -+* @param[in] prMsgHdr Message of Abort Request for a particular STA. -+* -+* @return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID saaFsmRunEventAbort(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) -+{ -+ P_MSG_SAA_FSM_ABORT_T prSaaFsmAbortMsg; -+ P_STA_RECORD_T prStaRec; -+ -+ ASSERT(prMsgHdr); -+ -+ prSaaFsmAbortMsg = (P_MSG_SAA_FSM_ABORT_T) prMsgHdr; -+ prStaRec = prSaaFsmAbortMsg->prStaRec; -+ -+ ASSERT(prStaRec); -+ if (!prStaRec) { -+ cnmMemFree(prAdapter, prMsgHdr); -+ return; -+ } -+ -+ DBGLOG(SAA, LOUD, "EVENT-ABORT: Stop SAA FSM.\n"); -+ -+ cnmMemFree(prAdapter, prMsgHdr); -+ -+ /* Reset Send Auth/(Re)Assoc Frame Count */ -+ prStaRec->ucTxAuthAssocRetryCount = 0; -+ -+ /* Cancel JOIN relative Timer */ -+ cnmTimerStopTimer(prAdapter, &prStaRec->rTxReqDoneOrRxRespTimer); -+ -+ if (prStaRec->eAuthAssocState != AA_STATE_IDLE) { -+#if DBG -+ DBGLOG(SAA, LOUD, "EVENT-ABORT: Previous Auth/Assoc State == %s.\n", -+ apucDebugAAState[prStaRec->eAuthAssocState]); -+#else -+ DBGLOG(SAA, LOUD, "EVENT-ABORT: Previous Auth/Assoc State == %d.\n", prStaRec->eAuthAssocState); -+#endif -+ } -+#if 0 -+ /* For the Auth/Assoc State to IDLE */ -+ prStaRec->eAuthAssocState = AA_STATE_IDLE; -+#else -+ /* Free this StaRec */ -+ cnmStaRecFree(prAdapter, prStaRec, FALSE); -+#endif -+ -+} /* end of saaFsmRunEventAbort() */ -+ -+/* TODO(Kevin): following code will be modified and move to AIS FSM */ -+#if 0 -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will send Join Timeout Event to JOIN FSM. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* -+* \retval WLAN_STATUS_FAILURE Fail because of Join Timeout -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS joinFsmRunEventJoinTimeOut(IN P_ADAPTER_T prAdapter) -+{ -+ P_JOIN_INFO_T prJoinInfo; -+ P_STA_RECORD_T prStaRec; -+ -+ DEBUGFUNC("joinFsmRunEventJoinTimeOut"); -+ -+ ASSERT(prAdapter); -+ prJoinInfo = &prAdapter->rJoinInfo; -+ -+ DBGLOG(JOIN, EVENT, "JOIN EVENT: JOIN TIMEOUT\n"); -+ -+ /* Get a Station Record if possible, TA == BSSID for AP */ -+ prStaRec = staRecGetStaRecordByAddr(prAdapter, prJoinInfo->prBssDesc->aucBSSID); -+ -+ /* We have renew this Sta Record when in JOIN_STATE_INIT */ -+ ASSERT(prStaRec); -+ -+ /* Record the Status Code of Authentication Request */ -+ prStaRec->u2StatusCode = STATUS_CODE_JOIN_TIMEOUT; -+ -+ /* Increase Failure Count */ -+ prStaRec->ucJoinFailureCount++; -+ -+ /* Reset Send Auth/(Re)Assoc Frame Count */ -+ prJoinInfo->ucTxAuthAssocRetryCount = 0; -+ -+ /* Cancel other JOIN relative Timer */ -+ ARB_CANCEL_TIMER(prAdapter, prJoinInfo->rTxRequestTimer); -+ -+ ARB_CANCEL_TIMER(prAdapter, prJoinInfo->rRxResponseTimer); -+ -+ /* Restore original setting from current BSS_INFO_T */ -+ if (prAdapter->eConnectionState == MEDIA_STATE_CONNECTED) -+ joinAdoptParametersFromCurrentBss(prAdapter); -+ -+ /* Pull back to IDLE */ -+ joinFsmSteps(prAdapter, JOIN_STATE_IDLE); -+ -+ return WLAN_STATUS_FAILURE; -+ -+} /* end of joinFsmRunEventJoinTimeOut() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will adopt the parameters from Peer BSS. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID joinAdoptParametersFromPeerBss(IN P_ADAPTER_T prAdapter) -+{ -+ P_JOIN_INFO_T prJoinInfo; -+ P_BSS_DESC_T prBssDesc; -+ -+ DEBUGFUNC("joinAdoptParametersFromPeerBss"); -+ -+ ASSERT(prAdapter); -+ prJoinInfo = &prAdapter->rJoinInfo; -+ prBssDesc = prJoinInfo->prBssDesc; -+ -+ /* 4 <1> Adopt Peer BSS' PHY TYPE */ -+ prAdapter->eCurrentPhyType = prBssDesc->ePhyType; -+ -+ DBGLOG(JOIN, INFO, "Target BSS[%s]'s PhyType = %s\n", -+ prBssDesc->aucSSID, (prBssDesc->ePhyType == PHY_TYPE_ERP_INDEX) ? "ERP" : "HR_DSSS"); -+ -+ /* 4 <2> Adopt Peer BSS' Frequency(Band/Channel) */ -+ DBGLOG(JOIN, INFO, "Target BSS's Channel = %d, Band = %d\n", prBssDesc->ucChannelNum, prBssDesc->eBand); -+ -+ nicSwitchChannel(prAdapter, prBssDesc->eBand, prBssDesc->ucChannelNum, 10); -+ -+ prJoinInfo->fgIsParameterAdopted = TRUE; -+ -+} /* end of joinAdoptParametersFromPeerBss() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will adopt the parameters from current associated BSS. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID joinAdoptParametersFromCurrentBss(IN P_ADAPTER_T prAdapter) -+{ -+ /* P_JOIN_INFO_T prJoinInfo = &prAdapter->rJoinInfo; */ -+ P_BSS_INFO_T prBssInfo; -+ -+ ASSERT(prAdapter); -+ prBssInfo = &prAdapter->rBssInfo; -+ -+ /* 4 <1> Adopt current BSS' PHY TYPE */ -+ prAdapter->eCurrentPhyType = prBssInfo->ePhyType; -+ -+ /* 4 <2> Adopt current BSS' Frequency(Band/Channel) */ -+ DBGLOG(JOIN, INFO, "Current BSS's Channel = %d, Band = %d\n", prBssInfo->ucChnl, prBssInfo->eBand); -+ -+ nicSwitchChannel(prAdapter, prBssInfo->eBand, prBssInfo->ucChnl, 10); -+} /* end of joinAdoptParametersFromCurrentBss() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will update all the SW variables and HW MCR registers after -+* the association with target BSS. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID joinComplete(IN P_ADAPTER_T prAdapter) -+{ -+ P_JOIN_INFO_T prJoinInfo; -+ P_BSS_DESC_T prBssDesc; -+ P_PEER_BSS_INFO_T prPeerBssInfo; -+ P_BSS_INFO_T prBssInfo; -+ P_CONNECTION_SETTINGS_T prConnSettings; -+ P_STA_RECORD_T prStaRec; -+ P_TX_CTRL_T prTxCtrl; -+#if CFG_SUPPORT_802_11D -+ P_IE_COUNTRY_T prIECountry; -+#endif -+ -+ DEBUGFUNC("joinComplete"); -+ -+ ASSERT(prAdapter); -+ prJoinInfo = &prAdapter->rJoinInfo; -+ prBssDesc = prJoinInfo->prBssDesc; -+ prPeerBssInfo = &prAdapter->rPeerBssInfo; -+ prBssInfo = &prAdapter->rBssInfo; -+ prConnSettings = &prAdapter->rConnSettings; -+ prTxCtrl = &prAdapter->rTxCtrl; -+ -+/* 4 <1> Update Connecting & Connected Flag of BSS_DESC_T. */ -+ /* Remove previous AP's Connection Flags if have */ -+ scanRemoveConnectionFlagOfBssDescByBssid(prAdapter, prBssInfo->aucBSSID); -+ -+ prBssDesc->fgIsConnected = TRUE; /* Mask as Connected */ -+ -+ if (prBssDesc->fgIsHiddenSSID) { -+ /* NOTE(Kevin): This is for the case of Passive Scan and the target BSS didn't -+ * broadcast SSID on its Beacon Frame. -+ */ -+ COPY_SSID(prBssDesc->aucSSID, -+ prBssDesc->ucSSIDLen, prAdapter->rConnSettings.aucSSID, prAdapter->rConnSettings.ucSSIDLen); -+ -+ if (prBssDesc->ucSSIDLen) -+ prBssDesc->fgIsHiddenSSID = FALSE; -+#if DBG -+ else -+ ASSERT(0); -+#endif /* DBG */ -+ -+ DBGLOG(JOIN, INFO, "Hidden SSID! - Update SSID : %s\n", prBssDesc->aucSSID); -+ } -+/* 4 <2> Update BSS_INFO_T from BSS_DESC_T */ -+ /* 4 <2.A> PHY Type */ -+ prBssInfo->ePhyType = prBssDesc->ePhyType; -+ -+ /* 4 <2.B> BSS Type */ -+ prBssInfo->eBSSType = BSS_TYPE_INFRASTRUCTURE; -+ -+ /* 4 <2.C> BSSID */ -+ COPY_MAC_ADDR(prBssInfo->aucBSSID, prBssDesc->aucBSSID); -+ -+ DBGLOG(JOIN, INFO, "JOIN to BSSID: [%pM]\n", prBssDesc->aucBSSID); -+ -+ /* 4 <2.D> SSID */ -+ COPY_SSID(prBssInfo->aucSSID, prBssInfo->ucSSIDLen, prBssDesc->aucSSID, prBssDesc->ucSSIDLen); -+ -+ /* 4 <2.E> Channel / Band information. */ -+ prBssInfo->eBand = prBssDesc->eBand; -+ prBssInfo->ucChnl = prBssDesc->ucChannelNum; -+ -+ /* 4 <2.F> RSN/WPA information. */ -+ secFsmRunEventStart(prAdapter); -+ prBssInfo->u4RsnSelectedPairwiseCipher = prBssDesc->u4RsnSelectedPairwiseCipher; -+ prBssInfo->u4RsnSelectedGroupCipher = prBssDesc->u4RsnSelectedGroupCipher; -+ prBssInfo->u4RsnSelectedAKMSuite = prBssDesc->u4RsnSelectedAKMSuite; -+ -+ if (secRsnKeyHandshakeEnabled()) -+ prBssInfo->fgIsWPAorWPA2Enabled = TRUE; -+ else -+ prBssInfo->fgIsWPAorWPA2Enabled = FALSE; -+ -+ /* 4 <2.G> Beacon interval. */ -+ prBssInfo->u2BeaconInterval = prBssDesc->u2BeaconInterval; -+ -+ /* 4 <2.H> DTIM period. */ -+ prBssInfo->ucDtimPeriod = prBssDesc->ucDTIMPeriod; -+ -+ /* 4 <2.I> ERP Information */ -+ if ((prBssInfo->ePhyType == PHY_TYPE_ERP_INDEX) && /* Our BSS's PHY_TYPE is ERP now. */ -+ (prBssDesc->fgIsERPPresent)) { -+ -+ prBssInfo->fgIsERPPresent = TRUE; -+ prBssInfo->ucERP = prBssDesc->ucERP; /* Save the ERP for later check */ -+ } else { /* Some AP, may send ProbeResp without ERP IE. Thus prBssDesc->fgIsERPPresent is FALSE. */ -+ prBssInfo->fgIsERPPresent = FALSE; -+ prBssInfo->ucERP = 0; -+ } -+ -+#if CFG_SUPPORT_802_11D -+ /* 4 <2.J> Country inforamtion of the associated AP */ -+ if (prConnSettings->fgMultiDomainCapabilityEnabled) { -+ DOMAIN_INFO_ENTRY rDomainInfo; -+ -+ if (domainGetDomainInfoByScanResult(prAdapter, &rDomainInfo)) { -+ if (prBssDesc->prIECountry) { -+ prIECountry = prBssDesc->prIECountry; -+ -+ domainParseCountryInfoElem(prIECountry, &prBssInfo->rDomainInfo); -+ -+ /* use the domain get from the BSS info */ -+ prBssInfo->fgIsCountryInfoPresent = TRUE; -+ nicSetupOpChnlList(prAdapter, prBssInfo->rDomainInfo.u2CountryCode, FALSE); -+ } else { -+ /* use the domain get from the scan result */ -+ prBssInfo->fgIsCountryInfoPresent = TRUE; -+ nicSetupOpChnlList(prAdapter, rDomainInfo.u2CountryCode, FALSE); -+ } -+ } -+ } -+#endif -+ -+ /* 4 <2.K> Signal Power of the associated AP */ -+ prBssInfo->rRcpi = prBssDesc->rRcpi; -+ prBssInfo->rRssi = RCPI_TO_dBm(prBssInfo->rRcpi); -+ GET_CURRENT_SYSTIME(&prBssInfo->rRssiLastUpdateTime); -+ -+ /* 4 <2.L> Capability Field of the associated AP */ -+ prBssInfo->u2CapInfo = prBssDesc->u2CapInfo; -+ -+ DBGLOG(JOIN, INFO, "prBssInfo-> fgIsERPPresent = %d, ucERP = %02x, rRcpi = %d, rRssi = %ld\n", -+ prBssInfo->fgIsERPPresent, prBssInfo->ucERP, prBssInfo->rRcpi, prBssInfo->rRssi); -+ -+/* 4 <3> Update BSS_INFO_T from PEER_BSS_INFO_T & NIC RATE FUNC */ -+ /* 4 <3.A> Association ID */ -+ prBssInfo->u2AssocId = prPeerBssInfo->u2AssocId; -+ -+ /* 4 <3.B> WMM Information */ -+ if (prAdapter->fgIsEnableWMM && (prPeerBssInfo->rWmmInfo.ucWmmFlag & WMM_FLAG_SUPPORT_WMM)) { -+ -+ prBssInfo->fgIsWmmAssoc = TRUE; -+ prTxCtrl->rTxQForVoipAccess = TXQ_AC3; -+ -+ qosWmmInfoInit(&prBssInfo->rWmmInfo, (prBssInfo->ePhyType == PHY_TYPE_HR_DSSS_INDEX) ? TRUE : FALSE); -+ -+ if (prPeerBssInfo->rWmmInfo.ucWmmFlag & WMM_FLAG_AC_PARAM_PRESENT) { -+ kalMemCopy(&prBssInfo->rWmmInfo, &prPeerBssInfo->rWmmInfo, sizeof(WMM_INFO_T)); -+ } else { -+ kalMemCopy(&prBssInfo->rWmmInfo, -+ &prPeerBssInfo->rWmmInfo, -+ sizeof(WMM_INFO_T) - sizeof(prPeerBssInfo->rWmmInfo.arWmmAcParams)); -+ } -+ } else { -+ prBssInfo->fgIsWmmAssoc = FALSE; -+ prTxCtrl->rTxQForVoipAccess = TXQ_AC1; -+ -+ kalMemZero(&prBssInfo->rWmmInfo, sizeof(WMM_INFO_T)); -+ } -+ -+ /* 4 <3.C> Operational Rate Set & BSS Basic Rate Set */ -+ prBssInfo->u2OperationalRateSet = prPeerBssInfo->u2OperationalRateSet; -+ prBssInfo->u2BSSBasicRateSet = prPeerBssInfo->u2BSSBasicRateSet; -+ -+ /* 4 <3.D> Short Preamble */ -+ if (prBssInfo->fgIsERPPresent) { -+ -+ /* NOTE(Kevin 2007/12/24): Truth Table. -+ * Short Preamble Bit in -+ * Final Driver Setting(Short) -+ * TRUE FALSE FALSE FALSE(shouldn't have such case, use the AssocResp) -+ * TRUE FALSE TRUE FALSE -+ * FALSE FALSE FALSE FALSE(shouldn't have such case, use the AssocResp) -+ * FALSE FALSE TRUE FALSE -+ * TRUE TRUE FALSE TRUE(follow ERP) -+ * TRUE TRUE TRUE FALSE(follow ERP) -+ * FALSE TRUE FALSE FALSE(shouldn't have such case, and we should set to FALSE) -+ * FALSE TRUE TRUE FALSE(we should set to FALSE) -+ */ -+ if ((prPeerBssInfo->fgIsShortPreambleAllowed) && -+ ((prConnSettings->ePreambleType == PREAMBLE_TYPE_SHORT) || -+ ((prConnSettings->ePreambleType == PREAMBLE_TYPE_AUTO) && -+ (prBssDesc->u2CapInfo & CAP_INFO_SHORT_PREAMBLE)))) { -+ -+ prBssInfo->fgIsShortPreambleAllowed = TRUE; -+ -+ if (prBssInfo->ucERP & ERP_INFO_BARKER_PREAMBLE_MODE) -+ prBssInfo->fgUseShortPreamble = FALSE; -+ else -+ prBssInfo->fgUseShortPreamble = TRUE; -+ } else { -+ prBssInfo->fgIsShortPreambleAllowed = FALSE; -+ prBssInfo->fgUseShortPreamble = FALSE; -+ } -+ } else { -+ /* NOTE(Kevin 2007/12/24): Truth Table. -+ * Short Preamble Bit in -+ * Final Driver Setting(Short) -+ * TRUE FALSE FALSE -+ * FALSE FALSE FALSE -+ * TRUE TRUE TRUE -+ * FALSE TRUE(status success) TRUE -+ * --> Honor the result of prPeerBssInfo. -+ */ -+ -+ prBssInfo->fgIsShortPreambleAllowed = prBssInfo->fgUseShortPreamble = -+ prPeerBssInfo->fgIsShortPreambleAllowed; -+ } -+ -+ DBGLOG(JOIN, INFO, "prBssInfo->fgIsShortPreambleAllowed = %d, prBssInfo->fgUseShortPreamble = %d\n", -+ prBssInfo->fgIsShortPreambleAllowed, prBssInfo->fgUseShortPreamble); -+ -+ /* 4 <3.E> Short Slot Time */ -+ prBssInfo->fgUseShortSlotTime = prPeerBssInfo->fgUseShortSlotTime; /* AP support Short Slot Time */ -+ -+ DBGLOG(JOIN, INFO, "prBssInfo->fgUseShortSlotTime = %d\n", prBssInfo->fgUseShortSlotTime); -+ -+ nicSetSlotTime(prAdapter, -+ prBssInfo->ePhyType, -+ ((prConnSettings->fgIsShortSlotTimeOptionEnable && -+ prBssInfo->fgUseShortSlotTime) ? TRUE : FALSE)); -+ -+ /* 4 <3.F> Update Tx Rate for Control Frame */ -+ bssUpdateTxRateForControlFrame(prAdapter); -+ -+ /* 4 <3.G> Save the available Auth Types during Roaming (Design for Fast BSS Transition). */ -+ /* if (prAdapter->fgIsEnableRoaming) */ /* NOTE(Kevin): Always prepare info for roaming */ -+ { -+ -+ if (prJoinInfo->ucCurrAuthAlgNum == AUTH_ALGORITHM_NUM_OPEN_SYSTEM) -+ prJoinInfo->ucRoamingAuthTypes |= AUTH_TYPE_OPEN_SYSTEM; -+ else if (prJoinInfo->ucCurrAuthAlgNum == AUTH_ALGORITHM_NUM_SHARED_KEY) -+ prJoinInfo->ucRoamingAuthTypes |= AUTH_TYPE_SHARED_KEY; -+ -+ prBssInfo->ucRoamingAuthTypes = prJoinInfo->ucRoamingAuthTypes; -+ -+ /* Set the stable time of the associated BSS. We won't do roaming decision -+ * during the stable time. -+ */ -+ SET_EXPIRATION_TIME(prBssInfo->rRoamingStableExpirationTime, -+ SEC_TO_SYSTIME(ROAMING_STABLE_TIMEOUT_SEC)); -+ } -+ -+ /* 4 <3.H> Update Parameter for TX Fragmentation Threshold */ -+#if CFG_TX_FRAGMENT -+ txFragInfoUpdate(prAdapter); -+#endif /* CFG_TX_FRAGMENT */ -+ -+/* 4 <4> Update STA_RECORD_T */ -+ /* Get a Station Record if possible */ -+ prStaRec = staRecGetStaRecordByAddr(prAdapter, prBssDesc->aucBSSID); -+ -+ if (prStaRec) { -+ UINT_16 u2OperationalRateSet, u2DesiredRateSet; -+ -+ /* 4 <4.A> Desired Rate Set */ -+ u2OperationalRateSet = (rPhyAttributes[prBssInfo->ePhyType].u2SupportedRateSet & -+ prBssInfo->u2OperationalRateSet); -+ -+ u2DesiredRateSet = (u2OperationalRateSet & prConnSettings->u2DesiredRateSet); -+ if (u2DesiredRateSet) { -+ prStaRec->u2DesiredRateSet = u2DesiredRateSet; -+ } else { -+ /* For Error Handling - The Desired Rate Set is not covered in Operational Rate Set. */ -+ prStaRec->u2DesiredRateSet = u2OperationalRateSet; -+ } -+ -+ /* Try to set the best initial rate for this entry */ -+ if (!rateGetBestInitialRateIndex(prStaRec->u2DesiredRateSet, -+ prStaRec->rRcpi, &prStaRec->ucCurrRate1Index)) { -+ -+ if (!rateGetLowestRateIndexFromRateSet(prStaRec->u2DesiredRateSet, &prStaRec->ucCurrRate1Index)) -+ ASSERT(0); -+ } -+ -+ DBGLOG(JOIN, INFO, "prStaRec->ucCurrRate1Index = %d\n", prStaRec->ucCurrRate1Index); -+ -+ /* 4 <4.B> Preamble Mode */ -+ prStaRec->fgIsShortPreambleOptionEnable = prBssInfo->fgUseShortPreamble; -+ -+ /* 4 <4.C> QoS Flag */ -+ prStaRec->fgIsQoS = prBssInfo->fgIsWmmAssoc; -+ } -+#if DBG -+ else -+ ASSERT(0); -+#endif /* DBG */ -+ -+/* 4 <5> Update NIC */ -+ /* 4 <5.A> Update BSSID & Operation Mode */ -+ nicSetupBSS(prAdapter, prBssInfo); -+ -+ /* 4 <5.B> Update WLAN Table. */ -+ if (nicSetHwBySta(prAdapter, prStaRec) == FALSE) -+ ASSERT(FALSE); -+ /* 4 <5.C> Update Desired Rate Set for BT. */ -+#if CFG_TX_FRAGMENT -+ if (prConnSettings->fgIsEnableTxAutoFragmentForBT) -+ txRateSetInitForBT(prAdapter, prStaRec); -+#endif /* CFG_TX_FRAGMENT */ -+ -+ /* 4 <5.D> TX AC Parameter and TX/RX Queue Control */ -+ if (prBssInfo->fgIsWmmAssoc) { -+ -+#if CFG_TX_AGGREGATE_HW_FIFO -+ nicTxAggregateTXQ(prAdapter, FALSE); -+#endif /* CFG_TX_AGGREGATE_HW_FIFO */ -+ -+ qosUpdateWMMParametersAndAssignAllowedACI(prAdapter, &prBssInfo->rWmmInfo); -+ } else { -+ -+#if CFG_TX_AGGREGATE_HW_FIFO -+ nicTxAggregateTXQ(prAdapter, TRUE); -+#endif /* CFG_TX_AGGREGATE_HW_FIFO */ -+ -+ nicTxNonQoSAssignDefaultAdmittedTXQ(prAdapter); -+ -+ nicTxNonQoSUpdateTXQParameters(prAdapter, prBssInfo->ePhyType); -+ } -+ -+#if CFG_TX_STOP_WRITE_TX_FIFO_UNTIL_JOIN -+ { -+ prTxCtrl->fgBlockTxDuringJoin = FALSE; -+ -+#if !CFG_TX_AGGREGATE_HW_FIFO /* TX FIFO AGGREGATE already do flush once */ -+ nicTxFlushStopQueues(prAdapter, (UINT_8) TXQ_DATA_MASK, (UINT_8) NULL); -+#endif /* CFG_TX_AGGREGATE_HW_FIFO */ -+ -+ nicTxRetransmitOfSendWaitQue(prAdapter); -+ -+ if (prTxCtrl->fgIsPacketInOsSendQueue) -+ nicTxRetransmitOfOsSendQue(prAdapter); -+#if CFG_SDIO_TX_ENHANCE -+ halTxLeftClusteredMpdu(prAdapter); -+#endif /* CFG_SDIO_TX_ENHANCE */ -+ -+ } -+#endif /* CFG_TX_STOP_WRITE_TX_FIFO_UNTIL_JOIN */ -+ -+/* 4 <6> Setup CONNECTION flag. */ -+ prAdapter->eConnectionState = MEDIA_STATE_CONNECTED; -+ prAdapter->eConnectionStateIndicated = MEDIA_STATE_CONNECTED; -+ -+ if (prJoinInfo->fgIsReAssoc) -+ prAdapter->fgBypassPortCtrlForRoaming = TRUE; -+ else -+ prAdapter->fgBypassPortCtrlForRoaming = FALSE; -+ -+ kalIndicateStatusAndComplete(prAdapter->prGlueInfo, WLAN_STATUS_MEDIA_CONNECT, (PVOID) NULL, 0); -+ -+} /* end of joinComplete() */ -+#endif -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/scan.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/scan.c -new file mode 100644 -index 000000000000..2c9ccbe82dd1 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/scan.c -@@ -0,0 +1,3103 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/scan.c#3 -+*/ -+ -+/*! \file "scan.c" -+ \brief This file defines the scan profile and the processing function of -+ scan result for SCAN Module. -+ -+ The SCAN Profile selection is part of SCAN MODULE and responsible for defining -+ SCAN Parameters - e.g. MIN_CHANNEL_TIME, number of scan channels. -+ In this file we also define the process of SCAN Result including adding, searching -+ and removing SCAN record from the list. -+*/ -+ -+/* -+** Log: scan.c -+** -+** 01 30 2013 yuche.tsai -+** [ALPS00451578] [JB2][WFD][Case Fail][JE][MR1]?????????[Java (JE),660,-1361051648,99, -+** /data/core/,0,system_server_crash,system_server]JE happens when try to connect WFD.(4/5) -+** Fix possible old scan result indicate to supplicant after formation. -+** -+** 01 16 2013 yuche.tsai -+** [ALPS00431980] [WFD]Aupus one ?play game 10 minitues?wfd connection automaticlly disconnect -+** Fix possible FW assert issue. -+ * -+ * 07 17 2012 yuche.tsai -+ * NULL -+ * Let netdev bring up. -+ * -+ * 07 17 2012 yuche.tsai -+ * NULL -+ * Compile no error before trial run. -+ * -+ * 06 25 2012 cp.wu -+ * [WCXRP00001258] [MT6620][MT5931][MT6628][Driver] Do not use stale scan result for deciding connection target -+ * drop off scan result which is older than 5 seconds when choosing which BSS to join -+ * -+ * 03 02 2012 terry.wu -+ * NULL -+ * Sync CFG80211 modification from branch 2,2. -+ * -+ * 01 16 2012 cp.wu -+ * [WCXRP00001169] [MT6620 Wi-Fi][Driver] API and behavior modification for preferred band -+ * configuration with corresponding network configuration -+ * correct typo. -+ * -+ * 01 16 2012 cp.wu -+ * [MT6620 Wi-Fi][Driver] API and behavior modification for preferred band configuration -+ * with corresponding network configuration -+ * add wlanSetPreferBandByNetwork() for glue layer to invoke for setting preferred -+ * band configuration corresponding to network type. -+ * -+ * 12 05 2011 cp.wu -+ * [WCXRP00001131] [MT6620 Wi-Fi][Driver][AIS] Implement connect-by-BSSID path -+ * add CONNECT_BY_BSSID policy -+ * -+ * 11 23 2011 cp.wu -+ * [WCXRP00001123] [MT6620 Wi-Fi][Driver] Add option to disable beacon content change detection -+ * add compile option to disable beacon content change detection. -+ * -+ * 11 04 2011 cp.wu -+ * [WCXRP00001085] [MT6628 Wi-Fi][Driver] deprecate old BSS-DESC if timestamp -+ * is reset with received beacon/probe response frames -+ * deprecate old BSS-DESC when timestamp in received beacon/probe response frames showed a smaller value than before -+ * -+ * 10 11 2011 cm.chang -+ * [WCXRP00001031] [All Wi-Fi][Driver] Check HT IE length to avoid wrong SCO parameter -+ * Ignore HT OP IE if its length field is not valid -+ * -+ * 09 30 2011 cp.wu -+ * [WCXRP00001021] [MT5931][Driver] Correct scan result generation for conversion between BSS type and operation mode -+ * correct type casting issue. -+ * -+ * 08 23 2011 yuche.tsai -+ * NULL -+ * Fix multicast address list issue. -+ * -+ * 08 11 2011 cp.wu -+ * [WCXRP00000830] [MT6620 Wi-Fi][Firmware] Use MDRDY counter to detect empty channel for shortening scan time -+ * sparse channel detection: -+ * driver: collect sparse channel information with scan-done event -+ * -+ * 08 10 2011 cp.wu -+ * [WCXRP00000922] [MT6620 Wi-Fi][Driver] traverse whole BSS-DESC list for removing -+ * traverse whole BSS-DESC list because BSSID is not unique anymore. -+ * -+ * 07 12 2011 cp.wu -+ * [WCXRP00000815] [MT6620 Wi-Fi][Driver] allow single BSSID with multiple -+ * SSID settings to work around some tricky AP which use space character as hidden SSID -+ * for multiple BSS descriptior detecting issue: -+ * 1) check BSSID for infrastructure network -+ * 2) check SSID for AdHoc network -+ * -+ * 07 12 2011 cp.wu -+ * [WCXRP00000815] [MT6620 Wi-Fi][Driver] allow single BSSID with multiple -+ * SSID settings to work around some tricky AP which use space character as hidden SSID -+ * check for BSSID for beacons used to update DTIM -+ * -+ * 07 12 2011 cp.wu -+ * [WCXRP00000815] [MT6620 Wi-Fi][Driver] allow single BSSID with multiple -+ * SSID settings to work around some tricky AP which use space character as hidden SSID -+ * do not check BSS descriptor for connected flag due to linksys's hidden -+ * SSID will use another BSS descriptor and never connected -+ * -+ * 07 11 2011 cp.wu -+ * [WCXRP00000815] [MT6620 Wi-Fi][Driver] allow single BSSID with multiple -+ * SSID settings to work around some tricky AP which use space character as hidden SSID -+ * just pass beacons with the same BSSID. -+ * -+ * 07 11 2011 wh.su -+ * [WCXRP00000849] [MT6620 Wi-Fi][Driver] Remove some of the WAPI define -+ * for make sure the value is initialize, for customer not enable WAPI -+ * For make sure wapi initial value is set. -+ * -+ * 06 28 2011 cp.wu -+ * [WCXRP00000815] [MT6620 Wi-Fi][Driver] allow single BSSID with multiple -+ * SSID settings to work around some tricky AP which use space character as hidden SSID -+ * Do not check for SSID as beacon content change due to the existence of -+ * single BSSID with multiple SSID AP configuration -+ * -+ * 06 27 2011 cp.wu -+ * [WCXRP00000815] [MT6620 Wi-Fi][Driver] allow single BSSID with multiple -+ * SSID settings to work around some tricky AP which use space character as hidden SSID -+ * 1. correct logic -+ * 2. replace only BSS-DESC which doesn't have a valid SSID. -+ * -+ * 06 27 2011 cp.wu -+ * [WCXRP00000815] [MT6620 Wi-Fi][Driver] allow single BSSID with multiple SSID -+ * settings to work around some tricky AP which use space character as hidden SSID -+ * remove unused temporal variable reference. -+ * -+ * 06 27 2011 cp.wu -+ * [WCXRP00000815] [MT6620 Wi-Fi][Driver] allow single BSSID with multiple SSID -+ * settings to work around some tricky AP which use space character as hidden SSID -+ * allow to have a single BSSID with multiple SSID to be presented in scanning result -+ * -+ * 06 02 2011 cp.wu -+ * [WCXRP00000757] [MT6620 Wi-Fi][Driver][SCN] take use of RLM API to filter out BSS in disallowed channels -+ * filter out BSS in disallowed channel by -+ * 1. do not add to scan result array if BSS is at disallowed channel -+ * 2. do not allow to search for BSS-DESC in disallowed channels -+ * -+ * 05 02 2011 cm.chang -+ * [WCXRP00000691] [MT6620 Wi-Fi][Driver] Workaround about AP's wrong HT capability IE to have wrong channel number -+ * Refine range of valid channel number -+ * -+ * 05 02 2011 cp.wu -+ * [MT6620 Wi-Fi][Driver] Take parsed result for channel information instead of -+ * hardware channel number passed from firmware domain -+ * take parsed result for generating scanning result with channel information. -+ * -+ * 05 02 2011 cm.chang -+ * [WCXRP00000691] [MT6620 Wi-Fi][Driver] Workaround about AP's wrong HT capability IE to have wrong channel number -+ * Check if channel is valided before record ing BSS channel -+ * -+ * 04 18 2011 terry.wu -+ * [WCXRP00000660] [MT6620 Wi-Fi][Driver] Remove flag CFG_WIFI_DIRECT_MOVED -+ * Remove flag CFG_WIFI_DIRECT_MOVED. -+ * -+ * 04 14 2011 cm.chang -+ * [WCXRP00000634] [MT6620 Wi-Fi][Driver][FW] 2nd BSS will not support 40MHz bandwidth for concurrency -+ * . -+ * -+ * 04 12 2011 eddie.chen -+ * [WCXRP00000617] [MT6620 Wi-Fi][DRV/FW] Fix for sigma -+ * Fix the sta index in processing security frame -+ * Simple flow control for TC4 to avoid mgt frames for PS STA to occupy the TC4 -+ * Add debug message. -+ * -+ * 03 25 2011 yuche.tsai -+ * NULL -+ * Always update Bss Type, for Bss Type for P2P Network is changing every time. -+ * -+ * 03 23 2011 yuche.tsai -+ * NULL -+ * Fix concurrent issue when AIS scan result would overwrite p2p scan result. -+ * -+ * 03 14 2011 cp.wu -+ * [WCXRP00000535] [MT6620 Wi-Fi][Driver] Fixed channel operation when AIS and Tethering are operating concurrently -+ * filtering out other BSS coming from adjacent channels -+ * -+ * 03 11 2011 chinglan.wang -+ * [WCXRP00000537] [MT6620 Wi-Fi][Driver] Can not connect to 802.11b/g/n mixed AP with WEP security. -+ * . -+ * -+ * 03 11 2011 cp.wu -+ * [WCXRP00000535] [MT6620 Wi-Fi][Driver] Fixed channel operation when AIS and Tethering are operating concurrently -+ * When fixed channel operation is necessary, AIS-FSM would scan and only connect for BSS on the specific channel -+ * -+ * 02 24 2011 cp.wu -+ * [WCXRP00000490] [MT6620 Wi-Fi][Driver][Win32] modify kalMsleep() implementation because NdisMSleep() -+ * won't sleep long enough for specified interval such as 500ms -+ * implement beacon change detection by checking SSID and supported rate. -+ * -+ * 02 22 2011 yuche.tsai -+ * [WCXRP00000480] [Volunteer Patch][MT6620][Driver] WCS IE format issue -+ * Fix WSC big endian issue. -+ * -+ * 02 21 2011 terry.wu -+ * [WCXRP00000476] [MT6620 Wi-Fi][Driver] Clean P2P scan list while removing P2P -+ * Clean P2P scan list while removing P2P. -+ * -+ * 01 27 2011 yuche.tsai -+ * [WCXRP00000399] [Volunteer Patch][MT6620/MT5931][Driver] Fix scan side effect after P2P module separate. -+ * Fix scan channel extension issue when p2p module is not registered. -+ * -+ * 01 26 2011 cm.chang -+ * [WCXRP00000395] [MT6620 Wi-Fi][Driver][FW] Search STA_REC with additional net type index argument -+ * . -+ * -+ * 01 21 2011 cp.wu -+ * [WCXRP00000380] [MT6620 Wi-Fi][Driver] SSID information should come from buffered -+ * BSS_DESC_T rather than using beacon-carried information -+ * SSID should come from buffered prBssDesc rather than beacon-carried information -+ * -+ * 01 14 2011 yuche.tsai -+ * [WCXRP00000352] [Volunteer Patch][MT6620][Driver] P2P Statsion Record Client List Issue -+ * Fix compile error. -+ * -+ * 01 14 2011 yuche.tsai -+ * [WCXRP00000352] [Volunteer Patch][MT6620][Driver] P2P Statsion Record Client List Issue -+ * Memfree for P2P Descriptor & P2P Descriptor List. -+ * -+ * 01 14 2011 yuche.tsai -+ * [WCXRP00000352] [Volunteer Patch][MT6620][Driver] P2P Statsion Record Client List Issue -+ * Free P2P Descriptor List & Descriptor under BSS Descriptor. -+ * -+ * 01 04 2011 cp.wu -+ * [WCXRP00000338] [MT6620 Wi-Fi][Driver] Separate kalMemAlloc into kmalloc -+ * and vmalloc implementations to ease physically continuous memory demands -+ * 1) correct typo in scan.c -+ * 2) TX descriptors, RX descriptos and management buffer should use virtually -+ * continuous buffer instead of physically continuous one -+ * -+ * 01 04 2011 cp.wu -+ * [WCXRP00000338] [MT6620 Wi-Fi][Driver] Separate kalMemAlloc into kmalloc -+ * and vmalloc implementations to ease physically continuous memory demands -+ * separate kalMemAlloc() into virtually-continuous and physically-continuous type to ease slab system pressure -+ * -+ * 12 31 2010 cp.wu -+ * [WCXRP00000327] [MT6620 Wi-Fi][Driver] Improve HEC WHQA 6972 workaround coverage in driver side -+ * while being unloaded, clear all pending interrupt then set LP-own to firmware -+ * -+ * 12 21 2010 cp.wu -+ * [WCXRP00000280] [MT6620 Wi-Fi][Driver] Enable BSS selection with best RCPI policy in SCN module -+ * SCN: enable BEST RSSI selection policy support -+ * -+ * 11 29 2010 cp.wu -+ * [WCXRP00000210] [MT6620 Wi-Fi][Driver][FW] Set RCPI value in STA_REC -+ * for initial TX rate selection of auto-rate algorithm -+ * update ucRcpi of STA_RECORD_T for AIS when -+ * 1) Beacons for IBSS merge is received -+ * 2) Associate Response for a connecting peer is received -+ * -+ * 11 03 2010 wh.su -+ * [WCXRP00000124] [MT6620 Wi-Fi] [Driver] Support the dissolve P2P Group -+ * Refine the HT rate disallow TKIP pairwise cipher . -+ * -+ * 10 12 2010 cp.wu -+ * [WCXRP00000091] [MT6620 Wi-Fi][Driver] Add scanning logic to filter out -+ * beacons which is received on the folding frequency -+ * trust HT IE if available for 5GHz band -+ * -+ * 10 11 2010 cp.wu -+ * [WCXRP00000091] [MT6620 Wi-Fi][Driver] Add scanning logic to filter out -+ * beacons which is received on the folding frequency -+ * add timing and strenght constraint for filtering out beacons with same SSID/TA but received on different channels -+ * -+ * 10 08 2010 wh.su -+ * [WCXRP00000085] [MT6620 Wif-Fi] [Driver] update the modified p2p state machine -+ * update the frog's new p2p state machine. -+ * -+ * 10 01 2010 yuche.tsai -+ * NULL -+ * [MT6620 P2P] Fix Big Endian Issue when parse P2P device name TLV. -+ * -+ * 09 24 2010 cp.wu -+ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning -+ * eliminate unused variables which lead gcc to argue -+ * -+ * 09 08 2010 cp.wu -+ * NULL -+ * use static memory pool for storing IEs of scanning result. -+ * -+ * 09 07 2010 yuche.tsai -+ * NULL -+ * When indicate scan result, append IE buffer information in the scan result. -+ * -+ * 09 03 2010 yuche.tsai -+ * NULL -+ * 1. Update Beacon RX count when running SLT. -+ * 2. Ignore Beacon when running SLT, would not update information from Beacon. -+ * -+ * 09 03 2010 kevin.huang -+ * NULL -+ * Refine #include sequence and solve recursive/nested #include issue -+ * -+ * 08 31 2010 kevin.huang -+ * NULL -+ * Use LINK LIST operation to process SCAN result -+ * -+ * 08 29 2010 yuche.tsai -+ * NULL -+ * 1. Fix P2P Descriptor List to be a link list, to avoid link corrupt after Bss Descriptor Free. -+ * 2.. Fix P2P Device Name Length BE issue. -+ * -+ * 08 23 2010 yuche.tsai -+ * NULL -+ * Add P2P Device Found Indication to supplicant -+ * -+ * 08 20 2010 cp.wu -+ * NULL -+ * reset BSS_DESC_T variables before parsing IE due to peer might have been reconfigured. -+ * -+ * 08 20 2010 yuche.tsai -+ * NULL -+ * Workaround for P2P Descriptor Infinite loop issue. -+ * -+ * 08 16 2010 cp.wu -+ * NULL -+ * Replace CFG_SUPPORT_BOW by CFG_ENABLE_BT_OVER_WIFI. -+ * There is no CFG_SUPPORT_BOW in driver domain source. -+ * -+ * 08 16 2010 yuche.tsai -+ * NULL -+ * Modify code of processing Probe Resonse frame for P2P. -+ * -+ * 08 12 2010 yuche.tsai -+ * NULL -+ * Add function to get P2P descriptor of BSS descriptor directly. -+ * -+ * 08 11 2010 yuche.tsai -+ * NULL -+ * Modify Scan result processing for P2P module. -+ * -+ * 08 05 2010 yuche.tsai -+ * NULL -+ * Update P2P Device Discovery result add function. -+ * -+ * 08 03 2010 cp.wu -+ * NULL -+ * surpress compilation warning. -+ * -+ * 07 26 2010 yuche.tsai -+ * -+ * Add support for Probe Request & Response parsing. -+ * -+ * 07 21 2010 cp.wu -+ * -+ * 1) change BG_SCAN to ONLINE_SCAN for consistent term -+ * 2) only clear scanning result when scan is permitted to do -+ * -+ * 07 21 2010 yuche.tsai -+ * -+ * Fix compile error for SCAN module while disabling P2P feature. -+ * -+ * 07 21 2010 yuche.tsai -+ * -+ * Add P2P Scan & Scan Result Parsing & Saving. -+ * -+ * 07 19 2010 wh.su -+ * -+ * update for security supporting. -+ * -+ * 07 19 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration. -+ * Add Ad-Hoc support to AIS-FSM -+ * -+ * 07 19 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration. -+ * SCN module is now able to handle multiple concurrent scanning requests -+ * -+ * 07 15 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration. -+ * driver no longer generates probe request frames -+ * -+ * 07 14 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration. -+ * remove timer in DRV-SCN. -+ * -+ * 07 09 2010 cp.wu -+ * -+ * 1) separate AIS_FSM state for two kinds of scanning. (OID triggered scan, and scan-for-connection) -+ * 2) eliminate PRE_BSS_DESC_T, Beacon/PrebResp is now parsed in single pass -+ * 3) implment DRV-SCN module, currently only accepts single scan request, -+ * other request will be directly dropped by returning BUSY -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 07 08 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * take use of RLM module for parsing/generating HT IEs for 11n capability -+ * -+ * 07 05 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) ignore RSN checking when RSN is not turned on. -+ * 2) set STA-REC deactivation callback as NULL -+ * 3) add variable initialization API based on PHY configuration -+ * -+ * 07 05 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * correct BSS_DESC_T initialization after allocated. -+ * -+ * 07 02 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) for event packet, no need to fill RFB. -+ * 2) when wlanAdapterStart() failed, no need to initialize state machines -+ * 3) after Beacon/ProbeResp parsing, corresponding BSS_DESC_T should be marked as IE-parsed -+ * -+ * 07 01 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add scan uninitialization procedure -+ * -+ * 06 30 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * if beacon/probe-resp is received in 2.4GHz bands and there is ELEM_ID_DS_PARAM_SET IE available, -+ * trust IE instead of RMAC information -+ * -+ * 06 29 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) sync to. CMD/EVENT document v0.03 -+ * 2) simplify DTIM period parsing in scan.c only, bss.c no longer parses it again. -+ * 3) send command packet to indicate FW-PM after -+ * a) 1st beacon is received after AIS has connected to an AP -+ * b) IBSS-ALONE has been created -+ * c) IBSS-MERGE has occurred -+ * -+ * 06 28 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * send MMPDU in basic rate. -+ * -+ * 06 25 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * modify Beacon/ProbeResp to complete parsing, -+ * because host software has looser memory usage restriction -+ * -+ * 06 23 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * integrate . -+ * -+ * 06 22 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * comment out RLM APIs by CFG_RLM_MIGRATION. -+ * -+ * 06 21 2010 yuche.tsai -+ * [WPD00003839][MT6620 5931][P2P] Feature migration -+ * Update P2P Function call. -+ * -+ * 06 21 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * RSN/PRIVACY compilation flag awareness correction -+ * -+ * 06 21 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * specify correct value for management frames. -+ * -+ * 06 18 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Provide cnmMgtPktAlloc() and alloc/free function of msg/buf -+ * -+ * 06 18 2010 wh.su -+ * [WPD00003840][MT6620 5931] Security migration -+ * migration from MT6620 firmware. -+ * -+ * 06 17 2010 yuche.tsai -+ * [WPD00003839][MT6620 5931][P2P] Feature migration -+ * Fix compile error when enable P2P function. -+ * -+ * 06 15 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * correct when ADHOC support is turned on. -+ * -+ * 06 15 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add scan.c. -+ * -+ * 06 04 2010 george.huang -+ * [BORA00000678][MT6620]WiFi LP integration -+ * [PM] Support U-APSD for STA mode -+ * -+ * 05 28 2010 wh.su -+ * [BORA00000680][MT6620] Support the statistic for Micxxsoft os query -+ * adding the TKIP disallow join a HT AP code. -+ * -+ * 05 14 2010 kevin.huang -+ * [BORA00000794][WIFISYS][New Feature]Power Management Support -+ * Add more chance of JOIN retry for BG_SCAN -+ * -+ * 05 12 2010 kevin.huang -+ * [BORA00000794][WIFISYS][New Feature]Power Management Support -+ * Add Power Management - Legacy PS-POLL support. -+ * -+ * 04 29 2010 wh.su -+ * [BORA00000637][MT6620 Wi-Fi] [Bug] WPA2 pre-authentication timer not correctly initialize -+ * adjsut the pre-authentication code. -+ * -+ * 04 27 2010 kevin.huang -+ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support -+ * Add Set Slot Time and Beacon Timeout Support for AdHoc Mode -+ * -+ * 04 24 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * g_aprBssInfo[] depends on CFG_SUPPORT_P2P and CFG_SUPPORT_BOW -+ * -+ * 04 19 2010 kevin.huang -+ * [BORA00000714][WIFISYS][New Feature]Beacon Timeout Support -+ * Add Beacon Timeout Support and will send Null frame to diagnose connection -+ * -+ * 04 13 2010 kevin.huang -+ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support -+ * Add new HW CH macro support -+ * -+ * 04 06 2010 wh.su -+ * [BORA00000680][MT6620] Support the statistic for Micxxsoft os query -+ * fixed the firmware return the broadcast frame at wrong tc. -+ * -+ * 03 29 2010 wh.su -+ * [BORA00000605][WIFISYS] Phase3 Integration -+ * let the rsn wapi IE always parsing. -+ * -+ * 03 24 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Not carry HT cap when being associated with b/g only AP -+ * -+ * 03 18 2010 kevin.huang -+ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support -+ * Solve the compile warning for 'return non-void' function -+ * -+ * 03 16 2010 kevin.huang -+ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support -+ * Add AdHoc Mode -+ * -+ * 03 10 2010 kevin.huang -+ * [BORA00000654][WIFISYS][New Feature] CNM Module - Ch Manager Support -+ * -+ * * * * * * * * * * * * * * * * Add Channel Manager for arbitration of JOIN and SCAN Req -+ * -+ * 03 03 2010 wh.su -+ * [BORA00000637][MT6620 Wi-Fi] [Bug] WPA2 pre-authentication timer not correctly initialize -+ * move the AIS specific variable for security to AIS specific structure. -+ * -+ * 03 01 2010 wh.su -+ * [BORA00000605][WIFISYS] Phase3 Integration -+ * Refine the variable and parameter for security. -+ * -+ * 02 26 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Fix No PKT_INFO_T issue -+ * -+ * 02 26 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Update outgoing ProbeRequest Frame's TX data rate -+ * -+ * 02 23 2010 wh.su -+ * [BORA00000592][MT6620 Wi-Fi] Adding the security related code for driver -+ * refine the scan procedure, reduce the WPA and WAPI IE parsing, and move the parsing to the time for join. -+ * -+ * 02 23 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Add support scan channel 1~14 and update scan result's frequency infou1rwduu`wvpghlqg|n`slk+mpdkb -+ * -+ * 02 04 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Add AAA Module Support, Revise Net Type to Net Type Index for array lookup -+ * -+ * 01 27 2010 wh.su -+ * [BORA00000476][Wi-Fi][firmware] Add the security module initialize code -+ * add and fixed some security function. -+ * -+ * 01 22 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Support protection and bandwidth switch -+ * -+ * 01 20 2010 kevin.huang -+ * [BORA00000569][WIFISYS] Phase 2 Integration Test -+ * Add PHASE_2_INTEGRATION_WORK_AROUND and CFG_SUPPORT_BCM flags -+ * -+ * 01 11 2010 kevin.huang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Add Deauth and Disassoc Handler -+ * -+ * 01 08 2010 kevin.huang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * -+ * Refine Beacon processing, add read RF channel from RX Status -+ * -+ * 01 04 2010 tehuang.liu -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * For working out the first connection Chariot-verified version -+ * -+ * 12 18 2009 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * . -+ * -+ * Dec 12 2009 mtk01104 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Modify u2EstimatedExtraIELen for probe request -+ * -+ * Dec 9 2009 mtk01104 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Add HT cap IE to probe request -+ * -+ * Dec 7 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Fix lint warning -+ * -+ * -+ * Dec 3 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Update the process of SCAN Result by adding more Phy Attributes -+ * -+ * Dec 1 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * adjust the function and code for meet the new define -+ * -+ * Nov 30 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Rename u4RSSI to i4RSSI -+ * -+ * Nov 30 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Report event of scan result to host -+ * -+ * Nov 26 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Fix SCAN Record update -+ * -+ * Nov 24 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Revise MGMT Handler with Retain Status and Integrate with TXM -+ * -+ * Nov 23 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Add (Ext)Support Rate Set IE to ProbeReq -+ * -+ * Nov 20 2009 mtk02468 -+ * [BORA00000337] To check in codes for FPGA emulation -+ * Removed the use of SW_RFB->u2FrameLength -+ * -+ * Nov 20 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Fix uninitial aucMacAddress[] for ProbeReq -+ * -+ * Nov 16 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Add scanSearchBssDescByPolicy() -+ * -+ * Nov 5 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Add Send Probe Request Frame -+ * -+ * Oct 30 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "precomp.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+#define REPLICATED_BEACON_TIME_THRESHOLD (3000) -+#define REPLICATED_BEACON_FRESH_PERIOD (10000) -+#define REPLICATED_BEACON_STRENGTH_THRESHOLD (32) -+ -+#define ROAMING_NO_SWING_RCPI_STEP (10) -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is used by SCN to initialize its variables -+* -+* @param (none) -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID scnInit(IN P_ADAPTER_T prAdapter) -+{ -+ P_SCAN_INFO_T prScanInfo; -+ P_BSS_DESC_T prBSSDesc; -+ PUINT_8 pucBSSBuff; -+ UINT_32 i; -+ -+ ASSERT(prAdapter); -+ -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ pucBSSBuff = &prScanInfo->aucScanBuffer[0]; -+ -+ DBGLOG(SCN, INFO, "->scnInit()\n"); -+ -+ /* 4 <1> Reset STATE and Message List */ -+ prScanInfo->eCurrentState = SCAN_STATE_IDLE; -+ -+ prScanInfo->rLastScanCompletedTime = (OS_SYSTIME) 0; -+ -+ LINK_INITIALIZE(&prScanInfo->rPendingMsgList); -+ -+ /* 4 <2> Reset link list of BSS_DESC_T */ -+ kalMemZero((PVOID) pucBSSBuff, SCN_MAX_BUFFER_SIZE); -+ -+ LINK_INITIALIZE(&prScanInfo->rFreeBSSDescList); -+ LINK_INITIALIZE(&prScanInfo->rBSSDescList); -+ -+ for (i = 0; i < CFG_MAX_NUM_BSS_LIST; i++) { -+ -+ prBSSDesc = (P_BSS_DESC_T) pucBSSBuff; -+ -+ LINK_INSERT_TAIL(&prScanInfo->rFreeBSSDescList, &prBSSDesc->rLinkEntry); -+ -+ pucBSSBuff += ALIGN_4(sizeof(BSS_DESC_T)); -+ } -+ /* Check if the memory allocation consist with this initialization function */ -+ ASSERT(((ULONG) pucBSSBuff - (ULONG)&prScanInfo->aucScanBuffer[0]) == SCN_MAX_BUFFER_SIZE); -+ -+ /* reset freest channel information */ -+ prScanInfo->fgIsSparseChannelValid = FALSE; -+ -+ /* reset NLO state */ -+ prScanInfo->fgNloScanning = FALSE; -+ prScanInfo->fgPscnOnnning = FALSE; -+ -+ prScanInfo->prPscnParam = kalMemAlloc(sizeof(PSCN_PARAM_T), VIR_MEM_TYPE); -+ if (prScanInfo->prPscnParam) -+ kalMemZero(prScanInfo->prPscnParam, sizeof(PSCN_PARAM_T)); -+ -+} /* end of scnInit() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is used by SCN to uninitialize its variables -+* -+* @param (none) -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID scnUninit(IN P_ADAPTER_T prAdapter) -+{ -+ P_SCAN_INFO_T prScanInfo; -+ -+ ASSERT(prAdapter); -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ -+ DBGLOG(SCN, INFO, "->scnUninit()\n"); -+ -+ /* 4 <1> Reset STATE and Message List */ -+ prScanInfo->eCurrentState = SCAN_STATE_IDLE; -+ -+ prScanInfo->rLastScanCompletedTime = (OS_SYSTIME) 0; -+ -+ /* NOTE(Kevin): Check rPendingMsgList ? */ -+ -+ /* 4 <2> Reset link list of BSS_DESC_T */ -+ LINK_INITIALIZE(&prScanInfo->rFreeBSSDescList); -+ LINK_INITIALIZE(&prScanInfo->rBSSDescList); -+ -+ kalMemFree(prScanInfo->prPscnParam, VIR_MEM_TYPE, sizeof(PSCN_PARAM_T)); -+ -+} /* end of scnUninit() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Find the corresponding BSS Descriptor according to given BSSID -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* @param[in] aucBSSID Given BSSID. -+* -+* @return Pointer to BSS Descriptor, if found. NULL, if not found -+*/ -+/*----------------------------------------------------------------------------*/ -+P_BSS_DESC_T scanSearchBssDescByBssid(IN P_ADAPTER_T prAdapter, IN UINT_8 aucBSSID[]) -+{ -+ return scanSearchBssDescByBssidAndSsid(prAdapter, aucBSSID, FALSE, NULL); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Find the corresponding BSS Descriptor according to given BSSID -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* @param[in] aucBSSID Given BSSID. -+* @param[in] fgCheckSsid Need to check SSID or not. (for multiple SSID with single BSSID cases) -+* @param[in] prSsid Specified SSID -+* -+* @return Pointer to BSS Descriptor, if found. NULL, if not found -+*/ -+/*----------------------------------------------------------------------------*/ -+P_BSS_DESC_T -+scanSearchBssDescByBssidAndSsid(IN P_ADAPTER_T prAdapter, -+ IN UINT_8 aucBSSID[], IN BOOLEAN fgCheckSsid, IN P_PARAM_SSID_T prSsid) -+{ -+ P_SCAN_INFO_T prScanInfo; -+ P_LINK_T prBSSDescList; -+ P_BSS_DESC_T prBssDesc; -+ P_BSS_DESC_T prDstBssDesc = (P_BSS_DESC_T) NULL; -+ -+ ASSERT(prAdapter); -+ ASSERT(aucBSSID); -+ -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ -+ prBSSDescList = &prScanInfo->rBSSDescList; -+ -+ /* Search BSS Desc from current SCAN result list. */ -+ LINK_FOR_EACH_ENTRY(prBssDesc, prBSSDescList, rLinkEntry, BSS_DESC_T) { -+ -+ if (EQUAL_MAC_ADDR(prBssDesc->aucBSSID, aucBSSID)) { -+ if (fgCheckSsid == FALSE || prSsid == NULL) -+ return prBssDesc; -+ -+ if (EQUAL_SSID(prBssDesc->aucSSID, -+ prBssDesc->ucSSIDLen, prSsid->aucSsid, prSsid->u4SsidLen)) { -+ return prBssDesc; -+ } else if (prDstBssDesc == NULL && prBssDesc->fgIsHiddenSSID == TRUE) { -+ prDstBssDesc = prBssDesc; -+ } else { -+ /* 20120206 frog: Equal BSSID but not SSID, SSID not hidden, -+ * SSID must be updated. */ -+ COPY_SSID(prBssDesc->aucSSID, -+ prBssDesc->ucSSIDLen, prSsid->aucSsid, prSsid->u4SsidLen); -+ return prBssDesc; -+ } -+ } -+ } -+ -+ return prDstBssDesc; -+ -+} /* end of scanSearchBssDescByBssid() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Find the corresponding BSS Descriptor according to given Transmitter Address. -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* @param[in] aucSrcAddr Given Source Address(TA). -+* -+* @return Pointer to BSS Descriptor, if found. NULL, if not found -+*/ -+/*----------------------------------------------------------------------------*/ -+P_BSS_DESC_T scanSearchBssDescByTA(IN P_ADAPTER_T prAdapter, IN UINT_8 aucSrcAddr[]) -+{ -+ return scanSearchBssDescByTAAndSsid(prAdapter, aucSrcAddr, FALSE, NULL); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Find the corresponding BSS Descriptor according to given Transmitter Address. -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* @param[in] aucSrcAddr Given Source Address(TA). -+* @param[in] fgCheckSsid Need to check SSID or not. (for multiple SSID with single BSSID cases) -+* @param[in] prSsid Specified SSID -+* -+* @return Pointer to BSS Descriptor, if found. NULL, if not found -+*/ -+/*----------------------------------------------------------------------------*/ -+P_BSS_DESC_T -+scanSearchBssDescByTAAndSsid(IN P_ADAPTER_T prAdapter, -+ IN UINT_8 aucSrcAddr[], IN BOOLEAN fgCheckSsid, IN P_PARAM_SSID_T prSsid) -+{ -+ P_SCAN_INFO_T prScanInfo; -+ P_LINK_T prBSSDescList; -+ P_BSS_DESC_T prBssDesc; -+ P_BSS_DESC_T prDstBssDesc = (P_BSS_DESC_T) NULL; -+ -+ ASSERT(prAdapter); -+ ASSERT(aucSrcAddr); -+ -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ -+ prBSSDescList = &prScanInfo->rBSSDescList; -+ -+ /* Search BSS Desc from current SCAN result list. */ -+ LINK_FOR_EACH_ENTRY(prBssDesc, prBSSDescList, rLinkEntry, BSS_DESC_T) { -+ -+ if (EQUAL_MAC_ADDR(prBssDesc->aucSrcAddr, aucSrcAddr)) { -+ if (fgCheckSsid == FALSE || prSsid == NULL) -+ return prBssDesc; -+ -+ if (EQUAL_SSID(prBssDesc->aucSSID, -+ prBssDesc->ucSSIDLen, prSsid->aucSsid, prSsid->u4SsidLen)) { -+ return prBssDesc; -+ } else if (prDstBssDesc == NULL && prBssDesc->fgIsHiddenSSID == TRUE) { -+ prDstBssDesc = prBssDesc; -+ } -+ -+ } -+ } -+ -+ return prDstBssDesc; -+ -+} /* end of scanSearchBssDescByTA() */ -+ -+#if CFG_SUPPORT_HOTSPOT_2_0 -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Find the corresponding BSS Descriptor according to given BSSID -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* @param[in] aucBSSID Given BSSID. -+* @param[in] fgCheckSsid Need to check SSID or not. (for multiple SSID with single BSSID cases) -+* @param[in] prSsid Specified SSID -+* -+* @return Pointer to BSS Descriptor, if found. NULL, if not found -+*/ -+/*----------------------------------------------------------------------------*/ -+P_BSS_DESC_T scanSearchBssDescByBssidAndLatestUpdateTime(IN P_ADAPTER_T prAdapter, IN UINT_8 aucBSSID[]) -+{ -+ P_SCAN_INFO_T prScanInfo; -+ P_LINK_T prBSSDescList; -+ P_BSS_DESC_T prBssDesc; -+ P_BSS_DESC_T prDstBssDesc = (P_BSS_DESC_T) NULL; -+ OS_SYSTIME rLatestUpdateTime = 0; -+ -+ ASSERT(prAdapter); -+ ASSERT(aucBSSID); -+ -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ -+ prBSSDescList = &prScanInfo->rBSSDescList; -+ -+ /* Search BSS Desc from current SCAN result list. */ -+ LINK_FOR_EACH_ENTRY(prBssDesc, prBSSDescList, rLinkEntry, BSS_DESC_T) { -+ -+ if (EQUAL_MAC_ADDR(prBssDesc->aucBSSID, aucBSSID)) { -+ if (!rLatestUpdateTime || CHECK_FOR_EXPIRATION(prBssDesc->rUpdateTime, rLatestUpdateTime)) { -+ prDstBssDesc = prBssDesc; -+ COPY_SYSTIME(rLatestUpdateTime, prBssDesc->rUpdateTime); -+ } -+ } -+ } -+ -+ return prDstBssDesc; -+ -+} /* end of scanSearchBssDescByBssid() */ -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Find the corresponding BSS Descriptor according to -+* given eBSSType, BSSID and Transmitter Address -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* @param[in] eBSSType BSS Type of incoming Beacon/ProbeResp frame. -+* @param[in] aucBSSID Given BSSID of Beacon/ProbeResp frame. -+* @param[in] aucSrcAddr Given source address (TA) of Beacon/ProbeResp frame. -+* -+* @return Pointer to BSS Descriptor, if found. NULL, if not found -+*/ -+/*----------------------------------------------------------------------------*/ -+P_BSS_DESC_T -+scanSearchExistingBssDesc(IN P_ADAPTER_T prAdapter, -+ IN ENUM_BSS_TYPE_T eBSSType, IN UINT_8 aucBSSID[], IN UINT_8 aucSrcAddr[]) -+{ -+ return scanSearchExistingBssDescWithSsid(prAdapter, eBSSType, aucBSSID, aucSrcAddr, FALSE, NULL); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Find the corresponding BSS Descriptor according to -+* given eBSSType, BSSID and Transmitter Address -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* @param[in] eBSSType BSS Type of incoming Beacon/ProbeResp frame. -+* @param[in] aucBSSID Given BSSID of Beacon/ProbeResp frame. -+* @param[in] aucSrcAddr Given source address (TA) of Beacon/ProbeResp frame. -+* @param[in] fgCheckSsid Need to check SSID or not. (for multiple SSID with single BSSID cases) -+* @param[in] prSsid Specified SSID -+* -+* @return Pointer to BSS Descriptor, if found. NULL, if not found -+*/ -+/*----------------------------------------------------------------------------*/ -+P_BSS_DESC_T -+scanSearchExistingBssDescWithSsid(IN P_ADAPTER_T prAdapter, -+ IN ENUM_BSS_TYPE_T eBSSType, -+ IN UINT_8 aucBSSID[], -+ IN UINT_8 aucSrcAddr[], IN BOOLEAN fgCheckSsid, IN P_PARAM_SSID_T prSsid) -+{ -+ P_SCAN_INFO_T prScanInfo; -+ P_BSS_DESC_T prBssDesc, prIBSSBssDesc; -+ P_LINK_T prBSSDescList; -+ P_LINK_T prFreeBSSDescList; -+ -+ -+ ASSERT(prAdapter); -+ ASSERT(aucSrcAddr); -+ -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ -+ switch (eBSSType) { -+ case BSS_TYPE_P2P_DEVICE: -+ fgCheckSsid = FALSE; -+ case BSS_TYPE_INFRASTRUCTURE: -+ case BSS_TYPE_BOW_DEVICE: -+ { -+ prBssDesc = scanSearchBssDescByBssidAndSsid(prAdapter, aucBSSID, fgCheckSsid, prSsid); -+ -+ /* if (eBSSType == prBssDesc->eBSSType) */ -+ -+ return prBssDesc; -+ } -+ -+ case BSS_TYPE_IBSS: -+ { -+ prIBSSBssDesc = scanSearchBssDescByBssidAndSsid(prAdapter, aucBSSID, fgCheckSsid, prSsid); -+ prBssDesc = scanSearchBssDescByTAAndSsid(prAdapter, aucSrcAddr, fgCheckSsid, prSsid); -+ -+ /* NOTE(Kevin): -+ * Rules to maintain the SCAN Result: -+ * For AdHoc - -+ * CASE I We have TA1(BSSID1), but it change its BSSID to BSSID2 -+ * -> Update TA1 entry's BSSID. -+ * CASE II We have TA1(BSSID1), and get TA1(BSSID1) again -+ * -> Update TA1 entry's contain. -+ * CASE III We have a SCAN result TA1(BSSID1), and TA2(BSSID2). Sooner or -+ * later, TA2 merge into TA1, we get TA2(BSSID1) -+ * -> Remove TA2 first and then replace TA1 entry's TA with TA2, -+ * Still have only one entry of BSSID. -+ * CASE IV We have a SCAN result TA1(BSSID1), and another TA2 also merge into BSSID1. -+ * -> Replace TA1 entry's TA with TA2, Still have only one entry. -+ * CASE V New IBSS -+ * -> Add this one to SCAN result. -+ */ -+ if (prBssDesc) { -+ if ((!prIBSSBssDesc) || /* CASE I */ -+ (prBssDesc == prIBSSBssDesc)) { /* CASE II */ -+ -+ return prBssDesc; -+ } /* CASE III */ -+ -+ prBSSDescList = &prScanInfo->rBSSDescList; -+ prFreeBSSDescList = &prScanInfo->rFreeBSSDescList; -+ -+ /* Remove this BSS Desc from the BSS Desc list */ -+ LINK_REMOVE_KNOWN_ENTRY(prBSSDescList, prBssDesc); -+ -+ /* Return this BSS Desc to the free BSS Desc list. */ -+ LINK_INSERT_TAIL(prFreeBSSDescList, &prBssDesc->rLinkEntry); -+ -+ return prIBSSBssDesc; -+ } -+ -+ if (prIBSSBssDesc) { /* CASE IV */ -+ -+ return prIBSSBssDesc; -+ } -+ /* CASE V */ -+ break; /* Return NULL; */ -+ } -+ -+ default: -+ break; -+ } -+ -+ return (P_BSS_DESC_T) NULL; -+ -+} /* end of scanSearchExistingBssDesc() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Delete BSS Descriptors from current list according to given Remove Policy. -+* -+* @param[in] u4RemovePolicy Remove Policy. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID scanRemoveBssDescsByPolicy(IN P_ADAPTER_T prAdapter, IN UINT_32 u4RemovePolicy) -+{ -+ P_CONNECTION_SETTINGS_T prConnSettings; -+ P_SCAN_INFO_T prScanInfo; -+ P_LINK_T prBSSDescList; -+ P_LINK_T prFreeBSSDescList; -+ P_BSS_DESC_T prBssDesc; -+ -+ ASSERT(prAdapter); -+ -+ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ prBSSDescList = &prScanInfo->rBSSDescList; -+ prFreeBSSDescList = &prScanInfo->rFreeBSSDescList; -+ -+ /* DBGLOG(SCN, TRACE, ("Before Remove - Number Of SCAN Result = %ld\n", */ -+ /* prBSSDescList->u4NumElem)); */ -+ -+ if (u4RemovePolicy & SCN_RM_POLICY_TIMEOUT) { -+ P_BSS_DESC_T prBSSDescNext; -+ OS_SYSTIME rCurrentTime; -+ -+ GET_CURRENT_SYSTIME(&rCurrentTime); -+ -+ /* Search BSS Desc from current SCAN result list. */ -+ LINK_FOR_EACH_ENTRY_SAFE(prBssDesc, prBSSDescNext, prBSSDescList, rLinkEntry, BSS_DESC_T) { -+ -+ if ((u4RemovePolicy & SCN_RM_POLICY_EXCLUDE_CONNECTED) && -+ (prBssDesc->fgIsConnected || prBssDesc->fgIsConnecting)) { -+ /* Don't remove the one currently we are connected. */ -+ continue; -+ } -+ -+ if (CHECK_FOR_TIMEOUT(rCurrentTime, prBssDesc->rUpdateTime, -+ SEC_TO_SYSTIME(SCN_BSS_DESC_REMOVE_TIMEOUT_SEC))) { -+ -+ /* DBGLOG(SCN, TRACE, ("Remove TIMEOUT BSS DESC(%#x): -+ * MAC: %pM, Current Time = %08lx, Update Time = %08lx\n", */ -+ /* prBssDesc, prBssDesc->aucBSSID, rCurrentTime, prBssDesc->rUpdateTime)); */ -+ -+ /* Remove this BSS Desc from the BSS Desc list */ -+ LINK_REMOVE_KNOWN_ENTRY(prBSSDescList, prBssDesc); -+ -+ /* Return this BSS Desc to the free BSS Desc list. */ -+ LINK_INSERT_TAIL(prFreeBSSDescList, &prBssDesc->rLinkEntry); -+ } -+ } -+ } else if (u4RemovePolicy & SCN_RM_POLICY_OLDEST_HIDDEN) { -+ P_BSS_DESC_T prBssDescOldest = (P_BSS_DESC_T) NULL; -+ -+ /* Search BSS Desc from current SCAN result list. */ -+ LINK_FOR_EACH_ENTRY(prBssDesc, prBSSDescList, rLinkEntry, BSS_DESC_T) { -+ -+ if ((u4RemovePolicy & SCN_RM_POLICY_EXCLUDE_CONNECTED) && -+ (prBssDesc->fgIsConnected || prBssDesc->fgIsConnecting)) { -+ /* Don't remove the one currently we are connected. */ -+ continue; -+ } -+ -+ if (!prBssDesc->fgIsHiddenSSID) -+ continue; -+ -+ if (!prBssDescOldest) { /* 1st element */ -+ prBssDescOldest = prBssDesc; -+ continue; -+ } -+ -+ if (TIME_BEFORE(prBssDesc->rUpdateTime, prBssDescOldest->rUpdateTime)) -+ prBssDescOldest = prBssDesc; -+ } -+ -+ if (prBssDescOldest) { -+ -+ /* DBGLOG(SCN, TRACE, ("Remove OLDEST HIDDEN BSS DESC(%#x): -+ * MAC: %pM, Update Time = %08lx\n", */ -+ /* prBssDescOldest, prBssDescOldest->aucBSSID, prBssDescOldest->rUpdateTime)); */ -+ -+ /* Remove this BSS Desc from the BSS Desc list */ -+ LINK_REMOVE_KNOWN_ENTRY(prBSSDescList, prBssDescOldest); -+ -+ /* Return this BSS Desc to the free BSS Desc list. */ -+ LINK_INSERT_TAIL(prFreeBSSDescList, &prBssDescOldest->rLinkEntry); -+ } -+ } else if (u4RemovePolicy & SCN_RM_POLICY_SMART_WEAKEST) { -+ P_BSS_DESC_T prBssDescWeakest = (P_BSS_DESC_T) NULL; -+ P_BSS_DESC_T prBssDescWeakestSameSSID = (P_BSS_DESC_T) NULL; -+ UINT_32 u4SameSSIDCount = 0; -+ -+ /* Search BSS Desc from current SCAN result list. */ -+ LINK_FOR_EACH_ENTRY(prBssDesc, prBSSDescList, rLinkEntry, BSS_DESC_T) { -+ -+ if ((u4RemovePolicy & SCN_RM_POLICY_EXCLUDE_CONNECTED) && -+ (prBssDesc->fgIsConnected || prBssDesc->fgIsConnecting)) { -+ /* Don't remove the one currently we are connected. */ -+ continue; -+ } -+ -+ if ((!prBssDesc->fgIsHiddenSSID) && -+ (EQUAL_SSID(prBssDesc->aucSSID, -+ prBssDesc->ucSSIDLen, prConnSettings->aucSSID, prConnSettings->ucSSIDLen))) { -+ -+ u4SameSSIDCount++; -+ -+ if (!prBssDescWeakestSameSSID) -+ prBssDescWeakestSameSSID = prBssDesc; -+ else if (prBssDesc->ucRCPI < prBssDescWeakestSameSSID->ucRCPI) -+ prBssDescWeakestSameSSID = prBssDesc; -+ } -+ -+ if (!prBssDescWeakest) { /* 1st element */ -+ prBssDescWeakest = prBssDesc; -+ continue; -+ } -+ -+ if (prBssDesc->ucRCPI < prBssDescWeakest->ucRCPI) -+ prBssDescWeakest = prBssDesc; -+ -+ } -+ -+ if ((u4SameSSIDCount >= SCN_BSS_DESC_SAME_SSID_THRESHOLD) && (prBssDescWeakestSameSSID)) -+ prBssDescWeakest = prBssDescWeakestSameSSID; -+ -+ if (prBssDescWeakest) { -+ -+ /* DBGLOG(SCN, TRACE, ("Remove WEAKEST BSS DESC(%#x): MAC: %pM, Update Time = %08lx\n", */ -+ /* prBssDescOldest, prBssDescOldest->aucBSSID, prBssDescOldest->rUpdateTime)); */ -+ -+ /* Remove this BSS Desc from the BSS Desc list */ -+ LINK_REMOVE_KNOWN_ENTRY(prBSSDescList, prBssDescWeakest); -+ -+ /* Return this BSS Desc to the free BSS Desc list. */ -+ LINK_INSERT_TAIL(prFreeBSSDescList, &prBssDescWeakest->rLinkEntry); -+ } -+ } else if (u4RemovePolicy & SCN_RM_POLICY_ENTIRE) { -+ P_BSS_DESC_T prBSSDescNext; -+ -+ LINK_FOR_EACH_ENTRY_SAFE(prBssDesc, prBSSDescNext, prBSSDescList, rLinkEntry, BSS_DESC_T) { -+ -+ if ((u4RemovePolicy & SCN_RM_POLICY_EXCLUDE_CONNECTED) && -+ (prBssDesc->fgIsConnected || prBssDesc->fgIsConnecting)) { -+ /* Don't remove the one currently we are connected. */ -+ continue; -+ } -+ -+ /* Remove this BSS Desc from the BSS Desc list */ -+ LINK_REMOVE_KNOWN_ENTRY(prBSSDescList, prBssDesc); -+ -+ /* Return this BSS Desc to the free BSS Desc list. */ -+ LINK_INSERT_TAIL(prFreeBSSDescList, &prBssDesc->rLinkEntry); -+ } -+ -+ } -+ -+ return; -+ -+} /* end of scanRemoveBssDescsByPolicy() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Delete BSS Descriptors from current list according to given BSSID. -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* @param[in] aucBSSID Given BSSID. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID scanRemoveBssDescByBssid(IN P_ADAPTER_T prAdapter, IN UINT_8 aucBSSID[]) -+{ -+ P_SCAN_INFO_T prScanInfo; -+ P_LINK_T prBSSDescList; -+ P_LINK_T prFreeBSSDescList; -+ P_BSS_DESC_T prBssDesc = (P_BSS_DESC_T) NULL; -+ P_BSS_DESC_T prBSSDescNext; -+ -+ ASSERT(prAdapter); -+ ASSERT(aucBSSID); -+ -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ prBSSDescList = &prScanInfo->rBSSDescList; -+ prFreeBSSDescList = &prScanInfo->rFreeBSSDescList; -+ -+ /* Check if such BSS Descriptor exists in a valid list */ -+ LINK_FOR_EACH_ENTRY_SAFE(prBssDesc, prBSSDescNext, prBSSDescList, rLinkEntry, BSS_DESC_T) { -+ -+ if (EQUAL_MAC_ADDR(prBssDesc->aucBSSID, aucBSSID)) { -+ -+ /* Remove this BSS Desc from the BSS Desc list */ -+ LINK_REMOVE_KNOWN_ENTRY(prBSSDescList, prBssDesc); -+ -+ /* Return this BSS Desc to the free BSS Desc list. */ -+ LINK_INSERT_TAIL(prFreeBSSDescList, &prBssDesc->rLinkEntry); -+ -+ /* BSSID is not unique, so need to traverse whols link-list */ -+ } -+ } -+ -+} /* end of scanRemoveBssDescByBssid() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Delete BSS Descriptors from current list according to given band configuration -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* @param[in] eBand Given band -+* @param[in] eNetTypeIndex AIS - Remove IBSS/Infrastructure BSS -+* BOW - Remove BOW BSS -+* P2P - Remove P2P BSS -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+scanRemoveBssDescByBandAndNetwork(IN P_ADAPTER_T prAdapter, -+ IN ENUM_BAND_T eBand, IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex) -+{ -+ P_SCAN_INFO_T prScanInfo; -+ P_LINK_T prBSSDescList; -+ P_LINK_T prFreeBSSDescList; -+ P_BSS_DESC_T prBssDesc = (P_BSS_DESC_T) NULL; -+ P_BSS_DESC_T prBSSDescNext; -+ BOOLEAN fgToRemove; -+ -+ ASSERT(prAdapter); -+ ASSERT(eBand <= BAND_NUM); -+ ASSERT(eNetTypeIndex <= NETWORK_TYPE_INDEX_NUM); -+ -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ prBSSDescList = &prScanInfo->rBSSDescList; -+ prFreeBSSDescList = &prScanInfo->rFreeBSSDescList; -+ -+ if (eBand == BAND_NULL) -+ return; /* no need to do anything, keep all scan result */ -+ -+ /* Check if such BSS Descriptor exists in a valid list */ -+ LINK_FOR_EACH_ENTRY_SAFE(prBssDesc, prBSSDescNext, prBSSDescList, rLinkEntry, BSS_DESC_T) { -+ fgToRemove = FALSE; -+ -+ if (prBssDesc->eBand == eBand) { -+ switch (eNetTypeIndex) { -+ case NETWORK_TYPE_AIS_INDEX: -+ if ((prBssDesc->eBSSType == BSS_TYPE_INFRASTRUCTURE) -+ || (prBssDesc->eBSSType == BSS_TYPE_IBSS)) { -+ fgToRemove = TRUE; -+ } -+ break; -+ -+ case NETWORK_TYPE_P2P_INDEX: -+ if (prBssDesc->eBSSType == BSS_TYPE_P2P_DEVICE) -+ fgToRemove = TRUE; -+ break; -+ -+ case NETWORK_TYPE_BOW_INDEX: -+ if (prBssDesc->eBSSType == BSS_TYPE_BOW_DEVICE) -+ fgToRemove = TRUE; -+ break; -+ -+ default: -+ ASSERT(0); -+ break; -+ } -+ } -+ -+ if (fgToRemove == TRUE) { -+ /* Remove this BSS Desc from the BSS Desc list */ -+ LINK_REMOVE_KNOWN_ENTRY(prBSSDescList, prBssDesc); -+ -+ /* Return this BSS Desc to the free BSS Desc list. */ -+ LINK_INSERT_TAIL(prFreeBSSDescList, &prBssDesc->rLinkEntry); -+ } -+ } -+ -+} /* end of scanRemoveBssDescByBand() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Clear the CONNECTION FLAG of a specified BSS Descriptor. -+* -+* @param[in] aucBSSID Given BSSID. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID scanRemoveConnFlagOfBssDescByBssid(IN P_ADAPTER_T prAdapter, IN UINT_8 aucBSSID[]) -+{ -+ P_SCAN_INFO_T prScanInfo; -+ P_LINK_T prBSSDescList; -+ P_BSS_DESC_T prBssDesc = (P_BSS_DESC_T) NULL; -+ -+ ASSERT(prAdapter); -+ ASSERT(aucBSSID); -+ -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ prBSSDescList = &prScanInfo->rBSSDescList; -+ -+ /* Search BSS Desc from current SCAN result list. */ -+ LINK_FOR_EACH_ENTRY(prBssDesc, prBSSDescList, rLinkEntry, BSS_DESC_T) { -+ -+ if (EQUAL_MAC_ADDR(prBssDesc->aucBSSID, aucBSSID)) { -+ prBssDesc->fgIsConnected = FALSE; -+ prBssDesc->fgIsConnecting = FALSE; -+ -+ /* BSSID is not unique, so need to traverse whols link-list */ -+ } -+ } -+ -+ return; -+ -+} /* end of scanRemoveConnectionFlagOfBssDescByBssid() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Allocate new BSS_DESC_T -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* -+* @return Pointer to BSS Descriptor, if has free space. NULL, if has no space. -+*/ -+/*----------------------------------------------------------------------------*/ -+P_BSS_DESC_T scanAllocateBssDesc(IN P_ADAPTER_T prAdapter) -+{ -+ P_SCAN_INFO_T prScanInfo; -+ P_LINK_T prFreeBSSDescList; -+ P_BSS_DESC_T prBssDesc; -+ -+ ASSERT(prAdapter); -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ -+ prFreeBSSDescList = &prScanInfo->rFreeBSSDescList; -+ -+ LINK_REMOVE_HEAD(prFreeBSSDescList, prBssDesc, P_BSS_DESC_T); -+ -+ if (prBssDesc) { -+ P_LINK_T prBSSDescList; -+ -+ kalMemZero(prBssDesc, sizeof(BSS_DESC_T)); -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ LINK_INITIALIZE(&(prBssDesc->rP2pDeviceList)); -+ prBssDesc->fgIsP2PPresent = FALSE; -+#endif /* CFG_ENABLE_WIFI_DIRECT */ -+ -+ prBSSDescList = &prScanInfo->rBSSDescList; -+ -+ /* NOTE(Kevin): In current design, this new empty BSS_DESC_T will be -+ * inserted to BSSDescList immediately. -+ */ -+ LINK_INSERT_TAIL(prBSSDescList, &prBssDesc->rLinkEntry); -+ } -+ -+ return prBssDesc; -+ -+} /* end of scanAllocateBssDesc() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This API parses Beacon/ProbeResp frame and insert extracted BSS_DESC_T -+* with IEs into prAdapter->rWifiVar.rScanInfo.aucScanBuffer -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* @param[in] prSwRfb Pointer to the receiving frame buffer. -+* -+* @return Pointer to BSS Descriptor -+* NULL if the Beacon/ProbeResp frame is invalid -+*/ -+/*----------------------------------------------------------------------------*/ -+P_BSS_DESC_T scanAddToBssDesc(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb) -+{ -+ P_BSS_DESC_T prBssDesc = NULL; -+ UINT_16 u2CapInfo; -+ ENUM_BSS_TYPE_T eBSSType = BSS_TYPE_INFRASTRUCTURE; -+ -+ PUINT_8 pucIE; -+ UINT_16 u2IELength; -+ UINT_16 u2Offset = 0; -+ -+ P_WLAN_BEACON_FRAME_T prWlanBeaconFrame = (P_WLAN_BEACON_FRAME_T) NULL; -+ P_IE_SSID_T prIeSsid = (P_IE_SSID_T) NULL; -+ P_IE_SUPPORTED_RATE_T prIeSupportedRate = (P_IE_SUPPORTED_RATE_T) NULL; -+ P_IE_EXT_SUPPORTED_RATE_T prIeExtSupportedRate = (P_IE_EXT_SUPPORTED_RATE_T) NULL; -+ P_HIF_RX_HEADER_T prHifRxHdr; -+ UINT_8 ucHwChannelNum = 0; -+ UINT_8 ucIeDsChannelNum = 0; -+ UINT_8 ucIeHtChannelNum = 0; -+ BOOLEAN fgIsValidSsid = FALSE, fgEscape = FALSE; -+ PARAM_SSID_T rSsid; -+ UINT_64 u8Timestamp; -+ BOOLEAN fgIsNewBssDesc = FALSE; -+ -+ UINT_32 i; -+ UINT_8 ucSSIDChar; -+ -+ UINT_8 ucOuiType; -+ UINT_16 u2SubTypeVersion; -+ -+ ASSERT(prAdapter); -+ ASSERT(prSwRfb); -+ -+ prWlanBeaconFrame = (P_WLAN_BEACON_FRAME_T) prSwRfb->pvHeader; -+ -+ WLAN_GET_FIELD_16(&prWlanBeaconFrame->u2CapInfo, &u2CapInfo); -+ WLAN_GET_FIELD_64(&prWlanBeaconFrame->au4Timestamp[0], &u8Timestamp); -+ -+ /* decide BSS type */ -+ switch (u2CapInfo & CAP_INFO_BSS_TYPE) { -+ case CAP_INFO_ESS: -+ /* It can also be Group Owner of P2P Group. */ -+ eBSSType = BSS_TYPE_INFRASTRUCTURE; -+ break; -+ -+ case CAP_INFO_IBSS: -+ eBSSType = BSS_TYPE_IBSS; -+ break; -+ case 0: -+ /* The P2P Device shall set the ESS bit of the Capabilities field -+ * in the Probe Response fame to 0 and IBSS bit to 0. (3.1.2.1.1) */ -+ eBSSType = BSS_TYPE_P2P_DEVICE; -+ break; -+ -+#if CFG_ENABLE_BT_OVER_WIFI -+ /* @TODO: add rule to identify BOW beacons */ -+#endif -+ -+ default: -+ DBGLOG(SCN, ERROR, "wrong bss type %d\n", (INT_32)(u2CapInfo & CAP_INFO_BSS_TYPE)); -+ return NULL; -+ } -+ -+ /* 4 <1.1> Pre-parse SSID IE */ -+ pucIE = prWlanBeaconFrame->aucInfoElem; -+ u2IELength = (prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen) - -+ (UINT_16) OFFSET_OF(WLAN_BEACON_FRAME_BODY_T, aucInfoElem[0]); -+ -+ if (u2IELength > CFG_IE_BUFFER_SIZE) -+ u2IELength = CFG_IE_BUFFER_SIZE; -+ kalMemZero(&rSsid, sizeof(rSsid)); -+ IE_FOR_EACH(pucIE, u2IELength, u2Offset) { -+ switch (IE_ID(pucIE)) { -+ case ELEM_ID_SSID: -+ if (IE_LEN(pucIE) <= ELEM_MAX_LEN_SSID) { -+ ucSSIDChar = '\0'; -+ -+ /* D-Link DWL-900AP+ */ -+ if (IE_LEN(pucIE) == 0) -+ fgIsValidSsid = FALSE; -+ /* Cisco AP1230A - (IE_LEN(pucIE) == 1) && (SSID_IE(pucIE)->aucSSID[0] == '\0') */ -+ /* Linksys WRK54G/WL520g - (IE_LEN(pucIE) == n) && -+ * (SSID_IE(pucIE)->aucSSID[0~(n-1)] == '\0') */ -+ else { -+ for (i = 0; i < IE_LEN(pucIE); i++) -+ ucSSIDChar |= SSID_IE(pucIE)->aucSSID[i]; -+ -+ if (ucSSIDChar) -+ fgIsValidSsid = TRUE; -+ } -+ -+ /* Update SSID to BSS Descriptor only if SSID is not hidden. */ -+ if (fgIsValidSsid == TRUE) { -+ COPY_SSID(rSsid.aucSsid, -+ rSsid.u4SsidLen, SSID_IE(pucIE)->aucSSID, SSID_IE(pucIE)->ucLength); -+ } -+ } -+ fgEscape = TRUE; -+ break; -+ default: -+ break; -+ } -+ -+ if (fgEscape == TRUE) -+ break; -+ } -+ if (fgIsValidSsid) -+ DBGLOG(SCN, EVENT, "%s %pM channel %d\n", rSsid.aucSsid, prWlanBeaconFrame->aucBSSID, -+ HIF_RX_HDR_GET_CHNL_NUM(prSwRfb->prHifRxHdr)); -+ else -+ DBGLOG(SCN, EVENT, "hidden ssid, %pM channel %d\n", prWlanBeaconFrame->aucBSSID, -+ HIF_RX_HDR_GET_CHNL_NUM(prSwRfb->prHifRxHdr)); -+ /* 4 <1.2> Replace existing BSS_DESC_T or allocate a new one */ -+ prBssDesc = scanSearchExistingBssDescWithSsid(prAdapter, -+ eBSSType, -+ (PUINT_8) prWlanBeaconFrame->aucBSSID, -+ (PUINT_8) prWlanBeaconFrame->aucSrcAddr, -+ fgIsValidSsid, fgIsValidSsid == TRUE ? &rSsid : NULL); -+ -+ if (prBssDesc == (P_BSS_DESC_T) NULL) { -+ fgIsNewBssDesc = TRUE; -+ -+ do { -+ /* 4 <1.2.1> First trial of allocation */ -+ prBssDesc = scanAllocateBssDesc(prAdapter); -+ if (prBssDesc) -+ break; -+ /* 4 <1.2.2> Hidden is useless, remove the oldest hidden ssid. (for passive scan) */ -+ scanRemoveBssDescsByPolicy(prAdapter, -+ (SCN_RM_POLICY_EXCLUDE_CONNECTED | SCN_RM_POLICY_OLDEST_HIDDEN)); -+ -+ /* 4 <1.2.3> Second tail of allocation */ -+ prBssDesc = scanAllocateBssDesc(prAdapter); -+ if (prBssDesc) -+ break; -+ /* 4 <1.2.4> Remove the weakest one */ -+ /* If there are more than half of BSS which has the same ssid as connection -+ * setting, remove the weakest one from them. -+ * Else remove the weakest one. -+ */ -+ scanRemoveBssDescsByPolicy(prAdapter, -+ (SCN_RM_POLICY_EXCLUDE_CONNECTED | SCN_RM_POLICY_SMART_WEAKEST)); -+ -+ /* 4 <1.2.5> reallocation */ -+ prBssDesc = scanAllocateBssDesc(prAdapter); -+ if (prBssDesc) -+ break; -+ /* 4 <1.2.6> no space, should not happen */ -+ DBGLOG(SCN, ERROR, "no bss desc available after remove policy\n"); -+ return NULL; -+ -+ } while (FALSE); -+ -+ } else { -+ OS_SYSTIME rCurrentTime; -+ -+ /* WCXRP00000091 */ -+ /* if the received strength is much weaker than the original one, */ -+ /* ignore it due to it might be received on the folding frequency */ -+ -+ GET_CURRENT_SYSTIME(&rCurrentTime); -+ -+ if (prBssDesc->eBSSType != eBSSType) { -+ prBssDesc->eBSSType = eBSSType; -+ } else if (HIF_RX_HDR_GET_CHNL_NUM(prSwRfb->prHifRxHdr) != prBssDesc->ucChannelNum && -+ prBssDesc->ucRCPI > prSwRfb->prHifRxHdr->ucRcpi) { -+ /* for signal strength is too much weaker and previous beacon is not stale */ -+ if ((prBssDesc->ucRCPI - prSwRfb->prHifRxHdr->ucRcpi) >= REPLICATED_BEACON_STRENGTH_THRESHOLD && -+ (rCurrentTime - prBssDesc->rUpdateTime) <= REPLICATED_BEACON_FRESH_PERIOD) { -+ DBGLOG(SCN, EVENT, "rssi is too much weaker and previous one is fresh\n"); -+ return prBssDesc; -+ } -+ /* for received beacons too close in time domain */ -+ else if (rCurrentTime - prBssDesc->rUpdateTime <= REPLICATED_BEACON_TIME_THRESHOLD) { -+ DBGLOG(SCN, EVENT, "receive beacon/probe reponses too close\n"); -+ return prBssDesc; -+ } -+ } -+ -+ /* if Timestamp has been reset, re-generate BSS DESC 'cause AP should have reset itself */ -+ if (prBssDesc->eBSSType == BSS_TYPE_INFRASTRUCTURE && u8Timestamp < prBssDesc->u8TimeStamp.QuadPart) { -+ BOOLEAN fgIsConnected, fgIsConnecting; -+ -+ /* set flag for indicating this is a new BSS-DESC */ -+ fgIsNewBssDesc = TRUE; -+ -+ /* backup 2 flags for APs which reset timestamp unexpectedly */ -+ fgIsConnected = prBssDesc->fgIsConnected; -+ fgIsConnecting = prBssDesc->fgIsConnecting; -+ scanRemoveBssDescByBssid(prAdapter, prBssDesc->aucBSSID); -+ -+ prBssDesc = scanAllocateBssDesc(prAdapter); -+ if (!prBssDesc) -+ return NULL; -+ -+ /* restore */ -+ prBssDesc->fgIsConnected = fgIsConnected; -+ prBssDesc->fgIsConnecting = fgIsConnecting; -+ } -+ } -+#if 1 -+ -+ prBssDesc->u2RawLength = prSwRfb->u2PacketLen; -+ if (prBssDesc->u2RawLength > CFG_RAW_BUFFER_SIZE) -+ prBssDesc->u2RawLength = CFG_RAW_BUFFER_SIZE; -+ kalMemCopy(prBssDesc->aucRawBuf, prWlanBeaconFrame, prBssDesc->u2RawLength); -+#endif -+ -+ /* NOTE: Keep consistency of Scan Record during JOIN process */ -+ if ((fgIsNewBssDesc == FALSE) && prBssDesc->fgIsConnecting) { -+ DBGLOG(SCN, INFO, "we're connecting this BSS(%pM) now, don't update it\n", -+ prBssDesc->aucBSSID); -+ return prBssDesc; -+ } -+ /* 4 <2> Get information from Fixed Fields */ -+ prBssDesc->eBSSType = eBSSType; /* Update the latest BSS type information. */ -+ -+ COPY_MAC_ADDR(prBssDesc->aucSrcAddr, prWlanBeaconFrame->aucSrcAddr); -+ -+ COPY_MAC_ADDR(prBssDesc->aucBSSID, prWlanBeaconFrame->aucBSSID); -+ -+ prBssDesc->u8TimeStamp.QuadPart = u8Timestamp; -+ -+ WLAN_GET_FIELD_16(&prWlanBeaconFrame->u2BeaconInterval, &prBssDesc->u2BeaconInterval); -+ -+ prBssDesc->u2CapInfo = u2CapInfo; -+ -+ /* 4 <2.1> Retrieve IEs for later parsing */ -+ u2IELength = (prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen) - -+ (UINT_16) OFFSET_OF(WLAN_BEACON_FRAME_BODY_T, aucInfoElem[0]); -+ -+ if (u2IELength > CFG_IE_BUFFER_SIZE) { -+ u2IELength = CFG_IE_BUFFER_SIZE; -+ prBssDesc->fgIsIEOverflow = TRUE; -+ } else { -+ prBssDesc->fgIsIEOverflow = FALSE; -+ } -+ prBssDesc->u2IELength = u2IELength; -+ -+ kalMemCopy(prBssDesc->aucIEBuf, prWlanBeaconFrame->aucInfoElem, u2IELength); -+ -+ /* 4 <2.2> reset prBssDesc variables in case that AP has been reconfigured */ -+ prBssDesc->fgIsERPPresent = FALSE; -+ prBssDesc->fgIsHTPresent = FALSE; -+ prBssDesc->eSco = CHNL_EXT_SCN; -+ prBssDesc->fgIEWAPI = FALSE; -+#if CFG_RSN_MIGRATION -+ prBssDesc->fgIERSN = FALSE; -+#endif -+#if CFG_PRIVACY_MIGRATION -+ prBssDesc->fgIEWPA = FALSE; -+#endif -+ -+ /* 4 <3.1> Full IE parsing on SW_RFB_T */ -+ pucIE = prWlanBeaconFrame->aucInfoElem; -+ -+ IE_FOR_EACH(pucIE, u2IELength, u2Offset) { -+ -+ switch (IE_ID(pucIE)) { -+ case ELEM_ID_SSID: -+ if ((!prIeSsid) && /* NOTE(Kevin): for Atheros IOT #1 */ -+ (IE_LEN(pucIE) <= ELEM_MAX_LEN_SSID)) { -+ BOOLEAN fgIsHiddenSSID = FALSE; -+ -+ ucSSIDChar = '\0'; -+ -+ prIeSsid = (P_IE_SSID_T) pucIE; -+ -+ /* D-Link DWL-900AP+ */ -+ if (IE_LEN(pucIE) == 0) -+ fgIsHiddenSSID = TRUE; -+ /* Cisco AP1230A - (IE_LEN(pucIE) == 1) && (SSID_IE(pucIE)->aucSSID[0] == '\0') */ -+ /* Linksys WRK54G/WL520g - (IE_LEN(pucIE) == n) && -+ * (SSID_IE(pucIE)->aucSSID[0~(n-1)] == '\0') */ -+ else { -+ for (i = 0; i < IE_LEN(pucIE); i++) -+ ucSSIDChar |= SSID_IE(pucIE)->aucSSID[i]; -+ -+ if (!ucSSIDChar) -+ fgIsHiddenSSID = TRUE; -+ } -+ -+ /* Update SSID to BSS Descriptor only if SSID is not hidden. */ -+ if (!fgIsHiddenSSID) { -+ COPY_SSID(prBssDesc->aucSSID, -+ prBssDesc->ucSSIDLen, -+ SSID_IE(pucIE)->aucSSID, SSID_IE(pucIE)->ucLength); -+ } -+#if 0 -+ /* -+ After we connect to a hidden SSID, prBssDesc->aucSSID[] will -+ not be empty and prBssDesc->ucSSIDLen will not be 0, -+ so maybe we need to empty prBssDesc->aucSSID[] and set -+ prBssDesc->ucSSIDLen to 0 in prBssDesc to avoid that -+ UI still displays hidden SSID AP in scan list after -+ we disconnect the hidden SSID AP. -+ */ -+ else { -+ prBssDesc->aucSSID[0] = '\0'; -+ prBssDesc->ucSSIDLen = 0; -+ } -+#endif -+ -+ } -+ break; -+ -+ case ELEM_ID_SUP_RATES: -+ /* NOTE(Kevin): Buffalo WHR-G54S's supported rate set IE exceed 8. -+ * IE_LEN(pucIE) == 12, "1(B), 2(B), 5.5(B), 6(B), 9(B), 11(B), -+ * 12(B), 18(B), 24(B), 36(B), 48(B), 54(B)" -+ */ -+ /* TP-LINK will set extra and incorrect ie with ELEM_ID_SUP_RATES */ -+ if ((!prIeSupportedRate) && (IE_LEN(pucIE) <= RATE_NUM)) -+ prIeSupportedRate = SUP_RATES_IE(pucIE); -+ break; -+ -+ case ELEM_ID_DS_PARAM_SET: -+ if (IE_LEN(pucIE) == ELEM_MAX_LEN_DS_PARAMETER_SET) -+ ucIeDsChannelNum = DS_PARAM_IE(pucIE)->ucCurrChnl; -+ break; -+ -+ case ELEM_ID_TIM: -+ if (IE_LEN(pucIE) <= ELEM_MAX_LEN_TIM) -+ prBssDesc->ucDTIMPeriod = TIM_IE(pucIE)->ucDTIMPeriod; -+ break; -+ -+ case ELEM_ID_IBSS_PARAM_SET: -+ if (IE_LEN(pucIE) == ELEM_MAX_LEN_IBSS_PARAMETER_SET) -+ prBssDesc->u2ATIMWindow = IBSS_PARAM_IE(pucIE)->u2ATIMWindow; -+ break; -+ -+#if 0 /* CFG_SUPPORT_802_11D */ -+ case ELEM_ID_COUNTRY_INFO: -+ prBssDesc->prIECountry = (P_IE_COUNTRY_T) pucIE; -+ break; -+#endif -+ -+ case ELEM_ID_ERP_INFO: -+ if (IE_LEN(pucIE) == ELEM_MAX_LEN_ERP) -+ prBssDesc->fgIsERPPresent = TRUE; -+ break; -+ -+ case ELEM_ID_EXTENDED_SUP_RATES: -+ if (!prIeExtSupportedRate) -+ prIeExtSupportedRate = EXT_SUP_RATES_IE(pucIE); -+ break; -+ -+#if CFG_RSN_MIGRATION -+ case ELEM_ID_RSN: -+ if (rsnParseRsnIE(prAdapter, RSN_IE(pucIE), &prBssDesc->rRSNInfo)) { -+ prBssDesc->fgIERSN = TRUE; -+ prBssDesc->u2RsnCap = prBssDesc->rRSNInfo.u2RsnCap; -+ if (prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA2) -+ rsnCheckPmkidCache(prAdapter, prBssDesc); -+ } -+ break; -+#endif -+ -+ case ELEM_ID_HT_CAP: -+ prBssDesc->fgIsHTPresent = TRUE; -+ break; -+ -+ case ELEM_ID_HT_OP: -+ if (IE_LEN(pucIE) != (sizeof(IE_HT_OP_T) - 2)) -+ break; -+ -+ if ((((P_IE_HT_OP_T) pucIE)->ucInfo1 & HT_OP_INFO1_SCO) != CHNL_EXT_RES) { -+ prBssDesc->eSco = (ENUM_CHNL_EXT_T) -+ (((P_IE_HT_OP_T) pucIE)->ucInfo1 & HT_OP_INFO1_SCO); -+ } -+ ucIeHtChannelNum = ((P_IE_HT_OP_T) pucIE)->ucPrimaryChannel; -+ -+ break; -+ -+#if CFG_SUPPORT_WAPI -+ case ELEM_ID_WAPI: -+ if (wapiParseWapiIE(WAPI_IE(pucIE), &prBssDesc->rIEWAPI)) -+ prBssDesc->fgIEWAPI = TRUE; -+ break; -+#endif -+ -+ case ELEM_ID_VENDOR: /* ELEM_ID_P2P, ELEM_ID_WMM */ -+#if CFG_PRIVACY_MIGRATION -+ if (rsnParseCheckForWFAInfoElem(prAdapter, pucIE, &ucOuiType, &u2SubTypeVersion)) { -+ if ((ucOuiType == VENDOR_OUI_TYPE_WPA) && (u2SubTypeVersion == VERSION_WPA)) { -+ -+ if (rsnParseWpaIE(prAdapter, WPA_IE(pucIE), &prBssDesc->rWPAInfo)) -+ prBssDesc->fgIEWPA = TRUE; -+ } -+ } -+#endif -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ if (prAdapter->fgIsP2PRegistered) { -+ if (p2pFuncParseCheckForP2PInfoElem(prAdapter, pucIE, &ucOuiType)) { -+ if (ucOuiType == VENDOR_OUI_TYPE_P2P) -+ prBssDesc->fgIsP2PPresent = TRUE; -+ } -+ } -+#endif /* CFG_ENABLE_WIFI_DIRECT */ -+ break; -+ -+ /* no default */ -+ } -+ } -+ -+ /* 4 <3.2> Save information from IEs - SSID */ -+ /* Update Flag of Hidden SSID for used in SEARCH STATE. */ -+ -+ /* NOTE(Kevin): in current driver, the ucSSIDLen == 0 represent -+ * all cases of hidden SSID. -+ * If the fgIsHiddenSSID == TRUE, it means we didn't get the ProbeResp with -+ * valid SSID. -+ */ -+ if (prBssDesc->ucSSIDLen == 0) -+ prBssDesc->fgIsHiddenSSID = TRUE; -+ else -+ prBssDesc->fgIsHiddenSSID = FALSE; -+ -+ /* 4 <3.3> Check rate information in related IEs. */ -+ if (prIeSupportedRate || prIeExtSupportedRate) { -+ rateGetRateSetFromIEs(prIeSupportedRate, -+ prIeExtSupportedRate, -+ &prBssDesc->u2OperationalRateSet, -+ &prBssDesc->u2BSSBasicRateSet, &prBssDesc->fgIsUnknownBssBasicRate); -+ } -+ /* 4 <4> Update information from HIF RX Header */ -+ { -+ prHifRxHdr = prSwRfb->prHifRxHdr; -+ -+ ASSERT(prHifRxHdr); -+ -+ /* 4 <4.1> Get TSF comparison result */ -+ prBssDesc->fgIsLargerTSF = HIF_RX_HDR_GET_TCL_FLAG(prHifRxHdr); -+ -+ /* 4 <4.2> Get Band information */ -+ prBssDesc->eBand = HIF_RX_HDR_GET_RF_BAND(prHifRxHdr); -+ -+ /* 4 <4.2> Get channel and RCPI information */ -+ ucHwChannelNum = HIF_RX_HDR_GET_CHNL_NUM(prHifRxHdr); -+ -+ if (BAND_2G4 == prBssDesc->eBand) { -+ -+ /* Update RCPI if in right channel */ -+ if (ucIeDsChannelNum >= 1 && ucIeDsChannelNum <= 14) { -+ -+ /* Receive Beacon/ProbeResp frame from adjacent channel. */ -+ if ((ucIeDsChannelNum == ucHwChannelNum) || (prHifRxHdr->ucRcpi > prBssDesc->ucRCPI)) -+ prBssDesc->ucRCPI = prHifRxHdr->ucRcpi; -+ /* trust channel information brought by IE */ -+ prBssDesc->ucChannelNum = ucIeDsChannelNum; -+ } else if (ucIeHtChannelNum >= 1 && ucIeHtChannelNum <= 14) { -+ /* Receive Beacon/ProbeResp frame from adjacent channel. */ -+ if ((ucIeHtChannelNum == ucHwChannelNum) || (prHifRxHdr->ucRcpi > prBssDesc->ucRCPI)) -+ prBssDesc->ucRCPI = prHifRxHdr->ucRcpi; -+ /* trust channel information brought by IE */ -+ prBssDesc->ucChannelNum = ucIeHtChannelNum; -+ } else { -+ prBssDesc->ucRCPI = prHifRxHdr->ucRcpi; -+ -+ prBssDesc->ucChannelNum = ucHwChannelNum; -+ } -+ } -+ /* 5G Band */ -+ else { -+ if (ucIeHtChannelNum >= 1 && ucIeHtChannelNum < 200) { -+ /* Receive Beacon/ProbeResp frame from adjacent channel. */ -+ if ((ucIeHtChannelNum == ucHwChannelNum) || (prHifRxHdr->ucRcpi > prBssDesc->ucRCPI)) -+ prBssDesc->ucRCPI = prHifRxHdr->ucRcpi; -+ /* trust channel information brought by IE */ -+ prBssDesc->ucChannelNum = ucIeHtChannelNum; -+ } else { -+ /* Always update RCPI */ -+ prBssDesc->ucRCPI = prHifRxHdr->ucRcpi; -+ -+ prBssDesc->ucChannelNum = ucHwChannelNum; -+ } -+ } -+ } -+ -+ /* 4 <5> PHY type setting */ -+ prBssDesc->ucPhyTypeSet = 0; -+ -+ if (BAND_2G4 == prBssDesc->eBand) { -+ /* check if support 11n */ -+ if (prBssDesc->fgIsHTPresent) -+ prBssDesc->ucPhyTypeSet |= PHY_TYPE_BIT_HT; -+ -+ /* if not 11n only */ -+ if (!(prBssDesc->u2BSSBasicRateSet & RATE_SET_BIT_HT_PHY)) { -+ /* check if support 11g */ -+ if ((prBssDesc->u2OperationalRateSet & RATE_SET_OFDM) || prBssDesc->fgIsERPPresent) -+ prBssDesc->ucPhyTypeSet |= PHY_TYPE_BIT_ERP; -+ -+ /* if not 11g only */ -+ if (!(prBssDesc->u2BSSBasicRateSet & RATE_SET_OFDM)) { -+ /* check if support 11b */ -+ if ((prBssDesc->u2OperationalRateSet & RATE_SET_HR_DSSS)) -+ prBssDesc->ucPhyTypeSet |= PHY_TYPE_BIT_HR_DSSS; -+ } -+ } -+ } else { /* (BAND_5G == prBssDesc->eBande) */ -+ /* check if support 11n */ -+ if (prBssDesc->fgIsHTPresent) -+ prBssDesc->ucPhyTypeSet |= PHY_TYPE_BIT_HT; -+ -+ /* if not 11n only */ -+ if (!(prBssDesc->u2BSSBasicRateSet & RATE_SET_BIT_HT_PHY)) { -+ /* Support 11a definitely */ -+ prBssDesc->ucPhyTypeSet |= PHY_TYPE_BIT_OFDM; -+ -+ ASSERT(!(prBssDesc->u2OperationalRateSet & RATE_SET_HR_DSSS)); -+ } -+ } -+ -+ /* 4 <6> Update BSS_DESC_T's Last Update TimeStamp. */ -+ GET_CURRENT_SYSTIME(&prBssDesc->rUpdateTime); -+ -+ return prBssDesc; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Convert the Beacon or ProbeResp Frame in SW_RFB_T to scan result for query -+* -+* @param[in] prSwRfb Pointer to the receiving SW_RFB_T structure. -+* -+* @retval WLAN_STATUS_SUCCESS It is a valid Scan Result and been sent to the host. -+* @retval WLAN_STATUS_FAILURE It is not a valid Scan Result. -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS scanAddScanResult(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBssDesc, IN P_SW_RFB_T prSwRfb) -+{ -+ P_SCAN_INFO_T prScanInfo; -+ UINT_8 aucRatesEx[PARAM_MAX_LEN_RATES_EX]; -+ P_WLAN_BEACON_FRAME_T prWlanBeaconFrame; -+ PARAM_MAC_ADDRESS rMacAddr; -+ PARAM_SSID_T rSsid; -+ ENUM_PARAM_NETWORK_TYPE_T eNetworkType; -+ PARAM_802_11_CONFIG_T rConfiguration; -+ ENUM_PARAM_OP_MODE_T eOpMode; -+ UINT_8 ucRateLen = 0; -+ UINT_32 i; -+ -+ ASSERT(prAdapter); -+ ASSERT(prSwRfb); -+ -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ -+ if (prBssDesc->eBand == BAND_2G4) { -+ if ((prBssDesc->u2OperationalRateSet & RATE_SET_OFDM) -+ || prBssDesc->fgIsERPPresent) { -+ eNetworkType = PARAM_NETWORK_TYPE_OFDM24; -+ } else { -+ eNetworkType = PARAM_NETWORK_TYPE_DS; -+ } -+ } else { -+ ASSERT(prBssDesc->eBand == BAND_5G); -+ eNetworkType = PARAM_NETWORK_TYPE_OFDM5; -+ } -+ -+ if (prBssDesc->eBSSType == BSS_TYPE_P2P_DEVICE) { -+ /* NOTE(Kevin): Not supported by WZC(TBD) */ -+ return WLAN_STATUS_FAILURE; -+ } -+ -+ prWlanBeaconFrame = (P_WLAN_BEACON_FRAME_T) prSwRfb->pvHeader; -+ COPY_MAC_ADDR(rMacAddr, prWlanBeaconFrame->aucBSSID); -+ COPY_SSID(rSsid.aucSsid, rSsid.u4SsidLen, prBssDesc->aucSSID, prBssDesc->ucSSIDLen); -+ -+ rConfiguration.u4Length = sizeof(PARAM_802_11_CONFIG_T); -+ rConfiguration.u4BeaconPeriod = (UINT_32) prWlanBeaconFrame->u2BeaconInterval; -+ rConfiguration.u4ATIMWindow = prBssDesc->u2ATIMWindow; -+ rConfiguration.u4DSConfig = nicChannelNum2Freq(prBssDesc->ucChannelNum); -+ rConfiguration.rFHConfig.u4Length = sizeof(PARAM_802_11_CONFIG_FH_T); -+ -+ rateGetDataRatesFromRateSet(prBssDesc->u2OperationalRateSet, 0, aucRatesEx, &ucRateLen); -+ -+ /* NOTE(Kevin): Set unused entries, if any, at the end of the array to 0. -+ * from OID_802_11_BSSID_LIST -+ */ -+ for (i = ucRateLen; i < sizeof(aucRatesEx) / sizeof(aucRatesEx[0]); i++) -+ aucRatesEx[i] = 0; -+ -+ switch (prBssDesc->eBSSType) { -+ case BSS_TYPE_IBSS: -+ eOpMode = NET_TYPE_IBSS; -+ break; -+ -+ case BSS_TYPE_INFRASTRUCTURE: -+ case BSS_TYPE_P2P_DEVICE: -+ case BSS_TYPE_BOW_DEVICE: -+ default: -+ eOpMode = NET_TYPE_INFRA; -+ break; -+ } -+ -+ DBGLOG(SCN, TRACE, "ind %s %d\n", prBssDesc->aucSSID, prBssDesc->ucChannelNum); -+ -+#if (CFG_SUPPORT_TDLS == 1) -+ { -+ if (flgTdlsTestExtCapElm == TRUE) { -+ /* only for RALINK AP */ -+ UINT8 *pucElm = (UINT8 *) (prSwRfb->pvHeader + prSwRfb->u2PacketLen); -+ -+ kalMemCopy(pucElm - 9, aucTdlsTestExtCapElm, 7); -+ prSwRfb->u2PacketLen -= 2; -+/* prSwRfb->u2PacketLen += 7; */ -+ -+ DBGLOG(TDLS, INFO, -+ " %s: append ext cap element to %pM\n", -+ __func__, prBssDesc->aucBSSID); -+ } -+ } -+#endif /* CFG_SUPPORT_TDLS */ -+ -+ if (prAdapter->rWifiVar.rScanInfo.fgNloScanning && -+ test_bit(SUSPEND_FLAG_CLEAR_WHEN_RESUME, &prAdapter->ulSuspendFlag)) { -+ UINT_8 i = 0; -+ P_BSS_DESC_T *pprPendBssDesc = &prScanInfo->rNloParam.aprPendingBssDescToInd[0]; -+ -+ for (; i < SCN_SSID_MATCH_MAX_NUM; i++) { -+ if (pprPendBssDesc[i]) -+ continue; -+ DBGLOG(SCN, INFO, -+ "indicate bss[%pM] before wiphy resume, need to indicate again after wiphy resume\n", -+ prBssDesc->aucBSSID); -+ pprPendBssDesc[i] = prBssDesc; -+ break; -+ } -+ } -+ -+ kalIndicateBssInfo(prAdapter->prGlueInfo, -+ (PUINT_8) prSwRfb->pvHeader, -+ prSwRfb->u2PacketLen, prBssDesc->ucChannelNum, RCPI_TO_dBm(prBssDesc->ucRCPI)); -+ -+ nicAddScanResult(prAdapter, -+ rMacAddr, -+ &rSsid, -+ prWlanBeaconFrame->u2CapInfo & CAP_INFO_PRIVACY ? 1 : 0, -+ RCPI_TO_dBm(prBssDesc->ucRCPI), -+ eNetworkType, -+ &rConfiguration, -+ eOpMode, -+ aucRatesEx, -+ prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen, -+ (PUINT_8) ((ULONG) (prSwRfb->pvHeader) + WLAN_MAC_MGMT_HEADER_LEN)); -+ -+ return WLAN_STATUS_SUCCESS; -+ -+} /* end of scanAddScanResult() */ -+ -+#if 1 -+ -+BOOLEAN scanCheckBssIsLegal(IN P_ADAPTER_T prAdapter, P_BSS_DESC_T prBssDesc) -+{ -+ BOOLEAN fgAddToScanResult = FALSE; -+ ENUM_BAND_T eBand = 0; -+ UINT_8 ucChannel = 0; -+ -+ ASSERT(prAdapter); -+ /* check the channel is in the legal doamin */ -+ if (rlmDomainIsLegalChannel(prAdapter, prBssDesc->eBand, prBssDesc->ucChannelNum) == TRUE) { -+ /* check ucChannelNum/eBand for adjacement channel filtering */ -+ if (cnmAisInfraChannelFixed(prAdapter, &eBand, &ucChannel) == TRUE && -+ (eBand != prBssDesc->eBand || ucChannel != prBssDesc->ucChannelNum)) { -+ fgAddToScanResult = FALSE; -+ } else { -+ fgAddToScanResult = TRUE; -+ } -+ } -+ return fgAddToScanResult; -+ -+} -+ -+VOID scanReportBss2Cfg80211(IN P_ADAPTER_T prAdapter, IN ENUM_BSS_TYPE_T eBSSType, IN P_BSS_DESC_T SpecificprBssDesc) -+{ -+ P_SCAN_INFO_T prScanInfo = (P_SCAN_INFO_T) NULL; -+ P_LINK_T prBSSDescList = (P_LINK_T) NULL; -+ P_BSS_DESC_T prBssDesc = (P_BSS_DESC_T) NULL; -+ RF_CHANNEL_INFO_T rChannelInfo; -+ -+ ASSERT(prAdapter); -+ -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ -+ prBSSDescList = &prScanInfo->rBSSDescList; -+ -+ DBGLOG(SCN, TRACE, "scanReportBss2Cfg80211\n"); -+ -+ if (SpecificprBssDesc) { -+ { -+ /* check BSSID is legal channel */ -+ if (!scanCheckBssIsLegal(prAdapter, SpecificprBssDesc)) { -+ DBGLOG(SCN, TRACE, "Remove specific SSID[%s %d]\n", -+ SpecificprBssDesc->aucSSID, SpecificprBssDesc->ucChannelNum); -+ return; -+ } -+ -+ DBGLOG(SCN, TRACE, "Report Specific SSID[%s]\n", SpecificprBssDesc->aucSSID); -+ if (eBSSType == BSS_TYPE_INFRASTRUCTURE) { -+ -+ kalIndicateBssInfo(prAdapter->prGlueInfo, -+ (PUINT_8) SpecificprBssDesc->aucRawBuf, -+ SpecificprBssDesc->u2RawLength, -+ SpecificprBssDesc->ucChannelNum, -+ RCPI_TO_dBm(SpecificprBssDesc->ucRCPI)); -+ } else { -+ -+ rChannelInfo.ucChannelNum = SpecificprBssDesc->ucChannelNum; -+ rChannelInfo.eBand = SpecificprBssDesc->eBand; -+ kalP2PIndicateBssInfo(prAdapter->prGlueInfo, -+ (PUINT_8) SpecificprBssDesc->aucRawBuf, -+ SpecificprBssDesc->u2RawLength, -+ &rChannelInfo, RCPI_TO_dBm(SpecificprBssDesc->ucRCPI)); -+ -+ } -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ SpecificprBssDesc->fgIsP2PReport = FALSE; -+#endif -+ } -+ } else { -+ /* Search BSS Desc from current SCAN result list. */ -+ LINK_FOR_EACH_ENTRY(prBssDesc, prBSSDescList, rLinkEntry, BSS_DESC_T) { -+ -+#if CFG_AUTO_CHANNEL_SEL_SUPPORT -+ /* 4 Auto Channel Selection:Record the AP Number */ -+ P_PARAM_CHN_LOAD_INFO prChnLoad; -+ UINT_8 ucIdx = 0; -+ -+ if (((prBssDesc->ucChannelNum > 0) && (prBssDesc->ucChannelNum <= 48)) -+ || (prBssDesc->ucChannelNum >= 147) /*non-DFS Channel */) { -+ if (prBssDesc->ucChannelNum <= HW_CHNL_NUM_MAX_2G4) { -+ ucIdx = prBssDesc->ucChannelNum - 1; -+ } else if (prBssDesc->ucChannelNum <= 48) { -+ ucIdx = (UINT_8) (HW_CHNL_NUM_MAX_2G4 + (prBssDesc->ucChannelNum - 34) / 4); -+ } else { -+ ucIdx = -+ (UINT_8) (HW_CHNL_NUM_MAX_2G4 + 4 + (prBssDesc->ucChannelNum - 149) / 4); -+ } -+ -+ if (ucIdx < MAX_AUTO_CHAL_NUM) { -+ prChnLoad = (P_PARAM_CHN_LOAD_INFO) & -+ (prAdapter->rWifiVar.rChnLoadInfo.rEachChnLoad[ucIdx]); -+ prChnLoad->ucChannel = prBssDesc->ucChannelNum; -+ prChnLoad->u2APNum++; -+ } else { -+ DBGLOG(SCN, WARN, "ACS: ChIdx > MAX_AUTO_CHAL_NUM\n"); -+ } -+ -+ } -+#endif -+ /* check BSSID is legal channel */ -+ if (!scanCheckBssIsLegal(prAdapter, prBssDesc)) { -+ DBGLOG(SCN, TRACE, "Remove SSID[%s %d]\n", -+ prBssDesc->aucSSID, prBssDesc->ucChannelNum); -+ -+ continue; -+ } -+ -+ if ((prBssDesc->eBSSType == eBSSType) -+#if CFG_ENABLE_WIFI_DIRECT -+ || ((eBSSType == BSS_TYPE_P2P_DEVICE) && (prBssDesc->fgIsP2PReport == TRUE)) -+#endif -+ ) { -+ -+ DBGLOG(SCN, TRACE, "Report ALL SSID[%s %d]\n", -+ prBssDesc->aucSSID, prBssDesc->ucChannelNum); -+ -+ if (eBSSType == BSS_TYPE_INFRASTRUCTURE) { -+ if (prBssDesc->u2RawLength != 0) { -+ kalIndicateBssInfo(prAdapter->prGlueInfo, -+ (PUINT_8) prBssDesc->aucRawBuf, -+ prBssDesc->u2RawLength, -+ prBssDesc->ucChannelNum, -+ RCPI_TO_dBm(prBssDesc->ucRCPI)); -+ kalMemZero(prBssDesc->aucRawBuf, CFG_RAW_BUFFER_SIZE); -+ prBssDesc->u2RawLength = 0; -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ prBssDesc->fgIsP2PReport = FALSE; -+#endif -+ } -+ } else { -+#if CFG_ENABLE_WIFI_DIRECT -+ if (prBssDesc->fgIsP2PReport == TRUE) { -+#endif -+ rChannelInfo.ucChannelNum = prBssDesc->ucChannelNum; -+ rChannelInfo.eBand = prBssDesc->eBand; -+ -+ kalP2PIndicateBssInfo(prAdapter->prGlueInfo, -+ (PUINT_8) prBssDesc->aucRawBuf, -+ prBssDesc->u2RawLength, -+ &rChannelInfo, RCPI_TO_dBm(prBssDesc->ucRCPI)); -+ -+ /* do not clear it then we can pass the bss in Specific report */ -+ /* kalMemZero(prBssDesc->aucRawBuf,CFG_RAW_BUFFER_SIZE); */ -+ -+ /* -+ the BSS entry will not be cleared after scan done. -+ So if we dont receive the BSS in next scan, we cannot -+ pass it. We use u2RawLength for the purpose. -+ */ -+ /* prBssDesc->u2RawLength=0; */ -+#if CFG_ENABLE_WIFI_DIRECT -+ prBssDesc->fgIsP2PReport = FALSE; -+ } -+#endif -+ } -+ } -+ -+ } -+#if CFG_AUTO_CHANNEL_SEL_SUPPORT -+ prAdapter->rWifiVar.rChnLoadInfo.fgDataReadyBit = TRUE; -+#endif -+ -+ } -+ -+} -+ -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Parse the content of given Beacon or ProbeResp Frame. -+* -+* @param[in] prSwRfb Pointer to the receiving SW_RFB_T structure. -+* -+* @retval WLAN_STATUS_SUCCESS if not report this SW_RFB_T to host -+* @retval WLAN_STATUS_PENDING if report this SW_RFB_T to host as scan result -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS scanProcessBeaconAndProbeResp(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb) -+{ -+ P_CONNECTION_SETTINGS_T prConnSettings; -+ P_BSS_DESC_T prBssDesc = (P_BSS_DESC_T) NULL; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ P_BSS_INFO_T prAisBssInfo; -+ P_WLAN_BEACON_FRAME_T prWlanBeaconFrame = (P_WLAN_BEACON_FRAME_T) NULL; -+#if CFG_SLT_SUPPORT -+ P_SLT_INFO_T prSltInfo = (P_SLT_INFO_T) NULL; -+#endif -+ -+ ASSERT(prAdapter); -+ ASSERT(prSwRfb); -+ -+ /* 4 <0> Ignore invalid Beacon Frame */ -+ if ((prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen) < -+ (TIMESTAMP_FIELD_LEN + BEACON_INTERVAL_FIELD_LEN + CAP_INFO_FIELD_LEN)) { -+ /* to debug beacon length too small issue */ -+ UINT_32 u4MailBox0; -+ -+ nicGetMailbox(prAdapter, 0, &u4MailBox0); -+ DBGLOG(SCN, WARN, "if conn sys also get less length (0x5a means yes) %x\n", (UINT_32) u4MailBox0); -+ DBGLOG(SCN, WARN, "u2PacketLen %d, u2HeaderLen %d, payloadLen %d\n", -+ prSwRfb->u2PacketLen, prSwRfb->u2HeaderLen, -+ prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen); -+ /* dumpMemory8(prSwRfb->pvHeader, prSwRfb->u2PacketLen); */ -+ -+#ifndef _lint -+ ASSERT(0); -+#endif /* _lint */ -+ return rStatus; -+ } -+#if CFG_SLT_SUPPORT -+ prSltInfo = &prAdapter->rWifiVar.rSltInfo; -+ -+ if (prSltInfo->fgIsDUT) { -+ DBGLOG(SCN, INFO, "\n\rBCN: RX\n"); -+ prSltInfo->u4BeaconReceiveCnt++; -+ return WLAN_STATUS_SUCCESS; -+ } else { -+ return WLAN_STATUS_SUCCESS; -+ } -+#endif -+ -+ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); -+ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ prWlanBeaconFrame = (P_WLAN_BEACON_FRAME_T) prSwRfb->pvHeader; -+ -+ /*ALPS01475157: don't show SSID on scan list for multicast MAC AP */ -+ if (IS_BMCAST_MAC_ADDR(prWlanBeaconFrame->aucSrcAddr)) { -+ DBGLOG(SCN, WARN, "received beacon/probe response from multicast AP\n"); -+ return rStatus; -+ } -+ -+ /* 4 <1> Parse and add into BSS_DESC_T */ -+ prBssDesc = scanAddToBssDesc(prAdapter, prSwRfb); -+ -+ if (prBssDesc) { -+ /* 4 <1.1> Beacon Change Detection for Connected BSS */ -+ if (prAisBssInfo->eConnectionState == PARAM_MEDIA_STATE_CONNECTED && -+ ((prBssDesc->eBSSType == BSS_TYPE_INFRASTRUCTURE && prConnSettings->eOPMode != NET_TYPE_IBSS) -+ || (prBssDesc->eBSSType == BSS_TYPE_IBSS && prConnSettings->eOPMode != NET_TYPE_INFRA)) && -+ EQUAL_MAC_ADDR(prBssDesc->aucBSSID, prAisBssInfo->aucBSSID) && -+ EQUAL_SSID(prBssDesc->aucSSID, prBssDesc->ucSSIDLen, prAisBssInfo->aucSSID, -+ prAisBssInfo->ucSSIDLen)) { -+ BOOLEAN fgNeedDisconnect = FALSE; -+ -+#if CFG_SUPPORT_BEACON_CHANGE_DETECTION -+ /* <1.1.2> check if supported rate differs */ -+ if (prAisBssInfo->u2OperationalRateSet != prBssDesc->u2OperationalRateSet) -+ fgNeedDisconnect = TRUE; -+#endif -+#if CFG_SUPPORT_DETECT_SECURITY_MODE_CHANGE -+ if ( -+#if CFG_SUPPORT_WAPI -+ (prAdapter->rWifiVar.rConnSettings.fgWapiMode == TRUE && -+ !wapiPerformPolicySelection(prAdapter, prBssDesc)) || -+#endif -+ rsnCheckSecurityModeChanged(prAdapter, prAisBssInfo, prBssDesc)) { -+ DBGLOG(SCN, INFO, "Beacon security mode change detected\n"); -+ fgNeedDisconnect = FALSE; -+ aisBssSecurityChanged(prAdapter); -+ } -+#endif -+ -+ /* <1.1.3> beacon content change detected, disconnect immediately */ -+ if (fgNeedDisconnect == TRUE) -+ aisBssBeaconTimeout(prAdapter); -+ } -+ /* 4 <1.1> Update AIS_BSS_INFO */ -+ if (((prBssDesc->eBSSType == BSS_TYPE_INFRASTRUCTURE && prConnSettings->eOPMode != NET_TYPE_IBSS) -+ || (prBssDesc->eBSSType == BSS_TYPE_IBSS && prConnSettings->eOPMode != NET_TYPE_INFRA))) { -+ if (prAisBssInfo->eConnectionState == PARAM_MEDIA_STATE_CONNECTED) { -+ /* *not* checking prBssDesc->fgIsConnected anymore, -+ * due to Linksys AP uses " " as hidden SSID, and would have different BSS descriptor */ -+ if ((!prAisBssInfo->ucDTIMPeriod) && -+ EQUAL_MAC_ADDR(prBssDesc->aucBSSID, prAisBssInfo->aucBSSID) && -+ (prAisBssInfo->eCurrentOPMode == OP_MODE_INFRASTRUCTURE) && -+ ((prWlanBeaconFrame->u2FrameCtrl & MASK_FRAME_TYPE) == MAC_FRAME_BEACON)) { -+ -+ prAisBssInfo->ucDTIMPeriod = prBssDesc->ucDTIMPeriod; -+ -+ /* sync with firmware for beacon information */ -+ nicPmIndicateBssConnected(prAdapter, NETWORK_TYPE_AIS_INDEX); -+ } -+ } -+#if CFG_SUPPORT_ADHOC -+ if (EQUAL_SSID(prBssDesc->aucSSID, -+ prBssDesc->ucSSIDLen, -+ prConnSettings->aucSSID, -+ prConnSettings->ucSSIDLen) && -+ (prBssDesc->eBSSType == BSS_TYPE_IBSS) && (prAisBssInfo->eCurrentOPMode == OP_MODE_IBSS)) { -+ ibssProcessMatchedBeacon(prAdapter, prAisBssInfo, prBssDesc, -+ prSwRfb->prHifRxHdr->ucRcpi); -+ } -+#endif /* CFG_SUPPORT_ADHOC */ -+ } -+ -+ rlmProcessBcn(prAdapter, -+ prSwRfb, -+ ((P_WLAN_BEACON_FRAME_T) (prSwRfb->pvHeader))->aucInfoElem, -+ (prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen) - -+ (UINT_16) (OFFSET_OF(WLAN_BEACON_FRAME_BODY_T, aucInfoElem[0]))); -+ -+ /* 4 <3> Send SW_RFB_T to HIF when we perform SCAN for HOST */ -+ if (prBssDesc->eBSSType == BSS_TYPE_INFRASTRUCTURE || prBssDesc->eBSSType == BSS_TYPE_IBSS) { -+ /* for AIS, send to host */ -+ if (prConnSettings->fgIsScanReqIssued || prAdapter->rWifiVar.rScanInfo.fgNloScanning) { -+ BOOLEAN fgAddToScanResult; -+ -+ fgAddToScanResult = scanCheckBssIsLegal(prAdapter, prBssDesc); -+ -+ if (fgAddToScanResult == TRUE) -+ rStatus = scanAddScanResult(prAdapter, prBssDesc, prSwRfb); -+ } -+ } -+#if CFG_ENABLE_WIFI_DIRECT -+ if (prAdapter->fgIsP2PRegistered) -+ scanP2pProcessBeaconAndProbeResp(prAdapter, prSwRfb, &rStatus, prBssDesc, prWlanBeaconFrame); -+#endif -+ } -+ -+ return rStatus; -+ -+} /* end of scanProcessBeaconAndProbeResp() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Search the Candidate of BSS Descriptor for JOIN(Infrastructure) or -+* MERGE(AdHoc) according to current Connection Policy. -+* -+* \return Pointer to BSS Descriptor, if found. NULL, if not found -+*/ -+/*----------------------------------------------------------------------------*/ -+P_BSS_DESC_T scanSearchBssDescByPolicy(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex) -+{ -+ P_CONNECTION_SETTINGS_T prConnSettings; -+ P_BSS_INFO_T prBssInfo; -+ P_AIS_SPECIFIC_BSS_INFO_T prAisSpecBssInfo; -+ P_SCAN_INFO_T prScanInfo; -+ -+ P_LINK_T prBSSDescList; -+ -+ P_BSS_DESC_T prBssDesc = (P_BSS_DESC_T) NULL; -+ P_BSS_DESC_T prPrimaryBssDesc = (P_BSS_DESC_T) NULL; -+ P_BSS_DESC_T prCandidateBssDesc = (P_BSS_DESC_T) NULL; -+ -+ P_STA_RECORD_T prStaRec = (P_STA_RECORD_T) NULL; -+ P_STA_RECORD_T prPrimaryStaRec; -+ P_STA_RECORD_T prCandidateStaRec = (P_STA_RECORD_T) NULL; -+ -+ OS_SYSTIME rCurrentTime; -+ -+ /* The first one reach the check point will be our candidate */ -+ BOOLEAN fgIsFindFirst = (BOOLEAN) FALSE; -+ -+ BOOLEAN fgIsFindBestRSSI = (BOOLEAN) FALSE; -+ BOOLEAN fgIsFindBestEncryptionLevel = (BOOLEAN) FALSE; -+ /* BOOLEAN fgIsFindMinChannelLoad = (BOOLEAN)FALSE; */ -+ -+ /* TODO(Kevin): Support Min Channel Load */ -+ /* UINT_8 aucChannelLoad[CHANNEL_NUM] = {0}; */ -+ -+ BOOLEAN fgIsFixedChannel; -+ ENUM_BAND_T eBand = 0; -+ UINT_8 ucChannel = 0; -+ -+ ASSERT(prAdapter); -+ -+ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[eNetTypeIndex]); -+ -+ prAisSpecBssInfo = &(prAdapter->rWifiVar.rAisSpecificBssInfo); -+ -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ prBSSDescList = &prScanInfo->rBSSDescList; -+ -+ GET_CURRENT_SYSTIME(&rCurrentTime); -+ -+ /* check for fixed channel operation */ -+ if (eNetTypeIndex == NETWORK_TYPE_AIS_INDEX) { -+#if CFG_P2P_LEGACY_COEX_REVISE -+ fgIsFixedChannel = cnmAisDetectP2PChannel(prAdapter, &eBand, &ucChannel); -+#else -+ fgIsFixedChannel = cnmAisInfraChannelFixed(prAdapter, &eBand, &ucChannel); -+#endif -+ } else { -+ fgIsFixedChannel = FALSE; -+ } -+ -+#if DBG -+ if (prConnSettings->ucSSIDLen < ELEM_MAX_LEN_SSID) -+ prConnSettings->aucSSID[prConnSettings->ucSSIDLen] = '\0'; -+#endif -+ -+ DBGLOG(SCN, INFO, "SEARCH: Bss Num: %d, Look for SSID: %s, %pM Band=%d, channel=%d\n", -+ (UINT_32) prBSSDescList->u4NumElem, prConnSettings->aucSSID, -+ (prConnSettings->aucBSSID), eBand, ucChannel); -+ -+ /* 4 <1> The outer loop to search for a candidate. */ -+ LINK_FOR_EACH_ENTRY(prBssDesc, prBSSDescList, rLinkEntry, BSS_DESC_T) { -+ -+ /* TODO(Kevin): Update Minimum Channel Load Information here */ -+ -+ DBGLOG(SCN, TRACE, "SEARCH: [ %pM ], SSID:%s\n", -+ prBssDesc->aucBSSID, prBssDesc->aucSSID); -+ -+ /* 4 <2> Check PHY Type and attributes */ -+ /* 4 <2.1> Check Unsupported BSS PHY Type */ -+ if (!(prBssDesc->ucPhyTypeSet & (prAdapter->rWifiVar.ucAvailablePhyTypeSet))) { -+ DBGLOG(SCN, TRACE, "SEARCH: Ignore unsupported ucPhyTypeSet = %x\n", prBssDesc->ucPhyTypeSet); -+ continue; -+ } -+ /* 4 <2.2> Check if has unknown NonHT BSS Basic Rate Set. */ -+ if (prBssDesc->fgIsUnknownBssBasicRate) -+ continue; -+ /* 4 <2.3> Check if fixed operation cases should be aware */ -+ if (fgIsFixedChannel == TRUE && (prBssDesc->eBand != eBand || prBssDesc->ucChannelNum != ucChannel)) -+ continue; -+ /* 4 <2.4> Check if the channel is legal under regulatory domain */ -+ if (rlmDomainIsLegalChannel(prAdapter, prBssDesc->eBand, prBssDesc->ucChannelNum) == FALSE) -+ continue; -+ /* 4 <2.5> Check if this BSS_DESC_T is stale */ -+ if (CHECK_FOR_TIMEOUT(rCurrentTime, prBssDesc->rUpdateTime, -+ SEC_TO_SYSTIME(SCN_BSS_DESC_REMOVE_TIMEOUT_SEC))) { -+ -+ BOOLEAN fgIsNeedToCheckTimeout = TRUE; -+ -+#if CFG_SUPPORT_ROAMING -+ P_ROAMING_INFO_T prRoamingFsmInfo; -+ -+ prRoamingFsmInfo = (P_ROAMING_INFO_T) &(prAdapter->rWifiVar.rRoamingInfo); -+ if ((prRoamingFsmInfo->eCurrentState == ROAMING_STATE_DISCOVERY) || -+ (prRoamingFsmInfo->eCurrentState == ROAMING_STATE_ROAM)) { -+ if (++prRoamingFsmInfo->RoamingEntryTimeoutSkipCount < -+ ROAMING_ENTRY_TIMEOUT_SKIP_COUNT_MAX) { -+ fgIsNeedToCheckTimeout = FALSE; -+ DBGLOG(SCN, INFO, "SEARCH: Romaing skip SCN_BSS_DESC_REMOVE_TIMEOUT_SEC\n"); -+ } -+ } -+#endif -+ -+ if (fgIsNeedToCheckTimeout == TRUE) { -+ DBGLOG(SCN, TRACE, "Ignore stale bss %pM\n", prBssDesc->aucBSSID); -+ continue; -+ } -+ } -+ /* 4 <3> Check if reach the excessive join retry limit */ -+ /* NOTE(Kevin): STA_RECORD_T is recorded by TA. */ -+ prStaRec = cnmGetStaRecByAddress(prAdapter, (UINT_8) eNetTypeIndex, prBssDesc->aucSrcAddr); -+ -+ if (prStaRec) { -+ /* NOTE(Kevin): -+ * The Status Code is the result of a Previous Connection Request, -+ * we use this as SCORE for choosing a proper -+ * candidate (Also used for compare see <6>) -+ * The Reason Code is an indication of the reason why AP reject us, -+ * we use this Code for "Reject" -+ * a SCAN result to become our candidate(Like a blacklist). -+ */ -+#if 0 /* TODO(Kevin): */ -+ if (prStaRec->u2ReasonCode != REASON_CODE_RESERVED) { -+ DBGLOG(SCN, INFO, "SEARCH: Ignore BSS with previous Reason Code = %d\n", -+ prStaRec->u2ReasonCode); -+ continue; -+ } else -+#endif -+ if (prStaRec->u2StatusCode != STATUS_CODE_SUCCESSFUL) { -+ /* NOTE(Kevin): greedy association - after timeout, we'll still -+ * try to associate to the AP whose STATUS of conection attempt -+ * was not success. -+ * We may also use (ucJoinFailureCount x JOIN_RETRY_INTERVAL_SEC) for -+ * time bound. -+ */ -+ if ((prStaRec->ucJoinFailureCount < JOIN_MAX_RETRY_FAILURE_COUNT) || -+ (CHECK_FOR_TIMEOUT(rCurrentTime, -+ prStaRec->rLastJoinTime, -+ SEC_TO_SYSTIME(JOIN_RETRY_INTERVAL_SEC)))) { -+ -+ /* NOTE(Kevin): Every JOIN_RETRY_INTERVAL_SEC interval, we can retry -+ * JOIN_MAX_RETRY_FAILURE_COUNT times. -+ */ -+ if (prStaRec->ucJoinFailureCount >= JOIN_MAX_RETRY_FAILURE_COUNT) -+ prStaRec->ucJoinFailureCount = 0; -+ DBGLOG(SCN, INFO, -+ "SEARCH: Try to join BSS again,Status Code=%d (Curr=%u/Last Join=%u)\n", -+ prStaRec->u2StatusCode, rCurrentTime, prStaRec->rLastJoinTime); -+ } else { -+ DBGLOG(SCN, INFO, -+ "SEARCH: Ignore BSS which reach maximum Join Retry Count = %d\n", -+ JOIN_MAX_RETRY_FAILURE_COUNT); -+ continue; -+ } -+ -+ } -+ } -+ /* 4 <4> Check for various NETWORK conditions */ -+ if (eNetTypeIndex == NETWORK_TYPE_AIS_INDEX) { -+ -+ /* 4 <4.1> Check BSS Type for the corresponding Operation Mode in Connection Setting */ -+ /* NOTE(Kevin): For NET_TYPE_AUTO_SWITCH, we will always pass following check. */ -+ if (((prConnSettings->eOPMode == NET_TYPE_INFRA) && -+ (prBssDesc->eBSSType != BSS_TYPE_INFRASTRUCTURE)) -+#if CFG_SUPPORT_ADHOC -+ || ((prConnSettings->eOPMode == NET_TYPE_IBSS -+ || prConnSettings->eOPMode == NET_TYPE_DEDICATED_IBSS) -+ && (prBssDesc->eBSSType != BSS_TYPE_IBSS)) -+#endif -+ ) { -+ -+ DBGLOG(SCN, TRACE, "Cur OPMode %d, Ignore eBSSType = %d\n", -+ prConnSettings->eOPMode, prBssDesc->eBSSType); -+ continue; -+ } -+ /* 4 <4.2> Check AP's BSSID if OID_802_11_BSSID has been set. */ -+ if ((prConnSettings->fgIsConnByBssidIssued) && -+ (prBssDesc->eBSSType == BSS_TYPE_INFRASTRUCTURE)) { -+ -+ if (UNEQUAL_MAC_ADDR(prConnSettings->aucBSSID, prBssDesc->aucBSSID)) { -+ -+ DBGLOG(SCN, TRACE, "SEARCH: Ignore due to BSSID was not matched!\n"); -+ continue; -+ } -+ } -+#if CFG_SUPPORT_ADHOC -+ /* 4 <4.3> Check for AdHoc Mode */ -+ if (prBssDesc->eBSSType == BSS_TYPE_IBSS) { -+ OS_SYSTIME rCurrentTime; -+ -+ /* 4 <4.3.1> Check if this SCAN record has been updated recently for IBSS. */ -+ /* NOTE(Kevin): Because some STA may change its BSSID frequently after it -+ * create the IBSS - e.g. IPN2220, so we need to make sure we get the new one. -+ * For BSS, if the old record was matched, however it won't be able to pass -+ * the Join Process later. -+ */ -+ GET_CURRENT_SYSTIME(&rCurrentTime); -+ if (CHECK_FOR_TIMEOUT(rCurrentTime, prBssDesc->rUpdateTime, -+ SEC_TO_SYSTIME(SCN_ADHOC_BSS_DESC_TIMEOUT_SEC))) { -+ DBGLOG(SCN, LOUD, -+ "SEARCH: Skip old record of BSS Descriptor - BSSID:[%pM]\n\n", -+ prBssDesc->aucBSSID); -+ continue; -+ } -+ /* 4 <4.3.2> Check Peer's capability */ -+ if (ibssCheckCapabilityForAdHocMode(prAdapter, prBssDesc) == WLAN_STATUS_FAILURE) { -+ -+ if (prPrimaryBssDesc) -+ DBGLOG(SCN, INFO, -+ "SEARCH: BSS DESC MAC: %pM, not supported AdHoc Mode.\n", -+ prPrimaryBssDesc->aucBSSID); -+ -+ continue; -+ } -+ /* 4 <4.3.3> Compare TSF */ -+ if (prBssInfo->fgIsBeaconActivated && -+ UNEQUAL_MAC_ADDR(prBssInfo->aucBSSID, prBssDesc->aucBSSID)) { -+ -+ DBGLOG(SCN, LOUD, -+ "SEARCH: prBssDesc->fgIsLargerTSF = %d\n", prBssDesc->fgIsLargerTSF); -+ -+ if (!prBssDesc->fgIsLargerTSF) { -+ DBGLOG(SCN, INFO, -+ "SEARCH: Ignore BSS DESC MAC: [ %pM ], Smaller TSF\n", -+ prBssDesc->aucBSSID); -+ continue; -+ } -+ } -+ } -+#endif /* CFG_SUPPORT_ADHOC */ -+ -+ } -+#if 0 /* TODO(Kevin): For IBSS */ -+ /* 4 <2.c> Check if this SCAN record has been updated recently for IBSS. */ -+ /* NOTE(Kevin): Because some STA may change its BSSID frequently after it -+ * create the IBSS, so we need to make sure we get the new one. -+ * For BSS, if the old record was matched, however it won't be able to pass -+ * the Join Process later. -+ */ -+ if (prBssDesc->eBSSType == BSS_TYPE_IBSS) { -+ OS_SYSTIME rCurrentTime; -+ -+ GET_CURRENT_SYSTIME(&rCurrentTime); -+ if (CHECK_FOR_TIMEOUT(rCurrentTime, prBssDesc->rUpdateTime, -+ SEC_TO_SYSTIME(BSS_DESC_TIMEOUT_SEC))) { -+ DBGLOG(SCAN, TRACE, "Skip old record of BSS Descriptor - BSSID:[%pM]\n\n", -+ prBssDesc->aucBSSID); -+ continue; -+ } -+ } -+ -+ if ((prBssDesc->eBSSType == BSS_TYPE_INFRASTRUCTURE) && -+ (prAdapter->eConnectionState == MEDIA_STATE_CONNECTED)) { -+ OS_SYSTIME rCurrentTime; -+ -+ GET_CURRENT_SYSTIME(&rCurrentTime); -+ if (CHECK_FOR_TIMEOUT(rCurrentTime, prBssDesc->rUpdateTime, -+ SEC_TO_SYSTIME(BSS_DESC_TIMEOUT_SEC))) { -+ DBGLOG(SCAN, TRACE, "Skip old record of BSS Descriptor - BSSID:[%pM]\n\n", -+ (prBssDesc->aucBSSID)); -+ continue; -+ } -+ } -+ /* 4 <4B> Check for IBSS AdHoc Mode. */ -+ /* Skip if one or more BSS Basic Rate are not supported by current AdHocMode */ -+ if (prPrimaryBssDesc->eBSSType == BSS_TYPE_IBSS) { -+ /* 4 <4B.1> Check if match the Capability of current IBSS AdHoc Mode. */ -+ if (ibssCheckCapabilityForAdHocMode(prAdapter, prPrimaryBssDesc) == WLAN_STATUS_FAILURE) { -+ -+ DBGLOG(SCAN, TRACE, -+ "Ignore BSS DESC MAC: %pM, Capability not supported for AdHoc Mode.\n", -+ prPrimaryBssDesc->aucBSSID); -+ -+ continue; -+ } -+ /* 4 <4B.2> IBSS Merge Decision Flow for SEARCH STATE. */ -+ if (prAdapter->fgIsIBSSActive && -+ UNEQUAL_MAC_ADDR(prBssInfo->aucBSSID, prPrimaryBssDesc->aucBSSID)) { -+ -+ if (!fgIsLocalTSFRead) { -+ NIC_GET_CURRENT_TSF(prAdapter, &rCurrentTsf); -+ -+ DBGLOG(SCAN, TRACE, -+ "\n\nCurrent TSF : %08lx-%08lx\n\n", -+ rCurrentTsf.u.HighPart, rCurrentTsf.u.LowPart); -+ } -+ -+ if (rCurrentTsf.QuadPart > prPrimaryBssDesc->u8TimeStamp.QuadPart) { -+ DBGLOG(SCAN, TRACE, -+ "Ignore BSS DESC MAC: [%pM], Current BSSID: [%pM].\n", -+ prPrimaryBssDesc->aucBSSID, prBssInfo->aucBSSID); -+ -+ DBGLOG(SCAN, TRACE, -+ "\n\nBSS's TSF : %08lx-%08lx\n\n", -+ prPrimaryBssDesc->u8TimeStamp.u.HighPart, -+ prPrimaryBssDesc->u8TimeStamp.u.LowPart); -+ -+ prPrimaryBssDesc->fgIsLargerTSF = FALSE; -+ continue; -+ } else { -+ prPrimaryBssDesc->fgIsLargerTSF = TRUE; -+ } -+ -+ } -+ } -+ /* 4 <5> Check the Encryption Status. */ -+ if (rsnPerformPolicySelection(prPrimaryBssDesc)) { -+ -+ if (prPrimaryBssDesc->ucEncLevel > 0) { -+ fgIsFindBestEncryptionLevel = TRUE; -+ -+ fgIsFindFirst = FALSE; -+ } -+ } else { -+ /* Can't pass the Encryption Status Check, get next one */ -+ continue; -+ } -+ -+ /* For RSN Pre-authentication, update the PMKID canidate list for -+ same SSID and encrypt status */ -+ /* Update PMKID candicate list. */ -+ if (prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA2) { -+ rsnUpdatePmkidCandidateList(prPrimaryBssDesc); -+ if (prAdapter->rWifiVar.rAisBssInfo.u4PmkidCandicateCount) -+ prAdapter->rWifiVar.rAisBssInfo.fgIndicatePMKID = rsnCheckPmkidCandicate(); -+ } -+#endif -+ -+ prPrimaryBssDesc = (P_BSS_DESC_T) NULL; -+ -+ /* 4 <6> Check current Connection Policy. */ -+ switch (prConnSettings->eConnectionPolicy) { -+ case CONNECT_BY_SSID_BEST_RSSI: -+ /* Choose Hidden SSID to join only if the `fgIsEnableJoin...` is TRUE */ -+ if (prAdapter->rWifiVar.fgEnableJoinToHiddenSSID && prBssDesc->fgIsHiddenSSID) { -+ /* NOTE(Kevin): following if () statement means that -+ * If Target is hidden, then we won't connect when user specify SSID_ANY policy. -+ */ -+ if (prConnSettings->ucSSIDLen) { -+ prPrimaryBssDesc = prBssDesc; -+ fgIsFindBestRSSI = TRUE; -+ } -+ -+ } else if (EQUAL_SSID(prBssDesc->aucSSID, -+ prBssDesc->ucSSIDLen, -+ prConnSettings->aucSSID, prConnSettings->ucSSIDLen)) { -+ prPrimaryBssDesc = prBssDesc; -+ fgIsFindBestRSSI = TRUE; -+ -+ DBGLOG(SCN, TRACE, "SEARCH: fgIsFindBestRSSI=TRUE, %d, prPrimaryBssDesc=[ %pM ]\n", -+ prBssDesc->ucRCPI, prPrimaryBssDesc->aucBSSID); -+ } -+ break; -+ -+ case CONNECT_BY_SSID_ANY: -+ /* NOTE(Kevin): In this policy, we don't know the desired -+ * SSID from user, so we should exclude the Hidden SSID from scan list. -+ * And because we refuse to connect to Hidden SSID node at the beginning, so -+ * when the JOIN Module deal with a BSS_DESC_T which has fgIsHiddenSSID == TRUE, -+ * then the Connection Settings must be valid without doubt. -+ */ -+ if (!prBssDesc->fgIsHiddenSSID) { -+ prPrimaryBssDesc = prBssDesc; -+ fgIsFindFirst = TRUE; -+ } -+ break; -+ -+ case CONNECT_BY_BSSID: -+ if (EQUAL_MAC_ADDR(prBssDesc->aucBSSID, prConnSettings->aucBSSID)) -+ prPrimaryBssDesc = prBssDesc; -+ break; -+ -+ default: -+ break; -+ } -+ -+ /* Primary Candidate was not found */ -+ if (prPrimaryBssDesc == NULL) -+ continue; -+ /* 4 <7> Check the Encryption Status. */ -+ if (prPrimaryBssDesc->eBSSType == BSS_TYPE_INFRASTRUCTURE) { -+#if CFG_SUPPORT_WAPI -+ if (prAdapter->rWifiVar.rConnSettings.fgWapiMode) { -+ DBGLOG(SCN, TRACE, "SEARCH: fgWapiMode == 1\n"); -+ -+ if (wapiPerformPolicySelection(prAdapter, prPrimaryBssDesc)) { -+ fgIsFindFirst = TRUE; -+ } else { -+ /* Can't pass the Encryption Status Check, get next one */ -+ DBGLOG(SCN, TRACE, "SEARCH: WAPI cannot pass the Encryption Status Check!\n"); -+ continue; -+ } -+ } else -+#endif -+#if CFG_RSN_MIGRATION -+ if (rsnPerformPolicySelection(prAdapter, prPrimaryBssDesc)) { -+ if (prAisSpecBssInfo->fgCounterMeasure) { -+ DBGLOG(RSN, INFO, "Skip while at counter measure period!!!\n"); -+ continue; -+ } -+ -+ if (prPrimaryBssDesc->ucEncLevel > 0) { -+ fgIsFindBestEncryptionLevel = TRUE; -+ fgIsFindFirst = FALSE; -+ } -+#if 0 -+ /* Update PMKID candicate list. */ -+ if (prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA2) { -+ rsnUpdatePmkidCandidateList(prPrimaryBssDesc); -+ if (prAisSpecBssInfo->u4PmkidCandicateCount) { -+ if (rsnCheckPmkidCandicate()) { -+ DBGLOG(RSN, WARN, -+ "Prepare a timer to indicate candidate %pM\n", -+ (prAisSpecBssInfo->arPmkidCache -+ [prAisSpecBssInfo->u4PmkidCacheCount]. -+ rBssidInfo.aucBssid))); -+ cnmTimerStopTimer(&prAisSpecBssInfo->rPreauthenticationTimer); -+ cnmTimerStartTimer(&prAisSpecBssInfo->rPreauthenticationTimer, -+ SEC_TO_MSEC -+ (WAIT_TIME_IND_PMKID_CANDICATE_SEC)); -+ } -+ } -+ } -+#endif -+ } else { -+ /* Can't pass the Encryption Status Check, get next one */ -+ continue; -+ } -+#endif -+ } else { -+ /* Todo:: P2P and BOW Policy Selection */ -+ } -+ -+ prPrimaryStaRec = prStaRec; -+ -+ /* 4 <8> Compare the Candidate and the Primary Scan Record. */ -+ if (!prCandidateBssDesc) { -+ prCandidateBssDesc = prPrimaryBssDesc; -+ prCandidateStaRec = prPrimaryStaRec; -+ -+ /* 4 <8.1> Condition - Get the first matched one. */ -+ if (fgIsFindFirst) -+ break; -+ } else { -+#if 0 /* TODO(Kevin): For security(TBD) */ -+ /* 4 <6B> Condition - Choose the one with best Encryption Score. */ -+ if (fgIsFindBestEncryptionLevel) { -+ if (prCandidateBssDesc->ucEncLevel < prPrimaryBssDesc->ucEncLevel) { -+ -+ prCandidateBssDesc = prPrimaryBssDesc; -+ prCandidateStaRec = prPrimaryStaRec; -+ continue; -+ } -+ } -+ -+ /* If reach here, that means they have the same Encryption Score. -+ */ -+ -+ /* 4 <6C> Condition - Give opportunity to the one we didn't connect before. */ -+ /* For roaming, only compare the candidates other than current associated BSSID. */ -+ if (!prCandidateBssDesc->fgIsConnected && !prPrimaryBssDesc->fgIsConnected) { -+ if ((prCandidateStaRec != (P_STA_RECORD_T) NULL) && -+ (prCandidateStaRec->u2StatusCode != STATUS_CODE_SUCCESSFUL)) { -+ -+ DBGLOG(SCAN, TRACE, -+ "So far -BSS DESC MAC: %pM has nonzero Status Code = %d\n", -+ prCandidateBssDesc->aucBSSID, -+ prCandidateStaRec->u2StatusCode); -+ -+ if (prPrimaryStaRec != (P_STA_RECORD_T) NULL) { -+ if (prPrimaryStaRec->u2StatusCode != STATUS_CODE_SUCCESSFUL) { -+ -+ /* Give opportunity to the one with smaller rLastJoinTime */ -+ if (TIME_BEFORE(prCandidateStaRec->rLastJoinTime, -+ prPrimaryStaRec->rLastJoinTime)) { -+ continue; -+ } -+ /* We've connect to CANDIDATE recently, -+ * let us try PRIMARY now */ -+ else { -+ prCandidateBssDesc = prPrimaryBssDesc; -+ prCandidateStaRec = prPrimaryStaRec; -+ continue; -+ } -+ } -+ /* PRIMARY's u2StatusCode = 0 */ -+ else { -+ prCandidateBssDesc = prPrimaryBssDesc; -+ prCandidateStaRec = prPrimaryStaRec; -+ continue; -+ } -+ } -+ /* PRIMARY has no StaRec - We didn't connet to PRIMARY before */ -+ else { -+ prCandidateBssDesc = prPrimaryBssDesc; -+ prCandidateStaRec = prPrimaryStaRec; -+ continue; -+ } -+ } else { -+ if ((prPrimaryStaRec != (P_STA_RECORD_T) NULL) && -+ (prPrimaryStaRec->u2StatusCode != STATUS_CODE_SUCCESSFUL)) { -+ continue; -+ } -+ } -+ } -+#endif -+ -+ /* 4 <6D> Condition - Visible SSID win Hidden SSID. */ -+ if (prCandidateBssDesc->fgIsHiddenSSID) { -+ if (!prPrimaryBssDesc->fgIsHiddenSSID) { -+ prCandidateBssDesc = prPrimaryBssDesc; /* The non Hidden SSID win. */ -+ prCandidateStaRec = prPrimaryStaRec; -+ continue; -+ } -+ } else { -+ if (prPrimaryBssDesc->fgIsHiddenSSID) -+ continue; -+ } -+ -+ /* 4 <6E> Condition - Choose the one with better RCPI(RSSI). */ -+ if (fgIsFindBestRSSI) { -+ /* TODO(Kevin): We shouldn't compare the actual value, we should -+ * allow some acceptable tolerance of some RSSI percentage here. -+ */ -+ DBGLOG(SCN, TRACE, -+ "Candidate [%pM]: RCPI = %d, joinFailCnt=%d, Primary [%pM]: RCPI = %d, joinFailCnt=%d\n", -+ prCandidateBssDesc->aucBSSID, -+ prCandidateBssDesc->ucRCPI, prCandidateBssDesc->ucJoinFailureCount, -+ prPrimaryBssDesc->aucBSSID, -+ prPrimaryBssDesc->ucRCPI, prPrimaryBssDesc->ucJoinFailureCount); -+ -+ ASSERT(!(prCandidateBssDesc->fgIsConnected && prPrimaryBssDesc->fgIsConnected)); -+ if (prPrimaryBssDesc->ucJoinFailureCount >= SCN_BSS_JOIN_FAIL_THRESOLD) { -+ /* give a chance to do join if join fail before -+ * SCN_BSS_DECRASE_JOIN_FAIL_CNT_SEC seconds -+ */ -+ if (CHECK_FOR_TIMEOUT(rCurrentTime, prBssDesc->rJoinFailTime, -+ SEC_TO_SYSTIME(SCN_BSS_JOIN_FAIL_CNT_RESET_SEC))) { -+ prBssDesc->ucJoinFailureCount = SCN_BSS_JOIN_FAIL_THRESOLD - -+ SCN_BSS_JOIN_FAIL_RESET_STEP; -+ DBGLOG(SCN, INFO, -+ "decrease join fail count for Bss %pM to %u, timeout second %d\n", -+ prBssDesc->aucBSSID, prBssDesc->ucJoinFailureCount, -+ SCN_BSS_JOIN_FAIL_CNT_RESET_SEC); -+ } -+ } -+ -+ /* NOTE: To prevent SWING, -+ * we do roaming only if target AP has at least 5dBm larger than us. */ -+ if (prCandidateBssDesc->fgIsConnected) { -+ if (prCandidateBssDesc->ucRCPI + ROAMING_NO_SWING_RCPI_STEP <= -+ prPrimaryBssDesc->ucRCPI && -+ prPrimaryBssDesc->ucJoinFailureCount < SCN_BSS_JOIN_FAIL_THRESOLD) { -+ -+ prCandidateBssDesc = prPrimaryBssDesc; -+ prCandidateStaRec = prPrimaryStaRec; -+ continue; -+ } -+ } else if (prPrimaryBssDesc->fgIsConnected) { -+ if (prCandidateBssDesc->ucRCPI < -+ (prPrimaryBssDesc->ucRCPI + ROAMING_NO_SWING_RCPI_STEP) || -+ (prCandidateBssDesc->ucJoinFailureCount >= -+ SCN_BSS_JOIN_FAIL_THRESOLD)) { -+ prCandidateBssDesc = prPrimaryBssDesc; -+ prCandidateStaRec = prPrimaryStaRec; -+ continue; -+ } -+ } else if (prPrimaryBssDesc->ucJoinFailureCount >= SCN_BSS_JOIN_FAIL_THRESOLD) -+ continue; -+ else if (prCandidateBssDesc->ucJoinFailureCount >= SCN_BSS_JOIN_FAIL_THRESOLD || -+ prCandidateBssDesc->ucRCPI < prPrimaryBssDesc->ucRCPI) { -+ prCandidateBssDesc = prPrimaryBssDesc; -+ prCandidateStaRec = prPrimaryStaRec; -+ continue; -+ } -+ } -+#if 0 -+ /* If reach here, that means they have the same Encryption Score, and -+ * both RSSI value are close too. -+ */ -+ /* 4 <6F> Seek the minimum Channel Load for less interference. */ -+ if (fgIsFindMinChannelLoad) { -+ /* Do nothing */ -+ /* TODO(Kevin): Check which one has minimum channel load in its channel */ -+ } -+#endif -+ } -+ } -+ -+ -+ if (prCandidateBssDesc != NULL) { -+ DBGLOG(SCN, INFO, -+ "SEARCH: Candidate BSS: %pM\n", prCandidateBssDesc->aucBSSID); -+ } -+ -+ return prCandidateBssDesc; -+ -+} /* end of scanSearchBssDescByPolicy() */ -+ -+#if CFG_SUPPORT_AGPS_ASSIST -+VOID scanReportScanResultToAgps(P_ADAPTER_T prAdapter) -+{ -+ P_LINK_T prBSSDescList = &prAdapter->rWifiVar.rScanInfo.rBSSDescList; -+ P_BSS_DESC_T prBssDesc = NULL; -+ P_AGPS_AP_LIST_T prAgpsApList; -+ P_AGPS_AP_INFO_T prAgpsInfo; -+ P_SCAN_INFO_T prScanInfo = &prAdapter->rWifiVar.rScanInfo; -+ UINT_8 ucIndex = 0; -+ -+ prAgpsApList = kalMemAlloc(sizeof(AGPS_AP_LIST_T), VIR_MEM_TYPE); -+ if (!prAgpsApList) -+ return; -+ -+ prAgpsInfo = &prAgpsApList->arApInfo[0]; -+ LINK_FOR_EACH_ENTRY(prBssDesc, prBSSDescList, rLinkEntry, BSS_DESC_T) { -+ if (prBssDesc->rUpdateTime < prScanInfo->rLastScanCompletedTime) -+ continue; -+ COPY_MAC_ADDR(prAgpsInfo->aucBSSID, prBssDesc->aucBSSID); -+ prAgpsInfo->ePhyType = AGPS_PHY_G; -+ prAgpsInfo->u2Channel = prBssDesc->ucChannelNum; -+ prAgpsInfo->i2ApRssi = RCPI_TO_dBm(prBssDesc->ucRCPI); -+ prAgpsInfo++; -+ ucIndex++; -+ if (ucIndex == 32) -+ break; -+ } -+ prAgpsApList->ucNum = ucIndex; -+ GET_CURRENT_SYSTIME(&prScanInfo->rLastScanCompletedTime); -+ /* DBGLOG(SCN, INFO, ("num of scan list:%d\n", ucIndex)); */ -+ kalIndicateAgpsNotify(prAdapter, AGPS_EVENT_WLAN_AP_LIST, (PUINT_8) prAgpsApList, sizeof(AGPS_AP_LIST_T)); -+ kalMemFree(prAgpsApList, VIR_MEM_TYPE, sizeof(AGPS_AP_LIST_T)); -+} -+#endif -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/scan_fsm.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/scan_fsm.c -new file mode 100644 -index 000000000000..fac9f94428dd ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/scan_fsm.c -@@ -0,0 +1,2136 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/scan_fsm.c#1 -+*/ -+ -+/*! \file "scan_fsm.c" -+ \brief This file defines the state transition function for SCAN FSM. -+ -+ The SCAN FSM is part of SCAN MODULE and responsible for performing basic SCAN -+ behavior as metioned in IEEE 802.11 2007 11.1.3.1 & 11.1.3.2 . -+*/ -+ -+/* -+** Log: scan_fsm.c -+ * -+ * 06 13 2012 yuche.tsai -+ * NULL -+ * Update maintrunk driver. -+ * Add support for driver compose assoc request frame. -+ * -+ * 11 24 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * Adjust code for DBG and CONFIG_XLOG. -+ * -+ * 11 14 2011 yuche.tsai -+ * [WCXRP00001095] [Volunteer Patch][Driver] Always Scan before enable Hot-Spot. -+ * Fix bug when unregister P2P network.. -+ * -+ * 11 11 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * modify the xlog related code. -+ * -+ * 11 02 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * adding the code for XLOG. -+ * -+ * 08 11 2011 cp.wu -+ * [WCXRP00000830] [MT6620 Wi-Fi][Firmware] Use MDRDY counter to detect empty channel for shortening scan time -+ * sparse channel detection: -+ * driver: collect sparse channel information with scan-done event -+ * -+ * 07 18 2011 cp.wu -+ * [WCXRP00000858] [MT5931][Driver][Firmware] Add support for scan to search -+ * for more than one SSID in a single scanning request -+ * free mailbox message afte parsing is completed. -+ * -+ * 07 18 2011 cp.wu -+ * [WCXRP00000858] [MT5931][Driver][Firmware] Add support for scan to search -+ * for more than one SSID in a single scanning request -+ * add framework in driver domain for supporting new SCAN_REQ_V2 for more than 1 SSID support -+ * as well as uProbeDelay in NDIS 6.x driver model -+ * -+ * 04 18 2011 terry.wu -+ * [WCXRP00000660] [MT6620 Wi-Fi][Driver] Remove flag CFG_WIFI_DIRECT_MOVED -+ * Remove flag CFG_WIFI_DIRECT_MOVED. -+ * -+ * 03 29 2011 cp.wu -+ * [WCXRP00000604] [MT6620 Wi-Fi][Driver] Surpress Klockwork Warning -+ * surpress klock warning with code path rewritten -+ * -+ * 03 18 2011 cm.chang -+ * [WCXRP00000576] [MT6620 Wi-Fi][Driver][FW] Remove P2P compile option in scan req/cancel command -+ * As CR title -+ * -+ * 02 18 2011 yuche.tsai -+ * [WCXRP00000478] [Volunteer Patch][MT6620][Driver] Probe request frame -+ * during search phase do not contain P2P wildcard SSID. -+ * Take P2P wildcard SSID into consideration. -+ * -+ * 01 27 2011 yuche.tsai -+ * [WCXRP00000399] [Volunteer Patch][MT6620/MT5931][Driver] Fix scan side effect after P2P module separate. -+ * Fix scan channel extension issue when p2p module is not registered. -+ * -+ * 01 26 2011 yuche.tsai -+ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record. -+ * . -+ * -+ * 01 25 2011 yuche.tsai -+ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record. -+ * Fix Compile Error when DBG is disabled. -+ * -+ * 12 07 2010 cm.chang -+ * [WCXRP00000238] MT6620 Wi-Fi][Driver][FW] Support regulation domain setting from NVRAM and supplicant -+ * 1. Country code is from NVRAM or supplicant -+ * 2. Change band definition in CMD/EVENT. -+ * -+ * 09 03 2010 kevin.huang -+ * NULL -+ * Refine #include sequence and solve recursive/nested #include issue -+ * -+ * 08 30 2010 cp.wu -+ * NULL -+ * eliminate klockwork errors -+ * -+ * 08 16 2010 cp.wu -+ * NULL -+ * add interface for RLM to trigger OBSS-SCAN. -+ * -+ * 08 16 2010 yuche.tsai -+ * NULL -+ * Fix bug for processing queued scan request. -+ * -+ * 08 11 2010 yuche.tsai -+ * NULL -+ * Add a function for returning channel. -+ * -+ * 08 05 2010 yuche.tsai -+ * NULL -+ * Update SCAN FSM for support P2P Device discovery scan. -+ * -+ * 08 03 2010 cp.wu -+ * NULL -+ * surpress compilation warning. -+ * -+ * 07 26 2010 yuche.tsai -+ * -+ * Add option of channel extension while cancelling scan request. -+ * -+ * 07 21 2010 yuche.tsai -+ * -+ * Add P2P Scan & Scan Result Parsing & Saving. -+ * -+ * 07 20 2010 cp.wu -+ * -+ * pass band information for scan in an efficient way by mapping ENUM_BAND_T into UINT_8.. -+ * -+ * 07 19 2010 cp.wu -+ * -+ * due to FW/DRV won't be sync. precisely, some strict assertions should be eased. -+ * -+ * 07 19 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration. -+ * SCN module is now able to handle multiple concurrent scanning requests -+ * -+ * 07 16 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration. -+ * bugfix for SCN migration -+ * 1) modify QUEUE_CONCATENATE_QUEUES() so it could be used to concatence with an empty queue -+ * 2) before AIS issues scan request, network(BSS) needs to be activated first -+ * 3) only invoke COPY_SSID when using specified SSID for scan -+ * -+ * 07 15 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration. -+ * driver no longer generates probe request frames -+ * -+ * 07 14 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration. -+ * pass band with channel number information as scan parameter -+ * -+ * 07 14 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration. -+ * remove timer in DRV-SCN. -+ * -+ * 07 09 2010 cp.wu -+ * -+ * 1) separate AIS_FSM state for two kinds of scanning. (OID triggered scan, and scan-for-connection) -+ * 2) eliminate PRE_BSS_DESC_T, Beacon/PrebResp is now parsed in single pass -+ * 3) implment DRV-SCN module, currently only accepts single scan request, -+ * other request will be directly dropped by returning BUSY -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 07 08 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * take use of RLM module for parsing/generating HT IEs for 11n capability -+ * -+ * 07 02 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * when returning to SCAN_IDLE state, send a correct message to source FSM. -+ * -+ * 07 01 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * implementation of DRV-SCN and related mailbox message handling. -+ * -+ * 06 22 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * comment out RLM APIs by CFG_RLM_MIGRATION. -+ * -+ * 06 21 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add scan_fsm into building. -+ * -+ * 05 14 2010 kevin.huang -+ * [BORA00000794][WIFISYS][New Feature]Power Management Support -+ * Refine the order of Stop TX Queue and Switch Channel -+ * -+ * 05 12 2010 kevin.huang -+ * [BORA00000794][WIFISYS][New Feature]Power Management Support -+ * Update pause/resume/flush API to new Bitmap API -+ * -+ * 05 12 2010 kevin.huang -+ * [BORA00000794][WIFISYS][New Feature]Power Management Support -+ * Add Power Management - Legacy PS-POLL support. -+ * -+ * 03 18 2010 kevin.huang -+ * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support -+ * Ignore the PROBE_DELAY state if the value of Probe Delay == 0 -+ * -+ * 03 10 2010 kevin.huang -+ * [BORA00000654][WIFISYS][New Feature] CNM Module - Ch Manager Support -+ * Add Channel Manager for arbitration of JOIN and SCAN Req -+ * -+ * 02 23 2010 kevin.huang -+ * [BORA00000603][WIFISYS] [New Feature] AAA Module Support -+ * Add support scan channel 1~14 and update scan result's frequency infou1rwduu`wvpghlqg|n`slk+mpdkb -+ * -+ * 01 08 2010 kevin.huang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * Add set RX Filter to receive BCN from different BSSID during SCAN -+ * -+ * 12 18 2009 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * . -+ * -+ * Nov 25 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Remove flag of CFG_TEST_MGMT_FSM -+ * -+ * Nov 20 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Change parameter of scanSendProbeReqFrames() -+ * -+ * Nov 16 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Update scnFsmSteps() -+ * -+ * Nov 5 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * Fix typo -+ * -+ * Nov 5 2009 mtk01461 -+ * [BORA00000018] Integrate WIFI part into BORA for the 1st time -+ * -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "precomp.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+#if DBG -+/*lint -save -e64 Type mismatch */ -+static PUINT_8 apucDebugScanState[SCAN_STATE_NUM] = { -+ (PUINT_8) DISP_STRING("SCAN_STATE_IDLE"), -+ (PUINT_8) DISP_STRING("SCAN_STATE_SCANNING"), -+}; -+ -+/*lint -restore */ -+#endif /* DBG */ -+ -+#define CURRENT_PSCN_VERSION 1 -+#define RSSI_MARGIN_DEFAULT 5 -+#define MAX_PERIOD 200000 -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID scnFsmSteps(IN P_ADAPTER_T prAdapter, IN ENUM_SCAN_STATE_T eNextState) -+{ -+ P_SCAN_INFO_T prScanInfo; -+ P_SCAN_PARAM_T prScanParam; -+ P_MSG_HDR_T prMsgHdr; -+ -+ BOOLEAN fgIsTransition = (BOOLEAN) FALSE; -+ -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ prScanParam = &prScanInfo->rScanParam; -+ -+ do { -+ -+#if DBG -+ DBGLOG(SCN, STATE, "TRANSITION: [%s] -> [%s]\n", -+ apucDebugScanState[prScanInfo->eCurrentState], apucDebugScanState[eNextState]); -+#else -+ DBGLOG(SCN, STATE, "[%d] TRANSITION: [%d] -> [%d]\n", -+ DBG_SCN_IDX, prScanInfo->eCurrentState, eNextState); -+#endif -+ -+ /* NOTE(Kevin): This is the only place to change the eCurrentState(except initial) */ -+ prScanInfo->eCurrentState = eNextState; -+ -+ fgIsTransition = (BOOLEAN) FALSE; -+ -+ switch (prScanInfo->eCurrentState) { -+ case SCAN_STATE_IDLE: -+ /* check for pending scanning requests */ -+ if (!LINK_IS_EMPTY(&(prScanInfo->rPendingMsgList))) { -+ /* load next message from pending list as scan parameters */ -+ LINK_REMOVE_HEAD(&(prScanInfo->rPendingMsgList), prMsgHdr, P_MSG_HDR_T); -+ -+ if (prMsgHdr->eMsgId == MID_AIS_SCN_SCAN_REQ -+ || prMsgHdr->eMsgId == MID_BOW_SCN_SCAN_REQ -+ || prMsgHdr->eMsgId == MID_P2P_SCN_SCAN_REQ -+ || prMsgHdr->eMsgId == MID_RLM_SCN_SCAN_REQ) { -+ scnFsmHandleScanMsg(prAdapter, (P_MSG_SCN_SCAN_REQ) prMsgHdr); -+ } else { -+ scnFsmHandleScanMsgV2(prAdapter, (P_MSG_SCN_SCAN_REQ_V2) prMsgHdr); -+ } -+ -+ /* switch to next state */ -+ eNextState = SCAN_STATE_SCANNING; -+ fgIsTransition = TRUE; -+ -+ cnmMemFree(prAdapter, prMsgHdr); -+ } -+ break; -+ -+ case SCAN_STATE_SCANNING: -+ if (prScanParam->fgIsScanV2 == FALSE) -+ scnSendScanReq(prAdapter); -+ else -+ scnSendScanReqV2(prAdapter); -+ break; -+ -+ default: -+ ASSERT(0); -+ break; -+ -+ } -+ } while (fgIsTransition); -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Generate CMD_ID_SCAN_REQ command -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID scnSendScanReqExtCh(IN P_ADAPTER_T prAdapter) -+{ -+ P_SCAN_INFO_T prScanInfo; -+ P_SCAN_PARAM_T prScanParam; -+ /*CMD_SCAN_REQ_EXT_CH rCmdScanReq;*/ -+ P_CMD_SCAN_REQ_EXT_CH prCmdScanReq; -+ UINT_32 i; -+ -+ ASSERT(prAdapter); -+ -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ prScanParam = &prScanInfo->rScanParam; -+ -+ prCmdScanReq = kalMemAlloc(sizeof(CMD_SCAN_REQ_EXT_CH), VIR_MEM_TYPE); -+ if (prCmdScanReq == NULL) -+ return; -+ -+ /* send command packet for scan */ -+ kalMemZero(prCmdScanReq, sizeof(CMD_SCAN_REQ_EXT_CH)); -+ -+ prCmdScanReq->ucSeqNum = prScanParam->ucSeqNum; -+ prCmdScanReq->ucNetworkType = (UINT_8) prScanParam->eNetTypeIndex; -+ prCmdScanReq->ucScanType = (UINT_8) prScanParam->eScanType; -+ prCmdScanReq->ucSSIDType = prScanParam->ucSSIDType; -+ -+ if (prScanParam->ucSSIDNum == 1) { -+ COPY_SSID(prCmdScanReq->aucSSID, -+ prCmdScanReq->ucSSIDLength, -+ prScanParam->aucSpecifiedSSID[0], prScanParam->ucSpecifiedSSIDLen[0]); -+ } -+ -+ prCmdScanReq->ucChannelType = (UINT_8) prScanParam->eScanChannel; -+ -+ if (prScanParam->eScanChannel == SCAN_CHANNEL_SPECIFIED) { -+ /* P2P would use: -+ * 1. Specified Listen Channel of passive scan for LISTEN state. -+ * 2. Specified Listen Channel of Target Device of active scan for SEARCH state. (Target != NULL) -+ */ -+ prCmdScanReq->ucChannelListNum = prScanParam->ucChannelListNum; -+ -+ for (i = 0; i < prCmdScanReq->ucChannelListNum; i++) { -+ prCmdScanReq->arChannelList[i].ucBand = (UINT_8) prScanParam->arChnlInfoList[i].eBand; -+ -+ prCmdScanReq->arChannelList[i].ucChannelNum = -+ (UINT_8) prScanParam->arChnlInfoList[i].ucChannelNum; -+ } -+ } -+#if CFG_ENABLE_WIFI_DIRECT -+ if (prScanParam->eNetTypeIndex == NETWORK_TYPE_P2P_INDEX) -+ prCmdScanReq->u2ChannelDwellTime = prScanParam->u2PassiveListenInterval; -+#endif -+ -+ if (prScanParam->u2IELen <= MAX_IE_LENGTH) -+ prCmdScanReq->u2IELen = prScanParam->u2IELen; -+ else -+ prCmdScanReq->u2IELen = MAX_IE_LENGTH; -+ -+ if (prScanParam->u2IELen) -+ kalMemCopy(prCmdScanReq->aucIE, prScanParam->aucIE, sizeof(UINT_8) * prCmdScanReq->u2IELen); -+ -+ wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SCAN_REQ, -+ TRUE, -+ FALSE, -+ FALSE, -+ NULL, -+ NULL, -+ OFFSET_OF(CMD_SCAN_REQ_EXT_CH, aucIE) + prCmdScanReq->u2IELen, -+ (PUINT_8) prCmdScanReq, NULL, 0); -+ /* sanity check for some scan parameters */ -+ if (prCmdScanReq->ucScanType >= SCAN_TYPE_NUM) -+ kalSendAeeWarning("wlan", "wrong scan type %d", prCmdScanReq->ucScanType); -+ else if (prCmdScanReq->ucChannelType >= SCAN_CHANNEL_NUM) -+ kalSendAeeWarning("wlan", "wrong channel type %d", prCmdScanReq->ucChannelType); -+ else if (prCmdScanReq->ucChannelType != SCAN_CHANNEL_SPECIFIED && -+ prCmdScanReq->ucChannelListNum != 0) -+ kalSendAeeWarning("wlan", -+ "channel list is not NULL but channel type is not specified"); -+ else if (prCmdScanReq->ucNetworkType >= NETWORK_TYPE_INDEX_NUM) -+ kalSendAeeWarning("wlan", "wrong network type %d", prCmdScanReq->ucNetworkType); -+ else if (prCmdScanReq->ucSSIDType >= BIT(4)) /* ssid type is wrong */ -+ kalSendAeeWarning("wlan", "wrong ssid type %d", prCmdScanReq->ucSSIDType); -+ else if (prCmdScanReq->ucSSIDLength > 32) -+ kalSendAeeWarning("wlan", "wrong ssid length %d", prCmdScanReq->ucSSIDLength); -+ -+ kalMemFree(prCmdScanReq, VIR_MEM_TYPE, sizeof(CMD_SCAN_REQ_EXT_CH)); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Generate CMD_ID_SCAN_REQ command -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID scnSendScanReq(IN P_ADAPTER_T prAdapter) -+{ -+ P_SCAN_INFO_T prScanInfo; -+ P_SCAN_PARAM_T prScanParam; -+ /*CMD_SCAN_REQ rCmdScanReq;*/ -+ P_CMD_SCAN_REQ prCmdScanReq; -+ UINT_32 i; -+ -+ ASSERT(prAdapter); -+ -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ prScanParam = &prScanInfo->rScanParam; -+ -+ if (prScanParam->ucChannelListNum > 32) { -+ scnSendScanReqExtCh(prAdapter); -+ } else { -+ prCmdScanReq = kalMemAlloc(sizeof(CMD_SCAN_REQ), VIR_MEM_TYPE); -+ if (prCmdScanReq == NULL) { -+ DBGLOG(SCN, INFO, "alloc CmdScanReq fail"); -+ return; -+ } -+ /* send command packet for scan */ -+ kalMemZero(prCmdScanReq, sizeof(CMD_SCAN_REQ)); -+ -+ prCmdScanReq->ucSeqNum = prScanParam->ucSeqNum; -+ prCmdScanReq->ucNetworkType = (UINT_8) prScanParam->eNetTypeIndex; -+ prCmdScanReq->ucScanType = (UINT_8) prScanParam->eScanType; -+ prCmdScanReq->ucSSIDType = prScanParam->ucSSIDType; -+ -+ if (prScanParam->ucSSIDNum == 1) { -+ COPY_SSID(prCmdScanReq->aucSSID, -+ prCmdScanReq->ucSSIDLength, -+ prScanParam->aucSpecifiedSSID[0], prScanParam->ucSpecifiedSSIDLen[0]); -+ } -+ -+ prCmdScanReq->ucChannelType = (UINT_8) prScanParam->eScanChannel; -+ -+ if (prScanParam->eScanChannel == SCAN_CHANNEL_SPECIFIED) { -+ /* P2P would use: -+ * 1. Specified Listen Channel of passive scan for LISTEN state. -+ * 2. Specified Listen Channel of Target Device of active scan for SEARCH state. -+ * (Target != NULL) -+ */ -+ prCmdScanReq->ucChannelListNum = prScanParam->ucChannelListNum; -+ -+ for (i = 0; i < prCmdScanReq->ucChannelListNum; i++) { -+ prCmdScanReq->arChannelList[i].ucBand = (UINT_8) prScanParam->arChnlInfoList[i].eBand; -+ -+ prCmdScanReq->arChannelList[i].ucChannelNum = -+ (UINT_8) prScanParam->arChnlInfoList[i].ucChannelNum; -+ } -+ } -+#if CFG_ENABLE_WIFI_DIRECT -+ if (prScanParam->eNetTypeIndex == NETWORK_TYPE_P2P_INDEX) -+ prCmdScanReq->u2ChannelDwellTime = prScanParam->u2PassiveListenInterval; -+#endif -+#if CFG_ENABLE_FAST_SCAN -+ if (prScanParam->eNetTypeIndex == NETWORK_TYPE_AIS_INDEX) -+ prCmdScanReq->u2ChannelDwellTime = CFG_FAST_SCAN_DWELL_TIME; -+#endif -+ if (prScanParam->u2IELen <= MAX_IE_LENGTH) -+ prCmdScanReq->u2IELen = prScanParam->u2IELen; -+ else -+ prCmdScanReq->u2IELen = MAX_IE_LENGTH; -+ -+ if (prScanParam->u2IELen) -+ kalMemCopy(prCmdScanReq->aucIE, prScanParam->aucIE, sizeof(UINT_8) * prCmdScanReq->u2IELen); -+ -+ wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SCAN_REQ, -+ TRUE, -+ FALSE, -+ FALSE, -+ NULL, -+ NULL, -+ OFFSET_OF(CMD_SCAN_REQ, aucIE) + prCmdScanReq->u2IELen, -+ (PUINT_8) prCmdScanReq, NULL, 0); -+ /* sanity check for some scan parameters */ -+ if (prCmdScanReq->ucScanType >= SCAN_TYPE_NUM) -+ kalSendAeeWarning("wlan", "wrong scan type %d", prCmdScanReq->ucScanType); -+ else if (prCmdScanReq->ucChannelType >= SCAN_CHANNEL_NUM) -+ kalSendAeeWarning("wlan", "wrong channel type %d", prCmdScanReq->ucChannelType); -+ else if (prCmdScanReq->ucChannelType != SCAN_CHANNEL_SPECIFIED && -+ prCmdScanReq->ucChannelListNum != 0) -+ kalSendAeeWarning("wlan", -+ "channel list is not NULL but channel type is not specified"); -+ else if (prCmdScanReq->ucNetworkType >= NETWORK_TYPE_INDEX_NUM) -+ kalSendAeeWarning("wlan", "wrong network type %d", prCmdScanReq->ucNetworkType); -+ else if (prCmdScanReq->ucSSIDType >= BIT(4)) /* ssid type is wrong */ -+ kalSendAeeWarning("wlan", "wrong ssid type %d", prCmdScanReq->ucSSIDType); -+ else if (prCmdScanReq->ucSSIDLength > 32) -+ kalSendAeeWarning("wlan", "wrong ssid length %d", prCmdScanReq->ucSSIDLength); -+ -+ kalMemFree(prCmdScanReq, VIR_MEM_TYPE, sizeof(CMD_SCAN_REQ)); -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Generate CMD_ID_SCAN_REQ_V2 command -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID scnSendScanReqV2ExtCh(IN P_ADAPTER_T prAdapter) -+{ -+ P_SCAN_INFO_T prScanInfo; -+ P_SCAN_PARAM_T prScanParam; -+ /*CMD_SCAN_REQ_V2_EXT_CH rCmdScanReq;*/ -+ P_CMD_SCAN_REQ_V2_EXT_CH prCmdScanReq; -+ UINT_32 i; -+ -+ ASSERT(prAdapter); -+ -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ prScanParam = &prScanInfo->rScanParam; -+ -+ prCmdScanReq = kalMemAlloc(sizeof(CMD_SCAN_REQ_V2_EXT_CH), VIR_MEM_TYPE); -+ if (prCmdScanReq == NULL) -+ return; -+ -+ /* send command packet for scan */ -+ kalMemZero(prCmdScanReq, sizeof(CMD_SCAN_REQ_V2_EXT_CH)); -+ -+ prCmdScanReq->ucSeqNum = prScanParam->ucSeqNum; -+ prCmdScanReq->ucNetworkType = (UINT_8) prScanParam->eNetTypeIndex; -+ prCmdScanReq->ucScanType = (UINT_8) prScanParam->eScanType; -+ prCmdScanReq->ucSSIDType = prScanParam->ucSSIDType; -+ -+ for (i = 0; i < prScanParam->ucSSIDNum; i++) { -+ COPY_SSID(prCmdScanReq->arSSID[i].aucSsid, -+ prCmdScanReq->arSSID[i].u4SsidLen, -+ prScanParam->aucSpecifiedSSID[i], prScanParam->ucSpecifiedSSIDLen[i]); -+ } -+ -+ prCmdScanReq->u2ProbeDelayTime = (UINT_8) prScanParam->u2ProbeDelayTime; -+ prCmdScanReq->ucChannelType = (UINT_8) prScanParam->eScanChannel; -+ -+ if (prScanParam->eScanChannel == SCAN_CHANNEL_SPECIFIED) { -+ /* P2P would use: -+ * 1. Specified Listen Channel of passive scan for LISTEN state. -+ * 2. Specified Listen Channel of Target Device of active scan for SEARCH state. (Target != NULL) -+ */ -+ prCmdScanReq->ucChannelListNum = prScanParam->ucChannelListNum; -+ -+ for (i = 0; i < prCmdScanReq->ucChannelListNum; i++) { -+ prCmdScanReq->arChannelList[i].ucBand = (UINT_8) prScanParam->arChnlInfoList[i].eBand; -+ -+ prCmdScanReq->arChannelList[i].ucChannelNum = -+ (UINT_8) prScanParam->arChnlInfoList[i].ucChannelNum; -+ } -+ } -+#if CFG_ENABLE_WIFI_DIRECT -+ if (prScanParam->eNetTypeIndex == NETWORK_TYPE_P2P_INDEX) -+ prCmdScanReq->u2ChannelDwellTime = prScanParam->u2PassiveListenInterval; -+#endif -+ -+ if (prScanParam->u2IELen <= MAX_IE_LENGTH) -+ prCmdScanReq->u2IELen = prScanParam->u2IELen; -+ else -+ prCmdScanReq->u2IELen = MAX_IE_LENGTH; -+ -+ if (prScanParam->u2IELen) -+ kalMemCopy(prCmdScanReq->aucIE, prScanParam->aucIE, sizeof(UINT_8) * prCmdScanReq->u2IELen); -+ -+ wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SCAN_REQ_V2, -+ TRUE, -+ FALSE, -+ FALSE, -+ NULL, -+ NULL, -+ OFFSET_OF(CMD_SCAN_REQ_V2_EXT_CH, aucIE) + prCmdScanReq->u2IELen, -+ (PUINT_8) prCmdScanReq, NULL, 0); -+ /* sanity check for some scan parameters */ -+ if (prCmdScanReq->ucScanType >= SCAN_TYPE_NUM) -+ kalSendAeeWarning("wlan", "wrong scan type %d", prCmdScanReq->ucScanType); -+ else if (prCmdScanReq->ucChannelType >= SCAN_CHANNEL_NUM) -+ kalSendAeeWarning("wlan", "wrong channel type %d", prCmdScanReq->ucChannelType); -+ else if (prCmdScanReq->ucChannelType != SCAN_CHANNEL_SPECIFIED && -+ prCmdScanReq->ucChannelListNum != 0) -+ kalSendAeeWarning("wlan", -+ "channel list is not NULL but channel type is not specified"); -+ else if (prCmdScanReq->ucNetworkType >= NETWORK_TYPE_INDEX_NUM) -+ kalSendAeeWarning("wlan", "wrong network type %d", prCmdScanReq->ucNetworkType); -+ else if (prCmdScanReq->ucSSIDType >= BIT(4)) /* ssid type is wrong */ -+ kalSendAeeWarning("wlan", "wrong ssid type %d", prCmdScanReq->ucSSIDType); -+ -+ kalMemFree(prCmdScanReq, VIR_MEM_TYPE, sizeof(CMD_SCAN_REQ_V2_EXT_CH)); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Generate CMD_ID_SCAN_REQ_V2 command -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID scnSendScanReqV2(IN P_ADAPTER_T prAdapter) -+{ -+ P_SCAN_INFO_T prScanInfo; -+ P_SCAN_PARAM_T prScanParam; -+ /*CMD_SCAN_REQ_V2 rCmdScanReq;*/ -+ P_CMD_SCAN_REQ_V2 prCmdScanReq; -+ UINT_32 i; -+ -+ ASSERT(prAdapter); -+ -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ prScanParam = &prScanInfo->rScanParam; -+ -+ if (prScanParam->ucChannelListNum > 32) { -+ scnSendScanReqV2ExtCh(prAdapter); -+ } else { -+ prCmdScanReq = kalMemAlloc(sizeof(CMD_SCAN_REQ_V2), VIR_MEM_TYPE); -+ if (prCmdScanReq == NULL) { -+ DBGLOG(SCN, INFO, "alloc CmdScanReq v2 fail"); -+ return; -+ } -+ /* send command packet for scan */ -+ kalMemZero(prCmdScanReq, sizeof(CMD_SCAN_REQ_V2)); -+ -+ prCmdScanReq->ucSeqNum = prScanParam->ucSeqNum; -+ prCmdScanReq->ucNetworkType = (UINT_8) prScanParam->eNetTypeIndex; -+ prCmdScanReq->ucScanType = (UINT_8) prScanParam->eScanType; -+ prCmdScanReq->ucSSIDType = prScanParam->ucSSIDType; -+ -+ for (i = 0; i < prScanParam->ucSSIDNum; i++) { -+ COPY_SSID(prCmdScanReq->arSSID[i].aucSsid, -+ prCmdScanReq->arSSID[i].u4SsidLen, -+ prScanParam->aucSpecifiedSSID[i], prScanParam->ucSpecifiedSSIDLen[i]); -+ } -+ -+ prCmdScanReq->u2ProbeDelayTime = (UINT_8) prScanParam->u2ProbeDelayTime; -+ prCmdScanReq->ucChannelType = (UINT_8) prScanParam->eScanChannel; -+ -+ if (prScanParam->eScanChannel == SCAN_CHANNEL_SPECIFIED) { -+ /* P2P would use: -+ * 1. Specified Listen Channel of passive scan for LISTEN state. -+ * 2. Specified Listen Channel of Target Device of active scan for SEARCH state. -+ * (Target != NULL) -+ */ -+ prCmdScanReq->ucChannelListNum = prScanParam->ucChannelListNum; -+ -+ for (i = 0; i < prCmdScanReq->ucChannelListNum; i++) { -+ prCmdScanReq->arChannelList[i].ucBand = (UINT_8) prScanParam->arChnlInfoList[i].eBand; -+ -+ prCmdScanReq->arChannelList[i].ucChannelNum = -+ (UINT_8) prScanParam->arChnlInfoList[i].ucChannelNum; -+ } -+ } -+#if CFG_ENABLE_WIFI_DIRECT -+ if (prScanParam->eNetTypeIndex == NETWORK_TYPE_P2P_INDEX) -+ prCmdScanReq->u2ChannelDwellTime = prScanParam->u2PassiveListenInterval; -+#endif -+ if (prScanParam->u2IELen <= MAX_IE_LENGTH) -+ prCmdScanReq->u2IELen = prScanParam->u2IELen; -+ else -+ prCmdScanReq->u2IELen = MAX_IE_LENGTH; -+ -+ if (prScanParam->u2IELen) -+ kalMemCopy(prCmdScanReq->aucIE, prScanParam->aucIE, sizeof(UINT_8) * prCmdScanReq->u2IELen); -+ -+ wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SCAN_REQ_V2, -+ TRUE, -+ FALSE, -+ FALSE, -+ NULL, -+ NULL, -+ OFFSET_OF(CMD_SCAN_REQ_V2, aucIE) + prCmdScanReq->u2IELen, -+ (PUINT_8) prCmdScanReq, NULL, 0); -+ /* sanity check for some scan parameters */ -+ if (prCmdScanReq->ucScanType >= SCAN_TYPE_NUM) -+ kalSendAeeWarning("wlan", "wrong scan type %d", prCmdScanReq->ucScanType); -+ else if (prCmdScanReq->ucChannelType >= SCAN_CHANNEL_NUM) -+ kalSendAeeWarning("wlan", "wrong channel type %d", prCmdScanReq->ucChannelType); -+ else if (prCmdScanReq->ucChannelType != SCAN_CHANNEL_SPECIFIED && -+ prCmdScanReq->ucChannelListNum != 0) -+ kalSendAeeWarning("wlan", -+ "channel list is not NULL but channel type is not specified"); -+ else if (prCmdScanReq->ucNetworkType >= NETWORK_TYPE_INDEX_NUM) -+ kalSendAeeWarning("wlan", "wrong network type %d", prCmdScanReq->ucNetworkType); -+ else if (prCmdScanReq->ucSSIDType >= BIT(4)) /* ssid type is wrong */ -+ kalSendAeeWarning("wlan", "wrong ssid type %d", prCmdScanReq->ucSSIDType); -+ -+ kalMemFree(prCmdScanReq, VIR_MEM_TYPE, sizeof(CMD_SCAN_REQ_V2)); -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID scnFsmMsgStart(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) -+{ -+ P_SCAN_INFO_T prScanInfo; -+ P_SCAN_PARAM_T prScanParam; -+ -+ ASSERT(prMsgHdr); -+ -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ prScanParam = &prScanInfo->rScanParam; -+ -+ if (prScanInfo->eCurrentState == SCAN_STATE_IDLE) { -+ if (prMsgHdr->eMsgId == MID_AIS_SCN_SCAN_REQ -+ || prMsgHdr->eMsgId == MID_BOW_SCN_SCAN_REQ -+ || prMsgHdr->eMsgId == MID_P2P_SCN_SCAN_REQ || prMsgHdr->eMsgId == MID_RLM_SCN_SCAN_REQ) { -+ scnFsmHandleScanMsg(prAdapter, (P_MSG_SCN_SCAN_REQ) prMsgHdr); -+ } else if (prMsgHdr->eMsgId == MID_AIS_SCN_SCAN_REQ_V2 -+ || prMsgHdr->eMsgId == MID_BOW_SCN_SCAN_REQ_V2 -+ || prMsgHdr->eMsgId == MID_P2P_SCN_SCAN_REQ_V2 -+ || prMsgHdr->eMsgId == MID_RLM_SCN_SCAN_REQ_V2) { -+ scnFsmHandleScanMsgV2(prAdapter, (P_MSG_SCN_SCAN_REQ_V2) prMsgHdr); -+ } else { -+ /* should not deliver to this function */ -+ ASSERT(0); -+ } -+ -+ cnmMemFree(prAdapter, prMsgHdr); -+ scnFsmSteps(prAdapter, SCAN_STATE_SCANNING); -+ } else { -+ LINK_INSERT_TAIL(&prScanInfo->rPendingMsgList, &prMsgHdr->rLinkEntry); -+ } -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID scnFsmMsgAbort(IN P_ADAPTER_T prAdapter, IN P_MSG_HDR_T prMsgHdr) -+{ -+ P_MSG_SCN_SCAN_CANCEL prScanCancel; -+ P_SCAN_INFO_T prScanInfo; -+ P_SCAN_PARAM_T prScanParam; -+ CMD_SCAN_CANCEL rCmdScanCancel; -+ -+ ASSERT(prMsgHdr); -+ -+ prScanCancel = (P_MSG_SCN_SCAN_CANCEL) prMsgHdr; -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ prScanParam = &prScanInfo->rScanParam; -+ -+ if (prScanInfo->eCurrentState != SCAN_STATE_IDLE) { -+ if (prScanCancel->ucSeqNum == prScanParam->ucSeqNum && -+ prScanCancel->ucNetTypeIndex == (UINT_8) prScanParam->eNetTypeIndex) { -+ /* send cancel message to firmware domain */ -+ rCmdScanCancel.ucSeqNum = prScanParam->ucSeqNum; -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ if (prScanParam->eNetTypeIndex == NETWORK_TYPE_P2P_INDEX) -+ rCmdScanCancel.ucIsExtChannel = (UINT_8) prScanCancel->fgIsChannelExt; -+ else -+ rCmdScanCancel.ucIsExtChannel = (UINT_8) FALSE; -+#endif -+ -+ wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SCAN_CANCEL, -+ TRUE, -+ FALSE, -+ FALSE, -+ NULL, NULL, sizeof(CMD_SCAN_CANCEL), (PUINT_8) &rCmdScanCancel, NULL, 0); -+ -+ /* generate scan-done event for caller */ -+ scnFsmGenerateScanDoneMsg(prAdapter, -+ prScanParam->ucSeqNum, -+ (UINT_8) prScanParam->eNetTypeIndex, SCAN_STATUS_CANCELLED); -+ -+ /* switch to next pending scan */ -+ scnFsmSteps(prAdapter, SCAN_STATE_IDLE); -+ } else { -+ scnFsmRemovePendingMsg(prAdapter, prScanCancel->ucSeqNum, prScanCancel->ucNetTypeIndex); -+ } -+ } -+ -+ cnmMemFree(prAdapter, prMsgHdr); -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Scan Message Parsing (Legacy) -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID scnFsmHandleScanMsg(IN P_ADAPTER_T prAdapter, IN P_MSG_SCN_SCAN_REQ prScanReqMsg) -+{ -+ P_SCAN_INFO_T prScanInfo; -+ P_SCAN_PARAM_T prScanParam; -+ UINT_32 i; -+ -+ ASSERT(prAdapter); -+ ASSERT(prScanReqMsg); -+ -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ prScanParam = &prScanInfo->rScanParam; -+ -+ prScanParam->eScanType = prScanReqMsg->eScanType; -+ prScanParam->eNetTypeIndex = (ENUM_NETWORK_TYPE_INDEX_T) prScanReqMsg->ucNetTypeIndex; -+ prScanParam->ucSSIDType = prScanReqMsg->ucSSIDType; -+ if (prScanParam->ucSSIDType & (SCAN_REQ_SSID_SPECIFIED | SCAN_REQ_SSID_P2P_WILDCARD)) { -+ prScanParam->ucSSIDNum = 1; -+ -+ COPY_SSID(prScanParam->aucSpecifiedSSID[0], -+ prScanParam->ucSpecifiedSSIDLen[0], prScanReqMsg->aucSSID, prScanReqMsg->ucSSIDLength); -+ -+ /* reset SSID length to zero for rest array entries */ -+ for (i = 1; i < SCN_SSID_MAX_NUM; i++) -+ prScanParam->ucSpecifiedSSIDLen[i] = 0; -+ } else { -+ prScanParam->ucSSIDNum = 0; -+ -+ for (i = 0; i < SCN_SSID_MAX_NUM; i++) -+ prScanParam->ucSpecifiedSSIDLen[i] = 0; -+ } -+ -+ prScanParam->u2ProbeDelayTime = 0; -+ prScanParam->eScanChannel = prScanReqMsg->eScanChannel; -+ if (prScanParam->eScanChannel == SCAN_CHANNEL_SPECIFIED) { -+ if (prScanReqMsg->ucChannelListNum <= MAXIMUM_OPERATION_CHANNEL_LIST) -+ prScanParam->ucChannelListNum = prScanReqMsg->ucChannelListNum; -+ else -+ prScanParam->ucChannelListNum = MAXIMUM_OPERATION_CHANNEL_LIST; -+ -+ kalMemCopy(prScanParam->arChnlInfoList, -+ prScanReqMsg->arChnlInfoList, sizeof(RF_CHANNEL_INFO_T) * prScanParam->ucChannelListNum); -+ } -+ -+ if (prScanReqMsg->u2IELen <= MAX_IE_LENGTH) -+ prScanParam->u2IELen = prScanReqMsg->u2IELen; -+ else -+ prScanParam->u2IELen = MAX_IE_LENGTH; -+ -+ if (prScanParam->u2IELen) -+ kalMemCopy(prScanParam->aucIE, prScanReqMsg->aucIE, prScanParam->u2IELen); -+#if CFG_ENABLE_WIFI_DIRECT -+ if (prScanParam->eNetTypeIndex == NETWORK_TYPE_P2P_INDEX) -+ prScanParam->u2PassiveListenInterval = prScanReqMsg->u2ChannelDwellTime; -+#endif -+ prScanParam->ucSeqNum = prScanReqMsg->ucSeqNum; -+ -+ if (prScanReqMsg->rMsgHdr.eMsgId == MID_RLM_SCN_SCAN_REQ) -+ prScanParam->fgIsObssScan = TRUE; -+ else -+ prScanParam->fgIsObssScan = FALSE; -+ -+ prScanParam->fgIsScanV2 = FALSE; -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Scan Message Parsing - V2 with multiple SSID support -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID scnFsmHandleScanMsgV2(IN P_ADAPTER_T prAdapter, IN P_MSG_SCN_SCAN_REQ_V2 prScanReqMsg) -+{ -+ P_SCAN_INFO_T prScanInfo; -+ P_SCAN_PARAM_T prScanParam; -+ UINT_32 i; -+ -+ ASSERT(prAdapter); -+ ASSERT(prScanReqMsg); -+ ASSERT(prScanReqMsg->ucSSIDNum <= SCN_SSID_MAX_NUM); -+ -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ prScanParam = &prScanInfo->rScanParam; -+ -+ prScanParam->eScanType = prScanReqMsg->eScanType; -+ prScanParam->eNetTypeIndex = (ENUM_NETWORK_TYPE_INDEX_T) prScanReqMsg->ucNetTypeIndex; -+ prScanParam->ucSSIDType = prScanReqMsg->ucSSIDType; -+ prScanParam->ucSSIDNum = prScanReqMsg->ucSSIDNum; -+ -+ for (i = 0; i < prScanReqMsg->ucSSIDNum; i++) { -+ COPY_SSID(prScanParam->aucSpecifiedSSID[i], -+ prScanParam->ucSpecifiedSSIDLen[i], -+ prScanReqMsg->prSsid[i].aucSsid, (UINT_8) prScanReqMsg->prSsid[i].u4SsidLen); -+ } -+ -+ prScanParam->u2ProbeDelayTime = prScanReqMsg->u2ProbeDelay; -+ prScanParam->eScanChannel = prScanReqMsg->eScanChannel; -+ if (prScanParam->eScanChannel == SCAN_CHANNEL_SPECIFIED) { -+ if (prScanReqMsg->ucChannelListNum <= MAXIMUM_OPERATION_CHANNEL_LIST) -+ prScanParam->ucChannelListNum = prScanReqMsg->ucChannelListNum; -+ else -+ prScanParam->ucChannelListNum = MAXIMUM_OPERATION_CHANNEL_LIST; -+ -+ kalMemCopy(prScanParam->arChnlInfoList, -+ prScanReqMsg->arChnlInfoList, sizeof(RF_CHANNEL_INFO_T) * prScanParam->ucChannelListNum); -+ } -+ -+ if (prScanReqMsg->u2IELen <= MAX_IE_LENGTH) -+ prScanParam->u2IELen = prScanReqMsg->u2IELen; -+ else -+ prScanParam->u2IELen = MAX_IE_LENGTH; -+ -+ if (prScanParam->u2IELen) -+ kalMemCopy(prScanParam->aucIE, prScanReqMsg->aucIE, prScanParam->u2IELen); -+#if CFG_ENABLE_WIFI_DIRECT -+ if (prScanParam->eNetTypeIndex == NETWORK_TYPE_P2P_INDEX) -+ prScanParam->u2PassiveListenInterval = prScanReqMsg->u2ChannelDwellTime; -+#endif -+ prScanParam->ucSeqNum = prScanReqMsg->ucSeqNum; -+ -+ if (prScanReqMsg->rMsgHdr.eMsgId == MID_RLM_SCN_SCAN_REQ) -+ prScanParam->fgIsObssScan = TRUE; -+ else -+ prScanParam->fgIsObssScan = FALSE; -+ -+ prScanParam->fgIsScanV2 = TRUE; -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Remove pending scan request -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID scnFsmRemovePendingMsg(IN P_ADAPTER_T prAdapter, IN UINT_8 ucSeqNum, IN UINT_8 ucNetTypeIndex) -+{ -+ P_SCAN_INFO_T prScanInfo; -+ P_SCAN_PARAM_T prScanParam; -+ P_MSG_HDR_T prPendingMsgHdr, prPendingMsgHdrNext, prRemoveMsgHdr = NULL; -+ P_LINK_ENTRY_T prRemoveLinkEntry = NULL; -+ -+ ASSERT(prAdapter); -+ -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ prScanParam = &prScanInfo->rScanParam; -+ -+ /* traverse through rPendingMsgList for removal */ -+ LINK_FOR_EACH_ENTRY_SAFE(prPendingMsgHdr, -+ prPendingMsgHdrNext, &(prScanInfo->rPendingMsgList), rLinkEntry, MSG_HDR_T) { -+ if (prPendingMsgHdr->eMsgId == MID_AIS_SCN_SCAN_REQ -+ || prPendingMsgHdr->eMsgId == MID_BOW_SCN_SCAN_REQ -+ || prPendingMsgHdr->eMsgId == MID_P2P_SCN_SCAN_REQ -+ || prPendingMsgHdr->eMsgId == MID_RLM_SCN_SCAN_REQ) { -+ P_MSG_SCN_SCAN_REQ prScanReqMsg = (P_MSG_SCN_SCAN_REQ) prPendingMsgHdr; -+ -+ if (ucSeqNum == prScanReqMsg->ucSeqNum && ucNetTypeIndex == prScanReqMsg->ucNetTypeIndex) { -+ prRemoveLinkEntry = &(prScanReqMsg->rMsgHdr.rLinkEntry); -+ prRemoveMsgHdr = prPendingMsgHdr; -+ } -+ } else if (prPendingMsgHdr->eMsgId == MID_AIS_SCN_SCAN_REQ_V2 -+ || prPendingMsgHdr->eMsgId == MID_BOW_SCN_SCAN_REQ_V2 -+ || prPendingMsgHdr->eMsgId == MID_P2P_SCN_SCAN_REQ_V2 -+ || prPendingMsgHdr->eMsgId == MID_RLM_SCN_SCAN_REQ_V2) { -+ P_MSG_SCN_SCAN_REQ_V2 prScanReqMsgV2 = (P_MSG_SCN_SCAN_REQ_V2) prPendingMsgHdr; -+ -+ if (ucSeqNum == prScanReqMsgV2->ucSeqNum && ucNetTypeIndex == prScanReqMsgV2->ucNetTypeIndex) { -+ prRemoveLinkEntry = &(prScanReqMsgV2->rMsgHdr.rLinkEntry); -+ prRemoveMsgHdr = prPendingMsgHdr; -+ } -+ } -+ -+ if (prRemoveLinkEntry) { -+ /* generate scan-done event for caller */ -+ scnFsmGenerateScanDoneMsg(prAdapter, ucSeqNum, ucNetTypeIndex, SCAN_STATUS_CANCELLED); -+ -+ /* remove from pending list */ -+ LINK_REMOVE_KNOWN_ENTRY(&(prScanInfo->rPendingMsgList), prRemoveLinkEntry); -+ cnmMemFree(prAdapter, prRemoveMsgHdr); -+ -+ break; -+ } -+ } -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID scnEventScanDone(IN P_ADAPTER_T prAdapter, IN P_EVENT_SCAN_DONE prScanDone) -+{ -+ P_SCAN_INFO_T prScanInfo; -+ P_SCAN_PARAM_T prScanParam; -+ -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ prScanParam = &prScanInfo->rScanParam; -+ -+ /* buffer empty channel information */ -+ if (prScanParam->eScanChannel == SCAN_CHANNEL_FULL || prScanParam->eScanChannel == SCAN_CHANNEL_2G4) { -+ if (prScanDone->ucSparseChannelValid) { -+ prScanInfo->fgIsSparseChannelValid = TRUE; -+ prScanInfo->rSparseChannel.eBand = (ENUM_BAND_T) prScanDone->rSparseChannel.ucBand; -+ prScanInfo->rSparseChannel.ucChannelNum = prScanDone->rSparseChannel.ucChannelNum; -+ } else { -+ prScanInfo->fgIsSparseChannelValid = FALSE; -+ } -+ } -+ -+ if (prScanInfo->eCurrentState == SCAN_STATE_SCANNING && prScanDone->ucSeqNum == prScanParam->ucSeqNum) { -+ /* generate scan-done event for caller */ -+ scnFsmGenerateScanDoneMsg(prAdapter, -+ prScanParam->ucSeqNum, (UINT_8) prScanParam->eNetTypeIndex, SCAN_STATUS_DONE); -+ -+ /* switch to next pending scan */ -+ scnFsmSteps(prAdapter, SCAN_STATE_IDLE); -+ } else { -+ DBGLOG(SCN, WARN, "Unexpected SCAN-DONE event: SeqNum = %d, Current State = %d\n", -+ prScanDone->ucSeqNum, prScanInfo->eCurrentState); -+ } -+ -+} /* end of scnEventScanDone */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+scnFsmGenerateScanDoneMsg(IN P_ADAPTER_T prAdapter, -+ IN UINT_8 ucSeqNum, IN UINT_8 ucNetTypeIndex, IN ENUM_SCAN_STATUS eScanStatus) -+{ -+ P_SCAN_INFO_T prScanInfo; -+ P_SCAN_PARAM_T prScanParam; -+ P_MSG_SCN_SCAN_DONE prScanDoneMsg; -+ -+ ASSERT(prAdapter); -+ -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ prScanParam = &prScanInfo->rScanParam; -+ -+ DBGLOG(SCN, INFO, "Rcv Scan Done, NetIdx %d, Obss %d, Status %d, Seq %d\n", -+ ucNetTypeIndex, prScanParam->fgIsObssScan, eScanStatus, ucSeqNum); -+ prScanDoneMsg = (P_MSG_SCN_SCAN_DONE) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_SCN_SCAN_DONE)); -+ if (!prScanDoneMsg) { -+ ASSERT(0); /* Can't indicate SCAN FSM Complete */ -+ return; -+ } -+ -+ if (prScanParam->fgIsObssScan == TRUE) { -+ prScanDoneMsg->rMsgHdr.eMsgId = MID_SCN_RLM_SCAN_DONE; -+ } else { -+ switch ((ENUM_NETWORK_TYPE_INDEX_T) ucNetTypeIndex) { -+ case NETWORK_TYPE_AIS_INDEX: -+ prScanDoneMsg->rMsgHdr.eMsgId = MID_SCN_AIS_SCAN_DONE; -+ break; -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ case NETWORK_TYPE_P2P_INDEX: -+ prScanDoneMsg->rMsgHdr.eMsgId = MID_SCN_P2P_SCAN_DONE; -+ break; -+#endif -+ -+#if CFG_ENABLE_BT_OVER_WIFI -+ case NETWORK_TYPE_BOW_INDEX: -+ prScanDoneMsg->rMsgHdr.eMsgId = MID_SCN_BOW_SCAN_DONE; -+ break; -+#endif -+ -+ default: -+ ASSERT(0); -+ break; -+ } -+ } -+ -+ prScanDoneMsg->ucSeqNum = ucSeqNum; -+ prScanDoneMsg->ucNetTypeIndex = ucNetTypeIndex; -+ prScanDoneMsg->eScanStatus = eScanStatus; -+ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prScanDoneMsg, MSG_SEND_METHOD_BUF); -+ -+} /* end of scnFsmGenerateScanDoneMsg() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Query for most sparse channel -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN scnQuerySparseChannel(IN P_ADAPTER_T prAdapter, P_ENUM_BAND_T prSparseBand, PUINT_8 pucSparseChannel) -+{ -+ P_SCAN_INFO_T prScanInfo; -+ -+ ASSERT(prAdapter); -+ -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ -+ if (prScanInfo->fgIsSparseChannelValid == TRUE) { -+ if (prSparseBand) -+ *prSparseBand = prScanInfo->rSparseChannel.eBand; -+ -+ if (pucSparseChannel) -+ *pucSparseChannel = prScanInfo->rSparseChannel.ucChannelNum; -+ -+ return TRUE; -+ } else { -+ return FALSE; -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Event handler for NLO done event -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID scnEventNloDone(IN P_ADAPTER_T prAdapter, IN P_EVENT_NLO_DONE_T prNloDone) -+{ -+ P_SCAN_INFO_T prScanInfo; -+ P_NLO_PARAM_T prNloParam; -+ P_SCAN_PARAM_T prScanParam; -+ -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ prNloParam = &prScanInfo->rNloParam; -+ prScanParam = &prNloParam->rScanParam; -+ -+ if (prScanInfo->fgNloScanning == TRUE) { -+ DBGLOG(SCN, INFO, "scnEventNloDone Current State = %d\n", prScanInfo->eCurrentState); -+ -+ kalSchedScanResults(prAdapter->prGlueInfo); -+ -+ if (prNloParam->fgStopAfterIndication == TRUE) -+ prScanInfo->fgNloScanning = FALSE; -+ -+ kalMemZero(&prNloParam->aprPendingBssDescToInd[0], -+ CFG_SCAN_SSID_MATCH_MAX_NUM * sizeof(P_BSS_DESC_T)); -+ } else { -+ DBGLOG(SCN, INFO, "Unexpected NLO-DONE event\n"); -+ } -+ -+} -+ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief handler for starting scheduled scan -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN -+scnFsmSchedScanRequest(IN P_ADAPTER_T prAdapter, -+ IN UINT_8 ucSsidNum, -+ IN P_PARAM_SSID_T prSsid, IN UINT_32 u4IeLength, IN PUINT_8 pucIe, IN UINT_16 u2Interval) -+{ -+ P_SCAN_INFO_T prScanInfo; -+ P_NLO_PARAM_T prNloParam; -+ P_SCAN_PARAM_T prScanParam; -+ P_CMD_NLO_REQ prCmdNloReq; -+ UINT_32 i, j; -+ -+ ASSERT(prAdapter); -+ -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ prNloParam = &prScanInfo->rNloParam; -+ prScanParam = &prNloParam->rScanParam; -+ -+ if (prScanInfo->fgNloScanning) { -+ DBGLOG(SCN, INFO, "prScanInfo->fgNloScanning == TRUE already scanning\n"); -+ return TRUE; -+ } -+ -+ prScanInfo->fgNloScanning = TRUE; -+ -+ /* 1. load parameters */ -+ prScanParam->ucSeqNum++; -+ /* prScanParam->ucBssIndex = prAdapter->prAisBssInfo->ucBssIndex; */ -+ -+ prNloParam->fgStopAfterIndication = TRUE; -+ prNloParam->ucFastScanIteration = 0; -+ prNloParam->u2FastScanPeriod = u2Interval; -+ prNloParam->u2SlowScanPeriod = u2Interval; -+ -+ if (prScanParam->ucSSIDNum > CFG_SCAN_SSID_MAX_NUM) -+ prScanParam->ucSSIDNum = CFG_SCAN_SSID_MAX_NUM; -+ else -+ prScanParam->ucSSIDNum = ucSsidNum; -+ -+ if (prNloParam->ucMatchSSIDNum > CFG_SCAN_SSID_MATCH_MAX_NUM) -+ prNloParam->ucMatchSSIDNum = CFG_SCAN_SSID_MATCH_MAX_NUM; -+ else -+ prNloParam->ucMatchSSIDNum = ucSsidNum; -+ -+ for (i = 0; i < prNloParam->ucMatchSSIDNum; i++) { -+ if (i < CFG_SCAN_SSID_MAX_NUM) { -+ COPY_SSID(prScanParam->aucSpecifiedSSID[i], -+ prScanParam->ucSpecifiedSSIDLen[i], prSsid[i].aucSsid, (UINT_8) prSsid[i].u4SsidLen); -+ } -+ -+ COPY_SSID(prNloParam->aucMatchSSID[i], -+ prNloParam->ucMatchSSIDLen[i], prSsid[i].aucSsid, (UINT_8) prSsid[i].u4SsidLen); -+ -+ prNloParam->aucCipherAlgo[i] = 0; -+ prNloParam->au2AuthAlgo[i] = 0; -+ -+ for (j = 0; j < SCN_NLO_NETWORK_CHANNEL_NUM; j++) -+ prNloParam->aucChannelHint[i][j] = 0; -+ } -+ -+ /* 2. prepare command for sending */ -+ prCmdNloReq = (P_CMD_NLO_REQ) cnmMemAlloc(prAdapter, RAM_TYPE_BUF, sizeof(CMD_NLO_REQ) + prScanParam->u2IELen); -+ -+ if (!prCmdNloReq) { -+ ASSERT(0); /* Can't initiate NLO operation */ -+ return FALSE; -+ } -+ -+ /* 3. send command packet for NLO operation */ -+ kalMemZero(prCmdNloReq, sizeof(CMD_NLO_REQ)); -+ -+ prCmdNloReq->ucSeqNum = prScanParam->ucSeqNum; -+ /* prCmdNloReq->ucBssIndex = prScanParam->ucBssIndex; */ -+ -+ prCmdNloReq->ucNetworkType = prScanParam->eNetTypeIndex; -+ prCmdNloReq->ucScanType = (UINT_8) prScanParam->eScanType; -+ -+ prCmdNloReq->fgStopAfterIndication = prNloParam->fgStopAfterIndication; -+ prCmdNloReq->ucFastScanIteration = prNloParam->ucFastScanIteration; -+ prCmdNloReq->u2FastScanPeriod = prNloParam->u2FastScanPeriod; -+ prCmdNloReq->u2SlowScanPeriod = prNloParam->u2SlowScanPeriod; -+ prCmdNloReq->ucEntryNum = prNloParam->ucMatchSSIDNum; -+ for (i = 0; i < prNloParam->ucMatchSSIDNum; i++) { -+ COPY_SSID(prCmdNloReq->arNetworkList[i].aucSSID, -+ prCmdNloReq->arNetworkList[i].ucSSIDLength, -+ prNloParam->aucMatchSSID[i], prNloParam->ucMatchSSIDLen[i]); -+ -+ prCmdNloReq->arNetworkList[i].ucCipherAlgo = prNloParam->aucCipherAlgo[i]; -+ prCmdNloReq->arNetworkList[i].u2AuthAlgo = prNloParam->au2AuthAlgo[i]; -+ -+ for (j = 0; j < SCN_NLO_NETWORK_CHANNEL_NUM; j++) -+ prCmdNloReq->arNetworkList[i].ucNumChannelHint[j] = prNloParam->aucChannelHint[i][j]; -+ } -+ -+ if (prScanParam->u2IELen <= MAX_IE_LENGTH) -+ prCmdNloReq->u2IELen = prScanParam->u2IELen; -+ else -+ prCmdNloReq->u2IELen = MAX_IE_LENGTH; -+ -+ if (prScanParam->u2IELen) -+ kalMemCopy(prCmdNloReq->aucIE, prScanParam->aucIE, sizeof(UINT_8) * prCmdNloReq->u2IELen); -+#if !CFG_SUPPORT_GSCN -+ -+ wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SET_NLO_REQ, -+ TRUE, -+ FALSE, -+ TRUE, -+ nicCmdEventSetCommon, -+ nicOidCmdTimeoutCommon, -+ sizeof(CMD_NLO_REQ) + prCmdNloReq->u2IELen, (PUINT_8) prCmdNloReq, NULL, 0); -+ -+#else -+ scnPSCNFsm(prAdapter, PSCN_RESET, prCmdNloReq, NULL, NULL, NULL, FALSE, FALSE, FALSE, FALSE); -+#endif -+ cnmMemFree(prAdapter, (PVOID) prCmdNloReq); -+ -+ return TRUE; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief handler for stopping scheduled scan -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN scnFsmSchedScanStopRequest(IN P_ADAPTER_T prAdapter) -+{ -+ P_SCAN_INFO_T prScanInfo; -+ P_NLO_PARAM_T prNloParam; -+ P_SCAN_PARAM_T prScanParam; -+ CMD_NLO_CANCEL rCmdNloCancel; -+ -+ ASSERT(prAdapter); -+ -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ prNloParam = &prScanInfo->rNloParam; -+ prScanParam = &prNloParam->rScanParam; -+ -+ /* send cancel message to firmware domain */ -+ rCmdNloCancel.ucSeqNum = prScanParam->ucSeqNum; -+ -+#if !CFG_SUPPORT_GSCN -+ -+ wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SET_NLO_CANCEL, -+ TRUE, -+ FALSE, -+ TRUE, -+ nicCmdEventSetStopSchedScan, -+ nicOidCmdTimeoutCommon, sizeof(CMD_NLO_CANCEL), (PUINT_8)(&rCmdNloCancel), NULL, 0); -+#else -+ -+ scnPSCNFsm(prAdapter, PSCN_RESET, NULL, NULL, NULL, NULL, TRUE, FALSE, FALSE, FALSE); -+#endif -+ -+ prScanInfo->fgNloScanning = FALSE; -+ -+ return TRUE; -+} -+ -+#if CFG_SUPPORT_GSCN -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief handler for Set PSCN action -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN scnFsmPSCNAction(IN P_ADAPTER_T prAdapter, IN UINT_8 ucPscanAct) -+{ -+ CMD_SET_PSCAN_ENABLE rCmdPscnAction; -+ P_SCAN_INFO_T prScanInfo; -+ -+ DBGLOG(SCN, TRACE, "scnFsmPSCNAction Act = %d\n", ucPscanAct); -+ -+ rCmdPscnAction.ucPscanAct = ucPscanAct; -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ -+ if (ucPscanAct == DISABLE) -+ prScanInfo->fgPscnOnnning = FALSE; -+ if (ucPscanAct == ENABLE) -+ prScanInfo->fgPscnOnnning = TRUE; -+ -+ wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SET_PSCN_ENABLE, -+ TRUE, -+ FALSE, -+ FALSE, NULL, NULL, sizeof(CMD_SET_PSCAN_ENABLE), (PUINT_8) &rCmdPscnAction, NULL, 0); -+ -+ DBGLOG(SCN, INFO, "scnFsmPSCNAction Act = %d is Set to FW\n", ucPscanAct); -+ return TRUE; -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief handler for Set PSCN param -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN scnFsmPSCNSetParam(IN P_ADAPTER_T prAdapter, IN P_CMD_SET_PSCAN_PARAM prCmdPscnParam) -+{ -+ UINT_8 i, j; -+ -+ i = 0; -+ j = 0; -+ -+ ASSERT(prAdapter); -+ /*prCmdPscnParam->u4BasePeriod = prCmdPscnParam->u4BasePeriod;*/ -+#if 0 -+ DBGLOG(SCN, TRACE, -+ "rCmdPscnParam: Period[%u],NumCache[%u],Threshold[%u],NumBkts[%u],fgGSCN[%d] fgNLO[%d] fgBatch[%d]\n", -+ prCmdPscnParam->rCmdGscnReq.u4BasePeriod, prCmdPscnParam->rCmdGscnReq.ucNumScnToCache, -+ prCmdPscnParam->rCmdGscnReq.u4BufferThreshold, prCmdPscnParam->rCmdGscnReq.u4NumBuckets, -+ prCmdPscnParam->fgGScnEnable, prCmdPscnParam->fgNLOScnEnable, prCmdPscnParam->fgBatchScnEnable)); -+ -+ for (i = 0; i < prCmdPscnParam->rCmdGscnReq.u4NumBuckets; i++) { -+ DBGLOG(SCN, TRACE, "rCmdPscnParam.rCmdGscnParam.arChannelBucket[%d] has channel: ", i); -+ DBGLOG(SCN, TRACE, -+ "band[%u], Index[%u] NumChannels[%u], ucBktFreqMultiple[%u] Flag[%u]\n", -+ prCmdPscnParam->rCmdGscnReq.arChannelBucket[i].eBand, -+ prCmdPscnParam->rCmdGscnReq.arChannelBucket[i].u2BucketIndex, -+ prCmdPscnParam->rCmdGscnReq.arChannelBucket[i].ucNumChannels, -+ prCmdPscnParam->rCmdGscnReq.arChannelBucket[i].ucBucketFreqMultiple, -+ prCmdPscnParam->rCmdGscnReq.arChannelBucket[i].ucReportFlag)); -+ for (j = 0; j < prCmdPscnParam->rCmdGscnReq.arChannelBucket[i].ucNumChannels; j++) -+ DBGLOG(SCN, TRACE, -+ " %d, ", prCmdPscnParam->rCmdGscnReq.arChannelBucket[i].arChannelList[j].ucChannel); -+ DBGLOG(SCN, TRACE, "\n"); -+ } -+#endif -+ -+ if (1 /*prScanInfo->fgPscnOnnning == FALSE */) { -+ wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SET_PSCAN_PARAM, -+ TRUE, -+ FALSE, -+ FALSE, NULL, NULL, sizeof(CMD_SET_PSCAN_PARAM), (PUINT_8) prCmdPscnParam, NULL, 0); -+ -+ DBGLOG(SCN, TRACE, "CMD_ID_SET_PSCAN_PARAM is set to FW !!!!!!!!!!\n"); -+ return TRUE; -+ } -+ return FALSE; -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief handler for Set hotlist -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN scnFsmPSCNSetHotlist(IN P_ADAPTER_T prAdapter, IN P_CMD_SET_PSCAN_ADD_HOTLIST_BSSID prCmdPscnAddHotlist) -+{ -+ CMD_SET_PSCAN_ADD_HOTLIST_BSSID rCmdPscnAddHotlist; -+ P_SCAN_INFO_T prScanInfo; -+ -+ ASSERT(prAdapter); -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ memcpy(&rCmdPscnAddHotlist.aucMacAddr, &(prCmdPscnAddHotlist->aucMacAddr), sizeof(MAC_ADDR_LEN)); -+ -+ /* rCmdPscnAddHotlist.aucMacAddr = prCmdPscnAddHotlist->aucMacAddr; */ -+ rCmdPscnAddHotlist.ucFlags = prCmdPscnAddHotlist->ucFlags; -+ -+ if (prScanInfo->fgPscnOnnning && prScanInfo->prPscnParam->fgGScnEnable) { -+ wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SET_PSCN_ADD_HOTLIST_BSSID, -+ TRUE, -+ FALSE, -+ FALSE, -+ NULL, -+ NULL, -+ sizeof(CMD_SET_PSCAN_ADD_HOTLIST_BSSID), (PUINT_8) &rCmdPscnAddHotlist, NULL, 0); -+ return TRUE; -+ } -+ /* debug msg, No PSCN, Sched SCAN no need to add the hotlist ??? */ -+ return FALSE; -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief handler for Set CMD_ID_SET_PSCN_ADD_SW_BSSID -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN scnFsmPSCNAddSWCBssId(IN P_ADAPTER_T prAdapter, IN P_CMD_SET_PSCAN_ADD_SWC_BSSID prCmdPscnAddSWCBssId) -+{ -+ CMD_SET_PSCAN_ADD_SWC_BSSID rCmdPscnAddSWCBssId; -+ P_SCAN_INFO_T prScanInfo; -+ -+ ASSERT(prAdapter); -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ -+ memcpy(&rCmdPscnAddSWCBssId.aucMacAddr, &(prCmdPscnAddSWCBssId->aucMacAddr), sizeof(MAC_ADDR_LEN)); -+ -+ /* rCmdPscnAddSWCBssId.aucMacAddr = prCmdPscnAddSWCBssId->aucMacAddr; */ -+ rCmdPscnAddSWCBssId.i4RssiHighThreshold = prCmdPscnAddSWCBssId->i4RssiHighThreshold; -+ rCmdPscnAddSWCBssId.i4RssiLowThreshold = prCmdPscnAddSWCBssId->i4RssiLowThreshold; -+ -+ if (prScanInfo->fgPscnOnnning && prScanInfo->prPscnParam->fgGScnEnable) { -+ wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SET_PSCN_ADD_SW_BSSID, -+ TRUE, -+ FALSE, -+ FALSE, -+ NULL, -+ NULL, -+ sizeof(CMD_SET_PSCAN_ADD_SWC_BSSID), (PUINT_8) &rCmdPscnAddSWCBssId, NULL, 0); -+ return TRUE; -+ } -+ /* debug msg, No PSCN, Sched SCAN no need to add the hotlist ??? */ -+ return FALSE; -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief handler for Set CMD_ID_SET_PSCN_MAC_ADDR -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN scnFsmPSCNSetMacAddr(IN P_ADAPTER_T prAdapter, IN P_CMD_SET_PSCAN_MAC_ADDR prCmdPscnSetMacAddr) -+{ -+ CMD_SET_PSCAN_MAC_ADDR rCmdPscnSetMacAddr; -+ P_SCAN_INFO_T prScanInfo; -+ -+ ASSERT(prAdapter); -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ -+ /* rCmdPscnSetMacAddr.aucMacAddr = prCmdPscnSetMacAddr->aucMacAddr; */ -+ memcpy(&rCmdPscnSetMacAddr.aucMacAddr, &(prCmdPscnSetMacAddr->aucMacAddr), sizeof(MAC_ADDR_LEN)); -+ -+ rCmdPscnSetMacAddr.ucFlags = prCmdPscnSetMacAddr->ucFlags; -+ rCmdPscnSetMacAddr.ucVersion = prCmdPscnSetMacAddr->ucVersion; -+ -+ if (1 /* (prScanInfo->fgPscnOnnning == TRUE */) { -+ wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SET_PSCN_MAC_ADDR, -+ TRUE, -+ FALSE, -+ FALSE, -+ NULL, -+ NULL, sizeof(CMD_SET_PSCAN_MAC_ADDR), (PUINT_8) &rCmdPscnSetMacAddr, NULL, 0); -+ return TRUE; -+ } -+ /* debug msg, No PSCN, Sched SCAN no need to add the hotlist ??? */ -+ return FALSE; -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief handler for Set GSCN param -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN scnSetGSCNParam(IN P_ADAPTER_T prAdapter, IN P_PARAM_WIFI_GSCAN_CMD_PARAMS prCmdGscnParam) -+{ -+ /*CMD_GSCN_REQ_T rCmdGscnParam;*/ -+ P_CMD_GSCN_REQ_T rCmdGscnParamp; -+ P_SCAN_INFO_T prScanInfo; -+ UINT_8 ucChannelBuckIndex; -+ UINT_8 i; -+ -+ ASSERT(prAdapter); -+ rCmdGscnParamp = kalMemAlloc(sizeof(CMD_GSCN_REQ_T), VIR_MEM_TYPE); -+ if (rCmdGscnParamp == NULL) { -+ DBGLOG(SCN, INFO, "alloc CmdGscnParam fail\n"); -+ return TRUE; -+ } -+ kalMemZero(rCmdGscnParamp, sizeof(CMD_GSCN_REQ_T)); -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ rCmdGscnParamp->u4NumBuckets = prCmdGscnParam->num_buckets; -+ rCmdGscnParamp->u4BasePeriod = prCmdGscnParam->base_period; -+ DBGLOG(SCN, INFO, -+ "u4BasePeriod[%d], u4NumBuckets[%d]\n", rCmdGscnParamp->u4BasePeriod, rCmdGscnParamp->u4NumBuckets); -+ for (ucChannelBuckIndex = 0; ucChannelBuckIndex < prCmdGscnParam->num_buckets; ucChannelBuckIndex++) { -+ DBGLOG(SCN, TRACE, "assign channels to bucket[%d]\n", ucChannelBuckIndex); -+ for (i = 0; i < prCmdGscnParam->buckets[ucChannelBuckIndex].num_channels; i++) { -+ rCmdGscnParamp->arChannelBucket[ucChannelBuckIndex].arChannelList[i].ucChannel = -+ (UINT_8) nicFreq2ChannelNum(prCmdGscnParam->buckets[ucChannelBuckIndex]. -+ channels[i].channel * 1000); -+ rCmdGscnParamp->arChannelBucket[ucChannelBuckIndex].arChannelList[i].ucPassive = -+ (UINT_8) prCmdGscnParam->buckets[ucChannelBuckIndex].channels[i].passive; -+ rCmdGscnParamp->arChannelBucket[ucChannelBuckIndex].arChannelList[i].u4DwellTimeMs = -+ (UINT_8) prCmdGscnParam->buckets[ucChannelBuckIndex].channels[i].dwellTimeMs; -+ -+ DBGLOG(SCN, TRACE, "[ucChannel %d, ucPassive %d, u4DwellTimeMs %d\n", -+ rCmdGscnParamp->arChannelBucket[ucChannelBuckIndex].arChannelList[i].ucChannel, -+ rCmdGscnParamp->arChannelBucket[ucChannelBuckIndex].arChannelList[i].ucPassive, -+ rCmdGscnParamp->arChannelBucket[ucChannelBuckIndex].arChannelList[i].u4DwellTimeMs); -+ -+ } -+ rCmdGscnParamp->arChannelBucket[ucChannelBuckIndex].u2BucketIndex = -+ (UINT_16) prCmdGscnParam->buckets[ucChannelBuckIndex].bucket; -+ rCmdGscnParamp->arChannelBucket[ucChannelBuckIndex].eBand = -+ prCmdGscnParam->buckets[ucChannelBuckIndex].band; -+ rCmdGscnParamp->arChannelBucket[ucChannelBuckIndex].ucBucketFreqMultiple = -+ (prCmdGscnParam->buckets[ucChannelBuckIndex].period / prCmdGscnParam->base_period); -+ rCmdGscnParamp->arChannelBucket[ucChannelBuckIndex].ucNumChannels = -+ prCmdGscnParam->buckets[ucChannelBuckIndex].num_channels; -+ rCmdGscnParamp->arChannelBucket[ucChannelBuckIndex].ucReportFlag = -+ prCmdGscnParam->buckets[ucChannelBuckIndex].report_events; -+ -+ /* printk("\n"); */ -+ } -+ -+ DBGLOG(SCN, INFO, "scnSetGSCNParam ---> scnPSCNFsm PSCN_RESET\n"); -+ -+ scnPSCNFsm(prAdapter, PSCN_RESET, NULL, NULL, rCmdGscnParamp, NULL, FALSE, FALSE, FALSE, FALSE); -+ kalMemFree(rCmdGscnParamp, VIR_MEM_TYPE, sizeof(CMD_GSCN_REQ_T)); -+ return TRUE; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief handler for Combine PNO Scan params into PSCAN param -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+ -+VOID -+scnSubCombineNLOtoPSCN(IN P_ADAPTER_T prAdapter, -+ IN P_CMD_NLO_REQ prNewCmdNloReq, IN P_CMD_SET_PSCAN_PARAM prCmdPscnParam) -+{ -+ P_SCAN_INFO_T prScanInfo; -+ -+ ASSERT(prAdapter); -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ -+ if (prNewCmdNloReq) { -+ prCmdPscnParam->fgNLOScnEnable = TRUE; -+ memcpy(&prCmdPscnParam->rCmdNloReq, prNewCmdNloReq, sizeof(CMD_NLO_REQ)); -+ } else if (prScanInfo->prPscnParam->fgNLOScnEnable) { -+ memcpy(&prCmdPscnParam->rCmdNloReq, &prScanInfo->prPscnParam->rCurrentCmdNloReq, sizeof(CMD_NLO_REQ)); -+ } else -+ prCmdPscnParam->fgNLOScnEnable = FALSE; -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief handler for Combine Batcht Scan params into PSCAN param -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+ -+VOID -+scnSubCombineBatchSCNtoPSCN(IN P_ADAPTER_T prAdapter, -+ IN P_CMD_BATCH_REQ_T prNewCmdBatchReq, IN P_CMD_SET_PSCAN_PARAM prCmdPscnParam) -+{ -+ P_SCAN_INFO_T prScanInfo; -+ -+ ASSERT(prAdapter); -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ -+ if (prNewCmdBatchReq) { -+ prCmdPscnParam->fgBatchScnEnable = TRUE; -+ memcpy(&prCmdPscnParam->rCmdBatchReq, prNewCmdBatchReq, sizeof(CMD_BATCH_REQ_T)); -+ } else if (prScanInfo->prPscnParam->fgBatchScnEnable) { -+ memcpy(&prCmdPscnParam->rCmdBatchReq, &prScanInfo->prPscnParam->rCurrentCmdBatchReq, -+ sizeof(CMD_BATCH_REQ_T)); -+ } else -+ prCmdPscnParam->fgBatchScnEnable = FALSE; -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief handler for Combine GSCN Scan params into PSCAN param -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+ -+VOID -+scnSubCombineGSCNtoPSCN(IN P_ADAPTER_T prAdapter, -+ IN P_CMD_GSCN_REQ_T prNewCmdGscnReq, -+ IN P_CMD_GSCN_SCN_COFIG_T prNewCmdGscnConfig, IN P_CMD_SET_PSCAN_PARAM prCmdPscnParam) -+{ -+ P_SCAN_INFO_T prScanInfo; -+ UINT_32 ucPeriodMin = MAX_PERIOD; -+ -+ ASSERT(prAdapter); -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ prCmdPscnParam->fgGScnEnable = FALSE; -+ -+ DBGLOG(SCN, TRACE, "scnSubCombineGSCNtoPSCN fgGScnParamSet %d fgGScnConfigSet %d\n", -+ prScanInfo->fgGScnParamSet, prScanInfo->fgGScnConfigSet); -+ -+ if (prNewCmdGscnReq) { -+ DBGLOG(SCN, INFO, "setup prNewCmdGscnReq\n"); -+ prScanInfo->fgGScnParamSet = TRUE; -+ memcpy(&prCmdPscnParam->rCmdGscnReq, prNewCmdGscnReq, sizeof(CMD_GSCN_REQ_T)); -+ if (ucPeriodMin > prNewCmdGscnReq->u4BasePeriod) -+ prCmdPscnParam->u4BasePeriod = prNewCmdGscnReq->u4BasePeriod; -+ } else if (prScanInfo->fgGScnParamSet) { -+ DBGLOG(SCN, INFO, "no new prNewCmdGscnReq but there is a old one\n"); -+ memcpy(&prCmdPscnParam->rCmdGscnReq, &prScanInfo->prPscnParam->rCurrentCmdGscnReq, -+ sizeof(CMD_GSCN_REQ_T)); -+ prCmdPscnParam->u4BasePeriod = prScanInfo->prPscnParam->u4BasePeriod; -+ } else -+ prScanInfo->fgGScnParamSet = FALSE; -+ -+ if (prNewCmdGscnConfig) { -+ DBGLOG(SCN, INFO, "set up prNewCmdGscnConfig\n"); -+ memcpy(prCmdPscnParam, prScanInfo->prPscnParam, sizeof(CMD_SET_PSCAN_PARAM)); -+ prScanInfo->fgGScnConfigSet = TRUE; -+ prCmdPscnParam->rCmdGscnReq.u4BufferThreshold = prNewCmdGscnConfig->u4BufferThreshold; -+ prCmdPscnParam->rCmdGscnReq.ucNumScnToCache = (UINT_8) prNewCmdGscnConfig->u4NumScnToCache; -+ } else if (prScanInfo->fgGScnConfigSet) { -+ DBGLOG(SCN, INFO, "no new prNewCmdGscnConfig but there is a old one\n"); -+ memcpy(prCmdPscnParam, prScanInfo->prPscnParam, sizeof(CMD_SET_PSCAN_PARAM)); -+ prCmdPscnParam->rCmdGscnReq.u4BufferThreshold = -+ prScanInfo->prPscnParam->rCurrentCmdGscnReq.u4BufferThreshold; -+ prCmdPscnParam->rCmdGscnReq.ucNumScnToCache = -+ (UINT_8) prScanInfo->prPscnParam->rCurrentCmdGscnReq.ucNumScnToCache; -+ } else -+ prScanInfo->fgGScnConfigSet = FALSE; -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief handler for Combine GSCN Scan params into PSCAN param -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+ -+VOID -+scnRemoveFromPSCN(IN P_ADAPTER_T prAdapter, -+ IN BOOLEAN fgRemoveNLOfromPSCN, -+ IN BOOLEAN fgRemoveBatchSCNfromPSCN, -+ IN BOOLEAN fgRemoveGSCNfromPSCN, IN P_CMD_SET_PSCAN_PARAM prCmdPscnParam) -+{ -+ P_SCAN_INFO_T prScanInfo; -+ UINT_8 ucPscanAct = DISABLE; -+ -+ ASSERT(prAdapter); -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ -+ { -+ DBGLOG(SCN, INFO, "remove NLO or Batch or GSCN from PSCN--->NLO=%d, BSN=%d, GSN=%d\n", -+ fgRemoveNLOfromPSCN, fgRemoveBatchSCNfromPSCN, fgRemoveGSCNfromPSCN); -+ -+ if (fgRemoveNLOfromPSCN) { -+ memcpy(prCmdPscnParam, prScanInfo->prPscnParam, sizeof(CMD_SET_PSCAN_PARAM)); -+ prCmdPscnParam->fgNLOScnEnable = FALSE; -+ kalMemZero(&prCmdPscnParam->rCmdNloReq, sizeof(CMD_NLO_REQ)); -+ kalMemZero(&prScanInfo->prPscnParam->rCurrentCmdNloReq, sizeof(CMD_NLO_REQ)); -+ } -+ if (fgRemoveBatchSCNfromPSCN) { -+ memcpy(prCmdPscnParam, prScanInfo->prPscnParam, sizeof(CMD_SET_PSCAN_PARAM)); -+ prCmdPscnParam->fgBatchScnEnable = FALSE; -+ kalMemZero(&prCmdPscnParam->rCmdBatchReq, sizeof(CMD_BATCH_REQ_T)); -+ kalMemZero(&prScanInfo->prPscnParam->rCurrentCmdBatchReq, sizeof(CMD_BATCH_REQ_T)); -+ } -+ if (fgRemoveGSCNfromPSCN) { -+ memcpy(prCmdPscnParam, prScanInfo->prPscnParam, sizeof(CMD_SET_PSCAN_PARAM)); -+ prCmdPscnParam->fgGScnEnable = FALSE; -+ prScanInfo->fgGScnParamSet = FALSE; -+ kalMemZero(&prCmdPscnParam->rCmdGscnReq, sizeof(CMD_GSCN_REQ_T)); -+ kalMemZero(&prScanInfo->prPscnParam->rCurrentCmdGscnReq, sizeof(CMD_GSCN_REQ_T)); -+ } -+ -+ if (!fgRemoveNLOfromPSCN && !fgRemoveBatchSCNfromPSCN && !fgRemoveGSCNfromPSCN) { -+ /* prCmdPscnParam->fgIsPeriodicallyScn = FALSE; */ -+ prScanInfo->fgPscnOnnning = FALSE; -+ scnFsmPSCNSetParam(prAdapter, prCmdPscnParam); -+ scnFsmPSCNAction(prAdapter, ucPscanAct); -+ } else { -+ /* prCmdPscnParam->fgIsPeriodicallyScn = TRUE; */ -+ scnFsmPSCNSetParam(prAdapter, prCmdPscnParam); -+ DBGLOG(SCN, INFO, " disable NLO or GSCN or Batch but fgIsPeriodicallyScn = TRUE <-----\n"); -+ } -+ } -+ -+} -+ -+#if 1 -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief handler for Combine GSCN , Batch, PNO Scan params into PSCAN param -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+ -+BOOLEAN -+scnCombineParamsIntoPSCN(IN P_ADAPTER_T prAdapter, -+ IN P_CMD_NLO_REQ prNewCmdNloReq, -+ IN P_CMD_BATCH_REQ_T prNewCmdBatchReq, -+ IN P_CMD_GSCN_REQ_T prNewCmdGscnReq, -+ IN P_CMD_GSCN_SCN_COFIG_T prNewCmdGscnConfig, -+ IN BOOLEAN fgRemoveNLOfromPSCN, -+ IN BOOLEAN fgRemoveBatchSCNfromPSCN, IN BOOLEAN fgRemoveGSCNfromPSCN) -+{ -+ P_SCAN_INFO_T prScanInfo; -+ /* CMD_SET_PSCAN_PARAM rCmdPscnParam; */ -+ P_CMD_SET_PSCAN_PARAM prCmdPscnParam; -+ /* UINT_8 i, j = 0; */ -+ -+ ASSERT(prAdapter); -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ -+ prCmdPscnParam = (P_CMD_SET_PSCAN_PARAM) kalMemAlloc(sizeof(CMD_SET_PSCAN_PARAM), VIR_MEM_TYPE); -+ if (!prCmdPscnParam) { -+ DBGLOG(SCN, ERROR, "Can not alloc memory for PARAM_WIFI_GSCAN_CMD_PARAMS\n"); -+ return -ENOMEM; -+ } -+ kalMemZero(prCmdPscnParam, sizeof(CMD_SET_PSCAN_PARAM)); -+ -+ prCmdPscnParam->ucVersion = CURRENT_PSCN_VERSION; -+ -+ if (fgRemoveNLOfromPSCN || fgRemoveBatchSCNfromPSCN || fgRemoveGSCNfromPSCN) { -+ scnRemoveFromPSCN(prAdapter, -+ fgRemoveNLOfromPSCN, fgRemoveBatchSCNfromPSCN, fgRemoveGSCNfromPSCN, prCmdPscnParam); -+ } else { -+ DBGLOG(SCN, INFO, "combine GSCN or Batch or NLO to PSCN --->\n"); -+ -+ scnSubCombineNLOtoPSCN(prAdapter, prNewCmdNloReq, prCmdPscnParam); -+ scnSubCombineBatchSCNtoPSCN(prAdapter, prNewCmdBatchReq, prCmdPscnParam); -+ if (prNewCmdGscnReq) -+ scnSubCombineGSCNtoPSCN(prAdapter, prNewCmdGscnReq, NULL, prCmdPscnParam); -+ if (prNewCmdGscnConfig) -+ scnSubCombineGSCNtoPSCN(prAdapter, NULL, prNewCmdGscnConfig, prCmdPscnParam); -+ /* scnFsmPSCNSetParam(prAdapter, prCmdPscnParam); */ -+ -+#if 0 -+ DBGLOG(SCN, TRACE, "combine GSCN or Batch or NLO to PSCN <--- rCmdPscnParam\n"); -+ DBGLOG(SCN, TRACE, -+ "Period[%u], NumCache[%u], Threshold[%u], NumBuckets[%u],GSCNEn[%d] NLOEn[%d] BatchEn[%d]\n", -+ prCmdPscnParam->rCmdGscnReq.u4BasePeriod, prCmdPscnParam->rCmdGscnReq.ucNumScnToCache, -+ prCmdPscnParam->rCmdGscnReq.u4BufferThreshold, prCmdPscnParam->rCmdGscnReq.u4NumBuckets, -+ prCmdPscnParam->fgGScnEnable, prCmdPscnParam->fgNLOScnEnable, -+ prCmdPscnParam->fgBatchScnEnable)); -+ -+ for (i = 0; i < prCmdPscnParam->rCmdGscnReq.u4NumBuckets; i++) { -+ DBGLOG(SCN, TRACE, "rCmdPscnParam.rCmdGscnParam.arChannelBucket[%d] has channel: ", i); -+ DBGLOG(SCN, TRACE, -+ "band[%u], ChnBkt[%u] NumChns[%u], BktFreqMltpl[%u] Flag[%u]\n", -+ prCmdPscnParam->rCmdGscnReq.arChannelBucket[i].eBand, -+ prCmdPscnParam->rCmdGscnReq.arChannelBucket[i].u2BucketIndex, -+ prCmdPscnParam->rCmdGscnReq.arChannelBucket[i].ucNumChannels, -+ prCmdPscnParam->rCmdGscnReq.arChannelBucket[i].ucBucketFreqMultiple, -+ prCmdPscnParam->rCmdGscnReq.arChannelBucket[i].ucReportFlag)); -+ for (j = 0; j < prCmdPscnParam->rCmdGscnReq.arChannelBucket[i].ucNumChannels; j++) { -+ DBGLOG(SCN, TRACE, " %d, ", -+ prCmdPscnParam->rCmdGscnReq.arChannelBucket[i].arChannelList[j].ucChannel); -+ } -+ DBGLOG(SCN, TRACE, "\n"); -+ } -+#endif -+ } -+ -+ memcpy(prScanInfo->prPscnParam, prCmdPscnParam, sizeof(CMD_SET_PSCAN_PARAM)); -+ kalMemFree(prCmdPscnParam, VIR_MEM_TYPE, sizeof(CMD_SET_PSCAN_PARAM)); -+ return TRUE; -+} -+ -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief handler for Set CMD_ID_SET_PSCN_MAC_ADDR -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN scnFsmSetGSCNConfig(IN P_ADAPTER_T prAdapter, IN P_CMD_GSCN_SCN_COFIG_T prCmdGscnScnConfig) -+{ -+ CMD_GSCN_SCN_COFIG_T rCmdGscnScnConfig; -+ -+ ASSERT(prAdapter); -+ memcpy(&rCmdGscnScnConfig, prCmdGscnScnConfig, sizeof(CMD_GSCN_SCN_COFIG_T)); -+ DBGLOG(SCN, TRACE, "rCmdGscnScnConfig: u4BufferThreshold; [%d] ucNumApPerScn [%d] ucNumScnToCache [%d]\n", -+ rCmdGscnScnConfig.u4BufferThreshold, -+ rCmdGscnScnConfig.ucNumApPerScn, -+ rCmdGscnScnConfig.u4NumScnToCache); -+ -+ scnPSCNFsm(prAdapter, PSCN_RESET, NULL, NULL, NULL, &rCmdGscnScnConfig, FALSE, FALSE, FALSE, FALSE); -+ -+ return TRUE; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief handler for Set CMD_ID_SET_PSCN_MAC_ADDR -+* -+* \param[in] -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN scnFsmGetGSCNResult(IN P_ADAPTER_T prAdapter, IN P_CMD_GET_GSCAN_RESULT_T prGetGscnScnResultCmd) -+{ -+ CMD_GET_GSCAN_RESULT_T rGetGscnScnResultCmd; -+ P_SCAN_INFO_T prScanInfo; -+ -+ ASSERT(prAdapter); -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ memcpy(&rGetGscnScnResultCmd, prGetGscnScnResultCmd, sizeof(CMD_GET_GSCAN_RESULT_T)); -+ DBGLOG(SCN, INFO, "rGetGscnScnResultCmd: ucGetNum [%d] fgFlush [%d]\n", -+ rGetGscnScnResultCmd.u4Num, rGetGscnScnResultCmd.ucFlush); -+ -+ if (prScanInfo->fgPscnOnnning && prScanInfo->prPscnParam->fgGScnEnable) { -+ wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_GET_GSCN_SCN_RESULT, -+ TRUE, -+ FALSE, -+ FALSE, -+ NULL, -+ NULL, sizeof(CMD_GET_GSCAN_RESULT_T), (PUINT_8) &rGetGscnScnResultCmd, NULL, 0); -+ return TRUE; -+ } -+ /* debug msg, No PSCN, Sched SCAN GSCN ongoing ??? */ -+ return FALSE; -+ -+} -+ -+VOID -+scnPSCNFsm(IN P_ADAPTER_T prAdapter, -+ ENUM_PSCAN_STATE_T eNextPSCNState, -+ IN P_CMD_NLO_REQ prCmdNloReq, -+ IN P_CMD_BATCH_REQ_T prCmdBatchReq, -+ IN P_CMD_GSCN_REQ_T prCmdGscnReq, -+ IN P_CMD_GSCN_SCN_COFIG_T prNewCmdGscnConfig, -+ IN BOOLEAN fgRemoveNLOfromPSCN, -+ IN BOOLEAN fgRemoveBatchSCNfromPSCN, IN BOOLEAN fgRemoveGSCNfromPSCN, IN BOOLEAN fgEnableGSCN) -+{ -+ P_SCAN_INFO_T prScanInfo; -+ BOOLEAN fgTransitionState = FALSE; -+ -+ ASSERT(prAdapter); -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ -+ do { -+ fgTransitionState = FALSE; -+ -+ DBGLOG(SCN, STATE, "eCurrentPSCNState=%d, eNextPSCNState=%d\n", -+ prScanInfo->eCurrentPSCNState, eNextPSCNState); -+ -+ switch (prScanInfo->eCurrentPSCNState) { -+ case PSCN_IDLE: -+ if (eNextPSCNState == PSCN_RESET) { -+ if (fgRemoveNLOfromPSCN || fgRemoveBatchSCNfromPSCN || fgRemoveGSCNfromPSCN) { -+ DBGLOG(SCN, TRACE, "Unexpected remove NLO/BATCH/GSCN request\n"); -+ eNextPSCNState = PSCN_IDLE; -+ break; -+ } -+ -+ if (prCmdNloReq || prCmdBatchReq) { -+ DBGLOG(SCN, TRACE, "PSCN_IDLE->PSCN_RESET,.... scnFsmPSCNActionDISABLE\n"); -+ /*TBD check PSCAN is ongoing */ -+ scnFsmPSCNAction(prAdapter, DISABLE); -+ break; -+ } -+ -+ } else if (eNextPSCNState == PSCN_SCANNING) { -+ if (fgEnableGSCN) { -+ if (prScanInfo->fgPscnOnnning) -+ scnFsmPSCNAction(prAdapter, DISABLE); -+ if (prScanInfo->fgGScnParamSet) { -+ DBGLOG(SCN, TRACE, -+ "PSCN_IDLE->PSCN_SCANNING,.... scnFsmPSCNActionENABLE\n"); -+ prScanInfo->prPscnParam->fgGScnEnable = TRUE; -+ scnFsmPSCNSetParam(prAdapter, -+ (P_CMD_SET_PSCAN_PARAM)prScanInfo->prPscnParam); -+ scnFsmPSCNAction(prAdapter, ENABLE); -+ eNextPSCNState = PSCN_SCANNING; -+ } -+ } -+ } -+ break; -+ -+ case PSCN_RESET: -+ scnCombineParamsIntoPSCN(prAdapter, -+ prCmdNloReq, -+ prCmdBatchReq, -+ prCmdGscnReq, -+ prNewCmdGscnConfig, -+ fgRemoveNLOfromPSCN, fgRemoveBatchSCNfromPSCN, fgRemoveGSCNfromPSCN); -+ -+ if (!prScanInfo->prPscnParam->fgNLOScnEnable && !prScanInfo->prPscnParam->fgBatchScnEnable -+ && !prScanInfo->prPscnParam->fgGScnEnable) { -+ DBGLOG(SCN, TRACE, -+ "PSCN_RESET->PSCN_IDLE,.... fgNLOScnEnable/fgBatchScnEnable/fgGScnEnable false\n"); -+ eNextPSCNState = PSCN_IDLE; -+ } else { -+ if (prScanInfo->prPscnParam->fgNLOScnEnable -+ || prScanInfo->prPscnParam->fgBatchScnEnable) { -+ scnFsmPSCNSetParam(prAdapter, (P_CMD_SET_PSCAN_PARAM) prScanInfo->prPscnParam); -+ scnFsmPSCNAction(prAdapter, ENABLE); -+ eNextPSCNState = PSCN_SCANNING; -+ DBGLOG(SCN, TRACE, -+ "PSCN_RESET->PSCN_SCANNING,.... fgNLOScnEnable/fgBatchScnEnable ENABLE\n"); -+ } -+ } -+ break; -+ -+ case PSCN_SCANNING: -+ if (eNextPSCNState == PSCN_RESET) { -+ if (fgRemoveNLOfromPSCN || fgRemoveBatchSCNfromPSCN || fgRemoveGSCNfromPSCN) { -+ DBGLOG(SCN, TRACE, -+ "PSCN_SCANNING->PSCN_RESET,.... fgRemoveNLOfromPSCN/fgRemoveBatchSCNfromPSCN/fgRemoveGSCNfromPSCN\n"); -+ scnFsmPSCNAction(prAdapter, DISABLE); -+ break; -+ } -+ -+ if (prCmdNloReq || prCmdBatchReq || prCmdGscnReq || prNewCmdGscnConfig) { -+ DBGLOG(SCN, TRACE, -+ "PSCN_SCANNING->PSCN_RESET,.... prCmdNloReq/prCmdBatchReq/prCmdGscnReq/prNewCmdGscnConfig\n"); -+ scnFsmPSCNAction(prAdapter, DISABLE); -+ break; -+ } -+ -+ } else if (eNextPSCNState == PSCN_SCANNING) { -+ if (fgEnableGSCN) { -+ if (prScanInfo->prPscnParam->fgGScnEnable && (!prScanInfo->fgPscnOnnning)) { -+ DBGLOG(SCN, TRACE, -+ "PSCN_SCANNING->PSCN_SCANNING,.... fgGScnEnable/!fgPscnOnnning\n"); -+ /* scnFsmPSCNAction(prAdapter, ENABLE); */ -+ eNextPSCNState = PSCN_SCANNING; -+ } else { -+ -+ DBGLOG(SCN, TRACE, -+ "PSCN_SCANNING->PSCN_SCANNING,.... fgGScnEnable/!fgPscnOnnning\n"); -+ } -+ } -+ } -+ eNextPSCNState = PSCN_SCANNING; -+ break; -+ -+ default: -+ DBGLOG(SCN, WARN, "Unexpected state\n"); -+ ASSERT(0); -+ break; -+ } -+ -+ DBGLOG(SCN, STATE, "eCurrentState %d , eNextPSCNState %d\n", -+ prScanInfo->eCurrentPSCNState, eNextPSCNState); -+ if (prScanInfo->eCurrentPSCNState != eNextPSCNState) -+ fgTransitionState = TRUE; -+ -+ prScanInfo->eCurrentPSCNState = eNextPSCNState; -+ } while (fgTransitionState); -+ -+} -+#endif -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/sec_fsm.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/sec_fsm.c -new file mode 100644 -index 000000000000..29eb8d4e7d92 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/sec_fsm.c -@@ -0,0 +1,1112 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/sec_fsm.c#1 -+*/ -+ -+/*! \file "sec_fsm.c" -+ \brief This is the file implement security check state machine. -+ -+ In security module, do the port control check after success join to an AP, -+ and the path to NORMAL TR, the state machine handle these state transition. -+*/ -+ -+/* -+** Log: sec_fsm.c -+ * -+ * 11 24 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * Adjust code for DBG and CONFIG_XLOG. -+ * -+ * 11 11 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * modify the xlog related code. -+ * -+ * 11 10 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * change the debug module level. -+ * -+ * 11 02 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * adding the code for XLOG. -+ * -+ * 03 29 2011 wh.su -+ * [WCXRP00000248] [MT6620 Wi-Fi][FW]Fixed the Klockwork error -+ * fixed the kclocwork error. -+ * -+ * 01 26 2011 yuche.tsai -+ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record. -+ * . -+ * -+ * 01 25 2011 yuche.tsai -+ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record. -+ * Fix Compile Error when DBG is disabled. -+ * -+ * 01 25 2011 yuche.tsai -+ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record. -+ * Change Station Type in Station Record, Modify MACRO definition for getting station type & network type index & Role. -+ * -+ * 09 29 2010 wh.su -+ * [WCXRP00000072] [MT6620 Wi-Fi][Driver] Fix TKIP Counter Measure EAPoL callback register issue -+ * [MT6620 Wi-Fi][Driver] Fix TKIP Counter Measure EAPoL callback register issue. -+ * -+ * 09 24 2010 wh.su -+ * NULL -+ * [WCXRP00005002][MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning. -+ * -+ * 09 03 2010 kevin.huang -+ * NULL -+ * Refine #include sequence and solve recursive/nested #include issue -+ * -+ * 08 20 2010 wh.su -+ * NULL -+ * adding the eapol callback setting. -+ * -+ * 08 19 2010 wh.su -+ * NULL -+ * adding the tx pkt call back handle for countermeasure. -+ * -+ * 07 19 2010 wh.su -+ * -+ * fixed the compilng error at debug mode. -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 21 2010 wh.su -+ * [WPD00003840][MT6620 5931] Security migration -+ * modify some code for concurrent network. -+ * -+ * 06 19 2010 wh.su -+ * [WPD00003840][MT6620 5931] Security migration -+ * consdier the concurrent network setting. -+ * -+ * 05 28 2010 wh.su -+ * [BORA00000626][MT6620] Refine the remove key flow for WHQL testing -+ * fixed the ad-hoc wpa-none send non-encrypted frame issue. -+ * -+ * 05 24 2010 kevin.huang -+ * [BORA00000794][WIFISYS][New Feature]Power Management Support -+ * Refine authSendAuthFrame() for NULL STA_RECORD_T case and minimum deauth interval. -+ * -+ * 04 24 2010 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * g_aprBssInfo[] depends on CFG_SUPPORT_P2P and CFG_SUPPORT_BOW -+ * -+ * 04 13 2010 wh.su -+ * [BORA00000680][MT6620] Support the statistic for Micxxsoft os query -+ * fixed the Klocwork error and refine the class error message. -+ * -+ * 03 03 2010 wh.su -+ * [BORA00000637][MT6620 Wi-Fi] [Bug] WPA2 pre-authentication timer not correctly initialize -+ * move the AIS specific variable for security to AIS specific structure. -+ * -+ * 03 03 2010 wh.su -+ * [BORA00000637][MT6620 Wi-Fi] [Bug] WPA2 pre-authentication timer not correctly initialize -+ * Fixed the pre-authentication timer not correctly init issue, -+ * and modify the security related callback function prototype. -+ * -+ * 03 01 2010 wh.su -+ * [BORA00000605][WIFISYS] Phase3 Integration -+ * Refine the variable and parameter for security. -+ * -+ * 01 27 2010 wh.su -+ * [BORA00000476][Wi-Fi][firmware] Add the security module initialize code -+ * add and fixed some security function. -+ * -+ * 01 13 2010 wh.su -+ * [BORA00000476][Wi-Fi][firmware] Add the security module initialize code -+ * fixed the compiling warning -+ * -+ * 12 18 2009 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * . -+ * -+ * Dec 7 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * refine some code -+ * -+ * Dec 4 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * refine the code -+ * -+ * Dec 1 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * code refine -+ * -+ * Nov 23 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * adjust the function name -+ * -+ * Nov 19 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * adjust the state machine, to meet the firmware security design v1.1 -+ * -+ * Nov 18 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * -+** -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "precomp.h" -+ -+#if CFG_RSN_MIGRATION -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+#if DBG -+/*lint -save -e64 Type mismatch */ -+static PUINT_8 apucDebugSecState[SEC_STATE_NUM] = { -+ (PUINT_8) DISP_STRING("SEC_STATE_INIT"), -+ (PUINT_8) DISP_STRING("SEC_STATE_INITIATOR_PORT_BLOCKED"), -+ (PUINT_8) DISP_STRING("SEC_STATE_RESPONDER_PORT_BLOCKED"), -+ (PUINT_8) DISP_STRING("SEC_STATE_CHECK_OK"), -+ (PUINT_8) DISP_STRING("SEC_STATE_SEND_EAPOL"), -+ (PUINT_8) DISP_STRING("SEC_STATE_SEND_DEAUTH"), -+ (PUINT_8) DISP_STRING("SEC_STATE_COUNTERMEASURE"), -+}; -+ -+/*lint -restore */ -+#endif /* DBG */ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will do initialization of Security FSM and all variables in -+* SEC_INFO_T. -+* -+* \param[in] prSta Pointer to the STA record -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID secFsmInit(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta) -+{ -+ P_SEC_INFO_T prSecInfo; -+ P_AIS_SPECIFIC_BSS_INFO_T prAisSpecBssInfo; -+ -+ ASSERT(prSta); -+ -+ prSecInfo = &prSta->rSecInfo; -+ -+#if 1 /* MT6620 */ -+ /* At MT5921, is ok, but at MT6620, firmware base ASIC, the firmware */ -+ /* will lost these data, thus, driver have to keep the wep material and */ -+ /* setting to firmware while awake from D3. */ -+#endif -+ -+ prSecInfo->eCurrentState = SEC_STATE_INIT; -+ -+ prSecInfo->fg2nd1xSend = FALSE; -+ prSecInfo->fgKeyStored = FALSE; -+ -+ if (IS_STA_IN_AIS(prSta)) { -+ prAisSpecBssInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo; -+ -+ prAisSpecBssInfo->u4RsnaLastMICFailTime = 0; -+ prAisSpecBssInfo->fgCheckEAPoLTxDone = FALSE; -+ -+ cnmTimerInitTimer(prAdapter, -+ &prAdapter->rWifiVar.rAisSpecificBssInfo.rRsnaEAPoLReportTimeoutTimer, -+ (PFN_MGMT_TIMEOUT_FUNC) secFsmEventEapolTxTimeout, (ULONG) prSta); -+ -+ cnmTimerInitTimer(prAdapter, -+ &prAdapter->rWifiVar.rAisSpecificBssInfo.rRsnaBlockTrafficTimer, -+ (PFN_MGMT_TIMEOUT_FUNC) secFsmEventEndOfCounterMeasure, (ULONG) prSta); -+ -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will do uninitialization of Security FSM and all variables in -+* SEC_INFO_T. -+* -+* \param[in] prSta Pointer to the STA record -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID /* whsu:Todo: */ -+secFsmUnInit(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta) -+{ -+ P_SEC_INFO_T prSecInfo; -+ -+ ASSERT(prSta); -+ -+ prSecInfo = &prSta->rSecInfo; -+ -+ prSecInfo->fg2nd1xSend = FALSE; -+ prSecInfo->fgKeyStored = FALSE; -+ -+ /* nicPrivacyRemoveWlanTable(prSta->ucWTEntry); */ -+ -+ if (IS_STA_IN_AIS(prSta)) { -+ cnmTimerStopTimer(prAdapter, &prAdapter->rWifiVar.rAisSpecificBssInfo.rRsnaEAPoLReportTimeoutTimer); -+ cnmTimerStopTimer(prAdapter, &prAdapter->rWifiVar.rAisSpecificBssInfo.rRsnaBlockTrafficTimer); -+ } -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will do action part while in STATE transition of -+* STANDBY to CHECK_OK. -+* -+* \param[in] prSta Pointer to the Sta record -+* -+* \return - none -+*/ -+/*----------------------------------------------------------------------------*/ -+static inline VOID secFsmTrans_INIT_to_CHECK_OK(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta) -+{ -+ secSetPortBlocked(prAdapter, prSta, FALSE); -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will do action part while in STATE transition of -+* INIT to INITIATOR_PORT_BLOCKED. -+* -+* \param[in] prSta Pointer to the Sta record -+* -+* \return - none -+*/ -+/*----------------------------------------------------------------------------*/ -+static inline VOID secFsmTrans_INIT_to_INITIATOR_PORT_BLOCKED(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta) -+{ -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will do action part while in STATE transition of -+* INIT to RESPONDER_PORT_BLOCKED. -+* -+* \param[in] prSta Pointer to the Sta record -+* -+* \return - none -+*/ -+/*----------------------------------------------------------------------------*/ -+static inline VOID secFsmTrans_INIT_to_RESPONDER_PORT_BLOCKED(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta) -+{ -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will do action part while in STATE transition of -+* INITIATOR_PORT_BLOCKED to CHECK_OK. -+* -+* \param[in] prSta Pointer to the Sta record -+* -+* \return - none -+*/ -+/*----------------------------------------------------------------------------*/ -+static inline VOID secFsmTrans_INITIATOR_PORT_BLOCKED_to_CHECK_OK(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta) -+{ -+ secSetPortBlocked(prAdapter, prSta, FALSE); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will do action part while in STATE transition of -+* RESPONDER_PORT_BLOCKED to CHECK_OK. -+* -+* \param[in] prSta Pointer to the Sta record -+* -+* \return - none -+*/ -+/*----------------------------------------------------------------------------*/ -+static inline VOID secFsmTrans_RESPONDER_PORT_BLOCKED_to_CHECK_OK(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta) -+{ -+ secSetPortBlocked(prAdapter, prSta, FALSE); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will do action part while in STATE transition of -+* CHECK_OK to SEND_EAPOL -+* -+* \param[in] prSta Pointer to the Sta record -+* -+* \return - -+*/ -+/*----------------------------------------------------------------------------*/ -+static inline VOID secFsmTrans_CHECK_OK_to_SEND_EAPOL(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta) -+{ -+ -+ P_AIS_SPECIFIC_BSS_INFO_T prAisBssInfo; -+ -+ ASSERT(prAdapter); -+ -+ ASSERT(prSta); -+ -+ prAisBssInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo; -+ -+ ASSERT(prAisBssInfo); -+ -+ if (!IS_STA_IN_AIS(prSta)) { -+ DBGLOG(RSN, INFO, "Counter Measure should occur at AIS network!!\n"); -+ /* ASSERT(0); */ -+ return; -+ } -+ -+ prAisBssInfo->fgCheckEAPoLTxDone = TRUE; -+ -+ /* cnmTimerStartTimer(prAdapter, */ -+ /* &prAisBssInfo->rRsnaEAPoLReportTimeoutTimer, */ -+ /* SEC_TO_MSEC(EAPOL_REPORT_SEND_TIMEOUT_INTERVAL_SEC)); */ -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will do action part while in STATE transition of -+* SEND_EAPOL to SEND_DEAUTH. -+* -+* \param[in] prSta Pointer to the Sta record -+* -+* \return - none -+*/ -+/*----------------------------------------------------------------------------*/ -+static inline VOID secFsmTrans_SEND_EAPOL_to_SEND_DEAUTH(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta) -+{ -+ -+ if (!IS_STA_IN_AIS(prSta)) { -+ DBGLOG(RSN, INFO, "Counter Measure should occur at AIS network!!\n"); -+ /* ASSERT(0); */ -+ return; -+ } -+ -+ /* Compose deauth frame to AP, a call back function for tx done */ -+ if (authSendDeauthFrame(prAdapter, -+ prSta, -+ (P_SW_RFB_T) NULL, -+ REASON_CODE_MIC_FAILURE, -+ (PFN_TX_DONE_HANDLER) secFsmEventDeauthTxDone) != WLAN_STATUS_SUCCESS) { -+ ASSERT(FALSE); -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will do action part while in STATE transition of -+* SEND_DEAUTH to COUNTERMEASURE. -+* -+* \param[in] prSta Pointer to the Sta record -+* -+* \return - -+*/ -+/*----------------------------------------------------------------------------*/ -+static inline VOID secFsmTrans_SEND_DEAUTH_to_COUNTERMEASURE(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta) -+{ -+ ASSERT(prAdapter); -+ ASSERT(prSta); -+ -+ if (!IS_STA_IN_AIS(prSta)) { -+ DBGLOG(RSN, INFO, "Counter Measure should occur at AIS network!!\n"); -+ /* ASSERT(0); */ -+ return; -+ } -+ /* Start the 60 sec timer */ -+ cnmTimerStartTimer(prAdapter, -+ &prAdapter->rWifiVar.rAisSpecificBssInfo.rRsnaBlockTrafficTimer, -+ SEC_TO_MSEC(COUNTER_MEASURE_TIMEOUT_INTERVAL_SEC)); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will do action part while in STATE transition of -+* SEND_DEAUTH to COUNTERMEASURE. -+* -+* \param[in] prSta Pointer to the Sta record -+* -+* \return - -+*/ -+/*----------------------------------------------------------------------------*/ -+static inline VOID secFsmTrans_COUNTERMEASURE_to_INIT(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta) -+{ -+ -+ /* Clear the counter measure flag */ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief The Core FSM engine of security module. -+* -+* \param[in] prSta Pointer to the Sta record -+* \param[in] eNextState Enum value of next sec STATE -+* -+* \return - -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID secFsmSteps(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta, IN ENUM_SEC_STATE_T eNextState) -+{ -+ P_SEC_INFO_T prSecInfo; -+ BOOLEAN fgIsTransition = (BOOLEAN) FALSE; -+ -+ ASSERT(prSta); -+ -+ prSecInfo = &prSta->rSecInfo; -+ ASSERT(prSecInfo); -+ -+ DEBUGFUNC("secFsmSteps"); -+ do { -+ /* Do entering Next State */ -+ prSecInfo->ePreviousState = prSecInfo->eCurrentState; -+ -+ /* Do entering Next State */ -+#if DBG -+ DBGLOG(RSN, STATE, "\n %pM TRANSITION: [%s] -> [%s]\n\n", -+ prSta->aucMacAddr, -+ apucDebugSecState[prSecInfo->eCurrentState], apucDebugSecState[eNextState]); -+#else -+ DBGLOG(RSN, STATE, "\n %pM [%d] TRANSITION: [%d] -> [%d]\n\n", -+ prSta->aucMacAddr, DBG_RSN_IDX, prSecInfo->eCurrentState, eNextState); -+#endif -+ prSecInfo->eCurrentState = eNextState; -+ -+ fgIsTransition = (BOOLEAN) FALSE; -+#if 0 -+ /* Do tasks of the State that we just entered */ -+ switch (prSecInfo->eCurrentState) { -+ case SEC_STATE_INIT: -+ break; -+ case SEC_STATE_INITIATOR_PORT_BLOCKED: -+ break; -+ case SEC_STATE_RESPONDER_PORT_BLOCKED: -+ break; -+ case SEC_STATE_CHECK_OK: -+ break; -+ case SEC_STATE_SEND_EAPOL: -+ break; -+ case SEC_STATE_SEND_DEAUTH: -+ break; -+ case SEC_STATE_COUNTERMEASURE: -+ break; -+ default: -+ ASSERT(0); /* Make sure we have handle all STATEs */ -+ break; -+ } -+#endif -+ } while (fgIsTransition); -+ -+ return; -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will do initialization of Security FSM and all variables in -+* SEC_INFO_T. -+* -+* \param[in] prSta Pointer to the Sta record -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID secFsmEventStart(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta) -+{ -+ P_SEC_INFO_T prSecInfo; -+ BOOLEAN fgIsTransition = (BOOLEAN) FALSE; -+ ENUM_SEC_STATE_T eNextState; -+ -+ DBGLOG(RSN, TRACE, "secFsmRunEventStart\n"); -+ -+ ASSERT(prSta); -+ -+ if (!prSta) -+ return; -+ -+ if (!IS_STA_IN_AIS(prSta)) -+ return; -+ -+ DBGLOG(RSN, TRACE, "secFsmRunEventStart for sta %pM network %d\n", -+ prSta->aucMacAddr, prSta->ucNetTypeIndex); -+ -+ prSecInfo = (P_SEC_INFO_T) &prSta->rSecInfo; -+ -+ eNextState = prSecInfo->eCurrentState; -+ -+ secSetPortBlocked(prAdapter, prSta, TRUE); -+ -+ /* prSta->fgTransmitKeyExist = FALSE; */ -+ /* whsu:: nicPrivacySetStaDefaultWTIdx(prSta); */ -+ -+#if 1 /* Since the 1x and key can set to firmware in order, always enter the check ok state */ -+ SEC_STATE_TRANSITION(prAdapter, prSta, INIT, CHECK_OK); -+#else -+ if (IS_STA_IN_AIS(prSta->eStaType)) { -+ if (secRsnKeyHandshakeEnabled(prAdapter) == TRUE -+#if CFG_SUPPORT_WAPI -+ || (prAdapter->rWifiVar.rConnSettings.fgWapiMode) -+#endif -+ ) { -+ prSta->fgTransmitKeyExist = FALSE; -+ /* nicPrivacyInitialize(prSta->ucNetTypeIndex); */ -+ SEC_STATE_TRANSITION(prAdapter, prSta, INIT, INITIATOR_PORT_BLOCKED); -+ } else { -+ SEC_STATE_TRANSITION(prAdapter, prSta, INIT, CHECK_OK); -+ } -+ } -+#if CFG_ENABLE_WIFI_DIRECT || CFG_ENABLE_BT_OVER_WIFI -+#if CFG_ENABLE_WIFI_DIRECT && CFG_ENABLE_BT_OVER_WIFI -+ else if ((prSta->eStaType == STA_TYPE_BOW_CLIENT) || (prSta->eStaType == STA_TYPE_P2P_GC)) { -+#elif CFG_ENABLE_WIFI_DIRECT -+ else if (prSta->eStaType == STA_TYPE_P2P_GC) { -+#elif CFG_ENABLE_BT_OVER_WIFI -+ else if (prSta->eStaType == STA_TYPE_BOW_CLIENT) { -+#endif -+ SEC_STATE_TRANSITION(prAdapter, prSta, INIT, RESPONDER_PORT_BLOCKED); -+ } -+#endif -+ else -+ SEC_STATE_TRANSITION(prAdapter, prSta, INIT, INITIATOR_PORT_BLOCKED); -+#endif -+ if (prSecInfo->eCurrentState != eNextState) -+ secFsmSteps(prAdapter, prSta, eNextState); -+ -+} /* secFsmRunEventStart */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function called by reset procedure to force the sec fsm enter -+* idle state -+* -+* \param[in] ucNetTypeIdx The Specific Network type index -+* \param[in] prSta Pointer to the Sta record -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID secFsmEventAbort(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta) -+{ -+ P_SEC_INFO_T prSecInfo; -+ -+ DBGLOG(RSN, TRACE, "secFsmEventAbort for sta %pM network %d\n", -+ prSta->aucMacAddr, prSta->ucNetTypeIndex); -+ -+ ASSERT(prSta); -+ -+ if (!prSta) -+ return; -+ -+ if (!IS_STA_IN_AIS(prSta)) -+ return; -+ -+ prSecInfo = (P_SEC_INFO_T) &prSta->rSecInfo; -+ -+ prSta->fgTransmitKeyExist = FALSE; -+ -+ secSetPortBlocked(prAdapter, prSta, TRUE); -+ -+ if (prSecInfo == NULL) -+ return; -+ -+ if (IS_STA_IN_AIS(prSta)) { -+ -+ prAdapter->rWifiVar.rAisSpecificBssInfo.fgTransmitKeyExist = FALSE; -+ -+ if (prSecInfo->eCurrentState == SEC_STATE_SEND_EAPOL) { -+ if (prAdapter->rWifiVar.rAisSpecificBssInfo.fgCheckEAPoLTxDone == FALSE) { -+ DBGLOG(RSN, TRACE, "EAPOL STATE not match the flag\n"); -+ /* cnmTimerStopTimer(prAdapter, &prAdapter->rWifiVar. -+ * rAisSpecificBssInfo.rRsnaEAPoLReportTimeoutTimer); */ -+ } -+ } -+ } -+ prSecInfo->eCurrentState = SEC_STATE_INIT; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will indicate an Event of "2nd EAPoL Tx is sending" to Sec FSM. -+* -+* \param[in] prSta Pointer to the Sta record -+* -+* \return - -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID secFsmEvent2ndEapolTx(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta) -+{ -+ P_SEC_INFO_T prSecInfo; -+ ENUM_SEC_STATE_T eNextState; -+ /* BOOLEAN fgIsTransition = (BOOLEAN)FALSE; */ -+ -+ DEBUGFUNC("secFsmRunEvent2ndEapolTx"); -+ -+ ASSERT(prSta); -+ -+ prSecInfo = &prSta->rSecInfo; -+ eNextState = prSecInfo->eCurrentState; -+ -+#if DBG -+ DBGLOG(RSN, TRACE, "%pM Sec state %s\n", prSta->aucMacAddr, -+ apucDebugSecState[prSecInfo->eCurrentState]); -+#else -+ DBGLOG(RSN, TRACE, "%pM Sec state [%d]\n", prSta->aucMacAddr, prSecInfo->eCurrentState); -+#endif -+ -+ switch (prSecInfo->eCurrentState) { -+ case SEC_STATE_INITIATOR_PORT_BLOCKED: -+ case SEC_STATE_CHECK_OK: -+ prSecInfo->fg2nd1xSend = TRUE; -+ break; -+ default: -+#if DBG -+ DBGLOG(RSN, WARN, "Rcv 2nd EAPoL at %s\n", apucDebugSecState[prSecInfo->eCurrentState]); -+#else -+ DBGLOG(RSN, WARN, "Rcv 2nd EAPoL at [%d]\n", prSecInfo->eCurrentState); -+#endif -+ break; -+ } -+ -+ if (prSecInfo->eCurrentState != eNextState) -+ secFsmSteps(prAdapter, prSta, eNextState); -+ -+ return; -+ -+} /* secFsmRunEvent2ndEapolTx */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will indicate an Event of "4th EAPoL Tx is Tx done" to Sec FSM. -+* -+* \param[in] prSta Pointer to the Sta record -+* -+* \return - -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID secFsmEvent4ndEapolTxDone(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta) -+{ -+ P_SEC_INFO_T prSecInfo; -+ ENUM_SEC_STATE_T eNextState; -+ BOOLEAN fgIsTransition = (BOOLEAN) FALSE; -+ P_CMD_802_11_KEY prStoredKey; -+ -+ DEBUGFUNC("secFsmRunEvent4ndEapolTx"); -+ -+ ASSERT(prSta); -+ -+ prSecInfo = &prSta->rSecInfo; -+ eNextState = prSecInfo->eCurrentState; -+ -+#if DBG -+ DBGLOG(RSN, TRACE, "%pM Sec state %s\n", prSta->aucMacAddr, -+ apucDebugSecState[prSecInfo->eCurrentState]); -+#else -+ DBGLOG(RSN, TRACE, "%pM Sec state [%d]\n", prSta->aucMacAddr, prSecInfo->eCurrentState); -+#endif -+ -+ switch (prSecInfo->eCurrentState) { -+ case SEC_STATE_INITIATOR_PORT_BLOCKED: -+ case SEC_STATE_CHECK_OK: -+ prSecInfo->fg2nd1xSend = FALSE; -+ if (prSecInfo->fgKeyStored) { -+ prStoredKey = (P_CMD_802_11_KEY) prSecInfo->aucStoredKey; -+ -+ /* prSta = rxmLookupStaRecIndexFromTA(prStoredKey->aucPeerAddr); */ -+ /* if (nicPrivacySetKeyEntry(prStoredKey, prSta->ucWTEntry) == FALSE) */ -+ /* DBGLOG(RSN, WARN, ("nicPrivacySetKeyEntry() fail,..\n")); */ -+ -+ /* key update */ -+ prSecInfo->fgKeyStored = FALSE; -+ prSta->fgTransmitKeyExist = TRUE; -+ } -+ if (prSecInfo->eCurrentState == SEC_STATE_INITIATOR_PORT_BLOCKED) -+ SEC_STATE_TRANSITION(prAdapter, prSta, INITIATOR_PORT_BLOCKED, CHECK_OK); -+ break; -+ default: -+ -+#if DBG -+ DBGLOG(RSN, WARN, "Rcv thh EAPoL Tx done at %s\n", apucDebugSecState[prSecInfo->eCurrentState]); -+#else -+ DBGLOG(RSN, WARN, "Rcv thh EAPoL Tx done at [%d]\n", prSecInfo->eCurrentState); -+#endif -+ break; -+ } -+ -+ if (prSecInfo->eCurrentState != eNextState) -+ secFsmSteps(prAdapter, prSta, eNextState); -+ -+ return; -+ -+} /* secFsmRunEvent4ndEapolTx */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will indicate an Event of "Pairwise key installed" to SEC FSM. -+* -+* \param[in] prSta Pointer to the Sta record -+* -+* \retval TRUE The key can be installed to HW -+* \retval FALSE The kay conflict with the current key, abort it -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN secFsmEventPTKInstalled(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta) -+{ -+ P_SEC_INFO_T prSecInfo; -+ ENUM_SEC_STATE_T eNextState; -+ BOOLEAN fgStatus = TRUE; -+ BOOLEAN fgIsTransition = (BOOLEAN) FALSE; -+ -+ ASSERT(prSta); -+ -+ prSecInfo = &prSta->rSecInfo; -+ if (prSecInfo == NULL) -+ return TRUE; /* Not PTK */ -+ -+#if DBG -+ DBGLOG(RSN, TRACE, "%pM Sec state %s\n", prSta->aucMacAdd), -+ apucDebugSecState[prSecInfo->eCurrentState]); -+#else -+ DBGLOG(RSN, TRACE, "%pM Sec state [%d]\n", prSta->aucMacAddr, prSecInfo->eCurrentState); -+#endif -+ -+ eNextState = prSecInfo->eCurrentState; -+ -+ switch (prSecInfo->eCurrentState) { -+ case SEC_STATE_INIT: -+ /* Legacy wep, wpa-none */ -+ break; -+ -+ case SEC_STATE_INITIATOR_PORT_BLOCKED: -+ if (prSecInfo->fg2nd1xSend) -+ ; -+ else -+ SEC_STATE_TRANSITION(prAdapter, prSta, INITIATOR_PORT_BLOCKED, CHECK_OK); -+ break; -+ -+ case SEC_STATE_RESPONDER_PORT_BLOCKED: -+ SEC_STATE_TRANSITION(prAdapter, prSta, RESPONDER_PORT_BLOCKED, CHECK_OK); -+ break; -+ -+ case SEC_STATE_CHECK_OK: -+ break; -+ -+ default: -+ fgStatus = FALSE; -+ break; -+ } -+ -+ if (prSecInfo->eCurrentState != eNextState) -+ secFsmSteps(prAdapter, prSta, eNextState); -+ -+ return fgStatus; -+ -+} /* end of secFsmRunEventPTKInstalled() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will indicate an Event of "Counter Measure" to SEC FSM. -+* -+* \param[in] prSta Pointer to the Sta record -+* -+* \return - -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID secFsmEventStartCounterMeasure(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta) -+{ -+ P_SEC_INFO_T prSecInfo; -+ ENUM_SEC_STATE_T eNextState; -+ BOOLEAN fgIsTransition = (BOOLEAN) FALSE; -+ -+ DEBUGFUNC("secFsmRunEventStartCounterMeasure"); -+ -+ ASSERT(prSta); -+ -+ if (!IS_STA_IN_AIS(prSta)) { -+ DBGLOG(RSN, INFO, "Counter Measure should occur at AIS network!!\n"); -+ /* ASSERT(0); */ -+ return; -+ } -+ -+ prSecInfo = &prSta->rSecInfo; -+ -+ eNextState = prSecInfo->eCurrentState; -+ -+#if DBG -+ DBGLOG(RSN, TRACE, "%pM Sec state %s\n", prSta->aucMacAddr, -+ apucDebugSecState[prSecInfo->eCurrentState]); -+#else -+ DBGLOG(RSN, TRACE, "%pM Sec state [%d]\n", prSta->aucMacAddr, prSecInfo->eCurrentState); -+#endif -+ -+ prAdapter->rWifiVar.rAisSpecificBssInfo.u4RsnaLastMICFailTime = 0; -+ -+ switch (prSecInfo->eCurrentState) { -+ case SEC_STATE_CHECK_OK: -+ { -+ prAdapter->rWifiVar.rAisSpecificBssInfo.fgCounterMeasure = TRUE; -+ -+ /* dls port control */ -+ SEC_STATE_TRANSITION(prAdapter, prSta, CHECK_OK, SEND_EAPOL); -+ } -+ break; -+ -+ default: -+ break; -+ } -+ -+ /* Call arbFsmSteps() when we are going to change ARB STATE */ -+ if (prSecInfo->eCurrentState != eNextState) -+ secFsmSteps(prAdapter, prSta, eNextState); -+ -+ return; -+ -+} /* secFsmRunEventStartCounterMeasure */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will indicate an Event of "802.1x EAPoL Tx Done" to Sec FSM. -+* -+* \param[in] prSta Pointer to the Sta record -+* -+* \return - -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+secFsmEventEapolTxDone(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus) -+{ -+ P_SEC_INFO_T prSecInfo; -+ ENUM_SEC_STATE_T eNextState; -+ BOOLEAN fgIsTransition = (BOOLEAN) FALSE; -+ P_AIS_SPECIFIC_BSS_INFO_T prAisBssInfo; -+ -+ DEBUGFUNC("secFsmRunEventEapolTxDone"); -+ -+ ASSERT(prStaRec); -+ -+ if (rTxDoneStatus != TX_RESULT_SUCCESS) { -+ DBGLOG(RSN, INFO, "Error EAPoL fram fail to send!!\n"); -+ /* ASSERT(0); */ -+ return; -+ } -+ -+ if (!IS_STA_IN_AIS(prStaRec)) { -+ DBGLOG(RSN, INFO, "Counter Measure should occur at AIS network!!\n"); -+ /* ASSERT(0); */ -+ return; -+ } -+ -+ prAisBssInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo; -+ -+ ASSERT(prAisBssInfo); -+ -+ prSecInfo = &prStaRec->rSecInfo; -+ eNextState = prSecInfo->eCurrentState; -+ -+#if DBG -+ DBGLOG(RSN, TRACE, "%pM Sec state %s\n", prStaRec->aucMacAddr, -+ apucDebugSecState[prSecInfo->eCurrentState]); -+#else -+ DBGLOG(RSN, TRACE, "%pM Sec state [%d]\n", prStaRec->aucMacAddr, prSecInfo->eCurrentState); -+#endif -+ -+ switch (prSecInfo->eCurrentState) { -+ case SEC_STATE_SEND_EAPOL: -+ if (prAisBssInfo->fgCheckEAPoLTxDone == FALSE) -+ ASSERT(0); -+ -+ prAisBssInfo->fgCheckEAPoLTxDone = FALSE; -+ /* cnmTimerStopTimer(prAdapter, &prAisBssInfo->rRsnaEAPoLReportTimeoutTimer); */ -+ -+ SEC_STATE_TRANSITION(prAdapter, prStaRec, SEND_EAPOL, SEND_DEAUTH); -+ break; -+ default: -+ break; -+ } -+ -+ if (prSecInfo->eCurrentState != eNextState) -+ secFsmSteps(prAdapter, prStaRec, eNextState); -+ -+ return; -+ -+} /* secFsmRunEventEapolTxDone */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will indicate an Event of "Deauth frame Tx Done" to Sec FSM. -+* -+* \param[in] pMsduInfo Pointer to the Msdu Info -+* \param[in] rStatus The Tx done status -+* -+* \return - -+* -+* \note after receive deauth frame, callback function call this -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+secFsmEventDeauthTxDone(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus) -+{ -+ P_STA_RECORD_T prStaRec; -+ P_SEC_INFO_T prSecInfo; -+ ENUM_SEC_STATE_T eNextState; -+ BOOLEAN fgIsTransition = (BOOLEAN) FALSE; -+ -+ DEBUGFUNC("secFsmRunEventDeauthTxDone"); -+ -+ ASSERT(prMsduInfo); -+ -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); -+ -+ ASSERT(prStaRec); -+ -+ if (!prStaRec) -+ return; -+ -+ if (!IS_STA_IN_AIS(prStaRec)) { -+ DBGLOG(RSN, INFO, "Counter Measure should occur at AIS network!!\n"); -+ /* ASSERT(0); */ -+ return; -+ } -+ -+ prSecInfo = (P_SEC_INFO_T) &prStaRec->rSecInfo; -+ -+#if DBG -+ DBGLOG(RSN, TRACE, "%pM Sec state %s\n", prStaRec->aucMacAddr, -+ apucDebugSecState[prSecInfo->eCurrentState]); -+#else -+ DBGLOG(RSN, TRACE, "%pM Sec state [%d]\n", prStaRec->aucMacAddr, prSecInfo->eCurrentState); -+#endif -+ -+ switch (prSecInfo->eCurrentState) { -+ case SEC_STATE_SEND_DEAUTH: -+ -+ DBGLOG(RSN, TRACE, "Set timer %d\n", COUNTER_MEASURE_TIMEOUT_INTERVAL_SEC); -+ -+ SEC_STATE_TRANSITION(prAdapter, prStaRec, SEND_DEAUTH, COUNTERMEASURE); -+ -+ break; -+ -+ default: -+ ASSERT(0); -+ break; -+ } -+ -+} /* secFsmRunEventDeauthTxDone */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will check the eapol error frame fail to send issue. -+* -+* \param[in] prSta Pointer to the Sta record -+* -+* \return - -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID secFsmEventEapolTxTimeout(IN P_ADAPTER_T prAdapter, IN ULONG ulParm) -+{ -+ P_STA_RECORD_T prStaRec; -+ -+ DEBUGFUNC("secFsmRunEventEapolTxTimeout"); -+ -+ prStaRec = (P_STA_RECORD_T) ulParm; -+ -+ ASSERT(prStaRec); -+ -+ /* Todo:: How to handle the Eapol Error fail to send case? */ -+ ASSERT(0); -+ -+ return; -+ -+} /* secFsmEventEapolTxTimeout */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will stop the counterMeasure duration. -+* -+* \param[in] prSta Pointer to the Sta record -+* -+* \return - -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID secFsmEventEndOfCounterMeasure(IN P_ADAPTER_T prAdapter, ULONG ulParm) -+{ -+ P_STA_RECORD_T prSta; -+ P_SEC_INFO_T prSecInfo; -+ ENUM_SEC_STATE_T eNextState; -+ BOOLEAN fgIsTransition = (BOOLEAN) FALSE; -+ -+ DEBUGFUNC("secFsmRunEventEndOfCounterMeasure"); -+ -+ prSta = (P_STA_RECORD_T) ulParm; -+ -+ ASSERT(prSta); -+ -+ if (!IS_STA_IN_AIS(prSta)) { -+ DBGLOG(RSN, INFO, "Counter Measure should occur at AIS network!!\n"); -+ /* ASSERT(0); */ -+ return; -+ } -+ -+ prSecInfo = &prSta->rSecInfo; -+ eNextState = prSecInfo->eCurrentState; -+ -+#if DBG -+ DBGLOG(RSN, TRACE, "%pM Sec state %s\n", prSta->aucMacAddr, -+ apucDebugSecState[prSecInfo->eCurrentState]); -+#else -+ DBGLOG(RSN, TRACE, "%pM Sec state [%d]\n", prSta->aucMacAddr, prSecInfo->eCurrentState); -+#endif -+ -+ switch (prSecInfo->eCurrentState) { -+ case SEC_STATE_SEND_DEAUTH: -+ { -+ prAdapter->rWifiVar.rAisSpecificBssInfo.fgCounterMeasure = FALSE; -+ -+ SEC_STATE_TRANSITION(prAdapter, prSta, COUNTERMEASURE, INIT); -+ } -+ break; -+ -+ default: -+ ASSERT(0); -+ } -+ -+ /* Call arbFsmSteps() when we are going to change ARB STATE */ -+ if (prSecInfo->eCurrentState != eNextState) -+ secFsmSteps(prAdapter, prSta, eNextState); -+ -+} /* end of secFsmRunEventEndOfCounterMeasure */ -+#endif -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/stats.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/stats.c -new file mode 100644 -index 000000000000..ab3fcc028375 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/stats.c -@@ -0,0 +1,1342 @@ -+/* -+** Id: stats.c#1 -+*/ -+ -+/*! \file stats.c -+ \brief This file includes statistics support. -+*/ -+ -+/* -+** Log: stats.c -+ * -+ * 07 17 2014 samp.lin -+ * NULL -+ * Initial version. -+ */ -+ -+/******************************************************************************* -+ * C O M P I L E R F L A G S -+ ******************************************************************************** -+ */ -+ -+/******************************************************************************* -+ * E X T E R N A L R E F E R E N C E S -+ ******************************************************************************** -+ */ -+#include "precomp.h" -+ -+enum EVENT_TYPE { -+ EVENT_RX, -+ EVENT_TX, -+ EVENT_TX_DONE -+}; -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+static void statsInfoEnvDisplay(GLUE_INFO_T *prGlueInfo, UINT8 *prInBuf, UINT32 u4InBufLen); -+ -+static WLAN_STATUS -+statsInfoEnvRequest(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen); -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+UINT_64 u8DrvOwnStart, u8DrvOwnEnd; -+UINT32 u4DrvOwnMax = 0; -+#define CFG_USER_LOAD 0 -+static UINT_16 su2TxDoneCfg = CFG_DHCP | CFG_ICMP | CFG_EAPOL; -+/******************************************************************************* -+* P R I V A T E F U N C T I O N S -+******************************************************************************** -+*/ -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to display all environment log. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prInBuf A pointer to the command string buffer, from u4EventSubId -+* \param[in] u4InBufLen The length of the buffer -+* \param[out] None -+* -+* \retval None -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static void statsInfoEnvDisplay(GLUE_INFO_T *prGlueInfo, UINT8 *prInBuf, UINT32 u4InBufLen) -+{ -+ P_ADAPTER_T prAdapter; -+ STA_RECORD_T *prStaRec; -+ UINT32 u4NumOfInfo, u4InfoId; -+ UINT32 u4RxErrBitmap; -+ STATS_INFO_ENV_T *prInfo; -+ UINT32 u4Total, u4RateId; -+ -+/* -+[wlan] statsInfoEnvRequest: (INIT INFO) statsInfoEnvRequest cmd ok. -+[wlan] statsEventHandle: (INIT INFO) statsEventHandle: Rcv a event -+[wlan] statsEventHandle: (INIT INFO) statsEventHandle: Rcv a event: 0 -+[wlan] statsInfoEnvDisplay: (INIT INFO) Display stats for [00:0c:43:31:35:97]: -+ -+[wlan] statsInfoEnvDisplay: (INIT INFO) TPAM(0x0) RTS(0 0) BA(0x1 0) OK(9 9 xxx) ERR(0 0 0 0 0 0 0) -+ TPAM (bit0: enable 40M, bit1: enable 20 short GI, bit2: enable 40 short GI, -+ bit3: use 40M TX, bit4: use short GI TX, bit5: use no ack) -+ RTS (1st: current use RTS/CTS, 2nd: ever use RTS/CTS) -+ BA (1st: TX session BA bitmap for TID0 ~ TID7, 2nd: peer receive maximum agg number) -+ OK (1st: total number of tx packet from host, 2nd: total number of tx ok, system time last TX OK) -+ ERR (1st: total number of tx err, 2nd ~ 7st: total number of -+ WLAN_STATUS_BUFFER_RETAINED, WLAN_STATUS_PACKET_FLUSHED, WLAN_STATUS_PACKET_AGING_TIMEOUT, -+ WLAN_STATUS_PACKET_MPDU_ERROR, WLAN_STATUS_PACKET_RTS_ERROR, WLAN_STATUS_PACKET_LIFETIME_ERROR) -+ -+[wlan] statsInfoEnvDisplay: (INIT INFO) TRATE (6 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0) (0 0 0 0 0 0 0 3) -+ TX rate count (1M 2 5.5 11 NA NA NA NA 48 24 12 6 54 36 18 9) (MCS0 ~ MCS7) -+ -+[wlan] statsInfoEnvDisplay: (INIT INFO) RX(148 1 0) BA(0x1 64) OK(2 2) ERR(0) -+ RX (1st: latest RCPI, 2nd: chan num) -+ BA (1st: RX session BA bitmap for TID0 ~ TID7, 2nd: our receive maximum agg number) -+ OK (number of rx packets without error, number of rx packets to OS) -+ ERR (number of rx packets with error) -+ -+[wlan] statsInfoEnvDisplay: (INIT INFO) RCCK (0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0) -+ CCK MODE (1 2 5.5 11M) -+[wlan] statsInfoEnvDisplay: (INIT INFO) ROFDM (0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0) -+ OFDM MODE (NA NA NA NA 6 9 12 18 24 36 48 54M) -+[wlan] statsInfoEnvDisplay: (INIT INFO) RHT (0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0) -+ MIXED MODE (number of rx packets with MCS0 ~ MCS15) -+ -+[wlan] statsInfoEnvDisplay: (INIT INFO) StayIntH2M us (29 29 32) (0 0 0) (0 0 0) -+ delay from HIF to MAC own bit=1 (min, avg, max for 500B) (min, avg, max for 1000B) (min, avg, max for others) -+ -+[wlan] statsInfoEnvDisplay: (INIT INFO) AirTime us (608 864 4480) (0 0 0) (0 0 0) -+ delay from MAC start TX to MAC TX done -+ -+[wlan] statsInfoEnvDisplay: (INIT INFO) StayInt us (795 1052 4644_4504) (0 0 0_0) (0 0 0_0) -+ delay from HIF to MAC TX done (min, avg, max_system time for 500B) -+ -+[wlan] statsInfoEnvDisplay: (INIT INFO) StayIntD2T us (795 1052 4644) (0 0 0) (0 0 0) -+ delay from driver to MAC TX done (min, avg, max for 500B) -+ -+[wlan] statsInfoEnvDisplay: (INIT INFO) StayIntR_M2H us (37 40 58) (0 0 0) (0 0 0) -+ delay from MAC to HIF (min, avg, max for 500B) -+ -+[wlan] statsInfoEnvDisplay: (INIT INFO) StayIntR_H2D us (0 0 0) (0 0 0) (0 0 0) -+ delay from HIF to Driver OS (min, avg, max for 500B) -+ -+[wlan] statsInfoEnvDisplay: (INIT INFO) StayCntD2H unit:10ms (10 0 0 0) -+ delay count from Driver to HIF (count in 0~10ms, 10~20ms, 20~30ms, others) -+ -+[wlan] statsInfoEnvDisplay: (INIT INFO) StayCnt unit:1ms (6 3 0 1) -+ delay count from HIF to TX DONE (count in 0~1ms, 1~5ms, 5~10ms, others) -+ -+[wlan] statsInfoEnvDisplay: (INIT INFO) StayCnt (0~1161:7) (1161~2322:2) (2322~3483:0) (3483~4644:0) (4644~:1) -+ delay count from HIF to TX DONE (count in 0~1161 ticks, 1161~2322, 2322~3483, 3483~4644, others) -+ -+[wlan] statsInfoEnvDisplay: (INIT INFO) OTHER (61877) (0) (38) (0) (0) (0ms) -+ Channel idle time, scan count, channel change count, empty tx quota count, -+ power save change count from active to PS, maximum delay from PS to active -+*/ -+ -+ /* init */ -+ prAdapter = prGlueInfo->prAdapter; -+ /*prInfo = &rStatsInfoEnv;*/ -+ prInfo = kalMemAlloc(sizeof(STATS_INFO_ENV_T), VIR_MEM_TYPE); -+ if (prInfo == NULL) { -+ DBGLOG(RX, INFO, "prInfo alloc fail"); -+ return; -+ } -+ -+ kalMemZero(prInfo, sizeof(STATS_INFO_ENV_T)); -+ -+ if (u4InBufLen > sizeof(STATS_INFO_ENV_T)) -+ u4InBufLen = sizeof(STATS_INFO_ENV_T); -+ -+ /* parse */ -+ u4NumOfInfo = *(UINT32 *) prInBuf; -+ u4RxErrBitmap = *(UINT32 *) (prInBuf + 4); -+ -+ /* print */ -+ for (u4InfoId = 0; u4InfoId < u4NumOfInfo; u4InfoId++) { -+ /* -+ use u4InBufLen, not sizeof(rStatsInfoEnv) -+ because the firmware version maybe not equal to driver version -+ */ -+ kalMemCopy(prInfo, prInBuf + 8, u4InBufLen); -+ -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prInfo->ucStaRecIdx); -+ if (prStaRec == NULL) -+ continue; -+ -+ DBGLOG(RX, INFO, " Display stats for [%pM]: %uB\n", -+ prStaRec->aucMacAddr, (UINT32) sizeof(STATS_INFO_ENV_T)); -+ -+ if (prStaRec->ucStatsGenDisplayCnt++ > 10) { -+ /* display general statistics information every 10 * (5 or 10s) */ -+ DBGLOG(RX, INFO, " TBA(0x%x %u) RBA(0x%x %u)\n", -+ prInfo->ucTxAggBitmap, prInfo->ucTxPeerAggMaxSize, -+ prInfo->ucRxAggBitmap, prInfo->ucRxAggMaxSize); -+ prStaRec->ucStatsGenDisplayCnt = 0; -+ } -+ -+ if (prInfo->u4TxDataCntErr == 0) { -+ DBGLOG(RX, INFO, " TOS(%u) OK(%u %u)\n", -+ (UINT32) prGlueInfo->rNetDevStats.tx_packets, -+ prInfo->u4TxDataCntAll, prInfo->u4TxDataCntOK); -+ } else { -+ DBGLOG(RX, INFO, " TOS(%u) OK(%u %u) ERR(%u)\n", -+ (UINT32) prGlueInfo->rNetDevStats.tx_packets, -+ prInfo->u4TxDataCntAll, prInfo->u4TxDataCntOK, prInfo->u4TxDataCntErr); -+ DBGLOG(RX, INFO, " ERR type(%u %u %u %u %u %u)\n", -+ prInfo->u4TxDataCntErrType[0], prInfo->u4TxDataCntErrType[1], -+ prInfo->u4TxDataCntErrType[2], prInfo->u4TxDataCntErrType[3], -+ prInfo->u4TxDataCntErrType[4], prInfo->u4TxDataCntErrType[5]); -+ } -+ -+ for (u4RateId = 1, u4Total = 0; u4RateId < 16; u4RateId++) -+ u4Total += prInfo->u4TxRateCntNonHT[u4RateId]; -+ if (u4Total > 0) { -+ DBGLOG(RX, INFO, " non-HT TRATE (%u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u)\n", -+ prInfo->u4TxRateCntNonHT[0], prInfo->u4TxRateCntNonHT[1], -+ prInfo->u4TxRateCntNonHT[2], prInfo->u4TxRateCntNonHT[3], -+ prInfo->u4TxRateCntNonHT[4], prInfo->u4TxRateCntNonHT[5], -+ prInfo->u4TxRateCntNonHT[6], prInfo->u4TxRateCntNonHT[7], -+ prInfo->u4TxRateCntNonHT[8], prInfo->u4TxRateCntNonHT[9], -+ prInfo->u4TxRateCntNonHT[10], prInfo->u4TxRateCntNonHT[11], -+ prInfo->u4TxRateCntNonHT[12], prInfo->u4TxRateCntNonHT[13], -+ prInfo->u4TxRateCntNonHT[14], prInfo->u4TxRateCntNonHT[15]); -+ } -+ if (prInfo->u4TxRateCntNonHT[0] > 0) { -+ DBGLOG(RX, INFO, " HT TRATE (1M %u) (%u %u %u %u %u %u %u %u)\n", -+ prInfo->u4TxRateCntNonHT[0], -+ prInfo->u4TxRateCntHT[0], prInfo->u4TxRateCntHT[1], -+ prInfo->u4TxRateCntHT[2], prInfo->u4TxRateCntHT[3], -+ prInfo->u4TxRateCntHT[4], prInfo->u4TxRateCntHT[5], -+ prInfo->u4TxRateCntHT[6], prInfo->u4TxRateCntHT[7]); -+ } else { -+ DBGLOG(RX, INFO, " HT TRATE (%u %u %u %u %u %u %u %u)\n", -+ prInfo->u4TxRateCntHT[0], prInfo->u4TxRateCntHT[1], -+ prInfo->u4TxRateCntHT[2], prInfo->u4TxRateCntHT[3], -+ prInfo->u4TxRateCntHT[4], prInfo->u4TxRateCntHT[5], -+ prInfo->u4TxRateCntHT[6], prInfo->u4TxRateCntHT[7]); -+ } -+ -+ if ((prStaRec->u4RxReorderFallAheadCnt != 0) || -+ (prStaRec->u4RxReorderFallBehindCnt != 0) || (prStaRec->u4RxReorderHoleCnt != 0)) { -+ DBGLOG(RX, INFO, " TREORDER (%u %u %u)\n", -+ prStaRec->u4RxReorderFallAheadCnt, -+ prStaRec->u4RxReorderFallBehindCnt, prStaRec->u4RxReorderHoleCnt); -+ } -+ -+ if (prInfo->u4RxDataCntErr == 0) { -+ DBGLOG(RX, INFO, " ROK(%u %u)\n", -+ prInfo->u4RxDataCntAll, prStaRec->u4StatsRxPassToOsCnt); -+ } else { -+ DBGLOG(RX, INFO, " ROK(%u %u) ERR(%u)\n", -+ prInfo->u4RxDataCntAll, prStaRec->u4StatsRxPassToOsCnt, -+ prInfo->u4RxDataCntErr); -+ } -+ -+ for (u4RateId = 1, u4Total = 0; u4RateId < 16; u4RateId++) -+ u4Total += prInfo->u4RxRateCnt[0][u4RateId] + prInfo->u4RxRateRetryCnt[0][u4RateId]; -+ if (u4Total > 0) { -+ for (u4RateId = 0, u4Total = 0; u4RateId < 16; u4RateId++) -+ u4Total += prInfo->u4RxRateRetryCnt[0][u4RateId]; -+ if (u4Total > 0) { -+ DBGLOG(RX, INFO, -+ " RCCK (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u)\n" -+ "(%u %u)(%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u)\n", -+ prInfo->u4RxRateCnt[0][0], prInfo->u4RxRateRetryCnt[0][0], -+ prInfo->u4RxRateCnt[0][1], prInfo->u4RxRateRetryCnt[0][1], -+ prInfo->u4RxRateCnt[0][2], prInfo->u4RxRateRetryCnt[0][2], -+ prInfo->u4RxRateCnt[0][3], prInfo->u4RxRateRetryCnt[0][3], -+ prInfo->u4RxRateCnt[0][4], prInfo->u4RxRateRetryCnt[0][4], -+ prInfo->u4RxRateCnt[0][5], prInfo->u4RxRateRetryCnt[0][5], -+ prInfo->u4RxRateCnt[0][6], prInfo->u4RxRateRetryCnt[0][6], -+ prInfo->u4RxRateCnt[0][7], prInfo->u4RxRateRetryCnt[0][7], -+ prInfo->u4RxRateCnt[0][8], prInfo->u4RxRateRetryCnt[0][8], -+ prInfo->u4RxRateCnt[0][9], prInfo->u4RxRateRetryCnt[0][9], -+ prInfo->u4RxRateCnt[0][10], prInfo->u4RxRateRetryCnt[0][10], -+ prInfo->u4RxRateCnt[0][11], prInfo->u4RxRateRetryCnt[0][11], -+ prInfo->u4RxRateCnt[0][12], prInfo->u4RxRateRetryCnt[0][12], -+ prInfo->u4RxRateCnt[0][13], prInfo->u4RxRateRetryCnt[0][13], -+ prInfo->u4RxRateCnt[0][14], prInfo->u4RxRateRetryCnt[0][14], -+ prInfo->u4RxRateCnt[0][15], prInfo->u4RxRateRetryCnt[0][15]); -+ } else { -+ DBGLOG(RX, INFO, " RCCK (%u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u)\n", -+ prInfo->u4RxRateCnt[0][0], -+ prInfo->u4RxRateCnt[0][1], -+ prInfo->u4RxRateCnt[0][2], -+ prInfo->u4RxRateCnt[0][3], -+ prInfo->u4RxRateCnt[0][4], -+ prInfo->u4RxRateCnt[0][5], -+ prInfo->u4RxRateCnt[0][6], -+ prInfo->u4RxRateCnt[0][7], -+ prInfo->u4RxRateCnt[0][8], -+ prInfo->u4RxRateCnt[0][9], -+ prInfo->u4RxRateCnt[0][10], -+ prInfo->u4RxRateCnt[0][11], -+ prInfo->u4RxRateCnt[0][12], -+ prInfo->u4RxRateCnt[0][13], -+ prInfo->u4RxRateCnt[0][14], prInfo->u4RxRateCnt[0][15]); -+ } -+ } else { -+ if ((prInfo->u4RxRateCnt[0][0] + prInfo->u4RxRateRetryCnt[0][0]) > 0) { -+ DBGLOG(RX, INFO, " RCCK (%u %u)\n", -+ prInfo->u4RxRateCnt[0][0], prInfo->u4RxRateRetryCnt[0][0]); -+ } -+ } -+ -+ for (u4RateId = 0, u4Total = 0; u4RateId < 16; u4RateId++) -+ u4Total += prInfo->u4RxRateCnt[1][u4RateId] + prInfo->u4RxRateRetryCnt[1][u4RateId]; -+ if (u4Total > 0) { -+ for (u4RateId = 0, u4Total = 0; u4RateId < 16; u4RateId++) -+ u4Total += prInfo->u4RxRateRetryCnt[1][u4RateId]; -+ if (u4Total > 0) { -+ DBGLOG(RX, INFO, -+ " ROFDM (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u)\n" -+ "(%u %u)(%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u)\n", -+ prInfo->u4RxRateCnt[1][0], prInfo->u4RxRateRetryCnt[1][0], -+ prInfo->u4RxRateCnt[1][1], prInfo->u4RxRateRetryCnt[1][1], -+ prInfo->u4RxRateCnt[1][2], prInfo->u4RxRateRetryCnt[1][2], -+ prInfo->u4RxRateCnt[1][3], prInfo->u4RxRateRetryCnt[1][3], -+ prInfo->u4RxRateCnt[1][4], prInfo->u4RxRateRetryCnt[1][4], -+ prInfo->u4RxRateCnt[1][5], prInfo->u4RxRateRetryCnt[1][5], -+ prInfo->u4RxRateCnt[1][6], prInfo->u4RxRateRetryCnt[1][6], -+ prInfo->u4RxRateCnt[1][7], prInfo->u4RxRateRetryCnt[1][7], -+ prInfo->u4RxRateCnt[1][8], prInfo->u4RxRateRetryCnt[1][8], -+ prInfo->u4RxRateCnt[1][9], prInfo->u4RxRateRetryCnt[1][9], -+ prInfo->u4RxRateCnt[1][10], prInfo->u4RxRateRetryCnt[1][10], -+ prInfo->u4RxRateCnt[1][11], prInfo->u4RxRateRetryCnt[1][11], -+ prInfo->u4RxRateCnt[1][12], prInfo->u4RxRateRetryCnt[1][12], -+ prInfo->u4RxRateCnt[1][13], prInfo->u4RxRateRetryCnt[1][13], -+ prInfo->u4RxRateCnt[1][14], prInfo->u4RxRateRetryCnt[1][14], -+ prInfo->u4RxRateCnt[1][15], prInfo->u4RxRateRetryCnt[1][15]); -+ } else { -+ DBGLOG(RX, INFO, " ROFDM (%u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u)\n", -+ prInfo->u4RxRateCnt[1][0], -+ prInfo->u4RxRateCnt[1][1], -+ prInfo->u4RxRateCnt[1][2], -+ prInfo->u4RxRateCnt[1][3], -+ prInfo->u4RxRateCnt[1][4], -+ prInfo->u4RxRateCnt[1][5], -+ prInfo->u4RxRateCnt[1][6], -+ prInfo->u4RxRateCnt[1][7], -+ prInfo->u4RxRateCnt[1][8], -+ prInfo->u4RxRateCnt[1][9], -+ prInfo->u4RxRateCnt[1][10], -+ prInfo->u4RxRateCnt[1][11], -+ prInfo->u4RxRateCnt[1][12], -+ prInfo->u4RxRateCnt[1][13], -+ prInfo->u4RxRateCnt[1][14], prInfo->u4RxRateCnt[1][15]); -+ } -+ } -+ -+ for (u4RateId = 0, u4Total = 0; u4RateId < 16; u4RateId++) -+ u4Total += prInfo->u4RxRateCnt[2][u4RateId] + prInfo->u4RxRateRetryCnt[2][u4RateId]; -+ if (u4Total > 0) { -+ for (u4RateId = 0, u4Total = 0; u4RateId < 16; u4RateId++) -+ u4Total += prInfo->u4RxRateRetryCnt[2][u4RateId]; -+ if (u4Total > 0) { -+ DBGLOG(RX, INFO, " RHT\n" -+ "(%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u)\n", -+ prInfo->u4RxRateCnt[2][0], prInfo->u4RxRateRetryCnt[2][0], -+ prInfo->u4RxRateCnt[2][1], prInfo->u4RxRateRetryCnt[2][1], -+ prInfo->u4RxRateCnt[2][2], prInfo->u4RxRateRetryCnt[2][2], -+ prInfo->u4RxRateCnt[2][3], prInfo->u4RxRateRetryCnt[2][3], -+ prInfo->u4RxRateCnt[2][4], prInfo->u4RxRateRetryCnt[2][4], -+ prInfo->u4RxRateCnt[2][5], prInfo->u4RxRateRetryCnt[2][5], -+ prInfo->u4RxRateCnt[2][6], prInfo->u4RxRateRetryCnt[2][6], -+ prInfo->u4RxRateCnt[2][7], prInfo->u4RxRateRetryCnt[2][7]); -+ } else { -+ DBGLOG(RX, INFO, " RHT (%u %u %u %u %u %u %u %u)\n", -+ prInfo->u4RxRateCnt[2][0], -+ prInfo->u4RxRateCnt[2][1], -+ prInfo->u4RxRateCnt[2][2], -+ prInfo->u4RxRateCnt[2][3], -+ prInfo->u4RxRateCnt[2][4], -+ prInfo->u4RxRateCnt[2][5], -+ prInfo->u4RxRateCnt[2][6], prInfo->u4RxRateCnt[2][7]); -+ } -+ } -+ -+ /* RX drop counts */ -+ for (u4RateId = 0, u4Total = 0; u4RateId < 20; u4RateId++) -+ u4Total += prInfo->u4NumOfRxDrop[u4RateId]; -+ if (u4Total > 0) { -+ DBGLOG(RX, INFO, " RX Drop Count: (%u) (%u) (%u) (%u) (%u) (%u) (%u) (%u)\n" -+ " (%u) (%u) (%u) (%u) (%u) (%u) (%u) (%u) (%u) (%u) (%u) (%u)\n", -+ prInfo->u4NumOfRxDrop[0], prInfo->u4NumOfRxDrop[1], -+ prInfo->u4NumOfRxDrop[2], prInfo->u4NumOfRxDrop[3], -+ prInfo->u4NumOfRxDrop[4], prInfo->u4NumOfRxDrop[5], -+ prInfo->u4NumOfRxDrop[6], prInfo->u4NumOfRxDrop[7], -+ prInfo->u4NumOfRxDrop[8], prInfo->u4NumOfRxDrop[9], -+ prInfo->u4NumOfRxDrop[10], prInfo->u4NumOfRxDrop[11], -+ prInfo->u4NumOfRxDrop[12], prInfo->u4NumOfRxDrop[13], -+ prInfo->u4NumOfRxDrop[14], prInfo->u4NumOfRxDrop[15], -+ prInfo->u4NumOfRxDrop[16], prInfo->u4NumOfRxDrop[17], -+ prInfo->u4NumOfRxDrop[18], prInfo->u4NumOfRxDrop[19]); -+ } -+ -+ /* delay from HIF RX to HIF RX Done */ -+ if (((prInfo->u4StayIntMinHR2HRD[1] + prInfo->u4StayIntAvgHR2HRD[1] + -+ prInfo->u4StayIntMaxHR2HRD[1]) > 0) || -+ ((prInfo->u4StayIntMinHR2HRD[2] + prInfo->u4StayIntAvgHR2HRD[2] + -+ prInfo->u4StayIntMaxHR2HRD[2]) > 0)) { -+ DBGLOG(RX, INFO, " StayIntR_HR2HRD us (%u %u %u) (%u %u %u) (%u %u %u)\n", -+ prInfo->u4StayIntMinHR2HRD[0], prInfo->u4StayIntAvgHR2HRD[0], -+ prInfo->u4StayIntMaxHR2HRD[0], -+ prInfo->u4StayIntMinHR2HRD[1], prInfo->u4StayIntAvgHR2HRD[1], -+ prInfo->u4StayIntMaxHR2HRD[1], -+ prInfo->u4StayIntMinHR2HRD[2], prInfo->u4StayIntAvgHR2HRD[2], -+ prInfo->u4StayIntMaxHR2HRD[2]); -+ } else { -+ DBGLOG(RX, INFO, " StayIntR_HR2HRD us (%u %u %u)\n", -+ prInfo->u4StayIntMinHR2HRD[0], prInfo->u4StayIntAvgHR2HRD[0], -+ prInfo->u4StayIntMaxHR2HRD[0]); -+ } -+ -+ /* others */ -+ DBGLOG(RX, INFO, " OTHER (%u) (%u) (%u) (%x)\n", -+ prInfo->u4RxFifoFullCnt, prAdapter->ucScanTime, -+ prInfo->u4NumOfChanChange, prInfo->u4CurrChnlInfo); -+#if CFG_SUPPORT_THERMO_THROTTLING -+ prAdapter->u4AirDelayTotal = (prInfo->u4AirDelayTotal << 5) / 400000; -+#endif -+ /* reset */ -+ kalMemZero(prStaRec->u4StayIntMinRx, sizeof(prStaRec->u4StayIntMinRx)); -+ kalMemZero(prStaRec->u4StayIntAvgRx, sizeof(prStaRec->u4StayIntAvgRx)); -+ kalMemZero(prStaRec->u4StayIntMaxRx, sizeof(prStaRec->u4StayIntMaxRx)); -+ prStaRec->u4StatsRxPassToOsCnt = 0; -+ prStaRec->u4RxReorderFallAheadCnt = 0; -+ prStaRec->u4RxReorderFallBehindCnt = 0; -+ prStaRec->u4RxReorderHoleCnt = 0; -+ } -+ -+ STATS_DRIVER_OWN_RESET(); -+ kalMemFree(prInfo, VIR_MEM_TYPE, sizeof(STATS_INFO_ENV_T)); -+} -+ -+#if 0 -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to display all environment log. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prInBuf A pointer to the command string buffer, from u4EventSubId -+* \param[in] u4InBufLen The length of the buffer -+* \param[out] None -+* -+* \retval None -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static void statsInfoEnvDisplay(GLUE_INFO_T *prGlueInfo, UINT8 *prInBuf, UINT32 u4InBufLen) -+{ -+ P_ADAPTER_T prAdapter; -+ STA_RECORD_T *prStaRec; -+ UINT32 u4NumOfInfo, u4InfoId; -+ UINT32 u4RxErrBitmap; -+ STATS_INFO_ENV_T rStatsInfoEnv, *prInfo; -+ -+/* -+[wlan] statsInfoEnvRequest: (INIT INFO) statsInfoEnvRequest cmd ok. -+[wlan] statsEventHandle: (INIT INFO) statsEventHandle: Rcv a event -+[wlan] statsEventHandle: (INIT INFO) statsEventHandle: Rcv a event: 0 -+[wlan] statsInfoEnvDisplay: (INIT INFO) Display stats for [00:0c:43:31:35:97]: -+ -+[wlan] statsInfoEnvDisplay: (INIT INFO) TPAM(0x0) RTS(0 0) BA(0x1 0) OK(9 9 xxx) ERR(0 0 0 0 0 0 0) -+ TPAM (bit0: enable 40M, bit1: enable 20 short GI, bit2: enable 40 short GI, -+ bit3: use 40M TX, bit4: use short GI TX, bit5: use no ack) -+ RTS (1st: current use RTS/CTS, 2nd: ever use RTS/CTS) -+ BA (1st: TX session BA bitmap for TID0 ~ TID7, 2nd: peer receive maximum agg number) -+ OK (1st: total number of tx packet from host, 2nd: total number of tx ok, system time last TX OK) -+ ERR (1st: total number of tx err, 2nd ~ 7st: total number of -+ WLAN_STATUS_BUFFER_RETAINED, WLAN_STATUS_PACKET_FLUSHED, WLAN_STATUS_PACKET_AGING_TIMEOUT, -+ WLAN_STATUS_PACKET_MPDU_ERROR, WLAN_STATUS_PACKET_RTS_ERROR, WLAN_STATUS_PACKET_LIFETIME_ERROR) -+ -+[wlan] statsInfoEnvDisplay: (INIT INFO) TRATE (6 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0) (0 0 0 0 0 0 0 3) -+ TX rate count (1M 2 5.5 11 NA NA NA NA 48 24 12 6 54 36 18 9) (MCS0 ~ MCS7) -+ -+[wlan] statsInfoEnvDisplay: (INIT INFO) RX(148 1 0) BA(0x1 64) OK(2 2) ERR(0) -+ RX (1st: latest RCPI, 2nd: chan num) -+ BA (1st: RX session BA bitmap for TID0 ~ TID7, 2nd: our receive maximum agg number) -+ OK (number of rx packets without error, number of rx packets to OS) -+ ERR (number of rx packets with error) -+ -+[wlan] statsInfoEnvDisplay: (INIT INFO) RCCK (0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0) -+ CCK MODE (1 2 5.5 11M) -+[wlan] statsInfoEnvDisplay: (INIT INFO) ROFDM (0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0) -+ OFDM MODE (NA NA NA NA 6 9 12 18 24 36 48 54M) -+[wlan] statsInfoEnvDisplay: (INIT INFO) RHT (0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0) -+ MIXED MODE (number of rx packets with MCS0 ~ MCS15) -+ -+[wlan] statsInfoEnvDisplay: (INIT INFO) StayIntH2M us (29 29 32) (0 0 0) (0 0 0) -+ delay from HIF to MAC own bit=1 (min, avg, max for 500B) (min, avg, max for 1000B) (min, avg, max for others) -+ -+[wlan] statsInfoEnvDisplay: (INIT INFO) AirTime us (608 864 4480) (0 0 0) (0 0 0) -+ delay from MAC start TX to MAC TX done -+ -+[wlan] statsInfoEnvDisplay: (INIT INFO) StayInt us (795 1052 4644_4504) (0 0 0_0) (0 0 0_0) -+ delay from HIF to MAC TX done (min, avg, max_system time for 500B) -+ -+[wlan] statsInfoEnvDisplay: (INIT INFO) StayIntD2T us (795 1052 4644) (0 0 0) (0 0 0) -+ delay from driver to MAC TX done (min, avg, max for 500B) -+ -+[wlan] statsInfoEnvDisplay: (INIT INFO) StayIntR_M2H us (37 40 58) (0 0 0) (0 0 0) -+ delay from MAC to HIF (min, avg, max for 500B) -+ -+[wlan] statsInfoEnvDisplay: (INIT INFO) StayIntR_H2D us (0 0 0) (0 0 0) (0 0 0) -+ delay from HIF to Driver OS (min, avg, max for 500B) -+ -+[wlan] statsInfoEnvDisplay: (INIT INFO) StayCntD2H unit:10ms (10 0 0 0) -+ delay count from Driver to HIF (count in 0~10ms, 10~20ms, 20~30ms, others) -+ -+[wlan] statsInfoEnvDisplay: (INIT INFO) StayCnt unit:1ms (6 3 0 1) -+ delay count from HIF to TX DONE (count in 0~1ms, 1~5ms, 5~10ms, others) -+ -+[wlan] statsInfoEnvDisplay: (INIT INFO) StayCnt (0~1161:7) (1161~2322:2) (2322~3483:0) (3483~4644:0) (4644~:1) -+ delay count from HIF to TX DONE (count in 0~1161 ticks, 1161~2322, 2322~3483, 3483~4644, others) -+ -+[wlan] statsInfoEnvDisplay: (INIT INFO) OTHER (61877) (0) (38) (0) (0) (0ms) -+ Channel idle time, scan count, channel change count, empty tx quota count, -+ power save change count from active to PS, maximum delay from PS to active -+*/ -+ -+ /* init */ -+ prAdapter = prGlueInfo->prAdapter; -+ prInfo = &rStatsInfoEnv; -+ kalMemZero(&rStatsInfoEnv, sizeof(rStatsInfoEnv)); -+ -+ if (u4InBufLen > sizeof(rStatsInfoEnv)) -+ u4InBufLen = sizeof(rStatsInfoEnv); -+ -+ /* parse */ -+ u4NumOfInfo = *(UINT32 *) prInBuf; -+ u4RxErrBitmap = *(UINT32 *) (prInBuf + 4); -+ -+ /* print */ -+ for (u4InfoId = 0; u4InfoId < u4NumOfInfo; u4InfoId++) { -+ /* -+ use u4InBufLen, not sizeof(rStatsInfoEnv) -+ because the firmware version maybe not equal to driver version -+ */ -+ kalMemCopy(&rStatsInfoEnv, prInBuf + 8, u4InBufLen); -+ -+ prStaRec = cnmGetStaRecByIndex(prAdapter, rStatsInfoEnv.ucStaRecIdx); -+ if (prStaRec == NULL) -+ continue; -+ -+ DBGLOG(RX, INFO, " Display stats V%d.%d for [%pM]: %uB %ums\n", -+ prInfo->ucFwVer[0], prInfo->ucFwVer[1], -+ (prStaRec->aucMacAddr), (UINT32) sizeof(STATS_INFO_ENV_T), -+ prInfo->u4ReportSysTime); -+ DBGLOG(RX, INFO, "TPAM(0x%x)RTS(%u %u)BA(0x%x %u)OS(%u)OK(%u %u)ERR(%u %u %u %u %u %u %u)\n", -+ prInfo->ucTxParam, -+ prInfo->fgTxIsRtsUsed, prInfo->fgTxIsRtsEverUsed, -+ prInfo->ucTxAggBitmap, prInfo->ucTxPeerAggMaxSize, -+ (UINT32) prGlueInfo->rNetDevStats.tx_packets, -+ prInfo->u4TxDataCntAll, prInfo->u4TxDataCntOK, -+ prInfo->u4TxDataCntErr, prInfo->u4TxDataCntErrType[0], -+ prInfo->u4TxDataCntErrType[1], prInfo->u4TxDataCntErrType[2], -+ prInfo->u4TxDataCntErrType[3], prInfo->u4TxDataCntErrType[4], -+ prInfo->u4TxDataCntErrType[5])); -+ -+ DBGLOG(RX, INFO, "TRATE(%u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u)\n", -+ prInfo->u4TxRateCntNonHT[0], prInfo->u4TxRateCntNonHT[1], -+ prInfo->u4TxRateCntNonHT[2], prInfo->u4TxRateCntNonHT[3], -+ prInfo->u4TxRateCntNonHT[4], prInfo->u4TxRateCntNonHT[5], -+ prInfo->u4TxRateCntNonHT[6], prInfo->u4TxRateCntNonHT[7], -+ prInfo->u4TxRateCntNonHT[8], prInfo->u4TxRateCntNonHT[9], -+ prInfo->u4TxRateCntNonHT[10], prInfo->u4TxRateCntNonHT[11], -+ prInfo->u4TxRateCntNonHT[12], prInfo->u4TxRateCntNonHT[13], -+ prInfo->u4TxRateCntNonHT[14], prInfo->u4TxRateCntNonHT[15], -+ prInfo->u4TxRateCntHT[0], prInfo->u4TxRateCntHT[1], -+ prInfo->u4TxRateCntHT[2], prInfo->u4TxRateCntHT[3], -+ prInfo->u4TxRateCntHT[4], prInfo->u4TxRateCntHT[5], -+ prInfo->u4TxRateCntHT[6], prInfo->u4TxRateCntHT[7])); -+ -+ DBGLOG(RX, INFO, " TREORDER (%u %u %u)\n", -+ prStaRec->u4RxReorderFallAheadCnt, -+ prStaRec->u4RxReorderFallBehindCnt, prStaRec->u4RxReorderHoleCnt); -+ -+ DBGLOG(RX, INFO, " RX(%u %u %u) BA(0x%x %u) OK(%u %u) ERR(%u)\n", -+ prInfo->ucRcvRcpi, prInfo->ucHwChanNum, prInfo->fgRxIsShortGI, -+ prInfo->ucRxAggBitmap, prInfo->ucRxAggMaxSize, -+ prInfo->u4RxDataCntAll, prStaRec->u4StatsRxPassToOsCnt, prInfo->u4RxDataCntErr); -+ -+ DBGLOG(RX, INFO, " RX Free MAC DESC(%u %u %u %u %u %u) Free HIF DESC(%u %u %u %u %u %u)\n", -+ prInfo->u4RxMacFreeDescCnt[0], prInfo->u4RxMacFreeDescCnt[1], -+ prInfo->u4RxMacFreeDescCnt[2], prInfo->u4RxMacFreeDescCnt[3], -+ prInfo->u4RxMacFreeDescCnt[4], prInfo->u4RxMacFreeDescCnt[5], -+ prInfo->u4RxHifFreeDescCnt[0], prInfo->u4RxHifFreeDescCnt[1], -+ prInfo->u4RxHifFreeDescCnt[2], prInfo->u4RxHifFreeDescCnt[3], -+ prInfo->u4RxHifFreeDescCnt[4], prInfo->u4RxHifFreeDescCnt[5])); -+ -+ DBGLOG(RX, INFO, " RCCK (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u)\n" -+ "(%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u)\n", -+ prInfo->u4RxRateCnt[0][0], prInfo->u4RxRateRetryCnt[0][0], -+ prInfo->u4RxRateCnt[0][1], prInfo->u4RxRateRetryCnt[0][1], -+ prInfo->u4RxRateCnt[0][2], prInfo->u4RxRateRetryCnt[0][2], -+ prInfo->u4RxRateCnt[0][3], prInfo->u4RxRateRetryCnt[0][3], -+ prInfo->u4RxRateCnt[0][4], prInfo->u4RxRateRetryCnt[0][4], -+ prInfo->u4RxRateCnt[0][5], prInfo->u4RxRateRetryCnt[0][5], -+ prInfo->u4RxRateCnt[0][6], prInfo->u4RxRateRetryCnt[0][6], -+ prInfo->u4RxRateCnt[0][7], prInfo->u4RxRateRetryCnt[0][7], -+ prInfo->u4RxRateCnt[0][8], prInfo->u4RxRateRetryCnt[0][8], -+ prInfo->u4RxRateCnt[0][9], prInfo->u4RxRateRetryCnt[0][9], -+ prInfo->u4RxRateCnt[0][10], prInfo->u4RxRateRetryCnt[0][10], -+ prInfo->u4RxRateCnt[0][11], prInfo->u4RxRateRetryCnt[0][11], -+ prInfo->u4RxRateCnt[0][12], prInfo->u4RxRateRetryCnt[0][12], -+ prInfo->u4RxRateCnt[0][13], prInfo->u4RxRateRetryCnt[0][13], -+ prInfo->u4RxRateCnt[0][14], prInfo->u4RxRateRetryCnt[0][14], -+ prInfo->u4RxRateCnt[0][15], prInfo->u4RxRateRetryCnt[0][15])); -+ DBGLOG(RX, INFO, " ROFDM (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u)\n" -+ "(%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u)\n", -+ prInfo->u4RxRateCnt[1][0], prInfo->u4RxRateRetryCnt[1][0], -+ prInfo->u4RxRateCnt[1][1], prInfo->u4RxRateRetryCnt[1][1], -+ prInfo->u4RxRateCnt[1][2], prInfo->u4RxRateRetryCnt[1][2], -+ prInfo->u4RxRateCnt[1][3], prInfo->u4RxRateRetryCnt[1][3], -+ prInfo->u4RxRateCnt[1][4], prInfo->u4RxRateRetryCnt[1][4], -+ prInfo->u4RxRateCnt[1][5], prInfo->u4RxRateRetryCnt[1][5], -+ prInfo->u4RxRateCnt[1][6], prInfo->u4RxRateRetryCnt[1][6], -+ prInfo->u4RxRateCnt[1][7], prInfo->u4RxRateRetryCnt[1][7], -+ prInfo->u4RxRateCnt[1][8], prInfo->u4RxRateRetryCnt[1][8], -+ prInfo->u4RxRateCnt[1][9], prInfo->u4RxRateRetryCnt[1][9], -+ prInfo->u4RxRateCnt[1][10], prInfo->u4RxRateRetryCnt[1][10], -+ prInfo->u4RxRateCnt[1][11], prInfo->u4RxRateRetryCnt[1][11], -+ prInfo->u4RxRateCnt[1][12], prInfo->u4RxRateRetryCnt[1][12], -+ prInfo->u4RxRateCnt[1][13], prInfo->u4RxRateRetryCnt[1][13], -+ prInfo->u4RxRateCnt[1][14], prInfo->u4RxRateRetryCnt[1][14], -+ prInfo->u4RxRateCnt[1][15], prInfo->u4RxRateRetryCnt[1][15])); -+ DBGLOG(RX, INFO, " RHT (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u)\n" -+ "(%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u) (%u %u)\n", -+ prInfo->u4RxRateCnt[2][0], prInfo->u4RxRateRetryCnt[2][0], -+ prInfo->u4RxRateCnt[2][1], prInfo->u4RxRateRetryCnt[2][1], -+ prInfo->u4RxRateCnt[2][2], prInfo->u4RxRateRetryCnt[2][2], -+ prInfo->u4RxRateCnt[2][3], prInfo->u4RxRateRetryCnt[2][3], -+ prInfo->u4RxRateCnt[2][4], prInfo->u4RxRateRetryCnt[2][4], -+ prInfo->u4RxRateCnt[2][5], prInfo->u4RxRateRetryCnt[2][5], -+ prInfo->u4RxRateCnt[2][6], prInfo->u4RxRateRetryCnt[2][6], -+ prInfo->u4RxRateCnt[2][7], prInfo->u4RxRateRetryCnt[2][7], -+ prInfo->u4RxRateCnt[2][8], prInfo->u4RxRateRetryCnt[2][8], -+ prInfo->u4RxRateCnt[2][9], prInfo->u4RxRateRetryCnt[2][9], -+ prInfo->u4RxRateCnt[2][10], prInfo->u4RxRateRetryCnt[2][10], -+ prInfo->u4RxRateCnt[2][11], prInfo->u4RxRateRetryCnt[2][11], -+ prInfo->u4RxRateCnt[2][12], prInfo->u4RxRateRetryCnt[2][12], -+ prInfo->u4RxRateCnt[2][13], prInfo->u4RxRateRetryCnt[2][13], -+ prInfo->u4RxRateCnt[2][14], prInfo->u4RxRateRetryCnt[2][14], -+ prInfo->u4RxRateCnt[2][15], prInfo->u4RxRateRetryCnt[2][15])); -+ -+ /* delay from HIF to MAC */ -+ DBGLOG(RX, INFO, " StayIntH2M us (%u %u %u) (%u %u %u) (%u %u %u)\n", -+ prInfo->u4StayIntMinH2M[0], prInfo->u4StayIntAvgH2M[0], -+ prInfo->u4StayIntMaxH2M[0], -+ prInfo->u4StayIntMinH2M[1], prInfo->u4StayIntAvgH2M[1], -+ prInfo->u4StayIntMaxH2M[1], -+ prInfo->u4StayIntMinH2M[2], prInfo->u4StayIntAvgH2M[2], -+ prInfo->u4StayIntMaxH2M[2])); -+ /* delay from MAC to TXDONE */ -+ DBGLOG(RX, INFO, " AirTime us (%u %u %u) (%u %u %u) (%u %u %u)\n", -+ prInfo->u4AirDelayMin[0] << 5, prInfo->u4AirDelayAvg[0] << 5, -+ prInfo->u4AirDelayMax[0] << 5, -+ prInfo->u4AirDelayMin[1] << 5, prInfo->u4AirDelayAvg[1] << 5, -+ prInfo->u4AirDelayMax[1] << 5, -+ prInfo->u4TxDataCntAll, (prInfo->u4AirDelayAvg[2] << 5) / (prInfo->u4TxDataCntAll), -+ (prInfo->u4AirDelayAvg[2] << 5) / 400000)); -+ prAdapter->u4AirDelayTotal = (prInfo->u4AirDelayTotal << 5) / 400000; -+ /* delay from HIF to TXDONE */ -+ DBGLOG(RX, INFO, " StayInt us (%u %u %u_%u) (%u %u %u_%u) (%u %u %u_%u)\n", -+ prInfo->u4StayIntMin[0], prInfo->u4StayIntAvg[0], -+ prInfo->u4StayIntMax[0], prInfo->u4StayIntMaxSysTime[0], -+ prInfo->u4StayIntMin[1], prInfo->u4StayIntAvg[1], -+ prInfo->u4StayIntMax[1], prInfo->u4StayIntMaxSysTime[1], -+ prInfo->u4StayIntMin[2], prInfo->u4StayIntAvg[2], -+ prInfo->u4StayIntMax[2], prInfo->u4StayIntMaxSysTime[2])); -+ /* delay from Driver to TXDONE */ -+ DBGLOG(RX, INFO, " StayIntD2T us (%u %u %u) (%u %u %u) (%u %u %u)\n", -+ prInfo->u4StayIntMinD2T[0], prInfo->u4StayIntAvgD2T[0], -+ prInfo->u4StayIntMaxD2T[0], -+ prInfo->u4StayIntMinD2T[1], prInfo->u4StayIntAvgD2T[1], -+ prInfo->u4StayIntMaxD2T[1], -+ prInfo->u4StayIntMinD2T[2], prInfo->u4StayIntAvgD2T[2], -+ prInfo->u4StayIntMaxD2T[2])); -+ -+ /* delay from RXDONE to HIF */ -+ DBGLOG(RX, INFO, " StayIntR_M2H us (%u %u %u) (%u %u %u) (%u %u %u)\n", -+ prInfo->u4StayIntMinRx[0], prInfo->u4StayIntAvgRx[0], -+ prInfo->u4StayIntMaxRx[0], -+ prInfo->u4StayIntMinRx[1], prInfo->u4StayIntAvgRx[1], -+ prInfo->u4StayIntMaxRx[1], -+ prInfo->u4StayIntMinRx[2], prInfo->u4StayIntAvgRx[2], prInfo->u4StayIntMaxRx[2])); -+ /* delay from HIF to OS */ -+ DBGLOG(RX, INFO, " StayIntR_H2D us (%u %u %u) (%u %u %u) (%u %u %u)\n", -+ prStaRec->u4StayIntMinRx[0], prStaRec->u4StayIntAvgRx[0], -+ prStaRec->u4StayIntMaxRx[0], -+ prStaRec->u4StayIntMinRx[1], prStaRec->u4StayIntAvgRx[1], -+ prStaRec->u4StayIntMaxRx[1], -+ prStaRec->u4StayIntMinRx[2], prStaRec->u4StayIntAvgRx[2], -+ prStaRec->u4StayIntMaxRx[2])); -+ -+ /* count based on delay from OS to HIF */ -+ DBGLOG(RX, INFO, " StayCntD2H unit:%dms (%d %d %d %d)\n", -+ STATS_STAY_INT_D2H_CONST, -+ prInfo->u4StayIntD2HByConst[0], prInfo->u4StayIntD2HByConst[1], -+ prInfo->u4StayIntD2HByConst[2], prInfo->u4StayIntD2HByConst[3]); -+ -+ /* count based on different delay from HIF to TX DONE */ -+ DBGLOG(RX, INFO, " StayCnt unit:%dms (%d %d %d %d)\n", -+ STATS_STAY_INT_CONST, -+ prInfo->u4StayIntByConst[0], prInfo->u4StayIntByConst[1], -+ prInfo->u4StayIntByConst[2], prInfo->u4StayIntByConst[3]); -+ DBGLOG(RX, INFO, " StayCnt (%d~%d:%d) (%d~%d:%d) (%d~%d:%d) (%d~%d:%d) (%d~:%d)\n", -+ 0, prInfo->u4StayIntMaxPast / 4, prInfo->u4StayIntCnt[0], -+ prInfo->u4StayIntMaxPast / 4, prInfo->u4StayIntMaxPast / 2, prInfo->u4StayIntCnt[1], -+ prInfo->u4StayIntMaxPast / 2, prInfo->u4StayIntMaxPast * 3 / 4, -+ prInfo->u4StayIntCnt[2], prInfo->u4StayIntMaxPast * 3 / 4, prInfo->u4StayIntMaxPast, -+ prInfo->u4StayIntCnt[3], prInfo->u4StayIntMaxPast, prInfo->u4StayIntCnt[4])); -+ -+ /* channel idle time */ -+ DBGLOG(RX, INFO, " Idle Time (slot): (%u) (%u) (%u) (%u) (%u) (%u) (%u) (%u) (%u) (%u)\n", -+ prInfo->au4ChanIdleCnt[0], prInfo->au4ChanIdleCnt[1], -+ prInfo->au4ChanIdleCnt[2], prInfo->au4ChanIdleCnt[3], -+ prInfo->au4ChanIdleCnt[4], prInfo->au4ChanIdleCnt[5], -+ prInfo->au4ChanIdleCnt[6], prInfo->au4ChanIdleCnt[7], -+ prInfo->au4ChanIdleCnt[8], prInfo->au4ChanIdleCnt[9])); -+ -+ /* BT coex */ -+ DBGLOG(RX, INFO, " BT coex (0x%x)\n", prInfo->u4BtContUseTime); -+ -+ /* others */ -+ DBGLOG(RX, INFO, " OTHER (%u) (%u) (%u) (%u) (%u) (%ums) (%uus)\n", -+ prInfo->u4RxFifoFullCnt, prAdapter->ucScanTime, -+ prInfo->u4NumOfChanChange, prStaRec->u4NumOfNoTxQuota, -+ prInfo->ucNumOfPsChange, prInfo->u4PsIntMax, u4DrvOwnMax / 1000); -+ -+ /* reset */ -+ kalMemZero(prStaRec->u4StayIntMinRx, sizeof(prStaRec->u4StayIntMinRx)); -+ kalMemZero(prStaRec->u4StayIntAvgRx, sizeof(prStaRec->u4StayIntAvgRx)); -+ kalMemZero(prStaRec->u4StayIntMaxRx, sizeof(prStaRec->u4StayIntMaxRx)); -+ prStaRec->u4StatsRxPassToOsCnt = 0; -+ prStaRec->u4RxReorderFallAheadCnt = 0; -+ prStaRec->u4RxReorderFallBehindCnt = 0; -+ prStaRec->u4RxReorderHoleCnt = 0; -+ } -+ -+ STATS_DRIVER_OWN_RESET(); -+} -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to request firmware to feedback statistics. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set -+* \param[in] u4SetBufferLen The length of the set buffer -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed due to invalid length of -+* the set buffer, returns the amount of storage needed. -+* -+* \retval TDLS_STATUS_xx -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static WLAN_STATUS -+statsInfoEnvRequest(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen) -+{ -+ STATS_CMD_CORE_T *prCmdContent; -+ WLAN_STATUS rStatus; -+ -+ /* sanity check */ -+ if (fgIsUnderSuspend == true) -+ return WLAN_STATUS_SUCCESS; /* do not request stats after early suspend */ -+ -+ /* init command buffer */ -+ prCmdContent = (STATS_CMD_CORE_T *) pvSetBuffer; -+ prCmdContent->u4Command = STATS_CORE_CMD_ENV_REQUEST; -+ -+ /* send the command */ -+ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ -+ CMD_ID_STATS, /* ucCID */ -+ TRUE, /* fgSetQuery */ -+ FALSE, /* fgNeedResp */ -+ FALSE, /* fgIsOid */ -+ NULL, NULL, /* pfCmdTimeoutHandler */ -+ sizeof(STATS_CMD_CORE_T), /* u4SetQueryInfoLen */ -+ (PUINT_8) prCmdContent, /* pucInfoBuffer */ -+ NULL, /* pvSetQueryBuffer */ -+ 0 /* u4SetQueryBufferLen */ -+ ); -+ -+ if (rStatus != WLAN_STATUS_PENDING) { -+ DBGLOG(RX, ERROR, "%s wlanSendSetQueryCmd allocation fail!\n", __func__); -+ return WLAN_STATUS_RESOURCES; -+ } -+ -+ DBGLOG(RX, INFO, "%s cmd ok.\n", __func__); -+ return WLAN_STATUS_SUCCESS; -+} -+ -+/******************************************************************************* -+* P U B L I C F U N C T I O N S -+******************************************************************************** -+*/ -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to handle any statistics event. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prInBuf A pointer to the command string buffer -+* \param[in] u4InBufLen The length of the buffer -+* \param[out] None -+* -+* \retval None -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID statsEventHandle(GLUE_INFO_T *prGlueInfo, UINT8 *prInBuf, UINT32 u4InBufLen) -+{ -+ UINT32 u4EventId; -+ -+ /* sanity check */ -+/* DBGLOG(RX, INFO, */ -+/* (" %s: Rcv a event\n", __FUNCTION__)); */ -+ -+ if ((prGlueInfo == NULL) || (prInBuf == NULL)) -+ return; /* shall not be here */ -+ -+ /* handle */ -+ u4EventId = *(UINT32 *) prInBuf; -+ u4InBufLen -= 4; -+ -+/* DBGLOG(RX, INFO, */ -+/* (" %s: Rcv a event: %d\n", __FUNCTION__, u4EventId)); */ -+ -+ switch (u4EventId) { -+ case STATS_HOST_EVENT_ENV_REPORT: -+ statsInfoEnvDisplay(prGlueInfo, prInBuf + 4, u4InBufLen); -+ break; -+ -+ default: -+ break; -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to detect if we can request firmware to feedback statistics. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] ucStaRecIndex The station index -+* \param[out] None -+* -+* \retval None -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID statsEnvReportDetect(ADAPTER_T *prAdapter, UINT8 ucStaRecIndex) -+{ -+ STA_RECORD_T *prStaRec; -+ OS_SYSTIME rCurTime; -+ STATS_CMD_CORE_T rCmd; -+ -+ prStaRec = cnmGetStaRecByIndex(prAdapter, ucStaRecIndex); -+ if (prStaRec == NULL) -+ return; -+ -+ prStaRec->u4StatsEnvTxCnt++; -+ GET_CURRENT_SYSTIME(&rCurTime); -+ -+ if (prStaRec->rStatsEnvTxPeriodLastTime == 0) { -+ prStaRec->rStatsEnvTxLastTime = rCurTime; -+ prStaRec->rStatsEnvTxPeriodLastTime = rCurTime; -+ return; -+ } -+ -+ if (prStaRec->u4StatsEnvTxCnt > STATS_ENV_TX_CNT_REPORT_TRIGGER) { -+ if (CHECK_FOR_TIMEOUT(rCurTime, prStaRec->rStatsEnvTxLastTime, -+ SEC_TO_SYSTIME(STATS_ENV_TX_CNT_REPORT_TRIGGER_SEC))) { -+ rCmd.ucStaRecIdx = ucStaRecIndex; -+ statsInfoEnvRequest(prAdapter, &rCmd, 0, NULL); -+ -+ prStaRec->rStatsEnvTxLastTime = rCurTime; -+ prStaRec->rStatsEnvTxPeriodLastTime = rCurTime; -+ prStaRec->u4StatsEnvTxCnt = 0; -+ return; -+ } -+ } -+ -+ if (CHECK_FOR_TIMEOUT(rCurTime, prStaRec->rStatsEnvTxPeriodLastTime, SEC_TO_SYSTIME(STATS_ENV_TIMEOUT_SEC))) { -+ rCmd.ucStaRecIdx = ucStaRecIndex; -+ statsInfoEnvRequest(prAdapter, &rCmd, 0, NULL); -+ -+ prStaRec->rStatsEnvTxPeriodLastTime = rCurTime; -+ return; -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to handle rx done. -+* -+* \param[in] prStaRec Pointer to the STA_RECORD_T structure -+* \param[in] prSwRfb Pointer to the received packet -+* \param[out] None -+* -+* \retval None -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID StatsEnvRxDone(STA_RECORD_T *prStaRec, SW_RFB_T *prSwRfb) -+{ -+ UINT32 u4LenId; -+ UINT32 u4CurTime, u4DifTime; -+ -+ /* sanity check */ -+ if (prStaRec == NULL) -+ return; -+ -+ /* stats: rx done count */ -+ prStaRec->u4StatsRxPassToOsCnt++; -+ -+ /* get length partition ID */ -+ u4LenId = 0; -+ if (prSwRfb->u2PacketLen < STATS_STAY_INT_BYTE_THRESHOLD) { -+ u4LenId = 0; -+ } else { -+ if ((STATS_STAY_INT_BYTE_THRESHOLD <= prSwRfb->u2PacketLen) && -+ (prSwRfb->u2PacketLen < (STATS_STAY_INT_BYTE_THRESHOLD << 1))) { -+ u4LenId = 1; -+ } else -+ u4LenId = 2; -+ } -+ -+ /* stats: rx delay */ -+ u4CurTime = kalGetTimeTick(); -+ -+ if ((u4CurTime > prSwRfb->rRxTime) && (prSwRfb->rRxTime != 0)) { -+ u4DifTime = u4CurTime - prSwRfb->rRxTime; -+ -+ if (prStaRec->u4StayIntMinRx[u4LenId] == 0) /* impossible */ -+ prStaRec->u4StayIntMinRx[u4LenId] = 0xffffffff; -+ -+ if (u4DifTime > prStaRec->u4StayIntMaxRx[u4LenId]) -+ prStaRec->u4StayIntMaxRx[u4LenId] = u4DifTime; -+ else if (u4DifTime < prStaRec->u4StayIntMinRx[u4LenId]) -+ prStaRec->u4StayIntMinRx[u4LenId] = u4DifTime; -+ -+ prStaRec->u4StayIntAvgRx[u4LenId] += u4DifTime; -+ if (prStaRec->u4StayIntAvgRx[u4LenId] != u4DifTime) -+ prStaRec->u4StayIntAvgRx[u4LenId] >>= 1; -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to handle rx done. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prInBuf A pointer to the command string buffer -+* \param[in] u4InBufLen The length of the buffer -+* \param[out] None -+* -+* \retval None -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT_64 StatsEnvTimeGet(VOID) -+{ -+ /* TODO: use better API to get time to save time, jiffies unit is 10ms, too large */ -+ -+/* struct timeval tv; */ -+ -+/* do_gettimeofday(&tv); */ -+/* return tv.tv_usec + tv.tv_sec * (UINT_64)1000000; */ -+ -+ UINT_64 u8Clk; -+/* UINT32 *pClk = &u8Clk; */ -+ -+ u8Clk = sched_clock(); /* unit: naro seconds */ -+/* printk(" sched_clock() = %x %x %u\n", pClk[0], pClk[1], sizeof(jiffies)); */ -+ -+ return (UINT_64) u8Clk; /* sched_clock *//* jiffies size = 4B */ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to handle rx done. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prInBuf A pointer to the command string buffer -+* \param[in] u4InBufLen The length of the buffer -+* \param[out] None -+* -+* \retval None -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID StatsEnvTxTime2Hif(MSDU_INFO_T *prMsduInfo, HIF_TX_HEADER_T *prHwTxHeader) -+{ -+ UINT_64 u8SysTime, u8SysTimeIn; -+ UINT32 u4TimeDiff; -+ -+ u8SysTime = StatsEnvTimeGet(); -+ u8SysTimeIn = GLUE_GET_PKT_XTIME(prMsduInfo->prPacket); -+ -+/* printk(" hif: 0x%x %u %u %u\n", */ -+/* prMsduInfo->prPacket, StatsEnvTimeGet(), u8SysTime, GLUE_GET_PKT_XTIME(prMsduInfo->prPacket)); */ -+ -+ if ((u8SysTimeIn > 0) && (u8SysTime > u8SysTimeIn)) { -+ u8SysTime = u8SysTime - u8SysTimeIn; -+ u4TimeDiff = (UINT32) u8SysTime; -+ u4TimeDiff = u4TimeDiff / 1000; /* ns to us */ -+ -+ /* pass the delay between OS to us and we to HIF */ -+ if (u4TimeDiff > 0xFFFF) -+ *(UINT16 *) prHwTxHeader->aucReserved = (UINT16) 0xFFFF; /* 65535 us */ -+ else -+ *(UINT16 *) prHwTxHeader->aucReserved = (UINT16) u4TimeDiff; -+ -+/* printk(" u4TimeDiff: %u\n", u4TimeDiff); */ -+ } else { -+ prHwTxHeader->aucReserved[0] = 0; -+ prHwTxHeader->aucReserved[1] = 0; -+ } -+} -+ -+static VOID statsParsePktInfo(PUINT_8 pucPkt, UINT_8 status, UINT_8 eventType, P_MSDU_INFO_T prMsduInfo) -+{ -+ /* get ethernet protocol */ -+ UINT_16 u2EtherType = (pucPkt[ETH_TYPE_LEN_OFFSET] << 8) | (pucPkt[ETH_TYPE_LEN_OFFSET + 1]); -+ PUINT_8 pucEthBody = &pucPkt[ETH_HLEN]; -+ -+ switch (u2EtherType) { -+ case ETH_P_ARP: -+ { -+ UINT_16 u2OpCode = (pucEthBody[6] << 8) | pucEthBody[7]; -+ if (eventType == EVENT_TX) -+ prMsduInfo->fgIsBasicRate = TRUE; -+ -+ if ((su2TxDoneCfg & CFG_ARP) == 0) -+ break; -+ -+ switch (eventType) { -+ case EVENT_RX: -+ if (u2OpCode == ARP_PRO_REQ) -+ DBGLOG(RX, INFO, " Arp Req From IP: %d.%d.%d.%d\n", -+ pucEthBody[14], pucEthBody[15], pucEthBody[16], pucEthBody[17]); -+ else if (u2OpCode == ARP_PRO_RSP) -+ DBGLOG(RX, INFO, " Arp Rsp from IP: %d.%d.%d.%d\n", -+ pucEthBody[14], pucEthBody[15], pucEthBody[16], pucEthBody[17]); -+ break; -+ case EVENT_TX: -+ if (u2OpCode == ARP_PRO_REQ) -+ DBGLOG(TX, INFO, " Arp Req to IP: %d.%d.%d.%d\n", -+ pucEthBody[24], pucEthBody[25], pucEthBody[26], pucEthBody[27]); -+ else if (u2OpCode == ARP_PRO_RSP) -+ DBGLOG(TX, INFO, " Arp Rsp to IP: %d.%d.%d.%d\n", -+ pucEthBody[24], pucEthBody[25], pucEthBody[26], pucEthBody[27]); -+ prMsduInfo->fgNeedTxDoneStatus = TRUE; -+ break; -+ case EVENT_TX_DONE: -+ if (u2OpCode == ARP_PRO_REQ) -+ DBGLOG(TX, INFO, " Arp Req to IP: %d.%d.%d.%d\n", status, -+ pucEthBody[24], pucEthBody[25], pucEthBody[26], pucEthBody[27]); -+ else if (u2OpCode == ARP_PRO_RSP) -+ DBGLOG(TX, INFO, " Arp Rsp to IP: %d.%d.%d.%d\n", status, -+ pucEthBody[24], pucEthBody[25], pucEthBody[26], pucEthBody[27]); -+ break; -+ } -+ break; -+ } -+ case ETH_P_IP: -+ { -+ UINT_8 ucIpProto = pucEthBody[9]; /* IP header without options */ -+ UINT_8 ucIpVersion = (pucEthBody[0] & IPVH_VERSION_MASK) >> IPVH_VERSION_OFFSET; -+ UINT_16 u2IpId = pucEthBody[4]<<8 | pucEthBody[5]; -+ -+ if (ucIpVersion != IPVERSION) -+ break; -+ -+ switch (ucIpProto) { -+ case IP_PRO_ICMP: -+ { -+ /* the number of ICMP packets is seldom so we print log here */ -+ UINT_8 ucIcmpType; -+ UINT_16 u2IcmpId, u2IcmpSeq; -+ PUINT_8 pucIcmp = &pucEthBody[20]; -+ -+ ucIcmpType = pucIcmp[0]; -+ /* don't log network unreachable packet */ -+ if (((su2TxDoneCfg & CFG_ICMP) == 0) || ucIcmpType == 3) -+ break; -+ u2IcmpId = *(UINT_16 *) &pucIcmp[4]; -+ u2IcmpSeq = *(UINT_16 *) &pucIcmp[6]; -+ switch (eventType) { -+ case EVENT_RX: -+ DBGLOG(RX, INFO, " ICMP: Type %d, Id BE 0x%04x, Seq BE 0x%04x\n", -+ ucIcmpType, u2IcmpId, u2IcmpSeq); -+ break; -+ case EVENT_TX: -+ DBGLOG(TX, INFO, " ICMP: Type %d, Id 0x04%x, Seq BE 0x%04x\n", -+ ucIcmpType, u2IcmpId, u2IcmpSeq); -+ prMsduInfo->fgNeedTxDoneStatus = TRUE; -+ break; -+ case EVENT_TX_DONE: -+ DBGLOG(TX, INFO, " Type %d, Id 0x%04x, Seq 0x%04x\n", -+ status, ucIcmpType, u2IcmpId, u2IcmpSeq); -+ break; -+ } -+ break; -+ } -+ case IP_PRO_UDP: -+ { -+ /* the number of DHCP packets is seldom so we print log here */ -+ PUINT_8 pucUdp = &pucEthBody[20]; -+ PUINT_8 pucUdpPayload = &pucUdp[8]; -+ UINT_16 u2UdpDstPort; -+ UINT_16 u2UdpSrcPort; -+ -+ u2UdpDstPort = (pucUdp[2] << 8) | pucUdp[3]; -+ u2UdpSrcPort = (pucUdp[0] << 8) | pucUdp[1]; -+ /* dhcp */ -+ if ((u2UdpDstPort == UDP_PORT_DHCPS) || (u2UdpDstPort == UDP_PORT_DHCPC)) { -+ UINT_32 u4TransID = pucUdpPayload[4]<<24 | pucUdpPayload[5]<<16 | -+ pucUdpPayload[6]<<8 | pucUdpPayload[7]; -+ -+ switch (eventType) { -+ case EVENT_RX: -+ DBGLOG(RX, INFO, " DHCP: IPID 0x%02x, MsgType 0x%x, TransID 0x%08x\n", -+ u2IpId, pucUdpPayload[0], u4TransID); -+ break; -+ case EVENT_TX: -+ DBGLOG(TX, INFO, " DHCP: IPID 0x%02x, MsgType 0x%x, TransID 0x%08x\n", -+ u2IpId, pucUdpPayload[0], u4TransID); -+ prMsduInfo->fgNeedTxDoneStatus = TRUE; -+ prMsduInfo->fgIsBasicRate = TRUE; -+ break; -+ case EVENT_TX_DONE: -+ DBGLOG(TX, INFO, -+ " DHCP: IPID 0x%02x, MsgType 0x%x, TransID 0x%08x\n", -+ status, u2IpId, pucUdpPayload[0], u4TransID); -+ break; -+ } -+ } else if (u2UdpDstPort == UDP_PORT_DNS) { /* tx dns */ -+ UINT_16 u2TransId = (pucUdpPayload[0] << 8) | pucUdpPayload[1]; -+ if (eventType == EVENT_TX) -+ prMsduInfo->fgIsBasicRate = TRUE; -+ -+ if ((su2TxDoneCfg & CFG_DNS) == 0) -+ break; -+ if (eventType == EVENT_TX) { -+ DBGLOG(TX, INFO, " DNS: IPID 0x%02x, TransID 0x%04x\n", u2IpId, u2TransId); -+ prMsduInfo->fgNeedTxDoneStatus = TRUE; -+ } else if (eventType == EVENT_TX_DONE) -+ DBGLOG(TX, INFO, " DNS: IPID 0x%02x, TransID 0x%04x\n", -+ status, u2IpId, u2TransId); -+ } else if (u2UdpSrcPort == UDP_PORT_DNS && eventType == EVENT_RX) { /* rx dns */ -+ UINT_16 u2TransId = (pucUdpPayload[0] << 8) | pucUdpPayload[1]; -+ -+ if ((su2TxDoneCfg & CFG_DNS) == 0) -+ break; -+ DBGLOG(RX, INFO, " DNS: IPID 0x%02x, TransID 0x%04x\n", u2IpId, u2TransId); -+ } else if ((su2TxDoneCfg & CFG_UDP) != 0) { -+ switch (eventType) { -+ case EVENT_RX: -+ DBGLOG(RX, INFO, " UDP: IPID 0x%04x\n", u2IpId); -+ break; -+ case EVENT_TX: -+ DBGLOG(TX, INFO, " UDP: IPID 0x%04x\n", u2IpId); -+ prMsduInfo->fgNeedTxDoneStatus = TRUE; -+ break; -+ case EVENT_TX_DONE: -+ DBGLOG(TX, INFO, " UDP: IPID 0x%04x\n", status, u2IpId); -+ break; -+ } -+ } -+ break; -+ } -+ case IP_PRO_TCP: -+ if ((su2TxDoneCfg & CFG_TCP) == 0) -+ break; -+ -+ switch (eventType) { -+ case EVENT_RX: -+ DBGLOG(RX, INFO, " TCP: IPID 0x%04x\n", u2IpId); -+ break; -+ case EVENT_TX: -+ DBGLOG(TX, INFO, " TCP: IPID 0x%04x\n", u2IpId); -+ prMsduInfo->fgNeedTxDoneStatus = TRUE; -+ break; -+ case EVENT_TX_DONE: -+ DBGLOG(TX, INFO, " TCP: IPID 0x%04x\n", status, u2IpId); -+ break; -+ } -+ break; -+ } -+ break; -+ } -+ case ETH_P_PRE_1X: -+ DBGLOG(RX, INFO, "pre-1x\n"); -+ case ETH_P_1X: -+ { -+ PUINT_8 pucEapol = pucEthBody; -+ UINT_8 ucEapolType = pucEapol[1]; -+ -+ switch (ucEapolType) { -+ case 0: /* eap packet */ -+ switch (eventType) { -+ case EVENT_RX: -+ DBGLOG(RX, INFO, " EAP Packet: code %d, id %d, type %d\n", -+ pucEapol[4], pucEapol[5], pucEapol[7]); -+ break; -+ case EVENT_TX: -+ DBGLOG(TX, INFO, " EAP Packet: code %d, id %d, type %d\n", -+ pucEapol[4], pucEapol[5], pucEapol[7]); -+ break; -+ case EVENT_TX_DONE: -+ DBGLOG(TX, INFO, " EAP Packet: code %d, id %d, type %d\n", -+ status, pucEapol[4], pucEapol[5], pucEapol[7]); -+ break; -+ } -+ break; -+ case 1: /* eapol start */ -+ switch (eventType) { -+ case EVENT_RX: -+ DBGLOG(RX, INFO, " EAPOL: start\n"); -+ break; -+ case EVENT_TX: -+ DBGLOG(TX, INFO, " EAPOL: start\n"); -+ break; -+ case EVENT_TX_DONE: -+ DBGLOG(TX, INFO, " EAPOL: start\n", status); -+ break; -+ } -+ break; -+ case 3: /* key */ -+ { -+ UINT_16 u2KeyInfo = pucEapol[5]<<8 | pucEapol[6]; -+ -+ switch (eventType) { -+ case EVENT_RX: -+ DBGLOG(RX, INFO, -+ " EAPOL: key, KeyInfo 0x%04x, Nonce %02x%02x%02x%02x%02x%02x%02x%02x...\n", -+ u2KeyInfo, pucEapol[17], pucEapol[18], pucEapol[19], pucEapol[20], -+ pucEapol[21], pucEapol[22], pucEapol[23], pucEapol[24]); -+ break; -+ case EVENT_TX: -+ DBGLOG(TX, INFO, -+ " EAPOL: key, KeyInfo 0x%04x, Nonce %02x%02x%02x%02x%02x%02x%02x%02x...\n", -+ u2KeyInfo, -+ pucEapol[17], pucEapol[18], pucEapol[19], pucEapol[20], -+ pucEapol[21], pucEapol[22], pucEapol[23], pucEapol[24]); -+ break; -+ case EVENT_TX_DONE: -+ DBGLOG(TX, INFO, -+ " EAPOL: key, KeyInfo 0x%04x, Nonce %02x%02x%02x%02x%02x%02x%02x%02x...\n", -+ status, u2KeyInfo, pucEapol[17], pucEapol[18], pucEapol[19], -+ pucEapol[20], pucEapol[21], pucEapol[22], pucEapol[23], pucEapol[24]); -+ break; -+ } -+ -+ break; -+ } -+ } -+ break; -+ } -+ case ETH_WPI_1X: -+ { -+ UINT_8 ucSubType = pucEthBody[3]; /* sub type filed*/ -+ UINT_16 u2Length = *(PUINT_16)&pucEthBody[6]; -+ UINT_16 u2Seq = *(PUINT_16)&pucEthBody[8]; -+ -+ switch (eventType) { -+ case EVENT_RX: -+ DBGLOG(RX, INFO, " WAPI: subType %d, Len %d, Seq %d\n", -+ ucSubType, u2Length, u2Seq); -+ break; -+ case EVENT_TX: -+ DBGLOG(TX, INFO, " WAPI: subType %d, Len %d, Seq %d\n", -+ ucSubType, u2Length, u2Seq); -+ break; -+ case EVENT_TX_DONE: -+ DBGLOG(TX, INFO, " WAPI: subType %d, Len %d, Seq %d\n", -+ status, ucSubType, u2Length, u2Seq); -+ break; -+ } -+ break; -+ } -+ } -+} -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to display rx packet information. -+* -+* \param[in] pPkt Pointer to the packet -+* \param[out] None -+* -+* \retval None -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID StatsRxPktInfoDisplay(UINT_8 *pPkt) -+{ -+ statsParsePktInfo(pPkt, 0, EVENT_RX, NULL); -+#if 0 /* carefully! too many ARP */ -+ if (pucIpHdr[0] == 0x00) { /* ARP */ -+ UINT_8 *pucDstIp = (UINT_8 *) pucIpHdr; -+ -+ if (pucDstIp[7] == ARP_PRO_REQ) { -+ DBGLOG(RX, TRACE, " OS rx a arp req from %d.%d.%d.%d\n", -+ pucDstIp[14], pucDstIp[15], pucDstIp[16], pucDstIp[17]); -+ } else if (pucDstIp[7] == ARP_PRO_RSP) { -+ DBGLOG(RX, TRACE, " OS rx a arp rsp from %d.%d.%d.%d\n", -+ pucDstIp[24], pucDstIp[25], pucDstIp[26], pucDstIp[27]); -+ } -+ } -+#endif -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to display tx packet information. -+* -+* \param[in] pPkt Pointer to the packet -+* \param[out] None -+* -+* \retval None -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID StatsTxPktCallBack(UINT_8 *pPkt, P_MSDU_INFO_T prMsduInfo) -+{ -+ UINT_16 u2EtherTypeLen; -+ -+ u2EtherTypeLen = (pPkt[ETH_TYPE_LEN_OFFSET] << 8) | (pPkt[ETH_TYPE_LEN_OFFSET + 1]); -+ statsParsePktInfo(pPkt, 0, EVENT_TX, prMsduInfo); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to handle display tx packet tx done information. -+* -+* \param[in] pPkt Pointer to the packet -+* \param[out] None -+* -+* \retval None -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID StatsTxPktDoneInfoDisplay(ADAPTER_T *prAdapter, UINT_8 *pucEvtBuf) -+{ -+ EVENT_TX_DONE_STATUS_T *prTxDone; -+ -+ prTxDone = (EVENT_TX_DONE_STATUS_T *) pucEvtBuf; -+ /* -+ * Why 65 Bytes: -+ * 8B + wlanheader(40B) + hif_tx_header(16B) + 6B + 6B(LLC) - 12B -+ */ -+ statsParsePktInfo(&prTxDone->aucPktBuf[64], prTxDone->ucStatus, EVENT_TX_DONE, NULL); -+} -+ -+VOID StatsSetCfgTxDone(UINT_16 u2Cfg, BOOLEAN fgSet) -+{ -+ if (fgSet) -+ su2TxDoneCfg |= u2Cfg; -+ else -+ su2TxDoneCfg &= ~u2Cfg; -+} -+ -+UINT_16 StatsGetCfgTxDone(VOID) -+{ -+ return su2TxDoneCfg; -+} -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/swcr.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/swcr.c -new file mode 100644 -index 000000000000..67eccbda9fa8 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/swcr.c -@@ -0,0 +1,1170 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/swcr.c#1 -+*/ -+ -+/*! \file "swcr.c" -+ \brief -+ -+*/ -+ -+/* -+** Log: swcr.c -+ * -+ * 06 04 2012 tsaiyuan.hsu -+ * [WCXRP00001249] [ALPS.ICS] Daily build warning on "wlan/mgmt/swcr.c#1" -+ * resolve build waring for "WNM_UNIT_TEST not defined". -+ * -+ * 03 02 2012 terry.wu -+ * NULL -+ * Sync CFG80211 modification from branch 2,2. -+ * -+ * 01 05 2012 tsaiyuan.hsu -+ * [WCXRP00001157] [MT6620 Wi-Fi][FW][DRV] add timing measurement support for 802.11v -+ * add timing measurement support for 802.11v. -+ * -+ * 11 22 2011 tsaiyuan.hsu -+ * [WCXRP00001083] [MT6620 Wi-Fi][DRV]] dump debug counter or frames when debugging is triggered -+ * keep debug counter setting after wake up. -+ * -+ * 11 15 2011 cm.chang -+ * NULL -+ * Fix compiling warning -+ * -+ * 11 11 2011 tsaiyuan.hsu -+ * [WCXRP00001083] [MT6620 Wi-Fi][DRV]] dump debug counter or frames when debugging is triggered -+ * fix debug counters of rx in driver. -+ * -+ * 11 11 2011 tsaiyuan.hsu -+ * [WCXRP00001083] [MT6620 Wi-Fi][DRV]] dump debug counter or frames when debugging is triggered -+ * add debug counters of bb and ar for xlog. -+ * -+ * 11 10 2011 eddie.chen -+ * [WCXRP00001096] [MT6620 Wi-Fi][Driver/FW] Enhance the log function (xlog) -+ * Modify the QM xlog level and remove LOG_FUNC. -+ * -+ * 11 08 2011 tsaiyuan.hsu -+ * [WCXRP00001083] [MT6620 Wi-Fi][DRV]] dump debug counter or frames when debugging is triggered -+ * add debug counters, eCurPsProf, for PS. -+ * -+ * 11 07 2011 tsaiyuan.hsu -+ * [WCXRP00001083] [MT6620 Wi-Fi][DRV]] dump debug counter or frames when debugging is triggered -+ * add debug counters and periodically dump counters for debugging. -+ * -+ * 11 03 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * change the DBGLOG for "\n" and "\r\n". LABEL to LOUD for XLOG -+ * -+ * 08 31 2011 tsaiyuan.hsu -+ * [WCXRP00000931] [MT5931 Wi-Fi][DRV/FW] add swcr to disable roaming from driver -+ * remove obsolete code. -+ * -+ * 08 15 2011 tsaiyuan.hsu -+ * [WCXRP00000931] [MT5931 Wi-Fi][DRV/FW] add swcr to disable roaming from driver -+ * add swcr in driver reg, 0x9fxx0000, to disable roaming . -+ * -+ * 05 11 2011 eddie.chen -+ * [WCXRP00000709] [MT6620 Wi-Fi][Driver] Check free number before copying broadcast packet -+ * Fix dest type when GO packet copying. -+ * -+ * 05 09 2011 eddie.chen -+ * [WCXRP00000709] [MT6620 Wi-Fi][Driver] Check free number before copying broadcast packet -+ * Check free number before copying broadcast packet. -+ * -+ * 04 14 2011 eddie.chen -+ * [WCXRP00000603] [MT6620 Wi-Fi][DRV] Fix Klocwork warning -+ * Check the SW RFB free. Fix the compile warning.. -+ * -+ * 04 12 2011 eddie.chen -+ * [WCXRP00000617] [MT6620 Wi-Fi][DRV/FW] Fix for sigma -+ * Fix the sta index in processing security frame -+ * Simple flow control for TC4 to avoid mgt frames for PS STA to occupy the TC4 -+ * Add debug message. -+ * -+ * 03 28 2011 eddie.chen -+ * [WCXRP00000603] [MT6620 Wi-Fi][DRV] Fix Klocwork warning -+ * Fix Klockwork warning. -+ * -+ * 03 15 2011 eddie.chen -+ * [WCXRP00000554] [MT6620 Wi-Fi][DRV] Add sw control debug counter -+ * Add sw debug counter for QM. -+ * -+ * 01 11 2011 eddie.chen -+ * [WCXRP00000322] Add WMM IE in beacon, -+Add per station flow control when STA is in PS -+ -+ * Add swcr for test. -+ * -+* -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "precomp.h" -+ -+#if CFG_SUPPORT_SWCR -+ -+#ifdef __GNUC__ -+#pragma GCC diagnostic ignored "-Wformat" -+#endif -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+#if 0 -+SWCR_MOD_MAP_ENTRY_T g_arSwCrAllMaps[] = { -+ {SWCR_MAP_NUM(g_arRlmArSwCrMap), g_arRlmArSwCrMap}, /* 0x00nn */ -+ {0, NULL} -+}; -+#endif -+ -+UINT_32 g_au4SwCr[SWCR_CR_NUM]; /*: 0: command other: data */ -+ -+/* JB mDNS Filter*/ -+UINT_32 g_u4mDNSRXFilter = 0; /* [31] 0: stop 1: start, [3] IPv6 [2] IPv4 */ -+ -+static TIMER_T g_rSwcrDebugTimer; -+static BOOLEAN g_fgSwcrDebugTimer = FALSE; -+static UINT_32 g_u4SwcrDebugCheckTimeout; -+static ENUM_SWCR_DBG_TYPE_T g_ucSwcrDebugCheckType; -+static UINT_32 g_u4SwcrDebugFrameDumpType; -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+#define TEST_PS 1 -+ -+static const PFN_CMD_RW_T g_arSwCtrlCmd[] = { -+ swCtrlCmdCategory0, -+ swCtrlCmdCategory1 -+#if TEST_PS -+ , testPsCmdCategory0, testPsCmdCategory1 -+#endif -+#if CFG_SUPPORT_802_11V -+#if (CFG_SUPPORT_802_11V_TIMING_MEASUREMENT == 1) && (WNM_UNIT_TEST == 1) -+ , testWNMCmdCategory0 -+#endif -+#endif -+}; -+ -+const PFN_SWCR_RW_T g_arSwCrModHandle[] = { -+ swCtrlSwCr, -+ NULL -+}; -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+enum { -+ SWCTRL_MAGIC, -+ SWCTRL_DEBUG, -+ SWCTRL_WIFI_VAR, -+ SWCTRL_ENABLE_INT, -+ SWCTRL_DISABLE_INT, -+ SWCTRL_TXM_INFO, -+ SWCTRL_RXM_INFO, -+ SWCTRL_DUMP_BSS, -+ SWCTRL_QM_INFO, -+ SWCTRL_DUMP_ALL_QUEUE_LEN, -+ SWCTRL_DUMP_MEM, -+ SWCTRL_TX_CTRL_INFO, -+ SWCTRL_DUMP_QUEUE, -+ SWCTRL_DUMP_QM_DBG_CNT, -+ SWCTRL_QM_DBG_CNT, -+ SWCTRL_RX_PKTS_DUMP, -+ SWCTRL_RX_MDNS_FILTER, -+ SWCTRL_CATA0_INDEX_NUM -+}; -+ -+enum { -+ SWCTRL_STA_INFO, -+ SWCTRL_DUMP_STA, -+ SWCTRL_STA_QUE_INFO, -+ SWCTRL_CATA1_INDEX_NUM -+}; -+ -+/* JB mDNS Filter*/ -+#define RX_MDNS_FILTER_START (1<<31) -+#define RX_MDNS_FILTER_IPV4 (1<<2) -+#define RX_MDNS_FILTER_IPV6 (1<<3) -+typedef enum _ENUM_SWCR_RX_MDNS_FILTER_CMD_T { -+ SWCR_RX_MDNS_FILTER_CMD_STOP = 0, -+ SWCR_RX_MDNS_FILTER_CMD_START, -+ SWCR_RX_MDNS_FILTER_CMD_ADD, -+ SWCR_RX_MDNS_FILTER_CMD_REMOVE, -+ SWCR_RX_MDNS_FILTER_NUM -+} ENUM_SWCR_RX_MDNS_FILTER_CMD_T; -+ -+#if TEST_PS -+enum { -+ TEST_PS_MAGIC, -+ TEST_PS_SETUP_BSS, -+ TEST_PS_ENABLE_BEACON, -+ TEST_PS_TRIGGER_BMC, -+ TEST_PS_SEND_NULL, -+ TEST_PS_BUFFER_BMC, -+ TEST_PS_UPDATE_BEACON, -+ TEST_PS_CATA0_INDEX_NUM -+}; -+ -+enum { -+ TEST_PS_STA_PS, -+ TEST_PS_STA_ENTER_PS, -+ TEST_PS_STA_EXIT_PS, -+ TEST_PS_STA_TRIGGER_PSPOLL, -+ TEST_PS_STA_TRIGGER_FRAME, -+ TEST_PS_CATA1_INDEX_NUM -+}; -+#endif -+ -+#if CFG_SUPPORT_802_11V -+#if WNM_UNIT_TEST -+enum { -+ TEST_WNM_TIMING_MEAS, -+ TEST_WNM_CATA0_INDEX_NUM -+}; -+#endif -+#endif -+ -+#define _SWCTRL_MAGIC 0x66201642 -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+void dumpQueue(P_ADAPTER_T prAdapter) -+{ -+ -+ P_TX_CTRL_T prTxCtrl; -+ P_QUE_MGT_T prQM; -+ P_GLUE_INFO_T prGlueInfo; -+ UINT_32 i; -+ UINT_32 j; -+ -+ DEBUGFUNC("dumpQueue"); -+ -+ prTxCtrl = &prAdapter->rTxCtrl; -+ prQM = &prAdapter->rQM; -+ prGlueInfo = prAdapter->prGlueInfo; -+ -+ for (i = TC0_INDEX; i <= TC5_INDEX; i++) { -+ DBGLOG(SW4, INFO, "TC %u\n", i); -+ DBGLOG(SW4, INFO, "Max %u Free %u\n", -+ prTxCtrl->rTc.aucMaxNumOfBuffer[i], prTxCtrl->rTc.aucFreeBufferCount[i]); -+ -+ DBGLOG(SW4, INFO, "Average %u minReserved %u CurrentTcResource %u GuaranteedTcResource %u\n", -+ QM_GET_TX_QUEUE_LEN(prAdapter, i), -+ prQM->au4MinReservedTcResource[i], -+ prQM->au4CurrentTcResource[i], prQM->au4GuaranteedTcResource[i]); -+ -+ } -+ -+ for (i = 0; i < NUM_OF_PER_STA_TX_QUEUES; i++) { -+ DBGLOG(SW4, INFO, -+ "TC %u HeadStaIdx %u ForwardCount %u\n", i, prQM->au4HeadStaRecIndex[i], -+ prQM->au4ForwardCount[i]); -+ } -+ -+ DBGLOG(SW4, INFO, "BMC or unknown TxQueue Len %u\n", prQM->arTxQueue[0].u4NumElem); -+ DBGLOG(SW4, INFO, "Pending %d\n", prGlueInfo->i4TxPendingFrameNum); -+ DBGLOG(SW4, INFO, "Pending Security %d\n", prGlueInfo->i4TxPendingSecurityFrameNum); -+#if defined(LINUX) -+ for (i = 0; i < 4; i++) { -+ for (j = 0; j < CFG_MAX_TXQ_NUM; j++) { -+ DBGLOG(SW4, INFO, -+ "Pending Q[%u][%u] %d\n", i, j, prGlueInfo->ai4TxPendingFrameNumPerQueue[i][j]); -+ } -+ } -+#endif -+ -+ DBGLOG(SW4, INFO, " rFreeSwRfbList %u\n", prAdapter->rRxCtrl.rFreeSwRfbList.u4NumElem); -+ DBGLOG(SW4, INFO, " rReceivedRfbList %u\n", prAdapter->rRxCtrl.rReceivedRfbList.u4NumElem); -+ DBGLOG(SW4, INFO, " rIndicatedRfbList %u\n", prAdapter->rRxCtrl.rIndicatedRfbList.u4NumElem); -+ DBGLOG(SW4, INFO, " ucNumIndPacket %u\n", prAdapter->rRxCtrl.ucNumIndPacket); -+ DBGLOG(SW4, INFO, " ucNumRetainedPacket %u\n", prAdapter->rRxCtrl.ucNumRetainedPacket); -+ -+} -+ -+void dumpSTA(P_ADAPTER_T prAdapter, P_STA_RECORD_T prStaRec) -+{ -+ UINT_8 ucWTEntry; -+ UINT_32 i; -+ P_BSS_INFO_T prBssInfo; -+ -+ DEBUGFUNC("dumpSTA"); -+ -+ ASSERT(prStaRec); -+ ucWTEntry = prStaRec->ucWTEntry; -+ -+ prBssInfo = &prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]; -+ ASSERT(prBssInfo); -+ -+ DBGLOG(SW4, INFO, "Mac address: %pM Rcpi %u" "\n", prStaRec->aucMacAddr, prStaRec->ucRCPI); -+ -+ DBGLOG(SW4, INFO, "Idx %u Wtbl %u Used %u State %u Bss Phy 0x%x Sta DesiredPhy 0x%x\n", -+ prStaRec->ucIndex, ucWTEntry, -+ prStaRec->fgIsInUse, prStaRec->ucStaState, -+ prBssInfo->ucPhyTypeSet, prStaRec->ucDesiredPhyTypeSet); -+ -+ DBGLOG(SW4, INFO, "Sta Operation 0x%x DesiredNontHtRateSet 0x%x Mcs 0x%x u2HtCapInfo 0x%x\n", -+ prStaRec->u2OperationalRateSet, prStaRec->u2DesiredNonHTRateSet, prStaRec->ucMcsSet, -+ prStaRec->u2HtCapInfo); -+ -+ for (i = 0; i < NUM_OF_PER_STA_TX_QUEUES; i++) -+ DBGLOG(SW4, INFO, "TC %u Queue Len %u\n", i, prStaRec->arTxQueue[i].u4NumElem); -+ -+ DBGLOG(SW4, INFO, "BmpDeliveryAC %x\n", prStaRec->ucBmpDeliveryAC); -+ DBGLOG(SW4, INFO, "BmpTriggerAC %x\n", prStaRec->ucBmpTriggerAC); -+ DBGLOG(SW4, INFO, "UapsdSpSupproted %u\n", prStaRec->fgIsUapsdSupported); -+ DBGLOG(SW4, INFO, "IsQoS %u\n", prStaRec->fgIsQoS); -+ DBGLOG(SW4, INFO, "AssocId %u\n", prStaRec->u2AssocId); -+ -+ DBGLOG(SW4, INFO, "fgIsInPS %u\n", prStaRec->fgIsInPS); -+ DBGLOG(SW4, INFO, "ucFreeQuota %u\n", prStaRec->ucFreeQuota); -+ DBGLOG(SW4, INFO, "ucFreeQuotaForDelivery %u\n", prStaRec->ucFreeQuotaForDelivery); -+ DBGLOG(SW4, INFO, "ucFreeQuotaForNonDelivery %u\n", prStaRec->ucFreeQuotaForNonDelivery); -+ -+#if 0 -+ DBGLOG(SW4, INFO, "IsQmmSup %u\n", prStaRec->fgIsWmmSupported); -+ DBGLOG(SW4, INFO, "IsUapsdSup %u\n", prStaRec->fgIsUapsdSupported); -+ DBGLOG(SW4, INFO, "AvailabaleDeliverPkts %u\n", prStaRec->ucAvailableDeliverPkts); -+ DBGLOG(SW4, INFO, "BmpDeliverPktsAC %u\n", prStaRec->u4BmpDeliverPktsAC); -+ DBGLOG(SW4, INFO, "BmpBufferAC %u\n", prStaRec->u4BmpBufferAC); -+ DBGLOG(SW4, INFO, "BmpNonDeliverPktsAC %u\n", prStaRec->u4BmpNonDeliverPktsAC); -+#endif -+ -+ for (i = 0; i < CFG_RX_MAX_BA_TID_NUM; i++) { -+ if (prStaRec->aprRxReorderParamRefTbl[i]) { -+ DBGLOG(SW4, INFO, -+ "RxReorder fgIsValid: %u\n", prStaRec->aprRxReorderParamRefTbl[i]->fgIsValid); -+ DBGLOG(SW4, INFO, "RxReorder Tid: %u\n", prStaRec->aprRxReorderParamRefTbl[i]->ucTid); -+ DBGLOG(SW4, INFO, -+ "RxReorder rReOrderQue Len: %u\n", -+ prStaRec->aprRxReorderParamRefTbl[i]->rReOrderQue.u4NumElem); -+ DBGLOG(SW4, INFO, -+ "RxReorder WinStart: %u\n", prStaRec->aprRxReorderParamRefTbl[i]->u2WinStart); -+ DBGLOG(SW4, INFO, "RxReorder WinEnd: %u\n", prStaRec->aprRxReorderParamRefTbl[i]->u2WinEnd); -+ DBGLOG(SW4, INFO, "RxReorder WinSize: %u\n", prStaRec->aprRxReorderParamRefTbl[i]->u2WinSize); -+ } -+ } -+ -+} -+ -+VOID dumpBss(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo) -+{ -+ -+ DBGLOG(SW4, INFO, "SSID %s\n", prBssInfo->aucSSID); -+ DBGLOG(SW4, INFO, "OWN %pM\n", prBssInfo->aucOwnMacAddr); -+ DBGLOG(SW4, INFO, "BSSID %pM\n", prBssInfo->aucBSSID); -+ DBGLOG(SW4, INFO, "ucNetTypeIndex %u\n", prBssInfo->ucNetTypeIndex); -+ DBGLOG(SW4, INFO, "eConnectionState %u\n", prBssInfo->eConnectionState); -+ DBGLOG(SW4, INFO, "eCurrentOPMode %u\n", prBssInfo->eCurrentOPMode); -+ DBGLOG(SW4, INFO, "fgIsQBSS %u\n", prBssInfo->fgIsQBSS); -+ DBGLOG(SW4, INFO, "fgIsShortPreambleAllowed %u\n", prBssInfo->fgIsShortPreambleAllowed); -+ DBGLOG(SW4, INFO, "fgUseShortPreamble %u\n", prBssInfo->fgUseShortPreamble); -+ DBGLOG(SW4, INFO, "fgUseShortSlotTime %u\n", prBssInfo->fgUseShortSlotTime); -+ DBGLOG(SW4, INFO, "ucNonHTBasicPhyType %x\n", prBssInfo->ucNonHTBasicPhyType); -+ DBGLOG(SW4, INFO, "u2OperationalRateSet %x\n", prBssInfo->u2OperationalRateSet); -+ DBGLOG(SW4, INFO, "u2BSSBasicRateSet %x\n", prBssInfo->u2BSSBasicRateSet); -+ DBGLOG(SW4, INFO, "ucPhyTypeSet %x\n", prBssInfo->ucPhyTypeSet); -+ DBGLOG(SW4, INFO, "rStaRecOfClientList %d\n", prBssInfo->rStaRecOfClientList.u4NumElem); -+ DBGLOG(SW4, INFO, "u2CapInfo %x\n", prBssInfo->u2CapInfo); -+ DBGLOG(SW4, INFO, "u2ATIMWindow %x\n", prBssInfo->u2ATIMWindow); -+ DBGLOG(SW4, INFO, "u2AssocId %x\n", prBssInfo->u2AssocId); -+ DBGLOG(SW4, INFO, "ucDTIMPeriod %x\n", prBssInfo->ucDTIMPeriod); -+ DBGLOG(SW4, INFO, "ucDTIMCount %x\n", prBssInfo->ucDTIMCount); -+ DBGLOG(SW4, INFO, "fgIsNetAbsent %x\n", prBssInfo->fgIsNetAbsent); -+ DBGLOG(SW4, INFO, "eBand %d\n", prBssInfo->eBand); -+ DBGLOG(SW4, INFO, "ucPrimaryChannel %d\n", prBssInfo->ucPrimaryChannel); -+ DBGLOG(SW4, INFO, "ucHtOpInfo1 %d\n", prBssInfo->ucHtOpInfo1); -+ DBGLOG(SW4, INFO, "ucHtOpInfo2 %d\n", prBssInfo->u2HtOpInfo2); -+ DBGLOG(SW4, INFO, "ucHtOpInfo3 %d\n", prBssInfo->u2HtOpInfo3); -+ DBGLOG(SW4, INFO, "fgErpProtectMode %d\n", prBssInfo->fgErpProtectMode); -+ DBGLOG(SW4, INFO, "eHtProtectMode %d\n", prBssInfo->eHtProtectMode); -+ DBGLOG(SW4, INFO, "eGfOperationMode %d\n", prBssInfo->eGfOperationMode); -+ DBGLOG(SW4, INFO, "eRifsOperationMode %d\n", prBssInfo->eRifsOperationMode); -+ DBGLOG(SW4, INFO, "fgObssErpProtectMode %d\n", prBssInfo->fgObssErpProtectMode); -+ DBGLOG(SW4, INFO, "eObssHtProtectMode %d\n", prBssInfo->eObssHtProtectMode); -+ DBGLOG(SW4, INFO, "eObssGfProtectMode %d\n", prBssInfo->eObssGfOperationMode); -+ DBGLOG(SW4, INFO, "fgObssRifsOperationMode %d\n", prBssInfo->fgObssRifsOperationMode); -+ DBGLOG(SW4, INFO, "fgAssoc40mBwAllowed %d\n", prBssInfo->fgAssoc40mBwAllowed); -+ DBGLOG(SW4, INFO, "fg40mBwAllowed %d\n", prBssInfo->fg40mBwAllowed); -+ DBGLOG(SW4, INFO, "eBssSCO %d\n", prBssInfo->eBssSCO); -+ -+} -+ -+VOID swCtrlCmdCategory0(P_ADAPTER_T prAdapter, UINT_8 ucCate, UINT_8 ucAction, UINT_8 ucOpt0, UINT_8 ucOpt1) -+{ -+ UINT_8 ucIndex, ucRead; -+ UINT_32 i; -+ -+ DEBUGFUNC("swCtrlCmdCategory0"); -+ -+ SWCR_GET_RW_INDEX(ucAction, ucRead, ucIndex); -+ -+ i = 0; -+ -+ if (ucIndex >= SWCTRL_CATA0_INDEX_NUM) -+ return; -+ -+ if (ucRead == SWCR_WRITE) { -+ switch (ucIndex) { -+ case SWCTRL_DEBUG: -+#if DBG -+ aucDebugModule[ucOpt0] = (UINT_8) g_au4SwCr[1]; -+#endif -+ break; -+ case SWCTRL_WIFI_VAR: -+ break; -+ -+#if QM_DEBUG_COUNTER -+ case SWCTRL_DUMP_QM_DBG_CNT: -+ for (i = 0; i < QM_DBG_CNT_NUM; i++) -+ prAdapter->rQM.au4QmDebugCounters[i] = 0; -+ break; -+ case SWCTRL_QM_DBG_CNT: -+ prAdapter->rQM.au4QmDebugCounters[ucOpt0] = g_au4SwCr[1]; -+ -+ break; -+#endif -+#if CFG_RX_PKTS_DUMP -+ case SWCTRL_RX_PKTS_DUMP: -+ /* DBGLOG(SW4, INFO,("SWCTRL_RX_PKTS_DUMP: mask %x\n", g_au4SwCr[1])); */ -+ prAdapter->rRxCtrl.u4RxPktsDumpTypeMask = g_au4SwCr[1]; -+ break; -+#endif -+ case SWCTRL_RX_MDNS_FILTER: -+ { -+ UINT_32 u4rxfilter; -+ BOOLEAN fgUpdate = FALSE; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ -+ if (ucOpt0 == SWCR_RX_MDNS_FILTER_CMD_STOP) { -+ g_u4mDNSRXFilter &= ~(RX_MDNS_FILTER_START); -+ -+ u4rxfilter = prAdapter->u4OsPacketFilter; -+ fgUpdate = TRUE; -+ } else if (ucOpt0 == SWCR_RX_MDNS_FILTER_CMD_START) { -+ g_u4mDNSRXFilter |= (RX_MDNS_FILTER_START); -+ -+ u4rxfilter = prAdapter->u4OsPacketFilter; -+ if ((g_u4mDNSRXFilter & RX_MDNS_FILTER_IPV4) || -+ (g_u4mDNSRXFilter & RX_MDNS_FILTER_IPV6)) { -+ u4rxfilter |= PARAM_PACKET_FILTER_ALL_MULTICAST; -+ } -+ fgUpdate = TRUE; -+ } else if (ucOpt0 == SWCR_RX_MDNS_FILTER_CMD_ADD) { -+ if (ucOpt1 < 31) -+ g_u4mDNSRXFilter |= (1 << ucOpt1); -+ } else if (ucOpt0 == SWCR_RX_MDNS_FILTER_CMD_REMOVE) { -+ if (ucOpt1 < 31) -+ g_u4mDNSRXFilter &= ~(1 << ucOpt1); -+ } -+ -+ if (fgUpdate == TRUE) { -+ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ -+ CMD_ID_SET_RX_FILTER, /* ucCID */ -+ TRUE, /* fgSetQuery */ -+ FALSE, /* fgNeedResp */ -+ FALSE, /* fgIsOid */ -+ NULL, /* pfCmdDoneHandler */ -+ NULL, /* pfCmdTimeoutHandler */ -+ sizeof(UINT_32), /* u4SetQueryInfoLen */ -+ (PUINT_8)&u4rxfilter, /* pucInfoBuffer */ -+ NULL, /* pvSetQueryBuffer */ -+ 0 /* un4SetQueryBufferLen */ -+ ); -+ } -+/* DBGLOG(SW4, INFO,("SWCTRL_RX_MDNS_FILTER: g_u4mDNSRXFilter %x ucOpt0 %x ucOpt1 %x fgUpdate %x u4rxfilter %x, */ -+/* rStatus %x\n", g_u4mDNSRXFilter, ucOpt0, ucOpt1, fgUpdate, u4rxfilter, rStatus)); */ -+ } -+ break; -+ default: -+ break; -+ } -+ } else { -+ switch (ucIndex) { -+ case SWCTRL_DEBUG: -+#if DBG -+ g_au4SwCr[1] = aucDebugModule[ucOpt0]; -+#endif -+ break; -+ case SWCTRL_MAGIC: -+ g_au4SwCr[1] = _SWCTRL_MAGIC; -+ /* DBGLOG(SW4, INFO, "BUILD TIME: %s %s\n", __DATE__, __TIME__); */ -+ break; -+ case SWCTRL_QM_INFO: -+ { -+ P_QUE_MGT_T prQM = &prAdapter->rQM; -+ -+ switch (ucOpt0) { -+ case 0: -+ g_au4SwCr[1] = (QM_GET_TX_QUEUE_LEN(prAdapter, ucOpt1)); -+ g_au4SwCr[2] = prQM->au4MinReservedTcResource[ucOpt1]; -+ g_au4SwCr[3] = prQM->au4CurrentTcResource[ucOpt1]; -+ g_au4SwCr[4] = prQM->au4GuaranteedTcResource[ucOpt1]; -+ break; -+ -+ case 1: -+ g_au4SwCr[1] = prQM->au4ForwardCount[ucOpt1]; -+ g_au4SwCr[2] = prQM->au4HeadStaRecIndex[ucOpt1]; -+ break; -+ -+ case 2: -+ g_au4SwCr[1] = prQM->arTxQueue[ucOpt1].u4NumElem; /* only one */ -+ -+ break; -+ } -+ -+ } -+ break; -+ case SWCTRL_TX_CTRL_INFO: -+ { -+ P_TX_CTRL_T prTxCtrl; -+ -+ prTxCtrl = &prAdapter->rTxCtrl; -+ switch (ucOpt0) { -+ case 0: -+ g_au4SwCr[1] = prAdapter->rTxCtrl.rTc.aucFreeBufferCount[ucOpt1]; -+ g_au4SwCr[2] = prAdapter->rTxCtrl.rTc.aucMaxNumOfBuffer[ucOpt1]; -+ break; -+ } -+ -+ } -+ break; -+ case SWCTRL_DUMP_QUEUE: -+ dumpQueue(prAdapter); -+ -+ break; -+#if QM_DEBUG_COUNTER -+ case SWCTRL_DUMP_QM_DBG_CNT: -+ for (i = 0; i < QM_DBG_CNT_NUM; i++) -+ DBGLOG(SW4, INFO, "QM:DBG %u %u\n", i, prAdapter->rQM.au4QmDebugCounters[i]); -+ break; -+ -+ case SWCTRL_QM_DBG_CNT: -+ g_au4SwCr[1] = prAdapter->rQM.au4QmDebugCounters[ucOpt0]; -+ break; -+#endif -+ case SWCTRL_DUMP_BSS: -+ { -+ dumpBss(prAdapter, &(prAdapter->rWifiVar.arBssInfo[ucOpt0])); -+ } -+ break; -+ -+ default: -+ break; -+ } -+ -+ } -+} -+ -+VOID swCtrlCmdCategory1(P_ADAPTER_T prAdapter, UINT_8 ucCate, UINT_8 ucAction, UINT_8 ucOpt0, UINT_8 ucOpt1) -+{ -+ UINT_8 ucIndex, ucRead; -+ UINT_8 ucWTEntry; -+ P_STA_RECORD_T prStaRec; -+ -+ DEBUGFUNC("swCtrlCmdCategory1"); -+ -+ SWCR_GET_RW_INDEX(ucAction, ucRead, ucIndex); -+ -+ if (ucOpt0 >= CFG_STA_REC_NUM) -+ return; -+ -+ /* prStaRec = cnmGetStaRecByIndex (prAdapter, ucOpt0); */ -+ prStaRec = &prAdapter->arStaRec[ucOpt0]; -+ ucWTEntry = prStaRec->ucWTEntry; -+ if (ucRead == SWCR_WRITE) { -+ /* Do nothing */ -+ } else { -+ /* Read */ -+ switch (ucIndex) { -+ case SWCTRL_STA_QUE_INFO: -+ { -+ g_au4SwCr[1] = prStaRec->arTxQueue[ucOpt1].u4NumElem; -+ } -+ break; -+ case SWCTRL_STA_INFO: -+ switch (ucOpt1) { -+ case 0: -+ g_au4SwCr[1] = prStaRec->fgIsInPS; -+ break; -+ } -+ -+ break; -+ -+ case SWCTRL_DUMP_STA: -+ { -+ dumpSTA(prAdapter, prStaRec); -+ } -+ break; -+ -+ default: -+ -+ break; -+ } -+ } -+ -+} -+ -+#if TEST_PS -+ -+VOID -+testPsSendQoSNullFrame(IN P_ADAPTER_T prAdapter, -+ IN P_STA_RECORD_T prStaRec, -+ IN UINT_8 ucUP, -+ IN UINT_8 ucNetTypeIndex, -+ IN BOOLEAN fgBMC, -+ IN BOOLEAN fgIsBurstEnd, IN BOOLEAN ucPacketType, IN BOOLEAN ucPsSessionID, IN BOOLEAN fgSetEOSP) -+{ -+ P_MSDU_INFO_T prMsduInfo; -+ UINT_16 u2EstimatedFrameLen; -+ P_WLAN_MAC_HEADER_QOS_T prQoSNullFrame; -+ -+ DEBUGFUNC("testPsSendQoSNullFrame"); -+ DBGLOG(SW4, LOUD, "\n"); -+ -+ /* 4 <1> Allocate a PKT_INFO_T for Null Frame */ -+ /* Init with MGMT Header Length */ -+ u2EstimatedFrameLen = MAC_TX_RESERVED_FIELD + WLAN_MAC_HEADER_QOS_LEN; -+ -+ /* Allocate a MSDU_INFO_T */ -+ prMsduInfo = cnmMgtPktAlloc(prAdapter, u2EstimatedFrameLen); -+ if (prMsduInfo == NULL) { -+ DBGLOG(SW4, WARN, "No PKT_INFO_T for sending Null Frame.\n"); -+ return; -+ } -+ /* 4 <2> Compose Null frame in MSDU_INfO_T. */ -+ bssComposeQoSNullFrame(prAdapter, -+ (PUINT_8) ((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD), -+ prStaRec, ucUP, fgSetEOSP); -+ -+ prMsduInfo->eSrc = TX_PACKET_MGMT; -+ /* prMsduInfo->ucPacketType = HIF_TX_PACKET_TYPE_DATA; */ -+ prMsduInfo->ucPacketType = ucPacketType; -+ prMsduInfo->ucStaRecIndex = prStaRec->ucIndex; -+ prMsduInfo->ucNetworkType = ucNetTypeIndex; -+ prMsduInfo->ucMacHeaderLength = WLAN_MAC_HEADER_QOS_LEN; -+ prMsduInfo->fgIs802_1x = FALSE; -+ prMsduInfo->fgIs802_11 = TRUE; -+ prMsduInfo->u2FrameLength = WLAN_MAC_HEADER_QOS_LEN; -+ prMsduInfo->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter); -+ prMsduInfo->pfTxDoneHandler = NULL; -+ prMsduInfo->fgIsBasicRate = TRUE; -+ prMsduInfo->fgIsBurstEnd = fgIsBurstEnd; -+ prMsduInfo->ucUserPriority = ucUP; -+ prMsduInfo->ucPsSessionID = ucPsSessionID /* 0~7 Test 7 means NOACK */; -+ -+ prQoSNullFrame = (P_WLAN_MAC_HEADER_QOS_T) (((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD)); -+ -+ if (fgBMC) -+ prQoSNullFrame->aucAddr1[0] = 0xfd; -+ else -+ prQoSNullFrame->aucAddr1[5] = 0xdd; -+ -+ /* 4 <4> Inform TXM to send this Null frame. */ -+ nicTxEnqueueMsdu(prAdapter, prMsduInfo); -+ -+} -+ -+VOID testPsSetupBss(IN P_ADAPTER_T prAdapter, IN UINT_8 ucNetworkTypeIndex) -+{ -+ P_BSS_INFO_T prBssInfo; -+ UINT_8 _aucZeroMacAddr[] = NULL_MAC_ADDR; -+ -+ DEBUGFUNC("testPsSetupBss()"); -+ DBGLOG(SW4, INFO, "index %d\n", ucNetworkTypeIndex); -+ -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[ucNetworkTypeIndex]); -+ -+ /* 4 <1.2> Initiate PWR STATE */ -+ /* SET_NET_PWR_STATE_IDLE(prAdapter, ucNetworkTypeIndex); */ -+ -+ /* 4 <2> Initiate BSS_INFO_T - common part */ -+ BSS_INFO_INIT(prAdapter, ucNetworkTypeIndex); -+ -+ prBssInfo->eConnectionState = PARAM_MEDIA_STATE_DISCONNECTED; -+ prBssInfo->eConnectionStateIndicated = PARAM_MEDIA_STATE_DISCONNECTED; -+ prBssInfo->eCurrentOPMode = OP_MODE_ACCESS_POINT; -+ prBssInfo->fgIsNetActive = TRUE; -+ prBssInfo->ucNetTypeIndex = (ucNetworkTypeIndex); -+ prBssInfo->ucReasonOfDisconnect = DISCONNECT_REASON_CODE_RESERVED; -+ -+ prBssInfo->ucPhyTypeSet = PHY_TYPE_SET_802_11BG; /* Depend on eBand */ -+ prBssInfo->ucConfigAdHocAPMode = AP_MODE_MIXED_11BG; /* Depend on eCurrentOPMode and ucPhyTypeSet */ -+ prBssInfo->u2BSSBasicRateSet = RATE_SET_ERP; -+ prBssInfo->u2OperationalRateSet = RATE_SET_OFDM; -+ prBssInfo->fgErpProtectMode = FALSE; -+ prBssInfo->fgIsQBSS = TRUE; -+ -+ /* 4 <1.5> Setup MIB for current BSS */ -+ prBssInfo->u2BeaconInterval = 100; -+ prBssInfo->ucDTIMPeriod = DOT11_DTIM_PERIOD_DEFAULT; -+ prBssInfo->u2ATIMWindow = 0; -+ -+ prBssInfo->ucBeaconTimeoutCount = 0; -+ -+ bssInitForAP(prAdapter, prBssInfo, TRUE); -+ -+ COPY_MAC_ADDR(prBssInfo->aucBSSID, _aucZeroMacAddr); -+ LINK_INITIALIZE(&prBssInfo->rStaRecOfClientList); -+ prBssInfo->fgIsBeaconActivated = TRUE; -+ prBssInfo->ucHwDefaultFixedRateCode = RATE_CCK_1M_LONG; -+ -+ COPY_MAC_ADDR(prBssInfo->aucOwnMacAddr, prAdapter->rWifiVar.aucMacAddress); -+ -+ /* 4 <3> Initiate BSS_INFO_T - private part */ -+ /* TODO */ -+ prBssInfo->eBand = BAND_2G4; -+ prBssInfo->ucPrimaryChannel = 1; -+ prBssInfo->prStaRecOfAP = (P_STA_RECORD_T) NULL; -+ -+ /* prBssInfo->fgErpProtectMode = eErpProectMode; */ -+ /* prBssInfo->eHtProtectMode = eHtProtectMode; */ -+ /* prBssInfo->eGfOperationMode = eGfOperationMode; */ -+ -+ /* 4 <4> Allocate MSDU_INFO_T for Beacon */ -+ prBssInfo->prBeacon = cnmMgtPktAlloc(prAdapter, OFFSET_OF(WLAN_BEACON_FRAME_T, aucInfoElem[0]) + MAX_IE_LENGTH); -+ -+ if (prBssInfo->prBeacon) { -+ prBssInfo->prBeacon->eSrc = TX_PACKET_MGMT; -+ prBssInfo->prBeacon->ucNetworkType = ucNetworkTypeIndex; -+ } else { -+ DBGLOG(SW4, INFO, "prBeacon allocation fail\n"); -+ } -+ -+#if 0 -+ prBssInfo->rPmProfSetupInfo.ucBmpDeliveryAC = PM_UAPSD_ALL; -+ prBssInfo->rPmProfSetupInfo.ucBmpTriggerAC = PM_UAPSD_ALL; -+ prBssInfo->rPmProfSetupInfo.ucUapsdSp = WMM_MAX_SP_LENGTH_2; -+#else -+ prBssInfo->rPmProfSetupInfo.ucBmpDeliveryAC = (UINT_8) prAdapter->u4UapsdAcBmp; -+ prBssInfo->rPmProfSetupInfo.ucBmpTriggerAC = (UINT_8) prAdapter->u4UapsdAcBmp; -+ prBssInfo->rPmProfSetupInfo.ucUapsdSp = (UINT_8) prAdapter->u4MaxSpLen; -+#endif -+ -+#if 0 -+ for (eAci = 0; eAci < WMM_AC_INDEX_NUM; eAci++) { -+ -+ prBssInfo->arACQueParms[eAci].fgIsACMSet = FALSE; -+ prBssInfo->arACQueParms[eAci].u2Aifsn = (UINT_16) eAci; -+ prBssInfo->arACQueParms[eAci].u2CWmin = 7; -+ prBssInfo->arACQueParms[eAci].u2CWmax = 31; -+ prBssInfo->arACQueParms[eAci].u2TxopLimit = eAci + 1; -+ DBGLOG(SW4, INFO, "MQM: eAci = %d, ACM = %d, Aifsn = %d, CWmin = %d, CWmax = %d, TxopLimit = %d\n", -+ eAci, prBssInfo->arACQueParms[eAci].fgIsACMSet, -+ prBssInfo->arACQueParms[eAci].u2Aifsn, -+ prBssInfo->arACQueParms[eAci].u2CWmin, -+ prBssInfo->arACQueParms[eAci].u2CWmax, prBssInfo->arACQueParms[eAci].u2TxopLimit)); -+ -+ } -+#endif -+ -+ DBGLOG(SW4, INFO, "[2] ucBmpDeliveryAC:0x%x, ucBmpTriggerAC:0x%x, ucUapsdSp:0x%x", -+ prBssInfo->rPmProfSetupInfo.ucBmpDeliveryAC, -+ prBssInfo->rPmProfSetupInfo.ucBmpTriggerAC, prBssInfo->rPmProfSetupInfo.ucUapsdSp); -+ -+} -+ -+VOID testPsCmdCategory0(P_ADAPTER_T prAdapter, UINT_8 ucCate, UINT_8 ucAction, UINT_8 ucOpt0, UINT_8 ucOpt1) -+{ -+ UINT_8 ucIndex, ucRead; -+ P_STA_RECORD_T prStaRec; -+ -+ DEBUGFUNC("testPsCmdCategory0"); -+ SWCR_GET_RW_INDEX(ucAction, ucRead, ucIndex); -+ -+ DBGLOG(SW4, LOUD, "Read %u Index %u\n", ucRead, ucIndex); -+ -+ prStaRec = cnmGetStaRecByIndex(prAdapter, 0); -+ -+ if (ucIndex >= TEST_PS_CATA0_INDEX_NUM) -+ return; -+ -+ if (ucRead == SWCR_WRITE) { -+ switch (ucIndex) { -+ case TEST_PS_SETUP_BSS: -+ testPsSetupBss(prAdapter, ucOpt0); -+ break; -+ -+ case TEST_PS_ENABLE_BEACON: -+ break; -+ -+ case TEST_PS_TRIGGER_BMC: -+ /* txmForwardQueuedBmcPkts (ucOpt0); */ -+ break; -+ case TEST_PS_SEND_NULL: -+ { -+ -+ testPsSendQoSNullFrame(prAdapter, prStaRec, (UINT_8) (g_au4SwCr[1] & 0xFF), /* UP */ -+ ucOpt0, (BOOLEAN) ((g_au4SwCr[1] >> 8) & 0xFF), /* BMC */ -+ (BOOLEAN) ((g_au4SwCr[1] >> 16) & 0xFF), /* BurstEnd */ -+ (BOOLEAN) ((g_au4SwCr[1] >> 24) & 0xFF), /* Packet type */ -+ (UINT_8) ((g_au4SwCr[2]) & 0xFF), /* PS sesson ID 7: NOACK */ -+ FALSE /* EOSP */ -+ ); -+ } -+ break; -+ case TEST_PS_BUFFER_BMC: -+ /* g_aprBssInfo[ucOpt0]->fgApToBufferBMC = (g_au4SwCr[1] & 0xFF); */ -+ break; -+ case TEST_PS_UPDATE_BEACON: -+ bssUpdateBeaconContent(prAdapter, ucOpt0 /*networktype */); -+ break; -+ -+ default: -+ break; -+ } -+ } else { -+ switch (ucIndex) { -+ -+ case TEST_PS_MAGIC: -+ g_au4SwCr[1] = 0x88660011; -+ break; -+ -+ } -+ } -+} -+ -+#endif /* TEST_PS */ -+ -+#if TEST_PS -+ -+VOID testPsCmdCategory1(P_ADAPTER_T prAdapter, UINT_8 ucCate, UINT_8 ucAction, UINT_8 ucOpt0, UINT_8 ucOpt1) -+{ -+ UINT_8 ucIndex, ucRead; -+ UINT_8 ucWTEntry; -+ P_STA_RECORD_T prStaRec; -+ -+ DEBUGFUNC("testPsCmdCategory1"); -+ -+ SWCR_GET_RW_INDEX(ucAction, ucRead, ucIndex); -+ -+ if (ucOpt0 >= CFG_STA_REC_NUM) -+ return; -+ -+ prStaRec = cnmGetStaRecByIndex(prAdapter, ucOpt0); -+ if (!prStaRec) -+ return; -+ ucWTEntry = prStaRec->ucWTEntry; -+ if (ucRead == SWCR_WRITE) { -+ -+ switch (ucIndex) { -+ case TEST_PS_STA_PS: -+ prStaRec->fgIsInPS = (BOOLEAN) (g_au4SwCr[1] & 0x1); -+ prStaRec->fgIsQoS = (BOOLEAN) (g_au4SwCr[1] >> 8 & 0xFF); -+ prStaRec->fgIsUapsdSupported = (BOOLEAN) (g_au4SwCr[1] >> 16 & 0xFF); -+ prStaRec->ucBmpDeliveryAC = (BOOLEAN) (g_au4SwCr[1] >> 24 & 0xFF); -+ break; -+ -+ } -+ -+ } else { -+ /* Read */ -+ switch (ucIndex) { -+ default: -+ break; -+ } -+ } -+ -+} -+ -+#endif /* TEST_PS */ -+ -+#if CFG_SUPPORT_802_11V -+#if (CFG_SUPPORT_802_11V_TIMING_MEASUREMENT == 1) && (WNM_UNIT_TEST == 1) -+VOID testWNMCmdCategory0(P_ADAPTER_T prAdapter, UINT_8 ucCate, UINT_8 ucAction, UINT_8 ucOpt0, UINT_8 ucOpt1) -+{ -+ UINT_8 ucIndex, ucRead; -+ P_STA_RECORD_T prStaRec; -+ -+ DEBUGFUNC("testWNMCmdCategory0"); -+ SWCR_GET_RW_INDEX(ucAction, ucRead, ucIndex); -+ -+ DBGLOG(SW4, INFO, "Read %u Index %u\n", ucRead, ucIndex); -+ -+ if (ucIndex >= TEST_WNM_CATA0_INDEX_NUM) -+ return; -+ -+ if (ucRead == SWCR_WRITE) { -+ switch (ucIndex) { -+ case TEST_WNM_TIMING_MEAS: -+ wnmTimingMeasUnitTest1(prAdapter, ucOpt0); -+ break; -+ -+ default: -+ break; -+ } -+ } -+} -+#endif /* TEST_WNM */ -+#endif /* CFG_SUPPORT_802_11V */ -+ -+VOID swCtrlSwCr(P_ADAPTER_T prAdapter, UINT_8 ucRead, UINT_16 u2Addr, UINT_32 *pu4Data) -+{ -+ /* According other register STAIDX */ -+ UINT_8 ucOffset; -+ -+ ucOffset = (u2Addr >> 2) & 0x3F; -+ -+ if (ucOffset >= SWCR_CR_NUM) -+ return; -+ -+ if (ucRead == SWCR_WRITE) { -+ g_au4SwCr[ucOffset] = *pu4Data; -+ if (ucOffset == 0x0) { -+ /* Commmand [31:24]: Category */ -+ /* Commmand [23:23]: 1(W) 0(R) */ -+ /* Commmand [22:16]: Index */ -+ /* Commmand [15:08]: Option0 */ -+ /* Commmand [07:00]: Option1 */ -+ UINT_8 ucCate; -+ UINT_32 u4Cmd; -+ -+ u4Cmd = g_au4SwCr[0]; -+ ucCate = (UINT_8) (u4Cmd >> 24); -+ if (ucCate < sizeof(g_arSwCtrlCmd) / sizeof(g_arSwCtrlCmd[0])) { -+ if (g_arSwCtrlCmd[ucCate] != NULL) { -+ g_arSwCtrlCmd[ucCate] (prAdapter, ucCate, (UINT_8) (u4Cmd >> 16 & 0xFF), -+ (UINT_8) ((u4Cmd >> 8) & 0xFF), (UINT_8) (u4Cmd & 0xFF)); -+ } -+ } -+ } -+ } else { -+ *pu4Data = g_au4SwCr[ucOffset]; -+ } -+} -+ -+VOID swCrReadWriteCmd(P_ADAPTER_T prAdapter, UINT_8 ucRead, UINT_16 u2Addr, UINT_32 *pu4Data) -+{ -+ UINT_8 ucMod; -+ -+ ucMod = u2Addr >> 8; -+ /* Address [15:8] MOD ID */ -+ /* Address [7:0] OFFSET */ -+ -+ DEBUGFUNC("swCrReadWriteCmd"); -+ DBGLOG(SW4, TRACE, "%u addr 0x%x data 0x%x\n", ucRead, u2Addr, *pu4Data); -+ -+ if (ucMod < (sizeof(g_arSwCrModHandle) / sizeof(g_arSwCrModHandle[0]))) { -+ -+ if (g_arSwCrModHandle[ucMod] != NULL) -+ g_arSwCrModHandle[ucMod] (prAdapter, ucRead, u2Addr, pu4Data); -+ } /* ucMod */ -+} -+ -+/* Debug Support */ -+VOID swCrFrameCheckEnable(P_ADAPTER_T prAdapter, UINT_32 u4DumpType) -+{ -+ g_u4SwcrDebugFrameDumpType = u4DumpType; -+ prAdapter->rRxCtrl.u4RxPktsDumpTypeMask = u4DumpType; -+} -+ -+VOID swCrDebugInit(P_ADAPTER_T prAdapter) -+{ -+ /* frame dump */ -+ if (g_u4SwcrDebugFrameDumpType) -+ swCrFrameCheckEnable(prAdapter, g_u4SwcrDebugFrameDumpType); -+ /* debug counter */ -+ g_fgSwcrDebugTimer = FALSE; -+ -+ cnmTimerInitTimer(prAdapter, &g_rSwcrDebugTimer, (PFN_MGMT_TIMEOUT_FUNC) swCrDebugCheckTimeout, (ULONG) NULL); -+ -+ if (g_u4SwcrDebugCheckTimeout) -+ swCrDebugCheckEnable(prAdapter, TRUE, g_ucSwcrDebugCheckType, g_u4SwcrDebugCheckTimeout); -+} -+ -+VOID swCrDebugUninit(P_ADAPTER_T prAdapter) -+{ -+ cnmTimerStopTimer(prAdapter, &g_rSwcrDebugTimer); -+ -+ g_fgSwcrDebugTimer = FALSE; -+} -+ -+VOID swCrDebugCheckEnable(P_ADAPTER_T prAdapter, BOOLEAN fgIsEnable, UINT_8 ucType, UINT_32 u4Timeout) -+{ -+ if (fgIsEnable) { -+ g_ucSwcrDebugCheckType = ucType; -+ g_u4SwcrDebugCheckTimeout = u4Timeout; -+ if (g_fgSwcrDebugTimer == FALSE) -+ swCrDebugCheckTimeout(prAdapter, 0); -+ } else { -+ cnmTimerStopTimer(prAdapter, &g_rSwcrDebugTimer); -+ g_u4SwcrDebugCheckTimeout = 0; -+ } -+ -+ g_fgSwcrDebugTimer = fgIsEnable; -+} -+ -+VOID swCrDebugCheck(P_ADAPTER_T prAdapter, P_CMD_SW_DBG_CTRL_T prCmdSwCtrl) -+{ -+ P_RX_CTRL_T prRxCtrl; -+ P_TX_CTRL_T prTxCtrl; -+ -+ ASSERT(prAdapter); -+ -+ prTxCtrl = &prAdapter->rTxCtrl; -+ prRxCtrl = &prAdapter->rRxCtrl; -+ -+ /* dump counters */ -+ if (prCmdSwCtrl) { -+ if (prCmdSwCtrl->u4Data == SWCR_DBG_TYPE_ALL) { -+ -+ /* TX Counter from fw */ -+ DBGLOG(SW4, INFO, "TX0\n" -+ "%08x %08x %08x %08x\n" -+ "%08x %08x %08x %08x\n", -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_TX_CNT], -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_TX_BCN_CNT], -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_TX_FAILED_CNT], -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_TX_RETRY_CNT], -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_TX_AGING_TIMEOUT_CNT], -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_TX_PS_OVERFLOW_CNT], -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_TX_MGNT_DROP_CNT], -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_TX_ERROR_CNT]); -+#if 1 -+ /* TX Counter from drv */ -+ DBGLOG(SW4, INFO, "TX1\n" -+ "%08x %08x %08x %08x\n", -+ (UINT_32) TX_GET_CNT(prTxCtrl, TX_INACTIVE_BSS_DROP), -+ (UINT_32) TX_GET_CNT(prTxCtrl, TX_INACTIVE_STA_DROP), -+ (UINT_32) TX_GET_CNT(prTxCtrl, TX_FORWARD_OVERFLOW_DROP), -+ (UINT_32) TX_GET_CNT(prTxCtrl, TX_AP_BORADCAST_DROP)); -+#endif -+ -+ /* RX Counter */ -+ DBGLOG(SW4, INFO, "RX0\n" -+ "%08x %08x %08x %08x\n" -+ "%08x %08x %08x %08x\n" -+ "%08x %08x %08x %08x\n" -+ "%08x %08x %08x %08x\n", -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_RX_CNT], -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_RX_DROP_CNT], -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_RX_DUP_DROP_CNT], -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_RX_TYPE_ERROR_DROP_CNT], -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_RX_CLASS_ERROR_DROP_CNT], -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_RX_AMPDU_ERROR_DROP_CNT], -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_RX_STATUS_ERROR_DROP_CNT], -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_RX_FORMAT_ERROR_DROP_CNT], -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_RX_ICV_ERROR_DROP_CNT], -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_RX_KEY_ERROR_DROP_CNT], -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_RX_TKIP_ERROR_DROP_CNT], -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_RX_MIC_ERROR_DROP_CNT], -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_RX_BIP_ERROR_DROP_CNT], -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_RX_FCSERR_CNT], -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_RX_FIFOFULL_CNT], -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_RX_PFDROP_CNT]); -+ -+ DBGLOG(SW4, INFO, "RX1\n" -+ "%08x %08x %08x %08x\n" -+ "%08x %08x %08x %08x\n", -+ (UINT_32) RX_GET_CNT(prRxCtrl, RX_MPDU_TOTAL_COUNT), -+ (UINT_32) RX_GET_CNT(prRxCtrl, RX_DATA_INDICATION_COUNT), -+ (UINT_32) RX_GET_CNT(prRxCtrl, RX_DATA_RETURNED_COUNT), -+ (UINT_32) RX_GET_CNT(prRxCtrl, RX_DATA_RETAINED_COUNT), -+ (UINT_32) RX_GET_CNT(prRxCtrl, RX_DROP_TOTAL_COUNT), -+ (UINT_32) RX_GET_CNT(prRxCtrl, RX_TYPE_ERR_DROP_COUNT), -+ (UINT_32) RX_GET_CNT(prRxCtrl, RX_CLASS_ERR_DROP_COUNT), -+ (UINT_32) RX_GET_CNT(prRxCtrl, RX_DST_NULL_DROP_COUNT)); -+ -+ DBGLOG(SW4, INFO, "PWR\n" -+ "%08x %08x %08x %08x\n" -+ "%08x %08x %08x %08x\n", -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_PWR_PS_POLL_CNT], -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_PWR_TRIGGER_NULL_CNT], -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_PWR_BCN_IND_CNT], -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_PWR_BCN_TIMEOUT_CNT], -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_PWR_PM_STATE0], -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_PWR_PM_STATE1], -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_PWR_CUR_PS_PROF0], -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_PWR_CUR_PS_PROF1]); -+ -+ DBGLOG(SW4, INFO, "ARM\n" -+ "%08x %08x %08x %08x\n" -+ "%08x %08x\n", -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_AR_STA0_RATE], -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_AR_STA0_BWGI], -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_AR_STA0_RX_RATE_RCPI], -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_ROAMING_ENABLE], -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_ROAMING_ROAM_CNT], -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_ROAMING_INT_CNT]); -+ -+ DBGLOG(SW4, INFO, "BB\n" -+ "%08x %08x %08x %08x\n" -+ "%08x %08x %08x %08x\n", -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_BB_RX_MDRDY_CNT], -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_BB_RX_FCSERR_CNT], -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_BB_CCK_PD_CNT], -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_BB_OFDM_PD_CNT], -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_BB_CCK_SFDERR_CNT], -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_BB_CCK_SIGERR_CNT], -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_BB_OFDM_TAGERR_CNT], -+ prCmdSwCtrl->u4DebugCnt[SWCR_DBG_ALL_BB_OFDM_SIGERR_CNT]); -+ -+ } -+ } -+ /* start the next check */ -+ if (g_u4SwcrDebugCheckTimeout) -+ cnmTimerStartTimer(prAdapter, &g_rSwcrDebugTimer, g_u4SwcrDebugCheckTimeout * MSEC_PER_SEC); -+} -+ -+VOID swCrDebugCheckTimeout(IN P_ADAPTER_T prAdapter, ULONG ulParam) -+{ -+ CMD_SW_DBG_CTRL_T rCmdSwCtrl; -+ WLAN_STATUS rStatus; -+ -+ rCmdSwCtrl.u4Id = (0xb000 << 16) + g_ucSwcrDebugCheckType; -+ rCmdSwCtrl.u4Data = 0; -+ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ -+ CMD_ID_SW_DBG_CTRL, /* ucCID */ -+ FALSE, /* fgSetQuery */ -+ TRUE, /* fgNeedResp */ -+ FALSE, /* fgIsOid */ -+ swCrDebugQuery, /* pfCmdDoneHandler */ -+ swCrDebugQueryTimeout, /* pfCmdTimeoutHandler */ -+ sizeof(CMD_SW_DBG_CTRL_T), /* u4SetQueryInfoLen */ -+ (PUINT_8)&rCmdSwCtrl, /* pucInfoBuffer */ -+ NULL, /* pvSetQueryBuffer */ -+ 0 /* u4SetQueryBufferLen */ -+ ); -+ -+ ASSERT(rStatus == WLAN_STATUS_PENDING); -+ -+} -+ -+VOID swCrDebugQuery(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) -+{ -+ ASSERT(prAdapter); -+ -+ swCrDebugCheck(prAdapter, (P_CMD_SW_DBG_CTRL_T) (pucEventBuf)); -+} -+ -+VOID swCrDebugQueryTimeout(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo) -+{ -+ ASSERT(prAdapter); -+ -+ swCrDebugCheck(prAdapter, NULL); -+} -+ -+#endif /* CFG_SUPPORT_SWCR */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/tdls.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/tdls.c -new file mode 100644 -index 000000000000..96293c57e2b0 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/tdls.c -@@ -0,0 +1,5199 @@ -+/* -+** Id: tdls.c#1 -+*/ -+ -+/*! \file tdls.c -+ \brief This file includes IEEE802.11z TDLS support. -+*/ -+ -+/* -+** Log: tdls.c -+ * -+ * 11 13 2013 vend_samp.lin -+ * NULL -+ * Initial version. -+ */ -+ -+/******************************************************************************* -+ * C O M P I L E R F L A G S -+ ******************************************************************************** -+ */ -+ -+/******************************************************************************* -+ * E X T E R N A L R E F E R E N C E S -+ ******************************************************************************** -+ */ -+#include "precomp.h" -+ -+#if (CFG_SUPPORT_TDLS == 1) -+#include "gl_wext.h" -+#include "tdls.h" -+#include "gl_cfg80211.h" -+#include -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+static VOID TdlsCmdTestRxIndicatePkts(GLUE_INFO_T *prGlueInfo, struct sk_buff *prSkb); -+ -+#if TDLS_CFG_CMD_TEST -+static void TdlsCmdTestAddPeer(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); -+ -+static void TdlsCmdTestChSwProhibitedBitSet(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); -+ -+static void TdlsCmdTestChSwReqRecv(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); -+ -+static void TdlsCmdTestChSwRspRecv(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); -+ -+static void TdlsCmdTestChSwTimeoutSkip(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); -+ -+static void TdlsCmdTestDataContSend(GLUE_INFO_T *prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); -+ -+static void TdlsCmdTestDataRecv(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); -+ -+static void TdlsCmdTestDataSend(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); -+ -+static void TdlsCmdTestDelay(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); -+ -+static void TdlsCmdTestDiscoveryReqRecv(GLUE_INFO_T *prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); -+ -+static void TdlsCmdTestKeepAliveSkip(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); -+ -+static void TdlsCmdTestProhibitedBitSet(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); -+ -+static void TdlsCmdTestPtiReqRecv(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); -+ -+static void TdlsCmdTestPtiRspRecv(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); -+ -+static void TdlsCmdTestPtiTxDoneFail(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); -+ -+static void TdlsCmdTestRvFrame(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); -+ -+static void TdlsCmdTestSetupConfirmRecv(GLUE_INFO_T *prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); -+ -+static void TdlsCmdTestSetupReqRecv(GLUE_INFO_T *prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); -+ -+static void TdlsCmdTestSetupRspRecv(GLUE_INFO_T *prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); -+ -+static void TdlsCmdTestScanCtrl(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); -+ -+static void TdlsCmdTestTearDownRecv(GLUE_INFO_T *prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); -+ -+static void TdlsCmdTestTxFailSkip(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); -+ -+static void TdlsCmdTestTxTdlsFrame(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); -+ -+static void TdlsCmdTestTxFrame(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); -+ -+static TDLS_STATUS -+TdlsCmdTestTxFmeSetupReqBufTranslate(UINT_8 *pCmdBuf, UINT_32 u4BufLen, PARAM_CUSTOM_TDLS_CMD_STRUCT_T *prCmd); -+ -+static void TdlsCmdTestUpdatePeer(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); -+ -+static void TdlsCmdTestNullRecv(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); -+ -+static VOID TdlsTimerTestDataContSend(ADAPTER_T *prAdapter, UINT_32 u4Param); -+ -+static TDLS_STATUS -+TdlsTestChStReqRecv(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen); -+ -+static TDLS_STATUS -+TdlsTestChStRspRecv(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen); -+ -+static TDLS_STATUS -+TdlsTestFrameSend(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen); -+ -+static TDLS_STATUS -+TdlsTestNullRecv(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen); -+ -+static TDLS_STATUS -+TdlsTestPtiReqRecv(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen); -+ -+static TDLS_STATUS -+TdlsTestPtiRspRecv(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen); -+ -+static TDLS_STATUS -+TdlsTestTearDownRecv(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen); -+ -+static TDLS_STATUS -+TdlsTestDataRecv(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen); -+ -+static TDLS_STATUS -+TdlsTestPtiTxFail(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen); -+ -+static TDLS_STATUS -+TdlsTestTdlsFrameSend(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen); -+ -+static TDLS_STATUS -+TdlsTestTxFailSkip(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen); -+ -+static TDLS_STATUS -+TdlsTestKeepAliveSkip(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen); -+ -+static TDLS_STATUS -+TdlsTestChSwTimeoutSkip(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen); -+ -+static TDLS_STATUS -+TdlsTestScanSkip(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen); -+ -+static TDLS_STATUS -+TdlsChSwConf(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen); -+ -+static void TdlsCmdChSwConf(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); -+ -+static void TdlsCmdInfoDisplay(GLUE_INFO_T *prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); -+ -+static void TdlsCmdKeyInfoDisplay(GLUE_INFO_T *prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); -+ -+static void TdlsCmdMibParamUpdate(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); -+ -+static void TdlsCmdSetupConf(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); -+ -+static void TdlsCmdUapsdConf(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); -+ -+static TDLS_STATUS -+TdlsInfoDisplay(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen); -+ -+static TDLS_STATUS -+TdlsKeyInfoDisplay(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen); -+ -+static VOID -+TdlsLinkHistoryRecord(GLUE_INFO_T *prGlueInfo, -+ BOOLEAN fgIsTearDown, -+ UINT8 *pucPeerMac, BOOLEAN fgIsFromUs, UINT16 u2ReasonCode, VOID *prOthers); -+ -+static VOID -+TdlsLinkHistoryRecordUpdate(GLUE_INFO_T *prGlueInfo, -+ UINT8 *pucPeerMac, TDLS_EVENT_HOST_SUBID_SPECIFIC_FRAME eFmeStatus, VOID *pInfo); -+ -+static TDLS_STATUS -+TdlsMibParamUpdate(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen); -+ -+static TDLS_STATUS -+TdlsSetupConf(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen); -+ -+static TDLS_STATUS -+TdlsUapsdConf(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen); -+ -+static void TdlsEventStatistics(GLUE_INFO_T *prGlueInfo, UINT8 *prInBuf, UINT32 u4InBufLen); -+ -+static void TdlsEventTearDown(GLUE_INFO_T *prGlueInfo, UINT8 *prInBuf, UINT32 u4InBufLen); -+ -+#endif /* TDLS_CFG_CMD_TEST */ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+static BOOLEAN fgIsPtiTimeoutSkip = FALSE; -+ -+/******************************************************************************* -+* P R I V A T E F U N C T I O N S -+******************************************************************************** -+*/ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to indicate packets to upper layer. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prSkb A pointer to the received packet -+* -+* \retval None -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static VOID TdlsCmdTestRxIndicatePkts(GLUE_INFO_T *prGlueInfo, struct sk_buff *prSkb) -+{ -+ struct net_device *prNetDev; -+ -+ /* init */ -+ prNetDev = prGlueInfo->prDevHandler; -+ prGlueInfo->rNetDevStats.rx_bytes += prSkb->len; -+ prGlueInfo->rNetDevStats.rx_packets++; -+ -+ /* pass to upper layer */ -+ //prNetDev->last_rx = jiffies; -+ prSkb->protocol = eth_type_trans(prSkb, prNetDev); -+ prSkb->dev = prNetDev; -+ -+ if (!in_interrupt()) -+ netif_rx_ni(prSkb); /* only in non-interrupt context */ -+ else -+ netif_rx(prSkb); -+} -+ -+#if TDLS_CFG_CMD_TEST -+ -+#define LR_TDLS_FME_FIELD_FILL(__Len) \ -+do { \ -+ pPkt += __Len; \ -+ u4PktLen += __Len; \ -+} while (0) -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to add a TDLS peer. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prInBuf A pointer to the command string buffer -+* \param[in] u4InBufLen The length of the buffer -+* \param[out] None -+* -+* \retval None -+* -+* EX: iwpriv wlan0 set_str_cmd 0_2_[Responder MAC] -+ -+ iwpriv wlan0 set_str_cmd 0_2_00:11:22:33:44:01 -+*/ -+/*----------------------------------------------------------------------------*/ -+static void TdlsCmdTestAddPeer(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) -+{ -+ PARAM_CUSTOM_TDLS_CMD_STRUCT_T rCmd; -+ struct wireless_dev *prWdev; -+ -+ /* reset */ -+ kalMemZero(&rCmd, sizeof(rCmd)); -+ -+ /* parse arguments */ -+ CmdStringMacParse(prInBuf, &prInBuf, &u4InBufLen, rCmd.arRspAddr); -+ -+ /* init */ -+ rCmd.rPeerInfo.supported_rates = NULL; -+ rCmd.rPeerInfo.ht_capa = &rCmd.rHtCapa; -+ rCmd.rPeerInfo.vht_capa = &rCmd.rVhtCapa; /* LINUX_KERNEL_VERSION >= 3.10.0 */ -+ rCmd.rPeerInfo.sta_flags_set = BIT(NL80211_STA_FLAG_TDLS_PEER); -+ -+ /* send command to wifi task to handle */ -+ prWdev = prGlueInfo->prDevHandler->ieee80211_ptr; -+ mtk_cfg80211_add_station(prWdev->wiphy, (void *)0x1, rCmd.arRspAddr, &rCmd.rPeerInfo); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to simulate to set the TDLS Prohibited bit. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prInBuf A pointer to the command string buffer -+* \param[in] u4InBufLen The length of the buffer -+* \param[out] None -+* -+* \retval None -+* -+* EX: iwpriv wlan0 set_str_cmd 0_16_[Enable/Disable]_[Set/Clear] -+ -+ iwpriv wlan0 set_str_cmd 0_16_1_1 -+*/ -+/*----------------------------------------------------------------------------*/ -+static void TdlsCmdTestChSwProhibitedBitSet(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) -+{ -+ TDLS_CMD_CORE_T rCmd; -+ -+ /* parse arguments */ -+ kalMemZero(rCmd.aucPeerMac, sizeof(rCmd.aucPeerMac)); -+ rCmd.Content.rCmdProhibit.fgIsEnable = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ rCmd.Content.rCmdProhibit.fgIsSet = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ -+ DBGLOG(TDLS, INFO, "%s: fgIsEnable = %d\n", __func__, rCmd.Content.rCmdProhibit.fgIsEnable); -+ -+ /* command to do this */ -+ flgTdlsTestExtCapElm = rCmd.Content.rCmdProhibit.fgIsEnable; -+ -+ aucTdlsTestExtCapElm[0] = ELEM_ID_EXTENDED_CAP; -+ aucTdlsTestExtCapElm[1] = 5; -+ aucTdlsTestExtCapElm[2] = 0; -+ aucTdlsTestExtCapElm[3] = 0; -+ aucTdlsTestExtCapElm[4] = 0; -+ aucTdlsTestExtCapElm[5] = 0; -+ aucTdlsTestExtCapElm[6] = (rCmd.Content.rCmdProhibit.fgIsSet << 7); /* bit39 */ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to receive a channel switch request from the peer. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prInBuf A pointer to the command string buffer -+* \param[in] u4InBufLen The length of the buffer -+* \param[out] None -+* -+* \retval None -+* -+* EX: iwpriv wlan0 set_str_cmd 0_1_5_[TDLS Peer MAC]_[Chan]_[RegulatoryClass]_ -+ [SecondaryChannelOffset]_[SwitchTime]_[SwitchTimeout] -+ -+ iwpriv wlan0 set_str_cmd 0_1_5_00:11:22:33:44:01_1_255_0_15000_30000 -+ -+ RegulatoryClass: TODO (reference to Annex I of 802.11n spec.) -+ Secondary Channel Offset: 0 (SCN - no secondary channel) -+ 1 (SCA - secondary channel above) -+ 2 (SCB - secondary channel below) -+ SwitchTime: units of microseconds -+ -+*/ -+/*----------------------------------------------------------------------------*/ -+static void TdlsCmdTestChSwReqRecv(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) -+{ -+ WLAN_STATUS rStatus; -+ TDLS_CMD_CORE_T rCmd; -+ UINT_32 u4BufLen; -+ -+ /* parse arguments */ -+ CmdStringMacParse(prInBuf, &prInBuf, &u4InBufLen, rCmd.aucPeerMac); -+ -+ rCmd.Content.rCmdChStReqRcv.u4Chan = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ rCmd.Content.rCmdChStReqRcv.u4RegClass = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ rCmd.Content.rCmdChStReqRcv.u4SecChanOff = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ rCmd.Content.rCmdChStReqRcv.u4SwitchTime = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ rCmd.Content.rCmdChStReqRcv.u4SwitchTimeout = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ -+ DBGLOG(TDLS, INFO, "%s:[%pM]u4Chan=%u u4RegClass=%u u4SecChanOff=%u u4SwitchTime=%u u4SwitchTimeout=%u\n", -+ __func__, rCmd.aucPeerMac, -+ (UINT32) rCmd.Content.rCmdChStReqRcv.u4Chan, -+ (UINT32) rCmd.Content.rCmdChStReqRcv.u4RegClass, -+ (UINT32) rCmd.Content.rCmdChStReqRcv.u4SecChanOff, -+ (UINT32) rCmd.Content.rCmdChStReqRcv.u4SwitchTime, -+ (UINT32) rCmd.Content.rCmdChStReqRcv.u4SwitchTimeout); -+ -+ /* command to do this */ -+ rStatus = kalIoctl(prGlueInfo, TdlsTestChStReqRecv, &rCmd, sizeof(rCmd), FALSE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ DBGLOG(TDLS, ERROR, "%s kalIoctl fail:%x\n", __func__, rStatus); -+ return; -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to receive a channel switch response from the peer. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prInBuf A pointer to the command string buffer -+* \param[in] u4InBufLen The length of the buffer -+* \param[out] None -+* -+* \retval None -+* -+* EX: iwpriv wlan0 set_str_cmd 0_1_6_[TDLS Peer MAC]_[Chan]_ -+ [SwitchTime]_[SwitchTimeout]_[StatusCode] -+ -+ iwpriv wlan0 set_str_cmd 0_1_6_00:11:22:33:44:01_11_15000_30000_0 -+ -+ RegulatoryClass: TODO (reference to Annex I of 802.11n spec.) -+ Secondary Channel Offset: 0 (SCN - no secondary channel) -+ 1 (SCA - secondary channel above) -+ 2 (SCB - secondary channel below) -+ SwitchTime: units of microseconds -+ -+*/ -+/*----------------------------------------------------------------------------*/ -+static void TdlsCmdTestChSwRspRecv(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) -+{ -+ WLAN_STATUS rStatus; -+ TDLS_CMD_CORE_T rCmd; -+ UINT_32 u4BufLen; -+ -+ /* parse arguments */ -+ CmdStringMacParse(prInBuf, &prInBuf, &u4InBufLen, rCmd.aucPeerMac); -+ -+ rCmd.Content.rCmdChStRspRcv.u4Chan = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ rCmd.Content.rCmdChStRspRcv.u4SwitchTime = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ rCmd.Content.rCmdChStRspRcv.u4SwitchTimeout = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ rCmd.Content.rCmdChStRspRcv.u4StatusCode = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ -+ DBGLOG(TDLS, INFO, "%s: [ %pM ] u4Chan=%u u4SwitchTime=%u u4SwitchTimeout=%u u4StatusCode=%u\n", -+ __func__, rCmd.aucPeerMac, -+ (UINT32) rCmd.Content.rCmdChStRspRcv.u4Chan, -+ (UINT32) rCmd.Content.rCmdChStRspRcv.u4SwitchTime, -+ (UINT32) rCmd.Content.rCmdChStRspRcv.u4SwitchTimeout, -+ (UINT32) rCmd.Content.rCmdChStRspRcv.u4StatusCode); -+ -+ /* command to do this */ -+ rStatus = kalIoctl(prGlueInfo, TdlsTestChStRspRecv, &rCmd, sizeof(rCmd), FALSE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ DBGLOG(TDLS, ERROR, "%s kalIoctl fail:%x\n", __func__, rStatus); -+ return; -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to inform firmware to skip channel switch timeout function. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prInBuf A pointer to the command string buffer -+* \param[in] u4InBufLen The length of the buffer -+* \param[out] None -+* -+* \retval None -+* -+* EX: iwpriv wlan0 set_str_cmd 0_11_[Enable/Disable] -+ -+ iwpriv wlan0 set_str_cmd 0_11_1 -+*/ -+/*----------------------------------------------------------------------------*/ -+static void TdlsCmdTestChSwTimeoutSkip(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) -+{ -+ WLAN_STATUS rStatus; -+ TDLS_CMD_CORE_T rCmd; -+ UINT_32 u4BufLen; -+ -+ /* parse arguments */ -+ kalMemZero(rCmd.aucPeerMac, sizeof(rCmd.aucPeerMac)); -+ rCmd.Content.rCmdKeepAliveSkip.fgIsEnable = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ -+ DBGLOG(TDLS, INFO, "%s: fgIsEnable = %d\n", __func__, rCmd.Content.rCmdKeepAliveSkip.fgIsEnable); -+ -+ /* command to do this */ -+ rStatus = kalIoctl(prGlueInfo, -+ TdlsTestChSwTimeoutSkip, &rCmd, sizeof(rCmd), FALSE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ DBGLOG(TDLS, ERROR, "%s kalIoctl fail:%x\n", __func__, rStatus); -+ return; -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to send a data frame to the peer periodically. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prInBuf A pointer to the command string buffer -+* \param[in] u4InBufLen The length of the buffer -+* \param[out] None -+* -+* \retval None -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static TIMER_T rTdlsTimerTestDataSend; -+static UINT_8 aucTdlsTestDataSPeerMac[6]; -+static UINT_16 u2TdlsTestDataSInterval; -+ -+static void TdlsCmdTestDataContSend(GLUE_INFO_T *prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) -+{ -+ ADAPTER_T *prAdapter; -+ BOOLEAN fgIsEnabled; -+ -+ /* init */ -+ prAdapter = prGlueInfo->prAdapter; -+ -+ /* parse arguments */ -+ CmdStringMacParse(prInBuf, &prInBuf, &u4InBufLen, aucTdlsTestDataSPeerMac); -+ u2TdlsTestDataSInterval = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ fgIsEnabled = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ -+ cnmTimerStopTimer(prAdapter, &rTdlsTimerTestDataSend); -+ -+ if (fgIsEnabled == FALSE) { -+ /* stop test timer */ -+ return; -+ } -+ -+ /* re-init test timer */ -+ cnmTimerInitTimer(prAdapter, -+ &rTdlsTimerTestDataSend, (PFN_MGMT_TIMEOUT_FUNC) TdlsTimerTestDataContSend, (ULONG) NULL); -+ -+ cnmTimerStartTimer(prAdapter, &rTdlsTimerTestDataSend, u2TdlsTestDataSInterval); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to receive a data frame from the peer. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prInBuf A pointer to the command string buffer -+* \param[in] u4InBufLen The length of the buffer -+* \param[out] None -+* -+* \retval None -+* -+* EX: iwpriv wlan0 set_str_cmd 0_0_x80_[TDLS Peer MAC]_[PM]_[UP]_[EOSP]_[IsNull] -+ -+ iwpriv wlan0 set_str_cmd 0_1_x80_00:11:22:33:44:01_0_0_0_0 -+*/ -+/*----------------------------------------------------------------------------*/ -+static void TdlsCmdTestDataRecv(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) -+{ -+ WLAN_STATUS rStatus; -+ TDLS_CMD_CORE_T rCmd; -+ UINT_32 u4BufLen; -+ -+ /* parse arguments */ -+ CmdStringMacParse(prInBuf, &prInBuf, &u4InBufLen, rCmd.aucPeerMac); -+ rCmd.Content.rCmdDatRcv.u4PM = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ rCmd.Content.rCmdDatRcv.u4UP = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ rCmd.Content.rCmdDatRcv.u4EOSP = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ rCmd.Content.rCmdDatRcv.u4IsNull = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ -+ DBGLOG(TDLS, INFO, -+ " %s: [%pM] PM(%u) UP(%u) EOSP(%u) NULL(%u)\n", -+ __func__, rCmd.aucPeerMac, -+ (UINT32) rCmd.Content.rCmdDatRcv.u4PM, -+ (UINT32) rCmd.Content.rCmdDatRcv.u4UP, -+ (UINT32) rCmd.Content.rCmdDatRcv.u4EOSP, (UINT32) rCmd.Content.rCmdDatRcv.u4IsNull); -+ -+ /* command to do this */ -+ rStatus = kalIoctl(prGlueInfo, TdlsTestDataRecv, &rCmd, sizeof(rCmd), FALSE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ DBGLOG(TDLS, ERROR, "%s kalIoctl fail:%x\n", __func__, rStatus); -+ return; -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to send a data frame to the peer. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prInBuf A pointer to the command string buffer -+* \param[in] u4InBufLen The length of the buffer -+* \param[out] None -+* -+* \retval None -+* -+* EX: iwpriv wlan0 set_str_cmd 0_4_[Responder MAC]_[tx status] -+ -+ iwpriv wlan0 set_str_cmd 0_4_00:11:22:33:44:01_0 -+*/ -+/*----------------------------------------------------------------------------*/ -+static void TdlsCmdTestDataSend(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) -+{ -+ P_ADAPTER_T prAdapter; -+ struct sk_buff *prMsduInfo; -+ UINT_8 *prPkt; -+ UINT_8 MAC[6]; -+ UINT_8 ucTxStatus; -+ -+ /* init */ -+ prAdapter = prGlueInfo->prAdapter; -+ -+ /* parse arguments */ -+ CmdStringMacParse(prInBuf, &prInBuf, &u4InBufLen, MAC); -+ ucTxStatus = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ -+ /* allocate a data frame */ -+ prMsduInfo = kalPacketAlloc(prGlueInfo, 1000, &prPkt); -+ if (prMsduInfo == NULL) { -+ DBGLOG(TDLS, ERROR, " %s allocate pkt fail!\n", __func__); -+ return; -+ } -+ -+ /* init dev */ -+ prMsduInfo->dev = prGlueInfo->prDevHandler; -+ if (prMsduInfo->dev == NULL) { -+ DBGLOG(TDLS, ERROR, " %s prMsduInfo->dev == NULL!\n", __func__); -+ kalPacketFree(prGlueInfo, prMsduInfo); -+ return; -+ } -+ -+ /* init packet */ -+ prMsduInfo->len = 1000; -+ kalMemZero(prMsduInfo->data, 100); /* for QoS field */ -+ kalMemCopy(prMsduInfo->data, MAC, 6); -+ kalMemCopy(prMsduInfo->data + 6, prAdapter->rMyMacAddr, 6); -+ *(UINT_16 *) (prMsduInfo->data + 12) = 0x0800; -+ -+ /* simulate OS to send the packet */ -+ wlanHardStartXmit(prMsduInfo, prMsduInfo->dev); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to simulate to set the TDLS Prohibited bit. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prInBuf A pointer to the command string buffer -+* \param[in] u4InBufLen The length of the buffer -+* \param[out] None -+* -+* \retval None -+* -+* EX: iwpriv wlan0 set_str_cmd 0_16_[mili seconds] -+ -+ iwpriv wlan0 set_str_cmd 0_19_1000 -+*/ -+/*----------------------------------------------------------------------------*/ -+static void TdlsCmdTestDelay(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) -+{ -+ UINT32 u4Delay; -+ -+ u4Delay = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ DBGLOG(TDLS, INFO, "%s: Delay = %d\n", __func__, u4Delay); -+ -+ kalMdelay(u4Delay); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to receive a test discovery request frame command. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prInBuf A pointer to the command string buffer -+* \param[in] u4InBufLen The length of the buffer -+* \param[out] None -+* -+* \retval None -+* -+* EX: iwpriv wlan0 set_str_cmd 0_1_10_[DialogToken]_[Peer MAC]_[BSSID] -+ -+ iwpriv wlan0 set_str_cmd 0_1_10_1_00:11:22:33:44:01 -+ iwpriv wlan0 set_str_cmd 0_1_10_1_00:11:22:33:44:01_00:22:33:44:11:22 -+*/ -+/*----------------------------------------------------------------------------*/ -+static void TdlsCmdTestDiscoveryReqRecv(GLUE_INFO_T *prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) -+{ -+ ADAPTER_T *prAdapter; -+ P_BSS_INFO_T prBssInfo; -+ struct sk_buff *prMsduInfo; -+ UINT_8 *pPkt; -+ UINT_32 u4PktLen, u4IeLen; -+ UINT_8 ucDialogToken, aucPeerMac[6], aucBSSID[6], aucZeroMac[6]; -+ -+ /* parse arguments */ -+ ucDialogToken = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ CmdStringMacParse(prInBuf, &prInBuf, &u4InBufLen, aucPeerMac); -+ -+ kalMemZero(aucZeroMac, sizeof(aucZeroMac)); -+ kalMemZero(aucBSSID, sizeof(aucBSSID)); -+ CmdStringMacParse(prInBuf, &prInBuf, &u4InBufLen, aucBSSID); -+ -+ DBGLOG(TDLS, INFO, -+ " %s: DialogToken=%d from %pM\n", __func__, ucDialogToken, aucPeerMac); -+ -+ /* allocate/init packet */ -+ prAdapter = prGlueInfo->prAdapter; -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ u4PktLen = 0; -+ -+ prMsduInfo = kalPacketAlloc(prGlueInfo, 1600, &pPkt); -+ if (prMsduInfo == NULL) { -+ DBGLOG(TDLS, ERROR, " %s: allocate pkt fail\n", __func__); -+ return; -+ } -+ -+ prMsduInfo->dev = prGlueInfo->prDevHandler; -+ if (prMsduInfo->dev == NULL) { -+ DBGLOG(TDLS, ERROR, " %s: MsduInfo->dev == NULL\n", __func__); -+ kalPacketFree(prGlueInfo, prMsduInfo); -+ return; -+ } -+ -+ /* make up frame content */ -+ /* 1. 802.3 header */ -+ kalMemCopy(pPkt, prAdapter->rMyMacAddr, TDLS_FME_MAC_ADDR_LEN); -+ LR_TDLS_FME_FIELD_FILL(TDLS_FME_MAC_ADDR_LEN); -+ kalMemCopy(pPkt, aucPeerMac, TDLS_FME_MAC_ADDR_LEN); -+ LR_TDLS_FME_FIELD_FILL(TDLS_FME_MAC_ADDR_LEN); -+ *(UINT_16 *) pPkt = htons(TDLS_FRM_PROT_TYPE); -+ LR_TDLS_FME_FIELD_FILL(2); -+ -+ /* 2. payload type */ -+ *pPkt = TDLS_FRM_PAYLOAD_TYPE; -+ LR_TDLS_FME_FIELD_FILL(1); -+ -+ /* 3. Frame Formation - (1) Category */ -+ *pPkt = TDLS_FRM_CATEGORY; -+ LR_TDLS_FME_FIELD_FILL(1); -+ -+ /* 3. Frame Formation - (2) Action */ -+ *pPkt = TDLS_FRM_ACTION_DISCOVERY_REQ; -+ LR_TDLS_FME_FIELD_FILL(1); -+ -+ /* 3. Frame Formation - (3) Dialog token */ -+ *pPkt = ucDialogToken; -+ LR_TDLS_FME_FIELD_FILL(1); -+ -+ /* 3. Frame Formation - (16) Link identifier element */ -+ TDLS_LINK_IDENTIFIER_IE(pPkt)->ucId = ELEM_ID_LINK_IDENTIFIER; -+ TDLS_LINK_IDENTIFIER_IE(pPkt)->ucLength = 18; -+ -+ if (kalMemCmp(aucBSSID, aucZeroMac, 6) == 0) -+ kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aBSSID, prBssInfo->aucBSSID, 6); -+ else -+ kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aBSSID, aucBSSID, 6); -+ -+ kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aInitiator, aucPeerMac, 6); -+ kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aResponder, prAdapter->rMyMacAddr, 6); -+ -+ u4IeLen = IE_SIZE(pPkt); -+ LR_TDLS_FME_FIELD_FILL(u4IeLen); -+ -+ /* 4. Update packet length */ -+ prMsduInfo->len = u4PktLen; -+ dumpMemory8(prMsduInfo->data, u4PktLen); -+ -+ /* pass to OS */ -+ TdlsCmdTestRxIndicatePkts(prGlueInfo, prMsduInfo); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to inform firmware to skip keep alive function. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prInBuf A pointer to the command string buffer -+* \param[in] u4InBufLen The length of the buffer -+* \param[out] None -+* -+* \retval None -+* -+* EX: iwpriv wlan0 set_str_cmd 0_10_[Enable/Disable] -+ -+ iwpriv wlan0 set_str_cmd 0_10_1 -+*/ -+/*----------------------------------------------------------------------------*/ -+static void TdlsCmdTestKeepAliveSkip(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) -+{ -+ WLAN_STATUS rStatus; -+ TDLS_CMD_CORE_T rCmd; -+ UINT_32 u4BufLen; -+ -+ /* parse arguments */ -+ kalMemZero(rCmd.aucPeerMac, sizeof(rCmd.aucPeerMac)); -+ rCmd.Content.rCmdKeepAliveSkip.fgIsEnable = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ -+ DBGLOG(TDLS, INFO, "%s: fgIsEnable = %d\n", __func__, rCmd.Content.rCmdKeepAliveSkip.fgIsEnable); -+ -+ /* command to do this */ -+ rStatus = kalIoctl(prGlueInfo, -+ TdlsTestKeepAliveSkip, &rCmd, sizeof(rCmd), FALSE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ DBGLOG(TDLS, ERROR, "%s kalIoctl fail:%x\n", __func__, rStatus); -+ return; -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to simulate to set the TDLS Prohibited bit. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prInBuf A pointer to the command string buffer -+* \param[in] u4InBufLen The length of the buffer -+* \param[out] None -+* -+* \retval None -+* -+* EX: iwpriv wlan0 set_str_cmd 0_11_[Enable/Disable]_[Set/Clear] -+ -+ iwpriv wlan0 set_str_cmd 0_13_1_1 -+*/ -+/*----------------------------------------------------------------------------*/ -+static void TdlsCmdTestProhibitedBitSet(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) -+{ -+ TDLS_CMD_CORE_T rCmd; -+ -+ /* parse arguments */ -+ kalMemZero(rCmd.aucPeerMac, sizeof(rCmd.aucPeerMac)); -+ rCmd.Content.rCmdProhibit.fgIsEnable = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ rCmd.Content.rCmdProhibit.fgIsSet = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ -+ DBGLOG(TDLS, INFO, "%s: fgIsEnable = %d\n", __func__, rCmd.Content.rCmdProhibit.fgIsEnable); -+ -+ /* command to do this */ -+ flgTdlsTestExtCapElm = rCmd.Content.rCmdProhibit.fgIsEnable; -+ -+ aucTdlsTestExtCapElm[0] = ELEM_ID_EXTENDED_CAP; -+ aucTdlsTestExtCapElm[1] = 5; -+ aucTdlsTestExtCapElm[2] = 0; -+ aucTdlsTestExtCapElm[3] = 0; -+ aucTdlsTestExtCapElm[4] = 0; -+ aucTdlsTestExtCapElm[5] = 0; -+ aucTdlsTestExtCapElm[6] = (rCmd.Content.rCmdProhibit.fgIsSet << 6); /* bit38 */ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to receive a PTI request from the AP. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prInBuf A pointer to the command string buffer -+* \param[in] u4InBufLen The length of the buffer -+* \param[out] None -+* -+* \retval None -+* -+* EX: iwpriv wlan0 set_str_cmd 0_1_4_[TDLS Peer MAC]_[Dialog Token] -+ -+ iwpriv wlan0 set_str_cmd 0_1_4_00:11:22:33:44:01_0 -+*/ -+/*----------------------------------------------------------------------------*/ -+static void TdlsCmdTestPtiReqRecv(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) -+{ -+ WLAN_STATUS rStatus; -+ TDLS_CMD_CORE_T rCmd; -+ UINT_32 u4BufLen; -+ -+ /* parse arguments */ -+ CmdStringMacParse(prInBuf, &prInBuf, &u4InBufLen, rCmd.aucPeerMac); -+ -+ rCmd.Content.rCmdPtiRspRcv.u4DialogToken = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ -+ DBGLOG(TDLS, INFO, "%s: [ %pM ] u4DialogToken = %u\n", -+ __func__, rCmd.aucPeerMac, (UINT32) rCmd.Content.rCmdPtiRspRcv.u4DialogToken); -+ -+ /* command to do this */ -+ rStatus = kalIoctl(prGlueInfo, TdlsTestPtiReqRecv, &rCmd, sizeof(rCmd), FALSE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ DBGLOG(TDLS, ERROR, "%s kalIoctl fail:%x\n", __func__, rStatus); -+ return; -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to receive a PTI response from the peer. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prInBuf A pointer to the command string buffer -+* \param[in] u4InBufLen The length of the buffer -+* \param[out] None -+* -+* \retval None -+* -+* EX: iwpriv wlan0 set_str_cmd 0_1_9_[TDLS Peer MAC]_[Dialog Token]_[PM] -+ -+ iwpriv wlan0 set_str_cmd 0_1_9_00:11:22:33:44:01_0_1 -+*/ -+/*----------------------------------------------------------------------------*/ -+static void TdlsCmdTestPtiRspRecv(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) -+{ -+ WLAN_STATUS rStatus; -+ TDLS_CMD_CORE_T rCmd; -+ UINT_32 u4BufLen; -+ -+ /* parse arguments */ -+ CmdStringMacParse(prInBuf, &prInBuf, &u4InBufLen, rCmd.aucPeerMac); -+ -+ rCmd.Content.rCmdPtiRspRcv.u4DialogToken = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ rCmd.Content.rCmdPtiRspRcv.u4PM = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ -+ DBGLOG(TDLS, INFO, "%s: [%pM] u4DialogToken = %u %u\n", -+ __func__, rCmd.aucPeerMac, -+ (UINT32) rCmd.Content.rCmdPtiRspRcv.u4DialogToken, -+ (UINT32) rCmd.Content.rCmdPtiRspRcv.u4PM); -+ -+ /* command to do this */ -+ rStatus = kalIoctl(prGlueInfo, TdlsTestPtiRspRecv, &rCmd, sizeof(rCmd), FALSE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ DBGLOG(TDLS, ERROR, "%s kalIoctl fail:%x\n", __func__, rStatus); -+ return; -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to inform firmware to simulate PTI tx done fail case. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prInBuf A pointer to the command string buffer -+* \param[in] u4InBufLen The length of the buffer -+* \param[out] None -+* -+* \retval None -+* -+* EX: iwpriv wlan0 set_str_cmd 0_21_[Enable/Disable] -+ -+ iwpriv wlan0 set_str_cmd 0_21_1 -+*/ -+/*----------------------------------------------------------------------------*/ -+static void TdlsCmdTestPtiTxDoneFail(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) -+{ -+ WLAN_STATUS rStatus; -+ TDLS_CMD_CORE_T rCmd; -+ UINT_32 u4BufLen; -+ -+ /* parse arguments */ -+ kalMemZero(rCmd.aucPeerMac, sizeof(rCmd.aucPeerMac)); -+ rCmd.Content.rCmdPtiTxFail.fgIsEnable = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ -+ DBGLOG(TDLS, INFO, "%s: fgIsEnable = %d\n", __func__, rCmd.Content.rCmdPtiTxFail.fgIsEnable); -+ -+ /* command to do this */ -+ rStatus = kalIoctl(prGlueInfo, TdlsTestPtiTxFail, &rCmd, sizeof(rCmd), FALSE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ DBGLOG(TDLS, ERROR, "%s kalIoctl fail:%x\n", __func__, rStatus); -+ return; -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to receive a test frame. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prInBuf A pointer to the command string buffer -+* \param[in] u4InBufLen The length of the buffer -+* \param[out] None -+* -+* \retval None -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static void TdlsCmdTestRvFrame(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) -+{ -+/* PARAM_CUSTOM_TDLS_CMD_STRUCT_T rCmd; */ -+/* TDLS_STATUS u4Status; */ -+ UINT_32 u4Subcmd; -+/* UINT_32 u4BufLen; */ -+ -+ /* parse sub-command */ -+ u4Subcmd = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ DBGLOG(TDLS, INFO, " test rv frame sub command = %u\n", (UINT32) u4Subcmd); -+ -+ /* parse command arguments */ -+ switch (u4Subcmd) { -+ case TDLS_FRM_ACTION_SETUP_REQ: -+ /* simulate to receive a setup request frame */ -+ TdlsCmdTestSetupReqRecv(prGlueInfo, prInBuf, u4InBufLen); -+ break; -+ -+ case TDLS_FRM_ACTION_SETUP_RSP: -+ /* simulate to receive a setup response frame */ -+ TdlsCmdTestSetupRspRecv(prGlueInfo, prInBuf, u4InBufLen); -+ break; -+ -+ case TDLS_FRM_ACTION_CONFIRM: -+ /* simulate to receive a setup confirm frame */ -+ TdlsCmdTestSetupConfirmRecv(prGlueInfo, prInBuf, u4InBufLen); -+ break; -+ -+ case TDLS_FRM_ACTION_TEARDOWN: -+ /* simulate to receive a tear down frame */ -+ TdlsCmdTestTearDownRecv(prGlueInfo, prInBuf, u4InBufLen); -+ break; -+ -+ case TDLS_FRM_ACTION_PTI: -+ /* simulate to receive a PTI request frame */ -+ TdlsCmdTestPtiReqRecv(prGlueInfo, prInBuf, u4InBufLen); -+ break; -+ -+ case TDLS_FRM_ACTION_PTI_RSP: -+ /* simulate to receive a PTI response frame */ -+ TdlsCmdTestPtiRspRecv(prGlueInfo, prInBuf, u4InBufLen); -+ break; -+ -+ case TDLS_FRM_DATA_TEST_DATA: -+ /* simulate to receive a DATA frame */ -+ TdlsCmdTestDataRecv(prGlueInfo, prInBuf, u4InBufLen); -+ break; -+ -+ case TDLS_FRM_ACTION_CHAN_SWITCH_REQ: -+ /* simulate to receive a channel switch request frame */ -+ TdlsCmdTestChSwReqRecv(prGlueInfo, prInBuf, u4InBufLen); -+ break; -+ -+ case TDLS_FRM_ACTION_CHAN_SWITCH_RSP: -+ /* simulate to receive a channel switch response frame */ -+ TdlsCmdTestChSwRspRecv(prGlueInfo, prInBuf, u4InBufLen); -+ break; -+ -+ case TDLS_FRM_ACTION_DISCOVERY_REQ: -+ /* simulate to receive a discovery request frame */ -+ TdlsCmdTestDiscoveryReqRecv(prGlueInfo, prInBuf, u4InBufLen); -+ break; -+ -+ default: -+ DBGLOG(TDLS, ERROR, " wrong test rv frame sub command\n"); -+ return; -+ } -+ -+/* if (u4Status != TDLS_STATUS_SUCCESS) */ -+ { -+/* DBGLOG(TDLS, ERROR, (" command parse fail\n")); */ -+/* return; */ -+ } -+ -+ /* send command to wifi task to handle */ -+#if 0 -+ kalIoctl(prGlueInfo, -+ TdlsTestFrameSend, -+ (PVOID)&rCmd, sizeof(PARAM_CUSTOM_TDLS_CMD_STRUCT_T), FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+#endif -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to receive a test setup confirm frame command. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prInBuf A pointer to the command string buffer -+* \param[in] u4InBufLen The length of the buffer -+* \param[out] None -+* -+* \retval None -+* -+* EX: iwpriv wlan0 set_str_cmd 0_1_2_[DialogToken]_[StatusCode]_[Peer MAC] -+ -+ iwpriv wlan0 set_str_cmd 0_1_2_1_0_00:11:22:33:44:01 -+*/ -+/*----------------------------------------------------------------------------*/ -+static void TdlsCmdTestSetupConfirmRecv(GLUE_INFO_T *prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) -+{ -+ ADAPTER_T *prAdapter; -+ P_BSS_INFO_T prBssInfo; -+ PM_PROFILE_SETUP_INFO_T *prPmProfSetupInfo; -+ struct sk_buff *prMsduInfo; -+ UINT_8 *pPkt; -+ UINT_32 u4PktLen, u4IeLen; -+ UINT_8 ucDialogToken, ucStatusCode, aucPeerMac[6]; -+ -+ /* parse arguments */ -+ ucDialogToken = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ ucStatusCode = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ CmdStringMacParse(prInBuf, &prInBuf, &u4InBufLen, aucPeerMac); -+ -+ DBGLOG(TDLS, INFO, -+ " %s: DialogToken=%d StatusCode=%d from %pM\n", -+ __func__, ucDialogToken, ucStatusCode, aucPeerMac); -+ -+ /* allocate/init packet */ -+ prAdapter = prGlueInfo->prAdapter; -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ prPmProfSetupInfo = &prBssInfo->rPmProfSetupInfo; -+ u4PktLen = 0; -+ -+ prMsduInfo = kalPacketAlloc(prGlueInfo, 1600, &pPkt); -+ if (prMsduInfo == NULL) { -+ DBGLOG(TDLS, ERROR, " %s: allocate pkt fail\n", __func__); -+ return; -+ } -+ -+ prMsduInfo->dev = prGlueInfo->prDevHandler; -+ if (prMsduInfo->dev == NULL) { -+ DBGLOG(TDLS, ERROR, " %s: MsduInfo->dev == NULL\n", __func__); -+ kalPacketFree(prGlueInfo, prMsduInfo); -+ return; -+ } -+ -+ /* make up frame content */ -+ /* 1. 802.3 header */ -+ kalMemCopy(pPkt, prAdapter->rMyMacAddr, TDLS_FME_MAC_ADDR_LEN); -+ LR_TDLS_FME_FIELD_FILL(TDLS_FME_MAC_ADDR_LEN); -+ kalMemCopy(pPkt, aucPeerMac, TDLS_FME_MAC_ADDR_LEN); -+ LR_TDLS_FME_FIELD_FILL(TDLS_FME_MAC_ADDR_LEN); -+ *(UINT_16 *) pPkt = htons(TDLS_FRM_PROT_TYPE); -+ LR_TDLS_FME_FIELD_FILL(2); -+ -+ /* 2. payload type */ -+ *pPkt = TDLS_FRM_PAYLOAD_TYPE; -+ LR_TDLS_FME_FIELD_FILL(1); -+ -+ /* 3. Frame Formation - (1) Category */ -+ *pPkt = TDLS_FRM_CATEGORY; -+ LR_TDLS_FME_FIELD_FILL(1); -+ -+ /* 3. Frame Formation - (2) Action */ -+ *pPkt = TDLS_FRM_ACTION_CONFIRM; -+ LR_TDLS_FME_FIELD_FILL(1); -+ -+ /* 3. Frame Formation - (3) Status Code */ -+ *pPkt = ucStatusCode; -+ *(pPkt + 1) = 0x00; -+ LR_TDLS_FME_FIELD_FILL(2); -+ -+ /* 3. Frame Formation - (4) Dialog token */ -+ *pPkt = ucDialogToken; -+ LR_TDLS_FME_FIELD_FILL(1); -+ -+ /* 3. Frame Formation - (17) WMM Information element */ -+ if (prAdapter->rWifiVar.fgSupportQoS) { -+ u4IeLen = mqmGenerateWmmParamIEByParam(prAdapter, prBssInfo, pPkt, OP_MODE_INFRASTRUCTURE); -+ LR_TDLS_FME_FIELD_FILL(u4IeLen); -+ } -+ -+ /* 3. Frame Formation - (16) Link identifier element */ -+ TDLS_LINK_IDENTIFIER_IE(pPkt)->ucId = ELEM_ID_LINK_IDENTIFIER; -+ TDLS_LINK_IDENTIFIER_IE(pPkt)->ucLength = ELEM_LEN_LINK_IDENTIFIER; -+ -+ kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aBSSID, prBssInfo->aucBSSID, 6); -+ kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aInitiator, aucPeerMac, 6); -+ kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aResponder, prAdapter->rMyMacAddr, 6); -+ -+ u4IeLen = IE_SIZE(pPkt); -+ LR_TDLS_FME_FIELD_FILL(u4IeLen); -+ -+ /* 4. Update packet length */ -+ prMsduInfo->len = u4PktLen; -+ dumpMemory8(prMsduInfo->data, u4PktLen); -+ -+ /* pass to OS */ -+ TdlsCmdTestRxIndicatePkts(prGlueInfo, prMsduInfo); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to receive a test setup request frame command. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prInBuf A pointer to the command string buffer -+* \param[in] u4InBufLen The length of the buffer -+* \param[out] None -+* -+* \retval None -+* -+* EX: iwpriv wlan0 set_str_cmd 0_1_0_[DialogToken]_[Peer MAC]_[BSSID] -+ -+ iwpriv wlan0 set_str_cmd 0_1_0_1_00:11:22:33:44:01 -+ iwpriv wlan0 set_str_cmd 0_1_0_1_00:11:22:33:44:01_00:22:33:44:11:22 -+*/ -+/*----------------------------------------------------------------------------*/ -+static void TdlsCmdTestSetupReqRecv(GLUE_INFO_T *prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) -+{ -+ ADAPTER_T *prAdapter; -+ P_BSS_INFO_T prBssInfo; -+ struct sk_buff *prMsduInfo; -+ UINT_8 *pPkt; -+ UINT_32 u4PktLen, u4IeLen; -+ UINT_8 ucDialogToken, aucPeerMac[6], aucBSSID[6], aucZeroMac[6]; -+ UINT_16 u2CapInfo; -+ -+ /* parse arguments */ -+ ucDialogToken = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ CmdStringMacParse(prInBuf, &prInBuf, &u4InBufLen, aucPeerMac); -+ -+ kalMemZero(aucZeroMac, sizeof(aucZeroMac)); -+ kalMemZero(aucBSSID, sizeof(aucBSSID)); -+ CmdStringMacParse(prInBuf, &prInBuf, &u4InBufLen, aucBSSID); -+ -+ DBGLOG(TDLS, INFO, -+ " %s: DialogToken=%d from %pM\n", __func__, ucDialogToken, aucPeerMac); -+ -+ /* allocate/init packet */ -+ prAdapter = prGlueInfo->prAdapter; -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ u4PktLen = 0; -+ -+ prMsduInfo = kalPacketAlloc(prGlueInfo, 1600, &pPkt); -+ if (prMsduInfo == NULL) { -+ DBGLOG(TDLS, ERROR, " %s: allocate pkt fail\n", __func__); -+ return; -+ } -+ -+ prMsduInfo->dev = prGlueInfo->prDevHandler; -+ if (prMsduInfo->dev == NULL) { -+ DBGLOG(TDLS, ERROR, " %s: MsduInfo->dev == NULL\n", __func__); -+ kalPacketFree(prGlueInfo, prMsduInfo); -+ return; -+ } -+ -+ /* make up frame content */ -+ /* 1. 802.3 header */ -+ kalMemCopy(pPkt, prAdapter->rMyMacAddr, TDLS_FME_MAC_ADDR_LEN); -+ LR_TDLS_FME_FIELD_FILL(TDLS_FME_MAC_ADDR_LEN); -+ kalMemCopy(pPkt, aucPeerMac, TDLS_FME_MAC_ADDR_LEN); -+ LR_TDLS_FME_FIELD_FILL(TDLS_FME_MAC_ADDR_LEN); -+ *(UINT_16 *) pPkt = htons(TDLS_FRM_PROT_TYPE); -+ LR_TDLS_FME_FIELD_FILL(2); -+ -+ /* 2. payload type */ -+ *pPkt = TDLS_FRM_PAYLOAD_TYPE; -+ LR_TDLS_FME_FIELD_FILL(1); -+ -+ /* 3. Frame Formation - (1) Category */ -+ *pPkt = TDLS_FRM_CATEGORY; -+ LR_TDLS_FME_FIELD_FILL(1); -+ -+ /* 3. Frame Formation - (2) Action */ -+ *pPkt = TDLS_FRM_ACTION_SETUP_REQ; -+ LR_TDLS_FME_FIELD_FILL(1); -+ -+ /* 3. Frame Formation - (3) Dialog token */ -+ *pPkt = ucDialogToken; -+ LR_TDLS_FME_FIELD_FILL(1); -+ -+ /* 3. Frame Formation - (4) Capability */ -+ u2CapInfo = assocBuildCapabilityInfo(prAdapter, NULL); -+ WLAN_SET_FIELD_16(pPkt, u2CapInfo); -+ LR_TDLS_FME_FIELD_FILL(2); -+ -+ /* 4. Append general IEs */ -+ u4IeLen = TdlsFrameGeneralIeAppend(prAdapter, NULL, 0, pPkt); -+ LR_TDLS_FME_FIELD_FILL(u4IeLen); -+ -+ /* 3. Frame Formation - (10) Extended capabilities element */ -+ EXT_CAP_IE(pPkt)->ucId = ELEM_ID_EXTENDED_CAP; -+ EXT_CAP_IE(pPkt)->ucLength = 5; -+ -+ EXT_CAP_IE(pPkt)->aucCapabilities[0] = 0x00; /* bit0 ~ bit7 */ -+ EXT_CAP_IE(pPkt)->aucCapabilities[1] = 0x00; /* bit8 ~ bit15 */ -+ EXT_CAP_IE(pPkt)->aucCapabilities[2] = 0x00; /* bit16 ~ bit23 */ -+ EXT_CAP_IE(pPkt)->aucCapabilities[3] = 0x00; /* bit24 ~ bit31 */ -+ EXT_CAP_IE(pPkt)->aucCapabilities[4] = 0x00; /* bit32 ~ bit39 */ -+ -+ /* TDLS_EX_CAP_PEER_UAPSD */ -+ EXT_CAP_IE(pPkt)->aucCapabilities[3] |= BIT((28 - 24)); -+ /* TDLS_EX_CAP_CHAN_SWITCH */ -+ EXT_CAP_IE(pPkt)->aucCapabilities[3] |= BIT((30 - 24)); -+ /* TDLS_EX_CAP_TDLS */ -+ EXT_CAP_IE(pPkt)->aucCapabilities[4] |= BIT((37 - 32)); -+ -+ u4IeLen = IE_SIZE(pPkt); -+ LR_TDLS_FME_FIELD_FILL(u4IeLen); -+ -+ /* 3. Frame Formation - (16) Link identifier element */ -+ TDLS_LINK_IDENTIFIER_IE(pPkt)->ucId = ELEM_ID_LINK_IDENTIFIER; -+ TDLS_LINK_IDENTIFIER_IE(pPkt)->ucLength = 18; -+ -+ if (kalMemCmp(aucBSSID, aucZeroMac, 6) == 0) -+ kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aBSSID, prBssInfo->aucBSSID, 6); -+ else -+ kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aBSSID, aucBSSID, 6); -+ -+ kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aInitiator, aucPeerMac, 6); -+ kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aResponder, prAdapter->rMyMacAddr, 6); -+ -+ u4IeLen = IE_SIZE(pPkt); -+ LR_TDLS_FME_FIELD_FILL(u4IeLen); -+ -+ /* 4. Update packet length */ -+ prMsduInfo->len = u4PktLen; -+ dumpMemory8(prMsduInfo->data, u4PktLen); -+ -+ /* pass to OS */ -+ TdlsCmdTestRxIndicatePkts(prGlueInfo, prMsduInfo); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to receive a test setup response frame command. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prInBuf A pointer to the command string buffer -+* \param[in] u4InBufLen The length of the buffer -+* \param[out] None -+* -+* \retval None -+* -+* EX: iwpriv wlan0 set_str_cmd 0_1_1_[DialogToken]_[StatusCode]_[Peer MAC] -+ -+ iwpriv wlan0 set_str_cmd 0_1_1_1_0_00:11:22:33:44:01 -+*/ -+/*----------------------------------------------------------------------------*/ -+static void TdlsCmdTestSetupRspRecv(GLUE_INFO_T *prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) -+{ -+ ADAPTER_T *prAdapter; -+ P_BSS_INFO_T prBssInfo; -+ struct sk_buff *prMsduInfo; -+ UINT_8 *pPkt; -+ UINT_32 u4PktLen, u4IeLen; -+ UINT_8 ucDialogToken, ucStatusCode, aucPeerMac[6]; -+ UINT_16 u2CapInfo; -+ -+ /* parse arguments */ -+ ucDialogToken = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ ucStatusCode = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ CmdStringMacParse(prInBuf, &prInBuf, &u4InBufLen, aucPeerMac); -+ -+ DBGLOG(TDLS, INFO, -+ " %s: DialogToken=%d StatusCode=%d from %pM\n", -+ __func__, ucDialogToken, ucStatusCode, aucPeerMac); -+ -+ /* allocate/init packet */ -+ prAdapter = prGlueInfo->prAdapter; -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ u4PktLen = 0; -+ -+ prMsduInfo = kalPacketAlloc(prGlueInfo, 1600, &pPkt); -+ if (prMsduInfo == NULL) { -+ DBGLOG(TDLS, ERROR, " %s: allocate pkt fail\n", __func__); -+ return; -+ } -+ -+ prMsduInfo->dev = prGlueInfo->prDevHandler; -+ if (prMsduInfo->dev == NULL) { -+ DBGLOG(TDLS, ERROR, " %s: MsduInfo->dev == NULL\n", __func__); -+ kalPacketFree(prGlueInfo, prMsduInfo); -+ return; -+ } -+ -+ /* make up frame content */ -+ /* 1. 802.3 header */ -+ kalMemCopy(pPkt, prAdapter->rMyMacAddr, TDLS_FME_MAC_ADDR_LEN); -+ LR_TDLS_FME_FIELD_FILL(TDLS_FME_MAC_ADDR_LEN); -+ kalMemCopy(pPkt, aucPeerMac, TDLS_FME_MAC_ADDR_LEN); -+ LR_TDLS_FME_FIELD_FILL(TDLS_FME_MAC_ADDR_LEN); -+ *(UINT_16 *) pPkt = htons(TDLS_FRM_PROT_TYPE); -+ LR_TDLS_FME_FIELD_FILL(2); -+ -+ /* 2. payload type */ -+ *pPkt = TDLS_FRM_PAYLOAD_TYPE; -+ LR_TDLS_FME_FIELD_FILL(1); -+ -+ /* 3. Frame Formation - (1) Category */ -+ *pPkt = TDLS_FRM_CATEGORY; -+ LR_TDLS_FME_FIELD_FILL(1); -+ -+ /* 3. Frame Formation - (2) Action */ -+ *pPkt = TDLS_FRM_ACTION_SETUP_RSP; -+ LR_TDLS_FME_FIELD_FILL(1); -+ -+ /* 3. Frame Formation - (3) Status Code */ -+ *pPkt = ucStatusCode; -+ *(pPkt + 1) = 0x00; -+ LR_TDLS_FME_FIELD_FILL(2); -+ -+ /* 3. Frame Formation - (4) Dialog token */ -+ *pPkt = ucDialogToken; -+ LR_TDLS_FME_FIELD_FILL(1); -+ -+ /* 3. Frame Formation - (5) Capability */ -+ u2CapInfo = assocBuildCapabilityInfo(prAdapter, NULL); -+ WLAN_SET_FIELD_16(pPkt, u2CapInfo); -+ LR_TDLS_FME_FIELD_FILL(2); -+ -+ /* 4. Append general IEs */ -+ u4IeLen = TdlsFrameGeneralIeAppend(prAdapter, NULL, 0, pPkt); -+ LR_TDLS_FME_FIELD_FILL(u4IeLen); -+ -+ /* 3. Frame Formation - (10) Extended capabilities element */ -+ EXT_CAP_IE(pPkt)->ucId = ELEM_ID_EXTENDED_CAP; -+ EXT_CAP_IE(pPkt)->ucLength = 5; -+ -+ EXT_CAP_IE(pPkt)->aucCapabilities[0] = 0x00; /* bit0 ~ bit7 */ -+ EXT_CAP_IE(pPkt)->aucCapabilities[1] = 0x00; /* bit8 ~ bit15 */ -+ EXT_CAP_IE(pPkt)->aucCapabilities[2] = 0x00; /* bit16 ~ bit23 */ -+ EXT_CAP_IE(pPkt)->aucCapabilities[3] = 0x00; /* bit24 ~ bit31 */ -+ EXT_CAP_IE(pPkt)->aucCapabilities[4] = 0x00; /* bit32 ~ bit39 */ -+ -+ /* TDLS_EX_CAP_PEER_UAPSD */ -+ EXT_CAP_IE(pPkt)->aucCapabilities[3] |= BIT((28 - 24)); -+ /* TDLS_EX_CAP_CHAN_SWITCH */ -+ EXT_CAP_IE(pPkt)->aucCapabilities[3] |= BIT((30 - 24)); -+ /* TDLS_EX_CAP_TDLS */ -+ EXT_CAP_IE(pPkt)->aucCapabilities[4] |= BIT((37 - 32)); -+ -+ u4IeLen = IE_SIZE(pPkt); -+ LR_TDLS_FME_FIELD_FILL(u4IeLen); -+ -+ /* 3. Frame Formation - (16) Link identifier element */ -+ TDLS_LINK_IDENTIFIER_IE(pPkt)->ucId = ELEM_ID_LINK_IDENTIFIER; -+ TDLS_LINK_IDENTIFIER_IE(pPkt)->ucLength = ELEM_LEN_LINK_IDENTIFIER; -+ -+ kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aBSSID, prBssInfo->aucBSSID, 6); -+ kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aInitiator, prAdapter->rMyMacAddr, 6); -+ kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aResponder, aucPeerMac, 6); -+ -+ u4IeLen = IE_SIZE(pPkt); -+ LR_TDLS_FME_FIELD_FILL(u4IeLen); -+ -+ /* 4. Update packet length */ -+ prMsduInfo->len = u4PktLen; -+ dumpMemory8(prMsduInfo->data, u4PktLen); -+ -+ /* pass to OS */ -+ TdlsCmdTestRxIndicatePkts(prGlueInfo, prMsduInfo); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to inform firmware to skip channel switch timeout function. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prInBuf A pointer to the command string buffer -+* \param[in] u4InBufLen The length of the buffer -+* \param[out] None -+* -+* \retval None -+* -+* EX: iwpriv wlan0 set_str_cmd 0_14_[Enable/Disable] -+ -+ iwpriv wlan0 set_str_cmd 0_14_0 -+*/ -+/*----------------------------------------------------------------------------*/ -+static void TdlsCmdTestScanCtrl(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) -+{ -+ WLAN_STATUS rStatus; -+ TDLS_CMD_CORE_T rCmd; -+ UINT_32 u4BufLen; -+ -+ /* parse arguments */ -+ kalMemZero(rCmd.aucPeerMac, sizeof(rCmd.aucPeerMac)); -+ rCmd.Content.rCmdScanSkip.fgIsEnable = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ -+ DBGLOG(TDLS, INFO, "%s: fgIsEnable = %d\n", __func__, rCmd.Content.rCmdScanSkip.fgIsEnable); -+ -+ /* command to do this */ -+ rStatus = kalIoctl(prGlueInfo, TdlsTestScanSkip, &rCmd, sizeof(rCmd), FALSE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ DBGLOG(TDLS, ERROR, "%s kalIoctl fail:%x\n", __func__, rStatus); -+ return; -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to receive a test tear down frame command. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prInBuf A pointer to the command string buffer -+* \param[in] u4InBufLen The length of the buffer -+* \param[out] None -+* -+* \retval None -+* -+* EX: iwpriv wlan0 set_str_cmd 0_1_3_[IsInitiator]_[ReasonCode]_[Peer MAC]_[Where] -+ -+ Where 0 (From driver) or 1 (From FW) -+ -+ iwpriv wlan0 set_str_cmd 0_1_3_1_26_00:11:22:33:44:01_0 -+*/ -+/*----------------------------------------------------------------------------*/ -+static void TdlsCmdTestTearDownRecv(GLUE_INFO_T *prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) -+{ -+ ADAPTER_T *prAdapter; -+ P_BSS_INFO_T prBssInfo; -+ struct sk_buff *prMsduInfo; -+ UINT_8 *pPkt; -+ UINT_32 u4PktLen, u4IeLen; -+ BOOLEAN fgIsInitiator; -+ UINT_8 ucReasonCode, aucPeerMac[6]; -+ BOOLEAN fgIsFromWhich; -+ WLAN_STATUS rStatus; -+ TDLS_CMD_CORE_T rCmd; -+ UINT_32 u4BufLen; -+ -+ /* parse arguments */ -+ fgIsInitiator = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ ucReasonCode = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ CmdStringMacParse(prInBuf, &prInBuf, &u4InBufLen, aucPeerMac); -+ fgIsFromWhich = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ -+ DBGLOG(TDLS, INFO, -+ " %s: ReasonCode=%d from %pM %d\n", -+ __func__, ucReasonCode, aucPeerMac, fgIsFromWhich); -+ -+ if (fgIsFromWhich == 0) { -+ /* allocate/init packet */ -+ prAdapter = prGlueInfo->prAdapter; -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ u4PktLen = 0; -+ -+ prMsduInfo = kalPacketAlloc(prGlueInfo, 1600, &pPkt); -+ if (prMsduInfo == NULL) { -+ DBGLOG(TDLS, ERROR, " %s: allocate pkt fail\n", __func__); -+ return; -+ } -+ -+ prMsduInfo->dev = prGlueInfo->prDevHandler; -+ if (prMsduInfo->dev == NULL) { -+ DBGLOG(TDLS, ERROR, " %s: MsduInfo->dev == NULL\n", __func__); -+ kalPacketFree(prGlueInfo, prMsduInfo); -+ return; -+ } -+ -+ /* make up frame content */ -+ /* 1. 802.3 header */ -+ kalMemCopy(pPkt, prAdapter->rMyMacAddr, TDLS_FME_MAC_ADDR_LEN); -+ LR_TDLS_FME_FIELD_FILL(TDLS_FME_MAC_ADDR_LEN); -+ kalMemCopy(pPkt, aucPeerMac, TDLS_FME_MAC_ADDR_LEN); -+ LR_TDLS_FME_FIELD_FILL(TDLS_FME_MAC_ADDR_LEN); -+ *(UINT_16 *) pPkt = htons(TDLS_FRM_PROT_TYPE); -+ LR_TDLS_FME_FIELD_FILL(2); -+ -+ /* 2. payload type */ -+ *pPkt = TDLS_FRM_PAYLOAD_TYPE; -+ LR_TDLS_FME_FIELD_FILL(1); -+ -+ /* 3. Frame Formation - (1) Category */ -+ *pPkt = TDLS_FRM_CATEGORY; -+ LR_TDLS_FME_FIELD_FILL(1); -+ -+ /* 3. Frame Formation - (2) Action */ -+ *pPkt = TDLS_FRM_ACTION_TEARDOWN; -+ LR_TDLS_FME_FIELD_FILL(1); -+ -+ /* 3. Frame Formation - (3) Reason Code */ -+ *pPkt = ucReasonCode; -+ *(pPkt + 1) = 0x00; -+ LR_TDLS_FME_FIELD_FILL(2); -+ -+ /* 3. Frame Formation - (16) Link identifier element */ -+ TDLS_LINK_IDENTIFIER_IE(pPkt)->ucId = ELEM_ID_LINK_IDENTIFIER; -+ TDLS_LINK_IDENTIFIER_IE(pPkt)->ucLength = ELEM_LEN_LINK_IDENTIFIER; -+ -+ kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aBSSID, prBssInfo->aucBSSID, 6); -+ if (fgIsInitiator == 1) { -+ kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aInitiator, aucPeerMac, 6); -+ kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aResponder, prAdapter->rMyMacAddr, 6); -+ } else { -+ kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aInitiator, prAdapter->rMyMacAddr, 6); -+ kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aResponder, aucPeerMac, 6); -+ } -+ -+ u4IeLen = IE_SIZE(pPkt); -+ LR_TDLS_FME_FIELD_FILL(u4IeLen); -+ -+ /* 4. Update packet length */ -+ prMsduInfo->len = u4PktLen; -+ dumpMemory8(prMsduInfo->data, u4PktLen); -+ -+ /* pass to OS */ -+ TdlsCmdTestRxIndicatePkts(prGlueInfo, prMsduInfo); -+ } else { -+ kalMemZero(&rCmd, sizeof(rCmd)); -+ kalMemCopy(rCmd.aucPeerMac, aucPeerMac, 6); -+ rCmd.Content.rCmdTearDownRcv.u4ReasonCode = (UINT32) ucReasonCode; -+ -+ /* command to do this */ -+ rStatus = kalIoctl(prGlueInfo, -+ TdlsTestTearDownRecv, &rCmd, sizeof(rCmd), FALSE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ DBGLOG(TDLS, ERROR, "%s kalIoctl fail:%x\n", __func__, rStatus); -+ return; -+ } -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to inform firmware to skip tx fail case. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prInBuf A pointer to the command string buffer -+* \param[in] u4InBufLen The length of the buffer -+* \param[out] None -+* -+* \retval None -+* -+* EX: iwpriv wlan0 set_str_cmd 0_7_[Enable/Disable] -+ -+ iwpriv wlan0 set_str_cmd 0_7_1 -+*/ -+/*----------------------------------------------------------------------------*/ -+static void TdlsCmdTestTxFailSkip(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) -+{ -+ WLAN_STATUS rStatus; -+ TDLS_CMD_CORE_T rCmd; -+ UINT_32 u4BufLen; -+ -+ /* parse arguments */ -+ kalMemZero(rCmd.aucPeerMac, sizeof(rCmd.aucPeerMac)); -+ rCmd.Content.rCmdTxFailSkip.fgIsEnable = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ -+ DBGLOG(TDLS, INFO, "%s: fgIsEnable = %d\n", __func__, rCmd.Content.rCmdTxFailSkip.fgIsEnable); -+ -+ /* command to do this */ -+ rStatus = kalIoctl(prGlueInfo, TdlsTestTxFailSkip, &rCmd, sizeof(rCmd), FALSE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ DBGLOG(TDLS, ERROR, "%s kalIoctl fail:%x\n", __func__, rStatus); -+ return; -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to send a test frame command to wifi task. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prInBuf A pointer to the command string buffer -+* \param[in] u4InBufLen The length of the buffer -+* \param[out] None -+* -+* \retval None -+* -+* EX: iwpriv wlan0 set_str_cmd 0_12_0_[FrameType]_[DialogToken]_[Peer MAC] -+ -+ iwpriv wlan0 set_str_cmd 0_12_0_0_1_00:11:22:33:44:01 -+* -+* EX: iwpriv wlan0 set_str_cmd 0_12_2_[FrameType]_[DialogToken]_[Peer MAC] -+ -+ iwpriv wlan0 set_str_cmd 0_12_2_0_1_00:11:22:33:44:01 -+*/ -+/*----------------------------------------------------------------------------*/ -+static void TdlsCmdTestTxTdlsFrame(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) -+{ -+ PARAM_CUSTOM_TDLS_CMD_STRUCT_T rCmd; -+ UINT32 u4Subcmd; -+ UINT_32 u4BufLen; -+ -+ /* parse sub-command */ -+ u4Subcmd = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ DBGLOG(TDLS, INFO, " test tx tdls frame sub command = %u\n", u4Subcmd); -+ -+ /* parse command arguments */ -+ rCmd.ucFmeType = CmdStringDecParse(prInBuf, &prInBuf, &u4BufLen); -+ -+ switch (u4Subcmd) { -+ case TDLS_FRM_ACTION_SETUP_REQ: -+ case TDLS_FRM_ACTION_SETUP_RSP: -+ case TDLS_FRM_ACTION_CONFIRM: -+ rCmd.ucToken = CmdStringDecParse(prInBuf, &prInBuf, &u4BufLen); -+ CmdStringMacParse(prInBuf, &prInBuf, &u4InBufLen, rCmd.arRspAddr); -+ -+ DBGLOG(TDLS, INFO, " setup FmeType=%d Token=%d to [%pM]\n", -+ rCmd.ucFmeType, rCmd.ucToken, rCmd.arRspAddr); -+ break; -+ -+ default: -+ DBGLOG(TDLS, ERROR, " wrong test tx frame sub command\n"); -+ return; -+ } -+ -+ /* send command to wifi task to handle */ -+ kalIoctl(prGlueInfo, -+ TdlsTestTdlsFrameSend, -+ (PVOID)&rCmd, sizeof(PARAM_CUSTOM_TDLS_CMD_STRUCT_T), FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to send a test frame command to wifi task. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prInBuf A pointer to the command string buffer -+* \param[in] u4InBufLen The length of the buffer -+* \param[out] None -+* -+* \retval None -+* -+* EX: iwpriv wlan0 set_str_cmd 0_0_0_[FrameType]_[DialogToken]_[Cap]_[ExCap]_ -+ [SupRate0]_[SupRate1]_[SupRate2]_[SupRate3]_ -+ [SupChan0]_[SupChan1]_[SupChan2]_[SupChan3]_ -+ [Timeout]_[Peer MAC] -+ -+ iwpriv wlan0 set_str_cmd 0_0_0_0_1_1_7_0_0_0_0_0_0_0_0_300_00:11:22:33:44:01 -+*/ -+/*----------------------------------------------------------------------------*/ -+static void TdlsCmdTestTxFrame(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) -+{ -+ PARAM_CUSTOM_TDLS_CMD_STRUCT_T rCmd; -+ TDLS_STATUS u4Status; -+ UINT_32 u4Subcmd; -+ UINT_32 u4BufLen; -+ -+ /* parse sub-command */ -+ u4Subcmd = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ DBGLOG(TDLS, INFO, " test tx frame sub command = %u\n", (UINT32) u4Subcmd); -+ -+ /* parse command arguments */ -+ switch (u4Subcmd) { -+ case TDLS_FRM_ACTION_SETUP_REQ: -+ u4Status = TdlsCmdTestTxFmeSetupReqBufTranslate(prInBuf, u4InBufLen, &rCmd); -+ break; -+ -+ default: -+ DBGLOG(TDLS, ERROR, " wrong test tx frame sub command\n"); -+ return; -+ } -+ -+ if (u4Status != TDLS_STATUS_SUCCESS) { -+ DBGLOG(TDLS, ERROR, " command parse fail\n"); -+ return; -+ } -+ -+ /* send command to wifi task to handle */ -+ kalIoctl(prGlueInfo, -+ TdlsTestFrameSend, -+ (PVOID)&rCmd, sizeof(PARAM_CUSTOM_TDLS_CMD_STRUCT_T), FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Parse the TDLS test frame command, setup request -+* -+* @param CmdBuf Pointer to the buffer. -+* @param BufLen Record buffer length. -+* @param CmdTspec Pointer to the structure. -+* -+* @retval WLAN_STATUS_SUCCESS: Translate OK. -+* @retval WLAN_STATUS_FAILURE: Translate fail. -+* @usage iwpriv wlan0 set_str_cmd [tdls]_[command] -+* -+* EX: iwpriv wlan0 set_str_cmd 0_0_0_[FrameType]_[DialogToken]_[Cap]_[ExCap]_ -+ [SupRate0]_[SupRate1]_[SupRate2]_[SupRate3]_ -+ [SupChan0]_[SupChan1]_[SupChan2]_[SupChan3]_ -+ [Timeout]_[Peer MAC] -+ -+ iwpriv wlan0 set_str_cmd 0_0_0_0_1_1_7_0_0_0_0_0_0_0_0_300_00:11:22:33:44:01 -+*/ -+/*----------------------------------------------------------------------------*/ -+static TDLS_STATUS -+TdlsCmdTestTxFmeSetupReqBufTranslate(UINT_8 *pCmdBuf, UINT_32 u4BufLen, PARAM_CUSTOM_TDLS_CMD_STRUCT_T *prCmd) -+{ -+/* dumpMemory8(ANDROID_LOG_INFO, pCmdBuf, u4BufLen); */ -+ -+ prCmd->ucFmeType = CmdStringDecParse(pCmdBuf, &pCmdBuf, &u4BufLen); -+ prCmd->ucToken = CmdStringDecParse(pCmdBuf, &pCmdBuf, &u4BufLen); -+ prCmd->u2Cap = CmdStringDecParse(pCmdBuf, &pCmdBuf, &u4BufLen); -+ prCmd->ucExCap = CmdStringDecParse(pCmdBuf, &pCmdBuf, &u4BufLen); -+ prCmd->arSupRate[0] = CmdStringDecParse(pCmdBuf, &pCmdBuf, &u4BufLen); -+ prCmd->arSupRate[1] = CmdStringDecParse(pCmdBuf, &pCmdBuf, &u4BufLen); -+ prCmd->arSupRate[2] = CmdStringDecParse(pCmdBuf, &pCmdBuf, &u4BufLen); -+ prCmd->arSupRate[3] = CmdStringDecParse(pCmdBuf, &pCmdBuf, &u4BufLen); -+ prCmd->arSupChan[0] = CmdStringDecParse(pCmdBuf, &pCmdBuf, &u4BufLen); -+ prCmd->arSupChan[1] = CmdStringDecParse(pCmdBuf, &pCmdBuf, &u4BufLen); -+ prCmd->arSupChan[2] = CmdStringDecParse(pCmdBuf, &pCmdBuf, &u4BufLen); -+ prCmd->arSupChan[3] = CmdStringDecParse(pCmdBuf, &pCmdBuf, &u4BufLen); -+ prCmd->u4Timeout = CmdStringDecParse(pCmdBuf, &pCmdBuf, &u4BufLen); -+ CmdStringMacParse(pCmdBuf, &pCmdBuf, &u4BufLen, prCmd->arRspAddr); -+ -+ DBGLOG(TDLS, INFO, " command content =\n"); -+ DBGLOG(TDLS, INFO, "\tPeer MAC = %pM\n", (prCmd->arRspAddr)); -+ DBGLOG(TDLS, INFO, "\tToken = %u, Cap = 0x%x, ExCap = 0x%x, Timeout = %us FrameType = %u\n", -+ (UINT32) prCmd->ucToken, prCmd->u2Cap, prCmd->ucExCap, -+ (UINT32) prCmd->u4Timeout, (UINT32) prCmd->ucFmeType); -+ DBGLOG(TDLS, INFO, "\tSupRate = 0x%x %x %x %x\n", -+ prCmd->arSupRate[0], prCmd->arSupRate[1], prCmd->arSupRate[2], prCmd->arSupRate[3]); -+ DBGLOG(TDLS, INFO, "\tSupChan = %d %d %d %d\n", -+ prCmd->arSupChan[0], prCmd->arSupChan[1], prCmd->arSupChan[2], prCmd->arSupChan[3]); -+ -+ return TDLS_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to update a TDLS peer. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prInBuf A pointer to the command string buffer -+* \param[in] u4InBufLen The length of the buffer -+* \param[out] None -+* -+* \retval None -+* -+* EX: iwpriv wlan0 set_str_cmd 0_3_[Responder MAC] -+ -+ iwpriv wlan0 set_str_cmd 0_3_00:11:22:33:44:01 -+*/ -+/*----------------------------------------------------------------------------*/ -+static void TdlsCmdTestUpdatePeer(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) -+{ -+ PARAM_CUSTOM_TDLS_CMD_STRUCT_T rCmd; -+ struct wireless_dev *prWdev; -+ -+ /* reset */ -+ kalMemZero(&rCmd, sizeof(rCmd)); -+ -+ /* parse arguments */ -+ CmdStringMacParse(prInBuf, &prInBuf, &u4InBufLen, rCmd.arRspAddr); -+ -+ /* init */ -+ rCmd.rPeerInfo.supported_rates = rCmd.arSupRate; -+ rCmd.rPeerInfo.ht_capa = &rCmd.rHtCapa; -+ rCmd.rPeerInfo.vht_capa = &rCmd.rVhtCapa; /* LINUX_KERNEL_VERSION >= 3.10.0 */ -+ rCmd.rPeerInfo.sta_flags_set = BIT(NL80211_STA_FLAG_TDLS_PEER); -+ rCmd.rPeerInfo.uapsd_queues = 0xf; /* all AC */ -+ rCmd.rPeerInfo.max_sp = 0; /* delivery all packets */ -+ -+ /* send command to wifi task to handle */ -+ prWdev = prGlueInfo->prDevHandler->ieee80211_ptr; -+ mtk_cfg80211_add_station(prWdev->wiphy, (void *)0x1, rCmd.arRspAddr, &rCmd.rPeerInfo); -+ -+ /* update */ -+ TdlsexCfg80211TdlsOper(prWdev->wiphy, (void *)0x1, rCmd.arRspAddr, NL80211_TDLS_ENABLE_LINK); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to receive a Null frame from the peer. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set -+* \param[in] u4SetBufferLen The length of the set buffer -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed due to invalid length of -+* the set buffer, returns the amount of storage needed. -+* -+* \retval TDLS_STATUS_xx -+* -+* EX: iwpriv wlan0 set_str_cmd 0_5_[Responder MAC]_[PM bit] -+ -+ iwpriv wlan0 set_str_cmd 0_5_00:11:22:33:44:01_1 -+*/ -+/*----------------------------------------------------------------------------*/ -+static void TdlsCmdTestNullRecv(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) -+{ -+ WLAN_STATUS rStatus; -+ TDLS_CMD_CORE_T rCmd; -+ UINT_32 u4BufLen; -+ -+ /* parse arguments */ -+ CmdStringMacParse(prInBuf, &prInBuf, &u4InBufLen, rCmd.aucPeerMac); -+ rCmd.Content.rCmdNullRcv.u4PM = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ -+ DBGLOG(TDLS, INFO, "%s: [%pM] u4PM = %u\n", -+ __func__, (rCmd.aucPeerMac), (UINT32) rCmd.Content.rCmdNullRcv.u4PM); -+ -+ /* command to do this */ -+ rStatus = kalIoctl(prGlueInfo, TdlsTestNullRecv, &rCmd, sizeof(rCmd), FALSE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ DBGLOG(TDLS, ERROR, "%s kalIoctl fail:%x\n", __func__, rStatus); -+ return; -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to send a data frame to the peer periodically. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* \param[in] u4Param no use -+* \param[out] None -+* -+* \retval None -+* -+* EX: iwpriv wlan0 set_str_cmd 0_15_[Responder MAC]_[Interval: ms]_[Enable/Disable] -+ -+ iwpriv wlan0 set_str_cmd 0_15_00:11:22:33:44:01_5000_1 -+*/ -+/*----------------------------------------------------------------------------*/ -+static VOID TdlsTimerTestDataContSend(ADAPTER_T *prAdapter, UINT_32 u4Param) -+{ -+ GLUE_INFO_T *prGlueInfo; -+ struct sk_buff *prMsduInfo; -+ UINT_8 *prPkt; -+ -+ /* init */ -+ prGlueInfo = prAdapter->prGlueInfo; -+ -+ /* allocate a data frame */ -+ prMsduInfo = kalPacketAlloc(prGlueInfo, 1000, &prPkt); -+ if (prMsduInfo == NULL) { -+ DBGLOG(TDLS, ERROR, " %s allocate pkt fail!\n", __func__); -+ return; -+ } -+ -+ /* init dev */ -+ prMsduInfo->dev = prGlueInfo->prDevHandler; -+ if (prMsduInfo->dev == NULL) { -+ DBGLOG(TDLS, ERROR, " %s prMsduInfo->dev == NULL!\n", __func__); -+ kalPacketFree(prGlueInfo, prMsduInfo); -+ return; -+ } -+ -+ /* init packet */ -+ prMsduInfo->len = 1000; -+ kalMemCopy(prMsduInfo->data, aucTdlsTestDataSPeerMac, 6); -+ kalMemCopy(prMsduInfo->data + 6, prAdapter->rMyMacAddr, 6); -+ *(UINT_16 *) (prMsduInfo->data + 12) = 0x0800; -+ -+ DBGLOG(TDLS, INFO, " %s try to send a data frame to %pM\n", -+ __func__, aucTdlsTestDataSPeerMac); -+ -+ /* simulate OS to send the packet */ -+ wlanHardStartXmit(prMsduInfo, prMsduInfo->dev); -+ -+ /* restart test timer */ -+ cnmTimerStartTimer(prAdapter, &rTdlsTimerTestDataSend, u2TdlsTestDataSInterval); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to receive a Channel Switch Request frame. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set -+* \param[in] u4SetBufferLen The length of the set buffer -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed due to invalid length of -+* the set buffer, returns the amount of storage needed. -+* -+* \retval TDLS_STATUS_xx -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static TDLS_STATUS -+TdlsTestChStReqRecv(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen) -+{ -+ TDLS_CMD_CORE_T *prCmdContent; -+ WLAN_STATUS rStatus; -+ -+ /* init command buffer */ -+ prCmdContent = (TDLS_CMD_CORE_T *) pvSetBuffer; -+ prCmdContent->u4Command = TDLS_CORE_CMD_TEST_CHSW_REQ; -+ -+ /* send the command */ -+ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ -+ CMD_ID_TDLS_CORE, /* ucCID */ -+ TRUE, /* fgSetQuery */ -+ FALSE, /* fgNeedResp */ -+ FALSE, /* fgIsOid */ -+ NULL, NULL, /* pfCmdTimeoutHandler */ -+ sizeof(TDLS_CMD_CORE_T), /* u4SetQueryInfoLen */ -+ (PUINT_8) prCmdContent, /* pucInfoBuffer */ -+ NULL, /* pvSetQueryBuffer */ -+ 0 /* u4SetQueryBufferLen */ -+ ); -+ -+ if (rStatus != WLAN_STATUS_PENDING) { -+ DBGLOG(TDLS, ERROR, "%s wlanSendSetQueryCmd allocation fail!\n", __func__); -+ return TDLS_STATUS_RESOURCES; -+ } -+ -+ DBGLOG(TDLS, INFO, "%s cmd ok.\n", __func__); -+ return TDLS_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to receive a Channel Switch Response frame. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set -+* \param[in] u4SetBufferLen The length of the set buffer -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed due to invalid length of -+* the set buffer, returns the amount of storage needed. -+* -+* \retval TDLS_STATUS_xx -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static TDLS_STATUS -+TdlsTestChStRspRecv(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen) -+{ -+ TDLS_CMD_CORE_T *prCmdContent; -+ WLAN_STATUS rStatus; -+ -+ /* init command buffer */ -+ prCmdContent = (TDLS_CMD_CORE_T *) pvSetBuffer; -+ prCmdContent->u4Command = TDLS_CORE_CMD_TEST_CHSW_RSP; -+ -+ /* send the command */ -+ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ -+ CMD_ID_TDLS_CORE, /* ucCID */ -+ TRUE, /* fgSetQuery */ -+ FALSE, /* fgNeedResp */ -+ FALSE, /* fgIsOid */ -+ NULL, NULL, /* pfCmdTimeoutHandler */ -+ sizeof(TDLS_CMD_CORE_T), /* u4SetQueryInfoLen */ -+ (PUINT_8) prCmdContent, /* pucInfoBuffer */ -+ NULL, /* pvSetQueryBuffer */ -+ 0 /* u4SetQueryBufferLen */ -+ ); -+ -+ if (rStatus != WLAN_STATUS_PENDING) { -+ DBGLOG(TDLS, ERROR, "%s wlanSendSetQueryCmd allocation fail!\n", __func__); -+ return TDLS_STATUS_RESOURCES; -+ } -+ -+ DBGLOG(TDLS, INFO, "%s cmd ok.\n", __func__); -+ return TDLS_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to send a test frame. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set -+* \param[in] u4SetBufferLen The length of the set buffer -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed due to invalid length of -+* the set buffer, returns the amount of storage needed. -+* -+* \retval TDLS_STATUS_xx -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static TDLS_STATUS -+TdlsTestFrameSend(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen) -+{ -+ GLUE_INFO_T *prGlueInfo; -+ PARAM_CUSTOM_TDLS_CMD_STRUCT_T *prCmd; -+ P_BSS_INFO_T prBssInfo; -+ struct sk_buff *prMsduInfo; -+ UINT_8 *pPkt; -+ UINT_32 u4PktLen, u4IeLen; -+ -+ /* sanity check */ -+ ASSERT(prAdapter); -+ ASSERT(pvSetBuffer); -+ ASSERT(pu4SetInfoLen); -+ -+ DBGLOG(TDLS, INFO, " %s\n", __func__); -+ -+ if (u4SetBufferLen == 0) -+ return TDLS_STATUS_INVALID_LENGTH; -+ -+ /* allocate/init packet */ -+ prGlueInfo = (GLUE_INFO_T *) prAdapter->prGlueInfo; -+ prCmd = (PARAM_CUSTOM_TDLS_CMD_STRUCT_T *) pvSetBuffer; -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ *pu4SetInfoLen = u4SetBufferLen; -+ u4PktLen = 0; -+ -+ prMsduInfo = kalPacketAlloc(prGlueInfo, 1600, &pPkt); -+ if (prMsduInfo == NULL) { -+ DBGLOG(TDLS, ERROR, " %s: allocate pkt fail\n", __func__); -+ return TDLS_STATUS_RESOURCES; -+ } -+ -+ prMsduInfo->dev = prGlueInfo->prDevHandler; -+ if (prMsduInfo->dev == NULL) { -+ DBGLOG(TDLS, ERROR, " %s: MsduInfo->dev == NULL\n", __func__); -+ kalPacketFree(prGlueInfo, prMsduInfo); -+ return TDLS_STATUS_FAILURE; -+ } -+ -+ /* make up frame content */ -+ /* 1. 802.3 header */ -+ kalMemCopy(pPkt, prCmd->arRspAddr, TDLS_FME_MAC_ADDR_LEN); -+ LR_TDLS_FME_FIELD_FILL(TDLS_FME_MAC_ADDR_LEN); -+ kalMemCopy(pPkt, prAdapter->rMyMacAddr, TDLS_FME_MAC_ADDR_LEN); -+ LR_TDLS_FME_FIELD_FILL(TDLS_FME_MAC_ADDR_LEN); -+ *(UINT_16 *) pPkt = htons(TDLS_FRM_PROT_TYPE); -+ LR_TDLS_FME_FIELD_FILL(2); -+ -+ /* 2. payload type */ -+ *pPkt = TDLS_FRM_PAYLOAD_TYPE; -+ LR_TDLS_FME_FIELD_FILL(1); -+ -+ /* 3. Frame Formation - (1) Category */ -+ *pPkt = TDLS_FRM_CATEGORY; -+ LR_TDLS_FME_FIELD_FILL(1); -+ -+ /* 3. Frame Formation - (2) Action */ -+ *pPkt = prCmd->ucFmeType; -+ LR_TDLS_FME_FIELD_FILL(1); -+ -+ /* 3. Frame Formation - (3) Dialog token */ -+ *pPkt = prCmd->ucToken; -+ LR_TDLS_FME_FIELD_FILL(1); -+ -+ /* 3. Frame Formation - (4) Capability */ -+ WLAN_SET_FIELD_16(pPkt, prCmd->u2Cap); -+ LR_TDLS_FME_FIELD_FILL(2); -+ -+ /* 4. Append general IEs */ -+ u4IeLen = TdlsFrameGeneralIeAppend(prAdapter, NULL, 0, pPkt); -+ LR_TDLS_FME_FIELD_FILL(u4IeLen); -+ -+ /* 3. Frame Formation - (10) Extended capabilities element */ -+ EXT_CAP_IE(pPkt)->ucId = ELEM_ID_EXTENDED_CAP; -+ EXT_CAP_IE(pPkt)->ucLength = 5; -+ -+ EXT_CAP_IE(pPkt)->aucCapabilities[0] = 0x00; /* bit0 ~ bit7 */ -+ EXT_CAP_IE(pPkt)->aucCapabilities[1] = 0x00; /* bit8 ~ bit15 */ -+ EXT_CAP_IE(pPkt)->aucCapabilities[2] = 0x00; /* bit16 ~ bit23 */ -+ EXT_CAP_IE(pPkt)->aucCapabilities[3] = 0x00; /* bit24 ~ bit31 */ -+ EXT_CAP_IE(pPkt)->aucCapabilities[4] = 0x00; /* bit32 ~ bit39 */ -+ -+ if (prCmd->ucExCap & TDLS_EX_CAP_PEER_UAPSD) -+ EXT_CAP_IE(pPkt)->aucCapabilities[3] |= BIT((28 - 24)); -+ if (prCmd->ucExCap & TDLS_EX_CAP_CHAN_SWITCH) -+ EXT_CAP_IE(pPkt)->aucCapabilities[3] |= BIT((30 - 24)); -+ if (prCmd->ucExCap & TDLS_EX_CAP_TDLS) -+ EXT_CAP_IE(pPkt)->aucCapabilities[4] |= BIT((37 - 32)); -+ -+ u4IeLen = IE_SIZE(pPkt); -+ LR_TDLS_FME_FIELD_FILL(u4IeLen); -+ -+ /* 3. Frame Formation - (12) Timeout interval element (TPK Key Lifetime) */ -+ TIMEOUT_INTERVAL_IE(pPkt)->ucId = ELEM_ID_TIMEOUT_INTERVAL; -+ TIMEOUT_INTERVAL_IE(pPkt)->ucLength = 5; -+ -+ TIMEOUT_INTERVAL_IE(pPkt)->ucType = IE_TIMEOUT_INTERVAL_TYPE_KEY_LIFETIME; -+ TIMEOUT_INTERVAL_IE(pPkt)->u4Value = htonl(prCmd->u4Timeout); -+ -+ u4IeLen = IE_SIZE(pPkt); -+ LR_TDLS_FME_FIELD_FILL(u4IeLen); -+ -+ /* 3. Frame Formation - (16) Link identifier element */ -+ TDLS_LINK_IDENTIFIER_IE(pPkt)->ucId = ELEM_ID_LINK_IDENTIFIER; -+ TDLS_LINK_IDENTIFIER_IE(pPkt)->ucLength = ELEM_LEN_LINK_IDENTIFIER; -+ -+ kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aBSSID, prBssInfo->aucBSSID, 6); -+ kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aInitiator, prAdapter->rMyMacAddr, 6); -+ kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aResponder, prCmd->arRspAddr, 6); -+ -+ u4IeLen = IE_SIZE(pPkt); -+ LR_TDLS_FME_FIELD_FILL(u4IeLen); -+ -+ /* 4. Update packet length */ -+ prMsduInfo->len = u4PktLen; -+ dumpMemory8(prMsduInfo->data, u4PktLen); -+ -+ /* 5. send the data frame */ -+ wlanHardStartXmit(prMsduInfo, prMsduInfo->dev); -+ return TDLS_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to receive a NULL frame. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set -+* \param[in] u4SetBufferLen The length of the set buffer -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed due to invalid length of -+* the set buffer, returns the amount of storage needed. -+* -+* \retval TDLS_STATUS_xx -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static TDLS_STATUS -+TdlsTestNullRecv(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen) -+{ -+ TDLS_CMD_CORE_T *prCmdContent; -+ WLAN_STATUS rStatus; -+ -+ /* init command buffer */ -+ prCmdContent = (TDLS_CMD_CORE_T *) pvSetBuffer; -+ prCmdContent->u4Command = TDLS_CORE_CMD_TEST_NULL_RCV; -+ -+ /* send the command */ -+ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ -+ CMD_ID_TDLS_CORE, /* ucCID */ -+ TRUE, /* fgSetQuery */ -+ FALSE, /* fgNeedResp */ -+ FALSE, /* fgIsOid */ -+ NULL, NULL, /* pfCmdTimeoutHandler */ -+ sizeof(TDLS_CMD_CORE_T), /* u4SetQueryInfoLen */ -+ (PUINT_8) prCmdContent, /* pucInfoBuffer */ -+ NULL, /* pvSetQueryBuffer */ -+ 0 /* u4SetQueryBufferLen */ -+ ); -+ -+ if (rStatus != WLAN_STATUS_PENDING) { -+ DBGLOG(TDLS, ERROR, "%s wlanSendSetQueryCmd allocation fail!\n", __func__); -+ return TDLS_STATUS_RESOURCES; -+ } -+ -+ DBGLOG(TDLS, INFO, "%s cmd ok.\n", __func__); -+ return TDLS_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to receive a PTI frame. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set -+* \param[in] u4SetBufferLen The length of the set buffer -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed due to invalid length of -+* the set buffer, returns the amount of storage needed. -+* -+* \retval TDLS_STATUS_xx -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static TDLS_STATUS -+TdlsTestPtiReqRecv(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen) -+{ -+ TDLS_CMD_CORE_T *prCmdContent; -+ WLAN_STATUS rStatus; -+ -+ /* init command buffer */ -+ prCmdContent = (TDLS_CMD_CORE_T *) pvSetBuffer; -+ prCmdContent->u4Command = TDLS_CORE_CMD_TEST_PTI_REQ; -+ -+ /* send the command */ -+ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ -+ CMD_ID_TDLS_CORE, /* ucCID */ -+ TRUE, /* fgSetQuery */ -+ FALSE, /* fgNeedResp */ -+ FALSE, /* fgIsOid */ -+ NULL, NULL, /* pfCmdTimeoutHandler */ -+ sizeof(TDLS_CMD_CORE_T), /* u4SetQueryInfoLen */ -+ (PUINT_8) prCmdContent, /* pucInfoBuffer */ -+ NULL, /* pvSetQueryBuffer */ -+ 0 /* u4SetQueryBufferLen */ -+ ); -+ -+ if (rStatus != WLAN_STATUS_PENDING) { -+ DBGLOG(TDLS, ERROR, "%s wlanSendSetQueryCmd allocation fail!\n", __func__); -+ return TDLS_STATUS_RESOURCES; -+ } -+ -+ DBGLOG(TDLS, INFO, "%s cmd ok.\n", __func__); -+ return TDLS_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to receive a PTI response frame. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set -+* \param[in] u4SetBufferLen The length of the set buffer -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed due to invalid length of -+* the set buffer, returns the amount of storage needed. -+* -+* \retval TDLS_STATUS_xx -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static TDLS_STATUS -+TdlsTestPtiRspRecv(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen) -+{ -+ TDLS_CMD_CORE_T *prCmdContent; -+ WLAN_STATUS rStatus; -+ -+ /* init command buffer */ -+ prCmdContent = (TDLS_CMD_CORE_T *) pvSetBuffer; -+ prCmdContent->u4Command = TDLS_CORE_CMD_TEST_PTI_RSP; -+ -+ /* send the command */ -+ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ -+ CMD_ID_TDLS_CORE, /* ucCID */ -+ TRUE, /* fgSetQuery */ -+ FALSE, /* fgNeedResp */ -+ FALSE, /* fgIsOid */ -+ NULL, NULL, /* pfCmdTimeoutHandler */ -+ sizeof(TDLS_CMD_CORE_T), /* u4SetQueryInfoLen */ -+ (PUINT_8) prCmdContent, /* pucInfoBuffer */ -+ NULL, /* pvSetQueryBuffer */ -+ 0 /* u4SetQueryBufferLen */ -+ ); -+ -+ if (rStatus != WLAN_STATUS_PENDING) { -+ DBGLOG(TDLS, ERROR, "%s wlanSendSetQueryCmd allocation fail!\n", __func__); -+ return TDLS_STATUS_RESOURCES; -+ } -+ -+ DBGLOG(TDLS, INFO, "%s cmd ok.\n", __func__); -+ return TDLS_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to receive a Tear Down frame. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set -+* \param[in] u4SetBufferLen The length of the set buffer -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed due to invalid length of -+* the set buffer, returns the amount of storage needed. -+* -+* \retval TDLS_STATUS_xx -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static TDLS_STATUS -+TdlsTestTearDownRecv(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen) -+{ -+ TDLS_CMD_CORE_T *prCmdContent; -+ WLAN_STATUS rStatus; -+ -+ /* init command buffer */ -+ prCmdContent = (TDLS_CMD_CORE_T *) pvSetBuffer; -+ prCmdContent->u4Command = TDLS_CORE_CMD_TEST_TEAR_DOWN; -+ -+ /* send the command */ -+ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ -+ CMD_ID_TDLS_CORE, /* ucCID */ -+ TRUE, /* fgSetQuery */ -+ FALSE, /* fgNeedResp */ -+ FALSE, /* fgIsOid */ -+ NULL, NULL, /* pfCmdTimeoutHandler */ -+ sizeof(TDLS_CMD_CORE_T), /* u4SetQueryInfoLen */ -+ (PUINT_8) prCmdContent, /* pucInfoBuffer */ -+ NULL, /* pvSetQueryBuffer */ -+ 0 /* u4SetQueryBufferLen */ -+ ); -+ -+ if (rStatus != WLAN_STATUS_PENDING) { -+ DBGLOG(TDLS, ERROR, "%s wlanSendSetQueryCmd allocation fail!\n", __func__); -+ return TDLS_STATUS_RESOURCES; -+ } -+ -+ DBGLOG(TDLS, INFO, "%s cmd ok.\n", __func__); -+ return TDLS_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to receive a data frame. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set -+* \param[in] u4SetBufferLen The length of the set buffer -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed due to invalid length of -+* the set buffer, returns the amount of storage needed. -+* -+* \retval TDLS_STATUS_xx -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static TDLS_STATUS -+TdlsTestDataRecv(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen) -+{ -+ TDLS_CMD_CORE_T *prCmdContent; -+ WLAN_STATUS rStatus; -+ -+ /* init command buffer */ -+ prCmdContent = (TDLS_CMD_CORE_T *) pvSetBuffer; -+ prCmdContent->u4Command = TDLS_CORE_CMD_TEST_DATA_RCV; -+ -+ /* send the command */ -+ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ -+ CMD_ID_TDLS_CORE, /* ucCID */ -+ TRUE, /* fgSetQuery */ -+ FALSE, /* fgNeedResp */ -+ FALSE, /* fgIsOid */ -+ NULL, NULL, /* pfCmdTimeoutHandler */ -+ sizeof(TDLS_CMD_CORE_T), /* u4SetQueryInfoLen */ -+ (PUINT_8) prCmdContent, /* pucInfoBuffer */ -+ NULL, /* pvSetQueryBuffer */ -+ 0 /* u4SetQueryBufferLen */ -+ ); -+ -+ if (rStatus != WLAN_STATUS_PENDING) { -+ DBGLOG(TDLS, ERROR, "%s wlanSendSetQueryCmd allocation fail!\n", __func__); -+ return TDLS_STATUS_RESOURCES; -+ } -+ -+ DBGLOG(TDLS, INFO, "%s cmd ok.\n", __func__); -+ return TDLS_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to skip PTI tx fail status. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set -+* \param[in] u4SetBufferLen The length of the set buffer -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed due to invalid length of -+* the set buffer, returns the amount of storage needed. -+* -+* \retval TDLS_STATUS_xx -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static TDLS_STATUS -+TdlsTestPtiTxFail(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen) -+{ -+ TDLS_CMD_CORE_T *prCmdContent; -+ WLAN_STATUS rStatus; -+ -+ /* init command buffer */ -+ prCmdContent = (TDLS_CMD_CORE_T *) pvSetBuffer; -+ prCmdContent->u4Command = TDLS_CORE_CMD_TEST_PTI_TX_FAIL; -+ -+ /* send the command */ -+ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ -+ CMD_ID_TDLS_CORE, /* ucCID */ -+ TRUE, /* fgSetQuery */ -+ FALSE, /* fgNeedResp */ -+ FALSE, /* fgIsOid */ -+ NULL, NULL, /* pfCmdTimeoutHandler */ -+ sizeof(TDLS_CMD_CORE_T), /* u4SetQueryInfoLen */ -+ (PUINT_8) prCmdContent, /* pucInfoBuffer */ -+ NULL, /* pvSetQueryBuffer */ -+ 0 /* u4SetQueryBufferLen */ -+ ); -+ -+ if (rStatus != WLAN_STATUS_PENDING) { -+ DBGLOG(TDLS, ERROR, "%s wlanSendSetQueryCmd allocation fail!\n", __func__); -+ return TDLS_STATUS_RESOURCES; -+ } -+ -+ DBGLOG(TDLS, INFO, "%s cmd ok.\n", __func__); -+ return TDLS_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to send a TDLS action frame. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set -+* \param[in] u4SetBufferLen The length of the set buffer -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed due to invalid length of -+* the set buffer, returns the amount of storage needed. -+* -+* \retval TDLS_STATUS_xx -+* -+* EX: iwpriv wlan0 set_str_cmd 0_12_0_[FrameType]_[DialogToken]_[Peer MAC] -+ -+ iwpriv wlan0 set_str_cmd 0_12_0_0_1_00:11:22:33:44:01 -+*/ -+/*----------------------------------------------------------------------------*/ -+static TDLS_STATUS -+TdlsTestTdlsFrameSend(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen) -+{ -+ GLUE_INFO_T *prGlueInfo; -+ PARAM_CUSTOM_TDLS_CMD_STRUCT_T *prCmd; -+ struct wireless_dev *prWdev; -+ -+ /* sanity check */ -+ ASSERT(prAdapter); -+ ASSERT(pvSetBuffer); -+ ASSERT(pu4SetInfoLen); -+ -+ DBGLOG(TDLS, INFO, " %s\n", __func__); -+ -+ if (u4SetBufferLen == 0) -+ return TDLS_STATUS_INVALID_LENGTH; -+ -+ /* allocate/init packet */ -+ prGlueInfo = (GLUE_INFO_T *) prAdapter->prGlueInfo; -+ prCmd = (PARAM_CUSTOM_TDLS_CMD_STRUCT_T *) pvSetBuffer; -+ prWdev = (struct wireless_dev *)prGlueInfo->prDevHandler->ieee80211_ptr; -+ -+ TdlsexCfg80211TdlsMgmt(prWdev->wiphy, NULL, -+ prCmd->arRspAddr, prCmd->ucFmeType, 1, -+ 0, 0, /* open/none */ -+ FALSE, NULL, 0); -+ -+ return TDLS_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to skip tx fail status. So always success in tx done in firmware. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set -+* \param[in] u4SetBufferLen The length of the set buffer -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed due to invalid length of -+* the set buffer, returns the amount of storage needed. -+* -+* \retval TDLS_STATUS_xx -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static TDLS_STATUS -+TdlsTestTxFailSkip(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen) -+{ -+ TDLS_CMD_CORE_T *prCmdContent; -+ WLAN_STATUS rStatus; -+ -+ /* init command buffer */ -+ prCmdContent = (TDLS_CMD_CORE_T *) pvSetBuffer; -+ prCmdContent->u4Command = TDLS_CORE_CMD_TEST_TX_FAIL_SKIP; -+ -+ /* send the command */ -+ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ -+ CMD_ID_TDLS_CORE, /* ucCID */ -+ TRUE, /* fgSetQuery */ -+ FALSE, /* fgNeedResp */ -+ FALSE, /* fgIsOid */ -+ NULL, NULL, /* pfCmdTimeoutHandler */ -+ sizeof(TDLS_CMD_CORE_T), /* u4SetQueryInfoLen */ -+ (PUINT_8) prCmdContent, /* pucInfoBuffer */ -+ NULL, /* pvSetQueryBuffer */ -+ 0 /* u4SetQueryBufferLen */ -+ ); -+ -+ if (rStatus != WLAN_STATUS_PENDING) { -+ DBGLOG(TDLS, ERROR, "%s wlanSendSetQueryCmd allocation fail!\n", __func__); -+ return TDLS_STATUS_RESOURCES; -+ } -+ -+ DBGLOG(TDLS, INFO, "%s cmd ok.\n", __func__); -+ return TDLS_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to skip to do keep alive function in firmware. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set -+* \param[in] u4SetBufferLen The length of the set buffer -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed due to invalid length of -+* the set buffer, returns the amount of storage needed. -+* -+* \retval TDLS_STATUS_xx -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static TDLS_STATUS -+TdlsTestKeepAliveSkip(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen) -+{ -+ TDLS_CMD_CORE_T *prCmdContent; -+ WLAN_STATUS rStatus; -+ -+ /* init command buffer */ -+ prCmdContent = (TDLS_CMD_CORE_T *) pvSetBuffer; -+ prCmdContent->u4Command = TDLS_CORE_CMD_TEST_KEEP_ALIVE_SKIP; -+ -+ /* send the command */ -+ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ -+ CMD_ID_TDLS_CORE, /* ucCID */ -+ TRUE, /* fgSetQuery */ -+ FALSE, /* fgNeedResp */ -+ FALSE, /* fgIsOid */ -+ NULL, NULL, /* pfCmdTimeoutHandler */ -+ sizeof(TDLS_CMD_CORE_T), /* u4SetQueryInfoLen */ -+ (PUINT_8) prCmdContent, /* pucInfoBuffer */ -+ NULL, /* pvSetQueryBuffer */ -+ 0 /* u4SetQueryBufferLen */ -+ ); -+ -+ if (rStatus != WLAN_STATUS_PENDING) { -+ DBGLOG(TDLS, ERROR, "%s wlanSendSetQueryCmd allocation fail!\n", __func__); -+ return TDLS_STATUS_RESOURCES; -+ } -+ -+ DBGLOG(TDLS, INFO, "%s cmd ok.\n", __func__); -+ return TDLS_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to skip channel switch timeout. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set -+* \param[in] u4SetBufferLen The length of the set buffer -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed due to invalid length of -+* the set buffer, returns the amount of storage needed. -+* -+* \retval TDLS_STATUS_xx -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static TDLS_STATUS -+TdlsTestChSwTimeoutSkip(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen) -+{ -+ TDLS_CMD_CORE_T *prCmdContent; -+ WLAN_STATUS rStatus; -+ -+ /* init command buffer */ -+ prCmdContent = (TDLS_CMD_CORE_T *) pvSetBuffer; -+ prCmdContent->u4Command = TDLS_CORE_CMD_TEST_CHSW_TIMEOUT_SKIP; -+ -+ /* send the command */ -+ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ -+ CMD_ID_TDLS_CORE, /* ucCID */ -+ TRUE, /* fgSetQuery */ -+ FALSE, /* fgNeedResp */ -+ FALSE, /* fgIsOid */ -+ NULL, NULL, /* pfCmdTimeoutHandler */ -+ sizeof(TDLS_CMD_CORE_T), /* u4SetQueryInfoLen */ -+ (PUINT_8) prCmdContent, /* pucInfoBuffer */ -+ NULL, /* pvSetQueryBuffer */ -+ 0 /* u4SetQueryBufferLen */ -+ ); -+ -+ if (rStatus != WLAN_STATUS_PENDING) { -+ DBGLOG(TDLS, ERROR, "%s wlanSendSetQueryCmd allocation fail!\n", __func__); -+ return TDLS_STATUS_RESOURCES; -+ } -+ -+ DBGLOG(TDLS, INFO, "%s cmd ok.\n", __func__); -+ return TDLS_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to skip scan request. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set -+* \param[in] u4SetBufferLen The length of the set buffer -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed due to invalid length of -+* the set buffer, returns the amount of storage needed. -+* -+* \retval TDLS_STATUS_xx -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static TDLS_STATUS -+TdlsTestScanSkip(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen) -+{ -+ TDLS_CMD_CORE_T *prCmdContent; -+ WLAN_STATUS rStatus; -+ -+ /* init command buffer */ -+ prCmdContent = (TDLS_CMD_CORE_T *) pvSetBuffer; -+ prCmdContent->u4Command = TDLS_CORE_CMD_TEST_SCAN_SKIP; -+ -+ /* send the command */ -+ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ -+ CMD_ID_TDLS_CORE, /* ucCID */ -+ TRUE, /* fgSetQuery */ -+ FALSE, /* fgNeedResp */ -+ FALSE, /* fgIsOid */ -+ NULL, NULL, /* pfCmdTimeoutHandler */ -+ sizeof(TDLS_CMD_CORE_T), /* u4SetQueryInfoLen */ -+ (PUINT_8) prCmdContent, /* pucInfoBuffer */ -+ NULL, /* pvSetQueryBuffer */ -+ 0 /* u4SetQueryBufferLen */ -+ ); -+ -+ if (rStatus != WLAN_STATUS_PENDING) { -+ DBGLOG(TDLS, ERROR, "%s wlanSendSetQueryCmd allocation fail!\n", __func__); -+ return TDLS_STATUS_RESOURCES; -+ } -+ -+ DBGLOG(TDLS, INFO, "%s cmd ok.\n", __func__); -+ return TDLS_STATUS_SUCCESS; -+} -+ -+#endif /* TDLS_CFG_CMD_TEST */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to configure channel switch parameters. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set -+* \param[in] u4SetBufferLen The length of the set buffer -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed due to invalid length of -+* the set buffer, returns the amount of storage needed. -+* -+* \retval TDLS_STATUS_xx -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static TDLS_STATUS -+TdlsChSwConf(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen) -+{ -+ TDLS_CMD_CORE_T *prCmdContent; -+ WLAN_STATUS rStatus; -+ -+ /* init command buffer */ -+ prCmdContent = (TDLS_CMD_CORE_T *) pvSetBuffer; -+ prCmdContent->u4Command = TDLS_CORE_CMD_CHSW_CONF; -+ -+ /* send the command */ -+ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ -+ CMD_ID_TDLS_CORE, /* ucCID */ -+ TRUE, /* fgSetQuery */ -+ FALSE, /* fgNeedResp */ -+ FALSE, /* fgIsOid */ -+ NULL, NULL, /* pfCmdTimeoutHandler */ -+ sizeof(TDLS_CMD_CORE_T), /* u4SetQueryInfoLen */ -+ (PUINT_8) prCmdContent, /* pucInfoBuffer */ -+ NULL, /* pvSetQueryBuffer */ -+ 0 /* u4SetQueryBufferLen */ -+ ); -+ -+ if (rStatus != WLAN_STATUS_PENDING) { -+ DBGLOG(TDLS, ERROR, "%s wlanSendSetQueryCmd allocation fail!\n", __func__); -+ return TDLS_STATUS_RESOURCES; -+ } -+ -+ DBGLOG(TDLS, INFO, "%s cmd ok.\n", __func__); -+ return TDLS_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to update channel switch parameters. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prInBuf A pointer to the command string buffer -+* \param[in] u4InBufLen The length of the buffer -+* \param[out] None -+* -+* \retval None -+* -+* EX: iwpriv wlan0 set_str_cmd 0_9_[TDLS Peer MAC]_ -+ [NetworkTypeIndex]_[1 (Enable) or (0) Disable]_[1 (Start) or 0 (Stop)]_ -+ [RegClass]_[Chan]_[SecChanOff]_[1 (Reqular) or (0) One Shot] -+ -+ RegulatoryClass: TODO (reference to Annex I of 802.11n spec.) -+ Secondary Channel Offset: 0 (SCN - no secondary channel) -+ 1 (SCA - secondary channel above) -+ 2 (SCB - secondary channel below) -+ SwitchTime: units of microseconds -+ -+ iwpriv wlan0 set_str_cmd 0_9_00:11:22:33:44:01_0_1_0_0_1_0_0 -+*/ -+/*----------------------------------------------------------------------------*/ -+static void TdlsCmdChSwConf(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) -+{ -+ WLAN_STATUS rStatus; -+ TDLS_CMD_CORE_T rCmd; -+ UINT_32 u4BufLen; -+ -+ /* parse arguments */ -+ CmdStringMacParse(prInBuf, &prInBuf, &u4InBufLen, rCmd.aucPeerMac); -+ -+ rCmd.Content.rCmdChSwConf.ucNetTypeIndex = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ rCmd.Content.rCmdChSwConf.fgIsChSwEnabled = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ rCmd.Content.rCmdChSwConf.fgIsChSwStarted = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ rCmd.Content.rCmdChSwConf.ucRegClass = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ rCmd.Content.rCmdChSwConf.ucTargetChan = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ rCmd.Content.rCmdChSwConf.ucSecChanOff = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ rCmd.Content.rCmdChSwConf.fgIsChSwRegular = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ -+ DBGLOG(TDLS, INFO, "%s: %pM ucNetTypeIndex=%d, fgIsChSwEnabled=%d, fgIsChSwStarted=%d", -+ __func__, (rCmd.aucPeerMac), -+ rCmd.Content.rCmdChSwConf.ucNetTypeIndex, -+ rCmd.Content.rCmdChSwConf.fgIsChSwEnabled, -+ rCmd.Content.rCmdChSwConf.fgIsChSwStarted); -+ DBGLOG(TDLS, INFO, " RegClass=%d, TargetChan=%d, SecChanOff=%d, Regular=%d\n", -+ rCmd.Content.rCmdChSwConf.ucRegClass, -+ rCmd.Content.rCmdChSwConf.ucTargetChan, -+ rCmd.Content.rCmdChSwConf.ucSecChanOff, rCmd.Content.rCmdChSwConf.fgIsChSwRegular); -+ -+ /* command to do this */ -+ rStatus = kalIoctl(prGlueInfo, TdlsChSwConf, &rCmd, sizeof(rCmd), FALSE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ DBGLOG(TDLS, ERROR, "%s kalIoctl fail:%x\n", __func__, rStatus); -+ return; -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to display TDLS related information. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prInBuf A pointer to the command string buffer -+* \param[in] u4InBufLen The length of the buffer -+* \param[out] None -+* -+* \retval None -+* -+* EX: iwpriv wlan0 set_str_cmd 0_18_[Peer MAC]_[Network Interface ID]_[IsClear] -+ -+ Network Interface ID: reference to ENUM_NETWORK_TYPE_INDEX_T -+ -+ typedef enum _ENUM_NETWORK_TYPE_INDEX_T { -+ NETWORK_TYPE_AIS_INDEX = 0, -+ NETWORK_TYPE_P2P_INDEX, -+ NETWORK_TYPE_BOW_INDEX, -+ NETWORK_TYPE_INDEX_NUM -+ } ENUM_NETWORK_TYPE_INDEX_T; -+ -+ iwpriv wlan0 set_str_cmd 0_18_00:00:00:00:00:00_0_0 -+*/ -+/*----------------------------------------------------------------------------*/ -+static void TdlsCmdInfoDisplay(GLUE_INFO_T *prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) -+{ -+ WLAN_STATUS rStatus; -+ TDLS_CMD_CORE_T rCmd; -+ UINT_32 u4BufLen; -+ -+ /* parse arguments */ -+ kalMemZero(&rCmd, sizeof(rCmd)); -+ -+ CmdStringMacParse(prInBuf, &prInBuf, &u4InBufLen, rCmd.aucPeerMac); -+ rCmd.ucNetTypeIndex = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ rCmd.Content.rCmdInfoDisplay.fgIsToClearAllHistory = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ -+ DBGLOG(TDLS, INFO, " %s: Command PeerMac=%pM in BSS%u\n", -+ __func__, (rCmd.aucPeerMac), rCmd.ucNetTypeIndex); -+ -+ /* command to do this */ -+ rStatus = kalIoctl(prGlueInfo, TdlsInfoDisplay, &rCmd, sizeof(rCmd), FALSE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ DBGLOG(TDLS, ERROR, "%s kalIoctl fail:%x\n", __func__, rStatus); -+ return; -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to display key related information. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prInBuf A pointer to the command string buffer -+* \param[in] u4InBufLen The length of the buffer -+* \param[out] None -+* -+* \retval None -+* -+* EX: iwpriv wlan0 set_str_cmd 0_20 -+ -+ iwpriv wlan0 set_str_cmd 0_20 -+*/ -+/*----------------------------------------------------------------------------*/ -+static void TdlsCmdKeyInfoDisplay(GLUE_INFO_T *prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) -+{ -+ WLAN_STATUS rStatus; -+ TDLS_CMD_CORE_T rCmd; -+ UINT_32 u4BufLen; -+ -+ /* parse arguments */ -+ kalMemZero(&rCmd, sizeof(rCmd)); -+ -+ DBGLOG(TDLS, INFO, " %s\n", __func__); -+ -+ /* command to do this */ -+ rStatus = kalIoctl(prGlueInfo, TdlsKeyInfoDisplay, &rCmd, sizeof(rCmd), FALSE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ DBGLOG(TDLS, ERROR, "%s kalIoctl fail:%x\n", __func__, rStatus); -+ return; -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to update MIB parameters. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prInBuf A pointer to the command string buffer -+* \param[in] u4InBufLen The length of the buffer -+* \param[out] None -+* -+* \retval None -+* -+* EX: iwpriv wlan0 set_str_cmd 0_6_[TdlsEn]_[UapsdEn]_[PsmEn]_[PtiWin]_[CWCap]_ -+ [AckMisRetry]_[RspTimeout]_[CWPbDelay]_[DRWin]_[LowestAcInt] -+ -+ iwpriv wlan0 set_str_cmd 0_6_1_1_0_1_1_3_5_1000_2_1 -+ -+ reference to TDLS_CMD_CORE_MIB_PARAM_UPDATE_T -+*/ -+/*----------------------------------------------------------------------------*/ -+static void TdlsCmdMibParamUpdate(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) -+{ -+ WLAN_STATUS rStatus; -+ TDLS_CMD_CORE_T rCmd; -+ UINT_32 u4BufLen; -+ -+ /* reset */ -+ kalMemZero(&rCmd, sizeof(rCmd)); -+ -+ /* parse arguments */ -+ rCmd.Content.rCmdMibUpdate.Tdlsdot11TunneledDirectLinkSetupImplemented = -+ CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ rCmd.Content.rCmdMibUpdate.Tdlsdot11TDLSPeerUAPSDBufferSTAActivated = -+ CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ rCmd.Content.rCmdMibUpdate.Tdlsdot11TDLSPeerPSMActivated = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ rCmd.Content.rCmdMibUpdate.Tdlsdot11TDLSPeerUAPSDIndicationWindow = -+ CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ rCmd.Content.rCmdMibUpdate.Tdlsdot11TDLSChannelSwitchingActivated = -+ CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ rCmd.Content.rCmdMibUpdate.Tdlsdot11TDLSPeerSTAMissingAckRetryLimit = -+ CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ rCmd.Content.rCmdMibUpdate.Tdlsdot11TDLSResponseTimeout = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ rCmd.Content.rCmdMibUpdate.Tdlsdot11TDLSProbeDelay = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ rCmd.Content.rCmdMibUpdate.Tdlsdot11TDLSDiscoveryRequestWindow = -+ CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ rCmd.Content.rCmdMibUpdate.Tdlsdot11TDLSACDeterminationInterval = -+ CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ -+ DBGLOG(TDLS, INFO, " MIB param = %d %d %d %d %d %d %d %d %d %d\n", -+ rCmd.Content.rCmdMibUpdate.Tdlsdot11TunneledDirectLinkSetupImplemented, -+ rCmd.Content.rCmdMibUpdate.Tdlsdot11TDLSPeerUAPSDBufferSTAActivated, -+ rCmd.Content.rCmdMibUpdate.Tdlsdot11TDLSPeerPSMActivated, -+ rCmd.Content.rCmdMibUpdate.Tdlsdot11TDLSPeerUAPSDIndicationWindow, -+ rCmd.Content.rCmdMibUpdate.Tdlsdot11TDLSChannelSwitchingActivated, -+ rCmd.Content.rCmdMibUpdate.Tdlsdot11TDLSPeerSTAMissingAckRetryLimit, -+ rCmd.Content.rCmdMibUpdate.Tdlsdot11TDLSResponseTimeout, -+ rCmd.Content.rCmdMibUpdate.Tdlsdot11TDLSProbeDelay, -+ rCmd.Content.rCmdMibUpdate.Tdlsdot11TDLSDiscoveryRequestWindow, -+ rCmd.Content.rCmdMibUpdate.Tdlsdot11TDLSACDeterminationInterval); -+ -+ /* command to do this */ -+ rStatus = kalIoctl(prGlueInfo, TdlsMibParamUpdate, &rCmd, sizeof(rCmd), FALSE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ DBGLOG(TDLS, ERROR, "%s kalIoctl fail:%x\n", __func__, rStatus); -+ return; -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to update setup parameters. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prInBuf A pointer to the command string buffer -+* \param[in] u4InBufLen The length of the buffer -+* \param[out] None -+* -+* \retval None -+* -+* EX: iwpriv wlan0 set_str_cmd 0_17_[20/40 Support] -+ -+ iwpriv wlan0 set_str_cmd 0_17_1 -+*/ -+/*----------------------------------------------------------------------------*/ -+static void TdlsCmdSetupConf(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) -+{ -+ WLAN_STATUS rStatus; -+ TDLS_CMD_CORE_T rCmd; -+ UINT_32 u4BufLen; -+ -+ /* parse arguments */ -+ kalMemZero(rCmd.aucPeerMac, sizeof(rCmd.aucPeerMac)); -+ -+ rCmd.Content.rCmdSetupConf.fgIs2040Supported = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ -+ DBGLOG(TDLS, INFO, "%s: rCmdSetupConf=%d\n", __func__, rCmd.Content.rCmdSetupConf.fgIs2040Supported); -+ -+ /* command to do this */ -+ prGlueInfo->rTdlsLink.fgIs2040Sup = rCmd.Content.rCmdSetupConf.fgIs2040Supported; -+ -+ rStatus = kalIoctl(prGlueInfo, TdlsSetupConf, &rCmd, sizeof(rCmd), FALSE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ DBGLOG(TDLS, ERROR, "%s kalIoctl fail:%x\n", __func__, rStatus); -+ return; -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to update UAPSD parameters. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prInBuf A pointer to the command string buffer -+* \param[in] u4InBufLen The length of the buffer -+* \param[out] None -+* -+* \retval None -+* -+* EX: iwpriv wlan0 set_str_cmd 0_8_[SP timeout skip]_[PTI timeout skip] -+ -+ iwpriv wlan0 set_str_cmd 0_8_1_1 -+*/ -+/*----------------------------------------------------------------------------*/ -+static void TdlsCmdUapsdConf(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) -+{ -+ WLAN_STATUS rStatus; -+ TDLS_CMD_CORE_T rCmd; -+ UINT_32 u4BufLen; -+ -+ /* parse arguments */ -+ kalMemZero(rCmd.aucPeerMac, sizeof(rCmd.aucPeerMac)); -+ -+ /* UAPSD Service Period */ -+ rCmd.Content.rCmdUapsdConf.fgIsSpTimeoutSkip = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ rCmd.Content.rCmdUapsdConf.fgIsPtiTimeoutSkip = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ /* PTI Service Period */ -+ fgIsPtiTimeoutSkip = rCmd.Content.rCmdUapsdConf.fgIsPtiTimeoutSkip; -+ -+ DBGLOG(TDLS, INFO, "%s: fgIsSpTimeoutSkip=%d, fgIsPtiTimeoutSkip=%d\n", -+ __func__, rCmd.Content.rCmdUapsdConf.fgIsSpTimeoutSkip, fgIsPtiTimeoutSkip); -+ -+ /* command to do this */ -+ rStatus = kalIoctl(prGlueInfo, TdlsUapsdConf, &rCmd, sizeof(rCmd), FALSE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ DBGLOG(TDLS, ERROR, "%s kalIoctl fail:%x\n", __func__, rStatus); -+ return; -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to display TDLS all information. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set -+* \param[in] u4SetBufferLen The length of the set buffer -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed due to invalid length of -+* the set buffer, returns the amount of storage needed. -+* -+* \retval TDLS_STATUS_xx -+* -+* iwpriv wlan0 set_str_cmd 0_18_00:00:00:00:00:00_0_0 -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static TDLS_STATUS -+TdlsInfoDisplay(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen) -+{ -+ GLUE_INFO_T *prGlueInfo; -+ TDLS_CMD_CORE_T *prCmdContent; -+ STA_RECORD_T *prStaRec; -+ TDLS_INFO_LINK_T *prLink; -+ UINT32 u4StartIdx; -+ UINT32 u4PeerNum; -+ BOOLEAN fgIsListAll; -+ UINT8 ucMacZero[6]; -+ UINT32 u4HisIdx; -+ UINT8 ucNetTypeIndex; -+ -+ /* init */ -+ prGlueInfo = prAdapter->prGlueInfo; -+ prCmdContent = (TDLS_CMD_CORE_T *) pvSetBuffer; -+ u4StartIdx = 0; -+ u4PeerNum = 1; -+ fgIsListAll = TRUE; -+ kalMemZero(ucMacZero, sizeof(ucMacZero)); -+ ucNetTypeIndex = NETWORK_TYPE_AIS_INDEX; -+ -+ /* display common information */ -+ DBGLOG(TDLS, TRACE, "TDLS common:\n"); -+ DBGLOG(TDLS, TRACE, "\t\trFreeSwRfbList=%u\n", (UINT32) prAdapter->rRxCtrl.rFreeSwRfbList.u4NumElem); -+ DBGLOG(TDLS, TRACE, "\t\tjiffies=%u %ums (HZ=%d)\n", (UINT32) jiffies, (UINT32) kalGetTimeTick(), HZ); -+ -+ /* display disconnection history information */ -+ DBGLOG(TDLS, TRACE, "TDLS link history: %d\n", prGlueInfo->rTdlsLink.u4LinkIdx); -+ -+ for (u4HisIdx = prGlueInfo->rTdlsLink.u4LinkIdx + 1; u4HisIdx < TDLS_LINK_HISTORY_MAX; u4HisIdx++) { -+ prLink = &prGlueInfo->rTdlsLink.rLinkHistory[u4HisIdx]; -+ -+ if (kalMemCmp(prLink->aucPeerMac, ucMacZero, 6) == 0) -+ continue; /* skip all zero */ -+ -+ DBGLOG(TDLS, TRACE, -+ "\t\t%d. %pM jiffies start(%lu %ums)end(%lu %ums)Reason(%u)fromUs(%u)Dup(%u)HT(%u)\n", -+ u4HisIdx, prLink->aucPeerMac, -+ prLink->jiffies_start, jiffies_to_msecs(prLink->jiffies_start), -+ prLink->jiffies_end, jiffies_to_msecs(prLink->jiffies_end), -+ prLink->ucReasonCode, -+ prLink->fgIsFromUs, prLink->ucDupCount, (prLink->ucHtCap & TDLS_INFO_LINK_HT_CAP_SUP)); -+ -+ if (prLink->ucHtCap & TDLS_INFO_LINK_HT_CAP_SUP) { -+ DBGLOG(TDLS, TRACE, -+ "\t\t\tBA (0x%x %x %x %x %x %x %x %x)\n", -+ prLink->ucHtBa[0], prLink->ucHtBa[1], -+ prLink->ucHtBa[2], prLink->ucHtBa[3], -+ prLink->ucHtBa[4], prLink->ucHtBa[5], prLink->ucHtBa[6], prLink->ucHtBa[7]); -+ } -+ } -+ for (u4HisIdx = 0; u4HisIdx <= prGlueInfo->rTdlsLink.u4LinkIdx; u4HisIdx++) { -+ prLink = &prGlueInfo->rTdlsLink.rLinkHistory[u4HisIdx]; -+ -+ if (kalMemCmp(prLink->aucPeerMac, ucMacZero, 6) == 0) -+ continue; /* skip all zero, use continue, not break */ -+ -+ DBGLOG(TDLS, TRACE, -+ "\t\t%d. %pM jiffies start(%lu %ums)end(%lu %ums)Reason(%u)fromUs(%u)Dup(%u)HT(%u)\n", -+ u4HisIdx, (prLink->aucPeerMac), -+ prLink->jiffies_start, jiffies_to_msecs(prLink->jiffies_start), -+ prLink->jiffies_end, jiffies_to_msecs(prLink->jiffies_end), -+ prLink->ucReasonCode, -+ prLink->fgIsFromUs, prLink->ucDupCount, (prLink->ucHtCap & TDLS_INFO_LINK_HT_CAP_SUP)); -+ -+ if (prLink->ucHtCap & TDLS_INFO_LINK_HT_CAP_SUP) { -+ DBGLOG(TDLS, TRACE, -+ "\t\t\tBA (0x%x %x %x %x %x %x %x %x)\n", -+ prLink->ucHtBa[0], prLink->ucHtBa[1], -+ prLink->ucHtBa[2], prLink->ucHtBa[3], -+ prLink->ucHtBa[4], prLink->ucHtBa[5], prLink->ucHtBa[6], prLink->ucHtBa[7]); -+ } -+ } -+ DBGLOG(TDLS, TRACE, "\n"); -+ -+ /* display link information */ -+ if (prCmdContent != NULL) { -+ if (kalMemCmp(prCmdContent->aucPeerMac, ucMacZero, 6) != 0) { -+ prStaRec = cnmGetStaRecByAddress(prAdapter, -+ prCmdContent->ucNetTypeIndex, prCmdContent->aucPeerMac); -+ if (prStaRec == NULL) -+ fgIsListAll = TRUE; -+ } -+ -+ ucNetTypeIndex = prCmdContent->ucNetTypeIndex; -+ } -+ -+ while (1) { -+ if (fgIsListAll == TRUE) { -+ /* list all TDLS peers */ -+ prStaRec = cnmStaTheTypeGet(prAdapter, ucNetTypeIndex, STA_TYPE_TDLS_PEER, &u4StartIdx); -+ if (prStaRec == NULL) -+ break; -+ } -+ -+ DBGLOG(TDLS, TRACE, "-------- TDLS %d: 0x %pM\n", u4PeerNum, (prStaRec->aucMacAddr)); -+ DBGLOG(TDLS, TRACE, "\t\t\t State %d, PM %d, Cap 0x%x\n", -+ prStaRec->ucStaState, prStaRec->fgIsInPS, prStaRec->u2CapInfo); -+ DBGLOG(TDLS, TRACE, "\t\t\t SetupDisable %d, ChSwDisable %d\n", -+ prStaRec->fgTdlsIsProhibited, prStaRec->fgTdlsIsChSwProhibited); -+ -+ if (fgIsListAll == FALSE) -+ break; /* only list one */ -+ } -+ -+ /* check if we need to clear all histories */ -+ if ((prCmdContent != NULL) && (prCmdContent->Content.rCmdInfoDisplay.fgIsToClearAllHistory == TRUE)) { -+ kalMemZero(&prGlueInfo->rTdlsLink, sizeof(prGlueInfo->rTdlsLink)); -+ prGlueInfo->rTdlsLink.u4LinkIdx = TDLS_LINK_HISTORY_MAX - 1; -+ } -+ -+ DBGLOG(TDLS, INFO, "%s cmd ok.\n", __func__); -+ return TDLS_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to display key information. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set -+* \param[in] u4SetBufferLen The length of the set buffer -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed due to invalid length of -+* the set buffer, returns the amount of storage needed. -+* -+* \retval TDLS_STATUS_xx -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static TDLS_STATUS -+TdlsKeyInfoDisplay(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen) -+{ -+ TDLS_CMD_CORE_T *prCmdContent; -+ WLAN_STATUS rStatus; -+ -+ /* init command buffer */ -+ prCmdContent = (TDLS_CMD_CORE_T *) pvSetBuffer; -+ prCmdContent->u4Command = TDLS_CORE_CMD_KEY_INFO; -+ -+ /* send the command */ -+ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ -+ CMD_ID_TDLS_CORE, /* ucCID */ -+ TRUE, /* fgSetQuery */ -+ FALSE, /* fgNeedResp */ -+ FALSE, /* fgIsOid */ -+ NULL, NULL, /* pfCmdTimeoutHandler */ -+ sizeof(TDLS_CMD_CORE_T), /* u4SetQueryInfoLen */ -+ (PUINT_8) prCmdContent, /* pucInfoBuffer */ -+ NULL, /* pvSetQueryBuffer */ -+ 0 /* u4SetQueryBufferLen */ -+ ); -+ -+ if (rStatus != WLAN_STATUS_PENDING) { -+ DBGLOG(TDLS, ERROR, "%s wlanSendSetQueryCmd allocation fail!\n", __func__); -+ return TDLS_STATUS_RESOURCES; -+ } -+ -+ DBGLOG(TDLS, INFO, "%s cmd ok.\n", __func__); -+ return TDLS_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to record a disconnection event. -+* -+* \param[in] prGlueInfo Pointer to the GLUE_INFO_T structure -+* \param[in] fgIsTearDown TRUE: the link is torn down -+* \param[in] pucPeerMac Pointer to the MAC of the TDLS peer -+* \param[in] fgIsFromUs TRUE: tear down is from us -+* \param[in] u2ReasonCode Disconnection reason (TDLS_REASON_CODE) -+* -+* \retval none -+*/ -+/*----------------------------------------------------------------------------*/ -+static VOID -+TdlsLinkHistoryRecord(GLUE_INFO_T *prGlueInfo, -+ BOOLEAN fgIsTearDown, -+ UINT8 *pucPeerMac, BOOLEAN fgIsFromUs, UINT16 u2ReasonCode, VOID *prOthers) -+{ -+ TDLS_INFO_LINK_T *prLink; -+ -+ DBGLOG(TDLS, INFO, -+ " %s: record history for %pM %d %d %d %d\n", -+ __func__, pucPeerMac, prGlueInfo->rTdlsLink.u4LinkIdx, -+ fgIsTearDown, fgIsFromUs, u2ReasonCode); -+ -+ /* check duplicate one */ -+ if (prGlueInfo->rTdlsLink.u4LinkIdx >= TDLS_LINK_HISTORY_MAX) { -+ DBGLOG(TDLS, ERROR, " %s: u4LinkIdx >= TDLS_LINK_HISTORY_MAX\n", __func__); -+ -+ /* reset to 0 */ -+ prGlueInfo->rTdlsLink.u4LinkIdx = 0; -+ } -+ -+ prLink = &prGlueInfo->rTdlsLink.rLinkHistory[prGlueInfo->rTdlsLink.u4LinkIdx]; -+ -+ if (kalMemCmp(&prLink->aucPeerMac, pucPeerMac, 6) == 0) { -+ if ((prLink->ucReasonCode == u2ReasonCode) && (prLink->fgIsFromUs == fgIsFromUs)) { -+ /* same Peer MAC, Reason Code, Trigger source */ -+ if (fgIsTearDown == TRUE) { -+ if (prLink->jiffies_end != 0) { -+ /* already torn down */ -+ prLink->ucDupCount++; -+ return; -+ } -+ } else { -+ /* already built */ -+ prLink->ucDupCount++; -+ return; -+ } -+ } -+ } -+ -+ /* search old entry */ -+ if (fgIsTearDown == TRUE) { -+ /* TODO: need to search all entries to find it if we support multiple TDLS link design */ -+ if (kalMemCmp(&prLink->aucPeerMac, pucPeerMac, 6) != 0) { -+ /* error! can not find the link entry */ -+ DBGLOG(TDLS, INFO, " %s: cannot find the same entry!!!\n", __func__); -+ return; -+ } -+ -+ prLink->jiffies_end = jiffies; -+ prLink->ucReasonCode = (UINT8) u2ReasonCode; -+ prLink->fgIsFromUs = fgIsFromUs; -+ } else { -+ /* record new one */ -+ prGlueInfo->rTdlsLink.u4LinkIdx++; -+ if (prGlueInfo->rTdlsLink.u4LinkIdx >= TDLS_LINK_HISTORY_MAX) -+ prGlueInfo->rTdlsLink.u4LinkIdx = 0; -+ -+ prLink = &prGlueInfo->rTdlsLink.rLinkHistory[prGlueInfo->rTdlsLink.u4LinkIdx]; -+ -+ prLink->jiffies_start = jiffies; -+ prLink->jiffies_end = 0; -+ kalMemCopy(&prLink->aucPeerMac, pucPeerMac, 6); -+ prLink->ucReasonCode = 0; -+ prLink->fgIsFromUs = (UINT8) fgIsFromUs; -+ prLink->ucDupCount = 0; -+ -+ if (prOthers != NULL) { -+ /* record other parameters */ -+ TDLS_LINK_HIS_OTHERS_T *prHisOthers; -+ -+ prHisOthers = (TDLS_LINK_HIS_OTHERS_T *) prOthers; -+ if (prHisOthers->fgIsHt == TRUE) -+ prLink->ucHtCap |= TDLS_INFO_LINK_HT_CAP_SUP; -+ } -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to update a disconnection event. -+* -+* \param[in] prGlueInfo Pointer to the GLUE_INFO_T structure -+* \param[in] pucPeerMac Pointer to the MAC of the TDLS peer -+* \param[in] eFmeStatus TDLS_EVENT_HOST_SUBID_SPECIFIC_FRAME -+* \param[in] pInfo other information -+* -+* \retval none -+*/ -+/*----------------------------------------------------------------------------*/ -+static VOID -+TdlsLinkHistoryRecordUpdate(GLUE_INFO_T *prGlueInfo, -+ UINT8 *pucPeerMac, TDLS_EVENT_HOST_SUBID_SPECIFIC_FRAME eFmeStatus, VOID *pInfo) -+{ -+ TDLS_INFO_LINK_T *prLink; -+ UINT32 u4LinkIdx; -+ UINT32 u4Tid; -+ -+ /* sanity check */ -+ if ((eFmeStatus < TDLS_HOST_EVENT_SF_BA) || (eFmeStatus > TDLS_HOST_EVENT_SF_BA_RSP_DECLINE)) { -+ /* do not care these frames */ -+ return; -+ } -+ -+ DBGLOG(TDLS, INFO, -+ " %s: update history for %pM %d %d\n", -+ __func__, (pucPeerMac), prGlueInfo->rTdlsLink.u4LinkIdx, eFmeStatus); -+ -+ /* init */ -+ u4LinkIdx = prGlueInfo->rTdlsLink.u4LinkIdx; -+ prLink = &prGlueInfo->rTdlsLink.rLinkHistory[u4LinkIdx]; -+ -+ /* TODO: need to search all entries to find it if we support multiple TDLS link design */ -+ if (kalMemCmp(&prLink->aucPeerMac, pucPeerMac, 6) != 0) { -+ /* error! can not find the link entry */ -+ DBGLOG(TDLS, INFO, " %s: cannot find the same entry!!!\n", __func__); -+ return; -+ } -+ -+ /* update */ -+ u4Tid = *(UINT32 *) pInfo; -+ switch (eFmeStatus) { -+ case TDLS_HOST_EVENT_SF_BA: -+ prLink->ucHtBa[u4Tid] |= TDLS_INFO_LINK_HT_BA_SETUP; -+ break; -+ -+ case TDLS_HOST_EVENT_SF_BA_OK: -+ prLink->ucHtBa[u4Tid] |= TDLS_INFO_LINK_HT_BA_SETUP_OK; -+ break; -+ -+ case TDLS_HOST_EVENT_SF_BA_DECLINE: -+ prLink->ucHtBa[u4Tid] |= TDLS_INFO_LINK_HT_BA_SETUP_DECLINE; -+ break; -+ -+ case TDLS_HOST_EVENT_SF_BA_PEER: -+ prLink->ucHtBa[u4Tid] |= TDLS_INFO_LINK_HT_BA_PEER; -+ break; -+ -+ case TDLS_HOST_EVENT_SF_BA_RSP_OK: -+ prLink->ucHtBa[u4Tid] |= TDLS_INFO_LINK_HT_BA_RSP_OK; -+ break; -+ -+ case TDLS_HOST_EVENT_SF_BA_RSP_DECLINE: -+ prLink->ucHtBa[u4Tid] |= TDLS_INFO_LINK_HT_BA_RSP_DECLINE; -+ break; -+ } -+ -+ /* display TDLS link history */ -+ TdlsInfoDisplay(prGlueInfo->prAdapter, NULL, 0, NULL); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to configure TDLS MIB parameters. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set -+* \param[in] u4SetBufferLen The length of the set buffer -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed due to invalid length of -+* the set buffer, returns the amount of storage needed. -+* -+* \retval TDLS_STATUS_xx -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static TDLS_STATUS -+TdlsMibParamUpdate(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen) -+{ -+ TDLS_CMD_CORE_T *prCmdContent; -+ WLAN_STATUS rStatus; -+ -+ /* init command buffer */ -+ prCmdContent = (TDLS_CMD_CORE_T *) pvSetBuffer; -+ prCmdContent->u4Command = TDLS_CORE_CMD_MIB_UPDATE; -+ -+ /* send the command */ -+ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ -+ CMD_ID_TDLS_CORE, /* ucCID */ -+ TRUE, /* fgSetQuery */ -+ FALSE, /* fgNeedResp */ -+ FALSE, /* fgIsOid */ -+ NULL, NULL, /* pfCmdTimeoutHandler */ -+ sizeof(TDLS_CMD_CORE_T), /* u4SetQueryInfoLen */ -+ (PUINT_8) prCmdContent, /* pucInfoBuffer */ -+ NULL, /* pvSetQueryBuffer */ -+ 0 /* u4SetQueryBufferLen */ -+ ); -+ -+ if (rStatus != WLAN_STATUS_PENDING) { -+ DBGLOG(TDLS, ERROR, "%s wlanSendSetQueryCmd allocation fail!\n", __func__); -+ return TDLS_STATUS_RESOURCES; -+ } -+ -+ DBGLOG(TDLS, INFO, "%s cmd ok.\n", __func__); -+ return TDLS_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to configure TDLS SETUP parameters. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set -+* \param[in] u4SetBufferLen The length of the set buffer -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed due to invalid length of -+* the set buffer, returns the amount of storage needed. -+* -+* \retval TDLS_STATUS_xx -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static TDLS_STATUS -+TdlsSetupConf(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen) -+{ -+ TDLS_CMD_CORE_T *prCmdContent; -+ WLAN_STATUS rStatus; -+ -+ /* init command buffer */ -+ prCmdContent = (TDLS_CMD_CORE_T *) pvSetBuffer; -+ prCmdContent->u4Command = TDLS_CORE_CMD_SETUP_CONF; -+ -+ /* send the command */ -+ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ -+ CMD_ID_TDLS_CORE, /* ucCID */ -+ TRUE, /* fgSetQuery */ -+ FALSE, /* fgNeedResp */ -+ FALSE, /* fgIsOid */ -+ NULL, NULL, /* pfCmdTimeoutHandler */ -+ sizeof(TDLS_CMD_CORE_T), /* u4SetQueryInfoLen */ -+ (PUINT_8) prCmdContent, /* pucInfoBuffer */ -+ NULL, /* pvSetQueryBuffer */ -+ 0 /* u4SetQueryBufferLen */ -+ ); -+ -+ if (rStatus != WLAN_STATUS_PENDING) { -+ DBGLOG(TDLS, ERROR, "%s wlanSendSetQueryCmd allocation fail!\n", __func__); -+ return TDLS_STATUS_RESOURCES; -+ } -+ -+ DBGLOG(TDLS, INFO, "%s cmd ok.\n", __func__); -+ return TDLS_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to configure UAPSD parameters. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set -+* \param[in] u4SetBufferLen The length of the set buffer -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed due to invalid length of -+* the set buffer, returns the amount of storage needed. -+* -+* \retval TDLS_STATUS_xx -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static TDLS_STATUS -+TdlsUapsdConf(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen) -+{ -+ TDLS_CMD_CORE_T *prCmdContent; -+ WLAN_STATUS rStatus; -+ -+ /* init command buffer */ -+ prCmdContent = (TDLS_CMD_CORE_T *) pvSetBuffer; -+ prCmdContent->u4Command = TDLS_CORE_CMD_UAPSD_CONF; -+ -+ /* send the command */ -+ rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */ -+ CMD_ID_TDLS_CORE, /* ucCID */ -+ TRUE, /* fgSetQuery */ -+ FALSE, /* fgNeedResp */ -+ FALSE, /* fgIsOid */ -+ NULL, NULL, /* pfCmdTimeoutHandler */ -+ sizeof(TDLS_CMD_CORE_T), /* u4SetQueryInfoLen */ -+ (PUINT_8) prCmdContent, /* pucInfoBuffer */ -+ NULL, /* pvSetQueryBuffer */ -+ 0 /* u4SetQueryBufferLen */ -+ ); -+ -+ if (rStatus != WLAN_STATUS_PENDING) { -+ DBGLOG(TDLS, ERROR, "%s wlanSendSetQueryCmd allocation fail!\n", __func__); -+ return TDLS_STATUS_RESOURCES; -+ } -+ -+ DBGLOG(TDLS, INFO, "%s cmd ok.\n", __func__); -+ return TDLS_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to update frame status. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prInBuf A pointer to the command string buffer, from u4EventSubId -+* \param[in] u4InBufLen The length of the buffer -+* \param[out] None -+* -+* \retval None -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static void TdlsEventFmeStatus(GLUE_INFO_T *prGlueInfo, UINT8 *prInBuf, UINT32 u4InBufLen) -+{ -+ TDLS_EVENT_HOST_SUBID_SPECIFIC_FRAME eFmeStatus; -+ STA_RECORD_T *prStaRec; -+ UINT32 u4Tid; -+ -+ /* init */ -+ u4Tid = *(UINT32 *) prInBuf; -+ prInBuf += 4; /* skip u4EventSubId */ -+ -+ /* sanity check */ -+ prStaRec = cnmGetStaRecByIndex(prGlueInfo->prAdapter, *prInBuf); -+ if ((prStaRec == NULL) || (!IS_TDLS_STA(prStaRec))) -+ return; -+ prInBuf++; -+ -+ /* update status */ -+ eFmeStatus = *prInBuf; -+ TdlsLinkHistoryRecordUpdate(prGlueInfo, prStaRec->aucMacAddr, eFmeStatus, &u4Tid); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to collect TDLS statistics from firmware. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prInBuf A pointer to the command string buffer, from u4EventSubId -+* \param[in] u4InBufLen The length of the buffer -+* \param[out] None -+* -+* \retval None -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static void TdlsEventStatistics(GLUE_INFO_T *prGlueInfo, UINT8 *prInBuf, UINT32 u4InBufLen) -+{ -+ STA_RECORD_T *prStaRec; -+ STAT_CNT_INFO_FW_T *prStat; -+ UINT32 u4RateId; -+ -+ /* init */ -+ prStaRec = cnmGetStaRecByIndex(prGlueInfo->prAdapter, *prInBuf); -+ if ((prStaRec == NULL) || (!IS_TDLS_STA(prStaRec))) -+ return; -+ -+ prInBuf += 4; /* skip prStaRec->ucIndex */ -+ -+ /* update statistics */ -+ kalMemCopy(&prStaRec->rTdlsStatistics.rFw, prInBuf, sizeof(prStaRec->rTdlsStatistics.rFw)); -+ -+ /* display statistics */ -+ prStat = &prStaRec->rTdlsStatistics.rFw; -+ -+ DBGLOG(TDLS, TRACE, " peer [%pM] statistics:\n", (prStaRec->aucMacAddr)); -+ DBGLOG(TDLS, TRACE, "\t\tT%d %d %d (P%d %d) (%dus) - E%d 0x%x - R%d (P%d)\n", -+ prStat->u4NumOfTx, prStat->u4NumOfTxOK, prStat->u4NumOfTxRetry, -+ prStat->u4NumOfPtiRspTxOk, prStat->u4NumOfPtiRspTxErr, -+ prStat->u4TxDoneAirTimeMax, -+ prStat->u4NumOfTxErr, prStat->u4TxErrBitmap, prStat->u4NumOfRx, prStat->u4NumOfPtiRspRx); -+ -+ DBGLOG(TDLS, TRACE, "\t\t"); -+ -+ for (u4RateId = prStat->u4TxRateOkHisId; u4RateId < STAT_CNT_INFO_MAX_TX_RATE_OK_HIS_NUM; u4RateId++) -+ DBGLOG(TDLS, TRACE, -+ "%d(%d) ", prStat->aucTxRateOkHis[u4RateId][0], prStat->aucTxRateOkHis[u4RateId][1]); -+ for (u4RateId = 0; u4RateId < prStat->u4TxRateOkHisId; u4RateId++) -+ DBGLOG(TDLS, TRACE, -+ "%d(%d) ", prStat->aucTxRateOkHis[u4RateId][0], prStat->aucTxRateOkHis[u4RateId][1]); -+ -+ DBGLOG(TDLS, TRACE, "\n\n"); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to do tear down. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prInBuf A pointer to the command string buffer, from u4EventSubId -+* \param[in] u4InBufLen The length of the buffer -+* \param[out] None -+* -+* \retval None -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static void TdlsEventTearDown(GLUE_INFO_T *prGlueInfo, UINT8 *prInBuf, UINT32 u4InBufLen) -+{ -+ STA_RECORD_T *prStaRec; -+ UINT16 u2ReasonCode; -+ UINT32 u4TearDownSubId; -+ UINT8 *pMac, aucZeroMac[6]; -+ -+ /* init */ -+ u4TearDownSubId = *(UINT32 *) prInBuf; -+ kalMemZero(aucZeroMac, sizeof(aucZeroMac)); -+ pMac = aucZeroMac; -+ -+ prStaRec = cnmGetStaRecByIndex(prGlueInfo->prAdapter, *(prInBuf + 4)); -+ if (prStaRec != NULL) -+ pMac = prStaRec->aucMacAddr; -+ -+ /* handle */ -+ if (u4TearDownSubId == TDLS_HOST_EVENT_TD_PTI_TIMEOUT) { -+ DBGLOG(TDLS, WARN, " %s: peer [%pM] Reason=PTI timeout\n", -+ __func__, pMac); -+ } else if (u4TearDownSubId == TDLS_HOST_EVENT_TD_AGE_TIMEOUT) { -+ DBGLOG(TDLS, WARN, " %s: peer [%pM] Reason=AGE timeout\n", -+ __func__, pMac); -+ } else { -+ DBGLOG(TDLS, WARN, " %s: peer [%pM] Reason=%d\n", -+ __func__, pMac, u4TearDownSubId); -+ } -+ -+ /* sanity check */ -+ if (prStaRec == NULL) -+ return; -+ -+ if (fgIsPtiTimeoutSkip == TRUE) { -+ /* skip PTI timeout event */ -+ if (u4TearDownSubId == TDLS_HOST_EVENT_TD_PTI_TIMEOUT) { -+ DBGLOG(TDLS, WARN, " %s: skip PTI timeout\n", __func__); -+ return; -+ } -+ } -+ -+ /* record history */ -+ if (u4TearDownSubId == TDLS_HOST_EVENT_TD_AGE_TIMEOUT) -+ u2ReasonCode = TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_AGE_TIMEOUT; -+ else if (u4TearDownSubId == TDLS_HOST_EVENT_TD_PTI_TIMEOUT) -+ u2ReasonCode = TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_PTI_TIMEOUT; -+ else if (u4TearDownSubId == TDLS_HOST_EVENT_TD_PTI_SEND_FAIL) -+ u2ReasonCode = TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_PTI_SEND_FAIL; -+ else if (u4TearDownSubId == TDLS_HOST_EVENT_TD_PTI_SEND_MAX_FAIL) -+ u2ReasonCode = TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_PTI_SEND_MAX_FAIL; -+ else if (u4TearDownSubId == TDLS_HOST_EVENT_TD_WRONG_NETWORK_IDX) -+ u2ReasonCode = TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_WRONG_NETWORK_IDX; -+ else if (u4TearDownSubId == TDLS_HOST_EVENT_TD_NON_STATE3) -+ u2ReasonCode = TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_NON_STATE3; -+ else if (u4TearDownSubId == TDLS_HOST_EVENT_TD_LOST_TEAR_DOWN) -+ u2ReasonCode = TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_LOST_TEAR_DOWN; -+ else { -+ /* shall not be here */ -+ u2ReasonCode = TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_UNKNOWN; -+ } -+ -+ TdlsLinkHistoryRecord(prGlueInfo, TRUE, prStaRec->aucMacAddr, TRUE, u2ReasonCode, NULL); -+ -+ /* correct correct reason code for PTI or AGE timeout to supplicant */ -+ if ((u2ReasonCode == TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_AGE_TIMEOUT) || -+ (u2ReasonCode == TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_PTI_TIMEOUT)) { -+ u2ReasonCode = TDLS_REASON_CODE_UNREACHABLE; -+ } -+ -+ /* 16 Nov 21:49 2012 http://permalink.gmane.org/gmane.linux.kernel.wireless.general/99712 */ -+ cfg80211_tdls_oper_request(prGlueInfo->prDevHandler, -+ prStaRec->aucMacAddr, NL80211_TDLS_TEARDOWN, u2ReasonCode, GFP_ATOMIC); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to do tx down. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prInBuf A pointer to the command string buffer, from u4EventSubId -+* \param[in] u4InBufLen The length of the buffer -+* \param[out] None -+* -+* \retval None -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static void TdlsEventTxDone(GLUE_INFO_T *prGlueInfo, UINT8 *prInBuf, UINT32 u4InBufLen) -+{ -+ /* UINT32 u4FmeIdx; */ -+ UINT8 *pucFmeHdr; -+ UINT8 ucErrStatus; -+ -+ ucErrStatus = *(UINT32 *) prInBuf; -+ -+ pucFmeHdr = prInBuf + 4; /* skip ucErrStatus */ -+ -+ if (ucErrStatus == 0) -+ DBGLOG(TDLS, TRACE, " %s: OK to tx a TDLS action:", __func__); -+ else -+ DBGLOG(TDLS, TRACE, " %s: fail to tx a TDLS action (err=0x%x):", __func__, ucErrStatus); -+ #if 0 -+ /* dump TX packet content from wlan header */ -+ for (u4FmeIdx = 0; u4FmeIdx < (u4InBufLen - 4); u4FmeIdx++) { -+ if ((u4FmeIdx % 16) == 0) -+ DBGLOG(TDLS, TRACE, "\n"); -+ -+ DBGLOG(TDLS, TRACE, "%02x ", *pucFmeHdr++); -+ } -+ DBGLOG(TDLS, TRACE, "\n\n"); -+ #endif -+} -+ -+/******************************************************************************* -+* P U B L I C F U N C T I O N S -+******************************************************************************** -+*/ -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to parse TDLS Extended Capabilities element. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prInBuf A pointer to the command string buffer -+* \param[in] u4InBufLen The length of the buffer -+* \param[out] None -+* -+* \retval None -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID TdlsexBssExtCapParse(STA_RECORD_T *prStaRec, UINT_8 *pucIE) -+{ -+ UINT_8 *pucIeExtCap; -+ -+ /* sanity check */ -+ if ((prStaRec == NULL) || (pucIE == NULL)) -+ return; -+ -+ if (IE_ID(pucIE) != ELEM_ID_EXTENDED_CAP) -+ return; -+ -+ /* -+ from bit0 ~ -+ -+ bit 38: TDLS Prohibited -+ The TDLS Prohibited subfield indicates whether the use of TDLS is prohibited. The -+ field is set to 1 to indicate that TDLS is prohibited and to 0 to indicate that TDLS is -+ allowed. -+ */ -+ if (IE_LEN(pucIE) < 5) -+ return; /* we need 39/8 = 5 bytes */ -+ -+ /* init */ -+ prStaRec->fgTdlsIsProhibited = FALSE; -+ prStaRec->fgTdlsIsChSwProhibited = FALSE; -+ -+ /* parse */ -+ pucIeExtCap = pucIE + 2; -+ pucIeExtCap += 4; /* shift to the byte we care about */ -+ -+ if ((*pucIeExtCap) & BIT(38 - 32)) -+ prStaRec->fgTdlsIsProhibited = TRUE; -+ if ((*pucIeExtCap) & BIT(39 - 32)) -+ prStaRec->fgTdlsIsChSwProhibited = TRUE; -+ -+ DBGLOG(TDLS, TRACE, -+ " %s: AP [%pM] tdls prohibit bit=%d %d\n", -+ __func__, -+ prStaRec->aucMacAddr, prStaRec->fgTdlsIsProhibited, prStaRec->fgTdlsIsChSwProhibited); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to transmit a TDLS data frame from nl80211. -+* -+* \param[in] pvAdapter Pointer to the Adapter structure. -+* \param[in] -+* \param[in] -+* \param[in] buf includes RSN IE + FT IE + Lifetimeout IE -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+int -+TdlsexCfg80211TdlsMgmt(struct wiphy *wiphy, struct net_device *dev, -+ const u8 *peer, u8 action_code, u8 dialog_token, -+ u16 status_code, u32 peer_capability, -+ bool initiator, const u8 *buf, size_t len) -+{ -+ ADAPTER_T *prAdapter; -+ GLUE_INFO_T *prGlueInfo; -+ BSS_INFO_T *prAisBssInfo; -+ WLAN_STATUS rStatus; -+ UINT_32 u4BufLen; -+ TDLS_MGMT_TX_INFO *prMgmtTxInfo; -+ -+ /* -+ Have correct behavior for STAUT receiving TDLS Setup Request after sending TDLS -+ Set Request and before receiving TDLS Setup Response: -+ -- Source Address of received Request is higher than own MAC address -+ -- Source Address of received Request is lower than own MAC address -+ -+ ==> STA with larger MAC address will send the response frame. -+ -+ Supplicant will do this in wpa_tdls_process_tpk_m1(). -+ */ -+ -+ /* sanity check */ -+ if ((wiphy == NULL) || (peer == NULL)) { -+ DBGLOG(TDLS, ERROR, " %s: wrong 0x%p 0x%p!\n", __func__, wiphy, peer); -+ return -EINVAL; -+ } -+ -+ DBGLOG(TDLS, INFO, " %s: [%pM] %d %d %d 0x%p %u\n", -+ __func__, peer, action_code, dialog_token, status_code, buf, (UINT32) len); -+ -+ /* init */ -+ prGlueInfo = (GLUE_INFO_T *) wiphy_priv(wiphy); -+ if (prGlueInfo == NULL) { -+ DBGLOG(TDLS, ERROR, " %s: wrong prGlueInfo 0x%p!\n", __func__, prGlueInfo); -+ return -EINVAL; -+ } -+ -+ prAdapter = prGlueInfo->prAdapter; -+ if (prAdapter->fgTdlsIsSup == FALSE) { -+ DBGLOG(TDLS, ERROR, " %s: firmware TDLS is not supported!\n", __func__); -+ return -EBUSY; -+ } -+ -+ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ if (prAisBssInfo->fgTdlsIsProhibited == TRUE) { -+ /* do not send anything if TDLS is prohibited in the BSS */ -+ return 0; -+ } -+ -+ prMgmtTxInfo = kalMemAlloc(sizeof(TDLS_MGMT_TX_INFO), VIR_MEM_TYPE); -+ if (prMgmtTxInfo == NULL) { -+ DBGLOG(TDLS, ERROR, " %s: allocate fail!\n", __func__); -+ return -ENOMEM; -+ } -+ -+ kalMemZero(prMgmtTxInfo, sizeof(TDLS_MGMT_TX_INFO)); -+ -+ if (peer != NULL) -+ kalMemCopy(prMgmtTxInfo->aucPeer, peer, 6); -+ prMgmtTxInfo->ucActionCode = action_code; -+ prMgmtTxInfo->ucDialogToken = dialog_token; -+ prMgmtTxInfo->u2StatusCode = status_code; -+ -+ if (buf != NULL) { -+ if (len > sizeof(prMgmtTxInfo->aucSecBuf)) { -+ kalMemFree(prMgmtTxInfo, VIR_MEM_TYPE, sizeof(TDLS_MGMT_TX_INFO)); -+ return -EINVAL; -+ } -+ prMgmtTxInfo->u4SecBufLen = len; -+ kalMemCopy(prMgmtTxInfo->aucSecBuf, buf, len); -+ } -+ -+ /* send the TDLS action data frame */ -+ rStatus = kalIoctl(prGlueInfo, -+ TdlsexMgmtCtrl, -+ prMgmtTxInfo, sizeof(TDLS_MGMT_TX_INFO), FALSE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ /* -+ clear all content to avoid any bug if we dont yet execute TdlsexMgmtCtrl() -+ then kalIoctl finishes -+ */ -+ kalMemZero(prMgmtTxInfo, sizeof(TDLS_MGMT_TX_INFO)); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ DBGLOG(TDLS, ERROR, "%s enable or disable link fail:%x\n", __func__, rStatus); -+ kalMemFree(prMgmtTxInfo, VIR_MEM_TYPE, sizeof(TDLS_MGMT_TX_INFO)); -+ return -EINVAL; -+ } -+ -+ kalMemFree(prMgmtTxInfo, VIR_MEM_TYPE, sizeof(TDLS_MGMT_TX_INFO)); -+ return 0; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to enable or disable TDLS link from upper layer. -+* -+* \param[in] pvAdapter Pointer to the Adapter structure. -+* \param[in] -+* \param[in] -+* \param[in] buf includes RSN IE + FT IE + Lifetimeout IE -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+int TdlsexCfg80211TdlsOper(struct wiphy *wiphy, struct net_device *dev, -+ const u8 *peer, enum nl80211_tdls_operation oper) -+{ -+ ADAPTER_T *prAdapter; -+ GLUE_INFO_T *prGlueInfo; -+ WLAN_STATUS rStatus; -+ UINT_32 u4BufLen; -+ TDLS_CMD_LINK_T rCmdLink; -+ -+ /* sanity check */ -+ if (peer == NULL) { -+ DBGLOG(TDLS, ERROR, " %s: peer == NULL!\n", __func__); -+ return -EINVAL; -+ } -+ -+ DBGLOG(TDLS, INFO, " %s: [%pM] %d %d\n", -+ __func__, peer, oper, (wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS)); -+ -+ if (!(wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS)) -+ return -ENOTSUPP; -+ -+ /* init */ -+ prGlueInfo = (GLUE_INFO_T *) wiphy_priv(wiphy); -+ if (prGlueInfo == NULL) { -+ DBGLOG(TDLS, ERROR, " %s: wrong prGlueInfo 0x%p!\n", __func__, prGlueInfo); -+ return -EINVAL; -+ } -+ prAdapter = prGlueInfo->prAdapter; -+ kalMemCopy(rCmdLink.aucPeerMac, peer, sizeof(rCmdLink.aucPeerMac)); -+ rCmdLink.fgIsEnabled = FALSE; -+ -+ /* -+ enum nl80211_tdls_operation { -+ NL80211_TDLS_DISCOVERY_REQ, -+ NL80211_TDLS_SETUP, -+ NL80211_TDLS_TEARDOWN, -+ NL80211_TDLS_ENABLE_LINK, -+ NL80211_TDLS_DISABLE_LINK, -+ }; -+ */ -+ -+ switch (oper) { -+ case NL80211_TDLS_ENABLE_LINK: -+ rCmdLink.fgIsEnabled = TRUE; -+ break; -+ -+ case NL80211_TDLS_DISABLE_LINK: -+ rCmdLink.fgIsEnabled = FALSE; -+ break; -+ -+ case NL80211_TDLS_TEARDOWN: -+ case NL80211_TDLS_SETUP: -+ case NL80211_TDLS_DISCOVERY_REQ: -+ /* we do not support setup/teardown/discovery from driver */ -+ return -ENOTSUPP; -+ -+ default: -+ return -ENOTSUPP; -+ } -+ -+ /* enable or disable TDLS link */ -+ rStatus = kalIoctl(prGlueInfo, -+ TdlsexLinkCtrl, &rCmdLink, sizeof(TDLS_CMD_LINK_T), FALSE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ DBGLOG(TDLS, ERROR, "%s enable or disable link fail:%x\n", __func__, rStatus); -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to send a command to TDLS module. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prInBuf A pointer to the command string buffer -+* \param[in] u4InBufLen The length of the buffer -+* \param[out] None -+* -+* \retval None -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID TdlsexCmd(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen) -+{ -+ UINT_32 u4Subcmd; -+ static void (*TdlsCmdTestFunc)(P_GLUE_INFO_T, UINT_8 *, UINT_32); -+ -+ /* parse TDLS sub-command */ -+ u4Subcmd = CmdStringDecParse(prInBuf, &prInBuf, &u4InBufLen); -+ DBGLOG(TDLS, INFO, " sub command = %u\n", (UINT32) u4Subcmd); -+ TdlsCmdTestFunc = NULL; -+ -+ /* handle different sub-command */ -+ switch (u4Subcmd) { -+#if TDLS_CFG_CMD_TEST /* only for unit test */ -+ case TDLS_CMD_TEST_TX_FRAME: -+ /* simulate to send a TDLS frame */ -+ /* TdlsCmdTestTxFrame(prGlueInfo, prInBuf, u4InBufLen); */ -+ TdlsCmdTestFunc = TdlsCmdTestTxFrame; -+ break; -+ -+ case TDLS_CMD_TEST_TX_TDLS_FRAME: -+ /* simulate to send a TDLS frame from supplicant */ -+ /* TdlsCmdTestTxTdlsFrame(prGlueInfo, prInBuf, u4InBufLen); */ -+ TdlsCmdTestFunc = TdlsCmdTestTxTdlsFrame; -+ break; -+ -+ case TDLS_CMD_TEST_RCV_FRAME: -+ /* simulate to receive a TDLS frame */ -+ /* TdlsCmdTestRvFrame(prGlueInfo, prInBuf, u4InBufLen); */ -+ TdlsCmdTestFunc = TdlsCmdTestRvFrame; -+ break; -+ -+ case TDLS_CMD_TEST_PEER_ADD: -+ /* simulate to add a TDLS peer */ -+ /* TdlsCmdTestAddPeer(prGlueInfo, prInBuf, u4InBufLen); */ -+ TdlsCmdTestFunc = TdlsCmdTestAddPeer; -+ break; -+ -+ case TDLS_CMD_TEST_PEER_UPDATE: -+ /* simulate to update a TDLS peer */ -+ /* TdlsCmdTestUpdatePeer(prGlueInfo, prInBuf, u4InBufLen); */ -+ TdlsCmdTestFunc = TdlsCmdTestUpdatePeer; -+ break; -+ -+ case TDLS_CMD_TEST_DATA_FRAME: -+ /* simulate to send a data frame to the peer */ -+ /* TdlsCmdTestDataSend(prGlueInfo, prInBuf, u4InBufLen); */ -+ TdlsCmdTestFunc = TdlsCmdTestDataSend; -+ break; -+ -+ case TDLS_CMD_TEST_RCV_NULL: -+ /* simulate to receive a QoS null frame from the peer */ -+ /* TdlsCmdTestNullRecv(prGlueInfo, prInBuf, u4InBufLen); */ -+ TdlsCmdTestFunc = TdlsCmdTestNullRecv; -+ break; -+ -+ case TDLS_CMD_TEST_SKIP_TX_FAIL: -+ /* command firmware to skip tx fail case */ -+ /* TdlsCmdTestTxFailSkip(prGlueInfo, prInBuf, u4InBufLen); */ -+ TdlsCmdTestFunc = TdlsCmdTestTxFailSkip; -+ break; -+ -+ case TDLS_CMD_TEST_SKIP_KEEP_ALIVE: -+ /* command firmware to skip keep alive function */ -+ /* TdlsCmdTestKeepAliveSkip(prGlueInfo, prInBuf, u4InBufLen); */ -+ TdlsCmdTestFunc = TdlsCmdTestKeepAliveSkip; -+ break; -+ -+ case TDLS_CMD_TEST_SKIP_CHSW_TIMEOUT: -+ /* command firmware to skip channel switch timeout function */ -+ /* TdlsCmdTestChSwTimeoutSkip(prGlueInfo, prInBuf, u4InBufLen); */ -+ TdlsCmdTestFunc = TdlsCmdTestChSwTimeoutSkip; -+ break; -+ -+ case TDLS_CMD_TEST_PROHIBIT_SET_IN_AP: -+ /* simulate to set Prohibited Bit in AP */ -+ /* TdlsCmdTestProhibitedBitSet(prGlueInfo, prInBuf, u4InBufLen); */ -+ TdlsCmdTestFunc = TdlsCmdTestProhibitedBitSet; -+ break; -+ -+ case TDLS_CMD_TEST_SCAN_DISABLE: -+ /* command to disable scan request to do channel switch */ -+ /* TdlsCmdTestScanCtrl(prGlueInfo, prInBuf, u4InBufLen); */ -+ TdlsCmdTestFunc = TdlsCmdTestScanCtrl; -+ break; -+ -+ case TDLS_CMD_TEST_DATA_FRAME_CONT: -+ /* simulate to send a data frame to the peer periodically */ -+ /* TdlsCmdTestDataContSend(prGlueInfo, prInBuf, u4InBufLen); */ -+ TdlsCmdTestFunc = TdlsCmdTestDataContSend; -+ break; -+ -+ case TDLS_CMD_TEST_CH_SW_PROHIBIT_SET_IN_AP: -+ /* simulate to set channel switch Prohibited Bit in AP */ -+ /* TdlsCmdTestChSwProhibitedBitSet(prGlueInfo, prInBuf, u4InBufLen); */ -+ TdlsCmdTestFunc = TdlsCmdTestChSwProhibitedBitSet; -+ break; -+ -+ case TDLS_CMD_TEST_DELAY: -+ /* delay a where */ -+ /* TdlsCmdTestDelay(prGlueInfo, prInBuf, u4InBufLen); */ -+ TdlsCmdTestFunc = TdlsCmdTestDelay; -+ break; -+ -+ case TDLS_CMD_TEST_PTI_TX_FAIL: -+ /* simulate the tx done fail for PTI */ -+ /* TdlsCmdTestPtiTxDoneFail(prGlueInfo, prInBuf, u4InBufLen); */ -+ TdlsCmdTestFunc = TdlsCmdTestPtiTxDoneFail; -+ break; -+#endif /* TDLS_CFG_CMD_TEST */ -+ -+ case TDLS_CMD_MIB_UPDATE: -+ /* update MIB parameters */ -+ /* TdlsCmdMibParamUpdate(prGlueInfo, prInBuf, u4InBufLen); */ -+ TdlsCmdTestFunc = TdlsCmdMibParamUpdate; -+ break; -+ -+ case TDLS_CMD_UAPSD_CONF: -+ /* config UAPSD parameters */ -+ /* TdlsCmdUapsdConf(prGlueInfo, prInBuf, u4InBufLen); */ -+ TdlsCmdTestFunc = TdlsCmdUapsdConf; -+ break; -+ -+ case TDLS_CMD_CH_SW_CONF: -+ /* enable or disable or start or stop channel switch function */ -+ /* TdlsCmdChSwConf(prGlueInfo, prInBuf, u4InBufLen); */ -+ TdlsCmdTestFunc = TdlsCmdChSwConf; -+ break; -+ -+ case TDLS_CMD_SETUP_CONF: -+ /* config setup parameters */ -+ /* TdlsCmdSetupConf(prGlueInfo, prInBuf, u4InBufLen); */ -+ TdlsCmdTestFunc = TdlsCmdSetupConf; -+ break; -+ -+ case TDLS_CMD_INFO: -+ /* display all TDLS information */ -+ /* TdlsCmdInfoDisplay(prGlueInfo, prInBuf, u4InBufLen); */ -+ TdlsCmdTestFunc = TdlsCmdInfoDisplay; -+ break; -+ -+ case TDLS_CMD_KEY_INFO: -+ /* display key information */ -+ /* TdlsCmdKeyInfoDisplay(prGlueInfo, prInBuf, u4InBufLen); */ -+ TdlsCmdTestFunc = TdlsCmdKeyInfoDisplay; -+ break; -+ -+ default: -+ break; -+ } -+ -+ if (TdlsCmdTestFunc != NULL) -+ TdlsCmdTestFunc(prGlueInfo, prInBuf, u4InBufLen); -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to record a disconnection event. -+* -+* \param[in] prGlueInfo Pointer to the GLUE_INFO_T structure -+* \param[in] fgIsTearDown TRUE: tear down -+* \param[in] pucPeerMac Pointer to the MAC of the TDLS peer -+* \param[in] fgIsFromUs TRUE: tear down is from us -+* \param[in] u2ReasonCode Disconnection reason (TDLS_REASON_CODE) -+* -+* \retval none -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+TdlsexLinkHistoryRecord(GLUE_INFO_T *prGlueInfo, -+ BOOLEAN fgIsTearDown, UINT8 *pucPeerMac, BOOLEAN fgIsFromUs, UINT16 u2ReasonCode) -+{ -+ /* sanity check */ -+ if ((prGlueInfo == NULL) || (pucPeerMac == NULL)) -+ return; -+ -+ DBGLOG(TDLS, INFO, -+ " %s: Rcv a inform from %pM %d %d\n", -+ __func__, pucPeerMac, fgIsFromUs, u2ReasonCode); -+ -+ /* record */ -+ TdlsLinkHistoryRecord(prGlueInfo, fgIsTearDown, pucPeerMac, fgIsFromUs, u2ReasonCode, NULL); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to send a command to TDLS module. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prInBuf A pointer to the command string buffer -+* \param[in] u4InBufLen The length of the buffer -+* \param[out] None -+* -+* \retval None -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID TdlsexEventHandle(GLUE_INFO_T *prGlueInfo, UINT8 *prInBuf, UINT32 u4InBufLen) -+{ -+ UINT32 u4EventId; -+ -+ /* sanity check */ -+ if ((prGlueInfo == NULL) || (prInBuf == NULL)) -+ return; /* shall not be here */ -+ -+ /* handle */ -+ u4EventId = *(UINT32 *) prInBuf; -+ u4InBufLen -= 4; -+ -+ DBGLOG(TDLS, INFO, " %s: Rcv a event: %d\n", __func__, u4EventId); -+ -+ switch (u4EventId) { -+ case TDLS_HOST_EVENT_TEAR_DOWN: -+ TdlsEventTearDown(prGlueInfo, prInBuf + 4, u4InBufLen); -+ break; -+ -+ case TDLS_HOST_EVENT_TX_DONE: -+ TdlsEventTxDone(prGlueInfo, prInBuf + 4, u4InBufLen); -+ break; -+ -+ case TDLS_HOST_EVENT_FME_STATUS: -+ TdlsEventFmeStatus(prGlueInfo, prInBuf + 4, u4InBufLen); -+ break; -+ -+ case TDLS_HOST_EVENT_STATISTICS: -+ TdlsEventStatistics(prGlueInfo, prInBuf + 4, u4InBufLen); -+ break; -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is used to initialize variables in TDLS. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* -+* @return TDLS_STATUS_SUCCESS: do not set key and key infor. is queued -+ TDLS_STATUS_FAILURE: set key -+*/ -+/*----------------------------------------------------------------------------*/ -+TDLS_STATUS TdlsexKeyHandle(ADAPTER_T *prAdapter, PARAM_KEY_T *prNewKey) -+{ -+ STA_RECORD_T *prStaRec; -+ -+ /* sanity check */ -+ if ((prAdapter == NULL) || (prNewKey == NULL)) -+ return TDLS_STATUS_FAILURE; -+ -+ /* -+ supplicant will set key before updating station & enabling the link so we need to -+ backup the key information and set key when link is enabled -+ */ -+ prStaRec = cnmGetStaRecByAddress(prAdapter, NETWORK_TYPE_AIS_INDEX, prNewKey->arBSSID); -+ if ((prStaRec != NULL) && IS_TDLS_STA(prStaRec)) { -+ DBGLOG(TDLS, TRACE, " %s: [%pM] queue key (len=%d) until link is enabled\n", -+ __func__, prNewKey->arBSSID, (UINT32) prNewKey->u4KeyLength); -+ -+ if (prStaRec->ucStaState == STA_STATE_3) { -+ DBGLOG(TDLS, TRACE, " %s: [%pM] tear down the link due to STA_STATE_3\n", -+ __func__, prNewKey->arBSSID); -+ -+ /* re-key */ -+ TdlsLinkHistoryRecord(prAdapter->prGlueInfo, TRUE, -+ prStaRec->aucMacAddr, TRUE, -+ TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_REKEY, NULL); -+ -+ /* 16 Nov 21:49 2012 http://permalink.gmane.org/gmane.linux.kernel.wireless.general/99712 */ -+ cfg80211_tdls_oper_request(prAdapter->prGlueInfo->prDevHandler, -+ prStaRec->aucMacAddr, TDLS_FRM_ACTION_TEARDOWN, -+ TDLS_REASON_CODE_UNSPECIFIED, GFP_ATOMIC); -+ return TDLS_STATUS_SUCCESS; -+ } -+ -+ /* backup the key */ -+ kalMemCopy(&prStaRec->rTdlsKeyTemp, prNewKey, sizeof(prStaRec->rTdlsKeyTemp)); -+ return TDLS_STATUS_SUCCESS; -+ } -+ -+ return TDLS_STATUS_FAILURE; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is used to initialize variables in TDLS. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID TdlsexInit(ADAPTER_T *prAdapter) -+{ -+ GLUE_INFO_T *prGlueInfo; -+ -+ /* init */ -+ prGlueInfo = (GLUE_INFO_T *) prAdapter->prGlueInfo; -+ -+ /* reset */ -+ kalMemZero(&prGlueInfo->rTdlsLink, sizeof(prGlueInfo->rTdlsLink)); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to get any peer is in power save. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* -+* \retval TRUE (at least one peer is in power save) -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN TdlsexIsAnyPeerInPowerSave(ADAPTER_T *prAdapter) -+{ -+ STA_RECORD_T *prStaRec; -+ UINT32 u4StaId, u4StartIdx; -+ -+ for (u4StaId = 0, u4StartIdx = 0; u4StaId < CFG_STA_REC_NUM; u4StaId++) { -+ /* list all TDLS peers */ -+ prStaRec = cnmStaTheTypeGet(prAdapter, NETWORK_TYPE_AIS_INDEX, STA_TYPE_TDLS_PEER, &u4StartIdx); -+ if (prStaRec == NULL) -+ break; -+ -+ if (prStaRec->fgIsInPS == TRUE) { -+ DBGLOG(TDLS, TRACE, " yes, at least one peer is in ps\n"); -+ return TRUE; -+ } -+ } -+ -+ return FALSE; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to enable or disable a TDLS link. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set -+* \param[in] u4SetBufferLen The length of the set buffer -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed due to invalid length of -+* the set buffer, returns the amount of storage needed. -+* -+* \retval TDLS_STATUS_xx -+*/ -+/*----------------------------------------------------------------------------*/ -+TDLS_STATUS TdlsexLinkCtrl(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen) -+{ -+ GLUE_INFO_T *prGlueInfo; -+ TDLS_CMD_LINK_T *prCmd; -+ BSS_INFO_T *prBssInfo; -+ STA_RECORD_T *prStaRec; -+ TDLS_LINK_HIS_OTHERS_T rHisOthers; -+ -+ /* sanity check */ -+ if ((prAdapter == NULL) || (pvSetBuffer == NULL) || (pu4SetInfoLen == NULL)) { -+ DBGLOG(TDLS, ERROR, " %s: sanity fail!\n", __func__); -+ return TDLS_STATUS_FAILURE; -+ } -+ -+ /* init */ -+ prGlueInfo = (GLUE_INFO_T *) prAdapter->prGlueInfo; -+ *pu4SetInfoLen = sizeof(TDLS_CMD_LINK_T); -+ prCmd = (TDLS_CMD_LINK_T *) pvSetBuffer; -+ -+ /* search old entry */ -+ prStaRec = cnmGetStaRecByAddress(prAdapter, (UINT_8) NETWORK_TYPE_AIS_INDEX, prCmd->aucPeerMac); -+ if (prStaRec == NULL) { -+ DBGLOG(TDLS, ERROR, " %s: cannot find the peer! %pM\n", -+ __func__, prCmd->aucPeerMac); -+ return TDLS_STATUS_FAILURE; -+ } -+ -+ if (prCmd->fgIsEnabled == TRUE) { -+ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_3); -+ DBGLOG(TDLS, TRACE, " %s: NL80211_TDLS_ENABLE_LINK\n", __func__); -+ -+ /* update key information after cnmStaRecChangeState(STA_STATE_3) */ -+ prStaRec->fgTdlsInSecurityMode = FALSE; -+ -+ if (prStaRec->rTdlsKeyTemp.u4Length > 0) { -+ UINT_32 u4BufLen; /* no use */ -+ -+ DBGLOG(TDLS, INFO, " %s: key len=%d\n", -+ __func__, (UINT32) prStaRec->rTdlsKeyTemp.u4Length); -+ -+ /* -+ reminder the function that we are CIPHER_SUITE_CCMP, -+ do not change cipher type to CIPHER_SUITE_WEP128 -+ */ -+ _wlanoidSetAddKey(prAdapter, &prStaRec->rTdlsKeyTemp, -+ prStaRec->rTdlsKeyTemp.u4Length, FALSE, CIPHER_SUITE_CCMP, &u4BufLen); -+ -+ /* clear the temp key */ -+ prStaRec->fgTdlsInSecurityMode = TRUE; -+ kalMemZero(&prStaRec->rTdlsKeyTemp, sizeof(prStaRec->rTdlsKeyTemp)); -+ } -+ -+ /* check if we need to disable channel switch function */ -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]); -+ if (prBssInfo->fgTdlsIsChSwProhibited == TRUE) { -+ TDLS_CMD_CORE_T rCmd; -+ -+ kalMemZero(&rCmd, sizeof(TDLS_CMD_CORE_T)); -+ rCmd.Content.rCmdChSwConf.ucNetTypeIndex = prStaRec->ucNetTypeIndex; -+ rCmd.Content.rCmdChSwConf.fgIsChSwEnabled = FALSE; -+ kalMemCopy(rCmd.aucPeerMac, prStaRec->aucMacAddr, 6); -+ TdlsChSwConf(prAdapter, &rCmd, 0, 0); -+ -+ DBGLOG(TDLS, INFO, " %s: disable channel switch\n", __func__); -+ } -+ -+ TDLS_LINK_INCREASE(prGlueInfo); -+ -+ /* record link */ -+ if (prStaRec->ucDesiredPhyTypeSet & PHY_TYPE_SET_802_11N) -+ rHisOthers.fgIsHt = TRUE; -+ else -+ rHisOthers.fgIsHt = FALSE; -+ -+ TdlsLinkHistoryRecord(prAdapter->prGlueInfo, FALSE, -+ prStaRec->aucMacAddr, !prStaRec->flgTdlsIsInitiator, 0, &rHisOthers); -+ } else { -+ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); -+ cnmStaRecFree(prAdapter, prStaRec, TRUE); /* release to other TDLS peers */ -+ DBGLOG(TDLS, TRACE, " %s: NL80211_TDLS_DISABLE_LINK\n", __func__); -+ -+ TDLS_LINK_DECREASE(prGlueInfo); -+/* while(1); //sample debug */ -+ } -+ -+ /* work-around link count */ -+ if ((TDLS_LINK_COUNT(prGlueInfo) < 0) || (TDLS_LINK_COUNT(prGlueInfo) > 1)) { -+ /* ERROR case: work-around to recount by searching all station records */ -+ UINT32 u4Idx; -+ -+ TDLS_LINK_COUNT_RESET(prGlueInfo); -+ -+ for (u4Idx = 0; u4Idx < CFG_STA_REC_NUM; u4Idx++) { -+ prStaRec = &prAdapter->arStaRec[u4Idx]; -+ -+ if (prStaRec->fgIsInUse && IS_TDLS_STA(prStaRec)) -+ TDLS_LINK_INCREASE(prGlueInfo); -+ } -+ -+ if (TDLS_LINK_COUNT(prGlueInfo) > 1) { -+ /* number of links is still > 1 */ -+ DBGLOG(TDLS, INFO, " %s: cTdlsLinkCnt %d > 1?\n", -+ __func__, TDLS_LINK_COUNT(prGlueInfo)); -+ -+ TDLS_LINK_COUNT_RESET(prGlueInfo); -+ -+ /* free all TDLS links */ -+ for (u4Idx = 0; u4Idx < CFG_STA_REC_NUM; u4Idx++) { -+ prStaRec = &prAdapter->arStaRec[u4Idx]; -+ -+ if (prStaRec->fgIsInUse && IS_TDLS_STA(prStaRec)) -+ cnmStaRecFree(prAdapter, prStaRec, TRUE); -+ } -+ -+ /* maybe inform supplicant ? */ -+ } -+ } -+ -+ /* display TDLS link history */ -+ TdlsInfoDisplay(prAdapter, NULL, 0, NULL); -+ -+ return TDLS_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to send a TDLS action data frame. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set -+* \param[in] u4SetBufferLen The length of the set buffer -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed due to invalid length of -+* the set buffer, returns the amount of storage needed. -+* -+* \retval TDLS_STATUS_xx -+*/ -+/*----------------------------------------------------------------------------*/ -+TDLS_STATUS TdlsexMgmtCtrl(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen) -+{ -+ GLUE_INFO_T *prGlueInfo; -+ TDLS_MGMT_TX_INFO *prMgmtTxInfo; -+ STA_RECORD_T *prStaRec; -+ -+ /* sanity check */ -+ if ((prAdapter == NULL) || (pvSetBuffer == NULL) || (pu4SetInfoLen == NULL)) { -+ DBGLOG(TDLS, ERROR, " %s: sanity fail!\n", __func__); -+ return TDLS_STATUS_FAILURE; -+ } -+ -+ /* init */ -+ prGlueInfo = (GLUE_INFO_T *) prAdapter->prGlueInfo; -+ *pu4SetInfoLen = sizeof(TDLS_MGMT_TX_INFO); -+ prMgmtTxInfo = (TDLS_MGMT_TX_INFO *) pvSetBuffer; -+ -+ switch (prMgmtTxInfo->ucActionCode) { -+ case TDLS_FRM_ACTION_DISCOVERY_RESPONSE: -+ prStaRec = NULL; -+ break; -+ -+ case TDLS_FRM_ACTION_SETUP_REQ: -+ prStaRec = cnmGetStaRecByAddress(prAdapter, (UINT_8) NETWORK_TYPE_AIS_INDEX, prMgmtTxInfo->aucPeer); -+ if ((prStaRec != NULL) && (prStaRec->ucStaState == STA_STATE_3)) { -+ /* rekey? we reject re-setup link currently */ -+ /* TODO: Still can setup link during rekey */ -+ -+ /* -+ return success to avoid supplicant clear TDLS entry; -+ Or we cannot send out any TDLS tear down frame to the peer -+ */ -+ DBGLOG(TDLS, TRACE, " %s: skip new setup on the exist link!\n", __func__); -+ return TDLS_STATUS_SUCCESS; -+ } -+ -+ prStaRec = NULL; -+ break; -+ -+ case TDLS_FRM_ACTION_SETUP_RSP: -+ case TDLS_FRM_ACTION_CONFIRM: -+ case TDLS_FRM_ACTION_TEARDOWN: -+ prStaRec = cnmGetStaRecByAddress(prAdapter, (UINT_8) NETWORK_TYPE_AIS_INDEX, prMgmtTxInfo->aucPeer); -+#if 0 /* in some cases, the prStaRec is still NULL */ -+ /* -+ EX: if a peer sends us a TDLS setup request with wrong BSSID, -+ supplicant will not call TdlsexPeerAdd() to create prStaRec and -+ supplicant will send a TDLS setup response with status code 7. -+ -+ So in the case, prStaRec will be NULL. -+ */ -+ if (prStaRec == NULL) { -+ DBGLOG(TDLS, ERROR, " %s: cannot find the peer!\n", __func__); -+ return -EINVAL; -+ } -+#endif -+ break; -+ -+ /* -+ TODO: Discovery response frame -+ Note that the TDLS Discovery Response frame is not a TDLS frame but a 11 -+ Public Action frame. -+ In WiFi TDLS Tech Minutes June 8 2010.doc, -+ a public action frame (i.e. it is no longer an encapsulated data frame) -+ */ -+ -+ default: -+ DBGLOG(TDLS, ERROR, -+ " %s: wrong action_code %d!\n", __func__, prMgmtTxInfo->ucActionCode); -+ return TDLS_STATUS_FAILURE; -+ } -+ -+ /* send the TDLS data frame */ -+ if (prStaRec != NULL) { -+ DBGLOG(TDLS, INFO, " %s: [%pM] ps=%d status=%d\n", -+ __func__, prStaRec->aucMacAddr, -+ prStaRec->fgIsInPS, prMgmtTxInfo->u2StatusCode); -+ -+ if (prMgmtTxInfo->ucActionCode == TDLS_FRM_ACTION_TEARDOWN) { -+ /* record disconnect history */ -+ TdlsLinkHistoryRecord(prGlueInfo, TRUE, prMgmtTxInfo->aucPeer, -+ TRUE, prMgmtTxInfo->u2StatusCode, NULL); -+ } -+ } -+ -+ return TdlsDataFrameSend(prAdapter, -+ prStaRec, -+ prMgmtTxInfo->aucPeer, -+ prMgmtTxInfo->ucActionCode, -+ prMgmtTxInfo->ucDialogToken, -+ prMgmtTxInfo->u2StatusCode, -+ (UINT_8 *) prMgmtTxInfo->aucSecBuf, prMgmtTxInfo->u4SecBufLen); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to add a peer record. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set -+* \param[in] u4SetBufferLen The length of the set buffer -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed due to invalid length of -+* the set buffer, returns the amount of storage needed. -+* -+* \retval TDLS_STATUS_xx -+*/ -+/*----------------------------------------------------------------------------*/ -+TDLS_STATUS TdlsexPeerAdd(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen) -+{ -+ GLUE_INFO_T *prGlueInfo; -+ TDLS_CMD_PEER_ADD_T *prCmd; -+ BSS_INFO_T *prAisBssInfo; -+ STA_RECORD_T *prStaRec; -+ UINT_8 ucNonHTPhyTypeSet; -+ UINT32 u4StartIdx; -+ OS_SYSTIME rCurTime; -+ -+ /* sanity check */ -+ DBGLOG(TDLS, INFO, " %s\n", __func__); -+ -+ if ((prAdapter == NULL) || (pvSetBuffer == NULL) || (pu4SetInfoLen == NULL)) { -+ DBGLOG(TDLS, ERROR, " %s: sanity fail!\n", __func__); -+ return TDLS_STATUS_FAILURE; -+ } -+ -+ /* init */ -+ prGlueInfo = (GLUE_INFO_T *) prAdapter->prGlueInfo; -+ *pu4SetInfoLen = sizeof(TDLS_CMD_PEER_ADD_T); -+ prCmd = (TDLS_CMD_PEER_ADD_T *) pvSetBuffer; -+ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ u4StartIdx = 0; -+ -+ /* search old entry */ -+ prStaRec = cnmGetStaRecByAddress(prAdapter, (UINT_8) NETWORK_TYPE_AIS_INDEX, prCmd->aucPeerMac); -+ -+ /* check if any TDLS link exists because we only support one TDLS link currently */ -+ if (prStaRec == NULL) { -+ /* the MAC is new peer */ -+ prStaRec = cnmStaTheTypeGet(prAdapter, NETWORK_TYPE_AIS_INDEX, STA_TYPE_TDLS_PEER, &u4StartIdx); -+ -+ if (prStaRec != NULL) { -+ /* a building TDLS link exists */ -+ DBGLOG(TDLS, ERROR, -+ " %s: one TDLS link setup [%pM] is going...\n", -+ __func__, prStaRec->aucMacAddr); -+ -+ if (prStaRec->ucStaState != STA_STATE_3) { -+ /* check timeout */ -+ GET_CURRENT_SYSTIME(&rCurTime); -+ -+ if (CHECK_FOR_TIMEOUT(rCurTime, prStaRec->rTdlsSetupStartTime, -+ SEC_TO_SYSTIME(TDLS_SETUP_TIMEOUT_SEC))) { -+ /* free the StaRec */ -+ cnmStaRecFree(prAdapter, prStaRec, TRUE); -+ -+ DBGLOG(TDLS, ERROR, -+ " %s: free going TDLS link setup [%pM]\n", -+ __func__, (prStaRec->aucMacAddr)); -+ -+ /* handle new setup */ -+ prStaRec = NULL; -+ } else -+ return TDLS_STATUS_FAILURE; -+ } else { -+ /* the TDLS is built and works fine, reject new one */ -+ return TDLS_STATUS_FAILURE; -+ } -+ } -+ } else { -+ if (prStaRec->ucStaState == STA_STATE_3) { -+ /* the peer exists, maybe TPK lifetime expired, supplicant wants to renew key */ -+ TdlsLinkHistoryRecord(prAdapter->prGlueInfo, TRUE, -+ prStaRec->aucMacAddr, TRUE, -+ TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_REKEY, NULL); -+ -+ /* 16 Nov 21:49 2012 http://permalink.gmane.org/gmane.linux.kernel.wireless.general/99712 */ -+ cfg80211_tdls_oper_request(prAdapter->prGlueInfo->prDevHandler, -+ prStaRec->aucMacAddr, TDLS_FRM_ACTION_TEARDOWN, -+ TDLS_REASON_CODE_UNSPECIFIED, GFP_ATOMIC); -+ -+ DBGLOG(TDLS, TRACE, -+ " %s: re-setup link for [%pM] maybe re-key?\n", -+ __func__, (prStaRec->aucMacAddr)); -+ return TDLS_STATUS_FAILURE; -+ } -+ } -+ -+ /* -+ create new entry if not exist -+ -+ 1. we are initiator -+ (1) send TDLS setup request -+ wpa_sm_tdls_peer_addset(sm, peer->addr, 1, 0, 0, NULL, 0, NULL, NULL, 0, NULL, 0); -+ create a station record with STA_STATE_1. -+ (2) got TDLS setup response and send TDLS setup confirm -+ wpa_tdls_enable_link() -+ update a station record with STA_STATE_3. -+ -+ 2. we are responder -+ (1) got TDLS setup request -+ wpa_sm_tdls_peer_addset(sm, peer->addr, 1, 0, 0, NULL, 0, NULL, NULL, 0, NULL, 0); -+ create a station record with STA_STATE_1. -+ (2) send TDLS setup response -+ (3) got TDLS setup confirm -+ wpa_tdls_enable_link() -+ update a station record with STA_STATE_3. -+ */ -+ if (prStaRec == NULL) { -+ prStaRec = cnmStaRecAlloc(prAdapter, (UINT_8) NETWORK_TYPE_AIS_INDEX); -+ -+ if (prStaRec == NULL) { -+ /* shall not be here */ -+ DBGLOG(TDLS, ERROR, " %s: alloc prStaRec fail!\n", __func__); -+ return TDLS_STATUS_RESOURCES; -+ } -+ -+ /* init the prStaRec */ -+ /* prStaRec will be zero first in cnmStaRecAlloc() */ -+ COPY_MAC_ADDR(prStaRec->aucMacAddr, prCmd->aucPeerMac); -+ -+/* cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); */ -+ } else { -+#if 0 -+ if ((prStaRec->ucStaState > STA_STATE_1) && (IS_TDLS_STA(prStaRec))) { -+ /* -+ test plan: The STAUT should locally tear down existing TDLS direct link and -+ respond with Set up Response frame. -+ */ -+ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); -+ } -+#endif -+ } -+ -+ /* reference to bssCreateStaRecFromBssDesc() and use our best capability */ -+ /* reference to assocBuildReAssocReqFrameCommonIEs() to fill elements */ -+ -+ /* prStaRec->u2CapInfo */ -+ /* TODO: Need to parse elements from setup request frame */ -+ prStaRec->u2OperationalRateSet = prAisBssInfo->u2OperationalRateSet; -+ prStaRec->u2BSSBasicRateSet = prAisBssInfo->u2BSSBasicRateSet; -+ prStaRec->u2DesiredNonHTRateSet = prAdapter->rWifiVar.ucAvailablePhyTypeSet; -+ prStaRec->ucPhyTypeSet = prAisBssInfo->ucPhyTypeSet; -+ prStaRec->eStaType = STA_TYPE_TDLS_PEER; -+ -+ prStaRec->ucDesiredPhyTypeSet = /*prStaRec->ucPhyTypeSet & */ -+ prAdapter->rWifiVar.ucAvailablePhyTypeSet; -+ ucNonHTPhyTypeSet = prStaRec->ucDesiredPhyTypeSet & PHY_TYPE_SET_802_11ABG; -+ -+ /* check for Target BSS's non HT Phy Types */ -+ if (ucNonHTPhyTypeSet) { -+ if (ucNonHTPhyTypeSet & PHY_TYPE_BIT_ERP) { -+ prStaRec->ucNonHTBasicPhyType = PHY_TYPE_ERP_INDEX; -+ } else if (ucNonHTPhyTypeSet & PHY_TYPE_BIT_OFDM) { -+ prStaRec->ucNonHTBasicPhyType = PHY_TYPE_OFDM_INDEX; -+ } else { /* if (ucNonHTPhyTypeSet & PHY_TYPE_HR_DSSS_INDEX) */ -+ -+ prStaRec->ucNonHTBasicPhyType = PHY_TYPE_HR_DSSS_INDEX; -+ } -+ -+ prStaRec->fgHasBasicPhyType = TRUE; -+ } else { -+ /* use mandatory for 11N only BSS */ -+/* ASSERT(prStaRec->ucPhyTypeSet & PHY_TYPE_SET_802_11N); */ -+ -+ prStaRec->ucNonHTBasicPhyType = PHY_TYPE_HR_DSSS_INDEX; -+ prStaRec->fgHasBasicPhyType = FALSE; -+ } -+ -+ /* update non HT Desired Rate Set */ -+ { -+ P_CONNECTION_SETTINGS_T prConnSettings; -+ -+ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); -+ prStaRec->u2DesiredNonHTRateSet = -+ (prStaRec->u2OperationalRateSet & prConnSettings->u2DesiredNonHTRateSet); -+ } -+ -+#if 0 /* TdlsexPeerAdd() will be called before we receive setup rsp in TdlsexRxFrameHandle() */ -+ /* check if the add is from the same peer in the 1st unhandled setup request frame */ -+ DBGLOG(TDLS, INFO, " %s: [%pM] [%pM]\n", -+ __func__, prGlueInfo->aucTdlsHtPeerMac, prCmd->aucPeerMac); -+ -+ if (kalMemCmp(prGlueInfo->aucTdlsHtPeerMac, prCmd->aucPeerMac, 6) == 0) { -+ /* copy the HT capability from its setup request */ -+ kalMemCopy(&prStaRec->rTdlsHtCap, &prGlueInfo->rTdlsHtCap, sizeof(IE_HT_CAP_T)); -+ -+ prStaRec->ucPhyTypeSet |= PHY_TYPE_SET_802_11N; -+ prStaRec->u2DesiredNonHTRateSet |= BIT(RATE_HT_PHY_INDEX); -+ -+ /* reset backup */ -+ kalMemZero(&prGlueInfo->rTdlsHtCap, sizeof(prStaRec->rTdlsHtCap)); -+ kalMemZero(prGlueInfo->aucTdlsHtPeerMac, sizeof(prGlueInfo->aucTdlsHtPeerMac)); -+ -+ DBGLOG(TDLS, INFO, " %s: peer is a HT device\n", __func__); -+ } -+#endif -+ -+ /* update WMM: must support due to UAPSD in TDLS link */ -+ prStaRec->fgIsWmmSupported = TRUE; -+ prStaRec->fgIsUapsdSupported = TRUE; -+ -+ /* update station record to firmware */ -+ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); -+ -+ /* update time */ -+ GET_CURRENT_SYSTIME(&prStaRec->rTdlsSetupStartTime); -+ -+ DBGLOG(TDLS, INFO, " %s: create a peer [%pM]\n", -+ __func__, (prStaRec->aucMacAddr)); -+ -+ return TDLS_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to update a peer record. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set -+* \param[in] u4SetBufferLen The length of the set buffer -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed due to invalid length of -+* the set buffer, returns the amount of storage needed. -+* -+* \retval TDLS_STATUS_xx -+*/ -+/*----------------------------------------------------------------------------*/ -+TDLS_STATUS TdlsexPeerUpdate(ADAPTER_T *prAdapter, VOID *pvSetBuffer, UINT_32 u4SetBufferLen, UINT_32 *pu4SetInfoLen) -+{ -+ GLUE_INFO_T *prGlueInfo; -+ TDLS_CMD_PEER_UPDATE_T *prCmd; -+ BSS_INFO_T *prAisBssInfo; -+ STA_RECORD_T *prStaRec; -+ IE_HT_CAP_T *prHtCap; -+ -+ /* sanity check */ -+ DBGLOG(TDLS, INFO, " %s\n", __func__); -+ -+ if ((prAdapter == NULL) || (pvSetBuffer == NULL) || (pu4SetInfoLen == NULL)) { -+ DBGLOG(TDLS, ERROR, " %s: sanity fail!\n", __func__); -+ return TDLS_STATUS_FAILURE; -+ } -+ -+ /* init */ -+ prGlueInfo = (GLUE_INFO_T *) prAdapter->prGlueInfo; -+ *pu4SetInfoLen = sizeof(TDLS_CMD_PEER_ADD_T); -+ prCmd = (TDLS_CMD_PEER_UPDATE_T *) pvSetBuffer; -+ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ -+ /* search old entry */ -+ prStaRec = cnmGetStaRecByAddress(prAdapter, (UINT_8) NETWORK_TYPE_AIS_INDEX, prCmd->aucPeerMac); -+ -+ /* -+ create new entry if not exist -+ -+ 1. we are initiator -+ (1) send TDLS setup request -+ wpa_sm_tdls_peer_addset(sm, peer->addr, 1, 0, 0, NULL, 0, NULL, NULL, 0, NULL, 0); -+ create a station record with STA_STATE_1. -+ (2) got TDLS setup response and send TDLS setup confirm -+ wpa_tdls_enable_link() -+ update a station record with STA_STATE_3. -+ -+ 2. we are responder -+ (1) got TDLS setup request -+ wpa_sm_tdls_peer_addset(sm, peer->addr, 1, 0, 0, NULL, 0, NULL, NULL, 0, NULL, 0); -+ create a station record with STA_STATE_1. -+ (2) send TDLS setup response -+ (3) got TDLS setup confirm -+ wpa_tdls_enable_link() -+ update a station record with STA_STATE_3. -+ */ -+ if ((prStaRec == NULL) || (prStaRec->fgIsInUse == 0)) { -+ DBGLOG(TDLS, ERROR, " %s: cannot find the peer!\n", __func__); -+ return TDLS_STATUS_FAILURE; -+ } -+ -+ DBGLOG(TDLS, INFO, " %s: update a peer [%pM] %d -> %d, 0x%x\n", -+ __func__, (prStaRec->aucMacAddr), -+ prStaRec->ucStaState, STA_STATE_3, prStaRec->eStaType); -+ -+ if (!IS_TDLS_STA(prStaRec)) { -+ DBGLOG(TDLS, ERROR, " %s: peer is not TDLS one!\n", __func__); -+ return TDLS_STATUS_FAILURE; -+ } -+ -+ /* check if the add is from the same peer in the 1st unhandled setup request frame */ -+ DBGLOG(TDLS, INFO, " %s: [%pM] [%pM]\n", -+ __func__, (prGlueInfo->aucTdlsHtPeerMac), (prCmd->aucPeerMac)); -+ -+ if (kalMemCmp(prGlueInfo->aucTdlsHtPeerMac, prCmd->aucPeerMac, 6) == 0) { -+ /* copy the HT capability from its setup request */ -+ kalMemCopy(&prStaRec->rTdlsHtCap, &prGlueInfo->rTdlsHtCap, sizeof(IE_HT_CAP_T)); -+ -+ prStaRec->ucPhyTypeSet |= PHY_TYPE_SET_802_11N; -+ prStaRec->u2DesiredNonHTRateSet |= BIT(RATE_HT_PHY_INDEX); -+ -+ /* reset backup */ -+ kalMemZero(&prGlueInfo->rTdlsHtCap, sizeof(prStaRec->rTdlsHtCap)); -+ kalMemZero(prGlueInfo->aucTdlsHtPeerMac, sizeof(prGlueInfo->aucTdlsHtPeerMac)); -+ -+ DBGLOG(TDLS, INFO, " %s: peer is a HT device\n", __func__); -+ } -+ -+ /* update the record join time. */ -+ GET_CURRENT_SYSTIME(&prStaRec->rUpdateTime); -+ -+ /* update Station Record - Status/Reason Code */ -+ prStaRec->u2StatusCode = prCmd->u2StatusCode; -+ -+ /* prStaRec->ucStaState shall be STA_STATE_1 */ -+ -+ prStaRec->u2CapInfo = prCmd->u2Capability; -+/* prStaRec->u2OperationalRateSet */ -+ prStaRec->u2AssocId = 0; /* no use */ -+ prStaRec->u2ListenInterval = 0; /* unknown */ -+/* prStaRec->ucDesiredPhyTypeSet */ -+/* prStaRec->u2DesiredNonHTRateSet */ -+/* prStaRec->u2BSSBasicRateSet */ -+/* prStaRec->ucMcsSet */ -+/* prStaRec->fgSupMcs32 */ -+/* prStaRec->u2HtCapInfo */ -+ prStaRec->fgIsQoS = TRUE; -+ prStaRec->fgIsUapsdSupported = (prCmd->UapsdBitmap == 0) ? FALSE : TRUE; -+/* prStaRec->ucAmpduParam */ -+/* prStaRec->u2HtExtendedCap */ -+ prStaRec->u4TxBeamformingCap = 0; /* no use */ -+ prStaRec->ucAselCap = 0; /* no use */ -+ prStaRec->ucRCPI = 0; -+ prStaRec->ucBmpTriggerAC = prCmd->UapsdBitmap; -+ prStaRec->ucBmpDeliveryAC = prCmd->UapsdBitmap; -+ prStaRec->ucUapsdSp = prCmd->UapsdMaxSp; -+ -+ /* update HT */ -+#if (TDLS_CFG_HT_SUP == 1) -+ if (prCmd->fgIsSupHt == FALSE) { -+ /* no HT IE is from supplicant so we use the backup */ -+ prHtCap = (IE_HT_CAP_T *) &prStaRec->rTdlsHtCap; -+ -+ DBGLOG(TDLS, INFO, " %s: [%pM] update ht ie 0x%x\n", -+ __func__, (prStaRec->aucMacAddr), prHtCap->ucId); -+ -+ if (prHtCap->ucId == ELEM_ID_HT_CAP) { -+ prStaRec->ucMcsSet = prHtCap->rSupMcsSet.aucRxMcsBitmask[0]; -+ prStaRec->fgSupMcs32 = (prHtCap->rSupMcsSet.aucRxMcsBitmask[32 / 8] & BIT(0)) ? TRUE : FALSE; -+ -+ prStaRec->u2HtCapInfo = prHtCap->u2HtCapInfo; -+ prStaRec->ucAmpduParam = prHtCap->ucAmpduParam; -+ prStaRec->u2HtExtendedCap = prHtCap->u2HtExtendedCap; -+ prStaRec->u4TxBeamformingCap = prHtCap->u4TxBeamformingCap; -+ prStaRec->ucAselCap = prHtCap->ucAselCap; -+ prStaRec->ucDesiredPhyTypeSet |= PHY_TYPE_SET_802_11N; -+ } -+ } else { -+ /* TODO: use the HT IE from supplicant */ -+ } -+#endif /* TDLS_CFG_HT_SUP */ -+ -+ DBGLOG(TDLS, INFO, " %s: UAPSD 0x%x %d MCS=0x%x\n", -+ __func__, prCmd->UapsdBitmap, prCmd->UapsdMaxSp, prStaRec->ucMcsSet); -+ -+/* cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_3); */ -+ -+ DBGLOG(TDLS, INFO, " %s: update a peer [%pM]\n", -+ __func__, (prStaRec->aucMacAddr)); -+ -+ return TDLS_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to check if we need to drop a TDLS action frame. -+* -+* \param[in] *pPkt Pointer to the struct sk_buff->data. -+* \param[in] -+* \param[in] -+* -+* \retval None -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN TdlsexRxFrameDrop(GLUE_INFO_T *prGlueInfo, UINT_8 *pPkt) -+{ -+ ADAPTER_T *prAdapter; -+ UINT8 ucActionId; -+ -+ /* sanity check */ -+ if ((pPkt == NULL) || (*(pPkt + 12) != 0x89) || (*(pPkt + 13) != 0x0d)) -+ return FALSE; /* not TDLS data frame htons(0x890d) */ -+ -+#if 0 /* supplicant handles this check */ -+ if (prStaRec == NULL) -+ return FALSE; /* shall not be here */ -+ -+ DBGLOG(TDLS, INFO, -+ " %s: Rcv a TDLS action frame (id=%d) %d %d\n", -+ __func__, *(pPkt + 13 + 4), prStaRec->fgTdlsIsProhibited, fgIsPtiTimeoutSkip); -+ -+ /* check if TDLS Prohibited bit is set in AP's beacon */ -+ if (prStaRec->fgTdlsIsProhibited == TRUE) -+ return TRUE; -+#endif -+ -+ ucActionId = *(pPkt + 12 + 2 + 2); /* skip dst, src MAC, type, payload type, category */ -+ -+ if (fgIsPtiTimeoutSkip == TRUE) { -+ /* also skip any tear down frame from the peer */ -+ if (ucActionId == TDLS_FRM_ACTION_TEARDOWN) -+ return TRUE; -+ } -+ -+ prAdapter = prGlueInfo->prAdapter; -+ DBGLOG(TDLS, INFO, -+ " %s: Rcv a TDLS action frame %d (%u)\n", -+ __func__, ucActionId, (UINT32) prAdapter->rRxCtrl.rFreeSwRfbList.u4NumElem); -+ -+ if (ucActionId == TDLS_FRM_ACTION_TEARDOWN) { -+ DBGLOG(TDLS, WARN, " %s: Rcv a TDLS tear down frame %d, will DISABLE link\n", -+ __func__, *(pPkt + 13 + 4)); /* reason code */ -+ -+ /* record disconnect history */ -+ TdlsLinkHistoryRecord(prGlueInfo, TRUE, pPkt + 6, FALSE, *(pPkt + 13 + 4), NULL); -+ -+ /* inform tear down to supplicant only in OPEN/NONE mode */ -+ /* -+ we need to tear down the link manually; or supplicant will display -+ "No FTIE in TDLS Teardown" and it will not tear down the link -+ */ -+ cfg80211_tdls_oper_request(prGlueInfo->prDevHandler, -+ pPkt + 6, TDLS_FRM_ACTION_TEARDOWN, *(pPkt + 13 + 4), GFP_ATOMIC); -+ } -+#if 0 /* pass all to supplicant except same thing is handled in supplicant */ -+ if (((*(pPkt + 13 + 3)) == TDLS_FRM_ACTION_PTI) || -+ ((*(pPkt + 13 + 3)) == TDLS_FRM_ACTION_CHAN_SWITCH_REQ) || -+ ((*(pPkt + 13 + 3)) == TDLS_FRM_ACTION_CHAN_SWITCH_RSP) || -+ ((*(pPkt + 13 + 3)) == TDLS_FRM_ACTION_PTI_RSP)) { -+ return TRUE; -+ } -+#endif -+ -+ return FALSE; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to parse some IEs in the setup frame from the peer. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] pPkt Pointer to the ethernet packet -+* -+* \retval None -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID TdlsexRxFrameHandle(GLUE_INFO_T *prGlueInfo, UINT8 *pPkt, UINT16 u2PktLen) -+{ -+ ADAPTER_T *prAdapter; -+ STA_RECORD_T *prStaRec; -+ UINT8 ucActionId; -+ UINT8 *pucPeerMac, ucElmId, ucElmLen; -+ INT16 s2FmeLen; -+ -+ /* sanity check */ -+ if ((prGlueInfo == NULL) || (pPkt == NULL) || (*(pPkt + 12) != 0x89) || (*(pPkt + 13) != 0x0d)) -+ return; -+ -+ ucActionId = *(pPkt + 12 + 2 + 2); /* skip dst, src MAC, type, payload type, category */ -+ -+ if ((ucActionId != TDLS_FRM_ACTION_SETUP_REQ) && (ucActionId != TDLS_FRM_ACTION_SETUP_RSP)) -+ return; -+ -+ /* init */ -+ prAdapter = prGlueInfo->prAdapter; -+ pucPeerMac = pPkt + 6; -+ s2FmeLen = (INT16) u2PktLen; -+ -+ DBGLOG(TDLS, TRACE, -+ " %s: get a setup frame %d from %pM\n", -+ __func__, ucActionId, (pucPeerMac)); -+ -+ if (ucActionId == TDLS_FRM_ACTION_SETUP_REQ) -+ pPkt += 12 + 2 + 2 + 1 + 1 + 2; /* skip action, dialog token, capability */ -+ else -+ pPkt += 12 + 2 + 2 + 1 + 2 + 1 + 2; /* skip action, status code, dialog token, capability */ -+ -+ /* check station record */ -+ prStaRec = cnmGetStaRecByAddress(prGlueInfo->prAdapter, (UINT_8) NETWORK_TYPE_AIS_INDEX, pucPeerMac); -+ -+ if (prStaRec == NULL) { -+ prStaRec = cnmStaRecAlloc(prAdapter, (UINT_8) NETWORK_TYPE_AIS_INDEX); -+ -+ if (prStaRec == NULL) { -+ /* TODO: only one TDLS entry, need to free old one if timeout */ -+ DBGLOG(TDLS, ERROR, " %s: alloc prStaRec fail!\n", __func__); -+ return; -+ } -+ -+ /* init the prStaRec */ -+ /* prStaRec will be zero first in cnmStaRecAlloc() */ -+ COPY_MAC_ADDR(prStaRec->aucMacAddr, pucPeerMac); -+ -+ cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); -+ } -+ -+ /* backup HT IE to station record */ -+ /* TODO: Maybe our TDLS only supports non-11n */ -+ while (s2FmeLen > 0) { -+ ucElmId = *pPkt++; -+ ucElmLen = *pPkt++; -+ -+ switch (ucElmId) { -+ case ELEM_ID_HT_CAP: /* 0x2d */ -+ /* backup the HT IE of 1st unhandled setup request frame */ -+ if (prGlueInfo->rTdlsHtCap.ucId == 0x00) { -+ kalMemCopy(prGlueInfo->aucTdlsHtPeerMac, pucPeerMac, 6); -+ kalMemCopy(&prGlueInfo->rTdlsHtCap, pPkt - 2, ucElmLen + 2); -+ -+ /* -+ cannot backup in prStaRec; or -+ -+ 1. we build a TDLS link -+ 2. peer re-sends setup req -+ 3. we backup HT cap element -+ 4. supplicant disables the link -+ 5. we clear the prStaRec -+ */ -+ -+ DBGLOG(TDLS, TRACE, -+ " %s: %pM: find a HT IE\n", -+ __func__, (pucPeerMac)); -+ } -+ return; -+ -+ case ELEM_ID_EXTENDED_CAP: -+ /* TODO: backup the extended capability IE */ -+ break; -+ } -+ -+ pPkt += ucElmLen; -+ s2FmeLen -= (2 + ucElmLen); -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! \brief This routine is called to get the TDLS station record. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure -+* \param[in] prInBuf A pointer to the command string buffer -+* \param[in] u4InBufLen The length of the buffer -+* \param[out] None -+* -+* \retval TDLS_STATUS_SUCCESS: this is TDLS packet -+* TDLS_STATUS_FAILURE: this is not TDLS packet -+*/ -+/*----------------------------------------------------------------------------*/ -+TDLS_STATUS TdlsexStaRecIdxGet(ADAPTER_T *prAdapter, MSDU_INFO_T *prMsduInfo) -+{ -+ BSS_INFO_T *prBssInfo; -+ STA_RECORD_T *prStaRec; -+ TDLS_STATUS Status; -+ -+ /* sanity check */ -+ if ((prAdapter == NULL) || (prMsduInfo == NULL)) -+ return TDLS_STATUS_FAILURE; -+ -+ if (prAdapter->prGlueInfo == NULL) -+ return TDLS_STATUS_FAILURE; -+ if (TDLS_IS_NO_LINK_GOING(prAdapter->prGlueInfo)) -+ return TDLS_STATUS_FAILURE; -+ -+ /* init */ -+ prMsduInfo->ucStaRecIndex = STA_REC_INDEX_NOT_FOUND; -+ Status = TDLS_STATUS_SUCCESS; -+ -+ /* get record by ether dest */ -+ prStaRec = cnmGetStaRecByAddress(prAdapter, (UINT_8) NETWORK_TYPE_AIS_INDEX, prMsduInfo->aucEthDestAddr); -+ -+ /* -+ TDLS Setup Request frames, TDLS Setup Response frames and TDLS Setup Confirm -+ frames shall be transmitted through the AP and shall not be transmitted to a group -+ address. -+ -+ 1. In first time, prStaRec == NULL or prStaRec->ucStaState != STA_STATE_3, -+ we will send them to AP; -+ 2. When link is still on, if you command to send TDLS setup from supplicant, -+ supplicant will DISABLE LINK first, prStaRec will be NULL then send TDLS -+ setup frame to the peer. -+ */ -+ -+ do { -+ if ((prStaRec != NULL) && (prStaRec->ucStaState == STA_STATE_3) && (IS_TDLS_STA(prStaRec))) { -+ /* -+ TDLS Test Case 5.3 Tear Down -+ Automatically sends TDLS Teardown frame to STA 2 via AP -+ -+ 11.21.5 TDLS Direct Link Teardown -+ The TDLS Teardown frame shall be sent over the direct path and the reason -+ code shall be set to "TDLS 40 direct link teardown for unspecified reason", -+ except when the TDLS peer STA is unreachable via the TDLS direct link, -+ in which case, the TDLS Teardown frame shall be sent through the AP and -+ the reason code shall be set to "TDLS direct link teardown due to TDLS peer -+ STA unreachable via the TDLS direct link". -+ */ -+ /* if (prStaRec->fgIsInPS == TRUE) */ -+ /* -+ check if the packet is tear down: -+ we do not want to use PTI to indicate the tear down and -+ we want to send the tear down to AP then AP help us to send it -+ */ -+ struct sk_buff *prSkb; -+ UINT8 *pEth; -+ UINT_16 u2EtherTypeLen; -+ -+ prSkb = (struct sk_buff *)prMsduInfo->prPacket; -+ if (prSkb != NULL) { -+ UINT8 ucActionCode, ucReasonCode; -+ -+ /* init */ -+ pEth = prSkb->data; -+ u2EtherTypeLen = (pEth[ETH_TYPE_LEN_OFFSET] << 8) | -+ (pEth[ETH_TYPE_LEN_OFFSET + 1]); -+ ucActionCode = pEth[ETH_TYPE_LEN_OFFSET + 1 + 3]; -+ ucReasonCode = pEth[ETH_TYPE_LEN_OFFSET + 1 + 4] | -+ (pEth[ETH_TYPE_LEN_OFFSET + 1 + 5] << 8); -+ -+ /* TDLS_REASON_CODE_UNREACHABLE: keep alive fail or PTI timeout */ -+ if ((u2EtherTypeLen == TDLS_FRM_PROT_TYPE) && -+ (ucActionCode == TDLS_FRM_ACTION_TEARDOWN) && -+ (ucReasonCode == TDLS_REASON_CODE_UNREACHABLE)) { -+ /* -+ when we cannot reach the peer, -+ we need AP's help to send the tear down frame -+ */ -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ prStaRec = prBssInfo->prStaRecOfAP; -+ if (prStaRec == NULL) { -+ Status = TDLS_STATUS_FAILURE; -+ break; -+ } -+#if 0 -+ /* change status code */ -+ pEth[ETH_TYPE_LEN_OFFSET + 1 + 4] = TDLS_REASON_CODE_UNREACHABLE; -+#endif -+ } -+ } -+ prMsduInfo->ucStaRecIndex = prStaRec->ucIndex; -+ } -+ } while (FALSE); -+ -+ DBGLOG(TDLS, INFO, " %s: (Status=%x) [%pM] ucStaRecIndex = %d!\n", -+ __func__, (INT32) Status, (prMsduInfo->aucEthDestAddr), -+ prMsduInfo->ucStaRecIndex); -+ return Status; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is used to check if we suffer timeout for TX quota empty case. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID TdlsexTxQuotaCheck(GLUE_INFO_T *prGlueInfo, STA_RECORD_T *prStaRec, UINT8 FreeQuota) -+{ -+ OS_SYSTIME rCurTime; -+ -+ /* sanity check */ -+ if (!IS_TDLS_STA(prStaRec)) -+ return; -+ -+ if (FreeQuota != 0) { -+ /* reset timeout */ -+ prStaRec->rTdlsTxQuotaEmptyTime = 0; -+ return; -+ } -+ -+ /* work-around: check if the no free quota case is too long */ -+ GET_CURRENT_SYSTIME(&rCurTime); -+ -+ if (prStaRec->rTdlsTxQuotaEmptyTime == 0) { -+ prStaRec->rTdlsTxQuotaEmptyTime = rCurTime; -+ } else { -+ if (CHECK_FOR_TIMEOUT(rCurTime, prStaRec->rTdlsTxQuotaEmptyTime, -+ SEC_TO_SYSTIME(TDLS_TX_QUOTA_EMPTY_TIMEOUT))) { -+ /* tear down the link */ -+ DBGLOG(TDLS, WARN, -+ " %s: [%pM] TX quota empty timeout!\n", -+ __func__, (prStaRec->aucMacAddr)); -+ -+ /* record disconnect history */ -+ TdlsLinkHistoryRecord(prGlueInfo, TRUE, prStaRec->aucMacAddr, -+ TRUE, TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_TX_QUOTA_EMPTY, NULL); -+ -+ /* inform tear down to supplicant only in OPEN/NONE mode */ -+ /* -+ we need to tear down the link manually; or supplicant will display -+ "No FTIE in TDLS Teardown" and it will not tear down the link -+ */ -+ cfg80211_tdls_oper_request(prGlueInfo->prDevHandler, -+ prStaRec->aucMacAddr, TDLS_FRM_ACTION_TEARDOWN, -+ TDLS_REASON_CODE_UNREACHABLE, GFP_ATOMIC); -+ } -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is used to un-initialize variables in TDLS. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID TdlsexUninit(ADAPTER_T *prAdapter) -+{ -+#if TDLS_CFG_CMD_TEST -+ cnmTimerStopTimer(prAdapter, &rTdlsTimerTestDataSend); -+#endif /* TDLS_CFG_CMD_TEST */ -+} -+ -+#endif /* CFG_SUPPORT_TDLS */ -+ -+/* End of tdls.c */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/tdls_com.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/tdls_com.c -new file mode 100644 -index 000000000000..5450cbb65183 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/tdls_com.c -@@ -0,0 +1,741 @@ -+/* -+** Id: tdls_com.c#1 -+*/ -+ -+/*! \file tdls_com.c -+ \brief This file includes IEEE802.11z TDLS main support. -+*/ -+ -+/* -+** Log: tdls_com.c -+ * -+ * 11 13 2013 vend_samp.lin -+ * NULL -+ * Initial version. -+ */ -+ -+/******************************************************************************* -+ * C O M P I L E R F L A G S -+ ******************************************************************************** -+ */ -+ -+/******************************************************************************* -+ * E X T E R N A L R E F E R E N C E S -+ ******************************************************************************** -+ */ -+ -+#include "precomp.h" -+ -+#if (CFG_SUPPORT_TDLS == 1) -+#include "tdls.h" -+ -+ /******************************************************************************* -+ * C O N S T A N T S -+ ******************************************************************************** -+ */ -+ -+ /******************************************************************************* -+ * F U N C T I O N D E C L A R A T I O N S -+ ******************************************************************************** -+ */ -+ -+ /******************************************************************************* -+ * P R I V A T E D A T A -+ ******************************************************************************** -+ */ -+ -+ /******************************************************************************* -+ * P R I V A T E F U N C T I O N S -+ ******************************************************************************** -+ */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to append general IEs. -+* -+* \param[in] pvAdapter Pointer to the Adapter structure. -+* \param[in] prStaRec Pointer to the STA_RECORD_T structure. -+* \param[in] u2StatusCode Status code. -+* \param[in] pPkt Pointer to the frame body -+* -+* \retval append length -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT_32 TdlsFrameGeneralIeAppend(ADAPTER_T *prAdapter, STA_RECORD_T *prStaRec, UINT_16 u2StatusCode, UINT_8 *pPkt) -+{ -+ GLUE_INFO_T *prGlueInfo; -+ BSS_INFO_T *prBssInfo; -+ PM_PROFILE_SETUP_INFO_T *prPmProfSetupInfo; -+ UINT_32 u4NonHTPhyType; -+ UINT_16 u2SupportedRateSet; -+ UINT_8 aucAllSupportedRates[RATE_NUM] = { 0 }; -+ UINT_8 ucAllSupportedRatesLen; -+ UINT_8 ucSupRatesLen; -+ UINT_8 ucExtSupRatesLen; -+ UINT_32 u4PktLen, u4IeLen; -+ BOOLEAN fg40mAllowed; -+ -+ /* reference to assocBuildReAssocReqFrameCommonIEs() */ -+ -+ /* init */ -+ prGlueInfo = (GLUE_INFO_T *) prAdapter->prGlueInfo; -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ prPmProfSetupInfo = &prBssInfo->rPmProfSetupInfo; -+ u4PktLen = 0; -+ -+ /* 3. Frame Formation - (5) Supported Rates element */ -+ /* use all sup rate we can support */ -+ if (prStaRec != NULL) -+ u4NonHTPhyType = prStaRec->ucNonHTBasicPhyType; -+ else -+ u4NonHTPhyType = PHY_TYPE_ERP_INDEX; /* default */ -+ -+ u2SupportedRateSet = rNonHTPhyAttributes[u4NonHTPhyType].u2SupportedRateSet; -+ -+ if (prStaRec != NULL) { -+ u2SupportedRateSet &= prStaRec->u2OperationalRateSet; -+ -+ if (u2SupportedRateSet == 0) -+ u2SupportedRateSet = rNonHTPhyAttributes[u4NonHTPhyType].u2SupportedRateSet; -+ } -+ -+ rateGetDataRatesFromRateSet(u2SupportedRateSet, -+ prBssInfo->u2BSSBasicRateSet, aucAllSupportedRates, &ucAllSupportedRatesLen); -+ -+ ucSupRatesLen = ((ucAllSupportedRatesLen > ELEM_MAX_LEN_SUP_RATES) ? -+ ELEM_MAX_LEN_SUP_RATES : ucAllSupportedRatesLen); -+ -+ ucExtSupRatesLen = ucAllSupportedRatesLen - ucSupRatesLen; -+ -+ if (ucSupRatesLen) { -+ SUP_RATES_IE(pPkt)->ucId = ELEM_ID_SUP_RATES; -+ SUP_RATES_IE(pPkt)->ucLength = ucSupRatesLen; -+ kalMemCopy(SUP_RATES_IE(pPkt)->aucSupportedRates, aucAllSupportedRates, ucSupRatesLen); -+ -+ u4IeLen = IE_SIZE(pPkt); -+ pPkt += u4IeLen; -+ u4PktLen += u4IeLen; -+ } -+ -+ /* 3. Frame Formation - (7) Extended sup rates element */ -+ if (ucExtSupRatesLen) { -+ -+ EXT_SUP_RATES_IE(pPkt)->ucId = ELEM_ID_EXTENDED_SUP_RATES; -+ EXT_SUP_RATES_IE(pPkt)->ucLength = ucExtSupRatesLen; -+ -+ kalMemCopy(EXT_SUP_RATES_IE(pPkt)->aucExtSupportedRates, -+ &aucAllSupportedRates[ucSupRatesLen], ucExtSupRatesLen); -+ -+ u4IeLen = IE_SIZE(pPkt); -+ pPkt += u4IeLen; -+ u4PktLen += u4IeLen; -+ } -+ -+ /* 3. Frame Formation - (8) Supported channels element */ -+ /* -+ The Supported channels element is included in Request frame and also in Response -+ frame if Status Code 0 (successful). -+ */ -+ if (u2StatusCode == 0) { -+ SUPPORTED_CHANNELS_IE(pPkt)->ucId = ELEM_ID_SUP_CHS; -+ SUPPORTED_CHANNELS_IE(pPkt)->ucLength = 2; -+ SUPPORTED_CHANNELS_IE(pPkt)->ucChannelNum[0] = 1; -+ SUPPORTED_CHANNELS_IE(pPkt)->ucChannelNum[1] = 11; -+ -+#if CFG_SUPPORT_DFS -+ if (prAdapter->fgEnable5GBand == TRUE) { -+ /* 5G support */ -+ SUPPORTED_CHANNELS_IE(pPkt)->ucLength = 10; -+ SUPPORTED_CHANNELS_IE(pPkt)->ucChannelNum[2] = 36; -+ SUPPORTED_CHANNELS_IE(pPkt)->ucChannelNum[3] = 4; -+ SUPPORTED_CHANNELS_IE(pPkt)->ucChannelNum[4] = 52; -+ SUPPORTED_CHANNELS_IE(pPkt)->ucChannelNum[5] = 4; -+ SUPPORTED_CHANNELS_IE(pPkt)->ucChannelNum[6] = 149; -+ SUPPORTED_CHANNELS_IE(pPkt)->ucChannelNum[7] = 4; -+ SUPPORTED_CHANNELS_IE(pPkt)->ucChannelNum[8] = 165; -+ SUPPORTED_CHANNELS_IE(pPkt)->ucChannelNum[9] = 4; -+ } -+#endif /* CFG_SUPPORT_DFS */ -+ -+ u4IeLen = IE_SIZE(pPkt); -+ pPkt += u4IeLen; -+ u4PktLen += u4IeLen; -+ } -+ -+ /* 3. Frame Formation - (14) HT capabilities element */ -+ -+ /* no need to check AP capability */ -+/* if ((prAdapter->rWifiVar.ucAvailablePhyTypeSet & PHY_TYPE_SET_802_11N) && */ -+ -+ /* -+ after we set ucPhyTypeSet to PHY_TYPE_SET_802_11N in TdlsexRxFrameHandle(), -+ supplicant will disable link if exists and we will clear prStaRec. -+ -+ finally, prStaRec->ucPhyTypeSet will also be 0 -+ -+ so we have a fix in TdlsexPeerAdd(). -+ */ -+ if (!prStaRec || (prStaRec->ucPhyTypeSet & PHY_TYPE_SET_802_11N)) { -+ /* TODO: prAdapter->rWifiVar.rConnSettings.uc5GBandwidthMode */ -+#if 0 /* always support */ -+ if (prAdapter->rWifiVar.rConnSettings.uc2G4BandwidthMode == CONFIG_BW_20M) -+ fg40mAllowed = FALSE; -+ else -+#endif -+ fg40mAllowed = TRUE; -+ -+ u4IeLen = rlmFillHtCapIEByParams(fg40mAllowed, -+ prAdapter->rWifiVar.rConnSettings.fgRxShortGIDisabled, -+ prAdapter->rWifiVar.u8SupportRxSgi20, -+ prAdapter->rWifiVar.u8SupportRxSgi40, -+ prAdapter->rWifiVar.u8SupportRxGf, -+ prAdapter->rWifiVar.u8SupportRxSTBC, prBssInfo->eCurrentOPMode, pPkt); -+ -+ pPkt += u4IeLen; -+ u4PktLen += u4IeLen; -+ } -+ -+ /* 3. Frame Formation - (17) WMM Information element */ -+ -+ /* always support */ -+/* if (prAdapter->rWifiVar.fgSupportQoS) */ -+ -+ { -+ /* force to support all UAPSD in TDLS link */ -+ u4IeLen = mqmGenerateWmmInfoIEByParam(TRUE /*prAdapter->rWifiVar.fgSupportUAPSD */ , -+ 0xf /*prPmProfSetupInfo->ucBmpDeliveryAC */ , -+ 0xf /*prPmProfSetupInfo->ucBmpTriggerAC */ , -+ WMM_MAX_SP_LENGTH_ALL /*prPmProfSetupInfo->ucUapsdSp */ , -+ pPkt); -+ -+ pPkt += u4IeLen; -+ u4PktLen += u4IeLen; -+ } -+ -+ return u4PktLen; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to transmit a TDLS data frame (setup req/rsp/confirm and tear down). -+* -+* \param[in] pvAdapter Pointer to the Adapter structure. -+* \param[in] prStaRec Pointer to the STA_RECORD_T structure. -+* \param[in] pPeerMac Pointer to the MAC of the TDLS peer -+* \param[in] ucActionCode TDLS Action -+* \param[in] ucDialogToken Dialog token -+* \param[in] u2StatusCode Status code -+* \param[in] pAppendIe Others IEs (here are security IEs from supplicant) -+* \param[in] AppendIeLen IE length of others IEs -+* -+* \retval TDLS_STATUS_xx -+*/ -+/*----------------------------------------------------------------------------*/ -+TDLS_STATUS -+TdlsDataFrameSend(ADAPTER_T *prAdapter, -+ STA_RECORD_T *prStaRec, -+ UINT_8 *pPeerMac, -+ UINT_8 ucActionCode, -+ UINT_8 ucDialogToken, UINT_16 u2StatusCode, UINT_8 *pAppendIe, UINT_32 AppendIeLen) -+{ -+#define LR_TDLS_FME_FIELD_FILL(__Len) \ -+do { \ -+ pPkt += __Len; \ -+ u4PktLen += __Len; \ -+} while (0) -+ -+ GLUE_INFO_T *prGlueInfo; -+ BSS_INFO_T *prBssInfo; -+ PM_PROFILE_SETUP_INFO_T *prPmProfSetupInfo; -+ struct sk_buff *prMsduInfo; -+ MSDU_INFO_T *prMsduInfoMgmt; -+ UINT8 *pPkt, *pucInitiator, *pucResponder; -+ UINT32 u4PktLen, u4IeLen; -+ UINT16 u2CapInfo; -+/* UINT8 *pPktTemp; */ -+ -+ prGlueInfo = (GLUE_INFO_T *) prAdapter->prGlueInfo; -+ -+ DBGLOG(TDLS, INFO, " %s: 2040=%d\n", __func__, prGlueInfo->rTdlsLink.fgIs2040Sup); -+ -+ /* sanity check */ -+ if (prStaRec != NULL) { -+ if (prStaRec->ucNetTypeIndex >= NETWORK_TYPE_INDEX_NUM) { -+ DBGLOG(TDLS, ERROR, -+ " %s: net index %d fail\n", __func__, prStaRec->ucNetTypeIndex); -+ return TDLS_STATUS_FAILURE; -+ } -+ -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]); -+ } else { -+ /* prStaRec maybe NULL in setup request */ -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ } -+ -+ /* allocate/init packet */ -+ prPmProfSetupInfo = &prBssInfo->rPmProfSetupInfo; -+ u4PktLen = 0; -+ prMsduInfo = NULL; -+ prMsduInfoMgmt = NULL; -+ -+ /* make up frame content */ -+ if (ucActionCode != TDLS_FRM_ACTION_DISCOVERY_RESPONSE) { -+ /* -+ The STAUT will not respond to a TDLS Discovery Request Frame with different BSSID. -+ Supplicant will check this in wpa_tdls_process_discovery_request(). -+ */ -+ -+ /* TODO: reduce 1600 to correct size */ -+ prMsduInfo = kalPacketAlloc(prGlueInfo, 1600, &pPkt); -+ if (prMsduInfo == NULL) { -+ DBGLOG(TDLS, ERROR, " %s: allocate pkt fail\n", __func__); -+ return TDLS_STATUS_RESOURCES; -+ } -+ -+ prMsduInfo->dev = prGlueInfo->prDevHandler; -+ if (prMsduInfo->dev == NULL) { -+ DBGLOG(TDLS, ERROR, " %s: MsduInfo->dev == NULL\n", __func__); -+ kalPacketFree(prGlueInfo, prMsduInfo); -+ return TDLS_STATUS_FAILURE; -+ } -+ -+ /* 1. 802.3 header */ -+/* pPktTemp = pPkt; */ -+ kalMemCopy(pPkt, pPeerMac, TDLS_FME_MAC_ADDR_LEN); -+ LR_TDLS_FME_FIELD_FILL(TDLS_FME_MAC_ADDR_LEN); -+ kalMemCopy(pPkt, prBssInfo->aucOwnMacAddr, TDLS_FME_MAC_ADDR_LEN); -+ LR_TDLS_FME_FIELD_FILL(TDLS_FME_MAC_ADDR_LEN); -+ *(UINT_16 *) pPkt = htons(TDLS_FRM_PROT_TYPE); -+ LR_TDLS_FME_FIELD_FILL(2); -+ -+ /* 2. payload type */ -+ *pPkt = TDLS_FRM_PAYLOAD_TYPE; -+ LR_TDLS_FME_FIELD_FILL(1); -+ -+ /* 3. Frame Formation - (1) Category */ -+ *pPkt = TDLS_FRM_CATEGORY; -+ LR_TDLS_FME_FIELD_FILL(1); -+ } else { -+ /* discovery response */ -+ WLAN_MAC_HEADER_T *prHdr; -+ -+ prMsduInfoMgmt = (MSDU_INFO_T *) -+ cnmMgtPktAlloc(prAdapter, PUBLIC_ACTION_MAX_LEN); -+ if (prMsduInfoMgmt == NULL) { -+ DBGLOG(TDLS, ERROR, " %s: allocate mgmt pkt fail\n", __func__); -+ return TDLS_STATUS_RESOURCES; -+ } -+ -+ pPkt = (UINT8 *) prMsduInfoMgmt->prPacket; -+ prHdr = (WLAN_MAC_HEADER_T *) pPkt; -+ -+ /* 1. 802.11 header */ -+ prHdr->u2FrameCtrl = MAC_FRAME_ACTION; -+ prHdr->u2DurationID = 0; -+ kalMemCopy(prHdr->aucAddr1, pPeerMac, TDLS_FME_MAC_ADDR_LEN); -+ kalMemCopy(prHdr->aucAddr2, prBssInfo->aucOwnMacAddr, TDLS_FME_MAC_ADDR_LEN); -+ kalMemCopy(prHdr->aucAddr3, prBssInfo->aucBSSID, TDLS_FME_MAC_ADDR_LEN); -+ prHdr->u2SeqCtrl = 0; -+ LR_TDLS_FME_FIELD_FILL(sizeof(WLAN_MAC_HEADER_T)); -+ -+ /* Frame Formation - (1) Category */ -+ *pPkt = CATEGORY_PUBLIC_ACTION; -+ LR_TDLS_FME_FIELD_FILL(1); -+ } -+ -+ /* 3. Frame Formation - (2) Action */ -+ *pPkt = ucActionCode; -+ LR_TDLS_FME_FIELD_FILL(1); -+ -+ /* 3. Frame Formation - Status Code */ -+ switch (ucActionCode) { -+ case TDLS_FRM_ACTION_SETUP_RSP: -+ case TDLS_FRM_ACTION_CONFIRM: -+ case TDLS_FRM_ACTION_TEARDOWN: -+ WLAN_SET_FIELD_16(pPkt, u2StatusCode); -+ LR_TDLS_FME_FIELD_FILL(2); -+ break; -+ } -+ -+ /* 3. Frame Formation - (3) Dialog token */ -+ if (ucActionCode != TDLS_FRM_ACTION_TEARDOWN) { -+ *pPkt = ucDialogToken; -+ LR_TDLS_FME_FIELD_FILL(1); -+ } -+ -+ /* Fill elements */ -+ if (ucActionCode != TDLS_FRM_ACTION_TEARDOWN) { -+ /* -+ Capability -+ -+ Support Rates -+ Extended Support Rates -+ Supported Channels -+ HT Capabilities -+ WMM Information Element -+ -+ Extended Capabilities -+ Link Identifier -+ -+ RSNIE -+ FTIE -+ Timeout Interval -+ */ -+ if (ucActionCode != TDLS_FRM_ACTION_CONFIRM) { -+ /* 3. Frame Formation - (4) Capability: 0x31 0x04, privacy bit will be set */ -+ u2CapInfo = assocBuildCapabilityInfo(prAdapter, prStaRec); -+ WLAN_SET_FIELD_16(pPkt, u2CapInfo); -+ LR_TDLS_FME_FIELD_FILL(2); -+ -+ /* 4. Append general IEs */ -+ /* -+ TODO check HT: prAdapter->rWifiVar.rConnSettings.uc2G4BandwidthMode -+ must be CONFIG_BW_20_40M. -+ -+ TODO check HT: HT_CAP_INFO_40M_INTOLERANT must be clear if -+ Tdls 20/40 is enabled. -+ */ -+ u4IeLen = TdlsFrameGeneralIeAppend(prAdapter, prStaRec, u2StatusCode, pPkt); -+ LR_TDLS_FME_FIELD_FILL(u4IeLen); -+ -+ /* 5. Frame Formation - Extended capabilities element */ -+ EXT_CAP_IE(pPkt)->ucId = ELEM_ID_EXTENDED_CAP; -+ EXT_CAP_IE(pPkt)->ucLength = 5; -+ -+ EXT_CAP_IE(pPkt)->aucCapabilities[0] = 0x00; /* bit0 ~ bit7 */ -+ EXT_CAP_IE(pPkt)->aucCapabilities[1] = 0x00; /* bit8 ~ bit15 */ -+ EXT_CAP_IE(pPkt)->aucCapabilities[2] = 0x00; /* bit16 ~ bit23 */ -+ EXT_CAP_IE(pPkt)->aucCapabilities[3] = 0x00; /* bit24 ~ bit31 */ -+ EXT_CAP_IE(pPkt)->aucCapabilities[4] = 0x00; /* bit32 ~ bit39 */ -+ -+ /* if (prCmd->ucExCap & TDLS_EX_CAP_PEER_UAPSD) */ -+ EXT_CAP_IE(pPkt)->aucCapabilities[3] |= BIT((28 - 24)); -+ /* if (prCmd->ucExCap & TDLS_EX_CAP_CHAN_SWITCH) */ -+ EXT_CAP_IE(pPkt)->aucCapabilities[3] |= BIT((30 - 24)); -+ /* if (prCmd->ucExCap & TDLS_EX_CAP_TDLS) */ -+ EXT_CAP_IE(pPkt)->aucCapabilities[4] |= BIT((37 - 32)); -+ -+ u4IeLen = IE_SIZE(pPkt); -+ LR_TDLS_FME_FIELD_FILL(u4IeLen); -+ } else { -+ /* 5. Frame Formation - WMM Parameter element */ -+ if (prAdapter->rWifiVar.fgSupportQoS) { -+ u4IeLen = mqmGenerateWmmParamIEByParam(prAdapter, -+ prBssInfo, pPkt, OP_MODE_INFRASTRUCTURE); -+ -+ LR_TDLS_FME_FIELD_FILL(u4IeLen); -+ } -+ } -+ } -+ -+ /* 6. Frame Formation - 20/40 BSS Coexistence */ -+ /* -+ Follow WiFi test plan, add 20/40 element to request/response/confirm. -+ */ -+/* if (prGlueInfo->rTdlsLink.fgIs2040Sup == TRUE) */ /* force to enable */ -+ if (ucActionCode != TDLS_FRM_ACTION_TEARDOWN) { -+ /* -+ bit0 = 1: The Information Request field is used to indicate that a -+ transmitting STA is requesting the recipient to transmit a 20/40 BSS -+ Coexistence Management frame with the transmitting STA as the -+ recipient. -+ -+ bit1 = 0: The Forty MHz Intolerant field is set to 1 to prohibit an AP -+ that receives this information or reports of this information from -+ operating a 20/40 MHz BSS. -+ -+ bit2 = 0: The 20 MHz BSS Width Request field is set to 1 to prohibit -+ a receiving AP from operating its BSS as a 20/40 MHz BSS. -+ */ -+ BSS_20_40_COEXIST_IE(pPkt)->ucId = ELEM_ID_20_40_BSS_COEXISTENCE; -+ BSS_20_40_COEXIST_IE(pPkt)->ucLength = 1; -+ BSS_20_40_COEXIST_IE(pPkt)->ucData = 0x01; -+ LR_TDLS_FME_FIELD_FILL(3); -+ } -+ -+ /* 6. Frame Formation - HT Operation element */ -+/* u4IeLen = rlmFillHtOpIeBody(prBssInfo, pPkt); */ -+/* LR_TDLS_FME_FIELD_FILL(u4IeLen); */ -+ -+ /* 7. Frame Formation - Link identifier element */ -+ /* Note1: Link ID sequence must be correct; Or the calculated MIC will be error */ -+ /* -+ Note2: When we receive a setup request with link ID, Marvell will send setup response -+ to the peer in link ID, not the SA in the WLAN header. -+ */ -+ TDLS_LINK_IDENTIFIER_IE(pPkt)->ucId = ELEM_ID_LINK_IDENTIFIER; -+ TDLS_LINK_IDENTIFIER_IE(pPkt)->ucLength = ELEM_LEN_LINK_IDENTIFIER; -+ -+ kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aBSSID, prBssInfo->aucBSSID, 6); -+ -+ switch (ucActionCode) { -+ case TDLS_FRM_ACTION_SETUP_REQ: -+ case TDLS_FRM_ACTION_CONFIRM: -+ default: -+ /* we are initiator */ -+ pucInitiator = prBssInfo->aucOwnMacAddr; -+ pucResponder = pPeerMac; -+ -+ if (prStaRec != NULL) -+ prStaRec->flgTdlsIsInitiator = TRUE; -+ break; -+ -+ case TDLS_FRM_ACTION_SETUP_RSP: -+ case TDLS_FRM_ACTION_DISCOVERY_RESPONSE: -+ /* peer is initiator */ -+ pucInitiator = pPeerMac; -+ pucResponder = prBssInfo->aucOwnMacAddr; -+ -+ if (prStaRec != NULL) -+ prStaRec->flgTdlsIsInitiator = FALSE; -+ break; -+ -+ case TDLS_FRM_ACTION_TEARDOWN: -+ if (prStaRec != NULL) { -+ if (prStaRec->flgTdlsIsInitiator == TRUE) { -+ /* we are initiator */ -+ pucInitiator = prBssInfo->aucOwnMacAddr; -+ pucResponder = pPeerMac; -+ } else { -+ /* peer is initiator */ -+ pucInitiator = pPeerMac; -+ pucResponder = prBssInfo->aucOwnMacAddr; -+ } -+ } else { -+ /* peer is initiator */ -+ pucInitiator = pPeerMac; -+ pucResponder = prBssInfo->aucOwnMacAddr; -+ } -+ break; -+ } -+ -+ kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aInitiator, pucInitiator, 6); -+ kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aResponder, pucResponder, 6); -+ -+ u4IeLen = IE_SIZE(pPkt); -+ LR_TDLS_FME_FIELD_FILL(u4IeLen); -+ -+ /* 8. Append security IEs */ -+ /* -+ 11.21.5 TDLS Direct Link Teardown -+ If the STA has security enabled on the link 37 with the AP, then the FTIE shall be -+ included in the TDLS Teardown frame. -+ -+ For ralink station, it can accept our tear down without FTIE but marvell station. -+ */ -+/* if ((ucActionCode != TDLS_FRM_ACTION_TEARDOWN) && (pAppendIe != NULL)) */ -+ if (pAppendIe != NULL) { -+ if ((ucActionCode != TDLS_FRM_ACTION_TEARDOWN) || -+ ((ucActionCode == TDLS_FRM_ACTION_TEARDOWN) && -+ (prStaRec != NULL) && (prStaRec->fgTdlsInSecurityMode == TRUE))) { -+ kalMemCopy(pPkt, pAppendIe, AppendIeLen); -+ LR_TDLS_FME_FIELD_FILL(AppendIeLen); -+ } -+ } -+ -+ /* 7. Append Supported Operating Classes IE */ -+ if (ucActionCode != TDLS_FRM_ACTION_TEARDOWN) { -+ /* Note: if we do not put the IE, Marvell STA will decline our TDLS setup request */ -+ u4IeLen = rlmDomainSupOperatingClassIeFill(pPkt); -+ LR_TDLS_FME_FIELD_FILL(u4IeLen); -+ } -+ -+ /* 11. send the data or management frame */ -+ if (ucActionCode != TDLS_FRM_ACTION_DISCOVERY_RESPONSE) { -+#if 0 -+ /* -+ Note1: remember to modify our MAC & AP MAC & peer MAC in LINK ID -+ Note2: dialog token in rsp & confirm must be same as sender. -+ */ -+ -+#if 1 -+ /* example for Ralink's and Broadcom's TDLS setup request frame in open/none */ -+ if (ucActionCode == TDLS_FRM_ACTION_SETUP_REQ) { -+#if 0 -+ /* mediatek */ -+ char buffer[] = { 0x31, 0x04, -+ 0x01, 0x08, 0x02, 0x04, 0x0b, 0x16, 0xc, 0x12, 0x18, 0x24, -+ 0x32, 0x04, 0x30, 0x48, 0x60, 0x6c, -+ 0x24, 0x0a, 0x01, 0x0b, 0x24, 0x04, 0x34, 0x04, 0x95, 0x04, 0xa5, 0x01, -+ 0x2d, 0x1a, 0x72, 0x11, 0x03, 0xff, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, -+ 0xdd, 0x07, 0x00, 0x50, 0xf2, 0x02, 0x00, 0x01, 0x0f, -+ 0x7f, 0x05, 0x00, 0x00, 0x00, 0x50, 0x20, -+ 0x48, 0x01, 0x01, -+ 0x65, 0x12, 0x00, 0x0c, 0x43, 0x31, 0x35, 0x97, 0x00, 0x11, 0x22, 0x33, -+ 0x44, 0x05, 0x00, 0x22, 0x58, 0x00, 0xcc, 0x0f, -+ 0x3b, 0x0d, 0x0c, 0x01, 0x02, 0x03, 0x05, 0x16, 0x17, 0x19, -+ 0x1b, 0x1c, 0x1e, 0x20, 0x21, -+ 0x07, 0x06, 0x55, 0x53, 0x20, 0x01, 0x0b, 0x1e -+ }; -+#endif -+ -+#if 1 -+ /* ralink *//* from capability */ -+ char buffer[] = { 0x21, 0x04, -+ 0x01, 0x08, 0x82, 0x84, 0x8b, 0x96, 0x12, 0x24, 0x48, 0x6c, -+ 0x07, 0x06, 0x55, 0x53, 0x20, 0xdd, 0x20, 0x00, -+ 0x32, 0x04, 0x0c, 0x18, 0x30, 0x60, -+ 0x24, 0x06, 0x01, 0x0b, 0x24, 0x08, 0x95, 0x04, -+ 0x7f, 0x05, 0x01, 0x00, 0x00, 0x50, 0x20, -+ 0x3b, 0x10, 0x20, 0x01, 0x02, 0x03, 0x04, 0x0c, 0x16, 0x17, 0x18, 0x19, -+ 0x1b, 0x1c, 0x1d, 0x1e, 0x20, 0x21, -+ 0x2d, 0x1a, 0x6e, 0x00, 0x17, 0xff, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, -+ 0x00, 0x00, 0x00, 0x00, -+ 0x48, 0x01, 0x01, -+ 0x65, 0x12, 0x00, 0x0c, 0x43, 0x44, 0x0b, 0x1a, 0x00, 0x11, 0x22, 0x33, -+ 0x44, 0x05, 0x00, 0x22, 0x58, 0x00, 0xcc, 0x0f, -+ 0xdd, 0x07, 0x00, 0x50, 0xf2, 0x02, 0x00, 0x01, 0x0f -+ }; -+#endif -+#if 0 -+ /* 6630 */ -+ char buffer[] = { 0x01, 0x01, -+ 0x01, 0x04, 0x02, 0x04, 0x0b, 0x16, -+ 0x24, 0x02, 0x01, 0x0d, -+ 0x7f, 0x05, 0x00, 0x00, 0x00, 0x50, 0xff, -+ 0x2d, 0x1a, 0x61, 0x01, 0x03, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, -+ 0x38, 0x05, 0x02, 0xc0, 0xa8, 0x00, 0x00, -+ 0x48, 0x01, 0x01, -+ 0x3b, 0x0d, 0x0c, 0x01, 0x02, 0x03, 0x05, 0x16, 0x17, 0x19, -+ 0x1b, 0x1c, 0x1d, 0x1e, 0x20, 0x21, -+ 0x07, 0x06, 0x55, 0x53, 0x20, 0x01, 0x0b, 0x1e, -+ 0x65, 0x12, 0x00, 0x0c, 0x43, 0x44, 0x0b, 0x1a, 0x00, 0x11, 0x22, 0x33, -+ 0x44, 0x05, 0x00, 0x22, 0x58, 0x00, 0xcc, 0x0f, -+ 0xdd, 0x18, 0x00, 0x50, 0xf2, 0x02, 0x01, 0x01, 0x80, 0x01, 0x00, 0x00, -+ 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x60, -+ 0x00, 0x00, 0x00, -+ 0xbf, 0x0c, 0x30, 0x01, 0x80, 0x03, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, -+ 0x00, 0x00 -+ }; -+#endif -+ -+ pPktTemp += 18; -+ memcpy(pPktTemp, buffer, sizeof(buffer)); -+ u4PktLen = 18 + sizeof(buffer); -+ } -+#endif -+ -+#if 1 -+ if (ucActionCode == TDLS_FRM_ACTION_CONFIRM) { -+ /* Note: dialog token must be same as request */ -+#if 1 -+ /* ralink */ -+ char buffer[] = { 0x00, -+ 0x01, 0x2d, 0x1a, 0x6e, 0x00, 0x17, 0xff, 0x00, 0x00, 0x00, -+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x65, 0x12, 0x00, 0x0c, 0x43, 0x44, 0x0b, 0x1a, 0x00, 0x11, 0x22, 0x33, -+ 0x44, 0x05, 0x00, 0x22, 0x58, 0x00, 0xcc, 0x0f, -+ 0xdd, 0x18, 0x00, 0x50, 0xf2, 0x02, 0x01, 0x01, 0x0f, 0x00, 0x03, -+ 0xa4, 0x00, 0x00, 0x27, 0xa4, 0x00, 0x00, 0x42, 0x43, 0x5e, 0x00, -+ 0x62, 0x32, 0x2f, 0x00 -+ }; -+#endif -+ -+#if 0 -+ /* 6630 */ -+ char buffer[] = { 0x00, -+ 0x01, -+ 0x38, 0x05, 0x02, 0xc0, 0xa8, 0x00, 0x00, -+ 0x48, 0x01, 0x01, -+ 0x3b, 0x0d, 0x0c, 0x01, 0x02, 0x03, 0x05, 0x16, 0x17, 0x19, -+ 0x1b, 0x1c, 0x1d, 0x1e, 0x20, 0x21, -+ 0x07, 0x06, 0x55, 0x53, 0x20, 0x01, 0x0b, 0x1e, -+ 0x65, 0x12, 0x00, 0x0c, 0x43, 0x44, 0x0b, 0x1a, 0x00, 0x11, 0x22, 0x33, -+ 0x44, 0x05, 0x00, 0x22, 0x58, 0x00, 0xcc, 0x0f, -+ 0xdd, 0x07, 0x00, 0x50, 0xf2, 0x02, 0x00, 0x01, 0x00, -+ 0xdd, 0x18, 0x00, 0x50, 0xf2, 0x02, 0x01, 0x01, 0x80, 0x3f, 0x00, 0x00, -+ 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x60, -+ 0x00, 0x00, 0x00 -+ }; -+#endif -+ -+#if 0 -+ /* A/D die */ -+ char buffer[] = { 0x00, -+ 0x01, -+ 0xdd, 0x18, 0x00, 0x50, 0xf2, 0x02, 0x01, 0x01, 0x0f, 0x6b, 0x00, 0x00, -+ 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x60, -+ 0x00, 0x00, 0x00 0x65, 0x12, 0x00, 0x0c, 0x43, 0x31, 0x35, 0x97, 0x00, 0x11, 0x22, 0x33, -+ 0x44, 0x05, 0x00, 0x22, 0x58, 0x00, 0xcc, 0x0f, -+ 0x38, 0x0d, 0x0c, 0x01, 0x02, 0x03, 0x05, 0x16, 0x17, 0x19, 0x1b, -+ 0x1c, 0x1e, 0x20, 0x21, -+ 0x07, 0x06, 0x55, 0x53, 0x20, 0x01, 0x0b, 0x1e -+ }; -+#endif -+ -+ pPktTemp += 18; -+ memcpy(pPktTemp, buffer, sizeof(buffer)); -+ u4PktLen = 18 + sizeof(buffer); -+ } -+#endif -+ -+#else -+ -+#if 0 -+ /* for test in open/none */ -+ if (ucActionCode == TDLS_FRM_ACTION_SETUP_REQ) { -+ char buffer[] = { 0x01, 0x04, -+ 0x01, 0x08, 0x82, 0x84, 0x8b, 0x96, 0x12, 0x24, 0x48, 0x6c, -+ 0x07, 0x06, 0x55, 0x53, 0x20, 0xdd, 0x20, 0x00, -+ 0x32, 0x04, 0x30, 0x48, 0x60, 0x6c, -+ 0x24, 0x0a, 0x01, 0x0b, 0x24, 0x04, 0x34, 0x04, 0x95, 0x04, 0xa5, 0x01, -+ 0x2d, 0x1a, 0x72, 0x11, 0x03, 0xff, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, -+ 0xdd, 0x07, 0x00, 0x50, 0xf2, 0x02, 0x00, 0x01, 0x0f, -+ 0x7f, 0x05, 0x00, 0x00, 0x00, 0x50, 0x20, -+ 0x48, 0x01, 0x01, -+ 0x65, 0x12, 0x00, 0x0c, 0x43, 0x44, 0x0b, 0x1a, 0x00, 0x11, 0x22, 0x33, -+ 0x44, 0x05, 0x00, 0x22, 0x58, 0x00, 0xcc, 0x0f, -+ 0x3b, 0x0d, 0x0c, 0x01, 0x02, 0x03, 0x05, 0x16, 0x17, 0x19, -+ 0x1b, 0x1c, 0x1e, 0x20, 0x21 -+ }; -+ -+ pPktTemp += 18; -+ memcpy(pPktTemp, buffer, sizeof(buffer)); -+ u4PktLen = 18 + sizeof(buffer); -+ } -+#endif -+#endif /* 0 */ -+ -+ /* 9. Update packet length */ -+ prMsduInfo->len = u4PktLen; -+ dumpMemory8(prMsduInfo->data, u4PktLen); -+ -+ wlanHardStartXmit(prMsduInfo, prMsduInfo->dev); -+ } else { -+ /* -+ A TDLS capable STA that receives a TDLS Discovery Request frame is required to -+ send the response "to the requesting STA, via the direct path." -+ However, prior to establishment of the direct link, the responding STA may not -+ know the rate capabilities of the requesting STA. In this case, the responding -+ STA shall send the TDLS Discovery Response frame using a rate from the -+ BSSBasicRateSet of the BSS to which the STA is currently associated. -+ */ -+ prMsduInfoMgmt->ucPacketType = HIF_TX_PACKET_TYPE_MGMT; -+ prMsduInfoMgmt->ucStaRecIndex = prBssInfo->prStaRecOfAP->ucIndex; -+ prMsduInfoMgmt->ucNetworkType = prBssInfo->ucNetTypeIndex; -+ prMsduInfoMgmt->ucMacHeaderLength = WLAN_MAC_MGMT_HEADER_LEN; -+ prMsduInfoMgmt->fgIs802_1x = FALSE; -+ prMsduInfoMgmt->fgIs802_11 = TRUE; -+ prMsduInfoMgmt->u2FrameLength = u4PktLen; -+ prMsduInfoMgmt->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter); -+ prMsduInfoMgmt->pfTxDoneHandler = NULL; -+ prMsduInfoMgmt->fgIsBasicRate = TRUE; /* use basic rate */ -+ -+ /* Send them to HW queue */ -+ nicTxEnqueueMsdu(prAdapter, prMsduInfoMgmt); -+ } -+ -+ return TDLS_STATUS_SUCCESS; -+} -+ -+#endif /* CFG_SUPPORT_TDLS */ -+ -+ /* End of tdls_com.c */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/wapi.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/wapi.c -new file mode 100644 -index 000000000000..af66ef95d17c ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/wapi.c -@@ -0,0 +1,491 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/wapi.c#1 -+*/ -+ -+/*! \file "wapi.c" -+ \brief This file including the WAPI related function. -+ -+ This file provided the macros and functions library support the wapi ie parsing, -+ cipher and AKM check to help the AP seleced deciding. -+*/ -+ -+/* -+** Log: wapi.c -+** -+** 10 24 2012 wh.su -+** [ALPS00376392] [klocwork 9.1] in wapi.c, line 344 -+** Use MAX_NUM_SUPPORTED_WAPI_AKM_SUITESfor avoid Klocwork warning. -+** -+** 10 24 2012 wh.su -+** [ALPS00376391] [klocwork 9.1] in wapi.c, line 311 -+** Use the MAX_NUM_SUPPORTED_WAPI_CIPHER_SUITES for avoid Klccwork waring. -+ * -+ * 11 10 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * change the debug module level. -+ * -+ * 10 20 2010 wh.su -+ * [WCXRP00000067] [MT6620 Wi-Fi][Driver] Support the android+ WAPI function -+ * fixed the network type -+ * -+ * 09 01 2010 wh.su -+ * NULL -+ * adding the wapi support for integration test. -+ * -+ * 07 20 2010 wh.su -+ * -+ * . -+ * -+ * 04 06 2010 wh.su -+ * [BORA00000680][MT6620] Support the statistic for Micxxsoft os query -+ * fixed the firmware return the broadcast frame at wrong tc. -+ * -+ * 03 03 2010 wh.su -+ * [BORA00000637][MT6620 Wi-Fi] [Bug] WPA2 pre-authentication timer not correctly initialize -+ * move the AIS specific variable for security to AIS specific structure. -+ * -+ * 12 18 2009 cm.chang -+ * [BORA00000018]Integrate WIFI part into BORA for the 1st time -+ * . -+ * -+ * Dec 8 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * adding the function to check and update the default wapi tx -+ * -+ * Dec 7 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * adding the generate wapi ie function, and replace the tabe by space -+ * -+ * Nov 23 2009 mtk01088 -+ * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code -+ * -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+#include "precomp.h" -+#if CFG_SUPPORT_WAPI -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* -+* \brief This routine is called to generate WPA IE for -+* associate request frame. -+* -+* \param[in] prCurrentBss The Selected BSS description -+* -+* \retval The append WPA IE length -+* -+* \note -+* Called by: AIS module, Associate request -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID wapiGenerateWAPIIE(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo) -+{ -+ PUINT_8 pucBuffer; -+ -+ ASSERT(prAdapter); -+ ASSERT(prMsduInfo); -+ -+ if (prMsduInfo->ucNetworkType != NETWORK_TYPE_AIS_INDEX) -+ return; -+ -+ pucBuffer = (PUINT_8) ((ULONG) prMsduInfo->prPacket + prMsduInfo->u2FrameLength); -+ -+ /* ASSOC INFO IE ID: 68 :0x44 */ -+ if (/* prWlanInfo->fgWapiMode && */ prAdapter->prGlueInfo->u2WapiAssocInfoIESz) { -+ kalMemCopy(pucBuffer, &prAdapter->prGlueInfo->aucWapiAssocInfoIEs, -+ prAdapter->prGlueInfo->u2WapiAssocInfoIESz); -+ prMsduInfo->u2FrameLength += prAdapter->prGlueInfo->u2WapiAssocInfoIESz; -+ } -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to parse WAPI IE. -+* -+* \param[in] prInfoElem Pointer to the RSN IE -+* \param[out] prRsnInfo Pointer to the BSSDescription structure to store the -+** WAPI information from the given WAPI IE -+* -+* \retval TRUE - Succeeded -+* \retval FALSE - Failed -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN wapiParseWapiIE(IN P_WAPI_INFO_ELEM_T prInfoElem, OUT P_WAPI_INFO_T prWapiInfo) -+{ -+ UINT_32 i; -+ INT_32 u4RemainWapiIeLen; -+ UINT_16 u2Version; -+ UINT_16 u2Cap = 0; -+ UINT_32 u4GroupSuite = WAPI_CIPHER_SUITE_WPI; -+ UINT_16 u2PairSuiteCount = 0; -+ UINT_16 u2AuthSuiteCount = 0; -+ PUCHAR pucPairSuite = NULL; -+ PUCHAR pucAuthSuite = NULL; -+ PUCHAR cp; -+ -+ DEBUGFUNC("wapiParseWapiIE"); -+ -+ ASSERT(prInfoElem); -+ ASSERT(prWapiInfo); -+ -+ /* Verify the length of the WAPI IE. */ -+ if (prInfoElem->ucLength < 6) { -+ DBGLOG(SEC, TRACE, "WAPI IE length too short (length=%d)\n", prInfoElem->ucLength); -+ return FALSE; -+ } -+ -+ /* Check WAPI version: currently, we only support version 1. */ -+ WLAN_GET_FIELD_16(&prInfoElem->u2Version, &u2Version); -+ if (u2Version != 1) { -+ DBGLOG(SEC, TRACE, "Unsupported WAPI IE version: %d\n", u2Version); -+ return FALSE; -+ } -+ -+ cp = (PUCHAR) &prInfoElem->u2AuthKeyMgtSuiteCount; -+ u4RemainWapiIeLen = (INT_32) prInfoElem->ucLength - 2; -+ -+ do { -+ if (u4RemainWapiIeLen == 0) -+ break; -+ -+ /* -+ AuthCount : 2 -+ AuthSuite : 4 * authSuiteCount -+ PairwiseCount: 2 -+ PairwiseSuite: 4 * pairSuiteCount -+ GroupSuite : 4 -+ Cap : 2 */ -+ -+ /* Parse the Authentication and Key Management Cipher Suite Count -+ field. */ -+ if (u4RemainWapiIeLen < 2) { -+ DBGLOG(SEC, TRACE, "Fail to parse WAPI IE in auth & key mgt suite count (IE len: %d)\n", -+ prInfoElem->ucLength); -+ return FALSE; -+ } -+ -+ WLAN_GET_FIELD_16(cp, &u2AuthSuiteCount); -+ cp += 2; -+ u4RemainWapiIeLen -= 2; -+ -+ /* Parse the Authentication and Key Management Cipher Suite List -+ field. */ -+ i = (UINT_32) u2AuthSuiteCount * 4; -+ if (u4RemainWapiIeLen < (INT_32) i) { -+ DBGLOG(SEC, TRACE, "Fail to parse WAPI IE in auth & key mgt suite list (IE len: %d)\n", -+ prInfoElem->ucLength); -+ return FALSE; -+ } -+ -+ pucAuthSuite = cp; -+ -+ cp += i; -+ u4RemainWapiIeLen -= (INT_32) i; -+ -+ if (u4RemainWapiIeLen == 0) -+ break; -+ -+ /* Parse the Pairwise Key Cipher Suite Count field. */ -+ if (u4RemainWapiIeLen < 2) { -+ DBGLOG(SEC, TRACE, "Fail to parse WAPI IE in pairwise cipher suite count (IE len: %d)\n", -+ prInfoElem->ucLength); -+ return FALSE; -+ } -+ -+ WLAN_GET_FIELD_16(cp, &u2PairSuiteCount); -+ cp += 2; -+ u4RemainWapiIeLen -= 2; -+ -+ /* Parse the Pairwise Key Cipher Suite List field. */ -+ i = (UINT_32) u2PairSuiteCount * 4; -+ if (u4RemainWapiIeLen < (INT_32) i) { -+ DBGLOG(SEC, TRACE, "Fail to parse WAPI IE in pairwise cipher suite list (IE len: %d)\n", -+ prInfoElem->ucLength); -+ return FALSE; -+ } -+ -+ pucPairSuite = cp; -+ -+ cp += i; -+ u4RemainWapiIeLen -= (INT_32) i; -+ -+ /* Parse the Group Key Cipher Suite field. */ -+ if (u4RemainWapiIeLen < 4) { -+ DBGLOG(SEC, TRACE, "Fail to parse WAPI IE in group cipher suite (IE len: %d)\n", -+ prInfoElem->ucLength); -+ return FALSE; -+ } -+ -+ WLAN_GET_FIELD_32(cp, &u4GroupSuite); -+ cp += 4; -+ u4RemainWapiIeLen -= 4; -+ -+ /* Parse the WAPI u2Capabilities field. */ -+ if (u4RemainWapiIeLen < 2) { -+ DBGLOG(SEC, TRACE, "Fail to parse WAPI IE in WAPI capabilities (IE len: %d)\n", -+ prInfoElem->ucLength); -+ return FALSE; -+ } -+ -+ WLAN_GET_FIELD_16(cp, &u2Cap); -+ u4RemainWapiIeLen -= 2; -+ -+ /* Todo:: BKID support */ -+ } while (FALSE); -+ -+ /* Save the WAPI information for the BSS. */ -+ -+ prWapiInfo->ucElemId = ELEM_ID_WAPI; -+ -+ prWapiInfo->u2Version = u2Version; -+ -+ prWapiInfo->u4GroupKeyCipherSuite = u4GroupSuite; -+ -+ DBGLOG(SEC, LOUD, "WAPI: version %d, group key cipher suite %02x-%02x-%02x-%02x\n", -+ u2Version, (UCHAR) (u4GroupSuite & 0x000000FF), -+ (UCHAR) ((u4GroupSuite >> 8) & 0x000000FF), -+ (UCHAR) ((u4GroupSuite >> 16) & 0x000000FF), (UCHAR) ((u4GroupSuite >> 24) & 0x000000FF)); -+ -+ if (pucPairSuite) { -+ /* The information about the pairwise key cipher suites is present. */ -+ if (u2PairSuiteCount > MAX_NUM_SUPPORTED_WAPI_CIPHER_SUITES) -+ u2PairSuiteCount = MAX_NUM_SUPPORTED_WAPI_CIPHER_SUITES; -+ -+ prWapiInfo->u4PairwiseKeyCipherSuiteCount = (UINT_32) u2PairSuiteCount; -+ -+ for (i = 0; i < (UINT_32) u2PairSuiteCount; i++) { -+ WLAN_GET_FIELD_32(pucPairSuite, &prWapiInfo->au4PairwiseKeyCipherSuite[i]); -+ pucPairSuite += 4; -+ -+ DBGLOG(SEC, LOUD, "WAPI: pairwise key cipher suite [%d]: %02x-%02x-%02x-%02x\n", -+ (UINT_8) i, (UCHAR) (prWapiInfo->au4PairwiseKeyCipherSuite[i] & 0x000000FF), -+ (UCHAR) ((prWapiInfo->au4PairwiseKeyCipherSuite[i] >> 8) & 0x000000FF), -+ (UCHAR) ((prWapiInfo->au4PairwiseKeyCipherSuite[i] >> 16) & 0x000000FF), -+ (UCHAR) ((prWapiInfo->au4PairwiseKeyCipherSuite[i] >> 24) & 0x000000FF)); -+ } -+ } else { -+ /* The information about the pairwise key cipher suites is not present. -+ Use the default chipher suite for WAPI: WPI. */ -+ prWapiInfo->u4PairwiseKeyCipherSuiteCount = 1; -+ prWapiInfo->au4PairwiseKeyCipherSuite[0] = WAPI_CIPHER_SUITE_WPI; -+ -+ DBGLOG(SEC, LOUD, "WAPI: pairwise key cipher suite: %02x-%02x-%02x-%02x (default)\n", -+ (UCHAR) (prWapiInfo->au4PairwiseKeyCipherSuite[0] & 0x000000FF), -+ (UCHAR) ((prWapiInfo->au4PairwiseKeyCipherSuite[0] >> 8) & 0x000000FF), -+ (UCHAR) ((prWapiInfo->au4PairwiseKeyCipherSuite[0] >> 16) & 0x000000FF), -+ (UCHAR) ((prWapiInfo->au4PairwiseKeyCipherSuite[0] >> 24) & 0x000000FF)); -+ } -+ -+ if (pucAuthSuite) { -+ /* The information about the authentication and key management suites -+ is present. */ -+ if (u2AuthSuiteCount > MAX_NUM_SUPPORTED_WAPI_AKM_SUITES) -+ u2AuthSuiteCount = MAX_NUM_SUPPORTED_WAPI_AKM_SUITES; -+ -+ prWapiInfo->u4AuthKeyMgtSuiteCount = (UINT_32) u2AuthSuiteCount; -+ -+ for (i = 0; i < (UINT_32) u2AuthSuiteCount; i++) { -+ WLAN_GET_FIELD_32(pucAuthSuite, &prWapiInfo->au4AuthKeyMgtSuite[i]); -+ pucAuthSuite += 4; -+ -+ DBGLOG(SEC, LOUD, "WAPI: AKM suite [%d]: %02x-%02x-%02x-%02x\n", -+ (UINT_8) i, (UCHAR) (prWapiInfo->au4AuthKeyMgtSuite[i] & 0x000000FF), -+ (UCHAR) ((prWapiInfo->au4AuthKeyMgtSuite[i] >> 8) & 0x000000FF), -+ (UCHAR) ((prWapiInfo->au4AuthKeyMgtSuite[i] >> 16) & 0x000000FF), -+ (UCHAR) ((prWapiInfo->au4AuthKeyMgtSuite[i] >> 24) & 0x000000FF)); -+ } -+ } else { -+ /* The information about the authentication and key management suites -+ is not present. Use the default AKM suite for WAPI. */ -+ prWapiInfo->u4AuthKeyMgtSuiteCount = 1; -+ prWapiInfo->au4AuthKeyMgtSuite[0] = WAPI_AKM_SUITE_802_1X; -+ -+ DBGLOG(SEC, LOUD, "WAPI: AKM suite: %02x-%02x-%02x-%02x (default)\n", -+ (UCHAR) (prWapiInfo->au4AuthKeyMgtSuite[0] & 0x000000FF), -+ (UCHAR) ((prWapiInfo->au4AuthKeyMgtSuite[0] >> 8) & 0x000000FF), -+ (UCHAR) ((prWapiInfo->au4AuthKeyMgtSuite[0] >> 16) & 0x000000FF), -+ (UCHAR) ((prWapiInfo->au4AuthKeyMgtSuite[0] >> 24) & 0x000000FF)); -+ } -+ -+ prWapiInfo->u2WapiCap = u2Cap; -+ DBGLOG(SEC, LOUD, "WAPI: cap: 0x%04x\n", prWapiInfo->u2WapiCap); -+ -+ return TRUE; -+} /* wapiParseWapiIE */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to perform WAPI policy selection for a given BSS. -+* -+* \param[in] prAdapter Pointer to the adapter object data area. -+* \param[in] prBss Pointer to the BSS description -+* -+* \retval TRUE - The WAPI policy selection for the given BSS is -+* successful. The selected pairwise and group cipher suites -+* are returned in the BSS description. -+* \retval FALSE - The WAPI policy selection for the given BSS is failed. -+* The driver shall not attempt to join the given BSS. -+* -+* \note The Encrypt status matched score will save to bss for final ap select. -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN wapiPerformPolicySelection(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBss) -+{ -+ UINT_32 i; -+ UINT_32 u4PairwiseCipher = 0; -+ UINT_32 u4GroupCipher = 0; -+ UINT_32 u4AkmSuite = 0; -+ P_WAPI_INFO_T prBssWapiInfo; -+ P_WLAN_INFO_T prWlanInfo; -+ -+ DEBUGFUNC("wapiPerformPolicySelection"); -+ -+ ASSERT(prBss); -+ -+ /* Notice!!!! WAPI AP not set the privacy bit for WAI and WAI-PSK at WZC configuration mode */ -+ prWlanInfo = &prAdapter->rWlanInfo; -+ -+ if (prBss->fgIEWAPI) { -+ prBssWapiInfo = &prBss->rIEWAPI; -+ } else { -+ if (prAdapter->rWifiVar.rConnSettings.fgWapiMode == FALSE) { -+ DBGLOG(SEC, TRACE, "-- No Protected BSS\n"); -+ return TRUE; -+ } -+ DBGLOG(SEC, TRACE, "WAPI Information Element does not exist.\n"); -+ return FALSE; -+ } -+ -+ /* Select pairwise/group ciphers */ -+ for (i = 0; i < prBssWapiInfo->u4PairwiseKeyCipherSuiteCount; i++) { -+ if (prBssWapiInfo->au4PairwiseKeyCipherSuite[i] == -+ prAdapter->rWifiVar.rConnSettings.u4WapiSelectedPairwiseCipher) { -+ u4PairwiseCipher = prBssWapiInfo->au4PairwiseKeyCipherSuite[i]; -+ } -+ } -+ if (prBssWapiInfo->u4GroupKeyCipherSuite == prAdapter->rWifiVar.rConnSettings.u4WapiSelectedGroupCipher) -+ u4GroupCipher = prBssWapiInfo->u4GroupKeyCipherSuite; -+ -+ /* Exception handler */ -+ /* If we cannot find proper pairwise and group cipher suites to join the -+ BSS, do not check the supported AKM suites. */ -+ if (u4PairwiseCipher == 0 || u4GroupCipher == 0) { -+ DBGLOG(SEC, TRACE, "Failed to select pairwise/group cipher (0x%08x/0x%08x)\n", -+ u4PairwiseCipher, u4GroupCipher); -+ return FALSE; -+ } -+ -+ /* Select AKM */ -+ /* If the driver cannot support any authentication suites advertised in -+ the given BSS, we fail to perform RSNA policy selection. */ -+ /* Attempt to find any overlapping supported AKM suite. */ -+ for (i = 0; i < prBssWapiInfo->u4AuthKeyMgtSuiteCount; i++) { -+ if (prBssWapiInfo->au4AuthKeyMgtSuite[i] == prAdapter->rWifiVar.rConnSettings.u4WapiSelectedAKMSuite) { -+ u4AkmSuite = prBssWapiInfo->au4AuthKeyMgtSuite[i]; -+ break; -+ } -+ } -+ -+ if (u4AkmSuite == 0) { -+ DBGLOG(SEC, TRACE, "Cannot support any AKM suites\n"); -+ return FALSE; -+ } -+ -+ DBGLOG(SEC, TRACE, "Selected pairwise/group cipher: %02x-%02x-%02x-%02x/%02x-%02x-%02x-%02x\n", -+ (UINT_8) (u4PairwiseCipher & 0x000000FF), -+ (UINT_8) ((u4PairwiseCipher >> 8) & 0x000000FF), -+ (UINT_8) ((u4PairwiseCipher >> 16) & 0x000000FF), -+ (UINT_8) ((u4PairwiseCipher >> 24) & 0x000000FF), -+ (UINT_8) (u4GroupCipher & 0x000000FF), -+ (UINT_8) ((u4GroupCipher >> 8) & 0x000000FF), -+ (UINT_8) ((u4GroupCipher >> 16) & 0x000000FF), -+ (UINT_8) ((u4GroupCipher >> 24) & 0x000000FF)); -+ -+ DBGLOG(SEC, TRACE, "Selected AKM suite: %02x-%02x-%02x-%02x\n", -+ (UINT_8) (u4AkmSuite & 0x000000FF), -+ (UINT_8) ((u4AkmSuite >> 8) & 0x000000FF), -+ (UINT_8) ((u4AkmSuite >> 16) & 0x000000FF), (UINT_8) ((u4AkmSuite >> 24) & 0x000000FF)); -+ -+ return TRUE; -+} /* wapiPerformPolicySelection */ -+ -+#if 0 -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is use for wapi mode, to update the current wpi tx idx ? 0 :1 . -+* -+* \param[in] prStaRec Pointer to the Sta record -+* \param[out] ucWlanIdx The Rx status->wlanidx field -+* -+* \retval TRUE - Succeeded -+* \retval FALSE - Failed -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN wapiUpdateTxKeyIdx(IN P_STA_RECORD_T prStaRec, IN UINT_8 ucWlanIdx) -+{ -+ UINT_8 ucKeyId; -+ -+ if ((ucWlanIdx & BITS(0, 3)) == CIPHER_SUITE_WPI) { -+ -+ ucKeyId = ((ucWlanIdx & BITS(4, 5)) >> 4); -+ -+ if (ucKeyId != g_prWifiVar->rAisSpecificBssInfo.ucWpiActivedPWKey) { -+ DBGLOG(RSN, STATE, -+ "Change wapi key index from %d->%d\n", -+ g_prWifiVar->rAisSpecificBssInfo.ucWpiActivedPWKey, ucKeyId); -+ g_prWifiVar->rAisSpecificBssInfo.ucWpiActivedPWKey = ucKeyId; -+ -+ prStaRec->ucWTEntry = -+ (ucKeyId == -+ WTBL_AIS_BSSID_WAPI_IDX_0) ? WTBL_AIS_BSSID_WAPI_IDX_0 : WTBL_AIS_BSSID_WAPI_IDX_1; -+ } -+ } -+} -+#endif -+#endif -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/wnm.c b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/wnm.c -new file mode 100644 -index 000000000000..f54d22941148 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/mgmt/wnm.c -@@ -0,0 +1,301 @@ -+/* -+** Id: //Department/DaVinci/TRUNK/MT6620_5931_WiFi_Driver/mgmt/wnm.c#1 -+*/ -+ -+/*! \file "wnm.c" -+ \brief This file includes the 802.11v default vale and functions. -+*/ -+ -+/* -+** Log: wnm.c -+ * -+ * 01 05 2012 tsaiyuan.hsu -+ * [WCXRP00001157] [MT6620 Wi-Fi][FW][DRV] add timing measurement support for 802.11v -+ * add timing measurement support for 802.11v. -+ * -+ * -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "precomp.h" -+ -+#if CFG_SUPPORT_802_11V -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+#define WNM_MAX_TOD_ERROR 0 -+#define WNM_MAX_TOA_ERROR 0 -+#define MICRO_TO_10NANO(x) ((x)*100) -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+static UINT_8 ucTimingMeasToken; -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* -+* \brief This routine is called to process the 802.11v wnm category action frame. -+* -+* -+* \note -+* Called by: Handle Rx mgmt request -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID wnmWNMAction(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb) -+{ -+ P_WLAN_ACTION_FRAME prRxFrame; -+ -+ ASSERT(prAdapter); -+ ASSERT(prSwRfb); -+ -+ prRxFrame = (P_WLAN_ACTION_FRAME) prSwRfb->pvHeader; -+ -+#if CFG_SUPPORT_802_11V_TIMING_MEASUREMENT -+ if (prRxFrame->ucAction == ACTION_WNM_TIMING_MEASUREMENT_REQUEST) { -+ wnmTimingMeasRequest(prAdapter, prSwRfb); -+ return; -+ } -+#endif -+ -+ DBGLOG(WNM, TRACE, "Unsupport WNM action frame: %d\n", prRxFrame->ucAction); -+} -+ -+#if CFG_SUPPORT_802_11V_TIMING_MEASUREMENT -+/*----------------------------------------------------------------------------*/ -+/*! -+* -+* \brief This routine is called to report timing measurement data. -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID wnmReportTimingMeas(IN P_ADAPTER_T prAdapter, IN UINT_8 ucStaRecIndex, IN UINT_32 u4ToD, IN UINT_32 u4ToA) -+{ -+ P_STA_RECORD_T prStaRec; -+ -+ prStaRec = cnmGetStaRecByIndex(prAdapter, ucStaRecIndex); -+ -+ if ((!prStaRec) || (!prStaRec->fgIsInUse)) -+ return; -+ -+ DBGLOG(WNM, TRACE, "wnmReportTimingMeas: u4ToD %x u4ToA %x", u4ToD, u4ToA); -+ -+ if (!prStaRec->rWNMTimingMsmt.ucTrigger) -+ return; -+ -+ prStaRec->rWNMTimingMsmt.u4ToD = MICRO_TO_10NANO(u4ToD); -+ prStaRec->rWNMTimingMsmt.u4ToA = MICRO_TO_10NANO(u4ToA); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will handle TxDone(TimingMeasurement) Event. -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* @param[in] prMsduInfo Pointer to the MSDU_INFO_T. -+* @param[in] rTxDoneStatus Return TX status of the Timing Measurement frame. -+* -+* @retval WLAN_STATUS_SUCCESS -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+wnmRunEventTimgingMeasTxDone(IN P_ADAPTER_T prAdapter, -+ IN P_MSDU_INFO_T prMsduInfo, IN ENUM_TX_RESULT_CODE_T rTxDoneStatus) -+{ -+ P_STA_RECORD_T prStaRec; -+ -+ ASSERT(prAdapter); -+ ASSERT(prMsduInfo); -+ -+ DBGLOG(WNM, LOUD, "EVENT-TX DONE: Current Time = %u\n", kalGetTimeTick()); -+ -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); -+ -+ if ((!prStaRec) || (!prStaRec->fgIsInUse)) -+ return WLAN_STATUS_SUCCESS; /* For the case of replying ERROR STATUS CODE */ -+ -+ DBGLOG(WNM, TRACE, "wnmRunEventTimgingMeasTxDone: ucDialog %d ucFollowUp %d u4ToD %x u4ToA %x", -+ prStaRec->rWNMTimingMsmt.ucDialogToken, -+ prStaRec->rWNMTimingMsmt.ucFollowUpDialogToken, -+ prStaRec->rWNMTimingMsmt.u4ToD, prStaRec->rWNMTimingMsmt.u4ToA); -+ -+ prStaRec->rWNMTimingMsmt.ucFollowUpDialogToken = prStaRec->rWNMTimingMsmt.ucDialogToken; -+ prStaRec->rWNMTimingMsmt.ucDialogToken = ++ucTimingMeasToken; -+ -+ wnmComposeTimingMeasFrame(prAdapter, prStaRec, NULL); -+ -+ return WLAN_STATUS_SUCCESS; -+ -+} /* end of wnmRunEventTimgingMeasTxDone() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will compose the Timing Measurement frame. -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* @param[in] prStaRec Pointer to the STA_RECORD_T. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+wnmComposeTimingMeasFrame(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec, IN PFN_TX_DONE_HANDLER pfTxDoneHandler) -+{ -+ P_MSDU_INFO_T prMsduInfo; -+ P_BSS_INFO_T prBssInfo; -+ P_ACTION_UNPROTECTED_WNM_TIMING_MEAS_FRAME prTxFrame; -+ UINT_16 u2PayloadLen; -+ -+ prBssInfo = &prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]; -+ ASSERT(prBssInfo); -+ -+ prMsduInfo = (P_MSDU_INFO_T) cnmMgtPktAlloc(prAdapter, MAC_TX_RESERVED_FIELD + PUBLIC_ACTION_MAX_LEN); -+ -+ if (!prMsduInfo) -+ return; -+ -+ prTxFrame = (P_ACTION_UNPROTECTED_WNM_TIMING_MEAS_FRAME) -+ ((ULONG) (prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD); -+ -+ prTxFrame->u2FrameCtrl = MAC_FRAME_ACTION; -+ -+ COPY_MAC_ADDR(prTxFrame->aucDestAddr, prStaRec->aucMacAddr); -+ COPY_MAC_ADDR(prTxFrame->aucSrcAddr, prBssInfo->aucOwnMacAddr); -+ COPY_MAC_ADDR(prTxFrame->aucBSSID, prBssInfo->aucBSSID); -+ -+ prTxFrame->ucCategory = CATEGORY_UNPROTECTED_WNM_ACTION; -+ prTxFrame->ucAction = ACTION_UNPROTECTED_WNM_TIMING_MEASUREMENT; -+ -+ /* 3 Compose the frame body's frame. */ -+ prTxFrame->ucDialogToken = prStaRec->rWNMTimingMsmt.ucDialogToken; -+ prTxFrame->ucFollowUpDialogToken = prStaRec->rWNMTimingMsmt.ucFollowUpDialogToken; -+ prTxFrame->u4ToD = prStaRec->rWNMTimingMsmt.u4ToD; -+ prTxFrame->u4ToA = prStaRec->rWNMTimingMsmt.u4ToA; -+ prTxFrame->ucMaxToDErr = WNM_MAX_TOD_ERROR; -+ prTxFrame->ucMaxToAErr = WNM_MAX_TOA_ERROR; -+ -+ u2PayloadLen = 2 + ACTION_UNPROTECTED_WNM_TIMING_MEAS_LEN; -+ -+ /* 4 Update information of MSDU_INFO_T */ -+ prMsduInfo->ucPacketType = HIF_TX_PACKET_TYPE_MGMT; /* Management frame */ -+ prMsduInfo->ucStaRecIndex = prStaRec->ucIndex; -+ prMsduInfo->ucNetworkType = prStaRec->ucNetTypeIndex; -+ prMsduInfo->ucMacHeaderLength = WLAN_MAC_MGMT_HEADER_LEN; -+ prMsduInfo->fgIs802_1x = FALSE; -+ prMsduInfo->fgIs802_11 = TRUE; -+ prMsduInfo->u2FrameLength = WLAN_MAC_MGMT_HEADER_LEN + u2PayloadLen; -+ prMsduInfo->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter); -+ prMsduInfo->pfTxDoneHandler = pfTxDoneHandler; -+ prMsduInfo->fgIsBasicRate = FALSE; -+ -+ DBGLOG(WNM, TRACE, "wnmComposeTimingMeasFrame: ucDialogToken %d ucFollowUpDialogToken %d u4ToD %x u4ToA %x\n", -+ prTxFrame->ucDialogToken, prTxFrame->ucFollowUpDialogToken, -+ prTxFrame->u4ToD, prTxFrame->u4ToA); -+ -+ /* 4 Enqueue the frame to send this action frame. */ -+ nicTxEnqueueMsdu(prAdapter, prMsduInfo); -+ -+ return; -+ -+} /* end of wnmComposeTimingMeasFrame() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* -+* \brief This routine is called to process the 802.11v timing measurement request. -+* -+* -+* \note -+* Handle Rx mgmt request -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID wnmTimingMeasRequest(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb) -+{ -+ P_ACTION_WNM_TIMING_MEAS_REQ_FRAME prRxFrame = NULL; -+ P_STA_RECORD_T prStaRec; -+ -+ prRxFrame = (P_ACTION_WNM_TIMING_MEAS_REQ_FRAME) prSwRfb->pvHeader; -+ if (!prRxFrame) -+ return; -+ -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); -+ if ((!prStaRec) || (!prStaRec->fgIsInUse)) -+ return; -+ -+ DBGLOG(WNM, TRACE, "IEEE 802.11: Received Timing Measuremen Request from %pM\n" -+ prStaRec->aucMacAdd); -+ -+ /* reset timing msmt */ -+ prStaRec->rWNMTimingMsmt.fgInitiator = TRUE; -+ prStaRec->rWNMTimingMsmt.ucTrigger = prRxFrame->ucTrigger; -+ if (!prRxFrame->ucTrigger) -+ return; -+ -+ prStaRec->rWNMTimingMsmt.ucDialogToken = ++ucTimingMeasToken; -+ prStaRec->rWNMTimingMsmt.ucFollowUpDialogToken = 0; -+ -+ wnmComposeTimingMeasFrame(prAdapter, prStaRec, wnmRunEventTimgingMeasTxDone); -+} -+ -+#if WNM_UNIT_TEST -+VOID wnmTimingMeasUnitTest1(P_ADAPTER_T prAdapter, UINT_8 ucStaRecIndex) -+{ -+ P_STA_RECORD_T prStaRec; -+ -+ prStaRec = cnmGetStaRecByIndex(prAdapter, ucStaRecIndex); -+ if ((!prStaRec) || (!prStaRec->fgIsInUse)) -+ return; -+ -+ DBGLOG(WNM, INFO, "IEEE 802.11v: Test Timing Measuremen Request from %pM\n", -+ prStaRec->aucMacAddr); -+ -+ prStaRec->rWNMTimingMsmt.fgInitiator = TRUE; -+ prStaRec->rWNMTimingMsmt.ucTrigger = 1; -+ -+ prStaRec->rWNMTimingMsmt.ucDialogToken = ++ucTimingMeasToken; -+ prStaRec->rWNMTimingMsmt.ucFollowUpDialogToken = 0; -+ -+ wnmComposeTimingMeasFrame(prAdapter, prStaRec, wnmRunEventTimgingMeasTxDone); -+} -+#endif -+ -+#endif /* CFG_SUPPORT_802_11V_TIMING_MEASUREMENT */ -+ -+#endif /* CFG_SUPPORT_802_11V */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/nic/cmd_buf.c b/drivers/misc/mediatek/connectivity/wlan/gen2/nic/cmd_buf.c -new file mode 100644 -index 000000000000..6f1bb6fd771e ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/nic/cmd_buf.c -@@ -0,0 +1,254 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/nic/cmd_buf.c#1 -+*/ -+ -+/*! \file "cmd_buf.c" -+ \brief This file contain the management function of internal Command Buffer -+ for CMD_INFO_T. -+ -+ We'll convert the OID into Command Packet and then send to FW. Thus we need -+ to copy the OID information to Command Buffer for following reasons. -+ 1. The data structure of OID information may not equal to the data structure of -+ Command, we cannot use the OID buffer directly. -+ 2. If the Command was not generated by driver we also need a place to store the -+ information. -+ 3. Because the CMD is NOT FIFO when doing memory allocation (CMD will be generated -+ from OID or interrupt handler), thus we'll use the Block style of Memory Allocation -+ here. -+*/ -+ -+/* -+** Log: cmd_buf.c -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 18 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Provide cnmMgtPktAlloc() and alloc/free function of msg/buf -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 02 03 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1. clear prPendingCmdInfo properly -+ * * 2. while allocating memory for cmdinfo, no need to add extra 4 bytes. -+** \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-10-13 21:59:08 GMT mtk01084 -+** remove un-neceasary spaces -+** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-05-20 12:24:26 GMT mtk01461 -+** Increase CMD Buffer - HIF_RX_HW_APPENDED_LEN when doing CMD_INFO_T allocation -+** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-04-21 09:41:08 GMT mtk01461 -+** Add init of Driver Domain MCR flag and fix lint MTK WARN -+** \main\maintrunk.MT6620WiFiDriver_Prj\1 2009-04-17 19:51:45 GMT mtk01461 -+** allocation function of CMD_INFO_T -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "precomp.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+static BOOLEAN fgCmdDumpIsDone = FALSE; -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is used to initial the MGMT memory pool for CMD Packet. -+* -+* @param prAdapter Pointer to the Adapter structure. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID cmdBufInitialize(IN P_ADAPTER_T prAdapter) -+{ -+ P_CMD_INFO_T prCmdInfo; -+ UINT_32 i; -+ -+ ASSERT(prAdapter); -+ -+ QUEUE_INITIALIZE(&prAdapter->rFreeCmdList); -+ -+ for (i = 0; i < CFG_TX_MAX_CMD_PKT_NUM; i++) { -+ prCmdInfo = &prAdapter->arHifCmdDesc[i]; -+ QUEUE_INSERT_TAIL(&prAdapter->rFreeCmdList, &prCmdInfo->rQueEntry); -+ } -+ fgCmdDumpIsDone = FALSE; -+} /* end of cmdBufInitialize() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief dump CMD queue and print to trace, for debug use only -+* @param[in] prQueue Pointer to the command Queue to be dumped -+* @param[in] quename Name of the queue -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID cmdBufDumpCmdQueue(P_QUE_T prQueue, CHAR *queName) -+{ -+ P_CMD_INFO_T prCmdInfo = (P_CMD_INFO_T)QUEUE_GET_HEAD(prQueue); -+ -+ DBGLOG(NIC, INFO, "Dump CMD info for %s, Elem number:%u\n", queName, prQueue->u4NumElem); -+ while (prCmdInfo) { -+ P_CMD_INFO_T prCmdInfo1, prCmdInfo2, prCmdInfo3; -+ -+ prCmdInfo1 = (P_CMD_INFO_T)QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T)prCmdInfo); -+ if (!prCmdInfo1) { -+ DBGLOG(NIC, INFO, "CID:%d SEQ:%d\n", prCmdInfo->ucCID, prCmdInfo->ucCmdSeqNum); -+ break; -+ } -+ prCmdInfo2 = (P_CMD_INFO_T)QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T)prCmdInfo1); -+ if (!prCmdInfo2) { -+ DBGLOG(NIC, INFO, "CID:%d, SEQ:%d; CID:%d, SEQ:%d\n", prCmdInfo->ucCID, -+ prCmdInfo->ucCmdSeqNum, prCmdInfo1->ucCID, prCmdInfo1->ucCmdSeqNum); -+ break; -+ } -+ prCmdInfo3 = (P_CMD_INFO_T)QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T)prCmdInfo2); -+ if (!prCmdInfo3) { -+ DBGLOG(NIC, INFO, "CID:%d, SEQ:%d; CID:%d, SEQ:%d; CID:%d, SEQ:%d\n", prCmdInfo->ucCID, -+ prCmdInfo->ucCmdSeqNum, prCmdInfo1->ucCID, prCmdInfo1->ucCmdSeqNum, -+ prCmdInfo2->ucCID, prCmdInfo2->ucCmdSeqNum); -+ break; -+ } -+ DBGLOG(NIC, INFO, "CID:%d, SEQ:%d; CID:%d, SEQ:%d; CID:%d, SEQ:%d; CID:%d, SEQ:%d\n", -+ prCmdInfo->ucCID, prCmdInfo->ucCmdSeqNum, prCmdInfo1->ucCID, -+ prCmdInfo1->ucCmdSeqNum, prCmdInfo2->ucCID, prCmdInfo2->ucCmdSeqNum, -+ prCmdInfo3->ucCID, prCmdInfo3->ucCmdSeqNum); -+ prCmdInfo = (P_CMD_INFO_T)QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T)prCmdInfo3); -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Allocate CMD_INFO_T from a free list and MGMT memory pool. -+* -+* @param[in] prAdapter Pointer to the Adapter structure. -+* @param[in] u4Length Length of the frame buffer to allocate. -+* -+* @retval NULL Pointer to the valid CMD Packet handler -+* @retval !NULL Fail to allocat CMD Packet -+*/ -+/*----------------------------------------------------------------------------*/ -+P_CMD_INFO_T cmdBufAllocateCmdInfo(IN P_ADAPTER_T prAdapter, IN UINT_32 u4Length) -+{ -+ P_CMD_INFO_T prCmdInfo; -+ -+ KAL_SPIN_LOCK_DECLARATION(); -+ -+ DEBUGFUNC("cmdBufAllocateCmdInfo"); -+ -+ ASSERT(prAdapter); -+ -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_RESOURCE); -+ QUEUE_REMOVE_HEAD(&prAdapter->rFreeCmdList, prCmdInfo, P_CMD_INFO_T); -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_RESOURCE); -+ -+ if (prCmdInfo) { -+ /* Setup initial value in CMD_INFO_T */ -+ /* Start address of allocated memory */ -+ prCmdInfo->pucInfoBuffer = cnmMemAlloc(prAdapter, RAM_TYPE_BUF, u4Length); -+ -+ if (prCmdInfo->pucInfoBuffer == NULL) { -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_RESOURCE); -+ QUEUE_INSERT_TAIL(&prAdapter->rFreeCmdList, &prCmdInfo->rQueEntry); -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_RESOURCE); -+ -+ prCmdInfo = NULL; -+ -+ DBGLOG(NIC, ERROR, "Allocate prCmdInfo->pucInfoBuffer fail!\n"); -+ } else { -+ prCmdInfo->u2InfoBufLen = 0; -+ prCmdInfo->fgIsOid = FALSE; -+ prCmdInfo->fgDriverDomainMCR = FALSE; -+ } -+ fgCmdDumpIsDone = FALSE; -+ } else if (!fgCmdDumpIsDone) { -+ P_GLUE_INFO_T prGlueInfo = prAdapter->prGlueInfo; -+ P_QUE_T prCmdQue = &prGlueInfo->rCmdQueue; -+ P_QUE_T prPendingCmdQue = &prAdapter->rPendingCmdQueue; -+ P_TX_TCQ_STATUS_T prTc = &prAdapter->rTxCtrl.rTc; -+ -+ fgCmdDumpIsDone = TRUE; -+ cmdBufDumpCmdQueue(prCmdQue, "waiting Tx CMD queue"); -+ cmdBufDumpCmdQueue(prPendingCmdQue, "waiting response CMD queue"); -+ DBGLOG(NIC, INFO, "Tc4 number:%d\n", prTc->aucFreeBufferCount[TC4_INDEX]); -+ if (prTc->aucFreeBufferCount[TC4_INDEX] != 0) -+ glDoChipReset(); -+ } -+ -+ return prCmdInfo; -+ -+} /* end of cmdBufAllocateCmdInfo() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is used to free the CMD Packet to the MGMT memory pool. -+* -+* @param prAdapter Pointer to the Adapter structure. -+* @param prCmdInfo CMD Packet handler -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID cmdBufFreeCmdInfo(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo) -+{ -+ KAL_SPIN_LOCK_DECLARATION(); -+ -+ DEBUGFUNC("cmdBufFreeCmdInfo"); -+ -+ ASSERT(prAdapter); -+ ASSERT(prCmdInfo); -+ -+ if (prCmdInfo) { -+ if (prCmdInfo->pucInfoBuffer) { -+ cnmMemFree(prAdapter, prCmdInfo->pucInfoBuffer); -+ prCmdInfo->pucInfoBuffer = NULL; -+ } -+ -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_RESOURCE); -+ QUEUE_INSERT_TAIL(&prAdapter->rFreeCmdList, &prCmdInfo->rQueEntry); -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_RESOURCE); -+ } -+ -+ return; -+ -+} /* end of cmdBufFreeCmdPacket() */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic.c b/drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic.c -new file mode 100644 -index 000000000000..dfaaedd118bf ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic.c -@@ -0,0 +1,4062 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/nic/nic.c#2 -+*/ -+ -+/*! \file nic.c -+ \brief Functions that provide operation in NIC's (Network Interface Card) point of view. -+ -+ This file includes functions which unite multiple hal(Hardware) operations -+ and also take the responsibility of Software Resource Management in order -+ to keep the synchronization with Hardware Manipulation. -+*/ -+ -+/* -+** Log: nic.c -+ * -+ * 07 17 2012 yuche.tsai -+ * NULL -+ * Compile no error before trial run. -+ * -+ * 05 02 2012 terry.wu -+ * NULL -+ * Set the default value of AP StaRec index to "STA_REC_INDEX_NOT_FOUND" in update firmware bss command. -+ * -+ * 03 02 2012 terry.wu -+ * NULL -+ * Sync CFG80211 modification from branch 2,2. -+ * -+ * 11 28 2011 cp.wu -+ * [WCXRP00001125] [MT6620 Wi-Fi][Firmware] Strengthen Wi-Fi power off sequence to have a clearroom environment when -+ * returining to ROM code -+ * 1. Due to firmware now stops HIF DMA for powering off, do not try to receive any packet from firmware -+ * 2. Take use of prAdapter->fgIsEnterD3ReqIssued for tracking whether it is powering off or not -+ * -+ * 11 22 2011 tsaiyuan.hsu -+ * [WCXRP00001083] [MT6620 Wi-Fi][DRV]] dump debug counter or frames when debugging is triggered -+ * keep debug counter setting after wake up. -+ * -+ * 11 19 2011 yuche.tsai -+ * NULL -+ * Update RSSI for P2P. -+ * -+ * 11 18 2011 yuche.tsai -+ * NULL -+ * CONFIG P2P support RSSI query, default turned off. -+ * -+ * 11 07 2011 tsaiyuan.hsu -+ * [WCXRP00001083] [MT6620 Wi-Fi][DRV]] dump debug counter or frames when debugging is triggered -+ * add debug counters and periodically dump counters for debugging. -+ * -+ * 11 04 2011 cp.wu -+ * [WCXRP00001079] [MT5931][Driver] Release pending MMPDU only when BSS is being deactivated -+ * pre-check for NULL before calling MMPDU free function -+ * -+ * 11 03 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * change the DBGLOG for "\n" and "\r\n". LABEL to LOUD for XLOG -+ * -+ * 11 01 2011 chinglan.wang -+ * NULL -+ * Modify the Wi-Fi method of the flush TX queue when disconnect the AP. -+ * If disconnect the AP and flush all the data frame in the TX queue, WPS cannot do the 4-way handshake to connect to -+ * the AP.. -+ * -+ * 10 11 2011 terry.wu -+ * NULL -+ * Rewrite Assert Dump Function for Portability. -+ * -+ * 09 20 2011 cm.chang -+ * [WCXRP00000997] [MT6620 Wi-Fi][Driver][FW] Handle change of BSS preamble type and slot time -+ * New CMD definition about RLM parameters -+ * -+ * 08 15 2011 cp.wu -+ * [WCXRP00000851] [MT6628 Wi-Fi][Driver] Add HIFSYS related definition to driver source tree -+ * reuse firmware download logic of MT6620 for MT6628. -+ * -+ * 08 03 2011 terry.wu -+ * [WCXRP00000899] [MT6620] [FW] Reply probe rsp in FW for hotspot mode -+ * Reply Probe Rsp in FW for Hotspot Mode. -+ * -+ * -+ * -+ * 08 03 2011 terry.wu -+ * [WCXRP00000899] [MT6620] [FW] Reply probe rsp in FW for hotspot mode -+ * Reply Probe Rsp in FW for Hotspot Mode. -+ * -+ * -+ * 08 03 2011 terry.wu -+ * [WCXRP00000899] [MT6620] [FW] Reply probe rsp in FW for hotspot mode -+ * Reply Probe Rsp in FW for Hotspot Mode. -+ * -+ * 08 03 2011 terry.wu -+ * [WCXRP00000899] [MT6620] [FW] Reply probe rsp in FW for hotspot mode -+ * Reply Probe Rsp in FW for Hotspot Mode. -+ * -+ * 08 02 2011 yuche.tsai -+ * [WCXRP00000896] [Volunteer Patch][WiFi Direct][Driver] GO with multiple client, TX deauth to a disconnecting device -+ * issue. -+ * Fix GO send deauth frame issue. -+ * -+ * 07 18 2011 chinghwa.yu -+ * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm -+ * Add CMD/Event for RDD and BWCS. -+ * -+ * 07 11 2011 wh.su -+ * [WCXRP00000849] [MT6620 Wi-Fi][Driver] Remove some of the WAPI define for make sure the value is initialize, for -+ * customer not enable WAPI -+ * For make sure wapi initial value is set. -+ * -+ * 06 27 2011 cp.wu -+ * [WCXRP00000815] [MT6620 Wi-Fi][Driver] allow single BSSID with multiple SSID settings to work around some tricky -+ * AP which use space character as hidden SSID -+ * 1. correct logic -+ * 2. replace only BSS-DESC which doesn't have a valid SSID. -+ * -+ * 06 27 2011 cp.wu -+ * [WCXRP00000815] [MT6620 Wi-Fi][Driver] allow single BSSID with multiple SSID settings to work around some tricky -+ * AP which use space character as hidden SSID -+ * allow to have a single BSSID with multiple SSID to be presented in scanning result -+ * -+ * 05 12 2011 puff.wen -+ * NULL -+ * FW Assert information dump to driver -+ * -+ * 04 18 2011 terry.wu -+ * [WCXRP00000660] [MT6620 Wi-Fi][Driver] Remove flag CFG_WIFI_DIRECT_MOVED -+ * Remove flag CFG_WIFI_DIRECT_MOVED. -+ * -+ * 04 15 2011 cp.wu -+ * [WCXRP00000651] [MT6620 Wi-Fi][Driver] Refine RSSI buffering mechanism -+ * ROLLBACK due to the special design is to workaround incorrect initial RCPI value coming from firmware domain. -+ * -+ * 04 14 2011 cm.chang -+ * [WCXRP00000634] [MT6620 Wi-Fi][Driver][FW] 2nd BSS will not support 40MHz bandwidth for concurrency -+ * . -+ * -+ * 04 14 2011 cp.wu -+ * [WCXRP00000598] [MT6620 Wi-Fi][Driver] Implementation of interface for communicating with user space process for -+ * RESET_START and RESET_END events -+ * 1. add code to put whole-chip resetting trigger when abnormal firmware assertion is detected -+ * 2. add dummy function for both Win32 and Linux part. -+ * -+ * 04 12 2011 cp.wu -+ * [WCXRP00000635] [MT6620 Wi-Fi][Driver] Clear pending security frames when QM clear pending data frames for -+ * dedicated network type -+ * clear pending security frames for dedicated network type when BSS is being deactivated/disconnected -+ * -+ * 04 12 2011 wh.su -+ * NULL -+ * enable the p2p check the cipher to set the bssInfo auth mode. -+ * -+ * 04 12 2011 wh.su -+ * NULL -+ * prepare the code for sync the auth mode and encryption status for P2P and BOW. -+ * -+ * 04 11 2011 yuche.tsai -+ * [WCXRP00000627] [Volunteer Patch][MT6620][Driver] Pending MMPUD of P2P Network may crash system issue. -+ * Fix kernel panic issue when MMPDU of P2P is pending in driver. -+ * -+ * 04 10 2011 george.huang -+ * [WCXRP00000621] [MT6620 Wi-Fi][Driver] Support P2P supplicant to set power mode -+ * Fix compiler issue. -+ * -+ * 04 08 2011 george.huang -+ * [WCXRP00000621] [MT6620 Wi-Fi][Driver] Support P2P supplicant to set power mode -+ * separate settings of P2P and AIS -+ * -+ * 04 08 2011 eddie.chen -+ * [WCXRP00000617] [MT6620 Wi-Fi][DRV/FW] Fix for sigma -+ * Fix for sigma -+ * -+ * 04 07 2011 cp.wu -+ * [WCXRP00000616] [MT6620 Wi-Fi][Driver] Free memory to pool and kernel in case any unexpected failure happend inside -+ * wlanAdapterStart -+ * . -+ * -+ * 04 07 2011 cp.wu -+ * [WCXRP00000616] [MT6620 Wi-Fi][Driver] Free memory to pool and kernel in case any unexpected failure happend inside -+ * wlanAdapterStart -+ * implementation of internal error handling of nicAllocateAdapterMemory. -+ * -+ * 03 31 2011 chinglan.wang -+ * [WCXRP00000613] [MT6620 Wi-Fi] [FW] [Driver] BssInfo can get the security mode which is WPA/WPA2/WAPI or not. -+ * . -+ * -+ * 03 21 2011 cp.wu -+ * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer -+ * portability improvement -+ * -+ * 03 17 2011 cp.wu -+ * [WCXRP00000562] [MT6620 Wi-Fi][Driver] I/O buffer pre-allocation to avoid physically continuous memory shortage -+ * after system running for a long period -+ * use pre-allocated buffer for storing enhanced interrupt response as well -+ * -+ * 03 16 2011 cp.wu -+ * [WCXRP00000562] [MT6620 Wi-Fi][Driver] I/O buffer pre-allocation to avoid physically continuous memory shortage -+ * after system running for a long period -+ * 1. pre-allocate physical continuous buffer while module is being loaded -+ * 2. use pre-allocated physical continuous buffer for TX/RX DMA transfer -+ * -+ * The windows part remained the same as before, but added similar APIs to hide the difference. -+ * -+ * 03 15 2011 cp.wu -+ * [WCXRP00000559] [MT6620 Wi-Fi][Driver] Combine TX/RX DMA buffers into a single one to reduce physically continuous -+ * memory consumption -+ * 1. deprecate CFG_HANDLE_IST_IN_SDIO_CALLBACK -+ * 2. Use common coalescing buffer for both TX/RX directions -+ * -+ * -+ * 03 10 2011 cm.chang -+ * [WCXRP00000358] [MT6620 Wi-Fi][Driver] Provide concurrent information for each module -+ * Add some functions to let AIS/Tethering or AIS/BOW be the same channel -+ * -+ * 03 07 2011 terry.wu -+ * [WCXRP00000521] [MT6620 Wi-Fi][Driver] Remove non-standard debug message -+ * Toggle non-standard debug messages to comments. -+ * -+ * 03 02 2011 cp.wu -+ * [WCXRP00000503] [MT6620 Wi-Fi][Driver] Take RCPI brought by association response as initial RSSI right after -+ * connection is built. -+ * use RCPI brought by ASSOC-RESP after connection is built as initial RCPI to avoid using a uninitialized MAC-RX RCPI. -+ * -+ * 02 08 2011 terry.wu -+ * [WCXRP00000412] [MT6620 Wi-Fi][FW/Driver] Dump firmware assert info at android kernel log -+ * Use kalPrint to print firmware assert info. -+ * -+ * 02 01 2011 terry.wu -+ * [WCXRP00000412] [MT6620 Wi-Fi][FW/Driver] Dump firmware assert info at android kernel log -+ * . -+ * -+ * 02 01 2011 cm.chang -+ * [WCXRP00000415] [MT6620 Wi-Fi][Driver] Check if any memory leakage happens when uninitializing in DGB mode -+ * . -+ * -+ * 01 31 2011 terry.wu -+ * [WCXRP00000412] [MT6620 Wi-Fi][FW/Driver] Dump firmware assert info at android kernel log -+ * Print firmware ASSERT info at Android kernel log, driver side -+ * -+ * 01 27 2011 tsaiyuan.hsu -+ * [WCXRP00000392] [MT6620 Wi-Fi][Driver] Add Roaming Support -+ * add roaming fsm -+ * 1. not support 11r, only use strength of signal to determine roaming. -+ * 2. not enable CFG_SUPPORT_ROAMING until completion of full test. -+ * 3. in 6620, adopt work-around to avoid sign extension problem of cck of hw -+ * 4. assume that change of link quality in smooth way. -+ * -+ * 01 26 2011 cm.chang -+ * [WCXRP00000395] [MT6620 Wi-Fi][Driver][FW] Search STA_REC with additional net type index argument -+ * Allocate system RAM if fixed message or mgmt buffer is not available -+ * -+ * 01 24 2011 cp.wu -+ * [WCXRP00000382] [MT6620 Wi-Fi][Driver] Track forwarding packet number with notifying tx thread for serving -+ * 1. add an extra counter for tracking pending forward frames. -+ * 2. notify TX service thread as well when there is pending forward frame -+ * 3. correct build errors leaded by introduction of Wi-Fi direct separation module -+ * -+ * 01 19 2011 cp.wu -+ * [WCXRP00000372] [MT6620 Wi-Fi][Driver] Check bus access failure inside nicProcessIST() -+ * check bus error and/or card removal when retrieving interrupt status from HAL -+ * -+ * 01 04 2011 cp.wu -+ * [WCXRP00000338] [MT6620 Wi-Fi][Driver] Separate kalMemAlloc into kmalloc and vmalloc implementations to ease -+ * physically continuous memory demands -+ * 1) correct typo in scan.c -+ * 2) TX descriptors, RX descriptos and management buffer should use virtually continuous buffer instead of -+ * physically contineous one -+ * -+ * 01 04 2011 cp.wu -+ * [WCXRP00000338] [MT6620 Wi-Fi][Driver] Separate kalMemAlloc into kmalloc and vmalloc implementations to ease -+ * physically continuous memory demands -+ * separate kalMemAlloc() into virtually-continuous and physically-continuous type to ease slab system pressure -+ * -+ * 12 30 2010 cp.wu -+ * [WCXRP00000327] [MT6620 Wi-Fi][Driver] Improve HEC WHQA 6972 workaround coverage in driver side -+ * host driver not to set FW-own when there is still pending interrupts -+ * -+ * 12 17 2010 cp.wu -+ * [WCXRP00000270] [MT6620 Wi-Fi][Driver] Clear issues after concurrent networking support has been merged -+ * before BSS disconnection is indicated to firmware, all correlated peer should be cleared and freed -+ * -+ * 12 07 2010 cm.chang -+ * [WCXRP00000239] MT6620 Wi-Fi][Driver][FW] Merge concurrent branch back to maintrunk -+ * 1. BSSINFO include RLM parameter -+ * 2. free all sta records when network is disconnected -+ * -+ * 12 02 2010 eddie.chen -+ * [WCXRP00000218] [MT6620 Wi-Fi][Driver] Add auto rate window control in registry -+ * Add more control value but dont use it now. -+ * -+ * 11 30 2010 eddie.chen -+ * [WCXRP00000218] [MT6620 Wi-Fi][Driver] Add auto rate window control in registry -+ * Add auto rate check window in registry -+ * -+ * 11 10 2010 eddie.chen -+ * [WCXRP00000156] [MT6620][FW] Change Auto rate window to 64 and add throughput swcr -+ * Use autorate parameter 1 as phy rate mask. -+ * -+ * 11 08 2010 cp.wu -+ * [WCXRP00000166] [MT6620 Wi-Fi][Driver] use SDIO CMD52 for enabling/disabling interrupt to reduce transaction period -+ * change to use CMD52 for enabling/disabling interrupt to reduce SDIO transaction time -+ * -+ * 10 26 2010 eddie.chen -+ * [WCXRP00000134] [MT6620 Wi-Fi][Driver] Add a registry to enable auto rate for SQA test by using E1 EVB -+ * Add auto rate parameter in registry. -+ * -+ * 10 18 2010 cp.wu -+ * [WCXRP00000053] [MT6620 Wi-Fi][Driver] Reset incomplete and might leads to -+ * BSOD when entering RF test with AIS associated -+ * 1. remove redundant variables in STA_REC structure -+ * 2. add STA-REC uninitialization routine for clearing pending events -+ * -+ * 10 18 2010 cp.wu -+ * [WCXRP00000103] [MT6620 Wi-Fi][Driver] Driver crashed when using WZC to connect to AP#B with connection with AP#A -+ * reset ptrs when IEs are going to be dropped -+ * -+ * 10 12 2010 cp.wu -+ * [WCXRP00000084] [MT6620 Wi-Fi][Driver][FW] Add fixed rate support for distance test -+ * add HT (802.11n) fixed rate support. -+ * -+ * 10 08 2010 cp.wu -+ * [WCXRP00000084] [MT6620 Wi-Fi][Driver][FW] Add fixed rate support for distance test -+ * adding fixed rate support for distance test. (from registry setting) -+ * -+ * 10 07 2010 cp.wu -+ * [WCXRP00000083] [MT5931][Driver][FW] Add necessary logic for MT5931 first connection -+ * add firmware download for MT5931. -+ * -+ * 10 05 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check -+ * load manufacture data when CFG_SUPPORT_NVRAM is set to 1 -+ * -+ * 10 04 2010 cp.wu -+ * [WCXRP00000077] [MT6620 Wi-Fi][Driver][FW] Eliminate use of ENUM_NETWORK_TYPE_T and replaced by -+ * ENUM_NETWORK_TYPE_INDEX_T only remove ENUM_NETWORK_TYPE_T definitions -+ * -+ * 09 21 2010 cp.wu -+ * [WCXRP00000053] [MT6620 Wi-Fi][Driver] Reset incomplete and might leads to BSOD when entering RF test -+ * with AIS associated -+ * Do a complete reset with STA-REC null checking for RF test re-entry -+ * -+ * 09 08 2010 cp.wu -+ * NULL -+ * use static memory pool for storing IEs of scanning result. -+ * -+ * 09 06 2010 cp.wu -+ * NULL -+ * Androi/Linux: return current operating channel information -+ * -+ * 09 01 2010 cp.wu -+ * NULL -+ * HIFSYS Clock Source Workaround -+ * -+ * 08 26 2010 yuche.tsai -+ * NULL -+ * Fix someones coding error while enable WIFI_DIRECT. -+ * -+ * 08 25 2010 george.huang -+ * NULL -+ * update OID/ registry control path for PM related settings -+ * -+ * 08 24 2010 cm.chang -+ * NULL -+ * Support RLM initail channel of Ad-hoc, P2P and BOW -+ * -+ * 08 24 2010 chinghwa.yu -+ * NULL -+ * Update BOW for the 1st time. -+ * -+ * 08 23 2010 chinghwa.yu -+ * NULL -+ * Update for BOW. -+ * -+ * 08 20 2010 yuche.tsai -+ * NULL -+ * Add state change indication. -+ * -+ * 08 16 2010 yuche.tsai -+ * NULL -+ * Add support for P2P BSS update info. -+ * -+ * 08 12 2010 cp.wu -+ * NULL -+ * [removing debugging] not to dump beacon content. -+ * -+ * 08 12 2010 cp.wu -+ * NULL -+ * [AIS-FSM] honor registry setting for adhoc running mode. (A/B/G) -+ * -+ * 08 11 2010 cp.wu -+ * NULL -+ * 1) do not use in-stack variable for beacon updating. (for MAUI porting) -+ * 2) extending scanning result to 64 instead of 48 -+ * -+ * 08 04 2010 yarco.yang -+ * NULL -+ * Add TX_AMPDU and ADDBA_REJECT command -+ * -+ * 08 03 2010 cp.wu -+ * NULL -+ * surpress compilation warning. -+ * -+ * 08 03 2010 cp.wu -+ * NULL -+ * Centralize mgmt/system service procedures into independent calls. -+ * -+ * 07 28 2010 cp.wu -+ * NULL -+ * 1) eliminate redundant variable eOPMode in prAdapter->rWlanInfo -+ * 2) change nicMediaStateChange() API prototype -+ * -+ * 07 28 2010 cp.wu -+ * NULL -+ * sync. CMD_BSS_INFO structure change to CMD-EVENT v0.15. -+ * -+ * 07 24 2010 wh.su -+ * -+ * .support the Wi-Fi RSN -+ * -+ * 07 23 2010 cp.wu -+ * -+ * FIX: structure of CMD_SET_BSS_INFO has been changed but no follow-ups are done. -+ * -+ * 07 22 2010 george.huang -+ * -+ * . -+ * -+ * 07 22 2010 george.huang -+ * -+ * Update fgIsQoS information in BSS INFO by CMD -+ * -+ * 07 19 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration. -+ * Add Ad-Hoc support to AIS-FSM -+ * -+ * 07 14 2010 yarco.yang -+ * -+ * 1. Remove CFG_MQM_MIGRATION -+ * 2. Add CMD_UPDATE_WMM_PARMS command -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 07 07 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * update prStaRecOfAP with BSS-INFO. -+ * -+ * 07 06 2010 george.huang -+ * [WPD00001556]Basic power managemenet function -+ * Update arguments for nicUpdateBeaconIETemplate() -+ * -+ * 07 06 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * STA-REC is maintained by CNM only. -+ * -+ * 07 05 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) ignore RSN checking when RSN is not turned on. -+ * 2) set STA-REC deactivation callback as NULL -+ * 3) add variable initialization API based on PHY configuration -+ * -+ * 07 01 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Support sync command of STA_REC -+ * -+ * 06 30 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * sync. with CMD/EVENT document ver0.07. -+ * -+ * 06 29 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * correct variable naming for 8-bit variable used in CMD_BEACON_TEMPLATE_UPDATE. -+ * -+ * 06 29 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) sync to. CMD/EVENT document v0.03 -+ * 2) simplify DTIM period parsing in scan.c only, bss.c no longer parses it again. -+ * 3) send command packet to indicate FW-PM after -+ * a) 1st beacon is received after AIS has connected to an AP -+ * b) IBSS-ALONE has been created -+ * c) IBSS-MERGE has occurred -+ * -+ * 06 25 2010 george.huang -+ * [WPD00001556]Basic power managemenet function -+ * Create beacon update path, with expose bssUpdateBeaconContent() -+ * -+ * 06 22 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * fill fgIsUapsdConnection when indicating BSS-CREATE with AIS-STA mode. -+ * -+ * 06 22 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) add command warpper for STA-REC/BSS-INFO sync. -+ * 2) enhance command packet sending procedure for non-oid part -+ * 3) add command packet definitions for STA-REC/BSS-INFO sync. -+ * -+ * 06 21 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * implement TX_DONE callback path. -+ * -+ * 06 21 2010 wh.su -+ * [WPD00003840][MT6620 5931] Security migration -+ * remove duplicate variable for migration. -+ * -+ * 06 21 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * TX descriptors are now allocated once for reducing allocation overhead -+ * -+ * 06 18 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Provide cnmMgtPktAlloc() and alloc/free function of msg/buf -+ * -+ * 06 11 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) migrate assoc.c. -+ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness -+ * 3) add configuration options for CNM_MEM and RSN modules -+ * 4) add data path for management frames -+ * 5) eliminate rPacketInfo of MSDU_INFO_T -+ * -+ * 06 10 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) eliminate CFG_CMD_EVENT_VERSION_0_9 -+ * 2) when disconnected, indicate nic directly (no event is needed) -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 04 26 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) surpress compiler warning -+ * 2) when acqruing LP-own, keep writing WHLPCR whenever OWN is not acquired yet -+ * -+ * 04 23 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * surpress compiler warning -+ * -+ * 04 13 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * add framework for BT-over-Wi-Fi support. -+ * * * * * * * * * * * * * 1) prPendingCmdInfo is replaced by queue for multiple handler capability -+ * * * * * * * * * * * * * 2) command sequence number is now increased atomically -+ * * * * * * * * * * * * * 3) private data could be hold and taken use for other purpose -+ * -+ * 04 12 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * add channel frequency <-> number conversion -+ * -+ * 04 06 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * eliminate direct access for prGlueInfo->fgIsCardRemoved in non-glue layer -+ * -+ * 04 06 2010 cp.wu -+ * [WPD00003827][MT6620 Wi-Fi] Chariot fail and following ping fail, no pkt send from driver -+ * correct nicProcessIST_impl() for interrupt status brought up by RX enhanced response -+ * -+ * 03 19 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) add ACPI D0/D3 state switching support -+ * * * * * * * 2) use more formal way to handle interrupt when the status is retrieved from enhanced RX response -+ * -+ * 03 17 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * always process TX interrupt first then RX interrupt. -+ * -+ * 02 25 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * correct behavior to prevent duplicated RX handling for RX0_DONE and RX1_DONE -+ * -+ * 02 23 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * add checksum offloading support. -+** \main\maintrunk.MT6620WiFiDriver_Prj\27 2009-12-16 18:03:43 GMT mtk02752 -+** handling enhanced response which fields are fetched at different moments -+** \main\maintrunk.MT6620WiFiDriver_Prj\26 2009-12-15 17:00:29 GMT mtk02752 -+** if RX enhanced response is used, D2H interrupt status should be coming from buffered result as well -+** \main\maintrunk.MT6620WiFiDriver_Prj\25 2009-12-15 12:01:55 GMT mtk02752 -+** if TX_DONE bit is not set but WTSR0/WTSR1 is non-zero, then set TX_DONE -+** bit due to time latency of interrupt status enhanced response -+** \main\maintrunk.MT6620WiFiDriver_Prj\24 2009-12-10 16:52:52 GMT mtk02752 -+** code clean -+** \main\maintrunk.MT6620WiFiDriver_Prj\23 2009-11-24 20:51:01 GMT mtk02752 -+** integrate with SD1 by invoking qmHandleMailboxRxMessage() -+** \main\maintrunk.MT6620WiFiDriver_Prj\22 2009-11-16 17:32:33 GMT mtk02752 -+** prepare code for invoking rxHandleMailboxRxMessage() -+** \main\maintrunk.MT6620WiFiDriver_Prj\21 2009-11-11 10:36:08 GMT mtk01084 -+** \main\maintrunk.MT6620WiFiDriver_Prj\20 2009-11-09 22:56:41 GMT mtk01084 -+** modify HW access routines -+** \main\maintrunk.MT6620WiFiDriver_Prj\19 2009-10-30 18:17:20 GMT mtk01084 -+** prevent warning -+** \main\maintrunk.MT6620WiFiDriver_Prj\18 2009-10-29 19:54:57 GMT mtk01084 -+** init HIF -+** \main\maintrunk.MT6620WiFiDriver_Prj\17 2009-10-23 16:08:30 GMT mtk01084 -+** \main\maintrunk.MT6620WiFiDriver_Prj\16 2009-10-13 21:59:12 GMT mtk01084 -+** update for new HW design -+** \main\maintrunk.MT6620WiFiDriver_Prj\15 2009-09-09 17:26:15 GMT mtk01084 -+** modify for CFG_TEST_WITH_MT5921 -+** \main\maintrunk.MT6620WiFiDriver_Prj\14 2009-05-19 10:55:22 GMT mtk01461 -+** Unmask the unused HISR -+** \main\maintrunk.MT6620WiFiDriver_Prj\13 2009-05-18 15:59:13 GMT mtk01084 -+** remove debug purpose code -+** \main\maintrunk.MT6620WiFiDriver_Prj\12 2009-05-18 14:05:02 GMT mtk01084 -+** update for WIFI ownback part on initial -+** \main\maintrunk.MT6620WiFiDriver_Prj\11 2009-05-04 21:32:57 GMT mtk01084 -+** add temporarily code to set driver own on adapter initialization -+** \main\maintrunk.MT6620WiFiDriver_Prj\10 2009-04-28 10:35:41 GMT mtk01461 -+** Add init of TX aggregation and fix RX STATUS is DW align for SDIO_STATUS_ENHANCE mode -+** \main\maintrunk.MT6620WiFiDriver_Prj\9 2009-04-24 21:12:10 GMT mtk01104 -+** Add function nicRestoreSpiDefMode() -+** \main\maintrunk.MT6620WiFiDriver_Prj\8 2009-04-21 09:43:31 GMT mtk01461 -+** Revise for MTK coding style - nicInitializeAdapter() -+** \main\maintrunk.MT6620WiFiDriver_Prj\7 2009-04-17 19:52:47 GMT mtk01461 -+** Update allocate Adapter Memory for MGMT Memory pool -+** \main\maintrunk.MT6620WiFiDriver_Prj\6 2009-04-01 10:57:08 GMT mtk01461 -+** Refine the order of release memory from pucRxCoalescingBufCached -+** \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-03-19 18:32:57 GMT mtk01084 -+** update for basic power management functions -+** \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-03-18 21:00:14 GMT mtk01426 -+** Add CFG_SDIO_RX_ENHANCE support -+** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-03-16 09:10:27 GMT mtk01461 -+** Update TX PATH API -+** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 20:25:59 GMT mtk01426 -+** Init for develop -+** -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "precomp.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+const UINT_8 aucPhyCfg2PhyTypeSet[PHY_CONFIG_NUM] = { -+ PHY_TYPE_SET_802_11ABG, /* PHY_CONFIG_802_11ABG */ -+ PHY_TYPE_SET_802_11BG, /* PHY_CONFIG_802_11BG */ -+ PHY_TYPE_SET_802_11G, /* PHY_CONFIG_802_11G */ -+ PHY_TYPE_SET_802_11A, /* PHY_CONFIG_802_11A */ -+ PHY_TYPE_SET_802_11B, /* PHY_CONFIG_802_11B */ -+ PHY_TYPE_SET_802_11ABGN, /* PHY_CONFIG_802_11ABGN */ -+ PHY_TYPE_SET_802_11BGN, /* PHY_CONFIG_802_11BGN */ -+ PHY_TYPE_SET_802_11AN, /* PHY_CONFIG_802_11AN */ -+ PHY_TYPE_SET_802_11GN /* PHY_CONFIG_802_11GN */ -+}; -+ -+#if (MT6620_E1_ASIC_HIFSYS_WORKAROUND == 1) -+#define REQ_GATING_ENABLE_H2D_INT BIT(31) -+#define REQ_GATING_DISABLE_H2D_INT BIT(30) -+#define ACK_GATING_ENABLE_D2H_INT BIT(31) -+#define ACK_GATING_DISABLE_D2H_INT BIT(30) -+ -+#define GATING_CONTROL_POLL_LIMIT 64 -+#endif -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+static INT_EVENT_MAP_T arIntEventMapTable[] = { -+ {WHISR_ABNORMAL_INT, INT_EVENT_ABNORMAL}, -+ {WHISR_D2H_SW_INT, INT_EVENT_SW_INT}, -+ {WHISR_TX_DONE_INT, INT_EVENT_TX}, -+ {(WHISR_RX0_DONE_INT | WHISR_RX1_DONE_INT), INT_EVENT_RX} -+}; -+ -+static const UINT_8 ucIntEventMapSize = (sizeof(arIntEventMapTable) / sizeof(INT_EVENT_MAP_T)); -+ -+static IST_EVENT_FUNCTION apfnEventFuncTable[] = { -+ nicProcessAbnormalInterrupt, /*!< INT_EVENT_ABNORMAL */ -+ nicProcessSoftwareInterrupt, /*!< INT_EVENT_SW_INT */ -+ nicProcessTxInterrupt, /*!< INT_EVENT_TX */ -+ nicProcessRxInterrupt, /*!< INT_EVENT_RX */ -+}; -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+/*! This macro is used to reduce coding errors inside nicAllocateAdapterMemory() -+ * and also enhance the readability. -+ */ -+#define LOCAL_NIC_ALLOCATE_MEMORY(pucMem, u4Size, eMemType, pucComment) \ -+ { \ -+ DBGLOG(NIC, INFO, "Allocating %u bytes for %s.\n", u4Size, pucComment); \ -+ pucMem = (PUINT_8)kalMemAlloc(u4Size, eMemType); \ -+ if (pucMem == (PUINT_8)NULL) { \ -+ DBGLOG(NIC, ERROR, "Could not allocate %u bytes for %s.\n", u4Size, pucComment); \ -+ break; \ -+ } \ -+ ASSERT(((ULONG)pucMem % 4) == 0); \ -+ DBGLOG(NIC, TRACE, "Virtual Address = %p for %s.\n", pucMem, pucComment); \ -+ } -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+VOID HifDumpEnhanceModeData(P_ADAPTER_T prAdapter) -+{ -+ dumpMemory32((PUINT_32)prAdapter->prSDIOCtrl, sizeof(ENHANCE_MODE_DATA_STRUCT_T)); -+} -+ -+VOID HifRegDump(P_ADAPTER_T prAdapter) -+{ -+ UINT_32 i; -+ UINT_32 RegVal = 0; -+ -+ for (i = 0; i <= 0x58; i += 4) { -+ if ((i != MCR_WTDR0) && (i != MCR_WTDR1) && (i != MCR_WRDR0) && -+ (i != MCR_WRDR1) && (i != MCR_WSDIOCSR) && (i != MCR_WRPLR)) { -+ HAL_MCR_RD(prAdapter, i, &RegVal); -+ DBGLOG(NIC, WARN, "HIF Reg 0x%x = 0x%x\n", i, RegVal); -+ } -+ } -+ DBGLOG(NIC, WARN, "\n\n"); -+} -+ -+BOOLEAN HifIsFwOwn(P_ADAPTER_T prAdapter) -+{ -+ return prAdapter->fgIsFwOwn; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This routine is responsible for the allocation of the data structures -+* inside the Adapter structure, include: -+* 1. SW_RFB_Ts -+* 2. Common coalescing buffer for TX PATH. -+* -+* @param prAdapter Pointer of Adapter Data Structure -+* -+* @retval WLAN_STATUS_SUCCESS - Has enough memory. -+* @retval WLAN_STATUS_RESOURCES - Memory is not enough. -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS nicAllocateAdapterMemory(IN P_ADAPTER_T prAdapter) -+{ -+ WLAN_STATUS status = WLAN_STATUS_RESOURCES; -+ P_RX_CTRL_T prRxCtrl; -+ P_TX_CTRL_T prTxCtrl; -+ -+ DEBUGFUNC("nicAllocateAdapterMemory"); -+ -+ ASSERT(prAdapter); -+ prRxCtrl = &prAdapter->rRxCtrl; -+ prTxCtrl = &prAdapter->rTxCtrl; -+ -+ do { -+ /* 4 <0> Reset all Memory Handler */ -+#if CFG_DBG_MGT_BUF -+ prAdapter->u4MemFreeDynamicCount = 0; -+ prAdapter->u4MemAllocDynamicCount = 0; -+#endif -+ prAdapter->pucMgtBufCached = (PUINT_8) NULL; -+ prRxCtrl->pucRxCached = (PUINT_8) NULL; -+ prAdapter->prSDIOCtrl = (P_SDIO_CTRL_T) NULL; -+ -+ /* 4 <1> Memory for Management Memory Pool and CMD_INFO_T */ -+ /* Allocate memory for the CMD_INFO_T and its MGMT memory pool. */ -+ prAdapter->u4MgtBufCachedSize = MGT_BUFFER_SIZE; -+ -+ LOCAL_NIC_ALLOCATE_MEMORY(prAdapter->pucMgtBufCached, -+ prAdapter->u4MgtBufCachedSize, VIR_MEM_TYPE, "COMMON MGMT MEMORY POOL"); -+ -+ /* 4 <2> Memory for RX Descriptor */ -+ /* Initialize the number of rx buffers we will have in our queue. */ -+ /* We may setup ucRxPacketDescriptors by GLUE Layer, and using -+ * this variable directly. -+ */ -+ /* Allocate memory for the SW receive structures. */ -+ prRxCtrl->u4RxCachedSize = CFG_RX_MAX_PKT_NUM * ALIGN_4(sizeof(SW_RFB_T)); -+ -+ LOCAL_NIC_ALLOCATE_MEMORY(prRxCtrl->pucRxCached, prRxCtrl->u4RxCachedSize, VIR_MEM_TYPE, "SW_RFB_T"); -+ -+ /* 4 <3> Memory for TX DEscriptor */ -+ prTxCtrl->u4TxCachedSize = CFG_TX_MAX_PKT_NUM * ALIGN_4(sizeof(MSDU_INFO_T)); -+ -+ LOCAL_NIC_ALLOCATE_MEMORY(prTxCtrl->pucTxCached, prTxCtrl->u4TxCachedSize, VIR_MEM_TYPE, "MSDU_INFO_T"); -+ -+ /* 4 <4> Memory for Common Coalescing Buffer */ -+#if CFG_COALESCING_BUFFER_SIZE || CFG_SDIO_RX_AGG -+ prAdapter->pucCoalescingBufCached = (PUINT_8) NULL; -+ -+ /* Allocate memory for the common coalescing buffer. */ -+ prAdapter->u4CoalescingBufCachedSize = CFG_COALESCING_BUFFER_SIZE > CFG_RX_COALESCING_BUFFER_SIZE ? -+ CFG_COALESCING_BUFFER_SIZE : CFG_RX_COALESCING_BUFFER_SIZE; -+ -+ prAdapter->pucCoalescingBufCached = kalAllocateIOBuffer(prAdapter->u4CoalescingBufCachedSize); -+ -+ if (prAdapter->pucCoalescingBufCached == NULL) { -+ DBGLOG(NIC, ERROR, -+ "Could not allocate %u bytes for coalescing buffer.\n", -+ prAdapter->u4CoalescingBufCachedSize); -+ break; -+ } -+#endif /* CFG_COALESCING_BUFFER_SIZE */ -+ -+ /* 4 <5> Memory for enhanced interrupt response */ -+ prAdapter->prSDIOCtrl = (P_SDIO_CTRL_T) -+ kalAllocateIOBuffer(sizeof(ENHANCE_MODE_DATA_STRUCT_T)); -+ -+ if (prAdapter->prSDIOCtrl == NULL) { -+ DBGLOG(NIC, ERROR, -+ "Could not allocate %zu bytes for interrupt response.\n", -+ sizeof(ENHANCE_MODE_DATA_STRUCT_T)); -+ break; -+ } -+ -+ status = WLAN_STATUS_SUCCESS; -+ -+ } while (FALSE); -+ -+ if (status != WLAN_STATUS_SUCCESS) -+ nicReleaseAdapterMemory(prAdapter); -+ -+ return status; -+ -+} /* end of nicAllocateAdapterMemory() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This routine is responsible for releasing the allocated memory by -+* nicAllocatedAdapterMemory(). -+* -+* @param prAdapter Pointer of Adapter Data Structure -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicReleaseAdapterMemory(IN P_ADAPTER_T prAdapter) -+{ -+ P_TX_CTRL_T prTxCtrl; -+ P_RX_CTRL_T prRxCtrl; -+ -+ ASSERT(prAdapter); -+ prTxCtrl = &prAdapter->rTxCtrl; -+ prRxCtrl = &prAdapter->rRxCtrl; -+ -+ /* 4 <5> Memory for enhanced interrupt response */ -+ if (prAdapter->prSDIOCtrl) { -+ kalReleaseIOBuffer((PVOID) prAdapter->prSDIOCtrl, sizeof(ENHANCE_MODE_DATA_STRUCT_T)); -+ prAdapter->prSDIOCtrl = (P_SDIO_CTRL_T) NULL; -+ } -+ /* 4 <4> Memory for Common Coalescing Buffer */ -+#if CFG_COALESCING_BUFFER_SIZE || CFG_SDIO_RX_AGG -+ if (prAdapter->pucCoalescingBufCached) { -+ kalReleaseIOBuffer((PVOID) prAdapter->pucCoalescingBufCached, prAdapter->u4CoalescingBufCachedSize); -+ prAdapter->pucCoalescingBufCached = (PUINT_8) NULL; -+ } -+#endif /* CFG_COALESCING_BUFFER_SIZE */ -+ -+ /* 4 <3> Memory for TX Descriptor */ -+ if (prTxCtrl->pucTxCached) { -+ kalMemFree((PVOID) prTxCtrl->pucTxCached, VIR_MEM_TYPE, prTxCtrl->u4TxCachedSize); -+ prTxCtrl->pucTxCached = (PUINT_8) NULL; -+ } -+ /* 4 <2> Memory for RX Descriptor */ -+ if (prRxCtrl->pucRxCached) { -+ kalMemFree((PVOID) prRxCtrl->pucRxCached, VIR_MEM_TYPE, prRxCtrl->u4RxCachedSize); -+ prRxCtrl->pucRxCached = (PUINT_8) NULL; -+ } -+ /* 4 <1> Memory for Management Memory Pool */ -+ if (prAdapter->pucMgtBufCached) { -+ kalMemFree((PVOID) prAdapter->pucMgtBufCached, VIR_MEM_TYPE, prAdapter->u4MgtBufCachedSize); -+ prAdapter->pucMgtBufCached = (PUINT_8) NULL; -+ } -+#if CFG_DBG_MGT_BUF -+ /* Check if all allocated memories are free */ -+ ASSERT(prAdapter->u4MemFreeDynamicCount == prAdapter->u4MemAllocDynamicCount); -+#endif -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief disable global interrupt -+* -+* @param prAdapter pointer to the Adapter handler -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicDisableInterrupt(IN P_ADAPTER_T prAdapter) -+{ -+ ASSERT(prAdapter); -+ -+ HAL_MCR_WR(prAdapter, MCR_WHLPCR, WHLPCR_INT_EN_CLR); -+ -+ prAdapter->fgIsIntEnable = FALSE; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief enable global interrupt -+* -+* @param prAdapter pointer to the Adapter handler -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicEnableInterrupt(IN P_ADAPTER_T prAdapter) -+{ -+ BOOLEAN fgIsIntEnableCache; -+ -+ ASSERT(prAdapter); -+ fgIsIntEnableCache = prAdapter->fgIsIntEnable; -+ -+ prAdapter->fgIsIntEnable = TRUE; /* NOTE(Kevin): It must be placed before MCR GINT write. */ -+ -+ /* If need enable INT and also set LPOwn at the same time. */ -+ if (prAdapter->fgIsIntEnableWithLPOwnSet) { -+ prAdapter->fgIsIntEnableWithLPOwnSet = FALSE; /* NOTE(Kevin): It's better to place it -+ * before MCR GINT write. -+ */ -+ /* If INT was enabled, only set LPOwn */ -+ if (fgIsIntEnableCache) { -+ HAL_MCR_WR(prAdapter, MCR_WHLPCR, WHLPCR_FW_OWN_REQ_SET); -+ prAdapter->fgIsFwOwn = TRUE; -+ } -+ /* If INT was not enabled, enable it and also set LPOwn now */ -+ else { -+ HAL_MCR_WR(prAdapter, MCR_WHLPCR, WHLPCR_FW_OWN_REQ_SET | WHLPCR_INT_EN_SET); -+ prAdapter->fgIsFwOwn = TRUE; -+ } -+ } -+ /* If INT was not enabled, enable it now */ -+ else if (!fgIsIntEnableCache) -+ HAL_MCR_WR(prAdapter, MCR_WHLPCR, WHLPCR_INT_EN_SET); -+ -+} /* end of nicEnableInterrupt() */ -+ -+#if CFG_SDIO_INTR_ENHANCE -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief For SDIO enhance mode, set the max rx len and tx status -+* -+* @param prAdapter a pointer to adapter private data structure. -+* -+* @return - none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicSDIOInit(IN P_ADAPTER_T prAdapter) -+{ -+ UINT_32 u4Value = 0; -+ -+ ASSERT(prAdapter); -+ -+ /* 4 <1> Check STATUS Buffer is DW alignment. */ -+ ASSERT(IS_ALIGN_4((ULONG)&prAdapter->prSDIOCtrl->u4WHISR)); -+ -+ /* 4 <2> Setup STATUS count. */ -+ { -+ HAL_MCR_RD(prAdapter, MCR_WHCR, &u4Value); -+ -+ /* 4 <2.1> Setup the number of maximum RX length to be report */ -+ u4Value &= ~(WHCR_MAX_HIF_RX_LEN_NUM); -+ u4Value |= ((SDIO_MAXIMUM_RX_LEN_NUM << WHCR_OFFSET_MAX_HIF_RX_LEN_NUM)); -+ -+ /* 4 <2.2> Setup RX enhancement mode */ -+#if CFG_SDIO_RX_ENHANCE -+ u4Value |= WHCR_RX_ENHANCE_MODE_EN; -+#else -+ u4Value &= ~WHCR_RX_ENHANCE_MODE_EN; -+#endif /* CFG_SDIO_RX_AGG */ -+ -+ HAL_MCR_WR(prAdapter, MCR_WHCR, u4Value); -+ } -+ -+ return; -+ -+} /* end of nicSDIOInit() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Read interrupt status from hardware -+* -+* @param prAdapter pointer to the Adapter handler -+* @param the interrupts -+* -+* @return N/A -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicSDIOReadIntStatus(IN P_ADAPTER_T prAdapter, OUT PUINT_32 pu4IntStatus) -+{ -+ P_SDIO_CTRL_T prSDIOCtrl; -+ -+ DEBUGFUNC("nicSDIOReadIntStatus"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pu4IntStatus); -+ -+ /* -+ prSDIOCtrl is from IO buffer. -+ prAdapter->prSDIOCtrl = (P_SDIO_CTRL_T) -+ kalAllocateIOBuffer(sizeof(ENHANCE_MODE_DATA_STRUCT_T)); -+ */ -+ prSDIOCtrl = prAdapter->prSDIOCtrl; -+ ASSERT(prSDIOCtrl); -+ -+ HAL_PORT_RD(prAdapter, -+ MCR_WHISR, -+ sizeof(ENHANCE_MODE_DATA_STRUCT_T), (PUINT_8) prSDIOCtrl, sizeof(ENHANCE_MODE_DATA_STRUCT_T)); -+ -+ if (kalIsCardRemoved(prAdapter->prGlueInfo) == TRUE || fgIsBusAccessFailed == TRUE) { -+ *pu4IntStatus = 0; -+ return; -+ } -+ -+ /* workaround */ -+ if ((prSDIOCtrl->u4WHISR & WHISR_TX_DONE_INT) == 0 && -+ (prSDIOCtrl->rTxInfo.au4WTSR[0] | prSDIOCtrl->rTxInfo.au4WTSR[1])) { -+ prSDIOCtrl->u4WHISR |= WHISR_TX_DONE_INT; -+ } -+ -+ if ((prSDIOCtrl->u4WHISR & BIT(31)) == 0 && -+ HAL_GET_MAILBOX_READ_CLEAR(prAdapter) == TRUE && -+ (prSDIOCtrl->u4RcvMailbox0 != 0 || prSDIOCtrl->u4RcvMailbox1 != 0)) { -+ prSDIOCtrl->u4WHISR |= BIT(31); -+ } -+ -+ *pu4IntStatus = prSDIOCtrl->u4WHISR; -+ -+} /* end of nicSDIOReadIntStatus() */ -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief The function used to read interrupt status and then invoking -+* dispatching procedure for the appropriate functions -+* corresponding to specific interrupt bits -+* -+* @param prAdapter pointer to the Adapter handler -+* -+* @retval WLAN_STATUS_SUCCESS -+* @retval WLAN_STATUS_ADAPTER_NOT_READY -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS nicProcessIST(IN P_ADAPTER_T prAdapter) -+{ -+ WLAN_STATUS u4Status = WLAN_STATUS_SUCCESS; -+ UINT_32 u4IntStatus = 0; -+ UINT_32 i; -+ -+ DEBUGFUNC("nicProcessIST"); -+ /* DBGLOG(NIC, LOUD, ("\n")); */ -+ -+ ASSERT(prAdapter); -+ -+ if (prAdapter->rAcpiState == ACPI_STATE_D3) { -+ DBGLOG(REQ, WARN, "Fail in set nicProcessIST! (Adapter not ready). ACPI=D%d, Radio=%d\n", -+ prAdapter->rAcpiState, prAdapter->fgIsRadioOff); -+ return WLAN_STATUS_ADAPTER_NOT_READY; -+ } -+#if (MT6620_E1_ASIC_HIFSYS_WORKAROUND == 1) -+ if (prAdapter->fgIsClockGatingEnabled == TRUE) -+ nicDisableClockGating(prAdapter); -+#endif -+ -+ for (i = 0; i < CFG_IST_LOOP_COUNT; i++) { /* CFG_IST_LOOP_COUNT = 1 */ -+ -+#if CFG_SDIO_INTR_ENHANCE -+ nicSDIOReadIntStatus(prAdapter, &u4IntStatus); -+#else -+ HAL_MCR_RD(prAdapter, MCR_WHISR, &u4IntStatus); -+#endif /* CFG_SDIO_INTR_ENHANCE */ -+ -+/* DBGLOG(NIC, TRACE, ("u4IntStatus: 0x%x\n", u4IntStatus)); */ -+ -+ if (u4IntStatus & ~(WHIER_DEFAULT | WHIER_FW_OWN_BACK_INT_EN)) { -+ DBGLOG(INTR, WARN, "Un-handled HISR %#x, HISR = %#x (HIER:0x%x)\n", -+ (UINT_32) (u4IntStatus & ~WHIER_DEFAULT), u4IntStatus, -+ (UINT_32) WHIER_DEFAULT); -+ u4IntStatus &= WHIER_DEFAULT; -+ } -+ -+ nicProcessIST_impl(prAdapter, u4IntStatus); -+ -+ if (u4IntStatus == 0) { -+ if (i == 0) -+ u4Status = WLAN_STATUS_NOT_INDICATING; -+ break; -+ } -+ } -+ -+#if (MT6620_E1_ASIC_HIFSYS_WORKAROUND == 1) -+ if (prAdapter->fgIsClockGatingEnabled == FALSE) -+ nicEnableClockGating(prAdapter); -+#endif -+ -+ return u4Status; -+} /* end of nicProcessIST() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief The function used to dispatch the appropriate functions for specific -+* interrupt bits -+* -+* @param prAdapter pointer to the Adapter handler -+* u4IntStatus interrupt status bits -+* -+* @retval WLAN_STATUS_SUCCESS -+* @retval WLAN_STATUS_ADAPTER_NOT_READY -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS nicProcessIST_impl(IN P_ADAPTER_T prAdapter, IN UINT_32 u4IntStatus) -+{ -+ UINT_32 u4IntCount = 0; -+ P_INT_EVENT_MAP_T prIntEventMap = NULL; -+ -+ ASSERT(prAdapter); -+ -+ prAdapter->u4IntStatus = u4IntStatus; -+ -+ /* Process each of the interrupt status consequently */ -+ prIntEventMap = &arIntEventMapTable[0]; -+ for (u4IntCount = 0; u4IntCount < ucIntEventMapSize; prIntEventMap++, u4IntCount++) { -+ if (prIntEventMap->u4Int & prAdapter->u4IntStatus) { -+ if (prIntEventMap->u4Event == INT_EVENT_RX && prAdapter->fgIsEnterD3ReqIssued == TRUE) { -+ /* ignore */ -+ } else if (apfnEventFuncTable[prIntEventMap->u4Event] != NULL) { -+ apfnEventFuncTable[prIntEventMap->u4Event] (prAdapter); -+ } else { -+ DBGLOG(INTR, WARN, -+ "Empty INTR handler! ISAR bit#: %u, event:%u, func: %p\n", -+ prIntEventMap->u4Int, prIntEventMap->u4Event, -+ apfnEventFuncTable[prIntEventMap->u4Event]); -+ -+ ASSERT(0); /* to trap any NULL interrupt handler */ -+ } -+ prAdapter->u4IntStatus &= ~prIntEventMap->u4Int; -+ } -+ } -+ -+ return WLAN_STATUS_SUCCESS; -+} /* end of nicProcessIST_impl() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Verify the CHIP ID -+* -+* @param prAdapter a pointer to adapter private data structure. -+* -+* -+* @retval TRUE CHIP ID is the same as the setting compiled -+* @retval FALSE CHIP ID is different from the setting compiled -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN nicVerifyChipID(IN P_ADAPTER_T prAdapter) -+{ -+ UINT_32 u4CIR = 0; -+ -+ ASSERT(prAdapter); -+ -+ HAL_MCR_RD(prAdapter, MCR_WCIR, &u4CIR); -+ -+ DBGLOG(NIC, TRACE, "Chip ID: 0x%x\n", (UINT_32) (u4CIR & WCIR_CHIP_ID)); -+ DBGLOG(NIC, TRACE, "Revision ID: 0x%x\n", (UINT_32) ((u4CIR & WCIR_REVISION_ID) >> 16)); -+ -+#if 0 -+ if (((u4CIR & WCIR_CHIP_ID) != MTK_CHIP_REV_72) && ((u4CIR & WCIR_CHIP_ID) != MTK_CHIP_REV_82)) -+ return FALSE; -+#endif -+ -+ prAdapter->ucRevID = (UINT_8) (((u4CIR & WCIR_REVISION_ID) >> 16) & 0xF); -+ -+ return TRUE; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Initialize the MCR to the appropriate init value, and verify the init -+* value -+* -+* @param prAdapter a pointer to adapter private data structure. -+* -+* @return - -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicMCRInit(IN P_ADAPTER_T prAdapter) -+{ -+ -+ ASSERT(prAdapter); -+ -+ /* 4 <0> Initial value */ -+} -+ -+VOID nicHifInit(IN P_ADAPTER_T prAdapter) -+{ -+ -+ ASSERT(prAdapter); -+#if 0 -+ /* reset event */ -+ nicPutMailbox(prAdapter, 0, 0x52455345); /* RESE */ -+ nicPutMailbox(prAdapter, 1, 0x545F5746); /* T_WF */ -+ nicSetSwIntr(prAdapter, BIT(16)); -+#endif -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Initialize the Adapter soft variable -+* -+* @param prAdapter pointer to the Adapter handler -+* -+* @return (none) -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS nicInitializeAdapter(IN P_ADAPTER_T prAdapter) -+{ -+ WLAN_STATUS u4Status = WLAN_STATUS_SUCCESS; -+ -+ ASSERT(prAdapter); -+ -+ prAdapter->fgIsIntEnableWithLPOwnSet = FALSE; -+ -+ do { -+ if (!nicVerifyChipID(prAdapter)) { -+ u4Status = WLAN_STATUS_FAILURE; -+ break; -+ } -+ /* 4 <1> MCR init */ -+ nicMCRInit(prAdapter); -+ -+#if CFG_SDIO_INTR_ENHANCE -+ nicSDIOInit(prAdapter); -+#endif /* CFG_SDIO_INTR_ENHANCE */ -+ -+ HAL_MCR_WR(prAdapter, MCR_WHIER, WHIER_DEFAULT); -+ -+ /* 4 <2> init FW HIF */ -+ nicHifInit(prAdapter); -+ } while (FALSE); -+ -+ return u4Status; -+} -+ -+#if defined(_HIF_SPI) -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Restore the SPI Mode Select to default mode, -+* this is important while driver is unload, and this must be last mcr -+* since the operation will let the hif use 8bit mode access -+* -+* \param[in] prAdapter a pointer to adapter private data structure. -+* \param[in] eGPIO2_Mode GPIO2 operation mode -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+void nicRestoreSpiDefMode(IN P_ADAPTER_T prAdapter) -+{ -+ ASSERT(prAdapter); -+ -+ HAL_MCR_WR(prAdapter, MCR_WCSR, SPICSR_8BIT_MODE_DATA); -+ -+} -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Process rx interrupt. When the rx -+* Interrupt is asserted, it means there are frames in queue. -+* -+* @param prAdapter Pointer to the Adapter structure. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicProcessAbnormalInterrupt(IN P_ADAPTER_T prAdapter) -+{ -+ UINT_32 u4Value = 0; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ -+ prGlueInfo = prAdapter->prGlueInfo; -+ prGlueInfo->IsrAbnormalCnt++; -+ HAL_MCR_RD(prAdapter, MCR_WASR, &u4Value); -+ DBGLOG(REQ, WARN, "MCR_WASR: 0x%x\n", u4Value); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief . -+* -+* @param prAdapter Pointer to the Adapter structure. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicProcessFwOwnBackInterrupt(IN P_ADAPTER_T prAdapter) -+{ -+ -+} /* end of nicProcessFwOwnBackInterrupt() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief . -+* -+* @param prAdapter Pointer to the Adapter structure. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicProcessSoftwareInterrupt(IN P_ADAPTER_T prAdapter) -+{ -+ UINT_32 u4IntrBits; -+ -+ P_GLUE_INFO_T prGlueInfo = prAdapter->prGlueInfo; -+ u4IntrBits = prAdapter->u4IntStatus & BITS(8, 31); -+ -+ prGlueInfo->IsrSoftWareCnt++; -+ -+ if ((u4IntrBits & WHISR_D2H_SW_ASSERT_INFO_INT) != 0) { -+ nicPrintFirmwareAssertInfo(prAdapter); -+#if CFG_CHIP_RESET_SUPPORT -+ glSendResetRequest(); -+#endif -+ } -+#if (MT6620_E1_ASIC_HIFSYS_WORKAROUND == 1) -+ ASSERT((u4IntrBits & (ACK_GATING_ENABLE_D2H_INT | ACK_GATING_DISABLE_D2H_INT)) -+ != (ACK_GATING_ENABLE_D2H_INT | ACK_GATING_DISABLE_D2H_INT)); -+ -+ if (u4IntrBits & ACK_GATING_ENABLE_D2H_INT) -+ prAdapter->fgIsClockGatingEnabled = TRUE; -+ -+ if (u4IntrBits & ACK_GATING_DISABLE_D2H_INT) { -+ prAdapter->fgIsClockGatingEnabled = FALSE; -+ -+ /* Indicate Service Thread for TX */ -+ if (kalGetTxPendingCmdCount(prAdapter->prGlueInfo) > 0 || wlanGetTxPendingFrameCount(prAdapter) > 0) -+ kalSetEvent(prAdapter->prGlueInfo); -+ } -+#endif -+ -+ DBGLOG(REQ, WARN, "u4IntrBits: 0x%x\n", u4IntrBits); -+} /* end of nicProcessSoftwareInterrupt() */ -+ -+VOID nicPutMailbox(IN P_ADAPTER_T prAdapter, IN UINT_32 u4MailboxNum, IN UINT_32 u4Data) -+{ -+ if (u4MailboxNum == 0) { -+ /* HAL_MCR_WR */ -+ HAL_MCR_WR(prAdapter, MCR_H2DSM0R, u4Data); -+ } else if (u4MailboxNum == 1) { -+ /* HAL_MCR_WR */ -+ HAL_MCR_WR(prAdapter, MCR_H2DSM1R, u4Data); -+ } else { -+ ASSERT(0); -+ } -+} -+ -+VOID nicGetMailbox(IN P_ADAPTER_T prAdapter, IN UINT_32 u4MailboxNum, OUT PUINT_32 pu4Data) -+{ -+ if (u4MailboxNum == 0) { -+ /* HAL_MCR_RD */ -+ HAL_MCR_RD(prAdapter, MCR_D2HRM0R, pu4Data); -+ } else if (u4MailboxNum == 1) { -+ /* HAL_MCR_RD */ -+ HAL_MCR_RD(prAdapter, MCR_D2HRM1R, pu4Data); -+ } else { -+ ASSERT(0); -+ } -+} -+ -+VOID nicSetSwIntr(IN P_ADAPTER_T prAdapter, IN UINT_32 u4SwIntrBitmap) -+{ -+ /* NOTE: -+ * SW interrupt in HW bit 16 is mapping to SW bit 0 (shift 16bit in HW transparancy) -+ * SW interrupt valid from b0~b15 -+ */ -+ ASSERT((u4SwIntrBitmap & BITS(0, 15)) == 0); -+/* DBGLOG(NIC, TRACE, ("u4SwIntrBitmap: 0x%08x\n", u4SwIntrBitmap)); */ -+ -+ HAL_MCR_WR(prAdapter, MCR_WSICR, u4SwIntrBitmap); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This procedure is used to dequeue from prAdapter->rPendingCmdQueue -+* with specified sequential number -+* -+* @param prAdapter Pointer of ADAPTER_T -+* ucSeqNum Sequential Number -+* -+* @retval - P_CMD_INFO_T -+*/ -+/*----------------------------------------------------------------------------*/ -+P_CMD_INFO_T nicGetPendingCmdInfo(IN P_ADAPTER_T prAdapter, IN UINT_8 ucSeqNum) -+{ -+ P_QUE_T prCmdQue; -+ QUE_T rTempCmdQue; -+ P_QUE_T prTempCmdQue = &rTempCmdQue; -+ P_QUE_ENTRY_T prQueueEntry = (P_QUE_ENTRY_T) NULL; -+ P_CMD_INFO_T prCmdInfo = (P_CMD_INFO_T) NULL; -+ -+ GLUE_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(prAdapter); -+ -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_PENDING); -+ -+ prCmdQue = &prAdapter->rPendingCmdQueue; -+ QUEUE_MOVE_ALL(prTempCmdQue, prCmdQue); -+ -+ QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T); -+ while (prQueueEntry) { -+ prCmdInfo = (P_CMD_INFO_T) prQueueEntry; -+ -+ if (prCmdInfo->ucCmdSeqNum == ucSeqNum) -+ break; -+ -+ QUEUE_INSERT_TAIL(prCmdQue, prQueueEntry); -+ -+ prCmdInfo = NULL; -+ -+ QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T); -+ } -+ QUEUE_CONCATENATE_QUEUES(prCmdQue, prTempCmdQue); -+ -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_PENDING); -+ -+ return prCmdInfo; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This procedure is used to dequeue from prAdapter->rTxCtrl.rTxMgmtTxingQueue -+* with specified sequential number -+* -+* @param prAdapter Pointer of ADAPTER_T -+* ucSeqNum Sequential Number -+* -+* @retval - P_MSDU_INFO_T -+*/ -+/*----------------------------------------------------------------------------*/ -+P_MSDU_INFO_T nicGetPendingTxMsduInfo(IN P_ADAPTER_T prAdapter, IN UINT_8 ucSeqNum) -+{ -+ P_QUE_T prTxingQue; -+ QUE_T rTempQue; -+ P_QUE_T prTempQue = &rTempQue; -+ P_QUE_ENTRY_T prQueueEntry = (P_QUE_ENTRY_T) NULL; -+ P_MSDU_INFO_T prMsduInfo = (P_MSDU_INFO_T) NULL; -+ -+ GLUE_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(prAdapter); -+ -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TXING_MGMT_LIST); -+ -+ prTxingQue = &(prAdapter->rTxCtrl.rTxMgmtTxingQueue); -+ QUEUE_MOVE_ALL(prTempQue, prTxingQue); -+ -+ QUEUE_REMOVE_HEAD(prTempQue, prQueueEntry, P_QUE_ENTRY_T); -+ while (prQueueEntry) { -+ prMsduInfo = (P_MSDU_INFO_T) prQueueEntry; -+ -+ if (prMsduInfo->ucTxSeqNum == ucSeqNum) -+ break; -+ -+ QUEUE_INSERT_TAIL(prTxingQue, prQueueEntry); -+ -+ prMsduInfo = NULL; -+ -+ QUEUE_REMOVE_HEAD(prTempQue, prQueueEntry, P_QUE_ENTRY_T); -+ } -+ QUEUE_CONCATENATE_QUEUES(prTxingQue, prTempQue); -+ -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TXING_MGMT_LIST); -+ -+ return prMsduInfo; -+} -+ -+P_MSDU_INFO_T nicGetPendingStaMMPDU(IN P_ADAPTER_T prAdapter, IN UINT_8 ucStaRecIdx) -+{ -+ P_MSDU_INFO_T prMsduInfoListHead = (P_MSDU_INFO_T) NULL; -+ P_QUE_T prTxingQue = (P_QUE_T) NULL; -+ QUE_T rTempQue; -+ P_QUE_T prTempQue = &rTempQue; -+ P_QUE_ENTRY_T prQueueEntry = (P_QUE_ENTRY_T) NULL; -+ P_MSDU_INFO_T prMsduInfo = (P_MSDU_INFO_T) NULL; -+ GLUE_SPIN_LOCK_DECLARATION(); -+ -+ if (prAdapter == NULL) { -+ ASSERT(FALSE); -+ return NULL; -+ } -+ -+ -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TXING_MGMT_LIST); -+ do { -+ -+ prTxingQue = &(prAdapter->rTxCtrl.rTxMgmtTxingQueue); -+ QUEUE_MOVE_ALL(prTempQue, prTxingQue); -+ -+ QUEUE_REMOVE_HEAD(prTempQue, prQueueEntry, P_QUE_ENTRY_T); -+ while (prQueueEntry) { -+ prMsduInfo = (P_MSDU_INFO_T) prQueueEntry; -+ -+ if ((prMsduInfo->ucStaRecIndex == ucStaRecIdx) && (prMsduInfo->pfTxDoneHandler != NULL)) { -+ QM_TX_SET_NEXT_MSDU_INFO(prMsduInfo, prMsduInfoListHead); -+ prMsduInfoListHead = prMsduInfo; -+ } else { -+ QUEUE_INSERT_TAIL(prTxingQue, prQueueEntry); -+ -+ prMsduInfo = NULL; -+ } -+ -+ QUEUE_REMOVE_HEAD(prTempQue, prQueueEntry, P_QUE_ENTRY_T); -+ } -+ -+ } while (FALSE); -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TXING_MGMT_LIST); -+ -+ return prMsduInfoListHead; -+} /* nicGetPendingStaMMPDU */ -+ -+VOID nicFreePendingTxMsduInfoByNetwork(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkType) -+{ -+ P_QUE_T prTxingQue; -+ QUE_T rTempQue; -+ P_QUE_T prTempQue = &rTempQue; -+ P_QUE_ENTRY_T prQueueEntry = (P_QUE_ENTRY_T) NULL; -+ P_MSDU_INFO_T prMsduInfoListHead = (P_MSDU_INFO_T) NULL; -+ P_MSDU_INFO_T prMsduInfoListTail = (P_MSDU_INFO_T) NULL; -+ P_MSDU_INFO_T prMsduInfo = (P_MSDU_INFO_T) NULL; -+ -+ GLUE_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(prAdapter); -+ -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TXING_MGMT_LIST); -+ -+ prTxingQue = &(prAdapter->rTxCtrl.rTxMgmtTxingQueue); -+ QUEUE_MOVE_ALL(prTempQue, prTxingQue); -+ -+ QUEUE_REMOVE_HEAD(prTempQue, prQueueEntry, P_QUE_ENTRY_T); -+ while (prQueueEntry) { -+ prMsduInfo = (P_MSDU_INFO_T) prQueueEntry; -+ -+ if ((ENUM_NETWORK_TYPE_INDEX_T) (prMsduInfo->ucNetworkType) == eNetworkType) { -+ if (prMsduInfoListHead == NULL) { -+ prMsduInfoListHead = prMsduInfoListTail = prMsduInfo; -+ } else { -+ QM_TX_SET_NEXT_MSDU_INFO(prMsduInfoListTail, prMsduInfo); -+ prMsduInfoListTail = prMsduInfo; -+ } -+ } else { -+ QUEUE_INSERT_TAIL(prTxingQue, prQueueEntry); -+ -+ prMsduInfo = NULL; -+ } -+ -+ QUEUE_REMOVE_HEAD(prTempQue, prQueueEntry, P_QUE_ENTRY_T); -+ } -+ QUEUE_CONCATENATE_QUEUES(prTxingQue, prTempQue); -+ -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TXING_MGMT_LIST); -+ -+ /* free */ -+ if (prMsduInfoListHead) -+ nicTxFreeMsduInfoPacket(prAdapter, prMsduInfoListHead); -+ -+ return; -+ -+} /* end of nicFreePendingTxMsduInfoByNetwork() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This procedure is used to retrieve a CMD sequence number atomically -+* -+* @param prAdapter Pointer of ADAPTER_T -+* -+* @retval - UINT_8 -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT_8 nicIncreaseCmdSeqNum(IN P_ADAPTER_T prAdapter) -+{ -+ UINT_8 ucRetval; -+ -+ KAL_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(prAdapter); -+ -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_SEQ_NUM); -+ -+ prAdapter->ucCmdSeqNum++; -+ ucRetval = prAdapter->ucCmdSeqNum; -+ -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_SEQ_NUM); -+ -+ return ucRetval; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This procedure is used to retrieve a TX sequence number atomically -+* -+* @param prAdapter Pointer of ADAPTER_T -+* -+* @retval - UINT_8 -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT_8 nicIncreaseTxSeqNum(IN P_ADAPTER_T prAdapter) -+{ -+ UINT_8 ucRetval; -+ -+ KAL_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(prAdapter); -+ -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_SEQ_NUM); -+ -+ prAdapter->ucTxSeqNum++; -+ ucRetval = prAdapter->ucTxSeqNum; -+ -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_SEQ_NUM); -+ -+ return ucRetval; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This utility function is used to handle -+* media state change event -+* -+* @param -+* -+* @retval -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+nicMediaStateChange(IN P_ADAPTER_T prAdapter, -+ IN ENUM_NETWORK_TYPE_INDEX_T eNetworkType, IN P_EVENT_CONNECTION_STATUS prConnectionStatus) -+{ -+ P_GLUE_INFO_T prGlueInfo; -+ -+ ASSERT(prAdapter); -+ prGlueInfo = prAdapter->prGlueInfo; -+ -+ switch (eNetworkType) { -+ case NETWORK_TYPE_AIS_INDEX: -+ if (prConnectionStatus->ucMediaStatus == PARAM_MEDIA_STATE_DISCONNECTED) { /* disconnected */ -+ if (kalGetMediaStateIndicated(prGlueInfo) != PARAM_MEDIA_STATE_DISCONNECTED) { -+ -+ DBGLOG(NIC, TRACE, "DisByMC\n"); -+ kalIndicateStatusAndComplete(prGlueInfo, WLAN_STATUS_MEDIA_DISCONNECT, NULL, 0); -+ -+ prAdapter->rWlanInfo.u4SysTime = kalGetTimeTick(); -+ } -+ -+ /* reset buffered link quality information */ -+ prAdapter->fgIsLinkQualityValid = FALSE; -+ prAdapter->fgIsLinkRateValid = FALSE; -+ } else if (prConnectionStatus->ucMediaStatus == PARAM_MEDIA_STATE_CONNECTED) { /* connected */ -+ prAdapter->rWlanInfo.u4SysTime = kalGetTimeTick(); -+ -+ /* fill information for association result */ -+ prAdapter->rWlanInfo.rCurrBssId.rSsid.u4SsidLen = prConnectionStatus->ucSsidLen; -+ kalMemCopy(prAdapter->rWlanInfo.rCurrBssId.rSsid.aucSsid, -+ prConnectionStatus->aucSsid, prConnectionStatus->ucSsidLen); -+ kalMemCopy(prAdapter->rWlanInfo.rCurrBssId.arMacAddress, -+ prConnectionStatus->aucBssid, MAC_ADDR_LEN); -+ prAdapter->rWlanInfo.rCurrBssId.u4Privacy -+ = prConnectionStatus->ucEncryptStatus; /* @FIXME */ -+ prAdapter->rWlanInfo.rCurrBssId.rRssi = 0; /* @FIXME */ -+ prAdapter->rWlanInfo.rCurrBssId.eNetworkTypeInUse -+ = PARAM_NETWORK_TYPE_AUTOMODE; /* @FIXME */ -+ prAdapter->rWlanInfo.rCurrBssId.rConfiguration.u4BeaconPeriod -+ = prConnectionStatus->u2BeaconPeriod; -+ prAdapter->rWlanInfo.rCurrBssId.rConfiguration.u4ATIMWindow = prConnectionStatus->u2ATIMWindow; -+ prAdapter->rWlanInfo.rCurrBssId.rConfiguration.u4DSConfig = prConnectionStatus->u4FreqInKHz; -+ prAdapter->rWlanInfo.ucNetworkType = prConnectionStatus->ucNetworkType; -+ prAdapter->rWlanInfo.rCurrBssId.eOpMode -+ = (ENUM_PARAM_OP_MODE_T) prConnectionStatus->ucInfraMode; -+ -+ /* always indicate to OS according to MSDN (re-association/roaming) */ -+ if (kalGetMediaStateIndicated(prGlueInfo) != PARAM_MEDIA_STATE_CONNECTED) { -+ kalIndicateStatusAndComplete(prGlueInfo, WLAN_STATUS_MEDIA_CONNECT, NULL, 0); -+ } else { -+ /* connected -> connected : roaming ? */ -+ kalIndicateStatusAndComplete(prGlueInfo, WLAN_STATUS_ROAM_OUT_FIND_BEST, NULL, 0); -+ } -+ } -+ break; -+ -+#if CFG_ENABLE_BT_OVER_WIFI -+ case NETWORK_TYPE_BOW_INDEX: -+ break; -+#endif -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ case NETWORK_TYPE_P2P_INDEX: -+ break; -+#endif -+ default: -+ ASSERT(0); -+ } -+ -+ return WLAN_STATUS_SUCCESS; -+} /* nicMediaStateChange */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This utility function is used to convert between -+* frequency and channel number -+* -+* @param u4ChannelNum -+* -+* @retval - Frequency in unit of KHz, 0 for invalid channel number -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT_32 nicChannelNum2Freq(UINT_32 u4ChannelNum) -+{ -+ UINT_32 u4ChannelInMHz; -+ -+ if (u4ChannelNum >= 1 && u4ChannelNum <= 13) -+ u4ChannelInMHz = 2412 + (u4ChannelNum - 1) * 5; -+ else if (u4ChannelNum == 14) -+ u4ChannelInMHz = 2484; -+ else if (u4ChannelNum == 133) -+ u4ChannelInMHz = 3665; /* 802.11y */ -+ else if (u4ChannelNum == 137) -+ u4ChannelInMHz = 3685; /* 802.11y */ -+ else if (u4ChannelNum >= 34 && u4ChannelNum <= 165) -+ u4ChannelInMHz = 5000 + u4ChannelNum * 5; -+ else if (u4ChannelNum >= 183 && u4ChannelNum <= 196) -+ u4ChannelInMHz = 4000 + u4ChannelNum * 5; -+ else -+ u4ChannelInMHz = 0; -+ -+ return 1000 * u4ChannelInMHz; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This utility function is used to convert between -+* frequency and channel number -+* -+* @param u4FreqInKHz -+* -+* @retval - Frequency Number, 0 for invalid freqency -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT_32 nicFreq2ChannelNum(UINT_32 u4FreqInKHz) -+{ -+ switch (u4FreqInKHz) { -+ case 2412000: -+ return 1; -+ case 2417000: -+ return 2; -+ case 2422000: -+ return 3; -+ case 2427000: -+ return 4; -+ case 2432000: -+ return 5; -+ case 2437000: -+ return 6; -+ case 2442000: -+ return 7; -+ case 2447000: -+ return 8; -+ case 2452000: -+ return 9; -+ case 2457000: -+ return 10; -+ case 2462000: -+ return 11; -+ case 2467000: -+ return 12; -+ case 2472000: -+ return 13; -+ case 2484000: -+ return 14; -+ case 3665000: -+ return 133; /* 802.11y */ -+ case 3685000: -+ return 137; /* 802.11y */ -+ case 4915000: -+ return 183; -+ case 4920000: -+ return 184; -+ case 4925000: -+ return 185; -+ case 4930000: -+ return 186; -+ case 4935000: -+ return 187; -+ case 4940000: -+ return 188; -+ case 4945000: -+ return 189; -+ case 4960000: -+ return 192; -+ case 4980000: -+ return 196; -+ case 5170000: -+ return 34; -+ case 5180000: -+ return 36; -+ case 5190000: -+ return 38; -+ case 5200000: -+ return 40; -+ case 5210000: -+ return 42; -+ case 5220000: -+ return 44; -+ case 5230000: -+ return 46; -+ case 5240000: -+ return 48; -+ case 5250000: -+ return 50; -+ case 5260000: -+ return 52; -+ case 5270000: -+ return 54; -+ case 5280000: -+ return 56; -+ case 5290000: -+ return 58; -+ case 5300000: -+ return 60; -+ case 5320000: -+ return 64; -+ case 5500000: -+ return 100; -+ case 5520000: -+ return 104; -+ case 5540000: -+ return 108; -+ case 5560000: -+ return 112; -+ case 5580000: -+ return 116; -+ case 5600000: -+ return 120; -+ case 5620000: -+ return 124; -+ case 5640000: -+ return 128; -+ case 5660000: -+ return 132; -+ case 5680000: -+ return 136; -+ case 5700000: -+ return 140; -+ case 5745000: -+ return 149; -+ case 5765000: -+ return 153; -+ case 5785000: -+ return 157; -+ case 5805000: -+ return 161; -+ case 5825000: -+ return 165; -+ case 5845000: -+ return 169; -+ case 5865000: -+ return 173; -+ default: -+ return 0; -+ } -+} -+ -+/* firmware command wrapper */ -+/* NETWORK (WIFISYS) */ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This utility function is used to activate WIFISYS for specified network -+* -+* @param prAdapter Pointer of ADAPTER_T -+* eNetworkTypeIdx Index of network type -+* -+* @retval - -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS nicActivateNetwork(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx) -+{ -+ CMD_BSS_ACTIVATE_CTRL rCmdActivateCtrl; -+ P_BSS_INFO_T prBssInfo; -+ -+ ASSERT(prAdapter); -+ ASSERT(eNetworkTypeIdx < NETWORK_TYPE_INDEX_NUM); -+ -+ rCmdActivateCtrl.ucNetTypeIndex = (UINT_8) eNetworkTypeIdx; -+ rCmdActivateCtrl.ucActive = 1; -+ -+ if (((UINT_8) eNetworkTypeIdx) < NETWORK_TYPE_INDEX_NUM) { -+ prBssInfo = &prAdapter->rWifiVar.arBssInfo[eNetworkTypeIdx]; -+ prBssInfo->fg40mBwAllowed = FALSE; -+ prBssInfo->fgAssoc40mBwAllowed = FALSE; -+ } -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_BSS_ACTIVATE_CTRL, -+ TRUE, -+ FALSE, -+ FALSE, -+ NULL, NULL, sizeof(CMD_BSS_ACTIVATE_CTRL), (PUINT_8)&rCmdActivateCtrl, NULL, 0); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This utility function is used to deactivate WIFISYS for specified network -+* -+* @param prAdapter Pointer of ADAPTER_T -+* eNetworkTypeIdx Index of network type -+* -+* @retval - -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS nicDeactivateNetwork(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx) -+{ -+ WLAN_STATUS u4Status; -+ CMD_BSS_ACTIVATE_CTRL rCmdActivateCtrl; -+ -+ ASSERT(prAdapter); -+ ASSERT(eNetworkTypeIdx < NETWORK_TYPE_INDEX_NUM); -+ -+ rCmdActivateCtrl.ucNetTypeIndex = (UINT_8) eNetworkTypeIdx; -+ rCmdActivateCtrl.ucActive = 0; -+ -+ u4Status = wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_BSS_ACTIVATE_CTRL, -+ TRUE, -+ FALSE, -+ FALSE, -+ NULL, -+ NULL, sizeof(CMD_BSS_ACTIVATE_CTRL), (PUINT_8)&rCmdActivateCtrl, NULL, 0); -+ -+ /* free all correlated station records */ -+ cnmStaFreeAllStaByNetType(prAdapter, eNetworkTypeIdx, FALSE); -+ qmFreeAllByNetType(prAdapter, eNetworkTypeIdx); -+ nicFreePendingTxMsduInfoByNetwork(prAdapter, eNetworkTypeIdx); -+ kalClearSecurityFramesByNetType(prAdapter->prGlueInfo, eNetworkTypeIdx); -+ -+ return u4Status; -+} -+ -+/* BSS-INFO */ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This utility function is used to sync bss info with firmware -+* when a new BSS has been connected or disconnected -+* -+* @param prAdapter Pointer of ADAPTER_T -+* eNetworkTypeIdx Index of BSS-INFO type -+* -+* @retval - -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS nicUpdateBss(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx) -+{ -+ WLAN_STATUS u4Status; -+ P_BSS_INFO_T prBssInfo; -+ CMD_SET_BSS_INFO rCmdSetBssInfo; -+ -+ ASSERT(prAdapter); -+ ASSERT(eNetworkTypeIdx < NETWORK_TYPE_INDEX_NUM); -+ -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[eNetworkTypeIdx]); -+ -+ kalMemZero(&rCmdSetBssInfo, sizeof(CMD_SET_BSS_INFO)); -+ -+ rCmdSetBssInfo.ucNetTypeIndex = (UINT_8) eNetworkTypeIdx; -+ rCmdSetBssInfo.ucConnectionState = (UINT_8) prBssInfo->eConnectionState; -+ rCmdSetBssInfo.ucCurrentOPMode = (UINT_8) prBssInfo->eCurrentOPMode; -+ rCmdSetBssInfo.ucSSIDLen = (UINT_8) prBssInfo->ucSSIDLen; -+ kalMemCopy(rCmdSetBssInfo.aucSSID, prBssInfo->aucSSID, prBssInfo->ucSSIDLen); -+ COPY_MAC_ADDR(rCmdSetBssInfo.aucBSSID, prBssInfo->aucBSSID); -+ rCmdSetBssInfo.ucIsQBSS = (UINT_8) prBssInfo->fgIsQBSS; -+ rCmdSetBssInfo.ucNonHTBasicPhyType = prBssInfo->ucNonHTBasicPhyType; -+ rCmdSetBssInfo.u2OperationalRateSet = prBssInfo->u2OperationalRateSet; -+ rCmdSetBssInfo.u2BSSBasicRateSet = prBssInfo->u2BSSBasicRateSet; -+ rCmdSetBssInfo.ucPhyTypeSet = prBssInfo->ucPhyTypeSet; -+ rCmdSetBssInfo.fgHiddenSsidMode = prBssInfo->eHiddenSsidType; -+#if CFG_ENABLE_WIFI_DIRECT -+ if (prAdapter->fgIsP2PRegistered) -+ COPY_MAC_ADDR(rCmdSetBssInfo.aucOwnMac, prBssInfo->aucOwnMacAddr); -+#endif -+ -+ rlmFillSyncCmdParam(&rCmdSetBssInfo.rBssRlmParam, prBssInfo); -+ -+ rCmdSetBssInfo.fgWapiMode = (UINT_8) FALSE; -+ -+ if (rCmdSetBssInfo.ucNetTypeIndex == NETWORK_TYPE_AIS_INDEX) { -+ P_CONNECTION_SETTINGS_T prConnSettings = &(prAdapter->rWifiVar.rConnSettings); -+ -+ rCmdSetBssInfo.ucAuthMode = (UINT_8) prConnSettings->eAuthMode; -+ rCmdSetBssInfo.ucEncStatus = (UINT_8) prConnSettings->eEncStatus; -+ rCmdSetBssInfo.fgWapiMode = (UINT_8) prConnSettings->fgWapiMode; -+ } -+#if CFG_ENABLE_BT_OVER_WIFI -+ else if (rCmdSetBssInfo.ucNetTypeIndex == NETWORK_TYPE_BOW_INDEX) { -+ /* P_CONNECTION_SETTINGS_T prConnSettings = &(prAdapter->rWifiVar.rConnSettings); */ -+ rCmdSetBssInfo.ucAuthMode = (UINT_8) AUTH_MODE_WPA2_PSK; -+ rCmdSetBssInfo.ucEncStatus = (UINT_8) ENUM_ENCRYPTION3_KEY_ABSENT; -+ } -+#endif -+ else { -+#if CFG_ENABLE_WIFI_DIRECT -+ if (prAdapter->fgIsP2PRegistered) { -+ if (kalP2PGetCipher(prAdapter->prGlueInfo)) { -+ rCmdSetBssInfo.ucAuthMode = (UINT_8) AUTH_MODE_WPA2_PSK; -+ rCmdSetBssInfo.ucEncStatus = (UINT_8) ENUM_ENCRYPTION3_KEY_ABSENT; -+ } else { -+ rCmdSetBssInfo.ucAuthMode = (UINT_8) AUTH_MODE_OPEN; -+ rCmdSetBssInfo.ucEncStatus = (UINT_8) ENUM_ENCRYPTION_DISABLED; -+ } -+ /* Need the probe response to detect the PBC overlap */ -+ rCmdSetBssInfo.fgIsApMode = p2pFuncIsAPMode(prAdapter->rWifiVar.prP2pFsmInfo); -+ } -+#else -+ rCmdSetBssInfo.ucAuthMode = (UINT_8) AUTH_MODE_WPA2_PSK; -+ rCmdSetBssInfo.ucEncStatus = (UINT_8) ENUM_ENCRYPTION3_KEY_ABSENT; -+#endif -+ } -+ -+ if (eNetworkTypeIdx == NETWORK_TYPE_AIS_INDEX && -+ prBssInfo->eCurrentOPMode == OP_MODE_INFRASTRUCTURE && prBssInfo->prStaRecOfAP != NULL) { -+ rCmdSetBssInfo.ucStaRecIdxOfAP = prBssInfo->prStaRecOfAP->ucIndex; -+ -+ cnmAisInfraConnectNotify(prAdapter); -+ } -+#if CFG_ENABLE_WIFI_DIRECT -+ else if ((prAdapter->fgIsP2PRegistered) && -+ (eNetworkTypeIdx == NETWORK_TYPE_P2P_INDEX) && -+ (prBssInfo->eCurrentOPMode == OP_MODE_INFRASTRUCTURE) && (prBssInfo->prStaRecOfAP != NULL)) { -+ rCmdSetBssInfo.ucStaRecIdxOfAP = prBssInfo->prStaRecOfAP->ucIndex; -+ } -+#endif -+ -+#if CFG_ENABLE_BT_OVER_WIFI -+ else if (eNetworkTypeIdx == NETWORK_TYPE_BOW_INDEX && -+ prBssInfo->eCurrentOPMode == OP_MODE_BOW && prBssInfo->prStaRecOfAP != NULL) { -+ rCmdSetBssInfo.ucStaRecIdxOfAP = prBssInfo->prStaRecOfAP->ucIndex; -+ } -+#endif -+ else -+ rCmdSetBssInfo.ucStaRecIdxOfAP = STA_REC_INDEX_NOT_FOUND; -+ -+ u4Status = wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SET_BSS_INFO, -+ TRUE, -+ FALSE, -+ FALSE, -+ NULL, NULL, sizeof(CMD_SET_BSS_INFO), (PUINT_8)&rCmdSetBssInfo, NULL, 0); -+ -+ /* if BSS-INFO is going to be disconnected state, free all correlated station records */ -+ if (prBssInfo->eConnectionState == PARAM_MEDIA_STATE_DISCONNECTED) { -+ /* clear client list */ -+ bssClearClientList(prAdapter, prBssInfo); -+ -+ /* free all correlated station records */ -+ cnmStaFreeAllStaByNetType(prAdapter, eNetworkTypeIdx, FALSE); -+ qmFreeAllByNetType(prAdapter, eNetworkTypeIdx); -+ kalClearSecurityFramesByNetType(prAdapter->prGlueInfo, eNetworkTypeIdx); -+#if CFG_ENABLE_GTK_FRAME_FILTER -+ if (prBssInfo->prIpV4NetAddrList) -+ FREE_IPV4_NETWORK_ADDR_LIST(prBssInfo->prIpV4NetAddrList); -+#endif -+ } -+ -+ return u4Status; -+} -+ -+/* BSS-INFO Indication (PM) */ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This utility function is used to indicate PM that -+* a BSS has been created. (for AdHoc / P2P-GO) -+* -+* @param prAdapter Pointer of ADAPTER_T -+* eNetworkTypeIdx Index of BSS-INFO -+* -+* @retval - -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS nicPmIndicateBssCreated(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx) -+{ -+ P_BSS_INFO_T prBssInfo; -+ CMD_INDICATE_PM_BSS_CREATED rCmdIndicatePmBssCreated; -+ -+ ASSERT(prAdapter); -+ ASSERT(eNetworkTypeIdx < NETWORK_TYPE_INDEX_NUM); -+ -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[eNetworkTypeIdx]); -+ -+ rCmdIndicatePmBssCreated.ucNetTypeIndex = (UINT_8) eNetworkTypeIdx; -+ rCmdIndicatePmBssCreated.ucDtimPeriod = prBssInfo->ucDTIMPeriod; -+ rCmdIndicatePmBssCreated.u2BeaconInterval = prBssInfo->u2BeaconInterval; -+ rCmdIndicatePmBssCreated.u2AtimWindow = prBssInfo->u2ATIMWindow; -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_INDICATE_PM_BSS_CREATED, -+ TRUE, -+ FALSE, -+ FALSE, -+ NULL, -+ NULL, -+ sizeof(CMD_INDICATE_PM_BSS_CREATED), (PUINT_8)&rCmdIndicatePmBssCreated, NULL, 0); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This utility function is used to indicate PM that -+* a BSS has been connected -+* -+* @param prAdapter Pointer of ADAPTER_T -+* eNetworkTypeIdx Index of BSS-INFO -+* -+* @retval - -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS nicPmIndicateBssConnected(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx) -+{ -+ P_BSS_INFO_T prBssInfo; -+ CMD_INDICATE_PM_BSS_CONNECTED rCmdIndicatePmBssConnected; -+ -+ ASSERT(prAdapter); -+ ASSERT(eNetworkTypeIdx < NETWORK_TYPE_INDEX_NUM); -+ -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[eNetworkTypeIdx]); -+ -+ rCmdIndicatePmBssConnected.ucNetTypeIndex = (UINT_8) eNetworkTypeIdx; -+ rCmdIndicatePmBssConnected.ucDtimPeriod = prBssInfo->ucDTIMPeriod; -+ rCmdIndicatePmBssConnected.u2AssocId = prBssInfo->u2AssocId; -+ rCmdIndicatePmBssConnected.u2BeaconInterval = prBssInfo->u2BeaconInterval; -+ rCmdIndicatePmBssConnected.u2AtimWindow = prBssInfo->u2ATIMWindow; -+ -+ rCmdIndicatePmBssConnected.ucBmpDeliveryAC = prBssInfo->rPmProfSetupInfo.ucBmpDeliveryAC; -+ rCmdIndicatePmBssConnected.ucBmpTriggerAC = prBssInfo->rPmProfSetupInfo.ucBmpTriggerAC; -+ -+ /* DBGPRINTF("nicPmIndicateBssConnected: ucBmpDeliveryAC:0x%x, ucBmpTriggerAC:0x%x", */ -+ /* rCmdIndicatePmBssConnected.ucBmpDeliveryAC, */ -+ /* rCmdIndicatePmBssConnected.ucBmpTriggerAC); */ -+ -+ if ((eNetworkTypeIdx == NETWORK_TYPE_AIS_INDEX) -+#if CFG_ENABLE_WIFI_DIRECT -+ || ((eNetworkTypeIdx == NETWORK_TYPE_P2P_INDEX) && (prAdapter->fgIsP2PRegistered)) -+#endif -+ ) { -+ if (prBssInfo->eCurrentOPMode == OP_MODE_INFRASTRUCTURE) { -+ rCmdIndicatePmBssConnected.fgIsUapsdConnection = -+ (UINT_8) prBssInfo->prStaRecOfAP->fgIsUapsdSupported; -+ } else { -+ rCmdIndicatePmBssConnected.fgIsUapsdConnection = 0; /* @FIXME */ -+ } -+ } else { -+ rCmdIndicatePmBssConnected.fgIsUapsdConnection = 0; -+ } -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_INDICATE_PM_BSS_CONNECTED, -+ TRUE, -+ FALSE, -+ FALSE, -+ NULL, -+ NULL, -+ sizeof(CMD_INDICATE_PM_BSS_CONNECTED), -+ (PUINT_8)&rCmdIndicatePmBssConnected, NULL, 0); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This utility function is used to indicate PM that -+* a BSS has been disconnected -+* -+* @param prAdapter Pointer of ADAPTER_T -+* eNetworkTypeIdx Index of BSS-INFO -+* -+* @retval - -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS nicPmIndicateBssAbort(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx) -+{ -+ CMD_INDICATE_PM_BSS_ABORT rCmdIndicatePmBssAbort; -+ -+ ASSERT(prAdapter); -+ ASSERT(eNetworkTypeIdx < NETWORK_TYPE_INDEX_NUM); -+ -+ rCmdIndicatePmBssAbort.ucNetTypeIndex = (UINT_8) eNetworkTypeIdx; -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_INDICATE_PM_BSS_ABORT, -+ TRUE, -+ FALSE, -+ FALSE, -+ NULL, -+ NULL, -+ sizeof(CMD_INDICATE_PM_BSS_ABORT), (PUINT_8)&rCmdIndicatePmBssAbort, NULL, 0); -+} -+ -+WLAN_STATUS -+nicConfigPowerSaveProfile(IN P_ADAPTER_T prAdapter, -+ ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, PARAM_POWER_MODE ePwrMode, BOOLEAN fgEnCmdEvent) -+{ -+ DEBUGFUNC("nicConfigPowerSaveProfile"); -+ DBGLOG(NIC, TRACE, "eNetTypeIndex:%d, ePwrMode:%d, fgEnCmdEvent:%d\n", -+ eNetTypeIndex, ePwrMode, fgEnCmdEvent); -+ -+ ASSERT(prAdapter); -+ -+ if (eNetTypeIndex >= NETWORK_TYPE_INDEX_NUM) { -+ ASSERT(0); -+ return WLAN_STATUS_NOT_SUPPORTED; -+ } -+/* prAdapter->rWlanInfo.ePowerSaveMode.ucNetTypeIndex = eNetTypeIndex; */ -+/* prAdapter->rWlanInfo.ePowerSaveMode.ucPsProfile = (UINT_8)ePwrMode; */ -+ prAdapter->rWlanInfo.arPowerSaveMode[eNetTypeIndex].ucNetTypeIndex = eNetTypeIndex; -+ prAdapter->rWlanInfo.arPowerSaveMode[eNetTypeIndex].ucPsProfile = (UINT_8) ePwrMode; -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_POWER_SAVE_MODE, -+ TRUE, -+ FALSE, -+ (fgEnCmdEvent ? TRUE : FALSE), -+ (fgEnCmdEvent ? nicCmdEventSetCommon : NULL), -+ (fgEnCmdEvent ? nicOidCmdTimeoutCommon : NULL), -+ sizeof(CMD_PS_PROFILE_T), -+ (PUINT_8)&(prAdapter->rWlanInfo.arPowerSaveMode[eNetTypeIndex]), -+ NULL, sizeof(PARAM_POWER_MODE) -+ ); -+ -+} /* end of wlanoidSetAcpiDevicePowerStateMode() */ -+ -+WLAN_STATUS nicEnterCtiaMode(IN P_ADAPTER_T prAdapter, BOOLEAN fgEnterCtia, BOOLEAN fgEnCmdEvent) -+{ -+ CMD_SW_DBG_CTRL_T rCmdSwCtrl; -+ CMD_ACCESS_REG rCmdAccessReg; -+ WLAN_STATUS rWlanStatus; -+ -+ DEBUGFUNC("nicEnterCtiaMode"); -+ DBGLOG(NIC, TRACE, "nicEnterCtiaMode: %d\n", fgEnterCtia); -+ -+ ASSERT(prAdapter); -+ -+ rWlanStatus = WLAN_STATUS_SUCCESS; -+ -+ if (fgEnterCtia) { -+ /* 1. Disable On-Lin Scan */ -+ prAdapter->fgEnOnlineScan = FALSE; -+ -+ /* 3. Disable FIFO FULL no ack */ -+ rCmdAccessReg.u4Address = 0x60140028; -+ rCmdAccessReg.u4Data = 0x904; -+ wlanSendSetQueryCmd(prAdapter, CMD_ID_ACCESS_REG, TRUE, /* FALSE, */ -+ FALSE, /* TRUE, */ -+ FALSE, NULL, NULL, sizeof(CMD_ACCESS_REG), (PUINT_8)&rCmdAccessReg, NULL, 0); -+ -+ /* 4. Disable Roaming */ -+ rCmdSwCtrl.u4Id = 0x90000204; -+ rCmdSwCtrl.u4Data = 0x0; -+ wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SW_DBG_CTRL, -+ TRUE, -+ FALSE, -+ FALSE, NULL, NULL, sizeof(CMD_SW_DBG_CTRL_T), (PUINT_8)&rCmdSwCtrl, NULL, 0); -+ -+ rCmdSwCtrl.u4Id = 0x90000200; -+ rCmdSwCtrl.u4Data = 0x820000; -+ wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SW_DBG_CTRL, -+ TRUE, -+ FALSE, -+ FALSE, NULL, NULL, sizeof(CMD_SW_DBG_CTRL_T), (PUINT_8)&rCmdSwCtrl, NULL, 0); -+ -+ /* Disalbe auto tx power */ -+ rCmdSwCtrl.u4Id = 0xa0100003; -+ rCmdSwCtrl.u4Data = 0x0; -+ wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SW_DBG_CTRL, -+ TRUE, -+ FALSE, -+ FALSE, NULL, NULL, sizeof(CMD_SW_DBG_CTRL_T), (PUINT_8)&rCmdSwCtrl, NULL, 0); -+ -+ /* 2. Keep at CAM mode */ -+ { -+ PARAM_POWER_MODE ePowerMode; -+ -+ prAdapter->u4CtiaPowerMode = 0; -+ prAdapter->fgEnCtiaPowerMode = TRUE; -+ -+ ePowerMode = Param_PowerModeCAM; -+ rWlanStatus = nicConfigPowerSaveProfile(prAdapter, -+ NETWORK_TYPE_AIS_INDEX, ePowerMode, fgEnCmdEvent); -+ } -+ -+ /* 5. Disable Beacon Timeout Detection */ -+ prAdapter->fgDisBcnLostDetection = TRUE; -+ } else { -+ /* 1. Enaable On-Lin Scan */ -+ prAdapter->fgEnOnlineScan = TRUE; -+ -+ /* 3. Enable FIFO FULL no ack */ -+ rCmdAccessReg.u4Address = 0x60140028; -+ rCmdAccessReg.u4Data = 0x905; -+ wlanSendSetQueryCmd(prAdapter, CMD_ID_ACCESS_REG, TRUE, /* FALSE, */ -+ FALSE, /* TRUE, */ -+ FALSE, NULL, NULL, sizeof(CMD_ACCESS_REG), (PUINT_8)&rCmdAccessReg, NULL, 0); -+ -+ /* 4. Enable Roaming */ -+ rCmdSwCtrl.u4Id = 0x90000204; -+ rCmdSwCtrl.u4Data = 0x1; -+ wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SW_DBG_CTRL, -+ TRUE, -+ FALSE, -+ FALSE, NULL, NULL, sizeof(CMD_SW_DBG_CTRL_T), (PUINT_8)&rCmdSwCtrl, NULL, 0); -+ -+ rCmdSwCtrl.u4Id = 0x90000200; -+ rCmdSwCtrl.u4Data = 0x820000; -+ wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SW_DBG_CTRL, -+ TRUE, -+ FALSE, -+ FALSE, NULL, NULL, sizeof(CMD_SW_DBG_CTRL_T), (PUINT_8)&rCmdSwCtrl, NULL, 0); -+ -+ /* Enable auto tx power */ -+ /* */ -+ -+ rCmdSwCtrl.u4Id = 0xa0100003; -+ rCmdSwCtrl.u4Data = 0x1; -+ wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SW_DBG_CTRL, -+ TRUE, -+ FALSE, -+ FALSE, NULL, NULL, sizeof(CMD_SW_DBG_CTRL_T), (PUINT_8)&rCmdSwCtrl, NULL, 0); -+ -+ /* 2. Keep at Fast PS */ -+ { -+ PARAM_POWER_MODE ePowerMode; -+ -+ prAdapter->u4CtiaPowerMode = 2; -+ prAdapter->fgEnCtiaPowerMode = TRUE; -+ -+ ePowerMode = Param_PowerModeFast_PSP; -+ rWlanStatus = nicConfigPowerSaveProfile(prAdapter, -+ NETWORK_TYPE_AIS_INDEX, ePowerMode, fgEnCmdEvent); -+ } -+ -+ /* 5. Enable Beacon Timeout Detection */ -+ prAdapter->fgDisBcnLostDetection = FALSE; -+ -+ } -+ -+ return rWlanStatus; -+} /* end of nicEnterCtiaMode() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This utility function is used to indicate firmware domain -+* for beacon generation parameters -+* -+* @param prAdapter Pointer of ADAPTER_T -+* eIeUpdMethod, Update Method -+* eNetTypeIndex Index of Network -+* u2Capability Capability -+* aucIe Pointer to buffer of IEs -+* u2IELen Length of IEs -+* -+* @retval - WLAN_STATUS_SUCCESS -+* WLAN_STATUS_FAILURE -+* WLAN_STATUS_PENDING -+* WLAN_STATUS_INVALID_DATA -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+nicUpdateBeaconIETemplate(IN P_ADAPTER_T prAdapter, -+ IN ENUM_IE_UPD_METHOD_T eIeUpdMethod, -+ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, -+ IN UINT_16 u2Capability, IN PUINT_8 aucIe, IN UINT_16 u2IELen) -+{ -+ P_CMD_BEACON_TEMPLATE_UPDATE prCmdBcnUpdate; -+ UINT_16 u2CmdBufLen = 0; -+ P_GLUE_INFO_T prGlueInfo; -+ P_CMD_INFO_T prCmdInfo; -+ P_WIFI_CMD_T prWifiCmd; -+ UINT_8 ucCmdSeqNum; -+ -+ DEBUGFUNC("wlanUpdateBeaconIETemplate"); -+ -+ DBGLOG(NIC, LOUD, "\nnicUpdateBeaconIETemplate\n"); -+ -+ ASSERT(prAdapter); -+ prGlueInfo = prAdapter->prGlueInfo; -+ -+ if (u2IELen > MAX_IE_LENGTH) -+ return WLAN_STATUS_INVALID_DATA; -+ -+ if (eIeUpdMethod == IE_UPD_METHOD_UPDATE_RANDOM || eIeUpdMethod == IE_UPD_METHOD_UPDATE_ALL) { -+ u2CmdBufLen = OFFSET_OF(CMD_BEACON_TEMPLATE_UPDATE, aucIE) + u2IELen; -+ } else if (eIeUpdMethod == IE_UPD_METHOD_DELETE_ALL) { -+ u2CmdBufLen = OFFSET_OF(CMD_BEACON_TEMPLATE_UPDATE, u2IELen); -+ } else { -+ ASSERT(0); -+ return WLAN_STATUS_FAILURE; -+ } -+ -+ /* prepare command info */ -+ prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, (CMD_HDR_SIZE + u2CmdBufLen)); -+ if (!prCmdInfo) { -+ DBGLOG(NIC, ERROR, "Allocate CMD_INFO_T ==> FAILED.\n"); -+ return WLAN_STATUS_FAILURE; -+ } -+ /* increase command sequence number */ -+ ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter); -+ DBGLOG(REQ, TRACE, "ucCmdSeqNum =%d\n", ucCmdSeqNum); -+ -+ /* Setup common CMD Info Packet */ -+ prCmdInfo->eCmdType = COMMAND_TYPE_NETWORK_IOCTL; -+ prCmdInfo->eNetworkType = eNetTypeIndex; -+ prCmdInfo->u2InfoBufLen = (UINT_16) (CMD_HDR_SIZE + u2CmdBufLen); -+ prCmdInfo->pfCmdDoneHandler = NULL; /* @FIXME */ -+ prCmdInfo->pfCmdTimeoutHandler = NULL; /* @FIXME */ -+ prCmdInfo->fgIsOid = FALSE; -+ prCmdInfo->ucCID = CMD_ID_UPDATE_BEACON_CONTENT; -+ prCmdInfo->fgSetQuery = TRUE; -+ prCmdInfo->fgNeedResp = FALSE; -+ prCmdInfo->fgDriverDomainMCR = FALSE; -+ prCmdInfo->ucCmdSeqNum = ucCmdSeqNum; -+ prCmdInfo->u4SetInfoLen = u2CmdBufLen; -+ prCmdInfo->pvInformationBuffer = NULL; -+ prCmdInfo->u4InformationBufferLength = 0; -+ -+ /* Setup WIFI_CMD_T (no payload) */ -+ prWifiCmd = (P_WIFI_CMD_T) (prCmdInfo->pucInfoBuffer); -+ prWifiCmd->u2TxByteCount_UserPriority = prCmdInfo->u2InfoBufLen; -+ prWifiCmd->ucCID = prCmdInfo->ucCID; -+ prWifiCmd->ucSetQuery = prCmdInfo->fgSetQuery; -+ prWifiCmd->ucSeqNum = prCmdInfo->ucCmdSeqNum; -+ -+ prCmdBcnUpdate = (P_CMD_BEACON_TEMPLATE_UPDATE) (prWifiCmd->aucBuffer); -+ -+ /* fill beacon updating command */ -+ prCmdBcnUpdate->ucUpdateMethod = (UINT_8) eIeUpdMethod; -+ prCmdBcnUpdate->ucNetTypeIndex = (UINT_8) eNetTypeIndex; -+ prCmdBcnUpdate->u2Capability = u2Capability; -+ prCmdBcnUpdate->u2IELen = u2IELen; -+ if (u2IELen > 0) -+ kalMemCopy(prCmdBcnUpdate->aucIE, aucIe, u2IELen); -+ -+ /* insert into prCmdQueue */ -+ kalEnqueueCommand(prGlueInfo, (P_QUE_ENTRY_T) prCmdInfo); -+ -+ /* wakeup txServiceThread later */ -+ GLUE_SET_EVENT(prGlueInfo); -+ return WLAN_STATUS_PENDING; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This utility function is used to initialization PHY related -+* varaibles -+* -+* @param prAdapter Pointer of ADAPTER_T -+* -+* @retval none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicSetAvailablePhyTypeSet(IN P_ADAPTER_T prAdapter) -+{ -+ P_CONNECTION_SETTINGS_T prConnSettings; -+ -+ ASSERT(prAdapter); -+ -+ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); -+ -+ if (prConnSettings->eDesiredPhyConfig >= PHY_CONFIG_NUM) { -+ ASSERT(0); -+ return; -+ } -+ -+ prAdapter->rWifiVar.ucAvailablePhyTypeSet = aucPhyCfg2PhyTypeSet[prConnSettings->eDesiredPhyConfig]; -+ -+ if (prAdapter->rWifiVar.ucAvailablePhyTypeSet & PHY_TYPE_BIT_ERP) -+ prAdapter->rWifiVar.eNonHTBasicPhyType2G4 = PHY_TYPE_ERP_INDEX; -+ /* NOTE(Kevin): Because we don't have N only mode, TBD */ -+ else { /* if (ucNonHTPhyTypeSet & PHY_TYPE_HR_DSSS_INDEX) */ -+ -+ prAdapter->rWifiVar.eNonHTBasicPhyType2G4 = PHY_TYPE_HR_DSSS_INDEX; -+ } -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This utility function is used to update WMM Parms -+* -+* @param prAdapter Pointer of ADAPTER_T -+* eNetworkTypeIdx Index of BSS-INFO -+* -+* @retval - -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS nicQmUpdateWmmParms(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx) -+{ -+ P_BSS_INFO_T prBssInfo; -+ CMD_UPDATE_WMM_PARMS_T rCmdUpdateWmmParms; -+ -+ ASSERT(prAdapter); -+ ASSERT(eNetworkTypeIdx < NETWORK_TYPE_INDEX_NUM); -+ -+ DBGLOG(QM, EVENT, "sizeof(AC_QUE_PARMS_T): %zu\n", sizeof(AC_QUE_PARMS_T)); -+ DBGLOG(QM, EVENT, "sizeof(CMD_UPDATE_WMM_PARMS): %zu\n", sizeof(CMD_UPDATE_WMM_PARMS_T)); -+ DBGLOG(QM, EVENT, "sizeof(WIFI_CMD_T): %zu\n", sizeof(WIFI_CMD_T)); -+ -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[eNetworkTypeIdx]); -+ rCmdUpdateWmmParms.ucNetTypeIndex = (UINT_8) eNetworkTypeIdx; -+ kalMemCopy(&rCmdUpdateWmmParms.arACQueParms[0], &prBssInfo->arACQueParms[0], (sizeof(AC_QUE_PARMS_T) * AC_NUM)); -+ -+ rCmdUpdateWmmParms.fgIsQBSS = prBssInfo->fgIsQBSS; -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_UPDATE_WMM_PARMS, -+ TRUE, -+ FALSE, -+ FALSE, -+ NULL, NULL, sizeof(CMD_UPDATE_WMM_PARMS_T), (PUINT_8)&rCmdUpdateWmmParms, NULL, 0); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This utility function is used to update TX power gain corresponding to -+* each band/modulation combination -+* -+* @param prAdapter Pointer of ADAPTER_T -+* prTxPwrParam Pointer of TX power parameters -+* -+* @retval WLAN_STATUS_PENDING -+* WLAN_STATUS_FAILURE -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS nicUpdateTxPower(IN P_ADAPTER_T prAdapter, IN P_CMD_TX_PWR_T prTxPwrParam) -+{ -+ DEBUGFUNC("nicUpdateTxPower"); -+ -+ ASSERT(prAdapter); -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SET_TX_PWR, -+ TRUE, -+ FALSE, FALSE, NULL, NULL, sizeof(CMD_TX_PWR_T), (PUINT_8) prTxPwrParam, NULL, 0); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This utility function is used to set auto tx power parameter -+* -+* @param prAdapter Pointer of ADAPTER_T -+* prTxPwrParam Pointer of Auto TX power parameters -+* -+* @retval WLAN_STATUS_PENDING -+* WLAN_STATUS_FAILURE -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS nicSetAutoTxPower(IN P_ADAPTER_T prAdapter, IN P_CMD_AUTO_POWER_PARAM_T prAutoPwrParam) -+{ -+ DEBUGFUNC("nicSetAutoTxPower"); -+ -+ ASSERT(prAdapter); -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SET_AUTOPWR_CTRL, -+ TRUE, -+ FALSE, -+ FALSE, -+ NULL, NULL, sizeof(CMD_AUTO_POWER_PARAM_T), (PUINT_8) prAutoPwrParam, NULL, 0); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This utility function is used to update TX power gain corresponding to -+* each band/modulation combination -+* -+* @param prAdapter Pointer of ADAPTER_T -+* prTxPwrParam Pointer of TX power parameters -+* -+* @retval WLAN_STATUS_PENDING -+* WLAN_STATUS_FAILURE -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS nicSetAutoTxPowerControl(IN P_ADAPTER_T prAdapter, IN P_CMD_TX_PWR_T prTxPwrParam) -+{ -+ DEBUGFUNC("nicUpdateTxPower"); -+ -+ ASSERT(prAdapter); -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SET_TX_PWR, -+ TRUE, -+ FALSE, FALSE, NULL, NULL, sizeof(CMD_TX_PWR_T), (PUINT_8) prTxPwrParam, NULL, 0); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This utility function is used to update power offset around 5GHz band -+* -+* @param prAdapter Pointer of ADAPTER_T -+* pr5GPwrOffset Pointer of 5GHz power offset parameter -+* -+* @retval WLAN_STATUS_PENDING -+* WLAN_STATUS_FAILURE -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS nicUpdate5GOffset(IN P_ADAPTER_T prAdapter, IN P_CMD_5G_PWR_OFFSET_T pr5GPwrOffset) -+{ -+ DEBUGFUNC("nicUpdate5GOffset"); -+ -+ ASSERT(prAdapter); -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SET_5G_PWR_OFFSET, -+ TRUE, -+ FALSE, -+ FALSE, NULL, NULL, sizeof(CMD_5G_PWR_OFFSET_T), (PUINT_8) pr5GPwrOffset, NULL, 0); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This utility function is used to update DPD calibration result -+* -+* @param prAdapter Pointer of ADAPTER_T -+* pr5GPwrOffset Pointer of parameter for DPD calibration result -+* -+* @retval WLAN_STATUS_PENDING -+* WLAN_STATUS_FAILURE -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS nicUpdateDPD(IN P_ADAPTER_T prAdapter, IN P_CMD_PWR_PARAM_T prDpdCalResult) -+{ -+ DEBUGFUNC("nicUpdateDPD"); -+ -+ ASSERT(prAdapter); -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SET_PWR_PARAM, -+ TRUE, -+ FALSE, -+ FALSE, NULL, NULL, sizeof(CMD_PWR_PARAM_T), (PUINT_8) prDpdCalResult, NULL, 0); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This utility function starts system service such as timer and -+* memory pools -+* -+* @param prAdapter Pointer of ADAPTER_T -+* -+* @retval none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicInitSystemService(IN P_ADAPTER_T prAdapter) -+{ -+ ASSERT(prAdapter); -+ -+ /* <1> Initialize MGMT Memory pool and STA_REC */ -+ cnmMemInit(prAdapter); -+ cnmStaRecInit(prAdapter); -+ cmdBufInitialize(prAdapter); -+ -+ /* <2> Mailbox Initialization */ -+ mboxInitialize(prAdapter); -+ -+ /* <3> Timer Initialization */ -+ cnmTimerInitialize(prAdapter); -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This utility function reset some specific system service, -+* such as STA-REC -+* -+* @param prAdapter Pointer of ADAPTER_T -+* -+* @retval none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicResetSystemService(IN P_ADAPTER_T prAdapter) -+{ -+ ASSERT(prAdapter); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This utility function is used to update WMM Parms -+* -+* @param prAdapter Pointer of ADAPTER_T -+* -+* @retval none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicUninitSystemService(IN P_ADAPTER_T prAdapter) -+{ -+ ASSERT(prAdapter); -+ -+ /* Timer Destruction */ -+ cnmTimerDestroy(prAdapter); -+ -+ /* Mailbox Destruction */ -+ mboxDestroy(prAdapter); -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This utility function is used to update WMM Parms -+* -+* @param prAdapter Pointer of ADAPTER_T -+* -+* @retval none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicInitMGMT(IN P_ADAPTER_T prAdapter, IN P_REG_INFO_T prRegInfo) -+{ -+ ASSERT(prAdapter); -+ -+ /* CNM Module - initialization */ -+ cnmInit(prAdapter); -+ -+ /* RLM Module - initialization */ -+ rlmFsmEventInit(prAdapter); -+ -+ /* SCN Module - initialization */ -+ scnInit(prAdapter); -+ -+ /* AIS Module - intiailization */ -+ aisInitializeConnectionSettings(prAdapter, prRegInfo); -+ aisFsmInit(prAdapter); -+ -+#if CFG_SUPPORT_ROAMING -+ /* Roaming Module - intiailization */ -+ roamingFsmInit(prAdapter); -+#endif /* CFG_SUPPORT_ROAMING */ -+ -+#if CFG_SUPPORT_SWCR -+ swCrDebugInit(prAdapter); -+#endif /* CFG_SUPPORT_SWCR */ -+ -+#if (CFG_SUPPORT_TDLS == 1) -+ TdlsexInit(prAdapter); -+#endif /* CFG_SUPPORT_TDLS */ -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This utility function is used to update WMM Parms -+* -+* @param prAdapter Pointer of ADAPTER_T -+* -+* @retval none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicUninitMGMT(IN P_ADAPTER_T prAdapter) -+{ -+ ASSERT(prAdapter); -+ -+#if CFG_SUPPORT_SWCR -+ swCrDebugUninit(prAdapter); -+#endif /* CFG_SUPPORT_SWCR */ -+ -+#if CFG_SUPPORT_ROAMING -+ /* Roaming Module - unintiailization */ -+ roamingFsmUninit(prAdapter); -+#endif /* CFG_SUPPORT_ROAMING */ -+ -+ /* AIS Module - unintiailization */ -+ aisFsmUninit(prAdapter); -+ -+ /* SCN Module - unintiailization */ -+ scnUninit(prAdapter); -+ -+ /* RLM Module - uninitialization */ -+ rlmFsmEventUninit(prAdapter); -+ -+ /* CNM Module - uninitialization */ -+ cnmUninit(prAdapter); -+ -+#if (CFG_SUPPORT_TDLS == 1) -+ TdlsexUninit(prAdapter); -+#endif /* CFG_SUPPORT_TDLS */ -+ -+} -+ -+#if (MT6620_E1_ASIC_HIFSYS_WORKAROUND == 1) -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This utility function is to inform firmware to enable MCU clock gating -+* -+* @param prAdapter Pointer of ADAPTER_T -+* -+* @retval none -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS nicEnableClockGating(IN P_ADAPTER_T prAdapter) -+{ -+ UINT_32 i, u4WHISR = 0; -+ -+ ASSERT(prAdapter); -+ -+ if (prAdapter->fgIsClockGatingEnabled == TRUE) -+ return WLAN_STATUS_SUCCESS; -+ -+ nicSetSwIntr(prAdapter, REQ_GATING_ENABLE_H2D_INT); -+ -+ i = 0; -+ while (i < GATING_CONTROL_POLL_LIMIT) { -+ if (kalIsCardRemoved(prAdapter->prGlueInfo) == TRUE || fgIsBusAccessFailed == TRUE) -+ return WLAN_STATUS_FAILURE; -+ -+ HAL_READ_INTR_STATUS(prAdapter, sizeof(UINT_32), (PUINT_8)&u4WHISR); -+ -+ if (u4WHISR & ACK_GATING_ENABLE_D2H_INT) { -+ prAdapter->fgIsClockGatingEnabled = TRUE; -+ return WLAN_STATUS_SUCCESS; -+ } -+ } -+ -+ ASSERT(0); -+ return WLAN_STATUS_PENDING; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This utility function is to inform firmware to disable MCU clock gating -+* -+* @param prAdapter Pointer of ADAPTER_T -+* -+* @retval none -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS nicDisableClockGating(IN P_ADAPTER_T prAdapter) -+{ -+ UINT_32 i, u4WHISR = 0; -+ -+ ASSERT(prAdapter); -+ -+ if (prAdapter->fgIsClockGatingEnabled == FALSE) -+ return WLAN_STATUS_SUCCESS; -+ -+ nicSetSwIntr(prAdapter, REQ_GATING_DISABLE_H2D_INT); -+ -+ i = 0; -+ while (i < GATING_CONTROL_POLL_LIMIT) { -+ if (kalIsCardRemoved(prAdapter->prGlueInfo) == TRUE || fgIsBusAccessFailed == TRUE) -+ return WLAN_STATUS_FAILURE; -+ -+ HAL_READ_INTR_STATUS(prAdapter, sizeof(UINT_32), (PUINT_8)&u4WHISR); -+ -+ if (u4WHISR & ACK_GATING_DISABLE_D2H_INT) { -+ prAdapter->fgIsClockGatingEnabled = FALSE; -+ return WLAN_STATUS_SUCCESS; -+ } -+ } -+ -+ ASSERT(0); -+ return WLAN_STATUS_PENDING; -+} -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is invoked to buffer scan result -+* -+* @param prAdapter Pointer to the Adapter structure. -+* @param rMacAddr BSSID -+* @param prSsid Pointer to SSID -+* @param u4Privacy Privacy settings (0: Open / 1: WEP/WPA/WPA2 enabled) -+* @param rRssi Received Strength (-10 ~ -200 dBm) -+* @param eNetworkType Network Type (a/b/g) -+* @param prConfiguration Network Parameter -+* @param eOpMode Infra/Ad-Hoc -+* @param rSupportedRates Supported basic rates -+* @param u2IELength IE Length -+* @param pucIEBuf Pointer to Information Elements(IEs) -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+nicAddScanResult(IN P_ADAPTER_T prAdapter, -+ IN PARAM_MAC_ADDRESS rMacAddr, -+ IN P_PARAM_SSID_T prSsid, -+ IN UINT_32 u4Privacy, -+ IN PARAM_RSSI rRssi, -+ IN ENUM_PARAM_NETWORK_TYPE_T eNetworkType, -+ IN P_PARAM_802_11_CONFIG_T prConfiguration, -+ IN ENUM_PARAM_OP_MODE_T eOpMode, -+ IN PARAM_RATES_EX rSupportedRates, IN UINT_16 u2IELength, IN PUINT_8 pucIEBuf) -+{ -+ BOOLEAN bReplace; -+ UINT_32 i; -+ UINT_32 u4IdxWeakest = 0; -+ PARAM_RSSI rWeakestRssi; -+ UINT_32 u4BufferSize; -+ -+ ASSERT(prAdapter); -+ -+ rWeakestRssi = (PARAM_RSSI) INT_MAX; -+ u4BufferSize = sizeof(prAdapter->rWlanInfo.aucScanIEBuf) / sizeof(prAdapter->rWlanInfo.aucScanIEBuf[0]); -+ -+ bReplace = FALSE; -+ -+ /* decide to replace or add */ -+ for (i = 0; i < prAdapter->rWlanInfo.u4ScanResultNum; i++) { -+ /* find weakest entry && not connected one */ -+ if (UNEQUAL_MAC_ADDR -+ (prAdapter->rWlanInfo.arScanResult[i].arMacAddress, prAdapter->rWlanInfo.rCurrBssId.arMacAddress) -+ && prAdapter->rWlanInfo.arScanResult[i].rRssi < rWeakestRssi) { -+ u4IdxWeakest = i; -+ rWeakestRssi = prAdapter->rWlanInfo.arScanResult[i].rRssi; -+ } -+ -+ if (prAdapter->rWlanInfo.arScanResult[i].eOpMode == eOpMode && -+ EQUAL_MAC_ADDR(&(prAdapter->rWlanInfo.arScanResult[i].arMacAddress), rMacAddr) && -+ (EQUAL_SSID(prAdapter->rWlanInfo.arScanResult[i].rSsid.aucSsid, -+ prAdapter->rWlanInfo.arScanResult[i].rSsid.u4SsidLen, -+ prSsid->aucSsid, prSsid->u4SsidLen) -+ || prAdapter->rWlanInfo.arScanResult[i].rSsid.u4SsidLen == 0)) { -+ /* replace entry */ -+ bReplace = TRUE; -+ -+ /* free IE buffer then zero */ -+ nicFreeScanResultIE(prAdapter, i); -+ kalMemZero(&(prAdapter->rWlanInfo.arScanResult[i]), OFFSET_OF(PARAM_BSSID_EX_T, aucIEs)); -+ -+ /* then fill buffer */ -+ prAdapter->rWlanInfo.arScanResult[i].u4Length = -+ OFFSET_OF(PARAM_BSSID_EX_T, aucIEs) + u2IELength; -+ COPY_MAC_ADDR(prAdapter->rWlanInfo.arScanResult[i].arMacAddress, rMacAddr); -+ COPY_SSID(prAdapter->rWlanInfo.arScanResult[i].rSsid.aucSsid, -+ prAdapter->rWlanInfo.arScanResult[i].rSsid.u4SsidLen, -+ prSsid->aucSsid, prSsid->u4SsidLen); -+ prAdapter->rWlanInfo.arScanResult[i].u4Privacy = u4Privacy; -+ prAdapter->rWlanInfo.arScanResult[i].rRssi = rRssi; -+ prAdapter->rWlanInfo.arScanResult[i].eNetworkTypeInUse = eNetworkType; -+ kalMemCopy(&(prAdapter->rWlanInfo.arScanResult[i].rConfiguration), -+ prConfiguration, sizeof(PARAM_802_11_CONFIG_T)); -+ prAdapter->rWlanInfo.arScanResult[i].eOpMode = eOpMode; -+ kalMemCopy((prAdapter->rWlanInfo.arScanResult[i].rSupportedRates), -+ rSupportedRates, sizeof(PARAM_RATES_EX)); -+ prAdapter->rWlanInfo.arScanResult[i].u4IELength = (UINT_32) u2IELength; -+ -+ /* IE - allocate buffer and update pointer */ -+ if (u2IELength > 0) { -+ if (ALIGN_4(u2IELength) + prAdapter->rWlanInfo.u4ScanIEBufferUsage <= u4BufferSize) { -+ kalMemCopy(& -+ (prAdapter-> -+ rWlanInfo.aucScanIEBuf[prAdapter->rWlanInfo.u4ScanIEBufferUsage]), -+ pucIEBuf, u2IELength); -+ -+ prAdapter->rWlanInfo.apucScanResultIEs[i] = -+ &(prAdapter-> -+ rWlanInfo.aucScanIEBuf[prAdapter->rWlanInfo.u4ScanIEBufferUsage]); -+ -+ prAdapter->rWlanInfo.u4ScanIEBufferUsage += ALIGN_4(u2IELength); -+ } else { -+ /* buffer is not enough */ -+ prAdapter->rWlanInfo.arScanResult[i].u4Length -= u2IELength; -+ prAdapter->rWlanInfo.arScanResult[i].u4IELength = 0; -+ prAdapter->rWlanInfo.apucScanResultIEs[i] = NULL; -+ } -+ } else { -+ prAdapter->rWlanInfo.apucScanResultIEs[i] = NULL; -+ } -+ -+ break; -+ } -+ } -+ -+ if (bReplace == FALSE) { -+ if (prAdapter->rWlanInfo.u4ScanResultNum < (CFG_MAX_NUM_BSS_LIST - 1)) { -+ i = prAdapter->rWlanInfo.u4ScanResultNum; -+ -+ /* zero */ -+ kalMemZero(&(prAdapter->rWlanInfo.arScanResult[i]), OFFSET_OF(PARAM_BSSID_EX_T, aucIEs)); -+ -+ /* then fill buffer */ -+ prAdapter->rWlanInfo.arScanResult[i].u4Length = -+ OFFSET_OF(PARAM_BSSID_EX_T, aucIEs) + u2IELength; -+ COPY_MAC_ADDR(prAdapter->rWlanInfo.arScanResult[i].arMacAddress, rMacAddr); -+ COPY_SSID(prAdapter->rWlanInfo.arScanResult[i].rSsid.aucSsid, -+ prAdapter->rWlanInfo.arScanResult[i].rSsid.u4SsidLen, -+ prSsid->aucSsid, prSsid->u4SsidLen); -+ prAdapter->rWlanInfo.arScanResult[i].u4Privacy = u4Privacy; -+ prAdapter->rWlanInfo.arScanResult[i].rRssi = rRssi; -+ prAdapter->rWlanInfo.arScanResult[i].eNetworkTypeInUse = eNetworkType; -+ kalMemCopy(&(prAdapter->rWlanInfo.arScanResult[i].rConfiguration), -+ prConfiguration, sizeof(PARAM_802_11_CONFIG_T)); -+ prAdapter->rWlanInfo.arScanResult[i].eOpMode = eOpMode; -+ kalMemCopy((prAdapter->rWlanInfo.arScanResult[i].rSupportedRates), -+ rSupportedRates, sizeof(PARAM_RATES_EX)); -+ prAdapter->rWlanInfo.arScanResult[i].u4IELength = (UINT_32) u2IELength; -+ -+ /* IE - allocate buffer and update pointer */ -+ if (u2IELength > 0) { -+ if (ALIGN_4(u2IELength) + prAdapter->rWlanInfo.u4ScanIEBufferUsage <= u4BufferSize) { -+ kalMemCopy(& -+ (prAdapter-> -+ rWlanInfo.aucScanIEBuf[prAdapter->rWlanInfo.u4ScanIEBufferUsage]), -+ pucIEBuf, u2IELength); -+ -+ prAdapter->rWlanInfo.apucScanResultIEs[i] = -+ &(prAdapter-> -+ rWlanInfo.aucScanIEBuf[prAdapter->rWlanInfo.u4ScanIEBufferUsage]); -+ -+ prAdapter->rWlanInfo.u4ScanIEBufferUsage += ALIGN_4(u2IELength); -+ } else { -+ /* buffer is not enough */ -+ prAdapter->rWlanInfo.arScanResult[i].u4Length -= u2IELength; -+ prAdapter->rWlanInfo.arScanResult[i].u4IELength = 0; -+ prAdapter->rWlanInfo.apucScanResultIEs[i] = NULL; -+ } -+ } else { -+ prAdapter->rWlanInfo.apucScanResultIEs[i] = NULL; -+ } -+ -+ prAdapter->rWlanInfo.u4ScanResultNum++; -+ } else if (rWeakestRssi != (PARAM_RSSI) INT_MAX) { -+ /* replace weakest one */ -+ i = u4IdxWeakest; -+ -+ /* free IE buffer then zero */ -+ nicFreeScanResultIE(prAdapter, i); -+ kalMemZero(&(prAdapter->rWlanInfo.arScanResult[i]), OFFSET_OF(PARAM_BSSID_EX_T, aucIEs)); -+ -+ /* then fill buffer */ -+ prAdapter->rWlanInfo.arScanResult[i].u4Length = -+ OFFSET_OF(PARAM_BSSID_EX_T, aucIEs) + u2IELength; -+ COPY_MAC_ADDR(prAdapter->rWlanInfo.arScanResult[i].arMacAddress, rMacAddr); -+ COPY_SSID(prAdapter->rWlanInfo.arScanResult[i].rSsid.aucSsid, -+ prAdapter->rWlanInfo.arScanResult[i].rSsid.u4SsidLen, -+ prSsid->aucSsid, prSsid->u4SsidLen); -+ prAdapter->rWlanInfo.arScanResult[i].u4Privacy = u4Privacy; -+ prAdapter->rWlanInfo.arScanResult[i].rRssi = rRssi; -+ prAdapter->rWlanInfo.arScanResult[i].eNetworkTypeInUse = eNetworkType; -+ kalMemCopy(&(prAdapter->rWlanInfo.arScanResult[i].rConfiguration), -+ prConfiguration, sizeof(PARAM_802_11_CONFIG_T)); -+ prAdapter->rWlanInfo.arScanResult[i].eOpMode = eOpMode; -+ kalMemCopy((prAdapter->rWlanInfo.arScanResult[i].rSupportedRates), -+ rSupportedRates, sizeof(PARAM_RATES_EX)); -+ prAdapter->rWlanInfo.arScanResult[i].u4IELength = (UINT_32) u2IELength; -+ -+ if (u2IELength > 0) { -+ /* IE - allocate buffer and update pointer */ -+ if (ALIGN_4(u2IELength) + prAdapter->rWlanInfo.u4ScanIEBufferUsage <= u4BufferSize) { -+ kalMemCopy(& -+ (prAdapter-> -+ rWlanInfo.aucScanIEBuf[prAdapter->rWlanInfo.u4ScanIEBufferUsage]), -+ pucIEBuf, u2IELength); -+ -+ prAdapter->rWlanInfo.apucScanResultIEs[i] = -+ &(prAdapter-> -+ rWlanInfo.aucScanIEBuf[prAdapter->rWlanInfo.u4ScanIEBufferUsage]); -+ -+ prAdapter->rWlanInfo.u4ScanIEBufferUsage += ALIGN_4(u2IELength); -+ } else { -+ /* buffer is not enough */ -+ prAdapter->rWlanInfo.arScanResult[i].u4Length -= u2IELength; -+ prAdapter->rWlanInfo.arScanResult[i].u4IELength = 0; -+ prAdapter->rWlanInfo.apucScanResultIEs[i] = NULL; -+ } -+ } else { -+ prAdapter->rWlanInfo.apucScanResultIEs[i] = NULL; -+ } -+ } -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is invoked to free IE buffer for dedicated scan result -+* -+* @param prAdapter Pointer to the Adapter structure. -+* @param u4Idx Index of Scan Result -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicFreeScanResultIE(IN P_ADAPTER_T prAdapter, IN UINT_32 u4Idx) -+{ -+ UINT_32 i; -+ PUINT_8 pucPivot, pucMovePivot; -+ UINT_32 u4MoveSize, u4FreeSize, u4ReserveSize; -+ -+ ASSERT(prAdapter); -+ ASSERT(u4Idx < CFG_MAX_NUM_BSS_LIST); -+ -+ if (prAdapter->rWlanInfo.arScanResult[u4Idx].u4IELength == 0 -+ || prAdapter->rWlanInfo.apucScanResultIEs[u4Idx] == NULL) { -+ return; -+ } -+ -+ u4FreeSize = ALIGN_4(prAdapter->rWlanInfo.arScanResult[u4Idx].u4IELength); -+ -+ pucPivot = prAdapter->rWlanInfo.apucScanResultIEs[u4Idx]; -+ pucMovePivot = (PUINT_8) ((ULONG) (prAdapter->rWlanInfo.apucScanResultIEs[u4Idx]) + u4FreeSize); -+ -+ u4ReserveSize = ((ULONG) pucPivot) - (ULONG) (&(prAdapter->rWlanInfo.aucScanIEBuf[0])); -+ u4MoveSize = prAdapter->rWlanInfo.u4ScanIEBufferUsage - u4ReserveSize - u4FreeSize; -+ -+ /* 1. rest of buffer to move forward */ -+ kalMemCopy(pucPivot, pucMovePivot, u4MoveSize); -+ -+ /* 1.1 modify pointers */ -+ for (i = 0; i < prAdapter->rWlanInfo.u4ScanResultNum; i++) { -+ if (i != u4Idx) { -+ if (prAdapter->rWlanInfo.apucScanResultIEs[i] >= pucMovePivot) { -+ prAdapter->rWlanInfo.apucScanResultIEs[i] = -+ (PUINT_8) ((ULONG) (prAdapter->rWlanInfo.apucScanResultIEs[i]) - u4FreeSize); -+ } -+ } -+ } -+ -+ /* 1.2 reset the freed one */ -+ prAdapter->rWlanInfo.arScanResult[u4Idx].u4IELength = 0; -+ prAdapter->rWlanInfo.apucScanResultIEs[i] = NULL; -+ -+ /* 2. reduce IE buffer usage */ -+ prAdapter->rWlanInfo.u4ScanIEBufferUsage -= u4FreeSize; -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is to hack parameters for WLAN TABLE for -+* fixed rate settings -+* -+* @param prAdapter Pointer to the Adapter structure. -+* @param eRateSetting -+* @param pu2DesiredNonHTRateSet, -+* @param pu2BSSBasicRateSet, -+* @param pucMcsSet -+* @param pucSupMcs32 -+* @param pu2HtCapInfo -+* -+* @return WLAN_STATUS_SUCCESS -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+nicUpdateRateParams(IN P_ADAPTER_T prAdapter, -+ IN ENUM_REGISTRY_FIXED_RATE_T eRateSetting, -+ IN PUINT_8 pucDesiredPhyTypeSet, -+ IN PUINT_16 pu2DesiredNonHTRateSet, -+ IN PUINT_16 pu2BSSBasicRateSet, -+ IN PUINT_8 pucMcsSet, IN PUINT_8 pucSupMcs32, IN PUINT_16 pu2HtCapInfo) -+{ -+ ASSERT(prAdapter); -+ ASSERT(eRateSetting > FIXED_RATE_NONE && eRateSetting < FIXED_RATE_NUM); -+ -+ switch (prAdapter->rWifiVar.eRateSetting) { -+ case FIXED_RATE_1M: -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HR_DSSS; -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_1M; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_1M; -+ *pucMcsSet = 0; -+ *pucSupMcs32 = 0; -+ *pu2HtCapInfo = 0; -+ break; -+ -+ case FIXED_RATE_2M: -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HR_DSSS; -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_2M; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_2M; -+ *pucMcsSet = 0; -+ *pucSupMcs32 = 0; -+ *pu2HtCapInfo = 0; -+ break; -+ -+ case FIXED_RATE_5_5M: -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HR_DSSS; -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_5_5M; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_5_5M; -+ *pucMcsSet = 0; -+ *pucSupMcs32 = 0; -+ *pu2HtCapInfo = 0; -+ break; -+ -+ case FIXED_RATE_11M: -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HR_DSSS; -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_11M; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_11M; -+ *pucMcsSet = 0; -+ *pucSupMcs32 = 0; -+ *pu2HtCapInfo = 0; -+ break; -+ -+ case FIXED_RATE_6M: -+ if ((*pucDesiredPhyTypeSet) & PHY_TYPE_BIT_ERP) -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_ERP; -+ else if ((*pucDesiredPhyTypeSet) & PHY_TYPE_BIT_OFDM) -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_OFDM; -+ -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_6M; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_6M; -+ *pucMcsSet = 0; -+ *pucSupMcs32 = 0; -+ *pu2HtCapInfo = 0; -+ break; -+ -+ case FIXED_RATE_9M: -+ if ((*pucDesiredPhyTypeSet) & PHY_TYPE_BIT_ERP) -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_ERP; -+ else if ((*pucDesiredPhyTypeSet) & PHY_TYPE_BIT_OFDM) -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_OFDM; -+ -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_9M; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_9M; -+ *pucMcsSet = 0; -+ *pucSupMcs32 = 0; -+ *pu2HtCapInfo = 0; -+ break; -+ -+ case FIXED_RATE_12M: -+ if ((*pucDesiredPhyTypeSet) & PHY_TYPE_BIT_ERP) -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_ERP; -+ else if ((*pucDesiredPhyTypeSet) & PHY_TYPE_BIT_OFDM) -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_OFDM; -+ -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_12M; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_12M; -+ *pucMcsSet = 0; -+ *pucSupMcs32 = 0; -+ *pu2HtCapInfo = 0; -+ break; -+ -+ case FIXED_RATE_18M: -+ if ((*pucDesiredPhyTypeSet) & PHY_TYPE_BIT_ERP) -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_ERP; -+ else if ((*pucDesiredPhyTypeSet) & PHY_TYPE_BIT_OFDM) -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_OFDM; -+ -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_18M; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_18M; -+ *pucMcsSet = 0; -+ *pucSupMcs32 = 0; -+ *pu2HtCapInfo = 0; -+ break; -+ -+ case FIXED_RATE_24M: -+ if ((*pucDesiredPhyTypeSet) & PHY_TYPE_BIT_ERP) -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_ERP; -+ else if ((*pucDesiredPhyTypeSet) & PHY_TYPE_BIT_OFDM) -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_OFDM; -+ -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_24M; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_24M; -+ *pucMcsSet = 0; -+ *pucSupMcs32 = 0; -+ *pu2HtCapInfo = 0; -+ break; -+ -+ case FIXED_RATE_36M: -+ if ((*pucDesiredPhyTypeSet) & PHY_TYPE_BIT_ERP) -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_ERP; -+ else if ((*pucDesiredPhyTypeSet) & PHY_TYPE_BIT_OFDM) -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_OFDM; -+ -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_36M; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_36M; -+ *pucMcsSet = 0; -+ *pucSupMcs32 = 0; -+ *pu2HtCapInfo = 0; -+ break; -+ -+ case FIXED_RATE_48M: -+ if ((*pucDesiredPhyTypeSet) & PHY_TYPE_BIT_ERP) -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_ERP; -+ else if ((*pucDesiredPhyTypeSet) & PHY_TYPE_BIT_OFDM) -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_OFDM; -+ -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_48M; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_48M; -+ *pucMcsSet = 0; -+ *pucSupMcs32 = 0; -+ *pu2HtCapInfo = 0; -+ break; -+ -+ case FIXED_RATE_54M: -+ if ((*pucDesiredPhyTypeSet) & PHY_TYPE_BIT_ERP) -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_ERP; -+ else if ((*pucDesiredPhyTypeSet) & PHY_TYPE_BIT_OFDM) -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_OFDM; -+ -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_54M; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_54M; -+ *pucMcsSet = 0; -+ *pucSupMcs32 = 0; -+ *pu2HtCapInfo = 0; -+ break; -+ -+ case FIXED_RATE_MCS0_20M_800NS: -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; -+ *pucMcsSet = HT_RATE_MCS0_INDEX; -+ *pucSupMcs32 = 0; -+ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH -+ | HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); -+ break; -+ -+ case FIXED_RATE_MCS1_20M_800NS: -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; -+ *pucMcsSet = HT_RATE_MCS1_INDEX; -+ *pucSupMcs32 = 0; -+ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH -+ | HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); -+ break; -+ -+ case FIXED_RATE_MCS2_20M_800NS: -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; -+ *pucMcsSet = HT_RATE_MCS2_INDEX; -+ *pucSupMcs32 = 0; -+ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH -+ | HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); -+ break; -+ -+ case FIXED_RATE_MCS3_20M_800NS: -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; -+ *pucMcsSet = HT_RATE_MCS3_INDEX; -+ *pucSupMcs32 = 0; -+ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH -+ | HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); -+ break; -+ -+ case FIXED_RATE_MCS4_20M_800NS: -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; -+ *pucMcsSet = HT_RATE_MCS4_INDEX; -+ *pucSupMcs32 = 0; -+ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH -+ | HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); -+ break; -+ -+ case FIXED_RATE_MCS5_20M_800NS: -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; -+ *pucMcsSet = HT_RATE_MCS5_INDEX; -+ *pucSupMcs32 = 0; -+ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH -+ | HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); -+ break; -+ -+ case FIXED_RATE_MCS6_20M_800NS: -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; -+ *pucMcsSet = HT_RATE_MCS6_INDEX; -+ *pucSupMcs32 = 0; -+ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH -+ | HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); -+ break; -+ -+ case FIXED_RATE_MCS7_20M_800NS: -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; -+ *pucMcsSet = HT_RATE_MCS7_INDEX; -+ *pucSupMcs32 = 0; -+ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH -+ | HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); -+ break; -+ -+ case FIXED_RATE_MCS0_20M_400NS: -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; -+ *pucMcsSet = HT_RATE_MCS0_INDEX; -+ *pucSupMcs32 = 0; -+ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); -+ (*pu2HtCapInfo) |= HT_CAP_INFO_SHORT_GI_20M; -+ break; -+ -+ case FIXED_RATE_MCS1_20M_400NS: -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; -+ *pucMcsSet = HT_RATE_MCS1_INDEX; -+ *pucSupMcs32 = 0; -+ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); -+ (*pu2HtCapInfo) |= HT_CAP_INFO_SHORT_GI_20M; -+ break; -+ -+ case FIXED_RATE_MCS2_20M_400NS: -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; -+ *pucMcsSet = HT_RATE_MCS2_INDEX; -+ *pucSupMcs32 = 0; -+ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); -+ (*pu2HtCapInfo) |= HT_CAP_INFO_SHORT_GI_20M; -+ break; -+ -+ case FIXED_RATE_MCS3_20M_400NS: -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; -+ *pucMcsSet = HT_RATE_MCS3_INDEX; -+ *pucSupMcs32 = 0; -+ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); -+ (*pu2HtCapInfo) |= HT_CAP_INFO_SHORT_GI_20M; -+ break; -+ -+ case FIXED_RATE_MCS4_20M_400NS: -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; -+ *pucMcsSet = HT_RATE_MCS4_INDEX; -+ *pucSupMcs32 = 0; -+ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); -+ (*pu2HtCapInfo) |= HT_CAP_INFO_SHORT_GI_20M; -+ break; -+ -+ case FIXED_RATE_MCS5_20M_400NS: -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; -+ *pucMcsSet = HT_RATE_MCS5_INDEX; -+ *pucSupMcs32 = 0; -+ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); -+ (*pu2HtCapInfo) |= HT_CAP_INFO_SHORT_GI_20M; -+ break; -+ -+ case FIXED_RATE_MCS6_20M_400NS: -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; -+ *pucMcsSet = HT_RATE_MCS6_INDEX; -+ *pucSupMcs32 = 0; -+ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); -+ (*pu2HtCapInfo) |= HT_CAP_INFO_SHORT_GI_20M; -+ break; -+ -+ case FIXED_RATE_MCS7_20M_400NS: -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; -+ *pucMcsSet = HT_RATE_MCS7_INDEX; -+ *pucSupMcs32 = 0; -+ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); -+ (*pu2HtCapInfo) |= HT_CAP_INFO_SHORT_GI_20M; -+ break; -+ -+ case FIXED_RATE_MCS0_40M_800NS: -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; -+ *pucMcsSet = HT_RATE_MCS0_INDEX; -+ *pucSupMcs32 = 0; -+ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); -+ (*pu2HtCapInfo) |= HT_CAP_INFO_SUP_CHNL_WIDTH; -+ break; -+ -+ case FIXED_RATE_MCS1_40M_800NS: -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; -+ *pucMcsSet = HT_RATE_MCS1_INDEX; -+ *pucSupMcs32 = 0; -+ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); -+ (*pu2HtCapInfo) |= HT_CAP_INFO_SUP_CHNL_WIDTH; -+ break; -+ -+ case FIXED_RATE_MCS2_40M_800NS: -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; -+ *pucMcsSet = HT_RATE_MCS2_INDEX; -+ *pucSupMcs32 = 0; -+ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); -+ (*pu2HtCapInfo) |= HT_CAP_INFO_SUP_CHNL_WIDTH; -+ break; -+ -+ case FIXED_RATE_MCS3_40M_800NS: -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; -+ *pucMcsSet = HT_RATE_MCS3_INDEX; -+ *pucSupMcs32 = 0; -+ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); -+ (*pu2HtCapInfo) |= HT_CAP_INFO_SUP_CHNL_WIDTH; -+ break; -+ -+ case FIXED_RATE_MCS4_40M_800NS: -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; -+ *pucMcsSet = HT_RATE_MCS4_INDEX; -+ *pucSupMcs32 = 0; -+ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); -+ (*pu2HtCapInfo) |= HT_CAP_INFO_SUP_CHNL_WIDTH; -+ break; -+ -+ case FIXED_RATE_MCS5_40M_800NS: -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; -+ *pucMcsSet = HT_RATE_MCS5_INDEX; -+ *pucSupMcs32 = 0; -+ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); -+ (*pu2HtCapInfo) |= HT_CAP_INFO_SUP_CHNL_WIDTH; -+ break; -+ -+ case FIXED_RATE_MCS6_40M_800NS: -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; -+ *pucMcsSet = HT_RATE_MCS6_INDEX; -+ *pucSupMcs32 = 0; -+ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); -+ (*pu2HtCapInfo) |= HT_CAP_INFO_SUP_CHNL_WIDTH; -+ break; -+ -+ case FIXED_RATE_MCS7_40M_800NS: -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; -+ *pucMcsSet = HT_RATE_MCS7_INDEX; -+ *pucSupMcs32 = 0; -+ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); -+ (*pu2HtCapInfo) |= HT_CAP_INFO_SUP_CHNL_WIDTH; -+ break; -+ -+ case FIXED_RATE_MCS32_800NS: -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; -+ *pucMcsSet = HT_RATE_MCS32_INDEX; -+ *pucSupMcs32 = 1; -+ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_HT_GF); -+ (*pu2HtCapInfo) |= HT_CAP_INFO_SUP_CHNL_WIDTH; -+ break; -+ -+ case FIXED_RATE_MCS0_40M_400NS: -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; -+ *pucMcsSet = HT_RATE_MCS0_INDEX; -+ *pucSupMcs32 = 0; -+ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_HT_GF); -+ (*pu2HtCapInfo) |= (HT_CAP_INFO_SUP_CHNL_WIDTH | HT_CAP_INFO_SHORT_GI_40M); -+ break; -+ -+ case FIXED_RATE_MCS1_40M_400NS: -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; -+ *pucMcsSet = HT_RATE_MCS1_INDEX; -+ *pucSupMcs32 = 0; -+ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_HT_GF); -+ (*pu2HtCapInfo) |= (HT_CAP_INFO_SUP_CHNL_WIDTH | HT_CAP_INFO_SHORT_GI_40M); -+ break; -+ -+ case FIXED_RATE_MCS2_40M_400NS: -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; -+ *pucMcsSet = HT_RATE_MCS2_INDEX; -+ *pucSupMcs32 = 0; -+ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_HT_GF); -+ (*pu2HtCapInfo) |= (HT_CAP_INFO_SUP_CHNL_WIDTH | HT_CAP_INFO_SHORT_GI_40M); -+ break; -+ -+ case FIXED_RATE_MCS3_40M_400NS: -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; -+ *pucMcsSet = HT_RATE_MCS3_INDEX; -+ *pucSupMcs32 = 0; -+ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_HT_GF); -+ (*pu2HtCapInfo) |= (HT_CAP_INFO_SUP_CHNL_WIDTH | HT_CAP_INFO_SHORT_GI_40M); -+ break; -+ -+ case FIXED_RATE_MCS4_40M_400NS: -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; -+ *pucMcsSet = HT_RATE_MCS4_INDEX; -+ *pucSupMcs32 = 0; -+ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_HT_GF); -+ (*pu2HtCapInfo) |= (HT_CAP_INFO_SUP_CHNL_WIDTH | HT_CAP_INFO_SHORT_GI_40M); -+ break; -+ -+ case FIXED_RATE_MCS5_40M_400NS: -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; -+ *pucMcsSet = HT_RATE_MCS5_INDEX; -+ *pucSupMcs32 = 0; -+ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_HT_GF); -+ (*pu2HtCapInfo) |= (HT_CAP_INFO_SUP_CHNL_WIDTH | HT_CAP_INFO_SHORT_GI_40M); -+ break; -+ -+ case FIXED_RATE_MCS6_40M_400NS: -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; -+ *pucMcsSet = HT_RATE_MCS6_INDEX; -+ *pucSupMcs32 = 0; -+ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_HT_GF); -+ (*pu2HtCapInfo) |= (HT_CAP_INFO_SUP_CHNL_WIDTH | HT_CAP_INFO_SHORT_GI_40M); -+ break; -+ -+ case FIXED_RATE_MCS7_40M_400NS: -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; -+ *pucMcsSet = HT_RATE_MCS7_INDEX; -+ *pucSupMcs32 = 0; -+ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_HT_GF); -+ (*pu2HtCapInfo) |= (HT_CAP_INFO_SUP_CHNL_WIDTH | HT_CAP_INFO_SHORT_GI_40M); -+ break; -+ -+ case FIXED_RATE_MCS32_400NS: -+ *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; -+ *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY; -+ *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY; -+ *pucMcsSet = HT_RATE_MCS32_INDEX; -+ *pucSupMcs32 = 1; -+ (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_HT_GF); -+ (*pu2HtCapInfo) |= (HT_CAP_INFO_SUP_CHNL_WIDTH | HT_CAP_INFO_SHORT_GI_40M); -+ break; -+ -+ default: -+ ASSERT(0); -+ } -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This utility function is used to write the register -+* -+* @param u4Address Register address -+* u4Value the value to be written -+* -+* @retval WLAN_STATUS_SUCCESS -+* WLAN_STATUS_FAILURE -+*/ -+/*----------------------------------------------------------------------------*/ -+ -+WLAN_STATUS nicWriteMcr(IN P_ADAPTER_T prAdapter, IN UINT_32 u4Address, IN UINT_32 u4Value) -+{ -+ CMD_ACCESS_REG rCmdAccessReg; -+ -+ rCmdAccessReg.u4Address = u4Address; -+ rCmdAccessReg.u4Data = u4Value; -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_ACCESS_REG, -+ TRUE, -+ FALSE, -+ FALSE, NULL, NULL, sizeof(CMD_ACCESS_REG), (PUINT_8) &rCmdAccessReg, NULL, 0); -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This utility function is used to modify the auto rate parameters -+* -+* @param u4ArSysParam0 see description below -+* u4ArSysParam1 -+* u4ArSysParam2 -+* u4ArSysParam3 -+* -+* -+* @retval WLAN_STATUS_SUCCESS -+* WLAN_STATUS_FAILURE -+* -+* @note -+* ArSysParam0[0:3] -> auto rate version (0:disable 1:version1 2:version2) -+* ArSysParam0[4:5]-> auto bw version (0:disable 1:version1 2:version2) -+* ArSysParam0[6:7]-> auto gi version (0:disable 1:version1 2:version2) -+* ArSysParam0[8:15]-> HT rate clear mask -+* ArSysParam0[16:31]-> Legacy rate clear mask -+* ArSysParam1[0:7]-> Auto Rate check weighting window -+* ArSysParam1[8:15]-> Auto Rate v1 Force Rate down -+* ArSysParam1[16:23]-> Auto Rate v1 PerH -+* ArSysParam1[24:31]-> Auto Rate v1 PerL -+* -+* Examples -+* ArSysParam0 = 1, -+* Enable auto rate version 1 -+* -+* ArSysParam0 = 983041, -+* Enable auto rate version 1 -+* Remove CCK 1M, 2M, 5.5M, 11M -+* -+* ArSysParam0 = 786433 -+* Enable auto rate version 1 -+* Remove CCK 5.5M 11M -+*/ -+/*----------------------------------------------------------------------------*/ -+ -+WLAN_STATUS -+nicRlmArUpdateParms(IN P_ADAPTER_T prAdapter, -+ IN UINT_32 u4ArSysParam0, -+ IN UINT_32 u4ArSysParam1, IN UINT_32 u4ArSysParam2, IN UINT_32 u4ArSysParam3) -+{ -+ UINT_8 ucArVer, ucAbwVer, ucAgiVer; -+ UINT_16 u2HtClrMask; -+ UINT_16 u2LegacyClrMask; -+ UINT_8 ucArCheckWindow; -+ UINT_8 ucArPerL; -+ UINT_8 ucArPerH; -+ UINT_8 ucArPerForceRateDownPer; -+ -+ ucArVer = (UINT_8) (u4ArSysParam0 & BITS(0, 3)); -+ ucAbwVer = (UINT_8) ((u4ArSysParam0 & BITS(4, 5)) >> 4); -+ ucAgiVer = (UINT_8) ((u4ArSysParam0 & BITS(6, 7)) >> 6); -+ u2HtClrMask = (UINT_16) ((u4ArSysParam0 & BITS(8, 15)) >> 8); -+ u2LegacyClrMask = (UINT_16) ((u4ArSysParam0 & BITS(16, 31)) >> 16); -+ -+#if 0 -+ ucArCheckWindow = (UINT_8) (u4ArSysParam1 & BITS(0, 7)); -+ ucArPerForceRateDownPer = (UINT_8) ((u4ArSysParam1 & BITS(8, 15) >> 8)); -+ ucArPerH = (UINT_8) ((u4ArSysParam1 & BITS(16, 23)) >> 16); -+ ucArPerL = (UINT_8) ((u4ArSysParam1 & BITS(24, 31)) >> 24); -+#endif -+ -+ ucArCheckWindow = (UINT_8) (u4ArSysParam1 & BITS(0, 7)); -+ ucArPerForceRateDownPer = (UINT_8) (((u4ArSysParam1 >> 8) & BITS(0, 7))); -+ ucArPerH = (UINT_8) (((u4ArSysParam1 >> 16) & BITS(0, 7))); -+ ucArPerL = (UINT_8) (((u4ArSysParam1 >> 24) & BITS(0, 7))); -+ -+ DBGLOG(NIC, INFO, "ArParam %u %u %u %u\n", u4ArSysParam0, u4ArSysParam1, u4ArSysParam2, u4ArSysParam3); -+ DBGLOG(NIC, INFO, "ArVer %u AbwVer %u AgiVer %u\n", ucArVer, ucAbwVer, ucAgiVer); -+ DBGLOG(NIC, INFO, "HtMask %x LegacyMask %x\n", u2HtClrMask, u2LegacyClrMask); -+ DBGLOG(NIC, INFO, -+ "CheckWin %u RateDownPer %u PerH %u PerL %u\n", ucArCheckWindow, ucArPerForceRateDownPer, ucArPerH, -+ ucArPerL); -+ -+#define SWCR_DATA_ADDR(MOD, ADDR) (0x90000000+(MOD<<8)+(ADDR)) -+#define SWCR_DATA_CMD(CATE, WRITE, INDEX, OPT0, OPT1) ((CATE<<24) | (WRITE<<23) | (INDEX<<16) | (OPT0 << 8) | OPT1) -+#define SWCR_DATA0 0x0 -+#define SWCR_DATA1 0x4 -+#define SWCR_DATA2 0x8 -+#define SWCR_DATA3 0xC -+#define SWCR_DATA4 0x10 -+#define SWCR_WRITE 1 -+#define SWCR_READ 0 -+ -+ if (ucArVer > 0) { -+ /* dummy = WiFi.WriteMCR(&h90000104, &h00000001) */ -+ /* dummy = WiFi.WriteMCR(&h90000100, &h00850000) */ -+ -+ nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, SWCR_DATA1), 1); -+ nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, SWCR_DATA0), SWCR_DATA_CMD(0, SWCR_WRITE, 5, 0, 0)); -+ } else { -+ nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, SWCR_DATA1), 0); -+ nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, SWCR_DATA0), SWCR_DATA_CMD(0, SWCR_WRITE, 5, 0, 0)); -+ } -+ -+ /* ucArVer 0: none 1:PER 2:Rcpi */ -+ nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, SWCR_DATA1), ucArVer); -+ nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, SWCR_DATA0), SWCR_DATA_CMD(0, SWCR_WRITE, 7, 0, 0)); -+ -+ /* Candidate rate Ht mask */ -+ nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, SWCR_DATA1), u2HtClrMask); -+ nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, SWCR_DATA0), SWCR_DATA_CMD(0, SWCR_WRITE, 0x1c, 0, 0)); -+ -+ /* Candidate rate legacy mask */ -+ nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, SWCR_DATA1), u2LegacyClrMask); -+ nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, SWCR_DATA0), SWCR_DATA_CMD(0, SWCR_WRITE, 0x1d, 0, 0)); -+ -+#if 0 -+ if (ucArCheckWindow != 0) { -+ /* TX DONE MCS INDEX CHECK STA RATE DOWN TH */ -+ nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, SWCR_DATA1), ucArCheckWindow); -+ nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, SWCR_DATA0), SWCR_DATA_CMD(0, SWCR_WRITE, 0x14, 0, 0)); -+ nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, SWCR_DATA1), ucArCheckWindow); -+ nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, SWCR_DATA0), SWCR_DATA_CMD(0, SWCR_WRITE, 0xc, 0, 0)); -+ } -+ -+ if (ucArPerForceRateDownPer != 0) { -+ nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, SWCR_DATA1), ucArPerForceRateDownPer); -+ nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, SWCR_DATA0), SWCR_DATA_CMD(0, SWCR_WRITE, 0x18, 0, 0)); -+ } -+ if (ucArPerH != 0) { -+ nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, SWCR_DATA1), ucArPerH); -+ nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, SWCR_DATA0), SWCR_DATA_CMD(0, SWCR_WRITE, 0x1, 0, 0)); -+ } -+ if (ucArPerL != 0) { -+ nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, SWCR_DATA1), ucArPerL); -+ nicWriteMcr(prAdapter, SWCR_DATA_ADDR(1 /*MOD*/, SWCR_DATA0), SWCR_DATA_CMD(0, SWCR_WRITE, 0x2, 0, 0)); -+ } -+#endif -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This utility function is used to enable roaming -+* -+* @param u4EnableRoaming -+* -+* -+* @retval WLAN_STATUS_SUCCESS -+* WLAN_STATUS_FAILURE -+* -+* @note -+* u4EnableRoaming -> Enable Romaing -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS nicRoamingUpdateParams(IN P_ADAPTER_T prAdapter, IN UINT_32 u4EnableRoaming) -+{ -+ P_CONNECTION_SETTINGS_T prConnSettings; -+ -+ prConnSettings = &(prAdapter->rWifiVar.rConnSettings); -+ prConnSettings->fgIsEnableRoaming = ((u4EnableRoaming > 0) ? (TRUE) : (FALSE)); -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief dump firmware Assert message -+* -+* \param[in] -+* prAdapter -+* -+* \return -+* TRUE -+* FALSE -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicPrintFirmwareAssertInfo(IN P_ADAPTER_T prAdapter) -+{ -+ UINT_32 u4MailBox0, u4MailBox1; -+ UINT_32 line = 0; -+ UINT_8 aucAssertFile[7]; -+ UINT_32 u4ChipId; -+ -+#if CFG_SDIO_INTR_ENHANCE -+ u4MailBox0 = prAdapter->prSDIOCtrl->u4RcvMailbox0; -+ u4MailBox1 = prAdapter->prSDIOCtrl->u4RcvMailbox1; -+#else -+ nicGetMailbox(prAdapter, 0, &u4MailBox0); -+ nicGetMailbox(prAdapter, 1, &u4MailBox1); -+#endif -+ -+ line = u4MailBox0 & 0x0000FFFF; -+ -+ u4MailBox0 = ((u4MailBox0 >> 16) & 0x0000FFFF); -+ -+ kalMemCopy(&aucAssertFile[0], &u4MailBox0, 2); -+ kalMemCopy(&aucAssertFile[2], &u4MailBox1, 4); -+ -+ aucAssertFile[6] = '\0'; -+ -+#if defined(MT6620) -+ u4ChipId = 6620; -+#elif defined(MT6628) -+ u4ChipId = 6582; -+#endif -+ -+ kalPrint("\n[MT%u][wifi][Firmware] Assert at \"%s\" #%u\n\n", u4ChipId, aucAssertFile, line); -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is called to update Link Quality information -+* -+* @param prAdapter Pointer of Adapter Data Structure -+* eNetTypeIdx -+* prEventLinkQuality -+* cRssi -+* cLinkQuality -+* -+* @return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+nicUpdateLinkQuality(IN P_ADAPTER_T prAdapter, -+ IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIdx, IN P_EVENT_LINK_QUALITY prEventLinkQuality) -+{ -+ ASSERT(prAdapter); -+ ASSERT(eNetTypeIdx < NETWORK_TYPE_INDEX_NUM); -+ ASSERT(prEventLinkQuality); -+ -+ switch (eNetTypeIdx) { -+ case NETWORK_TYPE_AIS_INDEX: -+ if (prAdapter->rWifiVar.arBssInfo[eNetTypeIdx].eConnectionState == PARAM_MEDIA_STATE_CONNECTED) { -+ /* check is to prevent RSSI to be updated by incorrect initial RSSI from hardware */ -+ /* buffer statistics for further query */ -+ if (prAdapter->fgIsLinkQualityValid == FALSE -+ || (kalGetTimeTick() - prAdapter->rLinkQualityUpdateTime) > CFG_LINK_QUALITY_VALID_PERIOD) { -+ nicUpdateRSSI(prAdapter, eNetTypeIdx, prEventLinkQuality->cRssi, -+ prEventLinkQuality->cLinkQuality); -+ } -+ -+ if (prAdapter->fgIsLinkRateValid == FALSE -+ || (kalGetTimeTick() - prAdapter->rLinkRateUpdateTime) > CFG_LINK_QUALITY_VALID_PERIOD) { -+ nicUpdateLinkSpeed(prAdapter, eNetTypeIdx, prEventLinkQuality->u2LinkSpeed); -+ } -+ } -+ break; -+#if CFG_ENABLE_WIFI_DIRECT && CFG_SUPPORT_P2P_RSSI_QUERY -+ case NETWORK_TYPE_P2P_INDEX: -+ if (prAdapter->fgIsP2pLinkQualityValid == FALSE -+ || (kalGetTimeTick() - prAdapter->rP2pLinkQualityUpdateTime) > CFG_LINK_QUALITY_VALID_PERIOD) { -+ P_EVENT_LINK_QUALITY_EX prEventLQEx = (P_EVENT_LINK_QUALITY_EX) prEventLinkQuality; -+ -+ nicUpdateRSSI(prAdapter, NETWORK_TYPE_P2P_INDEX, prEventLQEx->cRssiP2P, -+ prEventLQEx->cLinkQualityP2P); -+ } -+ break; -+#endif -+ default: -+ break; -+ -+ } -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is called to update RSSI and Link Quality information -+* -+* @param prAdapter Pointer of Adapter Data Structure -+* eNetTypeIdx -+* cRssi -+* cLinkQuality -+* -+* @return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+nicUpdateRSSI(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIdx, IN INT_8 cRssi, IN INT_8 cLinkQuality) -+{ -+ ASSERT(prAdapter); -+ ASSERT(eNetTypeIdx < NETWORK_TYPE_INDEX_NUM); -+ -+ switch (eNetTypeIdx) { -+ case NETWORK_TYPE_AIS_INDEX: -+ if (prAdapter->rWifiVar.arBssInfo[eNetTypeIdx].eConnectionState == PARAM_MEDIA_STATE_CONNECTED) { -+ prAdapter->fgIsLinkQualityValid = TRUE; -+ prAdapter->rLinkQualityUpdateTime = kalGetTimeTick(); -+ -+ prAdapter->rLinkQuality.cRssi = cRssi; -+ prAdapter->rLinkQuality.cLinkQuality = cLinkQuality; -+ -+ /* indicate to glue layer */ -+ kalUpdateRSSI(prAdapter->prGlueInfo, -+ KAL_NETWORK_TYPE_AIS_INDEX, -+ prAdapter->rLinkQuality.cRssi, prAdapter->rLinkQuality.cLinkQuality); -+ } -+ -+ break; -+#if CFG_ENABLE_WIFI_DIRECT -+#if CFG_SUPPORT_P2P_RSSI_QUERY -+ case NETWORK_TYPE_P2P_INDEX: -+ prAdapter->fgIsP2pLinkQualityValid = TRUE; -+ prAdapter->rP2pLinkQualityUpdateTime = kalGetTimeTick(); -+ -+ prAdapter->rP2pLinkQuality.cRssi = cRssi; -+ prAdapter->rP2pLinkQuality.cLinkQuality = cLinkQuality; -+ -+ kalUpdateRSSI(prAdapter->prGlueInfo, KAL_NETWORK_TYPE_P2P_INDEX, cRssi, cLinkQuality); -+ break; -+#endif -+#endif -+ default: -+ break; -+ -+ } -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is called to update Link Quality information -+* -+* @param prAdapter Pointer of Adapter Data Structure -+* eNetTypeIdx -+* prEventLinkQuality -+* cRssi -+* cLinkQuality -+* -+* @return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicUpdateLinkSpeed(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIdx, IN UINT_16 u2LinkSpeed) -+{ -+ ASSERT(prAdapter); -+ ASSERT(eNetTypeIdx < NETWORK_TYPE_INDEX_NUM); -+ -+ switch (eNetTypeIdx) { -+ case NETWORK_TYPE_AIS_INDEX: -+ if (prAdapter->rWifiVar.arBssInfo[eNetTypeIdx].eConnectionState == PARAM_MEDIA_STATE_CONNECTED) { -+ /* buffer statistics for further query */ -+ prAdapter->fgIsLinkRateValid = TRUE; -+ prAdapter->rLinkRateUpdateTime = kalGetTimeTick(); -+ -+ prAdapter->rLinkQuality.u2LinkSpeed = u2LinkSpeed; -+ } -+ break; -+ -+ default: -+ break; -+ -+ } -+ -+} -+ -+#if CFG_SUPPORT_RDD_TEST_MODE -+WLAN_STATUS nicUpdateRddTestMode(IN P_ADAPTER_T prAdapter, IN P_CMD_RDD_CH_T prRddChParam) -+{ -+ DEBUGFUNC("nicUpdateRddTestMode.\n"); -+ -+ ASSERT(prAdapter); -+ -+/* aisFsmScanRequest(prAdapter, NULL); */ -+ -+ return wlanSendSetQueryCmd(prAdapter, -+ CMD_ID_SET_RDD_CH, -+ TRUE, -+ FALSE, FALSE, NULL, NULL, sizeof(CMD_RDD_CH_T), (PUINT_8) prRddChParam, NULL, 0); -+} -+#endif -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic_cmd_event.c b/drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic_cmd_event.c -new file mode 100644 -index 000000000000..3c9c24f9542b ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic_cmd_event.c -@@ -0,0 +1,1636 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/nic/nic_cmd_event.c#1 -+*/ -+ -+/*! \file nic_cmd_event.c -+ \brief Callback functions for Command packets. -+ -+ Various Event packet handlers which will be setup in the callback function of -+ a command packet. -+*/ -+ -+/* -+** Log: nic_cmd_event.c -+ * -+ * 04 10 2012 yuche.tsai -+ * NULL -+ * Update address for wifi direct connection issue. -+ * -+ * 06 15 2011 cm.chang -+ * [WCXRP00000785] [MT6620 Wi-Fi][Driver][FW] P2P/BOW MAC address is XOR with AIS MAC address -+ * P2P/BOW mac address XOR with local bit instead of OR -+ * -+ * 03 05 2011 wh.su -+ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code -+ * add the code to get the check rsponse and indicate to app. -+ * -+ * 03 02 2011 wh.su -+ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code -+ * Add security check code. -+ * -+ * 02 24 2011 cp.wu -+ * [WCXRP00000493] [MT6620 Wi-Fi][Driver] Do not indicate redundant disconnection to host when entering into RF -+ * test mode -+ * only indicate DISCONNECTION to host when entering RF test if necessary (connected -> disconnected cases) -+ * -+ * 01 20 2011 eddie.chen -+ * [WCXRP00000374] [MT6620 Wi-Fi][DRV] SW debug control -+ * Add Oid for sw control debug command -+ * -+ * 12 31 2010 cp.wu -+ * [WCXRP00000335] [MT6620 Wi-Fi][Driver] change to use milliseconds sleep instead of delay to avoid blocking to -+ * system scheduling -+ * change to use msleep() and shorten waiting interval to reduce blocking to other task while Wi-Fi driver is being -+ * loaded -+ * -+ * 12 01 2010 cp.wu -+ * [WCXRP00000223] MT6620 Wi-Fi][Driver][FW] Adopt NVRAM parameters when enter/exit RF test mode -+ * reload NVRAM settings before entering RF test mode and leaving from RF test mode. -+ * -+ * 11 01 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000150] [MT6620 Wi-Fi][Driver] -+ * Add implementation for querying current TX rate from firmware auto rate module -+ * 1) Query link speed (TX rate) from firmware directly with buffering mechanism to reduce overhead -+ * 2) Remove CNM CH-RECOVER event handling -+ * 3) cfg read/write API renamed with kal prefix for unified naming rules. -+ * -+ * 10 20 2010 cp.wu -+ * [WCXRP00000117] [MT6620 Wi-Fi][Driver] Add logic for suspending driver when MT6620 is not responding anymore -+ * use OID_CUSTOM_TEST_MODE as indication for driver reset -+ * by dropping pending TX packets -+ * -+ * 10 18 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000086] [MT6620 Wi-Fi][Driver] -+ * The mac address is all zero at android -+ * complete implementation of Android NVRAM access -+ * -+ * 09 21 2010 cp.wu -+ * [WCXRP00000053] [MT6620 Wi-Fi][Driver] Reset incomplete and might leads to BSOD when entering RF test with AIS -+ * associated -+ * Do a complete reset with STA-REC null checking for RF test re-entry -+ * -+ * 09 15 2010 yuche.tsai -+ * NULL -+ * Start to test AT GO only when P2P state is not IDLE. -+ * -+ * 09 09 2010 yuche.tsai -+ * NULL -+ * Add AT GO Test mode after MAC address available. -+ * -+ * 09 03 2010 kevin.huang -+ * NULL -+ * Refine #include sequence and solve recursive/nested #include issue -+ * -+ * 08 30 2010 cp.wu -+ * NULL -+ * eliminate klockwork errors -+ * -+ * 08 16 2010 cp.wu -+ * NULL -+ * Replace CFG_SUPPORT_BOW by CFG_ENABLE_BT_OVER_WIFI. -+ * There is no CFG_SUPPORT_BOW in driver domain source. -+ * -+ * 08 12 2010 cp.wu -+ * NULL -+ * [AIS-FSM] honor registry setting for adhoc running mode. (A/B/G) -+ * -+ * 08 11 2010 yuche.tsai -+ * NULL -+ * Add support for P2P Device Address query from FW. -+ * -+ * 08 03 2010 cp.wu -+ * NULL -+ * Centralize mgmt/system service procedures into independent calls. -+ * -+ * 08 02 2010 cp.wu -+ * NULL -+ * reset FSMs before entering RF test mode. -+ * -+ * 07 22 2010 cp.wu -+ * -+ * 1) refine AIS-FSM indent. -+ * 2) when entering RF Test mode, flush 802.1X frames as well -+ * 3) when entering D3 state, flush 802.1X frames as well -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 07 05 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) change fake BSS_DESC from channel 6 to channel 1 due to channel switching is not done yet. -+ * 2) after MAC address is queried from firmware, all related variables in driver domain should be updated as well -+ * -+ * 06 21 2010 wh.su -+ * [WPD00003840][MT6620 5931] Security migration -+ * remove duplicate variable for migration. -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 05 29 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * change upon request: indicate as disconnected in driver domain when leaving from RF test mode -+ * -+ * 05 24 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * do not clear scanning list array after disassociation -+ * -+ * 05 22 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) disable NETWORK_LAYER_ADDRESSES handling temporally. -+ * 2) finish statistics OIDs -+ * -+ * 05 22 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * change OID behavior to meet WHQL requirement. -+ * -+ * 05 20 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) integrate OID_GEN_NETWORK_LAYER_ADDRESSES with CMD_ID_SET_IP_ADDRESS -+ * 2) buffer statistics data for 2 seconds -+ * 3) use default value for adhoc parameters instead of 0 -+ * -+ * 05 19 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) do not take timeout mechanism for power mode oids -+ * 2) retrieve network type from connection status -+ * 3) after disassciation, set radio state to off -+ * 4) TCP option over IPv6 is supported -+ * -+ * 05 17 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * correct OID_802_11_DISASSOCIATE handling. -+ * -+ * 05 17 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * 1) add timeout handler mechanism for pending command packets -+ * 2) add p2p add/removal key -+ * -+ * 04 16 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * treat BUS access failure as kind of card removal. -+ * -+ * 04 14 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * information buffer for query oid/ioctl is now buffered in prCmdInfo -+ * * * * * * instead of glue-layer variable to improve multiple oid/ioctl capability -+ * -+ * 04 13 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * add framework for BT-over-Wi-Fi support. -+ * * * * * * * * * * * * * * 1) prPendingCmdInfo is replaced by queue for multiple handler capability -+ * * * * * * * * * * * * * * 2) command sequence number is now increased atomically -+ * * * * * * * * * * * * * * 3) private data could be hold and taken use for other purpose -+ * -+ * 04 07 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * accessing to firmware load/start address, and access to OID handling information -+ * are now handled in glue layer -+ * -+ * 04 07 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * rWlanInfo should be placed at adapter rather than glue due to most operations -+ * * * * are done in adapter layer. -+ * -+ * 04 06 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * add KAL API: kalFlushPendingTxPackets(), and take use of the API -+ * -+ * 04 06 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * eliminate direct access to prGlueInfo->rWlanInfo.eLinkAttr.ucMediaStreamMode from non-glue layer. -+ * -+ * 04 06 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * improve none-glude code portability -+ * -+ * 04 06 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * sync statistics data structure definition with firmware implementation -+ * -+ * 04 06 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * code refine: fgTestMode should be at adapter rather than glue due to the device/fw is also involved -+ * -+ * 04 06 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * eliminate direct access for prGlueInfo->fgIsCardRemoved in non-glue layer -+ * -+ * 03 30 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * statistics information OIDs are now handled by querying from firmware domain -+ * -+ * 03 26 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * indicate media stream mode after set is done -+ * -+ * 03 24 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * initial import for Linux port -+ * -+ * 03 03 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * implement custom OID: EEPROM read/write access -+ * -+ * 03 03 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * implement OID_802_3_MULTICAST_LIST oid handling -+ * -+ * 02 25 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * limit RSSI return value to micxxsoft defined range. -+ * -+ * 02 09 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1. Permanent and current MAC address are now retrieved by CMD/EVENT packets instead of hard-coded address -+ * * * * * * * 2. follow MSDN defined behavior when associates to another AP -+ * * * * * * * 3. for firmware download, packet size could be up to 2048 bytes -+ * -+ * 01 29 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * block until firmware finished RF test enter/leave then indicate completion to upper layer -+ * -+ * 01 29 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * when entering RF test mode and leaving from RF test mode, wait for W_FUNC_RDY bit to be asserted forever until it -+ * is set or card is removed. -+ * -+ * 01 27 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1. eliminate improper variable in rHifInfo -+ * * * * * * * * 2. block TX/ordinary OID when RF test mode is engaged -+ * * * * * * * * 3. wait until firmware finish operation when entering into and leaving from RF test mode -+ * * * * * * * * 4. correct some HAL implementation -+ * -+ * 01 26 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * Under WinXP with SDIO, use prGlueInfo->rHifInfo.pvInformationBuffer instead of prGlueInfo->pvInformationBuffer -+ * -+ * 01 22 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * implement following 802.11 OIDs: -+ * * * * * OID_802_11_RSSI, -+ * * * * * OID_802_11_RSSI_TRIGGER, -+ * * * * * OID_802_11_STATISTICS, -+ * * * * * OID_802_11_DISASSOCIATE, -+ * * * * * OID_802_11_POWER_MODE -+ * -+ * 01 21 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * implement OID_802_11_MEDIA_STREAM_MODE -+ * -+ * 12 30 2009 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) According to CMD/EVENT documentation v0.8, -+ * * * * * * * * OID_CUSTOM_TEST_RX_STATUS & OID_CUSTOM_TEST_TX_STATUS is no longer used, -+ * * * * * * * * and result is retrieved by get ATInfo instead -+ * * * * * * * * 2) add 4 counter for recording aggregation statistics -+** \main\maintrunk.MT6620WiFiDriver_Prj\10 2009-12-10 16:47:47 GMT mtk02752 -+** only handle MCR read when accessing FW domain register -+** \main\maintrunk.MT6620WiFiDriver_Prj\9 2009-12-08 17:37:28 GMT mtk02752 -+** * refine nicCmdEventQueryMcrRead -+** + add TxStatus/RxStatus for RF test QueryInformation OIDs -+** \main\maintrunk.MT6620WiFiDriver_Prj\8 2009-12-02 22:05:45 GMT mtk02752 -+** kalOidComplete() will decrease i4OidPendingCount -+** \main\maintrunk.MT6620WiFiDriver_Prj\7 2009-12-01 23:02:57 GMT mtk02752 -+** remove unnecessary spin locks -+** \main\maintrunk.MT6620WiFiDriver_Prj\6 2009-12-01 22:51:18 GMT mtk02752 -+** maintein i4OidPendingCount -+** \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-11-30 10:55:03 GMT mtk02752 -+** modify for compatibility -+** \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-11-23 14:46:32 GMT mtk02752 -+** add another version of command-done handler upon new event structure -+** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-04-29 15:42:33 GMT mtk01461 -+** Add comment -+** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-04-21 19:32:42 GMT mtk01461 -+** Add nicCmdEventSetCommon() for general set OID -+** \main\maintrunk.MT6620WiFiDriver_Prj\1 2009-04-21 01:40:35 GMT mtk01461 -+** Command Done Handler -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "precomp.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+VOID nicCmdEventQueryMcrRead(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) -+{ -+ UINT_32 u4QueryInfoLen; -+ P_PARAM_CUSTOM_MCR_RW_STRUCT_T prMcrRdInfo; -+ P_GLUE_INFO_T prGlueInfo; -+ P_CMD_ACCESS_REG prCmdAccessReg; -+ -+ ASSERT(prAdapter); -+ ASSERT(prCmdInfo); -+ ASSERT(pucEventBuf); -+ -+ /* 4 <2> Update information of OID */ -+ if (prCmdInfo->fgIsOid) { -+ prGlueInfo = prAdapter->prGlueInfo; -+ prCmdAccessReg = (P_CMD_ACCESS_REG) (pucEventBuf); -+ -+ u4QueryInfoLen = sizeof(PARAM_CUSTOM_MCR_RW_STRUCT_T); -+ -+ prMcrRdInfo = (P_PARAM_CUSTOM_MCR_RW_STRUCT_T) prCmdInfo->pvInformationBuffer; -+ prMcrRdInfo->u4McrOffset = prCmdAccessReg->u4Address; -+ prMcrRdInfo->u4McrData = prCmdAccessReg->u4Data; -+ -+ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS); -+ } -+ -+ return; -+ -+} -+ -+VOID nicCmdEventQuerySwCtrlRead(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) -+{ -+ UINT_32 u4QueryInfoLen; -+ P_PARAM_CUSTOM_SW_CTRL_STRUCT_T prSwCtrlInfo; -+ P_GLUE_INFO_T prGlueInfo; -+ P_CMD_SW_DBG_CTRL_T prCmdSwCtrl; -+ -+ ASSERT(prAdapter); -+ ASSERT(prCmdInfo); -+ ASSERT(pucEventBuf); -+ -+ /* 4 <2> Update information of OID */ -+ if (prCmdInfo->fgIsOid) { -+ prGlueInfo = prAdapter->prGlueInfo; -+ prCmdSwCtrl = (P_CMD_SW_DBG_CTRL_T) (pucEventBuf); -+ -+ u4QueryInfoLen = sizeof(PARAM_CUSTOM_SW_CTRL_STRUCT_T); -+ -+ prSwCtrlInfo = (P_PARAM_CUSTOM_SW_CTRL_STRUCT_T) prCmdInfo->pvInformationBuffer; -+ prSwCtrlInfo->u4Id = prCmdSwCtrl->u4Id; -+ prSwCtrlInfo->u4Data = prCmdSwCtrl->u4Data; -+ -+ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS); -+ } -+ -+ return; -+ -+} -+ -+VOID nicCmdEventSetCommon(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) -+{ -+ ASSERT(prAdapter); -+ ASSERT(prCmdInfo); -+ -+ if (prCmdInfo->fgIsOid) { -+ /* Update Set Information Length */ -+ kalOidComplete(prAdapter->prGlueInfo, -+ prCmdInfo->fgSetQuery, prCmdInfo->u4InformationBufferLength, WLAN_STATUS_SUCCESS); -+ } -+ -+} -+ -+VOID nicCmdEventSetDisassociate(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) -+{ -+ ASSERT(prAdapter); -+ ASSERT(prCmdInfo); -+ -+ if (prCmdInfo->fgIsOid) { -+ /* Update Set Information Length */ -+ kalOidComplete(prAdapter->prGlueInfo, prCmdInfo->fgSetQuery, 0, WLAN_STATUS_SUCCESS); -+ } -+ -+ DBGLOG(NIC, TRACE, "DisByCmdE\n"); -+ kalIndicateStatusAndComplete(prAdapter->prGlueInfo, WLAN_STATUS_MEDIA_DISCONNECT, NULL, 0); -+ -+#if !defined(LINUX) -+ prAdapter->fgIsRadioOff = TRUE; -+#endif -+ -+} -+ -+VOID nicCmdEventSetIpAddress(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) -+{ -+ UINT_32 u4Count; -+ -+ ASSERT(prAdapter); -+ ASSERT(prCmdInfo); -+ -+ u4Count = (prCmdInfo->u4SetInfoLen - OFFSET_OF(CMD_SET_NETWORK_ADDRESS_LIST, arNetAddress)) -+ / sizeof(IPV4_NETWORK_ADDRESS); -+ -+ if (prCmdInfo->fgIsOid) { -+ /* Update Set Information Length */ -+ kalOidComplete(prAdapter->prGlueInfo, -+ prCmdInfo->fgSetQuery, -+ OFFSET_OF(PARAM_NETWORK_ADDRESS_LIST, arAddress) + u4Count * -+ (OFFSET_OF(PARAM_NETWORK_ADDRESS, aucAddress) + sizeof(PARAM_NETWORK_ADDRESS_IP)), -+ WLAN_STATUS_SUCCESS); -+ } -+ -+} -+ -+VOID nicCmdEventQueryRfTestATInfo(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) -+{ -+ P_EVENT_TEST_STATUS prTestStatus, prQueryBuffer; -+ P_GLUE_INFO_T prGlueInfo; -+ UINT_32 u4QueryInfoLen; -+ -+ ASSERT(prAdapter); -+ ASSERT(prCmdInfo); -+ -+ prTestStatus = (P_EVENT_TEST_STATUS) pucEventBuf; -+ -+ if (prCmdInfo->fgIsOid) { -+ prGlueInfo = prAdapter->prGlueInfo; -+ prQueryBuffer = (P_EVENT_TEST_STATUS) prCmdInfo->pvInformationBuffer; -+ -+ kalMemCopy(prQueryBuffer, prTestStatus, sizeof(EVENT_TEST_STATUS)); -+ -+ u4QueryInfoLen = sizeof(EVENT_TEST_STATUS); -+ -+ /* Update Query Information Length */ -+ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS); -+ } -+ -+} -+ -+VOID nicCmdEventQueryLinkQuality(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) -+{ -+ PARAM_RSSI rRssi, *prRssi; -+ P_EVENT_LINK_QUALITY prLinkQuality; -+ P_GLUE_INFO_T prGlueInfo; -+ UINT_32 u4QueryInfoLen; -+ -+ ASSERT(prAdapter); -+ ASSERT(prCmdInfo); -+ -+ prLinkQuality = (P_EVENT_LINK_QUALITY) pucEventBuf; -+ -+ rRssi = (PARAM_RSSI) prLinkQuality->cRssi; /* ranged from (-128 ~ 30) in unit of dBm */ -+ DBGLOG(NIC, INFO, " %s: rRssi = %d\n", __func__, rRssi); -+ -+ if (prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX].eConnectionState == PARAM_MEDIA_STATE_CONNECTED) { -+ if (rRssi > PARAM_WHQL_RSSI_MAX_DBM) -+ rRssi = PARAM_WHQL_RSSI_MAX_DBM; -+ else if (rRssi < PARAM_WHQL_RSSI_MIN_DBM) -+ rRssi = PARAM_WHQL_RSSI_MIN_DBM; -+ } else { -+ rRssi = PARAM_WHQL_RSSI_MIN_DBM; -+ } -+ -+ if (prCmdInfo->fgIsOid) { -+ prGlueInfo = prAdapter->prGlueInfo; -+ prRssi = (PARAM_RSSI *) prCmdInfo->pvInformationBuffer; -+ -+ kalMemCopy(prRssi, &rRssi, sizeof(PARAM_RSSI)); -+ u4QueryInfoLen = sizeof(PARAM_RSSI); -+ -+ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS); -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This routine is in response of OID_GEN_LINK_SPEED query request -+* -+* @param prAdapter Pointer to the Adapter structure. -+* @param prCmdInfo Pointer to the pending command info -+* @param pucEventBuf -+* -+* @retval none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicCmdEventQueryLinkSpeed(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) -+{ -+ P_EVENT_LINK_QUALITY prLinkQuality; -+ P_GLUE_INFO_T prGlueInfo; -+ UINT_32 u4QueryInfoLen; -+ PUINT_32 pu4LinkSpeed; -+ -+ ASSERT(prAdapter); -+ ASSERT(prCmdInfo); -+ -+ prLinkQuality = (P_EVENT_LINK_QUALITY) pucEventBuf; -+ -+ if (prCmdInfo->fgIsOid) { -+ prGlueInfo = prAdapter->prGlueInfo; -+ pu4LinkSpeed = (PUINT_32) (prCmdInfo->pvInformationBuffer); -+ -+ *pu4LinkSpeed = prLinkQuality->u2LinkSpeed * 5000; -+ -+ u4QueryInfoLen = sizeof(UINT_32); -+ -+ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS); -+ } -+} -+ -+VOID nicCmdEventQueryStatistics(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) -+{ -+ P_PARAM_802_11_STATISTICS_STRUCT_T prStatistics; -+ P_EVENT_STATISTICS prEventStatistics; -+ P_GLUE_INFO_T prGlueInfo; -+ UINT_32 u4QueryInfoLen; -+ -+ ASSERT(prAdapter); -+ ASSERT(prCmdInfo); -+ -+ prEventStatistics = (P_EVENT_STATISTICS) pucEventBuf; -+ -+ if (prCmdInfo->fgIsOid) { -+ prGlueInfo = prAdapter->prGlueInfo; -+ -+ u4QueryInfoLen = sizeof(PARAM_802_11_STATISTICS_STRUCT_T); -+ prStatistics = (P_PARAM_802_11_STATISTICS_STRUCT_T) prCmdInfo->pvInformationBuffer; -+ -+ prStatistics->u4Length = sizeof(PARAM_802_11_STATISTICS_STRUCT_T); -+ prStatistics->rTransmittedFragmentCount = prEventStatistics->rTransmittedFragmentCount; -+ prStatistics->rMulticastTransmittedFrameCount = prEventStatistics->rMulticastTransmittedFrameCount; -+ prStatistics->rFailedCount = prEventStatistics->rFailedCount; -+ prStatistics->rRetryCount = prEventStatistics->rRetryCount; -+ prStatistics->rMultipleRetryCount = prEventStatistics->rMultipleRetryCount; -+ prStatistics->rRTSSuccessCount = prEventStatistics->rRTSSuccessCount; -+ prStatistics->rRTSFailureCount = prEventStatistics->rRTSFailureCount; -+ prStatistics->rACKFailureCount = prEventStatistics->rACKFailureCount; -+ prStatistics->rFrameDuplicateCount = prEventStatistics->rFrameDuplicateCount; -+ prStatistics->rReceivedFragmentCount = prEventStatistics->rReceivedFragmentCount; -+ prStatistics->rMulticastReceivedFrameCount = prEventStatistics->rMulticastReceivedFrameCount; -+ prStatistics->rFCSErrorCount = prEventStatistics->rFCSErrorCount; -+ prStatistics->rTKIPLocalMICFailures.QuadPart = 0; -+ prStatistics->rTKIPICVErrors.QuadPart = 0; -+ prStatistics->rTKIPCounterMeasuresInvoked.QuadPart = 0; -+ prStatistics->rTKIPReplays.QuadPart = 0; -+ prStatistics->rCCMPFormatErrors.QuadPart = 0; -+ prStatistics->rCCMPReplays.QuadPart = 0; -+ prStatistics->rCCMPDecryptErrors.QuadPart = 0; -+ prStatistics->rFourWayHandshakeFailures.QuadPart = 0; -+ prStatistics->rWEPUndecryptableCount.QuadPart = 0; -+ prStatistics->rWEPICVErrorCount.QuadPart = 0; -+ prStatistics->rDecryptSuccessCount.QuadPart = 0; -+ prStatistics->rDecryptFailureCount.QuadPart = 0; -+ -+ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS); -+ } -+} -+ -+VOID nicCmdEventEnterRfTest(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) -+{ -+#define WAIT_FW_READY_RETRY_CNT 200 -+ -+ UINT_32 u4WHISR = 0, u4Value = 0; -+ UINT_8 aucTxCount[8]; -+ UINT_16 u2RetryCnt = 0; -+ -+ ASSERT(prAdapter); -+ ASSERT(prCmdInfo); -+ -+ /* [driver-land] */ -+ prAdapter->fgTestMode = TRUE; -+ -+ /* 0. always indicate disconnection */ -+ if (kalGetMediaStateIndicated(prAdapter->prGlueInfo) != PARAM_MEDIA_STATE_DISCONNECTED) -+ kalIndicateStatusAndComplete(prAdapter->prGlueInfo, WLAN_STATUS_MEDIA_DISCONNECT, NULL, 0); -+ /* 1. Remove pending TX */ -+ nicTxRelease(prAdapter); -+ -+ /* 1.1 clear pending Security / Management Frames */ -+ kalClearSecurityFrames(prAdapter->prGlueInfo); -+ kalClearMgmtFrames(prAdapter->prGlueInfo); -+ -+ /* 1.2 clear pending TX packet queued in glue layer */ -+ kalFlushPendingTxPackets(prAdapter->prGlueInfo); -+ -+ /* 2. Reset driver-domain FSMs */ -+ nicUninitMGMT(prAdapter); -+ -+ nicResetSystemService(prAdapter); -+ nicInitMGMT(prAdapter, NULL); -+ -+ /* 3. Disable Interrupt */ -+ HAL_INTR_DISABLE(prAdapter); -+ -+ /* 4. Block til firmware completed entering into RF test mode */ -+ kalMsleep(500); -+ while (1) { -+ HAL_MCR_RD(prAdapter, MCR_WCIR, &u4Value); -+ -+ if (u4Value & WCIR_WLAN_READY) { -+ break; -+ } else if (kalIsCardRemoved(prAdapter->prGlueInfo) == TRUE || fgIsBusAccessFailed == TRUE || -+ kalIsResetting() || u2RetryCnt >= WAIT_FW_READY_RETRY_CNT) { -+ if (prCmdInfo->fgIsOid) { -+ /* Update Set Information Length */ -+ kalOidComplete(prAdapter->prGlueInfo, -+ prCmdInfo->fgSetQuery, -+ prCmdInfo->u4SetInfoLen, WLAN_STATUS_NOT_SUPPORTED); -+ -+ } -+ return; -+ } -+ kalMsleep(10); -+ u2RetryCnt++; -+ } -+ -+ /* 5. Clear Interrupt Status */ -+ HAL_READ_INTR_STATUS(prAdapter, 4, (PUINT_8)&u4WHISR); -+ if (HAL_IS_TX_DONE_INTR(u4WHISR)) -+ HAL_READ_TX_RELEASED_COUNT(prAdapter, aucTxCount); -+ /* 6. Reset TX Counter */ -+ nicTxResetResource(prAdapter); -+ -+ /* 7. Re-enable Interrupt */ -+ HAL_INTR_ENABLE(prAdapter); -+ -+ /* 8. completion indication */ -+ if (prCmdInfo->fgIsOid) { -+ /* Update Set Information Length */ -+ kalOidComplete(prAdapter->prGlueInfo, -+ prCmdInfo->fgSetQuery, prCmdInfo->u4SetInfoLen, WLAN_STATUS_SUCCESS); -+ } -+#if CFG_SUPPORT_NVRAM -+ /* 9. load manufacture data */ -+ wlanLoadManufactureData(prAdapter, kalGetConfiguration(prAdapter->prGlueInfo)); -+#endif -+ -+} -+ -+VOID nicCmdEventLeaveRfTest(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) -+{ -+#define WAIT_FW_READY_RETRY_CNT 200 -+ -+ UINT_32 u4WHISR = 0, u4Value = 0; -+ UINT_8 aucTxCount[8]; -+ UINT_16 u2RetryCnt = 0; -+ -+ ASSERT(prAdapter); -+ ASSERT(prCmdInfo); -+ -+ /* 1. Disable Interrupt */ -+ HAL_INTR_DISABLE(prAdapter); -+ -+ /* 2. Block til firmware completed leaving from RF test mode */ -+ kalMsleep(500); -+ while (1) { -+ HAL_MCR_RD(prAdapter, MCR_WCIR, &u4Value); -+ -+ if (u4Value & WCIR_WLAN_READY) { -+ break; -+ } else if (kalIsCardRemoved(prAdapter->prGlueInfo) == TRUE || fgIsBusAccessFailed == TRUE || -+ kalIsResetting() || u2RetryCnt >= WAIT_FW_READY_RETRY_CNT) { -+ if (prCmdInfo->fgIsOid) { -+ /* Update Set Information Length */ -+ kalOidComplete(prAdapter->prGlueInfo, -+ prCmdInfo->fgSetQuery, -+ prCmdInfo->u4SetInfoLen, WLAN_STATUS_NOT_SUPPORTED); -+ -+ } -+ return; -+ } -+ kalMsleep(10); -+ u2RetryCnt++; -+ } -+ -+ /* 3. Clear Interrupt Status */ -+ HAL_READ_INTR_STATUS(prAdapter, 4, (PUINT_8)&u4WHISR); -+ if (HAL_IS_TX_DONE_INTR(u4WHISR)) -+ HAL_READ_TX_RELEASED_COUNT(prAdapter, aucTxCount); -+ /* 4. Reset TX Counter */ -+ nicTxResetResource(prAdapter); -+ -+ /* 5. Re-enable Interrupt */ -+ HAL_INTR_ENABLE(prAdapter); -+ -+ /* 6. set driver-land variable */ -+ prAdapter->fgTestMode = FALSE; -+ -+ /* 7. completion indication */ -+ if (prCmdInfo->fgIsOid) { -+ /* Update Set Information Length */ -+ kalOidComplete(prAdapter->prGlueInfo, -+ prCmdInfo->fgSetQuery, prCmdInfo->u4SetInfoLen, WLAN_STATUS_SUCCESS); -+ } -+ -+ /* 8. Indicate as disconnected */ -+ if (kalGetMediaStateIndicated(prAdapter->prGlueInfo) != PARAM_MEDIA_STATE_DISCONNECTED) { -+ -+ kalIndicateStatusAndComplete(prAdapter->prGlueInfo, WLAN_STATUS_MEDIA_DISCONNECT, NULL, 0); -+ -+ prAdapter->rWlanInfo.u4SysTime = kalGetTimeTick(); -+ } -+#if CFG_SUPPORT_NVRAM -+ /* 9. load manufacture data */ -+ wlanLoadManufactureData(prAdapter, kalGetConfiguration(prAdapter->prGlueInfo)); -+#endif -+ -+ /* 10. Override network address */ -+ wlanUpdateNetworkAddress(prAdapter); -+ -+} -+ -+VOID nicCmdEventQueryAddress(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) -+{ -+ UINT_32 u4QueryInfoLen; -+ P_GLUE_INFO_T prGlueInfo; -+ P_EVENT_BASIC_CONFIG prEventBasicConfig; -+ -+ ASSERT(prAdapter); -+ ASSERT(prCmdInfo); -+ ASSERT(pucEventBuf); -+ -+ prEventBasicConfig = (P_EVENT_BASIC_CONFIG) (pucEventBuf); -+ -+ /* copy to adapter */ -+ kalMemCopy(&(prAdapter->rMyMacAddr), &(prEventBasicConfig->rMyMacAddr), MAC_ADDR_LEN); -+ -+ /* 4 <2> Update information of OID */ -+ if (prCmdInfo->fgIsOid) { -+ prGlueInfo = prAdapter->prGlueInfo; -+ -+ kalMemCopy(prCmdInfo->pvInformationBuffer, &(prEventBasicConfig->rMyMacAddr), MAC_ADDR_LEN); -+ u4QueryInfoLen = MAC_ADDR_LEN; -+ -+ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS); -+ } -+ /* 4 <3> Update new MAC address and all 3 networks */ -+ COPY_MAC_ADDR(prAdapter->rWifiVar.aucMacAddress, prAdapter->rMyMacAddr); -+ COPY_MAC_ADDR(prAdapter->rWifiVar.aucDeviceAddress, prAdapter->rMyMacAddr); -+ prAdapter->rWifiVar.aucDeviceAddress[0] ^= MAC_ADDR_LOCAL_ADMIN; -+ -+ COPY_MAC_ADDR(prAdapter->rWifiVar.aucInterfaceAddress, prAdapter->rMyMacAddr); -+ prAdapter->rWifiVar.aucInterfaceAddress[0] ^= MAC_ADDR_LOCAL_ADMIN; -+ -+ COPY_MAC_ADDR(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX].aucOwnMacAddr, prAdapter->rMyMacAddr); -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ if (prAdapter->fgIsP2PRegistered) { -+ COPY_MAC_ADDR(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX].aucOwnMacAddr, -+ prAdapter->rWifiVar.aucDeviceAddress); -+ } -+#endif -+ -+#if CFG_ENABLE_BT_OVER_WIFI -+ COPY_MAC_ADDR(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_BOW_INDEX].aucOwnMacAddr, -+ prAdapter->rWifiVar.aucDeviceAddress); -+#endif -+ -+#if CFG_TEST_WIFI_DIRECT_GO -+ if (prAdapter->rWifiVar.prP2pFsmInfo->eCurrentState == P2P_STATE_IDLE) { -+ wlanEnableP2pFunction(prAdapter); -+ -+ wlanEnableATGO(prAdapter); -+ } -+#endif -+ -+ kalUpdateMACAddress(prAdapter->prGlueInfo, prAdapter->rWifiVar.aucMacAddress); -+ -+} -+ -+VOID nicCmdEventQueryMcastAddr(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) -+{ -+ UINT_32 u4QueryInfoLen; -+ P_GLUE_INFO_T prGlueInfo; -+ P_EVENT_MAC_MCAST_ADDR prEventMacMcastAddr; -+ -+ ASSERT(prAdapter); -+ ASSERT(prCmdInfo); -+ ASSERT(pucEventBuf); -+ -+ /* 4 <2> Update information of OID */ -+ if (prCmdInfo->fgIsOid) { -+ prGlueInfo = prAdapter->prGlueInfo; -+ prEventMacMcastAddr = (P_EVENT_MAC_MCAST_ADDR) (pucEventBuf); -+ -+ u4QueryInfoLen = prEventMacMcastAddr->u4NumOfGroupAddr * MAC_ADDR_LEN; -+ -+ /* buffer length check */ -+ if (prCmdInfo->u4InformationBufferLength < u4QueryInfoLen) { -+ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_BUFFER_TOO_SHORT); -+ } else { -+ kalMemCopy(prCmdInfo->pvInformationBuffer, -+ prEventMacMcastAddr->arAddress, -+ prEventMacMcastAddr->u4NumOfGroupAddr * MAC_ADDR_LEN); -+ -+ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS); -+ } -+ } -+} -+ -+VOID nicCmdEventQueryEepromRead(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) -+{ -+ UINT_32 u4QueryInfoLen; -+ P_PARAM_CUSTOM_EEPROM_RW_STRUCT_T prEepromRdInfo; -+ P_GLUE_INFO_T prGlueInfo; -+ P_EVENT_ACCESS_EEPROM prEventAccessEeprom; -+ -+ ASSERT(prAdapter); -+ ASSERT(prCmdInfo); -+ ASSERT(pucEventBuf); -+ -+ /* 4 <2> Update information of OID */ -+ if (prCmdInfo->fgIsOid) { -+ prGlueInfo = prAdapter->prGlueInfo; -+ prEventAccessEeprom = (P_EVENT_ACCESS_EEPROM) (pucEventBuf); -+ -+ u4QueryInfoLen = sizeof(PARAM_CUSTOM_EEPROM_RW_STRUCT_T); -+ -+ prEepromRdInfo = (P_PARAM_CUSTOM_EEPROM_RW_STRUCT_T) prCmdInfo->pvInformationBuffer; -+ prEepromRdInfo->ucEepromIndex = (UINT_8) (prEventAccessEeprom->u2Offset); -+ prEepromRdInfo->u2EepromData = prEventAccessEeprom->u2Data; -+ -+ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS); -+ } -+ -+ return; -+ -+} -+ -+VOID nicCmdEventSetMediaStreamMode(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) -+{ -+ PARAM_MEDIA_STREAMING_INDICATION rParamMediaStreamIndication; -+ -+ ASSERT(prAdapter); -+ ASSERT(prCmdInfo); -+ -+ if (prCmdInfo->fgIsOid) { -+ /* Update Set Information Length */ -+ kalOidComplete(prAdapter->prGlueInfo, -+ prCmdInfo->fgSetQuery, prCmdInfo->u4SetInfoLen, WLAN_STATUS_SUCCESS); -+ } -+ -+ rParamMediaStreamIndication.rStatus.eStatusType = ENUM_STATUS_TYPE_MEDIA_STREAM_MODE; -+ rParamMediaStreamIndication.eMediaStreamMode = -+ prAdapter->rWlanInfo.eLinkAttr.ucMediaStreamMode == 0 ? ENUM_MEDIA_STREAM_OFF : ENUM_MEDIA_STREAM_ON; -+ -+ kalIndicateStatusAndComplete(prAdapter->prGlueInfo, -+ WLAN_STATUS_MEDIA_SPECIFIC_INDICATION, -+ (PVOID)&rParamMediaStreamIndication, sizeof(PARAM_MEDIA_STREAMING_INDICATION)); -+} -+ -+/* Statistics responder */ -+VOID nicCmdEventQueryXmitOk(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) -+{ -+ P_EVENT_STATISTICS prEventStatistics; -+ P_GLUE_INFO_T prGlueInfo; -+ UINT_32 u4QueryInfoLen; -+ PUINT_32 pu4Data; -+ PUINT_64 pu8Data; -+ -+ ASSERT(prAdapter); -+ ASSERT(prCmdInfo); -+ -+ prEventStatistics = (P_EVENT_STATISTICS) pucEventBuf; -+ -+ if (prCmdInfo->fgIsOid) { -+ prGlueInfo = prAdapter->prGlueInfo; -+ -+ if (prCmdInfo->u4InformationBufferLength == sizeof(UINT_32)) { -+ u4QueryInfoLen = sizeof(UINT_32); -+ -+ pu4Data = (PUINT_32) prCmdInfo->pvInformationBuffer; -+ *pu4Data = (UINT_32) prEventStatistics->rTransmittedFragmentCount.QuadPart; -+ } else { -+ u4QueryInfoLen = sizeof(UINT_64); -+ -+ pu8Data = (PUINT_64) prCmdInfo->pvInformationBuffer; -+ *pu8Data = prEventStatistics->rTransmittedFragmentCount.QuadPart; -+ } -+ -+ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS); -+ } -+} -+ -+VOID nicCmdEventQueryRecvOk(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) -+{ -+ P_EVENT_STATISTICS prEventStatistics; -+ P_GLUE_INFO_T prGlueInfo; -+ UINT_32 u4QueryInfoLen; -+ PUINT_32 pu4Data; -+ PUINT_64 pu8Data; -+ -+ ASSERT(prAdapter); -+ ASSERT(prCmdInfo); -+ -+ prEventStatistics = (P_EVENT_STATISTICS) pucEventBuf; -+ -+ if (prCmdInfo->fgIsOid) { -+ prGlueInfo = prAdapter->prGlueInfo; -+ -+ if (prCmdInfo->u4InformationBufferLength == sizeof(UINT_32)) { -+ u4QueryInfoLen = sizeof(UINT_32); -+ -+ pu4Data = (PUINT_32) prCmdInfo->pvInformationBuffer; -+ *pu4Data = (UINT_32) prEventStatistics->rReceivedFragmentCount.QuadPart; -+ } else { -+ u4QueryInfoLen = sizeof(UINT_64); -+ -+ pu8Data = (PUINT_64) prCmdInfo->pvInformationBuffer; -+ *pu8Data = prEventStatistics->rReceivedFragmentCount.QuadPart; -+ } -+ -+ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS); -+ } -+} -+ -+VOID nicCmdEventQueryXmitError(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) -+{ -+ P_EVENT_STATISTICS prEventStatistics; -+ P_GLUE_INFO_T prGlueInfo; -+ UINT_32 u4QueryInfoLen; -+ PUINT_32 pu4Data; -+ PUINT_64 pu8Data; -+ -+ ASSERT(prAdapter); -+ ASSERT(prCmdInfo); -+ -+ prEventStatistics = (P_EVENT_STATISTICS) pucEventBuf; -+ -+ if (prCmdInfo->fgIsOid) { -+ prGlueInfo = prAdapter->prGlueInfo; -+ -+ if (prCmdInfo->u4InformationBufferLength == sizeof(UINT_32)) { -+ u4QueryInfoLen = sizeof(UINT_32); -+ -+ pu4Data = (PUINT_32) prCmdInfo->pvInformationBuffer; -+ *pu4Data = (UINT_32) prEventStatistics->rFailedCount.QuadPart; -+ } else { -+ u4QueryInfoLen = sizeof(UINT_64); -+ -+ pu8Data = (PUINT_64) prCmdInfo->pvInformationBuffer; -+ *pu8Data = (UINT_64) prEventStatistics->rFailedCount.QuadPart; -+ } -+ -+ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS); -+ } -+} -+ -+VOID nicCmdEventQueryRecvError(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) -+{ -+ P_EVENT_STATISTICS prEventStatistics; -+ P_GLUE_INFO_T prGlueInfo; -+ UINT_32 u4QueryInfoLen; -+ PUINT_32 pu4Data; -+ PUINT_64 pu8Data; -+ -+ ASSERT(prAdapter); -+ ASSERT(prCmdInfo); -+ -+ prEventStatistics = (P_EVENT_STATISTICS) pucEventBuf; -+ -+ if (prCmdInfo->fgIsOid) { -+ prGlueInfo = prAdapter->prGlueInfo; -+ -+ if (prCmdInfo->u4InformationBufferLength == sizeof(UINT_32)) { -+ u4QueryInfoLen = sizeof(UINT_32); -+ -+ pu4Data = (PUINT_32) prCmdInfo->pvInformationBuffer; -+ *pu4Data = (UINT_32) prEventStatistics->rFCSErrorCount.QuadPart; -+ /* @FIXME, RX_ERROR_DROP_COUNT/RX_FIFO_FULL_DROP_COUNT is not calculated */ -+ } else { -+ u4QueryInfoLen = sizeof(UINT_64); -+ -+ pu8Data = (PUINT_64) prCmdInfo->pvInformationBuffer; -+ *pu8Data = prEventStatistics->rFCSErrorCount.QuadPart; -+ /* @FIXME, RX_ERROR_DROP_COUNT/RX_FIFO_FULL_DROP_COUNT is not calculated */ -+ } -+ -+ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS); -+ } -+} -+ -+VOID nicCmdEventQueryRecvNoBuffer(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) -+{ -+ P_EVENT_STATISTICS prEventStatistics; -+ P_GLUE_INFO_T prGlueInfo; -+ UINT_32 u4QueryInfoLen; -+ PUINT_32 pu4Data; -+ PUINT_64 pu8Data; -+ -+ ASSERT(prAdapter); -+ ASSERT(prCmdInfo); -+ -+ prEventStatistics = (P_EVENT_STATISTICS) pucEventBuf; -+ -+ if (prCmdInfo->fgIsOid) { -+ prGlueInfo = prAdapter->prGlueInfo; -+ -+ if (prCmdInfo->u4InformationBufferLength == sizeof(UINT_32)) { -+ u4QueryInfoLen = sizeof(UINT_32); -+ -+ pu4Data = (PUINT_32) prCmdInfo->pvInformationBuffer; -+ *pu4Data = 0; /* @FIXME? */ -+ } else { -+ u4QueryInfoLen = sizeof(UINT_64); -+ -+ pu8Data = (PUINT_64) prCmdInfo->pvInformationBuffer; -+ *pu8Data = 0; /* @FIXME? */ -+ } -+ -+ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS); -+ } -+} -+ -+VOID nicCmdEventQueryRecvCrcError(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) -+{ -+ P_EVENT_STATISTICS prEventStatistics; -+ P_GLUE_INFO_T prGlueInfo; -+ UINT_32 u4QueryInfoLen; -+ PUINT_32 pu4Data; -+ PUINT_64 pu8Data; -+ -+ ASSERT(prAdapter); -+ ASSERT(prCmdInfo); -+ -+ prEventStatistics = (P_EVENT_STATISTICS) pucEventBuf; -+ -+ if (prCmdInfo->fgIsOid) { -+ prGlueInfo = prAdapter->prGlueInfo; -+ -+ if (prCmdInfo->u4InformationBufferLength == sizeof(UINT_32)) { -+ u4QueryInfoLen = sizeof(UINT_32); -+ -+ pu4Data = (PUINT_32) prCmdInfo->pvInformationBuffer; -+ *pu4Data = (UINT_32) prEventStatistics->rFCSErrorCount.QuadPart; -+ } else { -+ u4QueryInfoLen = sizeof(UINT_64); -+ -+ pu8Data = (PUINT_64) prCmdInfo->pvInformationBuffer; -+ *pu8Data = prEventStatistics->rFCSErrorCount.QuadPart; -+ } -+ -+ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS); -+ } -+} -+ -+VOID nicCmdEventQueryRecvErrorAlignment(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) -+{ -+ P_EVENT_STATISTICS prEventStatistics; -+ P_GLUE_INFO_T prGlueInfo; -+ UINT_32 u4QueryInfoLen; -+ PUINT_32 pu4Data; -+ PUINT_64 pu8Data; -+ -+ ASSERT(prAdapter); -+ ASSERT(prCmdInfo); -+ -+ prEventStatistics = (P_EVENT_STATISTICS) pucEventBuf; -+ -+ if (prCmdInfo->fgIsOid) { -+ prGlueInfo = prAdapter->prGlueInfo; -+ -+ if (prCmdInfo->u4InformationBufferLength == sizeof(UINT_32)) { -+ u4QueryInfoLen = sizeof(UINT_32); -+ -+ pu4Data = (PUINT_32) prCmdInfo->pvInformationBuffer; -+ *pu4Data = (UINT_32) 0; /* @FIXME */ -+ } else { -+ u4QueryInfoLen = sizeof(UINT_64); -+ -+ pu8Data = (PUINT_64) prCmdInfo->pvInformationBuffer; -+ *pu8Data = 0; /* @FIXME */ -+ } -+ -+ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS); -+ } -+} -+ -+VOID nicCmdEventQueryXmitOneCollision(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) -+{ -+ P_EVENT_STATISTICS prEventStatistics; -+ P_GLUE_INFO_T prGlueInfo; -+ UINT_32 u4QueryInfoLen; -+ PUINT_32 pu4Data; -+ PUINT_64 pu8Data; -+ -+ ASSERT(prAdapter); -+ ASSERT(prCmdInfo); -+ -+ prEventStatistics = (P_EVENT_STATISTICS) pucEventBuf; -+ -+ if (prCmdInfo->fgIsOid) { -+ prGlueInfo = prAdapter->prGlueInfo; -+ -+ if (prCmdInfo->u4InformationBufferLength == sizeof(UINT_32)) { -+ u4QueryInfoLen = sizeof(UINT_32); -+ -+ pu4Data = (PUINT_32) prCmdInfo->pvInformationBuffer; -+ *pu4Data = -+ (UINT_32) (prEventStatistics->rMultipleRetryCount.QuadPart - -+ prEventStatistics->rRetryCount.QuadPart); -+ } else { -+ u4QueryInfoLen = sizeof(UINT_64); -+ -+ pu8Data = (PUINT_64) prCmdInfo->pvInformationBuffer; -+ *pu8Data = -+ (UINT_64) (prEventStatistics->rMultipleRetryCount.QuadPart - -+ prEventStatistics->rRetryCount.QuadPart); -+ } -+ -+ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS); -+ } -+} -+ -+VOID nicCmdEventQueryXmitMoreCollisions(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) -+{ -+ P_EVENT_STATISTICS prEventStatistics; -+ P_GLUE_INFO_T prGlueInfo; -+ UINT_32 u4QueryInfoLen; -+ PUINT_32 pu4Data; -+ PUINT_64 pu8Data; -+ -+ ASSERT(prAdapter); -+ ASSERT(prCmdInfo); -+ -+ prEventStatistics = (P_EVENT_STATISTICS) pucEventBuf; -+ -+ if (prCmdInfo->fgIsOid) { -+ prGlueInfo = prAdapter->prGlueInfo; -+ -+ if (prCmdInfo->u4InformationBufferLength == sizeof(UINT_32)) { -+ u4QueryInfoLen = sizeof(UINT_32); -+ -+ pu4Data = (PUINT_32) prCmdInfo->pvInformationBuffer; -+ *pu4Data = (UINT_32) prEventStatistics->rMultipleRetryCount.QuadPart; -+ } else { -+ u4QueryInfoLen = sizeof(UINT_64); -+ -+ pu8Data = (PUINT_64) prCmdInfo->pvInformationBuffer; -+ *pu8Data = (UINT_64) prEventStatistics->rMultipleRetryCount.QuadPart; -+ } -+ -+ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS); -+ } -+} -+ -+VOID nicCmdEventQueryXmitMaxCollisions(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) -+{ -+ P_EVENT_STATISTICS prEventStatistics; -+ P_GLUE_INFO_T prGlueInfo; -+ UINT_32 u4QueryInfoLen; -+ PUINT_32 pu4Data; -+ PUINT_64 pu8Data; -+ -+ ASSERT(prAdapter); -+ ASSERT(prCmdInfo); -+ -+ prEventStatistics = (P_EVENT_STATISTICS) pucEventBuf; -+ -+ if (prCmdInfo->fgIsOid) { -+ prGlueInfo = prAdapter->prGlueInfo; -+ -+ if (prCmdInfo->u4InformationBufferLength == sizeof(UINT_32)) { -+ u4QueryInfoLen = sizeof(UINT_32); -+ -+ pu4Data = (PUINT_32) prCmdInfo->pvInformationBuffer; -+ *pu4Data = (UINT_32) prEventStatistics->rFailedCount.QuadPart; -+ } else { -+ u4QueryInfoLen = sizeof(UINT_64); -+ -+ pu8Data = (PUINT_64) prCmdInfo->pvInformationBuffer; -+ *pu8Data = (UINT_64) prEventStatistics->rFailedCount.QuadPart; -+ } -+ -+ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS); -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is called when command by OID/ioctl has been timeout -+* -+* @param prAdapter Pointer to the Adapter structure. -+* @param prCmdInfo Pointer to the command information -+* -+* @return TRUE -+* FALSE -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicOidCmdTimeoutCommon(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo) -+{ -+ ASSERT(prAdapter); -+ -+ kalOidComplete(prAdapter->prGlueInfo, prCmdInfo->fgSetQuery, 0, WLAN_STATUS_FAILURE); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is a generic command timeout handler -+* -+* @param pfnOidHandler Pointer to the OID handler -+* -+* @return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicCmdTimeoutCommon(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo) -+{ -+ ASSERT(prAdapter); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is called when command for entering RF test has -+* failed sending due to timeout (highly possibly by firmware crash) -+* -+* @param prAdapter Pointer to the Adapter structure. -+* @param prCmdInfo Pointer to the command information -+* -+* @return none -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicOidCmdEnterRFTestTimeout(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo) -+{ -+ ASSERT(prAdapter); -+ -+ /* 1. Remove pending TX frames */ -+ nicTxRelease(prAdapter); -+ -+ /* 1.1 clear pending Security / Management Frames */ -+ kalClearSecurityFrames(prAdapter->prGlueInfo); -+ kalClearMgmtFrames(prAdapter->prGlueInfo); -+ -+ /* 1.2 clear pending TX packet queued in glue layer */ -+ kalFlushPendingTxPackets(prAdapter->prGlueInfo); -+ -+ /* 2. indicate for OID failure */ -+ kalOidComplete(prAdapter->prGlueInfo, prCmdInfo->fgSetQuery, 0, WLAN_STATUS_FAILURE); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is called when command for memory dump has -+* replied a event. -+* -+* @param prAdapter Pointer to the Adapter structure. -+* @param prCmdInfo Pointer to the command information -+* @param pucEventBuf Pointer to event buffer -+* -+* @return none -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicCmdEventQueryMemDump(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) -+{ -+ UINT_32 u4QueryInfoLen; -+ P_PARAM_CUSTOM_MEM_DUMP_STRUCT_T prMemDumpInfo; -+ P_GLUE_INFO_T prGlueInfo; -+ P_EVENT_DUMP_MEM_T prEventDumpMem; -+ static UINT_8 aucPath[256]; -+ static UINT_32 u4CurTimeTick; -+ -+ ASSERT(prAdapter); -+ ASSERT(prCmdInfo); -+ ASSERT(pucEventBuf); -+ -+ /* 4 <2> Update information of OID */ -+ if (prCmdInfo->fgIsOid) { -+ prGlueInfo = prAdapter->prGlueInfo; -+ prEventDumpMem = (P_EVENT_DUMP_MEM_T) (pucEventBuf); -+ -+ u4QueryInfoLen = sizeof(P_PARAM_CUSTOM_MEM_DUMP_STRUCT_T); -+ -+ prMemDumpInfo = (P_PARAM_CUSTOM_MEM_DUMP_STRUCT_T) prCmdInfo->pvInformationBuffer; -+ prMemDumpInfo->u4Address = prEventDumpMem->u4Address; -+ prMemDumpInfo->u4Length = prEventDumpMem->u4Length; -+ prMemDumpInfo->u4RemainLength = prEventDumpMem->u4RemainLength; -+ prMemDumpInfo->ucFragNum = prEventDumpMem->ucFragNum; -+ -+#if 0 -+ do { -+ UINT_32 i = 0; -+ -+ DBGLOG(REQ, TRACE, "Rx dump address 0x%X, Length %d, FragNum %d, remain %d\n", -+ prEventDumpMem->u4Address, -+ prEventDumpMem->u4Length, prEventDumpMem->ucFragNum, prEventDumpMem->u4RemainLength); -+#if 0 -+ for (i = 0; i < prEventDumpMem->u4Length; i++) { -+ DBGLOG(REQ, TRACE, "%02X ", prEventDumpMem->aucBuffer[i]); -+ if (i % 32 == 31) -+ DBGLOG(REQ, TRACE, "\n"); -+ } -+#endif -+ } while (FALSE); -+#endif -+ -+ if (prEventDumpMem->ucFragNum == 1) { -+ /* Store memory dump into sdcard, -+ * path /sdcard/dump___.hex -+ */ -+ u4CurTimeTick = kalGetTimeTick(); -+ sprintf(aucPath, "/sdcard/dump_%d_0x%08X_%d.hex", -+ u4CurTimeTick, -+ prEventDumpMem->u4Address, prEventDumpMem->u4Length + prEventDumpMem->u4RemainLength); -+ kalWriteToFile(aucPath, FALSE, &prEventDumpMem->aucBuffer[0], prEventDumpMem->u4Length); -+ } else { -+ /* Append current memory dump to the hex file */ -+ kalWriteToFile(aucPath, TRUE, &prEventDumpMem->aucBuffer[0], prEventDumpMem->u4Length); -+ } -+ -+ if (prEventDumpMem->u4RemainLength == 0 || prEventDumpMem->u4Address == 0xFFFFFFFF) { -+ /* The request is finished or firmware response a error */ -+ /* Reply time tick to iwpriv */ -+ *((PUINT_32) prCmdInfo->pvInformationBuffer) = u4CurTimeTick; -+ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS); -+ } else { -+ /* The memory dump request is not finished, Send next command */ -+ wlanSendMemDumpCmd(prAdapter, -+ prCmdInfo->pvInformationBuffer, prCmdInfo->u4InformationBufferLength); -+ } -+ } -+ -+ return; -+ -+} -+ -+#if CFG_SUPPORT_BATCH_SCAN -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is called when event for SUPPORT_BATCH_SCAN -+* -+* @param prAdapter Pointer to the Adapter structure. -+* @param prCmdInfo Pointer to the command information -+* @param pucEventBuf Pointer to the event buffer -+* -+* @return none -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicCmdEventBatchScanResult(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) -+{ -+ UINT_32 u4QueryInfoLen; -+ P_EVENT_BATCH_RESULT_T prEventBatchResult; -+ P_GLUE_INFO_T prGlueInfo; -+ -+ DBGLOG(SCN, TRACE, "nicCmdEventBatchScanResult"); -+ -+ ASSERT(prAdapter); -+ ASSERT(prCmdInfo); -+ ASSERT(pucEventBuf); -+ -+ /* 4 <2> Update information of OID */ -+ if (prCmdInfo->fgIsOid) { -+ prGlueInfo = prAdapter->prGlueInfo; -+ prEventBatchResult = (P_EVENT_BATCH_RESULT_T) pucEventBuf; -+ -+ u4QueryInfoLen = sizeof(EVENT_BATCH_RESULT_T); -+ kalMemCopy(prCmdInfo->pvInformationBuffer, prEventBatchResult, sizeof(EVENT_BATCH_RESULT_T)); -+ -+ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS); -+ } -+ -+} -+#endif -+ -+#if CFG_SUPPORT_BUILD_DATE_CODE -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is called when event for build date code information -+* has been retrieved -+* -+* @param prAdapter Pointer to the Adapter structure. -+* @param prCmdInfo Pointer to the command information -+* @param pucEventBuf Pointer to the event buffer -+* -+* @return none -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicCmdEventBuildDateCode(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) -+{ -+ UINT_32 u4QueryInfoLen; -+ P_EVENT_BUILD_DATE_CODE prEvent; -+ P_GLUE_INFO_T prGlueInfo; -+ -+ ASSERT(prAdapter); -+ ASSERT(prCmdInfo); -+ ASSERT(pucEventBuf); -+ -+ /* 4 <2> Update information of OID */ -+ if (prCmdInfo->fgIsOid) { -+ prGlueInfo = prAdapter->prGlueInfo; -+ prEvent = (P_EVENT_BUILD_DATE_CODE) pucEventBuf; -+ -+ u4QueryInfoLen = sizeof(UINT_8) * 16; -+ kalMemCopy(prCmdInfo->pvInformationBuffer, prEvent->aucDateCode, sizeof(UINT_8) * 16); -+ -+ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS); -+ } -+ -+} -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is called when event for query STA link status -+* has been retrieved -+* -+* @param prAdapter Pointer to the Adapter structure. -+* @param prCmdInfo Pointer to the command information -+* @param pucEventBuf Pointer to the event buffer -+* -+* @return none -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicCmdEventQueryStaStatistics(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) -+{ -+ UINT_32 u4QueryInfoLen; -+ P_EVENT_STA_STATISTICS_T prEvent; -+ P_GLUE_INFO_T prGlueInfo; -+ P_PARAM_GET_STA_STATISTICS prStaStatistics; -+ -+ if ((prAdapter == NULL) -+ || (prCmdInfo == NULL) -+ || (pucEventBuf == NULL) -+ || (prCmdInfo->pvInformationBuffer == NULL)) { -+ ASSERT(FALSE); -+ return; -+ } -+ -+ if (prCmdInfo->fgIsOid) { -+ prGlueInfo = prAdapter->prGlueInfo; -+ prEvent = (P_EVENT_STA_STATISTICS_T) pucEventBuf; -+ prStaStatistics = (P_PARAM_GET_STA_STATISTICS) prCmdInfo->pvInformationBuffer; -+ -+ u4QueryInfoLen = sizeof(PARAM_GET_STA_STA_STATISTICS); -+ -+ /* Statistics from FW is valid */ -+ if (prEvent->u4Flags & BIT(0)) { -+ prStaStatistics->ucPer = prEvent->ucPer; -+ prStaStatistics->ucRcpi = prEvent->ucRcpi; -+ prStaStatistics->u4PhyMode = prEvent->u4PhyMode; -+ prStaStatistics->u2LinkSpeed = prEvent->u2LinkSpeed; -+ -+ prStaStatistics->u4TxFailCount = prEvent->u4TxFailCount; -+ prStaStatistics->u4TxLifeTimeoutCount = prEvent->u4TxLifeTimeoutCount; -+ -+ if (prEvent->u4TxCount) { -+ UINT_32 u4TxDoneAirTimeMs = USEC_TO_MSEC(prEvent->u4TxDoneAirTime * 32); -+ -+ prStaStatistics->u4TxAverageAirTime = (u4TxDoneAirTimeMs / prEvent->u4TxCount); -+ } else { -+ prStaStatistics->u4TxAverageAirTime = 0; -+ } -+ } -+ -+ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS); -+ } -+ -+} -+ -+#if CFG_AUTO_CHANNEL_SEL_SUPPORT -+ -+/* 4 Auto Channel Selection */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is called when event for query STA link status -+* has been retrieved -+* -+* @param prAdapter Pointer to the Adapter structure. -+* @param prCmdInfo Pointer to the command information -+* @param pucEventBuf Pointer to the event buffer -+* -+* @return none -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicCmdEventQueryChannelLoad(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) -+{ -+ UINT_32 u4QueryInfoLen; -+ P_EVENT_CHN_LOAD_T prEvent; -+ P_GLUE_INFO_T prGlueInfo; -+ P_PARAM_GET_CHN_LOAD prChnLoad; -+ -+ if ((prAdapter == NULL) -+ || (prCmdInfo == NULL) -+ || (pucEventBuf == NULL) -+ || (prCmdInfo->pvInformationBuffer == NULL)) { -+ ASSERT(FALSE); -+ return; -+ } -+ -+ if (prCmdInfo->fgIsOid) { -+ prGlueInfo = prAdapter->prGlueInfo; -+ prEvent = (P_EVENT_CHN_LOAD_T) pucEventBuf; /* 4 The firmware responsed data */ -+ /* 4 Fill the firmware data in and send it back to host */ -+ prChnLoad = (P_PARAM_GET_CHN_LOAD) prCmdInfo->pvInformationBuffer; -+ -+ u4QueryInfoLen = sizeof(PARAM_GET_CHN_LOAD); -+ -+ /* Statistics from FW is valid */ -+ if (prEvent->u4Flags & BIT(0)) { -+ prChnLoad->rEachChnLoad[0].ucChannel = prEvent->ucChannel; -+ prChnLoad->rEachChnLoad[0].u2ChannelLoad = prEvent->u2ChannelLoad; -+ DBGLOG(P2P, INFO, "CHN[%d]=%d\n", prEvent->ucChannel, prEvent->u2ChannelLoad); -+ -+ } -+ -+ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS); -+ } -+ -+} -+ -+VOID nicCmdEventQueryLTESafeChn(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) -+{ -+ UINT_8 ucIdx = 0; -+ UINT_32 u4QueryInfoLen; -+ P_EVENT_LTE_MODE_T prEvent; -+ P_GLUE_INFO_T prGlueInfo; -+ P_PARAM_GET_CHN_LOAD prLteSafeChnInfo; -+ -+ if ((prAdapter == NULL) -+ || (prCmdInfo == NULL) -+ || (pucEventBuf == NULL) -+ || (prCmdInfo->pvInformationBuffer == NULL)) { -+ ASSERT(FALSE); -+ return; -+ } -+ if (prCmdInfo->fgIsOid) { -+ prGlueInfo = prAdapter->prGlueInfo; -+ prEvent = (P_EVENT_LTE_MODE_T) pucEventBuf; /* 4 The firmware responsed data */ -+ -+ prLteSafeChnInfo = (P_PARAM_GET_CHN_LOAD) prCmdInfo->pvInformationBuffer; -+ -+ u4QueryInfoLen = sizeof(PARAM_GET_CHN_LOAD); -+ -+ /* Statistics from FW is valid */ -+ if (prEvent->u4Flags & BIT(0)) { -+ for (ucIdx = 0; ucIdx < (NL80211_TESTMODE_AVAILABLE_CHAN_NUM - 1); ucIdx++) { -+ prLteSafeChnInfo->rLteSafeChnList.au4SafeChannelBitmask[ucIdx] = -+ prEvent->rLteSafeChn.au4SafeChannelBitmask[ucIdx]; -+ -+ DBGLOG(P2P, INFO, -+ "[Auto Channel]LTE safe channels [%d]=[%x]\n", ucIdx, -+ (UINT32) prLteSafeChnInfo->rLteSafeChnList.au4SafeChannelBitmask[ucIdx]); -+ } -+ } -+ -+ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS); -+ } -+ -+} -+#endif -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is called when event for query FW bss info -+* has been retrieved -+* -+* @param prAdapter Pointer to the Adapter structure. -+* @param prCmdInfo Pointer to the command information -+* @param pucEventBuf Pointer to the event buffer -+* -+* @return none -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+ -+VOID nicCmdEventGetBSSInfo(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN PUINT_8 pucEventBuf) -+{ -+ UINT_32 u4QueryInfoLen; -+ P_EVENT_AIS_BSS_INFO_T prEvent; -+ P_GLUE_INFO_T prGlueInfo; -+ P_BSS_INFO_T prAisBssInfo; -+ -+ ASSERT(prAdapter); -+ -+ ASSERT(prCmdInfo); -+ ASSERT(pucEventBuf); -+ -+ /* 4 <2> Update information of OID */ -+ if (prCmdInfo->fgIsOid) { -+ prGlueInfo = prAdapter->prGlueInfo; -+ prEvent = (P_EVENT_AIS_BSS_INFO_T) pucEventBuf; -+ -+ u4QueryInfoLen = sizeof(EVENT_AIS_BSS_INFO_T); -+ kalMemCopy(prCmdInfo->pvInformationBuffer, prEvent, sizeof(EVENT_AIS_BSS_INFO_T)); -+ prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ -+ if (prEvent->eCurrentOPMode == OP_MODE_INFRASTRUCTURE) { -+ if (prEvent->eConnectionState != prAisBssInfo->eConnectionState) { -+ DBGLOG(NIC, ERROR, "driver[%d] & FW[%d] status didn't sync !!!\n", -+ prAisBssInfo->eConnectionState, prEvent->eCurrentOPMode); -+ aisFsmStateAbort(prAdapter, DISCONNECT_REASON_CODE_RADIO_LOST, FALSE); -+ } -+ } -+ -+ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, u4QueryInfoLen, WLAN_STATUS_SUCCESS); -+ } -+ -+} -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic_pwr_mgt.c b/drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic_pwr_mgt.c -new file mode 100644 -index 000000000000..cf80fd999a24 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic_pwr_mgt.c -@@ -0,0 +1,669 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/nic/nic_pwr_mgt.c#1 -+*/ -+ -+/*! \file "nic_pwr_mgt.c" -+ \brief In this file we define the STATE and EVENT for Power Management FSM. -+ -+ The SCAN FSM is responsible for performing SCAN behavior when the Arbiter enter -+ ARB_STATE_SCAN. The STATE and EVENT for SCAN FSM are defined here with detail -+ description. -+*/ -+ -+/* -+** Log: nic_pwr_mgt.c -+ * -+ * 11 28 2011 cp.wu -+ * [WCXRP00001125] [MT6620 Wi-Fi][Firmware] Strengthen Wi-Fi power off sequence to have a clearroom environment when -+ * returining to ROM code -+ * 1. Due to firmware now stops HIF DMA for powering off, do not try to receive any packet from firmware -+ * 2. Take use of prAdapter->fgIsEnterD3ReqIssued for tracking whether it is powering off or not -+ * -+ * 10 03 2011 cp.wu -+ * [WCXRP00001022] [MT6628 Driver][Firmware Download] Add multi section independent download functionality -+ * add firmware download path in divided scatters. -+ * -+ * 08 15 2011 cp.wu -+ * [WCXRP00000851] [MT6628 Wi-Fi][Driver] Add HIFSYS related definition to driver source tree -+ * reuse firmware download logic of MT6620 for MT6628. -+ * -+ * 05 11 2011 cp.wu -+ * [WCXRP00000718] [MT6620 Wi-Fi] modify the behavior of setting tx power -+ * ACPI APIs migrate to wlan_lib.c for glue layer to invoke. -+ * -+ * 04 29 2011 cp.wu -+ * [WCXRP00000636] [WHQL][MT5931 Driver] 2c_PMHibernate (hang on 2h) -+ * fix for compilation error when applied with FW_DOWNLOAD = 0 -+ * -+ * 04 18 2011 cp.wu -+ * [WCXRP00000636] [WHQL][MT5931 Driver] 2c_PMHibernate (hang on 2h) -+ * 1) add API for glue layer to query ACPI state -+ * 2) Windows glue should not access to hardware after switched into D3 state -+ * -+ * 04 13 2011 cp.wu -+ * [WCXRP00000639] [WHQL][MT5931 Driver] 2c_PMStandby test item can not complete -+ * refine for MT5931/MT6620 logic separation. -+ * -+ * 04 13 2011 cp.wu -+ * [WCXRP00000639] [WHQL][MT5931 Driver] 2c_PMStandby test item can not complete -+ * bugfix: firmware download procedure for ACPI state transition is not complete. -+ * -+ * 03 15 2011 cp.wu -+ * [WCXRP00000559] [MT6620 Wi-Fi][Driver] Combine TX/RX DMA buffers into a single one to reduce physically continuous -+ * memory consumption -+ * 1. deprecate CFG_HANDLE_IST_IN_SDIO_CALLBACK -+ * 2. Use common coalescing buffer for both TX/RX directions -+ * -+ * -+ * 03 07 2011 terry.wu -+ * [WCXRP00000521] [MT6620 Wi-Fi][Driver] Remove non-standard debug message -+ * Toggle non-standard debug messages to comments. -+ * -+ * 12 31 2010 cp.wu -+ * [WCXRP00000335] [MT6620 Wi-Fi][Driver] change to use milliseconds sleep instead of delay to avoid blocking to system -+ * scheduling -+ * change to use msleep() and shorten waiting interval to reduce blocking to other task while Wi-Fi driver is being -+ * loaded -+ * -+ * 12 31 2010 cp.wu -+ * [WCXRP00000327] [MT6620 Wi-Fi][Driver] Improve HEC WHQA 6972 workaround coverage in driver side -+ * check success or failure for setting fw-own -+ * -+ * 12 30 2010 cp.wu -+ * [WCXRP00000327] [MT6620 Wi-Fi][Driver] Improve HEC WHQA 6972 workaround coverage in driver side -+ * host driver not to set FW-own when there is still pending interrupts -+ * -+ * 10 07 2010 cp.wu -+ * [WCXRP00000083] [MT5931][Driver][FW] Add necessary logic for MT5931 first connection -+ * add firmware download for MT5931. -+ * -+ * 09 21 2010 cp.wu -+ * [WCXRP00000053] [MT6620 Wi-Fi][Driver] Reset incomplete and might leads to BSOD when entering RF test with AIS -+ * associated -+ * Do a complete reset with STA-REC null checking for RF test re-entry -+ * -+ * 08 30 2010 cp.wu -+ * NULL -+ * eliminate klockwork errors -+ * -+ * 08 30 2010 cp.wu -+ * NULL -+ * reset ACPI power state before waking up MT6620 Wi-Fi firmware. -+ * -+ * 08 12 2010 cp.wu -+ * NULL -+ * [AIS-FSM] honor registry setting for adhoc running mode. (A/B/G) -+ * -+ * 08 03 2010 cp.wu -+ * NULL -+ * Centralize mgmt/system service procedures into independent calls. -+ * -+ * 07 22 2010 cp.wu -+ * -+ * 1) refine AIS-FSM indent. -+ * 2) when entering RF Test mode, flush 802.1X frames as well -+ * 3) when entering D3 state, flush 802.1X frames as well -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 21 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * change MAC address updating logic. -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 05 24 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) when acquiring LP-own, write for clr-own with lower frequency compared to read poll -+ * 2) correct address list parsing -+ * -+ * 05 22 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * sleepy notify is only used for sleepy state, -+ * while wake-up state is automatically set when host needs to access device -+ * -+ * 05 19 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * correct hibernation problem. -+ * -+ * 04 26 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) surpress compiler warning -+ * 2) when acqruing LP-own, keep writing WHLPCR whenever OWN is not acquired yet -+ * -+ * 04 23 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * surpress compiler warning -+ * -+ * 04 22 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * when acquiring driver-own, wait for up to 8 seconds. -+ * -+ * 04 21 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * add for private ioctl support -+ * -+ * 04 20 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) remove redundant firmware image unloading -+ * * 2) use compile-time macros to separate logic related to accquiring own -+ * -+ * 04 16 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * treat BUS access failure as kind of card removal. -+ * -+ * 04 07 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * accessing to firmware load/start address, and access to OID handling information -+ * * are now handled in glue layer -+ * -+ * 04 06 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * ePowerCtrl is not necessary as a glue variable. -+ * -+ * 04 06 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * add KAL API: kalFlushPendingTxPackets(), and take use of the API -+ * -+ * 04 06 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * eliminate direct access for prGlueInfo->fgIsCardRemoved in non-glue layer -+ * -+ * 03 24 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * initial import for Linux port -+ * -+ * 03 22 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * always send CMD_NIC_POWER_CTRL packet when nic is being halted -+ * -+ * 03 19 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * correct typo. -+ * -+ * 03 19 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) add ACPI D0/D3 state switching support -+ * * * * * * * * 2) use more formal way to handle interrupt when the status is retrieved from enhanced RX -+ * response -+ * -+ * 03 08 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) add another spin-lock to protect MsduInfoList due to it might be accessed by different thread. -+ * * 2) change own-back acquiring procedure to wait for up to 16.67 seconds -+** \main\maintrunk.MT6620WiFiDriver_Prj\6 2009-10-13 21:59:15 GMT mtk01084 -+** update for new HW design -+** \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-09-09 17:26:36 GMT mtk01084 -+** remove CMD52 access -+** \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-05-18 14:50:29 GMT mtk01084 -+** modify lines in nicpmSetDriverOwn() -+** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-03-23 16:55:37 GMT mtk01084 -+** modify nicpmSetDriverOwn() -+** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-19 18:33:00 GMT mtk01084 -+** update for basic power management functions -+** \main\maintrunk.MT6620WiFiDriver_Prj\1 2009-03-19 15:05:32 GMT mtk01084 -+** Initial version -+** -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "precomp.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is used to process the POWER ON procedure. -+* -+* \param[in] pvAdapter Pointer to the Adapter structure. -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicpmSetFWOwn(IN P_ADAPTER_T prAdapter, IN BOOLEAN fgEnableGlobalInt) -+{ -+ UINT_32 u4RegValue = 0; -+ -+ ASSERT(prAdapter); -+ -+ if (prAdapter->fgIsFwOwn == TRUE) -+ return; -+ -+ if (nicProcessIST(prAdapter) != WLAN_STATUS_NOT_INDICATING) { -+ /* pending interrupts */ -+ return; -+ } -+ -+ if (fgEnableGlobalInt) { -+ prAdapter->fgIsIntEnableWithLPOwnSet = TRUE; -+ } else { -+ HAL_MCR_WR(prAdapter, MCR_WHLPCR, WHLPCR_FW_OWN_REQ_SET); -+ -+ HAL_MCR_RD(prAdapter, MCR_WHLPCR, &u4RegValue); -+ if (u4RegValue & WHLPCR_FW_OWN_REQ_SET) { -+ /* if set firmware own not successful (possibly pending interrupts), */ -+ /* indicate an own clear event */ -+ HAL_MCR_WR(prAdapter, MCR_WHLPCR, WHLPCR_FW_OWN_REQ_CLR); -+ -+ return; -+ } -+ -+ prAdapter->fgIsFwOwn = TRUE; -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is used to process the POWER OFF procedure. -+* -+* \param[in] pvAdapter Pointer to the Adapter structure. -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT_32 u4OriRegValue = 0; -+BOOLEAN nicpmSetDriverOwn(IN P_ADAPTER_T prAdapter) -+{ -+#define LP_OWN_BACK_TOTAL_DELAY_MS 2000 /* exponential of 2 */ -+#define LP_OWN_BACK_LOOP_DELAY_MS 1 /* exponential of 2 */ -+#define LP_OWN_BACK_CLR_OWN_ITERATION 256 /* exponential of 2 */ -+ -+ BOOLEAN fgStatus = TRUE; -+ UINT_32 i, u4CurrTick; -+ UINT_32 u4RegValue = 0; -+ GL_HIF_INFO_T *HifInfo; -+ -+ ASSERT(prAdapter); -+ -+ if (prAdapter->fgIsFwOwn == FALSE) -+ return fgStatus; -+ -+ HifInfo = &prAdapter->prGlueInfo->rHifInfo; -+ -+ u4CurrTick = kalGetTimeTick(); -+ STATS_DRIVER_OWN_START_RECORD(); -+ i = 0; -+ -+ while (1) { -+ HAL_MCR_RD(prAdapter, MCR_WHLPCR, &u4RegValue); -+ -+ if (u4RegValue & WHLPCR_FW_OWN_REQ_SET) { -+ HAL_MCR_RD(prAdapter, MCR_D2HRM2R, &u4OriRegValue); -+ prAdapter->fgIsFwOwn = FALSE; -+ break; -+ } else if (kalIsCardRemoved(prAdapter->prGlueInfo) == TRUE -+ || fgIsBusAccessFailed == TRUE -+ || (kalGetTimeTick() - u4CurrTick) > LP_OWN_BACK_TOTAL_DELAY_MS || fgIsResetting == TRUE) { -+ /* ERRORLOG(("LP cannot be own back (for %ld ms)", kalGetTimeTick() - u4CurrTick)); */ -+ fgStatus = FALSE; -+ if (fgIsResetting != TRUE) { -+ UINT_32 u4FwCnt; -+ static unsigned int u4OwnCnt; -+ /* MCR_D2HRM2R: low 4 bit means interrupt times, -+ * high 4 bit means firmware response times. -+ * ORI_MCR_D2HRM2R: the last successful value. -+ * for example: -+ * MCR_D2HRM2R = 0x44, ORI_MCR_D2HRM2R = 0x44 -+ * means firmware no receive interrupt form hardware. -+ * MCR_D2HRM2R = 0x45, ORI_MCR_D2HRM2R = 0x44 -+ * means firmware no send response. -+ * MCR_D2HRM2R = 0x55, ORI_MCR_D2HRM2R = 0x44 -+ * means firmware send response, but driver no receive. */ -+ HAL_MCR_RD(prAdapter, MCR_D2HRM2R, &u4RegValue); -+ DBGLOG(NIC, WARN, " [1]MCR_D2HRM2R = 0x%x, ORI_MCR_D2HRM2R = 0x%x\n", -+ u4RegValue, u4OriRegValue); -+ -+ HAL_MCR_WR(prAdapter, MCR_WHLPCR, WHLPCR_FW_OWN_REQ_CLR); -+ HAL_MCR_RD(prAdapter, MCR_WHLPCR, &u4RegValue); -+ if (u4RegValue & WHLPCR_FW_OWN_REQ_SET) { -+ HAL_MCR_RD(prAdapter, MCR_D2HRM2R, &u4OriRegValue); -+ prAdapter->fgIsFwOwn = FALSE; -+ break; -+ } -+ HAL_MCR_RD(prAdapter, MCR_D2HRM2R, &u4RegValue); -+ DBGLOG(NIC, WARN, " [2]MCR_D2HRM2R = 0x%x, ORI_MCR_D2HRM2R = 0x%x\n", -+ u4RegValue, u4OriRegValue); -+ DBGLOG(NIC, WARN, -+ " Fatal error! Driver own fail!!!!!!!!!!!! %d, fgIsBusAccessFailed: %d\n", -+ u4OwnCnt++, fgIsBusAccessFailed); -+ -+ DBGLOG(NIC, WARN, "CONNSYS FW CPUINFO:\n"); -+ for (u4FwCnt = 0; u4FwCnt < 16; u4FwCnt++) -+ DBGLOG(NIC, WARN, "0x%08x ", MCU_REG_READL(HifInfo, CONN_MCU_CPUPCR)); -+ /* CONSYS_REG_READ(CONSYS_CPUPCR_REG) */ -+ kalSendAeeWarning("[Fatal error! Driver own fail!]", __func__); -+ glDoChipReset(); -+ } -+ break; -+ } -+ if ((i & (LP_OWN_BACK_CLR_OWN_ITERATION - 1)) == 0) { -+ /* Software get LP ownership - per 256 iterations */ -+ HAL_MCR_WR(prAdapter, MCR_WHLPCR, WHLPCR_FW_OWN_REQ_CLR); -+ } -+ -+ /* Delay for LP engine to complete its operation. */ -+ kalMsleep(LP_OWN_BACK_LOOP_DELAY_MS); -+ i++; -+ } -+ -+ STATS_DRIVER_OWN_END_RECORD(); -+ STATS_DRIVER_OWN_STOP(); -+ -+ return fgStatus; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is used to set ACPI power mode to D0. -+* -+* \param[in] pvAdapter Pointer to the Adapter structure. -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN nicpmSetAcpiPowerD0(IN P_ADAPTER_T prAdapter) -+{ -+ WLAN_STATUS u4Status = WLAN_STATUS_SUCCESS; -+ UINT_32 u4Value = 0, u4WHISR = 0; -+ UINT_8 aucTxCount[8]; -+ UINT_32 i; -+#if CFG_ENABLE_FW_DOWNLOAD -+ UINT_32 u4FwImgLength, u4FwLoadAddr, u4ImgSecSize; -+ PVOID prFwMappingHandle; -+ PVOID pvFwImageMapFile = NULL; -+#if CFG_ENABLE_FW_DIVIDED_DOWNLOAD -+ UINT_32 j; -+ P_FIRMWARE_DIVIDED_DOWNLOAD_T prFwHead; -+ BOOLEAN fgValidHead; -+ const UINT_32 u4CRCOffset = offsetof(FIRMWARE_DIVIDED_DOWNLOAD_T, u4NumOfEntries); -+#endif -+#endif -+ -+ DEBUGFUNC("nicpmSetAcpiPowerD0"); -+ ASSERT(prAdapter); -+ -+ do { -+ /* 0. Reset variables in ADAPTER_T */ -+ prAdapter->fgIsFwOwn = TRUE; -+ prAdapter->fgWiFiInSleepyState = FALSE; -+ prAdapter->rAcpiState = ACPI_STATE_D0; -+ prAdapter->fgIsEnterD3ReqIssued = FALSE; -+ -+ /* 1. Request Ownership to enter F/W download state */ -+ ACQUIRE_POWER_CONTROL_FROM_PM(prAdapter); -+#if !CFG_ENABLE_FULL_PM -+ nicpmSetDriverOwn(prAdapter); -+#endif -+ -+ /* 2. Initialize the Adapter */ -+ u4Status = nicInitializeAdapter(prAdapter); -+ if (u4Status != WLAN_STATUS_SUCCESS) { -+ DBGLOG(NIC, ERROR, "nicInitializeAdapter failed!\n"); -+ u4Status = WLAN_STATUS_FAILURE; -+ break; -+ } -+ -+#if CFG_ENABLE_FW_DOWNLOAD -+ prFwMappingHandle = kalFirmwareImageMapping(prAdapter->prGlueInfo, &pvFwImageMapFile, &u4FwImgLength); -+ if (!prFwMappingHandle) { -+ DBGLOG(NIC, ERROR, "Fail to load FW image from file!\n"); -+ pvFwImageMapFile = NULL; -+ } -+ -+ if (pvFwImageMapFile == NULL) { -+ u4Status = WLAN_STATUS_FAILURE; -+ break; -+ } -+ -+ /* 3.1 disable interrupt, download is done by polling mode only */ -+ nicDisableInterrupt(prAdapter); -+ -+ /* 3.2 Initialize Tx Resource to fw download state */ -+ nicTxInitResetResource(prAdapter); -+ -+ /* 3.3 FW download here */ -+ u4FwLoadAddr = kalGetFwLoadAddress(prAdapter->prGlueInfo); -+ -+#if CFG_ENABLE_FW_DIVIDED_DOWNLOAD -+ /* 3a. parse file header for decision of divided firmware download or not */ -+ prFwHead = (P_FIRMWARE_DIVIDED_DOWNLOAD_T) pvFwImageMapFile; -+ -+ if (prFwHead->u4Signature == MTK_WIFI_SIGNATURE && -+ prFwHead->u4CRC == wlanCRC32((PUINT_8) pvFwImageMapFile + u4CRCOffset, -+ u4FwImgLength - u4CRCOffset)) { -+ fgValidHead = TRUE; -+ } else { -+ fgValidHead = FALSE; -+ } -+ -+ /* 3b. engage divided firmware downloading */ -+ if (fgValidHead == TRUE) { -+ for (i = 0; i < prFwHead->u4NumOfEntries; i++) { -+#if CFG_ENABLE_FW_DOWNLOAD_AGGREGATION -+ if (wlanImageSectionDownloadAggregated(prAdapter, -+ prFwHead->arSection[i].u4DestAddr, -+ prFwHead->arSection[i].u4Length, -+ (PUINT_8) pvFwImageMapFile + -+ prFwHead->arSection[i].u4Offset) != -+ WLAN_STATUS_SUCCESS) { -+ DBGLOG(NIC, ERROR, "Firmware scatter download failed!\n"); -+ u4Status = WLAN_STATUS_FAILURE; -+ } -+#else -+ for (j = 0; j < prFwHead->arSection[i].u4Length; j += CMD_PKT_SIZE_FOR_IMAGE) { -+ if (j + CMD_PKT_SIZE_FOR_IMAGE < prFwHead->arSection[i].u4Length) -+ u4ImgSecSize = CMD_PKT_SIZE_FOR_IMAGE; -+ else -+ u4ImgSecSize = prFwHead->arSection[i].u4Length - j; -+ -+ if (wlanImageSectionDownload(prAdapter, -+ prFwHead->arSection[i].u4DestAddr + j, -+ u4ImgSecSize, -+ (PUINT_8) pvFwImageMapFile + -+ prFwHead->arSection[i].u4Offset + j) != WLAN_STATUS_SUCCESS) { -+ DBGLOG(NIC, ERROR, "Firmware scatter download failed!\n"); -+ u4Status = WLAN_STATUS_FAILURE; -+ break; -+ } -+ } -+#endif -+ /* escape from loop if any pending error occurs */ -+ if (u4Status == WLAN_STATUS_FAILURE) -+ break; -+ } -+ } else -+#endif -+#if CFG_ENABLE_FW_DOWNLOAD_AGGREGATION -+ if (wlanImageSectionDownloadAggregated(prAdapter, -+ u4FwLoadAddr, -+ u4FwImgLength, -+ (PUINT_8) pvFwImageMapFile) != WLAN_STATUS_SUCCESS) { -+ DBGLOG(NIC, ERROR, "Firmware scatter download failed!\n"); -+ u4Status = WLAN_STATUS_FAILURE; -+ } -+#else -+ for (i = 0; i < u4FwImgLength; i += CMD_PKT_SIZE_FOR_IMAGE) { -+ if (i + CMD_PKT_SIZE_FOR_IMAGE < u4FwImgLength) -+ u4ImgSecSize = CMD_PKT_SIZE_FOR_IMAGE; -+ else -+ u4ImgSecSize = u4FwImgLength - i; -+ -+ if (wlanImageSectionDownload(prAdapter, -+ u4FwLoadAddr + i, -+ u4ImgSecSize, -+ (PUINT_8) pvFwImageMapFile + i) != WLAN_STATUS_SUCCESS) { -+ DBGLOG(NIC, ERROR, "wlanImageSectionDownload failed!\n"); -+ u4Status = WLAN_STATUS_FAILURE; -+ break; -+ } -+ } -+#endif -+ -+ if (u4Status != WLAN_STATUS_SUCCESS) { -+ kalFirmwareImageUnmapping(prAdapter->prGlueInfo, prFwMappingHandle, pvFwImageMapFile); -+ break; -+ } -+#if !CFG_ENABLE_FW_DOWNLOAD_ACK -+ /* Send INIT_CMD_ID_QUERY_PENDING_ERROR command and wait for response */ -+ if (wlanImageQueryStatus(prAdapter) != WLAN_STATUS_SUCCESS) { -+ kalFirmwareImageUnmapping(prAdapter->prGlueInfo, prFwMappingHandle, pvFwImageMapFile); -+ u4Status = WLAN_STATUS_FAILURE; -+ break; -+ } -+#endif -+ kalFirmwareImageUnmapping(prAdapter->prGlueInfo, prFwMappingHandle, pvFwImageMapFile); -+ -+ /* 4. send Wi-Fi Start command */ -+#if CFG_OVERRIDE_FW_START_ADDRESS -+ wlanConfigWifiFunc(prAdapter, TRUE, kalGetFwStartAddress(prAdapter->prGlueInfo)); -+#else -+ wlanConfigWifiFunc(prAdapter, FALSE, 0); -+#endif -+#endif /* if CFG_ENABLE_FW_DOWNLOAD */ -+ -+ /* 5. check Wi-Fi FW asserts ready bit */ -+ DBGLOG(NIC, TRACE, "wlanAdapterStart(): Waiting for Ready bit..\n"); -+ i = 0; -+ while (1) { -+ HAL_MCR_RD(prAdapter, MCR_WCIR, &u4Value); -+ -+ if (u4Value & WCIR_WLAN_READY) { -+ DBGLOG(NIC, TRACE, "Ready bit asserted\n"); -+ break; -+ } else if (kalIsCardRemoved(prAdapter->prGlueInfo) == TRUE || fgIsBusAccessFailed == TRUE) { -+ u4Status = WLAN_STATUS_FAILURE; -+ break; -+ } else if (i >= CFG_RESPONSE_POLLING_TIMEOUT) { -+ DBGLOG(NIC, ERROR, "Waiting for Ready bit: Timeout\n"); -+ u4Status = WLAN_STATUS_FAILURE; -+ break; -+ } -+ i++; -+ kalMsleep(10); -+ } -+ -+ if (u4Status == WLAN_STATUS_SUCCESS) { -+ /* 6.1 reset interrupt status */ -+ HAL_READ_INTR_STATUS(prAdapter, 4, (PUINT_8)(&u4WHISR)); -+ if (HAL_IS_TX_DONE_INTR(u4WHISR)) -+ HAL_READ_TX_RELEASED_COUNT(prAdapter, aucTxCount); -+ -+ /* 6.2 reset TX Resource for normal operation */ -+ nicTxResetResource(prAdapter); -+ -+ /* 6.3 Enable interrupt */ -+ nicEnableInterrupt(prAdapter); -+ -+ /* 6.4 Override network address */ -+ wlanUpdateNetworkAddress(prAdapter); -+ -+ /* 6.5 indicate disconnection as default status */ -+ kalIndicateStatusAndComplete(prAdapter->prGlueInfo, WLAN_STATUS_MEDIA_DISCONNECT, NULL, 0); -+ } -+ -+ RECLAIM_POWER_CONTROL_TO_PM(prAdapter, FALSE); -+ -+ /* MGMT Initialization */ -+ nicInitMGMT(prAdapter, NULL); -+ -+ } while (FALSE); -+ -+ if (u4Status != WLAN_STATUS_SUCCESS) -+ return FALSE; -+ else -+ return TRUE; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This routine is used to set ACPI power mode to D3. -+* -+* @param prAdapter pointer to the Adapter handler -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN nicpmSetAcpiPowerD3(IN P_ADAPTER_T prAdapter) -+{ -+ UINT_32 i; -+ -+ ASSERT(prAdapter); -+ -+ /* 1. MGMT - unitialization */ -+ nicUninitMGMT(prAdapter); -+ -+ /* 2. Disable Interrupt */ -+ nicDisableInterrupt(prAdapter); -+ -+ /* 3. emit CMD_NIC_POWER_CTRL command packet */ -+ wlanSendNicPowerCtrlCmd(prAdapter, 1); -+ -+ /* 4. Clear Interrupt Status */ -+ i = 0; -+ while (i < CFG_IST_LOOP_COUNT && nicProcessIST(prAdapter) != WLAN_STATUS_NOT_INDICATING) { -+ i++; -+ }; -+ -+ /* 5. Remove pending TX */ -+ nicTxRelease(prAdapter); -+ -+ /* 5.1 clear pending Security / Management Frames */ -+ kalClearSecurityFrames(prAdapter->prGlueInfo); -+ kalClearMgmtFrames(prAdapter->prGlueInfo); -+ -+ /* 5.2 clear pending TX packet queued in glue layer */ -+ kalFlushPendingTxPackets(prAdapter->prGlueInfo); -+ -+ /* 6. Set Onwership to F/W */ -+ nicpmSetFWOwn(prAdapter, FALSE); -+ -+ /* 7. Set variables */ -+ prAdapter->rAcpiState = ACPI_STATE_D3; -+ -+ return TRUE; -+} -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic_rx.c b/drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic_rx.c -new file mode 100644 -index 000000000000..ba4840414da8 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic_rx.c -@@ -0,0 +1,3782 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/nic/nic_rx.c#3 -+*/ -+ -+/*! \file nic_rx.c -+ \brief Functions that provide many rx-related functions -+ -+ This file includes the functions used to process RFB and dispatch RFBs to -+ the appropriate related rx functions for protocols. -+*/ -+ -+/* -+** Log: nic_rx.c -+** -+** 08 31 2012 yuche.tsai -+** [ALPS00349585] [6577JB][WiFi direct][KE]Establish p2p connection while both device have connected to AP previously, -+** one device reboots automatically with KE -+** Fix possible KE when concurrent & disconnect. -+ * -+ * 07 17 2012 yuche.tsai -+ * NULL -+ * Let netdev bring up. -+ * -+ * 07 17 2012 yuche.tsai -+ * NULL -+ * Compile no error before trial run. -+ * -+ * 03 02 2012 terry.wu -+ * NULL -+ * Sync CFG80211 modification from branch 2,2. -+ * -+ * 02 14 2012 cp.wu -+ * NULL -+ * remove another assertion by error message dump -+ * -+ * 01 05 2012 tsaiyuan.hsu -+ * [WCXRP00001157] [MT6620 Wi-Fi][FW][DRV] add timing measurement support for 802.11v -+ * add timing measurement support for 802.11v. -+ * -+ * 11 19 2011 yuche.tsai -+ * NULL -+ * Update RSSI for P2P. -+ * -+ * 11 18 2011 yuche.tsai -+ * NULL -+ * CONFIG P2P support RSSI query, default turned off. -+ * -+ * 11 17 2011 tsaiyuan.hsu -+ * [WCXRP00001115] [MT6620 Wi-Fi][DRV] avoid deactivating staRec when changing state 3 to 3. -+ * avoid deactivating staRec when changing state from 3 to 3. -+ * -+ * 11 11 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * modify the xlog related code. -+ * -+ * 11 10 2011 eddie.chen -+ * [WCXRP00001096] [MT6620 Wi-Fi][Driver/FW] Enhance the log function (xlog) -+ * Modify the QM xlog level and remove LOG_FUNC. -+ * -+ * 11 09 2011 eddie.chen -+ * [WCXRP00001096] [MT6620 Wi-Fi][Driver/FW] Enhance the log function (xlog) -+ * Add xlog for beacon timeout and sta aging timeout. -+ * -+ * 11 08 2011 eddie.chen -+ * [WCXRP00001096] [MT6620 Wi-Fi][Driver/FW] Enhance the log function (xlog) -+ * Add xlog function. -+ * -+ * 11 07 2011 tsaiyuan.hsu -+ * [WCXRP00001083] [MT6620 Wi-Fi][DRV]] dump debug counter or frames when debugging is triggered -+ * add debug counters and periodically dump counters for debugging. -+ * -+ * 10 21 2011 eddie.chen -+ * [WCXRP00001051] [MT6620 Wi-Fi][Driver/Fw] Adjust the STA aging timeout -+ * Add switch to ignore the STA aging timeout. -+ * -+ * 10 12 2011 wh.su -+ * [WCXRP00001036] [MT6620 Wi-Fi][Driver][FW] Adding the 802.11w code for MFP -+ * adding the 802.11w related function and define . -+ * -+ * 08 26 2011 cp.wu -+ * [WCXRP00000958] [MT6620 Wi-Fi][Driver] Extend polling timeout from 25ms to 1sec due to RF calibration might took -+ * up to 600ms -+ * extend polling RX response timeout period from 25ms to 1000ms. -+ * -+ * 08 11 2011 cp.wu -+ * [WCXRP00000830] [MT6620 Wi-Fi][Firmware] Use MDRDY counter to detect empty channel for shortening scan time -+ * sparse channel detection: -+ * driver: collect sparse channel information with scan-done event -+ * -+ * 07 28 2011 chinghwa.yu -+ * [WCXRP00000063] Update BCM CoEx design and settings -+ * Add BWCS cmd and event. -+ * -+ * 07 27 2011 cp.wu -+ * [WCXRP00000876] [MT5931][Drver] Decide to retain according to currently available RX counter and QUE_MGT used count -+ * correct comment. -+ * -+ * 07 27 2011 cp.wu -+ * [WCXRP00000876] [MT5931][Drver] Decide to retain according to currently available RX counter and QUE_MGT used count -+ * take use of QUE_MGT exported function to estimate currently RX buffer usage count. -+ * -+ * 07 18 2011 chinghwa.yu -+ * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm -+ * Add CMD/Event for RDD and BWCS. -+ * -+ * 06 09 2011 tsaiyuan.hsu -+ * [WCXRP00000760] [MT5931 Wi-Fi][FW] Refine rxmHandleMacRxDone to reduce code size -+ * move send_auth at rxmHandleMacRxDone in firmware to driver to reduce code size. -+ * -+ * 05 11 2011 eddie.chen -+ * [WCXRP00000709] [MT6620 Wi-Fi][Driver] Check free number before copying broadcast packet -+ * Fix dest type when GO packet copying. -+ * -+ * 05 09 2011 eddie.chen -+ * [WCXRP00000709] [MT6620 Wi-Fi][Driver] Check free number before copying broadcast packet -+ * Check free number before copying broadcast packet. -+ * -+ * 05 05 2011 cp.wu -+ * [WCXRP00000702] [MT5931][Driver] Modify initialization sequence for E1 ASIC -+ * add delay after whole-chip resetting for MT5931 E1 ASIC. -+ * -+ * 04 18 2011 terry.wu -+ * [WCXRP00000660] [MT6620 Wi-Fi][Driver] Remove flag CFG_WIFI_DIRECT_MOVED -+ * Remove flag CFG_WIFI_DIRECT_MOVED. -+ * -+ * 04 12 2011 cm.chang -+ * [WCXRP00000634] [MT6620 Wi-Fi][Driver][FW] 2nd BSS will not support 40MHz bandwidth for concurrency -+ * . -+ * -+ * 04 08 2011 yuche.tsai -+ * [WCXRP00000624] [Volunteer Patch][MT6620][Driver] Add device discoverability support for GO. -+ * Add device discoverability support for GO. -+ * -+ * 04 01 2011 tsaiyuan.hsu -+ * [WCXRP00000615] [MT 6620 Wi-Fi][Driver] Fix klocwork issues -+ * fix the klocwork issues, 57500, 57501, 57502 and 57503. -+ * -+ * 03 19 2011 yuche.tsai -+ * [WCXRP00000584] [Volunteer Patch][MT6620][Driver] Add beacon timeout support for WiFi Direct. -+ * Add beacon timeout support for WiFi Direct Network. -+ * -+ * 03 18 2011 wh.su -+ * [WCXRP00000530] [MT6620 Wi-Fi] [Driver] skip doing p2pRunEventAAAComplete after send assoc response Tx Done -+ * enable the Anti_piracy check at driver . -+ * -+ * 03 17 2011 cp.wu -+ * [WCXRP00000562] [MT6620 Wi-Fi][Driver] I/O buffer pre-allocation to avoid physically continuous memory shortage -+ * after system running for a long period -+ * use pre-allocated buffer for storing enhanced interrupt response as well -+ * -+ * 03 15 2011 cp.wu -+ * [WCXRP00000559] [MT6620 Wi-Fi][Driver] Combine TX/RX DMA buffers into a single one to reduce physically continuous -+ * memory consumption -+ * 1. deprecate CFG_HANDLE_IST_IN_SDIO_CALLBACK -+ * 2. Use common coalescing buffer for both TX/RX directions -+ * -+ * -+ * 03 07 2011 wh.su -+ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code -+ * rename the define to anti_pviracy. -+ * -+ * 03 05 2011 wh.su -+ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code -+ * add the code to get the check rsponse and indicate to app. -+ * -+ * 03 02 2011 wh.su -+ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code -+ * Add security check code. -+ * -+ * 03 02 2011 cp.wu -+ * [WCXRP00000503] [MT6620 Wi-Fi][Driver] Take RCPI brought by association response as initial RSSI right after -+ * connection is built. -+ * use RCPI brought by ASSOC-RESP after connection is built as initial RCPI to avoid using a uninitialized MAC-RX RCPI. -+ * -+ * 02 10 2011 yuche.tsai -+ * [WCXRP00000419] [Volunteer Patch][MT6620/MT5931][Driver] Provide function of disconnect to target station for AAA -+ * module. -+ * Remove Station Record after Aging timeout. -+ * -+ * 02 10 2011 cp.wu -+ * [WCXRP00000434] [MT6620 Wi-Fi][Driver] Obsolete unused event packet handlers -+ * EVENT_ID_CONNECTION_STATUS has been obsoleted and no need to handle. -+ * -+ * 02 09 2011 yuche.tsai -+ * [WCXRP00000431] [Volunteer Patch][MT6620][Driver] Add MLME support for deauthentication under AP(Hot-Spot) mode. -+ * Add MLME deauthentication support for Hot-Spot mode. -+ * -+ * 02 09 2011 eddie.chen -+ * [WCXRP00000426] [MT6620 Wi-Fi][FW/Driver] Add STA aging timeout and defualtHwRatein AP mode -+ * Adjust variable order. -+ * -+ * 02 08 2011 eddie.chen -+ * [WCXRP00000426] [MT6620 Wi-Fi][FW/Driver] Add STA aging timeout and defualtHwRatein AP mode -+ * Add event STA agint timeout -+ * -+ * 01 27 2011 tsaiyuan.hsu -+ * [WCXRP00000392] [MT6620 Wi-Fi][Driver] Add Roaming Support -+ * add roaming fsm -+ * 1. not support 11r, only use strength of signal to determine roaming. -+ * 2. not enable CFG_SUPPORT_ROAMING until completion of full test. -+ * 3. in 6620, adopt work-around to avoid sign extension problem of cck of hw -+ * 4. assume that change of link quality in smooth way. -+ * -+ * 01 26 2011 cm.chang -+ * [WCXRP00000395] [MT6620 Wi-Fi][Driver][FW] Search STA_REC with additional net type index argument -+ * . -+ * -+ * 01 24 2011 eddie.chen -+ * [WCXRP00000385] [MT6620 Wi-Fi][DRV] Add destination decision for forwarding packets -+ * Remove comments. -+ * -+ * 01 24 2011 eddie.chen -+ * [WCXRP00000385] [MT6620 Wi-Fi][DRV] Add destination decision for forwarding packets -+ * Add destination decision in AP mode. -+ * -+ * 01 24 2011 cm.chang -+ * [WCXRP00000384] [MT6620 Wi-Fi][Driver][FW] Handle 20/40 action frame in AP mode and stop ampdu timer when sta_rec -+ * is freed -+ * Process received 20/40 coexistence action frame for AP mode -+ * -+ * 01 24 2011 cp.wu -+ * [WCXRP00000382] [MT6620 Wi-Fi][Driver] Track forwarding packet number with notifying tx thread for serving -+ * 1. add an extra counter for tracking pending forward frames. -+ * 2. notify TX service thread as well when there is pending forward frame -+ * 3. correct build errors leaded by introduction of Wi-Fi direct separation module -+ * -+ * 01 12 2011 cp.wu -+ * [WCXRP00000357] [MT6620 Wi-Fi][Driver][Bluetooth over Wi-Fi] add another net device interface for BT AMP -+ * implementation of separate BT_OVER_WIFI data path. -+ * -+ * 12 29 2010 eddie.chen -+ * [WCXRP00000322] Add WMM IE in beacon, -+Add per station flow control when STA is in PS -+ -+ * 1) PS flow control event -+ * -+ * 2) WMM IE in beacon, assoc resp, probe resp -+ * -+ * 12 15 2010 george.huang -+ * [WCXRP00000152] [MT6620 Wi-Fi] AP mode power saving function -+ * update beacon for NoA -+ * -+ * 11 01 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000150] [MT6620 Wi-Fi][Driver] -+ * Add implementation for querying current TX rate from firmware auto rate module -+ * 1) Query link speed (TX rate) from firmware directly with buffering mechanism to reduce overhead -+ * 2) Remove CNM CH-RECOVER event handling -+ * 3) cfg read/write API renamed with kal prefix for unified naming rules. -+ * -+ * 10 27 2010 george.huang -+ * [WCXRP00000127] [MT6620 Wi-Fi][Driver] Add a registry to disable Beacon Timeout function for SQA test by using E1 EVB -+ * Support registry option for disable beacon lost detection. -+ * -+ * 10 20 2010 wh.su -+ * NULL -+ * add a cmd to reset the p2p key -+ * -+ * 10 20 2010 wh.su -+ * [WCXRP00000124] [MT6620 Wi-Fi] [Driver] Support the dissolve P2P Group -+ * Add the code to support disconnect p2p group -+ * -+ * 09 29 2010 wh.su -+ * [WCXRP00000072] [MT6620 Wi-Fi][Driver] Fix TKIP Counter Measure EAPoL callback register issue -+ * fixed compilier error. -+ * -+ * 09 29 2010 wh.su -+ * [WCXRP00000072] [MT6620 Wi-Fi][Driver] Fix TKIP Counter Measure EAPoL callback register issue -+ * [MT6620 Wi-Fi][Driver] Fix TKIP Counter Measure EAPoL callback register issue. -+ * -+ * 09 23 2010 cp.wu -+ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning -+ * eliminate reference of CFG_RESPONSE_MAX_PKT_SIZE -+ * -+ * 09 21 2010 cp.wu -+ * [WCXRP00000053] [MT6620 Wi-Fi][Driver] Reset incomplete and might leads to BSOD when entering RF test with AIS -+ * associated -+ * release RX packet to packet pool when in RF test mode -+ * -+ * 09 21 2010 cp.wu -+ * [WCXRP00000053] [MT6620 Wi-Fi][Driver] Reset incomplete and might leads to BSOD when entering RF test with AIS -+ @ associated -+ * Do a complete reset with STA-REC null checking for RF test re-entry -+ * -+ * 09 08 2010 cp.wu -+ * NULL -+ * use static memory pool for storing IEs of scanning result. -+ * -+ * 09 07 2010 yuche.tsai -+ * NULL -+ * Add a common buffer, store the IE of a P2P device in this common buffer. -+ * -+ * 09 03 2010 kevin.huang -+ * NULL -+ * Refine #include sequence and solve recursive/nested #include issue -+ * -+ * 08 31 2010 kevin.huang -+ * NULL -+ * Use LINK LIST operation to process SCAN result -+ * -+ * 08 30 2010 cp.wu -+ * NULL -+ * eliminate klockwork errors -+ * -+ * 08 20 2010 cm.chang -+ * NULL -+ * Migrate RLM code to host from FW -+ * -+ * 08 20 2010 yuche.tsai -+ * NULL -+ * When enable WiFi Direct function, check each packet to tell which interface to indicate. -+ * -+ * 08 05 2010 yuche.tsai -+ * NULL -+ * Add P2P Device Discovery Function. -+ * -+ * 08 03 2010 cp.wu -+ * NULL -+ * surpress compilation warning. -+ * -+ * 08 03 2010 george.huang -+ * NULL -+ * handle event for updating NOA parameters indicated from FW -+ * -+ * 08 02 2010 yuche.tsai -+ * NULL -+ * Add support API for RX public action frame. -+ * -+ * 08 02 2010 jeffrey.chang -+ * NULL -+ * 1) modify tx service thread to avoid busy looping -+ * 2) add spin lock declartion for linux build -+ * -+ * 07 30 2010 cp.wu -+ * NULL -+ * 1) BoW wrapper: use definitions instead of hard-coded constant for error code -+ * 2) AIS-FSM: eliminate use of desired RF parameters, use prTargetBssDesc instead -+ * 3) add handling for RX_PKT_DESTINATION_HOST_WITH_FORWARD for GO-broadcast frames -+ * -+ * 07 26 2010 yuche.tsai -+ * -+ * Update Device Capability Bitmap & Group Capability Bitmap from 16 bits to 8 bits. -+ * -+ * 07 24 2010 wh.su -+ * -+ * .support the Wi-Fi RSN -+ * -+ * 07 23 2010 cp.wu -+ * -+ * add AIS-FSM handling for beacon timeout event. -+ * -+ * 07 21 2010 yuche.tsai -+ * -+ * Add P2P Scan & Scan Result Parsing & Saving. -+ * -+ * 07 19 2010 cm.chang -+ * -+ * Set RLM parameters and enable CNM channel manager -+ * -+ * 07 19 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration. -+ * Add Ad-Hoc support to AIS-FSM -+ * -+ * 07 19 2010 jeffrey.chang -+ * -+ * Linux port modification -+ * -+ * 07 16 2010 yarco.yang -+ * -+ * 1. Support BSS Absence/Presence Event -+ * 2. Support STA change PS mode Event -+ * 3. Support BMC forwarding for AP mode. -+ * -+ * 07 15 2010 cp.wu -+ * -+ * sync. bluetooth-over-Wi-Fi interface to driver interface document v0.2.6. -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 07 07 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * fill ucStaRecIdx into SW_RFB_T. -+ * -+ * 07 02 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) for event packet, no need to fill RFB. -+ * 2) when wlanAdapterStart() failed, no need to initialize state machines -+ * 3) after Beacon/ProbeResp parsing, corresponding BSS_DESC_T should be marked as IE-parsed -+ * -+ * 07 01 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * implementation of DRV-SCN and related mailbox message handling. -+ * -+ * 06 29 2010 yarco.yang -+ * [WPD00003837][MT6620]Data Path Refine -+ * replace g_rQM with Adpater->rQM -+ * -+ * 06 23 2010 yarco.yang -+ * [WPD00003837][MT6620]Data Path Refine -+ * Merge g_arStaRec[] into adapter->arStaRec[] -+ * -+ * 06 22 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) add command warpper for STA-REC/BSS-INFO sync. -+ * 2) enhance command packet sending procedure for non-oid part -+ * 3) add command packet definitions for STA-REC/BSS-INFO sync. -+ * -+ * 06 21 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * refine TX-DONE callback. -+ * -+ * 06 21 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * implement TX_DONE callback path. -+ * -+ * 06 21 2010 yarco.yang -+ * [WPD00003837][MT6620]Data Path Refine -+ * Add TX Done Event handle entry -+ * -+ * 06 21 2010 wh.su -+ * [WPD00003840][MT6620 5931] Security migration -+ * remove duplicate variable for migration. -+ * -+ * 06 15 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * . -+ * -+ * 06 15 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * . -+ * -+ * 06 14 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * saa_fsm.c is migrated. -+ * -+ * 06 14 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add management dispatching function table. -+ * -+ * 06 11 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) migrate assoc.c. -+ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness -+ * 3) add configuration options for CNM_MEM and RSN modules -+ * 4) add data path for management frames -+ * 5) eliminate rPacketInfo of MSDU_INFO_T -+ * -+ * 06 10 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) eliminate CFG_CMD_EVENT_VERSION_0_9 -+ * 2) when disconnected, indicate nic directly (no event is needed) -+ * -+ * 06 08 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * cnm_timer has been migrated. -+ * -+ * 06 07 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * merge wlan_def.h. -+ * -+ * 06 07 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * sync with MT6620 driver for scan result replacement policy -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 05 20 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) integrate OID_GEN_NETWORK_LAYER_ADDRESSES with CMD_ID_SET_IP_ADDRESS -+ * 2) buffer statistics data for 2 seconds -+ * 3) use default value for adhoc parameters instead of 0 -+ * -+ * 05 19 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) do not take timeout mechanism for power mode oids -+ * 2) retrieve network type from connection status -+ * 3) after disassciation, set radio state to off -+ * 4) TCP option over IPv6 is supported -+ * -+ * 04 29 2010 wh.su -+ * [WPD00003816][MT6620 Wi-Fi] Adding the security support -+ * fixing the PMKID candicate indicate code. -+ * -+ * 04 28 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * change prefix for data structure used to communicate with 802.11 PAL -+ * to avoid ambiguous naming with firmware interface -+ * -+ * 04 27 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * basic implementation for EVENT_BT_OVER_WIFI -+ * -+ * 04 23 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * surpress compiler warning -+ * -+ * 04 22 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * -+ * 1) modify rx path code for supporting Wi-Fi direct -+ * 2) modify config.h since Linux dont need to consider retaining packet -+ * -+ * 04 16 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * treat BUS access failure as kind of card removal. -+ * -+ * 04 14 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * nicRxProcessEvent packet doesn't access spin-lock directly from now on. -+ * -+ * 04 14 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * do not need to release the spin lock due to it is done inside nicGetPendingCmdInfo() -+ * -+ * 04 13 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * add framework for BT-over-Wi-Fi support. -+ * * * * * * * * * * * * * * * 1) prPendingCmdInfo is replaced by queue for multiple handler capability -+ * * * * * * * * * * * * * * * 2) command sequence number is now increased atomically -+ * * * * * * * * * * * * * * * 3) private data could be hold and taken use for other purpose -+ * -+ * 04 12 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * add channel frequency <-> number conversion -+ * -+ * 04 09 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * 1) add spinlock -+ * 2) add KAPI for handling association info -+ * -+ * 04 07 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * rWlanInfo should be placed at adapter rather than glue due to most operations -+ * * * * * are done in adapter layer. -+ * -+ * 04 07 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * eliminate direct access to prGlueInfo->eParamMediaStateIndicated from non-glue layer -+ * -+ * 04 06 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * eliminate direct access for prGlueInfo->fgIsCardRemoved in non-glue layer -+ * -+ * 04 01 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * improve Linux supplicant compliance -+ * -+ * 03 31 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * fix ioctl which may cause cmdinfo memory leak -+ * -+ * 03 30 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * remove driver-land statistics. -+ * -+ * 03 29 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * improve none-glue code portability -+ * -+ * 03 28 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * rWlanInfo is modified before data is indicated to OS -+ * -+ * 03 28 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * rWlanInfo is modified before data is indicated to OS -+ * -+ * 03 26 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * add a temporary flag for integration with CMD/EVENT v0.9. -+ * -+ * 03 25 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) correct OID_802_11_CONFIGURATION with frequency setting behavior. -+ * * * the frequency is used for adhoc connection only -+ * * * 2) update with SD1 v0.9 CMD/EVENT documentation -+ * -+ * 03 24 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * initial import for Linux port -+ * -+ * 03 24 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * . -+ * -+ * 03 24 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * generate information for OID_GEN_RCV_OK & OID_GEN_XMIT_OK -+ * * * * -+ * -+ * 03 19 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) add ACPI D0/D3 state switching support -+ * * * * * * * * * 2) use more formal way to handle interrupt when the status is retrieved from enhanced RX -+ * response -+ * -+ * 03 15 2010 kevin.huang -+ * [WPD00003820][MT6620 Wi-Fi] Modify the code for meet the WHQL test -+ * Add event for activate STA_RECORD_T -+ * -+ * 03 12 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * correct fgSetQuery/fgNeedResp check -+ * -+ * 03 11 2010 cp.wu -+ * [WPD00003821][BUG] Host driver stops processing RX packets from HIF RX0 -+ * add RX starvation warning debug message controlled by CFG_HIF_RX_STARVATION_WARNING -+ * -+ * 03 10 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * code clean: removing unused variables and structure definitions -+ * -+ * 03 08 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) add another spin-lock to protect MsduInfoList due to it might be accessed by different thread. -+ * * * 2) change own-back acquiring procedure to wait for up to 16.67 seconds -+ * -+ * 03 02 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) the use of prPendingOid revised, all accessing are now protected by spin lock -+ * * * * 2) ensure wlanReleasePendingOid will clear all command queues -+ * -+ * 03 02 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * add mutex to avoid multiple access to qmTxQueue simultaneously. -+ * -+ * 02 26 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * move EVENT_ID_ASSOC_INFO from nic_rx.c to gl_kal_ndis_51.c -+ * * 'cause it involves OS dependent data structure handling -+ * -+ * 02 25 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * correct behavior to prevent duplicated RX handling for RX0_DONE and RX1_DONE -+ * -+ * 02 24 2010 tehuang.liu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * Updated API interfaces for qmHandleEventRxAddBa() and qmHandleEventRxDelBa() -+ * -+ * 02 10 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * implement host-side firmware download logic -+ * -+ * 02 10 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) remove unused function in nic_rx.c [which has been handled in que_mgt.c] -+ * * * * * 2) firmware image length is now retrieved via NdisFileOpen -+ * * * * * 3) firmware image is not structured by (P_IMG_SEC_HDR_T) anymore -+ * * * * * 4) nicRxWaitResponse() revised -+ * * * * * 5) another set of TQ counter default value is added for fw-download state -+ * * * * * 6) Wi-Fi load address is now retrieved from registry too -+ * -+ * 02 09 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1. Permanent and current MAC address are now retrieved by CMD/EVENT packets instead of hard-coded address -+ * * * * * * * * 2. follow MSDN defined behavior when associates to another AP -+ * * * * * * * * 3. for firmware download, packet size could be up to 2048 bytes -+ * -+ * 01 27 2010 wh.su -+ * [WPD00003816][MT6620 Wi-Fi] Adding the security support -+ * . -+ * -+ * 01 22 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * implement following 802.11 OIDs: -+ * * * * * * OID_802_11_RSSI, -+ * * * * * * OID_802_11_RSSI_TRIGGER, -+ * * * * * * OID_802_11_STATISTICS, -+ * * * * * * OID_802_11_DISASSOCIATE, -+ * * * * * * OID_802_11_POWER_MODE -+ * -+ * 12 30 2009 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) According to CMD/EVENT documentation v0.8, -+ * * * * * * * * * OID_CUSTOM_TEST_RX_STATUS & OID_CUSTOM_TEST_TX_STATUS is no longer used, -+ * * * * * * * * * and result is retrieved by get ATInfo instead -+ * * * * * * * * * 2) add 4 counter for recording aggregation statistics -+ * -+ * 12 23 2009 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * add a precheck: if free sw rfb is not enough, do not invoke read transactionu1rwduu`wvpghlqg|fu+rp -+ * -+ * 12 22 2009 cp.wu -+ * [WPD00003809][Bug] Host driver will crash when processing reordered MSDUs -+ * The root cause is pointer accessing by mistake. After dequeued from reordering-buffer, handling logic should access -+ * returned pointer instead of pointer which has been passed in before. -+** \main\maintrunk.MT6620WiFiDriver_Prj\58 2009-12-17 13:40:33 GMT mtk02752 -+** always update prAdapter->rSDIOCtrl when enhanced response is read by RX -+** \main\maintrunk.MT6620WiFiDriver_Prj\57 2009-12-16 18:01:38 GMT mtk02752 -+** if interrupt enhanced response is fetched by RX enhanced response, RX needs to invoke interrupt handlers too -+** \main\maintrunk.MT6620WiFiDriver_Prj\56 2009-12-16 14:16:52 GMT mtk02752 -+** \main\maintrunk.MT6620WiFiDriver_Prj\55 2009-12-15 20:03:12 GMT mtk02752 -+** ASSERT when RX FreeSwRfb is not enough -+** \main\maintrunk.MT6620WiFiDriver_Prj\54 2009-12-15 17:01:29 GMT mtk02752 -+** when CFG_SDIO_RX_ENHANCE is enabled, after enhanced response is read, rx procedure should process -+** 1) TX_DONE_INT 2) D2H INT as well -+** \main\maintrunk.MT6620WiFiDriver_Prj\53 2009-12-14 20:45:28 GMT mtk02752 -+** when CFG_SDIO_RX_ENHANCE is set, TC counter must be updated each time RX enhance response is read -+** -+** \main\maintrunk.MT6620WiFiDriver_Prj\52 2009-12-14 11:34:16 GMT mtk02752 -+** correct a trivial logic issue -+** \main\maintrunk.MT6620WiFiDriver_Prj\51 2009-12-14 10:28:25 GMT mtk02752 -+** add a protection to avoid out-of-boundary access -+** \main\maintrunk.MT6620WiFiDriver_Prj\50 2009-12-10 16:55:18 GMT mtk02752 -+** code clean -+** \main\maintrunk.MT6620WiFiDriver_Prj\49 2009-12-09 14:06:47 GMT MTK02468 -+** Added parsing event packets with EVENT_ID_RX_ADDBA or EVENT_ID_RX_DELBA -+** \main\maintrunk.MT6620WiFiDriver_Prj\48 2009-12-08 17:37:51 GMT mtk02752 -+** handle EVENT_ID_TEST_STATUS as well -+** \main\maintrunk.MT6620WiFiDriver_Prj\47 2009-12-04 17:59:11 GMT mtk02752 -+** to pass free-build compilation check -+** \main\maintrunk.MT6620WiFiDriver_Prj\46 2009-12-04 12:09:52 GMT mtk02752 -+** correct trivial mistake -+** \main\maintrunk.MT6620WiFiDriver_Prj\45 2009-12-04 11:53:37 GMT mtk02752 -+** all API should be compilable under SD1_SD3_DATAPATH_INTEGRATION == 0 -+** \main\maintrunk.MT6620WiFiDriver_Prj\44 2009-12-03 16:19:48 GMT mtk01461 -+** Fix the Connected Event -+** \main\maintrunk.MT6620WiFiDriver_Prj\43 2009-11-30 10:56:18 GMT mtk02752 -+** 1st DW of WIFI_EVENT_T is shared with HIF_RX_HEADER_T -+** \main\maintrunk.MT6620WiFiDriver_Prj\42 2009-11-30 10:11:27 GMT mtk02752 -+** implement replacement for bss scan result -+** \main\maintrunk.MT6620WiFiDriver_Prj\41 2009-11-27 11:08:05 GMT mtk02752 -+** add flush for reset -+** \main\maintrunk.MT6620WiFiDriver_Prj\40 2009-11-26 09:38:59 GMT mtk02752 -+** \main\maintrunk.MT6620WiFiDriver_Prj\39 2009-11-26 09:29:40 GMT mtk02752 -+** enable packet forwarding path (for AP mode) -+** \main\maintrunk.MT6620WiFiDriver_Prj\38 2009-11-25 21:37:00 GMT mtk02752 -+** sync. with EVENT_SCAN_RESULT_T change, and add an assert for checking event size -+** \main\maintrunk.MT6620WiFiDriver_Prj\37 2009-11-25 20:17:41 GMT mtk02752 -+** fill HIF_TX_HEADER_T.u2SeqNo -+** \main\maintrunk.MT6620WiFiDriver_Prj\36 2009-11-25 18:18:57 GMT mtk02752 -+** buffer scan result to prGlueInfo->rWlanInfo.arScanResult directly. -+** \main\maintrunk.MT6620WiFiDriver_Prj\35 2009-11-24 22:42:45 GMT mtk02752 -+** add nicRxAddScanResult() to prepare to handle SCAN_RESULT event (not implemented yet) -+** \main\maintrunk.MT6620WiFiDriver_Prj\34 2009-11-24 20:51:41 GMT mtk02752 -+** integrate with SD1's data path API -+** \main\maintrunk.MT6620WiFiDriver_Prj\33 2009-11-24 19:56:17 GMT mtk02752 -+** adopt P_HIF_RX_HEADER_T in new path -+** \main\maintrunk.MT6620WiFiDriver_Prj\32 2009-11-23 20:31:21 GMT mtk02752 -+** payload to send into pfCmdDoneHandler() will not include WIFI_EVENT_T -+** \main\maintrunk.MT6620WiFiDriver_Prj\31 2009-11-23 17:51:34 GMT mtk02752 -+** when event packet corresponding to some pendingOID is received, pendingOID should be cleared -+** \main\maintrunk.MT6620WiFiDriver_Prj\30 2009-11-23 14:46:54 GMT mtk02752 -+** implement nicRxProcessEventPacket() -+** \main\maintrunk.MT6620WiFiDriver_Prj\29 2009-11-17 22:40:54 GMT mtk01084 -+** \main\maintrunk.MT6620WiFiDriver_Prj\28 2009-11-16 21:48:22 GMT mtk02752 -+** add SD1_SD3_DATAPATH_INTEGRATION data path handling -+** \main\maintrunk.MT6620WiFiDriver_Prj\27 2009-11-16 15:41:18 GMT mtk01084 -+** modify the length to be read in emu mode -+** \main\maintrunk.MT6620WiFiDriver_Prj\26 2009-11-13 17:00:12 GMT mtk02752 -+** add blank function for event packet -+** \main\maintrunk.MT6620WiFiDriver_Prj\25 2009-11-13 13:54:24 GMT mtk01084 -+** \main\maintrunk.MT6620WiFiDriver_Prj\24 2009-11-11 14:41:51 GMT mtk02752 -+** fix typo -+** \main\maintrunk.MT6620WiFiDriver_Prj\23 2009-11-11 14:33:46 GMT mtk02752 -+** add protection when there is no packet avilable -+** \main\maintrunk.MT6620WiFiDriver_Prj\22 2009-11-11 12:33:36 GMT mtk02752 -+** add RX1 read path for aggregated/enhanced/normal packet read procedures -+** \main\maintrunk.MT6620WiFiDriver_Prj\21 2009-11-11 10:36:18 GMT mtk01084 -+** \main\maintrunk.MT6620WiFiDriver_Prj\20 2009-11-04 14:11:08 GMT mtk01084 -+** modify lines in RX aggregation -+** \main\maintrunk.MT6620WiFiDriver_Prj\19 2009-10-30 18:17:23 GMT mtk01084 -+** modify RX aggregation handling -+** \main\maintrunk.MT6620WiFiDriver_Prj\18 2009-10-29 19:56:12 GMT mtk01084 -+** modify HAL part -+** \main\maintrunk.MT6620WiFiDriver_Prj\17 2009-10-23 16:08:34 GMT mtk01084 -+** \main\maintrunk.MT6620WiFiDriver_Prj\16 2009-10-13 21:59:20 GMT mtk01084 -+** update for new HW design -+** \main\maintrunk.MT6620WiFiDriver_Prj\15 2009-10-02 13:59:08 GMT mtk01725 -+** \main\maintrunk.MT6620WiFiDriver_Prj\14 2009-05-21 23:39:05 GMT mtk01461 -+** Fix the paste error of RX STATUS in OOB of HIF Loopback CTRL -+** \main\maintrunk.MT6620WiFiDriver_Prj\13 2009-05-20 12:25:32 GMT mtk01461 -+** Fix process of Read Done, and add u4MaxEventBufferLen to nicRxWaitResponse() -+** \main\maintrunk.MT6620WiFiDriver_Prj\12 2009-05-18 21:13:18 GMT mtk01426 -+** Fixed compiler error -+** \main\maintrunk.MT6620WiFiDriver_Prj\11 2009-05-18 21:05:29 GMT mtk01426 -+** Fixed nicRxSDIOAggReceiveRFBs() ASSERT issue -+** \main\maintrunk.MT6620WiFiDriver_Prj\10 2009-04-28 10:38:43 GMT mtk01461 -+** Fix RX STATUS is DW align for SDIO_STATUS_ENHANCE mode and refine nicRxSDIOAggeceiveRFBs() for RX Aggregation -+** \main\maintrunk.MT6620WiFiDriver_Prj\9 2009-04-22 09:12:17 GMT mtk01461 -+** Fix nicRxProcessHIFLoopbackPacket(), the size of HIF CTRL LENGTH field is 1 byte -+** \main\maintrunk.MT6620WiFiDriver_Prj\8 2009-04-14 15:51:26 GMT mtk01426 -+** Update RX OOB Setting -+** \main\maintrunk.MT6620WiFiDriver_Prj\7 2009-04-03 14:58:58 GMT mtk01426 -+** Fixed logical error -+** \main\maintrunk.MT6620WiFiDriver_Prj\6 2009-04-01 10:58:31 GMT mtk01461 -+** Rename the HIF_PKT_TYPE_DATA -+** \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-03-23 21:51:18 GMT mtk01461 -+** Fix u4HeaderOffset in nicRxProcessHIFLoopbackPacket() -+** \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-03-18 21:02:58 GMT mtk01426 -+** Add CFG_SDIO_RX_ENHANCE and CFG_HIF_LOOPBACK support -+** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-03-17 20:20:59 GMT mtk01426 -+** Add nicRxWaitResponse function -+** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 20:26:01 GMT mtk01426 -+** Init for develop -+** -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "precomp.h" -+ -+#ifndef LINUX -+#include -+#else -+#include -+#endif -+ -+#include "gl_os.h" -+#include "debug.h" -+#include "wlan_lib.h" -+#include "gl_wext.h" -+#include -+#include -+#include -+#include "gl_cfg80211.h" -+#include "gl_vendor.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+#define RX_RESPONSE_TIMEOUT (1000) -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+#if CFG_MGMT_FRAME_HANDLING -+static PROCESS_RX_MGT_FUNCTION apfnProcessRxMgtFrame[MAX_NUM_OF_FC_SUBTYPES] = { -+#if CFG_SUPPORT_AAA -+ aaaFsmRunEventRxAssoc, /* subtype 0000: Association request */ -+#else -+ NULL, /* subtype 0000: Association request */ -+#endif /* CFG_SUPPORT_AAA */ -+ saaFsmRunEventRxAssoc, /* subtype 0001: Association response */ -+#if CFG_SUPPORT_AAA -+ aaaFsmRunEventRxAssoc, /* subtype 0010: Reassociation request */ -+#else -+ NULL, /* subtype 0010: Reassociation request */ -+#endif /* CFG_SUPPORT_AAA */ -+ saaFsmRunEventRxAssoc, /* subtype 0011: Reassociation response */ -+#if (CFG_SUPPORT_ADHOC) || (CFG_SUPPORT_AAA) -+ bssProcessProbeRequest, /* subtype 0100: Probe request */ -+#else -+ NULL, /* subtype 0100: Probe request */ -+#endif /* CFG_SUPPORT_ADHOC */ -+ scanProcessBeaconAndProbeResp, /* subtype 0101: Probe response */ -+ NULL, /* subtype 0110: reserved */ -+ NULL, /* subtype 0111: reserved */ -+ scanProcessBeaconAndProbeResp, /* subtype 1000: Beacon */ -+ NULL, /* subtype 1001: ATIM */ -+ saaFsmRunEventRxDisassoc, /* subtype 1010: Disassociation */ -+ authCheckRxAuthFrameTransSeq, /* subtype 1011: Authentication */ -+ saaFsmRunEventRxDeauth, /* subtype 1100: Deauthentication */ -+ nicRxProcessActionFrame, /* subtype 1101: Action */ -+ NULL, /* subtype 1110: reserved */ -+ NULL /* subtype 1111: reserved */ -+}; -+#endif -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Initialize the RFBs -+* -+* @param prAdapter Pointer to the Adapter structure. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicRxInitialize(IN P_ADAPTER_T prAdapter) -+{ -+ P_RX_CTRL_T prRxCtrl; -+ PUINT_8 pucMemHandle; -+ P_SW_RFB_T prSwRfb = (P_SW_RFB_T) NULL; -+ UINT_32 i; -+ -+ DEBUGFUNC("nicRxInitialize"); -+ -+ ASSERT(prAdapter); -+ prRxCtrl = &prAdapter->rRxCtrl; -+ -+ /* 4 <0> Clear allocated memory. */ -+ kalMemZero((PVOID) prRxCtrl->pucRxCached, prRxCtrl->u4RxCachedSize); -+ -+ /* 4 <1> Initialize the RFB lists */ -+ QUEUE_INITIALIZE(&prRxCtrl->rFreeSwRfbList); -+ QUEUE_INITIALIZE(&prRxCtrl->rReceivedRfbList); -+ QUEUE_INITIALIZE(&prRxCtrl->rIndicatedRfbList); -+ -+ pucMemHandle = prRxCtrl->pucRxCached; -+ for (i = CFG_RX_MAX_PKT_NUM; i != 0; i--) { -+ prSwRfb = (P_SW_RFB_T) pucMemHandle; -+ -+ nicRxSetupRFB(prAdapter, prSwRfb); -+ nicRxReturnRFB(prAdapter, prSwRfb); -+ -+ pucMemHandle += ALIGN_4(sizeof(SW_RFB_T)); -+ } -+ -+ ASSERT(prRxCtrl->rFreeSwRfbList.u4NumElem == CFG_RX_MAX_PKT_NUM); -+ /* Check if the memory allocation consist with this initialization function */ -+ ASSERT((ULONG) (pucMemHandle - prRxCtrl->pucRxCached) == prRxCtrl->u4RxCachedSize); -+ -+ /* 4 <2> Clear all RX counters */ -+ RX_RESET_ALL_CNTS(prRxCtrl); -+ -+#if CFG_SDIO_RX_AGG -+ prRxCtrl->pucRxCoalescingBufPtr = prAdapter->pucCoalescingBufCached; -+ HAL_CFG_MAX_HIF_RX_LEN_NUM(prAdapter, CFG_SDIO_MAX_RX_AGG_NUM); -+#else -+ HAL_CFG_MAX_HIF_RX_LEN_NUM(prAdapter, 1); -+#endif -+ -+#if CFG_HIF_STATISTICS -+ prRxCtrl->u4TotalRxAccessNum = 0; -+ prRxCtrl->u4TotalRxPacketNum = 0; -+#endif -+ -+#if CFG_HIF_RX_STARVATION_WARNING -+ prRxCtrl->u4QueuedCnt = 0; -+ prRxCtrl->u4DequeuedCnt = 0; -+#endif -+ -+} /* end of nicRxInitialize() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Uninitialize the RFBs -+* -+* @param prAdapter Pointer to the Adapter structure. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicRxUninitialize(IN P_ADAPTER_T prAdapter) -+{ -+ P_RX_CTRL_T prRxCtrl; -+ P_SW_RFB_T prSwRfb = (P_SW_RFB_T) NULL; -+ -+ KAL_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(prAdapter); -+ prRxCtrl = &prAdapter->rRxCtrl; -+ ASSERT(prRxCtrl); -+ -+ nicRxFlush(prAdapter); -+ -+ do { -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); -+ QUEUE_REMOVE_HEAD(&prRxCtrl->rReceivedRfbList, prSwRfb, P_SW_RFB_T); -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); -+ if (prSwRfb) { -+ if (prSwRfb->pvPacket) -+ kalPacketFree(prAdapter->prGlueInfo, prSwRfb->pvPacket); -+ prSwRfb->pvPacket = NULL; -+ } else { -+ break; -+ } -+ } while (TRUE); -+ -+ do { -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); -+ QUEUE_REMOVE_HEAD(&prRxCtrl->rFreeSwRfbList, prSwRfb, P_SW_RFB_T); -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); -+ if (prSwRfb) { -+ if (prSwRfb->pvPacket) -+ kalPacketFree(prAdapter->prGlueInfo, prSwRfb->pvPacket); -+ prSwRfb->pvPacket = NULL; -+ } else { -+ break; -+ } -+ } while (TRUE); -+ -+} /* end of nicRxUninitialize() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Fill RFB -+* -+* @param prAdapter pointer to the Adapter handler -+* @param prSWRfb specify the RFB to receive rx data -+* -+* @return (none) -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicRxFillRFB(IN P_ADAPTER_T prAdapter, IN OUT P_SW_RFB_T prSwRfb) -+{ -+ P_HIF_RX_HEADER_T prHifRxHdr; -+ -+ UINT_32 u4PktLen = 0; -+ UINT_32 u4MacHeaderLen; -+ UINT_32 u4HeaderOffset; -+ -+ DEBUGFUNC("nicRxFillRFB"); -+ -+ ASSERT(prAdapter); -+ ASSERT(prSwRfb); -+ -+ prHifRxHdr = prSwRfb->prHifRxHdr; -+ ASSERT(prHifRxHdr); -+ -+ u4PktLen = prHifRxHdr->u2PacketLen; -+ -+ u4HeaderOffset = (UINT_32) (prHifRxHdr->ucHerderLenOffset & HIF_RX_HDR_HEADER_OFFSET_MASK); -+ u4MacHeaderLen = (UINT_32) (prHifRxHdr->ucHerderLenOffset & HIF_RX_HDR_HEADER_LEN) -+ >> HIF_RX_HDR_HEADER_LEN_OFFSET; -+ -+ /* DBGLOG(RX, TRACE, ("u4HeaderOffset = %d, u4MacHeaderLen = %d\n", */ -+ /* u4HeaderOffset, u4MacHeaderLen)); */ -+ -+ prSwRfb->u2HeaderLen = (UINT_16) u4MacHeaderLen; -+ prSwRfb->pvHeader = (PUINT_8) prHifRxHdr + HIF_RX_HDR_SIZE + u4HeaderOffset; -+ prSwRfb->u2PacketLen = (UINT_16) (u4PktLen - (HIF_RX_HDR_SIZE + u4HeaderOffset)); -+ -+ /* DBGLOG(RX, TRACE, ("Dump Rx packet, u2PacketLen = %d\n", prSwRfb->u2PacketLen)); */ -+ /* DBGLOG_MEM8(RX, TRACE, prSwRfb->pvHeader, prSwRfb->u2PacketLen); */ -+ -+#if 0 -+ if (prHifRxHdr->ucReorder & HIF_RX_HDR_80211_HEADER_FORMAT) { -+ prSwRfb->u4HifRxHdrFlag |= HIF_RX_HDR_FLAG_802_11_FORMAT; -+ DBGLOG(RX, TRACE, "HIF_RX_HDR_FLAG_802_11_FORMAT\n"); -+ } -+ -+ if (prHifRxHdr->ucReorder & HIF_RX_HDR_DO_REORDER) { -+ prSwRfb->u4HifRxHdrFlag |= HIF_RX_HDR_FLAG_DO_REORDERING; -+ DBGLOG(RX, TRACE, "HIF_RX_HDR_FLAG_DO_REORDERING\n"); -+ -+ /* Get Seq. No and TID, Wlan Index info */ -+ if (prHifRxHdr->u2SeqNoTid & HIF_RX_HDR_BAR_FRAME) { -+ prSwRfb->u4HifRxHdrFlag |= HIF_RX_HDR_FLAG_BAR_FRAME; -+ DBGLOG(RX, TRACE, "HIF_RX_HDR_FLAG_BAR_FRAME\n"); -+ } -+ -+ prSwRfb->u2SSN = prHifRxHdr->u2SeqNoTid & HIF_RX_HDR_SEQ_NO_MASK; -+ prSwRfb->ucTid = (UINT_8) ((prHifRxHdr->u2SeqNoTid & HIF_RX_HDR_TID_MASK) -+ >> HIF_RX_HDR_TID_OFFSET); -+ DBGLOG(RX, TRACE, "u2SSN = %d, ucTid = %d\n", prSwRfb->u2SSN, prSwRfb->ucTid); -+ } -+ -+ if (prHifRxHdr->ucReorder & HIF_RX_HDR_WDS) { -+ prSwRfb->u4HifRxHdrFlag |= HIF_RX_HDR_FLAG_AMP_WDS; -+ DBGLOG(RX, TRACE, "HIF_RX_HDR_FLAG_AMP_WDS\n"); -+ } -+#endif -+} -+ -+#if CFG_TCP_IP_CHKSUM_OFFLOAD || CFG_TCP_IP_CHKSUM_OFFLOAD_NDIS_60 -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Fill checksum status in RFB -+* -+* @param prAdapter pointer to the Adapter handler -+* @param prSWRfb the RFB to receive rx data -+* @param u4TcpUdpIpCksStatus specify the Checksum status -+* -+* @return (none) -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicRxFillChksumStatus(IN P_ADAPTER_T prAdapter, IN OUT P_SW_RFB_T prSwRfb, IN UINT_32 u4TcpUdpIpCksStatus) -+{ -+ -+ ASSERT(prAdapter); -+ ASSERT(prSwRfb); -+ -+ if (prAdapter->u4CSUMFlags != CSUM_NOT_SUPPORTED) { -+ if (u4TcpUdpIpCksStatus & RX_CS_TYPE_IPv4) { /* IPv4 packet */ -+ prSwRfb->aeCSUM[CSUM_TYPE_IPV6] = CSUM_RES_NONE; -+ if (u4TcpUdpIpCksStatus & RX_CS_STATUS_IP) { /* IP packet csum failed */ -+ prSwRfb->aeCSUM[CSUM_TYPE_IPV4] = CSUM_RES_FAILED; -+ } else { -+ prSwRfb->aeCSUM[CSUM_TYPE_IPV4] = CSUM_RES_SUCCESS; -+ } -+ -+ if (u4TcpUdpIpCksStatus & RX_CS_TYPE_TCP) { /* TCP packet */ -+ prSwRfb->aeCSUM[CSUM_TYPE_UDP] = CSUM_RES_NONE; -+ if (u4TcpUdpIpCksStatus & RX_CS_STATUS_TCP) { /* TCP packet csum failed */ -+ prSwRfb->aeCSUM[CSUM_TYPE_TCP] = CSUM_RES_FAILED; -+ } else { -+ prSwRfb->aeCSUM[CSUM_TYPE_TCP] = CSUM_RES_SUCCESS; -+ } -+ } else if (u4TcpUdpIpCksStatus & RX_CS_TYPE_UDP) { /* UDP packet */ -+ prSwRfb->aeCSUM[CSUM_TYPE_TCP] = CSUM_RES_NONE; -+ if (u4TcpUdpIpCksStatus & RX_CS_STATUS_UDP) { /* UDP packet csum failed */ -+ prSwRfb->aeCSUM[CSUM_TYPE_UDP] = CSUM_RES_FAILED; -+ } else { -+ prSwRfb->aeCSUM[CSUM_TYPE_UDP] = CSUM_RES_SUCCESS; -+ } -+ } else { -+ prSwRfb->aeCSUM[CSUM_TYPE_UDP] = CSUM_RES_NONE; -+ prSwRfb->aeCSUM[CSUM_TYPE_TCP] = CSUM_RES_NONE; -+ } -+ } else if (u4TcpUdpIpCksStatus & RX_CS_TYPE_IPv6) { /* IPv6 packet */ -+ prSwRfb->aeCSUM[CSUM_TYPE_IPV4] = CSUM_RES_NONE; -+ prSwRfb->aeCSUM[CSUM_TYPE_IPV6] = CSUM_RES_SUCCESS; -+ -+ if (u4TcpUdpIpCksStatus & RX_CS_TYPE_TCP) { /* TCP packet */ -+ prSwRfb->aeCSUM[CSUM_TYPE_UDP] = CSUM_RES_NONE; -+ if (u4TcpUdpIpCksStatus & RX_CS_STATUS_TCP) { /* TCP packet csum failed */ -+ prSwRfb->aeCSUM[CSUM_TYPE_TCP] = CSUM_RES_FAILED; -+ } else { -+ prSwRfb->aeCSUM[CSUM_TYPE_TCP] = CSUM_RES_SUCCESS; -+ } -+ } else if (u4TcpUdpIpCksStatus & RX_CS_TYPE_UDP) { /* UDP packet */ -+ prSwRfb->aeCSUM[CSUM_TYPE_TCP] = CSUM_RES_NONE; -+ if (u4TcpUdpIpCksStatus & RX_CS_STATUS_UDP) { /* UDP packet csum failed */ -+ prSwRfb->aeCSUM[CSUM_TYPE_UDP] = CSUM_RES_FAILED; -+ } else { -+ prSwRfb->aeCSUM[CSUM_TYPE_UDP] = CSUM_RES_SUCCESS; -+ } -+ } else { -+ prSwRfb->aeCSUM[CSUM_TYPE_UDP] = CSUM_RES_NONE; -+ prSwRfb->aeCSUM[CSUM_TYPE_TCP] = CSUM_RES_NONE; -+ } -+ } else { -+ prSwRfb->aeCSUM[CSUM_TYPE_IPV4] = CSUM_RES_NONE; -+ prSwRfb->aeCSUM[CSUM_TYPE_IPV6] = CSUM_RES_NONE; -+ } -+ } -+ -+} -+#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Process packet doesn't need to do buffer reordering -+* -+* @param prAdapter pointer to the Adapter handler -+* @param prSWRfb the RFB to receive rx data -+* -+* @return (none) -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicRxProcessPktWithoutReorder(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb) -+{ -+ P_RX_CTRL_T prRxCtrl; -+ P_TX_CTRL_T prTxCtrl; -+ BOOLEAN fgIsRetained = FALSE; -+ UINT_32 u4CurrentRxBufferCount; -+ P_STA_RECORD_T prStaRec = (P_STA_RECORD_T) NULL; -+ -+ DEBUGFUNC("nicRxProcessPktWithoutReorder"); -+ /* DBGLOG(RX, TRACE, ("\n")); */ -+ -+ ASSERT(prAdapter); -+ ASSERT(prSwRfb); -+ -+ prRxCtrl = &prAdapter->rRxCtrl; -+ ASSERT(prRxCtrl); -+ -+ prTxCtrl = &prAdapter->rTxCtrl; -+ ASSERT(prTxCtrl); -+ -+ u4CurrentRxBufferCount = prRxCtrl->rFreeSwRfbList.u4NumElem; -+ /* QM USED = $A, AVAILABLE COUNT = $B, INDICATED TO OS = $C -+ * TOTAL = $A + $B + $C -+ * -+ * Case #1 (Retain) -+ * ------------------------------------------------------- -+ * $A + $B < THRESHOLD := $A + $B + $C < THRESHOLD + $C := $TOTAL - THRESHOLD < $C -+ * => $C used too much, retain -+ * -+ * Case #2 (Non-Retain) -+ * ------------------------------------------------------- -+ * $A + $B > THRESHOLD := $A + $B + $C > THRESHOLD + $C := $TOTAL - THRESHOLD > $C -+ * => still available for $C to use -+ * -+ */ -+ fgIsRetained = (((u4CurrentRxBufferCount + -+ qmGetRxReorderQueuedBufferCount(prAdapter) + -+ prTxCtrl->i4PendingFwdFrameCount) < CFG_RX_RETAINED_PKT_THRESHOLD) ? TRUE : FALSE); -+ -+ /* DBGLOG(RX, INFO, ("fgIsRetained = %d\n", fgIsRetained)); */ -+ -+ if (kalProcessRxPacket(prAdapter->prGlueInfo, -+ prSwRfb->pvPacket, -+ prSwRfb->pvHeader, -+ (UINT_32) prSwRfb->u2PacketLen, fgIsRetained, prSwRfb->aeCSUM) != WLAN_STATUS_SUCCESS) { -+ DBGLOG(RX, ERROR, "kalProcessRxPacket return value != WLAN_STATUS_SUCCESS\n"); -+ ASSERT(0); -+ -+ nicRxReturnRFB(prAdapter, prSwRfb); -+ return; -+ } -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); -+ -+ if (prStaRec) { -+#if CFG_ENABLE_WIFI_DIRECT -+ if (prStaRec->ucNetTypeIndex == NETWORK_TYPE_P2P_INDEX && prAdapter->fgIsP2PRegistered == TRUE) -+ GLUE_SET_PKT_FLAG_P2P(prSwRfb->pvPacket); -+#endif -+#if CFG_ENABLE_BT_OVER_WIFI -+ if (prStaRec->ucNetTypeIndex == NETWORK_TYPE_BOW_INDEX) -+ GLUE_SET_PKT_FLAG_PAL(prSwRfb->pvPacket); -+#endif -+ -+ /* record the count to pass to os */ -+ STATS_RX_PASS2OS_INC(prStaRec, prSwRfb); -+ } -+ prRxCtrl->apvIndPacket[prRxCtrl->ucNumIndPacket] = prSwRfb->pvPacket; -+ prRxCtrl->ucNumIndPacket++; -+ -+ if (fgIsRetained) { -+ prRxCtrl->apvRetainedPacket[prRxCtrl->ucNumRetainedPacket] = prSwRfb->pvPacket; -+ prRxCtrl->ucNumRetainedPacket++; -+ /* TODO : error handling of nicRxSetupRFB */ -+ nicRxSetupRFB(prAdapter, prSwRfb); -+ nicRxReturnRFB(prAdapter, prSwRfb); -+ } else { -+ prSwRfb->pvPacket = NULL; -+ nicRxReturnRFB(prAdapter, prSwRfb); -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Process forwarding data packet -+* -+* @param prAdapter pointer to the Adapter handler -+* @param prSWRfb the RFB to receive rx data -+* -+* @return (none) -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicRxProcessForwardPkt(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb) -+{ -+ P_MSDU_INFO_T prMsduInfo, prRetMsduInfoList; -+ P_TX_CTRL_T prTxCtrl; -+ P_RX_CTRL_T prRxCtrl; -+ -+ KAL_SPIN_LOCK_DECLARATION(); -+ -+ DEBUGFUNC("nicRxProcessForwardPkt"); -+ -+ ASSERT(prAdapter); -+ ASSERT(prSwRfb); -+ -+ prTxCtrl = &prAdapter->rTxCtrl; -+ prRxCtrl = &prAdapter->rRxCtrl; -+ -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_MSDU_INFO_LIST); -+ QUEUE_REMOVE_HEAD(&prTxCtrl->rFreeMsduInfoList, prMsduInfo, P_MSDU_INFO_T); -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_MSDU_INFO_LIST); -+ -+ if (prMsduInfo && kalProcessRxPacket(prAdapter->prGlueInfo, -+ prSwRfb->pvPacket, -+ prSwRfb->pvHeader, -+ (UINT_32) prSwRfb->u2PacketLen, -+ prRxCtrl->rFreeSwRfbList.u4NumElem < -+ CFG_RX_RETAINED_PKT_THRESHOLD ? TRUE : FALSE, -+ prSwRfb->aeCSUM) == WLAN_STATUS_SUCCESS) { -+ -+ prMsduInfo->eSrc = TX_PACKET_FORWARDING; -+ /* pack into MSDU_INFO_T */ -+ nicTxFillMsduInfo(prAdapter, prMsduInfo, (P_NATIVE_PACKET) (prSwRfb->pvPacket)); -+ /* Overwrite the ucNetworkType */ -+ prMsduInfo->ucNetworkType = HIF_RX_HDR_GET_NETWORK_IDX(prSwRfb->prHifRxHdr); -+ -+ /* release RX buffer (to rIndicatedRfbList) */ -+ prSwRfb->pvPacket = NULL; -+ nicRxReturnRFB(prAdapter, prSwRfb); -+ -+ /* increase forward frame counter */ -+ GLUE_INC_REF_CNT(prTxCtrl->i4PendingFwdFrameCount); -+ -+ /* send into TX queue */ -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_QM_TX_QUEUE); -+ prRetMsduInfoList = qmEnqueueTxPackets(prAdapter, prMsduInfo); -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_QM_TX_QUEUE); -+ -+ if (prRetMsduInfoList != NULL) { /* TX queue refuses queuing the packet */ -+ nicTxFreeMsduInfoPacket(prAdapter, prRetMsduInfoList); -+ nicTxReturnMsduInfo(prAdapter, prRetMsduInfoList); -+ } -+ /* indicate service thread for sending */ -+ if (prTxCtrl->i4PendingFwdFrameCount > 0) -+ kalSetEvent(prAdapter->prGlueInfo); -+ } else /* no TX resource */ -+ nicRxReturnRFB(prAdapter, prSwRfb); -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Process broadcast data packet for both host and forwarding -+* -+* @param prAdapter pointer to the Adapter handler -+* @param prSWRfb the RFB to receive rx data -+* -+* @return (none) -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicRxProcessGOBroadcastPkt(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb) -+{ -+ P_SW_RFB_T prSwRfbDuplicated; -+ P_TX_CTRL_T prTxCtrl; -+ P_RX_CTRL_T prRxCtrl; -+ P_HIF_RX_HEADER_T prHifRxHdr; -+ -+ KAL_SPIN_LOCK_DECLARATION(); -+ -+ DEBUGFUNC("nicRxProcessGOBroadcastPkt"); -+ -+ ASSERT(prAdapter); -+ ASSERT(prSwRfb); -+ -+ prTxCtrl = &prAdapter->rTxCtrl; -+ prRxCtrl = &prAdapter->rRxCtrl; -+ -+ prHifRxHdr = prSwRfb->prHifRxHdr; -+ ASSERT(prHifRxHdr); -+ -+ ASSERT(CFG_NUM_OF_QM_RX_PKT_NUM >= 16); -+ -+ if (prRxCtrl->rFreeSwRfbList.u4NumElem -+ >= (CFG_RX_MAX_PKT_NUM - (CFG_NUM_OF_QM_RX_PKT_NUM - 16 /* Reserved for others */))) { -+ -+ /* 1. Duplicate SW_RFB_T */ -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); -+ QUEUE_REMOVE_HEAD(&prRxCtrl->rFreeSwRfbList, prSwRfbDuplicated, P_SW_RFB_T); -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); -+ -+ if (prSwRfbDuplicated) { -+ kalMemCopy(prSwRfbDuplicated->pucRecvBuff, -+ prSwRfb->pucRecvBuff, ALIGN_4(prHifRxHdr->u2PacketLen + HIF_RX_HW_APPENDED_LEN)); -+ -+ prSwRfbDuplicated->ucPacketType = HIF_RX_PKT_TYPE_DATA; -+ prSwRfbDuplicated->ucStaRecIdx = (UINT_8) (prHifRxHdr->ucStaRecIdx); -+ nicRxFillRFB(prAdapter, prSwRfbDuplicated); -+ -+ /* 2. Modify eDst */ -+ prSwRfbDuplicated->eDst = RX_PKT_DESTINATION_FORWARD; -+ -+ /* 4. Forward */ -+ nicRxProcessForwardPkt(prAdapter, prSwRfbDuplicated); -+ } -+ } else { -+ DBGLOG(RX, WARN, "Stop to forward BMC packet due to less free Sw Rfb %u\n", -+ prRxCtrl->rFreeSwRfbList.u4NumElem); -+ } -+ -+ /* 3. Indicate to host */ -+ prSwRfb->eDst = RX_PKT_DESTINATION_HOST; -+ nicRxProcessPktWithoutReorder(prAdapter, prSwRfb); -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Process HIF data packet -+* -+* @param prAdapter pointer to the Adapter handler -+* @param prSWRfb the RFB to receive rx data -+* -+* @return (none) -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicRxProcessDataPacket(IN P_ADAPTER_T prAdapter, IN OUT P_SW_RFB_T prSwRfb) -+{ -+ P_RX_CTRL_T prRxCtrl; -+ P_SW_RFB_T prRetSwRfb, prNextSwRfb; -+ P_HIF_RX_HEADER_T prHifRxHdr; -+ P_STA_RECORD_T prStaRec; -+ BOOLEAN fIsDummy = FALSE; -+ -+ DEBUGFUNC("nicRxProcessDataPacket"); -+ /* DBGLOG(RX, TRACE, ("\n")); */ -+ -+ ASSERT(prAdapter); -+ ASSERT(prSwRfb); -+ -+ prHifRxHdr = prSwRfb->prHifRxHdr; -+ prRxCtrl = &prAdapter->rRxCtrl; -+ -+ fIsDummy = (prHifRxHdr->u2PacketLen >= 12) ? FALSE : TRUE; -+ -+ nicRxFillRFB(prAdapter, prSwRfb); -+ -+#if CFG_TCP_IP_CHKSUM_OFFLOAD || CFG_TCP_IP_CHKSUM_OFFLOAD_NDIS_60 -+ { -+ UINT_32 u4TcpUdpIpCksStatus; -+ -+ u4TcpUdpIpCksStatus = *((PUINT_32) ((ULONG) prHifRxHdr + (UINT_32) (ALIGN_4(prHifRxHdr->u2PacketLen)))); -+ nicRxFillChksumStatus(prAdapter, prSwRfb, u4TcpUdpIpCksStatus); -+ -+ } -+#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */ -+ -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prHifRxHdr->ucStaRecIdx); -+ if (secCheckClassError(prAdapter, prSwRfb, prStaRec) == TRUE && prAdapter->fgTestMode == FALSE) { -+#if CFG_HIF_RX_STARVATION_WARNING -+ prRxCtrl->u4QueuedCnt++; -+#endif -+ prRetSwRfb = qmHandleRxPackets(prAdapter, prSwRfb); -+ if (prRetSwRfb != NULL) { -+ do { -+ /* save next first */ -+ prNextSwRfb = (P_SW_RFB_T) QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T) prRetSwRfb); -+ if (fIsDummy == TRUE) { -+ nicRxReturnRFB(prAdapter, prRetSwRfb); -+ RX_INC_CNT(prRxCtrl, RX_DROP_TOTAL_COUNT); -+ DBGLOG(RX, WARN, "Drop Dummy Packets"); -+ -+ } else { -+ switch (prRetSwRfb->eDst) { -+ case RX_PKT_DESTINATION_HOST: -+#if ARP_MONITER_ENABLE -+ if (IS_STA_IN_AIS(prStaRec)) -+ qmHandleRxArpPackets(prAdapter, prRetSwRfb); -+#endif -+ nicRxProcessPktWithoutReorder(prAdapter, prRetSwRfb); -+ break; -+ -+ case RX_PKT_DESTINATION_FORWARD: -+ nicRxProcessForwardPkt(prAdapter, prRetSwRfb); -+ break; -+ -+ case RX_PKT_DESTINATION_HOST_WITH_FORWARD: -+ nicRxProcessGOBroadcastPkt(prAdapter, prRetSwRfb); -+ break; -+ -+ case RX_PKT_DESTINATION_NULL: -+ nicRxReturnRFB(prAdapter, prRetSwRfb); -+ RX_INC_CNT(prRxCtrl, RX_DST_NULL_DROP_COUNT); -+ RX_INC_CNT(prRxCtrl, RX_DROP_TOTAL_COUNT); -+ break; -+ -+ default: -+ break; -+ } -+ } -+#if CFG_HIF_RX_STARVATION_WARNING -+ prRxCtrl->u4DequeuedCnt++; -+#endif -+ prRetSwRfb = prNextSwRfb; -+ } while (prRetSwRfb); -+ } -+ } else { -+ nicRxReturnRFB(prAdapter, prSwRfb); -+ RX_INC_CNT(prRxCtrl, RX_CLASS_ERR_DROP_COUNT); -+ RX_INC_CNT(prRxCtrl, RX_DROP_TOTAL_COUNT); -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Process HIF event packet -+* -+* @param prAdapter pointer to the Adapter handler -+* @param prSWRfb the RFB to receive rx data -+* -+* @return (none) -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+ -+UINT_8 nicRxProcessGSCNEvent(IN P_ADAPTER_T prAdapter, IN OUT P_SW_RFB_T prSwRfb) -+{ -+ P_WIFI_EVENT_T prEvent; -+ P_GLUE_INFO_T prGlueInfo; -+ struct sk_buff *skb; -+ struct wiphy *wiphy; -+ -+ UINT_32 real_num = 0; -+ -+ P_EVENT_GSCAN_SCAN_AVAILABLE_T prEventGscnAvailable; -+ P_EVENT_GSCAN_RESULT_T prEventBuffer; -+ P_WIFI_GSCAN_RESULT_T prEventGscnResult; -+ INT_32 i4Status = -EINVAL; -+ struct nlattr *attr; -+ UINT_32 scan_id; -+ UINT_8 scan_flag; -+ P_EVENT_GSCAN_CAPABILITY_T prEventGscnCapbiblity; -+ P_EVENT_GSCAN_SCAN_COMPLETE_T prEventGscnScnDone; -+ P_WIFI_GSCAN_RESULT_T prEventGscnFullResult; -+ P_PARAM_WIFI_GSCAN_RESULT prParamGscnFullResult; -+ P_EVENT_GSCAN_SIGNIFICANT_CHANGE_T prEventGscnSignificantChange; -+ P_EVENT_GSCAN_SIGNIFICANT_CHANGE_T prEventGscnGeofenceFound; -+ -+ P_PARAM_WIFI_GSCAN_RESULT prResults; -+ -+ DEBUGFUNC("nicRxProcessGSCNEvent"); -+ /* DBGLOG(RX, TRACE, ("\n")); */ -+ -+ DBGLOG(SCN, INFO, "nicRxProcessGSCNEvent\n"); -+ -+ ASSERT(prAdapter); -+ ASSERT(prSwRfb); -+ -+ prEvent = (P_WIFI_EVENT_T) prSwRfb->pucRecvBuff; -+ prGlueInfo = prAdapter->prGlueInfo; -+ -+ /* Push the data to the skb */ -+ wiphy = priv_to_wiphy(prGlueInfo); -+ -+ /* prGlueInfo-> */ -+ -+ /* Event Handling */ -+ switch (prEvent->ucEID) { -+ case EVENT_ID_GSCAN_SCAN_AVAILABLE: -+ { -+ DBGLOG(SCN, INFO, "EVENT_ID_GSCAN_SCAN_AVAILABLE\n"); -+ -+ prEventGscnAvailable = (P_EVENT_GSCAN_SCAN_AVAILABLE_T) (prEvent->aucBuffer); -+ memcpy(prEventGscnAvailable, (P_EVENT_GSCAN_SCAN_AVAILABLE_T) (prEvent->aucBuffer), -+ sizeof(EVENT_GSCAN_SCAN_AVAILABLE_T)); -+ -+ mtk_cfg80211_vendor_event_scan_results_available(wiphy, prGlueInfo->prDevHandler->ieee80211_ptr, -+ prEventGscnAvailable->u2Num); -+ } -+ break; -+ -+ case EVENT_ID_GSCAN_RESULT: -+ { -+ DBGLOG(SCN, INFO, "EVENT_ID_GSCAN_RESULT 2\n"); -+ -+ prEventBuffer = (P_EVENT_GSCAN_RESULT_T) (prEvent->aucBuffer); -+ prEventGscnResult = prEventBuffer->rResult; -+/* -+ the following event struct should moved to kal and use the kal api to avoid future porting effort -+ -+*/ -+ scan_id = prEventBuffer->u2ScanId; -+ scan_flag = prEventBuffer->u2ScanFlags; -+ real_num = prEventBuffer->u2NumOfResults; -+ -+ DBGLOG(SCN, INFO, "scan_id=%d, scan_flag =%d, real_num=%d\r\n", scan_id, scan_flag, real_num); -+ -+ skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(PARAM_WIFI_GSCAN_RESULT) * real_num); -+ if (!skb) { -+ DBGLOG(RX, TRACE, "%s allocate skb failed:%x\n", __func__, i4Status); -+ return -ENOMEM; -+ } -+ -+ attr = nla_nest_start(skb, GSCAN_ATTRIBUTE_SCAN_RESULTS); -+ /*NLA_PUT_U32(skb, GSCAN_ATTRIBUTE_SCAN_ID, scan_id);*/ -+ { -+ unsigned int __tmp = scan_id; -+ -+ if (unlikely(nla_put(skb, GSCAN_ATTRIBUTE_SCAN_ID, sizeof(unsigned int), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ /*NLA_PUT_U8(skb, GSCAN_ATTRIBUTE_SCAN_FLAGS, 1);*/ -+ { -+ unsigned char __tmp = 1; -+ -+ if (unlikely(nla_put(skb, GSCAN_ATTRIBUTE_SCAN_FLAGS, sizeof(u8), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ /*NLA_PUT_U32(skb, GSCAN_ATTRIBUTE_NUM_OF_RESULTS, real_num);*/ -+ { -+ unsigned int __tmp = real_num; -+ -+ if (unlikely(nla_put(skb, GSCAN_ATTRIBUTE_NUM_OF_RESULTS, -+ sizeof(unsigned int), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ -+ prResults = (P_PARAM_WIFI_GSCAN_RESULT) prEventGscnResult; -+ if (prResults) -+ DBGLOG(SCN, INFO, "ssid=%s, rssi=%d, channel=%d \r\n", -+ prResults->ssid, prResults->rssi, prResults->channel); -+ /*NLA_PUT(skb, GSCAN_ATTRIBUTE_SCAN_RESULTS, sizeof(PARAM_WIFI_GSCAN_RESULT) * real_num, -+ prResults);*/ -+ -+ if (unlikely(nla_put(skb, GSCAN_ATTRIBUTE_SCAN_RESULTS, -+ sizeof(PARAM_WIFI_GSCAN_RESULT)*real_num, prResults) < 0)) -+ goto nla_put_failure; -+ -+ DBGLOG(SCN, INFO, "NLA_PUT scan results over\t"); -+ -+ if (attr) -+ nla_nest_end(skb, attr); -+ /* report_events=1 */ -+ /*NLA_PUT_U8(skb, GSCAN_ATTRIBUTE_SCAN_RESULTS_COMPLETE, 1);*/ -+ { -+ unsigned char __tmp = 1; -+ -+ if (unlikely(nla_put(skb, GSCAN_ATTRIBUTE_SCAN_RESULTS_COMPLETE, -+ sizeof(unsigned int), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ -+ -+ i4Status = cfg80211_vendor_cmd_reply(skb); -+ skb = NULL; -+ DBGLOG(SCN, INFO, " i4Status %d\n", i4Status); -+ } -+ break; -+ -+ case EVENT_ID_GSCAN_CAPABILITY: -+ { -+ DBGLOG(SCN, INFO, "EVENT_ID_GSCAN_CAPABILITY\n"); -+ -+ prEventGscnCapbiblity = (P_EVENT_GSCAN_CAPABILITY_T) (prEvent->aucBuffer); -+ memcpy(prEventGscnCapbiblity, (P_EVENT_GSCAN_CAPABILITY_T) (prEvent->aucBuffer), -+ sizeof(EVENT_GSCAN_CAPABILITY_T)); -+ -+ mtk_cfg80211_vendor_get_gscan_capabilities(wiphy, prGlueInfo->prDevHandler->ieee80211_ptr, -+ prEventGscnCapbiblity, sizeof(EVENT_GSCAN_CAPABILITY_T)); -+ } -+ break; -+ -+ case EVENT_ID_GSCAN_SCAN_COMPLETE: -+ { -+ DBGLOG(SCN, INFO, "EVENT_ID_GSCAN_SCAN_COMPLETE\n"); -+ prEventGscnScnDone = (P_EVENT_GSCAN_SCAN_COMPLETE_T) (prEvent->aucBuffer); -+ memcpy(prEventGscnScnDone, (P_EVENT_GSCAN_SCAN_COMPLETE_T) (prEvent->aucBuffer), -+ sizeof(EVENT_GSCAN_SCAN_COMPLETE_T)); -+ -+ mtk_cfg80211_vendor_event_complete_scan(wiphy, prGlueInfo->prDevHandler->ieee80211_ptr, -+ prEventGscnScnDone->ucScanState); -+ } -+ break; -+ -+ case EVENT_ID_GSCAN_FULL_RESULT: -+ { -+ DBGLOG(SCN, INFO, "EVENT_ID_GSCAN_FULL_RESULT\n"); -+ -+ prEventGscnFullResult = kalMemAlloc(sizeof(WIFI_GSCAN_RESULT_T), VIR_MEM_TYPE); -+ if (prEventGscnFullResult) -+ memcpy(prEventGscnFullResult, (P_WIFI_GSCAN_RESULT_T) (prEvent->aucBuffer), -+ sizeof(WIFI_GSCAN_RESULT_T)); -+ -+ prParamGscnFullResult = kalMemAlloc(sizeof(PARAM_WIFI_GSCAN_RESULT), VIR_MEM_TYPE); -+ if (prEventGscnFullResult && prParamGscnFullResult) { -+ kalMemZero(prParamGscnFullResult, sizeof(PARAM_WIFI_GSCAN_RESULT)); -+ memcpy(prParamGscnFullResult, prEventGscnFullResult, sizeof(WIFI_GSCAN_RESULT_T)); -+ -+ mtk_cfg80211_vendor_event_full_scan_results(wiphy, -+ prGlueInfo->prDevHandler->ieee80211_ptr, -+ prParamGscnFullResult, -+ sizeof(PARAM_WIFI_GSCAN_RESULT)); -+ } -+ } -+ break; -+ -+ case EVENT_ID_GSCAN_SIGNIFICANT_CHANGE: -+ { -+ prEventGscnSignificantChange = (P_EVENT_GSCAN_SIGNIFICANT_CHANGE_T) (prEvent->aucBuffer); -+ memcpy(prEventGscnSignificantChange, (P_EVENT_GSCAN_SIGNIFICANT_CHANGE_T) (prEvent->aucBuffer), -+ sizeof(EVENT_GSCAN_SIGNIFICANT_CHANGE_T)); -+ } -+ break; -+ -+ case EVENT_ID_GSCAN_GEOFENCE_FOUND: -+ { -+ prEventGscnGeofenceFound = (P_EVENT_GSCAN_SIGNIFICANT_CHANGE_T) (prEvent->aucBuffer); -+ memcpy(prEventGscnGeofenceFound, (P_EVENT_GSCAN_SIGNIFICANT_CHANGE_T) (prEvent->aucBuffer), -+ sizeof(EVENT_GSCAN_SIGNIFICANT_CHANGE_T)); -+ } -+ break; -+ -+ default: -+ DBGLOG(SCN, INFO, "not GSCN event ????\n"); -+ break; -+ } -+ -+ DBGLOG(SCN, INFO, "Done with GSCN event handling\n"); -+ return real_num; /* cfg80211_vendor_cmd_reply(skb); */ -+ -+nla_put_failure: -+ if (skb != NULL) -+ kfree_skb(skb); -+ DBGLOG(SCN, INFO, "nla_put_failure\n"); -+ return 0; /* cfg80211_vendor_cmd_reply(skb); */ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Process HIF event packet -+* -+* @param prAdapter pointer to the Adapter handler -+* @param prSWRfb the RFB to receive rx data -+* -+* @return (none) -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicRxProcessEventPacket(IN P_ADAPTER_T prAdapter, IN OUT P_SW_RFB_T prSwRfb) -+{ -+ P_CMD_INFO_T prCmdInfo; -+ P_MSDU_INFO_T prMsduInfo; -+ P_WIFI_EVENT_T prEvent; -+ P_GLUE_INFO_T prGlueInfo; -+ -+ DEBUGFUNC("nicRxProcessEventPacket"); -+ -+ ASSERT(prAdapter); -+ ASSERT(prSwRfb); -+ -+ prEvent = (P_WIFI_EVENT_T) prSwRfb->pucRecvBuff; -+ prGlueInfo = prAdapter->prGlueInfo; -+ -+ DBGLOG(RX, EVENT, "prEvent->ucEID = 0x%02x\n", prEvent->ucEID); -+ /* Event Handling */ -+ switch (prEvent->ucEID) { -+ case EVENT_ID_CMD_RESULT: -+ prCmdInfo = nicGetPendingCmdInfo(prAdapter, prEvent->ucSeqNum); -+ -+ if (prCmdInfo != NULL) { -+ P_EVENT_CMD_RESULT prCmdResult; -+ -+ prCmdResult = (P_EVENT_CMD_RESULT) ((PUINT_8) prEvent + EVENT_HDR_SIZE); -+ -+ /* CMD_RESULT should be only in response to Set commands */ -+ ASSERT(prCmdInfo->fgSetQuery == FALSE || prCmdInfo->fgNeedResp == TRUE); -+ -+ if (prCmdResult->ucStatus == 0) { /* success */ -+ if (prCmdInfo->pfCmdDoneHandler) { -+ prCmdInfo->pfCmdDoneHandler(prAdapter, prCmdInfo, prEvent->aucBuffer); -+ } else if (prCmdInfo->fgIsOid == TRUE) { -+ kalOidComplete(prAdapter->prGlueInfo, prCmdInfo->fgSetQuery, 0, -+ WLAN_STATUS_SUCCESS); -+ } -+ } else if (prCmdResult->ucStatus == 1) { /* reject */ -+ if (prCmdInfo->fgIsOid == TRUE) -+ kalOidComplete(prAdapter->prGlueInfo, prCmdInfo->fgSetQuery, 0, -+ WLAN_STATUS_FAILURE); -+ } else if (prCmdResult->ucStatus == 2) { /* unknown CMD */ -+ if (prCmdInfo->fgIsOid == TRUE) -+ kalOidComplete(prAdapter->prGlueInfo, prCmdInfo->fgSetQuery, 0, -+ WLAN_STATUS_NOT_SUPPORTED); -+ } -+ /* return prCmdInfo */ -+ cmdBufFreeCmdInfo(prAdapter, prCmdInfo); -+ } -+ -+ break; -+ -+#if 0 -+ case EVENT_ID_CONNECTION_STATUS: -+ /* OBSELETE */ -+ { -+ P_EVENT_CONNECTION_STATUS prConnectionStatus; -+ -+ prConnectionStatus = (P_EVENT_CONNECTION_STATUS) (prEvent->aucBuffer); -+ -+ DbgPrint("RX EVENT: EVENT_ID_CONNECTION_STATUS = %d\n", prConnectionStatus->ucMediaStatus); -+ if (prConnectionStatus->ucMediaStatus == PARAM_MEDIA_STATE_DISCONNECTED) { -+ /* disconnected */ -+ if (kalGetMediaStateIndicated(prGlueInfo) != PARAM_MEDIA_STATE_DISCONNECTED) { -+ -+ kalIndicateStatusAndComplete(prGlueInfo, WLAN_STATUS_MEDIA_DISCONNECT, NULL, 0); -+ -+ prAdapter->rWlanInfo.u4SysTime = kalGetTimeTick(); -+ } -+ } else if (prConnectionStatus->ucMediaStatus == PARAM_MEDIA_STATE_CONNECTED) { -+ /* connected */ -+ prAdapter->rWlanInfo.u4SysTime = kalGetTimeTick(); -+ -+ /* fill information for association result */ -+ prAdapter->rWlanInfo.rCurrBssId.rSsid.u4SsidLen = prConnectionStatus->ucSsidLen; -+ kalMemCopy(prAdapter->rWlanInfo.rCurrBssId.rSsid.aucSsid, -+ prConnectionStatus->aucSsid, prConnectionStatus->ucSsidLen); -+ -+ kalMemCopy(prAdapter->rWlanInfo.rCurrBssId.arMacAddress, -+ prConnectionStatus->aucBssid, MAC_ADDR_LEN); -+ -+ /* @FIXME */ -+ prAdapter->rWlanInfo.rCurrBssId.u4Privacy = prConnectionStatus->ucEncryptStatus; -+ prAdapter->rWlanInfo.rCurrBssId.rRssi = 0; /* @FIXME */ -+ /* @FIXME */ -+ prAdapter->rWlanInfo.rCurrBssId.eNetworkTypeInUse = PARAM_NETWORK_TYPE_AUTOMODE; -+ prAdapter->rWlanInfo.rCurrBssId.rConfiguration.u4BeaconPeriod -+ = prConnectionStatus->u2BeaconPeriod; -+ prAdapter->rWlanInfo.rCurrBssId.rConfiguration.u4ATIMWindow -+ = prConnectionStatus->u2ATIMWindow; -+ prAdapter->rWlanInfo.rCurrBssId.rConfiguration.u4DSConfig -+ = prConnectionStatus->u4FreqInKHz; -+ prAdapter->rWlanInfo.ucNetworkType = prConnectionStatus->ucNetworkType; -+ -+ switch (prConnectionStatus->ucInfraMode) { -+ case 0: -+ prAdapter->rWlanInfo.rCurrBssId.eOpMode = NET_TYPE_IBSS; -+ break; -+ case 1: -+ prAdapter->rWlanInfo.rCurrBssId.eOpMode = NET_TYPE_INFRA; -+ break; -+ case 2: -+ default: -+ prAdapter->rWlanInfo.rCurrBssId.eOpMode = NET_TYPE_AUTO_SWITCH; -+ break; -+ } -+ /* always indicate to OS according to MSDN (re-association/roaming) */ -+ kalIndicateStatusAndComplete(prGlueInfo, WLAN_STATUS_MEDIA_CONNECT, NULL, 0); -+ } -+ } -+ break; -+ -+ case EVENT_ID_SCAN_RESULT: -+ /* OBSELETE */ -+ break; -+#endif -+ -+ case EVENT_ID_RX_ADDBA: -+ /* The FW indicates that an RX BA agreement will be established */ -+ qmHandleEventRxAddBa(prAdapter, prEvent); -+ break; -+ -+ case EVENT_ID_RX_DELBA: -+ /* The FW indicates that an RX BA agreement has been deleted */ -+ qmHandleEventRxDelBa(prAdapter, prEvent); -+ break; -+ -+ case EVENT_ID_LINK_QUALITY: -+#if CFG_ENABLE_WIFI_DIRECT && CFG_SUPPORT_P2P_RSSI_QUERY -+ if (prEvent->u2PacketLen == EVENT_HDR_SIZE + sizeof(EVENT_LINK_QUALITY_EX)) { -+ P_EVENT_LINK_QUALITY_EX prLqEx = (P_EVENT_LINK_QUALITY_EX) (prEvent->aucBuffer); -+ -+ if (prLqEx->ucIsLQ0Rdy) -+ nicUpdateLinkQuality(prAdapter, NETWORK_TYPE_AIS_INDEX, (P_EVENT_LINK_QUALITY) prLqEx); -+ if (prLqEx->ucIsLQ1Rdy) -+ nicUpdateLinkQuality(prAdapter, NETWORK_TYPE_P2P_INDEX, (P_EVENT_LINK_QUALITY) prLqEx); -+ } else { -+ /* For old FW, P2P may invoke link quality query, and make driver flag becone TRUE. */ -+ DBGLOG(P2P, WARN, "Old FW version, not support P2P RSSI query.\n"); -+ -+ /* Must not use NETWORK_TYPE_P2P_INDEX, cause the structure is mismatch. */ -+ nicUpdateLinkQuality(prAdapter, NETWORK_TYPE_AIS_INDEX, -+ (P_EVENT_LINK_QUALITY) (prEvent->aucBuffer)); -+ } -+#else -+ nicUpdateLinkQuality(prAdapter, NETWORK_TYPE_AIS_INDEX, (P_EVENT_LINK_QUALITY) (prEvent->aucBuffer)); -+#endif -+ -+ /* command response handling */ -+ prCmdInfo = nicGetPendingCmdInfo(prAdapter, prEvent->ucSeqNum); -+ -+ if (prCmdInfo != NULL) { -+ if (prCmdInfo->pfCmdDoneHandler) -+ prCmdInfo->pfCmdDoneHandler(prAdapter, prCmdInfo, prEvent->aucBuffer); -+ else if (prCmdInfo->fgIsOid) -+ kalOidComplete(prAdapter->prGlueInfo, prCmdInfo->fgSetQuery, 0, WLAN_STATUS_SUCCESS); -+ /* return prCmdInfo */ -+ cmdBufFreeCmdInfo(prAdapter, prCmdInfo); -+ } -+#ifndef LINUX -+ if (prAdapter->rWlanInfo.eRssiTriggerType == ENUM_RSSI_TRIGGER_GREATER && -+ prAdapter->rWlanInfo.rRssiTriggerValue >= (PARAM_RSSI) (prAdapter->rLinkQuality.cRssi)) { -+ prAdapter->rWlanInfo.eRssiTriggerType = ENUM_RSSI_TRIGGER_TRIGGERED; -+ -+ kalIndicateStatusAndComplete(prGlueInfo, -+ WLAN_STATUS_MEDIA_SPECIFIC_INDICATION, -+ (PVOID)&(prAdapter->rWlanInfo.rRssiTriggerValue), -+ sizeof(PARAM_RSSI)); -+ } else if (prAdapter->rWlanInfo.eRssiTriggerType == ENUM_RSSI_TRIGGER_LESS -+ && prAdapter->rWlanInfo.rRssiTriggerValue <= (PARAM_RSSI) (prAdapter->rLinkQuality.cRssi)) { -+ prAdapter->rWlanInfo.eRssiTriggerType = ENUM_RSSI_TRIGGER_TRIGGERED; -+ -+ kalIndicateStatusAndComplete(prGlueInfo, -+ WLAN_STATUS_MEDIA_SPECIFIC_INDICATION, -+ (PVOID)&(prAdapter->rWlanInfo.rRssiTriggerValue), -+ sizeof(PARAM_RSSI)); -+ } -+#endif -+ -+ break; -+ -+ case EVENT_ID_MIC_ERR_INFO: -+ { -+ P_EVENT_MIC_ERR_INFO prMicError; -+ /* P_PARAM_AUTH_EVENT_T prAuthEvent; */ -+ P_STA_RECORD_T prStaRec; -+ -+ DBGLOG(RSN, EVENT, "EVENT_ID_MIC_ERR_INFO\n"); -+ -+ prMicError = (P_EVENT_MIC_ERR_INFO) (prEvent->aucBuffer); -+ prStaRec = cnmGetStaRecByAddress(prAdapter, -+ (UINT_8) NETWORK_TYPE_AIS_INDEX, -+ prAdapter->rWlanInfo.rCurrBssId.arMacAddress); -+ ASSERT(prStaRec); -+ -+ if (prStaRec) -+ rsnTkipHandleMICFailure(prAdapter, prStaRec, (BOOLEAN) prMicError->u4Flags); -+ else -+ DBGLOG(RSN, WARN, "No STA rec!!\n"); -+#if 0 -+ prAuthEvent = (P_PARAM_AUTH_EVENT_T) prAdapter->aucIndicationEventBuffer; -+ -+ /* Status type: Authentication Event */ -+ prAuthEvent->rStatus.eStatusType = ENUM_STATUS_TYPE_AUTHENTICATION; -+ -+ /* Authentication request */ -+ prAuthEvent->arRequest[0].u4Length = sizeof(PARAM_AUTH_REQUEST_T); -+ kalMemCopy((PVOID) prAuthEvent->arRequest[0].arBssid, -+ (PVOID) prAdapter->rWlanInfo.rCurrBssId.arMacAddress, -+ /* whsu:Todo? */PARAM_MAC_ADDR_LEN); -+ -+ if (prMicError->u4Flags != 0) -+ prAuthEvent->arRequest[0].u4Flags = PARAM_AUTH_REQUEST_GROUP_ERROR; -+ else -+ prAuthEvent->arRequest[0].u4Flags = PARAM_AUTH_REQUEST_PAIRWISE_ERROR; -+ -+ kalIndicateStatusAndComplete(prAdapter->prGlueInfo, -+ WLAN_STATUS_MEDIA_SPECIFIC_INDICATION, -+ (PVOID) prAuthEvent, -+ sizeof(PARAM_STATUS_INDICATION_T) + sizeof(PARAM_AUTH_REQUEST_T)); -+#endif -+ } -+ break; -+ -+ case EVENT_ID_ASSOC_INFO: -+ { -+ P_EVENT_ASSOC_INFO prAssocInfo; -+ -+ prAssocInfo = (P_EVENT_ASSOC_INFO) (prEvent->aucBuffer); -+ -+ kalHandleAssocInfo(prAdapter->prGlueInfo, prAssocInfo); -+ } -+ break; -+ -+ case EVENT_ID_802_11_PMKID: -+ { -+ P_PARAM_AUTH_EVENT_T prAuthEvent; -+ PUINT_8 cp; -+ UINT_32 u4LenOfUsedBuffer; -+ -+ prAuthEvent = (P_PARAM_AUTH_EVENT_T) prAdapter->aucIndicationEventBuffer; -+ -+ prAuthEvent->rStatus.eStatusType = ENUM_STATUS_TYPE_CANDIDATE_LIST; -+ -+ u4LenOfUsedBuffer = (UINT_32) (prEvent->u2PacketLen - 8); -+ -+ prAuthEvent->arRequest[0].u4Length = u4LenOfUsedBuffer; -+ -+ cp = (PUINT_8) &prAuthEvent->arRequest[0]; -+ -+ /* Status type: PMKID Candidatelist Event */ -+ kalMemCopy(cp, (P_EVENT_PMKID_CANDIDATE_LIST_T) (prEvent->aucBuffer), prEvent->u2PacketLen - 8); -+ -+ kalIndicateStatusAndComplete(prAdapter->prGlueInfo, -+ WLAN_STATUS_MEDIA_SPECIFIC_INDICATION, -+ (PVOID) prAuthEvent, -+ sizeof(PARAM_STATUS_INDICATION_T) + u4LenOfUsedBuffer); -+ } -+ break; -+ -+#if 0 -+ case EVENT_ID_ACTIVATE_STA_REC_T: -+ { -+ P_EVENT_ACTIVATE_STA_REC_T prActivateStaRec; -+ -+ prActivateStaRec = (P_EVENT_ACTIVATE_STA_REC_T) (prEvent->aucBuffer); -+ -+ DbgPrint("RX EVENT: EVENT_ID_ACTIVATE_STA_REC_T Index:%d, MAC:[%pM]\n", -+ prActivateStaRec->ucStaRecIdx, prActivateStaRec->aucMacAddr); -+ -+ qmActivateStaRec(prAdapter, -+ (UINT_32) prActivateStaRec->ucStaRecIdx, -+ ((prActivateStaRec->fgIsQoS) ? TRUE : FALSE), -+ prActivateStaRec->ucNetworkTypeIndex, -+ ((prActivateStaRec->fgIsAP) ? TRUE : FALSE), prActivateStaRec->aucMacAddr); -+ -+ } -+ break; -+ -+ case EVENT_ID_DEACTIVATE_STA_REC_T: -+ { -+ P_EVENT_DEACTIVATE_STA_REC_T prDeactivateStaRec; -+ -+ prDeactivateStaRec = (P_EVENT_DEACTIVATE_STA_REC_T) (prEvent->aucBuffer); -+ -+ DbgPrint("RX EVENT: EVENT_ID_DEACTIVATE_STA_REC_T Index:%d, MAC:[%pM]\n", -+ prDeactivateStaRec->ucStaRecIdx, prActivateStaRec->aucMacAddr); -+ -+ qmDeactivateStaRec(prAdapter, prDeactivateStaRec->ucStaRecIdx); -+ } -+ break; -+#endif -+ -+ case EVENT_ID_SCAN_DONE: -+ scnEventScanDone(prAdapter, (P_EVENT_SCAN_DONE) (prEvent->aucBuffer)); -+ break; -+ -+ case EVENT_ID_TX_DONE_STATUS: -+ STATS_TX_PKT_DONE_INFO_DISPLAY(prAdapter, prEvent->aucBuffer); -+ break; -+ -+ case EVENT_ID_TX_DONE: -+ { -+ P_EVENT_TX_DONE_T prTxDone; -+ -+ prTxDone = (P_EVENT_TX_DONE_T) (prEvent->aucBuffer); -+ if (prTxDone->ucStatus) -+ DBGLOG(RX, INFO, "EVENT_ID_TX_DONE PacketSeq:%u ucStatus: %u SN: %u\n", -+ prTxDone->ucPacketSeq, prTxDone->ucStatus, prTxDone->u2SequenceNumber); -+ -+ /* call related TX Done Handler */ -+ prMsduInfo = nicGetPendingTxMsduInfo(prAdapter, prTxDone->ucPacketSeq); -+ -+#if CFG_SUPPORT_802_11V_TIMING_MEASUREMENT -+ DBGLOG(RX, TRACE, "EVENT_ID_TX_DONE u4TimeStamp = %x u2AirDelay = %x\n", -+ prTxDone->au4Reserved1, prTxDone->au4Reserved2); -+ -+ wnmReportTimingMeas(prAdapter, prMsduInfo->ucStaRecIndex, -+ prTxDone->au4Reserved1, prTxDone->au4Reserved1 + prTxDone->au4Reserved2); -+#endif -+ -+ if (prMsduInfo) { -+ prMsduInfo->pfTxDoneHandler(prAdapter, prMsduInfo, -+ (ENUM_TX_RESULT_CODE_T) (prTxDone->ucStatus)); -+ -+ cnmMgtPktFree(prAdapter, prMsduInfo); -+ } -+ } -+ break; -+ case EVENT_ID_SLEEPY_NOTIFY: -+ { -+ P_EVENT_SLEEPY_NOTIFY prEventSleepyNotify; -+ -+ prEventSleepyNotify = (P_EVENT_SLEEPY_NOTIFY) (prEvent->aucBuffer); -+ -+ /* DBGLOG(RX, INFO, ("ucSleepyState = %d\n", prEventSleepyNotify->ucSleepyState)); */ -+ -+ prAdapter->fgWiFiInSleepyState = (BOOLEAN) (prEventSleepyNotify->ucSleepyState); -+ } -+ break; -+ case EVENT_ID_BT_OVER_WIFI: -+#if CFG_ENABLE_BT_OVER_WIFI -+ { -+ UINT_8 aucTmp[sizeof(AMPC_EVENT) + sizeof(BOW_LINK_DISCONNECTED)]; -+ P_EVENT_BT_OVER_WIFI prEventBtOverWifi; -+ P_AMPC_EVENT prBowEvent; -+ P_BOW_LINK_CONNECTED prBowLinkConnected; -+ P_BOW_LINK_DISCONNECTED prBowLinkDisconnected; -+ -+ prEventBtOverWifi = (P_EVENT_BT_OVER_WIFI) (prEvent->aucBuffer); -+ -+ /* construct event header */ -+ prBowEvent = (P_AMPC_EVENT) aucTmp; -+ -+ if (prEventBtOverWifi->ucLinkStatus == 0) { -+ /* Connection */ -+ prBowEvent->rHeader.ucEventId = BOW_EVENT_ID_LINK_CONNECTED; -+ prBowEvent->rHeader.ucSeqNumber = 0; -+ prBowEvent->rHeader.u2PayloadLength = sizeof(BOW_LINK_CONNECTED); -+ -+ /* fill event body */ -+ prBowLinkConnected = (P_BOW_LINK_CONNECTED) (prBowEvent->aucPayload); -+ prBowLinkConnected->rChannel.ucChannelNum = prEventBtOverWifi->ucSelectedChannel; -+ kalMemZero(prBowLinkConnected->aucPeerAddress, MAC_ADDR_LEN); /* @FIXME */ -+ -+ kalIndicateBOWEvent(prAdapter->prGlueInfo, prBowEvent); -+ } else { -+ /* Disconnection */ -+ prBowEvent->rHeader.ucEventId = BOW_EVENT_ID_LINK_DISCONNECTED; -+ prBowEvent->rHeader.ucSeqNumber = 0; -+ prBowEvent->rHeader.u2PayloadLength = sizeof(BOW_LINK_DISCONNECTED); -+ -+ /* fill event body */ -+ prBowLinkDisconnected = (P_BOW_LINK_DISCONNECTED) (prBowEvent->aucPayload); -+ prBowLinkDisconnected->ucReason = 0; /* @FIXME */ -+ kalMemZero(prBowLinkDisconnected->aucPeerAddress, MAC_ADDR_LEN); /* @FIXME */ -+ -+ kalIndicateBOWEvent(prAdapter->prGlueInfo, prBowEvent); -+ } -+ } -+ break; -+#endif -+ case EVENT_ID_STATISTICS: -+ /* buffer statistics for further query */ -+ prAdapter->fgIsStatValid = TRUE; -+ prAdapter->rStatUpdateTime = kalGetTimeTick(); -+ kalMemCopy(&prAdapter->rStatStruct, prEvent->aucBuffer, sizeof(EVENT_STATISTICS)); -+ -+ /* command response handling */ -+ prCmdInfo = nicGetPendingCmdInfo(prAdapter, prEvent->ucSeqNum); -+ -+ if (prCmdInfo != NULL) { -+ if (prCmdInfo->pfCmdDoneHandler) -+ prCmdInfo->pfCmdDoneHandler(prAdapter, prCmdInfo, prEvent->aucBuffer); -+ else if (prCmdInfo->fgIsOid) -+ kalOidComplete(prAdapter->prGlueInfo, prCmdInfo->fgSetQuery, 0, WLAN_STATUS_SUCCESS); -+ /* return prCmdInfo */ -+ cmdBufFreeCmdInfo(prAdapter, prCmdInfo); -+ } -+ -+ break; -+ -+ case EVENT_ID_CH_PRIVILEGE: -+ cnmChMngrHandleChEvent(prAdapter, prEvent); -+ break; -+ -+ case EVENT_ID_BSS_ABSENCE_PRESENCE: -+ qmHandleEventBssAbsencePresence(prAdapter, prEvent); -+ break; -+ -+ case EVENT_ID_STA_CHANGE_PS_MODE: -+ qmHandleEventStaChangePsMode(prAdapter, prEvent); -+ break; -+#if CFG_ENABLE_WIFI_DIRECT -+ case EVENT_ID_STA_UPDATE_FREE_QUOTA: -+ qmHandleEventStaUpdateFreeQuota(prAdapter, prEvent); -+ break; -+#endif -+ case EVENT_ID_BSS_BEACON_TIMEOUT: -+ if (prAdapter->fgDisBcnLostDetection == FALSE) { -+ P_EVENT_BSS_BEACON_TIMEOUT_T prEventBssBeaconTimeout; -+ -+ prEventBssBeaconTimeout = (P_EVENT_BSS_BEACON_TIMEOUT_T) (prEvent->aucBuffer); -+ -+ DBGLOG(RX, INFO, "Beacon Timeout Reason = %u\n", prEventBssBeaconTimeout->ucReason); -+ -+ if (prEventBssBeaconTimeout->ucNetTypeIndex == NETWORK_TYPE_AIS_INDEX) { -+ /* Request stats report before beacon timeout */ -+ P_BSS_INFO_T prBssInfo; -+ P_STA_RECORD_T prStaRec; -+ -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ if (prBssInfo) { -+ prStaRec = cnmGetStaRecByAddress(prAdapter, -+ NETWORK_TYPE_AIS_INDEX, -+ prBssInfo->aucBSSID); -+ if (prStaRec) -+ STATS_ENV_REPORT_DETECT(prAdapter, prStaRec->ucIndex); -+ } -+ aisBssBeaconTimeout(prAdapter); -+ } -+#if CFG_ENABLE_WIFI_DIRECT -+ else if ((prAdapter->fgIsP2PRegistered) && -+ (prEventBssBeaconTimeout->ucNetTypeIndex == NETWORK_TYPE_P2P_INDEX)) -+ -+ p2pFsmRunEventBeaconTimeout(prAdapter); -+#endif -+ else { -+ DBGLOG(RX, ERROR, "EVENT_ID_BSS_BEACON_TIMEOUT: (ucNetTypeIdx = %d)\n", -+ prEventBssBeaconTimeout->ucNetTypeIndex); -+ } -+ } -+ -+ break; -+ case EVENT_ID_UPDATE_NOA_PARAMS: -+#if CFG_ENABLE_WIFI_DIRECT -+ if (prAdapter->fgIsP2PRegistered) { -+ P_EVENT_UPDATE_NOA_PARAMS_T prEventUpdateNoaParam; -+ -+ prEventUpdateNoaParam = (P_EVENT_UPDATE_NOA_PARAMS_T) (prEvent->aucBuffer); -+ -+ if (prEventUpdateNoaParam->ucNetTypeIndex == NETWORK_TYPE_P2P_INDEX) { -+ p2pProcessEvent_UpdateNOAParam(prAdapter, -+ prEventUpdateNoaParam->ucNetTypeIndex, -+ prEventUpdateNoaParam); -+ } else { -+ ASSERT(0); -+ } -+ } -+#else -+ ASSERT(0); -+#endif -+ break; -+ -+ case EVENT_ID_STA_AGING_TIMEOUT: -+#if CFG_ENABLE_WIFI_DIRECT -+ { -+ if (prAdapter->fgDisStaAgingTimeoutDetection == FALSE) { -+ P_EVENT_STA_AGING_TIMEOUT_T prEventStaAgingTimeout; -+ P_STA_RECORD_T prStaRec; -+ P_BSS_INFO_T prBssInfo = (P_BSS_INFO_T) NULL; -+ -+ prEventStaAgingTimeout = (P_EVENT_STA_AGING_TIMEOUT_T) (prEvent->aucBuffer); -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prEventStaAgingTimeout->ucStaRecIdx); -+ if (prStaRec == NULL) -+ break; -+ -+ DBGLOG(RX, INFO, "EVENT_ID_STA_AGING_TIMEOUT %u %pM\n", -+ prEventStaAgingTimeout->ucStaRecIdx, -+ prStaRec->aucMacAddr); -+ -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]); -+ -+ bssRemoveStaRecFromClientList(prAdapter, prBssInfo, prStaRec); -+ -+ /* Call False Auth */ -+ if (prAdapter->fgIsP2PRegistered) -+ p2pFuncDisconnect(prAdapter, prStaRec, TRUE, REASON_CODE_DISASSOC_INACTIVITY); -+ -+ } -+ /* gDisStaAgingTimeoutDetection */ -+ } -+#endif -+ break; -+ -+ case EVENT_ID_AP_OBSS_STATUS: -+#if CFG_ENABLE_WIFI_DIRECT -+ if (prAdapter->fgIsP2PRegistered) -+ rlmHandleObssStatusEventPkt(prAdapter, (P_EVENT_AP_OBSS_STATUS_T) prEvent->aucBuffer); -+#endif -+ break; -+ -+ case EVENT_ID_ROAMING_STATUS: -+#if CFG_SUPPORT_ROAMING -+ { -+ P_ROAMING_PARAM_T prParam; -+ -+ prParam = (P_ROAMING_PARAM_T) (prEvent->aucBuffer); -+ roamingFsmProcessEvent(prAdapter, prParam); -+ } -+#endif /* CFG_SUPPORT_ROAMING */ -+ break; -+ case EVENT_ID_SEND_DEAUTH: -+ { -+ P_WLAN_MAC_HEADER_T prWlanMacHeader; -+ P_STA_RECORD_T prStaRec; -+ -+ prWlanMacHeader = (P_WLAN_MAC_HEADER_T) &prEvent->aucBuffer[0]; -+ DBGLOG(RSN, INFO, "nicRx: aucAddr1: %pM, nicRx: aucAddr2: %pM\n", -+ prWlanMacHeader->aucAddr1, prWlanMacHeader->aucAddr2); -+ prStaRec = cnmGetStaRecByAddress(prAdapter, NETWORK_TYPE_AIS_INDEX, prWlanMacHeader->aucAddr2); -+ if (prStaRec != NULL && prStaRec->ucStaState == STA_STATE_3) { -+ DBGLOG(RSN, WARN, "Ignore Deauth for Rx Class 3 error!\n"); -+ } else { -+ /* receive packets without StaRec */ -+ prSwRfb->pvHeader = (P_WLAN_MAC_HEADER_T) &prEvent->aucBuffer[0]; -+ if (WLAN_STATUS_SUCCESS == authSendDeauthFrame(prAdapter, -+ NULL, -+ prSwRfb, -+ REASON_CODE_CLASS_3_ERR, -+ (PFN_TX_DONE_HANDLER) NULL)) -+ DBGLOG(RSN, INFO, "Send Deauth for Rx Class3 Error\n"); -+ else -+ DBGLOG(RSN, WARN, "failed to send deauth for Rx class3 error\n"); -+ } -+ } -+ break; -+ -+#if CFG_SUPPORT_RDD_TEST_MODE -+ case EVENT_ID_UPDATE_RDD_STATUS: -+ { -+ P_EVENT_RDD_STATUS_T prEventRddStatus; -+ -+ prEventRddStatus = (P_EVENT_RDD_STATUS_T) (prEvent->aucBuffer); -+ -+ prAdapter->ucRddStatus = prEventRddStatus->ucRddStatus; -+ } -+ -+ break; -+#endif -+ -+#if CFG_SUPPORT_BCM && CFG_SUPPORT_BCM_BWCS -+ case EVENT_ID_UPDATE_BWCS_STATUS: -+ { -+ P_PTA_IPC_T prEventBwcsStatus; -+ -+ prEventBwcsStatus = (P_PTA_IPC_T) (prEvent->aucBuffer); -+ -+#if CFG_SUPPORT_BCM_BWCS_DEBUG -+ DBGLOG(RSN, INFO, -+ "BCM BWCS Event: %02x%02x%02x%02x\n", -+ prEventBwcsStatus->u.aucBTPParams[0], prEventBwcsStatus->u.aucBTPParams[1], -+ prEventBwcsStatus->u.aucBTPParams[2], prEventBwcsStatus->u.aucBTPParams[3]); -+ -+ DBGLOG(RSN, INFO, -+ "BCM BWCS Event: BTPParams[0]:%02x, BTPParams[1]:%02x, BTPParams[2]:%02x, BTPParams[3]:%02x\n", -+ prEventBwcsStatus->u.aucBTPParams[0], prEventBwcsStatus->u.aucBTPParams[1], -+ prEventBwcsStatus->u.aucBTPParams[2], prEventBwcsStatus->u.aucBTPParams[3]); -+#endif -+ -+ kalIndicateStatusAndComplete(prAdapter->prGlueInfo, -+ WLAN_STATUS_BWCS_UPDATE, -+ (PVOID) prEventBwcsStatus, sizeof(PTA_IPC_T)); -+ } -+ -+ break; -+ -+ case EVENT_ID_UPDATE_BCM_DEBUG: -+ { -+ P_PTA_IPC_T prEventBwcsStatus; -+ -+ prEventBwcsStatus = (P_PTA_IPC_T) (prEvent->aucBuffer); -+ -+#if CFG_SUPPORT_BCM_BWCS_DEBUG -+ DBGLOG(RSN, INFO, -+ "BCM FW status: %02x%02x%02x%02x\n", -+ prEventBwcsStatus->u.aucBTPParams[0], prEventBwcsStatus->u.aucBTPParams[1], -+ prEventBwcsStatus->u.aucBTPParams[2], prEventBwcsStatus->u.aucBTPParams[3]); -+ -+ DBGLOG(RSN, INFO, -+ "BCM FW status: BTPParams[0]:%02x, BTPParams[1]:%02x, BTPParams[2]:%02x, BTPParams[3]:%02x\n", -+ prEventBwcsStatus->u.aucBTPParams[0], prEventBwcsStatus->u.aucBTPParams[1], -+ prEventBwcsStatus->u.aucBTPParams[2], prEventBwcsStatus->u.aucBTPParams[3]; -+#endif -+ } -+ -+ break; -+#endif -+ -+ case EVENT_ID_DEBUG_CODE: /* only for debug */ -+ { -+ UINT_32 u4CodeId; -+ -+ DBGLOG(RSN, INFO, "[wlan-fw] function sequence: "); -+ for (u4CodeId = 0; u4CodeId < 1000; u4CodeId++) -+ DBGLOG(RSN, INFO, "%d ", prEvent->aucBuffer[u4CodeId]); -+ DBGLOG(RSN, INFO, "\n\n"); -+ } -+ break; -+ -+ case EVENT_ID_RFTEST_READY: -+ -+ /* command response handling */ -+ prCmdInfo = nicGetPendingCmdInfo(prAdapter, prEvent->ucSeqNum); -+ -+ if (prCmdInfo != NULL) { -+ if (prCmdInfo->pfCmdDoneHandler) -+ prCmdInfo->pfCmdDoneHandler(prAdapter, prCmdInfo, prEvent->aucBuffer); -+ else if (prCmdInfo->fgIsOid) -+ kalOidComplete(prAdapter->prGlueInfo, prCmdInfo->fgSetQuery, 0, WLAN_STATUS_SUCCESS); -+ /* return prCmdInfo */ -+ cmdBufFreeCmdInfo(prAdapter, prCmdInfo); -+ } -+ -+ break; -+ -+ case EVENT_ID_GSCAN_SCAN_AVAILABLE: -+ case EVENT_ID_GSCAN_CAPABILITY: -+ case EVENT_ID_GSCAN_SCAN_COMPLETE: -+ case EVENT_ID_GSCAN_FULL_RESULT: -+ case EVENT_ID_GSCAN_SIGNIFICANT_CHANGE: -+ case EVENT_ID_GSCAN_GEOFENCE_FOUND: -+ nicRxProcessGSCNEvent(prAdapter, prSwRfb); -+ break; -+ -+ case EVENT_ID_GSCAN_RESULT: -+ { -+ -+ UINT_8 realnum = 0; -+ -+ DBGLOG(SCN, TRACE, "nicRxProcessGSCNEvent ----->\n"); -+ realnum = nicRxProcessGSCNEvent(prAdapter, prSwRfb); -+ DBGLOG(SCN, TRACE, "nicRxProcessGSCNEvent <-----\n"); -+ -+#if 0 /* workaround for FW events cnt mis-match with the actual reqirements from wifi_hal */ -+ if (g_GetResultsCmdCnt == 0) { -+ DBGLOG(SCN, INFO, -+ "FW report events more than the wifi_hal asked number, buffer the results\n"); -+ UINT_8 i = 0; -+ -+ for (i = 0; i < MAX_BUFFERED_GSCN_RESULTS; i++) { -+#if 1 -+ if (!g_arGscanResultsIndicateNumber[i]) { -+ DBGLOG(SCN, INFO, -+ "found available index %d to insert results number %d into buffer\r\n", -+ i, realnum); -+ -+ g_arGscnResultsTempBuffer[i] = prSwRfb; -+ g_arGscanResultsIndicateNumber[i] = realnum; -+ g_GetResultsBufferedCnt++; -+ fgKeepprSwRfb = TRUE; -+ DBGLOG(SCN, INFO, "results buffered in index[%d] \r\n", i); -+ break; -+ } -+#endif -+ } -+ if (i == MAX_BUFFERED_GSCN_RESULTS) -+ DBGLOG(SCN, INFO, -+ "Gscn results buffer is full(all valid), no space to buffer result\r\n"); -+ } else if (g_GetResultsCmdCnt > 0) { -+ DBGLOG(SCN, INFO, "FW report events match the wifi_hal asked number\n"); -+ g_GetResultsCmdCnt--; -+ } else -+ DBGLOG(SCN, INFO, "g_GetResultsCmdCnt < 0 ??? unexpected case\n"); -+#endif -+ /* end of workaround */ -+ -+ } -+ break; -+ -+ case EVENT_ID_NLO_DONE: -+ prAdapter->rWifiVar.rScanInfo.fgPscnOnnning = FALSE; -+ -+ DBGLOG(INIT, INFO, "EVENT_ID_NLO_DONE\n"); -+ scnEventNloDone(prAdapter, (P_EVENT_NLO_DONE_T) (prEvent->aucBuffer)); -+ -+ break; -+ -+#if CFG_SUPPORT_BATCH_SCAN -+ case EVENT_ID_BATCH_RESULT: -+ DBGLOG(SCN, TRACE, "Got EVENT_ID_BATCH_RESULT"); -+ -+ /* command response handling */ -+ prCmdInfo = nicGetPendingCmdInfo(prAdapter, prEvent->ucSeqNum); -+ -+ if (prCmdInfo != NULL) { -+ if (prCmdInfo->pfCmdDoneHandler) -+ prCmdInfo->pfCmdDoneHandler(prAdapter, prCmdInfo, prEvent->aucBuffer); -+ else if (prCmdInfo->fgIsOid) -+ kalOidComplete(prAdapter->prGlueInfo, prCmdInfo->fgSetQuery, 0, WLAN_STATUS_SUCCESS); -+ /* return prCmdInfo */ -+ cmdBufFreeCmdInfo(prAdapter, prCmdInfo); -+ } -+ -+ break; -+#endif /* CFG_SUPPORT_BATCH_SCAN */ -+ -+#if (CFG_SUPPORT_TDLS == 1) -+ case EVENT_ID_TDLS: -+ TdlsexEventHandle(prAdapter->prGlueInfo, -+ (UINT8 *) prEvent->aucBuffer, (UINT32) (prEvent->u2PacketLen - 8)); -+ break; -+#endif /* CFG_SUPPORT_TDLS */ -+ -+#if (CFG_SUPPORT_STATISTICS == 1) -+ case EVENT_ID_STATS_ENV: -+ statsEventHandle(prAdapter->prGlueInfo, -+ (UINT8 *) prEvent->aucBuffer, (UINT32) (prEvent->u2PacketLen - 8)); -+ break; -+#endif /* CFG_SUPPORT_STATISTICS */ -+ -+ case EVENT_ID_FW_LOG_ENV: -+ { -+ P_EVENT_FW_LOG_T prEventLog; -+ -+ prEventLog = (P_EVENT_FW_LOG_T) (prEvent->aucBuffer); -+ DBGLOG(RX, INFO, "[F-L]%s\n", prEventLog->log); -+ } -+ break; -+ -+ default: -+ prCmdInfo = nicGetPendingCmdInfo(prAdapter, prEvent->ucSeqNum); -+ -+ if (prCmdInfo != NULL) { -+ if (prCmdInfo->pfCmdDoneHandler) -+ prCmdInfo->pfCmdDoneHandler(prAdapter, prCmdInfo, prEvent->aucBuffer); -+ else if (prCmdInfo->fgIsOid) -+ kalOidComplete(prAdapter->prGlueInfo, prCmdInfo->fgSetQuery, 0, WLAN_STATUS_SUCCESS); -+ /* return prCmdInfo */ -+ cmdBufFreeCmdInfo(prAdapter, prCmdInfo); -+ } -+ -+ break; -+ } -+ -+ nicRxReturnRFB(prAdapter, prSwRfb); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief nicRxProcessMgmtPacket is used to dispatch management frames -+* to corresponding modules -+* -+* @param prAdapter Pointer to the Adapter structure. -+* @param prSWRfb the RFB to receive rx data -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicRxProcessMgmtPacket(IN P_ADAPTER_T prAdapter, IN OUT P_SW_RFB_T prSwRfb) -+{ -+ UINT_8 ucSubtype; -+#if CFG_SUPPORT_802_11W -+ BOOLEAN fgMfgDrop = FALSE; -+#endif -+ ASSERT(prAdapter); -+ ASSERT(prSwRfb); -+ -+ nicRxFillRFB(prAdapter, prSwRfb); -+ -+ ucSubtype = (*(PUINT_8) (prSwRfb->pvHeader) & MASK_FC_SUBTYPE) >> OFFSET_OF_FC_SUBTYPE; -+ -+#if 0 /* CFG_RX_PKTS_DUMP */ -+ { -+ P_HIF_RX_HEADER_T prHifRxHdr; -+ UINT_16 u2TxFrameCtrl; -+ -+ prHifRxHdr = prSwRfb->prHifRxHdr; -+ u2TxFrameCtrl = (*(PUINT_8) (prSwRfb->pvHeader) & MASK_FRAME_TYPE); -+ /* if (prAdapter->rRxCtrl.u4RxPktsDumpTypeMask & BIT(HIF_RX_PKT_TYPE_MANAGEMENT)) { */ -+ /* if (u2TxFrameCtrl == MAC_FRAME_BEACON || */ -+ /* u2TxFrameCtrl == MAC_FRAME_PROBE_RSP) { */ -+ -+ DBGLOG(RX, INFO, "QM RX MGT: net %u sta idx %u wlan idx %u ssn %u ptype %u subtype %u 11 %u\n", -+ (UINT_32) HIF_RX_HDR_GET_NETWORK_IDX(prHifRxHdr), prHifRxHdr->ucStaRecIdx, -+ prSwRfb->ucWlanIdx, (UINT_32) HIF_RX_HDR_GET_SN(prHifRxHdr),/* The new SN of the frame */ -+ prSwRfb->ucPacketType, ucSubtype, HIF_RX_HDR_GET_80211_FLAG(prHifRxHdr)); -+ -+ /* DBGLOG_MEM8(SW4, TRACE, (PUINT_8)prSwRfb->pvHeader, prSwRfb->u2PacketLen); */ -+ /* } */ -+ /* } */ -+ } -+#endif -+ -+ if ((prAdapter->fgTestMode == FALSE) && (prAdapter->prGlueInfo->fgIsRegistered == TRUE)) { -+#if CFG_MGMT_FRAME_HANDLING -+#if CFG_SUPPORT_802_11W -+ fgMfgDrop = rsnCheckRxMgmt(prAdapter, prSwRfb, ucSubtype); -+ if (fgMfgDrop) { -+#if DBG -+ LOG_FUNC("QM RX MGT: Drop Unprotected Mgmt frame!!!\n"); -+#endif -+ nicRxReturnRFB(prAdapter, prSwRfb); -+ RX_INC_CNT(prRxCtrl, RX_DROP_TOTAL_COUNT); -+ return; -+ } -+#endif -+ if (apfnProcessRxMgtFrame[ucSubtype]) { -+ switch (apfnProcessRxMgtFrame[ucSubtype] (prAdapter, prSwRfb)) { -+ case WLAN_STATUS_PENDING: -+ return; -+ case WLAN_STATUS_SUCCESS: -+ case WLAN_STATUS_FAILURE: -+ break; -+ -+ default: -+ DBGLOG(RX, WARN, -+ "Unexpected MMPDU(0x%02X) returned with abnormal status\n", ucSubtype); -+ break; -+ } -+ } -+#endif -+ } -+ -+ nicRxReturnRFB(prAdapter, prSwRfb); -+} -+ -+#if CFG_SUPPORT_WAKEUP_REASON_DEBUG -+static VOID nicRxCheckWakeupReason(P_SW_RFB_T prSwRfb) -+{ -+ PUINT_8 pvHeader = NULL; -+ P_HIF_RX_HEADER_T prHifRxHdr; -+ UINT_16 u2PktLen = 0; -+ UINT_32 u4HeaderOffset; -+ -+ if (!prSwRfb) -+ return; -+ prHifRxHdr = prSwRfb->prHifRxHdr; -+ if (!prHifRxHdr) -+ return; -+ -+ switch (prSwRfb->ucPacketType) { -+ case HIF_RX_PKT_TYPE_DATA: -+ { -+ UINT_16 u2Temp = 0; -+ -+ if (HIF_RX_HDR_GET_BAR_FLAG(prHifRxHdr)) { -+ DBGLOG(RX, INFO, "BAR frame[SSN:%d, TID:%d] wakeup host\n", -+ (UINT_16)HIF_RX_HDR_GET_SN(prHifRxHdr), (UINT_8)HIF_RX_HDR_GET_TID(prHifRxHdr)); -+ break; -+ } -+ u4HeaderOffset = (UINT_32)(prHifRxHdr->ucHerderLenOffset & HIF_RX_HDR_HEADER_OFFSET_MASK); -+ pvHeader = (PUINT_8)prHifRxHdr + HIF_RX_HDR_SIZE + u4HeaderOffset; -+ u2PktLen = (UINT_16)(prHifRxHdr->u2PacketLen - (HIF_RX_HDR_SIZE + u4HeaderOffset)); -+ if (!pvHeader) { -+ DBGLOG(RX, ERROR, "data packet but pvHeader is NULL!\n"); -+ break; -+ } -+ u2Temp = (pvHeader[ETH_TYPE_LEN_OFFSET] << 8) | (pvHeader[ETH_TYPE_LEN_OFFSET + 1]); -+ -+ switch (u2Temp) { -+ case ETH_P_IPV4: -+ u2Temp = *(UINT_16 *) &pvHeader[ETH_HLEN + 4]; -+ DBGLOG(RX, INFO, "IP Packet from:%d.%d.%d.%d, IP ID 0x%04x wakeup host\n", -+ pvHeader[ETH_HLEN + 12], pvHeader[ETH_HLEN + 13], -+ pvHeader[ETH_HLEN + 14], pvHeader[ETH_HLEN + 15], u2Temp); -+ break; -+ case ETH_P_ARP: -+ { -+ PUINT_8 pucEthBody = &pvHeader[ETH_HLEN]; -+ UINT_16 u2OpCode = (pucEthBody[6] << 8) | pucEthBody[7]; -+ -+ if (u2OpCode == ARP_PRO_REQ) -+ DBGLOG(RX, INFO, "Arp Req From IP: %d.%d.%d.%d wakeup host\n", -+ pucEthBody[14], pucEthBody[15], pucEthBody[16], pucEthBody[17]); -+ else if (u2OpCode == ARP_PRO_RSP) -+ DBGLOG(RX, INFO, "Arp Rsp from IP: %d.%d.%d.%d wakeup host\n", -+ pucEthBody[14], pucEthBody[15], pucEthBody[16], pucEthBody[17]); -+ break; -+ } -+ case ETH_P_1X: -+ case ETH_P_PRE_1X: -+#if CFG_SUPPORT_WAPI -+ case ETH_WPI_1X: -+#endif -+ case ETH_P_AARP: -+ case ETH_P_IPV6: -+ case ETH_P_IPX: -+ case 0x8100: /* VLAN */ -+ case 0x890d: /* TDLS */ -+ DBGLOG(RX, INFO, "Data Packet, EthType 0x%04x wakeup host\n", u2Temp); -+ break; -+ default: -+ DBGLOG(RX, WARN, "maybe abnormal data packet, EthType 0x%04x wakeup host, dump it\n", -+ u2Temp); -+ DBGLOG_MEM8(RX, INFO, pvHeader, u2PktLen > 50 ? 50:u2PacketLen); -+ break; -+ } -+ break; -+ } -+ case HIF_RX_PKT_TYPE_EVENT: -+ { -+ P_WIFI_EVENT_T prEvent = (P_WIFI_EVENT_T) prSwRfb->pucRecvBuff; -+ -+ DBGLOG(RX, INFO, "Event 0x%02x wakeup host\n", prEvent->ucEID); -+ break; -+ } -+ case HIF_RX_PKT_TYPE_MANAGEMENT: -+ { -+ UINT_8 ucSubtype; -+ P_WLAN_MAC_MGMT_HEADER_T prWlanMgmtHeader; -+ -+ u4HeaderOffset = (UINT_32)(prHifRxHdr->ucHerderLenOffset & HIF_RX_HDR_HEADER_OFFSET_MASK); -+ pvHeader = (PUINT_8)prHifRxHdr + HIF_RX_HDR_SIZE + u4HeaderOffset; -+ if (!pvHeader) { -+ DBGLOG(RX, ERROR, "Mgmt Frame but pvHeader is NULL!\n"); -+ break; -+ } -+ prWlanMgmtHeader = (P_WLAN_MAC_MGMT_HEADER_T)pvHeader; -+ ucSubtype = (prWlanMgmtHeader->u2FrameCtrl & MASK_FC_SUBTYPE) >> -+ OFFSET_OF_FC_SUBTYPE; -+ DBGLOG(RX, INFO, "MGMT frame subtype: %d SeqCtrl %d wakeup host\n", -+ ucSubtype, prWlanMgmtHeader->u2SeqCtrl); -+ break; -+ } -+ default: -+ DBGLOG(RX, WARN, "Unknown Packet %d wakeup host\n", prSwRfb->ucPacketType); -+ break; -+ } -+} -+#endif -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief nicProcessRFBs is used to process RFBs in the rReceivedRFBList queue. -+* -+* @param prAdapter Pointer to the Adapter structure. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicRxProcessRFBs(IN P_ADAPTER_T prAdapter) -+{ -+ P_RX_CTRL_T prRxCtrl; -+ P_SW_RFB_T prSwRfb = (P_SW_RFB_T) NULL; -+ -+ KAL_SPIN_LOCK_DECLARATION(); -+ -+ DEBUGFUNC("nicRxProcessRFBs"); -+ -+ ASSERT(prAdapter); -+ -+ prRxCtrl = &prAdapter->rRxCtrl; -+ ASSERT(prRxCtrl); -+ -+ prRxCtrl->ucNumIndPacket = 0; -+ prRxCtrl->ucNumRetainedPacket = 0; -+ -+ do { -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); -+ QUEUE_REMOVE_HEAD(&prRxCtrl->rReceivedRfbList, prSwRfb, P_SW_RFB_T); -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); -+ -+ if (prSwRfb) { -+#if CFG_SUPPORT_WAKEUP_REASON_DEBUG -+ if (kalIsWakeupByWlan(prAdapter)) -+ nicRxCheckWakeupReason(prSwRfb); -+#endif -+ switch (prSwRfb->ucPacketType) { -+ case HIF_RX_PKT_TYPE_DATA: -+ nicRxProcessDataPacket(prAdapter, prSwRfb); -+ break; -+ -+ case HIF_RX_PKT_TYPE_EVENT: -+ nicRxProcessEventPacket(prAdapter, prSwRfb); -+ break; -+ -+ case HIF_RX_PKT_TYPE_TX_LOOPBACK: -+#if (CONF_HIF_LOOPBACK_AUTO == 1) -+ { -+ kalDevLoopbkRxHandle(prAdapter, prSwRfb); -+ nicRxReturnRFB(prAdapter, prSwRfb); -+ } -+#else -+ DBGLOG(RX, ERROR, "ucPacketType = %d\n", prSwRfb->ucPacketType); -+#endif /* CONF_HIF_LOOPBACK_AUTO */ -+ break; -+ -+ case HIF_RX_PKT_TYPE_MANAGEMENT: -+ nicRxProcessMgmtPacket(prAdapter, prSwRfb); -+ break; -+ -+ default: -+ RX_INC_CNT(prRxCtrl, RX_TYPE_ERR_DROP_COUNT); -+ RX_INC_CNT(prRxCtrl, RX_DROP_TOTAL_COUNT); -+ DBGLOG(RX, ERROR, "ucPacketType = %d\n", prSwRfb->ucPacketType); -+ nicRxReturnRFB(prAdapter, prSwRfb); /* need to free it */ -+ break; -+ } -+ } else { -+ break; -+ } -+ } while (TRUE); -+ -+ if (prRxCtrl->ucNumIndPacket > 0) { -+ RX_ADD_CNT(prRxCtrl, RX_DATA_INDICATION_COUNT, prRxCtrl->ucNumIndPacket); -+ RX_ADD_CNT(prRxCtrl, RX_DATA_RETAINED_COUNT, prRxCtrl->ucNumRetainedPacket); -+ -+ /* DBGLOG(RX, INFO, ("%d packets indicated, Retained cnt = %d\n", */ -+ /* prRxCtrl->ucNumIndPacket, prRxCtrl->ucNumRetainedPacket)); */ -+#if CFG_NATIVE_802_11 -+ kalRxIndicatePkts(prAdapter->prGlueInfo, (UINT_32) prRxCtrl->ucNumIndPacket, -+ (UINT_32) prRxCtrl->ucNumRetainedPacket); -+#else -+ kalRxIndicatePkts(prAdapter->prGlueInfo, prRxCtrl->apvIndPacket, (UINT_32) prRxCtrl->ucNumIndPacket); -+#endif -+ } -+ -+} /* end of nicRxProcessRFBs() */ -+ -+#if !CFG_SDIO_INTR_ENHANCE -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Read the rx data from data port and setup RFB -+* -+* @param prAdapter pointer to the Adapter handler -+* @param prSWRfb the RFB to receive rx data -+* -+* @retval WLAN_STATUS_SUCCESS: SUCCESS -+* @retval WLAN_STATUS_FAILURE: FAILURE -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS nicRxReadBuffer(IN P_ADAPTER_T prAdapter, IN OUT P_SW_RFB_T prSwRfb) -+{ -+ P_RX_CTRL_T prRxCtrl; -+ PUINT_8 pucBuf; -+ P_HIF_RX_HEADER_T prHifRxHdr; -+ UINT_32 u4PktLen = 0, u4ReadBytes; -+ WLAN_STATUS u4Status = WLAN_STATUS_SUCCESS; -+ BOOLEAN fgResult = TRUE; -+ UINT_32 u4RegValue; -+ UINT_32 rxNum; -+ -+ DEBUGFUNC("nicRxReadBuffer"); -+ -+ ASSERT(prAdapter); -+ ASSERT(prSwRfb); -+ -+ prRxCtrl = &prAdapter->rRxCtrl; -+ ASSERT(prRxCtrl); -+ -+ pucBuf = prSwRfb->pucRecvBuff; -+ prHifRxHdr = prSwRfb->prHifRxHdr; -+ ASSERT(pucBuf); -+ DBGLOG(RX, TRACE, "pucBuf= 0x%x, prHifRxHdr= 0x%x\n", pucBuf, prHifRxHdr); -+ -+ do { -+ /* Read the RFB DW length and packet length */ -+ HAL_MCR_RD(prAdapter, MCR_WRPLR, &u4RegValue); -+ if (!fgResult) { -+ DBGLOG(RX, ERROR, "Read RX Packet Lentgh Error\n"); -+ return WLAN_STATUS_FAILURE; -+ } -+ /* 20091021 move the line to get the HIF RX header (for RX0/1) */ -+ if (u4RegValue == 0) { -+ DBGLOG(RX, ERROR, "No RX packet\n"); -+ return WLAN_STATUS_FAILURE; -+ } -+ -+ u4PktLen = u4RegValue & BITS(0, 15); -+ if (u4PktLen != 0) { -+ rxNum = 0; -+ } else { -+ rxNum = 1; -+ u4PktLen = (u4RegValue & BITS(16, 31)) >> 16; -+ } -+ -+ DBGLOG(RX, TRACE, "RX%d: u4PktLen = %d\n", rxNum, u4PktLen); -+ -+ /* 4 <4> Read Entire RFB and packet, include HW appended DW (Checksum Status) */ -+ u4ReadBytes = ALIGN_4(u4PktLen) + 4; -+ HAL_READ_RX_PORT(prAdapter, rxNum, u4ReadBytes, pucBuf, CFG_RX_MAX_PKT_SIZE); -+ -+ /* 20091021 move the line to get the HIF RX header */ -+ /* u4PktLen = (UINT_32)prHifRxHdr->u2PacketLen; */ -+ if (u4PktLen != (UINT_32) prHifRxHdr->u2PacketLen) { -+ DBGLOG(RX, ERROR, "Read u4PktLen = %d, prHifRxHdr->u2PacketLen: %d\n", -+ u4PktLen, prHifRxHdr->u2PacketLen); -+#if DBG -+ dumpMemory8((PUINT_8) prHifRxHdr, -+ (prHifRxHdr->u2PacketLen > 4096) ? 4096 : prHifRxHdr->u2PacketLen); -+#endif -+ ASSERT(0); -+ } -+ /* u4PktLen is byte unit, not inlude HW appended DW */ -+ -+ prSwRfb->ucPacketType = (UINT_8) (prHifRxHdr->u2PacketType & HIF_RX_HDR_PACKET_TYPE_MASK); -+ DBGLOG(RX, TRACE, "ucPacketType = %d\n", prSwRfb->ucPacketType); -+ -+ prSwRfb->ucStaRecIdx = (UINT_8) (prHifRxHdr->ucStaRecIdx); -+ -+ /* fgResult will be updated in MACRO */ -+ if (!fgResult) -+ return WLAN_STATUS_FAILURE; -+ -+ DBGLOG(RX, TRACE, "Dump RX buffer, length = 0x%x\n", u4ReadBytes); -+ DBGLOG_MEM8(RX, TRACE, pucBuf, u4ReadBytes); -+ } while (FALSE); -+ -+ return u4Status; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Read frames from the data port, fill RFB -+* and put each frame into the rReceivedRFBList queue. -+* -+* @param prAdapter Pointer to the Adapter structure. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicRxReceiveRFBs(IN P_ADAPTER_T prAdapter) -+{ -+ P_RX_CTRL_T prRxCtrl; -+ P_SW_RFB_T prSwRfb = (P_SW_RFB_T) NULL; -+ P_HIF_RX_HEADER_T prHifRxHdr; -+ -+ UINT_32 u4HwAppendDW; -+ -+ KAL_SPIN_LOCK_DECLARATION(); -+ -+ DEBUGFUNC("nicRxReceiveRFBs"); -+ -+ ASSERT(prAdapter); -+ -+ prRxCtrl = &prAdapter->rRxCtrl; -+ ASSERT(prRxCtrl); -+ -+ do { -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); -+ QUEUE_REMOVE_HEAD(&prRxCtrl->rFreeSwRfbList, prSwRfb, P_SW_RFB_T); -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); -+ -+ if (!prSwRfb) { -+ DBGLOG(RX, TRACE, "No More RFB\n"); -+ break; -+ } -+ /* need to consider */ -+ if (nicRxReadBuffer(prAdapter, prSwRfb) == WLAN_STATUS_FAILURE) { -+ DBGLOG(RX, TRACE, "halRxFillRFB failed\n"); -+ nicRxReturnRFB(prAdapter, prSwRfb); -+ break; -+ } -+ -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); -+ QUEUE_INSERT_TAIL(&prRxCtrl->rReceivedRfbList, &prSwRfb->rQueEntry); -+ RX_INC_CNT(prRxCtrl, RX_MPDU_TOTAL_COUNT); -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); -+ -+ prHifRxHdr = prSwRfb->prHifRxHdr; -+ u4HwAppendDW = *((PUINT_32) ((ULONG) prHifRxHdr + (UINT_32) (ALIGN_4(prHifRxHdr->u2PacketLen)))); -+ DBGLOG(RX, TRACE, "u4HwAppendDW = 0x%x\n", u4HwAppendDW); -+ DBGLOG(RX, TRACE, "u2PacketLen = 0x%x\n", prHifRxHdr->u2PacketLen); -+ } while (FALSE); /* while (RX_STATUS_TEST_MORE_FLAG(u4HwAppendDW)); */ -+ -+ return; -+ -+} /* end of nicReceiveRFBs() */ -+ -+#else -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Read frames from the data port, fill RFB -+* and put each frame into the rReceivedRFBList queue. -+* -+* @param prAdapter Pointer to the Adapter structure. -+* @param u4DataPort Specify which port to read -+* @param u2RxLength Specify to the the rx packet length in Byte. -+* @param prSwRfb the RFB to receive rx data. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+ -+WLAN_STATUS -+nicRxEnhanceReadBuffer(IN P_ADAPTER_T prAdapter, -+ IN UINT_32 u4DataPort, IN UINT_16 u2RxLength, IN OUT P_SW_RFB_T prSwRfb) -+{ -+ P_RX_CTRL_T prRxCtrl; -+ PUINT_8 pucBuf; -+ P_HIF_RX_HEADER_T prHifRxHdr; -+ UINT_32 u4PktLen = 0; -+ WLAN_STATUS u4Status = WLAN_STATUS_FAILURE; -+ BOOLEAN fgResult = TRUE; -+ -+ DEBUGFUNC("nicRxEnhanceReadBuffer"); -+ -+ ASSERT(prAdapter); -+ ASSERT(prSwRfb); -+ -+ prRxCtrl = &prAdapter->rRxCtrl; -+ ASSERT(prRxCtrl); -+ -+ pucBuf = prSwRfb->pucRecvBuff; -+ ASSERT(pucBuf); -+ -+ prHifRxHdr = prSwRfb->prHifRxHdr; -+ ASSERT(prHifRxHdr); -+ -+ /* DBGLOG(RX, TRACE, ("u2RxLength = %d\n", u2RxLength)); */ -+ -+ do { -+ /* 4 <1> Read RFB frame from MCR_WRDR0, include HW appended DW */ -+ HAL_READ_RX_PORT(prAdapter, -+ u4DataPort, ALIGN_4(u2RxLength + HIF_RX_HW_APPENDED_LEN), pucBuf, CFG_RX_MAX_PKT_SIZE); -+ -+ if (!fgResult) { -+ DBGLOG(RX, ERROR, "Read RX Packet Lentgh Error\n"); -+ break; -+ } -+ -+ u4PktLen = (UINT_32) (prHifRxHdr->u2PacketLen); -+ /* DBGLOG(RX, TRACE, ("u4PktLen = %d\n", u4PktLen)); */ -+ -+ prSwRfb->ucPacketType = (UINT_8) (prHifRxHdr->u2PacketType & HIF_RX_HDR_PACKET_TYPE_MASK); -+ /* DBGLOG(RX, TRACE, ("ucPacketType = %d\n", prSwRfb->ucPacketType)); */ -+ -+ prSwRfb->ucStaRecIdx = (UINT_8) (prHifRxHdr->ucStaRecIdx); -+ -+ /* 4 <2> if the RFB dw size or packet size is zero */ -+ if (u4PktLen == 0) { -+ DBGLOG(RX, ERROR, "Packet Length = %u\n", u4PktLen); -+ ASSERT(0); -+ break; -+ } -+ /* 4 <3> if the packet is too large or too small */ -+ if (u4PktLen > CFG_RX_MAX_PKT_SIZE) { -+ DBGLOG(RX, TRACE, "Read RX Packet Lentgh Error (%u)\n", u4PktLen); -+ ASSERT(0); -+ break; -+ } -+ -+ u4Status = WLAN_STATUS_SUCCESS; -+ } while (FALSE); -+ -+ DBGLOG_MEM8(RX, TRACE, pucBuf, ALIGN_4(u2RxLength + HIF_RX_HW_APPENDED_LEN)); -+ return u4Status; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Read frames from the data port for SDIO -+* I/F, fill RFB and put each frame into the rReceivedRFBList queue. -+* -+* @param prAdapter Pointer to the Adapter structure. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicRxSDIOReceiveRFBs(IN P_ADAPTER_T prAdapter) -+{ -+ P_SDIO_CTRL_T prSDIOCtrl; -+ P_RX_CTRL_T prRxCtrl; -+ P_SW_RFB_T prSwRfb = (P_SW_RFB_T) NULL; -+ UINT_32 i, rxNum; -+ UINT_16 u2RxPktNum, u2RxLength = 0, u2Tmp = 0; -+ -+ KAL_SPIN_LOCK_DECLARATION(); -+ -+ DEBUGFUNC("nicRxSDIOReceiveRFBs"); -+ -+ ASSERT(prAdapter); -+ -+ prSDIOCtrl = prAdapter->prSDIOCtrl; -+ ASSERT(prSDIOCtrl); -+ -+ prRxCtrl = &prAdapter->rRxCtrl; -+ ASSERT(prRxCtrl); -+ -+ for (rxNum = 0; rxNum < 2; rxNum++) { -+ u2RxPktNum = -+ (rxNum == 0 ? prSDIOCtrl->rRxInfo.u.u2NumValidRx0Len : prSDIOCtrl->rRxInfo.u.u2NumValidRx1Len); -+ -+ if (u2RxPktNum == 0) -+ continue; -+ -+ for (i = 0; i < u2RxPktNum; i++) { -+ if (rxNum == 0) { -+ /* HAL_READ_RX_LENGTH */ -+ HAL_READ_RX_LENGTH(prAdapter, &u2RxLength, &u2Tmp); -+ } else if (rxNum == 1) { -+ /* HAL_READ_RX_LENGTH */ -+ HAL_READ_RX_LENGTH(prAdapter, &u2Tmp, &u2RxLength); -+ } -+ -+ if (!u2RxLength) -+ break; -+ -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); -+ QUEUE_REMOVE_HEAD(&prRxCtrl->rFreeSwRfbList, prSwRfb, P_SW_RFB_T); -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); -+ -+ if (!prSwRfb) { -+ DBGLOG(RX, TRACE, "No More RFB\n"); -+ break; -+ } -+ ASSERT(prSwRfb); -+ -+ if (nicRxEnhanceReadBuffer(prAdapter, rxNum, u2RxLength, prSwRfb) == WLAN_STATUS_FAILURE) { -+ DBGLOG(RX, TRACE, "nicRxEnhanceRxReadBuffer failed\n"); -+ nicRxReturnRFB(prAdapter, prSwRfb); -+ break; -+ } -+ /* prSDIOCtrl->au4RxLength[i] = 0; */ -+ -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); -+ QUEUE_INSERT_TAIL(&prRxCtrl->rReceivedRfbList, &prSwRfb->rQueEntry); -+ RX_INC_CNT(prRxCtrl, RX_MPDU_TOTAL_COUNT); -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); -+ } -+ } -+ -+ prSDIOCtrl->rRxInfo.u.u2NumValidRx0Len = 0; -+ prSDIOCtrl->rRxInfo.u.u2NumValidRx1Len = 0; -+ -+} /* end of nicRxSDIOReceiveRFBs() */ -+ -+#endif /* CFG_SDIO_INTR_ENHANCE */ -+ -+#if CFG_SDIO_RX_AGG -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Read frames from the data port for SDIO with Rx aggregation enabled -+* I/F, fill RFB and put each frame into the rReceivedRFBList queue. -+* -+* @param prAdapter Pointer to the Adapter structure. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicRxSDIOAggReceiveRFBs(IN P_ADAPTER_T prAdapter) -+{ -+ P_ENHANCE_MODE_DATA_STRUCT_T prEnhDataStr; -+ P_RX_CTRL_T prRxCtrl; -+ P_SDIO_CTRL_T prSDIOCtrl; -+ P_SW_RFB_T prSwRfb = (P_SW_RFB_T) NULL; -+ UINT_32 u4RxLength; -+ UINT_32 i, rxNum; -+ UINT_32 u4RxAggCount = 0, u4RxAggLength = 0; -+ UINT_32 u4RxAvailAggLen, u4CurrAvailFreeRfbCnt; -+ PUINT_8 pucSrcAddr; -+ P_HIF_RX_HEADER_T prHifRxHdr; -+ BOOLEAN fgResult = TRUE; -+ BOOLEAN fgIsRxEnhanceMode; -+ UINT_16 u2RxPktNum; -+#if CFG_SDIO_RX_ENHANCE -+ UINT_32 u4MaxLoopCount = CFG_MAX_RX_ENHANCE_LOOP_COUNT; -+#endif -+ -+ KAL_SPIN_LOCK_DECLARATION(); -+ -+ DEBUGFUNC("nicRxSDIOAggReceiveRFBs"); -+ -+ ASSERT(prAdapter); -+ prEnhDataStr = prAdapter->prSDIOCtrl; -+ prRxCtrl = &prAdapter->rRxCtrl; -+ prSDIOCtrl = prAdapter->prSDIOCtrl; -+ -+#if CFG_SDIO_RX_ENHANCE -+ fgIsRxEnhanceMode = TRUE; -+#else -+ fgIsRxEnhanceMode = FALSE; -+#endif -+ -+ do { -+#if CFG_SDIO_RX_ENHANCE -+ /* to limit maximum loop for RX */ -+ u4MaxLoopCount--; -+ if (u4MaxLoopCount == 0) -+ break; -+#endif -+ -+ if (prEnhDataStr->rRxInfo.u.u2NumValidRx0Len == 0 && prEnhDataStr->rRxInfo.u.u2NumValidRx1Len == 0) -+ break; -+ -+ for (rxNum = 0; rxNum < 2; rxNum++) { -+ u2RxPktNum = -+ (rxNum == -+ 0 ? prEnhDataStr->rRxInfo.u.u2NumValidRx0Len : prEnhDataStr->rRxInfo.u.u2NumValidRx1Len); -+ -+ /* if this assertion happened, it is most likely a F/W bug */ -+ ASSERT(u2RxPktNum <= 16); -+ -+ if (u2RxPktNum > 16) -+ continue; -+ -+ if (u2RxPktNum == 0) -+ continue; -+ -+#if CFG_HIF_STATISTICS -+ prRxCtrl->u4TotalRxAccessNum++; -+ prRxCtrl->u4TotalRxPacketNum += u2RxPktNum; -+#endif -+ -+ u4CurrAvailFreeRfbCnt = prRxCtrl->rFreeSwRfbList.u4NumElem; -+ -+ /* if SwRfb is not enough, abort reading this time */ -+ if (u4CurrAvailFreeRfbCnt < u2RxPktNum) { -+#if CFG_HIF_RX_STARVATION_WARNING -+ DbgPrint("FreeRfb is not enough: %d available, need %d\n", u4CurrAvailFreeRfbCnt, -+ u2RxPktNum); -+ DbgPrint("Queued Count: %d / Dequeud Count: %d\n", prRxCtrl->u4QueuedCnt, -+ prRxCtrl->u4DequeuedCnt); -+#endif -+ continue; -+ } -+#if CFG_SDIO_RX_ENHANCE -+ u4RxAvailAggLen = -+ CFG_RX_COALESCING_BUFFER_SIZE - (sizeof(ENHANCE_MODE_DATA_STRUCT_T) + -+ 4 /* extra HW padding */); -+#else -+ u4RxAvailAggLen = CFG_RX_COALESCING_BUFFER_SIZE; -+#endif -+ u4RxAggCount = 0; -+ -+ for (i = 0; i < u2RxPktNum; i++) { -+ u4RxLength = (rxNum == 0 ? -+ (UINT_32) prEnhDataStr->rRxInfo.u.au2Rx0Len[i] : -+ (UINT_32) prEnhDataStr->rRxInfo.u.au2Rx1Len[i]); -+ -+ if (!u4RxLength) { -+ ASSERT(0); -+ break; -+ } -+ -+ if (ALIGN_4(u4RxLength + HIF_RX_HW_APPENDED_LEN) < u4RxAvailAggLen) { -+ if (u4RxAggCount < u4CurrAvailFreeRfbCnt) { -+ u4RxAvailAggLen -= ALIGN_4(u4RxLength + HIF_RX_HW_APPENDED_LEN); -+ u4RxAggCount++; -+ } else { -+ /* no FreeSwRfb for rx packet */ -+ ASSERT(0); -+ break; -+ } -+ } else { -+ /* CFG_RX_COALESCING_BUFFER_SIZE is not large enough */ -+ ASSERT(0); -+ break; -+ } -+ } -+ -+ u4RxAggLength = (CFG_RX_COALESCING_BUFFER_SIZE - u4RxAvailAggLen); -+ /* DBGLOG(RX, INFO, ("u4RxAggCount = %d, u4RxAggLength = %d\n", */ -+ /* u4RxAggCount, u4RxAggLength)); */ -+ -+ HAL_READ_RX_PORT(prAdapter, -+ rxNum, -+ u4RxAggLength, prRxCtrl->pucRxCoalescingBufPtr, CFG_RX_COALESCING_BUFFER_SIZE); -+ if (!fgResult) { -+ DBGLOG(RX, ERROR, "Read RX Agg Packet Error\n"); -+ continue; -+ } -+ -+ pucSrcAddr = prRxCtrl->pucRxCoalescingBufPtr; -+ for (i = 0; i < u4RxAggCount; i++) { -+ UINT_16 u2PktLength; -+ -+ u2PktLength = (rxNum == 0 ? -+ prEnhDataStr->rRxInfo.u.au2Rx0Len[i] : -+ prEnhDataStr->rRxInfo.u.au2Rx1Len[i]); -+ -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); -+ QUEUE_REMOVE_HEAD(&prRxCtrl->rFreeSwRfbList, prSwRfb, P_SW_RFB_T); -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); -+ -+ ASSERT(prSwRfb); -+ kalMemCopy(prSwRfb->pucRecvBuff, pucSrcAddr, -+ ALIGN_4(u2PktLength + HIF_RX_HW_APPENDED_LEN)); -+ -+ /* record the rx time */ -+ STATS_RX_ARRIVE_TIME_RECORD(prSwRfb); /* ms */ -+ -+ prHifRxHdr = prSwRfb->prHifRxHdr; -+ ASSERT(prHifRxHdr); -+ -+ prSwRfb->ucPacketType = -+ (UINT_8) (prHifRxHdr->u2PacketType & HIF_RX_HDR_PACKET_TYPE_MASK); -+ /* DBGLOG(RX, TRACE, ("ucPacketType = %d\n", prSwRfb->ucPacketType)); */ -+ -+ prSwRfb->ucStaRecIdx = (UINT_8) (prHifRxHdr->ucStaRecIdx); -+ -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); -+ QUEUE_INSERT_TAIL(&prRxCtrl->rReceivedRfbList, &prSwRfb->rQueEntry); -+ RX_INC_CNT(prRxCtrl, RX_MPDU_TOTAL_COUNT); -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); -+ -+ pucSrcAddr += ALIGN_4(u2PktLength + HIF_RX_HW_APPENDED_LEN); -+ /* prEnhDataStr->au4RxLength[i] = 0; */ -+ } -+ -+#if CFG_SDIO_RX_ENHANCE -+ kalMemCopy(prAdapter->prSDIOCtrl, (pucSrcAddr + 4), sizeof(ENHANCE_MODE_DATA_STRUCT_T)); -+ -+ /* do the same thing what nicSDIOReadIntStatus() does */ -+ if ((prSDIOCtrl->u4WHISR & WHISR_TX_DONE_INT) == 0 && -+ (prSDIOCtrl->rTxInfo.au4WTSR[0] | prSDIOCtrl->rTxInfo.au4WTSR[1])) { -+ prSDIOCtrl->u4WHISR |= WHISR_TX_DONE_INT; -+ } -+ -+ if ((prSDIOCtrl->u4WHISR & BIT(31)) == 0 && -+ HAL_GET_MAILBOX_READ_CLEAR(prAdapter) == TRUE && -+ (prSDIOCtrl->u4RcvMailbox0 != 0 || prSDIOCtrl->u4RcvMailbox1 != 0)) { -+ prSDIOCtrl->u4WHISR |= BIT(31); -+ } -+ -+ /* dispatch to interrupt handler with RX bits masked */ -+ nicProcessIST_impl(prAdapter, -+ prSDIOCtrl->u4WHISR & (~(WHISR_RX0_DONE_INT | WHISR_RX1_DONE_INT))); -+#endif -+ } -+ -+#if !CFG_SDIO_RX_ENHANCE -+ prEnhDataStr->rRxInfo.u.u2NumValidRx0Len = 0; -+ prEnhDataStr->rRxInfo.u.u2NumValidRx1Len = 0; -+#endif -+ } while ((prEnhDataStr->rRxInfo.u.u2NumValidRx0Len || prEnhDataStr->rRxInfo.u.u2NumValidRx1Len) -+ && fgIsRxEnhanceMode); -+ -+} -+#endif /* CFG_SDIO_RX_AGG */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Setup a RFB and allocate the os packet to the RFB -+* -+* @param prAdapter Pointer to the Adapter structure. -+* @param prSwRfb Pointer to the RFB -+* -+* @retval WLAN_STATUS_SUCCESS -+* @retval WLAN_STATUS_RESOURCES -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS nicRxSetupRFB(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb) -+{ -+ PVOID pvPacket; -+ PUINT_8 pucRecvBuff; -+ -+ ASSERT(prAdapter); -+ ASSERT(prSwRfb); -+ -+ if (!prSwRfb->pvPacket) { -+ kalMemZero(prSwRfb, sizeof(SW_RFB_T)); -+ pvPacket = kalPacketAlloc(prAdapter->prGlueInfo, CFG_RX_MAX_PKT_SIZE, &pucRecvBuff); -+ if (pvPacket == NULL) -+ return WLAN_STATUS_RESOURCES; -+ -+ prSwRfb->pvPacket = pvPacket; -+ prSwRfb->pucRecvBuff = (PVOID) pucRecvBuff; -+ } else { -+ kalMemZero(((PUINT_8) prSwRfb + OFFSET_OF(SW_RFB_T, prHifRxHdr)), -+ (sizeof(SW_RFB_T) - OFFSET_OF(SW_RFB_T, prHifRxHdr))); -+ } -+ -+ prSwRfb->prHifRxHdr = (P_HIF_RX_HEADER_T) (prSwRfb->pucRecvBuff); -+ -+ return WLAN_STATUS_SUCCESS; -+ -+} /* end of nicRxSetupRFB() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This routine is called to put a RFB back onto the "RFB with Buffer" list -+* or "RFB without buffer" list according to pvPacket. -+* -+* @param prAdapter Pointer to the Adapter structure. -+* @param prSwRfb Pointer to the RFB -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicRxReturnRFB(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb) -+{ -+ P_RX_CTRL_T prRxCtrl; -+ P_QUE_ENTRY_T prQueEntry; -+ -+ KAL_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(prAdapter); -+ ASSERT(prSwRfb); -+ prRxCtrl = &prAdapter->rRxCtrl; -+ prQueEntry = &prSwRfb->rQueEntry; -+ -+ ASSERT(prQueEntry); -+ -+ /* The processing on this RFB is done, so put it back on the tail of -+ our list */ -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); -+ -+ if (prSwRfb->pvPacket) { -+ /* QUEUE_INSERT_TAIL */ -+ QUEUE_INSERT_TAIL(&prRxCtrl->rFreeSwRfbList, prQueEntry); -+ } else { -+ /* QUEUE_INSERT_TAIL */ -+ QUEUE_INSERT_TAIL(&prRxCtrl->rIndicatedRfbList, prQueEntry); -+ } -+ -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); -+} /* end of nicRxReturnRFB() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Process rx interrupt. When the rx -+* Interrupt is asserted, it means there are frames in queue. -+* -+* @param prAdapter Pointer to the Adapter structure. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicProcessRxInterrupt(IN P_ADAPTER_T prAdapter) -+{ -+ P_GLUE_INFO_T prGlueInfo = prAdapter->prGlueInfo; -+ -+ prGlueInfo->IsrRxCnt++; -+#if CFG_SDIO_INTR_ENHANCE -+#if CFG_SDIO_RX_AGG -+ nicRxSDIOAggReceiveRFBs(prAdapter); -+#else -+ nicRxSDIOReceiveRFBs(prAdapter); -+#endif -+#else -+ nicRxReceiveRFBs(prAdapter); -+#endif /* CFG_SDIO_INTR_ENHANCE */ -+ -+ nicRxProcessRFBs(prAdapter); -+ -+ return; -+ -+} /* end of nicProcessRxInterrupt() */ -+ -+#if CFG_TCP_IP_CHKSUM_OFFLOAD -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Used to update IP/TCP/UDP checksum statistics of RX Module. -+* -+* @param prAdapter Pointer to the Adapter structure. -+* @param aeCSUM The array of checksum result. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicRxUpdateCSUMStatistics(IN P_ADAPTER_T prAdapter, IN const ENUM_CSUM_RESULT_T aeCSUM[]) -+{ -+ P_RX_CTRL_T prRxCtrl; -+ -+ ASSERT(prAdapter); -+ ASSERT(aeCSUM); -+ -+ prRxCtrl = &prAdapter->rRxCtrl; -+ ASSERT(prRxCtrl); -+ -+ if ((aeCSUM[CSUM_TYPE_IPV4] == CSUM_RES_SUCCESS) || -+ (aeCSUM[CSUM_TYPE_IPV6] == CSUM_RES_SUCCESS)) { -+ RX_INC_CNT(prRxCtrl, RX_CSUM_IP_SUCCESS_COUNT); -+ } else if ((aeCSUM[CSUM_TYPE_IPV4] == CSUM_RES_FAILED) || (aeCSUM[CSUM_TYPE_IPV6] == CSUM_RES_FAILED)) { -+ RX_INC_CNT(prRxCtrl, RX_CSUM_IP_FAILED_COUNT); -+ } else if ((aeCSUM[CSUM_TYPE_IPV4] == CSUM_RES_NONE) && (aeCSUM[CSUM_TYPE_IPV6] == CSUM_RES_NONE)) { -+ RX_INC_CNT(prRxCtrl, RX_CSUM_UNKNOWN_L3_PKT_COUNT); -+ } else { -+ ASSERT(0); -+ } -+ -+ if (aeCSUM[CSUM_TYPE_TCP] == CSUM_RES_SUCCESS) { -+ /* count success num */ -+ RX_INC_CNT(prRxCtrl, RX_CSUM_TCP_SUCCESS_COUNT); -+ } else if (aeCSUM[CSUM_TYPE_TCP] == CSUM_RES_FAILED) { -+ RX_INC_CNT(prRxCtrl, RX_CSUM_TCP_FAILED_COUNT); -+ } else if (aeCSUM[CSUM_TYPE_UDP] == CSUM_RES_SUCCESS) { -+ RX_INC_CNT(prRxCtrl, RX_CSUM_UDP_SUCCESS_COUNT); -+ } else if (aeCSUM[CSUM_TYPE_UDP] == CSUM_RES_FAILED) { -+ RX_INC_CNT(prRxCtrl, RX_CSUM_UDP_FAILED_COUNT); -+ } else if ((aeCSUM[CSUM_TYPE_UDP] == CSUM_RES_NONE) && (aeCSUM[CSUM_TYPE_TCP] == CSUM_RES_NONE)) { -+ RX_INC_CNT(prRxCtrl, RX_CSUM_UNKNOWN_L4_PKT_COUNT); -+ } else { -+ ASSERT(0); -+ } -+ -+} /* end of nicRxUpdateCSUMStatistics() */ -+#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is used to query current status of RX Module. -+* -+* @param prAdapter Pointer to the Adapter structure. -+* @param pucBuffer Pointer to the message buffer. -+* @param pu4Count Pointer to the buffer of message length count. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicRxQueryStatus(IN P_ADAPTER_T prAdapter, IN PUINT_8 pucBuffer, OUT PUINT_32 pu4Count) -+{ -+ P_RX_CTRL_T prRxCtrl; -+ PUINT_8 pucCurrBuf = pucBuffer; -+ -+ ASSERT(prAdapter); -+ prRxCtrl = &prAdapter->rRxCtrl; -+ ASSERT(prRxCtrl); -+ -+ /* if (pucBuffer) {} */ /* For Windows, we'll print directly instead of sprintf() */ -+ ASSERT(pu4Count); -+ -+ SPRINTF(pucCurrBuf, ("\n\nRX CTRL STATUS:")); -+ SPRINTF(pucCurrBuf, ("\n===============")); -+ SPRINTF(pucCurrBuf, ("\nFREE RFB w/i BUF LIST :%9u", prRxCtrl->rFreeSwRfbList.u4NumElem)); -+ SPRINTF(pucCurrBuf, ("\nFREE RFB w/o BUF LIST :%9u", prRxCtrl->rIndicatedRfbList.u4NumElem)); -+ SPRINTF(pucCurrBuf, ("\nRECEIVED RFB LIST :%9u", prRxCtrl->rReceivedRfbList.u4NumElem)); -+ -+ SPRINTF(pucCurrBuf, ("\n\n")); -+ -+ /* *pu4Count = (UINT_32)((UINT_32)pucCurrBuf - (UINT_32)pucBuffer); */ -+ -+} /* end of nicRxQueryStatus() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Clear RX related counters -+* -+* @param prAdapter Pointer of Adapter Data Structure -+* -+* @return - (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicRxClearStatistics(IN P_ADAPTER_T prAdapter) -+{ -+ P_RX_CTRL_T prRxCtrl; -+ -+ ASSERT(prAdapter); -+ prRxCtrl = &prAdapter->rRxCtrl; -+ ASSERT(prRxCtrl); -+ -+ RX_RESET_ALL_CNTS(prRxCtrl); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is used to query current statistics of RX Module. -+* -+* @param prAdapter Pointer to the Adapter structure. -+* @param pucBuffer Pointer to the message buffer. -+* @param pu4Count Pointer to the buffer of message length count. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicRxQueryStatistics(IN P_ADAPTER_T prAdapter, IN PUINT_8 pucBuffer, OUT PUINT_32 pu4Count) -+{ -+ P_RX_CTRL_T prRxCtrl; -+ PUINT_8 pucCurrBuf = pucBuffer; -+ -+ ASSERT(prAdapter); -+ prRxCtrl = &prAdapter->rRxCtrl; -+ ASSERT(prRxCtrl); -+ -+ /* if (pucBuffer) {} */ /* For Windows, we'll print directly instead of sprintf() */ -+ ASSERT(pu4Count); -+ -+#define SPRINTF_RX_COUNTER(eCounter) \ -+ SPRINTF(pucCurrBuf, ("%-30s : %u\n", #eCounter, (UINT_32)prRxCtrl->au8Statistics[eCounter])) -+ -+ SPRINTF_RX_COUNTER(RX_MPDU_TOTAL_COUNT); -+ SPRINTF_RX_COUNTER(RX_SIZE_ERR_DROP_COUNT); -+ SPRINTF_RX_COUNTER(RX_DATA_INDICATION_COUNT); -+ SPRINTF_RX_COUNTER(RX_DATA_RETURNED_COUNT); -+ SPRINTF_RX_COUNTER(RX_DATA_RETAINED_COUNT); -+ -+#if CFG_TCP_IP_CHKSUM_OFFLOAD || CFG_TCP_IP_CHKSUM_OFFLOAD_NDIS_60 -+ SPRINTF_RX_COUNTER(RX_CSUM_TCP_FAILED_COUNT); -+ SPRINTF_RX_COUNTER(RX_CSUM_UDP_FAILED_COUNT); -+ SPRINTF_RX_COUNTER(RX_CSUM_IP_FAILED_COUNT); -+ SPRINTF_RX_COUNTER(RX_CSUM_TCP_SUCCESS_COUNT); -+ SPRINTF_RX_COUNTER(RX_CSUM_UDP_SUCCESS_COUNT); -+ SPRINTF_RX_COUNTER(RX_CSUM_IP_SUCCESS_COUNT); -+ SPRINTF_RX_COUNTER(RX_CSUM_UNKNOWN_L4_PKT_COUNT); -+ SPRINTF_RX_COUNTER(RX_CSUM_UNKNOWN_L3_PKT_COUNT); -+ SPRINTF_RX_COUNTER(RX_IP_V6_PKT_CCOUNT); -+#endif -+ -+ /* *pu4Count = (UINT_32)(pucCurrBuf - pucBuffer); */ -+ -+ nicRxClearStatistics(prAdapter); -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Read the Response data from data port -+* -+* @param prAdapter pointer to the Adapter handler -+* @param pucRspBuffer pointer to the Response buffer -+* -+* @retval WLAN_STATUS_SUCCESS: Response packet has been read -+* @retval WLAN_STATUS_FAILURE: Read Response packet timeout or error occurred -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+nicRxWaitResponse(IN P_ADAPTER_T prAdapter, -+ IN UINT_8 ucPortIdx, OUT PUINT_8 pucRspBuffer, IN UINT_32 u4MaxRespBufferLen, OUT PUINT_32 pu4Length) -+{ -+ UINT_32 u4Value = 0, u4PktLen = 0; -+ UINT_32 i = 0; -+ WLAN_STATUS u4Status = WLAN_STATUS_SUCCESS; -+ BOOLEAN fgResult = TRUE; -+ UINT_32 u4Time, u4Current; -+ -+ DEBUGFUNC("nicRxWaitResponse"); -+ -+ ASSERT(prAdapter); -+ ASSERT(pucRspBuffer); -+ ASSERT(ucPortIdx < 2); -+ -+ u4Time = kalGetTimeTick(); -+ -+ do { -+ /* Read the packet length */ -+ HAL_MCR_RD(prAdapter, MCR_WRPLR, &u4Value); -+ -+ if (!fgResult) { -+ DBGLOG(RX, ERROR, "Read Response Packet Error\n"); -+ return WLAN_STATUS_FAILURE; -+ } -+ -+ if (ucPortIdx == 0) -+ u4PktLen = u4Value & 0xFFFF; -+ else -+ u4PktLen = (u4Value >> 16) & 0xFFFF; -+ -+/* DBGLOG(RX, TRACE, ("i = %d, u4PktLen = %d\n", i, u4PktLen)); */ -+ -+ if (u4PktLen == 0) { -+ /* timeout exceeding check */ -+ u4Current = kalGetTimeTick(); -+ -+ if ((u4Current > u4Time) && ((u4Current - u4Time) > RX_RESPONSE_TIMEOUT)) { -+ DBGLOG(RX, ERROR, "RX_RESPONSE_TIMEOUT1 %u %d %u\n", u4PktLen, i, u4Current); -+ return WLAN_STATUS_FAILURE; -+ } else if (u4Current < u4Time && ((u4Current + (0xFFFFFFFF - u4Time)) > RX_RESPONSE_TIMEOUT)) { -+ DBGLOG(RX, ERROR, "RX_RESPONSE_TIMEOUT2 %u %d %u\n", u4PktLen, i, u4Current); -+ return WLAN_STATUS_FAILURE; -+ } -+ -+ /* Response packet is not ready */ -+ kalUdelay(50); -+ -+ i++; -+ continue; -+ } -+ if (u4PktLen > u4MaxRespBufferLen) { -+ /* -+ TO: buffer is not enough but we still need to read all data from HIF to avoid -+ HIF crazy. -+ */ -+ DBGLOG(RX, ERROR, -+ "Not enough Event Buffer: required length = 0x%x, available buffer length = %d\n", -+ u4PktLen, u4MaxRespBufferLen); -+ DBGLOG(RX, ERROR, "i = %d, u4PktLen = %u\n", i, u4PktLen); -+ return WLAN_STATUS_FAILURE; -+ } -+ HAL_PORT_RD(prAdapter, -+ ucPortIdx == 0 ? MCR_WRDR0 : MCR_WRDR1, u4PktLen, pucRspBuffer, u4MaxRespBufferLen); -+ -+ /* fgResult will be updated in MACRO */ -+ if (!fgResult) { -+ DBGLOG(RX, ERROR, "Read Response Packet Error\n"); -+ return WLAN_STATUS_FAILURE; -+ } -+ -+ DBGLOG(RX, TRACE, "Dump Response buffer, length = 0x%x\n", u4PktLen); -+ DBGLOG_MEM8(RX, TRACE, pucRspBuffer, u4PktLen); -+ -+ *pu4Length = u4PktLen; -+ break; -+ } while (TRUE); -+ -+ return u4Status; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Set filter to enable Promiscuous Mode -+* -+* @param prAdapter Pointer to the Adapter structure. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicRxEnablePromiscuousMode(IN P_ADAPTER_T prAdapter) -+{ -+ ASSERT(prAdapter); -+ -+} /* end of nicRxEnablePromiscuousMode() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Set filter to disable Promiscuous Mode -+* -+* @param prAdapter Pointer to the Adapter structure. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicRxDisablePromiscuousMode(IN P_ADAPTER_T prAdapter) -+{ -+ ASSERT(prAdapter); -+ -+} /* end of nicRxDisablePromiscuousMode() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief this function flushes all packets queued in reordering module -+* -+* @param prAdapter Pointer to the Adapter structure. -+* -+* @retval WLAN_STATUS_SUCCESS Flushed successfully -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS nicRxFlush(IN P_ADAPTER_T prAdapter) -+{ -+ P_SW_RFB_T prSwRfb; -+ -+ ASSERT(prAdapter); -+ -+ prSwRfb = qmFlushRxQueues(prAdapter); -+ if (prSwRfb != NULL) { -+ do { -+ P_SW_RFB_T prNextSwRfb; -+ -+ /* save next first */ -+ prNextSwRfb = (P_SW_RFB_T) QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T) prSwRfb); -+ -+ /* free */ -+ nicRxReturnRFB(prAdapter, prSwRfb); -+ -+ prSwRfb = prNextSwRfb; -+ } while (prSwRfb); -+ } -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief -+* -+* @param -+* -+* @retval -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS nicRxProcessActionFrame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb) -+{ -+ P_WLAN_ACTION_FRAME prActFrame; -+ -+ ASSERT(prAdapter); -+ ASSERT(prSwRfb); -+ -+ if (prSwRfb->u2PacketLen < sizeof(WLAN_ACTION_FRAME) - 1) -+ return WLAN_STATUS_INVALID_PACKET; -+ prActFrame = (P_WLAN_ACTION_FRAME) prSwRfb->pvHeader; -+ DBGLOG(RX, INFO, "Category %u\n", prActFrame->ucCategory); -+ -+ switch (prActFrame->ucCategory) { -+ case CATEGORY_PUBLIC_ACTION: -+ if (HIF_RX_HDR_GET_NETWORK_IDX(prSwRfb->prHifRxHdr) == NETWORK_TYPE_AIS_INDEX) -+ aisFuncValidateRxActionFrame(prAdapter, prSwRfb); -+#if CFG_ENABLE_WIFI_DIRECT -+ else if (prAdapter->fgIsP2PRegistered) { -+ rlmProcessPublicAction(prAdapter, prSwRfb); -+ -+ p2pFuncValidateRxActionFrame(prAdapter, prSwRfb); -+ -+ } -+#endif -+ break; -+ -+ case CATEGORY_HT_ACTION: -+#if CFG_ENABLE_WIFI_DIRECT -+ if (prAdapter->fgIsP2PRegistered) -+ rlmProcessHtAction(prAdapter, prSwRfb); -+#endif -+ break; -+ case CATEGORY_VENDOR_SPECIFIC_ACTION: -+#if CFG_ENABLE_WIFI_DIRECT -+ if (prAdapter->fgIsP2PRegistered) -+ p2pFuncValidateRxActionFrame(prAdapter, prSwRfb); -+#endif -+ break; -+#if CFG_SUPPORT_802_11W -+ case CATEGORY_SA_QUERT_ACTION: -+ { -+ P_HIF_RX_HEADER_T prHifRxHdr; -+ -+ prHifRxHdr = prSwRfb->prHifRxHdr; -+ -+ if ((HIF_RX_HDR_GET_NETWORK_IDX(prHifRxHdr) == NETWORK_TYPE_AIS_INDEX) -+ && prAdapter->rWifiVar.rAisSpecificBssInfo.fgMgmtProtection /* Use MFP */) { -+ if (!(prHifRxHdr->ucReserved & CONTROL_FLAG_UC_MGMT_NO_ENC)) { -+ /* MFP test plan 5.3.3.4 */ -+ rsnSaQueryAction(prAdapter, prSwRfb); -+ } else { -+ DBGLOG(RSN, TRACE, "Un-Protected SA Query, do nothing\n"); -+ } -+ } -+ } -+ break; -+#endif -+#if CFG_SUPPORT_802_11V -+ case CATEGORY_WNM_ACTION: -+ { -+ wnmWNMAction(prAdapter, prSwRfb); -+ } -+ break; -+#endif -+ -+#if CFG_SUPPORT_DFS /* Add by Enlai */ -+ case CATEGORY_SPEC_MGT: -+ { -+ if (prAdapter->fgEnable5GBand == TRUE) -+ rlmProcessSpecMgtAction(prAdapter, prSwRfb); -+ } -+ break; -+#endif -+ -+#if (CFG_SUPPORT_TDLS == 1) -+ case 12: /* shall not be here */ -+ /* -+ A received TDLS Action frame with the Type field set to Management shall -+ be discarded. Note that the TDLS Discovery Response frame is not a TDLS -+ frame but a Public Action frame. -+ */ -+ break; -+#endif /* CFG_SUPPORT_TDLS */ -+ -+ default: -+ break; -+ } /* end of switch case */ -+ -+ return WLAN_STATUS_SUCCESS; -+} -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic_tx.c b/drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic_tx.c -new file mode 100644 -index 000000000000..024bd9507603 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic_tx.c -@@ -0,0 +1,2350 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/nic/nic_tx.c#1 -+*/ -+ -+/*! \file nic_tx.c -+ \brief Functions that provide TX operation in NIC Layer. -+ -+ This file provides TX functions which are responsible for both Hardware and -+ Software Resource Management and keep their Synchronization. -+*/ -+ -+/* -+** Log: nic_tx.c -+ * -+ * 06 13 2012 yuche.tsai -+ * NULL -+ * Update maintrunk driver. -+ * Add support for driver compose assoc request frame. -+ * -+ * 11 18 2011 eddie.chen -+ * [WCXRP00001096] [MT6620 Wi-Fi][Driver/FW] Enhance the log function (xlog) -+ * Add log counter for tx -+ * -+ * 11 09 2011 eddie.chen -+ * [WCXRP00001096] [MT6620 Wi-Fi][Driver/FW] Enhance the log function (xlog) -+ * Add xlog for beacon timeout and sta aging timeout. -+ * -+ * 11 08 2011 eddie.chen -+ * [WCXRP00001096] [MT6620 Wi-Fi][Driver/FW] Enhance the log function (xlog) -+ * Add xlog function. -+ * -+ * 05 17 2011 cp.wu -+ * [WCXRP00000732] [MT6620 Wi-Fi][AIS] No need to switch back to IDLE state when DEAUTH frame is dropped due to bss -+ * disconnection -+ * when TX DONE status is TX_RESULT_DROPPED_IN_DRIVER, no need to switch back to IDLE state. -+ * -+ * 04 12 2011 eddie.chen -+ * [WCXRP00000617] [MT6620 Wi-Fi][DRV/FW] Fix for sigma -+ * Fix the sta index in processing security frame -+ * Simple flow control for TC4 to avoid mgt frames for PS STA to occupy the TC4 -+ * Add debug message. -+ * -+ * 04 12 2011 cp.wu -+ * [WCXRP00000631] [MT6620 Wi-Fi][Driver] Add an API for QM to retrieve current TC counter value and processing frame -+ * dropping cases for TC4 path -+ * remove unused variables. -+ * -+ * 04 12 2011 cp.wu -+ * [WCXRP00000631] [MT6620 Wi-Fi][Driver] Add an API for QM to retrieve current TC counter value and processing frame -+ * dropping cases for TC4 path -+ * 1. add nicTxGetResource() API for QM to make decisions. -+ * 2. if management frames is decided by QM for dropping, the call back is invoked to indicate such a case. -+ * -+ * 03 17 2011 cp.wu -+ * [WCXRP00000562] [MT6620 Wi-Fi][Driver] I/O buffer pre-allocation to avoid physically continuous memory shortage -+ * after system running for a long period -+ * use pre-allocated buffer for storing enhanced interrupt response as well -+ * -+ * 03 15 2011 cp.wu -+ * [WCXRP00000559] [MT6620 Wi-Fi][Driver] Combine TX/RX DMA buffers into a single one to reduce physically continuous -+ * memory consumption -+ * 1. deprecate CFG_HANDLE_IST_IN_SDIO_CALLBACK -+ * 2. Use common coalescing buffer for both TX/RX directions -+ * -+ * -+ * 02 16 2011 cp.wu -+ * [WCXRP00000449] [MT6620 Wi-Fi][Driver] Refine CMD queue handling by adding an extra API for checking available count -+ * and modify behavior -+ * 1. add new API: nicTxGetFreeCmdCount() -+ * 2. when there is insufficient command descriptor, nicTxEnqueueMsdu() will drop command packets directly -+ * -+ * 01 24 2011 cp.wu -+ * [WCXRP00000382] [MT6620 Wi-Fi][Driver] Track forwarding packet number with notifying tx thread for serving -+ * 1. add an extra counter for tracking pending forward frames. -+ * 2. notify TX service thread as well when there is pending forward frame -+ * 3. correct build errors leaded by introduction of Wi-Fi direct separation module -+ * -+ * 01 12 2011 cp.wu -+ * [WCXRP00000356] [MT6620 Wi-Fi][Driver] fill mac header length for security frames 'cause hardware header translation -+ * needs such information -+ * fill mac header length information for 802.1x frames. -+ * -+ * 12 31 2010 cp.wu -+ * [WCXRP00000335] [MT6620 Wi-Fi][Driver] change to use milliseconds sleep instead of delay to avoid blocking to system -+ * scheduling -+ * change to use msleep() and shorten waiting interval to reduce blocking to other task while Wi-Fi driver is being -+ * loaded -+ * -+ * 11 01 2010 yarco.yang -+ * [WCXRP00000149] [MT6620 WI-Fi][Driver]Fine tune performance on MT6516 platform -+ * Add GPIO debug function -+ * -+ * 10 18 2010 cp.wu -+ * [WCXRP00000117] [MT6620 Wi-Fi][Driver] Add logic for suspending driver when MT6620 is not responding anymore -+ * 1. when wlanAdapterStop() failed to send POWER CTRL command to firmware, do not poll for ready bit dis-assertion -+ * 2. shorten polling count for shorter response time -+ * 3. if bad I/O operation is detected during TX resource polling, then further operation is aborted as well -+ * -+ * 10 06 2010 cp.wu -+ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning -+ * code reorganization to improve isolation between GLUE and CORE layers. -+ * -+ * 09 29 2010 wh.su -+ * [WCXRP00000072] [MT6620 Wi-Fi][Driver] Fix TKIP Counter Measure EAPoL callback register issue -+ * [MT6620 Wi-Fi][Driver] Fix TKIP Counter Measure EAPoL callback register issue. -+ * -+ * 09 27 2010 wh.su -+ * NULL -+ * since the u2TxByteCount_UserPriority will or another setting, keep the overall buffer for avoid error -+ * -+ * 09 24 2010 wh.su -+ * NULL -+ * [WCXRP000000058][MT6620 Wi-Fi][Driver] Fail to handshake with WAPI AP due the 802.1x frame send to fw with extra -+ * bytes padding. -+ * -+ * 09 01 2010 cp.wu -+ * NULL -+ * HIFSYS Clock Source Workaround -+ * -+ * 08 30 2010 cp.wu -+ * NULL -+ * API added: nicTxPendingPackets(), for simplifying porting layer -+ * -+ * 08 30 2010 cp.wu -+ * NULL -+ * eliminate klockwork errors -+ * -+ * 08 20 2010 wh.su -+ * NULL -+ * adding the eapol callback setting. -+ * -+ * 08 18 2010 yarco.yang -+ * NULL -+ * 1. Fixed HW checksum offload function not work under Linux issue. -+ * 2. Add debug message. -+ * -+ * 08 05 2010 yuche.tsai -+ * NULL -+ * . -+ * -+ * 08 03 2010 cp.wu -+ * NULL -+ * surpress compilation warning. -+ * -+ * 08 02 2010 jeffrey.chang -+ * NULL -+ * 1) modify tx service thread to avoid busy looping -+ * 2) add spin lock declartion for linux build -+ * -+ * 07 29 2010 cp.wu -+ * NULL -+ * simplify post-handling after TX_DONE interrupt is handled. -+ * -+ * 07 19 2010 jeffrey.chang -+ * -+ * Linux port modification -+ * -+ * 07 13 2010 cp.wu -+ * -+ * 1) MMPDUs are now sent to MT6620 by CMD queue for keeping strict order of 1X/MMPDU/CMD packets -+ * 2) integrate with qmGetFrameAction() for deciding which MMPDU/1X could pass checking for sending -+ * 2) enhance CMD_INFO_T descriptor number from 10 to 32 to avoid descriptor underflow under concurrent network -+ * operation -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 29 2010 yarco.yang -+ * [WPD00003837][MT6620]Data Path Refine -+ * replace g_rQM with Adpater->rQM -+ * -+ * 06 25 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add API in que_mgt to retrieve sta-rec index for security frames. -+ * -+ * 06 24 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 802.1x and bluetooth-over-Wi-Fi security frames are now delievered to firmware via command path instead of data path. -+ * -+ * 06 23 2010 yarco.yang -+ * [WPD00003837][MT6620]Data Path Refine -+ * Merge g_arStaRec[] into adapter->arStaRec[] -+ * -+ * 06 22 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) add command warpper for STA-REC/BSS-INFO sync. -+ * 2) enhance command packet sending procedure for non-oid part -+ * 3) add command packet definitions for STA-REC/BSS-INFO sync. -+ * -+ * 06 21 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add checking for TX descriptor poll. -+ * -+ * 06 21 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * TX descriptors are now allocated once for reducing allocation overhead -+ * -+ * 06 18 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Provide cnmMgtPktAlloc() and alloc/free function of msg/buf -+ * -+ * 06 15 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * change zero-padding for TX port access to HAL. -+ * -+ * 06 15 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * . -+ * -+ * 06 15 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * . -+ * -+ * 06 14 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * fill extra information for revised HIF_TX_HEADER. -+ * -+ * 06 11 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) migrate assoc.c. -+ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness -+ * 3) add configuration options for CNM_MEM and RSN modules -+ * 4) add data path for management frames -+ * 5) eliminate rPacketInfo of MSDU_INFO_T -+ * -+ * 06 10 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * change to enqueue TX frame infinitely. -+ * -+ * 06 09 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add TX_PACKET_MGMT to indicate the frame is coming from management modules -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 05 10 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * fill network type field while doing frame identification. -+ * -+ * 04 23 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * surpress compiler warning -+ * -+ * 04 06 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * Tag the packet for QoS on Tx path -+ * -+ * 03 30 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * remove driver-land statistics. -+ * -+ * 03 29 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * improve none-glue code portability -+ * -+ * 03 24 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * initial import for Linux port -+ * -+ * 03 24 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * generate information for OID_GEN_RCV_OK & OID_GEN_XMIT_OK -+ * * * * * -+ * -+* 03 10 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * code clean: removing unused variables and structure definitions -+ * -+ * 03 08 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) add another spin-lock to protect MsduInfoList due to it might be accessed by different thread. -+ * * * * 2) change own-back acquiring procedure to wait for up to 16.67 seconds -+ * -+ * 03 02 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * add mutex to avoid multiple access to qmTxQueue simultaneously. -+ * -+ * 02 26 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * avoid referring to NDIS-specific data structure directly from non-glue layer. -+ * -+ * 02 24 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * add Ethernet destination address information in packet info for TX -+ * -+ * 02 10 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) remove unused function in nic_rx.c [which has been handled in que_mgt.c] -+ * * * * * * 2) firmware image length is now retrieved via NdisFileOpen -+ * * * * * * 3) firmware image is not structured by (P_IMG_SEC_HDR_T) anymore -+ * * * * * * 4) nicRxWaitResponse() revised -+ * * * * * * 5) another set of TQ counter default value is added for fw-download state -+ * * * * * * 6) Wi-Fi load address is now retrieved from registry too -+ * -+ * 02 09 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1. Permanent and current MAC address are now retrieved by CMD/EVENT packets instead of hard-coded address -+ * * * * * * * * * 2. follow MSDN defined behavior when associates to another AP -+ * * * * * * * * * 3. for firmware download, packet size could be up to 2048 bytes -+ * -+ * 02 08 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * prepare for implementing fw download logic -+ * -+ * 01 27 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1. eliminate improper variable in rHifInfo -+ * * * * * * * * * 2. block TX/ordinary OID when RF test mode is engaged -+ * * * * * * * * * 3. wait until firmware finish operation when entering into and leaving from RF test mode -+ * * * * * * * * * 4. correct some HAL implementation -+ * -+ * 01 13 2010 tehuang.liu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * Enabled the Burst_End Indication mechanism -+ * -+ * 01 13 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * TX: fill ucWlanHeaderLength/ucPktFormtId_Flags according to info provided by prMsduInfo -+ * -+ * 12 30 2009 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) According to CMD/EVENT documentation v0.8, -+ * * * * * * * * * * OID_CUSTOM_TEST_RX_STATUS & OID_CUSTOM_TEST_TX_STATUS is no longer used, -+ * * * * * * * * * * and result is retrieved by get ATInfo instead -+ * * * * * * * * * * 2) add 4 counter for recording aggregation statistics -+** \main\maintrunk.MT6620WiFiDriver_Prj\44 2009-12-10 16:52:15 GMT mtk02752 -+** remove unused API -+** \main\maintrunk.MT6620WiFiDriver_Prj\43 2009-12-07 22:44:24 GMT mtk02752 -+** correct assertion criterion -+** \main\maintrunk.MT6620WiFiDriver_Prj\42 2009-12-07 21:15:52 GMT mtk02752 -+** correct trivial mistake -+** \main\maintrunk.MT6620WiFiDriver_Prj\41 2009-12-04 15:47:21 GMT mtk02752 -+** + always append a dword of zero on TX path to avoid TX aggregation to triggered on uninitialized data -+** + add more assertion for packet size check -+** \main\maintrunk.MT6620WiFiDriver_Prj\40 2009-12-04 14:51:55 GMT mtk02752 -+** nicTxMsduInfo(): save ptr for next entry before attaching to qDataPort -+** \main\maintrunk.MT6620WiFiDriver_Prj\39 2009-12-04 11:54:54 GMT mtk02752 -+** add 2 assertion for size check -+** \main\maintrunk.MT6620WiFiDriver_Prj\38 2009-12-03 16:20:35 GMT mtk01461 -+** Add debug message -+** \main\maintrunk.MT6620WiFiDriver_Prj\37 2009-11-30 10:57:10 GMT mtk02752 -+** 1st DW of WIFI_CMD_T is shared with HIF_TX_HEADER_T -+** \main\maintrunk.MT6620WiFiDriver_Prj\36 2009-11-30 09:20:43 GMT mtk02752 -+** use TC4 instead of TC5 for command packet -+** \main\maintrunk.MT6620WiFiDriver_Prj\35 2009-11-27 11:08:11 GMT mtk02752 -+** add flush for reset -+** \main\maintrunk.MT6620WiFiDriver_Prj\34 2009-11-26 20:31:22 GMT mtk02752 -+** fill prMsduInfo->ucUserPriority -+** \main\maintrunk.MT6620WiFiDriver_Prj\33 2009-11-25 21:04:33 GMT mtk02752 -+** fill u2SeqNo -+** \main\maintrunk.MT6620WiFiDriver_Prj\32 2009-11-24 20:52:12 GMT mtk02752 -+** integration with SD1's data path API -+** \main\maintrunk.MT6620WiFiDriver_Prj\31 2009-11-24 19:54:25 GMT mtk02752 -+** nicTxRetransmitOfOsSendQue & nicTxData but changed to use nicTxMsduInfoList -+** \main\maintrunk.MT6620WiFiDriver_Prj\30 2009-11-23 17:53:18 GMT mtk02752 -+** add nicTxCmd() for SD1_SD3_DATAPATH_INTEGRATION, which will append only HIF_TX_HEADER. seqNum, -+** WIFI_CMD_T will be created inside oid handler -+** \main\maintrunk.MT6620WiFiDriver_Prj\29 2009-11-20 15:10:24 GMT mtk02752 -+** use TxAccquireResource instead of accessing TCQ directly. -+** \main\maintrunk.MT6620WiFiDriver_Prj\28 2009-11-17 22:40:57 GMT mtk01084 -+** \main\maintrunk.MT6620WiFiDriver_Prj\27 2009-11-17 17:35:40 GMT mtk02752 -+** add nicTxMsduInfoList () implementation -+** \main\maintrunk.MT6620WiFiDriver_Prj\26 2009-11-17 11:07:10 GMT mtk02752 -+** add nicTxAdjustTcq() implementation -+** \main\maintrunk.MT6620WiFiDriver_Prj\25 2009-11-16 22:28:38 GMT mtk02752 -+** move aucFreeBufferCount/aucMaxNumOfBuffer into another structure -+** \main\maintrunk.MT6620WiFiDriver_Prj\24 2009-11-16 21:45:32 GMT mtk02752 -+** add SD1_SD3_DATAPATH_INTEGRATION data path handling -+** \main\maintrunk.MT6620WiFiDriver_Prj\23 2009-11-13 13:29:56 GMT mtk01084 -+** modify TX hdr format, fix tx retransmission issue -+** \main\maintrunk.MT6620WiFiDriver_Prj\22 2009-11-11 10:36:21 GMT mtk01084 -+** \main\maintrunk.MT6620WiFiDriver_Prj\21 2009-11-04 14:11:11 GMT mtk01084 -+** modify TX SW data structure -+** \main\maintrunk.MT6620WiFiDriver_Prj\20 2009-10-29 19:56:17 GMT mtk01084 -+** modify HAL part -+** \main\maintrunk.MT6620WiFiDriver_Prj\19 2009-10-13 21:59:23 GMT mtk01084 -+** update for new HW design -+** \main\maintrunk.MT6620WiFiDriver_Prj\18 2009-10-02 14:00:18 GMT mtk01725 -+** \main\maintrunk.MT6620WiFiDriver_Prj\17 2009-05-20 12:26:06 GMT mtk01461 -+** Assign SeqNum to CMD Packet -+** \main\maintrunk.MT6620WiFiDriver_Prj\16 2009-05-19 10:54:04 GMT mtk01461 -+** Add debug message -+** \main\maintrunk.MT6620WiFiDriver_Prj\15 2009-05-12 09:41:55 GMT mtk01461 -+** Fix Query Command need resp issue -+** \main\maintrunk.MT6620WiFiDriver_Prj\14 2009-04-29 15:44:38 GMT mtk01461 -+** Move OS dependent code to kalQueryTxOOBData() -+** \main\maintrunk.MT6620WiFiDriver_Prj\13 2009-04-28 10:40:03 GMT mtk01461 -+** Add nicTxReleaseResource() for SDIO_STATUS_ENHANCE, and also fix the TX aggregation issue for 1x packet to TX1 port -+** \main\maintrunk.MT6620WiFiDriver_Prj\12 2009-04-21 09:50:47 GMT mtk01461 -+** Update nicTxCmd() for moving wait RESP function call to wlanSendCommand() -+** \main\maintrunk.MT6620WiFiDriver_Prj\11 2009-04-17 19:56:32 GMT mtk01461 -+** Move the CMD_INFO_T related function to cmd_buf.c -+** \main\maintrunk.MT6620WiFiDriver_Prj\10 2009-04-17 18:14:40 GMT mtk01426 -+** Update OOB query for TX packet -+** \main\maintrunk.MT6620WiFiDriver_Prj\9 2009-04-14 15:51:32 GMT mtk01426 -+** Support PKGUIO -+** \main\maintrunk.MT6620WiFiDriver_Prj\8 2009-04-02 17:26:40 GMT mtk01461 -+** Add virtual OOB for HIF LOOPBACK SW PRETEST -+** \main\maintrunk.MT6620WiFiDriver_Prj\7 2009-04-01 10:54:43 GMT mtk01461 -+** Add function for SDIO_TX_ENHANCE -+** \main\maintrunk.MT6620WiFiDriver_Prj\6 2009-03-23 21:53:47 GMT mtk01461 -+** Add code for retransmit of rOsSendQueue, mpSendPacket(), and add code for TX Checksum offload, Loopback Test. -+** \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-03-23 00:33:51 GMT mtk01461 -+** Add code for TX Data & Cmd Packet -+** \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-03-18 20:25:40 GMT mtk01461 -+** Fix LINT warning -+** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-03-16 09:10:30 GMT mtk01461 -+** Update TX PATH API -+** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 20:26:04 GMT mtk01426 -+** Init for develop -+** -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "precomp.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will initial all variables in regard to SW TX Queues and -+* all free lists of MSDU_INFO_T and SW_TFCB_T. -+* -+* @param prAdapter Pointer to the Adapter structure. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicTxInitialize(IN P_ADAPTER_T prAdapter) -+{ -+ P_TX_CTRL_T prTxCtrl; -+ PUINT_8 pucMemHandle; -+ P_MSDU_INFO_T prMsduInfo; -+ UINT_32 i; -+ -+ KAL_SPIN_LOCK_DECLARATION(); -+ -+ DEBUGFUNC("nicTxInitialize"); -+ -+ ASSERT(prAdapter); -+ prTxCtrl = &prAdapter->rTxCtrl; -+ -+ /* 4 <1> Initialization of Traffic Class Queue Parameters */ -+ nicTxResetResource(prAdapter); -+ -+#if CFG_SDIO_TX_AGG -+ prTxCtrl->pucTxCoalescingBufPtr = prAdapter->pucCoalescingBufCached; -+#endif /* CFG_SDIO_TX_AGG */ -+ -+ /* allocate MSDU_INFO_T and link it into rFreeMsduInfoList */ -+ QUEUE_INITIALIZE(&prTxCtrl->rFreeMsduInfoList); -+ -+ pucMemHandle = prTxCtrl->pucTxCached; -+ for (i = 0; i < CFG_TX_MAX_PKT_NUM; i++) { -+ prMsduInfo = (P_MSDU_INFO_T) pucMemHandle; -+ kalMemZero(prMsduInfo, sizeof(MSDU_INFO_T)); -+ -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_MSDU_INFO_LIST); -+ QUEUE_INSERT_TAIL(&prTxCtrl->rFreeMsduInfoList, (P_QUE_ENTRY_T) prMsduInfo); -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_MSDU_INFO_LIST); -+ -+ pucMemHandle += ALIGN_4(sizeof(MSDU_INFO_T)); -+ } -+ -+ ASSERT(prTxCtrl->rFreeMsduInfoList.u4NumElem == CFG_TX_MAX_PKT_NUM); -+ /* Check if the memory allocation consist with this initialization function */ -+ ASSERT((UINT_32) (pucMemHandle - prTxCtrl->pucTxCached) == prTxCtrl->u4TxCachedSize); -+ -+ QUEUE_INITIALIZE(&prTxCtrl->rTxMgmtTxingQueue); -+ prTxCtrl->i4TxMgmtPendingNum = 0; -+ -+#if CFG_HIF_STATISTICS -+ prTxCtrl->u4TotalTxAccessNum = 0; -+ prTxCtrl->u4TotalTxPacketNum = 0; -+#endif -+ -+ prTxCtrl->i4PendingFwdFrameCount = 0; -+ -+ qmInit(prAdapter); -+ -+ TX_RESET_ALL_CNTS(prTxCtrl); -+ -+} /* end of nicTxInitialize() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Driver maintain a variable that is synchronous with the usage of individual -+* TC Buffer Count. This function will check if has enough TC Buffer for incoming -+* packet and then update the value after promise to provide the resources. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] ucTC Specify the resource of TC -+* -+* \retval WLAN_STATUS_SUCCESS Resource is available and been assigned. -+* \retval WLAN_STATUS_RESOURCES Resource is not available. -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT_32 u4CurrTick = 0; -+WLAN_STATUS nicTxAcquireResource(IN P_ADAPTER_T prAdapter, IN UINT_8 ucTC, IN BOOLEAN pfgIsSecOrMgmt) -+{ -+#define TC4_NO_RESOURCE_DELAY_MS 5 /* exponential of 5s */ -+ -+ P_TX_CTRL_T prTxCtrl; -+ WLAN_STATUS u4Status = WLAN_STATUS_RESOURCES; -+ P_QUE_MGT_T prQM; -+ -+ KAL_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(prAdapter); -+ prTxCtrl = &prAdapter->rTxCtrl; -+ -+ prQM = &prAdapter->rQM; -+ -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_RESOURCE); -+ -+/* DbgPrint("nicTxAcquireResource prTxCtrl->rTc.aucFreeBufferCount[%d]=%d\n", -+ ucTC, prTxCtrl->rTc.aucFreeBufferCount[ucTC]); */ -+ do { -+ if (pfgIsSecOrMgmt && (ucTC == TC4_INDEX)) { -+ if (prTxCtrl->rTc.aucFreeBufferCount[ucTC] < 2) { -+ DBGLOG(TX, EVENT, " aucFreeBufferCount = %d\n", -+ prTxCtrl->rTc.aucFreeBufferCount[ucTC]); -+ -+ if (prTxCtrl->rTc.aucFreeBufferCount[ucTC]) -+ u4CurrTick = 0; -+ -+ break; -+ } -+ } -+ -+ if (prTxCtrl->rTc.aucFreeBufferCount[ucTC]) { -+ -+ if (ucTC == TC4_INDEX) -+ u4CurrTick = 0; -+ /* get a available TX entry */ -+ prTxCtrl->rTc.aucFreeBufferCount[ucTC]--; -+ -+ prQM->au4ResourceUsedCounter[ucTC]++; -+ -+ DBGLOG(TX, EVENT, "Acquire: TC = %d aucFreeBufferCount = %d\n", -+ ucTC, prTxCtrl->rTc.aucFreeBufferCount[ucTC]); -+ -+ u4Status = WLAN_STATUS_SUCCESS; -+ } -+ } while (FALSE); -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_RESOURCE); -+ -+ if (ucTC == TC4_INDEX) { -+ if (u4CurrTick == 0) -+ u4CurrTick = kalGetTimeTick(); -+ if (CHECK_FOR_TIMEOUT(kalGetTimeTick(), u4CurrTick, -+ SEC_TO_SYSTIME(TC4_NO_RESOURCE_DELAY_MS))) { -+ wlanDumpTcResAndTxedCmd(NULL, 0); -+ cmdBufDumpCmdQueue(&prAdapter->rPendingCmdQueue, "waiting response CMD queue"); -+ glDumpConnSysCpuInfo(prAdapter->prGlueInfo); -+ kalSendAeeWarning("[TC4 no resource delay 5s!]", __func__); -+ glDoChipReset(); -+ u4CurrTick = 0; -+ } -+ } -+ return u4Status; -+ -+} /* end of nicTxAcquireResourceAndTFCBs() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Driver maintain a variable that is synchronous with the usage of individual -+* TC Buffer Count. This function will do polling if FW has return the resource. -+* Used when driver start up before enable interrupt. -+* -+* @param prAdapter Pointer to the Adapter structure. -+* @param ucTC Specify the resource of TC -+* -+* @retval WLAN_STATUS_SUCCESS Resource is available. -+* @retval WLAN_STATUS_FAILURE Resource is not available. -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS nicTxPollingResource(IN P_ADAPTER_T prAdapter, IN UINT_8 ucTC) -+{ -+ P_TX_CTRL_T prTxCtrl; -+ WLAN_STATUS u4Status = WLAN_STATUS_FAILURE; -+ INT_32 i = NIC_TX_RESOURCE_POLLING_TIMEOUT; -+ UINT_32 au4WTSR[2]; -+ -+ ASSERT(prAdapter); -+ prTxCtrl = &prAdapter->rTxCtrl; -+ -+ if (ucTC >= TC_NUM) -+ return WLAN_STATUS_FAILURE; -+ -+ if (prTxCtrl->rTc.aucFreeBufferCount[ucTC] > 0) -+ return WLAN_STATUS_SUCCESS; -+ -+ while (i-- > 0) { -+ HAL_READ_TX_RELEASED_COUNT(prAdapter, au4WTSR); -+ -+ if (kalIsCardRemoved(prAdapter->prGlueInfo) == TRUE || fgIsBusAccessFailed == TRUE) { -+ u4Status = WLAN_STATUS_FAILURE; -+ break; -+ } else if (nicTxReleaseResource(prAdapter, (PUINT_8) au4WTSR)) { -+ if (prTxCtrl->rTc.aucFreeBufferCount[ucTC] > 0) { -+ u4Status = WLAN_STATUS_SUCCESS; -+ break; -+ } -+ kalMsleep(NIC_TX_RESOURCE_POLLING_DELAY_MSEC); -+ -+ } else { -+ kalMsleep(NIC_TX_RESOURCE_POLLING_DELAY_MSEC); -+ } -+ } -+ -+ if (i <= 0 && ucTC == TC4_INDEX) { -+ DBGLOG(TX, ERROR, "polling Tx resource for Tc4 timeout\n"); -+ glDumpConnSysCpuInfo(prAdapter->prGlueInfo); -+ } -+#if DBG -+ { -+ INT_32 i4Times = NIC_TX_RESOURCE_POLLING_TIMEOUT - (i + 1); -+ -+ if (i4Times) { -+ DBGLOG(TX, TRACE, "Polling MCR_WTSR delay %d times, %d msec\n", -+ i4Times, (i4Times * NIC_TX_RESOURCE_POLLING_DELAY_MSEC)); -+ } -+ } -+#endif /* DBG */ -+ -+ return u4Status; -+ -+} /* end of nicTxPollingResource() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Driver maintain a variable that is synchronous with the usage of individual -+* TC Buffer Count. This function will release TC Buffer count according to -+* the given TX_STATUS COUNTER after TX Done. -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* \param[in] u4TxStatusCnt Value of TX STATUS -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN nicTxReleaseResource(IN P_ADAPTER_T prAdapter, IN unsigned char *aucTxRlsCnt) -+{ -+ PUINT_32 pu4Tmp = (PUINT_32) aucTxRlsCnt; -+ P_TX_CTRL_T prTxCtrl; -+ BOOLEAN bStatus = FALSE; -+ UINT_32 i; -+ -+ KAL_SPIN_LOCK_DECLARATION(); -+ -+ P_QUE_MGT_T prQM = &prAdapter->rQM; -+ prTxCtrl = &prAdapter->rTxCtrl; -+ -+ if (pu4Tmp[0] | pu4Tmp[1]) { -+ -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_RESOURCE); -+ for (i = 0; i < TC_NUM; i++) -+ prTxCtrl->rTc.aucFreeBufferCount[i] += aucTxRlsCnt[i]; -+ for (i = 0; i < TC_NUM; i++) -+ prQM->au4QmTcResourceBackCounter[i] += aucTxRlsCnt[i]; -+ if (aucTxRlsCnt[TC4_INDEX] != 0) -+ wlanTraceReleaseTcRes(prAdapter, aucTxRlsCnt, prTxCtrl->rTc.aucFreeBufferCount[TC4_INDEX]); -+ -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_RESOURCE); -+#if 0 -+ for (i = 0; i < TC_NUM; i++) { -+ DBGLOG(TX, TRACE, "aucFreeBufferCount[%d]: %d, aucMaxNumOfBuffer[%d]: %d\n", -+ i, prTxCtrl->rTc.aucFreeBufferCount[i], i, -+ prTxCtrl->rTc.aucMaxNumOfBuffer[i]); -+ } -+ DbgPrint("prTxCtrl->rTc.aucFreeBufferCount[0]=%d\n", prTxCtrl->rTc.aucFreeBufferCount[0]); -+ DbgPrint("prTxCtrl->rTc.aucFreeBufferCount[1]=%d\n", prTxCtrl->rTc.aucFreeBufferCount[1]); -+ DbgPrint("prTxCtrl->rTc.aucFreeBufferCount[2]=%d\n", prTxCtrl->rTc.aucFreeBufferCount[2]); -+ DbgPrint("prTxCtrl->rTc.aucFreeBufferCount[3]=%d\n", prTxCtrl->rTc.aucFreeBufferCount[3]); -+ DbgPrint("prTxCtrl->rTc.aucFreeBufferCount[4]=%d\n", prTxCtrl->rTc.aucFreeBufferCount[4]); -+ DbgPrint("prTxCtrl->rTc.aucFreeBufferCount[5]=%d\n", prTxCtrl->rTc.aucFreeBufferCount[5]); -+#endif -+ ASSERT(prTxCtrl->rTc.aucFreeBufferCount[TC0_INDEX] <= prTxCtrl->rTc.aucMaxNumOfBuffer[TC0_INDEX]); -+ ASSERT(prTxCtrl->rTc.aucFreeBufferCount[TC1_INDEX] <= prTxCtrl->rTc.aucMaxNumOfBuffer[TC1_INDEX]); -+ ASSERT(prTxCtrl->rTc.aucFreeBufferCount[TC2_INDEX] <= prTxCtrl->rTc.aucMaxNumOfBuffer[TC2_INDEX]); -+ ASSERT(prTxCtrl->rTc.aucFreeBufferCount[TC3_INDEX] <= prTxCtrl->rTc.aucMaxNumOfBuffer[TC3_INDEX]); -+ ASSERT(prTxCtrl->rTc.aucFreeBufferCount[TC4_INDEX] <= prTxCtrl->rTc.aucMaxNumOfBuffer[TC4_INDEX]); -+ ASSERT(prTxCtrl->rTc.aucFreeBufferCount[TC5_INDEX] <= prTxCtrl->rTc.aucMaxNumOfBuffer[TC5_INDEX]); -+ bStatus = TRUE; -+ } -+ -+ return bStatus; -+} /* end of nicTxReleaseResource() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Reset TC Buffer Count to initialized value -+* -+* \param[in] prAdapter Pointer to the Adapter structure. -+* -+* @return WLAN_STATUS_SUCCESS -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS nicTxResetResource(IN P_ADAPTER_T prAdapter) -+{ -+ P_TX_CTRL_T prTxCtrl; -+ -+ KAL_SPIN_LOCK_DECLARATION(); -+ -+ DEBUGFUNC("nicTxResetResource"); -+ -+ ASSERT(prAdapter); -+ prTxCtrl = &prAdapter->rTxCtrl; -+ -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_RESOURCE); -+ -+ prTxCtrl->rTc.aucMaxNumOfBuffer[TC0_INDEX] = NIC_TX_BUFF_COUNT_TC0; -+ prTxCtrl->rTc.aucFreeBufferCount[TC0_INDEX] = NIC_TX_BUFF_COUNT_TC0; -+ -+ prTxCtrl->rTc.aucMaxNumOfBuffer[TC1_INDEX] = NIC_TX_BUFF_COUNT_TC1; -+ prTxCtrl->rTc.aucFreeBufferCount[TC1_INDEX] = NIC_TX_BUFF_COUNT_TC1; -+ -+ prTxCtrl->rTc.aucMaxNumOfBuffer[TC2_INDEX] = NIC_TX_BUFF_COUNT_TC2; -+ prTxCtrl->rTc.aucFreeBufferCount[TC2_INDEX] = NIC_TX_BUFF_COUNT_TC2; -+ -+ prTxCtrl->rTc.aucMaxNumOfBuffer[TC3_INDEX] = NIC_TX_BUFF_COUNT_TC3; -+ prTxCtrl->rTc.aucFreeBufferCount[TC3_INDEX] = NIC_TX_BUFF_COUNT_TC3; -+ -+ prTxCtrl->rTc.aucMaxNumOfBuffer[TC4_INDEX] = NIC_TX_BUFF_COUNT_TC4; -+ prTxCtrl->rTc.aucFreeBufferCount[TC4_INDEX] = NIC_TX_BUFF_COUNT_TC4; -+ -+ prTxCtrl->rTc.aucMaxNumOfBuffer[TC5_INDEX] = NIC_TX_BUFF_COUNT_TC5; -+ prTxCtrl->rTc.aucFreeBufferCount[TC5_INDEX] = NIC_TX_BUFF_COUNT_TC5; -+ -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_RESOURCE); -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Driver maintain a variable that is synchronous with the usage of individual -+* TC Buffer Count. This function will return the value for other component -+* which needs this information for making decisions -+* -+* @param prAdapter Pointer to the Adapter structure. -+* @param ucTC Specify the resource of TC -+* -+* @retval UINT_8 The number of corresponding TC number -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT_8 nicTxGetResource(IN P_ADAPTER_T prAdapter, IN UINT_8 ucTC) -+{ -+ P_TX_CTRL_T prTxCtrl; -+ -+ ASSERT(prAdapter); -+ prTxCtrl = &prAdapter->rTxCtrl; -+ -+ ASSERT(prTxCtrl); -+ -+ if (ucTC >= TC_NUM) -+ return 0; -+ else -+ return prTxCtrl->rTc.aucFreeBufferCount[ucTC]; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief In this function, we'll aggregate frame(PACKET_INFO_T) -+* corresponding to HIF TX port -+* -+* @param prAdapter Pointer to the Adapter structure. -+* @param prMsduInfoListHead a link list of P_MSDU_INFO_T -+* -+* @retval WLAN_STATUS_SUCCESS Bus access ok. -+* @retval WLAN_STATUS_FAILURE Bus access fail. -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS nicTxMsduInfoList(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfoListHead) -+{ -+ P_MSDU_INFO_T prMsduInfo, prNextMsduInfo; -+ QUE_T qDataPort0, qDataPort1; -+ WLAN_STATUS status; -+ BOOLEAN pfgIsSecOrMgmt = FALSE; -+ -+ ASSERT(prAdapter); -+ ASSERT(prMsduInfoListHead); -+ -+ prMsduInfo = prMsduInfoListHead; -+ -+ QUEUE_INITIALIZE(&qDataPort0); -+ QUEUE_INITIALIZE(&qDataPort1); -+ -+ /* Separate MSDU_INFO_T lists into 2 categories: for Port#0 & Port#1 */ -+ while (prMsduInfo) { -+ prNextMsduInfo = (P_MSDU_INFO_T) QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T) prMsduInfo); -+#if DBG && 0 -+ LOG_FUNC("nicTxMsduInfoList Acquire TC %d net %u mac len %u len %u Type %u 1x %u 11 %u\n", -+ prMsduInfo->ucTC, -+ prMsduInfo->ucNetworkType, -+ prMsduInfo->ucMacHeaderLength, -+ prMsduInfo->u2FrameLength, -+ prMsduInfo->ucPacketType, prMsduInfo->fgIs802_1x, prMsduInfo->fgIs802_11); -+ -+ LOG_FUNC("Dest Mac: %pM\n", prMsduInfo->aucEthDestAddr); -+#endif -+ -+ /* double-check available TX resouce (need to sync with CONNSYS FW) */ -+ /* caller must guarantee that the TX resource is enough in the func; OR assert here */ -+ switch (prMsduInfo->ucTC) { -+ case TC0_INDEX: -+ case TC1_INDEX: -+ case TC2_INDEX: -+ case TC3_INDEX: -+ case TC5_INDEX: /* Broadcast/multicast data packets */ -+ QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T) prMsduInfo) = NULL; -+ QUEUE_INSERT_TAIL(&qDataPort0, (P_QUE_ENTRY_T) prMsduInfo); -+ status = nicTxAcquireResource(prAdapter, prMsduInfo->ucTC, FALSE); -+ ASSERT(status == WLAN_STATUS_SUCCESS) -+ -+ break; -+ -+ case TC4_INDEX: /* Command or 802.1x packets */ -+ QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T) prMsduInfo) = NULL; -+ QUEUE_INSERT_TAIL(&qDataPort1, (P_QUE_ENTRY_T) prMsduInfo); -+ -+ if ((prMsduInfo->fgIs802_1x == TRUE) || -+ (prMsduInfo->fgIs802_11 == TRUE)) -+ pfgIsSecOrMgmt = TRUE; -+ -+ status = nicTxAcquireResource(prAdapter, prMsduInfo->ucTC, pfgIsSecOrMgmt); -+ ASSERT(status == WLAN_STATUS_SUCCESS) -+ -+ break; -+ -+ default: -+ ASSERT(0); -+ break; -+ } -+ -+ prMsduInfo = prNextMsduInfo; -+ } -+ -+ /* send packets to HIF port0 or port1 here */ -+ if (qDataPort0.u4NumElem > 0) -+ nicTxMsduQueue(prAdapter, 0, &qDataPort0); -+ -+ if (qDataPort1.u4NumElem > 0) -+ nicTxMsduQueue(prAdapter, 1, &qDataPort1); -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+#if CFG_ENABLE_PKT_LIFETIME_PROFILE -+ -+#if CFG_PRINT_RTP_PROFILE -+PKT_PROFILE_T rPrevRoundLastPkt; -+ -+BOOLEAN -+nicTxLifetimePrintCheckRTP(IN P_MSDU_INFO_T prPrevProfileMsduInfo, -+ IN P_PKT_PROFILE_T prPrevRoundLastPkt, -+ IN P_PKT_PROFILE_T prPktProfile, -+ IN OUT PBOOLEAN pfgGotFirst, IN UINT_32 u4MaxDeltaTime, IN UINT_8 ucSnToBePrinted) -+{ -+ BOOLEAN fgPrintCurPkt = FALSE; -+ -+ if (u4MaxDeltaTime) { -+ /* 4 1. check delta between current round first pkt and prevous round last pkt */ -+ if (!*pfgGotFirst) { -+ *pfgGotFirst = TRUE; -+ -+ if (prPrevRoundLastPkt->fgIsValid) { -+ if (CHK_PROFILES_DELTA(prPktProfile, prPrevRoundLastPkt, u4MaxDeltaTime)) { -+ PRINT_PKT_PROFILE(prPrevRoundLastPkt, "PR"); -+ fgPrintCurPkt = TRUE; -+ } -+ } -+ } -+ /* 4 2. check delta between current pkt and previous pkt */ -+ if (prPrevProfileMsduInfo) { -+ if (CHK_PROFILES_DELTA(prPktProfile, &prPrevProfileMsduInfo->rPktProfile, u4MaxDeltaTime)) { -+ PRINT_PKT_PROFILE(&prPrevProfileMsduInfo->rPktProfile, "P"); -+ fgPrintCurPkt = TRUE; -+ } -+ } -+ /* 4 3. check delta of current pkt lifetime */ -+ if (CHK_PROFILE_DELTA(prPktProfile, u4MaxDeltaTime)) -+ fgPrintCurPkt = TRUE; -+ } -+ /* 4 4. print every X RTP packets */ -+#if CFG_SUPPORT_WFD -+ if ((ucSnToBePrinted != 0) && (prPktProfile->u2RtpSn % ucSnToBePrinted) == 0) -+ fgPrintCurPkt = TRUE; -+#endif -+ -+ return fgPrintCurPkt; -+} -+ -+BOOLEAN -+nicTxLifetimePrintCheckSnOrder(IN P_MSDU_INFO_T prPrevProfileMsduInfo, -+ IN P_PKT_PROFILE_T prPrevRoundLastPkt, -+ IN P_PKT_PROFILE_T prPktProfile, IN OUT PBOOLEAN pfgGotFirst, IN UINT_8 ucLayer) -+{ -+ BOOLEAN fgPrintCurPkt = FALSE; -+ P_PKT_PROFILE_T prTarPktProfile = NULL; -+ UINT_16 u2PredictSn = 0; -+ UINT_16 u2CurrentSn = 0; -+ UINT_8 aucNote[8]; -+ -+ /* 4 1. Get the target packet profile to compare */ -+ -+ /* 4 1.1 check SN between current round first pkt and prevous round last pkt */ -+ if ((!*pfgGotFirst) && (prPrevRoundLastPkt->fgIsValid)) { -+ *pfgGotFirst = TRUE; -+ prTarPktProfile = prPrevRoundLastPkt; -+ kalMemCopy(aucNote, "PR\0", 3); -+ } -+ /* 4 1.2 check SN between current pkt and previous pkt */ -+ else if (prPrevProfileMsduInfo) { -+ prTarPktProfile = &prPrevProfileMsduInfo->rPktProfile; -+ kalMemCopy(aucNote, "P\0", 2); -+ } -+ -+ if (!prTarPktProfile) -+ return FALSE; -+ /* 4 2. Check IP or RTP SN */ -+ switch (ucLayer) { -+ /* Check IP SN */ -+ case 0: -+ u2PredictSn = prTarPktProfile->u2IpSn + 1; -+ u2CurrentSn = prPktProfile->u2IpSn; -+ break; -+ /* Check RTP SN */ -+ case 1: -+ default: -+ u2PredictSn = prTarPktProfile->u2RtpSn + 1; -+ u2CurrentSn = prPktProfile->u2RtpSn; -+ break; -+ -+ } -+ /* 4 */ -+ /* 4 3. Compare SN */ -+ if (u2CurrentSn != u2PredictSn) { -+ PRINT_PKT_PROFILE(prTarPktProfile, aucNote); -+ fgPrintCurPkt = TRUE; -+ } -+ -+ return fgPrintCurPkt; -+} -+#endif -+ -+VOID nicTxReturnMsduInfoProfiling(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfoListHead) -+{ -+ P_MSDU_INFO_T prMsduInfo = prMsduInfoListHead, prNextMsduInfo; -+ P_PKT_PROFILE_T prPktProfile; -+ UINT_16 u2MagicCode = 0; -+ -+ UINT_8 ucDebugtMode = 0; -+#if CFG_PRINT_RTP_PROFILE -+ P_MSDU_INFO_T prPrevProfileMsduInfo = NULL; -+ P_PKT_PROFILE_T prPrevRoundLastPkt = &rPrevRoundLastPkt; -+ -+ BOOLEAN fgPrintCurPkt = FALSE; -+ BOOLEAN fgGotFirst = FALSE; -+ UINT_8 ucSnToBePrinted = 0; -+ -+ UINT_32 u4MaxDeltaTime = 50; /* in ms */ -+#endif -+ -+#if CFG_ENABLE_PER_STA_STATISTICS -+ UINT_32 u4PktPrintPeriod = 0; -+#endif -+ -+#if CFG_SUPPORT_WFD -+ P_WFD_CFG_SETTINGS_T prWfdCfgSettings = (P_WFD_CFG_SETTINGS_T) NULL; -+ -+ if (prAdapter->fgIsP2PRegistered) { -+ prWfdCfgSettings = &prAdapter->rWifiVar.prP2pFsmInfo->rWfdConfigureSettings; -+ u2MagicCode = prWfdCfgSettings->u2WfdMaximumTp; -+ ucDebugtMode = prAdapter->rWifiVar.prP2pFsmInfo->rWfdDebugSetting.ucWfdDebugMode; -+ /* if(prWfdCfgSettings->ucWfdEnable && (prWfdCfgSettings->u4WfdFlag & BIT(0))) { */ -+ /* u2MagicCode = 0xE040; */ -+ /* } */ -+ } -+#endif -+ -+#if CFG_PRINT_RTP_PROFILE -+ if ((u2MagicCode >= 0xF000)) { -+ ucSnToBePrinted = (UINT_8) (u2MagicCode & BITS(0, 7)); -+ u4MaxDeltaTime = (UINT_8) (((u2MagicCode & BITS(8, 11)) >> 8) * 10); -+ } else { -+ ucSnToBePrinted = 0; -+ u4MaxDeltaTime = 0; -+ } -+ -+#endif -+ -+#if CFG_ENABLE_PER_STA_STATISTICS -+ if ((u2MagicCode >= 0xE000) && (u2MagicCode < 0xF000)) -+ u4PktPrintPeriod = (UINT_32) ((u2MagicCode & BITS(0, 7)) * 32); -+ else -+ u4PktPrintPeriod = 0; -+#endif -+ -+ while (prMsduInfo) { -+ prNextMsduInfo = (P_MSDU_INFO_T) QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T) prMsduInfo); -+ prPktProfile = &prMsduInfo->rPktProfile; -+ -+ if (prPktProfile->fgIsValid) { -+ -+ prPktProfile->rHifTxDoneTimestamp = kalGetTimeTick(); -+ if (ucDebugtMode > 1) { -+ -+#if CFG_PRINT_RTP_PROFILE -+#if CFG_PRINT_RTP_SN_SKIP -+ fgPrintCurPkt = nicTxLifetimePrintCheckSnOrder(prPrevProfileMsduInfo, -+ prPrevRoundLastPkt, -+ prPktProfile, &fgGotFirst, 0); -+#else -+ fgPrintCurPkt = nicTxLifetimePrintCheckRTP(prPrevProfileMsduInfo, -+ prPrevRoundLastPkt, -+ prPktProfile, -+ &fgGotFirst, -+ u4MaxDeltaTime, ucSnToBePrinted); -+#endif -+ -+ /* Print current pkt profile */ -+ if (fgPrintCurPkt && ucDebugtMode > 1) -+ PRINT_PKT_PROFILE(prPktProfile, "C"); -+ -+ prPrevProfileMsduInfo = prMsduInfo; -+ fgPrintCurPkt = FALSE; -+#endif -+ } -+#if CFG_ENABLE_PER_STA_STATISTICS -+ { -+ P_STA_RECORD_T prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); -+ UINT_32 u4DeltaTime; -+ UINT_32 u4DeltaHifTime; -+#if 0 -+ P_QUE_MGT_T prQM = &prAdapter->rQM; -+#endif -+ UINT_8 ucNetIndex; -+ -+ if (prStaRec) { -+ ucNetIndex = prStaRec->ucNetTypeIndex; -+ u4DeltaTime = (UINT_32) (prPktProfile->rHifTxDoneTimestamp - -+ prPktProfile->rHardXmitArrivalTimestamp); -+ u4DeltaHifTime = (UINT_32) (prPktProfile->rHifTxDoneTimestamp - -+ prPktProfile->rDequeueTimestamp); -+ prStaRec->u4TotalTxPktsNumber++; -+ -+ prStaRec->u4TotalTxPktsTime += u4DeltaTime; -+ prStaRec->u4TotalTxPktsHifTime += u4DeltaHifTime; -+ -+ if (u4DeltaTime > prStaRec->u4MaxTxPktsTime) -+ prStaRec->u4MaxTxPktsTime = u4DeltaTime; -+ -+ if (u4DeltaHifTime > prStaRec->u4MaxTxPktsHifTime) -+ prStaRec->u4MaxTxPktsHifTime = u4DeltaHifTime; -+ -+ -+ if (u4DeltaTime >= NIC_TX_TIME_THRESHOLD) -+ prStaRec->u4ThresholdCounter++; -+#if 0 -+ if (u4PktPrintPeriod && (prStaRec->u4TotalTxPktsNumber >= u4PktPrintPeriod)) { -+ -+ DBGLOG(TX, TRACE, "[%u]N[%4u]A[%5u]M[%4u]T[%4u]E[%4u]\n", -+ prStaRec->ucIndex, -+ prStaRec->u4TotalTxPktsNumber, -+ prStaRec->u4TotalTxPktsTime / prStaRec->u4TotalTxPktsNumber, -+ prStaRec->u4MaxTxPktsTime, -+ prStaRec->u4ThresholdCounter, -+ prQM->au4QmTcResourceEmptyCounter[ucNetIndex][TC2_INDEX]); -+ -+ prStaRec->u4TotalTxPktsNumber = 0; -+ prStaRec->u4TotalTxPktsTime = 0; -+ prStaRec->u4MaxTxPktsTime = 0; -+ prStaRec->u4ThresholdCounter = 0; -+ prQM->au4QmTcResourceEmptyCounter[ucNetIndex][TC2_INDEX] = 0; -+ } -+#endif -+ } -+ -+ } -+#endif -+ } -+ -+ prMsduInfo = prNextMsduInfo; -+ }; -+ -+#if CFG_PRINT_RTP_PROFILE -+ /* 4 4. record the lifetime of current round last pkt */ -+ if (prPrevProfileMsduInfo) { -+ prPktProfile = &prPrevProfileMsduInfo->rPktProfile; -+ prPrevRoundLastPkt->u2IpSn = prPktProfile->u2IpSn; -+ prPrevRoundLastPkt->u2RtpSn = prPktProfile->u2RtpSn; -+ prPrevRoundLastPkt->rHardXmitArrivalTimestamp = prPktProfile->rHardXmitArrivalTimestamp; -+ prPrevRoundLastPkt->rEnqueueTimestamp = prPktProfile->rEnqueueTimestamp; -+ prPrevRoundLastPkt->rDequeueTimestamp = prPktProfile->rDequeueTimestamp; -+ prPrevRoundLastPkt->rHifTxDoneTimestamp = prPktProfile->rHifTxDoneTimestamp; -+ prPrevRoundLastPkt->ucTcxFreeCount = prPktProfile->ucTcxFreeCount; -+ prPrevRoundLastPkt->fgIsPrinted = prPktProfile->fgIsPrinted; -+ prPrevRoundLastPkt->fgIsValid = TRUE; -+ } -+#endif -+ -+ nicTxReturnMsduInfo(prAdapter, prMsduInfoListHead); -+ -+} -+ -+VOID nicTxLifetimeRecordEn(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo, IN P_NATIVE_PACKET prPacket) -+{ -+ P_PKT_PROFILE_T prPktProfile = &prMsduInfo->rPktProfile; -+ -+ /* Enable packet lifetime profiling */ -+ prPktProfile->fgIsValid = TRUE; -+ -+ /* Packet arrival time at kernel Hard Xmit */ -+ prPktProfile->rHardXmitArrivalTimestamp = GLUE_GET_PKT_ARRIVAL_TIME(prPacket); -+ -+ /* Packet enqueue time */ -+ prPktProfile->rEnqueueTimestamp = (OS_SYSTIME) kalGetTimeTick(); -+ -+} -+ -+#if CFG_PRINT_RTP_PROFILE -+/* -+ in: -+ data RTP packet pointer -+ size RTP size -+ return -+ 0:audio 1: video, -1:none -+*/ -+UINT8 checkRtpAV(PUINT_8 data, UINT_32 size) -+{ -+ PUINT_8 buf = data + 12; -+ -+ while (buf + 188 <= data + size) { -+ int pid = ((buf[1] << 8) & 0x1F00) | (buf[2] & 0xFF); -+ -+ if (pid == 0 || pid == 0x100 || pid == 0x1000) -+ buf += 188; -+ else if (pid == 0x1100) -+ return 0; -+ else if (pid == 0x1011) -+ return 1; -+ } -+ return -1; -+} -+ -+VOID -+nicTxLifetimeCheckRTP(IN P_ADAPTER_T prAdapter, -+ IN P_MSDU_INFO_T prMsduInfo, -+ IN P_NATIVE_PACKET prPacket, IN UINT_32 u4PacketLen, IN UINT_8 ucNetworkType) -+{ -+ struct sk_buff *prSkb = (struct sk_buff *)prPacket; -+ UINT_16 u2EtherTypeLen; -+ PUINT_8 aucLookAheadBuf = NULL; -+ P_PKT_PROFILE_T prPktProfile = &prMsduInfo->rPktProfile; -+ -+ /* UINT_8 ucRtpHdrOffset = 28; */ -+ UINT_8 ucRtpSnOffset = 30; -+ /* UINT_32 u4RtpSrcPort = 15550; */ -+ P_TX_CTRL_T prTxCtrl; -+#if CFG_SUPPORT_WFD -+ P_WFD_CFG_SETTINGS_T prWfdCfgSettings = (P_WFD_CFG_SETTINGS_T) NULL; -+ P_WFD_DBG_CFG_SETTINGS_T prWfdDbgSettings = (P_WFD_DBG_CFG_SETTINGS_T) NULL; -+ -+ BOOLEAN fgEnProfiling = FALSE; -+ -+ if (prAdapter->fgIsP2PRegistered) { -+ prWfdCfgSettings = &prAdapter->rWifiVar.prP2pFsmInfo->rWfdConfigureSettings; -+ prWfdDbgSettings = &prAdapter->rWifiVar.prP2pFsmInfo->rWfdDebugSetting; -+#if CFG_PRINT_RTP_SN_SKIP -+ if (ucNetworkType == NETWORK_TYPE_P2P_INDEX) { -+ fgEnProfiling = TRUE; -+ } else -+#endif -+ if (((prWfdCfgSettings->u2WfdMaximumTp >= 0xF000) || -+ (prWfdDbgSettings->ucWfdDebugMode > 0)) && (ucNetworkType == NETWORK_TYPE_P2P_INDEX)) { -+ fgEnProfiling = TRUE; -+ } -+ } -+ -+ if (fgEnProfiling == FALSE) { -+ /* prPktProfile->fgIsValid = FALSE; */ -+ return; -+ } -+#endif -+ -+ prTxCtrl = &prAdapter->rTxCtrl; -+ /* prPktProfile->fgIsValid = FALSE; */ -+ -+ aucLookAheadBuf = prSkb->data; -+ -+ u2EtherTypeLen = (aucLookAheadBuf[ETH_TYPE_LEN_OFFSET] << 8) | (aucLookAheadBuf[ETH_TYPE_LEN_OFFSET + 1]); -+ -+ if ((u2EtherTypeLen == ETH_P_IP) && (u4PacketLen >= LOOK_AHEAD_LEN)) { -+ PUINT_8 pucIpHdr = &aucLookAheadBuf[ETH_HLEN]; -+ UINT_16 u2tmpIpSN = 0; -+ UINT_8 ucIpVersion; -+ -+ ucIpVersion = (pucIpHdr[0] & IPVH_VERSION_MASK) >> IPVH_VERSION_OFFSET; -+ if (ucIpVersion == IPVERSION) { -+ if (pucIpHdr[IPV4_HDR_IP_PROTOCOL_OFFSET] == IP_PROTOCOL_UDP) { -+ -+ /* if(checkRtpAV(&pucIpHdr[ucRtpHdrOffset], -+ (u4PacketLen - ETH_HLEN - ucRtpHdrOffset)) == 0) { */ -+ -+ if (prPktProfile->fgIsValid == FALSE) -+ nicTxLifetimeRecordEn(prAdapter, prMsduInfo, prPacket); -+ -+ prPktProfile->fgIsPrinted = FALSE; -+ -+ prPktProfile->ucTcxFreeCount = prTxCtrl->rTc.aucFreeBufferCount[TC2_INDEX]; -+ -+ /* RTP SN */ -+ prPktProfile->u2RtpSn = pucIpHdr[ucRtpSnOffset] << 8 | pucIpHdr[ucRtpSnOffset + 1]; -+ -+ /* IP SN */ -+ prPktProfile->u2IpSn = pucIpHdr[IPV4_HDR_IP_IDENTIFICATION_OFFSET] << 8 | -+ pucIpHdr[IPV4_HDR_IP_IDENTIFICATION_OFFSET + 1]; -+ u2tmpIpSN = prPktProfile->u2IpSn; -+ if (prWfdDbgSettings->ucWfdDebugMode == 1) { -+ if ((u2tmpIpSN & (prWfdDbgSettings->u2WfdSNShowPeiroid)) == 0) -+ DBGLOG(TX, TRACE, -+ "RtpSn=%d IPId=%d j=%lu\n", prPktProfile->u2RtpSn, -+ prPktProfile->u2IpSn, jiffies); -+ } -+ /* } */ -+ } -+ } -+ } -+ -+} -+#endif -+#if CFG_ENABLE_PER_STA_STATISTICS -+VOID -+nicTxLifetimeCheckByAC(IN P_ADAPTER_T prAdapter, -+ IN P_MSDU_INFO_T prMsduInfo, IN P_NATIVE_PACKET prPacket, IN UINT_8 ucPriorityParam) -+{ -+ switch (ucPriorityParam) { -+ /* BK */ -+ /* case 1: */ -+ /* case 2: */ -+ -+ /* BE */ -+ /* case 0: */ -+ /* case 3: */ -+ -+ /* VI */ -+ case 4: -+ case 5: -+ -+ /* VO */ -+ case 6: -+ case 7: -+ nicTxLifetimeRecordEn(prAdapter, prMsduInfo, prPacket); -+ break; -+ default: -+ break; -+ } -+} -+ -+#endif -+ -+VOID -+nicTxLifetimeCheck(IN P_ADAPTER_T prAdapter, -+ IN P_MSDU_INFO_T prMsduInfo, -+ IN P_NATIVE_PACKET prPacket, -+ IN UINT_8 ucPriorityParam, IN UINT_32 u4PacketLen, IN UINT_8 ucNetworkType) -+{ -+ P_PKT_PROFILE_T prPktProfile = &prMsduInfo->rPktProfile; -+ -+ /* Reset packet profile */ -+ prPktProfile->fgIsValid = FALSE; -+ -+#if CFG_ENABLE_PER_STA_STATISTICS -+ nicTxLifetimeCheckByAC(prAdapter, prMsduInfo, prPacket, ucPriorityParam); -+#endif -+ -+#if CFG_PRINT_RTP_PROFILE -+ nicTxLifetimeCheckRTP(prAdapter, prMsduInfo, prPacket, u4PacketLen, ucNetworkType); -+#endif -+ -+} -+ -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief In this function, we'll write frame(PACKET_INFO_T) into HIF. -+* -+* @param prAdapter Pointer to the Adapter structure. -+* @param ucPortIdx Port Number -+* @param prQue a link list of P_MSDU_INFO_T -+* -+* @retval WLAN_STATUS_SUCCESS Bus access ok. -+* @retval WLAN_STATUS_FAILURE Bus access fail. -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS nicTxMsduQueue(IN P_ADAPTER_T prAdapter, UINT_8 ucPortIdx, P_QUE_T prQue) -+{ -+ P_MSDU_INFO_T prMsduInfo, prNextMsduInfo; -+ HIF_TX_HEADER_T rHwTxHeader; -+ P_NATIVE_PACKET prNativePacket; -+ UINT_16 u2OverallBufferLength; -+ UINT_8 ucEtherTypeOffsetInWord; -+ PUINT_8 pucOutputBuf = (PUINT_8) NULL; /* Pointer to Transmit Data Structure Frame */ -+ UINT_32 u4TxHdrSize; -+ UINT_32 u4ValidBufSize; -+ UINT_32 u4TotalLength; -+ P_TX_CTRL_T prTxCtrl; -+ QUE_T rFreeQueue; -+#if CFG_TCP_IP_CHKSUM_OFFLOAD -+ UINT_8 ucChksumFlag; -+#endif -+ -+ ASSERT(prAdapter); -+ ASSERT(ucPortIdx < 2); -+ ASSERT(prQue); -+ -+ prTxCtrl = &prAdapter->rTxCtrl; -+ u4ValidBufSize = prAdapter->u4CoalescingBufCachedSize; -+ -+#if CFG_HIF_STATISTICS -+ prTxCtrl->u4TotalTxAccessNum++; -+ prTxCtrl->u4TotalTxPacketNum += prQue->u4NumElem; -+#endif -+ -+ QUEUE_INITIALIZE(&rFreeQueue); -+ -+ if (prQue->u4NumElem > 0) { -+ prMsduInfo = (P_MSDU_INFO_T) QUEUE_GET_HEAD(prQue); -+ pucOutputBuf = prTxCtrl->pucTxCoalescingBufPtr; -+ u4TotalLength = 0; -+ -+ while (prMsduInfo) { -+ -+#if (CFG_SUPPORT_TDLS_DBG == 1) -+ { -+ struct sk_buff *prSkb = (struct sk_buff *)prMsduInfo->prPacket; -+ UINT8 *pkt = prSkb->data; -+ UINT16 u2Identifier; -+ -+ if ((*(pkt + 12) == 0x08) && (*(pkt + 13) == 0x00)) { -+ /* ip */ -+ u2Identifier = ((*(pkt + 18)) << 8) | (*(pkt + 19)); -+ DBGLOG(TX, TRACE, " %d\n", u2Identifier); -+ } -+ } -+#endif -+#if (CFG_SUPPORT_MET_PROFILING == 1) -+ kalMetProfilingFinish(prAdapter, prMsduInfo); -+#endif -+ kalMemZero(&rHwTxHeader, sizeof(rHwTxHeader)); -+ -+ prNativePacket = prMsduInfo->prPacket; -+ -+ ASSERT(prNativePacket); -+ -+ u4TxHdrSize = TX_HDR_SIZE; -+ -+ u2OverallBufferLength = ((prMsduInfo->u2FrameLength + TX_HDR_SIZE) & -+ (UINT_16) HIF_TX_HDR_TX_BYTE_COUNT_MASK); -+ -+ /* init TX header */ -+ rHwTxHeader.u2TxByteCount_UserPriority = u2OverallBufferLength; -+ rHwTxHeader.u2TxByteCount_UserPriority |= -+ ((UINT_16) prMsduInfo->ucUserPriority << HIF_TX_HDR_USER_PRIORITY_OFFSET); -+ -+ if (prMsduInfo->fgIs802_11) { -+ ucEtherTypeOffsetInWord = -+ (TX_HDR_SIZE + prMsduInfo->ucMacHeaderLength + prMsduInfo->ucLlcLength) >> 1; -+ } else { -+ ucEtherTypeOffsetInWord = ((ETHER_HEADER_LEN - ETHER_TYPE_LEN) + TX_HDR_SIZE) >> 1; -+ } -+ -+ rHwTxHeader.ucEtherTypeOffset = ucEtherTypeOffsetInWord & HIF_TX_HDR_ETHER_TYPE_OFFSET_MASK; -+ -+ rHwTxHeader.ucResource_PktType_CSflags = (prMsduInfo->ucTC) << HIF_TX_HDR_RESOURCE_OFFSET; -+ rHwTxHeader.ucResource_PktType_CSflags |= -+ (UINT_8) (((prMsduInfo->ucPacketType) << HIF_TX_HDR_PACKET_TYPE_OFFSET) & -+ (HIF_TX_HDR_PACKET_TYPE_MASK)); -+ -+#if CFG_TCP_IP_CHKSUM_OFFLOAD -+ if (prMsduInfo->eSrc == TX_PACKET_OS || prMsduInfo->eSrc == TX_PACKET_FORWARDING) { -+ if (prAdapter->u4CSUMFlags & -+ (CSUM_OFFLOAD_EN_TX_TCP | CSUM_OFFLOAD_EN_TX_UDP | CSUM_OFFLOAD_EN_TX_IP)) { -+ kalQueryTxChksumOffloadParam(prNativePacket, &ucChksumFlag); -+ -+ if (ucChksumFlag & TX_CS_IP_GEN) -+ rHwTxHeader.ucResource_PktType_CSflags |= (UINT_8) HIF_TX_HDR_IP_CSUM; -+ -+ if (ucChksumFlag & TX_CS_TCP_UDP_GEN) -+ rHwTxHeader.ucResource_PktType_CSflags |= (UINT_8) HIF_TX_HDR_TCP_CSUM; -+ } -+ } -+#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */ -+ -+ rHwTxHeader.u2LLH = prMsduInfo->u2PalLLH; -+ rHwTxHeader.ucStaRecIdx = prMsduInfo->ucStaRecIndex; -+ rHwTxHeader.ucForwardingType_SessionID_Reserved = -+ (prMsduInfo->ucPsForwardingType) | ((prMsduInfo->ucPsSessionID) << -+ HIF_TX_HDR_PS_SESSION_ID_OFFSET) -+ | ((prMsduInfo->fgIsBurstEnd) ? HIF_TX_HDR_BURST_END_MASK : 0); -+ -+ rHwTxHeader.ucWlanHeaderLength = -+ (prMsduInfo->ucMacHeaderLength & HIF_TX_HDR_WLAN_HEADER_LEN_MASK); -+ rHwTxHeader.ucPktFormtId_Flags = (prMsduInfo->ucFormatID & HIF_TX_HDR_FORMAT_ID_MASK) -+ | ((prMsduInfo->ucNetworkType << HIF_TX_HDR_NETWORK_TYPE_OFFSET) & -+ HIF_TX_HDR_NETWORK_TYPE_MASK) -+ | ((prMsduInfo->fgIs802_1x << HIF_TX_HDR_FLAG_1X_FRAME_OFFSET) & -+ HIF_TX_HDR_FLAG_1X_FRAME_MASK) -+ | ((prMsduInfo->fgIs802_11 << HIF_TX_HDR_FLAG_802_11_FORMAT_OFFSET) & -+ HIF_TX_HDR_FLAG_802_11_FORMAT_MASK); -+ -+ rHwTxHeader.u2SeqNo = prMsduInfo->u2AclSN; -+ -+ if (prMsduInfo->pfTxDoneHandler) { -+ rHwTxHeader.ucPacketSeqNo = prMsduInfo->ucTxSeqNum; -+ rHwTxHeader.ucAck_BIP_BasicRate = HIF_TX_HDR_NEED_ACK; -+ } else { -+ rHwTxHeader.ucPacketSeqNo = 0; -+ rHwTxHeader.ucAck_BIP_BasicRate = 0; -+ } -+ -+ if (prMsduInfo->fgNeedTxDoneStatus == TRUE) -+ rHwTxHeader.ucAck_BIP_BasicRate |= HIF_TX_HDR_NEED_TX_DONE_STATUS; -+ -+ if (prMsduInfo->fgIsBIP) -+ rHwTxHeader.ucAck_BIP_BasicRate |= HIF_TX_HDR_BIP; -+ -+ if (prMsduInfo->fgIsBasicRate) -+ rHwTxHeader.ucAck_BIP_BasicRate |= HIF_TX_HDR_BASIC_RATE; -+#if CFG_ENABLE_PKT_LIFETIME_PROFILE -+ if (prMsduInfo->rPktProfile.fgIsValid) -+ prMsduInfo->rPktProfile.rDequeueTimestamp = kalGetTimeTick(); -+#endif -+ -+ /* record the queue time in driver */ -+ STATS_TX_TIME_TO_HIF(prMsduInfo, &rHwTxHeader); -+ -+#if CFG_SDIO_TX_AGG -+ /* attach to coalescing buffer */ -+ kalMemCopy(pucOutputBuf + u4TotalLength, &rHwTxHeader, u4TxHdrSize); -+ u4TotalLength += u4TxHdrSize; -+ -+ if (prMsduInfo->eSrc == TX_PACKET_OS || prMsduInfo->eSrc == TX_PACKET_FORWARDING) -+ kalCopyFrame(prAdapter->prGlueInfo, prNativePacket, pucOutputBuf + u4TotalLength); -+ else if (prMsduInfo->eSrc == TX_PACKET_MGMT) -+ kalMemCopy(pucOutputBuf + u4TotalLength, prNativePacket, prMsduInfo->u2FrameLength); -+ else -+ ASSERT(0); -+ -+ u4TotalLength += ALIGN_4(prMsduInfo->u2FrameLength); -+ -+#else -+ kalMemCopy(pucOutputBuf, &rHwTxHeader, u4TxHdrSize); -+ -+ /* Copy Frame Body */ -+ if (prMsduInfo->eSrc == TX_PACKET_OS || prMsduInfo->eSrc == TX_PACKET_FORWARDING) -+ kalCopyFrame(prAdapter->prGlueInfo, prNativePacket, pucOutputBuf + u4TxHdrSize); -+ else if (prMsduInfo->eSrc == TX_PACKET_MGMT) -+ kalMemCopy(pucOutputBuf + u4TxHdrSize, prNativePacket, prMsduInfo->u2FrameLength); -+ else -+ ASSERT(0); -+ -+ ASSERT(u2OverallBufferLength <= u4ValidBufSize); -+ -+ HAL_WRITE_TX_PORT(prAdapter, -+ ucPortIdx, -+ (UINT_32) u2OverallBufferLength, (PUINT_8) pucOutputBuf, u4ValidBufSize); -+ -+ /* send immediately */ -+#endif -+ prNextMsduInfo = (P_MSDU_INFO_T) -+ QUEUE_GET_NEXT_ENTRY(&prMsduInfo->rQueEntry); -+ -+ if (prMsduInfo->eSrc == TX_PACKET_MGMT) { -+ GLUE_DEC_REF_CNT(prTxCtrl->i4TxMgmtPendingNum); -+ -+ if (prMsduInfo->pfTxDoneHandler == NULL) { -+ cnmMgtPktFree(prAdapter, prMsduInfo); -+ } else { -+ KAL_SPIN_LOCK_DECLARATION(); -+ DBGLOG(TX, TRACE, "Wait TxSeqNum:%d\n", prMsduInfo->ucTxSeqNum); -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TXING_MGMT_LIST); -+ QUEUE_INSERT_TAIL(&(prTxCtrl->rTxMgmtTxingQueue), (P_QUE_ENTRY_T) prMsduInfo); -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TXING_MGMT_LIST); -+ } -+ } else { -+ /* only free MSDU when it is not a MGMT frame */ -+ QUEUE_INSERT_TAIL(&rFreeQueue, (P_QUE_ENTRY_T) prMsduInfo); -+ -+ if (prMsduInfo->eSrc == TX_PACKET_OS) -+ kalSendComplete(prAdapter->prGlueInfo, prNativePacket, WLAN_STATUS_SUCCESS); -+ else if (prMsduInfo->eSrc == TX_PACKET_FORWARDING) -+ GLUE_DEC_REF_CNT(prTxCtrl->i4PendingFwdFrameCount); -+ } -+ -+ prMsduInfo = prNextMsduInfo; -+ } -+ -+#if CFG_SDIO_TX_AGG -+ ASSERT(u4TotalLength <= u4ValidBufSize); -+ -+#if CFG_DBG_GPIO_PINS -+ { -+ /* Start port write */ -+ mtk_wcn_stp_debug_gpio_assert(IDX_TX_PORT_WRITE, DBG_TIE_LOW); -+ kalUdelay(1); -+ mtk_wcn_stp_debug_gpio_assert(IDX_TX_PORT_WRITE, DBG_TIE_HIGH); -+ } -+#endif -+ -+ /* send coalescing buffer */ -+ HAL_WRITE_TX_PORT(prAdapter, ucPortIdx, u4TotalLength, (PUINT_8) pucOutputBuf, u4ValidBufSize); -+#endif -+ -+#if CFG_ENABLE_PKT_LIFETIME_PROFILE -+#if CFG_SUPPORT_WFD && CFG_PRINT_RTP_PROFILE && !CFG_ENABLE_PER_STA_STATISTICS -+ do { -+ P_WFD_CFG_SETTINGS_T prWfdCfgSettings = (P_WFD_CFG_SETTINGS_T) NULL; -+ -+ prWfdCfgSettings = &prAdapter->rWifiVar.prP2pFsmInfo->rWfdConfigureSettings; -+ -+ if ((prWfdCfgSettings->u2WfdMaximumTp >= 0xF000)) { -+ /* Enable profiling */ -+ nicTxReturnMsduInfoProfiling(prAdapter, (P_MSDU_INFO_T) QUEUE_GET_HEAD(&rFreeQueue)); -+ } else { -+ /* Skip profiling */ -+ nicTxReturnMsduInfo(prAdapter, (P_MSDU_INFO_T) QUEUE_GET_HEAD(&rFreeQueue)); -+ } -+ } while (FALSE); -+#else -+ nicTxReturnMsduInfoProfiling(prAdapter, (P_MSDU_INFO_T) QUEUE_GET_HEAD(&rFreeQueue)); -+#endif -+#else -+ /* return */ -+ nicTxReturnMsduInfo(prAdapter, (P_MSDU_INFO_T) QUEUE_GET_HEAD(&rFreeQueue)); -+#endif -+ } -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief In this function, we'll write Command(CMD_INFO_T) into HIF. -+* -+* @param prAdapter Pointer to the Adapter structure. -+* @param prPacketInfo Pointer of CMD_INFO_T -+* @param ucTC Specify the resource of TC -+* -+* @retval WLAN_STATUS_SUCCESS Bus access ok. -+* @retval WLAN_STATUS_FAILURE Bus access fail. -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS nicTxCmd(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN UINT_8 ucTC) -+{ -+ P_WIFI_CMD_T prWifiCmd; -+ UINT_16 u2OverallBufferLength; -+ PUINT_8 pucOutputBuf = (PUINT_8) NULL; /* Pointer to Transmit Data Structure Frame */ -+ UINT_8 ucPortIdx; -+ HIF_TX_HEADER_T rHwTxHeader; -+ P_NATIVE_PACKET prNativePacket; -+ UINT_8 ucEtherTypeOffsetInWord; -+ P_MSDU_INFO_T prMsduInfo; -+ P_TX_CTRL_T prTxCtrl; -+ -+ KAL_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(prAdapter); -+ ASSERT(prCmdInfo); -+ -+ prTxCtrl = &prAdapter->rTxCtrl; -+ pucOutputBuf = prTxCtrl->pucTxCoalescingBufPtr; -+ -+ /* <1> Assign Data Port */ -+ if (ucTC != TC4_INDEX) { -+ ucPortIdx = 0; -+ } else { -+ /* Broadcast/multicast data frames, 1x frames, command packets, MMPDU */ -+ ucPortIdx = 1; -+ } -+ wlanTraceTxCmd(prCmdInfo); -+ -+ if (prCmdInfo->eCmdType == COMMAND_TYPE_SECURITY_FRAME) { -+ /* <2> Compose HIF_TX_HEADER */ -+ kalMemZero(&rHwTxHeader, sizeof(rHwTxHeader)); -+ -+ prNativePacket = prCmdInfo->prPacket; -+ -+ ASSERT(prNativePacket); -+ -+ u2OverallBufferLength = TFCB_FRAME_PAD_TO_DW((prCmdInfo->u2InfoBufLen + TX_HDR_SIZE) -+ & (UINT_16) HIF_TX_HDR_TX_BYTE_COUNT_MASK); -+ -+ rHwTxHeader.u2TxByteCount_UserPriority = ((prCmdInfo->u2InfoBufLen + TX_HDR_SIZE) -+ & (UINT_16) HIF_TX_HDR_TX_BYTE_COUNT_MASK); -+ ucEtherTypeOffsetInWord = ((ETHER_HEADER_LEN - ETHER_TYPE_LEN) + TX_HDR_SIZE) >> 1; -+ -+ rHwTxHeader.ucEtherTypeOffset = ucEtherTypeOffsetInWord & HIF_TX_HDR_ETHER_TYPE_OFFSET_MASK; -+ -+ rHwTxHeader.ucResource_PktType_CSflags = (ucTC << HIF_TX_HDR_RESOURCE_OFFSET); -+ -+ rHwTxHeader.ucStaRecIdx = prCmdInfo->ucStaRecIndex; -+ rHwTxHeader.ucForwardingType_SessionID_Reserved = HIF_TX_HDR_BURST_END_MASK; -+ -+ rHwTxHeader.ucWlanHeaderLength = (ETH_HLEN & HIF_TX_HDR_WLAN_HEADER_LEN_MASK); -+ rHwTxHeader.ucPktFormtId_Flags = -+ (((UINT_8) (prCmdInfo->eNetworkType) << HIF_TX_HDR_NETWORK_TYPE_OFFSET) & -+ HIF_TX_HDR_NETWORK_TYPE_MASK) -+ | ((1 << HIF_TX_HDR_FLAG_1X_FRAME_OFFSET) & HIF_TX_HDR_FLAG_1X_FRAME_MASK); -+ -+ rHwTxHeader.u2SeqNo = 0; -+ rHwTxHeader.ucPacketSeqNo = 0; -+ rHwTxHeader.ucAck_BIP_BasicRate = HIF_TX_HDR_NEED_TX_DONE_STATUS; -+ rHwTxHeader.ucAck_BIP_BasicRate |= HIF_TX_HDR_BASIC_RATE /* | HIF_TX_HDR_RTS */; -+ -+ /* <2.3> Copy HIF TX HEADER */ -+ kalMemCopy((PVOID)&pucOutputBuf[0], (PVOID)&rHwTxHeader, TX_HDR_SIZE); -+ -+ /* <3> Copy Frame Body Copy */ -+ kalCopyFrame(prAdapter->prGlueInfo, prNativePacket, pucOutputBuf + TX_HDR_SIZE); -+ } else if (prCmdInfo->eCmdType == COMMAND_TYPE_MANAGEMENT_FRAME) { -+ prMsduInfo = (P_MSDU_INFO_T) prCmdInfo->prPacket; -+ -+ ASSERT(prMsduInfo->fgIs802_11 == TRUE); -+ ASSERT(prMsduInfo->eSrc == TX_PACKET_MGMT); -+ -+ /* <2> Compose HIF_TX_HEADER */ -+ kalMemZero(&rHwTxHeader, sizeof(rHwTxHeader)); -+ -+ u2OverallBufferLength = ((prMsduInfo->u2FrameLength + TX_HDR_SIZE) & -+ (UINT_16) HIF_TX_HDR_TX_BYTE_COUNT_MASK); -+ -+ rHwTxHeader.u2TxByteCount_UserPriority = u2OverallBufferLength; -+ rHwTxHeader.u2TxByteCount_UserPriority |= -+ ((UINT_16) prMsduInfo->ucUserPriority << HIF_TX_HDR_USER_PRIORITY_OFFSET); -+ -+ ucEtherTypeOffsetInWord = (TX_HDR_SIZE + prMsduInfo->ucMacHeaderLength + prMsduInfo->ucLlcLength) >> 1; -+ -+ rHwTxHeader.ucEtherTypeOffset = ucEtherTypeOffsetInWord & HIF_TX_HDR_ETHER_TYPE_OFFSET_MASK; -+ -+ rHwTxHeader.ucResource_PktType_CSflags = (prMsduInfo->ucTC) << HIF_TX_HDR_RESOURCE_OFFSET; -+ rHwTxHeader.ucResource_PktType_CSflags |= -+ (UINT_8) (((prMsduInfo->ucPacketType) << HIF_TX_HDR_PACKET_TYPE_OFFSET) & -+ (HIF_TX_HDR_PACKET_TYPE_MASK)); -+ -+ rHwTxHeader.u2LLH = prMsduInfo->u2PalLLH; -+ rHwTxHeader.ucStaRecIdx = prMsduInfo->ucStaRecIndex; -+ rHwTxHeader.ucForwardingType_SessionID_Reserved = -+ (prMsduInfo->ucPsForwardingType) | ((prMsduInfo->ucPsSessionID) << HIF_TX_HDR_PS_SESSION_ID_OFFSET) -+ | ((prMsduInfo->fgIsBurstEnd) ? HIF_TX_HDR_BURST_END_MASK : 0); -+ -+ rHwTxHeader.ucWlanHeaderLength = (prMsduInfo->ucMacHeaderLength & HIF_TX_HDR_WLAN_HEADER_LEN_MASK); -+ rHwTxHeader.ucPktFormtId_Flags = (prMsduInfo->ucFormatID & HIF_TX_HDR_FORMAT_ID_MASK) -+ | ((prMsduInfo->ucNetworkType << HIF_TX_HDR_NETWORK_TYPE_OFFSET) & HIF_TX_HDR_NETWORK_TYPE_MASK) -+ | ((prMsduInfo->fgIs802_1x << HIF_TX_HDR_FLAG_1X_FRAME_OFFSET) & HIF_TX_HDR_FLAG_1X_FRAME_MASK) -+ | ((prMsduInfo->fgIs802_11 << HIF_TX_HDR_FLAG_802_11_FORMAT_OFFSET) & -+ HIF_TX_HDR_FLAG_802_11_FORMAT_MASK); -+ -+ rHwTxHeader.u2SeqNo = prMsduInfo->u2AclSN; -+ -+ if (prMsduInfo->pfTxDoneHandler) { -+ rHwTxHeader.ucPacketSeqNo = prMsduInfo->ucTxSeqNum; -+ rHwTxHeader.ucAck_BIP_BasicRate = HIF_TX_HDR_NEED_ACK; -+ } else { -+ rHwTxHeader.ucPacketSeqNo = 0; -+ rHwTxHeader.ucAck_BIP_BasicRate = 0; -+ } -+ -+ if (prMsduInfo->fgIsBIP) -+ rHwTxHeader.ucAck_BIP_BasicRate |= HIF_TX_HDR_BIP; -+ -+ if (prMsduInfo->fgIsBasicRate) -+ rHwTxHeader.ucAck_BIP_BasicRate |= HIF_TX_HDR_BASIC_RATE; -+ /* <2.3> Copy HIF TX HEADER */ -+ kalMemCopy((PVOID)&pucOutputBuf[0], (PVOID)&rHwTxHeader, TX_HDR_SIZE); -+ -+ /* <3> Copy Frame Body */ -+ kalMemCopy(pucOutputBuf + TX_HDR_SIZE, prMsduInfo->prPacket, prMsduInfo->u2FrameLength); -+ -+ /* <4> Management Frame Post-Processing */ -+ GLUE_DEC_REF_CNT(prTxCtrl->i4TxMgmtPendingNum); -+ -+ if (prMsduInfo->pfTxDoneHandler == NULL) { -+ cnmMgtPktFree(prAdapter, prMsduInfo); -+ } else { -+ -+ DBGLOG(TX, TRACE, "Wait Cmd TxSeqNum:%d\n", prMsduInfo->ucTxSeqNum); -+ -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TXING_MGMT_LIST); -+ QUEUE_INSERT_TAIL(&(prTxCtrl->rTxMgmtTxingQueue), (P_QUE_ENTRY_T) prMsduInfo); -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TXING_MGMT_LIST); -+ } -+ } else { -+ prWifiCmd = (P_WIFI_CMD_T) prCmdInfo->pucInfoBuffer; -+ -+ /* <2> Compose the Header of Transmit Data Structure for CMD Packet */ -+ u2OverallBufferLength = -+ TFCB_FRAME_PAD_TO_DW((prCmdInfo->u2InfoBufLen) & (UINT_16) HIF_TX_HDR_TX_BYTE_COUNT_MASK); -+ -+ prWifiCmd->u2TxByteCount_UserPriority = u2OverallBufferLength; -+ prWifiCmd->ucEtherTypeOffset = 0; -+ prWifiCmd->ucResource_PktType_CSflags = (ucTC << HIF_TX_HDR_RESOURCE_OFFSET) -+ | (UINT_8) ((HIF_TX_PKT_TYPE_CMD << HIF_TX_HDR_PACKET_TYPE_OFFSET) & (HIF_TX_HDR_PACKET_TYPE_MASK)); -+ -+ /* <3> Copy CMD Header to command buffer (by using pucCoalescingBufCached) */ -+ kalMemCopy((PVOID)&pucOutputBuf[0], (PVOID) prCmdInfo->pucInfoBuffer, prCmdInfo->u2InfoBufLen); -+ -+ ASSERT(u2OverallBufferLength <= prAdapter->u4CoalescingBufCachedSize); -+ -+ if ((prCmdInfo->ucCID == CMD_ID_SCAN_REQ) || -+ (prCmdInfo->ucCID == CMD_ID_SCAN_CANCEL) || -+ (prCmdInfo->ucCID == CMD_ID_SCAN_REQ_V2)) -+ DBGLOG(TX, INFO, "ucCmdSeqNum =%d, ucCID =%d\n", prCmdInfo->ucCmdSeqNum, prCmdInfo->ucCID); -+ } -+ -+ /* <4> Write frame to data port */ -+ HAL_WRITE_TX_PORT(prAdapter, -+ ucPortIdx, -+ (UINT_32) u2OverallBufferLength, -+ (PUINT_8) pucOutputBuf, (UINT_32) prAdapter->u4CoalescingBufCachedSize); -+ -+ return WLAN_STATUS_SUCCESS; -+} /* end of nicTxCmd() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function will clean up all the pending frames in internal SW Queues -+* by return the pending TX packet to the system. -+* -+* @param prAdapter Pointer to the Adapter structure. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicTxRelease(IN P_ADAPTER_T prAdapter) -+{ -+ P_TX_CTRL_T prTxCtrl; -+ P_MSDU_INFO_T prMsduInfo; -+ -+ KAL_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(prAdapter); -+ -+ prTxCtrl = &prAdapter->rTxCtrl; -+ -+ nicTxFlush(prAdapter); -+ -+ /* free MSDU_INFO_T from rTxMgmtMsduInfoList */ -+ do { -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TXING_MGMT_LIST); -+ QUEUE_REMOVE_HEAD(&prTxCtrl->rTxMgmtTxingQueue, prMsduInfo, P_MSDU_INFO_T); -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TXING_MGMT_LIST); -+ -+ if (prMsduInfo) { -+ /* the packet must be mgmt frame with tx done callback */ -+ ASSERT(prMsduInfo->eSrc == TX_PACKET_MGMT); -+ -+ /* invoke done handler */ -+ prMsduInfo->pfTxDoneHandler(prAdapter, prMsduInfo, TX_RESULT_LIFE_TIMEOUT); -+ -+ cnmMgtPktFree(prAdapter, prMsduInfo); -+ } else { -+ break; -+ } -+ } while (TRUE); -+ -+} /* end of nicTxRelease() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Process the TX Done interrupt and pull in more pending frames in SW -+* Queues for transmission. -+* -+* @param prAdapter Pointer to the Adapter structure. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicProcessTxInterrupt(IN P_ADAPTER_T prAdapter) -+{ -+ P_TX_CTRL_T prTxCtrl; -+#if CFG_SDIO_INTR_ENHANCE -+ P_SDIO_CTRL_T prSDIOCtrl; -+#else -+ UINT_32 au4TxCount[2]; -+#endif /* CFG_SDIO_INTR_ENHANCE */ -+ -+ P_GLUE_INFO_T prGlueInfo = prAdapter->prGlueInfo; -+ -+ prTxCtrl = &prAdapter->rTxCtrl; -+ ASSERT(prTxCtrl); -+ prGlueInfo->IsrTxCnt++; -+ -+ /* Get the TX STATUS */ -+#if CFG_SDIO_INTR_ENHANCE -+ -+ prSDIOCtrl = prAdapter->prSDIOCtrl; -+#if DBG -+ /* dumpMemory8((PUINT_8)prSDIOCtrl, sizeof(SDIO_CTRL_T)); */ -+#endif -+ -+ nicTxReleaseResource(prAdapter, (PUINT_8) &prSDIOCtrl->rTxInfo); -+ kalMemZero(&prSDIOCtrl->rTxInfo, sizeof(prSDIOCtrl->rTxInfo)); -+ -+#else -+ -+ HAL_MCR_RD(prAdapter, MCR_WTSR0, &au4TxCount[0]); -+ HAL_MCR_RD(prAdapter, MCR_WTSR1, &au4TxCount[1]); -+ DBGLOG(EMU, TRACE, "MCR_WTSR0: 0x%x, MCR_WTSR1: 0x%x\n", au4TxCount[0], au4TxCount[1]); -+ -+ nicTxReleaseResource(prAdapter, (PUINT_8) au4TxCount); -+ -+#endif /* CFG_SDIO_INTR_ENHANCE */ -+ -+ nicTxAdjustTcq(prAdapter); -+ -+ /* Indicate Service Thread */ -+ if (kalGetTxPendingCmdCount(prAdapter->prGlueInfo) > 0 || wlanGetTxPendingFrameCount(prAdapter) > 0) -+ kalSetEvent(prAdapter->prGlueInfo); -+ -+} /* end of nicProcessTxInterrupt() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief this function frees packet of P_MSDU_INFO_T linked-list -+* -+* @param prAdapter Pointer to the Adapter structure. -+* @param prMsduInfoList a link list of P_MSDU_INFO_T -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicTxFreeMsduInfoPacket(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfoListHead) -+{ -+ P_NATIVE_PACKET prNativePacket; -+ P_MSDU_INFO_T prMsduInfo = prMsduInfoListHead; -+ P_TX_CTRL_T prTxCtrl; -+ -+ ASSERT(prAdapter); -+ ASSERT(prMsduInfoListHead); -+ -+ prTxCtrl = &prAdapter->rTxCtrl; -+ -+ while (prMsduInfo) { -+ prNativePacket = prMsduInfo->prPacket; -+ -+ if (prMsduInfo->eSrc == TX_PACKET_OS) { -+ kalSendComplete(prAdapter->prGlueInfo, prNativePacket, WLAN_STATUS_FAILURE); -+ } else if (prMsduInfo->eSrc == TX_PACKET_MGMT) { -+ P_MSDU_INFO_T prTempMsduInfo = prMsduInfo; -+ -+ if (prMsduInfo->pfTxDoneHandler) -+ prMsduInfo->pfTxDoneHandler(prAdapter, prMsduInfo, TX_RESULT_DROPPED_IN_DRIVER); -+ prMsduInfo = (P_MSDU_INFO_T) QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T) prMsduInfo); -+ cnmMgtPktFree(prAdapter, prTempMsduInfo); -+ continue; -+ } else if (prMsduInfo->eSrc == TX_PACKET_FORWARDING) { -+ GLUE_DEC_REF_CNT(prTxCtrl->i4PendingFwdFrameCount); -+ } -+ -+ prMsduInfo = (P_MSDU_INFO_T) QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T) prMsduInfo); -+ } -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief this function returns P_MSDU_INFO_T of MsduInfoList to TxCtrl->rfreeMsduInfoList -+* -+* @param prAdapter Pointer to the Adapter structure. -+* @param prMsduInfoList a link list of P_MSDU_INFO_T -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID nicTxReturnMsduInfo(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfoListHead) -+{ -+ P_TX_CTRL_T prTxCtrl; -+ P_MSDU_INFO_T prMsduInfo = prMsduInfoListHead, prNextMsduInfo; -+ -+ KAL_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(prAdapter); -+ -+ prTxCtrl = &prAdapter->rTxCtrl; -+ ASSERT(prTxCtrl); -+ -+ while (prMsduInfo) { -+ prNextMsduInfo = (P_MSDU_INFO_T) QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T) prMsduInfo); -+ -+ switch (prMsduInfo->eSrc) { -+ case TX_PACKET_FORWARDING: -+ wlanReturnPacket(prAdapter, prMsduInfo->prPacket); -+ break; -+ case TX_PACKET_OS: -+ case TX_PACKET_OS_OID: -+ case TX_PACKET_MGMT: -+ default: -+ break; -+ } -+ -+ /* Reset MSDU_INFO fields */ -+ kalMemZero(prMsduInfo, sizeof(MSDU_INFO_T)); -+ -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_MSDU_INFO_LIST); -+ QUEUE_INSERT_TAIL(&prTxCtrl->rFreeMsduInfoList, (P_QUE_ENTRY_T) prMsduInfo); -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_MSDU_INFO_LIST); -+ prMsduInfo = prNextMsduInfo; -+ }; -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief this function fills packet information to P_MSDU_INFO_T -+* -+* @param prAdapter Pointer to the Adapter structure. -+* @param prMsduInfo P_MSDU_INFO_T -+* @param prPacket P_NATIVE_PACKET -+* -+* @retval TRUE Success to extract information -+* @retval FALSE Fail to extract correct information -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN nicTxFillMsduInfo(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo, IN P_NATIVE_PACKET prPacket) -+{ -+ P_GLUE_INFO_T prGlueInfo; -+ UINT_8 ucPriorityParam; -+ UINT_8 ucMacHeaderLen; -+ UINT_8 aucEthDestAddr[PARAM_MAC_ADDR_LEN]; -+ BOOLEAN fgIs1x = FALSE; -+ BOOLEAN fgIsPAL = FALSE; -+ UINT_32 u4PacketLen; -+ ULONG u4SysTime; -+ UINT_8 ucNetworkType; -+ struct sk_buff *prSkb = (struct sk_buff *)prPacket; -+ -+ ASSERT(prAdapter); -+ -+ prGlueInfo = prAdapter->prGlueInfo; -+ ASSERT(prGlueInfo); -+ -+ if (kalQoSFrameClassifierAndPacketInfo(prGlueInfo, -+ prPacket, -+ &ucPriorityParam, -+ &u4PacketLen, -+ aucEthDestAddr, -+ &fgIs1x, &fgIsPAL, &ucNetworkType, -+ NULL) == FALSE) { -+ return FALSE; -+ } -+#if CFG_ENABLE_PKT_LIFETIME_PROFILE -+ nicTxLifetimeCheck(prAdapter, prMsduInfo, prPacket, ucPriorityParam, u4PacketLen, ucNetworkType); -+#endif -+ -+ /* Save the value of Priority Parameter */ -+ GLUE_SET_PKT_TID(prPacket, ucPriorityParam); -+ -+ if (fgIs1x) -+ GLUE_SET_PKT_FLAG_1X(prPacket); -+ -+ if (fgIsPAL) -+ GLUE_SET_PKT_FLAG_PAL(prPacket); -+ -+ ucMacHeaderLen = ETH_HLEN; -+ -+ /* Save the value of Header Length */ -+ GLUE_SET_PKT_HEADER_LEN(prPacket, ucMacHeaderLen); -+ -+ /* Save the value of Frame Length */ -+ GLUE_SET_PKT_FRAME_LEN(prPacket, (UINT_16) u4PacketLen); -+ -+ /* Save the value of Arrival Time */ -+ u4SysTime = (OS_SYSTIME) kalGetTimeTick(); -+ GLUE_SET_PKT_ARRIVAL_TIME(prPacket, u4SysTime); -+ -+ prMsduInfo->prPacket = prPacket; -+ prMsduInfo->fgIs802_1x = fgIs1x; -+ prMsduInfo->fgIs802_11 = FALSE; -+ prMsduInfo->ucNetworkType = ucNetworkType; -+ prMsduInfo->ucUserPriority = ucPriorityParam; -+ prMsduInfo->ucMacHeaderLength = ucMacHeaderLen; -+ prMsduInfo->u2FrameLength = (UINT_16) u4PacketLen; -+ COPY_MAC_ADDR(prMsduInfo->aucEthDestAddr, aucEthDestAddr); -+ -+ if (prSkb->len > ETH_HLEN) -+ STATS_TX_PKT_CALLBACK(prSkb->data, prMsduInfo); -+ return TRUE; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief this function update TCQ values by passing current status to txAdjustTcQuotas -+* -+* @param prAdapter Pointer to the Adapter structure. -+* -+* @retval WLAN_STATUS_SUCCESS Updated successfully -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS nicTxAdjustTcq(IN P_ADAPTER_T prAdapter) -+{ -+ UINT_32 u4Num; -+ TX_TCQ_ADJUST_T rTcqAdjust; -+ P_TX_CTRL_T prTxCtrl; -+ -+ KAL_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(prAdapter); -+ -+ prTxCtrl = &prAdapter->rTxCtrl; -+ ASSERT(prTxCtrl); -+ -+ qmAdjustTcQuotas(prAdapter, &rTcqAdjust, &prTxCtrl->rTc); -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_RESOURCE); -+ -+ for (u4Num = 0; u4Num < TC_NUM; u4Num++) { -+ prTxCtrl->rTc.aucFreeBufferCount[u4Num] += rTcqAdjust.acVariation[u4Num]; -+ prTxCtrl->rTc.aucMaxNumOfBuffer[u4Num] += rTcqAdjust.acVariation[u4Num]; -+ } -+ -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_RESOURCE); -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief this function flushes all packets queued in STA/AC queue -+* -+* @param prAdapter Pointer to the Adapter structure. -+* -+* @retval WLAN_STATUS_SUCCESS Flushed successfully -+*/ -+/*----------------------------------------------------------------------------*/ -+ -+WLAN_STATUS nicTxFlush(IN P_ADAPTER_T prAdapter) -+{ -+ P_MSDU_INFO_T prMsduInfo; -+ -+ KAL_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(prAdapter); -+ -+ /* ask Per STA/AC queue to be fllushed and return all queued packets */ -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_QM_TX_QUEUE); -+ prMsduInfo = qmFlushTxQueues(prAdapter); -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_QM_TX_QUEUE); -+ -+ if (prMsduInfo != NULL) { -+ nicTxFreeMsduInfoPacket(prAdapter, prMsduInfo); -+ nicTxReturnMsduInfo(prAdapter, prMsduInfo); -+ } -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+#if CFG_ENABLE_FW_DOWNLOAD -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief In this function, we'll write Command(CMD_INFO_T) into HIF. -+* However this function is used for INIT_CMD. -+* -+* In order to avoid further maintenance issues, these 2 functions are separated -+* -+* @param prAdapter Pointer to the Adapter structure. -+* @param prPacketInfo Pointer of CMD_INFO_T -+* @param ucTC Specify the resource of TC -+* -+* @retval WLAN_STATUS_SUCCESS Bus access ok. -+* @retval WLAN_STATUS_FAILURE Bus access fail. -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS nicTxInitCmd(IN P_ADAPTER_T prAdapter, IN P_CMD_INFO_T prCmdInfo, IN UINT_8 ucTC) -+{ -+ P_INIT_HIF_TX_HEADER_T prInitTxHeader; -+ UINT_16 u2OverallBufferLength; -+ PUINT_8 pucOutputBuf = (PUINT_8) NULL; /* Pointer to Transmit Data Structure Frame */ -+ UINT_32 ucPortIdx; -+ P_TX_CTRL_T prTxCtrl; -+ -+ ASSERT(prAdapter); -+ ASSERT(prCmdInfo); -+ ASSERT(ucTC == TC0_INDEX); -+ -+ prTxCtrl = &prAdapter->rTxCtrl; -+ pucOutputBuf = prTxCtrl->pucTxCoalescingBufPtr; -+ prInitTxHeader = (P_INIT_HIF_TX_HEADER_T) prCmdInfo->pucInfoBuffer; -+ -+ /* <1> Compose the Header of Transmit Data Structure for CMD Packet */ -+ u2OverallBufferLength = -+ TFCB_FRAME_PAD_TO_DW((prCmdInfo->u2InfoBufLen) & (UINT_16) HIF_TX_HDR_TX_BYTE_COUNT_MASK); -+ -+ prInitTxHeader->u2TxByteCount = u2OverallBufferLength; -+ prInitTxHeader->ucEtherTypeOffset = 0; -+ prInitTxHeader->ucCSflags = 0; -+ -+ /* <2> Assign Data Port */ -+ if (ucTC != TC4_INDEX) { -+ ucPortIdx = 0; -+ } else { /* Broadcast/multicast data packets */ -+ ucPortIdx = 1; -+ } -+ -+ /* <3> Copy CMD Header to command buffer (by using pucCoalescingBufCached) */ -+ kalMemCopy((PVOID)&pucOutputBuf[0], (PVOID) prCmdInfo->pucInfoBuffer, prCmdInfo->u2InfoBufLen); -+ -+ ASSERT(u2OverallBufferLength <= prAdapter->u4CoalescingBufCachedSize); -+ -+ /* <4> Write frame to data port */ -+ HAL_WRITE_TX_PORT(prAdapter, -+ ucPortIdx, -+ (UINT_32) u2OverallBufferLength, -+ (PUINT_8) pucOutputBuf, (UINT_32) prAdapter->u4CoalescingBufCachedSize); -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief In this function, we'll reset TX resource counter to initial value used -+* in F/W download state -+* -+* @param prAdapter Pointer to the Adapter structure. -+* -+* @retval WLAN_STATUS_SUCCESS Reset is done successfully. -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS nicTxInitResetResource(IN P_ADAPTER_T prAdapter) -+{ -+ P_TX_CTRL_T prTxCtrl; -+ -+ DEBUGFUNC("nicTxInitResetResource"); -+ -+ ASSERT(prAdapter); -+ prTxCtrl = &prAdapter->rTxCtrl; -+ -+ prTxCtrl->rTc.aucMaxNumOfBuffer[TC0_INDEX] = NIC_TX_INIT_BUFF_COUNT_TC0; -+ prTxCtrl->rTc.aucFreeBufferCount[TC0_INDEX] = NIC_TX_INIT_BUFF_COUNT_TC0; -+ -+ prTxCtrl->rTc.aucMaxNumOfBuffer[TC1_INDEX] = NIC_TX_INIT_BUFF_COUNT_TC1; -+ prTxCtrl->rTc.aucFreeBufferCount[TC1_INDEX] = NIC_TX_INIT_BUFF_COUNT_TC1; -+ -+ prTxCtrl->rTc.aucMaxNumOfBuffer[TC2_INDEX] = NIC_TX_INIT_BUFF_COUNT_TC2; -+ prTxCtrl->rTc.aucFreeBufferCount[TC2_INDEX] = NIC_TX_INIT_BUFF_COUNT_TC2; -+ -+ prTxCtrl->rTc.aucMaxNumOfBuffer[TC3_INDEX] = NIC_TX_INIT_BUFF_COUNT_TC3; -+ prTxCtrl->rTc.aucFreeBufferCount[TC3_INDEX] = NIC_TX_INIT_BUFF_COUNT_TC3; -+ -+ prTxCtrl->rTc.aucMaxNumOfBuffer[TC4_INDEX] = NIC_TX_INIT_BUFF_COUNT_TC4; -+ prTxCtrl->rTc.aucFreeBufferCount[TC4_INDEX] = NIC_TX_INIT_BUFF_COUNT_TC4; -+ -+ prTxCtrl->rTc.aucMaxNumOfBuffer[TC5_INDEX] = NIC_TX_INIT_BUFF_COUNT_TC5; -+ prTxCtrl->rTc.aucFreeBufferCount[TC5_INDEX] = NIC_TX_INIT_BUFF_COUNT_TC5; -+ -+ return WLAN_STATUS_SUCCESS; -+ -+} -+ -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief this function enqueues MSDU_INFO_T into queue management, -+* or command queue -+* -+* @param prAdapter Pointer to the Adapter structure. -+* prMsduInfo Pointer to MSDU -+* -+* @retval WLAN_STATUS_SUCCESS Reset is done successfully. -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS nicTxEnqueueMsdu(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo) -+{ -+ P_TX_CTRL_T prTxCtrl; -+ P_MSDU_INFO_T prNextMsduInfo, prRetMsduInfo, prMsduInfoHead; -+ QUE_T qDataPort0, qDataPort1; -+ P_CMD_INFO_T prCmdInfo; -+ WLAN_STATUS u4Status = WLAN_STATUS_SUCCESS; -+ -+ KAL_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(prAdapter); -+ ASSERT(prMsduInfo); -+ -+ prTxCtrl = &prAdapter->rTxCtrl; -+ ASSERT(prTxCtrl); -+ -+ QUEUE_INITIALIZE(&qDataPort0); -+ QUEUE_INITIALIZE(&qDataPort1); -+ -+ /* check how many management frame are being queued */ -+ while (prMsduInfo) { -+ prNextMsduInfo = (P_MSDU_INFO_T) QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T) prMsduInfo); -+ -+ QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T) prMsduInfo) = NULL; -+ -+ if (prMsduInfo->eSrc == TX_PACKET_MGMT) { -+ /* MMPDU: force stick to TC4 */ -+ prMsduInfo->ucTC = TC4_INDEX; -+ -+ QUEUE_INSERT_TAIL(&qDataPort1, (P_QUE_ENTRY_T) prMsduInfo); -+ } else { -+ QUEUE_INSERT_TAIL(&qDataPort0, (P_QUE_ENTRY_T) prMsduInfo); -+ } -+ -+ prMsduInfo = prNextMsduInfo; -+ } -+ -+ if (qDataPort0.u4NumElem) { -+ /* send to QM: queue the packet to different TX queue by policy */ -+ KAL_SPIN_LOCK_DECLARATION(); -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_QM_TX_QUEUE); -+ prRetMsduInfo = qmEnqueueTxPackets(prAdapter, (P_MSDU_INFO_T) QUEUE_GET_HEAD(&qDataPort0)); -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_QM_TX_QUEUE); -+ -+ /* post-process for "dropped" packets */ -+ if (prRetMsduInfo != NULL) { /* unable to enqueue */ -+ nicTxFreeMsduInfoPacket(prAdapter, prRetMsduInfo); -+ nicTxReturnMsduInfo(prAdapter, prRetMsduInfo); -+ } -+ } -+ -+ if (qDataPort1.u4NumElem) { -+ prMsduInfoHead = (P_MSDU_INFO_T) QUEUE_GET_HEAD(&qDataPort1); -+ -+ if (qDataPort1.u4NumElem > nicTxGetFreeCmdCount(prAdapter)) { -+ /* not enough descriptors for sending */ -+ u4Status = WLAN_STATUS_FAILURE; -+ -+ /* free all MSDUs */ -+ while (prMsduInfoHead) { -+ prNextMsduInfo = (P_MSDU_INFO_T) QUEUE_GET_NEXT_ENTRY(&prMsduInfoHead->rQueEntry); -+ -+ if (prMsduInfoHead->pfTxDoneHandler != NULL) { -+ prMsduInfoHead->pfTxDoneHandler(prAdapter, prMsduInfoHead, -+ TX_RESULT_DROPPED_IN_DRIVER); -+ } -+ -+ cnmMgtPktFree(prAdapter, prMsduInfoHead); -+ -+ prMsduInfoHead = prNextMsduInfo; -+ } -+ } else { -+ /* send to command queue */ -+ while (prMsduInfoHead) { -+ prNextMsduInfo = (P_MSDU_INFO_T) QUEUE_GET_NEXT_ENTRY(&prMsduInfoHead->rQueEntry); -+ -+ KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_RESOURCE); -+ QUEUE_REMOVE_HEAD(&prAdapter->rFreeCmdList, prCmdInfo, P_CMD_INFO_T); -+ KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_RESOURCE); -+ -+ if (prCmdInfo) { -+ GLUE_INC_REF_CNT(prTxCtrl->i4TxMgmtPendingNum); -+ -+ kalMemZero(prCmdInfo, sizeof(CMD_INFO_T)); -+ -+ prCmdInfo->eCmdType = COMMAND_TYPE_MANAGEMENT_FRAME; -+ prCmdInfo->u2InfoBufLen = prMsduInfoHead->u2FrameLength; -+ prCmdInfo->pucInfoBuffer = NULL; -+ prCmdInfo->prPacket = (P_NATIVE_PACKET) prMsduInfoHead; -+ prCmdInfo->ucStaRecIndex = prMsduInfoHead->ucStaRecIndex; -+ prCmdInfo->eNetworkType = prMsduInfoHead->ucNetworkType; -+ prCmdInfo->pfCmdDoneHandler = NULL; -+ prCmdInfo->pfCmdTimeoutHandler = NULL; -+ prCmdInfo->fgIsOid = FALSE; -+ prCmdInfo->fgSetQuery = TRUE; -+ prCmdInfo->fgNeedResp = FALSE; -+ -+ kalEnqueueCommand(prAdapter->prGlueInfo, (P_QUE_ENTRY_T) prCmdInfo); -+ } else { -+ /* Cmd free count is larger than expected, but allocation fail. */ -+ ASSERT(0); -+ -+ u4Status = WLAN_STATUS_FAILURE; -+ cnmMgtPktFree(prAdapter, prMsduInfoHead); -+ } -+ -+ prMsduInfoHead = prNextMsduInfo; -+ } -+ } -+ } -+ -+ /* indicate service thread for sending */ -+ if (prTxCtrl->i4TxMgmtPendingNum > 0 || kalGetTxPendingFrameCount(prAdapter->prGlueInfo) > 0) -+ kalSetEvent(prAdapter->prGlueInfo); -+ -+ return u4Status; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief this function returns available count in command queue -+* -+* @param prAdapter Pointer to the Adapter structure. -+* -+* @retval -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT_32 nicTxGetFreeCmdCount(IN P_ADAPTER_T prAdapter) -+{ -+ ASSERT(prAdapter); -+ -+ return prAdapter->rFreeCmdList.u4NumElem; -+} -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/nic/p2p_nic.c b/drivers/misc/mediatek/connectivity/wlan/gen2/nic/p2p_nic.c -new file mode 100644 -index 000000000000..38e4569bc04f ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/nic/p2p_nic.c -@@ -0,0 +1,192 @@ -+/* -+** Id: @(#) p2p_nic.c@@ -+*/ -+ -+/*! \file p2p_nic.c -+ \brief Wi-Fi Direct Functions that provide operation in NIC's (Network Interface Card) point of view. -+ -+ This file includes functions which unite multiple hal(Hardware) operations -+ and also take the responsibility of Software Resource Management in order -+ to keep the synchronization with Hardware Manipulation. -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+#include "precomp.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief When Probe Rsp & Beacon frame is received and decide a P2P device, -+* this function will be invoked to buffer scan result -+* -+* @param prAdapter Pointer to the Adapter structure. -+* @param prEventScanResult Pointer of EVENT_SCAN_RESULT_T. -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+nicRxAddP2pDevice(IN P_ADAPTER_T prAdapter, -+ IN P_EVENT_P2P_DEV_DISCOVER_RESULT_T prP2pResult, IN PUINT_8 pucRxIEBuf, IN UINT_16 u2RxIELength) -+{ -+ P_P2P_INFO_T prP2pInfo = (P_P2P_INFO_T) NULL; -+ P_EVENT_P2P_DEV_DISCOVER_RESULT_T prTargetResult = (P_EVENT_P2P_DEV_DISCOVER_RESULT_T) NULL; -+ UINT_32 u4Idx = 0; -+ BOOLEAN bUpdate = FALSE; -+ -+ PUINT_8 pucIeBuf = (PUINT_8) NULL; -+ UINT_16 u2IELength = 0; -+ UINT_8 zeroMac[] = { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }; -+ -+ ASSERT(prAdapter); -+ -+ prP2pInfo = prAdapter->prP2pInfo; -+ -+ for (u4Idx = 0; u4Idx < prP2pInfo->u4DeviceNum; u4Idx++) { -+ prTargetResult = &prP2pInfo->arP2pDiscoverResult[u4Idx]; -+ -+ if (EQUAL_MAC_ADDR(prTargetResult->aucDeviceAddr, prP2pResult->aucDeviceAddr)) { -+ bUpdate = TRUE; -+ -+ /* Backup OLD buffer result. */ -+ pucIeBuf = prTargetResult->pucIeBuf; -+ u2IELength = prTargetResult->u2IELength; -+ -+ /* Update Device Info. */ -+ /* zero */ -+ kalMemZero(prTargetResult, sizeof(EVENT_P2P_DEV_DISCOVER_RESULT_T)); -+ -+ /* then buffer */ -+ kalMemCopy(prTargetResult, (PVOID) prP2pResult, sizeof(EVENT_P2P_DEV_DISCOVER_RESULT_T)); -+ -+ /* See if new IE length is longer or not. */ -+ if ((u2RxIELength > u2IELength) && (u2IELength != 0)) { -+ /* Buffer is not enough. */ -+ u2RxIELength = u2IELength; -+ } else if ((u2IELength == 0) && (u2RxIELength != 0)) { -+ /* RX new IE buf. */ -+ ASSERT(pucIeBuf == NULL); -+ pucIeBuf = prP2pInfo->pucCurrIePtr; -+ -+ if (((ULONG) prP2pInfo->pucCurrIePtr + (ULONG) u2RxIELength) > -+ (ULONG)&prP2pInfo->aucCommIePool[CFG_MAX_COMMON_IE_BUF_LEN]) { -+ /* Common Buffer is no enough. */ -+ u2RxIELength = -+ (UINT_16) ((ULONG)&prP2pInfo->aucCommIePool[CFG_MAX_COMMON_IE_BUF_LEN] - -+ (ULONG) prP2pInfo->pucCurrIePtr); -+ } -+ -+ /* Step to next buffer address. */ -+ prP2pInfo->pucCurrIePtr = -+ (PUINT_8) ((ULONG) prP2pInfo->pucCurrIePtr + (ULONG) u2RxIELength); -+ } -+ -+ /* Restore buffer pointer. */ -+ prTargetResult->pucIeBuf = pucIeBuf; -+ -+ if (pucRxIEBuf) { -+ /* If new received IE is available. -+ * Replace the old one & update new IE length. -+ */ -+ kalMemCopy(pucIeBuf, pucRxIEBuf, u2RxIELength); -+ prTargetResult->u2IELength = u2RxIELength; -+ } else { -+ /* There is no new IE information, keep the old one. */ -+ prTargetResult->u2IELength = u2IELength; -+ } -+ } -+ } -+ -+ if (!bUpdate) { -+ /* We would flush the whole scan result after each scan request is issued. -+ * If P2P device is too many, it may over the scan list. -+ */ -+ if ((u4Idx < CFG_MAX_NUM_BSS_LIST) && (UNEQUAL_MAC_ADDR(zeroMac, prP2pResult->aucDeviceAddr))) { -+ /* whsu:XXX */ -+ prTargetResult = &prP2pInfo->arP2pDiscoverResult[u4Idx]; -+ -+ /* zero */ -+ kalMemZero(prTargetResult, sizeof(EVENT_P2P_DEV_DISCOVER_RESULT_T)); -+ -+ /* then buffer */ -+ kalMemCopy(prTargetResult, (PVOID) prP2pResult, sizeof(EVENT_P2P_DEV_DISCOVER_RESULT_T)); -+ -+ /* printk("DVC FND %d %pM, %pM\n", -+ prP2pInfo->u4DeviceNum, -+ prP2pResult->aucDeviceAddr, -+ prTargetResult->aucDeviceAddr); */ -+ -+ if (u2RxIELength) { -+ prTargetResult->pucIeBuf = prP2pInfo->pucCurrIePtr; -+ -+ if (((ULONG) prP2pInfo->pucCurrIePtr + (ULONG) u2RxIELength) > -+ (ULONG)&prP2pInfo->aucCommIePool[CFG_MAX_COMMON_IE_BUF_LEN]) { -+ /* Common Buffer is no enough. */ -+ u2IELength = -+ (UINT_16) ((ULONG)&prP2pInfo->aucCommIePool[CFG_MAX_COMMON_IE_BUF_LEN] - -+ (ULONG) prP2pInfo->pucCurrIePtr); -+ } else { -+ u2IELength = u2RxIELength; -+ } -+ -+ prP2pInfo->pucCurrIePtr = -+ (PUINT_8) ((ULONG) prP2pInfo->pucCurrIePtr + (ULONG) u2IELength); -+ -+ kalMemCopy((PVOID) prTargetResult->pucIeBuf, (PVOID) pucRxIEBuf, (UINT_32) u2IELength); -+ prTargetResult->u2IELength = u2IELength; -+ } else { -+ prTargetResult->pucIeBuf = NULL; -+ prTargetResult->u2IELength = 0; -+ } -+ -+ prP2pInfo->u4DeviceNum++; -+ -+ } else { -+ /* TODO: Fixme to replace an old one. (?) */ -+ ASSERT(FALSE); -+ } -+ } -+} /* nicRxAddP2pDevice */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/nic/que_mgt.c b/drivers/misc/mediatek/connectivity/wlan/gen2/nic/que_mgt.c -new file mode 100644 -index 000000000000..dd00859d4608 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/nic/que_mgt.c -@@ -0,0 +1,5038 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/nic/que_mgt.c#1 -+*/ -+ -+/*! \file "que_mgt.c" -+ \brief TX/RX queues management -+ -+ The main tasks of queue management include TC-based HIF TX flow control, -+ adaptive TC quota adjustment, HIF TX grant scheduling, Power-Save -+ forwarding control, RX packet reordering, and RX BA agreement management. -+*/ -+ -+/* -+** Log: que_mgt.c -+** -+** 04 11 2013 yuche.tsai -+** [ALPS00542142] [Pre-SQC][6627][W]use wifi direct press cancel connect, phone all stop. -+** Drop the probe response packet when absent. -+** -+** 04 09 2013 yuche.tsai -+** [ALPS00542142] [Pre-SQC][6627][W]use wifi direct press cancel connect, phone all stop. -+** Fix CMD buffer short issue. -+** -+** 04 09 2013 yuche.tsai -+** [ALPS00542142] [Pre-SQC][6627][W]use wifi direct press cancel connect, phone all stop. -+** Fix CMD buffer short issue. -+ * -+ * 03 02 2012 terry.wu -+ * NULL -+ * Sync CFG80211 modification from branch 2,2. -+ * -+ * 02 23 2012 eddie.chen -+ * [WCXRP00001194] [MT6620][DRV/FW] follow admission control bit to change the enqueue rule -+ * Change the enqueue policy when ACM = 1. -+ * -+ * 11 22 2011 yuche.tsai -+ * NULL -+ * Code refine, remove one #if 0 code. -+ * -+ * 11 19 2011 eddie.chen -+ * [WCXRP00001096] [MT6620 Wi-Fi][Driver/FW] Enhance the log function (xlog) -+ * Add xlog for tx -+ * -+ * 11 18 2011 yuche.tsai -+ * NULL -+ * CONFIG P2P support RSSI query, default turned off. -+ * -+ * 11 18 2011 eddie.chen -+ * [WCXRP00001096] [MT6620 Wi-Fi][Driver/FW] Enhance the log function (xlog) -+ * Fix xlog format to hex format -+ * -+ * 11 17 2011 tsaiyuan.hsu -+ * [WCXRP00001115] [MT6620 Wi-Fi][DRV] avoid deactivating staRec when changing state 3 to 3. -+ * avoid deactivating staRec when changing state from 3 to 3. -+ * -+ * 11 11 2011 tsaiyuan.hsu -+ * [WCXRP00001083] [MT6620 Wi-Fi][DRV]] dump debug counter or frames when debugging is triggered -+ * add debug msg for xlog. -+ * -+ * 11 11 2011 tsaiyuan.hsu -+ * [WCXRP00001083] [MT6620 Wi-Fi][DRV]] dump debug counter or frames when debugging is triggered -+ * add debug counters of bb and ar for xlog. -+ * -+ * 11 10 2011 eddie.chen -+ * [WCXRP00001096] [MT6620 Wi-Fi][Driver/FW] Enhance the log function (xlog) -+ * Use short name for xlog. -+ * -+ * 11 10 2011 eddie.chen -+ * [WCXRP00001096] [MT6620 Wi-Fi][Driver/FW] Enhance the log function (xlog) -+ * Modify the QM xlog level and remove LOG_FUNC. -+ * -+ * 11 10 2011 chinglan.wang -+ * NULL -+ * [WiFi WPS]Can't switch to new AP via WPS PBC when there existing a connection to another AP. -+ * -+ * 11 09 2011 chinglan.wang -+ * NULL -+ * [WiFi direct]Can't make P2P connect via PBC. -+ * -+ * 11 08 2011 eddie.chen -+ * [WCXRP00001096] [MT6620 Wi-Fi][Driver/FW] Enhance the log function (xlog) -+ * Add xlog function. -+ * -+ * 11 07 2011 tsaiyuan.hsu -+ * [WCXRP00001083] [MT6620 Wi-Fi][DRV]] dump debug counter or frames when debugging is triggered -+ * add debug counters and periodically dump counters for debugging. -+ * -+ * 11 01 2011 chinglan.wang -+ * NULL -+ * Modify the Wi-Fi method of the flush TX queue when disconnect the AP. -+ * If disconnect the AP and flush all the data frame in the TX queue, WPS cannot do the 4-way handshake to connect to -+ * the AP.. -+ * -+ * 10 25 2011 wh.su -+ * [WCXRP00001059] [MT6620 Wi-Fi][Driver][P2P] Fixed sometimes data (1x) will not indicate to upper layer due ba check -+ * un-expect -+ * let the Rx BA accept even the sta not valid. -+ * -+ * 09 28 2011 tsaiyuan.hsu -+ * [WCXRP00000900] [MT5931 Wi-Fi] Improve balance of TX and RX -+ * enlarge window size only by 4. -+ * -+ * 09 01 2011 tsaiyuan.hsu -+ * [WCXRP00000900] [MT5931 Wi-Fi] Improve balance of TX and RX -+ * set rx window size as twice buffer size. -+ * -+ * 08 23 2011 yuche.tsai -+ * NULL -+ * Fix multicast address list issue. -+ * -+ * 08 03 2011 tsaiyuan.hsu -+ * [WCXRP00000900] [MT5931 Wi-Fi] Improve balance of TX and RX -+ * force window size at least 16. -+ * -+ * 08 02 2011 yuche.tsai -+ * [WCXRP00000896] [Volunteer Patch][WiFi Direct][Driver] GO with multiple client, TX deauth to a disconnecting device -+ * issue. -+ * Fix GO send deauth frame issue. -+ * -+ * 07 26 2011 eddie.chen -+ * [WCXRP00000874] [MT5931][DRV] API for query the RX reorder queued packets counter -+ * API for query the RX reorder queued packets counter. -+ * -+ * 07 07 2011 eddie.chen -+ * [WCXRP00000834] [MT6620 Wi-Fi][DRV] Send 1x packet when peer STA is in PS. -+ * Add setEvent when free quota is updated. -+ * -+ * 07 05 2011 eddie.chen -+ * [WCXRP00000834] [MT6620 Wi-Fi][DRV] Send 1x packet when peer STA is in PS. -+ * Send 1x when peer STA is in PS. -+ * -+ * 05 31 2011 eddie.chen -+ * [WCXRP00000753] [MT5931 Wi-Fi][DRV] Adjust QM for MT5931 -+ * Fix the QM quota in MT5931. -+ * -+ * 05 11 2011 eddie.chen -+ * [WCXRP00000709] [MT6620 Wi-Fi][Driver] Check free number before copying broadcast packet -+ * Fix dest type when GO packet copying. -+ * -+ * 05 09 2011 yuche.tsai -+ * [WCXRP00000712] [Volunteer Patch][MT6620][Driver] Sending deauth issue when Hot spot is disabled. (GO is dissolved) -+ * Deauthentication frame is not bound to network active status. -+ * -+ * 05 09 2011 eddie.chen -+ * [WCXRP00000709] [MT6620 Wi-Fi][Driver] Check free number before copying broadcast packet -+ * Check free number before copying broadcast packet. -+ * -+ * 04 14 2011 eddie.chen -+ * [WCXRP00000603] [MT6620 Wi-Fi][DRV] Fix Klocwork warning -+ * Check the SW RFB free. Fix the compile warning.. -+ * -+ * 04 12 2011 eddie.chen -+ * [WCXRP00000617] [MT6620 Wi-Fi][DRV/FW] Fix for sigma -+ * Fix the sta index in processing security frame -+ * Simple flow control for TC4 to avoid mgt frames for PS STA to occupy the TC4 -+ * Add debug message. -+ * -+ * 04 11 2011 yuche.tsai -+ * [WCXRP00000627] [Volunteer Patch][MT6620][Driver] Pending MMPUD of P2P Network may crash system issue. -+ * Fix kernel panic issue when MMPDU of P2P is pending in driver. -+ * -+ * 04 08 2011 eddie.chen -+ * [WCXRP00000617] [MT6620 Wi-Fi][DRV/FW] Fix for sigma -+ * Fix for sigma -+ * -+ * 03 28 2011 eddie.chen -+ * [WCXRP00000603] [MT6620 Wi-Fi][DRV] Fix Klocwork warning -+ * Fix Klockwork warning. -+ * -+ * 03 28 2011 eddie.chen -+ * [WCXRP00000602] [MT6620 Wi-Fi][DRV] Fix wmm parameters in beacon for BOW -+ * Fix wmm parameters in beacon for BOW. -+ * -+ * 03 15 2011 eddie.chen -+ * [WCXRP00000554] [MT6620 Wi-Fi][DRV] Add sw control debug counter -+ * Add sw debug counter for QM. -+ * -+ * 02 23 2011 eddie.chen -+ * [WCXRP00000463] [MT6620 Wi-Fi][FW/Driver][Hotspot] Cannot update WMM PS STA's partital bitmap -+ * Fix parsing WMM INFO and bmp delivery bitmap definition. -+ * -+ * 02 17 2011 eddie.chen -+ * [WCXRP00000458] [MT6620 Wi-Fi][Driver] BOW Concurrent - ProbeResp was exist in other channel -+ * 1) Change GetFrameAction decision when BSS is absent. -+ * 2) Check channel and resource in processing ProbeRequest -+ * -+ * 02 08 2011 eddie.chen -+ * [WCXRP00000426] [MT6620 Wi-Fi][FW/Driver] Add STA aging timeout and defualtHwRatein AP mode -+ * Add event STA agint timeout -+ * -+ * 01 27 2011 tsaiyuan.hsu -+ * [WCXRP00000392] [MT6620 Wi-Fi][Driver] Add Roaming Support -+ * add roaming fsm -+ * 1. not support 11r, only use strength of signal to determine roaming. -+ * 2. not enable CFG_SUPPORT_ROAMING until completion of full test. -+ * 3. in 6620, adopt work-around to avoid sign extension problem of cck of hw -+ * 4. assume that change of link quality in smooth way. -+ * -+ * 01 25 2011 yuche.tsai -+ * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record. -+ * Change Station Type in Station Record, Modify MACRO definition for getting station type & network type index & Role. -+ * -+ * 01 24 2011 eddie.chen -+ * [WCXRP00000385] [MT6620 Wi-Fi][DRV] Add destination decision for forwarding packets -+ * Remove comments. -+ * -+ * 01 24 2011 eddie.chen -+ * [WCXRP00000385] [MT6620 Wi-Fi][DRV] Add destination decision for forwarding packets -+ * Add destination decision in AP mode. -+ * -+ * 01 14 2011 wh.su -+ * [WCXRP00000099] [MT6620 Wi-Fi] [Driver] workaround to let the de-authentication can be send out[WCXRP00000326] -+ * [MT6620][Wi-Fi][Driver] check in the binary format gl_sec.o.new instead of use change type!!! -+ * Allow 802.1x can be send even the net is not active due the drver / fw sync issue. -+ * -+ * 01 13 2011 eddie.chen -+ * [WCXRP00000322] Add WMM IE in beacon, -+Add per station flow control when STA is in PS -+ * Fix typo and compile error. -+ * -+ * 01 12 2011 eddie.chen -+ * [WCXRP00000322] Add WMM IE in beacon, -+Add per station flow control when STA is in PS -+ * Fix WMM parameter condition for STA -+ * -+ * 01 12 2011 eddie.chen -+ * [WCXRP00000322] Add WMM IE in beacon, -+Add per station flow control when STA is in PS -+ * 1) Check Bss if support QoS before adding WMMIE -+ * 2) Check if support prAdapter->rWifiVar QoS and uapsd in flow control -+ * -+ * 01 12 2011 george.huang -+ * [WCXRP00000355] [MT6620 Wi-Fi] Set WMM-PS related setting with qualifying AP capability -+ * Update MQM for WMM IE generation method -+ * -+ * 01 11 2011 eddie.chen -+ * [WCXRP00000322] Add WMM IE in beacon, -+Add per station flow control when STA is in PS -+ -+ * Add per STA flow control when STA is in PS mode -+ * -+ * 01 03 2011 george.huang -+ * [WCXRP00000152] [MT6620 Wi-Fi] AP mode power saving function -+ * update prStaRec->fgIsUapsdSupported flag. -+ * -+ * 12 29 2010 eddie.chen -+ * [WCXRP00000322] Add WMM IE in beacon, -+Add per station flow control when STA is in PS -+ -+ * Add WMM parameter for broadcast. -+ * -+ * 12 29 2010 eddie.chen -+ * [WCXRP00000322] Add WMM IE in beacon, -+Add per station flow control when STA is in PS -+ -+ * 1) PS flow control event -+ * -+ * 2) WMM IE in beacon, assoc resp, probe resp -+ * -+ * 12 23 2010 george.huang -+ * [WCXRP00000152] [MT6620 Wi-Fi] AP mode power saving function -+ * 1. update WMM IE parsing, with ASSOC REQ handling -+ * 2. extend U-APSD parameter passing from driver to FW -+ * -+ * 10 14 2010 wh.su -+ * [WCXRP00000099] [MT6620 Wi-Fi] [Driver] workaround to let the de-authentication can be send out -+ * use the #14 and modify the add code for check MMPDU. -+ * -+ * 10 14 2010 wh.su -+ * [WCXRP00000099] [MT6620 Wi-Fi] [Driver] workaround to let the de-authentication can be send out -+ * only MMPDU not check the netActive flag. -+ * -+ * 10 14 2010 wh.su -+ * [WCXRP00000099] [MT6620 Wi-Fi] [Driver] workaround to let the de-authentication can be send out -+ * not check the netActive flag for mgmt . -+ * -+ * 10 04 2010 cp.wu -+ * [WCXRP00000077] [MT6620 Wi-Fi][Driver][FW] Eliminate use of ENUM_NETWORK_TYPE_T and replaced by -+ * ENUM_NETWORK_TYPE_INDEX_T only -+ * remove ENUM_NETWORK_TYPE_T definitions -+ * -+ * 09 21 2010 kevin.huang -+ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning -+ * Eliminate Linux Compile Warning -+ * -+ * 08 30 2010 yarco.yang -+ * NULL -+ * Fixed klockwork error message -+ * -+ * 08 18 2010 yarco.yang -+ * NULL -+ * 1. Fixed HW checksum offload function not work under Linux issue. -+ * 2. Add debug message. -+ * -+ * 08 10 2010 yarco.yang -+ * NULL -+ * Code refine -+ * -+ * 08 06 2010 yarco.yang -+ * NULL -+ * Update qmGetFrameAction() to allow P2P MGMT frame w/o STA_Record still can perform TX action -+ * -+ * 07 26 2010 cp.wu -+ * -+ * AIS-FSM FIX: return channel privilege even when the privilege is not granted yet -+ * QM: qmGetFrameAction() won't assert when corresponding STA-REC index is not found -+ * -+ * 07 20 2010 yarco.yang -+ * -+ * Add to SetEvent when BSS is from Absent to Present or STA from PS to Awake -+ * -+ * 07 16 2010 yarco.yang -+ * -+ * 1. Support BSS Absence/Presence Event -+ * 2. Support STA change PS mode Event -+ * 3. Support BMC forwarding for AP mode. -+ * -+ * 07 14 2010 yarco.yang -+ * -+ * 1. Remove CFG_MQM_MIGRATION -+ * 2. Add CMD_UPDATE_WMM_PARMS command -+ * -+ * 07 13 2010 yarco.yang -+ * -+ * [WPD00003849] -+ * [MT6620 and MT5931] SW Migration, add qmGetFrameAction() API for CMD Queue Processing -+ * -+ * 07 09 2010 yarco.yang -+ * -+ * [MT6620 and MT5931] SW Migration: Add ADDBA support -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 07 08 2010 yarco.yang -+ * [WPD00003837][MT6620]Data Path Refine -+ * . -+ * -+ * 07 06 2010 yarco.yang -+ * [WPD00003837][MT6620]Data Path Refine -+ * Use fgInUse instead of fgIsValid for De-queue judgement -+ * -+ * 07 06 2010 yarco.yang -+ * [WPD00003837][MT6620]Data Path Refine -+ * For MMPDU, STA_REC will be decided by caller module -+ * -+ * 07 06 2010 yarco.yang -+ * [WPD00003837][MT6620]Data Path Refine -+ * Add MGMT Packet type for HIF_TX_HEADER -+ * -+ * 06 29 2010 yarco.yang -+ * [WPD00003837][MT6620]Data Path Refine -+ * replace g_rQM with Adpater->rQM -+ * -+ * 06 25 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * add API in que_mgt to retrieve sta-rec index for security frames. -+ * -+ * 06 23 2010 yarco.yang -+ * [WPD00003837][MT6620]Data Path Refine -+ * Merge g_arStaRec[] into adapter->arStaRec[] -+ * -+ * 06 21 2010 yarco.yang -+ * [WPD00003837][MT6620]Data Path Refine -+ * Support CFG_MQM_MIGRATION flag -+ * -+ * 06 11 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) migrate assoc.c. -+ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness -+ * 3) add configuration options for CNM_MEM and RSN modules -+ * 4) add data path for management frames -+ * 5) eliminate rPacketInfo of MSDU_INFO_T -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 03 31 2010 tehuang.liu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * Refined the debug msg -+ * -+ * 03 30 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * comment out one assertion which refer to undefined data member. -+ * -+ * 03 30 2010 tehuang.liu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * Enabled adaptive TC resource control -+ * -+ * 03 24 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * initial import for Linux port -+ * -+* 03 17 2010 tehuang.liu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * Changed STA_REC index determination rules (DA=BMCAST always --> STA_REC_INDEX_BMCAST) -+ * -+ * 03 11 2010 tehuang.liu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * Fixed buffer leak when processing BAR frames -+ * -+ * 03 02 2010 tehuang.liu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * For TX packets with STA_REC index = STA_REC_INDEX_NOT_FOUND, use TC5 -+ * -+ * 03 01 2010 tehuang.liu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * Fixed STA_REC index determination bug (fgIsValid shall be checked) -+ * -+ * 02 25 2010 tehuang.liu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * Refined function qmDetermineStaRecIndex() for BMCAST packets -+ * -+ * 02 25 2010 tehuang.liu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * Enabled multi-STA TX path with fairness -+ * -+ * 02 24 2010 tehuang.liu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * Enabled dynamically activating and deactivating STA_RECs -+ * -+ * 02 24 2010 tehuang.liu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * Added code for dynamic activating and deactivating STA_RECs. -+ * -+ * 01 13 2010 tehuang.liu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * Enabled the 802.1x path -+ * -+ * 01 13 2010 tehuang.liu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * Enabled the Burst_End Indication mechanism -+** \main\maintrunk.MT6620WiFiDriver_Prj\13 2009-12-14 15:01:37 GMT MTK02468 -+** Fixed casting for qmAddRxBaEntry() -+** \main\maintrunk.MT6620WiFiDriver_Prj\12 2009-12-10 16:51:03 GMT mtk02752 -+** remove SD1_SD3.. flag -+** \main\maintrunk.MT6620WiFiDriver_Prj\11 2009-12-09 14:07:25 GMT MTK02468 -+** Added RX buffer reordering functions -+** \main\maintrunk.MT6620WiFiDriver_Prj\10 2009-12-04 13:34:16 GMT MTK02468 -+** Modified Flush Queue function to let queues be reinitialized -+** \main\maintrunk.MT6620WiFiDriver_Prj\9 2009-12-04 13:18:25 GMT MTK02468 -+** Added flushing per-Type queues code -+** \main\maintrunk.MT6620WiFiDriver_Prj\8 2009-12-02 23:39:49 GMT MTK02468 -+** Added Debug msgs and fixed incorrect assert -+** \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-11-26 23:50:27 GMT MTK02468 -+** Bug fixing (qmDequeueTxPackets local variable initialization) -+** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-11-26 09:39:25 GMT mtk02752 -+** correct and surpress PREfast warning -+** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-11-23 22:10:55 GMT mtk02468 -+** Used SD1_SD3_DATAPATH_INTEGRATION -+** \main\maintrunk.MT6620WiFiDriver_Prj\1 2009-11-23 22:02:30 GMT mtk02468 -+** Initial version -+** -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "precomp.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+OS_SYSTIME g_arMissTimeout[CFG_STA_REC_NUM][CFG_RX_MAX_BA_TID_NUM]; -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+#if ARP_MONITER_ENABLE -+static UINT_16 arpMoniter; -+static UINT_8 apIp[4]; -+#endif -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+static inline VOID qmDetermineStaRecIndex(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); -+ -+static inline VOID -+qmDequeueTxPacketsFromPerStaQueues(IN P_ADAPTER_T prAdapter, -+ OUT P_QUE_T prQue, -+ IN UINT_8 ucTC, IN UINT_8 ucCurrentAvailableQuota, IN UINT_8 ucTotalQuota); -+ -+static inline VOID -+qmDequeueTxPacketsFromPerTypeQueues(IN P_ADAPTER_T prAdapter, OUT P_QUE_T prQue, IN UINT_8 ucTC, IN UINT_8 ucMaxNum); -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Init Queue Management for TX -+* -+* \param[in] (none) -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID qmInit(IN P_ADAPTER_T prAdapter) -+{ -+ UINT_32 u4QueArrayIdx; -+ UINT_32 i; -+ -+ P_QUE_MGT_T prQM = &prAdapter->rQM; -+ -+ /* DbgPrint("QM: Enter qmInit()\n"); */ -+#if CFG_SUPPORT_QOS -+ prAdapter->rWifiVar.fgSupportQoS = TRUE; -+#else -+ prAdapter->rWifiVar.fgSupportQoS = FALSE; -+#endif -+ -+#if CFG_SUPPORT_AMPDU_RX -+ prAdapter->rWifiVar.fgSupportAmpduRx = TRUE; -+#else -+ prAdapter->rWifiVar.fgSupportAmpduRx = FALSE; -+#endif -+ -+#if CFG_SUPPORT_AMPDU_TX -+ prAdapter->rWifiVar.fgSupportAmpduTx = TRUE; -+#else -+ prAdapter->rWifiVar.fgSupportAmpduTx = FALSE; -+#endif -+ -+#if CFG_SUPPORT_TSPEC -+ prAdapter->rWifiVar.fgSupportTspec = TRUE; -+#else -+ prAdapter->rWifiVar.fgSupportTspec = FALSE; -+#endif -+ -+#if CFG_SUPPORT_UAPSD -+ prAdapter->rWifiVar.fgSupportUAPSD = TRUE; -+#else -+ prAdapter->rWifiVar.fgSupportUAPSD = FALSE; -+#endif -+ -+#if CFG_SUPPORT_UL_PSMP -+ prAdapter->rWifiVar.fgSupportULPSMP = TRUE; -+#else -+ prAdapter->rWifiVar.fgSupportULPSMP = FALSE; -+#endif -+ -+#if CFG_SUPPORT_RX_SGI -+ prAdapter->rWifiVar.u8SupportRxSgi20 = 0; -+ prAdapter->rWifiVar.u8SupportRxSgi40 = 0; -+#else -+ prAdapter->rWifiVar.u8SupportRxSgi20 = 2; -+ prAdapter->rWifiVar.u8SupportRxSgi40 = 2; -+#endif -+ -+#if CFG_SUPPORT_RX_HT_GF -+ prAdapter->rWifiVar.u8SupportRxGf = 0; -+#else -+ prAdapter->rWifiVar.u8SupportRxGf = 2; -+#endif -+ -+ /* 4 <2> Initialize other TX queues (queues not in STA_RECs) */ -+ for (u4QueArrayIdx = 0; u4QueArrayIdx < NUM_OF_PER_TYPE_TX_QUEUES; u4QueArrayIdx++) -+ QUEUE_INITIALIZE(&(prQM->arTxQueue[u4QueArrayIdx])); -+ -+ /* 4 <3> Initialize the RX BA table and RX queues */ -+ /* Initialize the RX Reordering Parameters and Queues */ -+ for (u4QueArrayIdx = 0; u4QueArrayIdx < CFG_NUM_OF_RX_BA_AGREEMENTS; u4QueArrayIdx++) { -+ prQM->arRxBaTable[u4QueArrayIdx].fgIsValid = FALSE; -+ QUEUE_INITIALIZE(&(prQM->arRxBaTable[u4QueArrayIdx].rReOrderQue)); -+ prQM->arRxBaTable[u4QueArrayIdx].u2WinStart = 0xFFFF; -+ prQM->arRxBaTable[u4QueArrayIdx].u2WinEnd = 0xFFFF; -+ -+ prQM->arRxBaTable[u4QueArrayIdx].fgIsWaitingForPktWithSsn = FALSE; -+ -+ } -+ prQM->ucRxBaCount = 0; -+ -+ kalMemSet(&g_arMissTimeout, 0, sizeof(g_arMissTimeout)); -+ -+#if QM_ADAPTIVE_TC_RESOURCE_CTRL -+ /* 4 <4> Initialize TC resource control variables */ -+ for (i = 0; i < TC_NUM; i++) -+ prQM->au4AverageQueLen[i] = 0; -+ prQM->u4TimeToAdjustTcResource = QM_INIT_TIME_TO_ADJUST_TC_RSC; -+ prQM->u4TimeToUpdateQueLen = QM_INIT_TIME_TO_UPDATE_QUE_LEN; -+ prQM->u4TxNumOfVi = 0; -+ prQM->u4TxNumOfVo = 0; -+ -+/* ASSERT(prQM->u4TimeToAdjust && prQM->u4TimeToUpdateQueLen); */ -+ -+ /* 1 20 1 1 4 1 */ -+ prQM->au4CurrentTcResource[TC0_INDEX] = NIC_TX_BUFF_COUNT_TC0; -+ prQM->au4CurrentTcResource[TC1_INDEX] = NIC_TX_BUFF_COUNT_TC1; -+ prQM->au4CurrentTcResource[TC2_INDEX] = NIC_TX_BUFF_COUNT_TC2; -+ prQM->au4CurrentTcResource[TC3_INDEX] = NIC_TX_BUFF_COUNT_TC3; -+ prQM->au4CurrentTcResource[TC4_INDEX] = NIC_TX_BUFF_COUNT_TC4; /* Not adjustable (TX port 1) */ -+ prQM->au4CurrentTcResource[TC5_INDEX] = NIC_TX_BUFF_COUNT_TC5; -+ DBGLOG(QM, TRACE, "QM: NIC_TX_BUFF_COUNT_TC0 = %d\n", NIC_TX_BUFF_COUNT_TC0); -+ DBGLOG(QM, TRACE, "QM: NIC_TX_BUFF_COUNT_TC1 = %d\n", NIC_TX_BUFF_COUNT_TC1); -+ DBGLOG(QM, TRACE, "QM: NIC_TX_BUFF_COUNT_TC2 = %d\n", NIC_TX_BUFF_COUNT_TC2); -+ DBGLOG(QM, TRACE, "QM: NIC_TX_BUFF_COUNT_TC3 = %d\n", NIC_TX_BUFF_COUNT_TC3); -+ DBGLOG(QM, TRACE, "QM: NIC_TX_BUFF_COUNT_TC4 = %d\n", NIC_TX_BUFF_COUNT_TC4); -+ DBGLOG(QM, TRACE, "QM: NIC_TX_BUFF_COUNT_TC5 = %d\n", NIC_TX_BUFF_COUNT_TC5); -+ -+ /* 1 1 1 1 2 1 */ -+ prQM->au4MinReservedTcResource[TC0_INDEX] = QM_MIN_RESERVED_TC0_RESOURCE; -+ prQM->au4MinReservedTcResource[TC1_INDEX] = QM_MIN_RESERVED_TC1_RESOURCE; -+ prQM->au4MinReservedTcResource[TC2_INDEX] = QM_MIN_RESERVED_TC2_RESOURCE; -+ prQM->au4MinReservedTcResource[TC3_INDEX] = QM_MIN_RESERVED_TC3_RESOURCE; -+ prQM->au4MinReservedTcResource[TC4_INDEX] = QM_MIN_RESERVED_TC4_RESOURCE; /* Not adjustable (TX port 1) */ -+ prQM->au4MinReservedTcResource[TC5_INDEX] = QM_MIN_RESERVED_TC5_RESOURCE; -+ -+ /* 4 4 6 6 2 4 */ -+ prQM->au4GuaranteedTcResource[TC0_INDEX] = QM_GUARANTEED_TC0_RESOURCE; -+ prQM->au4GuaranteedTcResource[TC1_INDEX] = QM_GUARANTEED_TC1_RESOURCE; -+ prQM->au4GuaranteedTcResource[TC2_INDEX] = QM_GUARANTEED_TC2_RESOURCE; -+ prQM->au4GuaranteedTcResource[TC3_INDEX] = QM_GUARANTEED_TC3_RESOURCE; -+ prQM->au4GuaranteedTcResource[TC4_INDEX] = QM_GUARANTEED_TC4_RESOURCE; -+ prQM->au4GuaranteedTcResource[TC5_INDEX] = QM_GUARANTEED_TC5_RESOURCE; -+ -+ prQM->fgTcResourcePostAnnealing = FALSE; -+ -+ ASSERT(QM_INITIAL_RESIDUAL_TC_RESOURCE < 64); -+#endif -+ -+#if QM_TEST_MODE -+ prQM->u4PktCount = 0; -+ -+#if QM_TEST_FAIR_FORWARDING -+ -+ prQM->u4CurrentStaRecIndexToEnqueue = 0; -+ { -+ UINT_8 aucMacAddr[MAC_ADDR_LEN]; -+ P_STA_RECORD_T prStaRec; -+ -+ /* Irrelevant in case this STA is an AIS AP (see qmDetermineStaRecIndex()) */ -+ aucMacAddr[0] = 0x11; -+ aucMacAddr[1] = 0x22; -+ aucMacAddr[2] = 0xAA; -+ aucMacAddr[3] = 0xBB; -+ aucMacAddr[4] = 0xCC; -+ aucMacAddr[5] = 0xDD; -+ -+ prStaRec = &prAdapter->arStaRec[1]; -+ ASSERT(prStaRec); -+ -+ prStaRec->fgIsValid = TRUE; -+ prStaRec->fgIsQoS = TRUE; -+ prStaRec->fgIsInPS = FALSE; -+ prStaRec->ucPsSessionID = 0xFF; -+ prStaRec->ucNetTypeIndex = NETWORK_TYPE_AIS_INDEX; -+ prStaRec->fgIsAp = TRUE; -+ COPY_MAC_ADDR((prStaRec)->aucMacAddr, aucMacAddr); -+ -+ } -+ -+#endif -+ -+#endif -+ -+#if QM_FORWARDING_FAIRNESS -+ { -+ UINT_32 i; -+ -+ for (i = 0; i < NUM_OF_PER_STA_TX_QUEUES; i++) { -+ prQM->au4ForwardCount[i] = 0; -+ prQM->au4HeadStaRecIndex[i] = 0; -+ } -+ } -+#endif -+ -+#if QM_TC_RESOURCE_EMPTY_COUNTER -+ kalMemZero(prQM->au4QmTcResourceEmptyCounter, sizeof(prQM->au4QmTcResourceEmptyCounter)); -+#endif -+ -+} -+ -+#if QM_TEST_MODE -+VOID qmTestCases(IN P_ADAPTER_T prAdapter) -+{ -+ P_QUE_MGT_T prQM = &prAdapter->rQM; -+ -+ DbgPrint("QM: ** TEST MODE **\n"); -+ -+ if (QM_TEST_STA_REC_DETERMINATION) { -+ if (prAdapter->arStaRec[0].fgIsValid) { -+ prAdapter->arStaRec[0].fgIsValid = FALSE; -+ DbgPrint("QM: (Test) Deactivate STA_REC[0]\n"); -+ } else { -+ prAdapter->arStaRec[0].fgIsValid = TRUE; -+ DbgPrint("QM: (Test) Activate STA_REC[0]\n"); -+ } -+ } -+ -+ if (QM_TEST_STA_REC_DEACTIVATION) { -+ /* Note that QM_STA_REC_HARD_CODING shall be set to 1 for this test */ -+ -+ if (prAdapter->arStaRec[0].fgIsValid) { -+ -+ DbgPrint("QM: (Test) Deactivate STA_REC[0]\n"); -+ qmDeactivateStaRec(prAdapter, 0); -+ } else { -+ -+ UINT_8 aucMacAddr[MAC_ADDR_LEN]; -+ -+ /* Irrelevant in case this STA is an AIS AP (see qmDetermineStaRecIndex()) */ -+ aucMacAddr[0] = 0x11; -+ aucMacAddr[1] = 0x22; -+ aucMacAddr[2] = 0xAA; -+ aucMacAddr[3] = 0xBB; -+ aucMacAddr[4] = 0xCC; -+ aucMacAddr[5] = 0xDD; -+ -+ DbgPrint("QM: (Test) Activate STA_REC[0]\n"); -+ qmActivateStaRec(prAdapter, /* Adapter pointer */ -+ 0, /* STA_REC index from FW */ -+ TRUE, /* fgIsQoS */ -+ NETWORK_TYPE_AIS_INDEX, /* Network type */ -+ TRUE, /* fgIsAp */ -+ aucMacAddr /* MAC address */ -+ ); -+ } -+ } -+ -+ if (QM_TEST_FAIR_FORWARDING) { -+ if (prAdapter->arStaRec[1].fgIsValid) { -+ prQM->u4CurrentStaRecIndexToEnqueue++; -+ prQM->u4CurrentStaRecIndexToEnqueue %= 2; -+ DbgPrint("QM: (Test) Switch to STA_REC[%u]\n", prQM->u4CurrentStaRecIndexToEnqueue); -+ } -+ } -+ -+} -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Activate a STA_REC -+* -+* \param[in] prAdapter Pointer to the Adapter instance -+* \param[in] u4StaRecIdx The index of the STA_REC -+* \param[in] fgIsQoS Set to TRUE if this is a QoS STA -+* \param[in] pucMacAddr The MAC address of the STA -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID qmActivateStaRec(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prStaRec) -+{ -+ -+ /* 4 <1> Deactivate first */ -+ ASSERT(prStaRec); -+ -+ if (prStaRec->fgIsValid) { /* The STA_REC has been activated */ -+ DBGLOG(QM, WARN, "QM: (WARNING) Activating a STA_REC which has been activated\n"); -+ DBGLOG(QM, WARN, "QM: (WARNING) Deactivating a STA_REC before re-activating\n"); -+ /* To flush TX/RX queues and del RX BA agreements */ -+ qmDeactivateStaRec(prAdapter, prStaRec->ucIndex); -+ } -+ /* 4 <2> Activate the STA_REC */ -+ /* Init the STA_REC */ -+ prStaRec->fgIsValid = TRUE; -+ prStaRec->fgIsInPS = FALSE; -+ prStaRec->ucPsSessionID = 0xFF; -+ prStaRec->fgIsAp = (IS_AP_STA(prStaRec)) ? TRUE : FALSE; -+ -+ /* Done in qmInit() or qmDeactivateStaRec() */ -+#if 0 -+ /* At the beginning, no RX BA agreements have been established */ -+ for (i = 0; i < CFG_RX_MAX_BA_TID_NUM; i++) -+ (prStaRec->aprRxReorderParamRefTbl)[i] = NULL; -+#endif -+ -+ DBGLOG(QM, TRACE, "QM: +STA[%u]\n", (UINT_32) prStaRec->ucIndex); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Deactivate a STA_REC -+* -+* \param[in] prAdapter Pointer to the Adapter instance -+* \param[in] u4StaRecIdx The index of the STA_REC -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID qmDeactivateStaRec(IN P_ADAPTER_T prAdapter, IN UINT_32 u4StaRecIdx) -+{ -+ P_STA_RECORD_T prStaRec; -+ UINT_32 i; -+ P_MSDU_INFO_T prFlushedTxPacketList = NULL; -+ -+ ASSERT(u4StaRecIdx < CFG_NUM_OF_STA_RECORD); -+ -+ prStaRec = &prAdapter->arStaRec[u4StaRecIdx]; -+ ASSERT(prStaRec); -+ -+ /* 4<1> Flush TX queues */ -+ prFlushedTxPacketList = qmFlushStaTxQueues(prAdapter, u4StaRecIdx); -+ -+ if (prFlushedTxPacketList) -+ wlanProcessQueuedMsduInfo(prAdapter, prFlushedTxPacketList); -+ /* 4 <2> Flush RX queues and delete RX BA agreements */ -+ for (i = 0; i < CFG_RX_MAX_BA_TID_NUM; i++) { -+ /* Delete the RX BA entry with TID = i */ -+ qmDelRxBaEntry(prAdapter, (UINT_8) u4StaRecIdx, (UINT_8) i, FALSE); -+ } -+ -+ /* 4 <3> Deactivate the STA_REC */ -+ prStaRec->fgIsValid = FALSE; -+ prStaRec->fgIsInPS = FALSE; -+ -+ /* To reduce printk for IOT sta to connect all the time, */ -+ /* DBGLOG(QM, INFO, ("QM: -STA[%ld]\n", u4StaRecIdx)); */ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Deactivate a STA_REC -+* -+* \param[in] prAdapter Pointer to the Adapter instance -+* \param[in] u4StaRecIdx The index of the network -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+ -+VOID qmFreeAllByNetType(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx) -+{ -+ -+ P_QUE_MGT_T prQM; -+ P_QUE_T prQue; -+ QUE_T rNeedToFreeQue; -+ QUE_T rTempQue; -+ P_QUE_T prNeedToFreeQue; -+ P_QUE_T prTempQue; -+ P_MSDU_INFO_T prMsduInfo; -+ -+ prQM = &prAdapter->rQM; -+ prQue = &prQM->arTxQueue[TX_QUEUE_INDEX_BMCAST]; -+ -+ QUEUE_INITIALIZE(&rNeedToFreeQue); -+ QUEUE_INITIALIZE(&rTempQue); -+ -+ prNeedToFreeQue = &rNeedToFreeQue; -+ prTempQue = &rTempQue; -+ -+ QUEUE_MOVE_ALL(prTempQue, prQue); -+ -+ QUEUE_REMOVE_HEAD(prTempQue, prMsduInfo, P_MSDU_INFO_T); -+ while (prMsduInfo) { -+ -+ if (prMsduInfo->ucNetworkType == eNetworkTypeIdx) { -+ /* QUEUE_INSERT_TAIL */ -+ QUEUE_INSERT_TAIL(prNeedToFreeQue, (P_QUE_ENTRY_T) prMsduInfo); -+ } else { -+ /* QUEUE_INSERT_TAIL */ -+ QUEUE_INSERT_TAIL(prQue, (P_QUE_ENTRY_T) prMsduInfo); -+ } -+ -+ QUEUE_REMOVE_HEAD(prTempQue, prMsduInfo, P_MSDU_INFO_T); -+ } -+ if (QUEUE_IS_NOT_EMPTY(prNeedToFreeQue)) -+ wlanProcessQueuedMsduInfo(prAdapter, (P_MSDU_INFO_T) QUEUE_GET_HEAD(prNeedToFreeQue)); -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Flush all TX queues -+* -+* \param[in] (none) -+* -+* \return The flushed packets (in a list of MSDU_INFOs) -+*/ -+/*----------------------------------------------------------------------------*/ -+P_MSDU_INFO_T qmFlushTxQueues(IN P_ADAPTER_T prAdapter) -+{ -+ UINT_8 ucStaArrayIdx; -+ UINT_8 ucQueArrayIdx; -+ -+ P_MSDU_INFO_T prMsduInfoListHead; -+ P_MSDU_INFO_T prMsduInfoListTail; -+ -+ P_QUE_MGT_T prQM = &prAdapter->rQM; -+ -+ DBGLOG(QM, TRACE, "QM: Enter qmFlushTxQueues()\n"); -+ -+ prMsduInfoListHead = NULL; -+ prMsduInfoListTail = NULL; -+ -+ /* Concatenate all MSDU_INFOs in per-STA queues */ -+ for (ucStaArrayIdx = 0; ucStaArrayIdx < CFG_NUM_OF_STA_RECORD; ucStaArrayIdx++) { -+ -+ /* Always check each STA_REC when flushing packets no matter it is inactive or active */ -+#if 0 -+ if (!prAdapter->arStaRec[ucStaArrayIdx].fgIsValid) -+ continue; /* Continue to check the next STA_REC */ -+#endif -+ -+ for (ucQueArrayIdx = 0; ucQueArrayIdx < NUM_OF_PER_STA_TX_QUEUES; ucQueArrayIdx++) { -+ if (QUEUE_IS_EMPTY(&(prAdapter->arStaRec[ucStaArrayIdx].arTxQueue[ucQueArrayIdx]))) -+ continue; /* Continue to check the next TX queue of the same STA */ -+ -+ if (!prMsduInfoListHead) { -+ -+ /* The first MSDU_INFO is found */ -+ prMsduInfoListHead = (P_MSDU_INFO_T) -+ QUEUE_GET_HEAD(&prAdapter->arStaRec[ucStaArrayIdx].arTxQueue[ucQueArrayIdx]); -+ prMsduInfoListTail = (P_MSDU_INFO_T) -+ QUEUE_GET_TAIL(&prAdapter->arStaRec[ucStaArrayIdx].arTxQueue[ucQueArrayIdx]); -+ } else { -+ /* Concatenate the MSDU_INFO list with the existing list */ -+ QM_TX_SET_NEXT_MSDU_INFO(prMsduInfoListTail, -+ QUEUE_GET_HEAD(&prAdapter-> -+ arStaRec[ucStaArrayIdx].arTxQueue -+ [ucQueArrayIdx])); -+ -+ prMsduInfoListTail = (P_MSDU_INFO_T) -+ QUEUE_GET_TAIL(&prAdapter->arStaRec[ucStaArrayIdx].arTxQueue[ucQueArrayIdx]); -+ } -+ -+ QUEUE_INITIALIZE(&prAdapter->arStaRec[ucStaArrayIdx].arTxQueue[ucQueArrayIdx]); -+ } -+ } -+ -+ /* Flush per-Type queues */ -+ for (ucQueArrayIdx = 0; ucQueArrayIdx < NUM_OF_PER_TYPE_TX_QUEUES; ucQueArrayIdx++) { -+ -+ if (QUEUE_IS_EMPTY(&(prQM->arTxQueue[ucQueArrayIdx]))) -+ continue; /* Continue to check the next TX queue of the same STA */ -+ -+ if (!prMsduInfoListHead) { -+ -+ /* The first MSDU_INFO is found */ -+ prMsduInfoListHead = (P_MSDU_INFO_T) -+ QUEUE_GET_HEAD(&prQM->arTxQueue[ucQueArrayIdx]); -+ prMsduInfoListTail = (P_MSDU_INFO_T) -+ QUEUE_GET_TAIL(&prQM->arTxQueue[ucQueArrayIdx]); -+ } else { -+ /* Concatenate the MSDU_INFO list with the existing list */ -+ QM_TX_SET_NEXT_MSDU_INFO(prMsduInfoListTail, QUEUE_GET_HEAD(&prQM->arTxQueue[ucQueArrayIdx])); -+ -+ prMsduInfoListTail = (P_MSDU_INFO_T) -+ QUEUE_GET_TAIL(&prQM->arTxQueue[ucQueArrayIdx]); -+ } -+ -+ QUEUE_INITIALIZE(&prQM->arTxQueue[ucQueArrayIdx]); -+ -+ } -+ -+ if (prMsduInfoListTail) { -+ /* Terminate the MSDU_INFO list with a NULL pointer */ -+ QM_TX_SET_NEXT_MSDU_INFO(prMsduInfoListTail, NULL); -+ } -+ -+ return prMsduInfoListHead; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Flush TX packets for a particular STA -+* -+* \param[in] u4StaRecIdx STA_REC index -+* -+* \return The flushed packets (in a list of MSDU_INFOs) -+*/ -+/*----------------------------------------------------------------------------*/ -+P_MSDU_INFO_T qmFlushStaTxQueues(IN P_ADAPTER_T prAdapter, IN UINT_32 u4StaRecIdx) -+{ -+ UINT_8 ucQueArrayIdx; -+ P_MSDU_INFO_T prMsduInfoListHead; -+ P_MSDU_INFO_T prMsduInfoListTail; -+ P_STA_RECORD_T prStaRec; -+ -+ /* To reduce printk for IOT sta to connect all the time, */ -+ /* DBGLOG(QM, TRACE, ("QM: Enter qmFlushStaTxQueues(%ld)\n", u4StaRecIdx)); */ -+ -+ ASSERT(u4StaRecIdx < CFG_NUM_OF_STA_RECORD); -+ -+ prMsduInfoListHead = NULL; -+ prMsduInfoListTail = NULL; -+ -+ prStaRec = &prAdapter->arStaRec[u4StaRecIdx]; -+ ASSERT(prStaRec); -+ -+ /* No matter whether this is an activated STA_REC, do flush */ -+#if 0 -+ if (!prStaRec->fgIsValid) -+ return NULL; -+#endif -+ -+ /* Concatenate all MSDU_INFOs in TX queues of this STA_REC */ -+ for (ucQueArrayIdx = 0; ucQueArrayIdx < NUM_OF_PER_STA_TX_QUEUES; ucQueArrayIdx++) { -+ if (QUEUE_IS_EMPTY(&(prStaRec->arTxQueue[ucQueArrayIdx]))) -+ continue; -+ -+ if (!prMsduInfoListHead) { -+ /* The first MSDU_INFO is found */ -+ prMsduInfoListHead = (P_MSDU_INFO_T) -+ QUEUE_GET_HEAD(&prStaRec->arTxQueue[ucQueArrayIdx]); -+ prMsduInfoListTail = (P_MSDU_INFO_T) -+ QUEUE_GET_TAIL(&prStaRec->arTxQueue[ucQueArrayIdx]); -+ } else { -+ /* Concatenate the MSDU_INFO list with the existing list */ -+ QM_TX_SET_NEXT_MSDU_INFO(prMsduInfoListTail, -+ QUEUE_GET_HEAD(&prStaRec->arTxQueue[ucQueArrayIdx])); -+ -+ prMsduInfoListTail = (P_MSDU_INFO_T) QUEUE_GET_TAIL(&prStaRec->arTxQueue[ucQueArrayIdx]); -+ } -+ -+ QUEUE_INITIALIZE(&prStaRec->arTxQueue[ucQueArrayIdx]); -+ -+ } -+ -+#if 0 -+ if (prMsduInfoListTail) { -+ /* Terminate the MSDU_INFO list with a NULL pointer */ -+ QM_TX_SET_NEXT_MSDU_INFO(prMsduInfoListTail, nicGetPendingStaMMPDU(prAdapter, (UINT_8) u4StaRecIdx)); -+ } else { -+ prMsduInfoListHead = nicGetPendingStaMMPDU(prAdapter, (UINT_8) u4StaRecIdx); -+ } -+#endif -+ -+ return prMsduInfoListHead; -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Flush RX packets -+* -+* \param[in] (none) -+* -+* \return The flushed packets (in a list of SW_RFBs) -+*/ -+/*----------------------------------------------------------------------------*/ -+P_SW_RFB_T qmFlushRxQueues(IN P_ADAPTER_T prAdapter) -+{ -+ UINT_32 i; -+ P_SW_RFB_T prSwRfbListHead; -+ P_SW_RFB_T prSwRfbListTail; -+ P_QUE_MGT_T prQM = &prAdapter->rQM; -+ -+ prSwRfbListHead = prSwRfbListTail = NULL; -+ -+ DBGLOG(QM, TRACE, "QM: Enter qmFlushRxQueues()\n"); -+ -+ for (i = 0; i < CFG_NUM_OF_RX_BA_AGREEMENTS; i++) { -+ if (QUEUE_IS_NOT_EMPTY(&(prQM->arRxBaTable[i].rReOrderQue))) { -+ if (!prSwRfbListHead) { -+ -+ /* The first MSDU_INFO is found */ -+ prSwRfbListHead = (P_SW_RFB_T) -+ QUEUE_GET_HEAD(&(prQM->arRxBaTable[i].rReOrderQue)); -+ prSwRfbListTail = (P_SW_RFB_T) -+ QUEUE_GET_TAIL(&(prQM->arRxBaTable[i].rReOrderQue)); -+ } else { -+ /* Concatenate the MSDU_INFO list with the existing list */ -+ QM_TX_SET_NEXT_MSDU_INFO(prSwRfbListTail, -+ QUEUE_GET_HEAD(&(prQM->arRxBaTable[i].rReOrderQue))); -+ -+ prSwRfbListTail = (P_SW_RFB_T) -+ QUEUE_GET_TAIL(&(prQM->arRxBaTable[i].rReOrderQue)); -+ } -+ -+ QUEUE_INITIALIZE(&(prQM->arRxBaTable[i].rReOrderQue)); -+ -+ } else { -+ continue; -+ } -+ } -+ -+ if (prSwRfbListTail) { -+ /* Terminate the MSDU_INFO list with a NULL pointer */ -+ QM_TX_SET_NEXT_SW_RFB(prSwRfbListTail, NULL); -+ } -+ return prSwRfbListHead; -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Flush RX packets with respect to a particular STA -+* -+* \param[in] u4StaRecIdx STA_REC index -+* \param[in] u4Tid TID -+* -+* \return The flushed packets (in a list of SW_RFBs) -+*/ -+/*----------------------------------------------------------------------------*/ -+P_SW_RFB_T qmFlushStaRxQueue(IN P_ADAPTER_T prAdapter, IN UINT_32 u4StaRecIdx, IN UINT_32 u4Tid) -+{ -+ /* UINT_32 i; */ -+ P_SW_RFB_T prSwRfbListHead; -+ P_SW_RFB_T prSwRfbListTail; -+ P_RX_BA_ENTRY_T prReorderQueParm; -+ P_STA_RECORD_T prStaRec; -+ -+ DBGLOG(QM, TRACE, "QM: Enter qmFlushStaRxQueues(%u)\n", u4StaRecIdx); -+ -+ prSwRfbListHead = prSwRfbListTail = NULL; -+ -+ prStaRec = &prAdapter->arStaRec[u4StaRecIdx]; -+ ASSERT(prStaRec); -+ -+ /* No matter whether this is an activated STA_REC, do flush */ -+#if 0 -+ if (!prStaRec->fgIsValid) -+ return NULL; -+#endif -+ -+ /* Obtain the RX BA Entry pointer */ -+ prReorderQueParm = ((prStaRec->aprRxReorderParamRefTbl)[u4Tid]); -+ -+ /* Note: For each queued packet, prCurrSwRfb->eDst equals RX_PKT_DESTINATION_HOST */ -+ if (prReorderQueParm) { -+ -+ if (QUEUE_IS_NOT_EMPTY(&(prReorderQueParm->rReOrderQue))) { -+ -+ prSwRfbListHead = (P_SW_RFB_T) -+ QUEUE_GET_HEAD(&(prReorderQueParm->rReOrderQue)); -+ prSwRfbListTail = (P_SW_RFB_T) -+ QUEUE_GET_TAIL(&(prReorderQueParm->rReOrderQue)); -+ -+ QUEUE_INITIALIZE(&(prReorderQueParm->rReOrderQue)); -+ -+ } -+ } -+ -+ if (prSwRfbListTail) { -+ /* Terminate the MSDU_INFO list with a NULL pointer */ -+ QM_TX_SET_NEXT_SW_RFB(prSwRfbListTail, NULL); -+ } -+ return prSwRfbListHead; -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Enqueue TX packets -+* -+* \param[in] prMsduInfoListHead Pointer to the list of TX packets -+* -+* \return The freed packets, which are not enqueued -+*/ -+/*----------------------------------------------------------------------------*/ -+P_MSDU_INFO_T qmEnqueueTxPackets(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfoListHead) -+{ -+ P_MSDU_INFO_T prMsduInfoReleaseList; -+ P_MSDU_INFO_T prCurrentMsduInfo; -+ P_MSDU_INFO_T prNextMsduInfo; -+ -+ P_STA_RECORD_T prStaRec; -+ QUE_T rNotEnqueuedQue; -+ P_QUE_T prTxQue = &rNotEnqueuedQue; -+ -+ UINT_8 ucPacketType; -+ UINT_8 ucTC; -+ P_QUE_MGT_T prQM = &prAdapter->rQM; -+ UINT_8 aucNextUP[WMM_AC_INDEX_NUM] = { 1 /* BEtoBK */ , 1 /*na */ , 0 /*VItoBE */ , 4 /*VOtoVI */ }; -+ -+ DBGLOG(QM, LOUD, "Enter qmEnqueueTxPackets\n"); -+ -+ ASSERT(prMsduInfoListHead); -+ -+#if QM_ADAPTIVE_TC_RESOURCE_CTRL -+ { -+ /* UINT_32 i; */ -+ /* 4 <0> Update TC resource control related variables */ -+ /* Keep track of the queue length */ -+ if (--prQM->u4TimeToUpdateQueLen == 0) { /* -- only here */ -+ prQM->u4TimeToUpdateQueLen = QM_INIT_TIME_TO_UPDATE_QUE_LEN; -+ qmUpdateAverageTxQueLen(prAdapter); -+ } -+ } -+#endif -+ -+ /* Push TX packets into STA_REC (for UNICAST) or prAdapter->rQM (for BMCAST) */ -+ prStaRec = NULL; -+ prMsduInfoReleaseList = NULL; -+ prCurrentMsduInfo = NULL; -+ QUEUE_INITIALIZE(&rNotEnqueuedQue); -+ prNextMsduInfo = prMsduInfoListHead; -+ -+ do { -+ P_BSS_INFO_T prBssInfo; -+ BOOLEAN fgCheckACMAgain; -+ ENUM_WMM_ACI_T eAci = WMM_AC_BE_INDEX; -+ -+ prCurrentMsduInfo = prNextMsduInfo; -+ prNextMsduInfo = QM_TX_GET_NEXT_MSDU_INFO(prCurrentMsduInfo); -+ ucTC = TC1_INDEX; -+ -+ /* 4 <1> Lookup the STA_REC index */ -+ /* The ucStaRecIndex will be set in this function */ -+ qmDetermineStaRecIndex(prAdapter, prCurrentMsduInfo); -+ ucPacketType = HIF_TX_PACKET_TYPE_DATA; -+ -+ STATS_ENV_REPORT_DETECT(prAdapter, prCurrentMsduInfo->ucStaRecIndex); -+ -+ DBGLOG(QM, LOUD, "***** ucStaRecIndex = %d *****\n", prCurrentMsduInfo->ucStaRecIndex); -+ -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prCurrentMsduInfo->ucNetworkType]); -+ -+#if (CONF_HIF_LOOPBACK_AUTO == 0) -+ if (IS_NET_ACTIVE(prAdapter, prCurrentMsduInfo->ucNetworkType)) { -+#else -+ /* force to send the loopback test packet */ -+ if (1) { -+ SET_NET_ACTIVE(prAdapter, prCurrentMsduInfo->ucNetworkType); -+ prCurrentMsduInfo->ucStaRecIndex = STA_REC_INDEX_BMCAST; -+ ucPacketType = HIF_TX_PKT_TYPE_HIF_LOOPBACK; -+#endif /* End of CONF_HIF_LOOPBACK_AUTO */ -+ -+ switch (prCurrentMsduInfo->ucStaRecIndex) { -+ case STA_REC_INDEX_BMCAST: -+ prTxQue = &prQM->arTxQueue[TX_QUEUE_INDEX_BMCAST]; -+ ucTC = TC5_INDEX; -+#if 0 -+ if (prCurrentMsduInfo->ucNetworkType == NETWORK_TYPE_P2P_INDEX -+ && prCurrentMsduInfo->eSrc != TX_PACKET_MGMT) { -+ if (LINK_IS_EMPTY -+ (&prAdapter->rWifiVar. -+ arBssInfo[NETWORK_TYPE_P2P_INDEX].rStaRecOfClientList)) { -+ prTxQue = &rNotEnqueuedQue; -+ TX_INC_CNT(&prAdapter->rTxCtrl, TX_AP_BORADCAST_DROP); -+ } -+ } -+#endif -+ -+ QM_DBG_CNT_INC(prQM, QM_DBG_CNT_23); -+ break; -+ -+ case STA_REC_INDEX_NOT_FOUND: -+ ucTC = TC5_INDEX; -+ -+ if (prCurrentMsduInfo->eSrc == TX_PACKET_FORWARDING) { -+ -+ /* if the packet is the forward type. the packet should be freed */ -+ DBGLOG(QM, TRACE, "Forwarding packet but Sta is STA_REC_INDEX_NOT_FOUND\n"); -+ /* prTxQue = &rNotEnqueuedQue; */ -+ } -+ prTxQue = &prQM->arTxQueue[TX_QUEUE_INDEX_NO_STA_REC]; -+ QM_DBG_CNT_INC(prQM, QM_DBG_CNT_24); -+ -+ break; -+ -+ default: -+ prStaRec = QM_GET_STA_REC_PTR_FROM_INDEX(prAdapter, prCurrentMsduInfo->ucStaRecIndex); -+ -+ if (!prStaRec) { -+ DBGLOG(QM, ERROR, "prStaRec is NULL\n"); -+ break; -+ } -+ ASSERT(prStaRec->fgIsValid); -+ -+ if (prCurrentMsduInfo->ucUserPriority < 8) { -+ QM_DBG_CNT_INC(prQM, prCurrentMsduInfo->ucUserPriority + 15); -+ /* QM_DBG_CNT_15 *//* QM_DBG_CNT_16 *//* QM_DBG_CNT_17 *//* QM_DBG_CNT_18 */ -+ /* QM_DBG_CNT_19 *//* QM_DBG_CNT_20 *//* QM_DBG_CNT_21 *//* QM_DBG_CNT_22 */ -+ } -+ -+ eAci = WMM_AC_BE_INDEX; -+ do { -+ fgCheckACMAgain = FALSE; -+ if (!prStaRec->fgIsQoS) { -+ prTxQue = &prStaRec->arTxQueue[TX_QUEUE_INDEX_AC1]; -+ ucTC = TC1_INDEX; -+ break; -+ } -+ -+ switch (prCurrentMsduInfo->ucUserPriority) { -+ case 1: -+ case 2: -+ prTxQue = &prStaRec->arTxQueue[TX_QUEUE_INDEX_AC0]; -+ ucTC = TC0_INDEX; -+ eAci = WMM_AC_BK_INDEX; -+ break; -+ case 0: -+ case 3: -+ prTxQue = &prStaRec->arTxQueue[TX_QUEUE_INDEX_AC1]; -+ ucTC = TC1_INDEX; -+ eAci = WMM_AC_BE_INDEX; -+ break; -+ case 4: -+ case 5: -+ prTxQue = &prStaRec->arTxQueue[TX_QUEUE_INDEX_AC2]; -+ ucTC = TC2_INDEX; -+ eAci = WMM_AC_VI_INDEX; -+#if QM_ADAPTIVE_TC_RESOURCE_CTRL -+ prQM->u4TxNumOfVi++; -+#endif -+ break; -+ case 6: -+ case 7: -+ prTxQue = &prStaRec->arTxQueue[TX_QUEUE_INDEX_AC3]; -+ ucTC = TC3_INDEX; -+ eAci = WMM_AC_VO_INDEX; -+#if QM_ADAPTIVE_TC_RESOURCE_CTRL -+ prQM->u4TxNumOfVo++; -+#endif -+ break; -+ default: -+ prTxQue = &prStaRec->arTxQueue[TX_QUEUE_INDEX_AC1]; -+ ucTC = TC1_INDEX; -+ eAci = WMM_AC_BE_INDEX; -+ ASSERT(0); -+ break; -+ } -+ if (prBssInfo->arACQueParms[eAci].fgIsACMSet && eAci -+ != WMM_AC_BK_INDEX) { -+ prCurrentMsduInfo->ucUserPriority = aucNextUP[eAci]; -+ fgCheckACMAgain = TRUE; -+ } -+ } while (fgCheckACMAgain); -+ -+ /* LOG_FUNC ("QoS %u UP %u TC %u", */ -+ /* prStaRec->fgIsQoS,prCurrentMsduInfo->ucUserPriority, ucTC); */ -+ -+#if QM_ADAPTIVE_TC_RESOURCE_CTRL -+ /* -+ In TDLS or AP mode, peer maybe enter "sleep mode". -+ -+ If QM_INIT_TIME_TO_UPDATE_QUE_LEN = 60 when peer is in sleep mode, -+ we need to wait 60 * u4TimeToAdjustTcResource = 180 packets -+ u4TimeToAdjustTcResource = 3, -+ then we will adjust TC resouce for VI or VO. -+ -+ But in TDLS test case, the throughput is very low, only 0.8Mbps in 5.7, -+ we will to wait about 12 seconds to collect 180 packets. -+ but the test time is only 20 seconds. -+ */ -+ if ((prQM->u4TxNumOfVi == 10) || (prQM->u4TxNumOfVo == 10)) { -+ /* force to do TC resouce update */ -+ prQM->u4TimeToUpdateQueLen = QM_INIT_TIME_TO_UPDATE_QUE_LEN_MIN; -+ prQM->u4TimeToAdjustTcResource = 1; -+ } -+#endif -+#if ARP_MONITER_ENABLE -+ if (IS_STA_IN_AIS(prStaRec) && prCurrentMsduInfo->eSrc == TX_PACKET_OS) -+ qmDetectArpNoResponse(prAdapter, prCurrentMsduInfo); -+#endif -+ -+ break; /*default */ -+ } /* switch (prCurrentMsduInfo->ucStaRecIndex) */ -+ -+ if (prCurrentMsduInfo->eSrc == TX_PACKET_FORWARDING) { -+ if (prTxQue->u4NumElem > 32) { -+ DBGLOG(QM, WARN, -+ "Drop the Packet for full Tx queue (forwarding) Bss %u\n", -+ prCurrentMsduInfo->ucNetworkType); -+ prTxQue = &rNotEnqueuedQue; -+ TX_INC_CNT(&prAdapter->rTxCtrl, TX_FORWARD_OVERFLOW_DROP); -+ } -+ } -+ -+ } else { -+ -+ DBGLOG(QM, WARN, "Drop the Packet for inactive Bss %u\n", prCurrentMsduInfo->ucNetworkType); -+ QM_DBG_CNT_INC(prQM, QM_DBG_CNT_31); -+ prTxQue = &rNotEnqueuedQue; -+ TX_INC_CNT(&prAdapter->rTxCtrl, TX_INACTIVE_BSS_DROP); -+ } -+ -+ /* 4 <3> Fill the MSDU_INFO for constructing HIF TX header */ -+ -+ /* TODO: Fill MSDU_INFO according to the network type, -+ * EtherType, and STA status (for PS forwarding control). -+ */ -+ -+ /* Note that the Network Type Index and STA_REC index are determined in -+ * qmDetermineStaRecIndex(prCurrentMsduInfo). -+ */ -+ QM_TX_SET_MSDU_INFO_FOR_DATA_PACKET(prCurrentMsduInfo, /* MSDU_INFO ptr */ -+ ucTC, /* TC tag */ -+ ucPacketType, /* Packet Type */ -+ 0, /* Format ID */ -+ prCurrentMsduInfo->fgIs802_1x, /* Flag 802.1x */ -+ prCurrentMsduInfo->fgIs802_11, /* Flag 802.11 */ -+ 0, /* PAL LLH */ -+ 0, /* ACL SN */ -+ PS_FORWARDING_TYPE_NON_PS, /* PS Forwarding Type */ -+ 0 /* PS Session ID */ -+ ); -+ -+ /* 4 <4> Enqueue the packet to different AC queue (max 5 AC queues) */ -+ QUEUE_INSERT_TAIL(prTxQue, (P_QUE_ENTRY_T) prCurrentMsduInfo); -+ -+ if (prTxQue != &rNotEnqueuedQue) { -+ prQM->u4EnqeueuCounter++; -+ prQM->au4ResourceWantedCounter[ucTC]++; -+ } -+ if (prStaRec) -+ prStaRec->u4EnqeueuCounter++; -+ -+#if QM_TC_RESOURCE_EMPTY_COUNTER -+ { -+ P_TX_CTRL_T prTxCtrl = &prAdapter->rTxCtrl; -+ -+ if (prTxCtrl->rTc.aucFreeBufferCount[ucTC] == 0) { -+ prQM->au4QmTcResourceEmptyCounter[prCurrentMsduInfo->ucNetworkType][ucTC]++; -+ /* -+ DBGLOG(QM, TRACE, ("TC%d Q Empty Count: [%d]%ld\n", -+ ucTC, -+ prCurrentMsduInfo->ucNetworkType, -+ prQM->au4QmTcResourceEmptyCounter[prCurrentMsduInfo->ucNetworkType][ucTC])); -+ */ -+ } -+ -+ } -+#endif -+ -+#if QM_TEST_MODE -+ if (++prQM->u4PktCount == QM_TEST_TRIGGER_TX_COUNT) { -+ prQM->u4PktCount = 0; -+ qmTestCases(prAdapter); -+ } -+#endif -+ -+ DBGLOG(QM, LOUD, "Current queue length = %u\n", prTxQue->u4NumElem); -+ } while (prNextMsduInfo); -+ -+ if (QUEUE_IS_NOT_EMPTY(&rNotEnqueuedQue)) { -+ QM_TX_SET_NEXT_MSDU_INFO((P_MSDU_INFO_T) QUEUE_GET_TAIL(&rNotEnqueuedQue), NULL); -+ prMsduInfoReleaseList = (P_MSDU_INFO_T) QUEUE_GET_HEAD(&rNotEnqueuedQue); -+ } -+ -+ return prMsduInfoReleaseList; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Determine the STA_REC index for a packet -+* -+* \param[in] prMsduInfo Pointer to the packet -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+static VOID qmDetermineStaRecIndex(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo) -+{ -+ UINT_32 i; -+ -+ P_STA_RECORD_T prTempStaRec; -+ /* P_QUE_MGT_T prQM = &prAdapter->rQM; */ -+ -+ prTempStaRec = NULL; -+ -+ ASSERT(prMsduInfo); -+ -+ /* 4 <1> DA = BMCAST */ -+ if (IS_BMCAST_MAC_ADDR(prMsduInfo->aucEthDestAddr)) { -+ /* For intrastructure mode and P2P (playing as a GC), BMCAST frames shall be sent to the AP. -+ * FW shall take care of this. The host driver is not able to distinguish these cases. */ -+ prMsduInfo->ucStaRecIndex = STA_REC_INDEX_BMCAST; -+ DBGLOG(QM, LOUD, "TX with DA = BMCAST\n"); -+ return; -+ } -+#if (CFG_SUPPORT_TDLS == 1) -+ /* Check if the peer is TDLS one */ -+ if (TdlsexStaRecIdxGet(prAdapter, prMsduInfo) == TDLS_STATUS_SUCCESS) -+ return; /* find a TDLS record */ -+#endif /* CFG_SUPPORT_TDLS */ -+ -+ /* 4 <2> Check if an AP STA is present */ -+ for (i = 0; i < CFG_NUM_OF_STA_RECORD; i++) { -+ prTempStaRec = &(prAdapter->arStaRec[i]); -+ -+ if ((prTempStaRec->ucNetTypeIndex == prMsduInfo->ucNetworkType) -+ && (prTempStaRec->fgIsAp) -+ && (prTempStaRec->fgIsValid)) { -+ prMsduInfo->ucStaRecIndex = prTempStaRec->ucIndex; -+ return; -+ } -+ } -+ -+ /* 4 <3> Not BMCAST, No AP --> Compare DA (i.e., to see whether this is a unicast frame to a client) */ -+ for (i = 0; i < CFG_NUM_OF_STA_RECORD; i++) { -+ prTempStaRec = &(prAdapter->arStaRec[i]); -+ if (prTempStaRec->fgIsValid) { -+ if (EQUAL_MAC_ADDR(prTempStaRec->aucMacAddr, prMsduInfo->aucEthDestAddr)) { -+ prMsduInfo->ucStaRecIndex = prTempStaRec->ucIndex; -+ return; -+ } -+ } -+ } -+ -+ /* 4 <4> No STA found, Not BMCAST --> Indicate NOT_FOUND to FW */ -+ prMsduInfo->ucStaRecIndex = STA_REC_INDEX_NOT_FOUND; -+ DBGLOG(QM, LOUD, "QM: TX with STA_REC_INDEX_NOT_FOUND\n"); -+ -+#if (QM_TEST_MODE && QM_TEST_FAIR_FORWARDING) -+ prMsduInfo->ucStaRecIndex = (UINT_8) prQM->u4CurrentStaRecIndexToEnqueue; -+#endif -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Dequeue TX packets from a STA_REC for a particular TC -+* -+* \param[out] prQue The queue to put the dequeued packets -+* \param[in] ucTC The TC index (TC0_INDEX to TC5_INDEX) -+* \param[in] ucMaxNum The maximum amount of dequeued packets -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+static VOID -+qmDequeueTxPacketsFromPerStaQueues(IN P_ADAPTER_T prAdapter, -+ OUT P_QUE_T prQue, IN UINT_8 ucTC, IN UINT_8 ucCurrentQuota, IN UINT_8 ucTotalQuota) -+{ -+ -+#if QM_FORWARDING_FAIRNESS -+ UINT_32 i; /* Loop for */ -+ -+ PUINT_32 pu4HeadStaRecIndex; /* The Head STA index */ -+ PUINT_32 pu4HeadStaRecForwardCount; /* The total forwarded packets for the head STA */ -+ -+ P_STA_RECORD_T prStaRec; /* The current focused STA */ -+ P_BSS_INFO_T prBssInfo; /* The Bss for current focused STA */ -+ P_QUE_T prCurrQueue; /* The current TX queue to dequeue */ -+ P_MSDU_INFO_T prDequeuedPkt; /* The dequeued packet */ -+ -+ UINT_32 u4ForwardCount; /* To remember the total forwarded packets for a STA */ -+ UINT_32 u4MaxForwardCount; /* The maximum number of packets a STA can forward */ -+ UINT_32 u4Resource; /* The TX resource amount */ -+ -+ BOOLEAN fgChangeHeadSta; /* Whether a new head STA shall be determined at the end of the function */ -+ P_QUE_MGT_T prQM = &prAdapter->rQM; -+ -+ PUINT_8 pucFreeQuota = NULL; -+#if CFG_ENABLE_WIFI_DIRECT -+ P_P2P_CHNL_REQ_INFO_T prChnlReqInfo = &prAdapter->rWifiVar.prP2pFsmInfo->rChnlReqInfo; -+ /*NFC Beam + Indication */ -+#endif -+ DBGLOG(QM, LOUD, "Enter qmDequeueTxPacketsFromPerStaQueues (TC = %u)\n", ucTC); -+ -+ ASSERT(ucTC == TC0_INDEX || ucTC == TC1_INDEX || ucTC == TC2_INDEX || ucTC == TC3_INDEX || ucTC == TC4_INDEX); -+ -+ if (!ucCurrentQuota) { -+ prQM->au4DequeueNoTcResourceCounter[ucTC]++; -+ DBGLOG(TX, LOUD, "@@@@@ TC = %u ucCurrentQuota = %u @@@@@\n", ucTC, ucCurrentQuota); -+ return; -+ } -+ -+ u4Resource = ucCurrentQuota; -+ -+ /* 4 <1> Determine the head STA */ -+ /* The head STA shall be an active STA */ -+ -+ pu4HeadStaRecIndex = &(prQM->au4HeadStaRecIndex[ucTC]); -+ pu4HeadStaRecForwardCount = &(prQM->au4ForwardCount[ucTC]); -+ -+ DBGLOG(QM, LOUD, "(Fairness) TID = %u Init Head STA = %u Resource = %u\n", -+ ucTC, *pu4HeadStaRecIndex, u4Resource); -+ -+ /* From STA[x] to STA[x+1] to STA[x+2] to ... to STA[x] */ -+ for (i = 0; i < CFG_NUM_OF_STA_RECORD + 1; i++) { -+ prStaRec = &prAdapter->arStaRec[(*pu4HeadStaRecIndex)]; -+ ASSERT(prStaRec); -+ -+ /* Only Data frame (1x was not included) will be queued in */ -+ if (prStaRec->fgIsValid) { -+ -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]); -+ -+ ASSERT(prBssInfo->ucNetTypeIndex == prStaRec->ucNetTypeIndex); -+ -+ /* Determine how many packets the head STA is allowed to send in a round */ -+ -+ QM_DBG_CNT_INC(prQM, QM_DBG_CNT_25); -+ u4MaxForwardCount = ucTotalQuota; -+#if CFG_ENABLE_WIFI_DIRECT -+ -+ pucFreeQuota = NULL; -+ if (prStaRec->fgIsInPS && (ucTC != TC4_INDEX)) { -+ /* TODO: Change the threshold in coorperation with the PS forwarding mechanism */ -+ /* u4MaxForwardCount = ucTotalQuota; */ -+ /* Per STA flow control when STA in PS mode */ -+ /* The PHASE 1: only update from ucFreeQuota (now) */ -+ /* XXX The PHASE 2: Decide by ucFreeQuota and ucBmpDeliveryAC (per queue ) */ -+ /* aucFreeQuotaPerQueue[] */ -+ /* NOTE: other method to set u4Resource */ -+ -+ if (prStaRec->fgIsQoS && prStaRec->fgIsUapsdSupported -+ /* && prAdapter->rWifiVar.fgSupportQoS -+ && prAdapter->rWifiVar.fgSupportUAPSD */) { -+ -+ if (prStaRec->ucBmpTriggerAC & BIT(ucTC)) { -+ u4MaxForwardCount = prStaRec->ucFreeQuotaForDelivery; -+ pucFreeQuota = &prStaRec->ucFreeQuotaForDelivery; -+ } else { -+ u4MaxForwardCount = prStaRec->ucFreeQuotaForNonDelivery; -+ pucFreeQuota = &prStaRec->ucFreeQuotaForNonDelivery; -+ } -+ -+ } else { -+ ASSERT(prStaRec->ucFreeQuotaForDelivery == 0); -+ u4MaxForwardCount = prStaRec->ucFreeQuotaForNonDelivery; -+ pucFreeQuota = &prStaRec->ucFreeQuotaForNonDelivery; -+ } -+ -+ } /* fgIsInPS */ -+#endif /* CFG_ENABLE_WIFI_DIRECT */ -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ -+ /*NFC Beam + Indication */ -+ -+ if (prBssInfo->fgIsNetAbsent && (ucTC != TC4_INDEX)) { -+ if (prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT) { -+ if ((prChnlReqInfo->NFC_BEAM != 1) && -+ (u4MaxForwardCount > prBssInfo->ucBssFreeQuota)) -+ u4MaxForwardCount = prBssInfo->ucBssFreeQuota; -+ } else { -+ if (u4MaxForwardCount > prBssInfo->ucBssFreeQuota) -+ u4MaxForwardCount = prBssInfo->ucBssFreeQuota; -+ } -+ } -+#endif /* CFG_ENABLE_WIFI_DIRECT */ -+ -+ /* Determine whether the head STA can continue to forward packets in this round */ -+ if ((*pu4HeadStaRecForwardCount) < u4MaxForwardCount) -+ break; -+ -+ } /* prStaRec->fgIsValid */ -+ else { -+ /* The current Head STA has been deactivated, so search for a new head STA */ -+ prStaRec = NULL; -+ prBssInfo = NULL; -+ (*pu4HeadStaRecIndex)++; -+ (*pu4HeadStaRecIndex) %= CFG_NUM_OF_STA_RECORD; -+ -+ /* Reset the forwarding count before searching (since this is for a new selected STA) */ -+ (*pu4HeadStaRecForwardCount) = 0; -+ } -+ } /* i < CFG_NUM_OF_STA_RECORD + 1 */ -+ -+ /* All STA_RECs are inactive, so exit */ -+ if (!prStaRec) { -+ /* Under concurrent, it is possible that there is no candidcated STA. */ -+ /* DBGLOG(TX, EVENT, ("All STA_RECs are inactive\n")); */ -+ return; -+ } -+ -+ DBGLOG(QM, LOUD, "(Fairness) TID = %u Round Head STA = %u\n", ucTC, *pu4HeadStaRecIndex); -+ -+ /* 4 <2> Dequeue packets from the head STA */ -+ -+ prCurrQueue = &prStaRec->arTxQueue[ucTC]; -+ prDequeuedPkt = NULL; -+ fgChangeHeadSta = FALSE; -+ -+#if (CFG_SUPPORT_TDLS == 1) -+ if (pucFreeQuota != NULL) -+ TdlsexTxQuotaCheck(prAdapter->prGlueInfo, prStaRec, *pucFreeQuota); -+#endif /* CFG_SUPPORT_TDLS */ -+ -+ while (prCurrQueue) { -+ -+#if QM_DEBUG_COUNTER -+ -+ if (ucTC <= TC4_INDEX) { -+ if (QUEUE_IS_EMPTY(prCurrQueue)) { -+ QM_DBG_CNT_INC(prQM, ucTC); -+ /* QM_DBG_CNT_00 *//* QM_DBG_CNT_01 *//* QM_DBG_CNT_02 */ -+ /* QM_DBG_CNT_03 *//* QM_DBG_CNT_04 */ -+ } -+ if (u4Resource == 0) { -+ QM_DBG_CNT_INC(prQM, ucTC + 5); -+ /* QM_DBG_CNT_05 *//* QM_DBG_CNT_06 *//* QM_DBG_CNT_07 */ -+ /* QM_DBG_CNT_08 *//* QM_DBG_CNT_09 */ -+ } -+ if (((*pu4HeadStaRecForwardCount) >= u4MaxForwardCount)) { -+ QM_DBG_CNT_INC(prQM, ucTC + 10); -+ /* QM_DBG_CNT_10 *//* QM_DBG_CNT_11 *//* QM_DBG_CNT_12 */ -+ /* QM_DBG_CNT_13 *//* QM_DBG_CNT_14 */ -+ } -+ } -+#endif -+ -+ /* Three cases to break: (1) No resource (2) No packets (3) Fairness */ -+ if (QUEUE_IS_EMPTY(prCurrQueue) || ((*pu4HeadStaRecForwardCount) >= u4MaxForwardCount)) { -+ fgChangeHeadSta = TRUE; -+ break; -+ } else if (u4Resource == 0) { -+#if (CFG_SUPPORT_STATISTICS == 1) -+ prStaRec->u4NumOfNoTxQuota++; -+#endif /* CFG_SUPPORT_STATISTICS */ -+ break; -+ } -+ -+ QUEUE_REMOVE_HEAD(prCurrQueue, prDequeuedPkt, P_MSDU_INFO_T); -+ prStaRec->u4DeqeueuCounter++; -+ prQM->u4DequeueCounter++; -+ -+#if (CFG_SUPPORT_TDLS_DBG == 1) -+ if (prDequeuedPkt != NULL) { -+ struct sk_buff *prSkb = (struct sk_buff *)prDequeuedPkt->prPacket; -+ UINT8 *pkt = prSkb->data; -+ UINT16 u2Identifier; -+ -+ if ((*(pkt + 12) == 0x08) && (*(pkt + 13) == 0x00)) { -+ /* ip */ -+ u2Identifier = ((*(pkt + 18)) << 8) | (*(pkt + 19)); -+ DBGLOG(QM, LOUD, " %d\n", u2Identifier); -+ } -+ } -+#endif -+#if DBG && 0 -+ LOG_FUNC("Deq0 TC %d queued %u net %u mac len %u len %u Type %u 1x %u 11 %u\n", -+ prDequeuedPkt->ucTC, -+ prCurrQueue->u4NumElem, -+ prDequeuedPkt->ucNetworkType, -+ prDequeuedPkt->ucMacHeaderLength, -+ prDequeuedPkt->u2FrameLength, -+ prDequeuedPkt->ucPacketType, prDequeuedPkt->fgIs802_1x, prDequeuedPkt->fgIs802_11); -+ -+ LOG_FUNC("Dest Mac: %pM\n", prDequeuedPkt->aucEthDestAddr); -+ -+#if LINUX -+ { -+ struct sk_buff *prSkb = (struct sk_buff *)prDequeuedPkt->prPacket; -+ -+ dumpMemory8((PUINT_8) prSkb->data, prSkb->len); -+ } -+#endif -+ -+#endif -+ -+ ASSERT(prDequeuedPkt->ucTC == ucTC); -+ -+ if (!QUEUE_IS_EMPTY(prCurrQueue)) { -+ /* XXX: check all queues for STA */ -+ prDequeuedPkt->ucPsForwardingType = PS_FORWARDING_MORE_DATA_ENABLED; -+ } -+ -+ QUEUE_INSERT_TAIL(prQue, (P_QUE_ENTRY_T) prDequeuedPkt); -+ u4Resource--; -+ (*pu4HeadStaRecForwardCount)++; -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ /* XXX The PHASE 2: decrease from aucFreeQuotaPerQueue[] */ -+ if (prStaRec->fgIsInPS && (ucTC != TC4_INDEX)) { -+ if ((pucFreeQuota) && (*pucFreeQuota > 0)) -+ *pucFreeQuota = *pucFreeQuota - 1; -+ } -+#endif /* CFG_ENABLE_WIFI_DIRECT */ -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ if (prBssInfo->fgIsNetAbsent && (ucTC != TC4_INDEX)) { -+ if (prBssInfo->ucBssFreeQuota > 0) -+ prBssInfo->ucBssFreeQuota--; -+ } -+#endif /* CFG_ENABLE_WIFI_DIRECT */ -+ -+ } -+ -+ if (*pu4HeadStaRecForwardCount) { -+ DBGLOG(QM, LOUD, -+ "TC = %u Round Head STA = %u, u4HeadStaRecForwardCount = %u\n", ucTC, *pu4HeadStaRecIndex, -+ (*pu4HeadStaRecForwardCount)); -+ } -+#if QM_BURST_END_INFO_ENABLED -+ /* Let FW know which packet is the last one dequeued from the STA */ -+ if (prDequeuedPkt) -+ prDequeuedPkt->fgIsBurstEnd = TRUE; -+#endif -+ -+ /* 4 <3> Dequeue from the other STAs if there is residual TX resource */ -+ -+ /* Check all of the STAs to continue forwarding packets (including the head STA) */ -+ for (i = 0; i < CFG_NUM_OF_STA_RECORD; i++) { -+ /* Break in case no reasource is available */ -+ if (u4Resource == 0) { -+ prQM->au4DequeueNoTcResourceCounter[ucTC]++; -+ break; -+ } -+ -+ /* The current head STA will be examined when i = CFG_NUM_OF_STA_RECORD-1 */ -+ prStaRec = &prAdapter->arStaRec[((*pu4HeadStaRecIndex) + i + 1) % CFG_NUM_OF_STA_RECORD]; -+ ASSERT(prStaRec); -+ -+ if (prStaRec->fgIsValid) { -+ -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]); -+ ASSERT(prBssInfo->ucNetTypeIndex == prStaRec->ucNetTypeIndex); -+ -+ DBGLOG(QM, LOUD, "(Fairness) TID = %u Sharing STA = %u Resource = %u\n", -+ ucTC, prStaRec->ucIndex, u4Resource); -+ -+ prCurrQueue = &prStaRec->arTxQueue[ucTC]; -+ u4ForwardCount = 0; -+ u4MaxForwardCount = ucTotalQuota; -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ pucFreeQuota = NULL; -+ if (prStaRec->fgIsInPS && (ucTC != TC4_INDEX)) { -+ /* TODO: Change the threshold in coorperation with the PS forwarding mechanism */ -+ /* u4MaxForwardCount = ucTotalQuota; */ -+ /* Per STA flow control when STA in PS mode */ -+ /* The PHASE 1: only update from ucFreeQuota (now) */ -+ /* XXX The PHASE 2: Decide by ucFreeQuota and ucBmpDeliveryAC (per queue ) */ -+ /* aucFreeQuotaPerQueue[] */ -+ /* NOTE: other method to set u4Resource */ -+ if (prStaRec->fgIsQoS && prStaRec->fgIsUapsdSupported -+ /* && prAdapter->rWifiVar.fgSupportQoS -+ && prAdapter->rWifiVar.fgSupportUAPSD */) { -+ -+ if (prStaRec->ucBmpTriggerAC & BIT(ucTC)) { -+ u4MaxForwardCount = prStaRec->ucFreeQuotaForDelivery; -+ pucFreeQuota = &prStaRec->ucFreeQuotaForDelivery; -+ } else { -+ u4MaxForwardCount = prStaRec->ucFreeQuotaForNonDelivery; -+ pucFreeQuota = &prStaRec->ucFreeQuotaForNonDelivery; -+ } -+ -+ } else { -+ ASSERT(prStaRec->ucFreeQuotaForDelivery == 0); -+ u4MaxForwardCount = prStaRec->ucFreeQuotaForNonDelivery; -+ pucFreeQuota = &prStaRec->ucFreeQuotaForNonDelivery; -+ } -+ -+ } -+#endif /* CFG_ENABLE_WIFI_DIRECT */ -+#if CFG_ENABLE_WIFI_DIRECT -+ if (prBssInfo->fgIsNetAbsent && (ucTC != TC4_INDEX)) { -+ if (u4MaxForwardCount > prBssInfo->ucBssFreeQuota) -+ u4MaxForwardCount = prBssInfo->ucBssFreeQuota; -+ } -+#endif /* CFG_ENABLE_WIFI_DIRECT */ -+ } /* prStaRec->fgIsValid */ -+ else { -+ prBssInfo = NULL; -+ /* Invalid STA, so check the next STA */ -+ continue; -+ } -+ -+ while (prCurrQueue) { -+ /* Three cases to break: (1) No resource (2) No packets (3) Fairness */ -+ if ((u4Resource == 0) || QUEUE_IS_EMPTY(prCurrQueue) || (u4ForwardCount >= u4MaxForwardCount)) -+ break; -+ -+ -+ QUEUE_REMOVE_HEAD(prCurrQueue, prDequeuedPkt, P_MSDU_INFO_T); -+ -+#if DBG && 0 -+ DBGLOG(QM, LOUD, "Deq0 TC %d queued %u net %u mac len %u len %u Type %u 1x %u 11 %u\n", -+ prDequeuedPkt->ucTC, -+ prCurrQueue->u4NumElem, -+ prDequeuedPkt->ucNetworkType, -+ prDequeuedPkt->ucMacHeaderLength, -+ prDequeuedPkt->u2FrameLength, -+ prDequeuedPkt->ucPacketType, -+ prDequeuedPkt->fgIs802_1x, prDequeuedPkt->fgIs802_11)); -+ -+ DBGLOG(QM, LOUD, "Dest Mac: %pM\n", prDequeuedPkt->aucEthDestAddr); -+ -+#if LINUX -+ { -+ struct sk_buff *prSkb = (struct sk_buff *)prDequeuedPkt->prPacket; -+ -+ dumpMemory8((PUINT_8) prSkb->data, prSkb->len); -+ } -+#endif -+ -+#endif -+ -+ ASSERT(prDequeuedPkt->ucTC == ucTC); -+ -+ if (!QUEUE_IS_EMPTY(prCurrQueue)) -+ /* more data field ? */ -+ prDequeuedPkt->ucPsForwardingType = PS_FORWARDING_MORE_DATA_ENABLED; -+ -+ QUEUE_INSERT_TAIL(prQue, (P_QUE_ENTRY_T) prDequeuedPkt); -+ if (prStaRec) -+ prStaRec->u4DeqeueuCounter++; -+ prQM->u4DequeueCounter++; -+ u4Resource--; -+ u4ForwardCount++; -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ /* XXX The PHASE 2: decrease from aucFreeQuotaPerQueue[] */ -+ if (prStaRec->fgIsInPS && (ucTC != TC4_INDEX)) { -+ ASSERT(pucFreeQuota); -+ ASSERT(*pucFreeQuota > 0); -+ if (*pucFreeQuota > 0) -+ *pucFreeQuota = *pucFreeQuota - 1; -+ } -+#endif /* CFG_ENABLE_WIFI_DIRECT */ -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ ASSERT(prBssInfo->ucNetTypeIndex == prStaRec->ucNetTypeIndex); -+ if (prBssInfo->fgIsNetAbsent && (ucTC != TC4_INDEX)) { -+ if (prBssInfo->ucBssFreeQuota > 0) -+ prBssInfo->ucBssFreeQuota--; -+ } -+#endif /* CFG_ENABLE_WIFI_DIRECT */ -+ -+ } -+ -+#if QM_BURST_END_INFO_ENABLED -+ /* Let FW know which packet is the last one dequeued from the STA */ -+ if (u4ForwardCount) -+ prDequeuedPkt->fgIsBurstEnd = TRUE; -+#endif -+ } -+ -+ if (fgChangeHeadSta) { -+ (*pu4HeadStaRecIndex)++; -+ (*pu4HeadStaRecIndex) %= CFG_NUM_OF_STA_RECORD; -+ (*pu4HeadStaRecForwardCount) = 0; -+ DBGLOG(QM, LOUD, "(Fairness) TID = %u Scheduled Head STA = %u Left Resource = %u\n", -+ ucTC, (*pu4HeadStaRecIndex), u4Resource); -+ } -+ -+/***************************************************************************************/ -+#else -+ UINT_8 ucStaRecIndex; -+ P_STA_RECORD_T prStaRec; -+ P_QUE_T prCurrQueue; -+ UINT_8 ucPktCount; -+ P_MSDU_INFO_T prDequeuedPkt; -+ -+ DBGLOG(QM, LOUD, "Enter qmDequeueTxPacketsFromPerStaQueues (TC = %u)\n", ucTC); -+ -+ if (ucCurrentQuota == 0) -+ return; -+ /* 4 <1> Determine the queue index and the head STA */ -+ -+ /* The head STA */ -+ ucStaRecIndex = 0; /* TODO: Get the current head STA */ -+ prStaRec = QM_GET_STA_REC_PTR_FROM_INDEX(prAdapter, ucStaRecIndex); -+ ASSERT(prStaRec); -+ -+ if (prStaRec == NULL) -+ return; -+ -+ /* The queue to pull out packets */ -+ ASSERT(ucTC == TC0_INDEX || ucTC == TC1_INDEX || ucTC == TC2_INDEX || ucTC == TC3_INDEX || ucTC == TC4_INDEX); -+ prCurrQueue = &prStaRec->arTxQueue[ucTC]; -+ -+ ucPktCount = ucCurrentQuota; -+ prDequeuedPkt = NULL; -+ -+ /* 4 <2> Dequeue packets for the head STA */ -+ while (TRUE) { -+ if (!(prStaRec->fgIsValid) || ucPktCount == 0 || QUEUE_IS_EMPTY(prCurrQueue)) { -+ break; -+ -+ } else { -+ -+ QUEUE_REMOVE_HEAD(prCurrQueue, prDequeuedPkt, P_MSDU_INFO_T); -+ /* DbgPrint("QM: Remove Queue Head, TC= %d\n", prDequeuedPkt->ucTC); */ -+ ASSERT(prDequeuedPkt->ucTC == ucTC); -+ -+ QUEUE_INSERT_TAIL(prQue, (P_QUE_ENTRY_T) prDequeuedPkt); -+ ucPktCount--; -+ } -+ } -+ -+ /* DbgPrint("QM: Remaining number of queued packets = %d\n", prCurrQueue->u4NumElem); */ -+ -+#if QM_BURST_END_INFO_ENABLED -+ if (prDequeuedPkt) -+ prDequeuedPkt->fgIsBurstEnd = TRUE; -+#endif -+ -+ /* 4 <3> Update scheduling info */ -+ /* TODO */ -+ -+ /* 4 <4> Utilize the remainaing TX opportunities for non-head STAs */ -+ /* TODO */ -+#endif -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Dequeue TX packets from a per-Type-based Queue for a particular TC -+* -+* \param[out] prQue The queue to put the dequeued packets -+* \param[in] ucTC The TC index (Shall always be TC5_INDEX) -+* \param[in] ucMaxNum The maximum amount of dequeued packets -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+static VOID -+qmDequeueTxPacketsFromPerTypeQueues(IN P_ADAPTER_T prAdapter, OUT P_QUE_T prQue, IN UINT_8 ucTC, IN UINT_8 ucMaxNum) -+{ -+ /* UINT_8 ucQueIndex; */ -+ /* UINT_8 ucStaRecIndex; */ -+ P_BSS_INFO_T prBssInfo; -+ P_BSS_INFO_T parBssInfo; -+ P_QUE_T prCurrQueue; -+ UINT_8 ucPktCount; -+ P_MSDU_INFO_T prDequeuedPkt; -+ P_MSDU_INFO_T prBurstEndPkt; -+ QUE_T rMergeQue; -+ P_QUE_T prMergeQue; -+ P_QUE_MGT_T prQM; -+ -+ DBGLOG(QM, LOUD, "Enter qmDequeueTxPacketsFromPerTypeQueues (TC = %d, Max = %d)\n", ucTC, ucMaxNum); -+ -+ /* TC5: Broadcast/Multicast data packets */ -+ ASSERT(ucTC == TC5_INDEX); -+ -+ if (ucMaxNum == 0) -+ return; -+ -+ prQM = &prAdapter->rQM; -+ /* 4 <1> Determine the queue */ -+ -+ prCurrQueue = &prQM->arTxQueue[TX_QUEUE_INDEX_BMCAST]; -+ ucPktCount = ucMaxNum; -+ prDequeuedPkt = NULL; -+ prBurstEndPkt = NULL; -+ -+ parBssInfo = prAdapter->rWifiVar.arBssInfo; -+ -+ QUEUE_INITIALIZE(&rMergeQue); -+ prMergeQue = &rMergeQue; -+ -+ /* 4 <2> Dequeue packets */ -+ while (TRUE) { -+ if (ucPktCount == 0 || QUEUE_IS_EMPTY(prCurrQueue)) -+ break; -+ -+ QUEUE_REMOVE_HEAD(prCurrQueue, prDequeuedPkt, P_MSDU_INFO_T); -+ ASSERT(prDequeuedPkt->ucTC == ucTC); -+ -+ ASSERT(prDequeuedPkt->ucNetworkType < NETWORK_TYPE_INDEX_NUM); -+ -+ prBssInfo = &parBssInfo[prDequeuedPkt->ucNetworkType]; -+ -+ if (IS_BSS_ACTIVE(prBssInfo)) { -+ if (!prBssInfo->fgIsNetAbsent) { -+ QUEUE_INSERT_TAIL(prQue, (P_QUE_ENTRY_T) prDequeuedPkt); -+ prQM->u4DequeueCounter++; -+ prBurstEndPkt = prDequeuedPkt; -+ ucPktCount--; -+ QM_DBG_CNT_INC(prQM, QM_DBG_CNT_26); -+#if DBG && 0 -+ LOG_FUNC -+ ("DeqType TC %d queued %u net %u mac len %u len %u Type %u 1x %u 11 %u\n", -+ prDequeuedPkt->ucTC, prCurrQueue->u4NumElem, prDequeuedPkt->ucNetworkType, -+ prDequeuedPkt->ucMacHeaderLength, prDequeuedPkt->u2FrameLength, -+ prDequeuedPkt->ucPacketType, prDequeuedPkt->fgIs802_1x, -+ prDequeuedPkt->fgIs802_11); -+ -+ LOG_FUNC("Dest Mac: %pM\n", prDequeuedPkt->aucEthDestAddr); -+ -+#if LINUX -+ { -+ struct sk_buff *prSkb = (struct sk_buff *)prDequeuedPkt->prPacket; -+ -+ dumpMemory8((PUINT_8) prSkb->data, prSkb->len); -+ } -+#endif -+ -+#endif -+ } else { -+ QUEUE_INSERT_TAIL(prMergeQue, (P_QUE_ENTRY_T) prDequeuedPkt); -+ } -+ } else { -+ QM_TX_SET_NEXT_MSDU_INFO(prDequeuedPkt, NULL); -+ wlanProcessQueuedMsduInfo(prAdapter, prDequeuedPkt); -+ } -+ } -+ -+ if (QUEUE_IS_NOT_EMPTY(prMergeQue)) { -+ QUEUE_CONCATENATE_QUEUES(prMergeQue, prCurrQueue); -+ QUEUE_MOVE_ALL(prCurrQueue, prMergeQue); -+ if (QUEUE_GET_TAIL(prCurrQueue)) -+ QM_TX_SET_NEXT_MSDU_INFO((P_MSDU_INFO_T) QUEUE_GET_TAIL(prCurrQueue), NULL); -+ } -+#if QM_BURST_END_INFO_ENABLED -+ if (prBurstEndPkt) -+ prBurstEndPkt->fgIsBurstEnd = TRUE; -+#endif -+} /* qmDequeueTxPacketsFromPerTypeQueues */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Dequeue TX packets to send to HIF TX -+* -+* \param[in] prTcqStatus Info about the maximum amount of dequeued packets -+* -+* \return The list of dequeued TX packets -+*/ -+/*----------------------------------------------------------------------------*/ -+P_MSDU_INFO_T qmDequeueTxPackets(IN P_ADAPTER_T prAdapter, IN P_TX_TCQ_STATUS_T prTcqStatus) -+{ -+ -+ INT32 i; -+ P_MSDU_INFO_T prReturnedPacketListHead; -+ QUE_T rReturnedQue; -+ -+ DBGLOG(QM, LOUD, "Enter qmDequeueTxPackets\n"); -+ -+ QUEUE_INITIALIZE(&rReturnedQue); -+ -+ prReturnedPacketListHead = NULL; -+ -+ /* dequeue packets from different AC queue based on available aucFreeBufferCount */ -+ /* TC0 to TC4: AC0~AC3, 802.1x (commands packets are not handled by QM) */ -+ for (i = TC4_INDEX; i >= TC0_INDEX; i--) { -+ DBGLOG(QM, LOUD, "Dequeue packets from Per-STA queue[%d]\n", i); -+ -+ /* -+ in the function, we will re-calculate the ucFreeQuota. -+ If any packet with any priority for the station will be sent, ucFreeQuota -- -+ -+ Note1: ucFreeQuota will be decrease only when station is in power save mode. -+ In active mode, we will sent the packet to the air directly. -+ -+ if(prStaRec->fgIsInPS && (ucTC!=TC4_INDEX)) { -+ ASSERT(pucFreeQuota); -+ ASSERT(*pucFreeQuota>0); -+ if ((pucFreeQuota) && (*pucFreeQuota>0)) { -+ *pucFreeQuota = *pucFreeQuota - 1; -+ } -+ } -+ -+ Note2: maximum queued number for a station is 10, TXM_MAX_BUFFER_PER_STA_DEF in fw -+ i.e. default prStaRec->ucFreeQuota = 10 -+ -+ Note3: In qmUpdateFreeQuota(), we will adjust -+ ucFreeQuotaForNonDelivery = ucFreeQuota>>1; -+ ucFreeQuotaForDelivery = ucFreeQuota - ucFreeQuotaForNonDelivery; -+ */ -+ qmDequeueTxPacketsFromPerStaQueues(prAdapter, -+ &rReturnedQue, -+ (UINT_8) i, -+ prTcqStatus->aucFreeBufferCount[i], /* maximum dequeue number */ -+ prTcqStatus->aucMaxNumOfBuffer[i]); -+ -+ /* The aggregate number of dequeued packets */ -+ DBGLOG(QM, LOUD, "DQA)[%u](%u)\n", i, rReturnedQue.u4NumElem); -+ } -+ -+ /* TC5 (BMCAST or STA-NOT-FOUND packets) */ -+ qmDequeueTxPacketsFromPerTypeQueues(prAdapter, -+ &rReturnedQue, TC5_INDEX, prTcqStatus->aucFreeBufferCount[TC5_INDEX] -+ ); -+ -+ DBGLOG(QM, LOUD, "Current total number of dequeued packets = %u\n", rReturnedQue.u4NumElem); -+ -+ if (QUEUE_IS_NOT_EMPTY(&rReturnedQue)) { -+ prReturnedPacketListHead = (P_MSDU_INFO_T) QUEUE_GET_HEAD(&rReturnedQue); -+ QM_TX_SET_NEXT_MSDU_INFO((P_MSDU_INFO_T) QUEUE_GET_TAIL(&rReturnedQue), NULL); -+ } -+ -+ return prReturnedPacketListHead; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Adjust the TC quotas according to traffic demands -+* -+* \param[out] prTcqAdjust The resulting adjustment -+* \param[in] prTcqStatus Info about the current TC quotas and counters -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID qmAdjustTcQuotas(IN P_ADAPTER_T prAdapter, OUT P_TX_TCQ_ADJUST_T prTcqAdjust, IN P_TX_TCQ_STATUS_T prTcqStatus) -+{ -+#if QM_ADAPTIVE_TC_RESOURCE_CTRL -+ UINT_32 i; -+ P_QUE_MGT_T prQM = &prAdapter->rQM; -+ -+ /* Must reset */ -+ for (i = 0; i < TC_NUM; i++) -+ prTcqAdjust->acVariation[i] = 0; -+ -+ /* 4 <1> If TC resource is not just adjusted, exit directly */ -+ if (!prQM->fgTcResourcePostAnnealing) -+ return; -+ /* 4 <2> Adjust TcqStatus according to the updated prQM->au4CurrentTcResource */ -+ else { -+ INT_32 i4TotalExtraQuota = 0; -+ INT_32 ai4ExtraQuota[TC_NUM]; -+ BOOLEAN fgResourceRedistributed = TRUE; -+ -+ /* Obtain the free-to-distribute resource */ -+ for (i = 0; i < TC_NUM; i++) { -+ ai4ExtraQuota[i] = -+ (INT_32) prTcqStatus->aucMaxNumOfBuffer[i] - (INT_32) prQM->au4CurrentTcResource[i]; -+ -+ if (ai4ExtraQuota[i] > 0) { /* The resource shall be reallocated to other TCs */ -+ -+ if (ai4ExtraQuota[i] > prTcqStatus->aucFreeBufferCount[i]) { -+ /* -+ we have residunt TC resources for the TC: -+ EX: aucMaxNumOfBuffer[] = 20, au4CurrentTcResource[] = 5 -+ ai4ExtraQuota[] = 15, aucFreeBufferCount[] = 10 -+ -+ so ai4ExtraQuota[] = aucFreeBufferCount[] = 10 -+ because we available TC resources actually is 10, not 20 -+ */ -+ ai4ExtraQuota[i] = prTcqStatus->aucFreeBufferCount[i]; -+ -+ /* -+ FALSE means we can re-do TC resource adjustment in tx done -+ at next time, maybe more tx done is finished -+ */ -+ fgResourceRedistributed = FALSE; -+ } -+ -+ /* accumulate current all available TC resources */ -+ i4TotalExtraQuota += ai4ExtraQuota[i]; -+ -+ /* deduce unused TC resources for the TC */ -+ prTcqAdjust->acVariation[i] = (INT_8) (-ai4ExtraQuota[i]); -+ } -+ } -+ -+ /* Distribute quotas to TCs which need extra resource according to prQM->au4CurrentTcResource */ -+ for (i = 0; i < TC_NUM; i++) { -+ if (ai4ExtraQuota[i] < 0) { -+ -+ /* The TC needs extra resources */ -+ if ((-ai4ExtraQuota[i]) > i4TotalExtraQuota) { -+ /* the number of needed extra resources is larger than total available */ -+ ai4ExtraQuota[i] = (-i4TotalExtraQuota); -+ -+ /* wait for next tx done to do adjustment */ -+ fgResourceRedistributed = FALSE; -+ } -+ -+ /* decrease the total available */ -+ i4TotalExtraQuota += ai4ExtraQuota[i]; -+ -+ /* mark to increase TC resources for the TC */ -+ prTcqAdjust->acVariation[i] = (INT_8) (-ai4ExtraQuota[i]); -+ } -+ } -+ -+ /* In case some TC is waiting for TX Done, continue to adjust TC quotas upon TX Done */ -+ -+ /* -+ if fgResourceRedistributed == TRUE, it means we will adjust at this time so -+ we need to re-adjust TC resources (fgTcResourcePostAnnealing = FALSE). -+ */ -+ prQM->fgTcResourcePostAnnealing = (!fgResourceRedistributed); -+ -+#if QM_PRINT_TC_RESOURCE_CTRL -+ DBGLOG(QM, LOUD, "QM: Curr Quota [0]=%u [1]=%u [2]=%u [3]=%u [4]=%u [5]=%u\n", -+ prTcqStatus->aucFreeBufferCount[0], -+ prTcqStatus->aucFreeBufferCount[1], -+ prTcqStatus->aucFreeBufferCount[2], -+ prTcqStatus->aucFreeBufferCount[3], -+ prTcqStatus->aucFreeBufferCount[4], prTcqStatus->aucFreeBufferCount[5] -+ )); -+#endif -+ } -+ -+#else -+ UINT_32 i; -+ -+ for (i = 0; i < TC_NUM; i++) -+ prTcqAdjust->acVariation[i] = 0; -+ -+#endif -+} -+ -+#if QM_ADAPTIVE_TC_RESOURCE_CTRL -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Update the average TX queue length for the TC resource control mechanism -+* -+* \param (none) -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID qmUpdateAverageTxQueLen(IN P_ADAPTER_T prAdapter) -+{ -+ INT_32 u4CurrQueLen, i, k; -+ P_STA_RECORD_T prStaRec; -+ P_QUE_MGT_T prQM = &prAdapter->rQM; -+ -+ /* 4 <1> Update the queue lengths for TC0 to TC3 (skip TC4) and TC5 */ -+ /* use moving average algorithm to calculate au4AverageQueLen for every TC queue */ -+ for (i = 0; i < NUM_OF_PER_STA_TX_QUEUES - 1; i++) { -+ u4CurrQueLen = 0; -+ -+ for (k = 0; k < CFG_NUM_OF_STA_RECORD; k++) { -+ prStaRec = &prAdapter->arStaRec[k]; -+ ASSERT(prStaRec); -+ -+ /* If the STA is activated, get the queue length */ -+ if (prStaRec->fgIsValid && -+ (!prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex].fgIsNetAbsent) -+ ) { -+ -+ u4CurrQueLen += (prStaRec->arTxQueue[i].u4NumElem); -+ } -+ } -+ -+ if (prQM->au4AverageQueLen[i] == 0) { -+ prQM->au4AverageQueLen[i] = (u4CurrQueLen << QM_QUE_LEN_MOVING_AVE_FACTOR); /* *8 */ -+ } else { -+ /* len => len - len/8 = 7/8 * len + new len */ -+ prQM->au4AverageQueLen[i] -= (prQM->au4AverageQueLen[i] >> QM_QUE_LEN_MOVING_AVE_FACTOR); -+ prQM->au4AverageQueLen[i] += (u4CurrQueLen); -+ } -+ -+ } -+ -+ /* Update the queue length for TC5 (BMCAST) */ -+ u4CurrQueLen = prQM->arTxQueue[TX_QUEUE_INDEX_BMCAST].u4NumElem; -+ -+ if (prQM->au4AverageQueLen[TC_NUM - 1] == 0) { -+ prQM->au4AverageQueLen[TC_NUM - 1] = (u4CurrQueLen << QM_QUE_LEN_MOVING_AVE_FACTOR); -+ } else { -+ prQM->au4AverageQueLen[TC_NUM - 1] -= -+ (prQM->au4AverageQueLen[TC_NUM - 1] >> QM_QUE_LEN_MOVING_AVE_FACTOR); -+ prQM->au4AverageQueLen[TC_NUM - 1] += (u4CurrQueLen); -+ } -+ -+ /* 4 <2> Adjust TC resource assignment every 3 times */ -+ /* Check whether it is time to adjust the TC resource assignment */ -+ if (--prQM->u4TimeToAdjustTcResource == 0) { /* u4TimeToAdjustTcResource = 3 */ -+ -+ /* The last assignment has not been completely applied */ -+ if (prQM->fgTcResourcePostAnnealing) { -+ /* Upon the next qmUpdateAverageTxQueLen function call, do this check again */ -+ -+ /* wait for next time to do qmReassignTcResource */ -+ prQM->u4TimeToAdjustTcResource = 1; -+ } else { /* The last assignment has been applied */ -+ prQM->u4TimeToAdjustTcResource = QM_INIT_TIME_TO_ADJUST_TC_RSC; -+ qmReassignTcResource(prAdapter); -+ } -+ } -+ -+ /* Debug */ -+#if QM_PRINT_TC_RESOURCE_CTRL -+ for (i = 0; i < TC_NUM; i++) { -+ if (QM_GET_TX_QUEUE_LEN(prAdapter, i) >= 100) { -+ DBGLOG(QM, LOUD, "QM: QueLen [%u %u %u %u %u %u]\n", -+ QM_GET_TX_QUEUE_LEN(prAdapter, 0), -+ QM_GET_TX_QUEUE_LEN(prAdapter, 1), -+ QM_GET_TX_QUEUE_LEN(prAdapter, 2), -+ QM_GET_TX_QUEUE_LEN(prAdapter, 3), -+ QM_GET_TX_QUEUE_LEN(prAdapter, 4), QM_GET_TX_QUEUE_LEN(prAdapter, 5) -+ )); -+ break; -+ } -+ } -+#endif -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Assign TX resource for each TC according to TX queue length and current assignment -+* -+* \param (none) -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID qmReassignTcResource(IN P_ADAPTER_T prAdapter) -+{ -+ INT_32 i4TotalResourceDemand = 0; -+ UINT_32 u4ResidualResource = 0; -+ UINT_32 i; -+ INT_32 ai4PerTcResourceDemand[TC_NUM]; -+ UINT_32 u4ShareCount = 0; -+ UINT_32 u4Share = 0; -+ P_QUE_MGT_T prQM = &prAdapter->rQM; -+ -+ /* Note: After the new assignment is obtained, set prQM->fgTcResourcePostAnnealing to TRUE to -+ * start the TC-quota adjusting procedure, which will be invoked upon every TX Done -+ */ -+ /* tx done -> nicProcessTxInterrupt() -> nicTxAdjustTcq() -+ * -> qmAdjustTcQuotas() -> check fgTcResourcePostAnnealing */ -+ -+ /* 4 <1> Determine the demands */ -+ /* Determine the amount of extra resource to fulfill all of the demands */ -+ for (i = 0; i < TC_NUM; i++) { -+ /* Skip TC4, which is not adjustable */ -+ if (i == TC4_INDEX) -+ continue; -+ -+ /* -+ Define: extra_demand = average que_length (includes all station records) + -+ min_reserved_quota - -+ current available TC resources -+ -+ extra_demand means we need extra TC resources to transmit; other TCs can -+ borrow their resources to us? -+ */ -+ ai4PerTcResourceDemand[i] = -+ ((UINT_32) (QM_GET_TX_QUEUE_LEN(prAdapter, i)) + -+ prQM->au4MinReservedTcResource[i] - prQM->au4CurrentTcResource[i]); -+ -+ /* If there are queued packets, allocate extra resource for the TC (for TCP consideration) */ -+ if (QM_GET_TX_QUEUE_LEN(prAdapter, i)) -+ ai4PerTcResourceDemand[i] += QM_EXTRA_RESERVED_RESOURCE_WHEN_BUSY; /* 0 */ -+ -+ /* -+ accumulate all needed extra TC resources -+ maybe someone need + resource, maybe someone need - resource -+ */ -+ i4TotalResourceDemand += ai4PerTcResourceDemand[i]; -+ } -+ -+ /* 4 <2> Case 1: Demand <= Total Resource */ -+ if (i4TotalResourceDemand <= 0) { -+ /* 4 <2.1> Satisfy every TC */ -+ /* total TC resources are enough, no extra TC resources is needed */ -+ -+ /* adjust used TC resources to average TC resources + min reserve TC resources */ -+ for (i = 0; i < TC_NUM; i++) { -+ /* Skip TC4 (not adjustable) */ -+ if (i == TC4_INDEX) -+ continue; -+ -+ /* -+ the number of resources that one TC releases can be used for -+ other TCs -+ -+ EX: TC0 au4CurrentTcResource[0] = 10 ai4PerTcResourceDemand[0] = -5 -+ TC1 au4CurrentTcResource[1] = 5 ai4PerTcResourceDemand[0] = +5 -+ => TC0 au4CurrentTcResource[0] = 10 + (-5) = 5 -+ TC1 au4CurrentTcResource[1] = 5 + (+5) = 10 -+ */ -+ prQM->au4CurrentTcResource[i] += ai4PerTcResourceDemand[i]; -+ } -+ -+ /* 4 <2.2> Share the residual resource evenly */ -+ u4ShareCount = (TC_NUM - 1); /* 5, excluding TC4 */ -+ -+ /* -+ EX: i4TotalResourceDemand = -10 -+ means we have 10 available resources can be used. -+ */ -+ u4ResidualResource = (UINT_32) (-i4TotalResourceDemand); -+ u4Share = (u4ResidualResource / u4ShareCount); -+ -+ /* share available TC resources to all TCs averagely */ -+ for (i = 0; i < TC_NUM; i++) { -+ /* Skip TC4 (not adjustable) */ -+ if (i == TC4_INDEX) -+ continue; -+ -+ /* allocate residual average resources to the TC */ -+ prQM->au4CurrentTcResource[i] += u4Share; -+ -+ /* Every TC is fully satisfied so no need extra resources */ -+ ai4PerTcResourceDemand[i] = 0; -+ -+ /* decrease the allocated resources */ -+ u4ResidualResource -= u4Share; -+ } -+ -+ /* if still have available resources, we decide to give them to VO (TC3) queue */ -+ /* 4 <2.3> Allocate the left resource to TC3 (VO) */ -+ prQM->au4CurrentTcResource[TC3_INDEX] += (u4ResidualResource); -+ -+ } -+ /* 4 <3> Case 2: Demand > Total Resource --> Guarantee a minimum amount of resource for each TC */ -+ else { -+ /* -+ u4ResidualResource means we at least need to keep -+ QM_INITIAL_RESIDUAL_TC_RESOURCE available TC resources -+ -+ in 6628, u4ResidualResource = 26, max 28 -+ */ -+ u4ResidualResource = QM_INITIAL_RESIDUAL_TC_RESOURCE; -+ -+ /* 4 <3.1> Allocated resource amount = minimum of (guaranteed, total demand) */ -+ for (i = 0; i < TC_NUM; i++) { -+ -+ if (i == TC4_INDEX) -+ continue; /* Skip TC4 (not adjustable) */ -+ -+ /* The demand can be fulfilled with the guaranteed resource amount 4 4 6 6 2 4 */ -+ -+ /* -+ ai4PerTcResourceDemand[i] = -+ ((UINT_32)(QM_GET_TX_QUEUE_LEN(prAdapter, i)) + -+ prQM->au4MinReservedTcResource[i] - -+ prQM->au4CurrentTcResource[i]); -+ -+ so au4CurrentTcResource + ai4PerTcResourceDemand = -+ -+ ((UINT_32)(QM_GET_TX_QUEUE_LEN(prAdapter, i)) + -+ prQM->au4MinReservedTcResource[i] = -+ -+ current average queue len + min TC resources -+ */ -+ if (prQM->au4CurrentTcResource[i] + ai4PerTcResourceDemand[i] < -+ prQM->au4GuaranteedTcResource[i]) { -+ -+ /* avg queue len + min reserve still smaller than guarantee so enough */ -+ prQM->au4CurrentTcResource[i] += ai4PerTcResourceDemand[i]; -+ -+ /* accumulate available TC resources from the TC */ -+ u4ResidualResource += -+ (prQM->au4GuaranteedTcResource[i] - prQM->au4CurrentTcResource[i]); -+ ai4PerTcResourceDemand[i] = 0; -+ } -+ -+ /* The demand can not be fulfilled with the guaranteed resource amount */ -+ else { -+ -+ /* means even we use all guarantee resources for the TC is still not enough */ -+ -+ /* -+ guarantee number is always for the TC so extra resource number cannot -+ include the guarantee number. -+ -+ EX: au4GuaranteedTcResource = 10, au4CurrentTcResource = 5 -+ ai4PerTcResourceDemand = 6 -+ -+ ai4PerTcResourceDemand -= (10 - 5) ==> 1 -+ only need extra 1 TC resouce is enough. -+ */ -+ ai4PerTcResourceDemand[i] -= -+ (prQM->au4GuaranteedTcResource[i] - prQM->au4CurrentTcResource[i]); -+ -+ /* update current avg TC resource to guarantee number */ -+ prQM->au4CurrentTcResource[i] = prQM->au4GuaranteedTcResource[i]; -+ -+ /* count how many TC queues need to get extra resources */ -+ u4ShareCount++; -+ } -+ } -+ -+ /* 4 <3.2> Allocate the residual resource */ -+ do { -+ /* If there is no resource left, exit directly */ -+ if (u4ResidualResource == 0) -+ break; -+ -+ /* This shall not happen */ -+ if (u4ShareCount == 0) { -+ prQM->au4CurrentTcResource[TC1_INDEX] += u4ResidualResource; -+ DBGLOG(QM, ERROR, "QM: (Error) u4ShareCount = 0\n"); -+ break; -+ } -+ -+ /* Share the residual resource evenly */ -+ u4Share = (u4ResidualResource / u4ShareCount); -+ -+ if (u4Share) { -+ for (i = 0; i < TC_NUM; i++) { -+ /* Skip TC4 (not adjustable) */ -+ if (i == TC4_INDEX) -+ continue; -+ -+ if (ai4PerTcResourceDemand[i] == 0) -+ continue; -+ -+ if (ai4PerTcResourceDemand[i] - u4Share) { -+ /* still not enough but we just can give it u4Share resources */ -+ prQM->au4CurrentTcResource[i] += u4Share; -+ u4ResidualResource -= u4Share; -+ ai4PerTcResourceDemand[i] -= u4Share; -+ } else { -+ /* enough */ -+ prQM->au4CurrentTcResource[i] += ai4PerTcResourceDemand[i]; -+ u4ResidualResource -= ai4PerTcResourceDemand[i]; -+ ai4PerTcResourceDemand[i] = 0; -+ } -+ } -+ } -+ -+ if (u4ResidualResource == 0) -+ break; -+ /* By priority, allocate the left resource that is not divisible by u4Share */ -+ -+ if (ai4PerTcResourceDemand[TC3_INDEX]) { /* VO */ -+ prQM->au4CurrentTcResource[TC3_INDEX]++; -+ if (--u4ResidualResource == 0) -+ break; -+ } -+ -+ if (ai4PerTcResourceDemand[TC2_INDEX]) { /* VI */ -+ prQM->au4CurrentTcResource[TC2_INDEX]++; -+ if (--u4ResidualResource == 0) -+ break; -+ } -+ -+ if (ai4PerTcResourceDemand[TC5_INDEX]) { /* BMCAST */ -+ prQM->au4CurrentTcResource[TC5_INDEX]++; -+ if (--u4ResidualResource == 0) -+ break; -+ } -+ -+ if (ai4PerTcResourceDemand[TC1_INDEX]) { /* BE */ -+ prQM->au4CurrentTcResource[TC1_INDEX]++; -+ if (--u4ResidualResource == 0) -+ break; -+ } -+ -+ if (ai4PerTcResourceDemand[TC0_INDEX]) { /* BK */ -+ prQM->au4CurrentTcResource[TC0_INDEX]++; -+ if (--u4ResidualResource == 0) -+ break; -+ } -+ -+ /* Allocate the left resource */ -+ prQM->au4CurrentTcResource[TC3_INDEX] += u4ResidualResource; -+ -+ } while (FALSE); -+ } -+ -+ /* mark the flag that we can start to do TC resource adjustment after TX done handle */ -+ prQM->fgTcResourcePostAnnealing = TRUE; -+ -+#if QM_PRINT_TC_RESOURCE_CTRL -+ /* Debug print */ -+ DBGLOG(QM, LOUD, "QM: TC Rsc %u %u %u %u %u %u\n", -+ prQM->au4CurrentTcResource[0], -+ prQM->au4CurrentTcResource[1], -+ prQM->au4CurrentTcResource[2], -+ prQM->au4CurrentTcResource[3], prQM->au4CurrentTcResource[4], prQM->au4CurrentTcResource[5] -+ )); -+#endif -+ -+} -+ -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/* RX-Related Queue Management */ -+/*----------------------------------------------------------------------------*/ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Init Queue Management for RX -+* -+* \param[in] (none) -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID qmInitRxQueues(IN P_ADAPTER_T prAdapter) -+{ -+ /* DbgPrint("QM: Enter qmInitRxQueues()\n"); */ -+ /* TODO */ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Handle RX packets (buffer reordering) -+* -+* \param[in] prSwRfbListHead The list of RX packets -+* -+* \return The list of packets which are not buffered for reordering -+*/ -+/*----------------------------------------------------------------------------*/ -+P_SW_RFB_T qmHandleRxPackets(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfbListHead) -+{ -+ -+#if CFG_RX_REORDERING_ENABLED -+ /* UINT_32 i; */ -+ P_SW_RFB_T prCurrSwRfb; -+ P_SW_RFB_T prNextSwRfb; -+ P_HIF_RX_HEADER_T prHifRxHdr; -+ QUE_T rReturnedQue; -+ PUINT_8 pucEthDestAddr; -+ BOOLEAN fgIsBMC; -+ -+ /* DbgPrint("QM: Enter qmHandleRxPackets()\n"); */ -+ -+ DEBUGFUNC("qmHandleRxPackets"); -+ -+ ASSERT(prSwRfbListHead); -+ -+ QUEUE_INITIALIZE(&rReturnedQue); -+ prNextSwRfb = prSwRfbListHead; -+ -+ do { -+ prCurrSwRfb = prNextSwRfb; -+ prNextSwRfb = QM_RX_GET_NEXT_SW_RFB(prCurrSwRfb); -+ -+ prHifRxHdr = prCurrSwRfb->prHifRxHdr; /* TODO: (Tehuang) Use macro to obtain the pointer */ -+ -+ /* TODO: (Tehuang) Check if relaying */ -+ prCurrSwRfb->eDst = RX_PKT_DESTINATION_HOST; -+ -+ /* Decide the Destination */ -+#if CFG_RX_PKTS_DUMP -+ if (prAdapter->rRxCtrl.u4RxPktsDumpTypeMask & BIT(HIF_RX_PKT_TYPE_DATA)) { -+ DBGLOG(SW4, INFO, "QM RX DATA: net %u sta idx %u wlan idx %u ssn %u tid %u ptype %u 11 %u\n", -+ (UINT_32) HIF_RX_HDR_GET_NETWORK_IDX(prHifRxHdr), -+ prHifRxHdr->ucStaRecIdx, prCurrSwRfb->ucWlanIdx, -+ (UINT_32) HIF_RX_HDR_GET_SN(prHifRxHdr), /* The new SN of the frame */ -+ (UINT_32) HIF_RX_HDR_GET_TID(prHifRxHdr), -+ prCurrSwRfb->ucPacketType, -+ (UINT_32) HIF_RX_HDR_GET_80211_FLAG(prHifRxHdr)); -+ -+ DBGLOG_MEM8(SW4, TRACE, (PUINT_8) prCurrSwRfb->pvHeader, prCurrSwRfb->u2PacketLen); -+ } -+#endif -+ -+ fgIsBMC = FALSE; -+ if (!HIF_RX_HDR_GET_80211_FLAG(prHifRxHdr)) { -+ -+ UINT_8 ucNetTypeIdx; -+ P_BSS_INFO_T prBssInfo; -+ -+ pucEthDestAddr = prCurrSwRfb->pvHeader; -+ ucNetTypeIdx = HIF_RX_HDR_GET_NETWORK_IDX(prHifRxHdr); -+ -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[ucNetTypeIdx]); -+ /* DBGLOG_MEM8(QM, TRACE,prCurrSwRfb->pvHeader, 16); */ -+ /* */ -+ -+ if (IS_BMCAST_MAC_ADDR(pucEthDestAddr) && (OP_MODE_ACCESS_POINT != prBssInfo->eCurrentOPMode)) -+ fgIsBMC = TRUE; -+ -+ if (prAdapter->rRxCtrl.rFreeSwRfbList.u4NumElem > -+ (CFG_RX_MAX_PKT_NUM - CFG_NUM_OF_QM_RX_PKT_NUM)) { -+ -+ if (!IS_BSS_ACTIVE(prBssInfo)) { -+ DBGLOG(QM, WARN, "Mark NULL the Packet for inactive Bss %u\n", ucNetTypeIdx); -+ prCurrSwRfb->eDst = RX_PKT_DESTINATION_NULL; -+ QUEUE_INSERT_TAIL(&rReturnedQue, (P_QUE_ENTRY_T) prCurrSwRfb); -+ continue; -+ } -+ -+ if (OP_MODE_ACCESS_POINT == prBssInfo->eCurrentOPMode) { -+ if (IS_BMCAST_MAC_ADDR(pucEthDestAddr)) -+ prCurrSwRfb->eDst = RX_PKT_DESTINATION_HOST_WITH_FORWARD; -+ else if (UNEQUAL_MAC_ADDR(prBssInfo->aucOwnMacAddr, pucEthDestAddr) && -+ bssGetClientByAddress(prBssInfo, pucEthDestAddr)) -+ prCurrSwRfb->eDst = RX_PKT_DESTINATION_FORWARD; -+ /* TODO : need to check the dst mac is valid */ -+ /* If src mac is invalid, the packet will be freed in fw */ -+ } /* OP_MODE_ACCESS_POINT */ -+#if CFG_SUPPORT_HOTSPOT_2_0 -+ else if (hs20IsFrameFilterEnabled(prAdapter, prBssInfo) && -+ hs20IsUnsecuredFrame(prAdapter, prBssInfo, prCurrSwRfb)) { -+ DBGLOG(QM, WARN, -+ "Mark NULL the Packet for Dropped Packet %u\n", ucNetTypeIdx); -+ prCurrSwRfb->eDst = RX_PKT_DESTINATION_NULL; -+ QUEUE_INSERT_TAIL(&rReturnedQue, (P_QUE_ENTRY_T) prCurrSwRfb); -+ continue; -+ } -+#endif -+ } else { -+ /* Dont not occupy other SW RFB */ -+ DBGLOG(QM, WARN, "Mark NULL the Packet for less Free Sw Rfb\n"); -+ prCurrSwRfb->eDst = RX_PKT_DESTINATION_NULL; -+ QUEUE_INSERT_TAIL(&rReturnedQue, (P_QUE_ENTRY_T) prCurrSwRfb); -+ continue; -+ } -+ -+ } -+#if CFG_SUPPORT_WAPI -+ if (prCurrSwRfb->u2PacketLen > ETHER_HEADER_LEN) { -+ PUINT_8 pc = (PUINT_8) prCurrSwRfb->pvHeader; -+ UINT_16 u2Etype = 0; -+ -+ u2Etype = (pc[ETH_TYPE_LEN_OFFSET] << 8) | (pc[ETH_TYPE_LEN_OFFSET + 1]); -+ -+ /* for wapi integrity test. WPI_1x packet should be always in non-encrypted mode. -+ if we received any WPI(0x88b4) packet that is encrypted, drop here. */ -+ if (u2Etype == ETH_WPI_1X && HIF_RX_HDR_GET_SEC_MODE(prHifRxHdr) != 0) { -+ DBGLOG(QM, INFO, "drop wpi packet with sec mode\n"); -+ prCurrSwRfb->eDst = RX_PKT_DESTINATION_NULL; -+ QUEUE_INSERT_TAIL(&rReturnedQue, (P_QUE_ENTRY_T) prCurrSwRfb); -+ continue; -+ } -+ } -+#endif -+ /* BAR frame */ -+ if (HIF_RX_HDR_GET_BAR_FLAG(prHifRxHdr)) { -+ prCurrSwRfb->eDst = RX_PKT_DESTINATION_NULL; -+ qmProcessBarFrame(prAdapter, prCurrSwRfb, &rReturnedQue); -+ } -+ /* Reordering is not required for this packet, return it without buffering */ -+ else if (!HIF_RX_HDR_GET_REORDER_FLAG(prHifRxHdr) || fgIsBMC) { -+#if 0 -+ if (!HIF_RX_HDR_GET_80211_FLAG(prHifRxHdr)) { -+ UINT_8 ucNetTypeIdx; -+ P_BSS_INFO_T prBssInfo; -+ -+ pucEthDestAddr = prCurrSwRfb->pvHeader; -+ ucNetTypeIdx = HIF_RX_HDR_GET_NETWORK_IDX(prHifRxHdr); -+ -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[ucNetTypeIdx]); -+ -+ if (IS_BMCAST_MAC_ADDR(pucEthDestAddr) -+ && (OP_MODE_ACCESS_POINT == prBssInfo->eCurrentOPMode)) { -+ prCurrSwRfb->eDst = RX_PKT_DESTINATION_HOST_WITH_FORWARD; -+ } -+ } -+#endif -+ QUEUE_INSERT_TAIL(&rReturnedQue, (P_QUE_ENTRY_T) prCurrSwRfb); -+ } -+ /* Reordering is required for this packet */ -+ else { -+ /* If this packet should dropped or indicated to the host immediately, -+ * it should be enqueued into the rReturnedQue with specific flags. If -+ * this packet should be buffered for reordering, it should be enqueued -+ * into the reordering queue in the STA_REC rather than into the -+ * rReturnedQue. -+ */ -+ qmProcessPktWithReordering(prAdapter, prCurrSwRfb, &rReturnedQue); -+ -+ } -+ } while (prNextSwRfb); -+ -+ /* RX_PKT_DESTINATION_HOST_WITH_FORWARD or RX_PKT_DESTINATION_FORWARD */ -+ /* The returned list of SW_RFBs must end with a NULL pointer */ -+ if (QUEUE_IS_NOT_EMPTY(&rReturnedQue)) -+ QM_TX_SET_NEXT_MSDU_INFO((P_SW_RFB_T) QUEUE_GET_TAIL(&rReturnedQue), NULL); -+ -+ return (P_SW_RFB_T) QUEUE_GET_HEAD(&rReturnedQue); -+ -+#else -+ -+ /* DbgPrint("QM: Enter qmHandleRxPackets()\n"); */ -+ return prSwRfbListHead; -+ -+#endif -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Reorder the received packet -+* -+* \param[in] prSwRfb The RX packet to process -+* \param[out] prReturnedQue The queue for indicating packets -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID qmProcessPktWithReordering(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, OUT P_QUE_T prReturnedQue) -+{ -+ -+ P_STA_RECORD_T prStaRec; -+ P_HIF_RX_HEADER_T prHifRxHdr; -+ P_RX_BA_ENTRY_T prReorderQueParm; -+ -+ UINT_32 u4SeqNo; -+ UINT_32 u4WinStart; -+ UINT_32 u4WinEnd; -+ P_QUE_T prReorderQue; -+ /* P_SW_RFB_T prReorderedSwRfb; */ -+ BOOLEAN fgIsBaTimeout; -+ -+ DEBUGFUNC("qmProcessPktWithReordering"); -+ -+ if ((prSwRfb == NULL) || (prReturnedQue == NULL) || (prSwRfb->prHifRxHdr == NULL)) { -+ ASSERT(FALSE); -+ return; -+ } -+ -+ prHifRxHdr = prSwRfb->prHifRxHdr; -+ prSwRfb->ucStaRecIdx = prHifRxHdr->ucStaRecIdx; -+ prSwRfb->u2SSN = HIF_RX_HDR_GET_SN(prHifRxHdr); /* The new SN of the frame */ -+ prSwRfb->ucTid = (UINT_8) (HIF_RX_HDR_GET_TID(prHifRxHdr)); -+ /* prSwRfb->eDst = RX_PKT_DESTINATION_HOST; */ -+ -+ /* Incorrect STA_REC index */ -+ if (prSwRfb->ucStaRecIdx >= CFG_NUM_OF_STA_RECORD) { -+ prSwRfb->eDst = RX_PKT_DESTINATION_NULL; -+ QUEUE_INSERT_TAIL(prReturnedQue, (P_QUE_ENTRY_T) prSwRfb); -+ DBGLOG(QM, WARN, "Reordering for a NULL STA_REC, ucStaRecIdx = %d\n", prSwRfb->ucStaRecIdx); -+ /* ASSERT(0); */ -+ return; -+ } -+ -+ /* Check whether the STA_REC is activated */ -+ prStaRec = &(prAdapter->arStaRec[prSwRfb->ucStaRecIdx]); -+ ASSERT(prStaRec); -+ -+#if 0 -+ if (!(prStaRec->fgIsValid)) { -+ /* TODO: (Tehuang) Handle the Host-FW sync issue. */ -+ prSwRfb->eDst = RX_PKT_DESTINATION_NULL; -+ QUEUE_INSERT_TAIL(prReturnedQue, (P_QUE_ENTRY_T) prSwRfb); -+ DBGLOG(QM, WARN, "Reordering for an invalid STA_REC\n"); -+ /* ASSERT(0); */ -+ return; -+ } -+#endif -+ -+ /* Check whether the BA agreement exists */ -+ prReorderQueParm = ((prStaRec->aprRxReorderParamRefTbl)[prSwRfb->ucTid]); -+ if (!prReorderQueParm) { -+ /* TODO: (Tehuang) Handle the Host-FW sync issue. */ -+ prSwRfb->eDst = RX_PKT_DESTINATION_NULL; -+ QUEUE_INSERT_TAIL(prReturnedQue, (P_QUE_ENTRY_T) prSwRfb); -+ DBGLOG(QM, WARN, "Reordering for a NULL ReorderQueParm\n"); -+ /* ASSERT(0); */ -+ return; -+ } -+ -+ /* Start to reorder packets */ -+ u4SeqNo = (UINT_32) (prSwRfb->u2SSN); -+ prReorderQue = &(prReorderQueParm->rReOrderQue); -+ u4WinStart = (UINT_32) (prReorderQueParm->u2WinStart); -+ u4WinEnd = (UINT_32) (prReorderQueParm->u2WinEnd); -+ -+ /* Debug */ -+ /* DbgPrint("QM:(R)[%d](%ld){%ld,%ld}\n", prSwRfb->ucTid, u4SeqNo, u4WinStart, u4WinEnd); */ -+ -+ /* Case 1: Fall within */ -+ if /* 0 - start - sn - end - 4095 */ -+ (((u4WinStart <= u4SeqNo) && (u4SeqNo <= u4WinEnd)) -+ /* 0 - end - start - sn - 4095 */ -+ || ((u4WinEnd < u4WinStart) && (u4WinStart <= u4SeqNo)) -+ /* 0 - sn - end - start - 4095 */ -+ || ((u4SeqNo <= u4WinEnd) && (u4WinEnd < u4WinStart))) { -+ -+ qmInsertFallWithinReorderPkt(prSwRfb, prReorderQueParm, prReturnedQue); -+ -+#if QM_RX_WIN_SSN_AUTO_ADVANCING -+ if (prReorderQueParm->fgIsWaitingForPktWithSsn) { -+ /* Let the first received packet pass the reorder check */ -+ DBGLOG(QM, LOUD, "QM:(A)[%d](%u){%u,%u}\n", prSwRfb->ucTid, u4SeqNo, u4WinStart, u4WinEnd); -+ -+ prReorderQueParm->u2WinStart = (UINT_16) u4SeqNo; -+ prReorderQueParm->u2WinEnd = -+ ((prReorderQueParm->u2WinStart) + (prReorderQueParm->u2WinSize) - 1) % MAX_SEQ_NO_COUNT; -+ prReorderQueParm->fgIsWaitingForPktWithSsn = FALSE; -+ } -+#endif -+ -+ if (qmPopOutDueToFallWithin(prReorderQueParm, prReturnedQue, &fgIsBaTimeout) == FALSE) -+ STATS_RX_REORDER_HOLE_INC(prStaRec); /* record hole count */ -+ STATS_RX_REORDER_HOLE_TIMEOUT_INC(prStaRec, fgIsBaTimeout); -+ } -+ /* Case 2: Fall ahead */ -+ else if -+ /* 0 - start - end - sn - (start+2048) - 4095 */ -+ (((u4WinStart < u4WinEnd) -+ && (u4WinEnd < u4SeqNo) -+ && (u4SeqNo < (u4WinStart + HALF_SEQ_NO_COUNT))) -+ /* 0 - sn - (start+2048) - start - end - 4095 */ -+ || ((u4SeqNo < u4WinStart) -+ && (u4WinStart < u4WinEnd) -+ && ((u4SeqNo + MAX_SEQ_NO_COUNT) < (u4WinStart + HALF_SEQ_NO_COUNT))) -+ /* 0 - end - sn - (start+2048) - start - 4095 */ -+ || ((u4WinEnd < u4SeqNo) -+ && (u4SeqNo < u4WinStart) -+ && ((u4SeqNo + MAX_SEQ_NO_COUNT) < (u4WinStart + HALF_SEQ_NO_COUNT)))) { -+ -+#if QM_RX_WIN_SSN_AUTO_ADVANCING -+ if (prReorderQueParm->fgIsWaitingForPktWithSsn) -+ prReorderQueParm->fgIsWaitingForPktWithSsn = FALSE; -+#endif -+ -+ qmInsertFallAheadReorderPkt(prSwRfb, prReorderQueParm, prReturnedQue); -+ -+ /* Advance the window after inserting a new tail */ -+ prReorderQueParm->u2WinEnd = (UINT_16) u4SeqNo; -+ prReorderQueParm->u2WinStart = -+ (((prReorderQueParm->u2WinEnd) - (prReorderQueParm->u2WinSize) + MAX_SEQ_NO_COUNT + 1) -+ % MAX_SEQ_NO_COUNT); -+ -+ qmPopOutDueToFallAhead(prReorderQueParm, prReturnedQue); -+ -+ STATS_RX_REORDER_FALL_AHEAD_INC(prStaRec); -+ -+ } -+ /* Case 3: Fall behind */ -+ else { -+ -+#if QM_RX_WIN_SSN_AUTO_ADVANCING -+#if QM_RX_INIT_FALL_BEHIND_PASS -+ if (prReorderQueParm->fgIsWaitingForPktWithSsn) { -+ /* ?? prSwRfb->eDst = RX_PKT_DESTINATION_HOST; */ -+ QUEUE_INSERT_TAIL(prReturnedQue, (P_QUE_ENTRY_T) prSwRfb); -+ /* DbgPrint("QM:(P)[%d](%ld){%ld,%ld}\n", prSwRfb->ucTid, u4SeqNo, u4WinStart, u4WinEnd); */ -+ return; -+ } -+#endif -+#endif -+ -+ STATS_RX_REORDER_FALL_BEHIND_INC(prStaRec); -+ /* An erroneous packet */ -+ prSwRfb->eDst = RX_PKT_DESTINATION_NULL; -+ QUEUE_INSERT_TAIL(prReturnedQue, (P_QUE_ENTRY_T) prSwRfb); -+ /* DbgPrint("QM:(D)[%d](%ld){%ld,%ld}\n", prSwRfb->ucTid, u4SeqNo, u4WinStart, u4WinEnd); */ -+ return; -+ } -+ -+ return; -+ -+} -+ -+VOID qmProcessBarFrame(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, OUT P_QUE_T prReturnedQue) -+{ -+ -+ P_STA_RECORD_T prStaRec; -+ P_HIF_RX_HEADER_T prHifRxHdr; -+ P_RX_BA_ENTRY_T prReorderQueParm; -+ -+ UINT_32 u4SSN; -+ UINT_32 u4WinStart; -+ UINT_32 u4WinEnd; -+ P_QUE_T prReorderQue; -+ /* P_SW_RFB_T prReorderedSwRfb; */ -+ -+ if ((prSwRfb == NULL) || (prReturnedQue == NULL) || (prSwRfb->prHifRxHdr == NULL)) { -+ ASSERT(FALSE); -+ return; -+ } -+ -+ prHifRxHdr = prSwRfb->prHifRxHdr; -+ prSwRfb->ucStaRecIdx = prHifRxHdr->ucStaRecIdx; -+ prSwRfb->u2SSN = HIF_RX_HDR_GET_SN(prHifRxHdr); /* The new SSN */ -+ prSwRfb->ucTid = (UINT_8) (HIF_RX_HDR_GET_TID(prHifRxHdr)); -+ -+ prSwRfb->eDst = RX_PKT_DESTINATION_NULL; -+ QUEUE_INSERT_TAIL(prReturnedQue, (P_QUE_ENTRY_T) prSwRfb); -+ -+ /* Incorrect STA_REC index */ -+ if (prSwRfb->ucStaRecIdx >= CFG_NUM_OF_STA_RECORD) { -+ DBGLOG(QM, WARN, "QM: (Warning) BAR for a NULL STA_REC, ucStaRecIdx = %d\n", prSwRfb->ucStaRecIdx); -+ /* ASSERT(0); */ -+ return; -+ } -+ -+ /* Check whether the STA_REC is activated */ -+ prStaRec = &(prAdapter->arStaRec[prSwRfb->ucStaRecIdx]); -+ ASSERT(prStaRec); -+ -+#if 0 -+ if (!(prStaRec->fgIsValid)) { -+ /* TODO: (Tehuang) Handle the Host-FW sync issue. */ -+ DbgPrint("QM: (Warning) BAR for an invalid STA_REC\n"); -+ /* ASSERT(0); */ -+ return; -+ } -+#endif -+ -+ /* Check whether the BA agreement exists */ -+ prReorderQueParm = ((prStaRec->aprRxReorderParamRefTbl)[prSwRfb->ucTid]); -+ if (!prReorderQueParm) { -+ /* TODO: (Tehuang) Handle the Host-FW sync issue. */ -+ DBGLOG(QM, WARN, "QM: (Warning) BAR for a NULL ReorderQueParm\n"); -+ /* ASSERT(0); */ -+ return; -+ } -+ -+ u4SSN = (UINT_32) (prSwRfb->u2SSN); -+ prReorderQue = &(prReorderQueParm->rReOrderQue); -+ u4WinStart = (UINT_32) (prReorderQueParm->u2WinStart); -+ u4WinEnd = (UINT_32) (prReorderQueParm->u2WinEnd); -+ -+ if (qmCompareSnIsLessThan(u4WinStart, u4SSN)) { -+ prReorderQueParm->u2WinStart = (UINT_16) u4SSN; -+ prReorderQueParm->u2WinEnd = -+ ((prReorderQueParm->u2WinStart) + (prReorderQueParm->u2WinSize) - 1) % MAX_SEQ_NO_COUNT; -+ DBGLOG(QM, TRACE, -+ "QM:(BAR)[%d](%u){%d,%d}\n", prSwRfb->ucTid, u4SSN, prReorderQueParm->u2WinStart, -+ prReorderQueParm->u2WinEnd); -+ qmPopOutDueToFallAhead(prReorderQueParm, prReturnedQue); -+ } else { -+ DBGLOG(QM, TRACE, "QM:(BAR)(%d)(%u){%u,%u}\n", prSwRfb->ucTid, u4SSN, u4WinStart, u4WinEnd); -+ } -+} -+ -+VOID qmInsertFallWithinReorderPkt(IN P_SW_RFB_T prSwRfb, IN P_RX_BA_ENTRY_T prReorderQueParm, OUT P_QUE_T prReturnedQue) -+{ -+ P_SW_RFB_T prExaminedQueuedSwRfb; -+ P_QUE_T prReorderQue; -+ -+ ASSERT(prSwRfb); -+ ASSERT(prReorderQueParm); -+ ASSERT(prReturnedQue); -+ -+ prReorderQue = &(prReorderQueParm->rReOrderQue); -+ prExaminedQueuedSwRfb = (P_SW_RFB_T) QUEUE_GET_HEAD(prReorderQue); -+ -+ /* There are no packets queued in the Reorder Queue */ -+ if (prExaminedQueuedSwRfb == NULL) { -+ ((P_QUE_ENTRY_T) prSwRfb)->prPrev = NULL; -+ ((P_QUE_ENTRY_T) prSwRfb)->prNext = NULL; -+ prReorderQue->prHead = (P_QUE_ENTRY_T) prSwRfb; -+ prReorderQue->prTail = (P_QUE_ENTRY_T) prSwRfb; -+ prReorderQue->u4NumElem++; -+ } -+ -+ /* Determine the insert position */ -+ else { -+ do { -+ /* Case 1: Terminate. A duplicate packet */ -+ if (((prExaminedQueuedSwRfb->u2SSN) == (prSwRfb->u2SSN))) { -+ prSwRfb->eDst = RX_PKT_DESTINATION_NULL; -+ QUEUE_INSERT_TAIL(prReturnedQue, (P_QUE_ENTRY_T) prSwRfb); -+ return; -+ } -+ -+ /* Case 2: Terminate. The insert point is found */ -+ else if (qmCompareSnIsLessThan((prSwRfb->u2SSN), (prExaminedQueuedSwRfb->u2SSN))) -+ break; -+ -+ /* Case 3: Insert point not found. Check the next SW_RFB in the Reorder Queue */ -+ else -+ prExaminedQueuedSwRfb = (P_SW_RFB_T) (((P_QUE_ENTRY_T) prExaminedQueuedSwRfb)->prNext); -+ } while (prExaminedQueuedSwRfb); -+ -+ /* Update the Reorder Queue Parameters according to the found insert position */ -+ if (prExaminedQueuedSwRfb == NULL) { -+ /* The received packet shall be placed at the tail */ -+ ((P_QUE_ENTRY_T) prSwRfb)->prPrev = prReorderQue->prTail; -+ ((P_QUE_ENTRY_T) prSwRfb)->prNext = NULL; -+ (prReorderQue->prTail)->prNext = (P_QUE_ENTRY_T) (prSwRfb); -+ prReorderQue->prTail = (P_QUE_ENTRY_T) (prSwRfb); -+ } else { -+ ((P_QUE_ENTRY_T) prSwRfb)->prPrev = ((P_QUE_ENTRY_T) prExaminedQueuedSwRfb)->prPrev; -+ ((P_QUE_ENTRY_T) prSwRfb)->prNext = (P_QUE_ENTRY_T) prExaminedQueuedSwRfb; -+ if (((P_QUE_ENTRY_T) prExaminedQueuedSwRfb) == (prReorderQue->prHead)) { -+ /* The received packet will become the head */ -+ prReorderQue->prHead = (P_QUE_ENTRY_T) prSwRfb; -+ } else { -+ (((P_QUE_ENTRY_T) prExaminedQueuedSwRfb)->prPrev)->prNext = (P_QUE_ENTRY_T) prSwRfb; -+ } -+ ((P_QUE_ENTRY_T) prExaminedQueuedSwRfb)->prPrev = (P_QUE_ENTRY_T) prSwRfb; -+ } -+ -+ prReorderQue->u4NumElem++; -+ -+ } -+ -+} -+ -+VOID qmInsertFallAheadReorderPkt(IN P_SW_RFB_T prSwRfb, IN P_RX_BA_ENTRY_T prReorderQueParm, OUT P_QUE_T prReturnedQue) -+{ -+ P_QUE_T prReorderQue; -+ -+ ASSERT(prSwRfb); -+ ASSERT(prReorderQueParm); -+ ASSERT(prReturnedQue); -+ -+ prReorderQue = &(prReorderQueParm->rReOrderQue); -+ -+ /* There are no packets queued in the Reorder Queue */ -+ if (QUEUE_IS_EMPTY(prReorderQue)) { -+ ((P_QUE_ENTRY_T) prSwRfb)->prPrev = NULL; -+ ((P_QUE_ENTRY_T) prSwRfb)->prNext = NULL; -+ prReorderQue->prHead = (P_QUE_ENTRY_T) prSwRfb; -+ } else { -+ ((P_QUE_ENTRY_T) prSwRfb)->prPrev = prReorderQue->prTail; -+ ((P_QUE_ENTRY_T) prSwRfb)->prNext = NULL; -+ (prReorderQue->prTail)->prNext = (P_QUE_ENTRY_T) (prSwRfb); -+ } -+ prReorderQue->prTail = (P_QUE_ENTRY_T) prSwRfb; -+ prReorderQue->u4NumElem++; -+ -+} -+ -+BOOLEAN -+qmPopOutDueToFallWithin(IN P_RX_BA_ENTRY_T prReorderQueParm, OUT P_QUE_T prReturnedQue, OUT BOOLEAN *fgIsTimeout) -+{ -+ P_SW_RFB_T prReorderedSwRfb; -+ P_QUE_T prReorderQue; -+ BOOLEAN fgDequeuHead, fgMissing; -+ OS_SYSTIME rCurrentTime, *prMissTimeout; -+ -+ prReorderQue = &(prReorderQueParm->rReOrderQue); -+ -+ *fgIsTimeout = FALSE; -+ fgMissing = FALSE; -+ rCurrentTime = 0; -+ prMissTimeout = &(g_arMissTimeout[prReorderQueParm->ucStaRecIdx][prReorderQueParm->ucTid]); -+ if ((*prMissTimeout)) { -+ fgMissing = TRUE; -+ GET_CURRENT_SYSTIME(&rCurrentTime); -+ } -+ -+ /* Check whether any packet can be indicated to the higher layer */ -+ while (TRUE) { -+ if (QUEUE_IS_EMPTY(prReorderQue)) -+ break; -+ -+ /* Always examine the head packet */ -+ prReorderedSwRfb = (P_SW_RFB_T) QUEUE_GET_HEAD(prReorderQue); -+ fgDequeuHead = FALSE; -+ -+ /* SN == WinStart, so the head packet shall be indicated (advance the window) */ -+ if ((prReorderedSwRfb->u2SSN) == (prReorderQueParm->u2WinStart)) { -+ -+ fgDequeuHead = TRUE; -+ prReorderQueParm->u2WinStart = (((prReorderedSwRfb->u2SSN) + 1) % MAX_SEQ_NO_COUNT); -+ } -+ /* SN > WinStart, break to update WinEnd */ -+ else { -+ if ((fgMissing == TRUE) && -+ CHECK_FOR_TIMEOUT(rCurrentTime, (*prMissTimeout), -+ MSEC_TO_SYSTIME(QM_RX_BA_ENTRY_MISS_TIMEOUT_MS))) { -+ DBGLOG(QM, TRACE, -+ "QM:RX BA Timout Next Tid %d SSN %d\n", prReorderQueParm->ucTid, -+ prReorderedSwRfb->u2SSN); -+ fgDequeuHead = TRUE; -+ prReorderQueParm->u2WinStart = (((prReorderedSwRfb->u2SSN) + 1) % MAX_SEQ_NO_COUNT); -+ -+ fgMissing = FALSE; -+ *fgIsTimeout = TRUE; -+ } else -+ break; -+ } -+ -+ /* Dequeue the head packet */ -+ if (fgDequeuHead) { -+ -+ if (((P_QUE_ENTRY_T) prReorderedSwRfb)->prNext == NULL) { -+ prReorderQue->prHead = NULL; -+ prReorderQue->prTail = NULL; -+ } else { -+ prReorderQue->prHead = ((P_QUE_ENTRY_T) prReorderedSwRfb)->prNext; -+ (((P_QUE_ENTRY_T) prReorderedSwRfb)->prNext)->prPrev = NULL; -+ } -+ prReorderQue->u4NumElem--; -+ /* DbgPrint("QM: [%d] %d (%d)\n", -+ prReorderQueParm->ucTid, -+ prReorderedSwRfb->u2PacketLen, -+ prReorderedSwRfb->u2SSN); */ -+ QUEUE_INSERT_TAIL(prReturnedQue, (P_QUE_ENTRY_T) prReorderedSwRfb); -+ } -+ } -+ -+ if (QUEUE_IS_EMPTY(prReorderQue)) -+ *prMissTimeout = 0; -+ else { -+ if (fgMissing == FALSE) -+ GET_CURRENT_SYSTIME(prMissTimeout); -+ } -+ -+ /* After WinStart has been determined, update the WinEnd */ -+ prReorderQueParm->u2WinEnd = -+ (((prReorderQueParm->u2WinStart) + (prReorderQueParm->u2WinSize) - 1) % MAX_SEQ_NO_COUNT); -+ return QUEUE_IS_EMPTY(prReorderQue); -+} -+ -+VOID qmPopOutDueToFallAhead(IN P_RX_BA_ENTRY_T prReorderQueParm, OUT P_QUE_T prReturnedQue) -+{ -+ P_SW_RFB_T prReorderedSwRfb; -+ P_QUE_T prReorderQue; -+ BOOLEAN fgDequeuHead; -+ -+ prReorderQue = &(prReorderQueParm->rReOrderQue); -+ -+ /* Check whether any packet can be indicated to the higher layer */ -+ while (TRUE) { -+ if (QUEUE_IS_EMPTY(prReorderQue)) -+ break; -+ -+ /* Always examine the head packet */ -+ prReorderedSwRfb = (P_SW_RFB_T) QUEUE_GET_HEAD(prReorderQue); -+ fgDequeuHead = FALSE; -+ -+ /* SN == WinStart, so the head packet shall be indicated (advance the window) */ -+ if ((prReorderedSwRfb->u2SSN) == (prReorderQueParm->u2WinStart)) { -+ -+ fgDequeuHead = TRUE; -+ prReorderQueParm->u2WinStart = (((prReorderedSwRfb->u2SSN) + 1) % MAX_SEQ_NO_COUNT); -+ } -+ -+ /* SN < WinStart, so the head packet shall be indicated (do not advance the window) */ -+ else if (qmCompareSnIsLessThan((UINT_32) (prReorderedSwRfb->u2SSN), -+ (UINT_32) (prReorderQueParm->u2WinStart))) -+ fgDequeuHead = TRUE; -+ -+ /* SN > WinStart, break to update WinEnd */ -+ else -+ break; -+ -+ /* Dequeue the head packet */ -+ if (fgDequeuHead) { -+ -+ if (((P_QUE_ENTRY_T) prReorderedSwRfb)->prNext == NULL) { -+ prReorderQue->prHead = NULL; -+ prReorderQue->prTail = NULL; -+ } else { -+ prReorderQue->prHead = ((P_QUE_ENTRY_T) prReorderedSwRfb)->prNext; -+ (((P_QUE_ENTRY_T) prReorderedSwRfb)->prNext)->prPrev = NULL; -+ } -+ prReorderQue->u4NumElem--; -+ /* DbgPrint("QM: [%d] %d (%d)\n", */ -+ /* prReorderQueParm->ucTid, prReorderedSwRfb->u2PacketLen, prReorderedSwRfb->u2SSN); */ -+ QUEUE_INSERT_TAIL(prReturnedQue, (P_QUE_ENTRY_T) prReorderedSwRfb); -+ } -+ } -+ -+ /* After WinStart has been determined, update the WinEnd */ -+ prReorderQueParm->u2WinEnd = -+ (((prReorderQueParm->u2WinStart) + (prReorderQueParm->u2WinSize) - 1) % MAX_SEQ_NO_COUNT); -+ -+} -+ -+BOOLEAN qmCompareSnIsLessThan(IN UINT_32 u4SnLess, IN UINT_32 u4SnGreater) -+{ -+ /* 0 <---> SnLess <--(gap>2048)--> SnGreater : SnLess > SnGreater */ -+ if ((u4SnLess + HALF_SEQ_NO_COUNT) <= u4SnGreater) /* Shall be <= */ -+ return FALSE; -+ -+ /* 0 <---> SnGreater <--(gap>2048)--> SnLess : SnLess < SnGreater */ -+ else if ((u4SnGreater + HALF_SEQ_NO_COUNT) < u4SnLess) -+ return TRUE; -+ -+ /* 0 <---> SnGreater <--(gap<2048)--> SnLess : SnLess > SnGreater */ -+ /* 0 <---> SnLess <--(gap<2048)--> SnGreater : SnLess < SnGreater */ -+ else if (u4SnLess < u4SnGreater) -+ return TRUE; -+ else -+ return FALSE; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Handle Mailbox RX messages -+* -+* \param[in] prMailboxRxMsg The received Mailbox message from the FW -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID qmHandleMailboxRxMessage(IN MAILBOX_MSG_T prMailboxRxMsg) -+{ -+ /* DbgPrint("QM: Enter qmHandleMailboxRxMessage()\n"); */ -+ /* TODO */ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Handle ADD RX BA Event from the FW -+* -+* \param[in] prAdapter Adapter pointer -+* \param[in] prEvent The event packet from the FW -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID qmHandleEventRxAddBa(IN P_ADAPTER_T prAdapter, IN P_WIFI_EVENT_T prEvent) -+{ -+ P_EVENT_RX_ADDBA_T prEventRxAddBa; -+ P_STA_RECORD_T prStaRec; -+ UINT_32 u4Tid; -+ UINT_32 u4WinSize; -+ -+ DBGLOG(QM, INFO, "QM:Event +RxBa\n"); -+ -+ prEventRxAddBa = (P_EVENT_RX_ADDBA_T) prEvent; -+ prStaRec = QM_GET_STA_REC_PTR_FROM_INDEX(prAdapter, prEventRxAddBa->ucStaRecIdx); -+ -+ if (!prStaRec) { -+ /* Invalid STA_REC index, discard the event packet */ -+ /* ASSERT(0); */ -+ DBGLOG(QM, WARN, "QM: (Warning) RX ADDBA Event for a NULL STA_REC\n"); -+ return; -+ } -+#if 0 -+ if (!(prStaRec->fgIsValid)) { -+ /* TODO: (Tehuang) Handle the Host-FW synchronization issue */ -+ DBGLOG(QM, WARN, "QM: (Warning) RX ADDBA Event for an invalid STA_REC\n"); -+ /* ASSERT(0); */ -+ /* return; */ -+ } -+#endif -+ -+ u4Tid = (((prEventRxAddBa->u2BAParameterSet) & BA_PARAM_SET_TID_MASK) -+ >> BA_PARAM_SET_TID_MASK_OFFSET); -+ -+ u4WinSize = (((prEventRxAddBa->u2BAParameterSet) & BA_PARAM_SET_BUFFER_SIZE_MASK) -+ >> BA_PARAM_SET_BUFFER_SIZE_MASK_OFFSET); -+ -+ if (!qmAddRxBaEntry(prAdapter, -+ prStaRec->ucIndex, -+ (UINT_8) u4Tid, -+ (prEventRxAddBa->u2BAStartSeqCtrl >> OFFSET_BAR_SSC_SN), (UINT_16) u4WinSize)) { -+ -+ /* FW shall ensure the availabiilty of the free-to-use BA entry */ -+ DBGLOG(QM, ERROR, "QM: (Error) qmAddRxBaEntry() failure\n"); -+ ASSERT(0); -+ } -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Handle DEL RX BA Event from the FW -+* -+* \param[in] prAdapter Adapter pointer -+* \param[in] prEvent The event packet from the FW -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID qmHandleEventRxDelBa(IN P_ADAPTER_T prAdapter, IN P_WIFI_EVENT_T prEvent) -+{ -+ P_EVENT_RX_DELBA_T prEventRxDelBa; -+ P_STA_RECORD_T prStaRec; -+ -+ /* DbgPrint("QM:Event -RxBa\n"); */ -+ -+ prEventRxDelBa = (P_EVENT_RX_DELBA_T) prEvent; -+ prStaRec = QM_GET_STA_REC_PTR_FROM_INDEX(prAdapter, prEventRxDelBa->ucStaRecIdx); -+ -+ if (!prStaRec) -+ /* Invalid STA_REC index, discard the event packet */ -+ /* ASSERT(0); */ -+ return; -+#if 0 -+ if (!(prStaRec->fgIsValid)) -+ /* TODO: (Tehuang) Handle the Host-FW synchronization issue */ -+ /* ASSERT(0); */ -+ return; -+#endif -+ -+ qmDelRxBaEntry(prAdapter, prStaRec->ucIndex, prEventRxDelBa->ucTid, TRUE); -+ -+} -+ -+P_RX_BA_ENTRY_T qmLookupRxBaEntry(IN P_ADAPTER_T prAdapter, UINT_8 ucStaRecIdx, UINT_8 ucTid) -+{ -+ int i; -+ P_QUE_MGT_T prQM = &prAdapter->rQM; -+ -+ /* DbgPrint("QM: Enter qmLookupRxBaEntry()\n"); */ -+ -+ for (i = 0; i < CFG_NUM_OF_RX_BA_AGREEMENTS; i++) { -+ if (prQM->arRxBaTable[i].fgIsValid) { -+ if ((prQM->arRxBaTable[i].ucStaRecIdx == ucStaRecIdx) && (prQM->arRxBaTable[i].ucTid == ucTid)) -+ return &prQM->arRxBaTable[i]; -+ } -+ } -+ return NULL; -+} -+ -+BOOLEAN -+qmAddRxBaEntry(IN P_ADAPTER_T prAdapter, -+ IN UINT_8 ucStaRecIdx, IN UINT_8 ucTid, IN UINT_16 u2WinStart, IN UINT_16 u2WinSize) -+{ -+ int i; -+ P_RX_BA_ENTRY_T prRxBaEntry = NULL; -+ P_STA_RECORD_T prStaRec; -+ P_QUE_MGT_T prQM = &prAdapter->rQM; -+ -+ ASSERT(ucStaRecIdx < CFG_NUM_OF_STA_RECORD); -+ -+ if (ucStaRecIdx >= CFG_NUM_OF_STA_RECORD) { -+ /* Invalid STA_REC index, discard the event packet */ -+ DBGLOG(QM, WARN, "QM: (WARNING) RX ADDBA Event for a invalid ucStaRecIdx = %d\n", ucStaRecIdx); -+ return FALSE; -+ } -+ -+ prStaRec = &prAdapter->arStaRec[ucStaRecIdx]; -+ ASSERT(prStaRec); -+ -+ /* if(!(prStaRec->fgIsValid)){ */ -+ /* DbgPrint("QM: (WARNING) Invalid STA when adding an RX BA\n"); */ -+ /* return FALSE; */ -+ /* } */ -+ -+ /* 4 <1> Delete before adding */ -+ /* Remove the BA entry for the same (STA, TID) tuple if it exists */ -+ if (qmLookupRxBaEntry(prAdapter, ucStaRecIdx, ucTid)) -+ qmDelRxBaEntry(prAdapter, ucStaRecIdx, ucTid, TRUE); /* prQM->ucRxBaCount-- */ -+ /* 4 <2> Add a new BA entry */ -+ /* No available entry to store the BA agreement info. Retrun FALSE. */ -+ if (prQM->ucRxBaCount >= CFG_NUM_OF_RX_BA_AGREEMENTS) { -+ DBGLOG(QM, ERROR, "QM: **failure** (limited resource, ucRxBaCount=%d)\n", prQM->ucRxBaCount); -+ return FALSE; -+ } -+ /* Find the free-to-use BA entry */ -+ for (i = 0; i < CFG_NUM_OF_RX_BA_AGREEMENTS; i++) { -+ if (!prQM->arRxBaTable[i].fgIsValid) { -+ prRxBaEntry = &(prQM->arRxBaTable[i]); -+ prQM->ucRxBaCount++; -+ DBGLOG(QM, LOUD, "QM: ucRxBaCount=%d\n", prQM->ucRxBaCount); -+ break; -+ } -+ } -+ /* If a free-to-use entry is found, configure it and associate it with the STA_REC */ -+ u2WinSize += CFG_RX_BA_INC_SIZE; -+ if (prRxBaEntry) { -+ prRxBaEntry->ucStaRecIdx = ucStaRecIdx; -+ prRxBaEntry->ucTid = ucTid; -+ prRxBaEntry->u2WinStart = u2WinStart; -+ prRxBaEntry->u2WinSize = u2WinSize; -+ prRxBaEntry->u2WinEnd = ((u2WinStart + u2WinSize - 1) % MAX_SEQ_NO_COUNT); -+ prRxBaEntry->fgIsValid = TRUE; -+ prRxBaEntry->fgIsWaitingForPktWithSsn = TRUE; -+ -+ g_arMissTimeout[ucStaRecIdx][ucTid] = 0; -+ -+ DBGLOG(QM, INFO, "QM: +RxBA(STA=%d TID=%d WinStart=%d WinEnd=%d WinSize=%d)\n", -+ ucStaRecIdx, ucTid, -+ prRxBaEntry->u2WinStart, prRxBaEntry->u2WinEnd, prRxBaEntry->u2WinSize); -+ -+ /* Update the BA entry reference table for per-packet lookup */ -+ prStaRec->aprRxReorderParamRefTbl[ucTid] = prRxBaEntry; -+ } else { -+ /* This shall not happen because FW should keep track of the usage of RX BA entries */ -+ DBGLOG(QM, ERROR, "QM: **AddBA Error** (ucRxBaCount=%d)\n", prQM->ucRxBaCount); -+ return FALSE; -+ } -+ return TRUE; -+} -+ -+VOID qmDelRxBaEntry(IN P_ADAPTER_T prAdapter, IN UINT_8 ucStaRecIdx, IN UINT_8 ucTid, IN BOOLEAN fgFlushToHost) -+{ -+ P_RX_BA_ENTRY_T prRxBaEntry; -+ P_STA_RECORD_T prStaRec; -+ P_SW_RFB_T prFlushedPacketList = NULL; -+ P_QUE_MGT_T prQM = &prAdapter->rQM; -+ -+ ASSERT(ucStaRecIdx < CFG_NUM_OF_STA_RECORD); -+ -+ prStaRec = &prAdapter->arStaRec[ucStaRecIdx]; -+ ASSERT(prStaRec); -+ -+#if 0 -+ if (!(prStaRec->fgIsValid)) { -+ DbgPrint("QM: (WARNING) Invalid STA when deleting an RX BA\n"); -+ return; -+ } -+#endif -+ -+ /* Remove the BA entry for the same (STA, TID) tuple if it exists */ -+ prRxBaEntry = prStaRec->aprRxReorderParamRefTbl[ucTid]; -+ -+ if (prRxBaEntry) { -+ -+ prFlushedPacketList = qmFlushStaRxQueue(prAdapter, ucStaRecIdx, ucTid); -+ -+ if (prFlushedPacketList) { -+ -+ if (fgFlushToHost) { -+ wlanProcessQueuedSwRfb(prAdapter, prFlushedPacketList); -+ } else { -+ -+ P_SW_RFB_T prSwRfb; -+ P_SW_RFB_T prNextSwRfb; -+ -+ prSwRfb = prFlushedPacketList; -+ -+ do { -+ prNextSwRfb = (P_SW_RFB_T) QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T) prSwRfb); -+ nicRxReturnRFB(prAdapter, prSwRfb); -+ prSwRfb = prNextSwRfb; -+ } while (prSwRfb); -+ -+ } -+ -+ } -+#if ((QM_TEST_MODE == 0) && (QM_TEST_STA_REC_DEACTIVATION == 0)) -+ /* Update RX BA entry state. Note that RX queue flush is not done here */ -+ prRxBaEntry->fgIsValid = FALSE; -+ prQM->ucRxBaCount--; -+ -+ /* Debug */ -+#if 0 -+ DbgPrint("QM: ucRxBaCount=%d\n", prQM->ucRxBaCount); -+#endif -+ -+ /* Update STA RX BA table */ -+ prStaRec->aprRxReorderParamRefTbl[ucTid] = NULL; -+#endif -+ -+ DBGLOG(QM, INFO, "QM: -RxBA(STA=%d,TID=%d)\n", ucStaRecIdx, ucTid); -+ -+ } -+ -+ /* Debug */ -+#if CFG_HIF_RX_STARVATION_WARNING -+ { -+ P_RX_CTRL_T prRxCtrl; -+ -+ prRxCtrl = &prAdapter->rRxCtrl; -+ DBGLOG(QM, TRACE, -+ "QM: (RX DEBUG) Enqueued: %d / Dequeued: %d\n", prRxCtrl->u4QueuedCnt, -+ prRxCtrl->u4DequeuedCnt); -+ } -+#endif -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief To process WMM related IEs in ASSOC_RSP -+* -+* \param[in] prAdapter Adapter pointer -+* \param[in] prSwRfb The received frame -+* \param[in] pucIE The pointer to the first IE in the frame -+* \param[in] u2IELength The total length of IEs in the frame -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID mqmProcessAssocReq(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, IN PUINT_8 pucIE, IN UINT_16 u2IELength) -+{ -+ P_STA_RECORD_T prStaRec; -+ UINT_16 u2Offset; -+ PUINT_8 pucIEStart; -+ UINT_8 aucWfaOui[] = VENDOR_OUI_WFA; -+ P_IE_WMM_INFO_T prIeWmmInfo; -+ UINT_8 ucQosInfo; -+ UINT_8 ucQosInfoAC; -+ UINT_8 ucBmpAC; -+ -+ DEBUGFUNC("mqmProcessAssocReq"); -+ -+ ASSERT(prSwRfb); -+ ASSERT(pucIE); -+ -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); -+ ASSERT(prStaRec); -+ -+ if (prStaRec == NULL) -+ return; -+ -+ prStaRec->fgIsQoS = FALSE; -+ prStaRec->fgIsWmmSupported = prStaRec->fgIsUapsdSupported = FALSE; -+ -+ pucIEStart = pucIE; -+ -+ /* If the device does not support QoS or if WMM is not supported by the peer, exit. */ -+ if (!prAdapter->rWifiVar.fgSupportQoS) -+ return; -+ -+ /* Determine whether QoS is enabled with the association */ -+ IE_FOR_EACH(pucIE, u2IELength, u2Offset) { -+ switch (IE_ID(pucIE)) { -+ case ELEM_ID_WMM: -+ -+ if ((WMM_IE_OUI_TYPE(pucIE) == VENDOR_OUI_TYPE_WMM) && -+ (!kalMemCmp(WMM_IE_OUI(pucIE), aucWfaOui, 3))) { -+ switch (WMM_IE_OUI_SUBTYPE(pucIE)) { -+ case VENDOR_OUI_SUBTYPE_WMM_INFO: -+ if (IE_LEN(pucIE) != 7) -+ break; /* WMM Info IE with a wrong length */ -+ prStaRec->fgIsQoS = TRUE; -+ prStaRec->fgIsWmmSupported = TRUE; -+ -+ prIeWmmInfo = (P_IE_WMM_INFO_T) pucIE; -+ ucQosInfo = prIeWmmInfo->ucQosInfo; -+ ucQosInfoAC = ucQosInfo & BITS(0, 3); -+ -+ prStaRec->fgIsUapsdSupported = ((ucQosInfoAC) ? TRUE : FALSE) & -+ prAdapter->rWifiVar.fgSupportUAPSD; -+ -+ ucBmpAC = 0; -+ -+ if (ucQosInfoAC & WMM_QOS_INFO_VO_UAPSD) -+ ucBmpAC |= BIT(ACI_VO); -+ if (ucQosInfoAC & WMM_QOS_INFO_VI_UAPSD) -+ ucBmpAC |= BIT(ACI_VI); -+ if (ucQosInfoAC & WMM_QOS_INFO_BE_UAPSD) -+ ucBmpAC |= BIT(ACI_BE); -+ if (ucQosInfoAC & WMM_QOS_INFO_BK_UAPSD) -+ ucBmpAC |= BIT(ACI_BK); -+ -+ prStaRec->ucBmpTriggerAC = prStaRec->ucBmpDeliveryAC = ucBmpAC; -+ -+ prStaRec->ucUapsdSp = -+ (ucQosInfo & WMM_QOS_INFO_MAX_SP_LEN_MASK) >> 5; -+ break; -+ default: -+ /* Other WMM QoS IEs. Ignore any */ -+ break; -+ } -+ } -+ /* else: VENDOR_OUI_TYPE_WPA, VENDOR_OUI_TYPE_WPS */ -+ -+ break; -+ -+ case ELEM_ID_HT_CAP: -+ /* Some client won't put the WMM IE if client is 802.11n */ -+ if (IE_LEN(pucIE) == (sizeof(IE_HT_CAP_T) - 2)) -+ prStaRec->fgIsQoS = TRUE; -+ break; -+ default: -+ break; -+ } -+ } -+ -+ DBGLOG(QM, TRACE, "MQM: Assoc_Req Parsing (QoS Enabled=%d)\n", prStaRec->fgIsQoS); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief To process WMM related IEs in ASSOC_RSP -+* -+* \param[in] prAdapter Adapter pointer -+* \param[in] prSwRfb The received frame -+* \param[in] pucIE The pointer to the first IE in the frame -+* \param[in] u2IELength The total length of IEs in the frame -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID mqmProcessAssocRsp(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb, IN PUINT_8 pucIE, IN UINT_16 u2IELength) -+{ -+ P_STA_RECORD_T prStaRec; -+ UINT_16 u2Offset; -+ PUINT_8 pucIEStart; -+ UINT_8 aucWfaOui[] = VENDOR_OUI_WFA; -+ -+ DEBUGFUNC("mqmProcessAssocRsp"); -+ -+ ASSERT(prSwRfb); -+ ASSERT(pucIE); -+ -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); -+ ASSERT(prStaRec); -+ -+ if (prStaRec == NULL) -+ return; -+ -+ prStaRec->fgIsQoS = FALSE; -+ -+ pucIEStart = pucIE; -+ -+ DBGLOG(QM, TRACE, "QM: (fgIsWmmSupported=%d, fgSupportQoS=%d)\n", -+ prStaRec->fgIsWmmSupported, prAdapter->rWifiVar.fgSupportQoS); -+ -+ /* If the device does not support QoS or if WMM is not supported by the peer, exit. */ -+ /* if((!prAdapter->rWifiVar.fgSupportQoS) || (!prStaRec->fgIsWmmSupported)) */ -+ if ((!prAdapter->rWifiVar.fgSupportQoS)) -+ return; -+ -+ /* Determine whether QoS is enabled with the association */ -+ IE_FOR_EACH(pucIE, u2IELength, u2Offset) { -+ switch (IE_ID(pucIE)) { -+ case ELEM_ID_WMM: -+ if ((WMM_IE_OUI_TYPE(pucIE) == VENDOR_OUI_TYPE_WMM) && -+ (!kalMemCmp(WMM_IE_OUI(pucIE), aucWfaOui, 3))) { -+ -+ switch (WMM_IE_OUI_SUBTYPE(pucIE)) { -+ case VENDOR_OUI_SUBTYPE_WMM_PARAM: -+ if (IE_LEN(pucIE) != 24) -+ break; /* WMM Info IE with a wrong length */ -+ prStaRec->fgIsQoS = TRUE; -+ break; -+ -+ case VENDOR_OUI_SUBTYPE_WMM_INFO: -+ if (IE_LEN(pucIE) != 7) -+ break; /* WMM Info IE with a wrong length */ -+ prStaRec->fgIsQoS = TRUE; -+ break; -+ -+ default: -+ /* Other WMM QoS IEs. Ignore any */ -+ break; -+ } -+ } -+ /* else: VENDOR_OUI_TYPE_WPA, VENDOR_OUI_TYPE_WPS */ -+ break; -+ -+ case ELEM_ID_HT_CAP: -+ /* Some AP won't put the WMM IE if client is 802.11n */ -+ if (IE_LEN(pucIE) == (sizeof(IE_HT_CAP_T) - 2)) -+ prStaRec->fgIsQoS = TRUE; -+ break; -+ default: -+ break; -+ } -+ } -+ -+ /* Parse AC parameters and write to HW CRs */ -+ if ((prStaRec->fgIsQoS) && (prStaRec->eStaType == STA_TYPE_LEGACY_AP)) { -+ mqmParseEdcaParameters(prAdapter, prSwRfb, pucIEStart, u2IELength, TRUE); -+#if ARP_MONITER_ENABLE -+ qmResetArpDetect(); -+#endif -+ } -+ -+ DBGLOG(QM, TRACE, "MQM: Assoc_Rsp Parsing (QoS Enabled=%d)\n", prStaRec->fgIsQoS); -+ if (prStaRec->fgIsWmmSupported) -+ nicQmUpdateWmmParms(prAdapter, prStaRec->ucNetTypeIndex); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief To parse WMM Parameter IE (in BCN or Assoc_Rsp) -+* -+* \param[in] prAdapter Adapter pointer -+* \param[in] prSwRfb The received frame -+* \param[in] pucIE The pointer to the first IE in the frame -+* \param[in] u2IELength The total length of IEs in the frame -+* \param[in] fgForceOverride TRUE: If EDCA parameters are found, always set to HW CRs. -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+mqmParseEdcaParameters(IN P_ADAPTER_T prAdapter, -+ IN P_SW_RFB_T prSwRfb, IN PUINT_8 pucIE, IN UINT_16 u2IELength, IN BOOLEAN fgForceOverride) -+{ -+ P_STA_RECORD_T prStaRec; -+ UINT_16 u2Offset; -+ UINT_8 aucWfaOui[] = VENDOR_OUI_WFA; -+ P_BSS_INFO_T prBssInfo; -+ P_AC_QUE_PARMS_T prAcQueParams; -+ P_IE_WMM_PARAM_T prIeWmmParam; -+ ENUM_WMM_ACI_T eAci; -+ PUINT_8 pucWmmParamSetCount; -+ -+ DEBUGFUNC("mqmParseEdcaParameters"); -+ -+ ASSERT(prSwRfb); -+ ASSERT(pucIE); -+ -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); -+ ASSERT(prStaRec); -+ if (prStaRec == NULL) -+ return; -+ -+ DBGLOG(QM, TRACE, "QM: (fgIsWmmSupported=%d, fgIsQoS=%d)\n", prStaRec->fgIsWmmSupported, prStaRec->fgIsQoS); -+ -+ if ((!prAdapter->rWifiVar.fgSupportQoS) || (!prStaRec->fgIsWmmSupported) || (!prStaRec->fgIsQoS)) -+ return; -+ -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]); -+ -+ /* Goal: Obtain the EDCA parameters */ -+ IE_FOR_EACH(pucIE, u2IELength, u2Offset) { -+ switch (IE_ID(pucIE)) { -+ case ELEM_ID_WMM: -+ if ((WMM_IE_OUI_TYPE(pucIE) != VENDOR_OUI_TYPE_WMM) || -+ (kalMemCmp(WMM_IE_OUI(pucIE), aucWfaOui, 3))) -+ break; -+ -+ switch (WMM_IE_OUI_SUBTYPE(pucIE)) { -+ case VENDOR_OUI_SUBTYPE_WMM_PARAM: -+ if (IE_LEN(pucIE) != 24) -+ break; /* WMM Param IE with a wrong length */ -+ -+ pucWmmParamSetCount = &(prBssInfo->ucWmmParamSetCount); -+ prIeWmmParam = (P_IE_WMM_PARAM_T) pucIE; -+ -+ /* Check the Parameter Set Count to determine whether EDCA parameters */ -+ /* have been changed */ -+ if (!fgForceOverride && (*pucWmmParamSetCount -+ == (prIeWmmParam->ucQosInfo & WMM_QOS_INFO_PARAM_SET_CNT))) -+ break; /* Ignore the IE without updating HW CRs */ -+ -+ /* Update Parameter Set Count */ -+ *pucWmmParamSetCount = -+ (prIeWmmParam->ucQosInfo & WMM_QOS_INFO_PARAM_SET_CNT); -+ -+ /* Update EDCA parameters */ -+ for (eAci = 0; eAci < WMM_AC_INDEX_NUM; eAci++) { -+ -+ prAcQueParams = &prBssInfo->arACQueParms[eAci]; -+ mqmFillAcQueParam(prIeWmmParam, eAci, prAcQueParams); -+ -+ prAcQueParams->fgIsACMSet = -+ (prAcQueParams->u2Aifsn & WMM_ACIAIFSN_ACM) ? TRUE : FALSE; -+ prAcQueParams->u2Aifsn &= WMM_ACIAIFSN_AIFSN; -+ -+ DBGLOG(QM, LOUD, -+ "eAci:%d, ACM:%d, Aifsn:%d, CWmin:%d, CWmax:%d, TxopLmt:%d\n", -+ eAci, prAcQueParams->fgIsACMSet, prAcQueParams->u2Aifsn, -+ prAcQueParams->u2CWmin, prAcQueParams->u2CWmax, -+ prAcQueParams->u2TxopLimit); -+ } -+ break; -+ default: -+ /* Other WMM QoS IEs. Ignore */ -+ break; -+ } -+ -+ /* else: VENDOR_OUI_TYPE_WPA, VENDOR_OUI_TYPE_WPS, ... (not cared) */ -+ break; -+ default: -+ break; -+ } -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is used for parsing EDCA parameters specified in the WMM Parameter IE -+* -+* \param[in] prAdapter Adapter pointer -+* \param[in] prIeWmmParam The pointer to the WMM Parameter IE -+* \param[in] u4AcOffset The offset specifying the AC queue for parsing -+* \param[in] prHwAcParams The parameter structure used to configure the HW CRs -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID mqmFillAcQueParam(IN P_IE_WMM_PARAM_T prIeWmmParam, IN UINT_32 u4AcOffset, OUT P_AC_QUE_PARMS_T prAcQueParams) -+{ -+ prAcQueParams->u2Aifsn = *((PUINT_8) (&(prIeWmmParam->ucAciAifsn_BE)) + (u4AcOffset * 4)); -+ -+ prAcQueParams->u2CWmax = BIT(((*((PUINT_8) (&(prIeWmmParam->ucEcw_BE)) + (u4AcOffset * 4))) & WMM_ECW_WMAX_MASK) -+ >> WMM_ECW_WMAX_OFFSET) - 1; -+ -+ prAcQueParams->u2CWmin = -+ BIT((*((PUINT_8) (&(prIeWmmParam->ucEcw_BE)) + (u4AcOffset * 4))) & WMM_ECW_WMIN_MASK) - 1; -+ -+ WLAN_GET_FIELD_16(((PUINT_8) (&(prIeWmmParam->aucTxopLimit_BE)) + (u4AcOffset * 4)), -+ &(prAcQueParams->u2TxopLimit)); -+ -+ prAcQueParams->ucGuradTime = TXM_DEFAULT_FLUSH_QUEUE_GUARD_TIME; -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief To parse WMM/11n related IEs in scan results (only for AP peers) -+* -+* \param[in] prAdapter Adapter pointer -+* \param[in] prScanResult The scan result which shall be parsed to obtain needed info -+* \param[out] prStaRec The obtained info is stored in the STA_REC -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+#if (CFG_SUPPORT_TDLS == 1) /* for test purpose */ -+BOOLEAN flgTdlsTestExtCapElm = FALSE; -+UINT8 aucTdlsTestExtCapElm[7]; -+#endif /* CFG_SUPPORT_TDLS */ -+VOID mqmProcessScanResult(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prScanResult, OUT P_STA_RECORD_T prStaRec) -+{ -+ PUINT_8 pucIE; -+ UINT_16 u2IELength; -+ UINT_16 u2Offset; -+ UINT_8 aucWfaOui[] = VENDOR_OUI_WFA; -+ -+ DEBUGFUNC("mqmProcessScanResult"); -+ -+ ASSERT(prScanResult); -+ ASSERT(prStaRec); -+ -+ /* Reset the flag before parsing */ -+ prStaRec->fgIsWmmSupported = prStaRec->fgIsUapsdSupported = FALSE; -+ -+ if (!prAdapter->rWifiVar.fgSupportQoS) -+ return; -+ -+ u2IELength = prScanResult->u2IELength; -+ pucIE = prScanResult->aucIEBuf; -+ -+#if (CFG_SUPPORT_TDLS == 1) -+ /* TDLS test purpose */ -+ if (flgTdlsTestExtCapElm == TRUE) -+ TdlsexBssExtCapParse(prStaRec, aucTdlsTestExtCapElm); -+#endif /* CFG_SUPPORT_TDLS */ -+ -+ /* Goal: Determine whether the peer supports WMM/QoS and UAPSDU */ -+ IE_FOR_EACH(pucIE, u2IELength, u2Offset) { -+ switch (IE_ID(pucIE)) { -+ case ELEM_ID_EXTENDED_CAP: -+#if (CFG_SUPPORT_TDLS == 1) -+ TdlsexBssExtCapParse(prStaRec, pucIE); -+#endif /* CFG_SUPPORT_TDLS */ -+ break; -+ -+ case ELEM_ID_WMM: -+ if ((WMM_IE_OUI_TYPE(pucIE) == VENDOR_OUI_TYPE_WMM) && -+ (!kalMemCmp(WMM_IE_OUI(pucIE), aucWfaOui, 3))) { -+ -+ switch (WMM_IE_OUI_SUBTYPE(pucIE)) { -+ case VENDOR_OUI_SUBTYPE_WMM_PARAM: -+ if (IE_LEN(pucIE) != 24) -+ break; /* WMM Param IE with a wrong length */ -+ -+ prStaRec->fgIsWmmSupported = TRUE; -+ prStaRec->fgIsUapsdSupported = -+ (((((P_IE_WMM_PARAM_T) pucIE)->ucQosInfo) & WMM_QOS_INFO_UAPSD) ? -+ TRUE : FALSE); -+ break; -+ -+ case VENDOR_OUI_SUBTYPE_WMM_INFO: -+ if (IE_LEN(pucIE) != 7) -+ break; /* WMM Info IE with a wrong length */ -+ -+ prStaRec->fgIsWmmSupported = TRUE; -+ prStaRec->fgIsUapsdSupported = -+ (((((P_IE_WMM_INFO_T) pucIE)->ucQosInfo) & WMM_QOS_INFO_UAPSD) ? -+ TRUE : FALSE); -+ break; -+ -+ default: -+ /* A WMM QoS IE that doesn't matter. Ignore it. */ -+ break; -+ } -+ } -+ /* else: VENDOR_OUI_TYPE_WPA, VENDOR_OUI_TYPE_WPS, ... (not cared) */ -+ -+ break; -+ -+ default: -+ /* A WMM IE that doesn't matter. Ignore it. */ -+ break; -+ } -+ } -+ DBGLOG(QM, LOUD, "MQM: Scan Result Parsing (WMM=%d, UAPSD=%d)\n", -+ prStaRec->fgIsWmmSupported, prStaRec->fgIsUapsdSupported); -+ -+} -+ -+UINT_8 qmGetStaRecIdx(IN P_ADAPTER_T prAdapter, IN PUINT_8 pucEthDestAddr, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkType) -+{ -+ UINT_32 i; -+ P_STA_RECORD_T prTempStaRec; -+ -+ prTempStaRec = NULL; -+ -+ ASSERT(prAdapter); -+ -+ /* 4 <1> DA = BMCAST */ -+ if (IS_BMCAST_MAC_ADDR(pucEthDestAddr)) -+ return STA_REC_INDEX_BMCAST; -+ /* 4 <2> Check if an AP STA is present */ -+ for (i = 0; i < CFG_NUM_OF_STA_RECORD; i++) { -+ prTempStaRec = &(prAdapter->arStaRec[i]); -+ if ((prTempStaRec->ucNetTypeIndex == eNetworkType) -+ && (prTempStaRec->fgIsAp) -+ && (prTempStaRec->fgIsValid)) { -+ return prTempStaRec->ucIndex; -+ } -+ } -+ -+ /* 4 <3> Not BMCAST, No AP --> Compare DA (i.e., to see whether this is a unicast frame to a client) */ -+ for (i = 0; i < CFG_NUM_OF_STA_RECORD; i++) { -+ prTempStaRec = &(prAdapter->arStaRec[i]); -+ if (prTempStaRec->fgIsValid) { -+ if (EQUAL_MAC_ADDR(prTempStaRec->aucMacAddr, pucEthDestAddr)) -+ return prTempStaRec->ucIndex; -+ } -+ } -+ -+ /* 4 <4> No STA found, Not BMCAST --> Indicate NOT_FOUND to FW */ -+ return STA_REC_INDEX_NOT_FOUND; -+} -+ -+UINT_32 -+mqmGenerateWmmInfoIEByParam(BOOLEAN fgSupportUAPSD, -+ UINT_8 ucBmpDeliveryAC, UINT_8 ucBmpTriggerAC, UINT_8 ucUapsdSp, UINT_8 *pOutBuf) -+{ -+ P_IE_WMM_INFO_T prIeWmmInfo; -+ UINT_32 ucUapsd[] = { -+ WMM_QOS_INFO_BE_UAPSD, -+ WMM_QOS_INFO_BK_UAPSD, -+ WMM_QOS_INFO_VI_UAPSD, -+ WMM_QOS_INFO_VO_UAPSD -+ }; -+ UINT_8 aucWfaOui[] = VENDOR_OUI_WFA; -+ -+ ASSERT(pOutBuf); -+ -+ prIeWmmInfo = (P_IE_WMM_INFO_T) pOutBuf; -+ -+ prIeWmmInfo->ucId = ELEM_ID_WMM; -+ prIeWmmInfo->ucLength = ELEM_MAX_LEN_WMM_INFO; -+ -+ /* WMM-2.2.1 WMM Information Element Field Values */ -+ prIeWmmInfo->aucOui[0] = aucWfaOui[0]; -+ prIeWmmInfo->aucOui[1] = aucWfaOui[1]; -+ prIeWmmInfo->aucOui[2] = aucWfaOui[2]; -+ prIeWmmInfo->ucOuiType = VENDOR_OUI_TYPE_WMM; -+ prIeWmmInfo->ucOuiSubtype = VENDOR_OUI_SUBTYPE_WMM_INFO; -+ -+ prIeWmmInfo->ucVersion = VERSION_WMM; -+ prIeWmmInfo->ucQosInfo = 0; -+ -+ /* UAPSD initial queue configurations (delivery and trigger enabled) */ -+ if (fgSupportUAPSD) { -+ -+ UINT_8 ucQosInfo = 0; -+ UINT_8 i; -+ -+ /* Static U-APSD setting */ -+ for (i = ACI_BE; i <= ACI_VO; i++) { -+ if (ucBmpDeliveryAC & ucBmpTriggerAC & BIT(i)) -+ ucQosInfo |= (UINT_8) ucUapsd[i]; -+ } -+ -+ if (ucBmpDeliveryAC & ucBmpTriggerAC) { -+ switch (ucUapsdSp) { -+ case WMM_MAX_SP_LENGTH_ALL: -+ ucQosInfo |= WMM_QOS_INFO_MAX_SP_ALL; -+ break; -+ -+ case WMM_MAX_SP_LENGTH_2: -+ ucQosInfo |= WMM_QOS_INFO_MAX_SP_2; -+ break; -+ -+ case WMM_MAX_SP_LENGTH_4: -+ ucQosInfo |= WMM_QOS_INFO_MAX_SP_4; -+ break; -+ -+ case WMM_MAX_SP_LENGTH_6: -+ ucQosInfo |= WMM_QOS_INFO_MAX_SP_6; -+ break; -+ -+ default: -+ DBGLOG(QM, WARN, "MQM: Incorrect SP length\n"); -+ ucQosInfo |= WMM_QOS_INFO_MAX_SP_2; -+ break; -+ } -+ } -+ prIeWmmInfo->ucQosInfo = ucQosInfo; -+ -+ } -+ -+ /* Increment the total IE length for the Element ID and Length fields. */ -+ return IE_SIZE(prIeWmmInfo); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Generate the WMM Info IE -+* -+* \param[in] prAdapter Adapter pointer -+* @param prMsduInfo The TX MMPDU -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID mqmGenerateWmmInfoIE(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo) -+{ -+ P_IE_WMM_INFO_T prIeWmmInfo; -+ P_PM_PROFILE_SETUP_INFO_T prPmProfSetupInfo; -+ P_BSS_INFO_T prBssInfo; -+ P_STA_RECORD_T prStaRec; -+ -+ DEBUGFUNC("mqmGenerateWmmInfoIE"); -+ -+ ASSERT(prMsduInfo); -+ -+ /* In case QoS is not turned off, exit directly */ -+ if (!prAdapter->rWifiVar.fgSupportQoS) -+ return; -+ -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); -+ ASSERT(prStaRec); -+ -+ if (prStaRec == NULL) -+ return; -+ -+ if (!prStaRec->fgIsWmmSupported) -+ return; -+ -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]); -+ -+ prPmProfSetupInfo = &prBssInfo->rPmProfSetupInfo; -+ -+ prIeWmmInfo = (P_IE_WMM_INFO_T) -+ ((PUINT_8) prMsduInfo->prPacket + prMsduInfo->u2FrameLength); -+ -+#if 0 -+ prIeWmmInfo->ucId = ELEM_ID_WMM; -+ prIeWmmInfo->ucLength = ELEM_MAX_LEN_WMM_INFO; -+ -+ /* WMM-2.2.1 WMM Information Element Field Values */ -+ prIeWmmInfo->aucOui[0] = aucWfaOui[0]; -+ prIeWmmInfo->aucOui[1] = aucWfaOui[1]; -+ prIeWmmInfo->aucOui[2] = aucWfaOui[2]; -+ prIeWmmInfo->ucOuiType = VENDOR_OUI_TYPE_WMM; -+ prIeWmmInfo->ucOuiSubtype = VENDOR_OUI_SUBTYPE_WMM_INFO; -+ -+ prIeWmmInfo->ucVersion = VERSION_WMM; -+ prIeWmmInfo->ucQosInfo = 0; -+ -+ /* UAPSD initial queue configurations (delivery and trigger enabled) */ -+/* if(prAdapter->rWifiVar.fgSupportUAPSD){ */ -+ if (prAdapter->rWifiVar.fgSupportUAPSD && prStaRec->fgIsUapsdSupported) { -+ -+ UINT_8 ucQosInfo = 0; -+ UINT_8 i; -+ -+ /* Static U-APSD setting */ -+ for (i = ACI_BE; i <= ACI_VO; i++) { -+ if (prPmProfSetupInfo->ucBmpDeliveryAC & prPmProfSetupInfo->ucBmpTriggerAC & BIT(i)) -+ ucQosInfo |= (UINT_8) ucUapsd[i]; -+ } -+ -+ if (prPmProfSetupInfo->ucBmpDeliveryAC & prPmProfSetupInfo->ucBmpTriggerAC) { -+ switch (prPmProfSetupInfo->ucUapsdSp) { -+ case WMM_MAX_SP_LENGTH_ALL: -+ ucQosInfo |= WMM_QOS_INFO_MAX_SP_ALL; -+ break; -+ -+ case WMM_MAX_SP_LENGTH_2: -+ ucQosInfo |= WMM_QOS_INFO_MAX_SP_2; -+ break; -+ -+ case WMM_MAX_SP_LENGTH_4: -+ ucQosInfo |= WMM_QOS_INFO_MAX_SP_4; -+ break; -+ -+ case WMM_MAX_SP_LENGTH_6: -+ ucQosInfo |= WMM_QOS_INFO_MAX_SP_6; -+ break; -+ -+ default: -+ DBGLOG(QM, INFO, "MQM: Incorrect SP length\n"); -+ ucQosInfo |= WMM_QOS_INFO_MAX_SP_2; -+ break; -+ } -+ } -+ prIeWmmInfo->ucQosInfo = ucQosInfo; -+ -+ } -+ -+ /* Increment the total IE length for the Element ID and Length fields. */ -+ prMsduInfo->u2FrameLength += IE_SIZE(prIeWmmInfo); -+#else -+ -+ prMsduInfo->u2FrameLength += mqmGenerateWmmInfoIEByParam((prAdapter->rWifiVar.fgSupportUAPSD -+ && prStaRec->fgIsUapsdSupported), -+ prPmProfSetupInfo->ucBmpDeliveryAC, -+ prPmProfSetupInfo->ucBmpTriggerAC, -+ prPmProfSetupInfo->ucUapsdSp, (UINT_8 *) prIeWmmInfo); -+#endif -+} -+ -+#if 0 -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief log2 calculation for CW -+* -+* @param[in] val value -+* -+* @return log2(val) -+*/ -+/*----------------------------------------------------------------------------*/ -+ -+UINT_32 cwlog2(UINT_32 val) -+{ -+ -+ UINT_32 n; -+ -+ n = 0; -+ -+ while (val >= 512) { -+ n += 9; -+ val = val >> 9; -+ } -+ while (val >= 16) { -+ n += 4; -+ val >>= 4; -+ } -+ while (val >= 2) { -+ n += 1; -+ val >>= 1; -+ } -+ return n; -+} -+#endif -+ -+UINT_32 mqmGenerateWmmParamIEByParam(P_ADAPTER_T prAdapter, -+ P_BSS_INFO_T prBssInfo, UINT_8 *pOutBuf, ENUM_OP_MODE_T ucOpMode) -+{ -+ P_IE_WMM_PARAM_T prIeWmmParam; -+ UINT_8 aucWfaOui[] = VENDOR_OUI_WFA; -+ UINT_8 aucACI[] = { -+ WMM_ACI_AC_BE, -+ WMM_ACI_AC_BK, -+ WMM_ACI_AC_VI, -+ WMM_ACI_AC_VO -+ }; -+ ENUM_WMM_ACI_T eAci; -+ UCHAR *pucAciAifsn, *pucEcw, *pucTxopLimit; -+ -+ ASSERT(pOutBuf); -+ -+ prIeWmmParam = (P_IE_WMM_PARAM_T) pOutBuf; -+ -+ prIeWmmParam->ucId = ELEM_ID_WMM; -+ prIeWmmParam->ucLength = ELEM_MAX_LEN_WMM_PARAM; -+ -+ /* WMM-2.2.1 WMM Information Element Field Values */ -+ prIeWmmParam->aucOui[0] = aucWfaOui[0]; -+ prIeWmmParam->aucOui[1] = aucWfaOui[1]; -+ prIeWmmParam->aucOui[2] = aucWfaOui[2]; -+ prIeWmmParam->ucOuiType = VENDOR_OUI_TYPE_WMM; -+ prIeWmmParam->ucOuiSubtype = VENDOR_OUI_SUBTYPE_WMM_PARAM; -+ -+ prIeWmmParam->ucVersion = VERSION_WMM; -+ prIeWmmParam->ucQosInfo = (prBssInfo->ucWmmParamSetCount & WMM_QOS_INFO_PARAM_SET_CNT); -+ -+ /* UAPSD initial queue configurations (delivery and trigger enabled) */ -+ if (prAdapter->rWifiVar.fgSupportUAPSD) { -+ if (ucOpMode == OP_MODE_INFRASTRUCTURE) -+ prIeWmmParam->ucQosInfo = 0xf; -+ else -+ prIeWmmParam->ucQosInfo |= WMM_QOS_INFO_UAPSD; -+ } -+ -+ /* EDCA parameter */ -+ -+ for (eAci = 0; eAci < WMM_AC_INDEX_NUM; eAci++) { -+ -+ /* DBGLOG(QM, LOUD, */ -+ /* ("MQM: eAci = %d, ACM = %d, Aifsn = %d, CWmin = %d, CWmax = %d, TxopLimit = %d\n", */ -+ /* eAci,prBssInfo->arACQueParmsForBcast[eAci].fgIsACMSet , */ -+ /* prBssInfo->arACQueParmsForBcast[eAci].u2Aifsn, */ -+ /* prBssInfo->arACQueParmsForBcast[eAci].u2CWmin, */ -+ /* prBssInfo->arACQueParmsForBcast[eAci].u2CWmax, */ -+ /* prBssInfo->arACQueParmsForBcast[eAci].u2TxopLimit)); */ -+ -+#if 0 -+ *(((PUINT_8) (&prIeWmmParam->ucAciAifsn_BE)) + (eAci << 2)) = (UINT_8) (aucACI[eAci] -+ | -+ (prBssInfo->arACQueParmsForBcast -+ [eAci].fgIsACMSet ? -+ WMM_ACIAIFSN_ACM : 0) -+ | -+ (prBssInfo->arACQueParmsForBcast -+ [eAci].u2Aifsn & -+ (WMM_ACIAIFSN_AIFSN))); -+#else -+ /* avoid compile warnings in Klockwork tool */ -+ if (eAci == WMM_AC_BE_INDEX) { -+ pucAciAifsn = &prIeWmmParam->ucAciAifsn_BE; -+ pucEcw = &prIeWmmParam->ucEcw_BE; -+ pucTxopLimit = prIeWmmParam->aucTxopLimit_BE; -+ } else if (eAci == WMM_AC_BK_INDEX) { -+ pucAciAifsn = &prIeWmmParam->ucAciAifsn_BG; -+ pucEcw = &prIeWmmParam->ucEcw_BG; -+ pucTxopLimit = prIeWmmParam->aucTxopLimit_BG; -+ } else if (eAci == WMM_AC_VI_INDEX) { -+ pucAciAifsn = &prIeWmmParam->ucAciAifsn_VI; -+ pucEcw = &prIeWmmParam->ucEcw_VI; -+ pucTxopLimit = prIeWmmParam->aucTxopLimit_VI; -+ } else if (eAci == WMM_AC_VO_INDEX) { -+ pucAciAifsn = &prIeWmmParam->ucAciAifsn_VO; -+ pucEcw = &prIeWmmParam->ucEcw_VO; -+ pucTxopLimit = prIeWmmParam->aucTxopLimit_VO; -+ } -+ -+ *pucAciAifsn = (UINT_8) (aucACI[eAci] -+ | (prBssInfo->arACQueParmsForBcast[eAci].fgIsACMSet ? WMM_ACIAIFSN_ACM : 0) -+ | (prBssInfo->arACQueParmsForBcast[eAci].u2Aifsn & (WMM_ACIAIFSN_AIFSN))); -+#endif -+ -+#if 1 -+/* *( ((PUINT_8)(&prIeWmmParam->ucEcw_BE)) + (eAci <<2) ) = (UINT_8) (0 */ -+ *pucEcw = (UINT_8) (0 | (((prBssInfo->aucCWminLog2ForBcast[eAci])) & WMM_ECW_WMIN_MASK) -+ | ((((prBssInfo->aucCWmaxLog2ForBcast[eAci])) << WMM_ECW_WMAX_OFFSET) & -+ WMM_ECW_WMAX_MASK) -+ ); -+#else -+ *(((PUINT_8) (&prIeWmmParam->ucEcw_BE)) + (eAci << 2)) = (UINT_8) (0 -+ | -+ (cwlog2 -+ ((prBssInfo->arACQueParmsForBcast -+ [eAci].u2CWmin + -+ 1)) & WMM_ECW_WMIN_MASK) -+ | -+ ((cwlog2 -+ ((prBssInfo->arACQueParmsForBcast -+ [eAci].u2CWmax + -+ 1)) << WMM_ECW_WMAX_OFFSET) & -+ WMM_ECW_WMAX_MASK) -+ ); -+#endif -+ -+#if 0 -+ WLAN_SET_FIELD_16(((PUINT_8) (prIeWmmParam->aucTxopLimit_BE)) + (eAci << 2) -+ , prBssInfo->arACQueParmsForBcast[eAci].u2TxopLimit); -+#else -+ WLAN_SET_FIELD_16(pucTxopLimit, prBssInfo->arACQueParmsForBcast[eAci].u2TxopLimit); -+#endif -+ } -+ -+ /* Increment the total IE length for the Element ID and Length fields. */ -+ return IE_SIZE(prIeWmmParam); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Generate the WMM Param IE -+* -+* \param[in] prAdapter Adapter pointer -+* @param prMsduInfo The TX MMPDU -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID mqmGenerateWmmParamIE(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo) -+{ -+ P_IE_WMM_PARAM_T prIeWmmParam; -+ -+#if 0 -+ UINT_8 aucWfaOui[] = VENDOR_OUI_WFA; -+ -+ UINT_8 aucACI[] = { -+ WMM_ACI_AC_BE, -+ WMM_ACI_AC_BK, -+ WMM_ACI_AC_VI, -+ WMM_ACI_AC_VO -+ }; -+ ENUM_WMM_ACI_T eAci; -+#endif -+ -+ P_BSS_INFO_T prBssInfo; -+ P_STA_RECORD_T prStaRec; -+ -+ DEBUGFUNC("mqmGenerateWmmParamIE"); -+ DBGLOG(QM, LOUD, "\n"); -+ -+ ASSERT(prMsduInfo); -+ -+ /* In case QoS is not turned off, exit directly */ -+ if (!prAdapter->rWifiVar.fgSupportQoS) -+ return; -+ -+ prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); -+ -+ if (prStaRec) { -+ if (!prStaRec->fgIsQoS) -+ return; -+ } -+ -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prMsduInfo->ucNetworkType]); -+ -+ if (!prBssInfo->fgIsQBSS) -+ return; -+/* 20120220 frog: update beacon content & change OP mode is a separate event for P2P network. */ -+#if 0 -+ if (prBssInfo->eCurrentOPMode != OP_MODE_ACCESS_POINT && prBssInfo->eCurrentOPMode != OP_MODE_BOW) -+ return; -+#endif -+ -+ prIeWmmParam = (P_IE_WMM_PARAM_T) -+ ((PUINT_8) prMsduInfo->prPacket + prMsduInfo->u2FrameLength); -+ -+#if 0 -+ prIeWmmParam->ucId = ELEM_ID_WMM; -+ prIeWmmParam->ucLength = ELEM_MAX_LEN_WMM_PARAM; -+ -+ /* WMM-2.2.1 WMM Information Element Field Values */ -+ prIeWmmParam->aucOui[0] = aucWfaOui[0]; -+ prIeWmmParam->aucOui[1] = aucWfaOui[1]; -+ prIeWmmParam->aucOui[2] = aucWfaOui[2]; -+ prIeWmmParam->ucOuiType = VENDOR_OUI_TYPE_WMM; -+ prIeWmmParam->ucOuiSubtype = VENDOR_OUI_SUBTYPE_WMM_PARAM; -+ -+ prIeWmmParam->ucVersion = VERSION_WMM; -+ prIeWmmParam->ucQosInfo = (prBssInfo->ucWmmParamSetCount & WMM_QOS_INFO_PARAM_SET_CNT); -+ -+ /* UAPSD initial queue configurations (delivery and trigger enabled) */ -+ if (prAdapter->rWifiVar.fgSupportUAPSD) -+ prIeWmmParam->ucQosInfo |= WMM_QOS_INFO_UAPSD; -+ -+ /* EDCA parameter */ -+ -+ for (eAci = 0; eAci < WMM_AC_INDEX_NUM; eAci++) { -+ -+ /* DBGLOG(QM, LOUD, */ -+ /* ("MQM: eAci = %d, ACM = %d, Aifsn = %d, CWmin = %d, CWmax = %d, TxopLimit = %d\n", */ -+ /* eAci,prBssInfo->arACQueParmsForBcast[eAci].fgIsACMSet , */ -+ /* prBssInfo->arACQueParmsForBcast[eAci].u2Aifsn, */ -+ /* prBssInfo->arACQueParmsForBcast[eAci].u2CWmin, */ -+ /* prBssInfo->arACQueParmsForBcast[eAci].u2CWmax, */ -+ /* prBssInfo->arACQueParmsForBcast[eAci].u2TxopLimit)); */ -+ -+ *(((PUINT_8) (&prIeWmmParam->ucAciAifsn_BE)) + (eAci << 2)) = (UINT_8) (aucACI[eAci] -+ | -+ (prBssInfo->arACQueParmsForBcast -+ [eAci].fgIsACMSet ? -+ WMM_ACIAIFSN_ACM : 0) -+ | -+ (prBssInfo->arACQueParmsForBcast -+ [eAci].u2Aifsn & -+ (WMM_ACIAIFSN_AIFSN))); -+#if 1 -+ *(((PUINT_8) (&prIeWmmParam->ucEcw_BE)) + (eAci << 2)) = (UINT_8) (0 -+ | -+ (((prBssInfo->aucCWminLog2ForBcast -+ [eAci])) & WMM_ECW_WMIN_MASK) -+ | -+ ((((prBssInfo->aucCWmaxLog2ForBcast -+ [eAci])) << WMM_ECW_WMAX_OFFSET) -+ & WMM_ECW_WMAX_MASK) -+ ); -+#else -+ *(((PUINT_8) (&prIeWmmParam->ucEcw_BE)) + (eAci << 2)) = (UINT_8) (0 -+ | -+ (cwlog2 -+ ((prBssInfo->arACQueParmsForBcast -+ [eAci].u2CWmin + -+ 1)) & WMM_ECW_WMIN_MASK) -+ | -+ ((cwlog2 -+ ((prBssInfo->arACQueParmsForBcast -+ [eAci].u2CWmax + -+ 1)) << WMM_ECW_WMAX_OFFSET) & -+ WMM_ECW_WMAX_MASK) -+ ); -+#endif -+ -+ WLAN_SET_FIELD_16(((PUINT_8) (prIeWmmParam->aucTxopLimit_BE)) + (eAci << 2) -+ , prBssInfo->arACQueParmsForBcast[eAci].u2TxopLimit); -+ -+ } -+ -+ /* Increment the total IE length for the Element ID and Length fields. */ -+ prMsduInfo->u2FrameLength += IE_SIZE(prIeWmmParam); -+#else -+ -+ prMsduInfo->u2FrameLength += mqmGenerateWmmParamIEByParam(prAdapter, -+ prBssInfo, (UINT_8 *) prIeWmmParam, OP_MODE_ACCESS_POINT); -+#endif -+} -+ -+ENUM_FRAME_ACTION_T -+qmGetFrameAction(IN P_ADAPTER_T prAdapter, -+ IN ENUM_NETWORK_TYPE_INDEX_T eNetworkType, -+ IN UINT_8 ucStaRecIdx, IN P_MSDU_INFO_T prMsduInfo, IN ENUM_FRAME_TYPE_IN_CMD_Q_T eFrameType) -+{ -+ P_BSS_INFO_T prBssInfo; -+ P_STA_RECORD_T prStaRec; -+ P_WLAN_MAC_HEADER_T prWlanFrame; -+ UINT_16 u2TxFrameCtrl; -+ -+ DEBUGFUNC("qmGetFrameAction"); -+ -+#if (NIC_TX_BUFF_COUNT_TC4 > 2) -+#define QM_MGMT_QUUEUD_THRESHOLD 2 -+#else -+#define QM_MGMT_QUUEUD_THRESHOLD 1 -+#endif -+ -+ DATA_STRUCT_INSPECTING_ASSERT(QM_MGMT_QUUEUD_THRESHOLD <= (NIC_TX_BUFF_COUNT_TC4)); -+ DATA_STRUCT_INSPECTING_ASSERT(QM_MGMT_QUUEUD_THRESHOLD > 0); -+ -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[eNetworkType]); -+ prStaRec = QM_GET_STA_REC_PTR_FROM_INDEX(prAdapter, ucStaRecIdx); -+ -+ /* XXX Check BOW P2P AIS time ot set active */ -+ if (!IS_BSS_ACTIVE(prBssInfo)) { -+ if (eFrameType == FRAME_TYPE_MMPDU) { -+ prWlanFrame = (P_WLAN_MAC_HEADER_T) prMsduInfo->prPacket; -+ u2TxFrameCtrl = (prWlanFrame->u2FrameCtrl) & MASK_FRAME_TYPE; /* Optimized for ARM */ -+ if (((u2TxFrameCtrl == MAC_FRAME_DEAUTH) -+ && (prMsduInfo->pfTxDoneHandler == NULL)) -+ || (u2TxFrameCtrl == MAC_FRAME_ACTION)) /* whsu */ -+ return FRAME_ACTION_TX_PKT; -+ } -+ -+ DBGLOG(QM, WARN, "Drop packets Action, eFrameType: %d (Bss Index %u).\n", -+ eFrameType, prBssInfo->ucNetTypeIndex); -+ TX_INC_CNT(&prAdapter->rTxCtrl, TX_INACTIVE_BSS_DROP); -+ return FRAME_ACTION_DROP_PKT; -+ } -+ -+ /* TODO Handle disconnect issue */ -+ -+ /* P2P probe Request frame */ -+ do { -+ if (eFrameType == FRAME_TYPE_MMPDU) { -+ prWlanFrame = (P_WLAN_MAC_HEADER_T) prMsduInfo->prPacket; -+ u2TxFrameCtrl = (prWlanFrame->u2FrameCtrl) & MASK_FRAME_TYPE; /* Optimized for ARM */ -+ -+ if (u2TxFrameCtrl == MAC_FRAME_BEACON) { -+ if (prBssInfo->fgIsNetAbsent) -+ return FRAME_ACTION_DROP_PKT; -+ } else if (u2TxFrameCtrl == MAC_FRAME_PROBE_RSP) { -+ if (prBssInfo->fgIsNetAbsent) -+ return FRAME_ACTION_DROP_PKT; -+ } else if (u2TxFrameCtrl == MAC_FRAME_DEAUTH) { -+ if (prBssInfo->fgIsNetAbsent) -+ break; -+ DBGLOG(P2P, LOUD, "Sending DEAUTH Frame\n"); -+ return FRAME_ACTION_TX_PKT; -+ } -+ /* MMPDU with prStaRec && fgIsInUse not check fgIsNetActive */ -+ else if (u2TxFrameCtrl == MAC_FRAME_ASSOC_REQ -+ || u2TxFrameCtrl == MAC_FRAME_AUTH -+ || u2TxFrameCtrl == MAC_FRAME_REASSOC_REQ -+ || u2TxFrameCtrl == MAC_FRAME_PROBE_REQ || u2TxFrameCtrl == MAC_FRAME_ACTION) { -+ -+ if ((prStaRec) && (prStaRec->fgIsInPS)) { -+ if (nicTxGetResource(prAdapter, TC4_INDEX) >= QM_MGMT_QUUEUD_THRESHOLD) -+ return FRAME_ACTION_TX_PKT; -+ else -+ return FRAME_ACTION_QUEUE_PKT; -+ } -+ return FRAME_ACTION_TX_PKT; -+ } -+ -+ if (!prStaRec) -+ return FRAME_ACTION_TX_PKT; -+ -+ if (!prStaRec->fgIsInUse) -+ return FRAME_ACTION_DROP_PKT; -+ -+ } /* FRAME_TYPE_MMPDU */ -+ else if (eFrameType == FRAME_TYPE_802_1X) { -+ -+ if (!prStaRec) -+ return FRAME_ACTION_TX_PKT; -+ -+ if (!prStaRec->fgIsInUse) -+ return FRAME_ACTION_DROP_PKT; -+ if (prStaRec->fgIsInPS) { -+ if (nicTxGetResource(prAdapter, TC4_INDEX) >= QM_MGMT_QUUEUD_THRESHOLD) -+ return FRAME_ACTION_TX_PKT; -+ else -+ return FRAME_ACTION_QUEUE_PKT; -+ } -+ -+ } /* FRAME_TYPE_802_1X */ -+ else if ((!IS_BSS_ACTIVE(prBssInfo)) -+ || (!prStaRec) -+ || (!prStaRec->fgIsInUse)) { -+ return FRAME_ACTION_DROP_PKT; -+ } -+ } while (0); -+ -+ if (prBssInfo->fgIsNetAbsent) { -+ DBGLOG(QM, LOUD, "Queue packets (Absent %u).\n", prBssInfo->ucNetTypeIndex); -+ return FRAME_ACTION_QUEUE_PKT; -+ } -+ -+ if (prStaRec && prStaRec->fgIsInPS) { -+ DBGLOG(QM, LOUD, "Queue packets (PS %u).\n", prStaRec->fgIsInPS); -+ return FRAME_ACTION_QUEUE_PKT; -+ } -+ switch (eFrameType) { -+ case FRAME_TYPE_802_1X: -+ if (!prStaRec->fgIsValid) -+ return FRAME_ACTION_QUEUE_PKT; -+ break; -+ -+ case FRAME_TYPE_MMPDU: -+ break; -+ -+ default: -+ ASSERT(0); -+ } -+ -+ return FRAME_ACTION_TX_PKT; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Handle BSS change operation Event from the FW -+* -+* \param[in] prAdapter Adapter pointer -+* \param[in] prEvent The event packet from the FW -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID qmHandleEventBssAbsencePresence(IN P_ADAPTER_T prAdapter, IN P_WIFI_EVENT_T prEvent) -+{ -+ P_EVENT_BSS_ABSENCE_PRESENCE_T prEventBssStatus; -+ P_BSS_INFO_T prBssInfo; -+ BOOLEAN fgIsNetAbsentOld; -+ -+ prEventBssStatus = (P_EVENT_BSS_ABSENCE_PRESENCE_T) prEvent; -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prEventBssStatus->ucNetTypeIdx]); -+ fgIsNetAbsentOld = prBssInfo->fgIsNetAbsent; -+ prBssInfo->fgIsNetAbsent = prEventBssStatus->fgIsAbsent; -+ prBssInfo->ucBssFreeQuota = prEventBssStatus->ucBssFreeQuota; -+ -+ /* DBGLOG(QM, TRACE, ("qmHandleEventBssAbsencePresence (ucNetTypeIdx=%d, fgIsAbsent=%d, FreeQuota=%d)\n", */ -+ /* prEventBssStatus->ucNetTypeIdx, prBssInfo->fgIsNetAbsent, prBssInfo->ucBssFreeQuota)); */ -+ -+ DBGLOG(QM, INFO, "NAF=%d,%d,%d\n", -+ prEventBssStatus->ucNetTypeIdx, prBssInfo->fgIsNetAbsent, prBssInfo->ucBssFreeQuota); -+ -+ if (!prBssInfo->fgIsNetAbsent) { -+ /* QM_DBG_CNT_27 */ -+ QM_DBG_CNT_INC(&(prAdapter->rQM), QM_DBG_CNT_27); -+ } else { -+ /* QM_DBG_CNT_28 */ -+ QM_DBG_CNT_INC(&(prAdapter->rQM), QM_DBG_CNT_28); -+ } -+ /* From Absent to Present */ -+ if ((fgIsNetAbsentOld) && (!prBssInfo->fgIsNetAbsent)) -+ kalSetEvent(prAdapter->prGlueInfo); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Handle STA change PS mode Event from the FW -+* -+* \param[in] prAdapter Adapter pointer -+* \param[in] prEvent The event packet from the FW -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID qmHandleEventStaChangePsMode(IN P_ADAPTER_T prAdapter, IN P_WIFI_EVENT_T prEvent) -+{ -+ P_EVENT_STA_CHANGE_PS_MODE_T prEventStaChangePsMode; -+ P_STA_RECORD_T prStaRec; -+ BOOLEAN fgIsInPSOld; -+ -+ /* DbgPrint("QM:Event -RxBa\n"); */ -+ -+ prEventStaChangePsMode = (P_EVENT_STA_CHANGE_PS_MODE_T) prEvent; -+ prStaRec = QM_GET_STA_REC_PTR_FROM_INDEX(prAdapter, prEventStaChangePsMode->ucStaRecIdx); -+ ASSERT(prStaRec); -+ -+ if (prStaRec) { -+ -+ fgIsInPSOld = prStaRec->fgIsInPS; -+ prStaRec->fgIsInPS = prEventStaChangePsMode->fgIsInPs; -+ -+ qmUpdateFreeQuota(prAdapter, -+ prStaRec, -+ prEventStaChangePsMode->ucUpdateMode, prEventStaChangePsMode->ucFreeQuota, 0); -+ -+ /* DBGLOG(QM, TRACE, ("qmHandleEventStaChangePsMode (ucStaRecIdx=%d, fgIsInPs=%d)\n", */ -+ /* prEventStaChangePsMode->ucStaRecIdx, prStaRec->fgIsInPS)); */ -+ -+ DBGLOG(QM, TRACE, "PS=%d,%d\n", prEventStaChangePsMode->ucStaRecIdx, prStaRec->fgIsInPS); -+ -+ /* From PS to Awake */ -+ if ((fgIsInPSOld) && (!prStaRec->fgIsInPS)) -+ kalSetEvent(prAdapter->prGlueInfo); -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Update STA free quota Event from FW -+* -+* \param[in] prAdapter Adapter pointer -+* \param[in] prEvent The event packet from the FW -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID qmHandleEventStaUpdateFreeQuota(IN P_ADAPTER_T prAdapter, IN P_WIFI_EVENT_T prEvent) -+{ -+ P_EVENT_STA_UPDATE_FREE_QUOTA_T prEventStaUpdateFreeQuota; -+ P_STA_RECORD_T prStaRec; -+ -+ prEventStaUpdateFreeQuota = (P_EVENT_STA_UPDATE_FREE_QUOTA_T) prEvent; -+ prStaRec = QM_GET_STA_REC_PTR_FROM_INDEX(prAdapter, prEventStaUpdateFreeQuota->ucStaRecIdx); -+ ASSERT(prStaRec); -+ -+ if (prStaRec) { -+ if (prStaRec->fgIsInPS) { -+ qmUpdateFreeQuota(prAdapter, -+ prStaRec, -+ prEventStaUpdateFreeQuota->ucUpdateMode, -+ prEventStaUpdateFreeQuota->ucFreeQuota, -+ prEventStaUpdateFreeQuota->aucReserved[0]); -+ -+ kalSetEvent(prAdapter->prGlueInfo); -+ } -+#if 0 -+ DBGLOG(QM, TRACE, -+ "qmHandleEventStaUpdateFreeQuota (ucStaRecIdx=%d, ucUpdateMode=%d, ucFreeQuota=%d)\n", -+ prEventStaUpdateFreeQuota->ucStaRecIdx, prEventStaUpdateFreeQuota->ucUpdateMode, -+ prEventStaUpdateFreeQuota->ucFreeQuota); -+#endif -+ -+ DBGLOG(QM, TRACE, "UFQ=%d,%d,%d\n", -+ prEventStaUpdateFreeQuota->ucStaRecIdx, -+ prEventStaUpdateFreeQuota->ucUpdateMode, prEventStaUpdateFreeQuota->ucFreeQuota); -+ -+ } -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Update STA free quota -+* -+* \param[in] prStaRec the STA -+* \param[in] ucUpdateMode the method to update free quota -+* \param[in] ucFreeQuota the value for update -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+qmUpdateFreeQuota(IN P_ADAPTER_T prAdapter, -+ IN P_STA_RECORD_T prStaRec, IN UINT_8 ucUpdateMode, IN UINT_8 ucFreeQuota, IN UINT_8 ucNumOfTxDone) -+{ -+ -+ UINT_8 ucFreeQuotaForNonDelivery; -+ UINT_8 ucFreeQuotaForDelivery; -+ BOOLEAN flgIsUpdateForcedToDelivery; -+ -+ ASSERT(prStaRec); -+ DBGLOG(QM, LOUD, "qmUpdateFreeQuota orig ucFreeQuota=%d Mode %u New %u\n", -+ prStaRec->ucFreeQuota, ucUpdateMode, ucFreeQuota); -+ -+ if (!prStaRec->fgIsInPS) -+ return; -+ -+ flgIsUpdateForcedToDelivery = FALSE; -+ -+ if (ucNumOfTxDone > 0) { -+ /* -+ update free quota by -+ num of tx done + resident free quota (delivery + non-delivery) -+ */ -+ UINT_8 ucAvailQuota; -+ -+ ucAvailQuota = ucNumOfTxDone + prStaRec->ucFreeQuotaForDelivery + prStaRec->ucFreeQuotaForNonDelivery; -+ if (ucAvailQuota > ucFreeQuota) /* sanity check */ -+ ucAvailQuota = ucFreeQuota; -+ -+ /* update current free quota */ -+ ucFreeQuota = ucAvailQuota; -+ -+ /* check if the update is from last packet */ -+ if (ucFreeQuota == (prStaRec->ucFreeQuota + 1)) { -+ /* just add the extra quota to delivery queue */ -+ -+ /* -+ EX: -+ 1. TDLS peer enters power save -+ 2. When the last 2 VI packets are tx done, we will receive 2 update events -+ 3. 1st update event: ucFreeQuota = 9 -+ 4. We will correct new quota for delivey and non-delivery to 7:2 -+ 5. 2rd update event: ucFreeQuota = 10 -+ 6. We will re-correct new quota for delivery and non-delivery to 5:5 -+ -+ But non-delivery queue is not busy. -+ So in the case, we will have wrong decision, i.e. higher queue always quota 5 -+ -+ Solution: skip the 2rd update event and just add the extra quota to delivery. -+ */ -+ -+ flgIsUpdateForcedToDelivery = TRUE; -+ } -+ } -+ -+ switch (ucUpdateMode) { -+ case FREE_QUOTA_UPDATE_MODE_INIT: -+ case FREE_QUOTA_UPDATE_MODE_OVERWRITE: -+ prStaRec->ucFreeQuota = ucFreeQuota; -+ break; -+ case FREE_QUOTA_UPDATE_MODE_INCREASE: -+ prStaRec->ucFreeQuota += ucFreeQuota; -+ break; -+ case FREE_QUOTA_UPDATE_MODE_DECREASE: -+ prStaRec->ucFreeQuota -= ucFreeQuota; -+ break; -+ default: -+ ASSERT(0); -+ } -+ -+ DBGLOG(QM, LOUD, "qmUpdateFreeQuota new ucFreeQuota=%d)\n", prStaRec->ucFreeQuota); -+ -+ ucFreeQuota = prStaRec->ucFreeQuota; -+ -+ ucFreeQuotaForNonDelivery = 0; -+ ucFreeQuotaForDelivery = 0; -+ -+ if (ucFreeQuota > 0) { -+ if (prStaRec->fgIsQoS && prStaRec->fgIsUapsdSupported -+ /* && prAdapter->rWifiVar.fgSupportQoS -+ && prAdapter->rWifiVar.fgSupportUAPSD */) { -+ /* XXX We should assign quota to aucFreeQuotaPerQueue[NUM_OF_PER_STA_TX_QUEUES] */ -+ -+ if (flgIsUpdateForcedToDelivery == FALSE) { -+ if (prStaRec->ucFreeQuotaForNonDelivery > 0 && prStaRec->ucFreeQuotaForDelivery > 0) { -+ ucFreeQuotaForNonDelivery = ucFreeQuota >> 1; -+ ucFreeQuotaForDelivery = ucFreeQuota - ucFreeQuotaForNonDelivery; -+ } else if (prStaRec->ucFreeQuotaForNonDelivery == 0 -+ && prStaRec->ucFreeQuotaForDelivery == 0) { -+ ucFreeQuotaForNonDelivery = ucFreeQuota >> 1; -+ ucFreeQuotaForDelivery = ucFreeQuota - ucFreeQuotaForNonDelivery; -+ } else if (prStaRec->ucFreeQuotaForNonDelivery > 0) { -+ /* NonDelivery is not busy */ -+ if (ucFreeQuota >= 3) { -+ ucFreeQuotaForNonDelivery = 2; -+ ucFreeQuotaForDelivery = ucFreeQuota - ucFreeQuotaForNonDelivery; -+ } else { -+ ucFreeQuotaForDelivery = ucFreeQuota; -+ ucFreeQuotaForNonDelivery = 0; -+ } -+ } else if (prStaRec->ucFreeQuotaForDelivery > 0) { -+ /* Delivery is not busy */ -+ if (ucFreeQuota >= 3) { -+ ucFreeQuotaForDelivery = 2; -+ ucFreeQuotaForNonDelivery = ucFreeQuota - ucFreeQuotaForDelivery; -+ } else { -+ ucFreeQuotaForNonDelivery = ucFreeQuota; -+ ucFreeQuotaForDelivery = 0; -+ } -+ } -+ } else { -+ ucFreeQuotaForNonDelivery = 2; -+ ucFreeQuotaForDelivery = ucFreeQuota - ucFreeQuotaForNonDelivery; -+ } -+ } else { -+ /* no use ? */ -+ /* !prStaRec->fgIsUapsdSupported */ -+ ucFreeQuotaForNonDelivery = ucFreeQuota; -+ ucFreeQuotaForDelivery = 0; -+ } -+ } -+ /* ucFreeQuota > 0 */ -+ prStaRec->ucFreeQuotaForDelivery = ucFreeQuotaForDelivery; -+ prStaRec->ucFreeQuotaForNonDelivery = ucFreeQuotaForNonDelivery; -+ -+#if (CFG_SUPPORT_TDLS_DBG == 1) -+ if (IS_TDLS_STA(prStaRec)) -+ DBGLOG(QM, LOUD, " quota %d %d %d\n", -+ ucFreeQuota, ucFreeQuotaForDelivery, ucFreeQuotaForNonDelivery); -+#endif -+ -+ DBGLOG(QM, LOUD, "new QuotaForDelivery = %d QuotaForNonDelivery = %d\n", -+ prStaRec->ucFreeQuotaForDelivery, prStaRec->ucFreeQuotaForNonDelivery); -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Return the reorder queued RX packets -+* -+* \param[in] (none) -+* -+* \return The number of queued RX packets -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT_32 qmGetRxReorderQueuedBufferCount(IN P_ADAPTER_T prAdapter) -+{ -+ UINT_32 i, u4Total; -+ P_QUE_MGT_T prQM = &prAdapter->rQM; -+ -+ u4Total = 0; -+ /* XXX The summation may impact the performance */ -+ for (i = 0; i < CFG_NUM_OF_RX_BA_AGREEMENTS; i++) { -+ u4Total += prQM->arRxBaTable[i].rReOrderQue.u4NumElem; -+#if DBG && 0 -+ if (QUEUE_IS_EMPTY(&(prQM->arRxBaTable[i].rReOrderQue))) -+ ASSERT(prQM->arRxBaTable[i].rReOrderQue == 0); -+#endif -+ } -+ ASSERT(u4Total <= (CFG_NUM_OF_QM_RX_PKT_NUM * 2)); -+ return u4Total; -+} -+ -+#if ARP_MONITER_ENABLE -+VOID qmDetectArpNoResponse(P_ADAPTER_T prAdapter, P_MSDU_INFO_T prMsduInfo) -+{ -+ struct sk_buff *prSkb = NULL; -+ PUINT_8 pucData = NULL; -+ UINT_16 u2EtherType = 0; -+ int arpOpCode = 0; -+ -+ prSkb = (struct sk_buff *)prMsduInfo->prPacket; -+ -+ if (!prSkb || (prSkb->len <= ETHER_HEADER_LEN)) -+ return; -+ -+ pucData = prSkb->data; -+ if (!pucData) -+ return; -+ u2EtherType = (pucData[ETH_TYPE_LEN_OFFSET] << 8) | (pucData[ETH_TYPE_LEN_OFFSET + 1]); -+ -+ if (u2EtherType != ETH_P_ARP || (apIp[0] | apIp[1] | apIp[2] | apIp[3]) == 0) -+ return; -+ -+ if (strncmp(apIp, &pucData[ETH_TYPE_LEN_OFFSET + 26], sizeof(apIp))) /* dest ip address */ -+ return; -+ -+ arpOpCode = (pucData[ETH_TYPE_LEN_OFFSET + 8] << 8) | (pucData[ETH_TYPE_LEN_OFFSET + 8 + 1]); -+ if (arpOpCode == ARP_PRO_REQ) { -+ arpMoniter++; -+ if (arpMoniter > 20) { -+ DBGLOG(INIT, WARN, "IOT Critical issue, arp no resp, check AP!\n"); -+ aisBssBeaconTimeout(prAdapter); -+ arpMoniter = 0; -+ kalMemZero(apIp, sizeof(apIp)); -+ } -+ } -+} -+ -+VOID qmHandleRxArpPackets(P_ADAPTER_T prAdapter, P_SW_RFB_T prSwRfb) -+{ -+ PUINT_8 pucData = NULL; -+ UINT_16 u2EtherType = 0; -+ int arpOpCode = 0; -+ P_BSS_INFO_T prBssInfo = NULL; -+ -+ if (prSwRfb->u2PacketLen <= ETHER_HEADER_LEN) -+ return; -+ -+ pucData = (PUINT_8)prSwRfb->pvHeader; -+ if (!pucData) -+ return; -+ u2EtherType = (pucData[ETH_TYPE_LEN_OFFSET] << 8) | (pucData[ETH_TYPE_LEN_OFFSET + 1]); -+ -+ if (u2EtherType != ETH_P_ARP) -+ return; -+ -+ arpOpCode = (pucData[ETH_TYPE_LEN_OFFSET + 8] << 8) | (pucData[ETH_TYPE_LEN_OFFSET + 8 + 1]); -+ prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); -+ if (arpOpCode == ARP_PRO_RSP) { -+ arpMoniter = 0; -+ if (prBssInfo && prBssInfo->prStaRecOfAP && prBssInfo->prStaRecOfAP->aucMacAddr) { -+ if (EQUAL_MAC_ADDR(&(pucData[ETH_TYPE_LEN_OFFSET + 10]), /* source hardware address */ -+ prBssInfo->prStaRecOfAP->aucMacAddr)) { -+ strncpy(apIp, &(pucData[ETH_TYPE_LEN_OFFSET + 16]), sizeof(apIp)); /* src ip address */ -+ DBGLOG(INIT, TRACE, "get arp response from AP %d.%d.%d.%d\n", -+ apIp[0], apIp[1], apIp[2], apIp[3]); -+ } -+ } -+ } -+} -+ -+VOID qmResetArpDetect(VOID) -+{ -+ arpMoniter = 0; -+ kalMemZero(apIp, sizeof(apIp)); -+} -+#endif -+ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_bow.c b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_bow.c -new file mode 100644 -index 000000000000..6f5c0bcdd90b ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_bow.c -@@ -0,0 +1,1177 @@ -+/* -+** Id: @(#) gl_bow.c@@ -+*/ -+ -+/*! \file gl_bow.c -+ \brief Main routines of Linux driver interface for 802.11 PAL (BT 3.0 + HS) -+ -+ This file contains the main routines of Linux driver for MediaTek Inc. 802.11 -+ Wireless LAN Adapters. -+*/ -+ -+/* -+** Log: gl_bow.c -+ * -+ * 02 16 2012 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * [ALPS00235223] [Rose][ICS][Cross Feature][AEE-IPANIC]The device reboot automatically and then the "KE" pops up -+ * after you turn on the "Airplane mode".(once) -+ * -+ * [Root Cause] -+ * PAL operates BOW char dev poll after BOW char dev is registered. -+ * -+ * [Solution] -+ * Rejects PAL char device operation after BOW is unregistered or when wlan GLUE_FLAG_HALT is set. -+ * -+ * This is a workaround for BOW driver robustness, happens only in ICS. -+ * -+ * Root cause should be fixed by CR [ALPS00231570] -+ * -+ * 02 03 2012 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * [ALPS00118114] [Rose][ICS][Free Test][Bluetooth]The "KE" pops up after you turn on the airplane mode.(5/5) -+ * -+ * [Root Cause] -+ * PAL operates BOW char dev poll after BOW char dev is registered. -+ * -+ * [Solution] -+ * Rejects PAL char device operation after BOW is unregistered. -+ * -+ * Happens only in ICS. -+ * -+ * Notified PAL owener to reivew MTKBT/PAL closing BOW char dev procedure. -+ * -+ * [Side Effect] -+ * None. -+ * -+ * 01 16 2012 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Support BOW for 5GHz band. -+ * -+ * 11 10 2011 cp.wu -+ * [WCXRP00001098] [MT6620 Wi-Fi][Driver] Replace printk by DBG LOG macros in linux porting layer -+ * 1. eliminaite direct calls to printk in porting layer. -+ * 2. replaced by DBGLOG, which would be XLOG on ALPS platforms. -+ * -+ * 10 25 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Modify ampc0 char device for major number 151 for all MT6575 projects. -+ * -+ * 07 28 2011 cp.wu -+ * [WCXRP00000884] [MT6620 Wi-Fi][Driver] Deprecate ioctl interface by unlocked ioctl -+ * unlocked_ioctl returns as long instead of int. -+ * -+ * 07 28 2011 cp.wu -+ * [WCXRP00000884] [MT6620 Wi-Fi][Driver] Deprecate ioctl interface by unlocked ioctl -+ * migrate to unlocked ioctl interface -+ * -+ * 04 12 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Add WMM IE for BOW initiator data. -+ * -+ * 04 10 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Change Link disconnection event procedure for hotspot and change skb length check to 1514 bytes. -+ * -+ * 04 09 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Change Link connection event procedure and change skb length check to 1512 bytes. -+ * -+ * 03 27 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Support multiple physical link. -+ * -+ * 03 06 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Sync BOW Driver to latest person development branch version.. -+ * -+ * 03 03 2011 jeffrey.chang -+ * [WCXRP00000512] [MT6620 Wi-Fi][Driver] modify the net device relative functions to support the H/W multiple queue -+ * support concurrent network -+ * -+ * 03 03 2011 jeffrey.chang -+ * [WCXRP00000512] [MT6620 Wi-Fi][Driver] modify the net device relative functions to support the H/W multiple queue -+ * replace alloc_netdev to alloc_netdev_mq for BoW -+ * -+ * 03 03 2011 jeffrey.chang -+ * [WCXRP00000512] [MT6620 Wi-Fi][Driver] modify the net device relative functions to support the H/W multiple queue -+ * modify net device relative functions to support multiple H/W queues -+ * -+ * 02 15 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Update net register and BOW for concurrent features. -+ * -+ * 02 10 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Fix kernel API change issue. -+ * Before ALPS 2.2 (2.2 included), kfifo_alloc() is -+ * struct kfifo *kfifo_alloc(unsigned int size, gfp_t gfp_mask, spinlock_t *lock); -+ * After ALPS 2.3, kfifo_alloc() is changed to -+ * int kfifo_alloc(struct kfifo *fifo, unsigned int size, gfp_t gfp_mask); -+ * -+ * 02 09 2011 cp.wu -+ * [WCXRP00000430] [MT6620 Wi-Fi][Firmware][Driver] Create V1.2 branch for MT6620E1 and MT6620E3 -+ * create V1.2 driver branch based on label MT6620_WIFI_DRIVER_V1_2_110209_1031 -+ * with BOW and P2P enabled as default -+ * -+ * 02 08 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Replace kfifo_get and kfifo_put with kfifo_out and kfifo_in. -+ * Update BOW get MAC status, remove returning event for AIS network type. -+ * -+ * 01 12 2011 cp.wu -+ * [WCXRP00000357] [MT6620 Wi-Fi][Driver][Bluetooth over Wi-Fi] add another net device interface for BT AMP -+ * implementation of separate BT_OVER_WIFI data path. -+ * -+ * 01 12 2011 cp.wu -+ * [WCXRP00000356] [MT6620 Wi-Fi][Driver] fill mac header length for security frames 'cause hardware header translation -+ * needs such information -+ * fill mac header length information for 802.1x frames. -+ * -+ * 11 11 2010 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Fix BoW timer assert issue. -+ * -+ * 09 14 2010 chinghwa.yu -+ * NULL -+ * Add bowRunEventAAAComplete. -+ * -+ * 09 14 2010 cp.wu -+ * NULL -+ * correct typo: POLLOUT instead of POLL_OUT -+ * -+ * 09 13 2010 cp.wu -+ * NULL -+ * add waitq for poll() and read(). -+ * -+ * 08 24 2010 chinghwa.yu -+ * NULL -+ * Update BOW for the 1st time. -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 05 05 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * change variable names for multiple physical link to match with coding convention -+ * -+ * 05 05 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * multiple BoW interfaces need to compare with peer address -+ * -+ * 04 28 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * change prefix for data structure used to communicate with 802.11 PAL -+ * to avoid ambiguous naming with firmware interface -+ * -+ * 04 28 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * fix kalIndicateBOWEvent. -+ * -+ * 04 27 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * add multiple physical link support -+ * -+ * 04 13 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * add framework for BT-over-Wi-Fi support. -+ * * * * * * * * * * * * * * * * 1) prPendingCmdInfo is replaced by queue for multiple handler capability -+ * * * * * * * * * * * * * * * * 2) command sequence number is now increased atomically -+ * * * * * * * * * * * * * * * * 3) private data could be hold and taken use for other purpose -+** -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "gl_os.h" -+#include "debug.h" -+#include "wlan_lib.h" -+#include "gl_wext.h" -+#include "precomp.h" -+#include -+#include "bss.h" -+ -+#if CFG_ENABLE_BT_OVER_WIFI -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+/* @FIXME if there is command/event with payload length > 28 */ -+#define MAX_BUFFER_SIZE (64) -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+#if CFG_BOW_TEST -+UINT_32 g_u4PrevSysTime = 0; -+UINT_32 g_u4CurrentSysTime = 0; -+UINT_32 g_arBowRevPalPacketTime[11]; -+#endif -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/* forward declarations */ -+static ssize_t mt6620_ampc_read(IN struct file *filp, IN char __user *buf, IN size_t size, IN OUT loff_t *ppos); -+ -+static ssize_t -+mt6620_ampc_write(IN struct file *filp, OUT const char __user *buf, IN size_t size, IN OUT loff_t *ppos); -+ -+static long mt6620_ampc_ioctl(IN struct file *filp, IN unsigned int cmd, IN OUT unsigned long arg); -+ -+static unsigned int mt6620_ampc_poll(IN struct file *filp, IN poll_table *wait); -+ -+static int mt6620_ampc_open(IN struct inode *inodep, IN struct file *filp); -+ -+static int mt6620_ampc_release(IN struct inode *inodep, IN struct file *filp); -+ -+/* character file operations */ -+static const struct file_operations mt6620_ampc_fops = { -+ /* .owner = THIS_MODULE, */ -+ .read = mt6620_ampc_read, -+ .write = mt6620_ampc_write, -+ .unlocked_ioctl = mt6620_ampc_ioctl, -+ .poll = mt6620_ampc_poll, -+ .open = mt6620_ampc_open, -+ .release = mt6620_ampc_release, -+}; -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Register for character device to communicate with 802.11 PAL -+* -+* \param[in] prGlueInfo Pointer to glue info -+* -+* \return TRUE -+* FALSE -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN glRegisterAmpc(IN P_GLUE_INFO_T prGlueInfo) -+{ -+ ASSERT(prGlueInfo); -+ -+ if (prGlueInfo->rBowInfo.fgIsRegistered == TRUE) -+ return FALSE; -+ -+#if 0 -+ /* 1. allocate major number dynamically */ -+ -+ if (alloc_chrdev_region(&(prGlueInfo->rBowInfo.u4DeviceNumber), 0, /* first minor number */ -+ 1, /* number */ -+ GLUE_BOW_DEVICE_NAME) != 0) -+ -+ return FALSE; -+#endif -+ -+#if 1 -+ -+#if defined(CONFIG_AMPC_CDEV_NUM) -+ prGlueInfo->rBowInfo.u4DeviceNumber = MKDEV(CONFIG_AMPC_CDEV_NUM, 0); -+#else -+ prGlueInfo->rBowInfo.u4DeviceNumber = MKDEV(226, 0); -+#endif -+ -+ if (register_chrdev_region(prGlueInfo->rBowInfo.u4DeviceNumber, 1, /* number */ -+ GLUE_BOW_DEVICE_NAME) != 0) -+ -+ return FALSE; -+#endif -+ -+ /* 2. spin-lock initialization */ -+ /* spin_lock_init(&(prGlueInfo->rBowInfo.rSpinLock)); */ -+ -+ /* 3. initialize kfifo */ -+/* prGlueInfo->rBowInfo.prKfifo = kfifo_alloc(GLUE_BOW_KFIFO_DEPTH, -+ GFP_KERNEL, -+ &(prGlueInfo->rBowInfo.rSpinLock));*/ -+ if ((kfifo_alloc((struct kfifo *)&(prGlueInfo->rBowInfo.rKfifo), GLUE_BOW_KFIFO_DEPTH, GFP_KERNEL))) -+ goto fail_kfifo_alloc; -+ -+/* if(prGlueInfo->rBowInfo.prKfifo == NULL) */ -+ if (&(prGlueInfo->rBowInfo.rKfifo) == NULL) -+ goto fail_kfifo_alloc; -+ -+ /* 4. initialize cdev */ -+ cdev_init(&(prGlueInfo->rBowInfo.cdev), &mt6620_ampc_fops); -+ /* prGlueInfo->rBowInfo.cdev.owner = THIS_MODULE; */ -+ prGlueInfo->rBowInfo.cdev.ops = &mt6620_ampc_fops; -+ -+ /* 5. add character device */ -+ if (cdev_add(&(prGlueInfo->rBowInfo.cdev), prGlueInfo->rBowInfo.u4DeviceNumber, 1)) -+ goto fail_cdev_add; -+ -+ /* 6. in queue initialization */ -+ init_waitqueue_head(&(prGlueInfo->rBowInfo.outq)); -+ -+ /* 7. finish */ -+ prGlueInfo->rBowInfo.fgIsRegistered = TRUE; -+ return TRUE; -+ -+fail_cdev_add: -+ kfifo_free(&(prGlueInfo->rBowInfo.rKfifo)); -+/* kfifo_free(prGlueInfo->rBowInfo.prKfifo); */ -+fail_kfifo_alloc: -+ unregister_chrdev_region(prGlueInfo->rBowInfo.u4DeviceNumber, 1); -+ return FALSE; -+} /* end of glRegisterAmpc */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Unregister character device for communicating with 802.11 PAL -+* -+* \param[in] prGlueInfo Pointer to glue info -+* -+* \return TRUE -+* FALSE -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN glUnregisterAmpc(IN P_GLUE_INFO_T prGlueInfo) -+{ -+ ASSERT(prGlueInfo); -+ -+ if (prGlueInfo->rBowInfo.fgIsRegistered == FALSE) -+ return FALSE; -+ -+ prGlueInfo->rBowInfo.fgIsRegistered = FALSE; -+ -+ /* 1. free netdev if necessary */ -+#if CFG_BOW_SEPARATE_DATA_PATH -+ kalUninitBowDevice(prGlueInfo); -+#endif -+ -+ /* 2. removal of character device */ -+ cdev_del(&(prGlueInfo->rBowInfo.cdev)); -+ -+ /* 3. free kfifo */ -+/* kfifo_free(prGlueInfo->rBowInfo.prKfifo); */ -+ kfifo_free(&(prGlueInfo->rBowInfo.rKfifo)); -+/* prGlueInfo->rBowInfo.prKfifo = NULL; */ -+/* prGlueInfo->rBowInfo.rKfifo = NULL; */ -+ -+ /* 4. free device number */ -+ unregister_chrdev_region(prGlueInfo->rBowInfo.u4DeviceNumber, 1); -+ -+ return TRUE; -+} /* end of glUnregisterAmpc */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief read handler for character device to communicate with 802.11 PAL -+* -+* \param[in] -+* \return -+* Follows Linux Character Device Interface -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static ssize_t mt6620_ampc_read(IN struct file *filp, IN char __user *buf, IN size_t size, IN OUT loff_t *ppos) -+{ -+ UINT_8 aucBuffer[MAX_BUFFER_SIZE]; -+ ssize_t retval; -+ P_GLUE_INFO_T prGlueInfo; -+ -+ prGlueInfo = (P_GLUE_INFO_T) (filp->private_data); -+ -+ ASSERT(prGlueInfo); -+ -+ if ((prGlueInfo->rBowInfo.fgIsRegistered == FALSE) || (prGlueInfo->ulFlag & GLUE_FLAG_HALT)) -+ return -EFAULT; -+ /* size check */ -+/* if(kfifo_len(prGlueInfo->rBowInfo.prKfifo) >= size) */ -+ if (kfifo_len(&(prGlueInfo->rBowInfo.rKfifo)) >= size) -+ retval = size; -+ else -+ retval = kfifo_len(&(prGlueInfo->rBowInfo.rKfifo)); -+/* retval = kfifo_len(prGlueInfo->rBowInfo.prKfifo); */ -+ -+/* kfifo_get(prGlueInfo->rBowInfo.prKfifo, aucBuffer, retval); */ -+/* kfifo_out(prGlueInfo->rBowInfo.prKfifo, aucBuffer, retval); */ -+ if (!(kfifo_out(&(prGlueInfo->rBowInfo.rKfifo), aucBuffer, retval))) { -+ retval = -EIO; -+ return retval; -+ } -+ -+ if (copy_to_user(buf, aucBuffer, retval)) -+ retval = -EIO; -+ -+ return retval; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief write handler for character device to communicate with 802.11 PAL -+* -+* \param[in] -+* \return -+* Follows Linux Character Device Interface -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static ssize_t -+mt6620_ampc_write(IN struct file *filp, OUT const char __user *buf, IN size_t size, IN OUT loff_t *ppos) -+{ -+#if CFG_BOW_TEST -+ UINT_8 i; -+#endif -+ -+ UINT_8 aucBuffer[MAX_BUFFER_SIZE]; -+ P_AMPC_COMMAND prCmd; -+ P_GLUE_INFO_T prGlueInfo; -+ -+ prGlueInfo = (P_GLUE_INFO_T) (filp->private_data); -+ ASSERT(prGlueInfo); -+ -+ if ((prGlueInfo->rBowInfo.fgIsRegistered == FALSE) || (prGlueInfo->ulFlag & GLUE_FLAG_HALT)) -+ return -EFAULT; -+ -+ if (size > MAX_BUFFER_SIZE) -+ return -EINVAL; -+ else if (copy_from_user(aucBuffer, buf, size)) -+ return -EIO; -+ -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "AMP driver CMD buffer size : %d.\n", size); -+ -+ for (i = 0; i < MAX_BUFFER_SIZE; i++) -+ DBGLOG(BOW, EVENT, "AMP write content : 0x%x.\n", aucBuffer[i]); -+ -+ DBGLOG(BOW, EVENT, "BoW CMD write.\n"); -+#endif -+ -+ prCmd = (P_AMPC_COMMAND) aucBuffer; -+ -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "AMP write content payload length : %d.\n", prCmd->rHeader.u2PayloadLength); -+ -+ DBGLOG(BOW, EVENT, "AMP write content header length : %d.\n", sizeof(AMPC_COMMAND_HEADER_T)); -+#endif -+ -+ /* size check */ -+ if (prCmd->rHeader.u2PayloadLength + sizeof(AMPC_COMMAND_HEADER_T) != size) { -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "Wrong CMD total length.\n"); -+#endif -+ -+ return -EINVAL; -+ } -+ -+ if (wlanbowHandleCommand(prGlueInfo->prAdapter, prCmd) == WLAN_STATUS_SUCCESS) -+ return size; -+ else -+ return -EINVAL; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief ioctl handler for character device to communicate with 802.11 PAL -+* -+* \param[in] -+* \return -+* Follows Linux Character Device Interface -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static long mt6620_ampc_ioctl(IN struct file *filp, IN unsigned int cmd, IN OUT unsigned long arg) -+{ -+ int err = 0; -+ P_GLUE_INFO_T prGlueInfo; -+ -+ prGlueInfo = (P_GLUE_INFO_T) (filp->private_data); -+ -+ ASSERT(prGlueInfo); -+ -+ if ((prGlueInfo->rBowInfo.fgIsRegistered == FALSE) || (prGlueInfo->ulFlag & GLUE_FLAG_HALT)) -+ return -EFAULT; -+ /* permission check */ -+ if (_IOC_DIR(cmd) & _IOC_READ) -+ err = !access_ok(VERIFY_WRITE, (void __user *)arg, _IOC_SIZE(cmd)); -+ else if (_IOC_DIR(cmd) & _IOC_WRITE) -+ err = !access_ok(VERIFY_READ, (void __user *)arg, _IOC_SIZE(cmd)); -+ if (err) -+ return -EFAULT; -+ -+ /* no ioctl is implemented yet */ -+ return 0; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief ioctl handler for character device to communicate with 802.11 PAL -+* -+* \param[in] -+* \return -+* Follows Linux Character Device Interface -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static unsigned int mt6620_ampc_poll(IN struct file *filp, IN poll_table *wait) -+{ -+ unsigned int retval; -+ P_GLUE_INFO_T prGlueInfo; -+ -+ prGlueInfo = (P_GLUE_INFO_T) (filp->private_data); -+ -+ ASSERT(prGlueInfo); -+ -+ if ((prGlueInfo->rBowInfo.fgIsRegistered == FALSE) || (prGlueInfo->ulFlag & GLUE_FLAG_HALT)) -+ return -EFAULT; -+ -+ poll_wait(filp, &prGlueInfo->rBowInfo.outq, wait); -+ -+ retval = (POLLOUT | POLLWRNORM); /* always accepts incoming command packets */ -+ -+/* DBGLOG(BOW, EVENT, ("mt6620_ampc_pol, POLLOUT | POLLWRNORM, %x\n", retval)); */ -+ -+/* if(kfifo_len(prGlueInfo->rBowInfo.prKfifo) > 0) */ -+ if (kfifo_len(&(prGlueInfo->rBowInfo.rKfifo)) > 0) { -+ retval |= (POLLIN | POLLRDNORM); -+ -+/* DBGLOG(BOW, EVENT, ("mt6620_ampc_pol, POLLIN | POLLRDNORM, %x\n", retval)); */ -+ -+ } -+ -+ return retval; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief open handler for character device to communicate with 802.11 PAL -+* -+* \param[in] -+* \return -+* Follows Linux Character Device Interface -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static int mt6620_ampc_open(IN struct inode *inodep, IN struct file *filp) -+{ -+ P_GLUE_INFO_T prGlueInfo; -+ P_GL_BOW_INFO prBowInfo; -+ -+ prBowInfo = container_of(inodep->i_cdev, GL_BOW_INFO, cdev); -+ ASSERT(prBowInfo); -+ -+ prGlueInfo = container_of(prBowInfo, GLUE_INFO_T, rBowInfo); -+ ASSERT(prGlueInfo); -+ -+ /* set-up private data */ -+ filp->private_data = prGlueInfo; -+ -+ return 0; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief close handler for character device to communicate with 802.11 PAL -+* -+* \param[in] -+* \return -+* Follows Linux Character Device Interface -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static int mt6620_ampc_release(IN struct inode *inodep, IN struct file *filp) -+{ -+ P_GLUE_INFO_T prGlueInfo; -+ -+ prGlueInfo = (P_GLUE_INFO_T) (filp->private_data); -+ -+ ASSERT(prGlueInfo); -+ -+ return 0; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief to indicate event for Bluetooth over Wi-Fi -+* -+* \param[in] -+* prGlueInfo -+* prEvent -+* \return -+* none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID kalIndicateBOWEvent(IN P_GLUE_INFO_T prGlueInfo, IN P_AMPC_EVENT prEvent) -+{ -+ size_t u4AvailSize, u4EventSize; -+ -+ ASSERT(prGlueInfo); -+ ASSERT(prEvent); -+ -+ /* check device */ -+ if ((prGlueInfo->rBowInfo.fgIsRegistered == FALSE) || (prGlueInfo->ulFlag & GLUE_FLAG_HALT)) -+ return; -+ -+/* u4AvailSize = -+ GLUE_BOW_KFIFO_DEPTH - kfifo_len(prGlueInfo->rBowInfo.prKfifo);*/ -+ -+ u4AvailSize = GLUE_BOW_KFIFO_DEPTH - kfifo_len(&(prGlueInfo->rBowInfo.rKfifo)); -+ -+ u4EventSize = prEvent->rHeader.u2PayloadLength + sizeof(AMPC_EVENT_HEADER_T); -+ -+ /* check kfifo availability */ -+ if (u4AvailSize < u4EventSize) { -+ DBGLOG(BOW, EVENT, "[bow] no space for event: %zu/%zu\n", u4EventSize, u4AvailSize); -+ return; -+ } -+ /* queue into kfifo */ -+/* kfifo_put(prGlueInfo->rBowInfo.prKfifo, (PUINT_8)prEvent, u4EventSize); */ -+/* kfifo_in(prGlueInfo->rBowInfo.prKfifo, (PUINT_8)prEvent, u4EventSize); */ -+ kfifo_in(&(prGlueInfo->rBowInfo.rKfifo), (PUINT_8) prEvent, u4EventSize); -+ wake_up_interruptible(&(prGlueInfo->rBowInfo.outq)); -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief to retrieve Bluetooth-over-Wi-Fi state from glue layer -+* -+* \param[in] -+* prGlueInfo -+* rPeerAddr -+* \return -+* ENUM_BOW_DEVICE_STATE -+*/ -+/*----------------------------------------------------------------------------*/ -+ENUM_BOW_DEVICE_STATE kalGetBowState(IN P_GLUE_INFO_T prGlueInfo, IN UINT_8 aucPeerAddress[6]) -+{ -+ UINT_8 i; -+ -+ ASSERT(prGlueInfo); -+ -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "kalGetBowState.\n"); -+#endif -+ -+ for (i = 0; i < CFG_BOW_PHYSICAL_LINK_NUM; i++) { -+ if (EQUAL_MAC_ADDR(prGlueInfo->rBowInfo.arPeerAddr, aucPeerAddress) == 0) { -+ -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "kalGetBowState, aucPeerAddress %x, %x:%x:%x:%x:%x:%x.\n", i, -+ aucPeerAddress[0], -+ aucPeerAddress[1], -+ aucPeerAddress[2], -+ aucPeerAddress[3], aucPeerAddress[4], aucPeerAddress[5])); -+ -+ DBGLOG(BOW, EVENT, -+ "kalGetBowState, prGlueInfo->rBowInfo.aeState %x, %x.\n", i, -+ prGlueInfo->rBowInfo.aeState[i]); -+ -+#endif -+ -+ return prGlueInfo->rBowInfo.aeState[i]; -+ } -+ } -+ -+ return BOW_DEVICE_STATE_DISCONNECTED; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief to set Bluetooth-over-Wi-Fi state in glue layer -+* -+* \param[in] -+* prGlueInfo -+* eBowState -+* rPeerAddr -+* \return -+* none -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN kalSetBowState(IN P_GLUE_INFO_T prGlueInfo, IN ENUM_BOW_DEVICE_STATE eBowState, IN UINT_8 aucPeerAddress[6]) -+{ -+ UINT_8 i; -+ -+ ASSERT(prGlueInfo); -+ -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "kalSetBowState.\n"); -+ -+ DBGLOG(BOW, EVENT, "kalSetBowState, prGlueInfo->rBowInfo.arPeerAddr, %x:%x:%x:%x:%x:%x.\n", -+ prGlueInfo->rBowInfo.arPeerAddr[0], -+ prGlueInfo->rBowInfo.arPeerAddr[1], -+ prGlueInfo->rBowInfo.arPeerAddr[2], -+ prGlueInfo->rBowInfo.arPeerAddr[3], -+ prGlueInfo->rBowInfo.arPeerAddr[4], prGlueInfo->rBowInfo.arPeerAddr[5])); -+ -+ DBGLOG(BOW, EVENT, "kalSetBowState, aucPeerAddress, %x:%x:%x:%x:%x:%x.\n", -+ aucPeerAddress[0], -+ aucPeerAddress[1], -+ aucPeerAddress[2], aucPeerAddress[3], aucPeerAddress[4], aucPeerAddress[5]); -+#endif -+ -+ for (i = 0; i < CFG_BOW_PHYSICAL_LINK_NUM; i++) { -+ if (EQUAL_MAC_ADDR(prGlueInfo->rBowInfo.arPeerAddr, aucPeerAddress) == 0) { -+ prGlueInfo->rBowInfo.aeState[i] = eBowState; -+ -+#if CFG_BOW_TEST -+ DBGLOG(BOW, EVENT, "kalSetBowState, aucPeerAddress %x, %x:%x:%x:%x:%x:%x.\n", i, -+ aucPeerAddress[0], -+ aucPeerAddress[1], -+ aucPeerAddress[2], -+ aucPeerAddress[3], aucPeerAddress[4], aucPeerAddress[5])); -+ -+ DBGLOG(BOW, EVENT, -+ "kalSetBowState, prGlueInfo->rBowInfo.aeState %x, %x.\n", i, -+ prGlueInfo->rBowInfo.aeState[i]); -+#endif -+ -+ return TRUE; -+ } -+ } -+ -+ return FALSE; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief to retrieve Bluetooth-over-Wi-Fi global state -+* -+* \param[in] -+* prGlueInfo -+* -+* \return -+* BOW_DEVICE_STATE_DISCONNECTED -+* in case there is no BoW connection or -+* BoW connection under initialization -+* -+* BOW_DEVICE_STATE_STARTING -+* in case there is no BoW connection but -+* some BoW connection under initialization -+* -+* BOW_DEVICE_STATE_CONNECTED -+* in case there is any BoW connection available -+*/ -+/*----------------------------------------------------------------------------*/ -+ENUM_BOW_DEVICE_STATE kalGetBowGlobalState(IN P_GLUE_INFO_T prGlueInfo) -+{ -+ UINT_32 i; -+ -+ ASSERT(prGlueInfo); -+ -+/* Henry, can reduce this logic to indentify state change */ -+ -+ for (i = 0; i < CFG_BOW_PHYSICAL_LINK_NUM; i++) { -+ if (prGlueInfo->rBowInfo.aeState[i] == BOW_DEVICE_STATE_CONNECTED) -+ return BOW_DEVICE_STATE_CONNECTED; -+ } -+ -+ for (i = 0; i < CFG_BOW_PHYSICAL_LINK_NUM; i++) { -+ if (prGlueInfo->rBowInfo.aeState[i] == BOW_DEVICE_STATE_STARTING) -+ return BOW_DEVICE_STATE_STARTING; -+ } -+ -+ return BOW_DEVICE_STATE_DISCONNECTED; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief to retrieve Bluetooth-over-Wi-Fi operating frequency -+* -+* \param[in] -+* prGlueInfo -+* -+* \return -+* in unit of KHz -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT_32 kalGetBowFreqInKHz(IN P_GLUE_INFO_T prGlueInfo) -+{ -+ ASSERT(prGlueInfo); -+ -+ return prGlueInfo->rBowInfo.u4FreqInKHz; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief to retrieve Bluetooth-over-Wi-Fi role -+* -+* \param[in] -+* prGlueInfo -+* -+* \return -+* 0: Responder -+* 1: Initiator -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT_8 kalGetBowRole(IN P_GLUE_INFO_T prGlueInfo, IN PARAM_MAC_ADDRESS rPeerAddr) -+{ -+ UINT_32 i; -+ -+ ASSERT(prGlueInfo); -+ -+ for (i = 0; i < CFG_BOW_PHYSICAL_LINK_NUM; i++) { -+ if (EQUAL_MAC_ADDR(prGlueInfo->rBowInfo.arPeerAddr[i], rPeerAddr) == 0) -+ return prGlueInfo->rBowInfo.aucRole[i]; -+ } -+ -+ return 0; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief to set Bluetooth-over-Wi-Fi role -+* -+* \param[in] -+* prGlueInfo -+* ucRole -+* 0: Responder -+* 1: Initiator -+* \return -+* none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID kalSetBowRole(IN P_GLUE_INFO_T prGlueInfo, IN UINT_8 ucRole, IN PARAM_MAC_ADDRESS rPeerAddr) -+{ -+ UINT_32 i; -+ -+ ASSERT(prGlueInfo); -+ ASSERT(ucRole <= 1); -+ -+ for (i = 0; i < CFG_BOW_PHYSICAL_LINK_NUM; i++) { -+ if (EQUAL_MAC_ADDR(prGlueInfo->rBowInfo.arPeerAddr[i], rPeerAddr) == 0) -+ prGlueInfo->rBowInfo.aucRole[i] = ucRole; /* Henry, 0 : Responder, 1 : Initiator */ -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief to get available Bluetooth-over-Wi-Fi physical link number -+* -+* \param[in] -+* prGlueInfo -+* \return -+* UINT_32 -+* how many physical links are aviailable -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT_8 kalGetBowAvailablePhysicalLinkCount(IN P_GLUE_INFO_T prGlueInfo) -+{ -+ UINT_8 i; -+ UINT_8 ucLinkCount = 0; -+ -+ ASSERT(prGlueInfo); -+ -+ for (i = 0; i < CFG_BOW_PHYSICAL_LINK_NUM; i++) { -+ if (prGlueInfo->rBowInfo.aeState[i] == BOW_DEVICE_STATE_DISCONNECTED) -+ ucLinkCount++; -+ } -+ -+#if 0 /* CFG_BOW_TEST */ -+ DBGLOG(BOW, EVENT, "kalGetBowAvailablePhysicalLinkCount, ucLinkCount, %c.\n", ucLinkCount); -+#endif -+ -+ return ucLinkCount; -+} -+ -+#if CFG_BOW_SEPARATE_DATA_PATH -+ -+/* Net Device Hooks */ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * \brief A function for net_device open (ifup) -+ * -+ * \param[in] prDev Pointer to struct net_device. -+ * -+ * \retval 0 The execution succeeds. -+ * \retval < 0 The execution failed. -+ */ -+/*----------------------------------------------------------------------------*/ -+static int bowOpen(IN struct net_device *prDev) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ P_ADAPTER_T prAdapter = NULL; -+ -+ ASSERT(prDev); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ ASSERT(prGlueInfo); -+ -+ prAdapter = prGlueInfo->prAdapter; -+ ASSERT(prAdapter); -+ -+ /* 2. carrier on & start TX queue */ -+ netif_carrier_on(prDev); -+ netif_tx_start_all_queues(prDev); -+ -+ return 0; /* success */ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * \brief A function for net_device stop (ifdown) -+ * -+ * \param[in] prDev Pointer to struct net_device. -+ * -+ * \retval 0 The execution succeeds. -+ * \retval < 0 The execution failed. -+ */ -+/*----------------------------------------------------------------------------*/ -+static int bowStop(IN struct net_device *prDev) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ P_ADAPTER_T prAdapter = NULL; -+ -+ ASSERT(prDev); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ ASSERT(prGlueInfo); -+ -+ prAdapter = prGlueInfo->prAdapter; -+ ASSERT(prAdapter); -+ -+ /* 1. stop TX queue */ -+ netif_tx_stop_all_queues(prDev); -+ -+ /* 2. turn of carrier */ -+ if (netif_carrier_ok(prDev)) -+ netif_carrier_off(prDev); -+ -+ return 0; -+}; -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * \brief This function is TX entry point of NET DEVICE. -+ * -+ * \param[in] prSkb Pointer of the sk_buff to be sent -+ * \param[in] prDev Pointer to struct net_device -+ * -+ * \retval NETDEV_TX_OK - on success. -+ * \retval NETDEV_TX_BUSY - on failure, packet will be discarded by upper layer. -+ */ -+/*----------------------------------------------------------------------------*/ -+static int bowHardStartXmit(IN struct sk_buff *prSkb, IN struct net_device *prDev) -+{ -+ P_GLUE_INFO_T prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ -+ P_QUE_ENTRY_T prQueueEntry = NULL; -+ P_QUE_T prTxQueue = NULL; -+ UINT_16 u2QueueIdx = 0; -+ UINT_8 ucDSAP, ucSSAP, ucControl; -+ UINT_8 aucOUI[3]; -+ PUINT_8 aucLookAheadBuf = NULL; -+ -+#if CFG_BOW_TEST -+ UINT_32 i; -+#endif -+ -+ GLUE_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(prSkb); -+ ASSERT(prDev); -+ ASSERT(prGlueInfo); -+ -+ aucLookAheadBuf = prSkb->data; -+ -+ ucDSAP = *(PUINT_8) &aucLookAheadBuf[ETH_LLC_OFFSET]; -+ ucSSAP = *(PUINT_8) &aucLookAheadBuf[ETH_LLC_OFFSET + 1]; -+ ucControl = *(PUINT_8) &aucLookAheadBuf[ETH_LLC_OFFSET + 2]; -+ aucOUI[0] = *(PUINT_8) &aucLookAheadBuf[ETH_SNAP_OFFSET]; -+ aucOUI[1] = *(PUINT_8) &aucLookAheadBuf[ETH_SNAP_OFFSET + 1]; -+ aucOUI[2] = *(PUINT_8) &aucLookAheadBuf[ETH_SNAP_OFFSET + 2]; -+ prGlueInfo->u8SkbToDriver++; -+ -+ if (!(ucDSAP == ETH_LLC_DSAP_SNAP && -+ ucSSAP == ETH_LLC_SSAP_SNAP && -+ ucControl == ETH_LLC_CONTROL_UNNUMBERED_INFORMATION && -+ aucOUI[0] == ETH_SNAP_BT_SIG_OUI_0 && -+ aucOUI[1] == ETH_SNAP_BT_SIG_OUI_1 && aucOUI[2] == ETH_SNAP_BT_SIG_OUI_2) || (prSkb->len > 1514)) { -+ -+#if CFG_BOW_TEST -+ DBGLOG(BOW, TRACE, "Invalid BOW packet, skip tx\n"); -+#endif -+ -+ dev_kfree_skb(prSkb); -+ prGlueInfo->u8SkbFreed++; -+ return NETDEV_TX_OK; -+ } -+ -+ if (prGlueInfo->ulFlag & GLUE_FLAG_HALT) { -+ DBGLOG(BOW, TRACE, "GLUE_FLAG_HALT skip tx\n"); -+ dev_kfree_skb(prSkb); -+ prGlueInfo->u8SkbFreed++; -+ return NETDEV_TX_OK; -+ } -+ -+ prQueueEntry = (P_QUE_ENTRY_T) GLUE_GET_PKT_QUEUE_ENTRY(prSkb); -+ prTxQueue = &prGlueInfo->rTxQueue; -+ -+#if CFG_BOW_TEST -+ DBGLOG(BOW, TRACE, "Tx sk_buff->len: %d\n", prSkb->len); -+ DBGLOG(BOW, TRACE, "Tx sk_buff->data_len: %d\n", prSkb->data_len); -+ DBGLOG(BOW, TRACE, "Tx sk_buff->data:\n"); -+ -+ for (i = 0; i < prSkb->len; i++) { -+ DBGLOG(BOW, TRACE, "%4x", prSkb->data[i]); -+ -+ if ((i + 1) % 16 == 0) -+ DBGLOG(BOW, TRACE, "\n"); -+ } -+ -+ DBGLOG(BOW, TRACE, "\n"; -+#endif -+#if CFG_BOW_TEST -+/* g_u4CurrentSysTime = (OS_SYSTIME)kalGetTimeTick(; */ -+ g_u4CurrentSysTime = (OS_SYSTIME) jiffies_to_usecs(jiffies); -+ i = g_u4CurrentSysTime - g_u4PrevSysTime; -+ if ((i >> 10) > 0) -+ i = 10; -+ else -+ i = i >> 7; -+ g_arBowRevPalPacketTime[i]++; -+ g_u4PrevSysTime = g_u4CurrentSysTime; -+#endif -+ if (wlanProcessSecurityFrame(prGlueInfo->prAdapter, (P_NATIVE_PACKET) prSkb) == FALSE) { -+ GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_TX_QUE); -+ QUEUE_INSERT_TAIL(prTxQueue, prQueueEntry); -+ GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_TX_QUE); -+ GLUE_INC_REF_CNT(prGlueInfo->i4TxPendingFrameNum); -+ GLUE_INC_REF_CNT(prGlueInfo->ai4TxPendingFrameNumPerQueue[NETWORK_TYPE_BOW_INDEX][u2QueueIdx]); -+ if (prGlueInfo->ai4TxPendingFrameNumPerQueue[NETWORK_TYPE_BOW_INDEX][u2QueueIdx] >= -+ CFG_TX_STOP_NETIF_PER_QUEUE_THRESHOLD) -+ DBGLOG(TX, INFO, "netif_stop_subqueue for BOW, Queue len: %d\n", -+ prGlueInfo->ai4TxPendingFrameNumPerQueue[NETWORK_TYPE_BOW_INDEX][u2QueueIdx]); -+ -+ netif_stop_subqueue(prDev, u2QueueIdx); -+ } else { -+ GLUE_INC_REF_CNT(prGlueInfo->i4TxPendingSecurityFrameNum); -+ } -+ -+ kalSetEvent(prGlueInfo); -+ /* For Linux, we'll always return OK FLAG, because we'll free this skb by ourself */ -+ return NETDEV_TX_OK; -+} -+ -+/* callbacks for netdevice */ -+static const struct net_device_ops bow_netdev_ops = { -+ .ndo_open = bowOpen, .ndo_stop = bowStop, .ndo_start_xmit = bowHardStartXmit,}; -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief initialize net device for Bluetooth-over-Wi-Fi -+* -+* \param[in] -+* prGlueInfo -+* prDevName -+* -+* \return -+* TRUE -+* FALSE -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN kalInitBowDevice(IN P_GLUE_INFO_T prGlueInfo, IN const char *prDevName) -+{ -+ P_ADAPTER_T prAdapter; -+ P_GL_HIF_INFO_T prHif; -+ PARAM_MAC_ADDRESS rMacAddr; -+ -+ ASSERT(prGlueInfo); -+ ASSERT(prGlueInfo->rBowInfo.fgIsRegistered == TRUE); -+ prAdapter = prGlueInfo->prAdapter; -+ ASSERT(prAdapter); -+ prHif = &prGlueInfo->rHifInfo; -+ ASSERT(prHif); -+ if (prGlueInfo->rBowInfo.fgIsNetRegistered == FALSE) { -+ prGlueInfo->rBowInfo.prDevHandler = -+ alloc_netdev_mq(sizeof(P_GLUE_INFO_T), prDevName, NET_NAME_PREDICTABLE, ether_setup, CFG_MAX_TXQ_NUM); -+ if (!prGlueInfo->rBowInfo.prDevHandler) -+ return FALSE; -+ -+ /* 1. setup netdev */ -+ /* 1.1 Point to shared glue structure */ -+ *((P_GLUE_INFO_T *) netdev_priv(prGlueInfo->rBowInfo.prDevHandler)) = prGlueInfo; -+ /* 1.2 fill hardware address */ -+ COPY_MAC_ADDR(rMacAddr, prAdapter->rMyMacAddr); -+ rMacAddr[0] |= 0x2; -+ /* change to local administrated address */ -+ ether_addr_copy(prGlueInfo->rBowInfo.prDevHandler->dev_addr, rMacAddr); -+ ether_addr_copy(prGlueInfo->rBowInfo.prDevHandler->perm_addr, -+ prGlueInfo->rBowInfo.prDevHandler->dev_addr); -+ /* 1.3 register callback functions */ -+ prGlueInfo->rBowInfo.prDevHandler->netdev_ops = &bow_netdev_ops; -+#if (MTK_WCN_HIF_SDIO == 0) -+ SET_NETDEV_DEV(prGlueInfo->rBowInfo.prDevHandler, prHif->Dev); -+#endif -+ register_netdev(prGlueInfo->rBowInfo.prDevHandler); -+ /* 2. net device initialize */ -+ netif_carrier_off(prGlueInfo->rBowInfo.prDevHandler); -+ netif_tx_stop_all_queues(prGlueInfo->rBowInfo.prDevHandler); -+ /* 3. finish */ -+ prGlueInfo->rBowInfo.fgIsNetRegistered = TRUE; -+ } -+ -+ return TRUE; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief uninitialize net device for Bluetooth-over-Wi-Fi -+* -+* \param[in] -+* prGlueInfo -+* -+* \return -+* TRUE -+* FALSE -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN kalUninitBowDevice(IN P_GLUE_INFO_T prGlueInfo) -+{ -+ ASSERT(prGlueInfo); -+ /* ASSERT(prGlueInfo->rBowInfo.fgIsRegistered == TRUE); */ -+ if (prGlueInfo->rBowInfo.fgIsNetRegistered == TRUE) { -+ prGlueInfo->rBowInfo.fgIsNetRegistered = FALSE; -+ if (netif_carrier_ok(prGlueInfo->rBowInfo.prDevHandler)) -+ netif_carrier_off(prGlueInfo->rBowInfo.prDevHandler); -+ -+ netif_tx_stop_all_queues(prGlueInfo->rBowInfo.prDevHandler); -+ /* netdevice unregistration & free */ -+ unregister_netdev(prGlueInfo->rBowInfo.prDevHandler); -+ free_netdev(prGlueInfo->rBowInfo.prDevHandler); -+ prGlueInfo->rBowInfo.prDevHandler = NULL; -+ return TRUE; -+ } else { -+ return FALSE; -+ } -+} -+#endif /* CFG_BOW_SEPARATE_DATA_PATH */ -+#endif /* CFG_ENABLE_BT_OVER_WIFI */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_cfg80211.c b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_cfg80211.c -new file mode 100644 -index 000000000000..1fed65ebc60e ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_cfg80211.c -@@ -0,0 +1,3110 @@ -+/* -+** Id: @(#) gl_cfg80211.c@@ -+*/ -+ -+/*! \file gl_cfg80211.c -+ \brief Main routines for supporintg MT6620 cfg80211 control interface -+ -+ This file contains the support routines of Linux driver for MediaTek Inc. 802.11 -+ Wireless LAN Adapters. -+*/ -+ -+/* -+** Log: gl_cfg80211.c -+** -+** 09 05 2013 cp.wu -+** correct length to pass to wlanoidSetBssid() -+** -+** 09 04 2013 cp.wu -+** fix typo -+** -+** 09 03 2013 cp.wu -+** add path for reassociation -+** -+** 11 23 2012 yuche.tsai -+** [ALPS00398671] [Acer-Tablet] Remove Wi-Fi Direct completely -+** Fix bug of WiFi may reboot under user load, when WiFi Direct is removed.. -+** -+** 09 12 2012 wcpadmin -+** [ALPS00276400] Remove MTK copyright and legal header on GPL/LGPL related packages -+** . -+** -+** 08 30 2012 chinglan.wang -+** [ALPS00349664] [6577JB][WIFI] Phone can not connect to AP secured with AES via WPS in 802.11n Only -+** . -+ * -+** -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "gl_os.h" -+#include "debug.h" -+#include "wlan_lib.h" -+#include "gl_wext.h" -+#include "precomp.h" -+#include -+#include -+#include -+#include "gl_cfg80211.h" -+#include "gl_vendor.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/* workaround for some ANR CRs. if suppliant is blocked longer than 10s, wifi hal will tell wifiMonitor -+to teminate. for the case which can block supplicant 10s is to del key more than 5 times. the root cause -+is that there is no resource in TC4, so del key command was not able to set, and then oid -+timeout was happed. if we found the root cause why fw couldn't release TC resouce, we will remove this -+workaround */ -+static UINT_8 gucKeyIndex = 255; -+ -+P_SW_RFB_T g_arGscnResultsTempBuffer[MAX_BUFFERED_GSCN_RESULTS]; -+UINT_8 g_GscanResultsTempBufferIndex = 0; -+UINT_8 g_arGscanResultsIndicateNumber[MAX_BUFFERED_GSCN_RESULTS] = { 0, 0, 0, 0, 0 }; -+ -+UINT_8 g_GetResultsBufferedCnt = 0; -+UINT_8 g_GetResultsCmdCnt = 0; -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * @brief This routine is responsible for change STA type between -+ * 1. Infrastructure Client (Non-AP STA) -+ * 2. Ad-Hoc IBSS -+ * -+ * @param -+ * -+ * @retval 0: successful -+ * others: failure -+ */ -+/*----------------------------------------------------------------------------*/ -+int -+mtk_cfg80211_change_iface(struct wiphy *wiphy, -+ struct net_device *ndev, enum nl80211_iftype type, /*u32 *flags,*/ struct vif_params *params) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ ENUM_PARAM_OP_MODE_T eOpMode; -+ UINT_32 u4BufLen; -+ -+ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); -+ ASSERT(prGlueInfo); -+ -+ if (type == NL80211_IFTYPE_STATION) -+ eOpMode = NET_TYPE_INFRA; -+ else if (type == NL80211_IFTYPE_ADHOC) -+ eOpMode = NET_TYPE_IBSS; -+ else -+ return -EINVAL; -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetInfrastructureMode, -+ &eOpMode, sizeof(eOpMode), FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) -+ DBGLOG(REQ, WARN, "set infrastructure mode error:%x\n", rStatus); -+ -+ /* reset wpa info */ -+ prGlueInfo->rWpaInfo.u4WpaVersion = IW_AUTH_WPA_VERSION_DISABLED; -+ prGlueInfo->rWpaInfo.u4KeyMgmt = 0; -+ prGlueInfo->rWpaInfo.u4CipherGroup = IW_AUTH_CIPHER_NONE; -+ prGlueInfo->rWpaInfo.u4CipherPairwise = IW_AUTH_CIPHER_NONE; -+ prGlueInfo->rWpaInfo.u4AuthAlg = IW_AUTH_ALG_OPEN_SYSTEM; -+#if CFG_SUPPORT_802_11W -+ prGlueInfo->rWpaInfo.u4Mfp = IW_AUTH_MFP_DISABLED; -+#endif -+ -+ return 0; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * @brief This routine is responsible for adding key -+ * -+ * @param -+ * -+ * @retval 0: successful -+ * others: failure -+ */ -+/*----------------------------------------------------------------------------*/ -+int -+mtk_cfg80211_add_key(struct wiphy *wiphy, -+ struct net_device *ndev, -+ u8 key_index, bool pairwise, const u8 *mac_addr, struct key_params *params) -+{ -+ PARAM_KEY_T rKey; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ INT_32 i4Rslt = -EINVAL; -+ UINT_32 u4BufLen = 0; -+ UINT_8 tmp1[8]; -+ UINT_8 tmp2[8]; -+ -+ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); -+ ASSERT(prGlueInfo); -+ -+ kalMemZero(&rKey, sizeof(PARAM_KEY_T)); -+ -+ rKey.u4KeyIndex = key_index; -+ -+ if (mac_addr) { -+ COPY_MAC_ADDR(rKey.arBSSID, mac_addr); -+ if ((rKey.arBSSID[0] == 0x00) && (rKey.arBSSID[1] == 0x00) && (rKey.arBSSID[2] == 0x00) && -+ (rKey.arBSSID[3] == 0x00) && (rKey.arBSSID[4] == 0x00) && (rKey.arBSSID[5] == 0x00)) { -+ rKey.arBSSID[0] = 0xff; -+ rKey.arBSSID[1] = 0xff; -+ rKey.arBSSID[2] = 0xff; -+ rKey.arBSSID[3] = 0xff; -+ rKey.arBSSID[4] = 0xff; -+ rKey.arBSSID[5] = 0xff; -+ } -+ if (rKey.arBSSID[0] != 0xFF) { -+ rKey.u4KeyIndex |= BIT(31); -+ if ((rKey.arBSSID[0] != 0x00) || (rKey.arBSSID[1] != 0x00) || (rKey.arBSSID[2] != 0x00) || -+ (rKey.arBSSID[3] != 0x00) || (rKey.arBSSID[4] != 0x00) || (rKey.arBSSID[5] != 0x00)) -+ rKey.u4KeyIndex |= BIT(30); -+ } -+ } else { -+ rKey.arBSSID[0] = 0xff; -+ rKey.arBSSID[1] = 0xff; -+ rKey.arBSSID[2] = 0xff; -+ rKey.arBSSID[3] = 0xff; -+ rKey.arBSSID[4] = 0xff; -+ rKey.arBSSID[5] = 0xff; -+ /* rKey.u4KeyIndex |= BIT(31);//Enable BIT 31 will make tx use bc key id,should use pairwise key id 0 */ -+ } -+ -+ if (params->key) { -+ /* rKey.aucKeyMaterial[0] = kalMemAlloc(params->key_len, VIR_MEM_TYPE); */ -+ kalMemCopy(rKey.aucKeyMaterial, params->key, params->key_len); -+ if (params->key_len == 32) { -+ kalMemCopy(tmp1, ¶ms->key[16], 8); -+ kalMemCopy(tmp2, ¶ms->key[24], 8); -+ kalMemCopy(&rKey.aucKeyMaterial[16], tmp2, 8); -+ kalMemCopy(&rKey.aucKeyMaterial[24], tmp1, 8); -+ } -+ } -+ -+ rKey.u4KeyLength = params->key_len; -+ rKey.u4Length = ((ULONG)&(((P_P2P_PARAM_KEY_T) 0)->aucKeyMaterial)) + rKey.u4KeyLength; -+ -+ rStatus = kalIoctl(prGlueInfo, wlanoidSetAddKey, &rKey, rKey.u4Length, FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ -+ if (rStatus == WLAN_STATUS_SUCCESS) -+ i4Rslt = 0; -+ -+ return i4Rslt; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * @brief This routine is responsible for getting key for specified STA -+ * -+ * @param -+ * -+ * @retval 0: successful -+ * others: failure -+ */ -+/*----------------------------------------------------------------------------*/ -+int -+mtk_cfg80211_get_key(struct wiphy *wiphy, -+ struct net_device *ndev, -+ u8 key_index, -+ bool pairwise, -+ const u8 *mac_addr, void *cookie, void (*callback) (void *cookie, struct key_params *)) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ -+ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); -+ ASSERT(prGlueInfo); -+ -+ DBGLOG(REQ, TRACE, "--> %s()\n", __func__); -+ -+ /* not implemented */ -+ -+ return -EINVAL; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * @brief This routine is responsible for removing key for specified STA -+ * -+ * @param -+ * -+ * @retval 0: successful -+ * others: failure -+ */ -+/*----------------------------------------------------------------------------*/ -+int mtk_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev, u8 key_index, bool pairwise, const u8 *mac_addr) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ PARAM_REMOVE_KEY_T rRemoveKey; -+ UINT_32 u4BufLen = 0; -+ INT_32 i4Rslt = -EINVAL; -+ -+ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); -+ ASSERT(prGlueInfo); -+ -+ kalMemZero(&rRemoveKey, sizeof(PARAM_REMOVE_KEY_T)); -+ if (mac_addr) -+ COPY_MAC_ADDR(rRemoveKey.arBSSID, mac_addr); -+ else if (key_index <= gucKeyIndex) { /* new operation, reset gucKeyIndex */ -+ gucKeyIndex = 255; -+ } else { /* bypass the next remove key operation */ -+ gucKeyIndex = key_index; -+ return -EBUSY; -+ } -+ rRemoveKey.u4KeyIndex = key_index; -+ rRemoveKey.u4Length = sizeof(PARAM_REMOVE_KEY_T); -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetRemoveKey, &rRemoveKey, rRemoveKey.u4Length, FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ DBGLOG(REQ, WARN, "remove key error:%x\n", rStatus); -+ if (WLAN_STATUS_FAILURE == rStatus && mac_addr) { -+ i4Rslt = -EBUSY; -+ gucKeyIndex = key_index; -+ } -+ } else { -+ gucKeyIndex = 255; -+ i4Rslt = 0; -+ } -+ -+ return i4Rslt; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * @brief This routine is responsible for setting default key on an interface -+ * -+ * @param -+ * -+ * @retval 0: successful -+ * others: failure -+ */ -+/*----------------------------------------------------------------------------*/ -+int -+mtk_cfg80211_set_default_key(struct wiphy *wiphy, struct net_device *ndev, u8 key_index, bool unicast, bool multicast) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ -+ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); -+ ASSERT(prGlueInfo); -+ -+ DBGLOG(REQ, TRACE, "--> %s()\n", __func__); -+ -+ /* not implemented */ -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * @brief This routine is responsible for setting set_default_mgmt_ke on an interface -+ * -+ * @param -+ * -+ * @retval 0: successful -+ * others: failure -+ */ -+/*----------------------------------------------------------------------------*/ -+int mtk_cfg80211_set_default_mgmt_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index) -+{ -+ return 0; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * @brief This routine is responsible for getting station information such as RSSI -+ * -+ * @param -+ * -+ * @retval 0: successful -+ * others: failure -+ */ -+/*----------------------------------------------------------------------------*/ -+int mtk_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev, const u8 *mac, struct station_info *sinfo) -+{ -+#define LINKSPEED_MAX_RANGE_11BGN 3000 -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ WLAN_STATUS rStatus; -+ PARAM_MAC_ADDRESS arBssid; -+ UINT_32 u4BufLen; -+ UINT_32 u4Rate = 0; -+ UINT_32 u8diffTxBad, u8diffRetry; -+ INT_32 i4Rssi = 0; -+ PARAM_802_11_STATISTICS_STRUCT_T rStatistics; -+ -+ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); -+ ASSERT(prGlueInfo); -+ -+ kalMemZero(arBssid, MAC_ADDR_LEN); -+ wlanQueryInformation(prGlueInfo->prAdapter, wlanoidQueryBssid, &arBssid[0], sizeof(arBssid), &u4BufLen); -+ -+ /* 1. check BSSID */ -+ if (UNEQUAL_MAC_ADDR(arBssid, mac)) { -+ /* wrong MAC address */ -+ DBGLOG(REQ, WARN, "incorrect BSSID: [ %pM ] currently connected BSSID[ %pM ]\n", -+ mac, arBssid); -+ return -ENOENT; -+ } -+ -+ /* 2. fill TX rate */ -+ if (prGlueInfo->eParamMediaStateIndicated != PARAM_MEDIA_STATE_CONNECTED) { -+ /* not connected */ -+ DBGLOG(REQ, WARN, "not yet connected\n"); -+ } else { -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidQueryLinkSpeed, &u4Rate, sizeof(u4Rate), TRUE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ sinfo->filled |= BIT(NL80211_STA_INFO_TX_BITRATE); -+ -+ if ((rStatus != WLAN_STATUS_SUCCESS) || (u4Rate == 0)) { -+ /* DBGLOG(REQ, WARN, "unable to retrieve link speed\n")); */ -+ DBGLOG(REQ, WARN, "last link speed\n"); -+ sinfo->txrate.legacy = prGlueInfo->u4LinkSpeedCache; -+ } else { -+ /* sinfo->filled |= STATION_INFO_TX_BITRATE; */ -+ sinfo->txrate.legacy = u4Rate / 1000; /* convert from 100bps to 100kbps */ -+ prGlueInfo->u4LinkSpeedCache = u4Rate / 1000; -+ } -+ } -+ -+ /* 3. fill RSSI */ -+ if (prGlueInfo->eParamMediaStateIndicated != PARAM_MEDIA_STATE_CONNECTED) { -+ /* not connected */ -+ DBGLOG(REQ, WARN, "not yet connected\n"); -+ } else { -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidQueryRssi, &i4Rssi, sizeof(i4Rssi), TRUE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS || (i4Rssi == PARAM_WHQL_RSSI_MIN_DBM) -+ || (i4Rssi == PARAM_WHQL_RSSI_MAX_DBM)) { -+ /* DBGLOG(REQ, WARN, "unable to retrieve link speed\n"); */ -+ DBGLOG(REQ, WARN, "last rssi\n"); -+ sinfo->signal = prGlueInfo->i4RssiCache; -+ } else { -+ /* in the cfg80211 layer, the signal is a signed char variable. */ -+ sinfo->signal = i4Rssi; /* dBm */ -+ prGlueInfo->i4RssiCache = i4Rssi; -+ } -+ sinfo->rx_packets = prGlueInfo->rNetDevStats.rx_packets; -+ -+ /* 4. Fill Tx OK and Tx Bad */ -+ -+ sinfo->filled |= BIT(NL80211_STA_INFO_TX_PACKETS); -+ sinfo->filled |= BIT(NL80211_STA_INFO_TX_FAILED); -+ { -+ WLAN_STATUS rStatus; -+ -+ kalMemZero(&rStatistics, sizeof(rStatistics)); -+ /* Get Tx OK/Fail cnt from AIS statistic counter */ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidQueryStatisticsPL, -+ &rStatistics, sizeof(rStatistics), TRUE, TRUE, TRUE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ DBGLOG(REQ, WARN, "unable to retrieive statistic\n"); -+ } else { -+ INT_32 i4RssiThreshold = -85; /* set rssi threshold -85dBm */ -+ UINT_32 u4LinkspeedThreshold = 55; /* set link speed threshold 5.5Mbps */ -+ BOOLEAN fgWeighted = 0; -+ -+ /* calculate difference */ -+ u8diffTxBad = rStatistics.rFailedCount.QuadPart - prGlueInfo->u8Statistic[0]; -+ u8diffRetry = rStatistics.rRetryCount.QuadPart - prGlueInfo->u8Statistic[1]; -+ /* restore counters */ -+ prGlueInfo->u8Statistic[0] = rStatistics.rFailedCount.QuadPart; -+ prGlueInfo->u8Statistic[1] = rStatistics.rRetryCount.QuadPart; -+ -+ /* check threshold is valid */ -+ if (prGlueInfo->fgPoorlinkValid) { -+ if (prGlueInfo->i4RssiThreshold) -+ i4RssiThreshold = prGlueInfo->i4RssiThreshold; -+ if (prGlueInfo->u4LinkspeedThreshold) -+ u4LinkspeedThreshold = prGlueInfo->u4LinkspeedThreshold; -+ } -+ /* add weighted to fail counter */ -+ if (sinfo->txrate.legacy < u4LinkspeedThreshold || sinfo->signal < i4RssiThreshold) { -+ prGlueInfo->u8TotalFailCnt += (u8diffTxBad * 16 + u8diffRetry); -+ fgWeighted = 1; -+ } else { -+ prGlueInfo->u8TotalFailCnt += u8diffTxBad; -+ } -+ /* report counters */ -+ prGlueInfo->rNetDevStats.tx_packets = rStatistics.rTransmittedFragmentCount.QuadPart; -+ prGlueInfo->rNetDevStats.tx_errors = prGlueInfo->u8TotalFailCnt; -+ -+ sinfo->tx_packets = prGlueInfo->rNetDevStats.tx_packets; -+ sinfo->tx_failed = prGlueInfo->rNetDevStats.tx_errors; -+ /* Good Fail Bad Difference retry difference Linkspeed Rate Weighted */ -+ DBGLOG(REQ, TRACE, -+ "Poorlink State TxOK(%d) TxFail(%d) Bad(%d) Retry(%d)", -+ sinfo->tx_packets, -+ sinfo->tx_failed, -+ (int)u8diffTxBad, -+ (int)u8diffRetry); -+ DBGLOG(REQ, TRACE, -+ "Rate(%d) Signal(%d) Weight(%d) QuadPart(%d)\n", -+ sinfo->txrate.legacy, -+ sinfo->signal, -+ (int)fgWeighted, -+ (int)rStatistics.rMultipleRetryCount.QuadPart); -+ } -+ } -+ -+ } -+ return 0; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * @brief This routine is responsible for adding a station information -+ * -+ * @param -+ * -+ * @retval 0: successful -+ * others: failure -+ */ -+/*----------------------------------------------------------------------------*/ -+int mtk_cfg80211_change_station(struct wiphy *wiphy, struct net_device *ndev, -+ const u8 *mac, struct station_parameters *params) -+{ -+#if (CFG_SUPPORT_TDLS == 1) -+ /* -+ EX: In supplicant, -+ (Supplicant) wpa_tdls_process_tpk_m3() -> -+ (Supplicant) wpa_tdls_enable_link() -> -+ (Supplicant) wpa_sm_tdls_peer_addset() -> -+ (Supplicant) ..tdls_peer_addset() -> -+ (Supplicant) wpa_supplicant_tdls_peer_addset() -> -+ (Supplicant) wpa_drv_sta_add() -> -+ (Supplicant) ..sta_add() -> -+ (Supplicant) wpa_driver_nl80211_sta_add() -> -+ (NL80211) nl80211_set_station() -> -+ (Driver) mtk_cfg80211_change_station() -+ -+ if nl80211_set_station fails, supplicant will tear down the link. -+ */ -+ P_GLUE_INFO_T prGlueInfo; -+ TDLS_CMD_PEER_UPDATE_T rCmdUpdate; -+ WLAN_STATUS rStatus; -+ UINT_32 u4BufLen, u4Temp; -+ -+ /* sanity check */ -+ if ((wiphy == NULL) || (mac == NULL) || (params == NULL)) -+ return -EINVAL; -+ -+ DBGLOG(TDLS, INFO, "%s: 0x%p 0x%x\n", __func__, params->supported_rates, params->sta_flags_set); -+ -+ if (!(params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER))) -+ return -EOPNOTSUPP; -+ -+ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); -+ if (prGlueInfo == NULL) -+ return -EINVAL; -+ -+ /* TODO: check if we are station mode, not AP mode */ -+ -+ /* init */ -+ kalMemZero(&rCmdUpdate, sizeof(rCmdUpdate)); -+ kalMemCopy(rCmdUpdate.aucPeerMac, mac, 6); -+ -+ if (params->supported_rates != NULL) { -+ u4Temp = params->supported_rates_len; -+ if (u4Temp > TDLS_CMD_PEER_UPDATE_SUP_RATE_MAX) { -+ u4Temp = TDLS_CMD_PEER_UPDATE_SUP_RATE_MAX; -+ DBGLOG(TDLS, ERROR, "%s sup rate too long: %d\n", __func__, params->supported_rates_len); -+ } -+ kalMemCopy(rCmdUpdate.aucSupRate, params->supported_rates, u4Temp); -+ rCmdUpdate.u2SupRateLen = u4Temp; -+ } -+ -+ /* -+ In supplicant, only recognize WLAN_EID_QOS 46, not 0xDD WMM -+ So force to support UAPSD here. -+ */ -+ rCmdUpdate.UapsdBitmap = 0x0F; /*params->uapsd_queues; */ -+ rCmdUpdate.UapsdMaxSp = 0; /*params->max_sp; */ -+ -+ DBGLOG(TDLS, INFO, "%s: UapsdBitmap=0x%x UapsdMaxSp=%d\n", -+ __func__, rCmdUpdate.UapsdBitmap, rCmdUpdate.UapsdMaxSp); -+ -+ rCmdUpdate.u2Capability = params->capability; -+ -+ if (params->ext_capab != NULL) { -+ u4Temp = params->ext_capab_len; -+ if (u4Temp > TDLS_CMD_PEER_UPDATE_EXT_CAP_MAXLEN) { -+ u4Temp = TDLS_CMD_PEER_UPDATE_EXT_CAP_MAXLEN; -+ DBGLOG(TDLS, ERROR, "%s ext_capab too long: %d\n", __func__, params->ext_capab_len); -+ } -+ kalMemCopy(rCmdUpdate.aucExtCap, params->ext_capab, u4Temp); -+ rCmdUpdate.u2ExtCapLen = u4Temp; -+ } -+ -+ if (params->ht_capa != NULL) { -+ DBGLOG(TDLS, INFO, "%s: peer is 11n device\n", __func__); -+ -+ rCmdUpdate.rHtCap.u2CapInfo = params->ht_capa->cap_info; -+ rCmdUpdate.rHtCap.ucAmpduParamsInfo = params->ht_capa->ampdu_params_info; -+ rCmdUpdate.rHtCap.u2ExtHtCapInfo = params->ht_capa->extended_ht_cap_info; -+ rCmdUpdate.rHtCap.u4TxBfCapInfo = params->ht_capa->tx_BF_cap_info; -+ rCmdUpdate.rHtCap.ucAntennaSelInfo = params->ht_capa->antenna_selection_info; -+ kalMemCopy(rCmdUpdate.rHtCap.rMCS.arRxMask, -+ params->ht_capa->mcs.rx_mask, sizeof(rCmdUpdate.rHtCap.rMCS.arRxMask)); -+ rCmdUpdate.rHtCap.rMCS.u2RxHighest = params->ht_capa->mcs.rx_highest; -+ rCmdUpdate.rHtCap.rMCS.ucTxParams = params->ht_capa->mcs.tx_params; -+ rCmdUpdate.fgIsSupHt = TRUE; -+ } -+ -+ /* update a TDLS peer record */ -+ rStatus = kalIoctl(prGlueInfo, -+ TdlsexPeerUpdate, -+ &rCmdUpdate, sizeof(TDLS_CMD_PEER_UPDATE_T), FALSE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ DBGLOG(TDLS, ERROR, "%s update error:%x\n", __func__, rStatus); -+ return -EINVAL; -+ } -+#endif /* CFG_SUPPORT_TDLS */ -+ -+ return 0; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * @brief This routine is responsible for adding a station information -+ * -+ * @param -+ * -+ * @retval 0: successful -+ * others: failure -+ */ -+/*----------------------------------------------------------------------------*/ -+int mtk_cfg80211_add_station(struct wiphy *wiphy, struct net_device *ndev, -+ const u8 *mac, struct station_parameters *params) -+{ -+#if (CFG_SUPPORT_TDLS == 1) -+ /* from supplicant -- wpa_supplicant_tdls_peer_addset() */ -+ P_GLUE_INFO_T prGlueInfo; -+ TDLS_CMD_PEER_ADD_T rCmdCreate; -+ WLAN_STATUS rStatus; -+ UINT_32 u4BufLen; -+ -+ if ((wiphy == NULL) || (mac == NULL) || (params == NULL)) -+ return -EINVAL; -+ -+ /* -+ wpa_sm_tdls_peer_addset(sm, peer->addr, 1, 0, 0, NULL, 0, NULL, NULL, 0, -+ NULL, 0); -+ -+ wpa_sm_tdls_peer_addset(struct wpa_sm *sm, const u8 *addr, int add, -+ u16 aid, u16 capability, const u8 *supp_rates, -+ size_t supp_rates_len, -+ const struct ieee80211_ht_capabilities *ht_capab, -+ const struct ieee80211_vht_capabilities *vht_capab, -+ u8 qosinfo, const u8 *ext_capab, size_t ext_capab_len) -+ -+ Only MAC address of the peer is valid. -+ */ -+ -+ DBGLOG(TDLS, INFO, "%s: 0x%p %d\n", __func__, params->supported_rates, params->supported_rates_len); -+ -+ /* sanity check */ -+ if (!(params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER))) -+ return -EOPNOTSUPP; -+ -+ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); -+ if (prGlueInfo == NULL) -+ return -EINVAL; -+ -+ /* TODO: check if we are station mode, not AP mode */ -+ -+ /* init */ -+ kalMemZero(&rCmdCreate, sizeof(rCmdCreate)); -+ kalMemCopy(rCmdCreate.aucPeerMac, mac, 6); -+ -+#if 0 -+ rCmdCreate.eNetTypeIndex = NETWORK_TYPE_AIS_INDEX; -+ -+ rCmdCreate.u2CapInfo = params->capability; -+ -+ DBGLOG(TDLS, INFO, " %s: capability = 0x%x\n", __func__, rCmdCreate.u2CapInfo); -+ -+ if ((params->supported_rates != NULL) && (params->supported_rates_len != 0)) { -+ UINT32 u4Idx; -+ -+ DBGLOG(TDLS, INFO, " %s: sup rate = 0x", __func__); -+ -+ rIeSup.ucId = ELEM_ID_SUP_RATES; -+ rIeSup.ucLength = params->supported_rates_len; -+ for (u4Idx = 0; u4Idx < rIeSup.ucLength; u4Idx++) { -+ rIeSup.aucSupportedRates[u4Idx] = params->supported_rates[u4Idx]; -+ DBGLOG(TDLS, INFO, "%x ", rIeSup.aucSupportedRates[u4Idx]); -+ } -+ DBGLOG(TDLS, INFO, "\n"); -+ -+ rateGetRateSetFromIEs(&rIeSup, -+ NULL, -+ &rCmdCreate.u2OperationalRateSet, -+ &rCmdCreate.u2BSSBasicRateSet, &rCmdCreate.fgIsUnknownBssBasicRate); -+ } -+ -+ /* phy type */ -+#endif -+ -+ /* create a TDLS peer record */ -+ rStatus = kalIoctl(prGlueInfo, -+ TdlsexPeerAdd, -+ &rCmdCreate, sizeof(TDLS_CMD_PEER_ADD_T), FALSE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ DBGLOG(TDLS, ERROR, "%s create error:%x\n", __func__, rStatus); -+ return -EINVAL; -+ } -+#endif /* CFG_SUPPORT_TDLS */ -+ -+ return 0; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * @brief This routine is responsible for deleting a station information -+ * -+ * @param -+ * -+ * @retval 0: successful -+ * others: failure -+ * -+ * @other -+ * must implement if you have add_station(). -+ */ -+/*----------------------------------------------------------------------------*/ -+int mtk_cfg80211_del_station(struct wiphy *wiphy, struct net_device *ndev, struct station_del_parameters *params) -+//int mtk_cfg80211_del_station(struct wiphy *wiphy, struct net_device *ndev, const u8 *mac) -+{ -+ return 0; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * @brief This routine is responsible for requesting to do a scan -+ * -+ * @param -+ * -+ * @retval 0: successful -+ * others: failure -+ */ -+/*----------------------------------------------------------------------------*/ -+static PARAM_SCAN_REQUEST_EXT_T rScanRequest; -+int mtk_cfg80211_scan(struct wiphy *wiphy, struct cfg80211_scan_request *request) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ WLAN_STATUS rStatus; -+ UINT_32 u4BufLen; -+/* PARAM_SCAN_REQUEST_EXT_T rScanRequest; */ -+ -+ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); -+ ASSERT(prGlueInfo); -+ -+ DBGLOG(REQ, TRACE, "mtk_cfg80211_scan\n"); -+ kalMemZero(&rScanRequest, sizeof(PARAM_SCAN_REQUEST_EXT_T)); -+ -+ /* check if there is any pending scan not yet finished */ -+ if (prGlueInfo->prScanRequest != NULL) { -+ DBGLOG(REQ, ERROR, "prGlueInfo->prScanRequest != NULL\n"); -+ return -EBUSY; -+ } -+ -+ if (request->n_ssids == 0) { -+ rScanRequest.rSsid.u4SsidLen = 0; -+ } else if (request->n_ssids == 1) { -+ COPY_SSID(rScanRequest.rSsid.aucSsid, rScanRequest.rSsid.u4SsidLen, request->ssids[0].ssid, -+ request->ssids[0].ssid_len); -+ } else { -+ DBGLOG(REQ, ERROR, "request->n_ssids:%d\n", request->n_ssids); -+ return -EINVAL; -+ } -+ -+ if (request->ie_len > 0) { -+ rScanRequest.u4IELength = request->ie_len; -+ rScanRequest.pucIE = (PUINT_8) (request->ie); -+ } else { -+ rScanRequest.u4IELength = 0; -+ } -+#if 0 -+ prGlueInfo->prScanRequest = request; -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetBssidListScanExt, -+ &rScanRequest, sizeof(PARAM_SCAN_REQUEST_EXT_T), FALSE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ DBGLOG(REQ, ERROR, "scan error:%x\n", rStatus); -+ prGlueInfo->prScanRequest = NULL; -+ return -EINVAL; -+ } -+ -+ /*prGlueInfo->prScanRequest = request;*/ -+#endif -+ -+ prGlueInfo->prScanRequest = request; -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetBssidListScanExt, -+ &rScanRequest, sizeof(PARAM_SCAN_REQUEST_EXT_T), FALSE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ prGlueInfo->prScanRequest = NULL; -+ DBGLOG(REQ, ERROR, "scan error:%x\n", rStatus); -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ -+static UINT_8 wepBuf[48]; -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * @brief This routine is responsible for requesting to connect to -+ * the ESS with the specified parameters -+ * -+ * @param -+ * -+ * @retval 0: successful -+ * others: failure -+ */ -+/*----------------------------------------------------------------------------*/ -+int mtk_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev, struct cfg80211_connect_params *sme) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ WLAN_STATUS rStatus; -+ UINT_32 u4BufLen; -+ ENUM_PARAM_ENCRYPTION_STATUS_T eEncStatus; -+ ENUM_PARAM_AUTH_MODE_T eAuthMode; -+ UINT_32 cipher; -+ PARAM_CONNECT_T rNewSsid; -+ BOOLEAN fgCarryWPSIE = FALSE; -+ ENUM_PARAM_OP_MODE_T eOpMode; -+ -+ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); -+ ASSERT(prGlueInfo); -+ -+ DBGLOG(REQ, TRACE, "[wlan] mtk_cfg80211_connect %p %zu\n", sme->ie, sme->ie_len); -+ -+ if (prGlueInfo->prAdapter->rWifiVar.rConnSettings.eOPMode > NET_TYPE_AUTO_SWITCH) -+ eOpMode = NET_TYPE_AUTO_SWITCH; -+ else -+ eOpMode = prGlueInfo->prAdapter->rWifiVar.rConnSettings.eOPMode; -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetInfrastructureMode, -+ &eOpMode, sizeof(eOpMode), FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ DBGLOG(REQ, ERROR, "wlanoidSetInfrastructureMode fail 0x%x\n", rStatus); -+ return -EFAULT; -+ } -+ -+ /* after set operation mode, key table are cleared */ -+ -+ /* reset wpa info */ -+ prGlueInfo->rWpaInfo.u4WpaVersion = IW_AUTH_WPA_VERSION_DISABLED; -+ prGlueInfo->rWpaInfo.u4KeyMgmt = 0; -+ prGlueInfo->rWpaInfo.u4CipherGroup = IW_AUTH_CIPHER_NONE; -+ prGlueInfo->rWpaInfo.u4CipherPairwise = IW_AUTH_CIPHER_NONE; -+ prGlueInfo->rWpaInfo.u4AuthAlg = IW_AUTH_ALG_OPEN_SYSTEM; -+#if CFG_SUPPORT_802_11W -+ prGlueInfo->rWpaInfo.u4Mfp = IW_AUTH_MFP_DISABLED; -+#endif -+ -+ if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1) -+ prGlueInfo->rWpaInfo.u4WpaVersion = IW_AUTH_WPA_VERSION_WPA; -+ else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2) -+ prGlueInfo->rWpaInfo.u4WpaVersion = IW_AUTH_WPA_VERSION_WPA2; -+ else -+ prGlueInfo->rWpaInfo.u4WpaVersion = IW_AUTH_WPA_VERSION_DISABLED; -+ -+ switch (sme->auth_type) { -+ case NL80211_AUTHTYPE_OPEN_SYSTEM: -+ prGlueInfo->rWpaInfo.u4AuthAlg = IW_AUTH_ALG_OPEN_SYSTEM; -+ break; -+ case NL80211_AUTHTYPE_SHARED_KEY: -+ prGlueInfo->rWpaInfo.u4AuthAlg = IW_AUTH_ALG_SHARED_KEY; -+ break; -+ default: -+ prGlueInfo->rWpaInfo.u4AuthAlg = IW_AUTH_ALG_OPEN_SYSTEM | IW_AUTH_ALG_SHARED_KEY; -+ break; -+ } -+ -+ if (sme->crypto.n_ciphers_pairwise) { -+ prGlueInfo->prAdapter->rWifiVar.rConnSettings.rRsnInfo.au4PairwiseKeyCipherSuite[0] = -+ sme->crypto.ciphers_pairwise[0]; -+ switch (sme->crypto.ciphers_pairwise[0]) { -+ case WLAN_CIPHER_SUITE_WEP40: -+ prGlueInfo->rWpaInfo.u4CipherPairwise = IW_AUTH_CIPHER_WEP40; -+ break; -+ case WLAN_CIPHER_SUITE_WEP104: -+ prGlueInfo->rWpaInfo.u4CipherPairwise = IW_AUTH_CIPHER_WEP104; -+ break; -+ case WLAN_CIPHER_SUITE_TKIP: -+ prGlueInfo->rWpaInfo.u4CipherPairwise = IW_AUTH_CIPHER_TKIP; -+ break; -+ case WLAN_CIPHER_SUITE_CCMP: -+ prGlueInfo->rWpaInfo.u4CipherPairwise = IW_AUTH_CIPHER_CCMP; -+ break; -+ case WLAN_CIPHER_SUITE_AES_CMAC: -+ prGlueInfo->rWpaInfo.u4CipherPairwise = IW_AUTH_CIPHER_CCMP; -+ break; -+ default: -+ DBGLOG(REQ, WARN, "invalid cipher pairwise (%d)\n", sme->crypto.ciphers_pairwise[0]); -+ return -EINVAL; -+ } -+ } -+ -+ if (sme->crypto.cipher_group) { -+ prGlueInfo->prAdapter->rWifiVar.rConnSettings.rRsnInfo.u4GroupKeyCipherSuite = sme->crypto.cipher_group; -+ switch (sme->crypto.cipher_group) { -+ case WLAN_CIPHER_SUITE_WEP40: -+ prGlueInfo->rWpaInfo.u4CipherGroup = IW_AUTH_CIPHER_WEP40; -+ break; -+ case WLAN_CIPHER_SUITE_WEP104: -+ prGlueInfo->rWpaInfo.u4CipherGroup = IW_AUTH_CIPHER_WEP104; -+ break; -+ case WLAN_CIPHER_SUITE_TKIP: -+ prGlueInfo->rWpaInfo.u4CipherGroup = IW_AUTH_CIPHER_TKIP; -+ break; -+ case WLAN_CIPHER_SUITE_CCMP: -+ prGlueInfo->rWpaInfo.u4CipherGroup = IW_AUTH_CIPHER_CCMP; -+ break; -+ case WLAN_CIPHER_SUITE_AES_CMAC: -+ prGlueInfo->rWpaInfo.u4CipherGroup = IW_AUTH_CIPHER_CCMP; -+ break; -+ default: -+ DBGLOG(REQ, WARN, "invalid cipher group (%d)\n", sme->crypto.cipher_group); -+ return -EINVAL; -+ } -+ } -+ -+ if (sme->crypto.n_akm_suites) { -+ prGlueInfo->prAdapter->rWifiVar.rConnSettings.rRsnInfo.au4AuthKeyMgtSuite[0] = -+ sme->crypto.akm_suites[0]; -+ if (prGlueInfo->rWpaInfo.u4WpaVersion == IW_AUTH_WPA_VERSION_WPA) { -+ switch (sme->crypto.akm_suites[0]) { -+ case WLAN_AKM_SUITE_8021X: -+ eAuthMode = AUTH_MODE_WPA; -+ break; -+ case WLAN_AKM_SUITE_PSK: -+ eAuthMode = AUTH_MODE_WPA_PSK; -+ break; -+ default: -+ DBGLOG(REQ, WARN, "invalid cipher group (%d)\n", sme->crypto.cipher_group); -+ return -EINVAL; -+ } -+ } else if (prGlueInfo->rWpaInfo.u4WpaVersion == IW_AUTH_WPA_VERSION_WPA2) { -+ switch (sme->crypto.akm_suites[0]) { -+ case WLAN_AKM_SUITE_8021X: -+ eAuthMode = AUTH_MODE_WPA2; -+ break; -+ case WLAN_AKM_SUITE_PSK: -+ eAuthMode = AUTH_MODE_WPA2_PSK; -+ break; -+ default: -+ DBGLOG(REQ, WARN, "invalid cipher group (%d)\n", sme->crypto.cipher_group); -+ return -EINVAL; -+ } -+ } -+ } -+ -+ if (prGlueInfo->rWpaInfo.u4WpaVersion == IW_AUTH_WPA_VERSION_DISABLED) { -+ eAuthMode = (prGlueInfo->rWpaInfo.u4AuthAlg == IW_AUTH_ALG_OPEN_SYSTEM) ? -+ AUTH_MODE_OPEN : AUTH_MODE_AUTO_SWITCH; -+ } -+ -+ prGlueInfo->rWpaInfo.fgPrivacyInvoke = sme->privacy; -+ -+ prGlueInfo->fgWpsActive = FALSE; -+#if CFG_SUPPORT_HOTSPOT_2_0 -+ prGlueInfo->fgConnectHS20AP = FALSE; -+#endif -+ -+ if (sme->ie && sme->ie_len > 0) { -+ WLAN_STATUS rStatus; -+ UINT_32 u4BufLen; -+ PUINT_8 prDesiredIE = NULL; -+ PUINT_8 pucIEStart = (PUINT_8)sme->ie; -+ -+#if CFG_SUPPORT_WAPI -+ if (wextSrchDesiredWAPIIE(pucIEStart, sme->ie_len, (PUINT_8 *) &prDesiredIE)) { -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetWapiAssocInfo, -+ prDesiredIE, IE_SIZE(prDesiredIE), FALSE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) -+ DBGLOG(SEC, WARN, "[wapi] set wapi assoc info error:%x\n", rStatus); -+ } -+#endif -+ -+ DBGLOG(REQ, TRACE, "[wlan] wlanoidSetWapiAssocInfo: .fgWapiMode = %d\n", -+ prGlueInfo->prAdapter->rWifiVar.rConnSettings.fgWapiMode); -+ -+#if CFG_SUPPORT_WPS2 -+ if (wextSrchDesiredWPSIE(pucIEStart, sme->ie_len, 0xDD, (PUINT_8 *) &prDesiredIE)) { -+ prGlueInfo->fgWpsActive = TRUE; -+ fgCarryWPSIE = TRUE; -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetWSCAssocInfo, -+ prDesiredIE, IE_SIZE(prDesiredIE), FALSE, FALSE, FALSE, FALSE, &u4BufLen); -+ if (rStatus != WLAN_STATUS_SUCCESS) -+ DBGLOG(SEC, WARN, "WSC] set WSC assoc info error:%x\n", rStatus); -+ } -+#endif -+ -+#if CFG_SUPPORT_HOTSPOT_2_0 -+ if (wextSrchDesiredHS20IE(pucIEStart, sme->ie_len, (PUINT_8 *) &prDesiredIE)) { -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetHS20Info, -+ prDesiredIE, IE_SIZE(prDesiredIE), FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ /* Do nothing */ -+ /* printk(KERN_INFO "[HS20] set HS20 assoc info error:%lx\n", rStatus); */ -+ } -+ } -+ if (wextSrchDesiredInterworkingIE(pucIEStart, sme->ie_len, (PUINT_8 *) &prDesiredIE)) { -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetInterworkingInfo, -+ prDesiredIE, IE_SIZE(prDesiredIE), FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ /* Do nothing */ -+ /* printk(KERN_INFO "[HS20] set Interworking assoc info error:%lx\n", rStatus); */ -+ } -+ } -+ if (wextSrchDesiredRoamingConsortiumIE(pucIEStart, sme->ie_len, (PUINT_8 *) &prDesiredIE)) { -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetRoamingConsortiumIEInfo, -+ prDesiredIE, IE_SIZE(prDesiredIE), FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ /* Do nothing */ -+ /* printk(KERN_INFO "[HS20] set RoamingConsortium assoc info error:%lx\n", rStatus); */ -+ } -+ } -+#endif -+ } -+ -+ /* clear WSC Assoc IE buffer in case WPS IE is not detected */ -+ if (fgCarryWPSIE == FALSE) { -+ kalMemZero(&prGlueInfo->aucWSCAssocInfoIE, 200); -+ prGlueInfo->u2WSCAssocInfoIELen = 0; -+ } -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetAuthMode, &eAuthMode, sizeof(eAuthMode), FALSE, FALSE, FALSE, FALSE, &u4BufLen); -+ if (rStatus != WLAN_STATUS_SUCCESS) -+ DBGLOG(REQ, WARN, "set auth mode error:%x\n", rStatus); -+ -+ cipher = prGlueInfo->rWpaInfo.u4CipherGroup | prGlueInfo->rWpaInfo.u4CipherPairwise; -+ -+ if (prGlueInfo->rWpaInfo.fgPrivacyInvoke) { -+ if (cipher & IW_AUTH_CIPHER_CCMP) { -+ eEncStatus = ENUM_ENCRYPTION3_ENABLED; -+ } else if (cipher & IW_AUTH_CIPHER_TKIP) { -+ eEncStatus = ENUM_ENCRYPTION2_ENABLED; -+ } else if (cipher & (IW_AUTH_CIPHER_WEP104 | IW_AUTH_CIPHER_WEP40)) { -+ eEncStatus = ENUM_ENCRYPTION1_ENABLED; -+ } else if (cipher & IW_AUTH_CIPHER_NONE) { -+ if (prGlueInfo->rWpaInfo.fgPrivacyInvoke) -+ eEncStatus = ENUM_ENCRYPTION1_ENABLED; -+ else -+ eEncStatus = ENUM_ENCRYPTION_DISABLED; -+ } else { -+ eEncStatus = ENUM_ENCRYPTION_DISABLED; -+ } -+ } else { -+ eEncStatus = ENUM_ENCRYPTION_DISABLED; -+ } -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetEncryptionStatus, -+ &eEncStatus, sizeof(eEncStatus), FALSE, FALSE, FALSE, FALSE, &u4BufLen); -+ if (rStatus != WLAN_STATUS_SUCCESS) -+ DBGLOG(REQ, WARN, "set encryption mode error:%x\n", rStatus); -+ -+ if (sme->key_len != 0 && prGlueInfo->rWpaInfo.u4WpaVersion == IW_AUTH_WPA_VERSION_DISABLED) { -+ P_PARAM_WEP_T prWepKey = (P_PARAM_WEP_T) wepBuf; -+ -+ prWepKey->u4Length = 12 + sme->key_len; -+ prWepKey->u4KeyLength = (UINT_32) sme->key_len; -+ prWepKey->u4KeyIndex = (UINT_32) sme->key_idx; -+ prWepKey->u4KeyIndex |= BIT(31); -+ if (prWepKey->u4KeyLength > 32) { -+ DBGLOG(REQ, ERROR, "Too long key length (%u)\n", prWepKey->u4KeyLength); -+ return -EINVAL; -+ } -+ kalMemCopy(prWepKey->aucKeyMaterial, sme->key, prWepKey->u4KeyLength); -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetAddWep, -+ prWepKey, prWepKey->u4Length, FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ DBGLOG(REQ, ERROR, "wlanoidSetAddWep fail 0x%x\n", rStatus); -+ return -EFAULT; -+ } -+ } -+ -+ if (sme->channel) -+ rNewSsid.u4CenterFreq = sme->channel->center_freq; -+ else -+ rNewSsid.u4CenterFreq = 0; -+ rNewSsid.pucBssid = (UINT_8 *)sme->bssid; -+ rNewSsid.pucSsid = (UINT_8 *)sme->ssid; -+ rNewSsid.u4SsidLen = sme->ssid_len; -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetConnect, -+ (PVOID)(&rNewSsid), sizeof(PARAM_CONNECT_T), FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ DBGLOG(REQ, ERROR, "set SSID:%x\n", rStatus); -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * @brief This routine is responsible for requesting to disconnect from -+ * currently connected ESS -+ * -+ * @param -+ * -+ * @retval 0: successful -+ * others: failure -+ */ -+/*----------------------------------------------------------------------------*/ -+int mtk_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *ndev, u16 reason_code) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ WLAN_STATUS rStatus; -+ UINT_32 u4BufLen; -+ -+ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); -+ ASSERT(prGlueInfo); -+ -+ rStatus = kalIoctl(prGlueInfo, wlanoidSetDisassociate, NULL, 0, FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ DBGLOG(REQ, WARN, "disassociate error:%x\n", rStatus); -+ return -EFAULT; -+ } -+ -+ return 0; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * @brief This routine is responsible for requesting to join an IBSS group -+ * -+ * @param -+ * -+ * @retval 0: successful -+ * others: failure -+ */ -+/*----------------------------------------------------------------------------*/ -+int mtk_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev, struct cfg80211_ibss_params *params) -+{ -+ PARAM_SSID_T rNewSsid; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ UINT_32 u4ChnlFreq; /* Store channel or frequency information */ -+ UINT_32 u4BufLen = 0; -+ WLAN_STATUS rStatus; -+ struct ieee80211_channel *channel = NULL; -+ -+ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); -+ ASSERT(prGlueInfo); -+ -+ /* set channel */ -+ if (params->chandef.chan) -+ channel = params->chandef.chan; -+ if (channel) { -+ u4ChnlFreq = nicChannelNum2Freq(channel->hw_value); -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetFrequency, -+ &u4ChnlFreq, sizeof(u4ChnlFreq), FALSE, FALSE, FALSE, FALSE, &u4BufLen); -+ if (rStatus != WLAN_STATUS_SUCCESS) -+ return -EFAULT; -+ } -+ -+ /* set SSID */ -+ kalMemCopy(rNewSsid.aucSsid, params->ssid, params->ssid_len); -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetSsid, -+ (PVOID)(&rNewSsid), sizeof(PARAM_SSID_T), FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ DBGLOG(REQ, WARN, "set SSID:%x\n", rStatus); -+ return -EFAULT; -+ } -+ -+ return 0; -+ -+ return -EINVAL; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * @brief This routine is responsible for requesting to leave from IBSS group -+ * -+ * @param -+ * -+ * @retval 0: successful -+ * others: failure -+ */ -+/*----------------------------------------------------------------------------*/ -+int mtk_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *ndev) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ WLAN_STATUS rStatus; -+ UINT_32 u4BufLen; -+ -+ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); -+ ASSERT(prGlueInfo); -+ -+ rStatus = kalIoctl(prGlueInfo, wlanoidSetDisassociate, NULL, 0, FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ DBGLOG(REQ, WARN, "disassociate error:%x\n", rStatus); -+ return -EFAULT; -+ } -+ -+ return 0; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * @brief This routine is responsible for requesting to configure -+ * WLAN power managemenet -+ * -+ * @param -+ * -+ * @retval 0: successful -+ * others: failure -+ */ -+/*----------------------------------------------------------------------------*/ -+int mtk_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *ndev, bool enabled, int timeout) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ WLAN_STATUS rStatus; -+ UINT_32 u4BufLen; -+ PARAM_POWER_MODE ePowerMode; -+ -+ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); -+ ASSERT(prGlueInfo); -+ -+ if (enabled) { -+ if (timeout == -1) -+ ePowerMode = Param_PowerModeFast_PSP; -+ else -+ ePowerMode = Param_PowerModeMAX_PSP; -+ } else { -+ ePowerMode = Param_PowerModeCAM; -+ } -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSet802dot11PowerSaveProfile, -+ &ePowerMode, sizeof(ePowerMode), FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ DBGLOG(REQ, WARN, "set_power_mgmt error:%x\n", rStatus); -+ return -EFAULT; -+ } -+ -+ return 0; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * @brief This routine is responsible for requesting to cache -+ * a PMKID for a BSSID -+ * -+ * @param -+ * -+ * @retval 0: successful -+ * others: failure -+ */ -+/*----------------------------------------------------------------------------*/ -+int mtk_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *ndev, struct cfg80211_pmksa *pmksa) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ WLAN_STATUS rStatus; -+ UINT_32 u4BufLen; -+ P_PARAM_PMKID_T prPmkid; -+ -+ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); -+ ASSERT(prGlueInfo); -+ -+ prPmkid = (P_PARAM_PMKID_T) kalMemAlloc(8 + sizeof(PARAM_BSSID_INFO_T), VIR_MEM_TYPE); -+ if (!prPmkid) { -+ DBGLOG(REQ, ERROR, "Can not alloc memory for IW_PMKSA_ADD\n"); -+ return -ENOMEM; -+ } -+ -+ prPmkid->u4Length = 8 + sizeof(PARAM_BSSID_INFO_T); -+ prPmkid->u4BSSIDInfoCount = 1; -+ kalMemCopy(prPmkid->arBSSIDInfo->arBSSID, pmksa->bssid, 6); -+ kalMemCopy(prPmkid->arBSSIDInfo->arPMKID, pmksa->pmkid, IW_PMKID_LEN); -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetPmkid, prPmkid, sizeof(PARAM_PMKID_T), FALSE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) -+ DBGLOG(REQ, WARN, "add pmkid error:%x\n", rStatus); -+ kalMemFree(prPmkid, VIR_MEM_TYPE, 8 + sizeof(PARAM_BSSID_INFO_T)); -+ -+ return 0; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * @brief This routine is responsible for requesting to remove -+ * a cached PMKID for a BSSID -+ * -+ * @param -+ * -+ * @retval 0: successful -+ * others: failure -+ */ -+/*----------------------------------------------------------------------------*/ -+int mtk_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *ndev, struct cfg80211_pmksa *pmksa) -+{ -+ -+ return 0; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * @brief This routine is responsible for requesting to flush -+ * all cached PMKID -+ * -+ * @param -+ * -+ * @retval 0: successful -+ * others: failure -+ */ -+/*----------------------------------------------------------------------------*/ -+int mtk_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *ndev) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ WLAN_STATUS rStatus; -+ UINT_32 u4BufLen; -+ P_PARAM_PMKID_T prPmkid; -+ -+ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); -+ ASSERT(prGlueInfo); -+ -+ prPmkid = (P_PARAM_PMKID_T) kalMemAlloc(8, VIR_MEM_TYPE); -+ if (!prPmkid) { -+ DBGLOG(REQ, ERROR, "Can not alloc memory for IW_PMKSA_FLUSH\n"); -+ return -ENOMEM; -+ } -+ -+ prPmkid->u4Length = 8; -+ prPmkid->u4BSSIDInfoCount = 0; -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetPmkid, prPmkid, sizeof(PARAM_PMKID_T), FALSE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) -+ DBGLOG(REQ, WARN, "flush pmkid error:%x\n", rStatus); -+ kalMemFree(prPmkid, VIR_MEM_TYPE, 8); -+ -+ return 0; -+} -+ -+void mtk_cfg80211_mgmt_frame_register(IN struct wiphy *wiphy, -+ IN struct wireless_dev *wdev, -+ IN u16 frame_type, IN bool reg) -+{ -+#if 0 -+ P_MSG_P2P_MGMT_FRAME_REGISTER_T prMgmtFrameRegister = (P_MSG_P2P_MGMT_FRAME_REGISTER_T) NULL; -+#endif -+ P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) NULL; -+ -+ do { -+ -+ DBGLOG(REQ, LOUD, "mtk_cfg80211_mgmt_frame_register\n"); -+ -+ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); -+ -+ switch (frame_type) { -+ case MAC_FRAME_PROBE_REQ: -+ if (reg) { -+ prGlueInfo->u4OsMgmtFrameFilter |= PARAM_PACKET_FILTER_PROBE_REQ; -+ DBGLOG(REQ, LOUD, "Open packet filer probe request\n"); -+ } else { -+ prGlueInfo->u4OsMgmtFrameFilter &= ~PARAM_PACKET_FILTER_PROBE_REQ; -+ DBGLOG(REQ, LOUD, "Close packet filer probe request\n"); -+ } -+ break; -+ case MAC_FRAME_ACTION: -+ if (reg) { -+ prGlueInfo->u4OsMgmtFrameFilter |= PARAM_PACKET_FILTER_ACTION_FRAME; -+ DBGLOG(REQ, LOUD, "Open packet filer action frame.\n"); -+ } else { -+ prGlueInfo->u4OsMgmtFrameFilter &= ~PARAM_PACKET_FILTER_ACTION_FRAME; -+ DBGLOG(REQ, LOUD, "Close packet filer action frame.\n"); -+ } -+ break; -+ default: -+ DBGLOG(REQ, TRACE, "Ask frog to add code for mgmt:%x\n", frame_type); -+ break; -+ } -+ -+ if (prGlueInfo->prAdapter != NULL) { -+ /* prGlueInfo->ulFlag |= GLUE_FLAG_FRAME_FILTER_AIS; */ -+ set_bit(GLUE_FLAG_FRAME_FILTER_AIS_BIT, &prGlueInfo->ulFlag); -+ -+ /* wake up main thread */ -+ wake_up_interruptible(&prGlueInfo->waitq); -+ -+ if (in_interrupt()) -+ DBGLOG(REQ, TRACE, "It is in interrupt level\n"); -+ } -+#if 0 -+ -+ prMgmtFrameRegister = (P_MSG_P2P_MGMT_FRAME_REGISTER_T) cnmMemAlloc(prGlueInfo->prAdapter, -+ RAM_TYPE_MSG, -+ sizeof -+ (MSG_P2P_MGMT_FRAME_REGISTER_T)); -+ -+ if (prMgmtFrameRegister == NULL) { -+ ASSERT(FALSE); -+ break; -+ } -+ -+ prMgmtFrameRegister->rMsgHdr.eMsgId = MID_MNY_P2P_MGMT_FRAME_REGISTER; -+ -+ prMgmtFrameRegister->u2FrameType = frame_type; -+ prMgmtFrameRegister->fgIsRegister = reg; -+ -+ mboxSendMsg(prGlueInfo->prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMgmtFrameRegister, MSG_SEND_METHOD_BUF); -+ -+#endif -+ -+ } while (FALSE); -+ -+} /* mtk_cfg80211_mgmt_frame_register */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * @brief This routine is responsible for requesting to stay on a -+ * specified channel -+ * -+ * @param -+ * -+ * @retval 0: successful -+ * others: failure -+ */ -+/*----------------------------------------------------------------------------*/ -+int mtk_cfg80211_remain_on_channel(struct wiphy *wiphy, -+ struct wireless_dev *wdev, -+ struct ieee80211_channel *chan, -+ unsigned int duration, u64 *cookie) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ INT_32 i4Rslt = -EINVAL; -+ P_MSG_REMAIN_ON_CHANNEL_T prMsgChnlReq = (P_MSG_REMAIN_ON_CHANNEL_T) NULL; -+ -+ do { -+ if ((wiphy == NULL) || (wdev == NULL) || (chan == NULL) || (cookie == NULL)) -+ break; -+ -+ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); -+ ASSERT(prGlueInfo); -+ -+#if 1 -+ DBGLOG(REQ, TRACE, "--> %s()\n", __func__); -+#endif -+ -+ *cookie = prGlueInfo->u8Cookie++; -+ -+ prMsgChnlReq = cnmMemAlloc(prGlueInfo->prAdapter, RAM_TYPE_MSG, sizeof(MSG_REMAIN_ON_CHANNEL_T)); -+ -+ if (prMsgChnlReq == NULL) { -+ ASSERT(FALSE); -+ i4Rslt = -ENOMEM; -+ break; -+ } -+ kalMemZero(prMsgChnlReq, sizeof(MSG_REMAIN_ON_CHANNEL_T)); -+ -+ prMsgChnlReq->rMsgHdr.eMsgId = MID_MNY_AIS_REMAIN_ON_CHANNEL; -+ prMsgChnlReq->u8Cookie = *cookie; -+ prMsgChnlReq->u4DurationMs = duration; -+ -+ prMsgChnlReq->ucChannelNum = nicFreq2ChannelNum(chan->center_freq * 1000); -+ -+ switch (chan->band) { -+ case NL80211_BAND_2GHZ: -+ prMsgChnlReq->eBand = BAND_2G4; -+ break; -+ case NL80211_BAND_5GHZ: -+ prMsgChnlReq->eBand = BAND_5G; -+ break; -+ default: -+ prMsgChnlReq->eBand = BAND_2G4; -+ break; -+ } -+ -+ mboxSendMsg(prGlueInfo->prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgChnlReq, MSG_SEND_METHOD_BUF); -+ -+ i4Rslt = 0; -+ } while (FALSE); -+ -+ return i4Rslt; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * @brief This routine is responsible for requesting to cancel staying -+ * on a specified channel -+ * -+ * @param -+ * -+ * @retval 0: successful -+ * others: failure -+ */ -+/*----------------------------------------------------------------------------*/ -+int mtk_cfg80211_cancel_remain_on_channel(struct wiphy *wiphy, -+ struct wireless_dev *wdev, -+ u64 cookie) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ INT_32 i4Rslt = -EINVAL; -+ P_MSG_CANCEL_REMAIN_ON_CHANNEL_T prMsgChnlAbort = (P_MSG_CANCEL_REMAIN_ON_CHANNEL_T) NULL; -+ -+ do { -+ if ((wiphy == NULL) || (wdev == NULL)) -+ break; -+ -+ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); -+ ASSERT(prGlueInfo); -+ -+#if 1 -+ DBGLOG(REQ, TRACE, "--> %s()\n", __func__); -+#endif -+ -+ prMsgChnlAbort = -+ cnmMemAlloc(prGlueInfo->prAdapter, RAM_TYPE_MSG, sizeof(MSG_CANCEL_REMAIN_ON_CHANNEL_T)); -+ -+ if (prMsgChnlAbort == NULL) { -+ ASSERT(FALSE); -+ i4Rslt = -ENOMEM; -+ break; -+ } -+ -+ prMsgChnlAbort->rMsgHdr.eMsgId = MID_MNY_AIS_CANCEL_REMAIN_ON_CHANNEL; -+ prMsgChnlAbort->u8Cookie = cookie; -+ -+ mboxSendMsg(prGlueInfo->prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgChnlAbort, MSG_SEND_METHOD_BUF); -+ -+ i4Rslt = 0; -+ } while (FALSE); -+ -+ return i4Rslt; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * @brief This routine is responsible for requesting to send a management frame -+ * -+ * @param -+ * -+ * @retval 0: successful -+ * others: failure -+ */ -+/*----------------------------------------------------------------------------*/ -+int -+mtk_cfg80211_mgmt_tx(struct wiphy *wiphy, -+ struct wireless_dev *wdev, -+ struct cfg80211_mgmt_tx_params *params, -+ u64 *cookie) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ INT_32 i4Rslt = -EINVAL; -+ P_MSG_MGMT_TX_REQUEST_T prMsgTxReq = (P_MSG_MGMT_TX_REQUEST_T) NULL; -+ P_MSDU_INFO_T prMgmtFrame = (P_MSDU_INFO_T) NULL; -+ PUINT_8 pucFrameBuf = (PUINT_8) NULL; -+ -+ do { -+#if 1 -+ DBGLOG(REQ, TRACE, "--> %s()\n", __func__); -+#endif -+ -+ if ((wiphy == NULL) || (wdev == NULL) || (params == 0) || (cookie == NULL)) -+ break; -+ -+ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); -+ ASSERT(prGlueInfo); -+ -+ *cookie = prGlueInfo->u8Cookie++; -+ -+ /* Channel & Channel Type & Wait time are ignored. */ -+ prMsgTxReq = cnmMemAlloc(prGlueInfo->prAdapter, RAM_TYPE_MSG, sizeof(MSG_MGMT_TX_REQUEST_T)); -+ -+ if (prMsgTxReq == NULL) { -+ ASSERT(FALSE); -+ i4Rslt = -ENOMEM; -+ break; -+ } -+ -+ prMsgTxReq->fgNoneCckRate = FALSE; -+ prMsgTxReq->fgIsWaitRsp = TRUE; -+ -+ prMgmtFrame = cnmMgtPktAlloc(prGlueInfo->prAdapter, (UINT_32) (params->len + MAC_TX_RESERVED_FIELD)); -+ prMsgTxReq->prMgmtMsduInfo = prMgmtFrame; -+ if (prMsgTxReq->prMgmtMsduInfo == NULL) { -+ ASSERT(FALSE); -+ i4Rslt = -ENOMEM; -+ break; -+ } -+ -+ prMsgTxReq->u8Cookie = *cookie; -+ prMsgTxReq->rMsgHdr.eMsgId = MID_MNY_AIS_MGMT_TX; -+ -+ pucFrameBuf = (PUINT_8) ((ULONG) prMgmtFrame->prPacket + MAC_TX_RESERVED_FIELD); -+ -+ kalMemCopy(pucFrameBuf, params->buf, params->len); -+ -+ prMgmtFrame->u2FrameLength = params->len; -+ -+ mboxSendMsg(prGlueInfo->prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgTxReq, MSG_SEND_METHOD_BUF); -+ -+ i4Rslt = 0; -+ } while (FALSE); -+ -+ if ((i4Rslt != 0) && (prMsgTxReq != NULL)) { -+ if (prMsgTxReq->prMgmtMsduInfo != NULL) -+ cnmMgtPktFree(prGlueInfo->prAdapter, prMsgTxReq->prMgmtMsduInfo); -+ -+ cnmMemFree(prGlueInfo->prAdapter, prMsgTxReq); -+ } -+ -+ return i4Rslt; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * @brief This routine is responsible for requesting to cancel the wait time -+ * from transmitting a management frame on another channel -+ * -+ * @param -+ * -+ * @retval 0: successful -+ * others: failure -+ */ -+/*----------------------------------------------------------------------------*/ -+int mtk_cfg80211_mgmt_tx_cancel_wait(struct wiphy *wiphy, -+ struct wireless_dev *wdev, -+ u64 cookie) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ -+ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); -+ ASSERT(prGlueInfo); -+ -+ DBGLOG(REQ, TRACE, "--> %s()\n", __func__); -+ -+ /* not implemented */ -+ -+ return -EINVAL; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * @brief This routine is responsible for handling sched_scan start/stop request -+ * -+ * @param -+ * -+ * @retval 0: successful -+ * others: failure -+ */ -+/*----------------------------------------------------------------------------*/ -+ -+int -+mtk_cfg80211_sched_scan_start(IN struct wiphy *wiphy, -+ IN struct net_device *ndev, IN struct cfg80211_sched_scan_request *request) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ WLAN_STATUS rStatus; -+ UINT_32 i, u4BufLen; -+ P_PARAM_SCHED_SCAN_REQUEST prSchedScanRequest; -+ -+ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); -+ -+ ASSERT(prGlueInfo); -+ -+ /* check if there is any pending scan/sched_scan not yet finished */ -+ if (prGlueInfo->prScanRequest != NULL || prGlueInfo->prSchedScanRequest != NULL) { -+ DBGLOG(SCN, ERROR, "(prGlueInfo->prScanRequest != NULL || prGlueInfo->prSchedScanRequest != NULL)\n"); -+ return -EBUSY; -+ } else if (request == NULL || request->n_match_sets > CFG_SCAN_SSID_MATCH_MAX_NUM) { -+ DBGLOG(SCN, ERROR, "(request == NULL || request->n_match_sets > CFG_SCAN_SSID_MATCH_MAX_NUM)\n"); -+ /* invalid scheduled scan request */ -+ return -EINVAL; -+ } else if (/* !request->n_ssids || */!request->n_match_sets) { -+ /* invalid scheduled scan request */ -+ return -EINVAL; -+ } -+ -+ prSchedScanRequest = (P_PARAM_SCHED_SCAN_REQUEST) kalMemAlloc(sizeof(PARAM_SCHED_SCAN_REQUEST), VIR_MEM_TYPE); -+ if (prSchedScanRequest == NULL) { -+ DBGLOG(SCN, ERROR, "(prSchedScanRequest == NULL) kalMemAlloc fail\n"); -+ return -ENOMEM; -+ } -+ -+ kalMemZero(prSchedScanRequest, sizeof(PARAM_SCHED_SCAN_REQUEST)); -+ -+ prSchedScanRequest->u4SsidNum = request->n_match_sets; -+ for (i = 0; i < request->n_match_sets; i++) { -+ if (request->match_sets == NULL || &(request->match_sets[i]) == NULL) { -+ prSchedScanRequest->arSsid[i].u4SsidLen = 0; -+ } else { -+ COPY_SSID(prSchedScanRequest->arSsid[i].aucSsid, -+ prSchedScanRequest->arSsid[i].u4SsidLen, -+ request->match_sets[i].ssid.ssid, request->match_sets[i].ssid.ssid_len); -+ } -+ } -+ -+ prSchedScanRequest->u4IELength = request->ie_len; -+ if (request->ie_len > 0) -+ prSchedScanRequest->pucIE = (PUINT_8) (request->ie); -+ -+ prSchedScanRequest->u2ScanInterval = (UINT_16) (request->scan_plans[0].interval); -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetStartSchedScan, -+ prSchedScanRequest, sizeof(PARAM_SCHED_SCAN_REQUEST), FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ -+ kalMemFree(prSchedScanRequest, VIR_MEM_TYPE, sizeof(PARAM_SCHED_SCAN_REQUEST)); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ DBGLOG(SCN, ERROR, "scheduled scan error:%x\n", rStatus); -+ return -EINVAL; -+ } -+ -+ prGlueInfo->prSchedScanRequest = request; -+ -+ return 0; -+} -+ -+int mtk_cfg80211_sched_scan_stop(IN struct wiphy *wiphy, IN struct net_device *ndev, u64 reqid) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ WLAN_STATUS rStatus; -+ UINT_32 u4BufLen; -+ -+ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); -+ ASSERT(prGlueInfo); -+ -+ /* check if there is any pending scan/sched_scan not yet finished */ -+ if (prGlueInfo->prSchedScanRequest == NULL) { -+ DBGLOG(SCN, ERROR, "prGlueInfo->prSchedScanRequest == NULL\n"); -+ return -EBUSY; -+ } -+ -+ rStatus = kalIoctl(prGlueInfo, wlanoidSetStopSchedScan, NULL, 0, FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ DBGLOG(SCN, ERROR, "scheduled scan error, rStatus: %d\n", rStatus); -+ return -EINVAL; -+ } -+ -+ /* 1. reset first for newly incoming request */ -+ /* GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV); */ -+ if (prGlueInfo->prSchedScanRequest != NULL) -+ prGlueInfo->prSchedScanRequest = NULL; -+ /* GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV); */ -+ -+ DBGLOG(SCN, TRACE, "start work queue to send event\n"); -+ schedule_delayed_work(&sched_workq, 0); -+ DBGLOG(SCN, TRACE, "tx_thread return from kalSchedScanStoppped\n"); -+ -+ return 0; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * @brief This routine is responsible for handling association request -+ * -+ * @param -+ * -+ * @retval 0: successful -+ * others: failure -+ */ -+/*----------------------------------------------------------------------------*/ -+int mtk_cfg80211_assoc(struct wiphy *wiphy, struct net_device *ndev, struct cfg80211_assoc_request *req) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ PARAM_MAC_ADDRESS arBssid; -+#if CFG_SUPPORT_HOTSPOT_2_0 -+ PUINT_8 prDesiredIE = NULL; -+#endif -+ WLAN_STATUS rStatus; -+ UINT_32 u4BufLen; -+ -+ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); -+ ASSERT(prGlueInfo); -+ -+ kalMemZero(arBssid, MAC_ADDR_LEN); -+ wlanQueryInformation(prGlueInfo->prAdapter, wlanoidQueryBssid, &arBssid[0], sizeof(arBssid), &u4BufLen); -+ -+ /* 1. check BSSID */ -+ if (UNEQUAL_MAC_ADDR(arBssid, req->bss->bssid)) { -+ /* wrong MAC address */ -+ DBGLOG(REQ, WARN, "incorrect BSSID: [ %pM ] currently connected BSSID[ %pM ]\n", -+ req->bss->bssid, arBssid); -+ return -ENOENT; -+ } -+ -+ if (req->ie && req->ie_len > 0) { -+#if CFG_SUPPORT_HOTSPOT_2_0 -+ if (wextSrchDesiredHS20IE((PUINT_8) req->ie, req->ie_len, (PUINT_8 *) &prDesiredIE)) { -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetHS20Info, -+ prDesiredIE, IE_SIZE(prDesiredIE), FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ /* Do nothing */ -+ /* printk(KERN_INFO "[HS20] set HS20 assoc info error:%lx\n", rStatus); */ -+ } -+ } -+ -+ if (wextSrchDesiredInterworkingIE((PUINT_8) req->ie, req->ie_len, (PUINT_8 *) &prDesiredIE)) { -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetInterworkingInfo, -+ prDesiredIE, IE_SIZE(prDesiredIE), FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ /* Do nothing */ -+ /* printk(KERN_INFO "[HS20] set Interworking assoc info error:%lx\n", rStatus); */ -+ } -+ } -+ -+ if (wextSrchDesiredRoamingConsortiumIE((PUINT_8) req->ie, req->ie_len, (PUINT_8 *) &prDesiredIE)) { -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetRoamingConsortiumIEInfo, -+ prDesiredIE, IE_SIZE(prDesiredIE), FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ /* Do nothing */ -+ /* printk(KERN_INFO "[HS20] set RoamingConsortium assoc info error:%lx\n", rStatus); */ -+ } -+ } -+#endif -+ } -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetBssid, -+ (PVOID) req->bss->bssid, MAC_ADDR_LEN, FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ DBGLOG(REQ, WARN, "set BSSID:%x\n", rStatus); -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ -+#if CONFIG_NL80211_TESTMODE -+/* -+#define NLA_PUT(skb, attrtype, attrlen, data) \ -+do { \ -+ if (unlikely(nla_put(skb, attrtype, attrlen, data) < 0)) \ -+ goto nla_put_failure; \ -+} while (0) -+ -+#define NLA_PUT_TYPE(skb, type, attrtype, value) \ -+do { \ -+ type __tmp = value; \ -+ NLA_PUT(skb, attrtype, sizeof(type), &__tmp); \ -+} while (0) -+ -+#define NLA_PUT_U8(skb, attrtype, value) \ -+ NLA_PUT_TYPE(skb, u8, attrtype, value) -+ -+#define NLA_PUT_U16(skb, attrtype, value) \ -+ NLA_PUT_TYPE(skb, u16, attrtype, value) -+ -+#define NLA_PUT_U32(skb, attrtype, value) \ -+ NLA_PUT_TYPE(skb, u32, attrtype, value) -+ -+#define NLA_PUT_U64(skb, attrtype, value) \ -+ NLA_PUT_TYPE(skb, u64, attrtype, value) -+*/ -+#if CFG_SUPPORT_WAPI -+int mtk_cfg80211_testmode_set_key_ext(IN struct wiphy *wiphy, IN void *data, IN int len) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ P_NL80211_DRIVER_SET_KEY_EXTS prParams = (P_NL80211_DRIVER_SET_KEY_EXTS) NULL; -+ struct iw_encode_exts *prIWEncExt = (struct iw_encode_exts *)NULL; -+ WLAN_STATUS rstatus = WLAN_STATUS_SUCCESS; -+ int fgIsValid = 0; -+ UINT_32 u4BufLen = 0; -+ -+ P_PARAM_WPI_KEY_T prWpiKey = (P_PARAM_WPI_KEY_T) keyStructBuf; -+ -+ memset(keyStructBuf, 0, sizeof(keyStructBuf)); -+ -+ ASSERT(wiphy); -+ -+ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); -+ -+ DBGLOG(REQ, TRACE, "--> %s()\n", __func__); -+ -+ if (data && len) { -+ prParams = (P_NL80211_DRIVER_SET_KEY_EXTS) data; -+ } else { -+ DBGLOG(REQ, ERROR, "mtk_cfg80211_testmode_set_key_ext, data is NULL\n"); -+ return -EINVAL; -+ } -+ -+ if (prParams) -+ prIWEncExt = (struct iw_encode_exts *)&prParams->ext; -+ -+ if (prIWEncExt->alg == IW_ENCODE_ALG_SMS4) { -+ /* KeyID */ -+ prWpiKey->ucKeyID = prParams->key_index; -+ prWpiKey->ucKeyID--; -+ if (prWpiKey->ucKeyID > 1) { -+ /* key id is out of range */ -+ /* printk(KERN_INFO "[wapi] add key error: key_id invalid %d\n", prWpiKey->ucKeyID); */ -+ return -EINVAL; -+ } -+ -+ if (prIWEncExt->key_len != 32) { -+ /* key length not valid */ -+ /* printk(KERN_INFO "[wapi] add key error: key_len invalid %d\n", prIWEncExt->key_len); */ -+ return -EINVAL; -+ } -+ /* printk(KERN_INFO "[wapi] %d ext_flags %d\n", prEnc->flags, prIWEncExt->ext_flags); */ -+ -+ if (prIWEncExt->ext_flags & IW_ENCODE_EXT_GROUP_KEY) { -+ prWpiKey->eKeyType = ENUM_WPI_GROUP_KEY; -+ prWpiKey->eDirection = ENUM_WPI_RX; -+ } else if (prIWEncExt->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) { -+ prWpiKey->eKeyType = ENUM_WPI_PAIRWISE_KEY; -+ prWpiKey->eDirection = ENUM_WPI_RX_TX; -+ } -+/* #if CFG_SUPPORT_WAPI */ -+ /* handle_sec_msg_final(prIWEncExt->key, 32, prIWEncExt->key, NULL); */ -+/* #endif */ -+ /* PN */ -+ memcpy(prWpiKey->aucPN, prIWEncExt->tx_seq, IW_ENCODE_SEQ_MAX_SIZE); -+ memcpy(prWpiKey->aucPN + IW_ENCODE_SEQ_MAX_SIZE, prIWEncExt->rx_seq, IW_ENCODE_SEQ_MAX_SIZE); -+ -+ -+ /* BSSID */ -+ memcpy(prWpiKey->aucAddrIndex, prIWEncExt->addr, 6); -+ -+ memcpy(prWpiKey->aucWPIEK, prIWEncExt->key, 16); -+ prWpiKey->u4LenWPIEK = 16; -+ -+ memcpy(prWpiKey->aucWPICK, &prIWEncExt->key[16], 16); -+ prWpiKey->u4LenWPICK = 16; -+ -+ rstatus = kalIoctl(prGlueInfo, -+ wlanoidSetWapiKey, -+ prWpiKey, sizeof(PARAM_WPI_KEY_T), FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ -+ if (rstatus != WLAN_STATUS_SUCCESS) { -+ /* printk(KERN_INFO "[wapi] add key error:%lx\n", rStatus); */ -+ fgIsValid = -EFAULT; -+ } -+ -+ } -+ return fgIsValid; -+} -+#endif -+ -+int -+mtk_cfg80211_testmode_get_sta_statistics(IN struct wiphy *wiphy, IN void *data, IN int len, IN P_GLUE_INFO_T prGlueInfo) -+{ -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ INT_32 i4Status = -EINVAL; -+ UINT_32 u4BufLen; -+ UINT_32 u4LinkScore; -+ UINT_32 u4TotalError; -+ UINT_32 u4TxExceedThresholdCount; -+ UINT_32 u4TxTotalCount; -+ -+ P_NL80211_DRIVER_GET_STA_STATISTICS_PARAMS prParams = NULL; -+ PARAM_GET_STA_STA_STATISTICS rQueryStaStatistics; -+ struct sk_buff *skb; -+ -+ ASSERT(wiphy); -+ ASSERT(prGlueInfo); -+ -+ if (data && len) { -+ prParams = (P_NL80211_DRIVER_GET_STA_STATISTICS_PARAMS) data; -+ } else { -+ DBGLOG(QM, ERROR, "mtk_cfg80211_testmode_get_sta_statistics, data is NULL\n"); -+ return -EINVAL; -+ } -+/* -+ if (!prParams->aucMacAddr) { -+ DBGLOG(QM, INFO, "%s MAC Address is NULL\n", __func__); -+ return -EINVAL; -+ } -+*/ -+ skb = cfg80211_testmode_alloc_reply_skb(wiphy, sizeof(PARAM_GET_STA_STA_STATISTICS) + 1); -+ -+ if (!skb) { -+ DBGLOG(QM, ERROR, "%s allocate skb failed:%x\n", __func__, rStatus); -+ return -ENOMEM; -+ } -+ -+ DBGLOG(QM, TRACE, "Get [ %pM ] STA statistics\n", prParams->aucMacAddr); -+ -+ kalMemZero(&rQueryStaStatistics, sizeof(rQueryStaStatistics)); -+ COPY_MAC_ADDR(rQueryStaStatistics.aucMacAddr, prParams->aucMacAddr); -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidQueryStaStatistics, -+ &rQueryStaStatistics, sizeof(rQueryStaStatistics), TRUE, FALSE, TRUE, TRUE, &u4BufLen); -+ -+ /* Calcute Link Score */ -+ u4TxExceedThresholdCount = rQueryStaStatistics.u4TxExceedThresholdCount; -+ u4TxTotalCount = rQueryStaStatistics.u4TxTotalCount; -+ u4TotalError = rQueryStaStatistics.u4TxFailCount + rQueryStaStatistics.u4TxLifeTimeoutCount; -+ -+ /* u4LinkScore 10~100 , ExceedThreshold ratio 0~90 only */ -+ /* u4LinkScore 0~9 , Drop packet ratio 0~9 and all packets exceed threshold */ -+ if (u4TxTotalCount) { -+ if (u4TxExceedThresholdCount <= u4TxTotalCount) -+ u4LinkScore = (90 - ((u4TxExceedThresholdCount * 90) / u4TxTotalCount)); -+ else -+ u4LinkScore = 0; -+ } else { -+ u4LinkScore = 90; -+ } -+ -+ u4LinkScore += 10; -+ -+ if (u4LinkScore == 10) { -+ -+ if (u4TotalError <= u4TxTotalCount) -+ u4LinkScore = (10 - ((u4TotalError * 10) / u4TxTotalCount)); -+ else -+ u4LinkScore = 0; -+ -+ } -+ -+ if (u4LinkScore > 100) -+ u4LinkScore = 100; -+ -+ /*NLA_PUT_U8(skb, NL80211_TESTMODE_STA_STATISTICS_INVALID, 0);*/ -+ { -+ unsigned char __tmp = 0; -+ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_INVALID, sizeof(unsigned char), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ -+ /*NLA_PUT_U8(skb, NL80211_TESTMODE_STA_STATISTICS_VERSION, NL80211_DRIVER_TESTMODE_VERSION);*/ -+ { -+ unsigned char __tmp = NL80211_DRIVER_TESTMODE_VERSION; -+ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_VERSION, sizeof(unsigned char), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ -+ /* NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_LINK_SCORE, u4LinkScore); */ -+ { -+ unsigned int __tmp = u4LinkScore; -+ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_LINK_SCORE, -+ sizeof(unsigned int), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ -+ /*NLA_PUT(skb, NL80211_TESTMODE_STA_STATISTICS_MAC, MAC_ADDR_LEN, prParams->aucMacAddr);*/ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_MAC, MAC_ADDR_LEN, &prParams->aucMacAddr) < 0)) -+ goto nla_put_failure; -+ -+ /*NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_FLAG, rQueryStaStatistics.u4Flag);*/ -+ { -+ unsigned int __tmp = rQueryStaStatistics.u4Flag; -+ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_FLAG, -+ sizeof(unsigned int), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ -+ -+ /* FW part STA link status */ -+ /*NLA_PUT_U8(skb, NL80211_TESTMODE_STA_STATISTICS_PER, rQueryStaStatistics.ucPer);*/ -+ { -+ unsigned char __tmp = rQueryStaStatistics.ucPer; -+ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_PER, sizeof(unsigned char), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ -+ /*NLA_PUT_U8(skb, NL80211_TESTMODE_STA_STATISTICS_RSSI, rQueryStaStatistics.ucRcpi);*/ -+ { -+ unsigned char __tmp = rQueryStaStatistics.ucRcpi; -+ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_RSSI, sizeof(unsigned char), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ -+ /*NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_PHY_MODE, rQueryStaStatistics.u4PhyMode);*/ -+ { -+ unsigned int __tmp = rQueryStaStatistics.u4PhyMode; -+ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_PHY_MODE, -+ sizeof(unsigned int), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ -+ /*NLA_PUT_U16(skb, NL80211_TESTMODE_STA_STATISTICS_TX_RATE, rQueryStaStatistics.u2LinkSpeed);*/ -+ { -+ unsigned short __tmp = rQueryStaStatistics.u2LinkSpeed; -+ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_TX_RATE, -+ sizeof(unsigned short), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ /*NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_FAIL_CNT, rQueryStaStatistics.u4TxFailCount);*/ -+ { -+ unsigned int __tmp = rQueryStaStatistics.u4TxFailCount; -+ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_FAIL_CNT, -+ sizeof(unsigned int), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ -+ /*NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_TIMEOUT_CNT, rQueryStaStatistics.u4TxLifeTimeoutCount);*/ -+ { -+ unsigned int __tmp = rQueryStaStatistics.u4TxLifeTimeoutCount; -+ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_TIMEOUT_CNT, -+ sizeof(unsigned int), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ -+ /*NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_AVG_AIR_TIME, rQueryStaStatistics.u4TxAverageAirTime);*/ -+ { -+ unsigned int __tmp = rQueryStaStatistics.u4TxAverageAirTime; -+ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_AVG_AIR_TIME, -+ sizeof(unsigned int), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ -+ /* Driver part link status */ -+ /*NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_TOTAL_CNT, rQueryStaStatistics.u4TxTotalCount);*/ -+ { -+ unsigned int __tmp = rQueryStaStatistics.u4TxTotalCount; -+ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_TOTAL_CNT, -+ sizeof(unsigned int), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ -+ /*NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_THRESHOLD_CNT, -+ rQueryStaStatistics.u4TxExceedThresholdCount);*/ -+ { -+ unsigned int __tmp = rQueryStaStatistics.u4TxExceedThresholdCount; -+ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_THRESHOLD_CNT, -+ sizeof(unsigned int), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ /*NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_AVG_PROCESS_TIME, -+ rQueryStaStatistics.u4TxAverageProcessTime);*/ -+ { -+ unsigned int __tmp = rQueryStaStatistics.u4TxAverageProcessTime; -+ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_AVG_PROCESS_TIME, -+ sizeof(unsigned int), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ -+ { -+ unsigned int __tmp = rQueryStaStatistics.u4TxMaxTime; -+ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_MAX_PROCESS_TIME, -+ sizeof(unsigned int), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ -+ -+ { -+ unsigned int __tmp = rQueryStaStatistics.u4TxAverageHifTime; -+ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_AVG_HIF_PROCESS_TIME, -+ sizeof(unsigned int), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ -+ { -+ unsigned int __tmp = rQueryStaStatistics.u4TxMaxHifTime; -+ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_MAX_HIF_PROCESS_TIME, -+ sizeof(unsigned int), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ -+ /* -+ * NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_ENQUEUE, rQueryStaStatistics.u4EnqueueCounter); -+ */ -+ { -+ unsigned int __tmp = rQueryStaStatistics.u4EnqueueCounter; -+ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_ENQUEUE, -+ sizeof(unsigned int), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ /* -+ * NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_DEQUEUE, rQueryStaStatistics.u4DequeueCounter); -+ */ -+ { -+ unsigned int __tmp = rQueryStaStatistics.u4DequeueCounter; -+ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_DEQUEUE, -+ sizeof(unsigned int), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ /* -+ * NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_STA_ENQUEUE, rQueryStaStatistics.u4EnqueueStaCounter); -+ */ -+ { -+ unsigned int __tmp = rQueryStaStatistics.u4EnqueueStaCounter; -+ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_STA_ENQUEUE, -+ sizeof(unsigned int), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ /* -+ * NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_STA_DEQUEUE, rQueryStaStatistics.u4DequeueStaCounter); -+ */ -+ { -+ unsigned int __tmp = rQueryStaStatistics.u4DequeueStaCounter; -+ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_STA_DEQUEUE, -+ sizeof(unsigned int), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ -+ /* -+ * NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_IRQ_ISR_CNT, rQueryStaStatistics.IsrCnt); -+ */ -+ { -+ unsigned int __tmp = rQueryStaStatistics.IsrCnt; -+ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_IRQ_ISR_CNT, -+ sizeof(unsigned int), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ /* -+ * NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_IRQ_ISR_PASS_CNT, rQueryStaStatistics.IsrPassCnt); -+ */ -+ { -+ unsigned int __tmp = rQueryStaStatistics.IsrPassCnt; -+ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_IRQ_ISR_PASS_CNT, -+ sizeof(unsigned int), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ /* -+ * NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_IRQ_TASK_CNT, rQueryStaStatistics.TaskIsrCnt); -+ */ -+ { -+ unsigned int __tmp = rQueryStaStatistics.TaskIsrCnt; -+ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_IRQ_TASK_CNT, -+ sizeof(unsigned int), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ -+ /* -+ * NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_IRQ_AB_CNT, rQueryStaStatistics.IsrAbnormalCnt); -+ */ -+ { -+ unsigned int __tmp = rQueryStaStatistics.IsrAbnormalCnt; -+ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_IRQ_AB_CNT, -+ sizeof(unsigned int), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ /* -+ * NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_IRQ_SW_CNT, rQueryStaStatistics.IsrSoftWareCnt); -+ */ -+ { -+ unsigned int __tmp = rQueryStaStatistics.IsrSoftWareCnt; -+ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_IRQ_SW_CNT, -+ sizeof(unsigned int), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ /* -+ * NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_IRQ_TX_CNT, rQueryStaStatistics.IsrTxCnt); -+ */ -+ { -+ unsigned int __tmp = rQueryStaStatistics.IsrTxCnt; -+ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_IRQ_TX_CNT, -+ sizeof(unsigned int), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ /* -+ *NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_IRQ_RX_CNT, rQueryStaStatistics.IsrRxCnt); -+ */ -+ { -+ unsigned int __tmp = rQueryStaStatistics.IsrRxCnt; -+ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_IRQ_RX_CNT, -+ sizeof(unsigned int), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ /* Network counter */ -+ /*NLA_PUT(skb, -+ NL80211_TESTMODE_STA_STATISTICS_TC_EMPTY_CNT_ARRAY, -+ sizeof(rQueryStaStatistics.au4TcResourceEmptyCount), rQueryStaStatistics.au4TcResourceEmptyCount);*/ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_TC_EMPTY_CNT_ARRAY, -+ sizeof(rQueryStaStatistics.au4TcResourceEmptyCount), &rQueryStaStatistics.au4TcResourceEmptyCount) < 0)) -+ goto nla_put_failure; -+ /* -+ NLA_PUT(skb, -+ NL80211_TESTMODE_STA_STATISTICS_NO_TC_ARRAY, -+ sizeof(rQueryStaStatistics.au4DequeueNoTcResource), rQueryStaStatistics.au4DequeueNoTcResource); -+ */ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_NO_TC_ARRAY, -+ sizeof(rQueryStaStatistics.au4DequeueNoTcResource), &rQueryStaStatistics.au4DequeueNoTcResource) < 0)) -+ goto nla_put_failure; -+ /* -+ NLA_PUT(skb, -+ NL80211_TESTMODE_STA_STATISTICS_RB_ARRAY, -+ sizeof(rQueryStaStatistics.au4TcResourceBackCount), rQueryStaStatistics.au4TcResourceBackCount); -+ */ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_RB_ARRAY, -+ sizeof(rQueryStaStatistics.au4TcResourceBackCount), &rQueryStaStatistics.au4TcResourceBackCount) < 0)) -+ goto nla_put_failure; -+ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_USED_BFCT_ARRAY, -+ sizeof(rQueryStaStatistics.au4TcResourceUsedCount), &rQueryStaStatistics.au4TcResourceUsedCount) < 0)) -+ goto nla_put_failure; -+ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_WANTED_BFCT_ARRAY, -+ sizeof(rQueryStaStatistics.au4TcResourceWantedCount), -+ &rQueryStaStatistics.au4TcResourceWantedCount) < 0)) -+ goto nla_put_failure; -+ -+ /* Sta queue length */ -+ /*NLA_PUT(skb, -+ NL80211_TESTMODE_STA_STATISTICS_TC_QUE_LEN_ARRAY, -+ sizeof(rQueryStaStatistics.au4TcQueLen), rQueryStaStatistics.au4TcQueLen);*/ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_TC_QUE_LEN_ARRAY, -+ sizeof(rQueryStaStatistics.au4TcQueLen), &rQueryStaStatistics.au4TcQueLen) < 0)) -+ goto nla_put_failure; -+ -+ -+ /* Global QM counter */ -+ /*NLA_PUT(skb, -+ NL80211_TESTMODE_STA_STATISTICS_TC_AVG_QUE_LEN_ARRAY, -+ sizeof(rQueryStaStatistics.au4TcAverageQueLen), rQueryStaStatistics.au4TcAverageQueLen);*/ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_TC_AVG_QUE_LEN_ARRAY, -+ sizeof(rQueryStaStatistics.au4TcAverageQueLen), &rQueryStaStatistics.au4TcAverageQueLen) < 0)) -+ goto nla_put_failure; -+ -+ /*NLA_PUT(skb, -+ NL80211_TESTMODE_STA_STATISTICS_TC_CUR_QUE_LEN_ARRAY, -+ sizeof(rQueryStaStatistics.au4TcCurrentQueLen), rQueryStaStatistics.au4TcCurrentQueLen);*/ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_TC_CUR_QUE_LEN_ARRAY, -+ sizeof(rQueryStaStatistics.au4TcCurrentQueLen), &rQueryStaStatistics.au4TcCurrentQueLen) < 0)) -+ goto nla_put_failure; -+ -+ -+ /* Reserved field */ -+ /*NLA_PUT(skb, -+ NL80211_TESTMODE_STA_STATISTICS_RESERVED_ARRAY, -+ sizeof(rQueryStaStatistics.au4Reserved), rQueryStaStatistics.au4Reserved);*/ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_RESERVED_ARRAY, -+ sizeof(rQueryStaStatistics.au4Reserved), &rQueryStaStatistics.au4Reserved) < 0)) -+ goto nla_put_failure; -+ -+ i4Status = cfg80211_testmode_reply(skb); -+ skb = NULL; -+ -+nla_put_failure: -+ if (skb != NULL) -+ kfree_skb(skb); -+ return i4Status; -+} -+ -+int -+mtk_cfg80211_testmode_get_link_detection(IN struct wiphy *wiphy, IN void *data, IN int len, IN P_GLUE_INFO_T prGlueInfo) -+{ -+ -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ INT_32 i4Status = -EINVAL; -+ UINT_32 u4BufLen; -+ -+ PARAM_802_11_STATISTICS_STRUCT_T rStatistics; -+ struct sk_buff *skb; -+ -+ ASSERT(wiphy); -+ ASSERT(prGlueInfo); -+ -+ skb = cfg80211_testmode_alloc_reply_skb(wiphy, sizeof(PARAM_GET_STA_STA_STATISTICS) + 1); -+ -+ if (!skb) { -+ DBGLOG(QM, TRACE, "%s allocate skb failed:%x\n", __func__, rStatus); -+ return -ENOMEM; -+ } -+ -+ kalMemZero(&rStatistics, sizeof(rStatistics)); -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidQueryStatistics, -+ &rStatistics, sizeof(rStatistics), TRUE, TRUE, TRUE, FALSE, &u4BufLen); -+ -+ /*NLA_PUT_U8(skb, NL80211_TESTMODE_STA_STATISTICS_INVALID, 0);*/ -+ { -+ unsigned char __tmp = 0; -+ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_STA_STATISTICS_INVALID, sizeof(unsigned char), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ -+ /*NLA_PUT_U64(skb, NL80211_TESTMODE_LINK_TX_FAIL_CNT, rStatistics.rFailedCount.QuadPart);*/ -+ { -+ u64 __tmp = rStatistics.rFailedCount.QuadPart; -+ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_LINK_TX_FAIL_CNT, -+ sizeof(u64), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ -+ /*NLA_PUT_U64(skb, NL80211_TESTMODE_LINK_TX_RETRY_CNT, rStatistics.rRetryCount.QuadPart);*/ -+ { -+ u64 __tmp = rStatistics.rFailedCount.QuadPart; -+ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_LINK_TX_RETRY_CNT, -+ sizeof(u64), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ -+ /*NLA_PUT_U64(skb, NL80211_TESTMODE_LINK_TX_MULTI_RETRY_CNT, rStatistics.rMultipleRetryCount.QuadPart);*/ -+ { -+ u64 __tmp = rStatistics.rMultipleRetryCount.QuadPart; -+ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_LINK_TX_MULTI_RETRY_CNT, -+ sizeof(u64), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ -+ /*NLA_PUT_U64(skb, NL80211_TESTMODE_LINK_ACK_FAIL_CNT, rStatistics.rACKFailureCount.QuadPart);*/ -+ { -+ u64 __tmp = rStatistics.rACKFailureCount.QuadPart; -+ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_LINK_ACK_FAIL_CNT, -+ sizeof(u64), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ -+ /*NLA_PUT_U64(skb, NL80211_TESTMODE_LINK_FCS_ERR_CNT, rStatistics.rFCSErrorCount.QuadPart);*/ -+ { -+ u64 __tmp = rStatistics.rFCSErrorCount.QuadPart; -+ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_LINK_FCS_ERR_CNT, -+ sizeof(u64), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ -+ -+ i4Status = cfg80211_testmode_reply(skb); -+ skb = NULL; -+ -+nla_put_failure: -+ if (skb != NULL) -+ kfree_skb(skb); -+ return i4Status; -+} -+ -+int mtk_cfg80211_testmode_sw_cmd(IN struct wiphy *wiphy, IN void *data, IN int len) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ P_NL80211_DRIVER_SW_CMD_PARAMS prParams = (P_NL80211_DRIVER_SW_CMD_PARAMS) NULL; -+ WLAN_STATUS rstatus = WLAN_STATUS_SUCCESS; -+ int fgIsValid = 0; -+ UINT_32 u4SetInfoLen = 0; -+ -+ ASSERT(wiphy); -+ -+ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); -+ -+ DBGLOG(REQ, TRACE, "--> %s()\n", __func__); -+ -+ if (data && len) -+ prParams = (P_NL80211_DRIVER_SW_CMD_PARAMS) data; -+ -+ if (prParams) { -+ if (prParams->set == 1) { -+ rstatus = kalIoctl(prGlueInfo, -+ (PFN_OID_HANDLER_FUNC) wlanoidSetSwCtrlWrite, -+ &prParams->adr, (UINT_32) 8, FALSE, FALSE, TRUE, FALSE, &u4SetInfoLen); -+ } -+ } -+ -+ if (WLAN_STATUS_SUCCESS != rstatus) -+ fgIsValid = -EFAULT; -+ -+ return fgIsValid; -+} -+ -+#if CFG_SUPPORT_HOTSPOT_2_0 -+int mtk_cfg80211_testmode_hs20_cmd(IN struct wiphy *wiphy, IN void *data, IN int len) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ struct wpa_driver_hs20_data_s *prParams = NULL; -+ WLAN_STATUS rstatus = WLAN_STATUS_SUCCESS; -+ int fgIsValid = 0; -+ UINT_32 u4SetInfoLen = 0; -+ -+ ASSERT(wiphy); -+ -+ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); -+ -+ DBGLOG(REQ, TRACE, "--> %s()\n", __func__); -+ -+ if (data && len) { -+ prParams = (struct wpa_driver_hs20_data_s *)data; -+ -+ DBGLOG(REQ, TRACE, "[%s] Cmd Type (%d)\n", __func__, prParams->CmdType); -+ } -+ -+ if (prParams) { -+ int i; -+ -+ switch (prParams->CmdType) { -+ case HS20_CMD_ID_SET_BSSID_POOL: -+ DBGLOG(REQ, TRACE, "fgBssidPoolIsEnable=%d, ucNumBssidPool=%d\n", -+ prParams->hs20_set_bssid_pool.fgBssidPoolIsEnable, -+ prParams->hs20_set_bssid_pool.ucNumBssidPool); -+ for (i = 0; i < prParams->hs20_set_bssid_pool.ucNumBssidPool; i++) { -+ DBGLOG(REQ, TRACE, "[%d][ %pM ]\n", i, -+ (prParams->hs20_set_bssid_pool.arBssidPool[i])); -+ } -+ rstatus = kalIoctl(prGlueInfo, -+ (PFN_OID_HANDLER_FUNC) wlanoidSetHS20BssidPool, -+ &prParams->hs20_set_bssid_pool, -+ sizeof(struct param_hs20_set_bssid_pool), -+ FALSE, FALSE, TRUE, FALSE, &u4SetInfoLen); -+ break; -+ default: -+ DBGLOG(REQ, TRACE, "[%s] Unknown Cmd Type (%d)\n", __func__, prParams->CmdType); -+ rstatus = WLAN_STATUS_FAILURE; -+ -+ } -+ -+ } -+ -+ if (WLAN_STATUS_SUCCESS != rstatus) -+ fgIsValid = -EFAULT; -+ -+ return fgIsValid; -+} -+ -+#endif -+int -+mtk_cfg80211_testmode_set_poorlink_param(IN struct wiphy *wiphy, IN void *data, IN int len, IN P_GLUE_INFO_T prGlueInfo) -+{ -+ int fgIsValid = 0; -+ P_NL80211_DRIVER_POORLINK_PARAMS prParams = NULL; -+ -+ ASSERT(wiphy); -+ ASSERT(prGlueInfo); -+ -+ if (data && len) { -+ prParams = (P_NL80211_DRIVER_POORLINK_PARAMS) data; -+ } else { -+ DBGLOG(REQ, ERROR, "mtk_cfg80211_testmode_set_poorlink_param, data is NULL\n"); -+ return -EINVAL; -+ } -+ if (prParams->ucLinkSpeed) -+ prGlueInfo->u4LinkspeedThreshold = prParams->ucLinkSpeed * 10; -+ if (prParams->cRssi) -+ prGlueInfo->i4RssiThreshold = prParams->cRssi; -+ if (!prGlueInfo->fgPoorlinkValid) -+ prGlueInfo->fgPoorlinkValid = 1; -+#if 0 -+ DBGLOG(REQ, TRACE, "poorlink set param valid(%d)rssi(%d)linkspeed(%d)\n", -+ prGlueInfo->fgPoorlinkValid, prGlueInfo->i4RssiThreshold, prGlueInfo->u4LinkspeedThreshold); -+#endif -+ -+ return fgIsValid; -+ -+} -+ -+int mtk_cfg80211_testmode_cmd(IN struct wiphy *wiphy, IN struct wireless_dev *wdev, IN void *data, IN int len) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ P_NL80211_DRIVER_TEST_MODE_PARAMS prParams = (P_NL80211_DRIVER_TEST_MODE_PARAMS) NULL; -+ INT_32 i4Status = -EINVAL; -+#if CFG_SUPPORT_HOTSPOT_2_0 -+ BOOLEAN fgIsValid = 0; -+#endif -+ -+ ASSERT(wiphy); -+ ASSERT(wdev); -+ -+ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); -+ -+ if (data && len) { -+ prParams = (P_NL80211_DRIVER_TEST_MODE_PARAMS) data; -+ } else { -+ DBGLOG(REQ, ERROR, "mtk_cfg80211_testmode_cmd, data is NULL\n"); -+ return i4Status; -+ } -+ -+ /* Clear the version byte */ -+ prParams->index = prParams->index & ~BITS(24, 31); -+ -+ if (prParams) { -+ switch (prParams->index) { -+ case TESTMODE_CMD_ID_SW_CMD: /* SW cmd */ -+ i4Status = mtk_cfg80211_testmode_sw_cmd(wiphy, data, len); -+ break; -+ case TESTMODE_CMD_ID_WAPI: /* WAPI */ -+#if CFG_SUPPORT_WAPI -+ i4Status = mtk_cfg80211_testmode_set_key_ext(wiphy, data, len); -+#endif -+ break; -+ case TESTMODE_CMD_ID_SUSPEND: -+ { -+ P_NL80211_DRIVER_SUSPEND_PARAMS prParams = (P_NL80211_DRIVER_SUSPEND_PARAMS) data; -+ -+ if (prParams->suspend == 1) { -+ wlanHandleSystemSuspend(); -+ if (prGlueInfo->prAdapter->fgIsP2PRegistered) -+ p2pHandleSystemSuspend(); -+ i4Status = 0; -+ } else if (prParams->suspend == 0) { -+ wlanHandleSystemResume(); -+ if (prGlueInfo->prAdapter->fgIsP2PRegistered) -+ p2pHandleSystemResume(); -+ i4Status = 0; -+ } -+ break; -+ } -+ case TESTMODE_CMD_ID_STATISTICS: -+ i4Status = mtk_cfg80211_testmode_get_sta_statistics(wiphy, data, len, prGlueInfo); -+ break; -+ case TESTMODE_CMD_ID_LINK_DETECT: -+ i4Status = mtk_cfg80211_testmode_get_link_detection(wiphy, data, len, prGlueInfo); -+ break; -+ case TESTMODE_CMD_ID_POORLINK: -+ i4Status = mtk_cfg80211_testmode_set_poorlink_param(wiphy, data, len, prGlueInfo); -+ break; -+ -+#if CFG_SUPPORT_HOTSPOT_2_0 -+ case TESTMODE_CMD_ID_HS20: -+ if (mtk_cfg80211_testmode_hs20_cmd(wiphy, data, len)) -+ fgIsValid = TRUE; -+ break; -+#endif -+ default: -+ i4Status = -EINVAL; -+ break; -+ } -+ } -+ -+ return i4Status; -+} -+ -+int mtk_cfg80211_testmode_get_scan_done(IN struct wiphy *wiphy, IN void *data, IN int len, IN P_GLUE_INFO_T prGlueInfo) -+{ -+#define NL80211_TESTMODE_P2P_SCANDONE_INVALID 0 -+#define NL80211_TESTMODE_P2P_SCANDONE_STATUS 1 -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ INT_32 i4Status = -EINVAL, READY_TO_BEAM = 0; -+ -+/* P_NL80211_DRIVER_GET_STA_STATISTICS_PARAMS prParams = NULL; */ -+ struct sk_buff *skb; -+ -+ ASSERT(wiphy); -+ ASSERT(prGlueInfo); -+ -+ skb = cfg80211_testmode_alloc_reply_skb(wiphy, sizeof(UINT_32)); -+ READY_TO_BEAM = -+ (UINT_32) (prGlueInfo->prAdapter->rWifiVar.prP2pFsmInfo->rScanReqInfo. -+ fgIsGOInitialDone) & -+ (!prGlueInfo->prAdapter->rWifiVar.prP2pFsmInfo->rScanReqInfo.fgIsScanRequest); -+ DBGLOG(QM, TRACE, -+ "NFC:GOInitialDone[%d] and P2PScanning[%d]\n", -+ prGlueInfo->prAdapter->rWifiVar.prP2pFsmInfo->rScanReqInfo.fgIsGOInitialDone, -+ prGlueInfo->prAdapter->rWifiVar.prP2pFsmInfo->rScanReqInfo.fgIsScanRequest); -+ -+ if (!skb) { -+ DBGLOG(QM, TRACE, "%s allocate skb failed:%x\n", __func__, rStatus); -+ return -ENOMEM; -+ } -+ -+ /*NLA_PUT_U8(skb, NL80211_TESTMODE_P2P_SCANDONE_INVALID, 0);*/ -+ { -+ unsigned char __tmp = 0; -+ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_P2P_SCANDONE_INVALID, sizeof(unsigned char), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ /*NLA_PUT_U32(skb, NL80211_TESTMODE_P2P_SCANDONE_STATUS, READY_TO_BEAM);*/ -+ { -+ unsigned int __tmp = READY_TO_BEAM; -+ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_P2P_SCANDONE_STATUS, sizeof(unsigned int), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ -+ -+ i4Status = cfg80211_testmode_reply(skb); -+ skb = NULL; -+ -+nla_put_failure: -+ if (skb != NULL) -+ kfree_skb(skb); -+ return i4Status; -+} -+ -+#if CFG_AUTO_CHANNEL_SEL_SUPPORT -+int -+mtk_cfg80211_testmode_get_lte_channel(IN struct wiphy *wiphy, IN void *data, IN int len, IN P_GLUE_INFO_T prGlueInfo) -+{ -+#define MAXMUN_2_4G_CHA_NUM 14 -+#define CHN_DIRTY_WEIGHT_UPPERBOUND 4 -+ -+ BOOLEAN fgIsReady = FALSE, fgIsFistRecord = TRUE; -+ BOOLEAN fgIsPureAP, fgIsLteSafeChn = FALSE; -+ -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ UINT_8 ucIdx = 0, ucMax_24G_Chn_List = 11, ucDefaultIdx = 0, ucArrayIdx = 0; -+ UINT_16 u2APNumScore = 0, u2UpThreshold = 0, u2LowThreshold = 0, ucInnerIdx = 0; -+ INT_32 i4Status = -EINVAL; -+ UINT_32 u4BufLen, u4LteSafeChnBitMask_2_4G = 0; -+ UINT32 AcsChnReport[4]; -+ /*RF_CHANNEL_INFO_T aucChannelList[MAXMUN_2_4G_CHA_NUM];*/ -+ -+ struct sk_buff *skb; -+ -+ /*PARAM_GET_CHN_LOAD rQueryLTEChn;*/ -+ P_PARAM_GET_CHN_LOAD prQueryLTEChn; -+ PARAM_PREFER_CHN_INFO rPreferChannels[2], ar2_4G_ChannelLoadingWeightScore[MAXMUN_2_4G_CHA_NUM]; -+ P_PARAM_CHN_LOAD_INFO prChnLoad; -+ P_PARAM_GET_CHN_LOAD prGetChnLoad; -+ -+ P_DOMAIN_INFO_ENTRY prDomainInfo; -+ -+/* -+ P_PARAM_GET_CHN_LOAD prParams = NULL; -+*/ -+ ASSERT(wiphy); -+ ASSERT(prGlueInfo); -+ -+ kalMemZero(rPreferChannels, sizeof(rPreferChannels)); -+ fgIsPureAP = prGlueInfo->prAdapter->rWifiVar.prP2pFsmInfo->fgIsApMode; -+#if 0 -+ if (data && len) -+ prParams = (P_NL80211_DRIVER_GET_LTE_PARAMS) data; -+#endif -+ skb = cfg80211_testmode_alloc_reply_skb(wiphy, sizeof(AcsChnReport) + sizeof(UINT8) + 1); -+ if (!skb) { -+ DBGLOG(QM, TRACE, "%s allocate skb failed:%x\n", __func__, rStatus); -+ return -ENOMEM; -+ } -+ -+ DBGLOG(P2P, INFO, "[Auto Channel]Get LTE Channels\n"); -+ prQueryLTEChn = kalMemAlloc(sizeof(PARAM_GET_CHN_LOAD), VIR_MEM_TYPE); -+ if (prQueryLTEChn == NULL) { -+ DBGLOG(QM, TRACE, "alloc QueryLTEChn fail\n"); -+ kalMemFree(skb, VIR_MEM_TYPE, sizeof(struct sk_buff)); -+ return -ENOMEM; -+ } -+ kalMemZero(prQueryLTEChn, sizeof(PARAM_GET_CHN_LOAD)); -+ -+ /* Query LTE Safe Channels */ -+ prQueryLTEChn->rLteSafeChnList.au4SafeChannelBitmask[NL80211_TESTMODE_AVAILABLE_CHAN_2G_BASE_1 - 1] -+ = 0xFFFFFFFF; -+ -+ prQueryLTEChn->rLteSafeChnList.au4SafeChannelBitmask[NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_34 - 1] -+ = 0xFFFFFFFF; -+ -+ prQueryLTEChn->rLteSafeChnList.au4SafeChannelBitmask[NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_149 - 1] -+ = 0xFFFFFFFF; -+ -+ prQueryLTEChn->rLteSafeChnList.au4SafeChannelBitmask[NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_184 - 1] = -+ 0xFFFFFFFF; -+ -+ rStatus = kalIoctl(prGlueInfo, wlanoidQueryACSChannelList, prQueryLTEChn, sizeof(PARAM_GET_CHN_LOAD), -+ TRUE, FALSE, TRUE, TRUE, &u4BufLen); -+#if 0 -+ if (fgIsPureAP) { -+ -+ AcsChnRepot[NL80211_TESTMODE_AVAILABLE_CHAN_2G_BASE_1 - 1] = 0x20; /* Channel 6 */ -+ } else -+#endif -+ { -+ fgIsReady = prGlueInfo->prAdapter->rWifiVar.rChnLoadInfo.fgDataReadyBit; -+ rPreferChannels[0].u2APNum = 0xFFFF; -+ rPreferChannels[1].u2APNum = 0xFFFF; -+ -+ /* 4 In LTE Mode, Hotspot pick up channels from ch4. */ -+ ucDefaultIdx = 0; -+ /* -+ if (fgIsPureAP) { -+ ucDefaultIdx=3; //SKIP LTE Channels 1~3 -+ } -+ */ -+ -+ /* 4 Get the Maximun channel List in 2.4G Bands */ -+ -+ prDomainInfo = rlmDomainGetDomainInfo(prGlueInfo->prAdapter); -+ ASSERT(prDomainInfo); -+ -+ /* 4 ToDo: Enable Step 2 only if we could get Country Code from framework */ -+ /* 4 2. Get current domain channel list */ -+ -+#if 0 -+ rlmDomainGetChnlList(prGlueInfo->prAdapter, -+ BAND_2G4, MAXMUN_2_4G_CHA_NUM, &ucMax_24G_Chn_List, aucChannelList); -+#endif -+ -+ prGetChnLoad = (P_PARAM_GET_CHN_LOAD) &(prGlueInfo->prAdapter->rWifiVar.rChnLoadInfo); -+ for (ucIdx = 0; ucIdx < ucMax_24G_Chn_List; ucIdx++) { -+ DBGLOG(P2P, INFO, -+ "[Auto Channel] ch[%d]=%d\n", ucIdx, -+ prGetChnLoad->rEachChnLoad[ucIdx + ucInnerIdx].u2APNum); -+ } -+ -+ /*Calculate Each Channel Direty Score */ -+ for (ucIdx = ucDefaultIdx; ucIdx < ucMax_24G_Chn_List; ucIdx++) { -+ -+#if 1 -+ u2APNumScore = prGetChnLoad->rEachChnLoad[ucIdx].u2APNum * CHN_DIRTY_WEIGHT_UPPERBOUND; -+ u2UpThreshold = u2LowThreshold = 3; -+ -+ if (ucIdx < 3) { -+ u2UpThreshold = ucIdx; -+ u2LowThreshold = 3; -+ } else if (ucIdx >= (ucMax_24G_Chn_List - 3)) { -+ u2UpThreshold = 3; -+ u2LowThreshold = ucMax_24G_Chn_List - (ucIdx + 1); -+ -+ } -+ -+ /*Calculate Lower Channel Dirty Score */ -+ for (ucInnerIdx = 0; ucInnerIdx < u2LowThreshold; ucInnerIdx++) { -+ ucArrayIdx = ucIdx + ucInnerIdx + 1; -+ if (ucArrayIdx < MAX_AUTO_CHAL_NUM) { -+ u2APNumScore += -+ (prGetChnLoad->rEachChnLoad[ucArrayIdx].u2APNum * -+ (CHN_DIRTY_WEIGHT_UPPERBOUND - 1 - ucInnerIdx)); -+ } -+ } -+ -+ /*Calculate Upper Channel Dirty Score */ -+ for (ucInnerIdx = 0; ucInnerIdx < u2UpThreshold; ucInnerIdx++) { -+ ucArrayIdx = ucIdx - ucInnerIdx - 1; -+ if (ucArrayIdx < MAX_AUTO_CHAL_NUM) { -+ u2APNumScore += -+ (prGetChnLoad->rEachChnLoad[ucArrayIdx].u2APNum * -+ (CHN_DIRTY_WEIGHT_UPPERBOUND - 1 - ucInnerIdx)); -+ } -+ } -+ -+ ar2_4G_ChannelLoadingWeightScore[ucIdx].u2APNum = u2APNumScore; -+ -+ DBGLOG(P2P, INFO, "[Auto Channel]chn=%d score=%d\n", ucIdx, u2APNumScore); -+#else -+ if (ucIdx == 0) { -+ /* ar2_4G_ChannelLoadingWeightScore[ucIdx].u2APNum = -+ (prGetChnLoad->rEachChnLoad[ucIdx].u2APNum + -+ prGetChnLoad->rEachChnLoad[ucIdx+1].u2APNum*0.75); */ -+ u2APNumScore = (prGetChnLoad->rEachChnLoad[ucIdx].u2APNum + ((UINT_16) -+ ((3 * -+ (prGetChnLoad-> -+ rEachChnLoad[ucIdx + -+ 1]. -+ u2APNum + -+ prGetChnLoad-> -+ rEachChnLoad[ucIdx + -+ 2]. -+ u2APNum)) / 4))); -+ -+ ar2_4G_ChannelLoadingWeightScore[ucIdx].u2APNum = u2APNumScore; -+ DBGLOG(P2P, INFO, -+ "[Auto Channel]ucIdx=%d score=%d=%d+0.75*%d\n", ucIdx, -+ ar2_4G_ChannelLoadingWeightScore[ucIdx].u2APNum, -+ prGetChnLoad->rEachChnLoad[ucIdx].u2APNum, -+ prGetChnLoad->rEachChnLoad[ucIdx + 1].u2APNum)); -+ } -+ if ((ucIdx > 0) && (ucIdx < (MAXMUN_2_4G_CHA_NUM - 1))) { -+ u2APNumScore = (prGetChnLoad->rEachChnLoad[ucIdx].u2APNum + ((UINT_16) -+ ((3 * -+ (prGetChnLoad-> -+ rEachChnLoad[ucIdx + -+ 1]. -+ u2APNum + -+ prGetChnLoad-> -+ rEachChnLoad[ucIdx - -+ 1]. -+ u2APNum)) / 4))); -+ -+ ar2_4G_ChannelLoadingWeightScore[ucIdx].u2APNum = u2APNumScore; -+ DBGLOG(P2P, INFO, -+ "[Auto Channel]ucIdx=%d score=%d=%d+0.75*%d+0.75*%d\n", ucIdx, -+ ar2_4G_ChannelLoadingWeightScore[ucIdx].u2APNum, -+ prGetChnLoad->rEachChnLoad[ucIdx].u2APNum, -+ prGetChnLoad->rEachChnLoad[ucIdx + 1].u2APNum, -+ prGetChnLoad->rEachChnLoad[ucIdx - 1].u2APNum)); -+ } -+ -+ if (ucIdx == (MAXMUN_2_4G_CHA_NUM - 1)) { -+ u2APNumScore = (prGetChnLoad->rEachChnLoad[ucIdx].u2APNum + -+ ((UINT_16) ((3 * prGetChnLoad->rEachChnLoad[ucIdx - 1].u2APNum) / 4))); -+ -+ ar2_4G_ChannelLoadingWeightScore[ucIdx].u2APNum = u2APNumScore; -+ DBGLOG(P2P, INFO, -+ "[Auto Channel]ucIdx=%d score=%d=%d+0.75*%d\n", ucIdx, -+ ar2_4G_ChannelLoadingWeightScore[ucIdx].u2APNum, -+ prGetChnLoad->rEachChnLoad[ucIdx].u2APNum, -+ prGetChnLoad->rEachChnLoad[ucIdx - 1].u2APNum)); -+ } -+#endif -+ -+ } -+ -+ u4LteSafeChnBitMask_2_4G = -+ prQueryLTEChn->rLteSafeChnList.au4SafeChannelBitmask[NL80211_TESTMODE_AVAILABLE_CHAN_2G_BASE_1 - 1]; -+ -+ /*Find out the best channel */ -+ for (ucIdx = ucDefaultIdx; ucIdx < ucMax_24G_Chn_List; ucIdx++) { -+ /* 4 Skip LTE Unsafe Channel */ -+ fgIsLteSafeChn = ((u4LteSafeChnBitMask_2_4G & BIT(ucIdx + 1)) >> ucIdx); -+ if (!fgIsLteSafeChn) -+ continue; -+ -+ prChnLoad = -+ (P_PARAM_CHN_LOAD_INFO) &(prGlueInfo->prAdapter->rWifiVar. -+ rChnLoadInfo.rEachChnLoad[ucIdx]); -+ if (rPreferChannels[0].u2APNum >= ar2_4G_ChannelLoadingWeightScore[ucIdx].u2APNum) { -+ rPreferChannels[1].ucChannel = rPreferChannels[0].ucChannel; -+ rPreferChannels[1].u2APNum = rPreferChannels[0].u2APNum; -+ -+ rPreferChannels[0].ucChannel = ucIdx; -+ rPreferChannels[0].u2APNum = ar2_4G_ChannelLoadingWeightScore[ucIdx].u2APNum; -+ } else { -+ if (rPreferChannels[1].u2APNum >= ar2_4G_ChannelLoadingWeightScore[ucIdx].u2APNum -+ || fgIsFistRecord == 1) { -+ fgIsFistRecord = FALSE; -+ rPreferChannels[1].ucChannel = ucIdx; -+ rPreferChannels[1].u2APNum = ar2_4G_ChannelLoadingWeightScore[ucIdx].u2APNum; -+ } -+ } -+ } -+ /* AcsChnRepot[NL80211_TESTMODE_AVAILABLE_CHAN_2G_BASE_1-1] = -+ BITS((rQueryLTEChn.rLteSafeChnList.ucChannelLow-1),(rQueryLTEChn.rLteSafeChnList.ucChannelHigh-1)); */ -+ AcsChnReport[NL80211_TESTMODE_AVAILABLE_CHAN_2G_BASE_1 - 1] = fgIsReady ? BIT(31) : 0; -+ AcsChnReport[NL80211_TESTMODE_AVAILABLE_CHAN_2G_BASE_1 - 1] |= BIT(rPreferChannels[0].ucChannel); -+ } -+ -+ /* ToDo: Support 5G Channel Selection */ -+ AcsChnReport[NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_34 - 1] = 0x11223344; -+ AcsChnReport[NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_149 - 1] = 0x55667788; -+ AcsChnReport[NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_184 - 1] = 0x99AABBCC; -+ -+ /*NLA_PUT_U8(skb, NL80211_TESTMODE_AVAILABLE_CHAN_INVALID, 0);*/ -+ { -+ unsigned char __tmp = 0; -+ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_AVAILABLE_CHAN_INVALID, sizeof(unsigned char), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ -+ /*NLA_PUT_U32(skb, NL80211_TESTMODE_AVAILABLE_CHAN_2G_BASE_1, -+ AcsChnReport[NL80211_TESTMODE_AVAILABLE_CHAN_2G_BASE_1 - 1]);*/ -+ { -+ unsigned int __tmp = AcsChnReport[NL80211_TESTMODE_AVAILABLE_CHAN_2G_BASE_1 - 1]; -+ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_AVAILABLE_CHAN_2G_BASE_1, -+ sizeof(unsigned int), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ -+ /*NLA_PUT_U32(skb, NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_34, -+ AcsChnReport[NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_34 - 1]);*/ -+ { -+ unsigned int __tmp = AcsChnReport[NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_34 - 1]; -+ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_34, -+ sizeof(unsigned int), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ -+ /*NLA_PUT_U32(skb, NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_149, -+ AcsChnReport[NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_149 - 1]);*/ -+ { -+ unsigned int __tmp = AcsChnReport[NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_149 - 1]; -+ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_149, -+ sizeof(unsigned int), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ -+ -+ /*NLA_PUT_U32(skb, NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_184, -+ AcsChnReport[NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_184 - 1]);*/ -+ { -+ unsigned int __tmp = AcsChnReport[NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_184 - 1]; -+ -+ if (unlikely(nla_put(skb, NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_184, -+ sizeof(unsigned int), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ -+ DBGLOG(P2P, INFO, -+ "[Auto Channel]Relpy AcsChanInfo[%x:%x:%x:%x]\n", AcsChnReport[0], AcsChnReport[1], AcsChnReport[2], -+ AcsChnReport[3]); -+ -+ i4Status = cfg80211_testmode_reply(skb); -+ /*need confirm cfg80211_testmode_reply will free skb*/ -+ skb = NULL; -+ /*kalMemFree(prQueryLTEChn, VIR_MEM_TYPE, sizeof(PARAM_GET_CHN_LOAD));*/ -+ -+nla_put_failure: -+ kalMemFree(prQueryLTEChn, VIR_MEM_TYPE, sizeof(PARAM_GET_CHN_LOAD)); -+ if (skb != NULL) -+ kfree_skb(skb); -+ return i4Status; -+ -+} -+#endif -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * @brief cfg80211 suspend callback, will be invoked in wiphy_suspend -+ * -+ * @param wiphy: pointer to wiphy -+ * wow: pointer to cfg80211_wowlan -+ * -+ * @retval 0: successful -+ * others: failure -+ */ -+/*----------------------------------------------------------------------------*/ -+int mtk_cfg80211_suspend(struct wiphy *wiphy, struct cfg80211_wowlan *wow) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ -+ if (kalHaltTryLock()) -+ return 0; -+ -+ if (kalIsHalted() || !wiphy) -+ goto end; -+ -+ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); -+ -+ set_bit(SUSPEND_FLAG_FOR_WAKEUP_REASON, &prGlueInfo->prAdapter->ulSuspendFlag); -+ set_bit(SUSPEND_FLAG_CLEAR_WHEN_RESUME, &prGlueInfo->prAdapter->ulSuspendFlag); -+end: -+ kalHaltUnlock(); -+ return 0; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * @brief cfg80211 resume callback, will be invoked in wiphy_resume. -+ * -+ * @param wiphy: pointer to wiphy -+ * -+ * @retval 0: successful -+ * others: failure -+ */ -+/*----------------------------------------------------------------------------*/ -+int mtk_cfg80211_resume(struct wiphy *wiphy) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ P_BSS_DESC_T *pprBssDesc = NULL; -+ P_ADAPTER_T prAdapter = NULL; -+ UINT_8 i = 0; -+ -+ if (kalHaltTryLock()) -+ return 0; -+ -+ if (kalIsHalted() || !wiphy) -+ goto end; -+ -+ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); -+ prAdapter = prGlueInfo->prAdapter; -+ clear_bit(SUSPEND_FLAG_CLEAR_WHEN_RESUME, &prAdapter->ulSuspendFlag); -+ pprBssDesc = &prAdapter->rWifiVar.rScanInfo.rNloParam.aprPendingBssDescToInd[0]; -+ for (; i < SCN_SSID_MATCH_MAX_NUM; i++) { -+ if (pprBssDesc[i] == NULL) -+ break; -+ if (pprBssDesc[i]->u2RawLength == 0) -+ continue; -+ kalIndicateBssInfo(prGlueInfo, -+ (PUINT_8) pprBssDesc[i]->aucRawBuf, -+ pprBssDesc[i]->u2RawLength, -+ pprBssDesc[i]->ucChannelNum, -+ RCPI_TO_dBm(pprBssDesc[i]->ucRCPI)); -+ } -+ DBGLOG(SCN, INFO, "pending %d sched scan results\n", i); -+ if (i > 0) -+ kalMemZero(&pprBssDesc[0], i * sizeof(P_BSS_DESC_T)); -+end: -+ kalHaltUnlock(); -+ return 0; -+} -+ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_init.c b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_init.c -new file mode 100644 -index 000000000000..95ca7546b1bb ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_init.c -@@ -0,0 +1,3502 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -+ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux/gl_init.c#7 -+*/ -+ -+/*! \file gl_init.c -+ \brief Main routines of Linux driver -+ -+ This file contains the main routines of Linux driver for MediaTek Inc. 802.11 -+ Wireless LAN Adapters. -+*/ -+ -+/* -+** Log: gl_init.c -+** -+** 09 03 2013 cp.wu -+** add path for reassociation -+ * -+ * 07 17 2012 yuche.tsai -+ * NULL -+ * Fix compile error. -+ * -+ * 07 17 2012 yuche.tsai -+ * NULL -+ * Fix compile error for JB. -+ * -+ * 07 17 2012 yuche.tsai -+ * NULL -+ * Let netdev bring up. -+ * -+ * 07 17 2012 yuche.tsai -+ * NULL -+ * Compile no error before trial run. -+ * -+ * 06 13 2012 yuche.tsai -+ * NULL -+ * Update maintrunk driver. -+ * Add support for driver compose assoc request frame. -+ * -+ * 05 25 2012 yuche.tsai -+ * NULL -+ * Fix reset KE issue. -+ * -+ * 05 11 2012 cp.wu -+ * [WCXRP00001237] [MT6620 Wi-Fi][Driver] Show MAC address and MAC address source for ACS's convenience -+ * show MAC address & source while initiliazation -+ * -+ * 03 02 2012 terry.wu -+ * NULL -+ * EXPORT_SYMBOL(rsnParseCheckForWFAInfoElem);. -+ * -+ * 03 02 2012 terry.wu -+ * NULL -+ * Snc CFG80211 modification for ICS migration from branch 2.2. -+ * -+ * 03 02 2012 terry.wu -+ * NULL -+ * Sync CFG80211 modification from branch 2,2. -+ * -+ * 03 02 2012 terry.wu -+ * NULL -+ * Enable CFG80211 Support. -+ * -+ * 12 22 2011 george.huang -+ * [WCXRP00000905] [MT6628 Wi-Fi][FW] Code refinement for ROM/ RAM module dependency -+ * using global variable instead of stack for setting wlanoidSetNetworkAddress(), due to buffer may be released before -+ * TX thread handling -+ * -+ * 11 18 2011 yuche.tsai -+ * NULL -+ * CONFIG P2P support RSSI query, default turned off. -+ * -+ * 11 14 2011 yuche.tsai -+ * [WCXRP00001107] [Volunteer Patch][Driver] Large Network Type index assert in FW issue. -+ * Fix large network type index assert in FW issue. -+ * -+ * 11 14 2011 cm.chang -+ * NULL -+ * Fix compiling warning -+ * -+ * 11 11 2011 yuche.tsai -+ * NULL -+ * Fix work thread cancel issue. -+ * -+ * 11 10 2011 cp.wu -+ * [WCXRP00001098] [MT6620 Wi-Fi][Driver] Replace printk by DBG LOG macros in linux porting layer -+ * 1. eliminaite direct calls to printk in porting layer. -+ * 2. replaced by DBGLOG, which would be XLOG on ALPS platforms. -+ * -+ * 10 06 2011 eddie.chen -+ * [WCXRP00001027] [MT6628 Wi-Fi][Firmware/Driver] Tx fragmentation -+ * Add rlmDomainGetChnlList symbol. -+ * -+ * 09 22 2011 cm.chang -+ * NULL -+ * Safer writng stype to avoid unitialized regitry structure -+ * -+ * 09 21 2011 cm.chang -+ * [WCXRP00000969] [MT6620 Wi-Fi][Driver][FW] Channel list for 5G band based on country code -+ * Avoid possible structure alignment problem -+ * -+ * 09 20 2011 chinglan.wang -+ * [WCXRP00000989] [WiFi Direct] [Driver] Add a new io control API to start the formation for the sigma test. -+ * . -+ * -+ * 09 08 2011 cm.chang -+ * [WCXRP00000969] [MT6620 Wi-Fi][Driver][FW] Channel list for 5G band based on country code -+ * Use new fields ucChannelListMap and ucChannelListIndex in NVRAM -+ * -+ * 08 31 2011 cm.chang -+ * [WCXRP00000969] [MT6620 Wi-Fi][Driver][FW] Channel list for 5G band based on country code -+ * . -+ * -+ * 08 11 2011 cp.wu -+ * [WCXRP00000830] [MT6620 Wi-Fi][Firmware] Use MDRDY counter to detect empty channel for shortening scan time -+ * expose scnQuerySparseChannel() for P2P-FSM. -+ * -+ * 08 11 2011 cp.wu -+ * [WCXRP00000830] [MT6620 Wi-Fi][Firmware] Use MDRDY counter to detect empty channel for shortening scan time -+ * sparse channel detection: -+ * driver: collect sparse channel information with scan-done event -+ * -+ * 08 02 2011 yuche.tsai -+ * [WCXRP00000896] [Volunteer Patch][WiFi Direct][Driver] GO with multiple client, TX deauth to a disconnecting -+ * device issue. -+ * Fix GO send deauth frame issue. -+ * -+ * 07 07 2011 wh.su -+ * [WCXRP00000839] [MT6620 Wi-Fi][Driver] Add the dumpMemory8 and dumpMemory32 EXPORT_SYMBOL -+ * Add the dumpMemory8 symbol export for debug mode. -+ * -+ * 07 06 2011 terry.wu -+ * [WCXRP00000735] [MT6620 Wi-Fi][BoW][FW/Driver] Protect BoW connection establishment -+ * Improve BoW connection establishment speed. -+ * -+ * 07 05 2011 yuche.tsai -+ * [WCXRP00000821] [Volunteer Patch][WiFi Direct][Driver] WiFi Direct Connection Speed Issue -+ * Export one symbol for enhancement. -+ * -+ * 06 13 2011 eddie.chen -+ * [WCXRP00000779] [MT6620 Wi-Fi][DRV] Add tx rx statistics in linux and use netif_rx_ni -+ * Add tx rx statistics and netif_rx_ni. -+ * -+ * 05 27 2011 cp.wu -+ * [WCXRP00000749] [MT6620 Wi-Fi][Driver] Add band edge tx power control to Wi-Fi NVRAM -+ * invoke CMD_ID_SET_EDGE_TXPWR_LIMIT when there is valid data exist in NVRAM content. -+ * -+ * 05 18 2011 cp.wu -+ * [WCXRP00000734] [MT6620 Wi-Fi][Driver] Pass PHY_PARAM in NVRAM to firmware domain -+ * pass PHY_PARAM in NVRAM from driver to firmware. -+ * -+ * 05 09 2011 jeffrey.chang -+ * [WCXRP00000710] [MT6620 Wi-Fi] Support pattern filter update function on IP address change -+ * support ARP filter through kernel notifier -+ * -+ * 05 03 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Use kalMemAlloc to allocate event buffer for kalIndicateBOWEvent. -+ * -+ * 04 27 2011 george.huang -+ * [WCXRP00000684] [MT6620 Wi-Fi][Driver] Support P2P setting ARP filter -+ * Support P2P ARP filter setting on early suspend/ late resume -+ * -+ * 04 18 2011 terry.wu -+ * [WCXRP00000660] [MT6620 Wi-Fi][Driver] Remove flag CFG_WIFI_DIRECT_MOVED -+ * Remove flag CFG_WIFI_DIRECT_MOVED. -+ * -+ * 04 15 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Add BOW short range mode. -+ * -+ * 04 14 2011 yuche.tsai -+ * [WCXRP00000646] [Volunteer Patch][MT6620][FW/Driver] Sigma Test Modification for some test case. -+ * Modify some driver connection flow or behavior to pass Sigma test more easier.. -+ * -+ * 04 12 2011 cm.chang -+ * [WCXRP00000634] [MT6620 Wi-Fi][Driver][FW] 2nd BSS will not support 40MHz bandwidth for concurrency -+ * . -+ * -+ * 04 11 2011 george.huang -+ * [WCXRP00000621] [MT6620 Wi-Fi][Driver] Support P2P supplicant to set power mode -+ * export wlan functions to p2p -+ * -+ * 04 08 2011 pat.lu -+ * [WCXRP00000623] [MT6620 Wi-Fi][Driver] use ARCH define to distinguish PC Linux driver -+ * Use CONFIG_X86 instead of PC_LINUX_DRIVER_USE option to have proper compile setting for PC Linux driver -+ * -+ * 04 08 2011 cp.wu -+ * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer -+ * glBusFreeIrq() should use the same pvCookie as glBusSetIrq() or request_irq()/free_irq() won't work as a pair. -+ * -+ * 04 08 2011 eddie.chen -+ * [WCXRP00000617] [MT6620 Wi-Fi][DRV/FW] Fix for sigma -+ * Fix for sigma -+ * -+ * 04 06 2011 cp.wu -+ * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer -+ * 1. do not check for pvData inside wlanNetCreate() due to it is NULL for eHPI port -+ * 2. update perm_addr as well for MAC address -+ * 3. not calling check_mem_region() anymore for eHPI -+ * 4. correct MSC_CS macro for 0-based notation -+ * -+ * 03 29 2011 cp.wu -+ * [WCXRP00000598] [MT6620 Wi-Fi][Driver] Implementation of interface for communicating with user space process for -+ * RESET_START and RESET_END events -+ * fix typo. -+ * -+ * 03 29 2011 cp.wu -+ * [WCXRP00000598] [MT6620 Wi-Fi][Driver] Implementation of interface for communicating with user space process for -+ * RESET_START and RESET_END events -+ * implement kernel-to-userspace communication via generic netlink socket for whole-chip resetting mechanism -+ * -+ * 03 23 2011 cp.wu -+ * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer -+ * apply multi-queue operation only for linux kernel > 2.6.26 -+ * -+ * 03 22 2011 pat.lu -+ * [WCXRP00000592] [MT6620 Wi-Fi][Driver] Support PC Linux Environment Driver Build -+ * Add a compiler option "PC_LINUX_DRIVER_USE" for building driver in PC Linux environment. -+ * -+ * 03 21 2011 cp.wu -+ * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer -+ * portability for compatible with linux 2.6.12. -+ * -+ * 03 21 2011 cp.wu -+ * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer -+ * improve portability for awareness of early version of linux kernel and wireless extension. -+ * -+ * 03 21 2011 cp.wu -+ * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer -+ * portability improvement -+ * -+ * 03 18 2011 jeffrey.chang -+ * [WCXRP00000512] [MT6620 Wi-Fi][Driver] modify the net device relative functions to support the H/W multiple queue -+ * remove early suspend functions -+ * -+ * 03 17 2011 cp.wu -+ * [WCXRP00000562] [MT6620 Wi-Fi][Driver] I/O buffer pre-allocation to avoid physically continuous memory shortage -+ * after system running for a long period -+ * reverse order to prevent probing racing. -+ * -+ * 03 16 2011 cp.wu -+ * [WCXRP00000562] [MT6620 Wi-Fi][Driver] I/O buffer pre-allocation to avoid physically continuous memory shortage -+ * after system running for a long period -+ * 1. pre-allocate physical continuous buffer while module is being loaded -+ * 2. use pre-allocated physical continuous buffer for TX/RX DMA transfer -+ * -+ * The windows part remained the same as before, but added similar APIs to hide the difference. -+ * -+ * 03 15 2011 jeffrey.chang -+ * [WCXRP00000558] [MT6620 Wi-Fi][MT6620 Wi-Fi][Driver] refine the queue selection algorithm for WMM -+ * refine the queue_select function -+ * -+ * 03 10 2011 cp.wu -+ * [WCXRP00000532] [MT6620 Wi-Fi][Driver] Migrate NVRAM configuration procedures from MT6620 E2 to MT6620 E3 -+ * deprecate configuration used by MT6620 E2 -+ * -+ * 03 10 2011 terry.wu -+ * [WCXRP00000505] [MT6620 Wi-Fi][Driver/FW] WiFi Direct Integration -+ * Remove unnecessary assert and message. -+ * -+ * 03 08 2011 terry.wu -+ * [WCXRP00000505] [MT6620 Wi-Fi][Driver/FW] WiFi Direct Integration -+ * Export nicQmUpdateWmmParms. -+ * -+ * 03 03 2011 jeffrey.chang -+ * [WCXRP00000512] [MT6620 Wi-Fi][Driver] modify the net device relative functions to support the H/W multiple queue -+ * support concurrent network -+ * -+ * 03 03 2011 jeffrey.chang -+ * [WCXRP00000512] [MT6620 Wi-Fi][Driver] modify the net device relative functions to support the H/W multiple queue -+ * modify net device relative functions to support multiple H/W queues -+ * -+ * 02 24 2011 george.huang -+ * [WCXRP00000495] [MT6620 Wi-Fi][FW] Support pattern filter for unwanted ARP frames -+ * Support ARP filter during suspended -+ * -+ * 02 21 2011 cp.wu -+ * [WCXRP00000482] [MT6620 Wi-Fi][Driver] Simplify logic for checking NVRAM existence in driver domain -+ * simplify logic for checking NVRAM existence only once. -+ * -+ * 02 17 2011 terry.wu -+ * [WCXRP00000459] [MT6620 Wi-Fi][Driver] Fix deference null pointer problem in wlanRemove -+ * Fix deference a null pointer problem in wlanRemove. -+ * -+ * 02 16 2011 jeffrey.chang -+ * NULL -+ * fix compilig error -+ * -+ * 02 16 2011 jeffrey.chang -+ * NULL -+ * Add query ipv4 and ipv6 address during early suspend and late resume -+ * -+ * 02 15 2011 jeffrey.chang -+ * NULL -+ * to support early suspend in android -+ * -+ * 02 11 2011 yuche.tsai -+ * [WCXRP00000431] [Volunteer Patch][MT6620][Driver] Add MLME support for deauthentication under AP(Hot-Spot) mode. -+ * Add one more export symbol. -+ * -+ * 02 10 2011 yuche.tsai -+ * [WCXRP00000431] [Volunteer Patch][MT6620][Driver] Add MLME support for deauthentication under AP(Hot-Spot) mode. -+ * Add RX deauthentication & disassociation process under Hot-Spot mode. -+ * -+ * 02 09 2011 terry.wu -+ * [WCXRP00000383] [MT6620 Wi-Fi][Driver] Separate WiFi and P2P driver into two modules -+ * Halt p2p module init and exit until TxThread finished p2p register and unregister. -+ * -+ * 02 08 2011 george.huang -+ * [WCXRP00000422] [MT6620 Wi-Fi][Driver] support query power mode OID handler -+ * Support querying power mode OID. -+ * -+ * 02 08 2011 yuche.tsai -+ * [WCXRP00000421] [Volunteer Patch][MT6620][Driver] Fix incorrect SSID length Issue -+ * Export Deactivation Network. -+ * -+ * 02 01 2011 jeffrey.chang -+ * [WCXRP00000414] KAL Timer is not unregistered when driver not loaded -+ * Unregister the KAL timer during driver unloading -+ * -+ * 01 26 2011 cm.chang -+ * [WCXRP00000395] [MT6620 Wi-Fi][Driver][FW] Search STA_REC with additional net type index argument -+ * Allocate system RAM if fixed message or mgmt buffer is not available -+ * -+ * 01 19 2011 cp.wu -+ * [WCXRP00000371] [MT6620 Wi-Fi][Driver] make linux glue layer portable for Android 2.3.1 with Linux 2.6.35.7 -+ * add compile option to check linux version 2.6.35 for different usage of system API to improve portability -+ * -+ * 01 12 2011 cp.wu -+ * [WCXRP00000357] [MT6620 Wi-Fi][Driver][Bluetooth over Wi-Fi] add another net device interface for BT AMP -+ * implementation of separate BT_OVER_WIFI data path. -+ * -+ * 01 10 2011 cp.wu -+ * [WCXRP00000349] [MT6620 Wi-Fi][Driver] make kalIoctl() of linux port as a thread safe API to avoid potential issues -+ * due to multiple access -+ * use mutex to protect kalIoctl() for thread safe. -+ * -+ * 01 04 2011 cp.wu -+ * [WCXRP00000338] [MT6620 Wi-Fi][Driver] Separate kalMemAlloc into kmalloc and vmalloc implementations to ease -+ * physically continuous memory demands -+ * separate kalMemAlloc() into virtually-continuous and physically-continuous type to ease slab system pressure -+ * -+ * 12 15 2010 cp.wu -+ * [WCXRP00000265] [MT6620 Wi-Fi][Driver] Remove set_mac_address routine from legacy Wi-Fi Android driver -+ * remove set MAC address. MAC address is always loaded from NVRAM instead. -+ * -+ * 12 10 2010 kevin.huang -+ * [WCXRP00000128] [MT6620 Wi-Fi][Driver] Add proc support to Android Driver for debug and driver status check -+ * Add Linux Proc Support -+ * -+ * 11 01 2010 yarco.yang -+ * [WCXRP00000149] [MT6620 WI-Fi][Driver]Fine tune performance on MT6516 platform -+ * Add GPIO debug function -+ * -+ * 11 01 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000150] [MT6620 Wi-Fi][Driver] -+ * Add implementation for querying current TX rate from firmware auto rate module -+ * 1) Query link speed (TX rate) from firmware directly with buffering mechanism to reduce overhead -+ * 2) Remove CNM CH-RECOVER event handling -+ * 3) cfg read/write API renamed with kal prefix for unified naming rules. -+ * -+ * 10 26 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000137] [MT6620 Wi-Fi] [FW] -+ * Support NIC capability query command -+ * 1) update NVRAM content template to ver 1.02 -+ * 2) add compile option for querying NIC capability (default: off) -+ * 3) modify AIS 5GHz support to run-time option, which could be turned on by registry or NVRAM setting -+ * 4) correct auto-rate compiler error under linux (treat warning as error) -+ * 5) simplify usage of NVRAM and REG_INFO_T -+ * 6) add version checking between driver and firmware -+ * -+ * 10 21 2010 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * . -+ * -+ * 10 19 2010 jeffrey.chang -+ * [WCXRP00000120] [MT6620 Wi-Fi][Driver] Refine linux kernel module to the license of MTK propietary and enable MTK -+ * HIF by default -+ * Refine linux kernel module to the license of MTK and enable MTK HIF -+ * -+ * 10 18 2010 jeffrey.chang -+ * [WCXRP00000106] [MT6620 Wi-Fi][Driver] Enable setting multicast callback in Android -+ * . -+ * -+ * 10 18 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000086] [MT6620 Wi-Fi][Driver] -+ * The mac address is all zero at android -+ * complete implementation of Android NVRAM access -+ * -+ * 09 27 2010 chinghwa.yu -+ * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000065] Update BoW design and settings -+ * Update BCM/BoW design and settings. -+ * -+ * 09 23 2010 cp.wu -+ * [WCXRP00000051] [MT6620 Wi-Fi][Driver] WHQL test fail in MAC address changed item -+ * use firmware reported mac address right after wlanAdapterStart() as permanent address -+ * -+ * 09 21 2010 kevin.huang -+ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning -+ * Eliminate Linux Compile Warning -+ * -+ * 09 03 2010 kevin.huang -+ * NULL -+ * Refine #include sequence and solve recursive/nested #include issue -+ * -+ * 09 01 2010 wh.su -+ * NULL -+ * adding the wapi support for integration test. -+ * -+ * 08 18 2010 yarco.yang -+ * NULL -+ * 1. Fixed HW checksum offload function not work under Linux issue. -+ * 2. Add debug message. -+ * -+ * 08 16 2010 yarco.yang -+ * NULL -+ * Support Linux x86 -+ * -+ * 08 02 2010 jeffrey.chang -+ * NULL -+ * 1) modify tx service thread to avoid busy looping -+ * 2) add spin lock declartion for linux build -+ * -+ * 07 29 2010 jeffrey.chang -+ * NULL -+ * fix memory leak for module unloading -+ * -+ * 07 28 2010 jeffrey.chang -+ * NULL -+ * 1) remove unused spinlocks -+ * 2) enable encyption ioctls -+ * 3) fix scan ioctl which may cause supplicant to hang -+ * -+ * 07 23 2010 jeffrey.chang -+ * -+ * bug fix: allocate regInfo when disabling firmware download -+ * -+ * 07 23 2010 jeffrey.chang -+ * -+ * use glue layer api to decrease or increase counter atomically -+ * -+ * 07 22 2010 jeffrey.chang -+ * -+ * add new spinlock -+ * -+ * 07 19 2010 jeffrey.chang -+ * -+ * modify cmd/data path for new design -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 05 26 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * 1) Modify set mac address code -+ * 2) remove power management macro -+ * -+ * 05 10 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * implement basic wi-fi direct framework -+ * -+ * 05 07 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * prevent supplicant accessing driver during resume -+ * -+ * 05 07 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * add basic framework for implementating P2P driver hook. -+ * -+ * 04 27 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * 1) fix firmware download bug -+ * 2) remove query statistics for acelerating firmware download -+ * -+ * 04 27 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * follow Linux's firmware framework, and remove unused kal API -+ * -+ * 04 21 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * add for private ioctl support -+ * -+ * 04 19 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * Query statistics from firmware -+ * -+ * 04 19 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * modify tcp/ip checksum offload flags -+ * -+ * 04 16 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * fix tcp/ip checksum offload bug -+ * -+ * 04 13 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * add framework for BT-over-Wi-Fi support. -+ * * * * * * * * * * * * * * * * * 1) prPendingCmdInfo is replaced by queue for multiple handler -+ * * * * * * * * * * * * * * * * * capability -+ * * * * * * * * * * * * * * * * * 2) command sequence number is now increased atomically -+ * * * * * * * * * * * * * * * * * 3) private data could be hold and taken use for other purpose -+ * -+ * 04 09 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * fix spinlock usage -+ * -+ * 04 07 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * Set MAC address from firmware -+ * -+ * 04 07 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * rWlanInfo should be placed at adapter rather than glue due to most operations -+ * * * * * * are done in adapter layer. -+ * -+ * 04 07 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * (1)improve none-glue code portability -+ * * (2) disable set Multicast address during atomic context -+ * -+ * 04 06 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * adding debug module -+ * -+ * 03 31 2010 wh.su -+ * [WPD00003816][MT6620 Wi-Fi] Adding the security support -+ * modify the wapi related code for new driver's design. -+ * -+ * 03 30 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * emulate NDIS Pending OID facility -+ * -+ * 03 26 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * fix f/w download start and load address by using config.h -+ * -+ * 03 26 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * [WPD00003826] Initial import for Linux port -+ * adding firmware download support -+ * -+ * 03 24 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * initial import for Linux port -+** \main\maintrunk.MT5921\52 2009-10-27 22:49:59 GMT mtk01090 -+** Fix compile error for Linux EHPI driver -+** \main\maintrunk.MT5921\51 2009-10-20 17:38:22 GMT mtk01090 -+** Refine driver unloading and clean up procedure. Block requests, stop main thread and clean up queued requests, -+** and then stop hw. -+** \main\maintrunk.MT5921\50 2009-10-08 10:33:11 GMT mtk01090 -+** Avoid accessing private data of net_device directly. Replace with netdev_priv(). Add more checking for input -+** parameters and pointers. -+** \main\maintrunk.MT5921\49 2009-09-28 20:19:05 GMT mtk01090 -+** Add private ioctl to carry OID structures. Restructure public/private ioctl interfaces to Linux kernel. -+** \main\maintrunk.MT5921\48 2009-09-03 13:58:46 GMT mtk01088 -+** remove non-used code -+** \main\maintrunk.MT5921\47 2009-09-03 11:40:25 GMT mtk01088 -+** adding the module parameter for wapi -+** \main\maintrunk.MT5921\46 2009-08-18 22:56:41 GMT mtk01090 -+** Add Linux SDIO (with mmc core) support. -+** Add Linux 2.6.21, 2.6.25, 2.6.26. -+** Fix compile warning in Linux. -+** \main\maintrunk.MT5921\45 2009-07-06 20:53:00 GMT mtk01088 -+** adding the code to check the wapi 1x frame -+** \main\maintrunk.MT5921\44 2009-06-23 23:18:55 GMT mtk01090 -+** Add build option BUILD_USE_EEPROM and compile option CFG_SUPPORT_EXT_CONFIG for NVRAM support -+** \main\maintrunk.MT5921\43 2009-02-16 23:46:51 GMT mtk01461 -+** Revise the order of increasing u4TxPendingFrameNum because of CFG_TX_RET_TX_CTRL_EARLY -+** \main\maintrunk.MT5921\42 2009-01-22 13:11:59 GMT mtk01088 -+** set the tid and 1x value at same packet reserved field -+** \main\maintrunk.MT5921\41 2008-10-20 22:43:53 GMT mtk01104 -+** Fix wrong variable name "prDev" in wlanStop() -+** \main\maintrunk.MT5921\40 2008-10-16 15:37:10 GMT mtk01461 -+** add handle WLAN_STATUS_SUCCESS in wlanHardStartXmit() for CFG_TX_RET_TX_CTRL_EARLY -+** \main\maintrunk.MT5921\39 2008-09-25 15:56:21 GMT mtk01461 -+** Update driver for Code review -+** \main\maintrunk.MT5921\38 2008-09-05 17:25:07 GMT mtk01461 -+** Update Driver for Code Review -+** \main\maintrunk.MT5921\37 2008-09-02 10:57:06 GMT mtk01461 -+** Update driver for code review -+** \main\maintrunk.MT5921\36 2008-08-05 01:53:28 GMT mtk01461 -+** Add support for linux statistics -+** \main\maintrunk.MT5921\35 2008-08-04 16:52:58 GMT mtk01461 -+** Fix ASSERT if removing module in BG_SSID_SCAN state -+** \main\maintrunk.MT5921\34 2008-06-13 22:52:24 GMT mtk01461 -+** Revise status code handling in wlanHardStartXmit() for WLAN_STATUS_SUCCESS -+** \main\maintrunk.MT5921\33 2008-05-30 18:56:53 GMT mtk01461 -+** Not use wlanoidSetCurrentAddrForLinux() -+** \main\maintrunk.MT5921\32 2008-05-30 14:39:40 GMT mtk01461 -+** Remove WMM Assoc Flag -+** \main\maintrunk.MT5921\31 2008-05-23 10:26:40 GMT mtk01084 -+** modify wlanISR interface -+** \main\maintrunk.MT5921\30 2008-05-03 18:52:36 GMT mtk01461 -+** Fix Unset Broadcast filter when setMulticast -+** \main\maintrunk.MT5921\29 2008-05-03 15:17:26 GMT mtk01461 -+** Move Query Media Status to GLUE -+** \main\maintrunk.MT5921\28 2008-04-24 22:48:21 GMT mtk01461 -+** Revise set multicast function by using windows oid style for LP own back -+** \main\maintrunk.MT5921\27 2008-04-24 12:00:08 GMT mtk01461 -+** Fix multicast setting in Linux and add comment -+** \main\maintrunk.MT5921\26 2008-03-28 10:40:22 GMT mtk01461 -+** Fix set mac address func in Linux -+** \main\maintrunk.MT5921\25 2008-03-26 15:37:26 GMT mtk01461 -+** Add set MAC Address -+** \main\maintrunk.MT5921\24 2008-03-26 14:24:53 GMT mtk01461 -+** For Linux, set net_device has feature with checksum offload by default -+** \main\maintrunk.MT5921\23 2008-03-11 14:50:52 GMT mtk01461 -+** Fix typo -+** \main\maintrunk.MT5921\22 2008-02-29 15:35:20 GMT mtk01088 -+** add 1x decide code for sw port control -+** \main\maintrunk.MT5921\21 2008-02-21 15:01:54 GMT mtk01461 -+** Rearrange the set off place of GLUE spin lock in HardStartXmit -+** \main\maintrunk.MT5921\20 2008-02-12 23:26:50 GMT mtk01461 -+** Add debug option - Packet Order for Linux and add debug level - Event -+** \main\maintrunk.MT5921\19 2007-12-11 00:11:12 GMT mtk01461 -+** Fix SPIN_LOCK protection -+** \main\maintrunk.MT5921\18 2007-11-30 17:02:25 GMT mtk01425 -+** 1. Set Rx multicast packets mode before setting the address list -+** \main\maintrunk.MT5921\17 2007-11-26 19:44:24 GMT mtk01461 -+** Add OS_TIMESTAMP to packet -+** \main\maintrunk.MT5921\16 2007-11-21 15:47:20 GMT mtk01088 -+** fixed the unload module issue -+** \main\maintrunk.MT5921\15 2007-11-07 18:37:38 GMT mtk01461 -+** Fix compile warnning -+** \main\maintrunk.MT5921\14 2007-11-02 01:03:19 GMT mtk01461 -+** Unify TX Path for Normal and IBSS Power Save + IBSS neighbor learning -+** \main\maintrunk.MT5921\13 2007-10-30 10:42:33 GMT mtk01425 -+** 1. Refine for multicast list -+** \main\maintrunk.MT5921\12 2007-10-25 18:08:13 GMT mtk01461 -+** Add VOIP SCAN Support & Refine Roaming -+** Revision 1.4 2007/07/05 07:25:33 MTK01461 -+** Add Linux initial code, modify doc, add 11BB, RF init code -+** -+** Revision 1.3 2007/06/27 02:18:50 MTK01461 -+** Update SCAN_FSM, Initial(Can Load Module), Proc(Can do Reg R/W), TX API -+** -+** Revision 1.2 2007/06/25 06:16:24 MTK01461 -+** Update illustrations, gl_init.c, gl_kal.c, gl_kal.h, gl_os.h and RX API -+** -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "gl_os.h" -+#include "wlan_lib.h" -+#include "gl_wext.h" -+#include "gl_cfg80211.h" -+#include "precomp.h" -+#if CFG_SUPPORT_AGPS_ASSIST -+#include "gl_kal.h" -+#endif -+#if defined(CONFIG_MTK_TC1_FEATURE) -+#include -+#endif -+#include "gl_vendor.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+/* #define MAX_IOREQ_NUM 10 */ -+ -+BOOLEAN fgIsUnderSuspend = false; -+ -+ -+#if CFG_ENABLE_WIFI_DIRECT -+spinlock_t g_p2p_lock; -+int g_u4P2PEnding = 0; -+int g_u4P2POnOffing = 0; -+#endif -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+/* Tasklet mechanism is like buttom-half in Linux. We just want to -+ * send a signal to OS for interrupt defer processing. All resources -+ * are NOT allowed reentry, so txPacket, ISR-DPC and ioctl must avoid preempty. -+ */ -+typedef struct _WLANDEV_INFO_T { -+ struct net_device *prDev; -+} WLANDEV_INFO_T, *P_WLANDEV_INFO_T; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+#define CHAN2G(_channel, _freq, _flags) \ -+{ \ -+ .band = NL80211_BAND_2GHZ, \ -+ .center_freq = (_freq), \ -+ .hw_value = (_channel), \ -+ .flags = (_flags), \ -+ .max_antenna_gain = 0, \ -+ .max_power = 30, \ -+} -+ -+static struct ieee80211_channel mtk_2ghz_channels[] = { -+ CHAN2G(1, 2412, 0), -+ CHAN2G(2, 2417, 0), -+ CHAN2G(3, 2422, 0), -+ CHAN2G(4, 2427, 0), -+ CHAN2G(5, 2432, 0), -+ CHAN2G(6, 2437, 0), -+ CHAN2G(7, 2442, 0), -+ CHAN2G(8, 2447, 0), -+ CHAN2G(9, 2452, 0), -+ CHAN2G(10, 2457, 0), -+ CHAN2G(11, 2462, 0), -+ CHAN2G(12, 2467, 0), -+ CHAN2G(13, 2472, 0), -+ CHAN2G(14, 2484, 0), -+}; -+ -+#define CHAN5G(_channel, _flags) \ -+{ \ -+ .band = NL80211_BAND_5GHZ, \ -+ .center_freq = 5000 + (5 * (_channel)), \ -+ .hw_value = (_channel), \ -+ .flags = (_flags), \ -+ .max_antenna_gain = 0, \ -+ .max_power = 30, \ -+} -+ -+static struct ieee80211_channel mtk_5ghz_channels[] = { -+ CHAN5G(34, 0), CHAN5G(36, 0), -+ CHAN5G(38, 0), CHAN5G(40, 0), -+ CHAN5G(42, 0), CHAN5G(44, 0), -+ CHAN5G(46, 0), CHAN5G(48, 0), -+ CHAN5G(52, 0), CHAN5G(56, 0), -+ CHAN5G(60, 0), CHAN5G(64, 0), -+ CHAN5G(100, 0), CHAN5G(104, 0), -+ CHAN5G(108, 0), CHAN5G(112, 0), -+ CHAN5G(116, 0), CHAN5G(120, 0), -+ CHAN5G(124, 0), CHAN5G(128, 0), -+ CHAN5G(132, 0), CHAN5G(136, 0), -+ CHAN5G(140, 0), CHAN5G(149, 0), -+ CHAN5G(153, 0), CHAN5G(157, 0), -+ CHAN5G(161, 0), CHAN5G(165, 0), -+ CHAN5G(169, 0), CHAN5G(173, 0), -+ CHAN5G(184, 0), CHAN5G(188, 0), -+ CHAN5G(192, 0), CHAN5G(196, 0), -+ CHAN5G(200, 0), CHAN5G(204, 0), -+ CHAN5G(208, 0), CHAN5G(212, 0), -+ CHAN5G(216, 0), -+}; -+ -+#define RATETAB_ENT(_rate, _rateid, _flags) \ -+{ \ -+ .bitrate = (_rate), \ -+ .hw_value = (_rateid), \ -+ .flags = (_flags), \ -+} -+ -+/* for cfg80211 - rate table */ -+static struct ieee80211_rate mtk_rates[] = { -+ RATETAB_ENT(10, 0x1000, 0), -+ RATETAB_ENT(20, 0x1001, 0), -+ RATETAB_ENT(55, 0x1002, 0), -+ RATETAB_ENT(110, 0x1003, 0), /* 802.11b */ -+ RATETAB_ENT(60, 0x2000, 0), -+ RATETAB_ENT(90, 0x2001, 0), -+ RATETAB_ENT(120, 0x2002, 0), -+ RATETAB_ENT(180, 0x2003, 0), -+ RATETAB_ENT(240, 0x2004, 0), -+ RATETAB_ENT(360, 0x2005, 0), -+ RATETAB_ENT(480, 0x2006, 0), -+ RATETAB_ENT(540, 0x2007, 0), /* 802.11a/g */ -+}; -+ -+#define mtk_a_rates (mtk_rates + 4) -+#define mtk_a_rates_size (sizeof(mtk_rates) / sizeof(mtk_rates[0]) - 4) -+#define mtk_g_rates (mtk_rates + 0) -+#define mtk_g_rates_size (sizeof(mtk_rates) / sizeof(mtk_rates[0]) - 0) -+ -+#define WLAN_MCS_INFO \ -+{ \ -+ .rx_mask = {0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0},\ -+ .rx_highest = 0, \ -+ .tx_params = IEEE80211_HT_MCS_TX_DEFINED, \ -+} -+ -+#define WLAN_HT_CAP \ -+{ \ -+ .ht_supported = true, \ -+ .cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 \ -+ | IEEE80211_HT_CAP_SM_PS \ -+ | IEEE80211_HT_CAP_GRN_FLD \ -+ | IEEE80211_HT_CAP_SGI_20 \ -+ | IEEE80211_HT_CAP_SGI_40, \ -+ .ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K, \ -+ .ampdu_density = IEEE80211_HT_MPDU_DENSITY_NONE, \ -+ .mcs = WLAN_MCS_INFO, \ -+} -+ -+/********************************************************** -+* Public for both legacy Wi-Fi and P2P to access -+**********************************************************/ -+struct ieee80211_supported_band mtk_band_2ghz = { -+ .band = NL80211_BAND_2GHZ, -+ .channels = mtk_2ghz_channels, -+ .n_channels = ARRAY_SIZE(mtk_2ghz_channels), -+ .bitrates = mtk_g_rates, -+ .n_bitrates = mtk_g_rates_size, -+ .ht_cap = WLAN_HT_CAP, -+}; -+ -+struct ieee80211_supported_band mtk_band_5ghz = { -+ .band = NL80211_BAND_5GHZ, -+ .channels = mtk_5ghz_channels, -+ .n_channels = ARRAY_SIZE(mtk_5ghz_channels), -+ .bitrates = mtk_a_rates, -+ .n_bitrates = mtk_a_rates_size, -+ .ht_cap = WLAN_HT_CAP, -+}; -+ -+const UINT_32 mtk_cipher_suites[5] = { -+ /* keep WEP first, it may be removed below */ -+ WLAN_CIPHER_SUITE_WEP40, -+ WLAN_CIPHER_SUITE_WEP104, -+ WLAN_CIPHER_SUITE_TKIP, -+ WLAN_CIPHER_SUITE_CCMP, -+ -+ /* keep last -- depends on hw flags! */ -+ WLAN_CIPHER_SUITE_AES_CMAC -+}; -+ -+/*********************************************************/ -+ -+#define NIC_INF_NAME "wlan%d" /* interface name */ -+#if CFG_TC1_FEATURE -+#define NIC_INF_NAME_IN_AP_MODE "legacy%d" -+#endif -+ -+/* support to change debug module info dynamically */ -+UINT_8 aucDebugModule[DBG_MODULE_NUM]; -+UINT_32 u4DebugModule = 0; -+ -+/* 4 2007/06/26, mikewu, now we don't use this, we just fix the number of wlan device to 1 */ -+static WLANDEV_INFO_T arWlanDevInfo[CFG_MAX_WLAN_DEVICES] = { {0} }; -+ -+static UINT_32 u4WlanDevNum; /* How many NICs coexist now */ -+ -+/**20150205 added work queue for sched_scan to avoid cfg80211 stop schedule scan dead loack**/ -+struct delayed_work sched_workq; -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+#if CFG_ENABLE_WIFI_DIRECT -+static SUB_MODULE_HANDLER rSubModHandler[SUB_MODULE_NUM] = { {NULL} }; -+#endif -+ -+static struct cfg80211_ops mtk_wlan_ops = { -+ .suspend = mtk_cfg80211_suspend, -+ .resume = mtk_cfg80211_resume, -+ .change_virtual_intf = mtk_cfg80211_change_iface, -+ .add_key = mtk_cfg80211_add_key, -+ .get_key = mtk_cfg80211_get_key, -+ .del_key = mtk_cfg80211_del_key, -+ .set_default_key = mtk_cfg80211_set_default_key, -+ .set_default_mgmt_key = mtk_cfg80211_set_default_mgmt_key, -+ .get_station = mtk_cfg80211_get_station, -+ .change_station = mtk_cfg80211_change_station, -+ .add_station = mtk_cfg80211_add_station, -+ .del_station = mtk_cfg80211_del_station, -+ .scan = mtk_cfg80211_scan, -+ .connect = mtk_cfg80211_connect, -+ .disconnect = mtk_cfg80211_disconnect, -+ .join_ibss = mtk_cfg80211_join_ibss, -+ .leave_ibss = mtk_cfg80211_leave_ibss, -+ .set_power_mgmt = mtk_cfg80211_set_power_mgmt, -+ .set_pmksa = mtk_cfg80211_set_pmksa, -+ .del_pmksa = mtk_cfg80211_del_pmksa, -+ .flush_pmksa = mtk_cfg80211_flush_pmksa, -+ .assoc = mtk_cfg80211_assoc, -+ /* Action Frame TX/RX */ -+ .remain_on_channel = mtk_cfg80211_remain_on_channel, -+ .cancel_remain_on_channel = mtk_cfg80211_cancel_remain_on_channel, -+ .mgmt_tx = mtk_cfg80211_mgmt_tx, -+/* .mgmt_tx_cancel_wait = mtk_cfg80211_mgmt_tx_cancel_wait, */ -+ .mgmt_frame_register = mtk_cfg80211_mgmt_frame_register, -+#ifdef CONFIG_NL80211_TESTMODE -+ .testmode_cmd = mtk_cfg80211_testmode_cmd, -+#endif -+#if (CFG_SUPPORT_TDLS == 1) -+ .tdls_mgmt = TdlsexCfg80211TdlsMgmt, -+ .tdls_oper = TdlsexCfg80211TdlsOper, -+#endif /* CFG_SUPPORT_TDLS */ -+#if 1 /* Remove schedule_scan because we need more verification for NLO */ -+ .sched_scan_start = mtk_cfg80211_sched_scan_start, -+ .sched_scan_stop = mtk_cfg80211_sched_scan_stop, -+#endif -+}; -+ -+static const struct wiphy_vendor_command mtk_wlan_vendor_ops[] = { -+ { -+ { -+ .vendor_id = GOOGLE_OUI, -+ .subcmd = WIFI_SUBCMD_GET_CHANNEL_LIST -+ }, -+ .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, -+ .doit = mtk_cfg80211_vendor_get_channel_list -+ }, -+ { -+ { -+ .vendor_id = GOOGLE_OUI, -+ .subcmd = WIFI_SUBCMD_SET_COUNTRY_CODE -+ }, -+ .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, -+ .doit = mtk_cfg80211_vendor_set_country_code -+ }, -+ /* GSCAN */ -+ { -+ { -+ .vendor_id = GOOGLE_OUI, -+ .subcmd = GSCAN_SUBCMD_GET_CAPABILITIES -+ }, -+ .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, -+ .doit = mtk_cfg80211_vendor_get_gscan_capabilities -+ }, -+ { -+ { -+ .vendor_id = GOOGLE_OUI, -+ .subcmd = GSCAN_SUBCMD_SET_CONFIG -+ }, -+ .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, -+ .doit = mtk_cfg80211_vendor_set_config -+ }, -+ { -+ { -+ .vendor_id = GOOGLE_OUI, -+ .subcmd = GSCAN_SUBCMD_SET_SCAN_CONFIG -+ }, -+ .flags = WIPHY_VENDOR_CMD_NEED_WDEV, -+ .doit = mtk_cfg80211_vendor_set_scan_config -+ }, -+ { -+ { -+ .vendor_id = GOOGLE_OUI, -+ .subcmd = GSCAN_SUBCMD_ENABLE_GSCAN -+ }, -+ .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, -+ .doit = mtk_cfg80211_vendor_enable_scan -+ }, -+ { -+ { -+ .vendor_id = GOOGLE_OUI, -+ .subcmd = GSCAN_SUBCMD_ENABLE_FULL_SCAN_RESULTS -+ }, -+ .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, -+ .doit = mtk_cfg80211_vendor_enable_full_scan_results -+ }, -+ { -+ { -+ .vendor_id = GOOGLE_OUI, -+ .subcmd = GSCAN_SUBCMD_GET_SCAN_RESULTS -+ }, -+ .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, -+ .doit = mtk_cfg80211_vendor_get_scan_results -+ }, -+ { -+ { -+ .vendor_id = GOOGLE_OUI, -+ .subcmd = GSCAN_SUBCMD_SET_SIGNIFICANT_CHANGE_CONFIG -+ }, -+ .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, -+ .doit = mtk_cfg80211_vendor_set_significant_change -+ }, -+ { -+ { -+ .vendor_id = GOOGLE_OUI, -+ .subcmd = GSCAN_SUBCMD_SET_HOTLIST -+ }, -+ .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, -+ .doit = mtk_cfg80211_vendor_set_hotlist -+ }, -+ /* RTT */ -+ { -+ { -+ .vendor_id = GOOGLE_OUI, -+ .subcmd = RTT_SUBCMD_GETCAPABILITY -+ }, -+ .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, -+ .doit = mtk_cfg80211_vendor_get_rtt_capabilities -+ }, -+ /* Link Layer Statistics */ -+ { -+ { -+ .vendor_id = GOOGLE_OUI, -+ .subcmd = LSTATS_SUBCMD_GET_INFO -+ }, -+ .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, -+ .doit = mtk_cfg80211_vendor_llstats_get_info -+ }, -+ -+}; -+ -+static const struct nl80211_vendor_cmd_info mtk_wlan_vendor_events[] = { -+ { -+ .vendor_id = GOOGLE_OUI, -+ .subcmd = GSCAN_EVENT_SIGNIFICANT_CHANGE_RESULTS -+ }, -+ { -+ .vendor_id = GOOGLE_OUI, -+ .subcmd = GSCAN_EVENT_HOTLIST_RESULTS_FOUND -+ }, -+ { -+ .vendor_id = GOOGLE_OUI, -+ .subcmd = GSCAN_EVENT_SCAN_RESULTS_AVAILABLE -+ }, -+ { -+ .vendor_id = GOOGLE_OUI, -+ .subcmd = GSCAN_EVENT_FULL_SCAN_RESULTS -+ }, -+ { -+ .vendor_id = GOOGLE_OUI, -+ .subcmd = RTT_EVENT_COMPLETE -+ }, -+ { -+ .vendor_id = GOOGLE_OUI, -+ .subcmd = GSCAN_EVENT_COMPLETE_SCAN -+ }, -+ { -+ .vendor_id = GOOGLE_OUI, -+ .subcmd = GSCAN_EVENT_HOTLIST_RESULTS_LOST -+ }, -+}; -+ -+/* There isn't a lot of sense in it, but you can transmit anything you like */ -+static const struct ieee80211_txrx_stypes -+ mtk_cfg80211_ais_default_mgmt_stypes[NUM_NL80211_IFTYPES] = { -+ [NL80211_IFTYPE_ADHOC] = { -+ .tx = 0xffff, -+ .rx = BIT(IEEE80211_STYPE_ACTION >> 4) -+ }, -+ [NL80211_IFTYPE_STATION] = { -+ .tx = 0xffff, -+ .rx = BIT(IEEE80211_STYPE_ACTION >> 4) | BIT(IEEE80211_STYPE_PROBE_REQ >> 4) -+ }, -+ [NL80211_IFTYPE_AP] = { -+ .tx = 0xffff, -+ .rx = BIT(IEEE80211_STYPE_PROBE_REQ >> 4) | BIT(IEEE80211_STYPE_ACTION >> 4) -+ }, -+ [NL80211_IFTYPE_AP_VLAN] = { -+ /* copy AP */ -+ .tx = 0xffff, -+ .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) | -+ BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) | -+ BIT(IEEE80211_STYPE_PROBE_REQ >> 4) | -+ BIT(IEEE80211_STYPE_DISASSOC >> 4) | -+ BIT(IEEE80211_STYPE_AUTH >> 4) | -+ BIT(IEEE80211_STYPE_DEAUTH >> 4) | BIT(IEEE80211_STYPE_ACTION >> 4) -+ }, -+ [NL80211_IFTYPE_P2P_CLIENT] = { -+ .tx = 0xffff, -+ .rx = BIT(IEEE80211_STYPE_ACTION >> 4) | BIT(IEEE80211_STYPE_PROBE_REQ >> 4) -+ }, -+ [NL80211_IFTYPE_P2P_GO] = { -+ .tx = 0xffff, -+ .rx = BIT(IEEE80211_STYPE_PROBE_REQ >> 4) | BIT(IEEE80211_STYPE_ACTION >> 4) -+ } -+}; -+ -+#ifdef CONFIG_PM -+static const struct wiphy_wowlan_support mtk_wlan_wowlan_support = { -+ .flags = WIPHY_WOWLAN_DISCONNECT | WIPHY_WOWLAN_ANY, -+}; -+#endif -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Override the implementation of select queue -+* -+* \param[in] dev Pointer to struct net_device -+* \param[in] skb Pointer to struct skb_buff -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+unsigned int _cfg80211_classify8021d(struct sk_buff *skb) -+{ -+ unsigned int dscp = 0; -+ -+ /* skb->priority values from 256->263 are magic values -+ * directly indicate a specific 802.1d priority. This is -+ * to allow 802.1d priority to be passed directly in from -+ * tags -+ */ -+ -+ if (skb->priority >= 256 && skb->priority <= 263) -+ return skb->priority - 256; -+ switch (skb->protocol) { -+ case htons(ETH_P_IP): -+ dscp = ip_hdr(skb)->tos & 0xfc; -+ break; -+ } -+ return dscp >> 5; -+} -+ -+static const UINT_16 au16Wlan1dToQueueIdx[8] = { 1, 0, 0, 1, 2, 2, 3, 3 }; -+ -+static UINT_16 wlanSelectQueue(struct net_device *dev, struct sk_buff *skb, -+ struct net_device *sb_dev, -+ select_queue_fallback_t fallback) -+{ -+ skb->priority = _cfg80211_classify8021d(skb); -+ -+ return au16Wlan1dToQueueIdx[skb->priority]; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Load NVRAM data and translate it into REG_INFO_T -+* -+* \param[in] prGlueInfo Pointer to struct GLUE_INFO_T -+* \param[out] prRegInfo Pointer to struct REG_INFO_T -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+static void glLoadNvram(IN P_GLUE_INFO_T prGlueInfo, OUT P_REG_INFO_T prRegInfo) -+{ -+ UINT_32 i, j; -+ UINT_8 aucTmp[2]; -+ PUINT_8 pucDest; -+ -+ ASSERT(prGlueInfo); -+ ASSERT(prRegInfo); -+ -+ if ((!prGlueInfo) || (!prRegInfo)) -+ return; -+ -+ if (kalCfgDataRead16(prGlueInfo, sizeof(WIFI_CFG_PARAM_STRUCT) - sizeof(UINT_16), (PUINT_16) aucTmp) == TRUE) { -+ prGlueInfo->fgNvramAvailable = TRUE; -+ -+ /* load MAC Address */ -+#if !defined(CONFIG_MTK_TC1_FEATURE) -+ for (i = 0; i < PARAM_MAC_ADDR_LEN; i += sizeof(UINT_16)) { -+ kalCfgDataRead16(prGlueInfo, -+ OFFSET_OF(WIFI_CFG_PARAM_STRUCT, aucMacAddress) + i, -+ (PUINT_16) (((PUINT_8) prRegInfo->aucMacAddr) + i)); -+ } -+#else -+ TC1_FAC_NAME(FacReadWifiMacAddr) ((unsigned char *)prRegInfo->aucMacAddr); -+#endif -+ -+ /* load country code */ -+ kalCfgDataRead16(prGlueInfo, OFFSET_OF(WIFI_CFG_PARAM_STRUCT, aucCountryCode[0]), (PUINT_16) aucTmp); -+ -+ /* cast to wide characters */ -+ prRegInfo->au2CountryCode[0] = (UINT_16) aucTmp[0]; -+ prRegInfo->au2CountryCode[1] = (UINT_16) aucTmp[1]; -+ -+ /* load default normal TX power */ -+ for (i = 0; i < sizeof(TX_PWR_PARAM_T); i += sizeof(UINT_16)) { -+ kalCfgDataRead16(prGlueInfo, -+ OFFSET_OF(WIFI_CFG_PARAM_STRUCT, rTxPwr) + i, -+ (PUINT_16) (((PUINT_8) &(prRegInfo->rTxPwr)) + i)); -+ } -+ -+ /* load feature flags */ -+ kalCfgDataRead16(prGlueInfo, OFFSET_OF(WIFI_CFG_PARAM_STRUCT, ucTxPwrValid), (PUINT_16) aucTmp); -+ prRegInfo->ucTxPwrValid = aucTmp[0]; -+ prRegInfo->ucSupport5GBand = aucTmp[1]; -+ -+ kalCfgDataRead16(prGlueInfo, OFFSET_OF(WIFI_CFG_PARAM_STRUCT, uc2G4BwFixed20M), (PUINT_16) aucTmp); -+ prRegInfo->uc2G4BwFixed20M = aucTmp[0]; -+ prRegInfo->uc5GBwFixed20M = aucTmp[1]; -+ -+ kalCfgDataRead16(prGlueInfo, OFFSET_OF(WIFI_CFG_PARAM_STRUCT, ucEnable5GBand), (PUINT_16) aucTmp); -+ prRegInfo->ucEnable5GBand = aucTmp[0]; -+ -+ /* load EFUSE overriding part */ -+ for (i = 0; i < sizeof(prRegInfo->aucEFUSE); i += sizeof(UINT_16)) { -+ kalCfgDataRead16(prGlueInfo, -+ OFFSET_OF(WIFI_CFG_PARAM_STRUCT, aucEFUSE) + i, -+ (PUINT_16) (((PUINT_8) &(prRegInfo->aucEFUSE)) + i)); -+ } -+ -+ /* load band edge tx power control */ -+ kalCfgDataRead16(prGlueInfo, OFFSET_OF(WIFI_CFG_PARAM_STRUCT, fg2G4BandEdgePwrUsed), (PUINT_16) aucTmp); -+ prRegInfo->fg2G4BandEdgePwrUsed = (BOOLEAN) aucTmp[0]; -+ if (aucTmp[0]) { -+ prRegInfo->cBandEdgeMaxPwrCCK = (INT_8) aucTmp[1]; -+ -+ kalCfgDataRead16(prGlueInfo, -+ OFFSET_OF(WIFI_CFG_PARAM_STRUCT, cBandEdgeMaxPwrOFDM20), (PUINT_16) aucTmp); -+ prRegInfo->cBandEdgeMaxPwrOFDM20 = (INT_8) aucTmp[0]; -+ prRegInfo->cBandEdgeMaxPwrOFDM40 = (INT_8) aucTmp[1]; -+ } -+ -+ /* load regulation subbands */ -+ kalCfgDataRead16(prGlueInfo, OFFSET_OF(WIFI_CFG_PARAM_STRUCT, ucRegChannelListMap), (PUINT_16) aucTmp); -+ prRegInfo->eRegChannelListMap = (ENUM_REG_CH_MAP_T) aucTmp[0]; -+ prRegInfo->ucRegChannelListIndex = aucTmp[1]; -+ -+ if (prRegInfo->eRegChannelListMap == REG_CH_MAP_CUSTOMIZED) { -+ for (i = 0; i < MAX_SUBBAND_NUM; i++) { -+ pucDest = (PUINT_8) &prRegInfo->rDomainInfo.rSubBand[i]; -+ for (j = 0; j < 6; j += sizeof(UINT_16)) { -+ kalCfgDataRead16(prGlueInfo, OFFSET_OF(WIFI_CFG_PARAM_STRUCT, aucRegSubbandInfo) -+ + (i * 6 + j), (PUINT_16) aucTmp); -+ -+ *pucDest++ = aucTmp[0]; -+ *pucDest++ = aucTmp[1]; -+ } -+ } -+ } -+ /* load RSSI compensation */ -+ kalCfgDataRead16(prGlueInfo, OFFSET_OF(WIFI_CFG_PARAM_STRUCT, uc2GRssiCompensation), (PUINT_16) aucTmp); -+ prRegInfo->uc2GRssiCompensation = aucTmp[0]; -+ prRegInfo->uc5GRssiCompensation = aucTmp[1]; -+ -+ kalCfgDataRead16(prGlueInfo, -+ OFFSET_OF(WIFI_CFG_PARAM_STRUCT, fgRssiCompensationValidbit), (PUINT_16) aucTmp); -+ prRegInfo->fgRssiCompensationValidbit = aucTmp[0]; -+ prRegInfo->ucRxAntennanumber = aucTmp[1]; -+ } else { -+ prGlueInfo->fgNvramAvailable = FALSE; -+ } -+ -+} -+ -+#if CFG_ENABLE_WIFI_DIRECT -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief called by txthread, run sub module init function -+* -+* \param[in] prGlueInfo Pointer to struct GLUE_INFO_T -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID wlanSubModRunInit(P_GLUE_INFO_T prGlueInfo) -+{ -+ /*now, we only have p2p module */ -+ if (rSubModHandler[P2P_MODULE].fgIsInited == FALSE) { -+ rSubModHandler[P2P_MODULE].subModInit(prGlueInfo); -+ rSubModHandler[P2P_MODULE].fgIsInited = TRUE; -+ } -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief called by txthread, run sub module exit function -+* -+* \param[in] prGlueInfo Pointer to struct GLUE_INFO_T -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID wlanSubModRunExit(P_GLUE_INFO_T prGlueInfo) -+{ -+ /*now, we only have p2p module */ -+ if (rSubModHandler[P2P_MODULE].fgIsInited == TRUE) { -+ rSubModHandler[P2P_MODULE].subModExit(prGlueInfo); -+ rSubModHandler[P2P_MODULE].fgIsInited = FALSE; -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief set sub module init flag, force TxThread to run sub modle init -+* -+* \param[in] prGlueInfo Pointer to struct GLUE_INFO_T -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN wlanSubModInit(P_GLUE_INFO_T prGlueInfo) -+{ -+ /* 4 Mark HALT, notify main thread to finish current job */ -+ prGlueInfo->ulFlag |= GLUE_FLAG_SUB_MOD_INIT; -+ /* wake up main thread */ -+ wake_up_interruptible(&prGlueInfo->waitq); -+ /* wait main thread finish sub module INIT */ -+ wait_for_completion_interruptible(&prGlueInfo->rSubModComp); -+ -+#if 0 -+ if (prGlueInfo->prAdapter->fgIsP2PRegistered) -+ p2pNetRegister(prGlueInfo); -+#endif -+ -+ return TRUE; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief set sub module exit flag, force TxThread to run sub modle exit -+* -+* \param[in] prGlueInfo Pointer to struct GLUE_INFO_T -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN wlanSubModExit(P_GLUE_INFO_T prGlueInfo) -+{ -+#if 0 -+ if (prGlueInfo->prAdapter->fgIsP2PRegistered) -+ p2pNetUnregister(prGlueInfo); -+#endif -+ -+ /* 4 Mark HALT, notify main thread to finish current job */ -+ prGlueInfo->ulFlag |= GLUE_FLAG_SUB_MOD_EXIT; -+ /* wake up main thread */ -+ wake_up_interruptible(&prGlueInfo->waitq); -+ /* wait main thread finish sub module EXIT */ -+ wait_for_completion_interruptible(&prGlueInfo->rSubModComp); -+ -+ return TRUE; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief set by sub module, indicate sub module is already inserted -+* -+* \param[in] rSubModInit, function pointer point to sub module init function -+* \param[in] rSubModExit, function pointer point to sub module exit function -+* \param[in] eSubModIdx, sub module index -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+wlanSubModRegisterInitExit(SUB_MODULE_INIT rSubModInit, SUB_MODULE_EXIT rSubModExit, ENUM_SUB_MODULE_IDX_T eSubModIdx) -+{ -+ rSubModHandler[eSubModIdx].subModInit = rSubModInit; -+ rSubModHandler[eSubModIdx].subModExit = rSubModExit; -+ rSubModHandler[eSubModIdx].fgIsInited = FALSE; -+} -+ -+#if 0 -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief check wlan is launched or not -+* -+* \param[in] (none) -+* -+* \return TRUE, wlan is already started -+* FALSE, wlan is not started yet -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN wlanIsLaunched(VOID) -+{ -+ struct net_device *prDev = NULL; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ -+ /* 4 <0> Sanity check */ -+ ASSERT(u4WlanDevNum <= CFG_MAX_WLAN_DEVICES); -+ if (0 == u4WlanDevNum) -+ return FALSE; -+ -+ prDev = arWlanDevInfo[u4WlanDevNum - 1].prDev; -+ -+ ASSERT(prDev); -+ if (NULL == prDev) -+ return FALSE; -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ ASSERT(prGlueInfo); -+ if (NULL == prGlueInfo) -+ return FALSE; -+ -+ return prGlueInfo->prAdapter->fgIsWlanLaunched; -+} -+ -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Export wlan GLUE_INFO_T pointer to p2p module -+* -+* \param[in] prGlueInfo Pointer to struct GLUE_INFO_T -+* -+* \return TRUE: get GlueInfo pointer successfully -+* FALSE: wlan is not started yet -+*/ -+/*---------------------------------------------------------------------------*/ -+BOOLEAN wlanExportGlueInfo(P_GLUE_INFO_T *prGlueInfoExpAddr) -+{ -+ struct net_device *prDev = NULL; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ -+ if (0 == u4WlanDevNum) -+ return FALSE; -+ -+ prDev = arWlanDevInfo[u4WlanDevNum - 1].prDev; -+ if (NULL == prDev) -+ return FALSE; -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ if (NULL == prGlueInfo) -+ return FALSE; -+ -+ if (FALSE == prGlueInfo->prAdapter->fgIsWlanLaunched) -+ return FALSE; -+ -+ *prGlueInfoExpAddr = prGlueInfo; -+ return TRUE; -+} -+ -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Release prDev from wlandev_array and free tasklet object related to it. -+* -+* \param[in] prDev Pointer to struct net_device -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+static void wlanClearDevIdx(struct net_device *prDev) -+{ -+ int i; -+ -+ ASSERT(prDev); -+ -+ for (i = 0; i < CFG_MAX_WLAN_DEVICES; i++) { -+ if (arWlanDevInfo[i].prDev == prDev) { -+ arWlanDevInfo[i].prDev = NULL; -+ u4WlanDevNum--; -+ } -+ } -+ -+} /* end of wlanClearDevIdx() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Allocate an unique interface index, net_device::ifindex member for this -+* wlan device. Store the net_device in wlandev_array, and initialize -+* tasklet object related to it. -+* -+* \param[in] prDev Pointer to struct net_device -+* -+* \retval >= 0 The device number. -+* \retval -1 Fail to get index. -+*/ -+/*----------------------------------------------------------------------------*/ -+static int wlanGetDevIdx(struct net_device *prDev) -+{ -+ int i; -+ -+ ASSERT(prDev); -+ -+ for (i = 0; i < CFG_MAX_WLAN_DEVICES; i++) { -+ if (arWlanDevInfo[i].prDev == (struct net_device *)NULL) { -+ /* Reserve 2 bytes space to store one digit of -+ * device number and NULL terminator. -+ */ -+ arWlanDevInfo[i].prDev = prDev; -+ u4WlanDevNum++; -+ return i; -+ } -+ } -+ -+ return -1; -+} /* end of wlanGetDevIdx() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief A method of struct net_device, a primary SOCKET interface to configure -+* the interface lively. Handle an ioctl call on one of our devices. -+* Everything Linux ioctl specific is done here. Then we pass the contents -+* of the ifr->data to the request message handler. -+* -+* \param[in] prDev Linux kernel netdevice -+* -+* \param[in] prIfReq Our private ioctl request structure, typed for the generic -+* struct ifreq so we can use ptr to function -+* -+* \param[in] cmd Command ID -+* -+* \retval 0 The IOCTL command is executed successfully. -+* \retval <0 The execution of IOCTL command is failed. -+*/ -+/*----------------------------------------------------------------------------*/ -+int wlanDoIOCTL(struct net_device *prDev, struct ifreq *prIfReq, int i4Cmd) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ int ret = 0; -+ -+ /* Verify input parameters for the following functions */ -+ ASSERT(prDev && prIfReq); -+ if (!prDev || !prIfReq) { -+ DBGLOG(INIT, ERROR, "Invalid input data\n"); -+ return -EINVAL; -+ } -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ if (!prGlueInfo) { -+ DBGLOG(INIT, ERROR, "prGlueInfo is NULL\n"); -+ return -EFAULT; -+ } -+ -+ if (prGlueInfo->u4ReadyFlag == 0) { -+ DBGLOG(INIT, ERROR, "Adapter is not ready\n"); -+ return -EINVAL; -+ } -+ -+ if ((i4Cmd >= SIOCIWFIRST) && (i4Cmd < SIOCIWFIRSTPRIV)) { -+ /* 0x8B00 ~ 0x8BDF, wireless extension region */ -+ ret = wext_support_ioctl(prDev, prIfReq, i4Cmd); -+ } else if ((i4Cmd >= SIOCIWFIRSTPRIV) && (i4Cmd < SIOCIWLASTPRIV)) { -+ /* 0x8BE0 ~ 0x8BFF, private ioctl region */ -+ ret = priv_support_ioctl(prDev, prIfReq, i4Cmd); -+ } else if (i4Cmd == SIOCDEVPRIVATE + 1) { -+ ret = priv_support_driver_cmd(prDev, prIfReq, i4Cmd); -+ } else { -+ DBGLOG(INIT, WARN, "Unexpected ioctl command: 0x%04x\n", i4Cmd); -+ ret = -EOPNOTSUPP; -+ } -+ -+ return ret; -+} /* end of wlanDoIOCTL() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is to set multicast list and set rx mode. -+* -+* \param[in] prDev Pointer to struct net_device -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+ -+static struct delayed_work workq; -+static struct net_device *gPrDev; -+static BOOLEAN fgIsWorkMcStart = FALSE; -+static BOOLEAN fgIsWorkMcEverInit = FALSE; -+static struct wireless_dev *gprWdev; -+ -+static void createWirelessDevice(void) -+{ -+ struct wiphy *prWiphy = NULL; -+ struct wireless_dev *prWdev = NULL; -+#if CFG_SUPPORT_PERSIST_NETDEV -+ struct net_device *prNetDev = NULL; -+#endif -+ -+ /* <1.1> Create wireless_dev */ -+ prWdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL); -+ if (!prWdev) { -+ DBGLOG(INIT, ERROR, "Allocating memory to wireless_dev context failed\n"); -+ return; -+ } -+ -+ -+ /* <1.2> Create wiphy */ -+ prWiphy = wiphy_new(&mtk_wlan_ops, sizeof(GLUE_INFO_T)); -+ if (!prWiphy) { -+ DBGLOG(INIT, ERROR, "Allocating memory to wiphy device failed\n"); -+ goto free_wdev; -+ } -+ -+ /* <1.3> configure wireless_dev & wiphy */ -+ prWdev->iftype = NL80211_IFTYPE_STATION; -+ prWiphy->max_scan_ssids = 1; /* FIXME: for combo scan */ -+ prWiphy->max_scan_ie_len = 512; -+ -+ prWiphy->max_sched_scan_ssids = CFG_SCAN_SSID_MAX_NUM; -+ prWiphy->max_match_sets = CFG_SCAN_SSID_MATCH_MAX_NUM; -+ prWiphy->max_sched_scan_ie_len = CFG_CFG80211_IE_BUF_LEN; -+ prWiphy->max_sched_scan_reqs = 1; -+ -+ prWiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC); -+ prWiphy->bands[NL80211_BAND_2GHZ] = &mtk_band_2ghz; -+ /* always assign 5Ghz bands here, if the chip is not support 5Ghz, -+ bands[IEEE80211_BAND_5GHZ] will be assign to NULL */ -+ prWiphy->bands[NL80211_BAND_5GHZ] = &mtk_band_5ghz; -+ prWiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM; -+ prWiphy->cipher_suites = mtk_cipher_suites; -+ prWiphy->n_cipher_suites = ARRAY_SIZE(mtk_cipher_suites); -+ prWiphy->flags = WIPHY_FLAG_SUPPORTS_FW_ROAM -+ | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL; -+ prWiphy->regulatory_flags = REGULATORY_CUSTOM_REG; -+#if CFG_SUPPORT_TDLS -+ TDLSEX_WIPHY_FLAGS_INIT(prWiphy->flags); -+#endif /* CFG_SUPPORT_TDLS */ -+ prWiphy->max_remain_on_channel_duration = 5000; -+ prWiphy->mgmt_stypes = mtk_cfg80211_ais_default_mgmt_stypes; -+ prWiphy->vendor_commands = mtk_wlan_vendor_ops; -+ prWiphy->n_vendor_commands = sizeof(mtk_wlan_vendor_ops) / sizeof(struct wiphy_vendor_command); -+ prWiphy->vendor_events = mtk_wlan_vendor_events; -+ prWiphy->n_vendor_events = ARRAY_SIZE(mtk_wlan_vendor_events); -+ -+ /* <1.4> wowlan support */ -+#ifdef CONFIG_PM -+ prWiphy->wowlan = &mtk_wlan_wowlan_support; -+#endif -+#ifdef CONFIG_CFG80211_WEXT -+ /* <1.5> Use wireless extension to replace IOCTL */ -+ prWiphy->wext = &wext_handler_def; -+#endif -+ -+ if (wiphy_register(prWiphy) < 0) { -+ DBGLOG(INIT, ERROR, "wiphy_register error\n"); -+ goto free_wiphy; -+ } -+ prWdev->wiphy = prWiphy; -+ -+#if CFG_SUPPORT_PERSIST_NETDEV -+ /* <2> allocate and register net_device */ -+#if CFG_TC1_FEATURE -+ if (wlan_if_changed) -+ prNetDev = alloc_netdev_mq(sizeof(P_GLUE_INFO_T), NIC_INF_NAME_IN_AP_MODE, NET_NAME_PREDICTABLE, -+ ether_setup, CFG_MAX_TXQ_NUM); -+ else -+#else -+ prNetDev = alloc_netdev_mq(sizeof(P_GLUE_INFO_T), NIC_INF_NAME, NET_NAME_PREDICTABLE, -+ ether_setup, CFG_MAX_TXQ_NUM); -+#endif -+ if (!prNetDev) { -+ DBGLOG(INIT, ERROR, "Allocating memory to net_device context failed\n"); -+ goto unregister_wiphy; -+ } -+ -+ *((P_GLUE_INFO_T *) netdev_priv(prNetDev)) = (P_GLUE_INFO_T) wiphy_priv(prWiphy); -+ -+ prNetDev->netdev_ops = &wlan_netdev_ops; -+#ifdef CONFIG_WIRELESS_EXT -+ prNetDev->wireless_handlers = &wext_handler_def; -+#endif -+ netif_carrier_off(prNetDev); -+ netif_tx_stop_all_queues(prNetDev); -+ -+ /* <2.1> co-relate with wireless_dev bi-directionally */ -+ prNetDev->ieee80211_ptr = prWdev; -+ prWdev->netdev = prNetDev; -+#if CFG_TCP_IP_CHKSUM_OFFLOAD -+ prNetDev->features = NETIF_F_HW_CSUM; -+#endif -+ -+ /* <2.2> co-relate net device & device tree */ -+ SET_NETDEV_DEV(prNetDev, wiphy_dev(prWiphy)); -+ -+ /* <2.3> register net_device */ -+ if (register_netdev(prWdev->netdev) < 0) { -+ DBGLOG(INIT, ERROR, "wlanNetRegister: net_device context is not registered.\n"); -+ goto unregister_wiphy; -+ } -+#endif /* CFG_SUPPORT_PERSIST_NETDEV */ -+ gprWdev = prWdev; -+ DBGLOG(INIT, INFO, "create wireless device success\n"); -+ return; -+ -+#if CFG_SUPPORT_PERSIST_NETDEV -+unregister_wiphy: -+ wiphy_unregister(prWiphy); -+#endif -+free_wiphy: -+ wiphy_free(prWiphy); -+free_wdev: -+ kfree(prWdev); -+} -+ -+static void destroyWirelessDevice(void) -+{ -+#if CFG_SUPPORT_PERSIST_NETDEV -+ unregister_netdev(gprWdev->netdev); -+ free_netdev(gprWdev->netdev); -+#endif -+ wiphy_unregister(gprWdev->wiphy); -+ wiphy_free(gprWdev->wiphy); -+ kfree(gprWdev); -+ gprWdev = NULL; -+} -+ -+static void wlanSetMulticastList(struct net_device *prDev) -+{ -+ gPrDev = prDev; -+ schedule_delayed_work(&workq, 0); -+} -+ -+/* FIXME: Since we cannot sleep in the wlanSetMulticastList, we arrange -+ * another workqueue for sleeping. We don't want to block -+ * tx_thread, so we can't let tx_thread to do this */ -+ -+static void wlanSetMulticastListWorkQueue(struct work_struct *work) -+{ -+ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ UINT_32 u4PacketFilter = 0; -+ UINT_32 u4SetInfoLen; -+ struct net_device *prDev = gPrDev; -+ -+ fgIsWorkMcStart = TRUE; -+ -+ if (kalHaltLock(KAL_HALT_LOCK_TIMEOUT_NORMAL_CASE)) -+ return; -+ if (kalIsHalted()) { -+ fgIsWorkMcStart = FALSE; -+ kalHaltUnlock(); -+ return; -+ } -+ -+ prGlueInfo = (NULL != prDev) ? *((P_GLUE_INFO_T *) netdev_priv(prDev)) : NULL; -+ ASSERT(prDev); -+ ASSERT(prGlueInfo); -+ if (!prDev || !prGlueInfo) { -+ DBGLOG(INIT, WARN, "abnormal dev or skb: prDev(0x%p), prGlueInfo(0x%p)\n", prDev, prGlueInfo); -+ fgIsWorkMcStart = FALSE; -+ kalHaltUnlock(); -+ return; -+ } -+ -+ if (prDev->flags & IFF_PROMISC) -+ u4PacketFilter |= PARAM_PACKET_FILTER_PROMISCUOUS; -+ -+ if (prDev->flags & IFF_BROADCAST) -+ u4PacketFilter |= PARAM_PACKET_FILTER_BROADCAST; -+ -+ if (prDev->flags & IFF_MULTICAST) { -+ if ((prDev->flags & IFF_ALLMULTI) || -+ (netdev_mc_count(prDev) > MAX_NUM_GROUP_ADDR)) { -+ -+ u4PacketFilter |= PARAM_PACKET_FILTER_ALL_MULTICAST; -+ } else { -+ u4PacketFilter |= PARAM_PACKET_FILTER_MULTICAST; -+ } -+ } -+ -+ kalHaltUnlock(); -+ -+ if (kalIoctl(prGlueInfo, -+ wlanoidSetCurrentPacketFilter, -+ &u4PacketFilter, -+ sizeof(u4PacketFilter), FALSE, FALSE, TRUE, FALSE, &u4SetInfoLen) != WLAN_STATUS_SUCCESS) { -+ fgIsWorkMcStart = FALSE; -+ DBGLOG(INIT, ERROR, "wlanSetMulticastListWorkQueue kalIoctl u4PacketFilter=%d\n", u4PacketFilter); -+ return; -+ } -+ -+ if (u4PacketFilter & PARAM_PACKET_FILTER_MULTICAST) { -+ /* Prepare multicast address list */ -+ struct netdev_hw_addr *ha; -+ PUINT_8 prMCAddrList = NULL; -+ UINT_32 i = 0; -+ -+ if (kalHaltLock(KAL_HALT_LOCK_TIMEOUT_NORMAL_CASE)) -+ return; -+ if (kalIsHalted()) { -+ fgIsWorkMcStart = FALSE; -+ kalHaltUnlock(); -+ /*DBGLOG(INIT, WARN, "wlanSetMulticastListWorkQueue g_u4HaltFlag=%d\n", g_u4HaltFlag);*/ -+ return; -+ } -+ -+ prMCAddrList = kalMemAlloc(MAX_NUM_GROUP_ADDR * ETH_ALEN, VIR_MEM_TYPE); -+ -+ netdev_for_each_mc_addr(ha, prDev) { -+ if (i < MAX_NUM_GROUP_ADDR) { -+ memcpy((prMCAddrList + i * ETH_ALEN), ha->addr, ETH_ALEN); -+ i++; -+ } -+ } -+ -+ kalHaltUnlock(); -+ -+ kalIoctl(prGlueInfo, -+ wlanoidSetMulticastList, -+ prMCAddrList, (i * ETH_ALEN), FALSE, FALSE, TRUE, FALSE, &u4SetInfoLen); -+ -+ kalMemFree(prMCAddrList, VIR_MEM_TYPE, MAX_NUM_GROUP_ADDR * ETH_ALEN); -+ } -+ -+ fgIsWorkMcStart = FALSE; -+ -+} /* end of wlanSetMulticastList() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief To indicate scheduled scan has been stopped -+* -+* \param[in] -+* prGlueInfo -+* -+* \return -+* None -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID wlanSchedScanStoppedWorkQueue(struct work_struct *work) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ struct net_device *prDev = gPrDev; -+ -+ prGlueInfo = (NULL != prDev) ? *((P_GLUE_INFO_T *) netdev_priv(prDev)) : NULL; -+ if (!prGlueInfo) { -+ DBGLOG(SCN, ERROR, "prGlueInfo == NULL unexpected\n"); -+ return; -+ } -+ -+ /* 2. indication to cfg80211 */ -+ /* 20150205 change cfg80211_sched_scan_stopped to work queue due to sched_scan_mtx dead lock issue */ -+ cfg80211_sched_scan_stopped(priv_to_wiphy(prGlueInfo),0); -+ DBGLOG(SCN, INFO, -+ "cfg80211_sched_scan_stopped event send done\n"); -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is TX entry point of NET DEVICE. -+* -+* \param[in] prSkb Pointer of the sk_buff to be sent -+* \param[in] prDev Pointer to struct net_device -+* -+* \retval NETDEV_TX_OK - on success. -+* \retval NETDEV_TX_BUSY - on failure, packet will be discarded by upper layer. -+*/ -+/*----------------------------------------------------------------------------*/ -+int wlanHardStartXmit(struct sk_buff *prSkb, struct net_device *prDev) -+{ -+ P_GLUE_INFO_T prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ -+ P_QUE_ENTRY_T prQueueEntry = NULL; -+ P_QUE_T prTxQueue = NULL; -+ UINT_16 u2QueueIdx = 0; -+#if (CFG_SUPPORT_TDLS_DBG == 1) -+ UINT16 u2Identifier = 0; -+#endif -+ -+#if CFG_BOW_TEST -+ UINT_32 i; -+#endif -+ -+ GLUE_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(prSkb); -+ ASSERT(prDev); -+ ASSERT(prGlueInfo); -+ prGlueInfo->u8SkbToDriver++; -+ -+#if (CFG_SUPPORT_TDLS_DBG == 1) -+ { -+ UINT8 *pkt = prSkb->data; -+ -+ if ((*(pkt + 12) == 0x08) && (*(pkt + 13) == 0x00)) { -+ /* ip */ -+ u2Identifier = ((*(pkt + 18)) << 8) | (*(pkt + 19)); -+ /* u2TdlsTxSeq[u4TdlsTxSeqId ++] = u2Identifier; */ -+ DBGLOG(INIT, INFO, " %d\n", u2Identifier); -+ } -+ } -+#endif -+ /* check if WiFi is halt */ -+ if (prGlueInfo->ulFlag & GLUE_FLAG_HALT) { -+ DBGLOG(INIT, INFO, "GLUE_FLAG_HALT skip tx\n"); -+ dev_kfree_skb(prSkb); -+ prGlueInfo->u8SkbFreed++; -+ return NETDEV_TX_OK; -+ } -+#if CFG_SUPPORT_HOTSPOT_2_0 -+ if (prGlueInfo->fgIsDad) { -+ /* kalPrint("[Passpoint R2] Due to ipv4_dad...TX is forbidden\n"); */ -+ dev_kfree_skb(prSkb); -+ prGlueInfo->u8SkbFreed++; -+ return NETDEV_TX_OK; -+ } -+ if (prGlueInfo->fgIs6Dad) { -+ /* kalPrint("[Passpoint R2] Due to ipv6_dad...TX is forbidden\n"); */ -+ dev_kfree_skb(prSkb); -+ prGlueInfo->u8SkbFreed++; -+ return NETDEV_TX_OK; -+ } -+#endif -+ -+ STATS_TX_TIME_ARRIVE(prSkb); -+ prQueueEntry = (P_QUE_ENTRY_T) GLUE_GET_PKT_QUEUE_ENTRY(prSkb); -+ prTxQueue = &prGlueInfo->rTxQueue; -+ -+#if CFG_BOW_TEST -+ DBGLOG(BOW, TRACE, "sk_buff->len: %d\n", prSkb->len); -+ DBGLOG(BOW, TRACE, "sk_buff->data_len: %d\n", prSkb->data_len); -+ DBGLOG(BOW, TRACE, "sk_buff->data:\n"); -+ -+ for (i = 0; i < prSkb->len; i++) { -+ DBGLOG(BOW, TRACE, "%4x", prSkb->data[i]); -+ -+ if ((i + 1) % 16 == 0) -+ DBGLOG(BOW, TRACE, "\n"); -+ } -+ -+ DBGLOG(BOW, TRACE, "\n"); -+#endif -+ -+ if (wlanProcessSecurityFrame(prGlueInfo->prAdapter, (P_NATIVE_PACKET) prSkb) == FALSE) { -+ -+ /* non-1x packets */ -+ -+#if CFG_DBG_GPIO_PINS -+ { -+ /* TX request from OS */ -+ mtk_wcn_stp_debug_gpio_assert(IDX_TX_REQ, DBG_TIE_LOW); -+ kalUdelay(1); -+ mtk_wcn_stp_debug_gpio_assert(IDX_TX_REQ, DBG_TIE_HIGH); -+ } -+#endif -+ -+ u2QueueIdx = skb_get_queue_mapping(prSkb); -+ ASSERT(u2QueueIdx < CFG_MAX_TXQ_NUM); -+ -+#if CFG_ENABLE_PKT_LIFETIME_PROFILE -+ GLUE_SET_PKT_ARRIVAL_TIME(prSkb, kalGetTimeTick()); -+#endif -+ GLUE_INC_REF_CNT(prGlueInfo->i4TxPendingFrameNum); -+ if (u2QueueIdx < CFG_MAX_TXQ_NUM) -+ GLUE_INC_REF_CNT(prGlueInfo->ai4TxPendingFrameNumPerQueue[NETWORK_TYPE_AIS_INDEX][u2QueueIdx]); -+ -+ GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_TX_QUE); -+ QUEUE_INSERT_TAIL(prTxQueue, prQueueEntry); -+ GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_TX_QUE); -+/* GLUE_INC_REF_CNT(prGlueInfo->i4TxPendingFrameNum); */ -+/* GLUE_INC_REF_CNT(prGlueInfo->ai4TxPendingFrameNumPerQueue[NETWORK_TYPE_AIS_INDEX][u2QueueIdx]); */ -+ -+ if (u2QueueIdx < CFG_MAX_TXQ_NUM) { -+ if (prGlueInfo->ai4TxPendingFrameNumPerQueue[NETWORK_TYPE_AIS_INDEX][u2QueueIdx] >= -+ CFG_TX_STOP_NETIF_PER_QUEUE_THRESHOLD) { -+ DBGLOG(TX, INFO, "netif_stop_subqueue for wlan0, Queue len: %d\n", -+ prGlueInfo->ai4TxPendingFrameNumPerQueue[NETWORK_TYPE_AIS_INDEX][u2QueueIdx]); -+ -+ netif_stop_subqueue(prDev, u2QueueIdx); -+ -+#if (CONF_HIF_LOOPBACK_AUTO == 1) -+ prGlueInfo->rHifInfo.HifLoopbkFlg |= 0x01; -+#endif /* CONF_HIF_LOOPBACK_AUTO */ -+ } -+ } -+ } else { -+ /* printk("is security frame\n"); */ -+ -+ GLUE_INC_REF_CNT(prGlueInfo->i4TxPendingSecurityFrameNum); -+ } -+ -+ DBGLOG(TX, EVENT, "\n+++++ pending frame %d len = %d +++++\n", prGlueInfo->i4TxPendingFrameNum, prSkb->len); -+ prGlueInfo->rNetDevStats.tx_bytes += prSkb->len; -+ prGlueInfo->rNetDevStats.tx_packets++; -+ kalPerMonStart(prGlueInfo); -+ -+ /* set GLUE_FLAG_TXREQ_BIT */ -+ -+ /* pr->u4Flag |= GLUE_FLAG_TXREQ; */ -+ /* wake_up_interruptible(&prGlueInfo->waitq); */ -+ kalSetEvent(prGlueInfo); -+ -+ /* For Linux, we'll always return OK FLAG, because we'll free this skb by ourself */ -+ return NETDEV_TX_OK; -+} /* end of wlanHardStartXmit() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief A method of struct net_device, to get the network interface statistical -+* information. -+* -+* Whenever an application needs to get statistics for the interface, this method -+* is called. This happens, for example, when ifconfig or netstat -i is run. -+* -+* \param[in] prDev Pointer to struct net_device. -+* -+* \return net_device_stats buffer pointer. -+*/ -+/*----------------------------------------------------------------------------*/ -+struct net_device_stats *wlanGetStats(IN struct net_device *prDev) -+{ -+ P_GLUE_INFO_T prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ -+#if 0 -+ WLAN_STATUS rStatus; -+ UINT_32 u4XmitError = 0; -+ UINT_32 u4XmitOk = 0; -+ UINT_32 u4RecvError = 0; -+ UINT_32 u4RecvOk = 0; -+ UINT_32 u4BufLen; -+ -+ ASSERT(prDev); -+ -+ /* @FIX ME: need a more clear way to do this */ -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidQueryXmitError, &u4XmitError, sizeof(UINT_32), TRUE, TRUE, TRUE, &u4BufLen); -+ -+ rStatus = kalIoctl(prGlueInfo, wlanoidQueryXmitOk, &u4XmitOk, sizeof(UINT_32), TRUE, TRUE, TRUE, &u4BufLen); -+ rStatus = kalIoctl(prGlueInfo, wlanoidQueryRcvOk, &u4RecvOk, sizeof(UINT_32), TRUE, TRUE, TRUE, &u4BufLen); -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidQueryRcvError, &u4RecvError, sizeof(UINT_32), TRUE, TRUE, TRUE, &u4BufLen); -+ prGlueInfo->rNetDevStats.rx_packets = u4RecvOk; -+ prGlueInfo->rNetDevStats.tx_packets = u4XmitOk; -+ prGlueInfo->rNetDevStats.tx_errors = u4XmitError; -+ prGlueInfo->rNetDevStats.rx_errors = u4RecvError; -+ /* prGlueInfo->rNetDevStats.rx_bytes = rCustomNetDevStats.u4RxBytes; */ -+ /* prGlueInfo->rNetDevStats.tx_bytes = rCustomNetDevStats.u4TxBytes; */ -+ /* prGlueInfo->rNetDevStats.rx_errors = rCustomNetDevStats.u4RxErrors; */ -+ /* prGlueInfo->rNetDevStats.multicast = rCustomNetDevStats.u4Multicast; */ -+#endif -+ /* prGlueInfo->rNetDevStats.rx_packets = 0; */ -+ /* prGlueInfo->rNetDevStats.tx_packets = 0; */ -+ prGlueInfo->rNetDevStats.tx_errors = 0; -+ prGlueInfo->rNetDevStats.rx_errors = 0; -+ /* prGlueInfo->rNetDevStats.rx_bytes = 0; */ -+ /* prGlueInfo->rNetDevStats.tx_bytes = 0; */ -+ prGlueInfo->rNetDevStats.rx_errors = 0; -+ prGlueInfo->rNetDevStats.multicast = 0; -+ -+ return &prGlueInfo->rNetDevStats; -+ -+} /* end of wlanGetStats() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief A function for prDev->init -+* -+* \param[in] prDev Pointer to struct net_device. -+* -+* \retval 0 The execution of wlanInit succeeds. -+* \retval -ENXIO No such device. -+*/ -+/*----------------------------------------------------------------------------*/ -+static int wlanInit(struct net_device *prDev) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ -+ if (fgIsWorkMcEverInit == FALSE) { -+ if (!prDev) -+ return -ENXIO; -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ INIT_DELAYED_WORK(&workq, wlanSetMulticastListWorkQueue); -+ -+ /* 20150205 work queue for sched_scan */ -+ INIT_DELAYED_WORK(&sched_workq, wlanSchedScanStoppedWorkQueue); -+ -+ fgIsWorkMcEverInit = TRUE; -+ } -+ -+ return 0; /* success */ -+} /* end of wlanInit() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief A function for prDev->uninit -+* -+* \param[in] prDev Pointer to struct net_device. -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+static void wlanUninit(struct net_device *prDev) -+{ -+ -+} /* end of wlanUninit() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief A function for prDev->open -+* -+* \param[in] prDev Pointer to struct net_device. -+* -+* \retval 0 The execution of wlanOpen succeeds. -+* \retval < 0 The execution of wlanOpen failed. -+*/ -+/*----------------------------------------------------------------------------*/ -+static int wlanOpen(struct net_device *prDev) -+{ -+ ASSERT(prDev); -+ -+ netif_tx_start_all_queues(prDev); -+ -+ return 0; /* success */ -+} /* end of wlanOpen() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief A function for prDev->stop -+* -+* \param[in] prDev Pointer to struct net_device. -+* -+* \retval 0 The execution of wlanStop succeeds. -+* \retval < 0 The execution of wlanStop failed. -+*/ -+/*----------------------------------------------------------------------------*/ -+static int wlanStop(struct net_device *prDev) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ struct cfg80211_scan_request *prScanRequest = NULL; -+ -+ struct cfg80211_scan_info info = { -+ .aborted = true, -+ }; -+ -+ GLUE_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(prDev); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ -+ /* CFG80211 down */ -+ GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV); -+ if (prGlueInfo->prScanRequest != NULL) { -+ prScanRequest = prGlueInfo->prScanRequest; -+ prGlueInfo->prScanRequest = NULL; -+ } -+ GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV); -+ -+ if (prScanRequest) -+ cfg80211_scan_done(prScanRequest, &info); -+ netif_tx_stop_all_queues(prDev); -+ -+ return 0; /* success */ -+} /* end of wlanStop() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * \brief Update channel table for cfg80211 based on current country domain -+ * -+ * \param[in] prGlueInfo Pointer to glue info -+ * -+ * \return none -+ */ -+/*----------------------------------------------------------------------------*/ -+VOID wlanUpdateChannelTable(P_GLUE_INFO_T prGlueInfo) -+{ -+ UINT_8 i, j; -+ UINT_8 ucNumOfChannel; -+ RF_CHANNEL_INFO_T aucChannelList[ARRAY_SIZE(mtk_2ghz_channels) + ARRAY_SIZE(mtk_5ghz_channels)]; -+ -+ /* 1. Disable all channels */ -+ for (i = 0; i < ARRAY_SIZE(mtk_2ghz_channels); i++) { -+ mtk_2ghz_channels[i].flags |= IEEE80211_CHAN_DISABLED; -+ mtk_2ghz_channels[i].orig_flags |= IEEE80211_CHAN_DISABLED; -+ } -+ -+ for (i = 0; i < ARRAY_SIZE(mtk_5ghz_channels); i++) { -+ mtk_5ghz_channels[i].flags |= IEEE80211_CHAN_DISABLED; -+ mtk_5ghz_channels[i].orig_flags |= IEEE80211_CHAN_DISABLED; -+ } -+ -+ /* 2. Get current domain channel list */ -+ rlmDomainGetChnlList(prGlueInfo->prAdapter, -+ BAND_NULL, FALSE, -+ ARRAY_SIZE(mtk_2ghz_channels) + ARRAY_SIZE(mtk_5ghz_channels), -+ &ucNumOfChannel, aucChannelList); -+ -+ /* 3. Enable specific channel based on domain channel list */ -+ for (i = 0; i < ucNumOfChannel; i++) { -+ switch (aucChannelList[i].eBand) { -+ case BAND_2G4: -+ for (j = 0; j < ARRAY_SIZE(mtk_2ghz_channels); j++) { -+ if (mtk_2ghz_channels[j].hw_value == aucChannelList[i].ucChannelNum) { -+ mtk_2ghz_channels[j].flags &= ~IEEE80211_CHAN_DISABLED; -+ mtk_2ghz_channels[j].orig_flags &= ~IEEE80211_CHAN_DISABLED; -+ break; -+ } -+ } -+ break; -+ -+ case BAND_5G: -+ for (j = 0; j < ARRAY_SIZE(mtk_5ghz_channels); j++) { -+ if (mtk_5ghz_channels[j].hw_value == aucChannelList[i].ucChannelNum) { -+ mtk_5ghz_channels[j].flags &= ~IEEE80211_CHAN_DISABLED; -+ mtk_5ghz_channels[j].orig_flags &= ~IEEE80211_CHAN_DISABLED; -+ break; -+ } -+ } -+ break; -+ -+ default: -+ DBGLOG(INIT, WARN, "Unknown band %d\n", aucChannelList[i].eBand); -+ break; -+ } -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Register the device to the kernel and return the index. -+* -+* \param[in] prDev Pointer to struct net_device. -+* -+* \retval 0 The execution of wlanNetRegister succeeds. -+* \retval < 0 The execution of wlanNetRegister failed. -+*/ -+/*----------------------------------------------------------------------------*/ -+static INT_32 wlanNetRegister(struct wireless_dev *prWdev) -+{ -+ P_GLUE_INFO_T prGlueInfo; -+ INT_32 i4DevIdx = -1; -+ -+ ASSERT(prWdev); -+ -+ do { -+ if (!prWdev) -+ break; -+ -+ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(prWdev->wiphy); -+ i4DevIdx = wlanGetDevIdx(prWdev->netdev); -+ if (i4DevIdx < 0) { -+ DBGLOG(INIT, ERROR, "wlanNetRegister: net_device number exceeds.\n"); -+ break; -+ } -+ -+#if !CFG_SUPPORT_PERSIST_NETDEV -+ if (register_netdev(prWdev->netdev) < 0) { -+ DBGLOG(INIT, ERROR, "wlanNetRegister: net_device context is not registered.\n"); -+ -+ wiphy_unregister(prWdev->wiphy); -+ wlanClearDevIdx(prWdev->netdev); -+ i4DevIdx = -1; -+ } -+#endif -+ if (i4DevIdx != -1) -+ prGlueInfo->fgIsRegistered = TRUE; -+ -+ } while (FALSE); -+ -+ return i4DevIdx; /* success */ -+} /* end of wlanNetRegister() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Unregister the device from the kernel -+* -+* \param[in] prWdev Pointer to struct net_device. -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+static VOID wlanNetUnregister(struct wireless_dev *prWdev) -+{ -+ P_GLUE_INFO_T prGlueInfo; -+ -+ if (!prWdev) { -+ DBGLOG(INIT, ERROR, "wlanNetUnregister: The device context is NULL\n"); -+ return; -+ } -+ DBGLOG(INIT, TRACE, "unregister net_dev(0x%p)\n", prWdev->netdev); -+ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(prWdev->wiphy); -+ wlanClearDevIdx(prWdev->netdev); -+#if !CFG_SUPPORT_PERSIST_NETDEV -+ unregister_netdev(prWdev->netdev); -+#endif -+ prGlueInfo->fgIsRegistered = FALSE; -+ -+ DBGLOG(INIT, INFO, "unregister wireless_dev(0x%p), ifindex=%d\n", prWdev, prWdev->netdev->ifindex); -+ -+} /* end of wlanNetUnregister() */ -+ -+static const struct net_device_ops wlan_netdev_ops = { -+ .ndo_open = wlanOpen, -+ .ndo_stop = wlanStop, -+ .ndo_set_rx_mode = wlanSetMulticastList, -+ .ndo_get_stats = wlanGetStats, -+ .ndo_do_ioctl = wlanDoIOCTL, -+ .ndo_start_xmit = wlanHardStartXmit, -+ .ndo_init = wlanInit, -+ .ndo_uninit = wlanUninit, -+ .ndo_select_queue = wlanSelectQueue, -+}; -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief A method for creating Linux NET4 struct net_device object and the -+* private data(prGlueInfo and prAdapter). Setup the IO address to the HIF. -+* Assign the function pointer to the net_device object -+* -+* \param[in] pvData Memory address for the device -+* -+* \retval Not null The wireless_dev object. -+* \retval NULL Fail to create wireless_dev object -+*/ -+/*----------------------------------------------------------------------------*/ -+static struct lock_class_key rSpinKey[SPIN_LOCK_NUM]; -+static struct wireless_dev *wlanNetCreate(PVOID pvData) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ struct wireless_dev *prWdev = gprWdev; -+ UINT_32 i; -+ struct device *prDev; -+ -+ if (!prWdev) { -+ DBGLOG(INIT, ERROR, "Allocating memory to wireless_dev context failed\n"); -+ return NULL; -+ } -+ /* 4 <1> co-relate wiphy & prDev */ -+#if MTK_WCN_HIF_SDIO -+ mtk_wcn_hif_sdio_get_dev(*((MTK_WCN_HIF_SDIO_CLTCTX *) pvData), &prDev); -+#else -+/* prDev = &((struct sdio_func *) pvData)->dev; //samp */ -+ prDev = pvData; /* samp */ -+#endif -+ if (!prDev) -+ DBGLOG(INIT, WARN, "unable to get struct dev for wlan\n"); -+ /* don't set prDev as parent of wiphy->dev, because we have done device_add -+ in driver init. if we set parent here, parent will be not able to know this child, -+ and may occurs a KE in device_shutdown, to free wiphy->dev, because his parent -+ has been freed. */ -+ /*set_wiphy_dev(prWdev->wiphy, prDev);*/ -+ -+#if !CFG_SUPPORT_PERSIST_NETDEV -+ /* 4 <3> Initial Glue structure */ -+ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(prWdev->wiphy); -+ kalMemZero(prGlueInfo, sizeof(GLUE_INFO_T)); -+ /* 4 <3.1> Create net device */ -+#if CFG_TC1_FEATURE -+ if (wlan_if_changed) { -+ prGlueInfo->prDevHandler = alloc_netdev_mq(sizeof(P_GLUE_INFO_T), NIC_INF_NAME_IN_AP_MODE, -+ NET_NAME_PREDICTABLE, ether_setup, CFG_MAX_TXQ_NUM); -+ } else { -+ prGlueInfo->prDevHandler = alloc_netdev_mq(sizeof(P_GLUE_INFO_T), NIC_INF_NAME, NET_NAME_PREDICTABLE, -+ ether_setup, CFG_MAX_TXQ_NUM); -+ } -+#else -+ prGlueInfo->prDevHandler = alloc_netdev_mq(sizeof(P_GLUE_INFO_T), NIC_INF_NAME, NET_NAME_PREDICTABLE, -+ ether_setup, CFG_MAX_TXQ_NUM); -+#endif -+ if (!prGlueInfo->prDevHandler) { -+ DBGLOG(INIT, ERROR, "Allocating memory to net_device context failed\n"); -+ return NULL; -+ } -+ DBGLOG(INIT, INFO, "net_device prDev(0x%p) allocated ifindex=%d\n", -+ prGlueInfo->prDevHandler, prGlueInfo->prDevHandler->ifindex); -+ -+ /* 4 <3.1.1> initialize net device varaiables */ -+ *((P_GLUE_INFO_T *) netdev_priv(prGlueInfo->prDevHandler)) = prGlueInfo; -+ -+ prGlueInfo->prDevHandler->netdev_ops = &wlan_netdev_ops; -+#ifdef CONFIG_WIRELESS_EXT -+ prGlueInfo->prDevHandler->wireless_handlers = &wext_handler_def; -+#endif -+ netif_carrier_off(prGlueInfo->prDevHandler); -+ netif_tx_stop_all_queues(prGlueInfo->prDevHandler); -+ -+ /* 4 <3.1.2> co-relate with wiphy bi-directionally */ -+ prGlueInfo->prDevHandler->ieee80211_ptr = prWdev; -+#if CFG_TCP_IP_CHKSUM_OFFLOAD -+ prGlueInfo->prDevHandler->features = NETIF_F_HW_CSUM; -+#endif -+ prWdev->netdev = prGlueInfo->prDevHandler; -+ -+ /* 4 <3.1.3> co-relate net device & prDev */ -+ /*SET_NETDEV_DEV(prGlueInfo->prDevHandler, wiphy_dev(prWdev->wiphy));*/ -+ SET_NETDEV_DEV(prGlueInfo->prDevHandler, prDev); -+#else /* CFG_SUPPORT_PERSIST_NETDEV */ -+ prGlueInfo->prDevHandler = gprWdev->netdev; -+#endif /* CFG_SUPPORT_PERSIST_NETDEV */ -+ -+ /* 4 <3.2> initiali glue variables */ -+ prGlueInfo->eParamMediaStateIndicated = PARAM_MEDIA_STATE_DISCONNECTED; -+ prGlueInfo->ePowerState = ParamDeviceStateD0; -+ prGlueInfo->fgIsMacAddrOverride = FALSE; -+ prGlueInfo->fgIsRegistered = FALSE; -+ prGlueInfo->prScanRequest = NULL; -+ -+#if CFG_SUPPORT_HOTSPOT_2_0 -+ /* Init DAD */ -+ prGlueInfo->fgIsDad = FALSE; -+ prGlueInfo->fgIs6Dad = FALSE; -+ kalMemZero(prGlueInfo->aucDADipv4, 4); -+ kalMemZero(prGlueInfo->aucDADipv6, 16); -+#endif -+ -+ init_completion(&prGlueInfo->rScanComp); -+ init_completion(&prGlueInfo->rHaltComp); -+ init_completion(&prGlueInfo->rPendComp); -+#if CFG_ENABLE_WIFI_DIRECT -+ init_completion(&prGlueInfo->rSubModComp); -+#endif -+ -+ /* initialize timer for OID timeout checker */ -+ kalOsTimerInitialize(prGlueInfo, kalTimeoutHandler); -+ -+ for (i = 0; i < SPIN_LOCK_NUM; i++) { -+ spin_lock_init(&prGlueInfo->rSpinLock[i]); -+ lockdep_set_class(&prGlueInfo->rSpinLock[i], &rSpinKey[i]); -+ } -+ -+ /* initialize semaphore for ioctl */ -+ sema_init(&prGlueInfo->ioctl_sem, 1); -+ -+ glSetHifInfo(prGlueInfo, (ULONG) pvData); -+ -+ /* 4 <8> Init Queues */ -+ init_waitqueue_head(&prGlueInfo->waitq); -+ QUEUE_INITIALIZE(&prGlueInfo->rCmdQueue); -+ QUEUE_INITIALIZE(&prGlueInfo->rTxQueue); -+ -+ /* 4 <4> Create Adapter structure */ -+ prGlueInfo->prAdapter = (P_ADAPTER_T) wlanAdapterCreate(prGlueInfo); -+ -+ if (!prGlueInfo->prAdapter) { -+ DBGLOG(INIT, ERROR, "Allocating memory to adapter failed\n"); -+ return NULL; -+ } -+ KAL_WAKE_LOCK_INIT(prAdapter, &prGlueInfo->rAhbIsrWakeLock, "WLAN AHB ISR"); -+#if CFG_SUPPORT_PERSIST_NETDEV -+ dev_open(prGlueInfo->prDevHandler); -+ netif_carrier_off(prGlueInfo->prDevHandler); -+ netif_tx_stop_all_queues(prGlueInfo->prDevHandler); -+#endif -+ -+ return prWdev; -+} /* end of wlanNetCreate() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Destroying the struct net_device object and the private data. -+* -+* \param[in] prWdev Pointer to struct wireless_dev. -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+static VOID wlanNetDestroy(struct wireless_dev *prWdev) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ -+ ASSERT(prWdev); -+ -+ if (!prWdev) { -+ DBGLOG(INIT, ERROR, "wlanNetDestroy: The device context is NULL\n"); -+ return; -+ } -+ -+ /* prGlueInfo is allocated with net_device */ -+ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(prWdev->wiphy); -+ ASSERT(prGlueInfo); -+ -+ /* destroy kal OS timer */ -+ kalCancelTimer(prGlueInfo); -+ -+ glClearHifInfo(prGlueInfo); -+ -+ wlanAdapterDestroy(prGlueInfo->prAdapter); -+ prGlueInfo->prAdapter = NULL; -+ -+#if CFG_SUPPORT_PERSIST_NETDEV -+ /* take the net_device to down state */ -+ dev_close(prGlueInfo->prDevHandler); -+#else -+ /* Free net_device and private data prGlueInfo, which are allocated by alloc_netdev(). */ -+ free_netdev(prWdev->netdev); -+#endif -+ -+} /* end of wlanNetDestroy() */ -+ -+#ifndef CONFIG_X86 -+UINT_8 g_aucBufIpAddr[32] = { 0 }; -+static void wlanNotifyFwSuspend(P_GLUE_INFO_T prGlueInfo, BOOLEAN fgSuspend) -+{ -+ WLAN_STATUS rStatus = WLAN_STATUS_FAILURE; -+ UINT_32 u4SetInfoLen; -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidNotifyFwSuspend, -+ (PVOID)&fgSuspend, -+ sizeof(fgSuspend), -+ FALSE, -+ FALSE, -+ TRUE, -+ FALSE, -+ &u4SetInfoLen); -+ if (rStatus != WLAN_STATUS_SUCCESS) -+ DBGLOG(INIT, INFO, "wlanNotifyFwSuspend fail\n"); -+} -+ -+void wlanHandleSystemSuspend(void) -+{ -+ WLAN_STATUS rStatus = WLAN_STATUS_FAILURE; -+ struct net_device *prDev = NULL; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ UINT_8 ip[4] = { 0 }; -+ UINT_32 u4NumIPv4 = 0; -+#ifdef CONFIG_IPV6 -+ UINT_8 ip6[16] = { 0 }; /* FIX ME: avoid to allocate large memory in stack */ -+ UINT_32 u4NumIPv6 = 0; -+#endif -+ UINT_32 i; -+ P_PARAM_NETWORK_ADDRESS_IP prParamIpAddr; -+ -+ /* <1> Sanity check and acquire the net_device */ -+ ASSERT(u4WlanDevNum <= CFG_MAX_WLAN_DEVICES); -+ if (u4WlanDevNum == 0) { -+ DBGLOG(INIT, ERROR, "wlanEarlySuspend u4WlanDevNum==0 invalid!!\n"); -+ return; -+ } -+ prDev = arWlanDevInfo[u4WlanDevNum - 1].prDev; -+ -+ fgIsUnderSuspend = true; -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ ASSERT(prGlueInfo); -+ -+ kalPerMonDisable(prGlueInfo); -+ -+ if (!prDev || !(prDev->ip_ptr) || -+ !((struct in_device *)(prDev->ip_ptr))->ifa_list || -+ !(&(((struct in_device *)(prDev->ip_ptr))->ifa_list->ifa_local))) { -+ goto notify_suspend; -+ } -+ kalMemCopy(ip, &(((struct in_device *)(prDev->ip_ptr))->ifa_list->ifa_local), sizeof(ip)); -+ -+ /* todo: traverse between list to find whole sets of IPv4 addresses */ -+ if (!((ip[0] == 0) && (ip[1] == 0) && (ip[2] == 0) && (ip[3] == 0))) -+ u4NumIPv4++; -+#ifdef CONFIG_IPV6 -+ if (!prDev || !(prDev->ip6_ptr) || -+ !((struct in_device *)(prDev->ip6_ptr))->ifa_list || -+ !(&(((struct in_device *)(prDev->ip6_ptr))->ifa_list->ifa_local))) { -+ goto notify_suspend; -+ } -+ kalMemCopy(ip6, &(((struct in_device *)(prDev->ip6_ptr))->ifa_list->ifa_local), sizeof(ip6)); -+ DBGLOG(INIT, INFO, "ipv6 is %d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d\n", -+ ip6[0], ip6[1], ip6[2], ip6[3], -+ ip6[4], ip6[5], ip6[6], ip6[7], -+ ip6[8], ip6[9], ip6[10], ip6[11], ip6[12], ip6[13], ip6[14], ip6[15] -+ ); -+ -+ /* todo: traverse between list to find whole sets of IPv6 addresses */ -+ if (!((ip6[0] == 0) && (ip6[1] == 0) && (ip6[2] == 0) && (ip6[3] == 0) && (ip6[4] == 0) && (ip6[5] == 0))) { -+ /* Do nothing */ -+ /* u4NumIPv6++; */ -+ } -+#endif -+ -+ /* <7> set up the ARP filter */ -+ { -+ UINT_32 u4SetInfoLen = 0; -+ UINT_32 u4Len = OFFSET_OF(PARAM_NETWORK_ADDRESS_LIST, arAddress); -+ P_PARAM_NETWORK_ADDRESS_LIST prParamNetAddrList = (P_PARAM_NETWORK_ADDRESS_LIST) g_aucBufIpAddr; -+ P_PARAM_NETWORK_ADDRESS prParamNetAddr = prParamNetAddrList->arAddress; -+ -+ kalMemZero(g_aucBufIpAddr, sizeof(g_aucBufIpAddr)); -+ -+ prParamNetAddrList->u4AddressCount = u4NumIPv4; -+#ifdef CONFIG_IPV6 -+ prParamNetAddrList->u4AddressCount += u4NumIPv6; -+#endif -+ prParamNetAddrList->u2AddressType = PARAM_PROTOCOL_ID_TCP_IP; -+ for (i = 0; i < u4NumIPv4; i++) { -+ prParamNetAddr->u2AddressLength = sizeof(PARAM_NETWORK_ADDRESS_IP); /* 4;; */ -+ prParamNetAddr->u2AddressType = PARAM_PROTOCOL_ID_TCP_IP; -+ prParamIpAddr = (P_PARAM_NETWORK_ADDRESS_IP) prParamNetAddr->aucAddress; -+ kalMemCopy(&prParamIpAddr->in_addr, ip, sizeof(ip)); -+ prParamNetAddr = -+ (P_PARAM_NETWORK_ADDRESS) ((ULONG) prParamNetAddr + sizeof(PARAM_NETWORK_ADDRESS)); -+ u4Len += OFFSET_OF(PARAM_NETWORK_ADDRESS, aucAddress) + sizeof(PARAM_NETWORK_ADDRESS); -+ } -+#ifdef CONFIG_IPV6 -+ for (i = 0; i < u4NumIPv6; i++) { -+ prParamNetAddr->u2AddressLength = 6; -+ prParamNetAddr->u2AddressType = PARAM_PROTOCOL_ID_TCP_IP; -+ kalMemCopy(prParamNetAddr->aucAddress, ip6, sizeof(ip6)); -+ prParamNetAddr = (P_PARAM_NETWORK_ADDRESS) ((ULONG) prParamNetAddr + sizeof(ip6)); -+ u4Len += OFFSET_OF(PARAM_NETWORK_ADDRESS, aucAddress) + sizeof(ip6); -+ } -+#endif -+ ASSERT(u4Len <= sizeof(g_aucBufIpAddr)); -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetNetworkAddress, -+ (PVOID) prParamNetAddrList, u4Len, FALSE, FALSE, TRUE, FALSE, &u4SetInfoLen); -+ } -+ -+notify_suspend: -+ DBGLOG(INIT, INFO, "IP: %d.%d.%d.%d, rStatus: %u\n", ip[0], ip[1], ip[2], ip[3], rStatus); -+ if (rStatus != WLAN_STATUS_SUCCESS) -+ wlanNotifyFwSuspend(prGlueInfo, TRUE); -+} -+ -+void wlanHandleSystemResume(void) -+{ -+ struct net_device *prDev = NULL; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ WLAN_STATUS rStatus = WLAN_STATUS_FAILURE; -+ UINT_8 ip[4] = { 0 }; -+#ifdef CONFIG_IPV6 -+ UINT_8 ip6[16] = { 0 }; /* FIX ME: avoid to allocate large memory in stack */ -+#endif -+ EVENT_AIS_BSS_INFO_T rParam; -+ UINT_32 u4BufLen = 0; -+ -+ /* <1> Sanity check and acquire the net_device */ -+ ASSERT(u4WlanDevNum <= CFG_MAX_WLAN_DEVICES); -+ if (u4WlanDevNum == 0) { -+ DBGLOG(INIT, ERROR, "wlanLateResume u4WlanDevNum==0 invalid!!\n"); -+ return; -+ } -+ prDev = arWlanDevInfo[u4WlanDevNum - 1].prDev; -+ /* ASSERT(prDev); */ -+ -+ fgIsUnderSuspend = false; -+ -+ if (!prDev) { -+ DBGLOG(INIT, INFO, "prDev == NULL!!!\n"); -+ return; -+ } -+ /* <3> acquire the prGlueInfo */ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ ASSERT(prGlueInfo); -+ -+ kalPerMonEnable(prGlueInfo); -+ -+ /* -+ We will receive the event in rx, we will check if the status is the same in driver -+ and FW, if not the same, trigger disconnetion procedure. -+ */ -+ -+ kalMemZero(&rParam, sizeof(EVENT_AIS_BSS_INFO_T)); -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidQueryBSSInfo, -+ &rParam, sizeof(EVENT_AIS_BSS_INFO_T), TRUE, TRUE, TRUE, FALSE, &u4BufLen); -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ DBGLOG(INIT, ERROR, "Query BSSinfo fail 0x%x!!\n", rStatus); -+ } -+ -+ /* <2> get the IPv4 address */ -+ if (!(prDev->ip_ptr) || -+ !((struct in_device *)(prDev->ip_ptr))->ifa_list || -+ !(&(((struct in_device *)(prDev->ip_ptr))->ifa_list->ifa_local))) { -+ goto notify_resume; -+ } -+ /* <4> copy the IPv4 address */ -+ kalMemCopy(ip, &(((struct in_device *)(prDev->ip_ptr))->ifa_list->ifa_local), sizeof(ip)); -+ -+#ifdef CONFIG_IPV6 -+ /* <5> get the IPv6 address */ -+ if (!prDev || !(prDev->ip6_ptr) || -+ !((struct in_device *)(prDev->ip6_ptr))->ifa_list || -+ !(&(((struct in_device *)(prDev->ip6_ptr))->ifa_list->ifa_local))) { -+ goto notify_resume; -+ } -+ /* <6> copy the IPv6 address */ -+ kalMemCopy(ip6, &(((struct in_device *)(prDev->ip6_ptr))->ifa_list->ifa_local), sizeof(ip6)); -+ DBGLOG(INIT, INFO, "ipv6 is %d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d\n", -+ ip6[0], ip6[1], ip6[2], ip6[3], -+ ip6[4], ip6[5], ip6[6], ip6[7], -+ ip6[8], ip6[9], ip6[10], ip6[11], ip6[12], ip6[13], ip6[14], ip6[15] -+ ); -+#endif -+ /* <7> clear the ARP filter */ -+ { -+ UINT_32 u4SetInfoLen = 0; -+/* UINT_8 aucBuf[32] = {0}; */ -+ UINT_32 u4Len = sizeof(PARAM_NETWORK_ADDRESS_LIST); -+ P_PARAM_NETWORK_ADDRESS_LIST prParamNetAddrList = (P_PARAM_NETWORK_ADDRESS_LIST) g_aucBufIpAddr; -+ /* aucBuf; */ -+ -+ kalMemZero(g_aucBufIpAddr, sizeof(g_aucBufIpAddr)); -+ -+ prParamNetAddrList->u4AddressCount = 0; -+ prParamNetAddrList->u2AddressType = PARAM_PROTOCOL_ID_TCP_IP; -+ -+ ASSERT(u4Len <= sizeof(g_aucBufIpAddr /*aucBuf */)); -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetNetworkAddress, -+ (PVOID) prParamNetAddrList, u4Len, FALSE, FALSE, TRUE, FALSE, &u4SetInfoLen); -+ } -+ -+notify_resume: -+ DBGLOG(INIT, INFO, "Query BSS result: %d %d %d, IP: %d.%d.%d.%d, rStatus: %u\n", -+ rParam.eConnectionState, rParam.eCurrentOPMode, rParam.fgIsNetActive, -+ ip[0], ip[1], ip[2], ip[3], rStatus); -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ wlanNotifyFwSuspend(prGlueInfo, FALSE); -+ } -+} -+#endif /* ! CONFIG_X86 */ -+ -+int set_p2p_mode_handler(struct net_device *netdev, PARAM_CUSTOM_P2P_SET_STRUCT_T p2pmode) -+{ -+#if 0 -+ P_GLUE_INFO_T prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(netdev)); -+ PARAM_CUSTOM_P2P_SET_STRUCT_T rSetP2P; -+ WLAN_STATUS rWlanStatus = WLAN_STATUS_SUCCESS; -+ UINT_32 u4BufLen = 0; -+ -+ rSetP2P.u4Enable = p2pmode.u4Enable; -+ rSetP2P.u4Mode = p2pmode.u4Mode; -+ -+ if (!rSetP2P.u4Enable) -+ p2pNetUnregister(prGlueInfo, TRUE); -+ -+ rWlanStatus = kalIoctl(prGlueInfo, -+ wlanoidSetP2pMode, -+ (PVOID) &rSetP2P, -+ sizeof(PARAM_CUSTOM_P2P_SET_STRUCT_T), FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ DBGLOG(INIT, INFO, "ret = %d\n", rWlanStatus); -+ if (rSetP2P.u4Enable) -+ p2pNetRegister(prGlueInfo, TRUE); -+ -+ return 0; -+ -+#else -+ -+ P_GLUE_INFO_T prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(netdev)); -+ PARAM_CUSTOM_P2P_SET_STRUCT_T rSetP2P; -+ WLAN_STATUS rWlanStatus = WLAN_STATUS_SUCCESS; -+ BOOLEAN fgIsP2PEnding; -+ UINT_32 u4BufLen = 0; -+ -+ GLUE_SPIN_LOCK_DECLARATION(); -+ -+ DBGLOG(INIT, INFO, "%u %u\n", (UINT_32) p2pmode.u4Enable, (UINT_32) p2pmode.u4Mode); -+ -+ /* avoid remove & p2p off command simultaneously */ -+ GLUE_ACQUIRE_THE_SPIN_LOCK(&g_p2p_lock); -+ fgIsP2PEnding = g_u4P2PEnding; -+ g_u4P2POnOffing = 1; -+ GLUE_RELEASE_THE_SPIN_LOCK(&g_p2p_lock); -+ -+ if (fgIsP2PEnding == 1) { -+ /* skip the command if we are removing */ -+ GLUE_ACQUIRE_THE_SPIN_LOCK(&g_p2p_lock); -+ g_u4P2POnOffing = 0; -+ GLUE_RELEASE_THE_SPIN_LOCK(&g_p2p_lock); -+ return 0; -+ } -+ -+ rSetP2P.u4Enable = p2pmode.u4Enable; -+ rSetP2P.u4Mode = p2pmode.u4Mode; -+ -+#if !CFG_SUPPORT_PERSIST_NETDEV -+ if ((!rSetP2P.u4Enable) && (fgIsResetting == FALSE)) -+ p2pNetUnregister(prGlueInfo, TRUE); -+#endif -+ /* move out to caller to avoid kalIoctrl & suspend/resume deadlock problem ALPS00844864 */ -+ /* -+ Scenario: -+ 1. System enters suspend/resume but not yet enter wlanearlysuspend() -+ or wlanlateresume(); -+ -+ 2. System switches to do PRIV_CMD_P2P_MODE and execute kalIoctl() -+ and get g_halt_sem then do glRegisterEarlySuspend() or -+ glUnregisterEarlySuspend(); -+ -+ But system suspend/resume procedure is not yet finished so we -+ suspend; -+ -+ 3. System switches back to do suspend/resume procedure and execute -+ kalIoctl(). But driver does not yet release g_halt_sem so system -+ suspend in wlanearlysuspend() or wlanlateresume(); -+ -+ ==> deadlock occurs. -+ */ -+ -+ rWlanStatus = kalIoctl(prGlueInfo, wlanoidSetP2pMode, (PVOID) &rSetP2P,/* pu4IntBuf[0]is used as input SubCmd */ -+ sizeof(PARAM_CUSTOM_P2P_SET_STRUCT_T), FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+#if !CFG_SUPPORT_PERSIST_NETDEV -+ /* Need to check fgIsP2PRegistered, in case of whole chip reset. -+ * in this case, kalIOCTL return success always, -+ * and prGlueInfo->prP2pInfo may be NULL */ -+ if ((rSetP2P.u4Enable) && (prGlueInfo->prAdapter->fgIsP2PRegistered) && (fgIsResetting == FALSE)) -+ p2pNetRegister(prGlueInfo, TRUE); -+#endif -+ GLUE_ACQUIRE_THE_SPIN_LOCK(&g_p2p_lock); -+ g_u4P2POnOffing = 0; -+ GLUE_RELEASE_THE_SPIN_LOCK(&g_p2p_lock); -+ return 0; -+#endif -+} -+ -+static void set_dbg_level_handler(unsigned char dbg_lvl[DBG_MODULE_NUM]) -+{ -+ kalMemCopy(aucDebugModule, dbg_lvl, sizeof(aucDebugModule)); -+ kalPrint("[wlan] change debug level"); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Wlan probe function. This function probes and initializes the device. -+* -+* \param[in] pvData data passed by bus driver init function -+* _HIF_EHPI: NULL -+* _HIF_SDIO: sdio bus driver handle -+* -+* \retval 0 Success -+* \retval negative value Failed -+*/ -+/*----------------------------------------------------------------------------*/ -+static INT_32 wlanProbe(PVOID pvData) -+{ -+ struct wireless_dev *prWdev = NULL; -+ enum probe_fail_reason { -+ BUS_INIT_FAIL, -+ NET_CREATE_FAIL, -+ BUS_SET_IRQ_FAIL, -+ ADAPTER_START_FAIL, -+ NET_REGISTER_FAIL, -+ PROC_INIT_FAIL, -+ FAIL_REASON_NUM -+ } eFailReason; -+ P_WLANDEV_INFO_T prWlandevInfo = NULL; -+ INT_32 i4DevIdx = 0; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ P_ADAPTER_T prAdapter = NULL; -+ INT_32 i4Status = 0; -+ BOOLEAN bRet = FALSE; -+ -+ eFailReason = FAIL_REASON_NUM; -+ do { -+ /* 4 <1> Initialize the IO port of the interface */ -+ /* GeorgeKuo: pData has different meaning for _HIF_XXX: -+ * _HIF_EHPI: pointer to memory base variable, which will be -+ * initialized by glBusInit(). -+ * _HIF_SDIO: bus driver handle -+ */ -+ -+ bRet = glBusInit(pvData); -+ wlanDebugInit(); -+ /* Cannot get IO address from interface */ -+ if (FALSE == bRet) { -+ DBGLOG(INIT, ERROR, KERN_ALERT "wlanProbe: glBusInit() fail\n"); -+ i4Status = -EIO; -+ eFailReason = BUS_INIT_FAIL; -+ break; -+ } -+ /* 4 <2> Create network device, Adapter, KalInfo, prDevHandler(netdev) */ -+ prWdev = wlanNetCreate(pvData); -+ if (prWdev == NULL) { -+ DBGLOG(INIT, ERROR, "wlanProbe: No memory for dev and its private\n"); -+ i4Status = -ENOMEM; -+ eFailReason = NET_CREATE_FAIL; -+ break; -+ } -+ /* 4 <2.5> Set the ioaddr to HIF Info */ -+ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(prWdev->wiphy); -+ gPrDev = prGlueInfo->prDevHandler; -+ -+ /* 4 <4> Setup IRQ */ -+ prWlandevInfo = &arWlanDevInfo[i4DevIdx]; -+ -+ i4Status = glBusSetIrq(prWdev->netdev, NULL, *((P_GLUE_INFO_T *) netdev_priv(prWdev->netdev))); -+ -+ if (i4Status != WLAN_STATUS_SUCCESS) { -+ DBGLOG(INIT, ERROR, "wlanProbe: Set IRQ error\n"); -+ eFailReason = BUS_SET_IRQ_FAIL; -+ break; -+ } -+ -+ prGlueInfo->i4DevIdx = i4DevIdx; -+ -+ prAdapter = prGlueInfo->prAdapter; -+ -+ prGlueInfo->u4ReadyFlag = 0; -+ -+#if CFG_TCP_IP_CHKSUM_OFFLOAD -+ prAdapter->u4CSUMFlags = (CSUM_OFFLOAD_EN_TX_TCP | CSUM_OFFLOAD_EN_TX_UDP | CSUM_OFFLOAD_EN_TX_IP); -+#endif -+#if CFG_SUPPORT_CFG_FILE -+ { -+ PUINT_8 pucConfigBuf; -+ UINT_32 u4ConfigReadLen; -+ -+ wlanCfgInit(prAdapter, NULL, 0, 0); -+ pucConfigBuf = (PUINT_8) kalMemAlloc(WLAN_CFG_FILE_BUF_SIZE, VIR_MEM_TYPE); -+ u4ConfigReadLen = 0; -+ DBGLOG(INIT, LOUD, "CFG_FILE: Read File...\n"); -+ if (pucConfigBuf) { -+ kalMemZero(pucConfigBuf, WLAN_CFG_FILE_BUF_SIZE); -+ if (kalReadToFile("/data/misc/wifi.cfg", -+ pucConfigBuf, WLAN_CFG_FILE_BUF_SIZE, &u4ConfigReadLen) == 0) { -+ DBGLOG(INIT, LOUD, "CFG_FILE: Read /data/misc/wifi.cfg\n"); -+ -+ } else if (kalReadToFile("/data/misc/wifi/wifi.cfg", -+ pucConfigBuf, WLAN_CFG_FILE_BUF_SIZE, &u4ConfigReadLen) == 0) { -+ DBGLOG(INIT, LOUD, "CFG_FILE: Read /data/misc/wifi/wifi.cfg\n"); -+ } else if (kalReadToFile("/etc/firmware/wifi.cfg", -+ pucConfigBuf, WLAN_CFG_FILE_BUF_SIZE, &u4ConfigReadLen) == 0) { -+ DBGLOG(INIT, LOUD, "CFG_FILE: Read /etc/firmware/wifi.cfg\n"); -+ } -+ -+ if (pucConfigBuf[0] != '\0' && u4ConfigReadLen > 0) -+ wlanCfgInit(prAdapter, pucConfigBuf, u4ConfigReadLen, 0); -+ kalMemFree(pucConfigBuf, VIR_MEM_TYPE, WLAN_CFG_FILE_BUF_SIZE); -+ } /* pucConfigBuf */ -+ } -+#endif -+ /* 4 <5> Start Device */ -+ /* */ -+#if CFG_ENABLE_FW_DOWNLOAD -+ DBGLOG(INIT, TRACE, "start to download firmware...\n"); -+ -+ /* before start adapter, we need to open and load firmware */ -+ { -+ UINT_32 u4FwSize = 0; -+ PVOID prFwBuffer = NULL; -+ P_REG_INFO_T prRegInfo = &prGlueInfo->rRegInfo; -+ -+ /* P_REG_INFO_T prRegInfo = (P_REG_INFO_T) kmalloc(sizeof(REG_INFO_T), GFP_KERNEL); */ -+ kalMemSet(prRegInfo, 0, sizeof(REG_INFO_T)); -+ prRegInfo->u4StartAddress = CFG_FW_START_ADDRESS; -+ prRegInfo->u4LoadAddress = CFG_FW_LOAD_ADDRESS; -+ -+ /* Load NVRAM content to REG_INFO_T */ -+ glLoadNvram(prGlueInfo, prRegInfo); -+#if CFG_SUPPORT_CFG_FILE -+ wlanCfgApply(prAdapter); -+#endif -+ -+ /* kalMemCopy(&prGlueInfo->rRegInfo, prRegInfo, sizeof(REG_INFO_T)); */ -+ -+ prRegInfo->u4PowerMode = CFG_INIT_POWER_SAVE_PROF; -+ prRegInfo->fgEnArpFilter = TRUE; -+ -+ if (kalFirmwareImageMapping(prGlueInfo, &prFwBuffer, &u4FwSize) == NULL) { -+ i4Status = -EIO; -+ DBGLOG(INIT, ERROR, "kalFirmwareImageMapping fail!\n"); -+ goto bailout; -+ } else { -+ -+ if (wlanAdapterStart(prAdapter, prRegInfo, prFwBuffer, -+ u4FwSize) != WLAN_STATUS_SUCCESS) { -+ i4Status = -EIO; -+ } -+ } -+ -+ kalFirmwareImageUnmapping(prGlueInfo, NULL, prFwBuffer); -+ -+bailout: -+ /* kfree(prRegInfo); */ -+ -+ DBGLOG(INIT, TRACE, "download firmware status = %d\n", i4Status); -+ -+ if (i4Status < 0) { -+ GL_HIF_INFO_T *HifInfo; -+ UINT_32 u4FwCnt; -+ -+ DBGLOG(INIT, WARN, "CONNSYS FW CPUINFO:\n"); -+ HifInfo = &prAdapter->prGlueInfo->rHifInfo; -+ for (u4FwCnt = 0; u4FwCnt < 16; u4FwCnt++) -+ DBGLOG(INIT, WARN, "0x%08x ", MCU_REG_READL(HifInfo, CONN_MCU_CPUPCR)); -+ /* CONSYS_REG_READ(CONSYS_CPUPCR_REG) */ -+ -+ /* dump HIF/DMA registers, if fgIsBusAccessFailed is FALSE, otherwise, */ -+ /* dump HIF register may be hung */ -+ if (!fgIsBusAccessFailed) -+ HifRegDump(prGlueInfo->prAdapter); -+/* if (prGlueInfo->rHifInfo.DmaOps->DmaRegDump != NULL) */ -+/* prGlueInfo->rHifInfo.DmaOps->DmaRegDump(&prGlueInfo->rHifInfo); */ -+ eFailReason = ADAPTER_START_FAIL; -+ break; -+ } -+ } -+#else -+ /* P_REG_INFO_T prRegInfo = (P_REG_INFO_T) kmalloc(sizeof(REG_INFO_T), GFP_KERNEL); */ -+ kalMemSet(&prGlueInfo->rRegInfo, 0, sizeof(REG_INFO_T)); -+ P_REG_INFO_T prRegInfo = &prGlueInfo->rRegInfo; -+ -+ /* Load NVRAM content to REG_INFO_T */ -+ glLoadNvram(prGlueInfo, prRegInfo); -+ -+ prRegInfo->u4PowerMode = CFG_INIT_POWER_SAVE_PROF; -+ -+ if (wlanAdapterStart(prAdapter, prRegInfo, NULL, 0) != WLAN_STATUS_SUCCESS) { -+ i4Status = -EIO; -+ eFailReason = ADAPTER_START_FAIL; -+ break; -+ } -+#endif -+ if (FALSE == prAdapter->fgEnable5GBand) -+ prWdev->wiphy->bands[NL80211_BAND_5GHZ] = NULL; -+ -+ prGlueInfo->main_thread = kthread_run(tx_thread, prGlueInfo->prDevHandler, "tx_thread"); -+ kalSetHalted(FALSE); -+#if CFG_SUPPORT_ROAMING_ENC -+ /* adjust roaming threshold */ -+ { -+ WLAN_STATUS rStatus = WLAN_STATUS_FAILURE; -+ CMD_ROAMING_INFO_T rRoamingInfo; -+ UINT_32 u4SetInfoLen = 0; -+ -+ prAdapter->fgIsRoamingEncEnabled = TRUE; -+ -+ /* suggestion from Tsaiyuan.Hsu */ -+ kalMemZero(&rRoamingInfo, sizeof(CMD_ROAMING_INFO_T)); -+ rRoamingInfo.fgIsFastRoamingApplied = TRUE; -+ -+ DBGLOG(INIT, TRACE, "Enable roaming enhance function\n"); -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetRoamingInfo, -+ &rRoamingInfo, sizeof(rRoamingInfo), TRUE, TRUE, TRUE, FALSE, &u4SetInfoLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) -+ DBGLOG(INIT, ERROR, "set roaming advance info fail 0x%x\n", rStatus); -+ } -+#endif /* CFG_SUPPORT_ROAMING_ENC */ -+ -+#if (CFG_SUPPORT_TXR_ENC == 1) -+ /* adjust tx rate switch threshold */ -+ rlmTxRateEnhanceConfig(prGlueInfo->prAdapter); -+#endif /* CFG_SUPPORT_TXR_ENC */ -+ -+ /* set MAC address */ -+ { -+ WLAN_STATUS rStatus = WLAN_STATUS_FAILURE; -+ struct sockaddr MacAddr; -+ UINT_32 u4SetInfoLen = 0; -+ -+ kalMemZero(MacAddr.sa_data, sizeof(MacAddr.sa_data)); -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidQueryCurrentAddr, -+ &MacAddr.sa_data, -+ PARAM_MAC_ADDR_LEN, TRUE, TRUE, TRUE, FALSE, &u4SetInfoLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ DBGLOG(INIT, WARN, "set MAC addr fail 0x%x\n", rStatus); -+ prGlueInfo->u4ReadyFlag = 0; -+ } else { -+ ether_addr_copy(prGlueInfo->prDevHandler->dev_addr, (const u8 *)&(MacAddr.sa_data)); -+ ether_addr_copy(prGlueInfo->prDevHandler->perm_addr, -+ prGlueInfo->prDevHandler->dev_addr); -+ -+ /* card is ready */ -+ prGlueInfo->u4ReadyFlag = 1; -+#if CFG_SHOW_MACADDR_SOURCE -+ DBGLOG(INIT, INFO, "MAC address: %pM ", (&MacAddr.sa_data)); -+#endif -+ } -+ } -+ -+#if CFG_TCP_IP_CHKSUM_OFFLOAD -+ /* set HW checksum offload */ -+ { -+ WLAN_STATUS rStatus = WLAN_STATUS_FAILURE; -+ UINT_32 u4CSUMFlags = CSUM_OFFLOAD_EN_ALL; -+ UINT_32 u4SetInfoLen = 0; -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetCSUMOffload, -+ (PVOID) &u4CSUMFlags, -+ sizeof(UINT_32), FALSE, FALSE, TRUE, FALSE, &u4SetInfoLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) -+ DBGLOG(INIT, WARN, "set HW checksum offload fail 0x%x\n", rStatus); -+ } -+#endif -+ -+ /* 4 <3> Register the card */ -+ DBGLOG(INIT, TRACE, "wlanNetRegister...\n"); -+ i4DevIdx = wlanNetRegister(prWdev); -+ if (i4DevIdx < 0) { -+ i4Status = -ENXIO; -+ DBGLOG(INIT, ERROR, "wlanProbe: Cannot register the net_device context to the kernel\n"); -+ eFailReason = NET_REGISTER_FAIL; -+ break; -+ } -+ -+ wlanRegisterNotifier(); -+ /* 4 <6> Initialize /proc filesystem */ -+#ifdef WLAN_INCLUDE_PROC -+ DBGLOG(INIT, TRACE, "init procfs...\n"); -+ i4Status = procCreateFsEntry(prGlueInfo); -+ if (i4Status < 0) { -+ DBGLOG(INIT, ERROR, "wlanProbe: init procfs failed\n"); -+ eFailReason = PROC_INIT_FAIL; -+ break; -+ } -+#endif /* WLAN_INCLUDE_PROC */ -+ -+#if CFG_ENABLE_BT_OVER_WIFI -+ prGlueInfo->rBowInfo.fgIsNetRegistered = FALSE; -+ prGlueInfo->rBowInfo.fgIsRegistered = FALSE; -+ glRegisterAmpc(prGlueInfo); -+#endif -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ DBGLOG(INIT, TRACE, "wlanSubModInit...\n"); -+ -+ /* wlan is launched */ -+ prGlueInfo->prAdapter->fgIsWlanLaunched = TRUE; -+ /* if p2p module is inserted, notify tx_thread to init p2p network */ -+ if (rSubModHandler[P2P_MODULE].subModInit) -+ wlanSubModInit(prGlueInfo); -+ /* register set_p2p_mode handler to mtk_wmt_wifi */ -+ register_set_p2p_mode_handler(set_p2p_mode_handler); -+#endif -+#if CFG_SPM_WORKAROUND_FOR_HOTSPOT -+ if (glIsChipNeedWakelock(prGlueInfo)) -+ KAL_WAKE_LOCK_INIT(prGlueInfo->prAdapter, &prGlueInfo->prAdapter->rApWakeLock, "WLAN AP"); -+#endif -+ } while (FALSE); -+ -+ if (i4Status != WLAN_STATUS_SUCCESS) { -+ switch (eFailReason) { -+ case PROC_INIT_FAIL: -+ wlanNetUnregister(prWdev); -+ set_bit(GLUE_FLAG_HALT_BIT, &prGlueInfo->ulFlag); -+ /* wake up main thread */ -+ wake_up_interruptible(&prGlueInfo->waitq); -+ /* wait main thread stops */ -+ wait_for_completion_interruptible(&prGlueInfo->rHaltComp); -+ KAL_WAKE_LOCK_DESTROY(prAdapter, &prAdapter->rTxThreadWakeLock); -+ wlanAdapterStop(prAdapter); -+ glBusFreeIrq(prWdev->netdev, *((P_GLUE_INFO_T *) netdev_priv(prWdev->netdev))); -+ KAL_WAKE_LOCK_DESTROY(prAdapter, &prGlueInfo->rAhbIsrWakeLock); -+ wlanNetDestroy(prWdev); -+ break; -+ case NET_REGISTER_FAIL: -+ set_bit(GLUE_FLAG_HALT_BIT, &prGlueInfo->ulFlag); -+ /* wake up main thread */ -+ wake_up_interruptible(&prGlueInfo->waitq); -+ /* wait main thread stops */ -+ wait_for_completion_interruptible(&prGlueInfo->rHaltComp); -+ KAL_WAKE_LOCK_DESTROY(prAdapter, &prAdapter->rTxThreadWakeLock); -+ wlanAdapterStop(prAdapter); -+ glBusFreeIrq(prWdev->netdev, *((P_GLUE_INFO_T *) netdev_priv(prWdev->netdev))); -+ KAL_WAKE_LOCK_DESTROY(prAdapter, &prGlueInfo->rAhbIsrWakeLock); -+ wlanNetDestroy(prWdev); -+ break; -+ case ADAPTER_START_FAIL: -+ glBusFreeIrq(prWdev->netdev, *((P_GLUE_INFO_T *) netdev_priv(prWdev->netdev))); -+ KAL_WAKE_LOCK_DESTROY(prAdapter, &prGlueInfo->rAhbIsrWakeLock); -+ wlanNetDestroy(prWdev); -+ break; -+ case BUS_SET_IRQ_FAIL: -+ KAL_WAKE_LOCK_DESTROY(prAdapter, &prGlueInfo->rAhbIsrWakeLock); -+ wlanNetDestroy(prWdev); -+ break; -+ case NET_CREATE_FAIL: -+ break; -+ case BUS_INIT_FAIL: -+ break; -+ default: -+ break; -+ } -+ } -+#if CFG_ENABLE_WIFI_DIRECT -+ { -+ GLUE_SPIN_LOCK_DECLARATION(); -+ -+ GLUE_ACQUIRE_THE_SPIN_LOCK(&g_p2p_lock); -+ g_u4P2PEnding = 0; -+ GLUE_RELEASE_THE_SPIN_LOCK(&g_p2p_lock); -+ } -+#endif -+#if CFG_SUPPORT_AGPS_ASSIST -+ if (i4Status == WLAN_STATUS_SUCCESS) -+ kalIndicateAgpsNotify(prAdapter, AGPS_EVENT_WLAN_ON, NULL, 0); -+#endif -+#if (CFG_SUPPORT_MET_PROFILING == 1) -+ { -+ int iMetInitRet = WLAN_STATUS_FAILURE; -+ -+ if (i4Status == WLAN_STATUS_SUCCESS) { -+ DBGLOG(INIT, TRACE, "init MET procfs...\n"); -+ iMetInitRet = kalMetInitProcfs(prGlueInfo); -+ if (iMetInitRet < 0) -+ DBGLOG(INIT, ERROR, "wlanProbe: init MET procfs failed\n"); -+ } -+ } -+#endif -+ if (i4Status == WLAN_STATUS_SUCCESS) { -+ /*Init performance monitor structure */ -+ kalPerMonInit(prGlueInfo); -+ /* probe ok */ -+ DBGLOG(INIT, TRACE, "wlanProbe ok\n"); -+ } else { -+ /* we don't care the return value of mtk_wcn_set_connsys_power_off_flag, -+ * because even this function returns -+ * error, we can also call core dump but only core dump failed. */ -+ if (g_IsNeedDoChipReset) -+ mtk_wcn_set_connsys_power_off_flag(0); -+ /* probe failed */ -+ DBGLOG(INIT, ERROR, "wlanProbe failed\n"); -+ } -+ -+ return i4Status; -+} /* end of wlanProbe() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief A method to stop driver operation and release all resources. Following -+* this call, no frame should go up or down through this interface. -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+static VOID wlanRemove(VOID) -+{ -+#define KAL_WLAN_REMOVE_TIMEOUT_MSEC 3000 -+ struct net_device *prDev = NULL; -+ P_WLANDEV_INFO_T prWlandevInfo = NULL; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ P_ADAPTER_T prAdapter = NULL; -+ -+ DBGLOG(INIT, LOUD, "Remove wlan!\n"); -+ -+ /* 4 <0> Sanity check */ -+ ASSERT(u4WlanDevNum <= CFG_MAX_WLAN_DEVICES); -+ if (0 == u4WlanDevNum) { -+ DBGLOG(INIT, ERROR, "0 == u4WlanDevNum\n"); -+ return; -+ } -+ /* unregister set_p2p_mode handler to mtk_wmt_wifi */ -+ register_set_p2p_mode_handler(NULL); -+ -+ prDev = arWlanDevInfo[u4WlanDevNum - 1].prDev; -+ prWlandevInfo = &arWlanDevInfo[u4WlanDevNum - 1]; -+ -+ ASSERT(prDev); -+ if (NULL == prDev) { -+ DBGLOG(INIT, ERROR, "NULL == prDev\n"); -+ return; -+ } -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ ASSERT(prGlueInfo); -+ if (NULL == prGlueInfo) { -+ DBGLOG(INIT, ERROR, "NULL == prGlueInfo\n"); -+ free_netdev(prDev); -+ return; -+ } -+ -+ kalPerMonDestroy(prGlueInfo); -+#if CFG_ENABLE_WIFI_DIRECT -+ /* avoid remove & p2p off command simultaneously */ -+ { -+ BOOLEAN fgIsP2POnOffing; -+ -+ GLUE_SPIN_LOCK_DECLARATION(); -+ -+ GLUE_ACQUIRE_THE_SPIN_LOCK(&g_p2p_lock); -+ g_u4P2PEnding = 1; -+ fgIsP2POnOffing = g_u4P2POnOffing; -+ GLUE_RELEASE_THE_SPIN_LOCK(&g_p2p_lock); -+ -+ DBGLOG(INIT, TRACE, "waiting for fgIsP2POnOffing...\n"); -+ -+ /* History: cannot use down() here, sometimes we cannot come back here */ -+ /* waiting for p2p off command finishes, we cannot skip the remove */ -+ while (1) { -+ if (fgIsP2POnOffing == 0) -+ break; -+ GLUE_ACQUIRE_THE_SPIN_LOCK(&g_p2p_lock); -+ fgIsP2POnOffing = g_u4P2POnOffing; -+ GLUE_RELEASE_THE_SPIN_LOCK(&g_p2p_lock); -+ } -+ } -+#endif -+ -+#if CFG_ENABLE_BT_OVER_WIFI -+ if (prGlueInfo->rBowInfo.fgIsNetRegistered) { -+ bowNotifyAllLinkDisconnected(prGlueInfo->prAdapter); -+ /* wait 300ms for BoW module to send deauth */ -+ kalMsleep(300); -+ } -+#endif -+ -+ /* 4 <1> Stopping handling interrupt and free IRQ */ -+ DBGLOG(INIT, TRACE, "free IRQ...\n"); -+ glBusFreeIrq(prDev, *((P_GLUE_INFO_T *) netdev_priv(prDev))); -+ -+ kalMemSet(&(prGlueInfo->prAdapter->rWlanInfo), 0, sizeof(WLAN_INFO_T)); -+ -+ kalSetHalted(TRUE); /* before flush_delayed_work() */ -+ if (fgIsWorkMcStart == TRUE) { -+ DBGLOG(INIT, TRACE, "flush_delayed_work...\n"); -+ flush_delayed_work(&workq); /* flush_delayed_work_sync is deprecated */ -+ } -+ -+ flush_delayed_work(&sched_workq); -+ -+ DBGLOG(INIT, INFO, "down g_halt_sem...\n"); -+ kalHaltLock(KAL_WLAN_REMOVE_TIMEOUT_MSEC); -+#if CFG_SPM_WORKAROUND_FOR_HOTSPOT -+ if (glIsChipNeedWakelock(prGlueInfo)) -+ KAL_WAKE_LOCK_DESTROY(prGlueInfo->prAdapter, &prGlueInfo->prAdapter->rApWakeLock); -+#endif -+ -+/* flush_delayed_work_sync(&workq); */ -+/* flush_delayed_work(&workq); */ /* flush_delayed_work_sync is deprecated */ -+ -+ /* 4 <2> Mark HALT, notify main thread to stop, and clean up queued requests */ -+/* prGlueInfo->u4Flag |= GLUE_FLAG_HALT; */ -+ set_bit(GLUE_FLAG_HALT_BIT, &prGlueInfo->ulFlag); -+ DBGLOG(INIT, TRACE, "waiting for tx_thread stop...\n"); -+ -+ /* wake up main thread */ -+ wake_up_interruptible(&prGlueInfo->waitq); -+ -+ DBGLOG(INIT, TRACE, "wait_for_completion_interruptible\n"); -+ -+ /* wait main thread stops */ -+ wait_for_completion_interruptible(&prGlueInfo->rHaltComp); -+ -+ DBGLOG(INIT, TRACE, "mtk_sdiod stopped\n"); -+ -+ KAL_WAKE_LOCK_DESTROY(prGlueInfo->prAdapter, &prGlueInfo->prAdapter->rTxThreadWakeLock); -+ KAL_WAKE_LOCK_DESTROY(prGlueInfo->prAdapter, &prGlueInfo->rAhbIsrWakeLock); -+ -+ /* prGlueInfo->rHifInfo.main_thread = NULL; */ -+ prGlueInfo->main_thread = NULL; -+ -+#if CFG_ENABLE_BT_OVER_WIFI -+ if (prGlueInfo->rBowInfo.fgIsRegistered) -+ glUnregisterAmpc(prGlueInfo); -+#endif -+ -+ /* 4 <3> Remove /proc filesystem. */ -+#ifdef WLAN_INCLUDE_PROC -+ procRemoveProcfs(); -+#endif /* WLAN_INCLUDE_PROC */ -+ -+#if (CFG_SUPPORT_MET_PROFILING == 1) -+ kalMetRemoveProcfs(); -+#endif -+ -+ /* Force to do DMA reset */ -+ DBGLOG(INIT, TRACE, "glResetHif\n"); -+ glResetHif(prGlueInfo); -+ -+ /* 4 <4> wlanAdapterStop */ -+ prAdapter = prGlueInfo->prAdapter; -+#if CFG_SUPPORT_AGPS_ASSIST -+ kalIndicateAgpsNotify(prAdapter, AGPS_EVENT_WLAN_OFF, NULL, 0); -+#endif -+ -+ wlanAdapterStop(prAdapter); -+ DBGLOG(INIT, TRACE, "Number of Stalled Packets = %d\n", prGlueInfo->i4TxPendingFrameNum); -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ prGlueInfo->prAdapter->fgIsWlanLaunched = FALSE; -+ if (prGlueInfo->prAdapter->fgIsP2PRegistered) { -+ DBGLOG(INIT, TRACE, "p2pNetUnregister...\n"); -+#if !CFG_SUPPORT_PERSIST_NETDEV -+ p2pNetUnregister(prGlueInfo, FALSE); -+#endif -+ DBGLOG(INIT, INFO, "p2pRemove...\n"); -+ p2pRemove(prGlueInfo); -+ } -+#endif -+ -+ /* 4 <5> Release the Bus */ -+ glBusRelease(prDev); -+ -+ kalHaltUnlock(); -+ wlanDebugUninit(); -+ /* 4 <6> Unregister the card */ -+ wlanNetUnregister(prDev->ieee80211_ptr); -+ -+ /* 4 <7> Destroy the device */ -+ wlanNetDestroy(prDev->ieee80211_ptr); -+ prDev = NULL; -+ -+ DBGLOG(INIT, LOUD, "wlanUnregisterNotifier...\n"); -+ wlanUnregisterNotifier(); -+ -+ DBGLOG(INIT, INFO, "wlanRemove ok\n"); -+} /* end of wlanRemove() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Driver entry point when the driver is configured as a Linux Module, and -+* is called once at module load time, by the user-level modutils -+* application: insmod or modprobe. -+* -+* \retval 0 Success -+*/ -+/*----------------------------------------------------------------------------*/ -+/* 1 Module Entry Point */ -+static int initWlan(void) -+{ -+ int ret = 0, i; -+#if DBG -+ for (i = 0; i < DBG_MODULE_NUM; i++) -+ aucDebugModule[i] = DBG_CLASS_MASK; /* enable all */ -+#else -+ /* Initial debug level is D1 */ -+ for (i = 0; i < DBG_MODULE_NUM; i++) -+ aucDebugModule[i] = DBG_CLASS_ERROR | DBG_CLASS_WARN | DBG_CLASS_INFO | DBG_CLASS_STATE; -+#endif /* DBG */ -+ DBGLOG(INIT, INFO, "initWlan\n"); -+ -+ spin_lock_init(&g_p2p_lock); -+ -+ /* memory pre-allocation */ -+ kalInitIOBuffer(); -+ procInitFs(); -+ createWirelessDevice(); -+ if (gprWdev) -+ glP2pCreateWirelessDevice((P_GLUE_INFO_T) wiphy_priv(gprWdev->wiphy)); -+ -+ ret = ((glRegisterBus(wlanProbe, wlanRemove) == WLAN_STATUS_SUCCESS) ? 0 : -EIO); -+ -+ if (ret == -EIO) { -+ kalUninitIOBuffer(); -+ return ret; -+ } -+#if (CFG_CHIP_RESET_SUPPORT) -+ glResetInit(); -+#endif -+ -+ /* register set_dbg_level handler to mtk_wmt_wifi */ -+ register_set_dbg_level_handler(set_dbg_level_handler); -+ -+ /* Set the initial DEBUG CLASS of each module */ -+ return ret; -+} /* end of initWlan() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Driver exit point when the driver as a Linux Module is removed. Called -+* at module unload time, by the user level modutils application: rmmod. -+* This is our last chance to clean up after ourselves. -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+/* 1 Module Leave Point */ -+static VOID exitWlan(void) -+{ -+ DBGLOG(INIT, INFO, "exitWlan\n"); -+ -+ /* unregister set_dbg_level handler to mtk_wmt_wifi */ -+ register_set_dbg_level_handler(NULL); -+ -+#if CFG_CHIP_RESET_SUPPORT -+ glResetUninit(); -+#endif -+ destroyWirelessDevice(); -+ glP2pDestroyWirelessDevice(); -+ -+ glUnregisterBus(wlanRemove); -+ -+ /* free pre-allocated memory */ -+ kalUninitIOBuffer(); -+ -+ DBGLOG(INIT, INFO, "exitWlan\n"); -+ procUninitProcFs(); -+ -+} /* end of exitWlan() */ -+ -+#ifdef MTK_WCN_BUILT_IN_DRIVER -+ -+int mtk_wcn_wlan_gen2_init(void) -+{ -+ return initWlan(); -+} -+EXPORT_SYMBOL(mtk_wcn_wlan_gen2_init); -+ -+void mtk_wcn_wlan_gen2_exit(void) -+{ -+ return exitWlan(); -+} -+EXPORT_SYMBOL(mtk_wcn_wlan_gen2_exit); -+ -+#else -+ -+module_init(initWlan); -+module_exit(exitWlan); -+ -+#endif -+ -+MODULE_AUTHOR(NIC_AUTHOR); -+MODULE_DESCRIPTION(NIC_DESC); -+MODULE_SUPPORTED_DEVICE(NIC_NAME); -+MODULE_LICENSE("GPL"); -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_kal.c b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_kal.c -new file mode 100644 -index 000000000000..3a257c9f85c4 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_kal.c -@@ -0,0 +1,4799 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux/gl_kal.c#3 -+*/ -+ -+/*! \file gl_kal.c -+ \brief GLUE Layer will export the required procedures here for internal driver stack. -+ -+ This file contains all routines which are exported from GLUE Layer to internal -+ driver stack. -+*/ -+ -+/* -+** Log: gl_kal.c -+** -+** 08 20 2012 yuche.tsai -+** NULL -+** Fix possible KE issue. -+ * -+ * 07 17 2012 yuche.tsai -+ * NULL -+ * Let netdev bring up. -+ * -+ * 07 17 2012 yuche.tsai -+ * NULL -+ * Compile no error before trial run. -+ * -+ * 06 13 2012 yuche.tsai -+ * NULL -+ * Update maintrunk driver. -+ * Add support for driver compose assoc request frame. -+ * -+ * 05 31 2012 terry.wu -+ * NULL -+ * . -+ * -+ * 03 26 2012 cp.wu -+ * [WCXRP00001187] [MT6620 Wi-Fi][Driver][Android] Add error handling while firmware image doesn't exist -+ * invoke put_cred() after get_current_cred() calls. -+ * -+ * 03 07 2012 yuche.tsai -+ * NULL -+ * Fix compile error when WiFi Direct is off. -+ * -+ * 03 02 2012 terry.wu -+ * NULL -+ * Snc CFG80211 modification for ICS migration from branch 2.2. -+ * -+ * 02 20 2012 cp.wu -+ * [WCXRP00001187] [MT6620 Wi-Fi][Driver][Android] Add error handling while firmware image doesn't exist -+ * do not need to invoke free() while firmware image file doesn't exist -+ * -+ * 01 05 2012 wh.su -+ * [WCXRP00001153] [MT6620 Wi-Fi][Driver] Adding the get_ch_list and set_tx_power proto type function -+ * Adding the related ioctl / wlan oid function to set the Tx power cfg. -+ * -+ * 01 02 2012 wh.su -+ * [WCXRP00001153] [MT6620 Wi-Fi][Driver] Adding the get_ch_list and set_tx_power proto type function -+ * Adding the proto type function for set_int set_tx_power and get int get_ch_list. -+ * -+ * 11 21 2011 cp.wu -+ * [WCXRP00001118] [MT6620 Wi-Fi][Driver] Corner case protections to pass Monkey testing -+ * 1. wlanoidQueryBssIdList might be passed with a non-zero length but a NULL pointer of buffer -+ * add more checking for such cases -+ * -+ * 2. kalSendComplete() might be invoked with a packet belongs to P2P network right after P2P is unregistered. -+ * add some tweaking to protect such cases because that net device has become invalid. -+ * -+ * 11 18 2011 yuche.tsai -+ * NULL -+ * CONFIG P2P support RSSI query, default turned off. -+ * -+ * 11 16 2011 yuche.tsai -+ * NULL -+ * Avoid using work thread. -+ * -+ * 11 10 2011 cp.wu -+ * [WCXRP00001098] [MT6620 Wi-Fi][Driver] Replace printk by DBG LOG macros in linux porting layer -+ * 1. eliminaite direct calls to printk in porting layer. -+ * 2. replaced by DBGLOG, which would be XLOG on ALPS platforms. -+ * -+ * 10 12 2011 wh.su -+ * [WCXRP00001036] [MT6620 Wi-Fi][Driver][FW] Adding the 802.11w code for MFP -+ * adding the 802.11w related function and define . -+ * -+ * 09 23 2011 yuche.tsai -+ * [WCXRP00000998] [Volunteer Patch][WiFi Direct][FW] P2P Social Channel & country domain issue -+ * Regulation domain feature check in. -+ * -+ * 08 12 2011 cp.wu -+ * [WCXRP00000913] [MT6620 Wi-Fi] create repository of source code dedicated for MT6620 E6 ASIC -+ * load WIFI_RAM_CODE_E6 for MT6620 E6 ASIC. -+ * -+ * 07 18 2011 chinghwa.yu -+ * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm -+ * Add CMD/Event for RDD and BWCS. -+ * -+ * 06 13 2011 eddie.chen -+ * [WCXRP00000779] [MT6620 Wi-Fi][DRV] Add tx rx statistics in linux and use netif_rx_ni -+ * Add tx rx statistics and netif_rx_ni. -+ * -+ * 04 15 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Add BOW short range mode. -+ * -+ * 04 12 2011 cp.wu -+ * [WCXRP00000635] [MT6620 Wi-Fi][Driver] Clear pending security frames when QM clear pending data frames for dedicated -+ * network type -+ * clear pending security frames for dedicated network type when BSS is being deactivated/disconnected -+ * -+ * 04 08 2011 cp.wu -+ * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer -+ * correct i4TxPendingFrameNum decreasing. -+ * -+ * 03 23 2011 cp.wu -+ * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer -+ * apply multi-queue operation only for linux kernel > 2.6.26 -+ * -+ * 03 21 2011 cp.wu -+ * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer -+ * portability for compatible with linux 2.6.12. -+ * -+ * 03 21 2011 cp.wu -+ * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer -+ * improve portability for awareness of early version of linux kernel and wireless extension. -+ * -+ * 03 18 2011 cp.wu -+ * [WCXRP00000562] [MT6620 Wi-Fi][Driver] I/O buffer pre-allocation to avoid physically continuous memory shortage -+ * after system running for a long period -+ * refix ... -+ * -+ * 03 18 2011 cp.wu -+ * [WCXRP00000562] [MT6620 Wi-Fi][Driver] I/O buffer pre-allocation to avoid physically continuous memory shortage -+ * after system running for a long period -+ * correct compiling warning/error. -+ * -+ * 03 18 2011 cp.wu -+ * [WCXRP00000562] [MT6620 Wi-Fi][Driver] I/O buffer pre-allocation to avoid physically continuous memory shortage -+ * after system running for a long period -+ * add more robust fault tolerance design when pre-allocation failed. (rarely happen) -+ * -+ * 03 17 2011 cp.wu -+ * [WCXRP00000562] [MT6620 Wi-Fi][Driver] I/O buffer pre-allocation to avoid physically continuous memory shortage -+ * after system running for a long period -+ * use pre-allocated buffer for storing enhanced interrupt response as well -+ * -+ * 03 16 2011 cp.wu -+ * [WCXRP00000562] [MT6620 Wi-Fi][Driver] I/O buffer pre-allocation to avoid physically continuous memory shortage -+ * after system running for a long period -+ * 1. pre-allocate physical continuous buffer while module is being loaded -+ * 2. use pre-allocated physical continuous buffer for TX/RX DMA transfer -+ * -+ * The windows part remained the same as before, but added similar APIs to hide the difference. -+ * -+ * 03 15 2011 cp.wu -+ * [WCXRP00000559] [MT6620 Wi-Fi][Driver] Combine TX/RX DMA buffers into a single one to reduce physically continuous -+ * memory consumption -+ * 1. deprecate CFG_HANDLE_IST_IN_SDIO_CALLBACK -+ * 2. Use common coalescing buffer for both TX/RX directions -+ * -+ * -+ * 03 14 2011 jeffrey.chang -+ * [WCXRP00000546] [MT6620 Wi-Fi][MT6620 Wi-Fi][Driver] fix kernel build warning message -+ * fix kernel build warning message -+ * -+ * 03 07 2011 terry.wu -+ * [WCXRP00000521] [MT6620 Wi-Fi][Driver] Remove non-standard debug message -+ * Toggle non-standard debug messages to comments. -+ * -+ * 03 06 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Sync BOW Driver to latest person development branch version.. -+ * -+ * 03 03 2011 jeffrey.chang -+ * [WCXRP00000512] [MT6620 Wi-Fi][Driver] modify the net device relative functions to support the H/W multiple queue -+ * support concurrent network -+ * -+ * 03 03 2011 jeffrey.chang -+ * [WCXRP00000512] [MT6620 Wi-Fi][Driver] modify the net device relative functions to support the H/W multiple queue -+ * modify net device relative functions to support multiple H/W queues -+ * -+ * 03 02 2011 cp.wu -+ * [WCXRP00000503] [MT6620 Wi-Fi][Driver] Take RCPI brought by association response as initial RSSI right after -+ * connection is built. -+ * use RCPI brought by ASSOC-RESP after connection is built as initial RCPI to avoid using a uninitialized MAC-RX RCPI. -+ * -+ * 02 21 2011 cp.wu -+ * [WCXRP00000482] [MT6620 Wi-Fi][Driver] Simplify logic for checking NVRAM existence in driver domain -+ * simplify logic for checking NVRAM existence only once. -+ * -+ * 01 24 2011 cp.wu -+ * [WCXRP00000382] [MT6620 Wi-Fi][Driver] Track forwarding packet number with notifying tx thread for serving -+ * 1. add an extra counter for tracking pending forward frames. -+ * 2. notify TX service thread as well when there is pending forward frame -+ * 3. correct build errors leaded by introduction of Wi-Fi direct separation module -+ * -+ * 01 19 2011 cp.wu -+ * [WCXRP00000371] [MT6620 Wi-Fi][Driver] make linux glue layer portable for Android 2.3.1 with Linux 2.6.35.7 -+ * add compile option to check linux version 2.6.35 for different usage of system API to improve portability -+ * -+ * 01 12 2011 cp.wu -+ * [WCXRP00000357] [MT6620 Wi-Fi][Driver][Bluetooth over Wi-Fi] add another net device interface for BT AMP -+ * implementation of separate BT_OVER_WIFI data path. -+ * -+ * 01 10 2011 cp.wu -+ * [WCXRP00000349] [MT6620 Wi-Fi][Driver] make kalIoctl() of linux port as a thread safe API to avoid potential issues -+ * due to multiple access -+ * use mutex to protect kalIoctl() for thread safe. -+ * -+ * 11 26 2010 cp.wu -+ * [WCXRP00000209] [MT6620 Wi-Fi][Driver] Modify NVRAM checking mechanism to warning only with necessary data field -+ * checking -+ * 1. NVRAM error is now treated as warning only, thus normal operation is still available but extra scan result used -+ * to indicate user is attached -+ * 2. DPD and TX-PWR are needed fields from now on, if these 2 fields are not available then warning message is shown -+ * -+ * 11 04 2010 wh.su -+ * [WCXRP00000164] [MT6620 Wi-Fi][Driver] Support the p2p random SSID -+ * adding the p2p random ssid support. -+ * -+ * 11 02 2010 jeffrey.chang -+ * [WCXRP00000145] [MT6620 Wi-Fi][Driver] fix issue of byte endian in packet classifier which discards BoW packets -+ * . -+ * -+ * 11 01 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000150] [MT6620 Wi-Fi][Driver] -+ * Add implementation for querying current TX rate from firmware auto rate module -+ * 1) Query link speed (TX rate) from firmware directly with buffering mechanism to reduce overhead -+ * 2) Remove CNM CH-RECOVER event handling -+ * 3) cfg read/write API renamed with kal prefix for unified naming rules. -+ * -+ * 11 01 2010 yarco.yang -+ * [WCXRP00000149] [MT6620 WI-Fi][Driver]Fine tune performance on MT6516 platform -+ * Add code to run WlanIST in SDIO callback. -+ * -+ * 10 26 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000137] [MT6620 Wi-Fi] [FW] -+ * Support NIC capability query command -+ * 1) update NVRAM content template to ver 1.02 -+ * 2) add compile option for querying NIC capability (default: off) -+ * 3) modify AIS 5GHz support to run-time option, which could be turned on by registry or NVRAM setting -+ * 4) correct auto-rate compiler error under linux (treat warning as error) -+ * 5) simplify usage of NVRAM and REG_INFO_T -+ * 6) add version checking between driver and firmware -+ * -+ * 10 25 2010 jeffrey.chang -+ * [WCXRP00000129] [MT6620] [Driver] Kernel panic when rmmod module on Andriod platform -+ * Remove redundant code which cause mismatch of power control release -+ * -+ * 10 25 2010 jeffrey.chang -+ * [WCXRP00000129] [MT6620] [Driver] Kernel panic when rmmod module on Andriod platform -+ * Remove redundant GLUE_HALT condfition to avoid unmatched release of power control -+ * -+ * 10 18 2010 jeffrey.chang -+ * [WCXRP00000116] [MT6620 Wi-Fi][Driver] Refine the set_scan ioctl to resolve the Android UI hanging issue -+ * refine the scan ioctl to prevent hanging of Android UI -+ * -+ * 10 18 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000086] [MT6620 Wi-Fi][Driver] -+ * The mac address is all zero at android -+ * complete implementation of Android NVRAM access -+ * -+ * 10 06 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check -+ * if there is NVRAM, then use MAC address on NVRAM as default MAC address. -+ * -+ * 10 06 2010 cp.wu -+ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning -+ * code reorganization to improve isolation between GLUE and CORE layers. -+ * -+ * 10 05 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check -+ * 1) add NVRAM access API -+ * 2) fake scanning result when NVRAM doesn't exist and/or version mismatch. (off by compiler option) -+ * 3) add OID implementation for NVRAM read/write service -+ * -+ * 09 21 2010 cp.wu -+ * [WCXRP00000053] [MT6620 Wi-Fi][Driver] Reset incomplete and might leads to BSOD when entering RF test with AIS -+ * associated -+ * Do a complete reset with STA-REC null checking for RF test re-entry -+ * -+ * 09 21 2010 kevin.huang -+ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning -+ * Eliminate Linux Compile Warning -+ * -+ * 09 07 2010 wh.su -+ * NULL -+ * adding the code for beacon/probe req/ probe rsp wsc ie at p2p. -+ * -+ * 09 03 2010 kevin.huang -+ * NULL -+ * Refine #include sequence and solve recursive/nested #include issue -+ * -+ * 08 30 2010 cp.wu -+ * NULL -+ * API added: nicTxPendingPackets(), for simplifying porting layer -+ * -+ * 08 20 2010 yuche.tsai -+ * NULL -+ * Support second interface indicate when enabling P2P. -+ * -+ * 08 18 2010 yarco.yang -+ * NULL -+ * 1. Fixed HW checksum offload function not work under Linux issue. -+ * 2. Add debug message. -+ * -+ * 08 16 2010 jeffrey.chang -+ * NULL -+ * remove redundant code which cause kernel panic -+ * -+ * 08 16 2010 cp.wu -+ * NULL -+ * P2P packets are now marked when being queued into driver, and identified later without checking MAC address -+ * -+ * 08 02 2010 jeffrey.chang -+ * NULL -+ * 1) modify tx service thread to avoid busy looping -+ * 2) add spin lock declartion for linux build -+ * -+ * 07 29 2010 cp.wu -+ * NULL -+ * simplify post-handling after TX_DONE interrupt is handled. -+ * -+ * 07 28 2010 jeffrey.chang -+ * NULL -+ * 1) remove unused spinlocks -+ * 2) enable encyption ioctls -+ * 3) fix scan ioctl which may cause supplicant to hang -+ * -+ * 07 23 2010 cp.wu -+ * -+ * 1) re-enable AIS-FSM beacon timeout handling. -+ * 2) scan done API revised -+ * -+ * 07 23 2010 jeffrey.chang -+ * -+ * add new KAL api -+ * -+ * 07 23 2010 jeffrey.chang -+ * -+ * bug fix: allocate regInfo when disabling firmware download -+ * -+ * 07 23 2010 jeffrey.chang -+ * -+ * use glue layer api to decrease or increase counter atomically -+ * -+ * 07 22 2010 jeffrey.chang -+ * -+ * modify tx thread and remove some spinlock -+ * -+ * 07 22 2010 jeffrey.chang -+ * -+ * use different spin lock for security frame -+ * -+ * 07 22 2010 jeffrey.chang -+ * -+ * add new spinlock -+ * -+ * 07 19 2010 jeffrey.chang -+ * -+ * add spinlock for pending security frame count -+ * -+ * 07 19 2010 jeffrey.chang -+ * -+ * adjust the timer unit to microsecond -+ * -+ * 07 19 2010 jeffrey.chang -+ * -+ * timer should return value greater than zero -+ * -+ * 07 19 2010 jeffrey.chang -+ * -+ * add kal api for scanning done -+ * -+ * 07 19 2010 jeffrey.chang -+ * -+ * modify cmd/data path for new design -+ * -+ * 07 19 2010 jeffrey.chang -+ * -+ * add new kal api -+ * -+ * 07 19 2010 jeffrey.chang -+ * -+ * for linux driver migration -+ * -+ * 07 19 2010 jeffrey.chang -+ * -+ * Linux port modification -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 23 2010 yarco.yang -+ * [WPD00003837][MT6620]Data Path Refine -+ * Merge g_arStaRec[] into adapter->arStaRec[] -+ * -+ * 06 21 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * change MAC address updating logic. -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 06 01 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * remove unused files. -+ * -+ * 05 29 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * fix private ioctl for rftest -+ * -+ * 05 29 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * workaround for fixing request_firmware() failure on android 2.1 -+ * -+ * 05 28 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * fix kernel panic when debug mode enabled -+ * -+ * 05 26 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * 1) Modify set mac address code -+ * 2) remove power management macro -+ * -+ * 05 17 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * 1) add timeout handler mechanism for pending command packets -+ * 2) add p2p add/removal key -+ * -+ * 05 14 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * Disable network interface after disassociation -+ * -+ * 05 10 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * fill network type field while doing frame identification. -+ * -+ * 05 07 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * prevent supplicant accessing driver during resume -+ * -+ * 04 27 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * identify BT Over Wi-Fi Security frame and mark it as 802.1X frame -+ * -+ * 04 27 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * 1) fix firmware download bug -+ * 2) remove query statistics for acelerating firmware download -+ * -+ * 04 27 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * follow Linux's firmware framework, and remove unused kal API -+ * -+ * 04 22 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * -+ * 1) modify rx path code for supporting Wi-Fi direct -+ * 2) modify config.h since Linux dont need to consider retaining packet -+ * -+ * 04 21 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * add for private ioctl support -+ * -+ * 04 15 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * change firmware name -+ * -+ * 04 14 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * flush pending TX packets while unloading driver -+ * -+ * 04 14 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * Set driver own before handling cmd queue -+ * -+ * 04 14 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * 1) prGlueInfo->pvInformationBuffer and prGlueInfo->u4InformationBufferLength are no longer used -+ * 2) fix ioctl -+ * -+ * 04 14 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * information buffer for query oid/ioctl is now buffered in prCmdInfo -+ * * * * * * * instead of glue-layer variable to improve multiple oid/ioctl capability -+ * -+ * 04 13 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * add framework for BT-over-Wi-Fi support. -+ * * * * * * * * * * * * * * * * * * 1) prPendingCmdInfo is replaced by queue for multiple handler -+ * * * * * * * * * * * * * * * * * * capability -+ * * * * * * * * * * * * * * * * * * 2) command sequence number is now increased atomically -+ * * * * * * * * * * * * * * * * * * 3) private data could be hold and taken use for other purpose -+ * -+ * 04 09 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * fix spinlock usage -+ * -+ * 04 09 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * add spinlock for i4TxPendingFrameNum access -+ * -+ * 04 09 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * 1) add spinlock -+ * * 2) add KAPI for handling association info -+ * -+ * 04 09 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * fix spinlock usage -+ * -+ * 04 09 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * adding firmware download KAPI -+ * -+ * 04 07 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * Set MAC address from firmware -+ * -+ * 04 07 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1. free cmdinfo after command is emiited. -+ * 2. for BoW frames, user priority is extracted from sk_buff directly. -+ * -+ * 04 07 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * finish non-glue layer access to glue variables -+ * -+ * 04 07 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * accessing to firmware load/start address, and access to OID handling information -+ * * * are now handled in glue layer -+ * -+ * 04 07 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * rWlanInfo should be placed at adapter rather than glue due to most operations -+ * * * * * * * are done in adapter layer. -+ * -+ * 04 07 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * eliminate direct access to prGlueInfo->eParamMediaStateIndicated from non-glue layer -+ * -+ * 04 06 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * (1)deliver the kalOidComplete status to upper layer -+ * (2) fix spin lock -+ * -+ * 04 06 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * add KAL API: kalFlushPendingTxPackets(), and take use of the API -+ * -+ * 04 06 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * eliminate direct access to prGlueInfo->rWlanInfo.eLinkAttr.ucMediaStreamMode from non-glue layer. -+ * -+ * 04 06 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * add timeout check in the kalOidComplete -+ * -+ * 04 06 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * improve none-glue code portability -+ * -+ * 04 06 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * code refine: fgTestMode should be at adapter rather than glue due to the device/fw is also involved -+ * -+ * 04 06 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * eliminate direct access for prGlueInfo->fgIsCardRemoved in non-glue layer -+ * -+ * 04 06 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) for some OID, never do timeout expiration -+ * * * 2) add 2 kal API for later integration -+ * -+ * 04 06 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * raising the priority of processing interrupt -+ * -+ * 04 01 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * Bug fix: the tx thread will cause starvation of MMC thread, and the interrupt will never come in -+ * -+ * 03 30 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * emulate NDIS Pending OID facility -+ * -+ * 03 28 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * adding secondary command queue for improving non-glue code portability -+ * -+ * 03 26 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * [WPD00003826] Initial import for Linux port -+ * adding firmware download kal api -+ * -+ * 03 25 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * add Bluetooth-over-Wifi frame header check -+ * -+ * 03 24 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * initial import for Linux port -+** \main\maintrunk.MT5921\50 2009-09-28 20:19:08 GMT mtk01090 -+** Add private ioctl to carry OID structures. Restructure public/private ioctl interfaces to Linux kernel. -+** \main\maintrunk.MT5921\49 2009-08-18 22:56:44 GMT mtk01090 -+** Add Linux SDIO (with mmc core) support. -+** Add Linux 2.6.21, 2.6.25, 2.6.26. -+** Fix compile warning in Linux. -+** \main\maintrunk.MT5921\48 2009-06-23 23:18:58 GMT mtk01090 -+** Add build option BUILD_USE_EEPROM and compile option CFG_SUPPORT_EXT_CONFIG for NVRAM support -+** \main\maintrunk.MT5921\47 2008-11-19 11:55:43 GMT mtk01088 -+** fixed some lint warning, and rename some variable with pre-fix to avoid the misunderstanding -+** \main\maintrunk.MT5921\46 2008-09-02 21:07:42 GMT mtk01461 -+** Remove ASSERT(pvBuf) in kalIndicateStatusAndComplete(), this parameter can be NULL -+** \main\maintrunk.MT5921\45 2008-08-29 16:03:21 GMT mtk01088 -+** remove non-used code for code review, add assert check -+** \main\maintrunk.MT5921\44 2008-08-21 00:32:49 GMT mtk01461 -+** \main\maintrunk.MT5921\43 2008-05-30 20:27:02 GMT mtk01461 -+** Rename KAL function -+** \main\maintrunk.MT5921\42 2008-05-30 15:47:29 GMT mtk01461 -+** \main\maintrunk.MT5921\41 2008-05-30 15:13:04 GMT mtk01084 -+** rename wlanoid -+** \main\maintrunk.MT5921\40 2008-05-29 14:15:14 GMT mtk01084 -+** remove un-used KAL function -+** \main\maintrunk.MT5921\39 2008-05-03 15:17:30 GMT mtk01461 -+** Move Query Media Status to GLUE -+** \main\maintrunk.MT5921\38 2008-04-24 11:59:44 GMT mtk01461 -+** change awake queue threshold and remove code which mark #if 0 -+** \main\maintrunk.MT5921\37 2008-04-17 23:06:35 GMT mtk01461 -+** Add iwpriv support for AdHocMode setting -+** \main\maintrunk.MT5921\36 2008-04-08 15:38:56 GMT mtk01084 -+** add KAL function to setting pattern search function enable/ disable -+** \main\maintrunk.MT5921\35 2008-04-01 23:53:13 GMT mtk01461 -+** Add comment -+** \main\maintrunk.MT5921\34 2008-03-26 15:36:48 GMT mtk01461 -+** Add update MAC Address for Linux -+** \main\maintrunk.MT5921\33 2008-03-18 11:49:34 GMT mtk01084 -+** update function for initial value access -+** \main\maintrunk.MT5921\32 2008-03-18 10:25:22 GMT mtk01088 -+** use kal update associate request at linux -+** \main\maintrunk.MT5921\31 2008-03-06 23:43:08 GMT mtk01385 -+** 1. add Query Registry Mac address function. -+** \main\maintrunk.MT5921\30 2008-02-26 09:47:57 GMT mtk01084 -+** modify KAL set network address/ checksum offload part -+** \main\maintrunk.MT5921\29 2008-02-12 23:26:53 GMT mtk01461 -+** Add debug option - Packet Order for Linux -+** \main\maintrunk.MT5921\28 2008-01-09 17:54:43 GMT mtk01084 -+** modify the argument of kalQueryPacketInfo() -+** \main\maintrunk.MT5921\27 2007-12-24 16:02:03 GMT mtk01425 -+** 1. Revise csum offload -+** \main\maintrunk.MT5921\26 2007-11-30 17:03:36 GMT mtk01425 -+** 1. Fix bugs -+** -+** \main\maintrunk.MT5921\25 2007-11-29 01:57:17 GMT mtk01461 -+** Fix Windows RX multiple packet retain problem -+** \main\maintrunk.MT5921\24 2007-11-20 11:24:07 GMT mtk01088 -+** CR90, not doing the netif_carrier_off to let supplicant 1x pkt can be rcv at hardstattXmit -+** \main\maintrunk.MT5921\23 2007-11-09 16:36:44 GMT mtk01425 -+** 1. Modify for CSUM offloading with Tx Fragment -+** \main\maintrunk.MT5921\22 2007-11-07 18:37:39 GMT mtk01461 -+** Add Tx Fragmentation Support -+** \main\maintrunk.MT5921\21 2007-11-06 19:34:06 GMT mtk01088 -+** add the WPS code, indicate the mgmt frame to upper layer -+** \main\maintrunk.MT5921\20 2007-11-02 01:03:21 GMT mtk01461 -+** Unify TX Path for Normal and IBSS Power Save + IBSS neighbor learning -+** \main\maintrunk.MT5921\19 2007-10-30 11:59:38 GMT MTK01425 -+** 1. Update wlanQueryInformation -+** \main\maintrunk.MT5921\18 2007-10-30 10:44:57 GMT mtk01425 -+** 1. Refine multicast list code -+** 2. Refine TCP/IP csum offload code -+** -+** Revision 1.5 2007/07/17 13:01:18 MTK01088 -+** add associate req and rsp function -+** -+** Revision 1.4 2007/07/13 05:19:19 MTK01084 -+** provide timer set functions -+** -+** Revision 1.3 2007/06/27 02:18:51 MTK01461 -+** Update SCAN_FSM, Initial(Can Load Module), Proc(Can do Reg R/W), TX API -+** -+** Revision 1.2 2007/06/25 06:16:24 MTK01461 -+** Update illustrations, gl_init.c, gl_kal.c, gl_kal.h, gl_os.h and RX API -+** -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include -+#include "gl_os.h" -+#include "gl_wext.h" -+#include "precomp.h" -+#if defined(CONFIG_MTK_TC1_FEATURE) -+#include -+#endif -+#if CFG_SUPPORT_AGPS_ASSIST -+#include -+#endif -+#if CFG_SUPPORT_WAKEUP_REASON_DEBUG -+#include -+#endif -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+#if DBG -+int allocatedMemSize = 0; -+#endif -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+/* #define MTK_DMA_BUF_MEMCPY_SUP */ -+static PVOID pvIoBuffer; -+ -+#ifdef MTK_DMA_BUF_MEMCPY_SUP -+static PVOID pvIoPhyBuf; -+static PVOID pvDmaBuffer; -+static PVOID pvDmaPhyBuf; -+#endif /* MTK_DMA_BUF_MEMCPY_SUP */ -+ -+static UINT_32 pvIoBufferSize; -+static UINT_32 pvIoBufferUsage; -+static struct KAL_HALT_CTRL_T rHaltCtrl = { -+ .lock = __SEMAPHORE_INITIALIZER(rHaltCtrl.lock, 1), -+ .owner = NULL, -+ .fgHalt = TRUE, -+ .fgHeldByKalIoctl = FALSE, -+ .u4HoldStart = 0, -+}; -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+#if defined(MT6620) && CFG_MULTI_ECOVER_SUPPORT -+typedef enum _ENUM_WMTHWVER_TYPE_T { -+ WMTHWVER_MT6620_E1 = 0x0, -+ WMTHWVER_MT6620_E2 = 0x1, -+ WMTHWVER_MT6620_E3 = 0x2, -+ WMTHWVER_MT6620_E4 = 0x3, -+ WMTHWVER_MT6620_E5 = 0x4, -+ WMTHWVER_MT6620_E6 = 0x5, -+ WMTHWVER_MT6620_MAX, -+ WMTHWVER_INVALID = 0xff -+} ENUM_WMTHWVER_TYPE_T, *P_ENUM_WMTHWVER_TYPE_T; -+#endif -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+VOID kalHifAhbKalWakeLockTimeout(IN P_GLUE_INFO_T prGlueInfo) -+{ -+ KAL_WAKE_LOCK_TIMEOUT(prGlueInfo->prAdapter, &(prGlueInfo->rAhbIsrWakeLock), (HZ / 10)); /* 100ms */ -+} -+ -+#if CFG_ENABLE_FW_DOWNLOAD -+ -+static struct file *filp; -+static uid_t orgfsuid; -+static gid_t orgfsgid; -+static mm_segment_t orgfs; -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is provided by GLUE Layer for internal driver stack to -+* open firmware image in kernel space -+* -+* \param[in] prGlueInfo Pointer of GLUE Data Structure -+* -+* \retval WLAN_STATUS_SUCCESS. -+* \retval WLAN_STATUS_FAILURE. -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS kalFirmwareOpen(IN P_GLUE_INFO_T prGlueInfo) -+{ -+ UINT_8 aucFilePath[50]; -+ -+ /* FIX ME: since we don't have hotplug script in the filesystem -+ * , so the request_firmware() KAPI can not work properly -+ */ -+ -+ /* save uid and gid used for filesystem access. -+ * set user and group to 0(root) */ -+ struct cred *cred = (struct cred *)get_current_cred(); -+ -+ orgfsuid = cred->fsuid.val; -+ orgfsgid = cred->fsgid.val; -+ cred->fsuid.val = cred->fsgid.val = 0; -+ -+ ASSERT(prGlueInfo); -+ -+ orgfs = get_fs(); -+ set_fs(get_ds()); -+ -+ /* open the fw file */ -+#if defined(MT6620) & CFG_MULTI_ECOVER_SUPPORT -+ switch (mtk_wcn_wmt_hwver_get()) { -+ case WMTHWVER_MT6620_E1: -+ case WMTHWVER_MT6620_E2: -+ case WMTHWVER_MT6620_E3: -+ case WMTHWVER_MT6620_E4: -+ case WMTHWVER_MT6620_E5: -+ filp = filp_open("/etc/firmware/" CFG_FW_FILENAME, O_RDONLY, 0); -+ break; -+ -+ case WMTHWVER_MT6620_E6: -+ default: -+ filp = filp_open("/etc/firmware/" CFG_FW_FILENAME "_E6", O_RDONLY, 0); -+ break; -+ } -+#elif defined(MT6628) -+/* filp = filp_open("/etc/firmware/"CFG_FW_FILENAME"_MT6628", O_RDONLY, 0); */ -+/* filp = filp_open("/etc/firmware/"CFG_FW_FILENAME"_MT6582", O_RDONLY, 0); */ -+#if 0 /* new wifi ram code mechanism, waiting firmware ready, then we can enable these code */ -+ kalMemZero(aucFilePath, sizeof(aucFilePath)); -+ kalMemCopy(aucFilePath, "/etc/firmware/" CFG_FW_FILENAME "_AD", sizeof("/etc/firmware/" CFG_FW_FILENAME "_AD")); -+ filp = filp_open(aucFilePath, O_RDONLY, 0); -+ if (!IS_ERR(filp)) -+ goto open_success; -+#endif -+ kalMemZero(aucFilePath, sizeof(aucFilePath)); -+ kalMemCopy(aucFilePath, "/etc/firmware/" CFG_FW_FILENAME "_", strlen("/etc/firmware/" CFG_FW_FILENAME "_")); -+ glGetChipInfo(prGlueInfo, &aucFilePath[strlen("/etc/firmware/" CFG_FW_FILENAME "_")]); -+ -+ DBGLOG(INIT, INFO, "open file: %s\n", aucFilePath); -+ -+ filp = filp_open(aucFilePath, O_RDONLY, 0); -+#else -+ filp = filp_open("/etc/firmware/" CFG_FW_FILENAME, O_RDONLY, 0); -+#endif -+ if (IS_ERR(filp)) { -+ DBGLOG(INIT, ERROR, "Open FW image: %s failed\n", CFG_FW_FILENAME); -+ goto error_open; -+ } -+#if 0 -+open_success: -+#endif -+ DBGLOG(INIT, TRACE, "Open FW image: %s done\n", CFG_FW_FILENAME); -+ return WLAN_STATUS_SUCCESS; -+ -+error_open: -+ /* restore */ -+ set_fs(orgfs); -+ cred->fsuid.val = orgfsuid; -+ cred->fsgid.val = orgfsgid; -+ put_cred(cred); -+ return WLAN_STATUS_FAILURE; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is provided by GLUE Layer for internal driver stack to -+* release firmware image in kernel space -+* -+* \param[in] prGlueInfo Pointer of GLUE Data Structure -+* -+* \retval WLAN_STATUS_SUCCESS. -+* \retval WLAN_STATUS_FAILURE. -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS kalFirmwareClose(IN P_GLUE_INFO_T prGlueInfo) -+{ -+ ASSERT(prGlueInfo); -+ -+ if ((filp != NULL) && !IS_ERR(filp)) { -+ /* close firmware file */ -+ filp_close(filp, NULL); -+ -+ /* restore */ -+ set_fs(orgfs); -+ { -+ struct cred *cred = (struct cred *)get_current_cred(); -+ -+ cred->fsuid.val = orgfsuid; -+ cred->fsgid.val = orgfsgid; -+ put_cred(cred); -+ } -+ filp = NULL; -+ } -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is provided by GLUE Layer for internal driver stack to -+* load firmware image in kernel space -+* -+* \param[in] prGlueInfo Pointer of GLUE Data Structure -+* -+* \retval WLAN_STATUS_SUCCESS. -+* \retval WLAN_STATUS_FAILURE. -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS kalFirmwareLoad(IN P_GLUE_INFO_T prGlueInfo, OUT PVOID prBuf, IN UINT_32 u4Offset, OUT PUINT_32 pu4Size) -+{ -+ ASSERT(prGlueInfo); -+ ASSERT(pu4Size); -+ ASSERT(prBuf); -+ -+ /* l = filp->f_path.dentry->d_inode->i_size; */ -+#if 0 -+ /* the object must have a read method */ -+ if ((filp == NULL) || IS_ERR(filp) || (filp->f_op == NULL) || (filp->f_op->read == NULL)) { -+ goto error_read; -+ } else { -+ filp->f_pos = u4Offset; -+ *pu4Size = filp->f_op->read(filp, prBuf, *pu4Size, &filp->f_pos); -+ } -+#else -+ /* the object must have a read method */ -+ if ((filp == NULL) || IS_ERR(filp) || (filp->f_op == NULL) ) { -+ goto error_read; -+ } else { -+ filp->f_pos = u4Offset; -+ *pu4Size = vfs_read(filp, prBuf, *pu4Size, &filp->f_pos); -+ } -+#endif -+ -+ return WLAN_STATUS_SUCCESS; -+ -+error_read: -+ return WLAN_STATUS_FAILURE; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is provided by GLUE Layer for internal driver stack to -+* query firmware image size in kernel space -+* -+* \param[in] prGlueInfo Pointer of GLUE Data Structure -+* -+* \retval WLAN_STATUS_SUCCESS. -+* \retval WLAN_STATUS_FAILURE. -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+ -+WLAN_STATUS kalFirmwareSize(IN P_GLUE_INFO_T prGlueInfo, OUT PUINT_32 pu4Size) -+{ -+ ASSERT(prGlueInfo); -+ ASSERT(pu4Size); -+ -+ //*pu4Size = filp->f_path.dentry->d_inode->i_size; -+ *pu4Size = filp->f_op->llseek(filp, 0, 2); -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is used to load firmware image -+* -+* \param pvGlueInfo Pointer of GLUE Data Structure -+* \param ppvMapFileBuf Pointer of pointer to memory-mapped firmware image -+* \param pu4FileLength File length and memory mapped length as well -+ -+* \retval Map File Handle, used for unammping -+*/ -+/*----------------------------------------------------------------------------*/ -+ -+PVOID kalFirmwareImageMapping(IN P_GLUE_INFO_T prGlueInfo, OUT PPVOID ppvMapFileBuf, OUT PUINT_32 pu4FileLength) -+{ -+ UINT_32 u4FwSize = 0; -+ PVOID prFwBuffer = NULL; -+ -+ DEBUGFUNC("kalFirmwareImageMapping"); -+ -+ ASSERT(prGlueInfo); -+ ASSERT(ppvMapFileBuf); -+ ASSERT(pu4FileLength); -+ -+ do { -+ /* <1> Open firmware */ -+ if (kalFirmwareOpen(prGlueInfo) != WLAN_STATUS_SUCCESS) { -+ DBGLOG(INIT, TRACE, "kalFirmwareOpen fail!\n"); -+ break; -+ } -+ -+ /* <2> Query firmare size */ -+ kalFirmwareSize(prGlueInfo, &u4FwSize); -+ printk(KERN_ERR "%s firmware size %d\n", __FUNCTION__, u4FwSize); -+ /* <3> Use vmalloc for allocating large memory trunk */ -+ prFwBuffer = vmalloc(ALIGN_4(u4FwSize)); -+ /* <4> Load image binary into buffer */ -+ if (kalFirmwareLoad(prGlueInfo, prFwBuffer, 0, &u4FwSize) != WLAN_STATUS_SUCCESS) { -+ vfree(prFwBuffer); -+ kalFirmwareClose(prGlueInfo); -+ DBGLOG(INIT, TRACE, "kalFirmwareLoad fail!\n"); -+ break; -+ } -+ /* <5> write back info */ -+ *pu4FileLength = u4FwSize; -+ *ppvMapFileBuf = prFwBuffer; -+ -+ return prFwBuffer; -+ -+ } while (FALSE); -+ -+ return NULL; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is used to unload firmware image mapped memory -+* -+* \param pvGlueInfo Pointer of GLUE Data Structure -+* \param pvFwHandle Pointer to mapping handle -+* \param pvMapFileBuf Pointer to memory-mapped firmware image -+* -+* \retval none -+*/ -+/*----------------------------------------------------------------------------*/ -+ -+VOID kalFirmwareImageUnmapping(IN P_GLUE_INFO_T prGlueInfo, IN PVOID prFwHandle, IN PVOID pvMapFileBuf) -+{ -+ DEBUGFUNC("kalFirmwareImageUnmapping"); -+ -+ ASSERT(prGlueInfo); -+ -+ /* pvMapFileBuf might be NULL when file doesn't exist */ -+ if (pvMapFileBuf) -+ vfree(pvMapFileBuf); -+ -+ kalFirmwareClose(prGlueInfo); -+} -+ -+#endif -+ -+#if 0 -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is used to load firmware image -+* -+* \param pvGlueInfo Pointer of GLUE Data Structure -+* \param ppvMapFileBuf Pointer of pointer to memory-mapped firmware image -+* \param pu4FileLength File length and memory mapped length as well -+ -+* \retval Map File Handle, used for unammping -+*/ -+/*----------------------------------------------------------------------------*/ -+ -+PVOID kalFirmwareImageMapping(IN P_GLUE_INFO_T prGlueInfo, OUT PPVOID ppvMapFileBuf, OUT PUINT_32 pu4FileLength) -+{ -+ INT_32 i4Ret = 0; -+ -+ DEBUGFUNC("kalFirmwareImageMapping"); -+ -+ ASSERT(prGlueInfo); -+ ASSERT(ppvMapFileBuf); -+ ASSERT(pu4FileLength); -+ -+ do { -+ GL_HIF_INFO_T *prHifInfo = &prGlueInfo->rHifInfo; -+ -+ prGlueInfo->prFw = NULL; -+ -+ /* <1> Open firmware */ -+ i4Ret = request_firmware(&prGlueInfo->prFw, CFG_FW_FILENAME, prHifInfo->Dev); -+ -+ if (i4Ret) { -+ DBGLOG(INIT, TRACE, "fw %s:request failed %d\n", CFG_FW_FILENAME, i4Ret); -+ break; -+ } -+ *pu4FileLength = prGlueInfo->prFw->size; -+ *ppvMapFileBuf = prGlueInfo->prFw->data; -+ return prGlueInfo->prFw->data; -+ -+ } while (FALSE); -+ -+ return NULL; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is used to unload firmware image mapped memory -+* -+* \param pvGlueInfo Pointer of GLUE Data Structure -+* \param pvFwHandle Pointer to mapping handle -+* \param pvMapFileBuf Pointer to memory-mapped firmware image -+* -+* \retval none -+*/ -+/*----------------------------------------------------------------------------*/ -+ -+VOID kalFirmwareImageUnmapping(IN P_GLUE_INFO_T prGlueInfo, IN PVOID prFwHandle, IN PVOID pvMapFileBuf) -+{ -+ DEBUGFUNC("kalFirmwareImageUnmapping"); -+ -+ ASSERT(prGlueInfo); -+ ASSERT(pvMapFileBuf); -+ -+ release_firmware(prGlueInfo->prFw); -+ -+} -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is provided by GLUE Layer for internal driver stack to acquire -+* OS SPIN_LOCK. -+* -+* \param[in] prGlueInfo Pointer of GLUE Data Structure -+* \param[in] rLockCategory Specify which SPIN_LOCK -+* \param[out] pu4Flags Pointer of a variable for saving IRQ flags -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+kalAcquireSpinLock(IN P_GLUE_INFO_T prGlueInfo, IN ENUM_SPIN_LOCK_CATEGORY_E rLockCategory, OUT unsigned long *pu4Flags) -+{ -+ unsigned long u4Flags = 0; -+ -+ ASSERT(prGlueInfo); -+ ASSERT(pu4Flags); -+ -+ if (rLockCategory < SPIN_LOCK_NUM) { -+ -+#if CFG_USE_SPIN_LOCK_BOTTOM_HALF -+ spin_lock_bh(&prGlueInfo->rSpinLock[rLockCategory]); -+#else /* !CFG_USE_SPIN_LOCK_BOTTOM_HALF */ -+ spin_lock_irqsave(&prGlueInfo->rSpinLock[rLockCategory], u4Flags); -+#endif /* !CFG_USE_SPIN_LOCK_BOTTOM_HALF */ -+ -+ *pu4Flags = u4Flags; -+/* DBGLOG(INIT, TRACE, ("A+%d\n", rLockCategory)); */ -+ } -+ -+} /* end of kalAcquireSpinLock() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is provided by GLUE Layer for internal driver stack to release -+* OS SPIN_LOCK. -+* -+* \param[in] prGlueInfo Pointer of GLUE Data Structure -+* \param[in] rLockCategory Specify which SPIN_LOCK -+* \param[in] u4Flags Saved IRQ flags -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID kalReleaseSpinLock(IN P_GLUE_INFO_T prGlueInfo, IN ENUM_SPIN_LOCK_CATEGORY_E rLockCategory, IN UINT_32 u4Flags) -+{ -+ ASSERT(prGlueInfo); -+ -+ if (rLockCategory < SPIN_LOCK_NUM) { -+ /* DBGLOG(INIT, TRACE, ("A-%d %d %d\n", rLockCategory, u4MemAllocCnt, u4MemFreeCnt)); */ -+#if CFG_USE_SPIN_LOCK_BOTTOM_HALF -+ spin_unlock_bh(&prGlueInfo->rSpinLock[rLockCategory]); -+#else /* !CFG_USE_SPIN_LOCK_BOTTOM_HALF */ -+ spin_unlock_irqrestore(&prGlueInfo->rSpinLock[rLockCategory], u4Flags); -+#endif /* !CFG_USE_SPIN_LOCK_BOTTOM_HALF */ -+ -+ } -+ -+} /* end of kalReleaseSpinLock() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is provided by GLUE Layer for internal driver stack to update -+* current MAC address. -+* -+* \param[in] prGlueInfo Pointer of GLUE Data Structure -+* \param[in] pucMacAddr Pointer of current MAC address -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID kalUpdateMACAddress(IN P_GLUE_INFO_T prGlueInfo, IN PUINT_8 pucMacAddr) -+{ -+ ASSERT(prGlueInfo); -+ ASSERT(pucMacAddr); -+ -+ if (UNEQUAL_MAC_ADDR(prGlueInfo->prDevHandler->dev_addr, pucMacAddr)) -+ memcpy(prGlueInfo->prDevHandler->dev_addr, pucMacAddr, PARAM_MAC_ADDR_LEN); -+ -+} -+ -+#if CFG_TCP_IP_CHKSUM_OFFLOAD -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief To query the packet information for offload related parameters. -+* -+* \param[in] pvPacket Pointer to the packet descriptor. -+* \param[in] pucFlag Points to the offload related parameter. -+* -+* \return (none) -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID kalQueryTxChksumOffloadParam(IN PVOID pvPacket, OUT PUINT_8 pucFlag) -+{ -+ struct sk_buff *skb = (struct sk_buff *)pvPacket; -+ UINT_8 ucFlag = 0; -+ -+ ASSERT(pvPacket); -+ ASSERT(pucFlag); -+ -+ -+ if (skb->ip_summed == CHECKSUM_PARTIAL) { -+#if DBG -+ /* Kevin: do double check, we can remove this part in Normal Driver. -+ * Because we register NIC feature with NETIF_F_IP_CSUM for MT5912B MAC, so -+ * we'll process IP packet only. -+ */ -+ if (skb->protocol != htons(ETH_P_IP)) { -+ /* printk("Wrong skb->protocol( = %08x) for TX Checksum Offload.\n", skb->protocol); */ -+ } else -+#endif -+ ucFlag |= (TX_CS_IP_GEN | TX_CS_TCP_UDP_GEN); -+ } -+ -+ *pucFlag = ucFlag; -+ -+} /* kalQueryChksumOffloadParam */ -+ -+/* 4 2007/10/8, mikewu, this is rewritten by Mike */ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief To update the checksum offload status to the packet to be indicated to OS. -+* -+* \param[in] pvPacket Pointer to the packet descriptor. -+* \param[in] pucFlag Points to the offload related parameter. -+* -+* \return (none) -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID kalUpdateRxCSUMOffloadParam(IN PVOID pvPacket, IN ENUM_CSUM_RESULT_T aeCSUM[]) -+{ -+ struct sk_buff *skb = (struct sk_buff *)pvPacket; -+ -+ ASSERT(pvPacket); -+ -+ if ((aeCSUM[CSUM_TYPE_IPV4] == CSUM_RES_SUCCESS || aeCSUM[CSUM_TYPE_IPV6] == CSUM_RES_SUCCESS) && -+ ((aeCSUM[CSUM_TYPE_TCP] == CSUM_RES_SUCCESS) || (aeCSUM[CSUM_TYPE_UDP] == CSUM_RES_SUCCESS))) { -+ skb->ip_summed = CHECKSUM_UNNECESSARY; -+ } else { -+ skb->ip_summed = CHECKSUM_NONE; -+#if DBG -+ if (aeCSUM[CSUM_TYPE_IPV4] == CSUM_RES_NONE && aeCSUM[CSUM_TYPE_IPV6] == CSUM_RES_NONE) -+ DBGLOG(RX, TRACE, "RX: \"non-IPv4/IPv6\" Packet\n"); -+ else if (aeCSUM[CSUM_TYPE_IPV4] == CSUM_RES_FAILED) -+ DBGLOG(RX, TRACE, "RX: \"bad IP Checksum\" Packet\n"); -+ else if (aeCSUM[CSUM_TYPE_TCP] == CSUM_RES_FAILED) -+ DBGLOG(RX, TRACE, "RX: \"bad TCP Checksum\" Packet\n"); -+ else if (aeCSUM[CSUM_TYPE_UDP] == CSUM_RES_FAILED) -+ DBGLOG(RX, TRACE, "RX: \"bad UDP Checksum\" Packet\n"); -+ else -+ /* Do nothing */ -+#endif -+ } -+ -+} /* kalUpdateRxCSUMOffloadParam */ -+#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is called to free packet allocated from kalPacketAlloc. -+* -+* \param[in] prGlueInfo Pointer of GLUE Data Structure -+* \param[in] pvPacket Pointer of the packet descriptor -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID kalPacketFree(IN P_GLUE_INFO_T prGlueInfo, IN PVOID pvPacket) -+{ -+ dev_kfree_skb((struct sk_buff *)pvPacket); -+ if (prGlueInfo) -+ prGlueInfo->u8SkbFreed++; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Only handles driver own creating packet (coalescing buffer). -+* -+* \param prGlueInfo Pointer of GLUE Data Structure -+* \param u4Size Pointer of Packet Handle -+* \param ppucData Status Code for OS upper layer -+* -+* \return NULL: Failed to allocate skb, Not NULL get skb -+*/ -+/*----------------------------------------------------------------------------*/ -+PVOID kalPacketAlloc(IN P_GLUE_INFO_T prGlueInfo, IN UINT_32 u4Size, OUT PUINT_8 *ppucData) -+{ -+ struct sk_buff *prSkb = dev_alloc_skb(u4Size); -+ -+ if (prSkb) -+ *ppucData = (PUINT_8) (prSkb->data); -+#if DBG -+ { -+ PUINT_32 pu4Head = (PUINT_32) &prSkb->cb[0]; -+ *pu4Head = (UINT_32) prSkb->head; -+ DBGLOG(RX, TRACE, "prSkb->head = %#x, prSkb->cb = %#x\n", (UINT_32) prSkb->head, *pu4Head); -+ } -+#endif -+ return (PVOID) prSkb; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Process the received packet for indicating to OS. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure. -+* \param[in] pvPacket Pointer of the packet descriptor -+* \param[in] pucPacketStart The starting address of the buffer of Rx packet. -+* \param[in] u4PacketLen The packet length. -+* \param[in] pfgIsRetain Is the packet to be retained. -+* \param[in] aerCSUM The result of TCP/ IP checksum offload. -+* -+* \retval WLAN_STATUS_SUCCESS. -+* \retval WLAN_STATUS_FAILURE. -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS -+kalProcessRxPacket(IN P_GLUE_INFO_T prGlueInfo, IN PVOID pvPacket, IN PUINT_8 pucPacketStart, IN UINT_32 u4PacketLen, -+ /* IN PBOOLEAN pfgIsRetain, */ -+ IN BOOLEAN fgIsRetain, IN ENUM_CSUM_RESULT_T aerCSUM[]) -+{ -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ struct sk_buff *skb = (struct sk_buff *)pvPacket; -+ -+ skb->data = pucPacketStart; -+ skb_reset_tail_pointer(skb); /* reset tail pointer first, for 64bit kernel,we should call linux kernel API */ -+ skb_trim(skb, 0); /* only if skb->len > len, then skb_trim has effect */ -+ skb_put(skb, u4PacketLen); /* shift tail and skb->len to correct value */ -+ -+#if CFG_TCP_IP_CHKSUM_OFFLOAD -+ kalUpdateRxCSUMOffloadParam(skb, aerCSUM); -+#endif -+ -+ return rStatus; -+} -+ -+#if (CONF_HIF_LOOPBACK_AUTO == 1) -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Do HIF loopback test. -+* -+* \param[in] GlueInfo Pointer to the GLUE_INFO_T structure. -+* -+* \retval None -+*/ -+/*----------------------------------------------------------------------------*/ -+unsigned int testmode = 0; -+unsigned int testlen = 64; -+ -+void kalDevLoopbkAuto(IN GLUE_INFO_T *GlueInfo) -+{ -+#define HIF_LOOPBK_AUTO_TEST_LEN 1600 -+/* GL_HIF_INFO_T *HifInfo; */ -+ static unsigned int txcnt; -+ struct sk_buff *MsduInfo; -+ UINT_8 *Pkt; -+ UINT_32 RegVal; -+ UINT_32 PktLen = 16; -+ -+ /* Init */ -+ if (testmode != 0) { -+ PktLen = kalRandomNumber() % 1520; -+ if (PktLen < 64) -+ PktLen = 64; -+ } else { -+ PktLen = testlen++; -+ if (PktLen > 1520) { -+ testmode = 1; -+ PktLen = 64; -+ } -+ } -+ -+/* PktLen = 100; */ -+ DBGLOG(INIT, INFO, "kalDevLoopbkAuto> Send a packet to HIF (len = %d) (total = %d)...\n", PktLen, ++txcnt); -+/* HifInfo = &GlueInfo->rHifInfo; */ -+ -+ /* Allocate a MSDU_INFO_T */ -+ MsduInfo = kalPacketAlloc(GlueInfo, HIF_LOOPBK_AUTO_TEST_LEN, &Pkt); -+ if (MsduInfo == NULL) { -+ DBGLOG(INIT, WARN, "No PKT_INFO_T for sending loopback packet!\n"); -+ return; -+ } -+ -+ /* Init the packet */ -+ MsduInfo->dev = GlueInfo->prDevHandler; -+ if (MsduInfo->dev == NULL) { -+ DBGLOG(INIT, WARN, "MsduInfo->dev == NULL!!\n"); -+ kalPacketFree(GlueInfo, MsduInfo); -+ return; -+ } -+ -+ MsduInfo->len = PktLen; -+ kalMemSet(MsduInfo->data, 0xff, 6); -+ kalMemSet(MsduInfo->data + 6, 0x5a, PktLen - 6); -+ -+ /* Simulate OS to send the packet */ -+ wlanHardStartXmit(MsduInfo, MsduInfo->dev); -+ -+#if 0 -+ PktLen += 4; -+ if (PktLen >= 1600) -+ PktLen = 16; -+#endif -+ -+ /* Note: in FPGA, clock is not accuracy so 3000 here, not 10000 */ -+/* HifInfo->HifTmrLoopbkFn.expires = jiffies + MSEC_TO_SYSTIME(1000); */ -+/* add_timer(&(HifInfo->HifTmrLoopbkFn)); */ -+} -+ -+int kalDevLoopbkThread(IN void *data) -+{ -+ struct net_device *dev = data; -+ P_GLUE_INFO_T GlueInfo = *((P_GLUE_INFO_T *) netdev_priv(dev)); -+ GL_HIF_INFO_T *HifInfo = &GlueInfo->rHifInfo; -+ int ret; -+ static int test; -+ -+ while (TRUE) { -+ ret = wait_event_interruptible(HifInfo->HifWaitq, (HifInfo->HifLoopbkFlg != 0)); -+ -+ if (HifInfo->HifLoopbkFlg == 0xFFFFFFFF) -+ break; -+ -+ while (TRUE) { -+ /* if ((HifInfo->HifLoopbkFlg & 0x01) == 0) */ -+ if (GlueInfo->i4TxPendingFrameNum < 64) { -+ DBGLOG(INIT, INFO, "GlueInfo->i4TxPendingFrameNum = %d\n", -+ GlueInfo->i4TxPendingFrameNum); -+ kalDevLoopbkAuto(GlueInfo); -+ -+ if (testmode == 0) -+ kalMsleep(3000); -+ } else -+ kalMsleep(1); -+ } -+ } -+} -+ -+void kalDevLoopbkRxHandle(IN P_ADAPTER_T prAdapter, IN OUT P_SW_RFB_T prSwRfb) -+{ -+ static unsigned int rxcnt; -+ UINT_32 i; -+ UINT_8 *Buf = prSwRfb->pucRecvBuff + sizeof(HIF_TX_HEADER_T); -+ P_HIF_RX_HEADER_T prHifRxHdr = prSwRfb->prHifRxHdr; -+ UINT_32 len = prHifRxHdr->u2PacketLen - sizeof(HIF_TX_HEADER_T); -+ -+ if (len > 1600) { -+ while (1) -+ DBGLOG(INIT, ERROR, "HIF> Loopback len > 1600!!! error!!!\n"); -+ } -+ -+ for (i = 0; i < 6; i++) { -+ if (Buf[i] != 0xff) { -+ while (1) { -+ DBGLOG(INIT, ERROR, "HIF> Loopbk dst addr error (len = %d)!\n", len); -+ dumpMemory8(prSwRfb->pucRecvBuff, prHifRxHdr->u2PacketLen); -+ } -+ } -+ } -+ -+ for (i = 6; i < len; i++) { -+ if (Buf[i] != 0x5a) { -+ while (1) { -+ DBGLOG(INIT, ERROR, "HIF> Loopbk error (len = %d)!\n", len); -+ dumpMemory8(prSwRfb->pucRecvBuff, prHifRxHdr->u2PacketLen); -+ } -+ } -+ } -+ -+ DBGLOG(INIT, INFO, "HIF> Loopbk OK (len = %d) (total = %d)!\n", len, ++rxcnt); -+} -+#endif /* CONF_HIF_LOOPBACK_AUTO */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief To indicate an array of received packets is available for higher -+* level protocol uses. -+* -+* \param[in] prGlueInfo Pointer to the Adapter structure. -+* \param[in] apvPkts The packet array to be indicated -+* \param[in] ucPktNum The number of packets to be indicated -+* -+* \retval TRUE Success. -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS kalRxIndicatePkts(IN P_GLUE_INFO_T prGlueInfo, IN PVOID apvPkts[], IN UINT_8 ucPktNum) -+{ -+ UINT_8 ucIdx = 0; -+ struct net_device *prNetDev = prGlueInfo->prDevHandler; -+ struct sk_buff *prSkb = NULL; -+ -+ ASSERT(prGlueInfo); -+ ASSERT(apvPkts); -+ -+#if CFG_BOW_TEST -+ UINT_32 i; -+#endif -+ -+ for (ucIdx = 0; ucIdx < ucPktNum; ucIdx++) { -+ prSkb = apvPkts[ucIdx]; -+#if DBG -+ do { -+ PUINT_8 pu4Head = (PUINT_8) &prSkb->cb[0]; -+ UINT_32 u4HeadValue = 0; -+ -+ kalMemCopy(&u4HeadValue, pu4Head, sizeof(u4HeadValue)); -+ DBGLOG(RX, TRACE, "prSkb->head = %p, prSkb->cb = 0x%x\n", pu4Head, u4HeadValue); -+ } while (0); -+#endif -+ -+ if (GLUE_GET_PKT_IS_P2P(prSkb)) { -+ /* P2P */ -+#if CFG_ENABLE_WIFI_DIRECT -+ if (prGlueInfo->prAdapter->fgIsP2PRegistered) -+ prNetDev = kalP2PGetDevHdlr(prGlueInfo); -+ /* prNetDev->stats.rx_bytes += prSkb->len; */ -+ /* prNetDev->stats.rx_packets++; */ -+ prGlueInfo->prP2PInfo->rNetDevStats.rx_bytes += prSkb->len; -+ prGlueInfo->prP2PInfo->rNetDevStats.rx_packets++; -+ -+#else -+ prNetDev = prGlueInfo->prDevHandler; -+#endif -+ } else if (GLUE_GET_PKT_IS_PAL(prSkb)) { -+ /* BOW */ -+#if CFG_ENABLE_BT_OVER_WIFI && CFG_BOW_SEPARATE_DATA_PATH -+ if (prGlueInfo->rBowInfo.fgIsNetRegistered) -+ prNetDev = prGlueInfo->rBowInfo.prDevHandler; -+#else -+ prNetDev = prGlueInfo->prDevHandler; -+#endif -+ } else { -+ /* AIS */ -+ prNetDev = prGlueInfo->prDevHandler; -+ prGlueInfo->rNetDevStats.rx_bytes += prSkb->len; -+ prGlueInfo->rNetDevStats.rx_packets++; -+ -+ } -+ -+ /* check if the "unicast" packet is from us */ -+ if (kalMemCmp(prSkb->data, prSkb->data + 6, 6) == 0) { -+ /* we will filter broadcast/multicast packet sent from us in hardware */ -+ /* source address = destination address ? */ -+ DBGLOG(RX, EVENT, -+ "kalRxIndicatePkts got from us!!! Drop it! ([ %pM ] len %d)\n", -+ prSkb->data, prSkb->len); -+ wlanReturnPacket(prGlueInfo->prAdapter, prSkb); -+ continue; -+ } -+#if (CFG_SUPPORT_TDLS == 1) -+ if (TdlsexRxFrameDrop(prGlueInfo, prSkb->data) == TRUE) { -+ /* drop the received TDLS action frame */ -+ DBGLOG(TDLS, WARN, -+ " %s: drop a received packet from %pM %u\n", -+ __func__, prSkb->data, -+ (UINT32) ((P_ADAPTER_T) (prGlueInfo->prAdapter))->rRxCtrl.rFreeSwRfbList.u4NumElem); -+ wlanReturnPacket(prGlueInfo->prAdapter, prSkb); -+ continue; -+ } -+ -+ /* -+ get a TDLS request/response/confirm, we need to parse the HT IE -+ because older supplicant does not pass HT IE to us -+ */ -+ TdlsexRxFrameHandle(prGlueInfo, prSkb->data, prSkb->len); -+#endif /* CFG_SUPPORT_TDLS */ -+ -+ STATS_RX_PKT_INFO_DISPLAY(prSkb->data); -+ -+ //prNetDev->last_rx = jiffies; -+ prSkb->protocol = eth_type_trans(prSkb, prNetDev); -+ prSkb->dev = prNetDev; -+ /* DBGLOG_MEM32(RX, TRACE, (PUINT_32)prSkb->data, prSkb->len); */ -+ DBGLOG(RX, TRACE, "kalRxIndicatePkts len = %d\n", prSkb->len); -+ -+#if CFG_BOW_TEST -+ DBGLOG(BOW, TRACE, "Rx sk_buff->len: %d\n", prSkb->len); -+ DBGLOG(BOW, TRACE, "Rx sk_buff->data_len: %d\n", prSkb->data_len); -+ DBGLOG(BOW, TRACE, "Rx sk_buff->data:\n"); -+ -+ for (i = 0; i < prSkb->len; i++) { -+ DBGLOG(BOW, TRACE, "%4x", prSkb->data[i]); -+ -+ if ((i + 1) % 16 == 0) -+ DBGLOG(BOW, TRACE, "\n"); -+ } -+ -+ DBGLOG(BOW, TRACE, "\n"); -+#endif -+ -+ if (!in_interrupt()) -+ netif_rx_ni(prSkb); /* only in non-interrupt context */ -+ else -+ netif_rx(prSkb); -+ -+ wlanReturnPacket(prGlueInfo->prAdapter, NULL); -+ } -+ -+ kalPerMonStart(prGlueInfo); -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Called by driver to indicate event to upper layer, for example, the wpa -+* supplicant or wireless tools. -+* -+* \param[in] pvAdapter Pointer to the adapter descriptor. -+* \param[in] eStatus Indicated status. -+* \param[in] pvBuf Indicated message buffer. -+* \param[in] u4BufLen Indicated message buffer size. -+* -+* \return (none) -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT_32 ScanCnt = 0, ScanDoneFailCnt = 0; -+VOID -+kalIndicateStatusAndComplete(IN P_GLUE_INFO_T prGlueInfo, IN WLAN_STATUS eStatus, IN PVOID pvBuf, IN UINT_32 u4BufLen) -+{ -+ UINT_32 bufLen; -+ P_PARAM_STATUS_INDICATION_T pStatus = (P_PARAM_STATUS_INDICATION_T) pvBuf; -+ P_PARAM_AUTH_EVENT_T pAuth = (P_PARAM_AUTH_EVENT_T) pStatus; -+ P_PARAM_PMKID_CANDIDATE_LIST_T pPmkid = (P_PARAM_PMKID_CANDIDATE_LIST_T) (pStatus + 1); -+ PARAM_MAC_ADDRESS arBssid; -+ struct cfg80211_scan_request *prScanRequest = NULL; -+ PARAM_SSID_T ssid; -+ struct ieee80211_channel *prChannel = NULL; -+ struct cfg80211_bss *bss; -+ UINT_8 ucChannelNum; -+ P_BSS_DESC_T prBssDesc = NULL; -+ struct cfg80211_scan_info info = { -+ .aborted = false, -+ }; -+ -+ GLUE_SPIN_LOCK_DECLARATION(); -+ -+ kalMemZero(arBssid, MAC_ADDR_LEN); -+ -+ ASSERT(prGlueInfo); -+ -+ switch (eStatus) { -+ case WLAN_STATUS_ROAM_OUT_FIND_BEST: -+ case WLAN_STATUS_MEDIA_CONNECT: -+ -+ prGlueInfo->eParamMediaStateIndicated = PARAM_MEDIA_STATE_CONNECTED; -+ -+ /* indicate assoc event */ -+ wlanQueryInformation(prGlueInfo->prAdapter, wlanoidQueryBssid, &arBssid[0], sizeof(arBssid), &bufLen); -+ wext_indicate_wext_event(prGlueInfo, SIOCGIWAP, arBssid, bufLen); -+ -+ /* switch netif on */ -+ netif_carrier_on(prGlueInfo->prDevHandler); -+ -+ do { -+ /* print message on console */ -+ wlanQueryInformation(prGlueInfo->prAdapter, wlanoidQuerySsid, &ssid, sizeof(ssid), &bufLen); -+ -+ ssid.aucSsid[(ssid.u4SsidLen >= PARAM_MAX_LEN_SSID) ? -+ (PARAM_MAX_LEN_SSID - 1) : ssid.u4SsidLen] = '\0'; -+ DBGLOG(AIS, INFO, " %s netif_carrier_on [ssid:%s %pM ]\n", -+ prGlueInfo->prDevHandler->name, ssid.aucSsid, arBssid); -+ } while (0); -+ -+ if (prGlueInfo->fgIsRegistered == TRUE) { -+ struct cfg80211_bss *bss_others = NULL; -+ UINT_8 ucLoopCnt = 15; /* only loop 15 times to avoid dead loop */ -+ -+ /* retrieve channel */ -+ ucChannelNum = wlanGetChannelNumberByNetwork(prGlueInfo->prAdapter, NETWORK_TYPE_AIS_INDEX); -+ if (ucChannelNum <= 14) { -+ prChannel = -+ ieee80211_get_channel(priv_to_wiphy(prGlueInfo), -+ ieee80211_channel_to_frequency(ucChannelNum, -+ NL80211_BAND_2GHZ)); -+ } else { -+ prChannel = -+ ieee80211_get_channel(priv_to_wiphy(prGlueInfo), -+ ieee80211_channel_to_frequency(ucChannelNum, -+ NL80211_BAND_5GHZ)); -+ } -+ -+ /* ensure BSS exists */ -+ bss = cfg80211_get_bss(priv_to_wiphy(prGlueInfo), prChannel, arBssid, -+ ssid.aucSsid, ssid.u4SsidLen, WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS); -+ -+ if (bss == NULL) { -+ /* create BSS on-the-fly */ -+ prBssDesc = -+ wlanGetTargetBssDescByNetwork(prGlueInfo->prAdapter, NETWORK_TYPE_AIS_INDEX); -+ -+ if (prBssDesc != NULL) { -+ bss = cfg80211_inform_bss(priv_to_wiphy(prGlueInfo), prChannel, -+ CFG80211_BSS_FTYPE_PRESP, -+ arBssid, 0, /* TSF */ -+ WLAN_CAPABILITY_ESS, -+ prBssDesc->u2BeaconInterval, /* beacon interval */ -+ prBssDesc->aucIEBuf, /* IE */ -+ prBssDesc->u2IELength, /* IE Length */ -+ RCPI_TO_dBm(prBssDesc->ucRCPI) * 100, /* MBM */ -+ GFP_KERNEL); -+ } -+ } -+ /* remove all bsses that before and only channel different with the current connected one -+ if without this patch, UI will show channel A is connected even if AP has change channel -+ from A to B */ -+ while (ucLoopCnt--) { -+ bss_others = cfg80211_get_bss(priv_to_wiphy(prGlueInfo), NULL, arBssid, -+ ssid.aucSsid, ssid.u4SsidLen, WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS); -+ if (bss && bss_others && bss_others != bss) { -+ DBGLOG(SCN, INFO, "remove BSSes that only channel different\n"); -+ cfg80211_unlink_bss(priv_to_wiphy(prGlueInfo), bss_others); -+ } else -+ break; -+ } -+ -+ /* CFG80211 Indication */ -+ if (eStatus == WLAN_STATUS_ROAM_OUT_FIND_BEST) { -+ /*cfg80211_roamed_bss(prGlueInfo->prDevHandler, -+ bss, -+ prGlueInfo->aucReqIe, -+ prGlueInfo->u4ReqIeLength, -+ prGlueInfo->aucRspIe, prGlueInfo->u4RspIeLength, GFP_KERNEL); -+ */ -+ struct cfg80211_roam_info roam_info = { -+ .bss = bss, -+ .req_ie = prGlueInfo->aucReqIe, -+ .req_ie_len = prGlueInfo->u4ReqIeLength, -+ .resp_ie = prGlueInfo->aucRspIe, -+ .resp_ie_len = prGlueInfo->u4RspIeLength -+ }; -+ cfg80211_roamed(prGlueInfo->prDevHandler, -+ &roam_info, -+ GFP_KERNEL); -+ } else { -+ /* to support user space roaming, cfg80211 will change the sme_state to connecting -+ before reassociate */ -+ cfg80211_connect_result(prGlueInfo->prDevHandler, -+ arBssid, -+ prGlueInfo->aucReqIe, -+ prGlueInfo->u4ReqIeLength, -+ prGlueInfo->aucRspIe, -+ prGlueInfo->u4RspIeLength, WLAN_STATUS_SUCCESS, GFP_KERNEL); -+ } -+ } -+ -+ break; -+ -+ case WLAN_STATUS_MEDIA_DISCONNECT: -+ case WLAN_STATUS_MEDIA_DISCONNECT_LOCALLY: -+ /* indicate disassoc event */ -+ wext_indicate_wext_event(prGlueInfo, SIOCGIWAP, NULL, 0); -+ /* For CR 90 and CR99, While supplicant do reassociate, driver will do netif_carrier_off first, -+ after associated success, at joinComplete(), do netif_carier_on, -+ but for unknown reason, the supplicant 1x pkt will not called the driver -+ hardStartXmit, for template workaround these bugs, add this compiling flag -+ */ -+ /* switch netif off */ -+ -+ DBGLOG(AIS, INFO, "[wifi] %s netif_carrier_off\n", -+ prGlueInfo->prDevHandler->name); -+ -+ netif_carrier_off(prGlueInfo->prDevHandler); -+ -+ if (prGlueInfo->fgIsRegistered == TRUE) { -+ P_WIFI_VAR_T prWifiVar = &prGlueInfo->prAdapter->rWifiVar; -+ UINT_16 u2DeauthReason = prWifiVar->arBssInfo[NETWORK_TYPE_AIS_INDEX].u2DeauthReason; -+ /* CFG80211 Indication */ -+ DBGLOG(AIS, INFO, "[wifi] %s cfg80211_disconnected\n", prGlueInfo->prDevHandler->name); -+ cfg80211_disconnected(prGlueInfo->prDevHandler, u2DeauthReason, NULL, 0, false, GFP_KERNEL); -+ } -+ -+ prGlueInfo->eParamMediaStateIndicated = PARAM_MEDIA_STATE_DISCONNECTED; -+ -+ break; -+ -+ case WLAN_STATUS_SCAN_COMPLETE: -+ /* indicate scan complete event */ -+ wext_indicate_wext_event(prGlueInfo, SIOCGIWSCAN, NULL, 0); -+ -+ /* 1. reset first for newly incoming request */ -+ GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV); -+ if (prGlueInfo->prScanRequest != NULL) { -+ prScanRequest = prGlueInfo->prScanRequest; -+ prGlueInfo->prScanRequest = NULL; -+ } -+ GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV); -+ -+ /* 2. then CFG80211 Indication */ -+ DBGLOG(SCN, TRACE, "[ais] scan complete %p %d %d\n", prScanRequest, ScanCnt, ScanDoneFailCnt); -+ -+ if (prScanRequest != NULL) -+ cfg80211_scan_done(prScanRequest, &info); -+ break; -+ case WLAN_STATUS_CONNECT_INDICATION: -+ /* indicate AIS Jion fail event -+ if (prGlueInfo->prDevHandler->ieee80211_ptr->sme_state == CFG80211_SME_CONNECTING) */ -+ cfg80211_connect_result(prGlueInfo->prDevHandler, -+ prGlueInfo->prAdapter->rWifiVar.rAisFsmInfo.prTargetBssDesc->aucBSSID, -+ prGlueInfo->aucReqIe, -+ prGlueInfo->u4ReqIeLength, -+ prGlueInfo->aucRspIe, -+ prGlueInfo->u4RspIeLength, WLAN_STATUS_AUTH_TIMEOUT, GFP_KERNEL); -+ break; -+ -+#if 0 -+ case WLAN_STATUS_MSDU_OK: -+ if (netif_running(prGlueInfo->prDevHandler)) -+ netif_wake_queue(prGlueInfo->prDevHandler); -+ break; -+#endif -+ -+ case WLAN_STATUS_MEDIA_SPECIFIC_INDICATION: -+ if (pStatus) { -+ switch (pStatus->eStatusType) { -+ case ENUM_STATUS_TYPE_AUTHENTICATION: -+ /* -+ printk(KERN_NOTICE "ENUM_STATUS_TYPE_AUTHENTICATION: L(%ld) [ %pM ] F:%lx\n", -+ pAuth->Request[0].Length, -+ pAuth->Request[0].Bssid, -+ pAuth->Request[0].Flags); -+ */ -+ /* indicate (UC/GC) MIC ERROR event only */ -+ if ((pAuth->arRequest[0].u4Flags == -+ PARAM_AUTH_REQUEST_PAIRWISE_ERROR) || -+ (pAuth->arRequest[0].u4Flags == PARAM_AUTH_REQUEST_GROUP_ERROR)) { -+ cfg80211_michael_mic_failure(prGlueInfo->prDevHandler, NULL, -+ (pAuth->arRequest[0].u4Flags == -+ PARAM_AUTH_REQUEST_PAIRWISE_ERROR) ? -+ NL80211_KEYTYPE_PAIRWISE : NL80211_KEYTYPE_GROUP, -+ 0, NULL, GFP_KERNEL); -+ wext_indicate_wext_event(prGlueInfo, IWEVMICHAELMICFAILURE, -+ (unsigned char *)&pAuth->arRequest[0], -+ pAuth->arRequest[0].u4Length); -+ } -+ break; -+ -+ case ENUM_STATUS_TYPE_CANDIDATE_LIST: -+ /* -+ printk(KERN_NOTICE "Param_StatusType_PMKID_CandidateList: Ver(%ld) Num(%ld)\n", -+ pPmkid->u2Version, -+ pPmkid->u4NumCandidates); -+ if (pPmkid->u4NumCandidates > 0) { -+ printk(KERN_NOTICE "candidate[ %pM ] preAuth Flag:%lx\n", -+ pPmkid->arCandidateList[0].rBSSID, -+ pPmkid->arCandidateList[0].fgFlags); -+ } -+ */ -+ { -+ UINT_32 i = 0; -+ /*struct net_device *prDev = prGlueInfo->prDevHandler; */ -+ P_PARAM_PMKID_CANDIDATE_T prCand = NULL; -+ /* indicate pmk candidate via cfg80211 to supplicant, -+ the second parameter is 1000 for -+ cfg80211_pmksa_candidate_notify, because wpa_supplicant defined it. */ -+ for (i = 0; i < pPmkid->u4NumCandidates; i++) { -+ prCand = &pPmkid->arCandidateList[i]; -+ cfg80211_pmksa_candidate_notify(prGlueInfo->prDevHandler, 1000, -+ prCand->arBSSID, prCand->u4Flags, -+ GFP_KERNEL); -+ -+ wext_indicate_wext_event(prGlueInfo, -+ IWEVPMKIDCAND, -+ (unsigned char *)prCand, -+ pPmkid->u4NumCandidates); -+ } -+ } -+ break; -+ -+ default: -+ /* case ENUM_STATUS_TYPE_MEDIA_STREAM_MODE */ -+ /* -+ printk(KERN_NOTICE "unknown media specific indication type:%x\n", -+ pStatus->StatusType); -+ */ -+ break; -+ } -+ } else { -+ /* -+ printk(KERN_WARNING "media specific indication buffer NULL\n"); -+ */ -+ } -+ break; -+ -+#if CFG_SUPPORT_BCM && CFG_SUPPORT_BCM_BWCS -+ case WLAN_STATUS_BWCS_UPDATE: -+ { -+ wext_indicate_wext_event(prGlueInfo, IWEVCUSTOM, pvBuf, sizeof(PTA_IPC_T)); -+ } -+ -+ break; -+ -+#endif -+ -+ default: -+ /* -+ printk(KERN_WARNING "unknown indication:%lx\n", eStatus); -+ */ -+ break; -+ } -+} /* kalIndicateStatusAndComplete */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to update the (re)association request -+* information to the structure used to query and set -+* OID_802_11_ASSOCIATION_INFORMATION. -+* -+* \param[in] prGlueInfo Pointer to the Glue structure. -+* \param[in] pucFrameBody Pointer to the frame body of the last (Re)Association -+* Request frame from the AP. -+* \param[in] u4FrameBodyLen The length of the frame body of the last -+* (Re)Association Request frame. -+* \param[in] fgReassocRequest TRUE, if it is a Reassociation Request frame. -+* -+* \return (none) -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+kalUpdateReAssocReqInfo(IN P_GLUE_INFO_T prGlueInfo, -+ IN PUINT_8 pucFrameBody, IN UINT_32 u4FrameBodyLen, IN BOOLEAN fgReassocRequest) -+{ -+ PUINT_8 cp; -+ -+ ASSERT(prGlueInfo); -+ -+ /* reset */ -+ prGlueInfo->u4ReqIeLength = 0; -+ -+ if (fgReassocRequest) { -+ if (u4FrameBodyLen < 15) { -+ /* -+ printk(KERN_WARNING "frameBodyLen too short:%ld\n", frameBodyLen); -+ */ -+ return; -+ } -+ } else { -+ if (u4FrameBodyLen < 9) { -+ /* -+ printk(KERN_WARNING "frameBodyLen too short:%ld\n", frameBodyLen); -+ */ -+ return; -+ } -+ } -+ -+ cp = pucFrameBody; -+ -+ if (fgReassocRequest) { -+ /* Capability information field 2 */ -+ /* Listen interval field 2 */ -+ /* Current AP address 6 */ -+ cp += 10; -+ u4FrameBodyLen -= 10; -+ } else { -+ /* Capability information field 2 */ -+ /* Listen interval field 2 */ -+ cp += 4; -+ u4FrameBodyLen -= 4; -+ } -+ -+ wext_indicate_wext_event(prGlueInfo, IWEVASSOCREQIE, cp, u4FrameBodyLen); -+ -+ if (u4FrameBodyLen <= CFG_CFG80211_IE_BUF_LEN) { -+ prGlueInfo->u4ReqIeLength = u4FrameBodyLen; -+ kalMemCopy(prGlueInfo->aucReqIe, cp, u4FrameBodyLen); -+ } -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This routine is called to update the (re)association -+* response information to the structure used to reply with -+* cfg80211_connect_result -+* -+* @param prGlueInfo Pointer to adapter descriptor -+* @param pucFrameBody Pointer to the frame body of the last (Re)Association -+* Response frame from the AP -+* @param u4FrameBodyLen The length of the frame body of the last -+* (Re)Association Response frame -+* -+* @return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID kalUpdateReAssocRspInfo(IN P_GLUE_INFO_T prGlueInfo, IN PUINT_8 pucFrameBody, IN UINT_32 u4FrameBodyLen) -+{ -+ UINT_32 u4IEOffset = 6; /* cap_info, status_code & assoc_id */ -+ UINT_32 u4IELength = u4FrameBodyLen - u4IEOffset; -+ -+ ASSERT(prGlueInfo); -+ -+ /* reset */ -+ prGlueInfo->u4RspIeLength = 0; -+ -+ if (u4IELength <= CFG_CFG80211_IE_BUF_LEN) { -+ prGlueInfo->u4RspIeLength = u4IELength; -+ kalMemCopy(prGlueInfo->aucRspIe, pucFrameBody + u4IEOffset, u4IELength); -+ } -+ -+} /* kalUpdateReAssocRspInfo */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Notify OS with SendComplete event of the specific packet. Linux should -+* free packets here. -+* -+* \param[in] prGlueInfo Pointer of GLUE Data Structure -+* \param[in] pvPacket Pointer of Packet Handle -+* \param[in] status Status Code for OS upper layer -+* -+* \return - -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID kalSendCompleteAndAwakeQueue(IN P_GLUE_INFO_T prGlueInfo, IN PVOID pvPacket) -+{ -+ -+ struct net_device *prDev = NULL; -+ struct sk_buff *prSkb = NULL; -+ UINT_16 u2QueueIdx = 0; -+ UINT_8 ucNetworkType = 0; -+ BOOLEAN fgIsValidDevice = TRUE; -+ -+ ASSERT(pvPacket); -+ ASSERT(prGlueInfo->i4TxPendingFrameNum); -+ -+ prSkb = (struct sk_buff *)pvPacket; -+ u2QueueIdx = skb_get_queue_mapping(prSkb); -+ ASSERT(u2QueueIdx < CFG_MAX_TXQ_NUM); -+ -+ if (GLUE_GET_PKT_IS_PAL(prSkb)) { -+ ucNetworkType = NETWORK_TYPE_BOW_INDEX; -+ } else if (GLUE_GET_PKT_IS_P2P(prSkb)) { -+ ucNetworkType = NETWORK_TYPE_P2P_INDEX; -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ /* in case packet was sent after P2P device is unregistered */ -+ if (prGlueInfo->prAdapter->fgIsP2PRegistered == FALSE) -+ fgIsValidDevice = FALSE; -+#endif -+ } else { -+ ucNetworkType = NETWORK_TYPE_AIS_INDEX; -+ } -+ -+ GLUE_DEC_REF_CNT(prGlueInfo->i4TxPendingFrameNum); -+ if (u2QueueIdx < CFG_MAX_TXQ_NUM) -+ GLUE_DEC_REF_CNT(prGlueInfo->ai4TxPendingFrameNumPerQueue[ucNetworkType][u2QueueIdx]); -+ prDev = prSkb->dev; -+ -+ ASSERT(prDev); -+ -+ if ((fgIsValidDevice == TRUE) && (u2QueueIdx < CFG_MAX_TXQ_NUM)) { -+ if (netif_subqueue_stopped(prDev, prSkb) && -+ prGlueInfo->ai4TxPendingFrameNumPerQueue[ucNetworkType][u2QueueIdx] <= -+ CFG_TX_START_NETIF_PER_QUEUE_THRESHOLD) { -+ DBGLOG(TX, INFO, "netif_wake_subqueue for bss: %d. Queue len: %d\n", -+ ucNetworkType, -+ prGlueInfo->ai4TxPendingFrameNumPerQueue[ucNetworkType][u2QueueIdx]); -+ netif_wake_subqueue(prDev, u2QueueIdx); -+ -+#if (CONF_HIF_LOOPBACK_AUTO == 1) -+ prGlueInfo->rHifInfo.HifLoopbkFlg &= ~0x01; -+#endif /* CONF_HIF_LOOPBACK_AUTO */ -+ } -+ } -+ -+ dev_kfree_skb((struct sk_buff *)pvPacket); -+ prGlueInfo->u8SkbFreed++; -+ -+ DBGLOG(TX, EVENT, "----- pending frame %d -----\n", prGlueInfo->i4TxPendingFrameNum); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Copy Mac Address setting from registry. It's All Zeros in Linux. -+* -+* \param[in] prAdapter Pointer to the Adapter structure -+* -+* \param[out] paucMacAddr Pointer to the Mac Address buffer -+* -+* \retval WLAN_STATUS_SUCCESS -+* -+* \note -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID kalQueryRegistryMacAddr(IN P_GLUE_INFO_T prGlueInfo, OUT PUINT_8 paucMacAddr) -+{ -+ UINT_8 aucZeroMac[MAC_ADDR_LEN] = { 0, 0, 0, 0, 0, 0 } -+ -+ DEBUGFUNC("kalQueryRegistryMacAddr"); -+ -+ ASSERT(prGlueInfo); -+ ASSERT(paucMacAddr); -+ -+ kalMemCopy((PVOID) paucMacAddr, (PVOID) aucZeroMac, MAC_ADDR_LEN); -+ -+} /* end of kalQueryRegistryMacAddr() */ -+ -+#if CFG_SUPPORT_EXT_CONFIG -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Read external configuration, ex. NVRAM or file -+* -+* \param[in] prGlueInfo Pointer of GLUE Data Structure -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT_32 kalReadExtCfg(IN P_GLUE_INFO_T prGlueInfo) -+{ -+ ASSERT(prGlueInfo); -+ -+ /* External data is given from user space by ioctl or /proc, not read by -+ driver. -+ */ -+ if (0 != prGlueInfo->u4ExtCfgLength) -+ DBGLOG(INIT, TRACE, "Read external configuration data -- OK\n"); -+ else -+ DBGLOG(INIT, TRACE, "Read external configuration data -- fail\n"); -+ -+ return prGlueInfo->u4ExtCfgLength; -+} -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This inline function is to extract some packet information, including -+* user priority, packet length, destination address, 802.1x and BT over Wi-Fi -+* or not. -+* -+* @param prGlueInfo Pointer to the glue structure -+* @param prNdisPacket Packet descriptor -+* @param pucPriorityParam User priority -+* @param pu4PacketLen Packet length -+* @param pucEthDestAddr Destination address -+* @param pfgIs1X 802.1x packet or not -+* @param pfgIsPAL BT over Wi-Fi packet or not -+* @prGenUse General used param -+* -+* @retval TRUE Success to extract information -+* @retval FALSE Fail to extract correct information -+*/ -+/*----------------------------------------------------------------------------*/ -+ -+BOOLEAN -+kalQoSFrameClassifierAndPacketInfo(IN P_GLUE_INFO_T prGlueInfo, -+ IN P_NATIVE_PACKET prPacket, -+ OUT PUINT_8 pucPriorityParam, -+ OUT PUINT_32 pu4PacketLen, -+ OUT PUINT_8 pucEthDestAddr, -+ OUT PBOOLEAN pfgIs1X, -+ OUT PBOOLEAN pfgIsPAL, OUT PUINT_8 pucNetworkType, -+ OUT PVOID prGenUse) -+{ -+ -+ UINT_32 u4PacketLen; -+ -+ UINT_8 ucUserPriority = USER_PRIORITY_DEFAULT; /* Default */ -+ UINT_16 u2EtherTypeLen; -+ struct sk_buff *prSkb = (struct sk_buff *)prPacket; -+ PUINT_8 aucLookAheadBuf = NULL; -+ -+ DEBUGFUNC("kalQoSFrameClassifierAndPacketInfo"); -+ -+ u4PacketLen = prSkb->len; -+ -+ if (u4PacketLen < ETH_HLEN) { -+ DBGLOG(TX, WARN, "Invalid Ether packet length: %u\n", (UINT_32) u4PacketLen); -+ return FALSE; -+ } -+ -+ aucLookAheadBuf = prSkb->data; -+ -+ *pfgIs1X = FALSE; -+ *pfgIsPAL = FALSE; -+ -+ /* 4 <3> Obtain the User Priority for WMM */ -+ u2EtherTypeLen = (aucLookAheadBuf[ETH_TYPE_LEN_OFFSET] << 8) | (aucLookAheadBuf[ETH_TYPE_LEN_OFFSET + 1]); -+ -+ if ((u2EtherTypeLen == ETH_P_IP) && (u4PacketLen >= LOOK_AHEAD_LEN)) { -+ PUINT_8 pucIpHdr = &aucLookAheadBuf[ETH_HLEN]; -+ UINT_8 ucIpVersion; -+ -+ ucIpVersion = (pucIpHdr[0] & IPVH_VERSION_MASK) >> IPVH_VERSION_OFFSET; -+ if (ucIpVersion == IPVERSION) { -+ UINT_8 ucIpTos; -+ /* Get the DSCP value from the header of IP packet. */ -+ ucIpTos = pucIpHdr[1]; -+ ucUserPriority = ((ucIpTos & IPTOS_PREC_MASK) >> IPTOS_PREC_OFFSET); -+ } -+ -+ /* TODO(Kevin): Add TSPEC classifier here */ -+ } else if (u2EtherTypeLen == ETH_P_1X || u2EtherTypeLen == ETH_P_PRE_1X) { /* For Port Control */ -+ PUINT_8 pucEapol = &aucLookAheadBuf[ETH_HLEN]; -+ UINT_8 ucEapolType = pucEapol[1]; -+ UINT_16 u2KeyInfo = pucEapol[5]<<8 | pucEapol[6]; -+ /* -+ * generate a seq number used to trace security frame TX -+ */ -+ if (prGenUse) -+ *(UINT_8 *)prGenUse = nicIncreaseCmdSeqNum(prGlueInfo->prAdapter); -+ -+ switch (ucEapolType) { -+ case 0: /* eap packet */ -+ DBGLOG(TX, INFO, " EAP Packet: code %d, id %d, type %d, seqNo %d\n", -+ pucEapol[4], pucEapol[5], pucEapol[7], -+ prGenUse ? *(UINT_8 *)prGenUse : 0); -+ break; -+ case 1: /* eapol start */ -+ DBGLOG(TX, INFO, " EAPOL: start, seqNo %d\n", -+ prGenUse ? *(UINT_8 *)prGenUse : 0); -+ break; -+ case 3: /* key */ -+ DBGLOG(TX, INFO, -+ " EAPOL: key, KeyInfo 0x%04x, Nonce %02x%02x%02x%02x%02x%02x%02x%02x... seqNo %d\n", -+ u2KeyInfo, pucEapol[17], pucEapol[18], pucEapol[19], pucEapol[20], -+ pucEapol[21], pucEapol[22], pucEapol[23], pucEapol[24], -+ prGenUse ? *(UINT_8 *)prGenUse : 0); -+ break; -+ } -+ *pfgIs1X = TRUE; -+ } -+#if CFG_SUPPORT_WAPI -+ else if (u2EtherTypeLen == ETH_WPI_1X) { -+ PUINT_8 pucEthBody = &aucLookAheadBuf[ETH_HLEN]; -+ UINT_8 ucSubType = pucEthBody[3]; /* sub type filed*/ -+ UINT_16 u2Length = *(PUINT_16)&pucEthBody[6]; -+ UINT_16 u2Seq = *(PUINT_16)&pucEthBody[8]; -+ -+ DBGLOG(TX, INFO, " WAPI: subType %d, Len %d, Seq %d\n", -+ ucSubType, u2Length, u2Seq); -+ *pfgIs1X = TRUE; -+ } -+#endif -+#if (CFG_SUPPORT_TDLS == 1) -+ else if (u2EtherTypeLen == TDLS_FRM_PROT_TYPE) { -+ /* TDLS case */ -+ TDLSEX_UP_ASSIGN(ucUserPriority); -+ } -+#endif /* CFG_SUPPORT_TDLS */ -+ else if (u2EtherTypeLen <= 1500) { /* 802.3 Frame */ -+ UINT_8 ucDSAP, ucSSAP, ucControl; -+ UINT_8 aucOUI[3]; -+ -+ ucDSAP = *(PUINT_8) &aucLookAheadBuf[ETH_LLC_OFFSET]; -+ ucSSAP = *(PUINT_8) &aucLookAheadBuf[ETH_LLC_OFFSET + 1]; -+ ucControl = *(PUINT_8) &aucLookAheadBuf[ETH_LLC_OFFSET + 2]; -+ -+ aucOUI[0] = *(PUINT_8) &aucLookAheadBuf[ETH_SNAP_OFFSET]; -+ aucOUI[1] = *(PUINT_8) &aucLookAheadBuf[ETH_SNAP_OFFSET + 1]; -+ aucOUI[2] = *(PUINT_8) &aucLookAheadBuf[ETH_SNAP_OFFSET + 2]; -+ -+ if (ucDSAP == ETH_LLC_DSAP_SNAP && -+ ucSSAP == ETH_LLC_SSAP_SNAP && -+ ucControl == ETH_LLC_CONTROL_UNNUMBERED_INFORMATION && -+ aucOUI[0] == ETH_SNAP_BT_SIG_OUI_0 && -+ aucOUI[1] == ETH_SNAP_BT_SIG_OUI_1 && aucOUI[2] == ETH_SNAP_BT_SIG_OUI_2) { -+ -+ UINT_16 tmp = -+ ((aucLookAheadBuf[ETH_SNAP_OFFSET + 3] << 8) | aucLookAheadBuf[ETH_SNAP_OFFSET + 4]); -+ -+ *pfgIsPAL = TRUE; -+ ucUserPriority = (UINT_8) prSkb->priority; -+ -+ if (tmp == BOW_PROTOCOL_ID_SECURITY_FRAME) { -+ PUINT_8 pucEapol = &aucLookAheadBuf[ETH_SNAP_OFFSET + 5]; -+ UINT_8 ucEapolType = pucEapol[1]; -+ UINT_16 u2KeyInfo = pucEapol[5]<<8 | pucEapol[6]; -+ if (prGenUse) -+ *(UINT_8 *)prGenUse = nicIncreaseCmdSeqNum(prGlueInfo->prAdapter); -+ -+ switch (ucEapolType) { -+ case 0: /* eap packet */ -+ DBGLOG(TX, INFO, " EAP Packet: code %d, id %d, type %d, seqNo %d\n", -+ pucEapol[4], pucEapol[5], pucEapol[7], -+ prGenUse ? *(UINT_8 *)prGenUse : 0); -+ break; -+ case 1: /* eapol start */ -+ DBGLOG(TX, INFO, " EAPOL: start, seqNo %d\n", -+ prGenUse ? *(UINT_8 *)prGenUse : 0); -+ break; -+ case 3: /* key */ -+ DBGLOG(TX, INFO, -+ " EAPOL: key, KeyInfo 0x%04x, Nonce %02x%02x%02x%02x%02x%02x%02x%02x seqNo %d\n", -+ u2KeyInfo, pucEapol[17], pucEapol[18], pucEapol[19], pucEapol[20], -+ pucEapol[21], pucEapol[22], pucEapol[23], pucEapol[24], -+ prGenUse ? *(UINT_8 *)prGenUse : 0); -+ break; -+ } -+ *pfgIs1X = TRUE; -+ } -+ } -+ } -+ /* 4 <4> Return the value of Priority Parameter. */ -+ *pucPriorityParam = ucUserPriority; -+ -+ /* 4 <5> Retrieve Packet Information - DA */ -+ /* Packet Length/ Destination Address */ -+ *pu4PacketLen = u4PacketLen; -+ -+ kalMemCopy(pucEthDestAddr, aucLookAheadBuf, PARAM_MAC_ADDR_LEN); -+ -+ /* <6> Network type */ -+#if CFG_ENABLE_BT_OVER_WIFI -+ if (*pfgIsPAL == TRUE) { -+ *pucNetworkType = NETWORK_TYPE_BOW_INDEX; -+ } else -+#endif -+ { -+#if CFG_ENABLE_WIFI_DIRECT -+ if (prGlueInfo->prAdapter->fgIsP2PRegistered && GLUE_GET_PKT_IS_P2P(prPacket)) { -+ *pucNetworkType = NETWORK_TYPE_P2P_INDEX; -+ } else -+#endif -+ { -+ *pucNetworkType = NETWORK_TYPE_AIS_INDEX; -+ } -+ } -+ return TRUE; -+} /* end of kalQoSFrameClassifier() */ -+ -+VOID -+kalOidComplete(IN P_GLUE_INFO_T prGlueInfo, -+ IN BOOLEAN fgSetQuery, IN UINT_32 u4SetQueryInfoLen, IN WLAN_STATUS rOidStatus) -+{ -+ -+ ASSERT(prGlueInfo); -+ /* remove timeout check timer */ -+ wlanoidClearTimeoutCheck(prGlueInfo->prAdapter); -+ -+ /* if (prGlueInfo->u4TimeoutFlag != 1) { */ -+ prGlueInfo->rPendStatus = rOidStatus; -+ DBGLOG(OID, TEMP, "kalOidComplete, caller: %p\n", __builtin_return_address(0)); -+ complete(&prGlueInfo->rPendComp); -+ prGlueInfo->u4OidCompleteFlag = 1; -+ /* } */ -+ /* else let it timeout on kalIoctl entry */ -+} -+ -+VOID kalOidClearance(IN P_GLUE_INFO_T prGlueInfo) -+{ -+ /* if (prGlueInfo->u4TimeoutFlag != 1) { */ -+ /* clear_bit(GLUE_FLAG_OID_BIT, &prGlueInfo->u4Flag); */ -+ if (prGlueInfo->u4OidCompleteFlag != 1) { -+ DBGLOG(OID, TEMP, "kalOidClearance, caller: %p\n", __builtin_return_address(0)); -+ complete(&prGlueInfo->rPendComp); -+ } -+ /* } */ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is used to transfer linux ioctl to OID, and we -+* need to specify the behavior of the OID by ourself -+* -+* @param prGlueInfo Pointer to the glue structure -+* @param pvInfoBuf Data buffer -+* @param u4InfoBufLen Data buffer length -+* @param fgRead Is this a read OID -+* @param fgWaitResp does this OID need to wait for values -+* @param fgCmd does this OID compose command packet -+* @param pu4QryInfoLen The data length of the return values -+* -+* @retval TRUE Success to extract information -+* @retval FALSE Fail to extract correct information -+*/ -+/*----------------------------------------------------------------------------*/ -+ -+/* todo: enqueue the i/o requests for multiple processes access */ -+/* */ -+/* currently, return -1 */ -+/* */ -+ -+/* static GL_IO_REQ_T OidEntry; */ -+ -+WLAN_STATUS -+kalIoctl(IN P_GLUE_INFO_T prGlueInfo, -+ IN PFN_OID_HANDLER_FUNC pfnOidHandler, -+ IN PVOID pvInfoBuf, -+ IN UINT_32 u4InfoBufLen, -+ IN BOOLEAN fgRead, IN BOOLEAN fgWaitResp, IN BOOLEAN fgCmd, IN BOOLEAN fgIsP2pOid, OUT PUINT_32 pu4QryInfoLen) -+{ -+ P_GL_IO_REQ_T prIoReq = NULL; -+ WLAN_STATUS ret = WLAN_STATUS_SUCCESS; -+ -+ if (fgIsResetting == TRUE) -+ return WLAN_STATUS_SUCCESS; -+ -+ /* GLUE_SPIN_LOCK_DECLARATION(); */ -+ ASSERT(prGlueInfo); -+ -+ /* <1> Check if driver is halt */ -+ /* if (prGlueInfo->u4Flag & GLUE_FLAG_HALT) { */ -+ /* return WLAN_STATUS_ADAPTER_NOT_READY; */ -+ /* } */ -+ -+ /* if wait longer than double OID timeout timer, then will show backtrace who held halt lock. -+ at this case, we will return kalIoctl failure because tx_thread may be hung */ -+ if (kalHaltLock(2 * WLAN_OID_TIMEOUT_THRESHOLD)) -+ return WLAN_STATUS_FAILURE; -+ -+ if (kalIsHalted()) { -+ kalHaltUnlock(); -+ return WLAN_STATUS_ADAPTER_NOT_READY; -+ } -+ -+ if (down_interruptible(&prGlueInfo->ioctl_sem)) { -+ kalHaltUnlock(); -+ return WLAN_STATUS_FAILURE; -+ } -+ -+ /* <2> TODO: thread-safe */ -+ -+ /* <3> point to the OidEntry of Glue layer */ -+ -+ prIoReq = &(prGlueInfo->OidEntry); -+ -+ ASSERT(prIoReq); -+ -+ /* <4> Compose the I/O request */ -+ prIoReq->prAdapter = prGlueInfo->prAdapter; -+ prIoReq->pfnOidHandler = pfnOidHandler; -+ prIoReq->pvInfoBuf = pvInfoBuf; -+ prIoReq->u4InfoBufLen = u4InfoBufLen; -+ prIoReq->pu4QryInfoLen = pu4QryInfoLen; -+ prIoReq->fgRead = fgRead; -+ prIoReq->fgWaitResp = fgWaitResp; -+ prIoReq->rStatus = WLAN_STATUS_FAILURE; -+#if CFG_ENABLE_WIFI_DIRECT -+ prIoReq->fgIsP2pOid = fgIsP2pOid; -+#endif -+ -+ /* <5> Reset the status of pending OID */ -+ prGlueInfo->rPendStatus = WLAN_STATUS_FAILURE; -+ /* prGlueInfo->u4TimeoutFlag = 0; */ -+ /* prGlueInfo->u4OidCompleteFlag = 0; */ -+ -+ /* <6> Check if we use the command queue */ -+ prIoReq->u4Flag = fgCmd; -+ -+ /* <7> schedule the OID bit */ -+ set_bit(GLUE_FLAG_OID_BIT, &prGlueInfo->ulFlag); -+ -+ /* <8> Wake up tx thread to handle kick start the I/O request */ -+ wake_up_interruptible(&prGlueInfo->waitq); -+ -+ /* <9> Block and wait for event or timeout, current the timeout is 5 secs */ -+ /* if (wait_for_completion_interruptible_timeout(&prGlueInfo->rPendComp, 5 * KAL_HZ)) { */ -+ /* if (!wait_for_completion_interruptible(&prGlueInfo->rPendComp)) { */ -+ DBGLOG(OID, TEMP, "kalIoctl: before wait, caller: %p\n", __builtin_return_address(0)); -+ wait_for_completion(&prGlueInfo->rPendComp); { -+ /* Case 1: No timeout. */ -+ /* if return WLAN_STATUS_PENDING, the status of cmd is stored in prGlueInfo */ -+ if (prIoReq->rStatus == WLAN_STATUS_PENDING) -+ ret = prGlueInfo->rPendStatus; -+ else -+ ret = prIoReq->rStatus; -+ } -+#if 0 -+ else { -+ /* Case 2: timeout */ -+ /* clear pending OID's cmd in CMD queue */ -+ if (fgCmd) { -+ prGlueInfo->u4TimeoutFlag = 1; -+ wlanReleasePendingOid(prGlueInfo->prAdapter, 0); -+ } -+ ret = WLAN_STATUS_FAILURE; -+ } -+#endif -+ DBGLOG(OID, TEMP, "kalIoctl: done\n"); -+ up(&prGlueInfo->ioctl_sem); -+ kalHaltUnlock(); -+ -+ return ret; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is used to clear all pending security frames -+* -+* \param prGlueInfo Pointer of GLUE Data Structure -+* -+* \retval none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID kalClearSecurityFrames(IN P_GLUE_INFO_T prGlueInfo) -+{ -+ P_QUE_T prCmdQue; -+ QUE_T rTempCmdQue; -+ P_QUE_T prTempCmdQue = &rTempCmdQue; -+ P_QUE_ENTRY_T prQueueEntry = (P_QUE_ENTRY_T) NULL; -+ P_CMD_INFO_T prCmdInfo = (P_CMD_INFO_T) NULL; -+ -+ GLUE_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(prGlueInfo); -+ -+ /* Clear pending security frames in prGlueInfo->rCmdQueue */ -+ prCmdQue = &prGlueInfo->rCmdQueue; -+ -+ GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE); -+ QUEUE_MOVE_ALL(prTempCmdQue, prCmdQue); -+ -+ QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T); -+ while (prQueueEntry) { -+ prCmdInfo = (P_CMD_INFO_T) prQueueEntry; -+ -+ if (prCmdInfo->eCmdType == COMMAND_TYPE_SECURITY_FRAME) { -+ prCmdInfo->pfCmdTimeoutHandler(prGlueInfo->prAdapter, prCmdInfo); -+ cmdBufFreeCmdInfo(prGlueInfo->prAdapter, prCmdInfo); -+ } else { -+ QUEUE_INSERT_TAIL(prCmdQue, prQueueEntry); -+ } -+ -+ QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T); -+ } -+ -+ QUEUE_CONCATENATE_QUEUES(prCmdQue, prTempCmdQue); -+ GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is used to clear pending security frames -+* belongs to dedicated network type -+* -+* \param prGlueInfo Pointer of GLUE Data Structure -+* \param eNetworkTypeIdx Network Type Index -+* -+* \retval none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID kalClearSecurityFramesByNetType(IN P_GLUE_INFO_T prGlueInfo, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx) -+{ -+ P_QUE_T prCmdQue; -+ QUE_T rTempCmdQue; -+ P_QUE_T prTempCmdQue = &rTempCmdQue; -+ P_QUE_ENTRY_T prQueueEntry = (P_QUE_ENTRY_T) NULL; -+ -+ P_CMD_INFO_T prCmdInfo = (P_CMD_INFO_T) NULL; -+ -+ GLUE_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(prGlueInfo); -+ -+ /* Clear pending security frames in prGlueInfo->rCmdQueue */ -+ prCmdQue = &prGlueInfo->rCmdQueue; -+ -+ GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE); -+ QUEUE_MOVE_ALL(prTempCmdQue, prCmdQue); -+ -+ QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T); -+ while (prQueueEntry) { -+ prCmdInfo = (P_CMD_INFO_T) prQueueEntry; -+ -+ if (prCmdInfo->eCmdType == COMMAND_TYPE_SECURITY_FRAME && prCmdInfo->eNetworkType == eNetworkTypeIdx) { -+ prCmdInfo->pfCmdTimeoutHandler(prGlueInfo->prAdapter, prCmdInfo); -+ cmdBufFreeCmdInfo(prGlueInfo->prAdapter, prCmdInfo); -+ } else { -+ QUEUE_INSERT_TAIL(prCmdQue, prQueueEntry); -+ } -+ -+ QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T); -+ } -+ -+ QUEUE_CONCATENATE_QUEUES(prCmdQue, prTempCmdQue); -+ GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is used to clear all pending management frames -+* -+* \param prGlueInfo Pointer of GLUE Data Structure -+* -+* \retval none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID kalClearMgmtFrames(IN P_GLUE_INFO_T prGlueInfo) -+{ -+ P_QUE_T prCmdQue; -+ QUE_T rTempCmdQue; -+ P_QUE_T prTempCmdQue = &rTempCmdQue; -+ P_QUE_ENTRY_T prQueueEntry = (P_QUE_ENTRY_T) NULL; -+ P_CMD_INFO_T prCmdInfo = (P_CMD_INFO_T) NULL; -+ -+ GLUE_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(prGlueInfo); -+ -+ /* Clear pending management frames in prGlueInfo->rCmdQueue */ -+ prCmdQue = &prGlueInfo->rCmdQueue; -+ -+ GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE); -+ QUEUE_MOVE_ALL(prTempCmdQue, prCmdQue); -+ -+ QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T); -+ while (prQueueEntry) { -+ prCmdInfo = (P_CMD_INFO_T) prQueueEntry; -+ -+ if (prCmdInfo->eCmdType == COMMAND_TYPE_MANAGEMENT_FRAME) { -+ wlanReleaseCommand(prGlueInfo->prAdapter, prCmdInfo); -+ cmdBufFreeCmdInfo(prGlueInfo->prAdapter, prCmdInfo); -+ } else { -+ QUEUE_INSERT_TAIL(prCmdQue, prQueueEntry); -+ } -+ -+ QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T); -+ } -+ -+ QUEUE_CONCATENATE_QUEUES(prCmdQue, prTempCmdQue); -+ GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is used to clear all pending management frames -+* belongs to dedicated network type -+* \param prGlueInfo Pointer of GLUE Data Structure -+* -+* \retval none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID kalClearMgmtFramesByNetType(IN P_GLUE_INFO_T prGlueInfo, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx) -+{ -+ P_QUE_T prCmdQue; -+ QUE_T rTempCmdQue; -+ P_QUE_T prTempCmdQue = &rTempCmdQue; -+ P_QUE_ENTRY_T prQueueEntry = (P_QUE_ENTRY_T) NULL; -+ P_CMD_INFO_T prCmdInfo = (P_CMD_INFO_T) NULL; -+ -+ GLUE_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(prGlueInfo); -+ -+ /* Clear pending management frames in prGlueInfo->rCmdQueue */ -+ prCmdQue = &prGlueInfo->rCmdQueue; -+ -+ GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE); -+ QUEUE_MOVE_ALL(prTempCmdQue, prCmdQue); -+ -+ QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T); -+ while (prQueueEntry) { -+ prCmdInfo = (P_CMD_INFO_T) prQueueEntry; -+ -+ if (prCmdInfo->eCmdType == COMMAND_TYPE_MANAGEMENT_FRAME && -+ prCmdInfo->eNetworkType == eNetworkTypeIdx) { -+ wlanReleaseCommand(prGlueInfo->prAdapter, prCmdInfo); -+ cmdBufFreeCmdInfo(prGlueInfo->prAdapter, prCmdInfo); -+ } else { -+ QUEUE_INSERT_TAIL(prCmdQue, prQueueEntry); -+ } -+ -+ QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T); -+ } -+ -+ QUEUE_CONCATENATE_QUEUES(prCmdQue, prTempCmdQue); -+ GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE); -+} /* kalClearMgmtFramesByNetType */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief This function is a kernel thread function for handling command packets -+* Tx requests and interrupt events -+* -+* @param data data pointer to private data of tx_thread -+* -+* @retval If the function succeeds, the return value is 0. -+* Otherwise, an error code is returned. -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+ -+int tx_thread(void *data) -+{ -+ struct net_device *dev = data; -+ P_GLUE_INFO_T prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(dev)); -+ -+ P_QUE_ENTRY_T prQueueEntry = NULL; -+ P_GL_IO_REQ_T prIoReq = NULL; -+ P_QUE_T prTxQueue = NULL; -+ P_QUE_T prCmdQue = NULL; -+ -+ int ret = 0; -+ -+ BOOLEAN fgNeedHwAccess = FALSE; -+ -+ struct sk_buff *prSkb = NULL; -+ -+ /* for spin lock acquire and release */ -+ GLUE_SPIN_LOCK_DECLARATION(); -+ -+ prTxQueue = &prGlueInfo->rTxQueue; -+ prCmdQue = &prGlueInfo->rCmdQueue; -+ -+ current->flags |= PF_NOFREEZE; -+ -+ DBGLOG(INIT, INFO, "tx_thread starts running...\n"); -+ -+ while (TRUE) { -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ /*run p2p multicast list work. */ -+ if (test_and_clear_bit(GLUE_FLAG_SUB_MOD_MULTICAST_BIT, &prGlueInfo->ulFlag)) -+ p2pSetMulticastListWorkQueueWrapper(prGlueInfo); -+#endif -+ -+ if (test_and_clear_bit(GLUE_FLAG_FRAME_FILTER_AIS_BIT, &prGlueInfo->ulFlag)) { -+ P_AIS_FSM_INFO_T prAisFsmInfo = (P_AIS_FSM_INFO_T) NULL; -+ /* printk("prGlueInfo->u4OsMgmtFrameFilter = %x", prGlueInfo->u4OsMgmtFrameFilter); */ -+ prAisFsmInfo = &(prGlueInfo->prAdapter->rWifiVar.rAisFsmInfo); -+ prAisFsmInfo->u4AisPacketFilter = prGlueInfo->u4OsMgmtFrameFilter; -+ } -+ -+ if (prGlueInfo->ulFlag & GLUE_FLAG_HALT) { -+ KAL_WAKE_UNLOCK(prGlueInfo->prAdapter, &(prGlueInfo->prAdapter)->rTxThreadWakeLock); -+ DBGLOG(INIT, INFO, "tx_thread should stop now...\n"); -+ break; -+ } -+ -+ /* -+ * sleep on waitqueue if no events occurred. Event contain (1) GLUE_FLAG_INT -+ * (2) GLUE_FLAG_OID (3) GLUE_FLAG_TXREQ (4) GLUE_FLAG_HALT -+ * -+ */ -+ KAL_WAKE_UNLOCK(prGlueInfo->prAdapter, &(prGlueInfo->prAdapter)->rTxThreadWakeLock); -+ -+ ret = wait_event_interruptible(prGlueInfo->waitq, (prGlueInfo->ulFlag != 0)); -+ -+ KAL_WAKE_LOCK(prGlueInfo->prAdapter, &(prGlueInfo->prAdapter)->rTxThreadWakeLock); -+ -+/* #if (CONF_HIF_LOOPBACK_AUTO == 1) */ -+/* if (test_and_clear_bit(GLUE_FLAG_HIF_LOOPBK_AUTO_BIT, &prGlueInfo->u4Flag)) { */ -+/* kalDevLoopbkAuto(prGlueInfo); */ -+/* } */ -+/* #endif */ /* CONF_HIF_LOOPBACK_AUTO */ -+ -+#if CFG_DBG_GPIO_PINS -+ /* TX thread Wake up */ -+ mtk_wcn_stp_debug_gpio_assert(IDX_TX_THREAD, DBG_TIE_LOW); -+#endif -+#if CFG_ENABLE_WIFI_DIRECT -+ /*run p2p multicast list work. */ -+ if (test_and_clear_bit(GLUE_FLAG_SUB_MOD_MULTICAST_BIT, &prGlueInfo->ulFlag)) -+ p2pSetMulticastListWorkQueueWrapper(prGlueInfo); -+ -+ if (test_and_clear_bit(GLUE_FLAG_FRAME_FILTER_BIT, &prGlueInfo->ulFlag)) { -+ p2pFuncUpdateMgmtFrameRegister(prGlueInfo->prAdapter, -+ prGlueInfo->prP2PInfo->u4OsMgmtFrameFilter); -+ } -+#endif -+ if (test_and_clear_bit(GLUE_FLAG_FRAME_FILTER_AIS_BIT, &prGlueInfo->ulFlag)) { -+ P_AIS_FSM_INFO_T prAisFsmInfo = (P_AIS_FSM_INFO_T) NULL; -+ /* printk("prGlueInfo->u4OsMgmtFrameFilter = %x", prGlueInfo->u4OsMgmtFrameFilter); */ -+ prAisFsmInfo = &(prGlueInfo->prAdapter->rWifiVar.rAisFsmInfo); -+ prAisFsmInfo->u4AisPacketFilter = prGlueInfo->u4OsMgmtFrameFilter; -+ } -+ -+ if (prGlueInfo->ulFlag & GLUE_FLAG_HALT) { -+ KAL_WAKE_UNLOCK(prGlueInfo->prAdapter, &(prGlueInfo->prAdapter)->rTxThreadWakeLock); -+ DBGLOG(INIT, INFO, "<1>tx_thread should stop now...\n"); -+ break; -+ } -+ -+ fgNeedHwAccess = FALSE; -+ -+ /* Handle Interrupt */ -+ if (test_and_clear_bit(GLUE_FLAG_INT_BIT, &prGlueInfo->ulFlag)) { -+ if (fgNeedHwAccess == FALSE) { -+ fgNeedHwAccess = TRUE; -+ -+ wlanAcquirePowerControl(prGlueInfo->prAdapter); -+ } -+ -+ /* the Wi-Fi interrupt is already disabled in mmc thread, -+ so we set the flag only to enable the interrupt later */ -+ prGlueInfo->prAdapter->fgIsIntEnable = FALSE; -+ /* wlanISR(prGlueInfo->prAdapter, TRUE); */ -+ -+ if (prGlueInfo->ulFlag & GLUE_FLAG_HALT) { -+ /* Should stop now... skip pending interrupt */ -+ DBGLOG(INIT, INFO, "ignore pending interrupt\n"); -+ } else { -+ prGlueInfo->TaskIsrCnt++; -+ wlanIST(prGlueInfo->prAdapter); -+ } -+ } -+ -+ /* transfer ioctl to OID request */ -+#if 0 -+ if (prGlueInfo->u4Flag & GLUE_FLAG_HALT) { -+ DBGLOG(INIT, INFO, "<2>tx_thread should stop now...\n"); -+ break; -+ } -+#endif -+ -+ do { -+ if (test_and_clear_bit(GLUE_FLAG_OID_BIT, &prGlueInfo->ulFlag)) { -+ /* get current prIoReq */ -+ prGlueInfo->u4OidCompleteFlag = 0; -+ -+ prIoReq = &(prGlueInfo->OidEntry); -+#if CFG_ENABLE_WIFI_DIRECT -+ if (prGlueInfo->prAdapter->fgIsP2PRegistered == FALSE && prIoReq->fgIsP2pOid == TRUE) { -+ /* if this Oid belongs to p2p and p2p module is removed -+ * do nothing, -+ */ -+ } else -+#endif -+ { -+ if (FALSE == prIoReq->fgRead) { -+ prIoReq->rStatus = wlanSetInformation(prIoReq->prAdapter, -+ prIoReq->pfnOidHandler, -+ prIoReq->pvInfoBuf, -+ prIoReq->u4InfoBufLen, -+ prIoReq->pu4QryInfoLen); -+ } else { -+ prIoReq->rStatus = wlanQueryInformation(prIoReq->prAdapter, -+ prIoReq->pfnOidHandler, -+ prIoReq->pvInfoBuf, -+ prIoReq->u4InfoBufLen, -+ prIoReq->pu4QryInfoLen); -+ } -+ -+ if (prIoReq->rStatus != WLAN_STATUS_PENDING) { -+ DBGLOG(OID, TEMP, "tx_thread, complete\n"); -+ complete(&prGlueInfo->rPendComp); -+ } else { -+ wlanoidTimeoutCheck(prGlueInfo->prAdapter, prIoReq->pfnOidHandler); -+ } -+ } -+ } -+ -+ } while (FALSE); -+ -+ /* -+ * -+ * if TX request, clear the TXREQ flag. TXREQ set by kalSetEvent/GlueSetEvent -+ * indicates the following requests occur -+ * -+ */ -+#if 0 -+ if (prGlueInfo->u4Flag & GLUE_FLAG_HALT) { -+ DBGLOG(INIT, INFO, "<3>tx_thread should stop now...\n"); -+ break; -+ } -+#endif -+ -+ if (test_and_clear_bit(GLUE_FLAG_TXREQ_BIT, &prGlueInfo->ulFlag)) { -+ /* Process Mailbox Messages */ -+ wlanProcessMboxMessage(prGlueInfo->prAdapter); -+ -+ /* Process CMD request */ -+ do { -+ if (prCmdQue->u4NumElem > 0) { -+ if (fgNeedHwAccess == FALSE) { -+ fgNeedHwAccess = TRUE; -+ -+ wlanAcquirePowerControl(prGlueInfo->prAdapter); -+ } -+ wlanProcessCommandQueue(prGlueInfo->prAdapter, prCmdQue); -+ } -+ } while (FALSE); -+ -+ /* Handle Packet Tx */ -+ { -+ while (QUEUE_IS_NOT_EMPTY(prTxQueue)) { -+ GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_TX_QUE); -+ QUEUE_REMOVE_HEAD(prTxQueue, prQueueEntry, P_QUE_ENTRY_T); -+ GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_TX_QUE); -+ -+ ASSERT(prQueueEntry); -+ if (NULL == prQueueEntry) -+ break; -+ -+ prSkb = (struct sk_buff *)GLUE_GET_PKT_DESCRIPTOR(prQueueEntry); -+ ASSERT(prSkb); -+ if (NULL == prSkb) { -+ DBGLOG(INIT, ERROR, "prSkb == NULL!\n"); -+ continue; -+ } -+#if (CFG_SUPPORT_TDLS_DBG == 1) -+ UINT8 *pkt = prSkb->data; -+ UINT16 u2Identifier; -+ -+ if ((*(pkt + 12) == 0x08) && (*(pkt + 13) == 0x00)) { -+ /* ip */ -+ u2Identifier = ((*(pkt + 18)) << 8) | (*(pkt + 19)); -+ DBGLOG(INIT, LOUD, " %d\n", u2Identifier); -+ } -+#endif -+ if (wlanEnqueueTxPacket(prGlueInfo->prAdapter, -+ (P_NATIVE_PACKET) prSkb) == WLAN_STATUS_RESOURCES) { -+ /* no available entry in rFreeMsduInfoList */ -+ GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_TX_QUE); -+ QUEUE_INSERT_HEAD(prTxQueue, prQueueEntry); -+ GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_TX_QUE); -+ -+ break; -+ } -+ } -+ -+ if (wlanGetTxPendingFrameCount(prGlueInfo->prAdapter) > 0) { -+ /* send packets to HIF here */ -+ wlanTxPendingPackets(prGlueInfo->prAdapter, &fgNeedHwAccess); -+ } -+ } -+ -+ } -+ -+ /* Process RX, In linux, we don't need to free sk_buff by ourself */ -+ -+ /* In linux, we don't need to free sk_buff by ourself */ -+ -+ /* In linux, we don't do reset */ -+ if (fgNeedHwAccess == TRUE) -+ wlanReleasePowerControl(prGlueInfo->prAdapter); -+ -+ /* handle cnmTimer time out */ -+ if (test_and_clear_bit(GLUE_FLAG_TIMEOUT_BIT, &prGlueInfo->ulFlag)) -+ wlanTimerTimeoutCheck(prGlueInfo->prAdapter); -+#if CFG_DBG_GPIO_PINS -+ /* TX thread go to sleep */ -+ if (!prGlueInfo->ulFlag) -+ mtk_wcn_stp_debug_gpio_assert(IDX_TX_THREAD, DBG_TIE_HIGH); -+#endif -+ } -+ -+#if 0 -+ if (fgNeedHwAccess == TRUE) -+ wlanReleasePowerControl(prGlueInfo->prAdapter); -+#endif -+ -+ /* exit while loop, tx thread is closed so we flush all pending packets */ -+ /* flush the pending TX packets */ -+ if (prGlueInfo->i4TxPendingFrameNum > 0) -+ kalFlushPendingTxPackets(prGlueInfo); -+ -+ /* flush pending security frames */ -+ if (prGlueInfo->i4TxPendingSecurityFrameNum > 0) -+ kalClearSecurityFrames(prGlueInfo); -+ -+ /* remove pending oid */ -+ wlanReleasePendingOid(prGlueInfo->prAdapter, 0); -+ -+ /* In linux, we don't need to free sk_buff by ourself */ -+ -+ DBGLOG(INIT, INFO, "mtk_sdiod stops\n"); -+ complete(&prGlueInfo->rHaltComp); -+ -+ return 0; -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is used to check if card is removed -+* -+* \param pvGlueInfo Pointer of GLUE Data Structure -+* -+* \retval TRUE: card is removed -+* FALSE: card is still attached -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN kalIsCardRemoved(IN P_GLUE_INFO_T prGlueInfo) -+{ -+ ASSERT(prGlueInfo); -+ -+ return FALSE; -+ /* Linux MMC doesn't have removal notification yet */ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * \brief This routine is used to send command to firmware for overriding netweork address -+ * -+ * \param pvGlueInfo Pointer of GLUE Data Structure -+ -+ * \retval TRUE -+ * FALSE -+ */ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN kalRetrieveNetworkAddress(IN P_GLUE_INFO_T prGlueInfo, IN OUT PARAM_MAC_ADDRESS *prMacAddr) -+{ -+ ASSERT(prGlueInfo); -+ -+ if (prGlueInfo->fgIsMacAddrOverride == FALSE) { -+#if !defined(CONFIG_X86) -+#if !defined(CONFIG_MTK_TC1_FEATURE) -+ UINT_32 i; -+#endif -+ BOOLEAN fgIsReadError = FALSE; -+ -+#if !defined(CONFIG_MTK_TC1_FEATURE) -+ for (i = 0; i < MAC_ADDR_LEN; i += 2) { -+ if (kalCfgDataRead16(prGlueInfo, -+ OFFSET_OF(WIFI_CFG_PARAM_STRUCT, aucMacAddress) + i, -+ (PUINT_16) (((PUINT_8) prMacAddr) + i)) == FALSE) { -+ fgIsReadError = TRUE; -+ break; -+ } -+ } -+#else -+ TC1_FAC_NAME(FacReadWifiMacAddr) ((unsigned char *)prMacAddr); -+#endif -+ -+ if (fgIsReadError == TRUE) -+ return FALSE; -+ else -+ return TRUE; -+#else -+ /* x86 Linux doesn't need to override network address so far */ -+ return FALSE; -+#endif -+ } else { -+ COPY_MAC_ADDR(prMacAddr, prGlueInfo->rMacAddrOverride); -+ -+ return TRUE; -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is used to flush pending TX packets in glue layer -+* -+* \param pvGlueInfo Pointer of GLUE Data Structure -+* -+* \retval none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID kalFlushPendingTxPackets(IN P_GLUE_INFO_T prGlueInfo) -+{ -+ P_QUE_T prTxQue; -+ P_QUE_ENTRY_T prQueueEntry; -+ PVOID prPacket; -+ -+ GLUE_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(prGlueInfo); -+ -+ prTxQue = &(prGlueInfo->rTxQueue); -+ -+ if (prGlueInfo->i4TxPendingFrameNum) { -+ while (TRUE) { -+ GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_TX_QUE); -+ QUEUE_REMOVE_HEAD(prTxQue, prQueueEntry, P_QUE_ENTRY_T); -+ GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_TX_QUE); -+ -+ if (prQueueEntry == NULL) -+ break; -+ -+ prPacket = GLUE_GET_PKT_DESCRIPTOR(prQueueEntry); -+ -+ kalSendComplete(prGlueInfo, prPacket, WLAN_STATUS_NOT_ACCEPTED); -+ } -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is get indicated media state -+* -+* \param pvGlueInfo Pointer of GLUE Data Structure -+* -+* \retval -+*/ -+/*----------------------------------------------------------------------------*/ -+ENUM_PARAM_MEDIA_STATE_T kalGetMediaStateIndicated(IN P_GLUE_INFO_T prGlueInfo) -+{ -+ ASSERT(prGlueInfo); -+ -+ return prGlueInfo->eParamMediaStateIndicated; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is used to set indicated media state -+* -+* \param pvGlueInfo Pointer of GLUE Data Structure -+* -+* \retval none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID kalSetMediaStateIndicated(IN P_GLUE_INFO_T prGlueInfo, IN ENUM_PARAM_MEDIA_STATE_T eParamMediaStateIndicate) -+{ -+ ASSERT(prGlueInfo); -+ -+ prGlueInfo->eParamMediaStateIndicated = eParamMediaStateIndicate; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is used to clear pending OID staying in command queue -+* -+* \param prGlueInfo Pointer of GLUE Data Structure -+* -+* \retval none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID kalOidCmdClearance(IN P_GLUE_INFO_T prGlueInfo) -+{ -+ P_QUE_T prCmdQue; -+ QUE_T rTempCmdQue; -+ P_QUE_T prTempCmdQue = &rTempCmdQue; -+ P_QUE_ENTRY_T prQueueEntry = (P_QUE_ENTRY_T) NULL; -+ P_CMD_INFO_T prCmdInfo = (P_CMD_INFO_T) NULL; -+ -+ GLUE_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(prGlueInfo); -+ -+ prCmdQue = &prGlueInfo->rCmdQueue; -+ -+ GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE); -+ QUEUE_MOVE_ALL(prTempCmdQue, prCmdQue); -+ -+ QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T); -+ while (prQueueEntry) { -+ -+ if (((P_CMD_INFO_T) prQueueEntry)->fgIsOid) { -+ prCmdInfo = (P_CMD_INFO_T) prQueueEntry; -+ break; -+ } -+ QUEUE_INSERT_TAIL(prCmdQue, prQueueEntry); -+ -+ QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T); -+ } -+ -+ QUEUE_CONCATENATE_QUEUES(prCmdQue, prTempCmdQue); -+ GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE); -+ -+ if (prCmdInfo) { -+ if (prCmdInfo->pfCmdTimeoutHandler) -+ prCmdInfo->pfCmdTimeoutHandler(prGlueInfo->prAdapter, prCmdInfo); -+ else -+ kalOidComplete(prGlueInfo, prCmdInfo->fgSetQuery, 0, WLAN_STATUS_NOT_ACCEPTED); -+ -+ prGlueInfo->u4OidCompleteFlag = 1; -+ cmdBufFreeCmdInfo(prGlueInfo->prAdapter, prCmdInfo); -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is used to insert command into prCmdQueue -+* -+* \param prGlueInfo Pointer of GLUE Data Structure -+* prQueueEntry Pointer of queue entry to be inserted -+* -+* \retval none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID kalEnqueueCommand(IN P_GLUE_INFO_T prGlueInfo, IN P_QUE_ENTRY_T prQueueEntry) -+{ -+ P_QUE_T prCmdQue; -+ P_CMD_INFO_T prCmdInfo; -+ P_MSDU_INFO_T prMsduInfo; -+ -+ GLUE_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(prGlueInfo); -+ ASSERT(prQueueEntry); -+ -+ prCmdQue = &prGlueInfo->rCmdQueue; -+ -+ prCmdInfo = (P_CMD_INFO_T) prQueueEntry; -+ if (prCmdInfo->prPacket && prCmdInfo->eCmdType == COMMAND_TYPE_MANAGEMENT_FRAME) { -+ prMsduInfo = (P_MSDU_INFO_T) (prCmdInfo->prPacket); -+ prMsduInfo->eCmdType = prCmdInfo->eCmdType; -+ prMsduInfo->ucCID = prCmdInfo->ucCID; -+ prMsduInfo->u4InqueTime = kalGetTimeTick(); -+ } -+ -+ GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE); -+ QUEUE_INSERT_TAIL(prCmdQue, prQueueEntry); -+ GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Handle EVENT_ID_ASSOC_INFO event packet by indicating to OS with -+* proper information -+* -+* @param pvGlueInfo Pointer of GLUE Data Structure -+* @param prAssocInfo Pointer of EVENT_ID_ASSOC_INFO Packet -+* -+* @return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID kalHandleAssocInfo(IN P_GLUE_INFO_T prGlueInfo, IN P_EVENT_ASSOC_INFO prAssocInfo) -+{ -+ /* to do */ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is used to get firmware load address from registry -+* -+* \param prGlueInfo Pointer of GLUE Data Structure -+* -+* \retval -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT_32 kalGetFwLoadAddress(IN P_GLUE_INFO_T prGlueInfo) -+{ -+ ASSERT(prGlueInfo); -+ -+ return prGlueInfo->rRegInfo.u4LoadAddress; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is used to get firmware start address from registry -+* -+* \param prGlueInfo Pointer of GLUE Data Structure -+* -+* \retval -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT_32 kalGetFwStartAddress(IN P_GLUE_INFO_T prGlueInfo) -+{ -+ ASSERT(prGlueInfo); -+ -+ return prGlueInfo->rRegInfo.u4StartAddress; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * * @brief Notify OS with SendComplete event of the specific packet. Linux should -+ * * free packets here. -+ * * -+ * * @param pvGlueInfo Pointer of GLUE Data Structure -+ * * @param pvPacket Pointer of Packet Handle -+ * * @param status Status Code for OS upper layer -+ * * -+ * * @return none -+ * */ -+/*----------------------------------------------------------------------------*/ -+ -+/* / Todo */ -+VOID kalSecurityFrameSendComplete(IN P_GLUE_INFO_T prGlueInfo, IN PVOID pvPacket, IN WLAN_STATUS rStatus) -+{ -+ ASSERT(pvPacket); -+ -+ dev_kfree_skb((struct sk_buff *)pvPacket); -+ if (prGlueInfo) -+ prGlueInfo->u8SkbFreed++; -+ GLUE_DEC_REF_CNT(prGlueInfo->i4TxPendingSecurityFrameNum); -+} -+ -+UINT_32 kalGetTxPendingFrameCount(IN P_GLUE_INFO_T prGlueInfo) -+{ -+ ASSERT(prGlueInfo); -+ -+ return (UINT_32) (prGlueInfo->i4TxPendingFrameNum); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is used to retrieve the number of pending commands -+* (including MMPDU, 802.1X and command packets) -+* -+* \param prGlueInfo Pointer of GLUE Data Structure -+* -+* \retval -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT_32 kalGetTxPendingCmdCount(IN P_GLUE_INFO_T prGlueInfo) -+{ -+ P_QUE_T prCmdQue; -+ -+ ASSERT(prGlueInfo); -+ prCmdQue = &prGlueInfo->rCmdQueue; -+ -+ return prCmdQue->u4NumElem; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Timer Initialization Procedure -+* -+* \param[in] prGlueInfo Pointer to GLUE Data Structure -+* \param[in] prTimerHandler Pointer to timer handling function, whose only -+* argument is "prAdapter" -+* -+* \retval none -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+ -+/* static struct timer_list tickfn; */ -+ -+VOID kalOsTimerInitialize(IN P_GLUE_INFO_T prGlueInfo, IN PVOID prTimerHandler) -+{ -+ -+ ASSERT(prGlueInfo); -+ -+ timer_setup(&(prGlueInfo->tickfn), prTimerHandler, 0); -+} -+ -+/* Todo */ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to set the time to do the time out check. -+* -+* \param[in] prGlueInfo Pointer to GLUE Data Structure -+* \param[in] rInterval Time out interval from current time. -+* -+* \retval TRUE Success. -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN kalSetTimer(IN P_GLUE_INFO_T prGlueInfo, IN UINT_32 u4Interval) -+{ -+ ASSERT(prGlueInfo); -+ del_timer_sync(&(prGlueInfo->tickfn)); -+ -+ prGlueInfo->tickfn.expires = jiffies + u4Interval * HZ / MSEC_PER_SEC; -+ add_timer(&(prGlueInfo->tickfn)); -+ -+ return TRUE; /* success */ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to cancel -+* -+* \param[in] prGlueInfo Pointer to GLUE Data Structure -+* -+* \retval TRUE : Timer has been canceled -+* FALAE : Timer doens't exist -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN kalCancelTimer(IN P_GLUE_INFO_T prGlueInfo) -+{ -+ ASSERT(prGlueInfo); -+ -+ clear_bit(GLUE_FLAG_TIMEOUT_BIT, &prGlueInfo->ulFlag); -+ -+ if (del_timer_sync(&(prGlueInfo->tickfn)) >= 0) -+ return TRUE; -+ else -+ return FALSE; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is a callback function for scanning done -+* -+* \param[in] prGlueInfo Pointer to GLUE Data Structure -+* -+* \retval none -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID kalScanDone(IN P_GLUE_INFO_T prGlueInfo, IN ENUM_KAL_NETWORK_TYPE_INDEX_T eNetTypeIdx, IN WLAN_STATUS status) -+{ -+ P_AIS_FSM_INFO_T prAisFsmInfo; -+ -+ ASSERT(prGlueInfo); -+ -+ prAisFsmInfo = &(prGlueInfo->prAdapter->rWifiVar.rAisFsmInfo); -+ /* report all queued beacon/probe response frames to upper layer */ -+ scanReportBss2Cfg80211(prGlueInfo->prAdapter, BSS_TYPE_INFRASTRUCTURE, NULL); -+ cnmTimerStopTimer(prGlueInfo->prAdapter, &prAisFsmInfo->rScanDoneTimer); -+ -+ /* check for system configuration for generating error message on scan list */ -+ wlanCheckSystemConfiguration(prGlueInfo->prAdapter); -+ -+ kalIndicateStatusAndComplete(prGlueInfo, WLAN_STATUS_SCAN_COMPLETE, NULL, 0); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is used to generate a random number -+* -+* \param none -+* -+* \retval UINT_32 -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT_32 kalRandomNumber(VOID) -+{ -+ UINT_32 number = 0; -+ -+ get_random_bytes(&number, 4); -+ -+ return number; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * \brief command timeout call-back function -+ * -+ * \param[in] prGlueInfo Pointer to the GLUE data structure. -+ * -+ * \retval (none) -+ */ -+/*----------------------------------------------------------------------------*/ -+VOID kalTimeoutHandler(struct timer_list *t) -+{ -+ -+ P_GLUE_INFO_T prGlueInfo = from_timer(prGlueInfo, t, tickfn); -+ -+ ASSERT(prGlueInfo); -+ -+ /* Notify tx thread for timeout event */ -+ set_bit(GLUE_FLAG_TIMEOUT_BIT, &prGlueInfo->ulFlag); -+ wake_up_interruptible(&prGlueInfo->waitq); -+ -+} -+ -+VOID kalSetEvent(P_GLUE_INFO_T pr) -+{ -+ set_bit(GLUE_FLAG_TXREQ_BIT, &pr->ulFlag); -+ wake_up_interruptible(&pr->waitq); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief to check if configuration file (NVRAM/Registry) exists -+* -+* \param[in] -+* prGlueInfo -+* -+* \return -+* TRUE -+* FALSE -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN kalIsConfigurationExist(IN P_GLUE_INFO_T prGlueInfo) -+{ -+#if !defined(CONFIG_X86) -+ ASSERT(prGlueInfo); -+ -+ return prGlueInfo->fgNvramAvailable; -+#else -+ /* there is no configuration data for x86-linux */ -+ return FALSE; -+#endif -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief to retrieve Registry information -+* -+* \param[in] -+* prGlueInfo -+* -+* \return -+* Pointer of REG_INFO_T -+*/ -+/*----------------------------------------------------------------------------*/ -+P_REG_INFO_T kalGetConfiguration(IN P_GLUE_INFO_T prGlueInfo) -+{ -+ ASSERT(prGlueInfo); -+ -+ return &(prGlueInfo->rRegInfo); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief to retrieve version information of corresponding configuration file -+* -+* \param[in] -+* prGlueInfo -+* -+* \param[out] -+* pu2Part1CfgOwnVersion -+* pu2Part1CfgPeerVersion -+* pu2Part2CfgOwnVersion -+* pu2Part2CfgPeerVersion -+* -+* \return -+* NONE -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+kalGetConfigurationVersion(IN P_GLUE_INFO_T prGlueInfo, -+ OUT PUINT_16 pu2Part1CfgOwnVersion, -+ OUT PUINT_16 pu2Part1CfgPeerVersion, -+ OUT PUINT_16 pu2Part2CfgOwnVersion, OUT PUINT_16 pu2Part2CfgPeerVersion) -+{ -+ ASSERT(prGlueInfo); -+ -+ ASSERT(pu2Part1CfgOwnVersion); -+ ASSERT(pu2Part1CfgPeerVersion); -+ ASSERT(pu2Part2CfgOwnVersion); -+ ASSERT(pu2Part2CfgPeerVersion); -+ -+ kalCfgDataRead16(prGlueInfo, OFFSET_OF(WIFI_CFG_PARAM_STRUCT, u2Part1OwnVersion), pu2Part1CfgOwnVersion); -+ -+ kalCfgDataRead16(prGlueInfo, OFFSET_OF(WIFI_CFG_PARAM_STRUCT, u2Part1PeerVersion), pu2Part1CfgPeerVersion); -+ -+ kalCfgDataRead16(prGlueInfo, OFFSET_OF(WIFI_CFG_PARAM_STRUCT, u2Part2OwnVersion), pu2Part2CfgOwnVersion); -+ -+ kalCfgDataRead16(prGlueInfo, OFFSET_OF(WIFI_CFG_PARAM_STRUCT, u2Part2PeerVersion), pu2Part2CfgPeerVersion); -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief to check if the WPS is active or not -+* -+* \param[in] -+* prGlueInfo -+* -+* \return -+* TRUE -+* FALSE -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN kalWSCGetActiveState(IN P_GLUE_INFO_T prGlueInfo) -+{ -+ ASSERT(prGlueInfo); -+ -+ return prGlueInfo->fgWpsActive; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief update RSSI and LinkQuality to GLUE layer -+* -+* \param[in] -+* prGlueInfo -+* eNetTypeIdx -+* cRssi -+* cLinkQuality -+* -+* \return -+* None -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+kalUpdateRSSI(IN P_GLUE_INFO_T prGlueInfo, -+ IN ENUM_KAL_NETWORK_TYPE_INDEX_T eNetTypeIdx, IN INT_8 cRssi, IN INT_8 cLinkQuality) -+{ -+ struct iw_statistics *pStats = (struct iw_statistics *)NULL; -+ -+ ASSERT(prGlueInfo); -+ -+ switch (eNetTypeIdx) { -+ case KAL_NETWORK_TYPE_AIS_INDEX: -+ pStats = (struct iw_statistics *)(&(prGlueInfo->rIwStats)); -+ break; -+#if CFG_ENABLE_WIFI_DIRECT -+#if CFG_SUPPORT_P2P_RSSI_QUERY -+ case KAL_NETWORK_TYPE_P2P_INDEX: -+ pStats = (struct iw_statistics *)(&(prGlueInfo->rP2pIwStats)); -+ break; -+#endif -+#endif -+ default: -+ break; -+ -+ } -+ -+ if (pStats) { -+ pStats->qual.qual = cLinkQuality; -+ pStats->qual.noise = 0; -+ pStats->qual.updated = IW_QUAL_QUAL_UPDATED | IW_QUAL_NOISE_UPDATED | IW_QUAL_DBM; -+ pStats->qual.level = 0x100 + cRssi; -+ pStats->qual.updated |= IW_QUAL_LEVEL_UPDATED; -+ } -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Pre-allocate I/O buffer -+* -+* \param[in] -+* none -+* -+* \return -+* TRUE -+* FALSE -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN kalInitIOBuffer(VOID) -+{ -+ UINT_32 u4Size; -+ -+ if (CFG_COALESCING_BUFFER_SIZE >= CFG_RX_COALESCING_BUFFER_SIZE) -+ u4Size = CFG_COALESCING_BUFFER_SIZE + sizeof(ENHANCE_MODE_DATA_STRUCT_T); -+ else -+ u4Size = CFG_RX_COALESCING_BUFFER_SIZE + sizeof(ENHANCE_MODE_DATA_STRUCT_T); -+ -+#ifdef MTK_DMA_BUF_MEMCPY_SUP -+ pvDmaBuffer = dma_alloc_coherent(NULL, CFG_RX_MAX_PKT_SIZE, &pvDmaPhyBuf, GFP_KERNEL); -+ if (pvDmaBuffer == NULL) -+ return FALSE; -+#endif /* MTK_DMA_BUF_MEMCPY_SUP */ -+ -+ pvIoBuffer = kmalloc(u4Size, GFP_KERNEL); -+/* pvIoBuffer = dma_alloc_coherent(NULL, u4Size, &pvIoPhyBuf, GFP_KERNEL); */ -+ if (pvIoBuffer) { -+ pvIoBufferSize = u4Size; -+ pvIoBufferUsage = 0; -+ -+ return TRUE; -+ } -+ -+ return FALSE; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Free pre-allocated I/O buffer -+* -+* \param[in] -+* none -+* -+* \return -+* none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID kalUninitIOBuffer(VOID) -+{ -+ kfree(pvIoBuffer); -+#ifdef MTK_DMA_BUF_MEMCPY_SUP -+ dma_free_coherent(NULL, CFG_RX_MAX_PKT_SIZE, pvDmaBuffer, pvDmaPhyBuf); -+#endif /* MTK_DMA_BUF_MEMCPY_SUP */ -+ /* dma_free_coherent(NULL, pvIoBufferSize, pvIoBuffer, pvIoPhyBuf); */ -+ -+ pvIoBuffer = (PVOID) NULL; -+ pvIoBufferSize = 0; -+ pvIoBufferUsage = 0; -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Dispatch pre-allocated I/O buffer -+* -+* \param[in] -+* u4AllocSize -+* -+* \return -+* PVOID for pointer of pre-allocated I/O buffer -+*/ -+/*----------------------------------------------------------------------------*/ -+PVOID kalAllocateIOBuffer(IN UINT_32 u4AllocSize) -+{ -+ PVOID ret = (PVOID) NULL; -+ -+ if (pvIoBuffer) { -+ if (u4AllocSize <= (pvIoBufferSize - pvIoBufferUsage)) { -+ ret = (PVOID) &(((PUINT_8) (pvIoBuffer))[pvIoBufferUsage]); -+ pvIoBufferUsage += u4AllocSize; -+ } -+ } else { -+ /* fault tolerance */ -+ ret = (PVOID) kalMemAlloc(u4AllocSize, PHY_MEM_TYPE); -+ } -+ -+ return ret; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Release all dispatched I/O buffer -+* -+* \param[in] -+* none -+* -+* \return -+* none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID kalReleaseIOBuffer(IN PVOID pvAddr, IN UINT_32 u4Size) -+{ -+ if (pvIoBuffer) { -+ pvIoBufferUsage -= u4Size; -+ } else { -+ /* fault tolerance */ -+ kalMemFree(pvAddr, PHY_MEM_TYPE, u4Size); -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] prAdapter Pointer of ADAPTER_T -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+kalGetChannelList(IN P_GLUE_INFO_T prGlueInfo, -+ IN ENUM_BAND_T eSpecificBand, -+ IN UINT_8 ucMaxChannelNum, IN PUINT_8 pucNumOfChannel, IN P_RF_CHANNEL_INFO_T paucChannelList) -+{ -+ rlmDomainGetChnlList(prGlueInfo->prAdapter, eSpecificBand, FALSE, ucMaxChannelNum, -+ pucNumOfChannel, paucChannelList); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] prAdapter Pointer of ADAPTER_T -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN kalIsAPmode(IN P_GLUE_INFO_T prGlueInfo) -+{ -+#if CFG_ENABLE_WIFI_DIRECT -+ if (IS_NET_ACTIVE(prGlueInfo->prAdapter, NETWORK_TYPE_P2P_INDEX) && -+ p2pFuncIsAPMode(prGlueInfo->prAdapter->rWifiVar.prP2pFsmInfo)) -+ return TRUE; -+#endif -+ -+ return FALSE; -+} -+ -+#ifdef MTK_DMA_BUF_MEMCPY_SUP -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function gets the physical address for Pre-allocate I/O buffer. -+* -+* \param[in] prGlueInfo Pointer of GLUE Data Structure -+* \param[in] rLockCategory Specify which SPIN_LOCK -+* \param[out] pu4Flags Pointer of a variable for saving IRQ flags -+* -+* \return physical addr -+*/ -+/*----------------------------------------------------------------------------*/ -+ULONG kalIOPhyAddrGet(IN ULONG VirtAddr) -+{ -+ ULONG PhyAddr; -+ -+ if ((VirtAddr >= (ULONG) pvIoBuffer) && (VirtAddr <= ((ULONG) (pvIoBuffer) + pvIoBufferSize))) { -+ PhyAddr = (ULONG) pvIoPhyBuf; -+ PhyAddr += (VirtAddr - (ULONG) (pvIoBuffer)); -+ return PhyAddr; -+ } -+ -+ return 0; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function gets the physical address for Pre-allocate I/O buffer. -+* -+* \param[in] prGlueInfo Pointer of GLUE Data Structure -+* \param[in] rLockCategory Specify which SPIN_LOCK -+* \param[out] pu4Flags Pointer of a variable for saving IRQ flags -+* -+* \return physical addr -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID kalDmaBufGet(OUT VOID **VirtAddr, OUT VOID **PhyAddr) -+{ -+ *VirtAddr = pvDmaBuffer; -+ *PhyAddr = pvDmaPhyBuf; -+} -+#endif /* MTK_DMA_BUF_MEMCPY_SUP */ -+ -+#if CFG_SUPPORT_802_11W -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief to check if the MFP is active or not -+* -+* \param[in] -+* prGlueInfo -+* -+* \return -+* TRUE -+* FALSE -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT_32 kalGetMfpSetting(IN P_GLUE_INFO_T prGlueInfo) -+{ -+ ASSERT(prGlueInfo); -+ -+ return prGlueInfo->rWpaInfo.u4Mfp; -+} -+#endif -+ -+struct file *kalFileOpen(const char *path, int flags, int rights) -+{ -+ struct file *filp = NULL; -+ mm_segment_t oldfs; -+ int err = 0; -+ -+ oldfs = get_fs(); -+ set_fs(get_ds()); -+ filp = filp_open(path, flags, rights); -+ set_fs(oldfs); -+ if (IS_ERR(filp)) { -+ err = PTR_ERR(filp); -+ return NULL; -+ } -+ return filp; -+} -+ -+VOID kalFileClose(struct file *file) -+{ -+ filp_close(file, NULL); -+} -+ -+UINT_32 kalFileRead(struct file *file, UINT_64 offset, UINT_8 *data, UINT_32 size) -+{ -+ mm_segment_t oldfs; -+ INT_32 ret; -+ -+ oldfs = get_fs(); -+ set_fs(get_ds()); -+ -+ ret = vfs_read(file, data, size, &offset); -+ -+ set_fs(oldfs); -+ return ret; -+} -+ -+UINT_32 kalFileWrite(struct file *file, UINT_64 offset, UINT_8 *data, UINT_32 size) -+{ -+ mm_segment_t oldfs; -+ INT_32 ret; -+ -+ oldfs = get_fs(); -+ set_fs(get_ds()); -+ -+ ret = vfs_write(file, data, size, &offset); -+ -+ set_fs(oldfs); -+ return ret; -+} -+ -+UINT_32 kalWriteToFile(const PUINT_8 pucPath, BOOLEAN fgDoAppend, PUINT_8 pucData, UINT_32 u4Size) -+{ -+ struct file *file = NULL; -+ UINT_32 ret = -1; -+ UINT_32 u4Flags = 0; -+ -+ if (fgDoAppend) -+ u4Flags = O_APPEND; -+ -+ file = kalFileOpen(pucPath, O_WRONLY | O_CREAT | u4Flags, S_IRWXU); -+ if (file) { -+ ret = kalFileWrite(file, 0, pucData, u4Size); -+ kalFileClose(file); -+ } -+ -+ return ret; -+} -+ -+INT_32 kalReadToFile(const PUINT_8 pucPath, PUINT_8 pucData, UINT_32 u4Size, PUINT_32 pu4ReadSize) -+{ -+ struct file *file = NULL; -+ INT_32 ret = -1; -+ UINT_32 u4ReadSize = 0; -+ -+ DBGLOG(INIT, LOUD, "kalReadToFile() path %s\n", pucPath); -+ -+ file = kalFileOpen(pucPath, O_RDONLY, 0); -+ -+ if ((file != NULL) && !IS_ERR(file)) { -+ u4ReadSize = kalFileRead(file, 0, pucData, u4Size); -+ kalFileClose(file); -+ if (pu4ReadSize) -+ *pu4ReadSize = u4ReadSize; -+ ret = 0; -+ } -+ return ret; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief To indicate BSS-INFO to NL80211 as scanning result -+* -+* \param[in] -+* prGlueInfo -+* pucBeaconProbeResp -+* u4FrameLen -+* -+* -+* -+* \return -+* none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+kalIndicateBssInfo(IN P_GLUE_INFO_T prGlueInfo, -+ IN PUINT_8 pucBeaconProbeResp, -+ IN UINT_32 u4FrameLen, IN UINT_8 ucChannelNum, IN INT_32 i4SignalStrength) -+{ -+ struct wiphy *wiphy; -+ struct ieee80211_channel *prChannel = NULL; -+ -+ ASSERT(prGlueInfo); -+ wiphy = priv_to_wiphy(prGlueInfo); -+ -+ /* search through channel entries */ -+ if (ucChannelNum <= 14) { -+ prChannel = -+ ieee80211_get_channel(wiphy, ieee80211_channel_to_frequency(ucChannelNum, NL80211_BAND_2GHZ)); -+ } else { -+ prChannel = -+ ieee80211_get_channel(wiphy, ieee80211_channel_to_frequency(ucChannelNum, NL80211_BAND_5GHZ)); -+ } -+ -+ if (prChannel != NULL && (prGlueInfo->prScanRequest != NULL || prGlueInfo->prSchedScanRequest != NULL)) { -+ struct cfg80211_bss *bss; -+#if CFG_SUPPORT_TSF_USING_BOOTTIME -+ struct ieee80211_mgmt *prMgmtFrame = (struct ieee80211_mgmt *)pucBeaconProbeResp; -+ -+ prMgmtFrame->u.beacon.timestamp = kalGetBootTime(); -+#endif -+ ScanCnt++; -+ -+ /* indicate to NL80211 subsystem */ -+ bss = cfg80211_inform_bss_frame(wiphy, -+ prChannel, -+ (struct ieee80211_mgmt *)pucBeaconProbeResp, -+ u4FrameLen, i4SignalStrength * 100, GFP_KERNEL); -+ -+ if (!bss) { -+ ScanDoneFailCnt++; -+ DBGLOG(SCN, WARN, "inform bss to cfg80211 failed, bss channel %d, rcpi %d\n", -+ ucChannelNum, i4SignalStrength); -+ } else { -+ cfg80211_put_bss(wiphy, bss); -+ DBGLOG(SCN, TRACE, "inform bss to cfg80211, bss channel %d, rcpi %d\n", -+ ucChannelNum, i4SignalStrength); -+ } -+ } -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief To indicate channel ready -+* -+* \param[in] -+* prGlueInfo -+* -+* \return -+* none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+kalReadyOnChannel(IN P_GLUE_INFO_T prGlueInfo, -+ IN UINT_64 u8Cookie, -+ IN ENUM_BAND_T eBand, IN ENUM_CHNL_EXT_T eSco, IN UINT_8 ucChannelNum, IN UINT_32 u4DurationMs) -+{ -+ struct ieee80211_channel *prChannel = NULL; -+ enum nl80211_channel_type rChannelType; -+ -+ /* ucChannelNum = wlanGetChannelNumberByNetwork(prGlueInfo->prAdapter, NETWORK_TYPE_AIS_INDEX); */ -+ -+ if (prGlueInfo->fgIsRegistered == TRUE) { -+ if (ucChannelNum <= 14) { -+ prChannel = -+ ieee80211_get_channel(priv_to_wiphy(prGlueInfo), -+ ieee80211_channel_to_frequency(ucChannelNum, NL80211_BAND_2GHZ)); -+ } else { -+ prChannel = -+ ieee80211_get_channel(priv_to_wiphy(prGlueInfo), -+ ieee80211_channel_to_frequency(ucChannelNum, NL80211_BAND_5GHZ)); -+ } -+ -+ switch (eSco) { -+ case CHNL_EXT_SCN: -+ rChannelType = NL80211_CHAN_NO_HT; -+ break; -+ -+ case CHNL_EXT_SCA: -+ rChannelType = NL80211_CHAN_HT40MINUS; -+ break; -+ -+ case CHNL_EXT_SCB: -+ rChannelType = NL80211_CHAN_HT40PLUS; -+ break; -+ -+ case CHNL_EXT_RES: -+ default: -+ rChannelType = NL80211_CHAN_HT20; -+ break; -+ } -+ -+ cfg80211_ready_on_channel(prGlueInfo->prDevHandler->ieee80211_ptr, u8Cookie, prChannel, u4DurationMs, -+ GFP_KERNEL); -+ } -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief To indicate channel expiration -+* -+* \param[in] -+* prGlueInfo -+* -+* \return -+* none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+kalRemainOnChannelExpired(IN P_GLUE_INFO_T prGlueInfo, -+ IN UINT_64 u8Cookie, IN ENUM_BAND_T eBand, IN ENUM_CHNL_EXT_T eSco, IN UINT_8 ucChannelNum) -+{ -+ struct ieee80211_channel *prChannel = NULL; -+ enum nl80211_channel_type rChannelType; -+ -+ ucChannelNum = wlanGetChannelNumberByNetwork(prGlueInfo->prAdapter, NETWORK_TYPE_AIS_INDEX); -+ -+ if (prGlueInfo->fgIsRegistered == TRUE) { -+ if (ucChannelNum <= 14) { -+ prChannel = -+ ieee80211_get_channel(priv_to_wiphy(prGlueInfo), -+ ieee80211_channel_to_frequency(ucChannelNum, NL80211_BAND_2GHZ)); -+ } else { -+ prChannel = -+ ieee80211_get_channel(priv_to_wiphy(prGlueInfo), -+ ieee80211_channel_to_frequency(ucChannelNum, NL80211_BAND_5GHZ)); -+ } -+ -+ switch (eSco) { -+ case CHNL_EXT_SCN: -+ rChannelType = NL80211_CHAN_NO_HT; -+ break; -+ -+ case CHNL_EXT_SCA: -+ rChannelType = NL80211_CHAN_HT40MINUS; -+ break; -+ -+ case CHNL_EXT_SCB: -+ rChannelType = NL80211_CHAN_HT40PLUS; -+ break; -+ -+ case CHNL_EXT_RES: -+ default: -+ rChannelType = NL80211_CHAN_HT20; -+ break; -+ } -+ -+ cfg80211_remain_on_channel_expired(prGlueInfo->prDevHandler->ieee80211_ptr, u8Cookie, prChannel, -+ GFP_KERNEL); -+ } -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief To indicate Mgmt tx status -+* -+* \param[in] -+* prGlueInfo -+* -+* \return -+* none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+kalIndicateMgmtTxStatus(IN P_GLUE_INFO_T prGlueInfo, -+ IN UINT_64 u8Cookie, IN BOOLEAN fgIsAck, IN PUINT_8 pucFrameBuf, IN UINT_32 u4FrameLen) -+{ -+ -+ do { -+ if ((prGlueInfo == NULL) || (pucFrameBuf == NULL) || (u4FrameLen == 0)) { -+ DBGLOG(AIS, TRACE, "Unexpected pointer PARAM. %p, %p, %u.", -+ prGlueInfo, pucFrameBuf, u4FrameLen); -+ ASSERT(FALSE); -+ break; -+ } -+ -+ cfg80211_mgmt_tx_status(prGlueInfo->prDevHandler->ieee80211_ptr, -+ u8Cookie, pucFrameBuf, u4FrameLen, fgIsAck, GFP_KERNEL); -+ } while (FALSE); -+ -+} /* kalIndicateMgmtTxStatus */ -+ -+VOID kalIndicateRxMgmtFrame(IN P_GLUE_INFO_T prGlueInfo, IN P_SW_RFB_T prSwRfb) -+{ -+#define DBG_MGMT_FRAME_INDICATION 1 -+ INT_32 i4Freq = 0; -+ UINT_8 ucChnlNum = 0; -+#if DBG_MGMT_FRAME_INDICATION -+ P_WLAN_MAC_HEADER_T prWlanHeader = (P_WLAN_MAC_HEADER_T) NULL; -+#endif -+ -+ do { -+ if ((prGlueInfo == NULL) || (prSwRfb == NULL)) { -+ ASSERT(FALSE); -+ break; -+ } -+ -+ ucChnlNum = prSwRfb->prHifRxHdr->ucHwChannelNum; -+ -+#if DBG_MGMT_FRAME_INDICATION -+ prWlanHeader = (P_WLAN_MAC_HEADER_T) prSwRfb->pvHeader; -+ -+ switch (prWlanHeader->u2FrameCtrl) { -+ case MAC_FRAME_PROBE_REQ: -+ DBGLOG(AIS, TRACE, "RX Probe Req at channel %d ", ucChnlNum); -+ break; -+ case MAC_FRAME_PROBE_RSP: -+ DBGLOG(AIS, TRACE, "RX Probe Rsp at channel %d ", ucChnlNum); -+ break; -+ case MAC_FRAME_ACTION: -+ DBGLOG(AIS, TRACE, "RX Action frame at channel %d ", ucChnlNum); -+ break; -+ default: -+ DBGLOG(AIS, TRACE, "RX Packet:%d at channel %d ", prWlanHeader->u2FrameCtrl, ucChnlNum); -+ break; -+ } -+ -+#endif -+ i4Freq = nicChannelNum2Freq(ucChnlNum) / 1000; -+ -+ cfg80211_rx_mgmt(prGlueInfo->prDevHandler->ieee80211_ptr, /* struct net_device * dev, */ -+ i4Freq, -+ RCPI_TO_dBm(prSwRfb->prHifRxHdr->ucRcpi), -+ prSwRfb->pvHeader, prSwRfb->u2PacketLen, GFP_KERNEL); -+ } while (FALSE); -+ -+} /* kalIndicateRxMgmtFrame */ -+ -+#if CFG_SUPPORT_AGPS_ASSIST -+BOOLEAN kalIndicateAgpsNotify(P_ADAPTER_T prAdapter, UINT_8 cmd, PUINT_8 data, UINT_16 dataLen) -+{ -+ P_GLUE_INFO_T prGlueInfo = prAdapter->prGlueInfo; -+ -+ struct sk_buff *skb = cfg80211_testmode_alloc_event_skb(priv_to_wiphy(prGlueInfo), -+ dataLen, GFP_KERNEL); -+ if (!skb) { -+ DBGLOG(AIS, ERROR, "kalIndicateAgpsNotify: alloc skb failed\n"); -+ return FALSE; -+ } -+ -+ /* DBGLOG(CCX, INFO, ("WLAN_STATUS_AGPS_NOTIFY, cmd=%d\n", cmd)); */ -+ if (unlikely(nla_put(skb, MTK_ATTR_AGPS_CMD, sizeof(cmd), &cmd) < 0)) -+ goto nla_put_failure; -+ if (dataLen > 0 && data && unlikely(nla_put(skb, MTK_ATTR_AGPS_DATA, dataLen, data) < 0)) -+ goto nla_put_failure; -+ if (unlikely(nla_put(skb, MTK_ATTR_AGPS_IFINDEX, sizeof(UINT_32), &prGlueInfo->prDevHandler->ifindex) < 0)) -+ goto nla_put_failure; -+ /* currently, the ifname maybe wlan0, p2p0, so the maximum name length will be 5 bytes */ -+ if (unlikely(nla_put(skb, MTK_ATTR_AGPS_IFNAME, 5, prGlueInfo->prDevHandler->name) < 0)) -+ goto nla_put_failure; -+ cfg80211_testmode_event(skb, GFP_KERNEL); -+ return TRUE; -+ -+nla_put_failure: -+ kfree_skb(skb); -+ return FALSE; -+} -+#endif -+ -+#if (CFG_SUPPORT_MET_PROFILING == 1) -+#define PROC_MET_PROF_CTRL "met_ctrl" -+#define PROC_MET_PROF_PORT "met_port" -+ -+struct proc_dir_entry *pMetProcDir; -+void *pMetGlobalData = NULL; -+static unsigned long __read_mostly tracing_mark_write_addr; -+ -+static inline void __mt_update_tracing_mark_write_addr(void) -+{ -+ if (unlikely(0 == tracing_mark_write_addr)) -+ tracing_mark_write_addr = kallsyms_lookup_name("tracing_mark_write"); -+} -+ -+VOID kalMetProfilingStart(IN P_GLUE_INFO_T prGlueInfo, IN struct sk_buff *prSkb) -+{ -+ UINT_8 ucIpVersion; -+ UINT_16 u2UdpSrcPort; -+ UINT_16 u2RtpSn; -+ PUINT_8 pucEthHdr = prSkb->data; -+ PUINT_8 pucIpHdr, pucUdpHdr, pucRtpHdr; -+ -+ /* | Ethernet(14) | IP(20) | UDP(8)| RTP(12) | */ -+ /* UDP==> |SRC_PORT(2)|DST_PORT(2)|LEN(2)|CHKSUM(2)| */ -+ /* RTP==> |CTRL(2)|SEQ(2)|TimeStamp(4)|... */ -+ /* printk("MET_PROF: MET enable=%d(HardXmit)\n", prGlueInfo->u8MetProfEnable); */ -+ if (prGlueInfo->u8MetProfEnable == 1) { -+ u2UdpSrcPort = prGlueInfo->u16MetUdpPort; -+ if ((*(pucEthHdr + 12) == 0x08) && (*(pucEthHdr + 13) == 0x00)) { -+ /* IP */ -+ pucIpHdr = pucEthHdr + ETH_HLEN; -+ ucIpVersion = (*pucIpHdr & IPVH_VERSION_MASK) >> IPVH_VERSION_OFFSET; -+ if ((ucIpVersion == IPVERSION) && (pucIpHdr[IPV4_HDR_IP_PROTOCOL_OFFSET] == IP_PROTOCOL_UDP)) { -+ /* UDP */ -+ pucUdpHdr = pucIpHdr + IP_HEADER_LEN; -+ /* check UDP port number */ -+ if (((UINT_16) pucUdpHdr[0] << 8 | (UINT_16) pucUdpHdr[1]) == u2UdpSrcPort) { -+ /* RTP */ -+ pucRtpHdr = pucUdpHdr + 8; -+ u2RtpSn = (UINT_16) pucRtpHdr[2] << 8 | pucRtpHdr[3]; -+ /* trace_printk("S|%d|%s|%d\n", current->tgid, "WIFI-CHIP", u2RtpSn); -+ //frm_sequence); */ -+#ifdef CONFIG_TRACING -+ __mt_update_tracing_mark_write_addr(); -+ if (tracing_mark_write_addr != 0) { -+ event_trace_printk(tracing_mark_write_addr, "S|%d|%s|%d\n", -+ current->tgid, "WIFI-CHIP", u2RtpSn); -+ } -+#endif -+ } -+ } -+ } -+ } -+} -+ -+VOID kalMetProfilingFinish(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo) -+{ -+ UINT_8 ucIpVersion; -+ UINT_16 u2UdpSrcPort; -+ UINT_16 u2RtpSn; -+ struct sk_buff *prSkb = (struct sk_buff *)prMsduInfo->prPacket; -+ PUINT_8 pucEthHdr = prSkb->data; -+ PUINT_8 pucIpHdr, pucUdpHdr, pucRtpHdr; -+ P_GLUE_INFO_T prGlueInfo = prAdapter->prGlueInfo; -+ -+ /* | Ethernet(14) | IP(20) | UDP(8)| RTP(12) | */ -+ /* UDP==> |SRC_PORT(2)|DST_PORT(2)|LEN(2)|CHKSUM(2)| */ -+ /* RTP==> |CTRL(2)|SEQ(2)|TimeStamp(4)|... */ -+ /* printk("MET_PROF: MET enable=%d(TxMsdu)\n", prGlueInfo->u8MetProfEnable); */ -+ if (prGlueInfo->u8MetProfEnable == 1) { -+ u2UdpSrcPort = prGlueInfo->u16MetUdpPort; -+ if ((*(pucEthHdr + 12) == 0x08) && (*(pucEthHdr + 13) == 0x00)) { -+ /* IP */ -+ pucIpHdr = pucEthHdr + ETH_HLEN; -+ ucIpVersion = (*pucIpHdr & IPVH_VERSION_MASK) >> IPVH_VERSION_OFFSET; -+ if ((ucIpVersion == IPVERSION) && (pucIpHdr[IPV4_HDR_IP_PROTOCOL_OFFSET] == IP_PROTOCOL_UDP)) { -+ /* UDP */ -+ pucUdpHdr = pucIpHdr + IP_HEADER_LEN; -+ /* check UDP port number */ -+ if (((UINT_16) pucUdpHdr[0] << 8 | (UINT_16) pucUdpHdr[1]) == u2UdpSrcPort) { -+ /* RTP */ -+ pucRtpHdr = pucUdpHdr + 8; -+ u2RtpSn = (UINT_16) pucRtpHdr[2] << 8 | pucRtpHdr[3]; -+ /* trace_printk("F|%d|%s|%d\n", current->tgid, "WIFI-CHIP", u2RtpSn); -+ //frm_sequence); */ -+#ifdef CONFIG_TRACING -+ __mt_update_tracing_mark_write_addr(); -+ if (tracing_mark_write_addr != 0) { -+ event_trace_printk(tracing_mark_write_addr, "F|%d|%s|%d\n", -+ current->tgid, "WIFI-CHIP", u2RtpSn); -+ } -+#endif -+ } -+ } -+ } -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief The PROC function for adjusting Debug Level to turn on/off debugging message. -+* -+* \param[in] file pointer to file. -+* \param[in] buffer Buffer from user space. -+* \param[in] count Number of characters to write -+* \param[in] data Pointer to the private data structure. -+* -+* \return number of characters write from User Space. -+*/ -+/*----------------------------------------------------------------------------*/ -+static ssize_t kalMetCtrlWriteProcfs(struct file *file, const char __user *buffer, size_t count, loff_t *off) -+{ -+ char acBuf[128 + 1]; /* + 1 for "\0" */ -+ UINT_32 u4CopySize; -+ int u8MetProfEnable; -+ -+ IN P_GLUE_INFO_T prGlueInfo; -+ -+ u4CopySize = (count < (sizeof(acBuf) - 1)) ? count : (sizeof(acBuf) - 1); -+ if (copy_from_user(acBuf, buffer, u4CopySize)) -+ return -1; -+ acBuf[u4CopySize] = '\0'; -+ -+ if (sscanf(acBuf, " %d", &u8MetProfEnable) == 1) -+ DBGLOG(INIT, INFO, "MET_PROF: Write MET PROC Enable=%d\n", u8MetProfEnable); -+ if (pMetGlobalData != NULL) { -+ prGlueInfo = (P_GLUE_INFO_T) pMetGlobalData; -+ prGlueInfo->u8MetProfEnable = (UINT_8) u8MetProfEnable; -+ } -+ return count; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief The PROC function for adjusting Debug Level to turn on/off debugging message. -+* -+* \param[in] file pointer to file. -+* \param[in] buffer Buffer from user space. -+* \param[in] count Number of characters to write -+* \param[in] data Pointer to the private data structure. -+* -+* \return number of characters write from User Space. -+*/ -+/*----------------------------------------------------------------------------*/ -+static ssize_t kalMetPortWriteProcfs(struct file *file, const char __user *buffer, size_t count, loff_t *off) -+{ -+ char acBuf[128 + 1]; /* + 1 for "\0" */ -+ UINT_32 u4CopySize; -+ int u16MetUdpPort; -+ -+ IN P_GLUE_INFO_T prGlueInfo; -+ -+ u4CopySize = (count < (sizeof(acBuf) - 1)) ? count : (sizeof(acBuf) - 1); -+ if (copy_from_user(acBuf, buffer, u4CopySize)) -+ return -1; -+ acBuf[u4CopySize] = '\0'; -+ -+ if (sscanf(acBuf, " %d", &u16MetUdpPort) == 1) -+ DBGLOG(INIT, INFO, "MET_PROF: Write MET PROC UDP_PORT=%d\n", u16MetUdpPort); -+ if (pMetGlobalData != NULL) { -+ prGlueInfo = (P_GLUE_INFO_T) pMetGlobalData; -+ prGlueInfo->u16MetUdpPort = (UINT_16) u16MetUdpPort; -+ } -+ return count; -+} -+ -+const struct file_operations rMetProcCtrlFops = { -+.write = kalMetCtrlWriteProcfs -+}; -+ -+const struct file_operations rMetProcPortFops = { -+.write = kalMetPortWriteProcfs -+}; -+ -+int kalMetInitProcfs(IN P_GLUE_INFO_T prGlueInfo) -+{ -+ /* struct proc_dir_entry *pMetProcDir; */ -+ if (init_net.proc_net == (struct proc_dir_entry *)NULL) { -+ DBGLOG(INIT, INFO, "init proc fs fail: proc_net == NULL\n"); -+ return -ENOENT; -+ } -+ /* -+ * Directory: Root (/proc/net/wlan0) -+ */ -+ pMetProcDir = proc_mkdir("wlan0", init_net.proc_net); -+ if (pMetProcDir == NULL) -+ return -ENOENT; -+ /* -+ /proc/net/wlan0 -+ |-- met_ctrl (PROC_MET_PROF_CTRL) -+ |-- met_port (PROC_MET_PROF_PORT) -+ */ -+ /* proc_create(PROC_MET_PROF_CTRL, 0x0644, pMetProcDir, &rMetProcFops); */ -+ proc_create(PROC_MET_PROF_CTRL, 0, pMetProcDir, &rMetProcCtrlFops); -+ proc_create(PROC_MET_PROF_PORT, 0, pMetProcDir, &rMetProcPortFops); -+ -+ pMetGlobalData = (void *)prGlueInfo; -+ -+ return 0; -+} -+ -+int kalMetRemoveProcfs(void) -+{ -+ -+ if (init_net.proc_net == (struct proc_dir_entry *)NULL) { -+ DBGLOG(INIT, WARN, "remove proc fs fail: proc_net == NULL\n"); -+ return -ENOENT; -+ } -+ remove_proc_entry(PROC_MET_PROF_CTRL, pMetProcDir); -+ remove_proc_entry(PROC_MET_PROF_PORT, pMetProcDir); -+ /* remove root directory (proc/net/wlan0) */ -+ remove_proc_entry("wlan0", init_net.proc_net); -+ /* clear MetGlobalData */ -+ pMetGlobalData = NULL; -+ -+ return 0; -+} -+#endif -+UINT_64 kalGetBootTime(void) -+{ -+ struct timespec ts; -+ UINT_64 bootTime = 0; -+ -+ get_monotonic_boottime(&ts); -+ /* we assign ts.tv_sec to bootTime first, then multiply USEC_PER_SEC -+ this will prevent multiply result turn to a negative value on 32bit system */ -+ bootTime = ts.tv_sec; -+ bootTime *= USEC_PER_SEC; -+ bootTime += ts.tv_nsec / NSEC_PER_USEC; -+ return bootTime; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief To indicate scheduled scan results are avilable -+* -+* \param[in] -+* prGlueInfo -+* -+* \return -+* None -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID kalSchedScanResults(IN P_GLUE_INFO_T prGlueInfo) -+{ -+ ASSERT(prGlueInfo); -+ -+ cfg80211_sched_scan_results(priv_to_wiphy(prGlueInfo),0); -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief To indicate scheduled scan has been stopped -+* -+* \param[in] -+* prGlueInfo -+* -+* \return -+* None -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID kalSchedScanStopped(IN P_GLUE_INFO_T prGlueInfo) -+{ -+ GLUE_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(prGlueInfo); -+ -+ /* 1. reset first for newly incoming request */ -+ GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV); -+ if (prGlueInfo->prSchedScanRequest != NULL) -+ prGlueInfo->prSchedScanRequest = NULL; -+ GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV); -+ DBGLOG(SCN, INFO, "cfg80211_sched_scan_stopped send event\n"); -+ -+ /* 2. indication to cfg80211 */ -+ /* 20150205 change cfg80211_sched_scan_stopped to work queue to use K thread to send event instead of Tx thread -+ due to sched_scan_mtx dead lock issue by Tx thread serves oid cmds and send event in the same time */ -+ DBGLOG(SCN, TRACE, "start work queue to send event\n"); -+ schedule_delayed_work(&sched_workq, 0); -+ DBGLOG(SCN, TRACE, "tx_thread return from kalSchedScanStoppped\n"); -+ -+} -+ -+#if CFG_SUPPORT_WAKEUP_REASON_DEBUG -+/* if SPM is not implement this function, we will use this default one */ -+wake_reason_t __weak slp_get_wake_reason(VOID) -+{ -+ return WR_NONE; -+} -+/* if SPM is not implement this function, we will use this default one */ -+UINT_32 __weak spm_get_last_wakeup_src(VOID) -+{ -+ return 0; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief To check if device if wake up by wlan -+* -+* \param[in] -+* prAdapter -+* -+* \return -+* TRUE: wake up by wlan; otherwise, FALSE -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN kalIsWakeupByWlan(P_ADAPTER_T prAdapter) -+{ -+ /* SUSPEND_FLAG_FOR_WAKEUP_REASON is set means system has suspended, but may be failed -+ duo to some driver suspend failed. so we need help of function slp_get_wake_reason */ -+ if (test_and_clear_bit(SUSPEND_FLAG_FOR_WAKEUP_REASON, &prAdapter->ulSuspendFlag) == 0) -+ return FALSE; -+ /* if slp_get_wake_reason or spm_get_last_wakeup_src is NULL, it means SPM module didn't implement -+ it. then we should return FALSE always. otherwise, if slp_get_wake_reason returns WR_WAKE_SRC, -+ then it means the host is suspend successfully. */ -+ if (slp_get_wake_reason() != WR_WAKE_SRC) -+ return FALSE; -+ /* spm_get_last_wakeup_src will returns the last wakeup source, -+ WAKE_SRC_CONN2AP is connsys */ -+ return !!(spm_get_last_wakeup_src() & WAKE_SRC_CONN2AP); -+} -+#endif -+ -+INT_32 kalHaltLock(UINT_32 waitMs) -+{ -+ INT_32 i4Ret = 0; -+ -+ if (waitMs) { -+ i4Ret = down_timeout(&rHaltCtrl.lock, MSEC_TO_JIFFIES(waitMs)); -+ if (!i4Ret) -+ goto success; -+ if (i4Ret != -ETIME) -+ return i4Ret; -+ if (rHaltCtrl.fgHeldByKalIoctl) { -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ -+ wlanExportGlueInfo(&prGlueInfo); -+ -+ DBGLOG(INIT, ERROR, -+ "kalIoctl was executed longer than %u ms, show backtrace of tx_thread!\n", -+ kalGetTimeTick() - rHaltCtrl.u4HoldStart); -+ if (prGlueInfo) -+ show_stack(prGlueInfo->main_thread, NULL); -+ } else { -+ DBGLOG(INIT, ERROR, "halt lock held by %s pid %d longer than %u ms!\n", -+ rHaltCtrl.owner->comm, rHaltCtrl.owner->pid, -+ kalGetTimeTick() - rHaltCtrl.u4HoldStart); -+ show_stack(rHaltCtrl.owner, NULL); -+ } -+ return i4Ret; -+ } -+ down(&rHaltCtrl.lock); -+success: -+ rHaltCtrl.owner = current; -+ rHaltCtrl.u4HoldStart = kalGetTimeTick(); -+ return 0; -+} -+ -+INT_32 kalHaltTryLock(VOID) -+{ -+ INT_32 i4Ret = 0; -+ -+ i4Ret = down_trylock(&rHaltCtrl.lock); -+ if (i4Ret) -+ return i4Ret; -+ rHaltCtrl.owner = current; -+ rHaltCtrl.u4HoldStart = kalGetTimeTick(); -+ return 0; -+} -+ -+VOID kalHaltUnlock(VOID) -+{ -+ if (kalGetTimeTick() - rHaltCtrl.u4HoldStart > WLAN_OID_TIMEOUT_THRESHOLD * 2 && -+ rHaltCtrl.owner) -+ DBGLOG(INIT, ERROR, "process %s pid %d hold halt lock longer than 4s!\n", -+ rHaltCtrl.owner->comm, rHaltCtrl.owner->pid); -+ rHaltCtrl.owner = NULL; -+ up(&rHaltCtrl.lock); -+} -+ -+VOID kalSetHalted(BOOLEAN fgHalt) -+{ -+ rHaltCtrl.fgHalt = fgHalt; -+} -+ -+BOOLEAN kalIsHalted(VOID) -+{ -+ return rHaltCtrl.fgHalt; -+} -+VOID kalPerMonDump(IN P_GLUE_INFO_T prGlueInfo) -+{ -+ struct GL_PER_MON_T *prPerMonitor; -+ -+ prPerMonitor = &prGlueInfo->prAdapter->rPerMonitor; -+ DBGLOG(SW4, WARN, "ulPerfMonFlag:0x%lx\n", prPerMonitor->ulPerfMonFlag); -+ DBGLOG(SW4, WARN, "ulLastTxBytes:%ld\n", prPerMonitor->ulLastTxBytes); -+ DBGLOG(SW4, WARN, "ulLastRxBytes:%ld\n", prPerMonitor->ulLastRxBytes); -+ DBGLOG(SW4, WARN, "ulP2PLastTxBytes:%ld\n", prPerMonitor->ulP2PLastTxBytes); -+ DBGLOG(SW4, WARN, "ulP2PLastRxBytes:%ld\n", prPerMonitor->ulP2PLastRxBytes); -+ DBGLOG(SW4, WARN, "ulThroughput:%ld\n", prPerMonitor->ulThroughput); -+ DBGLOG(SW4, WARN, "u4UpdatePeriod:%d\n", prPerMonitor->u4UpdatePeriod); -+ DBGLOG(SW4, WARN, "u4TarPerfLevel:%d\n", prPerMonitor->u4TarPerfLevel); -+ DBGLOG(SW4, WARN, "u4CurrPerfLevel:%d\n", prPerMonitor->u4CurrPerfLevel); -+ DBGLOG(SW4, WARN, "netStats tx_bytes:%ld\n", prGlueInfo->rNetDevStats.tx_bytes); -+ DBGLOG(SW4, WARN, "netStats tx_bytes:%ld\n", prGlueInfo->rNetDevStats.rx_bytes); -+ DBGLOG(SW4, WARN, "p2p netStats tx_bytes:%ld\n", prGlueInfo->prP2PInfo->rNetDevStats.tx_bytes); -+ DBGLOG(SW4, WARN, "p2p netStats tx_bytes:%ld\n", prGlueInfo->prP2PInfo->rNetDevStats.rx_bytes); -+} -+ -+inline INT32 kalPerMonInit(IN P_GLUE_INFO_T prGlueInfo) -+{ -+ struct GL_PER_MON_T *prPerMonitor; -+ -+ prPerMonitor = &prGlueInfo->prAdapter->rPerMonitor; -+ DBGLOG(SW4, INFO, "enter %s\n", __func__); -+ if (KAL_TEST_BIT(PERF_MON_RUNNING_BIT_OFF, prPerMonitor->ulPerfMonFlag)) -+ DBGLOG(SW4, WARN, "abnormal, perf monitory already running\n"); -+ KAL_CLR_BIT(PERF_MON_RUNNING_BIT_OFF, prPerMonitor->ulPerfMonFlag); -+ KAL_CLR_BIT(PERF_MON_DISABLE_BIT_OFF, prPerMonitor->ulPerfMonFlag); -+ KAL_SET_BIT(PERF_MON_STOP_BIT_OFF, prPerMonitor->ulPerfMonFlag); -+ prPerMonitor->u4UpdatePeriod = 1000; -+ cnmTimerInitTimer(prGlueInfo->prAdapter, -+ &prPerMonitor->rPerfMonTimer, -+ (PFN_MGMT_TIMEOUT_FUNC) kalPerMonHandler, (ULONG) NULL); -+ DBGLOG(SW4, INFO, "exit %s\n", __func__); -+ return 0; -+} -+ -+inline INT32 kalPerMonDisable(IN P_GLUE_INFO_T prGlueInfo) -+{ -+ struct GL_PER_MON_T *prPerMonitor; -+ -+ prPerMonitor = &prGlueInfo->prAdapter->rPerMonitor; -+ -+ DBGLOG(SW4, INFO, "enter %s\n", __func__); -+ if (KAL_TEST_BIT(PERF_MON_RUNNING_BIT_OFF, prPerMonitor->ulPerfMonFlag)) { -+ DBGLOG(SW4, TRACE, "need to stop before disable\n"); -+ kalPerMonStop(prGlueInfo); -+ } -+ KAL_SET_BIT(PERF_MON_DISABLE_BIT_OFF, prPerMonitor->ulPerfMonFlag); -+ DBGLOG(SW4, TRACE, "exit %s\n", __func__); -+ return 0; -+} -+ -+inline INT32 kalPerMonEnable(IN P_GLUE_INFO_T prGlueInfo) -+{ -+ struct GL_PER_MON_T *prPerMonitor; -+ -+ prPerMonitor = &prGlueInfo->prAdapter->rPerMonitor; -+ -+ DBGLOG(SW4, INFO, "enter %s\n", __func__); -+ KAL_CLR_BIT(PERF_MON_DISABLE_BIT_OFF, prPerMonitor->ulPerfMonFlag); -+ DBGLOG(SW4, TRACE, "exit %s\n", __func__); -+ return 0; -+} -+ -+inline INT32 kalPerMonStart(IN P_GLUE_INFO_T prGlueInfo) -+{ -+ struct GL_PER_MON_T *prPerMonitor; -+ -+ prPerMonitor = &prGlueInfo->prAdapter->rPerMonitor; -+ DBGLOG(SW4, TRACE, "enter %s\n", __func__); -+ if (KAL_TEST_BIT(PERF_MON_DISABLE_BIT_OFF, prPerMonitor->ulPerfMonFlag)) -+ return 0; -+ if (KAL_TEST_BIT(PERF_MON_RUNNING_BIT_OFF, prPerMonitor->ulPerfMonFlag)) { -+ DBGLOG(SW4, TRACE, "perf monitor already running\n"); -+ return 0; -+ } -+ cnmTimerStartTimer(prGlueInfo->prAdapter, &prPerMonitor->rPerfMonTimer, prPerMonitor->u4UpdatePeriod); -+ KAL_SET_BIT(PERF_MON_RUNNING_BIT_OFF, prPerMonitor->ulPerfMonFlag); -+ KAL_CLR_BIT(PERF_MON_STOP_BIT_OFF, prPerMonitor->ulPerfMonFlag); -+ DBGLOG(SW4, INFO, "perf monitor started\n"); -+ return 0; -+} -+ -+inline INT32 kalPerMonStop(IN P_GLUE_INFO_T prGlueInfo) -+{ -+ struct GL_PER_MON_T *prPerMonitor; -+ -+ prPerMonitor = &prGlueInfo->prAdapter->rPerMonitor; -+ DBGLOG(SW4, TRACE, "enter %s\n", __func__); -+ -+ if (KAL_TEST_BIT(PERF_MON_DISABLE_BIT_OFF, prPerMonitor->ulPerfMonFlag)) { -+ DBGLOG(SW4, TRACE, "perf monitory disabled\n"); -+ return 0; -+ } -+ -+ if (KAL_TEST_BIT(PERF_MON_STOP_BIT_OFF, prPerMonitor->ulPerfMonFlag)) { -+ DBGLOG(SW4, TRACE, "perf monitory already stopped\n"); -+ return 0; -+ } -+ -+ KAL_SET_BIT(PERF_MON_STOP_BIT_OFF, prPerMonitor->ulPerfMonFlag); -+ if (KAL_TEST_BIT(PERF_MON_RUNNING_BIT_OFF, prPerMonitor->ulPerfMonFlag)) { -+ cnmTimerStopTimer(prGlueInfo->prAdapter, &prPerMonitor->rPerfMonTimer); -+ KAL_CLR_BIT(PERF_MON_RUNNING_BIT_OFF, prPerMonitor->ulPerfMonFlag); -+ prPerMonitor->ulLastRxBytes = 0; -+ prPerMonitor->ulLastTxBytes = 0; -+ prPerMonitor->ulP2PLastRxBytes = 0; -+ prPerMonitor->ulP2PLastTxBytes = 0; -+ prPerMonitor->ulThroughput = 0; -+ prPerMonitor->u4CurrPerfLevel = 0; -+ prPerMonitor->u4TarPerfLevel = 0; -+ /*Cancel CPU performance mode request*/ -+ kalBoostCpu(0); -+ } -+ DBGLOG(SW4, TRACE, "exit %s\n", __func__); -+ return 0; -+} -+ -+inline INT32 kalPerMonDestroy(IN P_GLUE_INFO_T prGlueInfo) -+{ -+ kalPerMonDisable(prGlueInfo); -+ return 0; -+} -+ -+VOID kalPerMonHandler(IN P_ADAPTER_T prAdapter, ULONG ulParam) -+{ -+ /*Calculate current throughput*/ -+ struct GL_PER_MON_T *prPerMonitor; -+ -+ LONG latestTxBytes, latestRxBytes, txDiffBytes, rxDiffBytes; -+ LONG p2pLatestTxBytes, p2pLatestRxBytes, p2pTxDiffBytes, p2pRxDiffBytes; -+ P_GLUE_INFO_T prGlueInfo = prAdapter->prGlueInfo; -+ -+ if ((prGlueInfo->ulFlag & GLUE_FLAG_HALT) || (!prAdapter->fgIsP2PRegistered)) -+ return; -+ -+ prPerMonitor = &prAdapter->rPerMonitor; -+ DBGLOG(SW4, TRACE, "enter kalPerMonHandler\n"); -+ if (KAL_TEST_BIT(PERF_MON_DISABLE_BIT_OFF, prPerMonitor->ulPerfMonFlag)) { -+ KAL_CLR_BIT(PERF_MON_RUNNING_BIT_OFF, prPerMonitor->ulPerfMonFlag); -+ DBGLOG(SW4, WARN, "perf monitory disabled, omit timeout event\n"); -+ return; -+ } -+ -+ if (KAL_TEST_BIT(PERF_MON_STOP_BIT_OFF, prPerMonitor->ulPerfMonFlag)) { -+ KAL_CLR_BIT(PERF_MON_RUNNING_BIT_OFF, prPerMonitor->ulPerfMonFlag); -+ DBGLOG(SW4, WARN, "perf monitory stopped, omit timeout event\n"); -+ return; -+ } -+ latestTxBytes = prGlueInfo->rNetDevStats.tx_bytes; -+ latestRxBytes = prGlueInfo->rNetDevStats.rx_bytes; -+ p2pLatestTxBytes = prGlueInfo->prP2PInfo->rNetDevStats.tx_bytes; -+ p2pLatestRxBytes = prGlueInfo->prP2PInfo->rNetDevStats.rx_bytes; -+ if (0 == prPerMonitor->ulLastRxBytes && -+ 0 == prPerMonitor->ulLastTxBytes && -+ 0 == prPerMonitor->ulP2PLastRxBytes && -+ 0 == prPerMonitor->ulP2PLastTxBytes) { -+ prPerMonitor->ulThroughput = 0; -+ } else { -+ txDiffBytes = latestTxBytes - prPerMonitor->ulLastTxBytes; -+ rxDiffBytes = latestRxBytes - prPerMonitor->ulLastRxBytes; -+ if (0 > txDiffBytes) -+ txDiffBytes = -(txDiffBytes); -+ if (0 > rxDiffBytes) -+ rxDiffBytes = -(rxDiffBytes); -+ -+ p2pTxDiffBytes = p2pLatestTxBytes - prPerMonitor->ulP2PLastTxBytes; -+ p2pRxDiffBytes = p2pLatestRxBytes - prPerMonitor->ulP2PLastRxBytes; -+ if (0 > p2pTxDiffBytes) -+ p2pTxDiffBytes = -(p2pTxDiffBytes); -+ if (0 > p2pRxDiffBytes) -+ p2pRxDiffBytes = -(p2pRxDiffBytes); -+ -+ prPerMonitor->ulThroughput = txDiffBytes + rxDiffBytes + p2pTxDiffBytes + p2pRxDiffBytes; -+ prPerMonitor->ulThroughput *= 1000; -+ prPerMonitor->ulThroughput /= prPerMonitor->u4UpdatePeriod; -+ prPerMonitor->ulThroughput <<= 3; -+ } -+ /*start the timer again to make sure we can cancel performance mode request in the end*/ -+ cnmTimerStartTimer(prGlueInfo->prAdapter, &prPerMonitor->rPerfMonTimer, prPerMonitor->u4UpdatePeriod); -+ -+ prPerMonitor->ulLastTxBytes = latestTxBytes; -+ prPerMonitor->ulLastRxBytes = latestRxBytes; -+ prPerMonitor->ulP2PLastTxBytes = p2pLatestTxBytes; -+ prPerMonitor->ulP2PLastRxBytes = p2pLatestRxBytes; -+ -+ if (prPerMonitor->ulThroughput < THROUGHPUT_L1_THRESHOLD) -+ prPerMonitor->u4TarPerfLevel = 0; -+ else if (prPerMonitor->ulThroughput < THROUGHPUT_L2_THRESHOLD) -+ prPerMonitor->u4TarPerfLevel = 1; -+ else if (prPerMonitor->ulThroughput < THROUGHPUT_L3_THRESHOLD) -+ prPerMonitor->u4TarPerfLevel = 2; -+ else -+ prPerMonitor->u4TarPerfLevel = 3; -+ if (prPerMonitor->u4TarPerfLevel != prPerMonitor->u4CurrPerfLevel) { -+ if (0 == prPerMonitor->u4TarPerfLevel) { -+ /*cancel CPU performance mode request*/ -+ kalPerMonStop(prGlueInfo); -+ } else{ -+ DBGLOG(SW4, TRACE, "throughput:%ld bps\n", prPerMonitor->ulThroughput); -+ /*adjust CPU core number to prPerMonitor->u4TarPerfLevel+1*/ -+ kalBoostCpu(prPerMonitor->u4TarPerfLevel+1); -+ /*start the timer again to make sure we can cancel performance mode request in the end*/ -+ cnmTimerStartTimer(prGlueInfo->prAdapter, -+ &prPerMonitor->rPerfMonTimer, -+ prPerMonitor->u4UpdatePeriod); -+ } -+ } -+ prPerMonitor->u4CurrPerfLevel = prPerMonitor->u4TarPerfLevel; -+ DBGLOG(SW4, TRACE, "exit kalPerMonHandler\n"); -+} -+ -+INT32 __weak kalBoostCpu(UINT_32 core_num) -+{ -+ DBGLOG(SW4, WARN, "enter weak kalBoostCpu, core_num:%d\n", core_num); -+ return 0; -+} -+ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_p2p.c b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_p2p.c -new file mode 100644 -index 000000000000..945a6c03978b ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_p2p.c -@@ -0,0 +1,4672 @@ -+/* -+** Id: @(#) gl_p2p.c@@ -+*/ -+ -+/*! \file gl_p2p.c -+ \brief Main routines of Linux driver interface for Wi-Fi Direct -+ -+ This file contains the main routines of Linux driver for MediaTek Inc. 802.11 -+ Wireless LAN Adapters. -+*/ -+ -+/* -+** Log: gl_p2p.c -+** -+** 09 12 2012 wcpadmin -+** [ALPS00276400] Remove MTK copyright and legal header on GPL/LGPL related packages -+** . -+** -+** 08 17 2012 yuche.tsai -+** NULL -+** Fix compile warning. -+** -+** 08 16 2012 yuche.tsai -+** NULL -+** Fix compile warning. -+** -+** 08 14 2012 yuche.tsai -+** NULL -+** FPB from ALPS.JB to phase 2 release. -+** -+** 07 26 2012 yuche.tsai -+** [ALPS00324337] [ALPS.JB][Hot-Spot] Driver update for Hot-Spot -+** Update driver code of ALPS.JB for hot-spot. -+** -+** 07 19 2012 yuche.tsai -+** NULL -+** Code update for JB. -+ * -+ * 07 17 2012 yuche.tsai -+ * NULL -+ * Fix compile error for JB. -+ * -+ * 07 17 2012 yuche.tsai -+ * NULL -+ * Let netdev bring up. -+ * -+ * 07 17 2012 yuche.tsai -+ * NULL -+ * Compile no error before trial run. -+ * -+ * 01 09 2012 terry.wu -+ * [WCXRP00001166] [Wi-Fi] [Driver] cfg80211 integration for p2p newtork -+ * cfg80211 integration for p2p network. -+ * -+ * 12 19 2011 terry.wu -+ * [WCXRP00001142] [Wi-Fi] [P2P Driver] XOR local admin bit to generate p2p net device MAC -+ * XOR local administrated bit to generate net device MAC of p2p network. -+ * -+ * 12 02 2011 yuche.tsai -+ * NULL -+ * Fix possible KE when unload p2p. -+ * -+ * 11 24 2011 yuche.tsai -+ * NULL -+ * Fix P2P IOCTL of multicast address bug, add low power driver stop control. -+ * -+ * 11 22 2011 yuche.tsai -+ * NULL -+ * Update RSSI link quality of P2P Network query method. (Bug fix) -+ * -+ * 11 19 2011 yuche.tsai -+ * NULL -+ * Add RSSI support for P2P network. -+ * -+ * 11 16 2011 yuche.tsai -+ * [WCXRP00001107] [Volunteer Patch][Driver] Large Network Type index assert in FW issue. -+ * Avoid using work thread in set p2p multicast address callback. -+ * -+ * 11 11 2011 yuche.tsai -+ * NULL -+ * Fix work thread cancel issue. -+ * -+ * 11 11 2011 yuche.tsai -+ * NULL -+ * Fix default device name issue. -+ * -+ * 11 08 2011 yuche.tsai -+ * [WCXRP00001094] [Volunteer Patch][Driver] Driver version & supplicant version query & set support for service -+ * discovery version check. -+ * Add support for driver version query & p2p supplicant verseion set. -+ * For new service discovery mechanism sync. -+ * -+ * 11 07 2011 yuche.tsai -+ * NULL -+ * [ALPS 00087243] KE in worker thread. -+ * The multicast address list is scheduled in worker thread. -+ * Before the worker thread is excuted, if P2P is unloaded, a KE may occur. -+ * -+ * 10 26 2011 terry.wu -+ * [WCXRP00001066] [MT6620 Wi-Fi] [P2P Driver] Fix P2P Oid Issue -+ * Fix some P2P OID functions didn't raise its flag "fgIsP2pOid" issue. -+ * -+ * 10 25 2011 cm.chang -+ * [WCXRP00001058] [All Wi-Fi][Driver] Fix sta_rec's phyTypeSet and OBSS scan in AP mode -+ * . -+ * -+ * 10 18 2011 yuche.tsai -+ * [WCXRP00001045] [WiFi Direct][Driver] Check 2.1 branch. -+ * Support Channel Query. -+ * -+ * 10 18 2011 yuche.tsai -+ * [WCXRP00001045] [WiFi Direct][Driver] Check 2.1 branch. -+ * New 2.1 branch -+ -+ * -+ * 08 26 2011 yuche.tsai -+ * NULL -+ * Fix bug of parsing secondary device list type issue. -+ * -+ * 08 24 2011 yuche.tsai -+ * [WCXRP00000919] [Volunteer Patch][WiFi Direct][Driver] Invitation New Feature. -+ * Invitation Abort. -+ * -+ * 08 23 2011 yuche.tsai -+ * NULL -+ * Fix multicast address list issue of P2P. -+ * -+ * 08 22 2011 chinglan.wang -+ * NULL -+ * Fix invitation indication bug.. -+ * -+ * 08 16 2011 cp.wu -+ * [WCXRP00000934] [MT6620 Wi-Fi][Driver][P2P] Wi-Fi hot spot with auto sparse channel residence -+ * auto channel decision for 2.4GHz hot spot mode -+ * -+ * 08 16 2011 chinglan.wang -+ * NULL -+ * Add the group id information in the invitation indication. -+ * -+ * 08 09 2011 yuche.tsai -+ * [WCXRP00000919] [Volunteer Patch][WiFi Direct][Driver] Invitation New Feature. -+ * Invitation Feature add on. -+ * -+ * 08 05 2011 yuche.tsai -+ * [WCXRP00000856] [Volunteer Patch][WiFi Direct][Driver] MT6620 WiFi Direct IOT Issue with BCM solution. -+ * Add Password ID check for quick connection. -+ * Also modify some connection policy. -+ * -+ * 07 18 2011 chinglan.wang -+ * NULL -+ * Add IOC_P2P_GO_WSC_IE (p2p capability). -+ * -+ * 06 14 2011 yuche.tsai -+ * NULL -+ * Add compile flag to disable persistent group support. -+ * -+ * 05 04 2011 chinglan.wang -+ * [WCXRP00000698] [MT6620 Wi-Fi][P2P][Driver] Add p2p invitation command for the p2p driver -+ * . -+ * -+ * 05 02 2011 yuche.tsai -+ * [WCXRP00000693] [Volunteer Patch][MT6620][Driver] Clear Formation Flag after TX lifetime timeout. -+ * Clear formation flag after formation timeout. -+ * -+ * 04 22 2011 george.huang -+ * [WCXRP00000621] [MT6620 Wi-Fi][Driver] Support P2P supplicant to set power mode -+ * . -+ * -+ * 04 21 2011 george.huang -+ * [WCXRP00000621] [MT6620 Wi-Fi][Driver] Support P2P supplicant to set power mode -+ * 1. Revise P2P power mode setting. -+ * 2. Revise fast-PS for concurrent -+ * -+ * 04 19 2011 wh.su -+ * NULL -+ * Adding length check before doing WPA RSN IE parsing for scan results indicate. -+ * -+ * 04 14 2011 yuche.tsai -+ * [WCXRP00000646] [Volunteer Patch][MT6620][FW/Driver] Sigma Test Modification for some test case. -+ * Connection flow refine for Sigma test. -+ * -+ * 04 08 2011 yuche.tsai -+ * [WCXRP00000624] [Volunteer Patch][MT6620][Driver] Add device discoverability support for GO. -+ * Add device discoverability support. -+ * -+ * 04 08 2011 george.huang -+ * [WCXRP00000621] [MT6620 Wi-Fi][Driver] Support P2P supplicant to set power mode -+ * separate settings of P2P and AIS -+ * -+ * 04 07 2011 terry.wu -+ * [WCXRP00000619] [MT6620 Wi-Fi][Driver] fix kernel panic may occur when removing wlan -+ * Fix kernel panic may occur when removing wlan driver. -+ * -+ * 03 31 2011 wh.su -+ * [WCXRP00000614] [MT6620 Wi-Fi][Driver] P2P: Update beacon content while setting WSC IE -+ * Update the wsc ie to beacon content. -+ * -+ * 03 25 2011 wh.su -+ * NULL -+ * add the sample code for set power mode and get power mode. -+ * -+ * 03 25 2011 yuche.tsai -+ * NULL -+ * Improve some error handleing. -+ * -+ * 03 22 2011 george.huang -+ * [WCXRP00000504] [MT6620 Wi-Fi][FW] Support Sigma CAPI for power saving related command -+ * link with supplicant commands -+ * -+ * 03 22 2011 yuche.tsai -+ * [WCXRP00000584] [Volunteer Patch][MT6620][Driver] Add beacon timeout support for WiFi Direct. -+ * Modify formation policy. -+ * -+ * 03 22 2011 yuche.tsai -+ * NULL -+ * Modify formation policy setting. -+ * -+ * 03 18 2011 yuche.tsai -+ * [WCXRP00000574] [Volunteer Patch][MT6620][Driver] Modify P2P FSM Connection Flow -+ * Modify connection flow after Group Formation Complete, or device connect to a GO. -+ * Instead of request channel & connect directly, we use scan to allocate channel bandwidth & connect after RX BCN. -+ * -+ * 03 15 2011 wh.su -+ * [WCXRP00000563] [MT6620 Wi-Fi] [P2P] Set local config method while set password Id ready -+ * set lccal config method method while set password Id ready. -+ * -+ * 03 15 2011 yuche.tsai -+ * [WCXRP00000560] [Volunteer Patch][MT6620][Driver] P2P Connection from UI using KEY/DISPLAY issue -+ * Fix some configure method issue. -+ * -+ * 03 15 2011 jeffrey.chang -+ * [WCXRP00000558] [MT6620 Wi-Fi][MT6620 Wi-Fi][Driver] refine the queue selection algorithm for WMM -+ * refine queue_select function -+ * -+ * 03 13 2011 wh.su -+ * [WCXRP00000530] [MT6620 Wi-Fi] [Driver] skip doing p2pRunEventAAAComplete after send assoc response Tx Done -+ * add code for avoid compiling warning. -+ * -+ * 03 10 2011 yuche.tsai -+ * NULL -+ * Add P2P API. -+ * -+ * 03 10 2011 terry.wu -+ * [WCXRP00000505] [MT6620 Wi-Fi][Driver/FW] WiFi Direct Integration -+ * Remove unnecessary assert and message. -+ * -+ * 03 08 2011 wh.su -+ * [WCXRP00000488] [MT6620 Wi-Fi][Driver] Support the SIGMA set p2p parameter to driver -+ * support the power save related p2p setting. -+ * -+ * 03 07 2011 wh.su -+ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code -+ * rename the define to anti_pviracy. -+ * -+ * 03 05 2011 wh.su -+ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code -+ * add the code to get the check rsponse and indicate to app. -+ * -+ * 03 03 2011 jeffrey.chang -+ * [WCXRP00000512] [MT6620 Wi-Fi][Driver] modify the net device relative functions to support the H/W multiple queue -+ * support concurrent network -+ * -+ * 03 03 2011 jeffrey.chang -+ * [WCXRP00000512] [MT6620 Wi-Fi][Driver] modify the net device relative functions to support the H/W multiple queue -+ * modify P2P's netdevice functions to support multiple H/W queues -+ * -+ * 03 03 2011 cp.wu -+ * [WCXRP00000283] [MT6620 Wi-Fi][Driver][Wi-Fi Direct] Implementation of interface for supporting Wi-Fi Direct Service -+ * Discovery -+ * for get request, the buffer length to be copied is header + payload. -+ * -+ * 03 02 2011 wh.su -+ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code -+ * add code to let the beacon and probe response for Auto GO WSC . -+ * -+ * 03 02 2011 cp.wu -+ * [WCXRP00000283] [MT6620 Wi-Fi][Driver][Wi-Fi Direct] Implementation of interface for supporting Wi-Fi Direct Service -+ * Discovery -+ * add a missed break. -+ * -+ * 03 01 2011 yuche.tsai -+ * [WCXRP00000501] [Volunteer Patch][MT6620][Driver] No common channel issue when doing GO formation -+ * Update channel issue when doing GO formation.. -+ * -+ * 02 25 2011 wh.su -+ * [WCXRP00000488] [MT6620 Wi-Fi][Driver] Support the SIGMA set p2p parameter to driver -+ * add the Operation channel setting. -+ * -+ * 02 23 2011 wh.su -+ * [WCXRP00000488] [MT6620 Wi-Fi][Driver] Support the SIGMA set p2p parameter to driver -+ * fixed the set int ioctl set index and value map to driver issue. -+ * -+ * 02 22 2011 wh.su -+ * [WCXRP00000488] [MT6620 Wi-Fi][Driver] Support the SIGMA set p2p parameter to driver -+ * adding the ioctl set int from supplicant, and can used to set the p2p parameters -+ * -+ * 02 21 2011 terry.wu -+ * [WCXRP00000476] [MT6620 Wi-Fi][Driver] Clean P2P scan list while removing P2P -+ * Clean P2P scan list while removing P2P. -+ * -+ * 02 18 2011 wh.su -+ * [WCXRP00000471] [MT6620 Wi-Fi][Driver] Add P2P Provison discovery append Config Method attribute at WSC IE -+ * fixed the ioctl setting that index not map to spec defined config method. -+ * -+ * 02 17 2011 wh.su -+ * [WCXRP00000471] [MT6620 Wi-Fi][Driver] Add P2P Provison discovery append Config Method attribute at WSC IE -+ * append the WSC IE config method attribute at provision discovery request. -+ * -+ * 02 17 2011 wh.su -+ * [WCXRP00000448] [MT6620 Wi-Fi][Driver] Fixed WSC IE not send out at probe request -+ * modify the structure pointer for set WSC IE. -+ * -+ * 02 16 2011 wh.su -+ * [WCXRP00000448] [MT6620 Wi-Fi][Driver] Fixed WSC IE not send out at probe request -+ * fixed the probe request send out without WSC IE issue (at P2P). -+ * -+ * 02 09 2011 cp.wu -+ * [WCXRP00000283] [MT6620 Wi-Fi][Driver][Wi-Fi Direct] Implementation of interface for supporting Wi-Fi Direct Service -+ * Discovery -+ * fix typo -+ * -+ * 02 09 2011 yuche.tsai -+ * [WCXRP00000431] [Volunteer Patch][MT6620][Driver] Add MLME support for deauthentication under AP(Hot-Spot) mode. -+ * Add Support for MLME deauthentication for Hot-Spot. -+ * -+ * 01 25 2011 terry.wu -+ * [WCXRP00000393] [MT6620 Wi-Fi][Driver] Add new module insert parameter -+ * Add a new module parameter to indicate current runnig mode, P2P or AP. -+ * -+ * 01 12 2011 yuche.tsai -+ * [WCXRP00000352] [Volunteer Patch][MT6620][Driver] P2P Statsion Record Client List Issue -+ * 1. Modify Channel Acquire Time of AP mode from 5s to 1s. -+ * 2. Call cnmP2pIsPermit() before active P2P network. -+ * 3. Add channel selection support for AP mode. -+ * -+ * 01 05 2011 cp.wu -+ * [WCXRP00000283] [MT6620 Wi-Fi][Driver][Wi-Fi Direct] Implementation of interface for supporting Wi-Fi Direct Service -+ * Discovery -+ * ioctl implementations for P2P Service Discovery -+ * -+ * 01 04 2011 cp.wu -+ * [WCXRP00000338] [MT6620 Wi-Fi][Driver] Separate kalMemAlloc into kmalloc and vmalloc implementations to ease -+ * physically continuous memory demands -+ * separate kalMemAlloc() into virtually-continuous and physically-continuous type to ease slab system pressure -+ * -+ * 12 22 2010 cp.wu -+ * [WCXRP00000283] [MT6620 Wi-Fi][Driver][Wi-Fi Direct] Implementation of interface for supporting Wi-Fi Direct Service -+ * Discovery -+ * 1. header file restructure for more clear module isolation -+ * 2. add function interface definition for implementing Service Discovery callbacks -+ * -+ * 12 15 2010 cp.wu -+ * NULL -+ * invoke nicEnableInterrupt() before leaving from wlanAdapterStart() -+ * -+ * 12 08 2010 yuche.tsai -+ * [WCXRP00000245] [MT6620][Driver] Invitation & Provision Discovery Feature Check-in -+ * [WCXRP000000245][MT6620][Driver] Invitation Request Feature Add -+ * -+ * 11 30 2010 yuche.tsai -+ * NULL -+ * Invitation & Provision Discovery Indication. -+ * -+ * 11 17 2010 wh.su -+ * [WCXRP00000164] [MT6620 Wi-Fi][Driver] Support the p2p random SSID[WCXRP00000179] [MT6620 Wi-Fi][FW] Set the Tx -+ * lowest rate at wlan table for normal operation -+ * fixed some ASSERT check. -+ * -+ * 11 04 2010 wh.su -+ * [WCXRP00000164] [MT6620 Wi-Fi][Driver] Support the p2p random SSID -+ * adding the p2p random ssid support. -+ * -+ * 10 20 2010 wh.su -+ * [WCXRP00000124] [MT6620 Wi-Fi] [Driver] Support the dissolve P2P Group -+ * Add the code to support disconnect p2p group -+ * -+ * 10 04 2010 wh.su -+ * [WCXRP00000081] [MT6620][Driver] Fix the compiling error at WinXP while enable P2P -+ * add a kal function for set cipher. -+ * -+ * 10 04 2010 wh.su -+ * [WCXRP00000081] [MT6620][Driver] Fix the compiling error at WinXP while enable P2P -+ * fixed compiling error while enable p2p. -+ * -+ * 09 28 2010 wh.su -+ * NULL -+ * [WCXRP00000069][MT6620 Wi-Fi][Driver] Fix some code for phase 1 P2P Demo. -+ * -+ * 09 21 2010 kevin.huang -+ * [WCXRP00000054] [MT6620 Wi-Fi][Driver] Restructure driver for second Interface -+ * Isolate P2P related function for Hardware Software Bundle -+ * -+ * 09 21 2010 kevin.huang -+ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning -+ * Eliminate Linux Compile Warning -+ * -+ * 09 10 2010 george.huang -+ * NULL -+ * update iwpriv LP related -+ * -+ * 09 10 2010 wh.su -+ * NULL -+ * fixed the compiling error at win XP. -+ * -+ * 09 09 2010 cp.wu -+ * NULL -+ * add WPS/WPA/RSN IE for Wi-Fi Direct scanning result. -+ * -+ * 09 07 2010 wh.su -+ * NULL -+ * adding the code for beacon/probe req/ probe rsp wsc ie at p2p. -+ * -+ * 09 06 2010 wh.su -+ * NULL -+ * let the p2p can set the privacy bit at beacon and rsn ie at assoc req at key handshake state. -+ * -+ * 08 25 2010 cp.wu -+ * NULL -+ * add netdev_ops(NDO) for linux kernel 2.6.31 or greater -+ * -+ * 08 23 2010 cp.wu -+ * NULL -+ * revise constant definitions to be matched with implementation (original cmd-event definition is deprecated) -+ * -+ * 08 20 2010 cp.wu -+ * NULL -+ * correct typo. -+ * -+ * 08 20 2010 yuche.tsai -+ * NULL -+ * Invert Connection request provision status parameter. -+ * -+ * 08 19 2010 cp.wu -+ * NULL -+ * add set mac address interface for further possibilities of wpa_supplicant overriding interface address. -+ * -+ * 08 18 2010 cp.wu -+ * NULL -+ * modify pwp ioctls attribution by removing FIXED_SIZE. -+ * -+ * 08 18 2010 jeffrey.chang -+ * NULL -+ * support multi-function sdio -+ * -+ * 08 17 2010 cp.wu -+ * NULL -+ * correct p2p net device registration with NULL pointer access issue. -+ * -+ * 08 16 2010 cp.wu -+ * NULL -+ * P2P packets are now marked when being queued into driver, and identified later without checking MAC address -+ * -+ * 08 16 2010 cp.wu -+ * NULL -+ * add subroutines for P2P to set multicast list. -+ * -+ * 08 16 2010 george.huang -+ * NULL -+ * add wext handlers to link P2P set PS profile/ network address function (TBD) -+ * -+ * 08 16 2010 cp.wu -+ * NULL -+ * revised implementation of Wi-Fi Direct io controls. -+ * -+ * 08 12 2010 cp.wu -+ * NULL -+ * follow-up with ioctl interface update for Wi-Fi Direct application -+ * -+ * 08 06 2010 cp.wu -+ * NULL -+ * driver hook modifications corresponding to ioctl interface change. -+ * -+ * 08 03 2010 cp.wu -+ * NULL -+ * add basic support for ioctl of getting scan result. (only address and SSID are reporterd though) -+ * -+ * 08 03 2010 cp.wu -+ * NULL -+ * [Wi-Fi Direct Driver Hook] change event indication API to be consistent with supplicant -+ * -+ * 08 03 2010 cp.wu -+ * NULL -+ * surpress compilation warning. -+ * -+ * 08 03 2010 cp.wu -+ * NULL -+ * [Wi-Fi Direct] add framework for driver hooks -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 23 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * p2p interface revised to be sync. with HAL -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 06 01 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * add ioctl to configure scan mode for p2p connection -+ * -+ * 05 31 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * add cfg80211 interface, which is to replace WE, for further extension -+ * -+ * 05 17 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * implement private io controls for Wi-Fi Direct -+ * -+ * 05 17 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * implement get scan result. -+ * -+ * 05 17 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * add basic handling framework for wireless extension ioctls. -+ * -+ * 05 17 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * 1) add timeout handler mechanism for pending command packets -+ * 2) add p2p add/removal key -+ * -+ * 05 14 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * implement wireless extension ioctls in iw_handler form. -+ * -+ * 05 14 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * add ioctl framework for Wi-Fi Direct by reusing wireless extension ioctls as well -+ * -+ * 05 11 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * p2p ioctls revised. -+ * -+ * 05 11 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * add ioctl for controlling p2p scan phase parameters -+ * -+ * 05 10 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * implement basic wi-fi direct framework -+ * -+ * 05 07 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * add basic framework for implementating P2P driver hook. -+ * -+** -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include -+#include -+ -+#include "gl_os.h" -+#include "wlan_lib.h" -+#include "gl_wext.h" -+#include "gl_p2p_os.h" -+#include "gl_p2p_ioctl.h" -+#include "gl_vendor.h" -+ -+#include "precomp.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+#define ARGV_MAX_NUM (4) -+ -+/*For CFG80211 - wiphy parameters*/ -+#define MAX_SCAN_LIST_NUM (1) -+#define MAX_SCAN_IE_LEN (512) -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+#if CFG_ENABLE_WIFI_DIRECT_CFG_80211 -+static struct cfg80211_ops mtk_p2p_ops = { -+ .change_virtual_intf = mtk_p2p_cfg80211_change_iface, /* 1st */ -+ .change_bss = mtk_p2p_cfg80211_change_bss, -+ .scan = mtk_p2p_cfg80211_scan, -+ .remain_on_channel = mtk_p2p_cfg80211_remain_on_channel, -+ .cancel_remain_on_channel = mtk_p2p_cfg80211_cancel_remain_on_channel, -+ .mgmt_tx = mtk_p2p_cfg80211_mgmt_tx, -+ .connect = mtk_p2p_cfg80211_connect, -+ .disconnect = mtk_p2p_cfg80211_disconnect, -+ .deauth = mtk_p2p_cfg80211_deauth, -+ .disassoc = mtk_p2p_cfg80211_disassoc, -+ .start_ap = mtk_p2p_cfg80211_start_ap, -+ .change_beacon = mtk_p2p_cfg80211_change_beacon, -+ .stop_ap = mtk_p2p_cfg80211_stop_ap, -+ .set_wiphy_params = mtk_p2p_cfg80211_set_wiphy_params, -+ .del_station = mtk_p2p_cfg80211_del_station, -+ .set_monitor_channel = mtk_p2p_cfg80211_set_channel, -+ .set_bitrate_mask = mtk_p2p_cfg80211_set_bitrate_mask, -+ .mgmt_frame_register = mtk_p2p_cfg80211_mgmt_frame_register, -+ .get_station = mtk_p2p_cfg80211_get_station, -+ .add_key = mtk_p2p_cfg80211_add_key, -+ .get_key = mtk_p2p_cfg80211_get_key, -+ .del_key = mtk_p2p_cfg80211_del_key, -+ .set_default_key = mtk_p2p_cfg80211_set_default_key, -+ .join_ibss = mtk_p2p_cfg80211_join_ibss, -+ .leave_ibss = mtk_p2p_cfg80211_leave_ibss, -+ .set_tx_power = mtk_p2p_cfg80211_set_txpower, -+ .get_tx_power = mtk_p2p_cfg80211_get_txpower, -+ .set_power_mgmt = mtk_p2p_cfg80211_set_power_mgmt, -+#ifdef CONFIG_NL80211_TESTMODE -+ .testmode_cmd = mtk_p2p_cfg80211_testmode_cmd, -+#endif -+}; -+ -+static const struct wiphy_vendor_command mtk_p2p_vendor_ops[] = { -+ { -+ { -+ .vendor_id = GOOGLE_OUI, -+ .subcmd = WIFI_SUBCMD_GET_CHANNEL_LIST -+ }, -+ .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, -+ .doit = mtk_cfg80211_vendor_get_channel_list -+ }, -+ { -+ { -+ .vendor_id = GOOGLE_OUI, -+ .subcmd = WIFI_SUBCMD_SET_COUNTRY_CODE -+ }, -+ .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, -+ .doit = mtk_cfg80211_vendor_set_country_code -+ }, -+}; -+ -+/* There isn't a lot of sense in it, but you can transmit anything you like */ -+static const struct ieee80211_txrx_stypes -+ mtk_cfg80211_default_mgmt_stypes[NUM_NL80211_IFTYPES] = { -+ [NL80211_IFTYPE_ADHOC] = { -+ .tx = 0xffff, -+ .rx = BIT(IEEE80211_STYPE_ACTION >> 4) -+ }, -+ [NL80211_IFTYPE_STATION] = { -+ .tx = 0xffff, -+ .rx = BIT(IEEE80211_STYPE_ACTION >> 4) | BIT(IEEE80211_STYPE_PROBE_REQ >> 4) -+ }, -+ [NL80211_IFTYPE_AP] = { -+ .tx = 0xffff, -+ .rx = BIT(IEEE80211_STYPE_PROBE_REQ >> 4) | BIT(IEEE80211_STYPE_ACTION >> 4) -+ }, -+ [NL80211_IFTYPE_AP_VLAN] = { -+ /* copy AP */ -+ .tx = 0xffff, -+ .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) | -+ BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) | -+ BIT(IEEE80211_STYPE_PROBE_REQ >> 4) | -+ BIT(IEEE80211_STYPE_DISASSOC >> 4) | -+ BIT(IEEE80211_STYPE_AUTH >> 4) | -+ BIT(IEEE80211_STYPE_DEAUTH >> 4) | BIT(IEEE80211_STYPE_ACTION >> 4) -+ }, -+ [NL80211_IFTYPE_P2P_CLIENT] = { -+ .tx = 0xffff, -+ .rx = BIT(IEEE80211_STYPE_ACTION >> 4) | BIT(IEEE80211_STYPE_PROBE_REQ >> 4) -+ }, -+ [NL80211_IFTYPE_P2P_GO] = { -+ .tx = 0xffff, -+ .rx = BIT(IEEE80211_STYPE_PROBE_REQ >> 4) | BIT(IEEE80211_STYPE_ACTION >> 4) -+ } -+}; -+ -+#endif -+ -+/* the legacy wireless extension stuff */ -+static const iw_handler rP2PIwStandardHandler[] = { -+ [SIOCGIWPRIV - SIOCIWFIRST] = mtk_p2p_wext_get_priv, -+ [SIOCGIWSCAN - SIOCIWFIRST] = mtk_p2p_wext_discovery_results, -+ [SIOCSIWESSID - SIOCIWFIRST] = mtk_p2p_wext_reconnect, -+ [SIOCSIWAUTH - SIOCIWFIRST] = mtk_p2p_wext_set_auth, -+ [SIOCSIWENCODEEXT - SIOCIWFIRST] = mtk_p2p_wext_set_key, -+ [SIOCSIWPOWER - SIOCIWFIRST] = mtk_p2p_wext_set_powermode, -+ [SIOCGIWPOWER - SIOCIWFIRST] = mtk_p2p_wext_get_powermode, -+ [SIOCSIWTXPOW - SIOCIWFIRST] = mtk_p2p_wext_set_txpow, -+#if CFG_SUPPORT_P2P_RSSI_QUERY -+ [SIOCGIWSTATS - SIOCIWFIRST] = mtk_p2p_wext_get_rssi, -+#endif -+ [SIOCSIWMLME - SIOCIWFIRST] = mtk_p2p_wext_mlme_handler, -+}; -+ -+static const iw_handler rP2PIwPrivHandler[] = { -+ [IOC_P2P_CFG_DEVICE - SIOCIWFIRSTPRIV] = mtk_p2p_wext_set_local_dev_info, -+ [IOC_P2P_PROVISION_COMPLETE - SIOCIWFIRSTPRIV] = mtk_p2p_wext_set_provision_complete, -+ [IOC_P2P_START_STOP_DISCOVERY - SIOCIWFIRSTPRIV] = mtk_p2p_wext_start_stop_discovery, -+ [IOC_P2P_DISCOVERY_RESULTS - SIOCIWFIRSTPRIV] = mtk_p2p_wext_discovery_results, -+ [IOC_P2P_WSC_BEACON_PROBE_RSP_IE - SIOCIWFIRSTPRIV] = mtk_p2p_wext_wsc_ie, -+ [IOC_P2P_CONNECT_DISCONNECT - SIOCIWFIRSTPRIV] = mtk_p2p_wext_connect_disconnect, -+ [IOC_P2P_PASSWORD_READY - SIOCIWFIRSTPRIV] = mtk_p2p_wext_password_ready, -+/* [IOC_P2P_SET_PWR_MGMT_PARAM - SIOCIWFIRSTPRIV] = mtk_p2p_wext_set_pm_param, */ -+ [IOC_P2P_SET_INT - SIOCIWFIRSTPRIV] = mtk_p2p_wext_set_int, -+ [IOC_P2P_GET_STRUCT - SIOCIWFIRSTPRIV] = mtk_p2p_wext_get_struct, -+ [IOC_P2P_SET_STRUCT - SIOCIWFIRSTPRIV] = mtk_p2p_wext_set_struct, -+ [IOC_P2P_GET_REQ_DEVICE_INFO - SIOCIWFIRSTPRIV] = mtk_p2p_wext_request_dev_info, -+}; -+ -+static const struct iw_priv_args rP2PIwPrivTable[] = { -+ { -+ .cmd = IOC_P2P_CFG_DEVICE, -+ .set_args = IW_PRIV_TYPE_BYTE | (__u16) sizeof(IW_P2P_CFG_DEVICE_TYPE), -+ .get_args = IW_PRIV_TYPE_NONE, -+ .name = "P2P_CFG_DEVICE"} -+ , -+ { -+ .cmd = IOC_P2P_START_STOP_DISCOVERY, -+ .set_args = IW_PRIV_TYPE_BYTE | (__u16) sizeof(IW_P2P_REQ_DEVICE_TYPE), -+ .get_args = IW_PRIV_TYPE_NONE, -+ .name = "P2P_DISCOVERY"} -+ , -+ { -+ .cmd = IOC_P2P_DISCOVERY_RESULTS, -+ .set_args = IW_PRIV_TYPE_NONE, -+ .get_args = IW_PRIV_TYPE_NONE, -+ .name = "P2P_RESULT"} -+ , -+ { -+ .cmd = IOC_P2P_WSC_BEACON_PROBE_RSP_IE, -+ .set_args = IW_PRIV_TYPE_BYTE | (__u16) sizeof(IW_P2P_HOSTAPD_PARAM), -+ .get_args = IW_PRIV_TYPE_NONE, -+ .name = "P2P_WSC_IE"} -+ , -+ { -+ .cmd = IOC_P2P_CONNECT_DISCONNECT, -+ .set_args = IW_PRIV_TYPE_BYTE | (__u16) sizeof(IW_P2P_CONNECT_DEVICE), -+ .get_args = IW_PRIV_TYPE_NONE, -+ .name = "P2P_CONNECT"} -+ , -+ { -+ .cmd = IOC_P2P_PASSWORD_READY, -+ .set_args = IW_PRIV_TYPE_BYTE | (__u16) sizeof(IW_P2P_PASSWORD_READY), -+ .get_args = IW_PRIV_TYPE_NONE, -+ .name = "P2P_PASSWD_RDY"} -+ , -+ { -+ .cmd = IOC_P2P_GET_STRUCT, -+ .set_args = IW_PRIV_TYPE_NONE, -+ .get_args = 256, -+ .name = "P2P_GET_STRUCT"} -+ , -+ { -+ .cmd = IOC_P2P_SET_STRUCT, -+ .set_args = 256, -+ .get_args = IW_PRIV_TYPE_NONE, -+ .name = "P2P_SET_STRUCT"} -+ , -+ { -+ .cmd = IOC_P2P_GET_REQ_DEVICE_INFO, -+ .set_args = IW_PRIV_TYPE_NONE, -+ .get_args = IW_PRIV_TYPE_BYTE | (__u16) sizeof(IW_P2P_DEVICE_REQ), -+ .name = "P2P_GET_REQDEV"} -+ , -+ { -+ /* SET STRUCT sub-ioctls commands */ -+ .cmd = PRIV_CMD_OID, -+ .set_args = 256, -+ .get_args = IW_PRIV_TYPE_NONE, -+ .name = "set_oid"} -+ , -+ { -+ /* GET STRUCT sub-ioctls commands */ -+ .cmd = PRIV_CMD_OID, -+ .set_args = IW_PRIV_TYPE_NONE, -+ .get_args = 256, -+ .name = "get_oid"} -+}; -+ -+const struct iw_handler_def mtk_p2p_wext_handler_def = { -+ .num_standard = (__u16) sizeof(rP2PIwStandardHandler) / sizeof(iw_handler), -+ .num_private = (__u16) sizeof(rP2PIwPrivHandler) / sizeof(iw_handler), -+ .num_private_args = (__u16) sizeof(rP2PIwPrivTable) / sizeof(struct iw_priv_args), -+ .standard = rP2PIwStandardHandler, -+ .private = rP2PIwPrivHandler, -+ .private_args = rP2PIwPrivTable, -+#if CFG_SUPPORT_P2P_RSSI_QUERY -+ .get_wireless_stats = mtk_p2p_wext_get_wireless_stats, -+#else -+ .get_wireless_stats = NULL, -+#endif -+}; -+ -+#ifdef CONFIG_PM -+static const struct wiphy_wowlan_support p2p_wowlan_support = { -+ .flags = WIPHY_WOWLAN_DISCONNECT | WIPHY_WOWLAN_ANY, -+}; -+#endif -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+/* for IE Searching */ -+extern BOOLEAN -+wextSrchDesiredWPAIE(IN PUINT_8 pucIEStart, -+ IN INT_32 i4TotalIeLen, IN UINT_8 ucDesiredElemId, OUT PUINT_8 *ppucDesiredIE); -+ -+#if CFG_SUPPORT_WPS -+extern BOOLEAN -+wextSrchDesiredWPSIE(IN PUINT_8 pucIEStart, -+ IN INT_32 i4TotalIeLen, IN UINT_8 ucDesiredElemId, OUT PUINT_8 *ppucDesiredIE); -+#endif -+ -+/* Net Device Hooks */ -+static int p2pOpen(IN struct net_device *prDev); -+ -+static int p2pStop(IN struct net_device *prDev); -+ -+static struct net_device_stats *p2pGetStats(IN struct net_device *prDev); -+ -+static void p2pSetMulticastList(IN struct net_device *prDev); -+ -+static int p2pHardStartXmit(IN struct sk_buff *prSkb, IN struct net_device *prDev); -+ -+static int p2pDoIOCTL(struct net_device *prDev, struct ifreq *prIfReq, int i4Cmd); -+ -+static int p2pSetMACAddress(IN struct net_device *prDev, void *addr); -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Override the implementation of select queue -+* -+* \param[in] dev Pointer to struct net_device -+* \param[in] skb Pointer to struct skb_buff -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+ -+unsigned int _p2p_cfg80211_classify8021d(struct sk_buff *skb) -+{ -+ unsigned int dscp = 0; -+ -+ /* skb->priority values from 256->263 are magic values -+ * directly indicate a specific 802.1d priority. This is -+ * to allow 802.1d priority to be passed directly in from -+ * tags -+ */ -+ -+ if (skb->priority >= 256 && skb->priority <= 263) -+ return skb->priority - 256; -+ switch (skb->protocol) { -+ case htons(ETH_P_IP): -+ dscp = ip_hdr(skb)->tos & 0xfc; -+ break; -+ } -+ return dscp >> 5; -+} -+ -+static const UINT_16 au16Wlan1dToQueueIdx[8] = { 1, 0, 0, 1, 2, 2, 3, 3 }; -+ -+static UINT_16 p2pSelectQueue(struct net_device *dev, struct sk_buff *skb, -+ struct net_device *sb_dev, -+ select_queue_fallback_t fallback) -+{ -+ skb->priority = _p2p_cfg80211_classify8021d(skb); -+ -+ return au16Wlan1dToQueueIdx[skb->priority]; -+} -+ -+static struct net_device *g_P2pPrDev; -+static struct wireless_dev *gprP2pWdev; -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief A function for prDev->init -+* -+* \param[in] prDev Pointer to struct net_device. -+* -+* \retval 0 The execution of wlanInit succeeds. -+* \retval -ENXIO No such device. -+*/ -+/*----------------------------------------------------------------------------*/ -+static int p2pInit(struct net_device *prDev) -+{ -+/* P_GLUE_INFO_T prGlueInfo; */ -+ if (!prDev) -+ return -ENXIO; -+ -+ DBGLOG(P2P, INFO, "dev name=%s\n", prDev->name); -+ return 0; /* success */ -+} /* end of p2pInit() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief A function for prDev->uninit -+* -+* \param[in] prDev Pointer to struct net_device. -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+static void p2pUninit(IN struct net_device *prDev) -+{ -+ -+} /* end of p2pUninit() */ -+ -+static const struct net_device_ops p2p_netdev_ops = { -+ .ndo_open = p2pOpen, -+ .ndo_stop = p2pStop, -+ .ndo_set_mac_address = p2pSetMACAddress, -+ .ndo_set_rx_mode = p2pSetMulticastList, -+ .ndo_get_stats = p2pGetStats, -+ .ndo_do_ioctl = p2pDoIOCTL, -+ .ndo_start_xmit = p2pHardStartXmit, -+ .ndo_select_queue = p2pSelectQueue, -+ .ndo_init = p2pInit, -+ .ndo_uninit = p2pUninit, -+}; -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Allocate memory for P2P_INFO, GL_P2P_INFO, P2P_CONNECTION_SETTINGS -+* P2P_SPECIFIC_BSS_INFO, P2P_FSM_INFO -+* -+* \param[in] prGlueInfo Pointer to glue info -+* -+* \return TRUE -+* FALSE -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN p2PAllocInfo(IN P_GLUE_INFO_T prGlueInfo) -+{ -+ P_ADAPTER_T prAdapter = NULL; -+ P_WIFI_VAR_T prWifiVar = NULL; -+ -+ if ((!prGlueInfo) || (!prGlueInfo->prAdapter)) { -+ ASSERT(FALSE); -+ return FALSE; -+ } -+ -+ prAdapter = prGlueInfo->prAdapter; -+ prWifiVar = &(prAdapter->rWifiVar); -+ -+ if (!prWifiVar) { -+ ASSERT(FALSE); -+ return FALSE; -+ } -+ -+ do { -+ if (prGlueInfo->prP2PInfo == NULL) { -+ /*alloc memory for p2p info */ -+ prGlueInfo->prP2PInfo = kalMemAlloc(sizeof(GL_P2P_INFO_T), VIR_MEM_TYPE); -+ prAdapter->prP2pInfo = kalMemAlloc(sizeof(P2P_INFO_T), VIR_MEM_TYPE); -+ prWifiVar->prP2PConnSettings = kalMemAlloc(sizeof(P2P_CONNECTION_SETTINGS_T), VIR_MEM_TYPE); -+ prWifiVar->prP2pFsmInfo = kalMemAlloc(sizeof(P2P_FSM_INFO_T), VIR_MEM_TYPE); -+ prWifiVar->prP2pSpecificBssInfo = kalMemAlloc(sizeof(P2P_SPECIFIC_BSS_INFO_T), VIR_MEM_TYPE); -+ } else { -+ ASSERT(prAdapter->prP2pInfo != NULL); -+ ASSERT(prWifiVar->prP2PConnSettings != NULL); -+ ASSERT(prWifiVar->prP2pFsmInfo != NULL); -+ ASSERT(prWifiVar->prP2pSpecificBssInfo != NULL); -+ } -+ /*MUST set memory to 0 */ -+ if (prGlueInfo->prP2PInfo) -+ kalMemZero(prGlueInfo->prP2PInfo, sizeof(GL_P2P_INFO_T)); -+ if (prAdapter->prP2pInfo) -+ kalMemZero(prAdapter->prP2pInfo, sizeof(P2P_INFO_T)); -+ if (prWifiVar->prP2PConnSettings) -+ kalMemZero(prWifiVar->prP2PConnSettings, sizeof(P2P_CONNECTION_SETTINGS_T)); -+ if (prWifiVar->prP2pFsmInfo) -+ kalMemZero(prWifiVar->prP2pFsmInfo, sizeof(P2P_FSM_INFO_T)); -+ if (prWifiVar->prP2pSpecificBssInfo) -+ kalMemZero(prWifiVar->prP2pSpecificBssInfo, sizeof(P2P_SPECIFIC_BSS_INFO_T)); -+ -+ } while (FALSE); -+ -+ /* chk if alloc successful or not */ -+ if (prGlueInfo->prP2PInfo && -+ prAdapter->prP2pInfo && -+ prWifiVar->prP2PConnSettings && prWifiVar->prP2pFsmInfo && prWifiVar->prP2pSpecificBssInfo) { -+ return TRUE; -+ } -+ -+ if (prWifiVar->prP2pSpecificBssInfo) { -+ kalMemFree(prWifiVar->prP2pSpecificBssInfo, VIR_MEM_TYPE, sizeof(P2P_SPECIFIC_BSS_INFO_T)); -+ -+ prWifiVar->prP2pSpecificBssInfo = NULL; -+ } -+ if (prWifiVar->prP2pFsmInfo) { -+ kalMemFree(prWifiVar->prP2pFsmInfo, VIR_MEM_TYPE, sizeof(P2P_FSM_INFO_T)); -+ -+ prWifiVar->prP2pFsmInfo = NULL; -+ } -+ if (prWifiVar->prP2PConnSettings) { -+ kalMemFree(prWifiVar->prP2PConnSettings, VIR_MEM_TYPE, sizeof(P2P_CONNECTION_SETTINGS_T)); -+ -+ prWifiVar->prP2PConnSettings = NULL; -+ } -+ if (prGlueInfo->prP2PInfo) { -+ kalMemFree(prGlueInfo->prP2PInfo, VIR_MEM_TYPE, sizeof(GL_P2P_INFO_T)); -+ -+ prGlueInfo->prP2PInfo = NULL; -+ } -+ if (prAdapter->prP2pInfo) { -+ kalMemFree(prAdapter->prP2pInfo, VIR_MEM_TYPE, sizeof(P2P_INFO_T)); -+ -+ prAdapter->prP2pInfo = NULL; -+ } -+ return FALSE; -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Free memory for P2P_INFO, GL_P2P_INFO, P2P_CONNECTION_SETTINGS -+* P2P_SPECIFIC_BSS_INFO, P2P_FSM_INFO -+* -+* \param[in] prGlueInfo Pointer to glue info -+* -+* \return TRUE -+* FALSE -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN p2PFreeInfo(P_GLUE_INFO_T prGlueInfo) -+{ -+ -+ if ((!prGlueInfo) || (!prGlueInfo->prAdapter)) { -+ ASSERT(FALSE); -+ return FALSE; -+ } -+ -+ /* free memory after p2p module is ALREADY unregistered */ -+ if (prGlueInfo->prAdapter->fgIsP2PRegistered == FALSE) { -+ -+ kalMemFree(prGlueInfo->prAdapter->prP2pInfo, VIR_MEM_TYPE, sizeof(P2P_INFO_T)); -+ kalMemFree(prGlueInfo->prP2PInfo, VIR_MEM_TYPE, sizeof(GL_P2P_INFO_T)); -+ kalMemFree(prGlueInfo->prAdapter->rWifiVar.prP2PConnSettings, VIR_MEM_TYPE, -+ sizeof(P2P_CONNECTION_SETTINGS_T)); -+ kalMemFree(prGlueInfo->prAdapter->rWifiVar.prP2pFsmInfo, VIR_MEM_TYPE, sizeof(P2P_FSM_INFO_T)); -+ kalMemFree(prGlueInfo->prAdapter->rWifiVar.prP2pSpecificBssInfo, VIR_MEM_TYPE, -+ sizeof(P2P_SPECIFIC_BSS_INFO_T)); -+ -+ /*Reomve p2p bss scan list */ -+ scanRemoveAllP2pBssDesc(prGlueInfo->prAdapter); -+ -+ /*reset all pointer to NULL */ -+ prGlueInfo->prP2PInfo = NULL; -+ prGlueInfo->prAdapter->prP2pInfo = NULL; -+ prGlueInfo->prAdapter->rWifiVar.prP2PConnSettings = NULL; -+ prGlueInfo->prAdapter->rWifiVar.prP2pFsmInfo = NULL; -+ prGlueInfo->prAdapter->rWifiVar.prP2pSpecificBssInfo = NULL; -+ -+ return TRUE; -+ } else { -+ return FALSE; -+ } -+ -+} -+ -+#if !CFG_SUPPORT_PERSIST_NETDEV -+BOOLEAN p2pNetRegister(P_GLUE_INFO_T prGlueInfo, BOOLEAN fgIsRtnlLockAcquired) -+{ -+ BOOLEAN fgDoRegister = FALSE; -+/* BOOLEAN fgRollbackRtnlLock = FALSE; */ -+ BOOLEAN ret; -+ -+ GLUE_SPIN_LOCK_DECLARATION(); -+ -+ if ((!prGlueInfo) || (!prGlueInfo->prAdapter)) { -+ ASSERT(FALSE); -+ return FALSE; -+ } -+ -+ GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV); -+ if (prGlueInfo->prAdapter->rP2PNetRegState == ENUM_NET_REG_STATE_UNREGISTERED) { -+ prGlueInfo->prAdapter->rP2PNetRegState = ENUM_NET_REG_STATE_REGISTERING; -+ fgDoRegister = TRUE; -+ } -+ GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV); -+ -+ if (!fgDoRegister) -+ return TRUE; -+ -+ /* net device initialize */ -+ netif_carrier_off(prGlueInfo->prP2PInfo->prDevHandler); -+ netif_tx_stop_all_queues(prGlueInfo->prP2PInfo->prDevHandler); -+ -+ /* register for net device */ -+ if (register_netdev(prGlueInfo->prP2PInfo->prDevHandler) < 0) { -+ DBGLOG(P2P, WARN, "unable to register netdevice for p2p\n"); -+ -+ free_netdev(prGlueInfo->prP2PInfo->prDevHandler); -+ -+ ret = FALSE; -+ } else { -+ prGlueInfo->prAdapter->rP2PNetRegState = ENUM_NET_REG_STATE_REGISTERED; -+ ret = TRUE; -+ } -+ return ret; -+} -+ -+BOOLEAN p2pNetUnregister(P_GLUE_INFO_T prGlueInfo, BOOLEAN fgIsRtnlLockAcquired) -+{ -+ BOOLEAN fgDoUnregister = FALSE; -+/* BOOLEAN fgRollbackRtnlLock = FALSE; */ -+ GLUE_SPIN_LOCK_DECLARATION(); -+ -+ if ((!prGlueInfo) || (!prGlueInfo->prAdapter)) { -+ ASSERT(FALSE); -+ return FALSE; -+ } -+ -+ GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV); -+ if (prGlueInfo->prAdapter->rP2PNetRegState == ENUM_NET_REG_STATE_REGISTERED) { -+ prGlueInfo->prAdapter->rP2PNetRegState = ENUM_NET_REG_STATE_UNREGISTERING; -+ fgDoUnregister = TRUE; -+ } -+ GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV); -+ -+ if (!fgDoUnregister) -+ return TRUE; -+ -+ /* prepare for removal */ -+ if (netif_carrier_ok(prGlueInfo->prP2PInfo->prDevHandler)) -+ netif_carrier_off(prGlueInfo->prP2PInfo->prDevHandler); -+ -+ netif_tx_stop_all_queues(prGlueInfo->prP2PInfo->prDevHandler); -+ DBGLOG(P2P, INFO, "P2P unregister_netdev 0x%p\n", prGlueInfo->prP2PInfo->prDevHandler); -+ unregister_netdev(prGlueInfo->prP2PInfo->prDevHandler); -+ -+ prGlueInfo->prAdapter->rP2PNetRegState = ENUM_NET_REG_STATE_UNREGISTERED; -+ -+ return TRUE; -+} -+#endif -+ -+BOOLEAN glP2pCreateWirelessDevice(P_GLUE_INFO_T prGlueInfo) -+{ -+ struct wiphy *prWiphy = NULL; -+ struct wireless_dev *prWdev = NULL; -+#if CFG_SUPPORT_PERSIST_NETDEV -+ struct net_device *prNetDev = NULL; -+#endif -+#if CFG_ENABLE_WIFI_DIRECT_CFG_80211 -+ prWdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL); -+ if (!prWdev) { -+ DBGLOG(P2P, ERROR, "allocate p2p wireless device fail, no memory\n"); -+ return FALSE; -+ } -+ /* 1. allocate WIPHY */ -+ prWiphy = wiphy_new(&mtk_p2p_ops, sizeof(P_GLUE_INFO_T)); -+ if (!prWiphy) { -+ DBGLOG(P2P, ERROR, "unable to allocate wiphy for p2p\n"); -+ goto free_wdev; -+ } -+ -+ prWiphy->interface_modes = BIT(NL80211_IFTYPE_AP) | BIT(NL80211_IFTYPE_P2P_CLIENT) | -+ BIT(NL80211_IFTYPE_P2P_GO) | BIT(NL80211_IFTYPE_STATION); -+ -+ prWiphy->bands[NL80211_BAND_2GHZ] = &mtk_band_2ghz; -+ prWiphy->bands[NL80211_BAND_5GHZ] = &mtk_band_5ghz; -+ -+ prWiphy->mgmt_stypes = mtk_cfg80211_default_mgmt_stypes; -+ prWiphy->max_remain_on_channel_duration = 5000; -+ prWiphy->cipher_suites = mtk_cipher_suites; -+ prWiphy->n_cipher_suites = ARRAY_SIZE(mtk_cipher_suites); -+ prWiphy->flags = WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL | WIPHY_FLAG_HAVE_AP_SME; -+ prWiphy->regulatory_flags = REGULATORY_CUSTOM_REG; -+ prWiphy->ap_sme_capa = 1; -+ -+ prWiphy->max_scan_ssids = MAX_SCAN_LIST_NUM; -+ prWiphy->max_scan_ie_len = MAX_SCAN_IE_LEN; -+ prWiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM; -+ prWiphy->vendor_commands = mtk_p2p_vendor_ops; -+ prWiphy->n_vendor_commands = sizeof(mtk_p2p_vendor_ops) / sizeof(struct wiphy_vendor_command); -+ -+#ifdef CONFIG_PM -+ prWiphy->wowlan = &p2p_wowlan_support; -+#endif -+ -+ /* 2.1 set priv as pointer to glue structure */ -+ *((P_GLUE_INFO_T *) wiphy_priv(prWiphy)) = prGlueInfo; -+ if (wiphy_register(prWiphy) < 0) { -+ DBGLOG(P2P, ERROR, "fail to register wiphy for p2p\n"); -+ goto free_wiphy; -+ } -+ prWdev->wiphy = prWiphy; -+#if CFG_SUPPORT_PERSIST_NETDEV -+ /* 3. allocate netdev */ -+ prNetDev = alloc_netdev_mq(sizeof(P_GLUE_INFO_T), P2P_MODE_INF_NAME, NET_NAME_PREDICTABLE, -+ ether_setup, CFG_MAX_TXQ_NUM); -+ if (!prNetDev) { -+ DBGLOG(P2P, ERROR, "unable to allocate netdevice for p2p\n"); -+ goto unregister_wiphy; -+ } -+ -+ /* 4. setup netdev */ -+ /* 4.1 Point to shared glue structure */ -+ *((P_GLUE_INFO_T *) netdev_priv(prNetDev)) = prGlueInfo; -+ -+ /* 4.2 fill hardware address */ -+ /* COPY_MAC_ADDR(rMacAddr, prAdapter->rMyMacAddr); -+ rMacAddr[0] ^= 0x2; // change to local administrated address -+ memcpy(prGlueInfo->prP2PInfo->prDevHandler->dev_addr, rMacAddr, ETH_ALEN); -+ memcpy(prGlueInfo->prP2PInfo->prDevHandler->perm_addr, -+ prGlueInfo->prP2PInfo->prDevHandler->dev_addr, ETH_ALEN);*/ -+ -+ /* 4.3 register callback functions */ -+ prNetDev->netdev_ops = &p2p_netdev_ops; -+ /* prGlueInfo->prP2PInfo->prDevHandler->wireless_handlers = &mtk_p2p_wext_handler_def;*/ -+ -+ prNetDev->ieee80211_ptr = prWdev; -+ prWdev->netdev = prNetDev; -+ -+#if CFG_TCP_IP_CHKSUM_OFFLOAD -+ prNetDev->features = NETIF_F_IP_CSUM; -+#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */ -+ /* net device initialize */ -+ netif_carrier_off(prNetDev); -+ netif_tx_stop_all_queues(prNetDev); -+ -+ /* register for net device */ -+ if (register_netdev(prNetDev) < 0) { -+ DBGLOG(P2P, ERROR, "unable to register netdevice for p2p\n"); -+ free_netdev(prNetDev); -+ goto unregister_wiphy; -+ } -+#endif -+ gprP2pWdev = prWdev; -+ return TRUE; -+ -+#if CFG_SUPPORT_PERSIST_NETDEV -+unregister_wiphy: -+ wiphy_unregister(prWiphy); -+#endif -+free_wiphy: -+ wiphy_free(prWiphy); -+free_wdev: -+ kfree(prWdev); -+#endif -+ return FALSE; -+} -+ -+void glP2pDestroyWirelessDevice(VOID) -+{ -+#if CFG_ENABLE_WIFI_DIRECT_CFG_80211 -+#if CFG_SUPPORT_PERSIST_NETDEV -+ unregister_netdev(gprP2pWdev->netdev); -+ free_netdev(gprP2pWdev->netdev); -+#endif -+ wiphy_unregister(gprP2pWdev->wiphy); -+ wiphy_free(gprP2pWdev->wiphy); -+ kfree(gprP2pWdev); -+ gprP2pWdev = NULL; -+#endif -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Register for cfg80211 for Wi-Fi Direct -+* -+* \param[in] prGlueInfo Pointer to glue info -+* -+* \return TRUE -+* FALSE -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN glRegisterP2P(P_GLUE_INFO_T prGlueInfo, const char *prDevName, BOOLEAN fgIsApMode) -+{ -+ P_ADAPTER_T prAdapter = NULL; -+ P_GL_HIF_INFO_T prHif = NULL; -+ PARAM_MAC_ADDRESS rMacAddr; -+ struct net_device *prDevHandler = NULL; -+#if CFG_ENABLE_WIFI_DIRECT_CFG_80211 -+ struct device *prDev; -+#endif -+ -+ ASSERT(prGlueInfo); -+ -+ prAdapter = prGlueInfo->prAdapter; -+ ASSERT(prAdapter); -+ -+ prHif = &prGlueInfo->rHifInfo; -+ ASSERT(prHif); -+ -+ DBGLOG(P2P, TRACE, "glRegisterP2P\n"); -+#if CFG_ENABLE_WIFI_DIRECT_CFG_80211 -+ if (!gprP2pWdev) { -+ DBGLOG(P2P, ERROR, "gl_p2p, wireless device is not exist\n"); -+ return FALSE; -+ } -+#endif -+ /*0. allocate p2pinfo */ -+ if (!p2PAllocInfo(prGlueInfo)) { -+ DBGLOG(P2P, ERROR, "Allocate memory for p2p FAILED\n"); -+ ASSERT(0); -+ return FALSE; -+ } -+#if CFG_ENABLE_WIFI_DIRECT_CFG_80211 -+ prGlueInfo->prP2PInfo->prWdev = gprP2pWdev; -+ /* 1. fill wiphy parameters */ -+#if MTK_WCN_HIF_SDIO -+ mtk_wcn_hif_sdio_get_dev(prHif->cltCtx, &prDev); -+ if (!prDev) -+ DBGLOG(P2P, WARN, "unable to get struct dev for p2p\n"); -+#else -+ prDev = prHif->Dev; -+#endif -+ /*set_wiphy_dev(gprP2pWdev->wiphy, prDev);*/ -+ if (!prGlueInfo->prAdapter->fgEnable5GBand) -+ gprP2pWdev->wiphy->bands[NL80211_BAND_5GHZ] = NULL; -+ -+ /* 2 set priv as pointer to glue structure */ -+ *(P_GLUE_INFO_T *) wiphy_priv(gprP2pWdev->wiphy) = prGlueInfo; -+ -+ if (fgIsApMode) { -+ gprP2pWdev->iftype = NL80211_IFTYPE_AP; -+#if CFG_SUPPORT_PERSIST_NETDEV -+ if (kalStrnCmp(gprP2pWdev->netdev->name, AP_MODE_INF_NAME, 2)) { -+ rtnl_lock(); -+ dev_change_name(gprP2pWdev->netdev->name, AP_MODE_INF_NAME); -+ rtnl_unlock(); -+ } -+#endif -+ } else { -+#if CFG_SUPPORT_PERSIST_NETDEV -+ if (kalStrnCmp(gprP2pWdev->netdev->name, P2P_MODE_INF_NAME, 3)) { -+ rtnl_lock(); -+ dev_change_name(gprP2pWdev->netdev->name, P2P_MODE_INF_NAME); -+ rtnl_unlock(); -+ } -+#endif -+ gprP2pWdev->iftype = NL80211_IFTYPE_P2P_CLIENT; -+ } -+#endif /* CFG_ENABLE_WIFI_DIRECT_CFG_80211 */ -+ -+#if CFG_SUPPORT_PERSIST_NETDEV -+ prP2PInfo->prDevHandler = gprP2pWdev->netdev; -+#else /* CFG_SUPPORT_PERSIST_NETDEV */ -+ /* 3. allocate netdev */ -+ prDevHandler = -+ alloc_netdev_mq(sizeof(P_GLUE_INFO_T), prDevName, NET_NAME_PREDICTABLE, ether_setup, CFG_MAX_TXQ_NUM); -+ if (!prDevHandler) { -+ DBGLOG(P2P, ERROR, "unable to allocate netdevice for p2p\n"); -+ return FALSE; -+ } -+ prGlueInfo->prP2PInfo->prDevHandler = prDevHandler; -+ /* 4. setup netdev */ -+ /* 4.1 Point to shared glue structure */ -+ *((P_GLUE_INFO_T *) netdev_priv(prDevHandler)) = prGlueInfo; -+ -+ /* 4.2 fill hardware address */ -+ COPY_MAC_ADDR(rMacAddr, prAdapter->rMyMacAddr); -+ rMacAddr[0] ^= 0x2; /* change to local administrated address */ -+ ether_addr_copy(prDevHandler->dev_addr, rMacAddr); -+ ether_addr_copy(prDevHandler->perm_addr, prDevHandler->dev_addr); -+ -+ /* 4.3 register callback functions */ -+ prDevHandler->netdev_ops = &p2p_netdev_ops; -+ /* prGlueInfo->prP2PInfo->prDevHandler->wireless_handlers = &mtk_p2p_wext_handler_def; */ -+ -+#if (MTK_WCN_HIF_SDIO == 0) -+ SET_NETDEV_DEV(prDevHandler, prHif->Dev); -+#endif -+ -+#if CFG_ENABLE_WIFI_DIRECT_CFG_80211 -+ prDevHandler->ieee80211_ptr = gprP2pWdev; -+ gprP2pWdev->netdev = prDevHandler; -+#endif -+ -+#if CFG_TCP_IP_CHKSUM_OFFLOAD -+ prDevHandler->features = NETIF_F_IP_CSUM; -+#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */ -+#endif /* CFG_SUPPORT_PERSIST_NETDEV */ -+ -+ /* 5. set p2p net device register state */ -+ prAdapter->rP2PNetRegState = ENUM_NET_REG_STATE_UNREGISTERED; -+ -+ /* 6. setup running mode */ -+ prAdapter->rWifiVar.prP2pFsmInfo->fgIsApMode = fgIsApMode; -+ -+ /* 7. finish */ -+ p2pFsmInit(prAdapter); -+ -+ p2pFuncInitConnectionSettings(prAdapter, prAdapter->rWifiVar.prP2PConnSettings); -+ -+ /* Active network too early would cause HW not able to sleep. -+ * Defer the network active time. -+ */ -+/* nicActivateNetwork(prAdapter, NETWORK_TYPE_P2P_INDEX); */ -+ -+ return TRUE; -+} /* end of glRegisterP2P() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Unregister Net Device for Wi-Fi Direct -+* -+* \param[in] prGlueInfo Pointer to glue info -+* -+* \return TRUE -+* FALSE -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN glUnregisterP2P(P_GLUE_INFO_T prGlueInfo) -+{ -+ ASSERT(prGlueInfo); -+ /* normal flow: this func will called first before wlanRemove, and it can do fsmUninit/deactivateNetwork -+ gracefully. */ -+ /* when reset: because tx_thread with fw has stopped, so it can't do these job and the recovery will be -+ dependent on chip system reset. */ -+ /* if so, just skip it by flag GLUE_FLAG_HALT(warning: when tx_thread was stop, this flag was not cleared, -+ and NEED TO KEEP IT NOT CLEARED!). */ -+ if (!(prGlueInfo->ulFlag & GLUE_FLAG_HALT)) { -+ p2pFsmUninit(prGlueInfo->prAdapter); -+ nicDeactivateNetwork(prGlueInfo->prAdapter, NETWORK_TYPE_P2P_INDEX); -+ } -+#if CFG_SUPPORT_PERSIST_NETDEV -+ dev_close(prGlueInfo->prP2PInfo->prDevHandler); -+#else -+ free_netdev(prGlueInfo->prP2PInfo->prDevHandler); -+ prGlueInfo->prP2PInfo->prDevHandler = NULL; -+#endif -+ /* Free p2p memory */ -+ if (!p2PFreeInfo(prGlueInfo)) { -+ DBGLOG(P2P, ERROR, "Free memory for p2p FAILED\n"); -+ ASSERT(0); -+ return FALSE; -+ } -+ return TRUE; -+} /* end of glUnregisterP2P() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * \brief A function for stop p2p fsm immediate -+ * -+ * \param[in] prGlueInfo Pointer to struct P_GLUE_INFO_T. -+ * -+ * \retval TRUE The execution succeeds. -+ * \retval FALSE The execution failed. -+ */ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN p2pStopImmediate(P_GLUE_INFO_T prGlueInfo) -+{ -+/* P_ADAPTER_T prAdapter = NULL; */ -+/* P_MSG_P2P_FUNCTION_SWITCH_T prFuncSwitch; */ -+ -+ ASSERT(prGlueInfo); -+ -+/* prAdapter = prGlueInfo->prAdapter; */ -+/* ASSERT(prAdapter); */ -+ -+ /* 1. stop TX queue */ -+ netif_tx_stop_all_queues(prGlueInfo->prP2PInfo->prDevHandler); -+ -+#if 0 -+ /* 2. switch P2P-FSM off */ -+ /* 2.1 allocate for message */ -+ prFuncSwitch = (P_MSG_P2P_FUNCTION_SWITCH_T) cnmMemAlloc(prAdapter, -+ RAM_TYPE_MSG, sizeof(MSG_P2P_FUNCTION_SWITCH_T)); -+ -+ if (!prFuncSwitch) { -+ ASSERT(0); /* Can't trigger P2P FSM */ -+ DBGLOG(P2P, ERROR, "Allocate for p2p mesasage FAILED\n"); -+ /* return -ENOMEM; */ -+ } -+ -+ /* 2.2 fill message */ -+ prFuncSwitch->rMsgHdr.eMsgId = MID_MNY_P2P_FUN_SWITCH; -+ prFuncSwitch->fgIsFuncOn = FALSE; -+ -+ /* 2.3 send message */ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prFuncSwitch, MSG_SEND_METHOD_UNBUF); -+ -+#endif -+ -+ /* 3. stop queue and turn off carrier */ -+ prGlueInfo->prP2PInfo->eState = PARAM_MEDIA_STATE_DISCONNECTED; -+ -+ return TRUE; -+} /* end of p2pStop() */ -+ -+/* Net Device Hooks */ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * \brief A function for net_device open (ifup) -+ * -+ * \param[in] prDev Pointer to struct net_device. -+ * -+ * \retval 0 The execution succeeds. -+ * \retval < 0 The execution failed. -+ */ -+/*----------------------------------------------------------------------------*/ -+static int p2pOpen(IN struct net_device *prDev) -+{ -+/* P_GLUE_INFO_T prGlueInfo = NULL; */ -+/* P_ADAPTER_T prAdapter = NULL; */ -+/* P_MSG_P2P_FUNCTION_SWITCH_T prFuncSwitch; */ -+ -+ ASSERT(prDev); -+ -+#if 0 /* Move after device name set. (mtk_p2p_set_local_dev_info) */ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ ASSERT(prGlueInfo); -+ -+ prAdapter = prGlueInfo->prAdapter; -+ ASSERT(prAdapter); -+ -+ /* 1. switch P2P-FSM on */ -+ /* 1.1 allocate for message */ -+ prFuncSwitch = (P_MSG_P2P_FUNCTION_SWITCH_T) cnmMemAlloc(prAdapter, -+ RAM_TYPE_MSG, sizeof(MSG_P2P_FUNCTION_SWITCH_T)); -+ -+ if (!prFuncSwitch) { -+ ASSERT(0); /* Can't trigger P2P FSM */ -+ return -ENOMEM; -+ } -+ -+ /* 1.2 fill message */ -+ prFuncSwitch->rMsgHdr.eMsgId = MID_MNY_P2P_FUN_SWITCH; -+ prFuncSwitch->fgIsFuncOn = TRUE; -+ -+ /* 1.3 send message */ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prFuncSwitch, MSG_SEND_METHOD_BUF); -+#endif -+ -+ /* 2. carrier on & start TX queue */ -+ netif_carrier_on(prDev); -+ netif_tx_start_all_queues(prDev); -+ -+ return 0; /* success */ -+} /* end of p2pOpen() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * \brief A function for net_device stop (ifdown) -+ * -+ * \param[in] prDev Pointer to struct net_device. -+ * -+ * \retval 0 The execution succeeds. -+ * \retval < 0 The execution failed. -+ */ -+/*----------------------------------------------------------------------------*/ -+static int p2pStop(IN struct net_device *prDev) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ /* P_ADAPTER_T prAdapter = NULL; */ -+/* P_MSG_P2P_FUNCTION_SWITCH_T prFuncSwitch; */ -+ P_GL_P2P_INFO_T prGlueP2pInfo = (P_GL_P2P_INFO_T) NULL; -+ -+ struct cfg80211_scan_info info = { -+ .aborted = true, -+ }; -+ -+ struct cfg80211_scan_request *prScanRequest = NULL; -+ -+ GLUE_SPIN_LOCK_DECLARATION(); -+ ASSERT(prDev); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ ASSERT(prGlueInfo); -+ -+ prGlueP2pInfo = prGlueInfo->prP2PInfo; -+ ASSERT(prGlueP2pInfo); -+ -+ /* CFG80211 down */ -+ GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV); -+ if (prGlueP2pInfo->prScanRequest != NULL) { -+ prScanRequest = prGlueP2pInfo->prScanRequest; -+ prGlueP2pInfo->prScanRequest = NULL; -+ } -+ GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV); -+ -+ if (prScanRequest) -+ cfg80211_scan_done(prScanRequest, &info); -+#if 0 -+ -+ /* 1. stop TX queue */ -+ netif_tx_stop_all_queues(prDev); -+ -+ /* 2. switch P2P-FSM off */ -+ /* 2.1 allocate for message */ -+ prFuncSwitch = (P_MSG_P2P_FUNCTION_SWITCH_T) cnmMemAlloc(prAdapter, -+ RAM_TYPE_MSG, sizeof(MSG_P2P_FUNCTION_SWITCH_T)); -+ -+ if (!prFuncSwitch) { -+ ASSERT(0); /* Can't trigger P2P FSM */ -+ return -ENOMEM; -+ } -+ -+ /* 2.2 fill message */ -+ prFuncSwitch->rMsgHdr.eMsgId = MID_MNY_P2P_FUN_SWITCH; -+ prFuncSwitch->fgIsFuncOn = FALSE; -+ -+ /* 2.3 send message */ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prFuncSwitch, MSG_SEND_METHOD_BUF); -+#endif -+ /* 3. stop queue and turn off carrier */ -+ prGlueInfo->prP2PInfo->eState = PARAM_MEDIA_STATE_DISCONNECTED; -+ -+ netif_tx_stop_all_queues(prDev); -+ if (netif_carrier_ok(prDev)) -+ netif_carrier_off(prDev); -+ -+ return 0; -+} /* end of p2pStop() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * \brief A method of struct net_device, to get the network interface statistical -+ * information. -+ * -+ * Whenever an application needs to get statistics for the interface, this method -+ * is called. This happens, for example, when ifconfig or netstat -i is run. -+ * -+ * \param[in] prDev Pointer to struct net_device. -+ * -+ * \return net_device_stats buffer pointer. -+ */ -+/*----------------------------------------------------------------------------*/ -+struct net_device_stats *p2pGetStats(IN struct net_device *prDev) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ -+ ASSERT(prDev); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ -+#if CFG_SUPPORT_PERSIST_NETDEV -+ /* @FIXME */ -+ /* prDev->stats.rx_packets = 0; */ -+ /* prDev->stats.tx_packets = 0; */ -+ prDev->stats.tx_errors = 0; -+ prDev->stats.rx_errors = 0; -+ /* prDev->stats.rx_bytes = 0; */ -+ /* prDev->stats.tx_bytes = 0; */ -+ prDev->stats.multicast = 0; -+ -+ return &prDev->stats; -+ -+#else -+ /* prGlueInfo->prP2PInfo->rNetDevStats.rx_packets = 0; */ -+ /* prGlueInfo->prP2PInfo->rNetDevStats.tx_packets = 0; */ -+ prGlueInfo->prP2PInfo->rNetDevStats.tx_errors = 0; -+ prGlueInfo->prP2PInfo->rNetDevStats.rx_errors = 0; -+ /* prGlueInfo->prP2PInfo->rNetDevStats.rx_bytes = 0; */ -+ /* prGlueInfo->prP2PInfo->rNetDevStats.tx_bytes = 0; */ -+ /* prGlueInfo->prP2PInfo->rNetDevStats.rx_errors = 0; */ -+ prGlueInfo->prP2PInfo->rNetDevStats.multicast = 0; -+ -+ return &prGlueInfo->prP2PInfo->rNetDevStats; -+#endif -+} /* end of p2pGetStats() */ -+ -+static void p2pSetMulticastList(IN struct net_device *prDev) -+{ -+ P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) NULL; -+ -+ prGlueInfo = (NULL != prDev) ? *((P_GLUE_INFO_T *) netdev_priv(prDev)) : NULL; -+ -+ ASSERT(prDev); -+ ASSERT(prGlueInfo); -+ if (!prDev || !prGlueInfo) { -+ DBGLOG(P2P, WARN, "abnormal dev or skb: prDev(0x%p), prGlueInfo(0x%p)\n", prDev, prGlueInfo); -+ return; -+ } -+ -+ g_P2pPrDev = prDev; -+ -+ /* 4 Mark HALT, notify main thread to finish current job */ -+/* prGlueInfo->u4Flag |= GLUE_FLAG_SUB_MOD_MULTICAST; */ -+ set_bit(GLUE_FLAG_SUB_MOD_MULTICAST_BIT, &prGlueInfo->ulFlag); -+ -+ /* wake up main thread */ -+ wake_up_interruptible(&prGlueInfo->waitq); -+ -+} /* p2pSetMulticastList */ -+ -+/* FIXME: Since we cannot sleep in the wlanSetMulticastList, we arrange -+ * another workqueue for sleeping. We don't want to block -+ * tx_thread, so we can't let tx_thread to do this */ -+ -+void p2pSetMulticastListWorkQueueWrapper(P_GLUE_INFO_T prGlueInfo) -+{ -+ if (!prGlueInfo) { -+ DBGLOG(INIT, ERROR, "prGlueInfo is NULL\n"); -+ return; -+ } -+#if CFG_ENABLE_WIFI_DIRECT -+ if (prGlueInfo->prAdapter->fgIsP2PRegistered) -+ mtk_p2p_wext_set_Multicastlist(prGlueInfo); -+#endif -+} /* end of p2pSetMulticastListWorkQueueWrapper() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * \brief This function is to set multicast list and set rx mode. -+ * -+ * \param[in] prDev Pointer to struct net_device -+ * -+ * \return (none) -+ */ -+/*----------------------------------------------------------------------------*/ -+void mtk_p2p_wext_set_Multicastlist(P_GLUE_INFO_T prGlueInfo) -+{ -+ UINT_32 u4SetInfoLen = 0; -+ struct net_device *prDev = g_P2pPrDev; -+ -+ prGlueInfo = (NULL != prDev) ? *((P_GLUE_INFO_T *) netdev_priv(prDev)) : NULL; -+ -+ ASSERT(prDev); -+ ASSERT(prGlueInfo); -+ if (!prDev || !prGlueInfo) { -+ DBGLOG(P2P, WARN, "abnormal dev or skb: prDev(0x%p), prGlueInfo(0x%p)\n", prDev, prGlueInfo); -+ return; -+ } -+ -+ if (prDev->flags & IFF_PROMISC) -+ prGlueInfo->prP2PInfo->u4PacketFilter |= PARAM_PACKET_FILTER_PROMISCUOUS; -+ -+ if (prDev->flags & IFF_BROADCAST) -+ prGlueInfo->prP2PInfo->u4PacketFilter |= PARAM_PACKET_FILTER_BROADCAST; -+ -+ if (prDev->flags & IFF_MULTICAST) { -+ if ((prDev->flags & IFF_ALLMULTI) || -+ (netdev_mc_count(prDev) > MAX_NUM_GROUP_ADDR)) { -+ prGlueInfo->prP2PInfo->u4PacketFilter |= PARAM_PACKET_FILTER_ALL_MULTICAST; -+ } else { -+ prGlueInfo->prP2PInfo->u4PacketFilter |= PARAM_PACKET_FILTER_MULTICAST; -+ } -+ } -+ -+ if (prGlueInfo->prP2PInfo->u4PacketFilter & PARAM_PACKET_FILTER_MULTICAST) { -+ /* Prepare multicast address list */ -+ struct netdev_hw_addr *ha; -+ UINT_32 i = 0; -+ -+ netdev_for_each_mc_addr(ha, prDev) { -+ if (i < MAX_NUM_GROUP_ADDR) { -+ COPY_MAC_ADDR(&(prGlueInfo->prP2PInfo->aucMCAddrList[i]), ha->addr); -+ i++; -+ } -+ } -+ -+ DBGLOG(P2P, TRACE, "SEt Multicast Address List\n"); -+ -+ if (i >= MAX_NUM_GROUP_ADDR) -+ return; -+ wlanoidSetP2PMulticastList(prGlueInfo->prAdapter, -+ &(prGlueInfo->prP2PInfo->aucMCAddrList[0]), (i * ETH_ALEN), &u4SetInfoLen); -+ -+ } -+ -+} /* end of mtk_p2p_wext_set_Multicastlist */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * * \brief This function is TX entry point of NET DEVICE. -+ * * -+ * * \param[in] prSkb Pointer of the sk_buff to be sent -+ * * \param[in] prDev Pointer to struct net_device -+ * * -+ * * \retval NETDEV_TX_OK - on success. -+ * * \retval NETDEV_TX_BUSY - on failure, packet will be discarded by upper layer. -+ * */ -+/*----------------------------------------------------------------------------*/ -+int p2pHardStartXmit(IN struct sk_buff *prSkb, IN struct net_device *prDev) -+{ -+ P_QUE_ENTRY_T prQueueEntry = NULL; -+ P_QUE_T prTxQueue = NULL; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ UINT_16 u2QueueIdx = 0; -+ -+ GLUE_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(prSkb); -+ ASSERT(prDev); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ prGlueInfo->u8SkbToDriver++; -+ -+ if (prGlueInfo->ulFlag & GLUE_FLAG_HALT) { -+ DBGLOG(P2P, ERROR, "GLUE_FLAG_HALT skip tx\n"); -+ prGlueInfo->u8SkbFreed++; -+ dev_kfree_skb(prSkb); -+ return NETDEV_TX_OK; -+ } -+#if (CFG_SUPPORT_MET_PROFILING == 1) -+ kalMetProfilingStart(prGlueInfo, prSkb); -+#endif -+ -+ /* mark as P2P packets */ -+ GLUE_SET_PKT_FLAG_P2P(prSkb); -+#if CFG_ENABLE_PKT_LIFETIME_PROFILE -+ GLUE_SET_PKT_ARRIVAL_TIME(prSkb, kalGetTimeTick()); -+#endif -+ -+ STATS_TX_TIME_ARRIVE(prSkb); -+ prQueueEntry = (P_QUE_ENTRY_T) GLUE_GET_PKT_QUEUE_ENTRY(prSkb); -+ prTxQueue = &prGlueInfo->rTxQueue; -+ -+ if (wlanProcessSecurityFrame(prGlueInfo->prAdapter, (P_NATIVE_PACKET) prSkb) == FALSE) { -+ -+ u2QueueIdx = skb_get_queue_mapping(prSkb); -+ ASSERT(u2QueueIdx < CFG_MAX_TXQ_NUM); -+ -+ if (u2QueueIdx >= CFG_MAX_TXQ_NUM) { -+ DBGLOG(P2P, ERROR, "Incorrect queue index, skip this frame\n"); -+ prGlueInfo->u8SkbFreed++; -+ dev_kfree_skb(prSkb); -+ return NETDEV_TX_OK; -+ } -+ GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_TX_QUE); -+ QUEUE_INSERT_TAIL(prTxQueue, prQueueEntry); -+ GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_TX_QUE); -+ -+ GLUE_INC_REF_CNT(prGlueInfo->i4TxPendingFrameNum); -+ GLUE_INC_REF_CNT(prGlueInfo->ai4TxPendingFrameNumPerQueue[NETWORK_TYPE_P2P_INDEX][u2QueueIdx]); -+ -+ if (prGlueInfo->ai4TxPendingFrameNumPerQueue[NETWORK_TYPE_P2P_INDEX][u2QueueIdx] >= -+ CFG_TX_STOP_NETIF_PER_QUEUE_THRESHOLD) { -+ DBGLOG(TX, INFO, "netif_stop_subqueue for p2p0, Queue len: %d\n", -+ prGlueInfo->ai4TxPendingFrameNumPerQueue[NETWORK_TYPE_P2P_INDEX][u2QueueIdx]); -+ netif_stop_subqueue(prDev, u2QueueIdx); -+ } -+ } else { -+ GLUE_INC_REF_CNT(prGlueInfo->i4TxPendingSecurityFrameNum); -+ } -+ -+ kalSetEvent(prGlueInfo); -+ -+ /* Statistic usage. */ -+ prGlueInfo->prP2PInfo->rNetDevStats.tx_bytes += prSkb->len; -+ prGlueInfo->prP2PInfo->rNetDevStats.tx_packets++; -+ /* prDev->stats.tx_packets++; */ -+ kalPerMonStart(prGlueInfo); -+ return NETDEV_TX_OK; -+} /* end of p2pHardStartXmit() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * \brief A method of struct net_device, a primary SOCKET interface to configure -+ * the interface lively. Handle an ioctl call on one of our devices. -+ * Everything Linux ioctl specific is done here. Then we pass the contents -+ * of the ifr->data to the request message handler. -+ * -+ * \param[in] prDev Linux kernel netdevice -+ * -+ * \param[in] prIfReq Our private ioctl request structure, typed for the generic -+ * struct ifreq so we can use ptr to function -+ * -+ * \param[in] cmd Command ID -+ * -+ * \retval 0 The IOCTL command is executed successfully. -+ * \retval <0 The execution of IOCTL command is failed. -+ */ -+/*----------------------------------------------------------------------------*/ -+int p2pDoIOCTL(struct net_device *prDev, struct ifreq *prIfReq, int i4Cmd) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ int ret = 0; -+ char *prExtraBuf = NULL; -+ UINT_32 u4ExtraSize = 0; -+ struct iwreq *prIwReq = (struct iwreq *)prIfReq; -+ struct iw_request_info rIwReqInfo; -+ -+ ASSERT(prDev && prIfReq); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ if (!prGlueInfo) { -+ DBGLOG(P2P, ERROR, "prGlueInfo is NULL\n"); -+ return -EFAULT; -+ } -+ -+ if (prGlueInfo->u4ReadyFlag == 0) { -+ DBGLOG(P2P, ERROR, "Adapter is not ready\n"); -+ return -EINVAL; -+ } -+ -+ rIwReqInfo.cmd = (__u16) i4Cmd; -+ rIwReqInfo.flags = 0; -+ -+ switch (i4Cmd) { -+ case SIOCSIWENCODEEXT: -+ /* Set Encryption Material after 4-way handshaking is done */ -+ if (prIwReq->u.encoding.pointer) { -+ u4ExtraSize = prIwReq->u.encoding.length; -+ prExtraBuf = kalMemAlloc(u4ExtraSize, VIR_MEM_TYPE); -+ -+ if (!prExtraBuf) { -+ ret = -ENOMEM; -+ break; -+ } -+ -+ if (copy_from_user(prExtraBuf, prIwReq->u.encoding.pointer, prIwReq->u.encoding.length)) -+ ret = -EFAULT; -+ } else if (prIwReq->u.encoding.length != 0) { -+ ret = -EINVAL; -+ break; -+ } -+ -+ if (ret == 0) -+ ret = mtk_p2p_wext_set_key(prDev, &rIwReqInfo, &(prIwReq->u), prExtraBuf); -+ -+ kalMemFree(prExtraBuf, VIR_MEM_TYPE, u4ExtraSize); -+ prExtraBuf = NULL; -+ break; -+ -+ case SIOCSIWMLME: -+ /* IW_MLME_DISASSOC used for disconnection */ -+ if (prIwReq->u.data.length != sizeof(struct iw_mlme)) { -+ DBGLOG(P2P, WARN, "MLME buffer strange:%d\n", prIwReq->u.data.length); -+ ret = -EINVAL; -+ break; -+ } -+ -+ if (!prIwReq->u.data.pointer) { -+ ret = -EINVAL; -+ break; -+ } -+ -+ prExtraBuf = kalMemAlloc(sizeof(struct iw_mlme), VIR_MEM_TYPE); -+ if (!prExtraBuf) { -+ ret = -ENOMEM; -+ break; -+ } -+ -+ if (copy_from_user(prExtraBuf, prIwReq->u.data.pointer, sizeof(struct iw_mlme))) -+ ret = -EFAULT; -+ else -+ ret = mtk_p2p_wext_mlme_handler(prDev, &rIwReqInfo, &(prIwReq->u), prExtraBuf); -+ -+ kalMemFree(prExtraBuf, VIR_MEM_TYPE, sizeof(struct iw_mlme)); -+ prExtraBuf = NULL; -+ break; -+ -+ case SIOCGIWPRIV: -+ /* This ioctl is used to list all IW privilege ioctls */ -+ ret = mtk_p2p_wext_get_priv(prDev, &rIwReqInfo, &(prIwReq->u), NULL); -+ break; -+ -+ case SIOCGIWSCAN: -+ ret = mtk_p2p_wext_discovery_results(prDev, &rIwReqInfo, &(prIwReq->u), NULL); -+ break; -+ -+ case SIOCSIWAUTH: -+ ret = mtk_p2p_wext_set_auth(prDev, &rIwReqInfo, &(prIwReq->u), NULL); -+ break; -+ -+ case IOC_P2P_CFG_DEVICE: -+ case IOC_P2P_PROVISION_COMPLETE: -+ case IOC_P2P_START_STOP_DISCOVERY: -+ case IOC_P2P_DISCOVERY_RESULTS: -+ case IOC_P2P_WSC_BEACON_PROBE_RSP_IE: -+ case IOC_P2P_CONNECT_DISCONNECT: -+ case IOC_P2P_PASSWORD_READY: -+ case IOC_P2P_GET_STRUCT: -+ case IOC_P2P_SET_STRUCT: -+ case IOC_P2P_GET_REQ_DEVICE_INFO: -+ ret = -+ rP2PIwPrivHandler[i4Cmd - SIOCIWFIRSTPRIV] (prDev, &rIwReqInfo, &(prIwReq->u), -+ (char *)&(prIwReq->u)); -+ break; -+#if CFG_SUPPORT_P2P_RSSI_QUERY -+ case SIOCGIWSTATS: -+ ret = mtk_p2p_wext_get_rssi(prDev, &rIwReqInfo, &(prIwReq->u), NULL); -+ break; -+#endif -+ case IOC_GET_PRIVATE_IOCTL_CMD: -+ ret = priv_support_driver_cmd(prDev, prIfReq, i4Cmd); -+ -+ break; -+ default: -+ ret = -ENOTTY; -+ } -+ -+ return ret; -+} /* end of p2pDoIOCTL() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * \brief To report the iw private args table to user space. -+ * -+ * \param[in] prDev Net device requested. -+ * \param[in] info Pointer to iw_request_info. -+ * \param[inout] wrqu Pointer to iwreq_data. -+ * \param[inout] extra -+ * -+ * \retval 0 For success. -+ * \retval -E2BIG For user's buffer size is too small. -+ * \retval -EFAULT For fail. -+ * -+ */ -+/*----------------------------------------------------------------------------*/ -+int -+mtk_p2p_wext_get_priv(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) -+{ -+ struct iw_point *prData = (struct iw_point *)&wrqu->data; -+ UINT_16 u2BufferSize = prData->length; -+ -+ /* Update our private args table size */ -+ prData->length = (__u16)sizeof(rP2PIwPrivTable); -+ if (u2BufferSize < prData->length) -+ return -E2BIG; -+ -+ if (prData->length) { -+ if (copy_to_user(prData->pointer, rP2PIwPrivTable, sizeof(rP2PIwPrivTable))) -+ return -EFAULT; -+ } -+ -+ return 0; -+} /* end of mtk_p2p_wext_get_priv() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * \brief To indicate P2P-FSM for re-associate to the connecting device -+ * -+ * \param[in] prDev Net device requested. -+ * \param[inout] wrqu Pointer to iwreq_data -+ * -+ * \retval 0 For success. -+ * \retval -EFAULT For fail. -+ * -+ */ -+/*----------------------------------------------------------------------------*/ -+int -+mtk_p2p_wext_reconnect(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) -+{ -+#if 0 -+ P_ADAPTER_T prAdapter = NULL; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ P_MSG_HDR_T prMsgHdr; -+ -+ ASSERT(prDev); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ ASSERT(prGlueInfo); -+ -+ prAdapter = prGlueInfo->prAdapter; -+ ASSERT(prAdapter); -+ -+ prMsgHdr = (P_MSG_HDR_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_HDR_T)); -+ if (!prMsgHdr) { -+ ASSERT(0); /* Can't trigger P2P FSM */ -+ return -ENOMEM; -+ } -+ -+ /* 1.2 fill message */ -+ -+ DBGLOG(P2P, TRACE, "mtk_p2p_wext_reconnect: P2P Reconnect\n"); -+ -+ /* 1.3 send message */ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgHdr, MSG_SEND_METHOD_BUF); -+#endif -+ return 0; -+} /* end of mtk_p2p_wext_reconnect() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief MLME command handler -+* -+* \param[in] prDev Net device requested. -+* \param[inout] wrqu Pointer to iwreq_data -+* -+* \retval 0 Success. -+* \retval -EFAULT Setting parameters to driver fail. -+* \retval -EOPNOTSUPP Key size not supported. -+* -+* \note -+*/ -+/*----------------------------------------------------------------------------*/ -+int -+mtk_p2p_wext_mlme_handler(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) -+{ -+#if 0 -+ P_ADAPTER_T prAdapter = NULL; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ struct iw_mlme *mlme = (struct iw_mlme *)extra; -+ P_MSG_P2P_CONNECTION_ABORT_T prMsgP2PConnAbt = (P_MSG_P2P_CONNECTION_ABORT_T) NULL; -+ P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL; -+ -+ ASSERT(prDev); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ ASSERT(prGlueInfo); -+ -+ prAdapter = prGlueInfo->prAdapter; -+ ASSERT(prAdapter); -+ -+ prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); -+ -+ DBGLOG(P2P, TRACE, "mtk_p2p_wext_mlme_handler:\n"); -+ -+ switch (mlme->cmd) { -+ case IW_MLME_DISASSOC: -+ prMsgP2PConnAbt = -+ (P_MSG_HDR_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_P2P_CONNECTION_ABORT_T)); -+ if (!prMsgP2PConnAbt) { -+ ASSERT(0); /* Can't trigger P2P FSM */ -+ return -ENOMEM; -+ } -+ -+ COPY_MAC_ADDR(prMsgP2PConnAbt->aucTargetID, mlme->addr.sa_data); -+ -+ prMsgP2PConnAbt->u2ReasonCode = mlme->reason_code; -+ -+ if (EQUAL_MAC_ADDR(prMsgP2PConnAbt->aucTargetID, prP2pBssInfo->aucOwnMacAddr)) { -+ DBGLOG(P2P, TRACE, "P2P Connection Abort:\n"); -+ -+ /* 1.2 fill message */ -+ prMsgP2PConnAbt->rMsgHdr.eMsgId = MID_MNY_P2P_CONNECTION_ABORT; -+ } else { -+ DBGLOG(P2P, TRACE, "P2P Connection Pause:\n"); -+ -+ /* 1.2 fill message */ -+ } -+ -+ /* 1.3 send message */ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgP2PConnAbt, MSG_SEND_METHOD_BUF); -+ -+ break; -+ -+ default: -+ return -EOPNOTSUPP; -+ } -+#endif -+ return 0; -+} /* end of mtk_p2p_wext_mlme_handler() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief P2P Private I/O Control handler (IOC_P2P_PROVISION_COMPLETE) -+* -+* \param[in] prDev Net device requested. -+* \param[inout] wrqu Pointer to iwreq_data -+* -+* \retval 0 Success. -+* \retval -EFAULT Setting parameters to driver fail. -+* \retval -EOPNOTSUPP Key size not supported. -+* -+* \note -+*/ -+/*----------------------------------------------------------------------------*/ -+int -+mtk_p2p_wext_set_provision_complete(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) -+{ -+#if 0 -+ P_ADAPTER_T prAdapter = NULL; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ struct iw_point *prData = (struct iw_point *)&wrqu->data; -+ P_MSG_HDR_T prMsgHdr; -+ -+ ASSERT(prDev); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ ASSERT(prGlueInfo); -+ -+ prAdapter = prGlueInfo->prAdapter; -+ ASSERT(prAdapter); -+ -+ switch (prData->flags) { -+ case P2P_PROVISIONING_SUCCESS: -+ prMsgHdr = (P_MSG_HDR_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_HDR_T)); -+ if (!prMsgHdr) { -+ ASSERT(0); /* Can't trigger P2P FSM */ -+ return -ENOMEM; -+ } -+ -+ /* 1.2 fill message */ -+ -+ prGlueInfo->prP2PInfo->u4CipherPairwise = IW_AUTH_CIPHER_CCMP; -+ -+ /* 1.3 send message */ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgHdr, MSG_SEND_METHOD_BUF); -+ -+ break; -+ -+ case P2P_PROVISIONING_FAIL: -+ -+ break; -+ -+ default: -+ return -EOPNOTSUPP; -+ } -+#endif -+ -+ return 0; -+} /* end of mtk_p2p_wext_set_provision_complete() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief P2P Private I/O Control handler (IOC_P2P_START_STOP_DISCOVERY) -+* -+* \param[in] prDev Net device requested. -+* \param[inout] wrqu Pointer to iwreq_data -+* -+* \retval 0 Success. -+* \retval -EFAULT Setting parameters to driver fail. -+* \retval -EOPNOTSUPP Key size not supported. -+* -+* \note -+*/ -+/*----------------------------------------------------------------------------*/ -+int -+mtk_p2p_wext_start_stop_discovery(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) -+{ -+#if 0 -+ P_ADAPTER_T prAdapter = NULL; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ struct iw_point *prData = (struct iw_point *)&wrqu->data; -+ P_IW_P2P_REQ_DEVICE_TYPE prReqDeviceType = (P_IW_P2P_REQ_DEVICE_TYPE) extra; -+ UINT_8 au4IeBuf[MAX_IE_LENGTH]; -+ P_MSG_HDR_T prMsgHdr; -+ P_MSG_P2P_DEVICE_DISCOVER_T prDiscoverMsg; -+ P_P2P_CONNECTION_SETTINGS_T prConnSettings; -+ UINT_8 aucNullAddr[] = NULL_MAC_ADDR; -+ -+ ASSERT(prDev); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ ASSERT(prGlueInfo); -+ -+ prAdapter = prGlueInfo->prAdapter; -+ ASSERT(prAdapter); -+ -+ prConnSettings = prAdapter->rWifiVar.prP2PConnSettings; -+ -+ if (prData->flags == P2P_STOP_DISCOVERY) { -+ prMsgHdr = (P_MSG_HDR_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_HDR_T)); -+ -+ if (!prMsgHdr) { -+ ASSERT(0); /* Can't trigger P2P FSM */ -+ return -ENOMEM; -+ } -+ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgHdr, MSG_SEND_METHOD_BUF); -+ } else if (prData->flags == P2P_START_DISCOVERY) { -+ -+ /* retrieve IE for Probe Response */ -+ if (prReqDeviceType->probe_rsp_len > 0) { -+ if (prReqDeviceType->probe_rsp_len <= MAX_IE_LENGTH) { -+ if (copy_from_user -+ (prGlueInfo->prP2PInfo->aucWSCIE[2], prReqDeviceType->probe_rsp_ie, -+ prReqDeviceType->probe_rsp_len)) { -+ return -EFAULT; -+ } -+ prGlueInfo->prP2PInfo->u2WSCIELen[2] = prReqDeviceType->probe_rsp_len; -+ } else { -+ return -E2BIG; -+ } -+ } -+ -+ /* retrieve IE for Probe Request */ -+ if (prReqDeviceType->probe_req_len > 0) { -+ if (prReqDeviceType->probe_req_len <= MAX_IE_LENGTH) { -+ if (copy_from_user -+ (prGlueInfo->prP2PInfo->aucWSCIE[1], prReqDeviceType->probe_req_ie, -+ prReqDeviceType->probe_req_len)) { -+ return -EFAULT; -+ } -+ prGlueInfo->prP2PInfo->u2WSCIELen[1] = prReqDeviceType->probe_req_len; -+ } else { -+ return -E2BIG; -+ } -+ } -+ /* update IE for Probe Request */ -+ -+ if (prReqDeviceType->scan_type == P2P_LISTEN) { -+ /* update listening parameter */ -+ -+ /* @TODO: update prConnSettings for Probe Response IE */ -+ } else { -+ /* indicate P2P-FSM with MID_MNY_P2P_DEVICE_DISCOVERY */ -+ prDiscoverMsg = (P_MSG_P2P_DEVICE_DISCOVER_T) cnmMemAlloc(prAdapter, -+ RAM_TYPE_MSG, -+ sizeof(MSG_P2P_DEVICE_DISCOVER_T)); -+ -+ if (!prDiscoverMsg) { -+ ASSERT(0); /* Can't trigger P2P FSM */ -+ return -ENOMEM; -+ } -+ -+ prDiscoverMsg->rMsgHdr.eMsgId = MID_MNY_P2P_DEVICE_DISCOVERY; -+ prDiscoverMsg->u4DevDiscoverTime = 0; /* unlimited */ -+ prDiscoverMsg->fgIsSpecificType = TRUE; -+ prDiscoverMsg->rTargetDeviceType.u2CategoryID = -+ *(PUINT_16) (&(prReqDeviceType->pri_device_type[0])); -+ prDiscoverMsg->rTargetDeviceType.u2SubCategoryID = -+ *(PUINT_16) (&(prReqDeviceType->pri_device_type[6])); -+ COPY_MAC_ADDR(prDiscoverMsg->aucTargetDeviceID, aucNullAddr); -+ -+ /* @FIXME: parameter to be refined, where to pass IE buffer ? */ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prDiscoverMsg, MSG_SEND_METHOD_BUF); -+ } -+ } else { -+ return -EINVAL; -+ } -+#endif -+ -+ return 0; -+} /* end of mtk_p2p_wext_start_stop_discovery() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief P2P Private I/O Control handler (IOC_P2P_SET_INT) -+* -+* \param[in] prDev Net device requested. -+* \param[inout] wrqu Pointer to iwreq_data -+* -+* \retval 0 Success. -+* \retval -EFAULT Setting parameters to driver fail. -+* \retval -EOPNOTSUPP Setting parameters not support. -+* -+* \note -+*/ -+/*----------------------------------------------------------------------------*/ -+int -+mtk_p2p_wext_invitation_request(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) -+{ -+ int i4Status = 0; -+#if 0 -+ P_ADAPTER_T prAdapter = (P_ADAPTER_T) NULL; -+ P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) NULL; -+ struct iw_point *prData = (struct iw_point *)&wrqu->data; -+ P_IW_P2P_IOCTL_INVITATION_STRUCT prIoctlInvitation = (P_IW_P2P_IOCTL_INVITATION_STRUCT) NULL; -+ -+ do { -+ if ((prDev == NULL) || (extra == NULL)) { -+ ASSERT(FALSE); -+ i4Status = -EINVAL; -+ break; -+ } -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ prIoctlInvitation = (P_IW_P2P_IOCTL_INVITATION_STRUCT) extra; -+ -+ if (prGlueInfo == NULL) { -+ i4Status = -EINVAL; -+ break; -+ } -+ -+ prAdapter = prGlueInfo->prAdapter; -+ -+ if (prAdapter == NULL) { -+ i4Status = -EINVAL; -+ break; -+ } -+ -+ if (prIoctlInvitation->ucReinvoke == 1) { -+ /* TODO: Set Group ID */ -+ p2pFuncSetGroupID(prAdapter, prIoctlInvitation->aucGroupID, prIoctlInvitation->aucSsid, -+ prIoctlInvitation->u4SsidLen); -+ } -+ -+ else { -+ P_MSG_P2P_INVITATION_REQUEST_T prMsgP2PInvitationReq = (P_MSG_P2P_INVITATION_REQUEST_T) NULL; -+ -+ /* TODO: Do Invitation. */ -+ prMsgP2PInvitationReq = -+ (P_MSG_P2P_INVITATION_REQUEST_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, -+ sizeof(MSG_P2P_INVITATION_REQUEST_T)); -+ if (!prMsgP2PInvitationReq) { -+ ASSERT(0); /* Can't trigger P2P FSM */ -+ i4Status = -ENOMEM; -+ break; -+ } -+ -+ /* 1.2 fill message */ -+ kalMemCopy(prMsgP2PInvitationReq->aucDeviceID, prIoctlInvitation->aucDeviceID, MAC_ADDR_LEN); -+ -+ DBGLOG(P2P, TRACE, "mtk_p2p_wext_invitation_request: P2P Invitation Req\n"); -+ -+ /* 1.3 send message */ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgP2PInvitationReq, MSG_SEND_METHOD_BUF); -+ -+ } -+ -+ } while (FALSE); -+#endif -+ -+ return i4Status; -+ -+} -+ -+/* mtk_p2p_wext_invitation_request */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief P2P Private I/O Control handler (IOC_P2P_SET_INT) -+* -+* \param[in] prDev Net device requested. -+* \param[inout] wrqu Pointer to iwreq_data -+* -+* \retval 0 Success. -+* \retval -EFAULT Setting parameters to driver fail. -+* \retval -EOPNOTSUPP Setting parameters not support. -+* -+* \note -+*/ -+/*----------------------------------------------------------------------------*/ -+int -+mtk_p2p_wext_invitation_abort(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) -+{ -+ int i4Status = 0; -+#if 0 -+ P_ADAPTER_T prAdapter = (P_ADAPTER_T) NULL; -+ P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) NULL; -+ struct iw_point *prData = (struct iw_point *)&wrqu->data; -+ P_IW_P2P_IOCTL_ABORT_INVITATION prIoctlInvitationAbort = (P_IW_P2P_IOCTL_ABORT_INVITATION) NULL; -+ -+ UINT_8 bssid[MAC_ADDR_LEN]; -+ -+ do { -+ if ((prDev == NULL) || (extra == NULL)) { -+ ASSERT(FALSE); -+ i4Status = -EINVAL; -+ break; -+ } -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ prIoctlInvitationAbort = (P_IW_P2P_IOCTL_ABORT_INVITATION) extra; -+ -+ if (prGlueInfo == NULL) { -+ i4Status = -EINVAL; -+ break; -+ } -+ -+ prAdapter = prGlueInfo->prAdapter; -+ -+ if (prAdapter == NULL) { -+ i4Status = -EINVAL; -+ break; -+ } -+ P_MSG_P2P_INVITATION_REQUEST_T prMsgP2PInvitationAbort = (P_MSG_P2P_INVITATION_REQUEST_T) NULL; -+ -+ prMsgP2PInvitationAbort = -+ (P_MSG_P2P_INVITATION_REQUEST_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, -+ sizeof(MSG_P2P_INVITATION_REQUEST_T)); -+ -+ if (!prMsgP2PInvitationAbort) { -+ ASSERT(0); /* Can't trigger P2P FSM */ -+ i4Status = -ENOMEM; -+ break; -+ } -+ -+ /* 1.2 fill message */ -+ kalMemCopy(prMsgP2PInvitationAbort->aucDeviceID, prIoctlInvitationAbort->dev_addr, -+ MAC_ADDR_LEN); -+ -+ DBGLOG(P2P, TRACE, "mtk_p2p_wext_invitation_request: P2P Invitation Req\n"); -+ -+ /* 1.3 send message */ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgP2PInvitationAbort, MSG_SEND_METHOD_BUF); -+ -+ -+ } while (FALSE); -+#endif -+ -+ return i4Status; -+ -+} -+ -+/* mtk_p2p_wext_invitation_abort */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * \brief To override p2p interface address -+ * -+ * \param[in] prDev Net device requested. -+ * \param[in] addr Pointer to address -+ * -+ * \retval 0 For success. -+ * \retval -E2BIG For user's buffer size is too small. -+ * \retval -EFAULT For fail. -+ * -+ */ -+/*----------------------------------------------------------------------------*/ -+int p2pSetMACAddress(IN struct net_device *prDev, void *addr) -+{ -+ P_ADAPTER_T prAdapter = NULL; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ -+ ASSERT(prDev); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ ASSERT(prGlueInfo); -+ -+ prAdapter = prGlueInfo->prAdapter; -+ ASSERT(prAdapter); -+ -+ /* @FIXME */ -+ return eth_mac_addr(prDev, addr); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief To set encryption cipher suite -+* -+* \param[in] prDev Net device requested. -+* \param[out] -+* -+* \retval 0 Success. -+* \retval -EINVAL Invalid parameter -+* \retval -EOPNOTSUPP Key size not supported. -+* -+* \note -+*/ -+/*----------------------------------------------------------------------------*/ -+int -+mtk_p2p_wext_set_auth(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ struct iw_param *prAuth = (struct iw_param *)wrqu; -+ -+ ASSERT(prDev); -+ ASSERT(prAuth); -+ if (FALSE == GLUE_CHK_PR2(prDev, prAuth)) -+ return -EINVAL; -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ -+ /* Save information to glue info and process later when ssid is set. */ -+ switch (prAuth->flags & IW_AUTH_INDEX) { -+ case IW_AUTH_WPA_VERSION: -+ break; -+ case IW_AUTH_CIPHER_PAIRWISE: -+ prGlueInfo->prP2PInfo->u4CipherPairwise = prAuth->value; -+ break; -+ case IW_AUTH_CIPHER_GROUP: -+ case IW_AUTH_KEY_MGMT: -+ case IW_AUTH_TKIP_COUNTERMEASURES: -+ case IW_AUTH_DROP_UNENCRYPTED: -+ case IW_AUTH_80211_AUTH_ALG: -+ case IW_AUTH_WPA_ENABLED: -+ case IW_AUTH_RX_UNENCRYPTED_EAPOL: -+ case IW_AUTH_ROAMING_CONTROL: -+ case IW_AUTH_PRIVACY_INVOKED: -+ default: -+ /* @TODO */ -+ break; -+ } -+ -+ return 0; -+} /* end of mtk_p2p_wext_set_auth() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief To set encryption cipher and key. -+* -+* \param[in] prDev Net device requested. -+* \param[out] prIfReq Pointer to ifreq structure, content is copied back to -+* user space buffer in gl_iwpriv_table. -+* -+* \retval 0 Success. -+* \retval -EFAULT Setting parameters to driver fail. -+* \retval -EOPNOTSUPP Key size not supported. -+* -+* \note Securiry information is stored in pEnc. -+*/ -+/*----------------------------------------------------------------------------*/ -+int -+mtk_p2p_wext_set_key(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) -+{ -+ int ret = 0; -+ struct iw_encode_ext *prIWEncExt; -+ struct iw_point *prEnc; -+ char *prExtraBuf = NULL; -+ UINT_32 u4ExtraSize = 0; -+ UINT_8 keyStructBuf[100]; -+ P_PARAM_REMOVE_KEY_T prRemoveKey = (P_PARAM_REMOVE_KEY_T) keyStructBuf; -+ P_PARAM_KEY_T prKey = (P_PARAM_KEY_T) keyStructBuf; -+ P_GLUE_INFO_T prGlueInfo; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ UINT_32 u4BufLen = 0; -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ -+ do { -+ if (wrqu->encoding.pointer) { -+ u4ExtraSize = wrqu->encoding.length; -+ /*need confirm u4ExtraSize > 0 but is not very large*/ -+ prExtraBuf = kalMemAlloc(u4ExtraSize, VIR_MEM_TYPE); -+ -+ if (!prExtraBuf) { -+ ret = -ENOMEM; -+ break; -+ } -+ /* here should set prExtraBuf default value */ -+ memset(prExtraBuf, 0, u4ExtraSize); -+ if (copy_from_user(prExtraBuf, wrqu->encoding.pointer, wrqu->encoding.length)) { -+ ret = -EFAULT; -+ break; -+ } -+ } else if (wrqu->encoding.length != 0) { -+ ret = -EINVAL; -+ break; -+ } -+ -+ prEnc = &wrqu->encoding; -+ /* here, need confirm (struct iw_encode_ext) < u4ExtraSize */ -+ prIWEncExt = (struct iw_encode_ext *)prExtraBuf; -+ -+ if (GLUE_CHK_PR3(prDev, prEnc, prExtraBuf) != TRUE) { -+ ret = -EINVAL; -+ break; -+ } -+ -+ memset(keyStructBuf, 0, sizeof(keyStructBuf)); -+ -+ if ((prEnc->flags & IW_ENCODE_MODE) == IW_ENCODE_DISABLED) { /* Key Removal */ -+ prRemoveKey->u4Length = sizeof(*prRemoveKey); -+ memcpy(prRemoveKey->arBSSID, prIWEncExt->addr.sa_data, 6); -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetRemoveP2PKey, -+ prRemoveKey, -+ prRemoveKey->u4Length, FALSE, FALSE, TRUE, TRUE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) -+ ret = -EFAULT; -+ } else { -+ if (prIWEncExt->alg == IW_ENCODE_ALG_CCMP) { -+ /* KeyID */ -+ prKey->u4KeyIndex = (prEnc->flags & IW_ENCODE_INDEX) ? -+ ((prEnc->flags & IW_ENCODE_INDEX) - 1) : 0; -+ if (prKey->u4KeyIndex <= 3) { -+ /* bit(31) and bit(30) are shared by pKey and pRemoveKey */ -+ /* Tx Key Bit(31) */ -+ if (prIWEncExt->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) -+ prKey->u4KeyIndex |= 0x1UL << 31; -+ -+ /* Pairwise Key Bit(30) */ -+ if (prIWEncExt->ext_flags & IW_ENCODE_EXT_GROUP_KEY) { -+ /* group key */ -+ } else { -+ /* pairwise key */ -+ prKey->u4KeyIndex |= 0x1UL << 30; -+ } -+ -+ /* Rx SC Bit(29) */ -+ if (prIWEncExt->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID) { -+ prKey->u4KeyIndex |= 0x1UL << 29; -+ memcpy(&prKey->rKeyRSC, prIWEncExt->rx_seq, -+ IW_ENCODE_SEQ_MAX_SIZE); -+ } -+ -+ /* BSSID */ -+ memcpy(prKey->arBSSID, prIWEncExt->addr.sa_data, 6); -+ memcpy(prKey->aucKeyMaterial, prIWEncExt->key, prIWEncExt->key_len); -+ -+ prKey->u4KeyLength = prIWEncExt->key_len; -+ prKey->u4Length = -+ ((ULONG)&(((P_PARAM_KEY_T) 0)->aucKeyMaterial)) + -+ prKey->u4KeyLength; -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetAddP2PKey, -+ prKey, -+ prKey->u4Length, -+ FALSE, FALSE, TRUE, TRUE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) -+ ret = -EFAULT; -+ } else { -+ ret = -EINVAL; -+ } -+ } else { -+ ret = -EINVAL; -+ } -+ } -+ -+ } while (FALSE); -+ -+ if (prExtraBuf) { -+ kalMemFree(prExtraBuf, VIR_MEM_TYPE, u4ExtraSize); -+ prExtraBuf = NULL; -+ } -+ -+ return ret; -+} /* end of mtk_p2p_wext_set_key() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief set the p2p gc power mode -+* -+* \param[in] prDev Net device requested. -+* \param[inout] wrqu Pointer to iwreq_data -+* -+* \retval 0 Success. -+* \retval -EFAULT Setting parameters to driver fail. -+* \retval -EOPNOTSUPP Key size not supported. -+* -+* \note -+*/ -+/*----------------------------------------------------------------------------*/ -+int -+mtk_p2p_wext_set_powermode(IN struct net_device *prNetDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) -+{ -+ /* printk("set_powermode = %d, value = %d\n", wrqu->power.disabled, wrqu->power.value); */ -+ struct iw_param *prPower = (struct iw_param *)&wrqu->power; -+#if 1 -+ PARAM_POWER_MODE ePowerMode; -+ INT_32 i4PowerValue; -+ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ UINT_32 u4BufLen = 0; -+ -+ ASSERT(prNetDev); -+ ASSERT(prPower); -+ if (FALSE == GLUE_CHK_PR2(prNetDev, prPower)) -+ return -EINVAL; -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); -+ -+ /* printk(KERN_INFO "wext_set_power value(%d) disabled(%d) flag(0x%x)\n", */ -+ /* prPower->value, prPower->disabled, prPower->flags); */ -+ -+ if (prPower->disabled) { -+ ePowerMode = Param_PowerModeCAM; -+ } else { -+ i4PowerValue = prPower->value; -+#if WIRELESS_EXT < 21 -+ i4PowerValue /= 1000000; -+#endif -+ if (i4PowerValue == 0) { -+ ePowerMode = Param_PowerModeCAM; -+ } else if (i4PowerValue == 1) { -+ ePowerMode = Param_PowerModeMAX_PSP; -+ } else if (i4PowerValue == 2) { -+ ePowerMode = Param_PowerModeFast_PSP; -+ } else { -+ DBGLOG(P2P, ERROR, "%s(): unsupported power management mode value = %d.\n", -+ __func__, prPower->value); -+ -+ return -EINVAL; -+ } -+ } -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetP2pPowerSaveProfile, -+ &ePowerMode, sizeof(ePowerMode), FALSE, FALSE, TRUE, TRUE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ /* printk(KERN_INFO DRV_NAME"wlanoidSet802dot11PowerSaveProfile fail 0x%lx\n", rStatus); */ -+ return -EFAULT; -+ } -+#endif -+ -+ return 0; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief get the p2p gc power mode -+* -+* \param[in] prDev Net device requested. -+* \param[inout] wrqu Pointer to iwreq_data -+* -+* \retval 0 Success. -+* \retval -EFAULT Setting parameters to driver fail. -+* \retval -EOPNOTSUPP Key size not supported. -+* -+* \note -+*/ -+/*----------------------------------------------------------------------------*/ -+int -+mtk_p2p_wext_get_powermode(IN struct net_device *prNetDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) -+{ -+ /* printk("mtk_p2p_wext_get_powermode\n"); */ -+ /* wrqu->power.disabled = 0; */ -+ /* wrqu->power.value = 1; */ -+ -+ struct iw_param *prPower = (struct iw_param *)&wrqu->power; -+ PARAM_POWER_MODE ePowerMode = Param_PowerModeMax; -+ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ UINT_32 u4BufLen = 0; -+ -+ ASSERT(prNetDev); -+ ASSERT(prPower); -+ if (FALSE == GLUE_CHK_PR2(prNetDev, prPower)) -+ return -EINVAL; -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); -+ ASSERT(prGlueInfo); -+ -+#if 1 -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidQueryP2pPowerSaveProfile, -+ &ePowerMode, sizeof(ePowerMode), TRUE, FALSE, FALSE, TRUE, &u4BufLen); -+#else -+ rStatus = wlanQueryInformation(prGlueInfo->prAdapter, -+ wlanoidQueryP2pPowerSaveProfile, &ePowerMode, sizeof(ePowerMode), &u4BufLen); -+#endif -+ -+ prPower->value = 0; -+ prPower->disabled = 1; -+ -+ if (Param_PowerModeCAM == ePowerMode) { -+ prPower->value = 0; -+ prPower->disabled = 1; -+ } else if (Param_PowerModeMAX_PSP == ePowerMode) { -+ prPower->value = 1; -+ prPower->disabled = 0; -+ } else if (Param_PowerModeFast_PSP == ePowerMode) { -+ prPower->value = 2; -+ prPower->disabled = 0; -+ } -+ -+ prPower->flags = IW_POWER_PERIOD | IW_POWER_RELATIVE; -+#if WIRELESS_EXT < 21 -+ prPower->value *= 1000000; -+#endif -+ -+ return 0; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief P2P Private I/O Control handler (IOC_P2P_CFG_DEVICE) -+* -+* \param[in] prDev Net device requested. -+* \param[inout] wrqu Pointer to iwreq_data -+* -+* \retval 0 Success. -+* \retval -EFAULT Setting parameters to driver fail. -+* \retval -EOPNOTSUPP Key size not supported. -+* -+* \note -+*/ -+/*----------------------------------------------------------------------------*/ -+int -+mtk_p2p_wext_set_local_dev_info(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) -+{ -+ P_ADAPTER_T prAdapter = NULL; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ P_IW_P2P_CFG_DEVICE_TYPE prDeviceCfg = (P_IW_P2P_CFG_DEVICE_TYPE) extra; -+ P_P2P_CONNECTION_SETTINGS_T prConnSettings; -+ P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo = (P_P2P_SPECIFIC_BSS_INFO_T) NULL; -+ /* P_MSG_P2P_FUNCTION_SWITCH_T prFuncSwitch = (P_MSG_P2P_FUNCTION_SWITCH_T)NULL; */ -+ -+ ASSERT(prDev); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ ASSERT(prGlueInfo); -+ -+ prAdapter = prGlueInfo->prAdapter; -+ ASSERT(prAdapter); -+ -+ prConnSettings = prAdapter->rWifiVar.prP2PConnSettings; -+ prP2pSpecificBssInfo = prAdapter->rWifiVar.prP2pSpecificBssInfo; -+ -+ /* update connection settings for P2P-FSM */ -+ /* 1. update SSID */ -+ if (prDeviceCfg->ssid_len > ELEM_MAX_LEN_SSID) -+ prConnSettings->ucSSIDLen = ELEM_MAX_LEN_SSID; -+ else -+ prConnSettings->ucSSIDLen = prDeviceCfg->ssid_len; -+ -+ if (copy_from_user(prConnSettings->aucSSID, prDeviceCfg->ssid, prConnSettings->ucSSIDLen)) -+ return -EFAULT; -+ /* 2. update device type (WPS IE) */ -+ kalMemCopy(&(prConnSettings->rPrimaryDevTypeBE), &(prDeviceCfg->pri_device_type), sizeof(DEVICE_TYPE_T)); -+#if P2P_MAX_SUPPORTED_SEC_DEV_TYPE_COUNT -+ kalMemCopy(&(prConnSettings->arSecondaryDevTypeBE[0]), &(prDeviceCfg->snd_device_type), sizeof(DEVICE_TYPE_T)); -+#endif -+ -+ /* 3. update device name */ -+ if (prDeviceCfg->device_name_len > WPS_ATTRI_MAX_LEN_DEVICE_NAME) -+ prConnSettings->ucDevNameLen = WPS_ATTRI_MAX_LEN_DEVICE_NAME; -+ else -+ prConnSettings->ucDevNameLen = prDeviceCfg->device_name_len; -+ if (copy_from_user(prConnSettings->aucDevName, prDeviceCfg->device_name, prConnSettings->ucDevNameLen)) -+ return -EFAULT; -+ /* 4. update GO intent */ -+ prConnSettings->ucGoIntent = prDeviceCfg->intend; -+ -+ /* Preferred channel bandwidth */ -+ prAdapter->rWifiVar.rConnSettings.uc2G4BandwidthMode = prDeviceCfg->ch_width ? CONFIG_BW_20_40M : CONFIG_BW_20M; -+ prAdapter->rWifiVar.rConnSettings.uc5GBandwidthMode = prDeviceCfg->ch_width ? CONFIG_BW_20_40M : CONFIG_BW_20M; -+ -+#if 0 -+ /* 1. switch P2P-FSM on */ -+ /* 1.1 allocate for message */ -+ prFuncSwitch = (P_MSG_P2P_FUNCTION_SWITCH_T) cnmMemAlloc(prAdapter, -+ RAM_TYPE_MSG, sizeof(MSG_P2P_FUNCTION_SWITCH_T)); -+ -+ if (!prFuncSwitch) { -+ ASSERT(0); /* Can't trigger P2P FSM */ -+ return -ENOMEM; -+ } -+ -+ /* 1.2 fill message */ -+ prFuncSwitch->rMsgHdr.eMsgId = MID_MNY_P2P_FUN_SWITCH; -+ prFuncSwitch->fgIsFuncOn = TRUE; -+ -+ /* 1.3 send message */ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prFuncSwitch, MSG_SEND_METHOD_BUF); -+#endif -+ return 0; -+} /* end of mtk_p2p_wext_set_local_dev_info() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * \brief I/O Control handler for both -+ * IOC_P2P_START_STOP_DISCOVERY & SIOCGIWSCAN -+ * -+ * \param[in] prDev Net device requested. -+ * \param[inout] wrqu Pointer to iwreq_data -+ * -+ * \retval 0 Success. -+ * \retval -EFAULT Setting parameters to driver fail. -+ * \retval -EOPNOTSUPP Key size not supported. -+ * -+ * \note -+ */ -+/*----------------------------------------------------------------------------*/ -+int -+mtk_p2p_wext_discovery_results(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) -+{ -+ struct iw_event iwe; -+ char *current_ev = extra; -+ UINT_32 i; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ P_ADAPTER_T prAdapter = NULL; -+ P_P2P_INFO_T prP2PInfo = (P_P2P_INFO_T) NULL; -+ P_EVENT_P2P_DEV_DISCOVER_RESULT_T prTargetResult = (P_EVENT_P2P_DEV_DISCOVER_RESULT_T) NULL; -+ P_PARAM_VARIABLE_IE_T prDesiredIE = NULL; -+ -+ ASSERT(prDev); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ ASSERT(prGlueInfo); -+ -+ prAdapter = prGlueInfo->prAdapter; -+ ASSERT(prAdapter); -+ -+ prP2PInfo = prAdapter->prP2pInfo; -+ -+ for (i = 0; i < prP2PInfo->u4DeviceNum; i++) { -+ prTargetResult = &prP2PInfo->arP2pDiscoverResult[i]; -+ -+ /* SIOCGIWAP */ -+ iwe.cmd = SIOCGIWAP; -+ iwe.u.ap_addr.sa_family = ARPHRD_ETHER; -+ memcpy(iwe.u.ap_addr.sa_data, prTargetResult->aucInterfaceAddr, 6); -+ -+ current_ev = iwe_stream_add_event(info, current_ev, extra + IW_SCAN_MAX_DATA, &iwe, IW_EV_ADDR_LEN); -+ -+ /* SIOCGIWESSID */ -+ iwe.cmd = SIOCGIWESSID; -+ iwe.u.data.flags = 1; -+ iwe.u.data.length = prTargetResult->u2NameLength; -+ -+ current_ev = iwe_stream_add_point(info, current_ev, -+ extra + IW_SCAN_MAX_DATA, &iwe, prTargetResult->aucName); -+ -+ /* IWEVGENIE for WPA IE */ -+ if (prTargetResult->u2IELength <= 600 && wextSrchDesiredWPAIE(prTargetResult->pucIeBuf, -+ prTargetResult->u2IELength, -+ 0xDD, (PUINT_8 *) &prDesiredIE)) { -+ -+ iwe.cmd = IWEVGENIE; -+ iwe.u.data.flags = 1; -+ iwe.u.data.length = 2 + (__u16) prDesiredIE->ucLength; -+ -+ current_ev = iwe_stream_add_point(info, current_ev, -+ extra + IW_SCAN_MAX_DATA, &iwe, (char *)prDesiredIE); -+ } -+#if CFG_SUPPORT_WPS -+ -+ /* IWEVGENIE for WPS IE */ -+ if ((prTargetResult->u2IELength <= 600) && wextSrchDesiredWPSIE(prTargetResult->pucIeBuf, -+ prTargetResult->u2IELength, -+ 0xDD, (PUINT_8 *) &prDesiredIE)) { -+ -+ iwe.cmd = IWEVGENIE; -+ iwe.u.data.flags = 1; -+ iwe.u.data.length = 2 + (__u16) prDesiredIE->ucLength; -+ -+ current_ev = iwe_stream_add_point(info, current_ev, -+ extra + IW_SCAN_MAX_DATA, &iwe, (char *)prDesiredIE); -+ } -+#endif -+ -+ /* IWEVGENIE for RSN IE */ -+ if ((prTargetResult->u2IELength <= 600) && wextSrchDesiredWPAIE(prTargetResult->pucIeBuf, -+ prTargetResult->u2IELength, -+ 0x30, (PUINT_8 *) &prDesiredIE)) { -+ -+ iwe.cmd = IWEVGENIE; -+ iwe.u.data.flags = 1; -+ iwe.u.data.length = 2 + (__u16) prDesiredIE->ucLength; -+ -+ current_ev = iwe_stream_add_point(info, current_ev, -+ extra + IW_SCAN_MAX_DATA, &iwe, (char *)prDesiredIE); -+ } -+ -+ /* IOC_P2P_GO_WSC_IE */ -+#if 1 -+ /* device capability */ -+ if (1) { -+ UINT_8 data[40]; -+ -+ iwe.cmd = IWEVCUSTOM; -+ iwe.u.data.flags = 0; -+ iwe.u.data.length = 9 + sizeof("p2p_cap="); -+ if (iwe.u.data.length > 40) -+ iwe.u.data.length = 40; -+ -+ snprintf(data, iwe.u.data.length, "p2p_cap=%02x%02x%02x%02x%c", -+ prTargetResult->ucDeviceCapabilityBitmap, prTargetResult->ucGroupCapabilityBitmap, -+ (UINT_8) prTargetResult->u2ConfigMethod, -+ (UINT_8) (prTargetResult->u2ConfigMethod >> 8), '\0'); -+ current_ev = -+ iwe_stream_add_point(info, current_ev, extra + IW_SCAN_MAX_DATA, &iwe, (char *)data); -+ -+ /* printk("%s\n", data); */ -+ kalMemZero(data, 40); -+ -+ iwe.cmd = IWEVCUSTOM; -+ iwe.u.data.flags = 0; -+ iwe.u.data.length = 13 + sizeof("p2p_dev_type="); -+ if (iwe.u.data.length > 40) -+ iwe.u.data.length = 40; -+ -+ snprintf(data, iwe.u.data.length, "p2p_dev_type=%02x%02x%02x%02x%02x%02x%c", -+ (UINT_8) prTargetResult->rPriDevType.u2CategoryID, -+ (UINT_8) prTargetResult->rPriDevType.u2SubCategoryID, -+ (UINT_8) prTargetResult->arSecDevType[0].u2CategoryID, -+ (UINT_8) prTargetResult->arSecDevType[0].u2SubCategoryID, -+ (UINT_8) prTargetResult->arSecDevType[1].u2CategoryID, -+ (UINT_8) prTargetResult->arSecDevType[1].u2SubCategoryID, '\0'); -+ current_ev = -+ iwe_stream_add_point(info, current_ev, extra + IW_SCAN_MAX_DATA, &iwe, (char *)data); -+ /* printk("%s\n", data); */ -+ -+ kalMemZero(data, 40); -+ -+ iwe.cmd = IWEVCUSTOM; -+ iwe.u.data.flags = 0; -+ iwe.u.data.length = 17 + sizeof("p2p_grp_bssid="); -+ if (iwe.u.data.length > 40) -+ iwe.u.data.length = 40; -+ -+ snprintf(data, iwe.u.data.length, "p2p_grp_bssid= %pM %c", -+ prTargetResult->aucBSSID, '\0'); -+ current_ev = iwe_stream_add_point(info, current_ev, -+ extra + IW_SCAN_MAX_DATA, &iwe, (char *)data); -+ /* printk("%s\n", data); */ -+ -+ } -+#endif -+ } -+ -+ /* Length of data */ -+ wrqu->data.length = (current_ev - extra); -+ wrqu->data.flags = 0; -+ -+ return 0; -+} /* end of mtk_p2p_wext_discovery_results() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief P2P Private I/O Control handler (IOC_P2P_WSC_BEACON_PROBE_RSP_IE) -+* -+* \param[in] prDev Net device requested. -+* \param[inout] wrqu Pointer to iwreq_data -+* -+* \retval 0 Success. -+* \retval -EFAULT Setting parameters to driver fail. -+* \retval -EOPNOTSUPP Key size not supported. -+* -+* \note -+*/ -+/*----------------------------------------------------------------------------*/ -+int -+mtk_p2p_wext_wsc_ie(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) -+{ -+ P_ADAPTER_T prAdapter = NULL; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ P_IW_P2P_HOSTAPD_PARAM prHostapdParam = (P_IW_P2P_HOSTAPD_PARAM) extra; -+ -+ ASSERT(prDev); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ ASSERT(prGlueInfo); -+ -+ if (prHostapdParam->len > 0) { -+ if (prHostapdParam->len <= MAX_WSC_IE_LENGTH) { -+ if (copy_from_user -+ (prGlueInfo->prP2PInfo->aucWSCIE[0], prHostapdParam->data, prHostapdParam->len)) { -+ return -EFAULT; -+ } -+ if (copy_from_user -+ (prGlueInfo->prP2PInfo->aucWSCIE[2], prHostapdParam->data, prHostapdParam->len)) { -+ return -EFAULT; -+ } -+ } else { -+ return -E2BIG; -+ } -+ } -+ -+ prGlueInfo->prP2PInfo->u2WSCIELen[0] = prHostapdParam->len; -+ prGlueInfo->prP2PInfo->u2WSCIELen[2] = prHostapdParam->len; -+ -+ prAdapter = prGlueInfo->prAdapter; -+ ASSERT(prAdapter); -+ -+ bssUpdateBeaconContent(prAdapter, NETWORK_TYPE_P2P_INDEX); -+ -+ /* @TODO: send message to P2P-FSM */ -+ -+ return 0; -+} /* end of mtk_p2p_wext_wsc_ie() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief P2P Private I/O Control handler (IOC_P2P_CONNECT_DISCONNECT) -+* -+* \param[in] prDev Net device requested. -+* \param[inout] wrqu Pointer to iwreq_data -+* -+* \retval 0 Success. -+* \retval -EFAULT Setting parameters to driver fail. -+* \retval -EOPNOTSUPP Key size not supported. -+* -+* \note -+*/ -+/*----------------------------------------------------------------------------*/ -+int -+mtk_p2p_wext_connect_disconnect(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) -+{ -+ P_ADAPTER_T prAdapter = NULL; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ struct iw_point *prData = (struct iw_point *)&wrqu->data; -+/* P_IW_P2P_CONNECT_DEVICE prConnectDevice = (P_IW_P2P_CONNECT_DEVICE)extra; */ -+/* P_MSG_HDR_T prMsgHdr; */ -+/* P_MSG_P2P_CONNECTION_REQUEST_T prMsgP2PConnReq; */ -+/* P_MSG_P2P_CONNECTION_ABORT_T prMsgP2PConnAbt; */ -+/* UINT_8 aucBCAddr[] = BC_MAC_ADDR; */ -+ -+ ASSERT(prDev); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ ASSERT(prGlueInfo); -+ -+ prAdapter = prGlueInfo->prAdapter; -+ ASSERT(prAdapter); -+ -+ if (prData->flags == P2P_CONNECT) { -+#if 0 -+ /* indicate P2P-FSM with MID_MNY_P2P_CONNECTION_REQ */ -+ prMsgP2PConnReq = (P_MSG_P2P_CONNECTION_REQUEST_T) cnmMemAlloc(prAdapter, -+ RAM_TYPE_MSG, -+ sizeof(MSG_P2P_CONNECTION_REQUEST_T)); -+ -+ if (!prMsgP2PConnReq) { -+ ASSERT(0); /* Can't trigger P2P FSM */ -+ return -ENOMEM; -+ } -+ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgP2PConnReq, MSG_SEND_METHOD_BUF); -+#endif -+ } else if (prData->flags == P2P_DISCONNECT) { -+#if 0 -+ /* indicate P2P-FSM with MID_MNY_P2P_CONNECTION_ABORT */ -+ prMsgP2PConnAbt = (P_MSG_HDR_T) cnmMemAlloc(prAdapter, -+ RAM_TYPE_MSG, sizeof(MSG_P2P_CONNECTION_ABORT_T)); -+ -+ if (!prMsgP2PConnAbt) { -+ ASSERT(0); /* Can't trigger P2P FSM */ -+ return -ENOMEM; -+ } -+ -+ COPY_MAC_ADDR(prMsgP2PConnAbt->aucTargetID, prConnectDevice->sta_addr); -+ -+ prMsgP2PConnAbt->rMsgHdr.eMsgId = MID_MNY_P2P_CONNECTION_ABORT; -+ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgP2PConnAbt, MSG_SEND_METHOD_BUF); -+#endif -+ } else { -+ return -EINVAL; -+ } -+ -+ return 0; -+} /* end of mtk_p2p_wext_connect_disconnect() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief P2P Private I/O Control handler (IOC_P2P_PASSWORD_READY) -+* -+* \param[in] prDev Net device requested. -+* \param[inout] wrqu Pointer to iwreq_data -+* -+* \retval 0 Success. -+* \retval -EFAULT Setting parameters to driver fail. -+* \retval -EOPNOTSUPP Key size not supported. -+* -+* \note -+*/ -+/*----------------------------------------------------------------------------*/ -+int -+mtk_p2p_wext_password_ready(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) -+{ -+ P_ADAPTER_T prAdapter = NULL; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ P_IW_P2P_PASSWORD_READY prPasswordReady = (P_IW_P2P_PASSWORD_READY) extra; -+ P_P2P_CONNECTION_SETTINGS_T prConnSettings; -+ -+ ASSERT(prDev); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ ASSERT(prGlueInfo); -+ -+ prAdapter = prGlueInfo->prAdapter; -+ ASSERT(prAdapter); -+ -+ prConnSettings = prAdapter->rWifiVar.prP2PConnSettings; -+ -+ /* retrieve IE for Probe Request */ -+ if (prPasswordReady->probe_req_len > 0) { -+ if (prPasswordReady->probe_req_len <= MAX_WSC_IE_LENGTH) { -+ if (copy_from_user -+ (prGlueInfo->prP2PInfo->aucWSCIE[1], prPasswordReady->probe_req_ie, -+ prPasswordReady->probe_req_len)) { -+ return -EFAULT; -+ } -+ } else { -+ return -E2BIG; -+ } -+ } -+ -+ prGlueInfo->prP2PInfo->u2WSCIELen[1] = prPasswordReady->probe_req_len; -+ -+ /* retrieve IE for Probe Response */ -+ if (prPasswordReady->probe_rsp_len > 0) { -+ if (prPasswordReady->probe_rsp_len <= MAX_WSC_IE_LENGTH) { -+ if (copy_from_user -+ (prGlueInfo->prP2PInfo->aucWSCIE[2], prPasswordReady->probe_rsp_ie, -+ prPasswordReady->probe_rsp_len)) { -+ return -EFAULT; -+ } -+ } else { -+ return -E2BIG; -+ } -+ } -+ -+ prGlueInfo->prP2PInfo->u2WSCIELen[2] = prPasswordReady->probe_rsp_len; -+ -+ switch (prPasswordReady->active_config_method) { -+ case 1: -+ prConnSettings->u2LocalConfigMethod = WPS_ATTRI_CFG_METHOD_PUSH_BUTTON; -+ break; -+ case 2: -+ prConnSettings->u2LocalConfigMethod = WPS_ATTRI_CFG_METHOD_KEYPAD; -+ break; -+ case 3: -+ prConnSettings->u2LocalConfigMethod = WPS_ATTRI_CFG_METHOD_DISPLAY; -+ break; -+ default: -+ break; -+ } -+ -+ prConnSettings->fgIsPasswordIDRdy = TRUE; -+ return 0; -+} /* end of mtk_p2p_wext_password_ready() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief P2P Private I/O Control handler (IOC_P2P_GET_REQ_DEVICE_INFO) -+* -+* \param[in] prDev Net device requested. -+* \param[inout] wrqu Pointer to iwreq_data -+* -+* \retval 0 Success. -+* \retval -EFAULT Setting parameters to driver fail. -+* \retval -EOPNOTSUPP Key size not supported. -+* -+* \note -+*/ -+/*----------------------------------------------------------------------------*/ -+int -+mtk_p2p_wext_request_dev_info(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) -+{ -+ P_ADAPTER_T prAdapter = NULL; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ P_IW_P2P_DEVICE_REQ prDeviceReq = (P_IW_P2P_DEVICE_REQ) extra; -+ -+ ASSERT(prDev); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ ASSERT(prGlueInfo); -+ -+ prAdapter = prGlueInfo->prAdapter; -+ ASSERT(prAdapter); -+ -+ /* specify data length */ -+ wrqu->data.length = sizeof(IW_P2P_DEVICE_REQ); -+ -+ /* copy to upper-layer supplied buffer */ -+ kalMemCopy(prDeviceReq->name, prGlueInfo->prP2PInfo->aucConnReqDevName, -+ prGlueInfo->prP2PInfo->u4ConnReqNameLength); -+ prDeviceReq->name_len = prGlueInfo->prP2PInfo->u4ConnReqNameLength; -+ prDeviceReq->name[prDeviceReq->name_len] = '\0'; -+ COPY_MAC_ADDR(prDeviceReq->device_addr, prGlueInfo->prP2PInfo->rConnReqPeerAddr); -+ prDeviceReq->device_type = prGlueInfo->prP2PInfo->ucConnReqDevType; -+ prDeviceReq->config_method = prGlueInfo->prP2PInfo->i4ConnReqConfigMethod; -+ prDeviceReq->active_config_method = prGlueInfo->prP2PInfo->i4ConnReqActiveConfigMethod; -+ -+ return 0; -+} /* end of mtk_p2p_wext_request_dev_info() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief P2P Private I/O Control handler (IOC_P2P_GET_STRUCT) -+* -+* \param[in] prDev Net device requested. -+* \param[inout] wrqu Pointer to iwreq_data -+* -+* \retval 0 Success. -+* \retval -EFAULT Setting parameters to driver fail. -+* \retval -EOPNOTSUPP Key size not supported. -+* -+* \note -+*/ -+/*----------------------------------------------------------------------------*/ -+int -+mtk_p2p_wext_invitation_indicate(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) -+{ -+ P_ADAPTER_T prAdapter = NULL; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ P_IW_P2P_IOCTL_INVITATION_INDICATE prInvIndicate = (P_IW_P2P_IOCTL_INVITATION_INDICATE) extra; -+ -+ ASSERT(prDev); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ ASSERT(prGlueInfo); -+ -+ prAdapter = prGlueInfo->prAdapter; -+ ASSERT(prAdapter); -+ -+ /* specify data length */ -+ wrqu->data.length = sizeof(IW_P2P_IOCTL_INVITATION_INDICATE); -+ -+ /* copy to upper-layer supplied buffer */ -+ kalMemCopy(prInvIndicate->dev_name, prGlueInfo->prP2PInfo->aucConnReqDevName, -+ prGlueInfo->prP2PInfo->u4ConnReqNameLength); -+ kalMemCopy(prInvIndicate->group_bssid, prGlueInfo->prP2PInfo->rConnReqGroupAddr, MAC_ADDR_LEN); -+ prInvIndicate->name_len = prGlueInfo->prP2PInfo->u4ConnReqNameLength; -+ prInvIndicate->dev_name[prInvIndicate->name_len] = '\0'; -+ COPY_MAC_ADDR(prInvIndicate->dev_addr, prGlueInfo->prP2PInfo->rConnReqPeerAddr); -+ prInvIndicate->config_method = prGlueInfo->prP2PInfo->i4ConnReqConfigMethod; -+ prInvIndicate->operating_channel = prGlueInfo->prP2PInfo->ucOperatingChnl; -+ prInvIndicate->invitation_type = prGlueInfo->prP2PInfo->ucInvitationType; -+ -+ return 0; -+} /* end of mtk_p2p_wext_invitation_indicate() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief P2P Private I/O Control handler (IOC_P2P_GET_STRUCT) -+* -+* \param[in] prDev Net device requested. -+* \param[inout] wrqu Pointer to iwreq_data -+* -+* \retval 0 Success. -+* \retval -EFAULT Setting parameters to driver fail. -+* \retval -EOPNOTSUPP Key size not supported. -+* -+* \note -+*/ -+/*----------------------------------------------------------------------------*/ -+int -+mtk_p2p_wext_invitation_status(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) -+{ -+ P_ADAPTER_T prAdapter = NULL; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ P_IW_P2P_IOCTL_INVITATION_STATUS prInvStatus = (P_IW_P2P_IOCTL_INVITATION_STATUS) extra; -+ -+ ASSERT(prDev); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ ASSERT(prGlueInfo); -+ -+ prAdapter = prGlueInfo->prAdapter; -+ ASSERT(prAdapter); -+ -+ /* specify data length */ -+ wrqu->data.length = sizeof(IW_P2P_IOCTL_INVITATION_STATUS); -+ -+ /* copy to upper-layer supplied buffer */ -+ prInvStatus->status_code = prGlueInfo->prP2PInfo->u4InvStatus; -+ -+ return 0; -+} /* end of mtk_p2p_wext_invitation_status() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief indicate an event to supplicant for device found -+* -+* \param[in] prGlueInfo Pointer of GLUE_INFO_T -+* -+* \retval TRUE Success. -+* \retval FALSE Failure -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN kalP2PIndicateFound(IN P_GLUE_INFO_T prGlueInfo) -+{ -+ union iwreq_data evt; -+ UINT_8 aucBuffer[IW_CUSTOM_MAX]; -+ -+ ASSERT(prGlueInfo); -+ -+ memset(&evt, 0, sizeof(evt)); -+ -+ snprintf(aucBuffer, IW_CUSTOM_MAX - 1, "P2P_DVC_FND"); -+ evt.data.length = strlen(aucBuffer); -+ -+ /* indicate IWEVP2PDVCFND event */ -+ wireless_send_event(prGlueInfo->prP2PInfo->prDevHandler, IWEVCUSTOM, &evt, aucBuffer); -+ -+ return FALSE; -+} /* end of kalP2PIndicateFound() */ -+ -+int -+mtk_p2p_wext_set_network_address(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) -+{ -+ P_ADAPTER_T prAdapter = NULL; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ -+ ASSERT(prDev); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ ASSERT(prGlueInfo); -+ -+ prAdapter = prGlueInfo->prAdapter; -+ ASSERT(prAdapter); -+ -+ /* @TODO: invoke wlan_p2p functions */ -+#if 0 -+ rStatus = kalIoctl(prGlueInfo, -+ (PFN_OID_HANDLER_FUNC_REQ) wlanoidSetP2pNetworkAddress, -+ prKey, prKey->u4Length, FALSE, FALSE, TRUE, &u4BufLen); -+#endif -+ -+ return 0; -+ -+} -+ -+int -+mtk_p2p_wext_set_ps_profile(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) -+{ -+ P_ADAPTER_T prAdapter = NULL; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ -+ ASSERT(prDev); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ ASSERT(prGlueInfo); -+ -+ prAdapter = prGlueInfo->prAdapter; -+ ASSERT(prAdapter); -+ -+ /* @TODO: invoke wlan_p2p functions */ -+#if 0 -+ rStatus = kalIoctl(prGlueInfo, -+ (PFN_OID_HANDLER_FUNC_REQ) wlanoidSetP2pPowerSaveProfile, -+ prKey, prKey->u4Length, FALSE, FALSE, TRUE, &u4BufLen); -+#endif -+ -+ return 0; -+ -+} -+ -+int -+mtk_p2p_wext_set_pm_param(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) -+{ -+ P_ADAPTER_T prAdapter = NULL; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ -+ ASSERT(prDev); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ ASSERT(prGlueInfo); -+ -+ prAdapter = prGlueInfo->prAdapter; -+ ASSERT(prAdapter); -+ -+ /* @TODO: invoke wlan_p2p functions */ -+#if 0 -+ rStatus = kalIoctl(prGlueInfo, -+ (PFN_OID_HANDLER_FUNC_REQ) wlanoidSetP2pPowerSaveProfile, -+ prKey, prKey->u4Length, FALSE, FALSE, TRUE, &u4BufLen); -+#endif -+ -+ return 0; -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief P2P Private I/O Control handler (IOC_P2P_SET_INT) -+* -+* \param[in] prDev Net device requested. -+* \param[inout] wrqu Pointer to iwreq_data -+* -+* \retval 0 Success. -+* \retval -EFAULT Setting parameters to driver fail. -+* \retval -EOPNOTSUPP Setting parameters not support. -+* -+* \note -+*/ -+/*----------------------------------------------------------------------------*/ -+int -+mtk_p2p_wext_start_formation(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) -+{ -+ int i4Status = 0; -+ P_ADAPTER_T prAdapter = (P_ADAPTER_T) NULL; -+ P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) NULL; -+/* struct iw_point *prData = (struct iw_point*)&wrqu->data; */ -+ P_IW_P2P_IOCTL_START_FORMATION prIoctlStartFormation = (P_IW_P2P_IOCTL_START_FORMATION) NULL; -+ -+ do { -+ if ((prDev == NULL) || (extra == NULL)) { -+ ASSERT(FALSE); -+ i4Status = -EINVAL; -+ break; -+ } -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ prIoctlStartFormation = (P_IW_P2P_IOCTL_START_FORMATION) extra; -+ -+ if (prGlueInfo == NULL) { -+ i4Status = -EINVAL; -+ break; -+ } -+ -+ prAdapter = prGlueInfo->prAdapter; -+ -+ if (prAdapter == NULL) { -+ i4Status = -EINVAL; -+ break; -+ } -+ -+ } while (FALSE); -+ -+ return i4Status; -+ -+} -+ -+/* mtk_p2p_wext_start_formation */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief P2P Private I/O Control handler (IOC_P2P_SET_INT) -+* -+* \param[in] prDev Net device requested. -+* \param[inout] wrqu Pointer to iwreq_data -+* -+* \retval 0 Success. -+* \retval -EFAULT Setting parameters to driver fail. -+* \retval -EOPNOTSUPP Setting parameters not support. -+* -+* \note -+*/ -+/*----------------------------------------------------------------------------*/ -+int -+mtk_p2p_wext_set_int(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) -+{ -+ int status = 0; -+ UINT_32 u4SubCmd = 0; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ UINT_32 index; -+ INT_32 value; -+ PUINT_32 pu4IntBuf; -+ P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo = (P_P2P_SPECIFIC_BSS_INFO_T) NULL; -+ P_P2P_CONNECTION_SETTINGS_T prP2pConnSettings = (P_P2P_CONNECTION_SETTINGS_T) NULL; -+ P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T) NULL; -+ UINT_32 u4Leng; -+ -+ ASSERT(prDev); -+ ASSERT(wrqu); -+ -+ /* printk("mtk_p2p_wext_set_int\n"); */ -+ pu4IntBuf = (PUINT_32) extra; -+ -+ if (FALSE == GLUE_CHK_PR2(prDev, wrqu)) -+ return -EINVAL; -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ ASSERT(prGlueInfo); -+ -+ prP2pSpecificBssInfo = prGlueInfo->prAdapter->rWifiVar.prP2pSpecificBssInfo; -+ prP2pConnSettings = prGlueInfo->prAdapter->rWifiVar.prP2PConnSettings; -+ prP2pFsmInfo = prGlueInfo->prAdapter->rWifiVar.prP2pFsmInfo; -+ -+ u4SubCmd = (UINT_32) wrqu->mode; -+ index = pu4IntBuf[1]; -+ value = pu4IntBuf[2]; -+ -+ DBGLOG(P2P, INFO, "set parameter, u4SubCmd=%d idx=%d value=%d\n", (INT_16) u4SubCmd, (INT_16) index, value); -+ -+ switch (u4SubCmd) { -+ case PRIV_CMD_INT_P2P_SET: -+ switch (index) { -+ case 0: /* Listen CH */ -+ { -+ UINT_8 ucSuggestChnl = 0; -+ -+ prP2pConnSettings->ucListenChnl = value; -+ -+ /* 20110920 - frog: User configurations are placed in ConnSettings. */ -+ if (rlmFuncFindAvailableChannel -+ (prGlueInfo->prAdapter, value, &ucSuggestChnl, TRUE, TRUE)) { -+ prP2pSpecificBssInfo->ucListenChannel = value; -+ } else { -+ prP2pSpecificBssInfo->ucListenChannel = ucSuggestChnl; -+ } -+ -+ break; -+ } -+ case 1: /* P2p mode */ -+ break; -+ case 4: /* Noa duration */ -+ prP2pSpecificBssInfo->rNoaParam.u4NoaDurationMs = value; -+ /* only to apply setting when setting NOA count */ -+ /* status = mtk_p2p_wext_set_noa_param(prDev, info, wrqu, -+ (char *)&prP2pSpecificBssInfo->rNoaParam); */ -+ break; -+ case 5: /* Noa interval */ -+ prP2pSpecificBssInfo->rNoaParam.u4NoaIntervalMs = value; -+ /* only to apply setting when setting NOA count */ -+ /* status = mtk_p2p_wext_set_noa_param(prDev, info, wrqu, -+ (char *)&prP2pSpecificBssInfo->rNoaParam); */ -+ break; -+ case 6: /* Noa count */ -+ prP2pSpecificBssInfo->rNoaParam.u4NoaCount = value; -+ status = -+ mtk_p2p_wext_set_noa_param(prDev, info, wrqu, (char *)&prP2pSpecificBssInfo->rNoaParam); -+ break; -+ case 100: /* Oper CH */ -+ /* 20110920 - frog: User configurations are placed in ConnSettings. */ -+ prP2pConnSettings->ucOperatingChnl = value; -+ break; -+ case 101: /* Local config Method, for P2P SDK */ -+ /* prP2pConnSettings->u2LocalConfigMethod; */ -+ break; -+ case 102: /* Sigma P2p reset */ -+ kalMemZero(prP2pConnSettings->aucTargetDevAddr, MAC_ADDR_LEN); -+ /* prP2pConnSettings->eConnectionPolicy = ENUM_P2P_CONNECTION_POLICY_AUTO; */ -+ break; -+ case 103: /* WPS MODE */ -+ kalP2PSetWscMode(prGlueInfo, value); -+ break; -+ case 104: /* P2p send persence, duration */ -+ break; -+ case 105: /* P2p send persence, interval */ -+ break; -+ case 106: /* P2P set sleep */ -+ value = 1; -+ kalIoctl(prGlueInfo, -+ wlanoidSetP2pPowerSaveProfile, -+ &value, sizeof(value), FALSE, FALSE, TRUE, TRUE, &u4Leng); -+ break; -+ case 107: /* P2P set opps, CTWindowl */ -+ prP2pSpecificBssInfo->rOppPsParam.u4CTwindowMs = value; -+ status = -+ mtk_p2p_wext_set_oppps_param(prDev, info, wrqu, (char *)&prP2pSpecificBssInfo->rOppPsParam); -+ break; -+ case 108: /* p2p_set_power_save */ -+ kalIoctl(prGlueInfo, -+ wlanoidSetP2pPowerSaveProfile, -+ &value, sizeof(value), FALSE, FALSE, TRUE, TRUE, &u4Leng); -+ -+ break; -+ -+ default: -+ break; -+ } -+ break; -+ default: -+ break; -+ } -+ -+ return status; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief P2P Private I/O Control handler (IOC_P2P_SET_STRUCT) -+* -+* \param[in] prDev Net device requested. -+* \param[inout] wrqu Pointer to iwreq_data -+* -+* \retval 0 Success. -+* \retval -EFAULT Setting parameters to driver fail. -+* \retval -EOPNOTSUPP Key size not supported. -+* -+* \note -+*/ -+/*----------------------------------------------------------------------------*/ -+int -+mtk_p2p_wext_set_struct(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) -+{ -+ int status = 0; -+ UINT_32 u4SubCmd = 0; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ P_IW_P2P_TRANSPORT_STRUCT prP2PReq = NULL; -+ -+ ASSERT(prDev); -+ ASSERT(wrqu); -+ -+ if (FALSE == GLUE_CHK_PR2(prDev, wrqu)) -+ return -EINVAL; -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ ASSERT(prGlueInfo); -+ -+ u4SubCmd = (UINT_32) wrqu->data.flags; -+ -+ kalMemZero(&prGlueInfo->prP2PInfo->aucOidBuf[0], sizeof(prGlueInfo->prP2PInfo->aucOidBuf)); -+ -+ switch (u4SubCmd) { -+ case PRIV_CMD_OID: -+ if (copy_from_user(&(prGlueInfo->prP2PInfo->aucOidBuf[0]), wrqu->data.pointer, wrqu->data.length)) { -+ status = -EFAULT; -+ break; -+ } -+ -+ if (!kalMemCmp(&(prGlueInfo->prP2PInfo->aucOidBuf[0]), extra, wrqu->data.length)) -+ DBGLOG(P2P, INFO, "extra buffer is valid\n"); -+ else -+ DBGLOG(P2P, INFO, "extra 0x%p\n", extra); -+ -+ prP2PReq = (P_IW_P2P_TRANSPORT_STRUCT) (&(prGlueInfo->prP2PInfo->aucOidBuf[0])); -+ switch (prP2PReq->u4CmdId) { -+ case P2P_CMD_ID_SEND_SD_RESPONSE: -+ status = mtk_p2p_wext_send_service_discovery_response(prDev, info, wrqu, (char *)prP2PReq); -+ break; -+ -+ case P2P_CMD_ID_SEND_SD_REQUEST: -+ status = mtk_p2p_wext_send_service_discovery_request(prDev, info, wrqu, (char *)prP2PReq); -+ break; -+ -+ case P2P_CMD_ID_TERMINATE_SD_PHASE: -+ status = mtk_p2p_wext_terminate_service_discovery_phase(prDev, info, wrqu, (char *)prP2PReq); -+ break; -+ -+ case P2P_CMD_ID_INVITATION: -+ if (prP2PReq->inBufferLength == sizeof(IW_P2P_IOCTL_INVITATION_STRUCT)) { -+ /* Do nothing */ -+ /* status = mtk_p2p_wext_invitation_request(prDev, info, wrqu, -+ (char *)(prP2PReq->aucBuffer)); */ -+ } -+ break; -+ -+ case P2P_CMD_ID_INVITATION_ABORT: -+ if (prP2PReq->inBufferLength == sizeof(IW_P2P_IOCTL_ABORT_INVITATION)) { -+ /* Do nothing */ -+ /* status = mtk_p2p_wext_invitation_abort(prDev, info, wrqu, -+ (char *)(prP2PReq->aucBuffer)); */ -+ } -+ break; -+ -+ case P2P_CMD_ID_START_FORMATION: -+ if (prP2PReq->inBufferLength == sizeof(IW_P2P_IOCTL_START_FORMATION)) -+ status = mtk_p2p_wext_start_formation(prDev, info, wrqu, (char *)(prP2PReq->aucBuffer)); -+ break; -+ default: -+ status = -EOPNOTSUPP; -+ } -+ -+ break; -+#if CFG_SUPPORT_ANTI_PIRACY -+ case PRIV_SEC_CHECK_OID: -+ if (wrqu->data.length > 256) { -+ status = -EOPNOTSUPP; -+ break; -+ } -+ if (copy_from_user(&(prGlueInfo->prP2PInfo->aucSecCheck[0]), wrqu->data.pointer, wrqu->data.length)) { -+ status = -EFAULT; -+ break; -+ } -+ -+ if (!kalMemCmp(&(prGlueInfo->prP2PInfo->aucSecCheck[0]), extra, wrqu->data.length)) -+ DBGLOG(P2P, INFO, "extra buffer is valid\n"); -+ else -+ DBGLOG(P2P, INFO, "extra 0x%p\n", extra); -+ prP2PReq = (P_IW_P2P_TRANSPORT_STRUCT) (&(prGlueInfo->prP2PInfo->aucSecCheck[0])); -+ -+ switch (prP2PReq->u4CmdId) { -+ case P2P_CMD_ID_SEC_CHECK: -+ status = mtk_p2p_wext_set_sec_check_request(prDev, info, wrqu, (char *)prP2PReq); -+ break; -+ default: -+ status = -EOPNOTSUPP; -+ } -+ break; -+#endif -+ case PRIV_CMD_P2P_VERSION: -+ if (copy_from_user(&(prGlueInfo->prP2PInfo->aucOidBuf[0]), wrqu->data.pointer, wrqu->data.length)) { -+ status = -EFAULT; -+ break; -+ } -+ -+ if (!kalMemCmp(&(prGlueInfo->prP2PInfo->aucOidBuf[0]), extra, wrqu->data.length)) -+ DBGLOG(P2P, INFO, "extra buffer is valid\n"); -+ else -+ DBGLOG(P2P, INFO, "extra 0x%p\n", extra); -+ -+ prP2PReq = (P_IW_P2P_TRANSPORT_STRUCT) (&(prGlueInfo->prP2PInfo->aucOidBuf[0])); -+ switch (prP2PReq->u4CmdId) { -+ case P2P_CMD_ID_P2P_VERSION: -+ status = mtk_p2p_wext_set_p2p_version(prDev, info, wrqu, (char *)prP2PReq); -+ break; -+ default: -+ status = -EOPNOTSUPP; -+ break; -+ } -+ break; -+ default: -+ status = -EOPNOTSUPP; -+ break; -+ } -+ -+ return status; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief P2P Private I/O Control handler (IOC_P2P_GET_STRUCT) -+* -+* \param[in] prDev Net device requested. -+* \param[inout] wrqu Pointer to iwreq_data -+* -+* \retval 0 Success. -+* \retval -EFAULT Setting parameters to driver fail. -+* \retval -EOPNOTSUPP Key size not supported. -+* -+* \note -+*/ -+/*----------------------------------------------------------------------------*/ -+int -+mtk_p2p_wext_get_struct(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) -+{ -+ int status = 0; -+ UINT_32 u4SubCmd = 0; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ P_IW_P2P_TRANSPORT_STRUCT prP2PReq = NULL; -+ -+ ASSERT(prDev); -+ ASSERT(wrqu); -+ -+ if (!prDev || !wrqu) { -+ DBGLOG(P2P, WARN, "%s(): invalid param(0x%p, 0x%p)\n", __func__, prDev, wrqu); -+ return -EINVAL; -+ } -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ ASSERT(prGlueInfo); -+ -+ u4SubCmd = (UINT_32) wrqu->data.flags; -+ -+ kalMemZero(&(prGlueInfo->prP2PInfo->aucOidBuf[0]), sizeof(prGlueInfo->prP2PInfo->aucOidBuf)); -+ -+ switch (u4SubCmd) { -+ case PRIV_CMD_OID: -+ if (copy_from_user(&(prGlueInfo->prP2PInfo->aucOidBuf[0]), -+ wrqu->data.pointer, sizeof(IW_P2P_TRANSPORT_STRUCT))) { -+ DBGLOG(P2P, ERROR, "%s() copy_from_user oidBuf fail\n", __func__); -+ return -EFAULT; -+ } -+ -+ prP2PReq = (P_IW_P2P_TRANSPORT_STRUCT) (&(prGlueInfo->prP2PInfo->aucOidBuf[0])); -+ -+ switch (prP2PReq->u4CmdId) { -+ case P2P_CMD_ID_GET_SD_REQUEST: -+ status = mtk_p2p_wext_get_service_discovery_request(prDev, info, wrqu, (char *)prP2PReq); -+ break; -+ -+ case P2P_CMD_ID_GET_SD_RESPONSE: -+ status = mtk_p2p_wext_get_service_discovery_response(prDev, info, wrqu, (char *)prP2PReq); -+ break; -+ -+ case P2P_CMD_ID_INVITATION_INDICATE: -+ { -+ status = -+ mtk_p2p_wext_invitation_indicate(prDev, info, wrqu, (char *)(prP2PReq->aucBuffer)); -+ prP2PReq->outBufferLength = wrqu->data.length; -+ if (copy_to_user(wrqu->data.pointer, -+ &(prGlueInfo->prP2PInfo->aucOidBuf[0]), -+ wrqu->data.length + OFFSET_OF(IW_P2P_TRANSPORT_STRUCT, aucBuffer))) { -+ DBGLOG(P2P, ERROR, "%s() copy_to_user() fail\n", __func__); -+ return -EIO; -+ } else { -+ return 0; -+ } -+ break; -+ } -+ case P2P_CMD_ID_INVITATION_STATUS: -+ { -+ status = -+ mtk_p2p_wext_invitation_status(prDev, info, wrqu, (char *)(prP2PReq->aucBuffer)); -+ prP2PReq->outBufferLength = wrqu->data.length; -+ if (copy_to_user(wrqu->data.pointer, -+ &(prGlueInfo->prP2PInfo->aucOidBuf[0]), -+ wrqu->data.length + OFFSET_OF(IW_P2P_TRANSPORT_STRUCT, aucBuffer))) { -+ DBGLOG(P2P, ERROR, "%s() copy_to_user() fail\n", __func__); -+ return -EIO; -+ } else { -+ return 0; -+ } -+ break; -+ } -+ case P2P_CMD_ID_GET_CH_LIST: -+ { -+ UINT_16 i; -+ UINT_8 NumOfChannel = 50; -+ RF_CHANNEL_INFO_T aucChannelList[50]; -+ UINT_8 ucMaxChannelNum = 50; -+ PUINT_8 pucChnlList = (PUINT_8) prP2PReq->aucBuffer; -+ -+ kalGetChnlList(prGlueInfo, BAND_NULL, ucMaxChannelNum, &NumOfChannel, aucChannelList); -+ if (NumOfChannel > 50) -+ NumOfChannel = 50; -+ prP2PReq->outBufferLength = NumOfChannel; -+ /*here must confirm NumOfChannel < 16, for prP2PReq->aucBuffer 16 byte*/ -+ if (NumOfChannel >= 15) { -+ /*DBGLOG(P2P, ERROR, "channel num > 15\n", __func__);*/ -+ ASSERT(FALSE); -+ } -+ -+ for (i = 0; i < NumOfChannel; i++) { -+#if 0 -+ /* 20120208 frog: modify to avoid clockwork warning. */ -+ prP2PReq->aucBuffer[i] = aucChannelList[i].ucChannelNum; -+#else -+ *pucChnlList = aucChannelList[i].ucChannelNum; -+ pucChnlList++; -+#endif -+ } -+ if (copy_to_user(wrqu->data.pointer, -+ &(prGlueInfo->prP2PInfo->aucOidBuf[0]), -+ NumOfChannel + OFFSET_OF(IW_P2P_TRANSPORT_STRUCT, aucBuffer))) { -+ DBGLOG(P2P, ERROR, "%s() copy_to_user() fail\n", __func__); -+ return -EIO; -+ } else { -+ return 0; -+ } -+ break; -+ } -+ -+ case P2P_CMD_ID_GET_OP_CH: -+ { -+ prP2PReq->inBufferLength = 4; -+ -+ status = wlanoidQueryP2pOpChannel(prGlueInfo->prAdapter, -+ prP2PReq->aucBuffer, -+ prP2PReq->inBufferLength, &prP2PReq->outBufferLength); -+ -+ if (status == 0) { /* WLAN_STATUS_SUCCESS */ -+ if (copy_to_user(wrqu->data.pointer, -+ &(prGlueInfo->prP2PInfo->aucOidBuf[0]), -+ prP2PReq->outBufferLength + OFFSET_OF(IW_P2P_TRANSPORT_STRUCT, -+ aucBuffer))) { -+ DBGLOG(P2P, ERROR, "%s() copy_to_user() fail\n", __func__); -+ return -EIO; -+ } -+ } else { -+ if (copy_to_user(wrqu->data.pointer, -+ &(prGlueInfo->prP2PInfo->aucOidBuf[0]), -+ OFFSET_OF(IW_P2P_TRANSPORT_STRUCT, aucBuffer))) { -+ DBGLOG(P2P, ERROR, "%s() copy_to_user() fail\n", __func__); -+ return -EIO; -+ } -+ } -+ break; -+ } -+ -+ default: -+ status = -EOPNOTSUPP; -+ } -+ -+ break; -+#if CFG_SUPPORT_ANTI_PIRACY -+ case PRIV_SEC_CHECK_OID: -+ if (wrqu->data.length > 256) { -+ status = -EOPNOTSUPP; -+ break; -+ } -+ if (copy_from_user(&(prGlueInfo->prP2PInfo->aucSecCheck[0]), -+ wrqu->data.pointer, sizeof(IW_P2P_TRANSPORT_STRUCT))) { -+ DBGLOG(P2P, ERROR, "%s() copy_from_user oidBuf fail\n", __func__); -+ return -EFAULT; -+ } -+ -+ prP2PReq = (P_IW_P2P_TRANSPORT_STRUCT) (&(prGlueInfo->prP2PInfo->aucSecCheck[0])); -+ -+ switch (prP2PReq->u4CmdId) { -+ case P2P_CMD_ID_SEC_CHECK: -+ status = mtk_p2p_wext_get_sec_check_response(prDev, info, wrqu, (char *)prP2PReq); -+ break; -+ default: -+ status = -EOPNOTSUPP; -+ } -+ break; -+#endif -+ case PRIV_CMD_P2P_VERSION: -+ if (copy_from_user(&(prGlueInfo->prP2PInfo->aucOidBuf[0]), -+ wrqu->data.pointer, sizeof(IW_P2P_TRANSPORT_STRUCT))) { -+ DBGLOG(P2P, ERROR, "%s() copy_from_user oidBuf fail\n", __func__); -+ return -EFAULT; -+ } -+ -+ prP2PReq = (P_IW_P2P_TRANSPORT_STRUCT) (&(prGlueInfo->prP2PInfo->aucOidBuf[0])); -+ -+ switch (prP2PReq->u4CmdId) { -+ case P2P_CMD_ID_P2P_VERSION: -+ status = mtk_p2p_wext_get_p2p_version(prDev, info, wrqu, (char *)prP2PReq); -+ break; -+ default: -+ status = -EOPNOTSUPP; -+ break; -+ } -+ -+ /* Copy queried data to user. */ -+ if (status == 0) { /* WLAN_STATUS_SUCCESS */ -+ if (copy_to_user(wrqu->data.pointer, -+ &(prGlueInfo->prP2PInfo->aucOidBuf[0]), -+ prP2PReq->outBufferLength + OFFSET_OF(IW_P2P_TRANSPORT_STRUCT, aucBuffer))) { -+ DBGLOG(P2P, ERROR, "%s() copy_to_user() fail\n", __func__); -+ return -EIO; -+ } -+ } -+ -+ else { -+ if (copy_to_user(wrqu->data.pointer, -+ &(prGlueInfo->prP2PInfo->aucOidBuf[0]), -+ OFFSET_OF(IW_P2P_TRANSPORT_STRUCT, aucBuffer))) { -+ DBGLOG(P2P, ERROR, "%s() copy_to_user() fail\n", __func__); -+ return -EIO; -+ } -+ } -+ -+ break; -+ default: -+ return -EOPNOTSUPP; -+ } -+ -+ return status; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief P2P Private I/O Control handler for -+* getting service discovery request frame from driver -+* -+* \param[in] prDev Net device requested. -+* \param[inout] wrqu Pointer to iwreq_data -+* -+* \retval 0 Success. -+* \retval -EFAULT Setting parameters to driver fail. -+* \retval -EOPNOTSUPP Key size not supported. -+* -+* \note -+*/ -+/*----------------------------------------------------------------------------*/ -+int -+mtk_p2p_wext_get_service_discovery_request(IN struct net_device *prDev, -+ IN struct iw_request_info *info, -+ IN OUT union iwreq_data *wrqu, IN OUT char *extra) -+{ -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ UINT_32 u4QueryInfoLen = 0; -+ P_IW_P2P_TRANSPORT_STRUCT prP2PReq = (P_IW_P2P_TRANSPORT_STRUCT) extra; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ -+ ASSERT(prDev); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ ASSERT(prGlueInfo); -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidGetP2PSDRequest, -+ prP2PReq->aucBuffer, prP2PReq->outBufferLength, TRUE, FALSE, TRUE, TRUE, &u4QueryInfoLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) -+ return -EFAULT; -+ -+ prP2PReq->outBufferLength = u4QueryInfoLen; -+ -+ if (copy_to_user(wrqu->data.pointer, -+ &(prGlueInfo->prP2PInfo->aucOidBuf[0]), -+ u4QueryInfoLen + OFFSET_OF(IW_P2P_TRANSPORT_STRUCT, aucBuffer))) { -+ DBGLOG(P2P, ERROR, "%s() copy_to_user() fail\n", __func__); -+ return -EIO; -+ } else { -+ return 0; -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief P2P Private I/O Control handler for -+* getting service discovery response frame from driver -+* -+* \param[in] prDev Net device requested. -+* \param[inout] wrqu Pointer to iwreq_data -+* -+* \retval 0 Success. -+* \retval -EFAULT Setting parameters to driver fail. -+* \retval -EOPNOTSUPP Key size not supported. -+* -+* \note -+*/ -+/*----------------------------------------------------------------------------*/ -+int -+mtk_p2p_wext_get_service_discovery_response(IN struct net_device *prDev, -+ IN struct iw_request_info *info, -+ IN OUT union iwreq_data *wrqu, IN OUT char *extra) -+{ -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ UINT_32 u4QueryInfoLen = 0; -+ P_IW_P2P_TRANSPORT_STRUCT prP2PReq = (P_IW_P2P_TRANSPORT_STRUCT) extra; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ -+ ASSERT(prDev); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ ASSERT(prGlueInfo); -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidGetP2PSDResponse, -+ prP2PReq->aucBuffer, prP2PReq->outBufferLength, TRUE, FALSE, TRUE, TRUE, &u4QueryInfoLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) -+ return -EFAULT; -+ -+ prP2PReq->outBufferLength = u4QueryInfoLen; -+ -+ if (copy_to_user(wrqu->data.pointer, -+ &(prGlueInfo->prP2PInfo->aucOidBuf[0]), -+ u4QueryInfoLen + OFFSET_OF(IW_P2P_TRANSPORT_STRUCT, aucBuffer))) { -+ DBGLOG(P2P, ERROR, "%s() copy_to_user() fail\n", __func__); -+ return -EIO; -+ } -+ return 0; -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief P2P Private I/O Control handler for -+* sending service discovery request frame -+* -+* \param[in] prDev Net device requested. -+* \param[inout] wrqu Pointer to iwreq_data -+* -+* \retval 0 Success. -+* \retval -EFAULT Setting parameters to driver fail. -+* \retval -EOPNOTSUPP Key size not supported. -+* -+* \note -+*/ -+/*----------------------------------------------------------------------------*/ -+int -+mtk_p2p_wext_send_service_discovery_request(IN struct net_device *prDev, -+ IN struct iw_request_info *info, -+ IN OUT union iwreq_data *wrqu, IN OUT char *extra) -+{ -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ UINT_32 u4SetInfoLen; -+ P_IW_P2P_TRANSPORT_STRUCT prP2PReq = (P_IW_P2P_TRANSPORT_STRUCT) extra; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ -+ ASSERT(prDev); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ ASSERT(prGlueInfo); -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSendP2PSDRequest, -+ prP2PReq->aucBuffer, prP2PReq->inBufferLength, FALSE, FALSE, TRUE, TRUE, &u4SetInfoLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) -+ return -EFAULT; -+ else -+ return 0; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief P2P Private I/O Control handler for -+* sending service discovery response frame -+* -+* \param[in] prDev Net device requested. -+* \param[inout] wrqu Pointer to iwreq_data -+* -+* \retval 0 Success. -+* \retval -EFAULT Setting parameters to driver fail. -+* \retval -EOPNOTSUPP Key size not supported. -+* -+* \note -+*/ -+/*----------------------------------------------------------------------------*/ -+int -+mtk_p2p_wext_send_service_discovery_response(IN struct net_device *prDev, -+ IN struct iw_request_info *info, -+ IN OUT union iwreq_data *wrqu, IN OUT char *extra) -+{ -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ UINT_32 u4SetInfoLen; -+ P_IW_P2P_TRANSPORT_STRUCT prP2PReq = (P_IW_P2P_TRANSPORT_STRUCT) extra; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ -+ ASSERT(prDev); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ ASSERT(prGlueInfo); -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSendP2PSDResponse, -+ prP2PReq->aucBuffer, prP2PReq->inBufferLength, FALSE, FALSE, TRUE, TRUE, &u4SetInfoLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) -+ return -EFAULT; -+ else -+ return 0; -+} -+ -+#if CFG_SUPPORT_ANTI_PIRACY -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief P2P Private I/O Control handler for -+* -+* \param[in] prDev Net device requested. -+* \param[inout] wrqu Pointer to iwreq_data -+* -+* \retval 0 Success. -+* \retval -EFAULT Setting parameters to driver fail. -+* \retval -EOPNOTSUPP Key size not supported. -+* -+* \note -+*/ -+/*----------------------------------------------------------------------------*/ -+int -+mtk_p2p_wext_set_sec_check_request(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) -+{ -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ UINT_32 u4SetInfoLen; -+ P_IW_P2P_TRANSPORT_STRUCT prP2PReq = (P_IW_P2P_TRANSPORT_STRUCT) extra; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ -+ ASSERT(prDev); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ ASSERT(prGlueInfo); -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetSecCheckRequest, -+ prP2PReq->aucBuffer, prP2PReq->inBufferLength, FALSE, FALSE, TRUE, TRUE, &u4SetInfoLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) -+ return -EFAULT; -+ else -+ return 0; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief P2P Private I/O Control handler for -+* -+* \param[in] prDev Net device requested. -+* \param[inout] wrqu Pointer to iwreq_data -+* -+* \retval 0 Success. -+* \retval -EFAULT Setting parameters to driver fail. -+* \retval -EOPNOTSUPP Key size not supported. -+* -+* \note -+*/ -+/*----------------------------------------------------------------------------*/ -+int -+mtk_p2p_wext_get_sec_check_response(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) -+{ -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ UINT_32 u4QueryInfoLen = 0; -+ P_IW_P2P_TRANSPORT_STRUCT prP2PReq = (P_IW_P2P_TRANSPORT_STRUCT) extra; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ -+ ASSERT(prDev); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ ASSERT(prGlueInfo); -+ -+ DBGLOG(P2P, INFO, "mtk_p2p_wext_get_sec_check_response\n"); -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidGetSecCheckResponse, -+ prP2PReq->aucBuffer, prP2PReq->outBufferLength, TRUE, FALSE, TRUE, TRUE, &u4QueryInfoLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) -+ return -EFAULT; -+ -+ prP2PReq->outBufferLength = u4QueryInfoLen; -+ -+ if (copy_to_user(wrqu->data.pointer, -+ prP2PReq->aucBuffer, u4QueryInfoLen + OFFSET_OF(IW_P2P_TRANSPORT_STRUCT, aucBuffer))) { -+ DBGLOG(P2P, ERROR, "%s() copy_to_user() fail\n", __func__); -+ return -EIO; -+ } -+ return 0; -+ -+} -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief P2P Private I/O Control handler for -+* terminating service discovery phase -+* -+* \param[in] prDev Net device requested. -+* \param[inout] wrqu Pointer to iwreq_data -+* -+* \retval 0 Success. -+* \retval -EFAULT Setting parameters to driver fail. -+* \retval -EOPNOTSUPP Key size not supported. -+* -+* \note -+*/ -+/*----------------------------------------------------------------------------*/ -+int -+mtk_p2p_wext_terminate_service_discovery_phase(IN struct net_device *prDev, -+ IN struct iw_request_info *info, -+ IN OUT union iwreq_data *wrqu, IN OUT char *extra) -+{ -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ UINT_32 u4SetInfoLen; -+ P_IW_P2P_TRANSPORT_STRUCT prP2PReq = (P_IW_P2P_TRANSPORT_STRUCT) extra; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ -+ ASSERT(prDev); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ ASSERT(prGlueInfo); -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetP2PTerminateSDPhase, -+ prP2PReq->aucBuffer, prP2PReq->inBufferLength, FALSE, FALSE, TRUE, TRUE, &u4SetInfoLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) -+ return -EFAULT; -+ else -+ return 0; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief P2P Private I/O Control handler for -+* -+* \param[in] prDev Net device requested. -+* \param[inout] wrqu Pointer to iwreq_data -+* -+* \retval 0 Success. -+* \retval -EFAULT Setting parameters to driver fail. -+* \retval -EOPNOTSUPP Key size not supported. -+* -+* \note -+*/ -+/*----------------------------------------------------------------------------*/ -+int -+mtk_p2p_wext_set_noa_param(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) -+{ -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ UINT_32 u4SetInfoLen; -+ /* P_IW_P2P_TRANSPORT_STRUCT prP2PReq = (P_IW_P2P_TRANSPORT_STRUCT)extra; */ -+ P_PARAM_CUSTOM_NOA_PARAM_STRUCT_T prNoaParam = (P_PARAM_CUSTOM_NOA_PARAM_STRUCT_T) extra; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ -+ ASSERT(prDev); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ ASSERT(prGlueInfo); -+ -+ DBGLOG(P2P, INFO, "mtk_p2p_wext_set_noa_param\n"); -+ -+ rStatus = kalIoctl(prGlueInfo, wlanoidSetNoaParam, prNoaParam, /* prP2PReq->aucBuffer, */ -+ sizeof(PARAM_CUSTOM_NOA_PARAM_STRUCT_T), /* prP2PReq->inBufferLength, */ -+ FALSE, FALSE, TRUE, TRUE, &u4SetInfoLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) -+ return -EFAULT; -+ else -+ return 0; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief P2P Private I/O Control handler for -+* -+* \param[in] prDev Net device requested. -+* \param[inout] wrqu Pointer to iwreq_data -+* -+* \retval 0 Success. -+* \retval -EFAULT Setting parameters to driver fail. -+* \retval -EOPNOTSUPP Key size not supported. -+* -+* \note -+*/ -+/*----------------------------------------------------------------------------*/ -+int -+mtk_p2p_wext_set_oppps_param(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) -+{ -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ UINT_32 u4SetInfoLen; -+/* P_IW_P2P_TRANSPORT_STRUCT prP2PReq = (P_IW_P2P_TRANSPORT_STRUCT)extra; */ -+ P_PARAM_CUSTOM_OPPPS_PARAM_STRUCT_T prOppPsParam = (P_PARAM_CUSTOM_OPPPS_PARAM_STRUCT_T) extra; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ -+ ASSERT(prDev); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ ASSERT(prGlueInfo); -+ -+ DBGLOG(P2P, INFO, "mtk_p2p_wext_set_oppps_param\n"); -+ -+ rStatus = kalIoctl(prGlueInfo, wlanoidSetOppPsParam, prOppPsParam, /* prP2PReq->aucBuffer, */ -+ sizeof(PARAM_CUSTOM_OPPPS_PARAM_STRUCT_T), /* prP2PReq->inBufferLength, */ -+ FALSE, FALSE, TRUE, TRUE, &u4SetInfoLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) -+ return -EFAULT; -+ else -+ return 0; -+} -+ -+int -+mtk_p2p_wext_set_p2p_version(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) -+{ -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ P_IW_P2P_TRANSPORT_STRUCT prP2PReq = (P_IW_P2P_TRANSPORT_STRUCT) extra; -+ UINT_32 u4SetInfoLen; -+ -+ ASSERT(prDev); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ ASSERT(prGlueInfo); -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetP2pSupplicantVersion, -+ prP2PReq->aucBuffer, prP2PReq->inBufferLength, FALSE, FALSE, TRUE, TRUE, &u4SetInfoLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) -+ return -EFAULT; -+ else -+ return rStatus; -+ -+} -+ -+/* mtk_p2p_wext_set_p2p_version */ -+ -+int -+mtk_p2p_wext_get_p2p_version(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) -+{ -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ UINT_32 u4QueryInfoLen; -+ P_IW_P2P_TRANSPORT_STRUCT prP2PReq = (P_IW_P2P_TRANSPORT_STRUCT) extra; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ -+ ASSERT(prDev); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ ASSERT(prGlueInfo); -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidQueryP2pVersion, -+ prP2PReq->aucBuffer, prP2PReq->outBufferLength, TRUE, FALSE, TRUE, TRUE, &u4QueryInfoLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) -+ return -EFAULT; -+ else -+ return rStatus; -+ -+} /* mtk_p2p_wext_get_p2p_version */ -+ -+#if CFG_SUPPORT_P2P_RSSI_QUERY -+ -+int -+mtk_p2p_wext_get_rssi(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra) -+{ -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ UINT_32 u4QueryInfoLen; -+ struct iw_point *prData = (struct iw_point *)&wrqu->data; -+ UINT_16 u2BufferSize = 0; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ INT_32 i4Rssi; -+ struct iw_statistics *pStats = NULL; -+ -+ ASSERT(prDev); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ ASSERT(prGlueInfo); -+ -+ if (!prGlueInfo) { -+ rStatus = WLAN_STATUS_FAILURE; -+ goto stat_out; -+ } -+ -+ pStats = (struct iw_statistics *)(&(prGlueInfo->rP2pIwStats)); -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidQueryP2pRssi, &i4Rssi, sizeof(i4Rssi), TRUE, TRUE, TRUE, TRUE, &u4QueryInfoLen); -+ -+ u2BufferSize = prData->length; -+ -+ if (u2BufferSize < sizeof(struct iw_statistics)) -+ return -E2BIG; -+ -+ if (copy_to_user(prData->pointer, pStats, sizeof(struct iw_statistics))) -+ rStatus = WLAN_STATUS_FAILURE; -+ -+stat_out: -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) -+ return -EFAULT; -+ else -+ return rStatus; -+ -+} /* mtk_p2p_wext_get_rssi */ -+ -+struct iw_statistics *mtk_p2p_wext_get_wireless_stats(struct net_device *prDev) -+{ -+ WLAN_STATUS rStatus = WLAN_STATUS_FAILURE; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ struct iw_statistics *pStats = NULL; -+ INT_32 i4Rssi; -+ UINT_32 bufLen = 0; -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ ASSERT(prGlueInfo); -+ if (!prGlueInfo) -+ goto stat_out; -+ -+ pStats = (struct iw_statistics *)(&(prGlueInfo->rP2pIwStats)); -+ -+ if (!prDev || !netif_carrier_ok(prDev)) { -+ /* network not connected */ -+ goto stat_out; -+ } -+ -+ rStatus = kalIoctl(prGlueInfo, wlanoidQueryP2pRssi, &i4Rssi, sizeof(i4Rssi), TRUE, TRUE, TRUE, TRUE, &bufLen); -+ -+stat_out: -+ return pStats; -+} /* mtk_p2p_wext_get_wireless_stats */ -+ -+#endif /* CFG_SUPPORT_P2P_RSSI_QUERY */ -+ -+int -+mtk_p2p_wext_set_txpow(IN struct net_device *prDev, -+ IN struct iw_request_info *prIwrInfo, IN OUT union iwreq_data *prTxPow, IN char *pcExtra) -+{ -+ P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) NULL; -+ P_ADAPTER_T prAdapter = (P_ADAPTER_T) NULL; -+#if 0 -+ P_MSG_P2P_FUNCTION_SWITCH_T prMsgFuncSwitch = (P_MSG_P2P_FUNCTION_SWITCH_T) NULL; -+#endif -+ int i4Ret = 0; -+ -+ ASSERT(prDev); -+ ASSERT(prTxPow); -+ -+ do { -+ if ((!prDev) || (!prTxPow)) { -+ i4Ret = -EINVAL; -+ break; -+ } -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ -+ if (!prGlueInfo) { -+ i4Ret = -EINVAL; -+ break; -+ } -+ -+ prAdapter = prGlueInfo->prAdapter; -+#if 0 -+ prMsgFuncSwitch = -+ (P_MSG_P2P_FUNCTION_SWITCH_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, -+ sizeof(MSG_P2P_FUNCTION_SWITCH_T)); -+ if (!prMsgFuncSwitch) { -+ ASSERT(0); -+ return -ENOMEM; -+ } -+ -+ prMsgFuncSwitch->rMsgHdr.eMsgId = MID_MNY_P2P_FUN_SWITCH; -+ -+ if (prTxPow->disabled) { -+ /* Dissolve. */ -+ prMsgFuncSwitch->fgIsFuncOn = FALSE; -+ } else { -+ -+ /* Re-enable function. */ -+ prMsgFuncSwitch->fgIsFuncOn = TRUE; -+ } -+ -+ /* 1.3 send message */ -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgFuncSwitch, MSG_SEND_METHOD_BUF); -+#endif -+ -+ } while (FALSE); -+ -+ return i4Ret; -+} /* mtk_p2p_wext_set_txpow */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_p2p_cfg80211.c b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_p2p_cfg80211.c -new file mode 100644 -index 000000000000..4d71e0c59b05 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_p2p_cfg80211.c -@@ -0,0 +1,1935 @@ -+/* -+** Id: @(#) gl_p2p_cfg80211.c@@ -+*/ -+ -+/*! \file gl_p2p_cfg80211.c -+ \brief Main routines of Linux driver interface for Wi-Fi Direct -+ using cfg80211 interface -+ -+ This file contains the main routines of Linux driver for MediaTek Inc. 802.11 -+ Wireless LAN Adapters. -+*/ -+ -+/* -+** Log: gl_p2p_cfg80211.c -+** -+** 01 30 2013 yuche.tsai -+** [ALPS00455459] [GN_WIFI]??wifi direct??????????? -+** Fix possible race condition under GO mode. -+** -+** 09 12 2012 wcpadmin -+** [ALPS00276400] Remove MTK copyright and legal header on GPL/LGPL related packages -+** . -+** -+** 09 05 2012 wh.su -+** [ALPS00351547] [6577JB][WiFi direct]The 3rd device fail to establish p2p connection with GO sometimes -+** sync with the ICS code. -+** -+** 08 31 2012 yuche.tsai -+** [ALPS00349585] [6577JB][WiFi direct][KE]Establish p2p connection while both device have connected to AP previously, -+** one device reboots automatically with KE -+** Fix possible KE when concurrent & disconnect. -+** -+** 08 21 2012 yuche.tsai -+** NULL -+** Fix compile warning. -+** -+** 08 20 2012 yuche.tsai -+** NULL -+** Fix possible KE issue. -+** -+** 08 17 2012 yuche.tsai -+** NULL -+** Fix compile warning. -+** -+** 08 16 2012 yuche.tsai -+** NULL -+** Fix compile warning. -+** -+** 08 14 2012 yuche.tsai -+** NULL -+** Fix p2p bug find on ALPS.JB trunk. -+** -+** 07 26 2012 yuche.tsai -+** [ALPS00324337] [ALPS.JB][Hot-Spot] Driver update for Hot-Spot -+** Update driver code of ALPS.JB for hot-spot. -+** -+** 07 19 2012 yuche.tsai -+** NULL -+** Code update for JB. -+ * -+ * 07 17 2012 yuche.tsai -+ * NULL -+ * Fix compile error for JB. -+ * -+ * 07 17 2012 yuche.tsai -+ * NULL -+ * Compile no error before trial run. -+ * -+ * 09 21 2010 kevin.huang -+ * [WCXRP00000054] [MT6620 Wi-Fi][Driver] Restructure driver for second Interface -+ * Isolate P2P related function for Hardware Software Bundle -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 05 31 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * add cfg80211 interface, which is to replace WE, for further extension -+ * -+** -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+#include "config.h" -+ -+#if CFG_ENABLE_WIFI_DIRECT && CFG_ENABLE_WIFI_DIRECT_CFG_80211 -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "precomp.h" -+#include "gl_cfg80211.h" -+#include "gl_p2p_ioctl.h" -+ -+#ifdef __GNUC__ -+#pragma GCC diagnostic ignored "-Wformat" -+#endif -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+BOOLEAN -+mtk_p2p_cfg80211func_channel_format_switch(IN struct ieee80211_channel *channel, -+ IN enum nl80211_channel_type channel_type, -+ IN P_RF_CHANNEL_INFO_T prRfChnlInfo, IN P_ENUM_CHNL_EXT_T prChnlSco); -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+int mtk_p2p_cfg80211_add_key(struct wiphy *wiphy, -+ struct net_device *ndev, -+ u8 key_index, bool pairwise, const u8 *mac_addr, struct key_params *params) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ INT_32 i4Rslt = -EINVAL; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ UINT_32 u4BufLen = 0; -+ P2P_PARAM_KEY_T rKey; -+ -+ ASSERT(wiphy); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); -+ -+ kalMemZero(&rKey, sizeof(P2P_PARAM_KEY_T)); -+ -+ rKey.u4KeyIndex = key_index; -+ if (mac_addr) { -+ ether_addr_copy(rKey.arBSSID, mac_addr); -+ if ((rKey.arBSSID[0] == 0x00) && (rKey.arBSSID[1] == 0x00) && (rKey.arBSSID[2] == 0x00) && -+ (rKey.arBSSID[3] == 0x00) && (rKey.arBSSID[4] == 0x00) && (rKey.arBSSID[5] == 0x00)) { -+ rKey.arBSSID[0] = 0xff; -+ rKey.arBSSID[1] = 0xff; -+ rKey.arBSSID[2] = 0xff; -+ rKey.arBSSID[3] = 0xff; -+ rKey.arBSSID[4] = 0xff; -+ rKey.arBSSID[5] = 0xff; -+ } -+ if (rKey.arBSSID[0] != 0xFF) { -+ rKey.u4KeyIndex |= BIT(31); -+ if ((rKey.arBSSID[0] != 0x00) || (rKey.arBSSID[1] != 0x00) || (rKey.arBSSID[2] != 0x00) || -+ (rKey.arBSSID[3] != 0x00) || (rKey.arBSSID[4] != 0x00) || (rKey.arBSSID[5] != 0x00)) -+ rKey.u4KeyIndex |= BIT(30); -+ } else { -+ rKey.u4KeyIndex |= BIT(31); -+ } -+ } else { -+ rKey.arBSSID[0] = 0xff; -+ rKey.arBSSID[1] = 0xff; -+ rKey.arBSSID[2] = 0xff; -+ rKey.arBSSID[3] = 0xff; -+ rKey.arBSSID[4] = 0xff; -+ rKey.arBSSID[5] = 0xff; -+ rKey.u4KeyIndex |= BIT(31); /* ???? */ -+ } -+ if (params->key) { -+ /* rKey.aucKeyMaterial[0] = kalMemAlloc(params->key_len, VIR_MEM_TYPE); */ -+ kalMemCopy(rKey.aucKeyMaterial, params->key, params->key_len); -+ } -+ rKey.u4KeyLength = params->key_len; -+ rKey.u4Length = ((ULONG)&(((P_P2P_PARAM_KEY_T) 0)->aucKeyMaterial)) + rKey.u4KeyLength; -+ -+ rStatus = kalIoctl(prGlueInfo, wlanoidSetAddP2PKey, &rKey, rKey.u4Length, FALSE, FALSE, TRUE, TRUE, &u4BufLen); -+ if (rStatus == WLAN_STATUS_SUCCESS) -+ i4Rslt = 0; -+ -+ return i4Rslt; -+} -+ -+int mtk_p2p_cfg80211_get_key(struct wiphy *wiphy, -+ struct net_device *ndev, -+ u8 key_index, -+ bool pairwise, -+ const u8 *mac_addr, void *cookie, void (*callback) (void *cookie, struct key_params *) -+) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ -+ ASSERT(wiphy); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); -+ -+ /* not implemented yet */ -+ -+ return -EINVAL; -+} -+ -+int mtk_p2p_cfg80211_del_key(struct wiphy *wiphy, -+ struct net_device *ndev, u8 key_index, bool pairwise, const u8 *mac_addr) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ PARAM_REMOVE_KEY_T prRemoveKey; -+ INT_32 i4Rslt = -EINVAL; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ UINT_32 u4BufLen = 0; -+ -+ ASSERT(wiphy); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); -+ -+ if (prGlueInfo->ulFlag & GLUE_FLAG_HALT) { -+ i4Rslt = 0; -+ return i4Rslt; -+ } -+ -+ kalMemZero(&prRemoveKey, sizeof(PARAM_REMOVE_KEY_T)); -+ if (mac_addr) -+ memcpy(prRemoveKey.arBSSID, mac_addr, PARAM_MAC_ADDR_LEN); -+ prRemoveKey.u4KeyIndex = key_index; -+ prRemoveKey.u4Length = sizeof(PARAM_REMOVE_KEY_T); -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetRemoveP2PKey, -+ &prRemoveKey, prRemoveKey.u4Length, FALSE, FALSE, TRUE, TRUE, &u4BufLen); -+ -+ if (rStatus == WLAN_STATUS_SUCCESS) -+ i4Rslt = 0; -+ -+ return i4Rslt; -+} -+ -+int -+mtk_p2p_cfg80211_set_default_key(struct wiphy *wiphy, -+ struct net_device *netdev, u8 key_index, bool unicast, bool multicast) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ -+ ASSERT(wiphy); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); -+ -+ /* not implemented yet */ -+ -+ return WLAN_STATUS_SUCCESS; -+} -+ -+int mtk_p2p_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev, -+ const u8 *mac, struct station_info *sinfo) -+{ -+ INT_32 i4RetRslt = -EINVAL; -+ P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) NULL; -+ P_GL_P2P_INFO_T prP2pGlueInfo = (P_GL_P2P_INFO_T) NULL; -+ P2P_STATION_INFO_T rP2pStaInfo; -+ -+ ASSERT(wiphy); -+ -+ do { -+ if ((wiphy == NULL) || (ndev == NULL) || (sinfo == NULL) || (mac == NULL)) -+ break; -+ -+ DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_get_station\n"); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); -+ prP2pGlueInfo = prGlueInfo->prP2PInfo; -+ -+ sinfo->filled = 0; -+ -+ /* Get station information. */ -+ /* 1. Inactive time? */ -+ p2pFuncGetStationInfo(prGlueInfo->prAdapter, (PUINT_8)mac, &rP2pStaInfo); -+ -+ /* Inactive time. */ -+ sinfo->filled |= NL80211_STA_INFO_INACTIVE_TIME; -+ sinfo->inactive_time = rP2pStaInfo.u4InactiveTime; -+ sinfo->generation = prP2pGlueInfo->i4Generation; -+ -+ i4RetRslt = 0; -+ } while (FALSE); -+ -+ return i4RetRslt; -+} -+ -+int mtk_p2p_cfg80211_scan(struct wiphy *wiphy, struct cfg80211_scan_request *request) -+{ -+ P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) NULL; -+ P_GL_P2P_INFO_T prP2pGlueInfo = (P_GL_P2P_INFO_T) NULL; -+ P_MSG_P2P_SCAN_REQUEST_T prMsgScanRequest = (P_MSG_P2P_SCAN_REQUEST_T) NULL; -+ UINT_32 u4MsgSize = 0, u4Idx = 0; -+ INT_32 i4RetRslt = -EINVAL; -+ P_RF_CHANNEL_INFO_T prRfChannelInfo = (P_RF_CHANNEL_INFO_T) NULL; -+ P_P2P_SSID_STRUCT_T prSsidStruct = (P_P2P_SSID_STRUCT_T) NULL; -+ struct ieee80211_channel *prChannel = NULL; -+ struct cfg80211_ssid *prSsid = NULL; -+ -+ /* [---------Channel---------] [---------SSID---------][---------IE---------] */ -+ DBGLOG(INIT, TRACE, "mtk_p2p_cfg80211_scan\n"); -+ -+ do { -+ if ((wiphy == NULL) || (request == NULL)) -+ break; -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); -+ -+ prP2pGlueInfo = prGlueInfo->prP2PInfo; -+ -+ if (prP2pGlueInfo == NULL) { -+ ASSERT(FALSE); -+ break; -+ } -+ -+ DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_scan.\n"); -+ -+ if (prP2pGlueInfo->prScanRequest != NULL) { -+ /* There have been a scan request on-going processing. */ -+ DBGLOG(P2P, TRACE, "There have been a scan request on-going processing.\n"); -+ break; -+ } -+ -+ prP2pGlueInfo->prScanRequest = request; -+ -+ /* Should find out why the n_channels so many? */ -+ if (request->n_channels > MAXIMUM_OPERATION_CHANNEL_LIST) { -+ request->n_channels = MAXIMUM_OPERATION_CHANNEL_LIST; -+ DBGLOG(P2P, TRACE, "Channel list exceed the maximun support.\n"); -+ } -+ -+ u4MsgSize = sizeof(MSG_P2P_SCAN_REQUEST_T) + -+ (request->n_channels * sizeof(RF_CHANNEL_INFO_T)) + -+ (request->n_ssids * sizeof(PARAM_SSID_T)) + request->ie_len; -+ -+ prMsgScanRequest = cnmMemAlloc(prGlueInfo->prAdapter, RAM_TYPE_MSG, u4MsgSize); -+ -+ if (prMsgScanRequest == NULL) { -+ ASSERT(FALSE); -+ i4RetRslt = -ENOMEM; -+ prP2pGlueInfo->prScanRequest = NULL; -+ DBGLOG(INIT, TRACE, "mtk_p2p_cfg80211_scan Allocate Mem failed\n"); -+ break; -+ } -+ -+ DBGLOG(P2P, TRACE, "Generating scan request message.\n"); -+ -+ prMsgScanRequest->rMsgHdr.eMsgId = MID_MNY_P2P_DEVICE_DISCOVERY; -+ -+ DBGLOG(P2P, INFO, "Requesting channel number:%d.\n", request->n_channels); -+ -+ for (u4Idx = 0; u4Idx < request->n_channels; u4Idx++) { -+ /* Translate Freq from MHz to channel number. */ -+ prRfChannelInfo = &(prMsgScanRequest->arChannelListInfo[u4Idx]); -+ prChannel = request->channels[u4Idx]; -+ -+ prRfChannelInfo->ucChannelNum = nicFreq2ChannelNum(prChannel->center_freq * 1000); -+ DBGLOG(P2P, TRACE, "Scanning Channel:%d, freq: %d\n", -+ prRfChannelInfo->ucChannelNum, prChannel->center_freq); -+ switch (prChannel->band) { -+ case NL80211_BAND_2GHZ: -+ prRfChannelInfo->eBand = BAND_2G4; -+ break; -+ case NL80211_BAND_5GHZ: -+ prRfChannelInfo->eBand = BAND_5G; -+ break; -+ default: -+ DBGLOG(P2P, TRACE, "UNKNOWN Band info from supplicant\n"); -+ prRfChannelInfo->eBand = BAND_NULL; -+ break; -+ } -+ -+ /* Iteration. */ -+ prRfChannelInfo++; -+ } -+ prMsgScanRequest->u4NumChannel = request->n_channels; -+ -+ DBGLOG(P2P, TRACE, "Finish channel list.\n"); -+ -+ /* SSID */ -+ prSsid = request->ssids; -+ prSsidStruct = (P_P2P_SSID_STRUCT_T) prRfChannelInfo; -+ if (prSsidStruct) { -+ if (request->n_ssids) { -+ ASSERT((ULONG) prSsidStruct == (ULONG)&(prMsgScanRequest->arChannelListInfo[u4Idx])); -+ prMsgScanRequest->prSSID = prSsidStruct; -+ } -+ -+ for (u4Idx = 0; u4Idx < request->n_ssids; u4Idx++) { -+ COPY_SSID(prSsidStruct->aucSsid, -+ prSsidStruct->ucSsidLen, request->ssids->ssid, request->ssids->ssid_len); -+ -+ prSsidStruct++; -+ prSsid++; -+ } -+ -+ prMsgScanRequest->i4SsidNum = request->n_ssids; -+ -+ DBGLOG(P2P, TRACE, "Finish SSID list:%d.\n", request->n_ssids); -+ -+ /* IE BUFFERS */ -+ prMsgScanRequest->pucIEBuf = (PUINT_8) prSsidStruct; -+ if (request->ie_len) { -+ kalMemCopy(prMsgScanRequest->pucIEBuf, request->ie, request->ie_len); -+ prMsgScanRequest->u4IELen = request->ie_len; -+ } -+ } -+ -+ DBGLOG(P2P, TRACE, "Finish IE Buffer.\n"); -+#if CFG_AUTO_CHANNEL_SEL_SUPPORT -+ prGlueInfo->prAdapter->rWifiVar.rChnLoadInfo.fgDataReadyBit = FALSE; -+#endif -+ mboxSendMsg(prGlueInfo->prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgScanRequest, MSG_SEND_METHOD_BUF); -+ -+ i4RetRslt = 0; -+ } while (FALSE); -+ -+ return i4RetRslt; -+} /* mtk_p2p_cfg80211_scan */ -+ -+int mtk_p2p_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed) -+{ -+ INT_32 i4Rslt = -EINVAL; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ -+ do { -+ if (wiphy == NULL) -+ break; -+ -+ DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_set_wiphy_params\n"); -+ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); -+ -+ if (changed & WIPHY_PARAM_RETRY_SHORT) { -+ /* TODO: */ -+ DBGLOG(P2P, TRACE, "The RETRY short param is changed.\n"); -+ } -+ -+ if (changed & WIPHY_PARAM_RETRY_LONG) { -+ /* TODO: */ -+ DBGLOG(P2P, TRACE, "The RETRY long param is changed.\n"); -+ } -+ -+ if (changed & WIPHY_PARAM_FRAG_THRESHOLD) { -+ /* TODO: */ -+ DBGLOG(P2P, TRACE, "The RETRY fragmentation threshold is changed.\n"); -+ } -+ -+ if (changed & WIPHY_PARAM_RTS_THRESHOLD) { -+ /* TODO: */ -+ DBGLOG(P2P, TRACE, "The RETRY RTS threshold is changed.\n"); -+ } -+ -+ if (changed & WIPHY_PARAM_COVERAGE_CLASS) { -+ /* TODO: */ -+ DBGLOG(P2P, TRACE, "The coverage class is changed???\n"); -+ } -+ -+ i4Rslt = 0; -+ } while (FALSE); -+ -+ return i4Rslt; -+} /* mtk_p2p_cfg80211_set_wiphy_params */ -+ -+int mtk_p2p_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_ibss_params *params) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ -+ ASSERT(wiphy); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); -+ -+ /* not implemented yet */ -+ -+ return -EINVAL; -+} -+ -+int mtk_p2p_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ -+ ASSERT(wiphy); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); -+ -+ /* not implemented yet */ -+ -+ return -EINVAL; -+} -+ -+int mtk_p2p_cfg80211_set_txpower(struct wiphy *wiphy, -+ struct wireless_dev *wdev, -+ enum nl80211_tx_power_setting type, int mbm) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ -+ ASSERT(wiphy); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); -+ -+ /* not implemented yet */ -+ -+ return -EINVAL; -+} -+ -+int mtk_p2p_cfg80211_get_txpower(struct wiphy *wiphy, -+ struct wireless_dev *wdev, -+ int *dbm) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ -+ ASSERT(wiphy); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); -+ -+ /* not implemented yet */ -+ -+ return -EINVAL; -+} -+ -+int mtk_p2p_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev, bool enabled, int timeout) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ INT_32 value; -+ UINT_32 u4Leng; -+ -+ ASSERT(wiphy); -+ -+ if (enabled) -+ value = 2; -+ else -+ value = 0; -+ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); -+ DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_set_power_mgmt ps=%d.\n", enabled); -+ -+ /* p2p_set_power_save */ -+ kalIoctl(prGlueInfo, wlanoidSetP2pPowerSaveProfile, &value, sizeof(value), FALSE, FALSE, TRUE, TRUE, &u4Leng); -+ return 0; -+} -+ -+/* &&&&&&&&&&&&&&&&&&&&&&&&&& Add for ICS Wi-Fi Direct Support. &&&&&&&&&&&&&&&&&&&&&&& */ -+int mtk_p2p_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_ap_settings *settings) -+{ -+ P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) NULL; -+ INT_32 i4Rslt = -EINVAL; -+ P_MSG_P2P_BEACON_UPDATE_T prP2pBcnUpdateMsg = (P_MSG_P2P_BEACON_UPDATE_T) NULL; -+ P_MSG_P2P_START_AP_T prP2pStartAPMsg = (P_MSG_P2P_START_AP_T) NULL; -+ PUINT_8 pucBuffer = (PUINT_8) NULL; -+ /* P_IE_SSID_T prSsidIE = (P_IE_SSID_T)NULL; */ -+ -+ struct wireless_dev *wdev = dev->ieee80211_ptr; -+ struct cfg80211_chan_def *chandef = &wdev->preset_chandef; -+ -+ do { -+ if ((wiphy == NULL) || (settings == NULL)) -+ break; -+ -+ DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_start_ap.\n"); -+ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); -+ -+#if 1 -+ mtk_p2p_cfg80211_set_channel(wiphy, chandef); -+#else -+ prGlueInfo->prAdapter->rWifiVar.prP2PConnSettings->ucOperatingChnl = -+ (chandef->chan->center_freq - 2407) / 5; -+ prGlueInfo->prAdapter->rWifiVar.prP2PConnSettings->eBand = BAND_2G4; -+#endif -+ -+ prP2pBcnUpdateMsg = (P_MSG_P2P_BEACON_UPDATE_T) cnmMemAlloc(prGlueInfo->prAdapter, -+ RAM_TYPE_MSG, -+ (sizeof(MSG_P2P_BEACON_UPDATE_T) + -+ settings->beacon.head_len + -+ settings->beacon.tail_len)); -+ -+ if (prP2pBcnUpdateMsg == NULL) { -+ ASSERT(FALSE); -+ i4Rslt = -ENOMEM; -+ break; -+ } -+ -+ prP2pBcnUpdateMsg->rMsgHdr.eMsgId = MID_MNY_P2P_BEACON_UPDATE; -+ pucBuffer = prP2pBcnUpdateMsg->aucBuffer; -+ -+ if (settings->beacon.head_len != 0) { -+ kalMemCopy(pucBuffer, settings->beacon.head, settings->beacon.head_len); -+ -+ prP2pBcnUpdateMsg->u4BcnHdrLen = settings->beacon.head_len; -+ -+ prP2pBcnUpdateMsg->pucBcnHdr = pucBuffer; -+ -+ pucBuffer = (PUINT_8) ((ULONG) pucBuffer + (UINT_32) settings->beacon.head_len); -+ } else { -+ prP2pBcnUpdateMsg->u4BcnHdrLen = 0; -+ -+ prP2pBcnUpdateMsg->pucBcnHdr = NULL; -+ } -+ -+ if (settings->beacon.tail_len != 0) { -+ UINT_32 ucLen = settings->beacon.tail_len; -+ -+ prP2pBcnUpdateMsg->pucBcnBody = pucBuffer; -+ -+ /*Add TIM IE */ -+ /* IEEE 802.11 2007 - 7.3.2.6 */ -+ TIM_IE(pucBuffer)->ucId = ELEM_ID_TIM; -+ TIM_IE(pucBuffer)->ucLength = (3 + MAX_LEN_TIM_PARTIAL_BMP) /*((u4N2 - u4N1) + 4) */; -+ /* NOTE: fixed PVB length (AID is allocated from 8 ~ 15 only) */ -+ TIM_IE(pucBuffer)->ucDTIMCount = 0 /*prBssInfo->ucDTIMCount */; /* will be overwrite by FW */ -+ TIM_IE(pucBuffer)->ucDTIMPeriod = 1; -+ TIM_IE(pucBuffer)->ucBitmapControl = 0 /*ucBitmapControl | (UINT_8)u4N1 */; -+ /* will be overwrite by FW */ -+ ucLen += IE_SIZE(pucBuffer); -+ pucBuffer += IE_SIZE(pucBuffer); -+ -+ kalMemCopy(pucBuffer, settings->beacon.tail, settings->beacon.tail_len); -+ -+ prP2pBcnUpdateMsg->u4BcnBodyLen = ucLen; -+ } else { -+ prP2pBcnUpdateMsg->u4BcnBodyLen = 0; -+ -+ prP2pBcnUpdateMsg->pucBcnBody = NULL; -+ } -+ -+ mboxSendMsg(prGlueInfo->prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prP2pBcnUpdateMsg, MSG_SEND_METHOD_BUF); -+ -+ prP2pStartAPMsg = (P_MSG_P2P_START_AP_T) cnmMemAlloc(prGlueInfo->prAdapter, -+ RAM_TYPE_MSG, sizeof(MSG_P2P_START_AP_T)); -+ -+ if (prP2pStartAPMsg == NULL) { -+ ASSERT(FALSE); -+ i4Rslt = -ENOMEM; -+ break; -+ } -+ -+ prP2pStartAPMsg->rMsgHdr.eMsgId = MID_MNY_P2P_START_AP; -+ -+ prP2pStartAPMsg->fgIsPrivacy = settings->privacy; -+ -+ prP2pStartAPMsg->u4BcnInterval = settings->beacon_interval; -+ -+ prP2pStartAPMsg->u4DtimPeriod = settings->dtim_period; -+ -+ /* Copy NO SSID. */ -+ prP2pStartAPMsg->ucHiddenSsidType = settings->hidden_ssid; -+ -+ COPY_SSID(prP2pStartAPMsg->aucSsid, prP2pStartAPMsg->u2SsidLen, settings->ssid, settings->ssid_len); -+ -+ mboxSendMsg(prGlueInfo->prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prP2pStartAPMsg, MSG_SEND_METHOD_BUF); -+ -+ i4Rslt = 0; -+#if CFG_SPM_WORKAROUND_FOR_HOTSPOT -+ if (glIsChipNeedWakelock(prGlueInfo)) -+ KAL_WAKE_LOCK(prGlueInfo->prAdapter, &prGlueInfo->prAdapter->rApWakeLock); -+#endif -+ -+ } while (FALSE); -+ -+ return i4Rslt; -+ -+/* /////////////////////// */ -+ /** -+ * struct cfg80211_ap_settings - AP configuration -+ * -+ * Used to configure an AP interface. -+ * -+ * @beacon: beacon data -+ * @beacon_interval: beacon interval -+ * @dtim_period: DTIM period -+ * @ssid: SSID to be used in the BSS (note: may be %NULL if not provided from -+ * user space) -+ * @ssid_len: length of @ssid -+ * @hidden_ssid: whether to hide the SSID in Beacon/Probe Response frames -+ * @crypto: crypto settings -+ * @privacy: the BSS uses privacy -+ * @auth_type: Authentication type (algorithm) -+ * @inactivity_timeout: time in seconds to determine station's inactivity. -+ */ -+/* struct cfg80211_ap_settings { */ -+/* struct cfg80211_beacon_data beacon; */ -+/* */ -+/* int beacon_interval, dtim_period; */ -+/* const u8 *ssid; */ -+/* size_t ssid_len; */ -+/* enum nl80211_hidden_ssid hidden_ssid; */ -+/* struct cfg80211_crypto_settings crypto; */ -+/* bool privacy; */ -+/* enum nl80211_auth_type auth_type; */ -+/* int inactivity_timeout; */ -+/* }; */ -+/* ////////////////// */ -+ -+ return i4Rslt; -+} /* mtk_p2p_cfg80211_start_ap */ -+ -+int mtk_p2p_cfg80211_change_beacon(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_beacon_data *info) -+{ -+ P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) NULL; -+ INT_32 i4Rslt = -EINVAL; -+ P_MSG_P2P_BEACON_UPDATE_T prP2pBcnUpdateMsg = (P_MSG_P2P_BEACON_UPDATE_T) NULL; -+ PUINT_8 pucBuffer = (PUINT_8) NULL; -+ -+ do { -+ if ((wiphy == NULL) || (info == NULL)) -+ break; -+ -+ DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_change_beacon.\n"); -+ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); -+ -+ prP2pBcnUpdateMsg = (P_MSG_P2P_BEACON_UPDATE_T) cnmMemAlloc(prGlueInfo->prAdapter, -+ RAM_TYPE_MSG, -+ (sizeof(MSG_P2P_BEACON_UPDATE_T) + -+ info->head_len + info->tail_len)); -+ -+ if (prP2pBcnUpdateMsg == NULL) { -+ ASSERT(FALSE); -+ i4Rslt = -ENOMEM; -+ break; -+ } -+ -+ prP2pBcnUpdateMsg->rMsgHdr.eMsgId = MID_MNY_P2P_BEACON_UPDATE; -+ pucBuffer = prP2pBcnUpdateMsg->aucBuffer; -+ -+ if (info->head_len != 0) { -+ kalMemCopy(pucBuffer, info->head, info->head_len); -+ -+ prP2pBcnUpdateMsg->u4BcnHdrLen = info->head_len; -+ -+ prP2pBcnUpdateMsg->pucBcnHdr = pucBuffer; -+ -+ pucBuffer = (PUINT_8) ((ULONG) pucBuffer + (UINT_32) info->head_len); -+ } else { -+ prP2pBcnUpdateMsg->u4BcnHdrLen = 0; -+ -+ prP2pBcnUpdateMsg->pucBcnHdr = NULL; -+ } -+ -+ if (info->tail_len != 0) { -+ UINT_32 ucLen = info->tail_len; -+ -+ prP2pBcnUpdateMsg->pucBcnBody = pucBuffer; -+ -+ /*Add TIM IE */ -+ /* IEEE 802.11 2007 - 7.3.2.6 */ -+ TIM_IE(pucBuffer)->ucId = ELEM_ID_TIM; -+ TIM_IE(pucBuffer)->ucLength = (3 + MAX_LEN_TIM_PARTIAL_BMP) /*((u4N2 - u4N1) + 4) */; -+ /* NOTE: fixed PVB length (AID is allocated from 8 ~ 15 only) */ -+ TIM_IE(pucBuffer)->ucDTIMCount = 0 /*prBssInfo->ucDTIMCount */; /* will be overwrite by FW */ -+ TIM_IE(pucBuffer)->ucDTIMPeriod = 1; -+ TIM_IE(pucBuffer)->ucBitmapControl = 0 /*ucBitmapControl | (UINT_8)u4N1 */; -+ /* will be overwrite by FW */ -+ ucLen += IE_SIZE(pucBuffer); -+ pucBuffer += IE_SIZE(pucBuffer); -+ -+ kalMemCopy(pucBuffer, info->tail, info->tail_len); -+ -+ prP2pBcnUpdateMsg->u4BcnBodyLen = ucLen; -+ } else { -+ prP2pBcnUpdateMsg->u4BcnBodyLen = 0; -+ -+ prP2pBcnUpdateMsg->pucBcnBody = NULL; -+ } -+ -+ mboxSendMsg(prGlueInfo->prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prP2pBcnUpdateMsg, MSG_SEND_METHOD_BUF); -+ -+/* ////////////////////////// */ -+/** -+ * struct cfg80211_beacon_data - beacon data -+ * @head: head portion of beacon (before TIM IE) -+ * or %NULL if not changed -+ * @tail: tail portion of beacon (after TIM IE) -+ * or %NULL if not changed -+ * @head_len: length of @head -+ * @tail_len: length of @tail -+ * @beacon_ies: extra information element(s) to add into Beacon frames or %NULL -+ * @beacon_ies_len: length of beacon_ies in octets -+ * @proberesp_ies: extra information element(s) to add into Probe Response -+ * frames or %NULL -+ * @proberesp_ies_len: length of proberesp_ies in octets -+ * @assocresp_ies: extra information element(s) to add into (Re)Association -+ * Response frames or %NULL -+ * @assocresp_ies_len: length of assocresp_ies in octets -+ * @probe_resp_len: length of probe response template (@probe_resp) -+ * @probe_resp: probe response template (AP mode only) -+ */ -+/* struct cfg80211_beacon_data { */ -+/* const u8 *head, *tail; */ -+/* const u8 *beacon_ies; */ -+/* const u8 *proberesp_ies; */ -+/* const u8 *assocresp_ies; */ -+/* const u8 *probe_resp; */ -+ -+/* size_t head_len, tail_len; */ -+/* size_t beacon_ies_len; */ -+/* size_t proberesp_ies_len; */ -+/* size_t assocresp_ies_len; */ -+/* size_t probe_resp_len; */ -+/* }; */ -+ -+/* ////////////////////////// */ -+ -+ } while (FALSE); -+ -+ return i4Rslt; -+} /* mtk_p2p_cfg80211_change_beacon */ -+ -+int mtk_p2p_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *dev) -+{ -+ P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) NULL; -+ INT_32 i4Rslt = -EINVAL; -+ P_MSG_P2P_SWITCH_OP_MODE_T prP2pSwitchMode = (P_MSG_P2P_SWITCH_OP_MODE_T) NULL; -+ -+ do { -+ if (wiphy == NULL) -+ break; -+ -+ DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_stop_ap.\n"); -+ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); -+ -+ /* Switch OP MOde. */ -+ prP2pSwitchMode = cnmMemAlloc(prGlueInfo->prAdapter, RAM_TYPE_MSG, sizeof(MSG_P2P_SWITCH_OP_MODE_T)); -+ -+ if (prP2pSwitchMode == NULL) { -+ ASSERT(FALSE); -+ i4Rslt = -ENOMEM; -+ break; -+ } -+ -+ prP2pSwitchMode->rMsgHdr.eMsgId = MID_MNY_P2P_STOP_AP; -+ -+ mboxSendMsg(prGlueInfo->prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prP2pSwitchMode, MSG_SEND_METHOD_BUF); -+ -+ i4Rslt = 0; -+#if CFG_SPM_WORKAROUND_FOR_HOTSPOT -+ if (glIsChipNeedWakelock(prGlueInfo)) -+ KAL_WAKE_UNLOCK(prGlueInfo->prAdapter, &prGlueInfo->prAdapter->rApWakeLock); -+#endif -+ } while (FALSE); -+ -+ return i4Rslt; -+} /* mtk_p2p_cfg80211_stop_ap */ -+ -+/* TODO: */ -+int mtk_p2p_cfg80211_deauth(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_deauth_request *req) -+{ -+ P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) NULL; -+ -+ ASSERT(wiphy); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); -+ -+ /* not implemented yet */ -+ DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_deauth.\n"); -+ -+ return -EINVAL; -+} /* mtk_p2p_cfg80211_deauth */ -+ -+/* TODO: */ -+int mtk_p2p_cfg80211_disassoc(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_disassoc_request *req) -+{ -+ P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) NULL; -+ -+ ASSERT(wiphy); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); -+ -+ DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_disassoc.\n"); -+ -+ /* not implemented yet */ -+ -+ return -EINVAL; -+} /* mtk_p2p_cfg80211_disassoc */ -+ -+int mtk_p2p_cfg80211_remain_on_channel(struct wiphy *wiphy, -+ struct wireless_dev *wdev, -+ struct ieee80211_channel *chan, -+ unsigned int duration, u64 *cookie) -+{ -+ INT_32 i4Rslt = -EINVAL; -+ P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) NULL; -+ P_GL_P2P_INFO_T prGlueP2pInfo = (P_GL_P2P_INFO_T) NULL; -+ P_MSG_P2P_CHNL_REQUEST_T prMsgChnlReq = (P_MSG_P2P_CHNL_REQUEST_T) NULL; -+ -+ do { -+ if ((wiphy == NULL) || (wdev == NULL) || (chan == NULL) || (cookie == NULL)) -+ break; -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); -+ prGlueP2pInfo = prGlueInfo->prP2PInfo; -+ -+ *cookie = prGlueP2pInfo->u8Cookie++; -+ -+ prMsgChnlReq = cnmMemAlloc(prGlueInfo->prAdapter, RAM_TYPE_MSG, sizeof(MSG_P2P_CHNL_REQUEST_T)); -+ -+ if (prMsgChnlReq == NULL) { -+ ASSERT(FALSE); -+ i4Rslt = -ENOMEM; -+ break; -+ } -+ -+ DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_remain_on_channel\n"); -+ -+ prMsgChnlReq->rMsgHdr.eMsgId = MID_MNY_P2P_CHNL_REQ; -+ prMsgChnlReq->u8Cookie = *cookie; -+ prMsgChnlReq->u4Duration = duration; -+ -+ mtk_p2p_cfg80211func_channel_format_switch(chan, NL80211_CHAN_HT20, /* 4 KH Need Check */ -+ &prMsgChnlReq->rChannelInfo, &prMsgChnlReq->eChnlSco); -+ -+ mboxSendMsg(prGlueInfo->prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgChnlReq, MSG_SEND_METHOD_BUF); -+ -+ i4Rslt = 0; -+ -+ i4Rslt = 0; -+ } while (FALSE); -+ -+ return i4Rslt; -+} -+ -+/* mtk_p2p_cfg80211_remain_on_channel */ -+int mtk_p2p_cfg80211_cancel_remain_on_channel(struct wiphy *wiphy, -+ struct wireless_dev *wdev, -+ u64 cookie) -+{ -+ INT_32 i4Rslt = -EINVAL; -+ P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) NULL; -+ P_MSG_P2P_CHNL_ABORT_T prMsgChnlAbort = (P_MSG_P2P_CHNL_ABORT_T) NULL; -+ -+ do { -+ if ((wiphy == NULL) || (wdev == NULL)) -+ break; -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); -+ -+ prMsgChnlAbort = cnmMemAlloc(prGlueInfo->prAdapter, RAM_TYPE_MSG, sizeof(MSG_P2P_CHNL_ABORT_T)); -+ -+ if (prMsgChnlAbort == NULL) { -+ ASSERT(FALSE); -+ i4Rslt = -ENOMEM; -+ break; -+ } -+ -+ DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_cancel_remain_on_channel\n"); -+ -+ prMsgChnlAbort->rMsgHdr.eMsgId = MID_MNY_P2P_CHNL_ABORT; -+ prMsgChnlAbort->u8Cookie = cookie; -+ -+ mboxSendMsg(prGlueInfo->prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgChnlAbort, MSG_SEND_METHOD_BUF); -+ -+ i4Rslt = 0; -+ } while (FALSE); -+ -+ return i4Rslt; -+} /* mtk_p2p_cfg80211_cancel_remain_on_channel */ -+ -+int mtk_p2p_cfg80211_mgmt_tx(struct wiphy *wiphy, -+ struct wireless_dev *wdev, -+ struct cfg80211_mgmt_tx_params *params, -+ u64 *cookie) -+{ -+ P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) NULL; -+ P_GL_P2P_INFO_T prGlueP2pInfo = (P_GL_P2P_INFO_T) NULL; -+ INT_32 i4Rslt = -EINVAL; -+ struct _MSG_P2P_EXTEND_LISTEN_INTERVAL_T *prMsgExtListenReq = NULL; -+ P_MSG_P2P_MGMT_TX_REQUEST_T prMsgTxReq = (P_MSG_P2P_MGMT_TX_REQUEST_T) NULL; -+ P_MSDU_INFO_T prMgmtFrame = (P_MSDU_INFO_T) NULL; -+ PUINT_8 pucFrameBuf = (PUINT_8) NULL; -+ -+ do { -+ if ((wiphy == NULL) || (wdev == NULL) || (params == 0) || (cookie == NULL)) -+ break; -+ /* DBGLOG(P2P, TRACE, ("mtk_p2p_cfg80211_mgmt_tx\n")); */ -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); -+ prGlueP2pInfo = prGlueInfo->prP2PInfo; -+ -+ *cookie = prGlueP2pInfo->u8Cookie++; -+ -+ /* Channel & Channel Type & Wait time are ignored. */ -+ prMsgTxReq = cnmMemAlloc(prGlueInfo->prAdapter, RAM_TYPE_MSG, sizeof(MSG_P2P_MGMT_TX_REQUEST_T)); -+ -+ if (prMsgTxReq == NULL) { -+ ASSERT(FALSE); -+ i4Rslt = -ENOMEM; -+ break; -+ } -+ -+ /* Here need to extend the listen interval */ -+ prMsgExtListenReq = cnmMemAlloc(prGlueInfo->prAdapter, RAM_TYPE_MSG, -+ sizeof(struct _MSG_P2P_EXTEND_LISTEN_INTERVAL_T)); -+ if (prMsgExtListenReq) { -+ prMsgExtListenReq->rMsgHdr.eMsgId = MID_MNY_P2P_EXTEND_LISTEN_INTERVAL; -+ prMsgExtListenReq->wait = params->wait; -+ DBGLOG(P2P, INFO, "ext listen, wait: %d\n", prMsgExtListenReq->wait); -+ mboxSendMsg(prGlueInfo->prAdapter, MBOX_ID_0, (P_MSG_HDR_T)prMsgExtListenReq, -+ MSG_SEND_METHOD_BUF); -+ } -+ -+ prMsgTxReq->fgNoneCckRate = FALSE; -+ prMsgTxReq->fgIsWaitRsp = TRUE; -+ -+ prMgmtFrame = cnmMgtPktAlloc(prGlueInfo->prAdapter, (UINT_32) (params->len + MAC_TX_RESERVED_FIELD)); -+ -+ prMsgTxReq->prMgmtMsduInfo = prMgmtFrame; -+ if (prMsgTxReq->prMgmtMsduInfo == NULL) { -+ ASSERT(FALSE); -+ i4Rslt = -ENOMEM; -+ break; -+ } -+ -+ prMsgTxReq->u8Cookie = *cookie; -+ prMsgTxReq->rMsgHdr.eMsgId = MID_MNY_P2P_MGMT_TX; -+ -+ pucFrameBuf = (PUINT_8) ((ULONG) prMgmtFrame->prPacket + MAC_TX_RESERVED_FIELD); -+ -+ kalMemCopy(pucFrameBuf, params->buf, params->len); -+ -+ prMgmtFrame->u2FrameLength = params->len; -+ -+ mboxSendMsg(prGlueInfo->prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgTxReq, MSG_SEND_METHOD_BUF); -+ -+ i4Rslt = 0; -+ } while (FALSE); -+ -+ if ((i4Rslt != 0) && (prMsgTxReq != NULL)) { -+ if (prMsgTxReq->prMgmtMsduInfo != NULL) -+ cnmMgtPktFree(prGlueInfo->prAdapter, prMsgTxReq->prMgmtMsduInfo); -+ -+ cnmMemFree(prGlueInfo->prAdapter, prMsgTxReq); -+ } -+ -+ return i4Rslt; -+} /* mtk_p2p_cfg80211_mgmt_tx */ -+ -+int mtk_p2p_cfg80211_change_bss(struct wiphy *wiphy, struct net_device *dev, struct bss_parameters *params) -+{ -+ P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) NULL; -+ INT_32 i4Rslt = -EINVAL; -+ -+ ASSERT(wiphy); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); -+ -+ switch (params->use_cts_prot) { -+ case -1: -+ DBGLOG(P2P, TRACE, "CTS protection no change\n"); -+ break; -+ case 0: -+ DBGLOG(P2P, TRACE, "CTS protection disable.\n"); -+ break; -+ case 1: -+ DBGLOG(P2P, TRACE, "CTS protection enable\n"); -+ break; -+ default: -+ DBGLOG(P2P, TRACE, "CTS protection unknown\n"); -+ break; -+ } -+ -+ switch (params->use_short_preamble) { -+ case -1: -+ DBGLOG(P2P, TRACE, "Short prreamble no change\n"); -+ break; -+ case 0: -+ DBGLOG(P2P, TRACE, "Short prreamble disable.\n"); -+ break; -+ case 1: -+ DBGLOG(P2P, TRACE, "Short prreamble enable\n"); -+ break; -+ default: -+ DBGLOG(P2P, TRACE, "Short prreamble unknown\n"); -+ break; -+ } -+ -+#if 0 -+ /* not implemented yet */ -+ p2pFuncChangeBssParam(prGlueInfo->prAdapter, -+ prBssInfo->fgIsProtection, -+ prBssInfo->fgIsShortPreambleAllowed, prBssInfo->fgUseShortSlotTime, -+ /* Basic rates */ -+ /* basic rates len */ -+ /* ap isolate */ -+ /* ht opmode. */ -+ ); -+#else -+ i4Rslt = 0; -+#endif -+ -+ return i4Rslt; -+} /* mtk_p2p_cfg80211_change_bss */ -+ -+int mtk_p2p_cfg80211_del_station(struct wiphy *wiphy, struct net_device *dev, struct station_del_parameters *params) -+//int mtk_p2p_cfg80211_del_station(struct wiphy *wiphy, struct net_device *dev, const u8 *mac) -+{ -+ P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) NULL; -+ INT_32 i4Rslt = -EINVAL; -+ P_MSG_P2P_CONNECTION_ABORT_T prDisconnectMsg = (P_MSG_P2P_CONNECTION_ABORT_T) NULL; -+ UINT_8 aucBcMac[] = BC_MAC_ADDR; -+ const UINT_8 *mac = NULL; -+ -+ do { -+ if ((wiphy == NULL) || (dev == NULL)) -+ break; -+ -+ if (params->mac == NULL) -+ mac = aucBcMac; -+ else -+ mac = params->mac; -+ -+ DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_del_station.\n"); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); -+ -+ /* prDisconnectMsg = (P_MSG_P2P_CONNECTION_ABORT_T)kalMemAlloc(sizeof(MSG_P2P_CONNECTION_ABORT_T), -+ VIR_MEM_TYPE); */ -+ prDisconnectMsg = -+ (P_MSG_P2P_CONNECTION_ABORT_T) cnmMemAlloc(prGlueInfo->prAdapter, RAM_TYPE_MSG, -+ sizeof(MSG_P2P_CONNECTION_ABORT_T)); -+ -+ if (prDisconnectMsg == NULL) { -+ ASSERT(FALSE); -+ i4Rslt = -ENOMEM; -+ break; -+ } -+ -+ prDisconnectMsg->rMsgHdr.eMsgId = MID_MNY_P2P_CONNECTION_ABORT; -+ COPY_MAC_ADDR(prDisconnectMsg->aucTargetID, mac); -+ prDisconnectMsg->u2ReasonCode = REASON_CODE_UNSPECIFIED; -+ -+ mboxSendMsg(prGlueInfo->prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prDisconnectMsg, MSG_SEND_METHOD_BUF); -+ -+ i4Rslt = 0; -+ } while (FALSE); -+ -+ return i4Rslt; -+ -+} /* mtk_p2p_cfg80211_del_station */ -+ -+int mtk_p2p_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_connect_params *sme) -+{ -+ INT_32 i4Rslt = -EINVAL; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ P_MSG_P2P_CONNECTION_REQUEST_T prConnReqMsg = (P_MSG_P2P_CONNECTION_REQUEST_T) NULL; -+ -+ do { -+ if ((wiphy == NULL) || (dev == NULL) || (sme == NULL)) -+ break; -+ -+ DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_connect.\n"); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); -+ -+ prConnReqMsg = -+ (P_MSG_P2P_CONNECTION_REQUEST_T) cnmMemAlloc(prGlueInfo->prAdapter, RAM_TYPE_MSG, -+ (sizeof(MSG_P2P_CONNECTION_REQUEST_T) + sme->ie_len)); -+ -+ if (prConnReqMsg == NULL) { -+ ASSERT(FALSE); -+ i4Rslt = -ENOMEM; -+ break; -+ } -+ -+ prConnReqMsg->rMsgHdr.eMsgId = MID_MNY_P2P_CONNECTION_REQ; -+ -+ COPY_SSID(prConnReqMsg->rSsid.aucSsid, prConnReqMsg->rSsid.ucSsidLen, sme->ssid, sme->ssid_len); -+ -+ COPY_MAC_ADDR(prConnReqMsg->aucBssid, sme->bssid); -+ DBGLOG(P2P, INFO, "mtk_p2p_cfg80211_connect to %pM, IE len: %d\n", -+ prConnReqMsg->aucBssid, sme->ie_len); -+ -+ DBGLOG(P2P, TRACE, "Assoc Req IE Buffer Length:%d\n", sme->ie_len); -+ kalMemCopy(prConnReqMsg->aucIEBuf, sme->ie, sme->ie_len); -+ prConnReqMsg->u4IELen = sme->ie_len; -+ -+ mtk_p2p_cfg80211func_channel_format_switch(sme->channel, -+ NL80211_CHAN_NO_HT, -+ &prConnReqMsg->rChannelInfo, &prConnReqMsg->eChnlSco); -+ -+ mboxSendMsg(prGlueInfo->prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prConnReqMsg, MSG_SEND_METHOD_BUF); -+ -+ i4Rslt = 0; -+ } while (FALSE); -+ -+ return i4Rslt; -+} /* mtk_p2p_cfg80211_connect */ -+ -+int mtk_p2p_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev, u16 reason_code) -+{ -+ INT_32 i4Rslt = -EINVAL; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ P_MSG_P2P_CONNECTION_ABORT_T prDisconnMsg = (P_MSG_P2P_CONNECTION_ABORT_T) NULL; -+ UINT_8 aucBCAddr[] = BC_MAC_ADDR; -+ -+ do { -+ if ((wiphy == NULL) || (dev == NULL)) -+ break; -+ -+ DBGLOG(P2P, INFO, "mtk_p2p_cfg80211_disconnect.\n"); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); -+ -+/* prDisconnMsg = (P_MSG_P2P_CONNECTION_ABORT_T)kalMemAlloc(sizeof(P_MSG_P2P_CONNECTION_ABORT_T), VIR_MEM_TYPE); */ -+ prDisconnMsg = -+ (P_MSG_P2P_CONNECTION_ABORT_T) cnmMemAlloc(prGlueInfo->prAdapter, RAM_TYPE_MSG, -+ sizeof(MSG_P2P_CONNECTION_ABORT_T)); -+ -+ if (prDisconnMsg == NULL) { -+ ASSERT(FALSE); -+ i4Rslt = -ENOMEM; -+ DBGLOG(P2P, INFO, "mtk_p2p_cfg80211_disconnect.Allocate Memory Failed.\n"); -+ break; -+ } -+ -+ prDisconnMsg->rMsgHdr.eMsgId = MID_MNY_P2P_CONNECTION_ABORT; -+ prDisconnMsg->u2ReasonCode = reason_code; -+ prDisconnMsg->fgSendDeauth = TRUE; -+ COPY_MAC_ADDR(prDisconnMsg->aucTargetID, aucBCAddr); -+ -+ mboxSendMsg(prGlueInfo->prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prDisconnMsg, MSG_SEND_METHOD_BUF); -+ -+ i4Rslt = 0; -+ } while (FALSE); -+ -+ return i4Rslt; -+} /* mtk_p2p_cfg80211_disconnect */ -+ -+int -+mtk_p2p_cfg80211_change_iface(IN struct wiphy *wiphy, -+ IN struct net_device *ndev, -+ IN enum nl80211_iftype type,/* IN u32 *flags,*/ IN struct vif_params *params) -+{ -+ P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) NULL; -+ INT_32 i4Rslt = -EINVAL; -+ P_MSG_P2P_SWITCH_OP_MODE_T prSwitchModeMsg = (P_MSG_P2P_SWITCH_OP_MODE_T) NULL; -+ -+ do { -+ if ((wiphy == NULL) || (ndev == NULL)) -+ break; -+ -+ DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_change_iface.\n"); -+ -+ if (ndev->ieee80211_ptr) -+ ndev->ieee80211_ptr->iftype = type; -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); -+ -+ /* Switch OP MOde. */ -+ prSwitchModeMsg = -+ (P_MSG_P2P_SWITCH_OP_MODE_T) cnmMemAlloc(prGlueInfo->prAdapter, RAM_TYPE_MSG, -+ sizeof(MSG_P2P_SWITCH_OP_MODE_T)); -+ -+ if (prSwitchModeMsg == NULL) { -+ ASSERT(FALSE); -+ i4Rslt = -ENOMEM; -+ break; -+ } -+ -+ prSwitchModeMsg->rMsgHdr.eMsgId = MID_MNY_P2P_FUN_SWITCH; -+ -+ switch (type) { -+ case NL80211_IFTYPE_P2P_CLIENT: -+ DBGLOG(P2P, TRACE, "NL80211_IFTYPE_P2P_CLIENT.\n"); -+ case NL80211_IFTYPE_STATION: -+ if (type == NL80211_IFTYPE_STATION) -+ DBGLOG(P2P, TRACE, "NL80211_IFTYPE_STATION.\n"); -+ prSwitchModeMsg->eOpMode = OP_MODE_INFRASTRUCTURE; -+ break; -+ case NL80211_IFTYPE_AP: -+ DBGLOG(P2P, TRACE, "NL80211_IFTYPE_AP.\n"); -+ case NL80211_IFTYPE_P2P_GO: -+ if (type == NL80211_IFTYPE_P2P_GO) -+ DBGLOG(P2P, TRACE, "NL80211_IFTYPE_P2P_GO not AP.\n"); -+ prSwitchModeMsg->eOpMode = OP_MODE_ACCESS_POINT; -+ break; -+ default: -+ DBGLOG(P2P, TRACE, "Other type :%d .\n", type); -+ prSwitchModeMsg->eOpMode = OP_MODE_P2P_DEVICE; -+ break; -+ } -+ -+ mboxSendMsg(prGlueInfo->prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prSwitchModeMsg, MSG_SEND_METHOD_BUF); -+ -+ i4Rslt = 0; -+ -+ } while (FALSE); -+ -+ return i4Rslt; -+ -+} /* mtk_p2p_cfg80211_change_iface */ -+ -+int mtk_p2p_cfg80211_set_channel(IN struct wiphy *wiphy, -+ struct cfg80211_chan_def *chandef) -+{ -+ INT_32 i4Rslt = -EINVAL; -+ P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) NULL; -+ RF_CHANNEL_INFO_T rRfChnlInfo; -+ -+ do { -+ if (wiphy == NULL) -+ break; -+ -+ DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_set_channel.\n"); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); -+ mtk_p2p_cfg80211func_channel_format_switch(chandef->chan, chandef->width, &rRfChnlInfo, NULL); -+ p2pFuncSetChannel(prGlueInfo->prAdapter, &rRfChnlInfo); -+ -+ i4Rslt = 0; -+ } while (FALSE); -+ -+ return i4Rslt; -+ -+} -+ -+/* mtk_p2p_cfg80211_set_channel */ -+ -+int -+mtk_p2p_cfg80211_set_bitrate_mask(IN struct wiphy *wiphy, -+ IN struct net_device *dev, -+ IN const u8 *peer, IN const struct cfg80211_bitrate_mask *mask) -+{ -+ INT_32 i4Rslt = -EINVAL; -+ P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) NULL; -+ -+ do { -+ if ((wiphy == NULL) || (dev == NULL) || (mask == NULL)) -+ break; -+ -+ DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_set_bitrate_mask\n"); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); -+ -+ /* TODO: Set bitrate mask of the peer? */ -+ -+ i4Rslt = 0; -+ } while (FALSE); -+ -+ return i4Rslt; -+} /* mtk_p2p_cfg80211_set_bitrate_mask */ -+ -+void mtk_p2p_cfg80211_mgmt_frame_register(IN struct wiphy *wiphy, -+ struct wireless_dev *wdev, -+ IN u16 frame_type, IN bool reg) -+{ -+#if 0 -+ P_MSG_P2P_MGMT_FRAME_REGISTER_T prMgmtFrameRegister = (P_MSG_P2P_MGMT_FRAME_REGISTER_T) NULL; -+#endif -+ P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) NULL; -+ -+ do { -+ if ((wiphy == NULL) || (wdev == NULL)) -+ break; -+ -+ DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_mgmt_frame_register\n"); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); -+ -+ switch (frame_type) { -+ case MAC_FRAME_PROBE_REQ: -+ if (reg) { -+ prGlueInfo->prP2PInfo->u4OsMgmtFrameFilter |= PARAM_PACKET_FILTER_PROBE_REQ; -+ DBGLOG(P2P, TRACE, "Open packet filer probe request\n"); -+ } else { -+ prGlueInfo->prP2PInfo->u4OsMgmtFrameFilter &= ~PARAM_PACKET_FILTER_PROBE_REQ; -+ DBGLOG(P2P, TRACE, "Close packet filer probe request\n"); -+ } -+ break; -+ case MAC_FRAME_ACTION: -+ if (reg) { -+ prGlueInfo->prP2PInfo->u4OsMgmtFrameFilter |= PARAM_PACKET_FILTER_ACTION_FRAME; -+ DBGLOG(P2P, TRACE, "Open packet filer action frame.\n"); -+ } else { -+ prGlueInfo->prP2PInfo->u4OsMgmtFrameFilter &= ~PARAM_PACKET_FILTER_ACTION_FRAME; -+ DBGLOG(P2P, TRACE, "Close packet filer action frame.\n"); -+ } -+ break; -+ default: -+ DBGLOG(P2P, ERROR, "Ask frog to add code for mgmt:%x\n", frame_type); -+ break; -+ } -+ -+ if ((prGlueInfo->prAdapter != NULL) && (prGlueInfo->prAdapter->fgIsP2PRegistered == TRUE)) { -+ -+ /* prGlueInfo->u4Flag |= GLUE_FLAG_FRAME_FILTER; */ -+ set_bit(GLUE_FLAG_FRAME_FILTER_BIT, &prGlueInfo->ulFlag); -+ -+ /* wake up main thread */ -+ wake_up_interruptible(&prGlueInfo->waitq); -+ -+ if (in_interrupt()) -+ DBGLOG(P2P, TRACE, "It is in interrupt level\n"); -+ } -+#if 0 -+ -+ prMgmtFrameRegister = (P_MSG_P2P_MGMT_FRAME_REGISTER_T) cnmMemAlloc(prGlueInfo->prAdapter, -+ RAM_TYPE_MSG, -+ sizeof -+ (MSG_P2P_MGMT_FRAME_REGISTER_T)); -+ -+ if (prMgmtFrameRegister == NULL) { -+ ASSERT(FALSE); -+ break; -+ } -+ -+ prMgmtFrameRegister->rMsgHdr.eMsgId = MID_MNY_P2P_MGMT_FRAME_REGISTER; -+ -+ prMgmtFrameRegister->u2FrameType = frame_type; -+ prMgmtFrameRegister->fgIsRegister = reg; -+ -+ mboxSendMsg(prGlueInfo->prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMgmtFrameRegister, MSG_SEND_METHOD_BUF); -+ -+#endif -+ -+ } while (FALSE); -+ -+} /* mtk_p2p_cfg80211_mgmt_frame_register */ -+ -+BOOLEAN -+mtk_p2p_cfg80211func_channel_format_switch(IN struct ieee80211_channel *channel, -+ IN enum nl80211_channel_type channel_type, -+ IN P_RF_CHANNEL_INFO_T prRfChnlInfo, IN P_ENUM_CHNL_EXT_T prChnlSco) -+{ -+ BOOLEAN fgIsValid = FALSE; -+ -+ do { -+ if (channel == NULL) -+ break; -+ -+ if (prRfChnlInfo) { -+ prRfChnlInfo->ucChannelNum = nicFreq2ChannelNum(channel->center_freq * 1000); -+ -+ switch (channel->band) { -+ case NL80211_BAND_2GHZ: -+ prRfChnlInfo->eBand = BAND_2G4; -+ break; -+ case NL80211_BAND_5GHZ: -+ prRfChnlInfo->eBand = BAND_5G; -+ break; -+ default: -+ prRfChnlInfo->eBand = BAND_2G4; -+ break; -+ } -+ -+ } -+ -+ if (prChnlSco) { -+ -+ switch (channel_type) { -+ case NL80211_CHAN_NO_HT: -+ *prChnlSco = CHNL_EXT_SCN; -+ break; -+ case NL80211_CHAN_HT20: -+ *prChnlSco = CHNL_EXT_SCN; -+ break; -+ case NL80211_CHAN_HT40MINUS: -+ *prChnlSco = CHNL_EXT_SCA; -+ break; -+ case NL80211_CHAN_HT40PLUS: -+ *prChnlSco = CHNL_EXT_SCB; -+ break; -+ default: -+ ASSERT(FALSE); -+ *prChnlSco = CHNL_EXT_SCN; -+ break; -+ } -+ } -+ -+ fgIsValid = TRUE; -+ } while (FALSE); -+ -+ return fgIsValid; -+} -+ -+/* mtk_p2p_cfg80211func_channel_format_switch */ -+ -+#if CONFIG_NL80211_TESTMODE -+int mtk_p2p_cfg80211_testmode_cmd(IN struct wiphy *wiphy, IN struct wireless_dev *wdev, IN void *data, IN int len) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ P_NL80211_DRIVER_TEST_PARAMS prParams = (P_NL80211_DRIVER_TEST_PARAMS) NULL; -+ INT_32 i4Status = -EINVAL; -+ P_P2P_CHNL_REQ_INFO_T prChnlReqInfo = NULL; -+ -+ ASSERT(wiphy); -+ ASSERT(wdev); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); -+ -+ DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_testmode_cmd\n"); -+ -+ if (data && len) { -+ prParams = (P_NL80211_DRIVER_TEST_PARAMS) data; -+ } else { -+ DBGLOG(P2P, ERROR, "mtk_p2p_cfg80211_testmode_cmd, data is NULL\n"); -+ return i4Status; -+ } -+ -+ if (prParams->index >> 24 == 0x01) { -+ /* New version */ -+ } else { -+ /* Old version */ -+ mtk_p2p_cfg80211_testmode_p2p_sigma_pre_cmd(wiphy, data, len); -+ i4Status = 0; -+ return i4Status; -+ } -+ -+ /* Clear the version byte */ -+ prParams->index = prParams->index & ~BITS(24, 31); -+ -+ if (prParams) { -+ switch (prParams->index) { -+ case 1: /* P2P Simga */ -+#if CFG_SUPPORT_HOTSPOT_OPTIMIZATION -+ { -+ P_NL80211_DRIVER_SW_CMD_PARAMS prParamsCmd; -+ -+ prParamsCmd = (P_NL80211_DRIVER_SW_CMD_PARAMS) data; -+ -+ if ((prParamsCmd->adr & 0xffff0000) == 0xffff0000) { -+ i4Status = mtk_p2p_cfg80211_testmode_sw_cmd(wiphy, data, len); -+ break; -+ } -+ } -+#endif -+ i4Status = mtk_p2p_cfg80211_testmode_p2p_sigma_cmd(wiphy, data, len); -+ break; -+#if CFG_SUPPORT_WFD -+ case 2: /* WFD */ -+ i4Status = mtk_p2p_cfg80211_testmode_wfd_update_cmd(wiphy, data, len); -+ break; -+#endif -+ case 3: /* Hotspot Client Management */ -+ i4Status = mtk_p2p_cfg80211_testmode_hotspot_block_cmd(wiphy, data, len); -+ break; -+ case 0x10: -+ i4Status = mtk_cfg80211_testmode_get_sta_statistics(wiphy, data, len, prGlueInfo); -+ break; -+#if 1 -+ case 0x11: /*NFC Beam + Indication */ -+ prChnlReqInfo = &prGlueInfo->prAdapter->rWifiVar.prP2pFsmInfo->rChnlReqInfo; -+ if (data && len) { -+ P_NL80211_DRIVER_SET_NFC_PARAMS prParams = (P_NL80211_DRIVER_SET_NFC_PARAMS) data; -+ -+ prChnlReqInfo->NFC_BEAM = prParams->NFC_Enable; -+ DBGLOG(P2P, INFO, "NFC: BEAM[%d]\n", prChnlReqInfo->NFC_BEAM); -+ } -+ break; -+ case 0x12: /*NFC Beam + Indication */ -+ DBGLOG(P2P, INFO, "NFC: Polling\n"); -+ i4Status = mtk_cfg80211_testmode_get_scan_done(wiphy, data, len, prGlueInfo); -+ break; -+#endif -+#if CFG_AUTO_CHANNEL_SEL_SUPPORT -+ case 0x30: -+ i4Status = mtk_cfg80211_testmode_get_lte_channel(wiphy, data, len, prGlueInfo); -+ break; -+#endif -+ -+ default: -+ i4Status = -EINVAL; -+ break; -+ } -+ } -+ -+ return i4Status; -+} -+ -+int mtk_p2p_cfg80211_testmode_p2p_sigma_pre_cmd(IN struct wiphy *wiphy, IN void *data, IN int len) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ NL80211_DRIVER_TEST_PRE_PARAMS rParams; -+ P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo = (P_P2P_SPECIFIC_BSS_INFO_T) NULL; -+ P_P2P_CONNECTION_SETTINGS_T prP2pConnSettings = (P_P2P_CONNECTION_SETTINGS_T) NULL; -+ UINT_32 index_mode; -+ UINT_32 index; -+ INT_32 value; -+ int status = 0; -+ UINT_32 u4Leng; -+ -+ ASSERT(wiphy); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); -+ -+ kalMemZero(&rParams, sizeof(NL80211_DRIVER_TEST_PRE_PARAMS)); -+ -+ prP2pSpecificBssInfo = prGlueInfo->prAdapter->rWifiVar.prP2pSpecificBssInfo; -+ prP2pConnSettings = prGlueInfo->prAdapter->rWifiVar.prP2PConnSettings; -+ -+ DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_testmode_p2p_sigma_pre_cmd\n"); -+ -+ if (data && len) -+ memcpy(&rParams, data, len); -+ -+ DBGLOG(P2P, TRACE, "NL80211_ATTR_TESTDATA,idx_mode=%d idx=%d value=%u\n", -+ (INT_16) rParams.idx_mode, (INT_16) rParams.idx, rParams.value); -+ -+ index_mode = rParams.idx_mode; -+ index = rParams.idx; -+ value = rParams.value; -+ -+ switch (index) { -+ case 0: /* Listen CH */ -+ break; -+ case 1: /* P2p mode */ -+ break; -+ case 4: /* Noa duration */ -+ prP2pSpecificBssInfo->rNoaParam.u4NoaDurationMs = value; -+ /* only to apply setting when setting NOA count */ -+ /* status = mtk_p2p_wext_set_noa_param(prDev, info, wrqu, (char *)&prP2pSpecificBssInfo->rNoaParam); */ -+ break; -+ case 5: /* Noa interval */ -+ prP2pSpecificBssInfo->rNoaParam.u4NoaIntervalMs = value; -+ /* only to apply setting when setting NOA count */ -+ /* status = mtk_p2p_wext_set_noa_param(prDev, info, wrqu, (char *)&prP2pSpecificBssInfo->rNoaParam); */ -+ break; -+ case 6: /* Noa count */ -+ prP2pSpecificBssInfo->rNoaParam.u4NoaCount = value; -+ /* status = mtk_p2p_wext_set_noa_param(prDev, info, wrqu, (char *)&prP2pSpecificBssInfo->rNoaParam); */ -+ break; -+ case 100: /* Oper CH */ -+ /* 20110920 - frog: User configurations are placed in ConnSettings. */ -+ /* prP2pConnSettings->ucOperatingChnl = value; */ -+ break; -+ case 101: /* Local config Method, for P2P SDK */ -+ prP2pConnSettings->u2LocalConfigMethod = value; -+ break; -+ case 102: /* Sigma P2p reset */ -+ /* kalMemZero(prP2pConnSettings->aucTargetDevAddr, MAC_ADDR_LEN); */ -+ /* prP2pConnSettings->eConnectionPolicy = ENUM_P2P_CONNECTION_POLICY_AUTO; */ -+ p2pFsmUninit(prGlueInfo->prAdapter); -+ p2pFsmInit(prGlueInfo->prAdapter); -+ break; -+ case 103: /* WPS MODE */ -+ kalP2PSetWscMode(prGlueInfo, value); -+ break; -+ case 104: /* P2p send persence, duration */ -+ break; -+ case 105: /* P2p send persence, interval */ -+ break; -+ case 106: /* P2P set sleep */ -+ value = 1; -+ kalIoctl(prGlueInfo, -+ wlanoidSetP2pPowerSaveProfile, &value, sizeof(value), FALSE, FALSE, TRUE, TRUE, &u4Leng); -+ break; -+ case 107: /* P2P set opps, CTWindowl */ -+ prP2pSpecificBssInfo->rOppPsParam.u4CTwindowMs = value; -+ /* status = mtk_p2p_wext_set_oppps_param(prDev,info,wrqu,(char *)&prP2pSpecificBssInfo->rOppPsParam); */ -+ break; -+ case 108: /* p2p_set_power_save */ -+ kalIoctl(prGlueInfo, -+ wlanoidSetP2pPowerSaveProfile, &value, sizeof(value), FALSE, FALSE, TRUE, TRUE, &u4Leng); -+ -+ break; -+ default: -+ break; -+ } -+ -+ return status; -+ -+} -+ -+int mtk_p2p_cfg80211_testmode_p2p_sigma_cmd(IN struct wiphy *wiphy, IN void *data, IN int len) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ P_NL80211_DRIVER_P2P_SIGMA_PARAMS prParams = (P_NL80211_DRIVER_P2P_SIGMA_PARAMS) NULL; -+ P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo = (P_P2P_SPECIFIC_BSS_INFO_T) NULL; -+ P_P2P_CONNECTION_SETTINGS_T prP2pConnSettings = (P_P2P_CONNECTION_SETTINGS_T) NULL; -+ UINT_32 index; -+ INT_32 value; -+ int status = 0; -+ UINT_32 u4Leng; -+ -+ ASSERT(wiphy); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); -+ -+ prP2pSpecificBssInfo = prGlueInfo->prAdapter->rWifiVar.prP2pSpecificBssInfo; -+ prP2pConnSettings = prGlueInfo->prAdapter->rWifiVar.prP2PConnSettings; -+ -+ DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_testmode_p2p_sigma_cmd\n"); -+ -+ if (data && len) { -+ prParams = (P_NL80211_DRIVER_P2P_SIGMA_PARAMS) data; -+ } else { -+ DBGLOG(P2P, ERROR, "mtk_p2p_cfg80211_testmode_p2p_sigma_cmd, data is NULL or len is 0\n"); -+ return -EINVAL; -+ } -+ -+ index = (INT_32) prParams->idx; -+ value = (INT_32) prParams->value; -+ -+ DBGLOG(P2P, TRACE, "NL80211_ATTR_TESTDATA, idx=%d value=%d\n", -+ (INT_32) prParams->idx, (INT_32) prParams->value); -+ -+ switch (index) { -+ case 0: /* Listen CH */ -+ break; -+ case 1: /* P2p mode */ -+ break; -+ case 4: /* Noa duration */ -+ prP2pSpecificBssInfo->rNoaParam.u4NoaDurationMs = value; -+ /* only to apply setting when setting NOA count */ -+ /* status = mtk_p2p_wext_set_noa_param(prDev, info, wrqu, (char *)&prP2pSpecificBssInfo->rNoaParam); */ -+ break; -+ case 5: /* Noa interval */ -+ prP2pSpecificBssInfo->rNoaParam.u4NoaIntervalMs = value; -+ /* only to apply setting when setting NOA count */ -+ /* status = mtk_p2p_wext_set_noa_param(prDev, info, wrqu, (char *)&prP2pSpecificBssInfo->rNoaParam); */ -+ break; -+ case 6: /* Noa count */ -+ prP2pSpecificBssInfo->rNoaParam.u4NoaCount = value; -+ /* status = mtk_p2p_wext_set_noa_param(prDev, info, wrqu, (char *)&prP2pSpecificBssInfo->rNoaParam); */ -+ break; -+ case 100: /* Oper CH */ -+ /* 20110920 - frog: User configurations are placed in ConnSettings. */ -+ /* prP2pConnSettings->ucOperatingChnl = value; */ -+ break; -+ case 101: /* Local config Method, for P2P SDK */ -+ prP2pConnSettings->u2LocalConfigMethod = value; -+ break; -+ case 102: /* Sigma P2p reset */ -+ /* kalMemZero(prP2pConnSettings->aucTargetDevAddr, MAC_ADDR_LEN); */ -+ /* prP2pConnSettings->eConnectionPolicy = ENUM_P2P_CONNECTION_POLICY_AUTO; */ -+ break; -+ case 103: /* WPS MODE */ -+ kalP2PSetWscMode(prGlueInfo, value); -+ break; -+ case 104: /* P2p send persence, duration */ -+ break; -+ case 105: /* P2p send persence, interval */ -+ break; -+ case 106: /* P2P set sleep */ -+ value = 1; -+ kalIoctl(prGlueInfo, -+ wlanoidSetP2pPowerSaveProfile, &value, sizeof(value), FALSE, FALSE, TRUE, TRUE, &u4Leng); -+ break; -+ case 107: /* P2P set opps, CTWindowl */ -+ prP2pSpecificBssInfo->rOppPsParam.u4CTwindowMs = value; -+ /* status = mtk_p2p_wext_set_oppps_param(prDev,info,wrqu,(char *)&prP2pSpecificBssInfo->rOppPsParam); */ -+ break; -+ case 108: /* p2p_set_power_save */ -+ kalIoctl(prGlueInfo, -+ wlanoidSetP2pPowerSaveProfile, &value, sizeof(value), FALSE, FALSE, TRUE, TRUE, &u4Leng); -+ -+ break; -+ case 109: /* Max Clients */ -+ kalP2PSetMaxClients(prGlueInfo, value); -+ break; -+ case 110: /* Hotspot WPS mode */ -+ kalIoctl(prGlueInfo, wlanoidSetP2pWPSmode, &value, sizeof(value), FALSE, FALSE, TRUE, TRUE, &u4Leng); -+ break; -+ default: -+ break; -+ } -+ -+ return status; -+ -+} -+ -+#if CFG_SUPPORT_WFD -+int mtk_p2p_cfg80211_testmode_wfd_update_cmd(IN struct wiphy *wiphy, IN void *data, IN int len) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ P_NL80211_DRIVER_WFD_PARAMS prParams = (P_NL80211_DRIVER_WFD_PARAMS) NULL; -+ int status = 0; -+ P_WFD_CFG_SETTINGS_T prWfdCfgSettings = (P_WFD_CFG_SETTINGS_T) NULL; -+ P_MSG_WFD_CONFIG_SETTINGS_CHANGED_T prMsgWfdCfgUpdate = (P_MSG_WFD_CONFIG_SETTINGS_CHANGED_T) NULL; -+ static UINT_8 prevWfdEnable; -+ -+ ASSERT(wiphy); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); -+ -+ prParams = (P_NL80211_DRIVER_WFD_PARAMS) data; -+ -+ DBGLOG(P2P, INFO, "mtk_p2p_cfg80211_testmode_wfd_update_cmd\n"); -+ -+ /* to reduce log, print when state changed */ -+ if (prevWfdEnable != prParams->WfdEnable) { -+ prevWfdEnable = prParams->WfdEnable; -+ DBGLOG(P2P, INFO, "WFD Enable:%x\n", prParams->WfdEnable); -+ DBGLOG(P2P, INFO, "WFD Session Available:%x\n", prParams->WfdSessionAvailable); -+ DBGLOG(P2P, INFO, "WFD Couple Sink Status:%x\n", prParams->WfdCoupleSinkStatus); -+ /* aucReserved0[2] */ -+ DBGLOG(P2P, INFO, "WFD Device Info:%x\n", prParams->WfdDevInfo); -+ DBGLOG(P2P, INFO, "WFD Control Port:%x\n", prParams->WfdControlPort); -+ DBGLOG(P2P, INFO, "WFD Maximum Throughput:%x\n", prParams->WfdMaximumTp); -+ DBGLOG(P2P, INFO, "WFD Extend Capability:%x\n", prParams->WfdExtendCap); -+ DBGLOG(P2P, INFO, "WFD Couple Sink Addr %pM\n", prParams->WfdCoupleSinkAddress); -+ DBGLOG(P2P, INFO, "WFD Associated BSSID %pM\n", prParams->WfdAssociatedBssid); -+ /* UINT_8 aucVideolp[4]; */ -+ /* UINT_8 aucAudiolp[4]; */ -+ DBGLOG(P2P, INFO, "WFD Video Port:%x\n", prParams->WfdVideoPort); -+ DBGLOG(P2P, INFO, "WFD Audio Port:%x\n", prParams->WfdAudioPort); -+ DBGLOG(P2P, INFO, "WFD Flag:%x\n", prParams->WfdFlag); -+ DBGLOG(P2P, INFO, "WFD Policy:%x\n", prParams->WfdPolicy); -+ DBGLOG(P2P, INFO, "WFD State:%x\n", prParams->WfdState); -+ /* UINT_8 aucWfdSessionInformationIE[24*8]; */ -+ DBGLOG(P2P, INFO, "WFD Session Info Length:%x\n", prParams->WfdSessionInformationIELen); -+ /* UINT_8 aucReserved1[2]; */ -+ DBGLOG(P2P, INFO, "WFD Primary Sink Addr %pM\n", prParams->aucWfdPrimarySinkMac); -+ DBGLOG(P2P, INFO, "WFD Secondary Sink Addr %pM\n", prParams->aucWfdSecondarySinkMac); -+ DBGLOG(P2P, INFO, "WFD Advanced Flag:%x\n", prParams->WfdAdvanceFlag); -+ DBGLOG(P2P, INFO, "WFD Sigma mode:%x\n", prParams->WfdSigmaMode); -+ /* UINT_8 aucReserved2[64]; */ -+ /* UINT_8 aucReserved3[64]; */ -+ /* UINT_8 aucReserved4[64]; */ -+ } -+ -+ prWfdCfgSettings = &(prGlueInfo->prAdapter->rWifiVar.prP2pFsmInfo->rWfdConfigureSettings); -+ -+ kalMemCopy(&prWfdCfgSettings->u4WfdCmdType, &prParams->WfdCmdType, sizeof(WFD_CFG_SETTINGS_T)); -+ -+ prMsgWfdCfgUpdate = cnmMemAlloc(prGlueInfo->prAdapter, RAM_TYPE_MSG, sizeof(MSG_WFD_CONFIG_SETTINGS_CHANGED_T)); -+ -+ if (prMsgWfdCfgUpdate == NULL) { -+ ASSERT(FALSE); -+ return status; -+ } -+ -+ prMsgWfdCfgUpdate->rMsgHdr.eMsgId = MID_MNY_P2P_WFD_CFG_UPDATE; -+ prMsgWfdCfgUpdate->prWfdCfgSettings = prWfdCfgSettings; -+ -+ mboxSendMsg(prGlueInfo->prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgWfdCfgUpdate, MSG_SEND_METHOD_BUF); -+#if 0 /* Test Only */ -+/* prWfdCfgSettings->ucWfdEnable = 1; */ -+/* prWfdCfgSettings->u4WfdFlag |= WFD_FLAGS_DEV_INFO_VALID; */ -+ prWfdCfgSettings->u4WfdFlag |= WFD_FLAGS_DEV_INFO_VALID; -+ prWfdCfgSettings->u2WfdDevInfo = 123; -+ prWfdCfgSettings->u2WfdControlPort = 456; -+ prWfdCfgSettings->u2WfdMaximumTp = 789; -+ -+ prWfdCfgSettings->u4WfdFlag |= WFD_FLAGS_SINK_INFO_VALID; -+ prWfdCfgSettings->ucWfdCoupleSinkStatus = 0xAB; -+ { -+ UINT_8 aucTestAddr[MAC_ADDR_LEN] = { 0x77, 0x66, 0x55, 0x44, 0x33, 0x22 }; -+ -+ COPY_MAC_ADDR(prWfdCfgSettings->aucWfdCoupleSinkAddress, aucTestAddr); -+ } -+ -+ prWfdCfgSettings->u4WfdFlag |= WFD_FLAGS_EXT_CAPABILITY_VALID; -+ prWfdCfgSettings->u2WfdExtendCap = 0xCDE; -+ -+#endif -+ -+ return status; -+ -+} -+#endif /* CFG_SUPPORT_WFD */ -+ -+int mtk_p2p_cfg80211_testmode_hotspot_block_cmd(IN struct wiphy *wiphy, IN void *data, IN int len) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ P_NL80211_DRIVER_HOTSPOT_BLOCK_PARAMS prParams = (P_NL80211_DRIVER_HOTSPOT_BLOCK_PARAMS) NULL; -+ -+ ASSERT(wiphy); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); -+ -+ if (data && len) { -+ prParams = (P_NL80211_DRIVER_HOTSPOT_BLOCK_PARAMS) data; -+ } else { -+ DBGLOG(P2P, ERROR, "mtk_p2p_cfg80211_testmode_hotspot_block_cmd, data is NULL or len is 0\n"); -+ return -EINVAL; -+ } -+ -+ DBGLOG(P2P, TRACE, "mtk_p2p_cfg80211_testmode_hotspot_block_cmd\n"); -+ -+ return kalP2PSetBlackList(prGlueInfo, prParams->aucBssid, prParams->ucblocked); -+} -+ -+int mtk_p2p_cfg80211_testmode_sw_cmd(IN struct wiphy *wiphy, IN void *data, IN int len) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ P_NL80211_DRIVER_SW_CMD_PARAMS prParams = (P_NL80211_DRIVER_SW_CMD_PARAMS) NULL; -+ WLAN_STATUS rstatus = WLAN_STATUS_SUCCESS; -+ int fgIsValid = 0; -+ UINT_32 u4SetInfoLen = 0; -+ -+ ASSERT(wiphy); -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); -+ -+#if 1 -+ DBGLOG(P2P, TRACE, "--> %s()\n", __func__); -+#endif -+ -+ if (data && len) -+ prParams = (P_NL80211_DRIVER_SW_CMD_PARAMS) data; -+ -+ if (prParams) { -+ if (prParams->set == 1) { -+ rstatus = kalIoctl(prGlueInfo, -+ (PFN_OID_HANDLER_FUNC) wlanoidSetSwCtrlWrite, -+ &prParams->adr, (UINT_32) 8, FALSE, FALSE, TRUE, FALSE, &u4SetInfoLen); -+ } -+ } -+ -+ if (WLAN_STATUS_SUCCESS != rstatus) -+ fgIsValid = -EFAULT; -+ -+ return fgIsValid; -+} -+ -+#endif -+ -+#endif /* CFG_ENABLE_WIFI_DIRECT && CFG_ENABLE_WIFI_DIRECT_CFG_80211 */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_p2p_init.c b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_p2p_init.c -new file mode 100644 -index 000000000000..d0f2d25a4529 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_p2p_init.c -@@ -0,0 +1,433 @@ -+/* -+* Copyright (C) 2011-2014 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -+* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See the GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License along with this program. -+* If not, see . -+*/ -+ -+/* -+** Id: @(#) gl_p2p_init.c@@ -+*/ -+ -+/*! \file gl_p2p_init.c -+ \brief init and exit routines of Linux driver interface for Wi-Fi Direct -+ -+ This file contains the main routines of Linux driver for MediaTek Inc. 802.11 -+ Wireless LAN Adapters. -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+#include "precomp.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+#define P2P_MODE_INF_NAME "p2p%d" -+#if CFG_TC1_FEATURE -+#define AP_MODE_INF_NAME "wlan%d" -+#else -+#define AP_MODE_INF_NAME "ap%d" -+#endif -+/* #define MAX_INF_NAME_LEN 15 */ -+/* #define MIN_INF_NAME_LEN 1 */ -+ -+#define RUNNING_P2P_MODE 0 -+#define RUNNING_AP_MODE 1 -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/* Get interface name and running mode from module insertion parameter -+* Usage: insmod p2p.ko mode=1 -+* default: interface name is p2p%d -+* running mode is P2P -+*/ -+static PUCHAR ifname = P2P_MODE_INF_NAME; -+static UINT_16 mode = RUNNING_P2P_MODE; -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief check interface name parameter is valid or not -+* if invalid, set ifname to P2P_MODE_INF_NAME -+* -+* -+* \retval -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID p2pCheckInterfaceName(VOID) -+{ -+ -+ if (mode) { -+ mode = RUNNING_AP_MODE; -+ ifname = AP_MODE_INF_NAME; -+ } -+#if 0 -+ UINT_32 ifLen = 0; -+ -+ if (ifname) { -+ ifLen = strlen(ifname); -+ -+ if (ifLen > MAX_INF_NAME_LEN) -+ ifname[MAX_INF_NAME_LEN] = '\0'; -+ else if (ifLen < MIN_INF_NAME_LEN) -+ ifname = P2P_MODE_INF_NAME; -+ } else { -+ ifname = P2P_MODE_INF_NAME; -+ } -+#endif -+} -+ -+void p2pHandleSystemSuspend(void) -+{ -+ struct net_device *prDev = NULL; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ UINT_8 ip[4] = { 0 }; -+ UINT_32 u4NumIPv4 = 0; -+#ifdef CONFIG_IPV6 -+ UINT_8 ip6[16] = { 0 }; /* FIX ME: avoid to allocate large memory in stack */ -+ UINT_32 u4NumIPv6 = 0; -+#endif -+ UINT_32 i; -+ P_PARAM_NETWORK_ADDRESS_IP prParamIpAddr; -+ -+ -+ if (!wlanExportGlueInfo(&prGlueInfo)) { -+ DBGLOG(P2P, INFO, "No glue info\n"); -+ return; -+ } -+ -+ ASSERT(prGlueInfo); -+ /* <1> Sanity check and acquire the net_device */ -+ prDev = prGlueInfo->prP2PInfo->prDevHandler; -+ ASSERT(prDev); -+ -+ /* <3> get the IPv4 address */ -+ if (!prDev || !(prDev->ip_ptr) || -+ !((struct in_device *)(prDev->ip_ptr))->ifa_list || -+ !(&(((struct in_device *)(prDev->ip_ptr))->ifa_list->ifa_local))) { -+ DBGLOG(P2P, INFO, "ip is not available.\n"); -+ return; -+ } -+ /* <4> copy the IPv4 address */ -+ kalMemCopy(ip, &(((struct in_device *)(prDev->ip_ptr))->ifa_list->ifa_local), sizeof(ip)); -+ -+ /* todo: traverse between list to find whole sets of IPv4 addresses */ -+ if (!((ip[0] == 0) && (ip[1] == 0) && (ip[2] == 0) && (ip[3] == 0))) -+ u4NumIPv4++; -+#ifdef CONFIG_IPV6 -+ /* <5> get the IPv6 address */ -+ if (!prDev || !(prDev->ip6_ptr) || -+ !((struct in_device *)(prDev->ip6_ptr))->ifa_list || -+ !(&(((struct in_device *)(prDev->ip6_ptr))->ifa_list->ifa_local))) { -+ DBGLOG(P2P, INFO, "ipv6 is not available.\n"); -+ return; -+ } -+ /* <6> copy the IPv6 address */ -+ kalMemCopy(ip6, &(((struct in_device *)(prDev->ip6_ptr))->ifa_list->ifa_local), sizeof(ip6)); -+ DBGLOG(P2P, INFO, "ipv6 is %d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d\n", -+ ip6[0], ip6[1], ip6[2], ip6[3], -+ ip6[4], ip6[5], ip6[6], ip6[7], ip6[8], ip6[9], ip6[10], ip6[11], ip6[12], ip6[13], ip6[14], ip6[15]); -+ /* todo: traverse between list to find whole sets of IPv6 addresses */ -+ -+ if (!((ip6[0] == 0) && (ip6[1] == 0) && (ip6[2] == 0) && (ip6[3] == 0) && (ip6[4] == 0) && (ip6[5] == 0))) -+ ; /* Do nothing */ -+#endif -+ /* <7> set up the ARP filter */ -+ { -+ WLAN_STATUS rStatus = WLAN_STATUS_FAILURE; -+ UINT_32 u4SetInfoLen = 0; -+/* UINT_8 aucBuf[32] = {0}; */ -+ UINT_32 u4Len = OFFSET_OF(PARAM_NETWORK_ADDRESS_LIST, arAddress); -+ P_PARAM_NETWORK_ADDRESS_LIST prParamNetAddrList = (P_PARAM_NETWORK_ADDRESS_LIST) g_aucBufIpAddr; -+ /* aucBuf; */ -+ P_PARAM_NETWORK_ADDRESS prParamNetAddr = prParamNetAddrList->arAddress; -+ -+ kalMemZero(g_aucBufIpAddr, sizeof(g_aucBufIpAddr)); -+ -+ prParamNetAddrList->u4AddressCount = u4NumIPv4; -+#ifdef CONFIG_IPV6 -+ prParamNetAddrList->u4AddressCount += u4NumIPv6; -+#endif -+ -+ prParamNetAddrList->u2AddressType = PARAM_PROTOCOL_ID_TCP_IP; -+ for (i = 0; i < u4NumIPv4; i++) { -+ prParamNetAddr->u2AddressLength = sizeof(PARAM_NETWORK_ADDRESS_IP); /* 4;; */ -+ prParamNetAddr->u2AddressType = PARAM_PROTOCOL_ID_TCP_IP; -+#if 0 -+ kalMemCopy(prParamNetAddr->aucAddress, ip, sizeof(ip)); -+ prParamNetAddr = (P_PARAM_NETWORK_ADDRESS) ((UINT_32) prParamNetAddr + sizeof(ip)); -+ u4Len += OFFSET_OF(PARAM_NETWORK_ADDRESS, aucAddress) + sizeof(ip); -+#else -+ prParamIpAddr = (P_PARAM_NETWORK_ADDRESS_IP) prParamNetAddr->aucAddress; -+ kalMemCopy(&prParamIpAddr->in_addr, ip, sizeof(ip)); -+ -+/* prParamNetAddr = (P_PARAM_NETWORK_ADDRESS)((UINT_32)prParamNetAddr + sizeof(PARAM_NETWORK_ADDRESS)); -+// TODO: frog. The pointer is not right. */ -+ -+ prParamNetAddr = (P_PARAM_NETWORK_ADDRESS) ((ULONG) prParamNetAddr + -+ (ULONG) (prParamNetAddr->u2AddressLength + -+ OFFSET_OF(PARAM_NETWORK_ADDRESS, -+ aucAddress))); -+ -+ u4Len += OFFSET_OF(PARAM_NETWORK_ADDRESS, aucAddress) + sizeof(PARAM_NETWORK_ADDRESS_IP); -+#endif -+ } -+#ifdef CONFIG_IPV6 -+ for (i = 0; i < u4NumIPv6; i++) { -+ prParamNetAddr->u2AddressLength = 6; -+ prParamNetAddr->u2AddressType = PARAM_PROTOCOL_ID_TCP_IP; -+ kalMemCopy(prParamNetAddr->aucAddress, ip6, sizeof(ip6)); -+/* prParamNetAddr = (P_PARAM_NETWORK_ADDRESS)((UINT_32)prParamNetAddr + sizeof(ip6)); */ -+ -+ prParamNetAddr = (P_PARAM_NETWORK_ADDRESS) ((ULONG) prParamNetAddr + -+ (ULONG) (prParamNetAddr->u2AddressLength + -+ OFFSET_OF(PARAM_NETWORK_ADDRESS, -+ aucAddress))); -+ -+ u4Len += OFFSET_OF(PARAM_NETWORK_ADDRESS, aucAddress) + sizeof(ip6); -+ } -+#endif -+ ASSERT(u4Len <= sizeof(g_aucBufIpAddr /*aucBuf */)); -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetP2pSetNetworkAddress, -+ (PVOID) prParamNetAddrList, u4Len, FALSE, FALSE, TRUE, TRUE, &u4SetInfoLen); -+ -+ DBGLOG(INIT, INFO, "IP: %d.%d.%d.%d, rStatus: %u\n", ip[0], ip[1], ip[2], ip[3], rStatus); -+ } -+} -+ -+void p2pHandleSystemResume(void) -+{ -+ struct net_device *prDev = NULL; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ UINT_8 ip[4] = { 0 }; -+#ifdef CONFIG_IPV6 -+ UINT_8 ip6[16] = { 0 }; /* FIX ME: avoid to allocate large memory in stack */ -+#endif -+ -+ if (!wlanExportGlueInfo(&prGlueInfo)) { -+ DBGLOG(P2P, WARN, "no glue info\n"); -+ return; -+ } -+ -+ ASSERT(prGlueInfo); -+ /* <1> Sanity check and acquire the net_device */ -+ prDev = prGlueInfo->prP2PInfo->prDevHandler; -+ ASSERT(prDev); -+ -+ /* <3> get the IPv4 address */ -+ if (!prDev || !(prDev->ip_ptr) || -+ !((struct in_device *)(prDev->ip_ptr))->ifa_list || -+ !(&(((struct in_device *)(prDev->ip_ptr))->ifa_list->ifa_local))) { -+ DBGLOG(P2P, INFO, "ip is not available.\n"); -+ return; -+ } -+ /* <4> copy the IPv4 address */ -+ kalMemCopy(ip, &(((struct in_device *)(prDev->ip_ptr))->ifa_list->ifa_local), sizeof(ip)); -+ -+#ifdef CONFIG_IPV6 -+ /* <5> get the IPv6 address */ -+ if (!prDev || !(prDev->ip6_ptr) || -+ !((struct in_device *)(prDev->ip6_ptr))->ifa_list || -+ !(&(((struct in_device *)(prDev->ip6_ptr))->ifa_list->ifa_local))) { -+ DBGLOG(P2P, INFO, "ipv6 is not available.\n"); -+ return; -+ } -+ /* <6> copy the IPv6 address */ -+ kalMemCopy(ip6, &(((struct in_device *)(prDev->ip6_ptr))->ifa_list->ifa_local), sizeof(ip6)); -+ DBGLOG(P2P, INFO, "ipv6 is %d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d\n", -+ ip6[0], ip6[1], ip6[2], ip6[3], -+ ip6[4], ip6[5], ip6[6], ip6[7], ip6[8], ip6[9], ip6[10], ip6[11], ip6[12], ip6[13], ip6[14], ip6[15]); -+#endif -+ /* <7> clear the ARP filter */ -+ { -+ WLAN_STATUS rStatus = WLAN_STATUS_FAILURE; -+ UINT_32 u4SetInfoLen = 0; -+/* UINT_8 aucBuf[32] = {0}; */ -+ UINT_32 u4Len = sizeof(PARAM_NETWORK_ADDRESS_LIST); -+ P_PARAM_NETWORK_ADDRESS_LIST prParamNetAddrList = (P_PARAM_NETWORK_ADDRESS_LIST) g_aucBufIpAddr; -+ /* aucBuf; */ -+ -+ kalMemZero(g_aucBufIpAddr, sizeof(g_aucBufIpAddr)); -+ -+ prParamNetAddrList->u4AddressCount = 0; -+ prParamNetAddrList->u2AddressType = PARAM_PROTOCOL_ID_TCP_IP; -+ -+ ASSERT(u4Len <= sizeof(g_aucBufIpAddr /*aucBuf */)); -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetP2pSetNetworkAddress, -+ (PVOID) prParamNetAddrList, u4Len, FALSE, FALSE, TRUE, TRUE, &u4SetInfoLen); -+ -+ DBGLOG(INIT, INFO, "IP: %d.%d.%d.%d, rStatus: %u\n", ip[0], ip[1], ip[2], ip[3], rStatus); -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* run p2p init procedure, include register pointer to wlan -+* glue register p2p -+* set p2p registered flag -+* \retval 1 Success -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN p2pLaunch(P_GLUE_INFO_T prGlueInfo) -+{ -+ -+ DBGLOG(P2P, TRACE, "p2pLaunch\n"); -+ -+ if (prGlueInfo->prAdapter->fgIsP2PRegistered == TRUE) { -+ DBGLOG(P2P, INFO, "p2p already registered\n"); -+ return FALSE; -+ } else if (glRegisterP2P(prGlueInfo, ifname, (BOOLEAN) mode)) { -+ prGlueInfo->prAdapter->fgIsP2PRegistered = TRUE; -+ -+ DBGLOG(P2P, TRACE, "Launch success, fgIsP2PRegistered TRUE.\n"); -+ return TRUE; -+ } -+ DBGLOG(P2P, ERROR, "Launch Fail\n"); -+ -+ return FALSE; -+} -+ -+VOID p2pSetMode(IN BOOLEAN fgIsAPMOde) -+{ -+ if (fgIsAPMOde) { -+ mode = RUNNING_AP_MODE; -+ ifname = AP_MODE_INF_NAME; -+ } else { -+ mode = RUNNING_P2P_MODE; -+ ifname = P2P_MODE_INF_NAME; -+ } -+ -+} /* p2pSetMode */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* run p2p exit procedure, include unregister pointer to wlan -+* glue unregister p2p -+* set p2p registered flag -+ -+* \retval 1 Success -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN p2pRemove(P_GLUE_INFO_T prGlueInfo) -+{ -+ if (prGlueInfo->prAdapter->fgIsP2PRegistered == FALSE) { -+ DBGLOG(P2P, INFO, "p2p is not Registered.\n"); -+ return FALSE; -+ } -+ /*Check p2p fsm is stop or not. If not then stop now */ -+ if (IS_P2P_ACTIVE(prGlueInfo->prAdapter)) -+ p2pStopImmediate(prGlueInfo); -+ prGlueInfo->prAdapter->fgIsP2PRegistered = FALSE; -+ glUnregisterP2P(prGlueInfo); -+ /*p2p is removed successfully */ -+ return TRUE; -+ -+} -+ -+#if 0 -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Driver entry point when the driver is configured as a Linux Module, and -+* is called once at module load time, by the user-level modutils -+* application: insmod or modprobe. -+* -+* \retval 0 Success -+*/ -+/*----------------------------------------------------------------------------*/ -+static int initP2P(void) -+{ -+ P_GLUE_INFO_T prGlueInfo; -+ -+ /*check interface name validation */ -+ p2pCheckInterfaceName(); -+ -+ DBGLOG(P2P, INFO, "InitP2P, Ifname: %s, Mode: %s\n", ifname, mode ? "AP" : "P2P"); -+ -+ /*register p2p init & exit function to wlan sub module handler */ -+ wlanSubModRegisterInitExit(p2pLaunch, p2pRemove, P2P_MODULE); -+ -+ /*if wlan is not start yet, do nothing -+ * p2pLaunch will be called by txthread while wlan start -+ */ -+ /*if wlan is not started yet, return FALSE */ -+ if (wlanExportGlueInfo(&prGlueInfo)) { -+ wlanSubModInit(prGlueInfo); -+ return prGlueInfo->prAdapter->fgIsP2PRegistered ? 0 : -EIO; -+ } -+ -+ return 0; -+} /* end of initP2P() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Driver exit point when the driver as a Linux Module is removed. Called -+* at module unload time, by the user level modutils application: rmmod. -+* This is our last chance to clean up after ourselves. -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+/* 1 Module Leave Point */ -+static VOID __exit exitP2P(void) -+{ -+ P_GLUE_INFO_T prGlueInfo; -+ -+ DBGLOG(P2P, INFO, KERN_INFO DRV_NAME "ExitP2P\n"); -+ -+ /*if wlan is not started yet, return FALSE */ -+ if (wlanExportGlueInfo(&prGlueInfo)) -+ wlanSubModExit(prGlueInfo); -+ /*UNregister p2p init & exit function to wlan sub module handler */ -+ wlanSubModRegisterInitExit(NULL, NULL, P2P_MODULE); -+} /* end of exitP2P() */ -+#endif -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_p2p_kal.c b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_p2p_kal.c -new file mode 100644 -index 000000000000..11a417e4c74c ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_p2p_kal.c -@@ -0,0 +1,1314 @@ -+/* -+** Id: @(#) gl_p2p_cfg80211.c@@ -+*/ -+ -+/*! \file gl_p2p_kal.c -+ \brief -+ -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "net/cfg80211.h" -+#include "precomp.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief to retrieve Wi-Fi Direct state from glue layer -+* -+* \param[in] -+* prGlueInfo -+* rPeerAddr -+* \return -+* ENUM_BOW_DEVICE_STATE -+*/ -+/*----------------------------------------------------------------------------*/ -+ENUM_PARAM_MEDIA_STATE_T kalP2PGetState(IN P_GLUE_INFO_T prGlueInfo) -+{ -+ ASSERT(prGlueInfo); -+ -+ return prGlueInfo->prP2PInfo->eState; -+} /* end of kalP2PGetState() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief to update the assoc req to p2p -+* -+* \param[in] -+* prGlueInfo -+* pucFrameBody -+* u4FrameBodyLen -+* fgReassocRequest -+* \return -+* none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+kalP2PUpdateAssocInfo(IN P_GLUE_INFO_T prGlueInfo, -+ IN PUINT_8 pucFrameBody, IN UINT_32 u4FrameBodyLen, IN BOOLEAN fgReassocRequest) -+{ -+ union iwreq_data wrqu; -+ unsigned char *pucExtraInfo = NULL; -+ unsigned char *pucDesiredIE = NULL; -+/* unsigned char aucExtraInfoBuf[200]; */ -+ PUINT_8 cp; -+ -+ memset(&wrqu, 0, sizeof(wrqu)); -+ -+ if (fgReassocRequest) { -+ if (u4FrameBodyLen < 15) { -+ /* -+ printk(KERN_WARNING "frameBodyLen too short:%ld\n", frameBodyLen); -+ */ -+ return; -+ } -+ } else { -+ if (u4FrameBodyLen < 9) { -+ /* -+ printk(KERN_WARNING "frameBodyLen too short:%ld\n", frameBodyLen); -+ */ -+ return; -+ } -+ } -+ -+ cp = pucFrameBody; -+ -+ if (fgReassocRequest) { -+ /* Capability information field 2 */ -+ /* Listen interval field 2 */ -+ /* Current AP address 6 */ -+ cp += 10; -+ u4FrameBodyLen -= 10; -+ } else { -+ /* Capability information field 2 */ -+ /* Listen interval field 2 */ -+ cp += 4; -+ u4FrameBodyLen -= 4; -+ } -+ -+ /* do supplicant a favor, parse to the start of WPA/RSN IE */ -+ if (wextSrchDesiredWPSIE(cp, u4FrameBodyLen, 0xDD, &pucDesiredIE)) { -+ /* printk("wextSrchDesiredWPSIE!!\n"); */ -+ /* WPS IE found */ -+ } else if (wextSrchDesiredWPAIE(cp, u4FrameBodyLen, 0x30, &pucDesiredIE)) { -+ /* printk("wextSrchDesiredWPAIE!!\n"); */ -+ /* RSN IE found */ -+ } else if (wextSrchDesiredWPAIE(cp, u4FrameBodyLen, 0xDD, &pucDesiredIE)) { -+ /* printk("wextSrchDesiredWPAIE!!\n"); */ -+ /* WPA IE found */ -+ } else { -+ /* no WPA/RSN IE found, skip this event */ -+ goto skip_indicate_event; -+ } -+ -+ /* IWEVASSOCREQIE, indicate binary string */ -+ pucExtraInfo = pucDesiredIE; -+ wrqu.data.length = pucDesiredIE[1] + 2; -+ -+ /* Send event to user space */ -+ wireless_send_event(prGlueInfo->prP2PInfo->prDevHandler, IWEVASSOCREQIE, &wrqu, pucExtraInfo); -+ -+skip_indicate_event: -+ return; -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief to set Wi-Fi Direct state in glue layer -+* -+* \param[in] -+* prGlueInfo -+* eBowState -+* rPeerAddr -+* \return -+* none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+kalP2PSetState(IN P_GLUE_INFO_T prGlueInfo, -+ IN ENUM_PARAM_MEDIA_STATE_T eState, IN PARAM_MAC_ADDRESS rPeerAddr, IN UINT_8 ucRole) -+{ -+ union iwreq_data evt; -+ UINT_8 aucBuffer[IW_CUSTOM_MAX]; -+ -+ ASSERT(prGlueInfo); -+ -+ memset(&evt, 0, sizeof(evt)); -+ -+ if (eState == PARAM_MEDIA_STATE_CONNECTED) { -+ prGlueInfo->prP2PInfo->eState = PARAM_MEDIA_STATE_CONNECTED; -+ -+ snprintf(aucBuffer, IW_CUSTOM_MAX - 1, "P2P_STA_CONNECT=%pM ", rPeerAddr); -+ evt.data.length = strlen(aucBuffer); -+ -+ /* indicate in IWECUSTOM event */ -+ wireless_send_event(prGlueInfo->prP2PInfo->prDevHandler, IWEVCUSTOM, &evt, aucBuffer); -+ -+ } else if (eState == PARAM_MEDIA_STATE_DISCONNECTED) { -+ snprintf(aucBuffer, IW_CUSTOM_MAX - 1, "P2P_STA_DISCONNECT=%pM ", rPeerAddr); -+ evt.data.length = strlen(aucBuffer); -+ -+ /* indicate in IWECUSTOM event */ -+ wireless_send_event(prGlueInfo->prP2PInfo->prDevHandler, IWEVCUSTOM, &evt, aucBuffer); -+ } else { -+ ASSERT(0); -+ } -+ -+} /* end of kalP2PSetState() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief to retrieve Wi-Fi Direct operating frequency -+* -+* \param[in] -+* prGlueInfo -+* -+* \return -+* in unit of KHz -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT_32 kalP2PGetFreqInKHz(IN P_GLUE_INFO_T prGlueInfo) -+{ -+ ASSERT(prGlueInfo); -+ -+ return prGlueInfo->prP2PInfo->u4FreqInKHz; -+} /* end of kalP2PGetFreqInKHz() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief to retrieve Bluetooth-over-Wi-Fi role -+* -+* \param[in] -+* prGlueInfo -+* -+* \return -+* 0: P2P Device -+* 1: Group Client -+* 2: Group Owner -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT_8 kalP2PGetRole(IN P_GLUE_INFO_T prGlueInfo) -+{ -+ ASSERT(prGlueInfo); -+ -+ return prGlueInfo->prP2PInfo->ucRole; -+} /* end of kalP2PGetRole() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief to set Wi-Fi Direct role -+* -+* \param[in] -+* prGlueInfo -+* ucResult -+* 0: successful -+* 1: error -+* ucRole -+* 0: P2P Device -+* 1: Group Client -+* 2: Group Owner -+* -+* \return -+* none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+kalP2PSetRole(IN P_GLUE_INFO_T prGlueInfo, -+ IN UINT_8 ucResult, IN PUINT_8 pucSSID, IN UINT_8 ucSSIDLen, IN UINT_8 ucRole) -+{ -+ union iwreq_data evt; -+ UINT_8 aucBuffer[IW_CUSTOM_MAX]; -+ -+ ASSERT(prGlueInfo); -+ ASSERT(ucRole <= 2); -+ -+ memset(&evt, 0, sizeof(evt)); -+ -+ if (ucResult == 0) -+ prGlueInfo->prP2PInfo->ucRole = ucRole; -+ -+ if (pucSSID) -+ snprintf(aucBuffer, IW_CUSTOM_MAX - 1, "P2P_FORMATION_RST=%d%d%d%c%c", ucResult, ucRole, -+ 1 /* persistence or not */ , pucSSID[7], pucSSID[8]); -+ else -+ snprintf(aucBuffer, IW_CUSTOM_MAX - 1, "P2P_FORMATION_RST=%d%d%d%c%c", ucResult, ucRole, -+ 1 /* persistence or not */ , '0', '0'); -+ -+ evt.data.length = strlen(aucBuffer); -+ -+ /* if (pucSSID) */ -+ /* printk("P2P GO SSID DIRECT-%c%c\n", pucSSID[7], pucSSID[8]); */ -+ -+ /* indicate in IWECUSTOM event */ -+ wireless_send_event(prGlueInfo->prP2PInfo->prDevHandler, IWEVCUSTOM, &evt, aucBuffer); -+ -+} /* end of kalP2PSetRole() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief to set the cipher for p2p -+* -+* \param[in] -+* prGlueInfo -+* u4Cipher -+* -+* \return -+* none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID kalP2PSetCipher(IN P_GLUE_INFO_T prGlueInfo, IN UINT_32 u4Cipher) -+{ -+ if ((!prGlueInfo) || (!prGlueInfo->prP2PInfo)) { -+ ASSERT(FALSE); -+ return; -+ } -+ -+ prGlueInfo->prP2PInfo->u4CipherPairwise = u4Cipher; -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief to get the cipher, return for cipher is ccmp -+* -+* \param[in] -+* prGlueInfo -+* -+* \return -+* TRUE: cipher is ccmp -+* FALSE: cipher is none -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN kalP2PGetCipher(IN P_GLUE_INFO_T prGlueInfo) -+{ -+ if ((!prGlueInfo) || (!prGlueInfo->prP2PInfo)) { -+ ASSERT(FALSE); -+ return FALSE; -+ } -+ -+ if (prGlueInfo->prP2PInfo->u4CipherPairwise == IW_AUTH_CIPHER_CCMP) -+ return TRUE; -+ -+ if (prGlueInfo->prP2PInfo->u4CipherPairwise == IW_AUTH_CIPHER_TKIP) -+ return TRUE; -+ -+ return FALSE; -+} -+ -+BOOLEAN kalP2PGetCcmpCipher(IN P_GLUE_INFO_T prGlueInfo) -+{ -+ if ((!prGlueInfo) || (!prGlueInfo->prP2PInfo)) { -+ ASSERT(FALSE); -+ return FALSE; -+ } -+ -+ if (prGlueInfo->prP2PInfo->u4CipherPairwise == IW_AUTH_CIPHER_CCMP) -+ return TRUE; -+ -+ if (prGlueInfo->prP2PInfo->u4CipherPairwise == IW_AUTH_CIPHER_TKIP) -+ return FALSE; -+ -+ return FALSE; -+} -+ -+BOOLEAN kalP2PGetTkipCipher(IN P_GLUE_INFO_T prGlueInfo) -+{ -+ if ((!prGlueInfo) || (!prGlueInfo->prP2PInfo)) { -+ ASSERT(FALSE); -+ return FALSE; -+ } -+ -+ if (prGlueInfo->prP2PInfo->u4CipherPairwise == IW_AUTH_CIPHER_CCMP) -+ return FALSE; -+ -+ if (prGlueInfo->prP2PInfo->u4CipherPairwise == IW_AUTH_CIPHER_TKIP) -+ return TRUE; -+ -+ return FALSE; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief to set the status of WSC -+* -+* \param[in] -+* prGlueInfo -+* -+* \return -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID kalP2PSetWscMode(IN P_GLUE_INFO_T prGlueInfo, IN UINT_8 ucWscMode) -+{ -+ if ((!prGlueInfo) || (!prGlueInfo->prP2PInfo)) { -+ ASSERT(FALSE); -+ return; -+ } -+ -+ prGlueInfo->prP2PInfo->ucWSCRunning = ucWscMode; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief to get the status of WSC -+* -+* \param[in] -+* prGlueInfo -+* -+* \return -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT_8 kalP2PGetWscMode(IN P_GLUE_INFO_T prGlueInfo) -+{ -+ if ((!prGlueInfo) || (!prGlueInfo->prP2PInfo)) { -+ ASSERT(FALSE); -+ return 0; -+ } -+ -+ return prGlueInfo->prP2PInfo->ucWSCRunning; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief to get the wsc ie length -+* -+* \param[in] -+* prGlueInfo -+* ucType : 0 for beacon, 1 for probe req, 2 for probe resp -+* -+* \return -+* The WSC IE length -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT_16 kalP2PCalWSC_IELen(IN P_GLUE_INFO_T prGlueInfo, IN UINT_8 ucType) -+{ -+ ASSERT(prGlueInfo); -+ -+ ASSERT(ucType < 3); -+ -+ return prGlueInfo->prP2PInfo->u2WSCIELen[ucType]; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief to copy the wsc ie setting from p2p supplicant -+* -+* \param[in] -+* prGlueInfo -+* -+* \return -+* The WPS IE length -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID kalP2PGenWSC_IE(IN P_GLUE_INFO_T prGlueInfo, IN UINT_8 ucType, IN PUINT_8 pucBuffer) -+{ -+ P_GL_P2P_INFO_T prGlP2pInfo = (P_GL_P2P_INFO_T) NULL; -+ -+ do { -+ if ((prGlueInfo == NULL) || (ucType >= 3) || (pucBuffer == NULL)) -+ break; -+ -+ prGlP2pInfo = prGlueInfo->prP2PInfo; -+ -+ kalMemCopy(pucBuffer, prGlP2pInfo->aucWSCIE[ucType], prGlP2pInfo->u2WSCIELen[ucType]); -+ -+ } while (FALSE); -+ -+} -+ -+VOID kalP2PUpdateWSC_IE(IN P_GLUE_INFO_T prGlueInfo, IN UINT_8 ucType, IN PUINT_8 pucBuffer, IN UINT_16 u2BufferLength) -+{ -+ P_GL_P2P_INFO_T prGlP2pInfo = (P_GL_P2P_INFO_T) NULL; -+ -+ do { -+ if ((prGlueInfo == NULL) || (ucType >= 3) || ((u2BufferLength > 0) && (pucBuffer == NULL))) -+ break; -+ -+ if (u2BufferLength > 400) { -+ DBGLOG(P2P, ERROR, -+ "Buffer length is not enough, GLUE only 400 bytes but %d received\n", u2BufferLength); -+ ASSERT(FALSE); -+ break; -+ } -+ -+ prGlP2pInfo = prGlueInfo->prP2PInfo; -+ -+ kalMemCopy(prGlP2pInfo->aucWSCIE[ucType], pucBuffer, u2BufferLength); -+ -+ prGlP2pInfo->u2WSCIELen[ucType] = u2BufferLength; -+ -+ } while (FALSE); -+ -+} /* kalP2PUpdateWSC_IE */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief indicate an event to supplicant for device connection request -+* -+* \param[in] prGlueInfo Pointer of GLUE_INFO_T -+* -+* \retval none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID kalP2PIndicateConnReq(IN P_GLUE_INFO_T prGlueInfo, IN PUINT_8 pucDevName, IN INT_32 u4NameLength, -+ IN PARAM_MAC_ADDRESS rPeerAddr, IN UINT_8 ucDevType, /* 0: P2P Device / 1: GC / 2: GO */ -+ IN INT_32 i4ConfigMethod, IN INT_32 i4ActiveConfigMethod) -+{ -+ union iwreq_data evt; -+ UINT_8 aucBuffer[IW_CUSTOM_MAX]; -+ -+ ASSERT(prGlueInfo); -+ -+ /* buffer peer information for later IOC_P2P_GET_REQ_DEVICE_INFO access */ -+ prGlueInfo->prP2PInfo->u4ConnReqNameLength = u4NameLength > 32 ? 32 : u4NameLength; -+ kalMemCopy(prGlueInfo->prP2PInfo->aucConnReqDevName, pucDevName, prGlueInfo->prP2PInfo->u4ConnReqNameLength); -+ COPY_MAC_ADDR(prGlueInfo->prP2PInfo->rConnReqPeerAddr, rPeerAddr); -+ prGlueInfo->prP2PInfo->ucConnReqDevType = ucDevType; -+ prGlueInfo->prP2PInfo->i4ConnReqConfigMethod = i4ConfigMethod; -+ prGlueInfo->prP2PInfo->i4ConnReqActiveConfigMethod = i4ActiveConfigMethod; -+ -+ /* prepare event structure */ -+ memset(&evt, 0, sizeof(evt)); -+ -+ snprintf(aucBuffer, IW_CUSTOM_MAX - 1, "P2P_DVC_REQ"); -+ evt.data.length = strlen(aucBuffer); -+ -+ /* indicate in IWEVCUSTOM event */ -+ wireless_send_event(prGlueInfo->prP2PInfo->prDevHandler, IWEVCUSTOM, &evt, aucBuffer); -+ -+} /* end of kalP2PIndicateConnReq() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Indicate an event to supplicant for device connection request from other device. -+* -+* \param[in] prGlueInfo Pointer of GLUE_INFO_T -+* \param[in] pucGroupBssid Only valid when invitation Type equals to 0. -+* -+* \retval none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+kalP2PInvitationIndication(IN P_GLUE_INFO_T prGlueInfo, -+ IN P_P2P_DEVICE_DESC_T prP2pDevDesc, -+ IN PUINT_8 pucSsid, -+ IN UINT_8 ucSsidLen, -+ IN UINT_8 ucOperatingChnl, IN UINT_8 ucInvitationType, IN PUINT_8 pucGroupBssid) -+{ -+#if 1 -+ union iwreq_data evt; -+ UINT_8 aucBuffer[IW_CUSTOM_MAX]; -+ -+ ASSERT(prGlueInfo); -+ -+ /* buffer peer information for later IOC_P2P_GET_STRUCT access */ -+ prGlueInfo->prP2PInfo->u4ConnReqNameLength = -+ (UINT_32) ((prP2pDevDesc->u2NameLength > 32) ? 32 : prP2pDevDesc->u2NameLength); -+ kalMemCopy(prGlueInfo->prP2PInfo->aucConnReqDevName, prP2pDevDesc->aucName, -+ prGlueInfo->prP2PInfo->u4ConnReqNameLength); -+ COPY_MAC_ADDR(prGlueInfo->prP2PInfo->rConnReqPeerAddr, prP2pDevDesc->aucDeviceAddr); -+ COPY_MAC_ADDR(prGlueInfo->prP2PInfo->rConnReqGroupAddr, pucGroupBssid); -+ prGlueInfo->prP2PInfo->i4ConnReqConfigMethod = (INT_32) (prP2pDevDesc->u2ConfigMethod); -+ prGlueInfo->prP2PInfo->ucOperatingChnl = ucOperatingChnl; -+ prGlueInfo->prP2PInfo->ucInvitationType = ucInvitationType; -+ -+ /* prepare event structure */ -+ memset(&evt, 0, sizeof(evt)); -+ -+ snprintf(aucBuffer, IW_CUSTOM_MAX - 1, "P2P_INV_INDICATE"); -+ evt.data.length = strlen(aucBuffer); -+ -+ /* indicate in IWEVCUSTOM event */ -+ wireless_send_event(prGlueInfo->prP2PInfo->prDevHandler, IWEVCUSTOM, &evt, aucBuffer); -+ return; -+ -+#else -+ P_MSG_P2P_CONNECTION_REQUEST_T prP2pConnReq = (P_MSG_P2P_CONNECTION_REQUEST_T) NULL; -+ P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo = (P_P2P_SPECIFIC_BSS_INFO_T) NULL; -+ P_P2P_CONNECTION_SETTINGS_T prP2pConnSettings = (P_P2P_CONNECTION_SETTINGS_T) NULL; -+ -+ do { -+ ASSERT_BREAK((prGlueInfo != NULL) && (prP2pDevDesc != NULL)); -+ -+ /* Not a real solution */ -+ -+ prP2pSpecificBssInfo = prGlueInfo->prAdapter->rWifiVar.prP2pSpecificBssInfo; -+ prP2pConnSettings = prGlueInfo->prAdapter->rWifiVar.prP2PConnSettings; -+ -+ prP2pConnReq = (P_MSG_P2P_CONNECTION_REQUEST_T) cnmMemAlloc(prGlueInfo->prAdapter, -+ RAM_TYPE_MSG, -+ sizeof(MSG_P2P_CONNECTION_REQUEST_T)); -+ -+ if (prP2pConnReq == NULL) -+ break; -+ -+ kalMemZero(prP2pConnReq, sizeof(MSG_P2P_CONNECTION_REQUEST_T)); -+ -+ prP2pConnReq->rMsgHdr.eMsgId = MID_MNY_P2P_CONNECTION_REQ; -+ -+ prP2pConnReq->eFormationPolicy = ENUM_P2P_FORMATION_POLICY_AUTO; -+ -+ COPY_MAC_ADDR(prP2pConnReq->aucDeviceID, prP2pDevDesc->aucDeviceAddr); -+ -+ prP2pConnReq->u2ConfigMethod = prP2pDevDesc->u2ConfigMethod; -+ -+ if (ucInvitationType == P2P_INVITATION_TYPE_INVITATION) { -+ prP2pConnReq->fgIsPersistentGroup = FALSE; -+ prP2pConnReq->fgIsTobeGO = FALSE; -+ -+ } -+ -+ else if (ucInvitationType == P2P_INVITATION_TYPE_REINVOKE) { -+ DBGLOG(P2P, TRACE, "Re-invoke Persistent Group\n"); -+ prP2pConnReq->fgIsPersistentGroup = TRUE; -+ prP2pConnReq->fgIsTobeGO = (prGlueInfo->prP2PInfo->ucRole == 2) ? TRUE : FALSE; -+ -+ } -+ -+ p2pFsmRunEventDeviceDiscoveryAbort(prGlueInfo->prAdapter, NULL); -+ -+ if (ucOperatingChnl != 0) -+ prP2pSpecificBssInfo->ucPreferredChannel = ucOperatingChnl; -+ -+ if ((ucSsidLen < 32) && (pucSsid != NULL)) -+ COPY_SSID(prP2pConnSettings->aucSSID, prP2pConnSettings->ucSSIDLen, pucSsid, ucSsidLen); -+ -+ mboxSendMsg(prGlueInfo->prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prP2pConnReq, MSG_SEND_METHOD_BUF); -+ -+ } while (FALSE); -+ -+ /* frog add. */ -+ /* TODO: Invitation Indication */ -+ -+ return; -+#endif -+ -+} /* kalP2PInvitationIndication */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Indicate an status to supplicant for device invitation status. -+* -+* \param[in] prGlueInfo Pointer of GLUE_INFO_T -+* -+* \retval none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID kalP2PInvitationStatus(IN P_GLUE_INFO_T prGlueInfo, IN UINT_32 u4InvStatus) -+{ -+ union iwreq_data evt; -+ UINT_8 aucBuffer[IW_CUSTOM_MAX]; -+ -+ ASSERT(prGlueInfo); -+ -+ /* buffer peer information for later IOC_P2P_GET_STRUCT access */ -+ prGlueInfo->prP2PInfo->u4InvStatus = u4InvStatus; -+ -+ /* prepare event structure */ -+ memset(&evt, 0, sizeof(evt)); -+ -+ snprintf(aucBuffer, IW_CUSTOM_MAX - 1, "P2P_INV_STATUS"); -+ evt.data.length = strlen(aucBuffer); -+ -+ /* indicate in IWEVCUSTOM event */ -+ wireless_send_event(prGlueInfo->prP2PInfo->prDevHandler, IWEVCUSTOM, &evt, aucBuffer); -+ -+} /* kalP2PInvitationStatus */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Indicate an event to supplicant for Service Discovery request from other device. -+* -+* \param[in] prGlueInfo Pointer of GLUE_INFO_T -+* -+* \retval none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID kalP2PIndicateSDRequest(IN P_GLUE_INFO_T prGlueInfo, IN PARAM_MAC_ADDRESS rPeerAddr, IN UINT_8 ucSeqNum) -+{ -+ union iwreq_data evt; -+ UINT_8 aucBuffer[IW_CUSTOM_MAX]; -+ -+ ASSERT(prGlueInfo); -+ -+ memset(&evt, 0, sizeof(evt)); -+ -+ snprintf(aucBuffer, IW_CUSTOM_MAX - 1, "P2P_SD_REQ %d", ucSeqNum); -+ evt.data.length = strlen(aucBuffer); -+ -+ /* indicate IWEVP2PSDREQ event */ -+ wireless_send_event(prGlueInfo->prP2PInfo->prDevHandler, IWEVCUSTOM, &evt, aucBuffer); -+ -+} /* end of kalP2PIndicateSDRequest() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Indicate an event to supplicant for Service Discovery response -+* from other device. -+* -+* \param[in] prGlueInfo Pointer of GLUE_INFO_T -+* -+* \retval none -+*/ -+/*----------------------------------------------------------------------------*/ -+void kalP2PIndicateSDResponse(IN P_GLUE_INFO_T prGlueInfo, IN PARAM_MAC_ADDRESS rPeerAddr, IN UINT_8 ucSeqNum) -+{ -+ union iwreq_data evt; -+ UINT_8 aucBuffer[IW_CUSTOM_MAX]; -+ -+ ASSERT(prGlueInfo); -+ -+ memset(&evt, 0, sizeof(evt)); -+ -+ snprintf(aucBuffer, IW_CUSTOM_MAX - 1, "P2P_SD_RESP %d", ucSeqNum); -+ evt.data.length = strlen(aucBuffer); -+ -+ /* indicate IWEVP2PSDREQ event */ -+ wireless_send_event(prGlueInfo->prP2PInfo->prDevHandler, IWEVCUSTOM, &evt, aucBuffer); -+ -+} /* end of kalP2PIndicateSDResponse() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Indicate an event to supplicant for Service Discovery TX Done -+* from other device. -+* -+* \param[in] prGlueInfo Pointer of GLUE_INFO_T -+* \param[in] ucSeqNum Sequence number of the frame -+* \param[in] ucStatus Status code for TX -+* -+* \retval none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID kalP2PIndicateTXDone(IN P_GLUE_INFO_T prGlueInfo, IN UINT_8 ucSeqNum, IN UINT_8 ucStatus) -+{ -+ union iwreq_data evt; -+ UINT_8 aucBuffer[IW_CUSTOM_MAX]; -+ -+ ASSERT(prGlueInfo); -+ -+ memset(&evt, 0, sizeof(evt)); -+ -+ snprintf(aucBuffer, IW_CUSTOM_MAX - 1, "P2P_SD_XMITTED: %d %d", ucSeqNum, ucStatus); -+ evt.data.length = strlen(aucBuffer); -+ -+ /* indicate IWEVP2PSDREQ event */ -+ wireless_send_event(prGlueInfo->prP2PInfo->prDevHandler, IWEVCUSTOM, &evt, aucBuffer); -+ -+} /* end of kalP2PIndicateSDResponse() */ -+ -+struct net_device *kalP2PGetDevHdlr(P_GLUE_INFO_T prGlueInfo) -+{ -+ if ((!prGlueInfo) || (!prGlueInfo->prP2PInfo)) { -+ ASSERT(FALSE); -+ return NULL; -+ } -+ -+ return prGlueInfo->prP2PInfo->prDevHandler; -+} -+ -+#if CFG_SUPPORT_ANTI_PIRACY -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] prAdapter Pointer of ADAPTER_T -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID kalP2PIndicateSecCheckRsp(IN P_GLUE_INFO_T prGlueInfo, IN PUINT_8 pucRsp, IN UINT_16 u2RspLen) -+{ -+ union iwreq_data evt; -+ UINT_8 aucBuffer[IW_CUSTOM_MAX]; -+ -+ ASSERT(prGlueInfo); -+ -+ memset(&evt, 0, sizeof(evt)); -+ snprintf(aucBuffer, IW_CUSTOM_MAX - 1, "P2P_SEC_CHECK_RSP="); -+ -+ kalMemCopy(prGlueInfo->prP2PInfo->aucSecCheckRsp, pucRsp, u2RspLen); -+ evt.data.length = strlen(aucBuffer); -+ -+#if DBG -+ DBGLOG_MEM8(SEC, LOUD, prGlueInfo->prP2PInfo->aucSecCheckRsp, u2RspLen); -+#endif -+ /* indicate in IWECUSTOM event */ -+ wireless_send_event(prGlueInfo->prP2PInfo->prDevHandler, IWEVCUSTOM, &evt, aucBuffer); -+} /* p2pFsmRunEventRxDisassociation */ -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief -+* -+* \param[in] prAdapter Pointer of ADAPTER_T -+* -+* \return none -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID -+kalGetChnlList(IN P_GLUE_INFO_T prGlueInfo, -+ IN ENUM_BAND_T eSpecificBand, -+ IN UINT_8 ucMaxChannelNum, IN PUINT_8 pucNumOfChannel, IN P_RF_CHANNEL_INFO_T paucChannelList) -+{ -+ rlmDomainGetChnlList(prGlueInfo->prAdapter, eSpecificBand, FALSE, ucMaxChannelNum, -+ pucNumOfChannel, paucChannelList); -+} /* kalGetChnlList */ -+ -+/* ////////////////////////////////////ICS SUPPORT////////////////////////////////////// */ -+ -+VOID -+kalP2PIndicateChannelReady(IN P_GLUE_INFO_T prGlueInfo, -+ IN UINT_64 u8SeqNum, -+ IN UINT_32 u4ChannelNum, -+ IN ENUM_BAND_T eBand, IN ENUM_CHNL_EXT_T eSco, IN UINT_32 u4Duration) -+{ -+ struct ieee80211_channel *prIEEE80211ChnlStruct = (struct ieee80211_channel *)NULL; -+ RF_CHANNEL_INFO_T rChannelInfo; -+ enum nl80211_channel_type eChnlType = NL80211_CHAN_NO_HT; -+ -+ do { -+ if (prGlueInfo == NULL) -+ break; -+ -+ kalMemZero(&rChannelInfo, sizeof(RF_CHANNEL_INFO_T)); -+ -+ rChannelInfo.ucChannelNum = u4ChannelNum; -+ rChannelInfo.eBand = eBand; -+ -+ prIEEE80211ChnlStruct = kalP2pFuncGetChannelEntry(prGlueInfo->prP2PInfo, &rChannelInfo); -+ -+ kalP2pFuncGetChannelType(eSco, &eChnlType); -+ -+ cfg80211_ready_on_channel(prGlueInfo->prP2PInfo->prWdev, /* struct wireless_dev, */ -+ u8SeqNum, /* u64 cookie, */ -+ prIEEE80211ChnlStruct, /* struct ieee80211_channel * chan, */ -+ u4Duration, /* unsigned int duration, */ -+ GFP_KERNEL); /* gfp_t gfp */ /* allocation flags */ -+ } while (FALSE); -+ -+} /* kalP2PIndicateChannelReady */ -+ -+VOID kalP2PIndicateChannelExpired(IN P_GLUE_INFO_T prGlueInfo, IN P_P2P_CHNL_REQ_INFO_T prChnlReqInfo) -+{ -+ -+ P_GL_P2P_INFO_T prGlueP2pInfo = (P_GL_P2P_INFO_T) NULL; -+ struct ieee80211_channel *prIEEE80211ChnlStruct = (struct ieee80211_channel *)NULL; -+ enum nl80211_channel_type eChnlType = NL80211_CHAN_NO_HT; -+ RF_CHANNEL_INFO_T rRfChannelInfo; -+ -+ do { -+ if ((prGlueInfo == NULL) || (prChnlReqInfo == NULL)) { -+ -+ ASSERT(FALSE); -+ break; -+ } -+ -+ prGlueP2pInfo = prGlueInfo->prP2PInfo; -+ -+ if (prGlueP2pInfo == NULL) { -+ ASSERT(FALSE); -+ break; -+ } -+ -+ DBGLOG(P2P, TRACE, "kalP2PIndicateChannelExpired\n"); -+ -+ rRfChannelInfo.eBand = prChnlReqInfo->eBand; -+ rRfChannelInfo.ucChannelNum = prChnlReqInfo->ucReqChnlNum; -+ -+ prIEEE80211ChnlStruct = kalP2pFuncGetChannelEntry(prGlueP2pInfo, &rRfChannelInfo); -+ -+ kalP2pFuncGetChannelType(prChnlReqInfo->eChnlSco, &eChnlType); -+ -+ cfg80211_remain_on_channel_expired(prGlueP2pInfo->prWdev, /* struct wireless_dev, */ -+ prChnlReqInfo->u8Cookie, prIEEE80211ChnlStruct, GFP_KERNEL); -+ } while (FALSE); -+ -+} /* kalP2PIndicateChannelExpired */ -+ -+VOID kalP2PIndicateScanDone(IN P_GLUE_INFO_T prGlueInfo, IN BOOLEAN fgIsAbort) -+{ -+ P_GL_P2P_INFO_T prGlueP2pInfo = (P_GL_P2P_INFO_T) NULL; -+ struct cfg80211_scan_request *prScanRequest = NULL; -+ struct cfg80211_scan_info info = { -+ .aborted = true, -+ }; -+ -+ GLUE_SPIN_LOCK_DECLARATION(); -+ -+ do { -+ if (prGlueInfo == NULL) { -+ -+ ASSERT(FALSE); -+ break; -+ } -+ -+ prGlueP2pInfo = prGlueInfo->prP2PInfo; -+ -+ if (prGlueP2pInfo == NULL) { -+ ASSERT(FALSE); -+ break; -+ } -+ -+ DBGLOG(INIT, TRACE, "[p2p] scan complete %p\n", prGlueP2pInfo->prScanRequest); -+ -+ GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV); -+ if (prGlueP2pInfo->prScanRequest != NULL) { -+ prScanRequest = prGlueP2pInfo->prScanRequest; -+ prGlueP2pInfo->prScanRequest = NULL; -+ } -+ GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV); -+ -+ /* 2. then CFG80211 Indication */ -+ -+ if (prScanRequest != NULL) { -+ -+ /* report all queued beacon/probe response frames to upper layer */ -+ scanReportBss2Cfg80211(prGlueInfo->prAdapter, BSS_TYPE_P2P_DEVICE, NULL); -+ -+ info.aborted = fgIsAbort; -+ DBGLOG(INIT, TRACE, "DBG:p2p_cfg_scan_done\n"); -+ cfg80211_scan_done(prScanRequest, &info); -+ } -+ -+ } while (FALSE); -+ -+} /* kalP2PIndicateScanDone */ -+ -+VOID -+kalP2PIndicateBssInfo(IN P_GLUE_INFO_T prGlueInfo, -+ IN PUINT_8 pucFrameBuf, -+ IN UINT_32 u4BufLen, IN P_RF_CHANNEL_INFO_T prChannelInfo, IN INT_32 i4SignalStrength) -+{ -+ P_GL_P2P_INFO_T prGlueP2pInfo = (P_GL_P2P_INFO_T) NULL; -+ struct ieee80211_channel *prChannelEntry = (struct ieee80211_channel *)NULL; -+ struct ieee80211_mgmt *prBcnProbeRspFrame = (struct ieee80211_mgmt *)pucFrameBuf; -+ struct cfg80211_bss *prCfg80211Bss = (struct cfg80211_bss *)NULL; -+ -+ do { -+ if ((prGlueInfo == NULL) || (pucFrameBuf == NULL) || (prChannelInfo == NULL)) { -+ ASSERT(FALSE); -+ break; -+ } -+ -+ prGlueP2pInfo = prGlueInfo->prP2PInfo; -+ -+ if (prGlueP2pInfo == NULL) { -+ ASSERT(FALSE); -+ break; -+ } -+ -+ prChannelEntry = kalP2pFuncGetChannelEntry(prGlueP2pInfo, prChannelInfo); -+ -+ if (prChannelEntry == NULL) { -+ DBGLOG(P2P, WARN, "Unknown channel info\n"); -+ break; -+ } -+ /* rChannelInfo.center_freq = nicChannelNum2Freq((UINT_32)prChannelInfo->ucChannelNum) / 1000; */ -+ -+ prCfg80211Bss = cfg80211_inform_bss_frame(prGlueP2pInfo->prWdev->wiphy, /* struct wiphy * wiphy, */ -+ prChannelEntry, -+ prBcnProbeRspFrame, u4BufLen, i4SignalStrength, GFP_KERNEL); -+ -+ /* Return this structure. */ -+ if (!prCfg80211Bss) { -+ DBGLOG(P2P, WARN, "inform bss to cfg80211 failed, bss channel %d, rcpi %d\n", -+ prChannelInfo->ucChannelNum, i4SignalStrength); -+ } else { -+ cfg80211_put_bss(prGlueP2pInfo->prWdev->wiphy, prCfg80211Bss); -+ DBGLOG(P2P, TRACE, "inform bss to cfg80211, bss channel %d, rcpi %d\n", -+ prChannelInfo->ucChannelNum, i4SignalStrength); -+ } -+ } while (FALSE); -+ -+} /* kalP2PIndicateBssInfo */ -+ -+VOID -+kalP2PIndicateMgmtTxStatus(IN P_GLUE_INFO_T prGlueInfo, -+ IN UINT_64 u8Cookie, IN BOOLEAN fgIsAck, IN PUINT_8 pucFrameBuf, IN UINT_32 u4FrameLen) -+{ -+ P_GL_P2P_INFO_T prGlueP2pInfo = (P_GL_P2P_INFO_T) NULL; -+ -+ do { -+ if ((prGlueInfo == NULL) || (pucFrameBuf == NULL) || (u4FrameLen == 0)) { -+ DBGLOG(P2P, TRACE, "Unexpected pointer PARAM. %p, %p, %u.", -+ prGlueInfo, pucFrameBuf, u4FrameLen); -+ ASSERT(FALSE); -+ break; -+ } -+ -+ prGlueP2pInfo = prGlueInfo->prP2PInfo; -+ -+ cfg80211_mgmt_tx_status(prGlueP2pInfo->prWdev, /* struct net_device * dev, */ -+ u8Cookie, pucFrameBuf, u4FrameLen, fgIsAck, GFP_KERNEL); -+ -+ } while (FALSE); -+ -+} /* kalP2PIndicateMgmtTxStatus */ -+ -+VOID kalP2PIndicateRxMgmtFrame(IN P_GLUE_INFO_T prGlueInfo, IN P_SW_RFB_T prSwRfb) -+{ -+#define DBG_P2P_MGMT_FRAME_INDICATION 0 -+ P_GL_P2P_INFO_T prGlueP2pInfo = (P_GL_P2P_INFO_T) NULL; -+ INT_32 i4Freq = 0; -+ UINT_8 ucChnlNum = 0; -+#if DBG_P2P_MGMT_FRAME_INDICATION -+ P_WLAN_MAC_HEADER_T prWlanHeader = (P_WLAN_MAC_HEADER_T) NULL; -+#endif -+ -+ do { -+ if ((prGlueInfo == NULL) || (prSwRfb == NULL)) { -+ ASSERT(FALSE); -+ break; -+ } -+ -+ prGlueP2pInfo = prGlueInfo->prP2PInfo; -+ -+ ucChnlNum = prSwRfb->prHifRxHdr->ucHwChannelNum; -+ -+#if DBG_P2P_MGMT_FRAME_INDICATION -+ -+ prWlanHeader = (P_WLAN_MAC_HEADER_T) prSwRfb->pvHeader; -+ -+ switch (prWlanHeader->u2FrameCtrl) { -+ case MAC_FRAME_PROBE_REQ: -+ DBGLOG(P2P, TRACE, "RX Probe Req at channel %d ", ucChnlNum); -+ break; -+ case MAC_FRAME_PROBE_RSP: -+ DBGLOG(P2P, TRACE, "RX Probe Rsp at channel %d ", ucChnlNum); -+ break; -+ case MAC_FRAME_ACTION: -+ DBGLOG(P2P, TRACE, "RX Action frame at channel %d ", ucChnlNum); -+ break; -+ default: -+ DBGLOG(P2P, TRACE, "RX Packet:%d at channel %d ", prWlanHeader->u2FrameCtrl, ucChnlNum); -+ break; -+ } -+ -+ DBGLOG(P2P, TRACE, "from: %pM\n", prWlanHeader->aucAddr2); -+#endif -+ i4Freq = nicChannelNum2Freq(ucChnlNum) / 1000; -+ -+ cfg80211_rx_mgmt(prGlueP2pInfo->prWdev, /* struct net_device * dev, */ -+ i4Freq, -+ RCPI_TO_dBm(prSwRfb->prHifRxHdr->ucRcpi), -+ prSwRfb->pvHeader, prSwRfb->u2PacketLen, GFP_ATOMIC); -+ } while (FALSE); -+ -+} /* kalP2PIndicateRxMgmtFrame */ -+ -+VOID -+kalP2PGCIndicateConnectionStatus(IN P_GLUE_INFO_T prGlueInfo, -+ IN P_P2P_CONNECTION_REQ_INFO_T prP2pConnInfo, -+ IN PUINT_8 pucRxIEBuf, IN UINT_16 u2RxIELen, IN UINT_16 u2StatusReason, -+ IN WLAN_STATUS eStatus) -+{ -+ P_GL_P2P_INFO_T prGlueP2pInfo = (P_GL_P2P_INFO_T) NULL; -+ -+ do { -+ if (prGlueInfo == NULL) { -+ ASSERT(FALSE); -+ break; -+ } -+ -+ prGlueP2pInfo = prGlueInfo->prP2PInfo; -+ -+ if (prP2pConnInfo) { -+ cfg80211_connect_result(prGlueP2pInfo->prDevHandler, /* struct net_device * dev, */ -+ prP2pConnInfo->aucBssid, prP2pConnInfo->aucIEBuf, -+ prP2pConnInfo->u4BufLength, -+ pucRxIEBuf, u2RxIELen, u2StatusReason, GFP_KERNEL); -+ /* gfp_t gfp */ /* allocation flags */ -+ prP2pConnInfo->fgIsConnRequest = FALSE; -+ } else { -+ /* Disconnect, what if u2StatusReason == 0? */ -+ cfg80211_disconnected(prGlueP2pInfo->prDevHandler, /* struct net_device * dev, */ -+ u2StatusReason, pucRxIEBuf, u2RxIELen, -+ eStatus == WLAN_STATUS_MEDIA_DISCONNECT_LOCALLY ? true : false, -+ GFP_KERNEL); -+ } -+ -+ } while (FALSE); -+ -+} /* kalP2PGCIndicateConnectionStatus */ -+ -+VOID kalP2PGOStationUpdate(IN P_GLUE_INFO_T prGlueInfo, IN P_STA_RECORD_T prCliStaRec, IN BOOLEAN fgIsNew) -+{ -+ P_GL_P2P_INFO_T prP2pGlueInfo = (P_GL_P2P_INFO_T) NULL; -+ struct station_info rStationInfo; -+ -+ memset(&rStationInfo, 0, sizeof(struct station_info)); -+ -+ do { -+ if ((prGlueInfo == NULL) || (prCliStaRec == NULL)) -+ break; -+ -+ prP2pGlueInfo = prGlueInfo->prP2PInfo; -+ -+ if (fgIsNew) { -+ //rStationInfo.filled = STATION_INFO_ASSOC_REQ_IES; -+ rStationInfo.generation = ++prP2pGlueInfo->i4Generation; -+ -+ rStationInfo.assoc_req_ies = prCliStaRec->pucAssocReqIe; -+ rStationInfo.assoc_req_ies_len = prCliStaRec->u2AssocReqIeLen; -+/* rStationInfo.filled |= STATION_INFO_ASSOC_REQ_IES; */ -+ -+ cfg80211_new_sta(prGlueInfo->prP2PInfo->prDevHandler, /* struct net_device * dev, */ -+ prCliStaRec->aucMacAddr, &rStationInfo, GFP_KERNEL); -+ } else { -+ ++prP2pGlueInfo->i4Generation; -+ -+ cfg80211_del_sta(prGlueInfo->prP2PInfo->prDevHandler, /* struct net_device * dev, */ -+ prCliStaRec->aucMacAddr, GFP_KERNEL); -+ } -+ -+ } while (FALSE); -+ -+ return; -+ -+} /* kalP2PGOStationUpdate */ -+ -+BOOLEAN kalP2pFuncGetChannelType(IN ENUM_CHNL_EXT_T rChnlSco, OUT enum nl80211_channel_type *channel_type) -+{ -+ BOOLEAN fgIsValid = FALSE; -+ -+ do { -+ if (channel_type) { -+ -+ switch (rChnlSco) { -+ case CHNL_EXT_SCN: -+ *channel_type = NL80211_CHAN_NO_HT; -+ break; -+ case CHNL_EXT_SCA: -+ *channel_type = NL80211_CHAN_HT40MINUS; -+ break; -+ case CHNL_EXT_SCB: -+ *channel_type = NL80211_CHAN_HT40PLUS; -+ break; -+ default: -+ ASSERT(FALSE); -+ *channel_type = NL80211_CHAN_NO_HT; -+ break; -+ } -+ -+ } -+ -+ fgIsValid = TRUE; -+ } while (FALSE); -+ -+ return fgIsValid; -+} /* kalP2pFuncGetChannelType */ -+ -+struct ieee80211_channel *kalP2pFuncGetChannelEntry(IN P_GL_P2P_INFO_T prP2pInfo, IN P_RF_CHANNEL_INFO_T prChannelInfo) -+{ -+ struct ieee80211_channel *prTargetChannelEntry = (struct ieee80211_channel *)NULL; -+ UINT_32 u4TblSize = 0, u4Idx = 0; -+ struct ieee80211_supported_band **bands; -+ -+ do { -+ if ((prP2pInfo == NULL) || (prChannelInfo == NULL)) -+ break; -+ bands = &prP2pInfo->prWdev->wiphy->bands[0]; -+ switch (prChannelInfo->eBand) { -+ case BAND_2G4: -+ prTargetChannelEntry = bands[NL80211_BAND_2GHZ]->channels; -+ u4TblSize = bands[NL80211_BAND_2GHZ]->n_channels; -+ break; -+ case BAND_5G: -+ prTargetChannelEntry = bands[NL80211_BAND_5GHZ]->channels; -+ u4TblSize = bands[NL80211_BAND_5GHZ]->n_channels; -+ break; -+ default: -+ break; -+ } -+ -+ if (prTargetChannelEntry == NULL) -+ break; -+ -+ for (u4Idx = 0; u4Idx < u4TblSize; u4Idx++, prTargetChannelEntry++) { -+ if (prTargetChannelEntry->hw_value == prChannelInfo->ucChannelNum) -+ break; -+ } -+ -+ if (u4Idx == u4TblSize) { -+ prTargetChannelEntry = NULL; -+ break; -+ } -+ -+ } while (FALSE); -+ -+ return prTargetChannelEntry; -+} /* kalP2pFuncGetChannelEntry */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief to set the block list of Hotspot -+* -+* \param[in] -+* prGlueInfo -+* -+* \return -+*/ -+/*----------------------------------------------------------------------------*/ -+INT_32 kalP2PSetBlackList(IN P_GLUE_INFO_T prGlueInfo, IN PARAM_MAC_ADDRESS rbssid, IN BOOLEAN fgIsblock) -+{ -+ UINT_8 aucNullAddr[] = NULL_MAC_ADDR; -+ UINT_32 i; -+ -+ ASSERT(prGlueInfo); -+ ASSERT(prGlueInfo->prP2PInfo); -+ -+ if (EQUAL_MAC_ADDR(rbssid, aucNullAddr)) -+ return -EINVAL; -+ -+ if (fgIsblock) { -+ for (i = 0; i < 8; i++) { -+ if (EQUAL_MAC_ADDR(&(prGlueInfo->prP2PInfo->aucblackMACList[i]), rbssid)) { -+ break; -+ } else if (EQUAL_MAC_ADDR(&(prGlueInfo->prP2PInfo->aucblackMACList[i]), aucNullAddr)) { -+ COPY_MAC_ADDR(&(prGlueInfo->prP2PInfo->aucblackMACList[i]), rbssid); -+ break; -+ } -+ } -+ if (i >= 8) { -+ DBGLOG(P2P, ERROR, "AP black list is full, cannot block more STA!!\n"); -+ return -ENOBUFS; -+ } -+ } else { -+ for (i = 0; i < 8; i++) { -+ if (EQUAL_MAC_ADDR(&(prGlueInfo->prP2PInfo->aucblackMACList[i]), rbssid)) { -+ COPY_MAC_ADDR(&(prGlueInfo->prP2PInfo->aucblackMACList[i]), aucNullAddr); -+ break; -+ } -+ } -+ if (i >= 8) -+ DBGLOG(P2P, ERROR, "The STA is not found in black list!!\n"); -+ } -+ -+ return 0; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief to compare the black list of Hotspot -+* -+* \param[in] -+* prGlueInfo -+* -+* \return -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN kalP2PCmpBlackList(IN P_GLUE_INFO_T prGlueInfo, IN PARAM_MAC_ADDRESS rbssid) -+{ -+ UINT_8 aucNullAddr[] = NULL_MAC_ADDR; -+ BOOLEAN fgIsExsit = FALSE; -+ UINT_32 i; -+ -+ ASSERT(prGlueInfo); -+ ASSERT(prGlueInfo->prP2PInfo); -+ -+ for (i = 0; i < 8; i++) { -+ if (UNEQUAL_MAC_ADDR(rbssid, aucNullAddr)) { -+ if (EQUAL_MAC_ADDR(&(prGlueInfo->prP2PInfo->aucblackMACList[i]), rbssid)) { -+ fgIsExsit = TRUE; -+ return fgIsExsit; -+ } -+ } -+ } -+ -+ return fgIsExsit; -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief to return the max clients of Hotspot -+* -+* \param[in] -+* prGlueInfo -+* -+* \return -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID kalP2PSetMaxClients(IN P_GLUE_INFO_T prGlueInfo, IN UINT_32 u4MaxClient) -+{ -+ if ((!prGlueInfo) || (!prGlueInfo->prP2PInfo)) { -+ ASSERT(FALSE); -+ return; -+ } -+ -+ if (u4MaxClient == 0 || prGlueInfo->prP2PInfo->ucMaxClients >= P2P_MAXIMUM_CLIENT_COUNT) -+ prGlueInfo->prP2PInfo->ucMaxClients = P2P_MAXIMUM_CLIENT_COUNT; -+ else -+ prGlueInfo->prP2PInfo->ucMaxClients = u4MaxClient; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief to return the max clients of Hotspot -+* -+* \param[in] -+* prGlueInfo -+* -+* \return -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN kalP2PMaxClients(IN P_GLUE_INFO_T prGlueInfo, IN UINT_32 u4NumClient) -+{ -+ if ((!prGlueInfo) || (!prGlueInfo->prP2PInfo)) { -+ ASSERT(FALSE); -+ return FALSE; -+ } -+ -+ if (prGlueInfo->prP2PInfo->ucMaxClients) { -+ if ((UINT_8) u4NumClient > prGlueInfo->prP2PInfo->ucMaxClients) -+ return TRUE; -+ else -+ return FALSE; -+ } -+ -+ return FALSE; -+} -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_proc.c b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_proc.c -new file mode 100644 -index 000000000000..075045f547b7 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_proc.c -@@ -0,0 +1,1020 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux/gl_proc.c#1 -+*/ -+ -+/*! \file "gl_proc.c" -+ \brief This file defines the interface which can interact with users in /proc fs. -+ -+ Detail description. -+*/ -+ -+/* -+** Log: gl_proc.c -+ * -+ * 11 10 2011 cp.wu -+ * [WCXRP00001098] [MT6620 Wi-Fi][Driver] Replace printk by DBG LOG macros in linux porting layer -+ * 1. eliminaite direct calls to printk in porting layer. -+ * 2. replaced by DBGLOG, which would be XLOG on ALPS platforms. -+ * -+ * 12 10 2010 kevin.huang -+ * [WCXRP00000128] [MT6620 Wi-Fi][Driver] Add proc support to Android Driver for debug and driver status check -+ * Add Linux Proc Support -+** \main\maintrunk.MT5921\19 2008-09-02 21:08:37 GMT mtk01461 -+** Fix the compile error of SPRINTF() -+** \main\maintrunk.MT5921\18 2008-08-10 18:48:28 GMT mtk01461 -+** Update for Driver Review -+** \main\maintrunk.MT5921\17 2008-08-04 16:52:01 GMT mtk01461 -+** Add proc dbg print message of DOMAIN_INDEX level -+** \main\maintrunk.MT5921\16 2008-07-10 00:45:16 GMT mtk01461 -+** Remove the check of MCR offset, we may use the MCR address which is not align to DW boundary or proprietary usage. -+** \main\maintrunk.MT5921\15 2008-06-03 20:49:44 GMT mtk01461 -+** \main\maintrunk.MT5921\14 2008-06-02 22:56:00 GMT mtk01461 -+** Rename some functions for linux proc -+** \main\maintrunk.MT5921\13 2008-06-02 20:23:18 GMT mtk01461 -+** Revise PROC mcr read / write for supporting TELNET -+** \main\maintrunk.MT5921\12 2008-03-28 10:40:25 GMT mtk01461 -+** Remove temporary set desired rate in linux proc -+** \main\maintrunk.MT5921\11 2008-01-07 15:07:29 GMT mtk01461 -+** Add User Update Desired Rate Set for QA in Linux -+** \main\maintrunk.MT5921\10 2007-12-11 00:11:14 GMT mtk01461 -+** Fix SPIN_LOCK protection -+** \main\maintrunk.MT5921\9 2007-12-04 18:07:57 GMT mtk01461 -+** Add additional debug category to proc -+** \main\maintrunk.MT5921\8 2007-11-02 01:03:23 GMT mtk01461 -+** Unify TX Path for Normal and IBSS Power Save + IBSS neighbor learning -+** \main\maintrunk.MT5921\7 2007-10-25 18:08:14 GMT mtk01461 -+** Add VOIP SCAN Support & Refine Roaming -+** Revision 1.3 2007/07/05 07:25:33 MTK01461 -+** Add Linux initial code, modify doc, add 11BB, RF init code -+** -+** Revision 1.2 2007/06/27 02:18:51 MTK01461 -+** Update SCAN_FSM, Initial(Can Load Module), Proc(Can do Reg R/W), TX API -+** -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+#include "precomp.h" -+ -+/* #include "wlan_lib.h" */ -+/* #include "debug.h" */ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+#define PROC_WLAN_THERMO "wlanThermo" -+#define PROC_DRV_STATUS "status" -+#define PROC_RX_STATISTICS "rx_statistics" -+#define PROC_TX_STATISTICS "tx_statistics" -+#define PROC_DBG_LEVEL_NAME "dbgLevel" -+#define PROC_NEED_TX_DONE "TxDoneCfg" -+#define PROC_AUTO_PER_CFG "autoPerCfg" -+#define PROC_ROOT_NAME "wlan" -+#define PROC_CMD_DEBUG_NAME "cmdDebug" -+ -+#define PROC_MCR_ACCESS_MAX_USER_INPUT_LEN 20 -+#define PROC_RX_STATISTICS_MAX_USER_INPUT_LEN 10 -+#define PROC_TX_STATISTICS_MAX_USER_INPUT_LEN 10 -+#define PROC_DBG_LEVEL_MAX_USER_INPUT_LEN (20*10) -+#define PROC_DBG_LEVEL_MAX_DISPLAY_STR_LEN 8 -+ -+#define PROC_UID_SHELL 2000 -+#define PROC_GID_WIFI 1010 -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+/* static UINT_32 u4McrOffset; */ -+#if CFG_SUPPORT_THERMO_THROTTLING -+static P_GLUE_INFO_T g_prGlueInfo_proc; -+#endif -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief The PROC function for reading MCR register to User Space, the offset of -+* the MCR is specified in u4McrOffset. -+* -+* \param[in] page Buffer provided by kernel. -+* \param[in out] start Start Address to read(3 methods). -+* \param[in] off Offset. -+* \param[in] count Allowable number to read. -+* \param[out] eof End of File indication. -+* \param[in] data Pointer to the private data structure. -+* -+* \return number of characters print to the buffer from User Space. -+*/ -+/*----------------------------------------------------------------------------*/ -+#if 0 -+static int procMCRRead(char *page, char **start, off_t off, int count, int *eof, void *data) -+{ -+ P_GLUE_INFO_T prGlueInfo; -+ PARAM_CUSTOM_MCR_RW_STRUCT_T rMcrInfo; -+ UINT_32 u4BufLen; -+ char *p = page; -+ UINT_32 u4Count; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ -+ ASSERT(data); -+ -+ /* Kevin: Apply PROC read method 1. */ -+ if (off != 0) -+ return 0; /* To indicate end of file. */ -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv((struct net_device *)data)); -+ -+ rMcrInfo.u4McrOffset = u4McrOffset; -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidQueryMcrRead, -+ (PVOID)&rMcrInfo, sizeof(rMcrInfo), TRUE, TRUE, TRUE, FALSE, &u4BufLen); -+ -+ /* SPRINTF(p, ("MCR (0x%08lxh): 0x%08lx\n", */ -+ /* rMcrInfo.u4McrOffset, rMcrInfo.u4McrData)); */ -+ -+ u4Count = (UINT_32) (p - page); -+ -+ *eof = 1; -+ -+ return (int)u4Count; -+ -+} /* end of procMCRRead() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief The PROC function for writing MCR register to HW or update u4McrOffset -+* for reading MCR later. -+* -+* \param[in] file pointer to file. -+* \param[in] buffer Buffer from user space. -+* \param[in] count Number of characters to write -+* \param[in] data Pointer to the private data structure. -+* -+* \return number of characters write from User Space. -+*/ -+/*----------------------------------------------------------------------------*/ -+static int procMCRWrite(struct file *file, const char *buffer, unsigned long count, void *data) -+{ -+ P_GLUE_INFO_T prGlueInfo; -+ char acBuf[PROC_MCR_ACCESS_MAX_USER_INPUT_LEN + 1]; /* + 1 for "\0" */ -+ int i4CopySize; -+ PARAM_CUSTOM_MCR_RW_STRUCT_T rMcrInfo; -+ UINT_32 u4BufLen; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ -+ ASSERT(data); -+ -+ i4CopySize = (count < (sizeof(acBuf) - 1)) ? count : (sizeof(acBuf) - 1); -+ if (copy_from_user(acBuf, buffer, i4CopySize)) -+ return 0; -+ acBuf[i4CopySize] = '\0'; -+ -+ if (sscanf(acBuf, "0x%lx 0x%lx", &rMcrInfo.u4McrOffset, &rMcrInfo.u4McrData) == 2) { -+ /* NOTE: Sometimes we want to test if bus will still be ok, after accessing -+ * the MCR which is not align to DW boundary. -+ */ -+ /* if (IS_ALIGN_4(rMcrInfo.u4McrOffset)) */ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv((struct net_device *)data)); -+ -+ u4McrOffset = rMcrInfo.u4McrOffset; -+ -+ /* printk("Write 0x%lx to MCR 0x%04lx\n", */ -+ /* rMcrInfo.u4McrOffset, rMcrInfo.u4McrData); */ -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetMcrWrite, -+ (PVOID)&rMcrInfo, sizeof(rMcrInfo), FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ } -+ -+ if (sscanf(acBuf, "0x%lx 0x%lx", &rMcrInfo.u4McrOffset, &rMcrInfo.u4McrData) == 1) { -+ /* if (IS_ALIGN_4(rMcrInfo.u4McrOffset)) */ -+ u4McrOffset = rMcrInfo.u4McrOffset; -+ } -+ -+ return count; -+ -+} /* end of procMCRWrite() */ -+#endif -+ -+#if 0 -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief The PROC function for reading Driver Status to User Space. -+* -+* \param[in] page Buffer provided by kernel. -+* \param[in out] start Start Address to read(3 methods). -+* \param[in] off Offset. -+* \param[in] count Allowable number to read. -+* \param[out] eof End of File indication. -+* \param[in] data Pointer to the private data structure. -+* -+* \return number of characters print to the buffer from User Space. -+*/ -+/*----------------------------------------------------------------------------*/ -+static int procDrvStatusRead(char *page, char **start, off_t off, int count, int *eof, void *data) -+{ -+ P_GLUE_INFO_T prGlueInfo = ((struct net_device *)data)->priv; -+ char *p = page; -+ UINT_32 u4Count; -+ -+ GLUE_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(data); -+ -+ /* Kevin: Apply PROC read method 1. */ -+ if (off != 0) -+ return 0; /* To indicate end of file. */ -+ -+ SPRINTF(p, ("GLUE LAYER STATUS:")); -+ SPRINTF(p, ("\n==================")); -+ -+ SPRINTF(p, ("\n* Number of Pending Frames: %ld\n", prGlueInfo->u4TxPendingFrameNum)); -+ -+ GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_FSM); -+ -+ wlanoidQueryDrvStatusForLinuxProc(prGlueInfo->prAdapter, p, &u4Count); -+ -+ GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_FSM); -+ -+ u4Count += (UINT_32) (p - page); -+ -+ *eof = 1; -+ -+ return (int)u4Count; -+ -+} /* end of procDrvStatusRead() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief The PROC function for reading Driver RX Statistic Counters to User Space. -+* -+* \param[in] page Buffer provided by kernel. -+* \param[in out] start Start Address to read(3 methods). -+* \param[in] off Offset. -+* \param[in] count Allowable number to read. -+* \param[out] eof End of File indication. -+* \param[in] data Pointer to the private data structure. -+* -+* \return number of characters print to the buffer from User Space. -+*/ -+/*----------------------------------------------------------------------------*/ -+static int procRxStatisticsRead(char *page, char **start, off_t off, int count, int *eof, void *data) -+{ -+ P_GLUE_INFO_T prGlueInfo = ((struct net_device *)data)->priv; -+ char *p = page; -+ UINT_32 u4Count; -+ -+ GLUE_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(data); -+ -+ /* Kevin: Apply PROC read method 1. */ -+ if (off != 0) -+ return 0; /* To indicate end of file. */ -+ -+ SPRINTF(p, ("RX STATISTICS (Write 1 to clear):")); -+ SPRINTF(p, ("\n=================================\n")); -+ -+ GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_FSM); -+ -+ wlanoidQueryRxStatisticsForLinuxProc(prGlueInfo->prAdapter, p, &u4Count); -+ -+ GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_FSM); -+ -+ u4Count += (UINT_32) (p - page); -+ -+ *eof = 1; -+ -+ return (int)u4Count; -+ -+} /* end of procRxStatisticsRead() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief The PROC function for reset Driver RX Statistic Counters. -+* -+* \param[in] file pointer to file. -+* \param[in] buffer Buffer from user space. -+* \param[in] count Number of characters to write -+* \param[in] data Pointer to the private data structure. -+* -+* \return number of characters write from User Space. -+*/ -+/*----------------------------------------------------------------------------*/ -+static int procRxStatisticsWrite(struct file *file, const char *buffer, unsigned long count, void *data) -+{ -+ P_GLUE_INFO_T prGlueInfo = ((struct net_device *)data)->priv; -+ char acBuf[PROC_RX_STATISTICS_MAX_USER_INPUT_LEN + 1]; /* + 1 for "\0" */ -+ UINT_32 u4CopySize; -+ UINT_32 u4ClearCounter; -+ -+ GLUE_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(data); -+ -+ u4CopySize = (count < (sizeof(acBuf) - 1)) ? count : (sizeof(acBuf) - 1); -+ copy_from_user(acBuf, buffer, u4CopySize); -+ acBuf[u4CopySize] = '\0'; -+ -+ if (kstrtoint(acBuf, 10, &u4ClearCounter) == 1) { -+ if (u4ClearCounter == 1) { -+ GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_FSM); -+ -+ wlanoidSetRxStatisticsForLinuxProc(prGlueInfo->prAdapter); -+ -+ GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_FSM); -+ } -+ } -+ -+ return count; -+ -+} /* end of procRxStatisticsWrite() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief The PROC function for reading Driver TX Statistic Counters to User Space. -+* -+* \param[in] page Buffer provided by kernel. -+* \param[in out] start Start Address to read(3 methods). -+* \param[in] off Offset. -+* \param[in] count Allowable number to read. -+* \param[out] eof End of File indication. -+* \param[in] data Pointer to the private data structure. -+* -+* \return number of characters print to the buffer from User Space. -+*/ -+/*----------------------------------------------------------------------------*/ -+static int procTxStatisticsRead(char *page, char **start, off_t off, int count, int *eof, void *data) -+{ -+ P_GLUE_INFO_T prGlueInfo = ((struct net_device *)data)->priv; -+ char *p = page; -+ UINT_32 u4Count; -+ -+ GLUE_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(data); -+ -+ /* Kevin: Apply PROC read method 1. */ -+ if (off != 0) -+ return 0; /* To indicate end of file. */ -+ -+ SPRINTF(p, ("TX STATISTICS (Write 1 to clear):")); -+ SPRINTF(p, ("\n=================================\n")); -+ -+ GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_FSM); -+ -+ wlanoidQueryTxStatisticsForLinuxProc(prGlueInfo->prAdapter, p, &u4Count); -+ -+ GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_FSM); -+ -+ u4Count += (UINT_32) (p - page); -+ -+ *eof = 1; -+ -+ return (int)u4Count; -+ -+} /* end of procTxStatisticsRead() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief The PROC function for reset Driver TX Statistic Counters. -+* -+* \param[in] file pointer to file. -+* \param[in] buffer Buffer from user space. -+* \param[in] count Number of characters to write -+* \param[in] data Pointer to the private data structure. -+* -+* \return number of characters write from User Space. -+*/ -+/*----------------------------------------------------------------------------*/ -+static int procTxStatisticsWrite(struct file *file, const char *buffer, unsigned long count, void *data) -+{ -+ P_GLUE_INFO_T prGlueInfo = ((struct net_device *)data)->priv; -+ char acBuf[PROC_RX_STATISTICS_MAX_USER_INPUT_LEN + 1]; /* + 1 for "\0" */ -+ UINT_32 u4CopySize; -+ UINT_32 u4ClearCounter; -+ -+ GLUE_SPIN_LOCK_DECLARATION(); -+ -+ ASSERT(data); -+ -+ u4CopySize = (count < (sizeof(acBuf) - 1)) ? count : (sizeof(acBuf) - 1); -+ copy_from_user(acBuf, buffer, u4CopySize); -+ acBuf[u4CopySize] = '\0'; -+ -+ if (kstrtoint(acBuf, 10, &u4ClearCounter) == 1) { -+ if (u4ClearCounter == 1) { -+ GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_FSM); -+ -+ wlanoidSetTxStatisticsForLinuxProc(prGlueInfo->prAdapter); -+ -+ GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_FSM); -+ } -+ } -+ -+ return count; -+ -+} /* end of procTxStatisticsWrite() */ -+#endif -+static struct proc_dir_entry *gprProcRoot; -+static UINT_8 aucDbModuleName[][PROC_DBG_LEVEL_MAX_DISPLAY_STR_LEN] = { -+ "INIT", "HAL", "INTR", "REQ", "TX", "RX", "RFTEST", "EMU", "SW1", "SW2", -+ "SW3", "SW4", "HEM", "AIS", "RLM", "MEM", "CNM", "RSN", "BSS", "SCN", -+ "SAA", "AAA", "P2P", "QM", "SEC", "BOW", "WAPI", "ROAMING", "TDLS", "OID", -+ "NIC" -+}; -+static UINT_8 aucProcBuf[1536]; -+static ssize_t procDbgLevelRead(struct file *filp, char __user *buf, size_t count, loff_t *f_pos) -+{ -+ UINT_8 *temp = &aucProcBuf[0]; -+ UINT_32 u4CopySize = 0; -+ UINT_16 i; -+ UINT_16 u2ModuleNum = 0; -+ -+ /* if *f_ops>0, we should return 0 to make cat command exit */ -+ if (*f_pos > 0) -+ return 0; -+ -+ kalStrCpy(temp, "\nTEMP |LOUD |INFO |TRACE|EVENT|STATE|WARN |ERROR\n" -+ "bit7 |bit6 |bit5 |bit4 |bit3 |bit2 |bit1 |bit0\n\n" -+ "Debug Module\tIndex\tLevel\tDebug Module\tIndex\tLevel\n\n"); -+ temp += kalStrLen(temp); -+ -+ u2ModuleNum = (sizeof(aucDbModuleName) / PROC_DBG_LEVEL_MAX_DISPLAY_STR_LEN) & 0xfe; -+ for (i = 0; i < u2ModuleNum; i += 2) -+ SPRINTF(temp, ("DBG_%s_IDX\t(0x%02x):\t0x%02x\tDBG_%s_IDX\t(0x%02x):\t0x%02x\n", -+ &aucDbModuleName[i][0], i, aucDebugModule[i], -+ &aucDbModuleName[i+1][0], i+1, aucDebugModule[i+1])); -+ -+ if ((sizeof(aucDbModuleName) / PROC_DBG_LEVEL_MAX_DISPLAY_STR_LEN) & 0x1) -+ SPRINTF(temp, ("DBG_%s_IDX\t(0x%02x):\t0x%02x\n", -+ &aucDbModuleName[u2ModuleNum][0], u2ModuleNum, aucDebugModule[u2ModuleNum])); -+ -+ u4CopySize = kalStrLen(aucProcBuf); -+ if (u4CopySize > count) -+ u4CopySize = count; -+ if (copy_to_user(buf, aucProcBuf, u4CopySize)) { -+ kalPrint("copy to user failed\n"); -+ return -EFAULT; -+ } -+ -+ *f_pos += u4CopySize; -+ return (ssize_t)u4CopySize; -+} -+ -+static ssize_t procDbgLevelWrite(struct file *file, const char *buffer, size_t count, loff_t *data) -+{ -+ UINT_32 u4NewDbgModule, u4NewDbgLevel; -+ UINT_8 i = 0; -+ UINT_32 u4CopySize = kalStrLen(aucProcBuf);//sizeof(aucProcBuf); -+ UINT_8 *temp = &aucProcBuf[0]; -+ -+ if (u4CopySize >= count + 1) -+ u4CopySize = count; -+ -+ kalMemSet(aucProcBuf, 0, u4CopySize); -+ -+ if (copy_from_user(aucProcBuf, buffer, u4CopySize)) { -+ kalPrint("error of copy from user\n"); -+ return -EFAULT; -+ } -+ aucProcBuf[u4CopySize] = '\0'; -+ -+ while (temp) { -+ if (sscanf(temp, "0x%x:0x%x", &u4NewDbgModule, &u4NewDbgLevel) != 2) { -+ kalPrint("debug module and debug level should be one byte in length\n"); -+ break; -+ } -+ if (u4NewDbgModule == 0xFF) { -+ for (i = 0; i < DBG_MODULE_NUM; i++) -+ aucDebugModule[i] = u4NewDbgLevel & DBG_CLASS_MASK; -+ -+ break; -+ } else if (u4NewDbgModule >= DBG_MODULE_NUM) { -+ kalPrint("debug module index should less than %d\n", DBG_MODULE_NUM); -+ break; -+ } -+ aucDebugModule[u4NewDbgModule] = u4NewDbgLevel & DBG_CLASS_MASK; -+ temp = kalStrChr(temp, ','); -+ if (!temp) -+ break; -+ temp++; /* skip ',' */ -+ } -+ return count; -+} -+ -+ -+static const struct file_operations dbglevel_ops = { -+ .owner = THIS_MODULE, -+ .read = procDbgLevelRead, -+ .write = procDbgLevelWrite, -+}; -+ -+static ssize_t procTxDoneCfgRead(struct file *filp, char __user *buf, size_t count, loff_t *f_pos) -+{ -+ UINT_8 *temp = &aucProcBuf[0]; -+ UINT_32 u4CopySize = 0; -+ UINT_16 u2TxDoneCfg = 0; -+ -+ /* if *f_ops>0, we should return 0 to make cat command exit */ -+ if (*f_pos > 0) -+ return 0; -+ -+ u2TxDoneCfg = StatsGetCfgTxDone(); -+ SPRINTF(temp, ("Tx Done Configure:\nARP %d\tDNS %d\nTCP %d\tUDP %d\nEAPOL %d\tDHCP %d\nICMP %d\n", -+ !!(u2TxDoneCfg & CFG_ARP), !!(u2TxDoneCfg & CFG_DNS), !!(u2TxDoneCfg & CFG_TCP), -+ !!(u2TxDoneCfg & CFG_UDP), !!(u2TxDoneCfg & CFG_EAPOL), !!(u2TxDoneCfg & CFG_DHCP), -+ !!(u2TxDoneCfg & CFG_ICMP))); -+ -+ u4CopySize = kalStrLen(aucProcBuf); -+ if (u4CopySize > count) -+ u4CopySize = count; -+ if (copy_to_user(buf, aucProcBuf, u4CopySize)) { -+ kalPrint("copy to user failed\n"); -+ return -EFAULT; -+ } -+ -+ *f_pos += u4CopySize; -+ return (ssize_t)u4CopySize; -+} -+ -+static ssize_t procTxDoneCfgWrite(struct file *file, const char *buffer, size_t count, loff_t *data) -+{ -+#define MODULE_NAME_LENGTH 6 -+ -+ UINT_8 i = 0; -+ UINT_32 u4CopySize = kalStrLen(aucProcBuf);//sizeof(aucProcBuf); -+ UINT_8 *temp = &aucProcBuf[0]; -+ UINT_16 u2SetTxDoneCfg = 0; -+ UINT_16 u2ClsTxDoneCfg = 0; -+ UINT_8 aucModule[MODULE_NAME_LENGTH]; -+ UINT_32 u4Enabled; -+ UINT_8 aucModuleArray[][MODULE_NAME_LENGTH] = {"ARP", "DNS", "TCP", "UDP", "EAPOL", "DHCP", "ICMP"}; -+ -+ if (u4CopySize >= count + 1) -+ u4CopySize = count; -+ -+ kalMemSet(aucProcBuf, 0, u4CopySize); -+ if (copy_from_user(aucProcBuf, buffer, u4CopySize)) { -+ kalPrint("error of copy from user\n"); -+ return -EFAULT; -+ } -+ aucProcBuf[u4CopySize] = '\0'; -+ temp = &aucProcBuf[0]; -+ while (temp) { -+ /* pick up a string and teminated after meet : */ -+ if (sscanf(temp, "%s %d", aucModule, &u4Enabled) != 2) { -+ kalPrint("read param fail, aucModule=%s\n", aucModule); -+ break; -+ } -+ for (i = 0; i < sizeof(aucModuleArray)/MODULE_NAME_LENGTH; i++) { -+ if (kalStrniCmp(aucModule, aucModuleArray[i], MODULE_NAME_LENGTH) == 0) { -+ if (u4Enabled) -+ u2SetTxDoneCfg |= 1 << i; -+ else -+ u2ClsTxDoneCfg |= 1 << i; -+ break; -+ } -+ } -+ temp = kalStrChr(temp, ','); -+ if (!temp) -+ break; -+ temp++; /* skip ',' */ -+ } -+ if (u2SetTxDoneCfg) -+ StatsSetCfgTxDone(u2SetTxDoneCfg, TRUE); -+ -+ if (u2ClsTxDoneCfg) -+ StatsSetCfgTxDone(u2ClsTxDoneCfg, FALSE); -+ return count; -+} -+ -+static const struct file_operations proc_txdone_ops = { -+ .owner = THIS_MODULE, -+ .read = procTxDoneCfgRead, -+ .write = procTxDoneCfgWrite, -+}; -+ -+static ssize_t procAutoPerCfgRead(struct file *filp, char __user *buf, size_t count, loff_t *f_pos) -+{ -+ UINT_8 *temp = &aucProcBuf[0]; -+ UINT_32 u4CopySize = 0; -+ -+ /* if *f_ops>0, we should return 0 to make cat command exit */ -+ if (*f_pos > 0) -+ return 0; -+ -+ SPRINTF(temp, ("Auto Performance Configure:\nperiod\tL1\nL2\tL3\n")); -+ -+ u4CopySize = kalStrLen(aucProcBuf); -+ if (u4CopySize > count) -+ u4CopySize = count; -+ if (copy_to_user(buf, aucProcBuf, u4CopySize)) { -+ kalPrint("copy to user failed\n"); -+ return -EFAULT; -+ } -+ -+ *f_pos += u4CopySize; -+ return (ssize_t)u4CopySize; -+} -+ -+static ssize_t procAutoPerCfgWrite(struct file *file, const char *buffer, size_t count, loff_t *data) -+{ -+ DBGLOG(INIT, WARN, "%s\n", __func__); -+ return 0; -+} -+ -+static const struct file_operations auto_per_ops = { -+ .owner = THIS_MODULE, -+ .read = procAutoPerCfgRead, -+ .write = procAutoPerCfgWrite, -+}; -+ -+ -+static ssize_t procCmdDebug(struct file *filp, char __user *buf, size_t count, loff_t *f_pos) -+{ -+ UINT_32 u4CopySize = 0; -+ -+ /* if *f_ops>0, we should return 0 to make cat command exit */ -+ if (*f_pos > 0) -+ return 0; -+ -+ wlanDumpTcResAndTxedCmd(aucProcBuf, sizeof(aucProcBuf)); -+ -+ u4CopySize = kalStrLen(aucProcBuf); -+ if (u4CopySize > count) -+ u4CopySize = count; -+ if (copy_to_user(buf, aucProcBuf, u4CopySize)) { -+ kalPrint("copy to user failed\n"); -+ return -EFAULT; -+ } -+ -+ *f_pos += u4CopySize; -+ return (ssize_t)u4CopySize; -+} -+ -+static const struct file_operations proc_CmdDebug_ops = { -+ .owner = THIS_MODULE, -+ .read = procCmdDebug, -+}; -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function create a PROC fs in linux /proc/net subdirectory. -+* -+* \param[in] prDev Pointer to the struct net_device. -+* \param[in] pucDevName Pointer to the name of net_device. -+* -+* \return N/A -+*/ -+/*----------------------------------------------------------------------------*/ -+ -+#if CFG_SUPPORT_THERMO_THROTTLING -+ -+/** -+ * This function is called then the /proc file is read -+ * -+ */ -+typedef struct _COEX_BUF1 { -+ UINT8 buffer[128]; -+ INT32 availSize; -+} COEX_BUF1, *P_COEX_BUF1; -+ -+COEX_BUF1 gCoexBuf1; -+ -+static ssize_t procfile_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos) -+{ -+ -+ INT32 retval = 0; -+ INT32 i_ret = 0; -+ CHAR *warn_msg = "no data available, please run echo 15 xx > /proc/driver/wmt_psm first\n"; -+ -+ if (*f_pos > 0) { -+ retval = 0; -+ } else { -+ /*len = sprintf(page, "%d\n", g_psm_enable); */ -+#if 1 -+ if (gCoexBuf1.availSize <= 0) { -+ DBGLOG(INIT, WARN, "no data available\n"); -+ retval = strlen(warn_msg) + 1; -+ if (count < retval) -+ retval = count; -+ i_ret = copy_to_user(buf, warn_msg, retval); -+ if (i_ret) { -+ DBGLOG(INIT, ERROR, "copy to buffer failed, ret:%d\n", retval); -+ retval = -EFAULT; -+ goto err_exit; -+ } -+ *f_pos += retval; -+ } else -+#endif -+ { -+ INT32 i = 0; -+ INT32 len = 0; -+ CHAR msg_info[128]; -+ INT32 max_num = 0; -+ /*we do not check page buffer, because there are only 100 bytes in g_coex_buf, no reason page -+ buffer is not enough, a bomb is placed here on unexpected condition */ -+ -+ DBGLOG(INIT, TRACE, "%d bytes available\n", gCoexBuf1.availSize); -+ max_num = ((sizeof(msg_info) > count ? sizeof(msg_info) : count) - 1) / 5; -+ -+ if (max_num > gCoexBuf1.availSize) -+ max_num = gCoexBuf1.availSize; -+ else -+ DBGLOG(INIT, TRACE, -+ "round to %d bytes due to local buffer size limitation\n", max_num); -+ -+ for (i = 0; i < max_num; i++) -+ len += sprintf(msg_info + len, "%d", gCoexBuf1.buffer[i]); -+ -+ len += sprintf(msg_info + len, "\n"); -+ retval = len; -+ -+ i_ret = copy_to_user(buf, msg_info, retval); -+ if (i_ret) { -+ DBGLOG(INIT, ERROR, "copy to buffer failed, ret:%d\n", retval); -+ retval = -EFAULT; -+ goto err_exit; -+ } -+ *f_pos += retval; -+ } -+ } -+ gCoexBuf1.availSize = 0; -+err_exit: -+ -+ return retval; -+} -+ -+#if 1 -+typedef INT32 (*WLAN_DEV_DBG_FUNC)(void); -+static INT32 wlan_get_thermo_power(void); -+static INT32 wlan_get_link_mode(void); -+ -+static const WLAN_DEV_DBG_FUNC wlan_dev_dbg_func[] = { -+ [0] = wlan_get_thermo_power, -+ [1] = wlan_get_link_mode, -+ -+}; -+ -+INT32 wlan_get_thermo_power(void) -+{ -+ P_ADAPTER_T prAdapter; -+ -+ prAdapter = g_prGlueInfo_proc->prAdapter; -+ -+ if (prAdapter->u4AirDelayTotal > 100) -+ gCoexBuf1.buffer[0] = 100; -+ else -+ gCoexBuf1.buffer[0] = prAdapter->u4AirDelayTotal; -+ gCoexBuf1.availSize = 1; -+ DBGLOG(RLM, TRACE, "PROC %s thrmo_power(%d)\n", __func__, gCoexBuf1.buffer[0]); -+ -+ return 0; -+} -+ -+INT32 wlan_get_link_mode(void) -+{ -+ UINT_8 ucLinkMode = 0; -+ P_ADAPTER_T prAdapter; -+ BOOLEAN fgIsAPmode; -+ -+ prAdapter = g_prGlueInfo_proc->prAdapter; -+ fgIsAPmode = p2pFuncIsAPMode(prAdapter->rWifiVar.prP2pFsmInfo); -+ -+ DBGLOG(RLM, TRACE, "PROC %s AIS(%d)P2P(%d)AP(%d)\n", -+ __func__, -+ prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX].eConnectionState, -+ prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX].eConnectionState, fgIsAPmode); -+ -+#if 1 -+ -+ if (prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX].eConnectionState == PARAM_MEDIA_STATE_CONNECTED) -+ ucLinkMode |= BIT(0); -+ if (prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX].eConnectionState == PARAM_MEDIA_STATE_CONNECTED) -+ ucLinkMode |= BIT(1); -+ if (fgIsAPmode) -+ ucLinkMode |= BIT(2); -+ -+#endif -+ gCoexBuf1.buffer[0] = ucLinkMode; -+ gCoexBuf1.availSize = 1; -+ -+ return 0; -+} -+ -+static ssize_t procfile_write(struct file *filp, const char __user *buffer, size_t count, loff_t *f_pos) -+{ -+ char buf[256]; -+ char *pBuf; -+ ULONG len = count; -+ INT32 x = 0, y = 0, z = 0; -+ char *pToken = NULL; -+ char *pDelimiter = " \t"; -+ INT32 i4Ret = 0; -+ -+ if (copy_from_user(gCoexBuf1.buffer, buffer, count)) -+ return -EFAULT; -+ /* gCoexBuf1.availSize = count; */ -+ -+ /* return gCoexBuf1.availSize; */ -+#if 1 -+ DBGLOG(INIT, TRACE, "write parameter len = %d\n\r", (INT32) len); -+ if (len >= sizeof(buf)) { -+ DBGLOG(INIT, ERROR, "input handling fail!\n"); -+ len = sizeof(buf) - 1; -+ return -1; -+ } -+ -+ if (copy_from_user(buf, buffer, len)) -+ return -EFAULT; -+ buf[len] = '\0'; -+ DBGLOG(INIT, TRACE, "write parameter data = %s\n\r", buf); -+ -+ pBuf = buf; -+ pToken = strsep(&pBuf, pDelimiter); -+ -+ if (pToken) /* x = NULL != pToken ? simple_strtol(pToken, NULL, 16) : 0; */ -+ i4Ret = kalkStrtos32(pToken, 16, &x); -+ if (!i4Ret) -+ DBGLOG(INIT, TRACE, "x = 0x%x\n", x); -+ -+#if 1 -+ pToken = strsep(&pBuf, "\t\n "); -+ if (pToken != NULL) { -+ i4Ret = kalkStrtos32(pToken, 16, &y); /* y = simple_strtol(pToken, NULL, 16); */ -+ if (!i4Ret) -+ DBGLOG(INIT, TRACE, "y = 0x%08x\n\r", y); -+ } else { -+ y = 3000; -+ /*efuse, register read write default value */ -+ if (0x11 == x || 0x12 == x || 0x13 == x) -+ y = 0x80000000; -+ } -+ -+ pToken = strsep(&pBuf, "\t\n "); -+ if (pToken != NULL) { -+ i4Ret = kalkStrtos32(pToken, 16, &z); /* z = simple_strtol(pToken, NULL, 16); */ -+ if (!i4Ret) -+ DBGLOG(INIT, TRACE, "z = 0x%08x\n\r", z); -+ } else { -+ z = 10; -+ /*efuse, register read write default value */ -+ if (0x11 == x || 0x12 == x || 0x13 == x) -+ z = 0xffffffff; -+ } -+ -+ DBGLOG(INIT, TRACE, " x(0x%08x), y(0x%08x), z(0x%08x)\n\r", x, y, z); -+#endif -+ -+ if (((sizeof(wlan_dev_dbg_func) / sizeof(wlan_dev_dbg_func[0])) > x) && NULL != wlan_dev_dbg_func[x]) -+ (*wlan_dev_dbg_func[x]) (); -+ else -+ DBGLOG(INIT, ERROR, "no handler defined for command id(0x%08x)\n\r", x); -+#endif -+ -+ /* len = gCoexBuf1.availSize; */ -+ return len; -+} -+#endif -+ static const struct file_operations proc_fops = { -+ .owner = THIS_MODULE, -+ .read = procfile_read, -+ .write = procfile_write, -+ }; -+#endif -+ -+INT_32 procInitFs(VOID) -+{ -+ struct proc_dir_entry *prEntry; -+ -+ if (init_net.proc_net == (struct proc_dir_entry *)NULL) { -+ kalPrint("init proc fs fail: proc_net == NULL\n"); -+ return -ENOENT; -+ } -+ -+ /* -+ * Directory: Root (/proc/net/wlan0) -+ */ -+ -+ gprProcRoot = proc_mkdir(PROC_ROOT_NAME, init_net.proc_net); -+ if (!gprProcRoot) { -+ kalPrint("gprProcRoot == NULL\n"); -+ return -ENOENT; -+ } -+ proc_set_user(gprProcRoot, KUIDT_INIT(PROC_UID_SHELL), KGIDT_INIT(PROC_GID_WIFI)); -+ -+ prEntry = proc_create(PROC_DBG_LEVEL_NAME, 0664, gprProcRoot, &dbglevel_ops); -+ if (prEntry == NULL) { -+ kalPrint("Unable to create /proc entry dbgLevel\n\r"); -+ return -1; -+ } -+ proc_set_user(prEntry, KUIDT_INIT(PROC_UID_SHELL), KGIDT_INIT(PROC_GID_WIFI)); -+ -+ prEntry = proc_create(PROC_NEED_TX_DONE, 0664, gprProcRoot, &proc_txdone_ops); -+ if (prEntry == NULL) { -+ kalPrint("Unable to create /proc entry dbgLevel\n\r"); -+ return -1; -+ } -+ proc_set_user(prEntry, KUIDT_INIT(PROC_UID_SHELL), KGIDT_INIT(PROC_GID_WIFI)); -+ -+ prEntry = proc_create(PROC_AUTO_PER_CFG, 0664, gprProcRoot, &auto_per_ops); -+ if (prEntry == NULL) { -+ kalPrint("Unable to create /proc entry autoPerCfg\n\r"); -+ return -1; -+ } -+ proc_set_user(prEntry, KUIDT_INIT(PROC_UID_SHELL), KGIDT_INIT(PROC_GID_WIFI)); -+ -+ return 0; -+} /* end of procInitProcfs() */ -+ -+INT_32 procUninitProcFs(VOID) -+{ -+ remove_proc_entry(PROC_DBG_LEVEL_NAME, gprProcRoot); -+ remove_proc_subtree(PROC_ROOT_NAME, init_net.proc_net); -+ remove_proc_entry(PROC_AUTO_PER_CFG, gprProcRoot); -+ return 0; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function clean up a PROC fs created by procInitProcfs(). -+* -+* \param[in] prDev Pointer to the struct net_device. -+* \param[in] pucDevName Pointer to the name of net_device. -+* -+* \return N/A -+*/ -+/*----------------------------------------------------------------------------*/ -+INT_32 procRemoveProcfs(VOID) -+{ -+ /* remove root directory (proc/net/wlan0) */ -+ /* remove_proc_entry(pucDevName, init_net.proc_net); */ -+ remove_proc_entry(PROC_WLAN_THERMO, gprProcRoot); -+ remove_proc_entry(PROC_CMD_DEBUG_NAME, gprProcRoot); -+#if CFG_SUPPORT_THERMO_THROTTLING -+ g_prGlueInfo_proc = NULL; -+#endif -+ return 0; -+} /* end of procRemoveProcfs() */ -+ -+INT_32 procCreateFsEntry(P_GLUE_INFO_T prGlueInfo) -+{ -+ struct proc_dir_entry *prEntry; -+ -+ DBGLOG(INIT, TRACE, "[%s]\n", __func__); -+ -+#if CFG_SUPPORT_THERMO_THROTTLING -+ g_prGlueInfo_proc = prGlueInfo; -+#endif -+ -+ prGlueInfo->pProcRoot = gprProcRoot; -+ -+ prEntry = proc_create(PROC_WLAN_THERMO, 0664, gprProcRoot, &proc_fops); -+ if (prEntry == NULL) { -+ DBGLOG(INIT, ERROR, "Unable to create /proc entry\n\r"); -+ return -1; -+ } -+ -+ prEntry = proc_create(PROC_CMD_DEBUG_NAME, 0444, gprProcRoot, &proc_CmdDebug_ops); -+ if (prEntry == NULL) { -+ kalPrint("Unable to create /proc entry dbgLevel\n\r"); -+ return -1; -+ } -+ proc_set_user(prEntry, KUIDT_INIT(PROC_UID_SHELL), KGIDT_INIT(PROC_GID_WIFI)); -+ return 0; -+} -+ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_rst.c b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_rst.c -new file mode 100644 -index 000000000000..f97db8a69fd2 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_rst.c -@@ -0,0 +1,228 @@ -+/* -+** Id: @(#) gl_rst.c@@ -+*/ -+ -+/*! \file gl_rst.c -+ \brief Main routines for supporintg MT6620 whole-chip reset mechanism -+ -+ This file contains the support routines of Linux driver for MediaTek Inc. 802.11 -+ Wireless LAN Adapters. -+*/ -+ -+/* -+** Log: gl_rst.c -+ * -+ * 11 10 2011 cp.wu -+ * [WCXRP00001098] [MT6620 Wi-Fi][Driver] Replace printk by DBG LOG macros in linux porting layer -+ * 1. eliminaite direct calls to printk in porting layer. -+ * 2. replaced by DBGLOG, which would be XLOG on ALPS platforms. -+ * -+ * 04 22 2011 cp.wu -+ * [WCXRP00000598] [MT6620 Wi-Fi][Driver] Implementation of interface for communicating with user space process for -+ * RESET_START and RESET_END events -+ * skip power-off handshaking when RESET indication is received. -+ * -+ * 04 14 2011 cp.wu -+ * [WCXRP00000598] [MT6620 Wi-Fi][Driver] Implementation of interface for communicating with user space process for -+ * RESET_START and RESET_END events -+ * 1. add code to put whole-chip resetting trigger when abnormal firmware assertion is detected -+ * 2. add dummy function for both Win32 and Linux part. -+ * -+ * 03 30 2011 cp.wu -+ * [WCXRP00000598] [MT6620 Wi-Fi][Driver] Implementation of interface for communicating with user space process for -+ * RESET_START and RESET_END events -+ * use netlink unicast instead of broadcast -+ * -+** -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include -+#include -+ -+#include "precomp.h" -+#include "gl_rst.h" -+ -+#if CFG_CHIP_RESET_SUPPORT -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+BOOLEAN fgIsResetting = FALSE; -+UINT_32 g_IsNeedDoChipReset = 0; -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+static RESET_STRUCT_T wifi_rst; -+ -+static void mtk_wifi_reset(struct work_struct *work); -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+static void *glResetCallback(ENUM_WMTDRV_TYPE_T eSrcType, -+ ENUM_WMTDRV_TYPE_T eDstType, -+ ENUM_WMTMSG_TYPE_T eMsgType, void *prMsgBody, unsigned int u4MsgLength); -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * @brief This routine is responsible for -+ * 1. register wifi reset callback -+ * 2. initialize wifi reset work -+ * -+ * @param none -+ * -+ * @retval none -+ */ -+/*----------------------------------------------------------------------------*/ -+VOID glResetInit(VOID) -+{ -+#if (MTK_WCN_SINGLE_MODULE == 0) -+ /* 1. Register reset callback */ -+ mtk_wcn_wmt_msgcb_reg(WMTDRV_TYPE_WIFI, (PF_WMT_CB) glResetCallback); -+#endif /* MTK_WCN_SINGLE_MODULE */ -+ -+ /* 2. Initialize reset work */ -+ INIT_WORK(&(wifi_rst.rst_work), mtk_wifi_reset); -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * @brief This routine is responsible for -+ * 1. deregister wifi reset callback -+ * -+ * @param none -+ * -+ * @retval none -+ */ -+/*----------------------------------------------------------------------------*/ -+VOID glResetUninit(VOID) -+{ -+#if (MTK_WCN_SINGLE_MODULE == 0) -+ /* 1. Deregister reset callback */ -+ mtk_wcn_wmt_msgcb_unreg(WMTDRV_TYPE_WIFI); -+#endif /* MTK_WCN_SINGLE_MODULE */ -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * @brief This routine is invoked when there is reset messages indicated -+ * -+ * @param eSrcType -+ * eDstType -+ * eMsgType -+ * prMsgBody -+ * u4MsgLength -+ * -+ * @retval -+ */ -+/*----------------------------------------------------------------------------*/ -+static void *glResetCallback(ENUM_WMTDRV_TYPE_T eSrcType, -+ ENUM_WMTDRV_TYPE_T eDstType, -+ ENUM_WMTMSG_TYPE_T eMsgType, void *prMsgBody, unsigned int u4MsgLength) -+{ -+ switch (eMsgType) { -+ case WMTMSG_TYPE_RESET: -+ if (u4MsgLength == sizeof(ENUM_WMTRSTMSG_TYPE_T)) { -+ P_ENUM_WMTRSTMSG_TYPE_T prRstMsg = (P_ENUM_WMTRSTMSG_TYPE_T) prMsgBody; -+ -+ switch (*prRstMsg) { -+ case WMTRSTMSG_RESET_START: -+ DBGLOG(INIT, WARN, "Whole chip reset start!\n"); -+ fgIsResetting = TRUE; -+ wifi_reset_start(); -+ break; -+ -+ case WMTRSTMSG_RESET_END: -+ DBGLOG(INIT, WARN, "Whole chip reset end!\n"); -+ fgIsResetting = FALSE; -+ wifi_rst.rst_data = RESET_SUCCESS; -+ schedule_work(&(wifi_rst.rst_work)); -+ break; -+ -+ case WMTRSTMSG_RESET_END_FAIL: -+ DBGLOG(INIT, WARN, "Whole chip reset fail!\n"); -+ fgIsResetting = FALSE; -+ wifi_rst.rst_data = RESET_FAIL; -+ schedule_work(&(wifi_rst.rst_work)); -+ break; -+ -+ default: -+ break; -+ } -+ } -+ break; -+ -+ default: -+ break; -+ } -+ -+ return NULL; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * @brief This routine is called for wifi reset -+ * -+ * @param skb -+ * info -+ * -+ * @retval 0 -+ * nonzero -+ */ -+/*----------------------------------------------------------------------------*/ -+static void mtk_wifi_reset(struct work_struct *work) -+{ -+ RESET_STRUCT_T *rst = container_of(work, RESET_STRUCT_T, rst_work); -+ -+ wifi_reset_end(rst->rst_data); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * @brief This routine is called for generating reset request to WMT -+ * -+ * @param None -+ * -+ * @retval None -+ */ -+/*----------------------------------------------------------------------------*/ -+VOID glSendResetRequest(VOID) -+{ -+ /* WMT thread would trigger whole chip reset itself */ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+ * @brief This routine is called for checking if connectivity chip is resetting -+ * -+ * @param None -+ * -+ * @retval TRUE -+ * FALSE -+ */ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN kalIsResetting(VOID) -+{ -+ return fgIsResetting; -+} -+ -+#endif /* CFG_CHIP_RESET_SUPPORT */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_vendor.c b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_vendor.c -new file mode 100644 -index 000000000000..862d011a43df ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_vendor.c -@@ -0,0 +1,1220 @@ -+/* -+** Id: @(#) gl_cfg80211.c@@ -+*/ -+ -+/*! \file gl_cfg80211.c -+ \brief Main routines for supporintg MT6620 cfg80211 control interface -+ -+ This file contains the support routines of Linux driver for MediaTek Inc. 802.11 -+ Wireless LAN Adapters. -+*/ -+ -+/* -+** Log: gl_cfg80211.c -+** -+** 09 05 2013 cp.wu -+** correct length to pass to wlanoidSetBssid() -+** -+** 09 04 2013 cp.wu -+** fix typo -+** -+** 09 03 2013 cp.wu -+** add path for reassociation -+** -+** 11 23 2012 yuche.tsai -+** [ALPS00398671] [Acer-Tablet] Remove Wi-Fi Direct completely -+** Fix bug of WiFi may reboot under user load, when WiFi Direct is removed.. -+** -+** 09 12 2012 wcpadmin -+** [ALPS00276400] Remove MTK copyright and legal header on GPL/LGPL related packages -+** . -+** -+** 08 30 2012 chinglan.wang -+** [ALPS00349664] [6577JB][WIFI] Phone can not connect to AP secured with AES via WPS in 802.11n Only -+** . -+ * -+** -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include -+#include -+#include -+ -+#include "gl_os.h" -+#include "wlan_lib.h" -+#include "gl_wext.h" -+#include "precomp.h" -+#include "gl_cfg80211.h" -+#include "gl_vendor.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+static struct nla_policy nla_parse_policy[GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_FLUSH + 1] = { -+ [GSCAN_ATTRIBUTE_NUM_BUCKETS] = {.type = NLA_U32}, -+ [GSCAN_ATTRIBUTE_BASE_PERIOD] = {.type = NLA_U32}, -+ [GSCAN_ATTRIBUTE_BUCKETS_BAND] = {.type = NLA_U32}, -+ [GSCAN_ATTRIBUTE_BUCKET_ID] = {.type = NLA_U32}, -+ [GSCAN_ATTRIBUTE_BUCKET_PERIOD] = {.type = NLA_U32}, -+ [GSCAN_ATTRIBUTE_BUCKET_NUM_CHANNELS] = {.type = NLA_U32}, -+ [GSCAN_ATTRIBUTE_BUCKET_CHANNELS] = {.type = NLA_U32}, -+ [GSCAN_ATTRIBUTE_NUM_AP_PER_SCAN] = {.type = NLA_U32}, -+ [GSCAN_ATTRIBUTE_REPORT_THRESHOLD] = {.type = NLA_U32}, -+ [GSCAN_ATTRIBUTE_NUM_SCANS_TO_CACHE] = {.type = NLA_U32}, -+ [GSCAN_ATTRIBUTE_REPORT_EVENTS] = {.type = NLA_U32}, -+ [GSCAN_ATTRIBUTE_BSSID] = {.type = NLA_UNSPEC}, -+ [GSCAN_ATTRIBUTE_RSSI_LOW] = {.type = NLA_U32}, -+ [GSCAN_ATTRIBUTE_RSSI_HIGH] = {.type = NLA_U32}, -+ [GSCAN_ATTRIBUTE_RSSI_SAMPLE_SIZE] = {.type = NLA_U16}, -+ [GSCAN_ATTRIBUTE_LOST_AP_SAMPLE_SIZE] = {.type = NLA_U32}, -+ [GSCAN_ATTRIBUTE_MIN_BREACHING] = {.type = NLA_U16}, -+ [GSCAN_ATTRIBUTE_NUM_AP] = {.type = NLA_U16}, -+ [GSCAN_ATTRIBUTE_HOTLIST_FLUSH] = {.type = NLA_U8}, -+ [GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_FLUSH] = {.type = NLA_U8}, -+}; -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+int mtk_cfg80211_vendor_get_channel_list(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int data_len) -+{ -+ P_GLUE_INFO_T prGlueInfo; -+ struct nlattr *attr; -+ UINT_32 band = 0; -+ UINT_8 ucNumOfChannel, i, j; -+ RF_CHANNEL_INFO_T aucChannelList[64]; -+ UINT_32 num_channels; -+ wifi_channel channels[64]; -+ struct sk_buff *skb; -+ -+ ASSERT(wiphy && wdev); -+ if ((data == NULL) || !data_len) -+ return -EINVAL; -+ -+ DBGLOG(REQ, INFO, "vendor command: data_len=%d\n", data_len); -+ -+ attr = (struct nlattr *)data; -+ if (attr->nla_type == WIFI_ATTRIBUTE_BAND) -+ band = nla_get_u32(attr); -+ -+ DBGLOG(REQ, INFO, "Get channel list for band: %d\n", band); -+ -+ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); -+ if (!prGlueInfo) -+ return -EFAULT; -+ -+ if (band == 0) { /* 2.4G band */ -+ rlmDomainGetChnlList(prGlueInfo->prAdapter, BAND_2G4, TRUE, -+ 64, &ucNumOfChannel, aucChannelList); -+ } else { /* 5G band */ -+ rlmDomainGetChnlList(prGlueInfo->prAdapter, BAND_5G, TRUE, -+ 64, &ucNumOfChannel, aucChannelList); -+ } -+ -+ kalMemZero(channels, sizeof(channels)); -+ for (i = 0, j = 0; i < ucNumOfChannel; i++) { -+ /* We need to report frequency list to HAL */ -+ channels[j] = nicChannelNum2Freq(aucChannelList[i].ucChannelNum) / 1000; -+ if (channels[j] == 0) -+ continue; -+ else if ((prGlueInfo->prAdapter->rWifiVar.rConnSettings.u2CountryCode == COUNTRY_CODE_TW) && -+ (channels[j] >= 5180 && channels[j] <= 5260)) { -+ /* Taiwan NCC has resolution to follow FCC spec to support 5G Band 1/2/3/4 -+ * (CH36~CH48, CH52~CH64, CH100~CH140, CH149~CH165) -+ * Filter CH36~CH52 for compatible with some old devices. -+ */ -+ continue; -+ } else { -+ DBGLOG(REQ, INFO, "channels[%d] = %d\n", j, channels[j]); -+ j++; -+ } -+ } -+ num_channels = j; -+ -+ skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(channels)); -+ if (!skb) { -+ DBGLOG(REQ, ERROR, "Allocate skb failed\n"); -+ return -ENOMEM; -+ } -+ -+ if (unlikely(nla_put_u32(skb, WIFI_ATTRIBUTE_NUM_CHANNELS, num_channels) < 0)) -+ goto nla_put_failure; -+ -+ if (unlikely(nla_put(skb, WIFI_ATTRIBUTE_CHANNEL_LIST, -+ (sizeof(wifi_channel) * num_channels), channels) < 0)) -+ goto nla_put_failure; -+ -+ return cfg80211_vendor_cmd_reply(skb); -+ -+nla_put_failure: -+ kfree_skb(skb); -+ return -EFAULT; -+} -+ -+int mtk_cfg80211_vendor_set_country_code(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int data_len) -+{ -+ P_GLUE_INFO_T prGlueInfo; -+ WLAN_STATUS rStatus; -+ UINT_32 u4BufLen; -+ struct nlattr *attr; -+ UINT_8 country[2] = {0, 0}; -+ -+ ASSERT(wiphy && wdev); -+ if ((data == NULL) || (data_len == 0)) -+ return -EINVAL; -+ -+ DBGLOG(REQ, INFO, "vendor command: data_len=%d\n", data_len); -+ -+ attr = (struct nlattr *)data; -+ if (attr->nla_type == WIFI_ATTRIBUTE_COUNTRY_CODE) { -+ country[0] = *((PUINT_8)nla_data(attr)); -+ country[1] = *((PUINT_8)nla_data(attr) + 1); -+ } -+ -+ DBGLOG(REQ, INFO, "Set country code: %c%c\n", country[0], country[1]); -+ -+ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); -+ if (!prGlueInfo) -+ return -EFAULT; -+ -+ rStatus = kalIoctl(prGlueInfo, wlanoidSetCountryCode, country, 2, FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ DBGLOG(REQ, ERROR, "Set country code error: %x\n", rStatus); -+ return -EFAULT; -+ } -+ -+ return 0; -+} -+ -+int mtk_cfg80211_vendor_get_gscan_capabilities(struct wiphy *wiphy, -+ struct wireless_dev *wdev, const void *data, int data_len) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ INT_32 i4Status = -EINVAL; -+ PARAM_WIFI_GSCAN_CAPABILITIES_STRUCT_T rGscanCapabilities; -+ struct sk_buff *skb; -+ /* UINT_32 u4BufLen; */ -+ -+ DBGLOG(REQ, TRACE, "%s for vendor command \r\n", __func__); -+ -+ ASSERT(wiphy); -+ ASSERT(wdev); -+ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); -+ -+ skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(rGscanCapabilities)); -+ if (!skb) { -+ DBGLOG(REQ, ERROR, "%s allocate skb failed:%x\n", __func__, i4Status); -+ return -ENOMEM; -+ } -+ -+ kalMemZero(&rGscanCapabilities, sizeof(rGscanCapabilities)); -+ -+ /*rStatus = kalIoctl(prGlueInfo, -+ wlanoidQueryStatistics, -+ &rGscanCapabilities, -+ sizeof(rGscanCapabilities), -+ TRUE, -+ TRUE, -+ TRUE, -+ FALSE, -+ &u4BufLen); */ -+ rGscanCapabilities.max_scan_cache_size = PSCAN_MAX_SCAN_CACHE_SIZE; -+ rGscanCapabilities.max_scan_buckets = GSCAN_MAX_BUCKETS; -+ rGscanCapabilities.max_ap_cache_per_scan = PSCAN_MAX_AP_CACHE_PER_SCAN; -+ rGscanCapabilities.max_rssi_sample_size = 10; -+ rGscanCapabilities.max_scan_reporting_threshold = GSCAN_MAX_REPORT_THRESHOLD; -+ rGscanCapabilities.max_hotlist_aps = MAX_HOTLIST_APS; -+ rGscanCapabilities.max_significant_wifi_change_aps = MAX_SIGNIFICANT_CHANGE_APS; -+ rGscanCapabilities.max_bssid_history_entries = PSCAN_MAX_AP_CACHE_PER_SCAN * PSCAN_MAX_SCAN_CACHE_SIZE; -+ -+ /* NLA_PUT_U8(skb, NL80211_TESTMODE_STA_STATISTICS_INVALID, 0); */ -+ /* NLA_PUT_U32(skb, NL80211_ATTR_VENDOR_ID, GOOGLE_OUI); */ -+ /* NLA_PUT_U32(skb, NL80211_ATTR_VENDOR_SUBCMD, GSCAN_SUBCMD_GET_CAPABILITIES); */ -+ /*NLA_PUT(skb, GSCAN_ATTRIBUTE_CAPABILITIES, sizeof(rGscanCapabilities), &rGscanCapabilities);*/ -+ if (unlikely(nla_put(skb, GSCAN_ATTRIBUTE_CAPABILITIES, -+ sizeof(rGscanCapabilities), &rGscanCapabilities) < 0)) -+ goto nla_put_failure; -+ -+ i4Status = cfg80211_vendor_cmd_reply(skb); -+ return i4Status; -+ -+nla_put_failure: -+ kfree_skb(skb); -+ return i4Status; -+} -+ -+int mtk_cfg80211_vendor_set_config(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int data_len) -+{ -+ WLAN_STATUS rStatus; -+ UINT_32 u4BufLen; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ /* CMD_GSCN_REQ_T rCmdGscnParam; */ -+ -+ /* INT_32 i4Status = -EINVAL; */ -+ P_PARAM_WIFI_GSCAN_CMD_PARAMS prWifiScanCmd = NULL; -+ struct nlattr *attr[GSCAN_ATTRIBUTE_REPORT_EVENTS + 1]; -+ struct nlattr *pbucket, *pchannel; -+ UINT_32 len_basic, len_bucket, len_channel; -+ int i, j, k; -+ -+ ASSERT(wiphy); -+ ASSERT(wdev); -+ if ((data == NULL) || !data_len) -+ goto nla_put_failure; -+ -+ prWifiScanCmd = (P_PARAM_WIFI_GSCAN_CMD_PARAMS) kalMemAlloc(sizeof(PARAM_WIFI_GSCAN_CMD_PARAMS), VIR_MEM_TYPE); -+ if (!prWifiScanCmd) { -+ DBGLOG(REQ, ERROR, "Can not alloc memory for PARAM_WIFI_GSCAN_CMD_PARAMS\n"); -+ return -ENOMEM; -+ } -+ -+ DBGLOG(REQ, INFO, "%s for vendor command: data_len=%d \r\n", __func__, data_len); -+ kalMemZero(prWifiScanCmd, sizeof(PARAM_WIFI_GSCAN_CMD_PARAMS)); -+ kalMemZero(attr, sizeof(struct nlattr *) * (GSCAN_ATTRIBUTE_REPORT_EVENTS + 1)); -+ -+ nla_parse_nested(attr, GSCAN_ATTRIBUTE_REPORT_EVENTS, (struct nlattr *)(data - NLA_HDRLEN), nla_parse_policy,NULL); -+ len_basic = 0; -+ for (k = GSCAN_ATTRIBUTE_NUM_BUCKETS; k <= GSCAN_ATTRIBUTE_REPORT_EVENTS; k++) { -+ if (attr[k]) { -+ switch (k) { -+ case GSCAN_ATTRIBUTE_BASE_PERIOD: -+ prWifiScanCmd->base_period = nla_get_u32(attr[k]); -+ len_basic += NLA_ALIGN(attr[k]->nla_len); -+ break; -+ case GSCAN_ATTRIBUTE_NUM_BUCKETS: -+ prWifiScanCmd->num_buckets = nla_get_u32(attr[k]); -+ len_basic += NLA_ALIGN(attr[k]->nla_len); -+ DBGLOG(REQ, TRACE, "attr=0x%x, num_buckets=%d nla_len=%d, \r\n", -+ *(UINT_32 *) attr[k], prWifiScanCmd->num_buckets, attr[k]->nla_len); -+ break; -+ } -+ } -+ } -+ pbucket = (struct nlattr *)((UINT_8 *) data + len_basic); -+ DBGLOG(REQ, TRACE, "+++basic attribute size=%d pbucket=%p\r\n", len_basic, pbucket); -+ -+ for (i = 0; i < prWifiScanCmd->num_buckets; i++) { -+ if (nla_parse_nested(attr, GSCAN_ATTRIBUTE_REPORT_EVENTS, (struct nlattr *)pbucket, -+ nla_parse_policy,NULL) < 0) -+ goto nla_put_failure; -+ len_bucket = 0; -+ for (k = GSCAN_ATTRIBUTE_NUM_BUCKETS; k <= GSCAN_ATTRIBUTE_REPORT_EVENTS; k++) { -+ if (attr[k]) { -+ switch (k) { -+ case GSCAN_ATTRIBUTE_BUCKETS_BAND: -+ prWifiScanCmd->buckets[i].band = nla_get_u32(attr[k]); -+ len_bucket += NLA_ALIGN(attr[k]->nla_len); -+ break; -+ case GSCAN_ATTRIBUTE_BUCKET_ID: -+ prWifiScanCmd->buckets[i].bucket = nla_get_u32(attr[k]); -+ len_bucket += NLA_ALIGN(attr[k]->nla_len); -+ break; -+ case GSCAN_ATTRIBUTE_BUCKET_PERIOD: -+ prWifiScanCmd->buckets[i].period = nla_get_u32(attr[k]); -+ len_bucket += NLA_ALIGN(attr[k]->nla_len); -+ break; -+ case GSCAN_ATTRIBUTE_REPORT_EVENTS: -+ prWifiScanCmd->buckets[i].report_events = nla_get_u32(attr[k]); -+ len_bucket += NLA_ALIGN(attr[k]->nla_len); -+ break; -+ case GSCAN_ATTRIBUTE_BUCKET_NUM_CHANNELS: -+ prWifiScanCmd->buckets[i].num_channels = nla_get_u32(attr[k]); -+ len_bucket += NLA_ALIGN(attr[k]->nla_len); -+ DBGLOG(REQ, TRACE, "bucket%d: attr=0x%x, num_channels=%d nla_len = %d, \r\n", -+ i, *(UINT_32 *) attr[k], nla_get_u32(attr[k]), attr[k]->nla_len); -+ break; -+ } -+ } -+ } -+ pbucket = (struct nlattr *)((UINT_8 *) pbucket + NLA_HDRLEN); -+ /* request.attr_start(i) as nested attribute */ -+ DBGLOG(REQ, TRACE, "+++pure bucket size=%d pbucket=%p \r\n", len_bucket, pbucket); -+ pbucket = (struct nlattr *)((UINT_8 *) pbucket + len_bucket); -+ /* pure bucket payload, not include channels */ -+ -+ /*don't need to use nla_parse_nested to parse channels */ -+ /* the header of channel in bucket i */ -+ pchannel = (struct nlattr *)((UINT_8 *) pbucket + NLA_HDRLEN); -+ for (j = 0; j < prWifiScanCmd->buckets[i].num_channels; j++) { -+ prWifiScanCmd->buckets[i].channels[j].channel = nla_get_u32(pchannel); -+ len_channel = NLA_ALIGN(pchannel->nla_len); -+ DBGLOG(REQ, TRACE, -+ "attr=0x%x, channel=%d, \r\n", *(UINT_32 *) pchannel, nla_get_u32(pchannel)); -+ -+ pchannel = (struct nlattr *)((UINT_8 *) pchannel + len_channel); -+ } -+ pbucket = pchannel; -+ } -+ -+ DBGLOG(REQ, TRACE, "base_period=%d, num_buckets=%d, bucket0: %d %d %d %d", -+ prWifiScanCmd->base_period, prWifiScanCmd->num_buckets, -+ prWifiScanCmd->buckets[0].bucket, prWifiScanCmd->buckets[0].period, -+ prWifiScanCmd->buckets[0].band, prWifiScanCmd->buckets[0].report_events); -+ -+ DBGLOG(REQ, TRACE, "num_channels=%d, channel0=%d, channel1=%d; num_channels=%d, channel0=%d, channel1=%d", -+ prWifiScanCmd->buckets[0].num_channels, -+ prWifiScanCmd->buckets[0].channels[0].channel, prWifiScanCmd->buckets[0].channels[1].channel, -+ prWifiScanCmd->buckets[1].num_channels, -+ prWifiScanCmd->buckets[1].channels[0].channel, prWifiScanCmd->buckets[1].channels[1].channel); -+ -+ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); -+ ASSERT(prGlueInfo); -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetGSCNAParam, -+ prWifiScanCmd, sizeof(PARAM_WIFI_GSCAN_CMD_PARAMS), FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ kalMemFree(prWifiScanCmd, VIR_MEM_TYPE, sizeof(PARAM_WIFI_GSCAN_CMD_PARAMS)); -+ return 0; -+ -+nla_put_failure: -+ if (prWifiScanCmd != NULL) -+ kalMemFree(prWifiScanCmd, VIR_MEM_TYPE, sizeof(PARAM_WIFI_GSCAN_CMD_PARAMS)); -+ return -1; -+} -+ -+int mtk_cfg80211_vendor_set_scan_config(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int data_len) -+{ -+ WLAN_STATUS rStatus; -+ UINT_32 u4BufLen; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ -+ INT_32 i4Status = -EINVAL; -+ /*PARAM_WIFI_GSCAN_CMD_PARAMS rWifiScanCmd;*/ -+ P_PARAM_WIFI_GSCAN_CMD_PARAMS prWifiScanCmd = NULL; -+ struct nlattr *attr[GSCAN_ATTRIBUTE_NUM_SCANS_TO_CACHE + 1]; -+ /* UINT_32 num_scans = 0; */ /* another attribute */ -+ int k; -+ -+ ASSERT(wiphy); -+ ASSERT(wdev); -+ if ((data == NULL) || !data_len) -+ goto nla_put_failure; -+ DBGLOG(REQ, INFO, "%s for vendor command: data_len=%d \r\n", __func__, data_len); -+ /*kalMemZero(&rWifiScanCmd, sizeof(rWifiScanCmd));*/ -+ prWifiScanCmd = kalMemAlloc(sizeof(PARAM_WIFI_GSCAN_CMD_PARAMS), VIR_MEM_TYPE); -+ if (prWifiScanCmd == NULL) -+ goto nla_put_failure; -+ kalMemZero(prWifiScanCmd, sizeof(PARAM_WIFI_GSCAN_CMD_PARAMS)); -+ kalMemZero(attr, sizeof(struct nlattr *) * (GSCAN_ATTRIBUTE_NUM_SCANS_TO_CACHE + 1)); -+ -+ if (nla_parse_nested(attr, GSCAN_ATTRIBUTE_NUM_SCANS_TO_CACHE, -+ (struct nlattr *)(data - NLA_HDRLEN), nla_parse_policy,NULL) < 0) -+ goto nla_put_failure; -+ for (k = GSCAN_ATTRIBUTE_NUM_AP_PER_SCAN; k <= GSCAN_ATTRIBUTE_NUM_SCANS_TO_CACHE; k++) { -+ if (attr[k]) { -+ switch (k) { -+ case GSCAN_ATTRIBUTE_NUM_AP_PER_SCAN: -+ prWifiScanCmd->max_ap_per_scan = nla_get_u32(attr[k]); -+ break; -+ case GSCAN_ATTRIBUTE_REPORT_THRESHOLD: -+ prWifiScanCmd->report_threshold = nla_get_u32(attr[k]); -+ break; -+ case GSCAN_ATTRIBUTE_NUM_SCANS_TO_CACHE: -+ prWifiScanCmd->num_scans = nla_get_u32(attr[k]); -+ break; -+ } -+ } -+ } -+ DBGLOG(REQ, TRACE, "attr=0x%x, attr2=0x%x ", *(UINT_32 *) attr[GSCAN_ATTRIBUTE_NUM_AP_PER_SCAN], -+ *(UINT_32 *) attr[GSCAN_ATTRIBUTE_REPORT_THRESHOLD]); -+ -+ DBGLOG(REQ, TRACE, "max_ap_per_scan=%d, report_threshold=%d num_scans=%d \r\n", -+ prWifiScanCmd->max_ap_per_scan, prWifiScanCmd->report_threshold, prWifiScanCmd->num_scans); -+ -+ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); -+ ASSERT(prGlueInfo); -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetGSCNAConfig, -+ prWifiScanCmd, sizeof(PARAM_WIFI_GSCAN_CMD_PARAMS), FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ kalMemFree(prWifiScanCmd, VIR_MEM_TYPE, sizeof(PARAM_WIFI_GSCAN_CMD_PARAMS)); -+ return 0; -+ -+nla_put_failure: -+ if (prWifiScanCmd != NULL) -+ kalMemFree(prWifiScanCmd, VIR_MEM_TYPE, sizeof(PARAM_WIFI_GSCAN_CMD_PARAMS)); -+ return i4Status; -+} -+ -+int mtk_cfg80211_vendor_set_significant_change(struct wiphy *wiphy, struct wireless_dev *wdev, -+ const void *data, int data_len) -+{ -+ INT_32 i4Status = -EINVAL; -+ P_PARAM_WIFI_SIGNIFICANT_CHANGE prWifiChangeCmd = NULL; -+ UINT_8 flush = 0; -+ /* struct nlattr *attr[GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_FLUSH + 1]; */ -+ struct nlattr **attr = NULL; -+ struct nlattr *paplist; -+ int i, k; -+ UINT_32 len_basic, len_aplist; -+ -+ ASSERT(wiphy); -+ ASSERT(wdev); -+ if ((data == NULL) || !data_len) -+ goto nla_put_failure; -+ DBGLOG(REQ, INFO, "%s for vendor command: data_len=%d \r\n", __func__, data_len); -+ for (i = 0; i < 6; i++) -+ DBGLOG(REQ, LOUD, "0x%x 0x%x 0x%x 0x%x \r\n", -+ *((UINT_32 *) data + i * 4), *((UINT_32 *) data + i * 4 + 1), -+ *((UINT_32 *) data + i * 4 + 2), *((UINT_32 *) data + i * 4 + 3)); -+ prWifiChangeCmd = kalMemAlloc(sizeof(PARAM_WIFI_SIGNIFICANT_CHANGE), VIR_MEM_TYPE); -+ if (prWifiChangeCmd == NULL) -+ goto nla_put_failure; -+ kalMemZero(prWifiChangeCmd, sizeof(PARAM_WIFI_SIGNIFICANT_CHANGE)); -+ attr = kalMemAlloc(sizeof(struct nlattr *) * (GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_FLUSH + 1), VIR_MEM_TYPE); -+ if (attr == NULL) -+ goto nla_put_failure; -+ kalMemZero(attr, sizeof(struct nlattr *) * (GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_FLUSH + 1)); -+ -+ if (nla_parse_nested(attr, GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_FLUSH, -+ (struct nlattr *)(data - NLA_HDRLEN), nla_parse_policy,NULL) < 0) -+ goto nla_put_failure; -+ len_basic = 0; -+ for (k = GSCAN_ATTRIBUTE_RSSI_SAMPLE_SIZE; k <= GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_FLUSH; k++) { -+ if (attr[k]) { -+ switch (k) { -+ case GSCAN_ATTRIBUTE_RSSI_SAMPLE_SIZE: -+ prWifiChangeCmd->rssi_sample_size = nla_get_u16(attr[k]); -+ len_basic += NLA_ALIGN(attr[k]->nla_len); -+ break; -+ case GSCAN_ATTRIBUTE_LOST_AP_SAMPLE_SIZE: -+ prWifiChangeCmd->lost_ap_sample_size = nla_get_u16(attr[k]); -+ len_basic += NLA_ALIGN(attr[k]->nla_len); -+ break; -+ case GSCAN_ATTRIBUTE_MIN_BREACHING: -+ prWifiChangeCmd->min_breaching = nla_get_u16(attr[k]); -+ len_basic += NLA_ALIGN(attr[k]->nla_len); -+ break; -+ case GSCAN_ATTRIBUTE_NUM_AP: -+ prWifiChangeCmd->num_ap = nla_get_u16(attr[k]); -+ len_basic += NLA_ALIGN(attr[k]->nla_len); -+ DBGLOG(REQ, TRACE, "attr=0x%x, num_ap=%d nla_len=%d, \r\n", -+ *(UINT_32 *) attr[k], prWifiChangeCmd->num_ap, attr[k]->nla_len); -+ break; -+ case GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_FLUSH: -+ flush = nla_get_u8(attr[k]); -+ len_basic += NLA_ALIGN(attr[k]->nla_len); -+ break; -+ } -+ } -+ } -+ paplist = (struct nlattr *)((UINT_8 *) data + len_basic); -+ DBGLOG(REQ, TRACE, "+++basic attribute size=%d flush=%d\r\n", len_basic, flush); -+ -+ if (paplist->nla_type == GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_BSSIDS) -+ paplist = (struct nlattr *)((UINT_8 *) paplist + NLA_HDRLEN); -+ -+ for (i = 0; i < prWifiChangeCmd->num_ap; i++) { -+ if (nla_parse_nested(attr, GSCAN_ATTRIBUTE_RSSI_HIGH, (struct nlattr *)paplist, nla_parse_policy,NULL) < 0) -+ goto nla_put_failure; -+ paplist = (struct nlattr *)((UINT_8 *) paplist + NLA_HDRLEN); -+ /* request.attr_start(i) as nested attribute */ -+ len_aplist = 0; -+ for (k = GSCAN_ATTRIBUTE_BSSID; k <= GSCAN_ATTRIBUTE_RSSI_HIGH; k++) { -+ if (attr[k]) { -+ switch (k) { -+ case GSCAN_ATTRIBUTE_BSSID: -+ kalMemCopy(prWifiChangeCmd->ap[i].bssid, nla_data(attr[k]), sizeof(mac_addr)); -+ len_aplist += NLA_ALIGN(attr[k]->nla_len); -+ break; -+ case GSCAN_ATTRIBUTE_RSSI_LOW: -+ prWifiChangeCmd->ap[i].low = nla_get_u32(attr[k]); -+ len_aplist += NLA_ALIGN(attr[k]->nla_len); -+ break; -+ case GSCAN_ATTRIBUTE_RSSI_HIGH: -+ prWifiChangeCmd->ap[i].high = nla_get_u32(attr[k]); -+ len_aplist += NLA_ALIGN(attr[k]->nla_len); -+ break; -+ } -+ } -+ } -+ if (((i + 1) % 4 == 0) || (i == prWifiChangeCmd->num_ap - 1)) -+ DBGLOG(REQ, TRACE, "ap[%d], len_aplist=%d\n", i, len_aplist); -+ else -+ DBGLOG(REQ, TRACE, "ap[%d], len_aplist=%d \t", i, len_aplist); -+ paplist = (struct nlattr *)((UINT_8 *) paplist + len_aplist); -+ } -+ -+ DBGLOG(REQ, TRACE, -+ "flush=%d, rssi_sample_size=%d lost_ap_sample_size=%d min_breaching=%d", -+ flush, prWifiChangeCmd->rssi_sample_size, prWifiChangeCmd->lost_ap_sample_size, -+ prWifiChangeCmd->min_breaching); -+ DBGLOG(REQ, TRACE, -+ "ap[0].channel=%d low=%d high=%d, ap[1].channel=%d low=%d high=%d", -+ prWifiChangeCmd->ap[0].channel, prWifiChangeCmd->ap[0].low, prWifiChangeCmd->ap[0].high, -+ prWifiChangeCmd->ap[1].channel, prWifiChangeCmd->ap[1].low, prWifiChangeCmd->ap[1].high); -+ kalMemFree(prWifiChangeCmd, VIR_MEM_TYPE, sizeof(PARAM_WIFI_SIGNIFICANT_CHANGE)); -+ kalMemFree(attr, VIR_MEM_TYPE, sizeof(struct nlattr *) * (GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_FLUSH + 1)); -+ return 0; -+ -+nla_put_failure: -+ if (prWifiChangeCmd) -+ kalMemFree(prWifiChangeCmd, VIR_MEM_TYPE, sizeof(PARAM_WIFI_SIGNIFICANT_CHANGE)); -+ if (attr) -+ kalMemFree(attr, VIR_MEM_TYPE, -+ sizeof(struct nlattr *) * (GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_FLUSH + 1)); -+ return i4Status; -+} -+ -+int mtk_cfg80211_vendor_set_hotlist(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int data_len) -+{ -+ /*WLAN_STATUS rStatus;*/ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ CMD_SET_PSCAN_ADD_HOTLIST_BSSID rCmdPscnAddHotlist; -+ -+ INT_32 i4Status = -EINVAL; -+ P_PARAM_WIFI_BSSID_HOTLIST prWifiHotlistCmd = NULL; -+ UINT_8 flush = 0; -+ /* struct nlattr *attr[GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_FLUSH + 1]; */ -+ struct nlattr **attr = NULL; -+ struct nlattr *paplist; -+ int i, k; -+ UINT_32 len_basic, len_aplist; -+ -+ ASSERT(wiphy); -+ ASSERT(wdev); -+ if ((data == NULL) || !data_len) -+ goto nla_put_failure; -+ DBGLOG(REQ, INFO, "%s for vendor command: data_len=%d \r\n", __func__, data_len); -+ for (i = 0; i < 5; i++) -+ DBGLOG(REQ, LOUD, "0x%x 0x%x 0x%x 0x%x \r\n", -+ *((UINT_32 *) data + i * 4), *((UINT_32 *) data + i * 4 + 1), -+ *((UINT_32 *) data + i * 4 + 2), *((UINT_32 *) data + i * 4 + 3)); -+ prWifiHotlistCmd = kalMemAlloc(sizeof(PARAM_WIFI_BSSID_HOTLIST), VIR_MEM_TYPE); -+ if (prWifiHotlistCmd == NULL) -+ goto nla_put_failure; -+ kalMemZero(prWifiHotlistCmd, sizeof(PARAM_WIFI_BSSID_HOTLIST)); -+ attr = kalMemAlloc(sizeof(struct nlattr *) * (GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_FLUSH + 1), VIR_MEM_TYPE); -+ if (attr == NULL) -+ goto nla_put_failure; -+ kalMemZero(attr, sizeof(struct nlattr *) * (GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_FLUSH + 1)); -+ -+ if (nla_parse_nested(attr, GSCAN_ATTRIBUTE_NUM_AP, (struct nlattr *)(data - NLA_HDRLEN), nla_parse_policy,NULL) < 0) -+ goto nla_put_failure; -+ len_basic = 0; -+ for (k = GSCAN_ATTRIBUTE_HOTLIST_FLUSH; k <= GSCAN_ATTRIBUTE_NUM_AP; k++) { -+ if (attr[k]) { -+ switch (k) { -+ case GSCAN_ATTRIBUTE_LOST_AP_SAMPLE_SIZE: -+ prWifiHotlistCmd->lost_ap_sample_size = nla_get_u32(attr[k]); -+ len_basic += NLA_ALIGN(attr[k]->nla_len); -+ break; -+ case GSCAN_ATTRIBUTE_NUM_AP: -+ prWifiHotlistCmd->num_ap = nla_get_u16(attr[k]); -+ len_basic += NLA_ALIGN(attr[k]->nla_len); -+ DBGLOG(REQ, TRACE, "attr=0x%x, num_ap=%d nla_len=%d, \r\n", -+ *(UINT_32 *) attr[k], prWifiHotlistCmd->num_ap, attr[k]->nla_len); -+ break; -+ case GSCAN_ATTRIBUTE_HOTLIST_FLUSH: -+ flush = nla_get_u8(attr[k]); -+ len_basic += NLA_ALIGN(attr[k]->nla_len); -+ break; -+ } -+ } -+ } -+ paplist = (struct nlattr *)((UINT_8 *) data + len_basic); -+ DBGLOG(REQ, TRACE, "+++basic attribute size=%d flush=%d\r\n", len_basic, flush); -+ -+ if (paplist->nla_type == GSCAN_ATTRIBUTE_HOTLIST_BSSIDS) -+ paplist = (struct nlattr *)((UINT_8 *) paplist + NLA_HDRLEN); -+ -+ for (i = 0; i < prWifiHotlistCmd->num_ap; i++) { -+ if (nla_parse_nested(attr, GSCAN_ATTRIBUTE_RSSI_HIGH, (struct nlattr *)paplist, nla_parse_policy,NULL) < 0) -+ goto nla_put_failure; -+ paplist = (struct nlattr *)((UINT_8 *) paplist + NLA_HDRLEN); -+ /* request.attr_start(i) as nested attribute */ -+ len_aplist = 0; -+ for (k = GSCAN_ATTRIBUTE_BSSID; k <= GSCAN_ATTRIBUTE_RSSI_HIGH; k++) { -+ if (attr[k]) { -+ switch (k) { -+ case GSCAN_ATTRIBUTE_BSSID: -+ kalMemCopy(prWifiHotlistCmd->ap[i].bssid, nla_data(attr[k]), sizeof(mac_addr)); -+ len_aplist += NLA_ALIGN(attr[k]->nla_len); -+ break; -+ case GSCAN_ATTRIBUTE_RSSI_LOW: -+ prWifiHotlistCmd->ap[i].low = nla_get_u32(attr[k]); -+ len_aplist += NLA_ALIGN(attr[k]->nla_len); -+ break; -+ case GSCAN_ATTRIBUTE_RSSI_HIGH: -+ prWifiHotlistCmd->ap[i].high = nla_get_u32(attr[k]); -+ len_aplist += NLA_ALIGN(attr[k]->nla_len); -+ break; -+ } -+ } -+ } -+ if (((i + 1) % 4 == 0) || (i == prWifiHotlistCmd->num_ap - 1)) -+ DBGLOG(REQ, TRACE, "ap[%d], len_aplist=%d\n", i, len_aplist); -+ else -+ DBGLOG(REQ, TRACE, "ap[%d], len_aplist=%d \t", i, len_aplist); -+ paplist = (struct nlattr *)((UINT_8 *) paplist + len_aplist); -+ } -+ -+ DBGLOG(REQ, TRACE, -+ "flush=%d, lost_ap_sample_size=%d, Hotlist:ap[0].channel=%d low=%d high=%d, ap[1].channel=%d low=%d high=%d", -+ flush, prWifiHotlistCmd->lost_ap_sample_size, -+ prWifiHotlistCmd->ap[0].channel, prWifiHotlistCmd->ap[0].low, prWifiHotlistCmd->ap[0].high, -+ prWifiHotlistCmd->ap[1].channel, prWifiHotlistCmd->ap[1].low, prWifiHotlistCmd->ap[1].high); -+ -+ memcpy(&(rCmdPscnAddHotlist.aucMacAddr), &(prWifiHotlistCmd->ap[0].bssid), 6 * sizeof(UINT_8)); -+ rCmdPscnAddHotlist.ucFlags = (UINT_8) TRUE; -+ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); -+ ASSERT(prGlueInfo); -+ -+ kalMemFree(prWifiHotlistCmd, VIR_MEM_TYPE, sizeof(PARAM_WIFI_BSSID_HOTLIST)); -+ kalMemFree(attr, VIR_MEM_TYPE, sizeof(struct nlattr *) * (GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_FLUSH + 1)); -+ return 0; -+ -+nla_put_failure: -+ if (prWifiHotlistCmd) -+ kalMemFree(prWifiHotlistCmd, VIR_MEM_TYPE, sizeof(PARAM_WIFI_BSSID_HOTLIST)); -+ if (attr) -+ kalMemFree(attr, VIR_MEM_TYPE, -+ sizeof(struct nlattr *) * (GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_FLUSH + 1)); -+ return i4Status; -+} -+ -+int mtk_cfg80211_vendor_enable_scan(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int data_len) -+{ -+ WLAN_STATUS rStatus; -+ UINT_32 u4BufLen; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ PARAM_WIFI_GSCAN_ACTION_CMD_PARAMS rWifiScanActionCmd; -+ -+ INT_32 i4Status = -EINVAL; -+ struct nlattr *attr; -+ UINT_8 gGScanEn = 0; -+ -+ static UINT_8 k; /* only for test */ -+ -+ ASSERT(wiphy); -+ ASSERT(wdev); -+ if ((data == NULL) || !data_len) -+ goto nla_put_failure; -+ DBGLOG(REQ, INFO, "%s for vendor command: data_len=%d, data=0x%x 0x%x\r\n", -+ __func__, data_len, *((UINT_32 *) data), *((UINT_32 *) data + 1)); -+ -+ attr = (struct nlattr *)data; -+ if (attr->nla_type == GSCAN_ATTRIBUTE_ENABLE_FEATURE) -+ gGScanEn = nla_get_u32(attr); -+ DBGLOG(REQ, INFO, "gGScanEn=%d, \r\n", gGScanEn); -+ -+ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); -+ ASSERT(prGlueInfo); -+ if (gGScanEn == TRUE) -+ rWifiScanActionCmd.ucPscanAct = ENABLE; -+ else -+ rWifiScanActionCmd.ucPscanAct = DISABLE; -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetGSCNAction, -+ &rWifiScanActionCmd, -+ sizeof(PARAM_WIFI_GSCAN_ACTION_CMD_PARAMS), FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ -+ /* mtk_cfg80211_vendor_get_scan_results(wiphy, wdev, data, data_len ); */ -+ -+ return 0; -+ -+ /* only for test */ -+ if (k % 3 == 1) { -+ mtk_cfg80211_vendor_event_significant_change_results(wiphy, wdev, NULL, 0); -+ mtk_cfg80211_vendor_event_hotlist_ap_found(wiphy, wdev, NULL, 0); -+ mtk_cfg80211_vendor_event_hotlist_ap_lost(wiphy, wdev, NULL, 0); -+ } -+ k++; -+ -+ return 0; -+ -+nla_put_failure: -+ return i4Status; -+} -+ -+int mtk_cfg80211_vendor_enable_full_scan_results(struct wiphy *wiphy, struct wireless_dev *wdev, -+ const void *data, int data_len) -+{ -+ INT_32 i4Status = -EINVAL; -+ struct nlattr *attr; -+ UINT_8 gFullScanResultsEn = 0; -+ -+ ASSERT(wiphy); -+ ASSERT(wdev); -+ if ((data == NULL) || !data_len) -+ goto nla_put_failure; -+ DBGLOG(REQ, INFO, "%s for vendor command: data_len=%d, data=0x%x 0x%x\r\n", -+ __func__, data_len, *((UINT_32 *) data), *((UINT_32 *) data + 1)); -+ -+ attr = (struct nlattr *)data; -+ if (attr->nla_type == GSCAN_ENABLE_FULL_SCAN_RESULTS) -+ gFullScanResultsEn = nla_get_u32(attr); -+ DBGLOG(REQ, INFO, "gFullScanResultsEn=%d, \r\n", gFullScanResultsEn); -+ -+ return 0; -+ -+ /* only for test */ -+ mtk_cfg80211_vendor_event_complete_scan(wiphy, wdev, WIFI_SCAN_COMPLETE); -+ mtk_cfg80211_vendor_event_scan_results_available(wiphy, wdev, 4); -+ if (gFullScanResultsEn == TRUE) -+ mtk_cfg80211_vendor_event_full_scan_results(wiphy, wdev, NULL, 0); -+ -+ return 0; -+ -+nla_put_failure: -+ return i4Status; -+} -+ -+int mtk_cfg80211_vendor_get_scan_results(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int data_len) -+{ -+ /*WLAN_STATUS rStatus;*/ -+ UINT_32 u4BufLen; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ PARAM_WIFI_GSCAN_GET_RESULT_PARAMS rGSscnResultParm; -+ -+ INT_32 i4Status = -EINVAL; -+ struct nlattr *attr; -+ UINT_32 get_num = 0, real_num = 0; -+ UINT_8 flush = 0; -+ /*PARAM_WIFI_GSCAN_RESULT result[4], *pResult; -+ struct sk_buff *skb;*/ -+ int i; /*int j;*/ -+ /*UINT_32 scan_id;*/ -+ -+ ASSERT(wiphy); -+ ASSERT(wdev); -+ if ((data == NULL) || !data_len) -+ goto nla_put_failure; -+ DBGLOG(REQ, TRACE, "%s for vendor command: data_len=%d \r\n", __func__, data_len); -+ for (i = 0; i < 2; i++) -+ DBGLOG(REQ, LOUD, "0x%x 0x%x 0x%x 0x%x \r\n", *((UINT_32 *) data + i * 4), -+ *((UINT_32 *) data + i * 4 + 1), *((UINT_32 *) data + i * 4 + 2), -+ *((UINT_32 *) data + i * 4 + 3)); -+ -+ attr = (struct nlattr *)data; -+ if (attr->nla_type == GSCAN_ATTRIBUTE_NUM_OF_RESULTS) { -+ get_num = nla_get_u32(attr); -+ attr = (struct nlattr *)((UINT_8 *) attr + attr->nla_len); -+ } -+ if (attr->nla_type == GSCAN_ATTRIBUTE_FLUSH_RESULTS) { -+ flush = nla_get_u8(attr); -+ attr = (struct nlattr *)((UINT_8 *) attr + attr->nla_len); -+ } -+ DBGLOG(REQ, TRACE, "number=%d, flush=%d \r\n", get_num, flush); -+ -+ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); -+ ASSERT(prGlueInfo); -+ -+ real_num = (get_num < PSCAN_MAX_SCAN_CACHE_SIZE) ? get_num : PSCAN_MAX_SCAN_CACHE_SIZE; -+ get_num = real_num; -+ -+#if 0 /* driver buffer FW results and reports by buffer workaround for FW mismatch with hal results numbers */ -+ g_GetResultsCmdCnt++; -+ DBGLOG(REQ, INFO, -+ "(g_GetResultsCmdCnt [%d], g_GetResultsBufferedCnt [%d]\n", g_GetResultsCmdCnt, -+ g_GetResultsBufferedCnt); -+ -+ BOOLEAN fgIsGetResultFromBuffer = FALSE; -+ UINT_8 BufferedResultReportIndex = 0; -+ -+ if (g_GetResultsBufferedCnt > 0) { -+ -+ DBGLOG(REQ, INFO, -+ "(g_GetResultsBufferedCnt > 0), report buffered results instead of ask from FW\n"); -+ -+ /* reply the results to wifi_hal */ -+ for (i = 0; i < MAX_BUFFERED_GSCN_RESULTS; i++) { -+ -+ if (g_arGscanResultsIndicateNumber[i] > 0) { -+ real_num = g_arGscanResultsIndicateNumber[i]; -+ get_num = real_num; -+ g_arGscanResultsIndicateNumber[i] = 0; -+ fgIsGetResultFromBuffer = TRUE; -+ BufferedResultReportIndex = i; -+ break; -+ } -+ } -+ if (i == MAX_BUFFERED_GSCN_RESULTS) -+ DBGLOG(REQ, TRACE, "all buffered results are invalid, unexpected case \r\n"); -+ DBGLOG(REQ, TRACE, "BufferedResultReportIndex[%d] i = %d real_num[%d] get_num[%d] \r\n", -+ BufferedResultReportIndex, i, real_num, get_num); -+ } -+#endif -+ -+ rGSscnResultParm.get_num = get_num; -+ rGSscnResultParm.flush = flush; -+#if 0/* //driver buffer FW results and reports by buffer workaround for FW results mismatch with hal results number */ -+ if (fgIsGetResultFromBuffer) { -+ nicRxProcessGSCNEvent(prGlueInfo->prAdapter, g_arGscnResultsTempBuffer[BufferedResultReportIndex]); -+ g_GetResultsBufferedCnt--; -+ g_GetResultsCmdCnt--; -+ nicRxReturnRFB(prGlueInfo->prAdapter, g_arGscnResultsTempBuffer[BufferedResultReportIndex]); -+ } else -+#endif -+ { -+ kalIoctl(prGlueInfo, -+ wlanoidGetGSCNResult, -+ &rGSscnResultParm, -+ sizeof(PARAM_WIFI_GSCAN_GET_RESULT_PARAMS), FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ } -+ return 0; -+ -+nla_put_failure: -+ return i4Status; -+} -+ -+int mtk_cfg80211_vendor_get_rtt_capabilities(struct wiphy *wiphy, -+ struct wireless_dev *wdev, const void *data, int data_len) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ INT_32 i4Status = -EINVAL; -+ PARAM_WIFI_RTT_CAPABILITIES rRttCapabilities; -+ struct sk_buff *skb; -+ -+ DBGLOG(REQ, TRACE, "%s for vendor command \r\n", __func__); -+ -+ ASSERT(wiphy); -+ ASSERT(wdev); -+ prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); -+ -+ skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(rRttCapabilities)); -+ if (!skb) { -+ DBGLOG(REQ, ERROR, "%s allocate skb failed:%x\n", __func__, i4Status); -+ return -ENOMEM; -+ } -+ -+ kalMemZero(&rRttCapabilities, sizeof(rRttCapabilities)); -+ -+ /*rStatus = kalIoctl(prGlueInfo, -+ wlanoidQueryStatistics, -+ &rRttCapabilities, -+ sizeof(rRttCapabilities), -+ TRUE, -+ TRUE, -+ TRUE, -+ FALSE, -+ &u4BufLen); */ -+ rRttCapabilities.rtt_one_sided_supported = 0; -+ rRttCapabilities.rtt_ftm_supported = 0; -+ rRttCapabilities.lci_support = 0; -+ rRttCapabilities.lcr_support = 0; -+ rRttCapabilities.preamble_support = 0; -+ rRttCapabilities.bw_support = 0; -+ -+ if (unlikely(nla_put(skb, RTT_ATTRIBUTE_CAPABILITIES, -+ sizeof(rRttCapabilities), &rRttCapabilities) < 0)) -+ goto nla_put_failure; -+ -+ i4Status = cfg80211_vendor_cmd_reply(skb); -+ return i4Status; -+ -+nla_put_failure: -+ kfree_skb(skb); -+ return i4Status; -+} -+ -+int mtk_cfg80211_vendor_llstats_get_info(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int data_len) -+{ -+ INT_32 i4Status = -EINVAL; -+ WIFI_RADIO_STAT *pRadioStat; -+ struct sk_buff *skb; -+ UINT_32 u4BufLen; -+ -+ ASSERT(wiphy); -+ ASSERT(wdev); -+ -+ u4BufLen = sizeof(WIFI_RADIO_STAT) + sizeof(WIFI_IFACE_STAT); -+ pRadioStat = kalMemAlloc(u4BufLen, VIR_MEM_TYPE); -+ if (!pRadioStat) { -+ DBGLOG(REQ, ERROR, "%s kalMemAlloc pRadioStat failed\n", __func__); -+ return -ENOMEM; -+ } -+ kalMemZero(pRadioStat, u4BufLen); -+ -+ skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, u4BufLen); -+ if (!skb) { -+ DBGLOG(REQ, TRACE, "%s allocate skb failed:%x\n", __func__, i4Status); -+ return -ENOMEM; -+ } -+ -+ /*rStatus = kalIoctl(prGlueInfo, -+ wlanoidQueryStatistics, -+ &rRadioStat, -+ sizeof(rRadioStat), -+ TRUE, -+ TRUE, -+ TRUE, -+ FALSE, -+ &u4BufLen); */ -+ /* only for test */ -+ pRadioStat->radio = 10; -+ pRadioStat->on_time = 11; -+ pRadioStat->tx_time = 12; -+ pRadioStat->num_channels = 4; -+ -+ /*NLA_PUT(skb, LSTATS_ATTRIBUTE_STATS, u4BufLen, pRadioStat);*/ -+ if (unlikely(nla_put(skb, LSTATS_ATTRIBUTE_STATS, u4BufLen, pRadioStat) < 0)) -+ goto nla_put_failure; -+ -+ i4Status = cfg80211_vendor_cmd_reply(skb); -+ kalMemFree(pRadioStat, VIR_MEM_TYPE, u4BufLen); -+ return -1; /* not support LLS now*/ -+ /* return i4Status; */ -+ -+nla_put_failure: -+ kfree_skb(skb); -+ return i4Status; -+} -+ -+int mtk_cfg80211_vendor_event_complete_scan(struct wiphy *wiphy, struct wireless_dev *wdev, WIFI_SCAN_EVENT complete) -+{ -+ struct sk_buff *skb; -+ -+ ASSERT(wiphy); -+ ASSERT(wdev); -+ /* WIFI_SCAN_EVENT complete_scan; */ -+ -+ DBGLOG(REQ, INFO, "%s for vendor command \r\n", __func__); -+ -+ skb = cfg80211_vendor_event_alloc(wiphy, wdev, sizeof(complete), GSCAN_EVENT_COMPLETE_SCAN, GFP_KERNEL); -+ if (!skb) { -+ DBGLOG(REQ, ERROR, "%s allocate skb failed\n", __func__); -+ return -ENOMEM; -+ } -+ /* complete_scan = WIFI_SCAN_COMPLETE; */ -+ /*NLA_PUT_U32(skb, GSCAN_EVENT_COMPLETE_SCAN, complete);*/ -+ { -+ unsigned int __tmp = complete; -+ -+ if (unlikely(nla_put(skb, GSCAN_EVENT_COMPLETE_SCAN, -+ sizeof(unsigned int), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ -+ cfg80211_vendor_event(skb, GFP_KERNEL); -+ return 0; -+ -+nla_put_failure: -+ kfree_skb(skb); -+ return -1; -+} -+ -+int mtk_cfg80211_vendor_event_scan_results_available(struct wiphy *wiphy, struct wireless_dev *wdev, UINT_32 num) -+{ -+ struct sk_buff *skb; -+ -+ ASSERT(wiphy); -+ ASSERT(wdev); -+ /* UINT_32 scan_result; */ -+ -+ DBGLOG(REQ, INFO, "%s for vendor command %d \r\n", __func__, num); -+ -+ skb = cfg80211_vendor_event_alloc(wiphy, wdev, sizeof(num), GSCAN_EVENT_SCAN_RESULTS_AVAILABLE, GFP_KERNEL); -+ if (!skb) { -+ DBGLOG(REQ, ERROR, "%s allocate skb failed\n", __func__); -+ return -ENOMEM; -+ } -+ /* scan_result = 2; */ -+ /*NLA_PUT_U32(skb, GSCAN_EVENT_SCAN_RESULTS_AVAILABLE, num);*/ -+ { -+ unsigned int __tmp = num; -+ -+ if (unlikely(nla_put(skb, GSCAN_EVENT_SCAN_RESULTS_AVAILABLE, -+ sizeof(unsigned int), &__tmp) < 0)) -+ goto nla_put_failure; -+ } -+ -+ cfg80211_vendor_event(skb, GFP_KERNEL); -+ return 0; -+ -+nla_put_failure: -+ kfree_skb(skb); -+ return -1; -+} -+ -+int mtk_cfg80211_vendor_event_full_scan_results(struct wiphy *wiphy, struct wireless_dev *wdev, -+ P_PARAM_WIFI_GSCAN_RESULT pdata, UINT_32 data_len) -+{ -+ struct sk_buff *skb; -+ PARAM_WIFI_GSCAN_RESULT result; -+ -+ ASSERT(wiphy); -+ ASSERT(wdev); -+ DBGLOG(REQ, INFO, "%s for vendor command \r\n", __func__); -+ -+ skb = cfg80211_vendor_event_alloc(wiphy, wdev, sizeof(result), GSCAN_EVENT_FULL_SCAN_RESULTS, GFP_KERNEL); -+ if (!skb) { -+ DBGLOG(REQ, ERROR, "%s allocate skb failed\n", __func__); -+ return -ENOMEM; -+ } -+ -+ kalMemZero(&result, sizeof(result)); -+ kalMemCopy(result.ssid, "Gscan_full_test", sizeof("Gscan_full_test")); -+ result.channel = 2437; -+ -+ /* kalMemCopy(&result, pdata, sizeof(PARAM_WIFI_GSCAN_RESULT); */ -+ /*NLA_PUT(skb, GSCAN_EVENT_FULL_SCAN_RESULTS, sizeof(result), &result);*/ -+ if (unlikely(nla_put(skb, GSCAN_EVENT_FULL_SCAN_RESULTS, -+ sizeof(result), &result) < 0)) -+ goto nla_put_failure; -+ -+ cfg80211_vendor_event(skb, GFP_KERNEL); -+ return 0; -+ -+nla_put_failure: -+ kfree_skb(skb); -+ return -1; -+} -+ -+int mtk_cfg80211_vendor_event_significant_change_results(struct wiphy *wiphy, struct wireless_dev *wdev, -+ P_PARAM_WIFI_CHANGE_RESULT pdata, UINT_32 data_len) -+{ -+ struct sk_buff *skb; -+ PARAM_WIFI_CHANGE_RESULT result[2], *presult; -+ -+ ASSERT(wiphy); -+ ASSERT(wdev); -+ DBGLOG(REQ, INFO, "%s for vendor command \r\n", __func__); -+ -+ skb = cfg80211_vendor_event_alloc(wiphy, wdev, sizeof(PARAM_WIFI_CHANGE_RESULT), -+ GSCAN_EVENT_SIGNIFICANT_CHANGE_RESULTS, GFP_KERNEL); -+ if (!skb) { -+ DBGLOG(REQ, ERROR, "%s allocate skb failed\n", __func__); -+ return -ENOMEM; -+ } -+ -+ presult = result; -+ kalMemZero(presult, (sizeof(PARAM_WIFI_CHANGE_RESULT) * 2)); -+ /* only for test */ -+ kalMemCopy(presult->bssid, "213123", sizeof(mac_addr)); -+ presult->channel = 2437; -+ presult->rssi[0] = -45; -+ presult->rssi[1] = -46; -+ presult++; -+ presult->channel = 2439; -+ presult->rssi[0] = -47; -+ presult->rssi[1] = -48; -+ /*NLA_PUT(skb, GSCAN_EVENT_SIGNIFICANT_CHANGE_RESULTS, (sizeof(PARAM_WIFI_CHANGE_RESULT) * 2), result);*/ -+ if (unlikely(nla_put(skb, GSCAN_EVENT_SIGNIFICANT_CHANGE_RESULTS, -+ (sizeof(PARAM_WIFI_CHANGE_RESULT) * 2), result) < 0)) -+ goto nla_put_failure; -+ -+ cfg80211_vendor_event(skb, GFP_KERNEL); -+ return 0; -+ -+nla_put_failure: -+ kfree_skb(skb); -+ return -1; -+} -+ -+int mtk_cfg80211_vendor_event_hotlist_ap_found(struct wiphy *wiphy, struct wireless_dev *wdev, -+ P_PARAM_WIFI_GSCAN_RESULT pdata, UINT_32 data_len) -+{ -+ struct sk_buff *skb; -+ PARAM_WIFI_GSCAN_RESULT result[2], *presult; -+ -+ ASSERT(wiphy); -+ ASSERT(wdev); -+ DBGLOG(REQ, INFO, "%s for vendor command \r\n", __func__); -+ -+ skb = cfg80211_vendor_event_alloc(wiphy, wdev, sizeof(PARAM_WIFI_GSCAN_RESULT), -+ GSCAN_EVENT_HOTLIST_RESULTS_FOUND, GFP_KERNEL); -+ if (!skb) { -+ DBGLOG(REQ, ERROR, "%s allocate skb failed\n", __func__); -+ return -ENOMEM; -+ } -+ -+ presult = result; -+ kalMemZero(presult, (sizeof(PARAM_WIFI_GSCAN_RESULT) * 2)); -+ /* only for test */ -+ kalMemCopy(presult->bssid, "123123", sizeof(mac_addr)); -+ presult->channel = 2441; -+ presult->rssi = -45; -+ presult++; -+ presult->channel = 2443; -+ presult->rssi = -47; -+ /*NLA_PUT(skb, GSCAN_EVENT_HOTLIST_RESULTS_FOUND, (sizeof(PARAM_WIFI_GSCAN_RESULT) * 2), result);*/ -+ if (unlikely(nla_put(skb, GSCAN_EVENT_HOTLIST_RESULTS_FOUND, -+ (sizeof(PARAM_WIFI_GSCAN_RESULT) * 2), result) < 0)) -+ goto nla_put_failure; -+ -+ cfg80211_vendor_event(skb, GFP_KERNEL); -+ return 0; -+ -+nla_put_failure: -+ kfree_skb(skb); -+ return -1; -+} -+ -+int mtk_cfg80211_vendor_event_hotlist_ap_lost(struct wiphy *wiphy, struct wireless_dev *wdev, -+ P_PARAM_WIFI_GSCAN_RESULT pdata, UINT_32 data_len) -+{ -+ struct sk_buff *skb; -+ PARAM_WIFI_GSCAN_RESULT result[2], *presult; -+ -+ ASSERT(wiphy); -+ ASSERT(wdev); -+ DBGLOG(REQ, INFO, "%s for vendor command \r\n", __func__); -+ -+ skb = cfg80211_vendor_event_alloc(wiphy, wdev, sizeof(PARAM_WIFI_GSCAN_RESULT), -+ GSCAN_EVENT_HOTLIST_RESULTS_LOST, GFP_KERNEL); -+ if (!skb) { -+ DBGLOG(REQ, ERROR, "%s allocate skb failed\n", __func__); -+ return -ENOMEM; -+ } -+ -+ presult = result; -+ kalMemZero(presult, (sizeof(PARAM_WIFI_GSCAN_RESULT) * 2)); -+ /* only for test */ -+ kalMemCopy(presult->bssid, "321321", sizeof(mac_addr)); -+ presult->channel = 2445; -+ presult->rssi = -46; -+ presult++; -+ presult->channel = 2447; -+ presult->rssi = -48; -+ /*NLA_PUT(skb, GSCAN_EVENT_HOTLIST_RESULTS_LOST, (sizeof(PARAM_WIFI_GSCAN_RESULT) * 2), result);*/ -+ if (unlikely(nla_put(skb, GSCAN_EVENT_HOTLIST_RESULTS_LOST, -+ (sizeof(PARAM_WIFI_GSCAN_RESULT) * 2), result) < 0)) -+ goto nla_put_failure; -+ -+ cfg80211_vendor_event(skb, GFP_KERNEL); -+ return 0; -+ -+nla_put_failure: -+ kfree_skb(skb); -+ return -1; -+} -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_wext.c b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_wext.c -new file mode 100644 -index 000000000000..1793742e9802 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_wext.c -@@ -0,0 +1,4158 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux/gl_wext.c#3 -+*/ -+ -+/*! \file gl_wext.c -+ \brief ioctl() (mostly Linux Wireless Extensions) routines for STA driver. -+*/ -+ -+/* -+** Log: gl_wext.c -+ * -+ * 06 13 2012 yuche.tsai -+ * NULL -+ * Update maintrunk driver. -+ * Add support for driver compose assoc request frame. -+ * -+ * 01 16 2012 wh.su -+ * [WCXRP00001170] [MT6620 Wi-Fi][Driver] Adding the related code for set/get band ioctl -+ * Adding the template code for set / get band IOCTL (with ICS supplicant_6).. -+ * -+ * 01 05 2012 wh.su -+ * [WCXRP00001153] [MT6620 Wi-Fi][Driver] Adding the get_ch_list and set_tx_power proto type function -+ * Adding the related ioctl / wlan oid function to set the Tx power cfg. -+ * -+ * 01 02 2012 wh.su -+ * [WCXRP00001153] [MT6620 Wi-Fi][Driver] Adding the get_ch_list and set_tx_power proto type function -+ * Adding the proto type function for set_int set_tx_power and get int get_ch_list. -+ * -+ * 11 10 2011 cp.wu -+ * [WCXRP00001098] [MT6620 Wi-Fi][Driver] Replace printk by DBG LOG macros in linux porting layer -+ * 1. eliminaite direct calls to printk in porting layer. -+ * 2. replaced by DBGLOG, which would be XLOG on ALPS platforms. -+ * -+ * 10 12 2011 wh.su -+ * [WCXRP00001036] [MT6620 Wi-Fi][Driver][FW] Adding the 802.11w code for MFP -+ * adding the 802.11w related function and define . -+ * -+ * 09 23 2011 tsaiyuan.hsu -+ * [WCXRP00000979] [MT6620 Wi-Fi][DRV]] stop attempting to connect to config AP after D3 state -+ * avoid entering D3 state after deep sleep. -+ * -+ * 07 28 2011 chinghwa.yu -+ * [WCXRP00000063] Update BCM CoEx design and settings -+ * Add BWCS cmd and event. -+ * -+ * 07 27 2011 wh.su -+ * [WCXRP00000877] [MT6620 Wi-Fi][Driver] Remove the netif_carry_ok check for avoid the wpa_supplicant fail to query -+ * the ap address -+ * Remove the netif check while query bssid and ssid -+ * -+ * 07 26 2011 chinglan.wang -+ * NULL -+ * [MT6620][WiFi Driver] Do not include the WSC IE in the association info packet when not do the wps connection.. -+ * -+ * 07 18 2011 chinghwa.yu -+ * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm -+ * Add CMD/Event for RDD and BWCS. -+ * -+ * 05 17 2011 eddie.chen -+ * [WCXRP00000603] [MT6620 Wi-Fi][DRV] Fix Klocwork warning -+ * Initialize the vairlabes. -+ * -+ * 05 11 2011 jeffrey.chang -+ * [WCXRP00000718] [MT6620 Wi-Fi] modify the behavior of setting tx power -+ * modify set_tx_pow ioctl -+ * -+ * 03 29 2011 terry.wu -+ * [WCXRP00000610] [MT 6620 Wi-Fi][Driver] Fix klocwork waring -+ * [MT6620 Wi-Fi][Driver] Fix klocwork warning. Add Null pointer check on wext_get_essid. Limit the upper bound of -+ * essid storage array. -+ * -+ * 03 21 2011 cp.wu -+ * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer -+ * improve portability for awareness of early version of linux kernel and wireless extension. -+ * -+ * 03 17 2011 chinglan.wang -+ * [WCXRP00000570] [MT6620 Wi-Fi][Driver] Add Wi-Fi Protected Setup v2.0 feature -+ * . -+ * -+ * 03 07 2011 terry.wu -+ * [WCXRP00000521] [MT6620 Wi-Fi][Driver] Remove non-standard debug message -+ * Toggle non-standard debug messages to comments. -+ * -+ * 02 21 2011 wh.su -+ * [WCXRP00000483] [MT6620 Wi-Fi][Driver] Check the kalIoctl return value before doing the memory copy at linux get -+ * essid -+ * fixed the potential error to do a larget memory copy while wlanoid get essid not actually running. -+ * -+ * 02 08 2011 george.huang -+ * [WCXRP00000422] [MT6620 Wi-Fi][Driver] support query power mode OID handler -+ * Support querying power mode OID. -+ * -+ * 01 29 2011 wh.su -+ * [WCXRP00000408] [MT6620 Wi-Fi][Driver] Not doing memory alloc while ioctl set ie with length 0 -+ * not doing mem alloc. while set ie length already 0 -+ * -+ * 01 20 2011 eddie.chen -+ * [WCXRP00000374] [MT6620 Wi-Fi][DRV] SW debug control -+ * Remove debug text. -+ * -+ * 01 20 2011 eddie.chen -+ * [WCXRP00000374] [MT6620 Wi-Fi][DRV] SW debug control -+ * Adjust OID order. -+ * -+ * 01 20 2011 eddie.chen -+ * [WCXRP00000374] [MT6620 Wi-Fi][DRV] SW debug control -+ * Add Oid for sw control debug command -+ * -+ * 01 11 2011 chinglan.wang -+ * NULL -+ * Modify to reslove the CR :[ALPS00028994] Use WEP security to connect Marvell 11N AP. Connection establish -+ * successfully. -+ * Use the WPS function to connect AP, the privacy bit always is set to 1. . -+ * -+ * 01 07 2011 cm.chang -+ * [WCXRP00000336] [MT6620 Wi-Fi][Driver] Add test mode commands in normal phone operation -+ * Add a new compiling option to control if MCR read/write is permitted -+ * -+ * 01 04 2011 cp.wu -+ * [WCXRP00000338] [MT6620 Wi-Fi][Driver] Separate kalMemAlloc into kmalloc and vmalloc implementations to ease -+ * physically continuous memory demands -+ * separate kalMemAlloc() into virtually-continuous and physically-continuous types -+ * to ease slab system pressure -+ * -+ * 01 04 2011 cp.wu -+ * [WCXRP00000338] [MT6620 Wi-Fi][Driver] Separate kalMemAlloc into kmalloc and vmalloc implementations to ease -+ * physically continuous memory demands -+ * separate kalMemAlloc() into virtually-continuous and physically-continuous type to ease slab system pressure -+ * -+ * 12 31 2010 cm.chang -+ * [WCXRP00000336] [MT6620 Wi-Fi][Driver] Add test mode commands in normal phone operation -+ * Add some iwpriv commands to support test mode operation -+ * -+ * 12 15 2010 george.huang -+ * [WCXRP00000152] [MT6620 Wi-Fi] AP mode power saving function -+ * Support set PS profile and set WMM-PS related iwpriv. -+ * -+ * 12 15 2010 george.huang -+ * [WCXRP00000152] [MT6620 Wi-Fi] AP mode power saving function -+ * Allow change PS profile function (through wext_set_power()). -+ * -+ * 12 14 2010 jeffrey.chang -+ * [WCXRP00000262] [MT6620 Wi-Fi][Driver] modify the scan request ioctl to handle hidden SSID -+ * handle hidden SSID -+ * -+ * 12 13 2010 chinglan.wang -+ * NULL -+ * Add WPS 1.0 feature flag to enable the WPS 1.0 function. -+ * -+ * 12 07 2010 cm.chang -+ * [WCXRP00000238] MT6620 Wi-Fi][Driver][FW] Support regulation domain setting from NVRAM and supplicant -+ * Fix compiling error -+ * -+ * 12 07 2010 cm.chang -+ * [WCXRP00000238] MT6620 Wi-Fi][Driver][FW] Support regulation domain setting from NVRAM and supplicant -+ * 1. Country code is from NVRAM or supplicant -+ * 2. Change band definition in CMD/EVENT. -+ * -+ * 11 30 2010 cp.wu -+ * [WCXRP00000213] [MT6620 Wi-Fi][Driver] Implement scanning with specified SSID for wpa_supplicant with ap_scan=1 -+ * . -+ * -+ * 11 08 2010 wh.su -+ * [WCXRP00000171] [MT6620 Wi-Fi][Driver] Add message check code same behavior as mt5921 -+ * add the message check code from mt5921. -+ * -+ * 10 19 2010 jeffrey.chang -+ * [WCXRP00000121] [MT6620 Wi-Fi][Driver] Temporarily disable set power mode ioctl which may cause 6620 to enter power -+ * saving -+ * Temporarily disable set power mode ioctl which may cause MT6620 to enter power saving -+ * -+ * 10 18 2010 jeffrey.chang -+ * [WCXRP00000116] [MT6620 Wi-Fi][Driver] Refine the set_scan ioctl to resolve the Android UI hanging issue -+ * refine the scan ioctl to prevent hanging of Android UI -+ * -+ * 10 01 2010 wh.su -+ * [WCXRP00000067] [MT6620 Wi-Fi][Driver] Support the android+ WAPI function -+ * add the scan result with wapi ie. -+ * -+ * 09 30 2010 wh.su -+ * [WCXRP00000072] [MT6620 Wi-Fi][Driver] Fix TKIP Counter Measure EAPoL callback register issue -+ * fixed the wapi ie assigned issue. -+ * -+ * 09 27 2010 wh.su -+ * NULL -+ * [WCXRP00000067][MT6620 Wi-Fi][Driver] Support the android+ WAPI function. -+ * -+ * 09 21 2010 kevin.huang -+ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning -+ * Eliminate Linux Compile Warning -+ * -+ * 09 09 2010 cp.wu -+ * NULL -+ * add WPS/WPA/RSN IE for Wi-Fi Direct scanning result. -+ * -+ * 09 06 2010 cp.wu -+ * NULL -+ * Androi/Linux: return current operating channel information -+ * -+ * 09 01 2010 wh.su -+ * NULL -+ * adding the wapi support for integration test. -+ * -+ * 08 02 2010 jeffrey.chang -+ * NULL -+ * enable remove key ioctl -+ * -+ * 08 02 2010 jeffrey.chang -+ * NULL -+ * 1) modify tx service thread to avoid busy looping -+ * 2) add spin lock declartion for linux build -+ * -+ * 07 28 2010 jeffrey.chang -+ * NULL -+ * 1) enable encyption ioctls -+ * 2) temporarily disable remove keys ioctl to prevent TX1 busy -+ * -+ * 07 28 2010 jeffrey.chang -+ * NULL -+ * 1) remove unused spinlocks -+ * 2) enable encyption ioctls -+ * 3) fix scan ioctl which may cause supplicant to hang -+ * -+ * 07 19 2010 jeffrey.chang -+ * -+ * add kal api for scanning done -+ * -+ * 07 19 2010 jeffrey.chang -+ * -+ * for linux driver migration -+ * -+ * 07 19 2010 jeffrey.chang -+ * -+ * Linux port modification -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 05 28 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * remove unused macro and debug messages -+ * -+ * 05 14 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * Add dissassoication support for wpa supplicant -+ * -+ * 04 22 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * -+ * 1) modify rx path code for supporting Wi-Fi direct -+ * 2) modify config.h since Linux dont need to consider retaining packet -+ * -+ * 04 21 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * add for private ioctl support -+ * -+ * 04 19 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * Add ioctl of power management -+ * -+ * 04 19 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * remove debug message -+ * -+ * 04 14 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * 1) prGlueInfo->pvInformationBuffer and prGlueInfo->u4InformationBufferLength are no longer used -+ * * 2) fix ioctl -+ * -+ * 04 12 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * remove debug messages for pre-release -+ * -+ * 04 07 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * rWlanInfo should be placed at adapter rather than glue due to most operations -+ * * * * * * * * are done in adapter layer. -+ * -+ * 04 02 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * fix ioctl type -+ * -+ * 04 01 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * enable pmksa cache operation -+ * -+ * 03 31 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * fix ioctl which may cause cmdinfo memory leak -+ * -+ * 03 31 2010 wh.su -+ * [WPD00003816][MT6620 Wi-Fi] Adding the security support -+ * modify the wapi related code for new driver's design. -+ * -+ * 03 30 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * emulate NDIS Pending OID facility -+ * -+ * 03 24 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * initial import for Linux port -+** \main\maintrunk.MT5921\38 2009-10-08 10:33:22 GMT mtk01090 -+** Avoid accessing private data of net_device directly. Replace with netdev_priv(). -+** Add more checking for input parameters and pointers. -+** \main\maintrunk.MT5921\37 2009-09-29 16:49:48 GMT mtk01090 -+** Remove unused variables -+** \main\maintrunk.MT5921\36 2009-09-28 20:19:11 GMT mtk01090 -+** Add private ioctl to carry OID structures. Restructure public/private ioctl interfaces to Linux kernel. -+** \main\maintrunk.MT5921\35 2009-09-03 11:42:30 GMT mtk01088 -+** adding the wapi ioctl support -+** \main\maintrunk.MT5921\34 2009-08-18 22:56:50 GMT mtk01090 -+** Add Linux SDIO (with mmc core) support. -+** Add Linux 2.6.21, 2.6.25, 2.6.26. -+** Fix compile warning in Linux. -+** \main\maintrunk.MT5921\33 2009-05-14 22:43:47 GMT mtk01089 -+** fix compiling warning -+** \main\maintrunk.MT5921\32 2009-05-07 22:26:18 GMT mtk01089 -+** Add mandatory and private IO control for Linux BWCS -+** \main\maintrunk.MT5921\31 2009-02-07 15:11:14 GMT mtk01088 -+** fixed the compiling error -+** \main\maintrunk.MT5921\30 2009-02-07 14:46:51 GMT mtk01088 -+** add the privacy setting from linux supplicant ap selection -+** \main\maintrunk.MT5921\29 2008-11-19 15:18:50 GMT mtk01088 -+** fixed the compling error -+** \main\maintrunk.MT5921\28 2008-11-19 11:56:18 GMT mtk01088 -+** rename some variable with pre-fix to avoid the misunderstanding -+** \main\maintrunk.MT5921\27 2008-08-29 16:59:43 GMT mtk01088 -+** fixed compiling error -+** \main\maintrunk.MT5921\26 2008-08-29 14:55:53 GMT mtk01088 -+** adjust the code for meet the coding style, and add assert check -+** \main\maintrunk.MT5921\25 2008-06-02 11:15:19 GMT mtk01461 -+** Update after wlanoidSetPowerMode changed -+** \main\maintrunk.MT5921\24 2008-05-30 15:13:12 GMT mtk01084 -+** rename wlanoid -+** \main\maintrunk.MT5921\23 2008-03-28 10:40:28 GMT mtk01461 -+** Add set desired rate in Linux STD IOCTL -+** \main\maintrunk.MT5921\22 2008-03-18 10:31:24 GMT mtk01088 -+** add pmkid ioctl and indicate -+** \main\maintrunk.MT5921\21 2008-03-11 15:21:24 GMT mtk01461 -+** \main\maintrunk.MT5921\20 2008-03-11 14:50:55 GMT mtk01461 -+** Refine WPS related priv ioctl for unified interface -+** -+** \main\maintrunk.MT5921\19 2008-03-06 16:30:41 GMT mtk01088 -+** move the configuration code from set essid function, -+** remove the non-used code -+** \main\maintrunk.MT5921\18 2008-02-21 15:47:09 GMT mtk01461 -+** Fix CR[489] -+** \main\maintrunk.MT5921\17 2008-02-12 23:38:31 GMT mtk01461 -+** Add Set Frequency & Channel oid support for Linux -+** \main\maintrunk.MT5921\16 2008-01-24 12:07:34 GMT mtk01461 -+** \main\maintrunk.MT5921\15 2008-01-24 12:00:10 GMT mtk01461 -+** Modify the wext_essid for set up correct information for IBSS, and fix the wrong input ptr for prAdapter -+** \main\maintrunk.MT5921\14 2007-12-06 09:30:12 GMT mtk01425 -+** 1. Branch Test -+** \main\maintrunk.MT5921\13 2007-12-04 18:07:59 GMT mtk01461 -+** fix typo -+** \main\maintrunk.MT5921\12 2007-11-30 17:10:21 GMT mtk01425 -+** 1. Fix compiling erros -+** -+** \main\maintrunk.MT5921\11 2007-11-27 10:43:22 GMT mtk01425 -+** 1. Add WMM-PS setting -+** \main\maintrunk.MT5921\10 2007-11-06 20:33:32 GMT mtk01088 -+** fixed the compiler error -+** \main\maintrunk.MT5921\9 2007-11-06 19:33:15 GMT mtk01088 -+** add WPS code -+** \main\maintrunk.MT5921\8 2007-10-30 12:00:44 GMT MTK01425 -+** 1. Update wlanQueryInformation -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+#include "gl_os.h" -+ -+#include "config.h" -+#include "wlan_oid.h" -+ -+#include "gl_wext.h" -+#include "gl_wext_priv.h" -+ -+#include "precomp.h" -+ -+#if CFG_SUPPORT_WAPI -+#include "gl_sec.h" -+#endif -+ -+/* compatibility to wireless extensions */ -+#ifdef WIRELESS_EXT -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+const long channel_freq[] = { -+ 2412, 2417, 2422, 2427, 2432, 2437, 2442, -+ 2447, 2452, 2457, 2462, 2467, 2472, 2484 -+}; -+ -+ -+#define NUM_CHANNELS (sizeof(channel_freq) / sizeof(channel_freq[0])) -+ -+#define MAX_SSID_LEN 32 -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+/* NOTE: name in iwpriv_args only have 16 bytes */ -+static const struct iw_priv_args rIwPrivTable[] = { -+ {IOCTL_SET_INT, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, ""}, -+ {IOCTL_GET_INT, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, ""}, -+ {IOCTL_SET_INT, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3, 0, ""}, -+ {IOCTL_GET_INT, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3, ""}, -+ {IOCTL_SET_INT, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, ""}, -+ -+ {IOCTL_GET_INT, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, ""}, -+ {IOCTL_GET_INT, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, ""}, -+ -+ {IOCTL_SET_INTS, IW_PRIV_TYPE_INT | 4, 0, ""}, -+ {IOCTL_GET_INT, 0, IW_PRIV_TYPE_INT | 50, ""}, -+ {IOCTL_GET_INT, 0, IW_PRIV_TYPE_CHAR | 16, ""}, -+ -+ {IOCTL_SET_STRING, IW_PRIV_TYPE_CHAR | 256, 0, ""}, -+ -+ /* added for set_oid and get_oid */ -+ {IOCTL_SET_STRUCT, 256, 0, ""}, -+ {IOCTL_GET_STRUCT, 0, 256, ""}, -+ -+ /* sub-ioctl definitions */ -+#if 0 -+ {PRIV_CMD_REG_DOMAIN, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_reg_domain"}, -+ {PRIV_CMD_REG_DOMAIN, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_reg_domain"}, -+#endif -+ -+#if CFG_TCP_IP_CHKSUM_OFFLOAD -+ {PRIV_CMD_CSUM_OFFLOAD, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_tcp_csum"}, -+#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */ -+ -+ {PRIV_CMD_POWER_MODE, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_power_mode"}, -+ {PRIV_CMD_POWER_MODE, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_power_mode"}, -+ -+ {PRIV_CMD_WMM_PS, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3, 0, "set_wmm_ps"}, -+ -+ {PRIV_CMD_TEST_MODE, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_test_mode"}, -+ {PRIV_CMD_TEST_CMD, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "set_test_cmd"}, -+ {PRIV_CMD_TEST_CMD, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, -+ "get_test_result"}, -+#if CFG_SUPPORT_PRIV_MCR_RW -+ {PRIV_CMD_ACCESS_MCR, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "set_mcr"}, -+ {PRIV_CMD_ACCESS_MCR, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, -+ "get_mcr"}, -+#endif -+ {PRIV_CMD_SW_CTRL, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "set_sw_ctrl"}, -+ {PRIV_CMD_SW_CTRL, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, -+ "get_sw_ctrl"}, -+ -+#if CFG_SUPPORT_BCM && CFG_SUPPORT_BCM_BWCS -+ {PRIV_CUSTOM_BWCS_CMD, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_bwcs"}, -+ /* GET STRUCT sub-ioctls commands */ -+ {PRIV_CUSTOM_BWCS_CMD, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, -+ "get_bwcs"}, -+#endif -+ -+ /* SET STRUCT sub-ioctls commands */ -+ {PRIV_CMD_OID, 256, 0, "set_oid"}, -+ /* GET STRUCT sub-ioctls commands */ -+ {PRIV_CMD_OID, 0, 256, "get_oid"}, -+ -+ {PRIV_CMD_BAND_CONFIG, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_band"}, -+ {PRIV_CMD_BAND_CONFIG, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_band"}, -+ -+ {PRIV_CMD_SET_TX_POWER, IW_PRIV_TYPE_INT | 4, 0, "set_txpower"}, -+ {PRIV_CMD_GET_CH_LIST, 0, IW_PRIV_TYPE_INT | 50, "get_ch_list"}, -+ {PRIV_CMD_DUMP_MEM, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, -+ "get_mem"}, -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ {PRIV_CMD_P2P_MODE, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "set_p2p_mode"}, -+#endif -+ {PRIV_CMD_GET_BUILD_DATE_CODE, 0, IW_PRIV_TYPE_CHAR | 16, "get_date_code"}, -+ {PRIV_CMD_GET_DEBUG_CODE, 0, IW_PRIV_TYPE_CHAR | 16, "get_dbg_code"}, -+ /* handle any command with many input parameters */ -+ {PRIV_CMD_OTHER, IW_PRIV_TYPE_CHAR | 256, 0, "set_str_cmd"}, -+ -+ {PRIV_CMD_WFD_DEBUG_CODE, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "set_wfd_dbg_code"}, -+}; -+ -+static const iw_handler rIwPrivHandler[] = { -+ [IOCTL_SET_INT - SIOCIWFIRSTPRIV] = priv_set_int, -+ [IOCTL_GET_INT - SIOCIWFIRSTPRIV] = priv_get_int, -+ [IOCTL_SET_ADDRESS - SIOCIWFIRSTPRIV] = NULL, -+ [IOCTL_GET_ADDRESS - SIOCIWFIRSTPRIV] = NULL, -+ [IOCTL_SET_STR - SIOCIWFIRSTPRIV] = NULL, -+ [IOCTL_GET_STR - SIOCIWFIRSTPRIV] = NULL, -+ [IOCTL_SET_KEY - SIOCIWFIRSTPRIV] = NULL, -+ [IOCTL_GET_KEY - SIOCIWFIRSTPRIV] = NULL, -+ [IOCTL_SET_STRUCT - SIOCIWFIRSTPRIV] = priv_set_struct, -+ [IOCTL_GET_STRUCT - SIOCIWFIRSTPRIV] = priv_get_struct, -+ [IOCTL_SET_STRUCT_FOR_EM - SIOCIWFIRSTPRIV] = priv_set_struct, -+ [IOCTL_SET_INTS - SIOCIWFIRSTPRIV] = priv_set_ints, -+ [IOCTL_GET_INTS - SIOCIWFIRSTPRIV] = priv_get_ints, -+ [IOCTL_SET_STRING - SIOCIWFIRSTPRIV] = priv_set_string, -+}; -+ -+const struct iw_handler_def wext_handler_def = { -+ .num_standard = 0, -+ .num_private = (__u16) sizeof(rIwPrivHandler) / sizeof(iw_handler), -+ .num_private_args = (__u16) sizeof(rIwPrivTable) / sizeof(struct iw_priv_args), -+ .standard = (iw_handler *) NULL, -+ .private = rIwPrivHandler, -+ .private_args = rIwPrivTable, -+ .get_wireless_stats = wext_get_wireless_stats, -+}; -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Find the desired WPA/RSN Information Element according to desiredElemID. -+* -+* \param[in] pucIEStart IE starting address. -+* \param[in] i4TotalIeLen Total length of all the IE. -+* \param[in] ucDesiredElemId Desired element ID. -+* \param[out] ppucDesiredIE Pointer to the desired IE. -+* -+* \retval TRUE Find the desired IE. -+* \retval FALSE Desired IE not found. -+* -+* \note -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN -+wextSrchDesiredWPAIE(IN PUINT_8 pucIEStart, -+ IN INT_32 i4TotalIeLen, IN UINT_8 ucDesiredElemId, OUT PUINT_8 *ppucDesiredIE) -+{ -+ INT_32 i4InfoElemLen; -+ -+ ASSERT(pucIEStart); -+ ASSERT(ppucDesiredIE); -+ -+ while (i4TotalIeLen >= 2) { -+ i4InfoElemLen = (INT_32) pucIEStart[1] + 2; -+ -+ if (pucIEStart[0] == ucDesiredElemId && i4InfoElemLen <= i4TotalIeLen) { -+ if (ucDesiredElemId != 0xDD) { -+ /* Non 0xDD, OK! */ -+ *ppucDesiredIE = &pucIEStart[0]; -+ return TRUE; -+ } -+ /* EID == 0xDD, check WPA IE */ -+ if (pucIEStart[1] >= 4) { -+ if (memcmp(&pucIEStart[2], "\x00\x50\xf2\x01", 4) == 0) { -+ *ppucDesiredIE = &pucIEStart[0]; -+ return TRUE; -+ } -+ } /* check WPA IE length */ -+ /* check EID == 0xDD */ -+ } -+ -+ /* check desired EID */ -+ /* Select next information element. */ -+ i4TotalIeLen -= i4InfoElemLen; -+ pucIEStart += i4InfoElemLen; -+ } -+ -+ return FALSE; -+} /* parseSearchDesiredWPAIE */ -+ -+#if CFG_SUPPORT_WAPI -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Find the desired WAPI Information Element . -+* -+* \param[in] pucIEStart IE starting address. -+* \param[in] i4TotalIeLen Total length of all the IE. -+* \param[out] ppucDesiredIE Pointer to the desired IE. -+* -+* \retval TRUE Find the desired IE. -+* \retval FALSE Desired IE not found. -+* -+* \note -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN wextSrchDesiredWAPIIE(IN PUINT_8 pucIEStart, IN INT_32 i4TotalIeLen, OUT PUINT_8 *ppucDesiredIE) -+{ -+ INT_32 i4InfoElemLen; -+ -+ ASSERT(pucIEStart); -+ ASSERT(ppucDesiredIE); -+ -+ while (i4TotalIeLen >= 2) { -+ i4InfoElemLen = (INT_32) pucIEStart[1] + 2; -+ -+ if (pucIEStart[0] == ELEM_ID_WAPI && i4InfoElemLen <= i4TotalIeLen) { -+ *ppucDesiredIE = &pucIEStart[0]; -+ return TRUE; -+ } -+ -+ /* check desired EID */ -+ /* Select next information element. */ -+ i4TotalIeLen -= i4InfoElemLen; -+ pucIEStart += i4InfoElemLen; -+ } -+ -+ return FALSE; -+} /* wextSrchDesiredWAPIIE */ -+#endif -+ -+#if CFG_SUPPORT_HOTSPOT_2_0 -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Check if exist the desired HS2.0 Information Element according to desiredElemID. -+* -+* \param[in] pucIEStart IE starting address. -+* \param[in] i4TotalIeLen Total length of all the IE. -+* \param[in] ucDesiredElemId Desired element ID. -+* \param[out] ppucDesiredIE Pointer to the desired IE. -+* -+* \retval TRUE Find the desired IE. -+* \retval FALSE Desired IE not found. -+* -+* \note -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN wextIsDesiredHS20IE(IN PUINT_8 pucCurIE, IN INT_32 i4TotalIeLen) -+{ -+ INT_32 i4InfoElemLen; -+ -+ ASSERT(pucCurIE); -+ -+ i4InfoElemLen = (INT_32) pucCurIE[1] + 2; -+ -+ if (pucCurIE[0] == ELEM_ID_VENDOR && i4InfoElemLen <= i4TotalIeLen) { -+ if (pucCurIE[1] >= ELEM_MIN_LEN_HS20_INDICATION) { -+ if (memcmp(&pucCurIE[2], "\x50\x6f\x9a\x10", 4) == 0) -+ return TRUE; -+ } -+ } -+ /* check desired EID */ -+ return FALSE; -+} /* wextIsDesiredHS20IE */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Check if exist the desired interworking Information Element according to desiredElemID. -+* -+* \param[in] pucIEStart IE starting address. -+* \param[in] i4TotalIeLen Total length of all the IE. -+* \param[in] ucDesiredElemId Desired element ID. -+* \param[out] ppucDesiredIE Pointer to the desired IE. -+* -+* \retval TRUE Find the desired IE. -+* \retval FALSE Desired IE not found. -+* -+* \note -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN wextIsDesiredInterworkingIE(IN PUINT_8 pucCurIE, IN INT_32 i4TotalIeLen) -+{ -+ INT_32 i4InfoElemLen; -+ -+ ASSERT(pucCurIE); -+ -+ i4InfoElemLen = (INT_32) pucCurIE[1] + 2; -+ -+ if (pucCurIE[0] == ELEM_ID_INTERWORKING && i4InfoElemLen <= i4TotalIeLen) { -+ switch (pucCurIE[1]) { -+ case IW_IE_LENGTH_ANO: -+ case IW_IE_LENGTH_ANO_HESSID: -+ case IW_IE_LENGTH_ANO_VENUE: -+ case IW_IE_LENGTH_ANO_VENUE_HESSID: -+ return TRUE; -+ -+ default: -+ break; -+ } -+ -+ } -+ /* check desired EID */ -+ return FALSE; -+} /* wextIsDesiredInterworkingIE */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Check if exist the desired Adv Protocol Information Element according to desiredElemID. -+* -+* \param[in] pucIEStart IE starting address. -+* \param[in] i4TotalIeLen Total length of all the IE. -+* \param[in] ucDesiredElemId Desired element ID. -+* \param[out] ppucDesiredIE Pointer to the desired IE. -+* -+* \retval TRUE Find the desired IE. -+* \retval FALSE Desired IE not found. -+* -+* \note -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN wextIsDesiredAdvProtocolIE(IN PUINT_8 pucCurIE, IN INT_32 i4TotalIeLen) -+{ -+ INT_32 i4InfoElemLen; -+ -+ ASSERT(pucCurIE); -+ -+ i4InfoElemLen = (INT_32) pucCurIE[1] + 2; -+ -+ if (pucCurIE[0] == ELEM_ID_ADVERTISEMENT_PROTOCOL && i4InfoElemLen <= i4TotalIeLen) -+ return TRUE; -+ /* check desired EID */ -+ return FALSE; -+} /* wextIsDesiredAdvProtocolIE */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Check if exist the desired Roaming Consortium Information Element according to desiredElemID. -+* -+* \param[in] pucIEStart IE starting address. -+* \param[in] i4TotalIeLen Total length of all the IE. -+* \param[in] ucDesiredElemId Desired element ID. -+* \param[out] ppucDesiredIE Pointer to the desired IE. -+* -+* \retval TRUE Find the desired IE. -+* \retval FALSE Desired IE not found. -+* -+* \note -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN wextIsDesiredRoamingConsortiumIE(IN PUINT_8 pucCurIE, IN INT_32 i4TotalIeLen) -+{ -+ INT_32 i4InfoElemLen; -+ -+ ASSERT(pucCurIE); -+ -+ i4InfoElemLen = (INT_32) pucCurIE[1] + 2; -+ -+ if (pucCurIE[0] == ELEM_ID_ROAMING_CONSORTIUM && i4InfoElemLen <= i4TotalIeLen) -+ return TRUE; -+ /* check desired EID */ -+ return FALSE; -+} /* wextIsDesiredRoamingConsortiumIE */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Find the desired HS2.0 Information Element according to desiredElemID. -+* -+* \param[in] pucIEStart IE starting address. -+* \param[in] i4TotalIeLen Total length of all the IE. -+* \param[in] ucDesiredElemId Desired element ID. -+* \param[out] ppucDesiredIE Pointer to the desired IE. -+* -+* \retval TRUE Find the desired IE. -+* \retval FALSE Desired IE not found. -+* -+* \note -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN wextSrchDesiredHS20IE(IN PUINT_8 pucIEStart, IN INT_32 i4TotalIeLen, OUT PUINT_8 *ppucDesiredIE) -+{ -+ INT_32 i4InfoElemLen; -+ -+ ASSERT(pucIEStart); -+ ASSERT(ppucDesiredIE); -+ -+ while (i4TotalIeLen >= 2) { -+ i4InfoElemLen = (INT_32) pucIEStart[1] + 2; -+ -+ if (pucIEStart[0] == ELEM_ID_VENDOR && i4InfoElemLen <= i4TotalIeLen) { -+ if (pucIEStart[1] >= ELEM_MIN_LEN_HS20_INDICATION) { -+ if (memcmp(&pucIEStart[2], "\x50\x6f\x9a\x10", 4) == 0) { -+ *ppucDesiredIE = &pucIEStart[0]; -+ return TRUE; -+ } -+ } -+ } -+ -+ /* check desired EID */ -+ /* Select next information element. */ -+ i4TotalIeLen -= i4InfoElemLen; -+ pucIEStart += i4InfoElemLen; -+ } -+ -+ return FALSE; -+} /* wextSrchDesiredHS20IE */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Find the desired interworking Information Element according to desiredElemID. -+* -+* \param[in] pucIEStart IE starting address. -+* \param[in] i4TotalIeLen Total length of all the IE. -+* \param[in] ucDesiredElemId Desired element ID. -+* \param[out] ppucDesiredIE Pointer to the desired IE. -+* -+* \retval TRUE Find the desired IE. -+* \retval FALSE Desired IE not found. -+* -+* \note -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN wextSrchDesiredInterworkingIE(IN PUINT_8 pucIEStart, IN INT_32 i4TotalIeLen, OUT PUINT_8 *ppucDesiredIE) -+{ -+ INT_32 i4InfoElemLen; -+ -+ ASSERT(pucIEStart); -+ ASSERT(ppucDesiredIE); -+ -+ while (i4TotalIeLen >= 2) { -+ i4InfoElemLen = (INT_32) pucIEStart[1] + 2; -+ -+ if (pucIEStart[0] == ELEM_ID_INTERWORKING && i4InfoElemLen <= i4TotalIeLen) { -+ *ppucDesiredIE = &pucIEStart[0]; -+ return TRUE; -+ } -+ -+ /* check desired EID */ -+ /* Select next information element. */ -+ i4TotalIeLen -= i4InfoElemLen; -+ pucIEStart += i4InfoElemLen; -+ } -+ -+ return FALSE; -+} /* wextSrchDesiredInterworkingIE */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Find the desired Adv Protocol Information Element according to desiredElemID. -+* -+* \param[in] pucIEStart IE starting address. -+* \param[in] i4TotalIeLen Total length of all the IE. -+* \param[in] ucDesiredElemId Desired element ID. -+* \param[out] ppucDesiredIE Pointer to the desired IE. -+* -+* \retval TRUE Find the desired IE. -+* \retval FALSE Desired IE not found. -+* -+* \note -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN wextSrchDesiredAdvProtocolIE(IN PUINT_8 pucIEStart, IN INT_32 i4TotalIeLen, OUT PUINT_8 *ppucDesiredIE) -+{ -+ INT_32 i4InfoElemLen; -+ -+ ASSERT(pucIEStart); -+ ASSERT(ppucDesiredIE); -+ -+ while (i4TotalIeLen >= 2) { -+ i4InfoElemLen = (INT_32) pucIEStart[1] + 2; -+ -+ if (pucIEStart[0] == ELEM_ID_ADVERTISEMENT_PROTOCOL && i4InfoElemLen <= i4TotalIeLen) { -+ *ppucDesiredIE = &pucIEStart[0]; -+ return TRUE; -+ } -+ -+ /* check desired EID */ -+ /* Select next information element. */ -+ i4TotalIeLen -= i4InfoElemLen; -+ pucIEStart += i4InfoElemLen; -+ } -+ -+ return FALSE; -+} /* wextSrchDesiredAdvProtocolIE */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Find the desired Roaming Consortium Information Element according to desiredElemID. -+* -+* \param[in] pucIEStart IE starting address. -+* \param[in] i4TotalIeLen Total length of all the IE. -+* \param[in] ucDesiredElemId Desired element ID. -+* \param[out] ppucDesiredIE Pointer to the desired IE. -+* -+* \retval TRUE Find the desired IE. -+* \retval FALSE Desired IE not found. -+* -+* \note -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN wextSrchDesiredRoamingConsortiumIE(IN PUINT_8 pucIEStart, IN INT_32 i4TotalIeLen, OUT PUINT_8 *ppucDesiredIE) -+{ -+ INT_32 i4InfoElemLen; -+ -+ ASSERT(pucIEStart); -+ ASSERT(ppucDesiredIE); -+ -+ while (i4TotalIeLen >= 2) { -+ i4InfoElemLen = (INT_32) pucIEStart[1] + 2; -+ -+ if (pucIEStart[0] == ELEM_ID_ROAMING_CONSORTIUM && i4InfoElemLen <= i4TotalIeLen) { -+ *ppucDesiredIE = &pucIEStart[0]; -+ return TRUE; -+ } -+ -+ /* check desired EID */ -+ /* Select next information element. */ -+ i4TotalIeLen -= i4InfoElemLen; -+ pucIEStart += i4InfoElemLen; -+ } -+ -+ return FALSE; -+} /* wextSrchDesiredRoamingConsortiumIE */ -+#endif -+ -+#if CFG_SUPPORT_WPS -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Find the desired WPS Information Element according to desiredElemID. -+* -+* \param[in] pucIEStart IE starting address. -+* \param[in] i4TotalIeLen Total length of all the IE. -+* \param[in] ucDesiredElemId Desired element ID. -+* \param[out] ppucDesiredIE Pointer to the desired IE. -+* -+* \retval TRUE Find the desired IE. -+* \retval FALSE Desired IE not found. -+* -+* \note -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN -+wextSrchDesiredWPSIE(IN PUINT_8 pucIEStart, -+ IN INT_32 i4TotalIeLen, IN UINT_8 ucDesiredElemId, OUT PUINT_8 *ppucDesiredIE) -+{ -+ INT_32 i4InfoElemLen; -+ -+ ASSERT(pucIEStart); -+ ASSERT(ppucDesiredIE); -+ -+ while (i4TotalIeLen >= 2) { -+ i4InfoElemLen = (INT_32) pucIEStart[1] + 2; -+ -+ if (pucIEStart[0] == ucDesiredElemId && i4InfoElemLen <= i4TotalIeLen) { -+ if (ucDesiredElemId != 0xDD) { -+ /* Non 0xDD, OK! */ -+ *ppucDesiredIE = &pucIEStart[0]; -+ return TRUE; -+ } -+ /* EID == 0xDD, check WPS IE */ -+ if (pucIEStart[1] >= 4) { -+ if (memcmp(&pucIEStart[2], "\x00\x50\xf2\x04", 4) == 0) { -+ *ppucDesiredIE = &pucIEStart[0]; -+ return TRUE; -+ } -+ } /* check WPS IE length */ -+ /* check EID == 0xDD */ -+ } -+ -+ /* check desired EID */ -+ /* Select next information element. */ -+ i4TotalIeLen -= i4InfoElemLen; -+ pucIEStart += i4InfoElemLen; -+ } -+ -+ return FALSE; -+} /* parseSearchDesiredWPSIE */ -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Get the name of the protocol used on the air. -+* -+* \param[in] prDev Net device requested. -+* \param[in] prIwrInfo NULL. -+* \param[out] pcName Buffer to store protocol name string -+* \param[in] pcExtra NULL. -+* -+* \retval 0 For success. -+* -+* \note If netif_carrier_ok, protocol name is returned; -+* otherwise, "disconnected" is returned. -+*/ -+/*----------------------------------------------------------------------------*/ -+static int -+wext_get_name(IN struct net_device *prNetDev, IN struct iw_request_info *prIwrInfo, OUT char *pcName, IN char *pcExtra) -+{ -+ ENUM_PARAM_NETWORK_TYPE_T eNetWorkType = PARAM_NETWORK_TYPE_NUM; -+ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ UINT_32 u4BufLen = 0; -+ -+ ASSERT(prNetDev); -+ ASSERT(pcName); -+ if (FALSE == GLUE_CHK_PR2(prNetDev, pcName)) -+ return -EINVAL; -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); -+ -+ if (netif_carrier_ok(prNetDev)) { -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidQueryNetworkTypeInUse, -+ &eNetWorkType, sizeof(eNetWorkType), TRUE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ switch (eNetWorkType) { -+ case PARAM_NETWORK_TYPE_DS: -+ strcpy(pcName, "IEEE 802.11b"); -+ break; -+ case PARAM_NETWORK_TYPE_OFDM24: -+ strcpy(pcName, "IEEE 802.11bgn"); -+ break; -+ case PARAM_NETWORK_TYPE_AUTOMODE: -+ case PARAM_NETWORK_TYPE_OFDM5: -+ strcpy(pcName, "IEEE 802.11abgn"); -+ break; -+ case PARAM_NETWORK_TYPE_FH: -+ default: -+ strcpy(pcName, "IEEE 802.11"); -+ break; -+ } -+ } else { -+ strcpy(pcName, "Disconnected"); -+ } -+ -+ return 0; -+} /* wext_get_name */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief To set the operating channel in the wireless device. -+* -+* \param[in] prDev Net device requested. -+* \param[in] prIwrInfo NULL -+* \param[in] prFreq Buffer to store frequency information -+* \param[in] pcExtra NULL -+* -+* \retval 0 For success. -+* \retval -EOPNOTSUPP If infrastructure mode is not NET NET_TYPE_IBSS. -+* \retval -EINVAL Invalid channel frequency. -+* -+* \note If infrastructure mode is IBSS, new channel frequency is set to device. -+* The range of channel number depends on different regulatory domain. -+*/ -+/*----------------------------------------------------------------------------*/ -+static int -+wext_set_freq(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwReqInfo, IN struct iw_freq *prIwFreq, IN char *pcExtra) -+{ -+ -+#if 0 -+ UINT_32 u4ChnlFreq; /* Store channel or frequency information */ -+ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ UINT_32 u4BufLen = 0; -+ -+ ASSERT(prNetDev); -+ ASSERT(prIwFreq); -+ if (FALSE == GLUE_CHK_PR2(prNetDev, prIwFreq)) -+ return -EINVAL; -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); -+ -+ /* -+ printk("set m:%d, e:%d, i:%d, flags:%d\n", -+ prIwFreq->m, prIwFreq->e, prIwFreq->i, prIwFreq->flags); -+ */ -+ -+ /* If setting by frequency, convert to a channel */ -+ if ((prIwFreq->e == 1) && (prIwFreq->m >= (int)2.412e8) && (prIwFreq->m <= (int)2.484e8)) { -+ -+ /* Change to KHz format */ -+ u4ChnlFreq = (UINT_32) (prIwFreq->m / (KILO / 10)); -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetFrequency, -+ &u4ChnlFreq, sizeof(u4ChnlFreq), FALSE, FALSE, FALSE, &u4BufLen); -+ -+ if (WLAN_STATUS_SUCCESS != rStatus) -+ return -EINVAL; -+ } -+ /* Setting by channel number */ -+ else if ((prIwFreq->m > KILO) || (prIwFreq->e > 0)) -+ return -EOPNOTSUPP; -+ -+ /* Change to channel number format */ -+ u4ChnlFreq = (UINT_32) prIwFreq->m; -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetChannel, &u4ChnlFreq, sizeof(u4ChnlFreq), FALSE, FALSE, FALSE, &u4BufLen); -+ -+ if (WLAN_STATUS_SUCCESS != rStatus) -+ return -EINVAL; -+ -+#endif -+ -+ return 0; -+ -+} /* wext_set_freq */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief To get the operating channel in the wireless device. -+* -+* \param[in] prDev Net device requested. -+* \param[in] prIwrInfo NULL. -+* \param[out] prFreq Buffer to store frequency information. -+* \param[in] pcExtra NULL. -+* -+* \retval 0 If netif_carrier_ok. -+* \retval -ENOTCONN Otherwise -+* -+* \note If netif_carrier_ok, channel frequency information is stored in pFreq. -+*/ -+/*----------------------------------------------------------------------------*/ -+static int -+wext_get_freq(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwrInfo, OUT struct iw_freq *prIwFreq, IN char *pcExtra) -+{ -+ UINT_32 u4Channel = 0; -+ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ UINT_32 u4BufLen = 0; -+ -+ ASSERT(prNetDev); -+ ASSERT(prIwFreq); -+ if (FALSE == GLUE_CHK_PR2(prNetDev, prIwFreq)) -+ return -EINVAL; -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); -+ -+ /* GeorgeKuo: TODO skip checking in IBSS mode */ -+ if (!netif_carrier_ok(prNetDev)) -+ return -ENOTCONN; -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidQueryFrequency, &u4Channel, sizeof(u4Channel), TRUE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ prIwFreq->m = (int)u4Channel; /* freq in KHz */ -+ prIwFreq->e = 3; -+ -+ return 0; -+ -+} /* wext_get_freq */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief To set operating mode. -+* -+* \param[in] prDev Net device requested. -+* \param[in] prIwrInfo NULL. -+* \param[in] pu4Mode Pointer to new operation mode. -+* \param[in] pcExtra NULL. -+* -+* \retval 0 For success. -+* \retval -EOPNOTSUPP If new mode is not supported. -+* -+* \note Device will run in new operation mode if it is valid. -+*/ -+/*----------------------------------------------------------------------------*/ -+static int -+wext_set_mode(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwReqInfo, IN unsigned int *pu4Mode, IN char *pcExtra) -+{ -+ ENUM_PARAM_OP_MODE_T eOpMode; -+ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ UINT_32 u4BufLen = 0; -+ -+ ASSERT(prNetDev); -+ ASSERT(pu4Mode); -+ if (FALSE == GLUE_CHK_PR2(prNetDev, pu4Mode)) -+ return -EINVAL; -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); -+ -+ switch (*pu4Mode) { -+ case IW_MODE_AUTO: -+ eOpMode = NET_TYPE_AUTO_SWITCH; -+ break; -+ -+ case IW_MODE_ADHOC: -+ eOpMode = NET_TYPE_IBSS; -+ break; -+ -+ case IW_MODE_INFRA: -+ eOpMode = NET_TYPE_INFRA; -+ break; -+ -+ default: -+ DBGLOG(REQ, ERROR, "%s(): Set UNSUPPORTED Mode = %d.\n", __func__, *pu4Mode); -+ return -EOPNOTSUPP; -+ } -+ -+ /* printk("%s(): Set Mode = %d\n", __FUNCTION__, *pu4Mode); */ -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetInfrastructureMode, -+ &eOpMode, sizeof(eOpMode), FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ -+ /* after set operation mode, key table are cleared */ -+ -+ /* reset wpa info */ -+ prGlueInfo->rWpaInfo.u4WpaVersion = IW_AUTH_WPA_VERSION_DISABLED; -+ prGlueInfo->rWpaInfo.u4KeyMgmt = 0; -+ prGlueInfo->rWpaInfo.u4CipherGroup = IW_AUTH_CIPHER_NONE; -+ prGlueInfo->rWpaInfo.u4CipherPairwise = IW_AUTH_CIPHER_NONE; -+ prGlueInfo->rWpaInfo.u4AuthAlg = IW_AUTH_ALG_OPEN_SYSTEM; -+#if CFG_SUPPORT_802_11W -+ prGlueInfo->rWpaInfo.u4Mfp = IW_AUTH_MFP_DISABLED; -+#endif -+ -+ return 0; -+} /* wext_set_mode */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief To get operating mode. -+* -+* \param[in] prNetDev Net device requested. -+* \param[in] prIwReqInfo NULL. -+* \param[out] pu4Mode Buffer to store operating mode information. -+* \param[in] pcExtra NULL. -+* -+* \retval 0 If data is valid. -+* \retval -EINVAL Otherwise. -+* -+* \note If netif_carrier_ok, operating mode information is stored in pu4Mode. -+*/ -+/*----------------------------------------------------------------------------*/ -+static int -+wext_get_mode(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwReqInfo, OUT unsigned int *pu4Mode, IN char *pcExtra) -+{ -+ ENUM_PARAM_OP_MODE_T eOpMode = NET_TYPE_NUM; -+ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ UINT_32 u4BufLen = 0; -+ -+ ASSERT(prNetDev); -+ ASSERT(pu4Mode); -+ if (FALSE == GLUE_CHK_PR2(prNetDev, pu4Mode)) -+ return -EINVAL; -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidQueryInfrastructureMode, -+ &eOpMode, sizeof(eOpMode), TRUE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ switch (eOpMode) { -+ case NET_TYPE_IBSS: -+ *pu4Mode = IW_MODE_ADHOC; -+ break; -+ -+ case NET_TYPE_INFRA: -+ *pu4Mode = IW_MODE_INFRA; -+ break; -+ -+ case NET_TYPE_AUTO_SWITCH: -+ *pu4Mode = IW_MODE_AUTO; -+ break; -+ -+ default: -+ DBGLOG(REQ, ERROR, "%s(): Get UNKNOWN Mode.\n", __func__); -+ return -EINVAL; -+ } -+ -+ return 0; -+} /* wext_get_mode */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief To get the valid range for each configurable STA setting value. -+* -+* \param[in] prDev Net device requested. -+* \param[in] prIwrInfo NULL. -+* \param[in] prData Pointer to iw_point structure, not used. -+* \param[out] pcExtra Pointer to buffer which is allocated by caller of this -+* function, wext_support_ioctl() or ioctl_standard_call() in -+* wireless.c. -+* -+* \retval 0 If data is valid. -+* -+* \note The extra buffer (pcExtra) is filled with information from driver. -+*/ -+/*----------------------------------------------------------------------------*/ -+static int -+wext_get_range(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwrInfo, IN struct iw_point *prData, OUT char *pcExtra) -+{ -+ struct iw_range *prRange = NULL; -+ PARAM_RATES_EX aucSuppRate = { 0 }; /* data buffers */ -+ int i = 0; -+ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ UINT_32 u4BufLen = 0; -+ -+ ASSERT(prNetDev); -+ ASSERT(pcExtra); -+ if (FALSE == GLUE_CHK_PR2(prNetDev, pcExtra)) -+ return -EINVAL; -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); -+ -+ prRange = (struct iw_range *)pcExtra; -+ -+ memset(prRange, 0, sizeof(*prRange)); -+ prRange->throughput = 20000000; /* 20Mbps */ -+ prRange->min_nwid = 0; /* not used */ -+ prRange->max_nwid = 0; /* not used */ -+ -+ /* scan_capa not implemented */ -+ -+ /* event_capa[6]: kernel + driver capabilities */ -+ prRange->event_capa[0] = (IW_EVENT_CAPA_K_0 | IW_EVENT_CAPA_MASK(SIOCGIWAP) -+ | IW_EVENT_CAPA_MASK(SIOCGIWSCAN) -+ /* can't display meaningful string in iwlist -+ | IW_EVENT_CAPA_MASK(SIOCGIWTXPOW) -+ | IW_EVENT_CAPA_MASK(IWEVMICHAELMICFAILURE) -+ | IW_EVENT_CAPA_MASK(IWEVASSOCREQIE) -+ | IW_EVENT_CAPA_MASK(IWEVPMKIDCAND) -+ */ -+ ); -+ prRange->event_capa[1] = IW_EVENT_CAPA_K_1; -+ -+ /* report 2.4G channel and frequency only */ -+ prRange->num_channels = (__u16) NUM_CHANNELS; -+ prRange->num_frequency = (__u8) NUM_CHANNELS; -+ for (i = 0; i < NUM_CHANNELS; i++) { -+ /* iwlib takes this number as channel number */ -+ prRange->freq[i].i = i + 1; -+ prRange->freq[i].m = channel_freq[i]; -+ prRange->freq[i].e = 6; /* Values in table in MHz */ -+ } -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidQuerySupportedRates, -+ &aucSuppRate, sizeof(aucSuppRate), TRUE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ for (i = 0; i < IW_MAX_BITRATES && i < PARAM_MAX_LEN_RATES_EX; i++) { -+ if (aucSuppRate[i] == 0) -+ break; -+ prRange->bitrate[i] = (aucSuppRate[i] & 0x7F) * 500000; /* 0.5Mbps */ -+ } -+ prRange->num_bitrates = i; -+ -+ prRange->min_rts = 0; -+ prRange->max_rts = 2347; -+ prRange->min_frag = 256; -+ prRange->max_frag = 2346; -+ -+ prRange->min_pmp = 0; /* power management by driver */ -+ prRange->max_pmp = 0; /* power management by driver */ -+ prRange->min_pmt = 0; /* power management by driver */ -+ prRange->max_pmt = 0; /* power management by driver */ -+ prRange->pmp_flags = IW_POWER_RELATIVE; /* pm default flag */ -+ prRange->pmt_flags = IW_POWER_ON; /* pm timeout flag */ -+ prRange->pm_capa = IW_POWER_ON; /* power management by driver */ -+ -+ prRange->encoding_size[0] = 5; /* wep40 */ -+ prRange->encoding_size[1] = 16; /* tkip */ -+ prRange->encoding_size[2] = 16; /* ckip */ -+ prRange->encoding_size[3] = 16; /* ccmp */ -+ prRange->encoding_size[4] = 13; /* wep104 */ -+ prRange->encoding_size[5] = 16; /* wep128 */ -+ prRange->num_encoding_sizes = 6; -+ prRange->max_encoding_tokens = 6; /* token? */ -+ -+#if WIRELESS_EXT < 17 -+ prRange->txpower_capa = 0x0002; /* IW_TXPOW_RELATIVE */ -+#else -+ prRange->txpower_capa = IW_TXPOW_RELATIVE; -+#endif -+ prRange->num_txpower = 5; -+ prRange->txpower[0] = 0; /* minimum */ -+ prRange->txpower[1] = 25; /* 25% */ -+ prRange->txpower[2] = 50; /* 50% */ -+ prRange->txpower[3] = 100; /* 100% */ -+ -+ prRange->we_version_compiled = WIRELESS_EXT; -+ prRange->we_version_source = WIRELESS_EXT; -+ -+ prRange->retry_capa = IW_RETRY_LIMIT; -+ prRange->retry_flags = IW_RETRY_LIMIT; -+ prRange->min_retry = 7; -+ prRange->max_retry = 7; -+ prRange->r_time_flags = IW_RETRY_ON; -+ prRange->min_r_time = 0; -+ prRange->max_r_time = 0; -+ -+ /* signal strength and link quality */ -+ /* Just define range here, reporting value moved to wext_get_stats() */ -+ prRange->sensitivity = -83; /* fixed value */ -+ prRange->max_qual.qual = 100; /* max 100% */ -+ prRange->max_qual.level = (__u8) (0x100 - 0); /* max 0 dbm */ -+ prRange->max_qual.noise = (__u8) (0x100 - 0); /* max 0 dbm */ -+ -+ /* enc_capa */ -+#if WIRELESS_EXT > 17 -+ prRange->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 | IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP; -+#endif -+ -+ /* min_pms; Minimal PM saving */ -+ /* max_pms; Maximal PM saving */ -+ /* pms_flags; How to decode max/min PM saving */ -+ -+ /* modul_capa; IW_MODUL_* bit field */ -+ /* bitrate_capa; Types of bitrates supported */ -+ -+ return 0; -+} /* wext_get_range */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief To set BSSID of AP to connect. -+* -+* \param[in] prDev Net device requested. -+* \param[in] prIwrInfo NULL. -+* \param[in] prAddr Pointer to struct sockaddr structure containing AP's BSSID. -+* \param[in] pcExtra NULL. -+* -+* \retval 0 For success. -+* -+* \note Desired AP's BSSID is set to driver. -+*/ -+/*----------------------------------------------------------------------------*/ -+static int -+wext_set_ap(IN struct net_device *prDev, -+ IN struct iw_request_info *prIwrInfo, IN struct sockaddr *prAddr, IN char *pcExtra) -+{ -+ return 0; -+} /* wext_set_ap */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief To get AP MAC address. -+* -+* \param[in] prDev Net device requested. -+* \param[in] prIwrInfo NULL. -+* \param[out] prAddr Pointer to struct sockaddr structure storing AP's BSSID. -+* \param[in] pcExtra NULL. -+* -+* \retval 0 If netif_carrier_ok. -+* \retval -ENOTCONN Otherwise. -+* -+* \note If netif_carrier_ok, AP's mac address is stored in pAddr->sa_data. -+*/ -+/*----------------------------------------------------------------------------*/ -+static int -+wext_get_ap(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwrInfo, OUT struct sockaddr *prAddr, IN char *pcExtra) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ UINT_32 u4BufLen = 0; -+ -+ ASSERT(prNetDev); -+ ASSERT(prAddr); -+ if (FALSE == GLUE_CHK_PR2(prNetDev, prAddr)) -+ return -EINVAL; -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); -+ -+ /* if (!netif_carrier_ok(prNetDev)) { */ -+ /* return -ENOTCONN; */ -+ /* } */ -+ -+ if (prGlueInfo->eParamMediaStateIndicated == PARAM_MEDIA_STATE_DISCONNECTED) { -+ /*memset(prAddr, 0, 6);*/ -+ memset(prAddr, 0, sizeof(struct sockaddr)); -+ return 0; -+ } -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidQueryBssid, prAddr->sa_data, ETH_ALEN, TRUE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ return 0; -+} /* wext_get_ap */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief To set mlme operation request. -+* -+* \param[in] prDev Net device requested. -+* \param[in] prIwrInfo NULL. -+* \param[in] prData Pointer of iw_point header. -+* \param[in] pcExtra Pointer to iw_mlme structure mlme request information. -+* -+* \retval 0 For success. -+* \retval -EOPNOTSUPP unsupported IW_MLME_ command. -+* \retval -EINVAL Set MLME Fail, different bssid. -+* -+* \note Driver will start mlme operation if valid. -+*/ -+/*----------------------------------------------------------------------------*/ -+static int -+wext_set_mlme(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwrInfo, IN struct iw_point *prData, IN char *pcExtra) -+{ -+ struct iw_mlme *prMlme = NULL; -+ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ UINT_32 u4BufLen = 0; -+ -+ ASSERT(prNetDev); -+ ASSERT(pcExtra); -+ if (FALSE == GLUE_CHK_PR2(prNetDev, pcExtra)) -+ return -EINVAL; -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); -+ -+ prMlme = (struct iw_mlme *)pcExtra; -+ if (prMlme->cmd == IW_MLME_DEAUTH || prMlme->cmd == IW_MLME_DISASSOC) { -+ if (!netif_carrier_ok(prNetDev)) { -+ DBGLOG(REQ, WARN, "[wifi] Set MLME Deauth/Disassoc, but netif_carrier_off\n"); -+ return 0; -+ } -+ -+ rStatus = kalIoctl(prGlueInfo, wlanoidSetDisassociate, NULL, 0, FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ return 0; -+ } -+ DBGLOG(REQ, WARN, "[wifi] unsupported IW_MLME_ command :%d\n", prMlme->cmd); -+ return -EOPNOTSUPP; -+ -+} /* wext_set_mlme */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief To issue scan request. -+* -+* \param[in] prDev Net device requested. -+* \param[in] prIwrInfo NULL. -+* \param[in] prData NULL. -+* \param[in] pcExtra NULL. -+* -+* \retval 0 For success. -+* \retval -EFAULT Tx power is off. -+* -+* \note Device will start scanning. -+*/ -+/*----------------------------------------------------------------------------*/ -+static int -+wext_set_scan(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwrInfo, IN union iwreq_data *prData, IN char *pcExtra) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ UINT_32 u4BufLen = 0; -+ int essid_len = 0; -+ -+ ASSERT(prNetDev); -+ if (FALSE == GLUE_CHK_DEV(prNetDev)) -+ return -EINVAL; -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); -+ -+#if WIRELESS_EXT > 17 -+ /* retrieve SSID */ -+ if (prData) -+ essid_len = ((struct iw_scan_req *)(((struct iw_point *)prData)->pointer))->essid_len; -+#endif -+ -+ init_completion(&prGlueInfo->rScanComp); -+ -+ /* TODO: parse flags and issue different scan requests? */ -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetBssidListScan, pcExtra, essid_len, FALSE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ /* wait_for_completion_interruptible_timeout(&prGlueInfo->rScanComp, 2 * KAL_HZ); */ -+ /* kalIndicateStatusAndComplete(prGlueInfo, WLAN_STATUS_SCAN_COMPLETE, NULL, 0); */ -+ -+ return 0; -+} /* wext_set_scan */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief To write the ie to buffer -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static inline int snprintf_hex(char *buf, size_t buf_size, const u8 *data, size_t len) -+{ -+ size_t i; -+ char *pos = buf, *end = buf + buf_size; -+ int ret; -+ -+ if (buf_size == 0) -+ return 0; -+ -+ for (i = 0; i < len; i++) { -+ ret = snprintf(pos, end - pos, "%02x", data[i]); -+ if (ret < 0 || ret >= end - pos) { -+ end[-1] = '\0'; -+ return pos - buf; -+ } -+ pos += ret; -+ } -+ end[-1] = '\0'; -+ return pos - buf; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief To get scan results, transform results from driver's format to WE's. -+* -+* \param[in] prDev Net device requested. -+* \param[in] prIwrInfo NULL. -+* \param[out] prData Pointer to iw_point structure, pData->length is the size of -+* pcExtra buffer before used, and is updated after filling scan -+* results. -+* \param[out] pcExtra Pointer to buffer which is allocated by caller of this -+* function, wext_support_ioctl() or ioctl_standard_call() in -+* wireless.c. -+* -+* \retval 0 For success. -+* \retval -ENOMEM If dynamic memory allocation fail. -+* \retval -E2BIG Invalid length. -+* -+* \note Scan results is filled into pcExtra buffer, data size is updated in -+* pData->length. -+*/ -+/*----------------------------------------------------------------------------*/ -+static int -+wext_get_scan(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwrInfo, IN OUT struct iw_point *prData, IN char *pcExtra) -+{ -+ UINT_32 i = 0; -+ UINT_32 j = 0; -+ P_PARAM_BSSID_LIST_EX_T prList = NULL; -+ P_PARAM_BSSID_EX_T prBss = NULL; -+ P_PARAM_VARIABLE_IE_T prDesiredIE = NULL; -+ struct iw_event iwEvent; /* local iw_event buffer */ -+ -+ /* write pointer of extra buffer */ -+ char *pcCur = NULL; -+ /* pointer to the end of last full entry in extra buffer */ -+ char *pcValidEntryEnd = NULL; -+ char *pcEnd = NULL; /* end of extra buffer */ -+ -+ UINT_32 u4AllocBufLen = 0; -+ -+ /* arrange rate information */ -+ UINT_32 u4HighestRate = 0; -+ char aucRatesBuf[64]; -+ UINT_32 u4BufIndex; -+ -+ /* return value */ -+ int ret = 0; -+ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ UINT_32 u4BufLen = 0; -+ -+ ASSERT(prNetDev); -+ ASSERT(prData); -+ ASSERT(pcExtra); -+ if (FALSE == GLUE_CHK_PR3(prNetDev, prData, pcExtra)) -+ return -EINVAL; -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); -+ -+ /* Initialize local variables */ -+ pcCur = pcExtra; -+ pcValidEntryEnd = pcExtra; -+ pcEnd = pcExtra + prData->length; /* end of extra buffer */ -+ -+ /* Allocate another query buffer with the same size of extra buffer */ -+ u4AllocBufLen = prData->length; -+ prList = kalMemAlloc(u4AllocBufLen, VIR_MEM_TYPE); -+ if (prList == NULL) { -+ DBGLOG(REQ, ERROR, "[wifi] no memory for scan list:%d\n", prData->length); -+ ret = -ENOMEM; -+ goto error; -+ } -+ prList->u4NumberOfItems = 0; -+ -+ /* wait scan done */ -+ /* printk ("wait for scan results\n"); */ -+ /* wait_for_completion_interruptible_timeout(&prGlueInfo->rScanComp, 4 * KAL_HZ); */ -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidQueryBssidList, prList, u4AllocBufLen, TRUE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ if (rStatus == WLAN_STATUS_INVALID_LENGTH) { -+ /* Buffer length is not large enough. */ -+ /* printk(KERN_INFO "[wifi] buf:%d result:%ld\n", pData->length, u4BufLen); */ -+ -+#if WIRELESS_EXT >= 17 -+ /* This feature is supported in WE-17 or above, limited by iwlist. -+ ** Return -E2BIG and iwlist will request again with a larger buffer. -+ */ -+ ret = -E2BIG; -+ /* Update length to give application a hint on result length */ -+ prData->length = (__u16) u4BufLen; -+ goto error; -+#else -+ /* Realloc a larger query buffer here, but don't write too much to extra -+ ** buffer when filling it later. -+ */ -+ kalMemFree(prList, VIR_MEM_TYPE, u4AllocBufLen); -+ -+ u4AllocBufLen = u4BufLen; -+ prList = kalMemAlloc(u4AllocBufLen, VIR_MEM_TYPE); -+ if (prList == NULL) { -+ DBGLOG(REQ, ERROR, "[wifi] no memory for larger scan list :%u\n", u4BufLen); -+ ret = -ENOMEM; -+ goto error; -+ } -+ prList->NumberOfItems = 0; -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidQueryBssidList, prList, u4AllocBufLen, TRUE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ if (rStatus == WLAN_STATUS_INVALID_LENGTH) { -+ DBGLOG(REQ, ERROR, "[wifi] larger buf:%u result:%u\n", u4AllocBufLen, u4BufLen); -+ ret = -E2BIG; -+ prData->length = (__u16) u4BufLen; -+ goto error; -+ } -+#endif /* WIRELESS_EXT >= 17 */ -+ -+ } -+ -+ if (prList->u4NumberOfItems > CFG_MAX_NUM_BSS_LIST) { -+ DBGLOG(REQ, WARN, "[wifi] strange scan result count:%u\n", prList->u4NumberOfItems); -+ goto error; -+ } -+ -+ /* Copy required data from pList to pcExtra */ -+ prBss = &prList->arBssid[0]; /* set to the first entry */ -+ for (i = 0; i < prList->u4NumberOfItems; ++i) { -+ /* BSSID */ -+ iwEvent.cmd = SIOCGIWAP; -+ iwEvent.len = IW_EV_ADDR_LEN; -+ if ((pcCur + iwEvent.len) > pcEnd) -+ break; -+ iwEvent.u.ap_addr.sa_family = ARPHRD_ETHER; -+ ether_addr_copy(iwEvent.u.ap_addr.sa_data, prBss->arMacAddress); -+ memcpy(pcCur, &iwEvent, IW_EV_ADDR_LEN); -+ pcCur += IW_EV_ADDR_LEN; -+ -+ /* SSID */ -+ iwEvent.cmd = SIOCGIWESSID; -+ /* Modification to user space pointer(essid.pointer) is not needed. */ -+ iwEvent.u.essid.length = (__u16) prBss->rSsid.u4SsidLen; -+ iwEvent.len = IW_EV_POINT_LEN + iwEvent.u.essid.length; -+ -+ if ((pcCur + iwEvent.len) > pcEnd) -+ break; -+ iwEvent.u.essid.flags = 1; -+ iwEvent.u.essid.pointer = NULL; -+ -+#if WIRELESS_EXT <= 18 -+ memcpy(pcCur, &iwEvent, iwEvent.len); -+#else -+ memcpy(pcCur, &iwEvent, IW_EV_LCP_LEN); -+ memcpy(pcCur + IW_EV_LCP_LEN, &iwEvent.u.data.length, sizeof(struct iw_point) - IW_EV_POINT_OFF); -+#endif -+ memcpy(pcCur + IW_EV_POINT_LEN, prBss->rSsid.aucSsid, iwEvent.u.essid.length); -+ pcCur += iwEvent.len; -+ /* Frequency */ -+ iwEvent.cmd = SIOCGIWFREQ; -+ iwEvent.len = IW_EV_FREQ_LEN; -+ if ((pcCur + iwEvent.len) > pcEnd) -+ break; -+ iwEvent.u.freq.m = prBss->rConfiguration.u4DSConfig; -+ iwEvent.u.freq.e = 3; /* (in KHz) */ -+ iwEvent.u.freq.i = 0; -+ memcpy(pcCur, &iwEvent, IW_EV_FREQ_LEN); -+ pcCur += IW_EV_FREQ_LEN; -+ -+ /* Operation Mode */ -+ iwEvent.cmd = SIOCGIWMODE; -+ iwEvent.len = IW_EV_UINT_LEN; -+ if ((pcCur + iwEvent.len) > pcEnd) -+ break; -+ if (prBss->eOpMode == NET_TYPE_IBSS) -+ iwEvent.u.mode = IW_MODE_ADHOC; -+ else if (prBss->eOpMode == NET_TYPE_INFRA) -+ iwEvent.u.mode = IW_MODE_INFRA; -+ else -+ iwEvent.u.mode = IW_MODE_AUTO; -+ memcpy(pcCur, &iwEvent, IW_EV_UINT_LEN); -+ pcCur += IW_EV_UINT_LEN; -+ -+ /* Quality */ -+ iwEvent.cmd = IWEVQUAL; -+ iwEvent.len = IW_EV_QUAL_LEN; -+ if ((pcCur + iwEvent.len) > pcEnd) -+ break; -+ iwEvent.u.qual.qual = 0; /* Quality not available now */ -+ /* -100 < Rssi < -10, normalized by adding 0x100 */ -+ iwEvent.u.qual.level = 0x100 + prBss->rRssi; -+ iwEvent.u.qual.noise = 0; /* Noise not available now */ -+ iwEvent.u.qual.updated = IW_QUAL_QUAL_INVALID | IW_QUAL_LEVEL_UPDATED | IW_QUAL_NOISE_INVALID; -+ memcpy(pcCur, &iwEvent, IW_EV_QUAL_LEN); -+ pcCur += IW_EV_QUAL_LEN; -+ -+ /* Security Mode */ -+ iwEvent.cmd = SIOCGIWENCODE; -+ iwEvent.len = IW_EV_POINT_LEN; -+ if ((pcCur + iwEvent.len) > pcEnd) -+ break; -+ iwEvent.u.data.pointer = NULL; -+ iwEvent.u.data.flags = 0; -+ iwEvent.u.data.length = 0; -+ if (!prBss->u4Privacy) -+ iwEvent.u.data.flags |= IW_ENCODE_DISABLED; -+#if WIRELESS_EXT <= 18 -+ memcpy(pcCur, &iwEvent, IW_EV_POINT_LEN); -+#else -+ memcpy(pcCur, &iwEvent, IW_EV_LCP_LEN); -+ memcpy(pcCur + IW_EV_LCP_LEN, &iwEvent.u.data.length, sizeof(struct iw_point) - IW_EV_POINT_OFF); -+#endif -+ pcCur += IW_EV_POINT_LEN; -+ -+ /* rearrange rate information */ -+ u4BufIndex = sprintf(aucRatesBuf, "Rates (Mb/s):"); -+ u4HighestRate = 0; -+ for (j = 0; j < PARAM_MAX_LEN_RATES_EX; ++j) { -+ UINT_8 curRate = prBss->rSupportedRates[j] & 0x7F; -+ -+ if (curRate == 0) -+ break; -+ -+ if (curRate > u4HighestRate) -+ u4HighestRate = curRate; -+ -+ if (curRate == RATE_5_5M) -+ u4BufIndex += sprintf(aucRatesBuf + u4BufIndex, " 5.5"); -+ else -+ u4BufIndex += sprintf(aucRatesBuf + u4BufIndex, " %d", curRate / 2); -+#if DBG -+ if (u4BufIndex > sizeof(aucRatesBuf)) { -+ /* printk("rate info too long\n"); */ -+ break; -+ } -+#endif -+ } -+ /* Report Highest Rates */ -+ iwEvent.cmd = SIOCGIWRATE; -+ iwEvent.len = IW_EV_PARAM_LEN; -+ if ((pcCur + iwEvent.len) > pcEnd) -+ break; -+ iwEvent.u.bitrate.value = u4HighestRate * 500000; -+ iwEvent.u.bitrate.fixed = 0; -+ iwEvent.u.bitrate.disabled = 0; -+ iwEvent.u.bitrate.flags = 0; -+ memcpy(pcCur, &iwEvent, iwEvent.len); -+ pcCur += iwEvent.len; -+ -+#if WIRELESS_EXT >= 15 /* IWEVCUSTOM is available in WE-15 or above */ -+ /* Report Residual Rates */ -+ iwEvent.cmd = IWEVCUSTOM; -+ iwEvent.u.data.length = u4BufIndex; -+ iwEvent.len = IW_EV_POINT_LEN + iwEvent.u.data.length; -+ if ((pcCur + iwEvent.len) > pcEnd) -+ break; -+ iwEvent.u.data.flags = 0; -+#if WIRELESS_EXT <= 18 -+ memcpy(pcCur, &iwEvent, IW_EV_POINT_LEN); -+#else -+ memcpy(pcCur, &iwEvent, IW_EV_LCP_LEN); -+ memcpy(pcCur + IW_EV_LCP_LEN, &iwEvent.u.data.length, sizeof(struct iw_point) - IW_EV_POINT_OFF); -+#endif -+ memcpy(pcCur + IW_EV_POINT_LEN, aucRatesBuf, u4BufIndex); -+ pcCur += iwEvent.len; -+#endif /* WIRELESS_EXT >= 15 */ -+ -+ if (wextSrchDesiredWPAIE(&prBss->aucIEs[sizeof(PARAM_FIXED_IEs)], -+ prBss->u4IELength - sizeof(PARAM_FIXED_IEs), -+ 0xDD, (PUINT_8 *) &prDesiredIE)) { -+ iwEvent.cmd = IWEVGENIE; -+ iwEvent.u.data.flags = 1; -+ iwEvent.u.data.length = 2 + (__u16) prDesiredIE->ucLength; -+ iwEvent.len = IW_EV_POINT_LEN + iwEvent.u.data.length; -+ if ((pcCur + iwEvent.len) > pcEnd) -+ break; -+#if WIRELESS_EXT <= 18 -+ memcpy(pcCur, &iwEvent, IW_EV_POINT_LEN); -+#else -+ memcpy(pcCur, &iwEvent, IW_EV_LCP_LEN); -+ memcpy(pcCur + IW_EV_LCP_LEN, -+ &iwEvent.u.data.length, sizeof(struct iw_point) - IW_EV_POINT_OFF); -+#endif -+ memcpy(pcCur + IW_EV_POINT_LEN, prDesiredIE, 2 + prDesiredIE->ucLength); -+ pcCur += iwEvent.len; -+ } -+#if CFG_SUPPORT_WPS /* search WPS IE (0xDD, 221, OUI: 0x0050f204 ) */ -+ if (wextSrchDesiredWPSIE(&prBss->aucIEs[sizeof(PARAM_FIXED_IEs)], -+ prBss->u4IELength - sizeof(PARAM_FIXED_IEs), -+ 0xDD, (PUINT_8 *) &prDesiredIE)) { -+ iwEvent.cmd = IWEVGENIE; -+ iwEvent.u.data.flags = 1; -+ iwEvent.u.data.length = 2 + (__u16) prDesiredIE->ucLength; -+ iwEvent.len = IW_EV_POINT_LEN + iwEvent.u.data.length; -+ if ((pcCur + iwEvent.len) > pcEnd) -+ break; -+#if WIRELESS_EXT <= 18 -+ memcpy(pcCur, &iwEvent, IW_EV_POINT_LEN); -+#else -+ memcpy(pcCur, &iwEvent, IW_EV_LCP_LEN); -+ memcpy(pcCur + IW_EV_LCP_LEN, -+ &iwEvent.u.data.length, sizeof(struct iw_point) - IW_EV_POINT_OFF); -+#endif -+ memcpy(pcCur + IW_EV_POINT_LEN, prDesiredIE, 2 + prDesiredIE->ucLength); -+ pcCur += iwEvent.len; -+ } -+#endif -+ -+ /* Search RSN IE (0x30, 48). pBss->IEs starts from timestamp. */ -+ /* pBss->IEs starts from timestamp */ -+ if (wextSrchDesiredWPAIE(&prBss->aucIEs[sizeof(PARAM_FIXED_IEs)], -+ prBss->u4IELength - sizeof(PARAM_FIXED_IEs), -+ 0x30, (PUINT_8 *) &prDesiredIE)) { -+ -+ iwEvent.cmd = IWEVGENIE; -+ iwEvent.u.data.flags = 1; -+ iwEvent.u.data.length = 2 + (__u16) prDesiredIE->ucLength; -+ iwEvent.len = IW_EV_POINT_LEN + iwEvent.u.data.length; -+ if ((pcCur + iwEvent.len) > pcEnd) -+ break; -+#if WIRELESS_EXT <= 18 -+ memcpy(pcCur, &iwEvent, IW_EV_POINT_LEN); -+#else -+ memcpy(pcCur, &iwEvent, IW_EV_LCP_LEN); -+ memcpy(pcCur + IW_EV_LCP_LEN, -+ &iwEvent.u.data.length, sizeof(struct iw_point) - IW_EV_POINT_OFF); -+#endif -+ memcpy(pcCur + IW_EV_POINT_LEN, prDesiredIE, 2 + prDesiredIE->ucLength); -+ pcCur += iwEvent.len; -+ } -+#if CFG_SUPPORT_WAPI /* Android+ */ -+ if (wextSrchDesiredWAPIIE(&prBss->aucIEs[sizeof(PARAM_FIXED_IEs)], -+ prBss->u4IELength - sizeof(PARAM_FIXED_IEs), (PUINT_8 *) &prDesiredIE)) { -+ -+#if 0 -+ iwEvent.cmd = IWEVGENIE; -+ iwEvent.u.data.flags = 1; -+ iwEvent.u.data.length = 2 + (__u16) prDesiredIE->ucLength; -+ iwEvent.len = IW_EV_POINT_LEN + iwEvent.u.data.length; -+ if ((pcCur + iwEvent.len) > pcEnd) -+ break; -+#if WIRELESS_EXT <= 18 -+ memcpy(pcCur, &iwEvent, IW_EV_POINT_LEN); -+#else -+ memcpy(pcCur, &iwEvent, IW_EV_LCP_LEN); -+ memcpy(pcCur + IW_EV_LCP_LEN, -+ &iwEvent.u.data.length, sizeof(struct iw_point) - IW_EV_POINT_OFF); -+#endif -+ memcpy(pcCur + IW_EV_POINT_LEN, prDesiredIE, 2 + prDesiredIE->ucLength); -+ pcCur += iwEvent.len; -+#else -+ iwEvent.cmd = IWEVCUSTOM; -+ iwEvent.u.data.length = (2 + prDesiredIE->ucLength) * 2 + 8 /* wapi_ie= */; -+ iwEvent.len = IW_EV_POINT_LEN + iwEvent.u.data.length; -+ if ((pcCur + iwEvent.len) > pcEnd) -+ break; -+ iwEvent.u.data.flags = 1; -+ -+ memcpy(pcCur, &iwEvent, IW_EV_LCP_LEN); -+ memcpy(pcCur + IW_EV_LCP_LEN, -+ &iwEvent.u.data.length, sizeof(struct iw_point) - IW_EV_POINT_OFF); -+ -+ pcCur += (IW_EV_POINT_LEN); -+ -+ pcCur += sprintf(pcCur, "wapi_ie="); -+ -+ snprintf_hex(pcCur, pcEnd - pcCur, (UINT_8 *) prDesiredIE, prDesiredIE->ucLength + 2); -+ -+ pcCur += (2 + prDesiredIE->ucLength) * 2 /* iwEvent.len */; -+#endif -+ } -+#endif -+ /* Complete an entry. Update end of valid entry */ -+ pcValidEntryEnd = pcCur; -+ /* Extract next bss */ -+ prBss = (P_PARAM_BSSID_EX_T) ((char *)prBss + prBss->u4Length); -+ } -+ -+ /* Update valid data length for caller function and upper layer -+ * applications. -+ */ -+ prData->length = (pcValidEntryEnd - pcExtra); -+ /* printk(KERN_INFO "[wifi] buf:%d result:%ld\n", pData->length, u4BufLen); */ -+ -+ /* kalIndicateStatusAndComplete(prGlueInfo, WLAN_STATUS_SCAN_COMPLETE, NULL, 0); */ -+ -+error: -+ /* free local query buffer */ -+ if (prList) -+ kalMemFree(prList, VIR_MEM_TYPE, u4AllocBufLen); -+ -+ return ret; -+} /* wext_get_scan */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief To set desired network name ESSID. -+* -+* \param[in] prDev Net device requested. -+* \param[in] prIwrInfo NULL. -+* \param[in] prEssid Pointer of iw_point header. -+* \param[in] pcExtra Pointer to buffer srtoring essid string. -+* -+* \retval 0 If netif_carrier_ok. -+* \retval -E2BIG Essid string length is too big. -+* \retval -EINVAL pcExtra is null pointer. -+* \retval -EFAULT Driver fail to set new essid. -+* -+* \note If string length is ok, device will try connecting to the new network. -+*/ -+/*----------------------------------------------------------------------------*/ -+static int -+wext_set_essid(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwrInfo, IN struct iw_point *prEssid, IN char *pcExtra) -+{ -+ PARAM_SSID_T rNewSsid; -+ UINT_32 cipher; -+ ENUM_PARAM_ENCRYPTION_STATUS_T eEncStatus; -+ ENUM_PARAM_AUTH_MODE_T eAuthMode; -+ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ UINT_32 u4BufLen = 0; -+ -+ ASSERT(prNetDev); -+ ASSERT(prEssid); -+ ASSERT(pcExtra); -+ if (FALSE == GLUE_CHK_PR3(prNetDev, prEssid, pcExtra)) -+ return -EINVAL; -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); -+ -+ if (prEssid->length > IW_ESSID_MAX_SIZE) -+ return -E2BIG; -+ -+ /* set auth mode */ -+ if (prGlueInfo->rWpaInfo.u4WpaVersion == IW_AUTH_WPA_VERSION_DISABLED) { -+ eAuthMode = (prGlueInfo->rWpaInfo.u4AuthAlg == IW_AUTH_ALG_OPEN_SYSTEM) ? -+ AUTH_MODE_OPEN : AUTH_MODE_AUTO_SWITCH; -+ /* printk(KERN_INFO "IW_AUTH_WPA_VERSION_DISABLED->Param_AuthMode%s\n", */ -+ /* (eAuthMode == AUTH_MODE_OPEN) ? "Open" : "Shared"); */ -+ } else { -+ /* set auth mode */ -+ switch (prGlueInfo->rWpaInfo.u4KeyMgmt) { -+ case IW_AUTH_KEY_MGMT_802_1X: -+ eAuthMode = -+ (prGlueInfo->rWpaInfo.u4WpaVersion == IW_AUTH_WPA_VERSION_WPA) ? -+ AUTH_MODE_WPA : AUTH_MODE_WPA2; -+ /* printk("IW_AUTH_KEY_MGMT_802_1X->AUTH_MODE_WPA%s\n", */ -+ /* (eAuthMode == AUTH_MODE_WPA) ? "" : "2"); */ -+ break; -+ case IW_AUTH_KEY_MGMT_PSK: -+ eAuthMode = -+ (prGlueInfo->rWpaInfo.u4WpaVersion == IW_AUTH_WPA_VERSION_WPA) ? -+ AUTH_MODE_WPA_PSK : AUTH_MODE_WPA2_PSK; -+ /* printk("IW_AUTH_KEY_MGMT_PSK->AUTH_MODE_WPA%sPSK\n", */ -+ /* (eAuthMode == AUTH_MODE_WPA_PSK) ? "" : "2"); */ -+ break; -+#if CFG_SUPPORT_WAPI /* Android+ */ -+ case IW_AUTH_KEY_MGMT_WAPI_PSK: -+ break; -+ case IW_AUTH_KEY_MGMT_WAPI_CERT: -+ break; -+#endif -+ -+/* #if defined (IW_AUTH_KEY_MGMT_WPA_NONE) */ -+/* case IW_AUTH_KEY_MGMT_WPA_NONE: */ -+/* eAuthMode = AUTH_MODE_WPA_NONE; */ -+/* //printk("IW_AUTH_KEY_MGMT_WPA_NONE->AUTH_MODE_WPA_NONE\n"); */ -+/* break; */ -+/* #endif */ -+#if CFG_SUPPORT_802_11W -+ case IW_AUTH_KEY_MGMT_802_1X_SHA256: -+ eAuthMode = AUTH_MODE_WPA2; -+ break; -+ case IW_AUTH_KEY_MGMT_PSK_SHA256: -+ eAuthMode = AUTH_MODE_WPA2_PSK; -+ break; -+#endif -+ default: -+ /* printk(KERN_INFO DRV_NAME"strange IW_AUTH_KEY_MGMT : %ld set auto switch\n", */ -+ /* prGlueInfo->rWpaInfo.u4KeyMgmt); */ -+ eAuthMode = AUTH_MODE_AUTO_SWITCH; -+ break; -+ } -+ } -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetAuthMode, &eAuthMode, sizeof(eAuthMode), FALSE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ /* set encryption status */ -+ cipher = prGlueInfo->rWpaInfo.u4CipherGroup | prGlueInfo->rWpaInfo.u4CipherPairwise; -+ if (cipher & IW_AUTH_CIPHER_CCMP) { -+ /* printk("IW_AUTH_CIPHER_CCMP->ENUM_ENCRYPTION3_ENABLED\n"); */ -+ eEncStatus = ENUM_ENCRYPTION3_ENABLED; -+ } else if (cipher & IW_AUTH_CIPHER_TKIP) { -+ /* printk("IW_AUTH_CIPHER_TKIP->ENUM_ENCRYPTION2_ENABLED\n"); */ -+ eEncStatus = ENUM_ENCRYPTION2_ENABLED; -+ } else if (cipher & (IW_AUTH_CIPHER_WEP104 | IW_AUTH_CIPHER_WEP40)) { -+ /* printk("IW_AUTH_CIPHER_WEPx->ENUM_ENCRYPTION1_ENABLED\n"); */ -+ eEncStatus = ENUM_ENCRYPTION1_ENABLED; -+ } else if (cipher & IW_AUTH_CIPHER_NONE) { -+ /* printk("IW_AUTH_CIPHER_NONE->ENUM_ENCRYPTION_DISABLED\n"); */ -+ if (prGlueInfo->rWpaInfo.fgPrivacyInvoke) -+ eEncStatus = ENUM_ENCRYPTION1_ENABLED; -+ else -+ eEncStatus = ENUM_ENCRYPTION_DISABLED; -+ } else { -+ /* printk("unknown IW_AUTH_CIPHER->Param_EncryptionDisabled\n"); */ -+ eEncStatus = ENUM_ENCRYPTION_DISABLED; -+ } -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetEncryptionStatus, -+ &eEncStatus, sizeof(eEncStatus), FALSE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+#if WIRELESS_EXT < 21 -+ /* GeorgeKuo: a length error bug exists in (WE < 21) cases, kernel before -+ ** 2.6.19. Cut the trailing '\0'. -+ */ -+ rNewSsid.u4SsidLen = (prEssid->length) ? prEssid->length - 1 : 0; -+#else -+ rNewSsid.u4SsidLen = prEssid->length; -+#endif -+ kalMemCopy(rNewSsid.aucSsid, pcExtra, rNewSsid.u4SsidLen); -+ -+ /* -+ rNewSsid.aucSsid[rNewSsid.u4SsidLen] = '\0'; -+ printk("set ssid(%lu): %s\n", rNewSsid.u4SsidLen, rNewSsid.aucSsid); -+ */ -+ -+ if (kalIoctl(prGlueInfo, -+ wlanoidSetSsid, -+ (PVOID)&rNewSsid, -+ sizeof(PARAM_SSID_T), FALSE, FALSE, TRUE, FALSE, &u4BufLen) != WLAN_STATUS_SUCCESS) { -+ /* printk(KERN_WARNING "Fail to set ssid\n"); */ -+ return -EFAULT; -+ } -+ -+ return 0; -+} /* wext_set_essid */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief To get current network name ESSID. -+* -+* \param[in] prDev Net device requested. -+* \param[in] prIwrInfo NULL. -+* \param[in] prEssid Pointer to iw_point structure containing essid information. -+* \param[out] pcExtra Pointer to buffer srtoring essid string. -+* -+* \retval 0 If netif_carrier_ok. -+* \retval -ENOTCONN Otherwise. -+* -+* \note If netif_carrier_ok, network essid is stored in pcExtra. -+*/ -+/*----------------------------------------------------------------------------*/ -+/* static PARAM_SSID_T ssid; */ -+static int -+wext_get_essid(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwrInfo, IN struct iw_point *prEssid, OUT char *pcExtra) -+{ -+ /* PARAM_SSID_T ssid; */ -+ -+ P_PARAM_SSID_T prSsid; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ UINT_32 u4BufLen = 0; -+ -+ ASSERT(prNetDev); -+ ASSERT(prEssid); -+ ASSERT(pcExtra); -+ -+ if (FALSE == GLUE_CHK_PR3(prNetDev, prEssid, pcExtra)) -+ return -EINVAL; -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); -+ -+ /* if (!netif_carrier_ok(prNetDev)) { */ -+ /* return -ENOTCONN; */ -+ /* } */ -+ -+ prSsid = kalMemAlloc(sizeof(PARAM_SSID_T), VIR_MEM_TYPE); -+ -+ if (!prSsid) -+ return -ENOMEM; -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidQuerySsid, prSsid, sizeof(PARAM_SSID_T), TRUE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ if ((rStatus == WLAN_STATUS_SUCCESS) && (prSsid->u4SsidLen <= MAX_SSID_LEN)) { -+ kalMemCopy(pcExtra, prSsid->aucSsid, prSsid->u4SsidLen); -+ prEssid->length = prSsid->u4SsidLen; -+ prEssid->flags = 1; -+ } -+ -+ kalMemFree(prSsid, VIR_MEM_TYPE, sizeof(PARAM_SSID_T)); -+ -+ return 0; -+} /* wext_get_essid */ -+ -+#if 0 -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief To set tx desired bit rate. Three cases here -+* iwconfig wlan0 auto -> Set to origianl supported rate set. -+* iwconfig wlan0 18M -> Imply "fixed" case, set to 18Mbps as desired rate. -+* iwconfig wlan0 18M auto -> Set to auto rate lower and equal to 18Mbps -+* -+* \param[in] prNetDev Pointer to the net_device handler. -+* \param[in] prIwReqInfo Pointer to the Request Info. -+* \param[in] prRate Pointer to the Rate Parameter. -+* \param[in] pcExtra Pointer to the extra buffer. -+* -+* \retval 0 Update desired rate. -+* \retval -EINVAL Wrong parameter -+*/ -+/*----------------------------------------------------------------------------*/ -+int -+wext_set_rate(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwReqInfo, IN struct iw_param *prRate, IN char *pcExtra) -+{ -+ PARAM_RATES_EX aucSuppRate = { 0 }; -+ PARAM_RATES_EX aucNewRate = { 0 }; -+ UINT_32 u4NewRateLen = 0; -+ UINT_32 i; -+ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ UINT_32 u4BufLen = 0; -+ -+ ASSERT(prNetDev); -+ ASSERT(prRate); -+ if (FALSE == GLUE_CHK_PR2(prNetDev, prRate)) -+ return -EINVAL; -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); -+ -+ /* -+ printk("value = %d, fixed = %d, disable = %d, flags = %d\n", -+ prRate->value, prRate->fixed, prRate->disabled, prRate->flags); -+ */ -+ -+ rStatus = wlanQueryInformation(prGlueInfo->prAdapter, -+ wlanoidQuerySupportedRates, &aucSuppRate, sizeof(aucSuppRate), &u4BufLen); -+ -+ /* Case: AUTO */ -+ if (prRate->value < 0) { -+ if (prRate->fixed == 0) { -+ /* iwconfig wlan0 rate auto */ -+ -+ /* set full supported rate to device */ -+ /* printk("wlanoidQuerySupportedRates():u4BufLen = %ld\n", u4BufLen); */ -+ rStatus = wlanSetInformation(prGlueInfo->prAdapter, -+ wlanoidSetDesiredRates, -+ &aucSuppRate, sizeof(aucSuppRate), &u4BufLen); -+ return 0; -+ } -+ /* iwconfig wlan0 rate fixed */ -+ -+ /* fix rate to what? DO NOTHING */ -+ return -EINVAL; -+ } -+ -+ aucNewRate[0] = prRate->value / 500000; /* In unit of 500k */ -+ -+ for (i = 0; i < PARAM_MAX_LEN_RATES_EX; i++) { -+ /* check the given value is supported */ -+ if (aucSuppRate[i] == 0) -+ break; -+ -+ if (aucNewRate[0] == aucSuppRate[i]) { -+ u4NewRateLen = 1; -+ break; -+ } -+ } -+ -+ if (u4NewRateLen == 0) { -+ /* the given value is not supported */ -+ /* return error or use given rate as upper bound? */ -+ return -EINVAL; -+ } -+ -+ if (prRate->fixed == 0) { -+ /* add all rates lower than desired rate */ -+ for (i = 0; i < PARAM_MAX_LEN_RATES_EX; ++i) { -+ if (aucSuppRate[i] == 0) -+ break; -+ -+ if (aucSuppRate[i] < aucNewRate[0]) -+ aucNewRate[u4NewRateLen++] = aucSuppRate[i]; -+ } -+ } -+ -+ rStatus = wlanSetInformation(prGlueInfo->prAdapter, -+ wlanoidSetDesiredRates, &aucNewRate, sizeof(aucNewRate), &u4BufLen); -+ return 0; -+} /* wext_set_rate */ -+ -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief To get current tx bit rate. -+* -+* \param[in] prDev Net device requested. -+* \param[in] prIwrInfo NULL. -+* \param[out] prRate Pointer to iw_param structure to store current tx rate. -+* \param[in] pcExtra NULL. -+* -+* \retval 0 If netif_carrier_ok. -+* \retval -ENOTCONN Otherwise. -+* -+* \note If netif_carrier_ok, current tx rate is stored in pRate. -+*/ -+/*----------------------------------------------------------------------------*/ -+static int -+wext_get_rate(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwrInfo, OUT struct iw_param *prRate, IN char *pcExtra) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ UINT_32 u4BufLen = 0; -+ UINT_32 u4Rate = 0; -+ -+ ASSERT(prNetDev); -+ ASSERT(prRate); -+ if (FALSE == GLUE_CHK_PR2(prNetDev, prRate)) -+ return -EINVAL; -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); -+ -+ if (!netif_carrier_ok(prNetDev)) -+ return -ENOTCONN; -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidQueryLinkSpeed, &u4Rate, sizeof(u4Rate), TRUE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) -+ return -EFAULT; -+ -+ prRate->value = u4Rate * 100; /* u4Rate is in unit of 100bps */ -+ prRate->fixed = 0; -+ -+ return 0; -+} /* wext_get_rate */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief To set RTS/CTS theshold. -+* -+* \param[in] prDev Net device requested. -+* \param[in] prIwrInfo NULL. -+* \param[in] prRts Pointer to iw_param structure containing rts threshold. -+* \param[in] pcExtra NULL. -+* -+* \retval 0 For success. -+* \retval -EINVAL Given value is out of range. -+* -+* \note If given value is valid, device will follow the new setting. -+*/ -+/*----------------------------------------------------------------------------*/ -+static int -+wext_set_rts(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwrInfo, IN struct iw_param *prRts, IN char *pcExtra) -+{ -+ PARAM_RTS_THRESHOLD u4RtsThresh; -+ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ UINT_32 u4BufLen = 0; -+ -+ ASSERT(prNetDev); -+ ASSERT(prRts); -+ if (FALSE == GLUE_CHK_PR2(prNetDev, prRts)) -+ return -EINVAL; -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); -+ -+ if (prRts->disabled == 1) -+ u4RtsThresh = 2347; -+ else if (prRts->value < 0 || prRts->value > 2347) -+ return -EINVAL; -+ -+ u4RtsThresh = (PARAM_RTS_THRESHOLD) prRts->value; -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetRtsThreshold, -+ &u4RtsThresh, sizeof(u4RtsThresh), FALSE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ prRts->value = (typeof(prRts->value)) u4RtsThresh; -+ prRts->disabled = (prRts->value > 2347) ? 1 : 0; -+ prRts->fixed = 1; -+ -+ return 0; -+} /* wext_set_rts */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief To get RTS/CTS theshold. -+* -+* \param[in] prDev Net device requested. -+* \param[in] prIwrInfo NULL. -+* \param[out] prRts Pointer to iw_param structure containing rts threshold. -+* \param[in] pcExtra NULL. -+* -+* \retval 0 Success. -+* -+* \note RTS threshold is stored in pRts. -+*/ -+/*----------------------------------------------------------------------------*/ -+static int -+wext_get_rts(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwrInfo, OUT struct iw_param *prRts, IN char *pcExtra) -+{ -+ PARAM_RTS_THRESHOLD u4RtsThresh = 0; -+ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ UINT_32 u4BufLen = 0; -+ -+ ASSERT(prNetDev); -+ ASSERT(prRts); -+ if (FALSE == GLUE_CHK_PR2(prNetDev, prRts)) -+ return -EINVAL; -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidQueryRtsThreshold, -+ &u4RtsThresh, sizeof(u4RtsThresh), TRUE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ prRts->value = (typeof(prRts->value)) u4RtsThresh; -+ prRts->disabled = (prRts->value > 2347 || prRts->value < 0) ? 1 : 0; -+ prRts->fixed = 1; -+ -+ return 0; -+} /* wext_get_rts */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief To get fragmentation threshold. -+* -+* \param[in] prDev Net device requested. -+* \param[in] prIwrInfo NULL. -+* \param[out] prFrag Pointer to iw_param structure containing frag threshold. -+* \param[in] pcExtra NULL. -+* -+* \retval 0 Success. -+* -+* \note RTS threshold is stored in pFrag. Fragmentation is disabled. -+*/ -+/*----------------------------------------------------------------------------*/ -+static int -+wext_get_frag(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwrInfo, OUT struct iw_param *prFrag, IN char *pcExtra) -+{ -+ ASSERT(prFrag); -+ -+ prFrag->value = 2346; -+ prFrag->fixed = 1; -+ prFrag->disabled = 1; -+ return 0; -+} /* wext_get_frag */ -+ -+#if 1 -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief To set TX power, or enable/disable the radio. -+* -+* \param[in] prDev Net device requested. -+* \param[in] prIwrInfo NULL. -+* \param[in] prTxPow Pointer to iw_param structure containing tx power setting. -+* \param[in] pcExtra NULL. -+* -+* \retval 0 Success. -+* -+* \note Tx power is stored in pTxPow. iwconfig wlan0 txpow on/off are used -+* to enable/disable the radio. -+*/ -+/*----------------------------------------------------------------------------*/ -+ -+static int -+wext_set_txpow(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwrInfo, IN struct iw_param *prTxPow, IN char *pcExtra) -+{ -+ int ret = 0; -+ /* PARAM_DEVICE_POWER_STATE ePowerState; */ -+ ENUM_ACPI_STATE_T ePowerState; -+ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ UINT_32 u4BufLen = 0; -+ -+ ASSERT(prNetDev); -+ ASSERT(prTxPow); -+ if (FALSE == GLUE_CHK_PR2(prNetDev, prTxPow)) -+ return -EINVAL; -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); -+ -+ if (prTxPow->disabled) { -+ /* <1> disconnect */ -+ rStatus = kalIoctl(prGlueInfo, wlanoidSetDisassociate, NULL, 0, FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ if (rStatus != WLAN_STATUS_SUCCESS) -+ DBGLOG(REQ, ERROR, "######set disassoc failed\n"); -+ else -+ DBGLOG(REQ, TRACE, "######set assoc ok\n"); -+ /* <2> mark to power state flag */ -+ ePowerState = ACPI_STATE_D0; -+ DBGLOG(REQ, INFO, "set to acpi d3(0)\n"); -+ wlanSetAcpiState(prGlueInfo->prAdapter, ePowerState); -+ -+ } else { -+ ePowerState = ACPI_STATE_D0; -+ DBGLOG(REQ, INFO, "set to acpi d0\n"); -+ wlanSetAcpiState(prGlueInfo->prAdapter, ePowerState); -+ } -+ -+ prGlueInfo->ePowerState = ePowerState; -+ -+ return ret; -+} /* wext_set_txpow */ -+ -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief To get TX power. -+* -+* \param[in] prDev Net device requested. -+* \param[in] prIwrInfo NULL. -+* \param[out] prTxPow Pointer to iw_param structure containing tx power setting. -+* \param[in] pcExtra NULL. -+* -+* \retval 0 Success. -+* -+* \note Tx power is stored in pTxPow. -+*/ -+/*----------------------------------------------------------------------------*/ -+static int -+wext_get_txpow(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwrInfo, OUT struct iw_param *prTxPow, IN char *pcExtra) -+{ -+ /* PARAM_DEVICE_POWER_STATE ePowerState; */ -+ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ -+ ASSERT(prNetDev); -+ ASSERT(prTxPow); -+ if (FALSE == GLUE_CHK_PR2(prNetDev, prTxPow)) -+ return -EINVAL; -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); -+ -+ /* GeorgeKuo: wlanoidQueryAcpiDevicePowerState() reports capability, not -+ * current state. Use GLUE_INFO_T to store state. -+ */ -+ /* ePowerState = prGlueInfo->ePowerState; */ -+ -+ /* TxPow parameters: Fixed at relative 100% */ -+#if WIRELESS_EXT < 17 -+ prTxPow->flags = 0x0002; /* IW_TXPOW_RELATIVE */ -+#else -+ prTxPow->flags = IW_TXPOW_RELATIVE; -+#endif -+ prTxPow->value = 100; -+ prTxPow->fixed = 1; -+ /* prTxPow->disabled = (ePowerState != ParamDeviceStateD3) ? FALSE : TRUE; */ -+ prTxPow->disabled = TRUE; -+ -+ return 0; -+} /* wext_get_txpow */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief To get encryption cipher and key. -+* -+* \param[in] prDev Net device requested. -+* \param[in] prIwrInfo NULL. -+* \param[out] prEnc Pointer to iw_point structure containing securiry information. -+* \param[in] pcExtra Buffer to store key content. -+* -+* \retval 0 Success. -+* -+* \note Securiry information is stored in pEnc except key content. -+*/ -+/*----------------------------------------------------------------------------*/ -+static int -+wext_get_encode(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwrInfo, OUT struct iw_point *prEnc, IN char *pcExtra) -+{ -+#if 1 -+ /* ENUM_ENCRYPTION_STATUS_T eEncMode; */ -+ ENUM_PARAM_ENCRYPTION_STATUS_T eEncMode = ENUM_WEP_ENABLED; -+ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ UINT_32 u4BufLen = 0; -+ -+ ASSERT(prNetDev); -+ ASSERT(prEnc); -+ if (FALSE == GLUE_CHK_PR2(prNetDev, prEnc)) -+ return -EINVAL; -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidQueryEncryptionStatus, -+ &eEncMode, sizeof(eEncMode), TRUE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ switch (eEncMode) { -+ case ENUM_WEP_DISABLED: -+ prEnc->flags = IW_ENCODE_DISABLED; -+ break; -+ case ENUM_WEP_ENABLED: -+ prEnc->flags = IW_ENCODE_ENABLED; -+ break; -+ case ENUM_WEP_KEY_ABSENT: -+ prEnc->flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY; -+ break; -+ default: -+ prEnc->flags = IW_ENCODE_ENABLED; -+ break; -+ } -+ -+ /* Cipher, Key Content, Key ID can't be queried */ -+ prEnc->flags |= IW_ENCODE_NOKEY; -+#endif -+ return 0; -+} /* wext_get_encode */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief To set encryption cipher and key. -+* -+* \param[in] prDev Net device requested. -+* \param[in] prIwrInfo NULL. -+* \param[in] prEnc Pointer to iw_point structure containing securiry information. -+* \param[in] pcExtra Pointer to key string buffer. -+* -+* \retval 0 Success. -+* \retval -EINVAL Key ID error for WEP. -+* \retval -EFAULT Setting parameters to driver fail. -+* \retval -EOPNOTSUPP Key size not supported. -+* -+* \note Securiry information is stored in pEnc. -+*/ -+/*----------------------------------------------------------------------------*/ -+static UINT_8 wepBuf[48]; -+ -+static int -+wext_set_encode(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwrInfo, IN struct iw_point *prEnc, IN char *pcExtra) -+{ -+#if 1 -+ ENUM_PARAM_ENCRYPTION_STATUS_T eEncStatus; -+ ENUM_PARAM_AUTH_MODE_T eAuthMode; -+ /* UINT_8 wepBuf[48]; */ -+ P_PARAM_WEP_T prWepKey = (P_PARAM_WEP_T) wepBuf; -+ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ UINT_32 u4BufLen = 0; -+ -+ ASSERT(prNetDev); -+ ASSERT(prEnc); -+ ASSERT(pcExtra); -+ if (FALSE == GLUE_CHK_PR3(prNetDev, prEnc, pcExtra)) -+ return -EINVAL; -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); -+ -+ /* reset to default mode */ -+ prGlueInfo->rWpaInfo.u4WpaVersion = IW_AUTH_WPA_VERSION_DISABLED; -+ prGlueInfo->rWpaInfo.u4KeyMgmt = 0; -+ prGlueInfo->rWpaInfo.u4CipherPairwise = IW_AUTH_CIPHER_NONE; -+ prGlueInfo->rWpaInfo.u4CipherGroup = IW_AUTH_CIPHER_NONE; -+ prGlueInfo->rWpaInfo.u4AuthAlg = IW_AUTH_ALG_OPEN_SYSTEM; -+#if CFG_SUPPORT_802_11W -+ prGlueInfo->rWpaInfo.u4Mfp = IW_AUTH_MFP_DISABLED; -+#endif -+ -+ /* iwconfig wlan0 key off */ -+ if ((prEnc->flags & IW_ENCODE_MODE) == IW_ENCODE_DISABLED) { -+ eAuthMode = AUTH_MODE_OPEN; -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetAuthMode, -+ &eAuthMode, sizeof(eAuthMode), FALSE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ eEncStatus = ENUM_ENCRYPTION_DISABLED; -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetEncryptionStatus, -+ &eEncStatus, sizeof(eEncStatus), FALSE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ return 0; -+ } -+ -+ /* iwconfig wlan0 key 0123456789 */ -+ /* iwconfig wlan0 key s:abcde */ -+ /* iwconfig wlan0 key 0123456789 [1] */ -+ /* iwconfig wlan0 key 01234567890123456789012345 [1] */ -+ /* check key size for WEP */ -+ if (prEnc->length == 5 || prEnc->length == 13 || prEnc->length == 16) { -+ /* prepare PARAM_WEP key structure */ -+ prWepKey->u4KeyIndex = (prEnc->flags & IW_ENCODE_INDEX) ? (prEnc->flags & IW_ENCODE_INDEX) - 1 : 0; -+ if (prWepKey->u4KeyIndex > 3) { -+ /* key id is out of range */ -+ return -EINVAL; -+ } -+ prWepKey->u4KeyIndex |= 0x80000000; -+ prWepKey->u4Length = 12 + prEnc->length; -+ prWepKey->u4KeyLength = prEnc->length; -+ kalMemCopy(prWepKey->aucKeyMaterial, pcExtra, prEnc->length); -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetAddWep, -+ prWepKey, prWepKey->u4Length, FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ DBGLOG(REQ, ERROR, "wlanoidSetAddWep fail 0x%x\n", rStatus); -+ return -EFAULT; -+ } -+ -+ /* change to auto switch */ -+ prGlueInfo->rWpaInfo.u4AuthAlg = IW_AUTH_ALG_SHARED_KEY | IW_AUTH_ALG_OPEN_SYSTEM; -+ eAuthMode = AUTH_MODE_AUTO_SWITCH; -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetAuthMode, -+ &eAuthMode, sizeof(eAuthMode), FALSE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ /* printk(KERN_INFO DRV_NAME"wlanoidSetAuthMode fail 0x%lx\n", rStatus); */ -+ return -EFAULT; -+ } -+ -+ prGlueInfo->rWpaInfo.u4CipherPairwise = IW_AUTH_CIPHER_WEP104 | IW_AUTH_CIPHER_WEP40; -+ prGlueInfo->rWpaInfo.u4CipherGroup = IW_AUTH_CIPHER_WEP104 | IW_AUTH_CIPHER_WEP40; -+ -+ eEncStatus = ENUM_WEP_ENABLED; -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetEncryptionStatus, -+ &eEncStatus, -+ sizeof(ENUM_PARAM_ENCRYPTION_STATUS_T), FALSE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ /* printk(KERN_INFO DRV_NAME"wlanoidSetEncryptionStatus fail 0x%lx\n", rStatus); */ -+ return -EFAULT; -+ } -+ -+ return 0; -+ } -+#endif -+ return -EOPNOTSUPP; -+} /* wext_set_encode */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief To set power management. -+* -+* \param[in] prDev Net device requested. -+* \param[in] prIwrInfo NULL. -+* \param[in] prPower Pointer to iw_param structure containing tx power setting. -+* \param[in] pcExtra NULL. -+* -+* \retval 0 Success. -+* -+* \note New Power Management Mode is set to driver. -+*/ -+/*----------------------------------------------------------------------------*/ -+static int -+wext_set_power(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwrInfo, IN struct iw_param *prPower, IN char *pcExtra) -+{ -+#if 1 -+ -+ PARAM_POWER_MODE ePowerMode; -+ INT_32 i4PowerValue; -+ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ UINT_32 u4BufLen = 0; -+ -+ ASSERT(prNetDev); -+ ASSERT(prPower); -+ if (FALSE == GLUE_CHK_PR2(prNetDev, prPower)) -+ return -EINVAL; -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); -+ -+ /* printk(KERN_INFO "wext_set_power value(%d) disabled(%d) flag(0x%x)\n", */ -+ /* prPower->value, prPower->disabled, prPower->flags); */ -+ -+ if (prPower->disabled) { -+ ePowerMode = Param_PowerModeCAM; -+ } else { -+ i4PowerValue = prPower->value; -+#if WIRELESS_EXT < 21 -+ i4PowerValue /= 1000000; -+#endif -+ if (i4PowerValue == 0) { -+ ePowerMode = Param_PowerModeCAM; -+ } else if (i4PowerValue == 1) { -+ ePowerMode = Param_PowerModeMAX_PSP; -+ } else if (i4PowerValue == 2) { -+ ePowerMode = Param_PowerModeFast_PSP; -+ } else { -+ DBGLOG(REQ, ERROR, "%s(): unsupported power management mode value = %d.\n", -+ __func__, prPower->value); -+ -+ return -EINVAL; -+ } -+ } -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSet802dot11PowerSaveProfile, -+ &ePowerMode, sizeof(ePowerMode), FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ /* printk(KERN_INFO DRV_NAME"wlanoidSet802dot11PowerSaveProfile fail 0x%lx\n", rStatus); */ -+ return -EFAULT; -+ } -+#endif -+ return 0; -+} /* wext_set_power */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief To get power management. -+* -+* \param[in] prDev Net device requested. -+* \param[in] prIwrInfo NULL. -+* \param[out] prPower Pointer to iw_param structure containing tx power setting. -+* \param[in] pcExtra NULL. -+* -+* \retval 0 Success. -+* -+* \note Power management mode is stored in pTxPow->value. -+*/ -+/*----------------------------------------------------------------------------*/ -+static int -+wext_get_power(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwrInfo, OUT struct iw_param *prPower, IN char *pcExtra) -+{ -+ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ UINT_32 u4BufLen = 0; -+ PARAM_POWER_MODE ePowerMode = Param_PowerModeCAM; -+ -+ ASSERT(prNetDev); -+ ASSERT(prPower); -+ if (FALSE == GLUE_CHK_PR2(prNetDev, prPower)) -+ return -EINVAL; -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); -+ -+#if 0 -+#if defined(_HIF_SDIO) -+ rStatus = sdio_io_ctrl(prGlueInfo, -+ wlanoidQuery802dot11PowerSaveProfile, -+ &ePowerMode, sizeof(ePowerMode), TRUE, TRUE, &u4BufLen); -+#else -+ rStatus = wlanQueryInformation(prGlueInfo->prAdapter, -+ wlanoidQuery802dot11PowerSaveProfile, -+ &ePowerMode, sizeof(ePowerMode), &u4BufLen); -+#endif -+#else -+ rStatus = wlanQueryInformation(prGlueInfo->prAdapter, -+ wlanoidQuery802dot11PowerSaveProfile, -+ &ePowerMode, sizeof(ePowerMode), &u4BufLen); -+#endif -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) -+ return -EFAULT; -+ -+ prPower->value = 0; -+ prPower->disabled = 1; -+ -+ if (Param_PowerModeCAM == ePowerMode) { -+ prPower->value = 0; -+ prPower->disabled = 1; -+ } else if (Param_PowerModeMAX_PSP == ePowerMode) { -+ prPower->value = 1; -+ prPower->disabled = 0; -+ } else if (Param_PowerModeFast_PSP == ePowerMode) { -+ prPower->value = 2; -+ prPower->disabled = 0; -+ } -+ -+ prPower->flags = IW_POWER_PERIOD | IW_POWER_RELATIVE; -+#if WIRELESS_EXT < 21 -+ prPower->value *= 1000000; -+#endif -+ -+ /* printk(KERN_INFO "wext_get_power value(%d) disabled(%d) flag(0x%x)\n", */ -+ /* prPower->value, prPower->disabled, prPower->flags); */ -+ -+ return 0; -+} /* wext_get_power */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief To set authentication parameters. -+* -+* \param[in] prDev Net device requested. -+* \param[in] prIwrInfo NULL. -+* \param[in] rpAuth Pointer to iw_param structure containing authentication information. -+* \param[in] pcExtra Pointer to key string buffer. -+* -+* \retval 0 Success. -+* \retval -EINVAL Key ID error for WEP. -+* \retval -EFAULT Setting parameters to driver fail. -+* \retval -EOPNOTSUPP Key size not supported. -+* -+* \note Securiry information is stored in pEnc. -+*/ -+/*----------------------------------------------------------------------------*/ -+static int -+wext_set_auth(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwrInfo, IN struct iw_param *prAuth, IN char *pcExtra) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ -+ ASSERT(prNetDev); -+ ASSERT(prAuth); -+ if (FALSE == GLUE_CHK_PR2(prNetDev, prAuth)) -+ return -EINVAL; -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); -+ -+ /* Save information to glue info and process later when ssid is set. */ -+ switch (prAuth->flags & IW_AUTH_INDEX) { -+ case IW_AUTH_WPA_VERSION: -+#if CFG_SUPPORT_WAPI -+ if (wlanQueryWapiMode(prGlueInfo->prAdapter)) { -+ prGlueInfo->rWpaInfo.u4WpaVersion = IW_AUTH_WPA_VERSION_DISABLED; -+ prGlueInfo->rWpaInfo.u4AuthAlg = IW_AUTH_ALG_OPEN_SYSTEM; -+ } else { -+ prGlueInfo->rWpaInfo.u4WpaVersion = prAuth->value; -+ } -+#else -+ prGlueInfo->rWpaInfo.u4WpaVersion = prAuth->value; -+#endif -+ break; -+ -+ case IW_AUTH_CIPHER_PAIRWISE: -+ prGlueInfo->rWpaInfo.u4CipherPairwise = prAuth->value; -+ break; -+ -+ case IW_AUTH_CIPHER_GROUP: -+ prGlueInfo->rWpaInfo.u4CipherGroup = prAuth->value; -+ break; -+ -+ case IW_AUTH_KEY_MGMT: -+ prGlueInfo->rWpaInfo.u4KeyMgmt = prAuth->value; -+#if CFG_SUPPORT_WAPI -+ if (prGlueInfo->rWpaInfo.u4KeyMgmt == IW_AUTH_KEY_MGMT_WAPI_PSK || -+ prGlueInfo->rWpaInfo.u4KeyMgmt == IW_AUTH_KEY_MGMT_WAPI_CERT) { -+ UINT_32 u4BufLen; -+ WLAN_STATUS rStatus; -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetWapiMode, -+ &prAuth->value, sizeof(UINT_32), FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ DBGLOG(REQ, INFO, "IW_AUTH_WAPI_ENABLED :%d\n", prAuth->value); -+ } -+#endif -+ if (prGlueInfo->rWpaInfo.u4KeyMgmt == IW_AUTH_KEY_MGMT_WPS) -+ prGlueInfo->fgWpsActive = TRUE; -+ else -+ prGlueInfo->fgWpsActive = FALSE; -+ break; -+ -+ case IW_AUTH_80211_AUTH_ALG: -+ prGlueInfo->rWpaInfo.u4AuthAlg = prAuth->value; -+ break; -+ -+ case IW_AUTH_PRIVACY_INVOKED: -+ prGlueInfo->rWpaInfo.fgPrivacyInvoke = prAuth->value; -+ break; -+#if CFG_SUPPORT_802_11W -+ case IW_AUTH_MFP: -+ /* printk("wext_set_auth IW_AUTH_MFP=%d\n", prAuth->value); */ -+ prGlueInfo->rWpaInfo.u4Mfp = prAuth->value; -+ break; -+#endif -+#if CFG_SUPPORT_WAPI -+ case IW_AUTH_WAPI_ENABLED: -+ { -+ UINT_32 u4BufLen; -+ WLAN_STATUS rStatus; -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetWapiMode, -+ &prAuth->value, sizeof(UINT_32), FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ } -+ DBGLOG(REQ, INFO, "IW_AUTH_WAPI_ENABLED :%d\n", prAuth->value); -+ break; -+#endif -+ default: -+ /* -+ printk(KERN_INFO "[wifi] unsupported IW_AUTH_INDEX :%d\n", prAuth->flags); -+ */ -+ break; -+ } -+ return 0; -+} /* wext_set_auth */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief To set encryption cipher and key. -+* -+* \param[in] prDev Net device requested. -+* \param[in] prIwrInfo NULL. -+* \param[in] prEnc Pointer to iw_point structure containing securiry information. -+* \param[in] pcExtra Pointer to key string buffer. -+* -+* \retval 0 Success. -+* \retval -EINVAL Key ID error for WEP. -+* \retval -EFAULT Setting parameters to driver fail. -+* \retval -EOPNOTSUPP Key size not supported. -+* -+* \note Securiry information is stored in pEnc. -+*/ -+/*----------------------------------------------------------------------------*/ -+#if CFG_SUPPORT_WAPI -+UINT_8 keyStructBuf[320]; /* add/remove key shared buffer */ -+#else -+UINT_8 keyStructBuf[100]; /* add/remove key shared buffer */ -+#endif -+ -+static int -+wext_set_encode_ext(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwrInfo, IN struct iw_point *prEnc, IN char *pcExtra) -+{ -+ P_PARAM_REMOVE_KEY_T prRemoveKey = (P_PARAM_REMOVE_KEY_T) keyStructBuf; -+ P_PARAM_KEY_T prKey = (P_PARAM_KEY_T) keyStructBuf; -+ -+ P_PARAM_WEP_T prWepKey = (P_PARAM_WEP_T) wepBuf; -+ -+ struct iw_encode_ext *prIWEncExt = (struct iw_encode_ext *)pcExtra; -+ -+ ENUM_PARAM_ENCRYPTION_STATUS_T eEncStatus; -+ ENUM_PARAM_AUTH_MODE_T eAuthMode; -+ /* ENUM_PARAM_OP_MODE_T eOpMode = NET_TYPE_AUTO_SWITCH; */ -+ -+#if CFG_SUPPORT_WAPI -+ P_PARAM_WPI_KEY_T prWpiKey = (P_PARAM_WPI_KEY_T) keyStructBuf; -+#endif -+ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ UINT_32 u4BufLen = 0; -+ -+ ASSERT(prNetDev); -+ ASSERT(prEnc); -+ if (FALSE == GLUE_CHK_PR3(prNetDev, prEnc, pcExtra)) -+ return -EINVAL; -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); -+ -+ memset(keyStructBuf, 0, sizeof(keyStructBuf)); -+ -+#if CFG_SUPPORT_WAPI -+ if (prIWEncExt->alg == IW_ENCODE_ALG_SMS4) { -+ if (prEnc->flags & IW_ENCODE_DISABLED) { -+ /* printk(KERN_INFO "[wapi] IW_ENCODE_DISABLED\n"); */ -+ return 0; -+ } -+ /* KeyID */ -+ prWpiKey->ucKeyID = (prEnc->flags & IW_ENCODE_INDEX); -+ prWpiKey->ucKeyID--; -+ if (prWpiKey->ucKeyID > 1) { -+ /* key id is out of range */ -+ /* printk(KERN_INFO "[wapi] add key error: key_id invalid %d\n", prWpiKey->ucKeyID); */ -+ return -EINVAL; -+ } -+ -+ if (prIWEncExt->key_len != 32) { -+ /* key length not valid */ -+ /* printk(KERN_INFO "[wapi] add key error: key_len invalid %d\n", prIWEncExt->key_len); */ -+ return -EINVAL; -+ } -+ /* printk(KERN_INFO "[wapi] %d ext_flags %d\n", prEnc->flags, prIWEncExt->ext_flags); */ -+ -+ if (prIWEncExt->ext_flags & IW_ENCODE_EXT_GROUP_KEY) { -+ prWpiKey->eKeyType = ENUM_WPI_GROUP_KEY; -+ prWpiKey->eDirection = ENUM_WPI_RX; -+ } else if (prIWEncExt->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) { -+ prWpiKey->eKeyType = ENUM_WPI_PAIRWISE_KEY; -+ prWpiKey->eDirection = ENUM_WPI_RX_TX; -+ } -+ -+ /* PN */ -+ { -+ UINT_32 i; -+ -+ for (i = 0; i < IW_ENCODE_SEQ_MAX_SIZE; i++) -+ prWpiKey->aucPN[i] = prIWEncExt->tx_seq[i]; -+ for (i = 0; i < IW_ENCODE_SEQ_MAX_SIZE; i++) -+ prWpiKey->aucPN[IW_ENCODE_SEQ_MAX_SIZE + i] = prIWEncExt->rx_seq[i]; -+ } -+ -+ /* BSSID */ -+ memcpy(prWpiKey->aucAddrIndex, prIWEncExt->addr.sa_data, 6); -+ -+ memcpy(prWpiKey->aucWPIEK, prIWEncExt->key, 16); -+ prWpiKey->u4LenWPIEK = 16; -+ -+ memcpy(prWpiKey->aucWPICK, &prIWEncExt->key[16], 16); -+ prWpiKey->u4LenWPICK = 16; -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetWapiKey, -+ prWpiKey, sizeof(PARAM_WPI_KEY_T), FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ /* Do nothing */ -+ /* printk(KERN_INFO "[wapi] add key error:%lx\n", rStatus); */ -+ } -+ } else -+#endif -+ { -+ -+ if ((prEnc->flags & IW_ENCODE_MODE) == IW_ENCODE_DISABLED) { -+ prRemoveKey->u4Length = sizeof(*prRemoveKey); -+ memcpy(prRemoveKey->arBSSID, prIWEncExt->addr.sa_data, 6); -+ /* -+ printk("IW_ENCODE_DISABLED: ID:%d, Addr:[ %pM ]\n", -+ prRemoveKey->KeyIndex, prRemoveKey->BSSID); -+ */ -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetRemoveKey, -+ prRemoveKey, prRemoveKey->u4Length, FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) -+ DBGLOG(REQ, INFO, "remove key error:%x\n", rStatus); -+ return 0; -+ } -+ /* return 0; */ -+ /* printk ("alg %x\n", prIWEncExt->alg); */ -+ -+ switch (prIWEncExt->alg) { -+ case IW_ENCODE_ALG_NONE: -+ break; -+ case IW_ENCODE_ALG_WEP: -+ /* iwconfig wlan0 key 0123456789 */ -+ /* iwconfig wlan0 key s:abcde */ -+ /* iwconfig wlan0 key 0123456789 [1] */ -+ /* iwconfig wlan0 key 01234567890123456789012345 [1] */ -+ /* check key size for WEP */ -+ if (prIWEncExt->key_len == 5 || prIWEncExt->key_len == 13 || prIWEncExt->key_len == 16) { -+ /* prepare PARAM_WEP key structure */ -+ prWepKey->u4KeyIndex = (prEnc->flags & IW_ENCODE_INDEX) ? -+ (prEnc->flags & IW_ENCODE_INDEX) - 1 : 0; -+ if (prWepKey->u4KeyIndex > 3) { -+ /* key id is out of range */ -+ return -EINVAL; -+ } -+ prWepKey->u4KeyIndex |= 0x80000000; -+ prWepKey->u4Length = 12 + prIWEncExt->key_len; -+ prWepKey->u4KeyLength = prIWEncExt->key_len; -+ /* kalMemCopy(prWepKey->aucKeyMaterial, pcExtra, prIWEncExt->key_len); */ -+ kalMemCopy(prWepKey->aucKeyMaterial, prIWEncExt->key, prIWEncExt->key_len); -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetAddWep, -+ prWepKey, prWepKey->u4Length, FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ DBGLOG(REQ, ERROR, "wlanoidSetAddWep fail 0x%x\n", rStatus); -+ return -EFAULT; -+ } -+ -+ /* change to auto switch */ -+ prGlueInfo->rWpaInfo.u4AuthAlg = IW_AUTH_ALG_SHARED_KEY | IW_AUTH_ALG_OPEN_SYSTEM; -+ eAuthMode = AUTH_MODE_AUTO_SWITCH; -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetAuthMode, -+ &eAuthMode, -+ sizeof(eAuthMode), FALSE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ DBGLOG(REQ, ERROR, "wlanoidSetAuthMode fail 0x%x\n", rStatus); -+ return -EFAULT; -+ } -+ -+ prGlueInfo->rWpaInfo.u4CipherPairwise = IW_AUTH_CIPHER_WEP104 | IW_AUTH_CIPHER_WEP40; -+ prGlueInfo->rWpaInfo.u4CipherGroup = IW_AUTH_CIPHER_WEP104 | IW_AUTH_CIPHER_WEP40; -+ -+ eEncStatus = ENUM_WEP_ENABLED; -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetEncryptionStatus, -+ &eEncStatus, -+ sizeof(ENUM_PARAM_ENCRYPTION_STATUS_T), -+ FALSE, FALSE, FALSE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ DBGLOG(REQ, ERROR, "wlanoidSetEncryptionStatus fail 0x%x\n", rStatus); -+ return -EFAULT; -+ } -+ -+ } else { -+ DBGLOG(REQ, INFO, "key length %x\n", prIWEncExt->key_len); -+ DBGLOG(REQ, INFO, "key error\n"); -+ } -+ -+ break; -+ case IW_ENCODE_ALG_TKIP: -+ case IW_ENCODE_ALG_CCMP: -+#if CFG_SUPPORT_802_11W -+ case IW_ENCODE_ALG_AES_CMAC: -+#endif -+ { -+ -+ /* KeyID */ -+ prKey->u4KeyIndex = (prEnc->flags & IW_ENCODE_INDEX) ? -+ (prEnc->flags & IW_ENCODE_INDEX) - 1 : 0; -+#if CFG_SUPPORT_802_11W -+ if (prKey->u4KeyIndex > 5) { -+#else -+ if (prKey->u4KeyIndex > 3) { -+#endif -+ DBGLOG(REQ, ERROR, "key index error:0x%x\n", prKey->u4KeyIndex); -+ /* key id is out of range */ -+ return -EINVAL; -+ } -+ -+ /* bit(31) and bit(30) are shared by pKey and pRemoveKey */ -+ /* Tx Key Bit(31) */ -+ if (prIWEncExt->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) { -+ prKey->u4KeyIndex |= 0x1UL << 31; -+ /* Code style */ -+ } -+ /* Pairwise Key Bit(30) */ -+ if (prIWEncExt->ext_flags & IW_ENCODE_EXT_GROUP_KEY) { -+ /* Do nothing */ -+ /* group key */ -+ } else { -+ /* pairwise key */ -+ prKey->u4KeyIndex |= 0x1UL << 30; -+ } -+ } -+ /* Rx SC Bit(29) */ -+ if (prIWEncExt->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID) { -+ prKey->u4KeyIndex |= 0x1UL << 29; -+ memcpy(&prKey->rKeyRSC, prIWEncExt->rx_seq, IW_ENCODE_SEQ_MAX_SIZE); -+ } -+ -+ /* BSSID */ -+ memcpy(prKey->arBSSID, prIWEncExt->addr.sa_data, 6); -+ -+ /* switch tx/rx MIC key for sta */ -+ if (prIWEncExt->alg == IW_ENCODE_ALG_TKIP && prIWEncExt->key_len == 32) { -+ memcpy(prKey->aucKeyMaterial, prIWEncExt->key, 16); -+ memcpy(((PUINT_8) prKey->aucKeyMaterial) + 16, prIWEncExt->key + 24, 8); -+ memcpy((prKey->aucKeyMaterial) + 24, prIWEncExt->key + 16, 8); -+ } else { -+ memcpy(prKey->aucKeyMaterial, prIWEncExt->key, prIWEncExt->key_len); -+ } -+ -+ prKey->u4KeyLength = prIWEncExt->key_len; -+ prKey->u4Length = ((ULONG)&(((P_PARAM_KEY_T) 0)->aucKeyMaterial)) + prKey->u4KeyLength; -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetAddKey, -+ prKey, prKey->u4Length, FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ DBGLOG(REQ, ERROR, "add key error:%x\n", rStatus); -+ return -EFAULT; -+ } -+ break; -+ } -+ } -+ -+ return 0; -+} /* wext_set_encode_ext */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Set country code -+* -+* \param[in] prNetDev Net device requested. -+* \param[in] prData iwreq.u.data carries country code value. -+* -+* \retval 0 For success. -+* \retval -EEFAULT For fail. -+* -+* \note Country code is stored and channel list is updated based on current country domain. -+*/ -+/*----------------------------------------------------------------------------*/ -+static int wext_set_country(IN struct net_device *prNetDev, IN struct iw_point *prData) -+{ -+ P_GLUE_INFO_T prGlueInfo; -+ WLAN_STATUS rStatus; -+ UINT_32 u4BufLen; -+ UINT_8 aucCountry[2]; -+ -+ ASSERT(prNetDev); -+ -+ /* prData->pointer should be like "COUNTRY US", "COUNTRY EU" -+ * and "COUNTRY JP" -+ */ -+ if (FALSE == GLUE_CHK_PR2(prNetDev, prData) || !prData->pointer || prData->length < 10) -+ return -EINVAL; -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); -+ -+ aucCountry[0] = *((PUINT_8)prData->pointer + 8); -+ aucCountry[1] = *((PUINT_8)prData->pointer + 9); -+ -+ rStatus = kalIoctl(prGlueInfo, wlanoidSetCountryCode, &aucCountry[0], 2, FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ DBGLOG(REQ, ERROR, "Set country code error: %x\n", rStatus); -+ return -EFAULT; -+ } -+ -+ return 0; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief To report the iw private args table to user space. -+* -+* \param[in] prNetDev Net device requested. -+* \param[out] prData iwreq.u.data to carry the private args table. -+* -+* \retval 0 For success. -+* \retval -E2BIG For user's buffer size is too small. -+* \retval -EFAULT For fail. -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static int wext_get_priv(IN struct net_device *prNetDev, OUT struct iw_point *prData) -+{ -+ UINT_16 u2BufferSize = prData->length; -+ -+ /* Update our private args table size */ -+ prData->length = (__u16)sizeof(rIwPrivTable); -+ if (u2BufferSize < prData->length) -+ return -E2BIG; -+ -+ if (prData->length) { -+ if (copy_to_user(prData->pointer, rIwPrivTable, sizeof(rIwPrivTable))) -+ return -EFAULT; -+ } -+ -+ return 0; -+} /* wext_get_priv */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief ioctl() (Linux Wireless Extensions) routines -+* -+* \param[in] prDev Net device requested. -+* \param[in] ifr The ifreq structure for seeting the wireless extension. -+* \param[in] i4Cmd The wireless extension ioctl command. -+* -+* \retval zero On success. -+* \retval -EOPNOTSUPP If the cmd is not supported. -+* \retval -EFAULT If copy_to_user goes wrong. -+* \retval -EINVAL If any value's out of range. -+* -+* \note -+*/ -+/*----------------------------------------------------------------------------*/ -+int wext_support_ioctl(IN struct net_device *prDev, IN struct ifreq *prIfReq, IN int i4Cmd) -+{ -+ struct iwreq *iwr = (struct iwreq *)prIfReq; -+ struct iw_request_info rIwReqInfo; -+ int ret = 0; -+ char *prExtraBuf = NULL; -+ UINT_32 u4ExtraSize = 0; -+ P_GLUE_INFO_T prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ WLAN_STATUS rStatus; -+ UINT_32 u4BufLen; -+ P_PARAM_PMKID_T prPmkid; -+ -+ /* printk("%d CMD:0x%x\n", jiffies_to_msecs(jiffies), i4Cmd); */ -+ -+ rIwReqInfo.cmd = (__u16) i4Cmd; -+ rIwReqInfo.flags = 0; -+ -+ switch (i4Cmd) { -+ case SIOCGIWNAME: /* 0x8B01, get wireless protocol name */ -+ ret = wext_get_name(prDev, &rIwReqInfo, (char *)&iwr->u.name, NULL); -+ break; -+ -+ /* case SIOCSIWNWID: 0x8B02, deprecated */ -+ /* case SIOCGIWNWID: 0x8B03, deprecated */ -+ -+ case SIOCSIWFREQ: /* 0x8B04, set channel */ -+ ret = wext_set_freq(prDev, NULL, &iwr->u.freq, NULL); -+ break; -+ -+ case SIOCGIWFREQ: /* 0x8B05, get channel */ -+ ret = wext_get_freq(prDev, NULL, &iwr->u.freq, NULL); -+ break; -+ -+ case SIOCSIWMODE: /* 0x8B06, set operation mode */ -+ ret = wext_set_mode(prDev, NULL, &iwr->u.mode, NULL); -+ /* ret = 0; */ -+ break; -+ -+ case SIOCGIWMODE: /* 0x8B07, get operation mode */ -+ ret = wext_get_mode(prDev, NULL, &iwr->u.mode, NULL); -+ break; -+ -+ /* case SIOCSIWSENS: 0x8B08, unsupported */ -+ /* case SIOCGIWSENS: 0x8B09, unsupported */ -+ -+ /* case SIOCSIWRANGE: 0x8B0A, unused */ -+ case SIOCGIWRANGE: /* 0x8B0B, get range of parameters */ -+ if (iwr->u.data.pointer != NULL) { -+ /* Buffer size should be large enough */ -+ if (iwr->u.data.length < sizeof(struct iw_range)) { -+ ret = -E2BIG; -+ break; -+ } -+ -+ prExtraBuf = kalMemAlloc(sizeof(struct iw_range), VIR_MEM_TYPE); -+ if (!prExtraBuf) { -+ ret = -ENOMEM; -+ break; -+ } -+ -+ /* reset all fields */ -+ memset(prExtraBuf, 0, sizeof(struct iw_range)); -+ iwr->u.data.length = sizeof(struct iw_range); -+ -+ ret = wext_get_range(prDev, NULL, &iwr->u.data, prExtraBuf); -+ /* Push up to the caller */ -+ if (copy_to_user(iwr->u.data.pointer, prExtraBuf, iwr->u.data.length)) -+ ret = -EFAULT; -+ -+ kalMemFree(prExtraBuf, VIR_MEM_TYPE, sizeof(struct iw_range)); -+ prExtraBuf = NULL; -+ } else { -+ ret = -EINVAL; -+ } -+ break; -+ -+ case SIOCSIWPRIV: /* 0x8B0C, set country code */ -+ ret = wext_set_country(prDev, &iwr->u.data); -+ break; -+ -+ case SIOCGIWPRIV: /* 0x8B0D, get private args table */ -+ ret = wext_get_priv(prDev, &iwr->u.data); -+ break; -+ -+ /* case SIOCSIWSTATS: 0x8B0E, unused */ -+ /* case SIOCGIWSTATS: -+ get statistics, intercepted by wireless_process_ioctl() in wireless.c, -+ redirected to dev_iwstats(), dev->get_wireless_stats(). -+ */ -+ /* case SIOCSIWSPY: 0x8B10, unsupported */ -+ /* case SIOCGIWSPY: 0x8B11, unsupported */ -+ /* case SIOCSIWTHRSPY: 0x8B12, unsupported */ -+ /* case SIOCGIWTHRSPY: 0x8B13, unsupported */ -+ -+ case SIOCSIWAP: /* 0x8B14, set access point MAC addresses (BSSID) */ -+ if (iwr->u.ap_addr.sa_data[0] == 0 && -+ iwr->u.ap_addr.sa_data[1] == 0 && -+ iwr->u.ap_addr.sa_data[2] == 0 && -+ iwr->u.ap_addr.sa_data[3] == 0 && -+ iwr->u.ap_addr.sa_data[4] == 0 && iwr->u.ap_addr.sa_data[5] == 0) { -+ /* WPA Supplicant will set 000000000000 in -+ ** wpa_driver_wext_deinit(), do nothing here or disassoc again? -+ */ -+ ret = 0; -+ break; -+ } -+ ret = wext_set_ap(prDev, NULL, &iwr->u.ap_addr, NULL); -+ -+ break; -+ -+ case SIOCGIWAP: /* 0x8B15, get access point MAC addresses (BSSID) */ -+ ret = wext_get_ap(prDev, NULL, &iwr->u.ap_addr, NULL); -+ break; -+ -+ case SIOCSIWMLME: /* 0x8B16, request MLME operation */ -+ /* Fixed length structure */ -+ if (iwr->u.data.length != sizeof(struct iw_mlme)) { -+ DBGLOG(REQ, ERROR, "MLME buffer strange:%d\n", iwr->u.data.length); -+ ret = -EINVAL; -+ break; -+ } -+ -+ if (!iwr->u.data.pointer) { -+ ret = -EINVAL; -+ break; -+ } -+ -+ prExtraBuf = kalMemAlloc(sizeof(struct iw_mlme), VIR_MEM_TYPE); -+ if (!prExtraBuf) { -+ ret = -ENOMEM; -+ break; -+ } -+ -+ if (copy_from_user(prExtraBuf, iwr->u.data.pointer, sizeof(struct iw_mlme))) -+ ret = -EFAULT; -+ else -+ ret = wext_set_mlme(prDev, NULL, &(iwr->u.data), prExtraBuf); -+ -+ kalMemFree(prExtraBuf, VIR_MEM_TYPE, sizeof(struct iw_mlme)); -+ prExtraBuf = NULL; -+ break; -+ -+ /* case SIOCGIWAPLIST: 0x8B17, deprecated */ -+ case SIOCSIWSCAN: /* 0x8B18, scan request */ -+ if (iwr->u.data.pointer == NULL) -+ ret = wext_set_scan(prDev, NULL, NULL, NULL); -+#if WIRELESS_EXT > 17 -+ else if (iwr->u.data.length == sizeof(struct iw_scan_req)) { -+ prExtraBuf = kalMemAlloc(MAX_SSID_LEN, VIR_MEM_TYPE); -+ if (!prExtraBuf) { -+ ret = -ENOMEM; -+ break; -+ } -+ if (copy_from_user(prExtraBuf, ((struct iw_scan_req *)(iwr->u.data.pointer))->essid, -+ ((struct iw_scan_req *)(iwr->u.data.pointer))->essid_len)) { -+ ret = -EFAULT; -+ } else { -+ ret = wext_set_scan(prDev, NULL, (union iwreq_data *)&(iwr->u.data), prExtraBuf); -+ } -+ -+ kalMemFree(prExtraBuf, VIR_MEM_TYPE, MAX_SSID_LEN); -+ prExtraBuf = NULL; -+ } -+#endif -+ else -+ ret = -EINVAL; -+ break; -+#if 1 -+ case SIOCGIWSCAN: /* 0x8B19, get scan results */ -+ if (!iwr->u.data.pointer || !iwr->u.essid.pointer) { -+ ret = -EINVAL; -+ break; -+ } -+ -+ u4ExtraSize = iwr->u.data.length; -+ /* allocate the same size of kernel buffer to store scan results. */ -+ prExtraBuf = kalMemAlloc(u4ExtraSize, VIR_MEM_TYPE); -+ if (!prExtraBuf) { -+ ret = -ENOMEM; -+ break; -+ } -+ -+ /* iwr->u.data.length may be updated by wext_get_scan() */ -+ ret = wext_get_scan(prDev, NULL, &iwr->u.data, prExtraBuf); -+ if (ret != 0) { -+ if (ret == -E2BIG) -+ DBGLOG(REQ, WARN, "[wifi] wext_get_scan -E2BIG\n"); -+ } else { -+ /* check updated length is valid */ -+ ASSERT(iwr->u.data.length <= u4ExtraSize); -+ if (iwr->u.data.length > u4ExtraSize) { -+ DBGLOG(REQ, INFO, "Updated result length is larger than allocated (%d > %u)\n", -+ iwr->u.data.length, u4ExtraSize); -+ iwr->u.data.length = u4ExtraSize; -+ } -+ -+ if (copy_to_user(iwr->u.data.pointer, prExtraBuf, iwr->u.data.length)) -+ ret = -EFAULT; -+ } -+ -+ kalMemFree(prExtraBuf, VIR_MEM_TYPE, u4ExtraSize); -+ prExtraBuf = NULL; -+ -+ break; -+ -+#endif -+ -+#if 1 -+ case SIOCSIWESSID: /* 0x8B1A, set SSID (network name) */ -+ if (iwr->u.essid.length > IW_ESSID_MAX_SIZE) { -+ ret = -E2BIG; -+ break; -+ } -+ if (!iwr->u.essid.pointer) { -+ ret = -EINVAL; -+ break; -+ } -+ -+ prExtraBuf = kalMemAlloc(IW_ESSID_MAX_SIZE + 4, VIR_MEM_TYPE); -+ if (!prExtraBuf) { -+ ret = -ENOMEM; -+ break; -+ } -+ -+ if (copy_from_user(prExtraBuf, iwr->u.essid.pointer, iwr->u.essid.length)) { -+ ret = -EFAULT; -+ } else { -+ /* Add trailing '\0' for printk */ -+ /* prExtraBuf[iwr->u.essid.length] = 0; */ -+ /* printk(KERN_INFO "wext_set_essid: %s (%d)\n", prExtraBuf, iwr->u.essid.length); */ -+ ret = wext_set_essid(prDev, NULL, &iwr->u.essid, prExtraBuf); -+ /* printk ("set essid %d\n", ret); */ -+ } -+ -+ kalMemFree(prExtraBuf, VIR_MEM_TYPE, IW_ESSID_MAX_SIZE + 4); -+ prExtraBuf = NULL; -+ break; -+ -+#endif -+ -+ case SIOCGIWESSID: /* 0x8B1B, get SSID */ -+ if (!iwr->u.essid.pointer) { -+ ret = -EINVAL; -+ break; -+ } -+ -+ if (iwr->u.essid.length < IW_ESSID_MAX_SIZE) { -+ DBGLOG(REQ, ERROR, "[wifi] iwr->u.essid.length:%d too small\n", iwr->u.essid.length); -+ ret = -E2BIG; /* let caller try larger buffer */ -+ break; -+ } -+ -+ prExtraBuf = kalMemAlloc(IW_ESSID_MAX_SIZE, VIR_MEM_TYPE); -+ if (!prExtraBuf) { -+ ret = -ENOMEM; -+ break; -+ } -+ -+ /* iwr->u.essid.length is updated by wext_get_essid() */ -+ -+ ret = wext_get_essid(prDev, NULL, &iwr->u.essid, prExtraBuf); -+ if (ret == 0) { -+ if (copy_to_user(iwr->u.essid.pointer, prExtraBuf, iwr->u.essid.length)) -+ ret = -EFAULT; -+ } -+ -+ kalMemFree(prExtraBuf, VIR_MEM_TYPE, IW_ESSID_MAX_SIZE); -+ prExtraBuf = NULL; -+ -+ break; -+ -+ /* case SIOCSIWNICKN: 0x8B1C, not supported */ -+ /* case SIOCGIWNICKN: 0x8B1D, not supported */ -+ -+ case SIOCSIWRATE: /* 0x8B20, set default bit rate (bps) */ -+ /* ret = wext_set_rate(prDev, &rIwReqInfo, &iwr->u.bitrate, NULL); */ -+ break; -+ -+ case SIOCGIWRATE: /* 0x8B21, get current bit rate (bps) */ -+ ret = wext_get_rate(prDev, NULL, &iwr->u.bitrate, NULL); -+ break; -+ -+ case SIOCSIWRTS: /* 0x8B22, set rts/cts threshold */ -+ ret = wext_set_rts(prDev, NULL, &iwr->u.rts, NULL); -+ break; -+ -+ case SIOCGIWRTS: /* 0x8B23, get rts/cts threshold */ -+ ret = wext_get_rts(prDev, NULL, &iwr->u.rts, NULL); -+ break; -+ -+ /* case SIOCSIWFRAG: 0x8B24, unsupported */ -+ case SIOCGIWFRAG: /* 0x8B25, get frag threshold */ -+ ret = wext_get_frag(prDev, NULL, &iwr->u.frag, NULL); -+ break; -+ -+ case SIOCSIWTXPOW: /* 0x8B26, set relative tx power (in %) */ -+ ret = wext_set_txpow(prDev, NULL, &iwr->u.txpower, NULL); -+ break; -+ -+ case SIOCGIWTXPOW: /* 0x8B27, get relative tx power (in %) */ -+ ret = wext_get_txpow(prDev, NULL, &iwr->u.txpower, NULL); -+ break; -+ -+ /* case SIOCSIWRETRY: 0x8B28, unsupported */ -+ /* case SIOCGIWRETRY: 0x8B29, unsupported */ -+ -+#if 1 -+ case SIOCSIWENCODE: /* 0x8B2A, set encoding token & mode */ -+ /* Only DISABLED case has NULL pointer and length == 0 */ -+ if (iwr->u.encoding.pointer) { -+ if (iwr->u.encoding.length > 16) { -+ ret = -E2BIG; -+ break; -+ } -+ -+ u4ExtraSize = iwr->u.encoding.length; -+ prExtraBuf = kalMemAlloc(u4ExtraSize, VIR_MEM_TYPE); -+ if (!prExtraBuf) { -+ ret = -ENOMEM; -+ break; -+ } -+ -+ if (copy_from_user(prExtraBuf, iwr->u.encoding.pointer, iwr->u.encoding.length)) -+ ret = -EFAULT; -+ } else if (iwr->u.encoding.length != 0) { -+ ret = -EINVAL; -+ break; -+ } -+ -+ if (ret == 0) -+ ret = wext_set_encode(prDev, NULL, &iwr->u.encoding, prExtraBuf); -+ -+ if (prExtraBuf) { -+ kalMemFree(prExtraBuf, VIR_MEM_TYPE, u4ExtraSize); -+ prExtraBuf = NULL; -+ } -+ break; -+ -+ case SIOCGIWENCODE: /* 0x8B2B, get encoding token & mode */ -+ /* check pointer */ -+ ret = wext_get_encode(prDev, NULL, &iwr->u.encoding, NULL); -+ break; -+ -+ case SIOCSIWPOWER: /* 0x8B2C, set power management */ -+ ret = wext_set_power(prDev, NULL, &iwr->u.power, NULL); -+ break; -+ -+ case SIOCGIWPOWER: /* 0x8B2D, get power management */ -+ ret = wext_get_power(prDev, NULL, &iwr->u.power, NULL); -+ break; -+ -+#if WIRELESS_EXT > 17 -+ case SIOCSIWGENIE: /* 0x8B30, set gen ie */ -+ if (iwr->u.data.pointer == NULL) -+ break; -+ -+ if (0 /* wlanQueryWapiMode(prGlueInfo->prAdapter) */) -+ break; -+ -+ /* Fixed length structure */ -+#if CFG_SUPPORT_WAPI -+ if (iwr->u.data.length > 42 /* The max wapi ie buffer */) { -+ ret = -EINVAL; -+ break; -+ } -+#endif -+ u4ExtraSize = iwr->u.data.length; -+ if (u4ExtraSize == 0) -+ break; -+ -+ prExtraBuf = kalMemAlloc(u4ExtraSize, VIR_MEM_TYPE); -+ if (!prExtraBuf) { -+ ret = -ENOMEM; -+ break; -+ } -+ if (copy_from_user(prExtraBuf, iwr->u.data.pointer, iwr->u.data.length)) { -+ ret = -EFAULT; -+ } else { -+#if CFG_SUPPORT_WAPI -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetWapiAssocInfo, -+ prExtraBuf, -+ u4ExtraSize, FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ /* printk(KERN_INFO "[wapi] set wapi assoc info error:%lx\n", -+ rStatus); */ -+#endif -+#if CFG_SUPPORT_WPS2 -+ PUINT_8 prDesiredIE = NULL; -+ -+ if (wextSrchDesiredWPSIE(prExtraBuf, -+ u4ExtraSize, -+ 0xDD, (PUINT_8 *) &prDesiredIE)) { -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetWSCAssocInfo, -+ prDesiredIE, -+ IE_SIZE(prDesiredIE), -+ FALSE, -+ FALSE, TRUE, FALSE, &u4BufLen); -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ /* printk(KERN_INFO "[WSC] set WSC assoc info -+ error:%lx\n", rStatus); */ -+ } -+ } -+#endif -+#if CFG_SUPPORT_WAPI -+ } -+#endif -+ } -+ kalMemFree(prExtraBuf, VIR_MEM_TYPE, u4ExtraSize); -+ prExtraBuf = NULL; -+ break; -+ -+ case SIOCGIWGENIE: /* 0x8B31, get gen ie, unused */ -+ break; -+ -+#endif -+ -+ case SIOCSIWAUTH: /* 0x8B32, set auth mode params */ -+ ret = wext_set_auth(prDev, NULL, &iwr->u.param, NULL); -+ break; -+ -+ /* case SIOCGIWAUTH: 0x8B33, unused? */ -+ case SIOCSIWENCODEEXT: /* 0x8B34, set extended encoding token & mode */ -+ if (iwr->u.encoding.pointer) { -+ u4ExtraSize = iwr->u.encoding.length; -+ prExtraBuf = kalMemAlloc(u4ExtraSize, VIR_MEM_TYPE); -+ if (!prExtraBuf) { -+ ret = -ENOMEM; -+ break; -+ } -+ -+ if (copy_from_user(prExtraBuf, iwr->u.encoding.pointer, iwr->u.encoding.length)) -+ ret = -EFAULT; -+ } else if (iwr->u.encoding.length != 0) { -+ ret = -EINVAL; -+ break; -+ } -+ -+ if (ret == 0) -+ ret = wext_set_encode_ext(prDev, NULL, &iwr->u.encoding, prExtraBuf); -+ -+ if (prExtraBuf) { -+ kalMemFree(prExtraBuf, VIR_MEM_TYPE, u4ExtraSize); -+ prExtraBuf = NULL; -+ } -+ break; -+ -+ /* case SIOCGIWENCODEEXT: 0x8B35, unused? */ -+ -+ case SIOCSIWPMKSA: /* 0x8B36, pmksa cache operation */ -+#if 1 -+ if (iwr->u.data.pointer) { -+ /* Fixed length structure */ -+ if (iwr->u.data.length != sizeof(struct iw_pmksa)) { -+ ret = -EINVAL; -+ break; -+ } -+ -+ u4ExtraSize = sizeof(struct iw_pmksa); -+ prExtraBuf = kalMemAlloc(u4ExtraSize, VIR_MEM_TYPE); -+ if (!prExtraBuf) { -+ ret = -ENOMEM; -+ break; -+ } -+ -+ if (copy_from_user(prExtraBuf, iwr->u.data.pointer, sizeof(struct iw_pmksa))) { -+ ret = -EFAULT; -+ } else { -+ switch (((struct iw_pmksa *)prExtraBuf)->cmd) { -+ case IW_PMKSA_ADD: -+ /* -+ printk(KERN_INFO "IW_PMKSA_ADD [ %pM ]\n", -+ (((struct iw_pmksa *)pExtraBuf)->bssid.sa_data)); -+ */ -+ prPmkid = -+ (P_PARAM_PMKID_T) kalMemAlloc(8 + sizeof(PARAM_BSSID_INFO_T), -+ VIR_MEM_TYPE); -+ if (!prPmkid) { -+ DBGLOG(REQ, ERROR, "Can not alloc memory for IW_PMKSA_ADD\n"); -+ ret = -ENOMEM; -+ break; -+ } -+ -+ prPmkid->u4Length = 8 + sizeof(PARAM_BSSID_INFO_T); -+ prPmkid->u4BSSIDInfoCount = 1; -+ kalMemCopy(prPmkid->arBSSIDInfo->arBSSID, -+ ((struct iw_pmksa *)prExtraBuf)->bssid.sa_data, 6); -+ kalMemCopy(prPmkid->arBSSIDInfo->arPMKID, -+ ((struct iw_pmksa *)prExtraBuf)->pmkid, IW_PMKID_LEN); -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetPmkid, -+ prPmkid, -+ sizeof(PARAM_PMKID_T), -+ FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) -+ DBGLOG(REQ, ERROR, "add pmkid error:%x\n", rStatus); -+ kalMemFree(prPmkid, VIR_MEM_TYPE, 8 + sizeof(PARAM_BSSID_INFO_T)); -+ break; -+ case IW_PMKSA_REMOVE: -+ /* -+ printk(KERN_INFO "IW_PMKSA_REMOVE [ %pM ]\n", -+ (((struct iw_pmksa *)buf)->bssid.sa_data)); -+ */ -+ break; -+ case IW_PMKSA_FLUSH: -+ /* -+ printk(KERN_INFO "IW_PMKSA_FLUSH\n"); -+ */ -+ prPmkid = (P_PARAM_PMKID_T) kalMemAlloc(8, VIR_MEM_TYPE); -+ if (!prPmkid) { -+ DBGLOG(REQ, ERROR, -+ "Can not alloc memory for IW_PMKSA_FLUSH\n"); -+ ret = -ENOMEM; -+ break; -+ } -+ -+ prPmkid->u4Length = 8; -+ prPmkid->u4BSSIDInfoCount = 0; -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetPmkid, -+ prPmkid, -+ sizeof(PARAM_PMKID_T), -+ FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) -+ DBGLOG(REQ, ERROR, "flush pmkid error:%x\n", rStatus); -+ kalMemFree(prPmkid, VIR_MEM_TYPE, 8); -+ break; -+ default: -+ DBGLOG(REQ, WARN, "UNKNOWN iw_pmksa command:%d\n", -+ ((struct iw_pmksa *)prExtraBuf)->cmd); -+ ret = -EFAULT; -+ break; -+ } -+ } -+ -+ if (prExtraBuf) { -+ kalMemFree(prExtraBuf, VIR_MEM_TYPE, u4ExtraSize); -+ prExtraBuf = NULL; -+ } -+ } else if (iwr->u.data.length != 0) { -+ ret = -EINVAL; -+ break; -+ } -+#endif -+ break; -+ -+#endif -+ -+ default: -+ /* printk(KERN_NOTICE "unsupported IOCTL: 0x%x\n", i4Cmd); */ -+ ret = -EOPNOTSUPP; -+ break; -+ } -+ -+ /* printk("%ld CMD:0x%x ret:%d\n", jiffies_to_msecs(jiffies), i4Cmd, ret); */ -+ -+ return ret; -+} /* wext_support_ioctl */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief To send an event (RAW socket pacekt) to user process actively. -+* -+* \param[in] prGlueInfo Glue layer info. -+* \param[in] u4cmd Whcih event command we want to indicate to user process. -+* \param[in] pData Data buffer to be indicated. -+* \param[in] dataLen Available data size in pData. -+* -+* \return (none) -+* -+* \note Event is indicated to upper layer if cmd is supported and data is valid. -+* Using of kernel symbol wireless_send_event(), which is defined in -+* after WE-14 (2.4.20). -+*/ -+/*----------------------------------------------------------------------------*/ -+void -+wext_indicate_wext_event(IN P_GLUE_INFO_T prGlueInfo, -+ IN unsigned int u4Cmd, IN unsigned char *pucData, IN unsigned int u4dataLen) -+{ -+ union iwreq_data wrqu; -+ unsigned char *pucExtraInfo = NULL; -+#if WIRELESS_EXT >= 15 -+ unsigned char *pucDesiredIE = NULL; -+ unsigned char aucExtraInfoBuf[200]; -+#endif -+#if WIRELESS_EXT < 18 -+ int i; -+#endif -+ -+ memset(&wrqu, 0, sizeof(wrqu)); -+ -+ switch (u4Cmd) { -+ case SIOCGIWTXPOW: -+ memcpy(&wrqu.power, pucData, u4dataLen); -+ break; -+ case SIOCGIWSCAN: -+ complete_all(&prGlueInfo->rScanComp); -+ break; -+ -+ case SIOCGIWAP: -+ if (pucData) -+ ether_addr_copy((u8 *)&(wrqu.ap_addr.sa_data), pucData); -+ /*memcpy(&wrqu.ap_addr.sa_data, pucData, ETH_ALEN);*/ -+ else -+ memset(&wrqu.ap_addr.sa_data, 0, ETH_ALEN); -+ break; -+ -+ case IWEVASSOCREQIE: -+#if WIRELESS_EXT < 15 -+ /* under WE-15, no suitable Event can be used */ -+ goto skip_indicate_event; -+#else -+ /* do supplicant a favor, parse to the start of WPA/RSN IE */ -+ if (wextSrchDesiredWPAIE(pucData, u4dataLen, 0x30, &pucDesiredIE)) { -+ /* RSN IE found */ -+ /* Do nothing */ -+#if 0 -+ } else if (wextSrchDesiredWPSIE(pucData, u4dataLen, 0xDD, &pucDesiredIE)) { -+ /* WPS IE found */ -+ /* Do nothing */ -+#endif -+ } else if (wextSrchDesiredWPAIE(pucData, u4dataLen, 0xDD, &pucDesiredIE)) { -+ /* WPA IE found */ -+ /* Do nothing*/ -+#if CFG_SUPPORT_WAPI /* Android+ */ -+ } else if (wextSrchDesiredWAPIIE(pucData, u4dataLen, &pucDesiredIE)) { -+ /* WAPI IE found */ -+ /* printk("wextSrchDesiredWAPIIE!!\n"); */ -+#endif -+ } else { -+ /* no WPA/RSN IE found, skip this event */ -+ goto skip_indicate_event; -+ } -+#if WIRELESS_EXT < 18 -+ /* under WE-18, only IWEVCUSTOM can be used */ -+ u4Cmd = IWEVCUSTOM; -+ pucExtraInfo = aucExtraInfoBuf; -+ pucExtraInfo += sprintf(pucExtraInfo, "ASSOCINFO(ReqIEs="); -+ /* printk(KERN_DEBUG "assoc info buffer size needed:%d\n", infoElemLen * 2 + 17); */ -+ /* translate binary string to hex string, requirement of IWEVCUSTOM */ -+ for (i = 0; i < pucDesiredIE[1] + 2; ++i) -+ pucExtraInfo += sprintf(pucExtraInfo, "%02x", pucDesiredIE[i]); -+ pucExtraInfo = aucExtraInfoBuf; -+ wrqu.data.length = 17 + (pucDesiredIE[1] + 2) * 2; -+#else -+ /* IWEVASSOCREQIE, indicate binary string */ -+ pucExtraInfo = pucDesiredIE; -+ wrqu.data.length = pucDesiredIE[1] + 2; -+#endif -+#endif /* WIRELESS_EXT < 15 */ -+ break; -+ -+ case IWEVMICHAELMICFAILURE: -+#if WIRELESS_EXT < 15 -+ /* under WE-15, no suitable Event can be used */ -+ goto skip_indicate_event; -+#else -+ if (pucData) { -+ P_PARAM_AUTH_REQUEST_T pAuthReq = (P_PARAM_AUTH_REQUEST_T) pucData; -+ /* under WE-18, only IWEVCUSTOM can be used */ -+ u4Cmd = IWEVCUSTOM; -+ pucExtraInfo = aucExtraInfoBuf; -+ pucExtraInfo += sprintf(pucExtraInfo, "MLME-MICHAELMICFAILURE.indication "); -+ pucExtraInfo += sprintf(pucExtraInfo, -+ "%s", -+ (pAuthReq->u4Flags == PARAM_AUTH_REQUEST_GROUP_ERROR) ? -+ "groupcast " : "unicast "); -+ -+ wrqu.data.length = pucExtraInfo - aucExtraInfoBuf; -+ pucExtraInfo = aucExtraInfoBuf; -+ } -+#endif /* WIRELESS_EXT < 15 */ -+ break; -+ -+ case IWEVPMKIDCAND: -+ if (prGlueInfo->rWpaInfo.u4WpaVersion == IW_AUTH_WPA_VERSION_WPA2 && -+ prGlueInfo->rWpaInfo.u4KeyMgmt == IW_AUTH_KEY_MGMT_802_1X) { -+ -+ /* only used in WPA2 */ -+#if WIRELESS_EXT >= 18 -+ P_PARAM_PMKID_CANDIDATE_T prPmkidCand = (P_PARAM_PMKID_CANDIDATE_T) pucData; -+ -+ struct iw_pmkid_cand rPmkidCand; -+ -+ pucExtraInfo = aucExtraInfoBuf; -+ -+ rPmkidCand.flags = prPmkidCand->u4Flags; -+ rPmkidCand.index = 0; -+ rPmkidCand.bssid.sa_family = 0; -+ kalMemCopy(rPmkidCand.bssid.sa_data, prPmkidCand->arBSSID, 6); -+ -+ kalMemCopy(pucExtraInfo, (PUINT_8) &rPmkidCand, sizeof(struct iw_pmkid_cand)); -+ wrqu.data.length = sizeof(struct iw_pmkid_cand); -+ -+ /* pmkid canadidate list is supported after WE-18 */ -+ /* indicate struct iw_pmkid_cand */ -+#else -+ /* printk(KERN_INFO "IWEVPMKIDCAND event skipped, WE < 18\n"); */ -+ goto skip_indicate_event; -+#endif -+ } else { -+ /* printk(KERN_INFO "IWEVPMKIDCAND event skipped, NOT WPA2\n"); */ -+ goto skip_indicate_event; -+ } -+ break; -+ -+ case IWEVCUSTOM: -+ u4Cmd = IWEVCUSTOM; -+ pucExtraInfo = aucExtraInfoBuf; -+ kalMemCopy(pucExtraInfo, pucData, sizeof(PTA_IPC_T)); -+ wrqu.data.length = sizeof(PTA_IPC_T); -+ break; -+ -+ default: -+ /* printk(KERN_INFO "Unsupported wext event:%x\n", cmd); */ -+ goto skip_indicate_event; -+ } -+ -+ /* Send event to user space */ -+ wireless_send_event(prGlueInfo->prDevHandler, u4Cmd, &wrqu, pucExtraInfo); -+ -+skip_indicate_event: -+ return; -+} /* wext_indicate_wext_event */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief A method of struct net_device, to get the network interface statistical -+* information. -+* -+* Whenever an application needs to get statistics for the interface, this method -+* is called. This happens, for example, when ifconfig or netstat -i is run. -+* -+* \param[in] pDev Pointer to struct net_device. -+* -+* \return net_device_stats buffer pointer. -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+struct iw_statistics *wext_get_wireless_stats(struct net_device *prDev) -+{ -+ -+ WLAN_STATUS rStatus = WLAN_STATUS_FAILURE; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ struct iw_statistics *pStats = NULL; -+ INT_32 i4Rssi; -+ UINT_32 bufLen = 0; -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ ASSERT(prGlueInfo); -+ if (!prGlueInfo) -+ goto stat_out; -+ -+ pStats = (struct iw_statistics *)(&(prGlueInfo->rIwStats)); -+ -+ if (!prDev || !netif_carrier_ok(prDev)) { -+ /* network not connected */ -+ goto stat_out; -+ } -+ -+ rStatus = kalIoctl(prGlueInfo, wlanoidQueryRssi, &i4Rssi, sizeof(i4Rssi), TRUE, TRUE, TRUE, FALSE, &bufLen); -+ -+stat_out: -+ return pStats; -+} /* wlan_get_wireless_stats */ -+ -+ -+#endif /* WIRELESS_EXT */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_wext_priv.c b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_wext_priv.c -new file mode 100644 -index 000000000000..2b6c3df84594 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_wext_priv.c -@@ -0,0 +1,3142 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux/gl_wext_priv.c#4 -+*/ -+ -+/*! \file gl_wext_priv.c -+ \brief This file includes private ioctl support. -+*/ -+ -+/* -+** Log: gl_wext_priv.c -+ * -+ * 07 17 2012 yuche.tsai -+ * NULL -+ * Let netdev bring up. -+ * -+ * 06 13 2012 yuche.tsai -+ * NULL -+ * Update maintrunk driver. -+ * Add support for driver compose assoc request frame. -+ * -+ * 03 20 2012 wh.su -+ * [WCXRP00001153] [MT6620 Wi-Fi][Driver] Adding the get_ch_list and set_tx_power proto type function -+ * [WCXRP00001202] [MT6628 Wi-Fi][FW] Adding the New PN init code -+ * use return to avoid the ioctl return not supported -+ * -+ * 03 02 2012 terry.wu -+ * NULL -+ * Snc CFG80211 modification for ICS migration from branch 2.2. -+ * -+ * 01 16 2012 wh.su -+ * [WCXRP00001170] [MT6620 Wi-Fi][Driver] Adding the related code for set/get band ioctl -+ * Adding the template code for set / get band IOCTL (with ICS supplicant_6).. -+ * -+ * 01 05 2012 wh.su -+ * [WCXRP00001153] [MT6620 Wi-Fi][Driver] Adding the get_ch_list and set_tx_power proto type function -+ * Adding the related ioctl / wlan oid function to set the Tx power cfg. -+ * -+ * 01 02 2012 wh.su -+ * [WCXRP00001153] [MT6620 Wi-Fi][Driver] Adding the get_ch_list and set_tx_power proto type function -+ * Adding the proto type function for set_int set_tx_power and get int get_ch_list. -+ * -+ * 11 10 2011 cp.wu -+ * [WCXRP00001098] [MT6620 Wi-Fi][Driver] Replace printk by DBG LOG macros in linux porting layer -+ * 1. eliminaite direct calls to printk in porting layer. -+ * 2. replaced by DBGLOG, which would be XLOG on ALPS platforms. -+ * -+ * 11 02 2011 chinghwa.yu -+ * [WCXRP00000063] Update BCM CoEx design and settings -+ * Fixed typo. -+ * -+ * 09 20 2011 chinglan.wang -+ * [WCXRP00000989] [WiFi Direct] [Driver] Add a new io control API to start the formation for the sigma test. -+ * . -+ * -+ * 07 28 2011 chinghwa.yu -+ * [WCXRP00000063] Update BCM CoEx design and settings -+ * Add BWCS cmd and event. -+ * -+ * 07 18 2011 chinghwa.yu -+ * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm -+ * Add CMD/Event for RDD and BWCS. -+ * -+ * 03 17 2011 chinglan.wang -+ * [WCXRP00000570] [MT6620 Wi-Fi][Driver] Add Wi-Fi Protected Setup v2.0 feature -+ * . -+ * -+ * 03 07 2011 terry.wu -+ * [WCXRP00000521] [MT6620 Wi-Fi][Driver] Remove non-standard debug message -+ * Toggle non-standard debug messages to comments. -+ * -+ * 01 27 2011 cm.chang -+ * [WCXRP00000402] [MT6620 Wi-Fi][Driver] Enable MCR read/write by iwpriv by default -+ * . -+ * -+ * 01 26 2011 wh.su -+ * [WCXRP00000396] [MT6620 Wi-Fi][Driver] Support Sw Ctrl ioctl at linux -+ * adding the SW cmd ioctl support, use set/get structure ioctl. -+ * -+ * 01 20 2011 eddie.chen -+ * [WCXRP00000374] [MT6620 Wi-Fi][DRV] SW debug control -+ * Adjust OID order. -+ * -+ * 01 20 2011 eddie.chen -+ * [WCXRP00000374] [MT6620 Wi-Fi][DRV] SW debug control -+ * Add Oid for sw control debug command -+ * -+ * 01 07 2011 cm.chang -+ * [WCXRP00000336] [MT6620 Wi-Fi][Driver] Add test mode commands in normal phone operation -+ * Add a new compiling option to control if MCR read/write is permitted -+ * -+ * 12 31 2010 cm.chang -+ * [WCXRP00000336] [MT6620 Wi-Fi][Driver] Add test mode commands in normal phone operation -+ * Add some iwpriv commands to support test mode operation -+ * -+ * 12 15 2010 george.huang -+ * [WCXRP00000152] [MT6620 Wi-Fi] AP mode power saving function -+ * Support set PS profile and set WMM-PS related iwpriv. -+ * -+ * 11 08 2010 wh.su -+ * [WCXRP00000171] [MT6620 Wi-Fi][Driver] Add message check code same behavior as mt5921 -+ * add the message check code from mt5921. -+ * -+ * 10 18 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check -+ * [WCXRP00000086] [MT6620 Wi-Fi][Driver] The mac address is all zero at android -+ * complete implementation of Android NVRAM access -+ * -+ * 09 24 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check -+ * correct typo for NVRAM access. -+ * -+ * 09 23 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check -+ * add skeleton for NVRAM integration -+ * -+ * 08 04 2010 cp.wu -+ * NULL -+ * revert changelist #15371, efuse read/write access will be done by RF test approach -+ * -+ * 08 04 2010 cp.wu -+ * NULL -+ * add OID definitions for EFUSE read/write access. -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 06 01 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * enable OID_CUSTOM_MTK_WIFI_TEST for RFTest & META tool -+ * -+ * 05 29 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * fix private ioctl for rftest -+ * -+ * 04 21 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * add for private ioctl support -+** \main\maintrunk.MT5921\32 2009-10-08 10:33:25 GMT mtk01090 -+** Avoid accessing private data of net_device directly. Replace with netdev_priv(). Add more checking for input -+** parameters and pointers. -+** \main\maintrunk.MT5921\31 2009-09-29 16:46:21 GMT mtk01090 -+** Remove unused functions -+** \main\maintrunk.MT5921\30 2009-09-29 14:46:47 GMT mtk01090 -+** Fix compile warning -+** \main\maintrunk.MT5921\29 2009-09-29 14:28:48 GMT mtk01090 -+** Fix compile warning -+** \main\maintrunk.MT5921\28 2009-09-28 22:21:38 GMT mtk01090 -+** Refine lines to suppress compile warning -+** \main\maintrunk.MT5921\27 2009-09-28 20:19:14 GMT mtk01090 -+** Add private ioctl to carry OID structures. Restructure public/private ioctl interfaces to Linux kernel. -+** \main\maintrunk.MT5921\26 2009-08-18 22:56:53 GMT mtk01090 -+** Add Linux SDIO (with mmc core) support. -+** Add Linux 2.6.21, 2.6.25, 2.6.26. -+** Fix compile warning in Linux. -+** \main\maintrunk.MT5921\25 2009-05-07 22:26:15 GMT mtk01089 -+** Add mandatory and private IO control for Linux BWCS -+** \main\maintrunk.MT5921\24 2009-04-29 10:07:05 GMT mtk01088 -+** fixed the compiling error at linux -+** \main\maintrunk.MT5921\23 2009-04-24 09:09:45 GMT mtk01088 -+** mark the code not used at linux supplicant v0.6.7 -+** \main\maintrunk.MT5921\22 2008-11-24 21:03:51 GMT mtk01425 -+** 1. Add PTA_ENABLED flag -+** \main\maintrunk.MT5921\21 2008-08-29 14:55:59 GMT mtk01088 -+** adjust the code for meet the coding style, and add assert check -+** \main\maintrunk.MT5921\20 2008-07-16 15:23:20 GMT mtk01104 -+** Support GPIO2 mode -+** \main\maintrunk.MT5921\19 2008-07-15 17:43:11 GMT mtk01084 -+** modify variable name -+** \main\maintrunk.MT5921\18 2008-07-14 14:37:58 GMT mtk01104 -+** Add exception handle about length in function priv_set_struct() -+** \main\maintrunk.MT5921\17 2008-07-14 13:55:32 GMT mtk01104 -+** Support PRIV_CMD_BT_COEXIST -+** \main\maintrunk.MT5921\16 2008-07-09 00:20:15 GMT mtk01461 -+** Add priv oid to support WMM_PS_TEST -+** \main\maintrunk.MT5921\15 2008-06-02 11:15:22 GMT mtk01461 -+** Update after wlanoidSetPowerMode changed -+** \main\maintrunk.MT5921\14 2008-05-30 19:31:07 GMT mtk01461 -+** Add IOCTL for Power Mode -+** \main\maintrunk.MT5921\13 2008-05-30 18:57:15 GMT mtk01461 -+** Not use wlanoidSetCSUMOffloadForLinux() -+** \main\maintrunk.MT5921\12 2008-05-30 15:13:18 GMT mtk01084 -+** rename wlanoid -+** \main\maintrunk.MT5921\11 2008-05-29 14:16:31 GMT mtk01084 -+** rename for wlanoidSetBeaconIntervalForLinux -+** \main\maintrunk.MT5921\10 2008-04-17 23:06:37 GMT mtk01461 -+** Add iwpriv support for AdHocMode setting -+** \main\maintrunk.MT5921\9 2008-03-31 21:00:55 GMT mtk01461 -+** Add priv IOCTL for VOIP setting -+** \main\maintrunk.MT5921\8 2008-03-31 13:49:43 GMT mtk01461 -+** Add priv ioctl to turn on / off roaming -+** \main\maintrunk.MT5921\7 2008-03-26 15:35:14 GMT mtk01461 -+** Add CSUM offload priv ioctl for Linux -+** \main\maintrunk.MT5921\6 2008-03-11 14:50:59 GMT mtk01461 -+** Unify priv ioctl -+** \main\maintrunk.MT5921\5 2007-11-06 19:32:30 GMT mtk01088 -+** add WPS code -+** \main\maintrunk.MT5921\4 2007-10-30 12:01:39 GMT MTK01425 -+** 1. Update wlanQueryInformation and wlanSetInformation -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "precomp.h" -+ -+#include "gl_os.h" -+#include "gl_wext_priv.h" -+#if CFG_SUPPORT_WAPI -+#include "gl_sec.h" -+#endif -+#if CFG_ENABLE_WIFI_DIRECT -+#include "gl_p2p_os.h" -+#endif -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+#define NUM_SUPPORTED_OIDS (sizeof(arWlanOidReqTable) / sizeof(WLAN_REQ_ENTRY)) -+#define CMD_START "START" -+#define CMD_STOP "STOP" -+#define CMD_SCAN_ACTIVE "SCAN-ACTIVE" -+#define CMD_SCAN_PASSIVE "SCAN-PASSIVE" -+#define CMD_RSSI "RSSI" -+#define CMD_LINKSPEED "LINKSPEED" -+#define CMD_RXFILTER_START "RXFILTER-START" -+#define CMD_RXFILTER_STOP "RXFILTER-STOP" -+#define CMD_RXFILTER_ADD "RXFILTER-ADD" -+#define CMD_RXFILTER_REMOVE "RXFILTER-REMOVE" -+#define CMD_BTCOEXSCAN_START "BTCOEXSCAN-START" -+#define CMD_BTCOEXSCAN_STOP "BTCOEXSCAN-STOP" -+#define CMD_BTCOEXMODE "BTCOEXMODE" -+#define CMD_SETSUSPENDOPT "SETSUSPENDOPT" -+#define CMD_SETSUSPENDMODE "SETSUSPENDMODE" -+#define CMD_P2P_DEV_ADDR "P2P_DEV_ADDR" -+#define CMD_SETFWPATH "SETFWPATH" -+#define CMD_SETBAND "SETBAND" -+#define CMD_GETBAND "GETBAND" -+#define CMD_COUNTRY "COUNTRY" -+#define CMD_P2P_SET_NOA "P2P_SET_NOA" -+#define CMD_P2P_GET_NOA "P2P_GET_NOA" -+#define CMD_P2P_SET_PS "P2P_SET_PS" -+#define CMD_SET_AP_WPS_P2P_IE "SET_AP_WPS_P2P_IE" -+#define CMD_SETROAMMODE "SETROAMMODE" -+#define CMD_MIRACAST "MIRACAST" -+ -+#define CMD_PNOSSIDCLR_SET "PNOSSIDCLR" -+#define CMD_PNOSETUP_SET "PNOSETUP " -+#define CMD_PNOENABLE_SET "PNOFORCE" -+#define CMD_PNODEBUG_SET "PNODEBUG" -+#define CMD_WLS_BATCHING "WLS_BATCHING" -+ -+#define CMD_OKC_SET_PMK "SET_PMK" -+#define CMD_OKC_ENABLE "OKC_ENABLE" -+ -+/* miracast related definition */ -+#define MIRACAST_MODE_OFF 0 -+#define MIRACAST_MODE_SOURCE 1 -+#define MIRACAST_MODE_SINK 2 -+ -+#ifndef MIRACAST_AMPDU_SIZE -+#define MIRACAST_AMPDU_SIZE 8 -+#endif -+ -+#ifndef MIRACAST_MCHAN_ALGO -+#define MIRACAST_MCHAN_ALGO 1 -+#endif -+ -+#ifndef MIRACAST_MCHAN_BW -+#define MIRACAST_MCHAN_BW 25 -+#endif -+ -+#define CMD_BAND_AUTO 0 -+#define CMD_BAND_5G 1 -+#define CMD_BAND_2G 2 -+#define CMD_BAND_ALL 3 -+ -+/* Mediatek private command */ -+ -+#define CMD_SET_SW_CTRL "SET_SW_CTRL" -+#define CMD_GET_SW_CTRL "GET_SW_CTRL" -+#define CMD_SET_CFG "SET_CFG" -+#define CMD_GET_CFG "GET_CFG" -+#define CMD_SET_CHIP "SET_CHIP" -+#define CMD_GET_CHIP "GET_CHIP" -+#define CMD_SET_DBG_LEVEL "SET_DBG_LEVEL" -+#define CMD_GET_DBG_LEVEL "GET_DBG_LEVEL" -+#define PRIV_CMD_SIZE 512 -+ -+static UINT_32 g_ucMiracastMode = MIRACAST_MODE_OFF; -+ -+typedef struct cmd_tlv { -+ char prefix; -+ char version; -+ char subver; -+ char reserved; -+} cmd_tlv_t; -+ -+typedef struct priv_driver_cmd_s { -+ char buf[PRIV_CMD_SIZE]; -+ int used_len; -+ int total_len; -+} priv_driver_cmd_t; -+ -+#if CFG_SUPPORT_BATCH_SCAN -+#define CMD_BATCH_SET "WLS_BATCHING SET" -+#define CMD_BATCH_GET "WLS_BATCHING GET" -+#define CMD_BATCH_STOP "WLS_BATCHING STOP" -+#endif -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+static int -+priv_get_ndis(IN struct net_device *prNetDev, IN NDIS_TRANSPORT_STRUCT * prNdisReq, OUT PUINT_32 pu4OutputLen); -+ -+static int -+priv_set_ndis(IN struct net_device *prNetDev, IN NDIS_TRANSPORT_STRUCT * prNdisReq, OUT PUINT_32 pu4OutputLen); -+ -+#if 0 /* CFG_SUPPORT_WPS */ -+static int -+priv_set_appie(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, OUT char *pcExtra); -+ -+static int -+priv_set_filter(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, OUT char *pcExtra); -+#endif /* CFG_SUPPORT_WPS */ -+ -+static BOOLEAN reqSearchSupportedOidEntry(IN UINT_32 rOid, OUT P_WLAN_REQ_ENTRY * ppWlanReqEntry); -+ -+#if 0 -+static WLAN_STATUS -+reqExtQueryConfiguration(IN P_GLUE_INFO_T prGlueInfo, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+static WLAN_STATUS -+reqExtSetConfiguration(IN P_GLUE_INFO_T prGlueInfo, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+#endif -+ -+static WLAN_STATUS -+reqExtSetAcpiDevicePowerState(IN P_GLUE_INFO_T prGlueInfo, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen); -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+static UINT_8 aucOidBuf[4096] = { 0 }; -+ -+/* OID processing table */ -+/* Order is important here because the OIDs should be in order of -+ increasing value for binary searching. */ -+static WLAN_REQ_ENTRY arWlanOidReqTable[] = { -+ /* -+ {(NDIS_OID)rOid, -+ (PUINT_8)pucOidName, -+ fgQryBufLenChecking, fgSetBufLenChecking, fgIsHandleInGlueLayerOnly, u4InfoBufLen, -+ pfOidQueryHandler, -+ pfOidSetHandler} -+ */ -+ /* General Operational Characteristics */ -+ -+ /* Ethernet Operational Characteristics */ -+ {OID_802_3_CURRENT_ADDRESS, -+ DISP_STRING("OID_802_3_CURRENT_ADDRESS"), -+ TRUE, TRUE, ENUM_OID_DRIVER_CORE, 6, -+ (PFN_OID_HANDLER_FUNC_REQ) wlanoidQueryCurrentAddr, -+ NULL}, -+ -+ /* OID_802_3_MULTICAST_LIST */ -+ /* OID_802_3_MAXIMUM_LIST_SIZE */ -+ /* Ethernet Statistics */ -+ -+ /* NDIS 802.11 Wireless LAN OIDs */ -+ {OID_802_11_SUPPORTED_RATES, -+ DISP_STRING("OID_802_11_SUPPORTED_RATES"), -+ TRUE, FALSE, ENUM_OID_DRIVER_CORE, sizeof(PARAM_RATES_EX), -+ (PFN_OID_HANDLER_FUNC_REQ) wlanoidQuerySupportedRates, -+ NULL} -+ , -+ /* -+ {OID_802_11_CONFIGURATION, -+ DISP_STRING("OID_802_11_CONFIGURATION"), -+ TRUE, TRUE, ENUM_OID_GLUE_EXTENSION, sizeof(PARAM_802_11_CONFIG_T), -+ (PFN_OID_HANDLER_FUNC_REQ)reqExtQueryConfiguration, -+ (PFN_OID_HANDLER_FUNC_REQ)reqExtSetConfiguration}, -+ */ -+ {OID_PNP_SET_POWER, -+ DISP_STRING("OID_PNP_SET_POWER"), -+ TRUE, FALSE, ENUM_OID_GLUE_EXTENSION, sizeof(PARAM_DEVICE_POWER_STATE), -+ NULL, -+ (PFN_OID_HANDLER_FUNC_REQ) reqExtSetAcpiDevicePowerState} -+ , -+ -+ /* Custom OIDs */ -+ {OID_CUSTOM_OID_INTERFACE_VERSION, -+ DISP_STRING("OID_CUSTOM_OID_INTERFACE_VERSION"), -+ TRUE, FALSE, ENUM_OID_DRIVER_CORE, 4, -+ (PFN_OID_HANDLER_FUNC_REQ) wlanoidQueryOidInterfaceVersion, -+ NULL} -+ , -+ -+ /* -+ #if PTA_ENABLED -+ {OID_CUSTOM_BT_COEXIST_CTRL, -+ DISP_STRING("OID_CUSTOM_BT_COEXIST_CTRL"), -+ FALSE, TRUE, ENUM_OID_DRIVER_CORE, sizeof(PARAM_CUSTOM_BT_COEXIST_T), -+ NULL, -+ (PFN_OID_HANDLER_FUNC_REQ)wlanoidSetBtCoexistCtrl}, -+ #endif -+ */ -+ -+ /* -+ {OID_CUSTOM_POWER_MANAGEMENT_PROFILE, -+ DISP_STRING("OID_CUSTOM_POWER_MANAGEMENT_PROFILE"), -+ FALSE, FALSE, ENUM_OID_DRIVER_CORE, 0, -+ (PFN_OID_HANDLER_FUNC_REQ)wlanoidQueryPwrMgmtProfParam, -+ (PFN_OID_HANDLER_FUNC_REQ)wlanoidSetPwrMgmtProfParam}, -+ {OID_CUSTOM_PATTERN_CONFIG, -+ DISP_STRING("OID_CUSTOM_PATTERN_CONFIG"), -+ TRUE, TRUE, ENUM_OID_DRIVER_CORE, sizeof(PARAM_CUSTOM_PATTERN_SEARCH_CONFIG_STRUCT_T), -+ NULL, -+ (PFN_OID_HANDLER_FUNC_REQ)wlanoidSetPatternConfig}, -+ {OID_CUSTOM_BG_SSID_SEARCH_CONFIG, -+ DISP_STRING("OID_CUSTOM_BG_SSID_SEARCH_CONFIG"), -+ FALSE, FALSE, ENUM_OID_DRIVER_CORE, 0, -+ NULL, -+ (PFN_OID_HANDLER_FUNC_REQ)wlanoidSetBgSsidParam}, -+ {OID_CUSTOM_VOIP_SETUP, -+ DISP_STRING("OID_CUSTOM_VOIP_SETUP"), -+ TRUE, TRUE, ENUM_OID_DRIVER_CORE, 4, -+ (PFN_OID_HANDLER_FUNC_REQ)wlanoidQueryVoipConnectionStatus, -+ (PFN_OID_HANDLER_FUNC_REQ)wlanoidSetVoipConnectionStatus}, -+ {OID_CUSTOM_ADD_TS, -+ DISP_STRING("OID_CUSTOM_ADD_TS"), -+ TRUE, TRUE, ENUM_OID_DRIVER_CORE, 4, -+ NULL, -+ (PFN_OID_HANDLER_FUNC_REQ)wlanoidAddTS}, -+ {OID_CUSTOM_DEL_TS, -+ DISP_STRING("OID_CUSTOM_DEL_TS"), -+ TRUE, TRUE, ENUM_OID_DRIVER_CORE, 4, -+ NULL, -+ (PFN_OID_HANDLER_FUNC_REQ)wlanoidDelTS}, -+ */ -+ -+ /* -+ #if CFG_LP_PATTERN_SEARCH_SLT -+ {OID_CUSTOM_SLT, -+ DISP_STRING("OID_CUSTOM_SLT"), -+ FALSE, FALSE, ENUM_OID_DRIVER_CORE, 0, -+ (PFN_OID_HANDLER_FUNC_REQ)wlanoidQuerySltResult, -+ (PFN_OID_HANDLER_FUNC_REQ)wlanoidSetSltMode}, -+ #endif -+ -+ {OID_CUSTOM_ROAMING_EN, -+ DISP_STRING("OID_CUSTOM_ROAMING_EN"), -+ TRUE, TRUE, ENUM_OID_DRIVER_CORE, 4, -+ (PFN_OID_HANDLER_FUNC_REQ)wlanoidQueryRoamingFunction, -+ (PFN_OID_HANDLER_FUNC_REQ)wlanoidSetRoamingFunction}, -+ {OID_CUSTOM_WMM_PS_TEST, -+ DISP_STRING("OID_CUSTOM_WMM_PS_TEST"), -+ TRUE, TRUE, ENUM_OID_DRIVER_CORE, 4, -+ NULL, -+ (PFN_OID_HANDLER_FUNC_REQ)wlanoidSetWiFiWmmPsTest}, -+ {OID_CUSTOM_COUNTRY_STRING, -+ DISP_STRING("OID_CUSTOM_COUNTRY_STRING"), -+ FALSE, FALSE, ENUM_OID_DRIVER_CORE, 0, -+ (PFN_OID_HANDLER_FUNC_REQ)wlanoidQueryCurrentCountry, -+ (PFN_OID_HANDLER_FUNC_REQ)wlanoidSetCurrentCountry}, -+ -+ #if CFG_SUPPORT_802_11D -+ {OID_CUSTOM_MULTI_DOMAIN_CAPABILITY, -+ DISP_STRING("OID_CUSTOM_MULTI_DOMAIN_CAPABILITY"), -+ FALSE, FALSE, ENUM_OID_DRIVER_CORE, 0, -+ (PFN_OID_HANDLER_FUNC_REQ)wlanoidQueryMultiDomainCap, -+ (PFN_OID_HANDLER_FUNC_REQ)wlanoidSetMultiDomainCap}, -+ #endif -+ -+ {OID_CUSTOM_GPIO2_MODE, -+ DISP_STRING("OID_CUSTOM_GPIO2_MODE"), -+ FALSE, TRUE, ENUM_OID_DRIVER_CORE, sizeof(ENUM_PARAM_GPIO2_MODE_T), -+ NULL, -+ (PFN_OID_HANDLER_FUNC_REQ)wlanoidSetGPIO2Mode}, -+ {OID_CUSTOM_CONTINUOUS_POLL, -+ DISP_STRING("OID_CUSTOM_CONTINUOUS_POLL"), -+ FALSE, TRUE, ENUM_OID_DRIVER_CORE, sizeof(PARAM_CONTINUOUS_POLL_T), -+ (PFN_OID_HANDLER_FUNC_REQ)wlanoidQueryContinuousPollInterval, -+ (PFN_OID_HANDLER_FUNC_REQ)wlanoidSetContinuousPollProfile}, -+ {OID_CUSTOM_DISABLE_BEACON_DETECTION, -+ DISP_STRING("OID_CUSTOM_DISABLE_BEACON_DETECTION"), -+ FALSE, TRUE, ENUM_OID_DRIVER_CORE, 4, -+ (PFN_OID_HANDLER_FUNC_REQ)wlanoidQueryDisableBeaconDetectionFunc, -+ (PFN_OID_HANDLER_FUNC_REQ)wlanoidSetDisableBeaconDetectionFunc}, -+ */ -+ -+ /* WPS */ -+ /* -+ {OID_CUSTOM_DISABLE_PRIVACY_CHECK, -+ DISP_STRING("OID_CUSTOM_DISABLE_PRIVACY_CHECK"), -+ FALSE, TRUE, ENUM_OID_DRIVER_CORE, 4, -+ NULL, -+ (PFN_OID_HANDLER_FUNC_REQ)wlanoidSetDisablePriavcyCheck}, -+ */ -+ -+ {OID_CUSTOM_MCR_RW, -+ DISP_STRING("OID_CUSTOM_MCR_RW"), -+ TRUE, TRUE, ENUM_OID_DRIVER_CORE, sizeof(PARAM_CUSTOM_MCR_RW_STRUCT_T), -+ (PFN_OID_HANDLER_FUNC_REQ) wlanoidQueryMcrRead, -+ (PFN_OID_HANDLER_FUNC_REQ) wlanoidSetMcrWrite} -+ , -+ -+ {OID_CUSTOM_EEPROM_RW, -+ DISP_STRING("OID_CUSTOM_EEPROM_RW"), -+ TRUE, TRUE, ENUM_OID_DRIVER_CORE, sizeof(PARAM_CUSTOM_EEPROM_RW_STRUCT_T), -+ (PFN_OID_HANDLER_FUNC_REQ) wlanoidQueryEepromRead, -+ (PFN_OID_HANDLER_FUNC_REQ) wlanoidSetEepromWrite} -+ , -+ -+ {OID_CUSTOM_SW_CTRL, -+ DISP_STRING("OID_CUSTOM_SW_CTRL"), -+ TRUE, TRUE, ENUM_OID_DRIVER_CORE, sizeof(PARAM_CUSTOM_SW_CTRL_STRUCT_T), -+ (PFN_OID_HANDLER_FUNC_REQ) wlanoidQuerySwCtrlRead, -+ (PFN_OID_HANDLER_FUNC_REQ) wlanoidSetSwCtrlWrite} -+ , -+ -+ {OID_CUSTOM_MEM_DUMP, -+ DISP_STRING("OID_CUSTOM_MEM_DUMP"), -+ TRUE, TRUE, ENUM_OID_DRIVER_CORE, sizeof(PARAM_CUSTOM_MEM_DUMP_STRUCT_T), -+ (PFN_OID_HANDLER_FUNC_REQ) wlanoidQueryMemDump, -+ NULL} -+ , -+ -+ {OID_CUSTOM_TEST_MODE, -+ DISP_STRING("OID_CUSTOM_TEST_MODE"), -+ FALSE, FALSE, ENUM_OID_DRIVER_CORE, 0, -+ NULL, -+ (PFN_OID_HANDLER_FUNC_REQ) wlanoidRftestSetTestMode} -+ , -+ -+ /* -+ {OID_CUSTOM_TEST_RX_STATUS, -+ DISP_STRING("OID_CUSTOM_TEST_RX_STATUS"), -+ FALSE, TRUE, ENUM_OID_DRIVER_CORE, sizeof(PARAM_CUSTOM_RFTEST_RX_STATUS_STRUCT_T), -+ (PFN_OID_HANDLER_FUNC_REQ)wlanoidQueryRfTestRxStatus, -+ NULL}, -+ {OID_CUSTOM_TEST_TX_STATUS, -+ DISP_STRING("OID_CUSTOM_TEST_TX_STATUS"), -+ FALSE, TRUE, ENUM_OID_DRIVER_CORE, sizeof(PARAM_CUSTOM_RFTEST_TX_STATUS_STRUCT_T), -+ (PFN_OID_HANDLER_FUNC_REQ)wlanoidQueryRfTestTxStatus, -+ NULL}, -+ */ -+ {OID_CUSTOM_ABORT_TEST_MODE, -+ DISP_STRING("OID_CUSTOM_ABORT_TEST_MODE"), -+ FALSE, FALSE, ENUM_OID_DRIVER_CORE, 0, -+ NULL, -+ (PFN_OID_HANDLER_FUNC_REQ) wlanoidRftestSetAbortTestMode} -+ , -+ {OID_CUSTOM_MTK_WIFI_TEST, -+ DISP_STRING("OID_CUSTOM_MTK_WIFI_TEST"), -+ TRUE, TRUE, ENUM_OID_DRIVER_CORE, sizeof(PARAM_MTK_WIFI_TEST_STRUCT_T), -+ (PFN_OID_HANDLER_FUNC_REQ) wlanoidRftestQueryAutoTest, -+ (PFN_OID_HANDLER_FUNC_REQ) wlanoidRftestSetAutoTest} -+ , -+ -+ /* OID_CUSTOM_EMULATION_VERSION_CONTROL */ -+ -+ /* BWCS */ -+#if CFG_SUPPORT_BCM && CFG_SUPPORT_BCM_BWCS -+ {OID_CUSTOM_BWCS_CMD, -+ DISP_STRING("OID_CUSTOM_BWCS_CMD"), -+ FALSE, FALSE, ENUM_OID_DRIVER_CORE, sizeof(PTA_IPC_T), -+ (PFN_OID_HANDLER_FUNC_REQ) wlanoidQueryBT, -+ (PFN_OID_HANDLER_FUNC_REQ) wlanoidSetBT} -+ , -+#endif -+ -+/* {OID_CUSTOM_SINGLE_ANTENNA, -+ DISP_STRING("OID_CUSTOM_SINGLE_ANTENNA"), -+ FALSE, FALSE, ENUM_OID_DRIVER_CORE, 4, -+ (PFN_OID_HANDLER_FUNC_REQ)wlanoidQueryBtSingleAntenna, -+ (PFN_OID_HANDLER_FUNC_REQ)wlanoidSetBtSingleAntenna}, -+ {OID_CUSTOM_SET_PTA, -+ DISP_STRING("OID_CUSTOM_SET_PTA"), -+ FALSE, FALSE, ENUM_OID_DRIVER_CORE, 4, -+ (PFN_OID_HANDLER_FUNC_REQ)wlanoidQueryPta, -+ (PFN_OID_HANDLER_FUNC_REQ)wlanoidSetPta}, -+ */ -+ -+ {OID_CUSTOM_MTK_NVRAM_RW, -+ DISP_STRING("OID_CUSTOM_MTK_NVRAM_RW"), -+ TRUE, TRUE, ENUM_OID_DRIVER_CORE, sizeof(PARAM_CUSTOM_NVRAM_RW_STRUCT_T), -+ (PFN_OID_HANDLER_FUNC_REQ) wlanoidQueryNvramRead, -+ (PFN_OID_HANDLER_FUNC_REQ) wlanoidSetNvramWrite} -+ , -+ -+ {OID_CUSTOM_CFG_SRC_TYPE, -+ DISP_STRING("OID_CUSTOM_CFG_SRC_TYPE"), -+ FALSE, FALSE, ENUM_OID_DRIVER_CORE, sizeof(ENUM_CFG_SRC_TYPE_T), -+ (PFN_OID_HANDLER_FUNC_REQ) wlanoidQueryCfgSrcType, -+ NULL} -+ , -+ -+ {OID_CUSTOM_EEPROM_TYPE, -+ DISP_STRING("OID_CUSTOM_EEPROM_TYPE"), -+ FALSE, FALSE, ENUM_OID_DRIVER_CORE, sizeof(ENUM_EEPROM_TYPE_T), -+ (PFN_OID_HANDLER_FUNC_REQ) wlanoidQueryEepromType, -+ NULL} -+ , -+ -+#if CFG_SUPPORT_WAPI -+ {OID_802_11_WAPI_MODE, -+ DISP_STRING("OID_802_11_WAPI_MODE"), -+ FALSE, TRUE, ENUM_OID_DRIVER_CORE, 4, -+ NULL, -+ (PFN_OID_HANDLER_FUNC_REQ) wlanoidSetWapiMode} -+ , -+ {OID_802_11_WAPI_ASSOC_INFO, -+ DISP_STRING("OID_802_11_WAPI_ASSOC_INFO"), -+ FALSE, FALSE, ENUM_OID_DRIVER_CORE, 0, -+ NULL, -+ (PFN_OID_HANDLER_FUNC_REQ) wlanoidSetWapiAssocInfo} -+ , -+ {OID_802_11_SET_WAPI_KEY, -+ DISP_STRING("OID_802_11_SET_WAPI_KEY"), -+ FALSE, FALSE, ENUM_OID_DRIVER_CORE, sizeof(PARAM_WPI_KEY_T), -+ NULL, -+ (PFN_OID_HANDLER_FUNC_REQ) wlanoidSetWapiKey} -+ , -+#endif -+ -+#if CFG_SUPPORT_WPS2 -+ {OID_802_11_WSC_ASSOC_INFO, -+ DISP_STRING("OID_802_11_WSC_ASSOC_INFO"), -+ FALSE, FALSE, ENUM_OID_DRIVER_CORE, 0, -+ NULL, -+ (PFN_OID_HANDLER_FUNC_REQ) wlanoidSetWSCAssocInfo} -+ , -+#endif -+}; -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Dispatching function for private ioctl region (SIOCIWFIRSTPRIV ~ -+* SIOCIWLASTPRIV). -+* -+* \param[in] prNetDev Net device requested. -+* \param[in] prIfReq Pointer to ifreq structure. -+* \param[in] i4Cmd Command ID between SIOCIWFIRSTPRIV and SIOCIWLASTPRIV. -+* -+* \retval 0 for success. -+* \retval -EOPNOTSUPP If cmd is not supported. -+* \retval -EFAULT For fail. -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+int priv_support_ioctl(IN struct net_device *prNetDev, IN OUT struct ifreq *prIfReq, IN int i4Cmd) -+{ -+ /* prIfReq is verified in the caller function wlanDoIOCTL() */ -+ struct iwreq *prIwReq = (struct iwreq *)prIfReq; -+ struct iw_request_info rIwReqInfo; -+ -+ /* prDev is verified in the caller function wlanDoIOCTL() */ -+ -+ /* Prepare the call */ -+ rIwReqInfo.cmd = (__u16) i4Cmd; -+ rIwReqInfo.flags = 0; -+ -+ switch (i4Cmd) { -+ case IOCTL_SET_INT: -+ /* NOTE(Kevin): 1/3 INT Type <= IFNAMSIZ, so we don't need copy_from/to_user() */ -+ return priv_set_int(prNetDev, &rIwReqInfo, &(prIwReq->u), (char *)&(prIwReq->u)); -+ -+ case IOCTL_GET_INT: -+ /* NOTE(Kevin): 1/3 INT Type <= IFNAMSIZ, so we don't need copy_from/to_user() */ -+ return priv_get_int(prNetDev, &rIwReqInfo, &(prIwReq->u), (char *)&(prIwReq->u)); -+ -+ case IOCTL_SET_STRUCT: -+ case IOCTL_SET_STRUCT_FOR_EM: -+ return priv_set_struct(prNetDev, &rIwReqInfo, &prIwReq->u, (char *)&(prIwReq->u)); -+ -+ case IOCTL_GET_STRUCT: -+ return priv_get_struct(prNetDev, &rIwReqInfo, &prIwReq->u, (char *)&(prIwReq->u)); -+ -+ default: -+ return -EOPNOTSUPP; -+ -+ } /* end of switch */ -+ -+} /* priv_support_ioctl */ -+ -+#if CFG_SUPPORT_BATCH_SCAN -+ -+EVENT_BATCH_RESULT_T g_rEventBatchResult[CFG_BATCH_MAX_MSCAN]; -+ -+UINT_32 batchChannelNum2Freq(UINT_32 u4ChannelNum) -+{ -+ UINT_32 u4ChannelInMHz; -+ -+ if (u4ChannelNum >= 1 && u4ChannelNum <= 13) -+ u4ChannelInMHz = 2412 + (u4ChannelNum - 1) * 5; -+ else if (u4ChannelNum == 14) -+ u4ChannelInMHz = 2484; -+ else if (u4ChannelNum == 133) -+ u4ChannelInMHz = 3665; /* 802.11y */ -+ else if (u4ChannelNum == 137) -+ u4ChannelInMHz = 3685; /* 802.11y */ -+ else if (u4ChannelNum >= 34 && u4ChannelNum <= 165) -+ u4ChannelInMHz = 5000 + u4ChannelNum * 5; -+ else if (u4ChannelNum >= 183 && u4ChannelNum <= 196) -+ u4ChannelInMHz = 4000 + u4ChannelNum * 5; -+ else -+ u4ChannelInMHz = 0; -+ -+ return u4ChannelInMHz; -+} -+ -+#define TMP_TEXT_LEN_S 40 -+#define TMP_TEXT_LEN_L 60 -+static UCHAR text1[TMP_TEXT_LEN_S], text2[TMP_TEXT_LEN_L], text3[TMP_TEXT_LEN_L]; /* A safe len */ -+ -+WLAN_STATUS -+batchConvertResult(IN P_EVENT_BATCH_RESULT_T prEventBatchResult, -+ OUT PVOID pvBuffer, IN UINT_32 u4MaxBufferLen, OUT PUINT_32 pu4RetLen) -+{ -+ CHAR *p = pvBuffer; -+ CHAR ssid[ELEM_MAX_LEN_SSID + 1]; -+ INT_32 nsize = 0, nsize1, nsize2, nsize3, scancount; -+ INT_32 i, j, nleft; -+ UINT_32 freq; -+ -+ P_EVENT_BATCH_RESULT_ENTRY_T prEntry; -+ P_EVENT_BATCH_RESULT_T pBr; -+ -+ nleft = u4MaxBufferLen - 5; /* -5 for "----\n" */ -+ -+ pBr = prEventBatchResult; -+ scancount = 0; -+ for (j = 0; j < CFG_BATCH_MAX_MSCAN; j++) { -+ scancount += pBr->ucScanCount; -+ pBr++; -+ } -+ -+ nsize1 = kalSnprintf(text1, TMP_TEXT_LEN_S, "scancount=%x\nnextcount=%x\n", scancount, scancount); -+ if (nsize1 < nleft) { -+ p += nsize1 = kalSprintf(p, "%s", text1); -+ nleft -= nsize1; -+ } else -+ goto short_buf; -+ -+ pBr = prEventBatchResult; -+ for (j = 0; j < CFG_BATCH_MAX_MSCAN; j++) { -+ DBGLOG(SCN, TRACE, "convert mscan = %d, apcount=%d, nleft=%d\n", j, pBr->ucScanCount, nleft); -+ -+ if (pBr->ucScanCount == 0) { -+ pBr++; -+ continue; -+ } -+ -+ nleft -= 5; /* -5 for "####\n" */ -+ -+ /* We only support one round scan result now. */ -+ nsize1 = kalSnprintf(text1, TMP_TEXT_LEN_S, "apcount=%d\n", pBr->ucScanCount); -+ if (nsize1 < nleft) { -+ p += nsize1 = kalSprintf(p, "%s", text1); -+ nleft -= nsize1; -+ } else -+ goto short_buf; -+ -+ for (i = 0; i < pBr->ucScanCount; i++) { -+ prEntry = &pBr->arBatchResult[i]; -+ -+ nsize1 = kalSnprintf(text1, TMP_TEXT_LEN_S, "bssid=" MACSTR "\n", -+ prEntry->aucBssid[0], -+ prEntry->aucBssid[1], -+ prEntry->aucBssid[2], -+ prEntry->aucBssid[3], -+ prEntry->aucBssid[4], prEntry->aucBssid[5]); -+ -+ kalMemCopy(ssid, -+ prEntry->aucSSID, -+ (prEntry->ucSSIDLen < ELEM_MAX_LEN_SSID ? prEntry->ucSSIDLen : ELEM_MAX_LEN_SSID)); -+ ssid[(prEntry->ucSSIDLen < -+ (ELEM_MAX_LEN_SSID - 1) ? prEntry->ucSSIDLen : (ELEM_MAX_LEN_SSID - 1))] = '\0'; -+ nsize2 = kalSnprintf(text2, TMP_TEXT_LEN_L, "ssid=%s\n", ssid); -+ -+ freq = batchChannelNum2Freq(prEntry->ucFreq); -+ nsize3 = -+ kalSnprintf(text3, TMP_TEXT_LEN_L, -+ "freq=%u\nlevel=%d\ndist=%u\ndistSd=%u\n====\n", freq, -+ prEntry->cRssi, prEntry->u4Dist, prEntry->u4Distsd); -+ -+ nsize = nsize1 + nsize2 + nsize3; -+ if (nsize < nleft) { -+ -+ kalStrnCpy(p, text1, TMP_TEXT_LEN_S); -+ p += nsize1; -+ -+ kalStrnCpy(p, text2, TMP_TEXT_LEN_L); -+ p += nsize2; -+ -+ kalStrnCpy(p, text3, TMP_TEXT_LEN_L); -+ p += nsize3; -+ -+ nleft -= nsize; -+ } else { -+ DBGLOG(SCN, TRACE, "Warning: Early break! (%d)\n", i); -+ break; /* discard following entries, TODO: apcount? */ -+ } -+ } -+ -+ nsize1 = kalSnprintf(text1, TMP_TEXT_LEN_S, "%s", "####\n"); -+ p += kalSprintf(p, "%s", text1); -+ -+ pBr++; -+ } -+ -+ nsize1 = kalSnprintf(text1, TMP_TEXT_LEN_S, "%s", "----\n"); -+ kalSprintf(p, "%s", text1); -+ -+ *pu4RetLen = u4MaxBufferLen - nleft; -+ DBGLOG(SCN, TRACE, "total len = %d (max len = %d)\n", *pu4RetLen, u4MaxBufferLen); -+ -+ return WLAN_STATUS_SUCCESS; -+ -+short_buf: -+ DBGLOG(SCN, TRACE, -+ "Short buffer issue! %d > %d, %s\n", u4MaxBufferLen + (nsize - nleft), -+ u4MaxBufferLen, (char *)pvBuffer); -+ return WLAN_STATUS_INVALID_LENGTH; -+} -+#endif -+ -+#if CFG_SUPPORT_GET_CH_ENV -+WLAN_STATUS -+scanEnvResult(P_GLUE_INFO_T prGlueInfo, OUT PVOID pvBuffer, IN UINT_32 u4MaxBufferLen, OUT PUINT_32 pu4RetLen) -+{ -+ P_ADAPTER_T prAdapter = NULL; -+ CHAR *p = pvBuffer; -+ INT_32 nsize; -+ INT_32 i, nleft; -+ P_SCAN_INFO_T prScanInfo; -+ P_LINK_T prBSSDescList; -+ P_BSS_DESC_T prBssDesc; -+ CH_ENV_T chEnvInfo[54]; /* 54: from FW define; TODO: sync MAXIMUM_OPERATION_CHANNEL_LIST */ -+ UINT_32 i4GetCh = 0; -+ INT_32 i4Argc = 0; -+ PCHAR apcArgv[WLAN_CFG_ARGV_MAX] = { 0 }; -+ UINT_8 ucTextLen = 40; -+ UCHAR text[ucTextLen]; -+ INT_32 u4Ret; -+ -+ prAdapter = prGlueInfo->prAdapter; -+ prScanInfo = &(prAdapter->rWifiVar.rScanInfo); -+ prBSSDescList = &prScanInfo->rBSSDescList; -+ -+ kalMemZero(chEnvInfo, sizeof(chEnvInfo)); -+ -+ DBGLOG(SCN, TRACE, "pvBuffer:%s, pu4RetLen:%d\n", (char *)pvBuffer, *pu4RetLen); -+ -+ wlanCfgParseArgument(pvBuffer, &i4Argc, apcArgv); -+ DBGLOG(REQ, LOUD, "argc is %i\n", i4Argc); -+ -+ if (i4Argc >= 2) { -+ u4Ret = kalkStrtou32(apcArgv[1], 0, &i4GetCh); -+ if (u4Ret) -+ DBGLOG(SCN, TRACE, "parse pvBuffer error u4Ret=%d\n", u4Ret); -+ /* i4GetCh = kalStrtoul(apcArgv[1], NULL, 0); */ -+ } -+ -+ nleft = u4MaxBufferLen - 5; /* -5 for "----\n" */ -+ -+ nsize = kalSnprintf(text, ucTextLen, "%s", "scanEnvResult\nResult:1\n");/* Always return 1 for alpha version. */ -+ -+ if (nsize < nleft) { -+ p += nsize = kalSnprintf(p, ucTextLen, "%s", text); -+ nleft -= nsize; -+ } else -+ goto short_buf; -+ -+ /* Search BSS Desc from current SCAN result list. */ -+ LINK_FOR_EACH_ENTRY(prBssDesc, prBSSDescList, rLinkEntry, BSS_DESC_T) { -+ if (prBssDesc->ucChannelNum > 0) { -+ if (prBssDesc->ucChannelNum <= 14) { /* 1~14 */ -+ chEnvInfo[prBssDesc->ucChannelNum - 1].ucChNum = prBssDesc->ucChannelNum; -+ chEnvInfo[prBssDesc->ucChannelNum - 1].ucApNum++; -+ } else if (prBssDesc->ucChannelNum <= 64) { /* 15~22 */ -+ chEnvInfo[prBssDesc->ucChannelNum / 4 + 5].ucChNum = prBssDesc->ucChannelNum; -+ chEnvInfo[prBssDesc->ucChannelNum / 4 + 5].ucApNum++; -+ } else if (prBssDesc->ucChannelNum <= 116) { /* 23~27 */ -+ chEnvInfo[prBssDesc->ucChannelNum / 4 - 3].ucChNum = prBssDesc->ucChannelNum; -+ chEnvInfo[prBssDesc->ucChannelNum / 4 - 3].ucApNum++; -+ } else if (prBssDesc->ucChannelNum <= 140) { /* 28~30 */ -+ chEnvInfo[prBssDesc->ucChannelNum / 4 - 6].ucChNum = prBssDesc->ucChannelNum; -+ chEnvInfo[prBssDesc->ucChannelNum / 4 - 6].ucApNum++; -+ } else if (prBssDesc->ucChannelNum <= 165) { /* 31~35 */ -+ chEnvInfo[(prBssDesc->ucChannelNum - 1) / 4 - 7].ucChNum = prBssDesc->ucChannelNum; -+ chEnvInfo[(prBssDesc->ucChannelNum - 1) / 4 - 7].ucApNum++; -+ } -+ } -+ } -+ -+ for (i = 0; i < 54; i++) { -+ if (chEnvInfo[i].ucChNum != 0) { -+ if (i4GetCh == 0 || (chEnvInfo[i].ucChNum == (UINT_8)i4GetCh)) { -+ DBGLOG(SCN, TRACE, "chNum=%d,apNum=%d\n", chEnvInfo[i].ucChNum, chEnvInfo[i].ucApNum); -+ p += nsize = -+ kalSnprintf(p, ucTextLen, "chNum=%d,apNum=%d\n", chEnvInfo[i].ucChNum, -+ chEnvInfo[i].ucApNum); -+ nleft -= nsize; -+ } -+ } -+ } -+ -+ p += nsize = kalSnprintf(p, ucTextLen, "%s", "----\n"); -+ nleft -= nsize; -+ -+ *pu4RetLen = u4MaxBufferLen - nleft; -+ DBGLOG(SCN, TRACE, "total len = %d (max len = %d)\n", *pu4RetLen, u4MaxBufferLen); -+ -+ return WLAN_STATUS_SUCCESS; -+ -+short_buf: -+ DBGLOG(SCN, TRACE, "Short buffer issue! %d > %d, %s\n", u4MaxBufferLen + (nsize - nleft), u4MaxBufferLen, p); -+ return WLAN_STATUS_INVALID_LENGTH; -+} -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Private ioctl set int handler. -+* -+* \param[in] prNetDev Net device requested. -+* \param[in] prIwReqInfo Pointer to iwreq structure. -+* \param[in] prIwReqData The ioctl data structure, use the field of sub-command. -+* \param[in] pcExtra The buffer with input value -+* -+* \retval 0 For success. -+* \retval -EOPNOTSUPP If cmd is not supported. -+* \retval -EINVAL If a value is out of range. -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static int -+_priv_set_int(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN char *pcExtra) -+{ -+ UINT_32 u4SubCmd; -+ PUINT_32 pu4IntBuf; -+ P_NDIS_TRANSPORT_STRUCT prNdisReq; -+ P_GLUE_INFO_T prGlueInfo; -+ UINT_32 u4BufLen = 0; -+ int status = 0; -+ P_PTA_IPC_T prPtaIpc; -+ -+ ASSERT(prNetDev); -+ ASSERT(prIwReqInfo); -+ ASSERT(prIwReqData); -+ ASSERT(pcExtra); -+ -+ if (FALSE == GLUE_CHK_PR3(prNetDev, prIwReqData, pcExtra)) -+ return -EINVAL; -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); -+ -+ u4SubCmd = (UINT_32) prIwReqData->mode; -+ pu4IntBuf = (PUINT_32) pcExtra; -+ -+ switch (u4SubCmd) { -+ case PRIV_CMD_TEST_MODE: -+ /* printk("TestMode=%ld\n", pu4IntBuf[1]); */ -+ prNdisReq = (P_NDIS_TRANSPORT_STRUCT) &aucOidBuf[0]; -+ -+ if (pu4IntBuf[1] == PRIV_CMD_TEST_MAGIC_KEY) { -+ prNdisReq->ndisOidCmd = OID_CUSTOM_TEST_MODE; -+ } else if (pu4IntBuf[1] == 0) { -+ prNdisReq->ndisOidCmd = OID_CUSTOM_ABORT_TEST_MODE; -+ } else { -+ status = 0; -+ break; -+ } -+ prNdisReq->inNdisOidlength = 0; -+ prNdisReq->outNdisOidLength = 0; -+ -+ /* Execute this OID */ -+ status = priv_set_ndis(prNetDev, prNdisReq, &u4BufLen); -+ break; -+ -+ case PRIV_CMD_TEST_CMD: -+ /* printk("CMD=0x%08lx, data=0x%08lx\n", pu4IntBuf[1], pu4IntBuf[2]); */ -+ prNdisReq = (P_NDIS_TRANSPORT_STRUCT) &aucOidBuf[0]; -+ -+ kalMemCopy(&prNdisReq->ndisOidContent[0], &pu4IntBuf[1], 8); -+ -+ prNdisReq->ndisOidCmd = OID_CUSTOM_MTK_WIFI_TEST; -+ prNdisReq->inNdisOidlength = 8; -+ prNdisReq->outNdisOidLength = 8; -+ -+ /* Execute this OID */ -+ status = priv_set_ndis(prNetDev, prNdisReq, &u4BufLen); -+ break; -+ -+#if CFG_SUPPORT_PRIV_MCR_RW -+ case PRIV_CMD_ACCESS_MCR: -+ /* printk("addr=0x%08lx, data=0x%08lx\n", pu4IntBuf[1], pu4IntBuf[2]); */ -+ prNdisReq = (P_NDIS_TRANSPORT_STRUCT) &aucOidBuf[0]; -+ -+ if (!prGlueInfo->fgMcrAccessAllowed) { -+ if (pu4IntBuf[1] == PRIV_CMD_TEST_MAGIC_KEY && pu4IntBuf[2] == PRIV_CMD_TEST_MAGIC_KEY) -+ prGlueInfo->fgMcrAccessAllowed = TRUE; -+ status = 0; -+ break; -+ } -+ -+ kalMemCopy(&prNdisReq->ndisOidContent[0], &pu4IntBuf[1], 8); -+ -+ prNdisReq->ndisOidCmd = OID_CUSTOM_MCR_RW; -+ prNdisReq->inNdisOidlength = 8; -+ prNdisReq->outNdisOidLength = 8; -+ -+ /* Execute this OID */ -+ status = priv_set_ndis(prNetDev, prNdisReq, &u4BufLen); -+ break; -+#endif -+ -+ case PRIV_CMD_SW_CTRL: -+ /* printk("addr=0x%08lx, data=0x%08lx\n", pu4IntBuf[1], pu4IntBuf[2]); */ -+ prNdisReq = (P_NDIS_TRANSPORT_STRUCT) &aucOidBuf[0]; -+ -+ kalMemCopy(&prNdisReq->ndisOidContent[0], &pu4IntBuf[1], 8); -+ -+ prNdisReq->ndisOidCmd = OID_CUSTOM_SW_CTRL; -+ prNdisReq->inNdisOidlength = 8; -+ prNdisReq->outNdisOidLength = 8; -+ -+ /* Execute this OID */ -+ status = priv_set_ndis(prNetDev, prNdisReq, &u4BufLen); -+ break; -+ -+#if 0 -+ case PRIV_CMD_BEACON_PERIOD: -+ rStatus = wlanSetInformation(prGlueInfo->prAdapter, wlanoidSetBeaconInterval, -+ (PVOID)&pu4IntBuf[1],/* pu4IntBuf[0] is used as input SubCmd */ -+ sizeof(UINT_32), &u4BufLen); -+ break; -+#endif -+ -+#if CFG_TCP_IP_CHKSUM_OFFLOAD -+ case PRIV_CMD_CSUM_OFFLOAD: -+ { -+ UINT_32 u4CSUMFlags; -+ -+ if (pu4IntBuf[1] == 1) -+ u4CSUMFlags = CSUM_OFFLOAD_EN_ALL; -+ else if (pu4IntBuf[1] == 0) -+ u4CSUMFlags = 0; -+ else -+ return -EINVAL; -+ -+ if (kalIoctl(prGlueInfo, -+ wlanoidSetCSUMOffload, -+ (PVOID)&u4CSUMFlags, -+ sizeof(UINT_32), FALSE, FALSE, TRUE, FALSE, &u4BufLen) == WLAN_STATUS_SUCCESS) { -+ if (pu4IntBuf[1] == 1) -+ prNetDev->features |= NETIF_F_HW_CSUM; -+ else if (pu4IntBuf[1] == 0) -+ prNetDev->features &= ~NETIF_F_HW_CSUM; -+ } -+ } -+ break; -+#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */ -+ -+ case PRIV_CMD_POWER_MODE: -+ kalIoctl(prGlueInfo, wlanoidSet802dot11PowerSaveProfile, -+ (PVOID)&pu4IntBuf[1], /* pu4IntBuf[0] is used as input SubCmd */ -+ sizeof(UINT_32), FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ break; -+ -+ case PRIV_CMD_WMM_PS: -+ { -+ PARAM_CUSTOM_WMM_PS_TEST_STRUCT_T rWmmPsTest; -+ -+ rWmmPsTest.bmfgApsdEnAc = (UINT_8) pu4IntBuf[1]; -+ rWmmPsTest.ucIsEnterPsAtOnce = (UINT_8) pu4IntBuf[2]; -+ rWmmPsTest.ucIsDisableUcTrigger = (UINT_8) pu4IntBuf[3]; -+ rWmmPsTest.reserved = 0; -+ -+ kalIoctl(prGlueInfo, -+ wlanoidSetWiFiWmmPsTest, -+ (PVOID)&rWmmPsTest, -+ sizeof(PARAM_CUSTOM_WMM_PS_TEST_STRUCT_T), FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ } -+ break; -+ -+#if 0 -+ case PRIV_CMD_ADHOC_MODE: -+ rStatus = wlanSetInformation(prGlueInfo->prAdapter, wlanoidSetAdHocMode, -+ (PVOID)&pu4IntBuf[1], /* pu4IntBuf[0] is used as input SubCmd */ -+ sizeof(UINT_32), &u4BufLen); -+ break; -+#endif -+ -+ case PRIV_CUSTOM_BWCS_CMD: -+ -+ DBGLOG(REQ, INFO, "pu4IntBuf[1] = %x, size of PTA_IPC_T = %zu.\n", -+ pu4IntBuf[1], sizeof(PARAM_PTA_IPC_T)); -+ -+ prPtaIpc = (P_PTA_IPC_T) aucOidBuf; -+ prPtaIpc->u.aucBTPParams[0] = (UINT_8) (pu4IntBuf[1] >> 24); -+ prPtaIpc->u.aucBTPParams[1] = (UINT_8) (pu4IntBuf[1] >> 16); -+ prPtaIpc->u.aucBTPParams[2] = (UINT_8) (pu4IntBuf[1] >> 8); -+ prPtaIpc->u.aucBTPParams[3] = (UINT_8) (pu4IntBuf[1]); -+ -+ DBGLOG(REQ, INFO, -+ "BCM BWCS CMD : BTPParams[0]=%02x, BTPParams[1]=%02x, BTPParams[2]=%02x, BTPParams[3]=%02x.\n", -+ prPtaIpc->u.aucBTPParams[0], prPtaIpc->u.aucBTPParams[1], prPtaIpc->u.aucBTPParams[2], -+ prPtaIpc->u.aucBTPParams[3]); -+ -+#if 0 -+ status = wlanSetInformation(prGlueInfo->prAdapter, -+ wlanoidSetBT, (PVOID)&aucOidBuf[0], u4CmdLen, &u4BufLen); -+#endif -+ -+ status = wlanoidSetBT(prGlueInfo->prAdapter, -+ (PVOID)&aucOidBuf[0], sizeof(PARAM_PTA_IPC_T), &u4BufLen); -+ -+ if (WLAN_STATUS_SUCCESS != status) -+ status = -EFAULT; -+ -+ break; -+ -+ case PRIV_CMD_BAND_CONFIG: -+ { -+ DBGLOG(REQ, INFO, "CMD set_band=%u\n", (UINT_32) pu4IntBuf[1]); -+ } -+ break; -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ case PRIV_CMD_P2P_MODE: -+ { -+ /* no use, move to set_p2p_mode_handler() */ -+ PARAM_CUSTOM_P2P_SET_STRUCT_T p2pmode; -+ -+ p2pmode.u4Enable = pu4IntBuf[1]; -+ p2pmode.u4Mode = pu4IntBuf[2]; -+ set_p2p_mode_handler(prNetDev, p2pmode); -+#if 0 -+ PARAM_CUSTOM_P2P_SET_STRUCT_T rSetP2P; -+ WLAN_STATUS rWlanStatus = WLAN_STATUS_SUCCESS; -+ BOOLEAN fgIsP2PEnding; -+ -+ GLUE_SPIN_LOCK_DECLARATION(); -+ -+ /* avoid remove & p2p off command simultaneously */ -+ GLUE_ACQUIRE_THE_SPIN_LOCK(&g_p2p_lock); -+ fgIsP2PEnding = g_u4P2PEnding; -+ g_u4P2POnOffing = 1; -+ GLUE_RELEASE_THE_SPIN_LOCK(&g_p2p_lock); -+ -+ if (fgIsP2PEnding == 1) { -+ /* skip the command if we are removing */ -+ GLUE_ACQUIRE_THE_SPIN_LOCK(&g_p2p_lock); -+ g_u4P2POnOffing = 0; -+ GLUE_RELEASE_THE_SPIN_LOCK(&g_p2p_lock); -+ break; -+ } -+ rSetP2P.u4Enable = pu4IntBuf[1]; -+ rSetP2P.u4Mode = pu4IntBuf[2]; -+ -+ if (!rSetP2P.u4Enable) -+ p2pNetUnregister(prGlueInfo, TRUE); -+ -+ /* move out to caller to avoid kalIoctrl & suspend/resume deadlock problem ALPS00844864 */ -+ /* -+ Scenario: -+ 1. System enters suspend/resume but not yet enter wlanearlysuspend() -+ or wlanlateresume(); -+ -+ 2. System switches to do PRIV_CMD_P2P_MODE and execute kalIoctl() -+ and get g_halt_sem then do glRegisterEarlySuspend() or -+ glUnregisterEarlySuspend(); -+ -+ But system suspend/resume procedure is not yet finished so we -+ suspend; -+ -+ 3. System switches back to do suspend/resume procedure and execute -+ kalIoctl(). But driver does not yet release g_halt_sem so system -+ suspend in wlanearlysuspend() or wlanlateresume(); -+ -+ ==> deadlock occurs. -+ */ -+ if ((!rSetP2P.u4Enable) && (g_u4HaltFlag == 0) && (fgIsResetting == FALSE)) { -+ /* fgIsP2PRegistered == TRUE means P2P is enabled */ -+ DBGLOG(P2P, INFO, "p2pEalySuspendReg\n"); -+ p2pEalySuspendReg(prGlueInfo, rSetP2P.u4Enable); /* p2p remove */ -+ } -+ -+ DBGLOG(P2P, INFO, -+ "wlanoidSetP2pMode 0x%p %d %d\n", &rSetP2P, rSetP2P.u4Enable, rSetP2P.u4Mode); -+ rWlanStatus = kalIoctl(prGlueInfo, wlanoidSetP2pMode, -+ (PVOID)&rSetP2P, /* pu4IntBuf[0] is used as input SubCmd */ -+ sizeof(PARAM_CUSTOM_P2P_SET_STRUCT_T), -+ FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ DBGLOG(P2P, INFO, "wlanoidSetP2pMode ok\n"); -+ -+ /* move out to caller to avoid kalIoctrl & suspend/resume deadlock problem ALPS00844864 */ -+ if ((rSetP2P.u4Enable) && (g_u4HaltFlag == 0) && (fgIsResetting == FALSE)) { -+ /* fgIsP2PRegistered == TRUE means P2P on successfully */ -+ p2pEalySuspendReg(prGlueInfo, rSetP2P.u4Enable); /* p2p on */ -+ } -+ -+ if (rSetP2P.u4Enable) -+ p2pNetRegister(prGlueInfo, TRUE); -+ -+ GLUE_ACQUIRE_THE_SPIN_LOCK(&g_p2p_lock); -+ g_u4P2POnOffing = 0; -+ GLUE_RELEASE_THE_SPIN_LOCK(&g_p2p_lock); -+#endif -+ } -+ break; -+#endif -+ -+#if (CFG_SUPPORT_MET_PROFILING == 1) -+ case PRIV_CMD_MET_PROFILING: -+ { -+ /* PARAM_CUSTOM_WFD_DEBUG_STRUCT_T rWfdDebugModeInfo; */ -+ /* rWfdDebugModeInfo.ucWFDDebugMode=(UINT_8)pu4IntBuf[1]; */ -+ /* rWfdDebugModeInfo.u2SNPeriod=(UINT_16)pu4IntBuf[2]; */ -+ /* DBGLOG(REQ, INFO,("WFD Debug Mode:%d Period:%d\n", -+ rWfdDebugModeInfo.ucWFDDebugMode,rWfdDebugModeInfo.u2SNPeriod)); */ -+ prGlueInfo->u8MetProfEnable = (UINT_8) pu4IntBuf[1]; -+ prGlueInfo->u16MetUdpPort = (UINT_16) pu4IntBuf[2]; -+ DBGLOG(REQ, INFO, "MET_PROF: Enable=%d UDP_PORT=%d\n", prGlueInfo->u8MetProfEnable, -+ prGlueInfo->u16MetUdpPort); -+ -+ } -+ break; -+ -+#endif -+ case PRIV_CMD_WFD_DEBUG_CODE: -+ { -+ PARAM_CUSTOM_WFD_DEBUG_STRUCT_T rWfdDebugModeInfo; -+ -+ rWfdDebugModeInfo.ucWFDDebugMode = (UINT_8) pu4IntBuf[1]; -+ rWfdDebugModeInfo.u2SNPeriod = (UINT_16) pu4IntBuf[2]; -+ DBGLOG(REQ, INFO, "WFD Debug Mode:%d Period:%d\n", rWfdDebugModeInfo.ucWFDDebugMode, -+ rWfdDebugModeInfo.u2SNPeriod); -+ kalIoctl(prGlueInfo, wlanoidSetWfdDebugMode, (PVOID)&rWfdDebugModeInfo, -+ sizeof(PARAM_CUSTOM_WFD_DEBUG_STRUCT_T), FALSE, FALSE, TRUE, FALSE, &u4BufLen); -+ -+ } -+ break; -+ default: -+ return -EOPNOTSUPP; -+ } -+ -+ return status; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Private ioctl get int handler. -+* -+* \param[in] pDev Net device requested. -+* \param[out] pIwReq Pointer to iwreq structure. -+* \param[in] prIwReqData The ioctl req structure, use the field of sub-command. -+* \param[out] pcExtra The buffer with put the return value -+* -+* \retval 0 For success. -+* \retval -EOPNOTSUPP If cmd is not supported. -+* \retval -EFAULT For fail. -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT_8 gucBufDbgCode[1000]; -+ -+static int -+_priv_get_int(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN OUT char *pcExtra) -+{ -+ UINT_32 u4SubCmd; -+ PUINT_32 pu4IntBuf; -+ P_GLUE_INFO_T prGlueInfo; -+ UINT_32 u4BufLen = 0; -+ int status = 0; -+ P_NDIS_TRANSPORT_STRUCT prNdisReq; -+ -+ ASSERT(prNetDev); -+ ASSERT(prIwReqInfo); -+ ASSERT(prIwReqData); -+ ASSERT(pcExtra); -+ if (FALSE == GLUE_CHK_PR3(prNetDev, prIwReqData, pcExtra)) -+ return -EINVAL; -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); -+ -+ u4SubCmd = (UINT_32) prIwReqData->mode; -+ pu4IntBuf = (PUINT_32) pcExtra; -+ -+ switch (u4SubCmd) { -+ case PRIV_CMD_TEST_CMD: -+ /* printk("CMD=0x%08lx, data=0x%08lx\n", pu4IntBuf[1], pu4IntBuf[2]); */ -+ prNdisReq = (P_NDIS_TRANSPORT_STRUCT) &aucOidBuf[0]; -+ -+ kalMemCopy(&prNdisReq->ndisOidContent[0], &pu4IntBuf[1], 8); -+ -+ prNdisReq->ndisOidCmd = OID_CUSTOM_MTK_WIFI_TEST; -+ prNdisReq->inNdisOidlength = 8; -+ prNdisReq->outNdisOidLength = 8; -+ -+ status = priv_get_ndis(prNetDev, prNdisReq, &u4BufLen); -+ if (status == 0) { -+ /* printk("Result=%ld\n", *(PUINT_32)&prNdisReq->ndisOidContent[4]); */ -+ prIwReqData->mode = *(PUINT_32) &prNdisReq->ndisOidContent[4]; -+ /* -+ if (copy_to_user(prIwReqData->data.pointer, -+ &prNdisReq->ndisOidContent[4], 4)) { -+ printk(KERN_NOTICE "priv_get_int() copy_to_user oidBuf fail(3)\n"); -+ return -EFAULT; -+ } -+ */ -+ } -+ return status; -+ -+#if CFG_SUPPORT_PRIV_MCR_RW -+ case PRIV_CMD_ACCESS_MCR: -+ /* printk("addr=0x%08lx\n", pu4IntBuf[1]); */ -+ prNdisReq = (P_NDIS_TRANSPORT_STRUCT) &aucOidBuf[0]; -+ -+ if (!prGlueInfo->fgMcrAccessAllowed) { -+ status = 0; -+ return status; -+ } -+ -+ kalMemCopy(&prNdisReq->ndisOidContent[0], &pu4IntBuf[1], 8); -+ -+ prNdisReq->ndisOidCmd = OID_CUSTOM_MCR_RW; -+ prNdisReq->inNdisOidlength = 8; -+ prNdisReq->outNdisOidLength = 8; -+ -+ status = priv_get_ndis(prNetDev, prNdisReq, &u4BufLen); -+ if (status == 0) { -+ /* printk("Result=%ld\n", *(PUINT_32)&prNdisReq->ndisOidContent[4]); */ -+ prIwReqData->mode = *(PUINT_32) &prNdisReq->ndisOidContent[4]; -+ } -+ return status; -+#endif -+ -+ case PRIV_CMD_DUMP_MEM: -+ prNdisReq = (P_NDIS_TRANSPORT_STRUCT) &aucOidBuf[0]; -+ -+#if 1 -+ if (!prGlueInfo->fgMcrAccessAllowed) { -+ status = 0; -+ return status; -+ } -+#endif -+ kalMemCopy(&prNdisReq->ndisOidContent[0], &pu4IntBuf[1], 8); -+ -+ prNdisReq->ndisOidCmd = OID_CUSTOM_MEM_DUMP; -+ prNdisReq->inNdisOidlength = 8; -+ prNdisReq->outNdisOidLength = 8; -+ -+ status = priv_get_ndis(prNetDev, prNdisReq, &u4BufLen); -+ if (status == 0) -+ prIwReqData->mode = *(PUINT_32) &prNdisReq->ndisOidContent[0]; -+ return status; -+ -+ case PRIV_CMD_SW_CTRL: -+ /* printk(" addr=0x%08lx\n", pu4IntBuf[1]); */ -+ -+ prNdisReq = (P_NDIS_TRANSPORT_STRUCT) &aucOidBuf[0]; -+ -+ kalMemCopy(&prNdisReq->ndisOidContent[0], &pu4IntBuf[1], 8); -+ -+ prNdisReq->ndisOidCmd = OID_CUSTOM_SW_CTRL; -+ prNdisReq->inNdisOidlength = 8; -+ prNdisReq->outNdisOidLength = 8; -+ -+ status = priv_get_ndis(prNetDev, prNdisReq, &u4BufLen); -+ if (status == 0) { -+ /* printk("Result=%ld\n", *(PUINT_32)&prNdisReq->ndisOidContent[4]); */ -+ prIwReqData->mode = *(PUINT_32) &prNdisReq->ndisOidContent[4]; -+ } -+ return status; -+ -+#if 0 -+ case PRIV_CMD_BEACON_PERIOD: -+ status = wlanQueryInformation(prGlueInfo->prAdapter, -+ wlanoidQueryBeaconInterval, -+ (PVOID) pu4IntBuf, sizeof(UINT_32), &u4BufLen); -+ return status; -+ -+ case PRIV_CMD_POWER_MODE: -+ status = wlanQueryInformation(prGlueInfo->prAdapter, -+ wlanoidQuery802dot11PowerSaveProfile, -+ (PVOID) pu4IntBuf, sizeof(UINT_32), &u4BufLen); -+ return status; -+ -+ case PRIV_CMD_ADHOC_MODE: -+ status = wlanQueryInformation(prGlueInfo->prAdapter, -+ wlanoidQueryAdHocMode, (PVOID) pu4IntBuf, sizeof(UINT_32), &u4BufLen); -+ return status; -+#endif -+ -+ case PRIV_CMD_BAND_CONFIG: -+ DBGLOG(REQ, INFO, "CMD get_band=\n"); -+ prIwReqData->mode = 0; -+ return status; -+ -+ default: -+ break; -+ } -+ -+ u4SubCmd = (UINT_32) prIwReqData->data.flags; -+ -+ switch (u4SubCmd) { -+ case PRIV_CMD_GET_CH_LIST: -+ { -+ UINT_16 i, j = 0; -+ UINT_8 NumOfChannel = 50; -+ UINT_8 ucMaxChannelNum = 50; -+ INT_32 ch[50]; -+ /*RF_CHANNEL_INFO_T aucChannelList[50];*/ -+ P_RF_CHANNEL_INFO_T paucChannelList; -+ P_RF_CHANNEL_INFO_T ChannelList_t; -+ -+ paucChannelList = kalMemAlloc(sizeof(RF_CHANNEL_INFO_T) * 50, VIR_MEM_TYPE); -+ if (paucChannelList == NULL) { -+ DBGLOG(REQ, INFO, "alloc ChannelList fail\n"); -+ return -EFAULT; -+ } -+ kalMemZero(paucChannelList, sizeof(RF_CHANNEL_INFO_T) * 50); -+ kalGetChannelList(prGlueInfo, BAND_NULL, ucMaxChannelNum, &NumOfChannel, paucChannelList); -+ if (NumOfChannel > 50) { -+ ASSERT(0); -+ NumOfChannel = 50; -+ } -+ -+ ChannelList_t = paucChannelList; -+ if (kalIsAPmode(prGlueInfo)) { -+ for (i = 0; i < NumOfChannel; i++) { -+ if ((ChannelList_t->ucChannelNum <= 13) -+ || (ChannelList_t->ucChannelNum == 36 -+ || ChannelList_t->ucChannelNum == 40 -+ || ChannelList_t->ucChannelNum == 44 -+ || ChannelList_t->ucChannelNum == 48)) { -+ ch[j] = (INT_32) ChannelList_t->ucChannelNum; -+ ChannelList_t++; -+ j++; -+ } -+ } -+ } else { -+ for (j = 0; j < NumOfChannel; j++) { -+ ch[j] = (INT_32) ChannelList_t->ucChannelNum; -+ ChannelList_t++; -+ } -+ } -+ -+ kalMemFree(paucChannelList, VIR_MEM_TYPE, sizeof(RF_CHANNEL_INFO_T) * 50); -+ -+ prIwReqData->data.length = j; -+ if (copy_to_user(prIwReqData->data.pointer, ch, NumOfChannel * sizeof(INT_32))) -+ return -EFAULT; -+ else -+ return status; -+ } -+ -+ case PRIV_CMD_GET_BUILD_DATE_CODE: -+ { -+ UINT_8 aucBuffer[16]; -+ -+ if (kalIoctl(prGlueInfo, -+ wlanoidQueryBuildDateCode, -+ (PVOID) aucBuffer, -+ sizeof(UINT_8) * 16, TRUE, TRUE, TRUE, FALSE, &u4BufLen) == WLAN_STATUS_SUCCESS) { -+ prIwReqData->data.length = sizeof(UINT_8) * 16; -+ -+ if (copy_to_user(prIwReqData->data.pointer, aucBuffer, prIwReqData->data.length)) -+ return -EFAULT; -+ else -+ return status; -+ } else { -+ return -EFAULT; -+ } -+ } -+ -+ case PRIV_CMD_GET_DEBUG_CODE: -+ { -+ wlanQueryDebugCode(prGlueInfo->prAdapter); -+ -+ kalMemSet(gucBufDbgCode, '.', sizeof(gucBufDbgCode)); -+ if (copy_to_user(prIwReqData->data.pointer, gucBufDbgCode, prIwReqData->data.length)) -+ return -EFAULT; -+ else -+ return status; -+ } -+ -+ default: -+ return -EOPNOTSUPP; -+ } -+ -+ return status; -+} /* priv_get_int */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Private ioctl set int array handler. -+* -+* \param[in] prNetDev Net device requested. -+* \param[in] prIwReqInfo Pointer to iwreq structure. -+* \param[in] prIwReqData The ioctl data structure, use the field of sub-command. -+* \param[in] pcExtra The buffer with input value -+* -+* \retval 0 For success. -+* \retval -EOPNOTSUPP If cmd is not supported. -+* \retval -EINVAL If a value is out of range. -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static int -+_priv_set_ints(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN char *pcExtra) -+{ -+ UINT_32 u4SubCmd, u4BufLen; -+ P_GLUE_INFO_T prGlueInfo; -+ int status = 0; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ P_SET_TXPWR_CTRL_T prTxpwr; -+ -+ ASSERT(prNetDev); -+ ASSERT(prIwReqInfo); -+ ASSERT(prIwReqData); -+ ASSERT(pcExtra); -+ -+ if (FALSE == GLUE_CHK_PR3(prNetDev, prIwReqData, pcExtra)) -+ return -EINVAL; -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); -+ -+ u4SubCmd = (UINT_32) prIwReqData->data.flags; -+ -+ switch (u4SubCmd) { -+ case PRIV_CMD_SET_TX_POWER: -+ { -+ INT_32 *setting = prIwReqData->data.pointer; -+ UINT_16 i; -+ -+#if 0 -+ DBGLOG(REQ, INFO, "Tx power num = %d\n", prIwReqData->data.length); -+ -+ DBGLOG(REQ, INFO, "Tx power setting = %d %d %d %d\n", -+ setting[0], setting[1], setting[2], setting[3]); -+#endif -+ prTxpwr = &prGlueInfo->rTxPwr; -+ if (setting[0] == 0 && prIwReqData->data.length == 4 /* argc num */) { -+ /* 0 (All networks), 1 (legacy STA), 2 (Hotspot AP), 3 (P2P), 4 (BT over Wi-Fi) */ -+ if (setting[1] == 1 || setting[1] == 0) { -+ if (setting[2] == 0 || setting[2] == 1) -+ prTxpwr->c2GLegacyStaPwrOffset = setting[3]; -+ if (setting[2] == 0 || setting[2] == 2) -+ prTxpwr->c5GLegacyStaPwrOffset = setting[3]; -+ } -+ if (setting[1] == 2 || setting[1] == 0) { -+ if (setting[2] == 0 || setting[2] == 1) -+ prTxpwr->c2GHotspotPwrOffset = setting[3]; -+ if (setting[2] == 0 || setting[2] == 2) -+ prTxpwr->c5GHotspotPwrOffset = setting[3]; -+ } -+ if (setting[1] == 3 || setting[1] == 0) { -+ if (setting[2] == 0 || setting[2] == 1) -+ prTxpwr->c2GP2pPwrOffset = setting[3]; -+ if (setting[2] == 0 || setting[2] == 2) -+ prTxpwr->c5GP2pPwrOffset = setting[3]; -+ } -+ if (setting[1] == 4 || setting[1] == 0) { -+ if (setting[2] == 0 || setting[2] == 1) -+ prTxpwr->c2GBowPwrOffset = setting[3]; -+ if (setting[2] == 0 || setting[2] == 2) -+ prTxpwr->c5GBowPwrOffset = setting[3]; -+ } -+ } else if (setting[0] == 1 && prIwReqData->data.length == 2) { -+ prTxpwr->ucConcurrencePolicy = setting[1]; -+ } else if (setting[0] == 2 && prIwReqData->data.length == 3) { -+ if (setting[1] == 0) { -+ for (i = 0; i < 14; i++) -+ prTxpwr->acTxPwrLimit2G[i] = setting[2]; -+ } else if (setting[1] <= 14) -+ prTxpwr->acTxPwrLimit2G[setting[1] - 1] = setting[2]; -+ } else if (setting[0] == 3 && prIwReqData->data.length == 3) { -+ if (setting[1] == 0) { -+ for (i = 0; i < 4; i++) -+ prTxpwr->acTxPwrLimit5G[i] = setting[2]; -+ } else if (setting[1] <= 4) -+ prTxpwr->acTxPwrLimit5G[setting[1] - 1] = setting[2]; -+ } else if (setting[0] == 4 && prIwReqData->data.length == 2) { -+ if (setting[1] == 0) -+ wlanDefTxPowerCfg(prGlueInfo->prAdapter); -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetTxPower, -+ prTxpwr, -+ sizeof(SET_TXPWR_CTRL_T), TRUE, FALSE, FALSE, FALSE, &u4BufLen); -+ } else -+ return -EFAULT; -+ } -+ return status; -+ default: -+ break; -+ } -+ -+ return status; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Private ioctl get int array handler. -+* -+* \param[in] pDev Net device requested. -+* \param[out] pIwReq Pointer to iwreq structure. -+* \param[in] prIwReqData The ioctl req structure, use the field of sub-command. -+* \param[out] pcExtra The buffer with put the return value -+* -+* \retval 0 For success. -+* \retval -EOPNOTSUPP If cmd is not supported. -+* \retval -EFAULT For fail. -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static int -+_priv_get_ints(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN OUT char *pcExtra) -+{ -+ UINT_32 u4SubCmd; -+ P_GLUE_INFO_T prGlueInfo; -+ int status = 0; -+ INT_32 ch[50]; -+ -+ ASSERT(prNetDev); -+ ASSERT(prIwReqInfo); -+ ASSERT(prIwReqData); -+ ASSERT(pcExtra); -+ if (FALSE == GLUE_CHK_PR3(prNetDev, prIwReqData, pcExtra)) -+ return -EINVAL; -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); -+ -+ u4SubCmd = (UINT_32) prIwReqData->data.flags; -+ -+ switch (u4SubCmd) { -+ case PRIV_CMD_GET_CH_LIST: -+ { -+ UINT_16 i; -+ UINT_8 NumOfChannel = 50; -+ UINT_8 ucMaxChannelNum = 50; -+ /*RF_CHANNEL_INFO_T aucChannelList[50];*/ -+ P_RF_CHANNEL_INFO_T paucChannelList; -+ P_RF_CHANNEL_INFO_T ChannelList_t; -+ -+ paucChannelList = kalMemAlloc(sizeof(RF_CHANNEL_INFO_T) * 50, VIR_MEM_TYPE); -+ if (paucChannelList == NULL) { -+ DBGLOG(REQ, INFO, "alloc fail\n"); -+ return -EINVAL; -+ } -+ kalMemZero(paucChannelList, sizeof(RF_CHANNEL_INFO_T) * 50); -+ -+ kalGetChannelList(prGlueInfo, BAND_NULL, ucMaxChannelNum, &NumOfChannel, paucChannelList); -+ if (NumOfChannel > 50) -+ NumOfChannel = 50; -+ -+ ChannelList_t = paucChannelList; -+ for (i = 0; i < NumOfChannel; i++) { -+ ch[i] = (INT_32) ChannelList_t->ucChannelNum; -+ ChannelList_t++; -+ } -+ -+ kalMemFree(paucChannelList, VIR_MEM_TYPE, sizeof(RF_CHANNEL_INFO_T) * 50); -+ prIwReqData->data.length = NumOfChannel; -+ if (copy_to_user(prIwReqData->data.pointer, ch, NumOfChannel * sizeof(INT_32))) -+ return -EFAULT; -+ else -+ return status; -+ } -+ default: -+ break; -+ } -+ -+ return status; -+} /* priv_get_int */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Private ioctl set structure handler. -+* -+* \param[in] pDev Net device requested. -+* \param[in] prIwReqData Pointer to iwreq_data structure. -+* -+* \retval 0 For success. -+* \retval -EOPNOTSUPP If cmd is not supported. -+* \retval -EINVAL If a value is out of range. -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static int -+_priv_set_struct(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN char *pcExtra) -+{ -+ UINT_32 u4SubCmd = 0; -+ int status = 0; -+ /* WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; */ -+ UINT_32 u4CmdLen = 0; -+ P_NDIS_TRANSPORT_STRUCT prNdisReq; -+ PUINT_32 pu4IntBuf = NULL; -+ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ UINT_32 u4BufLen = 0; -+ -+ ASSERT(prNetDev); -+ /* ASSERT(prIwReqInfo); */ -+ ASSERT(prIwReqData); -+ /* ASSERT(pcExtra); */ -+ -+ kalMemZero(&aucOidBuf[0], sizeof(aucOidBuf)); -+ -+ if (FALSE == GLUE_CHK_PR2(prNetDev, prIwReqData)) -+ return -EINVAL; -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); -+ -+ u4SubCmd = (UINT_32) prIwReqData->data.flags; -+ -+#if 0 -+ DBGLOG(REQ, INFO, "priv_set_struct(): prIwReqInfo->cmd(0x%X), u4SubCmd(%ld)\n", -+ prIwReqInfo->cmd, u4SubCmd); -+#endif -+ -+ switch (u4SubCmd) { -+#if 0 /* PTA_ENABLED */ -+ case PRIV_CMD_BT_COEXIST: -+ u4CmdLen = prIwReqData->data.length * sizeof(UINT_32); -+ ASSERT(sizeof(PARAM_CUSTOM_BT_COEXIST_T) >= u4CmdLen); -+ if (sizeof(PARAM_CUSTOM_BT_COEXIST_T) < u4CmdLen) -+ return -EFAULT; -+ -+ if (copy_from_user(&aucOidBuf[0], prIwReqData->data.pointer, u4CmdLen)) { -+ status = -EFAULT; /* return -EFAULT; */ -+ break; -+ } -+ -+ rStatus = wlanSetInformation(prGlueInfo->prAdapter, -+ wlanoidSetBtCoexistCtrl, (PVOID)&aucOidBuf[0], u4CmdLen, &u4BufLen); -+ if (WLAN_STATUS_SUCCESS != rStatus) -+ status = -EFAULT; -+ break; -+#endif -+ -+ case PRIV_CUSTOM_BWCS_CMD: -+ u4CmdLen = prIwReqData->data.length * sizeof(UINT_32); -+ ASSERT(sizeof(PARAM_PTA_IPC_T) >= u4CmdLen); -+ if (sizeof(PARAM_PTA_IPC_T) < u4CmdLen) -+ return -EFAULT; -+#if CFG_SUPPORT_BCM && CFG_SUPPORT_BCM_BWCS && CFG_SUPPORT_BCM_BWCS_DEBUG -+ DBGLOG(REQ, INFO, -+ "ucCmdLen = %d, size of PTA_IPC_T = %d, prIwReqData->data = 0x%x.\n", u4CmdLen, -+ sizeof(PARAM_PTA_IPC_T), prIwReqData->data); -+ -+ DBGLOG(REQ, INFO, "priv_set_struct(): prIwReqInfo->cmd(0x%X), u4SubCmd(%u)\n", -+ prIwReqInfo->cmd, u4SubCmd); -+ -+ DBGLOG(REQ, INFO, "*pcExtra = 0x%x\n", *pcExtra); -+#endif -+ -+ if (copy_from_user(&aucOidBuf[0], prIwReqData->data.pointer, u4CmdLen)) { -+ status = -EFAULT; /* return -EFAULT; */ -+ break; -+ } -+#if CFG_SUPPORT_BCM && CFG_SUPPORT_BCM_BWCS && CFG_SUPPORT_BCM_BWCS_DEBUG -+ DBGLOG(REQ, INFO, "priv_set_struct(): BWCS CMD = %02x%02x%02x%02x\n", -+ aucOidBuf[2], aucOidBuf[3], aucOidBuf[4], aucOidBuf[5]); -+#endif -+ -+#if 0 -+ status = wlanSetInformation(prGlueInfo->prAdapter, -+ wlanoidSetBT, (PVOID)&aucOidBuf[0], u4CmdLen, &u4BufLen); -+#endif -+ -+#if 1 -+ status = wlanoidSetBT(prGlueInfo->prAdapter, (PVOID)&aucOidBuf[0], u4CmdLen, &u4BufLen); -+#endif -+ -+ if (WLAN_STATUS_SUCCESS != status) -+ status = -EFAULT; -+ -+ break; -+ -+#if CFG_SUPPORT_WPS2 -+ case PRIV_CMD_WSC_PROBE_REQ: -+ { -+ /* retrieve IE for Probe Request */ -+ if (prIwReqData->data.length > 0) { -+ if (copy_from_user(prGlueInfo->aucWSCIE, prIwReqData->data.pointer, -+ prIwReqData->data.length)) { -+ status = -EFAULT; -+ break; -+ } -+ prGlueInfo->u2WSCIELen = prIwReqData->data.length; -+ } else { -+ prGlueInfo->u2WSCIELen = 0; -+ } -+ } -+ break; -+#endif -+ case PRIV_CMD_OID: -+ if (copy_from_user(&aucOidBuf[0], prIwReqData->data.pointer, prIwReqData->data.length)) { -+ status = -EFAULT; -+ break; -+ } -+ if (!kalMemCmp(&aucOidBuf[0], pcExtra, prIwReqData->data.length)) -+ DBGLOG(REQ, INFO, "pcExtra buffer is valid\n"); -+ else -+ DBGLOG(REQ, INFO, "pcExtra 0x%p\n", pcExtra); -+ /* Execute this OID */ -+ status = priv_set_ndis(prNetDev, (P_NDIS_TRANSPORT_STRUCT) &aucOidBuf[0], &u4BufLen); -+ /* Copy result to user space */ -+ ((P_NDIS_TRANSPORT_STRUCT) &aucOidBuf[0])->outNdisOidLength = u4BufLen; -+ -+ if (copy_to_user(prIwReqData->data.pointer, -+ &aucOidBuf[0], OFFSET_OF(NDIS_TRANSPORT_STRUCT, ndisOidContent))) { -+ DBGLOG(REQ, INFO, "copy_to_user oidBuf fail\n"); -+ status = -EFAULT; -+ } -+ -+ break; -+ -+ case PRIV_CMD_SW_CTRL: -+ pu4IntBuf = (PUINT_32) prIwReqData->data.pointer; -+ prNdisReq = (P_NDIS_TRANSPORT_STRUCT) &aucOidBuf[0]; -+ -+ /* kalMemCopy(&prNdisReq->ndisOidContent[0], prIwReqData->data.pointer, 8); */ -+ if (copy_from_user(&prNdisReq->ndisOidContent[0], prIwReqData->data.pointer, -+ prIwReqData->data.length)) { -+ status = -EFAULT; -+ break; -+ } -+ prNdisReq->ndisOidCmd = OID_CUSTOM_SW_CTRL; -+ prNdisReq->inNdisOidlength = 8; -+ prNdisReq->outNdisOidLength = 8; -+ -+ /* Execute this OID */ -+ status = priv_set_ndis(prNetDev, prNdisReq, &u4BufLen); -+ break; -+ -+ default: -+ return -EOPNOTSUPP; -+ } -+ -+ return status; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Private ioctl get struct handler. -+* -+* \param[in] pDev Net device requested. -+* \param[out] pIwReq Pointer to iwreq structure. -+* \param[in] cmd Private sub-command. -+* -+* \retval 0 For success. -+* \retval -EFAULT If copy from user space buffer fail. -+* \retval -EOPNOTSUPP Parameter "cmd" not recognized. -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static int -+_priv_get_struct(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN OUT char *pcExtra) -+{ -+ UINT_32 u4SubCmd = 0; -+ P_NDIS_TRANSPORT_STRUCT prNdisReq = NULL; -+ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ UINT_32 u4BufLen = 0; -+ PUINT_32 pu4IntBuf = NULL; -+ int status = 0; -+ -+ kalMemZero(&aucOidBuf[0], sizeof(aucOidBuf)); -+ -+ ASSERT(prNetDev); -+ ASSERT(prIwReqData); -+ if (!prNetDev || !prIwReqData) { -+ DBGLOG(REQ, INFO, "priv_get_struct(): invalid param(0x%p, 0x%p)\n", prNetDev, prIwReqData); -+ return -EINVAL; -+ } -+ -+ u4SubCmd = (UINT_32) prIwReqData->data.flags; -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); -+ ASSERT(prGlueInfo); -+ if (!prGlueInfo) { -+ DBGLOG(REQ, INFO, "priv_get_struct(): invalid prGlueInfo(0x%p, 0x%p)\n", -+ prNetDev, *((P_GLUE_INFO_T *) netdev_priv(prNetDev))); -+ return -EINVAL; -+ } -+#if 0 -+ DBGLOG(REQ, INFO, "priv_get_struct(): prIwReqInfo->cmd(0x%X), u4SubCmd(%ld)\n", -+ prIwReqInfo->cmd, u4SubCmd); -+#endif -+ memset(aucOidBuf, 0, sizeof(aucOidBuf)); -+ -+ switch (u4SubCmd) { -+ case PRIV_CMD_OID: -+ if (copy_from_user(&aucOidBuf[0], prIwReqData->data.pointer, sizeof(NDIS_TRANSPORT_STRUCT))) { -+ DBGLOG(REQ, INFO, "priv_get_struct() copy_from_user oidBuf fail\n"); -+ return -EFAULT; -+ } -+ -+ prNdisReq = (P_NDIS_TRANSPORT_STRUCT) &aucOidBuf[0]; -+#if 0 -+ DBGLOG(REQ, INFO, "\n priv_get_struct cmd 0x%02x len:%d OID:0x%08x OID Len:%d\n", -+ cmd, pIwReq->u.data.length, ndisReq->ndisOidCmd, ndisReq->inNdisOidlength); -+#endif -+ if (priv_get_ndis(prNetDev, prNdisReq, &u4BufLen) == 0) { -+ prNdisReq->outNdisOidLength = u4BufLen; -+ if (copy_to_user(prIwReqData->data.pointer, -+ &aucOidBuf[0], -+ u4BufLen + sizeof(NDIS_TRANSPORT_STRUCT) - -+ sizeof(prNdisReq->ndisOidContent))) { -+ DBGLOG(REQ, INFO, "priv_get_struct() copy_to_user oidBuf fail(1)\n"); -+ return -EFAULT; -+ } -+ return 0; -+ } -+ prNdisReq->outNdisOidLength = u4BufLen; -+ if (copy_to_user(prIwReqData->data.pointer, -+ &aucOidBuf[0], OFFSET_OF(NDIS_TRANSPORT_STRUCT, ndisOidContent))) { -+ DBGLOG(REQ, INFO, "priv_get_struct() copy_to_user oidBuf fail(2)\n"); -+ } -+ return -EFAULT; -+ -+ case PRIV_CMD_SW_CTRL: -+ pu4IntBuf = (PUINT_32) prIwReqData->data.pointer; -+ prNdisReq = (P_NDIS_TRANSPORT_STRUCT) &aucOidBuf[0]; -+ -+ if (copy_from_user(&prNdisReq->ndisOidContent[0], prIwReqData->data.pointer, -+ prIwReqData->data.length)) { -+ DBGLOG(REQ, INFO, "priv_get_struct() copy_from_user oidBuf fail\n"); -+ return -EFAULT; -+ } -+ -+ prNdisReq->ndisOidCmd = OID_CUSTOM_SW_CTRL; -+ prNdisReq->inNdisOidlength = 8; -+ prNdisReq->outNdisOidLength = 8; -+ -+ status = priv_get_ndis(prNetDev, prNdisReq, &u4BufLen); -+ if (status == 0) { -+ prNdisReq->outNdisOidLength = u4BufLen; -+ /* printk("len=%d Result=%08lx\n", u4BufLen, *(PUINT_32)&prNdisReq->ndisOidContent[4]); */ -+ -+ if (copy_to_user(prIwReqData->data.pointer, -+ &prNdisReq->ndisOidContent[4], -+ 4 /* OFFSET_OF(NDIS_TRANSPORT_STRUCT, ndisOidContent) */)) { -+ DBGLOG(REQ, INFO, "priv_get_struct() copy_to_user oidBuf fail(2)\n"); -+ } -+ } -+ return 0; -+ -+ default: -+ DBGLOG(REQ, WARN, "get struct cmd:0x%x\n", u4SubCmd); -+ return -EOPNOTSUPP; -+ } -+} /* priv_get_struct */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief The routine handles a set operation for a single OID. -+* -+* \param[in] pDev Net device requested. -+* \param[in] ndisReq Ndis request OID information copy from user. -+* \param[out] outputLen_p If the call is successful, returns the number of -+* bytes written into the query buffer. If the -+* call failed due to invalid length of the query -+* buffer, returns the amount of storage needed.. -+* -+* \retval 0 On success. -+* \retval -EOPNOTSUPP If cmd is not supported. -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static int -+priv_set_ndis(IN struct net_device *prNetDev, IN NDIS_TRANSPORT_STRUCT * prNdisReq, OUT PUINT_32 pu4OutputLen) -+{ -+ P_WLAN_REQ_ENTRY prWlanReqEntry = NULL; -+ WLAN_STATUS status = WLAN_STATUS_SUCCESS; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ UINT_32 u4SetInfoLen = 0; -+ -+ ASSERT(prNetDev); -+ ASSERT(prNdisReq); -+ ASSERT(pu4OutputLen); -+ -+ if (!prNetDev || !prNdisReq || !pu4OutputLen) { -+ DBGLOG(REQ, INFO, "priv_set_ndis(): invalid param(0x%p, 0x%p, 0x%p)\n", -+ prNetDev, prNdisReq, pu4OutputLen); -+ return -EINVAL; -+ } -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); -+ ASSERT(prGlueInfo); -+ if (!prGlueInfo) { -+ DBGLOG(REQ, INFO, "priv_set_ndis(): invalid prGlueInfo(0x%p, 0x%p)\n", -+ prNetDev, *((P_GLUE_INFO_T *) netdev_priv(prNetDev))); -+ return -EINVAL; -+ } -+#if 0 -+ DBGLOG(REQ, INFO, "priv_set_ndis(): prNdisReq->ndisOidCmd(0x%lX)\n", prNdisReq->ndisOidCmd); -+#endif -+ -+ if (FALSE == reqSearchSupportedOidEntry(prNdisReq->ndisOidCmd, &prWlanReqEntry)) { -+ /* WARNLOG(("Set OID: 0x%08lx (unknown)\n", prNdisReq->ndisOidCmd)); */ -+ return -EOPNOTSUPP; -+ } -+ -+ if (NULL == prWlanReqEntry->pfOidSetHandler) { -+ /* WARNLOG(("Set %s: Null set handler\n", prWlanReqEntry->pucOidName)); */ -+ return -EOPNOTSUPP; -+ } -+#if 0 -+ DBGLOG(REQ, INFO, "priv_set_ndis(): %s\n", prWlanReqEntry->pucOidName); -+#endif -+ -+ if (prWlanReqEntry->fgSetBufLenChecking) { -+ if (prNdisReq->inNdisOidlength != prWlanReqEntry->u4InfoBufLen) { -+ DBGLOG(REQ, WARN, "Set %s: Invalid length (current=%u, needed=%u)\n", -+ prWlanReqEntry->pucOidName, -+ prNdisReq->inNdisOidlength, prWlanReqEntry->u4InfoBufLen); -+ -+ *pu4OutputLen = prWlanReqEntry->u4InfoBufLen; -+ return -EINVAL; -+ } -+ } -+ -+ if (prWlanReqEntry->eOidMethod == ENUM_OID_GLUE_ONLY) { -+ /* GLUE sw info only */ -+ status = prWlanReqEntry->pfOidSetHandler(prGlueInfo, -+ prNdisReq->ndisOidContent, -+ prNdisReq->inNdisOidlength, &u4SetInfoLen); -+ } else if (prWlanReqEntry->eOidMethod == ENUM_OID_GLUE_EXTENSION) { -+ /* multiple sw operations */ -+ status = prWlanReqEntry->pfOidSetHandler(prGlueInfo, -+ prNdisReq->ndisOidContent, -+ prNdisReq->inNdisOidlength, &u4SetInfoLen); -+ } else if (prWlanReqEntry->eOidMethod == ENUM_OID_DRIVER_CORE) { -+ /* driver core */ -+ -+ status = kalIoctl(prGlueInfo, -+ (PFN_OID_HANDLER_FUNC) prWlanReqEntry->pfOidSetHandler, -+ prNdisReq->ndisOidContent, -+ prNdisReq->inNdisOidlength, FALSE, FALSE, TRUE, FALSE, &u4SetInfoLen); -+ } else { -+ DBGLOG(REQ, INFO, "priv_set_ndis(): unsupported OID method:0x%x\n", prWlanReqEntry->eOidMethod); -+ return -EOPNOTSUPP; -+ } -+ -+ *pu4OutputLen = u4SetInfoLen; -+ -+ switch (status) { -+ case WLAN_STATUS_SUCCESS: -+ break; -+ -+ case WLAN_STATUS_INVALID_LENGTH: -+ /* WARNLOG(("Set %s: Invalid length (current=%ld, needed=%ld)\n", */ -+ /* prWlanReqEntry->pucOidName, */ -+ /* prNdisReq->inNdisOidlength, */ -+ /* u4SetInfoLen)); */ -+ break; -+ } -+ -+ if (WLAN_STATUS_SUCCESS != status) -+ return -EFAULT; -+ -+ return 0; -+} /* priv_set_ndis */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief The routine handles a query operation for a single OID. Basically we -+* return information about the current state of the OID in question. -+* -+* \param[in] pDev Net device requested. -+* \param[in] ndisReq Ndis request OID information copy from user. -+* \param[out] outputLen_p If the call is successful, returns the number of -+* bytes written into the query buffer. If the -+* call failed due to invalid length of the query -+* buffer, returns the amount of storage needed.. -+* -+* \retval 0 On success. -+* \retval -EOPNOTSUPP If cmd is not supported. -+* \retval -EINVAL invalid input parameters -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static int -+priv_get_ndis(IN struct net_device *prNetDev, IN NDIS_TRANSPORT_STRUCT * prNdisReq, OUT PUINT_32 pu4OutputLen) -+{ -+ P_WLAN_REQ_ENTRY prWlanReqEntry = NULL; -+ UINT_32 u4BufLen = 0; -+ WLAN_STATUS status = WLAN_STATUS_SUCCESS; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ -+ ASSERT(prNetDev); -+ ASSERT(prNdisReq); -+ ASSERT(pu4OutputLen); -+ -+ if (!prNetDev || !prNdisReq || !pu4OutputLen) { -+ DBGLOG(REQ, INFO, "priv_get_ndis(): invalid param(0x%p, 0x%p, 0x%p)\n", -+ prNetDev, prNdisReq, pu4OutputLen); -+ return -EINVAL; -+ } -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); -+ ASSERT(prGlueInfo); -+ if (!prGlueInfo) { -+ DBGLOG(REQ, INFO, "priv_get_ndis(): invalid prGlueInfo(0x%p, 0x%p)\n", -+ prNetDev, *((P_GLUE_INFO_T *) netdev_priv(prNetDev))); -+ return -EINVAL; -+ } -+#if 0 -+ DBGLOG(REQ, INFO, "priv_get_ndis(): prNdisReq->ndisOidCmd(0x%lX)\n", prNdisReq->ndisOidCmd); -+#endif -+ -+ if (FALSE == reqSearchSupportedOidEntry(prNdisReq->ndisOidCmd, &prWlanReqEntry)) { -+ /* WARNLOG(("Query OID: 0x%08lx (unknown)\n", prNdisReq->ndisOidCmd)); */ -+ return -EOPNOTSUPP; -+ } -+ -+ if (NULL == prWlanReqEntry->pfOidQueryHandler) { -+ /* WARNLOG(("Query %s: Null query handler\n", prWlanReqEntry->pucOidName)); */ -+ return -EOPNOTSUPP; -+ } -+#if 0 -+ DBGLOG(REQ, INFO, "priv_get_ndis(): %s\n", prWlanReqEntry->pucOidName); -+#endif -+ -+ if (prWlanReqEntry->fgQryBufLenChecking) { -+ if (prNdisReq->inNdisOidlength < prWlanReqEntry->u4InfoBufLen) { -+ /* Not enough room in InformationBuffer. Punt */ -+ /* WARNLOG(("Query %s: Buffer too short (current=%ld, needed=%ld)\n", */ -+ /* prWlanReqEntry->pucOidName, */ -+ /* prNdisReq->inNdisOidlength, */ -+ /* prWlanReqEntry->u4InfoBufLen)); */ -+ -+ *pu4OutputLen = prWlanReqEntry->u4InfoBufLen; -+ -+ status = WLAN_STATUS_INVALID_LENGTH; -+ return -EINVAL; -+ } -+ } -+ -+ if (prWlanReqEntry->eOidMethod == ENUM_OID_GLUE_ONLY) { -+ /* GLUE sw info only */ -+ status = prWlanReqEntry->pfOidQueryHandler(prGlueInfo, -+ prNdisReq->ndisOidContent, -+ prNdisReq->inNdisOidlength, &u4BufLen); -+ } else if (prWlanReqEntry->eOidMethod == ENUM_OID_GLUE_EXTENSION) { -+ /* multiple sw operations */ -+ status = prWlanReqEntry->pfOidQueryHandler(prGlueInfo, -+ prNdisReq->ndisOidContent, -+ prNdisReq->inNdisOidlength, &u4BufLen); -+ } else if (prWlanReqEntry->eOidMethod == ENUM_OID_DRIVER_CORE) { -+ /* driver core */ -+ -+ status = kalIoctl(prGlueInfo, -+ (PFN_OID_HANDLER_FUNC) prWlanReqEntry->pfOidQueryHandler, -+ prNdisReq->ndisOidContent, -+ prNdisReq->inNdisOidlength, TRUE, TRUE, TRUE, FALSE, &u4BufLen); -+ } else { -+ DBGLOG(REQ, INFO, "priv_set_ndis(): unsupported OID method:0x%x\n", prWlanReqEntry->eOidMethod); -+ return -EOPNOTSUPP; -+ } -+ -+ *pu4OutputLen = u4BufLen; -+ -+ switch (status) { -+ case WLAN_STATUS_SUCCESS: -+ break; -+ -+ case WLAN_STATUS_INVALID_LENGTH: -+ /* WARNLOG(("Set %s: Invalid length (current=%ld, needed=%ld)\n", */ -+ /* prWlanReqEntry->pucOidName, */ -+ /* prNdisReq->inNdisOidlength, */ -+ /* u4BufLen)); */ -+ break; -+ } -+ -+ if (WLAN_STATUS_SUCCESS != status) -+ return -EOPNOTSUPP; -+ -+ return 0; -+} /* priv_get_ndis */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Parse command value in a string. -+* -+* @param InStr Pointer to the string buffer. -+* @param OutStr Pointer to the next command value. -+* @param OutLen Record the resident buffer length. -+* -+* @retval Command value. -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT_32 CmdStringDecParse(IN UINT_8 *InStr, OUT UINT_8 **OutStr, OUT UINT_32 *OutLen) -+{ -+ unsigned char Charc, *Buf; -+ unsigned int Num; -+ int Maxloop; -+ int ReadId; -+ int TotalLen; -+ -+ /* init */ -+ Num = 0; -+ Maxloop = 0; -+ ReadId = 0; -+ Buf = (unsigned char *)InStr; -+ TotalLen = *OutLen; -+ *OutStr = Buf; -+ -+ /* sanity check */ -+ if (Buf[0] == 0x00) -+ return 0; -+ -+ /* check the value is decimal or hex */ -+ if ((Buf[ReadId] == 'x') || ((Buf[ReadId] == '0') && (Buf[ReadId + 1] == 'x'))) { -+ /* skip x or 0x */ -+ if (Buf[ReadId] == 'x') -+ ReadId++; -+ else -+ ReadId += 2; -+ -+ /* translate the hex number */ -+ while (Maxloop++ < 10) { -+ Charc = Buf[ReadId]; -+ if ((Charc >= 0x30) && (Charc <= 0x39)) -+ Charc -= 0x30; -+ else if ((Charc >= 'a') && (Charc <= 'f')) -+ Charc -= 'a'; -+ else if ((Charc >= 'A') && (Charc <= 'F')) -+ Charc -= 'A'; -+ else -+ break; /* exit the parsing */ -+ Num = Num * 16 + Charc + 10; -+ ReadId++; -+ TotalLen--; -+ } -+ } else { -+ /* translate the decimal number */ -+ while (Maxloop++ < 10) { -+ Charc = Buf[ReadId]; -+ if ((Charc < 0x30) || (Charc > 0x39)) -+ break; /* exit the parsing */ -+ Charc -= 0x30; -+ Num = Num * 10 + Charc; -+ ReadId++; -+ TotalLen--; -+ } -+ } -+ -+ if (Buf[ReadId] == 0x00) -+ *OutStr = &Buf[ReadId]; -+ else -+ *OutStr = &Buf[ReadId + 1]; /* skip the character: _ */ -+ -+ *OutLen = TotalLen - 1; /* skip the character: _ */ -+ return Num; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* @brief Parse command MAC address in a string. -+* -+* @param InStr Pointer to the string buffer. -+* @param OutStr Pointer to the next command value. -+* @param OutLen Record the resident buffer length. -+* -+* @retval Command value. -+*/ -+/*----------------------------------------------------------------------------*/ -+UINT_32 CmdStringMacParse(IN UINT_8 *InStr, OUT UINT_8 **OutStr, OUT UINT_32 *OutLen, OUT UINT_8 *OutMac) -+{ -+ unsigned char Charc, *Buf; -+ unsigned int Num; -+ int Maxloop; -+ int ReadId; -+ int TotalLen; -+ -+ /* init */ -+ Num = 0; -+ Maxloop = 0; -+ ReadId = 0; -+ Buf = (unsigned char *)InStr; -+ TotalLen = *OutLen; -+ *OutStr = Buf; -+ -+ /* sanity check */ -+ if (Buf[0] == 0x00) -+ return 0; -+ -+ /* parse MAC */ -+ while (Maxloop < 6) { -+ Charc = Buf[ReadId]; -+ if ((Charc >= 0x30) && (Charc <= 0x39)) -+ Charc -= 0x30; -+ else if ((Charc >= 'a') && (Charc <= 'f')) -+ Charc = Charc - 'a' + 10; -+ else if ((Charc >= 'A') && (Charc <= 'F')) -+ Charc = Charc - 'A' + 10; -+ else -+ return -1; /* error, exit the parsing */ -+ -+ Num = Charc; -+ ReadId++; -+ TotalLen--; -+ -+ Charc = Buf[ReadId]; -+ if ((Charc >= 0x30) && (Charc <= 0x39)) -+ Charc -= 0x30; -+ else if ((Charc >= 'a') && (Charc <= 'f')) -+ Charc = Charc - 'a' + 10; -+ else if ((Charc >= 'A') && (Charc <= 'F')) -+ Charc = Charc - 'A' + 10; -+ else -+ return -1; /* error, exit the parsing */ -+ -+ Num = Num * 16 + Charc; -+ ReadId += 2; /* skip the character and ':' */ -+ TotalLen -= 2; -+ -+ OutMac[Maxloop] = Num; -+ Maxloop++; -+ } -+ -+ *OutStr = &Buf[ReadId]; /* skip the character: _ */ -+ *OutLen = TotalLen; /* skip the character: _ */ -+ return Num; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief The routine handles a set operation for a single OID. -+* -+* \param[in] pDev Net device requested. -+* \param[in] ndisReq Ndis request OID information copy from user. -+* \param[out] outputLen_p If the call is successful, returns the number of -+* bytes written into the query buffer. If the -+* call failed due to invalid length of the query -+* buffer, returns the amount of storage needed.. -+* -+* \retval 0 On success. -+* \retval -EOPNOTSUPP If cmd is not supported. -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static int -+_priv_set_string(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN char *pcExtra) -+{ -+ P_GLUE_INFO_T GlueInfo; -+ INT_32 Status; -+ UINT_32 Subcmd; -+ UINT_8 *InBuf; -+ UINT_32 InBufLen; -+ -+ /* sanity check */ -+ ASSERT(prNetDev); -+ ASSERT(prIwReqInfo); -+ ASSERT(prIwReqData); -+ ASSERT(pcExtra); -+ -+ /* init */ -+ DBGLOG(REQ, INFO, "priv_set_string (%s)(%d)\n", -+ (UINT8 *) prIwReqData->data.pointer, (INT32) prIwReqData->data.length); -+ -+ if (FALSE == GLUE_CHK_PR3(prNetDev, prIwReqData, pcExtra)) -+ return -EINVAL; -+ GlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); -+ -+ InBuf = aucOidBuf; -+ InBufLen = prIwReqData->data.length; -+ Status = 0; -+ -+ if (copy_from_user(InBuf, prIwReqData->data.pointer, prIwReqData->data.length)) -+ return -EFAULT; -+ -+ Subcmd = CmdStringDecParse(prIwReqData->data.pointer, &InBuf, &InBufLen); -+ DBGLOG(REQ, INFO, "priv_set_string> command = %u\n", (UINT32) Subcmd); -+ -+ /* handle the command */ -+ switch (Subcmd) { -+#if (CFG_SUPPORT_TDLS == 1) -+ case PRIV_CMD_OTHER_TDLS: -+ TdlsexCmd(GlueInfo, InBuf, InBufLen); -+ break; -+#endif /* CFG_SUPPORT_TDLS */ -+ -+#if (CFG_SUPPORT_TXR_ENC == 1) -+ case PRIV_CMD_OTHER_TAR: -+ { -+ rlmCmd(GlueInfo, InBuf, InBufLen); -+ break; -+ } -+#endif /* CFG_SUPPORT_TXR_ENC */ -+ default: -+ break; -+ } -+ -+ return Status; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to search desired OID. -+* -+* \param rOid[in] Desired NDIS_OID -+* \param ppWlanReqEntry[out] Found registered OID entry -+* -+* \retval TRUE: Matched OID is found -+* \retval FALSE: No matched OID is found -+*/ -+/*----------------------------------------------------------------------------*/ -+static BOOLEAN reqSearchSupportedOidEntry(IN UINT_32 rOid, OUT P_WLAN_REQ_ENTRY *ppWlanReqEntry) -+{ -+ INT_32 i, j, k; -+ -+ i = 0; -+ j = NUM_SUPPORTED_OIDS - 1; -+ -+ while (i <= j) { -+ k = (i + j) / 2; -+ -+ if (rOid == arWlanOidReqTable[k].rOid) { -+ *ppWlanReqEntry = &arWlanOidReqTable[k]; -+ return TRUE; -+ } else if (rOid < arWlanOidReqTable[k].rOid) { -+ j = k - 1; -+ } else { -+ i = k + 1; -+ } -+ } -+ -+ return FALSE; -+} /* reqSearchSupportedOidEntry */ -+ -+#if 0 -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to query the radio configuration used in IBSS -+* mode and RF test mode. -+* -+* \param[in] prGlueInfo Pointer to the GLUE_INFO_T structure. -+* \param[out] pvQueryBuffer Pointer to the buffer that holds the result of the query. -+* \param[in] u4QueryBufferLen The length of the query buffer. -+* \param[out] pu4QueryInfoLen If the call is successful, returns the number of -+* bytes written into the query buffer. If the call -+* failed due to invalid length of the query buffer, -+* returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+*/ -+/*----------------------------------------------------------------------------*/ -+static WLAN_STATUS -+reqExtQueryConfiguration(IN P_GLUE_INFO_T prGlueInfo, -+ OUT PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen) -+{ -+ P_PARAM_802_11_CONFIG_T prQueryConfig = (P_PARAM_802_11_CONFIG_T) pvQueryBuffer; -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ UINT_32 u4QueryInfoLen = 0; -+ -+ DEBUGFUNC("wlanoidQueryConfiguration"); -+ -+ ASSERT(prGlueInfo); -+ ASSERT(pu4QueryInfoLen); -+ -+ *pu4QueryInfoLen = sizeof(PARAM_802_11_CONFIG_T); -+ if (u4QueryBufferLen < sizeof(PARAM_802_11_CONFIG_T)) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ ASSERT(pvQueryBuffer); -+ -+ kalMemZero(prQueryConfig, sizeof(PARAM_802_11_CONFIG_T)); -+ -+ /* Update the current radio configuration. */ -+ prQueryConfig->u4Length = sizeof(PARAM_802_11_CONFIG_T); -+ -+#if defined(_HIF_SDIO) -+ rStatus = sdio_io_ctrl(prGlueInfo, -+ wlanoidSetBeaconInterval, -+ &prQueryConfig->u4BeaconPeriod, sizeof(UINT_32), TRUE, TRUE, &u4QueryInfoLen); -+#else -+ rStatus = wlanQueryInformation(prGlueInfo->prAdapter, -+ wlanoidQueryBeaconInterval, -+ &prQueryConfig->u4BeaconPeriod, sizeof(UINT_32), &u4QueryInfoLen); -+#endif -+ if (rStatus != WLAN_STATUS_SUCCESS) -+ return rStatus; -+#if defined(_HIF_SDIO) -+ rStatus = sdio_io_ctrl(prGlueInfo, -+ wlanoidQueryAtimWindow, -+ &prQueryConfig->u4ATIMWindow, sizeof(UINT_32), TRUE, TRUE, &u4QueryInfoLen); -+#else -+ rStatus = wlanQueryInformation(prGlueInfo->prAdapter, -+ wlanoidQueryAtimWindow, -+ &prQueryConfig->u4ATIMWindow, sizeof(UINT_32), &u4QueryInfoLen); -+#endif -+ if (rStatus != WLAN_STATUS_SUCCESS) -+ return rStatus; -+#if defined(_HIF_SDIO) -+ rStatus = sdio_io_ctrl(prGlueInfo, -+ wlanoidQueryFrequency, -+ &prQueryConfig->u4DSConfig, sizeof(UINT_32), TRUE, TRUE, &u4QueryInfoLen); -+#else -+ rStatus = wlanQueryInformation(prGlueInfo->prAdapter, -+ wlanoidQueryFrequency, -+ &prQueryConfig->u4DSConfig, sizeof(UINT_32), &u4QueryInfoLen); -+#endif -+ if (rStatus != WLAN_STATUS_SUCCESS) -+ return rStatus; -+ -+ prQueryConfig->rFHConfig.u4Length = sizeof(PARAM_802_11_CONFIG_FH_T); -+ -+ return rStatus; -+ -+} /* end of reqExtQueryConfiguration() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to set the radio configuration used in IBSS -+* mode. -+* -+* \param[in] prGlueInfo Pointer to the GLUE_INFO_T structure. -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set. -+* \param[in] u4SetBufferLen The length of the set buffer. -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed -+* due to invalid length of the set buffer, returns -+* the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_LENGTH -+* \retval WLAN_STATUS_NOT_ACCEPTED -+*/ -+/*----------------------------------------------------------------------------*/ -+static WLAN_STATUS -+reqExtSetConfiguration(IN P_GLUE_INFO_T prGlueInfo, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ P_PARAM_802_11_CONFIG_T prNewConfig = (P_PARAM_802_11_CONFIG_T) pvSetBuffer; -+ UINT_32 u4SetInfoLen = 0; -+ -+ DEBUGFUNC("wlanoidSetConfiguration"); -+ -+ ASSERT(prGlueInfo); -+ ASSERT(pu4SetInfoLen); -+ -+ *pu4SetInfoLen = sizeof(PARAM_802_11_CONFIG_T); -+ -+ if (u4SetBufferLen < *pu4SetInfoLen) -+ return WLAN_STATUS_INVALID_LENGTH; -+ -+ /* OID_802_11_CONFIGURATION. If associated, NOT_ACCEPTED shall be returned. */ -+ if (prGlueInfo->eParamMediaStateIndicated == PARAM_MEDIA_STATE_CONNECTED) -+ return WLAN_STATUS_NOT_ACCEPTED; -+ -+ ASSERT(pvSetBuffer); -+ -+#if defined(_HIF_SDIO) -+ rStatus = sdio_io_ctrl(prGlueInfo, -+ wlanoidSetBeaconInterval, -+ &prNewConfig->u4BeaconPeriod, sizeof(UINT_32), FALSE, TRUE, &u4SetInfoLen); -+#else -+ rStatus = wlanSetInformation(prGlueInfo->prAdapter, -+ wlanoidSetBeaconInterval, -+ &prNewConfig->u4BeaconPeriod, sizeof(UINT_32), &u4SetInfoLen); -+#endif -+ if (rStatus != WLAN_STATUS_SUCCESS) -+ return rStatus; -+#if defined(_HIF_SDIO) -+ rStatus = sdio_io_ctrl(prGlueInfo, -+ wlanoidSetAtimWindow, -+ &prNewConfig->u4ATIMWindow, sizeof(UINT_32), FALSE, TRUE, &u4SetInfoLen); -+#else -+ rStatus = wlanSetInformation(prGlueInfo->prAdapter, -+ wlanoidSetAtimWindow, &prNewConfig->u4ATIMWindow, sizeof(UINT_32), &u4SetInfoLen); -+#endif -+ if (rStatus != WLAN_STATUS_SUCCESS) -+ return rStatus; -+#if defined(_HIF_SDIO) -+ rStatus = sdio_io_ctrl(prGlueInfo, -+ wlanoidSetFrequency, -+ &prNewConfig->u4DSConfig, sizeof(UINT_32), FALSE, TRUE, &u4SetInfoLen); -+#else -+ rStatus = wlanSetInformation(prGlueInfo->prAdapter, -+ wlanoidSetFrequency, &prNewConfig->u4DSConfig, sizeof(UINT_32), &u4SetInfoLen); -+#endif -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) -+ return rStatus; -+ -+ return rStatus; -+ -+} /* end of reqExtSetConfiguration() */ -+ -+#endif -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This routine is called to set beacon detection function enable/disable state -+* This is mainly designed for usage under BT inquiry state (disable function). -+* -+* \param[in] pvAdapter Pointer to the Adapter structure -+* \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set -+* \param[in] u4SetBufferLen The length of the set buffer -+* \param[out] pu4SetInfoLen If the call is successful, returns the number of -+* bytes read from the set buffer. If the call failed due to invalid length of -+* the set buffer, returns the amount of storage needed. -+* -+* \retval WLAN_STATUS_SUCCESS -+* \retval WLAN_STATUS_INVALID_DATA If new setting value is wrong. -+* \retval WLAN_STATUS_INVALID_LENGTH -+* -+*/ -+/*----------------------------------------------------------------------------*/ -+static WLAN_STATUS -+reqExtSetAcpiDevicePowerState(IN P_GLUE_INFO_T prGlueInfo, -+ IN PVOID pvSetBuffer, IN UINT_32 u4SetBufferLen, OUT PUINT_32 pu4SetInfoLen) -+{ -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ -+ ASSERT(prGlueInfo); -+ ASSERT(pvSetBuffer); -+ ASSERT(pu4SetInfoLen); -+ -+ /* WIFI is enabled, when ACPI is D0 (ParamDeviceStateD0 = 1). And vice versa */ -+ -+ /* rStatus = wlanSetInformation(prGlueInfo->prAdapter, */ -+ /* wlanoidSetAcpiDevicePowerState, */ -+ /* pvSetBuffer, */ -+ /* u4SetBufferLen, */ -+ /* pu4SetInfoLen); */ -+ return rStatus; -+} -+ -+int priv_driver_set_chip_config(IN struct net_device *prNetDev, IN char *pcCommand, IN int i4TotalLen) -+{ -+ WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ P_ADAPTER_T prAdapter = NULL; -+ UINT_32 u4BufLen = 0; -+ INT_32 i4BytesWritten = 0; -+ UINT_32 u4CmdLen = 0; -+ UINT_32 u4PrefixLen = 0; -+ /* INT_32 i4Argc = 0; */ -+ /* PCHAR apcArgv[WLAN_CFG_ARGV_MAX] = {0}; */ -+ -+ PARAM_CUSTOM_CHIP_CONFIG_STRUCT_T rChipConfigInfo; -+ -+ ASSERT(prNetDev); -+ if (FALSE == GLUE_CHK_PR2(prNetDev, pcCommand)) -+ return -1; -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); -+ prAdapter = prGlueInfo->prAdapter; -+ DBGLOG(REQ, INFO, "priv_driver_set_chip_config command is %s\n", pcCommand); -+ /* wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); */ -+ /* DBGLOG(REQ, LOUD,("argc is %i\n",i4Argc)); */ -+ /* */ -+ u4CmdLen = kalStrnLen(pcCommand, i4TotalLen); -+ u4PrefixLen = kalStrLen(CMD_SET_CHIP) + 1 /*space */; -+ -+ kalMemZero(&rChipConfigInfo, sizeof(rChipConfigInfo)); -+ -+ /* if(i4Argc >= 2) { */ -+ if (u4CmdLen > u4PrefixLen) { -+ -+ rChipConfigInfo.ucType = CHIP_CONFIG_TYPE_WO_RESPONSE; -+ /* rChipConfigInfo.u2MsgSize = kalStrnLen(apcArgv[1],CHIP_CONFIG_RESP_SIZE); */ -+ rChipConfigInfo.u2MsgSize = u4CmdLen - u4PrefixLen; -+ /* kalStrnCpy(rChipConfigInfo.aucCmd,apcArgv[1],CHIP_CONFIG_RESP_SIZE); */ -+ if (u4PrefixLen <= CHIP_CONFIG_RESP_SIZE) { -+ kalStrnCpy(rChipConfigInfo.aucCmd, pcCommand + u4PrefixLen, -+ CHIP_CONFIG_RESP_SIZE - u4PrefixLen); -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetChipConfig, -+ &rChipConfigInfo, -+ sizeof(rChipConfigInfo), FALSE, FALSE, TRUE, TRUE, &u4BufLen); -+ } else { -+ -+ DBGLOG(REQ, INFO, "%s: kalIoctl Command Len > %d\n", __func__, CHIP_CONFIG_RESP_SIZE); -+ rStatus = WLAN_STATUS_FAILURE; -+ } -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) { -+ DBGLOG(REQ, INFO, "%s: kalIoctl ret=%d\n", __func__, rStatus); -+ i4BytesWritten = -1; -+ } -+ } -+ -+ return i4BytesWritten; -+ -+} -+ -+int priv_driver_set_miracast(IN struct net_device *prNetDev, IN char *pcCommand, IN int i4TotalLen) -+{ -+ P_ADAPTER_T prAdapter = NULL; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ UINT_32 i4BytesWritten = 0; -+ /* WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; */ -+ /* UINT_32 u4BufLen = 0; */ -+ INT_32 i4Argc = 0; -+ UINT_32 ucMode = 0; -+ P_WFD_CFG_SETTINGS_T prWfdCfgSettings = (P_WFD_CFG_SETTINGS_T) NULL; -+ P_MSG_WFD_CONFIG_SETTINGS_CHANGED_T prMsgWfdCfgUpdate = (P_MSG_WFD_CONFIG_SETTINGS_CHANGED_T) NULL; -+ PCHAR apcArgv[WLAN_CFG_ARGV_MAX]; -+ INT_32 u4Ret; -+ -+ ASSERT(prNetDev); -+ if (FALSE == GLUE_CHK_PR2(prNetDev, pcCommand)) -+ return -1; -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); -+ -+ DBGLOG(REQ, LOUD, "command is %s\n", pcCommand); -+ wlanCfgParseArgument(pcCommand, &i4Argc, apcArgv); -+ DBGLOG(REQ, LOUD, "argc is %i\n", i4Argc); -+ -+ prAdapter = prGlueInfo->prAdapter; -+ if (i4Argc >= 2) { -+ u4Ret = kalkStrtou32(apcArgv[1], 0, &ucMode); /* ucMode = kalStrtoul(apcArgv[1], NULL, 0); */ -+ if (u4Ret) -+ DBGLOG(REQ, LOUD, "parse pcCommand error u4Ret=%d\n", u4Ret); -+ -+ if (g_ucMiracastMode == ucMode) -+ ; -+ /* XXX: continue or skip */ -+ -+ g_ucMiracastMode = ucMode; -+ prMsgWfdCfgUpdate = cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_WFD_CONFIG_SETTINGS_CHANGED_T)); -+ -+ if (prMsgWfdCfgUpdate != NULL) { -+ -+ prWfdCfgSettings = &(prGlueInfo->prAdapter->rWifiVar.prP2pFsmInfo->rWfdConfigureSettings); -+ prMsgWfdCfgUpdate->rMsgHdr.eMsgId = MID_MNY_P2P_WFD_CFG_UPDATE; -+ prMsgWfdCfgUpdate->prWfdCfgSettings = prWfdCfgSettings; -+ -+ if (ucMode == MIRACAST_MODE_OFF) { -+ prWfdCfgSettings->ucWfdEnable = 0; -+ snprintf(pcCommand, i4TotalLen, CMD_SET_CHIP " mira 0"); -+ } else if (ucMode == MIRACAST_MODE_SOURCE) { -+ prWfdCfgSettings->ucWfdEnable = 1; -+ snprintf(pcCommand, i4TotalLen, CMD_SET_CHIP " mira 1"); -+ } else if (ucMode == MIRACAST_MODE_SINK) { -+ prWfdCfgSettings->ucWfdEnable = 2; -+ snprintf(pcCommand, i4TotalLen, CMD_SET_CHIP " mira 2"); -+ } else { -+ prWfdCfgSettings->ucWfdEnable = 0; -+ snprintf(pcCommand, i4TotalLen, CMD_SET_CHIP " mira 0"); -+ } -+ mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prMsgWfdCfgUpdate, MSG_SEND_METHOD_BUF); -+ -+ priv_driver_set_chip_config(prNetDev, pcCommand, i4TotalLen); -+ -+ } /* prMsgWfdCfgUpdate */ -+ else { -+ ASSERT(FALSE); -+ i4BytesWritten = -1; -+ } -+ } -+ -+ /* i4Argc */ -+ return i4BytesWritten; -+} -+ -+int priv_support_driver_cmd(IN struct net_device *prNetDev, IN OUT struct ifreq *prReq, IN int i4Cmd) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ int ret = 0; -+ char *pcCommand = NULL; -+ priv_driver_cmd_t *priv_cmd = NULL; -+ int i4BytesWritten = 0; -+ int i4TotalLen = 0; -+ -+ if (!prReq->ifr_data) { -+ ret = -EINVAL; -+ goto exit; -+ } -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); -+ -+ if (!prGlueInfo) { -+ DBGLOG(REQ, WARN, "No glue info\n"); -+ ret = -EFAULT; -+ goto exit; -+ } -+ if (prGlueInfo->u4ReadyFlag == 0) { -+ ret = -EINVAL; -+ goto exit; -+ } -+ -+ priv_cmd = kzalloc(sizeof(priv_driver_cmd_t), GFP_KERNEL); -+ if (!priv_cmd) { -+ DBGLOG(REQ, WARN, "%s, alloc mem failed\n", __func__); -+ return -ENOMEM; -+ } -+ -+ if (copy_from_user(priv_cmd, prReq->ifr_data, sizeof(priv_driver_cmd_t))) { -+ DBGLOG(REQ, INFO, "%s: copy_from_user fail\n", __func__); -+ ret = -EFAULT; -+ goto exit; -+ } -+ -+ i4TotalLen = priv_cmd->total_len; -+ -+ if (i4TotalLen <= 0) { -+ ret = -EINVAL; -+ DBGLOG(REQ, INFO, "%s: i4TotalLen invalid\n", __func__); -+ goto exit; -+ } -+ -+ pcCommand = priv_cmd->buf; -+ -+ DBGLOG(REQ, INFO, "%s: driver cmd \"%s\" on %s\n", __func__, pcCommand, prReq->ifr_name); -+ -+ i4BytesWritten = priv_driver_cmds(prNetDev, pcCommand, i4TotalLen); -+ -+ if (i4BytesWritten < 0) { -+ DBGLOG(REQ, INFO, "%s: command %s failed; Written is %d\n", -+ __func__, pcCommand, i4BytesWritten); -+ ret = -EFAULT; -+ } -+ -+exit: -+ kfree(priv_cmd); -+ -+ return ret; -+} -+ -+#if CFG_SUPPORT_BATCH_SCAN -+#define CMD_BATCH_SET "WLS_BATCHING SET" -+#define CMD_BATCH_GET "WLS_BATCHING GET" -+#define CMD_BATCH_STOP "WLS_BATCHING STOP" -+#endif -+ -+#if CFG_SUPPORT_GET_CH_ENV -+#define CMD_CH_ENV_GET "CH_ENV_GET" -+#endif -+ -+INT_32 priv_driver_cmds(IN struct net_device *prNetDev, IN PCHAR pcCommand, IN INT_32 i4TotalLen) -+{ -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ INT_32 i4BytesWritten = 0; -+ INT_32 i4CmdFound = 0; -+ -+ if (FALSE == GLUE_CHK_PR2(prNetDev, pcCommand)) -+ return -1; -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev)); -+ -+ if (i4CmdFound == 0) { -+ i4CmdFound = 1; -+ -+ if (strnicmp(pcCommand, CMD_MIRACAST, strlen(CMD_MIRACAST)) == 0) -+ i4BytesWritten = priv_driver_set_miracast(prNetDev, pcCommand, i4TotalLen); -+#if CFG_SUPPORT_BATCH_SCAN -+ else if (strnicmp(pcCommand, CMD_BATCH_SET, strlen(CMD_BATCH_SET)) == 0) { -+ kalIoctl(prGlueInfo, -+ wlanoidSetBatchScanReq, -+ (PVOID) pcCommand, i4TotalLen, FALSE, FALSE, TRUE, FALSE, &i4BytesWritten); -+ } else if (strnicmp(pcCommand, CMD_BATCH_GET, strlen(CMD_BATCH_GET)) == 0) { -+ /* strcpy(pcCommand, "BATCH SCAN DATA FROM FIRMWARE"); */ -+ /* i4BytesWritten = strlen("BATCH SCAN DATA FROM FIRMWARE") + 1; */ -+ /* i4BytesWritten = priv_driver_get_linkspeed (prNetDev, pcCommand, i4TotalLen); */ -+ -+ UINT_32 u4BufLen; -+ int i; -+ /* int rlen=0; */ -+ -+ for (i = 0; i < CFG_BATCH_MAX_MSCAN; i++) { -+ g_rEventBatchResult[i].ucScanCount = i + 1; /* for get which mscan */ -+ kalIoctl(prGlueInfo, -+ wlanoidQueryBatchScanResult, -+ (PVOID)&g_rEventBatchResult[i], -+ sizeof(EVENT_BATCH_RESULT_T), TRUE, TRUE, TRUE, FALSE, &u4BufLen); -+ } -+ -+#if 0 -+ DBGLOG(SCN, INFO, "Batch Scan Results, scan count = %u\n", g_rEventBatchResult.ucScanCount); -+ for (i = 0; i < g_rEventBatchResult.ucScanCount; i++) { -+ prEntry = &g_rEventBatchResult.arBatchResult[i]; -+ DBGLOG(SCN, INFO, "Entry %u\n", i); -+ DBGLOG(SCN, INFO, " BSSID = %pM\n", prEntry->aucBssid); -+ DBGLOG(SCN, INFO, " SSID = %s\n", prEntry->aucSSID); -+ DBGLOG(SCN, INFO, " SSID len = %u\n", prEntry->ucSSIDLen); -+ DBGLOG(SCN, INFO, " RSSI = %d\n", prEntry->cRssi); -+ DBGLOG(SCN, INFO, " Freq = %u\n", prEntry->ucFreq); -+ } -+#endif -+ -+ batchConvertResult(&g_rEventBatchResult[0], pcCommand, i4TotalLen, &i4BytesWritten); -+ -+ /* Dump for debug */ -+ /* print_hex_dump(KERN_INFO, "BATCH", DUMP_PREFIX_ADDRESS, 16, 1, pcCommand, -+ i4BytesWritten, TRUE); */ -+ -+ } else if (strnicmp(pcCommand, CMD_BATCH_STOP, strlen(CMD_BATCH_STOP)) == 0) { -+ kalIoctl(prGlueInfo, -+ wlanoidSetBatchScanReq, -+ (PVOID) pcCommand, i4TotalLen, FALSE, FALSE, TRUE, FALSE, &i4BytesWritten); -+ } -+#endif -+#if CFG_SUPPORT_GET_CH_ENV -+ else if (strnicmp(pcCommand, CMD_CH_ENV_GET, strlen(CMD_CH_ENV_GET)) == 0) -+ scanEnvResult(prGlueInfo, pcCommand, i4TotalLen, &i4BytesWritten); -+#endif -+ -+#if 0 -+ -+ else if (strnicmp(pcCommand, CMD_RSSI, strlen(CMD_RSSI)) == 0) { -+ /* i4BytesWritten = wl_android_get_rssi(net, command, i4TotalLen); */ -+ } else if (strnicmp(pcCommand, CMD_LINKSPEED, strlen(CMD_LINKSPEED)) == 0) { -+ i4BytesWritten = priv_driver_get_linkspeed(prNetDev, pcCommand, i4TotalLen); -+ } else if (strnicmp(pcCommand, CMD_PNOSSIDCLR_SET, strlen(CMD_PNOSSIDCLR_SET)) == 0) { -+ /* Do nothing */ -+ } else if (strnicmp(pcCommand, CMD_PNOSETUP_SET, strlen(CMD_PNOSETUP_SET)) == 0) { -+ /* Do nothing */ -+ } else if (strnicmp(pcCommand, CMD_PNOENABLE_SET, strlen(CMD_PNOENABLE_SET)) == 0) { -+ /* Do nothing */ -+ } else if (strnicmp(pcCommand, CMD_SETSUSPENDOPT, strlen(CMD_SETSUSPENDOPT)) == 0) { -+ /* i4BytesWritten = wl_android_set_suspendopt(net, pcCommand, i4TotalLen); */ -+ } else if (strnicmp(pcCommand, CMD_SETSUSPENDMODE, strlen(CMD_SETSUSPENDMODE)) == 0) { -+ i4BytesWritten = priv_driver_set_suspend_mode(prNetDev, pcCommand, i4TotalLen); -+ } else if (strnicmp(pcCommand, CMD_SETBAND, strlen(CMD_SETBAND)) == 0) { -+ i4BytesWritten = priv_driver_set_band(prNetDev, pcCommand, i4TotalLen); -+ } else if (strnicmp(pcCommand, CMD_GETBAND, strlen(CMD_GETBAND)) == 0) { -+ /* i4BytesWritten = wl_android_get_band(net, pcCommand, i4TotalLen); */ -+ } else if (strnicmp(pcCommand, CMD_COUNTRY, strlen(CMD_COUNTRY)) == 0) { -+ i4BytesWritten = priv_driver_set_country(prNetDev, pcCommand, i4TotalLen); -+ } -+ /* Mediatek private command */ -+ else if (strnicmp(pcCommand, CMD_SET_SW_CTRL, strlen(CMD_SET_SW_CTRL)) == 0) { -+ i4BytesWritten = priv_driver_set_sw_ctrl(prNetDev, pcCommand, i4TotalLen); -+ } else if (strnicmp(pcCommand, CMD_GET_SW_CTRL, strlen(CMD_GET_SW_CTRL)) == 0) { -+ i4BytesWritten = priv_driver_get_sw_ctrl(prNetDev, pcCommand, i4TotalLen); -+ } else if (strnicmp(pcCommand, CMD_SET_CFG, strlen(CMD_SET_CFG)) == 0) { -+ i4BytesWritten = priv_driver_set_cfg(prNetDev, pcCommand, i4TotalLen); -+ } else if (strnicmp(pcCommand, CMD_GET_CFG, strlen(CMD_GET_CFG)) == 0) { -+ i4BytesWritten = priv_driver_get_cfg(prNetDev, pcCommand, i4TotalLen); -+ } else if (strnicmp(pcCommand, CMD_SET_CHIP, strlen(CMD_SET_CHIP)) == 0) { -+ i4BytesWritten = priv_driver_set_chip_config(prNetDev, pcCommand, i4TotalLen); -+ } else if (strnicmp(pcCommand, CMD_GET_CHIP, strlen(CMD_GET_CHIP)) == 0) { -+ i4BytesWritten = priv_driver_get_chip_config(prNetDev, pcCommand, i4TotalLen); -+ } else if (strnicmp(pcCommand, CMD_SET_DBG_LEVEL, strlen(CMD_SET_DBG_LEVEL)) == 0) { -+ i4BytesWritten = priv_driver_set_dbg_level(prNetDev, pcCommand, i4TotalLen); -+ } else if (strnicmp(pcCommand, CMD_GET_DBG_LEVEL, strlen(CMD_GET_DBG_LEVEL)) == 0) { -+ i4BytesWritten = priv_driver_get_dbg_level(prNetDev, pcCommand, i4TotalLen); -+ } -+#if CFG_SUPPORT_BATCH_SCAN -+ else if (strnicmp(pcCommand, CMD_BATCH_SET, strlen(CMD_BATCH_SET)) == 0) { -+ kalIoctl(prGlueInfo, -+ wlanoidSetBatchScanReq, -+ (PVOID) pcCommand, i4TotalLen, FALSE, FALSE, TRUE, &i4BytesWritten); -+ } else if (strnicmp(pcCommand, CMD_BATCH_GET, strlen(CMD_BATCH_GET)) == 0) { -+ /* strcpy(pcCommand, "BATCH SCAN DATA FROM FIRMWARE"); */ -+ /* i4BytesWritten = strlen("BATCH SCAN DATA FROM FIRMWARE") + 1; */ -+ /* i4BytesWritten = priv_driver_get_linkspeed (prNetDev, pcCommand, i4TotalLen); */ -+ -+ UINT_32 u4BufLen; -+ int i; -+ /* int rlen=0; */ -+ -+ for (i = 0; i < CFG_BATCH_MAX_MSCAN; i++) { -+ g_rEventBatchResult[i].ucScanCount = i + 1; /* for get which mscan */ -+ kalIoctl(prGlueInfo, -+ wlanoidQueryBatchScanResult, -+ (PVOID)&g_rEventBatchResult[i], -+ sizeof(EVENT_BATCH_RESULT_T), TRUE, TRUE, TRUE, &u4BufLen); -+ } -+ -+#if 0 -+ DBGLOG(SCN, INFO, "Batch Scan Results, scan count = %u\n", g_rEventBatchResult.ucScanCount); -+ for (i = 0; i < g_rEventBatchResult.ucScanCount; i++) { -+ prEntry = &g_rEventBatchResult.arBatchResult[i]; -+ DBGLOG(SCN, INFO, "Entry %u\n", i); -+ DBGLOG(SCN, INFO, " BSSID = %pM\n", prEntry->aucBssid); -+ DBGLOG(SCN, INFO, " SSID = %s\n", prEntry->aucSSID); -+ DBGLOG(SCN, INFO, " SSID len = %u\n", prEntry->ucSSIDLen); -+ DBGLOG(SCN, INFO, " RSSI = %d\n", prEntry->cRssi); -+ DBGLOG(SCN, INFO, " Freq = %u\n", prEntry->ucFreq); -+ } -+#endif -+ -+ batchConvertResult(&g_rEventBatchResult[0], pcCommand, i4TotalLen, &i4BytesWritten); -+ -+ /* Dump for debug */ -+ /* print_hex_dump(KERN_INFO, "BATCH", DUMP_PREFIX_ADDRESS, 16, 1, pcCommand, i4BytesWritten, -+ TRUE); */ -+ -+ } else if (strnicmp(pcCommand, CMD_BATCH_STOP, strlen(CMD_BATCH_STOP)) == 0) { -+ kalIoctl(prGlueInfo, -+ wlanoidSetBatchScanReq, -+ (PVOID) pcCommand, i4TotalLen, FALSE, FALSE, TRUE, &i4BytesWritten); -+ } -+#endif -+ -+#endif -+ -+ else -+ i4CmdFound = 0; -+ } -+ -+ /* i4CmdFound */ -+ if (i4CmdFound == 0) -+ DBGLOG(REQ, TRACE, "Unknown driver command %s - ignored\n", pcCommand); -+ -+ if (i4BytesWritten >= 0) { -+ if ((i4BytesWritten == 0) && (i4TotalLen > 0)) { -+ /* reset the command buffer */ -+ pcCommand[0] = '\0'; -+ } -+ -+ if (i4BytesWritten >= i4TotalLen) { -+ DBGLOG(REQ, INFO, -+ "%s: i4BytesWritten %d > i4TotalLen < %d\n", __func__, i4BytesWritten, i4TotalLen); -+ i4BytesWritten = i4TotalLen; -+ } else { -+ pcCommand[i4BytesWritten] = '\0'; -+ i4BytesWritten++; -+ } -+ } -+ -+ return i4BytesWritten; -+ -+} -+ -+static int compat_priv(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN char *pcExtra, -+ int (*priv_func)(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN char *pcExtra)) -+{ -+ struct iw_point *prIwp; -+ int ret = 0; -+#ifdef CONFIG_COMPAT -+ struct compat_iw_point *iwp_compat = NULL; -+ struct iw_point iwp; -+#endif -+ -+ if (!prIwReqData) -+ return -EINVAL; -+ -+#ifdef CONFIG_COMPAT -+ if (prIwReqInfo->flags & IW_REQUEST_FLAG_COMPAT) { -+ iwp_compat = (struct compat_iw_point *) &prIwReqData->data; -+ iwp.pointer = compat_ptr(iwp_compat->pointer); -+ iwp.length = iwp_compat->length; -+ iwp.flags = iwp_compat->flags; -+ prIwp = &iwp; -+ } else -+#endif -+ prIwp = &prIwReqData->data; -+ -+ -+ ret = priv_func(prNetDev, prIwReqInfo, (union iwreq_data *)prIwp, pcExtra); -+ -+#ifdef CONFIG_COMPAT -+ if (prIwReqInfo->flags & IW_REQUEST_FLAG_COMPAT) { -+ iwp_compat->pointer = ptr_to_compat(iwp.pointer); -+ iwp_compat->length = iwp.length; -+ iwp_compat->flags = iwp.flags; -+ } -+#endif -+ return ret; -+} -+ -+int -+priv_set_int(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN char *pcExtra) -+{ -+ return compat_priv(prNetDev, prIwReqInfo, prIwReqData, pcExtra, _priv_set_int); -+} -+ -+int -+priv_get_int(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN OUT char *pcExtra) -+{ -+ return compat_priv(prNetDev, prIwReqInfo, prIwReqData, pcExtra, _priv_get_int); -+} -+ -+int -+priv_set_ints(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN char *pcExtra) -+{ -+ return compat_priv(prNetDev, prIwReqInfo, prIwReqData, pcExtra, _priv_set_ints); -+} -+ -+int -+priv_get_ints(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN OUT char *pcExtra) -+{ -+ return compat_priv(prNetDev, prIwReqInfo, prIwReqData, pcExtra, _priv_get_ints); -+} -+ -+int -+priv_set_struct(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN char *pcExtra) -+{ -+ return compat_priv(prNetDev, prIwReqInfo, prIwReqData, pcExtra, _priv_set_struct); -+} -+ -+int -+priv_get_struct(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN OUT char *pcExtra) -+{ -+ return compat_priv(prNetDev, prIwReqInfo, prIwReqData, pcExtra, _priv_get_struct); -+} -+ -+int -+priv_set_string(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN char *pcExtra) -+{ -+ return compat_priv(prNetDev, prIwReqInfo, prIwReqData, pcExtra, _priv_set_string); -+} -+ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/ahb.c b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/ahb.c -new file mode 100644 -index 000000000000..c13d24906bf8 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/ahb.c -@@ -0,0 +1,1643 @@ -+/****************************************************************************** -+*[File] ahb.c -+*[Version] v1.0 -+*[Revision Date] 2013-01-16 -+*[Author] -+*[Description] -+* The program provides AHB HIF driver -+*[Copyright] -+* Copyright (C) 2013 MediaTek Incorporation. All Rights Reserved. -+******************************************************************************/ -+ -+/* -+** Log: ahb.c -+ * -+ * 01 16 2013 vend_samp.lin -+ * Port sdio.c to ahb.c on MT6572/MT6582 -+ * 1) Initial version -+ * -+ * 04 12 2012 terry.wu -+ * NULL -+ * Add AEE message support -+ * 1) Show AEE warning(red screen) if SDIO access error occurs -+ * -+ * 02 14 2012 cp.wu -+ * [WCXRP00000851] [MT6628 Wi-Fi][Driver] Add HIFSYS related definition to driver source tree -+ * include correct header file upon setting. -+ * -+ * 11 10 2011 cp.wu -+ * [WCXRP00001098] [MT6620 Wi-Fi][Driver] Replace printk by DBG LOG macros in linux porting layer -+ * 1. eliminaite direct calls to printk in porting layer. -+ * 2. replaced by DBGLOG, which would be XLOG on ALPS platforms. -+ * -+ * 09 20 2011 cp.wu -+ * [WCXRP00000994] [MT6620 Wi-Fi][Driver] dump message for bus error and reset bus error flag while re-initialized -+ * 1. always show error message for SDIO bus errors. -+ * 2. reset bus error flag when re-initialization -+ * -+ * 08 17 2011 cp.wu -+ * [WCXRP00000851] [MT6628 Wi-Fi][Driver] Add HIFSYS related definition to driver source tree -+ * add MT6628 related definitions for Linux/Android driver. -+ * -+ * 05 18 2011 cp.wu -+ * [WCXRP00000702] [MT5931][Driver] Modify initialization sequence for E1 ASIC -+ * add device ID for MT5931. -+ * -+ * 04 08 2011 pat.lu -+ * [WCXRP00000623] [MT6620 Wi-Fi][Driver] use ARCH define to distinguish PC Linux driver -+ * Use CONFIG_X86 instead of PC_LINUX_DRIVER_USE option to have proper compile setting for PC Linux driver -+ * -+ * 03 22 2011 pat.lu -+ * [WCXRP00000592] [MT6620 Wi-Fi][Driver] Support PC Linux Environment Driver Build -+ * Add a compiler option "PC_LINUX_DRIVER_USE" for building driver in PC Linux environment. -+ * -+ * 03 18 2011 cp.wu -+ * [WCXRP00000559] [MT6620 Wi-Fi][Driver] Combine TX/RX DMA buffers into a single one to reduce physically continuous -+ * memory consumption -+ * deprecate CFG_HANDLE_IST_IN_SDIO_CALLBACK. -+ * -+ * 03 15 2011 cp.wu -+ * [WCXRP00000559] [MT6620 Wi-Fi][Driver] Combine TX/RX DMA buffers into a single one to reduce physically continuous -+ * memory consumption -+ * 1. deprecate CFG_HANDLE_IST_IN_SDIO_CALLBACK -+ * 2. Use common coalescing buffer for both TX/RX directions -+ * -+ * -+ * 03 07 2011 terry.wu -+ * [WCXRP00000521] [MT6620 Wi-Fi][Driver] Remove non-standard debug message -+ * Toggle non-standard debug messages to comments. -+ * -+ * 11 15 2010 jeffrey.chang -+ * [WCXRP00000181] [MT6620 Wi-Fi][Driver] fix the driver message "GLUE_FLAG_HALT skip INT" during unloading -+ * Fix GLUE_FALG_HALT message which cause driver to hang -+ * -+ * 11 08 2010 cp.wu -+ * [WCXRP00000166] [MT6620 Wi-Fi][Driver] use SDIO CMD52 for enabling/disabling interrupt to reduce transaction period -+ * correct typo -+ * -+ * 11 08 2010 cp.wu -+ * [WCXRP00000166] [MT6620 Wi-Fi][Driver] use SDIO CMD52 for enabling/disabling interrupt to reduce transaction period -+ * change to use CMD52 for enabling/disabling interrupt to reduce SDIO transaction time -+ * -+ * 11 01 2010 yarco.yang -+ * [WCXRP00000149] [MT6620 WI-Fi][Driver]Fine tune performance on MT6516 platform -+ * Add code to run WlanIST in SDIO callback. -+ * -+ * 10 19 2010 cp.wu -+ * [WCXRP00000122] [MT6620 Wi-Fi][Driver] Preparation for YuSu source tree integration -+ * remove HIF_SDIO_ONE flags because the settings could be merged for runtime detection instead of compile-time. -+ * -+ * 10 19 2010 jeffrey.chang -+ * [WCXRP00000120] [MT6620 Wi-Fi][Driver] Refine linux kernel module to the license of MTK propietary and enable MTK -+ * HIF by default -+ * Refine linux kernel module to the license of MTK and enable MTK HIF -+ * -+ * 08 21 2010 jeffrey.chang -+ * NULL -+ * 1) add sdio two setting -+ * 2) bug fix of sdio glue -+ * -+ * 08 18 2010 jeffrey.chang -+ * NULL -+ * support multi-function sdio -+ * -+ * 08 18 2010 cp.wu -+ * NULL -+ * #if defined(__X86__) is not working, change to use #ifdef CONFIG_X86. -+ * -+ * 08 17 2010 cp.wu -+ * NULL -+ * add ENE SDIO host workaround for x86 linux platform. -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 05 07 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * Fix hotplug bug -+ * -+ * 03 28 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * clear sdio interrupt -+ * -+ * 03 24 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * initial import for Linux port -+** -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include -+/* #include */ -+#include -+/* #include */ -+#include -+/* #include */ -+/* #include */ -+/* #include */ -+ -+#include -+#ifndef CONFIG_X86 -+#include -+#endif -+ -+#ifdef CONFIG_OF -+#include -+#include -+#include -+#else -+ -+#endif -+ -+/* #include -+#include */ -+ -+#include "gl_os.h" -+ -+#if defined(MT6620) -+#include "mt6620_reg.h" -+#elif defined(MT6628) -+#include "mtreg.h" -+#endif -+ -+#if !defined(CONFIG_MTK_CLKMGR) -+#include -+#endif -+ -+/* #define MTK_DMA_BUF_MEMCPY_SUP */ /* no virt_to_phys() use */ -+/* #define HIF_DEBUG_SUP */ -+/* #define HIF_DEBUG_SUP_TX */ -+ -+#ifdef HIF_DEBUG_SUP -+#define HIF_DBG(msg) (printk msg) -+#else -+#define HIF_DBG(msg) -+#endif /* HIF_DEBUG_SUP */ -+ -+#ifdef HIF_DEBUG_SUP_TX -+#define HIF_DBG_TX(msg) (printk msg) -+#else -+#define HIF_DBG_TX(msg) -+#endif /* HIF_DEBUG_SUP */ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+static UINT_32 -+HifAhbDmaEnhanceModeConf(IN GLUE_INFO_T *GlueInfo, IN UINT_32 BurstLen, IN UINT_32 PortId, IN UINT_32 TransByte); -+ -+static irqreturn_t HifAhbISR(IN int Irq, IN void *Arg); -+ -+static int HifAhbProbe(VOID); -+ -+static int HifAhbRemove(VOID); -+ -+#if (MTK_WCN_SINGLE_MODULE == 0) -+static int HifAhbBusCntGet(VOID); -+ -+static int HifAhbBusCntClr(VOID); -+ -+static int HifTxCnt; -+#endif /* MTK_WCN_SINGLE_MODULE */ -+ -+#if (CONF_HIF_DEV_MISC == 1) -+static ssize_t HifAhbMiscRead(IN struct file *Filp, OUT char __user *DstBuf, IN size_t Size, IN loff_t *Ppos); -+ -+static ssize_t HifAhbMiscWrite(IN struct file *Filp, IN const char __user *SrcBuf, IN size_t Size, IN loff_t *Ppos); -+ -+static int HifAhbMiscIoctl(IN struct file *Filp, IN unsigned int Cmd, IN unsigned long arg); -+ -+static int HifAhbMiscOpen(IN struct inode *Inodep, IN struct file *Filp); -+ -+static int HifAhbMiscClose(IN struct inode *Inodep, IN struct file *Filp); -+#else -+ -+static int HifAhbPltmProbe(IN struct platform_device *PDev); -+ -+static int __exit HifAhbPltmRemove(IN struct platform_device *PDev); -+ -+#ifdef CONFIG_PM -+static int HifAhbPltmSuspend(IN struct platform_device *PDev, pm_message_t Message); -+ -+static int HifAhbPltmResume(IN struct platform_device *PDev); -+#endif /* CONFIG_PM */ -+ -+#endif /* CONF_HIF_DEV_MISC */ -+ -+#if (CONF_HIF_LOOPBACK_AUTO == 1) /* only for development test */ -+static VOID HifAhbLoopbkAuto(IN unsigned long arg); -+#endif /* CONF_HIF_LOOPBACK_AUTO */ -+ -+#if (CONF_HIF_DMA_INT == 1) -+static irqreturn_t HifDmaISR(IN int Irq, IN void *Arg); -+#endif /* CONF_HIF_DMA_INT */ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/* initialiation function from other module */ -+static probe_card pfWlanProbe; -+ -+/* release function from other module */ -+static remove_card pfWlanRemove; -+ -+static BOOLEAN WlanDmaFatalErr; -+ -+#if (CONF_HIF_DEV_MISC == 1) -+static const struct file_operations MtkAhbOps = { -+ .owner = THIS_MODULE, -+ .read = HifAhbMiscRead, -+ .write = HifAhbMiscWrite, -+ .unlocked_ioctl = HifAhbMiscIoctl, -+#ifdef CONFIG_COMPAT -+ .compat_ioctl = HifAhbMiscIoctl, -+#endif -+ .open = HifAhbMiscOpen, -+ .release = HifAhbMiscClose, -+}; -+ -+static struct miscdevice MtkAhbDriver = { -+ .minor = MISC_DYNAMIC_MINOR, /* any minor number */ -+ .name = HIF_MOD_NAME, -+ .fops = &MtkAhbOps, -+}; -+#else -+ -+#ifdef CONFIG_OF -+static const struct of_device_id apwifi_of_ids[] = { -+ {.compatible = "mediatek,wifi", .data = (void *)0}, -+ {.compatible = "mediatek,mt7623-wifi", .data = (void *)0x7623}, -+ {} -+}; -+#endif -+ -+struct platform_driver MtkPltmAhbDriver = { -+ .driver = { -+ .name = "mt-wifi", -+ .owner = THIS_MODULE, -+#ifdef CONFIG_OF -+ .of_match_table = apwifi_of_ids, -+#endif -+ }, -+ .probe = HifAhbPltmProbe, -+#ifdef CONFIG_PM -+ .suspend = HifAhbPltmSuspend, -+ .resume = HifAhbPltmResume, -+#else -+ .suspend = NULL, -+ .resume = NULL, -+#endif /* CONFIG_PM */ -+ .remove = __exit_p(HifAhbPltmRemove), -+}; -+ -+static struct platform_device *HifAhbPDev; -+ -+#endif /* CONF_HIF_DEV_MISC */ -+ -+/******************************************************************************* -+* P U B L I C F U N C T I O N S -+******************************************************************************** -+*/ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will register sdio bus to the os -+* -+* \param[in] pfProbe Function pointer to detect card -+* \param[in] pfRemove Function pointer to remove card -+* -+* \return The result of registering HIF driver (WLAN_STATUS_SUCCESS = 0) -+*/ -+/*----------------------------------------------------------------------------*/ -+WLAN_STATUS glRegisterBus(probe_card pfProbe, remove_card pfRemove) -+{ -+ WLAN_STATUS Ret; -+ -+ ASSERT(pfProbe); -+ ASSERT(pfRemove); -+ -+ pfWlanProbe = pfProbe; /* wlan card initialization in other modules = wlanProbe() */ -+ pfWlanRemove = pfRemove; -+ -+#if (CONF_HIF_DEV_MISC == 1) -+ Ret = misc_register(&MtkAhbDriver); -+ if (Ret != 0) -+ return Ret; -+ HifAhbProbe(); -+#else -+ Ret = platform_driver_register(&MtkPltmAhbDriver); -+#endif /* CONF_HIF_DEV_MISC */ -+ -+ return Ret; -+ -+} /* end of glRegisterBus() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will unregister sdio bus to the os -+* -+* \param[in] pfRemove Function pointer to remove card -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID glUnregisterBus(remove_card pfRemove) -+{ -+ ASSERT(pfRemove); -+ -+ pfRemove(); -+ -+#if (CONF_HIF_DEV_MISC == 1) -+ HifAhbRemove(); -+ -+ if ((misc_deregister(&MtkAhbDriver)) != 0) -+ ; -+#else -+ -+ platform_driver_unregister(&MtkPltmAhbDriver); -+#endif /* CONF_HIF_DEV_MISC */ -+ -+ return; -+ -+} /* end of glUnregisterBus() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will inform us whole chip reset start event. -+* -+* \param[in] GlueInfo Pointer to glue info structure -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID glResetHif(GLUE_INFO_T *GlueInfo) -+{ -+ GL_HIF_INFO_T *HifInfo; -+ -+ ASSERT(GlueInfo); -+ HifInfo = &GlueInfo->rHifInfo; -+ if (HifInfo->DmaOps) -+ HifInfo->DmaOps->DmaReset(HifInfo); -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function stores hif related info, which is initialized before. -+* -+* \param[in] GlueInfo Pointer to glue info structure -+* \param[in] u4Cookie Pointer to UINT_32 memory base variable for _HIF_HPI -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID glSetHifInfo(GLUE_INFO_T *GlueInfo, ULONG ulCookie) -+{ -+ GL_HIF_INFO_T *HifInfo; -+ const struct of_device_id *of_id; -+ -+ /* Init HIF */ -+ ASSERT(GlueInfo); -+ HifInfo = &GlueInfo->rHifInfo; -+#if (CONF_HIF_DEV_MISC == 1) -+ HifInfo->Dev = MtkAhbDriver.this_device; -+#else -+ HifInfo->Dev = &HifAhbPDev->dev; -+#endif /* CONF_HIF_DEV_MISC */ -+ SET_NETDEV_DEV(GlueInfo->prDevHandler, HifInfo->Dev); -+ -+ HifInfo->HifRegBaseAddr = ioremap(HIF_DRV_BASE, HIF_DRV_LENGTH); -+ HifInfo->McuRegBaseAddr = ioremap(CONN_MCU_DRV_BASE, CONN_MCU_REG_LENGTH); -+ DBGLOG(INIT, INFO, "[WiFi/HIF]HifInfo->HifRegBaseAddr=0x%p, HifInfo->McuRegBaseAddr=0x%p\n", -+ HifInfo->HifRegBaseAddr, HifInfo->McuRegBaseAddr); -+ -+ /* default disable DMA */ -+ HifInfo->fgDmaEnable = FALSE; -+ HifInfo->DmaRegBaseAddr = 0; -+ HifInfo->DmaOps = NULL; -+ of_id = of_match_node(apwifi_of_ids, HifAhbPDev->dev.of_node); -+ if (of_id && of_id->data) { -+ HifInfo->ChipID = (UINT_32)(unsigned long)of_id->data; -+ } else { -+ /* read chip ID */ -+ HifInfo->ChipID = HIF_REG_READL(HifInfo, MCR_WCIR) & 0xFFFF; -+ if (HifInfo->ChipID == 0x0321 || HifInfo->ChipID == 0x0335 || HifInfo->ChipID == 0x0337) -+ HifInfo->ChipID = 0x6735; /* Denali ChipID transition */ -+ if (HifInfo->ChipID == 0x0326) -+ HifInfo->ChipID = 0x6755; -+ } -+ DBGLOG(INIT, INFO, "[WiFi/HIF] ChipID = 0x%x\n", HifInfo->ChipID); -+#ifdef CONFIG_OF -+#if !defined(CONFIG_MTK_CLKMGR) -+ HifInfo->clk_wifi_dma = devm_clk_get(&HifAhbPDev->dev, "wifi-dma"); -+ if (IS_ERR(HifInfo->clk_wifi_dma)) -+ DBGLOG(INIT, ERROR, "[WiFi/HIF][CCF]cannot get HIF clk_wifi_dma clock.\n"); -+ DBGLOG(INIT, TRACE, "[WiFi/HIF][CCF]HIF clk_wifi_dma=0x%p\n", HifInfo->clk_wifi_dma); -+#endif -+#endif -+ -+ /* Init DMA */ -+ WlanDmaFatalErr = 0; /* reset error flag */ -+ -+#if (CONF_MTK_AHB_DMA == 1) -+ spin_lock_init(&HifInfo->DdmaLock); -+ -+ HifPdmaInit(HifInfo); -+#endif /* CONF_MTK_AHB_DMA */ -+ -+ /* Start loopback test after 10 seconds */ -+#if (CONF_HIF_LOOPBACK_AUTO == 1) /* only for development test */ -+ { -+ init_timer(&(HifInfo->HifTmrLoopbkFn)); -+ HifInfo->HifTmrLoopbkFn.function = HifAhbLoopbkAuto; -+ HifInfo->HifTmrLoopbkFn.data = (unsigned long)GlueInfo; -+ -+ init_waitqueue_head(&HifInfo->HifWaitq); -+ HifInfo->HifTaskLoopbkFn = kthread_run(kalDevLoopbkThread, GlueInfo->prDevHandler, "LoopbkThread"); -+ HifInfo->HifLoopbkFlg = 0; -+ -+ /* Note: in FPGA, clock is not accuracy so 3000 here, not 10000 */ -+ HifInfo->HifTmrLoopbkFn.expires = jiffies + MSEC_TO_SYSTIME(30000); -+ add_timer(&(HifInfo->HifTmrLoopbkFn)); -+ -+ HIF_DBG(("[WiFi/HIF] Start loopback test after 10 seconds (jiffies = %u)...\n", jiffies)); -+ } -+#endif /* CONF_HIF_LOOPBACK_AUTO */ -+ -+#if (CONF_HIF_DMA_INT == 1) -+ init_waitqueue_head(&HifInfo->HifDmaWaitq); -+ HifInfo->HifDmaWaitFlg = 0; -+#endif /* CONF_HIF_DMA_INT */ -+ -+} /* end of glSetHifInfo() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function clears hif related info. -+* -+* \param[in] GlueInfo Pointer to glue info structure -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID glClearHifInfo(GLUE_INFO_T *GlueInfo) -+{ -+ iounmap(GlueInfo->rHifInfo.HifRegBaseAddr); -+ iounmap(GlueInfo->rHifInfo.DmaRegBaseAddr); -+ iounmap(GlueInfo->rHifInfo.McuRegBaseAddr); -+ return; -+ -+} /* end of glClearHifInfo() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function clears hif related info. -+* -+* \param[in] GlueInfo Pointer to glue info structure -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID glGetChipInfo(GLUE_INFO_T *GlueInfo, UINT_8 *pucChipBuf) -+{ -+ GL_HIF_INFO_T *HifInfo; -+ -+ HifInfo = &GlueInfo->rHifInfo; -+ DBGLOG(INIT, TRACE, "glGetChipInfo ChipID = 0x%x\n", HifInfo->ChipID); -+ switch (HifInfo->ChipID) { -+ case MTK_CHIP_ID_6571: -+ case MTK_CHIP_ID_8127: -+ case MTK_CHIP_ID_6752: -+ case MTK_CHIP_ID_8163: -+ case MTK_CHIP_ID_6735: -+ case MTK_CHIP_ID_6580: -+ case MTK_CHIP_ID_6755: -+ case MTK_CHIP_ID_7623: -+ kalSprintf(pucChipBuf, "%04x", HifInfo->ChipID); -+ break; -+ default: -+ kalMemCopy(pucChipBuf, "SOC", strlen("SOC")); -+ } -+} /* end of glGetChipInfo() */ -+ -+#if CFG_SPM_WORKAROUND_FOR_HOTSPOT -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function to check if we need wakelock under Hotspot mode. -+* -+* \param[in] GlueInfo Pointer to glue info structure -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN glIsChipNeedWakelock(GLUE_INFO_T *GlueInfo) -+{ -+ GL_HIF_INFO_T *HifInfo; -+ -+ HifInfo = &GlueInfo->rHifInfo; -+ if (HifInfo->ChipID == MTK_CHIP_ID_6572 || HifInfo->ChipID == MTK_CHIP_ID_6582) -+ return TRUE; -+ else -+ return FALSE; -+} /* end of glIsChipNeedWakelock() */ -+#endif /* CFG_SPM_WORKAROUND_FOR_HOTSPOT */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Initialize bus operation and hif related information, request resources. -+* -+* \param[out] pvData A pointer to HIF-specific data type buffer. -+* For eHPI, pvData is a pointer to UINT_32 type and stores a -+* mapped base address. -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN glBusInit(PVOID pvData) -+{ -+ return TRUE; -+} /* end of glBusInit() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Stop bus operation and release resources. -+* -+* \param[in] pvData A pointer to struct net_device. -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID glBusRelease(PVOID pvData) -+{ -+} /* end of glBusRelease() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Setup bus interrupt operation and interrupt handler for os. -+* -+* \param[in] pvData A pointer to struct net_device. -+* \param[in] pfnIsr A pointer to interrupt handler function. -+* \param[in] pvCookie Private data for pfnIsr function. -+* -+* \retval WLAN_STATUS_SUCCESS if success -+* NEGATIVE_VALUE if fail -+*/ -+/*----------------------------------------------------------------------------*/ -+#ifdef CONFIG_OF -+INT_32 glBusSetIrq(PVOID pvData, PVOID pfnIsr, PVOID pvCookie) -+{ -+ struct device_node *node = NULL; -+ unsigned int irq_info[3] = { 0, 0, 0 }; -+ /* unsigned int phy_base; */ -+ unsigned int irq_id = 0; -+ unsigned int irq_flags = 0; -+ -+ struct net_device *prNetDevice; -+ -+ ASSERT(pvData); -+ if (!pvData) -+ return -1; -+ prNetDevice = (struct net_device *)pvData; -+ -+ node = of_find_compatible_node(NULL, NULL, "mediatek,wifi"); -+ if (node) { -+ irq_id = irq_of_parse_and_map(node, 0); -+ DBGLOG(INIT, INFO, "WIFI-OF: get wifi irq(%d)\n", irq_id); -+ } else { -+ DBGLOG(INIT, ERROR, "WIFI-OF: get wifi device node fail\n"); -+ } -+ -+ /* get the interrupt line behaviour */ -+ if (of_property_read_u32_array(node, "interrupts", irq_info, ARRAY_SIZE(irq_info))) { -+ DBGLOG(INIT, ERROR, "WIFI-OF: get interrupt flag from DTS fail\n"); -+ } else { -+ irq_flags = irq_info[2]; -+ DBGLOG(INIT, LOUD, "WIFI-OF: get interrupt flag(0x%x)\n", irq_flags); -+ } -+ -+ /* Register AHB IRQ */ -+ if (request_irq(irq_id, HifAhbISR, irq_flags, HIF_MOD_NAME, prNetDevice)) { -+ DBGLOG(INIT, ERROR, "WIFI-OF: request irq %d fail!\n", irq_id); -+ return -1; -+ } -+ -+ return 0; -+} -+ -+VOID glBusFreeIrq(PVOID pvData, PVOID pvCookie) -+{ -+ struct device_node *node = NULL; -+ unsigned int irq_info[3] = { 0, 0, 0 }; -+ /* unsigned int phy_base; */ -+ unsigned int irq_id = 0; -+ unsigned int irq_flags = 0; -+ -+ struct net_device *prNetDevice; -+ -+ /* Init */ -+ ASSERT(pvData); -+ if (!pvData) -+ return; -+ prNetDevice = (struct net_device *)pvData; -+ -+ node = of_find_compatible_node(NULL, NULL, "mediatek,wifi"); -+ if (node) { -+ irq_id = irq_of_parse_and_map(node, 0); -+ DBGLOG(INIT, INFO, "WIFI-OF: get wifi irq(%d)\n", irq_id); -+ } else { -+ DBGLOG(INIT, ERROR, "WIFI-OF: get wifi device node fail\n"); -+ } -+ -+ /* get the interrupt line behaviour */ -+ if (of_property_read_u32_array(node, "interrupts", irq_info, ARRAY_SIZE(irq_info))) { -+ DBGLOG(INIT, ERROR, "WIFI-OF: get interrupt flag from DTS fail\n"); -+ } else { -+ irq_flags = irq_info[2]; -+ DBGLOG(INIT, LOUD, "WIFI-OF: get interrupt flag(0x%x)\n", irq_flags); -+ } -+ -+ /* Free the IRQ */ -+ free_irq(irq_id, prNetDevice); -+ return; -+ -+} -+#else -+/* the name is different in 72 and 82 */ -+#ifndef MT_WF_HIF_IRQ_ID /* for MT6572/82/92 */ -+#define MT_WF_HIF_IRQ_ID WF_HIF_IRQ_ID -+#endif /* MT_WF_HIF_IRQ_ID */ -+ -+INT_32 glBusSetIrq(PVOID pvData, PVOID pfnIsr, PVOID pvCookie) -+{ -+ int ret = 0; -+ struct net_device *prNetDevice; -+ GLUE_INFO_T *GlueInfo; -+ GL_HIF_INFO_T *HifInfo; -+ -+ /* Init */ -+ ASSERT(pvData); -+ if (!pvData) -+ return -1; -+ -+ prNetDevice = (struct net_device *)pvData; -+ GlueInfo = (GLUE_INFO_T *) pvCookie; -+ ASSERT(GlueInfo); -+ if (!GlueInfo) { -+ DBGLOG(INIT, ERROR, "GlueInfo == NULL!\n"); -+ return -1; -+ } -+ -+ HifInfo = &GlueInfo->rHifInfo; -+ -+ /* Register AHB IRQ */ -+ if (request_irq(MT_WF_HIF_IRQ_ID, HifAhbISR, IRQF_TRIGGER_LOW, HIF_MOD_NAME, prNetDevice)) { -+ DBGLOG(INIT, ERROR, "request irq %d fail!\n", MT_WF_HIF_IRQ_ID); -+ return -1; -+ } -+#if (CONF_HIF_DMA_INT == 1) -+ if (request_irq(MT_GDMA2_IRQ_ID, HifDmaISR, IRQF_TRIGGER_LOW, "AHB_DMA", prNetDevice)) { -+ DBGLOG(INIT, ERROR, "request irq %d fail!\n", MT_GDMA2_IRQ_ID); -+ free_irq(MT_WF_HIF_IRQ_ID, prNetDevice); -+ return -1; -+ } -+#endif /* CONF_HIF_DMA_INT */ -+ -+ return ret; -+ -+} /* end of glBusSetIrq() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Stop bus interrupt operation and disable interrupt handling for os. -+* -+* \param[in] pvData A pointer to struct net_device. -+* \param[in] pvCookie Private data for pfnIsr function. -+* -+* \return (none) -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID glBusFreeIrq(PVOID pvData, PVOID pvCookie) -+{ -+ struct net_device *prNetDevice; -+ GLUE_INFO_T *GlueInfo; -+ GL_HIF_INFO_T *HifInfo; -+ -+ /* Init */ -+ ASSERT(pvData); -+ if (!pvData) -+ return; -+ -+ prNetDevice = (struct net_device *)pvData; -+ GlueInfo = (GLUE_INFO_T *) pvCookie; -+ ASSERT(GlueInfo); -+ if (!GlueInfo) -+ return; -+ -+ HifInfo = &GlueInfo->rHifInfo; -+ -+ /* Free the IRQ */ -+ free_irq(MT_WF_HIF_IRQ_ID, prNetDevice); -+ return; -+ -+} /* end of glBusreeIrq() */ -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Read a 32-bit device register -+* -+* \param[in] GlueInfo Pointer to the GLUE_INFO_T structure. -+* \param[in] RegOffset Register offset -+* \param[in] pu4Value Pointer to variable used to store read value -+* -+* \retval TRUE operation success -+* \retval FALSE operation fail -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN kalDevRegRead(IN GLUE_INFO_T *GlueInfo, IN UINT_32 RegOffset, OUT UINT_32 *pu4Value) -+{ -+ GL_HIF_INFO_T *HifInfo; -+ -+ /* sanity check and init */ -+ ASSERT(GlueInfo); -+ ASSERT(pu4Value); -+ HifInfo = &GlueInfo->rHifInfo; -+ -+ /* use PIO mode to read register */ -+ if (WlanDmaFatalErr && RegOffset != MCR_WCIR && RegOffset != MCR_WHLPCR) -+ return FALSE; -+ *pu4Value = HIF_REG_READL(HifInfo, RegOffset); -+ -+ if ((RegOffset == MCR_WRDR0) || (RegOffset == MCR_WRDR1)) -+ HIF_DBG(("[WiFi/HIF] kalDevRegRead from Data Port 0 or 1\n")); -+ -+ return TRUE; -+ -+} /* end of kalDevRegRead() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Write a 32-bit device register -+* -+* \param[in] GlueInfo Pointer to the GLUE_INFO_T structure. -+* \param[in] RegOffset Register offset -+* \param[in] RegValue RegValue to be written -+* -+* \retval TRUE operation success -+* \retval FALSE operation fail -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN kalDevRegWrite(IN GLUE_INFO_T *GlueInfo, IN UINT_32 RegOffset, IN UINT_32 RegValue) -+{ -+ GL_HIF_INFO_T *HifInfo; -+ -+ /* sanity check and init */ -+ ASSERT(GlueInfo); -+ HifInfo = &GlueInfo->rHifInfo; -+ -+ /* use PIO mode to write register */ -+ if (WlanDmaFatalErr && RegOffset != MCR_WCIR && RegOffset != MCR_WHLPCR) -+ return FALSE; -+ HIF_REG_WRITEL(HifInfo, RegOffset, RegValue); -+ -+ if ((RegOffset == MCR_WTDR0) || (RegOffset == MCR_WTDR1)) -+ HIF_DBG(("[WiFi/HIF] kalDevRegWrite to Data Port 0 or 1\n")); -+ -+ return TRUE; -+ -+} /* end of kalDevRegWrite() */ -+ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Read device I/O port -+* -+* \param[in] GlueInfo Pointer to the GLUE_INFO_T structure. -+* \param[in] Port I/O port offset -+* \param[in] Size Length to be read -+* \param[out] Buf Pointer to read buffer -+* \param[in] MaxBufSize Length of the buffer valid to be accessed -+* -+* \retval TRUE operation success -+* \retval FALSE operation fail -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN -+kalDevPortRead(IN P_GLUE_INFO_T GlueInfo, IN UINT_16 Port, IN UINT_32 Size, OUT PUINT_8 Buf, IN UINT_32 MaxBufSize) -+{ -+ GL_HIF_INFO_T *HifInfo; -+ UINT_32 u4HSTCRValue = 0; -+ UINT_32 RegWHLPCR = 0; -+ -+ /* sanity check */ -+ if ((WlanDmaFatalErr == 1) || (fgIsResetting == TRUE) || (HifIsFwOwn(GlueInfo->prAdapter) == TRUE)) { -+ DBGLOG(RX, ERROR, "WlanDmaFatalErr: %d, fgIsResetting: %d, HifIsFwOwn: %d\n", -+ WlanDmaFatalErr, fgIsResetting, HifIsFwOwn(GlueInfo->prAdapter)); -+ return FALSE; -+ } -+ /* Init */ -+ ASSERT(GlueInfo); -+ HifInfo = &GlueInfo->rHifInfo; -+ -+ ASSERT(Buf); -+ ASSERT(Size <= MaxBufSize); -+ -+ /* Note: burst length should be equal to the one used in DMA */ -+ if (Port == MCR_WRDR0) -+ u4HSTCRValue = HifAhbDmaEnhanceModeConf(GlueInfo, HIF_BURST_4DW, HIF_TARGET_RXD0, Size); -+ else if (Port == MCR_WRDR1) -+ u4HSTCRValue = HifAhbDmaEnhanceModeConf(GlueInfo, HIF_BURST_4DW, HIF_TARGET_RXD1, Size); -+ else if (Port == MCR_WHISR) -+ u4HSTCRValue = HifAhbDmaEnhanceModeConf(GlueInfo, HIF_BURST_4DW, HIF_TARGET_WHISR, Size); -+ -+ RegWHLPCR = HIF_REG_READL(HifInfo, MCR_WHLPCR); -+ if ((RegWHLPCR & WHLPCR_INT_EN_SET) == 1) -+ HIF_REG_WRITEL(HifInfo, MCR_WHLPCR, WHLPCR_INT_EN_CLR); -+ -+ /* Read */ -+#if (CONF_MTK_AHB_DMA == 1) -+ if ((HifInfo->fgDmaEnable == TRUE) && (HifInfo->DmaOps != NULL) -+ && ((Port == MCR_WRDR0) || (Port == MCR_WRDR1))) { -+ /* only for data port */ -+#ifdef MTK_DMA_BUF_MEMCPY_SUP -+ VOID *DmaVBuf = NULL, *DmaPBuf = NULL; -+#endif /* MTK_DMA_BUF_MEMCPY_SUP */ -+ GL_HIF_DMA_OPS_T *prDmaOps = HifInfo->DmaOps; -+ MTK_WCN_HIF_DMA_CONF DmaConf; -+ UINT_32 LoopCnt; -+ unsigned long PollTimeout; -+#if (CONF_HIF_DMA_INT == 1) -+ INT_32 RtnVal = 0; -+#endif -+ /* config DMA, Port = MCR_WRDR0 or MCR_WRDR1 */ -+ DmaConf.Count = Size; -+ DmaConf.Dir = HIF_DMA_DIR_RX; -+ DmaConf.Src = HIF_DRV_BASE + Port; /* must be physical addr */ -+ -+#ifdef MTK_DMA_BUF_MEMCPY_SUP -+ DmaConf.Dst = kalIOPhyAddrGet(Buf); /* must be physical addr */ -+ -+ /* TODO: use virt_to_phys() */ -+ if (DmaConf.Dst == NULL) { -+ HIF_DBG(("[WiFi/HIF] Use Dma Buffer to RX packet (%d %d)...\n", Size, CFG_RX_MAX_PKT_SIZE)); -+ ASSERT(Size <= CFG_RX_MAX_PKT_SIZE); -+ -+ kalDmaBufGet(&DmaVBuf, &DmaPBuf); -+ DmaConf.Dst = (ULONG) DmaPBuf; -+ } -+#else -+ /* -+ http://kernelnewbies.org/KernelMemoryAllocation -+ Since the cache-coherent mapping may be expensive, also a streaming allocation exists. -+ -+ This is a buffer for one-way communication, which means coherency is limited to -+ flushing the data from the cache after a write finishes. The buffer has to be -+ pre-allocated (e.g. using kmalloc()). DMA for it is set up with dma_map_single(). -+ -+ When the DMA is finished (e.g. when the device has sent an interrupt signaling end of -+ DMA), call dma_unmap_single(). Between map and unmap, the device is in control of the -+ buffer: if you write to the device, do it before dma_map_single(), if you read from -+ it, do it after dma_unmap_single(). -+ */ -+ /* DMA_FROM_DEVICE invalidated (without writeback) the cache */ -+ /* TODO: if dst_off was not cacheline aligned */ -+ DmaConf.Dst = dma_map_single(HifInfo->Dev, Buf, Size, DMA_FROM_DEVICE); -+#endif /* MTK_DMA_BUF_MEMCPY_SUP */ -+ -+ /* start to read data */ -+ AP_DMA_HIF_LOCK(HifInfo); /* lock to avoid other codes config GDMA */ -+ -+ prDmaOps->DmaClockCtrl(TRUE); -+ prDmaOps->DmaConfig(HifInfo, &DmaConf); -+ prDmaOps->DmaStart(HifInfo); -+ -+#if (CONF_HIF_DMA_INT == 1) -+ RtnVal = wait_event_interruptible_timeout(HifInfo->HifDmaWaitq, (HifInfo->HifDmaWaitFlg != 0), 1000); -+ if (RtnVal <= 0) -+ DBGLOG(RX, ERROR, "fatal error1! reset DMA!\n"); -+ HifInfo->HifDmaWaitFlg = 0; -+#else -+ PollTimeout = jiffies + HZ * 5; -+ -+ do { -+ if (time_before(jiffies, PollTimeout)) -+ continue; -+ DBGLOG(RX, INFO, "RX DMA Timeout, HSTCR: 0x%08x, and dump WHISR EnhanceMode data\n", -+ u4HSTCRValue); -+ HifDumpEnhanceModeData(GlueInfo->prAdapter); -+ if (prDmaOps->DmaRegDump != NULL) -+ prDmaOps->DmaRegDump(HifInfo); -+ WlanDmaFatalErr = 1; -+ /* we still need complete dma progress even dma timeout */ -+ break; -+ } while (!prDmaOps->DmaPollIntr(HifInfo)); -+#endif /* CONF_HIF_DMA_INT */ -+ /* we should disable dma interrupt then clear dma interrupt, otherwise, -+ for dma timeout case, interrupt may be set after we clear it */ -+ prDmaOps->DmaStop(HifInfo); -+ prDmaOps->DmaAckIntr(HifInfo); -+ -+ LoopCnt = 0; -+ do { -+ if (LoopCnt++ > 100000) { -+ /* TODO: impossible! reset DMA */ -+ DBGLOG(RX, ERROR, "fatal error2! reset DMA!\n"); -+ break; -+ } -+ } while (prDmaOps->DmaPollStart(HifInfo) != 0); -+ -+ prDmaOps->DmaClockCtrl(FALSE); -+ -+ AP_DMA_HIF_UNLOCK(HifInfo); -+ -+#ifdef MTK_DMA_BUF_MEMCPY_SUP -+ if (DmaVBuf != NULL) -+ kalMemCopy(Buf, DmaVBuf, Size); -+#else -+ dma_unmap_single(HifInfo->Dev, DmaConf.Dst, Size, DMA_FROM_DEVICE); -+#endif /* MTK_DMA_BUF_MEMCPY_SUP */ -+ -+ if ((RegWHLPCR & WHLPCR_INT_EN_SET) == 1) -+ HIF_REG_WRITEL(HifInfo, MCR_WHLPCR, WHLPCR_INT_EN_SET); -+ -+ if (WlanDmaFatalErr) { -+ if (!fgIsResetting) -+ glDoChipReset(); -+ return FALSE; -+ } -+ HIF_DBG(("[WiFi/HIF] DMA RX OK!\n")); -+ } else -+#endif /* CONF_MTK_AHB_DMA */ -+ { -+ UINT_32 IdLoop, MaxLoop; -+ UINT_32 *LoopBuf; -+ -+ /* default PIO mode */ -+ MaxLoop = Size >> 2; -+ if (Size & 0x3) -+ MaxLoop++; -+ LoopBuf = (UINT_32 *) Buf; -+ -+ for (IdLoop = 0; IdLoop < MaxLoop; IdLoop++) { -+ -+ *LoopBuf = HIF_REG_READL(HifInfo, Port); -+ LoopBuf++; -+ } -+ -+ if ((RegWHLPCR & WHLPCR_INT_EN_SET) == 1) -+ HIF_REG_WRITEL(HifInfo, MCR_WHLPCR, WHLPCR_INT_EN_SET); -+ } -+ -+ return TRUE; -+ -+} /* end of kalDevPortRead() */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Write device I/O port -+* -+* \param[in] GlueInfo Pointer to the GLUE_INFO_T structure. -+* \param[in] Port I/O port offset -+* \param[in] Size Length to be write -+* \param[in] Buf Pointer to write buffer -+* \param[in] MaxBufSize Length of the buffer valid to be accessed -+* -+* \retval TRUE operation success -+* \retval FALSE operation fail -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN -+kalDevPortWrite(IN P_GLUE_INFO_T GlueInfo, IN UINT_16 Port, IN UINT_32 Size, IN PUINT_8 Buf, IN UINT_32 MaxBufSize) -+{ -+ GL_HIF_INFO_T *HifInfo; -+ UINT_32 u4HSTCRValue = 0; -+ UINT_32 RegWHLPCR = 0; -+ -+ /* sanity check */ -+ if ((WlanDmaFatalErr == 1) || (fgIsResetting == TRUE) || (HifIsFwOwn(GlueInfo->prAdapter) == TRUE)) { -+ DBGLOG(RX, ERROR, "WlanDmaFatalErr: %d, fgIsResetting: %d, HifIsFwOwn: %d\n", -+ WlanDmaFatalErr, fgIsResetting, HifIsFwOwn(GlueInfo->prAdapter)); -+ return FALSE; -+ } -+ -+ /* Init */ -+ ASSERT(GlueInfo); -+ HifInfo = &GlueInfo->rHifInfo; -+ -+ ASSERT(Buf); -+ ASSERT(Size <= MaxBufSize); -+ -+ HifTxCnt++; -+ -+ /* Note: burst length should be equal to the one used in DMA */ -+ if (Port == MCR_WTDR0) -+ u4HSTCRValue = HifAhbDmaEnhanceModeConf(GlueInfo, HIF_BURST_4DW, HIF_TARGET_TXD0, Size); -+ else if (Port == MCR_WTDR1) -+ u4HSTCRValue = HifAhbDmaEnhanceModeConf(GlueInfo, HIF_BURST_4DW, HIF_TARGET_TXD1, Size); -+ /* else other non-data port */ -+ -+ RegWHLPCR = HIF_REG_READL(HifInfo, MCR_WHLPCR); -+ if ((RegWHLPCR & WHLPCR_INT_EN_SET) == 1) -+ HIF_REG_WRITEL(HifInfo, MCR_WHLPCR, WHLPCR_INT_EN_CLR); -+ -+ /* Write */ -+#if (CONF_MTK_AHB_DMA == 1) -+ if ((HifInfo->fgDmaEnable == TRUE) && (HifInfo->DmaOps != NULL) && ((Port == MCR_WTDR0) || -+ (Port == MCR_WTDR1))) { -+ /* only for data port */ -+#ifdef MTK_DMA_BUF_MEMCPY_SUP -+ VOID *DmaVBuf = NULL, *DmaPBuf = NULL; -+#endif /* MTK_DMA_BUF_MEMCPY_SUP */ -+ GL_HIF_DMA_OPS_T *prDmaOps = HifInfo->DmaOps; -+ MTK_WCN_HIF_DMA_CONF DmaConf; -+ UINT_32 LoopCnt; -+ unsigned long PollTimeout; -+#if (CONF_HIF_DMA_INT == 1) -+ INT_32 RtnVal = 0; -+#endif -+ -+ /* config GDMA */ -+ HIF_DBG_TX(("[WiFi/HIF/DMA] Prepare to send data...\n")); -+ DmaConf.Count = Size; -+ DmaConf.Dir = HIF_DMA_DIR_TX; -+ DmaConf.Dst = HIF_DRV_BASE + Port; /* must be physical addr */ -+ -+#ifdef MTK_DMA_BUF_MEMCPY_SUP -+ DmaConf.Src = kalIOPhyAddrGet(Buf); /* must be physical addr */ -+ -+ /* TODO: use virt_to_phys() */ -+ if (DmaConf.Src == NULL) { -+ HIF_DBG_TX(("[WiFi/HIF] Use Dma Buffer to TX packet (%d %d)...\n", Size, CFG_RX_MAX_PKT_SIZE)); -+ ASSERT(Size <= CFG_RX_MAX_PKT_SIZE); -+ -+ kalDmaBufGet(&DmaVBuf, &DmaPBuf); -+ DmaConf.Src = (ULONG) DmaPBuf; -+ -+ kalMemCopy(DmaVBuf, Buf, Size); -+ } -+#else -+ -+ /* DMA_TO_DEVICE writeback the cache */ -+ DmaConf.Src = dma_map_single(HifInfo->Dev, Buf, Size, DMA_TO_DEVICE); -+#endif /* MTK_DMA_BUF_MEMCPY_SUP */ -+ -+ /* start to write */ -+ AP_DMA_HIF_LOCK(HifInfo); -+ -+ prDmaOps->DmaClockCtrl(TRUE); -+ prDmaOps->DmaConfig(HifInfo, &DmaConf); -+ prDmaOps->DmaStart(HifInfo); -+ -+#if (CONF_HIF_DMA_INT == 1) -+ RtnVal = wait_event_interruptible_timeout(HifInfo->HifDmaWaitq, (HifInfo->HifDmaWaitFlg != 0), 1000); -+ if (RtnVal <= 0) -+ DBGLOG(TX, ERROR, "fatal error1! reset DMA!\n"); -+ HifInfo->HifDmaWaitFlg = 0; -+#else -+ -+ LoopCnt = 0; -+ PollTimeout = jiffies + HZ * 5; -+ -+ do { -+ if (time_before(jiffies, PollTimeout)) -+ continue; -+ DBGLOG(TX, INFO, "TX DMA Timeout, HSTCR: 0x%08x\n", u4HSTCRValue); -+ if (prDmaOps->DmaRegDump != NULL) -+ prDmaOps->DmaRegDump(HifInfo); -+ WlanDmaFatalErr = 1; -+ /* we still need complete dma progress even dma timeout */ -+ break; -+ } while (!prDmaOps->DmaPollIntr(HifInfo)); -+#endif /* CONF_HIF_DMA_INT */ -+ /* we should disable dma interrupt then clear dma interrupt, otherwise, -+ for dma timeout case, interrupt may be set after we clear it */ -+ prDmaOps->DmaStop(HifInfo); -+ prDmaOps->DmaAckIntr(HifInfo); -+ -+ LoopCnt = 0; -+ do { -+ if (LoopCnt++ > 100000) { -+ DBGLOG(TX, ERROR, "fatal error2! reset DMA!\n"); -+ break; -+ } -+ } while (prDmaOps->DmaPollStart(HifInfo) != 0); -+ -+ prDmaOps->DmaClockCtrl(FALSE); -+ -+ AP_DMA_HIF_UNLOCK(HifInfo); -+ -+#ifndef MTK_DMA_BUF_MEMCPY_SUP -+ dma_unmap_single(HifInfo->Dev, DmaConf.Src, Size, DMA_TO_DEVICE); -+#endif /* MTK_DMA_BUF_MEMCPY_SUP */ -+ -+ if ((RegWHLPCR & WHLPCR_INT_EN_SET) == 1) -+ HIF_REG_WRITEL(HifInfo, MCR_WHLPCR, WHLPCR_INT_EN_SET); -+ -+ if (WlanDmaFatalErr) { -+ if (!fgIsResetting) -+ glDoChipReset(); -+ return FALSE; -+ } -+ HIF_DBG_TX(("[WiFi/HIF] DMA TX OK!\n")); -+ } else -+#endif /* CONF_MTK_AHB_DMA */ -+ { -+ UINT_32 IdLoop, MaxLoop; -+ UINT_32 *LoopBuf; -+ -+ /* PIO mode */ -+ MaxLoop = Size >> 2; -+ LoopBuf = (UINT_32 *) Buf; -+ -+ HIF_DBG_TX(("[WiFi/HIF/PIO] Prepare to send data (%d 0x%p-0x%p)...\n", -+ Size, LoopBuf, (((UINT8 *) LoopBuf) + (Size & (~0x03))))); -+ -+ if (Size & 0x3) -+ MaxLoop++; -+ -+ for (IdLoop = 0; IdLoop < MaxLoop; IdLoop++) { -+ HIF_REG_WRITEL(HifInfo, Port, *LoopBuf); -+ LoopBuf++; -+ } -+ -+ if ((RegWHLPCR & WHLPCR_INT_EN_SET) == 1) -+ HIF_REG_WRITEL(HifInfo, MCR_WHLPCR, WHLPCR_INT_EN_SET); -+ -+ HIF_DBG_TX(("\n\n")); -+ } -+ -+ return TRUE; -+ -+} /* end of kalDevPortWrite() */ -+ -+/******************************************************************************* -+* P R I V A T E F U N C T I O N S -+******************************************************************************** -+*/ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is a SDIO interrupt callback function -+* -+* \param[in] func pointer to SDIO handle -+* -+* \return void -+*/ -+/*----------------------------------------------------------------------------*/ -+static irqreturn_t HifAhbISR(IN int Irq, IN void *Arg) -+{ -+ struct net_device *prNetDevice = (struct net_device *)Arg; -+ GLUE_INFO_T *GlueInfo; -+ GL_HIF_INFO_T *HifInfo; -+ -+ /* Init */ -+ IsrCnt++; -+ ASSERT(prNetDevice); -+ GlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDevice)); -+ ASSERT(GlueInfo); -+ -+ if (!GlueInfo) -+ return IRQ_HANDLED; -+ -+ HifInfo = &GlueInfo->rHifInfo; -+ -+ GlueInfo->IsrCnt++; -+ -+ if (GlueInfo->ulFlag & GLUE_FLAG_HALT) { -+ HIF_REG_WRITEL(HifInfo, MCR_WHLPCR, WHLPCR_INT_EN_CLR); -+ return IRQ_HANDLED; -+ } -+ -+ HIF_REG_WRITEL(HifInfo, MCR_WHLPCR, WHLPCR_INT_EN_CLR); -+ -+ /* lock 100ms to avoid suspend */ -+ kalHifAhbKalWakeLockTimeout(GlueInfo); -+ -+ /* Wake up main thread */ -+ set_bit(GLUE_FLAG_INT_BIT, &GlueInfo->ulFlag); -+ -+ /* when we got sdio interrupt, we wake up the tx servie thread */ -+ wake_up_interruptible(&GlueInfo->waitq); -+ -+ IsrPassCnt++; -+ GlueInfo->IsrPassCnt++; -+ return IRQ_HANDLED; -+ -+} -+ -+#if (CONF_HIF_DMA_INT == 1) -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is a SDIO interrupt callback function -+* -+* \param[in] func pointer to SDIO handle -+* -+* \return void -+*/ -+/*----------------------------------------------------------------------------*/ -+ -+static irqreturn_t HifDmaISR(IN int Irq, IN void *Arg) -+{ -+ struct net_device *prNetDevice = (struct net_device *)Arg; -+ GLUE_INFO_T *GlueInfo; -+ GL_HIF_INFO_T *HifInfo; -+ -+ /* Init */ -+ ASSERT(prNetDevice); -+ GlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDevice)); -+ ASSERT(GlueInfo); -+ -+ if (!GlueInfo) -+ return IRQ_HANDLED; -+ HifInfo = &GlueInfo->rHifInfo; -+ -+ /* disable interrupt */ -+ HifInfo->DmaOps->DmaAckIntr(HifInfo); -+ -+ /* Wake up main thread */ -+ set_bit(1, &HifInfo->HifDmaWaitFlg); -+ -+ /* when we got sdio interrupt, we wake up the tx servie thread */ -+ wake_up_interruptible(&HifInfo->HifDmaWaitq); -+ -+ return IRQ_HANDLED; -+ -+} -+#endif /* CONF_HIF_DMA_INT */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is a SDIO probe function -+* -+* \param[in] func pointer to SDIO handle -+* \param[in] id pointer to SDIO device id table -+* -+* \return void -+*/ -+/*----------------------------------------------------------------------------*/ -+#if defined(CONFIG_MTK_CLKMGR) -+#if defined(MTK_EXTERNAL_LDO) || defined(MTK_ALPS_BOX_SUPPORT) -+#include -+#endif -+#endif -+ -+static int HifAhbProbe(VOID) -+{ -+ int Ret = 0; -+ -+ DBGLOG(INIT, INFO, "HifAhbProbe()\n"); -+ -+ /* power on WiFi TX PA 3.3V and HIF GDMA clock */ -+ { -+#ifdef CONFIG_MTK_PMIC_MT6397 -+#if defined(CONFIG_MTK_CLKMGR) -+#ifdef MTK_EXTERNAL_LDO -+ /* for 8127 tablet */ -+ mt_set_gpio_mode(GPIO51, GPIO_MODE_04); -+ mt_set_gpio_dir(GPIO51, GPIO_DIR_OUT); -+ mt_set_gpio_pull_enable(GPIO51, GPIO_PULL_ENABLE); -+ mt_set_gpio_pull_select(GPIO51, GPIO_PULL_UP); -+#elif defined(MTK_ALPS_BOX_SUPPORT) -+ /* for 8127 box */ -+ mt_set_gpio_mode(GPIO89, GPIO_MODE_04); -+ mt_set_gpio_dir(GPIO89, GPIO_DIR_OUT); -+ mt_set_gpio_pull_enable(GPIO89, GPIO_PULL_ENABLE); -+ mt_set_gpio_pull_select(GPIO89, GPIO_PULL_UP); -+#else -+ hwPowerOn(MT65XX_POWER_LDO_VGP4, VOL_3300, "WLAN"); -+#endif -+#endif -+#else -+#ifdef CONFIG_OF /*for MT6752 */ -+ mtk_wcn_consys_hw_wifi_paldo_ctrl(1); /* switch to HW mode */ -+#else /*for MT6572/82/92 */ -+ hwPowerOn(MT6323_POWER_LDO_VCN33_WIFI, VOL_3300, "WLAN"); -+ upmu_set_vcn33_on_ctrl_wifi(1); /* switch to HW mode */ -+#endif -+#endif -+ -+ } -+ -+#if (CONF_HIF_DEV_MISC == 1) -+ if (pfWlanProbe((PVOID) &MtkAhbDriver.this_device) != WLAN_STATUS_SUCCESS) { -+#else -+ if (pfWlanProbe((PVOID) &HifAhbPDev->dev) != WLAN_STATUS_SUCCESS) { -+#endif /* CONF_HIF_DEV_MISC */ -+ -+ pfWlanRemove(); -+ Ret = -1; -+ } -+ -+ return Ret; -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function will do module remove. -+* -+* \param[in] None -+* -+* \return The result of remove (WLAN_STATUS_SUCCESS = 0) -+*/ -+/*----------------------------------------------------------------------------*/ -+static int HifAhbRemove(VOID) -+{ -+ DBGLOG(INIT, INFO, "HifAhbRemove()\n"); -+ -+ pfWlanRemove(); -+ -+ { -+#ifdef CONFIG_MTK_PMIC_MT6397 -+#if defined(CONFIG_MTK_CLKMGR) -+#ifdef MTK_EXTERNAL_LDO -+ /* for 8127 tablet */ -+ mt_set_gpio_mode(GPIO51, GPIO_MODE_04); -+ mt_set_gpio_dir(GPIO51, GPIO_DIR_OUT); -+ mt_set_gpio_pull_enable(GPIO51, GPIO_PULL_ENABLE); -+ mt_set_gpio_pull_select(GPIO51, GPIO_PULL_DOWN); -+#elif defined(MTK_ALPS_BOX_SUPPORT) -+ /* for 8127 box */ -+ mt_set_gpio_mode(GPIO89, GPIO_MODE_04); -+ mt_set_gpio_dir(GPIO89, GPIO_DIR_OUT); -+ mt_set_gpio_pull_enable(GPIO89, GPIO_PULL_ENABLE); -+ mt_set_gpio_pull_select(GPIO89, GPIO_PULL_DOWN); -+#else -+ hwPowerDown(MT65XX_POWER_LDO_VGP4, "WLAN"); -+#endif -+#endif -+#else -+#ifdef CONFIG_OF /*for MT6752 */ -+ mtk_wcn_consys_hw_wifi_paldo_ctrl(0); /* switch to SW mode */ -+#else /*for MT6572/82/92 */ -+ upmu_set_vcn33_on_ctrl_wifi(0); /* switch to SW mode */ -+ hwPowerDown(MT6323_POWER_LDO_VCN33_WIFI, "WLAN"); -+#endif -+#endif -+ -+ } -+ -+ return 0; -+} -+ -+#if (MTK_WCN_SINGLE_MODULE == 0) -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function gets the TX count pass through HIF AHB bus. -+* -+* \param[in] None -+* -+* \return TX count -+*/ -+/*----------------------------------------------------------------------------*/ -+static int HifAhbBusCntGet(VOID) -+{ -+ return HifTxCnt; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function resets the TX count pass through HIF AHB bus. -+* -+* \param[in] None -+* -+* \return 0 -+*/ -+/*----------------------------------------------------------------------------*/ -+static int HifAhbBusCntClr(VOID) -+{ -+ HifTxCnt = 0; -+ return 0; -+} -+#endif /* MTK_WCN_SINGLE_MODULE */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function configs the DMA TX/RX settings before any real TX/RX. -+* -+* \param[in] GlueInfo Pointer to the GLUE_INFO_T structure. -+* \param[in] BurstLen 0(1DW), 1(4DW), 2(8DW), Others(Reserved) -+* \param[in] PortId 0(TXD0), 1(TXD1), 2(RXD0), 3(RXD1), 4(WHISR enhance) -+* \param[in] TransByte Should be 4-byte align. -+* -+* \return void -+*/ -+/*----------------------------------------------------------------------------*/ -+static UINT_32 HifAhbDmaEnhanceModeConf(IN GLUE_INFO_T * GlueInfo, UINT_32 BurstLen, UINT_32 PortId, UINT_32 TransByte) -+{ -+ GL_HIF_INFO_T *HifInfo; -+ UINT_32 RegHSTCR; -+ -+ ASSERT(GlueInfo); -+ HifInfo = &GlueInfo->rHifInfo; -+ -+ RegHSTCR = HIF_REG_READL(HifInfo, MCR_WHIER); -+ -+ RegHSTCR = HIF_REG_READL(HifInfo, MCR_HSTCR); -+ RegHSTCR = -+ ((BurstLen << HSTCR_AFF_BURST_LEN_OFFSET) & HSTCR_AFF_BURST_LEN) | -+ ((PortId << HSTCR_TRANS_TARGET_OFFSET) & HSTCR_TRANS_TARGET) | -+ (((TransByte & 0x3) == 0) ? (TransByte & HSTCR_HSIF_TRANS_CNT) : ((TransByte + 4) & HSTCR_HSIF_TRANS_CNT)); -+ HIF_REG_WRITEL(HifInfo, MCR_HSTCR, RegHSTCR); -+ return RegHSTCR; -+} -+ -+VOID glSetPowerState(IN GLUE_INFO_T *GlueInfo, IN UINT_32 ePowerMode) -+{ -+ -+} -+ -+#if (CONF_HIF_DEV_MISC == 1) -+/* no use */ -+static ssize_t HifAhbMiscRead(IN struct file *Filp, OUT char __user *DstBuf, IN size_t Size, IN loff_t *Ppos) -+{ -+ return 0; -+} -+ -+static ssize_t HifAhbMiscWrite(IN struct file *Filp, IN const char __user *SrcBuf, IN size_t Size, IN loff_t *Ppos) -+{ -+ return 0; -+} -+ -+static int HifAhbMiscIoctl(IN struct file *Filp, IN unsigned int Cmd, IN unsigned long arg) -+{ -+ return 0; -+} -+ -+static int HifAhbMiscOpen(IN struct inode *Inodep, IN struct file *Filp) -+{ -+ return 0; -+} -+ -+static int HifAhbMiscClose(IN struct inode *Inodep, IN struct file *Filp) -+{ -+ return 0; -+} -+#else -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is called by OS platform device module. -+* -+* \param[in] PDev Pointer to the platform device structure. -+* -+* \return 0 -+*/ -+/*----------------------------------------------------------------------------*/ -+static int HifAhbPltmProbe(IN struct platform_device *PDev) -+{ -+ HifAhbPDev = PDev; -+ -+ DBGLOG(INIT, INFO, "HifAhbPltmProbe\n"); -+ -+#if (CONF_HIF_PMIC_TEST == 1) -+ wmt_set_jtag_for_mcu(); -+ wmt_set_jtag_for_gps(); -+ -+#endif /* CONF_HIF_PMIC_TEST */ -+ -+#if (MTK_WCN_SINGLE_MODULE == 1) -+ HifAhbProbe(); /* only for test purpose without WMT module */ -+ -+#else -+ -+ /* register WiFi function to WMT */ -+ DBGLOG(INIT, INFO, "mtk_wcn_wmt_wlan_reg\n"); -+ { -+ MTK_WCN_WMT_WLAN_CB_INFO WmtCb; -+ -+ WmtCb.wlan_probe_cb = HifAhbProbe; -+ WmtCb.wlan_remove_cb = HifAhbRemove; -+ WmtCb.wlan_bus_cnt_get_cb = HifAhbBusCntGet; -+ WmtCb.wlan_bus_cnt_clr_cb = HifAhbBusCntClr; -+ mtk_wcn_wmt_wlan_reg(&WmtCb); -+ } -+#endif /* MTK_WCN_SINGLE_MODULE */ -+ return 0; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is called by OS platform device module. -+* -+* \param[in] PDev Pointer to the platform device structure. -+* -+* \return 0 -+*/ -+/*----------------------------------------------------------------------------*/ -+static int __exit HifAhbPltmRemove(IN struct platform_device *PDev) -+{ -+#if (MTK_WCN_SINGLE_MODULE == 0) -+ mtk_wcn_wmt_wlan_unreg(); -+#endif /* MTK_WCN_SINGLE_MODULE */ -+ return 0; -+} -+ -+#ifdef CONFIG_PM -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is called by OS platform device module. -+* -+* \param[in] PDev Pointer to the platform device structure. -+* \param[in] Message -+* -+* \return 0 -+*/ -+/*----------------------------------------------------------------------------*/ -+static int HifAhbPltmSuspend(IN struct platform_device *PDev, pm_message_t Message) -+{ -+ return 0; -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is called by OS platform device module. -+* -+* \param[in] PDev Pointer to the platform device structure. -+* -+* \return 0 -+*/ -+/*----------------------------------------------------------------------------*/ -+static int HifAhbPltmResume(IN struct platform_device *PDev) -+{ -+ return 0; -+} -+#endif /* CONFIG_PM */ -+ -+#endif /* CONF_HIF_DEV_MISC */ -+ -+#if (CONF_HIF_LOOPBACK_AUTO == 1) -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Trigger to do HIF loopback test. -+* -+* \param[in] arg Pointer to the GLUE_INFO_T structure. -+* -+* \retval None -+*/ -+/*----------------------------------------------------------------------------*/ -+static VOID HifAhbLoopbkAuto(IN unsigned long arg) -+{ -+ -+ P_GLUE_INFO_T GlueInfo = (P_GLUE_INFO_T) arg; -+ GL_HIF_INFO_T *HifInfo = &GlueInfo->rHifInfo; -+ -+ ASSERT(GlueInfo); -+ -+ HIF_DBG(("[WiFi/HIF] Trigger to do loopback test...\n")); -+ -+ set_bit(GLUE_FLAG_HIF_LOOPBK_AUTO_BIT, &HifInfo->HifLoopbkFlg); -+ wake_up_interruptible(&HifInfo->HifWaitq); -+ -+} -+#endif /* CONF_HIF_LOOPBACK_AUTO */ -+ -+VOID glDumpConnSysCpuInfo(P_GLUE_INFO_T prGlueInfo) -+{ -+ GL_HIF_INFO_T *prHifInfo = &prGlueInfo->rHifInfo; -+ unsigned short j; -+ -+ for (j = 0; j < 512; j++) { -+ DBGLOG(INIT, WARN, "0x%08x ", MCU_REG_READL(prHifInfo, CONN_MCU_CPUPCR)); -+ if ((j + 1) % 16 == 0) -+ DBGLOG(INIT, WARN, "\n"); -+ } -+} -+ -+/* End of ahb.c */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/arm.c b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/arm.c -new file mode 100644 -index 000000000000..6b719028ae93 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/arm.c -@@ -0,0 +1,31 @@ -+/****************************************************************************** -+*[File] mt6516-evb.c -+*[Version] v1.0 -+*[Revision Date] 2010-03-01 -+*[Author] -+*[Description] -+* dummy file for build system -+*[Copyright] -+* Copyright (C) 2010 MediaTek Incorporation. All Rights Reserved. -+******************************************************************************/ -+ -+/* -+** Log: mt6516-evb.c -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 04 19 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * remove debug message -+ * -+ * 03 24 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * initial import for Linux port -+** -+*/ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/include/hif.h b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/include/hif.h -new file mode 100644 -index 000000000000..1507d5560040 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/include/hif.h -@@ -0,0 +1,340 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux/hif/sdio/include/hif.h#1 -+*/ -+ -+/*! \file "hif.h" -+ \brief Functions for the driver to register bus and setup the IRQ -+ -+ Functions for the driver to register bus and setup the IRQ -+*/ -+ -+/* -+** Log: hif.h -+ * -+ * 11 01 2010 yarco.yang -+ * [WCXRP00000149] [MT6620 WI-Fi][Driver]Fine tune performance on MT6516 platform -+ * Add GPIO debug function -+ * -+ * 10 19 2010 jeffrey.chang -+ * [WCXRP00000120] [MT6620 Wi-Fi][Driver] Refine linux kernel module to the license of MTK propietary and enable MTK -+ * HIF by default -+ * Refine linux kernel module to the license of MTK and enable MTK HIF -+ * -+ * 08 18 2010 jeffrey.chang -+ * NULL -+ * support multi-function sdio -+ * -+ * 08 17 2010 cp.wu -+ * NULL -+ * add ENE SDIO host workaround for x86 linux platform. -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 03 24 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * initial import for Linux port -+** \main\maintrunk.MT5921\4 2009-10-20 17:38:28 GMT mtk01090 -+** Refine driver unloading and clean up procedure. Block requests, stop main thread and clean up queued requests, -+** and then stop hw. -+** \main\maintrunk.MT5921\3 2009-09-28 20:19:20 GMT mtk01090 -+** Add private ioctl to carry OID structures. Restructure public/private ioctl interfaces to Linux kernel. -+** \main\maintrunk.MT5921\2 2009-08-18 22:57:05 GMT mtk01090 -+** Add Linux SDIO (with mmc core) support. -+** Add Linux 2.6.21, 2.6.25, 2.6.26. -+** Fix compile warning in Linux. -+** \main\maintrunk.MT5921\2 2008-09-22 23:18:17 GMT mtk01461 -+** Update driver for code review -+** Revision 1.1 2007/07/05 07:25:33 MTK01461 -+** Add Linux initial code, modify doc, add 11BB, RF init code -+** -+** Revision 1.3 2007/06/27 02:18:51 MTK01461 -+** Update SCAN_FSM, Initial(Can Load Module), Proc(Can do Reg R/W), TX API -+** -+*/ -+ -+#ifndef _HIF_H -+#define _HIF_H -+ -+#include "gl_typedef.h" -+#include "mtk_porting.h" -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+#define CONF_MTK_AHB_DMA 1 /* PIO mode is default mode if DMA is disabled */ -+ -+#define CONF_HIF_DEV_MISC 0 /* register as misc device */ -+#define CONF_HIF_LOOPBACK_AUTO 0 /* hif loopback test triggered by open() */ -+ /* only for development test */ -+ -+#define CONF_HIF_PMIC_TEST 0 /* test purpose: power on CONNSYS */ -+ -+#define CONF_HIF_DMA_INT 0 /* DMA interrupt mode */ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+extern phys_addr_t gConEmiPhyBase; -+extern BOOLEAN fgIsResetting; -+extern UINT_32 IsrCnt, IsrPassCnt; -+extern int kalDevLoopbkThread(IN void *data); -+ -+#ifdef CONFIG_MTK_PMIC_MT6397 -+#else -+#ifdef CONFIG_OF /*for MT6752 */ -+extern INT_32 mtk_wcn_consys_hw_wifi_paldo_ctrl(UINT_32 enable); -+#else /*for MT6572/82/92 */ -+extern void upmu_set_vcn33_on_ctrl_wifi(UINT_32 val); -+#endif -+#endif -+ -+#if (CONF_HIF_DEV_MISC == 1) -+#else -+/* extern INT32 mtk_wcn_consys_hw_reg_ctrl(UINT32 on, UINT32 co_clock_en); */ -+#endif -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+#ifndef CONN_MCU_CONFIG_BASE -+#define CONN_MCU_CONFIG_BASE 0xF8070000 /* MT6572 */ -+#endif /* CONN_MCU_CONFIG_BASE */ -+ -+#define CONSYS_CPUPCR_REG (CONN_MCU_CONFIG_BASE + 0x00000160) -+#define CONSYS_REG_READ(addr) (*((volatile unsigned int *)(addr))) -+ -+#define CONN_MCU_DRV_BASE 0x18070000 -+#define CONN_MCU_REG_LENGTH 0x0200 -+#define CONN_MCU_CPUPCR 0x0160 -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/* host interface's private data structure, which is attached to os glue -+** layer info structure. -+ */ -+typedef struct _GL_HIF_DMA_OPS_T { /* DMA Operators */ -+ VOID (*DmaConfig)(IN VOID *HifInfo, IN VOID *Conf); -+ -+ VOID (*DmaStart)(IN VOID *HifInfo); -+ -+ VOID (*DmaStop)(IN VOID *HifInfo); -+ -+ MTK_WCN_BOOL (*DmaPollStart)(IN VOID *HifInfo); -+ -+ MTK_WCN_BOOL (*DmaPollIntr)(IN VOID *HifInfo); -+ -+ VOID (*DmaAckIntr)(IN VOID *HifInfo); -+ -+ VOID (*DmaClockCtrl)(IN UINT_32 FlgIsEnabled); -+ -+ VOID (*DmaRegDump)(IN VOID *HifInfo); -+ -+ VOID (*DmaReset)(IN VOID *HifInfo); -+ -+} GL_HIF_DMA_OPS_T; -+ -+typedef struct _GL_HIF_INFO_T { -+ -+ /* General */ -+ VOID *Dev; /* struct device */ -+ -+#define MTK_CHIP_ID_6571 0x6571 -+#define MTK_CHIP_ID_6572 0x6572 -+#define MTK_CHIP_ID_6582 0x6582 -+#define MTK_CHIP_ID_8127 0x8127 -+#define MTK_CHIP_ID_6752 0x6752 -+#define MTK_CHIP_ID_8163 0x8163 -+#define MTK_CHIP_ID_6735 0x6735 -+#define MTK_CHIP_ID_6580 0x6580 -+#define MTK_CHIP_ID_6755 0x6755 -+#define MTK_CHIP_ID_7623 0x7623 -+ -+ UINT_32 ChipID; -+ -+ /* Control flag */ -+ BOOLEAN fgIntReadClear; -+ BOOLEAN fgMbxReadClear; -+ BOOLEAN fgDmaEnable; /* TRUE: DMA mode is used (default) */ -+ -+ /* HIF related */ -+ UINT_8 *HifRegBaseAddr; /* HIF register base */ -+ UINT_8 *McuRegBaseAddr; /* CONN MCU register base */ -+ -+#if (CONF_HIF_LOOPBACK_AUTO == 1) -+ struct timer_list HifTmrLoopbkFn; /* HIF loopback test trigger timer */ -+ wait_queue_head_t HifWaitq; -+ UINT_32 HifLoopbkFlg; -+ struct task_struct *HifTaskLoopbkFn; /* HIF loopback test task */ -+#endif /* CONF_HIF_LOOPBACK_AUTO */ -+ -+#if (CONF_HIF_DMA_INT == 1) -+ wait_queue_head_t HifDmaWaitq; -+ UINT_32 HifDmaWaitFlg; -+#endif /* CONF_HIF_DMA_INT */ -+ -+ /* DMA related */ -+#define AP_DMA_HIF_LOCK(_lock) /* spin_lock_bh(&(_lock)->DdmaLock) */ -+#define AP_DMA_HIF_UNLOCK(_lock) /* spin_unlock_bh(&(_lock)->DdmaLock) */ -+ spinlock_t DdmaLock; /* protect DMA access */ -+ -+ UINT_8 *DmaRegBaseAddr; /* DMA register base */ -+ GL_HIF_DMA_OPS_T *DmaOps; /* DMA Operators */ -+ -+#if !defined(CONFIG_MTK_CLKMGR) -+ struct clk *clk_wifi_dma; -+#endif -+} GL_HIF_INFO_T, *P_GL_HIF_INFO_T; -+ -+#define HIF_MOD_NAME "AHB_SLAVE_HIF" -+ -+#define HIF_DRV_BASE 0x180F0000 -+#define HIF_DRV_LENGTH 0x005c -+ -+typedef enum _MTK_WCN_HIF_BURST_LEN { -+ HIF_BURST_1DW = 0, -+ HIF_BURST_4DW, -+ HIF_BURST_8DW -+} MTK_WCN_HIF_BURST_LEN; -+ -+typedef enum _MTK_WCN_HIF_TXRX_TARGET { -+ HIF_TARGET_TXD0 = 0, -+ HIF_TARGET_TXD1, -+ HIF_TARGET_RXD0, -+ HIF_TARGET_RXD1, -+ HIF_TARGET_WHISR -+} MTK_WCN_HIF_TXRX_TARGET; -+ -+typedef enum _MTK_WCN_HIF_DMA_DIR { -+ HIF_DMA_DIR_TX = 0, -+ HIF_DMA_DIR_RX -+} MTK_WCN_HIF_DMA_DIR; -+ -+typedef struct _MTK_WCN_HIF_DMA_CONF { -+ UINT_32 Count; -+ MTK_WCN_HIF_DMA_DIR Dir; -+ UINT_32 Burst; -+ UINT_32 Wsize; -+ UINT_32 Ratio; -+ UINT_32 Connect; -+ UINT_32 Fix_en; -+ ULONG Src; -+ ULONG Dst; -+} MTK_WCN_HIF_DMA_CONF; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+#define MCU_REG_READL(_hif, _addr) \ -+ readl((volatile UINT_32 *)((_hif)->McuRegBaseAddr + _addr)) -+ -+/* PIO mode HIF register read/write */ -+#define HIF_REG_READL(_hif, _addr) \ -+ readl((volatile UINT_32 *)((_hif)->HifRegBaseAddr + _addr)) -+ -+#define HIF_REG_WRITEL(_hif, _addr, _val) \ -+ writel(_val, ((volatile UINT_32 *)((_hif)->HifRegBaseAddr + _addr))) -+ -+#define HIF_REG_WRITEB(_hif, _addr, _val) \ -+ writeb(_val, ((volatile UINT_32 *)((_hif)->HifRegBaseAddr + _addr))) -+ -+/* PIO mode DMA register read/write */ -+#define HIF_DMAR_READL(_hif, _addr) \ -+ readl((volatile UINT_32 *)((_hif)->DmaRegBaseAddr + _addr)) -+ -+#define HIF_DMAR_WRITEL(_hif, _addr, _val) \ -+ writel(_val, ((volatile UINT_32 *)((_hif)->DmaRegBaseAddr + _addr))) -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+#ifndef MODULE_AHB_DMA -+VOID HifDumpEnhanceModeData(P_ADAPTER_T prAdapter); -+ -+VOID HifRegDump(P_ADAPTER_T prAdapter); -+ -+BOOLEAN HifIsFwOwn(P_ADAPTER_T prAdapter); -+ -+WLAN_STATUS glRegisterBus(probe_card pfProbe, remove_card pfRemove); -+ -+VOID glUnregisterBus(remove_card pfRemove); -+ -+VOID glResetHif(GLUE_INFO_T *GlueInfo); -+ -+VOID glSetHifInfo(P_GLUE_INFO_T prGlueInfo, ULONG ulCookie); -+ -+VOID glClearHifInfo(P_GLUE_INFO_T prGlueInfo); -+ -+VOID glGetChipInfo(GLUE_INFO_T *GlueInfo, UINT_8 *pucChipBuf); -+ -+#if CFG_SPM_WORKAROUND_FOR_HOTSPOT -+BOOLEAN glIsChipNeedWakelock(GLUE_INFO_T *GlueInfo); -+#endif -+ -+BOOLEAN glBusInit(PVOID pvData); -+ -+VOID glBusRelease(PVOID pData); -+ -+INT_32 glBusSetIrq(PVOID pvData, PVOID pfnIsr, PVOID pvCookie); -+ -+VOID glBusFreeIrq(PVOID pvData, PVOID pvCookie); -+ -+VOID glSetPowerState(IN P_GLUE_INFO_T prGlueInfo, IN UINT_32 ePowerMode); -+ -+VOID glDumpConnSysCpuInfo(P_GLUE_INFO_T prGlueInfo); -+ -+#endif /* MODULE_AHB_DMA */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Config GDMA TX/RX. -+* -+* \param[in] DmaRegBaseAddr Pointer to the IO register base. -+* \param[in] Conf Pointer to the DMA operator. -+* -+* \retval NONE -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID HifGdmaInit(GL_HIF_INFO_T *HifInfo); -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Config PDMA TX/RX. -+* -+* \param[in] DmaRegBaseAddr Pointer to the IO register base. -+* \param[in] Conf Pointer to the DMA operator. -+* -+* \retval NONE -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID HifPdmaInit(GL_HIF_INFO_T *HifInfo); -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+#endif /* _HIF_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/include/hif_gdma.h b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/include/hif_gdma.h -new file mode 100644 -index 000000000000..094c07f98eff ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/include/hif_gdma.h -@@ -0,0 +1,154 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux/hif/sdio/include/hif.h#1 -+*/ -+ -+/*! \file "hif_gdma.h" -+ \brief MARCO, definition, structure for GDMA. -+ -+ MARCO, definition, structure for GDMA. -+*/ -+ -+/* -+** Log: hif_gdma.h -+ * -+ * 01 16 2013 vend_samp.lin -+ * Add AHB GDMA support -+ * 1) Initial version -+** -+*/ -+ -+#ifndef _HIF_GDMA_H -+#define _HIF_GDMA_H -+ -+#include "mtk_porting.h" -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+typedef enum _MTK_WCN_HIF_GDMA_BURST_LEN { -+ HIF_GDMA_BURST_1_8 = 0, -+ HIF_GDMA_BURST_2_8, -+ HIF_GDMA_BURST_3_8, -+ HIF_GDMA_BURST_4_8, -+ HIF_GDMA_BURST_5_8, -+ HIF_GDMA_BURST_6_8, -+ HIF_GDMA_BURST_7_8, -+ HIF_GDMA_BURST_8_8 /* same as HIF_GDMA_BURST_7_8 */ -+} MTK_WCN_HIF_GDMA_BURST_LEN; -+ -+typedef enum _MTK_WCN_HIF_GDMA_WRITE_LEN { -+ HIF_GDMA_WRITE_0 = 0, /* transaction size is 1 byte */ -+ HIF_GDMA_WRITE_1, /* transaction size is 2 byte */ -+ HIF_GDMA_WRITE_2, /* transaction size is 4 byte */ -+ HIF_GDMA_WRITE_3 /* transaction size is 1 byte */ -+} MTK_WCN_HIF_GDMA_WRITE_LEN; -+ -+typedef enum _MTK_WCN_HIF_GDMA_RATIO { -+ HIF_GDMA_RATIO_0 = 0, /* 1/2 */ -+ HIF_GDMA_RATIO_1 /* 1/1 */ -+} MTK_WCN_HIF_GDMA_RATIO; -+ -+typedef enum _MTK_WCN_HIF_GDMA_CONNECT { -+ HIF_GDMA_CONNECT_NO = 0, /* no connect */ -+ HIF_GDMA_CONNECT_SET1, /* connect set1 (req/ack) */ -+ HIF_GDMA_CONNECT_SET2, /* connect set2 (req/ack) */ -+ HIF_GDMA_CONNECT_SET3 /* connect set3 (req/ack) */ -+} MTK_WCN_HIF_GDMA_CONNECT; -+ -+/* reference to MT6572_AP_P_DMA_Spec.doc */ -+#define AP_DMA_HIF_BASE 0x11000100 -+ -+#define AP_P_DMA_G_DMA_2_INT_FLAG (0x0000) -+#define AP_P_DMA_G_DMA_2_CON (0x0018) -+#define AP_P_DMA_G_DMA_2_CONNECT (0x0034) -+#define AP_P_DMA_G_DMA_2_LEN1 (0x0024) -+#define AP_P_DMA_G_DMA_2_SRC_ADDR (0x001C) -+#define AP_P_DMA_G_DMA_2_DST_ADDR (0x0020) -+#define AP_P_DMA_G_DMA_2_INT_EN (0x0004) -+#define AP_P_DMA_G_DMA_2_EN (0x0008) -+#define AP_P_DMA_G_DMA_2_RST (0x000C) -+#define AP_P_DMA_G_DMA_2_STOP (0x0010) -+ -+#define AP_DMA_HIF_0_LENGTH 0x0038 -+ -+/* AP_DMA_HIF_0_INT_FLAG */ -+#define ADH_CR_FLAG_0 BIT(0) -+ -+/* AP_DMA_HIF_0_INT_EN */ -+#define ADH_CR_INTEN_FLAG_0 BIT(0) -+ -+/* AP_DMA_HIF_0_EN */ -+#define ADH_CR_EN BIT(0) -+#define ADH_CR_CONN_BUR_EN BIT(1) -+ -+/* AP_DMA_HIF_0_STOP */ -+#define ADH_CR_PAUSE BIT(1) -+#define ADH_CR_STOP BIT(0) -+ -+/* AP_P_DMA_G_DMA_2_CON */ -+#define ADH_CR_FLAG_FINISH BIT(30) -+#define ADH_CR_RSIZE BITS(28, 29) -+#define ADH_CR_RSIZE_OFFSET 28 -+#define ADH_CR_WSIZE BITS(24, 25) -+#define ADH_CR_WSIZE_OFFSET 24 -+#define ADH_CR_BURST_LEN BITS(16, 18) -+#define ADH_CR_BURST_LEN_OFFSET 16 -+#define ADH_CR_WADDR_FIX_EN BIT(3) -+#define ADH_CR_WADDR_FIX_EN_OFFSET 3 -+#define ADH_CR_RADDR_FIX_EN BIT(4) -+#define ADH_CR_RADDR_FIX_EN_OFFSET 4 -+ -+/* AP_P_DMA_G_DMA_2_CONNECT */ -+#define ADH_CR_RATIO BIT(3) -+#define ADH_CR_RATIO_OFFSET 3 -+#define ADH_CR_DIR BIT(2) -+#define ADH_CR_DIR_OFFSET 2 -+#define ADH_CR_CONNECT BITS(0, 1) -+ -+/* AP_DMA_HIF_0_LEN */ -+#define ADH_CR_LEN BITS(0, 19) -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+#endif /* _HIF_GDMA_H */ -+ -+/* End of hif_gdma.h */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/include/hif_pdma.h b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/include/hif_pdma.h -new file mode 100644 -index 000000000000..32224e8f17d8 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/include/hif_pdma.h -@@ -0,0 +1,141 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux/hif/sdio/include/hif.h#1 -+*/ -+ -+/*! \file "hif_pdma.h" -+ \brief MARCO, definition, structure for PDMA. -+ -+ MARCO, definition, structure for PDMA. -+*/ -+ -+/* -+** Log: hif_pdma.h -+ * -+ * 01 16 2013 vend_samp.lin -+ * Add AHB PDMA support -+ * 1) Initial version -+** -+*/ -+ -+#ifndef _HIF_PDMA_H -+#define _HIF_PDMA_H -+ -+#include "mtk_porting.h" -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+typedef enum _MTK_WCN_HIF_PDMA_BURST_LEN { -+ HIF_PDMA_BURST_1_4 = 0, -+ HIF_PDMA_BURST_2_4, -+ HIF_PDMA_BURST_3_4, -+ HIF_PDMA_BURST_4_4 -+} MTK_WCN_HIF_PDMA_BURST_LEN; -+ -+/* reference to MT6572_AP_P_DMA_Spec.doc */ -+#ifdef CONFIG_OF -+/*for MT6752*/ -+#define AP_DMA_HIF_BASE 0x11000080 -+#else -+/*for MT6572/82/92*/ -+#define AP_DMA_HIF_BASE 0x11000180 -+#endif -+ -+#define AP_DMA_HIF_0_INT_FLAG (0x0000) -+#define AP_DMA_HIF_0_INT_EN (0x0004) -+#define AP_DMA_HIF_0_EN (0x0008) -+#define AP_DMA_HIF_0_RST (0x000C) -+#define AP_DMA_HIF_0_STOP (0x0010) -+#define AP_DMA_HIF_0_FLUSH (0x0014) -+#define AP_DMA_HIF_0_CON (0x0018) -+#define AP_DMA_HIF_0_SRC_ADDR (0x001C) -+#define AP_DMA_HIF_0_DST_ADDR (0x0020) -+#define AP_DMA_HIF_0_LEN (0x0024) -+#define AP_DMA_HIF_0_INT_BUF_SIZE (0x0038) -+#define AP_DMA_HIF_0_DEBUG_STATUS (0x0050) -+#define AP_DMA_HIF_0_SRC_ADDR2 (0x0054) -+#define AP_DMA_HIF_0_DST_ADDR2 (0x0058) -+ -+#define AP_DMA_HIF_0_LENGTH 0x0080 -+ -+/* AP_DMA_HIF_0_INT_FLAG */ -+#define ADH_CR_FLAG_0 BIT(0) -+ -+/* AP_DMA_HIF_0_INT_EN */ -+#define ADH_CR_INTEN_FLAG_0 BIT(0) -+ -+/* AP_DMA_HIF_0_EN */ -+#define ADH_CR_EN BIT(0) -+ -+/* AP_DMA_HIF_0_RST */ -+#define ADH_CR_HARD_RST BIT(1) -+#define ADH_CR_WARM_RST BIT(0) -+ -+/* AP_DMA_HIF_0_STOP */ -+#define ADH_CR_PAUSE BIT(1) -+#define ADH_CR_STOP BIT(0) -+ -+/* AP_DMA_HIF_0_FLUSH */ -+#define ADH_CR_FLUSH BIT(0) -+ -+/* AP_DMA_HIF_0_CON */ -+#define ADH_CR_BURST_LEN BITS(16, 17) -+#define ADH_CR_BURST_LEN_OFFSET 16 -+#define ADH_CR_SLOW_CNT BITS(5, 14) -+#define ADH_CR_SLOW_EN BIT(2) -+#define ADH_CR_FIX_EN BIT(1) -+#define ADH_CR_FIX_EN_OFFSET 1 -+#define ADH_CR_DIR BIT(0) -+ -+/* AP_DMA_HIF_0_LEN */ -+#define ADH_CR_LEN BITS(0, 19) -+ -+/* AP_DMA_HIF_0_SRC_ADDR2 */ -+#define ADH_CR_SRC_ADDR2 BIT(0) -+/* AP_DMA_HIF_0_DST_ADDR2 */ -+#define ADH_CR_DST_ADDR2 BIT(0) -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+#endif /* _HIF_PDMA_H */ -+ -+/* End of hif_gdma.h */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/include/mtk_porting.h b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/include/mtk_porting.h -new file mode 100644 -index 000000000000..91557137af9a ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/include/mtk_porting.h -@@ -0,0 +1,91 @@ -+/* porting layer */ -+/* Android */ -+ -+#ifndef _MTK_PORTING_H_ -+#define _MTK_PORTING_H_ -+ -+#include /* include stddef.h for NULL */ -+ -+#define CONF_MTK_AHB_DMA 1 -+ -+/* Type definition for signed integers */ -+/*typedef signed char INT8, *PINT8; -+typedef signed short INT16, *PINT16; -+typedef signed int INT_32, *PINT32;*/ -+ -+/* Type definition for unsigned integers */ -+/*typedef unsigned char UINT8, *PUINT8; -+typedef unsigned short UINT16, *PUINT16; -+typedef unsigned int UINT32, *PUINT32;*/ -+ -+#ifndef VOID -+/*typedef void VOID, *PVOID;*/ -+#endif -+ -+#ifndef IN -+#define IN -+#endif -+ -+#ifndef OUT -+#define OUT -+#endif -+ -+#ifndef INTOUT -+#define INOUT -+#endif -+ -+#ifndef TRUE -+#define TRUE 1 -+#endif -+ -+#ifndef FALSE -+#define FALSE 0 -+#endif -+ -+#ifndef BIT -+#define BIT(n) ((UINT_32) 1U << (n)) -+#endif /* BIT */ -+ -+#ifndef BITS -+/* bits range: for example BITS(16,23) = 0xFF0000 -+ * ==> (BIT(m)-1) = 0x0000FFFF ~(BIT(m)-1) => 0xFFFF0000 -+ * ==> (BIT(n+1)-1) = 0x00FFFFFF -+ */ -+#define BITS(m, n) (~(BIT(m)-1) & ((BIT(n) - 1) | BIT(n))) -+#endif /* BIT */ -+ -+#ifndef BOOLEAN -+#define BOOLEAN unsigned char -+#endif -+ -+typedef int MTK_WCN_BOOL; -+#ifndef MTK_WCN_BOOL_TRUE -+#define MTK_WCN_BOOL_FALSE ((MTK_WCN_BOOL) 0) -+#define MTK_WCN_BOOL_TRUE ((MTK_WCN_BOOL) 1) -+#endif -+ -+typedef int MTK_WCN_MUTEX; -+ -+typedef int MTK_WCN_TIMER; -+ -+/* system APIs */ -+/* mutex */ -+typedef MTK_WCN_MUTEX(*MUTEX_CREATE) (const char *const name); -+typedef INT_32(*MUTEX_DESTROY) (MTK_WCN_MUTEX mtx); -+typedef INT_32(*MUTEX_LOCK) (MTK_WCN_MUTEX mtx); -+typedef INT_32(*MUTEX_UNLOCK) (MTK_WCN_MUTEX mtx, unsigned long flags); -+/* debug */ -+typedef INT_32(*DBG_PRINT) (const char *str, ...); -+typedef INT_32(*DBG_ASSERT) (INT_32 expr, const char *file, INT_32 line); -+/* timer */ -+typedef void (*MTK_WCN_TIMER_CB) (void); -+typedef MTK_WCN_TIMER(*TIMER_CREATE) (const char *const name); -+typedef INT_32(*TIMER_DESTROY) (MTK_WCN_TIMER tmr); -+typedef INT_32(*TIMER_START) (MTK_WCN_TIMER tmr, UINT_32 timeout, MTK_WCN_TIMER_CB tmr_cb, void *param); -+typedef INT_32(*TIMER_STOP) (MTK_WCN_TIMER tmr); -+/* kernel lib */ -+typedef void *(*SYS_MEMCPY) (void *dest, const void *src, UINT_32 n); -+typedef void *(*SYS_MEMSET) (void *s, INT_32 c, UINT_32 n); -+typedef INT_32(*SYS_SPRINTF) (char *str, const char *format, ...); -+ -+#endif /* _MTK_PORTING_H_ */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/mt8127/ahb_pdma.c b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/mt8127/ahb_pdma.c -new file mode 100644 -index 000000000000..94cc05ba3224 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/hif/ahb/mt8127/ahb_pdma.c -@@ -0,0 +1,480 @@ -+/****************************************************************************** -+*[File] ahb_pdma.c -+*[Version] v1.0 -+*[Revision Date] 2013-03-13 -+*[Author] -+*[Description] -+* The program provides AHB PDMA driver -+*[Copyright] -+* Copyright (C) 2013 MediaTek Incorporation. All Rights Reserved. -+******************************************************************************/ -+ -+/* -+** Log: ahb_pdma.c -+ * -+ * 03 13 2013 vend_samp.lin -+ * Add AHB PDMA support -+ * 1) Initial version -+** -+*/ -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+#define MODULE_AHB_DMA -+ -+#include /* constant of kernel version */ -+ -+#include /* bitops.h */ -+ -+#include /* struct timer_list */ -+#include /* jiffies */ -+#include /* udelay and mdelay macro */ -+ -+#if 0 -+#if CONFIG_ANDROID -+#include -+#endif -+#endif -+ -+#include /* IRQT_FALLING */ -+ -+#include /* struct net_device, struct net_device_stats */ -+#include /* for eth_type_trans() function */ -+#include /* struct iw_statistics */ -+#include -+#include /* struct in_device */ -+ -+#include /* struct iphdr */ -+ -+#include /* for memcpy()/memset() function */ -+#include /* for offsetof() macro */ -+ -+#include /* The proc filesystem constants/structures */ -+ -+#include /* for rtnl_lock() and rtnl_unlock() */ -+#include /* kthread_should_stop(), kthread_run() */ -+#include /* for copy_from_user() */ -+#include /* for firmware download */ -+#include -+ -+#include /* for kfifo interface */ -+#include /* for cdev interface */ -+ -+#include /* for firmware download */ -+ -+#include -+ -+#include /* readw and writew */ -+ -+#include -+ -+#if defined(CONFIG_MTK_CLKMGR) -+#include -+#else -+#include -+#endif /* defined(CONFIG_MTK_CLKMGR) */ -+ -+#include "hif.h" -+#include "hif_pdma.h" -+#include "gl_os.h" -+ -+/* #include */ -+ -+/* #if (CONF_MTK_AHB_DMA == 1) */ -+ -+/* #define PDMA_DEBUG_SUP */ -+ -+#ifdef PDMA_DEBUG_SUP -+#define PDMA_DBG pr_debug -+#else -+#define PDMA_DBG(_fmt, ...) -+#endif /* PDMA_DEBUG_SUP */ -+ -+#if !defined(CONFIG_MTK_CLKMGR) -+struct clk *g_clk_wifi_pdma; -+#endif -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+static VOID HifPdmaConfig(IN void *HifInfoSrc, IN void *Conf); -+ -+static VOID HifPdmaStart(IN void *HifInfoSrc); -+ -+static VOID HifPdmaStop(IN void *HifInfoSrc); -+ -+static MTK_WCN_BOOL HifPdmaPollStart(IN void *HifInfoSrc); -+ -+static MTK_WCN_BOOL HifPdmaPollIntr(IN void *HifInfoSrc); -+ -+static VOID HifPdmaAckIntr(IN void *HifInfoSrc); -+ -+static VOID HifPdmaClockCtrl(IN UINT32 FlgIsEnabled); -+ -+static VOID HifPdmaRegDump(IN void *HifInfoSrc); -+ -+static VOID HifPdmaReset(IN void *HifInfoSrc); -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+GL_HIF_DMA_OPS_T HifPdmaOps = { -+ .DmaConfig = HifPdmaConfig, -+ .DmaStart = HifPdmaStart, -+ .DmaStop = HifPdmaStop, -+ .DmaPollStart = HifPdmaPollStart, -+ .DmaPollIntr = HifPdmaPollIntr, -+ .DmaAckIntr = HifPdmaAckIntr, -+ .DmaClockCtrl = HifPdmaClockCtrl, -+ .DmaRegDump = HifPdmaRegDump, -+ .DmaReset = HifPdmaReset -+}; -+ -+/******************************************************************************* -+* P U B L I C F U N C T I O N S -+******************************************************************************** -+*/ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Config PDMA TX/RX. -+* -+* \param[in] prGlueInfo Pointer to the GLUE_INFO_T structure. -+* \param[in] Conf Pointer to the settings. -+* -+* \retval NONE -+*/ -+/*----------------------------------------------------------------------------*/ -+VOID HifPdmaInit(GL_HIF_INFO_T *HifInfo) -+{ -+ /* IO remap PDMA register memory */ -+#ifdef AP_DMA_HIF_BASE -+#undef AP_DMA_HIF_BASE -+#define AP_DMA_HIF_BASE 0x11000180 -+#endif -+ HifInfo->DmaRegBaseAddr = ioremap(AP_DMA_HIF_BASE, AP_DMA_HIF_0_LENGTH); -+ -+ /* assign PDMA operators */ -+ HifInfo->DmaOps = &HifPdmaOps; -+ -+ /* enable PDMA mode */ -+ HifInfo->fgDmaEnable = TRUE; -+ -+ /* Set EMI protection here */ -+#if 0 -+#ifdef MTK_TEE_CCCI_SECURE_SHARE_MEM_SUPPORT -+ DBGLOG(INIT, INFO, "WIFI set EMI MPU for TEE project\n"); -+ emi_mpu_set_region_protection(gConEmiPhyBase, -+ gConEmiPhyBase + SZ_1M / 2, -+ 5, SET_ACCESS_PERMISSON(FORBIDDEN, NO_PROTECTION, FORBIDDEN, FORBIDDEN)); -+#else -+ DBGLOG(INIT, INFO, "WIFI set EMI MPU for non-TEE project\n"); -+ emi_mpu_set_region_protection(gConEmiPhyBase, -+ gConEmiPhyBase + SZ_1M / 2, -+ 4, SET_ACCESS_PERMISSON(FORBIDDEN, NO_PROTECTION, FORBIDDEN, FORBIDDEN)); -+#endif -+#endif -+ -+#if !defined(CONFIG_MTK_CLKMGR) -+ g_clk_wifi_pdma = HifInfo->clk_wifi_dma; -+#endif -+ -+ PDMA_DBG("PDMA> HifPdmaInit ok!\n"); -+} -+ -+/******************************************************************************* -+* P R I V A T E F U N C T I O N S -+******************************************************************************** -+*/ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Config PDMA TX/RX. -+* -+* \param[in] HifInfo Pointer to the GL_HIF_INFO_T structure. -+* \param[in] Param Pointer to the settings. -+* -+* \retval NONE -+*/ -+/*----------------------------------------------------------------------------*/ -+static VOID HifPdmaConfig(IN void *HifInfoSrc, IN void *Param) -+{ -+ GL_HIF_INFO_T *HifInfo = (GL_HIF_INFO_T *) HifInfoSrc; -+ MTK_WCN_HIF_DMA_CONF *Conf = (MTK_WCN_HIF_DMA_CONF *) Param; -+ UINT32 RegVal; -+ -+ /* Assign fixed value */ -+ Conf->Burst = HIF_PDMA_BURST_4_4; /* vs. HIF_BURST_4DW */ -+ Conf->Fix_en = FALSE; -+ -+ /* AP_P_DMA_G_DMA_2_CON */ -+ PDMA_DBG("PDMA> Conf->Dir = %d\n", Conf->Dir); -+ -+ /* AP_DMA_HIF_0_CON */ -+ RegVal = HIF_DMAR_READL(HifInfo, AP_DMA_HIF_0_CON); -+ RegVal &= ~(ADH_CR_BURST_LEN | ADH_CR_FIX_EN | ADH_CR_DIR); -+ RegVal |= (((Conf->Burst << ADH_CR_BURST_LEN_OFFSET) & ADH_CR_BURST_LEN) | -+ (Conf->Fix_en << ADH_CR_FIX_EN_OFFSET) | (Conf->Dir)); -+ HIF_DMAR_WRITEL(HifInfo, AP_DMA_HIF_0_CON, RegVal); -+ PDMA_DBG("PDMA> AP_DMA_HIF_0_CON = 0x%08x\n", RegVal); -+ -+ /* AP_DMA_HIF_0_SRC_ADDR */ -+ HIF_DMAR_WRITEL(HifInfo, AP_DMA_HIF_0_SRC_ADDR, Conf->Src); -+ PDMA_DBG("PDMA> AP_DMA_HIF_0_SRC_ADDR = 0x%08lx\n", Conf->Src); -+ -+ /* AP_DMA_HIF_0_DST_ADDR */ -+ HIF_DMAR_WRITEL(HifInfo, AP_DMA_HIF_0_DST_ADDR, Conf->Dst); -+ PDMA_DBG("PDMA> AP_DMA_HIF_0_DST_ADDR = 0x%08lx\n", Conf->Dst); -+ -+ /* AP_DMA_HIF_0_LEN */ -+ HIF_DMAR_WRITEL(HifInfo, AP_DMA_HIF_0_LEN, (Conf->Count & ADH_CR_LEN)); -+ PDMA_DBG("PDMA> AP_DMA_HIF_0_LEN = %u\n", (UINT_32)(Conf->Count & ADH_CR_LEN)); -+ -+} /* End of HifPdmaConfig */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Start PDMA TX/RX. -+* -+* \param[in] HifInfo Pointer to the GL_HIF_INFO_T structure. -+* -+* \retval NONE -+*/ -+/*----------------------------------------------------------------------------*/ -+static VOID HifPdmaStart(IN void *HifInfoSrc) -+{ -+ GL_HIF_INFO_T *HifInfo = (GL_HIF_INFO_T *) HifInfoSrc; -+ UINT32 RegVal; -+ -+ /* Enable interrupt */ -+ RegVal = HIF_DMAR_READL(HifInfo, AP_DMA_HIF_0_INT_EN); -+ HIF_DMAR_WRITEL(HifInfo, AP_DMA_HIF_0_INT_EN, (RegVal | ADH_CR_INTEN_FLAG_0)); -+ -+ /* Start DMA */ -+ RegVal = HIF_DMAR_READL(HifInfo, AP_DMA_HIF_0_EN); -+ HIF_DMAR_WRITEL(HifInfo, AP_DMA_HIF_0_EN, (RegVal | ADH_CR_EN)); -+ -+ PDMA_DBG("PDMA> HifPdmaStart...\n"); -+ -+} /* End of HifPdmaStart */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Stop PDMA TX/RX. -+* -+* \param[in] HifInfo Pointer to the GL_HIF_INFO_T structure. -+* -+* \retval NONE -+*/ -+/*----------------------------------------------------------------------------*/ -+static VOID HifPdmaStop(IN void *HifInfoSrc) -+{ -+ GL_HIF_INFO_T *HifInfo = (GL_HIF_INFO_T *) HifInfoSrc; -+ UINT32 RegVal; -+/* UINT32 pollcnt; */ -+ -+ /* Disable interrupt */ -+ RegVal = HIF_DMAR_READL(HifInfo, AP_DMA_HIF_0_INT_EN); -+ HIF_DMAR_WRITEL(HifInfo, AP_DMA_HIF_0_INT_EN, (RegVal & ~(ADH_CR_INTEN_FLAG_0))); -+ -+#if 0 /* DE says we donot need to do it */ -+ /* Stop DMA */ -+ RegVal = HIF_DMAR_READL(HifInfo, AP_DMA_HIF_0_STOP); -+ HIF_DMAR_WRITEL(HifInfo, AP_DMA_HIF_0_STOP, (RegVal | ADH_CR_STOP)); -+ -+ /* Polling START bit turn to 0 */ -+ pollcnt = 0; -+ do { -+ RegVal = HIF_DMAR_READL(HifInfo, AP_DMA_HIF_0_EN); -+ if (pollcnt++ > 100000) -+ ; /* TODO: warm reset PDMA */ -+ } while (RegVal & ADH_CR_EN); -+#endif -+ -+} /* End of HifPdmaStop */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Enable PDMA TX/RX. -+* -+* \param[in] HifInfo Pointer to the GL_HIF_INFO_T structure. -+* -+* \retval NONE -+*/ -+/*----------------------------------------------------------------------------*/ -+static MTK_WCN_BOOL HifPdmaPollStart(IN void *HifInfoSrc) -+{ -+ GL_HIF_INFO_T *HifInfo = (GL_HIF_INFO_T *) HifInfoSrc; -+ UINT32 RegVal; -+ -+ RegVal = HIF_DMAR_READL(HifInfo, AP_DMA_HIF_0_EN); -+ return ((RegVal & ADH_CR_EN) != 0) ? TRUE : FALSE; -+ -+} /* End of HifPdmaPollStart */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Poll PDMA TX/RX done. -+* -+* \param[in] HifInfo Pointer to the GL_HIF_INFO_T structure. -+* -+* \retval NONE -+*/ -+/*----------------------------------------------------------------------------*/ -+static MTK_WCN_BOOL HifPdmaPollIntr(IN void *HifInfoSrc) -+{ -+ GL_HIF_INFO_T *HifInfo = (GL_HIF_INFO_T *) HifInfoSrc; -+ UINT32 RegVal; -+ -+ RegVal = HIF_DMAR_READL(HifInfo, AP_DMA_HIF_0_INT_FLAG); -+ return ((RegVal & ADH_CR_FLAG_0) != 0) ? TRUE : FALSE; -+ -+} /* End of HifPdmaPollIntr */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Acknowledge PDMA TX/RX done. -+* -+* \param[in] HifInfo Pointer to the GL_HIF_INFO_T structure. -+* -+* \retval NONE -+*/ -+/*----------------------------------------------------------------------------*/ -+static VOID HifPdmaAckIntr(IN void *HifInfoSrc) -+{ -+ GL_HIF_INFO_T *HifInfo = (GL_HIF_INFO_T *) HifInfoSrc; -+ UINT32 RegVal; -+ -+ /* Write 0 to clear interrupt */ -+ RegVal = HIF_DMAR_READL(HifInfo, AP_DMA_HIF_0_INT_FLAG); -+ HIF_DMAR_WRITEL(HifInfo, AP_DMA_HIF_0_INT_FLAG, (RegVal & ~ADH_CR_FLAG_0)); -+ -+} /* End of HifPdmaAckIntr */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Acknowledge PDMA TX/RX done. -+* -+* \param[in] FlgIsEnabled TRUE: enable; FALSE: disable -+* -+* \retval NONE -+*/ -+/*----------------------------------------------------------------------------*/ -+static VOID HifPdmaClockCtrl(IN UINT32 FlgIsEnabled) -+{ -+#if !defined(CONFIG_MTK_CLKMGR) -+ int ret = 0; -+#endif -+#if defined(CONFIG_MTK_CLKMGR) -+ if (FlgIsEnabled == TRUE) -+ enable_clock(MT_CG_INFRA_APDMA, "WLAN"); -+ else -+ disable_clock(MT_CG_INFRA_APDMA, "WLAN"); -+#else -+ if (FlgIsEnabled == TRUE) { -+ ret = clk_prepare_enable(g_clk_wifi_pdma); -+ if (ret) -+ DBGLOG(INIT, TRACE, "[CCF]clk_prepare_enable ret= %d\n", ret); -+ } else { -+ clk_disable_unprepare(g_clk_wifi_pdma); -+ } -+#endif -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Dump PDMA related registers. -+* -+* \param[in] HifInfo Pointer to the GL_HIF_INFO_T structure. -+* -+* \retval NONE -+*/ -+/*----------------------------------------------------------------------------*/ -+static VOID HifPdmaRegDump(IN void *HifInfoSrc) -+{ -+ GL_HIF_INFO_T *HifInfo = (GL_HIF_INFO_T *) HifInfoSrc; -+ UINT32 RegId, RegVal; -+ UINT32 RegNum = 0; -+ -+ DBGLOG(INIT, INFO, "PDMA> Register content 0x%x=\n\t", AP_DMA_HIF_BASE); -+ for (RegId = 0; RegId < AP_DMA_HIF_0_LENGTH; RegId += 4) { -+ RegVal = HIF_DMAR_READL(HifInfo, RegId); -+ DBGLOG(INIT, INFO, "0x%08x ", RegVal); -+ -+ if (RegNum++ >= 3) { -+ DBGLOG(INIT, INFO, "\n"); -+ DBGLOG(INIT, INFO, "PDMA> Register content 0x%x=\n\t", AP_DMA_HIF_BASE + RegId + 4); -+ RegNum = 0; -+ } -+ } -+ -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Reset DMA. -+* -+* \param[in] HifInfo Pointer to the GL_HIF_INFO_T structure. -+* -+* \retval NONE -+*/ -+/*----------------------------------------------------------------------------*/ -+static VOID HifPdmaReset(IN void *HifInfoSrc) -+{ -+ GL_HIF_INFO_T *HifInfo = (GL_HIF_INFO_T *) HifInfoSrc; -+ UINT32 LoopCnt; -+ -+ /* do warm reset: DMA will wait for current traction finished */ -+ DBGLOG(INIT, INFO, "\nDMA> do warm reset...\n"); -+ -+ /* normally, we need to sure that bit0 of AP_P_DMA_G_DMA_2_EN is 1 here */ -+ -+ HIF_DMAR_WRITEL(HifInfo, AP_DMA_HIF_0_RST, 0x01); -+ -+ for (LoopCnt = 0; LoopCnt < 10000; LoopCnt++) { -+ if (!HifPdmaPollStart(HifInfo)) -+ break; /* reset ok */ -+ } -+ -+ if (HifPdmaPollStart(HifInfo)) { -+ /* do hard reset because warm reset fails */ -+ DBGLOG(INIT, INFO, "\nDMA> do hard reset...\n"); -+ HIF_DMAR_WRITEL(HifInfo, AP_DMA_HIF_0_RST, 0x02); -+ mdelay(1); -+ HIF_DMAR_WRITEL(HifInfo, AP_DMA_HIF_0_RST, 0x00); -+ } -+} -+ -+/* #endif */ /* CONF_MTK_AHB_DMA */ -+ -+/* End of ahb_pdma.c */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_cfg80211.h b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_cfg80211.h -new file mode 100644 -index 000000000000..ec9f46bdab2e ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_cfg80211.h -@@ -0,0 +1,341 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux/include/gl_cfg80211.h#1 -+*/ -+ -+/*! \file gl_cfg80211.h -+ \brief This file is for Portable Driver linux cfg80211 support. -+*/ -+ -+/* -+** Log: gl_cfg80211.h -+** -+** 09 03 2013 cp.wu -+** add path for reassociation -+** -+** 09 12 2012 wcpadmin -+** [ALPS00276400] Remove MTK copyright and legal header on GPL/LGPL related packages -+** . -+** -+** 08 30 2012 chinglan.wang -+** [ALPS00349664] [6577JB][WIFI] Phone can not connect to AP secured with AES via WPS in 802.11n Only -+** . -+ * -+*/ -+ -+#ifndef _GL_CFG80211_H -+#define _GL_CFG80211_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include -+#include -+#include -+#include -+#include -+ -+#include "gl_os.h" -+extern void wlanHandleSystemResume(void); -+extern void wlanHandleSystemSuspend(void); -+extern void p2pHandleSystemResume(void); -+extern void p2pHandleSystemSuspend(void); -+ -+#if CFG_SUPPORT_WAPI -+extern UINT_8 keyStructBuf[1024]; /* add/remove key shared buffer */ -+#else -+extern UINT_8 keyStructBuf[100]; /* add/remove key shared buffer */ -+#endif -+ -+extern struct delayed_work sched_workq; -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+#if CONFIG_NL80211_TESTMODE -+#define NL80211_DRIVER_TESTMODE_VERSION 2 -+#endif -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+#if CONFIG_NL80211_TESTMODE -+ -+typedef struct _NL80211_DRIVER_GET_STA_STATISTICS_PARAMS { -+ NL80211_DRIVER_TEST_MODE_PARAMS hdr; -+ UINT_32 u4Version; -+ UINT_32 u4Flag; -+ UINT_8 aucMacAddr[MAC_ADDR_LEN]; -+} NL80211_DRIVER_GET_STA_STATISTICS_PARAMS, *P_NL80211_DRIVER_GET_STA_STATISTICS_PARAMS; -+ -+typedef struct _NL80211_DRIVER_POORLINK_PARAMS { -+ NL80211_DRIVER_TEST_MODE_PARAMS hdr; -+ INT_8 cRssi; /* cRssi=0 means it is a invalid value. */ -+ UINT_8 ucLinkSpeed; /* ucLinkSpeed=0 means it is a invalid value */ -+ UINT_16 u2Reserved; -+} NL80211_DRIVER_POORLINK_PARAMS, *P_NL80211_DRIVER_POORLINK_PARAMS; -+ -+typedef enum _ENUM_TESTMODE_STA_STATISTICS_ATTR { -+ NL80211_TESTMODE_STA_STATISTICS_INVALID = 0, -+ NL80211_TESTMODE_STA_STATISTICS_VERSION, -+ NL80211_TESTMODE_STA_STATISTICS_MAC, -+ NL80211_TESTMODE_STA_STATISTICS_LINK_SCORE, -+ NL80211_TESTMODE_STA_STATISTICS_FLAG, -+ -+ NL80211_TESTMODE_STA_STATISTICS_PER, -+ NL80211_TESTMODE_STA_STATISTICS_RSSI, -+ NL80211_TESTMODE_STA_STATISTICS_PHY_MODE, -+ NL80211_TESTMODE_STA_STATISTICS_TX_RATE, -+ -+ NL80211_TESTMODE_STA_STATISTICS_TOTAL_CNT, -+ NL80211_TESTMODE_STA_STATISTICS_THRESHOLD_CNT, -+ -+ NL80211_TESTMODE_STA_STATISTICS_AVG_PROCESS_TIME, -+ NL80211_TESTMODE_STA_STATISTICS_MAX_PROCESS_TIME, -+ NL80211_TESTMODE_STA_STATISTICS_AVG_HIF_PROCESS_TIME, -+ NL80211_TESTMODE_STA_STATISTICS_MAX_HIF_PROCESS_TIME, -+ -+ NL80211_TESTMODE_STA_STATISTICS_FAIL_CNT, -+ NL80211_TESTMODE_STA_STATISTICS_TIMEOUT_CNT, -+ NL80211_TESTMODE_STA_STATISTICS_AVG_AIR_TIME, -+ -+ NL80211_TESTMODE_STA_STATISTICS_TC_EMPTY_CNT_ARRAY, -+ NL80211_TESTMODE_STA_STATISTICS_TC_QUE_LEN_ARRAY, -+ -+ NL80211_TESTMODE_STA_STATISTICS_TC_AVG_QUE_LEN_ARRAY, -+ NL80211_TESTMODE_STA_STATISTICS_TC_CUR_QUE_LEN_ARRAY, -+ -+ /* -+ * how many packages TX during statistics interval -+ */ -+ NL80211_TESTMODE_STA_STATISTICS_ENQUEUE, -+ -+ /* -+ * how many packages this TX during statistics interval -+ */ -+ NL80211_TESTMODE_STA_STATISTICS_STA_ENQUEUE, -+ -+ /* -+ * how many packages dequeue during statistics interval -+ */ -+ NL80211_TESTMODE_STA_STATISTICS_DEQUEUE, -+ -+ /* -+ * how many packages this sta dequeue during statistics interval -+ */ -+ NL80211_TESTMODE_STA_STATISTICS_STA_DEQUEUE, -+ -+ /* -+ * how many TC[0-3] resource back from firmware during -+ * statistics interval -+ */ -+ NL80211_TESTMODE_STA_STATISTICS_RB_ARRAY, -+ NL80211_TESTMODE_STA_STATISTICS_NO_TC_ARRAY, -+ NL80211_TESTMODE_STA_STATISTICS_USED_BFCT_ARRAY, -+ NL80211_TESTMODE_STA_STATISTICS_WANTED_BFCT_ARRAY, -+ -+ NL80211_TESTMODE_STA_STATISTICS_IRQ_ISR_CNT, -+ NL80211_TESTMODE_STA_STATISTICS_IRQ_ISR_PASS_CNT, -+ NL80211_TESTMODE_STA_STATISTICS_IRQ_TASK_CNT, -+ NL80211_TESTMODE_STA_STATISTICS_IRQ_AB_CNT, -+ NL80211_TESTMODE_STA_STATISTICS_IRQ_SW_CNT, -+ NL80211_TESTMODE_STA_STATISTICS_IRQ_TX_CNT, -+ NL80211_TESTMODE_STA_STATISTICS_IRQ_RX_CNT, -+ -+ NL80211_TESTMODE_STA_STATISTICS_RESERVED_ARRAY, -+ -+ NL80211_TESTMODE_STA_STATISTICS_NUM -+} ENUM_TESTMODE_STA_STATISTICS_ATTR; -+typedef struct _NL80211_DRIVER_SET_NFC_PARAMS { -+ NL80211_DRIVER_TEST_MODE_PARAMS hdr; -+ UINT_32 NFC_Enable; -+ -+} NL80211_DRIVER_SET_NFC_PARAMS, *P_NL80211_DRIVER_SET_NFC_PARAMS; -+typedef struct _NL80211_DRIVER_GET_SCANDONE_PARAMS { -+ NL80211_DRIVER_TEST_MODE_PARAMS hdr; -+ UINT_32 u4ScanDone; -+ -+} NL80211_DRIVER_GET_SCANDONE_PARAMS, *P_NL80211_DRIVER_GET_SCANDONE_PARAMS; -+ -+typedef enum _ENUM_TESTMODE_LINK_DETECTION_ATTR { -+ NL80211_TESTMODE_LINK_INVALID = 0, -+ NL80211_TESTMODE_LINK_TX_FAIL_CNT, -+ NL80211_TESTMODE_LINK_TX_RETRY_CNT, -+ NL80211_TESTMODE_LINK_TX_MULTI_RETRY_CNT, -+ NL80211_TESTMODE_LINK_ACK_FAIL_CNT, -+ NL80211_TESTMODE_LINK_FCS_ERR_CNT, -+ -+ NL80211_TESTMODE_LINK_DETECT_NUM, -+} ENUM_TESTMODE_LINK_DETECTION_ATTR; -+ -+#if CFG_AUTO_CHANNEL_SEL_SUPPORT -+ -+typedef struct _NL80211_DRIVER_GET_LTE_PARAMS { -+ NL80211_DRIVER_TEST_MODE_PARAMS hdr; -+ UINT_32 u4Version; -+ UINT_32 u4Flag; -+ -+} NL80211_DRIVER_GET_LTE_PARAMS, *P_NL80211_DRIVER_GET_LTE_PARAMS; -+ -+/*typedef enum _ENUM_TESTMODE_AVAILABLE_CHAN_ATTR{ -+ NL80211_TESTMODE_AVAILABLE_CHAN_INVALID = 0, -+ NL80211_TESTMODE_AVAILABLE_CHAN_2G_BASE_1, -+ NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_34, -+ NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_149, -+ NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_184, -+ -+ NL80211_TESTMODE_AVAILABLE_CHAN_NUM, -+}ENUM_TESTMODE_AVAILABLE_CHAN_ATTR;*/ -+ -+#endif -+#endif -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+/* cfg80211 hooks */ -+int -+mtk_cfg80211_change_iface(struct wiphy *wiphy, -+ struct net_device *ndev, enum nl80211_iftype type,/* u32 *flags,*/ struct vif_params *params); -+ -+int -+mtk_cfg80211_add_key(struct wiphy *wiphy, -+ struct net_device *ndev, -+ u8 key_index, bool pairwise, const u8 *mac_addr, struct key_params *params); -+ -+int -+mtk_cfg80211_get_key(struct wiphy *wiphy, -+ struct net_device *ndev, -+ u8 key_index, -+ bool pairwise, -+ const u8 *mac_addr, void *cookie, void (*callback) (void *cookie, struct key_params *) -+); -+ -+int -+mtk_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev, u8 key_index, bool pairwise, const u8 *mac_addr); -+ -+int -+mtk_cfg80211_set_default_key(struct wiphy *wiphy, struct net_device *ndev, u8 key_index, bool unicast, bool multicast); -+ -+int mtk_cfg80211_set_default_mgmt_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index); -+ -+int mtk_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev, const u8 *mac, struct station_info *sinfo); -+ -+int mtk_cfg80211_add_station(struct wiphy *wiphy, struct net_device *ndev, -+ const u8 *mac, struct station_parameters *params); -+ -+int mtk_cfg80211_change_station(struct wiphy *wiphy, struct net_device *ndev, -+ const u8 *mac, struct station_parameters *params); -+ -+int mtk_cfg80211_del_station(struct wiphy *wiphy, struct net_device *ndev, struct station_del_parameters *params); -+//int mtk_cfg80211_del_station(struct wiphy *wiphy, struct net_device *ndev, const u8 *mac); -+ -+int mtk_cfg80211_scan(struct wiphy *wiphy, struct cfg80211_scan_request *request); -+ -+int mtk_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev, struct cfg80211_connect_params *sme); -+ -+int mtk_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *ndev, u16 reason_code); -+ -+int mtk_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev, struct cfg80211_ibss_params *params); -+ -+int mtk_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *ndev); -+ -+int mtk_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *ndev, bool enabled, int timeout); -+ -+int mtk_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *ndev, struct cfg80211_pmksa *pmksa); -+ -+int mtk_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *ndev, struct cfg80211_pmksa *pmksa); -+ -+int mtk_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *ndev); -+ -+int mtk_cfg80211_remain_on_channel(struct wiphy *wiphy, -+ struct wireless_dev *wdev, -+ struct ieee80211_channel *chan, -+ unsigned int duration, u64 *cookie); -+ -+int mtk_cfg80211_cancel_remain_on_channel(struct wiphy *wiphy, struct wireless_dev *wdev, u64 cookie); -+ -+int -+mtk_cfg80211_mgmt_tx(struct wiphy *wiphy, -+ struct wireless_dev *wdev, -+ struct cfg80211_mgmt_tx_params *params, -+ u64 *cookie); -+ -+void mtk_cfg80211_mgmt_frame_register(IN struct wiphy *wiphy, -+ IN struct wireless_dev *wdev, -+ IN u16 frame_type, IN bool reg); -+ -+int mtk_cfg80211_mgmt_tx_cancel_wait(struct wiphy *wiphy, struct wireless_dev *wdev, u64 cookie); -+ -+int mtk_cfg80211_assoc(struct wiphy *wiphy, struct net_device *ndev, struct cfg80211_assoc_request *req); -+ -+int -+mtk_cfg80211_sched_scan_start(IN struct wiphy *wiphy, -+ IN struct net_device *ndev, IN struct cfg80211_sched_scan_request *request); -+ -+int mtk_cfg80211_sched_scan_stop(IN struct wiphy *wiphy, IN struct net_device *ndev,u64 reqid); -+ -+#if CONFIG_NL80211_TESTMODE -+#if CFG_AUTO_CHANNEL_SEL_SUPPORT -+WLAN_STATUS -+wlanoidQueryACSChannelList(IN P_ADAPTER_T prAdapter, -+ IN PVOID pvQueryBuffer, IN UINT_32 u4QueryBufferLen, OUT PUINT_32 pu4QueryInfoLen); -+ -+int -+mtk_cfg80211_testmode_get_lte_channel(IN struct wiphy *wiphy, IN void *data, IN int len, IN P_GLUE_INFO_T prGlueInfo); -+#endif -+int -+mtk_cfg80211_testmode_get_sta_statistics(IN struct wiphy *wiphy, -+ IN void *data, IN int len, IN P_GLUE_INFO_T prGlueInfo); -+ -+int mtk_cfg80211_testmode_get_scan_done(IN struct wiphy *wiphy, IN void *data, IN int len, IN P_GLUE_INFO_T prGlueInfo); -+ -+int mtk_cfg80211_testmode_cmd(IN struct wiphy *wiphy, IN struct wireless_dev *wdev, IN void *data, IN int len); -+ -+int mtk_cfg80211_testmode_sw_cmd(IN struct wiphy *wiphy, IN void *data, IN int len); -+#if CFG_SUPPORT_WAPI -+int mtk_cfg80211_testmode_set_key_ext(IN struct wiphy *wiphy, IN void *data, IN int len); -+#endif -+ -+#if CFG_SUPPORT_HOTSPOT_2_0 -+int mtk_cfg80211_testmode_hs20_cmd(IN struct wiphy *wiphy, IN void *data, IN int len); -+#endif -+ -+#if CFG_ENABLE_WIFI_DIRECT && CFG_ENABLE_WIFI_DIRECT_CFG_80211 -+int mtk_p2p_cfg80211_testmode_sw_cmd(IN struct wiphy *wiphy, IN void *data, IN int len); -+#endif -+ -+#else -+#error "Please ENABLE kernel config (CONFIG_NL80211_TESTMODE) to support Wi-Fi Direct" -+#endif -+int mtk_cfg80211_suspend(struct wiphy *wiphy, struct cfg80211_wowlan *wow); -+int mtk_cfg80211_resume(struct wiphy *wiphy); -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif /* _GL_CFG80211_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_kal.h b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_kal.h -new file mode 100644 -index 000000000000..1406905095e6 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_kal.h -@@ -0,0 +1,1565 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux/include/gl_kal.h#1 -+*/ -+ -+/*! \file gl_kal.h -+ \brief Declaration of KAL functions - kal*() which is provided by GLUE Layer. -+ -+ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. -+*/ -+ -+/* -+** Log: gl_kal.h -+ * -+ * 06 13 2012 yuche.tsai -+ * NULL -+ * Update maintrunk driver. -+ * Add support for driver compose assoc request frame. -+ * -+ * 04 12 2012 terry.wu -+ * NULL -+ * Add AEE message support -+ * 1) Show AEE warning(red screen) if SDIO access error occurs -+ -+ * -+ * 03 02 2012 terry.wu -+ * NULL -+ * Snc CFG80211 modification for ICS migration from branch 2.2. -+ * -+ * 02 06 2012 wh.su -+ * [WCXRP00001177] [MT6620 Wi-Fi][Driver][2.2] Adding the query channel filter for AP mode -+ * adding the channel query filter for AP mode. -+ * -+ * 01 02 2012 wh.su -+ * [WCXRP00001153] [MT6620 Wi-Fi][Driver] Adding the get_ch_list and set_tx_power proto type function -+ * Adding the proto type function for set_int set_tx_power and get int get_ch_list. -+ * -+ * 12 13 2011 cm.chang -+ * [WCXRP00001136] [All Wi-Fi][Driver] Add wake lock for pending timer -+ * Add wake lock if timer timeout value is smaller than 5 seconds -+ * -+ * 11 24 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * adjust the code for Non-DBG and no XLOG. -+ * -+ * 11 22 2011 cp.wu -+ * [WCXRP00001120] [MT6620 Wi-Fi][Driver] Modify roaming to AIS state transition from synchronous to asynchronous -+ * approach to avoid incomplete state termination -+ * 1. change RDD related compile option brace position. -+ * 2. when roaming is triggered, ask AIS to transit immediately only when AIS is in Normal TR state without join -+ * timeout timer ticking -+ * 3. otherwise, insert AIS_REQUEST into pending request queue -+ * -+ * 11 11 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * modify the xlog related code. -+ * -+ * 11 10 2011 eddie.chen -+ * [WCXRP00001096] [MT6620 Wi-Fi][Driver/FW] Enhance the log function (xlog) -+ * Modify the QM xlog level and remove LOG_FUNC. -+ * -+ * 11 10 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * Using the new XLOG define for dum Memory. -+ * -+ * 11 08 2011 eddie.chen -+ * [WCXRP00001096] [MT6620 Wi-Fi][Driver/FW] Enhance the log function (xlog) -+ * Add xlog function. -+ * -+ * 11 08 2011 tsaiyuan.hsu -+ * [WCXRP00001083] [MT6620 Wi-Fi][DRV]] dump debug counter or frames when debugging is triggered -+ * add debug counters, eCurPsProf, for PS. -+ * -+ * 11 08 2011 cm.chang -+ * NULL -+ * Add RLM and CNM debug message for XLOG -+ * -+ * 11 07 2011 tsaiyuan.hsu -+ * [WCXRP00001083] [MT6620 Wi-Fi][DRV]] dump debug counter or frames when debugging is triggered -+ * add debug counters and periodically dump counters for debugging. -+ * -+ * 11 03 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * Add dumpMemory8 at XLOG support. -+ * -+ * 11 02 2011 wh.su -+ * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG -+ * adding the code for XLOG. -+ * -+ * 10 12 2011 wh.su -+ * [WCXRP00001036] [MT6620 Wi-Fi][Driver][FW] Adding the 802.11w code for MFP -+ * adding the 802.11w related function and define . -+ * -+ * 04 18 2011 terry.wu -+ * [WCXRP00000660] [MT6620 Wi-Fi][Driver] Remove flag CFG_WIFI_DIRECT_MOVED -+ * Remove flag CFG_WIFI_DIRECT_MOVED. -+ * -+ * 04 12 2011 cp.wu -+ * [WCXRP00000635] [MT6620 Wi-Fi][Driver] Clear pending security frames when QM clear pending data frames for dedicated -+ * network type -+ * include link.h for linux's port. -+ * -+ * 04 12 2011 cp.wu -+ * [WCXRP00000635] [MT6620 Wi-Fi][Driver] Clear pending security frames when QM clear pending data frames for dedicated -+ * network type -+ * clear pending security frames for dedicated network type when BSS is being deactivated/disconnected -+ * -+ * 04 01 2011 cp.wu -+ * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer -+ * 1. simplify config.h due to aggregation options could be also applied for eHPI/SPI interface -+ * 2. use spin-lock instead of semaphore for protecting eHPI access because of possible access from ISR -+ * 3. request_irq() API has some changes between linux kernel 2.6.12 and 2.6.26 -+ * -+ * 03 16 2011 cp.wu -+ * [WCXRP00000562] [MT6620 Wi-Fi][Driver] I/O buffer pre-allocation to avoid physically continuous memory shortage -+ * after system running for a long period -+ * 1. pre-allocate physical continuous buffer while module is being loaded -+ * 2. use pre-allocated physical continuous buffer for TX/RX DMA transfer -+ * -+ * The windows part remained the same as before, but added similar APIs to hide the difference. -+ * -+ * 03 10 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Add BOW table. -+ * -+ * 03 07 2011 terry.wu -+ * [WCXRP00000521] [MT6620 Wi-Fi][Driver] Remove non-standard debug message -+ * Toggle non-standard debug messages to comments. -+ * -+ * 03 06 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Sync BOW Driver to latest person development branch version.. -+ * -+ * 03 02 2011 cp.wu -+ * [WCXRP00000503] [MT6620 Wi-Fi][Driver] Take RCPI brought by association response as initial RSSI right after -+ * connection is built. -+ * use RCPI brought by ASSOC-RESP after connection is built as initial RCPI to avoid using a uninitialized MAC-RX RCPI. -+ * -+ * 02 24 2011 cp.wu -+ * [WCXRP00000490] [MT6620 Wi-Fi][Driver][Win32] modify kalMsleep() implementation because NdisMSleep() won't sleep -+ * long enough for specified interval such as 500ms -+ * modify cnm_timer and hem_mbox APIs to be thread safe to ease invoking restrictions -+ * -+ * 01 12 2011 cp.wu -+ * [WCXRP00000357] [MT6620 Wi-Fi][Driver][Bluetooth over Wi-Fi] add another net device interface for BT AMP -+ * implementation of separate BT_OVER_WIFI data path. -+ * -+ * 01 04 2011 cp.wu -+ * [WCXRP00000338] [MT6620 Wi-Fi][Driver] Separate kalMemAlloc into kmalloc and vmalloc implementations to ease -+ * physically continuous memory demands -+ * separate kalMemAlloc() into virtually-continuous and physically-continuous type to ease slab system pressure -+ * -+ * 12 31 2010 cp.wu -+ * [WCXRP00000335] [MT6620 Wi-Fi][Driver] change to use milliseconds sleep instead of delay to avoid blocking to system -+ * scheduling -+ * change to use msleep() and shorten waiting interval to reduce blocking to other task while Wi-Fi driver is being -+ * loaded -+ * -+ * 12 31 2010 jeffrey.chang -+ * [WCXRP00000332] [MT6620 Wi-Fi][Driver] add kal sleep function for delay which use blocking call -+ * modify the implementation of kalDelay to msleep -+ * -+ * 12 22 2010 cp.wu -+ * [WCXRP00000283] [MT6620 Wi-Fi][Driver][Wi-Fi Direct] Implementation of interface for supporting Wi-Fi Direct Service -+ * Discovery -+ * 1. header file restructure for more clear module isolation -+ * 2. add function interface definition for implementing Service Discovery callbacks -+ * -+ * 11 30 2010 yuche.tsai -+ * NULL -+ * Invitation & Provision Discovery Indication. -+ * -+ * 11 26 2010 cp.wu -+ * [WCXRP00000209] [MT6620 Wi-Fi][Driver] Modify NVRAM checking mechanism to warning only with necessary data field -+ * checking -+ * 1. NVRAM error is now treated as warning only, thus normal operation is still available but extra scan result used -+ * to indicate user is attached -+ * 2. DPD and TX-PWR are needed fields from now on, if these 2 fields are not available then warning message is shown -+ * -+ * 11 08 2010 cp.wu -+ * [WCXRP00000166] [MT6620 Wi-Fi][Driver] use SDIO CMD52 for enabling/disabling interrupt to reduce transaction period -+ * change to use CMD52 for enabling/disabling interrupt to reduce SDIO transaction time -+ * -+ * 11 01 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000150] [MT6620 Wi-Fi][Driver] -+ * Add implementation for querying current TX rate from firmware auto rate module -+ * 1) Query link speed (TX rate) from firmware directly with buffering mechanism to reduce overhead -+ * 2) Remove CNM CH-RECOVER event handling -+ * 3) cfg read/write API renamed with kal prefix for unified naming rules. -+ * -+ * 10 05 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check -+ * 1) add NVRAM access API -+ * 2) fake scanning result when NVRAM doesn't exist and/or version mismatch. (off by compiler option) -+ * 3) add OID implementation for NVRAM read/write service -+ * -+ * 10 04 2010 wh.su -+ * [WCXRP00000081] [MT6620][Driver] Fix the compiling error at WinXP while enable P2P -+ * add a kal function for set cipher. -+ * -+ * 10 04 2010 wh.su -+ * [WCXRP00000081] [MT6620][Driver] Fix the compiling error at WinXP while enable P2P -+ * fixed compiling error while enable p2p. -+ * -+ * 09 28 2010 wh.su -+ * NULL -+ * [WCXRP00000069][MT6620 Wi-Fi][Driver] Fix some code for phase 1 P2P Demo. -+ * -+ * 09 21 2010 cp.wu -+ * [WCXRP00000053] [MT6620 Wi-Fi][Driver] Reset incomplete and might leads to BSOD when entering RF test with AIS -+ * associated -+ * Do a complete reset with STA-REC null checking for RF test re-entry -+ * -+ * 09 21 2010 kevin.huang -+ * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning -+ * Eliminate Linux Compile Warning -+ * -+ * 09 10 2010 wh.su -+ * NULL -+ * fixed the compiling error at win XP. -+ * -+ * 09 07 2010 wh.su -+ * NULL -+ * adding the code for beacon/probe req/ probe rsp wsc ie at p2p. -+ * -+ * 09 06 2010 wh.su -+ * NULL -+ * let the p2p can set the privacy bit at beacon and rsn ie at assoc req at key handshake state. -+ * -+ * 09 03 2010 kevin.huang -+ * NULL -+ * Refine #include sequence and solve recursive/nested #include issue -+ * -+ * 08 06 2010 cp.wu -+ * NULL -+ * driver hook modifications corresponding to ioctl interface change. -+ * -+ * 08 03 2010 cp.wu -+ * NULL -+ * [Wi-Fi Direct Driver Hook] change event indication API to be consistent with supplicant -+ * -+ * 08 03 2010 cp.wu -+ * NULL -+ * [Wi-Fi Direct] add framework for driver hooks -+ * -+ * 08 02 2010 jeffrey.chang -+ * NULL -+ * modify kalSetEvent declaration -+ * -+ * 07 29 2010 cp.wu -+ * NULL -+ * simplify post-handling after TX_DONE interrupt is handled. -+ * -+ * 07 23 2010 cp.wu -+ * -+ * 1) re-enable AIS-FSM beacon timeout handling. -+ * 2) scan done API revised -+ * -+ * 07 23 2010 jeffrey.chang -+ * -+ * fix kal header file -+ * -+ * 07 22 2010 jeffrey.chang -+ * -+ * use different spin lock for security frame -+ * -+ * 07 22 2010 jeffrey.chang -+ * -+ * add new spinlock -+ * -+ * 07 19 2010 jeffrey.chang -+ * -+ * add kal api for scanning done -+ * -+ * 07 19 2010 jeffrey.chang -+ * -+ * modify cmd/data path for new design -+ * -+ * 07 19 2010 jeffrey.chang -+ * -+ * add new kal api -+ * -+ * 07 19 2010 jeffrey.chang -+ * -+ * Linux port modification -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 21 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * change MAC address updating logic. -+ * -+ * 06 18 2010 cm.chang -+ * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver -+ * Provide cnmMgtPktAlloc() and alloc/free function of msg/buf -+ * -+ * 06 11 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * 1) migrate assoc.c. -+ * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness -+ * 3) add configuration options for CNM_MEM and RSN modules -+ * 4) add data path for management frames -+ * 5) eliminate rPacketInfo of MSDU_INFO_T -+ * -+ * 06 07 2010 cp.wu -+ * [WPD00003833][MT6620 and MT5931] Driver migration -+ * gl_kal merged -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 05 17 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * add basic handling framework for wireless extension ioctls. -+ * -+ * 05 11 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * add ioctl for controlling p2p scan phase parameters -+ * -+ * 05 10 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * fill network type field while doing frame identification. -+ * -+ * 05 10 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * implement basic wi-fi direct framework -+ * -+ * 05 07 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * add basic framework for implementating P2P driver hook. -+ * -+ * 05 07 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * modify kalMemAlloc method -+ * -+ * 04 28 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * change prefix for data structure used to communicate with 802.11 PAL -+ * to avoid ambiguous naming with firmware interface -+ * -+ * 04 27 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * add multiple physical link support -+ * -+ * 04 27 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * follow Linux's firmware framework, and remove unused kal API -+ * -+ * 04 22 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * when acquiring driver-own, wait for up to 8 seconds. -+ * -+ * 04 22 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * -+ * 1) modify rx path code for supporting Wi-Fi direct -+ * 2) modify config.h since Linux dont need to consider retaining packet -+ * -+ * 04 21 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * add for private ioctl support -+ * -+ * 04 20 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * don't need SPIN_LOCK_PWR_CTRL anymore, it will raise IRQL -+ * * and cause SdBusSubmitRequest running at DISPATCH_LEVEL as well. -+ * -+ * 04 14 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * information buffer for query oid/ioctl is now buffered in prCmdInfo -+ * * * * * * * * instead of glue-layer variable to improve multiple oid/ioctl capability -+ * -+ * 04 13 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * add framework for BT-over-Wi-Fi support. -+ * * * * * * * * * * * * * * * * * * * 1) prPendingCmdInfo is replaced by queue for multiple handler -+ * * * * * * * * * * * * * * * * * * * capability -+ * * * * * * * * * * * * * * * * * * * 2) command sequence number is now increased atomically -+ * * * * * * * * * * * * * * * * * * * 3) private data could be hold and taken use for other purpose -+ * -+ * 04 09 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * 1) add spinlock -+ * * * 2) add KAPI for handling association info -+ * -+ * 04 09 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * adding firmware download KAPI -+ * -+ * 04 07 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * finish non-glue layer access to glue variables -+ * -+ * 04 07 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * accessing to firmware load/start address, and access to OID handling information -+ * * * * are now handled in glue layer -+ * -+ * 04 07 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * rWlanInfo should be placed at adapter rather than glue due to most operations -+ * * * * * * * * * are done in adapter layer. -+ * -+ * 04 07 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * eliminate direct access to prGlueInfo->eParamMediaStateIndicated from non-glue layer -+ * -+ * 04 06 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * add KAL API: kalFlushPendingTxPackets(), and take use of the API -+ * -+ * 04 06 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * eliminate direct access to prGlueInfo->rWlanInfo.eLinkAttr.ucMediaStreamMode from non-glue layer. -+ * -+ * 04 06 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * improve none-glue code portability -+ * -+ * 04 06 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * code refine: fgTestMode should be at adapter rather than glue due to the device/fw is also involved -+ * -+ * 04 06 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) for some OID, never do timeout expiration -+ * * * * 2) add 2 kal API for later integration -+ * -+ * 03 30 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * emulate NDIS Pending OID facility -+ * -+ * 03 26 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * [WPD00003826] Initial import for Linux port -+ * adding firmware download KAPI -+ * -+ * 03 24 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * initial import for Linux port -+** \main\maintrunk.MT5921\41 2009-09-28 20:19:23 GMT mtk01090 -+** Add private ioctl to carry OID structures. Restructure public/private ioctl interfaces to Linux kernel. -+** \main\maintrunk.MT5921\40 2009-08-18 22:57:09 GMT mtk01090 -+** Add Linux SDIO (with mmc core) support. -+** Add Linux 2.6.21, 2.6.25, 2.6.26. -+** Fix compile warning in Linux. -+** \main\maintrunk.MT5921\39 2009-06-23 23:19:15 GMT mtk01090 -+** Add build option BUILD_USE_EEPROM and compile option CFG_SUPPORT_EXT_CONFIG for NVRAM support -+** \main\maintrunk.MT5921\38 2009-02-09 14:03:17 GMT mtk01090 -+** Add KAL function kalDevSetPowerState(). It is not implemented yet. Only add an empty macro. -+** -+** \main\maintrunk.MT5921\37 2009-01-22 13:05:59 GMT mtk01088 -+** new defeine to got 1x value at packet reserved field -+** \main\maintrunk.MT5921\36 2008-12-08 16:15:02 GMT mtk01461 -+** Add kalQueryValidBufferLength() macro -+** \main\maintrunk.MT5921\35 2008-11-13 20:33:15 GMT mtk01104 -+** Remove lint warning -+** \main\maintrunk.MT5921\34 2008-10-22 11:05:52 GMT mtk01461 -+** Remove unused macro -+** \main\maintrunk.MT5921\33 2008-10-16 15:48:17 GMT mtk01461 -+** Update driver to fix lint warning -+** \main\maintrunk.MT5921\32 2008-09-02 11:50:51 GMT mtk01461 -+** SPIN_LOCK_SDIO_DDK_TX_QUE -+** \main\maintrunk.MT5921\31 2008-08-29 15:58:30 GMT mtk01088 -+** remove non-used function for code refine -+** \main\maintrunk.MT5921\30 2008-08-21 00:33:29 GMT mtk01461 -+** Update for Driver Review -+** \main\maintrunk.MT5921\29 2008-06-19 13:29:14 GMT mtk01425 -+** 1. Add declaration of SPIN_LOCK_SDIO_DDK_TX_QUE and SPIN_LOCK_SDIO_DDK_RX_QUE -+** \main\maintrunk.MT5921\28 2008-05-30 20:27:34 GMT mtk01461 -+** Rename KAL function -+** \main\maintrunk.MT5921\27 2008-05-30 14:42:05 GMT mtk01461 -+** Remove WMM Assoc Flag in KAL -+** \main\maintrunk.MT5921\26 2008-05-29 14:15:18 GMT mtk01084 -+** remove un-used function -+** \main\maintrunk.MT5921\25 2008-04-23 14:02:20 GMT mtk01084 -+** modify KAL port access function prototype -+** \main\maintrunk.MT5921\24 2008-04-17 23:06:41 GMT mtk01461 -+** Add iwpriv support for AdHocMode setting -+** \main\maintrunk.MT5921\23 2008-04-08 15:38:50 GMT mtk01084 -+** add KAL function to setting pattern search function enable/ disable -+** \main\maintrunk.MT5921\22 2008-03-26 15:34:48 GMT mtk01461 -+** Add update MAC address func -+** \main\maintrunk.MT5921\21 2008-03-18 15:56:15 GMT mtk01084 -+** update ENUM_NIC_INITIAL_PARAM_E -+** \main\maintrunk.MT5921\20 2008-03-18 11:49:28 GMT mtk01084 -+** update function for initial value access -+** \main\maintrunk.MT5921\19 2008-03-18 10:21:31 GMT mtk01088 -+** use kal update associate request at linux -+** \main\maintrunk.MT5921\18 2008-03-14 18:03:41 GMT mtk01084 -+** refine register and port access function -+** \main\maintrunk.MT5921\17 2008-03-11 14:51:02 GMT mtk01461 -+** Add copy_to(from)_user macro -+** \main\maintrunk.MT5921\16 2008-03-06 23:42:21 GMT mtk01385 -+** 1. add Query Registry Mac address function. -+** \main\maintrunk.MT5921\15 2008-02-26 09:48:04 GMT mtk01084 -+** modify KAL set network address/ checksum offload part -+** \main\maintrunk.MT5921\14 2008-01-09 17:54:58 GMT mtk01084 -+** Modify the argument of kalQueryPacketInfo -+** \main\maintrunk.MT5921\13 2007-11-29 02:05:20 GMT mtk01461 -+** Fix Windows RX multiple packet retain problem -+** \main\maintrunk.MT5921\12 2007-11-26 19:43:45 GMT mtk01461 -+** Add OS_TIMESTAMP macro -+** -+** \main\maintrunk.MT5921\11 2007-11-09 16:36:15 GMT mtk01425 -+** 1. Modify for CSUM offloading with Tx Fragment -+** \main\maintrunk.MT5921\10 2007-11-07 18:38:37 GMT mtk01461 -+** Add Tx Fragmentation Support -+** \main\maintrunk.MT5921\9 2007-11-06 19:36:50 GMT mtk01088 -+** add the WPS related code -+** \main\maintrunk.MT5921\8 2007-11-02 01:03:57 GMT mtk01461 -+** Unify TX Path for Normal and IBSS Power Save + IBSS neighbor learning -+** Revision 1.4 2007/07/05 07:25:33 MTK01461 -+** Add Linux initial code, modify doc, add 11BB, RF init code -+** -+** Revision 1.3 2007/06/27 02:18:50 MTK01461 -+** Update SCAN_FSM, Initial(Can Load Module), Proc(Can do Reg R/W), TX API -+** -+** Revision 1.2 2007/06/25 06:16:23 MTK01461 -+** Update illustrations, gl_init.c, gl_kal.c, gl_kal.h, gl_os.h and RX API -+** -+*/ -+ -+#ifndef _GL_KAL_H -+#define _GL_KAL_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "config.h" -+#include "gl_typedef.h" -+#include "gl_os.h" -+#include "link.h" -+#include "nic/mac.h" -+#include "nic/wlan_def.h" -+#include "wlan_lib.h" -+#include "wlan_oid.h" -+#include "gl_wext_priv.h" -+#include -+ -+#if CFG_ENABLE_BT_OVER_WIFI -+#include "nic/bow.h" -+#endif -+ -+#if DBG -+extern int allocatedMemSize; -+#endif -+ -+#if CFG_SUPPORT_MET_PROFILING -+#include "linux/kallsyms.h" -+#include -+#endif -+ -+extern BOOLEAN fgIsUnderSuspend; -+extern UINT_32 TaskIsrCnt; -+extern BOOLEAN fgIsResetting; -+extern int wlanHardStartXmit(struct sk_buff *prSkb, struct net_device *prDev); -+extern UINT_32 u4MemAllocCnt, u4MemFreeCnt; -+ -+ -+extern struct delayed_work sched_workq; -+ -+#if defined(MT6620) && CFG_MULTI_ECOVER_SUPPORT -+extern ENUM_WMTHWVER_TYPE_T mtk_wcn_wmt_hwver_get(VOID); -+#endif -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+/* #define USEC_PER_MSEC (1000) */ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+typedef enum _ENUM_SPIN_LOCK_CATEGORY_E { -+ SPIN_LOCK_FSM = 0, -+ -+ /* FIX ME */ -+ SPIN_LOCK_RX_QUE, -+ SPIN_LOCK_TX_QUE, -+ SPIN_LOCK_CMD_QUE, -+ SPIN_LOCK_TX_RESOURCE, -+ SPIN_LOCK_CMD_RESOURCE, -+ SPIN_LOCK_QM_TX_QUEUE, -+ SPIN_LOCK_CMD_PENDING, -+ SPIN_LOCK_CMD_SEQ_NUM, -+ SPIN_LOCK_TX_MSDU_INFO_LIST, -+ SPIN_LOCK_TXING_MGMT_LIST, -+ SPIN_LOCK_TX_SEQ_NUM, -+ SPIN_LOCK_TX_COUNT, -+ SPIN_LOCK_TXS_COUNT, -+ /* end */ -+ SPIN_LOCK_TX, -+ SPIN_LOCK_IO_REQ, -+ SPIN_LOCK_INT, -+ -+ SPIN_LOCK_MGT_BUF, -+ SPIN_LOCK_MSG_BUF, -+ SPIN_LOCK_STA_REC, -+ -+ SPIN_LOCK_MAILBOX, -+ SPIN_LOCK_TIMER, -+ -+ SPIN_LOCK_BOW_TABLE, -+ -+ SPIN_LOCK_EHPI_BUS, /* only for EHPI */ -+ SPIN_LOCK_NET_DEV, -+ SPIN_LOCK_NUM -+} ENUM_SPIN_LOCK_CATEGORY_E; -+ -+/* event for assoc information update */ -+typedef struct _EVENT_ASSOC_INFO { -+ UINT_8 ucAssocReq; /* 1 for assoc req, 0 for assoc rsp */ -+ UINT_8 ucReassoc; /* 0 for assoc, 1 for reassoc */ -+ UINT_16 u2Length; -+ PUINT_8 pucIe; -+} EVENT_ASSOC_INFO, *P_EVENT_ASSOC_INFO; -+ -+typedef enum _ENUM_KAL_NETWORK_TYPE_INDEX_T { -+ KAL_NETWORK_TYPE_AIS_INDEX = 0, -+#if CFG_ENABLE_WIFI_DIRECT -+ KAL_NETWORK_TYPE_P2P_INDEX, -+#endif -+#if CFG_ENABLE_BT_OVER_WIFI -+ KAL_NETWORK_TYPE_BOW_INDEX, -+#endif -+ KAL_NETWORK_TYPE_INDEX_NUM -+} ENUM_KAL_NETWORK_TYPE_INDEX_T; -+ -+typedef enum _ENUM_KAL_MEM_ALLOCATION_TYPE_E { -+ PHY_MEM_TYPE, /* physically continuous */ -+ VIR_MEM_TYPE, /* virtually continuous */ -+ MEM_TYPE_NUM -+} ENUM_KAL_MEM_ALLOCATION_TYPE; -+ -+#if CONFIG_ANDROID /* Defined in Android kernel source */ -+typedef struct wake_lock KAL_WAKE_LOCK_T, *P_KAL_WAKE_LOCK_T; -+#else -+typedef UINT_32 KAL_WAKE_LOCK_T, *P_KAL_WAKE_LOCK_T; -+#endif -+ -+#if CFG_SUPPORT_AGPS_ASSIST -+typedef enum _ENUM_MTK_AGPS_ATTR { -+ MTK_ATTR_AGPS_INVALID, -+ MTK_ATTR_AGPS_CMD, -+ MTK_ATTR_AGPS_DATA, -+ MTK_ATTR_AGPS_IFINDEX, -+ MTK_ATTR_AGPS_IFNAME, -+ MTK_ATTR_AGPS_MAX -+} ENUM_MTK_CCX_ATTR; -+ -+typedef enum _ENUM_AGPS_EVENT { -+ AGPS_EVENT_WLAN_ON, -+ AGPS_EVENT_WLAN_OFF, -+ AGPS_EVENT_WLAN_AP_LIST, -+ WIFI_EVENT_CHIP_RESET, -+} ENUM_CCX_EVENT; -+BOOLEAN kalIndicateAgpsNotify(P_ADAPTER_T prAdapter, UINT_8 cmd, PUINT_8 data, UINT_16 dataLen); -+#endif -+ -+struct KAL_HALT_CTRL_T { -+ struct semaphore lock; -+ struct task_struct *owner; -+ BOOLEAN fgHalt; -+ BOOLEAN fgHeldByKalIoctl; -+ OS_SYSTIME u4HoldStart; -+}; -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/*----------------------------------------------------------------------------*/ -+/* Macros of bit operation */ -+/*----------------------------------------------------------------------------*/ -+#define KAL_SET_BIT(bitOffset, value) set_bit(bitOffset, &value) -+#define KAL_CLR_BIT(bitOffset, value) clear_bit(bitOffset, &value) -+#define KAL_TEST_AND_CLEAR_BIT(bitOffset, value) test_and_clear_bit(bitOffset, &value) -+#define KAL_TEST_BIT(bitOffset, value) test_bit(bitOffset, &value) -+ -+/*----------------------------------------------------------------------------*/ -+/* Macros of SPIN LOCK operations for using in Driver Layer */ -+/*----------------------------------------------------------------------------*/ -+#define KAL_SPIN_LOCK_DECLARATION() unsigned long __u4Flags -+ -+#define KAL_ACQUIRE_SPIN_LOCK(_prAdapter, _rLockCategory) \ -+ kalAcquireSpinLock(((P_ADAPTER_T)_prAdapter)->prGlueInfo, _rLockCategory, &__u4Flags) -+ -+#define KAL_RELEASE_SPIN_LOCK(_prAdapter, _rLockCategory) \ -+ kalReleaseSpinLock(((P_ADAPTER_T)_prAdapter)->prGlueInfo, _rLockCategory, __u4Flags) -+ -+/*----------------------------------------------------------------------------*/ -+/* Macros for accessing Reserved Fields of native packet */ -+/*----------------------------------------------------------------------------*/ -+#define KAL_GET_PKT_QUEUE_ENTRY(_p) GLUE_GET_PKT_QUEUE_ENTRY(_p) -+#define KAL_GET_PKT_DESCRIPTOR(_prQueueEntry) GLUE_GET_PKT_DESCRIPTOR(_prQueueEntry) -+#define KAL_GET_PKT_TID(_p) GLUE_GET_PKT_TID(_p) -+#define KAL_GET_PKT_IS1X(_p) GLUE_GET_PKT_IS1X(_p) -+#define KAL_GET_PKT_HEADER_LEN(_p) GLUE_GET_PKT_HEADER_LEN(_p) -+#define KAL_GET_PKT_PAYLOAD_LEN(_p) GLUE_GET_PKT_PAYLOAD_LEN(_p) -+#define KAL_GET_PKT_ARRIVAL_TIME(_p) GLUE_GET_PKT_ARRIVAL_TIME(_p) -+ -+/*----------------------------------------------------------------------------*/ -+/* Macros of wake_lock operations for using in Driver Layer */ -+/*----------------------------------------------------------------------------*/ -+#if CONFIG_ANDROID /* Defined in Android kernel source */ -+#define KAL_WAKE_LOCK_INIT(_prAdapter, _prWakeLock, _pcName) \ -+ wake_lock_init(_prWakeLock, WAKE_LOCK_SUSPEND, _pcName) -+ -+#define KAL_WAKE_LOCK_DESTROY(_prAdapter, _prWakeLock) \ -+ wake_lock_destroy(_prWakeLock) -+ -+#define KAL_WAKE_LOCK(_prAdapter, _prWakeLock) \ -+ wake_lock(_prWakeLock) -+ -+#define KAL_WAKE_LOCK_TIMEOUT(_prAdapter, _prWakeLock, _u4Timeout) \ -+ wake_lock_timeout(_prWakeLock, _u4Timeout) -+ -+#define KAL_WAKE_UNLOCK(_prAdapter, _prWakeLock) \ -+ wake_unlock(_prWakeLock) -+ -+#else -+#define KAL_WAKE_LOCK_INIT(_prAdapter, _prWakeLock, _pcName) -+#define KAL_WAKE_LOCK_DESTROY(_prAdapter, _prWakeLock) -+#define KAL_WAKE_LOCK(_prAdapter, _prWakeLock) -+#define KAL_WAKE_LOCK_TIMEOUT(_prAdapter, _prWakeLock, _u4Timeout) -+#define KAL_WAKE_UNLOCK(_prAdapter, _prWakeLock) -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Cache memory allocation -+* -+* \param[in] u4Size Required memory size. -+* \param[in] eMemType Memory allocation type -+* -+* \return Pointer to allocated memory -+* or NULL -+*/ -+/*----------------------------------------------------------------------------*/ -+#if DBG -+#define kalMemAlloc(u4Size, eMemType) ({ \ -+ void *pvAddr; \ -+ if (eMemType == PHY_MEM_TYPE) { \ -+ pvAddr = kmalloc(u4Size, GFP_KERNEL); \ -+ } \ -+ else { \ -+ pvAddr = vmalloc(u4Size); \ -+ } \ -+ if (pvAddr) { \ -+ allocatedMemSize += u4Size; \ -+ DBGLOG(INIT, INFO, "%p(%u) allocated (%s:%s)\n", \ -+ pvAddr, (UINT_32)u4Size, __FILE__, __func__); \ -+ } \ -+ pvAddr; \ -+}) -+#else -+#define kalMemAlloc(u4Size, eMemType) ({ \ -+ void *pvAddr; \ -+ if (eMemType == PHY_MEM_TYPE) { \ -+ pvAddr = kmalloc(u4Size, GFP_KERNEL); \ -+ } \ -+ else { \ -+ pvAddr = vmalloc(u4Size); \ -+ } \ -+ pvAddr; \ -+}) -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Free allocated cache memory -+* -+* \param[in] pvAddr Required memory size. -+* \param[in] eMemType Memory allocation type -+* \param[in] u4Size Allocated memory size. -+* -+* \return - -+*/ -+/*----------------------------------------------------------------------------*/ -+#if DBG -+#define kalMemFree(pvAddr, eMemType, u4Size) \ -+{ \ -+ if (pvAddr) { \ -+ allocatedMemSize -= u4Size; \ -+ DBGLOG(INIT, INFO, "%p(%u) freed (%s:%s)\n", \ -+ pvAddr, (UINT_32)u4Size, __FILE__, __func__); \ -+ } \ -+ if (eMemType == PHY_MEM_TYPE) { \ -+ kfree(pvAddr); \ -+ } \ -+ else { \ -+ vfree(pvAddr); \ -+ } \ -+} -+#else -+#define kalMemFree(pvAddr, eMemType, u4Size) \ -+{ \ -+ if (eMemType == PHY_MEM_TYPE) { \ -+ kfree(pvAddr); \ -+ } \ -+ else { \ -+ vfree(pvAddr); \ -+ } \ -+} -+#endif -+ -+#define kalUdelay(u4USec) udelay(u4USec) -+ -+#define kalMdelay(u4MSec) mdelay(u4MSec) -+#define kalMsleep(u4MSec) msleep(u4MSec) -+ -+/* Copy memory from user space to kernel space */ -+#define kalMemCopyFromUser(_pvTo, _pvFrom, _u4N) copy_from_user(_pvTo, _pvFrom, _u4N) -+ -+/* Copy memory from kernel space to user space */ -+#define kalMemCopyToUser(_pvTo, _pvFrom, _u4N) copy_to_user(_pvTo, _pvFrom, _u4N) -+ -+/* Copy memory block with specific size */ -+#define kalMemCopy(pvDst, pvSrc, u4Size) memcpy(pvDst, pvSrc, u4Size) -+ -+/* Set memory block with specific pattern */ -+#define kalMemSet(pvAddr, ucPattern, u4Size) memset(pvAddr, ucPattern, u4Size) -+ -+/* Compare two memory block with specific length. -+ * Return zero if they are the same. -+ */ -+#define kalMemCmp(pvAddr1, pvAddr2, u4Size) memcmp(pvAddr1, pvAddr2, u4Size) -+ -+/* Zero specific memory block */ -+#define kalMemZero(pvAddr, u4Size) memset(pvAddr, 0, u4Size) -+ -+/* string operation */ -+#define kalStrCpy(dest, src) strcpy(dest, src) -+#define kalStrnCpy(dest, src, n) strncpy(dest, src, n) -+#define kalStrCmp(ct, cs) strcmp(ct, cs) -+#define kalStrnCmp(ct, cs, n) strncmp(ct, cs, n) -+#define kalStrChr(s, c) strchr(s, c) -+#define kalStrrChr(s, c) strrchr(s, c) -+#define kalStrnChr(s, n, c) strnchr(s, n, c) -+#define kalStrLen(s) strlen(s) -+#define kalStrnLen(s, b) strnlen(s, b) -+//#define kalStrniCmp(s1, s2, n) strnicmp(s1, s2, n) -+#define kalStrniCmp(s1, s2, n) strncasecmp(s1, s2, n) -+#define strnicmp(s1, s2, n) strncasecmp(s1, s2, n) -+/* #define kalStrtoul(cp, endp, base) simple_strtoul(cp, endp, base) -+#define kalStrtol(cp, endp, base) simple_strtol(cp, endp, base) */ -+#define kalkStrtou32(cp, base, resp) kstrtou32(cp, base, resp) -+#define kalkStrtos32(cp, base, resp) kstrtos32(cp, base, resp) -+#define kalSnprintf(buf, size, fmt, ...) snprintf(buf, size, fmt, __VA_ARGS__) -+#define kalSprintf(buf, fmt, ...) sprintf(buf, fmt, __VA_ARGS__) -+/* remove for AOSP */ -+/* #define kalSScanf(buf, fmt, ...) sscanf(buf, fmt, __VA_ARGS__) */ -+#define kalStrStr(ct, cs) strstr(ct, cs) -+#define kalStrSep(s, ct) strsep(s, ct) -+#define kalStrCat(dest, src) strcat(dest, src) -+ -+/* defined for wince sdio driver only */ -+#if defined(_HIF_SDIO) -+#define kalDevSetPowerState(prGlueInfo, ePowerMode) glSetPowerState(prGlueInfo, ePowerMode) -+#else -+#define kalDevSetPowerState(prGlueInfo, ePowerMode) -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Notify OS with SendComplete event of the specific packet. Linux should -+* free packets here. -+* -+* \param[in] prGlueInfo Pointer of GLUE Data Structure -+* \param[in] pvPacket Pointer of Packet Handle -+* \param[in] status Status Code for OS upper layer -+* -+* \return - -+*/ -+/*----------------------------------------------------------------------------*/ -+#define kalSendComplete(prGlueInfo, pvPacket, status) \ -+ kalSendCompleteAndAwakeQueue(prGlueInfo, pvPacket) -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is used to locate the starting address of incoming ethernet -+* frame for skb. -+* -+* \param[in] prGlueInfo Pointer of GLUE Data Structure -+* \param[in] pvPacket Pointer of Packet Handle -+* -+* \return starting address of ethernet frame buffer. -+*/ -+/*----------------------------------------------------------------------------*/ -+#define kalQueryBufferPointer(prGlueInfo, pvPacket) \ -+ ((PUINT_8)((struct sk_buff *)pvPacket)->data) -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is used to query the length of valid buffer which is accessible during -+* port read/write. -+* -+* \param[in] prGlueInfo Pointer of GLUE Data Structure -+* \param[in] pvPacket Pointer of Packet Handle -+* -+* \return starting address of ethernet frame buffer. -+*/ -+/*----------------------------------------------------------------------------*/ -+#define kalQueryValidBufferLength(prGlueInfo, pvPacket) \ -+ ((UINT_32)((struct sk_buff *)pvPacket)->end - \ -+ (UINT_32)((struct sk_buff *)pvPacket)->data) -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief This function is used to copy the entire frame from skb to the destination -+* address in the input parameter. -+* -+* \param[in] prGlueInfo Pointer of GLUE Data Structure -+* \param[in] pvPacket Pointer of Packet Handle -+* \param[in] pucDestBuffer Destination Address -+* -+* \return - -+*/ -+/*----------------------------------------------------------------------------*/ -+#define kalCopyFrame(prGlueInfo, pvPacket, pucDestBuffer) \ -+ do {struct sk_buff *skb = (struct sk_buff *)pvPacket; \ -+ memcpy(pucDestBuffer, skb->data, skb->len); } while (0) -+ -+#define kalGetTimeTick() jiffies_to_msecs(jiffies) -+ -+#define kalPrint pr_debug -+ -+#if !DBG -+#define AIS_ERROR_LOGFUNC(_Fmt...) -+#define AIS_WARN_LOGFUNC(_Fmt...) -+#define AIS_INFO_LOGFUNC(_Fmt...) -+#define AIS_STATE_LOGFUNC(_Fmt...) -+#define AIS_EVENT_LOGFUNC(_Fmt...) -+#define AIS_TRACE_LOGFUNC(_Fmt...) -+#define AIS_LOUD_LOGFUNC(_Fmt...) -+#define AIS_TEMP_LOGFUNC(_Fmt...) -+ -+#define INTR_ERROR_LOGFUNC(_Fmt...) -+#define INTR_WARN_LOGFUNC(_Fmt...) -+#define INTR_INFO_LOGFUNC(_Fmt...) -+#define INTR_STATE_LOGFUNC(_Fmt...) -+#define INTR_EVENT_LOGFUNC(_Fmt...) -+#define INTR_TRACE_LOGFUNC(_Fmt...) -+#define INTR_LOUD_LOGFUNC(_Fmt...) -+#define INTR_TEMP_LOGFUNC(_Fmt...) -+ -+#define INIT_ERROR_LOGFUNC(_Fmt...) kalPrint(_Fmt) -+#define INIT_WARN_LOGFUNC(_Fmt...) kalPrint(_Fmt) -+#define INIT_INFO_LOGFUNC(_Fmt...) kalPrint(_Fmt) -+#define INIT_STATE_LOGFUNC(_Fmt...) kalPrint(_Fmt) -+#define INIT_EVENT_LOGFUNC(_Fmt...) kalPrint(_Fmt) -+#define INIT_TRACE_LOGFUNC(_Fmt...) -+#define INIT_LOUD_LOGFUNC(_Fmt...) -+#define INIT_TEMP_LOGFUNC(_Fmt...) -+ -+#define AAA_ERROR_LOGFUNC(_Fmt...) kalPrint(_Fmt) -+#define AAA_WARN_LOGFUNC(_Fmt...) kalPrint(_Fmt) -+#define AAA_INFO_LOGFUNC(_Fmt...) kalPrint(_Fmt) -+#define AAA_STATE_LOGFUNC(_Fmt...) kalPrint(_Fmt) -+#define AAA_EVENT_LOGFUNC(_Fmt...) kalPrint(_Fmt) -+#define AAA_TRACE_LOGFUNC(_Fmt...) kalPrint(_Fmt) -+#define AAA_LOUD_LOGFUNC(_Fmt...) -+#define AAA_TEMP_LOGFUNC(_Fmt...) -+ -+#define ROAMING_ERROR_LOGFUNC(_Fmt...) -+#define ROAMING_WARN_LOGFUNC(_Fmt...) -+#define ROAMING_INFO_LOGFUNC(_Fmt...) -+#define ROAMING_STATE_LOGFUNC(_Fmt...) -+#define ROAMING_EVENT_LOGFUNC(_Fmt...) -+#define ROAMING_TRACE_LOGFUNC(_Fmt...) -+#define ROAMING_LOUD_LOGFUNC(_Fmt...) -+#define ROAMING_TEMP_LOGFUNC(_Fmt...) -+ -+#define REQ_ERROR_LOGFUNC(_Fmt...) -+#define REQ_WARN_LOGFUNC(_Fmt...) -+#define REQ_INFO_LOGFUNC(_Fmt...) -+#define REQ_STATE_LOGFUNC(_Fmt...) -+#define REQ_EVENT_LOGFUNC(_Fmt...) -+#define REQ_TRACE_LOGFUNC(_Fmt...) -+#define REQ_LOUD_LOGFUNC(_Fmt...) -+#define REQ_TEMP_LOGFUNC(_Fmt...) -+ -+#define TX_ERROR_LOGFUNC(_Fmt...) -+#define TX_WARN_LOGFUNC(_Fmt...) -+#define TX_INFO_LOGFUNC(_Fmt...) -+#define TX_STATE_LOGFUNC(_Fmt...) -+#define TX_EVENT_LOGFUNC(_Fmt...) -+#define TX_TRACE_LOGFUNC(_Fmt...) kalPrint(_Fmt) -+#define TX_LOUD_LOGFUNC(_Fmt...) -+#define TX_TEMP_LOGFUNC(_Fmt...) -+ -+#define RX_ERROR_LOGFUNC(_Fmt...) -+#define RX_WARN_LOGFUNC(_Fmt...) -+#define RX_INFO_LOGFUNC(_Fmt...) -+#define RX_STATE_LOGFUNC(_Fmt...) -+#define RX_EVENT_LOGFUNC(_Fmt...) -+#define RX_TRACE_LOGFUNC(_Fmt...) -+#define RX_LOUD_LOGFUNC(_Fmt...) -+#define RX_TEMP_LOGFUNC(_Fmt...) -+ -+#define RFTEST_ERROR_LOGFUNC(_Fmt...) -+#define RFTEST_WARN_LOGFUNC(_Fmt...) -+#define RFTEST_INFO_LOGFUNC(_Fmt...) -+#define RFTEST_STATE_LOGFUNC(_Fmt...) -+#define RFTEST_EVENT_LOGFUNC(_Fmt...) -+#define RFTEST_TRACE_LOGFUNC(_Fmt...) -+#define RFTEST_LOUD_LOGFUNC(_Fmt...) -+#define RFTEST_TEMP_LOGFUNC(_Fmt...) -+ -+#define EMU_ERROR_LOGFUNC(_Fmt...) -+#define EMU_WARN_LOGFUNC(_Fmt...) -+#define EMU_INFO_LOGFUNC(_Fmt...) -+#define EMU_STATE_LOGFUNC(_Fmt...) -+#define EMU_EVENT_LOGFUNC(_Fmt...) -+#define EMU_TRACE_LOGFUNC(_Fmt...) -+#define EMU_LOUD_LOGFUNC(_Fmt...) -+#define EMU_TEMP_LOGFUNC(_Fmt...) -+ -+#define HEM_ERROR_LOGFUNC(_Fmt...) -+#define HEM_WARN_LOGFUNC(_Fmt...) -+#define HEM_INFO_LOGFUNC(_Fmt...) -+#define HEM_STATE_LOGFUNC(_Fmt...) -+#define HEM_EVENT_LOGFUNC(_Fmt...) -+#define HEM_TRACE_LOGFUNC(_Fmt...) -+#define HEM_LOUD_LOGFUNC(_Fmt...) -+#define HEM_TEMP_LOGFUNC(_Fmt...) -+ -+#define RLM_ERROR_LOGFUNC(_Fmt...) -+#define RLM_WARN_LOGFUNC(_Fmt...) -+#define RLM_INFO_LOGFUNC(_Fmt...) -+#define RLM_STATE_LOGFUNC(_Fmt...) -+#define RLM_EVENT_LOGFUNC(_Fmt...) -+#define RLM_TRACE_LOGFUNC(_Fmt...) -+#define RLM_LOUD_LOGFUNC(_Fmt...) -+#define RLM_TEMP_LOGFUNC(_Fmt...) -+ -+#define MEM_ERROR_LOGFUNC(_Fmt...) -+#define MEM_WARN_LOGFUNC(_Fmt...) -+#define MEM_INFO_LOGFUNC(_Fmt...) -+#define MEM_STATE_LOGFUNC(_Fmt...) -+#define MEM_EVENT_LOGFUNC(_Fmt...) -+#define MEM_TRACE_LOGFUNC(_Fmt...) -+#define MEM_LOUD_LOGFUNC(_Fmt...) -+#define MEM_TEMP_LOGFUNC(_Fmt...) -+ -+#define CNM_ERROR_LOGFUNC(_Fmt...) kalPrint(_Fmt) -+#define CNM_WARN_LOGFUNC(_Fmt...) kalPrint(_Fmt) -+#define CNM_INFO_LOGFUNC(_Fmt...) kalPrint(_Fmt) -+#define CNM_STATE_LOGFUNC(_Fmt...) -+#define CNM_EVENT_LOGFUNC(_Fmt...) -+#define CNM_TRACE_LOGFUNC(_Fmt...) -+#define CNM_LOUD_LOGFUNC(_Fmt...) -+#define CNM_TEMP_LOGFUNC(_Fmt...) -+ -+#define RSN_ERROR_LOGFUNC(_Fmt...) -+#define RSN_WARN_LOGFUNC(_Fmt...) -+#define RSN_INFO_LOGFUNC(_Fmt...) -+#define RSN_STATE_LOGFUNC(_Fmt...) -+#define RSN_EVENT_LOGFUNC(_Fmt...) -+#define RSN_TRACE_LOGFUNC(_Fmt...) -+#define RSN_LOUD_LOGFUNC(_Fmt...) -+#define RSN_TEMP_LOGFUNC(_Fmt...) -+ -+#define BSS_ERROR_LOGFUNC(_Fmt...) -+#define BSS_WARN_LOGFUNC(_Fmt...) -+#define BSS_INFO_LOGFUNC(_Fmt...) -+#define BSS_STATE_LOGFUNC(_Fmt...) -+#define BSS_EVENT_LOGFUNC(_Fmt...) -+#define BSS_TRACE_LOGFUNC(_Fmt...) -+#define BSS_LOUD_LOGFUNC(_Fmt...) -+#define BSS_TEMP_LOGFUNC(_Fmt...) -+ -+#define SCN_ERROR_LOGFUNC(_Fmt...) -+#define SCN_WARN_LOGFUNC(_Fmt...) -+#define SCN_INFO_LOGFUNC(_Fmt...) -+#define SCN_STATE_LOGFUNC(_Fmt...) -+#define SCN_EVENT_LOGFUNC(_Fmt...) -+#define SCN_TRACE_LOGFUNC(_Fmt...) -+#define SCN_LOUD_LOGFUNC(_Fmt...) -+#define SCN_TEMP_LOGFUNC(_Fmt...) -+ -+#define SAA_ERROR_LOGFUNC(_Fmt...) -+#define SAA_WARN_LOGFUNC(_Fmt...) -+#define SAA_INFO_LOGFUNC(_Fmt...) -+#define SAA_STATE_LOGFUNC(_Fmt...) -+#define SAA_EVENT_LOGFUNC(_Fmt...) -+#define SAA_TRACE_LOGFUNC(_Fmt...) -+#define SAA_LOUD_LOGFUNC(_Fmt...) -+#define SAA_TEMP_LOGFUNC(_Fmt...) -+ -+#define P2P_ERROR_LOGFUNC(_Fmt...) -+#define P2P_WARN_LOGFUNC(_Fmt...) -+#define P2P_INFO_LOGFUNC(_Fmt...) -+#define P2P_STATE_LOGFUNC(_Fmt...) -+#define P2P_EVENT_LOGFUNC(_Fmt...) -+#define P2P_TRACE_LOGFUNC(_Fmt...) -+#define P2P_LOUD_LOGFUNC(_Fmt...) -+#define P2P_TEMP_LOGFUNC(_Fmt...) -+ -+#define QM_ERROR_LOGFUNC(_Fmt...) kalPrint(_Fmt) -+#define QM_WARN_LOGFUNC(_Fmt...) kalPrint(_Fmt) -+#define QM_INFO_LOGFUNC(_Fmt...) kalPrint(_Fmt) -+#define QM_STATE_LOGFUNC(_Fmt...) -+#define QM_EVENT_LOGFUNC(_Fmt...) -+#define QM_TRACE_LOGFUNC(_Fmt...) kalPrint(_Fmt) -+#define QM_LOUD_LOGFUNC(_Fmt...) -+#define QM_TEMP_LOGFUNC(_Fmt...) -+ -+#define SEC_ERROR_LOGFUNC(_Fmt...) -+#define SEC_WARN_LOGFUNC(_Fmt...) -+#define SEC_INFO_LOGFUNC(_Fmt...) -+#define SEC_STATE_LOGFUNC(_Fmt...) -+#define SEC_EVENT_LOGFUNC(_Fmt...) -+#define SEC_TRACE_LOGFUNC(_Fmt...) -+#define SEC_LOUD_LOGFUNC(_Fmt...) -+#define SEC_TEMP_LOGFUNC(_Fmt...) -+ -+#define BOW_ERROR_LOGFUNC(_Fmt...) -+#define BOW_WARN_LOGFUNC(_Fmt...) -+#define BOW_INFO_LOGFUNC(_Fmt...) -+#define BOW_STATE_LOGFUNC(_Fmt...) -+#define BOW_EVENT_LOGFUNC(_Fmt...) -+#define BOW_TRACE_LOGFUNC(_Fmt...) -+#define BOW_LOUD_LOGFUNC(_Fmt...) -+#define BOW_TEMP_LOGFUNC(_Fmt...) -+ -+#define HAL_ERROR_LOGFUNC(_Fmt...) kalPrint(_Fmt) -+#define HAL_WARN_LOGFUNC(_Fmt...) -+#define HAL_INFO_LOGFUNC(_Fmt...) -+#define HAL_STATE_LOGFUNC(_Fmt...) -+#define HAL_EVENT_LOGFUNC(_Fmt...) -+#define HAL_TRACE_LOGFUNC(_Fmt...) -+#define HAL_LOUD_LOGFUNC(_Fmt...) -+#define HAL_TEMP_LOGFUNC(_Fmt...) -+ -+#define WAPI_ERROR_LOGFUNC(_Fmt...) -+#define WAPI_WARN_LOGFUNC(_Fmt...) -+#define WAPI_INFO_LOGFUNC(_Fmt...) -+#define WAPI_STATE_LOGFUNC(_Fmt...) -+#define WAPI_EVENT_LOGFUNC(_Fmt...) -+#define WAPI_TRACE_LOGFUNC(_Fmt...) -+#define WAPI_LOUD_LOGFUNC(_Fmt...) -+#define WAPI_TEMP_LOGFUNC(_Fmt...) -+ -+#define TDLS_ERROR_LOGFUNC(_Fmt...) kalPrint(_Fmt) -+#define TDLS_WARN_LOGFUNC(_Fmt...) kalPrint(_Fmt) -+#define TDLS_INFO_LOGFUNC(_Fmt...) kalPrint(_Fmt) -+#define TDLS_STATE_LOGFUNC(_Fmt...) -+#define TDLS_EVENT_LOGFUNC(_Fmt...) -+#define TDLS_TRACE_LOGFUNC(_Fmt...) -+#define TDLS_LOUD_LOGFUNC(_Fmt...) -+#define TDLS_TEMP_LOGFUNC(_Fmt...) -+ -+#define SW1_ERROR_LOGFUNC(_Fmt...) -+#define SW1_WARN_LOGFUNC(_Fmt...) -+#define SW1_INFO_LOGFUNC(_Fmt...) -+#define SW1_STATE_LOGFUNC(_Fmt...) -+#define SW1_EVENT_LOGFUNC(_Fmt...) -+#define SW1_TRACE_LOGFUNC(_Fmt...) -+#define SW1_LOUD_LOGFUNC(_Fmt...) -+#define SW1_TEMP_LOGFUNC(_Fmt...) -+ -+#define SW2_ERROR_LOGFUNC(_Fmt...) -+#define SW2_WARN_LOGFUNC(_Fmt...) -+#define SW2_INFO_LOGFUNC(_Fmt...) -+#define SW2_STATE_LOGFUNC(_Fmt...) -+#define SW2_EVENT_LOGFUNC(_Fmt...) -+#define SW2_TRACE_LOGFUNC(_Fmt...) -+#define SW2_LOUD_LOGFUNC(_Fmt...) -+#define SW2_TEMP_LOGFUNC(_Fmt...) -+ -+#define SW3_ERROR_LOGFUNC(_Fmt...) -+#define SW3_WARN_LOGFUNC(_Fmt...) -+#define SW3_INFO_LOGFUNC(_Fmt...) -+#define SW3_STATE_LOGFUNC(_Fmt...) -+#define SW3_EVENT_LOGFUNC(_Fmt...) -+#define SW3_TRACE_LOGFUNC(_Fmt...) -+#define SW3_LOUD_LOGFUNC(_Fmt...) -+#define SW3_TEMP_LOGFUNC(_Fmt...) -+ -+#define SW4_ERROR_LOGFUNC(_Fmt...) -+#define SW4_WARN_LOGFUNC(_Fmt...) -+#define SW4_INFO_LOGFUNC(_Fmt...) -+#define SW4_STATE_LOGFUNC(_Fmt...) -+#define SW4_EVENT_LOGFUNC(_Fmt...) -+#define SW4_TRACE_LOGFUNC(_Fmt...) -+#define SW4_LOUD_LOGFUNC(_Fmt...) -+#define SW4_TEMP_LOGFUNC(_Fmt...) -+#endif -+ -+#define kalBreakPoint() \ -+do { \ -+ BUG(); \ -+ panic("Oops"); \ -+} while (0) -+ -+#if CFG_ENABLE_AEE_MSG -+#define kalSendAeeException aee_kernel_exception -+#define kalSendAeeWarning aee_kernel_warning -+#define kalSendAeeReminding aee_kernel_reminding -+#else -+#define kalSendAeeException(_module, _desc, ...) -+#define kalSendAeeWarning(_module, _desc, ...) -+#define kalSendAeeReminding(_module, _desc, ...) -+#endif -+ -+#define PRINTF_ARG(...) __VA_ARGS__ -+#define SPRINTF(buf, arg) {buf += sprintf((char *)(buf), PRINTF_ARG arg); } -+ -+#define USEC_TO_SYSTIME(_usec) ((_usec) / USEC_PER_MSEC) -+#define MSEC_TO_SYSTIME(_msec) (_msec) -+ -+#define MSEC_TO_JIFFIES(_msec) msecs_to_jiffies(_msec) -+ -+#define KAL_HALT_LOCK_TIMEOUT_NORMAL_CASE 3000 /* 3s */ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+/*----------------------------------------------------------------------------*/ -+/* Routines in gl_kal.c */ -+/*----------------------------------------------------------------------------*/ -+VOID -+kalAcquireSpinLock(IN P_GLUE_INFO_T prGlueInfo, -+ IN ENUM_SPIN_LOCK_CATEGORY_E rLockCategory, OUT unsigned long *pu4Flags); -+ -+VOID kalReleaseSpinLock(IN P_GLUE_INFO_T prGlueInfo, IN ENUM_SPIN_LOCK_CATEGORY_E rLockCategory, IN UINT_32 u4Flags); -+ -+VOID kalUpdateMACAddress(IN P_GLUE_INFO_T prGlueInfo, IN PUINT_8 pucMacAddr); -+ -+VOID kalPacketFree(IN P_GLUE_INFO_T prGlueInfo, IN PVOID pvPacket); -+ -+PVOID kalPacketAlloc(IN P_GLUE_INFO_T prGlueInfo, IN UINT_32 u4Size, OUT PUINT_8 *ppucData); -+ -+VOID kalOsTimerInitialize(IN P_GLUE_INFO_T prGlueInfo, IN PVOID prTimerHandler); -+ -+BOOLEAN kalSetTimer(IN P_GLUE_INFO_T prGlueInfo, IN OS_SYSTIME rInterval); -+ -+WLAN_STATUS -+kalProcessRxPacket(IN P_GLUE_INFO_T prGlueInfo, IN PVOID pvPacket, IN PUINT_8 pucPacketStart, IN UINT_32 u4PacketLen, -+ /* IN PBOOLEAN pfgIsRetain, */ -+ IN BOOLEAN fgIsRetain, IN ENUM_CSUM_RESULT_T aeCSUM[] -+); -+ -+WLAN_STATUS kalRxIndicatePkts(IN P_GLUE_INFO_T prGlueInfo, IN PVOID apvPkts[], IN UINT_8 ucPktNum); -+ -+VOID -+kalIndicateStatusAndComplete(IN P_GLUE_INFO_T prGlueInfo, IN WLAN_STATUS eStatus, IN PVOID pvBuf, IN UINT_32 u4BufLen); -+ -+VOID -+kalUpdateReAssocReqInfo(IN P_GLUE_INFO_T prGlueInfo, -+ IN PUINT_8 pucFrameBody, IN UINT_32 u4FrameBodyLen, IN BOOLEAN fgReassocRequest); -+ -+VOID kalUpdateReAssocRspInfo(IN P_GLUE_INFO_T prGlueInfo, IN PUINT_8 pucFrameBody, IN UINT_32 u4FrameBodyLen); -+ -+#if CFG_TX_FRAGMENT -+BOOLEAN -+kalQueryTxPacketHeader(IN P_GLUE_INFO_T prGlueInfo, -+ IN PVOID pvPacket, OUT PUINT_16 pu2EtherTypeLen, OUT PUINT_8 pucEthDestAddr); -+#endif /* CFG_TX_FRAGMENT */ -+ -+VOID kalSendCompleteAndAwakeQueue(IN P_GLUE_INFO_T prGlueInfo, IN PVOID pvPacket); -+ -+#if CFG_TCP_IP_CHKSUM_OFFLOAD -+VOID kalQueryTxChksumOffloadParam(IN PVOID pvPacket, OUT PUINT_8 pucFlag); -+ -+VOID kalUpdateRxCSUMOffloadParam(IN PVOID pvPacket, IN ENUM_CSUM_RESULT_T eCSUM[] -+); -+#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */ -+ -+BOOLEAN kalRetrieveNetworkAddress(IN P_GLUE_INFO_T prGlueInfo, IN OUT PARAM_MAC_ADDRESS *prMacAddr); -+ -+VOID -+kalReadyOnChannel(IN P_GLUE_INFO_T prGlueInfo, -+ IN UINT_64 u8Cookie, -+ IN ENUM_BAND_T eBand, IN ENUM_CHNL_EXT_T eSco, IN UINT_8 ucChannelNum, IN UINT_32 u4DurationMs); -+ -+VOID -+kalRemainOnChannelExpired(IN P_GLUE_INFO_T prGlueInfo, -+ IN UINT_64 u8Cookie, IN ENUM_BAND_T eBand, IN ENUM_CHNL_EXT_T eSco, IN UINT_8 ucChannelNum); -+ -+VOID -+kalIndicateMgmtTxStatus(IN P_GLUE_INFO_T prGlueInfo, -+ IN UINT_64 u8Cookie, IN BOOLEAN fgIsAck, IN PUINT_8 pucFrameBuf, IN UINT_32 u4FrameLen); -+ -+VOID kalIndicateRxMgmtFrame(IN P_GLUE_INFO_T prGlueInfo, IN P_SW_RFB_T prSwRfb); -+ -+/*----------------------------------------------------------------------------*/ -+/* Routines in interface - ehpi/sdio.c */ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN kalDevRegRead(IN P_GLUE_INFO_T prGlueInfo, IN UINT_32 u4Register, OUT PUINT_32 pu4Value); -+ -+BOOLEAN kalDevRegWrite(P_GLUE_INFO_T prGlueInfo, IN UINT_32 u4Register, IN UINT_32 u4Value); -+ -+BOOLEAN -+kalDevPortRead(IN P_GLUE_INFO_T prGlueInfo, -+ IN UINT_16 u2Port, IN UINT_32 u2Len, OUT PUINT_8 pucBuf, IN UINT_32 u2ValidOutBufSize); -+ -+BOOLEAN -+kalDevPortWrite(P_GLUE_INFO_T prGlueInfo, -+ IN UINT_16 u2Port, IN UINT_32 u2Len, IN PUINT_8 pucBuf, IN UINT_32 u2ValidInBufSize); -+ -+BOOLEAN kalDevWriteWithSdioCmd52(IN P_GLUE_INFO_T prGlueInfo, IN UINT_32 u4Addr, IN UINT_8 ucData); -+ -+void kalDevLoopbkAuto(IN GLUE_INFO_T *GlueInfo); -+ -+#if CFG_SUPPORT_EXT_CONFIG -+UINT_32 kalReadExtCfg(IN P_GLUE_INFO_T prGlueInfo); -+#endif -+ -+BOOLEAN -+kalQoSFrameClassifierAndPacketInfo(IN P_GLUE_INFO_T prGlueInfo, -+ IN P_NATIVE_PACKET prPacket, -+ OUT PUINT_8 pucPriorityParam, -+ OUT PUINT_32 pu4PacketLen, -+ OUT PUINT_8 pucEthDestAddr, -+ OUT PBOOLEAN pfgIs1X, -+ OUT PBOOLEAN pfgIsPAL, OUT PUINT_8 pucNetworkType, -+ OUT PVOID prGenUse); -+ -+VOID -+kalOidComplete(IN P_GLUE_INFO_T prGlueInfo, -+ IN BOOLEAN fgSetQuery, IN UINT_32 u4SetQueryInfoLen, IN WLAN_STATUS rOidStatus); -+ -+WLAN_STATUS -+kalIoctl(IN P_GLUE_INFO_T prGlueInfo, -+ IN PFN_OID_HANDLER_FUNC pfnOidHandler, -+ IN PVOID pvInfoBuf, -+ IN UINT_32 u4InfoBufLen, -+ IN BOOLEAN fgRead, IN BOOLEAN fgWaitResp, IN BOOLEAN fgCmd, IN BOOLEAN fgIsP2pOid, OUT PUINT_32 pu4QryInfoLen); -+ -+VOID kalHandleAssocInfo(IN P_GLUE_INFO_T prGlueInfo, IN P_EVENT_ASSOC_INFO prAssocInfo); -+ -+#if CFG_ENABLE_FW_DOWNLOAD -+ -+PVOID kalFirmwareImageMapping(IN P_GLUE_INFO_T prGlueInfo, OUT PPVOID ppvMapFileBuf, OUT PUINT_32 pu4FileLength); -+ -+VOID kalFirmwareImageUnmapping(IN P_GLUE_INFO_T prGlueInfo, IN PVOID prFwHandle, IN PVOID pvMapFileBuf); -+#endif -+ -+/*----------------------------------------------------------------------------*/ -+/* Card Removal Check */ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN kalIsCardRemoved(IN P_GLUE_INFO_T prGlueInfo); -+ -+/*----------------------------------------------------------------------------*/ -+/* TX */ -+/*----------------------------------------------------------------------------*/ -+VOID kalFlushPendingTxPackets(IN P_GLUE_INFO_T prGlueInfo); -+ -+/*----------------------------------------------------------------------------*/ -+/* Media State Indication */ -+/*----------------------------------------------------------------------------*/ -+ENUM_PARAM_MEDIA_STATE_T kalGetMediaStateIndicated(IN P_GLUE_INFO_T prGlueInfo); -+ -+VOID kalSetMediaStateIndicated(IN P_GLUE_INFO_T prGlueInfo, IN ENUM_PARAM_MEDIA_STATE_T eParamMediaStateIndicate); -+ -+/*----------------------------------------------------------------------------*/ -+/* OID handling */ -+/*----------------------------------------------------------------------------*/ -+VOID kalOidCmdClearance(IN P_GLUE_INFO_T prGlueInfo); -+ -+VOID kalOidClearance(IN P_GLUE_INFO_T prGlueInfo); -+ -+VOID kalEnqueueCommand(IN P_GLUE_INFO_T prGlueInfo, IN P_QUE_ENTRY_T prQueueEntry); -+ -+#if CFG_ENABLE_BT_OVER_WIFI -+/*----------------------------------------------------------------------------*/ -+/* Bluetooth over Wi-Fi handling */ -+/*----------------------------------------------------------------------------*/ -+VOID kalIndicateBOWEvent(IN P_GLUE_INFO_T prGlueInfo, IN P_AMPC_EVENT prEvent); -+ -+ENUM_BOW_DEVICE_STATE kalGetBowState(IN P_GLUE_INFO_T prGlueInfo, IN PARAM_MAC_ADDRESS rPeerAddr); -+ -+BOOLEAN kalSetBowState(IN P_GLUE_INFO_T prGlueInfo, IN ENUM_BOW_DEVICE_STATE eBowState, PARAM_MAC_ADDRESS rPeerAddr); -+ -+ENUM_BOW_DEVICE_STATE kalGetBowGlobalState(IN P_GLUE_INFO_T prGlueInfo); -+ -+UINT_32 kalGetBowFreqInKHz(IN P_GLUE_INFO_T prGlueInfo); -+ -+UINT_8 kalGetBowRole(IN P_GLUE_INFO_T prGlueInfo, IN PARAM_MAC_ADDRESS rPeerAddr); -+ -+VOID kalSetBowRole(IN P_GLUE_INFO_T prGlueInfo, IN UINT_8 ucRole, IN PARAM_MAC_ADDRESS rPeerAddr); -+ -+UINT_8 kalGetBowAvailablePhysicalLinkCount(IN P_GLUE_INFO_T prGlueInfo); -+ -+#if CFG_BOW_SEPARATE_DATA_PATH -+/*----------------------------------------------------------------------------*/ -+/* Bluetooth over Wi-Fi Net Device Init/Uninit */ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN kalInitBowDevice(IN P_GLUE_INFO_T prGlueInfo, IN const char *prDevName); -+ -+BOOLEAN kalUninitBowDevice(IN P_GLUE_INFO_T prGlueInfo); -+#endif /* CFG_BOW_SEPARATE_DATA_PATH */ -+#endif /* CFG_ENABLE_BT_OVER_WIFI */ -+ -+/*----------------------------------------------------------------------------*/ -+/* Firmware Download Handling */ -+/*----------------------------------------------------------------------------*/ -+UINT_32 kalGetFwStartAddress(IN P_GLUE_INFO_T prGlueInfo); -+ -+UINT_32 kalGetFwLoadAddress(IN P_GLUE_INFO_T prGlueInfo); -+ -+/*----------------------------------------------------------------------------*/ -+/* Security Frame Clearance */ -+/*----------------------------------------------------------------------------*/ -+VOID kalClearSecurityFrames(IN P_GLUE_INFO_T prGlueInfo); -+ -+VOID kalClearSecurityFramesByNetType(IN P_GLUE_INFO_T prGlueInfo, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx); -+ -+VOID kalSecurityFrameSendComplete(IN P_GLUE_INFO_T prGlueInfo, IN PVOID pvPacket, IN WLAN_STATUS rStatus); -+ -+/*----------------------------------------------------------------------------*/ -+/* Management Frame Clearance */ -+/*----------------------------------------------------------------------------*/ -+VOID kalClearMgmtFrames(IN P_GLUE_INFO_T prGlueInfo); -+ -+VOID kalClearMgmtFramesByNetType(IN P_GLUE_INFO_T prGlueInfo, IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx); -+ -+UINT_32 kalGetTxPendingFrameCount(IN P_GLUE_INFO_T prGlueInfo); -+ -+UINT_32 kalGetTxPendingCmdCount(IN P_GLUE_INFO_T prGlueInfo); -+ -+BOOLEAN kalSetTimer(IN P_GLUE_INFO_T prGlueInfo, IN UINT_32 u4Interval); -+ -+BOOLEAN kalCancelTimer(IN P_GLUE_INFO_T prGlueInfo); -+ -+VOID kalScanDone(IN P_GLUE_INFO_T prGlueInfo, IN ENUM_KAL_NETWORK_TYPE_INDEX_T eNetTypeIdx, IN WLAN_STATUS status); -+ -+UINT_32 kalRandomNumber(VOID); -+ -+VOID kalTimeoutHandler(struct timer_list *t); -+ -+VOID kalSetEvent(P_GLUE_INFO_T pr); -+ -+/*----------------------------------------------------------------------------*/ -+/* NVRAM/Registry Service */ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN kalIsConfigurationExist(IN P_GLUE_INFO_T prGlueInfo); -+ -+P_REG_INFO_T kalGetConfiguration(IN P_GLUE_INFO_T prGlueInfo); -+ -+VOID -+kalGetConfigurationVersion(IN P_GLUE_INFO_T prGlueInfo, -+ OUT PUINT_16 pu2Part1CfgOwnVersion, -+ OUT PUINT_16 pu2Part1CfgPeerVersion, -+ OUT PUINT_16 pu2Part2CfgOwnVersion, OUT PUINT_16 pu2Part2CfgPeerVersion); -+ -+BOOLEAN kalCfgDataRead16(IN P_GLUE_INFO_T prGlueInfo, IN UINT_32 u4Offset, OUT PUINT_16 pu2Data); -+ -+BOOLEAN kalCfgDataWrite16(IN P_GLUE_INFO_T prGlueInfo, IN UINT_32 u4Offset, IN UINT_16 u2Data); -+ -+/*----------------------------------------------------------------------------*/ -+/* WSC Connection */ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN kalWSCGetActiveState(IN P_GLUE_INFO_T prGlueInfo); -+ -+/*----------------------------------------------------------------------------*/ -+/* RSSI Updating */ -+/*----------------------------------------------------------------------------*/ -+VOID -+kalUpdateRSSI(IN P_GLUE_INFO_T prGlueInfo, -+ IN ENUM_KAL_NETWORK_TYPE_INDEX_T eNetTypeIdx, IN INT_8 cRssi, IN INT_8 cLinkQuality); -+ -+/*----------------------------------------------------------------------------*/ -+/* I/O Buffer Pre-allocation */ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN kalInitIOBuffer(VOID); -+ -+VOID kalUninitIOBuffer(VOID); -+ -+PVOID kalAllocateIOBuffer(IN UINT_32 u4AllocSize); -+ -+VOID kalReleaseIOBuffer(IN PVOID pvAddr, IN UINT_32 u4Size); -+ -+VOID -+kalGetChannelList(IN P_GLUE_INFO_T prGlueInfo, -+ IN ENUM_BAND_T eSpecificBand, -+ IN UINT_8 ucMaxChannelNum, IN PUINT_8 pucNumOfChannel, IN P_RF_CHANNEL_INFO_T paucChannelList); -+ -+BOOLEAN kalIsAPmode(IN P_GLUE_INFO_T prGlueInfo); -+ -+ULONG kalIOPhyAddrGet(IN ULONG VirtAddr); -+ -+VOID kalDmaBufGet(OUT VOID **VirtAddr, OUT VOID **PhyAddr); -+ -+#if CFG_SUPPORT_802_11W -+/*----------------------------------------------------------------------------*/ -+/* 802.11W */ -+/*----------------------------------------------------------------------------*/ -+UINT_32 kalGetMfpSetting(IN P_GLUE_INFO_T prGlueInfo); -+#endif -+ -+UINT_32 kalWriteToFile(const PUINT_8 pucPath, BOOLEAN fgDoAppend, PUINT_8 pucData, UINT_32 u4Size); -+ -+/*----------------------------------------------------------------------------*/ -+/* NL80211 */ -+/*----------------------------------------------------------------------------*/ -+VOID -+kalIndicateBssInfo(IN P_GLUE_INFO_T prGlueInfo, -+ IN PUINT_8 pucFrameBuf, IN UINT_32 u4BufLen, IN UINT_8 ucChannelNum, IN INT_32 i4SignalStrength); -+ -+/*----------------------------------------------------------------------------*/ -+/* PNO Support */ -+/*----------------------------------------------------------------------------*/ -+VOID kalSchedScanResults(IN P_GLUE_INFO_T prGlueInfo); -+ -+VOID kalSchedScanStopped(IN P_GLUE_INFO_T prGlueInfo); -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+int tx_thread(void *data); -+ -+VOID kalHifAhbKalWakeLockTimeout(IN P_GLUE_INFO_T prGlueInfo); -+VOID kalMetProfilingStart(IN P_GLUE_INFO_T prGlueInfo, IN struct sk_buff *prSkb); -+VOID kalMetProfilingFinish(IN P_ADAPTER_T prAdapter, IN P_MSDU_INFO_T prMsduInfo); -+int kalMetInitProcfs(IN P_GLUE_INFO_T prGlueInfo); -+int kalMetRemoveProcfs(void); -+ -+UINT_64 kalGetBootTime(void); -+ -+INT_32 kalReadToFile(const PUINT_8 pucPath, PUINT_8 pucData, UINT_32 u4Size, PUINT_32 pu4ReadSize); -+#if CFG_SUPPORT_WAKEUP_REASON_DEBUG -+BOOLEAN kalIsWakeupByWlan(P_ADAPTER_T prAdapter); -+#endif -+INT_32 kalHaltLock(UINT_32 waitMs); -+INT_32 kalHaltTryLock(VOID); -+VOID kalHaltUnlock(VOID); -+VOID kalSetHalted(BOOLEAN fgHalt); -+BOOLEAN kalIsHalted(VOID); -+ -+INT32 kalPerMonInit(IN P_GLUE_INFO_T prGlueInfo); -+INT32 kalPerMonDisable(IN P_GLUE_INFO_T prGlueInfo); -+INT32 kalPerMonEnable(IN P_GLUE_INFO_T prGlueInfo); -+INT32 kalPerMonStart(IN P_GLUE_INFO_T prGlueInfo); -+INT32 kalPerMonStop(IN P_GLUE_INFO_T prGlueInfo); -+INT32 kalPerMonDestroy(IN P_GLUE_INFO_T prGlueInfo); -+VOID kalPerMonHandler(IN P_ADAPTER_T prAdapter, ULONG ulParam); -+INT32 kalBoostCpu(UINT_32 core_num); -+ -+#endif /* _GL_KAL_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_os.h b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_os.h -new file mode 100644 -index 000000000000..a4321e7f9a11 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_os.h -@@ -0,0 +1,1270 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux/include/gl_os.h#2 -+*/ -+ -+/*! \file gl_os.h -+ \brief List the external reference to OS for GLUE Layer. -+ -+ In this file we define the data structure - GLUE_INFO_T to store those objects -+ we acquired from OS - e.g. TIMER, SPINLOCK, NET DEVICE ... . And all the -+ external reference (header file, extern func() ..) to OS for GLUE Layer should -+ also list down here. -+*/ -+ -+/* -+** Log: gl_os.h -+** -+** 08 20 2012 yuche.tsai -+** NULL -+** Fix possible KE issue. -+** -+** 08 20 2012 yuche.tsai -+** [ALPS00339327] [Rose][6575JB][BSP Package][Free Test][KE][WIFI]There is no response when you tap the turn off/on -+** button,wait a minutes, the device will reboot automatically and "KE" will pop up. -+** Fix possible KE when netlink operate mgmt frame register. -+ * -+ * 04 12 2012 terry.wu -+ * NULL -+ * Add AEE message support -+ * 1) Show AEE warning(red screen) if SDIO access error occurs -+ -+ * -+ * 03 02 2012 terry.wu -+ * NULL -+ * Enable CFG80211 Support. -+ * -+ * 01 05 2012 wh.su -+ * [WCXRP00001153] [MT6620 Wi-Fi][Driver] Adding the get_ch_list and set_tx_power proto type function -+ * Adding the related ioctl / wlan oid function to set the Tx power cfg. -+ * -+ * 12 13 2011 cm.chang -+ * [WCXRP00001136] [All Wi-Fi][Driver] Add wake lock for pending timer -+ * Add wake lock if timer timeout value is smaller than 5 seconds -+ * -+ * 11 18 2011 yuche.tsai -+ * NULL -+ * CONFIG P2P support RSSI query, default turned off. -+ * -+ * 11 16 2011 yuche.tsai -+ * NULL -+ * Avoid using work thread. -+ * -+ * 11 11 2011 yuche.tsai -+ * NULL -+ * Fix work thread cancel issue. -+ * -+ * 10 12 2011 wh.su -+ * [WCXRP00001036] [MT6620 Wi-Fi][Driver][FW] Adding the 802.11w code for MFP -+ * adding the 802.11w related function and define . -+ * -+ * 09 29 2011 terry.wu -+ * NULL -+ * Show DRV_NAME by chip id. -+ * -+ * 04 18 2011 terry.wu -+ * [WCXRP00000660] [MT6620 Wi-Fi][Driver] Remove flag CFG_WIFI_DIRECT_MOVED -+ * Remove flag CFG_WIFI_DIRECT_MOVED. -+ * -+ * 03 29 2011 cp.wu -+ * [WCXRP00000598] [MT6620 Wi-Fi][Driver] Implementation of interface for communicating with user space process for -+ * RESET_START and RESET_END events -+ * implement kernel-to-userspace communication via generic netlink socket for whole-chip resetting mechanism -+ * -+ * 03 21 2011 cp.wu -+ * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer -+ * portability improvement -+ * -+ * 03 17 2011 chinglan.wang -+ * [WCXRP00000570] [MT6620 Wi-Fi][Driver] Add Wi-Fi Protected Setup v2.0 feature -+ * . -+ * -+ * 03 03 2011 jeffrey.chang -+ * [WCXRP00000512] [MT6620 Wi-Fi][Driver] modify the net device relative functions to support the H/W multiple queue -+ * support concurrent network -+ * -+ * 03 03 2011 jeffrey.chang -+ * [WCXRP00000512] [MT6620 Wi-Fi][Driver] modify the net device relative functions to support the H/W multiple queue -+ * modify net device relative functions to support multiple H/W queues -+ * -+ * 03 02 2011 wh.su -+ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code -+ * Add security check code. -+ * -+ * 02 21 2011 cp.wu -+ * [WCXRP00000482] [MT6620 Wi-Fi][Driver] Simplify logic for checking NVRAM existence in driver domain -+ * simplify logic for checking NVRAM existence only once. -+ * -+ * 02 16 2011 jeffrey.chang -+ * NULL -+ * Add query ipv4 and ipv6 address during early suspend and late resume -+ * -+ * 02 10 2011 chinghwa.yu -+ * [WCXRP00000065] Update BoW design and settings -+ * Fix kernel API change issue. -+ * Before ALPS 2.2 (2.2 included), kfifo_alloc() is -+ * struct kfifo *kfifo_alloc(unsigned int size, gfp_t gfp_mask, spinlock_t *lock); -+ * After ALPS 2.3, kfifo_alloc() is changed to -+ * int kfifo_alloc(struct kfifo *fifo, unsigned int size, gfp_t gfp_mask); -+ * -+ * 02 09 2011 wh.su -+ * [WCXRP00000433] [MT6620 Wi-Fi][Driver] Remove WAPI structure define for avoid P2P module with structure miss-align -+ * pointer issue -+ * always pre-allio WAPI related structure for align p2p module. -+ * -+ * 02 09 2011 terry.wu -+ * [WCXRP00000383] [MT6620 Wi-Fi][Driver] Separate WiFi and P2P driver into two modules -+ * Halt p2p module init and exit until TxThread finished p2p register and unregister. -+ * -+ * 02 01 2011 cm.chang -+ * [WCXRP00000415] [MT6620 Wi-Fi][Driver] Check if any memory leakage happens when uninitializing in DGB mode -+ * . -+ * -+ * 01 27 2011 cm.chang -+ * [WCXRP00000402] [MT6620 Wi-Fi][Driver] Enable MCR read/write by iwpriv by default -+ * . -+ * -+ * 01 12 2011 cp.wu -+ * [WCXRP00000357] [MT6620 Wi-Fi][Driver][Bluetooth over Wi-Fi] add another net device interface for BT AMP -+ * implementation of separate BT_OVER_WIFI data path. -+ * -+ * 01 12 2011 cp.wu -+ * [WCXRP00000356] [MT6620 Wi-Fi][Driver] fill mac header length for security frames 'cause hardware header translation -+ * needs such information -+ * fill mac header length information for 802.1x frames. -+ * -+ * 01 11 2011 chinglan.wang -+ * NULL -+ * Modify to reslove the CR :[ALPS00028994] Use WEP security to connect Marvell 11N AP. Connection establish -+ * successfully. -+ * Use the WPS function to connect AP, the privacy bit always is set to 1. -+ * -+ * 01 10 2011 cp.wu -+ * [WCXRP00000349] [MT6620 Wi-Fi][Driver] make kalIoctl() of linux port as a thread safe API to avoid potential issues -+ * due to multiple access -+ * use mutex to protect kalIoctl() for thread safe. -+ * -+ * 01 05 2011 cp.wu -+ * [WCXRP00000283] [MT6620 Wi-Fi][Driver][Wi-Fi Direct] Implementation of interface for supporting Wi-Fi Direct Service -+ * Discovery -+ * ioctl implementations for P2P Service Discovery -+ * -+ * 11 04 2010 wh.su -+ * [WCXRP00000164] [MT6620 Wi-Fi][Driver] Support the p2p random SSID -+ * adding the p2p random ssid support. -+ * -+ * 10 18 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000086] [MT6620 Wi-Fi][Driver] -+ * The mac address is all zero at android -+ * complete implementation of Android NVRAM access -+ * -+ * 09 28 2010 wh.su -+ * NULL -+ * [WCXRP00000069][MT6620 Wi-Fi][Driver] Fix some code for phase 1 P2P Demo. -+ * -+ * 09 23 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check -+ * add skeleton for NVRAM integration -+ * -+ * 09 13 2010 cp.wu -+ * NULL -+ * add waitq for poll() and read(). -+ * -+ * 09 07 2010 wh.su -+ * NULL -+ * adding the code for beacon/probe req/ probe rsp wsc ie at p2p. -+ * -+ * 09 06 2010 wh.su -+ * NULL -+ * let the p2p can set the privacy bit at beacon and rsn ie at assoc req at key handshake state. -+ * -+ * 09 03 2010 kevin.huang -+ * NULL -+ * Refine #include sequence and solve recursive/nested #include issue -+ * -+ * 09 01 2010 wh.su -+ * NULL -+ * adding the wapi support for integration test. -+ * -+ * 08 31 2010 kevin.huang -+ * NULL -+ * Use LINK LIST operation to process SCAN result -+ * -+ * 08 23 2010 cp.wu -+ * NULL -+ * revise constant definitions to be matched with implementation (original cmd-event definition is deprecated) -+ * -+ * 08 16 2010 cp.wu -+ * NULL -+ * P2P packets are now marked when being queued into driver, and identified later without checking MAC address -+ * -+ * 08 16 2010 cp.wu -+ * NULL -+ * revised implementation of Wi-Fi Direct io controls. -+ * -+ * 08 11 2010 cp.wu -+ * NULL -+ * 1) do not use in-stack variable for beacon updating. (for MAUI porting) -+ * 2) extending scanning result to 64 instead of 48 -+ * -+ * 08 06 2010 cp.wu -+ * NULL -+ * driver hook modifications corresponding to ioctl interface change. -+ * -+ * 08 03 2010 cp.wu -+ * NULL -+ * [Wi-Fi Direct] add framework for driver hooks -+ * -+ * 08 02 2010 jeffrey.chang -+ * NULL -+ * 1) modify tx service thread to avoid busy looping -+ * 2) add spin lock declartion for linux build -+ * -+ * 07 23 2010 jeffrey.chang -+ * -+ * add new KAL api -+ * -+ * 07 22 2010 jeffrey.chang -+ * -+ * modify tx thread and remove some spinlock -+ * -+ * 07 19 2010 jeffrey.chang -+ * -+ * add security frame pending count -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 06 01 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * add ioctl to configure scan mode for p2p connection -+ * -+ * 05 31 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * add cfg80211 interface, which is to replace WE, for further extension -+ * -+ * 05 14 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * add ioctl framework for Wi-Fi Direct by reusing wireless extension ioctls as well -+ * -+ * 05 11 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * p2p ioctls revised. -+ * -+ * 05 11 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * add ioctl for controlling p2p scan phase parameters -+ * -+ * 05 10 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * implement basic wi-fi direct framework -+ * -+ * 05 07 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * prevent supplicant accessing driver during resume -+ * -+ * 05 07 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * add basic framework for implementating P2P driver hook. -+ * -+ * 05 05 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * change variable names for multiple physical link to match with coding convention -+ * -+ * 04 27 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * identify BT Over Wi-Fi Security frame and mark it as 802.1X frame -+ * -+ * 04 27 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * add multiple physical link support -+ * -+ * 04 27 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * 1) fix firmware download bug -+ * 2) remove query statistics for acelerating firmware download -+ * -+ * 04 27 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * follow Linux's firmware framework, and remove unused kal API -+ * -+ * 04 23 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * surpress compiler warning -+ * -+ * 04 19 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * supporting power management -+ * -+ * 04 14 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * pvInformationBuffer and u4InformationBufferLength are no longer in glue -+ * -+ * 04 13 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * add framework for BT-over-Wi-Fi support. -+ * * * * * * * * * * * * * * * * * * * * 1) prPendingCmdInfo is replaced by queue for multiple -+ * * * * * * * * * * * * * * * * * * * * handler capability -+ * * * * * * * * * * * * * * * * * * * * 2) command sequence number is now increased atomically -+ * * * * * * * * * * * * * * * * * * * * 3) private data could be hold and taken use for other -+ * * * * * * * * * * * * * * * * * * * * purpose -+ * -+ * 04 07 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * rWlanInfo should be placed at adapter rather than glue due to most operations -+ * * * * * * * * * * are done in adapter layer. -+ * -+ * 04 06 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * Tag the packet for QoS on Tx path -+ * -+ * 04 06 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * (1)deliver the kalOidComplete status to upper layer -+ * * (2) fix spin lock -+ * -+ * 04 06 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * add timeout check in the kalOidComplete -+ * -+ * 04 06 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * improve none-glue code portability -+ * -+ * 04 06 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * code refine: fgTestMode should be at adapter rather than glue due to the device/fw is also involved -+ * -+ * 04 06 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * eliminate direct access for prGlueInfo->fgIsCardRemoved in non-glue layer -+ * -+ * 03 30 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * emulate NDIS Pending OID facility -+ * -+ * 03 26 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * [WPD00003826] Initial import for Linux port -+ * adding firmware download related data type -+ * -+ * 03 25 2010 cp.wu -+ * [WPD00001943]Create WiFi test driver framework on WinXP -+ * 1) correct OID_802_11_CONFIGURATION with frequency setting behavior. -+ * * * * the frequency is used for adhoc connection only -+ * * * * 2) update with SD1 v0.9 CMD/EVENT documentation -+ * -+ * 03 25 2010 cp.wu -+ * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support -+ * add Bluetooth-over-Wifi frame header check -+ * -+ * 03 24 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * initial import for Linux port -+** \main\maintrunk.MT5921\30 2009-10-20 17:38:31 GMT mtk01090 -+** Refine driver unloading and clean up procedure. Block requests, stop main thread and clean up queued requests, -+** and then stop hw. -+** \main\maintrunk.MT5921\29 2009-10-08 10:33:33 GMT mtk01090 -+** Avoid accessing private data of net_device directly. Replace with netdev_priv(). Add more checking for input -+** parameters and pointers. -+** \main\maintrunk.MT5921\28 2009-09-28 20:19:26 GMT mtk01090 -+** Add private ioctl to carry OID structures. Restructure public/private ioctl interfaces to Linux kernel. -+** \main\maintrunk.MT5921\27 2009-08-18 22:57:12 GMT mtk01090 -+** Add Linux SDIO (with mmc core) support. -+** Add Linux 2.6.21, 2.6.25, 2.6.26. -+** Fix compile warning in Linux. -+** \main\maintrunk.MT5921\26 2009-07-06 21:42:25 GMT mtk01088 -+** fixed the compiling error at linux -+** \main\maintrunk.MT5921\25 2009-07-06 20:51:46 GMT mtk01088 -+** adding the wapi 1x ether type define -+** \main\maintrunk.MT5921\24 2009-06-23 23:19:18 GMT mtk01090 -+** Add build option BUILD_USE_EEPROM and compile option CFG_SUPPORT_EXT_CONFIG for NVRAM support -+** \main\maintrunk.MT5921\23 2009-02-07 15:05:06 GMT mtk01088 -+** add the privacy flag to ingo driver the supplicant selected ap's security -+** \main\maintrunk.MT5921\22 2009-02-05 15:34:09 GMT mtk01088 -+** fixed the compiling error for using bits marco for only one parameter -+** \main\maintrunk.MT5921\21 2009-01-22 13:02:13 GMT mtk01088 -+** data frame is or not 802.1x value share with tid, using the same reserved byte, provide the function to set and get -+** \main\maintrunk.MT5921\20 2008-10-24 12:04:16 GMT mtk01088 -+** move the config.h from precomp.h to here for lint check -+** \main\maintrunk.MT5921\19 2008-09-22 23:19:02 GMT mtk01461 -+** Update driver for code review -+** \main\maintrunk.MT5921\18 2008-09-05 17:25:13 GMT mtk01461 -+** Update Driver for Code Review -+** \main\maintrunk.MT5921\17 2008-08-01 13:32:47 GMT mtk01084 -+** Prevent redundent driver assertion in driver logic when BUS is detached -+** \main\maintrunk.MT5921\16 2008-05-30 14:41:43 GMT mtk01461 -+** Remove WMM Assoc Flag in KAL -+** \main\maintrunk.MT5921\15 2008-05-29 14:16:25 GMT mtk01084 -+** remoev un-used variable -+** \main\maintrunk.MT5921\14 2008-05-03 15:17:14 GMT mtk01461 -+** Add Media Status variable in Glue Layer -+** \main\maintrunk.MT5921\13 2008-04-24 11:58:41 GMT mtk01461 -+** change threshold to 256 -+** \main\maintrunk.MT5921\12 2008-03-11 14:51:05 GMT mtk01461 -+** Remove redundant GL_CONN_INFO_T -+** \main\maintrunk.MT5921\11 2008-01-07 15:07:41 GMT mtk01461 -+** Adjust the netif stop threshold to 150 -+** \main\maintrunk.MT5921\10 2007-11-26 19:43:46 GMT mtk01461 -+** Add OS_TIMESTAMP macro -+** -+** \main\maintrunk.MT5921\9 2007-11-07 18:38:38 GMT mtk01461 -+** Move definition -+** \main\maintrunk.MT5921\8 2007-11-02 01:04:00 GMT mtk01461 -+** Unify TX Path for Normal and IBSS Power Save + IBSS neighbor learning -+** Revision 1.5 2007/07/12 11:04:28 MTK01084 -+** update macro to delay for ms order -+** -+** Revision 1.4 2007/07/05 07:25:34 MTK01461 -+** Add Linux initial code, modify doc, add 11BB, RF init code -+** -+** Revision 1.3 2007/06/27 02:18:51 MTK01461 -+** Update SCAN_FSM, Initial(Can Load Module), Proc(Can do Reg R/W), TX API -+** -+** Revision 1.2 2007/06/25 06:16:24 MTK01461 -+** Update illustrations, gl_init.c, gl_kal.c, gl_kal.h, gl_os.h and RX API -+** -+*/ -+ -+#ifndef _GL_OS_H -+#define _GL_OS_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+/*------------------------------------------------------------------------------ -+ * Flags for LINUX(OS) dependent -+ *------------------------------------------------------------------------------ -+ */ -+#define CFG_MAX_WLAN_DEVICES 1 /* number of wlan card will coexist */ -+ -+#define CFG_MAX_TXQ_NUM 4 /* number of tx queue for support multi-queue h/w */ -+ -+#define CFG_USE_SPIN_LOCK_BOTTOM_HALF 0 /* 1: Enable use of SPIN LOCK Bottom Half for LINUX -+ 0: Disable - use SPIN LOCK IRQ SAVE instead */ -+ -+#define CFG_TX_PADDING_SMALL_ETH_PACKET 0 /* 1: Enable - Drop ethernet packet if it < 14 bytes. -+ And pad ethernet packet with dummy 0 if it < 60 bytes. -+ 0: Disable */ -+ -+#define CFG_TX_STOP_NETIF_QUEUE_THRESHOLD 256 /* packets */ -+ -+#define CFG_TX_STOP_NETIF_PER_QUEUE_THRESHOLD 256 /* packets */ -+#define CFG_TX_START_NETIF_PER_QUEUE_THRESHOLD 128 /* packets */ -+ -+#define ETH_P_1X 0x888E -+#define IPTOS_PREC_OFFSET 5 -+#define USER_PRIORITY_DEFAULT 0 -+ -+#define ETH_WPI_1X 0x88B4 -+ -+#define ETH_HLEN 14 -+#define ETH_TYPE_LEN_OFFSET 12 -+#define ETH_P_IP 0x0800 -+#define ETH_P_1X 0x888E -+#define ETH_P_PRE_1X 0x88C7 -+#define ETH_P_ARP 0x0806 -+ -+#define ARP_PRO_REQ 1 -+#define ARP_PRO_RSP 2 -+ -+#define IPVERSION 4 -+#define IP_HEADER_LEN 20 -+ -+#define IP_PRO_ICMP 0x01 -+#define IP_PRO_UDP 0x11 -+#define IP_PRO_TCP 0x06 -+ -+#define UDP_PORT_DHCPS 0x43 -+#define UDP_PORT_DHCPC 0x44 -+#define UDP_PORT_DNS 0x35 -+ -+#define IPVH_VERSION_OFFSET 4 /* For Little-Endian */ -+#define IPVH_VERSION_MASK 0xF0 -+#define IPTOS_PREC_OFFSET 5 -+#define IPTOS_PREC_MASK 0xE0 -+ -+#define SOURCE_PORT_LEN 2 -+/* NOTE(Kevin): Without IP Option Length */ -+#define LOOK_AHEAD_LEN (ETH_HLEN + IP_HEADER_LEN + SOURCE_PORT_LEN) -+ -+/* 802.2 LLC/SNAP */ -+#define ETH_LLC_OFFSET (ETH_HLEN) -+#define ETH_LLC_LEN 3 -+#define ETH_LLC_DSAP_SNAP 0xAA -+#define ETH_LLC_SSAP_SNAP 0xAA -+#define ETH_LLC_CONTROL_UNNUMBERED_INFORMATION 0x03 -+ -+/* Bluetooth SNAP */ -+#define ETH_SNAP_OFFSET (ETH_HLEN + ETH_LLC_LEN) -+#define ETH_SNAP_LEN 5 -+#define ETH_SNAP_BT_SIG_OUI_0 0x00 -+#define ETH_SNAP_BT_SIG_OUI_1 0x19 -+#define ETH_SNAP_BT_SIG_OUI_2 0x58 -+ -+#define BOW_PROTOCOL_ID_SECURITY_FRAME 0x0003 -+ -+#if defined(MT6620) -+#define CHIP_NAME "MT6620" -+#elif defined(MT6628) -+#define CHIP_NAME "MT6582" -+#endif -+ -+#define DRV_NAME "["CHIP_NAME"]: " -+ -+#define CONFIG_ANDROID 1 -+/* Define if target platform is Android. -+ * It should already be defined in Android kernel source -+ */ -+ -+/* for CFG80211 IE buffering mechanism */ -+#define CFG_CFG80211_IE_BUF_LEN (512) -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include /* constant of kernel version */ -+ -+#include /* bitops.h */ -+ -+#include /* struct timer_list */ -+#include /* jiffies */ -+#include /* udelay and mdelay macro */ -+ -+#if CONFIG_ANDROID -+#include -+#endif -+ -+#include /* IRQT_FALLING */ -+ -+#include /* struct net_device, struct net_device_stats */ -+#include /* for eth_type_trans() function */ -+#include /* struct iw_statistics */ -+#include -+#include /* struct in_device */ -+ -+#include /* struct iphdr */ -+ -+#include /* for memcpy()/memset() function */ -+#include /* for offsetof() macro */ -+ -+#include /* The proc filesystem constants/structures */ -+ -+#include /* for rtnl_lock() and rtnl_unlock() */ -+#include /* kthread_should_stop(), kthread_run() */ -+#include /* for copy_from_user() */ -+#include /* for firmware download */ -+#include -+ -+#include /* for kfifo interface */ -+#include /* for cdev interface */ -+ -+#include /* for firmware download */ -+ -+#if defined(_HIF_SDIO) -+#include -+#include -+#endif -+ -+#include -+ -+#include -+#include -+ -+#include /* readw and writew */ -+ -+#if WIRELESS_EXT > 12 -+#include -+#endif -+ -+#include "version.h" -+#include "config.h" -+ -+#if CFG_ENABLE_WIFI_DIRECT_CFG_80211 -+#include -+#include -+#endif -+ -+#include -+ -+#if CFG_SUPPORT_HOTSPOT_2_0 -+#include -+#endif -+ -+#include "gl_typedef.h" -+#include "typedef.h" -+#include "queue.h" -+#include "gl_kal.h" -+#include "hif.h" -+#if CFG_CHIP_RESET_SUPPORT -+#include "gl_rst.h" -+#endif -+ -+#if (CFG_SUPPORT_TDLS == 1) -+#include "tdls_extr.h" -+#endif -+#include "debug.h" -+ -+#include "wlan_lib.h" -+#include "wlan_oid.h" -+ -+#if CFG_ENABLE_AEE_MSG -+#include -+#endif -+ -+extern BOOLEAN fgIsBusAccessFailed; -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+#define GLUE_FLAG_HALT BIT(0) -+#define GLUE_FLAG_INT BIT(1) -+#define GLUE_FLAG_OID BIT(2) -+#define GLUE_FLAG_TIMEOUT BIT(3) -+#define GLUE_FLAG_TXREQ BIT(4) -+#define GLUE_FLAG_SUB_MOD_INIT BIT(5) -+#define GLUE_FLAG_SUB_MOD_EXIT BIT(6) -+#define GLUE_FLAG_SUB_MOD_MULTICAST BIT(7) -+#define GLUE_FLAG_FRAME_FILTER BIT(8) -+#define GLUE_FLAG_FRAME_FILTER_AIS BIT(9) -+#define GLUE_FLAG_HIF_LOOPBK_AUTO BIT(10) -+#define GLUE_FLAG_HALT_BIT (0) -+#define GLUE_FLAG_INT_BIT (1) -+#define GLUE_FLAG_OID_BIT (2) -+#define GLUE_FLAG_TIMEOUT_BIT (3) -+#define GLUE_FLAG_TXREQ_BIT (4) -+#define GLUE_FLAG_SUB_MOD_INIT_BIT (5) -+#define GLUE_FLAG_SUB_MOD_EXIT_BIT (6) -+#define GLUE_FLAG_SUB_MOD_MULTICAST_BIT (7) -+#define GLUE_FLAG_FRAME_FILTER_BIT (8) -+#define GLUE_FLAG_FRAME_FILTER_AIS_BIT (9) -+#define GLUE_FLAG_HIF_LOOPBK_AUTO_BIT (10) -+ -+#define GLUE_BOW_KFIFO_DEPTH (1024) -+/* #define GLUE_BOW_DEVICE_NAME "MT6620 802.11 AMP" */ -+#define GLUE_BOW_DEVICE_NAME "ampc0" -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+typedef struct _GL_WPA_INFO_T { -+ UINT_32 u4WpaVersion; -+ UINT_32 u4KeyMgmt; -+ UINT_32 u4CipherGroup; -+ UINT_32 u4CipherPairwise; -+ UINT_32 u4AuthAlg; -+ BOOLEAN fgPrivacyInvoke; -+#if CFG_SUPPORT_802_11W -+ UINT_32 u4Mfp; -+#endif -+} GL_WPA_INFO_T, *P_GL_WPA_INFO_T; -+ -+typedef enum _ENUM_RSSI_TRIGGER_TYPE { -+ ENUM_RSSI_TRIGGER_NONE, -+ ENUM_RSSI_TRIGGER_GREATER, -+ ENUM_RSSI_TRIGGER_LESS, -+ ENUM_RSSI_TRIGGER_TRIGGERED, -+ ENUM_RSSI_TRIGGER_NUM -+} ENUM_RSSI_TRIGGER_TYPE; -+ -+#if CFG_ENABLE_WIFI_DIRECT -+typedef enum _ENUM_SUB_MODULE_IDX_T { -+ P2P_MODULE = 0, -+ SUB_MODULE_NUM -+} ENUM_SUB_MODULE_IDX_T; -+ -+typedef enum _ENUM_NET_REG_STATE_T { -+ ENUM_NET_REG_STATE_UNREGISTERED, -+ ENUM_NET_REG_STATE_REGISTERING, -+ ENUM_NET_REG_STATE_REGISTERED, -+ ENUM_NET_REG_STATE_UNREGISTERING, -+ ENUM_NET_REG_STATE_NUM -+} ENUM_NET_REG_STATE_T; -+ -+#endif -+ -+typedef struct _GL_IO_REQ_T { -+ QUE_ENTRY_T rQueEntry; -+ /* wait_queue_head_t cmdwait_q; */ -+ BOOLEAN fgRead; -+ BOOLEAN fgWaitResp; -+#if CFG_ENABLE_WIFI_DIRECT -+ BOOLEAN fgIsP2pOid; -+#endif -+ P_ADAPTER_T prAdapter; -+ PFN_OID_HANDLER_FUNC pfnOidHandler; -+ PVOID pvInfoBuf; -+ UINT_32 u4InfoBufLen; -+ PUINT_32 pu4QryInfoLen; -+ WLAN_STATUS rStatus; -+ UINT_32 u4Flag; -+} GL_IO_REQ_T, *P_GL_IO_REQ_T; -+ -+#if CFG_ENABLE_BT_OVER_WIFI -+typedef struct _GL_BOW_INFO { -+ BOOLEAN fgIsRegistered; -+ dev_t u4DeviceNumber; /* dynamic device number */ -+/* struct kfifo *prKfifo; */ /* for buffering indicated events */ -+ struct kfifo rKfifo; /* for buffering indicated events */ -+ spinlock_t rSpinLock; /* spin lock for kfifo */ -+ struct cdev cdev; -+ UINT_32 u4FreqInKHz; /* frequency */ -+ -+ UINT_8 aucRole[CFG_BOW_PHYSICAL_LINK_NUM]; /* 0: Responder, 1: Initiator */ -+ ENUM_BOW_DEVICE_STATE aeState[CFG_BOW_PHYSICAL_LINK_NUM]; -+ PARAM_MAC_ADDRESS arPeerAddr[CFG_BOW_PHYSICAL_LINK_NUM]; -+ -+ wait_queue_head_t outq; -+ -+#if CFG_BOW_SEPARATE_DATA_PATH -+ /* Device handle */ -+ struct net_device *prDevHandler; -+ BOOLEAN fgIsNetRegistered; -+#endif -+ -+} GL_BOW_INFO, *P_GL_BOW_INFO; -+#endif -+ -+#if (CFG_SUPPORT_TDLS == 1) -+typedef struct _TDLS_INFO_LINK_T { -+ /* start time when link is built, end time when link is broken */ -+ unsigned long jiffies_start, jiffies_end; -+ -+ /* the peer MAC */ -+ UINT8 aucPeerMac[6]; -+ -+ /* broken reason */ -+ UINT8 ucReasonCode; -+ -+ /* TRUE: torn down is triggerred by us */ -+ UINT8 fgIsFromUs; -+ -+ /* duplicate count; same reason */ -+ UINT8 ucDupCount; -+ -+ /* HT capability */ -+#define TDLS_INFO_LINK_HT_CAP_SUP 0x01 -+ UINT8 ucHtCap; -+#define TDLS_INFO_LINK_HT_BA_SETUP 0x01 -+#define TDLS_INFO_LINK_HT_BA_SETUP_OK 0x02 -+#define TDLS_INFO_LINK_HT_BA_SETUP_DECLINE 0x04 -+#define TDLS_INFO_LINK_HT_BA_PEER 0x10 -+#define TDLS_INFO_LINK_HT_BA_RSP_OK 0x20 -+#define TDLS_INFO_LINK_HT_BA_RSP_DECLINE 0x40 -+ UINT8 ucHtBa[8]; /* TID0 ~ TID7 */ -+} TDLS_INFO_LINK_T; -+ -+typedef struct _TDLS_INFO_T { -+ /* link history */ -+#define TDLS_LINK_HISTORY_MAX 30 -+ TDLS_INFO_LINK_T rLinkHistory[TDLS_LINK_HISTORY_MAX]; -+ UINT32 u4LinkIdx; -+ -+ /* TRUE: support 20/40 bandwidth in TDLS link */ -+ BOOLEAN fgIs2040Sup; -+ -+ /* total TDLS link count */ -+ INT8 cLinkCnt; -+} TDLS_INFO_T; -+#endif /* CFG_SUPPORT_TDLS */ -+ -+/* -+* type definition of pointer to p2p structure -+*/ -+typedef struct _GL_P2P_INFO_T GL_P2P_INFO_T, *P_GL_P2P_INFO_T; -+ -+struct _GLUE_INFO_T { -+ /* Device handle */ -+ struct net_device *prDevHandler; -+ -+ /* Device Index(index of arWlanDevInfo[]) */ -+ INT_32 i4DevIdx; -+ -+ /* Device statistics */ -+ struct net_device_stats rNetDevStats; -+ -+ /* Wireless statistics struct net_device */ -+ struct iw_statistics rIwStats; -+ -+ /* spinlock to sync power save mechanism */ -+ spinlock_t rSpinLock[SPIN_LOCK_NUM]; -+ -+ /* semaphore for ioctl */ -+ struct semaphore ioctl_sem; -+ -+ UINT_64 u8Cookie; -+ -+ ULONG ulFlag; /* GLUE_FLAG_XXX */ -+ UINT_32 u4PendFlag; -+ /* UINT_32 u4TimeoutFlag; */ -+ UINT_32 u4OidCompleteFlag; -+ UINT_32 u4ReadyFlag; /* check if card is ready */ -+ -+ UINT_32 u4OsMgmtFrameFilter; -+ -+ /* Number of pending frames, also used for debuging if any frame is -+ * missing during the process of unloading Driver. -+ * -+ * NOTE(Kevin): In Linux, we also use this variable as the threshold -+ * for manipulating the netif_stop(wake)_queue() func. -+ */ -+ INT_32 ai4TxPendingFrameNumPerQueue[4][CFG_MAX_TXQ_NUM]; -+ INT_32 i4TxPendingFrameNum; -+ INT_32 i4TxPendingSecurityFrameNum; -+ -+ /* current IO request for kalIoctl */ -+ GL_IO_REQ_T OidEntry; -+ -+ /* registry info */ -+ REG_INFO_T rRegInfo; -+ -+ /* firmware */ -+ struct firmware *prFw; -+ -+ /* Host interface related information */ -+ /* defined in related hif header file */ -+ GL_HIF_INFO_T rHifInfo; -+ -+ /*! \brief wext wpa related information */ -+ GL_WPA_INFO_T rWpaInfo; -+ -+ /* Pointer to ADAPTER_T - main data structure of internal protocol stack */ -+ P_ADAPTER_T prAdapter; -+ -+#ifdef WLAN_INCLUDE_PROC -+ struct proc_dir_entry *pProcRoot; -+#endif /* WLAN_INCLUDE_PROC */ -+ -+ /* Indicated media state */ -+ ENUM_PARAM_MEDIA_STATE_T eParamMediaStateIndicated; -+ -+ /* Device power state D0~D3 */ -+ PARAM_DEVICE_POWER_STATE ePowerState; -+ -+ struct completion rScanComp; /* indicate scan complete */ -+ struct completion rHaltComp; /* indicate main thread halt complete */ -+ struct completion rPendComp; /* indicate main thread halt complete */ -+#if CFG_ENABLE_WIFI_DIRECT -+ struct completion rSubModComp; /*indicate sub module init or exit complete */ -+#endif -+ WLAN_STATUS rPendStatus; -+ -+ QUE_T rTxQueue; -+ -+ /* OID related */ -+ QUE_T rCmdQueue; -+ /* PVOID pvInformationBuffer; */ -+ /* UINT_32 u4InformationBufferLength; */ -+ /* PVOID pvOidEntry; */ -+ /* PUINT_8 pucIOReqBuff; */ -+ /* QUE_T rIOReqQueue; */ -+ /* QUE_T rFreeIOReqQueue; */ -+ -+ wait_queue_head_t waitq; -+ struct task_struct *main_thread; -+ -+ struct timer_list tickfn; -+ -+#if CFG_SUPPORT_EXT_CONFIG -+ UINT_16 au2ExtCfg[256]; /* NVRAM data buffer */ -+ UINT_32 u4ExtCfgLength; /* 0 means data is NOT valid */ -+#endif -+ -+#if 1 /* CFG_SUPPORT_WAPI */ -+ /* Should be large than the PARAM_WAPI_ASSOC_INFO_T */ -+ UINT_8 aucWapiAssocInfoIEs[42]; -+ UINT_16 u2WapiAssocInfoIESz; -+#endif -+ -+#if CFG_ENABLE_BT_OVER_WIFI -+ GL_BOW_INFO rBowInfo; -+#endif -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ P_GL_P2P_INFO_T prP2PInfo; -+#if CFG_SUPPORT_P2P_RSSI_QUERY -+ /* Wireless statistics struct net_device */ -+ struct iw_statistics rP2pIwStats; -+#endif -+#endif -+ BOOLEAN fgWpsActive; -+ UINT_8 aucWSCIE[500]; /*for probe req */ -+ UINT_16 u2WSCIELen; -+ UINT_8 aucWSCAssocInfoIE[200]; /*for Assoc req */ -+ UINT_16 u2WSCAssocInfoIELen; -+ -+#if CFG_SUPPORT_HOTSPOT_2_0 -+ UINT_8 aucHS20AssocInfoIE[200]; /*for Assoc req */ -+ UINT_16 u2HS20AssocInfoIELen; -+ UINT_8 ucHotspotConfig; -+ BOOLEAN fgConnectHS20AP; -+#endif -+ -+ /* NVRAM availability */ -+ BOOLEAN fgNvramAvailable; -+ -+ BOOLEAN fgMcrAccessAllowed; -+ -+ /* MAC Address Overridden by IOCTL */ -+ BOOLEAN fgIsMacAddrOverride; -+ PARAM_MAC_ADDRESS rMacAddrOverride; -+ -+ SET_TXPWR_CTRL_T rTxPwr; -+ -+ /* for cfg80211 scan done indication */ -+ struct cfg80211_scan_request *prScanRequest; -+ -+ /* for cfg80211 scheduled scan */ -+ struct cfg80211_sched_scan_request *prSchedScanRequest; -+ -+ /* to indicate registered or not */ -+ BOOLEAN fgIsRegistered; -+ -+ /* for cfg80211 connected indication */ -+ UINT_32 u4RspIeLength; -+ UINT_8 aucRspIe[CFG_CFG80211_IE_BUF_LEN]; -+ -+ UINT_32 u4ReqIeLength; -+ UINT_8 aucReqIe[CFG_CFG80211_IE_BUF_LEN]; -+ -+ KAL_WAKE_LOCK_T rAhbIsrWakeLock; -+ -+#if CFG_SUPPORT_HOTSPOT_2_0 -+ BOOLEAN fgIsDad; -+ UINT_8 aucDADipv4[4]; -+ BOOLEAN fgIs6Dad; -+ UINT_8 aucDADipv6[16]; -+#endif -+#if (CFG_SUPPORT_MET_PROFILING == 1) -+ UINT_8 u8MetProfEnable; -+ INT_16 u16MetUdpPort; -+#endif -+ BOOLEAN fgPoorlinkValid; -+ UINT_64 u8Statistic[2]; -+ UINT_64 u8TotalFailCnt; -+ UINT_32 u4LinkspeedThreshold; -+ INT_32 i4RssiThreshold; -+ INT_32 i4RssiCache; -+ UINT_32 u4LinkSpeedCache; -+ -+#if (CFG_SUPPORT_TDLS == 1) -+ TDLS_INFO_T rTdlsLink; -+ -+ UINT8 aucTdlsHtPeerMac[6]; -+ IE_HT_CAP_T rTdlsHtCap; /* temp to queue HT capability element */ -+ -+ /* -+ [0~7]: jiffies -+ [8~13]: Peer MAC -+ [14]: Reason Code -+ [15]: From us or peer -+ [16]: Duplicate Count -+ */ -+/* UINT8 aucTdlsDisconHistory[TDLS_DISCON_HISTORY_MAX][20]; */ -+/* UINT32 u4TdlsDisconIdx; */ -+#endif /* CFG_SUPPORT_TDLS */ -+ UINT_32 IsrCnt; -+ UINT_32 IsrPassCnt; -+ UINT_32 TaskIsrCnt; -+ -+ UINT_32 IsrPreCnt; -+ UINT_32 IsrPrePassCnt; -+ UINT_32 TaskPreIsrCnt; -+ -+ UINT_32 IsrAbnormalCnt; -+ UINT_32 IsrSoftWareCnt; -+ UINT_32 IsrTxCnt; -+ UINT_32 IsrRxCnt; -+ UINT_64 u8SkbToDriver; -+ UINT_64 u8SkbFreed; -+}; -+ -+typedef irqreturn_t(*PFN_WLANISR) (int irq, void *dev_id, struct pt_regs *regs); -+ -+typedef void (*PFN_LINUX_TIMER_FUNC) (unsigned long); -+ -+/* generic sub module init/exit handler -+* now, we only have one sub module, p2p -+*/ -+#if CFG_ENABLE_WIFI_DIRECT -+typedef BOOLEAN(*SUB_MODULE_INIT) (P_GLUE_INFO_T prGlueInfo); -+typedef BOOLEAN(*SUB_MODULE_EXIT) (P_GLUE_INFO_T prGlueInfo); -+ -+typedef struct _SUB_MODULE_HANDLER { -+ SUB_MODULE_INIT subModInit; -+ SUB_MODULE_EXIT subModExit; -+ BOOLEAN fgIsInited; -+} SUB_MODULE_HANDLER, *P_SUB_MODULE_HANDLER; -+ -+#endif -+ -+ -+#ifdef CONFIG_NL80211_TESTMODE -+enum TestModeCmdType { -+ /* old test mode command id, compatible with exist testmode command */ -+ TESTMODE_CMD_ID_SW_CMD = 1, -+ TESTMODE_CMD_ID_WAPI = 2, -+ TESTMODE_CMD_ID_HS20 = 3, -+ TESTMODE_CMD_ID_POORLINK = 4, -+ TESTMODE_CMD_ID_STATISTICS = 0x10, -+ TESTMODE_CMD_ID_LINK_DETECT = 0x20, -+ /* old test mode command id, compatible with exist testmode command */ -+ -+ /* all new added test mode command should great than TESTMODE_CMD_ID_NEW_BEGIN */ -+ TESTMODE_CMD_ID_NEW_BEGIN = 100, -+ TESTMODE_CMD_ID_SUSPEND = 101, -+}; -+#if CFG_SUPPORT_HOTSPOT_2_0 -+enum Hs20CmdType { -+ HS20_CMD_ID_SET_BSSID_POOL = 0, -+ NUM_OF_HS20_CMD_ID -+}; -+#endif -+ -+typedef struct _NL80211_DRIVER_TEST_MODE_PARAMS { -+ UINT_32 index; -+ UINT_32 buflen; -+} NL80211_DRIVER_TEST_MODE_PARAMS, *P_NL80211_DRIVER_TEST_MODE_PARAMS; -+ -+/*SW CMD */ -+typedef struct _NL80211_DRIVER_SW_CMD_PARAMS { -+ NL80211_DRIVER_TEST_MODE_PARAMS hdr; -+ UINT_8 set; -+ UINT_32 adr; -+ UINT_32 data; -+} NL80211_DRIVER_SW_CMD_PARAMS, *P_NL80211_DRIVER_SW_CMD_PARAMS; -+ -+typedef struct _NL80211_DRIVER_SUSPEND_PARAMS { -+ NL80211_DRIVER_TEST_MODE_PARAMS hdr; -+ UINT_8 suspend; -+} NL80211_DRIVER_SUSPEND_PARAMS, *P_NL80211_DRIVER_SUSPEND_PARAMS; -+struct iw_encode_exts { -+ __u32 ext_flags; /*!< IW_ENCODE_EXT_* */ -+ __u8 tx_seq[IW_ENCODE_SEQ_MAX_SIZE]; /*!< LSB first */ -+ __u8 rx_seq[IW_ENCODE_SEQ_MAX_SIZE]; /*!< LSB first */ -+ __u8 addr[MAC_ADDR_LEN]; /*!< ff:ff:ff:ff:ff:ff for broadcast/multicast -+ * (group) keys or unicast address for -+ * individual keys */ -+ __u16 alg; /*!< IW_ENCODE_ALG_* */ -+ __u16 key_len; -+ __u8 key[32]; -+}; -+ -+/*SET KEY EXT */ -+typedef struct _NL80211_DRIVER_SET_KEY_EXTS { -+ NL80211_DRIVER_TEST_MODE_PARAMS hdr; -+ UINT_8 key_index; -+ UINT_8 key_len; -+ struct iw_encode_exts ext; -+} NL80211_DRIVER_SET_KEY_EXTS, *P_NL80211_DRIVER_SET_KEY_EXTS; -+ -+#if CFG_SUPPORT_HOTSPOT_2_0 -+ -+struct param_hs20_set_bssid_pool { -+ u8 fgBssidPoolIsEnable; -+ u8 ucNumBssidPool; -+ u8 arBssidPool[8][ETH_ALEN]; -+}; -+ -+struct wpa_driver_hs20_data_s { -+ NL80211_DRIVER_TEST_MODE_PARAMS hdr; -+ enum Hs20CmdType CmdType; -+ struct param_hs20_set_bssid_pool hs20_set_bssid_pool; -+}; -+ -+#endif /* CFG_SUPPORT_HOTSPOT_2_0 */ -+ -+#endif -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+/*----------------------------------------------------------------------------*/ -+/* Macros of SPIN LOCK operations for using in Glue Layer */ -+/*----------------------------------------------------------------------------*/ -+#if CFG_USE_SPIN_LOCK_BOTTOM_HALF -+#define GLUE_SPIN_LOCK_DECLARATION() -+#define GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, rLockCategory) \ -+ { \ -+ if (rLockCategory < SPIN_LOCK_NUM) \ -+ spin_lock_bh(&(prGlueInfo->rSpinLock[rLockCategory])); \ -+ } -+#define GLUE_RELEASE_SPIN_LOCK(prGlueInfo, rLockCategory) \ -+ { \ -+ if (rLockCategory < SPIN_LOCK_NUM) \ -+ spin_unlock_bh(&(prGlueInfo->rSpinLock[rLockCategory])); \ -+ } -+#define GLUE_ACQUIRE_THE_SPIN_LOCK(prLock) \ -+ spin_lock_bh(prLock) -+#define GLUE_RELEASE_THE_SPIN_LOCK(prLock) \ -+ spin_unlock_bh(prLock) -+ -+#else /* !CFG_USE_SPIN_LOCK_BOTTOM_HALF */ -+#define GLUE_SPIN_LOCK_DECLARATION() unsigned long __u4Flags = 0 -+#define GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, rLockCategory) \ -+ { \ -+ if (rLockCategory < SPIN_LOCK_NUM) \ -+ spin_lock_irqsave(&(prGlueInfo)->rSpinLock[rLockCategory], __u4Flags); \ -+ } -+#define GLUE_RELEASE_SPIN_LOCK(prGlueInfo, rLockCategory) \ -+ { \ -+ if (rLockCategory < SPIN_LOCK_NUM) \ -+ spin_unlock_irqrestore(&(prGlueInfo->rSpinLock[rLockCategory]), __u4Flags); \ -+ } -+#define GLUE_ACQUIRE_THE_SPIN_LOCK(prLock) \ -+ spin_lock_irqsave(prLock, __u4Flags) -+#define GLUE_RELEASE_THE_SPIN_LOCK(prLock) \ -+ spin_unlock_irqrestore(prLock, __u4Flags) -+#endif /* !CFG_USE_SPIN_LOCK_BOTTOM_HALF */ -+ -+/*----------------------------------------------------------------------------*/ -+/* Macros for accessing Reserved Fields of native packet */ -+/*----------------------------------------------------------------------------*/ -+#define GLUE_CB_OFFSET 4 /* For 64-bit platform, avoiding that the cb -+ isoverwrited by "(prQueueEntry)->prNext = -+ (P_QUE_ENTRY_T)NULL;" in QUEUE_INSERT_TAIL */ -+#define GLUE_GET_PKT_QUEUE_ENTRY(_p) \ -+ (&(((struct sk_buff *)(_p))->cb[0])) -+ -+#define GLUE_GET_PKT_DESCRIPTOR(_prQueueEntry) \ -+ ((P_NATIVE_PACKET) ((ULONG)_prQueueEntry - offsetof(struct sk_buff, cb[0]))) -+ -+#define GLUE_SET_PKT_FLAG_802_11(_p) \ -+ (*((PUINT_8)&(((struct sk_buff *)(_p))->cb[GLUE_CB_OFFSET+4])) |= BIT(7)) -+ -+#define GLUE_SET_PKT_FLAG_1X(_p) \ -+ (*((PUINT_8)&(((struct sk_buff *)(_p))->cb[GLUE_CB_OFFSET+4])) |= BIT(6)) -+ -+#define GLUE_SET_PKT_FLAG_PAL(_p) \ -+ (*((PUINT_8)&(((struct sk_buff *)(_p))->cb[GLUE_CB_OFFSET+4])) |= BIT(5)) -+ -+#define GLUE_SET_PKT_FLAG_P2P(_p) \ -+ (*((PUINT_8)&(((struct sk_buff *)(_p))->cb[GLUE_CB_OFFSET+4])) |= BIT(4)) -+ -+#define GLUE_SET_PKT_TID(_p, _tid) \ -+ (*((PUINT_8)&(((struct sk_buff *)(_p))->cb[GLUE_CB_OFFSET+4])) |= (((UINT_8)((_tid) & (BITS(0, 3)))))) -+ -+#define GLUE_SET_PKT_FRAME_LEN(_p, _u2PayloadLen) \ -+ (*((PUINT_16)&(((struct sk_buff *)(_p))->cb[GLUE_CB_OFFSET+6])) = (UINT_16)(_u2PayloadLen)) -+ -+#define GLUE_GET_PKT_FRAME_LEN(_p) \ -+ (*((PUINT_16)&(((struct sk_buff *)(_p))->cb[GLUE_CB_OFFSET+6]))) -+ -+#define GLUE_GET_PKT_IS_802_11(_p) \ -+ ((*((PUINT_8)&(((struct sk_buff *)(_p))->cb[GLUE_CB_OFFSET+4]))) & (BIT(7))) -+ -+#define GLUE_GET_PKT_IS_1X(_p) \ -+ ((*((PUINT_8)&(((struct sk_buff *)(_p))->cb[GLUE_CB_OFFSET+4]))) & (BIT(6))) -+ -+#define GLUE_GET_PKT_TID(_p) \ -+ ((*((PUINT_8)&(((struct sk_buff *)(_p))->cb[GLUE_CB_OFFSET+4]))) & (BITS(0, 3))) -+ -+#define GLUE_GET_PKT_IS_PAL(_p) \ -+ ((*((PUINT_8)&(((struct sk_buff *)(_p))->cb[GLUE_CB_OFFSET+4]))) & (BIT(5))) -+ -+#define GLUE_GET_PKT_IS_P2P(_p) \ -+ ((*((PUINT_8)&(((struct sk_buff *)(_p))->cb[GLUE_CB_OFFSET+4]))) & (BIT(4))) -+ -+#define GLUE_SET_PKT_HEADER_LEN(_p, _ucMacHeaderLen) \ -+ (*((PUINT_8)&(((struct sk_buff *)(_p))->cb[GLUE_CB_OFFSET+5])) = (UINT_8)(_ucMacHeaderLen)) -+ -+#define GLUE_GET_PKT_HEADER_LEN(_p) \ -+ (*((PUINT_8)&(((struct sk_buff *)(_p))->cb[GLUE_CB_OFFSET+5]))) -+ -+#define GLUE_SET_PKT_ARRIVAL_TIME(_p, _rSysTime) \ -+ (*((POS_SYSTIME)&(((struct sk_buff *)(_p))->cb[GLUE_CB_OFFSET+8])) = (OS_SYSTIME)(_rSysTime)) -+ -+#define GLUE_GET_PKT_ARRIVAL_TIME(_p) \ -+ (*((POS_SYSTIME)&(((struct sk_buff *)(_p))->cb[GLUE_CB_OFFSET+8]))) -+ -+#define GLUE_SET_PKT_XTIME(_p, _rSysTime) \ -+ (*((UINT_64 *)&(((struct sk_buff *)(_p))->cb[GLUE_CB_OFFSET+16])) = (UINT_64)(_rSysTime)) -+ -+#define GLUE_GET_PKT_XTIME(_p) \ -+ (*((UINT_64 *)&(((struct sk_buff *)(_p))->cb[GLUE_CB_OFFSET+16]))) -+ -+/* Check validity of prDev, private data, and pointers */ -+#define GLUE_CHK_DEV(prDev) \ -+ ((prDev && *((P_GLUE_INFO_T *) netdev_priv(prDev))) ? TRUE : FALSE) -+ -+#define GLUE_CHK_PR2(prDev, pr2) \ -+ ((GLUE_CHK_DEV(prDev) && pr2) ? TRUE : FALSE) -+ -+#define GLUE_CHK_PR3(prDev, pr2, pr3) \ -+ ((GLUE_CHK_PR2(prDev, pr2) && pr3) ? TRUE : FALSE) -+ -+#define GLUE_CHK_PR4(prDev, pr2, pr3, pr4) \ -+ ((GLUE_CHK_PR3(prDev, pr2, pr3) && pr4) ? TRUE : FALSE) -+ -+#define GLUE_SET_EVENT(pr) \ -+ kalSetEvent(pr) -+ -+#define GLUE_INC_REF_CNT(_refCount) atomic_inc((atomic_t *)&(_refCount)) -+#define GLUE_DEC_REF_CNT(_refCount) atomic_dec((atomic_t *)&(_refCount)) -+ -+#define DbgPrint(...) -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+#ifdef WLAN_INCLUDE_PROC -+INT_32 procRemoveProcfs(VOID); -+ -+INT_32 procCreateFsEntry(P_GLUE_INFO_T prGlueInfo); -+INT_32 procInitFs(VOID); -+INT_32 procUninitProcFs(VOID); -+ -+#endif /* WLAN_INCLUDE_PROC */ -+ -+#if CFG_ENABLE_BT_OVER_WIFI -+BOOLEAN glRegisterAmpc(P_GLUE_INFO_T prGlueInfo); -+ -+BOOLEAN glUnregisterAmpc(P_GLUE_INFO_T prGlueInfo); -+#endif -+ -+#if CFG_ENABLE_WIFI_DIRECT -+ -+VOID wlanSubModRunInit(P_GLUE_INFO_T prGlueInfo); -+ -+VOID wlanSubModRunExit(P_GLUE_INFO_T prGlueInfo); -+ -+BOOLEAN wlanSubModInit(P_GLUE_INFO_T prGlueInfo); -+ -+BOOLEAN wlanSubModExit(P_GLUE_INFO_T prGlueInfo); -+ -+VOID -+wlanSubModRegisterInitExit(SUB_MODULE_INIT rSubModInit, SUB_MODULE_EXIT rSubModExit, ENUM_SUB_MODULE_IDX_T eSubModIdx); -+ -+BOOLEAN wlanExportGlueInfo(P_GLUE_INFO_T *prGlueInfoExpAddr); -+ -+BOOLEAN wlanIsLaunched(VOID); -+ -+VOID wlanUpdateChannelTable(P_GLUE_INFO_T prGlueInfo); -+ -+#endif -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif /* _GL_OS_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_p2p_ioctl.h b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_p2p_ioctl.h -new file mode 100644 -index 000000000000..a27294e33500 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_p2p_ioctl.h -@@ -0,0 +1,743 @@ -+/* -+** Id: //Department/DaVinci/TRUNK/WiFi_P2P_Driver/os/linux/include/gl_p2p_ioctl.h#9 -+*/ -+ -+/*! \file gl_p2p_ioctl.h -+ \brief This file is for custom ioctls for Wi-Fi Direct only -+*/ -+ -+/* -+** Log: gl_p2p_ioctl.h -+** -+** 07 26 2012 yuche.tsai -+** [ALPS00324337] [ALPS.JB][Hot-Spot] Driver update for Hot-Spot -+** Update driver code of ALPS.JB for hot-spot. -+** -+** 07 19 2012 yuche.tsai -+** NULL -+** Code update for JB. -+ * -+ * 07 17 2012 yuche.tsai -+ * NULL -+ * Compile no error before trial run. -+ * -+ * 06 07 2011 yuche.tsai -+ * [WCXRP00000763] [Volunteer Patch][MT6620][Driver] RX Service Discovery Frame under AP mode Issue -+ * Fix RX SD request under AP mode issue. -+ * -+ * 03 25 2011 wh.su -+ * NULL -+ * Fix P2P IOCTL of multicast address bug, add low power driver stop control. -+ * -+ * 11 22 2011 yuche.tsai -+ * NULL -+ * Update RSSI link quality of P2P Network query method. (Bug fix) -+ * -+ * 11 19 2011 yuche.tsai -+ * NULL -+ * Add RSSI support for P2P network. -+ * -+ * 11 11 2011 yuche.tsai -+ * NULL -+ * Fix work thread cancel issue. -+ * -+ * 11 08 2011 yuche.tsai -+ * [WCXRP00001094] [Volunteer Patch][Driver] Driver version & supplicant version query & set support for service -+ * discovery version check. -+ * Add support for driver version query & p2p supplicant verseion set. -+ * For new service discovery mechanism sync. -+ * -+ * 10 25 2011 cm.chang -+ * [WCXRP00001058] [All Wi-Fi][Driver] Fix sta_rec's phyTypeSet and OBSS scan in AP mode -+ * . -+ * -+ * 10 18 2011 yuche.tsai -+ * [WCXRP00001045] [WiFi Direct][Driver] Check 2.1 branch. -+ * New 2.1 branch -+ -+ * -+ * 08 16 2011 chinglan.wang -+ * NULL -+ * Add the group id information in the invitation indication. -+ * -+ * 08 09 2011 yuche.tsai -+ * [WCXRP00000919] [Volunteer Patch][WiFi Direct][Driver] Invitation New Feature. -+ * Invitation Feature add on. -+ * -+ * 05 04 2011 chinglan.wang -+ * [WCXRP00000698] [MT6620 Wi-Fi][P2P][Driver] Add p2p invitation command for the p2p driver -+ * . -+ * -+ * 03 29 2011 wh.su -+ * [WCXRP00000095] [MT6620 Wi-Fi] [FW] Refine the P2P GO send broadcast protected code -+ * add the set power and get power function sample. -+ * -+ * 03 22 2011 george.huang -+ * [WCXRP00000504] [MT6620 Wi-Fi][FW] Support Sigma CAPI for power saving related command -+ * link with supplicant commands -+ * -+ * 03 07 2011 wh.su -+ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code -+ * rename the define to anti_pviracy. -+ * -+ * 03 02 2011 wh.su -+ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code -+ * Add Security check related code. -+ * -+ * 03 01 2011 wh.su -+ * [WCXRP00000488] [MT6620 Wi-Fi][Driver] Support the SIGMA set p2p parameter to driver -+ * fixed the ioctl sumcmd to meet the p2p_supplicant setting. -+ * -+ * 02 23 2011 wh.su -+ * [WCXRP00000488] [MT6620 Wi-Fi][Driver] Support the SIGMA set p2p parameter to driver -+ * adding the ioctl set int define for p2p parameter. -+ * -+ * 02 22 2011 wh.su -+ * [WCXRP00000488] [MT6620 Wi-Fi][Driver] Support the SIGMA set p2p parameter to driver -+ * adding the ioctl set int from supplicant, and can used to set the p2p parameters -+ * -+ * 02 17 2011 wh.su -+ * [WCXRP00000448] [MT6620 Wi-Fi][Driver] Fixed WSC IE not send out at probe request -+ * adjust the set wsc ie structure. -+ * -+ * 01 05 2011 cp.wu -+ * [WCXRP00000283] [MT6620 Wi-Fi][Driver][Wi-Fi Direct] Implementation of interface for supporting Wi-Fi Direct Service -+ * Discovery -+ * ioctl implementations for P2P Service Discovery -+ * -+ * 12 22 2010 cp.wu -+ * [WCXRP00000283] [MT6620 Wi-Fi][Driver][Wi-Fi Direct] Implementation of interface for supporting Wi-Fi Direct Service -+ * Discovery -+ * 1. header file restructure for more clear module isolation -+ * 2. add function interface definition for implementing Service Discovery callbacks -+ * -+ * 12 15 2010 cp.wu -+ * NULL -+ * invoke nicEnableInterrupt() before leaving from wlanAdapterStart() -+ * -+ * 12 07 2010 cp.wu -+ * [WCXRP00000237] [MT6620 Wi-Fi][Wi-Fi Direct][Driver] Add interface for supporting service discovery -+ * define a pair of i/o control for multiplexing layer -+ * -+ * 11 04 2010 wh.su -+ * [WCXRP00000164] [MT6620 Wi-Fi][Driver] Support the p2p random SSID -+ * adding the p2p random ssid support. -+ * -+ * 10 20 2010 wh.su -+ * [WCXRP00000124] [MT6620 Wi-Fi] [Driver] Support the dissolve P2P Group -+ * Add the code to support disconnect p2p group -+ * -+ * 09 21 2010 kevin.huang -+ * [WCXRP00000054] [MT6620 Wi-Fi][Driver] Restructure driver for second Interface -+ * Isolate P2P related function for Hardware Software Bundle -+ * -+ * 09 10 2010 george.huang -+ * NULL -+ * update iwpriv LP related -+ * -+ * 09 07 2010 wh.su -+ * NULL -+ * adding the code for beacon/probe req/ probe rsp wsc ie at p2p. -+ * -+ * 08 25 2010 cp.wu -+ * NULL -+ * add netdev_ops(NDO) for linux kernel 2.6.31 or greater -+ * -+ * 08 20 2010 yuche.tsai -+ * NULL -+ * Refine a function parameter name. -+ * -+ * 08 19 2010 cp.wu -+ * NULL -+ * add set mac address interface for further possibilities of wpa_supplicant overriding interface address. -+ * -+ * 08 16 2010 george.huang -+ * NULL -+ * add wext handlers to link P2P set PS profile/ network address function (TBD) -+ * -+ * 08 16 2010 cp.wu -+ * NULL -+ * revised implementation of Wi-Fi Direct io controls. -+ * -+ * 08 12 2010 cp.wu -+ * NULL -+ * follow-up with ioctl interface update for Wi-Fi Direct application -+ * -+ * 08 06 2010 cp.wu -+ * NULL -+ * driver hook modifications corresponding to ioctl interface change. -+ * -+ * 08 03 2010 cp.wu -+ * NULL -+ * [Wi-Fi Direct] add framework for driver hooks -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 06 01 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * add ioctl to configure scan mode for p2p connection -+ * -+ * 05 31 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * add cfg80211 interface, which is to replace WE, for further extension -+ * -+ * 05 17 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * implement get scan result. -+ * -+ * 05 14 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * implement wireless extension ioctls in iw_handler form. -+ * -+ * 05 14 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * add ioctl framework for Wi-Fi Direct by reusing wireless extension ioctls as well -+ * -+ * 05 11 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * p2p ioctls revised. -+ * -+ * 05 11 2010 cp.wu -+ * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support -+ * add ioctl for controlling p2p scan phase parameters -+ * -+*/ -+ -+#ifndef _GL_P2P_IOCTL_H -+#define _GL_P2P_IOCTL_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include -+#include -+#include -+#if CFG_ENABLE_WIFI_DIRECT_CFG_80211 -+#include -+#include -+#endif -+ -+#include "wlan_oid.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+/* Device private ioctl calls */ -+/* #define SIOCDEVPRIVATE 0x89F0*/ -+#define IOC_GET_PRIVATE_IOCTL_CMD (SIOCDEVPRIVATE+1) -+ -+/* (WirelessExtension) Private I/O Controls */ -+#define IOC_P2P_CFG_DEVICE (SIOCIWFIRSTPRIV+0) -+#define IOC_P2P_PROVISION_COMPLETE (SIOCIWFIRSTPRIV+2) -+#define IOC_P2P_START_STOP_DISCOVERY (SIOCIWFIRSTPRIV+4) -+#define IOC_P2P_DISCOVERY_RESULTS (SIOCIWFIRSTPRIV+5) -+#define IOC_P2P_WSC_BEACON_PROBE_RSP_IE (SIOCIWFIRSTPRIV+6) -+#define IOC_P2P_GO_WSC_IE IOC_P2P_WSC_BEACON_PROBE_RSP_IE -+#define IOC_P2P_CONNECT_DISCONNECT (SIOCIWFIRSTPRIV+8) -+#define IOC_P2P_PASSWORD_READY (SIOCIWFIRSTPRIV+10) -+/* #define IOC_P2P_SET_PWR_MGMT_PARAM (SIOCIWFIRSTPRIV+12) */ -+#define IOC_P2P_SET_INT (SIOCIWFIRSTPRIV+12) -+#define IOC_P2P_GET_STRUCT (SIOCIWFIRSTPRIV+13) -+#define IOC_P2P_SET_STRUCT (SIOCIWFIRSTPRIV+14) -+#define IOC_P2P_GET_REQ_DEVICE_INFO (SIOCIWFIRSTPRIV+15) -+ -+#define PRIV_CMD_INT_P2P_SET 0 -+ -+/* IOC_P2P_PROVISION_COMPLETE (iw_point . flags) */ -+#define P2P_PROVISIONING_SUCCESS 0 -+#define P2P_PROVISIONING_FAIL 1 -+ -+/* IOC_P2P_START_STOP_DISCOVERY (iw_point . flags) */ -+#define P2P_STOP_DISCOVERY 0 -+#define P2P_START_DISCOVERY 1 -+ -+/* IOC_P2P_CONNECT_DISCONNECT (iw_point . flags) */ -+#define P2P_CONNECT 0 -+#define P2P_DISCONNECT 1 -+ -+/* IOC_P2P_START_STOP_DISCOVERY (scan_type) */ -+#define P2P_SCAN_FULL_AND_FIND 0 -+#define P2P_SCAN_FULL 1 -+#define P2P_SCAN_SEARCH_AND_LISTEN 2 -+#define P2P_LISTEN 3 -+ -+/* IOC_P2P_GET_STRUCT/IOC_P2P_SET_STRUCT */ -+#define P2P_SEND_SD_RESPONSE 0 -+#define P2P_GET_SD_REQUEST 1 -+#define P2P_SEND_SD_REQUEST 2 -+#define P2P_GET_SD_RESPONSE 3 -+#define P2P_TERMINATE_SD_PHASE 4 -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+/*----------------------------------------------------------------------------*/ -+/* Wireless Extension: Private I/O Control */ -+/*----------------------------------------------------------------------------*/ -+typedef struct iw_p2p_cfg_device_type { -+ void __user *ssid; -+ UINT_8 ssid_len; -+ UINT_8 pri_device_type[8]; -+ UINT_8 snd_device_type[8]; -+ void __user *device_name; -+ UINT_8 device_name_len; -+ UINT_8 intend; -+ UINT_8 persistence; -+ UINT_8 sec_mode; -+ UINT_8 ch; -+ UINT_8 ch_width; /* 0: 20 Mhz 1:20/40 Mhz auto */ -+ UINT_8 max_scb; -+} IW_P2P_CFG_DEVICE_TYPE, *P_IW_P2P_CFG_DEVICE_TYPE; -+ -+typedef struct iw_p2p_hostapd_param { -+ UINT_8 cmd; -+ UINT_8 rsv[3]; -+ UINT_8 sta_addr[6]; -+ void __user *data; -+ UINT_16 len; -+} IW_P2P_HOSTAPD_PARAM, *P_IW_P2P_HOSTAPD_PARAM; -+ -+typedef struct iw_p2p_req_device_type { -+ UINT_8 scan_type; /* 0: Full scan + Find -+ * 1: Full scan -+ * 2: Scan (Search +Listen) -+ * 3: Listen -+ * other : reserved -+ */ -+ UINT_8 pri_device_type[8]; -+ void __user *probe_req_ie; -+ UINT_16 probe_req_len; -+ void __user *probe_rsp_ie; -+ UINT_16 probe_rsp_len; -+} IW_P2P_REQ_DEVICE_TYPE, *P_IW_P2P_REQ_DEVICE_TYPE; -+ -+typedef struct iw_p2p_connect_device { -+ UINT_8 sta_addr[6]; -+ UINT_8 p2pRole; /* 0: P2P Device, 1:GC, 2: GO */ -+ UINT_8 needProvision; /* 0: Don't needed provision, 1: doing the wsc provision first */ -+ UINT_8 authPeer; /* 1: auth peer invitation request */ -+ UINT_8 intend_config_method; /* Request Peer Device used config method */ -+} IW_P2P_CONNECT_DEVICE, *P_IW_P2P_CONNECT_DEVICE; -+ -+typedef struct iw_p2p_password_ready { -+ UINT_8 active_config_method; -+ void __user *probe_req_ie; -+ UINT_16 probe_req_len; -+ void __user *probe_rsp_ie; -+ UINT_16 probe_rsp_len; -+} IW_P2P_PASSWORD_READY, *P_IW_P2P_PASSWORD_READY; -+ -+typedef struct iw_p2p_device_req { -+ UINT_8 name[33]; -+ UINT_32 name_len; -+ UINT_8 device_addr[6]; -+ UINT_8 device_type; -+ INT_32 config_method; -+ INT_32 active_config_method; -+} IW_P2P_DEVICE_REQ, *P_IW_P2P_DEVICE_REQ; -+ -+typedef struct iw_p2p_transport_struct { -+ UINT_32 u4CmdId; -+ UINT_32 inBufferLength; -+ UINT_32 outBufferLength; -+ UINT_8 aucBuffer[16]; -+} IW_P2P_TRANSPORT_STRUCT, *P_IW_P2P_TRANSPORT_STRUCT; -+ -+/* For Invitation */ -+typedef struct iw_p2p_ioctl_invitation_struct { -+ UINT_8 aucDeviceID[6]; -+ UINT_8 aucGroupID[6]; /* BSSID */ -+ UINT_8 aucSsid[32]; -+ UINT_32 u4SsidLen; -+ UINT_8 ucReinvoke; -+} IW_P2P_IOCTL_INVITATION_STRUCT, *P_IW_P2P_IOCTL_INVITATION_STRUCT; -+ -+typedef struct iw_p2p_ioctl_abort_invitation { -+ UINT_8 dev_addr[6]; -+} IW_P2P_IOCTL_ABORT_INVITATION, *P_IW_P2P_IOCTL_ABORT_INVITATION; -+ -+typedef struct iw_p2p_ioctl_invitation_indicate { -+ UINT_8 dev_addr[6]; -+ UINT_8 group_bssid[6]; -+ INT_32 config_method; /* peer device supported config method */ -+ UINT_8 dev_name[32]; /* for reinvoke */ -+ UINT_32 name_len; -+ UINT_8 operating_channel; /* for re-invoke, target operating channel */ -+ UINT_8 invitation_type; /* invitation or re-invoke */ -+} IW_P2P_IOCTL_INVITATION_INDICATE, *P_IW_P2P_IOCTL_INVITATION_INDICATE; -+ -+typedef struct iw_p2p_ioctl_invitation_status { -+ UINT_32 status_code; -+} IW_P2P_IOCTL_INVITATION_STATUS, *P_IW_P2P_IOCTL_INVITATION_STATUS; -+ -+/* For Formation */ -+typedef struct iw_p2p_ioctl_start_formation { -+ UINT_8 dev_addr[6]; /* bssid */ -+ UINT_8 role; /* 0: P2P Device, 1:GC, 2: GO */ -+ UINT_8 needProvision; /* 0: Don't needed provision, 1: doing the wsc provision first */ -+ UINT_8 auth; /* 1: auth peer invitation request */ -+ UINT_8 config_method; /* Request Peer Device used config method */ -+} IW_P2P_IOCTL_START_FORMATION, *P_IW_P2P_IOCTL_START_FORMATION; -+ -+/* SET_STRUCT / GET_STRUCT */ -+typedef enum _ENUM_P2P_CMD_ID_T { -+ P2P_CMD_ID_SEND_SD_RESPONSE = 0, /* 0x00 (Set) */ -+ P2P_CMD_ID_GET_SD_REQUEST, /* 0x01 (Get) */ -+ P2P_CMD_ID_SEND_SD_REQUEST, /* 0x02 (Set) */ -+ P2P_CMD_ID_GET_SD_RESPONSE, /* 0x03 (Get) */ -+ P2P_CMD_ID_TERMINATE_SD_PHASE, /* 0x04 (Set) */ -+#if 1 /* CFG_SUPPORT_ANTI_PIRACY */ -+ P2P_CMD_ID_SEC_CHECK, /* 0x05(Set) */ -+#endif -+ P2P_CMD_ID_INVITATION, /* 0x06 (Set) */ -+ P2P_CMD_ID_INVITATION_INDICATE, /* 0x07 (Get) */ -+ P2P_CMD_ID_INVITATION_STATUS, /* 0x08 (Get) */ -+ P2P_CMD_ID_INVITATION_ABORT, /* 0x09 (Set) */ -+ P2P_CMD_ID_START_FORMATION, /* 0x0A (Set) */ -+ P2P_CMD_ID_P2P_VERSION, /* 0x0B (Set/Get) */ -+ P2P_CMD_ID_GET_CH_LIST = 12, /* 0x0C (Get) */ -+ P2P_CMD_ID_GET_OP_CH = 14 /* 0x0E (Get) */ -+} ENUM_P2P_CMD_ID_T, *P_ENUM_P2P_CMD_ID_T; -+ -+/* Service Discovery */ -+typedef struct iw_p2p_cmd_send_sd_response { -+ PARAM_MAC_ADDRESS rReceiverAddr; -+ UINT_8 fgNeedTxDoneIndication; -+ UINT_8 ucSeqNum; -+ UINT_16 u2PacketLength; -+ UINT_8 aucPacketContent[0]; /*native 802.11 */ -+} IW_P2P_CMD_SEND_SD_RESPONSE, *P_IW_P2P_CMD_SEND_SD_RESPONSE; -+ -+typedef struct iw_p2p_cmd_get_sd_request { -+ PARAM_MAC_ADDRESS rTransmitterAddr; -+ UINT_16 u2PacketLength; -+ UINT_8 aucPacketContent[0]; /*native 802.11 */ -+} IW_P2P_CMD_GET_SD_REQUEST, *P_IW_P2P_CMD_GET_SD_REQUEST; -+ -+typedef struct iw_p2p_cmd_send_service_discovery_request { -+ PARAM_MAC_ADDRESS rReceiverAddr; -+ UINT_8 fgNeedTxDoneIndication; -+ UINT_8 ucSeqNum; -+ UINT_16 u2PacketLength; -+ UINT_8 aucPacketContent[0]; /*native 802.11 */ -+} IW_P2P_CMD_SEND_SD_REQUEST, *P_IW_P2P_CMD_SEND_SD_REQUEST; -+ -+typedef struct iw_p2p_cmd_get_sd_response { -+ PARAM_MAC_ADDRESS rTransmitterAddr; -+ UINT_16 u2PacketLength; -+ UINT_8 aucPacketContent[0]; /*native 802.11 */ -+} IW_P2P_CMD_GET_SD_RESPONSE, *P_IW_P2P_CMD_GET_SD_RESPONSE; -+ -+typedef struct iw_p2p_cmd_terminate_sd_phase { -+ PARAM_MAC_ADDRESS rPeerAddr; -+} IW_P2P_CMD_TERMINATE_SD_PHASE, *P_IW_P2P_CMD_TERMINATE_SD_PHASE; -+ -+typedef struct iw_p2p_version { -+ UINT_32 u4Version; -+} IW_P2P_VERSION, *P_IW_P2P_VERSION; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+#if CFG_ENABLE_WIFI_DIRECT_CFG_80211 -+extern struct ieee80211_supported_band mtk_band_2ghz; -+extern struct ieee80211_supported_band mtk_band_5ghz; -+extern UINT_32 mtk_cipher_suites[5]; -+#endif -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+#if CFG_ENABLE_WIFI_DIRECT_CFG_80211 -+int mtk_p2p_cfg80211_change_iface(struct wiphy *wiphy, -+ struct net_device *ndev, -+ enum nl80211_iftype type,/* u32 *flags,*/ struct vif_params *params); -+ -+int mtk_p2p_cfg80211_add_key(struct wiphy *wiphy, -+ struct net_device *ndev, -+ u8 key_index, bool pairwise, const u8 *mac_addr, struct key_params *params); -+ -+int mtk_p2p_cfg80211_get_key(struct wiphy *wiphy, -+ struct net_device *ndev, -+ u8 key_index, -+ bool pairwise, -+ const u8 *mac_addr, void *cookie, void (*callback) (void *cookie, struct key_params *) -+); -+ -+int mtk_p2p_cfg80211_del_key(struct wiphy *wiphy, -+ struct net_device *ndev, u8 key_index, bool pairwise, const u8 *mac_addr); -+ -+int -+mtk_p2p_cfg80211_set_default_key(struct wiphy *wiphy, -+ struct net_device *netdev, u8 key_index, bool unicast, bool multicast); -+ -+int mtk_p2p_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev, -+ const u8 *mac, struct station_info *sinfo); -+ -+int mtk_p2p_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed); -+ -+int mtk_p2p_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_connect_params *sme); -+ -+int mtk_p2p_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev, u16 reason_code); -+ -+int mtk_p2p_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_ibss_params *params); -+ -+int mtk_p2p_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev); -+ -+int mtk_p2p_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev, bool enabled, int timeout); -+ -+int mtk_p2p_cfg80211_change_bss(struct wiphy *wiphy, struct net_device *dev, struct bss_parameters *params); -+ -+int mtk_p2p_cfg80211_remain_on_channel(struct wiphy *wiphy, -+ struct wireless_dev *wdev, -+ struct ieee80211_channel *chan, unsigned int duration, u64 *cookie); -+ -+int mtk_p2p_cfg80211_scan(struct wiphy *wiphy, struct cfg80211_scan_request *request); -+ -+int mtk_p2p_cfg80211_cancel_remain_on_channel(struct wiphy *wiphy, struct wireless_dev *wdev, u64 cookie); -+ -+int mtk_p2p_cfg80211_set_txpower(struct wiphy *wiphy, -+ struct wireless_dev *wdev, enum nl80211_tx_power_setting type, int mbm); -+ -+int mtk_p2p_cfg80211_get_txpower(struct wiphy *wiphy, struct wireless_dev *wdev, int *dbm); -+ -+int mtk_p2p_cfg80211_deauth(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_deauth_request *req); -+ -+int mtk_p2p_cfg80211_disassoc(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_disassoc_request *req); -+ -+int mtk_p2p_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_ap_settings *settings); -+ -+int mtk_p2p_cfg80211_change_beacon(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_beacon_data *info); -+ -+int mtk_p2p_cfg80211_mgmt_tx(struct wiphy *wiphy, -+ struct wireless_dev *wdev, -+ struct cfg80211_mgmt_tx_params *params, -+ u64 *cookie); -+ -+int mtk_p2p_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *dev); -+ -+int mtk_p2p_cfg80211_del_station(struct wiphy *wiphy, struct net_device *dev, struct station_del_parameters *params); -+//int mtk_p2p_cfg80211_del_station(struct wiphy *wiphy, struct net_device *dev, const u8 *mac); -+ -+int mtk_p2p_cfg80211_set_channel(struct wiphy *wiphy, struct cfg80211_chan_def *chandef); -+ -+void mtk_p2p_cfg80211_mgmt_frame_register(struct wiphy *wiphy, struct wireless_dev *wdev, u16 frame_type, bool reg); -+ -+int -+mtk_p2p_cfg80211_set_bitrate_mask(IN struct wiphy *wiphy, -+ IN struct net_device *dev, -+ IN const u8 *peer, IN const struct cfg80211_bitrate_mask *mask); -+ -+#ifdef CONFIG_NL80211_TESTMODE -+int mtk_p2p_cfg80211_testmode_cmd(IN struct wiphy *wiphy, IN struct wireless_dev *wdev, IN void *data, IN int len); -+int mtk_p2p_cfg80211_testmode_p2p_sigma_pre_cmd(IN struct wiphy *wiphy, IN void *data, IN int len); -+int mtk_p2p_cfg80211_testmode_p2p_sigma_cmd(IN struct wiphy *wiphy, IN void *data, IN int len); -+ -+#if CFG_SUPPORT_WFD -+int mtk_p2p_cfg80211_testmode_wfd_update_cmd(IN struct wiphy *wiphy, IN void *data, IN int len); -+#endif -+ -+int mtk_p2p_cfg80211_testmode_hotspot_block_cmd(IN struct wiphy *wiphy, IN void *data, IN int len); -+#else -+#error "Please ENABLE kernel config (CONFIG_NL80211_TESTMODE) to support Wi-Fi Direct" -+#endif -+ -+#endif -+ -+/* I/O control handlers */ -+ -+int -+mtk_p2p_wext_get_priv(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); -+ -+int -+mtk_p2p_wext_reconnect(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); -+ -+int -+mtk_p2p_wext_set_auth(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); -+ -+int -+mtk_p2p_wext_set_key(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); -+ -+int -+mtk_p2p_wext_mlme_handler(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); -+ -+int -+mtk_p2p_wext_set_powermode(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); -+ -+int -+mtk_p2p_wext_get_powermode(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); -+ -+/* Private Wireless I/O Controls takes use of iw_handler */ -+int -+mtk_p2p_wext_set_local_dev_info(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); -+ -+int -+mtk_p2p_wext_set_provision_complete(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); -+ -+int -+mtk_p2p_wext_start_stop_discovery(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); -+ -+int -+mtk_p2p_wext_discovery_results(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); -+ -+int -+mtk_p2p_wext_wsc_ie(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); -+ -+int -+mtk_p2p_wext_connect_disconnect(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); -+ -+int -+mtk_p2p_wext_password_ready(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); -+ -+int -+mtk_p2p_wext_request_dev_info(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); -+ -+int -+mtk_p2p_wext_invitation_indicate(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); -+ -+int -+mtk_p2p_wext_invitation_status(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); -+ -+int -+mtk_p2p_wext_set_pm_param(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); -+ -+int -+mtk_p2p_wext_set_ps_profile(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); -+ -+int -+mtk_p2p_wext_set_network_address(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); -+ -+int -+mtk_p2p_wext_set_int(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); -+ -+/* Private Wireless I/O Controls for IOC_SET_STRUCT/IOC_GET_STRUCT */ -+int -+mtk_p2p_wext_set_struct(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); -+ -+int -+mtk_p2p_wext_get_struct(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); -+ -+/* IOC_SET_STRUCT/IOC_GET_STRUCT: Service Discovery */ -+int -+mtk_p2p_wext_get_service_discovery_request(IN struct net_device *prDev, -+ IN struct iw_request_info *info, -+ IN OUT union iwreq_data *wrqu, IN OUT char *extra); -+ -+int -+mtk_p2p_wext_get_service_discovery_response(IN struct net_device *prDev, -+ IN struct iw_request_info *info, -+ IN OUT union iwreq_data *wrqu, IN OUT char *extra); -+ -+int -+mtk_p2p_wext_send_service_discovery_request(IN struct net_device *prDev, -+ IN struct iw_request_info *info, -+ IN OUT union iwreq_data *wrqu, IN OUT char *extra); -+ -+int -+mtk_p2p_wext_send_service_discovery_response(IN struct net_device *prDev, -+ IN struct iw_request_info *info, -+ IN OUT union iwreq_data *wrqu, IN OUT char *extra); -+ -+int -+mtk_p2p_wext_terminate_service_discovery_phase(IN struct net_device *prDev, -+ IN struct iw_request_info *info, -+ IN OUT union iwreq_data *wrqu, IN OUT char *extra); -+ -+#if CFG_SUPPORT_ANTI_PIRACY -+int -+mtk_p2p_wext_set_sec_check_request(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); -+ -+int -+mtk_p2p_wext_get_sec_check_response(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); -+#endif -+ -+int -+mtk_p2p_wext_set_noa_param(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); -+ -+int -+mtk_p2p_wext_set_oppps_param(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); -+ -+int -+mtk_p2p_wext_set_p2p_version(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); -+ -+int -+mtk_p2p_wext_get_p2p_version(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); -+ -+void mtk_p2p_wext_set_Multicastlist(IN P_GLUE_INFO_T prGlueInfo); -+ -+#if CFG_SUPPORT_P2P_RSSI_QUERY -+int -+mtk_p2p_wext_get_rssi(IN struct net_device *prDev, -+ IN struct iw_request_info *info, IN OUT union iwreq_data *wrqu, IN OUT char *extra); -+ -+struct iw_statistics *mtk_p2p_wext_get_wireless_stats(struct net_device *prDev); -+ -+#endif -+ -+int -+mtk_p2p_wext_set_txpow(IN struct net_device *prDev, -+ IN struct iw_request_info *prIwrInfo, IN OUT union iwreq_data *prTxPow, IN char *pcExtra); -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif /* _GL_P2P_IOCTL_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_p2p_kal.h b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_p2p_kal.h -new file mode 100644 -index 000000000000..bf9d8871ef48 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_p2p_kal.h -@@ -0,0 +1,243 @@ -+/* -+** Id: //Department/DaVinci/TRUNK/WiFi_P2P_Driver/os/linux/include/gl_p2p_kal.h#2 -+*/ -+ -+/*! \file gl_p2p_kal.h -+ \brief Declaration of KAL functions for Wi-Fi Direct support -+ - kal*() which is provided by GLUE Layer. -+ -+ Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. -+*/ -+ -+/* -+** Log: gl_p2p_kal.h -+** -+** 08 30 2012 chinglan.wang -+** [ALPS00349664] [6577JB][WIFI] Phone can not connect to AP secured with AES via WPS in 802.11n Only -+** . -+ * -+ * 07 17 2012 yuche.tsai -+ * NULL -+ * Compile no error before trial run. -+ * -+ * 10 18 2011 yuche.tsai -+ * [WCXRP00001045] [WiFi Direct][Driver] Check 2.1 branch. -+ * New 2.1 branch -+ -+ * -+ * 08 15 2011 yuche.tsai -+ * [WCXRP00000919] [Volunteer Patch][WiFi Direct][Driver] Invitation New Feature. -+ * Add group BSSID in invitation request indication. -+ * The BSSID is used for APP to decide the configure method. -+ * -+ * 08 09 2011 yuche.tsai -+ * [WCXRP00000919] [Volunteer Patch][WiFi Direct][Driver] Invitation New Feature. -+ * Invitation Feature add on. -+ * -+ * 03 19 2011 terry.wu -+ * [WCXRP00000577] [MT6620 Wi-Fi][Driver][FW] Create V2.0 branch for firmware and driver -+ * create V2.0 p2p driver release based on label "MT6620_WIFI_P2P_DRIVER_V2_0_2100_0319_2011" from main trunk. -+ * -+ * 03 07 2011 wh.su -+ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code -+ * rename the define to anti_pviracy. -+ * -+ * 03 05 2011 wh.su -+ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code -+ * add the code to get the check rsponse and indicate to app. -+ * -+ * 03 02 2011 wh.su -+ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code -+ * Add Security check related code. -+ * -+ * 12 22 2010 cp.wu -+ * [WCXRP00000283] [MT6620 Wi-Fi][Driver][Wi-Fi Direct] Implementation of interface for supporting Wi-Fi Direct Service -+ * Discovery -+ * 1. header file restructure for more clear module isolation -+ * 2. add function interface definition for implementing Service Discovery callbacks -+ * -+*/ -+ -+#ifndef _GL_P2P_KAL_H -+#define _GL_P2P_KAL_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "config.h" -+#include "gl_typedef.h" -+#include "gl_os.h" -+#include "wlan_lib.h" -+#include "wlan_oid.h" -+#include "wlan_p2p.h" -+#include "gl_kal.h" -+#include "gl_wext_priv.h" -+#include "nic/p2p.h" -+ -+#if DBG -+extern int allocatedMemSize; -+#endif -+ -+extern BOOLEAN -+wextSrchDesiredWPAIE(IN PUINT_8 pucIEStart, -+ IN INT_32 i4TotalIeLen, IN UINT_8 ucDesiredElemId, OUT unsigned char **ppucDesiredIE); -+ -+#if CFG_SUPPORT_WPS -+extern BOOLEAN -+wextSrchDesiredWPSIE(IN PUINT_8 pucIEStart, -+ IN INT_32 i4TotalIeLen, IN UINT_8 ucDesiredElemId, OUT unsigned char **ppucDesiredIE); -+#endif -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+BOOLEAN kalP2pFuncGetChannelType(IN ENUM_CHNL_EXT_T rChnlSco, OUT enum nl80211_channel_type *channel_type); -+struct ieee80211_channel *kalP2pFuncGetChannelEntry(IN P_GL_P2P_INFO_T prP2pInfo, IN P_RF_CHANNEL_INFO_T prChannelInfo); -+ -+/* Service Discovery */ -+VOID kalP2PIndicateSDRequest(IN P_GLUE_INFO_T prGlueInfo, IN PARAM_MAC_ADDRESS rPeerAddr, IN UINT_8 ucSeqNum); -+ -+void kalP2PIndicateSDResponse(IN P_GLUE_INFO_T prGlueInfo, IN PARAM_MAC_ADDRESS rPeerAddr, IN UINT_8 ucSeqNum); -+ -+VOID kalP2PIndicateTXDone(IN P_GLUE_INFO_T prGlueInfo, IN UINT_8 ucSeqNum, IN UINT_8 ucStatus); -+ -+/*----------------------------------------------------------------------------*/ -+/* Wi-Fi Direct handling */ -+/*----------------------------------------------------------------------------*/ -+ENUM_PARAM_MEDIA_STATE_T kalP2PGetState(IN P_GLUE_INFO_T prGlueInfo); -+ -+VOID -+kalP2PSetState(IN P_GLUE_INFO_T prGlueInfo, -+ IN ENUM_PARAM_MEDIA_STATE_T eState, IN PARAM_MAC_ADDRESS rPeerAddr, IN UINT_8 ucRole); -+ -+VOID -+kalP2PUpdateAssocInfo(IN P_GLUE_INFO_T prGlueInfo, -+ IN PUINT_8 pucFrameBody, IN UINT_32 u4FrameBodyLen, IN BOOLEAN fgReassocRequest); -+ -+UINT_32 kalP2PGetFreqInKHz(IN P_GLUE_INFO_T prGlueInfo); -+ -+UINT_8 kalP2PGetRole(IN P_GLUE_INFO_T prGlueInfo); -+ -+VOID -+kalP2PSetRole(IN P_GLUE_INFO_T prGlueInfo, -+ IN UINT_8 ucResult, IN PUINT_8 pucSSID, IN UINT_8 ucSSIDLen, IN UINT_8 ucRole); -+ -+VOID kalP2PSetCipher(IN P_GLUE_INFO_T prGlueInfo, IN UINT_32 u4Cipher); -+ -+BOOLEAN kalP2PGetCipher(IN P_GLUE_INFO_T prGlueInfo); -+ -+BOOLEAN kalP2PGetTkipCipher(IN P_GLUE_INFO_T prGlueInfo); -+ -+BOOLEAN kalP2PGetCcmpCipher(IN P_GLUE_INFO_T prGlueInfo); -+ -+VOID kalP2PSetWscMode(IN P_GLUE_INFO_T prGlueInfo, IN UINT_8 ucWscMode); -+ -+UINT_8 kalP2PGetWscMode(IN P_GLUE_INFO_T prGlueInfo); -+ -+UINT_16 kalP2PCalWSC_IELen(IN P_GLUE_INFO_T prGlueInfo, IN UINT_8 ucType); -+ -+VOID kalP2PGenWSC_IE(IN P_GLUE_INFO_T prGlueInfo, IN UINT_8 ucType, IN PUINT_8 pucBuffer); -+ -+VOID kalP2PUpdateWSC_IE(IN P_GLUE_INFO_T prGlueInfo, IN UINT_8 ucType, IN PUINT_8 pucBuffer, IN UINT_16 u2BufferLength); -+ -+BOOLEAN kalP2PIndicateFound(IN P_GLUE_INFO_T prGlueInfo); -+ -+VOID kalP2PIndicateConnReq(IN P_GLUE_INFO_T prGlueInfo, IN PUINT_8 pucDevName, IN INT_32 u4NameLength, -+ IN PARAM_MAC_ADDRESS rPeerAddr, IN UINT_8 ucDevType, /* 0: P2P Device / 1: GC / 2: GO */ -+ IN INT_32 i4ConfigMethod, IN INT_32 i4ActiveConfigMethod); -+ -+VOID kalP2PInvitationStatus(IN P_GLUE_INFO_T prGlueInfo, IN UINT_32 u4InvStatus); -+ -+VOID -+kalP2PInvitationIndication(IN P_GLUE_INFO_T prGlueInfo, -+ IN P_P2P_DEVICE_DESC_T prP2pDevDesc, -+ IN PUINT_8 pucSsid, -+ IN UINT_8 ucSsidLen, -+ IN UINT_8 ucOperatingChnl, IN UINT_8 ucInvitationType, IN PUINT_8 pucGroupBssid); -+ -+struct net_device *kalP2PGetDevHdlr(P_GLUE_INFO_T prGlueInfo); -+ -+VOID -+kalGetChnlList(IN P_GLUE_INFO_T prGlueInfo, -+ IN ENUM_BAND_T eSpecificBand, -+ IN UINT_8 ucMaxChannelNum, IN PUINT_8 pucNumOfChannel, IN P_RF_CHANNEL_INFO_T paucChannelList); -+ -+#if CFG_SUPPORT_ANTI_PIRACY -+VOID kalP2PIndicateSecCheckRsp(IN P_GLUE_INFO_T prGlueInfo, IN PUINT_8 pucRsp, IN UINT_16 u2RspLen); -+#endif -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+VOID -+kalP2PIndicateChannelReady(IN P_GLUE_INFO_T prGlueInfo, -+ IN UINT_64 u8SeqNum, -+ IN UINT_32 u4ChannelNum, -+ IN ENUM_BAND_T eBand, IN ENUM_CHNL_EXT_T eSco, IN UINT_32 u4Duration); -+ -+VOID kalP2PIndicateScanDone(IN P_GLUE_INFO_T prGlueInfo, IN BOOLEAN fgIsAbort); -+ -+VOID -+kalP2PIndicateBssInfo(IN P_GLUE_INFO_T prGlueInfo, -+ IN PUINT_8 pucFrameBuf, -+ IN UINT_32 u4BufLen, IN P_RF_CHANNEL_INFO_T prChannelInfo, IN INT_32 i4SignalStrength); -+ -+VOID kalP2PIndicateRxMgmtFrame(IN P_GLUE_INFO_T prGlueInfo, IN P_SW_RFB_T prSwRfb); -+ -+VOID -+kalP2PIndicateMgmtTxStatus(IN P_GLUE_INFO_T prGlueInfo, -+ IN UINT_64 u8Cookie, IN BOOLEAN fgIsAck, IN PUINT_8 pucFrameBuf, IN UINT_32 u4FrameLen); -+ -+VOID kalP2PIndicateChannelExpired(IN P_GLUE_INFO_T prGlueInfo, IN P_P2P_CHNL_REQ_INFO_T prChnlReqInfo); -+ -+VOID -+kalP2PGCIndicateConnectionStatus(IN P_GLUE_INFO_T prGlueInfo, -+ IN P_P2P_CONNECTION_REQ_INFO_T prP2pConnInfo, -+ IN PUINT_8 pucRxIEBuf, IN UINT_16 u2RxIELen, IN UINT_16 u2StatusReason, -+ IN WLAN_STATUS eStatus); -+ -+VOID kalP2PGOStationUpdate(IN P_GLUE_INFO_T prGlueInfo, IN P_STA_RECORD_T prCliStaRec, IN BOOLEAN fgIsNew); -+ -+INT_32 kalP2PSetBlackList(IN P_GLUE_INFO_T prGlueInfo, IN PARAM_MAC_ADDRESS rbssid, IN BOOLEAN fgIsblock); -+ -+BOOLEAN kalP2PCmpBlackList(IN P_GLUE_INFO_T prGlueInfo, IN PARAM_MAC_ADDRESS rbssid); -+ -+VOID kalP2PSetMaxClients(IN P_GLUE_INFO_T prGlueInfo, IN UINT_32 u4MaxClient); -+ -+BOOLEAN kalP2PMaxClients(IN P_GLUE_INFO_T prGlueInfo, IN UINT_32 u4NumClient); -+ -+#endif /* _GL_P2P_KAL_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_p2p_os.h b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_p2p_os.h -new file mode 100644 -index 000000000000..e5026e7e6eec ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_p2p_os.h -@@ -0,0 +1,242 @@ -+/* -+** Id: -+//Department/DaVinci/TRUNK/MT6620_5931_WiFi_Driver/os/linux/include/gl_p2p_os.h#28 -+*/ -+ -+/*! \file gl_p2p_os.h -+ \brief List the external reference to OS for p2p GLUE Layer. -+ -+ In this file we define the data structure - GLUE_INFO_T to store those objects -+ we acquired from OS - e.g. TIMER, SPINLOCK, NET DEVICE ... . And all the -+ external reference (header file, extern func() ..) to OS for GLUE Layer should -+ also list down here. -+*/ -+ -+#ifndef _GL_P2P_OS_H -+#define _GL_P2P_OS_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include -+#if CFG_ENABLE_WIFI_DIRECT_CFG_80211 -+#include -+#endif -+ -+#include "wlan_oid.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+struct _GL_P2P_INFO_T { -+ -+ /* Device handle */ -+ struct net_device *prDevHandler; -+ -+#if CFG_ENABLE_WIFI_DIRECT_CFG_80211 -+ /* cfg80211 */ -+ struct wireless_dev *prWdev; -+ -+ struct cfg80211_scan_request *prScanRequest; -+ -+ UINT_64 u8Cookie; -+ -+ /* Generation for station list update. */ -+ INT_32 i4Generation; -+ -+ UINT_32 u4OsMgmtFrameFilter; -+ -+#endif -+ -+ /* Device statistics */ -+ struct net_device_stats rNetDevStats; -+ -+ /* glue layer variables */ -+ UINT_32 u4FreqInKHz; /* frequency */ -+ UINT_8 ucRole; /* 0: P2P Device, 1: Group Client, 2: Group Owner */ -+ UINT_8 ucIntent; /* range: 0-15 */ -+ UINT_8 ucScanMode; /* 0: Search & Listen, 1: Scan without probe response */ -+ -+ ENUM_PARAM_MEDIA_STATE_T eState; -+ UINT_32 u4PacketFilter; -+ PARAM_MAC_ADDRESS aucMCAddrList[MAX_NUM_GROUP_ADDR]; -+ -+ /* connection-requested peer information */ -+ UINT_8 aucConnReqDevName[32]; -+ INT_32 u4ConnReqNameLength; -+ PARAM_MAC_ADDRESS rConnReqPeerAddr; -+ PARAM_MAC_ADDRESS rConnReqGroupAddr; /* For invitation group. */ -+ UINT_8 ucConnReqDevType; -+ INT_32 i4ConnReqConfigMethod; -+ INT_32 i4ConnReqActiveConfigMethod; -+ -+ UINT_32 u4CipherPairwise; -+ UINT_8 ucWSCRunning; -+ -+ UINT_8 aucWSCIE[3][400]; /* 0 for beacon, 1 for probe req, 2 for probe response */ -+ UINT_16 u2WSCIELen[3]; -+ -+#if CFG_SUPPORT_WFD -+ UINT_8 aucVenderIE[1024]; /* Save the other IE for prove resp */ -+ UINT_16 u2VenderIELen; -+#endif -+ -+ UINT_8 ucOperatingChnl; -+ UINT_8 ucInvitationType; -+ -+ UINT_32 u4InvStatus; -+ -+ /* For SET_STRUCT/GET_STRUCT */ -+ UINT_8 aucOidBuf[4096]; -+ -+#if 1 /* CFG_SUPPORT_ANTI_PIRACY */ -+ UINT_8 aucSecCheck[256]; -+ UINT_8 aucSecCheckRsp[256]; -+#endif -+ -+ /* Hotspot Client Management */ -+ PARAM_MAC_ADDRESS aucblackMACList[8]; -+ UINT_8 ucMaxClients; -+ -+#if CFG_SUPPORT_HOTSPOT_OPTIMIZATION -+ UINT_32 u4PsLevel; -+#endif -+}; -+ -+#ifdef CONFIG_NL80211_TESTMODE -+typedef struct _NL80211_DRIVER_TEST_PRE_PARAMS { -+ UINT_16 idx_mode; -+ UINT_16 idx; -+ UINT_32 value; -+} NL80211_DRIVER_TEST_PRE_PARAMS, *P_NL80211_DRIVER_TEST_PRE_PARAMS; -+ -+typedef struct _NL80211_DRIVER_TEST_PARAMS { -+ UINT_32 index; -+ UINT_32 buflen; -+} NL80211_DRIVER_TEST_PARAMS, *P_NL80211_DRIVER_TEST_PARAMS; -+ -+/* P2P Sigma*/ -+typedef struct _NL80211_DRIVER_P2P_SIGMA_PARAMS { -+ NL80211_DRIVER_TEST_PARAMS hdr; -+ UINT_32 idx; -+ UINT_32 value; -+} NL80211_DRIVER_P2P_SIGMA_PARAMS, *P_NL80211_DRIVER_P2P_SIGMA_PARAMS; -+ -+/* Hotspot Client Management */ -+typedef struct _NL80211_DRIVER_HOTSPOT_BLOCK_PARAMS { -+ NL80211_DRIVER_TEST_PARAMS hdr; -+ UINT_8 ucblocked; -+ UINT_8 aucBssid[MAC_ADDR_LEN]; -+} NL80211_DRIVER_HOTSPOT_BLOCK_PARAMS, *P_NL80211_DRIVER_HOTSPOT_BLOCK_PARAMS; -+ -+#if CFG_SUPPORT_WFD -+typedef struct _NL80211_DRIVER_WFD_PARAMS { -+ NL80211_DRIVER_TEST_PARAMS hdr; -+ UINT_32 WfdCmdType; -+ UINT_8 WfdEnable; -+ UINT_8 WfdCoupleSinkStatus; -+ UINT_8 WfdSessionAvailable; -+ UINT_8 WfdSigmaMode; -+ UINT_16 WfdDevInfo; -+ UINT_16 WfdControlPort; -+ UINT_16 WfdMaximumTp; -+ UINT_16 WfdExtendCap; -+ UINT_8 WfdCoupleSinkAddress[MAC_ADDR_LEN]; -+ UINT_8 WfdAssociatedBssid[MAC_ADDR_LEN]; -+ UINT_8 WfdVideoIp[4]; -+ UINT_8 WfdAudioIp[4]; -+ UINT_16 WfdVideoPort; -+ UINT_16 WfdAudioPort; -+ UINT_32 WfdFlag; -+ UINT_32 WfdPolicy; -+ UINT_32 WfdState; -+ UINT_8 WfdSessionInformationIE[24 * 8]; /* Include Subelement ID, length */ -+ UINT_16 WfdSessionInformationIELen; -+ UINT_8 aucReserved1[2]; -+ UINT_8 aucWfdPrimarySinkMac[MAC_ADDR_LEN]; -+ UINT_8 aucWfdSecondarySinkMac[MAC_ADDR_LEN]; -+ UINT_32 WfdAdvanceFlag; -+ /* Group 1 64 bytes */ -+ UINT_8 aucWfdLocalIp[4]; -+ UINT_16 WfdLifetimeAc2; /* Unit is 2 TU */ -+ UINT_16 WfdLifetimeAc3; /* Unit is 2 TU */ -+ UINT_16 WfdCounterThreshold; /* Unit is ms */ -+ UINT_8 aucReserved2[54]; -+ /* Group 3 64 bytes */ -+ UINT_8 aucReserved3[64]; -+ /* Group 3 64 bytes */ -+ UINT_8 aucReserved4[64]; -+} NL80211_DRIVER_WFD_PARAMS, *P_NL80211_DRIVER_WFD_PARAMS; -+#endif -+#endif -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+BOOLEAN p2pLaunch(P_GLUE_INFO_T prGlueInfo); -+ -+BOOLEAN p2pRemove(P_GLUE_INFO_T prGlueInfo); -+ -+VOID p2pSetMode(IN BOOLEAN fgIsAPMOde); -+ -+BOOLEAN glRegisterP2P(P_GLUE_INFO_T prGlueInfo, const char *prDevName, BOOLEAN fgIsApMode); -+ -+VOID p2pEalySuspendReg(P_GLUE_INFO_T prGlueInfo, BOOLEAN fgIsEnable); -+ -+BOOLEAN glUnregisterP2P(P_GLUE_INFO_T prGlueInfo); -+ -+BOOLEAN p2pNetRegister(P_GLUE_INFO_T prGlueInfo, BOOLEAN fgIsRtnlLockAcquired); -+ -+BOOLEAN p2pNetUnregister(P_GLUE_INFO_T prGlueInfo, BOOLEAN fgIsRtnlLockAcquired); -+ -+BOOLEAN p2pStopImmediate(P_GLUE_INFO_T prGlueInfo); -+ -+BOOLEAN p2PFreeInfo(P_GLUE_INFO_T prGlueInfo); -+ -+BOOLEAN glP2pCreateWirelessDevice(P_GLUE_INFO_T prGlueInfo); -+ -+VOID glP2pDestroyWirelessDevice(VOID); -+ -+VOID p2pSetMulticastListWorkQueueWrapper(P_GLUE_INFO_T prGlueInfo); -+ -+#endif -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_rst.h b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_rst.h -new file mode 100644 -index 000000000000..f24ceee9e921 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_rst.h -@@ -0,0 +1,133 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux/include/gl_rst.h#1 -+*/ -+ -+/*! \file gl_rst.h -+ \brief Declaration of functions and finite state machine for -+ MT6620 Whole-Chip Reset Mechanism -+*/ -+ -+#ifndef _GL_RST_H -+#define _GL_RST_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include "gl_typedef.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+#if 1 -+typedef INT_32(*wmt_wlan_probe_cb) (VOID); -+typedef INT_32(*wmt_wlan_remove_cb) (VOID); -+typedef INT_32(*wmt_wlan_bus_cnt_get_cb) (VOID); -+typedef INT_32(*wmt_wlan_bus_cnt_clr_cb) (VOID); -+ -+typedef struct _MTK_WCN_WMT_WLAN_CB_INFO { -+ wmt_wlan_probe_cb wlan_probe_cb; -+ wmt_wlan_remove_cb wlan_remove_cb; -+ wmt_wlan_bus_cnt_get_cb wlan_bus_cnt_get_cb; -+ wmt_wlan_bus_cnt_clr_cb wlan_bus_cnt_clr_cb; -+} MTK_WCN_WMT_WLAN_CB_INFO, *P_MTK_WCN_WMT_WLAN_CB_INFO; -+ -+extern INT_32 mtk_wcn_wmt_wlan_reg(P_MTK_WCN_WMT_WLAN_CB_INFO pWmtWlanCbInfo); -+extern INT_32 mtk_wcn_wmt_wlan_unreg(VOID); -+#endif -+ -+typedef enum _ENUM_RESET_STATUS_T { -+ RESET_FAIL, -+ RESET_SUCCESS -+} ENUM_RESET_STATUS_T; -+ -+typedef struct _RESET_STRUCT_T { -+ ENUM_RESET_STATUS_T rst_data; -+ struct work_struct rst_work; -+} RESET_STRUCT_T; -+ -+typedef enum _ENUM_WMTRSTMSG_TYPE_T { -+ WMTRSTMSG_RESET_START = 0x0, -+ WMTRSTMSG_RESET_END = 0x1, -+ WMTRSTMSG_RESET_END_FAIL = 0x2, -+ WMTRSTMSG_RESET_MAX, -+ WMTRSTMSG_RESET_INVALID = 0xff -+} ENUM_WMTRSTMSG_TYPE_T, *P_ENUM_WMTRSTMSG_TYPE_T; -+ -+typedef void (*PF_WMT_CB) (ENUM_WMTDRV_TYPE_T, /* Source driver type */ -+ ENUM_WMTDRV_TYPE_T, /* Destination driver type */ -+ ENUM_WMTMSG_TYPE_T, /* Message type */ -+ void *, /* READ-ONLY buffer. Buffer is allocated and freed by WMT_drv. Client -+ can't touch this buffer after this function return. */ -+ unsigned int /* Buffer size in unit of byte */ -+); -+ -+/******************************************************************************* -+* E X T E R N A L F U N C T I O N S -+******************************************************************************** -+*/ -+#define glDoChipReset() \ -+ do { \ -+ if (!kalStrnCmp(current->comm, "mtk_wmtd", 8)) { \ -+ g_IsNeedDoChipReset = 1; \ -+ DBGLOG(INIT, ERROR, "forbid core dump in mtk_wmtd %s line %d\n", __func__, __LINE__); \ -+ break; \ -+ } \ -+ DBGLOG(INIT, ERROR, "Do core dump and chip reset in %s line %d\n", __func__, __LINE__); \ -+ mtk_wcn_wmt_assert(WMTDRV_TYPE_WIFI, 0x40); \ -+ } while (0) -+ -+#if CFG_CHIP_RESET_SUPPORT -+extern int mtk_wcn_wmt_msgcb_reg(ENUM_WMTDRV_TYPE_T eType, PF_WMT_CB pCb); -+extern int mtk_wcn_wmt_msgcb_unreg(ENUM_WMTDRV_TYPE_T eType); -+extern int wifi_reset_start(void); -+extern int wifi_reset_end(ENUM_RESET_STATUS_T); -+#endif -+extern MTK_WCN_BOOL mtk_wcn_wmt_assert(ENUM_WMTDRV_TYPE_T type, UINT32 reason); -+extern BOOLEAN mtk_wcn_set_connsys_power_off_flag(BOOLEAN value); -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+extern UINT_32 g_IsNeedDoChipReset; -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+VOID glResetInit(VOID); -+ -+VOID glResetUninit(VOID); -+ -+VOID glSendResetRequest(VOID); -+ -+BOOLEAN kalIsResetting(VOID); -+ -+#endif /* _GL_RST_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_sec.h b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_sec.h -new file mode 100644 -index 000000000000..3cc57780f201 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_sec.h -@@ -0,0 +1,21 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux/include/gl_sec.h#1 -+*/ -+ -+/*! \file p2p_fsm.h -+ \brief Declaration of functions and finite state machine for P2P Module. -+ -+ Declaration of functions and finite state machine for P2P Module. -+*/ -+ -+#ifndef _GL_SEC_H -+#define _GL_SEC_H -+ -+extern void handle_sec_msg_1(unsigned char *msg_in, int msg_in_len, unsigned char *msg_out, int *msg_out_len); -+extern void handle_sec_msg_2(unsigned char *msg_in, int msg_in_len, unsigned char *msg_out, int *msg_out_len); -+extern void handle_sec_msg_3(unsigned char *msg_in, int msg_in_len, unsigned char *msg_out, int *msg_out_len); -+extern void handle_sec_msg_4(unsigned char *msg_in, int msg_in_len, unsigned char *msg_out, int *msg_out_len); -+extern void handle_sec_msg_5(unsigned char *msg_in, int msg_in_len, unsigned char *msg_out, int *msg_out_len); -+extern void handle_sec_msg_final(unsigned char *msg_in, int msg_in_len, unsigned char *msg_out, int *msg_out_len); -+ -+#endif /* _GL_SEC_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_typedef.h b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_typedef.h -new file mode 100644 -index 000000000000..e9aa3e849eb2 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_typedef.h -@@ -0,0 +1,298 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux/include/gl_typedef.h#1 -+*/ -+ -+/*! \file gl_typedef.h -+ \brief Definition of basic data type(os dependent). -+ -+ In this file we define the basic data type. -+*/ -+ -+/* -+** Log: gl_typedef.h -+ * -+ * 06 22 2012 cp.wu -+ * [WCXRP00001257] [MT6620][MT5931][MT6628][Driver][Linux] Modify KAL_HZ to align ms accuracy -+ * modify KAL_HZ to (1000) for correct definition. -+ * -+ * 03 21 2011 cp.wu -+ * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer -+ * portability improvement -+ * -+ * 02 15 2011 jeffrey.chang -+ * NULL -+ * to support early suspend in android -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 03 24 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * initial import for Linux port -+** \main\maintrunk.MT5921\6 2009-08-18 22:57:14 GMT mtk01090 -+** Add Linux SDIO (with mmc core) support. -+** Add Linux 2.6.21, 2.6.25, 2.6.26. -+** Fix compile warning in Linux. -+** \main\maintrunk.MT5921\5 2008-09-22 23:19:30 GMT mtk01461 -+** Update comment for code review -+** \main\maintrunk.MT5921\4 2008-09-05 17:25:16 GMT mtk01461 -+** Update Driver for Code Review -+** \main\maintrunk.MT5921\3 2007-11-09 11:00:50 GMT mtk01425 -+** 1. Use macro to unify network-to-host and host-to-network related functions -+** Revision 1.3 2007/06/27 02:18:51 MTK01461 -+** Update SCAN_FSM, Initial(Can Load Module), Proc(Can do Reg R/W), TX API -+** -+** Revision 1.2 2007/06/25 06:16:24 MTK01461 -+** Update illustrations, gl_init.c, gl_kal.c, gl_kal.h, gl_os.h and RX API -+** -+*/ -+ -+#ifndef _GL_TYPEDEF_H -+#define _GL_TYPEDEF_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+/* Define HZ of timer tick for function kalGetTimeTick() */ -+#define KAL_HZ (1000) -+ -+/* Miscellaneous Equates */ -+#ifndef FALSE -+#define FALSE ((BOOLEAN) 0) -+#define TRUE ((BOOLEAN) 1) -+#endif /* FALSE */ -+ -+#ifndef NULL -+#if defined(__cplusplus) -+#define NULL 0 -+#else -+#define NULL ((void *) 0) -+#endif -+#endif -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+/* Type definition for void */ -+/*mach/mt_typedefs.h define _TYPEDEFS_H, to avoid compile error*/ -+#ifndef _TYPEDEFS_H -+typedef void VOID; -+#endif -+typedef void *PVOID, **PPVOID; -+ -+/* Type definition for Boolean */ -+typedef unsigned char BOOLEAN, *PBOOLEAN; -+ -+/* Type definition for signed integers */ -+typedef signed char CHAR, *PCHAR, **PPCHAR; -+typedef signed char INT_8, *PINT_8, **PPINT_8; -+typedef signed short INT_16, *PINT_16, **PPINT_16; -+typedef signed int INT_32, *PINT_32, **PPINT_32; -+typedef long LONG, *PLONG, **PPLONG; -+typedef signed long long INT_64, *PINT_64, **PPINT_64; -+ -+/* Type definition for unsigned integers */ -+typedef unsigned char UCHAR, *PUCHAR, **PPUCHAR; -+typedef unsigned char UINT_8, *PUINT_8, **PPUINT_8, *P_UINT_8; -+typedef unsigned short UINT_16, *PUINT_16, **PPUINT_16; -+typedef unsigned int UINT32, *PUINT32; -+typedef unsigned int UINT_32, *PUINT_32, **PPUINT_32; -+typedef unsigned long ULONG, *PULONG, **PPULONG; -+typedef unsigned long long UINT_64, *PUINT_64, **PPUINT_64; -+ -+typedef unsigned int OS_SYSTIME, *POS_SYSTIME, **PPOS_SYSTIME; -+ -+#ifndef _TYPEDEFS_H -+typedef signed char INT8, *PINT8; -+typedef signed short INT16, *PINT16; -+typedef signed int INT32, *PINT32; -+typedef unsigned char UINT8, *PUINT8; -+typedef unsigned short UINT16, *PUINT16; -+typedef unsigned int UINT32, *PUINT32; -+#endif -+ -+/* Type definition of large integer (64bits) union to be comptaible with -+ * Windows definition, so we won't apply our own coding style to these data types. -+ * NOTE: LARGE_INTEGER must NOT be floating variable. -+ * : Check for big-endian compatibility. -+ */ -+typedef union _LARGE_INTEGER { -+ struct { -+ UINT_32 LowPart; -+ INT_32 HighPart; -+ } u; -+ INT_64 QuadPart; -+} LARGE_INTEGER, *PLARGE_INTEGER; -+ -+typedef union _ULARGE_INTEGER { -+ struct { -+ UINT_32 LowPart; -+ UINT_32 HighPart; -+ } u; -+ UINT_64 QuadPart; -+} ULARGE_INTEGER, *PULARGE_INTEGER; -+ -+typedef INT_32(*probe_card) (PVOID pvData); -+typedef VOID(*remove_card) (VOID); -+ -+/* duplicated from wmt_exp.h for better driver isolation */ -+typedef enum _ENUM_WMTDRV_TYPE_T { -+ WMTDRV_TYPE_BT = 0, -+ WMTDRV_TYPE_FM = 1, -+ WMTDRV_TYPE_GPS = 2, -+ WMTDRV_TYPE_WIFI = 3, -+ WMTDRV_TYPE_WMT = 4, -+ WMTDRV_TYPE_STP = 5, -+ WMTDRV_TYPE_SDIO1 = 6, -+ WMTDRV_TYPE_SDIO2 = 7, -+ WMTDRV_TYPE_LPBK = 8, -+ WMTDRV_TYPE_MAX -+} ENUM_WMTDRV_TYPE_T, *P_ENUM_WMTDRV_TYPE_T; -+ -+typedef enum _ENUM_WMTMSG_TYPE_T { -+ WMTMSG_TYPE_POWER_ON = 0, -+ WMTMSG_TYPE_POWER_OFF = 1, -+ WMTMSG_TYPE_RESET = 2, -+ WMTMSG_TYPE_STP_RDY = 3, -+ WMTMSG_TYPE_HW_FUNC_ON = 4, -+ WMTMSG_TYPE_MAX -+} ENUM_WMTMSG_TYPE_T, *P_ENUM_WMTMSG_TYPE_T; -+ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+#define IN /* volatile */ -+#define OUT /* volatile */ -+ -+#define __KAL_ATTRIB_PACKED__ __attribute__((__packed__)) -+#define __KAL_ATTRIB_ALIGN_4__ __aligned(4) -+ -+#ifndef BIT -+#define BIT(n) ((UINT_32) 1U << (n)) -+#endif /* BIT */ -+ -+#ifndef BITS -+/* bits range: for example BITS(16,23) = 0xFF0000 -+ * ==> (BIT(m)-1) = 0x0000FFFF ~(BIT(m)-1) => 0xFFFF0000 -+ * ==> (BIT(n+1)-1) = 0x00FFFFFF -+ */ -+#define BITS(m, n) (~(BIT(m)-1) & ((BIT(n) - 1) | BIT(n))) -+#endif /* BIT */ -+ -+/* This macro returns the byte offset of a named field in a known structure -+ type. -+ _type - structure name, -+ _field - field name of the structure */ -+#ifndef OFFSET_OF -+#define OFFSET_OF(_type, _field) ((ULONG)&(((_type *)0)->_field)) -+#endif /* OFFSET_OF */ -+ -+/* This macro returns the base address of an instance of a structure -+ * given the type of the structure and the address of a field within the -+ * containing structure. -+ * _addrOfField - address of current field of the structure, -+ * _type - structure name, -+ * _field - field name of the structure -+ */ -+#ifndef ENTRY_OF -+#define ENTRY_OF(_addrOfField, _type, _field) \ -+ ((_type *)((PINT_8)(_addrOfField) - (PINT_8)OFFSET_OF(_type, _field))) -+#endif /* ENTRY_OF */ -+ -+/* This macro align the input value to the DW boundary. -+ * _value - value need to check -+ */ -+#ifndef ALIGN_4 -+#define ALIGN_4(_value) (((_value) + 3) & ~3u) -+#endif /* ALIGN_4 */ -+ -+/* This macro check the DW alignment of the input value. -+ * _value - value of address need to check -+ */ -+#ifndef IS_ALIGN_4 -+#define IS_ALIGN_4(_value) (((_value) & 0x3) ? FALSE : TRUE) -+#endif /* IS_ALIGN_4 */ -+ -+#ifndef IS_NOT_ALIGN_4 -+#define IS_NOT_ALIGN_4(_value) (((_value) & 0x3) ? TRUE : FALSE) -+#endif /* IS_NOT_ALIGN_4 */ -+ -+/* This macro evaluate the input length in unit of Double Word(4 Bytes). -+ * _value - value in unit of Byte, output will round up to DW boundary. -+ */ -+#ifndef BYTE_TO_DWORD -+#define BYTE_TO_DWORD(_value) ((_value + 3) >> 2) -+#endif /* BYTE_TO_DWORD */ -+ -+/* This macro evaluate the input length in unit of Byte. -+ * _value - value in unit of DW, output is in unit of Byte. -+ */ -+#ifndef DWORD_TO_BYTE -+#define DWORD_TO_BYTE(_value) ((_value) << 2) -+#endif /* DWORD_TO_BYTE */ -+ -+#if 1 /* Little-Endian */ -+#define CONST_NTOHS(_x) ntohs(_x) -+ -+#define CONST_HTONS(_x) htons(_x) -+ -+#define NTOHS(_x) ntohs(_x) -+ -+#define HTONS(_x) htons(_x) -+ -+#define NTOHL(_x) ntohl(_x) -+ -+#define HTONL(_x) htonl(_x) -+ -+#else /* Big-Endian */ -+ -+#define CONST_NTOHS(_x) -+ -+#define CONST_HTONS(_x) -+ -+#define NTOHS(_x) -+ -+#define HTONS(_x) -+ -+#endif -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif /* _GL_TYPEDEF_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_vendor.h b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_vendor.h -new file mode 100644 -index 000000000000..d8d5b0fb6740 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_vendor.h -@@ -0,0 +1,619 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux/include/gl_vendor.h#1 -+*/ -+ -+/*! \file gl_vendor.h -+ \brief This file is for Portable Driver linux gl_vendor support. -+*/ -+ -+/* -+** Log: gl_vendor.h -+** -+** 10 14 2014 -+** add vendor declaration -+** -+ * -+*/ -+ -+#ifndef _GL_VENDOR_H -+#define _GL_VENDOR_H -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "gl_os.h" -+ -+#include "wlan_lib.h" -+#include "gl_wext.h" -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+#define GOOGLE_OUI 0x001A11 -+ -+typedef enum { -+ /* Don't use 0 as a valid subcommand */ -+ ANDROID_NL80211_SUBCMD_UNSPECIFIED, -+ -+ /* Define all vendor startup commands between 0x0 and 0x0FFF */ -+ ANDROID_NL80211_SUBCMD_WIFI_RANGE_START = 0x0001, -+ ANDROID_NL80211_SUBCMD_WIFI_RANGE_END = 0x0FFF, -+ -+ /* Define all GScan related commands between 0x1000 and 0x10FF */ -+ ANDROID_NL80211_SUBCMD_GSCAN_RANGE_START = 0x1000, -+ ANDROID_NL80211_SUBCMD_GSCAN_RANGE_END = 0x10FF, -+ -+ /* Define all RTT related commands between 0x1100 and 0x11FF */ -+ ANDROID_NL80211_SUBCMD_RTT_RANGE_START = 0x1100, -+ ANDROID_NL80211_SUBCMD_RTT_RANGE_END = 0x11FF, -+ -+ ANDROID_NL80211_SUBCMD_LSTATS_RANGE_START = 0x1200, -+ ANDROID_NL80211_SUBCMD_LSTATS_RANGE_END = 0x12FF, -+ -+ /* Define all Logger related commands between 0x1400 and 0x14FF */ -+ ANDROID_NL80211_SUBCMD_DEBUG_RANGE_START = 0x1400, -+ ANDROID_NL80211_SUBCMD_DEBUG_RANGE_END = 0x14FF, -+ -+ /* Define all wifi offload related commands between 0x1600 and 0x16FF */ -+ ANDROID_NL80211_SUBCMD_WIFI_OFFLOAD_RANGE_START = 0x1600, -+ ANDROID_NL80211_SUBCMD_WIFI_OFFLOAD_RANGE_END = 0x16FF, -+ -+ /* This is reserved for future usage */ -+ -+} ANDROID_VENDOR_SUB_COMMAND; -+ -+typedef enum { -+ WIFI_SUBCMD_GET_CHANNEL_LIST = ANDROID_NL80211_SUBCMD_WIFI_RANGE_START, -+ -+ WIFI_SUBCMD_GET_FEATURE_SET, /* 0x0001 */ -+ WIFI_SUBCMD_GET_FEATURE_SET_MATRIX, /* 0x0002 */ -+ WIFI_SUBCMD_SET_PNO_RANDOM_MAC_OUI, /* 0x0003 */ -+ WIFI_SUBCMD_NODFS_SET, /* 0x0004 */ -+ WIFI_SUBCMD_SET_COUNTRY_CODE, /* 0x0005 */ -+ /* Add more sub commands here */ -+ -+} WIFI_SUB_COMMAND; -+ -+typedef enum { -+ GSCAN_SUBCMD_GET_CAPABILITIES = ANDROID_NL80211_SUBCMD_GSCAN_RANGE_START, -+ -+ GSCAN_SUBCMD_SET_CONFIG, /* 0x1001 */ -+ GSCAN_SUBCMD_SET_SCAN_CONFIG, /* 0x1002 */ -+ GSCAN_SUBCMD_ENABLE_GSCAN, /* 0x1003 */ -+ GSCAN_SUBCMD_GET_SCAN_RESULTS, /* 0x1004 */ -+ GSCAN_SUBCMD_SCAN_RESULTS, /* 0x1005 */ -+ -+ GSCAN_SUBCMD_SET_HOTLIST, /* 0x1006 */ -+ -+ GSCAN_SUBCMD_SET_SIGNIFICANT_CHANGE_CONFIG, /* 0x1007 */ -+ GSCAN_SUBCMD_ENABLE_FULL_SCAN_RESULTS, /* 0x1008 */ -+ /* Add more sub commands here */ -+ -+} GSCAN_SUB_COMMAND; -+ -+typedef enum { -+ RTT_SUBCMD_SET_CONFIG = ANDROID_NL80211_SUBCMD_RTT_RANGE_START, -+ RTT_SUBCMD_CANCEL_CONFIG, -+ RTT_SUBCMD_GETCAPABILITY, -+} RTT_SUB_COMMAND; -+ -+typedef enum { -+ LSTATS_SUBCMD_GET_INFO = ANDROID_NL80211_SUBCMD_LSTATS_RANGE_START, -+} LSTATS_SUB_COMMAND; -+ -+typedef enum { -+ GSCAN_EVENT_SIGNIFICANT_CHANGE_RESULTS, -+ GSCAN_EVENT_HOTLIST_RESULTS_FOUND, -+ GSCAN_EVENT_SCAN_RESULTS_AVAILABLE, -+ GSCAN_EVENT_FULL_SCAN_RESULTS, -+ RTT_EVENT_COMPLETE, -+ GSCAN_EVENT_COMPLETE_SCAN, -+ GSCAN_EVENT_HOTLIST_RESULTS_LOST -+} WIFI_VENDOR_EVENT; -+ -+typedef enum { -+ WIFI_ATTRIBUTE_BAND, -+ WIFI_ATTRIBUTE_NUM_CHANNELS, -+ WIFI_ATTRIBUTE_CHANNEL_LIST, -+ -+ WIFI_ATTRIBUTE_NUM_FEATURE_SET, -+ WIFI_ATTRIBUTE_FEATURE_SET, -+ WIFI_ATTRIBUTE_PNO_RANDOM_MAC_OUI, -+ WIFI_ATTRIBUTE_NODFS_VALUE, -+ WIFI_ATTRIBUTE_COUNTRY_CODE -+ -+} WIFI_ATTRIBUTE; -+ -+typedef enum { -+ GSCAN_ATTRIBUTE_CAPABILITIES = 1, -+ -+ GSCAN_ATTRIBUTE_NUM_BUCKETS = 10, -+ GSCAN_ATTRIBUTE_BASE_PERIOD, -+ GSCAN_ATTRIBUTE_BUCKETS_BAND, -+ GSCAN_ATTRIBUTE_BUCKET_ID, -+ GSCAN_ATTRIBUTE_BUCKET_PERIOD, -+ GSCAN_ATTRIBUTE_BUCKET_NUM_CHANNELS, -+ GSCAN_ATTRIBUTE_BUCKET_CHANNELS, -+ GSCAN_ATTRIBUTE_NUM_AP_PER_SCAN, -+ GSCAN_ATTRIBUTE_REPORT_THRESHOLD, -+ GSCAN_ATTRIBUTE_NUM_SCANS_TO_CACHE, -+ -+ GSCAN_ATTRIBUTE_ENABLE_FEATURE = 20, -+ GSCAN_ATTRIBUTE_SCAN_RESULTS_COMPLETE, /* indicates no more results */ -+ GSCAN_ATTRIBUTE_FLUSH_FEATURE, /* Flush all the configs */ -+ GSCAN_ENABLE_FULL_SCAN_RESULTS, -+ GSCAN_ATTRIBUTE_REPORT_EVENTS, -+ -+ GSCAN_ATTRIBUTE_NUM_OF_RESULTS = 30, -+ GSCAN_ATTRIBUTE_FLUSH_RESULTS, -+ GSCAN_ATTRIBUTE_SCAN_RESULTS, /* flat array of wifi_scan_result */ -+ GSCAN_ATTRIBUTE_SCAN_ID, /* indicates scan number */ -+ GSCAN_ATTRIBUTE_SCAN_FLAGS, /* indicates if scan was aborted */ -+ GSCAN_ATTRIBUTE_AP_FLAGS, /* flags on significant change event */ -+ -+ GSCAN_ATTRIBUTE_SSID = 40, -+ GSCAN_ATTRIBUTE_BSSID, -+ GSCAN_ATTRIBUTE_CHANNEL, -+ GSCAN_ATTRIBUTE_RSSI, -+ GSCAN_ATTRIBUTE_TIMESTAMP, -+ GSCAN_ATTRIBUTE_RTT, -+ GSCAN_ATTRIBUTE_RTTSD, -+ -+ GSCAN_ATTRIBUTE_HOTLIST_BSSIDS = 50, -+ GSCAN_ATTRIBUTE_RSSI_LOW, -+ GSCAN_ATTRIBUTE_RSSI_HIGH, -+ GSCAN_ATTRIBUTE_HOTLIST_ELEM, -+ GSCAN_ATTRIBUTE_HOTLIST_FLUSH, -+ -+ GSCAN_ATTRIBUTE_RSSI_SAMPLE_SIZE = 60, -+ GSCAN_ATTRIBUTE_LOST_AP_SAMPLE_SIZE, -+ GSCAN_ATTRIBUTE_MIN_BREACHING, -+ GSCAN_ATTRIBUTE_NUM_AP, -+ GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_BSSIDS, -+ GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_FLUSH -+ -+} GSCAN_ATTRIBUTE; -+ -+typedef enum { -+ RTT_ATTRIBUTE_CAPABILITIES = 1, -+ -+ RTT_ATTRIBUTE_TARGET_CNT = 10, -+ RTT_ATTRIBUTE_TARGET_INFO, -+ RTT_ATTRIBUTE_TARGET_MAC, -+ RTT_ATTRIBUTE_TARGET_TYPE, -+ RTT_ATTRIBUTE_TARGET_PEER, -+ RTT_ATTRIBUTE_TARGET_CHAN, -+ RTT_ATTRIBUTE_TARGET_PERIOD, -+ RTT_ATTRIBUTE_TARGET_NUM_BURST, -+ RTT_ATTRIBUTE_TARGET_NUM_FTM_BURST, -+ RTT_ATTRIBUTE_TARGET_NUM_RETRY_FTM, -+ RTT_ATTRIBUTE_TARGET_NUM_RETRY_FTMR, -+ RTT_ATTRIBUTE_TARGET_LCI, -+ RTT_ATTRIBUTE_TARGET_LCR, -+ RTT_ATTRIBUTE_TARGET_BURST_DURATION, -+ RTT_ATTRIBUTE_TARGET_PREAMBLE, -+ RTT_ATTRIBUTE_TARGET_BW, -+ RTT_ATTRIBUTE_RESULTS_COMPLETE = 30, -+ RTT_ATTRIBUTE_RESULTS_PER_TARGET, -+ RTT_ATTRIBUTE_RESULT_CNT, -+ RTT_ATTRIBUTE_RESULT -+} RTT_ATTRIBUTE; -+ -+typedef enum { -+ LSTATS_ATTRIBUTE_STATS = 2, -+} LSTATS_ATTRIBUTE; -+ -+typedef enum { -+ WIFI_BAND_UNSPECIFIED, -+ WIFI_BAND_BG = 1, /* 2.4 GHz */ -+ WIFI_BAND_A = 2, /* 5 GHz without DFS */ -+ WIFI_BAND_A_DFS = 4, /* 5 GHz DFS only */ -+ WIFI_BAND_A_WITH_DFS = 6, /* 5 GHz with DFS */ -+ WIFI_BAND_ABG = 3, /* 2.4 GHz + 5 GHz; no DFS */ -+ WIFI_BAND_ABG_WITH_DFS = 7, /* 2.4 GHz + 5 GHz with DFS */ -+} WIFI_BAND; -+ -+typedef enum { -+ WIFI_SCAN_BUFFER_FULL, -+ WIFI_SCAN_COMPLETE, -+} WIFI_SCAN_EVENT; -+ -+#define GSCAN_MAX_REPORT_THRESHOLD 1024000 -+#define GSCAN_MAX_CHANNELS 8 -+#define GSCAN_MAX_BUCKETS 8 -+#define MAX_HOTLIST_APS 16 -+#define MAX_SIGNIFICANT_CHANGE_APS 16 -+#define PSCAN_MAX_SCAN_CACHE_SIZE 16 -+#define PSCAN_MAX_AP_CACHE_PER_SCAN 16 -+#define PSCAN_VERSION 1 -+ -+#define MAX_BUFFERED_GSCN_RESULTS 5 -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+typedef UINT_64 wifi_timestamp; /* In microseconds (us) */ -+typedef UINT_64 wifi_timespan; /* In nanoseconds (ns) */ -+ -+typedef UINT_8 mac_addr[6]; -+typedef UINT_32 wifi_channel; /* Indicates channel frequency in MHz */ -+typedef INT_32 wifi_rssi; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+typedef struct _PARAM_WIFI_GSCAN_GET_RESULT_PARAMS { -+ UINT_32 get_num; -+ UINT_8 flush; -+} PARAM_WIFI_GSCAN_GET_RESULT_PARAMS, *P_PARAM_WIFI_GSCAN_GET_RESULT_PARAMS; -+ -+typedef struct _PARAM_WIFI_GSCAN_ACTION_CMD_PARAMS { -+ UINT_8 ucPscanAct; -+ UINT_8 aucReserved[3]; -+} PARAM_WIFI_GSCAN_ACTION_CMD_PARAMS, *P_PARAM_WIFI_GSCAN_ACTION_CMD_PARAMS; -+ -+typedef struct _PARAM_WIFI_GSCAN_CAPABILITIES_STRUCT_T { -+ UINT_32 max_scan_cache_size; /* total space allocated for scan (in bytes) */ -+ UINT_32 max_scan_buckets; /* maximum number of channel buckets */ -+ UINT_32 max_ap_cache_per_scan; /* maximum number of APs that can be stored per scan */ -+ UINT_32 max_rssi_sample_size; /* number of RSSI samples used for averaging RSSI */ -+ UINT_32 max_scan_reporting_threshold; /* max possible report_threshold as described */ -+ /* in wifi_scan_cmd_params */ -+ UINT_32 max_hotlist_aps; /* maximum number of entries for hotlist APs */ -+ UINT_32 max_significant_wifi_change_aps; /* maximum number of entries for */ -+ /* significant wifi change APs */ -+ UINT_32 max_bssid_history_entries; /* number of BSSID/RSSI entries that device can hold */ -+} PARAM_WIFI_GSCAN_CAPABILITIES_STRUCT_T, *P_PARAM_WIFI_GSCAN_CAPABILITIES_STRUCT_T; -+ -+typedef struct _PARAM_WIFI_GSCAN_CHANNEL_SPEC { -+ UINT_32 channel; /* frequency */ -+ UINT_32 dwellTimeMs; /* dwell time hint */ -+ UINT_32 passive; /* 0 => active, 1 => passive scan; ignored for DFS */ -+ /* Add channel class */ -+} PARAM_WIFI_GSCAN_CHANNEL_SPEC, *P_PARAM_WIFI_GSCAN_CHANNEL_SPEC; -+ -+typedef struct _PARAM_WIFI_GSCAN_BUCKET_SPEC { -+ UINT_32 bucket; /* bucket index, 0 based */ -+ WIFI_BAND band; /* when UNSPECIFIED, use channel list */ -+ UINT_32 period; /* desired period, in millisecond; if this is too */ -+ /* low, the firmware should choose to generate results as */ -+ /* fast as it can instead of failing the command */ -+ /* report_events semantics - -+ * 0 => report only when scan history is % full -+ * 1 => same as 0 + report a scan completion event after scanning this bucket -+ * 2 => same as 1 + forward scan results (beacons/probe responses + IEs) in real time to HAL -+ * 3 => same as 2 + forward scan results (beacons/probe responses + IEs) in real time to -+ supplicant as well (optional) . */ -+ UINT_8 report_events; -+ -+ UINT_32 num_channels; -+ PARAM_WIFI_GSCAN_CHANNEL_SPEC channels[GSCAN_MAX_CHANNELS]; /* channels to scan; -+ these may include DFS channels */ -+} PARAM_WIFI_GSCAN_BUCKET_SPEC, *P_PARAM_WIFI_GSCAN_BUCKET_SPEC; -+ -+typedef struct _PARAM_WIFI_GSCAN_CMD_PARAMS { -+ UINT_32 base_period; /* base timer period in ms */ -+ UINT_32 max_ap_per_scan; /* number of APs to store in each scan in the */ -+ /* BSSID/RSSI history buffer (keep the highest RSSI APs) */ -+ UINT_32 report_threshold; /* in %, when scan buffer is this much full, wake up AP */ -+ UINT_32 num_scans; -+ UINT_32 num_buckets; -+ PARAM_WIFI_GSCAN_BUCKET_SPEC buckets[GSCAN_MAX_BUCKETS]; -+} PARAM_WIFI_GSCAN_CMD_PARAMS, *P_PARAM_WIFI_GSCAN_CMD_PARAMS; -+ -+typedef struct _PARAM_WIFI_GSCAN_RESULT { -+ wifi_timestamp ts; /* time since boot (in microsecond) when the result was */ -+ /* retrieved */ -+ UINT_8 ssid[32 + 1]; /* null terminated */ -+ mac_addr bssid; -+ wifi_channel channel; /* channel frequency in MHz */ -+ wifi_rssi rssi; /* in db */ -+ wifi_timespan rtt; /* in nanoseconds */ -+ wifi_timespan rtt_sd; /* standard deviation in rtt */ -+ UINT_16 beacon_period; /* period advertised in the beacon */ -+ UINT_16 capability; /* capabilities advertised in the beacon */ -+ UINT_32 ie_length; /* size of the ie_data blob */ -+ UINT_8 ie_data[1]; /* blob of all the information elements found in the */ -+ /* beacon; this data should be a packed list of */ -+ /* wifi_information_element objects, one after the other. */ -+ /* other fields */ -+} PARAM_WIFI_GSCAN_RESULT, *P_PARAM_WIFI_GSCAN_RESULT; -+ -+/* Significant wifi change*/ -+/*typedef struct _PARAM_WIFI_CHANGE_RESULT{ -+ mac_addr bssid; // BSSID -+ wifi_channel channel; // channel frequency in MHz -+ UINT_32 num_rssi; // number of rssi samples -+ wifi_rssi rssi[8]; // RSSI history in db -+} PARAM_WIFI_CHANGE_RESULT, *P_PARAM_WIFI_CHANGE_RESULT;*/ -+ -+typedef struct _PARAM_WIFI_CHANGE_RESULT { -+ UINT_16 flags; -+ UINT_16 channel; -+ mac_addr bssid; /* BSSID */ -+ INT_8 rssi[8]; /* RSSI history in db */ -+} PARAM_WIFI_CHANGE_RESULT, *P_PARAM_WIFI_CHANGE_RESULT; -+ -+typedef struct _PARAM_AP_THRESHOLD { -+ mac_addr bssid; /* AP BSSID */ -+ wifi_rssi low; /* low threshold */ -+ wifi_rssi high; /* high threshold */ -+ wifi_channel channel; /* channel hint */ -+} PARAM_AP_THRESHOLD, *P_PARAM_AP_THRESHOLD; -+ -+typedef struct _PARAM_WIFI_BSSID_HOTLIST { -+ UINT_32 lost_ap_sample_size; -+ UINT_32 num_ap; /* number of hotlist APs */ -+ PARAM_AP_THRESHOLD ap[MAX_HOTLIST_APS]; /* hotlist APs */ -+} PARAM_WIFI_BSSID_HOTLIST, *P_PARAM_WIFI_BSSID_HOTLIST; -+ -+typedef struct _PARAM_WIFI_SIGNIFICANT_CHANGE { -+ UINT_16 rssi_sample_size; /* number of samples for averaging RSSI */ -+ UINT_16 lost_ap_sample_size; /* number of samples to confirm AP loss */ -+ UINT_16 min_breaching; /* number of APs breaching threshold */ -+ UINT_16 num_ap; /* max 64 */ -+ PARAM_AP_THRESHOLD ap[MAX_SIGNIFICANT_CHANGE_APS]; -+} PARAM_WIFI_SIGNIFICANT_CHANGE, *P_PARAM_WIFI_SIGNIFICANT_CHANGE; -+ -+/* RTT Capabilities */ -+typedef struct _PARAM_WIFI_RTT_CAPABILITIES { -+ UINT_8 rtt_one_sided_supported; /* if 1-sided rtt data collection is supported */ -+ UINT_8 rtt_ftm_supported; /* if ftm rtt data collection is supported */ -+ UINT_8 lci_support; /* if initiator supports LCI request. Applies to 2-sided RTT */ -+ UINT_8 lcr_support; /* if initiator supports LCR request. Applies to 2-sided RTT */ -+ UINT_8 preamble_support; /* bit mask indicates what preamble is supported by initiator */ -+ UINT_8 bw_support; /* bit mask indicates what BW is supported by initiator */ -+} PARAM_WIFI_RTT_CAPABILITIES, *P_PARAM_WIFI_RTT_CAPABILITIES; -+ -+/* channel operating width */ -+typedef enum { -+ WIFI_CHAN_WIDTH_20 = 0, -+ WIFI_CHAN_WIDTH_40 = 1, -+ WIFI_CHAN_WIDTH_80 = 2, -+ WIFI_CHAN_WIDTH_160 = 3, -+ WIFI_CHAN_WIDTH_80P80 = 4, -+ WIFI_CHAN_WIDTH_5 = 5, -+ WIFI_CHAN_WIDTH_10 = 6, -+ WIFI_CHAN_WIDTH_INVALID = -1 -+} WIFI_CHANNEL_WIDTH; -+ -+/* channel information */ -+typedef struct { -+ WIFI_CHANNEL_WIDTH width; /* channel width (20, 40, 80, 80+80, 160) */ -+ UINT_32 center_freq; /* primary 20 MHz channel */ -+ UINT_32 center_freq0; /* center frequency (MHz) first segment */ -+ UINT_32 center_freq1; /* center frequency (MHz) second segment */ -+} WIFI_CHANNEL_INFO; -+ -+/* channel statistics */ -+typedef struct { -+ WIFI_CHANNEL_INFO channel; /* channel */ -+ UINT_32 on_time; /* msecs the radio is awake (32 bits number accruing over time) */ -+ UINT_32 cca_busy_time; /* msecs the CCA register is busy (32 bits number accruing over time) */ -+} WIFI_CHANNEL_STAT; -+ -+/* radio statistics */ -+typedef struct { -+ UINT_32 radio; /* wifi radio (if multiple radio supported) */ -+ UINT_32 on_time; /* msecs the radio is awake (32 bits number accruing over time) */ -+ UINT_32 tx_time; /* msecs the radio is transmitting (32 bits number accruing over time) */ -+ UINT_32 rx_time; /* msecs the radio is in active receive (32 bits number accruing over time) */ -+ UINT_32 on_time_scan; /* msecs the radio is awake due to all scan (32 bits number accruing over time) */ -+ UINT_32 on_time_nbd; /* msecs the radio is awake due to NAN (32 bits number accruing over time) */ -+ UINT_32 on_time_gscan; /* msecs the radio is awake due to G?scan (32 bits number accruing over time) */ -+ UINT_32 on_time_roam_scan; /* msecs the radio is awake due to roam?scan -+ (32 bits number accruing over time) */ -+ UINT_32 on_time_pno_scan; /* msecs the radio is awake due to PNO scan -+ (32 bits number accruing over time) */ -+ UINT_32 on_time_hs20; /* msecs the radio is awake due to HS2.0 scans and GAS exchange -+ 32 bits number accruing over time) */ -+ UINT_32 num_channels; /* number of channels */ -+ WIFI_CHANNEL_STAT channels[]; /* channel statistics */ -+} WIFI_RADIO_STAT; -+ -+/* wifi rate */ -+typedef struct { -+ UINT_32 preamble:3; /* 0: OFDM, 1:CCK, 2:HT 3:VHT 4..7 reserved */ -+ UINT_32 nss:2; /* 0:1x1, 1:2x2, 3:3x3, 4:4x4 */ -+ UINT_32 bw:3; /* 0:20MHz, 1:40Mhz, 2:80Mhz, 3:160Mhz */ -+ UINT_32 rateMcsIdx:8; /* OFDM/CCK rate code would be as per ieee std in the units of 0.5mbps */ -+ /* HT/VHT it would be mcs index */ -+ UINT_32 reserved:16; /* reserved */ -+ UINT_32 bitrate; /* units of 100 Kbps */ -+} WIFI_RATE; -+ -+/* per rate statistics */ -+typedef struct { -+ WIFI_RATE rate; /* rate information */ -+ UINT_32 tx_mpdu; /* number of successfully transmitted data pkts (ACK rcvd) */ -+ UINT_32 rx_mpdu; /* number of received data pkts */ -+ UINT_32 mpdu_lost; /* number of data packet losses (no ACK) */ -+ UINT_32 retries; /* total number of data pkt retries */ -+ UINT_32 retries_short; /* number of short data pkt retries */ -+ UINT_32 retries_long; /* number of long data pkt retries */ -+} WIFI_RATE_STAT; -+ -+/*wifi_interface_link_layer_info*/ -+typedef enum { -+ WIFI_DISCONNECTED = 0, -+ WIFI_AUTHENTICATING = 1, -+ WIFI_ASSOCIATING = 2, -+ WIFI_ASSOCIATED = 3, -+ WIFI_EAPOL_STARTED = 4, /* if done by firmware/driver */ -+ WIFI_EAPOL_COMPLETED = 5, /* if done by firmware/driver */ -+} WIFI_CONNECTION_STATE; -+ -+typedef enum { -+ WIFI_ROAMING_IDLE = 0, -+ WIFI_ROAMING_ACTIVE = 1, -+} WIFI_ROAM_STATE; -+ -+typedef enum { -+ WIFI_INTERFACE_STA = 0, -+ WIFI_INTERFACE_SOFTAP = 1, -+ WIFI_INTERFACE_IBSS = 2, -+ WIFI_INTERFACE_P2P_CLIENT = 3, -+ WIFI_INTERFACE_P2P_GO = 4, -+ WIFI_INTERFACE_NAN = 5, -+ WIFI_INTERFACE_MESH = 6, -+ WIFI_INTERFACE_UNKNOWN = -1 -+} WIFI_INTERFACE_MODE; -+ -+typedef struct { -+ WIFI_INTERFACE_MODE mode; /* interface mode */ -+ u8 mac_addr[6]; /* interface mac address (self) */ -+ WIFI_CONNECTION_STATE state; /* connection state (valid for STA, CLI only) */ -+ WIFI_ROAM_STATE roaming; /* roaming state */ -+ u32 capabilities; /* WIFI_CAPABILITY_XXX (self) */ -+ u8 ssid[33]; /* null terminated SSID */ -+ u8 bssid[6]; /* bssid */ -+ u8 ap_country_str[3]; /* country string advertised by AP */ -+ u8 country_str[3]; /* country string for this association */ -+} WIFI_INTERFACE_LINK_LAYER_INFO; -+ -+/* access categories */ -+typedef enum { -+ WIFI_AC_VO = 0, -+ WIFI_AC_VI = 1, -+ WIFI_AC_BE = 2, -+ WIFI_AC_BK = 3, -+ WIFI_AC_MAX = 4, -+} WIFI_TRAFFIC_AC; -+ -+/* wifi peer type */ -+typedef enum { -+ WIFI_PEER_STA, -+ WIFI_PEER_AP, -+ WIFI_PEER_P2P_GO, -+ WIFI_PEER_P2P_CLIENT, -+ WIFI_PEER_NAN, -+ WIFI_PEER_TDLS, -+ WIFI_PEER_INVALID, -+} WIFI_PEER_TYPE; -+ -+/* per peer statistics */ -+typedef struct { -+ WIFI_PEER_TYPE type; /* peer type (AP, TDLS, GO etc.) */ -+ UINT_8 peer_mac_address[6]; /* mac address */ -+ UINT_32 capabilities; /* peer WIFI_CAPABILITY_XXX */ -+ UINT_32 num_rate; /* number of rates */ -+ WIFI_RATE_STAT rate_stats[]; /* per rate statistics, number of entries = num_rate */ -+} WIFI_PEER_INFO; -+ -+/* per access category statistics */ -+typedef struct { -+ WIFI_TRAFFIC_AC ac; /* access category (VI, VO, BE, BK) */ -+ UINT_32 tx_mpdu; /* number of successfully transmitted unicast data pkts (ACK rcvd) */ -+ UINT_32 rx_mpdu; /* number of received unicast mpdus */ -+ UINT_32 tx_mcast; /* number of successfully transmitted multicast data packets */ -+ /* STA case: implies ACK received from AP for the unicast packet in which mcast pkt was sent */ -+ UINT_32 rx_mcast; /* number of received multicast data packets */ -+ UINT_32 rx_ampdu; /* number of received unicast a-mpdus */ -+ UINT_32 tx_ampdu; /* number of transmitted unicast a-mpdus */ -+ UINT_32 mpdu_lost; /* number of data pkt losses (no ACK) */ -+ UINT_32 retries; /* total number of data pkt retries */ -+ UINT_32 retries_short; /* number of short data pkt retries */ -+ UINT_32 retries_long; /* number of long data pkt retries */ -+ UINT_32 contention_time_min; /* data pkt min contention time (usecs) */ -+ UINT_32 contention_time_max; /* data pkt max contention time (usecs) */ -+ UINT_32 contention_time_avg; /* data pkt avg contention time (usecs) */ -+ UINT_32 contention_num_samples; /* num of data pkts used for contention statistics */ -+} WIFI_WMM_AC_STAT; -+ -+/* interface statistics */ -+typedef struct { -+ /* wifi_interface_handle iface; // wifi interface */ -+ WIFI_INTERFACE_LINK_LAYER_INFO info; /* current state of the interface */ -+ UINT_32 beacon_rx; /* access point beacon received count from connected AP */ -+ UINT_32 mgmt_rx; /* access point mgmt frames received count from connected AP (including Beacon) */ -+ UINT_32 mgmt_action_rx; /* action frames received count */ -+ UINT_32 mgmt_action_tx; /* action frames transmit count */ -+ wifi_rssi rssi_mgmt; /* access Point Beacon and Management frames RSSI (averaged) */ -+ wifi_rssi rssi_data; /* access Point Data Frames RSSI (averaged) from connected AP */ -+ wifi_rssi rssi_ack; /* access Point ACK RSSI (averaged) from connected AP */ -+ WIFI_WMM_AC_STAT ac[WIFI_AC_MAX]; /* per ac data packet statistics */ -+ UINT_32 num_peers; /* number of peers */ -+ WIFI_PEER_INFO peer_info[]; /* per peer statistics */ -+} WIFI_IFACE_STAT; -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+int mtk_cfg80211_vendor_get_channel_list(struct wiphy *wiphy, struct wireless_dev *wdev, -+ const void *data, int data_len); -+ -+int mtk_cfg80211_vendor_set_country_code(struct wiphy *wiphy, struct wireless_dev *wdev, -+ const void *data, int data_len); -+ -+int mtk_cfg80211_vendor_get_gscan_capabilities(struct wiphy *wiphy, struct wireless_dev *wdev, -+ const void *data, int data_len); -+ -+int mtk_cfg80211_vendor_set_config(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int data_len); -+ -+int mtk_cfg80211_vendor_set_scan_config(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int data_len); -+ -+int mtk_cfg80211_vendor_set_significant_change(struct wiphy *wiphy, struct wireless_dev *wdev, -+ const void *data, int data_len); -+ -+int mtk_cfg80211_vendor_set_hotlist(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int data_len); -+ -+int mtk_cfg80211_vendor_enable_scan(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int data_len); -+ -+int mtk_cfg80211_vendor_enable_full_scan_results(struct wiphy *wiphy, struct wireless_dev *wdev, -+ const void *data, int data_len); -+ -+int mtk_cfg80211_vendor_get_scan_results(struct wiphy *wiphy, struct wireless_dev *wdev, -+ const void *data, int data_len); -+ -+int mtk_cfg80211_vendor_get_rtt_capabilities(struct wiphy *wiphy, struct wireless_dev *wdev, -+ const void *data, int data_len); -+ -+int mtk_cfg80211_vendor_llstats_get_info(struct wiphy *wiphy, struct wireless_dev *wdev, -+ const void *data, int data_len); -+ -+int mtk_cfg80211_vendor_event_complete_scan(struct wiphy *wiphy, struct wireless_dev *wdev, WIFI_SCAN_EVENT complete); -+ -+int mtk_cfg80211_vendor_event_scan_results_available(struct wiphy *wiphy, struct wireless_dev *wdev, UINT_32 num); -+ -+int mtk_cfg80211_vendor_event_full_scan_results(struct wiphy *wiphy, struct wireless_dev *wdev, -+ P_PARAM_WIFI_GSCAN_RESULT pdata, UINT_32 data_len); -+ -+int mtk_cfg80211_vendor_event_significant_change_results(struct wiphy *wiphy, struct wireless_dev *wdev, -+ P_PARAM_WIFI_CHANGE_RESULT pdata, UINT_32 data_len); -+ -+int mtk_cfg80211_vendor_event_hotlist_ap_found(struct wiphy *wiphy, struct wireless_dev *wdev, -+ P_PARAM_WIFI_GSCAN_RESULT pdata, UINT_32 data_len); -+ -+int mtk_cfg80211_vendor_event_hotlist_ap_lost(struct wiphy *wiphy, struct wireless_dev *wdev, -+ P_PARAM_WIFI_GSCAN_RESULT pdata, UINT_32 data_len); -+ -+#endif /* _GL_VENDOR_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_wext.h b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_wext.h -new file mode 100644 -index 000000000000..827ff92b1581 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_wext.h -@@ -0,0 +1,357 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux/include/gl_wext.h#1 -+*/ -+ -+/*! \file gl_wext.h -+ \brief This file is for Portable Driver linux wireless extension support. -+*/ -+ -+/* -+** Log: gl_wext.h -+ * -+ * 10 12 2011 wh.su -+ * [WCXRP00001036] [MT6620 Wi-Fi][Driver][FW] Adding the 802.11w code for MFP -+ * adding the 802.11w related function and define . -+ * -+ * 09 20 2011 chinglan.wang -+ * [WCXRP00000989] [WiFi Direct] [Driver] Add a new io control API to start the formation for the sigma test. -+ * . -+ * -+ * 09 20 2011 chinglan.wang -+ * [WCXRP00000989] [WiFi Direct] [Driver] Add a new io control API to start the formation for the sigma test. -+ * . -+ * -+ * 01 11 2011 chinglan.wang -+ * NULL -+ * Modify to reslove the CR :[ALPS00028994] Use WEP security to connect Marvell 11N AP. -+ * Connection establish successfully. -+ * Use the WPS function to connect AP, the privacy bit always is set to 1. . -+ * -+ * 09 27 2010 wh.su -+ * NULL -+ * [WCXRP00000067][MT6620 Wi-Fi][Driver] Support the android+ WAPI function. -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 03 31 2010 wh.su -+ * [WPD00003816][MT6620 Wi-Fi] Adding the security support -+ * modify the wapi related code for new driver's design. -+ * -+ * 03 24 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * initial import for Linux port -+** \main\maintrunk.MT5921\12 2009-10-20 17:38:33 GMT mtk01090 -+** Refine driver unloading and clean up procedure. Block requests, stop main thread and clean up queued requests, -+** and then stop hw. -+** \main\maintrunk.MT5921\11 2009-09-28 20:19:28 GMT mtk01090 -+** Add private ioctl to carry OID structures. Restructure public/private ioctl interfaces to Linux kernel. -+** \main\maintrunk.MT5921\10 2009-09-03 12:12:35 GMT mtk01088 -+** adding the function declaration -+** \main\maintrunk.MT5921\9 2009-08-18 22:57:17 GMT mtk01090 -+** Add Linux SDIO (with mmc core) support. -+** Add Linux 2.6.21, 2.6.25, 2.6.26. -+** Fix compile warning in Linux. -+** \main\maintrunk.MT5921\8 2008-08-29 16:59:07 GMT mtk01088 -+** fixed compiling error -+** \main\maintrunk.MT5921\7 2008-08-29 14:13:28 GMT mtk01088 -+** adjust the header file for code refine -+** \main\maintrunk.MT5921\6 2008-03-28 10:40:31 GMT mtk01461 -+** Add set desired rate in Linux STD IOCTL -+** \main\maintrunk.MT5921\5 2008-03-11 14:51:08 GMT mtk01461 -+** Refine private IOCTL functions -+** \main\maintrunk.MT5921\4 2008-02-12 23:45:45 GMT mtk01461 -+** Add Set Frequency & Channel oid support for Linux -+** \main\maintrunk.MT5921\3 2007-11-06 19:36:19 GMT mtk01088 -+** add the WPS related code -+*/ -+ -+#ifndef _GL_WEXT_H -+#define _GL_WEXT_H -+ -+#ifdef WIRELESS_EXT -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+#define KILO 1000 -+#define RATE_5_5M 11 /* 5.5M */ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+typedef struct _PARAM_FIXED_IEs { -+ UINT_8 aucTimestamp[8]; -+ UINT_16 u2BeaconInterval; -+ UINT_16 u2Capabilities; -+} PARAM_FIXED_IEs; -+ -+typedef struct _PARAM_VARIABLE_IE_T { -+ UINT_8 ucElementID; -+ UINT_8 ucLength; -+ UINT_8 aucData[1]; -+} PARAM_VARIABLE_IE_T, *P_PARAM_VARIABLE_IE_T; -+ -+#if WIRELESS_EXT < 18 -+ -+#define SIOCSIWMLME 0x8B16 /* request MLME operation; uses struct iw_mlme */ -+/* MLME requests (SIOCSIWMLME / struct iw_mlme) */ -+#define IW_MLME_DEAUTH 0 -+#define IW_MLME_DISASSOC 1 -+ -+/*! \brief SIOCSIWMLME data */ -+struct iw_mlme { -+ __u16 cmd; /*!< IW_MLME_* */ -+ __u16 reason_code; -+ struct sockaddr addr; -+}; -+ -+#define SIOCSIWAUTH 0x8B32 /* set authentication mode params */ -+#define SIOCGIWAUTH 0x8B33 /* get authentication mode params */ -+/* SIOCSIWAUTH/SIOCGIWAUTH struct iw_param flags */ -+#define IW_AUTH_INDEX 0x0FFF -+#define IW_AUTH_FLAGS 0xF000 -+/* SIOCSIWAUTH/SIOCGIWAUTH parameters (0 .. 4095) -+ * (IW_AUTH_INDEX mask in struct iw_param flags; this is the index of the -+ * parameter that is being set/get to; value will be read/written to -+ * struct iw_param value field) */ -+#define IW_AUTH_WPA_VERSION 0 -+#define IW_AUTH_CIPHER_PAIRWISE 1 -+#define IW_AUTH_CIPHER_GROUP 2 -+#define IW_AUTH_KEY_MGMT 3 -+#define IW_AUTH_TKIP_COUNTERMEASURES 4 -+#define IW_AUTH_DROP_UNENCRYPTED 5 -+#define IW_AUTH_80211_AUTH_ALG 6 -+#define IW_AUTH_WPA_ENABLED 7 -+#define IW_AUTH_RX_UNENCRYPTED_EAPOL 8 -+#define IW_AUTH_ROAMING_CONTROL 9 -+#define IW_AUTH_PRIVACY_INVOKED 10 -+#if CFG_SUPPORT_802_11W -+#define IW_AUTH_MFP 12 -+ -+#define IW_AUTH_MFP_DISABLED 0 /* MFP disabled */ -+#define IW_AUTH_MFP_OPTIONAL 1 /* MFP optional */ -+#define IW_AUTH_MFP_REQUIRED 2 /* MFP required */ -+#endif -+ -+/* IW_AUTH_WPA_VERSION values (bit field) */ -+#define IW_AUTH_WPA_VERSION_DISABLED 0x00000001 -+#define IW_AUTH_WPA_VERSION_WPA 0x00000002 -+#define IW_AUTH_WPA_VERSION_WPA2 0x00000004 -+ -+/* IW_AUTH_PAIRWISE_CIPHER and IW_AUTH_GROUP_CIPHER values (bit field) */ -+#define IW_AUTH_CIPHER_NONE 0x00000001 -+#define IW_AUTH_CIPHER_WEP40 0x00000002 -+#define IW_AUTH_CIPHER_TKIP 0x00000004 -+#define IW_AUTH_CIPHER_CCMP 0x00000008 -+#define IW_AUTH_CIPHER_WEP104 0x00000010 -+ -+/* IW_AUTH_KEY_MGMT values (bit field) */ -+#define IW_AUTH_KEY_MGMT_802_1X 1 -+#define IW_AUTH_KEY_MGMT_PSK 2 -+#define IW_AUTH_KEY_MGMT_WPA_NONE 4 -+ -+/* IW_AUTH_80211_AUTH_ALG values (bit field) */ -+#define IW_AUTH_ALG_OPEN_SYSTEM 0x00000001 -+#define IW_AUTH_ALG_SHARED_KEY 0x00000002 -+#define IW_AUTH_ALG_LEAP 0x00000004 -+ -+/* IW_AUTH_ROAMING_CONTROL values */ -+#define IW_AUTH_ROAMING_ENABLE 0 /* driver/firmware based roaming */ -+#define IW_AUTH_ROAMING_DISABLE 1 /* user space program used for roaming -+ * control */ -+ -+#define SIOCSIWENCODEEXT 0x8B34 /* set encoding token & mode */ -+#define SIOCGIWENCODEEXT 0x8B35 /* get encoding token & mode */ -+/* SIOCSIWENCODEEXT definitions */ -+#define IW_ENCODE_SEQ_MAX_SIZE 8 -+/* struct iw_encode_ext ->alg */ -+#define IW_ENCODE_ALG_NONE 0 -+#define IW_ENCODE_ALG_WEP 1 -+#define IW_ENCODE_ALG_TKIP 2 -+#define IW_ENCODE_ALG_CCMP 3 -+#if CFG_SUPPORT_802_11W -+#define IW_ENCODE_ALG_AES_CMAC 5 -+#endif -+ -+/* struct iw_encode_ext ->ext_flags */ -+#define IW_ENCODE_EXT_TX_SEQ_VALID 0x00000001 -+#define IW_ENCODE_EXT_RX_SEQ_VALID 0x00000002 -+#define IW_ENCODE_EXT_GROUP_KEY 0x00000004 -+#define IW_ENCODE_EXT_SET_TX_KEY 0x00000008 -+ -+struct iw_encode_ext { -+ __u32 ext_flags; /*!< IW_ENCODE_EXT_* */ -+ __u8 tx_seq[IW_ENCODE_SEQ_MAX_SIZE]; /*!< LSB first */ -+ __u8 rx_seq[IW_ENCODE_SEQ_MAX_SIZE]; /*!< LSB first */ -+ struct sockaddr addr; /*!< ff:ff:ff:ff:ff:ff for broadcast/multicast -+ * (group) keys or unicast address for -+ * individual keys */ -+ __u16 alg; /*!< IW_ENCODE_ALG_* */ -+ __u16 key_len; -+ __u8 key[0]; -+}; -+ -+#define SIOCSIWPMKSA 0x8B36 /* PMKSA cache operation */ -+#define IW_PMKSA_ADD 1 -+#define IW_PMKSA_REMOVE 2 -+#define IW_PMKSA_FLUSH 3 -+ -+#define IW_PMKID_LEN 16 -+ -+struct iw_pmksa { -+ __u32 cmd; /*!< IW_PMKSA_* */ -+ struct sockaddr bssid; -+ __u8 pmkid[IW_PMKID_LEN]; -+}; -+ -+#define IWEVGENIE 0x8C05 /* Generic IE (WPA, RSN, WMM, ..) -+ * (scan results); This includes id and -+ * length fields. One IWEVGENIE may -+ * contain more than one IE. Scan -+ * results may contain one or more -+ * IWEVGENIE events. */ -+#define IWEVMICHAELMICFAILURE 0x8C06 /* Michael MIC failure -+ * (struct iw_michaelmicfailure) -+ */ -+#define IWEVASSOCREQIE 0x8C07 /* IEs used in (Re)Association Request. -+ * The data includes id and length -+ * fields and may contain more than one -+ * IE. This event is required in -+ * Managed mode if the driver -+ * generates its own WPA/RSN IE. This -+ * should be sent just before -+ * IWEVREGISTERED event for the -+ * association. */ -+#define IWEVASSOCRESPIE 0x8C08 /* IEs used in (Re)Association -+ * Response. The data includes id and -+ * length fields and may contain more -+ * than one IE. This may be sent -+ * between IWEVASSOCREQIE and -+ * IWEVREGISTERED events for the -+ * association. */ -+#define IWEVPMKIDCAND 0x8C09 /* PMKID candidate for RSN -+ * pre-authentication -+ * (struct iw_pmkid_cand) */ -+ -+#endif /* WIRELESS_EXT < 18 */ -+ -+#if WIRELESS_EXT < 17 -+/* Statistics flags (bitmask in updated) */ -+#define IW_QUAL_QUAL_UPDATED 0x1 /* Value was updated since last read */ -+#define IW_QUAL_LEVEL_UPDATED 0x2 -+#define IW_QUAL_NOISE_UPDATED 0x4 -+#define IW_QUAL_QUAL_INVALID 0x10 /* Driver doesn't provide value */ -+#define IW_QUAL_LEVEL_INVALID 0x20 -+#define IW_QUAL_NOISE_INVALID 0x40 -+#endif -+ -+enum { -+ IEEE80211_FILTER_TYPE_BEACON = 1 << 0, -+ IEEE80211_FILTER_TYPE_PROBE_REQ = 1 << 1, -+ IEEE80211_FILTER_TYPE_PROBE_RESP = 1 << 2, -+ IEEE80211_FILTER_TYPE_ASSOC_REQ = 1 << 3, -+ IEEE80211_FILTER_TYPE_ASSOC_RESP = 1 << 4, -+ IEEE80211_FILTER_TYPE_AUTH = 1 << 5, -+ IEEE80211_FILTER_TYPE_DEAUTH = 1 << 6, -+ IEEE80211_FILTER_TYPE_DISASSOC = 1 << 7, -+ IEEE80211_FILTER_TYPE_ALL = 0xFF /* used to check the valid filter bits */ -+}; -+ -+#if CFG_SUPPORT_WAPI -+#define IW_AUTH_WAPI_ENABLED 0x20 -+#define IW_ENCODE_ALG_SMS4 0x20 -+#endif -+ -+#if CFG_SUPPORT_WAPI /* Android+ */ -+#define IW_AUTH_KEY_MGMT_WAPI_PSK 3 -+#define IW_AUTH_KEY_MGMT_WAPI_CERT 4 -+#endif -+#define IW_AUTH_KEY_MGMT_WPS 5 -+ -+#if CFG_SUPPORT_802_11W -+#define IW_AUTH_KEY_MGMT_802_1X_SHA256 7 -+#define IW_AUTH_KEY_MGMT_PSK_SHA256 8 -+#endif -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+extern const struct iw_handler_def wext_handler_def; -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+/* wireless extensions' ioctls */ -+int wext_support_ioctl(IN struct net_device *prDev, IN struct ifreq *prIfReq, IN int i4Cmd); -+ -+int -+wext_set_rate(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwReqInfo, IN struct iw_param *prRate, IN char *pcExtra); -+ -+void -+wext_indicate_wext_event(IN P_GLUE_INFO_T prGlueInfo, -+ IN unsigned int u4Cmd, IN unsigned char *pucData, IN unsigned int u4DataLen); -+ -+struct iw_statistics *wext_get_wireless_stats(struct net_device *prDev); -+ -+BOOLEAN -+wextSrchDesiredWPAIE(IN PUINT_8 pucIEStart, -+ IN INT_32 i4TotalIeLen, IN UINT_8 ucDesiredElemId, OUT PUINT_8 *ppucDesiredIE); -+ -+#if CFG_SUPPORT_WPS -+BOOLEAN -+wextSrchDesiredWPSIE(IN PUINT_8 pucIEStart, -+ IN INT_32 i4TotalIeLen, IN UINT_8 ucDesiredElemId, OUT PUINT_8 *ppucDesiredIE); -+#endif -+ -+#if CFG_SUPPORT_HOTSPOT_2_0 -+BOOLEAN wextSrchDesiredHS20IE(IN PUINT_8 pucIEStart, IN INT_32 i4TotalIeLen, OUT PUINT_8 *ppucDesiredIE); -+ -+BOOLEAN wextSrchDesiredInterworkingIE(IN PUINT_8 pucIEStart, IN INT_32 i4TotalIeLen, OUT PUINT_8 *ppucDesiredIE); -+ -+BOOLEAN wextSrchDesiredAdvProtocolIE(IN PUINT_8 pucIEStart, IN INT_32 i4TotalIeLen, OUT PUINT_8 *ppucDesiredIE); -+ -+BOOLEAN wextSrchDesiredRoamingConsortiumIE(IN PUINT_8 pucIEStart, IN INT_32 i4TotalIeLen, OUT PUINT_8 *ppucDesiredIE); -+#endif -+ -+#if CFG_SUPPORT_WAPI -+BOOLEAN wextSrchDesiredWAPIIE(IN PUINT_8 pucIEStart, IN INT_32 i4TotalIeLen, OUT PUINT_8 *ppucDesiredIE); -+#endif -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif /* WIRELESS_EXT */ -+ -+#endif /* _GL_WEXT_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_wext_priv.h b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_wext_priv.h -new file mode 100644 -index 000000000000..31933fc6a461 ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_wext_priv.h -@@ -0,0 +1,402 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux/include/gl_wext_priv.h#3 -+*/ -+ -+/*! \file gl_wext_priv.h -+ \brief This file includes private ioctl support. -+*/ -+ -+/* -+** Log: gl_wext_priv.h -+ * -+ * 01 16 2012 wh.su -+ * [WCXRP00001170] [MT6620 Wi-Fi][Driver] Adding the related code for set/get band ioctl -+ * Adding the template code for set / get band IOCTL (with ICS supplicant_6).. -+ * -+ * 01 05 2012 wh.su -+ * [WCXRP00001153] [MT6620 Wi-Fi][Driver] Adding the get_ch_list and set_tx_power proto type function -+ * Adding the related ioctl / wlan oid function to set the Tx power cfg. -+ * -+ * 01 02 2012 wh.su -+ * [WCXRP00001153] [MT6620 Wi-Fi][Driver] Adding the get_ch_list and set_tx_power proto type function -+ * Adding the proto type function for set_int set_tx_power and get int get_ch_list. -+ * -+ * 11 08 2011 yuche.tsai -+ * [WCXRP00001094] [Volunteer Patch][Driver] Driver version & supplicant version query & set support for service -+ * discovery version check. -+ * Add a CMD ID for P2P driver version query. -+ * -+ * 03 17 2011 chinglan.wang -+ * [WCXRP00000570] [MT6620 Wi-Fi][Driver] Add Wi-Fi Protected Setup v2.0 feature -+ * . -+ * -+ * 03 02 2011 wh.su -+ * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code -+ * Add security check code. -+ * -+ * 01 27 2011 cm.chang -+ * [WCXRP00000402] [MT6620 Wi-Fi][Driver] Enable MCR read/write by iwpriv by default -+ * . -+ * -+ * 01 20 2011 eddie.chen -+ * [WCXRP00000374] [MT6620 Wi-Fi][DRV] SW debug control -+ * Add Oid for sw control debug command -+ * -+ * 01 07 2011 cm.chang -+ * [WCXRP00000336] [MT6620 Wi-Fi][Driver] Add test mode commands in normal phone operation -+ * Add a new compiling option to control if MCR read/write is permitted -+ * -+ * 12 31 2010 cm.chang -+ * [WCXRP00000336] [MT6620 Wi-Fi][Driver] Add test mode commands in normal phone operation -+ * Add some iwpriv commands to support test mode operation -+ * -+ * 11 08 2010 wh.su -+ * [WCXRP00000171] [MT6620 Wi-Fi][Driver] Add message check code same behavior as mt5921 -+ * add the message check code from mt5921. -+ * -+ * 10 18 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000086] [MT6620 Wi-Fi][Driver] -+ * The mac address is all zero at android -+ * complete implementation of Android NVRAM access -+ * -+ * 09 23 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check -+ * add skeleton for NVRAM integration -+ * -+ * 08 04 2010 cp.wu -+ * NULL -+ * revert changelist #15371, efuse read/write access will be done by RF test approach -+ * -+ * 08 04 2010 cp.wu -+ * NULL -+ * add OID definitions for EFUSE read/write access. -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+ * -+ * 03 31 2010 wh.su -+ * [WPD00003816][MT6620 Wi-Fi] Adding the security support -+ * modify the wapi related code for new driver's design. -+ * -+ * 03 24 2010 jeffrey.chang -+ * [WPD00003826]Initial import for Linux port -+ * initial import for Linux port -+** \main\maintrunk.MT5921\16 2009-09-29 16:47:23 GMT mtk01090 -+** Remove unused functions -+** \main\maintrunk.MT5921\15 2009-09-28 20:19:31 GMT mtk01090 -+** Add private ioctl to carry OID structures. Restructure public/private ioctl interfaces to Linux kernel. -+** \main\maintrunk.MT5921\14 2009-05-07 22:26:06 GMT mtk01089 -+** add private IO control for Linux BWCS -+** \main\maintrunk.MT5921\13 2008-08-29 14:55:20 GMT mtk01088 -+** adjust the code to meet coding style -+** \main\maintrunk.MT5921\12 2008-07-16 15:23:45 GMT mtk01104 -+** Support GPIO2 mode -+** \main\maintrunk.MT5921\11 2008-07-14 13:55:58 GMT mtk01104 -+** Support PRIV_CMD_BT_COEXIST -+** \main\maintrunk.MT5921\10 2008-07-09 00:20:24 GMT mtk01461 -+** Add priv oid to support WMM_PS_TEST -+** \main\maintrunk.MT5921\9 2008-05-30 20:27:24 GMT mtk01461 -+** Add POWER_MODE Private IOCTL cmd -+** \main\maintrunk.MT5921\8 2008-04-17 23:06:44 GMT mtk01461 -+** Add iwpriv support for AdHocMode setting -+** \main\maintrunk.MT5921\7 2008-03-31 21:01:24 GMT mtk01461 -+** Add priv IOCTL for VOIP settings -+** \main\maintrunk.MT5921\6 2008-03-31 13:49:47 GMT mtk01461 -+** add priv ioctl arg definition for turning on / off roaming -+** \main\maintrunk.MT5921\5 2008-03-26 15:35:09 GMT mtk01461 -+** Add CSUM offload priv ioctl for Linux -+** \main\maintrunk.MT5921\4 2008-03-11 14:51:11 GMT mtk01461 -+** Refine private IOCTL functions -+** \main\maintrunk.MT5921\3 2007-11-06 19:36:25 GMT mtk01088 -+** add the WPS related code -+*/ -+ -+#ifndef _GL_WEXT_PRIV_H -+#define _GL_WEXT_PRIV_H -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+/* If it is set to 1, iwpriv will support register read/write */ -+#define CFG_SUPPORT_PRIV_MCR_RW 1 -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+#if CFG_ENABLE_WIFI_DIRECT -+extern int set_p2p_mode_handler(struct net_device *netdev, PARAM_CUSTOM_P2P_SET_STRUCT_T p2pmode); -+#if 0 -+extern BOOLEAN fgIsResetting; -+extern BOOLEAN g_u4HaltFlag; -+extern spinlock_t g_p2p_lock; -+extern int g_u4P2PEnding; -+extern int g_u4P2POnOffing; -+#endif -+#endif -+ -+ -+#if (CFG_SUPPORT_TXR_ENC == 1) -+extern VOID rlmCmd(P_GLUE_INFO_T prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen); -+#endif /* CFG_SUPPORT_TXR_ENC */ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+/* New wireless extensions API - SET/GET convention (even ioctl numbers are -+ * root only) -+ */ -+#define IOCTL_SET_INT (SIOCIWFIRSTPRIV + 0) -+#define IOCTL_GET_INT (SIOCIWFIRSTPRIV + 1) -+ -+#define IOCTL_SET_ADDRESS (SIOCIWFIRSTPRIV + 2) -+#define IOCTL_GET_ADDRESS (SIOCIWFIRSTPRIV + 3) -+#define IOCTL_SET_STR (SIOCIWFIRSTPRIV + 4) -+#define IOCTL_GET_STR (SIOCIWFIRSTPRIV + 5) -+#define IOCTL_SET_KEY (SIOCIWFIRSTPRIV + 6) -+#define IOCTL_GET_KEY (SIOCIWFIRSTPRIV + 7) -+#define IOCTL_SET_STRUCT (SIOCIWFIRSTPRIV + 8) -+#define IOCTL_GET_STRUCT (SIOCIWFIRSTPRIV + 9) -+#define IOCTL_SET_STRUCT_FOR_EM (SIOCIWFIRSTPRIV + 11) -+#define IOCTL_SET_INTS (SIOCIWFIRSTPRIV + 12) -+#define IOCTL_GET_INTS (SIOCIWFIRSTPRIV + 13) -+#define IOCTL_SET_STRING (SIOCIWFIRSTPRIV + 14) -+ -+#define PRIV_CMD_REG_DOMAIN 0 -+#define PRIV_CMD_BEACON_PERIOD 1 -+#define PRIV_CMD_ADHOC_MODE 2 -+ -+#if CFG_TCP_IP_CHKSUM_OFFLOAD -+#define PRIV_CMD_CSUM_OFFLOAD 3 -+#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */ -+ -+#define PRIV_CMD_ROAMING 4 -+#define PRIV_CMD_VOIP_DELAY 5 -+#define PRIV_CMD_POWER_MODE 6 -+ -+#define PRIV_CMD_WMM_PS 7 -+#define PRIV_CMD_BT_COEXIST 8 -+#define PRIV_GPIO2_MODE 9 -+ -+#define PRIV_CUSTOM_SET_PTA 10 -+#define PRIV_CUSTOM_CONTINUOUS_POLL 11 -+#define PRIV_CUSTOM_SINGLE_ANTENNA 12 -+#define PRIV_CUSTOM_BWCS_CMD 13 -+#define PRIV_CUSTOM_DISABLE_BEACON_DETECTION 14 /* later */ -+#define PRIV_CMD_OID 15 -+#define PRIV_SEC_MSG_OID 16 -+ -+#define PRIV_CMD_TEST_MODE 17 -+#define PRIV_CMD_TEST_CMD 18 -+#define PRIV_CMD_ACCESS_MCR 19 -+#define PRIV_CMD_SW_CTRL 20 -+ -+#if 1 /* ANTI_PRIVCY */ -+#define PRIV_SEC_CHECK_OID 21 -+#endif -+ -+#define PRIV_CMD_WSC_PROBE_REQ 22 -+ -+#define PRIV_CMD_P2P_VERSION 23 -+ -+#define PRIV_CMD_GET_CH_LIST 24 -+ -+#define PRIV_CMD_SET_TX_POWER 25 -+ -+#define PRIV_CMD_BAND_CONFIG 26 -+ -+#define PRIV_CMD_DUMP_MEM 27 -+ -+#define PRIV_CMD_P2P_MODE 28 -+ -+#define PRIV_CMD_GET_BUILD_DATE_CODE 29 -+ -+#define PRIV_CMD_GET_DEBUG_CODE 30 -+ -+#define PRIV_CMD_OTHER 31 -+ -+#define PRIV_CMD_WFD_DEBUG_CODE 32 -+ -+#define PRIV_CMD_MET_PROFILING 33 -+ -+/* other string command ID */ -+#define PRIV_CMD_OTHER_TDLS 0x00 -+#define PRIV_CMD_OTHER_TAR 0x01 /* TX auto rate */ -+ -+/* 802.3 Objects (Ethernet) */ -+#define OID_802_3_CURRENT_ADDRESS 0x01010102 -+ -+/* IEEE 802.11 OIDs */ -+#define OID_802_11_SUPPORTED_RATES 0x0D01020E -+#define OID_802_11_CONFIGURATION 0x0D010211 -+ -+/* PnP and PM OIDs, NDIS default OIDS */ -+#define OID_PNP_SET_POWER 0xFD010101 -+ -+#define OID_CUSTOM_OID_INTERFACE_VERSION 0xFFA0C000 -+ -+/* MT5921 specific OIDs */ -+#define OID_CUSTOM_BT_COEXIST_CTRL 0xFFA0C580 -+#define OID_CUSTOM_POWER_MANAGEMENT_PROFILE 0xFFA0C581 -+#define OID_CUSTOM_PATTERN_CONFIG 0xFFA0C582 -+#define OID_CUSTOM_BG_SSID_SEARCH_CONFIG 0xFFA0C583 -+#define OID_CUSTOM_VOIP_SETUP 0xFFA0C584 -+#define OID_CUSTOM_ADD_TS 0xFFA0C585 -+#define OID_CUSTOM_DEL_TS 0xFFA0C586 -+#define OID_CUSTOM_SLT 0xFFA0C587 -+#define OID_CUSTOM_ROAMING_EN 0xFFA0C588 -+#define OID_CUSTOM_WMM_PS_TEST 0xFFA0C589 -+#define OID_CUSTOM_COUNTRY_STRING 0xFFA0C58A -+#define OID_CUSTOM_MULTI_DOMAIN_CAPABILITY 0xFFA0C58B -+#define OID_CUSTOM_GPIO2_MODE 0xFFA0C58C -+#define OID_CUSTOM_CONTINUOUS_POLL 0xFFA0C58D -+#define OID_CUSTOM_DISABLE_BEACON_DETECTION 0xFFA0C58E -+ -+/* CR1460, WPS privacy bit check disable */ -+#define OID_CUSTOM_DISABLE_PRIVACY_CHECK 0xFFA0C600 -+ -+/* Precedent OIDs */ -+#define OID_CUSTOM_MCR_RW 0xFFA0C801 -+#define OID_CUSTOM_EEPROM_RW 0xFFA0C803 -+#define OID_CUSTOM_SW_CTRL 0xFFA0C805 -+#define OID_CUSTOM_MEM_DUMP 0xFFA0C807 -+ -+/* RF Test specific OIDs */ -+#define OID_CUSTOM_TEST_MODE 0xFFA0C901 -+#define OID_CUSTOM_TEST_RX_STATUS 0xFFA0C903 -+#define OID_CUSTOM_TEST_TX_STATUS 0xFFA0C905 -+#define OID_CUSTOM_ABORT_TEST_MODE 0xFFA0C906 -+#define OID_CUSTOM_MTK_WIFI_TEST 0xFFA0C911 -+ -+/* BWCS */ -+#define OID_CUSTOM_BWCS_CMD 0xFFA0C931 -+#define OID_CUSTOM_SINGLE_ANTENNA 0xFFA0C932 -+#define OID_CUSTOM_SET_PTA 0xFFA0C933 -+ -+/* NVRAM */ -+#define OID_CUSTOM_MTK_NVRAM_RW 0xFFA0C941 -+#define OID_CUSTOM_CFG_SRC_TYPE 0xFFA0C942 -+#define OID_CUSTOM_EEPROM_TYPE 0xFFA0C943 -+ -+#if CFG_SUPPORT_WAPI -+#define OID_802_11_WAPI_MODE 0xFFA0CA00 -+#define OID_802_11_WAPI_ASSOC_INFO 0xFFA0CA01 -+#define OID_802_11_SET_WAPI_KEY 0xFFA0CA02 -+#endif -+ -+#if CFG_SUPPORT_WPS2 -+#define OID_802_11_WSC_ASSOC_INFO 0xFFA0CB00 -+#endif -+ -+/* Define magic key of test mode (Don't change it for future compatibity) */ -+#define PRIV_CMD_TEST_MAGIC_KEY 2011 -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+/* NIC BBCR configuration entry structure */ -+typedef struct _PRIV_CONFIG_ENTRY { -+ UINT_8 ucOffset; -+ UINT_8 ucValue; -+} PRIV_CONFIG_ENTRY, *PPRIV_CONFIG_ENTRY; -+ -+typedef WLAN_STATUS(*PFN_OID_HANDLER_FUNC_REQ) (IN PVOID prAdapter, -+ IN OUT PVOID pvBuf, IN UINT_32 u4BufLen, OUT PUINT_32 pu4OutInfoLen); -+ -+typedef enum _ENUM_OID_METHOD_T { -+ ENUM_OID_GLUE_ONLY, -+ ENUM_OID_GLUE_EXTENSION, -+ ENUM_OID_DRIVER_CORE -+} ENUM_OID_METHOD_T, *P_ENUM_OID_METHOD_T; -+ -+/* OID set/query processing entry */ -+typedef struct _WLAN_REQ_ENTRY { -+ UINT_32 rOid; /* OID */ -+ PUINT_8 pucOidName; /* OID name text */ -+ BOOLEAN fgQryBufLenChecking; -+ BOOLEAN fgSetBufLenChecking; -+ ENUM_OID_METHOD_T eOidMethod; -+ UINT_32 u4InfoBufLen; -+ PFN_OID_HANDLER_FUNC_REQ pfOidQueryHandler; /* PFN_OID_HANDLER_FUNC */ -+ PFN_OID_HANDLER_FUNC_REQ pfOidSetHandler; /* PFN_OID_HANDLER_FUNC */ -+} WLAN_REQ_ENTRY, *P_WLAN_REQ_ENTRY; -+ -+typedef struct _NDIS_TRANSPORT_STRUCT { -+ UINT_32 ndisOidCmd; -+ UINT_32 inNdisOidlength; -+ UINT_32 outNdisOidLength; -+ UINT_8 ndisOidContent[16]; -+} NDIS_TRANSPORT_STRUCT, *P_NDIS_TRANSPORT_STRUCT; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+int -+priv_set_int(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN char *pcExtra); -+ -+int -+priv_get_int(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN OUT char *pcExtra); -+ -+int -+priv_set_ints(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN char *pcExtra); -+ -+int -+priv_get_ints(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN OUT char *pcExtra); -+ -+int -+priv_set_struct(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN char *pcExtra); -+ -+int -+priv_get_struct(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN OUT char *pcExtra); -+ -+UINT_32 CmdStringDecParse(IN UINT_8 *InStr, OUT UINT_8 **OutStr, OUT UINT_32 *OutLen); -+ -+UINT_32 CmdStringMacParse(IN UINT_8 *InStr, OUT UINT_8 **OutStr, OUT UINT_32 *OutLen, OUT UINT_8 *OutMac); -+ -+int -+priv_set_string(IN struct net_device *prNetDev, -+ IN struct iw_request_info *prIwReqInfo, IN union iwreq_data *prIwReqData, IN char *pcExtra); -+ -+int priv_support_ioctl(IN struct net_device *prDev, IN OUT struct ifreq *prReq, IN int i4Cmd); -+ -+int priv_support_driver_cmd(IN struct net_device *prDev, IN OUT struct ifreq *prReq, IN int i4Cmd); -+ -+INT_32 priv_driver_cmds(IN struct net_device *prNetDev, IN PCHAR pcCommand, IN INT_32 i4TotalLen); -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif /* _GL_WEXT_PRIV_H */ -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/platform.c b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/platform.c -new file mode 100644 -index 000000000000..fba854cfd68e ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/platform.c -@@ -0,0 +1,542 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux/platform.c#1 -+*/ -+ -+/*! \file "platform.c" -+ \brief This file including the protocol layer privacy function. -+ -+ This file provided the macros and functions library support for the -+ protocol layer security setting from wlan_oid.c and for parse.c and -+ rsn.c and nic_privacy.c -+ -+*/ -+ -+/* -+** Log: platform.c -+ * -+ * 11 14 2011 cm.chang -+ * NULL -+ * Fix compiling warning -+ * -+ * 11 10 2011 cp.wu -+ * [WCXRP00001098] [MT6620 Wi-Fi][Driver] Replace printk by DBG LOG macros in linux porting layer -+ * 1. eliminaite direct calls to printk in porting layer. -+ * 2. replaced by DBGLOG, which would be XLOG on ALPS platforms. -+ * -+ * 09 13 2011 jeffrey.chang -+ * [WCXRP00000983] [MT6620][Wi-Fi Driver] invalid pointer casting causes kernel panic during p2p connection -+ * fix the pointer casting -+ * -+ * 06 29 2011 george.huang -+ * [WCXRP00000818] [MT6620 Wi-Fi][Driver] Remove unused code segment regarding CONFIG_IPV6 -+ * . -+ * -+ * 06 28 2011 george.huang -+ * [WCXRP00000818] [MT6620 Wi-Fi][Driver] Remove unused code segment regarding CONFIG_IPV6 -+ * remove un-used code -+ * -+ * 05 11 2011 jeffrey.chang -+ * NULL -+ * fix build error -+ * -+ * 05 09 2011 jeffrey.chang -+ * [WCXRP00000710] [MT6620 Wi-Fi] Support pattern filter update function on IP address change -+ * support ARP filter through kernel notifier -+ * -+ * 04 08 2011 pat.lu -+ * [WCXRP00000623] [MT6620 Wi-Fi][Driver] use ARCH define to distinguish PC Linux driver -+ * Use CONFIG_X86 instead of PC_LINUX_DRIVER_USE option to have proper compile setting for PC Linux driver -+ * -+ * 03 22 2011 pat.lu -+ * [WCXRP00000592] [MT6620 Wi-Fi][Driver] Support PC Linux Environment Driver Build -+ * Add a compiler option "PC_LINUX_DRIVER_USE" for building driver in PC Linux environment. -+ * -+ * 03 21 2011 cp.wu -+ * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer -+ * improve portability for awareness of early version of linux kernel and wireless extension. -+ * -+ * 03 18 2011 jeffrey.chang -+ * [WCXRP00000512] [MT6620 Wi-Fi][Driver] modify the net device relative functions to support the H/W multiple queue -+ * remove early suspend functions -+ * -+ * 03 03 2011 jeffrey.chang -+ * NULL -+ * add the ARP filter callback -+ * -+ * 02 15 2011 jeffrey.chang -+ * NULL -+ * to support early suspend in android -+ * -+ * 02 01 2011 cp.wu -+ * [WCXRP00000413] [MT6620 Wi-Fi][Driver] Merge 1103 changes on NVRAM file path change to DaVinci main trunk and V1.1 -+ * branch -+ * upon Jason Zhang(NVRAM owner)'s change, ALPS has modified its NVRAM storage from /nvram/... to /data/nvram/... -+ * -+ * 11 01 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000150] [MT6620 Wi-Fi][Driver] -+ * Add implementation for querying current TX rate from firmware auto rate module -+ * 1) Query link speed (TX rate) from firmware directly with buffering mechanism to reduce overhead -+ * 2) Remove CNM CH-RECOVER event handling -+ * 3) cfg read/write API renamed with kal prefix for unified naming rules. -+ * -+ * 10 18 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000086] [MT6620 Wi-Fi][Driver] -+ * The mac address is all zero at android -+ * complete implementation of Android NVRAM access -+ * -+ * 10 05 2010 cp.wu -+ * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check -+ * 1) add NVRAM access API -+ * 2) fake scanning result when NVRAM doesn't exist and/or version mismatch. (off by compiler option) -+ * 3) add OID implementation for NVRAM read/write service -+ * -+** -+*/ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+#include "gl_os.h" -+ -+#ifndef CONFIG_X86 -+#if defined(CONFIG_HAS_EARLY_SUSPEND) -+#include -+#endif -+#endif -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+#define WIFI_NVRAM_FILE_NAME "/etc/firmware/nvram/WIFI" -+#define WIFI_NVRAM_CUSTOM_NAME "/etc/firmware/nvram/WIFI_CUSTOM" -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+static int netdev_event(struct notifier_block *nb, unsigned long notification, void *ptr) -+{ -+ UINT_8 ip[4] = { 0 }; -+ UINT_32 u4NumIPv4 = 0; -+/* #ifdef CONFIG_IPV6 */ -+#if 0 -+ UINT_8 ip6[16] = { 0 }; /* FIX ME: avoid to allocate large memory in stack */ -+ UINT_32 u4NumIPv6 = 0; -+#endif -+ struct in_ifaddr *ifa = (struct in_ifaddr *)ptr; -+ struct net_device *prDev = ifa->ifa_dev->dev; -+ UINT_32 i; -+ P_PARAM_NETWORK_ADDRESS_IP prParamIpAddr; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ -+ if (prDev == NULL) { -+ DBGLOG(REQ, ERROR, "netdev_event: device is empty.\n"); -+ return NOTIFY_DONE; -+ } -+ DBGLOG(REQ, INFO, "netdev_event, addr=%x, notification=%lx, dev_name=%s\n", -+ ifa->ifa_address, notification, prDev->name); -+ if (!fgIsUnderSuspend) -+ return NOTIFY_DONE; -+ if ((strncmp(prDev->name, "p2p", 3) != 0) && (strncmp(prDev->name, "wlan", 4) != 0)) { -+ DBGLOG(REQ, WARN, "netdev_event: not our device\n"); -+ return NOTIFY_DONE; -+ } -+#if 0 /* CFG_SUPPORT_HOTSPOT_2_0 */ -+ { -+ /* printk(KERN_INFO "[netdev_event] IPV4_DAD is unlock now!!\n"); */ -+ prGlueInfo->fgIsDad = FALSE; -+ } -+#endif -+ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ -+ if (prGlueInfo == NULL) { -+ DBGLOG(REQ, ERROR, "netdev_event: prGlueInfo is empty.\n"); -+ return NOTIFY_DONE; -+ } -+ ASSERT(prGlueInfo); -+ -+ /* <3> get the IPv4 address */ -+ if (!prDev || !(prDev->ip_ptr) || -+ !((struct in_device *)(prDev->ip_ptr))->ifa_list || -+ !(&(((struct in_device *)(prDev->ip_ptr))->ifa_list->ifa_local))) { -+ DBGLOG(REQ, INFO, "ip is not available.\n"); -+ return NOTIFY_DONE; -+ } -+ -+ kalMemCopy(ip, &(((struct in_device *)(prDev->ip_ptr))->ifa_list->ifa_local), sizeof(ip)); -+ DBGLOG(REQ, INFO, "ip is %d.%d.%d.%d\n", ip[0], ip[1], ip[2], ip[3]); -+ -+ /* todo: traverse between list to find whole sets of IPv4 addresses */ -+ if (!((ip[0] == 0) && (ip[1] == 0) && (ip[2] == 0) && (ip[3] == 0))) -+ u4NumIPv4++; -+/* #ifdef CONFIG_IPV6 */ -+#if 0 -+ if (!prDev || !(prDev->ip6_ptr) || -+ !((struct in_device *)(prDev->ip6_ptr))->ifa_list || -+ !(&(((struct in_device *)(prDev->ip6_ptr))->ifa_list->ifa_local))) { -+ DBGLOG(REQ, INFO, "ipv6 is not available.\n"); -+ return NOTIFY_DONE; -+ } -+ -+ kalMemCopy(ip6, &(((struct in_device *)(prDev->ip6_ptr))->ifa_list->ifa_local), sizeof(ip6)); -+ DBGLOG(REQ, INFO, "ipv6 is %d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d\n", -+ ip6[0], ip6[1], ip6[2], ip6[3], -+ ip6[4], ip6[5], ip6[6], ip6[7], ip6[8], ip6[9], ip6[10], ip6[11], ip6[12], ip6[13], ip6[14], ip6[15]); -+ -+ /* todo: traverse between list to find whole sets of IPv6 addresses */ -+ if (!((ip6[0] == 0) && (ip6[1] == 0) && (ip6[2] == 0) && (ip6[3] == 0) && (ip6[4] == 0) && (ip6[5] == 0))) -+ /* u4NumIPv6++; */ -+#endif -+ -+ /* here we can compare the dev with other network's netdev to */ -+ /* set the proper arp filter */ -+ /* */ -+ /* IMPORTANT: please make sure if the context can sleep, if the context can't sleep */ -+ /* we should schedule a kernel thread to do this for us */ -+ -+ /* <7> set up the ARP filter */ -+ { -+ WLAN_STATUS rStatus = WLAN_STATUS_FAILURE; -+ UINT_32 u4SetInfoLen = 0; -+ UINT_8 aucBuf[32] = { 0 }; -+ UINT_32 u4Len = OFFSET_OF(PARAM_NETWORK_ADDRESS_LIST, arAddress); -+ P_PARAM_NETWORK_ADDRESS_LIST prParamNetAddrList = (P_PARAM_NETWORK_ADDRESS_LIST) aucBuf; -+ P_PARAM_NETWORK_ADDRESS prParamNetAddr = prParamNetAddrList->arAddress; -+ -+/* #ifdef CONFIG_IPV6 */ -+#if 0 -+ prParamNetAddrList->u4AddressCount = u4NumIPv4 + u4NumIPv6; -+#else -+ prParamNetAddrList->u4AddressCount = u4NumIPv4; -+#endif -+ prParamNetAddrList->u2AddressType = PARAM_PROTOCOL_ID_TCP_IP; -+ for (i = 0; i < u4NumIPv4; i++) { -+ prParamNetAddr->u2AddressLength = sizeof(PARAM_NETWORK_ADDRESS_IP); /* 4;; */ -+ prParamNetAddr->u2AddressType = PARAM_PROTOCOL_ID_TCP_IP; -+#if 0 -+ kalMemCopy(prParamNetAddr->aucAddress, ip, sizeof(ip)); -+ prParamNetAddr = (P_PARAM_NETWORK_ADDRESS) ((PUINT_8) prParamNetAddr + sizeof(ip)); -+ u4Len += OFFSET_OF(PARAM_NETWORK_ADDRESS, aucAddress) + sizeof(ip); -+#else -+ prParamIpAddr = (P_PARAM_NETWORK_ADDRESS_IP) prParamNetAddr->aucAddress; -+ kalMemCopy(&prParamIpAddr->in_addr, ip, sizeof(ip)); -+ prParamNetAddr = -+ (P_PARAM_NETWORK_ADDRESS) ((PUINT_8) prParamNetAddr + sizeof(PARAM_NETWORK_ADDRESS)); -+ u4Len += OFFSET_OF(PARAM_NETWORK_ADDRESS, aucAddress) + sizeof(PARAM_NETWORK_ADDRESS); -+#endif -+ } -+/* #ifdef CONFIG_IPV6 */ -+#if 0 -+ for (i = 0; i < u4NumIPv6; i++) { -+ prParamNetAddr->u2AddressLength = 6; -+ prParamNetAddr->u2AddressType = PARAM_PROTOCOL_ID_TCP_IP; -+ kalMemCopy(prParamNetAddr->aucAddress, ip6, sizeof(ip6)); -+ prParamNetAddr = (P_PARAM_NETWORK_ADDRESS) ((PUINT_8) prParamNetAddr + sizeof(ip6)); -+ u4Len += OFFSET_OF(PARAM_NETWORK_ADDRESS, aucAddress) + sizeof(ip6); -+ } -+#endif -+ ASSERT(u4Len <= sizeof(aucBuf)); -+ -+ DBGLOG(REQ, INFO, "kalIoctl (0x%p, 0x%p)\n", prGlueInfo, prParamNetAddrList); -+ -+ rStatus = kalIoctl(prGlueInfo, -+ wlanoidSetNetworkAddress, -+ (PVOID) prParamNetAddrList, u4Len, FALSE, FALSE, TRUE, FALSE, &u4SetInfoLen); -+ -+ if (rStatus != WLAN_STATUS_SUCCESS) -+ DBGLOG(REQ, ERROR, "set HW pattern filter fail 0x%x\n", rStatus); -+ } -+ -+ return NOTIFY_DONE; -+ -+} -+ -+/* #if CFG_SUPPORT_HOTSPOT_2_0 */ -+#if 0 -+static int net6dev_event(struct notifier_block *nb, unsigned long notification, void *ptr) -+{ -+ struct inet6_ifaddr *ifa = (struct inet6_ifaddr *)ptr; -+ struct net_device *prDev = ifa->idev->dev; -+ P_GLUE_INFO_T prGlueInfo = NULL; -+ -+ if (prDev == NULL) { -+ DBGLOG(REQ, INFO, "net6dev_event: device is empty.\n"); -+ return NOTIFY_DONE; -+ } -+ -+ if ((strncmp(prDev->name, "p2p", 3) != 0) && (strncmp(prDev->name, "wlan", 4) != 0)) { -+ DBGLOG(REQ, INFO, "net6dev_event: xxx\n"); -+ return NOTIFY_DONE; -+ } -+ -+ if (strncmp(prDev->name, "p2p", 3) == 0) { -+ /* because we store the address of prGlueInfo in p2p's private date of net device */ -+ /* *((P_GLUE_INFO_T *) netdev_priv(prGlueInfo->prP2PInfo->prDevHandler)) = prGlueInfo; */ -+ prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); -+ } else { /* wlan0 */ -+ prGlueInfo = (P_GLUE_INFO_T) netdev_priv(prDev); -+ } -+ -+ if (prGlueInfo == NULL) { -+ DBGLOG(REQ, INFO, "netdev_event: prGlueInfo is empty.\n"); -+ return NOTIFY_DONE; -+ } -+ /* printk(KERN_INFO "[net6dev_event] IPV6_DAD is unlock now!!\n"); */ -+ prGlueInfo->fgIs6Dad = FALSE; -+ -+ return NOTIFY_DONE; -+} -+#endif -+ -+static struct notifier_block inetaddr_notifier = { -+ .notifier_call = netdev_event, -+}; -+ -+#if 0 /* CFG_SUPPORT_HOTSPOT_2_0 */ -+static struct notifier_block inet6addr_notifier = { -+ .notifier_call = net6dev_event, -+}; -+#endif -+ -+void wlanRegisterNotifier(void) -+{ -+ register_inetaddr_notifier(&inetaddr_notifier); -+ -+#if CFG_SUPPORT_HOTSPOT_2_0 -+ /* register_inet6addr_notifier(&inet6addr_notifier); */ -+#endif -+} -+ -+/* EXPORT_SYMBOL(wlanRegisterNotifier); */ -+ -+void wlanUnregisterNotifier(void) -+{ -+ unregister_inetaddr_notifier(&inetaddr_notifier); -+ -+#if CFG_SUPPORT_HOTSPOT_2_0 -+ /* unregister_inetaddr_notifier(&inet6addr_notifier); */ -+#endif -+} -+ -+/* EXPORT_SYMBOL(wlanUnregisterNotifier); */ -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Utility function for reading data from files on NVRAM-FS -+* -+* \param[in] -+* filename -+* len -+* offset -+* \param[out] -+* buf -+* \return -+* actual length of data being read -+*/ -+/*----------------------------------------------------------------------------*/ -+static int nvram_read(char *filename, char *buf, ssize_t len, int offset) -+{ -+#if CFG_SUPPORT_NVRAM -+ struct file *fd; -+ int retLen = -1; -+ -+ mm_segment_t old_fs = get_fs(); -+ -+ set_fs(KERNEL_DS); -+ -+ fd = filp_open(filename, O_RDONLY, 0644); -+ -+ if (IS_ERR(fd)) { -+ DBGLOG(INIT, INFO, "[MT6620][nvram_read] : failed to open!!\n"); -+ return -1; -+ } -+ -+ do { -+ //if ((fd->f_op == NULL) || (fd->f_op->read == NULL)) { -+ if ( fd->f_op == NULL ) { -+ DBGLOG(INIT, INFO, "[MT6620][nvram_read] : file can not be read!!\n"); -+ break; -+ } -+ -+ if (fd->f_pos != offset) { -+ if (fd->f_op->llseek) { -+ if (fd->f_op->llseek(fd, offset, 0) != offset) { -+ DBGLOG(INIT, INFO, "[MT6620][nvram_read] : failed to seek!!\n"); -+ break; -+ } -+ } else { -+ fd->f_pos = offset; -+ } -+ } -+ -+ retLen = vfs_read(fd, buf, len, &fd->f_pos); -+ -+ } while (FALSE); -+ -+ filp_close(fd, NULL); -+ -+ set_fs(old_fs); -+ -+ return retLen; -+ -+#else /* !CFG_SUPPORT_NVRAM */ -+ -+ return -EIO; -+ -+#endif -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief Utility function for writing data to files on NVRAM-FS -+* -+* \param[in] -+* filename -+* buf -+* len -+* offset -+* \return -+* actual length of data being written -+*/ -+/*----------------------------------------------------------------------------*/ -+static int nvram_write(char *filename, char *buf, ssize_t len, int offset) -+{ -+#if CFG_SUPPORT_NVRAM -+ struct file *fd; -+ int retLen = -1; -+ -+ mm_segment_t old_fs = get_fs(); -+ -+ set_fs(KERNEL_DS); -+ -+ fd = filp_open(filename, O_WRONLY | O_CREAT, 0644); -+ -+ if (IS_ERR(fd)) { -+ DBGLOG(INIT, INFO, "[MT6620][nvram_write] : failed to open!!\n"); -+ return -1; -+ } -+ -+ do { -+ if ((fd->f_op == NULL) || (fd->f_op->write == NULL)) { -+ DBGLOG(INIT, INFO, "[MT6620][nvram_write] : file can not be write!!\n"); -+ break; -+ } -+ /* End of if */ -+ if (fd->f_pos != offset) { -+ if (fd->f_op->llseek) { -+ if (fd->f_op->llseek(fd, offset, 0) != offset) { -+ DBGLOG(INIT, INFO, "[MT6620][nvram_write] : failed to seek!!\n"); -+ break; -+ } -+ } else { -+ fd->f_pos = offset; -+ } -+ } -+ -+ retLen = vfs_write(fd, buf, len, &fd->f_pos); -+ -+ } while (FALSE); -+ -+ filp_close(fd, NULL); -+ -+ set_fs(old_fs); -+ -+ return retLen; -+ -+#else /* !CFG_SUPPORT_NVRAMS */ -+ -+ return -EIO; -+ -+#endif -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief API for reading data on NVRAM -+* -+* \param[in] -+* prGlueInfo -+* u4Offset -+* \param[out] -+* pu2Data -+* \return -+* TRUE -+* FALSE -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN kalCfgDataRead16(IN P_GLUE_INFO_T prGlueInfo, IN UINT_32 u4Offset, OUT PUINT_16 pu2Data) -+{ -+ if (pu2Data == NULL) -+ return FALSE; -+ -+ if (nvram_read(WIFI_NVRAM_FILE_NAME, -+ (char *)pu2Data, sizeof(unsigned short), u4Offset) != sizeof(unsigned short)) { -+ return FALSE; -+ } else { -+ return TRUE; -+ } -+} -+ -+/*----------------------------------------------------------------------------*/ -+/*! -+* \brief API for writing data on NVRAM -+* -+* \param[in] -+* prGlueInfo -+* u4Offset -+* u2Data -+* \return -+* TRUE -+* FALSE -+*/ -+/*----------------------------------------------------------------------------*/ -+BOOLEAN kalCfgDataWrite16(IN P_GLUE_INFO_T prGlueInfo, UINT_32 u4Offset, UINT_16 u2Data) -+{ -+ if (nvram_write(WIFI_NVRAM_FILE_NAME, -+ (char *)&u2Data, sizeof(unsigned short), u4Offset) != sizeof(unsigned short)) { -+ return FALSE; -+ } else { -+ return TRUE; -+ } -+} -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/version.h b/drivers/misc/mediatek/connectivity/wlan/gen2/os/version.h -new file mode 100644 -index 000000000000..9444d415c60e ---- /dev/null -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/version.h -@@ -0,0 +1,190 @@ -+/* -+** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/version.h#1 -+*/ -+ -+/*! \file "version.h" -+ \brief Driver's version definition -+ -+*/ -+ -+/* -+** Log: version.h -+ * -+ * 11 01 2011 chinglan.wang -+ * NULL -+ * Change the version number to v2.0.1.1. -+ * -+ * 08 26 2011 chinglan.wang -+ * NULL -+ * Change the version number to v2.0.0.9.. -+ * -+ * 08 23 2011 chinglan.wang -+ * NULL -+ * Change the version number to v2.0.0.8. -+ * -+ * 08 15 2011 cp.wu -+ * [WCXRP00000851] [MT6628 Wi-Fi][Driver] Add HIFSYS related definition to driver source tree -+ * correct typo. -+ * -+ * 08 15 2011 cp.wu -+ * [WCXRP00000851] [MT6628 Wi-Fi][Driver] Add HIFSYS related definition to driver source tree -+ * for building MT6628 Win32 driver environment -+ * -+ * 08 03 2011 chinglan.wang -+ * NULL -+ * Change the version number to v2.0.0.7. -+ * -+ * 07 24 2011 puff.wen -+ * NULL -+ * [MT5931][Beta 5]Change the version number to v0.2.2.0 -+ * -+ * 06 01 2011 chinglan.wang -+ * NULL -+ * Change the version number to v2.0.0.6.. -+ * -+ * 05 09 2011 chinglan.wang -+ * NULL -+ * Change the version number to v2.0.0.5.. -+ * -+ * 04 19 2011 chinglan.wang -+ * NULL -+ * Change the version number to v2.0.0.4. -+ * -+ * 04 18 2011 chinglan.wang -+ * NULL -+ * Change the version number to v2.0.0.3. -+ * -+ * 03 25 2011 chinglan.wang -+ * NULL -+ * Change the version number to v2.0.0.2. -+ * -+ * 03 21 2011 chinglan.wang -+ * NULL -+ * Change the version number to 2.0.0.1. -+ * -+ * 03 18 2011 chinglan.wang -+ * NULL -+ * Change the version number to v2.0.0.0. -+ * -+ * 02 11 2011 chinglan.wang -+ * NULL -+ * Change to the version 1.2.0.2. -+ * -+ * 02 10 2011 chinglan.wang -+ * NULL -+ * Change the version to 1.2.0.1. -+ * -+ * 02 08 2011 cp.wu -+ * [WCXRP00000427] [MT6620 Wi-Fi][Driver] Modify veresion information to match with release revision number -+ * change version number to v1.2.0.0 for preparing v1.2 software package release. -+ * -+ * 12 10 2010 kevin.huang -+ * [WCXRP00000128] [MT6620 Wi-Fi][Driver] Add proc support to Android Driver for debug and driver status check -+ * Add Linux Proc Support -+ * -+ * 10 07 2010 cp.wu -+ * [WCXRP00000083] [MT5931][Driver][FW] Add necessary logic for MT5931 first connection -+ * [WINDDK] build system changes for MT5931 -+ * -+ * 07 08 2010 cp.wu -+ * -+ * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. -+ * -+ * 06 06 2010 kevin.huang -+ * [WPD00003832][MT6620 5931] Create driver base -+ * [MT6620 5931] Create driver base -+** \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-12-14 14:10:55 GMT mtk01084 -+** \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-11-17 22:41:00 GMT mtk01084 -+** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-11-13 16:20:33 GMT mtk01084 -+** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 20:27:13 GMT mtk01426 -+** Init for develop -+** -+*/ -+ -+#ifndef _VERSION_H -+#define _VERSION_H -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+#ifndef NIC_AUTHOR -+#define NIC_AUTHOR "NIC_AUTHOR" -+#endif -+#ifndef NIC_DESC -+#define NIC_DESC "NIC_DESC" -+#endif -+ -+#ifndef NIC_NAME -+#if defined(MT6620) -+#define NIC_NAME "MT6620" -+#define NIC_DEVICE_ID "MT6620" -+#define NIC_DEVICE_ID_LOW "mt6620" -+#elif defined(MT6628) -+#define NIC_NAME "MT6582" -+#define NIC_DEVICE_ID "MT6582" -+#define NIC_DEVICE_ID_LOW "mt6582" -+#endif -+#endif -+ -+/* NIC driver information */ -+#define NIC_VENDOR "MediaTek Inc." -+#define NIC_VENDOR_OUI {0x00, 0x0C, 0xE7} -+ -+#if defined(MT6620) -+#define NIC_PRODUCT_NAME "MediaTek Inc. MT6620 Wireless LAN Adapter" -+#define NIC_DRIVER_NAME "MediaTek Inc. MT6620 Wireless LAN Adapter Driver" -+#elif defined(MT6628) -+/* #define NIC_PRODUCT_NAME "MediaTek Inc. MT6628 Wireless LAN Adapter" */ -+/* #define NIC_DRIVER_NAME "MediaTek Inc. MT6628 Wireless LAN Adapter Driver" */ -+#define NIC_PRODUCT_NAME "MediaTek Inc. MT6582 Wireless LAN Adapter" -+#define NIC_DRIVER_NAME "MediaTek Inc. MT6582 Wireless LAN Adapter Driver" -+#endif -+ -+/* Define our driver version */ -+#define NIC_DRIVER_MAJOR_VERSION 2 -+#define NIC_DRIVER_MINOR_VERSION 0 -+#define NIC_DRIVER_VERSION (2, 0, 1, 1) -+#define NIC_DRIVER_VERSION_STRING "2.0.1.1" -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif /* _VERSION_H */ -diff --git a/drivers/misc/mediatek/include/mt-plat/aee.h b/drivers/misc/mediatek/include/mt-plat/aee.h -new file mode 100644 -index 000000000000..d1cf448dafb2 ---- /dev/null -+++ b/drivers/misc/mediatek/include/mt-plat/aee.h -@@ -0,0 +1,284 @@ -+/* -+ * Copyright (C) 2015 MediaTek Inc. -+ * -+ * 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. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#if !defined(__AEE_H__) -+#define __AEE_H__ -+ -+#include -+#include -+ -+#define AEE_MODULE_NAME_LENGTH 64 -+#define AEE_PROCESS_NAME_LENGTH 256 -+#define AEE_BACKTRACE_LENGTH 3072 -+ -+typedef enum { -+ AE_DEFECT_FATAL, -+ AE_DEFECT_EXCEPTION, -+ AE_DEFECT_WARNING, -+ AE_DEFECT_REMINDING, -+ AE_DEFECT_ATTR_END -+} AE_DEFECT_ATTR; -+ -+typedef enum { -+ AE_KE = 0, /* Fatal Exception */ -+ AE_HWT, -+ AE_REBOOT, -+ AE_NE, -+ AE_JE, -+ AE_SWT, -+ AE_EE, -+ AE_EXP_ERR_END, -+ AE_ANR, /* Error or Warning or Defect */ -+ AE_RESMON, -+ AE_MODEM_WARNING, -+ AE_WTF, -+ AE_WRN_ERR_END, -+ AE_MANUAL, /* Manual Raise */ -+ AE_EXP_CLASS_END, -+ -+ AE_KERNEL_PROBLEM_REPORT = 1000, -+ AE_SYSTEM_JAVA_DEFECT, -+ AE_SYSTEM_NATIVE_DEFECT, -+ AE_MANUAL_MRDUMP_KEY, -+} AE_EXP_CLASS; /* General Program Exception Class */ -+ -+typedef enum { -+ AEE_REBOOT_MODE_NORMAL = 0, -+ AEE_REBOOT_MODE_KERNEL_OOPS, -+ AEE_REBOOT_MODE_KERNEL_PANIC, -+ AEE_REBOOT_MODE_NESTED_EXCEPTION, -+ AEE_REBOOT_MODE_WDT, -+ AEE_REBOOT_MODE_MANUAL_KDUMP, -+} AEE_REBOOT_MODE; -+ -+#define AEE_SZ_SYMBOL_L 140 -+#define AEE_SZ_SYMBOL_S 80 -+struct aee_bt_frame { -+ __u64 pc; -+ __u64 lr; -+ __u32 pad[5]; -+ char pc_symbol[AEE_SZ_SYMBOL_S]; /* Now we use different symbol length for PC &LR */ -+ char lr_symbol[AEE_SZ_SYMBOL_L]; -+}; -+ -+/* aee_process_info struct should strictly small than ipanic_buffer, now 4KB */ -+struct aee_process_info { -+ char process_path[AEE_PROCESS_NAME_LENGTH]; -+ char backtrace[AEE_BACKTRACE_LENGTH]; -+ struct aee_bt_frame ke_frame; -+}; -+ -+struct aee_process_bt { -+ __u32 pid; -+ __u32 nr_entries; -+ struct aee_bt_frame *entries; -+}; -+ -+ -+struct aee_thread_reg { -+ pid_t tid; -+ struct pt_regs regs; -+}; -+ -+struct aee_user_thread_stack { -+ pid_t tid; -+ int StackLength; -+ unsigned char *Userthread_Stack; /*8k stack ,define to char only for match 64bit/32bit*/ -+}; -+ -+struct aee_user_thread_maps { -+ pid_t tid; -+ int Userthread_mapsLength; -+ unsigned char *Userthread_maps; /*8k stack ,define to char only for match 64bit/32bit*/ -+}; -+ -+ -+ -+struct aee_oops { -+ struct list_head list; -+ AE_DEFECT_ATTR attr; -+ AE_EXP_CLASS clazz; -+ -+ char module[AEE_MODULE_NAME_LENGTH]; -+ /* consist with struct aee_process_info */ -+ char process_path[AEE_PROCESS_NAME_LENGTH]; -+ char backtrace[AEE_BACKTRACE_LENGTH]; -+ struct aee_bt_frame ke_frame; -+ -+ char *detail; -+ int detail_len; -+ -+ char *console; -+ int console_len; -+ -+ char *android_main; -+ int android_main_len; -+ char *android_radio; -+ int android_radio_len; -+ char *android_system; -+ int android_system_len; -+ -+ char *userspace_info; -+ int userspace_info_len; -+ -+ char *mmprofile; -+ int mmprofile_len; -+ -+ char *mini_rdump; -+ int mini_rdump_len; -+ -+ -+ struct aee_user_thread_stack userthread_stack; -+ struct aee_thread_reg userthread_reg; -+ struct aee_user_thread_maps userthread_maps; -+ -+ int dump_option; -+}; -+ -+struct aee_kernel_api { -+ void (*kernel_reportAPI)(const AE_DEFECT_ATTR attr, const int db_opt, const char *module, -+ const char *msg); -+ void (*md_exception)(const char *assert_type, const int *log, int log_size, const int *phy, -+ int phy_size, const char *detail, const int db_opt); -+ void (*md32_exception)(const char *assert_type, const int *log, int log_size, -+ const int *phy, int phy_size, const char *detail, const int db_opt); -+ void (*combo_exception)(const char *assert_type, const int *log, int log_size, -+ const int *phy, int phy_size, const char *detail, const int db_opt); -+ void (*scp_exception)(const char *assert_type, const int *log, int log_size, -+ const int *phy, int phy_size, const char *detail, const int db_opt); -+}; -+ -+void aee_sram_printk(const char *fmt, ...); -+int aee_nested_printf(const char *fmt, ...); -+void aee_wdt_irq_info(void); -+void aee_wdt_fiq_info(void *arg, void *regs, void *svc_sp); -+void aee_trigger_kdb(void); -+struct aee_oops *aee_oops_create(AE_DEFECT_ATTR attr, AE_EXP_CLASS clazz, const char *module); -+void aee_oops_set_backtrace(struct aee_oops *oops, const char *backtrace); -+void aee_oops_set_process_path(struct aee_oops *oops, const char *process_path); -+void aee_oops_free(struct aee_oops *oops); -+/* powerkey press,modules use bits */ -+#define AE_WDT_Powerkey_DEVICE_PATH "/dev/kick_powerkey" -+#define WDT_SETBY_DEFAULT (0) -+#define WDT_SETBY_Backlight (1<<0) -+#define WDT_SETBY_Display (1<<1) -+#define WDT_SETBY_SF (1<<2) -+#define WDT_SETBY_PM (1<<3) -+#define WDT_SETBY_WMS_DISABLE_PWK_MONITOR (0xAEEAEE00) -+#define WDT_SETBY_WMS_ENABLE_PWK_MONITOR (0xAEEAEE01) -+#define WDT_PWK_HANG_FORCE_HWT (0xAEE0FFFF) -+ -+/* QHQ RT Monitor */ -+#define AEEIOCTL_RT_MON_Kick _IOR('p', 0x0A, int) -+#define AE_WDT_DEVICE_PATH "/dev/RT_Monitor" -+/* QHQ RT Monitor end */ -+ -+/* DB dump option bits, set relative bit to 1 to include related file in db */ -+#define DB_OPT_DEFAULT (0) -+#define DB_OPT_FTRACE (1<<0) -+#define DB_OPT_PRINTK_TOO_MUCH (1<<1) -+#define DB_OPT_NE_JBT_TRACES (1<<2) -+#define DB_OPT_SWT_JBT_TRACES (1<<3) -+#define DB_OPT_VM_TRACES (1<<4) -+#define DB_OPT_DUMPSYS_ACTIVITY (1<<5) -+#define DB_OPT_DUMPSYS_WINDOW (1<<6) -+#define DB_OPT_DUMPSYS_GFXINFO (1<<7) -+#define DB_OPT_DUMPSYS_SURFACEFLINGER (1<<8) -+#define DB_OPT_DISPLAY_HANG_DUMP (1<<9) -+#define DB_OPT_LOW_MEMORY_KILLER (1<<10) -+#define DB_OPT_PROC_MEM (1<<11) -+#define DB_OPT_FS_IO_LOG (1<<12) -+#define DB_OPT_PROCESS_COREDUMP (1<<13) -+#define DB_OPT_VM_HPROF (1<<14) -+#define DB_OPT_PROCMEM (1<<15) -+#define DB_OPT_DUMPSYS_INPUT (1<<16) -+#define DB_OPT_MMPROFILE_BUFFER (1<<17) -+#define DB_OPT_BINDER_INFO (1<<18) -+#define DB_OPT_WCN_ISSUE_INFO (1<<19) -+#define DB_OPT_DUMMY_DUMP (1<<20) -+#define DB_OPT_PID_MEMORY_INFO (1<<21) -+#define DB_OPT_VM_OOME_HPROF (1<<22) -+#define DB_OPT_PID_SMAPS (1<<23) -+#define DB_OPT_PROC_CMDQ_INFO (1<<24) -+#define DB_OPT_PROC_USKTRK (1<<25) -+#define DB_OPT_SF_RTT_DUMP (1<<26) -+#define DB_OPT_PAGETYPE_INFO (1<<27) -+#define DB_OPT_DUMPSYS_PROCSTATS (1<<28) -+#define DB_OPT_DUMP_DISPLAY (1<<29) -+#define DB_OPT_NATIVE_BACKTRACE (1<<30) -+#define DB_OPT_AARCH64 (1<<31) -+ -+#define aee_kernel_exception(module, msg...) \ -+ aee_kernel_exception_api(__FILE__, __LINE__, DB_OPT_DEFAULT, module, msg) -+#define aee_kernel_warning(module, msg...) \ -+ aee_kernel_warning_api(__FILE__, __LINE__, DB_OPT_DEFAULT, module, msg) -+#define aee_kernel_reminding(module, msg...) \ -+ aee_kernel_reminding_api(__FILE__, __LINE__, DB_OPT_DEFAULT, module, msg) -+#define aee_kernel_dal_show(msg) \ -+ aee_kernel_dal_api(__FILE__, __LINE__, msg) -+ -+#define aed_md_exception(log, log_size, phy, phy_size, detail) \ -+ aed_md_exception_api(log, log_size, phy, phy_size, detail, DB_OPT_DEFAULT) -+#define aed_md32_exception(log, log_size, phy, phy_size, detail) \ -+ aed_md32_exception_api(log, log_size, phy, phy_size, detail, DB_OPT_DEFAULT) -+#define aed_scp_exception(log, log_size, phy, phy_size, detail) \ -+ aed_scp_exception_api(log, log_size, phy, phy_size, detail, DB_OPT_DEFAULT) -+#define aed_combo_exception(log, log_size, phy, phy_size, detail) \ -+ aed_combo_exception_api(log, log_size, phy, phy_size, detail, DB_OPT_DEFAULT) -+ -+void aee_kernel_exception_api(const char *file, const int line, const int db_opt, -+ const char *module, const char *msg, ...); -+void aee_kernel_warning_api(const char *file, const int line, const int db_opt, const char *module, -+ const char *msg, ...); -+void aee_kernel_reminding_api(const char *file, const int line, const int db_opt, -+ const char *module, const char *msg, ...); -+void aee_kernel_dal_api(const char *file, const int line, const char *msg); -+ -+void aed_md_exception_api(const int *log, int log_size, const int *phy, int phy_size, -+ const char *detail, const int db_opt); -+void aed_md32_exception_api(const int *log, int log_size, const int *phy, int phy_size, -+ const char *detail, const int db_opt); -+void aed_scp_exception_api(const int *log, int log_size, const int *phy, int phy_size, -+ const char *detail, const int db_opt); -+void aed_combo_exception_api(const int *log, int log_size, const int *phy, int phy_size, -+ const char *detail, const int db_opt); -+ -+void aee_kernel_wdt_kick_Powkey_api(const char *module, int msg); -+int aee_kernel_wdt_kick_api(int kinterval); -+void aee_powerkey_notify_press(unsigned long pressed); -+int aee_kernel_Powerkey_is_press(void); -+ -+void ipanic_recursive_ke(struct pt_regs *regs, struct pt_regs *excp_regs, int cpu); -+ -+/* QHQ RT Monitor */ -+void aee_kernel_RT_Monitor_api(int lParam); -+/* QHQ RT Monitor end */ -+void mt_fiq_printf(const char *fmt, ...); -+void aee_register_api(struct aee_kernel_api *aee_api); -+int aee_in_nested_panic(void); -+void aee_stop_nested_panic(struct pt_regs *regs); -+void aee_wdt_dump_info(void); -+void aee_wdt_printf(const char *fmt, ...); -+ -+void aee_fiq_ipi_cpu_stop(void *arg, void *regs, void *svc_sp); -+ -+#if defined(CONFIG_MTK_AEE_DRAM_CONSOLE) -+void aee_dram_console_reserve_memory(void); -+#else -+static inline void aee_dram_console_reserve_memory(void) -+{ -+} -+#endif -+ -+extern void *aee_excp_regs; /* To store latest exception, in case of stack corruption */ -+#endif /* __AEE_H__ */ -diff --git a/drivers/misc/mediatek/include/mt-plat/mrdump.h b/drivers/misc/mediatek/include/mt-plat/mrdump.h -new file mode 100644 -index 000000000000..b6bdfa2f7617 ---- /dev/null -+++ b/drivers/misc/mediatek/include/mt-plat/mrdump.h -@@ -0,0 +1,204 @@ -+/* -+ * Copyright (C) 2016 MediaTek Inc. -+ * -+ * 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. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+ * See http://www.gnu.org/licenses/gpl-2.0.html for more details. -+ */ -+ -+#if !defined(__MRDUMP_H__) -+#define __MRDUMP_H__ -+ -+#include -+#include -+#include -+#include -+#include -+ -+#ifdef __aarch64__ -+#define reg_pc pc -+#define reg_lr regs[30] -+#define reg_sp sp -+#define reg_fp regs[29] -+#else -+#define reg_pc ARM_pc -+#define reg_lr ARM_lr -+#define reg_sp ARM_sp -+#define reg_ip ARM_ip -+#define reg_fp ARM_fp -+#endif -+ -+#define MRDUMP_CPU_MAX 16 -+ -+#define MRDUMP_DEV_NULL 0 -+#define MRDUMP_DEV_SDCARD 1 -+#define MRDUMP_DEV_EMMC 2 -+ -+#define MRDUMP_FS_NULL 0 -+#define MRDUMP_FS_VFAT 1 -+#define MRDUMP_FS_EXT4 2 -+ -+#define MRDUMP_GO_DUMP "MRDUMP04" -+ -+typedef uint32_t arm32_gregset_t[18]; -+typedef uint64_t aarch64_gregset_t[34]; -+ -+struct mrdump_crash_record { -+ int reboot_mode; -+ -+ char msg[128]; -+ char backtrace[512]; -+ -+ uint32_t fault_cpu; -+ -+ union { -+ arm32_gregset_t arm32_regs; -+ aarch64_gregset_t aarch64_regs; -+ } cpu_regs[MRDUMP_CPU_MAX]; -+}; -+ -+struct mrdump_machdesc { -+ uint32_t crc; -+ -+ uint32_t output_device; -+ -+ uint32_t nr_cpus; -+ -+ uint64_t page_offset; -+ uint64_t high_memory; -+ -+ uint64_t vmalloc_start; -+ uint64_t vmalloc_end; -+ -+ uint64_t modules_start; -+ uint64_t modules_end; -+ -+ uint64_t phys_offset; -+ uint64_t master_page_table; -+ -+ uint32_t output_fstype; -+ uint32_t output_lbaooo; -+}; -+ -+struct mrdump_control_block { -+ char sig[8]; -+ -+ struct mrdump_machdesc machdesc; -+ struct mrdump_crash_record crash_record; -+}; -+ -+/* NOTE!! any change to this struct should be compatible in aed */ -+struct mrdump_mini_reg_desc { -+ unsigned long reg; /* register value */ -+ unsigned long kstart; /* start kernel addr of memory dump */ -+ unsigned long kend; /* end kernel addr of memory dump */ -+ unsigned long pos; /* next pos to dump */ -+ int valid; /* 1: valid regiser, 0: invalid regiser */ -+ int pad; /* reserved */ -+ loff_t offset; /* offset in buffer */ -+}; -+ -+/* it should always be smaller than MRDUMP_MINI_HEADER_SIZE */ -+struct mrdump_mini_header { -+ struct mrdump_mini_reg_desc reg_desc[ELF_NGREG]; -+}; -+ -+#define MRDUMP_MINI_NR_SECTION 60 -+#define MRDUMP_MINI_SECTION_SIZE (32 * 1024) -+#define NT_IPANIC_MISC 4095 -+#define MRDUMP_MINI_NR_MISC 20 -+ -+struct mrdump_mini_elf_misc { -+ unsigned long vaddr; -+ unsigned long paddr; -+ unsigned long start; -+ unsigned long size; -+}; -+ -+#define NOTE_NAME_SHORT 12 -+#define NOTE_NAME_LONG 20 -+ -+struct mrdump_mini_elf_psinfo { -+ struct elf_note note; -+ char name[NOTE_NAME_SHORT]; -+ struct elf_prpsinfo data; -+}; -+ -+struct mrdump_mini_elf_prstatus { -+ struct elf_note note; -+ char name[NOTE_NAME_SHORT]; -+ struct elf_prstatus data; -+}; -+ -+struct mrdump_mini_elf_note { -+ struct elf_note note; -+ char name[NOTE_NAME_LONG]; -+ struct mrdump_mini_elf_misc data; -+}; -+ -+struct mrdump_mini_elf_header { -+ struct elfhdr ehdr; -+ struct elf_phdr phdrs[MRDUMP_MINI_NR_SECTION]; -+ struct mrdump_mini_elf_psinfo psinfo; -+ struct mrdump_mini_elf_prstatus prstatus[NR_CPUS + 1]; -+ struct mrdump_mini_elf_note misc[MRDUMP_MINI_NR_MISC]; -+}; -+ -+typedef struct mrdump_rsvmem_block { -+ phys_addr_t start_addr; -+ phys_addr_t size; -+} mrdump_rsvmem_block_t; -+ -+ -+#define MRDUMP_MINI_HEADER_SIZE ALIGN(sizeof(struct mrdump_mini_elf_header), PAGE_SIZE) -+#define MRDUMP_MINI_DATA_SIZE (MRDUMP_MINI_NR_SECTION * MRDUMP_MINI_SECTION_SIZE) -+#define MRDUMP_MINI_BUF_SIZE (MRDUMP_MINI_HEADER_SIZE + MRDUMP_MINI_DATA_SIZE) -+ -+#ifdef CONFIG_MTK_RAM_CONSOLE_DRAM_ADDR -+#define MRDUMP_MINI_BUF_PADDR (CONFIG_MTK_RAM_CONSOLE_DRAM_ADDR + 0xf0000) -+#else -+#define MRDUMP_MINI_BUF_PADDR 0 -+#endif -+ -+int mrdump_init(void); -+void __mrdump_create_oops_dump(AEE_REBOOT_MODE reboot_mode, struct pt_regs *regs, const char *msg, -+ ...); -+#if defined(CONFIG_MTK_AEE_IPANIC) -+void mrdump_rsvmem(void); -+#else -+static inline void mrdump_rsvmem(void) -+{ -+} -+#endif -+ -+#if defined(CONFIG_MTK_AEE_MRDUMP) -+void aee_kdump_reboot(AEE_REBOOT_MODE, const char *msg, ...); -+#else -+static inline void aee_kdump_reboot(AEE_REBOOT_MODE reboot_mode, const char *msg, ...) -+{ -+} -+#endif -+ -+typedef int (*mrdump_write)(void *buf, int off, int len, int encrypt); -+#if defined(CONFIG_MTK_AEE_IPANIC) -+int mrdump_mini_create_oops_dump(AEE_REBOOT_MODE reboot_mode, mrdump_write write, -+ loff_t sd_offset, const char *msg, va_list ap); -+void mrdump_mini_reserve_memory(void); -+#else -+static inline int mrdump_mini_create_oops_dump(AEE_REBOOT_MODE reboot_mode, mrdump_write write, -+ loff_t sd_offset, const char *msg, va_list ap) -+{ -+ return 0; -+} -+ -+static inline void mrdump_mini_reserve_memory(void) -+{ -+} -+#endif -+ -+#endif -diff --git a/drivers/misc/mediatek/include/mt-plat/mt7622/include/mach/mtk_thermal.h b/drivers/misc/mediatek/include/mt-plat/mt7622/include/mach/mtk_thermal.h -new file mode 100644 -index 000000000000..1b60f007d0fd ---- /dev/null -+++ b/drivers/misc/mediatek/include/mt-plat/mt7622/include/mach/mtk_thermal.h -@@ -0,0 +1,295 @@ -+/* -+ * Copyright (C) 2015 MediaTek Inc. -+ * -+ * 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. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+ -+#ifndef _MT8167_THERMAL_H -+#define _MT8167_THERMAL_H -+ -+#include -+#include -+#include -+#include -+ -+#include -+#include -+ -+#include "sync_write.h" -+ -+extern void __iomem *thermal_base; -+extern void __iomem *auxadc_ts_base; -+extern void __iomem *apmixed_base; -+extern void __iomem *pericfg_base; -+extern int auxadc_ts_phy_base; -+extern int apmixed_phy_base; -+ -+#define THERM_CTRL_BASE_2 thermal_base -+#define AUXADC_BASE_2 auxadc_ts_base -+#define PERICFG_BASE pericfg_base -+#define APMIXED_BASE_2 apmixed_base -+ -+#define MT6752_EVB_BUILD_PASS /*Jerry fix build error FIX_ME*/ -+ -+/******************************************************************************* -+* AUXADC Register Definition -+******************************************************************************/ -+/*AUXADC_BASE: 0xF1001000 from Vincent Liang 2014.5.8*/ -+ -+#define AUXADC_CON0_V (AUXADC_BASE_2 + 0x000) /*yes, 0x11003000*/ -+#define AUXADC_CON1_V (AUXADC_BASE_2 + 0x004) -+#define AUXADC_CON1_SET_V (AUXADC_BASE_2 + 0x008) -+#define AUXADC_CON1_CLR_V (AUXADC_BASE_2 + 0x00C) -+#define AUXADC_CON2_V (AUXADC_BASE_2 + 0x010) -+/*#define AUXADC_CON3_V (AUXADC_BASE_2 + 0x014)*/ -+#define AUXADC_DAT0_V (AUXADC_BASE_2 + 0x014) -+#define AUXADC_DAT1_V (AUXADC_BASE_2 + 0x018) -+#define AUXADC_DAT2_V (AUXADC_BASE_2 + 0x01C) -+#define AUXADC_DAT3_V (AUXADC_BASE_2 + 0x020) -+#define AUXADC_DAT4_V (AUXADC_BASE_2 + 0x024) -+#define AUXADC_DAT5_V (AUXADC_BASE_2 + 0x028) -+#define AUXADC_DAT6_V (AUXADC_BASE_2 + 0x02C) -+#define AUXADC_DAT7_V (AUXADC_BASE_2 + 0x030) -+#define AUXADC_DAT8_V (AUXADC_BASE_2 + 0x034) -+#define AUXADC_DAT9_V (AUXADC_BASE_2 + 0x038) -+#define AUXADC_DAT10_V (AUXADC_BASE_2 + 0x03C) -+#define AUXADC_DAT11_V (AUXADC_BASE_2 + 0x040) -+#define AUXADC_MISC_V (AUXADC_BASE_2 + 0x094) -+ -+#define AUXADC_CON0_P (auxadc_ts_phy_base + 0x000) -+#define AUXADC_CON1_P (auxadc_ts_phy_base + 0x004) -+#define AUXADC_CON1_SET_P (auxadc_ts_phy_base + 0x008) -+#define AUXADC_CON1_CLR_P (auxadc_ts_phy_base + 0x00C) -+#define AUXADC_CON2_P (auxadc_ts_phy_base + 0x010) -+/*#define AUXADC_CON3_P (auxadc_ts_phy_base + 0x014)*/ -+#define AUXADC_DAT0_P (auxadc_ts_phy_base + 0x014) -+#define AUXADC_DAT1_P (auxadc_ts_phy_base + 0x018) -+#define AUXADC_DAT2_P (auxadc_ts_phy_base + 0x01C) -+#define AUXADC_DAT3_P (auxadc_ts_phy_base + 0x020) -+#define AUXADC_DAT4_P (auxadc_ts_phy_base + 0x024) -+#define AUXADC_DAT5_P (auxadc_ts_phy_base + 0x028) -+#define AUXADC_DAT6_P (auxadc_ts_phy_base + 0x02C) -+#define AUXADC_DAT7_P (auxadc_ts_phy_base + 0x030) -+#define AUXADC_DAT8_P (auxadc_ts_phy_base + 0x034) -+#define AUXADC_DAT9_P (auxadc_ts_phy_base + 0x038) -+#define AUXADC_DAT10_P (auxadc_ts_phy_base + 0x03C) -+#define AUXADC_DAT11_P (auxadc_ts_phy_base + 0x040) -+ -+#define AUXADC_MISC_P (auxadc_ts_phy_base + 0x094) -+ -+/******************************************************************************* -+* Peripheral Configuration Register Definition -+******************************************************************************/ -+/*#define PERICFG_BASE (0x10002000)*/ -+#define PERI_GLOBALCON_RST0 (pericfg_base + 0x000) /*yes, 0x10002000*/ -+/******************************************************************************* -+ * APMixedSys Configuration Register Definition -+ ******************************************************************************/ -+#define TS_CON0 (APMIXED_BASE_2 + 0x600) /*yes 0x10209000*/ -+#define TS_CON1 (APMIXED_BASE_2 + 0x604) -+#define TS_CON0_TM (APMIXED_BASE_2 + 0x600) /* yes 0x10209000 */ -+#define TS_CON1_TM (APMIXED_BASE_2 + 0x604) -+#define TS_CON0_P (apmixed_phy_base + 0x600) -+#define TS_CON1_P (apmixed_phy_base + 0x604) -+ -+/******************************************************************************* -+ * Thermal Controller Register Definition -+ ******************************************************************************/ -+#define TEMPMONCTL0 (THERM_CTRL_BASE_2 + 0x000) /*yes 0x1100B000*/ -+#define TEMPMONCTL1 (THERM_CTRL_BASE_2 + 0x004) -+#define TEMPMONCTL2 (THERM_CTRL_BASE_2 + 0x008) -+#define TEMPMONINT (THERM_CTRL_BASE_2 + 0x00C) -+#define TEMPMONINTSTS (THERM_CTRL_BASE_2 + 0x010) -+#define TEMPMONIDET0 (THERM_CTRL_BASE_2 + 0x014) -+#define TEMPMONIDET1 (THERM_CTRL_BASE_2 + 0x018) -+#define TEMPMONIDET2 (THERM_CTRL_BASE_2 + 0x01C) -+#define TEMPH2NTHRE (THERM_CTRL_BASE_2 + 0x024) -+#define TEMPHTHRE (THERM_CTRL_BASE_2 + 0x028) -+#define TEMPCTHRE (THERM_CTRL_BASE_2 + 0x02C) -+#define TEMPOFFSETH (THERM_CTRL_BASE_2 + 0x030) -+#define TEMPOFFSETL (THERM_CTRL_BASE_2 + 0x034) -+#define TEMPMSRCTL0 (THERM_CTRL_BASE_2 + 0x038) -+#define TEMPMSRCTL1 (THERM_CTRL_BASE_2 + 0x03C) -+#define TEMPAHBPOLL (THERM_CTRL_BASE_2 + 0x040) -+#define TEMPAHBTO (THERM_CTRL_BASE_2 + 0x044) -+#define TEMPADCPNP0 (THERM_CTRL_BASE_2 + 0x048) -+#define TEMPADCPNP1 (THERM_CTRL_BASE_2 + 0x04C) -+#define TEMPADCPNP2 (THERM_CTRL_BASE_2 + 0x050) -+#define TEMPADCPNP3 (THERM_CTRL_BASE_2 + 0x0B4) -+ -+#define TEMPADCMUX (THERM_CTRL_BASE_2 + 0x054) -+#define TEMPADCEXT (THERM_CTRL_BASE_2 + 0x058) -+#define TEMPADCEXT1 (THERM_CTRL_BASE_2 + 0x05C) -+#define TEMPADCEN (THERM_CTRL_BASE_2 + 0x060) -+#define TEMPPNPMUXADDR (THERM_CTRL_BASE_2 + 0x064) -+#define TEMPADCMUXADDR (THERM_CTRL_BASE_2 + 0x068) -+#define TEMPADCEXTADDR (THERM_CTRL_BASE_2 + 0x06C) -+#define TEMPADCEXT1ADDR (THERM_CTRL_BASE_2 + 0x070) -+#define TEMPADCENADDR (THERM_CTRL_BASE_2 + 0x074) -+#define TEMPADCVALIDADDR (THERM_CTRL_BASE_2 + 0x078) -+#define TEMPADCVOLTADDR (THERM_CTRL_BASE_2 + 0x07C) -+#define TEMPRDCTRL (THERM_CTRL_BASE_2 + 0x080) -+#define TEMPADCVALIDMASK (THERM_CTRL_BASE_2 + 0x084) -+#define TEMPADCVOLTAGESHIFT (THERM_CTRL_BASE_2 + 0x088) -+#define TEMPADCWRITECTRL (THERM_CTRL_BASE_2 + 0x08C) -+#define TEMPMSR0 (THERM_CTRL_BASE_2 + 0x090) -+#define TEMPMSR1 (THERM_CTRL_BASE_2 + 0x094) -+#define TEMPMSR2 (THERM_CTRL_BASE_2 + 0x098) -+#define TEMPMSR3 (THERM_CTRL_BASE_2 + 0x0B8) -+ -+#define TEMPIMMD0 (THERM_CTRL_BASE_2 + 0x0A0) -+#define TEMPIMMD1 (THERM_CTRL_BASE_2 + 0x0A4) -+#define TEMPIMMD2 (THERM_CTRL_BASE_2 + 0x0A8) -+#define TEMPIMMD3 (THERM_CTRL_BASE_2 + 0x0BC) -+ -+ -+#define TEMPPROTCTL (THERM_CTRL_BASE_2 + 0x0C0) -+#define TEMPPROTTA (THERM_CTRL_BASE_2 + 0x0C4) -+#define TEMPPROTTB (THERM_CTRL_BASE_2 + 0x0C8) -+#define TEMPPROTTC (THERM_CTRL_BASE_2 + 0x0CC) -+ -+#define TEMPSPARE0 (THERM_CTRL_BASE_2 + 0x0F0) -+#define TEMPSPARE1 (THERM_CTRL_BASE_2 + 0x0F4) -+#define TEMPSPARE2 (THERM_CTRL_BASE_2 + 0x0F8) -+#define TEMPSPARE3 (THERM_CTRL_BASE_2 + 0x0FC) -+ -+#define PTPCORESEL (THERM_CTRL_BASE_2 + 0x400) -+#define THERMINTST (THERM_CTRL_BASE_2 + 0x404) -+#define PTPODINTST (THERM_CTRL_BASE_2 + 0x408) -+#define THSTAGE0ST (THERM_CTRL_BASE_2 + 0x40C) -+#define THSTAGE1ST (THERM_CTRL_BASE_2 + 0x410) -+#define THSTAGE2ST (THERM_CTRL_BASE_2 + 0x414) -+#define THAHBST0 (THERM_CTRL_BASE_2 + 0x418) -+#define THAHBST1 (THERM_CTRL_BASE_2 + 0x41C) /*Only for DE debug*/ -+#define PTPSPARE0 (THERM_CTRL_BASE_2 + 0x420) -+#define PTPSPARE1 (THERM_CTRL_BASE_2 + 0x424) -+#define PTPSPARE2 (THERM_CTRL_BASE_2 + 0x428) -+#define PTPSPARE3 (THERM_CTRL_BASE_2 + 0x42C) -+#define THSLPEVEB (THERM_CTRL_BASE_2 + 0x430) -+ -+ -+#define PTPSPARE0_P (thermal_phy_base + 0x420) -+#define PTPSPARE1_P (thermal_phy_base + 0x424) -+#define PTPSPARE2_P (thermal_phy_base + 0x428) -+#define PTPSPARE3_P (thermal_phy_base + 0x42C) -+ -+/******************************************************************************* -+ * Thermal Controller Register Mask Definition -+ ******************************************************************************/ -+#define THERMAL_ENABLE_SEN0 0x1 -+#define THERMAL_ENABLE_SEN1 0x2 -+#define THERMAL_ENABLE_SEN2 0x4 -+#define THERMAL_MONCTL0_MASK 0x00000007 -+ -+#define THERMAL_PUNT_MASK 0x00000FFF -+#define THERMAL_FSINTVL_MASK 0x03FF0000 -+#define THERMAL_SPINTVL_MASK 0x000003FF -+#define THERMAL_MON_INT_MASK 0x0007FFFF -+ -+#define THERMAL_MON_CINTSTS0 0x000001 -+#define THERMAL_MON_HINTSTS0 0x000002 -+#define THERMAL_MON_LOINTSTS0 0x000004 -+#define THERMAL_MON_HOINTSTS0 0x000008 -+#define THERMAL_MON_NHINTSTS0 0x000010 -+#define THERMAL_MON_CINTSTS1 0x000020 -+#define THERMAL_MON_HINTSTS1 0x000040 -+#define THERMAL_MON_LOINTSTS1 0x000080 -+#define THERMAL_MON_HOINTSTS1 0x000100 -+#define THERMAL_MON_NHINTSTS1 0x000200 -+#define THERMAL_MON_CINTSTS2 0x000400 -+#define THERMAL_MON_HINTSTS2 0x000800 -+#define THERMAL_MON_LOINTSTS2 0x001000 -+#define THERMAL_MON_HOINTSTS2 0x002000 -+#define THERMAL_MON_NHINTSTS2 0x004000 -+#define THERMAL_MON_TOINTSTS 0x008000 -+#define THERMAL_MON_IMMDINTSTS0 0x010000 -+#define THERMAL_MON_IMMDINTSTS1 0x020000 -+#define THERMAL_MON_IMMDINTSTS2 0x040000 -+#define THERMAL_MON_FILTINTSTS0 0x080000 -+#define THERMAL_MON_FILTINTSTS1 0x100000 -+#define THERMAL_MON_FILTINTSTS2 0x200000 -+ -+ -+#define THERMAL_tri_SPM_State0 0x20000000 -+#define THERMAL_tri_SPM_State1 0x40000000 -+#define THERMAL_tri_SPM_State2 0x80000000 -+ -+ -+#define THERMAL_MSRCTL0_MASK 0x00000007 -+#define THERMAL_MSRCTL1_MASK 0x00000038 -+#define THERMAL_MSRCTL2_MASK 0x000001C0 -+ -+enum thermal_sensor_name { -+ THERMAL_SENSOR1 = 0,/*TS_MCU1*/ -+ THERMAL_SENSOR_NUM -+}; -+ -+enum thermal_bank_name { -+ THERMAL_BANK0 = 0, /*CPU (TS_MCU1) (TS1)*/ -+ THERMAL_BANK_NUM -+}; -+ -+struct TS_SVS { -+ unsigned int ts_MTS; -+ unsigned int ts_BTS; -+}; -+ -+struct mtk_gpu_power_info { -+ unsigned int gpufreq_khz; -+ unsigned int gpufreq_power; -+}; -+ -+/* svs driver need this function */ -+extern void get_thermal_slope_intercept(struct TS_SVS *ts_info, enum thermal_bank_name ts_bank); -+ -+/* mtk_thermal_platform.c need this */ -+extern void set_taklking_flag(bool flag); -+ -+#define THERMAL_WRAP_WR32(val, addr) mt_reg_sync_writel((val), ((void *)addr)) -+ -+enum MTK_THERMAL_SENSOR_CPU_ID_MET { -+ MTK_THERMAL_SENSOR_TS1 = 0, -+ MTK_THERMAL_SENSOR_TS2, -+ MTK_THERMAL_SENSOR_TS3, -+ MTK_THERMAL_SENSOR_TS4, -+ MTK_THERMAL_SENSOR_TSABB, -+ -+ ATM_CPU_LIMIT, -+ ATM_GPU_LIMIT, -+ -+ MTK_THERMAL_SENSOR_CPU_COUNT -+}; -+ -+extern int tscpu_get_cpu_temp_met(enum MTK_THERMAL_SENSOR_CPU_ID_MET id); -+extern int mtk_gpufreq_register(struct mtk_gpu_power_info *freqs, int num); -+ -+typedef void (*met_thermalsampler_funcMET)(void); -+void mt_thermalsampler_registerCB(met_thermalsampler_funcMET pCB); -+ -+void tscpu_start_thermal(void); -+void tscpu_stop_thermal(void); -+void tscpu_cancel_thermal_timer(void); -+void tscpu_start_thermal_timer(void); -+int mtkts_bts_get_hw_temp(void); -+ -+extern int get_immediate_ts1_wrap(void); -+extern int get_immediate_ts2_wrap(void); -+extern int get_immediate_ts3_wrap(void); -+ -+extern int is_cpu_power_unlimit(void); /* in mtk_ts_cpu.c */ -+extern int is_cpu_power_min(void); /* in mtk_ts_cpu.c */ -+extern int get_cpu_target_tj(void); -+extern int get_cpu_target_offset(void); -+ -+extern int mtktscpu_debug_log; -+ -+#endif -+ -diff --git a/drivers/misc/mediatek/include/mt-plat/mt8127/include/mach/mt_freqhopping.h b/drivers/misc/mediatek/include/mt-plat/mt8127/include/mach/mt_freqhopping.h -new file mode 100644 -index 000000000000..142a007805b9 ---- /dev/null -+++ b/drivers/misc/mediatek/include/mt-plat/mt8127/include/mach/mt_freqhopping.h -@@ -0,0 +1,159 @@ -+/* -+ * Copyright (C) 2011 MediaTek, Inc. -+ * -+ * Author: Holmes Chiou -+ * -+ * This software is licensed under the terms of the GNU General Public -+ * License version 2, as published by the Free Software Foundation, and -+ * may be copied, distributed, and modified under those terms. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ */ -+ -+#ifndef __MT_FREQHOPPING_H__ -+#define __MT_FREQHOPPING_H__ -+ -+#define MT_FHPLL_MAX 6 -+#define MT_SSC_NR_PREDEFINE_SETTING 10 /* TODO: is 10 a good number ? */ -+ -+#define MEMPLL_SSC 0 -+#define MAINPLL_SSC 1 -+ -+#define FHTAG "[FH]" -+ -+#define VERBOSE_DEBUG 0 -+ -+#if VERBOSE_DEBUG -+#define FH_MSG(fmt, args...) \ -+ pr_debug(FHTAG""fmt" <- %s(): L<%d> PID<%s><%d>\n", ##args, __func__, __LINE__, current->comm, current->pid) -+#else -+ -+#if 1 /* log level is 6 xlog */ -+#define FH_MSG(fmt, args...) pr_debug(fmt, ##args) -+#else /* log level is 4 (printk) */ -+#define FH_MSG(fmt, args...) printk(FHTAG""fmt"\n", ##args) -+#endif -+ -+#endif -+ -+/* not support at mt2701 yet */ -+/* DRAMC */ -+#define FULLY_VERSION_FHCTL 0 -+ -+enum FH_FH_STATUS { -+ FH_FH_DISABLE = 0, -+ FH_FH_ENABLE_SSC, -+ FH_FH_ENABLE_DFH, -+ FH_FH_ENABLE_DVFS, -+}; -+ -+enum FH_PLL_STATUS { -+ FH_PLL_DISABLE = 0, -+ FH_PLL_ENABLE = 1 -+}; -+ -+/* TODO: FREQ_MODIFIED should not be here */ -+/* FH_PLL_STATUS_FREQ_MODIFIED = 3 */ -+ -+ -+enum FH_CMD { -+ FH_CMD_ENABLE = 1, -+ FH_CMD_DISABLE, -+ FH_CMD_ENABLE_USR_DEFINED, -+ FH_CMD_DISABLE_USR_DEFINED, -+ FH_CMD_INTERNAL_MAX_CMD, -+/* TODO: do we need these cmds ? -+ * FH_CMD_PLL_ENABLE, -+ * FH_CMD_PLL_DISABLE, -+ * FH_CMD_EXT_ALL_FULL_RANGE_CMD, -+ * FH_CMD_EXT_ALL_HALF_RANGE_CMD, -+ * FH_CMD_EXT_DISABLE_ALL_CMD, -+ * FH_CMD_EXT_DESIGNATED_PLL_FULL_RANGE_CMD, -+ * FH_CMD_EXT_DESIGNATED_PLL_AND_SETTING_CMD -+*/ -+}; -+ -+/* -+ * enum FH_OPCODE{ -+ * FH_OPCODE_ENABLE_WITH_ID = 1, -+ * FH_OPCODE_ENABLE_WITHOUT_ID, -+ * FH_OPCODE_DISABLE, -+ * }; -+*/ -+ -+enum FH_PLL_ID { -+ MT658X_FH_MINIMUMM_PLL = 0, -+ MT658X_FH_ARM_PLL = MT658X_FH_MINIMUMM_PLL, -+ MT658X_FH_MAIN_PLL = 1, -+ MT658X_FH_MEM_PLL = 2, -+ MT658X_FH_MSDC_PLL = 3, -+ MT658X_FH_MM_PLL = 4, /* MT658X_FH_TVD_PLL = 4, */ -+ MT658X_FH_VENC_PLL = 5, /* MT658X_FH_LVDS_PLL = 5, */ -+ /* 8127 FHCTL MB */ -+ MT658X_FH_TVD_PLL = 6, /* MT658X_FH_TVD_PLL = 6, */ -+ MT658X_FH_MAXIMUMM_PLL = MT658X_FH_TVD_PLL, -+ /* 8127 FHCTL ME */ -+ MT658X_FH_PLL_TOTAL_NUM -+}; -+ -+/* keep track the status of each PLL */ -+/* TODO: do we need another "uint mode" for Dynamic FH */ -+typedef struct { -+ unsigned int fh_status; -+ unsigned int pll_status; -+ unsigned int setting_id; -+ unsigned int curr_freq; -+ unsigned int user_defined; -+} fh_pll_t; -+ -+ -+/* Record the owner of enable freq hopping <==TBD */ -+struct freqhopping_pll { -+ union { -+ int mt_pll[MT_FHPLL_MAX]; -+ struct { -+ int mt_arm_fhpll; -+ int mt_main_fhpll; -+ int mt_mem_fhpll; -+ int mt_msdc_fhpll; -+ int mt_mm_fhpll; -+ int mt_venc_fhpll; -+ }; -+ }; -+}; -+ -+struct freqhopping_ssc { -+ unsigned int freq; -+ unsigned int dt; -+ unsigned int df; -+ unsigned int upbnd; -+ unsigned int lowbnd; -+ unsigned int dds; -+}; -+ -+struct freqhopping_ioctl { -+ unsigned int pll_id; -+ struct freqhopping_ssc ssc_setting; /* used only when user-define */ -+ int result; -+}; -+ -+int freqhopping_config(unsigned int pll_id, unsigned long vco_freq, unsigned int enable); -+void mt_freqhopping_init(void); -+void mt_freqhopping_pll_init(void); -+int mt_h2l_mempll(void); -+int mt_l2h_mempll(void); -+int mt_h2l_dvfs_mempll(void); -+int mt_l2h_dvfs_mempll(void); -+int mt_dfs_armpll(unsigned int current_freq, unsigned int target_freq); -+int mt_is_support_DFS_mode(void); -+void mt_fh_popod_save(void); -+void mt_fh_popod_restore(void); -+int mt_fh_dram_overclock(int clk); -+int mt_fh_get_dramc(void); -+unsigned int mt_get_emi_freq(void); -+ -+#endif /* !__MT_FREQHOPPING_H__ */ -diff --git a/drivers/misc/mediatek/include/mt-plat/mt8127/include/mach/mt_spm_mtcmos.h b/drivers/misc/mediatek/include/mt-plat/mt8127/include/mach/mt_spm_mtcmos.h -new file mode 100644 -index 000000000000..0c049db9aa97 ---- /dev/null -+++ b/drivers/misc/mediatek/include/mt-plat/mt8127/include/mach/mt_spm_mtcmos.h -@@ -0,0 +1,37 @@ -+/* -+ * Copyright (c) 2015 MediaTek Inc. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#include -+ -+#define STA_POWER_DOWN 0 -+#define STA_POWER_ON 1 -+ -+/* -+ * 1. for CPU MTCMOS: CPU0, CPU1, CPU2, CPU3, DBG0, CPU4, CPU5, CPU6, CPU7, DBG1, CPUSYS1 -+ * 2. call spm_mtcmos_cpu_lock/unlock() before/after any operations -+ */ -+extern int spm_mtcmos_cpu_init(void); -+extern void spm_mtcmos_cpu_lock(unsigned long *flags); -+extern void spm_mtcmos_cpu_unlock(unsigned long *flags); -+extern int spm_mtcmos_ctrl_cpu(unsigned int cpu, int state, int chkWfiBeforePdn); -+extern int spm_mtcmos_ctrl_cpu0(int state, int chkWfiBeforePdn); -+extern int spm_mtcmos_ctrl_cpu1(int state, int chkWfiBeforePdn); -+extern int spm_mtcmos_ctrl_cpu2(int state, int chkWfiBeforePdn); -+extern int spm_mtcmos_ctrl_cpu3(int state, int chkWfiBeforePdn); -+extern int spm_mtcmos_ctrl_cpu4(int state, int chkWfiBeforePdn); -+extern int spm_mtcmos_ctrl_cpu5(int state, int chkWfiBeforePdn); -+extern int spm_mtcmos_ctrl_cpu6(int state, int chkWfiBeforePdn); -+extern int spm_mtcmos_ctrl_cpu7(int state, int chkWfiBeforePdn); -+extern int spm_mtcmos_ctrl_cpusys0(int state, int chkWfiBeforePdn); -+extern bool spm_cpusys0_can_power_down(void); -diff --git a/drivers/misc/mediatek/include/mt-plat/mt8127/include/mach/mtk_boot_share_page.h b/drivers/misc/mediatek/include/mt-plat/mt8127/include/mach/mtk_boot_share_page.h -new file mode 100644 -index 000000000000..28176b3cd9af ---- /dev/null -+++ b/drivers/misc/mediatek/include/mt-plat/mt8127/include/mach/mtk_boot_share_page.h -@@ -0,0 +1,40 @@ -+/* -+ * Copyright (c) 2015 MediaTek Inc. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#ifndef __MTK_BOOT_SHARE_PAGE_H__ -+#define __MTK_BOOT_SHARE_PAGE_H__ -+ -+#define BOOT_SHARE_BASE (0xC0002000) /* address in linux kernel */ -+#define BOOT_SHARE_SIZE (0x1000) /* page size 4K bytes */ -+ -+#define BOOT_SHARE_MAGIC (0x4545544D) /* MTEE */ -+ -+/* Memory map & defines for boot share page */ -+/* -+ * Note: -+ * 1. BOOT_SHARE_XXXXX_OFST is the address offset related to BOOT_SHARE_BASE -+ */ -+#define BOOT_SHARE_MAGIC1_OFST (0) -+#define BOOT_SHARE_MAGIC1_SIZE (4) -+ -+#define BOOT_SHARE_DEV_INFO_OFST (BOOT_SHARE_MAGIC1_OFST+BOOT_SHARE_MAGIC1_SIZE) -+#define BOOT_SHARE_DEV_INFO_SIZE (16) -+ -+#define BOOT_SHARE_HOTPLUG_OFST (1008) /* 16 bytes for hotplug/jump-reg */ -+#define BOOT_SHARE_HOTPLUG_SIZE (32) -+ -+#define BOOT_SHARE_MAGIC2_OFST (4092) -+#define BOOT_SHARE_MAGIC2_SIZE (4) -+ -+#endif /* __MTK_BOOT_SHARE_PAGE_H__ */ -diff --git a/drivers/misc/mediatek/include/mt-plat/mt8127/include/mach/mtk_thermal.h b/drivers/misc/mediatek/include/mt-plat/mt8127/include/mach/mtk_thermal.h -new file mode 100644 -index 000000000000..eefdaad4aaa5 ---- /dev/null -+++ b/drivers/misc/mediatek/include/mt-plat/mt8127/include/mach/mtk_thermal.h -@@ -0,0 +1,301 @@ -+/* -+ * Copyright (C) 2016 MediaTek Inc. -+ * -+ * 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. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+ * See http://www.gnu.org/licenses/gpl-2.0.html for more details. -+ */ -+ -+#ifndef _MT8127_THERMAL_H -+#define _MT8127_THERMAL_H -+ -+#include -+#include -+#include -+#include -+ -+#include -+#include -+ -+#include "mt-plat/sync_write.h" -+#include -+ -+/* #include */ -+/* #include "../../../../../thermal/mt8127/inc/mt_gpufreq.h" */ -+ -+#if 1 -+extern void __iomem *thermal_base; -+extern void __iomem *auxadc_ts_base; -+extern void __iomem *pericfg_base; -+extern void __iomem *apmixed_ts_base; -+ -+extern int mtktscpu_limited_dmips; -+ -+void __attribute__ ((weak)) mt_gpufreq_thermal_protect(unsigned int limited_power) { -+} -+ -+unsigned int __attribute__ ((weak)) mt_gpufreq_get_cur_freq(void) { -+ return 0; -+} -+ -+u32 __attribute__ ((weak)) get_devinfo_with_index(u32 index) { -+ return 0; -+} -+ -+extern int IMM_GetOneChannelValue(int dwChannel, int data[4], int *rawdata); -+extern int IMM_IsAdcInitReady(void); -+extern int PMIC_IMM_GetOneChannelValue(int dwChannel, int deCount, int trimd); -+extern int thermal_phy_base; -+extern int auxadc_ts_phy_base; -+extern int apmixed_phy_base; -+extern int pericfg_phy_base; -+ -+/* extern int last_abb_t; */ -+/* extern int last_CPU2_t; */ -+extern int get_immediate_temp2_wrap(void); -+extern void mtkts_dump_cali_info(void); -+extern u32 get_devinfo_with_index(u32 index); -+extern int bts_cur_temp; -+ -+#define THERM_CTRL_BASE_2 thermal_base -+#define AUXADC_BASE_2 auxadc_ts_base -+#define PERICFG_BASE_2 pericfg_base -+#define APMIXED_BASE_2 apmixed_ts_base -+#endif -+ -+/******************************************************************************* -+ * AUXADC Register Definition -+ ******************************************************************************/ -+#define AUXADC_CON0_V (AUXADC_BASE_2 + 0x000) /* yes, 0x11001000 */ -+#define AUXADC_CON1_V (AUXADC_BASE_2 + 0x004) -+#define AUXADC_CON1_SET_V (AUXADC_BASE_2 + 0x008) -+#define AUXADC_CON1_CLR_V (AUXADC_BASE_2 + 0x00C) -+#define AUXADC_CON2_V (AUXADC_BASE_2 + 0x010) -+#define AUXADC_DAT0_V (AUXADC_BASE_2 + 0x014) -+#define AUXADC_DAT1_V (AUXADC_BASE_2 + 0x018) -+#define AUXADC_DAT2_V (AUXADC_BASE_2 + 0x01C) -+#define AUXADC_DAT3_V (AUXADC_BASE_2 + 0x020) -+#define AUXADC_DAT4_V (AUXADC_BASE_2 + 0x024) -+#define AUXADC_DAT5_V (AUXADC_BASE_2 + 0x028) -+#define AUXADC_DAT6_V (AUXADC_BASE_2 + 0x02C) -+#define AUXADC_DAT7_V (AUXADC_BASE_2 + 0x030) -+#define AUXADC_DAT8_V (AUXADC_BASE_2 + 0x034) -+#define AUXADC_DAT9_V (AUXADC_BASE_2 + 0x038) -+#define AUXADC_DAT10_V (AUXADC_BASE_2 + 0x03C) -+#define AUXADC_DAT11_V (AUXADC_BASE_2 + 0x040) -+#define AUXADC_MISC_V (AUXADC_BASE_2 + 0x094) -+#define AUXADC_CON0_P (auxadc_ts_phy_base + 0x000) -+#define AUXADC_CON1_P (auxadc_ts_phy_base + 0x004) -+#define AUXADC_CON1_SET_P (auxadc_ts_phy_base + 0x008) -+#define AUXADC_CON1_CLR_P (auxadc_ts_phy_base + 0x00C) -+#define AUXADC_CON2_P (auxadc_ts_phy_base + 0x010) -+#define AUXADC_DAT0_P (auxadc_ts_phy_base + 0x014) -+#define AUXADC_DAT1_P (auxadc_ts_phy_base + 0x018) -+#define AUXADC_DAT2_P (auxadc_ts_phy_base + 0x01C) -+#define AUXADC_DAT3_P (auxadc_ts_phy_base + 0x020) -+#define AUXADC_DAT4_P (auxadc_ts_phy_base + 0x024) -+#define AUXADC_DAT5_P (auxadc_ts_phy_base + 0x028) -+#define AUXADC_DAT6_P (auxadc_ts_phy_base + 0x02C) -+#define AUXADC_DAT7_P (auxadc_ts_phy_base + 0x030) -+#define AUXADC_DAT8_P (auxadc_ts_phy_base + 0x034) -+#define AUXADC_DAT9_P (auxadc_ts_phy_base + 0x038) -+#define AUXADC_DAT10_P (auxadc_ts_phy_base + 0x03C) -+#define AUXADC_DAT11_P (auxadc_ts_phy_base + 0x040) -+#define AUXADC_MISC_P (auxadc_ts_phy_base + 0x094) -+ -+/******************************************************************************* -+ * Peripheral Configuration Register Definition -+ ******************************************************************************/ -+#define PERI_GLOBALCON_RST0 (PERICFG_BASE_2 + 0x000) /* yes, 0x10003000 */ -+ -+/******************************************************************************* -+ * APMixedSys Configuration Register Definition -+ ******************************************************************************/ -+#define TS_CON0 (APMIXED_BASE_2 + 0x600) /* yes 0x10209000 */ -+#define TS_CON1 (APMIXED_BASE_2 + 0x604) -+/******************************************************************************* -+ * Thermal Controller Register Definition -+ ******************************************************************************/ -+#define TEMPMONCTL0 (THERM_CTRL_BASE_2 + 0x000) /* yes 0x1100B000 */ -+#define TEMPMONCTL1 (THERM_CTRL_BASE_2 + 0x004) -+#define TEMPMONCTL2 (THERM_CTRL_BASE_2 + 0x008) -+#define TEMPMONINT (THERM_CTRL_BASE_2 + 0x00C) -+#define TEMPMONINTSTS (THERM_CTRL_BASE_2 + 0x010) -+#define TEMPMONIDET0 (THERM_CTRL_BASE_2 + 0x014) -+#define TEMPMONIDET1 (THERM_CTRL_BASE_2 + 0x018) -+#define TEMPMONIDET2 (THERM_CTRL_BASE_2 + 0x01C) -+#define TEMPH2NTHRE (THERM_CTRL_BASE_2 + 0x024) -+#define TEMPHTHRE (THERM_CTRL_BASE_2 + 0x028) -+#define TEMPCTHRE (THERM_CTRL_BASE_2 + 0x02C) -+#define TEMPOFFSETH (THERM_CTRL_BASE_2 + 0x030) -+#define TEMPOFFSETL (THERM_CTRL_BASE_2 + 0x034) -+#define TEMPMSRCTL0 (THERM_CTRL_BASE_2 + 0x038) -+#define TEMPMSRCTL1 (THERM_CTRL_BASE_2 + 0x03C) -+#define TEMPAHBPOLL (THERM_CTRL_BASE_2 + 0x040) -+#define TEMPAHBTO (THERM_CTRL_BASE_2 + 0x044) -+#define TEMPADCPNP0 (THERM_CTRL_BASE_2 + 0x048) -+#define TEMPADCPNP1 (THERM_CTRL_BASE_2 + 0x04C) -+#define TEMPADCPNP2 (THERM_CTRL_BASE_2 + 0x050) -+#define TEMPADCPNP3 (THERM_CTRL_BASE_2 + 0x0B4) -+ -+#define TEMPADCMUX (THERM_CTRL_BASE_2 + 0x054) -+#define TEMPADCEXT (THERM_CTRL_BASE_2 + 0x058) -+#define TEMPADCEXT1 (THERM_CTRL_BASE_2 + 0x05C) -+#define TEMPADCEN (THERM_CTRL_BASE_2 + 0x060) -+#define TEMPPNPMUXADDR (THERM_CTRL_BASE_2 + 0x064) -+#define TEMPADCMUXADDR (THERM_CTRL_BASE_2 + 0x068) -+#define TEMPADCEXTADDR (THERM_CTRL_BASE_2 + 0x06C) -+#define TEMPADCEXT1ADDR (THERM_CTRL_BASE_2 + 0x070) -+#define TEMPADCENADDR (THERM_CTRL_BASE_2 + 0x074) -+#define TEMPADCVALIDADDR (THERM_CTRL_BASE_2 + 0x078) -+#define TEMPADCVOLTADDR (THERM_CTRL_BASE_2 + 0x07C) -+#define TEMPRDCTRL (THERM_CTRL_BASE_2 + 0x080) -+#define TEMPADCVALIDMASK (THERM_CTRL_BASE_2 + 0x084) -+#define TEMPADCVOLTAGESHIFT (THERM_CTRL_BASE_2 + 0x088) -+#define TEMPADCWRITECTRL (THERM_CTRL_BASE_2 + 0x08C) -+#define TEMPMSR0 (THERM_CTRL_BASE_2 + 0x090) -+#define TEMPMSR1 (THERM_CTRL_BASE_2 + 0x094) -+#define TEMPMSR2 (THERM_CTRL_BASE_2 + 0x098) -+#define TEMPMSR3 (THERM_CTRL_BASE_2 + 0x0B8) -+ -+#define TEMPIMMD0 (THERM_CTRL_BASE_2 + 0x0A0) -+#define TEMPIMMD1 (THERM_CTRL_BASE_2 + 0x0A4) -+#define TEMPIMMD2 (THERM_CTRL_BASE_2 + 0x0A8) -+ -+#define TEMPPROTCTL (THERM_CTRL_BASE_2 + 0x0C0) -+#define TEMPPROTTA (THERM_CTRL_BASE_2 + 0x0C4) -+#define TEMPPROTTB (THERM_CTRL_BASE_2 + 0x0C8) -+#define TEMPPROTTC (THERM_CTRL_BASE_2 + 0x0CC) -+ -+#define TEMPSPARE0 (THERM_CTRL_BASE_2 + 0x0F0) -+#define TEMPSPARE1 (THERM_CTRL_BASE_2 + 0x0F4) -+#define TEMPSPARE2 (THERM_CTRL_BASE_2 + 0x0F8) -+#define TEMPSPARE3 (THERM_CTRL_BASE_2 + 0x0FC) -+ -+#define PTPCORESEL (THERM_CTRL_BASE_2 + 0x400) -+#define THERMINTST (THERM_CTRL_BASE_2 + 0x404) -+#define PTPODINTST (THERM_CTRL_BASE_2 + 0x408) -+#define THSTAGE0ST (THERM_CTRL_BASE_2 + 0x40C) -+#define THSTAGE1ST (THERM_CTRL_BASE_2 + 0x410) -+#define THSTAGE2ST (THERM_CTRL_BASE_2 + 0x414) -+#define THAHBST0 (THERM_CTRL_BASE_2 + 0x418) -+#define THAHBST1 (THERM_CTRL_BASE_2 + 0x41C) /* Only for DE debug */ -+#define PTPSPARE0 (THERM_CTRL_BASE_2 + 0x420) -+#define PTPSPARE1 (THERM_CTRL_BASE_2 + 0x424) -+#define PTPSPARE2 (THERM_CTRL_BASE_2 + 0x428) -+#define PTPSPARE3 (THERM_CTRL_BASE_2 + 0x42C) -+#define THSLPEVEB (THERM_CTRL_BASE_2 + 0x430) -+ -+/******************************************************************************* -+ * Thermal Controller Register Mask Definition -+ ******************************************************************************/ -+#define THERMAL_ENABLE_SEN0 0x1 -+#define THERMAL_ENABLE_SEN1 0x2 -+#define THERMAL_ENABLE_SEN2 0x4 -+#define THERMAL_MONCTL0_MASK 0x00000007 -+ -+#define THERMAL_PUNT_MASK 0x00000FFF -+#define THERMAL_FSINTVL_MASK 0x03FF0000 -+#define THERMAL_SPINTVL_MASK 0x000003FF -+#define THERMAL_MON_INT_MASK 0x0007FFFF -+ -+#define THERMAL_MON_CINTSTS0 0x000001 -+#define THERMAL_MON_HINTSTS0 0x000002 -+#define THERMAL_MON_LOINTSTS0 0x000004 -+#define THERMAL_MON_HOINTSTS0 0x000008 -+#define THERMAL_MON_NHINTSTS0 0x000010 -+#define THERMAL_MON_CINTSTS1 0x000020 -+#define THERMAL_MON_HINTSTS1 0x000040 -+#define THERMAL_MON_LOINTSTS1 0x000080 -+#define THERMAL_MON_HOINTSTS1 0x000100 -+#define THERMAL_MON_NHINTSTS1 0x000200 -+#define THERMAL_MON_CINTSTS2 0x000400 -+#define THERMAL_MON_HINTSTS2 0x000800 -+#define THERMAL_MON_LOINTSTS2 0x001000 -+#define THERMAL_MON_HOINTSTS2 0x002000 -+#define THERMAL_MON_NHINTSTS2 0x004000 -+#define THERMAL_MON_TOINTSTS 0x008000 -+#define THERMAL_MON_IMMDINTSTS0 0x010000 -+#define THERMAL_MON_IMMDINTSTS1 0x020000 -+#define THERMAL_MON_IMMDINTSTS2 0x040000 -+#define THERMAL_MON_FILTINTSTS0 0x080000 -+#define THERMAL_MON_FILTINTSTS1 0x100000 -+#define THERMAL_MON_FILTINTSTS2 0x200000 -+ -+ -+#define THERMAL_tri_SPM_State0 0x20000000 -+#define THERMAL_tri_SPM_State1 0x40000000 -+#define THERMAL_tri_SPM_State2 0x80000000 -+ -+ -+#define THERMAL_MSRCTL0_MASK 0x00000007 -+#define THERMAL_MSRCTL1_MASK 0x00000038 -+#define THERMAL_MSRCTL2_MASK 0x000001C0 -+ -+/* extern int thermal_one_shot_handler(int times); */ -+ -+typedef enum { -+ THERMAL_SENSOR1 = 0, /* TS1 */ -+ THERMAL_SENSOR_NUM -+} thermal_sensor_name; -+ -+struct TS_PTPOD { -+ unsigned int ts_MTS; -+ unsigned int ts_BTS; -+}; -+ -+extern void get_thermal_slope_intercept(struct TS_PTPOD *ts_info); -+extern void set_taklking_flag(bool flag); -+extern int tscpu_get_cpu_temp(void); -+ -+/*5 thermal sensors*/ -+typedef enum { -+ MTK_THERMAL_SENSOR_TS1 = 0, -+ ATM_CPU_LIMIT, -+ ATM_GPU_LIMIT, -+ MTK_THERMAL_SENSOR_CPU_COUNT -+} MTK_THERMAL_SENSOR_CPU_ID_MET; -+ -+struct mtk_cpu_power_info { -+ unsigned int cpufreq_khz; -+ unsigned int cpufreq_ncpu; -+ unsigned int cpufreq_power; -+}; -+extern int mtk_cpufreq_register(struct mtk_cpu_power_info *freqs, int num); -+ -+extern int tscpu_get_cpu_temp_met(MTK_THERMAL_SENSOR_CPU_ID_MET id); -+ -+ -+typedef void (*met_thermalsampler_funcMET) (void); -+void mt_thermalsampler_registerCB(met_thermalsampler_funcMET pCB); -+ -+void tscpu_start_thermal(void); -+void tscpu_stop_thermal(void); -+void tscpu_cancel_thermal_timer(void); -+void tscpu_start_thermal_timer(void); -+int mtkts_AP_get_hw_temp(void); -+ -+extern int amddulthro_backoff(int level); -+/* extern int IMM_GetOneChannelValue(int dwChannel, int data[4], int *rawdata); */ -+/* extern int IMM_IsAdcInitReady(void); */ -+extern int get_immediate_temp2_wrap(void); -+extern void mtkts_dump_cali_info(void); -+extern unsigned int read_dram_temperature(void); -+extern int mtk_thermal_get_cpu_load_sum(void); -+ -+/********************************** -+ * Power table struct for thermal -+ **********************************/ -+struct mt_gpufreq_power_table_info { -+ unsigned int gpufreq_khz; -+ unsigned int gpufreq_volt; -+ unsigned int gpufreq_power; -+}; -+ -+extern int mtk_gpufreq_register(struct mt_gpufreq_power_table_info *freqs, int num); -+#endif -diff --git a/drivers/misc/mediatek/include/mt-plat/mt_sched.h b/drivers/misc/mediatek/include/mt-plat/mt_sched.h -new file mode 100644 -index 000000000000..71206f080548 ---- /dev/null -+++ b/drivers/misc/mediatek/include/mt-plat/mt_sched.h -@@ -0,0 +1,34 @@ -+/* -+* Copyright (C) 2016 MediaTek Inc. -+* -+* 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. -+* -+* This program is distributed in the hope that it will be useful, -+* but WITHOUT ANY WARRANTY; without even the implied warranty of -+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -+* See http://www.gnu.org/licenses/gpl-2.0.html for more details. -+*/ -+ -+#ifdef CONFIG_MTK_SCHED_RQAVG_US -+/* -+ * @cpu: cpu id -+ * @reset: reset the statistic start time after this time query -+ * @use_maxfreq: caculate cpu loading with max cpu max frequency -+ * return: cpu loading as percentage (0~100) -+ */ -+extern unsigned int sched_get_percpu_load(int cpu, bool reset, bool use_maxfreq); -+ -+/* -+ * return: heavy task(loading>90%) number in the system -+ */ -+extern unsigned int sched_get_nr_heavy_task(void); -+ -+/* -+ * @threshold: heavy task loading threshold (0~1023) -+ * return: heavy task(loading>threshold) number in the system -+ */ -+extern unsigned int sched_get_nr_heavy_task_by_threshold(unsigned int threshold); -+#endif /* CONFIG_MTK_SCHED_RQAVG_US */ -+ -diff --git a/drivers/misc/mediatek/include/mt-plat/mtk_io.h b/drivers/misc/mediatek/include/mt-plat/mtk_io.h -new file mode 100644 -index 000000000000..de17db505d3e ---- /dev/null -+++ b/drivers/misc/mediatek/include/mt-plat/mtk_io.h -@@ -0,0 +1,23 @@ -+/* -+ * Copyright (C) 2015 MediaTek Inc. -+ * -+ * 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. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#ifndef __MT_IO_H__ -+#define __MT_IO_H__ -+ -+/* only for arm64 */ -+#ifdef CONFIG_ARM64 -+#define IOMEM(a) ((void __force __iomem *)((a))) -+#endif -+ -+#endif /* !__MT_IO_H__ */ -+ -diff --git a/drivers/misc/mediatek/include/mt-plat/mtk_lpae.h b/drivers/misc/mediatek/include/mt-plat/mtk_lpae.h -new file mode 100644 -index 000000000000..d679c5a1ce73 ---- /dev/null -+++ b/drivers/misc/mediatek/include/mt-plat/mtk_lpae.h -@@ -0,0 +1,62 @@ -+/* -+ * Copyright (C) 2016 MediaTek Inc. -+ * -+ * 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. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#ifndef __MTK_LPAE_H__ -+#define __MTK_LPAE_H__ -+#ifdef CONFIG_MTK_LM_MODE -+ -+#include -+ -+#define INTERAL_MAPPING_OFFSET (0x40000000) -+#define INTERAL_MAPPING_LIMIT (INTERAL_MAPPING_OFFSET + 0x80000000) -+ -+#define MT_OVERFLOW_ADDR_START 0x100000000ULL -+ -+unsigned int __attribute__((weak)) enable_4G(void) -+{ -+ return 0; -+} -+ -+/* For HW modules which support 33-bit address setting */ -+#define CROSS_OVERFLOW_ADDR_TRANSFER(phy_addr, size, ret) \ -+ do { \ -+ ret = 0; \ -+ if (enable_4G()) {\ -+ if (((phys_addr_t)phy_addr < MT_OVERFLOW_ADDR_START)\ -+ && (((phys_addr_t)phy_addr + size) >= MT_OVERFLOW_ADDR_START)) \ -+ ret = MT_OVERFLOW_ADDR_START - phy_addr; \ -+ } \ -+ } while (0) \ -+ -+/* For SPM and MD32 only in ROME */ -+#define MAPPING_DRAM_ACCESS_ADDR(phy_addr) \ -+ do { \ -+ if (enable_4G()) {\ -+ if (phy_addr >= INTERAL_MAPPING_OFFSET && phy_addr < INTERAL_MAPPING_LIMIT) \ -+ phy_addr += INTERAL_MAPPING_OFFSET; \ -+ } \ -+ } while (0)\ -+ -+#else /* !CONFIG_ARM_LPAE */ -+ -+#define CROSS_OVERFLOW_ADDR_TRANSFER(phy_addr, size, ret) -+#define MAPPING_DRAM_ACCESS_ADDR(phy_addr) -+#define MT_OVERFLOW_ADDR_START 0 -+ -+static inline unsigned int enable_4G(void) -+{ -+ return 0; -+} -+ -+#endif -+#endif /*!__MTK_LPAE_H__ */ -diff --git a/drivers/misc/mediatek/include/mt-plat/mtk_mdm_monitor.h b/drivers/misc/mediatek/include/mt-plat/mtk_mdm_monitor.h -new file mode 100644 -index 000000000000..7baafc4329bf ---- /dev/null -+++ b/drivers/misc/mediatek/include/mt-plat/mtk_mdm_monitor.h -@@ -0,0 +1,42 @@ -+/* -+ * Copyright (C) 2015 MediaTek Inc. -+ * -+ * 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. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#ifndef _MTK_MDM_MONITOR_H -+#define _MTK_MDM_MONITOR_H -+ -+struct md_info { -+ char *attribute; -+ int value; -+ char *unit; -+ int invalid_value; -+ int index; -+}; -+ -+extern -+int mtk_mdm_get_md_info(struct md_info **p_inf, int *size); -+ -+extern -+int mtk_mdm_start_query(void); -+ -+extern -+int mtk_mdm_stop_query(void); -+ -+extern -+int mtk_mdm_set_signal_period(int second); -+ -+extern -+int mtk_mdm_set_md1_signal_period(int second); -+ -+extern -+int mtk_mdm_set_md2_signal_period(int second); -+#endif -diff --git a/drivers/misc/mediatek/include/mt-plat/mtk_platform_debug.h b/drivers/misc/mediatek/include/mt-plat/mtk_platform_debug.h -new file mode 100644 -index 000000000000..8f20f38b75d6 ---- /dev/null -+++ b/drivers/misc/mediatek/include/mt-plat/mtk_platform_debug.h -@@ -0,0 +1,28 @@ -+/* -+ * Copyright (C) 2016 MediaTek Inc. -+ * -+ * 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. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#ifndef __MTK_PLATFORM_DEBUG_H__ -+#define __MTK_PLATFORM_DEBUG_H__ -+ -+#ifdef CONFIG_MTK_PLAT_SRAM_FLAG -+/* plat_sram_flag */ -+extern int set_sram_flag_lastpc_valid(void); -+extern int set_sram_flag_dfd_valid(void); -+extern int set_sram_flag_etb_user(unsigned int etb_id, unsigned int user_id); -+#endif -+ -+#ifdef CONFIG_MTK_DFD_INTERNAL_DUMP -+extern int dfd_setup(void); -+#endif -+ -+#endif /* __MTK_PLATFORM_DEBUG_H__ */ -diff --git a/drivers/misc/mediatek/include/mt-plat/mtk_ram_console.h b/drivers/misc/mediatek/include/mt-plat/mtk_ram_console.h -new file mode 100644 -index 000000000000..3a94a1bbcd24 ---- /dev/null -+++ b/drivers/misc/mediatek/include/mt-plat/mtk_ram_console.h -@@ -0,0 +1,162 @@ -+/* -+ * Copyright (C) 2015 MediaTek Inc. -+ * -+ * 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. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#ifndef __MTK_RAM_CONSOLE_H__ -+#define __MTK_RAM_CONSOLE_H__ -+ -+#include -+#include -+ -+typedef enum { -+ AEE_FIQ_STEP_FIQ_ISR_BASE = 1, -+ AEE_FIQ_STEP_WDT_FIQ_INFO = 4, -+ AEE_FIQ_STEP_WDT_FIQ_STACK, -+ AEE_FIQ_STEP_WDT_FIQ_LOOP, -+ AEE_FIQ_STEP_WDT_FIQ_DONE, -+ AEE_FIQ_STEP_WDT_IRQ_INFO = 8, -+ AEE_FIQ_STEP_WDT_IRQ_KICK, -+ AEE_FIQ_STEP_WDT_IRQ_SMP_STOP, -+ AEE_FIQ_STEP_WDT_IRQ_TIME, -+ AEE_FIQ_STEP_WDT_IRQ_STACK, -+ AEE_FIQ_STEP_WDT_IRQ_GIC, -+ AEE_FIQ_STEP_WDT_IRQ_LOCALTIMER, -+ AEE_FIQ_STEP_WDT_IRQ_IDLE, -+ AEE_FIQ_STEP_WDT_IRQ_SCHED, -+ AEE_FIQ_STEP_WDT_IRQ_DONE, -+ AEE_FIQ_STEP_KE_WDT_INFO = 20, -+ AEE_FIQ_STEP_KE_WDT_PERCPU, -+ AEE_FIQ_STEP_KE_WDT_LOG, -+ AEE_FIQ_STEP_KE_SCHED_DEBUG, -+ AEE_FIQ_STEP_KE_EINT_DEBUG, -+ AEE_FIQ_STEP_KE_WDT_DONE, -+ AEE_FIQ_STEP_KE_IPANIC_DIE = 32, -+ AEE_FIQ_STEP_KE_IPANIC_START, -+ AEE_FIQ_STEP_KE_IPANIC_OOP_HEADER, -+ AEE_FIQ_STEP_KE_IPANIC_DETAIL, -+ AEE_FIQ_STEP_KE_IPANIC_CONSOLE, -+ AEE_FIQ_STEP_KE_IPANIC_USERSPACE, -+ AEE_FIQ_STEP_KE_IPANIC_ANDROID, -+ AEE_FIQ_STEP_KE_IPANIC_MMPROFILE, -+ AEE_FIQ_STEP_KE_IPANIC_HEADER, -+ AEE_FIQ_STEP_KE_IPANIC_DONE, -+ AEE_FIQ_STEP_KE_NESTED_PANIC = 64, -+} AEE_FIQ_STEP_NUM; -+ -+#ifdef CONFIG_MTK_RAM_CONSOLE -+extern int aee_rr_curr_fiq_step(void); -+extern void aee_rr_rec_fiq_step(u8 i); -+extern void aee_rr_rec_reboot_mode(u8 mode); -+extern void aee_rr_rec_kdump_params(void *params); -+extern void aee_rr_rec_last_irq_enter(int cpu, int irq, u64 j); -+extern void aee_rr_rec_last_irq_exit(int cpu, int irq, u64 j); -+extern void aee_rr_rec_last_sched_jiffies(int cpu, u64 j, const char *comm); -+extern void aee_sram_fiq_log(const char *msg); -+extern void ram_console_write(struct console *console, const char *s, unsigned int count); -+extern void aee_sram_fiq_save_bin(const char *buffer, size_t len); -+extern void aee_rr_rec_hotplug_footprint(int cpu, u8 fp); -+extern void aee_rr_rec_hotplug_cpu_event(u8 val); -+extern void aee_rr_rec_hotplug_cb_index(u8 val); -+extern void aee_rr_rec_hotplug_cb_fp(unsigned long val); -+#ifdef CONFIG_MTK_EMMC_SUPPORT -+extern void last_kmsg_store_to_emmc(void); -+#endif -+ -+#else -+static inline void aee_rr_rec_hotplug_footprint(int cpu, u8 fp) -+{ -+} -+static inline void aee_rr_rec_hotplug_cpu_event(u8 val) -+{ -+} -+static inline void aee_rr_rec_hotplug_cb_index(u8 val) -+{ -+} -+static inline void aee_rr_rec_hotplug_cb_fp(unsigned long val) -+{ -+} -+static inline int aee_rr_curr_fiq_step(void) -+{ -+ return 0; -+} -+ -+static inline void aee_rr_rec_fiq_step(u8 i) -+{ -+} -+ -+static inline unsigned int aee_rr_curr_exp_type(void) -+{ -+ return 0; -+} -+ -+static inline void aee_rr_rec_exp_type(unsigned int type) -+{ -+} -+ -+static inline void aee_rr_rec_reboot_mode(u8 mode) -+{ -+} -+ -+static inline void aee_rr_rec_kdump_params(void *params) -+{ -+} -+ -+static inline void aee_rr_rec_last_irq_enter(int cpu, int irq, u64 j) -+{ -+} -+ -+static inline void aee_rr_rec_last_irq_exit(int cpu, int irq, u64 j) -+{ -+} -+ -+static inline void aee_rr_rec_last_sched_jiffies(int cpu, u64 j, const char *comm) -+{ -+} -+ -+static inline void aee_sram_fiq_log(const char *msg) -+{ -+} -+ -+static inline void ram_console_write(struct console *console, const char *s, unsigned int count) -+{ -+} -+ -+static inline void aee_sram_fiq_save_bin(unsigned char *buffer, size_t len) -+{ -+} -+ -+#ifdef CONFIG_MTK_EMMC_SUPPORT -+static inline void last_kmsg_store_to_emmc(void) -+{ -+} -+#endif -+ -+#endif /* CONFIG_MTK_RAM_CONSOLE */ -+ -+#ifdef CONFIG_MTK_AEE_IPANIC -+extern int ipanic_kmsg_write(unsigned int part, const char *buf, size_t size); -+extern int ipanic_kmsg_get_next(int *count, u64 *id, enum pstore_type_id *type, struct timespec *time, -+ char **buf, struct pstore_info *psi); -+#else -+static inline int ipanic_kmsg_write(unsigned int part, const char *buf, size_t size) -+{ -+ return 0; -+} -+ -+static inline int ipanic_kmsg_get_next(int *count, u64 *id, enum pstore_type_id *type, struct timespec *time, -+ char **buf, struct pstore_info *psi) -+{ -+ return 0; -+} -+#endif /* CONFIG_MTK_AEE_IPANIC */ -+ -+#endif -diff --git a/drivers/misc/mediatek/include/mt-plat/mtk_rtc.h b/drivers/misc/mediatek/include/mt-plat/mtk_rtc.h -new file mode 100644 -index 000000000000..2181e9989593 ---- /dev/null -+++ b/drivers/misc/mediatek/include/mt-plat/mtk_rtc.h -@@ -0,0 +1,85 @@ -+/* -+ * Copyright (C) 2015 MediaTek Inc. -+ * -+ * 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. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#ifndef MTK_RTC_H -+#define MTK_RTC_H -+ -+#include -+#include -+#include -+ -+typedef enum { -+ RTC_GPIO_USER_WIFI = 8, -+ RTC_GPIO_USER_GPS = 9, -+ RTC_GPIO_USER_BT = 10, -+ RTC_GPIO_USER_FM = 11, -+ RTC_GPIO_USER_PMIC = 12, -+} rtc_gpio_user_t; -+ -+#ifdef CONFIG_MTK_RTC -+ -+/* -+ * NOTE: -+ * 1. RTC_GPIO always exports 32K enabled by some user even if the phone is powered off -+ */ -+ -+extern unsigned long rtc_read_hw_time(void); -+extern void rtc_gpio_enable_32k(rtc_gpio_user_t user); -+extern void rtc_gpio_disable_32k(rtc_gpio_user_t user); -+extern bool rtc_gpio_32k_status(void); -+ -+/* for AUDIOPLL (deprecated) */ -+extern void rtc_enable_abb_32k(void); -+extern void rtc_disable_abb_32k(void); -+ -+/* NOTE: used in Sleep driver to workaround Vrtc-Vore level shifter issue */ -+extern void rtc_enable_writeif(void); -+extern void rtc_disable_writeif(void); -+ -+extern void rtc_mark_recovery(void); -+#if defined(CONFIG_MTK_KERNEL_POWER_OFF_CHARGING) -+extern void rtc_mark_kpoc(void); -+#endif/*if defined(CONFIG_MTK_KERNEL_POWER_OFF_CHARGING)*/ -+extern void rtc_mark_fast(void); -+extern u16 rtc_rdwr_uart_bits(u16 *val); -+extern void rtc_bbpu_power_down(void); -+extern void rtc_read_pwron_alarm(struct rtc_wkalrm *alm); -+extern int get_rtc_spare_fg_value(void); -+extern int set_rtc_spare_fg_value(int val); -+extern void rtc_irq_handler(void); -+extern bool crystal_exist_status(void); -+extern void mt_power_off(void); -+#else/*ifdef CONFIG_MTK_RTC*/ -+#define rtc_read_hw_time() ({ 0; }) -+#define rtc_gpio_enable_32k(user) do {} while (0) -+#define rtc_gpio_disable_32k(user) do {} while (0) -+#define rtc_gpio_32k_status() do {} while (0) -+#define rtc_enable_abb_32k() do {} while (0) -+#define rtc_disable_abb_32k() do {} while (0) -+#define rtc_enable_writeif() do {} while (0) -+#define rtc_disable_writeif() do {} while (0) -+#define rtc_mark_recovery() do {} while (0) -+#if defined(CONFIG_MTK_KERNEL_POWER_OFF_CHARGING) -+#define rtc_mark_kpoc() do {} while (0) -+#endif/*if defined(CONFIG_MTK_KERNEL_POWER_OFF_CHARGING)*/ -+#define rtc_mark_fast() do {} while (0) -+#define rtc_rdwr_uart_bits(val) ({ 0; }) -+#define rtc_bbpu_power_down() do {} while (0) -+#define rtc_read_pwron_alarm(alm) do {} while (0) -+#define get_rtc_spare_fg_value() ({ 0; }) -+#define set_rtc_spare_fg_value(val) ({ 0; }) -+#define rtc_irq_handler() do {} while (0) -+#define crystal_exist_status() do {} while (0) -+__weak void mt_power_off(void); -+#endif/*ifdef CONFIG_MTK_RTC*/ -+#endif -diff --git a/drivers/misc/mediatek/include/mt-plat/mtk_thermal_ext_control.h b/drivers/misc/mediatek/include/mt-plat/mtk_thermal_ext_control.h -new file mode 100644 -index 000000000000..eac6bc713c98 ---- /dev/null -+++ b/drivers/misc/mediatek/include/mt-plat/mtk_thermal_ext_control.h -@@ -0,0 +1,69 @@ -+/* -+ * Copyright (c) 2009 Travis Geiselbrecht -+ * -+ * Permission is hereby granted, free of charge, to any person obtaining -+ * a copy of this software and associated documentation files -+ * (the "Software"), to deal in the Software without restriction, -+ * including without limitation the rights to use, copy, modify, merge, -+ * publish, distribute, sublicense, and/or sell copies of the Software, -+ * and to permit persons to whom the Software is furnished to do so, -+ * subject to the following conditions: -+ * -+ * The above copyright notice and this permission notice shall be -+ * included in all copies or substantial portions of the Software. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+ */ -+ -+#ifndef _MTK_THERMAL_EXT_CONTROL_H -+#define _MTK_THERMAL_EXT_CONTROL_H -+ -+#define THERMAL_MD32_IPI_MSG_BASE 0x1F00 -+#define THERMAL_AP_IPI_MSG_BASE 0x2F00 -+ -+typedef enum { -+ THERMAL_AP_IPI_MSG_SET_TZ_THRESHOLD = THERMAL_AP_IPI_MSG_BASE, -+ THERMAL_AP_IPI_MSG_MD32_START, -+ -+ THERMAL_MD32_IPI_MSG_READY = THERMAL_MD32_IPI_MSG_BASE, -+ THERMAL_MD32_IPI_MSG_MD32_START_ACK, -+ THERMAL_MD32_IPI_MSG_REACH_THRESHOLD, -+} thermal_ipi_msg_id; -+ -+typedef enum { -+/* MTK_THERMAL_EXT_SENSOR_CPU = 0, */ -+ MTK_THERMAL_EXT_SENSOR_ABB = 0, -+ MTK_THERMAL_EXT_SENSOR_PMIC, -+ MTK_THERMAL_EXT_SENSOR_BATTERY, -+ MTK_THERMAL_EXT_SENSOR_COUNT -+} MTK_THERMAL_EXT_SENSOR_ID; -+ -+typedef struct { -+ int id; /* id of this tz */ -+ int polling_delay; /* polling delay of this tz */ -+ long high_trip_point; /* high threshold of this tz */ -+ long low_trip_point; /* low threshold of this tz */ -+} thermal_zone_data; -+ -+typedef struct { -+ int id; /* id of this tz */ -+ long high_trip_point; /* high threshold of this tz */ -+ long low_trip_point; /* low threshold of this tz */ -+ long temperature; /* Current temperature gotten from TS */ -+} thermal_zone_status; -+ -+typedef struct { -+ short id; -+ union { -+ thermal_zone_data tz; -+ thermal_zone_status tz_status; -+ } data; -+} thermal_ipi_msg; -+ -+#endif /* _MTK_THERMAL_EXT_CONTROL_H */ -diff --git a/drivers/misc/mediatek/include/mt-plat/mtk_thermal_monitor.h b/drivers/misc/mediatek/include/mt-plat/mtk_thermal_monitor.h -new file mode 100644 -index 000000000000..7903b49dc419 ---- /dev/null -+++ b/drivers/misc/mediatek/include/mt-plat/mtk_thermal_monitor.h -@@ -0,0 +1,102 @@ -+/* -+ * Copyright (C) 2015 MediaTek Inc. -+ * -+ * 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. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#ifndef _MTK_THERMAL_MONITOR_H -+#define _MTK_THERMAL_MONITOR_H -+ -+#include -+ -+/* -+ * MTK_THERMAL_WRAPPER_BYPASS = 1 (use original Linux Thermal API) -+ * MTK_THERMAL_WRAPPER_BYPASS = 0 (use MTK Thermal API Monitor) -+ */ -+#define MTK_THERMAL_WRAPPER_BYPASS 0 -+ -+#if MTK_THERMAL_WRAPPER_BYPASS -+/* Original LTF API */ -+#define mtk_thermal_zone_device_register thermal_zone_device_register -+#define mtk_thermal_zone_device_unregister thermal_zone_device_unregister -+#define mtk_thermal_cooling_device_unregister thermal_cooling_device_unregister -+#define mtk_thermal_cooling_device_register thermal_cooling_device_register -+#define mtk_thermal_zone_bind_cooling_device thermal_zone_bind_cooling_device -+ -+#else -+ -+struct thermal_cooling_device_ops_extra { -+ int (*set_cur_temp)(struct thermal_cooling_device *, unsigned long); -+}; -+ -+extern -+struct thermal_zone_device *mtk_thermal_zone_device_register_wrapper -+(char *type, int trips, void *devdata, const struct thermal_zone_device_ops *ops, -+int tc1, int tc2, int passive_delay, int polling_delay); -+ -+extern -+void mtk_thermal_zone_device_unregister_wrapper(struct thermal_zone_device *tz); -+ -+extern -+struct thermal_cooling_device *mtk_thermal_cooling_device_register_wrapper -+(char *type, void *devdata, const struct thermal_cooling_device_ops *ops); -+ -+extern -+struct thermal_cooling_device *mtk_thermal_cooling_device_register_wrapper_extra -+(char *type, void *devdata, const struct thermal_cooling_device_ops *ops, -+const struct thermal_cooling_device_ops_extra *ops_ext); -+ -+extern -+int mtk_thermal_cooling_device_add_exit_point -+(struct thermal_cooling_device *cdev, int exit_point); -+ -+extern -+void mtk_thermal_cooling_device_unregister_wrapper(struct thermal_cooling_device *cdev); -+ -+extern int mtk_thermal_zone_bind_cooling_device_wrapper -+(struct thermal_zone_device *tz, int trip, struct thermal_cooling_device *cdev); -+ -+extern int mtk_thermal_zone_bind_trigger_trip(struct thermal_zone_device *tz, int trip, int mode); -+#define mtk_thermal_zone_device_register mtk_thermal_zone_device_register_wrapper -+#define mtk_thermal_zone_device_unregister mtk_thermal_zone_device_unregister_wrapper -+#define mtk_thermal_cooling_device_unregister mtk_thermal_cooling_device_unregister_wrapper -+#define mtk_thermal_cooling_device_register mtk_thermal_cooling_device_register_wrapper -+#define mtk_thermal_zone_bind_cooling_device mtk_thermal_zone_bind_cooling_device_wrapper -+ -+#endif -+ -+typedef enum { -+ MTK_THERMAL_SENSOR_CPU = 0, -+ MTK_THERMAL_SENSOR_ABB, -+ MTK_THERMAL_SENSOR_PMIC, -+ MTK_THERMAL_SENSOR_BATTERY, -+ MTK_THERMAL_SENSOR_MD1, -+ MTK_THERMAL_SENSOR_MD2, -+ MTK_THERMAL_SENSOR_WIFI, -+ MTK_THERMAL_SENSOR_BATTERY2, -+ MTK_THERMAL_SENSOR_BUCK, -+ MTK_THERMAL_SENSOR_AP, -+ MTK_THERMAL_SENSOR_PCB1, -+ MTK_THERMAL_SENSOR_PCB2, -+ MTK_THERMAL_SENSOR_SKIN, -+ MTK_THERMAL_SENSOR_XTAL, -+ MTK_THERMAL_SENSOR_MD_PA, -+ -+ MTK_THERMAL_SENSOR_COUNT -+} MTK_THERMAL_SENSOR_ID; -+ -+extern int mtk_thermal_get_temp(MTK_THERMAL_SENSOR_ID id); -+extern struct proc_dir_entry *mtk_thermal_get_proc_drv_therm_dir_entry(void); -+ -+/* This API function is implemented in mediatek/kernel/drivers/leds/leds.c */ -+extern int setMaxbrightness(int max_level, int enable); -+ -+extern void machine_power_off(void); -+#endif -diff --git a/drivers/misc/mediatek/include/mt-plat/mtk_thermal_platform.h b/drivers/misc/mediatek/include/mt-plat/mtk_thermal_platform.h -new file mode 100644 -index 000000000000..305574031196 ---- /dev/null -+++ b/drivers/misc/mediatek/include/mt-plat/mtk_thermal_platform.h -@@ -0,0 +1,114 @@ -+/* -+ * Copyright (C) 2015 MediaTek Inc. -+ * -+ * 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. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#ifndef _MTK_THERMAL_PLATFORM_H -+#define _MTK_THERMAL_PLATFORM_H -+ -+#include -+#include -+ -+extern -+int mtk_thermal_get_cpu_info(int *nocores, int **cpufreq, int **cpuloading); -+ -+extern -+int mtk_thermal_get_gpu_info(int *nocores, int **gpufreq, int **gpuloading); -+ -+extern -+int mtk_thermal_get_batt_info(int *batt_voltage, int *batt_current, int *batt_temp); -+ -+extern -+int mtk_thermal_get_extra_info(int *no_extra_attr, -+ char ***attr_names, int **attr_values, char ***attr_unit); -+ -+extern -+int mtk_thermal_force_get_batt_temp(void); -+ -+ -+enum { -+ MTK_THERMAL_SCEN_CALL = 0x1 -+}; -+ -+extern -+unsigned int mtk_thermal_set_user_scenarios(unsigned int mask); -+ -+extern -+unsigned int mtk_thermal_clear_user_scenarios(unsigned int mask); -+ -+ -+#if defined(CONFIG_MTK_SMART_BATTERY) -+/* global variable from battery driver... */ -+extern kal_bool gFG_Is_Charging; -+#endif -+ -+extern int force_get_tbat(void); -+#endif /* _MTK_THERMAL_PLATFORM_H */ -+ -+ -+typedef enum { -+ TA_DAEMON_CMD_GET_INIT_FLAG = 0, -+ TA_DAEMON_CMD_SET_DAEMON_PID, -+ TA_DAEMON_CMD_NOTIFY_DAEMON, -+ TA_DAEMON_CMD_NOTIFY_DAEMON_CATMINIT, -+ TA_DAEMON_CMD_SET_TTJ, -+ TA_DAEMON_CMD_GET_TPCB, -+ -+ TA_DAEMON_CMD_TO_KERNEL_NUMBER -+} TA_DAEMON_CTRL_CMD_TO_KERNEL; /*must sync userspace/kernel: TA_DAEMON_CTRL_CMD_FROM_USER*/ -+ -+#define TAD_NL_MSG_T_HDR_LEN 12 -+#define TAD_NL_MSG_MAX_LEN 2048 -+ -+struct tad_nl_msg_t { -+ unsigned int tad_cmd; -+ unsigned int tad_data_len; -+ unsigned int tad_ret_data_len; -+ char tad_data[TAD_NL_MSG_MAX_LEN]; -+}; -+ -+enum { -+ TA_CATMPLUS = 1, -+ TA_CONTINUOUS = 2, -+ TA_CATMPLUS_TTJ = 3 -+}; -+ -+ -+struct cATM_params_t { -+ int CATM_ON; -+ int K_TT; -+ int K_SUM_TT_LOW; -+ int K_SUM_TT_HIGH; -+ int MIN_SUM_TT; -+ int MAX_SUM_TT; -+ int MIN_TTJ; -+ int CATMP_STEADY_TTJ_DELTA; -+}; -+struct continuetm_params_t { -+ int STEADY_TARGET_TJ; -+ int MAX_TARGET_TJ; -+ int TRIP_TPCB; -+ int STEADY_TARGET_TPCB; -+}; -+ -+ -+struct CATM_T { -+ struct cATM_params_t t_catm_par; -+ struct continuetm_params_t t_continuetm_par; -+}; -+extern struct CATM_T thermal_atm_t; -+int wakeup_ta_algo(int flow_state); -+int ta_get_ttj(void); -+ -+extern int mtk_thermal_get_tpcb_target(void); -+extern int tsatm_thermal_get_catm_type(void); -+ -+ -diff --git a/drivers/misc/mediatek/include/mt-plat/mtk_thermal_trace.h b/drivers/misc/mediatek/include/mt-plat/mtk_thermal_trace.h -new file mode 100644 -index 000000000000..1c23a9f4a862 ---- /dev/null -+++ b/drivers/misc/mediatek/include/mt-plat/mtk_thermal_trace.h -@@ -0,0 +1,47 @@ -+/* -+ * Copyright (C) 2015 MediaTek Inc. -+ * -+ * 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. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#undef TRACE_SYSTEM -+#define TRACE_SYSTEM thermal -+ -+#if !defined(_MTK_THERMAL_TRACE_H) || defined(TRACE_HEADER_MULTI_READ) -+#define _MTK_THERMAL_TRACE_H -+ -+#include -+ -+TRACE_EVENT(cooling_device_state, -+ TP_PROTO(int device, unsigned long state), -+ TP_ARGS(device, state), TP_STRUCT__entry(__field(int, device) -+ __field(unsigned long, state) -+ ), -+ TP_fast_assign(__entry->device = device; -+ __entry->state = state;), -+ TP_printk("cooling_device=%d, state=%lu\n", __entry->device, __entry->state) -+); -+ -+TRACE_EVENT(thermal_zone_state, -+ TP_PROTO(int device, int state), -+ TP_ARGS(device, state), TP_STRUCT__entry(__field(int, device) -+ __field(int, state) -+ ), -+ TP_fast_assign(__entry->device = device; -+ __entry->state = state;), -+ TP_printk("thermal_zone=%d, state=%d\n", __entry->device, __entry->state) -+); -+#endif /* _MTK_THERMAL_TRACE_H */ -+ -+/* This part must be outside protection */ -+#undef TRACE_INCLUDE_PATH -+#define TRACE_INCLUDE_PATH . -+#define TRACE_INCLUDE_FILE mach/mtk_thermal_trace -+#include -diff --git a/drivers/misc/mediatek/include/mt-plat/mtk_thermal_typedefs.h b/drivers/misc/mediatek/include/mt-plat/mtk_thermal_typedefs.h -new file mode 100644 -index 000000000000..dfcef3d952fc ---- /dev/null -+++ b/drivers/misc/mediatek/include/mt-plat/mtk_thermal_typedefs.h -@@ -0,0 +1,241 @@ -+/* -+ * Copyright (C) 2015 MediaTek Inc. -+ * -+ * 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. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#ifndef _TYPEDEFS_H -+#define _TYPEDEFS_H -+ -+#include -+ -+/* --------------------------------------------------------------------------- */ -+/* Basic Type Definitions */ -+/* --------------------------------------------------------------------------- */ -+ -+typedef volatile unsigned char *P_kal_uint8; -+typedef volatile unsigned short *P_kal_uint16; -+typedef volatile unsigned int *P_kal_uint32; -+ -+typedef long LONG; -+typedef unsigned char UBYTE; -+typedef short SHORT; -+ -+typedef signed char kal_int8; -+typedef signed short kal_int16; -+typedef signed int kal_int32; -+typedef long long kal_int64; -+typedef unsigned char kal_uint8; -+typedef unsigned short kal_uint16; -+typedef unsigned int kal_uint32; -+typedef unsigned long long kal_uint64; -+typedef char kal_char; -+ -+typedef unsigned int *UINT32P; -+typedef volatile unsigned short *UINT16P; -+typedef volatile unsigned char *UINT8P; -+typedef unsigned char *U8P; -+ -+typedef volatile unsigned char *P_U8; -+typedef volatile signed char *P_S8; -+typedef volatile unsigned short *P_U16; -+typedef volatile signed short *P_S16; -+typedef volatile unsigned int *P_U32; -+typedef volatile signed int *P_S32; -+typedef unsigned long long *P_U64; -+typedef signed long long *P_S64; -+ -+typedef unsigned char U8; -+typedef signed char S8; -+typedef unsigned short U16; -+typedef signed short S16; -+typedef unsigned int U32; -+typedef signed int S32; -+typedef unsigned long long U64; -+typedef signed long long S64; -+/* typedef unsigned char bool; */ -+ -+typedef unsigned char UINT8; -+typedef unsigned short UINT16; -+typedef unsigned int UINT32; -+typedef unsigned short USHORT; -+typedef signed char INT8; -+typedef signed short INT16; -+typedef signed int INT32; -+typedef unsigned int DWORD; -+typedef void VOID; -+typedef unsigned char BYTE; -+typedef float FLOAT; -+ -+typedef char *LPCSTR; -+typedef short *LPWSTR; -+ -+ -+/* --------------------------------------------------------------------------- */ -+/* Constants */ -+/* --------------------------------------------------------------------------- */ -+ -+#ifndef FALSE -+#define FALSE (0) -+#endif -+ -+#ifndef TRUE -+#define TRUE (1) -+#endif -+ -+#ifndef NULL -+#define NULL (0) -+#endif -+ -+/* enum boolean {false, true}; */ -+enum { RX, TX, NONE }; -+ -+#ifndef BOOL -+typedef unsigned char BOOL; -+#endif -+ -+#ifndef BATTERY_BOOL -+#define BATTERY_BOOL -+typedef enum { -+ KAL_FALSE = 0, -+ KAL_TRUE = 1, -+} kal_bool; -+#endif -+ -+/* --------------------------------------------------------------------------- */ -+/* Type Casting */ -+/* --------------------------------------------------------------------------- */ -+ -+#define AS_INT32(x) (*(INT32 *)((void *)x)) -+#define AS_INT16(x) (*(INT16 *)((void *)x)) -+#define AS_INT8(x) (*(INT8 *)((void *)x)) -+ -+#define AS_UINT32(x) (*(UINT32 *)((void *)x)) -+#define AS_UINT16(x) (*(UINT16 *)((void *)x)) -+#define AS_UINT8(x) (*(UINT8 *)((void *)x)) -+ -+ -+/* --------------------------------------------------------------------------- */ -+/* Register Manipulations */ -+/* --------------------------------------------------------------------------- */ -+ -+#define READ_REGISTER_UINT32(reg) \ -+ (*(volatile UINT32 * const)(reg)) -+ -+#define WRITE_REGISTER_UINT32(reg, val) \ -+ ((*(volatile UINT32 * const)(reg)) = (val)) -+ -+#define READ_REGISTER_UINT16(reg) \ -+ ((*(volatile UINT16 * const)(reg))) -+ -+#define WRITE_REGISTER_UINT16(reg, val) \ -+ ((*(volatile UINT16 * const)(reg)) = (val)) -+ -+#define READ_REGISTER_UINT8(reg) \ -+ ((*(volatile UINT8 * const)(reg))) -+ -+#define WRITE_REGISTER_UINT8(reg, val) \ -+ ((*(volatile UINT8 * const)(reg)) = (val)) -+ -+#define INREG8(x) READ_REGISTER_UINT8((UINT8 *)((void *)(x))) -+#define OUTREG8(x, y) WRITE_REGISTER_UINT8((UINT8 *)((void *)(x)), (UINT8)(y)) -+#define SETREG8(x, y) OUTREG8(x, INREG8(x)|(y)) -+#define CLRREG8(x, y) OUTREG8(x, INREG8(x)&~(y)) -+#define MASKREG8(x, y, z) OUTREG8(x, (INREG8(x)&~(y))|(z)) -+ -+#define INREG16(x) READ_REGISTER_UINT16((UINT16 *)((void *)(x))) -+#define OUTREG16(x, y) WRITE_REGISTER_UINT16((UINT16 *)((void *)(x)), (UINT16)(y)) -+#define SETREG16(x, y) OUTREG16(x, INREG16(x)|(y)) -+#define CLRREG16(x, y) OUTREG16(x, INREG16(x)&~(y)) -+#define MASKREG16(x, y, z) OUTREG16(x, (INREG16(x)&~(y))|(z)) -+ -+#define INREG32(x) READ_REGISTER_UINT32((UINT32 *)((void *)(x))) -+#define OUTREG32(x, y) WRITE_REGISTER_UINT32((UINT32 *)((void *)(x)), (UINT32)(y)) -+#define SETREG32(x, y) OUTREG32(x, INREG32(x)|(y)) -+#define CLRREG32(x, y) OUTREG32(x, INREG32(x)&~(y)) -+#define MASKREG32(x, y, z) OUTREG32(x, (INREG32(x)&~(y))|(z)) -+ -+ -+#define DRV_Reg8(addr) INREG8(addr) -+#define DRV_WriteReg8(addr, data) OUTREG8(addr, data) -+#define DRV_SetReg8(addr, data) SETREG8(addr, data) -+#define DRV_ClrReg8(addr, data) CLRREG8(addr, data) -+ -+#define DRV_Reg16(addr) INREG16(addr) -+#define DRV_WriteReg16(addr, data) OUTREG16(addr, data) -+#define DRV_SetReg16(addr, data) SETREG16(addr, data) -+#define DRV_ClrReg16(addr, data) CLRREG16(addr, data) -+ -+#define DRV_Reg32(addr) INREG32(addr) -+#define DRV_WriteReg32(addr, data) OUTREG32(addr, data) -+#define DRV_SetReg32(addr, data) SETREG32(addr, data) -+#define DRV_ClrReg32(addr, data) CLRREG32(addr, data) -+ -+/* !!! DEPRECATED, WILL BE REMOVED LATER !!! */ -+#define DRV_Reg(addr) DRV_Reg16(addr) -+#define DRV_WriteReg(addr, data) DRV_WriteReg16(addr, data) -+#define DRV_SetReg(addr, data) DRV_SetReg16(addr, data) -+#define DRV_ClrReg(addr, data) DRV_ClrReg16(addr, data) -+ -+ -+/* --------------------------------------------------------------------------- */ -+/* Compiler Time Deduction Macros */ -+/* --------------------------------------------------------------------------- */ -+ -+ -+ -+/* --------------------------------------------------------------------------- */ -+/* Assertions */ -+/* --------------------------------------------------------------------------- */ -+ -+/* -+*#ifndef ASSERT -+*#define ASSERT(expr) BUG_ON(!(expr)) -+*#endif -+* -+*#ifndef NOT_IMPLEMENTED -+*#define NOT_IMPLEMENTED() BUG_ON(1) -+*#endif -+*/ -+#define STATIC_ASSERT(pred) STATIC_ASSERT_X(pred, __LINE__) -+#define STATIC_ASSERT_X(pred, line) STATIC_ASSERT_XX(pred, line) -+#define STATIC_ASSERT_XX(pred, line) \ -+extern char assertion_failed_at_##line[(pred) ? 1 : -1] -+ -+/* --------------------------------------------------------------------------- */ -+/* Resolve Compiler Warnings */ -+/* --------------------------------------------------------------------------- */ -+ -+#define NOT_REFERENCED(x) { (x) = (x); } -+ -+ -+/* --------------------------------------------------------------------------- */ -+/* Utilities */ -+/* --------------------------------------------------------------------------- */ -+ -+#define MAXIMUM(A, B) (((A) > (B))?(A):(B)) -+#define MINIMUM(A, B) (((A) < (B))?(A):(B)) -+ -+#define ARY_SIZE(x) (sizeof((x)) / sizeof((x[0]))) -+#define DVT_DELAYMACRO(u4Num) \ -+{ \ -+ UINT32 u4Count = 0; \ -+ for (u4Count = 0; u4Count < u4Num; u4Count++) \ -+ ; \ -+} \ -+ -+#define A68351B 0 -+#define B68351B 1 -+#define B68351D 2 -+#define B68351E 3 -+#define UNKNOWN_IC_VERSION 0xFF -+ -+ -+#endif /* _TYPEDEFS_H */ -diff --git a/drivers/misc/mediatek/include/mt-plat/mtk_wcn_cmb_stub.h b/drivers/misc/mediatek/include/mt-plat/mtk_wcn_cmb_stub.h -new file mode 100644 -index 000000000000..0a4fda191654 ---- /dev/null -+++ b/drivers/misc/mediatek/include/mt-plat/mtk_wcn_cmb_stub.h -@@ -0,0 +1,185 @@ -+/* -+ * Copyright (C) 2015 MediaTek Inc. -+ * -+ * 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. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+/*! \file -+ * \brief Declaration of library functions -+ * -+ * Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. -+*/ -+ -+#ifndef _MTK_WCN_CMB_STUB_H_ -+#define _MTK_WCN_CMB_STUB_H_ -+ -+#include -+ -+/******************************************************************************* -+* C O M P I L E R F L A G S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* M A C R O S -+******************************************************************************** -+*/ -+/* Audio GPIO naming style for 73/75/77 */ -+/* #define MTK_WCN_CMB_AUD_IO_NAMING_STYLE_0 1 */ -+/* Audio GPIO naming style for 89/8135 */ -+/* #define MTK_WCN_CMB_AUD_IO_NAMING_STYLE_1 1 */ -+/* Audio GPIO naming style for 6592 */ -+/* #define MTK_WCN_CMB_AUD_IO_NAMING_STYLE_2 1 */ -+/* Audio GPIO naming style for 6595 */ -+#define MTK_WCN_CMB_AUD_IO_NAMING_STYLE_3 1 -+#define MTK_WCN_CMB_FOR_SDIO_1V_AUTOK 1 -+ -+/******************************************************************************* -+* E X T E R N A L R E F E R E N C E S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* C O N S T A N T S -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* D A T A T Y P E S -+******************************************************************************** -+*/ -+typedef enum { -+ CMB_STUB_AIF_0 = 0, /* 0000: BT_PCM_OFF & FM analog (line in/out) */ -+ CMB_STUB_AIF_1 = 1, /* 0001: BT_PCM_ON & FM analog (in/out) */ -+ CMB_STUB_AIF_2 = 2, /* 0010: BT_PCM_OFF & FM digital (I2S) */ -+ CMB_STUB_AIF_3 = 3, /* 0011: BT_PCM_ON & FM digital (I2S) (invalid in 73evb & 1.2 phone configuration) */ -+ CMB_STUB_AIF_4 = 4, /* 0100: BT_I2S & FM disable in special projects, e.g. protea*/ -+ CMB_STUB_AIF_MAX = 5, -+} CMB_STUB_AIF_X; -+ -+/*COMBO_CHIP_AUDIO_PIN_CTRL*/ -+typedef enum { -+ CMB_STUB_AIF_CTRL_DIS = 0, -+ CMB_STUB_AIF_CTRL_EN = 1, -+ CMB_STUB_AIF_CTRL_MAX = 2, -+} CMB_STUB_AIF_CTRL; -+ -+typedef enum { -+ COMBO_FUNC_TYPE_BT = 0, -+ COMBO_FUNC_TYPE_FM = 1, -+ COMBO_FUNC_TYPE_GPS = 2, -+ COMBO_FUNC_TYPE_WIFI = 3, -+ COMBO_FUNC_TYPE_WMT = 4, -+ COMBO_FUNC_TYPE_STP = 5, -+ COMBO_FUNC_TYPE_NUM = 6 -+} COMBO_FUNC_TYPE; -+ -+typedef enum { -+ COMBO_IF_UART = 0, -+ COMBO_IF_MSDC = 1, -+ COMBO_IF_BTIF = 2, -+ COMBO_IF_MAX, -+} COMBO_IF; -+ -+typedef void (*wmt_bgf_eirq_cb) (void); -+typedef int (*wmt_aif_ctrl_cb) (CMB_STUB_AIF_X, CMB_STUB_AIF_CTRL); -+typedef void (*wmt_func_ctrl_cb) (unsigned int, unsigned int); -+typedef signed long (*wmt_thermal_query_cb) (void); -+typedef int (*wmt_deep_idle_ctrl_cb) (unsigned int); -+typedef int (*wmt_func_do_reset) (unsigned int); -+ -+/* for DVFS driver do 1v autok */ -+#if MTK_WCN_CMB_FOR_SDIO_1V_AUTOK -+typedef unsigned int (*wmt_get_drv_status)(unsigned int); -+#endif -+ -+typedef void (*msdc_sdio_irq_handler_t) (void *); /* external irq handler */ -+typedef void (*pm_callback_t) (pm_message_t state, void *data); -+ -+struct sdio_ops { -+ void (*sdio_request_eirq)(msdc_sdio_irq_handler_t irq_handler, void *data); -+ void (*sdio_enable_eirq)(void); -+ void (*sdio_disable_eirq)(void); -+ void (*sdio_register_pm)(pm_callback_t pm_cb, void *data); -+}; -+ -+typedef struct _CMB_STUB_CB_ { -+ unsigned int size; /* structure size */ -+ /*wmt_bgf_eirq_cb bgf_eirq_cb; *//* remove bgf_eirq_cb from stub. handle it in platform */ -+ wmt_aif_ctrl_cb aif_ctrl_cb; -+ wmt_func_ctrl_cb func_ctrl_cb; -+ wmt_thermal_query_cb thermal_query_cb; -+ wmt_deep_idle_ctrl_cb deep_idle_ctrl_cb; -+ wmt_func_do_reset wmt_do_reset_cb; -+#if MTK_WCN_CMB_FOR_SDIO_1V_AUTOK -+ wmt_get_drv_status get_drv_status_cb; -+#endif -+} CMB_STUB_CB, *P_CMB_STUB_CB; -+ -+/******************************************************************************* -+* P U B L I C D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* P R I V A T E D A T A -+******************************************************************************** -+*/ -+ -+/******************************************************************************* -+* F U N C T I O N D E C L A R A T I O N S -+******************************************************************************** -+*/ -+ -+extern struct sdio_ops mt_sdio_ops[4]; -+ -+extern int mtk_wcn_cmb_stub_reg(P_CMB_STUB_CB p_stub_cb); -+extern int mtk_wcn_cmb_stub_unreg(void); -+ -+extern int mtk_wcn_cmb_stub_aif_ctrl(CMB_STUB_AIF_X state, CMB_STUB_AIF_CTRL ctrl); -+ -+static inline int mtk_wcn_cmb_stub_audio_ctrl(CMB_STUB_AIF_X state) -+{ -+/* return mtk_wcn_cmb_stub_aif_ctrl(state, 1); */ -+ return 0; -+} -+ -+extern int mt_combo_plt_enter_deep_idle(COMBO_IF src); -+extern int mt_combo_plt_exit_deep_idle(COMBO_IF src); -+ -+/* Use new mtk_wcn_stub APIs instead of old mt_combo ones for kernel to control -+ * function on/off. -+ */ -+extern void mtk_wcn_cmb_stub_func_ctrl(unsigned int type, unsigned int on); -+extern int mtk_wcn_cmb_stub_query_ctrl(void); -+extern int board_sdio_ctrl(unsigned int sdio_port_num, unsigned int on); -+extern int mtk_wcn_sdio_irq_flag_set(int falg); -+ -+#if MTK_WCN_CMB_FOR_SDIO_1V_AUTOK -+extern int mtk_wcn_cmb_stub_1vautok_for_dvfs(void); -+#endif -+ -+extern int mtk_wcn_wmt_chipid_query(void); -+extern void mtk_wcn_wmt_set_chipid(int chipid); -+ -+/* mtk_uart_pdn_enable -- request uart port enter/exit deep idle mode, this API is defined in uart driver -+ * -+ * @ port - uart port name, Eg: "ttyMT0", "ttyMT1", "ttyMT2" -+ * @ enable - "1", enable deep idle; "0", disable deep idle -+ * -+ * Return 0 if success, else -1 -+ */ -+extern unsigned int mtk_uart_pdn_enable(char *port, int enable); -+/******************************************************************************* -+* F U N C T I O N S -+******************************************************************************** -+*/ -+ -+#endif /* _MTK_WCN_CMB_STUB_H_ */ -diff --git a/drivers/misc/mediatek/include/mt-plat/rt-regmap.h b/drivers/misc/mediatek/include/mt-plat/rt-regmap.h -new file mode 100644 -index 000000000000..9a45e23005ca ---- /dev/null -+++ b/drivers/misc/mediatek/include/mt-plat/rt-regmap.h -@@ -0,0 +1,291 @@ -+/* drivers/misc/mediatek/include/mt-plat/rt-regmap.h -+ * Header of Richtek regmap with debugfs Driver -+ * -+ * Copyright (C) 2014 Richtek Technology Corp. -+ * Jeff Chang -+ * -+ * 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. -+ */ -+ -+#ifndef MISC_MEDIATEK_RT_REGMAP_H -+#define MISC_MEDIATEK_RT_REGMAP_H -+ -+#include -+#include -+ -+/* #define RT_REGMAP_VERSION "1.1.11_G" */ -+ -+enum rt_access_mode { -+ RT_1BYTE_MODE = 1, -+ RT_2BYTE_MODE = 2, -+ RT_4BYTE_MODE = 4, -+}; -+ -+/* start : the start address of group -+ * end : the end address of group -+ * mode : access mode (1,2,4 bytes) -+ */ -+struct rt_access_group { -+ u32 start; -+ u32 end; -+ enum rt_access_mode mode; -+}; -+ -+/* rt_reg_type -+ * RT_NORMAL : Write data without mask -+ * Read from cache -+ * RT_WBITS : Write data with mask -+ * Read from cache -+ * RT_VOLATILE : Write data to chip directly -+ * Read data from chip -+ * RT_RESERVE : Reserve registers (Write/Read as RT_NORMAL) -+ */ -+ -+#define RT_REG_TYPE_MASK (0x03) -+#define RT_NORMAL (0x00) -+#define RT_WBITS (0x01) -+#define RT_VOLATILE (0x02) -+#define RT_RESERVE (0x03) -+ -+/* RT_WR_ONCE : write once will check write data and cache data, -+ * if write data = cache data, data will not be writen. -+ */ -+#define RT_WR_ONCE (0x08) -+#define RT_NORMAL_WR_ONCE (RT_NORMAL|RT_WR_ONCE) -+#define RT_WBITS_WR_ONCE (RT_WBITS|RT_WR_ONCE) -+ -+enum rt_data_format { -+ RT_LITTLE_ENDIAN, -+ RT_BIG_ENDIAN, -+}; -+ -+/* rt_regmap_mode -+ * 0 0 0 0 0 0 0 0 -+ * | | | | | | -+ * | | | |__| byte_mode -+ * | |__| || -+ * | || Cache_mode -+ * | Block_mode -+ * Debug_mode -+ */ -+ -+#define RT_BYTE_MODE_MASK (0x01) -+/* 1 byte for each register*/ -+#define RT_SINGLE_BYTE (0 << 0) -+/* multi bytes for each regiseter*/ -+#define RT_MULTI_BYTE (1 << 0) -+ -+#define RT_CACHE_MODE_MASK (0x06) -+/* write to cache and chip synchronously */ -+#define RT_CACHE_WR_THROUGH (0 << 1) -+/* write to cache and chip asynchronously */ -+#define RT_CACHE_WR_BACK (1 << 1) -+/* disable cache */ -+#define RT_CACHE_DISABLE (2 << 1) -+ -+#define RT_IO_BLK_MODE_MASK (0x18) -+/* pass through all write function */ -+#define RT_IO_PASS_THROUGH (0 << 3) -+/* block all write function */ -+#define RT_IO_BLK_ALL (1 << 3) -+/* block cache write function */ -+#define RT_IO_BLK_CACHE (2 << 3) -+/* block chip write function */ -+#define RT_IO_BLK_CHIP (3 << 3) -+ -+#define DBG_MODE_MASK (0x20) -+/* create general debugfs for register map */ -+#define RT_DBG_GENERAL (0 << 5) -+/* create node for each regisetr map by register address*/ -+#define RT_DBG_SPECIAL (1 << 5) -+ -+ -+/* struct rt_register -+ * -+ * Ricktek register map structure for store mapping data -+ * @addr: register address. -+ * @name: register name. -+ * @size: register byte size. -+ * @reg_type: register R/W type ( RT_NORMAL, RT_WBITS, RT_VOLATILE, RT_RESERVE) -+ * @wbit_mask: register writeable bits mask; -+ * @cache_data: cache data for store cache value. -+ */ -+struct rt_register { -+ u32 addr; -+ const char *name; -+ unsigned int size; -+ unsigned char reg_type; -+ unsigned char *wbit_mask; -+ unsigned char *cache_data; -+}; -+ -+/* Declare a rt_register by RT_REG_DECL -+ * @_addr: regisetr address. -+ * @_reg_length: register data length. -+ * @_reg_type: register type (rt_reg_type). -+ * @_mask: register writealbe mask. -+ */ -+#define RT_REG_DECL(_addr, _reg_length, _reg_type, _mask_...) \ -+ static unsigned char rt_writable_mask_##_addr[_reg_length] = _mask_;\ -+ static struct rt_register rt_register_##_addr = { \ -+ .addr = _addr, \ -+ .size = _reg_length,\ -+ .reg_type = _reg_type,\ -+ .wbit_mask = rt_writable_mask_##_addr,\ -+ } -+ -+/* Declare a rt_register by RT_NAMED_REG_DECL -+ * @_name: a name for a rt_register. -+ */ -+#define RT_NAMED_REG_DECL(_addr, _name, _reg_length, _reg_type, _mask_...) \ -+ static unsigned char rt_writable_mask_##_addr[_reg_length] = _mask_;\ -+ static struct rt_register rt_register_##_addr = { \ -+ .addr = _addr, \ -+ .name = _name, \ -+ .size = _reg_length,\ -+ .reg_type = _reg_type,\ -+ .wbit_mask = rt_writable_mask_##_addr,\ -+ } -+ -+#define RT_REG(_addr) (&rt_register_##_addr) -+ -+/* rt_regmap_properties -+ * @name: the name of debug node. -+ * @aliases: alisis name of rt_regmap_device. -+ * @register_num: the number of rt_register_map registers. -+ * @rm: rt_regiseter_map pointer array. -+ * @group: register map access group. -+ * @rt_format: default is little endian. -+ * @rt_regmap_mode: rt_regmap_device mode. -+ * @io_log_en: enable/disable io log -+ */ -+struct rt_regmap_properties { -+ const char *name; -+ const char *aliases; -+ int register_num; -+ struct rt_register **rm; -+ struct rt_access_group *group; -+ enum rt_data_format rt_format; -+ unsigned char rt_regmap_mode; -+ unsigned char io_log_en:1; -+}; -+ -+/* A passing struct for rt_regmap_reg_read and rt_regmap_reg_write function -+ * reg: regmap addr. -+ * mask: mask for update bits. -+ * rt_data: register value. -+ */ -+struct rt_reg_data { -+ u32 reg; -+ u32 mask; -+ union { -+ u32 data_u32; -+ u16 data_u16; -+ u8 data_u8; -+ u8 data[4]; -+ } rt_data; -+}; -+ -+struct rt_regmap_device; -+ -+struct rt_debug_st { -+ void *info; -+ int id; -+}; -+ -+/* basic chip read/write function */ -+struct rt_regmap_fops { -+ int (*read_device)(void *client, u32 addr, int leng, void *dst); -+ int (*write_device)(void *client, u32 addr, int leng, const void *src); -+}; -+ -+/* with slave address */ -+extern struct rt_regmap_device* -+ rt_regmap_device_register_ex(struct rt_regmap_properties *props, -+ struct rt_regmap_fops *rops, -+ struct device *parent, -+ void *client, int slv_addr, void *drvdata); -+ -+static inline struct rt_regmap_device* -+ rt_regmap_device_register(struct rt_regmap_properties *props, -+ struct rt_regmap_fops *rops, -+ struct device *parent, -+ struct i2c_client *client, void *drvdata) -+{ -+ return rt_regmap_device_register_ex(props, rops, parent, -+ client, client->addr, drvdata); -+} -+ -+extern void rt_regmap_device_unregister(struct rt_regmap_device *rd); -+ -+extern int rt_regmap_cache_init(struct rt_regmap_device *rd); -+ -+extern int rt_regmap_cache_reload(struct rt_regmap_device *rd); -+ -+extern int rt_regmap_block_write(struct rt_regmap_device *rd, u32 reg, -+ int bytes, const void *rc); -+extern int rt_asyn_regmap_block_write(struct rt_regmap_device *rd, u32 reg, -+ int bytes, const void *rc); -+extern int rt_regmap_block_read(struct rt_regmap_device *rd, u32 reg, -+ int bytes, void *dst); -+ -+extern int _rt_regmap_reg_read(struct rt_regmap_device *rd, -+ struct rt_reg_data *rrd); -+extern int _rt_regmap_reg_write(struct rt_regmap_device *rd, -+ struct rt_reg_data *rrd); -+extern int _rt_asyn_regmap_reg_write(struct rt_regmap_device *rd, -+ struct rt_reg_data *rrd); -+extern int _rt_regmap_update_bits(struct rt_regmap_device *rd, -+ struct rt_reg_data *rrd); -+ -+static inline int rt_regmap_reg_read(struct rt_regmap_device *rd, -+ struct rt_reg_data *rrd, u32 reg) -+{ -+ rrd->reg = reg; -+ return _rt_regmap_reg_read(rd, rrd); -+}; -+ -+static inline int rt_regmap_reg_write(struct rt_regmap_device *rd, -+ struct rt_reg_data *rrd, u32 reg, const u32 data) -+{ -+ rrd->reg = reg; -+ rrd->rt_data.data_u32 = data; -+ return _rt_regmap_reg_write(rd, rrd); -+}; -+ -+static inline int rt_asyn_regmap_reg_write(struct rt_regmap_device *rd, -+ struct rt_reg_data *rrd, u32 reg, const u32 data) -+{ -+ rrd->reg = reg; -+ rrd->rt_data.data_u32 = data; -+ return _rt_asyn_regmap_reg_write(rd, rrd); -+}; -+ -+static inline int rt_regmap_update_bits(struct rt_regmap_device *rd, -+ struct rt_reg_data *rrd, u32 reg, u32 mask, u32 data) -+{ -+ rrd->reg = reg; -+ rrd->mask = mask; -+ rrd->rt_data.data_u32 = data; -+ return _rt_regmap_update_bits(rd, rrd); -+} -+ -+extern void rt_regmap_cache_backup(struct rt_regmap_device *rd); -+ -+extern void rt_regmap_cache_sync(struct rt_regmap_device *rd); -+extern void rt_regmap_cache_write_back(struct rt_regmap_device *rd, u32 reg); -+ -+extern int rt_is_reg_readable(struct rt_regmap_device *rd, u32 reg); -+extern int rt_is_reg_volatile(struct rt_regmap_device *rd, u32 reg); -+extern int rt_get_regsize(struct rt_regmap_device *rd, u32 reg); -+extern void rt_cache_getlasterror(struct rt_regmap_device *rd, char *buf); -+extern void rt_cache_clrlasterror(struct rt_regmap_device *rd); -+ -+extern int rt_regmap_add_debugfs(struct rt_regmap_device *rd, const char *name, -+ umode_t mode, void *data, const struct file_operations *fops); -+ -+#define to_rt_regmap_device(obj) container_of(obj, struct rt_regmap_device, dev) -+ -+#endif /*MISC_MEDIATEK_RT_REGMAP_H*/ -diff --git a/drivers/misc/mediatek/include/mt-plat/sync_write.h b/drivers/misc/mediatek/include/mt-plat/sync_write.h -new file mode 100644 -index 000000000000..f9e5fe4c23e1 ---- /dev/null -+++ b/drivers/misc/mediatek/include/mt-plat/sync_write.h -@@ -0,0 +1,88 @@ -+/* -+ * Copyright (C) 2015 MediaTek Inc. -+ * -+ * 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. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#ifndef _MT_SYNC_WRITE_H -+#define _MT_SYNC_WRITE_H -+ -+#if defined(__KERNEL__) -+ -+#include -+#include -+ -+/* -+ * Define macros. -+ */ -+#define mt_reg_sync_writel(v, a) \ -+ do { \ -+ __raw_writel((v), (void __force __iomem *)((a))); \ -+ mb(); \ -+ } while (0) -+ -+#define mt_reg_sync_writew(v, a) \ -+ do { \ -+ __raw_writew((v), (void __force __iomem *)((a))); \ -+ mb(); \ -+ } while (0) -+ -+#define mt_reg_sync_writeb(v, a) \ -+ do { \ -+ __raw_writeb((v), (void __force __iomem *)((a))); \ -+ mb(); \ -+ } while (0) -+ -+#ifdef CONFIG_64BIT -+#define mt_reg_sync_writeq(v, a) \ -+ do { \ -+ __raw_writeq((v), (void __force __iomem *)((a))); \ -+ mb(); \ -+ } while (0) -+#endif -+ -+#else /* __KERNEL__ */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+#define mt_reg_sync_writel(v, a) mt65xx_reg_sync_writel(v, a) -+#define mt_reg_sync_writew(v, a) mt65xx_reg_sync_writew(v, a) -+#define mt_reg_sync_writeb(v, a) mt65xx_reg_sync_writeb(v, a) -+ -+#define mb() \ -+ { \ -+ __asm__ __volatile__ ("dsb" : : : "memory"); \ -+ } -+ -+#define mt65xx_reg_sync_writel(v, a) \ -+ do { \ -+ *(volatile unsigned int *)(a) = (v); \ -+ mb(); \ -+ } while (0) -+ -+#define mt65xx_reg_sync_writew(v, a) \ -+ do { \ -+ *(volatile unsigned short *)(a) = (v); \ -+ mb(); \ -+ } while (0) -+ -+#define mt65xx_reg_sync_writeb(v, a) \ -+ do { \ -+ *(volatile unsigned char *)(a) = (v); \ -+ mb(); \ -+ } while (0) -+ -+#endif /* __KERNEL__ */ -+ -+#endif /* !_MT_SYNC_WRITE_H */ -diff --git a/drivers/misc/mediatek/include/mt-plat/wakelock.h b/drivers/misc/mediatek/include/mt-plat/wakelock.h -new file mode 100644 -index 000000000000..f4a698a22880 ---- /dev/null -+++ b/drivers/misc/mediatek/include/mt-plat/wakelock.h -@@ -0,0 +1,67 @@ -+/* include/linux/wakelock.h -+ * -+ * Copyright (C) 2007-2012 Google, Inc. -+ * -+ * This software is licensed under the terms of the GNU General Public -+ * License version 2, as published by the Free Software Foundation, and -+ * may be copied, distributed, and modified under those terms. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ */ -+ -+#ifndef _LINUX_WAKELOCK_H -+#define _LINUX_WAKELOCK_H -+ -+#include -+#include -+ -+/* A wake_lock prevents the system from entering suspend or other low power -+ * states when active. If the type is set to WAKE_LOCK_SUSPEND, the wake_lock -+ * prevents a full system suspend. -+ */ -+ -+enum { -+ WAKE_LOCK_SUSPEND, /* Prevent suspend */ -+ WAKE_LOCK_TYPE_COUNT -+}; -+ -+struct wake_lock { -+ struct wakeup_source ws; -+}; -+ -+static inline void wake_lock_init(struct wake_lock *lock, int type, -+ const char *name) -+{ -+ wakeup_source_init(&lock->ws, name); -+} -+ -+static inline void wake_lock_destroy(struct wake_lock *lock) -+{ -+ wakeup_source_trash(&lock->ws); -+} -+ -+static inline void wake_lock(struct wake_lock *lock) -+{ -+ __pm_stay_awake(&lock->ws); -+} -+ -+static inline void wake_lock_timeout(struct wake_lock *lock, long timeout) -+{ -+ __pm_wakeup_event(&lock->ws, jiffies_to_msecs(timeout)); -+} -+ -+static inline void wake_unlock(struct wake_lock *lock) -+{ -+ __pm_relax(&lock->ws); -+} -+ -+static inline int wake_lock_active(struct wake_lock *lock) -+{ -+ return lock->ws.active; -+} -+ -+#endif --- -2.19.1 - diff --git a/root/target/linux/mediatek/patches-4.19/0007-wifi-adding-wifi-related-changes-outside-driver-dire.patch b/root/target/linux/mediatek/patches-4.19/0007-wifi-adding-wifi-related-changes-outside-driver-dire.patch deleted file mode 100644 index c4e0a903..00000000 --- a/root/target/linux/mediatek/patches-4.19/0007-wifi-adding-wifi-related-changes-outside-driver-dire.patch +++ /dev/null @@ -1,846 +0,0 @@ -From 83ffbaceffed1cd47a6f67fb20e39737dfb2d01a Mon Sep 17 00:00:00 2001 -From: Frank Wunderlich -Date: Tue, 28 Aug 2018 18:14:56 +0200 -Subject: [PATCH 07/77] [wifi] adding wifi-related changes outside - driver-directory - ---- - arch/arm/boot/dts/mt7623.dtsi | 41 +- - arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts | 42 ++ - drivers/soc/mediatek/mtk-pmic-wrap.c | 12 + - drivers/watchdog/mtk_wdt.c | 377 +++++++++++++++++- - include/linux/wakelock.h | 67 ++++ - include/net/genetlink.h | 44 ++ - include/soc/mediatek/pmic_wrap.h | 19 + - include/uapi/linux/genetlink.h | 1 + - 8 files changed, 588 insertions(+), 15 deletions(-) - create mode 100644 include/linux/wakelock.h - create mode 100644 include/soc/mediatek/pmic_wrap.h - -diff --git a/arch/arm/boot/dts/mt7623.dtsi b/arch/arm/boot/dts/mt7623.dtsi -index 04228cf9ddbb..af6b6228f8a8 100644 ---- a/arch/arm/boot/dts/mt7623.dtsi -+++ b/arch/arm/boot/dts/mt7623.dtsi -@@ -266,6 +266,8 @@ - compatible = "mediatek,mt7623-wdt", - "mediatek,mt6589-wdt"; - reg = <0 0x10007000 0 0x100>; -+ interrupts = ; -+ #reset-cells = <1>; - }; - - timer: timer@10008000 { -@@ -494,13 +496,26 @@ - "mediatek,mtk-btif"; - reg = <0 0x1100c000 0 0x1000>; - interrupts = ; -- clocks = <&pericfg CLK_PERI_BTIF>; -- clock-names = "main"; -+ clocks = <&pericfg CLK_PERI_BTIF>, <&pericfg CLK_PERI_AP_DMA>; -+ clock-names = "main", "apdmac"; - reg-shift = <2>; - reg-io-width = <4>; - status = "disabled"; - }; - -+ btif_tx: btif_tx@11000780 { -+ compatible = "mediatek,btif_tx"; -+ reg = <0 0x11000780 0 0x80>; -+ interrupts = ; -+ status = "okay"; -+ }; -+ btif_rx: btif_rx@11000800 { -+ compatible = "mediatek,btif_rx"; -+ reg = <0 0x11000800 0 0x80>; -+ interrupts = ; -+ status = "okay"; -+ }; -+ - nandc: nfi@1100d000 { - compatible = "mediatek,mt7623-nfc", - "mediatek,mt2701-nfc"; -@@ -683,6 +698,28 @@ - status = "disabled"; - }; - -+ consys: consys@18070000 { -+ compatible = "mediatek,mt7623-consys"; -+ reg = <0 0x18070000 0 0x0200>, /*CONN_MCU_CONFIG_BASE */ -+ <0 0x10001000 0 0x1600>; /*TOPCKGEN_BASE */ -+ clocks = <&infracfg CLK_INFRA_CONNMCU>; -+ clock-names = "consysbus"; -+ power-domains = <&scpsys MT2701_POWER_DOMAIN_CONN>; -+ interrupts = , /* BGF_EINT */ -+ ; /* WDT_EINT */ -+ resets = <&watchdog MT2701_TOPRGU_CONN_MCU_RST>; -+ reset-names = "connsys"; -+ status="disabled"; -+ }; -+ wifi:wifi@180f0000 { -+ compatible = "mediatek,mt7623-wifi", -+ "mediatek,wifi"; -+ reg = <0 0x180f0000 0 0x005c>; -+ interrupts = ; -+ clocks = <&pericfg CLK_PERI_AP_DMA>; -+ clock-names = "wifi-dma"; -+ }; -+ - hifsys: syscon@1a000000 { - compatible = "mediatek,mt7623-hifsys", - "mediatek,mt2701-hifsys", -diff --git a/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts b/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts -index 2b760f90f38c..465fb887b2ca 100644 ---- a/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts -+++ b/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts -@@ -84,6 +84,18 @@ - }; - }; - -+ reserved-memory { -+ #address-cells = <2>; -+ #size-cells = <2>; -+ ranges; -+ consys-reserve-memory { -+ compatible = "mediatek,consys-reserve-memory"; -+ no-map; -+ size = <0 0x100000>; -+ alignment = <0 0x100000>; -+ }; -+ }; -+ - leds { - compatible = "gpio-leds"; - pinctrl-names = "default"; -@@ -259,6 +271,36 @@ - }; - }; - -+&pio { -+ consys_pins_default: consys_pins_default { -+ adie { -+ pinmux = , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ ; -+ bias-disable; -+ }; -+ }; -+}; -+&consys { -+ mediatek,pwrap-regmap = <&pwrap>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&consys_pins_default>; -+ vcn18-supply = <&mt6323_vcn18_reg>; -+ vcn28-supply = <&mt6323_vcn28_reg>; -+ vcn33_bt-supply = <&mt6323_vcn33_bt_reg>; -+ vcn33_wifi-supply = <&mt6323_vcn33_wifi_reg>; -+ status = "okay"; -+}; -+ - &pcie { - pinctrl-names = "default"; - pinctrl-0 = <&pcie_default>; -diff --git a/drivers/soc/mediatek/mtk-pmic-wrap.c b/drivers/soc/mediatek/mtk-pmic-wrap.c -index 4e931fdf4d09..6600396ee299 100644 ---- a/drivers/soc/mediatek/mtk-pmic-wrap.c -+++ b/drivers/soc/mediatek/mtk-pmic-wrap.c -@@ -1530,6 +1530,18 @@ static const struct of_device_id of_pwrap_match_tbl[] = { - }; - MODULE_DEVICE_TABLE(of, of_pwrap_match_tbl); - -+struct regmap *pwrap_node_to_regmap(struct device_node *np) -+{ -+ struct platform_device *pdev; -+ struct pmic_wrapper *wrp; -+ pdev = of_find_device_by_node(np); -+ if (!pdev) -+ return ERR_PTR(-ENODEV); -+ wrp = platform_get_drvdata(pdev); -+ return wrp->regmap; -+} -+EXPORT_SYMBOL_GPL(pwrap_node_to_regmap); -+ - static int pwrap_probe(struct platform_device *pdev) - { - int ret, irq; -diff --git a/drivers/watchdog/mtk_wdt.c b/drivers/watchdog/mtk_wdt.c -index 4baf64f21aa1..6a361f808aed 100644 ---- a/drivers/watchdog/mtk_wdt.c -+++ b/drivers/watchdog/mtk_wdt.c -@@ -1,4 +1,3 @@ --// SPDX-License-Identifier: GPL-2.0+ - /* - * Mediatek Watchdog Driver - * -@@ -6,20 +5,51 @@ - * - * Matthias Brugger - * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * - * Based on sunxi_wdt.c - */ - - #include - #include - #include -+#include - #include - #include - #include -+#include -+#include -+#include - #include -+#include - #include -+#ifdef CONFIG_FIQ_GLUE -+#include -+#include -+#endif - #include - #include -+#include -+#include - #include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#ifdef CONFIG_MT6397_MISC -+#include -+#endif - - #define WDT_MAX_TIMEOUT 31 - #define WDT_MIN_TIMEOUT 1 -@@ -38,37 +68,167 @@ - #define WDT_MODE_EXRST_EN (1 << 2) - #define WDT_MODE_IRQ_EN (1 << 3) - #define WDT_MODE_AUTO_START (1 << 4) -+#define WDT_MODE_IRQ_LVL (1 << 5) - #define WDT_MODE_DUAL_EN (1 << 6) - #define WDT_MODE_KEY 0x22000000 - -+#define WDT_STATUS 0x0c -+#define WDT_NONRST_REG 0x20 -+#define WDT_NONRST_REG2 0x24 -+ - #define WDT_SWRST 0x14 - #define WDT_SWRST_KEY 0x1209 - -+#define WDT_SWSYSRST 0x18 -+#define WDT_SWSYSRST_KEY 0x88000000 -+ -+#define WDT_REQ_MODE 0x30 -+#define WDT_REQ_MODE_KEY 0x33000000 -+#define WDT_REQ_IRQ_EN 0x34 -+#define WDT_REQ_IRQ_KEY 0x44000000 -+#define WDT_REQ_MODE_DEBUG_EN 0x80000 -+ -+ - #define DRV_NAME "mtk-wdt" --#define DRV_VERSION "1.0" -+#define DRV_VERSION "2.0" - - static bool nowayout = WATCHDOG_NOWAYOUT; --static unsigned int timeout; -+static unsigned int timeout = WDT_MAX_TIMEOUT; -+ -+struct toprgu_reset { -+ spinlock_t lock; -+ void __iomem *toprgu_swrst_base; -+ int regofs; -+ struct reset_controller_dev rcdev; -+}; - - struct mtk_wdt_dev { - struct watchdog_device wdt_dev; - void __iomem *wdt_base; -+ int wdt_irq_id; -+ struct notifier_block restart_handler; -+ struct toprgu_reset reset_controller; - }; - --static int mtk_wdt_restart(struct watchdog_device *wdt_dev, -- unsigned long action, void *data) -+static void __iomem *toprgu_base; -+static struct watchdog_device *wdt_dev; -+ -+static int toprgu_reset_assert(struct reset_controller_dev *rcdev, -+ unsigned long id) - { -- struct mtk_wdt_dev *mtk_wdt = watchdog_get_drvdata(wdt_dev); -+ unsigned int tmp; -+ unsigned long flags; -+ struct toprgu_reset *data = container_of(rcdev, struct toprgu_reset, rcdev); -+ -+ spin_lock_irqsave(&data->lock, flags); -+ -+ tmp = __raw_readl(data->toprgu_swrst_base + data->regofs); -+ tmp |= BIT(id); -+ tmp |= WDT_SWSYSRST_KEY; -+ writel(tmp, data->toprgu_swrst_base + data->regofs); -+ -+ spin_unlock_irqrestore(&data->lock, flags); -+ -+ return 0; -+} -+ -+static int toprgu_reset_deassert(struct reset_controller_dev *rcdev, -+ unsigned long id) -+{ -+ unsigned int tmp; -+ unsigned long flags; -+ struct toprgu_reset *data = container_of(rcdev, struct toprgu_reset, rcdev); -+ -+ spin_lock_irqsave(&data->lock, flags); -+ -+ tmp = __raw_readl(data->toprgu_swrst_base + data->regofs); -+ tmp &= ~BIT(id); -+ tmp |= WDT_SWSYSRST_KEY; -+ writel(tmp, data->toprgu_swrst_base + data->regofs); -+ -+ spin_unlock_irqrestore(&data->lock, flags); -+ -+ return 0; -+} -+ -+static int toprgu_reset(struct reset_controller_dev *rcdev, -+ unsigned long id) -+{ -+ int ret; -+ -+ ret = toprgu_reset_assert(rcdev, id); -+ if (ret) -+ return ret; -+ -+ return toprgu_reset_deassert(rcdev, id); -+} -+ -+static struct reset_control_ops toprgu_reset_ops = { -+ .assert = toprgu_reset_assert, -+ .deassert = toprgu_reset_deassert, -+ .reset = toprgu_reset, -+}; -+ -+static void toprgu_register_reset_controller(struct platform_device *pdev, int regofs) -+{ -+ int ret; -+ struct mtk_wdt_dev *mtk_wdt = platform_get_drvdata(pdev); -+ -+ spin_lock_init(&mtk_wdt->reset_controller.lock); -+ -+ mtk_wdt->reset_controller.toprgu_swrst_base = mtk_wdt->wdt_base; -+ mtk_wdt->reset_controller.regofs = regofs; -+ mtk_wdt->reset_controller.rcdev.owner = THIS_MODULE; -+ mtk_wdt->reset_controller.rcdev.nr_resets = 15; -+ mtk_wdt->reset_controller.rcdev.ops = &toprgu_reset_ops; -+ mtk_wdt->reset_controller.rcdev.of_node = pdev->dev.of_node; -+ -+ ret = reset_controller_register(&mtk_wdt->reset_controller.rcdev); -+ if (ret) -+ pr_err("could not register toprgu reset controller: %d\n", ret); -+} -+ -+static int mtk_reset_handler(struct notifier_block *this, unsigned long mode, -+ void *cmd) -+{ -+ struct mtk_wdt_dev *mtk_wdt; - void __iomem *wdt_base; -+ u32 reg; - -+ mtk_wdt = container_of(this, struct mtk_wdt_dev, restart_handler); - wdt_base = mtk_wdt->wdt_base; - -- while (1) { -- writel(WDT_SWRST_KEY, wdt_base + WDT_SWRST); -- mdelay(5); -+ /* WDT_STATUS will be cleared to zero after writing to WDT_MODE, so we backup it in WDT_NONRST_REG, -+ * and then print it out in mtk_wdt_probe() after reset -+ */ -+ writel(__raw_readl(wdt_base + WDT_STATUS), wdt_base + WDT_NONRST_REG); -+ -+ reg = ioread32(wdt_base + WDT_MODE); -+ reg &= ~(WDT_MODE_DUAL_EN | WDT_MODE_IRQ_EN | WDT_MODE_EN); -+ reg |= WDT_MODE_KEY; -+ iowrite32(reg, wdt_base + WDT_MODE); -+ -+ if (cmd && !strcmp(cmd, "rpmbpk")) { -+ iowrite32(ioread32(wdt_base + WDT_NONRST_REG2) | (1 << 0), wdt_base + WDT_NONRST_REG2); -+ } else if (cmd && !strcmp(cmd, "recovery")) { -+ iowrite32(ioread32(wdt_base + WDT_NONRST_REG2) | (1 << 1), wdt_base + WDT_NONRST_REG2); -+ #ifdef CONFIG_MT6397_MISC -+ mtk_misc_mark_recovery(); -+ #endif -+ } else if (cmd && !strcmp(cmd, "bootloader")) { -+ iowrite32(ioread32(wdt_base + WDT_NONRST_REG2) | (1 << 2), wdt_base + WDT_NONRST_REG2); -+ #ifdef CONFIG_MT6397_MISC -+ mtk_misc_mark_fast(); -+ #endif - } - -- return 0; -+ if (!arm_pm_restart) { -+ while (1) { -+ writel(WDT_SWRST_KEY, wdt_base + WDT_SWRST); -+ mdelay(5); -+ } -+ } -+ return NOTIFY_DONE; - } - - static int mtk_wdt_ping(struct watchdog_device *wdt_dev) -@@ -77,6 +237,7 @@ static int mtk_wdt_ping(struct watchdog_device *wdt_dev) - void __iomem *wdt_base = mtk_wdt->wdt_base; - - iowrite32(WDT_RST_RELOAD, wdt_base + WDT_RST); -+ printk_deferred("[WDK]: kick Ex WDT\n"); - - return 0; - } -@@ -128,7 +289,8 @@ static int mtk_wdt_start(struct watchdog_device *wdt_dev) - return ret; - - reg = ioread32(wdt_base + WDT_MODE); -- reg &= ~(WDT_MODE_IRQ_EN | WDT_MODE_DUAL_EN); -+ reg |= (WDT_MODE_DUAL_EN | WDT_MODE_IRQ_EN | WDT_MODE_EXRST_EN); -+ reg &= ~(WDT_MODE_IRQ_LVL | WDT_MODE_EXT_POL_HIGH); - reg |= (WDT_MODE_EN | WDT_MODE_KEY); - iowrite32(reg, wdt_base + WDT_MODE); - -@@ -148,13 +310,56 @@ static const struct watchdog_ops mtk_wdt_ops = { - .stop = mtk_wdt_stop, - .ping = mtk_wdt_ping, - .set_timeout = mtk_wdt_set_timeout, -- .restart = mtk_wdt_restart, - }; - -+#ifdef CONFIG_FIQ_GLUE -+static void wdt_fiq(void *arg, void *regs, void *svc_sp) -+{ -+ unsigned int wdt_mode_val; -+ void __iomem *wdt_base = ((struct mtk_wdt_dev *)arg)->wdt_base; -+ -+ wdt_mode_val = __raw_readl(wdt_base + WDT_STATUS); -+ writel(wdt_mode_val, wdt_base + WDT_NONRST_REG); -+ -+ aee_wdt_fiq_info(arg, regs, svc_sp); -+} -+#else -+static void wdt_report_info(void) -+{ -+ struct task_struct *task; -+ -+ task = &init_task; -+ pr_debug("Qwdt: -- watchdog time out\n"); -+ -+ for_each_process(task) { -+ if (task->state == 0) { -+ pr_debug("PID: %d, name: %s\n backtrace:\n", task->pid, task->comm); -+ show_stack(task, NULL); -+ pr_debug("\n"); -+ } -+ } -+ -+ pr_debug("backtrace of current task:\n"); -+ show_stack(NULL, NULL); -+ pr_debug("Qwdt: -- watchdog time out\n"); -+} -+ -+static irqreturn_t mtk_wdt_isr(int irq, void *dev_id) -+{ -+ pr_err("fwq mtk_wdt_isr\n"); -+ -+ wdt_report_info(); -+ BUG(); -+ -+ return IRQ_HANDLED; -+} -+#endif -+ - static int mtk_wdt_probe(struct platform_device *pdev) - { - struct mtk_wdt_dev *mtk_wdt; - struct resource *res; -+ unsigned int tmp; - int err; - - mtk_wdt = devm_kzalloc(&pdev->dev, sizeof(*mtk_wdt), GFP_KERNEL); -@@ -165,9 +370,32 @@ static int mtk_wdt_probe(struct platform_device *pdev) - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - mtk_wdt->wdt_base = devm_ioremap_resource(&pdev->dev, res); -+ - if (IS_ERR(mtk_wdt->wdt_base)) - return PTR_ERR(mtk_wdt->wdt_base); - -+ pr_err("MTK_WDT_NONRST_REG(%x)\n", __raw_readl(mtk_wdt->wdt_base + WDT_NONRST_REG)); -+ -+ mtk_wdt->wdt_irq_id = irq_of_parse_and_map(pdev->dev.of_node, 0); -+ if (!mtk_wdt->wdt_irq_id) { -+ pr_err("RGU get IRQ ID failed\n"); -+ return -ENODEV; -+ } -+ -+#ifndef CONFIG_FIQ_GLUE -+ err = request_irq(mtk_wdt->wdt_irq_id, (irq_handler_t)mtk_wdt_isr, IRQF_TRIGGER_NONE, DRV_NAME, mtk_wdt); -+#else -+ mtk_wdt->wdt_irq_id = get_hardware_irq(mtk_wdt->wdt_irq_id); -+ err = request_fiq(mtk_wdt->wdt_irq_id, wdt_fiq, IRQF_TRIGGER_FALLING, mtk_wdt); -+#endif -+ if (err != 0) { -+ pr_err("mtk_wdt_probe : failed to request irq (%d)\n", err); -+ return err; -+ } -+ -+ toprgu_base = mtk_wdt->wdt_base; -+ wdt_dev = &mtk_wdt->wdt_dev; -+ - mtk_wdt->wdt_dev.info = &mtk_wdt_info; - mtk_wdt->wdt_dev.ops = &mtk_wdt_ops; - mtk_wdt->wdt_dev.timeout = WDT_MAX_TIMEOUT; -@@ -177,7 +405,6 @@ static int mtk_wdt_probe(struct platform_device *pdev) - - watchdog_init_timeout(&mtk_wdt->wdt_dev, timeout, &pdev->dev); - watchdog_set_nowayout(&mtk_wdt->wdt_dev, nowayout); -- watchdog_set_restart_priority(&mtk_wdt->wdt_dev, 128); - - watchdog_set_drvdata(&mtk_wdt->wdt_dev, mtk_wdt); - -@@ -187,9 +414,40 @@ static int mtk_wdt_probe(struct platform_device *pdev) - if (unlikely(err)) - return err; - -+ mtk_wdt->restart_handler.notifier_call = mtk_reset_handler; -+ mtk_wdt->restart_handler.priority = 128; -+ -+ if (arm_pm_restart) { -+ dev_info(&pdev->dev, "register restart_handler on reboot_notifier_list for psci reset\n"); -+ err = register_reboot_notifier(&mtk_wdt->restart_handler); -+ if (err != 0) -+ dev_warn(&pdev->dev, -+ "cannot register reboot notifier (err=%d)\n", err); -+ } else { -+ err = register_restart_handler(&mtk_wdt->restart_handler); -+ if (err) -+ dev_warn(&pdev->dev, -+ "cannot register restart handler (err=%d)\n", err); -+ } -+ - dev_info(&pdev->dev, "Watchdog enabled (timeout=%d sec, nowayout=%d)\n", - mtk_wdt->wdt_dev.timeout, nowayout); - -+ writel(WDT_REQ_MODE_KEY | (__raw_readl(mtk_wdt->wdt_base + WDT_REQ_MODE) & -+ (~WDT_REQ_MODE_DEBUG_EN)), mtk_wdt->wdt_base + WDT_REQ_MODE); -+ -+ toprgu_register_reset_controller(pdev, WDT_SWSYSRST); -+ -+ /* enable scpsys thermal and thermal_controller request, and set to reset directly mode */ -+ tmp = ioread32(mtk_wdt->wdt_base + WDT_REQ_MODE) | (1 << 18) | (1 << 0); -+ tmp |= WDT_REQ_MODE_KEY; -+ iowrite32(tmp, mtk_wdt->wdt_base + WDT_REQ_MODE); -+ -+ tmp = ioread32(mtk_wdt->wdt_base + WDT_REQ_IRQ_EN); -+ tmp &= ~((1 << 18) | (1 << 0)); -+ tmp |= WDT_REQ_IRQ_KEY; -+ iowrite32(tmp, mtk_wdt->wdt_base + WDT_REQ_IRQ_EN); -+ - return 0; - } - -@@ -205,8 +463,12 @@ static int mtk_wdt_remove(struct platform_device *pdev) - { - struct mtk_wdt_dev *mtk_wdt = platform_get_drvdata(pdev); - -+ unregister_restart_handler(&mtk_wdt->restart_handler); -+ - watchdog_unregister_device(&mtk_wdt->wdt_dev); - -+ reset_controller_unregister(&mtk_wdt->reset_controller.rcdev); -+ - return 0; - } - -@@ -258,6 +520,95 @@ static struct platform_driver mtk_wdt_driver = { - - module_platform_driver(mtk_wdt_driver); - -+static int wk_proc_cmd_read(struct seq_file *s, void *v) -+{ -+ unsigned int enabled = 1; -+ -+ if (!(ioread32(toprgu_base + WDT_MODE) & WDT_MODE_EN)) -+ enabled = 0; -+ -+ seq_printf(s, "enabled timeout\n%-4d %-8d\n", enabled, wdt_dev->timeout); -+ -+ return 0; -+} -+ -+static int wk_proc_cmd_open(struct inode *inode, struct file *file) -+{ -+ return single_open(file, wk_proc_cmd_read, NULL); -+} -+ -+static ssize_t wk_proc_cmd_write(struct file *file, const char *buf, size_t count, loff_t *data) -+{ -+ int ret; -+ int enable; -+ int timeout; -+ char wk_cmd_buf[256]; -+ -+ if (count == 0) -+ return -1; -+ -+ if (count > 255) -+ count = 255; -+ -+ ret = copy_from_user(wk_cmd_buf, buf, count); -+ if (ret < 0) -+ return -1; -+ -+ wk_cmd_buf[count] = '\0'; -+ -+ pr_debug("Write %s\n", wk_cmd_buf); -+ -+ ret = sscanf(wk_cmd_buf, "%d %d", &enable, &timeout); -+ if (ret != 2) -+ pr_debug("%s: expect 2 numbers\n", __func__); -+ -+ pr_debug("[WDK] enable=%d timeout=%d\n", enable, timeout); -+ -+ if (timeout > 20 && timeout <= WDT_MAX_TIMEOUT) { -+ wdt_dev->timeout = timeout; -+ mtk_wdt_set_timeout(wdt_dev, wdt_dev->timeout); -+ } else { -+ pr_err("[WDK] The timeout(%d) should bigger than 20 and not bigger than %d\n", -+ timeout, WDT_MAX_TIMEOUT); -+ -+ } -+ -+ if (enable == 1) { -+ mtk_wdt_start(wdt_dev); -+ set_bit(WDOG_ACTIVE, &wdt_dev->status); -+ pr_err("[WDK] enable wdt\n"); -+ } else if (enable == 0) { -+ mtk_wdt_stop(wdt_dev); -+ clear_bit(WDOG_ACTIVE, &wdt_dev->status); -+ pr_err("[WDK] disable wdt\n"); -+ } -+ -+ return count; -+} -+ -+static const struct file_operations wk_proc_cmd_fops = { -+ .owner = THIS_MODULE, -+ .open = wk_proc_cmd_open, -+ .read = seq_read, -+ .write = wk_proc_cmd_write, -+ .llseek = seq_lseek, -+ .release = single_release, -+}; -+ -+static int __init wk_proc_init(void) -+{ -+ struct proc_dir_entry *de = proc_create("wdk", 0660, NULL, &wk_proc_cmd_fops); -+ -+ if (!de) -+ pr_err("[wk_proc_init]: create /proc/wdk failed\n"); -+ -+ pr_debug("[WDK] Initialize proc\n"); -+ -+ return 0; -+} -+ -+late_initcall(wk_proc_init); -+ - module_param(timeout, uint, 0); - MODULE_PARM_DESC(timeout, "Watchdog heartbeat in seconds"); - -diff --git a/include/linux/wakelock.h b/include/linux/wakelock.h -new file mode 100644 -index 000000000000..f4a698a22880 ---- /dev/null -+++ b/include/linux/wakelock.h -@@ -0,0 +1,67 @@ -+/* include/linux/wakelock.h -+ * -+ * Copyright (C) 2007-2012 Google, Inc. -+ * -+ * This software is licensed under the terms of the GNU General Public -+ * License version 2, as published by the Free Software Foundation, and -+ * may be copied, distributed, and modified under those terms. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ */ -+ -+#ifndef _LINUX_WAKELOCK_H -+#define _LINUX_WAKELOCK_H -+ -+#include -+#include -+ -+/* A wake_lock prevents the system from entering suspend or other low power -+ * states when active. If the type is set to WAKE_LOCK_SUSPEND, the wake_lock -+ * prevents a full system suspend. -+ */ -+ -+enum { -+ WAKE_LOCK_SUSPEND, /* Prevent suspend */ -+ WAKE_LOCK_TYPE_COUNT -+}; -+ -+struct wake_lock { -+ struct wakeup_source ws; -+}; -+ -+static inline void wake_lock_init(struct wake_lock *lock, int type, -+ const char *name) -+{ -+ wakeup_source_init(&lock->ws, name); -+} -+ -+static inline void wake_lock_destroy(struct wake_lock *lock) -+{ -+ wakeup_source_trash(&lock->ws); -+} -+ -+static inline void wake_lock(struct wake_lock *lock) -+{ -+ __pm_stay_awake(&lock->ws); -+} -+ -+static inline void wake_lock_timeout(struct wake_lock *lock, long timeout) -+{ -+ __pm_wakeup_event(&lock->ws, jiffies_to_msecs(timeout)); -+} -+ -+static inline void wake_unlock(struct wake_lock *lock) -+{ -+ __pm_relax(&lock->ws); -+} -+ -+static inline int wake_lock_active(struct wake_lock *lock) -+{ -+ return lock->ws.active; -+} -+ -+#endif -diff --git a/include/net/genetlink.h b/include/net/genetlink.h -index decf6012a401..6471da92334a 100644 ---- a/include/net/genetlink.h -+++ b/include/net/genetlink.h -@@ -144,6 +144,50 @@ struct genl_ops { - }; - - int genl_register_family(struct genl_family *family); -+ -+/** -+ * genl_register_family_with_ops - register a generic netlink family with ops -+ * @family: generic netlink family -+ * @ops: operations to be registered -+ * @n_ops: number of elements to register -+ * -+ * Registers the specified family and operations from the specified table. -+ * Only one family may be registered with the same family name or identifier. -+ * -+ * The family id may equal GENL_ID_GENERATE causing an unique id to -+ * be automatically generated and assigned. -+ * -+ * Either a doit or dumpit callback must be specified for every registered -+ * operation or the function will fail. Only one operation structure per -+ * command identifier may be registered. -+ * -+ * See include/net/genetlink.h for more documenation on the operations -+ * structure. -+ * -+ * Return 0 on success or a negative error code. -+ */ -+static inline int -+_genl_register_family_with_ops_grps(struct genl_family *family, -+ const struct genl_ops *ops, size_t n_ops, -+ const struct genl_multicast_group *mcgrps, -+ size_t n_mcgrps) -+{ -+ family->module = THIS_MODULE; -+ family->ops = ops; -+ family->n_ops = n_ops; -+ family->mcgrps = mcgrps; -+ family->n_mcgrps = n_mcgrps; -+ return genl_register_family(family); -+} -+#define genl_register_family_with_ops(family, ops) \ -+ _genl_register_family_with_ops_grps((family), \ -+ (ops), ARRAY_SIZE(ops), \ -+ NULL, 0) -+#define genl_register_family_with_ops_groups(family, ops, grps) \ -+ _genl_register_family_with_ops_grps((family), \ -+ (ops), ARRAY_SIZE(ops), \ -+ (grps), ARRAY_SIZE(grps)) -+ - int genl_unregister_family(const struct genl_family *family); - void genl_notify(const struct genl_family *family, struct sk_buff *skb, - struct genl_info *info, u32 group, gfp_t flags); -diff --git a/include/soc/mediatek/pmic_wrap.h b/include/soc/mediatek/pmic_wrap.h -new file mode 100644 -index 000000000000..5b5c85272c58 ---- /dev/null -+++ b/include/soc/mediatek/pmic_wrap.h -@@ -0,0 +1,19 @@ -+/* -+ * Copyright (C) 2015 MediaTek Inc. -+ * -+ * 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. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#ifndef __SOC_MEDIATEK_PMIC_WRAP_H -+#define __SOC_MEDIATEK_PMIC_WRAP_H -+ -+extern struct regmap *pwrap_node_to_regmap(struct device_node *np); -+ -+#endif /* __SOC_MEDIATEK_PMIC_WRAP_H */ -diff --git a/include/uapi/linux/genetlink.h b/include/uapi/linux/genetlink.h -index 877f7fa95466..6a176b3d43f9 100644 ---- a/include/uapi/linux/genetlink.h -+++ b/include/uapi/linux/genetlink.h -@@ -27,6 +27,7 @@ struct genlmsghdr { - /* - * List of reserved static generic netlink identifiers: - */ -+#define GENL_ID_GENERATE 0 - #define GENL_ID_CTRL NLMSG_MIN_TYPE - #define GENL_ID_VFS_DQUOT (NLMSG_MIN_TYPE + 1) - #define GENL_ID_PMCRAID (NLMSG_MIN_TYPE + 2) --- -2.19.1 - diff --git a/root/target/linux/mediatek/patches-4.19/0008-gcc-gcc8-fixes-by-Dominik-Koch-nic_rx-patch-from-htt.patch b/root/target/linux/mediatek/patches-4.19/0008-gcc-gcc8-fixes-by-Dominik-Koch-nic_rx-patch-from-htt.patch deleted file mode 100644 index ed80e2bb..00000000 --- a/root/target/linux/mediatek/patches-4.19/0008-gcc-gcc8-fixes-by-Dominik-Koch-nic_rx-patch-from-htt.patch +++ /dev/null @@ -1,78 +0,0 @@ -From 203a5a7727a80ab519ea00181a909e415c5567ab Mon Sep 17 00:00:00 2001 -From: Frank Wunderlich -Date: Wed, 29 Aug 2018 19:17:00 +0200 -Subject: [PATCH 08/77] [gcc] gcc8-fixes by Dominik Koch + nic_rx-patch from - https://bugs.linaro.org/show_bug.cgi?id=3823 - ---- - .../misc/mediatek/connectivity/wlan/gen2/nic/nic_rx.c | 10 ++++++---- - .../misc/mediatek/connectivity/wlan/gen2/nic/que_mgt.c | 2 +- - .../connectivity/wlan/gen2/os/linux/include/gl_kal.h | 2 +- - 3 files changed, 8 insertions(+), 6 deletions(-) - -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic_rx.c b/drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic_rx.c -index ba4840414da8..65823023cec0 100644 ---- a/drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic_rx.c -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic_rx.c -@@ -2061,7 +2061,6 @@ VOID nicRxProcessEventPacket(IN P_ADAPTER_T prAdapter, IN OUT P_SW_RFB_T prSwRfb - case EVENT_ID_BT_OVER_WIFI: - #if CFG_ENABLE_BT_OVER_WIFI - { -- UINT_8 aucTmp[sizeof(AMPC_EVENT) + sizeof(BOW_LINK_DISCONNECTED)]; - P_EVENT_BT_OVER_WIFI prEventBtOverWifi; - P_AMPC_EVENT prBowEvent; - P_BOW_LINK_CONNECTED prBowLinkConnected; -@@ -2069,11 +2068,11 @@ VOID nicRxProcessEventPacket(IN P_ADAPTER_T prAdapter, IN OUT P_SW_RFB_T prSwRfb - - prEventBtOverWifi = (P_EVENT_BT_OVER_WIFI) (prEvent->aucBuffer); - -- /* construct event header */ -- prBowEvent = (P_AMPC_EVENT) aucTmp; -- - if (prEventBtOverWifi->ucLinkStatus == 0) { - /* Connection */ -+ UINT_8 aucTmp[sizeof(AMPC_EVENT) + sizeof(BOW_LINK_CONNECTED)]; -+ /* construct event header */ -+ prBowEvent = (P_AMPC_EVENT) aucTmp; - prBowEvent->rHeader.ucEventId = BOW_EVENT_ID_LINK_CONNECTED; - prBowEvent->rHeader.ucSeqNumber = 0; - prBowEvent->rHeader.u2PayloadLength = sizeof(BOW_LINK_CONNECTED); -@@ -2086,6 +2085,9 @@ VOID nicRxProcessEventPacket(IN P_ADAPTER_T prAdapter, IN OUT P_SW_RFB_T prSwRfb - kalIndicateBOWEvent(prAdapter->prGlueInfo, prBowEvent); - } else { - /* Disconnection */ -+ UINT_8 aucTmp[sizeof(AMPC_EVENT) + sizeof(BOW_LINK_DISCONNECTED)]; -+ /* construct event header */ -+ prBowEvent = (P_AMPC_EVENT) aucTmp; - prBowEvent->rHeader.ucEventId = BOW_EVENT_ID_LINK_DISCONNECTED; - prBowEvent->rHeader.ucSeqNumber = 0; - prBowEvent->rHeader.u2PayloadLength = sizeof(BOW_LINK_DISCONNECTED); -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/nic/que_mgt.c b/drivers/misc/mediatek/connectivity/wlan/gen2/nic/que_mgt.c -index dd00859d4608..ad7107b1d9a4 100644 ---- a/drivers/misc/mediatek/connectivity/wlan/gen2/nic/que_mgt.c -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/nic/que_mgt.c -@@ -5021,7 +5021,7 @@ VOID qmHandleRxArpPackets(P_ADAPTER_T prAdapter, P_SW_RFB_T prSwRfb) - if (prBssInfo && prBssInfo->prStaRecOfAP && prBssInfo->prStaRecOfAP->aucMacAddr) { - if (EQUAL_MAC_ADDR(&(pucData[ETH_TYPE_LEN_OFFSET + 10]), /* source hardware address */ - prBssInfo->prStaRecOfAP->aucMacAddr)) { -- strncpy(apIp, &(pucData[ETH_TYPE_LEN_OFFSET + 16]), sizeof(apIp)); /* src ip address */ -+ memcpy(apIp, &(pucData[ETH_TYPE_LEN_OFFSET + 16]), sizeof(apIp)); /* src ip address */ - DBGLOG(INIT, TRACE, "get arp response from AP %d.%d.%d.%d\n", - apIp[0], apIp[1], apIp[2], apIp[3]); - } -diff --git a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_kal.h b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_kal.h -index 1406905095e6..b1386918c08d 100644 ---- a/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_kal.h -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_kal.h -@@ -852,7 +852,7 @@ struct KAL_HALT_CTRL_T { - - /* string operation */ - #define kalStrCpy(dest, src) strcpy(dest, src) --#define kalStrnCpy(dest, src, n) strncpy(dest, src, n) -+#define kalStrnCpy(dest, src, n) memcpy(dest, src, n) - #define kalStrCmp(ct, cs) strcmp(ct, cs) - #define kalStrnCmp(ct, cs, n) strncmp(ct, cs, n) - #define kalStrChr(s, c) strchr(s, c) --- -2.19.1 - diff --git a/root/target/linux/mediatek/patches-4.19/0009-wifi-activated-wifi-options.patch b/root/target/linux/mediatek/patches-4.19/0009-wifi-activated-wifi-options.patch deleted file mode 100644 index 02d55f18..00000000 --- a/root/target/linux/mediatek/patches-4.19/0009-wifi-activated-wifi-options.patch +++ /dev/null @@ -1,52 +0,0 @@ -From b3bf5911a5d9f6eb8112d294ffaf5f474dccc686 Mon Sep 17 00:00:00 2001 -From: Frank Wunderlich -Date: Tue, 23 Oct 2018 13:31:20 +0200 -Subject: [PATCH 09/77] [wifi] activated wifi-options - ---- - arch/arm/configs/mt7623n_evb_fwu_defconfig | 18 +++++++++--------- - 1 file changed, 9 insertions(+), 9 deletions(-) - -diff --git a/arch/arm/configs/mt7623n_evb_fwu_defconfig b/arch/arm/configs/mt7623n_evb_fwu_defconfig -index 09df75013c09..fe7532886ccc 100644 ---- a/arch/arm/configs/mt7623n_evb_fwu_defconfig -+++ b/arch/arm/configs/mt7623n_evb_fwu_defconfig -@@ -141,8 +141,8 @@ CONFIG_NF_LOG_IPV6=m - CONFIG_NF_REJECT_IPV6=m - CONFIG_IP_NF_NAT=m - CONFIG_IP6_NF_NAT=m --CONFIG_NF_NAT_MASQUERADE_IPV4=m --CONFIG_NF_NAT_MASQUERADE_IPV6=m -+CONFIG_NF_NAT_MASQUERADE_IPV4=y -+CONFIG_NF_NAT_MASQUERADE_IPV6=y - CONFIG_IP_NF_FILTER=m - CONFIG_IP6_NF_FILTER=m - CONFIG_IP_NF_TARGET_MASQUERADE=m -@@ -376,17 +376,17 @@ CONFIG_CFG80211=y - - #internal wlan (not working yet) - # CONFIG_MTK_CONN_LTE_IDC_SUPPORT is not set --#CONFIG_MTK_COMBO=y --#CONFIG_MTK_COMBO_CHIP_CONSYS_7623=y -+CONFIG_MTK_COMBO=y -+CONFIG_MTK_COMBO_CHIP_CONSYS_7623=y - #used in 4.4, but should be set in Kconfig by selecting mt7623 COMBO --#CONFIG_MTK_PLATFORM="mt7623" -+CONFIG_MTK_PLATFORM="mt7623" - --#CONFIG_MTK_COMBO_COMM=y --#CONFIG_MTK_COMBO_WIFI=y --#CONFIG_NL80211_TESTMODE=y -+CONFIG_MTK_COMBO_COMM=y -+CONFIG_MTK_COMBO_WIFI=y -+CONFIG_NL80211_TESTMODE=y - - #internal Bluetooth (also not working yet) --#CONFIG_BT=y -+CONFIG_BT=y - #CONFIG_MTK_COMBO_BT=y - #CONFIG_MTK_COMBO_BT_HCI=y - #needed for BT? --- -2.19.1 - diff --git a/root/target/linux/mediatek/patches-4.19/0012-defconfig-add-missing-CONFIG_PCI_MSI-needed-for-pcie.patch b/root/target/linux/mediatek/patches-4.19/0012-defconfig-add-missing-CONFIG_PCI_MSI-needed-for-pcie.patch deleted file mode 100644 index 829e2c89..00000000 --- a/root/target/linux/mediatek/patches-4.19/0012-defconfig-add-missing-CONFIG_PCI_MSI-needed-for-pcie.patch +++ /dev/null @@ -1,34 +0,0 @@ -From ec64b17f37390c32cd88ebddbabd423f438335fc Mon Sep 17 00:00:00 2001 -From: Frank Wunderlich -Date: Sun, 11 Nov 2018 09:52:44 +0100 -Subject: [PATCH 12/77] [defconfig] add missing CONFIG_PCI_MSI (needed for pcie - and maybe sata) and EARLY_PRINTK - ---- - arch/arm/configs/mt7623n_evb_fwu_defconfig | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/arch/arm/configs/mt7623n_evb_fwu_defconfig b/arch/arm/configs/mt7623n_evb_fwu_defconfig -index d7741650941f..fe1edaa7680f 100644 ---- a/arch/arm/configs/mt7623n_evb_fwu_defconfig -+++ b/arch/arm/configs/mt7623n_evb_fwu_defconfig -@@ -1,6 +1,8 @@ - CONFIG_LOCALVERSION="-bpi-r2" - CONFIG_LOCALVERSION_AUTO=n - -+CONFIG_EARLY_PRINTK=y -+ - #spectre/meltdown - CONFIG_PAGE_TABLE_ISOLATION=y - -@@ -58,6 +60,7 @@ CONFIG_PL310_ERRATA_753970=y - CONFIG_PL310_ERRATA_769419=y - - CONFIG_PCI=y -+CONFIG_PCI_MSI=y - CONFIG_SMP=y - CONFIG_HAVE_ARM_ARCH_TIMER=y - CONFIG_NR_CPUS=16 --- -2.19.1 - diff --git a/root/target/linux/mediatek/patches-4.19/0014-dts-set-mac-address-eth0.patch b/root/target/linux/mediatek/patches-4.19/0014-dts-set-mac-address-eth0.patch deleted file mode 100644 index 33a9e095..00000000 --- a/root/target/linux/mediatek/patches-4.19/0014-dts-set-mac-address-eth0.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 961d318c99fb0019f0fa571a160af09e859d63e8 Mon Sep 17 00:00:00 2001 -From: Frank Wunderlich -Date: Mon, 31 Dec 2018 17:00:56 +0100 -Subject: [PATCH 14/77] [dts] set mac-address (eth0) - -can be overwritten by uboot (ethaddr) if using separated fdt -or devicetree-overlay ---- - arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts b/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts -index 465fb887b2ca..a47022765326 100644 ---- a/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts -+++ b/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts -@@ -15,6 +15,7 @@ - - aliases { - serial2 = &uart2; -+ ethernet0 = &gmac0; - }; - - chosen { -@@ -147,6 +148,7 @@ - compatible = "mediatek,eth-mac"; - reg = <0>; - phy-mode = "trgmii"; -+ mac-address = [02 02 02 02 02 02]; - - fixed-link { - speed = <1000>; --- -2.19.1 - diff --git a/root/target/linux/mediatek/patches-4.19/0016-build.sh-dts-added-devicetree-Overlay.patch b/root/target/linux/mediatek/patches-4.19/0016-build.sh-dts-added-devicetree-Overlay.patch deleted file mode 100644 index 92638e53..00000000 --- a/root/target/linux/mediatek/patches-4.19/0016-build.sh-dts-added-devicetree-Overlay.patch +++ /dev/null @@ -1,40 +0,0 @@ -From d226d27f0419a6d1f2fa42abbf67eb4315223372 Mon Sep 17 00:00:00 2001 -From: Frank Wunderlich -Date: Sat, 5 Jan 2019 10:11:41 +0100 -Subject: [PATCH 16/77] [build.sh,dts] added devicetree-Overlay - -compile bpi-r2-mac.dts like this: - -dtc -@ -I dts -O dtb -o bpi-r2-mac.dtb bpi-r2-mac.dts - -in uboot you can load DTO with this (after loading base ftd): -loaddto=echo "loaddto:${dto}";fdt addr ${dtaddr};fdt resize 8192; setexpr fdtovaddr ${dtaddr} + F000; - fatload ${device} ${partition} ${fdtovaddr} ${bpi}/${board}/${service}/dtb/${dto} && fdt apply ${fdtovaddr} - -uboot needs option CONFIG_OF_LIBFDT_OVERLAY=y ---- - bpi-r2-mac.dts | 12 ++++++++++++ - 1 files changed, 12 insertions(+) - create mode 100644 bpi-r2-mac.dts - -diff --git a/bpi-r2-mac.dts b/bpi-r2-mac.dts -new file mode 100644 -index 000000000000..f4eed976e158 ---- /dev/null -+++ b/bpi-r2-mac.dts -@@ -0,0 +1,12 @@ -+/dts-v1/; -+/plugin/; -+ -+/ { -+ fragment@0 { -+ /*target = <&gmac0>;*/ -+ target-path = "/eth/gmac0"; -+ __overlay__ { -+ mac-address = [02 01 02 03 04 05]; -+ }; -+ }; -+}; --- -2.19.1 - diff --git a/root/target/linux/mediatek/patches-4.19/0019-net-dsa-adding-fields-for-holding-information-about-.patch b/root/target/linux/mediatek/patches-4.19/0019-net-dsa-adding-fields-for-holding-information-about-.patch deleted file mode 100644 index f8e8812a..00000000 --- a/root/target/linux/mediatek/patches-4.19/0019-net-dsa-adding-fields-for-holding-information-about-.patch +++ /dev/null @@ -1,60 +0,0 @@ -From 329ff45aafea77cd9f5c97d2988e7c399ef05d6d Mon Sep 17 00:00:00 2001 -From: Frank Wunderlich -Date: Thu, 29 Nov 2018 11:34:09 +0100 -Subject: [PATCH 19/77] net: dsa: adding fields for holding information about - upstream-port - -for multiple cpu-Ports aech port needs storing the the cpu-port to be used -this Patch adds the needed fields for this - -based on -https://github.com/openwrt/openwrt/blob/master/target/linux/mediatek/patches-4.14/0033-dsa-multi-cpu.patch - -Signed-off-by: Frank Wunderlich ---- - include/net/dsa.h | 4 ++++ - net/dsa/dsa_priv.h | 5 +++++ - 2 files changed, 9 insertions(+) - -diff --git a/include/net/dsa.h b/include/net/dsa.h -index 461e8a7661b7..6e0c95625a21 100644 ---- a/include/net/dsa.h -+++ b/include/net/dsa.h -@@ -202,6 +202,10 @@ struct dsa_port { - struct net_device *bridge_dev; - struct devlink_port devlink_port; - struct phylink *pl; -+ -+ struct net_device *ethernet; -+ int upstream; -+ - /* - * Original copy of the master netdev ethtool_ops - */ -diff --git a/net/dsa/dsa_priv.h b/net/dsa/dsa_priv.h -index 3964c6f7a7c0..559a3a250c88 100644 ---- a/net/dsa/dsa_priv.h -+++ b/net/dsa/dsa_priv.h -@@ -81,6 +81,8 @@ struct dsa_slave_priv { - - /* TC context */ - struct list_head mall_tc_list; -+ -+ struct net_device *master; - }; - - /* dsa.c */ -@@ -187,7 +189,10 @@ static inline struct net_device * - dsa_slave_to_master(const struct net_device *dev) - { - struct dsa_port *dp = dsa_slave_to_port(dev); -+ struct dsa_slave_priv *p = netdev_priv(dev); - -+ if (p->master) -+ return p->master; - return dp->cpu_dp->master; - } - --- -2.19.1 - diff --git a/root/target/linux/mediatek/patches-4.19/0020-net-dsa-add-helper-functions.patch b/root/target/linux/mediatek/patches-4.19/0020-net-dsa-add-helper-functions.patch deleted file mode 100644 index feb001f8..00000000 --- a/root/target/linux/mediatek/patches-4.19/0020-net-dsa-add-helper-functions.patch +++ /dev/null @@ -1,86 +0,0 @@ -From 90adf38283688d8c25feeb7e3989cc2da3d58122 Mon Sep 17 00:00:00 2001 -From: Frank Wunderlich -Date: Thu, 29 Nov 2018 11:27:12 +0100 -Subject: [PATCH 20/77] net: dsa: add helper functions - -for using mutliple cpu-Ports 3 additional functions are defined to read -dts-option (dsa_user_parse) and check if current port is a upstream-port -(dsa_port_upstream_port, dsa_is_upstream_port) - -based on -https://github.com/openwrt/openwrt/blob/master/target/linux/mediatek/patches-4.14/0033-dsa-multi-cpu.patch - -Signed-off-by: Frank Wunderlich ---- - include/net/dsa.h | 18 ++++++++++++++++++ - net/dsa/dsa2.c | 18 ++++++++++++++++++ - 2 files changed, 36 insertions(+) - -diff --git a/include/net/dsa.h b/include/net/dsa.h -index 6e0c95625a21..36db2ee83da6 100644 ---- a/include/net/dsa.h -+++ b/include/net/dsa.h -@@ -318,6 +318,12 @@ static inline unsigned int dsa_towards_port(struct dsa_switch *ds, int device, - return ds->rtable[device]; - } - -+ -+static inline bool dsa_is_upstream_port(struct dsa_switch *ds, int p) -+{ -+ return dsa_is_cpu_port(ds, p) || dsa_is_dsa_port(ds, p); -+} -+ - /* Return the local port used to reach the dedicated CPU port */ - static inline unsigned int dsa_upstream_port(struct dsa_switch *ds, int port) - { -@@ -330,6 +336,18 @@ static inline unsigned int dsa_upstream_port(struct dsa_switch *ds, int port) - return dsa_towards_port(ds, cpu_dp->ds->index, cpu_dp->index); - } - -+static inline u8 dsa_port_upstream_port(struct dsa_switch *ds, int port) -+{ -+ /* -+ * If this port has a specific upstream cpu port, use it, -+ * otherwise use the switch default. -+ */ -+ if (ds->ports[port].upstream) -+ return ds->ports[port].upstream; -+ else -+ return dsa_upstream_port(ds, port); -+} -+ - typedef int dsa_fdb_dump_cb_t(const unsigned char *addr, u16 vid, - bool is_static, void *data); - struct dsa_switch_ops { -diff --git a/net/dsa/dsa2.c b/net/dsa/dsa2.c -index a1917025e155..b7c6da2f1f08 100644 ---- a/net/dsa/dsa2.c -+++ b/net/dsa/dsa2.c -@@ -255,6 +255,24 @@ static void dsa_tree_teardown_default_cpu(struct dsa_switch_tree *dst) - dst->cpu_dp = NULL; - } - -+static int dsa_user_parse(struct dsa_port *port, u32 index, -+ struct dsa_switch *ds) -+{ -+ struct device_node *cpu_port; -+ const unsigned int *cpu_port_reg; -+ int cpu_port_index; -+ -+ cpu_port = of_parse_phandle(port->dn, "default_cpu", 0); -+ if (cpu_port) { -+ cpu_port_reg = of_get_property(cpu_port, "reg", NULL); -+ if (!cpu_port_reg) -+ return -EINVAL; -+ cpu_port_index = be32_to_cpup(cpu_port_reg); -+ ds->ports[index].upstream = cpu_port_index; -+ } -+ return 0; -+} -+ - static int dsa_port_setup(struct dsa_port *dp) - { - struct dsa_switch *ds = dp->ds; --- -2.19.1 - diff --git a/root/target/linux/mediatek/patches-4.19/0021-net-dsa-adding-handling-of-second-CPU-Port.patch b/root/target/linux/mediatek/patches-4.19/0021-net-dsa-adding-handling-of-second-CPU-Port.patch deleted file mode 100644 index 8b5a9730..00000000 --- a/root/target/linux/mediatek/patches-4.19/0021-net-dsa-adding-handling-of-second-CPU-Port.patch +++ /dev/null @@ -1,102 +0,0 @@ -From 8325a7cbf9648725163a7596ba3381775039fe69 Mon Sep 17 00:00:00 2001 -From: Frank Wunderlich -Date: Thu, 29 Nov 2018 11:38:27 +0100 -Subject: [PATCH 21/77] net: dsa: adding handling of second CPU-Port - -this patch adds the core-functionality of multiple cpu-ports - -currently it uses definition in dts to make connection between cpu and user-port - -based on -https://github.com/openwrt/openwrt/blob/master/target/linux/mediatek/patches-4.14/0033-dsa-multi-cpu.patch - -Signed-off-by: Frank Wunderlich ---- - net/dsa/dsa2.c | 18 ++++++++++++++++++ - net/dsa/slave.c | 3 ++- - 2 files changed, 20 insertions(+), 1 deletion(-) - -diff --git a/net/dsa/dsa2.c b/net/dsa/dsa2.c -index b7c6da2f1f08..8f64535fd2a0 100644 ---- a/net/dsa/dsa2.c -+++ b/net/dsa/dsa2.c -@@ -303,6 +303,8 @@ static int dsa_port_setup(struct dsa_port *dp) - ds->index, dp->index); - return err; - } -+ if (dp->master) -+ dp->master->dsa_ptr = dp; - break; - case DSA_PORT_TYPE_DSA: - /* dp->index is used now as port_number. However -@@ -323,12 +325,17 @@ static int dsa_port_setup(struct dsa_port *dp) - devlink_port_attrs_set(&dp->devlink_port, - DEVLINK_PORT_FLAVOUR_PHYSICAL, - dp->index, false, 0); -+ err = dsa_user_parse(dp, dp->index, ds); -+ if (err) -+ return err; -+ - err = dsa_slave_create(dp); - if (err) - dev_err(ds->dev, "failed to create slave for port %d.%d\n", - ds->index, dp->index); - else - devlink_port_type_eth_set(&dp->devlink_port, dp->slave); -+ - break; - } - -@@ -344,6 +351,14 @@ static void dsa_port_teardown(struct dsa_port *dp) - case DSA_PORT_TYPE_UNUSED: - break; - case DSA_PORT_TYPE_CPU: -+ dsa_port_link_unregister_of(dp); -+ if (dp->master) -+ dp->master->dsa_ptr = NULL; -+ if (dp->ethernet) { -+ dev_put(dp->ethernet); -+ dp->ethernet = NULL; -+ } -+ break; - case DSA_PORT_TYPE_DSA: - dsa_port_link_unregister_of(dp); - break; -@@ -598,6 +613,9 @@ static int dsa_port_parse_cpu(struct dsa_port *dp, struct net_device *master) - dp->master = master; - dp->dst = dst; - -+ dev_hold(master); -+ ds->ports[dp->index].ethernet = master; -+ - return 0; - } - -diff --git a/net/dsa/slave.c b/net/dsa/slave.c -index 1c45c1d6d241..3bdbd53d3420 100644 ---- a/net/dsa/slave.c -+++ b/net/dsa/slave.c -@@ -1291,11 +1291,11 @@ static void dsa_slave_notify(struct net_device *dev, unsigned long val) - int dsa_slave_create(struct dsa_port *port) - { - const struct dsa_port *cpu_dp = port->cpu_dp; -- struct net_device *master = cpu_dp->master; - struct dsa_switch *ds = port->ds; - const char *name = port->name; - struct net_device *slave_dev; - struct dsa_slave_priv *p; -+ struct net_device *master = ds->ports[port->upstream].ethernet; - int ret; - - if (!ds->num_tx_queues) -@@ -1334,6 +1334,7 @@ int dsa_slave_create(struct dsa_port *port) - p->dp = port; - INIT_LIST_HEAD(&p->mall_tc_list); - p->xmit = cpu_dp->tag_ops->xmit; -+ p->master = master; - port->slave = slave_dev; - - netif_carrier_off(slave_dev); --- -2.19.1 - diff --git a/root/target/linux/mediatek/patches-4.19/0022-net-dsa-add-support-for-GMAC2-wired-to-ext.patch b/root/target/linux/mediatek/patches-4.19/0022-net-dsa-add-support-for-GMAC2-wired-to-ext.patch deleted file mode 100644 index ade0497f..00000000 --- a/root/target/linux/mediatek/patches-4.19/0022-net-dsa-add-support-for-GMAC2-wired-to-ext.patch +++ /dev/null @@ -1,34 +0,0 @@ -From a80c992c93729c817267ea5575faa089a278e593 Mon Sep 17 00:00:00 2001 -From: Frank Wunderlich -Date: Sat, 8 Dec 2018 19:22:22 +0100 -Subject: [PATCH 22/77] net: dsa: add support for GMAC2 wired to ext - -cpu-ports of mt7530 need some special flags to be set - -based on -https://github.com/openwrt/openwrt/blob/master/target/linux/mediatek/patches-4.14/0032-net-dsa-mediatek-add-support-for-GMAC2-wired-to-ext-.patch - -Signed-off-by: Frank Wunderlich ---- - drivers/net/dsa/mt7530.c | 5 +++++ - 1 file changed, 5 insertions(+) - -diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c -index 62e486652e62..8ed0af6abe7d 100644 ---- a/drivers/net/dsa/mt7530.c -+++ b/drivers/net/dsa/mt7530.c -@@ -1281,6 +1281,11 @@ mt7530_setup(struct dsa_switch *ds) - val = mt7530_read(priv, MT7530_MHWTRAP); - val &= ~MHWTRAP_P6_DIS & ~MHWTRAP_PHY_ACCESS; - val |= MHWTRAP_MANUAL; -+ if (!dsa_is_cpu_port(ds, 5)) { -+ val |= MHWTRAP_P5_DIS; -+ val |= MHWTRAP_P5_MAC_SEL; -+ val |= MHWTRAP_P5_RGMII_MODE; -+ } - mt7530_write(priv, MT7530_MHWTRAP, val); - - /* Enable and reset MIB counters */ --- -2.19.1 - diff --git a/root/target/linux/mediatek/patches-4.19/0023-net-dsa-dsa-multi-cpu-mt7530.c.patch b/root/target/linux/mediatek/patches-4.19/0023-net-dsa-dsa-multi-cpu-mt7530.c.patch deleted file mode 100644 index 5a08b31e..00000000 --- a/root/target/linux/mediatek/patches-4.19/0023-net-dsa-dsa-multi-cpu-mt7530.c.patch +++ /dev/null @@ -1,121 +0,0 @@ -From 954b359077f770bdbb376db571a4710965684dc9 Mon Sep 17 00:00:00 2001 -From: Frank Wunderlich -Date: Sat, 8 Dec 2018 19:25:57 +0100 -Subject: [PATCH 23/77] net: dsa: dsa multi cpu (mt7530.c) - -implementing changes to mt7530 switch driver for supporting multiple (2) -cpu-ports - -based on -https://github.com/openwrt/openwrt/blob/master/target/linux/mediatek/patches-4.14/0033-dsa-multi-cpu.patch - -Signed-off-by: Frank Wunderlich ---- - drivers/net/dsa/mt7530.c | 34 +++++++++++++++++++--------------- - 1 file changed, 19 insertions(+), 15 deletions(-) - -diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c -index 8ed0af6abe7d..fda1b67dfeac 100644 ---- a/drivers/net/dsa/mt7530.c -+++ b/drivers/net/dsa/mt7530.c -@@ -678,6 +678,9 @@ static int - mt7530_cpu_port_enable(struct mt7530_priv *priv, - int port) - { -+ u8 port_mask = 0; -+ int i; -+ - /* Enable Mediatek header mode on the cpu port */ - mt7530_write(priv, MT7530_PVC_P(port), - PORT_SPEC_TAG); -@@ -694,8 +697,14 @@ mt7530_cpu_port_enable(struct mt7530_priv *priv, - /* CPU port gets connected to all user ports of - * the switch - */ -+ -+ for (i = 0; i < MT7530_NUM_PORTS; i++) -+ if ((priv->ds->ports[port].type == DSA_PORT_TYPE_USER) && -+ (dsa_port_upstream_port(priv->ds, i) == port)) -+ port_mask |= BIT(i); -+ - mt7530_write(priv, MT7530_PCR_P(port), -- PCR_MATRIX(dsa_user_ports(priv->ds))); -+ PCR_MATRIX(port_mask)); - - return 0; - } -@@ -705,6 +714,7 @@ mt7530_port_enable(struct dsa_switch *ds, int port, - struct phy_device *phy) - { - struct mt7530_priv *priv = ds->priv; -+ u8 upstream = dsa_port_upstream_port(ds, port); - - mutex_lock(&priv->reg_mutex); - -@@ -715,7 +725,7 @@ mt7530_port_enable(struct dsa_switch *ds, int port, - * restore the port matrix if the port is the member of a certain - * bridge. - */ -- priv->ports[port].pm |= PCR_MATRIX(BIT(MT7530_CPU_PORT)); -+ priv->ports[port].pm |= PCR_MATRIX(BIT(upstream)); - priv->ports[port].enable = true; - mt7530_rmw(priv, MT7530_PCR_P(port), PCR_MATRIX_MASK, - priv->ports[port].pm); -@@ -778,7 +788,8 @@ mt7530_port_bridge_join(struct dsa_switch *ds, int port, - struct net_device *bridge) - { - struct mt7530_priv *priv = ds->priv; -- u32 port_bitmap = BIT(MT7530_CPU_PORT); -+ u8 upstream = dsa_port_upstream_port(ds, port); -+ u32 port_bitmap = BIT(upstream); - int i; - - mutex_lock(&priv->reg_mutex); -@@ -879,6 +890,7 @@ mt7530_port_bridge_leave(struct dsa_switch *ds, int port, - struct net_device *bridge) - { - struct mt7530_priv *priv = ds->priv; -+ u8 upstream = dsa_port_upstream_port(ds, port); - int i; - - mutex_lock(&priv->reg_mutex); -@@ -906,8 +918,8 @@ mt7530_port_bridge_leave(struct dsa_switch *ds, int port, - */ - if (priv->ports[port].enable) - mt7530_rmw(priv, MT7530_PCR_P(port), PCR_MATRIX_MASK, -- PCR_MATRIX(BIT(MT7530_CPU_PORT))); -- priv->ports[port].pm = PCR_MATRIX(BIT(MT7530_CPU_PORT)); -+ PCR_MATRIX(BIT(upstream))); -+ priv->ports[port].pm = PCR_MATRIX(BIT(upstream)); - - mt7530_port_set_vlan_unaware(ds, port); - -@@ -1198,15 +1210,7 @@ mt7530_port_vlan_del(struct dsa_switch *ds, int port, - static enum dsa_tag_protocol - mtk_get_tag_protocol(struct dsa_switch *ds, int port) - { -- struct mt7530_priv *priv = ds->priv; -- -- if (port != MT7530_CPU_PORT) { -- dev_warn(priv->dev, -- "port not matched with tagging CPU port\n"); -- return DSA_TAG_PROTO_NONE; -- } else { -- return DSA_TAG_PROTO_MTK; -- } -+ return DSA_TAG_PROTO_MTK; - } - - static int -@@ -1279,7 +1283,7 @@ mt7530_setup(struct dsa_switch *ds) - - /* Enable Port 6 only; P5 as GMAC5 which currently is not supported */ - val = mt7530_read(priv, MT7530_MHWTRAP); -- val &= ~MHWTRAP_P6_DIS & ~MHWTRAP_PHY_ACCESS; -+ val &= ~MHWTRAP_P5_DIS & ~MHWTRAP_P6_DIS & ~MHWTRAP_PHY_ACCESS; - val |= MHWTRAP_MANUAL; - if (!dsa_is_cpu_port(ds, 5)) { - val |= MHWTRAP_P5_DIS; --- -2.19.1 - diff --git a/root/target/linux/mediatek/patches-4.19/0024-net-dsa-tell-GDMA-when-we-are-turning-on-the-special.patch b/root/target/linux/mediatek/patches-4.19/0024-net-dsa-tell-GDMA-when-we-are-turning-on-the-special.patch deleted file mode 100644 index 00e6a555..00000000 --- a/root/target/linux/mediatek/patches-4.19/0024-net-dsa-tell-GDMA-when-we-are-turning-on-the-special.patch +++ /dev/null @@ -1,54 +0,0 @@ -From 943ed2bae585cd595d8264a1f37fa3f3d5a5715b Mon Sep 17 00:00:00 2001 -From: Frank Wunderlich -Date: Sat, 8 Dec 2018 20:59:09 +0100 -Subject: [PATCH 24/77] net: dsa: tell GDMA when we are turning on the special - tag - -Enabling this bit will make the RX DMA descriptor enable the SP bit for -all ingress traffic inside the return descriptor. The PPE needs this to -know that a SP is present. - -based on -https://github.com/openwrt/openwrt/blob/master/target/linux/mediatek/patches-4.14/0044-net-next-dsa-mediatek-tell-GDMA-when-we-are-turning-.patch - -Signed-off-by: Frank Wunderlich ---- - drivers/net/dsa/mt7530.c | 6 ++++++ - drivers/net/dsa/mt7530.h | 4 ++++ - 2 files changed, 10 insertions(+) - -diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c -index fda1b67dfeac..9690a9b59fce 100644 ---- a/drivers/net/dsa/mt7530.c -+++ b/drivers/net/dsa/mt7530.c -@@ -685,6 +685,12 @@ mt7530_cpu_port_enable(struct mt7530_priv *priv, - mt7530_write(priv, MT7530_PVC_P(port), - PORT_SPEC_TAG); - -+ /* Enable Mediatek header mode on the GMAC that the cpu port -+ * connects to -+ */ -+ regmap_write_bits(priv->ethernet, MTK_GDMA_FWD_CFG(port), -+ GDMA_SPEC_TAG, GDMA_SPEC_TAG); -+ - /* Setup the MAC by default for the cpu port */ - mt7530_write(priv, MT7530_PMCR_P(port), PMCR_CPUP_LINK); - -diff --git a/drivers/net/dsa/mt7530.h b/drivers/net/dsa/mt7530.h -index d9b407a22a58..310f2536175b 100644 ---- a/drivers/net/dsa/mt7530.h -+++ b/drivers/net/dsa/mt7530.h -@@ -23,6 +23,10 @@ - - #define TRGMII_BASE(x) (0x10000 + (x)) - -+/* Registers for GDMA configuration access */ -+#define MTK_GDMA_FWD_CFG(x) (0x500 + (x * 0x1000)) -+#define GDMA_SPEC_TAG BIT(24) -+ - /* Registers to ethsys access */ - #define ETHSYS_CLKCFG0 0x2c - #define ETHSYS_TRGMII_CLK_SEL362_5 BIT(11) --- -2.19.1 - diff --git a/root/target/linux/mediatek/patches-4.19/0025-net-dsa-mt7530-add-linking-to-mdio.patch b/root/target/linux/mediatek/patches-4.19/0025-net-dsa-mt7530-add-linking-to-mdio.patch deleted file mode 100644 index 117dd7b5..00000000 --- a/root/target/linux/mediatek/patches-4.19/0025-net-dsa-mt7530-add-linking-to-mdio.patch +++ /dev/null @@ -1,47 +0,0 @@ -From 0f5ff06adcb20916acaf55976975a8b8844e785a Mon Sep 17 00:00:00 2001 -From: Frank Wunderlich -Date: Sat, 8 Dec 2018 20:59:40 +0100 -Subject: [PATCH 25/77] net: dsa: mt7530 add linking to mdio - -switch (7530) needs to to be linked to mdio-bus - -based on -https://github.com/openwrt/openwrt/blob/master/target/linux/mediatek/patches-4.14/0045-net-dsa-mediatek-turn-into-platform-driver.patch - -Signed-off-by: Frank Wunderlich ---- - drivers/net/dsa/mt7530.c | 10 ++++++++-- - 1 file changed, 8 insertions(+), 2 deletions(-) - -diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c -index 9690a9b59fce..8f95e22a33f6 100644 ---- a/drivers/net/dsa/mt7530.c -+++ b/drivers/net/dsa/mt7530.c -@@ -1349,7 +1349,7 @@ static int - mt7530_probe(struct mdio_device *mdiodev) - { - struct mt7530_priv *priv; -- struct device_node *dn; -+ struct device_node *dn, *mdio; - - dn = mdiodev->dev.of_node; - -@@ -1396,8 +1396,14 @@ mt7530_probe(struct mdio_device *mdiodev) - return PTR_ERR(priv->reset); - } - } -+ mdio = of_get_parent(dn); -+ if (!mdio) -+ return -EINVAL; -+ -+ priv->bus = of_mdio_find_bus(mdio); -+ if (!priv->bus) -+ return -EPROBE_DEFER; - -- priv->bus = mdiodev->bus; - priv->dev = &mdiodev->dev; - priv->ds->priv = priv; - priv->ds->ops = &mt7530_switch_ops; --- -2.19.1 - diff --git a/root/target/linux/mediatek/patches-4.19/0026-net-dsa-changes-to-dts.patch b/root/target/linux/mediatek/patches-4.19/0026-net-dsa-changes-to-dts.patch deleted file mode 100644 index e3d37c86..00000000 --- a/root/target/linux/mediatek/patches-4.19/0026-net-dsa-changes-to-dts.patch +++ /dev/null @@ -1,81 +0,0 @@ -From 52365639697e10f1b641d25460c10d9ccc56a6d6 Mon Sep 17 00:00:00 2001 -From: Frank Wunderlich -Date: Thu, 29 Nov 2018 10:53:44 +0100 -Subject: [PATCH 26/77] net: dsa: changes to dts - ---- - arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts | 29 ++++++++++++++++++- - 1 file changed, 28 insertions(+), 1 deletion(-) - -diff --git a/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts b/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts -index a47022765326..4c6e53d9e736 100644 ---- a/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts -+++ b/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts -@@ -157,6 +157,18 @@ - }; - }; - -+ gmac1: mac@1 { -+ compatible = "mediatek,eth-mac"; -+ reg = <1>; -+ phy-mode = "trgmii"; -+ -+ fixed-link { -+ speed = <1000>; -+ full-duplex; -+ pause; -+ }; -+ }; -+ - mdio: mdio-bus { - #address-cells = <1>; - #size-cells = <0>; -@@ -175,29 +187,44 @@ - port@0 { - reg = <0>; - label = "wan"; -+ default_cpu = <&cpu_port1>; - }; - - port@1 { - reg = <1>; - label = "lan0"; -+ default_cpu = <&cpu_port0>; - }; - - port@2 { - reg = <2>; - label = "lan1"; -+ default_cpu = <&cpu_port0>; - }; - - port@3 { - reg = <3>; - label = "lan2"; -+ default_cpu = <&cpu_port0>; - }; - - port@4 { - reg = <4>; - label = "lan3"; -+ default_cpu = <&cpu_port0>; - }; - -- port@6 { -+ cpu_port1: port@5 { -+ reg = <5>; -+ label = "cpu"; -+ ethernet = <&gmac1>; -+ phy-mode = "trgmii"; -+ fixed-link { -+ speed = <1000>; -+ full-duplex; -+ }; -+ }; -+ cpu_port0: port@6 { - reg = <6>; - label = "cpu"; - ethernet = <&gmac0>; --- -2.19.1 - diff --git a/root/target/linux/mediatek/patches-4.19/0027-drm-mediatek-add-refcount-for-DPI-power-on-off.patch b/root/target/linux/mediatek/patches-4.19/0027-drm-mediatek-add-refcount-for-DPI-power-on-off.patch deleted file mode 100644 index 375741bc..00000000 --- a/root/target/linux/mediatek/patches-4.19/0027-drm-mediatek-add-refcount-for-DPI-power-on-off.patch +++ /dev/null @@ -1,171 +0,0 @@ -From 49f64db56f05dc7ccb1d8836c19243b5620fc93d Mon Sep 17 00:00:00 2001 -From: chunhui dai -Date: Wed, 3 Oct 2018 11:41:41 +0800 -Subject: [PATCH 27/77] drm/mediatek: add refcount for DPI power on/off - -After the kernel 4.4, the DRM disable flow was changed, if DPI was -disableed before CRTC, it will cause warning message as following: - -------------[ cut here ]------------ -WARNING: CPU: 0 PID: 1339 at ../../linux/linux-4.4.24-mtk/drivers/gpu/drm/drm_irq.c:1326 drm_wait_one_vblank+0x188/0x18c() -vblank wait timed out on crtc 0 -Modules linked in: bridge mt8521p_ir_shim(O) i2c_eeprom(O) mtk_m4(O) fuse_ctrl(O) virtual_block(O) caamkeys(PO) chk(PO) amperctl(O) ledctl(O) apple_auth(PO) micctl(O) sensors(PO) lla(O) sdd(PO) ice40_fpga(O) psmon(O) event_queue(PO) utils(O) blackbox(O) -CPU: 0 PID: 1339 Comm: kworker/0:1 Tainted: P W O 4.4.24 #1 -Hardware name: Mediatek Cortex-A7 (Device Tree) -Workqueue: events drm_mode_rmfb_work_fn -[] (unwind_backtrace) from [] (show_stack+0x20/0x24) -[] (show_stack) from [] (dump_stack+0x98/0xac) -[] (dump_stack) from [] (warn_slowpath_common+0x94/0xc4) -[] (warn_slowpath_common) from [] (warn_slowpath_fmt+0x40/0x48) -[] (warn_slowpath_fmt) from [] (drm_wait_one_vblank+0x188/0x18c) -[] (drm_wait_one_vblank) from [] (drm_crtc_wait_one_vblank+0x28/0x2c) -[] (drm_crtc_wait_one_vblank) from [] (mtk_drm_crtc_disable+0x78/0x240) -[] (mtk_drm_crtc_disable) from [] (drm_atomic_helper_commit_modeset_disables+0x128/0x3b8) -[] (drm_atomic_helper_commit_modeset_disables) from [] (mtk_atomic_complete+0x74/0xb4) -[] (mtk_atomic_complete) from [] (mtk_atomic_commit+0x68/0x98) -[] (mtk_atomic_commit) from [] (drm_atomic_commit+0x54/0x74) -[] (drm_atomic_commit) from [] (drm_atomic_helper_set_config+0x7c/0xa0) -[] (drm_atomic_helper_set_config) from [] (drm_mode_set_config_internal+0x68/0xe4) -[] (drm_mode_set_config_internal) from [] (drm_framebuffer_remove+0xe4/0x120) -[] (drm_framebuffer_remove) from [] (drm_mode_rmfb_work_fn+0x48/0x58) -[] (drm_mode_rmfb_work_fn) from [] (process_one_work+0x154/0x50c) -[] (process_one_work) from [] (worker_thread+0x284/0x568) -[] (worker_thread) from [] (kthread+0xec/0x104) -[] (kthread) from [] (ret_from_fork+0x14/0x3c) ----[ end trace 12ae5358e992abd5 ]--- - -so, we add refcount for DPI power on/off to protect the flow. - -Signed-off-by: Bibby Hsieh -Signed-off-by: chunhui dai -Reviewed-by: CK Hu ---- - drivers/gpu/drm/mediatek/mtk_dpi.c | 43 +++++++++--------------------- - 1 file changed, 13 insertions(+), 30 deletions(-) - -diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c -index 6c0ea39d5739..5ede1ddbaa1a 100644 ---- a/drivers/gpu/drm/mediatek/mtk_dpi.c -+++ b/drivers/gpu/drm/mediatek/mtk_dpi.c -@@ -76,8 +76,7 @@ struct mtk_dpi { - enum mtk_dpi_out_yc_map yc_map; - enum mtk_dpi_out_bit_num bit_num; - enum mtk_dpi_out_channel_swap channel_swap; -- bool power_sta; -- u8 power_ctl; -+ int refcount; - }; - - static inline struct mtk_dpi *mtk_dpi_from_encoder(struct drm_encoder *e) -@@ -90,11 +89,6 @@ enum mtk_dpi_polarity { - MTK_DPI_POLARITY_FALLING, - }; - --enum mtk_dpi_power_ctl { -- DPI_POWER_START = BIT(0), -- DPI_POWER_ENABLE = BIT(1), --}; -- - struct mtk_dpi_polarities { - enum mtk_dpi_polarity de_pol; - enum mtk_dpi_polarity ck_pol; -@@ -367,40 +361,30 @@ static void mtk_dpi_config_color_format(struct mtk_dpi *dpi, - } - } - --static void mtk_dpi_power_off(struct mtk_dpi *dpi, enum mtk_dpi_power_ctl pctl) -+static void mtk_dpi_power_off(struct mtk_dpi *dpi) - { -- dpi->power_ctl &= ~pctl; -- -- if ((dpi->power_ctl & DPI_POWER_START) || -- (dpi->power_ctl & DPI_POWER_ENABLE)) -+ if (WARN_ON(dpi->refcount == 0)) - return; - -- if (!dpi->power_sta) -+ if (--dpi->refcount != 0) - return; - - mtk_dpi_disable(dpi); - clk_disable_unprepare(dpi->pixel_clk); - clk_disable_unprepare(dpi->engine_clk); -- dpi->power_sta = false; - } - --static int mtk_dpi_power_on(struct mtk_dpi *dpi, enum mtk_dpi_power_ctl pctl) -+static int mtk_dpi_power_on(struct mtk_dpi *dpi) - { - int ret; - -- dpi->power_ctl |= pctl; -- -- if (!(dpi->power_ctl & DPI_POWER_START) && -- !(dpi->power_ctl & DPI_POWER_ENABLE)) -- return 0; -- -- if (dpi->power_sta) -+ if (++dpi->refcount != 1) - return 0; - - ret = clk_prepare_enable(dpi->engine_clk); - if (ret) { - dev_err(dpi->dev, "Failed to enable engine clock: %d\n", ret); -- goto err_eng; -+ goto err_refcount; - } - - ret = clk_prepare_enable(dpi->pixel_clk); -@@ -410,13 +394,12 @@ static int mtk_dpi_power_on(struct mtk_dpi *dpi, enum mtk_dpi_power_ctl pctl) - } - - mtk_dpi_enable(dpi); -- dpi->power_sta = true; - return 0; - - err_pixel: - clk_disable_unprepare(dpi->engine_clk); --err_eng: -- dpi->power_ctl &= ~pctl; -+err_refcount: -+ dpi->refcount--; - return ret; - } - -@@ -552,14 +535,14 @@ static void mtk_dpi_encoder_disable(struct drm_encoder *encoder) - { - struct mtk_dpi *dpi = mtk_dpi_from_encoder(encoder); - -- mtk_dpi_power_off(dpi, DPI_POWER_ENABLE); -+ mtk_dpi_power_off(dpi); - } - - static void mtk_dpi_encoder_enable(struct drm_encoder *encoder) - { - struct mtk_dpi *dpi = mtk_dpi_from_encoder(encoder); - -- mtk_dpi_power_on(dpi, DPI_POWER_ENABLE); -+ mtk_dpi_power_on(dpi); - mtk_dpi_set_display_mode(dpi, &dpi->mode); - } - -@@ -582,14 +565,14 @@ static void mtk_dpi_start(struct mtk_ddp_comp *comp) - { - struct mtk_dpi *dpi = container_of(comp, struct mtk_dpi, ddp_comp); - -- mtk_dpi_power_on(dpi, DPI_POWER_START); -+ mtk_dpi_power_on(dpi); - } - - static void mtk_dpi_stop(struct mtk_ddp_comp *comp) - { - struct mtk_dpi *dpi = container_of(comp, struct mtk_dpi, ddp_comp); - -- mtk_dpi_power_off(dpi, DPI_POWER_START); -+ mtk_dpi_power_off(dpi); - } - - static const struct mtk_ddp_comp_funcs mtk_dpi_funcs = { --- -2.19.1 - diff --git a/root/target/linux/mediatek/patches-4.19/0028-drm-mediatek-move-hardware-register-to-node-data.patch b/root/target/linux/mediatek/patches-4.19/0028-drm-mediatek-move-hardware-register-to-node-data.patch deleted file mode 100644 index fc67fb41..00000000 --- a/root/target/linux/mediatek/patches-4.19/0028-drm-mediatek-move-hardware-register-to-node-data.patch +++ /dev/null @@ -1,101 +0,0 @@ -From c2b3363773bfc93b3e4082ccfa99cda18ea980be Mon Sep 17 00:00:00 2001 -From: chunhui dai -Date: Wed, 3 Oct 2018 11:41:42 +0800 -Subject: [PATCH 28/77] drm/mediatek: move hardware register to node data - -The address of register DPI_H_FRE_CON is different in different IC. -Using of_node data to find this address. - -Reviewed-by: CK Hu -Signed-off-by: chunhui dai ---- - drivers/gpu/drm/mediatek/mtk_dpi.c | 19 ++++++++++++++++--- - drivers/gpu/drm/mediatek/mtk_dpi_regs.h | 1 - - 2 files changed, 16 insertions(+), 4 deletions(-) - -diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c -index 5ede1ddbaa1a..72aa43187731 100644 ---- a/drivers/gpu/drm/mediatek/mtk_dpi.c -+++ b/drivers/gpu/drm/mediatek/mtk_dpi.c -@@ -18,6 +18,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -72,6 +73,7 @@ struct mtk_dpi { - struct clk *tvd_clk; - int irq; - struct drm_display_mode mode; -+ const struct mtk_dpi_conf *conf; - enum mtk_dpi_out_color_format color_format; - enum mtk_dpi_out_yc_map yc_map; - enum mtk_dpi_out_bit_num bit_num; -@@ -110,6 +112,10 @@ struct mtk_dpi_yc_limit { - u16 c_bottom; - }; - -+struct mtk_dpi_conf { -+ u32 reg_h_fre_con; -+}; -+ - static void mtk_dpi_mask(struct mtk_dpi *dpi, u32 offset, u32 val, u32 mask) - { - u32 tmp = readl(dpi->regs + offset) & ~mask; -@@ -335,7 +341,7 @@ static void mtk_dpi_config_swap_input(struct mtk_dpi *dpi, bool enable) - - static void mtk_dpi_config_2n_h_fre(struct mtk_dpi *dpi) - { -- mtk_dpi_mask(dpi, DPI_H_FRE_CON, H_FRE_2N, H_FRE_2N); -+ mtk_dpi_mask(dpi, dpi->conf->reg_h_fre_con, H_FRE_2N, H_FRE_2N); - } - - static void mtk_dpi_config_color_format(struct mtk_dpi *dpi, -@@ -639,6 +645,10 @@ static const struct component_ops mtk_dpi_component_ops = { - .unbind = mtk_dpi_unbind, - }; - -+static const struct mtk_dpi_conf mt8173_conf = { -+ .reg_h_fre_con = 0xe0, -+}; -+ - static int mtk_dpi_probe(struct platform_device *pdev) - { - struct device *dev = &pdev->dev; -@@ -653,6 +663,7 @@ static int mtk_dpi_probe(struct platform_device *pdev) - return -ENOMEM; - - dpi->dev = dev; -+ dpi->conf = (struct mtk_dpi_conf *)of_device_get_match_data(dev); - - mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); - dpi->regs = devm_ioremap_resource(dev, mem); -@@ -732,8 +743,10 @@ static int mtk_dpi_remove(struct platform_device *pdev) - } - - static const struct of_device_id mtk_dpi_of_ids[] = { -- { .compatible = "mediatek,mt8173-dpi", }, -- {} -+ { .compatible = "mediatek,mt8173-dpi", -+ .data = &mt8173_conf, -+ }, -+ { }, - }; - - struct platform_driver mtk_dpi_driver = { -diff --git a/drivers/gpu/drm/mediatek/mtk_dpi_regs.h b/drivers/gpu/drm/mediatek/mtk_dpi_regs.h -index 4b6ad4751a31..040444d7718d 100644 ---- a/drivers/gpu/drm/mediatek/mtk_dpi_regs.h -+++ b/drivers/gpu/drm/mediatek/mtk_dpi_regs.h -@@ -223,6 +223,5 @@ - #define ESAV_CODE2 (0xFFF << 0) - #define ESAV_CODE3_MSB BIT(16) - --#define DPI_H_FRE_CON 0xE0 - #define H_FRE_2N BIT(25) - #endif /* __MTK_DPI_REGS_H */ --- -2.19.1 - diff --git a/root/target/linux/mediatek/patches-4.19/0029-drm-mediatek-adjust-EDGE-to-match-clock-and-data.patch b/root/target/linux/mediatek/patches-4.19/0029-drm-mediatek-adjust-EDGE-to-match-clock-and-data.patch deleted file mode 100644 index 71118456..00000000 --- a/root/target/linux/mediatek/patches-4.19/0029-drm-mediatek-adjust-EDGE-to-match-clock-and-data.patch +++ /dev/null @@ -1,62 +0,0 @@ -From d0b9bb15fad38e8328f9436501e36697e4e1a89d Mon Sep 17 00:00:00 2001 -From: chunhui dai -Date: Wed, 3 Oct 2018 11:41:43 +0800 -Subject: [PATCH 29/77] drm/mediatek: adjust EDGE to match clock and data - -The default timing of DPI data and clock is not match. -We could adjust this bit to make them match. - -Signed-off-by: chunhui dai -Reviewed-by: CK Hu ---- - drivers/gpu/drm/mediatek/mtk_dpi.c | 8 ++++++++ - drivers/gpu/drm/mediatek/mtk_dpi_regs.h | 1 + - 2 files changed, 9 insertions(+) - -diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c -index 72aa43187731..0ce4b61efaeb 100644 ---- a/drivers/gpu/drm/mediatek/mtk_dpi.c -+++ b/drivers/gpu/drm/mediatek/mtk_dpi.c -@@ -114,6 +114,7 @@ struct mtk_dpi_yc_limit { - - struct mtk_dpi_conf { - u32 reg_h_fre_con; -+ bool edge_sel_en; - }; - - static void mtk_dpi_mask(struct mtk_dpi *dpi, u32 offset, u32 val, u32 mask) -@@ -344,6 +345,12 @@ static void mtk_dpi_config_2n_h_fre(struct mtk_dpi *dpi) - mtk_dpi_mask(dpi, dpi->conf->reg_h_fre_con, H_FRE_2N, H_FRE_2N); - } - -+static void mtk_dpi_config_disable_edge(struct mtk_dpi *dpi) -+{ -+ if (dpi->conf->edge_sel_en) -+ mtk_dpi_mask(dpi, dpi->conf->reg_h_fre_con, 0, EDGE_SEL_EN); -+} -+ - static void mtk_dpi_config_color_format(struct mtk_dpi *dpi, - enum mtk_dpi_out_color_format format) - { -@@ -507,6 +514,7 @@ static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi, - mtk_dpi_config_yc_map(dpi, dpi->yc_map); - mtk_dpi_config_color_format(dpi, dpi->color_format); - mtk_dpi_config_2n_h_fre(dpi); -+ mtk_dpi_config_disable_edge(dpi); - mtk_dpi_sw_reset(dpi, false); - - return 0; -diff --git a/drivers/gpu/drm/mediatek/mtk_dpi_regs.h b/drivers/gpu/drm/mediatek/mtk_dpi_regs.h -index 040444d7718d..d9db8c4cacd7 100644 ---- a/drivers/gpu/drm/mediatek/mtk_dpi_regs.h -+++ b/drivers/gpu/drm/mediatek/mtk_dpi_regs.h -@@ -223,5 +223,6 @@ - #define ESAV_CODE2 (0xFFF << 0) - #define ESAV_CODE3_MSB BIT(16) - -+#define EDGE_SEL_EN BIT(5) - #define H_FRE_2N BIT(25) - #endif /* __MTK_DPI_REGS_H */ --- -2.19.1 - diff --git a/root/target/linux/mediatek/patches-4.19/0030-drm-mediatek-add-clock-factor-for-different-IC.patch b/root/target/linux/mediatek/patches-4.19/0030-drm-mediatek-add-clock-factor-for-different-IC.patch deleted file mode 100644 index 8977fbe6..00000000 --- a/root/target/linux/mediatek/patches-4.19/0030-drm-mediatek-add-clock-factor-for-different-IC.patch +++ /dev/null @@ -1,68 +0,0 @@ -From 0a8f36a231341ac5d66c186bcb1600a5abc00132 Mon Sep 17 00:00:00 2001 -From: chunhui dai -Date: Wed, 3 Oct 2018 11:41:44 +0800 -Subject: [PATCH 30/77] drm/mediatek: add clock factor for different IC - -different IC has different clock designed in HDMI, the factor for -calculate clock should be different. Usinng the data in of_node -to find this factor. - -Reviewed-by: CK Hu -Signed-off-by: chunhui dai ---- - drivers/gpu/drm/mediatek/mtk_dpi.c | 24 +++++++++++++++--------- - 1 file changed, 15 insertions(+), 9 deletions(-) - -diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c -index 0ce4b61efaeb..0dbe9345fa2e 100644 ---- a/drivers/gpu/drm/mediatek/mtk_dpi.c -+++ b/drivers/gpu/drm/mediatek/mtk_dpi.c -@@ -113,6 +113,7 @@ struct mtk_dpi_yc_limit { - }; - - struct mtk_dpi_conf { -+ unsigned int (*cal_factor)(int clock); - u32 reg_h_fre_con; - bool edge_sel_en; - }; -@@ -431,15 +432,7 @@ static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi, - unsigned int factor; - - /* let pll_rate can fix the valid range of tvdpll (1G~2GHz) */ -- -- if (mode->clock <= 27000) -- factor = 3 << 4; -- else if (mode->clock <= 84000) -- factor = 3 << 3; -- else if (mode->clock <= 167000) -- factor = 3 << 2; -- else -- factor = 3 << 1; -+ factor = dpi->conf->cal_factor(mode->clock); - drm_display_mode_to_videomode(mode, &vm); - pll_rate = vm.pixelclock * factor; - -@@ -653,7 +646,20 @@ static const struct component_ops mtk_dpi_component_ops = { - .unbind = mtk_dpi_unbind, - }; - -+static unsigned int mt8173_calculate_factor(int clock) -+{ -+ if (clock <= 27000) -+ return 3 << 4; -+ else if (clock <= 84000) -+ return 3 << 3; -+ else if (clock <= 167000) -+ return 3 << 2; -+ else -+ return 3 << 1; -+} -+ - static const struct mtk_dpi_conf mt8173_conf = { -+ .cal_factor = mt8173_calculate_factor, - .reg_h_fre_con = 0xe0, - }; - --- -2.19.1 - diff --git a/root/target/linux/mediatek/patches-4.19/0031-drm-mediatek-convert-dpi-driver-to-use-drm_of_find_p.patch b/root/target/linux/mediatek/patches-4.19/0031-drm-mediatek-convert-dpi-driver-to-use-drm_of_find_p.patch deleted file mode 100644 index 25bd3912..00000000 --- a/root/target/linux/mediatek/patches-4.19/0031-drm-mediatek-convert-dpi-driver-to-use-drm_of_find_p.patch +++ /dev/null @@ -1,66 +0,0 @@ -From ef9b74fc6412b2402f882b012f78bfb3031aa4c6 Mon Sep 17 00:00:00 2001 -From: chunhui dai -Date: Wed, 3 Oct 2018 11:41:45 +0800 -Subject: [PATCH 31/77] drm/mediatek: convert dpi driver to use - drm_of_find_panel_or_bridge - -Convert dpi driver to use drm_of_find_panel_or_bridge. -This changes some error messages to debug messages (in the graph core). -Graph connections are often "no connects" depending on the particular -board, so we want to avoid spurious messages. Plus the kernel is not a -DT validator. -related links: -[1] https://lkml.org/lkml/2017/2/3/716 -[2] https://lkml.org/lkml/2017/2/3/719 - -Signed-off-by: chunhui dai -Reviewed-by: CK Hu ---- - drivers/gpu/drm/mediatek/mtk_dpi.c | 16 ++++++---------- - 1 file changed, 6 insertions(+), 10 deletions(-) - -diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c -index 0dbe9345fa2e..08915e1765f8 100644 ---- a/drivers/gpu/drm/mediatek/mtk_dpi.c -+++ b/drivers/gpu/drm/mediatek/mtk_dpi.c -@@ -14,6 +14,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -668,7 +669,6 @@ static int mtk_dpi_probe(struct platform_device *pdev) - struct device *dev = &pdev->dev; - struct mtk_dpi *dpi; - struct resource *mem; -- struct device_node *bridge_node; - int comp_id; - int ret; - -@@ -714,16 +714,12 @@ static int mtk_dpi_probe(struct platform_device *pdev) - return -EINVAL; - } - -- bridge_node = of_graph_get_remote_node(dev->of_node, 0, 0); -- if (!bridge_node) -- return -ENODEV; -- -- dev_info(dev, "Found bridge node: %pOF\n", bridge_node); -+ ret = drm_of_find_panel_or_bridge(dev->of_node, 0, 0, -+ NULL, &dpi->bridge); -+ if (ret) -+ return ret; - -- dpi->bridge = of_drm_find_bridge(bridge_node); -- of_node_put(bridge_node); -- if (!dpi->bridge) -- return -EPROBE_DEFER; -+ dev_info(dev, "Found bridge node: %pOF\n", dpi->bridge->of_node); - - comp_id = mtk_ddp_comp_get_id(dev->of_node, MTK_DPI); - if (comp_id < 0) { --- -2.19.1 - diff --git a/root/target/linux/mediatek/patches-4.19/0032-drm-mediatek-add-dpi-driver-for-mt2701-and-mt7623.patch b/root/target/linux/mediatek/patches-4.19/0032-drm-mediatek-add-dpi-driver-for-mt2701-and-mt7623.patch deleted file mode 100644 index 2aa37a7d..00000000 --- a/root/target/linux/mediatek/patches-4.19/0032-drm-mediatek-add-dpi-driver-for-mt2701-and-mt7623.patch +++ /dev/null @@ -1,76 +0,0 @@ -From 5750b7268c5412e18a476482f92425eb0228564b Mon Sep 17 00:00:00 2001 -From: chunhui dai -Date: Wed, 3 Oct 2018 11:41:46 +0800 -Subject: [PATCH 32/77] drm/mediatek: add dpi driver for mt2701 and mt7623 - -This patch adds dpi dirver suppot for both mt2701 and mt7623. -And also support other (existing or future) chips that use -the same binding and driver. - -Reviewed-by: CK Hu -Signed-off-by: chunhui dai ---- - drivers/gpu/drm/mediatek/mtk_dpi.c | 21 +++++++++++++++++++++ - drivers/gpu/drm/mediatek/mtk_drm_drv.c | 2 ++ - 2 files changed, 23 insertions(+) - -diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c -index 08915e1765f8..62a9d47df948 100644 ---- a/drivers/gpu/drm/mediatek/mtk_dpi.c -+++ b/drivers/gpu/drm/mediatek/mtk_dpi.c -@@ -659,11 +659,29 @@ static unsigned int mt8173_calculate_factor(int clock) - return 3 << 1; - } - -+static unsigned int mt2701_calculate_factor(int clock) -+{ -+ if (clock <= 64000) -+ return 16; -+ else if (clock <= 128000) -+ return 8; -+ else if (clock <= 256000) -+ return 4; -+ else -+ return 2; -+} -+ - static const struct mtk_dpi_conf mt8173_conf = { - .cal_factor = mt8173_calculate_factor, - .reg_h_fre_con = 0xe0, - }; - -+static const struct mtk_dpi_conf mt2701_conf = { -+ .cal_factor = mt2701_calculate_factor, -+ .reg_h_fre_con = 0xb0, -+ .edge_sel_en = true, -+}; -+ - static int mtk_dpi_probe(struct platform_device *pdev) - { - struct device *dev = &pdev->dev; -@@ -753,6 +771,9 @@ static int mtk_dpi_remove(struct platform_device *pdev) - } - - static const struct of_device_id mtk_dpi_of_ids[] = { -+ { .compatible = "mediatek,mt2701-dpi", -+ .data = &mt2701_conf, -+ }, - { .compatible = "mediatek,mt8173-dpi", - .data = &mt8173_conf, - }, -diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c -index 47ec604289b7..6422e99952fe 100644 ---- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c -+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c -@@ -424,6 +424,8 @@ static const struct of_device_id mtk_ddp_comp_dt_ids[] = { - .data = (void *)MTK_DSI }, - { .compatible = "mediatek,mt8173-dsi", - .data = (void *)MTK_DSI }, -+ { .compatible = "mediatek,mt2701-dpi", -+ .data = (void *)MTK_DPI }, - { .compatible = "mediatek,mt8173-dpi", - .data = (void *)MTK_DPI }, - { .compatible = "mediatek,mt2701-disp-mutex", --- -2.19.1 - diff --git a/root/target/linux/mediatek/patches-4.19/0033-drm-mediatek-separate-hdmi-phy-to-different-file.patch b/root/target/linux/mediatek/patches-4.19/0033-drm-mediatek-separate-hdmi-phy-to-different-file.patch deleted file mode 100644 index 1c769415..00000000 --- a/root/target/linux/mediatek/patches-4.19/0033-drm-mediatek-separate-hdmi-phy-to-different-file.patch +++ /dev/null @@ -1,641 +0,0 @@ -From 186643bd86d33f0a773139deb5af6e12354b5907 Mon Sep 17 00:00:00 2001 -From: chunhui dai -Date: Wed, 3 Oct 2018 11:41:47 +0800 -Subject: [PATCH 33/77] drm/mediatek: separate hdmi phy to different file - -Different IC has different phy setting of HDMI. -This patch separates the phy hardware relate part for mt8173. - -Signed-off-by: chunhui dai -Reviewed-by: CK Hu ---- - drivers/gpu/drm/mediatek/Makefile | 6 +- - drivers/gpu/drm/mediatek/mtk_hdmi.c | 1 + - drivers/gpu/drm/mediatek/mtk_hdmi.h | 2 +- - drivers/gpu/drm/mediatek/mtk_hdmi_phy.c | 232 ++++++++++++++++++ - drivers/gpu/drm/mediatek/mtk_hdmi_phy.h | 58 +++++ - .../gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c | 226 +---------------- - 6 files changed, 302 insertions(+), 223 deletions(-) - create mode 100644 drivers/gpu/drm/mediatek/mtk_hdmi_phy.c - create mode 100644 drivers/gpu/drm/mediatek/mtk_hdmi_phy.h - -diff --git a/drivers/gpu/drm/mediatek/Makefile b/drivers/gpu/drm/mediatek/Makefile -index ce83c396a742..61cf0d2ab28a 100644 ---- a/drivers/gpu/drm/mediatek/Makefile -+++ b/drivers/gpu/drm/mediatek/Makefile -@@ -1,4 +1,5 @@ - # SPDX-License-Identifier: GPL-2.0 -+ - mediatek-drm-y := mtk_disp_color.o \ - mtk_disp_ovl.o \ - mtk_disp_rdma.o \ -@@ -18,6 +19,7 @@ obj-$(CONFIG_DRM_MEDIATEK) += mediatek-drm.o - mediatek-drm-hdmi-objs := mtk_cec.o \ - mtk_hdmi.o \ - mtk_hdmi_ddc.o \ -- mtk_mt8173_hdmi_phy.o -+ mtk_mt8173_hdmi_phy.o \ -+ mtk_hdmi_phy.o - --obj-$(CONFIG_DRM_MEDIATEK_HDMI) += mediatek-drm-hdmi.o -+obj-$(CONFIG_DRM_MEDIATEK_HDMI) += mediatek-drm-hdmi.o -\ No newline at end of file -diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi.c b/drivers/gpu/drm/mediatek/mtk_hdmi.c -index 643f5edd68fe..29bd2a144b19 100644 ---- a/drivers/gpu/drm/mediatek/mtk_hdmi.c -+++ b/drivers/gpu/drm/mediatek/mtk_hdmi.c -@@ -233,6 +233,7 @@ static void mtk_hdmi_hw_vid_black(struct mtk_hdmi *hdmi, bool black) - static void mtk_hdmi_hw_make_reg_writable(struct mtk_hdmi *hdmi, bool enable) - { - struct arm_smccc_res res; -+ struct mtk_hdmi_phy *hdmi_phy = phy_get_drvdata(hdmi->phy); - - /* - * MT8173 HDMI hardware has an output control bit to enable/disable HDMI -diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi.h b/drivers/gpu/drm/mediatek/mtk_hdmi.h -index 6371b3de1ff6..3e9fb8d19802 100644 ---- a/drivers/gpu/drm/mediatek/mtk_hdmi.h -+++ b/drivers/gpu/drm/mediatek/mtk_hdmi.h -@@ -13,11 +13,11 @@ - */ - #ifndef _MTK_HDMI_CTRL_H - #define _MTK_HDMI_CTRL_H -+#include "mtk_hdmi_phy.h" - - struct platform_driver; - - extern struct platform_driver mtk_cec_driver; - extern struct platform_driver mtk_hdmi_ddc_driver; --extern struct platform_driver mtk_hdmi_phy_driver; - - #endif /* _MTK_HDMI_CTRL_H */ -diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi_phy.c b/drivers/gpu/drm/mediatek/mtk_hdmi_phy.c -new file mode 100644 -index 000000000000..514f3e9a8767 ---- /dev/null -+++ b/drivers/gpu/drm/mediatek/mtk_hdmi_phy.c -@@ -0,0 +1,232 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (c) 2018 MediaTek Inc. -+ * Author: Jie Qiu -+ */ -+ -+#include "mtk_hdmi_phy.h" -+ -+static int mtk_hdmi_phy_power_on(struct phy *phy); -+static int mtk_hdmi_phy_power_off(struct phy *phy); -+ -+static const struct phy_ops mtk_hdmi_phy_dev_ops = { -+ .power_on = mtk_hdmi_phy_power_on, -+ .power_off = mtk_hdmi_phy_power_off, -+ .owner = THIS_MODULE, -+}; -+ -+long mtk_hdmi_pll_round_rate(struct clk_hw *hw, unsigned long rate, -+ unsigned long *parent_rate) -+{ -+ struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw); -+ -+ hdmi_phy->pll_rate = rate; -+ if (rate <= 74250000) -+ *parent_rate = rate; -+ else -+ *parent_rate = rate / 2; -+ -+ return rate; -+} -+ -+unsigned long mtk_hdmi_pll_recalc_rate(struct clk_hw *hw, -+ unsigned long parent_rate) -+{ -+ struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw); -+ -+ return hdmi_phy->pll_rate; -+} -+ -+void mtk_hdmi_phy_clear_bits(struct mtk_hdmi_phy *hdmi_phy, u32 offset, -+ u32 bits) -+{ -+ void __iomem *reg = hdmi_phy->regs + offset; -+ u32 tmp; -+ -+ tmp = readl(reg); -+ tmp &= ~bits; -+ writel(tmp, reg); -+} -+ -+void mtk_hdmi_phy_set_bits(struct mtk_hdmi_phy *hdmi_phy, u32 offset, -+ u32 bits) -+{ -+ void __iomem *reg = hdmi_phy->regs + offset; -+ u32 tmp; -+ -+ tmp = readl(reg); -+ tmp |= bits; -+ writel(tmp, reg); -+} -+ -+void mtk_hdmi_phy_mask(struct mtk_hdmi_phy *hdmi_phy, u32 offset, -+ u32 val, u32 mask) -+{ -+ void __iomem *reg = hdmi_phy->regs + offset; -+ u32 tmp; -+ -+ tmp = readl(reg); -+ tmp = (tmp & ~mask) | (val & mask); -+ writel(tmp, reg); -+} -+ -+inline struct mtk_hdmi_phy *to_mtk_hdmi_phy(struct clk_hw *hw) -+{ -+ return container_of(hw, struct mtk_hdmi_phy, pll_hw); -+} -+ -+static int mtk_hdmi_phy_power_on(struct phy *phy) -+{ -+ struct mtk_hdmi_phy *hdmi_phy = phy_get_drvdata(phy); -+ int ret; -+ -+ ret = clk_prepare_enable(hdmi_phy->pll); -+ if (ret < 0) -+ return ret; -+ -+ hdmi_phy->conf->hdmi_phy_enable_tmds(hdmi_phy); -+ return 0; -+} -+ -+static int mtk_hdmi_phy_power_off(struct phy *phy) -+{ -+ struct mtk_hdmi_phy *hdmi_phy = phy_get_drvdata(phy); -+ -+ hdmi_phy->conf->hdmi_phy_disable_tmds(hdmi_phy); -+ clk_disable_unprepare(hdmi_phy->pll); -+ -+ return 0; -+} -+ -+static const struct phy_ops * -+mtk_hdmi_phy_dev_get_ops(const struct mtk_hdmi_phy *hdmi_phy) -+{ -+ if (hdmi_phy && hdmi_phy->conf && -+ hdmi_phy->conf->hdmi_phy_enable_tmds && -+ hdmi_phy->conf->hdmi_phy_disable_tmds) -+ return &mtk_hdmi_phy_dev_ops; -+ -+ dev_err(hdmi_phy->dev, "Failed to get dev ops of phy\n"); -+ return NULL; -+} -+ -+static void mtk_hdmi_phy_clk_get_ops(struct mtk_hdmi_phy *hdmi_phy, -+ const struct clk_ops **ops) -+{ -+ if (hdmi_phy && hdmi_phy->conf && hdmi_phy->conf->hdmi_phy_clk_ops) -+ *ops = hdmi_phy->conf->hdmi_phy_clk_ops; -+ else -+ dev_err(hdmi_phy->dev, "Failed to get clk ops of phy\n"); -+} -+ -+static int mtk_hdmi_phy_probe(struct platform_device *pdev) -+{ -+ struct device *dev = &pdev->dev; -+ struct mtk_hdmi_phy *hdmi_phy; -+ struct resource *mem; -+ struct clk *ref_clk; -+ const char *ref_clk_name; -+ struct clk_init_data clk_init = { -+ .num_parents = 1, -+ .parent_names = (const char * const *)&ref_clk_name, -+ .flags = CLK_SET_RATE_PARENT | CLK_SET_RATE_GATE, -+ }; -+ -+ struct phy *phy; -+ struct phy_provider *phy_provider; -+ int ret; -+ -+ hdmi_phy = devm_kzalloc(dev, sizeof(*hdmi_phy), GFP_KERNEL); -+ if (!hdmi_phy) -+ return -ENOMEM; -+ -+ mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ hdmi_phy->regs = devm_ioremap_resource(dev, mem); -+ if (IS_ERR(hdmi_phy->regs)) { -+ ret = PTR_ERR(hdmi_phy->regs); -+ dev_err(dev, "Failed to get memory resource: %d\n", ret); -+ return ret; -+ } -+ -+ ref_clk = devm_clk_get(dev, "pll_ref"); -+ if (IS_ERR(ref_clk)) { -+ ret = PTR_ERR(ref_clk); -+ dev_err(&pdev->dev, "Failed to get PLL reference clock: %d\n", -+ ret); -+ return ret; -+ } -+ ref_clk_name = __clk_get_name(ref_clk); -+ -+ ret = of_property_read_string(dev->of_node, "clock-output-names", -+ &clk_init.name); -+ if (ret < 0) { -+ dev_err(dev, "Failed to read clock-output-names: %d\n", ret); -+ return ret; -+ } -+ -+ hdmi_phy->dev = dev; -+ hdmi_phy->conf = -+ (struct mtk_hdmi_phy_conf *)of_device_get_match_data(dev); -+ mtk_hdmi_phy_clk_get_ops(hdmi_phy, &clk_init.ops); -+ hdmi_phy->pll_hw.init = &clk_init; -+ hdmi_phy->pll = devm_clk_register(dev, &hdmi_phy->pll_hw); -+ if (IS_ERR(hdmi_phy->pll)) { -+ ret = PTR_ERR(hdmi_phy->pll); -+ dev_err(dev, "Failed to register PLL: %d\n", ret); -+ return ret; -+ } -+ -+ ret = of_property_read_u32(dev->of_node, "mediatek,ibias", -+ &hdmi_phy->ibias); -+ if (ret < 0) { -+ dev_err(&pdev->dev, "Failed to get ibias: %d\n", ret); -+ return ret; -+ } -+ -+ ret = of_property_read_u32(dev->of_node, "mediatek,ibias_up", -+ &hdmi_phy->ibias_up); -+ if (ret < 0) { -+ dev_err(&pdev->dev, "Failed to get ibias up: %d\n", ret); -+ return ret; -+ } -+ -+ dev_info(dev, "Using default TX DRV impedance: 4.2k/36\n"); -+ hdmi_phy->drv_imp_clk = 0x30; -+ hdmi_phy->drv_imp_d2 = 0x30; -+ hdmi_phy->drv_imp_d1 = 0x30; -+ hdmi_phy->drv_imp_d0 = 0x30; -+ -+ phy = devm_phy_create(dev, NULL, mtk_hdmi_phy_dev_get_ops(hdmi_phy)); -+ if (IS_ERR(phy)) { -+ dev_err(dev, "Failed to create HDMI PHY\n"); -+ return PTR_ERR(phy); -+ } -+ phy_set_drvdata(phy, hdmi_phy); -+ -+ phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); -+ if (IS_ERR(phy_provider)) { -+ dev_err(dev, "Failed to register HDMI PHY\n"); -+ return PTR_ERR(phy_provider); -+ } -+ -+ return of_clk_add_provider(dev->of_node, of_clk_src_simple_get, -+ hdmi_phy->pll); -+} -+ -+static const struct of_device_id mtk_hdmi_phy_match[] = { -+ { .compatible = "mediatek,mt8173-hdmi-phy", -+ .data = &mtk_hdmi_phy_8173_conf, -+ }, -+ {}, -+}; -+ -+struct platform_driver mtk_hdmi_phy_driver = { -+ .probe = mtk_hdmi_phy_probe, -+ .driver = { -+ .name = "mediatek-hdmi-phy", -+ .of_match_table = mtk_hdmi_phy_match, -+ }, -+}; -+ -+MODULE_DESCRIPTION("MediaTek HDMI PHY Driver"); -+MODULE_LICENSE("GPL v2"); -diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi_phy.h b/drivers/gpu/drm/mediatek/mtk_hdmi_phy.h -new file mode 100644 -index 000000000000..09b8f525e6b8 ---- /dev/null -+++ b/drivers/gpu/drm/mediatek/mtk_hdmi_phy.h -@@ -0,0 +1,58 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (c) 2018 MediaTek Inc. -+ * Author: Chunhui Dai -+ */ -+ -+#ifndef _MTK_HDMI_PHY_H -+#define _MTK_HDMI_PHY_H -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+struct mtk_hdmi_phy; -+ -+struct mtk_hdmi_phy_conf { -+ const struct clk_ops *hdmi_phy_clk_ops; -+ void (*hdmi_phy_enable_tmds)(struct mtk_hdmi_phy *hdmi_phy); -+ void (*hdmi_phy_disable_tmds)(struct mtk_hdmi_phy *hdmi_phy); -+}; -+ -+struct mtk_hdmi_phy { -+ void __iomem *regs; -+ struct device *dev; -+ struct mtk_hdmi_phy_conf *conf; -+ struct clk *pll; -+ struct clk_hw pll_hw; -+ unsigned long pll_rate; -+ unsigned char drv_imp_clk; -+ unsigned char drv_imp_d2; -+ unsigned char drv_imp_d1; -+ unsigned char drv_imp_d0; -+ unsigned int ibias; -+ unsigned int ibias_up; -+}; -+ -+void mtk_hdmi_phy_clear_bits(struct mtk_hdmi_phy *hdmi_phy, u32 offset, -+ u32 bits); -+void mtk_hdmi_phy_set_bits(struct mtk_hdmi_phy *hdmi_phy, u32 offset, -+ u32 bits); -+void mtk_hdmi_phy_mask(struct mtk_hdmi_phy *hdmi_phy, u32 offset, -+ u32 val, u32 mask); -+struct mtk_hdmi_phy *to_mtk_hdmi_phy(struct clk_hw *hw); -+long mtk_hdmi_pll_round_rate(struct clk_hw *hw, unsigned long rate, -+ unsigned long *parent_rate); -+unsigned long mtk_hdmi_pll_recalc_rate(struct clk_hw *hw, -+ unsigned long parent_rate); -+ -+extern struct platform_driver mtk_hdmi_phy_driver; -+extern struct mtk_hdmi_phy_conf mtk_hdmi_phy_8173_conf; -+ -+#endif /* _MTK_HDMI_PHY_H */ -diff --git a/drivers/gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c b/drivers/gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c -index 51cb9cfb6646..ed5916b27658 100644 ---- a/drivers/gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c -+++ b/drivers/gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c -@@ -12,15 +12,7 @@ - * GNU General Public License for more details. - */ - --#include --#include --#include --#include --#include --#include --#include --#include --#include -+#include "mtk_hdmi_phy.h" - - #define HDMI_CON0 0x00 - #define RG_HDMITX_PLL_EN BIT(31) -@@ -123,20 +115,6 @@ - #define RGS_HDMITX_5T1_EDG (0xf << 4) - #define RGS_HDMITX_PLUG_TST BIT(0) - --struct mtk_hdmi_phy { -- void __iomem *regs; -- struct device *dev; -- struct clk *pll; -- struct clk_hw pll_hw; -- unsigned long pll_rate; -- u8 drv_imp_clk; -- u8 drv_imp_d2; -- u8 drv_imp_d1; -- u8 drv_imp_d0; -- u32 ibias; -- u32 ibias_up; --}; -- - static const u8 PREDIV[3][4] = { - {0x0, 0x0, 0x0, 0x0}, /* 27Mhz */ - {0x1, 0x1, 0x1, 0x1}, /* 74Mhz */ -@@ -185,44 +163,6 @@ static const u8 HTPLLBR[3][4] = { - {0x1, 0x2, 0x2, 0x1} /* 148Mhz */ - }; - --static void mtk_hdmi_phy_clear_bits(struct mtk_hdmi_phy *hdmi_phy, u32 offset, -- u32 bits) --{ -- void __iomem *reg = hdmi_phy->regs + offset; -- u32 tmp; -- -- tmp = readl(reg); -- tmp &= ~bits; -- writel(tmp, reg); --} -- --static void mtk_hdmi_phy_set_bits(struct mtk_hdmi_phy *hdmi_phy, u32 offset, -- u32 bits) --{ -- void __iomem *reg = hdmi_phy->regs + offset; -- u32 tmp; -- -- tmp = readl(reg); -- tmp |= bits; -- writel(tmp, reg); --} -- --static void mtk_hdmi_phy_mask(struct mtk_hdmi_phy *hdmi_phy, u32 offset, -- u32 val, u32 mask) --{ -- void __iomem *reg = hdmi_phy->regs + offset; -- u32 tmp; -- -- tmp = readl(reg); -- tmp = (tmp & ~mask) | (val & mask); -- writel(tmp, reg); --} -- --static inline struct mtk_hdmi_phy *to_mtk_hdmi_phy(struct clk_hw *hw) --{ -- return container_of(hw, struct mtk_hdmi_phy, pll_hw); --} -- - static int mtk_hdmi_pll_prepare(struct clk_hw *hw) - { - struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw); -@@ -345,29 +285,7 @@ static int mtk_hdmi_pll_set_rate(struct clk_hw *hw, unsigned long rate, - return 0; - } - --static long mtk_hdmi_pll_round_rate(struct clk_hw *hw, unsigned long rate, -- unsigned long *parent_rate) --{ -- struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw); -- -- hdmi_phy->pll_rate = rate; -- if (rate <= 74250000) -- *parent_rate = rate; -- else -- *parent_rate = rate / 2; -- -- return rate; --} -- --static unsigned long mtk_hdmi_pll_recalc_rate(struct clk_hw *hw, -- unsigned long parent_rate) --{ -- struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw); -- -- return hdmi_phy->pll_rate; --} -- --static const struct clk_ops mtk_hdmi_pll_ops = { -+static const struct clk_ops mtk_hdmi_phy_pll_ops = { - .prepare = mtk_hdmi_pll_prepare, - .unprepare = mtk_hdmi_pll_unprepare, - .set_rate = mtk_hdmi_pll_set_rate, -@@ -390,142 +308,10 @@ static void mtk_hdmi_phy_disable_tmds(struct mtk_hdmi_phy *hdmi_phy) - RG_HDMITX_SER_EN); - } - --static int mtk_hdmi_phy_power_on(struct phy *phy) --{ -- struct mtk_hdmi_phy *hdmi_phy = phy_get_drvdata(phy); -- int ret; -- -- ret = clk_prepare_enable(hdmi_phy->pll); -- if (ret < 0) -- return ret; -- -- mtk_hdmi_phy_enable_tmds(hdmi_phy); -- -- return 0; --} -- --static int mtk_hdmi_phy_power_off(struct phy *phy) --{ -- struct mtk_hdmi_phy *hdmi_phy = phy_get_drvdata(phy); -- -- mtk_hdmi_phy_disable_tmds(hdmi_phy); -- clk_disable_unprepare(hdmi_phy->pll); -- -- return 0; --} -- --static const struct phy_ops mtk_hdmi_phy_ops = { -- .power_on = mtk_hdmi_phy_power_on, -- .power_off = mtk_hdmi_phy_power_off, -- .owner = THIS_MODULE, --}; -- --static int mtk_hdmi_phy_probe(struct platform_device *pdev) --{ -- struct device *dev = &pdev->dev; -- struct mtk_hdmi_phy *hdmi_phy; -- struct resource *mem; -- struct clk *ref_clk; -- const char *ref_clk_name; -- struct clk_init_data clk_init = { -- .ops = &mtk_hdmi_pll_ops, -- .num_parents = 1, -- .parent_names = (const char * const *)&ref_clk_name, -- .flags = CLK_SET_RATE_PARENT | CLK_SET_RATE_GATE, -- }; -- struct phy *phy; -- struct phy_provider *phy_provider; -- int ret; -- -- hdmi_phy = devm_kzalloc(dev, sizeof(*hdmi_phy), GFP_KERNEL); -- if (!hdmi_phy) -- return -ENOMEM; -- -- mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); -- hdmi_phy->regs = devm_ioremap_resource(dev, mem); -- if (IS_ERR(hdmi_phy->regs)) { -- ret = PTR_ERR(hdmi_phy->regs); -- dev_err(dev, "Failed to get memory resource: %d\n", ret); -- return ret; -- } -- -- ref_clk = devm_clk_get(dev, "pll_ref"); -- if (IS_ERR(ref_clk)) { -- ret = PTR_ERR(ref_clk); -- dev_err(&pdev->dev, "Failed to get PLL reference clock: %d\n", -- ret); -- return ret; -- } -- ref_clk_name = __clk_get_name(ref_clk); -- -- ret = of_property_read_string(dev->of_node, "clock-output-names", -- &clk_init.name); -- if (ret < 0) { -- dev_err(dev, "Failed to read clock-output-names: %d\n", ret); -- return ret; -- } -- -- hdmi_phy->pll_hw.init = &clk_init; -- hdmi_phy->pll = devm_clk_register(dev, &hdmi_phy->pll_hw); -- if (IS_ERR(hdmi_phy->pll)) { -- ret = PTR_ERR(hdmi_phy->pll); -- dev_err(dev, "Failed to register PLL: %d\n", ret); -- return ret; -- } -- -- ret = of_property_read_u32(dev->of_node, "mediatek,ibias", -- &hdmi_phy->ibias); -- if (ret < 0) { -- dev_err(&pdev->dev, "Failed to get ibias: %d\n", ret); -- return ret; -- } -- -- ret = of_property_read_u32(dev->of_node, "mediatek,ibias_up", -- &hdmi_phy->ibias_up); -- if (ret < 0) { -- dev_err(&pdev->dev, "Failed to get ibias up: %d\n", ret); -- return ret; -- } -- -- dev_info(dev, "Using default TX DRV impedance: 4.2k/36\n"); -- hdmi_phy->drv_imp_clk = 0x30; -- hdmi_phy->drv_imp_d2 = 0x30; -- hdmi_phy->drv_imp_d1 = 0x30; -- hdmi_phy->drv_imp_d0 = 0x30; -- -- phy = devm_phy_create(dev, NULL, &mtk_hdmi_phy_ops); -- if (IS_ERR(phy)) { -- dev_err(dev, "Failed to create HDMI PHY\n"); -- return PTR_ERR(phy); -- } -- phy_set_drvdata(phy, hdmi_phy); -- -- phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); -- if (IS_ERR(phy_provider)) -- return PTR_ERR(phy_provider); -- -- hdmi_phy->dev = dev; -- return of_clk_add_provider(dev->of_node, of_clk_src_simple_get, -- hdmi_phy->pll); --} -- --static int mtk_hdmi_phy_remove(struct platform_device *pdev) --{ -- return 0; --} -- --static const struct of_device_id mtk_hdmi_phy_match[] = { -- { .compatible = "mediatek,mt8173-hdmi-phy", }, -- {}, --}; -- --struct platform_driver mtk_hdmi_phy_driver = { -- .probe = mtk_hdmi_phy_probe, -- .remove = mtk_hdmi_phy_remove, -- .driver = { -- .name = "mediatek-hdmi-phy", -- .of_match_table = mtk_hdmi_phy_match, -- }, -+struct mtk_hdmi_phy_conf mtk_hdmi_phy_8173_conf = { -+ .hdmi_phy_clk_ops = &mtk_hdmi_phy_pll_ops, -+ .hdmi_phy_enable_tmds = mtk_hdmi_phy_enable_tmds, -+ .hdmi_phy_disable_tmds = mtk_hdmi_phy_disable_tmds, - }; - - MODULE_AUTHOR("Jie Qiu "); --- -2.19.1 - diff --git a/root/target/linux/mediatek/patches-4.19/0034-drm-mediatek-add-support-for-SPDIF-audio-in-HDMI.patch b/root/target/linux/mediatek/patches-4.19/0034-drm-mediatek-add-support-for-SPDIF-audio-in-HDMI.patch deleted file mode 100644 index 8c3d0162..00000000 --- a/root/target/linux/mediatek/patches-4.19/0034-drm-mediatek-add-support-for-SPDIF-audio-in-HDMI.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 93440802592c9acbec41645809dcae5eb350d966 Mon Sep 17 00:00:00 2001 -From: chunhui dai -Date: Wed, 3 Oct 2018 11:41:48 +0800 -Subject: [PATCH 34/77] drm/mediatek: add support for SPDIF audio in HDMI - -add support for SPDIF audio in HDMI - -Signed-off-by: chunhui dai -Reviewed-by: CK Hu ---- - drivers/gpu/drm/mediatek/mtk_hdmi.c | 5 +++++ - 1 file changed, 5 insertions(+) - -diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi.c b/drivers/gpu/drm/mediatek/mtk_hdmi.c -index 29bd2a144b19..90e1139f02f8 100644 ---- a/drivers/gpu/drm/mediatek/mtk_hdmi.c -+++ b/drivers/gpu/drm/mediatek/mtk_hdmi.c -@@ -1577,6 +1577,11 @@ static int mtk_hdmi_audio_hw_params(struct device *dev, void *data, - hdmi_params.aud_i2s_fmt = HDMI_I2S_MODE_I2S_24BIT; - hdmi_params.aud_mclk = HDMI_AUD_MCLK_128FS; - break; -+ case HDMI_SPDIF: -+ hdmi_params.aud_codec = HDMI_AUDIO_CODING_TYPE_PCM; -+ hdmi_params.aud_sampe_size = HDMI_AUDIO_SAMPLE_SIZE_16; -+ hdmi_params.aud_input_type = HDMI_AUD_INPUT_SPDIF; -+ break; - default: - dev_err(hdmi->dev, "%s: Invalid DAI format %d\n", __func__, - daifmt->fmt); --- -2.19.1 - diff --git a/root/target/linux/mediatek/patches-4.19/0035-drm-mediatek-add-hdmi-driver-for-MT2701-and-MT7623.patch b/root/target/linux/mediatek/patches-4.19/0035-drm-mediatek-add-hdmi-driver-for-MT2701-and-MT7623.patch deleted file mode 100644 index b56c6315..00000000 --- a/root/target/linux/mediatek/patches-4.19/0035-drm-mediatek-add-hdmi-driver-for-MT2701-and-MT7623.patch +++ /dev/null @@ -1,309 +0,0 @@ -From 7ced4ebd71acd0677a73976bf6be399c2362ca6e Mon Sep 17 00:00:00 2001 -From: chunhui dai -Date: Wed, 3 Oct 2018 11:41:49 +0800 -Subject: [PATCH 35/77] drm/mediatek: add hdmi driver for MT2701 and MT7623 - -This patch adds hdmi dirver suppot for both MT2701 and MT7623. -And also support other (existing or future) chips that use -the same binding and driver. - -Signed-off-by: chunhui dai -Reviewed-by: CK Hu ---- - drivers/gpu/drm/mediatek/Makefile | 3 +- - drivers/gpu/drm/mediatek/mtk_hdmi.c | 9 +- - drivers/gpu/drm/mediatek/mtk_hdmi_phy.c | 3 + - drivers/gpu/drm/mediatek/mtk_hdmi_phy.h | 2 + - .../gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c | 212 ++++++++++++++++++ - 5 files changed, 226 insertions(+), 3 deletions(-) - create mode 100644 drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c - -diff --git a/drivers/gpu/drm/mediatek/Makefile b/drivers/gpu/drm/mediatek/Makefile -index 61cf0d2ab28a..82ae49c64221 100644 ---- a/drivers/gpu/drm/mediatek/Makefile -+++ b/drivers/gpu/drm/mediatek/Makefile -@@ -19,7 +19,8 @@ obj-$(CONFIG_DRM_MEDIATEK) += mediatek-drm.o - mediatek-drm-hdmi-objs := mtk_cec.o \ - mtk_hdmi.o \ - mtk_hdmi_ddc.o \ -+ mtk_mt2701_hdmi_phy.o \ - mtk_mt8173_hdmi_phy.o \ - mtk_hdmi_phy.o - --obj-$(CONFIG_DRM_MEDIATEK_HDMI) += mediatek-drm-hdmi.o -\ No newline at end of file -+obj-$(CONFIG_DRM_MEDIATEK_HDMI) += mediatek-drm-hdmi.o -diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi.c b/drivers/gpu/drm/mediatek/mtk_hdmi.c -index 90e1139f02f8..862f3ec22131 100644 ---- a/drivers/gpu/drm/mediatek/mtk_hdmi.c -+++ b/drivers/gpu/drm/mediatek/mtk_hdmi.c -@@ -241,8 +241,13 @@ static void mtk_hdmi_hw_make_reg_writable(struct mtk_hdmi *hdmi, bool enable) - * The ARM trusted firmware provides an API for the HDMI driver to set - * this control bit to enable HDMI output in supervisor mode. - */ -- arm_smccc_smc(MTK_SIP_SET_AUTHORIZED_SECURE_REG, 0x14000904, 0x80000000, -- 0, 0, 0, 0, 0, &res); -+ if (hdmi_phy->conf && hdmi_phy->conf->tz_disabled) -+ regmap_update_bits(hdmi->sys_regmap, -+ hdmi->sys_offset + HDMI_SYS_CFG20, -+ 0x80008005, enable ? 0x80000005 : 0x8000); -+ else -+ arm_smccc_smc(MTK_SIP_SET_AUTHORIZED_SECURE_REG, 0x14000904, -+ 0x80000000, 0, 0, 0, 0, 0, &res); - - regmap_update_bits(hdmi->sys_regmap, hdmi->sys_offset + HDMI_SYS_CFG20, - HDMI_PCLK_FREE_RUN, enable ? HDMI_PCLK_FREE_RUN : 0); -diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi_phy.c b/drivers/gpu/drm/mediatek/mtk_hdmi_phy.c -index 514f3e9a8767..4ef9c57ffd44 100644 ---- a/drivers/gpu/drm/mediatek/mtk_hdmi_phy.c -+++ b/drivers/gpu/drm/mediatek/mtk_hdmi_phy.c -@@ -214,6 +214,9 @@ static int mtk_hdmi_phy_probe(struct platform_device *pdev) - } - - static const struct of_device_id mtk_hdmi_phy_match[] = { -+ { .compatible = "mediatek,mt2701-hdmi-phy", -+ .data = &mtk_hdmi_phy_2701_conf, -+ }, - { .compatible = "mediatek,mt8173-hdmi-phy", - .data = &mtk_hdmi_phy_8173_conf, - }, -diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi_phy.h b/drivers/gpu/drm/mediatek/mtk_hdmi_phy.h -index 09b8f525e6b8..f39b1fc66612 100644 ---- a/drivers/gpu/drm/mediatek/mtk_hdmi_phy.h -+++ b/drivers/gpu/drm/mediatek/mtk_hdmi_phy.h -@@ -20,6 +20,7 @@ - struct mtk_hdmi_phy; - - struct mtk_hdmi_phy_conf { -+ bool tz_disabled; - const struct clk_ops *hdmi_phy_clk_ops; - void (*hdmi_phy_enable_tmds)(struct mtk_hdmi_phy *hdmi_phy); - void (*hdmi_phy_disable_tmds)(struct mtk_hdmi_phy *hdmi_phy); -@@ -54,5 +55,6 @@ unsigned long mtk_hdmi_pll_recalc_rate(struct clk_hw *hw, - - extern struct platform_driver mtk_hdmi_phy_driver; - extern struct mtk_hdmi_phy_conf mtk_hdmi_phy_8173_conf; -+extern struct mtk_hdmi_phy_conf mtk_hdmi_phy_2701_conf; - - #endif /* _MTK_HDMI_PHY_H */ -diff --git a/drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c b/drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c -new file mode 100644 -index 000000000000..fcc42dc6ea7f ---- /dev/null -+++ b/drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c -@@ -0,0 +1,212 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (c) 2018 MediaTek Inc. -+ * Author: Chunhui Dai -+ */ -+ -+#include "mtk_hdmi_phy.h" -+ -+#define HDMI_CON0 0x00 -+#define RG_HDMITX_DRV_IBIAS 0 -+#define RG_HDMITX_DRV_IBIAS_MASK (0x3f << 0) -+#define RG_HDMITX_EN_SER 12 -+#define RG_HDMITX_EN_SER_MASK (0x0f << 12) -+#define RG_HDMITX_EN_SLDO 16 -+#define RG_HDMITX_EN_SLDO_MASK (0x0f << 16) -+#define RG_HDMITX_EN_PRED 20 -+#define RG_HDMITX_EN_PRED_MASK (0x0f << 20) -+#define RG_HDMITX_EN_IMP 24 -+#define RG_HDMITX_EN_IMP_MASK (0x0f << 24) -+#define RG_HDMITX_EN_DRV 28 -+#define RG_HDMITX_EN_DRV_MASK (0x0f << 28) -+ -+#define HDMI_CON1 0x04 -+#define RG_HDMITX_PRED_IBIAS 18 -+#define RG_HDMITX_PRED_IBIAS_MASK (0x0f << 18) -+#define RG_HDMITX_PRED_IMP (0x01 << 22) -+#define RG_HDMITX_DRV_IMP 26 -+#define RG_HDMITX_DRV_IMP_MASK (0x3f << 26) -+ -+#define HDMI_CON2 0x08 -+#define RG_HDMITX_EN_TX_CKLDO (0x01 << 0) -+#define RG_HDMITX_EN_TX_POSDIV (0x01 << 1) -+#define RG_HDMITX_TX_POSDIV 3 -+#define RG_HDMITX_TX_POSDIV_MASK (0x03 << 3) -+#define RG_HDMITX_EN_MBIAS (0x01 << 6) -+#define RG_HDMITX_MBIAS_LPF_EN (0x01 << 7) -+ -+#define HDMI_CON4 0x10 -+#define RG_HDMITX_RESERVE_MASK (0xffffffff << 0) -+ -+#define HDMI_CON6 0x18 -+#define RG_HTPLL_BR 0 -+#define RG_HTPLL_BR_MASK (0x03 << 0) -+#define RG_HTPLL_BC 2 -+#define RG_HTPLL_BC_MASK (0x03 << 2) -+#define RG_HTPLL_BP 4 -+#define RG_HTPLL_BP_MASK (0x0f << 4) -+#define RG_HTPLL_IR 8 -+#define RG_HTPLL_IR_MASK (0x0f << 8) -+#define RG_HTPLL_IC 12 -+#define RG_HTPLL_IC_MASK (0x0f << 12) -+#define RG_HTPLL_POSDIV 16 -+#define RG_HTPLL_POSDIV_MASK (0x03 << 16) -+#define RG_HTPLL_PREDIV 18 -+#define RG_HTPLL_PREDIV_MASK (0x03 << 18) -+#define RG_HTPLL_FBKSEL 20 -+#define RG_HTPLL_FBKSEL_MASK (0x03 << 20) -+#define RG_HTPLL_RLH_EN (0x01 << 22) -+#define RG_HTPLL_FBKDIV 24 -+#define RG_HTPLL_FBKDIV_MASK (0x7f << 24) -+#define RG_HTPLL_EN (0x01 << 31) -+ -+#define HDMI_CON7 0x1c -+#define RG_HTPLL_AUTOK_EN (0x01 << 23) -+#define RG_HTPLL_DIVEN 28 -+#define RG_HTPLL_DIVEN_MASK (0x07 << 28) -+ -+static int mtk_hdmi_pll_prepare(struct clk_hw *hw) -+{ -+ struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw); -+ -+ mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON7, RG_HTPLL_AUTOK_EN); -+ mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON6, RG_HTPLL_RLH_EN); -+ mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON6, RG_HTPLL_POSDIV_MASK); -+ mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON2, RG_HDMITX_EN_MBIAS); -+ usleep_range(80, 100); -+ mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON6, RG_HTPLL_EN); -+ mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON2, RG_HDMITX_EN_TX_CKLDO); -+ mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_SLDO_MASK); -+ usleep_range(80, 100); -+ mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON2, RG_HDMITX_MBIAS_LPF_EN); -+ mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON2, RG_HDMITX_EN_TX_POSDIV); -+ mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_SER_MASK); -+ mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_PRED_MASK); -+ mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_DRV_MASK); -+ usleep_range(80, 100); -+ return 0; -+} -+ -+static void mtk_hdmi_pll_unprepare(struct clk_hw *hw) -+{ -+ struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw); -+ -+ mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_DRV_MASK); -+ mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_PRED_MASK); -+ mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_SER_MASK); -+ mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON2, RG_HDMITX_EN_TX_POSDIV); -+ mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON2, RG_HDMITX_MBIAS_LPF_EN); -+ usleep_range(80, 100); -+ mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_SLDO_MASK); -+ mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON2, RG_HDMITX_EN_TX_CKLDO); -+ mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON6, RG_HTPLL_EN); -+ usleep_range(80, 100); -+ mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON2, RG_HDMITX_EN_MBIAS); -+ mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON6, RG_HTPLL_POSDIV_MASK); -+ mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON6, RG_HTPLL_RLH_EN); -+ mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON7, RG_HTPLL_AUTOK_EN); -+ usleep_range(80, 100); -+} -+ -+static int mtk_hdmi_pll_set_rate(struct clk_hw *hw, unsigned long rate, -+ unsigned long parent_rate) -+{ -+ struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw); -+ u32 pos_div; -+ -+ if (rate <= 64000000) -+ pos_div = 3; -+ else if (rate <= 12800000) -+ pos_div = 1; -+ else -+ pos_div = 1; -+ -+ mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON6, RG_HTPLL_PREDIV_MASK); -+ mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON6, RG_HTPLL_POSDIV_MASK); -+ mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON6, (0x1 << RG_HTPLL_IC), -+ RG_HTPLL_IC_MASK); -+ mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON6, (0x1 << RG_HTPLL_IR), -+ RG_HTPLL_IR_MASK); -+ mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON2, (pos_div << RG_HDMITX_TX_POSDIV), -+ RG_HDMITX_TX_POSDIV_MASK); -+ mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON6, (1 << RG_HTPLL_FBKSEL), -+ RG_HTPLL_FBKSEL_MASK); -+ mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON6, (19 << RG_HTPLL_FBKDIV), -+ RG_HTPLL_FBKDIV_MASK); -+ mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON7, (0x2 << RG_HTPLL_DIVEN), -+ RG_HTPLL_DIVEN_MASK); -+ mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON6, (0xc << RG_HTPLL_BP), -+ RG_HTPLL_BP_MASK); -+ mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON6, (0x2 << RG_HTPLL_BC), -+ RG_HTPLL_BC_MASK); -+ mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON6, (0x1 << RG_HTPLL_BR), -+ RG_HTPLL_BR_MASK); -+ -+ mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON1, RG_HDMITX_PRED_IMP); -+ mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON1, (0x3 << RG_HDMITX_PRED_IBIAS), -+ RG_HDMITX_PRED_IBIAS_MASK); -+ mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_IMP_MASK); -+ mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON1, (0x28 << RG_HDMITX_DRV_IMP), -+ RG_HDMITX_DRV_IMP_MASK); -+ mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON4, 0x28, RG_HDMITX_RESERVE_MASK); -+ mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON0, (0xa << RG_HDMITX_DRV_IBIAS), -+ RG_HDMITX_DRV_IBIAS_MASK); -+ return 0; -+} -+ -+static const struct clk_ops mtk_hdmi_phy_pll_ops = { -+ .prepare = mtk_hdmi_pll_prepare, -+ .unprepare = mtk_hdmi_pll_unprepare, -+ .set_rate = mtk_hdmi_pll_set_rate, -+ .round_rate = mtk_hdmi_pll_round_rate, -+ .recalc_rate = mtk_hdmi_pll_recalc_rate, -+}; -+ -+static void mtk_hdmi_phy_enable_tmds(struct mtk_hdmi_phy *hdmi_phy) -+{ -+ mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON7, RG_HTPLL_AUTOK_EN); -+ mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON6, RG_HTPLL_RLH_EN); -+ mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON6, RG_HTPLL_POSDIV_MASK); -+ mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON2, RG_HDMITX_EN_MBIAS); -+ usleep_range(80, 100); -+ mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON6, RG_HTPLL_EN); -+ mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON2, RG_HDMITX_EN_TX_CKLDO); -+ mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_SLDO_MASK); -+ usleep_range(80, 100); -+ mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON2, RG_HDMITX_MBIAS_LPF_EN); -+ mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON2, RG_HDMITX_EN_TX_POSDIV); -+ mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_SER_MASK); -+ mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_PRED_MASK); -+ mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_DRV_MASK); -+ usleep_range(80, 100); -+} -+ -+static void mtk_hdmi_phy_disable_tmds(struct mtk_hdmi_phy *hdmi_phy) -+{ -+ mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_DRV_MASK); -+ mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_PRED_MASK); -+ mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_SER_MASK); -+ mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON2, RG_HDMITX_EN_TX_POSDIV); -+ mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON2, RG_HDMITX_MBIAS_LPF_EN); -+ usleep_range(80, 100); -+ mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_SLDO_MASK); -+ mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON2, RG_HDMITX_EN_TX_CKLDO); -+ mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON6, RG_HTPLL_EN); -+ usleep_range(80, 100); -+ mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON2, RG_HDMITX_EN_MBIAS); -+ mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON6, RG_HTPLL_POSDIV_MASK); -+ mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON6, RG_HTPLL_RLH_EN); -+ mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON7, RG_HTPLL_AUTOK_EN); -+ usleep_range(80, 100); -+} -+ -+struct mtk_hdmi_phy_conf mtk_hdmi_phy_2701_conf = { -+ .tz_disabled = true, -+ .hdmi_phy_clk_ops = &mtk_hdmi_phy_pll_ops, -+ .hdmi_phy_enable_tmds = mtk_hdmi_phy_enable_tmds, -+ .hdmi_phy_disable_tmds = mtk_hdmi_phy_disable_tmds, -+}; -+ -+MODULE_AUTHOR("Chunhui Dai "); -+MODULE_DESCRIPTION("MediaTek HDMI PHY Driver"); -+MODULE_LICENSE("GPL v2"); --- -2.19.1 - diff --git a/root/target/linux/mediatek/patches-4.19/0036-drm-mediatek-implement-connection-from-BLS-to-DPI0.patch b/root/target/linux/mediatek/patches-4.19/0036-drm-mediatek-implement-connection-from-BLS-to-DPI0.patch deleted file mode 100644 index ba5d1160..00000000 --- a/root/target/linux/mediatek/patches-4.19/0036-drm-mediatek-implement-connection-from-BLS-to-DPI0.patch +++ /dev/null @@ -1,58 +0,0 @@ -From 2ac94b8b6a664bb66404b595da4789687f13bcc4 Mon Sep 17 00:00:00 2001 -From: Bibby Hsieh -Date: Wed, 3 Oct 2018 11:41:50 +0800 -Subject: [PATCH 36/77] drm/mediatek: implement connection from BLS to DPI0 - -Modify display driver to support connection from BLS to DPI. - -Signed-off-by: Bibby Hsieh -Reviewed-by: CK Hu ---- - drivers/gpu/drm/mediatek/mtk_drm_ddp.c | 14 +++++++++++++- - 1 file changed, 13 insertions(+), 1 deletion(-) - -diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp.c b/drivers/gpu/drm/mediatek/mtk_drm_ddp.c -index 546b3e3b300b..579ce28d801d 100644 ---- a/drivers/gpu/drm/mediatek/mtk_drm_ddp.c -+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp.c -@@ -39,6 +39,7 @@ - #define DISP_REG_CONFIG_DISP_OVL_MOUT_EN 0x030 - #define DISP_REG_CONFIG_OUT_SEL 0x04c - #define DISP_REG_CONFIG_DSI_SEL 0x050 -+#define DISP_REG_CONFIG_DPI_SEL 0x064 - - #define DISP_REG_MUTEX_EN(n) (0x20 + 0x20 * (n)) - #define DISP_REG_MUTEX(n) (0x24 + 0x20 * (n)) -@@ -136,7 +137,10 @@ - - #define OVL_MOUT_EN_RDMA 0x1 - #define BLS_TO_DSI_RDMA1_TO_DPI1 0x8 -+#define BLS_TO_DPI_RDMA1_TO_DSI 0x2 - #define DSI_SEL_IN_BLS 0x0 -+#define DPI_SEL_IN_BLS 0x0 -+#define DSI_SEL_IN_RDMA 0x1 - - struct mtk_disp_mutex { - int id; -@@ -339,9 +343,17 @@ static void mtk_ddp_sout_sel(void __iomem *config_regs, - enum mtk_ddp_comp_id cur, - enum mtk_ddp_comp_id next) - { -- if (cur == DDP_COMPONENT_BLS && next == DDP_COMPONENT_DSI0) -+ if (cur == DDP_COMPONENT_BLS && next == DDP_COMPONENT_DSI0) { - writel_relaxed(BLS_TO_DSI_RDMA1_TO_DPI1, - config_regs + DISP_REG_CONFIG_OUT_SEL); -+ } else if (cur == DDP_COMPONENT_BLS && next == DDP_COMPONENT_DPI0) { -+ writel_relaxed(BLS_TO_DPI_RDMA1_TO_DSI, -+ config_regs + DISP_REG_CONFIG_OUT_SEL); -+ writel_relaxed(DSI_SEL_IN_RDMA, -+ config_regs + DISP_REG_CONFIG_DSI_SEL); -+ writel_relaxed(DPI_SEL_IN_BLS, -+ config_regs + DISP_REG_CONFIG_DPI_SEL); -+ } - } - - void mtk_ddp_add_comp_to_path(void __iomem *config_regs, --- -2.19.1 - diff --git a/root/target/linux/mediatek/patches-4.19/0037-drm-mediatek-add-a-error-return-value-when-clock-dri.patch b/root/target/linux/mediatek/patches-4.19/0037-drm-mediatek-add-a-error-return-value-when-clock-dri.patch deleted file mode 100644 index 0693a2d9..00000000 --- a/root/target/linux/mediatek/patches-4.19/0037-drm-mediatek-add-a-error-return-value-when-clock-dri.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 4a50f2d17feb0b95488cb3f0769972f01e60209f Mon Sep 17 00:00:00 2001 -From: Bibby Hsieh -Date: Wed, 3 Oct 2018 11:41:51 +0800 -Subject: [PATCH 37/77] drm/mediatek: add a error return value when clock - driver has been prepared - -DRM driver get the comp->clk by of_clk_get(), we only -assign NULL to comp->clk when error happened, but do -not return the error number. - -Signed-off-by: Bibby Hsieh -Reviewed-by: CK Hu ---- - drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c -index ff974d82a4a6..54ca794db3e9 100644 ---- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c -+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c -@@ -294,7 +294,7 @@ int mtk_ddp_comp_init(struct device *dev, struct device_node *node, - comp->irq = of_irq_get(node, 0); - comp->clk = of_clk_get(node, 0); - if (IS_ERR(comp->clk)) -- comp->clk = NULL; -+ return PTR_ERR(comp->clk); - - /* Only DMA capable components need the LARB property */ - comp->larb_dev = NULL; --- -2.19.1 - diff --git a/root/target/linux/mediatek/patches-4.19/0038-drm-mediatek-config-component-output-by-device-node-.patch b/root/target/linux/mediatek/patches-4.19/0038-drm-mediatek-config-component-output-by-device-node-.patch deleted file mode 100644 index 831180aa..00000000 --- a/root/target/linux/mediatek/patches-4.19/0038-drm-mediatek-config-component-output-by-device-node-.patch +++ /dev/null @@ -1,142 +0,0 @@ -From 9712ba59916d5a7cf568e8ba73d4fba4f2ebfd5f Mon Sep 17 00:00:00 2001 -From: Bibby Hsieh -Date: Fri, 21 Sep 2018 11:28:22 +0800 -Subject: [PATCH 38/77] drm/mediatek: config component output by device node - port - -We can select output component by decive node port. -Main path default output component is DSI. -External path default output component is DPI. - -Signed-off-by: Bibby Hsieh -Signed-off-by: Frank Wunderlich ---- - drivers/gpu/drm/mediatek/mtk_drm_drv.c | 41 ++++++++++++++++++++++---- - drivers/gpu/drm/mediatek/mtk_drm_drv.h | 4 +-- - 2 files changed, 37 insertions(+), 8 deletions(-) - -diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c -index 6422e99952fe..188b83d63c87 100644 ---- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c -+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c -@@ -21,7 +21,9 @@ - #include - #include - #include -+#include - #include -+#include - #include - #include - -@@ -133,7 +135,7 @@ static const struct drm_mode_config_funcs mtk_drm_mode_config_funcs = { - .atomic_commit = mtk_atomic_commit, - }; - --static const enum mtk_ddp_comp_id mt2701_mtk_ddp_main[] = { -+static enum mtk_ddp_comp_id mt2701_mtk_ddp_main[] = { - DDP_COMPONENT_OVL0, - DDP_COMPONENT_RDMA0, - DDP_COMPONENT_COLOR0, -@@ -141,12 +143,12 @@ static const enum mtk_ddp_comp_id mt2701_mtk_ddp_main[] = { - DDP_COMPONENT_DSI0, - }; - --static const enum mtk_ddp_comp_id mt2701_mtk_ddp_ext[] = { -+static enum mtk_ddp_comp_id mt2701_mtk_ddp_ext[] = { - DDP_COMPONENT_RDMA1, - DDP_COMPONENT_DPI0, - }; - --static const enum mtk_ddp_comp_id mt2712_mtk_ddp_main[] = { -+static enum mtk_ddp_comp_id mt2712_mtk_ddp_main[] = { - DDP_COMPONENT_OVL0, - DDP_COMPONENT_COLOR0, - DDP_COMPONENT_AAL0, -@@ -156,7 +158,7 @@ static const enum mtk_ddp_comp_id mt2712_mtk_ddp_main[] = { - DDP_COMPONENT_PWM0, - }; - --static const enum mtk_ddp_comp_id mt2712_mtk_ddp_ext[] = { -+static enum mtk_ddp_comp_id mt2712_mtk_ddp_ext[] = { - DDP_COMPONENT_OVL1, - DDP_COMPONENT_COLOR1, - DDP_COMPONENT_AAL1, -@@ -172,7 +174,7 @@ static const enum mtk_ddp_comp_id mt2712_mtk_ddp_third[] = { - DDP_COMPONENT_PWM2, - }; - --static const enum mtk_ddp_comp_id mt8173_mtk_ddp_main[] = { -+static enum mtk_ddp_comp_id mt8173_mtk_ddp_main[] = { - DDP_COMPONENT_OVL0, - DDP_COMPONENT_COLOR0, - DDP_COMPONENT_AAL0, -@@ -183,7 +185,7 @@ static const enum mtk_ddp_comp_id mt8173_mtk_ddp_main[] = { - DDP_COMPONENT_PWM0, - }; - --static const enum mtk_ddp_comp_id mt8173_mtk_ddp_ext[] = { -+static enum mtk_ddp_comp_id mt8173_mtk_ddp_ext[] = { - DDP_COMPONENT_OVL1, - DDP_COMPONENT_COLOR1, - DDP_COMPONENT_GAMMA, -@@ -472,6 +474,7 @@ static int mtk_drm_probe(struct platform_device *pdev) - - /* Iterate over sibling DISP function blocks */ - for_each_child_of_node(dev->of_node->parent, node) { -+ struct device_node *port, *ep, *remote; - const struct of_device_id *of_id; - enum mtk_ddp_comp_type comp_type; - int comp_id; -@@ -531,6 +534,32 @@ static int mtk_drm_probe(struct platform_device *pdev) - - private->ddp_comp[comp_id] = comp; - } -+ -+ if (comp_type != MTK_DSI && comp_type != MTK_DPI) { -+ port = of_graph_get_port_by_id(node, 0); -+ if (!port) -+ continue; -+ ep = of_get_child_by_name(port, "endpoint"); -+ of_node_put(port); -+ if (!ep) -+ continue; -+ remote = of_graph_get_remote_port_parent(ep); -+ of_node_put(ep); -+ if (!remote) -+ continue; -+ of_id = of_match_node(mtk_ddp_comp_dt_ids, remote); -+ if (!of_id) -+ continue; -+ comp_type = (enum mtk_ddp_comp_type)of_id->data; -+ for (i = 0; i < private->data->main_len - 1; i++) -+ if (private->data->main_path[i] == comp_id) -+ private->data->main_path[i + 1] = -+ mtk_ddp_comp_get_id(node, comp_type); -+ for (i = 0; i < private->data->ext_len - 1; i++) -+ if (private->data->ext_path[i] == comp_id) -+ private->data->ext_path[i + 1] = -+ mtk_ddp_comp_get_id(node, comp_type); -+ } - } - - if (!private->mutex_node) { -diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.h b/drivers/gpu/drm/mediatek/mtk_drm_drv.h -index ecc00ca3221d..256a3ff2e66e 100644 ---- a/drivers/gpu/drm/mediatek/mtk_drm_drv.h -+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.h -@@ -29,9 +29,9 @@ struct drm_property; - struct regmap; - - struct mtk_mmsys_driver_data { -- const enum mtk_ddp_comp_id *main_path; -+ enum mtk_ddp_comp_id *main_path; - unsigned int main_len; -- const enum mtk_ddp_comp_id *ext_path; -+ enum mtk_ddp_comp_id *ext_path; - unsigned int ext_len; - const enum mtk_ddp_comp_id *third_path; - unsigned int third_len; --- -2.19.1 - diff --git a/root/target/linux/mediatek/patches-4.19/0039-arm-dts-mt7623-add-a-performance-counter-unit-device.patch b/root/target/linux/mediatek/patches-4.19/0039-arm-dts-mt7623-add-a-performance-counter-unit-device.patch deleted file mode 100644 index 8d61ae13..00000000 --- a/root/target/linux/mediatek/patches-4.19/0039-arm-dts-mt7623-add-a-performance-counter-unit-device.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 687aeb6d2f7e36d8fffc23b5d767110b79beda59 Mon Sep 17 00:00:00 2001 -From: Ryder Lee -Date: Wed, 5 Sep 2018 18:22:17 +0800 -Subject: [PATCH 39/77] arm: dts: mt7623: add a performance counter unit device - node - -Add ARM PMU device node to enable hardware perf events. - -Signed-off-by: Ryder Lee ---- - arch/arm/boot/dts/mt7623.dtsi | 9 +++++++++ - 1 file changed, 9 insertions(+) - -diff --git a/arch/arm/boot/dts/mt7623.dtsi b/arch/arm/boot/dts/mt7623.dtsi -index af6b6228f8a8..d009b50f917e 100644 ---- a/arch/arm/boot/dts/mt7623.dtsi -+++ b/arch/arm/boot/dts/mt7623.dtsi -@@ -121,6 +121,15 @@ - }; - }; - -+ pmu { -+ compatible = "arm,cortex-a7-pmu"; -+ interrupts = , -+ , -+ , -+ ; -+ interrupt-affinity = <&cpu0>, <&cpu1>, <&cpu2>, <&cpu3>; -+ }; -+ - system_clk: dummy13m { - compatible = "fixed-clock"; - clock-frequency = <13000000>; --- -2.19.1 - diff --git a/root/target/linux/mediatek/patches-4.19/0040-arm-dts-mt7623-update-subsystem-clock-controller-dev.patch b/root/target/linux/mediatek/patches-4.19/0040-arm-dts-mt7623-update-subsystem-clock-controller-dev.patch deleted file mode 100644 index aa075e99..00000000 --- a/root/target/linux/mediatek/patches-4.19/0040-arm-dts-mt7623-update-subsystem-clock-controller-dev.patch +++ /dev/null @@ -1,76 +0,0 @@ -From 63b2249cb5ccf8ff0625cd707f243b3e882bc366 Mon Sep 17 00:00:00 2001 -From: Ryder Lee -Date: Wed, 5 Sep 2018 18:22:18 +0800 -Subject: [PATCH 40/77] arm: dts: mt7623: update subsystem clock controller - device nodes - -Update MT7623 subsystem clock controllers, inlcuding mmsys, imgsys, -vdecsys, g3dsys and bdpsys. - -Signed-off-by: Ryder Lee ---- - arch/arm/boot/dts/mt7623.dtsi | 41 +++++++++++++++++++++++++++++++++++ - 1 file changed, 41 insertions(+) - -diff --git a/arch/arm/boot/dts/mt7623.dtsi b/arch/arm/boot/dts/mt7623.dtsi -index d009b50f917e..35b0fa4112b0 100644 ---- a/arch/arm/boot/dts/mt7623.dtsi -+++ b/arch/arm/boot/dts/mt7623.dtsi -@@ -729,6 +729,39 @@ - clock-names = "wifi-dma"; - }; - -+ g3dsys: syscon@13000000 { -+ compatible = "mediatek,mt7623-g3dsys", -+ "mediatek,mt2701-g3dsys", -+ "syscon"; -+ reg = <0 0x13000000 0 0x200>; -+ #clock-cells = <1>; -+ #reset-cells = <1>; -+ }; -+ -+ mmsys: syscon@14000000 { -+ compatible = "mediatek,mt7623-mmsys", -+ "mediatek,mt2701-mmsys", -+ "syscon"; -+ reg = <0 0x14000000 0 0x1000>; -+ #clock-cells = <1>; -+ }; -+ -+ imgsys: syscon@15000000 { -+ compatible = "mediatek,mt7623-imgsys", -+ "mediatek,mt2701-imgsys", -+ "syscon"; -+ reg = <0 0x15000000 0 0x1000>; -+ #clock-cells = <1>; -+ }; -+ -+ vdecsys: syscon@16000000 { -+ compatible = "mediatek,mt7623-vdecsys", -+ "mediatek,mt2701-vdecsys", -+ "syscon"; -+ reg = <0 0x16000000 0 0x1000>; -+ #clock-cells = <1>; -+ }; -+ - hifsys: syscon@1a000000 { - compatible = "mediatek,mt7623-hifsys", - "mediatek,mt2701-hifsys", -@@ -983,6 +1016,14 @@ - power-domains = <&scpsys MT2701_POWER_DOMAIN_ETH>; - status = "disabled"; - }; -+ -+ bdpsys: syscon@1c000000 { -+ compatible = "mediatek,mt7623-bdpsys", -+ "mediatek,mt2701-bdpsys", -+ "syscon"; -+ reg = <0 0x1c000000 0 0x1000>; -+ #clock-cells = <1>; -+ }; - }; - - &pio { --- -2.19.1 - diff --git a/root/target/linux/mediatek/patches-4.19/0041-arm-dts-mt7623-add-iommu-smi-device-nodes.patch b/root/target/linux/mediatek/patches-4.19/0041-arm-dts-mt7623-add-iommu-smi-device-nodes.patch deleted file mode 100644 index 5a485788..00000000 --- a/root/target/linux/mediatek/patches-4.19/0041-arm-dts-mt7623-add-iommu-smi-device-nodes.patch +++ /dev/null @@ -1,120 +0,0 @@ -From d6515baf44e1f6aa4809edf0d0ca314ce9e35a66 Mon Sep 17 00:00:00 2001 -From: Ryder Lee -Date: Wed, 5 Sep 2018 18:22:19 +0800 -Subject: [PATCH 41/77] arm: dts: mt7623: add iommu/smi device nodes - -Add iommu/smi device nodes for MT7623. - -Signed-off-by: Ryder Lee ---- - arch/arm/boot/dts/mt7623.dtsi | 59 +++++++++++++++++++++++++++++++++++ - 1 file changed, 59 insertions(+) - -diff --git a/arch/arm/boot/dts/mt7623.dtsi b/arch/arm/boot/dts/mt7623.dtsi -index 35b0fa4112b0..7864c3804377 100644 ---- a/arch/arm/boot/dts/mt7623.dtsi -+++ b/arch/arm/boot/dts/mt7623.dtsi -@@ -13,6 +13,7 @@ - #include - #include - #include -+#include - #include - #include - -@@ -288,6 +289,17 @@ - clock-names = "system-clk", "rtc-clk"; - }; - -+ smi_common: smi@1000c000 { -+ compatible = "mediatek,mt7623-smi-common", -+ "mediatek,mt2701-smi-common"; -+ reg = <0 0x1000c000 0 0x1000>; -+ clocks = <&infracfg CLK_INFRA_SMI>, -+ <&mmsys CLK_MM_SMI_COMMON>, -+ <&infracfg CLK_INFRA_SMI>; -+ clock-names = "apb", "smi", "async"; -+ power-domains = <&scpsys MT2701_POWER_DOMAIN_DISP>; -+ }; -+ - pwrap: pwrap@1000d000 { - compatible = "mediatek,mt7623-pwrap", - "mediatek,mt2701-pwrap"; -@@ -319,6 +331,17 @@ - reg = <0 0x10200100 0 0x1c>; - }; - -+ iommu: mmsys_iommu@10205000 { -+ compatible = "mediatek,mt7623-m4u", -+ "mediatek,mt2701-m4u"; -+ reg = <0 0x10205000 0 0x1000>; -+ interrupts = ; -+ clocks = <&infracfg CLK_INFRA_M4U>; -+ clock-names = "bclk"; -+ mediatek,larbs = <&larb0 &larb1 &larb2>; -+ #iommu-cells = <1>; -+ }; -+ - efuse: efuse@10206000 { - compatible = "mediatek,mt7623-efuse", - "mediatek,mt8173-efuse"; -@@ -746,6 +769,18 @@ - #clock-cells = <1>; - }; - -+ larb0: larb@14010000 { -+ compatible = "mediatek,mt7623-smi-larb", -+ "mediatek,mt2701-smi-larb"; -+ reg = <0 0x14010000 0 0x1000>; -+ mediatek,smi = <&smi_common>; -+ mediatek,larb-id = <0>; -+ clocks = <&mmsys CLK_MM_SMI_LARB0>, -+ <&mmsys CLK_MM_SMI_LARB0>; -+ clock-names = "apb", "smi"; -+ power-domains = <&scpsys MT2701_POWER_DOMAIN_DISP>; -+ }; -+ - imgsys: syscon@15000000 { - compatible = "mediatek,mt7623-imgsys", - "mediatek,mt2701-imgsys", -@@ -754,6 +789,18 @@ - #clock-cells = <1>; - }; - -+ larb2: larb@15001000 { -+ compatible = "mediatek,mt7623-smi-larb", -+ "mediatek,mt2701-smi-larb"; -+ reg = <0 0x15001000 0 0x1000>; -+ mediatek,smi = <&smi_common>; -+ mediatek,larb-id = <2>; -+ clocks = <&imgsys CLK_IMG_SMI_COMM>, -+ <&imgsys CLK_IMG_SMI_COMM>; -+ clock-names = "apb", "smi"; -+ power-domains = <&scpsys MT2701_POWER_DOMAIN_ISP>; -+ }; -+ - vdecsys: syscon@16000000 { - compatible = "mediatek,mt7623-vdecsys", - "mediatek,mt2701-vdecsys", -@@ -762,6 +809,18 @@ - #clock-cells = <1>; - }; - -+ larb1: larb@16010000 { -+ compatible = "mediatek,mt7623-smi-larb", -+ "mediatek,mt2701-smi-larb"; -+ reg = <0 0x16010000 0 0x1000>; -+ mediatek,smi = <&smi_common>; -+ mediatek,larb-id = <1>; -+ clocks = <&vdecsys CLK_VDEC_CKGEN>, -+ <&vdecsys CLK_VDEC_LARB>; -+ clock-names = "apb", "smi"; -+ power-domains = <&scpsys MT2701_POWER_DOMAIN_VDEC>; -+ }; -+ - hifsys: syscon@1a000000 { - compatible = "mediatek,mt7623-hifsys", - "mediatek,mt2701-hifsys", --- -2.19.1 - diff --git a/root/target/linux/mediatek/patches-4.19/0042-arm-dts-mt7623-add-jpeg-decoder-device-node.patch b/root/target/linux/mediatek/patches-4.19/0042-arm-dts-mt7623-add-jpeg-decoder-device-node.patch deleted file mode 100644 index 66edb33f..00000000 --- a/root/target/linux/mediatek/patches-4.19/0042-arm-dts-mt7623-add-jpeg-decoder-device-node.patch +++ /dev/null @@ -1,41 +0,0 @@ -From bd988dc66763555c2aa6509b060fa5b3ceb682a6 Mon Sep 17 00:00:00 2001 -From: Ryder Lee -Date: Wed, 5 Sep 2018 18:22:20 +0800 -Subject: [PATCH 42/77] arm: dts: mt7623: add jpeg decoder device node - -Add a jpeg decoder device node for MT7623. - -Signed-off-by: Ryder Lee ---- - arch/arm/boot/dts/mt7623.dtsi | 15 +++++++++++++++ - 1 file changed, 15 insertions(+) - -diff --git a/arch/arm/boot/dts/mt7623.dtsi b/arch/arm/boot/dts/mt7623.dtsi -index 7864c3804377..ce9fb23eb5cb 100644 ---- a/arch/arm/boot/dts/mt7623.dtsi -+++ b/arch/arm/boot/dts/mt7623.dtsi -@@ -801,6 +801,21 @@ - power-domains = <&scpsys MT2701_POWER_DOMAIN_ISP>; - }; - -+ jpegdec: jpegdec@15004000 { -+ compatible = "mediatek,mt7623-jpgdec", -+ "mediatek,mt2701-jpgdec"; -+ reg = <0 0x15004000 0 0x1000>; -+ interrupts = ; -+ clocks = <&imgsys CLK_IMG_JPGDEC_SMI>, -+ <&imgsys CLK_IMG_JPGDEC>; -+ clock-names = "jpgdec-smi", -+ "jpgdec"; -+ power-domains = <&scpsys MT2701_POWER_DOMAIN_ISP>; -+ mediatek,larb = <&larb2>; -+ iommus = <&iommu MT2701_M4U_PORT_JPGDEC_WDMA>, -+ <&iommu MT2701_M4U_PORT_JPGDEC_BSDMA>; -+ }; -+ - vdecsys: syscon@16000000 { - compatible = "mediatek,mt7623-vdecsys", - "mediatek,mt2701-vdecsys", --- -2.19.1 - diff --git a/root/target/linux/mediatek/patches-4.19/0043-arm-dts-mt7623-add-display-subsystem-related-device-.patch b/root/target/linux/mediatek/patches-4.19/0043-arm-dts-mt7623-add-display-subsystem-related-device-.patch deleted file mode 100644 index de1842b4..00000000 --- a/root/target/linux/mediatek/patches-4.19/0043-arm-dts-mt7623-add-display-subsystem-related-device-.patch +++ /dev/null @@ -1,493 +0,0 @@ -From c7dbe108de2c9f47f952910f424d1fa9a3470a5b Mon Sep 17 00:00:00 2001 -From: Ryder Lee -Date: Wed, 5 Sep 2018 22:09:27 +0800 -Subject: [PATCH 43/77] arm: dts: mt7623: add display subsystem related device - nodes - -Add display subsystem related device nodes for MT7623. - -Cc: CK Hu -Signed-off-by: chunhui dai -Signed-off-by: Bibby Hsieh -Signed-off-by: Ryder Lee ---- - arch/arm/boot/dts/mt7623.dtsi | 177 ++++++++++++++++++ - arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts | 85 +++++++++ - arch/arm/boot/dts/mt7623n-rfb-emmc.dts | 85 +++++++++ - 3 files changed, 347 insertions(+) - -diff --git a/arch/arm/boot/dts/mt7623.dtsi b/arch/arm/boot/dts/mt7623.dtsi -index ce9fb23eb5cb..619843514d74 100644 ---- a/arch/arm/boot/dts/mt7623.dtsi -+++ b/arch/arm/boot/dts/mt7623.dtsi -@@ -23,6 +23,11 @@ - #address-cells = <2>; - #size-cells = <2>; - -+ aliases { -+ rdma0 = &rdma0; -+ rdma1 = &rdma1; -+ }; -+ - cpu_opp_table: opp-table { - compatible = "operating-points-v2"; - opp-shared; -@@ -313,6 +318,25 @@ - clock-names = "spi", "wrap"; - }; - -+ mipi_tx0: mipi-dphy@10010000 { -+ compatible = "mediatek,mt7623-mipi-tx", -+ "mediatek,mt2701-mipi-tx"; -+ reg = <0 0x10010000 0 0x90>; -+ clocks = <&clk26m>; -+ clock-output-names = "mipi_tx0_pll"; -+ #clock-cells = <0>; -+ #phy-cells = <0>; -+ }; -+ -+ cec: cec@10012000 { -+ compatible = "mediatek,mt7623-cec", -+ "mediatek,mt8173-cec"; -+ reg = <0 0x10012000 0 0xbc>; -+ interrupts = ; -+ clocks = <&infracfg CLK_INFRA_CEC>; -+ status = "disabled"; -+ }; -+ - cir: cir@10013000 { - compatible = "mediatek,mt7623-cir"; - reg = <0 0x10013000 0 0x1000>; -@@ -361,6 +385,18 @@ - #clock-cells = <1>; - }; - -+ hdmi_phy: phy@10209100 { -+ compatible = "mediatek,mt7623-hdmi-phy", -+ "mediatek,mt2701-hdmi-phy"; -+ reg = <0 0x10209100 0 0x24>; -+ clocks = <&apmixedsys CLK_APMIXED_HDMI_REF>; -+ clock-names = "pll_ref"; -+ clock-output-names = "hdmitx_dig_cts"; -+ #clock-cells = <0>; -+ #phy-cells = <0>; -+ status = "disabled"; -+ }; -+ - rng: rng@1020f000 { - compatible = "mediatek,mt7623-rng"; - reg = <0 0x1020f000 0 0x1000>; -@@ -573,6 +609,16 @@ - status = "disabled"; - }; - -+ hdmiddc0: i2c@11013000 { -+ compatible = "mediatek,mt7623-hdmi-ddc", -+ "mediatek,mt8173-hdmi-ddc"; -+ interrupts = ; -+ reg = <0 0x11013000 0 0x1C>; -+ clocks = <&pericfg CLK_PERI_I2C3>; -+ clock-names = "ddc-i2c"; -+ status = "disabled"; -+ }; -+ - nor_flash: spi@11014000 { - compatible = "mediatek,mt7623-nor", - "mediatek,mt8173-nor"; -@@ -769,6 +815,84 @@ - #clock-cells = <1>; - }; - -+ display_components: dispsys@14000000 { -+ compatible = "mediatek,mt7623-mmsys", -+ "mediatek,mt2701-mmsys"; -+ reg = <0 0x14000000 0 0x1000>; -+ power-domains = <&scpsys MT2701_POWER_DOMAIN_DISP>; -+ }; -+ -+ ovl@14007000 { -+ compatible = "mediatek,mt7623-disp-ovl", -+ "mediatek,mt2701-disp-ovl"; -+ reg = <0 0x14007000 0 0x1000>; -+ interrupts = ; -+ clocks = <&mmsys CLK_MM_DISP_OVL>; -+ iommus = <&iommu MT2701_M4U_PORT_DISP_OVL_0>; -+ mediatek,larb = <&larb0>; -+ }; -+ -+ rdma0: rdma@14008000 { -+ compatible = "mediatek,mt7623-disp-rdma", -+ "mediatek,mt2701-disp-rdma"; -+ reg = <0 0x14008000 0 0x1000>; -+ interrupts = ; -+ clocks = <&mmsys CLK_MM_DISP_RDMA>; -+ iommus = <&iommu MT2701_M4U_PORT_DISP_RDMA>; -+ mediatek,larb = <&larb0>; -+ }; -+ -+ wdma@14009000 { -+ compatible = "mediatek,mt7623-disp-wdma", -+ "mediatek,mt2701-disp-wdma"; -+ reg = <0 0x14009000 0 0x1000>; -+ interrupts = ; -+ clocks = <&mmsys CLK_MM_DISP_WDMA>; -+ iommus = <&iommu MT2701_M4U_PORT_DISP_WDMA>; -+ mediatek,larb = <&larb0>; -+ }; -+ -+ bls: pwm@1400a000 { -+ compatible = "mediatek,mt7623-disp-pwm", -+ "mediatek,mt2701-disp-pwm"; -+ reg = <0 0x1400a000 0 0x1000>; -+ #pwm-cells = <2>; -+ clocks = <&mmsys CLK_MM_MDP_BLS_26M>, -+ <&mmsys CLK_MM_DISP_BLS>; -+ clock-names = "main", "mm"; -+ status = "disabled"; -+ }; -+ -+ color@1400b000 { -+ compatible = "mediatek,mt7623-disp-color", -+ "mediatek,mt2701-disp-color"; -+ reg = <0 0x1400b000 0 0x1000>; -+ interrupts = ; -+ clocks = <&mmsys CLK_MM_DISP_COLOR>; -+ }; -+ -+ dsi: dsi@1400c000 { -+ compatible = "mediatek,mt7623-dsi", -+ "mediatek,mt2701-dsi"; -+ reg = <0 0x1400c000 0 0x1000>; -+ interrupts = ; -+ clocks = <&mmsys CLK_MM_DSI_ENGINE>, -+ <&mmsys CLK_MM_DSI_DIG>, -+ <&mipi_tx0>; -+ clock-names = "engine", "digital", "hs"; -+ phys = <&mipi_tx0>; -+ phy-names = "dphy"; -+ status = "disabled"; -+ }; -+ -+ mutex: mutex@1400e000 { -+ compatible = "mediatek,mt7623-disp-mutex", -+ "mediatek,mt2701-disp-mutex"; -+ reg = <0 0x1400e000 0 0x1000>; -+ interrupts = ; -+ clocks = <&mmsys CLK_MM_MUTEX_32K>; -+ }; -+ - larb0: larb@14010000 { - compatible = "mediatek,mt7623-smi-larb", - "mediatek,mt2701-smi-larb"; -@@ -781,6 +905,44 @@ - power-domains = <&scpsys MT2701_POWER_DOMAIN_DISP>; - }; - -+ rdma1: rdma@14012000 { -+ compatible = "mediatek,mt7623-disp-rdma", -+ "mediatek,mt2701-disp-rdma"; -+ reg = <0 0x14012000 0 0x1000>; -+ interrupts = ; -+ clocks = <&mmsys CLK_MM_DISP_RDMA1>; -+ iommus = <&iommu MT2701_M4U_PORT_DISP_RDMA1>; -+ mediatek,larb = <&larb0>; -+ }; -+ -+ dpi0: dpi@14014000 { -+ compatible = "mediatek,mt7623-dpi", -+ "mediatek,mt2701-dpi"; -+ reg = <0 0x14014000 0 0x1000>; -+ interrupts = ; -+ clocks = <&mmsys CLK_MM_DPI1_DIGL>, -+ <&mmsys CLK_MM_DPI1_ENGINE>, -+ <&topckgen CLK_TOP_TVDPLL>; -+ clock-names = "pixel", "engine", "pll"; -+ status = "disabled"; -+ }; -+ -+ hdmi0: hdmi@14015000 { -+ compatible = "mediatek,mt7623-hdmi", -+ "mediatek,mt8173-hdmi"; -+ reg = <0 0x14015000 0 0x400>; -+ clocks = <&mmsys CLK_MM_HDMI_PIXEL>, -+ <&mmsys CLK_MM_HDMI_PLL>, -+ <&mmsys CLK_MM_HDMI_AUDIO>, -+ <&mmsys CLK_MM_HDMI_SPDIF>; -+ clock-names = "pixel", "pll", "bclk", "spdif"; -+ phys = <&hdmi_phy>; -+ phy-names = "hdmi"; -+ mediatek,syscon-hdmi = <&mmsys 0x900>; -+ cec = <&cec>; -+ status = "disabled"; -+ }; -+ - imgsys: syscon@15000000 { - compatible = "mediatek,mt7623-imgsys", - "mediatek,mt2701-imgsys", -@@ -1108,6 +1270,21 @@ - }; - }; - -+ hdmi_pins_a: hdmi-default { -+ pins-hdmi { -+ pinmux = ; -+ input-enable; -+ bias-pull-down; -+ }; -+ }; -+ -+ hdmi_ddc_pins_a: hdmi_ddc-default { -+ pins-hdmi-ddc { -+ pinmux = , -+ ; -+ }; -+ }; -+ - i2c0_pins_a: i2c0-default { - pins-i2c0 { - pinmux = , -diff --git a/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts b/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts -index 4c6e53d9e736..d97edde586ad 100644 ---- a/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts -+++ b/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts -@@ -22,6 +22,19 @@ - stdout-path = "serial2:115200n8"; - }; - -+ connector { -+ compatible = "hdmi-connector"; -+ label = "hdmi"; -+ type = "d"; -+ ddc-i2c-bus = <&hdmiddc0>; -+ -+ port { -+ hdmi_connector_in: endpoint { -+ remote-endpoint = <&hdmi0_out>; -+ }; -+ }; -+ }; -+ - cpus { - cpu@0 { - proc-supply = <&mt6323_vproc_reg>; -@@ -127,10 +140,24 @@ - }; - }; - -+&bls { -+ status = "okay"; -+ -+ port { -+ bls_out: endpoint { -+ remote-endpoint = <&dpi0_in>; -+ }; -+ }; -+}; -+ - &btif { - status = "okay"; - }; - -+&cec { -+ status = "okay"; -+}; -+ - &cir { - pinctrl-names = "default"; - pinctrl-0 = <&cir_pins_a>; -@@ -141,6 +168,28 @@ - status = "okay"; - }; - -+&dpi0 { -+ status = "okay"; -+ -+ ports { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ port@0 { -+ reg = <0>; -+ dpi0_out: endpoint { -+ remote-endpoint = <&hdmi0_in>; -+ }; -+ }; -+ -+ port@1 { -+ reg = <1>; -+ dpi0_in: endpoint { -+ remote-endpoint = <&bls_out>; -+ }; -+ }; -+ }; -+}; -+ - ð { - status = "okay"; - -@@ -240,6 +289,42 @@ - }; - }; - -+&hdmi0 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&hdmi_pins_a>; -+ status = "okay"; -+ -+ ports { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ port@0 { -+ reg = <0>; -+ hdmi0_in: endpoint { -+ remote-endpoint = <&dpi0_out>; -+ }; -+ }; -+ -+ port@1 { -+ reg = <1>; -+ hdmi0_out: endpoint { -+ remote-endpoint = <&hdmi_connector_in>; -+ }; -+ }; -+ }; -+}; -+ -+&hdmiddc0 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&hdmi_ddc_pins_a>; -+ status = "okay"; -+}; -+ -+&hdmi_phy { -+ mediatek,ibias = <0xa>; -+ mediatek,ibias_up = <0x1c>; -+ status = "okay"; -+}; -+ - &i2c0 { - pinctrl-names = "default"; - pinctrl-0 = <&i2c0_pins_a>; -diff --git a/arch/arm/boot/dts/mt7623n-rfb-emmc.dts b/arch/arm/boot/dts/mt7623n-rfb-emmc.dts -index b7606130ade9..3e5911d8d6bc 100644 ---- a/arch/arm/boot/dts/mt7623n-rfb-emmc.dts -+++ b/arch/arm/boot/dts/mt7623n-rfb-emmc.dts -@@ -24,6 +24,19 @@ - stdout-path = "serial2:115200n8"; - }; - -+ connector { -+ compatible = "hdmi-connector"; -+ label = "hdmi"; -+ type = "d"; -+ ddc-i2c-bus = <&hdmiddc0>; -+ -+ port { -+ hdmi_connector_in: endpoint { -+ remote-endpoint = <&hdmi0_out>; -+ }; -+ }; -+ }; -+ - cpus { - cpu@0 { - proc-supply = <&mt6323_vproc_reg>; -@@ -106,10 +119,24 @@ - }; - }; - -+&bls { -+ status = "okay"; -+ -+ port { -+ bls_out: endpoint { -+ remote-endpoint = <&dpi0_in>; -+ }; -+ }; -+}; -+ - &btif { - status = "okay"; - }; - -+&cec { -+ status = "okay"; -+}; -+ - &cir { - pinctrl-names = "default"; - pinctrl-0 = <&cir_pins_a>; -@@ -120,6 +147,28 @@ - status = "okay"; - }; - -+&dpi0 { -+ status = "okay"; -+ -+ ports { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ port@0 { -+ reg = <0>; -+ dpi0_out: endpoint { -+ remote-endpoint = <&hdmi0_in>; -+ }; -+ }; -+ -+ port@1 { -+ reg = <1>; -+ dpi0_in: endpoint { -+ remote-endpoint = <&bls_out>; -+ }; -+ }; -+ }; -+}; -+ - ð { - status = "okay"; - -@@ -202,6 +251,42 @@ - }; - }; - -+&hdmi0 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&hdmi_pins_a>; -+ status = "okay"; -+ -+ ports { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ port@0 { -+ reg = <0>; -+ hdmi0_in: endpoint { -+ remote-endpoint = <&dpi0_out>; -+ }; -+ }; -+ -+ port@1 { -+ reg = <1>; -+ hdmi0_out: endpoint { -+ remote-endpoint = <&hdmi_connector_in>; -+ }; -+ }; -+ }; -+}; -+ -+&hdmiddc0 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&hdmi_ddc_pins_a>; -+ status = "okay"; -+}; -+ -+&hdmi_phy { -+ mediatek,ibias = <0xa>; -+ mediatek,ibias_up = <0x1c>; -+ status = "okay"; -+}; -+ - &i2c0 { - pinctrl-names = "default"; - pinctrl-0 = <&i2c0_pins_a>; --- -2.19.1 - diff --git a/root/target/linux/mediatek/patches-4.19/0044-fix-boot-up-for-720-and-480-but-1080.patch b/root/target/linux/mediatek/patches-4.19/0044-fix-boot-up-for-720-and-480-but-1080.patch deleted file mode 100644 index 71dfebd4..00000000 --- a/root/target/linux/mediatek/patches-4.19/0044-fix-boot-up-for-720-and-480-but-1080.patch +++ /dev/null @@ -1,72 +0,0 @@ -From fa095b2751309a70d42d9d2f2f0881731b090d18 Mon Sep 17 00:00:00 2001 -From: chunhui dai -Date: Wed, 31 Oct 2018 16:59:34 +0800 -Subject: [PATCH 44/77] fix boot up for 720 and 480 but 1080 - -1080 plg in/out with ng/ok - -[ALPSxxxxxxxx] - -[Detail] - -[Solution] - -Change-Id: Icd395eaf635a6cfe03f8f0508ed97ab40cbf6632 -CR-Id: -Feature: ---- - drivers/gpu/drm/mediatek/mtk_hdmi_phy.c | 3 +++ - drivers/gpu/drm/mediatek/mtk_hdmi_phy.h | 1 + - drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c | 3 ++- - 3 files changed, 6 insertions(+), 1 deletion(-) - -diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi_phy.c b/drivers/gpu/drm/mediatek/mtk_hdmi_phy.c -index 4ef9c57ffd44..40e08df57f48 100644 ---- a/drivers/gpu/drm/mediatek/mtk_hdmi_phy.c -+++ b/drivers/gpu/drm/mediatek/mtk_hdmi_phy.c -@@ -209,6 +209,9 @@ static int mtk_hdmi_phy_probe(struct platform_device *pdev) - return PTR_ERR(phy_provider); - } - -+ if (hdmi_phy->conf->pll_default_off) -+ hdmi_phy->conf->hdmi_phy_disable_tmds(hdmi_phy); -+ - return of_clk_add_provider(dev->of_node, of_clk_src_simple_get, - hdmi_phy->pll); - } -diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi_phy.h b/drivers/gpu/drm/mediatek/mtk_hdmi_phy.h -index f39b1fc66612..a173a27d7a40 100644 ---- a/drivers/gpu/drm/mediatek/mtk_hdmi_phy.h -+++ b/drivers/gpu/drm/mediatek/mtk_hdmi_phy.h -@@ -21,6 +21,7 @@ struct mtk_hdmi_phy; - - struct mtk_hdmi_phy_conf { - bool tz_disabled; -+ bool pll_default_off; - const struct clk_ops *hdmi_phy_clk_ops; - void (*hdmi_phy_enable_tmds)(struct mtk_hdmi_phy *hdmi_phy); - void (*hdmi_phy_disable_tmds)(struct mtk_hdmi_phy *hdmi_phy); -diff --git a/drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c b/drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c -index fcc42dc6ea7f..534bcbc9f3b7 100644 ---- a/drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c -+++ b/drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c -@@ -116,7 +116,7 @@ static int mtk_hdmi_pll_set_rate(struct clk_hw *hw, unsigned long rate, - - if (rate <= 64000000) - pos_div = 3; -- else if (rate <= 12800000) -+ else if (rate <= 128000000) - pos_div = 1; - else - pos_div = 1; -@@ -202,6 +202,7 @@ static void mtk_hdmi_phy_disable_tmds(struct mtk_hdmi_phy *hdmi_phy) - - struct mtk_hdmi_phy_conf mtk_hdmi_phy_2701_conf = { - .tz_disabled = true, -+ .pll_default_off = true, - .hdmi_phy_clk_ops = &mtk_hdmi_phy_pll_ops, - .hdmi_phy_enable_tmds = mtk_hdmi_phy_enable_tmds, - .hdmi_phy_disable_tmds = mtk_hdmi_phy_disable_tmds, --- -2.19.1 - diff --git a/root/target/linux/mediatek/patches-4.19/0045-using-different-round-rate-for-mt7623.patch b/root/target/linux/mediatek/patches-4.19/0045-using-different-round-rate-for-mt7623.patch deleted file mode 100644 index 5b2214a5..00000000 --- a/root/target/linux/mediatek/patches-4.19/0045-using-different-round-rate-for-mt7623.patch +++ /dev/null @@ -1,103 +0,0 @@ -From 4501501b8f55b277f219eaf7e863d91ddb1d8af7 Mon Sep 17 00:00:00 2001 -From: chunhui dai -Date: Wed, 31 Oct 2018 17:59:50 +0800 -Subject: [PATCH 45/77] using different round rate for mt7623 - -Change-Id: Ifac315b09d691fe2c056212dd59ae50212417d58 -CR-Id: -Feature: ---- - drivers/gpu/drm/mediatek/mtk_hdmi_phy.c | 14 -------------- - drivers/gpu/drm/mediatek/mtk_hdmi_phy.h | 2 -- - drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c | 11 +++++++++++ - drivers/gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c | 14 ++++++++++++++ - 4 files changed, 25 insertions(+), 16 deletions(-) - -diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi_phy.c b/drivers/gpu/drm/mediatek/mtk_hdmi_phy.c -index 40e08df57f48..f014d65fa5ad 100644 ---- a/drivers/gpu/drm/mediatek/mtk_hdmi_phy.c -+++ b/drivers/gpu/drm/mediatek/mtk_hdmi_phy.c -@@ -15,20 +15,6 @@ static const struct phy_ops mtk_hdmi_phy_dev_ops = { - .owner = THIS_MODULE, - }; - --long mtk_hdmi_pll_round_rate(struct clk_hw *hw, unsigned long rate, -- unsigned long *parent_rate) --{ -- struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw); -- -- hdmi_phy->pll_rate = rate; -- if (rate <= 74250000) -- *parent_rate = rate; -- else -- *parent_rate = rate / 2; -- -- return rate; --} -- - unsigned long mtk_hdmi_pll_recalc_rate(struct clk_hw *hw, - unsigned long parent_rate) - { -diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi_phy.h b/drivers/gpu/drm/mediatek/mtk_hdmi_phy.h -index a173a27d7a40..76e352d088d0 100644 ---- a/drivers/gpu/drm/mediatek/mtk_hdmi_phy.h -+++ b/drivers/gpu/drm/mediatek/mtk_hdmi_phy.h -@@ -49,8 +49,6 @@ void mtk_hdmi_phy_set_bits(struct mtk_hdmi_phy *hdmi_phy, u32 offset, - void mtk_hdmi_phy_mask(struct mtk_hdmi_phy *hdmi_phy, u32 offset, - u32 val, u32 mask); - struct mtk_hdmi_phy *to_mtk_hdmi_phy(struct clk_hw *hw); --long mtk_hdmi_pll_round_rate(struct clk_hw *hw, unsigned long rate, -- unsigned long *parent_rate); - unsigned long mtk_hdmi_pll_recalc_rate(struct clk_hw *hw, - unsigned long parent_rate); - -diff --git a/drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c b/drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c -index 534bcbc9f3b7..2f87d0320882 100644 ---- a/drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c -+++ b/drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c -@@ -154,6 +154,17 @@ static int mtk_hdmi_pll_set_rate(struct clk_hw *hw, unsigned long rate, - return 0; - } - -+static long mtk_hdmi_pll_round_rate(struct clk_hw *hw, unsigned long rate, -+ unsigned long *parent_rate) -+{ -+ struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw); -+ -+ hdmi_phy->pll_rate = rate; -+ *parent_rate = rate; -+ -+ return rate; -+} -+ - static const struct clk_ops mtk_hdmi_phy_pll_ops = { - .prepare = mtk_hdmi_pll_prepare, - .unprepare = mtk_hdmi_pll_unprepare, -diff --git a/drivers/gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c b/drivers/gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c -index ed5916b27658..d8cb252c6781 100644 ---- a/drivers/gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c -+++ b/drivers/gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c -@@ -285,6 +285,20 @@ static int mtk_hdmi_pll_set_rate(struct clk_hw *hw, unsigned long rate, - return 0; - } - -+static long mtk_hdmi_pll_round_rate(struct clk_hw *hw, unsigned long rate, -+ unsigned long *parent_rate) -+{ -+ struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw); -+ -+ hdmi_phy->pll_rate = rate; -+ if (rate <= 74250000) -+ *parent_rate = rate; -+ else -+ *parent_rate = rate / 2; -+ -+ return rate; -+} -+ - static const struct clk_ops mtk_hdmi_phy_pll_ops = { - .prepare = mtk_hdmi_pll_prepare, - .unprepare = mtk_hdmi_pll_unprepare, --- -2.19.1 - diff --git a/root/target/linux/mediatek/patches-4.19/0046-hdmi-fix-possible_crtcs.patch b/root/target/linux/mediatek/patches-4.19/0046-hdmi-fix-possible_crtcs.patch deleted file mode 100644 index 284ced83..00000000 --- a/root/target/linux/mediatek/patches-4.19/0046-hdmi-fix-possible_crtcs.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 1c978fae6f6112b46d4815c0054fbeab0274a363 Mon Sep 17 00:00:00 2001 -From: Ryder Lee -Date: Fri, 16 Nov 2018 16:33:00 +0100 -Subject: [PATCH 46/77] [hdmi] fix possible_crtcs - -source: http://forum.banana-pi.org/t/kernel-4-19-rc1-for-testers/6618/52 ---- - drivers/gpu/drm/mediatek/mtk_dpi.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c -index 62a9d47df948..a066b0755119 100644 ---- a/drivers/gpu/drm/mediatek/mtk_dpi.c -+++ b/drivers/gpu/drm/mediatek/mtk_dpi.c -@@ -610,7 +610,7 @@ static int mtk_dpi_bind(struct device *dev, struct device *master, void *data) - drm_encoder_helper_add(&dpi->encoder, &mtk_dpi_encoder_helper_funcs); - - /* Currently DPI0 is fixed to be driven by OVL1 */ -- dpi->encoder.possible_crtcs = BIT(1); -+ dpi->encoder.possible_crtcs = BIT(0)|BIT(1); - - ret = drm_bridge_attach(&dpi->encoder, dpi->bridge, NULL); - if (ret) { --- -2.19.1 - diff --git a/root/target/linux/mediatek/patches-4.19/0047-hdmi-added-options-to-defconfig.patch b/root/target/linux/mediatek/patches-4.19/0047-hdmi-added-options-to-defconfig.patch deleted file mode 100644 index 4e173116..00000000 --- a/root/target/linux/mediatek/patches-4.19/0047-hdmi-added-options-to-defconfig.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 88aa4bffe7e5b38e8596e5f09e7b40e8bc112a24 Mon Sep 17 00:00:00 2001 -From: Frank Wunderlich -Date: Fri, 16 Nov 2018 16:40:16 +0100 -Subject: [PATCH 47/77] [hdmi] added options to defconfig - ---- - arch/arm/configs/mt7623n_evb_fwu_defconfig | 11 +++++++++++ - 1 file changed, 11 insertions(+) - -diff --git a/arch/arm/configs/mt7623n_evb_fwu_defconfig b/arch/arm/configs/mt7623n_evb_fwu_defconfig -index f5e7a0edda0e..5932b552f2ea 100644 ---- a/arch/arm/configs/mt7623n_evb_fwu_defconfig -+++ b/arch/arm/configs/mt7623n_evb_fwu_defconfig -@@ -652,3 +652,14 @@ CONFIG_POWER_RESET_MT6397_RTC=y - - #CONFIG_NET_MEDIATEK_HW_QOS=m - -+#Graphic -+CONFIG_DRM=y -+CONFIG_DRM_MEDIATEK=y -+CONFIG_DRM_MEDIATEK_HDMI=y -+CONFIG_DRM_ARM=y -+CONFIG_DRM_MALI_DISPLAY=y -+CONFIG_COMMON_CLK_MT2701_MMSYS=y -+CONFIG_COMMON_CLK_MT2701_IMGSYS=y -+CONFIG_COMMON_CLK_MT2701_VDECSYS=y -+#CONFIG_FRAMEBUFFER_CONSOLE=y -+#CONFIG_DRM_FBDEV_EMULATION=y --- -2.19.1 - diff --git a/root/target/linux/mediatek/patches-4.19/0049-hdmi-added-fbdev-options.patch b/root/target/linux/mediatek/patches-4.19/0049-hdmi-added-fbdev-options.patch deleted file mode 100644 index 4ca5483f..00000000 --- a/root/target/linux/mediatek/patches-4.19/0049-hdmi-added-fbdev-options.patch +++ /dev/null @@ -1,24 +0,0 @@ -From 7d0222b1fd42f22f0590b71c0e42660974c492d2 Mon Sep 17 00:00:00 2001 -From: Frank Wunderlich -Date: Fri, 16 Nov 2018 17:27:50 +0100 -Subject: [PATCH 49/77] [hdmi] added fbdev-options - ---- - arch/arm/configs/mt7623n_evb_fwu_defconfig | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/arch/arm/configs/mt7623n_evb_fwu_defconfig b/arch/arm/configs/mt7623n_evb_fwu_defconfig -index 5932b552f2ea..668a6c45177d 100644 ---- a/arch/arm/configs/mt7623n_evb_fwu_defconfig -+++ b/arch/arm/configs/mt7623n_evb_fwu_defconfig -@@ -661,5 +661,5 @@ CONFIG_DRM_MALI_DISPLAY=y - CONFIG_COMMON_CLK_MT2701_MMSYS=y - CONFIG_COMMON_CLK_MT2701_IMGSYS=y - CONFIG_COMMON_CLK_MT2701_VDECSYS=y --#CONFIG_FRAMEBUFFER_CONSOLE=y --#CONFIG_DRM_FBDEV_EMULATION=y -+CONFIG_FRAMEBUFFER_CONSOLE=y -+CONFIG_DRM_FBDEV_EMULATION=y --- -2.19.1 - diff --git a/root/target/linux/mediatek/patches-4.19/0050-BT-fix-Bluetooth.patch b/root/target/linux/mediatek/patches-4.19/0050-BT-fix-Bluetooth.patch deleted file mode 100644 index e3f7ee41..00000000 --- a/root/target/linux/mediatek/patches-4.19/0050-BT-fix-Bluetooth.patch +++ /dev/null @@ -1,69 +0,0 @@ -From c0603006d7f020bbcb42bed36127fbfe94b1b512 Mon Sep 17 00:00:00 2001 -From: Oleksii Shevchuk -Date: Fri, 11 Jan 2019 18:34:01 +0100 -Subject: [PATCH 50/77] [BT] fix Bluetooth -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -- first call wifi.sh or at least call - wmt_loader + stp-uart-launcher -- then load BT-module “modprobe stp_chrdev_bt” ---- - arch/arm/configs/mt7623n_evb_fwu_defconfig | 4 ++-- - .../common/common_detect/drv_init/bluetooth_drv_init.c | 3 ++- - .../connectivity/common/conn_soc/linux/pub/stp_chrdev_bt.c | 3 ++- - 3 files changed, 6 insertions(+), 4 deletions(-) - -diff --git a/arch/arm/configs/mt7623n_evb_fwu_defconfig b/arch/arm/configs/mt7623n_evb_fwu_defconfig -index 668a6c45177d..343800fc24d6 100644 ---- a/arch/arm/configs/mt7623n_evb_fwu_defconfig -+++ b/arch/arm/configs/mt7623n_evb_fwu_defconfig -@@ -390,8 +390,8 @@ CONFIG_NL80211_TESTMODE=y - - #internal Bluetooth (also not working yet) - CONFIG_BT=y --#CONFIG_MTK_COMBO_BT=y --#CONFIG_MTK_COMBO_BT_HCI=y -+CONFIG_MTK_COMBO_BT=m -+CONFIG_MTK_COMBO_BT_HCI=y - #needed for BT? - #Bluetooth Classic (BR/EDR) features - CONFIG_BT_BREDR=y -diff --git a/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/bluetooth_drv_init.c b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/bluetooth_drv_init.c -index 47b055433443..82b799f256b4 100644 ---- a/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/bluetooth_drv_init.c -+++ b/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/bluetooth_drv_init.c -@@ -23,13 +23,14 @@ - int do_bluetooth_drv_init(int chip_id) - { - int i_ret = -1; -- -+#if 0 - #if defined(CONFIG_MTK_COMBO_BT) || defined(CONFIG_MTK_COMBO_BT_HCI) - WMT_DETECT_INFO_FUNC("start to do bluetooth driver init\n"); - i_ret = mtk_wcn_stpbt_drv_init(); - WMT_DETECT_INFO_FUNC("finish bluetooth driver init, i_ret:%d\n", i_ret); - #else - WMT_DETECT_INFO_FUNC("CONFIG_MTK_COMBO_BT is not defined\n"); -+#endif - #endif - return i_ret; - } -diff --git a/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/stp_chrdev_bt.c b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/stp_chrdev_bt.c -index 190fa3944d80..5a85f68b092f 100644 ---- a/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/stp_chrdev_bt.c -+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/stp_chrdev_bt.c -@@ -877,7 +877,8 @@ static void BT_exit(void) - BT_INFO_FUNC("%s driver removed\n", BT_DRIVER_NAME); - } - --#ifdef MTK_WCN_REMOVE_KERNEL_MODULE -+#if 0 -+//#ifdef MTK_WCN_REMOVE_KERNEL_MODULE - - int mtk_wcn_stpbt_drv_init(void) - { --- -2.19.1 - diff --git a/root/target/linux/mediatek/patches-4.19/0053-defconfig-disable-some-debug-messages-evbug-gpio.patch b/root/target/linux/mediatek/patches-4.19/0053-defconfig-disable-some-debug-messages-evbug-gpio.patch deleted file mode 100644 index 7e2e22d2..00000000 --- a/root/target/linux/mediatek/patches-4.19/0053-defconfig-disable-some-debug-messages-evbug-gpio.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 32d96a7e0127ae64f4c091e8c14f2961619f4fa2 Mon Sep 17 00:00:00 2001 -From: Frank Wunderlich -Date: Sun, 20 Jan 2019 13:23:22 +0100 -Subject: [PATCH 53/77] [defconfig] disable some debug-messages (evbug,gpio) - ---- - arch/arm/configs/mt7623n_evb_fwu_defconfig | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/arch/arm/configs/mt7623n_evb_fwu_defconfig b/arch/arm/configs/mt7623n_evb_fwu_defconfig -index 343800fc24d6..2a9696b249e9 100644 ---- a/arch/arm/configs/mt7623n_evb_fwu_defconfig -+++ b/arch/arm/configs/mt7623n_evb_fwu_defconfig -@@ -223,7 +223,7 @@ CONFIG_NET_MEDIATEK_SOC=y - - CONFIG_ICPLUS_PHY=y - CONFIG_INPUT_EVDEV=y --CONFIG_INPUT_EVBUG=m -+#CONFIG_INPUT_EVBUG=m - CONFIG_KEYBOARD_MATRIX=y - CONFIG_KEYBOARD_SAMSUNG=y - CONFIG_KEYBOARD_MTK_PMIC=m -@@ -370,7 +370,7 @@ CONFIG_BTRFS_FS=m - - #GPIO - CONFIG_DEBUG_FS=y --CONFIG_DEBUG_GPIO=y -+#CONFIG_DEBUG_GPIO=y - CONFIG_GPIO_SYSFS=y - - #wlan --- -2.19.1 - diff --git a/root/target/linux/mediatek/patches-4.19/0058-defconfig-add-multiple-routing-tables-for-IPv4.patch b/root/target/linux/mediatek/patches-4.19/0058-defconfig-add-multiple-routing-tables-for-IPv4.patch deleted file mode 100644 index 56f9cd2d..00000000 --- a/root/target/linux/mediatek/patches-4.19/0058-defconfig-add-multiple-routing-tables-for-IPv4.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 04b3085371657fe44d7949168de9a080c61b1607 Mon Sep 17 00:00:00 2001 -From: Frank Wunderlich -Date: Fri, 25 Jan 2019 15:08:26 +0100 -Subject: [PATCH 58/77] [defconfig] add multiple routing-tables for IPv4 - ---- - arch/arm/configs/mt7623n_evb_fwu_defconfig | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/arch/arm/configs/mt7623n_evb_fwu_defconfig b/arch/arm/configs/mt7623n_evb_fwu_defconfig -index 2a9696b249e9..16fbafbea0c3 100644 ---- a/arch/arm/configs/mt7623n_evb_fwu_defconfig -+++ b/arch/arm/configs/mt7623n_evb_fwu_defconfig -@@ -101,6 +101,8 @@ CONFIG_DUMMY=m - CONFIG_PACKET=y - CONFIG_UNIX=y - CONFIG_INET=y -+CONFIG_IP_ADVANCED_ROUTER=y -+CONFIG_IP_MULTIPLE_TABLES=y - CONFIG_IP_PNP=y - CONFIG_IP_PNP_DHCP=y - CONFIG_IP_PNP_BOOTP=y --- -2.19.1 - diff --git a/root/target/linux/mediatek/patches-4.19/0059-defconfig-added-options-for-Traffic-Shaping.patch b/root/target/linux/mediatek/patches-4.19/0059-defconfig-added-options-for-Traffic-Shaping.patch deleted file mode 100644 index 22ade4c8..00000000 --- a/root/target/linux/mediatek/patches-4.19/0059-defconfig-added-options-for-Traffic-Shaping.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 4ca583e03d89abdab30393529e048d5fadcffb2b Mon Sep 17 00:00:00 2001 -From: Frank Wunderlich -Date: Fri, 25 Jan 2019 15:53:58 +0100 -Subject: [PATCH 59/77] [defconfig] added options for Traffic Shaping - ---- - arch/arm/configs/mt7623n_evb_fwu_defconfig | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/arch/arm/configs/mt7623n_evb_fwu_defconfig b/arch/arm/configs/mt7623n_evb_fwu_defconfig -index 16fbafbea0c3..cd86a013b161 100644 ---- a/arch/arm/configs/mt7623n_evb_fwu_defconfig -+++ b/arch/arm/configs/mt7623n_evb_fwu_defconfig -@@ -98,6 +98,7 @@ CONFIG_APM_EMULATION=y - - CONFIG_NET=y - CONFIG_DUMMY=m -+CONFIG_IFB=m - CONFIG_PACKET=y - CONFIG_UNIX=y - CONFIG_INET=y -@@ -525,6 +526,8 @@ CONFIG_NET_SCH_GRED=m - CONFIG_NET_SCH_DSMARK=m - CONFIG_NET_SCH_INGRESS=m - CONFIG_NET_SCH_NETEM=m -+CONFIG_NET_SCH_FQ_CODEL=m -+CONFIG_NET_ACT_MIRRED=m - CONFIG_NET_QOS=y - CONFIG_NET_ESTIMATOR=y - CONFIG_NET_CLS=y --- -2.19.1 - diff --git a/root/target/linux/mediatek/patches-4.19/0061-defconfig-add-nftables.patch b/root/target/linux/mediatek/patches-4.19/0061-defconfig-add-nftables.patch deleted file mode 100644 index f3a725b3..00000000 --- a/root/target/linux/mediatek/patches-4.19/0061-defconfig-add-nftables.patch +++ /dev/null @@ -1,60 +0,0 @@ -From ac6c3841de57124c49f95da9f50448a82070cce3 Mon Sep 17 00:00:00 2001 -From: Frank Wunderlich -Date: Fri, 8 Feb 2019 16:27:44 +0100 -Subject: [PATCH 61/77] [defconfig] add nftables - ---- - arch/arm/configs/mt7623n_evb_fwu_defconfig | 37 ++++++++++++++++++++++ - 1 file changed, 37 insertions(+) - -diff --git a/arch/arm/configs/mt7623n_evb_fwu_defconfig b/arch/arm/configs/mt7623n_evb_fwu_defconfig -index cd86a013b161..6ec6625102b3 100644 ---- a/arch/arm/configs/mt7623n_evb_fwu_defconfig -+++ b/arch/arm/configs/mt7623n_evb_fwu_defconfig -@@ -179,6 +179,43 @@ CONFIG_IP_VS=m - CONFIG_NETFILTER_XT_MATCH_IPVS=m - CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m - -+CONFIG_NF_TABLES=m -+CONFIG_NF_TABLES_IPV4=y -+CONFIG_NF_TABLES_IPV6=y -+CONFIG_NF_TABLES_INET=y -+CONFIG_NF_TABLES_NETDEV=y -+CONFIG_NFT_NUMGEN=m -+CONFIG_NFT_CT=m -+CONFIG_NFT_COUNTER=m -+CONFIG_NFT_CONNLIMIT=m -+CONFIG_NFT_LOG=m -+CONFIG_NFT_LIMIT=m -+CONFIG_NFT_MASQ=m -+CONFIG_NFT_MASQ_IPV4=m -+CONFIG_NFT_REDIR=m -+CONFIG_NFT_NAT=m -+CONFIG_NFT_CHAIN_NAT_IPV4=m -+CONFIG_NFT_TUNNEL=m -+CONFIG_NFT_OBJREF=m -+CONFIG_NFT_QUOTA=m -+CONFIG_NFT_REJECT=m -+CONFIG_NFT_COMPAT=m -+CONFIG_NFT_HASH=m -+CONFIG_NFT_SOCKET=m -+CONFIG_NFT_OSF=m -+CONFIG_NFT_TPROXY=m -+CONFIG_NFT_QUEUE=m -+CONFIG_NFT_FIB_IPV4=m -+CONFIG_NFT_FIB_IPV6=m -+CONFIG_NFT_FIB_INET=m -+CONFIG_NFT_FIB_NETDEV=m -+CONFIG_NFT_FLOW_OFFLOAD=m -+CONFIG_NFT_FWD_NETDEV=m -+CONFIG_NFT_REDIR_IPV4=m -+CONFIG_NFT_REDIR_IPV6=m -+CONFIG_NFT_CHAIN_ROUTE_IPV4=m -+CONFIG_NFT_CHAIN_ROUTE_IPV6=m -+ - CONFIG_NET_MEDIATEK_HNAT=m - CONFIG_DEBUG_SECTION_MISMATCH=y - --- -2.19.1 - diff --git a/root/target/linux/mediatek/patches-4.19/0063-defconfig-add-all-XT-matches-targets.patch b/root/target/linux/mediatek/patches-4.19/0063-defconfig-add-all-XT-matches-targets.patch deleted file mode 100644 index e6532ba2..00000000 --- a/root/target/linux/mediatek/patches-4.19/0063-defconfig-add-all-XT-matches-targets.patch +++ /dev/null @@ -1,100 +0,0 @@ -From 56aa779864c232422984341490eb1bb96259efe0 Mon Sep 17 00:00:00 2001 -From: Frank Wunderlich -Date: Sat, 16 Feb 2019 09:39:43 +0100 -Subject: [PATCH 63/77] [defconfig] add all XT-matches/targets - ---- - arch/arm/configs/mt7623n_evb_fwu_defconfig | 71 +++++++++++++++++++--- - 1 file changed, 62 insertions(+), 9 deletions(-) - -diff --git a/arch/arm/configs/mt7623n_evb_fwu_defconfig b/arch/arm/configs/mt7623n_evb_fwu_defconfig -index 6ec6625102b3..660b4c234ad2 100644 ---- a/arch/arm/configs/mt7623n_evb_fwu_defconfig -+++ b/arch/arm/configs/mt7623n_evb_fwu_defconfig -@@ -163,21 +163,74 @@ CONFIG_NETFILTER_SYNPROXY=m - CONFIG_IP_NF_TARGET_SYNPROXY=m - CONFIG_IP6_NF_TARGET_SYNPROXY=m - -+CONFIG_IP_VS=m -+ - CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m --CONFIG_NETFILTER_XT_MATCH_LIMIT=m --CONFIG_NETFILTER_XT_MATCH_STATE=m -+CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m -+CONFIG_NETFILTER_XT_TARGET_CONNMARK=m -+CONFIG_NETFILTER_XT_TARGET_DSCP=m -+CONFIG_NETFILTER_XT_TARGET_HL=m -+CONFIG_NETFILTER_XT_TARGET_HMARK=m -+CONFIG_NETFILTER_XT_TARGET_IDLETIMER=m -+CONFIG_NETFILTER_XT_TARGET_LED=m - CONFIG_NETFILTER_XT_TARGET_LOG=m -+CONFIG_NETFILTER_XT_TARGET_MARK=m -+CONFIG_NETFILTER_XT_TARGET_NETMAP=m -+CONFIG_NETFILTER_XT_TARGET_NFLOG=m -+CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m -+CONFIG_NETFILTER_XT_TARGET_RATEEST=m -+CONFIG_NETFILTER_XT_TARGET_REDIRECT=m -+CONFIG_NETFILTER_XT_TARGET_TEE=m -+CONFIG_NETFILTER_XT_TARGET_TPROXY=m -+CONFIG_NETFILTER_XT_TARGET_TCPMSS=m - CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m -+# Xtables matches -+CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m -+CONFIG_NETFILTER_XT_MATCH_BPF=m -+CONFIG_NETFILTER_XT_MATCH_CGROUP=m -+CONFIG_NETFILTER_XT_MATCH_CLUSTER=m -+CONFIG_NETFILTER_XT_MATCH_COMMENT=m -+CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m -+CONFIG_NETFILTER_XT_MATCH_CONNLABEL=m -+CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m -+CONFIG_NETFILTER_XT_MATCH_CONNMARK=m - CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m --CONFIG_NETFILTER_XT_MATCH_MAC=m --CONFIG_NETFILTER_XT_MATCH_RECENT=m -+CONFIG_NETFILTER_XT_MATCH_CPU=m -+CONFIG_NETFILTER_XT_MATCH_DCCP=m -+CONFIG_NETFILTER_XT_MATCH_DEVGROUP=m -+CONFIG_NETFILTER_XT_MATCH_DSCP=m -+CONFIG_NETFILTER_XT_MATCH_ECN=m -+CONFIG_NETFILTER_XT_MATCH_ESP=m -+CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m -+CONFIG_NETFILTER_XT_MATCH_HELPER=m -+CONFIG_NETFILTER_XT_MATCH_HL=m -+CONFIG_NETFILTER_XT_MATCH_IPCOMP=m - CONFIG_NETFILTER_XT_MATCH_IPRANGE=m --CONFIG_NETFILTER_XT_MARK=m --CONFIG_NETFILTER_XT_CONNMARK=m --CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m --CONFIG_IP_VS=m - CONFIG_NETFILTER_XT_MATCH_IPVS=m --CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m -+CONFIG_NETFILTER_XT_MATCH_L2TP=m -+CONFIG_NETFILTER_XT_MATCH_LENGTH=m -+CONFIG_NETFILTER_XT_MATCH_LIMIT=m -+CONFIG_NETFILTER_XT_MATCH_MAC=m -+CONFIG_NETFILTER_XT_MATCH_MARK=m -+CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m -+CONFIG_NETFILTER_XT_MATCH_NFACCT=m -+CONFIG_NETFILTER_XT_MATCH_OSF=m -+CONFIG_NETFILTER_XT_MATCH_OWNER=m -+CONFIG_NETFILTER_XT_MATCH_POLICY=m -+CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m -+CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m -+CONFIG_NETFILTER_XT_MATCH_QUOTA=m -+CONFIG_NETFILTER_XT_MATCH_RATEEST=m -+CONFIG_NETFILTER_XT_MATCH_REALM=m -+CONFIG_NETFILTER_XT_MATCH_RECENT=m -+CONFIG_NETFILTER_XT_MATCH_SCTP=m -+CONFIG_NETFILTER_XT_MATCH_STATE=m -+CONFIG_NETFILTER_XT_MATCH_STATISTIC=m -+CONFIG_NETFILTER_XT_MATCH_STRING=m -+CONFIG_NETFILTER_XT_MATCH_TCPMSS=m -+CONFIG_NETFILTER_XT_MATCH_TIME=m -+CONFIG_NETFILTER_XT_MATCH_U32=m -+ - - CONFIG_NF_TABLES=m - CONFIG_NF_TABLES_IPV4=y --- -2.19.1 - diff --git a/root/target/linux/mediatek/patches-4.19/0064-dsa-fix-oops-in-br_vlan_enabled.patch b/root/target/linux/mediatek/patches-4.19/0064-dsa-fix-oops-in-br_vlan_enabled.patch deleted file mode 100644 index ff38a894..00000000 --- a/root/target/linux/mediatek/patches-4.19/0064-dsa-fix-oops-in-br_vlan_enabled.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 769d236f61e884cc24897f23ede001744a77a469 Mon Sep 17 00:00:00 2001 -From: Frank Wunderlich -Date: Sat, 16 Feb 2019 17:26:51 +0100 -Subject: [PATCH 64/77] [dsa] fix oops in br_vlan_enabled - ---- - net/dsa/port.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/net/dsa/port.c b/net/dsa/port.c -index ed0595459df1..0891c6f554dc 100644 ---- a/net/dsa/port.c -+++ b/net/dsa/port.c -@@ -255,7 +255,7 @@ int dsa_port_vlan_add(struct dsa_port *dp, - if (netif_is_bridge_master(vlan->obj.orig_dev)) - return -EOPNOTSUPP; - -- if (br_vlan_enabled(dp->bridge_dev)) -+ if (!dp->bridge_dev || br_vlan_enabled(dp->bridge_dev)) - return dsa_port_notify(dp, DSA_NOTIFIER_VLAN_ADD, &info); - - return 0; -@@ -273,7 +273,7 @@ int dsa_port_vlan_del(struct dsa_port *dp, - if (netif_is_bridge_master(vlan->obj.orig_dev)) - return -EOPNOTSUPP; - -- if (br_vlan_enabled(dp->bridge_dev)) -+ if (!dp->bridge_dev || br_vlan_enabled(dp->bridge_dev)) - return dsa_port_notify(dp, DSA_NOTIFIER_VLAN_DEL, &info); - - return 0; --- -2.19.1 - diff --git a/root/target/linux/mediatek/patches-4.19/0066-defconfig-enable-mt76x2.patch b/root/target/linux/mediatek/patches-4.19/0066-defconfig-enable-mt76x2.patch deleted file mode 100644 index 329d9bd2..00000000 --- a/root/target/linux/mediatek/patches-4.19/0066-defconfig-enable-mt76x2.patch +++ /dev/null @@ -1,25 +0,0 @@ -From b0ff7f6f16836ac39eb8a66f3cee3d7cee7cd3fc Mon Sep 17 00:00:00 2001 -From: Frank Wunderlich -Date: Sun, 17 Feb 2019 18:02:51 +0100 -Subject: [PATCH 66/77] [defconfig] enable mt76x2 - ---- - arch/arm/configs/mt7623n_evb_fwu_defconfig | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/arch/arm/configs/mt7623n_evb_fwu_defconfig b/arch/arm/configs/mt7623n_evb_fwu_defconfig -index 660b4c234ad2..44b34cac3614 100644 ---- a/arch/arm/configs/mt7623n_evb_fwu_defconfig -+++ b/arch/arm/configs/mt7623n_evb_fwu_defconfig -@@ -506,7 +506,7 @@ CONFIG_RFKILL_INPUT=y - CONFIG_RFKILL_GPIO=y - - #if you use a mt76x2 or mt76x3 pcie-card --#CONFIG_MT76=m -+CONFIG_MT76x2E=m - - #pcie - CONFIG_PCIEPORTBUS=y --- -2.19.1 - diff --git a/root/target/linux/mediatek/patches-4.19/0067-dsa-fix-from-florian.patch b/root/target/linux/mediatek/patches-4.19/0067-dsa-fix-from-florian.patch deleted file mode 100644 index 383766be..00000000 --- a/root/target/linux/mediatek/patches-4.19/0067-dsa-fix-from-florian.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 4b2f75faab7f63d9cbddd99080632a8767cda28c Mon Sep 17 00:00:00 2001 -From: Frank Wunderlich -Date: Tue, 19 Feb 2019 17:25:57 +0100 -Subject: [PATCH 67/77] [dsa] fix from florian - ---- - net/dsa/port.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/net/dsa/port.c b/net/dsa/port.c -index 0891c6f554dc..792a13068c50 100644 ---- a/net/dsa/port.c -+++ b/net/dsa/port.c -@@ -255,7 +255,7 @@ int dsa_port_vlan_add(struct dsa_port *dp, - if (netif_is_bridge_master(vlan->obj.orig_dev)) - return -EOPNOTSUPP; - -- if (!dp->bridge_dev || br_vlan_enabled(dp->bridge_dev)) -+ if (dp->bridge_dev && br_vlan_enabled(dp->bridge_dev)) - return dsa_port_notify(dp, DSA_NOTIFIER_VLAN_ADD, &info); - - return 0; -@@ -273,7 +273,7 @@ int dsa_port_vlan_del(struct dsa_port *dp, - if (netif_is_bridge_master(vlan->obj.orig_dev)) - return -EOPNOTSUPP; - -- if (!dp->bridge_dev || br_vlan_enabled(dp->bridge_dev)) -+ if (dp->bridge_dev && br_vlan_enabled(dp->bridge_dev)) - return dsa_port_notify(dp, DSA_NOTIFIER_VLAN_DEL, &info); - - return 0; --- -2.19.1 - diff --git a/root/target/linux/mediatek/patches-4.19/0068-defconfig-add-atheros-wireless-lan-9k-10k-support.patch b/root/target/linux/mediatek/patches-4.19/0068-defconfig-add-atheros-wireless-lan-9k-10k-support.patch deleted file mode 100644 index 442b9c5a..00000000 --- a/root/target/linux/mediatek/patches-4.19/0068-defconfig-add-atheros-wireless-lan-9k-10k-support.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 9cbdef979d2119a250d4b8724b247f2a4cad899c Mon Sep 17 00:00:00 2001 -From: Frank Wunderlich -Date: Wed, 20 Feb 2019 17:29:38 +0100 -Subject: [PATCH 68/77] [defconfig] add atheros wireless lan 9k/10k support - ---- - arch/arm/configs/mt7623n_evb_fwu_defconfig | 10 +++++++++- - 1 file changed, 9 insertions(+), 1 deletion(-) - -diff --git a/arch/arm/configs/mt7623n_evb_fwu_defconfig b/arch/arm/configs/mt7623n_evb_fwu_defconfig -index 44b34cac3614..ad85e0d37e3f 100644 ---- a/arch/arm/configs/mt7623n_evb_fwu_defconfig -+++ b/arch/arm/configs/mt7623n_evb_fwu_defconfig -@@ -630,9 +630,17 @@ CONFIG_NET_CLS_RSVP=m - CONFIG_NET_CLS_RSVP6=m - CONFIG_NET_CLS_POLICE=y - -+CONFIG_WLAN_VENDOR_ATH=y -+CONFIG_ATH9K=m -+CONFIG_ATH9K_PCI=y -+CONFIG_ATH9K_RFKILL=y -+CONFIG_ATH9K_HWRNG=y -+CONFIG_ATH10K=m -+CONFIG_ATH10K_PCI=m -+ -+ - #unused drivers which are set by default - CONFIG_WLAN_VENDOR_ADMTEK=n --CONFIG_WLAN_VENDOR_ATH=n - CONFIG_WLAN_VENDOR_ATMEL=n - CONFIG_WLAN_VENDOR_BROADCOM=n - CONFIG_WLAN_VENDOR_CISCO=n --- -2.19.1 - diff --git a/root/target/linux/mediatek/patches-4.19/0072-defconfig-add-ebtables.patch b/root/target/linux/mediatek/patches-4.19/0072-defconfig-add-ebtables.patch deleted file mode 100644 index 43390eae..00000000 --- a/root/target/linux/mediatek/patches-4.19/0072-defconfig-add-ebtables.patch +++ /dev/null @@ -1,47 +0,0 @@ -From e5c7c5e17a52863ff61fa7f8cdee9c8c4ae036ec Mon Sep 17 00:00:00 2001 -From: Frank Wunderlich -Date: Fri, 8 Mar 2019 17:17:41 +0100 -Subject: [PATCH 72/77] [defconfig] add ebtables - ---- - arch/arm/configs/mt7623n_evb_fwu_defconfig | 24 ++++++++++++++++++++++ - 1 file changed, 24 insertions(+) - -diff --git a/arch/arm/configs/mt7623n_evb_fwu_defconfig b/arch/arm/configs/mt7623n_evb_fwu_defconfig -index ad85e0d37e3f..b49b5feee3eb 100644 ---- a/arch/arm/configs/mt7623n_evb_fwu_defconfig -+++ b/arch/arm/configs/mt7623n_evb_fwu_defconfig -@@ -269,6 +269,30 @@ CONFIG_NFT_REDIR_IPV6=m - CONFIG_NFT_CHAIN_ROUTE_IPV4=m - CONFIG_NFT_CHAIN_ROUTE_IPV6=m - -+#ebtables -+CONFIG_NF_TABLES_BRIDGE=y -+CONFIG_BRIDGE_NF_EBTABLES=m -+CONFIG_BRIDGE_EBT_BROUTE=m -+CONFIG_BRIDGE_EBT_T_FILTER=m -+CONFIG_BRIDGE_EBT_T_NAT=m -+CONFIG_BRIDGE_EBT_802_3=m -+CONFIG_BRIDGE_EBT_AMONG=m -+CONFIG_BRIDGE_EBT_ARP=m -+CONFIG_BRIDGE_EBT_IP=m -+CONFIG_BRIDGE_EBT_IP6=m -+CONFIG_BRIDGE_EBT_LIMIT=m -+CONFIG_BRIDGE_EBT_MARK=m -+CONFIG_BRIDGE_EBT_PKTTYPE=m -+CONFIG_BRIDGE_EBT_STP=m -+CONFIG_BRIDGE_EBT_VLAN=m -+CONFIG_BRIDGE_EBT_ARPREPLY=m -+CONFIG_BRIDGE_EBT_DNAT=m -+CONFIG_BRIDGE_EBT_MARK_T=m -+CONFIG_BRIDGE_EBT_REDIRECT=m -+CONFIG_BRIDGE_EBT_SNAT=m -+CONFIG_BRIDGE_EBT_LOG=m -+CONFIG_BRIDGE_EBT_NFLOG=m -+ - CONFIG_NET_MEDIATEK_HNAT=m - CONFIG_DEBUG_SECTION_MISMATCH=y - --- -2.19.1 - diff --git a/root/target/linux/mediatek/patches-4.19/0074-add-compiler-gcc8.h.patch b/root/target/linux/mediatek/patches-4.19/0074-add-compiler-gcc8.h.patch deleted file mode 100644 index 7d993c37..00000000 --- a/root/target/linux/mediatek/patches-4.19/0074-add-compiler-gcc8.h.patch +++ /dev/null @@ -1,78 +0,0 @@ -From f290d46885f04adeed948a332ff333e258fb6868 Mon Sep 17 00:00:00 2001 -From: Frank Wunderlich -Date: Wed, 20 Mar 2019 17:29:14 +0100 -Subject: [PATCH 74/77] add compiler-gcc8.h - ---- - include/linux/compiler-gcc8.h | 59 +++++++++++++++++++++++++++++++++++ - 1 file changed, 59 insertions(+) - create mode 100644 include/linux/compiler-gcc8.h - -diff --git a/include/linux/compiler-gcc8.h b/include/linux/compiler-gcc8.h -new file mode 100644 -index 000000000000..eecd5e1fd781 ---- /dev/null -+++ b/include/linux/compiler-gcc8.h -@@ -0,0 +1,59 @@ -+#ifndef __LINUX_COMPILER_H -+#error "Please don't include directly, include instead." -+#endif -+ -+#define __used __attribute__((__used__)) -+#define __must_check __attribute__((warn_unused_result)) -+#define __compiler_offsetof(a, b) __builtin_offsetof(a, b) -+ -+/* Mark functions as cold. gcc will assume any path leading to a call -+ to them will be unlikely. This means a lot of manual unlikely()s -+ are unnecessary now for any paths leading to the usual suspects -+ like BUG(), printk(), panic() etc. [but let's keep them for now for -+ older compilers] -+ -+ gcc also has a __attribute__((__hot__)) to move hot functions into -+ a special section, but I don't see any sense in this right now in -+ the kernel context */ -+#define __cold __attribute__((__cold__)) -+ -+#define __UNIQUE_ID(prefix) __PASTE(__PASTE(__UNIQUE_ID_, prefix), __COUNTER__) -+ -+#ifndef __CHECKER__ -+# define __compiletime_warning(message) __attribute__((warning(message))) -+# define __compiletime_error(message) __attribute__((error(message))) -+#endif /* __CHECKER__ */ -+ -+/* -+ * Mark a position in code as unreachable. This can be used to -+ * suppress control flow warnings after asm blocks that transfer -+ * control elsewhere. -+ */ -+#define unreachable() __builtin_unreachable() -+ -+/* Mark a function definition as prohibited from being cloned. */ -+#define __noclone __attribute__((__noclone__)) -+ -+/* -+ * Tell the optimizer that something else uses this function or variable. -+ */ -+#define __visible __attribute__((externally_visible)) -+ -+/* -+ * GCC 'asm goto' miscompiles certain code sequences: -+ * -+ * http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58670 -+ * -+ * Work it around via a compiler barrier quirk suggested by Jakub Jelinek. -+ * -+ * (asm goto is automatically volatile - the naming reflects this.) -+ */ -+#define asm_volatile_goto(x...) do { asm goto(x); asm (""); } while (0) -+ -+#ifdef CONFIG_ARCH_USE_BUILTIN_BSWAP -+#define __HAVE_BUILTIN_BSWAP32__ -+#define __HAVE_BUILTIN_BSWAP64__ -+#define __HAVE_BUILTIN_BSWAP16__ -+#endif /* CONFIG_ARCH_USE_BUILTIN_BSWAP */ -+ -+#define KASAN_ABI_VERSION 6 --- -2.19.1 - diff --git a/root/target/linux/mediatek/patches-4.19/0076-defconfig-add-mqueue-and-seccomp-for-docker.patch b/root/target/linux/mediatek/patches-4.19/0076-defconfig-add-mqueue-and-seccomp-for-docker.patch deleted file mode 100644 index a733d587..00000000 --- a/root/target/linux/mediatek/patches-4.19/0076-defconfig-add-mqueue-and-seccomp-for-docker.patch +++ /dev/null @@ -1,37 +0,0 @@ -From f78e2765e6588afd6264c128a060642ed0f6b323 Mon Sep 17 00:00:00 2001 -From: Frank Wunderlich -Date: Fri, 12 Apr 2019 11:43:37 +0200 -Subject: [PATCH 76/77] [defconfig] add mqueue and seccomp for docker - ---- - arch/arm/configs/mt7623n_evb_fwu_defconfig | 7 ++++++- - 1 file changed, 6 insertions(+), 1 deletion(-) - -diff --git a/arch/arm/configs/mt7623n_evb_fwu_defconfig b/arch/arm/configs/mt7623n_evb_fwu_defconfig -index b49b5feee3eb..314a07cf92fd 100644 ---- a/arch/arm/configs/mt7623n_evb_fwu_defconfig -+++ b/arch/arm/configs/mt7623n_evb_fwu_defconfig -@@ -22,7 +22,6 @@ CONFIG_CGROUP_SCHED=y - CONFIG_CPUSETS=y - #some options for docker - CONFIG_CGROUP_FREEZER=y --CONFIG_POSIX_MQUEUE=y - CONFIG_OVERLAY_FS=y - CONFIG_MEMCG_SWAP=y - CONFIG_MEMCG_SWAP_ENABLED=y -@@ -131,6 +130,12 @@ CONFIG_IP_PIMSM_V2=y - CONFIG_UNIX_DIAG=m - CONFIG_PACKET_DIAG=m - -+#added for docker -+CONFIG_POSIX_MQUEUE=y -+CONFIG_POSIX_MQUEUE_SYSCTL=y -+CONFIG_HAVE_ARCH_SECCOMP_FILTER=y -+CONFIG_SECCOMP_FILTER=y -+CONFIG_SECCOMP=y - - CONFIG_IPV6=m - CONFIG_NETFILTER=y --- -2.19.1 - diff --git a/root/target/linux/mediatek/patches-4.19/0227-arm-dts-Add-Unielec-U7623-DTS.patch b/root/target/linux/mediatek/patches-4.19/0227-arm-dts-Add-Unielec-U7623-DTS.patch deleted file mode 100644 index 348035d1..00000000 --- a/root/target/linux/mediatek/patches-4.19/0227-arm-dts-Add-Unielec-U7623-DTS.patch +++ /dev/null @@ -1,397 +0,0 @@ -From 004eb24e939b5b31f828333f37fb5cb2a877d6f2 Mon Sep 17 00:00:00 2001 -From: Kristian Evensen -Date: Sun, 17 Jun 2018 14:41:47 +0200 -Subject: [PATCH] arm: dts: Add Unielec U7623 DTS - ---- - arch/arm/boot/dts/Makefile | 1 + - .../dts/mt7623a-unielec-u7623-02-emmc-512M.dts | 18 + - .../boot/dts/mt7623a-unielec-u7623-02-emmc.dtsi | 366 +++++++++++++++++++++ - 3 files changed, 385 insertions(+) - create mode 100644 arch/arm/boot/dts/mt7623a-unielec-u7623-02-emmc-512M.dts - create mode 100644 arch/arm/boot/dts/mt7623a-unielec-u7623-02-emmc.dtsi - ---- a/arch/arm/boot/dts/Makefile -+++ b/arch/arm/boot/dts/Makefile -@@ -1062,7 +1062,8 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += \ - mt6589-aquaris5.dtb \ - mt6592-evb.dtb \ - mt7623a-rfb-emmc.dtb \ -+ mt7623a-unielec-u7623-02-emmc-512M.dtb \ - mt7623a-rfb-nand.dtb \ - mt7623n-rfb-emmc.dtb \ - mt7623n-bananapi-bpi-r2.dtb \ - mt8127-moose.dtb \ ---- /dev/null -+++ b/arch/arm/boot/dts/mt7623a-unielec-u7623-02-emmc-512M.dts -@@ -0,0 +1,18 @@ -+/* -+ * Copyright 2018 Kristian Evensen -+ * -+ * SPDX-License-Identifier: (GPL-2.0+ OR MIT) -+ */ -+ -+/dts-v1/; -+#include "mt7623a-unielec-u7623-02-emmc.dtsi" -+ -+/ { -+ model = "UniElec U7623-02 eMMC (512M RAM)"; -+ compatible = "unielec,u7623-02-emmc-512m", "unielec,u7623-02-emmc", "mediatek,mt7623"; -+ -+ memory@80000000 { -+ device_type = "memory"; -+ reg = <0 0x80000000 0 0x20000000>; -+ }; -+}; ---- /dev/null -+++ b/arch/arm/boot/dts/mt7623a-unielec-u7623-02-emmc.dtsi -@@ -0,0 +1,349 @@ -+/* -+ * Copyright 2018 Kristian Evensen -+ * -+ * SPDX-License-Identifier: (GPL-2.0+ OR MIT) -+ */ -+ -+#include -+#include "mt7623.dtsi" -+#include "mt6323.dtsi" -+ -+/ { -+ compatible = "unielec,u7623-02-emmc", "mediatek,mt7623"; -+ -+ aliases { -+ serial2 = &uart2; -+ }; -+ -+ chosen { -+ bootargs = "root=/dev/mmcblk0p2 rootfstype=squashfs,f2fs"; -+ stdout-path = "serial2:115200n8"; -+ }; -+ -+ cpus { -+ cpu@0 { -+ proc-supply = <&mt6323_vproc_reg>; -+ }; -+ -+ cpu@1 { -+ proc-supply = <&mt6323_vproc_reg>; -+ }; -+ -+ cpu@2 { -+ proc-supply = <&mt6323_vproc_reg>; -+ }; -+ -+ cpu@3 { -+ proc-supply = <&mt6323_vproc_reg>; -+ }; -+ }; -+ -+ reg_1p8v: regulator-1p8v { -+ compatible = "regulator-fixed"; -+ regulator-name = "fixed-1.8V"; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ regulator-boot-on; -+ regulator-always-on; -+ }; -+ -+ reg_3p3v: regulator-3p3v { -+ compatible = "regulator-fixed"; -+ regulator-name = "fixed-3.3V"; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ regulator-boot-on; -+ regulator-always-on; -+ }; -+ -+ reg_5v: regulator-5v { -+ compatible = "regulator-fixed"; -+ regulator-name = "fixed-5V"; -+ regulator-min-microvolt = <5000000>; -+ regulator-max-microvolt = <5000000>; -+ regulator-boot-on; -+ regulator-always-on; -+ }; -+ -+ gpio-keys { -+ compatible = "gpio-keys"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&key_pins_a>; -+ -+ factory { -+ label = "factory"; -+ linux,code = ; -+ gpios = <&pio 256 GPIO_ACTIVE_LOW>; -+ }; -+ }; -+ -+ leds { -+ compatible = "gpio-leds"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&led_pins_unielec>; -+ -+ led3 { -+ label = "u7623-01:green:led3"; -+ gpios = <&pio 14 GPIO_ACTIVE_LOW>; -+ default-state = "off"; -+ }; -+ -+ led4 { -+ label = "u7623-01:green:led4"; -+ gpios = <&pio 15 GPIO_ACTIVE_LOW>; -+ default-state = "off"; -+ }; -+ }; -+ -+ mt7530: switch@0 { -+ compatible = "mediatek,mt7530"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ }; -+}; -+ -+&crypto { -+ status = "okay"; -+}; -+ -+ð { -+ status = "okay"; -+ -+ gmac0: mac@0 { -+ compatible = "mediatek,eth-mac"; -+ reg = <0>; -+ phy-mode = "trgmii"; -+ -+ fixed-link { -+ speed = <1000>; -+ full-duplex; -+ pause; -+ }; -+ }; -+ -+ mdio: mdio-bus { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ phy5: ethernet-phy@5 { -+ reg = <5>; -+ phy-mode = "rgmii-rxid"; -+ }; -+ }; -+}; -+ -+&mt7530 { -+ compatible = "mediatek,mt7530"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <0>; -+ pinctrl-names = "default"; -+ mediatek,mcm; -+ resets = <ðsys 2>; -+ reset-names = "mcm"; -+ core-supply = <&mt6323_vpa_reg>; -+ io-supply = <&mt6323_vemc3v3_reg>; -+ -+ dsa,mii-bus = <&mdio>; -+ -+ ports { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <0>; -+ -+ port@0 { -+ reg = <0>; -+ label = "lan0"; -+ cpu = <&cpu_port0>; -+ }; -+ -+ port@1 { -+ reg = <1>; -+ label = "lan1"; -+ cpu = <&cpu_port0>; -+ }; -+ -+ port@2 { -+ reg = <2>; -+ label = "lan2"; -+ cpu = <&cpu_port0>; -+ }; -+ -+ port@3 { -+ reg = <3>; -+ label = "lan3"; -+ cpu = <&cpu_port0>; -+ }; -+ -+ port@4 { -+ reg = <4>; -+ label = "wan"; -+ cpu = <&cpu_port0>; -+ }; -+ -+ cpu_port0: port@6 { -+ reg = <6>; -+ label = "cpu"; -+ ethernet = <&gmac0>; -+ phy-mode = "trgmii"; -+ -+ fixed-link { -+ speed = <1000>; -+ full-duplex; -+ }; -+ }; -+ }; -+}; -+ -+&mmc0 { -+ pinctrl-names = "default", "state_uhs"; -+ pinctrl-0 = <&mmc0_pins_default>; -+ pinctrl-1 = <&mmc0_pins_uhs>; -+ status = "okay"; -+ bus-width = <8>; -+ max-frequency = <50000000>; -+ cap-mmc-highspeed; -+ vmmc-supply = <®_3p3v>; -+ vqmmc-supply = <®_1p8v>; -+ non-removable; -+}; -+ -+&pio { -+ key_pins_a: keys-alt { -+ pins-keys { -+ pinmux = , -+ ; -+ input-enable; -+ }; -+ }; -+ -+ led_pins_unielec: leds-unielec { -+ pins-leds { -+ pinmux = , -+ ; -+ }; -+ }; -+ -+ mmc0_pins_default: mmc0default { -+ pins_cmd_dat { -+ pinmux = , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ ; -+ input-enable; -+ bias-pull-up; -+ }; -+ -+ pins_clk { -+ pinmux = ; -+ bias-pull-down; -+ }; -+ -+ pins_rst { -+ pinmux = ; -+ bias-pull-up; -+ }; -+ }; -+ -+ mmc0_pins_uhs: mmc0 { -+ pins_cmd_dat { -+ pinmux = , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ ; -+ input-enable; -+ drive-strength = ; -+ bias-pull-up = ; -+ }; -+ -+ pins_clk { -+ pinmux = ; -+ drive-strength = ; -+ bias-pull-down = ; -+ }; -+ -+ pins_rst { -+ pinmux = ; -+ bias-pull-up; -+ }; -+ }; -+ -+ pcie_default: pcie_pin_default { -+ pins_cmd_dat { -+ pinmux = , -+ ; -+ bias-disable; -+ }; -+ }; -+}; -+ -+&pwm { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pwm_pins_a>; -+ status = "okay"; -+}; -+ -+&pwrap { -+ mt6323 { -+ mt6323led: led { -+ compatible = "mediatek,mt6323-led"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ led@0 { -+ reg = <0>; -+ label = "led0"; -+ default-state = "off"; -+ }; -+ }; -+ }; -+}; -+ -+&uart2 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&uart2_pins_b>; -+ status = "okay"; -+}; -+ -+&usb1 { -+ vusb33-supply = <®_3p3v>; -+ vbus-supply = <®_3p3v>; -+ status = "okay"; -+}; -+ -+&u3phy1 { -+ status = "okay"; -+}; -+ -+&u3phy2 { -+ status = "okay"; -+ mediatek,phy-switch = <&hifsys>; -+}; -+ -+&pcie { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pcie_default>; -+ status = "okay"; -+ -+ pcie@1,0 { -+ status = "okay"; -+ }; -+ -+ pcie@2,0 { -+ status = "okay"; -+ }; -+}; -+ -+&pcie1_phy { -+ status = "okay"; -+}; -+ diff --git a/root/target/linux/mediatek/patches-4.19/0233-revert-unexport-vfs_read-write.patch b/root/target/linux/mediatek/patches-4.19/0233-revert-unexport-vfs_read-write.patch deleted file mode 100644 index 5b8e6131..00000000 --- a/root/target/linux/mediatek/patches-4.19/0233-revert-unexport-vfs_read-write.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 16c20209050ce9dc0d67e256c3dfba902868c3ed Mon Sep 17 00:00:00 2001 -From: Nikolay Amiantov -Date: Tue, 3 Jul 2018 12:40:04 +0000 -Subject: [PATCH] Revert "fs: unexport vfs_read and vfs_write" - -This reverts commit bd8df82be66698042d11e7919e244c8d72b042ca. ---- - fs/read_write.c | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/fs/read_write.c b/fs/read_write.c -index 0046d72efe94..62b9c341afa9 100644 ---- a/fs/read_write.c -+++ b/fs/read_write.c -@@ -455,6 +455,8 @@ ssize_t vfs_read(struct file *file, char __user *buf, size_t count, loff_t *pos) - return ret; - } - -+EXPORT_SYMBOL(vfs_read); -+ - static ssize_t new_sync_write(struct file *filp, const char __user *buf, size_t len, loff_t *ppos) - { - struct iovec iov = { .iov_base = (void __user *)buf, .iov_len = len }; -@@ -553,6 +555,8 @@ ssize_t vfs_write(struct file *file, const char __user *buf, size_t count, loff_ - return ret; - } - -+EXPORT_SYMBOL(vfs_write); -+ - static inline loff_t file_pos_read(struct file *file) - { - return file->f_pos; --- -2.17.1 - diff --git a/root/target/linux/mediatek/patches-4.19/0234-fix-mtk-wlan_gen2-module.patch b/root/target/linux/mediatek/patches-4.19/0234-fix-mtk-wlan_gen2-module.patch deleted file mode 100644 index bc957ee1..00000000 --- a/root/target/linux/mediatek/patches-4.19/0234-fix-mtk-wlan_gen2-module.patch +++ /dev/null @@ -1,127 +0,0 @@ -Index: linux-4.14.51/drivers/misc/mediatek/connectivity/common/conn_soc/mt7623/mtk_wcn_consys_hw.c -=================================================================== ---- linux-4.14.51.orig/drivers/misc/mediatek/connectivity/common/conn_soc/mt7623/mtk_wcn_consys_hw.c -+++ linux-4.14.51/drivers/misc/mediatek/connectivity/common/conn_soc/mt7623/mtk_wcn_consys_hw.c -@@ -519,6 +519,9 @@ INT32 mtk_wcn_consys_hw_wifi_paldo_ctrl( - } - - #endif -+ -+EXPORT_SYMBOL(mtk_wcn_consys_hw_wifi_paldo_ctrl); -+ - INT32 mtk_wcn_consys_hw_vcn28_ctrl(UINT32 enable) - { - if (enable) { -Index: linux-4.14.51/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_kal.c -=================================================================== ---- linux-4.14.51.orig/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_kal.c -+++ linux-4.14.51/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_kal.c -@@ -4530,13 +4530,10 @@ INT_32 kalHaltLock(UINT_32 waitMs) - DBGLOG(INIT, ERROR, - "kalIoctl was executed longer than %u ms, show backtrace of tx_thread!\n", - kalGetTimeTick() - rHaltCtrl.u4HoldStart); -- if (prGlueInfo) -- show_stack(prGlueInfo->main_thread, NULL); - } else { - DBGLOG(INIT, ERROR, "halt lock held by %s pid %d longer than %u ms!\n", - rHaltCtrl.owner->comm, rHaltCtrl.owner->pid, - kalGetTimeTick() - rHaltCtrl.u4HoldStart); -- show_stack(rHaltCtrl.owner, NULL); - } - return i4Ret; - } -Index: linux-4.14.51/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_rst.c -=================================================================== ---- linux-4.14.51.orig/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_rst.c -+++ linux-4.14.51/drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/gl_rst.c -@@ -58,7 +58,6 @@ - ******************************************************************************** - */ - BOOLEAN fgIsResetting = FALSE; --UINT_32 g_IsNeedDoChipReset = 0; - - /******************************************************************************* - * P R I V A T E D A T A -Index: linux-4.14.51/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/wmt_chrdev_wifi.c -=================================================================== ---- linux-4.14.51.orig/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/wmt_chrdev_wifi.c -+++ linux-4.14.51/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/wmt_chrdev_wifi.c -@@ -44,6 +44,9 @@ MODULE_LICENSE("Dual BSD/GPL"); - #define WIFI_LOG_WARN 1 - #define WIFI_LOG_ERR 0 - -+UINT32 g_IsNeedDoChipReset = 0; -+EXPORT_SYMBOL(g_IsNeedDoChipReset); -+ - UINT32 gDbgLevel = WIFI_LOG_DBG; - - #define WIFI_DBG_FUNC(fmt, arg...)\ -Index: linux-4.14.51/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/Makefile -=================================================================== ---- linux-4.14.51.orig/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/Makefile -+++ linux-4.14.51/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/Makefile -@@ -21,7 +21,11 @@ endif - obj-y += osal.o \ - bgw_desense.o \ - wmt_idc.o --obj-$(CONFIG_MTK_COMBO_BT) += stp_chrdev_bt.o --obj-$(CONFIG_MTK_COMBO_WIFI) += wmt_chrdev_wifi.o -+ifneq ($(CONFIG_MTK_COMBO_BT),) -+ obj-y += stp_chrdev_bt.o -+endif -+ifneq ($(CONFIG_MTK_COMBO_WIFI),) -+ obj-y += wmt_chrdev_wifi.o -+endif - - endif -Index: linux-4.14.51/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/wlan_drv_init.c -=================================================================== ---- linux-4.14.51.orig/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/wlan_drv_init.c -+++ linux-4.14.51/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/wlan_drv_init.c -@@ -25,7 +25,7 @@ int do_wlan_drv_init(int chip_id) - { - int i_ret = 0; - --#ifdef CONFIG_MTK_COMBO_WIFI -+#ifdef MTK_WIFI_ENABLED - int ret = 0; - - WMT_DETECT_INFO_FUNC("start to do wlan module init 0x%x\n", chip_id); -@@ -35,6 +35,7 @@ int do_wlan_drv_init(int chip_id) - WMT_DETECT_INFO_FUNC("WMT-WIFI char dev init, ret:%d\n", ret); - i_ret += ret; - -+#ifdef CONFIG_MTK_COMBO_WIFI - switch (chip_id) { - case 0x6630: - case 0x6797: -@@ -61,13 +62,10 @@ int do_wlan_drv_init(int chip_id) - #endif - break; - } -- -+#endif - WMT_DETECT_INFO_FUNC("finish wlan module init\n"); -- - #else -- - WMT_DETECT_INFO_FUNC("CONFIG_MTK_COMBO_WIFI is not defined\n"); -- - #endif - - return i_ret; -Index: linux-4.14.51/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/Makefile -=================================================================== ---- linux-4.14.51.orig/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/Makefile -+++ linux-4.14.51/drivers/misc/mediatek/connectivity/common/common_detect/drv_init/Makefile -@@ -11,6 +11,10 @@ else ifneq ($(filter "CONSYS_%",$(CONFIG - ccflags-y += -D MTK_WCN_WLAN_GEN2 - endif - -+ifneq ($(CONFIG_MTK_COMBO_WIFI),) -+ ccflags-y += -D MTK_WIFI_ENABLED -+endif -+ - obj-y += conn_drv_init.o - obj-y += common_drv_init.o - obj-y += bluetooth_drv_init.o diff --git a/root/target/linux/mediatek/patches-4.19/0235-mtk_wdt-remove-debug-printk.patch b/root/target/linux/mediatek/patches-4.19/0235-mtk_wdt-remove-debug-printk.patch deleted file mode 100644 index a9f2078c..00000000 --- a/root/target/linux/mediatek/patches-4.19/0235-mtk_wdt-remove-debug-printk.patch +++ /dev/null @@ -1,12 +0,0 @@ -Index: linux-4.14.51/drivers/watchdog/mtk_wdt.c -=================================================================== ---- linux-4.14.51.orig/drivers/watchdog/mtk_wdt.c -+++ linux-4.14.51/drivers/watchdog/mtk_wdt.c -@@ -236,7 +236,6 @@ static int mtk_wdt_ping(struct watchdog_ - void __iomem *wdt_base = mtk_wdt->wdt_base; - - iowrite32(WDT_RST_RELOAD, wdt_base + WDT_RST); -- printk_deferred("[WDK]: kick Ex WDT\n"); - - return 0; - } diff --git a/root/target/linux/mediatek/patches-4.19/0236-mt6625l-rename-wlan.patch b/root/target/linux/mediatek/patches-4.19/0236-mt6625l-rename-wlan.patch deleted file mode 100644 index e1691fd3..00000000 --- a/root/target/linux/mediatek/patches-4.19/0236-mt6625l-rename-wlan.patch +++ /dev/null @@ -1,13 +0,0 @@ -Index: linux-4.14.51/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/wmt_chrdev_wifi.c -=================================================================== ---- linux-4.14.51.orig/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/wmt_chrdev_wifi.c -+++ linux-4.14.51/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/wmt_chrdev_wifi.c -@@ -62,7 +62,7 @@ UINT32 gDbgLevel = WIFI_LOG_DBG; - - #define VERSION "1.0" - --#define WLAN_IFACE_NAME "wlan0" -+#define WLAN_IFACE_NAME "mtkwlan0" - #if CFG_TC1_FEATURE - #define LEGACY_IFACE_NAME "legacy0" - #endif diff --git a/root/target/linux/mediatek/patches-4.19/0999-wlan-memcpy-fix.patch b/root/target/linux/mediatek/patches-4.19/0999-wlan-memcpy-fix.patch deleted file mode 100644 index 4239690c..00000000 --- a/root/target/linux/mediatek/patches-4.19/0999-wlan-memcpy-fix.patch +++ /dev/null @@ -1,20 +0,0 @@ ---- a/drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic_rx.c 2019-11-19 10:19:47.020273630 +0100 -+++ b/drivers/misc/mediatek/connectivity/wlan/gen2/nic/nic_rx.c 2019-11-19 10:20:52.819020893 +0100 -@@ -1544,7 +1544,7 @@ - DBGLOG(SCN, INFO, "EVENT_ID_GSCAN_SCAN_AVAILABLE\n"); - - prEventGscnAvailable = (P_EVENT_GSCAN_SCAN_AVAILABLE_T) (prEvent->aucBuffer); -- memcpy(prEventGscnAvailable, (P_EVENT_GSCAN_SCAN_AVAILABLE_T) (prEvent->aucBuffer), -+ memmove(prEventGscnAvailable, (P_EVENT_GSCAN_SCAN_AVAILABLE_T) (prEvent->aucBuffer), - sizeof(EVENT_GSCAN_SCAN_AVAILABLE_T)); - - mtk_cfg80211_vendor_event_scan_results_available(wiphy, prGlueInfo->prDevHandler->ieee80211_ptr, -@@ -1647,7 +1647,7 @@ - { - DBGLOG(SCN, INFO, "EVENT_ID_GSCAN_SCAN_COMPLETE\n"); - prEventGscnScnDone = (P_EVENT_GSCAN_SCAN_COMPLETE_T) (prEvent->aucBuffer); -- memcpy(prEventGscnScnDone, (P_EVENT_GSCAN_SCAN_COMPLETE_T) (prEvent->aucBuffer), -+ memmove(prEventGscnScnDone, (P_EVENT_GSCAN_SCAN_COMPLETE_T) (prEvent->aucBuffer), - sizeof(EVENT_GSCAN_SCAN_COMPLETE_T)); - - mtk_cfg80211_vendor_event_complete_scan(wiphy, prGlueInfo->prDevHandler->ieee80211_ptr, diff --git a/root/target/linux/mediatek/patches-5.4/0004-mediatek-fix-packet-corruption-on-bridged-interface.patch b/root/target/linux/mediatek/patches-5.4/0004-mediatek-fix-packet-corruption-on-bridged-interface.patch deleted file mode 100644 index 6c1c2764..00000000 --- a/root/target/linux/mediatek/patches-5.4/0004-mediatek-fix-packet-corruption-on-bridged-interface.patch +++ /dev/null @@ -1,51 +0,0 @@ -From 0593f719ca873722c6ac66604f027a63663c9b64 Mon Sep 17 00:00:00 2001 -From: Alexey Loukianov -Date: Fri, 7 Jun 2019 12:33:45 +0300 -Subject: [PATCH 04/12] mediatek: fix packet corruption on bridged interface - - This fixes problem that was reported here: - http://forum.banana-pi.org/t/openwrt-18-06-malformed-ip-packets-at-bridged-interface/ - - Fix is to set both gmacs to use trgmii mode. - This fix is not technically correct as second gmac - does not support trgmii mode but current driver - implementation seems to handle it somehow and - it is the only way to have both gmacs enabled - and avoid corruption of the packets on brigded - lanX interfaces. - - Signed-off-by: Alexey Loukianov ---- - .../0067-dts-bpi-r2-fix-second-gmac.patch | 20 +++++++++++++++++++ - 1 file changed, 20 insertions(+) - create mode 100644 target/linux/mediatek/patches-4.14/0067-dts-bpi-r2-fix-second-gmac.patch - -diff --git a/target/linux/mediatek/patches-4.14/0067-dts-bpi-r2-fix-second-gmac.patch b/target/linux/mediatek/patches-4.14/0067-dts-bpi-r2-fix-second-gmac.patch -new file mode 100644 -index 0000000000..145c188972 ---- /dev/null -+++ b/target/linux/mediatek/patches-4.14/0067-dts-bpi-r2-fix-second-gmac.patch -@@ -0,0 +1,20 @@ -+--- a/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts -++++ b/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts -+@@ -141,7 +141,7 @@ -+ gmac1: mac@1 { -+ compatible = "mediatek,eth-mac"; -+ reg = <1>; -+- phy-mode = "rgmii"; -++ phy-mode = "trgmii"; -+ -+ fixed-link { -+ speed = <1000>; -+@@ -206,7 +206,7 @@ -+ reg = <5>; -+ label = "cpu"; -+ ethernet = <&gmac1>; -+- phy-mode = "rgmii"; -++ phy-mode = "trgmii"; -+ -+ fixed-link { -+ speed = <1000>; --- -2.23.0 - diff --git a/root/target/linux/mediatek/patches-5.4/0006-dts-fix-bpi2-console.patch b/root/target/linux/mediatek/patches-5.4/0006-dts-fix-bpi2-console.patch deleted file mode 100644 index be378827..00000000 --- a/root/target/linux/mediatek/patches-5.4/0006-dts-fix-bpi2-console.patch +++ /dev/null @@ -1,10 +0,0 @@ ---- a/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts -+++ b/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts -@@ -19,6 +19,7 @@ - - chosen { - stdout-path = "serial2:115200n8"; -+ bootargs = "console=ttyS2,115200n8 root=/dev/mmcblk1p2 rootfstype=ext4 rootwait vmalloc=496M"; - }; - - cpus { diff --git a/root/target/linux/mediatek/patches-5.4/0100-dts-add-second-gmac.patch b/root/target/linux/mediatek/patches-5.4/0100-dts-add-second-gmac.patch deleted file mode 100644 index d985a929..00000000 --- a/root/target/linux/mediatek/patches-5.4/0100-dts-add-second-gmac.patch +++ /dev/null @@ -1,54 +0,0 @@ -From 97fdec52fff8079d3af104e8723602a3cb9d2a11 Mon Sep 17 00:00:00 2001 -From: Frank Wunderlich -Date: Thu, 20 Jun 2019 23:06:41 +0200 -Subject: [PATCH] net: dts: add second gmac for bananapi r2 - ---- - arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts | 18 ++++++++++++++++-- - 1 file changed, 16 insertions(+), 2 deletions(-) - -diff --git a/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts b/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts -index 2b760f90f38c..fad09608b86c 100644 ---- a/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts -+++ b/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts -@@ -143,13 +143,25 @@ - }; - }; - -+ gmac1: mac@1 { -+ compatible = "mediatek,eth-mac"; -+ reg = <1>; -+ label = "wan"; -+ phy-mode = "rgmii"; -+ phy-handle = <&ephy0>; -+ }; -+ - mdio: mdio-bus { - #address-cells = <1>; - #size-cells = <0>; - -- switch@0 { -- compatible = "mediatek,mt7530"; -+ ephy0: ethernet-phy@0 { - reg = <0>; -+ }; -+ -+ switch@1f { -+ compatible = "mediatek,mt7530"; -+ reg = <0x1f>; - reset-gpios = <&pio 33 0>; - core-supply = <&mt6323_vpa_reg>; - io-supply = <&mt6323_vemc3v3_reg>; -@@ -158,10 +170,12 @@ - #address-cells = <1>; - #size-cells = <0>; - -+/* Disabled, is now handled by gmac1 (eth1/wan) via phy-handle! - port@0 { - reg = <0>; - label = "wan"; - }; -+*/ - - port@1 { - reg = <1>; diff --git a/root/target/linux/mediatek/patches-5.4/0103-net-support-net-labels.patch b/root/target/linux/mediatek/patches-5.4/0103-net-support-net-labels.patch deleted file mode 100644 index 1c58130b..00000000 --- a/root/target/linux/mediatek/patches-5.4/0103-net-support-net-labels.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 934747eba782050ba87a29a3a59f805e36410685 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Ren=C3=A9=20van=20Dorst?= -Date: Fri, 21 Jun 2019 10:04:05 +0200 -Subject: [PATCH] net: ethernet: mediatek: support net-labels -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -With this patch, device name can be set within dts file in the same way as dsa -port can. -Add: label = "wan"; to GMAC node. - -Signed-off-by: René van Dorst ---- - drivers/net/ethernet/mediatek/mtk_eth_soc.c | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -index c61069340f4f..87ced6269411 100644 ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -2756,6 +2756,7 @@ static const struct net_device_ops mtk_netdev_ops = { - - static int mtk_add_mac(struct mtk_eth *eth, struct device_node *np) - { -+ const char *name = of_get_property(np, "label", NULL); - const __be32 *_id = of_get_property(np, "reg", NULL); - struct phylink *phylink; - int phy_mode, id, err; -@@ -2846,6 +2847,9 @@ static int mtk_add_mac(struct mtk_eth *eth, struct device_node *np) - eth->netdev[id]->irq = eth->irq[0]; - eth->netdev[id]->dev.of_node = np; - -+ if (name) -+ strlcpy(eth->netdev[id]->name, name, IFNAMSIZ); -+ - return 0; - - free_netdev: diff --git a/root/target/linux/mediatek/patches-5.4/0110-rtc-mt6397.patch b/root/target/linux/mediatek/patches-5.4/0110-rtc-mt6397.patch deleted file mode 100644 index bbb478e7..00000000 --- a/root/target/linux/mediatek/patches-5.4/0110-rtc-mt6397.patch +++ /dev/null @@ -1,249 +0,0 @@ ---- a/drivers/rtc/rtc-mt6397.c 2020-03-05 23:43:52.000000000 +0800 -+++ b/drivers/rtc/rtc-mt6397.c 2020-03-18 00:54:20.445907453 +0800 -@@ -4,48 +4,18 @@ - * Author: Tianping.Fang - */ - --#include --#include -+#include -+#include -+#include - #include -+#include -+#include - #include - #include --#include --#include --#include --#include --#include --#include -- --#define RTC_BBPU 0x0000 --#define RTC_BBPU_CBUSY BIT(6) -- --#define RTC_WRTGR 0x003c -+#include -+#include - --#define RTC_IRQ_STA 0x0002 --#define RTC_IRQ_STA_AL BIT(0) --#define RTC_IRQ_STA_LP BIT(3) -- --#define RTC_IRQ_EN 0x0004 --#define RTC_IRQ_EN_AL BIT(0) --#define RTC_IRQ_EN_ONESHOT BIT(2) --#define RTC_IRQ_EN_LP BIT(3) --#define RTC_IRQ_EN_ONESHOT_AL (RTC_IRQ_EN_ONESHOT | RTC_IRQ_EN_AL) -- --#define RTC_AL_MASK 0x0008 --#define RTC_AL_MASK_DOW BIT(4) -- --#define RTC_TC_SEC 0x000a --/* Min, Hour, Dom... register offset to RTC_TC_SEC */ --#define RTC_OFFSET_SEC 0 --#define RTC_OFFSET_MIN 1 --#define RTC_OFFSET_HOUR 2 --#define RTC_OFFSET_DOM 3 --#define RTC_OFFSET_DOW 4 --#define RTC_OFFSET_MTH 5 --#define RTC_OFFSET_YEAR 6 --#define RTC_OFFSET_COUNT 7 -- --#define RTC_AL_SEC 0x0018 -+#include - - #define RTC_AL_SEC_MASK 0x003f - #define RTC_AL_MIN_MASK 0x003f -@@ -55,26 +25,8 @@ - #define RTC_AL_MTH_MASK 0x000f - #define RTC_AL_YEA_MASK 0x007f - --#define RTC_PDN2 0x002e --#define RTC_PDN2_PWRON_ALARM BIT(4) -- --#define RTC_MIN_YEAR 1968 --#define RTC_BASE_YEAR 1900 --#define RTC_NUM_YEARS 128 --#define RTC_MIN_YEAR_OFFSET (RTC_MIN_YEAR - RTC_BASE_YEAR) -- --struct mt6397_rtc { -- struct device *dev; -- struct rtc_device *rtc_dev; -- struct mutex lock; -- struct regmap *regmap; -- int irq; -- u32 addr_base; --}; -- - static int mtk_rtc_write_trigger(struct mt6397_rtc *rtc) - { -- unsigned long timeout = jiffies + HZ; - int ret; - u32 data; - -@@ -82,19 +34,13 @@ static int mtk_rtc_write_trigger(struct - if (ret < 0) - return ret; - -- while (1) { -- ret = regmap_read(rtc->regmap, rtc->addr_base + RTC_BBPU, -- &data); -- if (ret < 0) -- break; -- if (!(data & RTC_BBPU_CBUSY)) -- break; -- if (time_after(jiffies, timeout)) { -- ret = -ETIMEDOUT; -- break; -- } -- cpu_relax(); -- } -+ ret = regmap_read_poll_timeout(rtc->regmap, -+ rtc->addr_base + RTC_BBPU, data, -+ !(data & RTC_BBPU_CBUSY), -+ MTK_RTC_POLL_DELAY_US, -+ MTK_RTC_POLL_TIMEOUT); -+ if (ret < 0) -+ dev_err(rtc->dev, "failed to write WRTGE: %d\n", ret); - - return ret; - } -@@ -338,19 +284,19 @@ static int mtk_rtc_probe(struct platform - return rtc->irq; - - rtc->regmap = mt6397_chip->regmap; -- rtc->dev = &pdev->dev; - mutex_init(&rtc->lock); - - platform_set_drvdata(pdev, rtc); - -- rtc->rtc_dev = devm_rtc_allocate_device(rtc->dev); -+ rtc->rtc_dev = devm_rtc_allocate_device(&pdev->dev); - if (IS_ERR(rtc->rtc_dev)) - return PTR_ERR(rtc->rtc_dev); - -- ret = request_threaded_irq(rtc->irq, NULL, -- mtk_rtc_irq_handler_thread, -- IRQF_ONESHOT | IRQF_TRIGGER_HIGH, -- "mt6397-rtc", rtc); -+ ret = devm_request_threaded_irq(&pdev->dev, rtc->irq, NULL, -+ mtk_rtc_irq_handler_thread, -+ IRQF_ONESHOT | IRQF_TRIGGER_HIGH, -+ "mt6397-rtc", rtc); -+ - if (ret) { - dev_err(&pdev->dev, "Failed to request alarm IRQ: %d: %d\n", - rtc->irq, ret); -@@ -372,15 +318,6 @@ out_free_irq: - return ret; - } - --static int mtk_rtc_remove(struct platform_device *pdev) --{ -- struct mt6397_rtc *rtc = platform_get_drvdata(pdev); -- -- free_irq(rtc->irq, rtc); -- -- return 0; --} -- - #ifdef CONFIG_PM_SLEEP - static int mt6397_rtc_suspend(struct device *dev) - { -@@ -407,6 +344,7 @@ static SIMPLE_DEV_PM_OPS(mt6397_pm_ops, - mt6397_rtc_resume); - - static const struct of_device_id mt6397_rtc_of_match[] = { -+ { .compatible = "mediatek,mt6323-rtc", }, - { .compatible = "mediatek,mt6397-rtc", }, - { } - }; -@@ -419,7 +357,6 @@ static struct platform_driver mtk_rtc_dr - .pm = &mt6397_pm_ops, - }, - .probe = mtk_rtc_probe, -- .remove = mtk_rtc_remove, - }; - - module_platform_driver(mtk_rtc_driver); -diff --git a/include/linux/mfd/mt6397/rtc.h b/include/linux/mfd/mt6397/rtc.h -new file mode 100644 -index 000000000000..f84b9163c0ee ---- /dev/null -+++ b/include/linux/mfd/mt6397/rtc.h -@@ -0,0 +1,71 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2014-2019 MediaTek Inc. -+ * -+ * Author: Tianping.Fang -+ * Sean Wang -+ */ -+ -+#ifndef _LINUX_MFD_MT6397_RTC_H_ -+#define _LINUX_MFD_MT6397_RTC_H_ -+ -+#include -+#include -+#include -+#include -+ -+#define RTC_BBPU 0x0000 -+#define RTC_BBPU_CBUSY BIT(6) -+#define RTC_BBPU_KEY (0x43 << 8) -+ -+#define RTC_WRTGR 0x003c -+ -+#define RTC_IRQ_STA 0x0002 -+#define RTC_IRQ_STA_AL BIT(0) -+#define RTC_IRQ_STA_LP BIT(3) -+ -+#define RTC_IRQ_EN 0x0004 -+#define RTC_IRQ_EN_AL BIT(0) -+#define RTC_IRQ_EN_ONESHOT BIT(2) -+#define RTC_IRQ_EN_LP BIT(3) -+#define RTC_IRQ_EN_ONESHOT_AL (RTC_IRQ_EN_ONESHOT | RTC_IRQ_EN_AL) -+ -+#define RTC_AL_MASK 0x0008 -+#define RTC_AL_MASK_DOW BIT(4) -+ -+#define RTC_TC_SEC 0x000a -+/* Min, Hour, Dom... register offset to RTC_TC_SEC */ -+#define RTC_OFFSET_SEC 0 -+#define RTC_OFFSET_MIN 1 -+#define RTC_OFFSET_HOUR 2 -+#define RTC_OFFSET_DOM 3 -+#define RTC_OFFSET_DOW 4 -+#define RTC_OFFSET_MTH 5 -+#define RTC_OFFSET_YEAR 6 -+#define RTC_OFFSET_COUNT 7 -+ -+#define RTC_AL_SEC 0x0018 -+ -+#define RTC_PDN2 0x002e -+#define RTC_PDN2_PWRON_ALARM BIT(4) -+ -+#define RTC_MIN_YEAR 1968 -+#define RTC_BASE_YEAR 1900 -+#define RTC_NUM_YEARS 128 -+#define RTC_MIN_YEAR_OFFSET (RTC_MIN_YEAR - RTC_BASE_YEAR) -+ -+#define MTK_RTC_POLL_DELAY_US 10 -+#define MTK_RTC_POLL_TIMEOUT (jiffies_to_usecs(HZ)) -+ -+struct mt6397_rtc { -+ struct device *dev; -+ struct rtc_device *rtc_dev; -+ -+ /* Protect register access from multiple tasks */ -+ struct mutex lock; -+ struct regmap *regmap; -+ int irq; -+ u32 addr_base; -+}; -+ -+#endif /* _LINUX_MFD_MT6397_RTC_H_ */ - diff --git a/root/target/linux/mediatek/patches-5.4/0111-mt6323-poweroff.patch b/root/target/linux/mediatek/patches-5.4/0111-mt6323-poweroff.patch deleted file mode 100644 index b8552824..00000000 --- a/root/target/linux/mediatek/patches-5.4/0111-mt6323-poweroff.patch +++ /dev/null @@ -1,160 +0,0 @@ -From 559614ab0ae2c85596218226f095be36c12cf0fa Mon Sep 17 00:00:00 2001 -From: Josef Friedl -Date: Wed, 3 Jul 2019 12:24:52 +0200 -Subject: [PATCH] power: reset: add driver for mt6323 poweroff - -add poweroff driver for mt6323 and make Makefile and Kconfig-Entries - -Suggested-by: Frank Wunderlich -Signed-off-by: Josef Friedl -Signed-off-by: Frank Wunderlich -Acked-by: Sebastian Reichel ---- -changes since v6: none -changes since v5: split out mfd/mt6397/core.h -changes since v4: none -changes since v3: none -changes since v2: none (=v2 part 5) ---- - drivers/power/reset/Kconfig | 10 +++ - drivers/power/reset/Makefile | 1 + - drivers/power/reset/mt6323-poweroff.c | 97 +++++++++++++++++++++++++++ - 3 files changed, 108 insertions(+) - create mode 100644 drivers/power/reset/mt6323-poweroff.c - -diff --git a/drivers/power/reset/Kconfig b/drivers/power/reset/Kconfig -index a564237278ff..c721939767eb 100644 ---- a/drivers/power/reset/Kconfig -+++ b/drivers/power/reset/Kconfig -@@ -140,6 +140,16 @@ config POWER_RESET_LTC2952 - This driver supports an external powerdown trigger and board power - down via the LTC2952. Bindings are made in the device tree. - -+config POWER_RESET_MT6323 -+ bool "MediaTek MT6323 power-off driver" -+ depends on MFD_MT6397 -+ help -+ The power-off driver is responsible for externally shutdown down -+ the power of a remote MediaTek SoC MT6323 is connected to through -+ controlling a tiny circuit BBPU inside MT6323 RTC. -+ -+ Say Y if you have a board where MT6323 could be found. -+ - config POWER_RESET_QNAP - bool "QNAP power-off driver" - depends on OF_GPIO && PLAT_ORION -diff --git a/drivers/power/reset/Makefile b/drivers/power/reset/Makefile -index 85da3198e4e0..da37f8b851dc 100644 ---- a/drivers/power/reset/Makefile -+++ b/drivers/power/reset/Makefile -@@ -11,6 +11,7 @@ obj-$(CONFIG_POWER_RESET_GPIO) += gpio-poweroff.o - obj-$(CONFIG_POWER_RESET_GPIO_RESTART) += gpio-restart.o - obj-$(CONFIG_POWER_RESET_HISI) += hisi-reboot.o - obj-$(CONFIG_POWER_RESET_MSM) += msm-poweroff.o -+obj-$(CONFIG_POWER_RESET_MT6323) += mt6323-poweroff.o - obj-$(CONFIG_POWER_RESET_QCOM_PON) += qcom-pon.o - obj-$(CONFIG_POWER_RESET_OCELOT_RESET) += ocelot-reset.o - obj-$(CONFIG_POWER_RESET_PIIX4_POWEROFF) += piix4-poweroff.o -diff --git a/drivers/power/reset/mt6323-poweroff.c b/drivers/power/reset/mt6323-poweroff.c -new file mode 100644 -index 000000000000..1caf43d9e46d ---- /dev/null -+++ b/drivers/power/reset/mt6323-poweroff.c -@@ -0,0 +1,97 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Power off through MediaTek PMIC -+ * -+ * Copyright (C) 2018 MediaTek Inc. -+ * -+ * Author: Sean Wang -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+struct mt6323_pwrc { -+ struct device *dev; -+ struct regmap *regmap; -+ u32 base; -+}; -+ -+static struct mt6323_pwrc *mt_pwrc; -+ -+static void mt6323_do_pwroff(void) -+{ -+ struct mt6323_pwrc *pwrc = mt_pwrc; -+ unsigned int val; -+ int ret; -+ -+ regmap_write(pwrc->regmap, pwrc->base + RTC_BBPU, RTC_BBPU_KEY); -+ regmap_write(pwrc->regmap, pwrc->base + RTC_WRTGR, 1); -+ -+ ret = regmap_read_poll_timeout(pwrc->regmap, -+ pwrc->base + RTC_BBPU, val, -+ !(val & RTC_BBPU_CBUSY), -+ MTK_RTC_POLL_DELAY_US, -+ MTK_RTC_POLL_TIMEOUT); -+ if (ret) -+ dev_err(pwrc->dev, "failed to write BBPU: %d\n", ret); -+ -+ /* Wait some time until system down, otherwise, notice with a warn */ -+ mdelay(1000); -+ -+ WARN_ONCE(1, "Unable to power off system\n"); -+} -+ -+static int mt6323_pwrc_probe(struct platform_device *pdev) -+{ -+ struct mt6397_chip *mt6397_chip = dev_get_drvdata(pdev->dev.parent); -+ struct mt6323_pwrc *pwrc; -+ struct resource *res; -+ -+ pwrc = devm_kzalloc(&pdev->dev, sizeof(*pwrc), GFP_KERNEL); -+ if (!pwrc) -+ return -ENOMEM; -+ -+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ pwrc->base = res->start; -+ pwrc->regmap = mt6397_chip->regmap; -+ pwrc->dev = &pdev->dev; -+ mt_pwrc = pwrc; -+ -+ pm_power_off = &mt6323_do_pwroff; -+ -+ return 0; -+} -+ -+static int mt6323_pwrc_remove(struct platform_device *pdev) -+{ -+ if (pm_power_off == &mt6323_do_pwroff) -+ pm_power_off = NULL; -+ -+ return 0; -+} -+ -+static const struct of_device_id mt6323_pwrc_dt_match[] = { -+ { .compatible = "mediatek,mt6323-pwrc" }, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, mt6323_pwrc_dt_match); -+ -+static struct platform_driver mt6323_pwrc_driver = { -+ .probe = mt6323_pwrc_probe, -+ .remove = mt6323_pwrc_remove, -+ .driver = { -+ .name = "mt6323-pwrc", -+ .of_match_table = mt6323_pwrc_dt_match, -+ }, -+}; -+ -+module_platform_driver(mt6323_pwrc_driver); -+ -+MODULE_DESCRIPTION("Poweroff driver for MT6323 PMIC"); -+MODULE_AUTHOR("Sean Wang "); -+MODULE_LICENSE("GPL v2"); diff --git a/root/target/linux/mediatek/patches-5.4/0112-dts-mt6323-add-key-rtc-power.patch b/root/target/linux/mediatek/patches-5.4/0112-dts-mt6323-add-key-rtc-power.patch deleted file mode 100644 index 41a4305c..00000000 --- a/root/target/linux/mediatek/patches-5.4/0112-dts-mt6323-add-key-rtc-power.patch +++ /dev/null @@ -1,57 +0,0 @@ -From c3db4c1163cc20ab0a456086a15c00acb022a67d Mon Sep 17 00:00:00 2001 -From: Josef Friedl -Date: Thu, 20 Dec 2018 18:27:17 +0100 -Subject: [PATCH] arm: dts: mt6323: add keys, power-controller, rtc and codec - -support poweroff and power-related keys on bpi-r2 - -Suggested-by: Frank Wunderlich -Signed-off-by: Josef Friedl -Signed-off-by: Frank Wunderlich ---- -changes since v6: none -changes since v5: none -changes since v4: none -changes since v3: none -changes since v2: none (=v2 part 7) ---- - arch/arm/boot/dts/mt6323.dtsi | 27 +++++++++++++++++++++++++++ - 1 file changed, 27 insertions(+) - -diff --git a/arch/arm/boot/dts/mt6323.dtsi b/arch/arm/boot/dts/mt6323.dtsi -index ba397407c1dd..7fda40ab5fe8 100644 ---- a/arch/arm/boot/dts/mt6323.dtsi -+++ b/arch/arm/boot/dts/mt6323.dtsi -@@ -238,5 +238,32 @@ - regulator-enable-ramp-delay = <216>; - }; - }; -+ -+ mt6323keys: mt6323keys { -+ compatible = "mediatek,mt6323-keys"; -+ mediatek,long-press-mode = <1>; -+ power-off-time-sec = <0>; -+ -+ power { -+ linux,keycodes = <116>; -+ wakeup-source; -+ }; -+ -+ home { -+ linux,keycodes = <114>; -+ }; -+ }; -+ -+ codec: mt6397codec { -+ compatible = "mediatek,mt6397-codec"; -+ }; -+ -+ power-controller { -+ compatible = "mediatek,mt6323-pwrc"; -+ }; -+ -+ rtc { -+ compatible = "mediatek,mt6323-rtc"; -+ }; - }; - }; diff --git a/root/target/linux/mediatek/patches-5.4/0170-dts-mt7623-add-display.patch b/root/target/linux/mediatek/patches-5.4/0170-dts-mt7623-add-display.patch deleted file mode 100644 index 36c38786..00000000 --- a/root/target/linux/mediatek/patches-5.4/0170-dts-mt7623-add-display.patch +++ /dev/null @@ -1,500 +0,0 @@ -From ae7a8d61a108bb58af8c3ecb16d8e95aad0b1975 Mon Sep 17 00:00:00 2001 -From: Ryder Lee -Date: Wed, 5 Sep 2018 22:09:27 +0800 -Subject: [PATCH] arm: dts: mt7623: add display subsystem related device nodes - -Add display subsystem related device nodes for MT7623. - -Cc: CK Hu -Signed-off-by: chunhui dai -Signed-off-by: Bibby Hsieh -Signed-off-by: Ryder Lee - -additional fixes: - -[hdmi,dts] fixed dts-warnings -author: Bibby Hsieh - -[dtsi] fix dpi0-node -author: Ryder Lee - -Signed-off-by: Frank Wunderlich -Tested-by: Frank Wunderlich ---- - arch/arm/boot/dts/mt7623.dtsi | 177 ++++++++++++++++++ - arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts | 85 +++++++++ - arch/arm/boot/dts/mt7623n-rfb-emmc.dts | 85 +++++++++ - 3 files changed, 347 insertions(+) - -diff --git a/arch/arm/boot/dts/mt7623.dtsi b/arch/arm/boot/dts/mt7623.dtsi -index 59e69f3dffa2..f1880ff04193 100644 ---- a/arch/arm/boot/dts/mt7623.dtsi -+++ b/arch/arm/boot/dts/mt7623.dtsi -@@ -23,6 +23,11 @@ - #address-cells = <2>; - #size-cells = <2>; - -+ aliases { -+ rdma0 = &rdma0; -+ rdma1 = &rdma1; -+ }; -+ - cpu_opp_table: opp-table { - compatible = "operating-points-v2"; - opp-shared; -@@ -320,6 +325,25 @@ - clock-names = "spi", "wrap"; - }; - -+ mipi_tx0: mipi-dphy@10010000 { -+ compatible = "mediatek,mt7623-mipi-tx", -+ "mediatek,mt2701-mipi-tx"; -+ reg = <0 0x10010000 0 0x90>; -+ clocks = <&clk26m>; -+ clock-output-names = "mipi_tx0_pll"; -+ #clock-cells = <0>; -+ #phy-cells = <0>; -+ }; -+ -+ cec: cec@10012000 { -+ compatible = "mediatek,mt7623-cec", -+ "mediatek,mt8173-cec"; -+ reg = <0 0x10012000 0 0xbc>; -+ interrupts = ; -+ clocks = <&infracfg CLK_INFRA_CEC>; -+ status = "disabled"; -+ }; -+ - cir: cir@10013000 { - compatible = "mediatek,mt7623-cir"; - reg = <0 0x10013000 0 0x1000>; -@@ -368,6 +392,18 @@ - #clock-cells = <1>; - }; - -+ hdmi_phy: phy@10209100 { -+ compatible = "mediatek,mt7623-hdmi-phy", -+ "mediatek,mt2701-hdmi-phy"; -+ reg = <0 0x10209100 0 0x24>; -+ clocks = <&apmixedsys CLK_APMIXED_HDMI_REF>; -+ clock-names = "pll_ref"; -+ clock-output-names = "hdmitx_dig_cts"; -+ #clock-cells = <0>; -+ #phy-cells = <0>; -+ status = "disabled"; -+ }; -+ - rng: rng@1020f000 { - compatible = "mediatek,mt7623-rng"; - reg = <0 0x1020f000 0 0x1000>; -@@ -567,6 +603,16 @@ - status = "disabled"; - }; - -+ hdmiddc0: i2c@11013000 { -+ compatible = "mediatek,mt7623-hdmi-ddc", -+ "mediatek,mt8173-hdmi-ddc"; -+ interrupts = ; -+ reg = <0 0x11013000 0 0x1C>; -+ clocks = <&pericfg CLK_PERI_I2C3>; -+ clock-names = "ddc-i2c"; -+ status = "disabled"; -+ }; -+ - nor_flash: spi@11014000 { - compatible = "mediatek,mt7623-nor", - "mediatek,mt8173-nor"; -@@ -741,6 +787,84 @@ - #clock-cells = <1>; - }; - -+ display_components: dispsys@14000000 { -+ compatible = "mediatek,mt7623-mmsys", -+ "mediatek,mt2701-mmsys"; -+ reg = <0 0x14000000 0 0x1000>; -+ power-domains = <&scpsys MT2701_POWER_DOMAIN_DISP>; -+ }; -+ -+ ovl@14007000 { -+ compatible = "mediatek,mt7623-disp-ovl", -+ "mediatek,mt2701-disp-ovl"; -+ reg = <0 0x14007000 0 0x1000>; -+ interrupts = ; -+ clocks = <&mmsys CLK_MM_DISP_OVL>; -+ iommus = <&iommu MT2701_M4U_PORT_DISP_OVL_0>; -+ mediatek,larb = <&larb0>; -+ }; -+ -+ rdma0: rdma@14008000 { -+ compatible = "mediatek,mt7623-disp-rdma", -+ "mediatek,mt2701-disp-rdma"; -+ reg = <0 0x14008000 0 0x1000>; -+ interrupts = ; -+ clocks = <&mmsys CLK_MM_DISP_RDMA>; -+ iommus = <&iommu MT2701_M4U_PORT_DISP_RDMA>; -+ mediatek,larb = <&larb0>; -+ }; -+ -+ wdma@14009000 { -+ compatible = "mediatek,mt7623-disp-wdma", -+ "mediatek,mt2701-disp-wdma"; -+ reg = <0 0x14009000 0 0x1000>; -+ interrupts = ; -+ clocks = <&mmsys CLK_MM_DISP_WDMA>; -+ iommus = <&iommu MT2701_M4U_PORT_DISP_WDMA>; -+ mediatek,larb = <&larb0>; -+ }; -+ -+ bls: pwm@1400a000 { -+ compatible = "mediatek,mt7623-disp-pwm", -+ "mediatek,mt2701-disp-pwm"; -+ reg = <0 0x1400a000 0 0x1000>; -+ #pwm-cells = <2>; -+ clocks = <&mmsys CLK_MM_MDP_BLS_26M>, -+ <&mmsys CLK_MM_DISP_BLS>; -+ clock-names = "main", "mm"; -+ status = "disabled"; -+ }; -+ -+ color@1400b000 { -+ compatible = "mediatek,mt7623-disp-color", -+ "mediatek,mt2701-disp-color"; -+ reg = <0 0x1400b000 0 0x1000>; -+ interrupts = ; -+ clocks = <&mmsys CLK_MM_DISP_COLOR>; -+ }; -+ -+ dsi: dsi@1400c000 { -+ compatible = "mediatek,mt7623-dsi", -+ "mediatek,mt2701-dsi"; -+ reg = <0 0x1400c000 0 0x1000>; -+ interrupts = ; -+ clocks = <&mmsys CLK_MM_DSI_ENGINE>, -+ <&mmsys CLK_MM_DSI_DIG>, -+ <&mipi_tx0>; -+ clock-names = "engine", "digital", "hs"; -+ phys = <&mipi_tx0>; -+ phy-names = "dphy"; -+ status = "disabled"; -+ }; -+ -+ mutex: mutex@1400e000 { -+ compatible = "mediatek,mt7623-disp-mutex", -+ "mediatek,mt2701-disp-mutex"; -+ reg = <0 0x1400e000 0 0x1000>; -+ interrupts = ; -+ clocks = <&mmsys CLK_MM_MUTEX_32K>; -+ }; -+ - larb0: larb@14010000 { - compatible = "mediatek,mt7623-smi-larb", - "mediatek,mt2701-smi-larb"; -@@ -753,6 +877,44 @@ - power-domains = <&scpsys MT2701_POWER_DOMAIN_DISP>; - }; - -+ rdma1: rdma@14012000 { -+ compatible = "mediatek,mt7623-disp-rdma", -+ "mediatek,mt2701-disp-rdma"; -+ reg = <0 0x14012000 0 0x1000>; -+ interrupts = ; -+ clocks = <&mmsys CLK_MM_DISP_RDMA1>; -+ iommus = <&iommu MT2701_M4U_PORT_DISP_RDMA1>; -+ mediatek,larb = <&larb0>; -+ }; -+ -+ dpi0: dpi@14014000 { -+ compatible = "mediatek,mt7623-dpi", -+ "mediatek,mt2701-dpi"; -+ reg = <0 0x14014000 0 0x1000>; -+ interrupts = ; -+ clocks = <&mmsys CLK_MM_DPI1_DIGL>, -+ <&mmsys CLK_MM_DPI1_ENGINE>, -+ <&apmixedsys CLK_APMIXED_TVDPLL>; -+ clock-names = "pixel", "engine", "pll"; -+ status = "disabled"; -+ }; -+ -+ hdmi0: hdmi@14015000 { -+ compatible = "mediatek,mt7623-hdmi", -+ "mediatek,mt8173-hdmi"; -+ reg = <0 0x14015000 0 0x400>; -+ clocks = <&mmsys CLK_MM_HDMI_PIXEL>, -+ <&mmsys CLK_MM_HDMI_PLL>, -+ <&mmsys CLK_MM_HDMI_AUDIO>, -+ <&mmsys CLK_MM_HDMI_SPDIF>; -+ clock-names = "pixel", "pll", "bclk", "spdif"; -+ phys = <&hdmi_phy>; -+ phy-names = "hdmi"; -+ mediatek,syscon-hdmi = <&mmsys 0x900>; -+ cec = <&cec>; -+ status = "disabled"; -+ }; -+ - imgsys: syscon@15000000 { - compatible = "mediatek,mt7623-imgsys", - "mediatek,mt2701-imgsys", -@@ -1077,6 +1239,21 @@ - }; - }; - -+ hdmi_pins_a: hdmi-default { -+ pins-hdmi { -+ pinmux = ; -+ input-enable; -+ bias-pull-down; -+ }; -+ }; -+ -+ hdmi_ddc_pins_a: hdmi_ddc-default { -+ pins-hdmi-ddc { -+ pinmux = , -+ ; -+ }; -+ }; -+ - i2c0_pins_a: i2c0-default { - pins-i2c0 { - pinmux = , -diff --git a/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts b/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts -index 2b760f90f38c..7a1763472018 100644 ---- a/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts -+++ b/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts -@@ -21,6 +21,19 @@ - stdout-path = "serial2:115200n8"; - }; - -+ connector { -+ compatible = "hdmi-connector"; -+ label = "hdmi"; -+ type = "d"; -+ ddc-i2c-bus = <&hdmiddc0>; -+ -+ port { -+ hdmi_connector_in: endpoint { -+ remote-endpoint = <&hdmi0_out>; -+ }; -+ }; -+ }; -+ - cpus { - cpu@0 { - proc-supply = <&mt6323_vproc_reg>; -@@ -114,10 +127,24 @@ - }; - }; - -+&bls { -+ status = "okay"; -+ -+ port { -+ bls_out: endpoint { -+ remote-endpoint = <&dpi0_in>; -+ }; -+ }; -+}; -+ - &btif { - status = "okay"; - }; - -+&cec { -+ status = "okay"; -+}; -+ - &cir { - pinctrl-names = "default"; - pinctrl-0 = <&cir_pins_a>; -@@ -128,6 +155,28 @@ - status = "okay"; - }; - -+&dpi0 { -+ status = "okay"; -+ -+ ports { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ port@0 { -+ reg = <0>; -+ dpi0_out: endpoint { -+ remote-endpoint = <&hdmi0_in>; -+ }; -+ }; -+ -+ port@1 { -+ reg = <1>; -+ dpi0_in: endpoint { -+ remote-endpoint = <&bls_out>; -+ }; -+ }; -+ }; -+}; -+ - ð { - status = "okay"; - -@@ -199,6 +248,42 @@ - }; - }; - -+&hdmi0 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&hdmi_pins_a>; -+ status = "okay"; -+ -+ ports { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ port@0 { -+ reg = <0>; -+ hdmi0_in: endpoint { -+ remote-endpoint = <&dpi0_out>; -+ }; -+ }; -+ -+ port@1 { -+ reg = <1>; -+ hdmi0_out: endpoint { -+ remote-endpoint = <&hdmi_connector_in>; -+ }; -+ }; -+ }; -+}; -+ -+&hdmiddc0 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&hdmi_ddc_pins_a>; -+ status = "okay"; -+}; -+ -+&hdmi_phy { -+ mediatek,ibias = <0xa>; -+ mediatek,ibias_up = <0x1c>; -+ status = "okay"; -+}; -+ - &i2c0 { - pinctrl-names = "default"; - pinctrl-0 = <&i2c0_pins_a>; -diff --git a/arch/arm/boot/dts/mt7623n-rfb-emmc.dts b/arch/arm/boot/dts/mt7623n-rfb-emmc.dts -index b7606130ade9..3e5911d8d6bc 100644 ---- a/arch/arm/boot/dts/mt7623n-rfb-emmc.dts -+++ b/arch/arm/boot/dts/mt7623n-rfb-emmc.dts -@@ -24,6 +24,19 @@ - stdout-path = "serial2:115200n8"; - }; - -+ connector { -+ compatible = "hdmi-connector"; -+ label = "hdmi"; -+ type = "d"; -+ ddc-i2c-bus = <&hdmiddc0>; -+ -+ port { -+ hdmi_connector_in: endpoint { -+ remote-endpoint = <&hdmi0_out>; -+ }; -+ }; -+ }; -+ - cpus { - cpu@0 { - proc-supply = <&mt6323_vproc_reg>; -@@ -106,10 +119,24 @@ - }; - }; - -+&bls { -+ status = "okay"; -+ -+ port { -+ bls_out: endpoint { -+ remote-endpoint = <&dpi0_in>; -+ }; -+ }; -+}; -+ - &btif { - status = "okay"; - }; - -+&cec { -+ status = "okay"; -+}; -+ - &cir { - pinctrl-names = "default"; - pinctrl-0 = <&cir_pins_a>; -@@ -120,6 +147,28 @@ - status = "okay"; - }; - -+&dpi0 { -+ status = "okay"; -+ -+ ports { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ port@0 { -+ reg = <0>; -+ dpi0_out: endpoint { -+ remote-endpoint = <&hdmi0_in>; -+ }; -+ }; -+ -+ port@1 { -+ reg = <1>; -+ dpi0_in: endpoint { -+ remote-endpoint = <&bls_out>; -+ }; -+ }; -+ }; -+}; -+ - ð { - status = "okay"; - -@@ -202,6 +251,42 @@ - }; - }; - -+&hdmi0 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&hdmi_pins_a>; -+ status = "okay"; -+ -+ ports { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ port@0 { -+ reg = <0>; -+ hdmi0_in: endpoint { -+ remote-endpoint = <&dpi0_out>; -+ }; -+ }; -+ -+ port@1 { -+ reg = <1>; -+ hdmi0_out: endpoint { -+ remote-endpoint = <&hdmi_connector_in>; -+ }; -+ }; -+ }; -+}; -+ -+&hdmiddc0 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&hdmi_ddc_pins_a>; -+ status = "okay"; -+}; -+ -+&hdmi_phy { -+ mediatek,ibias = <0xa>; -+ mediatek,ibias_up = <0x1c>; -+ status = "okay"; -+}; -+ - &i2c0 { - pinctrl-names = "default"; - pinctrl-0 = <&i2c0_pins_a>; diff --git a/root/target/linux/mediatek/patches-5.4/0171-dts-mt7623-add-mali450.patch b/root/target/linux/mediatek/patches-5.4/0171-dts-mt7623-add-mali450.patch deleted file mode 100644 index c49690c5..00000000 --- a/root/target/linux/mediatek/patches-5.4/0171-dts-mt7623-add-mali450.patch +++ /dev/null @@ -1,77 +0,0 @@ -From 6468d187f12604f38f0a3acde430fdc5c5390771 Mon Sep 17 00:00:00 2001 -From: Ryder Lee -Date: Tue, 23 Jul 2019 11:32:50 +0800 -Subject: [PATCH] arm: dts: mt7623: add Mali-450 device nodes - -Add nodes for Mali-450 and iommu larb3. - -Signed-off-by: Sean Wang -Signed-off-by: Ryder Lee ---- - arch/arm/boot/dts/mt7623.dtsi | 39 ++++++++++++++++++++++++++++++++++- - 1 file changed, 38 insertions(+), 1 deletion(-) - -diff --git a/arch/arm/boot/dts/mt7623.dtsi b/arch/arm/boot/dts/mt7623.dtsi -index 8d0807fd9460..f7905561b30e 100644 ---- a/arch/arm/boot/dts/mt7623.dtsi -+++ b/arch/arm/boot/dts/mt7623.dtsi -@@ -3,6 +3,7 @@ - * Copyright (c) 2017-2018 MediaTek Inc. - * Author: John Crispin - * Sean Wang -+ * Ryder Lee - * - */ - -@@ -371,7 +372,7 @@ - interrupts = ; - clocks = <&infracfg CLK_INFRA_M4U>; - clock-names = "bclk"; -- mediatek,larbs = <&larb0 &larb1 &larb2>; -+ mediatek,larbs = <&larb0 &larb1 &larb2 &larb3>; - #iommu-cells = <1>; - }; - -@@ -794,6 +795,42 @@ - #reset-cells = <1>; - }; - -+ larb3: larb@13010000 { -+ compatible = "mediatek,mt7623-smi-larb", -+ "mediatek,mt2701-smi-larb"; -+ reg = <0 0x13010000 0 0x1000>; -+ mediatek,smi = <&smi_common>; -+ mediatek,larb-id = <3>; -+ clocks = <&clk26m>, <&clk26m>; -+ clock-names = "apb", "smi"; -+ power-domains = <&scpsys MT2701_POWER_DOMAIN_MFG>; -+ }; -+ -+ mali: gpu@13040000 { -+ compatible = "mediatek,mt7623-mali", "arm,mali-450"; -+ reg = <0 0x13040000 0 0x30000>; -+ interrupts = , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ ; -+ interrupt-names = "gp", "gpmmu", "pp0", "ppmmu0", "pp1", -+ "ppmmu1", "pp2", "ppmmu2", "pp3", "ppmmu3", -+ "pp"; -+ clocks = <&topckgen CLK_TOP_MMPLL>, -+ <&g3dsys CLK_G3DSYS_CORE>; -+ clock-names = "bus", "core"; -+ power-domains = <&scpsys MT2701_POWER_DOMAIN_MFG>; -+ mediatek,larb = <&larb3>; -+ resets = <&g3dsys MT2701_G3DSYS_CORE_RST>; -+ }; -+ - mmsys: syscon@14000000 { - compatible = "mediatek,mt7623-mmsys", - "mediatek,mt2701-mmsys", diff --git a/root/target/linux/mediatek/patches-5.4/0180-lima-power-on-off.patch b/root/target/linux/mediatek/patches-5.4/0180-lima-power-on-off.patch deleted file mode 100644 index fe4b742c..00000000 --- a/root/target/linux/mediatek/patches-5.4/0180-lima-power-on-off.patch +++ /dev/null @@ -1,68 +0,0 @@ -From d87e1a23e51158f9c2923f6213a42d5e942a4091 Mon Sep 17 00:00:00 2001 -From: Frank Wunderlich -Date: Thu, 23 Jan 2020 07:16:30 +0100 -Subject: [PATCH] lima: power on/off via register (function) - ---- - drivers/gpu/drm/lima/lima_device.c | 31 ++++++++++++++++++++++++++++++ - 1 file changed, 31 insertions(+) - -diff --git a/drivers/gpu/drm/lima/lima_device.c b/drivers/gpu/drm/lima/lima_device.c -index d86b8d81a483..7d5d45e176f2 100644 ---- a/drivers/gpu/drm/lima/lima_device.c -+++ b/drivers/gpu/drm/lima/lima_device.c -@@ -6,6 +6,7 @@ - #include - #include - #include -+#include - - #include "lima_device.h" - #include "lima_gp.h" -@@ -287,11 +288,33 @@ static void lima_fini_pp_pipe(struct lima_device *dev) - lima_sched_pipe_fini(pipe); - } - -+void mtk_set_power(bool on) -+{ -+ if (on) { -+ void __iomem *wakeup_register; -+ wakeup_register = ioremap(0x10003014 , 0x04); -+ writel(0x00000001,wakeup_register); // this may be wrong, may need bitbang 0th bit to 1 -+ iounmap(wakeup_register); -+ }else { -+ void __iomem *powerdown_register; -+ powerdown_register = ioremap(0x1000300C , 0x04); // powerdown register -+ writel(0x00000001,powerdown_register); // this may be wrong, may need bitbang 0th bit to 1 -+ iounmap(powerdown_register); -+ } -+} -+ - int lima_device_init(struct lima_device *ldev) - { - int err, i; - struct resource *res; - -+ #ifdef CONFIG_MTK_COMBO_CHIP_CONSYS_7623 -+ mtk_set_power(true); -+ pm_runtime_enable(ldev->dev); -+ pm_runtime_set_active(ldev->dev); -+ pm_runtime_get_sync(ldev->dev); -+ #endif -+ - dma_set_coherent_mask(ldev->dev, DMA_BIT_MASK(32)); - - err = lima_clk_init(ldev); -@@ -385,4 +408,12 @@ void lima_device_fini(struct lima_device *ldev) - lima_regulator_fini(ldev); - - lima_clk_fini(ldev); -+ -+ #ifdef CONFIG_MTK_COMBO_CHIP_CONSYS_7623 -+ pm_runtime_set_suspended(ldev->dev); -+ pm_runtime_put_noidle(ldev->dev); -+ pm_runtime_disable(ldev->dev); -+ -+ mtk_set_power(false); -+ #endif - } diff --git a/root/target/linux/mediatek/patches-5.4/0181-drm-Add-get_possible_crtc.patch b/root/target/linux/mediatek/patches-5.4/0181-drm-Add-get_possible_crtc.patch deleted file mode 100644 index ff149dce..00000000 --- a/root/target/linux/mediatek/patches-5.4/0181-drm-Add-get_possible_crtc.patch +++ /dev/null @@ -1,84 +0,0 @@ -From 452b508468a46ef0fe7357fab6b000c52fd047d3 Mon Sep 17 00:00:00 2001 -From: Stu Hsieh -Date: Fri, 16 Nov 2018 16:33:00 +0100 -Subject: [PATCH] drm: Add get_possible_crtc API for dpi, dsi - -Test: build pass and run ok - -Signed-off-by: Stu Hsieh ---- - drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 40 +++++++++++++++++++++ - drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h | 2 ++ - 2 files changed, 42 insertions(+) - -diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c -index efa85973e46b..29796e78b26a 100644 ---- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c -+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c -@@ -237,6 +237,22 @@ static const struct mtk_ddp_comp_match mtk_ddp_matches[DDP_COMPONENT_ID_MAX] = { - [DDP_COMPONENT_WDMA1] = { MTK_DISP_WDMA, 1, NULL }, - }; - -+static bool mtk_drm_find_comp_in_ddp(struct mtk_ddp_comp ddp_comp, -+ const enum mtk_ddp_comp_id *path, -+ unsigned int path_len) -+{ -+ unsigned int i; -+ -+ if (path == NULL) -+ return false; -+ -+ for (i = 0U; i < path_len; i++) -+ if (ddp_comp.id == path[i]) -+ return true; -+ -+ return false; -+} -+ - int mtk_ddp_comp_get_id(struct device_node *node, - enum mtk_ddp_comp_type comp_type) - { -@@ -252,6 +268,30 @@ int mtk_ddp_comp_get_id(struct device_node *node, - return -EINVAL; - } - -+unsigned int mtk_drm_find_possible_crtc_by_comp(struct drm_device *drm, -+ struct mtk_ddp_comp ddp_comp) -+{ -+ struct mtk_drm_private *private = drm->dev_private; -+ unsigned int ret; -+ -+ if (mtk_drm_find_comp_in_ddp(ddp_comp, private->data->main_path, -+ private->data->main_len) == true) { -+ ret = BIT(0); -+ } else if (mtk_drm_find_comp_in_ddp(ddp_comp, -+ private->data->ext_path, -+ private->data->ext_len) == true) { -+ ret = BIT(1); -+ } else if (mtk_drm_find_comp_in_ddp(ddp_comp, -+ private->data->third_path, -+ private->data->third_len) == true) { -+ ret = BIT(2); -+ } else { -+ DRM_INFO("Failed to find comp in ddp table\n"); -+ ret = 0; -+ } -+ return ret; -+} -+ - int mtk_ddp_comp_init(struct device *dev, struct device_node *node, - struct mtk_ddp_comp *comp, enum mtk_ddp_comp_id comp_id, - const struct mtk_ddp_comp_funcs *funcs) -diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h -index 0ad287f427cc..97be111c3e52 100644 ---- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h -+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h -@@ -160,6 +160,8 @@ static inline void mtk_ddp_gamma_set(struct mtk_ddp_comp *comp, - - int mtk_ddp_comp_get_id(struct device_node *node, - enum mtk_ddp_comp_type comp_type); -+unsigned int mtk_drm_find_possible_crtc_by_comp(struct drm_device *drm, -+ struct mtk_ddp_comp ddp_comp); - int mtk_ddp_comp_init(struct device *dev, struct device_node *comp_node, - struct mtk_ddp_comp *comp, enum mtk_ddp_comp_id comp_id, - const struct mtk_ddp_comp_funcs *funcs); diff --git a/root/target/linux/mediatek/patches-5.4/0182-drm-change-possible_crtc.patch b/root/target/linux/mediatek/patches-5.4/0182-drm-change-possible_crtc.patch deleted file mode 100644 index c92e18cc..00000000 --- a/root/target/linux/mediatek/patches-5.4/0182-drm-change-possible_crtc.patch +++ /dev/null @@ -1,45 +0,0 @@ -From f4ca44932ccf088f225062aafef04d2bd629b2c4 Mon Sep 17 00:00:00 2001 -From: Jitao Shi -Date: Fri, 3 May 2019 17:16:19 +0200 -Subject: [PATCH] drm/mediatek: dpi/dsi: change the getting possible_crtc way - -[Detail] -dpi/dsi get the possible_crtc by -mtk_drm_find_possible_crtc_by_comp(*drm_dev, ddp_comp) - -Test: build pass and boot to logo - -Signed-off-by: Jitao Shi ---- - drivers/gpu/drm/mediatek/mtk_dpi.c | 3 ++- - drivers/gpu/drm/mediatek/mtk_dsi.c | 3 ++- - 2 files changed, 4 insertions(+), 2 deletions(-) - -diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c -index be6d95c5ff25..00d31b5aa09f 100644 ---- a/drivers/gpu/drm/mediatek/mtk_dpi.c -+++ b/drivers/gpu/drm/mediatek/mtk_dpi.c -@@ -604,7 +604,8 @@ static int mtk_dpi_bind(struct device *dev, struct device *master, void *data) - drm_encoder_helper_add(&dpi->encoder, &mtk_dpi_encoder_helper_funcs); - - /* Currently DPI0 is fixed to be driven by OVL1 */ -- dpi->encoder.possible_crtcs = BIT(1); -+ dpi->encoder.possible_crtcs = -+ mtk_drm_find_possible_crtc_by_comp(drm_dev, dpi->ddp_comp); - - ret = drm_bridge_attach(&dpi->encoder, dpi->bridge, NULL); - if (ret) { -diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c -index 224afb666881..2c2d3643f3e8 100644 ---- a/drivers/gpu/drm/mediatek/mtk_dsi.c -+++ b/drivers/gpu/drm/mediatek/mtk_dsi.c -@@ -817,7 +817,8 @@ static int mtk_dsi_create_conn_enc(struct drm_device *drm, struct mtk_dsi *dsi) - * Currently display data paths are statically assigned to a crtc each. - * crtc 0 is OVL0 -> COLOR0 -> AAL -> OD -> RDMA0 -> UFOE -> DSI0 - */ -- dsi->encoder.possible_crtcs = 1; -+ dsi->encoder.possible_crtcs = -+ mtk_drm_find_possible_crtc_by_comp(drm, dsi->ddp_comp); - - /* If there's a bridge, attach to it and let it create the connector */ - if (dsi->bridge) { diff --git a/root/target/linux/mediatek/patches-5.4/0183-drm-fix-DRM_INFO.patch b/root/target/linux/mediatek/patches-5.4/0183-drm-fix-DRM_INFO.patch deleted file mode 100644 index 98bba9dc..00000000 --- a/root/target/linux/mediatek/patches-5.4/0183-drm-fix-DRM_INFO.patch +++ /dev/null @@ -1,21 +0,0 @@ -From 34dd2a86c9e3b3ad1a3a00add409edda2b2ed776 Mon Sep 17 00:00:00 2001 -From: Frank Wunderlich -Date: Tue, 1 Oct 2019 11:21:03 +0200 -Subject: [PATCH] drm: fix implicit declaration of function 'DRM_INFO' - ---- - drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c -index 29796e78b26a..e65d83267563 100644 ---- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c -+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c -@@ -12,6 +12,7 @@ - #include - #include - #include -+#include - - #include "mtk_drm_drv.h" - #include "mtk_drm_plane.h" diff --git a/root/target/linux/mediatek/patches-5.4/0184-drm-config-component-output.patch b/root/target/linux/mediatek/patches-5.4/0184-drm-config-component-output.patch deleted file mode 100644 index adc35c7d..00000000 --- a/root/target/linux/mediatek/patches-5.4/0184-drm-config-component-output.patch +++ /dev/null @@ -1,146 +0,0 @@ -From 6e3f7375acdcf714d1fcbae1238cd39cc9391560 Mon Sep 17 00:00:00 2001 -From: Bibby Hsieh -Date: Fri, 21 Sep 2018 11:28:22 +0800 -Subject: [PATCH] drm/mediatek: config component output by device node port - -We can select output component by decive node port. -Main path default output component is DSI. -External path default output component is DPI. - -Signed-off-by: Bibby Hsieh - -added small fixes for warnings - -Signed-off-by: Frank Wunderlich -Tested-by: Frank Wunderlich ---- - drivers/gpu/drm/mediatek/mtk_drm_drv.c | 46 ++++++++++++++++++++++---- - drivers/gpu/drm/mediatek/mtk_drm_drv.h | 4 +-- - 2 files changed, 42 insertions(+), 8 deletions(-) - -diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c -index 352b81a7a670..33511c77b800 100644 ---- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c -+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c -@@ -21,6 +21,13 @@ - #include - #include - #include -+#include -+#include -+#include -+#include -+#include -+#include -+#include - - #include "mtk_drm_crtc.h" - #include "mtk_drm_ddp.h" -@@ -121,7 +128,7 @@ static const struct drm_mode_config_funcs mtk_drm_mode_config_funcs = { - .atomic_commit = mtk_atomic_commit, - }; - --static const enum mtk_ddp_comp_id mt2701_mtk_ddp_main[] = { -+static enum mtk_ddp_comp_id mt2701_mtk_ddp_main[] = { - DDP_COMPONENT_OVL0, - DDP_COMPONENT_RDMA0, - DDP_COMPONENT_COLOR0, -@@ -129,12 +136,12 @@ static const enum mtk_ddp_comp_id mt2701_mtk_ddp_main[] = { - DDP_COMPONENT_DSI0, - }; - --static const enum mtk_ddp_comp_id mt2701_mtk_ddp_ext[] = { -+static enum mtk_ddp_comp_id mt2701_mtk_ddp_ext[] = { - DDP_COMPONENT_RDMA1, - DDP_COMPONENT_DPI0, - }; - --static const enum mtk_ddp_comp_id mt2712_mtk_ddp_main[] = { -+static enum mtk_ddp_comp_id mt2712_mtk_ddp_main[] = { - DDP_COMPONENT_OVL0, - DDP_COMPONENT_COLOR0, - DDP_COMPONENT_AAL0, -@@ -144,7 +151,7 @@ static const enum mtk_ddp_comp_id mt2712_mtk_ddp_main[] = { - DDP_COMPONENT_PWM0, - }; - --static const enum mtk_ddp_comp_id mt2712_mtk_ddp_ext[] = { -+static enum mtk_ddp_comp_id mt2712_mtk_ddp_ext[] = { - DDP_COMPONENT_OVL1, - DDP_COMPONENT_COLOR1, - DDP_COMPONENT_AAL1, -@@ -160,7 +167,7 @@ static const enum mtk_ddp_comp_id mt2712_mtk_ddp_third[] = { - DDP_COMPONENT_PWM2, - }; - --static const enum mtk_ddp_comp_id mt8173_mtk_ddp_main[] = { -+static enum mtk_ddp_comp_id mt8173_mtk_ddp_main[] = { - DDP_COMPONENT_OVL0, - DDP_COMPONENT_COLOR0, - DDP_COMPONENT_AAL0, -@@ -171,7 +178,7 @@ static const enum mtk_ddp_comp_id mt8173_mtk_ddp_main[] = { - DDP_COMPONENT_PWM0, - }; - --static const enum mtk_ddp_comp_id mt8173_mtk_ddp_ext[] = { -+static enum mtk_ddp_comp_id mt8173_mtk_ddp_ext[] = { - DDP_COMPONENT_OVL1, - DDP_COMPONENT_COLOR1, - DDP_COMPONENT_GAMMA, -@@ -510,6 +517,7 @@ static int mtk_drm_probe(struct platform_device *pdev) - - /* Iterate over sibling DISP function blocks */ - for_each_child_of_node(dev->of_node->parent, node) { -+ struct device_node *port, *ep, *remote; - const struct of_device_id *of_id; - enum mtk_ddp_comp_type comp_type; - int comp_id; -@@ -572,6 +580,32 @@ static int mtk_drm_probe(struct platform_device *pdev) - - private->ddp_comp[comp_id] = comp; - } -+ -+ if (comp_type != MTK_DSI && comp_type != MTK_DPI) { -+ port = of_graph_get_port_by_id(node, 0); -+ if (!port) -+ continue; -+ ep = of_get_child_by_name(port, "endpoint"); -+ of_node_put(port); -+ if (!ep) -+ continue; -+ remote = of_graph_get_remote_port_parent(ep); -+ of_node_put(ep); -+ if (!remote) -+ continue; -+ of_id = of_match_node(mtk_ddp_comp_dt_ids, remote); -+ if (!of_id) -+ continue; -+ comp_type = (enum mtk_ddp_comp_type)of_id->data; -+ for (i = 0; i < private->data->main_len - 1; i++) -+ if (private->data->main_path[i] == comp_id) -+ private->data->main_path[i + 1] = -+ mtk_ddp_comp_get_id(node, comp_type); -+ for (i = 0; i < private->data->ext_len - 1; i++) -+ if (private->data->ext_path[i] == comp_id) -+ private->data->ext_path[i + 1] = -+ mtk_ddp_comp_get_id(node, comp_type); -+ } - } - - if (!private->mutex_node) { -diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.h b/drivers/gpu/drm/mediatek/mtk_drm_drv.h -index e03fea12ff59..5fb723415ff6 100644 ---- a/drivers/gpu/drm/mediatek/mtk_drm_drv.h -+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.h -@@ -21,9 +21,9 @@ struct drm_property; - struct regmap; - - struct mtk_mmsys_driver_data { -- const enum mtk_ddp_comp_id *main_path; -+ enum mtk_ddp_comp_id *main_path; - unsigned int main_len; -- const enum mtk_ddp_comp_id *ext_path; -+ enum mtk_ddp_comp_id *ext_path; - unsigned int ext_len; - const enum mtk_ddp_comp_id *third_path; - unsigned int third_len; diff --git a/root/target/linux/mediatek/patches-5.4/0185-drm-fix-boot-up.patch b/root/target/linux/mediatek/patches-5.4/0185-drm-fix-boot-up.patch deleted file mode 100644 index 247853f3..00000000 --- a/root/target/linux/mediatek/patches-5.4/0185-drm-fix-boot-up.patch +++ /dev/null @@ -1,55 +0,0 @@ -From ba9c6527b05d294bdda7910db224e327f1460166 Mon Sep 17 00:00:00 2001 -From: chunhui dai -Date: Wed, 31 Oct 2018 16:59:34 +0800 -Subject: [PATCH] drm/mediatek: fix boot up for 720 and 480 but 1080 - -- 1080 plg in/out with ng/ok -- support other resolutions like 1280x1024 - -Signed-off-by: chunhui dai -Signed-off-by: Frank Wunderlich -Tested-by: Frank Wunderlich ---- - drivers/gpu/drm/mediatek/mtk_hdmi_phy.c | 3 +++ - drivers/gpu/drm/mediatek/mtk_hdmi_phy.h | 1 + - drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c | 1 + - 3 files changed, 5 insertions(+) - -diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi_phy.c b/drivers/gpu/drm/mediatek/mtk_hdmi_phy.c -index 5223498502c4..edadb7a700f1 100644 ---- a/drivers/gpu/drm/mediatek/mtk_hdmi_phy.c -+++ b/drivers/gpu/drm/mediatek/mtk_hdmi_phy.c -@@ -184,6 +184,9 @@ static int mtk_hdmi_phy_probe(struct platform_device *pdev) - return PTR_ERR(phy_provider); - } - -+ if (hdmi_phy->conf->pll_default_off) -+ hdmi_phy->conf->hdmi_phy_disable_tmds(hdmi_phy); -+ - return of_clk_add_provider(dev->of_node, of_clk_src_simple_get, - hdmi_phy->pll); - } -diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi_phy.h b/drivers/gpu/drm/mediatek/mtk_hdmi_phy.h -index 2d8b3182470d..f472fdeb63dc 100644 ---- a/drivers/gpu/drm/mediatek/mtk_hdmi_phy.h -+++ b/drivers/gpu/drm/mediatek/mtk_hdmi_phy.h -@@ -22,6 +22,7 @@ struct mtk_hdmi_phy; - struct mtk_hdmi_phy_conf { - bool tz_disabled; - unsigned long flags; -+ bool pll_default_off; - const struct clk_ops *hdmi_phy_clk_ops; - void (*hdmi_phy_enable_tmds)(struct mtk_hdmi_phy *hdmi_phy); - void (*hdmi_phy_disable_tmds)(struct mtk_hdmi_phy *hdmi_phy); -diff --git a/drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c b/drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c -index d3cc4022e988..6fbedacfc1e8 100644 ---- a/drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c -+++ b/drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c -@@ -239,6 +239,7 @@ static void mtk_hdmi_phy_disable_tmds(struct mtk_hdmi_phy *hdmi_phy) - struct mtk_hdmi_phy_conf mtk_hdmi_phy_2701_conf = { - .tz_disabled = true, - .flags = CLK_SET_RATE_GATE, -+ .pll_default_off = true, - .hdmi_phy_clk_ops = &mtk_hdmi_phy_pll_ops, - .hdmi_phy_enable_tmds = mtk_hdmi_phy_enable_tmds, - .hdmi_phy_disable_tmds = mtk_hdmi_phy_disable_tmds, diff --git a/root/target/linux/mediatek/patches-5.4/0190-thermal-add-sensor.patch b/root/target/linux/mediatek/patches-5.4/0190-thermal-add-sensor.patch deleted file mode 100644 index cc897705..00000000 --- a/root/target/linux/mediatek/patches-5.4/0190-thermal-add-sensor.patch +++ /dev/null @@ -1,56 +0,0 @@ -From aa97a44297179ab6ba1aa8f59e781541a320066b Mon Sep 17 00:00:00 2001 -From: Frank Wunderlich -Date: Fri, 31 Jan 2020 17:28:04 +0100 -Subject: [PATCH] thermal: mediatek: add sensors-support - ---- - drivers/thermal/mtk_thermal.c | 22 ++++++++++++++++++++++ - 1 file changed, 22 insertions(+) - -diff --git a/drivers/thermal/mtk_thermal.c b/drivers/thermal/mtk_thermal.c -index d1b066383c45..8cf3a69bfa46 100644 ---- a/drivers/thermal/mtk_thermal.c -+++ b/drivers/thermal/mtk_thermal.c -@@ -23,6 +23,8 @@ - #include - #include - -+#include "thermal_hwmon.h" -+ - /* AUXADC Registers */ - #define AUXADC_CON1_SET_V 0x008 - #define AUXADC_CON1_CLR_V 0x00c -@@ -990,6 +992,13 @@ static void mtk_thermal_release_periodic_ts(struct mtk_thermal *mt, - writel((tmp & (~0x10e)), mt->thermal_base + TEMP_MSRCTL1); - } - -+static void mtk_thermal_hwmon_action(void *data) -+{ -+ struct thermal_zone_device *zone = data; -+ -+ thermal_remove_hwmon_sysfs(zone); -+} -+ - static int mtk_thermal_probe(struct platform_device *pdev) - { - int ret, i, ctrl_id; -@@ -1094,6 +1103,19 @@ static int mtk_thermal_probe(struct platform_device *pdev) - goto err_disable_clk_peri_therm; - } - -+ tzdev->tzp->no_hwmon = false; -+ ret = thermal_add_hwmon_sysfs(tzdev); -+ if (ret) -+ dev_err(&pdev->dev,"error in thermal_add_hwmon_sysfs"); -+ //goto err_disable_clk_peri_therm; -+ -+ ret = devm_add_action(&pdev->dev, mtk_thermal_hwmon_action, tzdev); -+ if (ret) { -+ dev_err(&pdev->dev,"error in devm_add_action"); -+ mtk_thermal_hwmon_action(tzdev); -+ //goto err_disable_clk_peri_therm; -+ } -+ - return 0; - - err_disable_clk_peri_therm: diff --git a/root/target/linux/mediatek/patches-5.4/0191-thermal.patch b/root/target/linux/mediatek/patches-5.4/0191-thermal.patch deleted file mode 100644 index 01ead975..00000000 --- a/root/target/linux/mediatek/patches-5.4/0191-thermal.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 9847677bda4920bbba15499f28009ce095f02c99 Mon Sep 17 00:00:00 2001 -From: Frank Wunderlich -Date: Fri, 31 Jan 2020 18:49:56 +0100 -Subject: [PATCH] thermal: mediatek: execute hwmon-code only if hwmon_thermal - is set - ---- - drivers/thermal/mtk_thermal.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/drivers/thermal/mtk_thermal.c b/drivers/thermal/mtk_thermal.c -index 8cf3a69bfa46..3a646b88f587 100644 ---- a/drivers/thermal/mtk_thermal.c -+++ b/drivers/thermal/mtk_thermal.c -@@ -1103,18 +1103,18 @@ static int mtk_thermal_probe(struct platform_device *pdev) - goto err_disable_clk_peri_therm; - } - -+#ifdef CONFIG_THERMAL_HWMON - tzdev->tzp->no_hwmon = false; - ret = thermal_add_hwmon_sysfs(tzdev); - if (ret) - dev_err(&pdev->dev,"error in thermal_add_hwmon_sysfs"); -- //goto err_disable_clk_peri_therm; - - ret = devm_add_action(&pdev->dev, mtk_thermal_hwmon_action, tzdev); - if (ret) { - dev_err(&pdev->dev,"error in devm_add_action"); - mtk_thermal_hwmon_action(tzdev); -- //goto err_disable_clk_peri_therm; - } -+#endif - - return 0; - diff --git a/root/target/linux/mediatek/patches-5.4/0230-pthread.patch b/root/target/linux/mediatek/patches-5.4/0230-pthread.patch deleted file mode 100644 index ab5523cf..00000000 --- a/root/target/linux/mediatek/patches-5.4/0230-pthread.patch +++ /dev/null @@ -1,14 +0,0 @@ ---- a/scripts/Makefile 2020-03-21 22:28:13.290800484 +0800 -+++ b/scripts/Makefile 2020-03-21 22:28:26.230870790 +0800 -@@ -23,8 +23,8 @@ hostprogs-$(CONFIG_SYSTEM_EXTRA_CERTIFIC - - HOSTCFLAGS_sortextable.o = -I$(srctree)/tools/include - HOSTCFLAGS_asn1_compiler.o = -I$(srctree)/include --HOSTLDLIBS_sign-file = -lcrypto --HOSTLDLIBS_extract-cert = -lcrypto -+HOSTLDLIBS_sign-file = -lcrypto -lpthread -+HOSTLDLIBS_extract-cert = -lcrypto -lpthread - - always := $(hostprogs-y) $(hostprogs-m) - - diff --git a/root/target/linux/mediatek/patches-5.4/0999-lan-to-wan.patch b/root/target/linux/mediatek/patches-5.4/0999-lan-to-wan.patch deleted file mode 100644 index d780caba..00000000 --- a/root/target/linux/mediatek/patches-5.4/0999-lan-to-wan.patch +++ /dev/null @@ -1,49 +0,0 @@ ---- a/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts 2020-04-19 11:02:56.505715879 +0200 -+++ b/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts 2020-04-19 11:03:53.620780390 +0200 -@@ -196,7 +196,7 @@ - gmac1: mac@1 { - compatible = "mediatek,eth-mac"; - reg = <1>; -- label = "wan"; -+ label = "lan"; - phy-mode = "rgmii"; - phy-handle = <&ephy0>; - local-mac-address = [00 0a 35 00 00 02]; -@@ -221,31 +221,31 @@ - #address-cells = <1>; - #size-cells = <0>; - --/* Disabled, is now handled by gmac1 (eth1/wan) via phy-handle! -+/* Disabled, is now handled by gmac1 (eth1/lan) via phy-handle! - port@0 { - reg = <0>; -- label = "wan"; -+ label = "lan"; - }; - */ - - port@1 { - reg = <1>; -- label = "lan0"; -+ label = "wan1"; - }; - - port@2 { - reg = <2>; -- label = "lan1"; -+ label = "wan2"; - }; - - port@3 { - reg = <3>; -- label = "lan2"; -+ label = "wan3"; - }; - - port@4 { - reg = <4>; -- label = "lan3"; -+ label = "wan4"; - }; - - port@6 { diff --git a/root/target/linux/mvebu/config-4.14 b/root/target/linux/mvebu/config-4.14 deleted file mode 100644 index 0efd8f5c..00000000 --- a/root/target/linux/mvebu/config-4.14 +++ /dev/null @@ -1,498 +0,0 @@ -CONFIG_AHCI_MVEBU=y -CONFIG_ALIGNMENT_TRAP=y -CONFIG_ARCH_CLOCKSOURCE_DATA=y -CONFIG_ARCH_HAS_DEBUG_VIRTUAL=y -CONFIG_ARCH_HAS_ELF_RANDOMIZE=y -CONFIG_ARCH_HAS_GCOV_PROFILE_ALL=y -CONFIG_ARCH_HAS_SET_MEMORY=y -CONFIG_ARCH_HAS_SG_CHAIN=y -CONFIG_ARCH_HAS_STRICT_KERNEL_RWX=y -CONFIG_ARCH_HAS_STRICT_MODULE_RWX=y -CONFIG_ARCH_HAS_TICK_BROADCAST=y -CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y -CONFIG_ARCH_HIBERNATION_POSSIBLE=y -CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y -CONFIG_ARCH_MULTIPLATFORM=y -# CONFIG_ARCH_MULTI_CPU_AUTO is not set -CONFIG_ARCH_MULTI_V6_V7=y -CONFIG_ARCH_MULTI_V7=y -CONFIG_ARCH_MVEBU=y -CONFIG_ARCH_NR_GPIO=0 -CONFIG_ARCH_OPTIONAL_KERNEL_RWX=y -CONFIG_ARCH_OPTIONAL_KERNEL_RWX_DEFAULT=y -# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set -# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set -CONFIG_ARCH_SUPPORTS_ATOMIC_RMW=y -CONFIG_ARCH_SUPPORTS_BIG_ENDIAN=y -CONFIG_ARCH_SUPPORTS_UPROBES=y -CONFIG_ARCH_SUSPEND_POSSIBLE=y -CONFIG_ARCH_USE_BUILTIN_BSWAP=y -CONFIG_ARCH_USE_CMPXCHG_LOCKREF=y -CONFIG_ARCH_WANT_GENERAL_HUGETLB=y -CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y -CONFIG_ARM=y -CONFIG_ARMADA_370_CLK=y -CONFIG_ARMADA_370_XP_IRQ=y -CONFIG_ARMADA_370_XP_TIMER=y -CONFIG_ARMADA_38X_CLK=y -CONFIG_ARMADA_THERMAL=y -CONFIG_ARMADA_XP_CLK=y -CONFIG_ARM_APPENDED_DTB=y -# CONFIG_ARM_ARMADA_37XX_CPUFREQ is not set -CONFIG_ARM_ATAG_DTB_COMPAT=y -# CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_EXTEND is not set -# CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_FROM_BOOTLOADER is not set -CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_MANGLE=y -CONFIG_ARM_CPU_SUSPEND=y -CONFIG_ARM_CRYPTO=y -CONFIG_ARM_ERRATA_720789=y -CONFIG_ARM_ERRATA_764369=y -CONFIG_ARM_GIC=y -CONFIG_ARM_GLOBAL_TIMER=y -CONFIG_ARM_HAS_SG_CHAIN=y -CONFIG_ARM_HEAVY_MB=y -CONFIG_ARM_L1_CACHE_SHIFT=6 -CONFIG_ARM_L1_CACHE_SHIFT_6=y -# CONFIG_ARM_LPAE is not set -CONFIG_ARM_MODULE_PLTS=y -CONFIG_ARM_MVEBU_V7_CPUIDLE=y -CONFIG_ARM_PATCH_IDIV=y -CONFIG_ARM_PATCH_PHYS_VIRT=y -CONFIG_ARM_THUMB=y -# CONFIG_ARM_THUMBEE is not set -CONFIG_ARM_UNWIND=y -CONFIG_ARM_VIRT_EXT=y -CONFIG_ASYNC_TX_ENABLE_CHANNEL_SWITCH=y -CONFIG_ATA=y -CONFIG_ATAGS=y -CONFIG_AUTO_ZRELADDR=y -CONFIG_BLK_DEV_LOOP=y -CONFIG_BLK_DEV_SD=y -CONFIG_BLK_MQ_PCI=y -CONFIG_BLK_SCSI_REQUEST=y -CONFIG_BOUNCE=y -# CONFIG_CACHE_FEROCEON_L2 is not set -CONFIG_CACHE_L2X0=y -CONFIG_CLKDEV_LOOKUP=y -CONFIG_CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK=y -CONFIG_CLKSRC_MMIO=y -CONFIG_CLONE_BACKWARDS=y -CONFIG_COMMON_CLK=y -CONFIG_CPUFREQ_DT=y -CONFIG_CPUFREQ_DT_PLATDEV=y -CONFIG_CPU_32v6K=y -CONFIG_CPU_32v7=y -CONFIG_CPU_ABRT_EV7=y -# CONFIG_CPU_BIG_ENDIAN is not set -# CONFIG_CPU_BPREDICT_DISABLE is not set -CONFIG_CPU_CACHE_V7=y -CONFIG_CPU_CACHE_VIPT=y -CONFIG_CPU_COPY_V6=y -CONFIG_CPU_CP15=y -CONFIG_CPU_CP15_MMU=y -CONFIG_CPU_FREQ=y -CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y -# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set -CONFIG_CPU_FREQ_GOV_ATTR_SET=y -CONFIG_CPU_FREQ_GOV_COMMON=y -# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set -CONFIG_CPU_FREQ_GOV_ONDEMAND=y -CONFIG_CPU_FREQ_GOV_PERFORMANCE=y -# CONFIG_CPU_FREQ_GOV_POWERSAVE is not set -# CONFIG_CPU_FREQ_GOV_USERSPACE is not set -CONFIG_CPU_FREQ_STAT=y -CONFIG_CPU_HAS_ASID=y -# CONFIG_CPU_HOTPLUG_STATE_CONTROL is not set -# CONFIG_CPU_ICACHE_DISABLE is not set -CONFIG_CPU_IDLE=y -CONFIG_CPU_IDLE_GOV_LADDER=y -CONFIG_CPU_PABRT_V7=y -CONFIG_CPU_PJ4B=y -CONFIG_CPU_PM=y -CONFIG_CPU_RMAP=y -CONFIG_CPU_SPECTRE=y -CONFIG_CPU_THERMAL=y -CONFIG_CPU_THUMB_CAPABLE=y -CONFIG_CPU_TLB_V7=y -CONFIG_CPU_V7=y -CONFIG_CRC16=y -CONFIG_CRYPTO_ACOMP2=y -CONFIG_CRYPTO_AEAD=y -CONFIG_CRYPTO_AEAD2=y -CONFIG_CRYPTO_AES_ARM=y -CONFIG_CRYPTO_AES_ARM_BS=y -# CONFIG_CRYPTO_AES_ARM_CE is not set -# CONFIG_CRYPTO_CHACHA20_NEON is not set -CONFIG_CRYPTO_CRC32=y -CONFIG_CRYPTO_CRC32C=y -# CONFIG_CRYPTO_CRC32_ARM_CE is not set -CONFIG_CRYPTO_CRYPTD=y -CONFIG_CRYPTO_DEFLATE=y -CONFIG_CRYPTO_DES=y -CONFIG_CRYPTO_DEV_MARVELL_CESA=y -# CONFIG_CRYPTO_GHASH_ARM_CE is not set -CONFIG_CRYPTO_HASH=y -CONFIG_CRYPTO_HASH2=y -CONFIG_CRYPTO_HW=y -CONFIG_CRYPTO_LZO=y -CONFIG_CRYPTO_MANAGER=y -CONFIG_CRYPTO_MANAGER2=y -CONFIG_CRYPTO_NULL2=y -CONFIG_CRYPTO_RNG2=y -CONFIG_CRYPTO_SHA1=y -CONFIG_CRYPTO_SHA1_ARM=y -# CONFIG_CRYPTO_SHA1_ARM_CE is not set -CONFIG_CRYPTO_SHA1_ARM_NEON=y -CONFIG_CRYPTO_SHA256_ARM=y -# CONFIG_CRYPTO_SHA2_ARM_CE is not set -CONFIG_CRYPTO_SHA512_ARM=y -CONFIG_CRYPTO_SIMD=y -CONFIG_CRYPTO_WORKQUEUE=y -CONFIG_DCACHE_WORD_ACCESS=y -CONFIG_DEBUG_ALIGN_RODATA=y -CONFIG_DEBUG_INFO=y -CONFIG_DEBUG_LL=y -CONFIG_DEBUG_LL_INCLUDE="debug/8250.S" -CONFIG_DEBUG_MVEBU_UART0=y -# CONFIG_DEBUG_MVEBU_UART0_ALTERNATE is not set -# CONFIG_DEBUG_MVEBU_UART1_ALTERNATE is not set -CONFIG_DEBUG_UART_8250=y -# CONFIG_DEBUG_UART_8250_FLOW_CONTROL is not set -CONFIG_DEBUG_UART_8250_SHIFT=2 -# CONFIG_DEBUG_UART_8250_WORD is not set -CONFIG_DEBUG_UART_PHYS=0xd0012000 -CONFIG_DEBUG_UART_VIRT=0xfec12000 -CONFIG_DEBUG_UNCOMPRESS=y -CONFIG_DEBUG_USER=y -CONFIG_DMADEVICES=y -CONFIG_DMA_ENGINE=y -CONFIG_DMA_ENGINE_RAID=y -CONFIG_DMA_OF=y -CONFIG_DTC=y -CONFIG_EARLY_PRINTK=y -CONFIG_EDAC_ATOMIC_SCRUB=y -CONFIG_EDAC_SUPPORT=y -CONFIG_EXT4_FS=y -CONFIG_EXTCON=y -# CONFIG_F2FS_CHECK_FS is not set -CONFIG_F2FS_FS=y -# CONFIG_F2FS_FS_SECURITY is not set -CONFIG_F2FS_FS_XATTR=y -CONFIG_F2FS_STAT_FS=y -CONFIG_FIXED_PHY=y -CONFIG_FIX_EARLYCON_MEM=y -CONFIG_FS_MBCACHE=y -CONFIG_GENERIC_ALLOCATOR=y -CONFIG_GENERIC_ARCH_TOPOLOGY=y -CONFIG_GENERIC_BUG=y -CONFIG_GENERIC_CLOCKEVENTS=y -CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y -CONFIG_GENERIC_CPU_AUTOPROBE=y -CONFIG_GENERIC_EARLY_IOREMAP=y -CONFIG_GENERIC_IDLE_POLL_SETUP=y -CONFIG_GENERIC_IO=y -CONFIG_GENERIC_IRQ_CHIP=y -CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y -CONFIG_GENERIC_IRQ_SHOW=y -CONFIG_GENERIC_IRQ_SHOW_LEVEL=y -CONFIG_GENERIC_MSI_IRQ=y -CONFIG_GENERIC_MSI_IRQ_DOMAIN=y -CONFIG_GENERIC_PCI_IOMAP=y -CONFIG_GENERIC_PHY=y -CONFIG_GENERIC_SCHED_CLOCK=y -CONFIG_GENERIC_SMP_IDLE_THREAD=y -CONFIG_GENERIC_STRNCPY_FROM_USER=y -CONFIG_GENERIC_STRNLEN_USER=y -CONFIG_GLOB=y -CONFIG_GPIOLIB=y -CONFIG_GPIOLIB_IRQCHIP=y -CONFIG_GPIO_GENERIC=y -CONFIG_GPIO_GENERIC_PLATFORM=y -CONFIG_GPIO_MVEBU=y -CONFIG_GPIO_PCA953X=y -CONFIG_GPIO_PCA953X_IRQ=y -CONFIG_GPIO_SYSFS=y -# CONFIG_GRO_CELLS is not set -CONFIG_HANDLE_DOMAIN_IRQ=y -CONFIG_HARDEN_BRANCH_PREDICTOR=y -CONFIG_HARDIRQS_SW_RESEND=y -CONFIG_HAS_DMA=y -CONFIG_HAS_IOMEM=y -CONFIG_HAS_IOPORT_MAP=y -# CONFIG_HAVE_64BIT_ALIGNED_ACCESS is not set -CONFIG_HAVE_ARCH_AUDITSYSCALL=y -CONFIG_HAVE_ARCH_BITREVERSE=y -CONFIG_HAVE_ARCH_JUMP_LABEL=y -CONFIG_HAVE_ARCH_KGDB=y -CONFIG_HAVE_ARCH_PFN_VALID=y -CONFIG_HAVE_ARCH_SECCOMP_FILTER=y -CONFIG_HAVE_ARCH_TRACEHOOK=y -CONFIG_HAVE_ARM_SCU=y -CONFIG_HAVE_ARM_SMCCC=y -CONFIG_HAVE_ARM_TWD=y -# CONFIG_HAVE_BOOTMEM_INFO_NODE is not set -CONFIG_HAVE_CC_STACKPROTECTOR=y -CONFIG_HAVE_CLK=y -CONFIG_HAVE_CLK_PREPARE=y -CONFIG_HAVE_CONTEXT_TRACKING=y -CONFIG_HAVE_C_RECORDMCOUNT=y -CONFIG_HAVE_DEBUG_KMEMLEAK=y -CONFIG_HAVE_DMA_API_DEBUG=y -CONFIG_HAVE_DMA_CONTIGUOUS=y -CONFIG_HAVE_DYNAMIC_FTRACE=y -CONFIG_HAVE_DYNAMIC_FTRACE_WITH_REGS=y -CONFIG_HAVE_EBPF_JIT=y -CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y -CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y -CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y -CONFIG_HAVE_FUNCTION_TRACER=y -CONFIG_HAVE_GENERIC_DMA_COHERENT=y -CONFIG_HAVE_IDE=y -CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y -CONFIG_HAVE_MEMBLOCK=y -CONFIG_HAVE_MOD_ARCH_SPECIFIC=y -CONFIG_HAVE_NET_DSA=y -CONFIG_HAVE_OPROFILE=y -CONFIG_HAVE_OPTPROBES=y -CONFIG_HAVE_PERF_EVENTS=y -CONFIG_HAVE_PERF_REGS=y -CONFIG_HAVE_PERF_USER_STACK_DUMP=y -CONFIG_HAVE_PROC_CPU=y -CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y -CONFIG_HAVE_SMP=y -CONFIG_HAVE_SYSCALL_TRACEPOINTS=y -CONFIG_HAVE_UID16=y -CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y -CONFIG_HIGHMEM=y -# CONFIG_HIGHPTE is not set -CONFIG_HOTPLUG_CPU=y -CONFIG_HWBM=y -CONFIG_HWMON=y -CONFIG_HW_RANDOM=y -# CONFIG_HW_RANDOM_OMAP is not set -CONFIG_HZ_FIXED=0 -CONFIG_HZ_PERIODIC=y -CONFIG_I2C=y -CONFIG_I2C_BOARDINFO=y -CONFIG_I2C_CHARDEV=y -CONFIG_I2C_MV64XXX=y -# CONFIG_I2C_PXA is not set -CONFIG_INITRAMFS_SOURCE="" -CONFIG_IOMMU_HELPER=y -CONFIG_IRQCHIP=y -CONFIG_IRQ_DOMAIN=y -CONFIG_IRQ_DOMAIN_DEBUG=y -CONFIG_IRQ_DOMAIN_HIERARCHY=y -CONFIG_IRQ_FORCED_THREADING=y -CONFIG_IRQ_WORK=y -# CONFIG_IWMMXT is not set -CONFIG_JBD2=y -CONFIG_LEDS_GPIO=y -CONFIG_LEDS_PCA963X=y -CONFIG_LEDS_TLC591XX=y -CONFIG_LEDS_TRIGGER_DISK=y -CONFIG_LIBFDT=y -CONFIG_LOCK_SPIN_ON_OWNER=y -CONFIG_LZO_COMPRESS=y -CONFIG_LZO_DECOMPRESS=y -CONFIG_MACH_ARMADA_370=y -# CONFIG_MACH_ARMADA_375 is not set -CONFIG_MACH_ARMADA_38X=y -# CONFIG_MACH_ARMADA_39X is not set -CONFIG_MACH_ARMADA_XP=y -# CONFIG_MACH_DOVE is not set -CONFIG_MACH_MVEBU_ANY=y -CONFIG_MACH_MVEBU_V7=y -CONFIG_MAGIC_SYSRQ=y -CONFIG_MANGLE_BOOTARGS=y -CONFIG_MARVELL_PHY=y -CONFIG_MDIO_BUS=y -CONFIG_MDIO_DEVICE=y -CONFIG_MDIO_I2C=y -CONFIG_MEMORY=y -CONFIG_MIGHT_HAVE_CACHE_L2X0=y -CONFIG_MIGHT_HAVE_PCI=y -CONFIG_MIGRATION=y -CONFIG_MMC=y -CONFIG_MMC_BLOCK=y -CONFIG_MMC_MVSDIO=y -CONFIG_MMC_SDHCI=y -# CONFIG_MMC_SDHCI_PCI is not set -CONFIG_MMC_SDHCI_PLTFM=y -CONFIG_MMC_SDHCI_PXAV3=y -# CONFIG_MMC_TIFM_SD is not set -CONFIG_MODULES_USE_ELF_REL=y -CONFIG_MTD_CFI_STAA=y -CONFIG_MTD_M25P80=y -CONFIG_MTD_NAND=y -CONFIG_MTD_NAND_ECC=y -CONFIG_MTD_NAND_PXA3xx=y -CONFIG_MTD_SPI_NOR=y -CONFIG_MTD_SPLIT_FIRMWARE=y -CONFIG_MTD_UBI=y -CONFIG_MTD_UBI_BEB_LIMIT=20 -CONFIG_MTD_UBI_BLOCK=y -# CONFIG_MTD_UBI_FASTMAP is not set -# CONFIG_MTD_UBI_GLUEBI is not set -CONFIG_MTD_UBI_WL_THRESHOLD=4096 -CONFIG_MULTI_IRQ_HANDLER=y -CONFIG_MUTEX_SPIN_ON_OWNER=y -CONFIG_MVEBU_CLK_COMMON=y -CONFIG_MVEBU_CLK_COREDIV=y -CONFIG_MVEBU_CLK_CPU=y -CONFIG_MVEBU_DEVBUS=y -CONFIG_MVEBU_MBUS=y -CONFIG_MVMDIO=y -CONFIG_MVNETA=y -CONFIG_MVNETA_BM=y -CONFIG_MVNETA_BM_ENABLE=y -CONFIG_MVPP2=y -CONFIG_MVSW61XX_PHY=y -CONFIG_MV_XOR=y -CONFIG_NEED_DMA_MAP_STATE=y -CONFIG_NEON=y -CONFIG_NET_DSA=y -CONFIG_NET_DSA_MV88E6XXX=y -CONFIG_NET_DSA_MV88E6XXX_GLOBAL2=y -CONFIG_NET_DSA_TAG_DSA=y -CONFIG_NET_DSA_TAG_EDSA=y -CONFIG_NET_FLOW_LIMIT=y -CONFIG_NET_SWITCHDEV=y -CONFIG_NLS=y -CONFIG_NOP_USB_XCEIV=y -CONFIG_NO_BOOTMEM=y -CONFIG_NR_CPUS=4 -CONFIG_OF=y -CONFIG_OF_ADDRESS=y -CONFIG_OF_ADDRESS_PCI=y -CONFIG_OF_EARLY_FLATTREE=y -CONFIG_OF_FLATTREE=y -CONFIG_OF_GPIO=y -CONFIG_OF_IRQ=y -CONFIG_OF_MDIO=y -CONFIG_OF_NET=y -CONFIG_OF_PCI=y -CONFIG_OF_PCI_IRQ=y -CONFIG_OF_RESERVED_MEM=y -CONFIG_OLD_SIGACTION=y -CONFIG_OLD_SIGSUSPEND3=y -CONFIG_ORION_WATCHDOG=y -CONFIG_OUTER_CACHE=y -CONFIG_OUTER_CACHE_SYNC=y -CONFIG_PADATA=y -CONFIG_PAGE_OFFSET=0xC0000000 -CONFIG_PCI=y -CONFIG_PCI_DOMAINS=y -CONFIG_PCI_DOMAINS_GENERIC=y -CONFIG_PCI_MSI=y -CONFIG_PCI_MSI_IRQ_DOMAIN=y -CONFIG_PCI_MVEBU=y -CONFIG_PERF_USE_VMALLOC=y -CONFIG_PGTABLE_LEVELS=2 -CONFIG_PHYLIB=y -CONFIG_PHYLINK=y -# CONFIG_PHY_MVEBU_CP110_COMPHY is not set -CONFIG_PINCTRL=y -CONFIG_PINCTRL_ARMADA_370=y -CONFIG_PINCTRL_ARMADA_38X=y -CONFIG_PINCTRL_ARMADA_XP=y -CONFIG_PINCTRL_MVEBU=y -# CONFIG_PINCTRL_SINGLE is not set -CONFIG_PJ4B_ERRATA_4742=y -# CONFIG_PL310_ERRATA_588369 is not set -# CONFIG_PL310_ERRATA_727915 is not set -CONFIG_PL310_ERRATA_753970=y -# CONFIG_PL310_ERRATA_769419 is not set -CONFIG_PLAT_ORION=y -CONFIG_PM_OPP=y -CONFIG_PRINTK_SAFE_LOG_BUF_SHIFT=11 -CONFIG_PWM=y -CONFIG_PWM_SYSFS=y -CONFIG_RATIONAL=y -CONFIG_RCU_NEED_SEGCBLIST=y -CONFIG_RCU_STALL_COMMON=y -CONFIG_REGMAP=y -CONFIG_REGMAP_I2C=y -CONFIG_REGMAP_MMIO=y -CONFIG_REGMAP_SPI=y -CONFIG_REGULATOR=y -CONFIG_REGULATOR_FIXED_VOLTAGE=y -CONFIG_RFS_ACCEL=y -CONFIG_RPS=y -CONFIG_RTC_CLASS=y -CONFIG_RTC_DRV_ARMADA38X=y -CONFIG_RTC_DRV_MV=y -CONFIG_RTC_I2C_AND_SPI=y -CONFIG_RTC_MC146818_LIB=y -CONFIG_RWSEM_SPIN_ON_OWNER=y -CONFIG_RWSEM_XCHGADD_ALGORITHM=y -CONFIG_SATA_AHCI_PLATFORM=y -CONFIG_SATA_MV=y -CONFIG_SATA_PMP=y -# CONFIG_SCHED_INFO is not set -CONFIG_SCSI=y -CONFIG_SENSORS_PWM_FAN=y -CONFIG_SENSORS_TMP421=y -CONFIG_SERIAL_8250_DW=y -CONFIG_SERIAL_8250_FSL=y -CONFIG_SERIAL_MVEBU_CONSOLE=y -CONFIG_SERIAL_MVEBU_UART=y -CONFIG_SFP=y -CONFIG_SG_POOL=y -CONFIG_SMP=y -CONFIG_SMP_ON_UP=y -CONFIG_SOC_BUS=y -CONFIG_SPARSE_IRQ=y -CONFIG_SPI=y -# CONFIG_SPI_ARMADA_3700 is not set -CONFIG_SPI_MASTER=y -CONFIG_SPI_ORION=y -CONFIG_SRAM=y -CONFIG_SRAM_EXEC=y -CONFIG_SRCU=y -CONFIG_SWCONFIG=y -CONFIG_SWIOTLB=y -CONFIG_SWPHY=y -CONFIG_SWP_EMULATE=y -CONFIG_SYS_SUPPORTS_APM_EMULATION=y -CONFIG_THERMAL=y -CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y -CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=0 -CONFIG_THERMAL_GOV_STEP_WISE=y -CONFIG_THERMAL_HWMON=y -CONFIG_THERMAL_OF=y -# CONFIG_THUMB2_KERNEL is not set -CONFIG_TICK_CPU_ACCOUNTING=y -CONFIG_TIMER_OF=y -CONFIG_TIMER_PROBE=y -CONFIG_TREE_RCU=y -CONFIG_TREE_SRCU=y -CONFIG_UBIFS_FS=y -# CONFIG_UBIFS_FS_ADVANCED_COMPR is not set -CONFIG_UBIFS_FS_LZO=y -CONFIG_UBIFS_FS_ZLIB=y -CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h" -CONFIG_USB=y -CONFIG_USB_COMMON=y -CONFIG_USB_EHCI_HCD=y -CONFIG_USB_EHCI_HCD_ORION=y -CONFIG_USB_EHCI_HCD_PLATFORM=y -CONFIG_USB_LEDS_TRIGGER_USBPORT=y -CONFIG_USB_PHY=y -CONFIG_USB_STORAGE=y -CONFIG_USB_SUPPORT=y -CONFIG_USB_XHCI_HCD=y -CONFIG_USB_XHCI_MVEBU=y -CONFIG_USB_XHCI_PLATFORM=y -CONFIG_USE_OF=y -CONFIG_VECTORS_BASE=0xffff0000 -CONFIG_VFP=y -CONFIG_VFPv3=y -CONFIG_WATCHDOG_CORE=y -CONFIG_XPS=y -CONFIG_XZ_DEC_ARM=y -CONFIG_XZ_DEC_BCJ=y -CONFIG_ZBOOT_ROM_BSS=0x0 -CONFIG_ZBOOT_ROM_TEXT=0x0 -CONFIG_ZLIB_DEFLATE=y -CONFIG_ZLIB_INFLATE=y diff --git a/root/target/linux/mvebu/config-4.19 b/root/target/linux/mvebu/config-4.19 deleted file mode 100644 index a2d815f9..00000000 --- a/root/target/linux/mvebu/config-4.19 +++ /dev/null @@ -1,531 +0,0 @@ -CONFIG_AHCI_MVEBU=y -CONFIG_ALIGNMENT_TRAP=y -CONFIG_ARCH_CLOCKSOURCE_DATA=y -CONFIG_ARCH_HAS_DEBUG_VIRTUAL=y -CONFIG_ARCH_HAS_ELF_RANDOMIZE=y -CONFIG_ARCH_HAS_FORTIFY_SOURCE=y -CONFIG_ARCH_HAS_GCOV_PROFILE_ALL=y -CONFIG_ARCH_HAS_KCOV=y -CONFIG_ARCH_HAS_MEMBARRIER_SYNC_CORE=y -CONFIG_ARCH_HAS_PHYS_TO_DMA=y -CONFIG_ARCH_HAS_SET_MEMORY=y -CONFIG_ARCH_HAS_SG_CHAIN=y -CONFIG_ARCH_HAS_STRICT_KERNEL_RWX=y -CONFIG_ARCH_HAS_STRICT_MODULE_RWX=y -CONFIG_ARCH_HAS_TICK_BROADCAST=y -CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y -CONFIG_ARCH_HIBERNATION_POSSIBLE=y -CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y -CONFIG_ARCH_MULTIPLATFORM=y -CONFIG_ARCH_MULTI_V6_V7=y -CONFIG_ARCH_MULTI_V7=y -CONFIG_ARCH_MVEBU=y -CONFIG_ARCH_NR_GPIO=0 -CONFIG_ARCH_OPTIONAL_KERNEL_RWX=y -CONFIG_ARCH_OPTIONAL_KERNEL_RWX_DEFAULT=y -CONFIG_ARCH_SUPPORTS_ATOMIC_RMW=y -CONFIG_ARCH_SUPPORTS_BIG_ENDIAN=y -CONFIG_ARCH_SUPPORTS_UPROBES=y -CONFIG_ARCH_SUSPEND_POSSIBLE=y -CONFIG_ARCH_USE_BUILTIN_BSWAP=y -CONFIG_ARCH_USE_CMPXCHG_LOCKREF=y -CONFIG_ARCH_WANT_GENERAL_HUGETLB=y -CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y -CONFIG_ARM=y -CONFIG_ARMADA375_USBCLUSTER_PHY=y -CONFIG_ARMADA_370_CLK=y -CONFIG_ARMADA_370_XP_IRQ=y -CONFIG_ARMADA_370_XP_TIMER=y -CONFIG_ARMADA_375_CLK=y -CONFIG_ARMADA_38X_CLK=y -CONFIG_ARMADA_39X_CLK=y -CONFIG_ARMADA_THERMAL=y -CONFIG_ARMADA_XP_CLK=y -CONFIG_ARM_APPENDED_DTB=y -# CONFIG_ARM_ARMADA_37XX_CPUFREQ is not set -CONFIG_ARM_ATAG_DTB_COMPAT=y -# CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_EXTEND is not set -# CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_FROM_BOOTLOADER is not set -CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_MANGLE=y -CONFIG_ARM_CPU_SUSPEND=y -CONFIG_ARM_CRYPTO=y -CONFIG_ARM_ERRATA_720789=y -CONFIG_ARM_ERRATA_764369=y -CONFIG_ARM_GIC=y -CONFIG_ARM_GLOBAL_TIMER=y -CONFIG_ARM_HAS_SG_CHAIN=y -CONFIG_ARM_HEAVY_MB=y -CONFIG_ARM_L1_CACHE_SHIFT=6 -CONFIG_ARM_L1_CACHE_SHIFT_6=y -# CONFIG_ARM_LPAE is not set -CONFIG_ARM_MODULE_PLTS=y -CONFIG_ARM_MVEBU_V7_CPUIDLE=y -CONFIG_ARM_PATCH_IDIV=y -CONFIG_ARM_PATCH_PHYS_VIRT=y -CONFIG_ARM_THUMB=y -# CONFIG_ARM_THUMBEE is not set -CONFIG_ARM_UNWIND=y -CONFIG_ARM_VIRT_EXT=y -CONFIG_ASYNC_TX_ENABLE_CHANNEL_SWITCH=y -CONFIG_ATA=y -CONFIG_ATAGS=y -CONFIG_AUTO_ZRELADDR=y -CONFIG_BLK_DEV_LOOP=y -CONFIG_BLK_DEV_SD=y -CONFIG_BLK_MQ_PCI=y -CONFIG_BLK_SCSI_REQUEST=y -CONFIG_BOUNCE=y -# CONFIG_CACHE_FEROCEON_L2 is not set -CONFIG_CACHE_L2X0=y -# CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE is not set -CONFIG_CC_OPTIMIZE_FOR_SIZE=y -CONFIG_CLKDEV_LOOKUP=y -CONFIG_CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK=y -CONFIG_CLKSRC_MMIO=y -CONFIG_CLONE_BACKWARDS=y -CONFIG_COMMON_CLK=y -CONFIG_CPUFREQ_DT=y -CONFIG_CPUFREQ_DT_PLATDEV=y -CONFIG_CPU_32v6K=y -CONFIG_CPU_32v7=y -CONFIG_CPU_ABRT_EV7=y -# CONFIG_CPU_BIG_ENDIAN is not set -# CONFIG_CPU_BPREDICT_DISABLE is not set -CONFIG_CPU_CACHE_V7=y -CONFIG_CPU_CACHE_VIPT=y -CONFIG_CPU_COPY_V6=y -CONFIG_CPU_CP15=y -CONFIG_CPU_CP15_MMU=y -CONFIG_CPU_FREQ=y -CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y -# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set -CONFIG_CPU_FREQ_GOV_ATTR_SET=y -CONFIG_CPU_FREQ_GOV_COMMON=y -# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set -CONFIG_CPU_FREQ_GOV_ONDEMAND=y -CONFIG_CPU_FREQ_GOV_PERFORMANCE=y -# CONFIG_CPU_FREQ_GOV_POWERSAVE is not set -# CONFIG_CPU_FREQ_GOV_USERSPACE is not set -CONFIG_CPU_FREQ_STAT=y -CONFIG_CPU_HAS_ASID=y -# CONFIG_CPU_HOTPLUG_STATE_CONTROL is not set -# CONFIG_CPU_ICACHE_DISABLE is not set -CONFIG_CPU_IDLE=y -CONFIG_CPU_IDLE_GOV_LADDER=y -CONFIG_CPU_ISOLATION=y -CONFIG_CPU_PABRT_V7=y -CONFIG_CPU_PJ4B=y -CONFIG_CPU_PM=y -CONFIG_CPU_RMAP=y -CONFIG_CPU_SPECTRE=y -CONFIG_CPU_THERMAL=y -CONFIG_CPU_THUMB_CAPABLE=y -CONFIG_CPU_TLB_V7=y -CONFIG_CPU_V7=y -CONFIG_CRASH_DUMP=y -CONFIG_CRC16=y -CONFIG_CRYPTO_ACOMP2=y -CONFIG_CRYPTO_AEAD=y -CONFIG_CRYPTO_AEAD2=y -CONFIG_CRYPTO_AES_ARM=y -CONFIG_CRYPTO_AES_ARM_BS=y -# CONFIG_CRYPTO_AES_ARM_CE is not set -# CONFIG_CRYPTO_CHACHA20_NEON is not set -CONFIG_CRYPTO_CRC32=y -CONFIG_CRYPTO_CRC32C=y -# CONFIG_CRYPTO_CRC32_ARM_CE is not set -CONFIG_CRYPTO_CRYPTD=y -CONFIG_CRYPTO_DEFLATE=y -CONFIG_CRYPTO_DES=y -CONFIG_CRYPTO_DEV_MARVELL_CESA=y -# CONFIG_CRYPTO_GHASH_ARM_CE is not set -CONFIG_CRYPTO_HASH=y -CONFIG_CRYPTO_HASH2=y -CONFIG_CRYPTO_HW=y -CONFIG_CRYPTO_LZO=y -CONFIG_CRYPTO_MANAGER=y -CONFIG_CRYPTO_MANAGER2=y -CONFIG_CRYPTO_NULL2=y -CONFIG_CRYPTO_RNG2=y -CONFIG_CRYPTO_SHA1=y -CONFIG_CRYPTO_SHA1_ARM=y -# CONFIG_CRYPTO_SHA1_ARM_CE is not set -CONFIG_CRYPTO_SHA1_ARM_NEON=y -CONFIG_CRYPTO_SHA256_ARM=y -# CONFIG_CRYPTO_SHA2_ARM_CE is not set -CONFIG_CRYPTO_SHA512_ARM=y -CONFIG_CRYPTO_SIMD=y -CONFIG_CRYPTO_WORKQUEUE=y -CONFIG_DCACHE_WORD_ACCESS=y -CONFIG_DEBUG_ALIGN_RODATA=y -CONFIG_DEBUG_INFO=y -CONFIG_DEBUG_LL=y -CONFIG_DEBUG_LL_INCLUDE="debug/8250.S" -CONFIG_DEBUG_MVEBU_UART0=y -# CONFIG_DEBUG_MVEBU_UART0_ALTERNATE is not set -# CONFIG_DEBUG_MVEBU_UART1_ALTERNATE is not set -CONFIG_DEBUG_UART_8250=y -# CONFIG_DEBUG_UART_8250_FLOW_CONTROL is not set -CONFIG_DEBUG_UART_8250_SHIFT=2 -# CONFIG_DEBUG_UART_8250_WORD is not set -CONFIG_DEBUG_UART_PHYS=0xd0012000 -CONFIG_DEBUG_UART_VIRT=0xfec12000 -CONFIG_DEBUG_UNCOMPRESS=y -CONFIG_DEBUG_USER=y -CONFIG_DMADEVICES=y -CONFIG_DMA_ENGINE=y -CONFIG_DMA_ENGINE_RAID=y -CONFIG_DMA_OF=y -CONFIG_DTC=y -CONFIG_EARLY_PRINTK=y -CONFIG_EDAC_ATOMIC_SCRUB=y -CONFIG_EDAC_SUPPORT=y -CONFIG_EXT4_FS=y -CONFIG_EXTCON=y -# CONFIG_F2FS_CHECK_FS is not set -# CONFIG_F2FS_FS is not set -# CONFIG_F2FS_FS_SECURITY is not set -# CONFIG_F2FS_FS_XATTR is not set -# CONFIG_F2FS_STAT_FS is not set -CONFIG_FIXED_PHY=y -CONFIG_FIX_EARLYCON_MEM=y -CONFIG_FS_IOMAP=y -CONFIG_FS_MBCACHE=y -CONFIG_GENERIC_ALLOCATOR=y -CONFIG_GENERIC_ARCH_TOPOLOGY=y -CONFIG_GENERIC_BUG=y -CONFIG_GENERIC_CLOCKEVENTS=y -CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y -CONFIG_GENERIC_CPU_AUTOPROBE=y -CONFIG_GENERIC_EARLY_IOREMAP=y -CONFIG_GENERIC_IDLE_POLL_SETUP=y -CONFIG_GENERIC_IRQ_CHIP=y -CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y -CONFIG_GENERIC_IRQ_MULTI_HANDLER=y -CONFIG_GENERIC_IRQ_SHOW=y -CONFIG_GENERIC_IRQ_SHOW_LEVEL=y -CONFIG_GENERIC_MSI_IRQ=y -CONFIG_GENERIC_MSI_IRQ_DOMAIN=y -CONFIG_GENERIC_PCI_IOMAP=y -CONFIG_GENERIC_PHY=y -CONFIG_GENERIC_SCHED_CLOCK=y -CONFIG_GENERIC_SMP_IDLE_THREAD=y -CONFIG_GENERIC_STRNCPY_FROM_USER=y -CONFIG_GENERIC_STRNLEN_USER=y -CONFIG_GLOB=y -CONFIG_GPIOLIB=y -CONFIG_GPIOLIB_IRQCHIP=y -CONFIG_GPIO_GENERIC=y -CONFIG_GPIO_GENERIC_PLATFORM=y -CONFIG_GPIO_MVEBU=y -CONFIG_GPIO_PCA953X=y -CONFIG_GPIO_PCA953X_IRQ=y -CONFIG_GPIO_SYSFS=y -CONFIG_HANDLE_DOMAIN_IRQ=y -CONFIG_HARDEN_BRANCH_PREDICTOR=y -CONFIG_HARDIRQS_SW_RESEND=y -CONFIG_HAS_DMA=y -CONFIG_HAS_IOMEM=y -CONFIG_HAS_IOPORT_MAP=y -CONFIG_HAVE_ARCH_AUDITSYSCALL=y -CONFIG_HAVE_ARCH_BITREVERSE=y -CONFIG_HAVE_ARCH_JUMP_LABEL=y -CONFIG_HAVE_ARCH_KGDB=y -CONFIG_HAVE_ARCH_PFN_VALID=y -CONFIG_HAVE_ARCH_SECCOMP_FILTER=y -CONFIG_HAVE_ARCH_THREAD_STRUCT_WHITELIST=y -CONFIG_HAVE_ARCH_TRACEHOOK=y -CONFIG_HAVE_ARM_SCU=y -CONFIG_HAVE_ARM_SMCCC=y -CONFIG_HAVE_ARM_TWD=y -CONFIG_HAVE_CLK=y -CONFIG_HAVE_CLK_PREPARE=y -CONFIG_HAVE_CONTEXT_TRACKING=y -CONFIG_HAVE_C_RECORDMCOUNT=y -CONFIG_HAVE_DEBUG_KMEMLEAK=y -CONFIG_HAVE_DMA_CONTIGUOUS=y -CONFIG_HAVE_DYNAMIC_FTRACE=y -CONFIG_HAVE_DYNAMIC_FTRACE_WITH_REGS=y -CONFIG_HAVE_EBPF_JIT=y -CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y -CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y -CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y -CONFIG_HAVE_FUNCTION_TRACER=y -CONFIG_HAVE_GENERIC_DMA_COHERENT=y -CONFIG_HAVE_IDE=y -CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y -CONFIG_HAVE_LD_DEAD_CODE_DATA_ELIMINATION=y -CONFIG_HAVE_MEMBLOCK=y -CONFIG_HAVE_MOD_ARCH_SPECIFIC=y -CONFIG_HAVE_NET_DSA=y -CONFIG_HAVE_OPROFILE=y -CONFIG_HAVE_OPTPROBES=y -CONFIG_HAVE_PERF_EVENTS=y -CONFIG_HAVE_PERF_REGS=y -CONFIG_HAVE_PERF_USER_STACK_DUMP=y -CONFIG_HAVE_PROC_CPU=y -CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y -CONFIG_HAVE_RSEQ=y -CONFIG_HAVE_SMP=y -CONFIG_HAVE_SYSCALL_TRACEPOINTS=y -CONFIG_HAVE_UID16=y -CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y -CONFIG_HIGHMEM=y -# CONFIG_HIGHPTE is not set -CONFIG_HOTPLUG_CPU=y -CONFIG_HWBM=y -CONFIG_HWMON=y -CONFIG_HW_RANDOM=y -CONFIG_HW_RANDOM_OMAP=y -CONFIG_HZ_FIXED=0 -CONFIG_HZ_PERIODIC=y -CONFIG_I2C=y -CONFIG_I2C_BOARDINFO=y -CONFIG_I2C_CHARDEV=y -CONFIG_I2C_MV64XXX=y -# CONFIG_I2C_PXA is not set -CONFIG_INITRAMFS_SOURCE="" -CONFIG_IP6_NF_IPTABLES=y -CONFIG_IP6_NF_MATCH_SRH=y -CONFIG_IPV6=y -CONFIG_IRQCHIP=y -CONFIG_IRQ_DOMAIN=y -CONFIG_IRQ_DOMAIN_HIERARCHY=y -CONFIG_IRQ_FORCED_THREADING=y -CONFIG_IRQ_WORK=y -# CONFIG_IWMMXT is not set -CONFIG_JBD2=y -CONFIG_LEDS_GPIO=y -CONFIG_LEDS_PCA963X=y -CONFIG_LEDS_TLC591XX=y -CONFIG_LEDS_TRIGGER_DISK=y -CONFIG_LIBFDT=y -CONFIG_LOCK_DEBUGGING_SUPPORT=y -CONFIG_LOCK_SPIN_ON_OWNER=y -CONFIG_LZO_COMPRESS=y -CONFIG_LZO_DECOMPRESS=y -CONFIG_MACH_ARMADA_370=y -CONFIG_MACH_ARMADA_375=y -CONFIG_MACH_ARMADA_38X=y -CONFIG_MACH_ARMADA_39X=y -CONFIG_MACH_ARMADA_XP=y -# CONFIG_MACH_DOVE is not set -CONFIG_MACH_MVEBU_ANY=y -CONFIG_MACH_MVEBU_V7=y -CONFIG_MAGIC_SYSRQ=y -CONFIG_MANGLE_BOOTARGS=y -CONFIG_MARVELL_PHY=y -CONFIG_MDIO_BUS=y -CONFIG_MDIO_DEVICE=y -CONFIG_MDIO_I2C=y -CONFIG_MEMFD_CREATE=y -CONFIG_MEMORY=y -CONFIG_MFD_SYSCON=y -CONFIG_MIGHT_HAVE_CACHE_L2X0=y -CONFIG_MIGHT_HAVE_PCI=y -CONFIG_MIGRATION=y -CONFIG_MMC=y -CONFIG_MMC_BLOCK=y -CONFIG_MMC_MVSDIO=y -CONFIG_MMC_SDHCI=y -# CONFIG_MMC_SDHCI_PCI is not set -CONFIG_MMC_SDHCI_PLTFM=y -CONFIG_MMC_SDHCI_PXAV3=y -# CONFIG_MMC_TIFM_SD is not set -CONFIG_MODULES_USE_ELF_REL=y -CONFIG_MTD_CFI_STAA=y -CONFIG_MTD_M25P80=y -CONFIG_MTD_NAND=y -CONFIG_MTD_NAND_ECC=y -CONFIG_MTD_NAND_MARVELL=y -CONFIG_MTD_SPI_NOR=y -CONFIG_MTD_SPLIT_FIRMWARE=y -CONFIG_MTD_UBI=y -CONFIG_MTD_UBI_BEB_LIMIT=20 -CONFIG_MTD_UBI_BLOCK=y -# CONFIG_MTD_UBI_FASTMAP is not set -# CONFIG_MTD_UBI_GLUEBI is not set -CONFIG_MTD_UBI_WL_THRESHOLD=4096 -CONFIG_MUTEX_SPIN_ON_OWNER=y -CONFIG_MVEBU_CLK_COMMON=y -CONFIG_MVEBU_CLK_COREDIV=y -CONFIG_MVEBU_CLK_CPU=y -CONFIG_MVEBU_DEVBUS=y -CONFIG_MVEBU_MBUS=y -CONFIG_MVMDIO=y -CONFIG_MVNETA=y -CONFIG_MVNETA_BM=y -CONFIG_MVNETA_BM_ENABLE=y -CONFIG_MVPP2=y -CONFIG_MVSW61XX_PHY=y -CONFIG_MV_XOR=y -CONFIG_NEED_DMA_MAP_STATE=y -CONFIG_NEON=y -CONFIG_NETFILTER=y -CONFIG_NETFILTER_ADVANCED=y -CONFIG_NETFILTER_XTABLES=y -CONFIG_NET_DSA=y -CONFIG_NET_DSA_LEGACY=y -CONFIG_NET_DSA_MV88E6XXX=y -CONFIG_NET_DSA_MV88E6XXX_GLOBAL2=y -# CONFIG_NET_DSA_MV88E6XXX_PTP is not set -# CONFIG_NET_DSA_REALTEK_SMI is not set -CONFIG_NET_DSA_TAG_DSA=y -CONFIG_NET_DSA_TAG_EDSA=y -# CONFIG_NET_DSA_VITESSE_VSC73XX is not set -CONFIG_NET_FLOW_LIMIT=y -CONFIG_NET_SWITCHDEV=y -# CONFIG_NET_VENDOR_CORTINA is not set -# CONFIG_NET_VENDOR_MICROSEMI is not set -# CONFIG_NET_VENDOR_NI is not set -# CONFIG_NET_VENDOR_SOCIONEXT is not set -# CONFIG_NF_LOG_IPV6 is not set -CONFIG_NF_TPROXY_IPV4=y -CONFIG_NLS=y -CONFIG_NOP_USB_XCEIV=y -CONFIG_NO_BOOTMEM=y -CONFIG_NR_CPUS=4 -CONFIG_NVMEM=y -CONFIG_OF=y -CONFIG_OF_ADDRESS=y -CONFIG_OF_EARLY_FLATTREE=y -CONFIG_OF_FLATTREE=y -CONFIG_OF_GPIO=y -CONFIG_OF_IRQ=y -CONFIG_OF_KOBJ=y -CONFIG_OF_MDIO=y -CONFIG_OF_NET=y -CONFIG_OF_RESERVED_MEM=y -CONFIG_OLD_SIGACTION=y -CONFIG_OLD_SIGSUSPEND3=y -CONFIG_ORION_WATCHDOG=y -CONFIG_OUTER_CACHE=y -CONFIG_OUTER_CACHE_SYNC=y -# CONFIG_OVERLAY_FS_XINO_AUTO is not set -CONFIG_PADATA=y -CONFIG_PAGE_OFFSET=0xC0000000 -CONFIG_PCI=y -CONFIG_PCI_DOMAINS=y -CONFIG_PCI_DOMAINS_GENERIC=y -CONFIG_PCI_MSI=y -CONFIG_PCI_MSI_IRQ_DOMAIN=y -CONFIG_PCI_MVEBU=y -# CONFIG_PCI_V3_SEMI is not set -CONFIG_PERF_USE_VMALLOC=y -CONFIG_PGTABLE_LEVELS=2 -CONFIG_PHYLIB=y -CONFIG_PHYLINK=y -# CONFIG_PHY_MVEBU_CP110_COMPHY is not set -CONFIG_PINCTRL=y -CONFIG_PINCTRL_ARMADA_370=y -CONFIG_PINCTRL_ARMADA_375=y -CONFIG_PINCTRL_ARMADA_38X=y -CONFIG_PINCTRL_ARMADA_39X=y -CONFIG_PINCTRL_ARMADA_XP=y -CONFIG_PINCTRL_MVEBU=y -# CONFIG_PINCTRL_SINGLE is not set -CONFIG_PJ4B_ERRATA_4742=y -# CONFIG_PL310_ERRATA_588369 is not set -# CONFIG_PL310_ERRATA_727915 is not set -CONFIG_PL310_ERRATA_753970=y -# CONFIG_PL310_ERRATA_769419 is not set -CONFIG_PLAT_ORION=y -CONFIG_PM_OPP=y -CONFIG_PRINTK_SAFE_LOG_BUF_SHIFT=11 -CONFIG_PROC_VMCORE=y -CONFIG_PROC_VMCORE_DEVICE_DUMP=y -CONFIG_PWM=y -CONFIG_PWM_SYSFS=y -CONFIG_RATIONAL=y -CONFIG_RCU_NEED_SEGCBLIST=y -CONFIG_RCU_STALL_COMMON=y -CONFIG_REFCOUNT_FULL=y -CONFIG_REGMAP=y -CONFIG_REGMAP_I2C=y -CONFIG_REGMAP_MMIO=y -CONFIG_REGMAP_SPI=y -CONFIG_REGULATOR=y -CONFIG_REGULATOR_FIXED_VOLTAGE=y -CONFIG_RFS_ACCEL=y -CONFIG_RPS=y -CONFIG_RSEQ=y -CONFIG_RTC_CLASS=y -CONFIG_RTC_DRV_ARMADA38X=y -CONFIG_RTC_DRV_MV=y -CONFIG_RTC_I2C_AND_SPI=y -CONFIG_RTC_MC146818_LIB=y -CONFIG_RWSEM_SPIN_ON_OWNER=y -CONFIG_RWSEM_XCHGADD_ALGORITHM=y -CONFIG_SATA_AHCI_PLATFORM=y -CONFIG_SATA_MV=y -CONFIG_SATA_PMP=y -CONFIG_SCSI=y -CONFIG_SENSORS_PWM_FAN=y -CONFIG_SENSORS_TMP421=y -CONFIG_SERIAL_8250_DW=y -CONFIG_SERIAL_8250_FSL=y -CONFIG_SERIAL_MVEBU_CONSOLE=y -CONFIG_SERIAL_MVEBU_UART=y -CONFIG_SFP=y -CONFIG_SGL_ALLOC=y -CONFIG_SG_POOL=y -CONFIG_SMP=y -CONFIG_SMP_ON_UP=y -CONFIG_SOC_BUS=y -CONFIG_SPARSE_IRQ=y -CONFIG_SPI=y -# CONFIG_SPI_ARMADA_3700 is not set -CONFIG_SPI_MASTER=y -CONFIG_SPI_MEM=y -CONFIG_SPI_ORION=y -CONFIG_SRAM=y -CONFIG_SRAM_EXEC=y -CONFIG_SRCU=y -CONFIG_STACKPROTECTOR=y -CONFIG_STACKPROTECTOR_STRONG=y -CONFIG_SWCONFIG=y -CONFIG_SWPHY=y -CONFIG_SWP_EMULATE=y -CONFIG_SYS_SUPPORTS_APM_EMULATION=y -CONFIG_THERMAL=y -CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y -CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=0 -CONFIG_THERMAL_GOV_STEP_WISE=y -CONFIG_THERMAL_HWMON=y -CONFIG_THERMAL_OF=y -# CONFIG_THUMB2_KERNEL is not set -CONFIG_TICK_CPU_ACCOUNTING=y -CONFIG_TIMER_OF=y -CONFIG_TIMER_PROBE=y -CONFIG_TREE_RCU=y -CONFIG_TREE_SRCU=y -CONFIG_UBIFS_FS=y -# CONFIG_UBIFS_FS_ADVANCED_COMPR is not set -CONFIG_UBIFS_FS_LZO=y -CONFIG_UBIFS_FS_XATTR=y -CONFIG_UBIFS_FS_ZLIB=y -CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h" -CONFIG_USB=y -CONFIG_USB_COMMON=y -CONFIG_USB_EHCI_HCD=y -CONFIG_USB_EHCI_HCD_ORION=y -CONFIG_USB_EHCI_HCD_PLATFORM=y -CONFIG_USB_LEDS_TRIGGER_USBPORT=y -CONFIG_USB_PHY=y -CONFIG_USB_STORAGE=y -CONFIG_USB_SUPPORT=y -CONFIG_USB_XHCI_HCD=y -CONFIG_USB_XHCI_MVEBU=y -CONFIG_USB_XHCI_PLATFORM=y -CONFIG_USE_OF=y -CONFIG_VFP=y -CONFIG_VFPv3=y -CONFIG_WATCHDOG_CORE=y -CONFIG_XDP_SOCKETS=y -CONFIG_XPS=y -CONFIG_XZ_DEC_ARM=y -CONFIG_XZ_DEC_BCJ=y -CONFIG_ZBOOT_ROM_BSS=0x0 -CONFIG_ZBOOT_ROM_TEXT=0x0 -CONFIG_ZLIB_DEFLATE=y -CONFIG_ZLIB_INFLATE=y diff --git a/root/target/linux/x86/config-4.19 b/root/target/linux/x86/config-4.19 deleted file mode 100644 index 80a94b24..00000000 --- a/root/target/linux/x86/config-4.19 +++ /dev/null @@ -1,500 +0,0 @@ -# CONFIG_60XX_WDT is not set -# CONFIG_64BIT is not set -# CONFIG_ACPI is not set -# CONFIG_ACQUIRE_WDT is not set -# CONFIG_ADVANTECH_WDT is not set -# CONFIG_ALIM1535_WDT is not set -# CONFIG_ALIX is not set -CONFIG_AMD_NB=y -CONFIG_ARCH_CLOCKSOURCE_DATA=y -CONFIG_ARCH_DEFCONFIG="arch/x86/configs/i386_defconfig" -CONFIG_ARCH_DISCARD_MEMBLOCK=y -CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y -CONFIG_ARCH_HAS_CACHE_LINE_SIZE=y -CONFIG_ARCH_HAS_CPU_RELAX=y -CONFIG_ARCH_HAS_DEBUG_VIRTUAL=y -CONFIG_ARCH_HAS_ELF_RANDOMIZE=y -CONFIG_ARCH_HAS_FAST_MULTIPLIER=y -CONFIG_ARCH_HAS_FILTER_PGPROT=y -CONFIG_ARCH_HAS_FORTIFY_SOURCE=y -CONFIG_ARCH_HAS_GCOV_PROFILE_ALL=y -CONFIG_ARCH_HAS_MEMBARRIER_SYNC_CORE=y -CONFIG_ARCH_HAS_MEM_ENCRYPT=y -CONFIG_ARCH_HAS_PTE_SPECIAL=y -CONFIG_ARCH_HAS_REFCOUNT=y -CONFIG_ARCH_HAS_SET_MEMORY=y -CONFIG_ARCH_HAS_SG_CHAIN=y -CONFIG_ARCH_HAS_STRICT_KERNEL_RWX=y -CONFIG_ARCH_HAS_STRICT_MODULE_RWX=y -CONFIG_ARCH_HAS_SYNC_CORE_BEFORE_USERMODE=y -CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG=y -CONFIG_ARCH_HIBERNATION_POSSIBLE=y -CONFIG_ARCH_MAY_HAVE_PC_FDC=y -CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y -CONFIG_ARCH_MIGHT_HAVE_PC_SERIO=y -CONFIG_ARCH_RANDOM=y -CONFIG_ARCH_SELECT_MEMORY_MODEL=y -CONFIG_ARCH_SPARSEMEM_ENABLE=y -CONFIG_ARCH_SUPPORTS_ACPI=y -CONFIG_ARCH_SUPPORTS_ATOMIC_RMW=y -CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y -CONFIG_ARCH_SUPPORTS_MEMORY_FAILURE=y -CONFIG_ARCH_SUPPORTS_UPROBES=y -CONFIG_ARCH_SUSPEND_POSSIBLE=y -CONFIG_ARCH_USES_PG_UNCACHED=y -CONFIG_ARCH_USE_BUILTIN_BSWAP=y -CONFIG_ARCH_USE_QUEUED_RWLOCKS=y -CONFIG_ARCH_USE_QUEUED_SPINLOCKS=y -CONFIG_ARCH_WANTS_DYNAMIC_TASK_STRUCT=y -CONFIG_ARCH_WANT_BATCHED_UNMAP_TLB_FLUSH=y -CONFIG_ARCH_WANT_GENERAL_HUGETLB=y -CONFIG_ARCH_WANT_HUGE_PMD_SHARE=y -CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y -CONFIG_ATA=y -CONFIG_ATA_GENERIC=y -CONFIG_ATA_PIIX=y -CONFIG_BINFMT_MISC=y -CONFIG_BLK_DEV_LOOP=y -CONFIG_BLK_DEV_SD=y -CONFIG_BLK_MQ_PCI=y -CONFIG_BLK_SCSI_REQUEST=y -CONFIG_BOUNCE=y -CONFIG_CC_HAS_SANE_STACKPROTECTOR=y -CONFIG_CLKBLD_I8253=y -CONFIG_CLKDEV_LOOKUP=y -CONFIG_CLKEVT_I8253=y -CONFIG_CLKSRC_I8253=y -CONFIG_CLOCKSOURCE_VALIDATE_LAST_CYCLE=y -CONFIG_CLOCKSOURCE_WATCHDOG=y -CONFIG_CLONE_BACKWARDS=y -CONFIG_COMMON_CLK=y -CONFIG_COMPAT_32=y -# CONFIG_COMPAT_VDSO is not set -CONFIG_CONSOLE_TRANSLATIONS=y -# CONFIG_CPU5_WDT is not set -CONFIG_CPU_FREQ=y -CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y -# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set -CONFIG_CPU_FREQ_GOV_ATTR_SET=y -CONFIG_CPU_FREQ_GOV_COMMON=y -# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set -CONFIG_CPU_FREQ_GOV_ONDEMAND=y -CONFIG_CPU_FREQ_GOV_PERFORMANCE=y -# CONFIG_CPU_FREQ_GOV_POWERSAVE is not set -# CONFIG_CPU_FREQ_GOV_USERSPACE is not set -CONFIG_CPU_FREQ_STAT=y -CONFIG_CPU_IDLE=y -CONFIG_CPU_IDLE_GOV_LADDER=y -CONFIG_CPU_SUP_AMD=y -CONFIG_CPU_SUP_CENTAUR=y -CONFIG_CPU_SUP_CYRIX_32=y -CONFIG_CPU_SUP_INTEL=y -CONFIG_CPU_SUP_TRANSMETA_32=y -CONFIG_CPU_SUP_UMC_32=y -# CONFIG_CRASHLOG is not set -CONFIG_CRASH_CORE=y -CONFIG_CRC16=y -CONFIG_CRYPTO_AES_586=y -CONFIG_CRYPTO_CRC32=y -CONFIG_CRYPTO_CRC32C=y -# CONFIG_CRYPTO_CRC32_PCLMUL is not set -CONFIG_CRYPTO_HASH=y -CONFIG_CRYPTO_HASH2=y -CONFIG_CRYPTO_RNG2=y -# CONFIG_CRYPTO_SERPENT_SSE2_586 is not set -CONFIG_CRYPTO_WORKQUEUE=y -# CONFIG_CX_ECAT is not set -CONFIG_DCACHE_WORD_ACCESS=y -# CONFIG_DCDBAS is not set -# CONFIG_DEBUG_BOOT_PARAMS is not set -# CONFIG_DEBUG_ENTRY is not set -CONFIG_DEBUG_MEMORY_INIT=y -# CONFIG_DEBUG_NMI_SELFTEST is not set -# CONFIG_DEBUG_TLBFLUSH is not set -CONFIG_DECOMPRESS_BZIP2=y -CONFIG_DECOMPRESS_GZIP=y -CONFIG_DEFAULT_IO_DELAY_TYPE=0 -# CONFIG_DELL_RBU is not set -CONFIG_DMA_DIRECT_OPS=y -CONFIG_DMI=y -CONFIG_DMIID=y -CONFIG_DMI_SCAN_MACHINE_NON_EFI_FALLBACK=y -CONFIG_DMI_SYSFS=y -CONFIG_DNOTIFY=y -CONFIG_DUMMY_CONSOLE=y -CONFIG_EARLY_PRINTK=y -# CONFIG_EARLY_PRINTK_DBGP is not set -CONFIG_EDAC_ATOMIC_SCRUB=y -CONFIG_EDAC_SUPPORT=y -# CONFIG_EDD is not set -# CONFIG_EUROTECH_WDT is not set -CONFIG_EXT4_FS=y -# CONFIG_F2FS_CHECK_FS is not set -CONFIG_F2FS_FS=y -# CONFIG_F2FS_FS_SECURITY is not set -CONFIG_F2FS_FS_XATTR=y -CONFIG_F2FS_STAT_FS=y -# CONFIG_F71808E_WDT is not set -CONFIG_FIRMWARE_MEMMAP=y -CONFIG_FIX_EARLYCON_MEM=y -CONFIG_FRAME_POINTER=y -CONFIG_FS_IOMAP=y -CONFIG_FS_MBCACHE=y -CONFIG_FUSION=y -# CONFIG_FUSION_CTL is not set -# CONFIG_FUSION_LOGGING is not set -CONFIG_FUSION_MAX_SGE=128 -CONFIG_FUSION_SPI=y -CONFIG_GENERIC_ALLOCATOR=y -CONFIG_GENERIC_BUG=y -CONFIG_GENERIC_CLOCKEVENTS=y -CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y -CONFIG_GENERIC_CLOCKEVENTS_MIN_ADJUST=y -CONFIG_GENERIC_CMOS_UPDATE=y -CONFIG_GENERIC_CPU_AUTOPROBE=y -CONFIG_GENERIC_CPU_VULNERABILITIES=y -CONFIG_GENERIC_EARLY_IOREMAP=y -CONFIG_GENERIC_FIND_FIRST_BIT=y -CONFIG_GENERIC_IOMAP=y -CONFIG_GENERIC_IRQ_MATRIX_ALLOCATOR=y -CONFIG_GENERIC_IRQ_RESERVATION_MODE=y -CONFIG_GENERIC_IRQ_SHOW=y -CONFIG_GENERIC_ISA_DMA=y -CONFIG_GENERIC_MSI_IRQ=y -CONFIG_GENERIC_MSI_IRQ_DOMAIN=y -CONFIG_GENERIC_PCI_IOMAP=y -CONFIG_GENERIC_SMP_IDLE_THREAD=y -CONFIG_GENERIC_STRNCPY_FROM_USER=y -CONFIG_GENERIC_STRNLEN_USER=y -CONFIG_GENERIC_TIME_VSYSCALL=y -# CONFIG_GEOS is not set -CONFIG_GLOB=y -# CONFIG_HANGCHECK_TIMER is not set -CONFIG_HAS_DMA=y -CONFIG_HAS_IOMEM=y -CONFIG_HAS_IOPORT_MAP=y -CONFIG_HAVE_ALIGNED_STRUCT_PAGE=y -CONFIG_HAVE_AOUT=y -CONFIG_HAVE_ARCH_AUDITSYSCALL=y -CONFIG_HAVE_ARCH_JUMP_LABEL=y -CONFIG_HAVE_ARCH_KGDB=y -CONFIG_HAVE_ARCH_PREL32_RELOCATIONS=y -CONFIG_HAVE_ARCH_SECCOMP_FILTER=y -CONFIG_HAVE_ARCH_THREAD_STRUCT_WHITELIST=y -CONFIG_HAVE_ARCH_TRACEHOOK=y -CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE=y -CONFIG_HAVE_ATOMIC_IOMAP=y -CONFIG_HAVE_CLK=y -CONFIG_HAVE_CLK_PREPARE=y -CONFIG_HAVE_CMPXCHG_DOUBLE=y -CONFIG_HAVE_CMPXCHG_LOCAL=y -CONFIG_HAVE_COPY_THREAD_TLS=y -CONFIG_HAVE_C_RECORDMCOUNT=y -CONFIG_HAVE_DEBUG_KMEMLEAK=y -CONFIG_HAVE_DEBUG_STACKOVERFLOW=y -CONFIG_HAVE_DMA_CONTIGUOUS=y -CONFIG_HAVE_DYNAMIC_FTRACE=y -CONFIG_HAVE_DYNAMIC_FTRACE_WITH_REGS=y -CONFIG_HAVE_EBPF_JIT=y -CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y -CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y -CONFIG_HAVE_FUNCTION_ERROR_INJECTION=y -CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y -CONFIG_HAVE_FUNCTION_TRACER=y -CONFIG_HAVE_GENERIC_DMA_COHERENT=y -CONFIG_HAVE_GENERIC_GUP=y -CONFIG_HAVE_HARDLOCKUP_DETECTOR_PERF=y -CONFIG_HAVE_HW_BREAKPOINT=y -CONFIG_HAVE_IDE=y -CONFIG_HAVE_IOREMAP_PROT=y -CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y -CONFIG_HAVE_KPROBES_ON_FTRACE=y -CONFIG_HAVE_KVM=y -CONFIG_HAVE_MEMBLOCK=y -CONFIG_HAVE_MEMBLOCK_NODE_MAP=y -CONFIG_HAVE_MIXED_BREAKPOINTS_REGS=y -CONFIG_HAVE_MMIOTRACE_SUPPORT=y -CONFIG_HAVE_MOD_ARCH_SPECIFIC=y -CONFIG_HAVE_NET_DSA=y -CONFIG_HAVE_OPROFILE=y -CONFIG_HAVE_OPTPROBES=y -CONFIG_HAVE_PCSPKR_PLATFORM=y -CONFIG_HAVE_PERF_EVENTS=y -CONFIG_HAVE_PERF_EVENTS_NMI=y -CONFIG_HAVE_PERF_REGS=y -CONFIG_HAVE_PERF_USER_STACK_DUMP=y -CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y -CONFIG_HAVE_RSEQ=y -CONFIG_HAVE_SETUP_PER_CPU_AREA=y -CONFIG_HAVE_SYSCALL_TRACEPOINTS=y -CONFIG_HAVE_UID16=y -CONFIG_HAVE_UNSTABLE_SCHED_CLOCK=y -CONFIG_HAVE_USER_RETURN_NOTIFIER=y -CONFIG_HID=y -CONFIG_HIGHMEM=y -CONFIG_HIGHMEM4G=y -# CONFIG_HIGHPTE is not set -CONFIG_HPET_EMULATE_RTC=y -CONFIG_HPET_TIMER=y -# CONFIG_HP_WATCHDOG is not set -# CONFIG_HUGETLBFS is not set -CONFIG_HW_CONSOLE=y -CONFIG_HW_RANDOM=y -CONFIG_HW_RANDOM_GEODE=y -CONFIG_HW_RANDOM_VIA=y -# CONFIG_HYPERVISOR_GUEST is not set -CONFIG_HZ_PERIODIC=y -CONFIG_I8253_LOCK=y -# CONFIG_I8K is not set -# CONFIG_IB700_WDT is not set -# CONFIG_IBMASR is not set -# CONFIG_IBM_RTL is not set -# CONFIG_IE6XX_WDT is not set -CONFIG_ILLEGAL_POINTER_VALUE=0 -CONFIG_INITRAMFS_SOURCE="" -CONFIG_INPUT=y -CONFIG_INPUT_KEYBOARD=y -CONFIG_INSTRUCTION_DECODER=y -# CONFIG_INTEL_PCH_THERMAL is not set -# CONFIG_INTEL_POWERCLAMP is not set -# CONFIG_INTEL_RDT is not set -# CONFIG_IOSF_MBI is not set -CONFIG_IO_DELAY_0X80=y -# CONFIG_IO_DELAY_0XED is not set -# CONFIG_IO_DELAY_NONE is not set -CONFIG_IO_DELAY_TYPE_0X80=0 -CONFIG_IO_DELAY_TYPE_0XED=1 -CONFIG_IO_DELAY_TYPE_NONE=3 -CONFIG_IO_DELAY_TYPE_UDELAY=2 -# CONFIG_IO_DELAY_UDELAY is not set -CONFIG_IRQ_DOMAIN=y -CONFIG_IRQ_DOMAIN_HIERARCHY=y -CONFIG_IRQ_FORCED_THREADING=y -CONFIG_IRQ_WORK=y -# CONFIG_ISA is not set -CONFIG_ISA_DMA_API=y -# CONFIG_IT8712F_WDT is not set -# CONFIG_IT87_WDT is not set -# CONFIG_ITCO_WDT is not set -CONFIG_JBD2=y -CONFIG_KALLSYMS=y -CONFIG_KEXEC=y -CONFIG_KEXEC_CORE=y -CONFIG_KEYBOARD_ATKBD=y -# CONFIG_LEDS_CLEVO_MAIL is not set -CONFIG_LOCK_DEBUGGING_SUPPORT=y -# CONFIG_M486 is not set -# CONFIG_M586 is not set -CONFIG_M586MMX=y -# CONFIG_M586TSC is not set -# CONFIG_M686 is not set -# CONFIG_MACHZ_WDT is not set -# CONFIG_MATOM is not set -# CONFIG_MCORE2 is not set -# CONFIG_MCRUSOE is not set -# CONFIG_MCYRIXIII is not set -# CONFIG_MEFFICEON is not set -# CONFIG_MELAN is not set -CONFIG_MEMFD_CREATE=y -# CONFIG_MFD_INTEL_LPSS_PCI is not set -# CONFIG_MGEODEGX1 is not set -# CONFIG_MGEODE_LX is not set -CONFIG_MICROCODE=y -CONFIG_MICROCODE_AMD=y -CONFIG_MICROCODE_INTEL=y -CONFIG_MICROCODE_OLD_INTERFACE=y -CONFIG_MIGRATION=y -# CONFIG_MK6 is not set -# CONFIG_MK7 is not set -# CONFIG_MK8 is not set -# CONFIG_MODIFY_LDT_SYSCALL is not set -CONFIG_MODULES_TREE_LOOKUP=y -CONFIG_MODULES_USE_ELF_REL=y -# CONFIG_MPENTIUM4 is not set -# CONFIG_MPENTIUMII is not set -# CONFIG_MPENTIUMIII is not set -# CONFIG_MPENTIUMM is not set -# CONFIG_MTD is not set -CONFIG_MTRR=y -# CONFIG_MTRR_SANITIZER is not set -# CONFIG_MVIAC3_2 is not set -# CONFIG_MVIAC7 is not set -# CONFIG_MWINCHIP3D is not set -# CONFIG_MWINCHIPC6 is not set -CONFIG_NAMESPACES=y -CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK=y -CONFIG_NEED_PER_CPU_KM=y -CONFIG_NEED_PER_CPU_PAGE_FIRST_CHUNK=y -CONFIG_NEED_SG_DMA_LENGTH=y -# CONFIG_NET5501 is not set -# CONFIG_NET_NS is not set -CONFIG_NLS=y -# CONFIG_NOHIGHMEM is not set -CONFIG_NO_BOOTMEM=y -CONFIG_NR_CPUS=1 -CONFIG_NR_CPUS_DEFAULT=1 -CONFIG_NR_CPUS_RANGE_BEGIN=1 -CONFIG_NR_CPUS_RANGE_END=1 -# CONFIG_NSC_GPIO is not set -CONFIG_NVRAM=y -# CONFIG_OF is not set -CONFIG_OLD_SIGACTION=y -CONFIG_OLD_SIGSUSPEND3=y -# CONFIG_OLPC is not set -CONFIG_OPROFILE_NMI_TIMER=y -CONFIG_OUTPUT_FORMAT="elf32-i386" -CONFIG_PAGE_OFFSET=0xC0000000 -CONFIG_PC104=y -# CONFIG_PC8736x_GPIO is not set -# CONFIG_PC87413_WDT is not set -CONFIG_PCI=y -CONFIG_PCI_BIOS=y -CONFIG_PCI_DIRECT=y -CONFIG_PCI_DOMAINS=y -CONFIG_PCI_GOANY=y -# CONFIG_PCI_GOBIOS is not set -# CONFIG_PCI_GODIRECT is not set -# CONFIG_PCI_GOMMCONFIG is not set -CONFIG_PCI_LABEL=y -CONFIG_PCI_LOCKLESS_CONFIG=y -CONFIG_PCI_MSI=y -CONFIG_PCI_MSI_IRQ_DOMAIN=y -CONFIG_PCSPKR_PLATFORM=y -CONFIG_PERF_EVENTS=y -CONFIG_PERF_EVENTS_INTEL_CSTATE=y -CONFIG_PERF_EVENTS_INTEL_RAPL=y -CONFIG_PERF_EVENTS_INTEL_UNCORE=y -CONFIG_PGTABLE_LEVELS=2 -CONFIG_PHYSICAL_ALIGN=0x100000 -CONFIG_PHYSICAL_START=0x1000000 -CONFIG_PMC_ATOM=y -CONFIG_POWER_SUPPLY=y -# CONFIG_PROCESSOR_SELECT is not set -CONFIG_PROC_PAGE_MONITOR=y -# CONFIG_PROVIDE_OHCI1394_DMA_INIT is not set -# CONFIG_PUNIT_ATOM_DEBUG is not set -CONFIG_RATIONAL=y -CONFIG_RD_BZIP2=y -CONFIG_RD_GZIP=y -CONFIG_RETPOLINE=y -CONFIG_RTC_CLASS=y -CONFIG_RTC_MC146818_LIB=y -CONFIG_RWSEM_XCHGADD_ALGORITHM=y -# CONFIG_SBC7240_WDT is not set -# CONFIG_SBC8360_WDT is not set -# CONFIG_SBC_EPX_C3_WATCHDOG is not set -# CONFIG_SC1200_WDT is not set -CONFIG_SCSI=y -CONFIG_SCSI_SPI_ATTRS=y -CONFIG_SCx200=y -CONFIG_SCx200HR_TIMER=y -# CONFIG_SCx200_GPIO is not set -# CONFIG_SCx200_WDT is not set -CONFIG_SERIAL_8250_PCI=y -CONFIG_SERIO=y -CONFIG_SERIO_I8042=y -CONFIG_SERIO_LIBPS2=y -CONFIG_SERIO_SERPORT=y -CONFIG_SG_POOL=y -# CONFIG_SMSC37B787_WDT is not set -# CONFIG_SMSC_SCH311X_WDT is not set -CONFIG_SPARSEMEM_STATIC=y -CONFIG_SPARSE_IRQ=y -CONFIG_SRCU=y -CONFIG_SYSCTL_EXCEPTION_TRACE=y -# CONFIG_TELCLOCK is not set -CONFIG_THERMAL=y -CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y -CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=0 -CONFIG_THERMAL_GOV_STEP_WISE=y -CONFIG_THREAD_INFO_IN_TASK=y -CONFIG_TICK_CPU_ACCOUNTING=y -CONFIG_TINY_SRCU=y -# CONFIG_TOSHIBA is not set -CONFIG_UNWINDER_FRAME_POINTER=y -# CONFIG_UNWINDER_GUESS is not set -CONFIG_UP_LATE_INIT=y -CONFIG_USB=y -CONFIG_USB_COMMON=y -CONFIG_USB_EHCI_HCD=y -# CONFIG_USB_EHCI_HCD_PLATFORM is not set -CONFIG_USB_EHCI_PCI=y -CONFIG_USB_HID=y -CONFIG_USB_HIDDEV=y -CONFIG_USB_OHCI_HCD=y -CONFIG_USB_OHCI_HCD_PCI=y -# CONFIG_USB_OHCI_HCD_PLATFORM is not set -CONFIG_USB_PCI=y -CONFIG_USB_SUPPORT=y -CONFIG_USB_UHCI_HCD=y -CONFIG_USB_XHCI_HCD=y -CONFIG_USB_XHCI_PCI=y -# CONFIG_USB_XHCI_PLATFORM is not set -# CONFIG_USERIO is not set -# CONFIG_USER_NS is not set -CONFIG_USER_STACKTRACE_SUPPORT=y -# CONFIG_VGACON_SOFT_SCROLLBACK is not set -CONFIG_VGA_CONSOLE=y -# CONFIG_VIA_WDT is not set -# CONFIG_VMWARE_VMCI is not set -CONFIG_VM_EVENT_COUNTERS=y -CONFIG_VT=y -CONFIG_VT_CONSOLE=y -CONFIG_VT_HW_CONSOLE_BINDING=y -# CONFIG_WAFER_WDT is not set -CONFIG_X86=y -CONFIG_X86_32=y -# CONFIG_X86_32_IRIS is not set -CONFIG_X86_32_LAZY_GS=y -CONFIG_X86_ALIGNMENT_16=y -# CONFIG_X86_ANCIENT_MCE is not set -# CONFIG_X86_CHECK_BIOS_CORRUPTION is not set -CONFIG_X86_CMPXCHG64=y -# CONFIG_X86_CPUFREQ_NFORCE2 is not set -# CONFIG_X86_CPUID is not set -# CONFIG_X86_DEBUG_FPU is not set -# CONFIG_X86_EXTENDED_PLATFORM is not set -CONFIG_X86_F00F_BUG=y -CONFIG_X86_FEATURE_NAMES=y -CONFIG_X86_GENERIC=y -# CONFIG_X86_GX_SUSPMOD is not set -# CONFIG_X86_INTEL_PSTATE is not set -CONFIG_X86_INTEL_UMIP=y -CONFIG_X86_INTEL_USERCOPY=y -CONFIG_X86_INTERNODE_CACHE_SHIFT=6 -CONFIG_X86_IO_APIC=y -CONFIG_X86_L1_CACHE_SHIFT=6 -# CONFIG_X86_LEGACY_VM86 is not set -CONFIG_X86_LOCAL_APIC=y -# CONFIG_X86_LONGRUN is not set -CONFIG_X86_MCE=y -# CONFIG_X86_MCELOG_LEGACY is not set -CONFIG_X86_MCE_AMD=y -# CONFIG_X86_MCE_INJECT is not set -CONFIG_X86_MCE_INTEL=y -CONFIG_X86_MCE_THRESHOLD=y -CONFIG_X86_MINIMUM_CPU_FAMILY=5 -CONFIG_X86_MPPARSE=y -CONFIG_X86_MSR=y -# CONFIG_X86_P4_CLOCKMOD is not set -CONFIG_X86_PAT=y -CONFIG_X86_PLATFORM_DEVICES=y -# CONFIG_X86_POWERNOW_K6 is not set -# CONFIG_X86_POWERNOW_K7 is not set -# CONFIG_X86_PTDUMP is not set -# CONFIG_X86_REBOOTFIXUPS is not set -CONFIG_X86_REROUTE_FOR_BROKEN_BOOT_IRQS=y -CONFIG_X86_RESERVE_LOW=64 -# CONFIG_X86_SMAP is not set -# CONFIG_X86_SPEEDSTEP_CENTRINO is not set -# CONFIG_X86_SPEEDSTEP_ICH is not set -# CONFIG_X86_SPEEDSTEP_SMI is not set -CONFIG_X86_SUPPORTS_MEMORY_FAILURE=y -CONFIG_X86_THERMAL_VECTOR=y -CONFIG_X86_TSC=y -CONFIG_X86_UP_APIC=y -CONFIG_X86_UP_IOAPIC=y -CONFIG_X86_VERBOSE_BOOTUP=y -CONFIG_XZ_DEC_BCJ=y -CONFIG_XZ_DEC_X86=y -CONFIG_ZLIB_INFLATE=y